Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
diff --git a/.gitignore b/.gitignore
index 5014bfa..3f8fb68 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@
 *.a
 *.s
 *.ko
+*.so
 *.mod.c
 
 #
@@ -23,6 +24,7 @@
 # Generated include files
 #
 include/asm
+include/asm-*/asm-offsets.h
 include/config
 include/linux/autoconf.h
 include/linux/compile.h
diff --git a/CREDITS b/CREDITS
index 1b4f869..8e577ce 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1883,6 +1883,7 @@
 E: jayalk@intworks.biz
 W: http://www.intworks.biz
 D: Arc monochrome LCD framebuffer driver, x86 reboot fixups
+D: pirq addr, CS5535 alsa audio driver
 S: Gurgaon, India
 S: Kuala Lumpur, Malaysia
 
@@ -3202,7 +3203,7 @@
 E: ebs@ebshome.net
 W: http://kernel.ebshome.net/
 P: 1024D/AE5467F1 FF22 39F1 6728 89F6 6E6C  2365 7602 F33D AE54 67F1
-D: Embedded PowerPC 4xx: I2C, PIC and random hacks/fixes
+D: Embedded PowerPC 4xx: EMAC, I2C, PIC and random hacks/fixes
 S: Sunnyvale, California 94085
 S: USA
 
diff --git a/Documentation/Changes b/Documentation/Changes
index 86b8639..fe5ae0f 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -31,8 +31,6 @@
 Eine deutsche Version dieser Datei finden Sie unter
 <http://www.stefan-winter.de/Changes-2.4.0.txt>.
 
-Last updated: October 29th, 2002
-
 Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu).
 
 Current Minimal Requirements
@@ -48,7 +46,7 @@
 hardware, for example, you probably needn't concern yourself with
 isdn4k-utils.
 
-o  Gnu C                  2.95.3                  # gcc --version
+o  Gnu C                  3.2                     # gcc --version
 o  Gnu make               3.79.1                  # make --version
 o  binutils               2.12                    # ld -v
 o  util-linux             2.10o                   # fdformat --version
@@ -74,26 +72,7 @@
 ---
 
 The gcc version requirements may vary depending on the type of CPU in your
-computer. The next paragraph applies to users of x86 CPUs, but not
-necessarily to users of other CPUs. Users of other CPUs should obtain
-information about their gcc version requirements from another source.
-
-The recommended compiler for the kernel is gcc 2.95.x (x >= 3), and it
-should be used when you need absolute stability. You may use gcc 3.0.x
-instead if you wish, although it may cause problems. Later versions of gcc 
-have not received much testing for Linux kernel compilation, and there are 
-almost certainly bugs (mainly, but not exclusively, in the kernel) that
-will need to be fixed in order to use these compilers. In any case, using
-pgcc instead of plain gcc is just asking for trouble.
-
-The Red Hat gcc 2.96 compiler subtree can also be used to build this tree.
-You should ensure you use gcc-2.96-74 or later. gcc-2.96-54 will not build
-the kernel correctly.
-
-In addition, please pay attention to compiler optimization.  Anything
-greater than -O2 may not be wise.  Similarly, if you choose to use gcc-2.95.x
-or derivatives, be sure not to use -fstrict-aliasing (which, depending on
-your version of gcc 2.95.x, may necessitate using -fno-strict-aliasing).
+computer.
 
 Make
 ----
@@ -322,9 +301,9 @@
 Kernel compilation
 ******************
 
-gcc 2.95.3
-----------
-o  <ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3.tar.gz>
+gcc
+---
+o  <ftp://ftp.gnu.org/gnu/gcc/>
 
 Make
 ----
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle
index eb7db3c..ce780ef 100644
--- a/Documentation/CodingStyle
+++ b/Documentation/CodingStyle
@@ -344,7 +344,7 @@
 have a reference count on it, you almost certainly have a bug.
 
 
-		Chapter 11: Macros, Enums, Inline functions and RTL
+		Chapter 11: Macros, Enums and RTL
 
 Names of macros defining constants and labels in enums are capitalized.
 
@@ -429,7 +429,35 @@
 language.
 
 
-		Chapter 14: References
+		Chapter 14: The inline disease
+
+There appears to be a common misperception that gcc has a magic "make me
+faster" speedup option called "inline". While the use of inlines can be
+appropriate (for example as a means of replacing macros, see Chapter 11), it
+very often is not. Abundant use of the inline keyword leads to a much bigger
+kernel, which in turn slows the system as a whole down, due to a bigger
+icache footprint for the CPU and simply because there is less memory
+available for the pagecache. Just think about it; a pagecache miss causes a
+disk seek, which easily takes 5 miliseconds. There are a LOT of cpu cycles
+that can go into these 5 miliseconds.
+
+A reasonable rule of thumb is to not put inline at functions that have more
+than 3 lines of code in them. An exception to this rule are the cases where
+a parameter is known to be a compiletime constant, and as a result of this
+constantness you *know* the compiler will be able to optimize most of your
+function away at compile time. For a good example of this later case, see
+the kmalloc() inline function.
+
+Often people argue that adding inline to functions that are static and used
+only once is always a win since there is no space tradeoff. While this is
+technically correct, gcc is capable of inlining these automatically without
+help, and the maintenance issue of removing the inline when a second user
+appears outweighs the potential value of the hint that tells gcc to do
+something it would have done anyway.
+
+
+
+		Chapter 15: References
 
 The C Programming Language, Second Edition
 by Brian W. Kernighan and Dennis M. Ritchie.
@@ -444,10 +472,13 @@
 URL: http://cm.bell-labs.com/cm/cs/tpop/
 
 GNU manuals - where in compliance with K&R and this text - for cpp, gcc,
-gcc internals and indent, all available from http://www.gnu.org
+gcc internals and indent, all available from http://www.gnu.org/manual/
 
 WG14 is the international standardization working group for the programming
-language C, URL: http://std.dkuug.dk/JTC1/SC22/WG14/
+language C, URL: http://www.open-std.org/JTC1/SC22/WG14/
+
+Kernel CodingStyle, by greg@kroah.com at OLS 2002:
+http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
 
 --
-Last updated on 16 February 2004 by a community effort on LKML.
+Last updated on 30 December 2005 by a community effort on LKML.
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index 767433b..3c47a3f 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -369,6 +369,7 @@
 X!Edrivers/acpi/bus.c
 -->
 !Edrivers/acpi/scan.c
+!Idrivers/acpi/scan.c
 <!-- No correct structured comments
 X!Edrivers/acpi/pci_bind.c
 -->
diff --git a/Documentation/DocBook/usb.tmpl b/Documentation/DocBook/usb.tmpl
index 15ce0f2..320af25 100644
--- a/Documentation/DocBook/usb.tmpl
+++ b/Documentation/DocBook/usb.tmpl
@@ -253,6 +253,7 @@
 !Edrivers/usb/core/urb.c
 !Edrivers/usb/core/message.c
 !Edrivers/usb/core/file.c
+!Edrivers/usb/core/driver.c
 !Edrivers/usb/core/usb.c
 !Edrivers/usb/core/hub.c
     </chapter>
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt
index a23fee6..3f60db41 100644
--- a/Documentation/RCU/rcuref.txt
+++ b/Documentation/RCU/rcuref.txt
@@ -1,74 +1,67 @@
-Refcounter framework for elements of lists/arrays protected by
-RCU.
+Refcounter design for elements of lists/arrays protected by RCU.
 
 Refcounting on elements of  lists which are protected by traditional
 reader/writer spinlocks or semaphores are straight forward as in:
 
-1.					2.
-add()					search_and_reference()
-{					{
-	alloc_object				read_lock(&list_lock);
-	...					search_for_element
-	atomic_set(&el->rc, 1);			atomic_inc(&el->rc);
-	write_lock(&list_lock);			...
-	add_element				read_unlock(&list_lock);
-	...					...
-	write_unlock(&list_lock);	}
+1.				2.
+add()				search_and_reference()
+{				{
+    alloc_object		    read_lock(&list_lock);
+    ...				    search_for_element
+    atomic_set(&el->rc, 1);	    atomic_inc(&el->rc);
+    write_lock(&list_lock);	     ...
+    add_element			    read_unlock(&list_lock);
+    ...				    ...
+    write_unlock(&list_lock);	}
 }
 
 3.					4.
 release_referenced()			delete()
 {					{
-	...				write_lock(&list_lock);
-	atomic_dec(&el->rc, relfunc)	...
-	...				delete_element
-}					write_unlock(&list_lock);
- 					...
-					if (atomic_dec_and_test(&el->rc))
-						kfree(el);
-					...
+    ...					    write_lock(&list_lock);
+    atomic_dec(&el->rc, relfunc)	    ...
+    ...					    delete_element
+}					    write_unlock(&list_lock);
+ 					    ...
+					    if (atomic_dec_and_test(&el->rc))
+					        kfree(el);
+					    ...
 					}
 
 If this list/array is made lock free using rcu as in changing the
 write_lock in add() and delete() to spin_lock and changing read_lock
-in search_and_reference to rcu_read_lock(), the rcuref_get in
+in search_and_reference to rcu_read_lock(), the atomic_get in
 search_and_reference could potentially hold reference to an element which
-has already been deleted from the list/array.  rcuref_lf_get_rcu takes
+has already been deleted from the list/array.  atomic_inc_not_zero takes
 care of this scenario. search_and_reference should look as;
 
 1.					2.
 add()					search_and_reference()
 {					{
- 	alloc_object				rcu_read_lock();
-	...					search_for_element
-	atomic_set(&el->rc, 1);			if (rcuref_inc_lf(&el->rc)) {
-	write_lock(&list_lock);				rcu_read_unlock();
-							return FAIL;
-	add_element				}
-	...					...
-	write_unlock(&list_lock);		rcu_read_unlock();
+    alloc_object			    rcu_read_lock();
+    ...					    search_for_element
+    atomic_set(&el->rc, 1);		    if (atomic_inc_not_zero(&el->rc)) {
+    write_lock(&list_lock);		        rcu_read_unlock();
+					        return FAIL;
+    add_element				    }
+    ...					    ...
+    write_unlock(&list_lock);		    rcu_read_unlock();
 }					}
 3.					4.
 release_referenced()			delete()
 {					{
-	...				write_lock(&list_lock);
-	rcuref_dec(&el->rc, relfunc)	...
-	...				delete_element
-}					write_unlock(&list_lock);
- 					...
-					if (rcuref_dec_and_test(&el->rc))
-						call_rcu(&el->head, el_free);
-					...
+    ...					    write_lock(&list_lock);
+    atomic_dec(&el->rc, relfunc)	    ...
+    ...					    delete_element
+}					    write_unlock(&list_lock);
+ 					    ...
+					    if (atomic_dec_and_test(&el->rc))
+					        call_rcu(&el->head, el_free);
+					    ...
 					}
 
 Sometimes, reference to the element need to be obtained in the
-update (write) stream.  In such cases, rcuref_inc_lf might be an overkill
-since the spinlock serialising list updates are held. rcuref_inc
+update (write) stream.  In such cases, atomic_inc_not_zero might be an
+overkill since the spinlock serialising list updates are held. atomic_inc
 is to be used in such cases.
-For arches which do not have cmpxchg rcuref_inc_lf
-api uses a hashed spinlock implementation and the same hashed spinlock
-is acquired in all rcuref_xxx primitives to preserve atomicity.
-Note: Use rcuref_inc api only if you need to use rcuref_inc_lf on the
-refcounter atleast at one place.  Mixing rcuref_inc and atomic_xxx api
-might lead to races. rcuref_inc_lf() must be used in lockfree
-RCU critical sections only.
+
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index c3cca92..dd311cf 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -27,18 +27,17 @@
 ------------------------
 
 Linux 2.0:
-	No new drivers are accepted for this kernel tree
+	No new drivers are accepted for this kernel tree.
 
 Linux 2.2:
+	No new drivers are accepted for this kernel tree.
+
+Linux 2.4:
 	If the code area has a general maintainer then please submit it to
 	the maintainer listed in MAINTAINERS in the kernel file. If the
 	maintainer does not respond or you cannot find the appropriate
-	maintainer then please contact the 2.2 kernel maintainer:
-	Marc-Christian Petersen <m.c.p@wolk-project.de>.
-
-Linux 2.4:
-	The same rules apply as 2.2. The final contact point for Linux 2.4
-	submissions is Marcelo Tosatti <marcelo.tosatti@cyclades.com>.
+	maintainer then please contact Marcelo Tosatti
+	<marcelo.tosatti@cyclades.com>.
 
 Linux 2.6:
 	The same rules apply as 2.4 except that you should follow linux-kernel
@@ -53,6 +52,7 @@
 		of exclusive GPL licensing, and if you wish the driver
 		to be useful to other communities such as BSD you may well
 		wish to release under multiple licenses.
+		See accepted licenses at include/linux/module.h
 
 Copyright:	The copyright owner must agree to use of GPL.
 		It's best if the submitter and copyright owner
@@ -143,5 +143,13 @@
 	http://kernelnewbies.org/
 
 Linux USB project:
-	http://sourceforge.net/projects/linux-usb/
+	http://linux-usb.sourceforge.net/
 
+How to NOT write kernel driver by arjanv@redhat.com
+	http://people.redhat.com/arjanv/olspaper.pdf
+
+Kernel Janitor:
+	http://janitor.kernelnewbies.org/
+
+--
+Last updated on 17 Nov 2005.
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 237d54c..6198e5e 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -78,7 +78,9 @@
 http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz
 
 Andrew Morton's patch scripts:
-http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.20
+http://www.zip.com.au/~akpm/linux/patches/
+Instead of these scripts, quilt is the recommended patch management
+tool (see above).
 
 
 
@@ -97,7 +99,7 @@
 
 3) Separate your changes.
 
-Separate each logical change into its own patch.
+Separate _logical changes_ into a single patch file.
 
 For example, if your changes include both bug fixes and performance
 enhancements for a single driver, separate those changes into two
@@ -112,6 +114,10 @@
 complete, that is OK.  Simply note "this patch depends on patch X"
 in your patch description.
 
+If you cannot condense your patch set into a smaller set of patches,
+then only post say 15 or so at a time and wait for review and integration.
+
+
 
 4) Select e-mail destination.
 
@@ -124,6 +130,10 @@
 linux-kernel@vger.kernel.org.  Most kernel developers monitor this
 e-mail list, and can comment on your changes.
 
+
+Do not send more than 15 patches at once to the vger mailing lists!!!
+
+
 Linus Torvalds is the final arbiter of all changes accepted into the
 Linux kernel.  His e-mail address is <torvalds@osdl.org>.  He gets
 a lot of e-mail, so typically you should do your best to -avoid- sending
@@ -149,6 +159,9 @@
 MAINTAINERS file for a mailing list that relates specifically to
 your change.
 
+Majordomo lists of VGER.KERNEL.ORG at:
+	<http://vger.kernel.org/vger-lists.html>
+
 If changes affect userland-kernel interfaces, please send
 the MAN-PAGES maintainer (as listed in the MAINTAINERS file)
 a man-pages patch, or at least a notification of the change,
@@ -158,7 +171,7 @@
 copy the maintainer when you change their code.
 
 For small patches you may want to CC the Trivial Patch Monkey
-trivial@rustcorp.com.au set up by Rusty Russell; which collects "trivial"
+trivial@kernel.org managed by Adrian Bunk; which collects "trivial"
 patches. Trivial patches must qualify for one of the following rules:
  Spelling fixes in documentation
  Spelling fixes which could break grep(1).
@@ -171,7 +184,7 @@
  since people copy, as long as it's trivial)
  Any fix by the author/maintainer of the file. (ie. patch monkey
  in re-transmission mode)
-URL: <http://www.kernel.org/pub/linux/kernel/people/rusty/trivial/>
+URL: <http://www.kernel.org/pub/linux/kernel/people/bunk/trivial/>
 
 
 
@@ -373,27 +386,14 @@
 and deleted lines per file.  A diffstat is especially useful on bigger
 patches.  Other comments relevant only to the moment or the maintainer,
 not suitable for the permanent changelog, should also go here.
+Use diffstat options "-p 1 -w 70" so that filenames are listed from the
+top of the kernel source tree and don't use too much horizontal space
+(easily fit in 80 columns, maybe with some indentation).
 
 See more details on the proper patch format in the following
 references.
 
 
-13) More references for submitting patches
-
-Andrew Morton, "The perfect patch" (tpp).
-  <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
-
-Jeff Garzik, "Linux kernel patch submission format."
-  <http://linux.yyz.us/patch-format.html>
-
-Greg KH, "How to piss off a kernel subsystem maintainer"
-  <http://www.kroah.com/log/2005/03/31/>
-
-Kernel Documentation/CodingStyle
-  <http://sosdg.org/~coywolf/lxr/source/Documentation/CodingStyle>
-
-Linus Torvald's mail on the canonical patch format:
-  <http://lkml.org/lkml/2005/4/7/183>
 
 
 -----------------------------------
@@ -466,3 +466,30 @@
 Don't try to anticipate nebulous future cases which may or may not
 be useful:  "Make it as simple as you can, and no simpler."
 
+
+
+----------------------
+SECTION 3 - REFERENCES
+----------------------
+
+Andrew Morton, "The perfect patch" (tpp).
+  <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
+
+Jeff Garzik, "Linux kernel patch submission format."
+  <http://linux.yyz.us/patch-format.html>
+
+Greg Kroah, "How to piss off a kernel subsystem maintainer".
+  <http://www.kroah.com/log/2005/03/31/>
+  <http://www.kroah.com/log/2005/07/08/>
+  <http://www.kroah.com/log/2005/10/19/>
+
+NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people!.
+  <http://marc.theaimsgroup.com/?l=linux-kernel&m=112112749912944&w=2>
+
+Kernel Documentation/CodingStyle
+  <http://sosdg.org/~coywolf/lxr/source/Documentation/CodingStyle>
+
+Linus Torvald's mail on the canonical patch format:
+  <http://lkml.org/lkml/2005/4/7/183>
+--
+Last updated on 17 Nov 2005.
diff --git a/Documentation/applying-patches.txt b/Documentation/applying-patches.txt
index 681e426..05a08c2 100644
--- a/Documentation/applying-patches.txt
+++ b/Documentation/applying-patches.txt
@@ -2,7 +2,8 @@
 	Applying Patches To The Linux Kernel
 	------------------------------------
 
-	(Written by Jesper Juhl, August 2005)
+	Original by: Jesper Juhl, August 2005
+	Last update: 2005-12-02
 
 
 
@@ -118,7 +119,7 @@
 
 When patch encounters a change that it can't fix up with fuzz it rejects it
 outright and leaves a file with a .rej extension (a reject file). You can
-read this file to see exactely what change couldn't be applied, so you can
+read this file to see exactly what change couldn't be applied, so you can
 go fix it up by hand if you wish.
 
 If you don't have any third party patches applied to your kernel source, but
@@ -127,7 +128,7 @@
 never see a fuzz or reject message from patch. If you do see such messages
 anyway, then there's a high risk that either your local source tree or the
 patch file is corrupted in some way. In that case you should probably try
-redownloading the patch and if things are still not OK then you'd be advised
+re-downloading the patch and if things are still not OK then you'd be advised
 to start with a fresh tree downloaded in full from kernel.org.
 
 Let's look a bit more at some of the messages patch can produce.
@@ -180,9 +181,11 @@
 
 Are there any alternatives to `patch'?
 ---
- Yes there are alternatives. You can use the `interdiff' program
-(http://cyberelk.net/tim/patchutils/) to generate a patch representing the
-differences between two patches and then apply the result.
+ Yes there are alternatives.
+
+ You can use the `interdiff' program (http://cyberelk.net/tim/patchutils/) to
+generate a patch representing the differences between two patches and then
+apply the result.
 This will let you move from something like 2.6.12.2 to 2.6.12.3 in a single
 step. The -z flag to interdiff will even let you feed it patches in gzip or
 bzip2 compressed form directly without the use of zcat or bzcat or manual
@@ -197,7 +200,7 @@
  Another alternative is `ketchup', which is a python script for automatic
 downloading and applying of patches (http://www.selenic.com/ketchup/).
 
-Other nice tools are diffstat which shows a summary of changes made by a
+ Other nice tools are diffstat which shows a summary of changes made by a
 patch, lsdiff which displays a short listing of affected files in a patch
 file, along with (optionally) the line numbers of the start of each patch
 and grepdiff which displays a list of the files modified by a patch where
@@ -258,7 +261,7 @@
 					# source dir is now 2.6.11
 $ patch -p1 < ../patch-2.6.12		# apply new 2.6.12 patch
 $ cd ..
-$ mv linux-2.6.11.1 inux-2.6.12		# rename source dir
+$ mv linux-2.6.11.1 linux-2.6.12		# rename source dir
 
 
 The 2.6.x.y kernels
@@ -433,7 +436,11 @@
 $ mv linux-2.6.12-mm1 linux-2.6.13-rc3-mm3	# rename the source dir
 
 
-This concludes this list of explanations of the various kernel trees and I
-hope you are now crystal clear on how to apply the various patches and help
-testing the kernel.
+This concludes this list of explanations of the various kernel trees.
+I hope you are now clear on how to apply the various patches and help testing
+the kernel.
+
+Thank you's to Randy Dunlap, Rolf Eike Beer, Linus Torvalds, Bodo Eggert,
+Johannes Stezenbach, Grant Coady, Pavel Machek and others that I may have
+forgotten for their reviews and contributions to this document.
 
diff --git a/Documentation/arm/00-INDEX b/Documentation/arm/00-INDEX
index d753fe5..2c6a3b3 100644
--- a/Documentation/arm/00-INDEX
+++ b/Documentation/arm/00-INDEX
@@ -16,5 +16,7 @@
 	- Empeg documentation
 mem_alignment
 	- alignment abort handler documentation
+memory.txt
+	- description of the virtual memory layout
 nwfpe
 	- NWFPE floating point emulator documentation
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index 0fe01c8..8e63831 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -31,7 +31,7 @@
 document:
 	Christoph Hellwig <hch@infradead.org>
 	Arjan van de Ven <arjanv@redhat.com>
-	Randy Dunlap <rddunlap@osdl.org>
+	Randy Dunlap <rdunlap@xenotime.net>
 	Andre Hedrick <andre@linux-ide.org>
 
 The following people helped with fixes/contributions to the bio patches
@@ -263,14 +263,8 @@
 The generic i/o scheduler would make sure that it places the barrier request and
 all other requests coming after it after all the previous requests in the
 queue. Barriers may be implemented in different ways depending on the
-driver. A SCSI driver for example could make use of ordered tags to
-preserve the necessary ordering with a lower impact on throughput. For IDE
-this might be two sync cache flush: a pre and post flush when encountering
-a barrier write.
-
-There is a provision for queues to indicate what kind of barriers they
-can provide. This is as of yet unmerged, details will be added here once it
-is in the kernel.
+driver. For more details regarding I/O barriers, please read barrier.txt
+in this directory.
 
 1.2.2 Request Priority/Latency
 
diff --git a/Documentation/block/stat.txt b/Documentation/block/stat.txt
new file mode 100644
index 0000000..0dbc946
--- /dev/null
+++ b/Documentation/block/stat.txt
@@ -0,0 +1,82 @@
+Block layer statistics in /sys/block/<dev>/stat
+===============================================
+
+This file documents the contents of the /sys/block/<dev>/stat file.
+
+The stat file provides several statistics about the state of block
+device <dev>.
+
+Q. Why are there multiple statistics in a single file?  Doesn't sysfs
+   normally contain a single value per file?
+A. By having a single file, the kernel can guarantee that the statistics
+   represent a consistent snapshot of the state of the device.  If the
+   statistics were exported as multiple files containing one statistic
+   each, it would be impossible to guarantee that a set of readings
+   represent a single point in time.
+
+The stat file consists of a single line of text containing 11 decimal
+values separated by whitespace.  The fields are summarized in the
+following table, and described in more detail below.
+
+Name            units         description
+----            -----         -----------
+read I/Os       requests      number of read I/Os processed
+read merges     requests      number of read I/Os merged with in-queue I/O
+read sectors    sectors       number of sectors read
+read ticks      milliseconds  total wait time for read requests
+write I/Os      requests      number of write I/Os processed
+write merges    requests      number of write I/Os merged with in-queue I/O
+write sectors   sectors       number of sectors written
+write ticks     milliseconds  total wait time for write requests
+in_flight       requests      number of I/Os currently in flight
+io_ticks        milliseconds  total time this block device has been active
+time_in_queue   milliseconds  total wait time for all requests
+
+read I/Os, write I/Os
+=====================
+
+These values increment when an I/O request completes.
+
+read merges, write merges
+=========================
+
+These values increment when an I/O request is merged with an
+already-queued I/O request.
+
+read sectors, write sectors
+===========================
+
+These values count the number of sectors read from or written to this
+block device.  The "sectors" in question are the standard UNIX 512-byte
+sectors, not any device- or filesystem-specific block size.  The
+counters are incremented when the I/O completes.
+
+read ticks, write ticks
+=======================
+
+These values count the number of milliseconds that I/O requests have
+waited on this block device.  If there are multiple I/O requests waiting,
+these values will increase at a rate greater than 1000/second; for
+example, if 60 read requests wait for an average of 30 ms, the read_ticks
+field will increase by 60*30 = 1800.
+
+in_flight
+=========
+
+This value counts the number of I/O requests that have been issued to
+the device driver but have not yet completed.  It does not include I/O
+requests that are in the queue but not yet issued to the device driver.
+
+io_ticks
+========
+
+This value counts the number of milliseconds during which the device has
+had I/O requests queued.
+
+time_in_queue
+=============
+
+This value counts the number of milliseconds that I/O requests have waited
+on this block device.  If there are multiple I/O requests waiting, this
+value will increase as the product of the number of milliseconds times the
+number of requests waiting (see "read ticks" above for an example).
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
index 933fae7..f4b8dc4 100644
--- a/Documentation/cpu-freq/governors.txt
+++ b/Documentation/cpu-freq/governors.txt
@@ -27,6 +27,7 @@
 2.2  Powersave
 2.3  Userspace
 2.4  Ondemand
+2.5  Conservative
 
 3.   The Governor Interface in the CPUfreq Core
 
@@ -110,9 +111,64 @@
 
 The CPUfreq govenor "ondemand" sets the CPU depending on the
 current usage. To do this the CPU must have the capability to
-switch the frequency very fast.
+switch the frequency very quickly.  There are a number of sysfs file
+accessible parameters:
+
+sampling_rate: measured in uS (10^-6 seconds), this is how often you
+want the kernel to look at the CPU usage and to make decisions on
+what to do about the frequency.  Typically this is set to values of
+around '10000' or more.
+
+show_sampling_rate_(min|max): the minimum and maximum sampling rates
+available that you may set 'sampling_rate' to.
+
+up_threshold: defines what the average CPU usaged between the samplings
+of 'sampling_rate' needs to be for the kernel to make a decision on
+whether it should increase the frequency.  For example when it is set
+to its default value of '80' it means that between the checking
+intervals the CPU needs to be on average more than 80% in use to then
+decide that the CPU frequency needs to be increased.  
+
+sampling_down_factor: this parameter controls the rate that the CPU
+makes a decision on when to decrease the frequency.  When set to its
+default value of '5' it means that at 1/5 the sampling_rate the kernel
+makes a decision to lower the frequency.  Five "lower rate" decisions
+have to be made in a row before the CPU frequency is actually lower.
+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
+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
+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.
 
 
+2.5 Conservative
+----------------
+
+The CPUfreq governor "conservative", much like the "ondemand"
+governor, sets the CPU depending on the current usage.  It differs in
+behaviour in that it gracefully increases and decreases the CPU speed
+rather than jumping to max speed the moment there is any load on the
+CPU.  This behaviour more suitable in a battery powered environment.
+The governor is tweaked in the same manner as the "ondemand" governor
+through sysfs with the addition of:
+
+freq_step: this describes what percentage steps the cpu freq should be
+increased and decreased smoothly by.  By default the cpu frequency will
+increase in 5% chunks of your maximum cpu frequency.  You can change this
+value to anywhere between 0 and 100 where '0' will effectively lock your
+CPU at a speed regardless of its load whilst '100' will, in theory, make
+it behave identically to the "ondemand" governor.
+
+down_threshold: same as the 'up_threshold' found for the "ondemand"
+governor but for the opposite direction.  For example when set to its
+default value of '20' it means that if the CPU usage needs to be below
+20% between samples to have the frequency decreased.
 
 3. The Governor Interface in the CPUfreq Core
 =============================================
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt
new file mode 100644
index 0000000..08c5d04
--- /dev/null
+++ b/Documentation/cpu-hotplug.txt
@@ -0,0 +1,357 @@
+		CPU hotplug Support in Linux(tm) Kernel
+
+		Maintainers:
+		CPU Hotplug Core:
+			Rusty Russell <rusty@rustycorp.com.au>
+			Srivatsa Vaddagiri <vatsa@in.ibm.com>
+		i386:
+			Zwane Mwaikambo <zwane@arm.linux.org.uk>
+		ppc64:
+			Nathan Lynch <nathanl@austin.ibm.com>
+			Joel Schopp <jschopp@austin.ibm.com>
+		ia64/x86_64:
+			Ashok Raj <ashok.raj@intel.com>
+
+Authors: Ashok Raj <ashok.raj@intel.com>
+Lots of feedback: Nathan Lynch <nathanl@austin.ibm.com>,
+	     Joel Schopp <jschopp@austin.ibm.com>
+
+Introduction
+
+Modern advances in system architectures have introduced advanced error
+reporting and correction capabilities in processors. CPU architectures permit
+partitioning support, where compute resources of a single CPU could be made
+available to virtual machine environments. There are couple OEMS that
+support NUMA hardware which are hot pluggable as well, where physical
+node insertion and removal require support for CPU hotplug.
+
+Such advances require CPUs available to a kernel to be removed either for
+provisioning reasons, or for RAS purposes to keep an offending CPU off
+system execution path. Hence the need for CPU hotplug support in the
+Linux kernel.
+
+A more novel use of CPU-hotplug support is its use today in suspend
+resume support for SMP. Dual-core and HT support makes even
+a laptop run SMP kernels which didn't support these methods. SMP support
+for suspend/resume is a work in progress.
+
+General Stuff about CPU Hotplug
+--------------------------------
+
+Command Line Switches
+---------------------
+maxcpus=n    Restrict boot time cpus to n. Say if you have 4 cpus, using
+             maxcpus=2 will only boot 2. You can choose to bring the
+             other cpus later online, read FAQ's for more info.
+
+additional_cpus=n	[x86_64 only] use this to limit hotpluggable cpus.
+                        This option sets
+			cpu_possible_map = cpu_present_map + additional_cpus
+
+CPU maps and such
+-----------------
+[More on cpumaps and primitive to manipulate, please check
+include/linux/cpumask.h that has more descriptive text.]
+
+cpu_possible_map: Bitmap of possible CPUs that can ever be available in the
+system. This is used to allocate some boot time memory for per_cpu variables
+that aren't designed to grow/shrink as CPUs are made available or removed.
+Once set during boot time discovery phase, the map is static, i.e no bits
+are added or removed anytime.  Trimming it accurately for your system needs
+upfront can save some boot time memory. See below for how we use heuristics
+in x86_64 case to keep this under check.
+
+cpu_online_map: Bitmap of all CPUs currently online. Its set in __cpu_up()
+after a cpu is available for kernel scheduling and ready to receive
+interrupts from devices. Its cleared when a cpu is brought down using
+__cpu_disable(), before which all OS services including interrupts are
+migrated to another target CPU.
+
+cpu_present_map: Bitmap of CPUs currently present in the system. Not all
+of them may be online. When physical hotplug is processed by the relevant
+subsystem (e.g ACPI) can change and new bit either be added or removed
+from the map depending on the event is hot-add/hot-remove. There are currently
+no locking rules as of now. Typical usage is to init topology during boot,
+at which time hotplug is disabled.
+
+You really dont need to manipulate any of the system cpu maps. They should
+be read-only for most use. When setting up per-cpu resources almost always use
+cpu_possible_map/for_each_cpu() to iterate.
+
+Never use anything other than cpumask_t to represent bitmap of CPUs.
+
+#include <linux/cpumask.h>
+
+for_each_cpu              - Iterate over cpu_possible_map
+for_each_online_cpu       - Iterate over cpu_online_map
+for_each_present_cpu      - Iterate over cpu_present_map
+for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask.
+
+#include <linux/cpu.h>
+lock_cpu_hotplug() and unlock_cpu_hotplug():
+
+The above calls are used to inhibit cpu hotplug operations. While holding the
+cpucontrol mutex, cpu_online_map will not change. If you merely need to avoid
+cpus going away, you could also use preempt_disable() and preempt_enable()
+for those sections. Just remember the critical section cannot call any
+function that can sleep or schedule this process away. The preempt_disable()
+will work as long as stop_machine_run() is used to take a cpu down.
+
+CPU Hotplug - Frequently Asked Questions.
+
+Q: How to i enable my kernel to support CPU hotplug?
+A: When doing make defconfig, Enable CPU hotplug support
+
+   "Processor type and Features" -> Support for Hotpluggable CPUs
+
+Make sure that you have CONFIG_HOTPLUG, and CONFIG_SMP turned on as well.
+
+You would need to enable CONFIG_HOTPLUG_CPU for SMP suspend/resume support
+as well.
+
+Q: What architectures support CPU hotplug?
+A: As of 2.6.14, the following architectures support CPU hotplug.
+
+i386 (Intel), ppc, ppc64, parisc, s390, ia64 and x86_64
+
+Q: How to test if hotplug is supported on the newly built kernel?
+A: You should now notice an entry in sysfs.
+
+Check if sysfs is mounted, using the "mount" command. You should notice
+an entry as shown below in the output.
+
+....
+none on /sys type sysfs (rw)
+....
+
+if this is not mounted, do the following.
+
+#mkdir /sysfs
+#mount -t sysfs sys /sys
+
+now you should see entries for all present cpu, the following is an example
+in a 8-way system.
+
+#pwd
+#/sys/devices/system/cpu
+#ls -l
+total 0
+drwxr-xr-x  10 root root 0 Sep 19 07:44 .
+drwxr-xr-x  13 root root 0 Sep 19 07:45 ..
+drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu0
+drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu1
+drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu2
+drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu3
+drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu4
+drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu5
+drwxr-xr-x   3 root root 0 Sep 19 07:44 cpu6
+drwxr-xr-x   3 root root 0 Sep 19 07:48 cpu7
+
+Under each directory you would find an "online" file which is the control
+file to logically online/offline a processor.
+
+Q: Does hot-add/hot-remove refer to physical add/remove of cpus?
+A: The usage of hot-add/remove may not be very consistently used in the code.
+CONFIG_CPU_HOTPLUG enables logical online/offline capability in the kernel.
+To support physical addition/removal, one would need some BIOS hooks and
+the platform should have something like an attention button in PCI hotplug.
+CONFIG_ACPI_HOTPLUG_CPU enables ACPI support for physical add/remove of CPUs.
+
+Q: How do i logically offline a CPU?
+A: Do the following.
+
+#echo 0 > /sys/devices/system/cpu/cpuX/online
+
+once the logical offline is successful, check
+
+#cat /proc/interrupts
+
+you should now not see the CPU that you removed. Also online file will report
+the state as 0 when a cpu if offline and 1 when its online.
+
+#To display the current cpu state.
+#cat /sys/devices/system/cpu/cpuX/online
+
+Q: Why cant i remove CPU0 on some systems?
+A: Some architectures may have some special dependency on a certain CPU.
+
+For e.g in IA64 platforms we have ability to sent platform interrupts to the
+OS. a.k.a Corrected Platform Error Interrupts (CPEI). In current ACPI
+specifications, we didn't have a way to change the target CPU. Hence if the
+current ACPI version doesn't support such re-direction, we disable that CPU
+by making it not-removable.
+
+In such cases you will also notice that the online file is missing under cpu0.
+
+Q: How do i find out if a particular CPU is not removable?
+A: Depending on the implementation, some architectures may show this by the
+absence of the "online" file. This is done if it can be determined ahead of
+time that this CPU cannot be removed.
+
+In some situations, this can be a run time check, i.e if you try to remove the
+last CPU, this will not be permitted. You can find such failures by
+investigating the return value of the "echo" command.
+
+Q: What happens when a CPU is being logically offlined?
+A: The following happen, listed in no particular order :-)
+
+- A notification is sent to in-kernel registered modules by sending an event
+  CPU_DOWN_PREPARE
+- All process is migrated away from this outgoing CPU to a new CPU
+- All interrupts targeted to this CPU is migrated to a new CPU
+- timers/bottom half/task lets are also migrated to a new CPU
+- Once all services are migrated, kernel calls an arch specific routine
+  __cpu_disable() to perform arch specific cleanup.
+- Once this is successful, an event for successful cleanup is sent by an event
+  CPU_DEAD.
+
+  "It is expected that each service cleans up when the CPU_DOWN_PREPARE
+  notifier is called, when CPU_DEAD is called its expected there is nothing
+  running on behalf of this CPU that was offlined"
+
+Q: If i have some kernel code that needs to be aware of CPU arrival and
+   departure, how to i arrange for proper notification?
+A: This is what you would need in your kernel code to receive notifications.
+
+    #include <linux/cpu.h>
+    static int __cpuinit foobar_cpu_callback(struct notifier_block *nfb,
+					    unsigned long action, void *hcpu)
+	{
+		unsigned int cpu = (unsigned long)hcpu;
+
+		switch (action) {
+		case CPU_ONLINE:
+			foobar_online_action(cpu);
+			break;
+		case CPU_DEAD:
+			foobar_dead_action(cpu);
+			break;
+		}
+		return NOTIFY_OK;
+	}
+
+	static struct notifier_block foobar_cpu_notifer =
+	{
+	   .notifier_call = foobar_cpu_callback,
+	};
+
+
+In your init function,
+
+	register_cpu_notifier(&foobar_cpu_notifier);
+
+You can fail PREPARE notifiers if something doesn't work to prepare resources.
+This will stop the activity and send a following CANCELED event back.
+
+CPU_DEAD should not be failed, its just a goodness indication, but bad
+things will happen if a notifier in path sent a BAD notify code.
+
+Q: I don't see my action being called for all CPUs already up and running?
+A: Yes, CPU notifiers are called only when new CPUs are on-lined or offlined.
+   If you need to perform some action for each cpu already in the system, then
+
+  for_each_online_cpu(i) {
+		foobar_cpu_callback(&foobar_cpu_notifier, CPU_UP_PREPARE, i);
+		foobar_cpu_callback(&foobar-cpu_notifier, CPU_ONLINE, i);
+  }
+
+Q: If i would like to develop cpu hotplug support for a new architecture,
+   what do i need at a minimum?
+A: The following are what is required for CPU hotplug infrastructure to work
+   correctly.
+
+    - Make sure you have an entry in Kconfig to enable CONFIG_HOTPLUG_CPU
+    - __cpu_up()        - Arch interface to bring up a CPU
+    - __cpu_disable()   - Arch interface to shutdown a CPU, no more interrupts
+                          can be handled by the kernel after the routine
+                          returns. Including local APIC timers etc are
+                          shutdown.
+     - __cpu_die()      - This actually supposed to ensure death of the CPU.
+                          Actually look at some example code in other arch
+                          that implement CPU hotplug. The processor is taken
+                          down from the idle() loop for that specific
+                          architecture. __cpu_die() typically waits for some
+                          per_cpu state to be set, to ensure the processor
+                          dead routine is called to be sure positively.
+
+Q: I need to ensure that a particular cpu is not removed when there is some
+   work specific to this cpu is in progress.
+A: First switch the current thread context to preferred cpu
+
+   int my_func_on_cpu(int cpu)
+   {
+       cpumask_t saved_mask, new_mask = CPU_MASK_NONE;
+       int curr_cpu, err = 0;
+
+       saved_mask = current->cpus_allowed;
+       cpu_set(cpu, new_mask);
+       err = set_cpus_allowed(current, new_mask);
+
+       if (err)
+           return err;
+
+       /*
+        * If we got scheduled out just after the return from
+        * set_cpus_allowed() before running the work, this ensures
+        * we stay locked.
+        */
+       curr_cpu = get_cpu();
+
+       if (curr_cpu != cpu) {
+	   err = -EAGAIN;
+           goto ret;
+       } else {
+       	   /*
+	    * Do work : But cant sleep, since get_cpu() disables preempt
+	    */
+       }
+    ret:
+    	put_cpu();
+	set_cpus_allowed(current, saved_mask);
+	return err;
+    }
+
+
+Q: How do we determine how many CPUs are available for hotplug.
+A: There is no clear spec defined way from ACPI that can give us that
+   information today. Based on some input from Natalie of Unisys,
+   that the ACPI MADT (Multiple APIC Description Tables) marks those possible
+   CPUs in a system with disabled status.
+
+   Andi implemented some simple heuristics that count the number of disabled
+   CPUs in MADT as hotpluggable CPUS.  In the case there are no disabled CPUS
+   we assume 1/2 the number of CPUs currently present can be hotplugged.
+
+   Caveat: Today's ACPI MADT can only provide 256 entries since the apicid field
+   in MADT is only 8 bits.
+
+User Space Notification
+
+Hotplug support for devices is common in Linux today. Its being used today to
+support automatic configuration of network, usb and pci devices. A hotplug
+event can be used to invoke an agent script to perform the configuration task.
+
+You can add /etc/hotplug/cpu.agent to handle hotplug notification user space
+scripts.
+
+	#!/bin/bash
+	# $Id: cpu.agent
+	# Kernel hotplug params include:
+	#ACTION=%s [online or offline]
+	#DEVPATH=%s
+	#
+	cd /etc/hotplug
+	. ./hotplug.functions
+
+	case $ACTION in
+		online)
+			echo `date` ":cpu.agent" add cpu >> /tmp/hotplug.txt
+			;;
+		offline)
+			echo `date` ":cpu.agent" remove cpu >>/tmp/hotplug.txt
+			;;
+		*)
+			debug_mesg CPU $ACTION event not supported
+        exit 1
+        ;;
+	esac
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index a09a8eb..9e49b1c 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -14,7 +14,10 @@
   1.1 What are cpusets ?
   1.2 Why are cpusets needed ?
   1.3 How are cpusets implemented ?
-  1.4 How do I use cpusets ?
+  1.4 What are exclusive cpusets ?
+  1.5 What does notify_on_release do ?
+  1.6 What is memory_pressure ?
+  1.7 How do I use cpusets ?
 2. Usage Examples and Syntax
   2.1 Basic Usage
   2.2 Adding/removing cpus
@@ -49,29 +52,6 @@
 allocate a page on a node that is not allowed in the requesting tasks
 mems_allowed vector.
 
-If a cpuset is cpu or mem exclusive, no other cpuset, other than a direct
-ancestor or descendent, may share any of the same CPUs or Memory Nodes.
-A cpuset that is cpu exclusive has a sched domain associated with it.
-The sched domain consists of all cpus in the current cpuset that are not
-part of any exclusive child cpusets.
-This ensures that the scheduler load balacing code only balances
-against the cpus that are in the sched domain as defined above and not
-all of the cpus in the system. This removes any overhead due to
-load balancing code trying to pull tasks outside of the cpu exclusive
-cpuset only to be prevented by the tasks' cpus_allowed mask.
-
-A cpuset that is mem_exclusive restricts kernel allocations for
-page, buffer and other data commonly shared by the kernel across
-multiple users.  All cpusets, whether mem_exclusive or not, restrict
-allocations of memory for user space.  This enables configuring a
-system so that several independent jobs can share common kernel
-data, such as file system pages, while isolating each jobs user
-allocation in its own cpuset.  To do this, construct a large
-mem_exclusive cpuset to hold all the jobs, and construct child,
-non-mem_exclusive cpusets for each individual job.  Only a small
-amount of typical kernel memory, such as requests from interrupt
-handlers, is allowed to be taken outside even a mem_exclusive cpuset.
-
 User level code may create and destroy cpusets by name in the cpuset
 virtual file system, manage the attributes and permissions of these
 cpusets and which CPUs and Memory Nodes are assigned to each cpuset,
@@ -192,9 +172,15 @@
 
  - cpus: list of CPUs in that cpuset
  - mems: list of Memory Nodes in that cpuset
+ - memory_migrate flag: if set, move pages to cpusets nodes
  - cpu_exclusive flag: is cpu placement exclusive?
  - mem_exclusive flag: is memory placement exclusive?
  - tasks: list of tasks (by pid) attached to that cpuset
+ - notify_on_release flag: run /sbin/cpuset_release_agent on exit?
+ - memory_pressure: measure of how much paging pressure in cpuset
+
+In addition, the root cpuset only has the following file:
+ - memory_pressure_enabled flag: compute memory_pressure?
 
 New cpusets are created using the mkdir system call or shell
 command.  The properties of a cpuset, such as its flags, allowed
@@ -228,7 +214,108 @@
 to represent the cpuset hierarchy provides for a familiar permission
 and name space for cpusets, with a minimum of additional kernel code.
 
-1.4 How do I use cpusets ?
+
+1.4 What are exclusive cpusets ?
+--------------------------------
+
+If a cpuset is cpu or mem exclusive, no other cpuset, other than
+a direct ancestor or descendent, may share any of the same CPUs or
+Memory Nodes.
+
+A cpuset that is cpu_exclusive has a scheduler (sched) domain
+associated with it.  The sched domain consists of all CPUs in the
+current cpuset that are not part of any exclusive child cpusets.
+This ensures that the scheduler load balancing code only balances
+against the CPUs that are in the sched domain as defined above and
+not all of the CPUs in the system. This removes any overhead due to
+load balancing code trying to pull tasks outside of the cpu_exclusive
+cpuset only to be prevented by the tasks' cpus_allowed mask.
+
+A cpuset that is mem_exclusive restricts kernel allocations for
+page, buffer and other data commonly shared by the kernel across
+multiple users.  All cpusets, whether mem_exclusive or not, restrict
+allocations of memory for user space.  This enables configuring a
+system so that several independent jobs can share common kernel data,
+such as file system pages, while isolating each jobs user allocation in
+its own cpuset.  To do this, construct a large mem_exclusive cpuset to
+hold all the jobs, and construct child, non-mem_exclusive cpusets for
+each individual job.  Only a small amount of typical kernel memory,
+such as requests from interrupt handlers, is allowed to be taken
+outside even a mem_exclusive cpuset.
+
+
+1.5 What does notify_on_release do ?
+------------------------------------
+
+If the notify_on_release flag is enabled (1) in a cpuset, then whenever
+the last task in the cpuset leaves (exits or attaches to some other
+cpuset) and the last child cpuset of that cpuset is removed, then
+the kernel runs the command /sbin/cpuset_release_agent, supplying the
+pathname (relative to the mount point of the cpuset file system) of the
+abandoned cpuset.  This enables automatic removal of abandoned cpusets.
+The default value of notify_on_release in the root cpuset at system
+boot is disabled (0).  The default value of other cpusets at creation
+is the current value of their parents notify_on_release setting.
+
+
+1.6 What is memory_pressure ?
+-----------------------------
+The memory_pressure of a cpuset provides a simple per-cpuset metric
+of the rate that the tasks in a cpuset are attempting to free up in
+use memory on the nodes of the cpuset to satisfy additional memory
+requests.
+
+This enables batch managers monitoring jobs running in dedicated
+cpusets to efficiently detect what level of memory pressure that job
+is causing.
+
+This is useful both on tightly managed systems running a wide mix of
+submitted jobs, which may choose to terminate or re-prioritize jobs that
+are trying to use more memory than allowed on the nodes assigned them,
+and with tightly coupled, long running, massively parallel scientific
+computing jobs that will dramatically fail to meet required performance
+goals if they start to use more memory than allowed to them.
+
+This mechanism provides a very economical way for the batch manager
+to monitor a cpuset for signs of memory pressure.  It's up to the
+batch manager or other user code to decide what to do about it and
+take action.
+
+==> Unless this feature is enabled by writing "1" to the special file
+    /dev/cpuset/memory_pressure_enabled, the hook in the rebalance
+    code of __alloc_pages() for this metric reduces to simply noticing
+    that the cpuset_memory_pressure_enabled flag is zero.  So only
+    systems that enable this feature will compute the metric.
+
+Why a per-cpuset, running average:
+
+    Because this meter is per-cpuset, rather than per-task or mm,
+    the system load imposed by a batch scheduler monitoring this
+    metric is sharply reduced on large systems, because a scan of
+    the tasklist can be avoided on each set of queries.
+
+    Because this meter is a running average, instead of an accumulating
+    counter, a batch scheduler can detect memory pressure with a
+    single read, instead of having to read and accumulate results
+    for a period of time.
+
+    Because this meter is per-cpuset rather than per-task or mm,
+    the batch scheduler can obtain the key information, memory
+    pressure in a cpuset, with a single read, rather than having to
+    query and accumulate results over all the (dynamically changing)
+    set of tasks in the cpuset.
+
+A per-cpuset simple digital filter (requires a spinlock and 3 words
+of data per-cpuset) is kept, and updated by any task attached to that
+cpuset, if it enters the synchronous (direct) page reclaim code.
+
+A per-cpuset file provides an integer number representing the recent
+(half-life of 10 seconds) rate of direct page reclaims caused by
+the tasks in the cpuset, in units of reclaims attempted per second,
+times 1000.
+
+
+1.7 How do I use cpusets ?
 --------------------------
 
 In order to minimize the impact of cpusets on critical kernel
@@ -277,6 +364,30 @@
 impacting the scheduler code in the kernel with a check for changes
 in a tasks processor placement.
 
+Normally, once a page is allocated (given a physical page
+of main memory) then that page stays on whatever node it
+was allocated, so long as it remains allocated, even if the
+cpusets memory placement policy 'mems' subsequently changes.
+If the cpuset flag file 'memory_migrate' is set true, then when
+tasks are attached to that cpuset, any pages that task had
+allocated to it on nodes in its previous cpuset are migrated
+to the tasks new cpuset.  Depending on the implementation,
+this migration may either be done by swapping the page out,
+so that the next time the page is referenced, it will be paged
+into the tasks new cpuset, usually on the node where it was
+referenced, or this migration may be done by directly copying
+the pages from the tasks previous cpuset to the new cpuset,
+where possible to the same node, relative to the new cpuset,
+as the node that held the page, relative to the old cpuset.
+Also if 'memory_migrate' is set true, then if that cpusets
+'mems' file is modified, pages allocated to tasks in that
+cpuset, that were on nodes in the previous setting of 'mems',
+will be moved to nodes in the new setting of 'mems.'  Again,
+depending on the implementation, this might be done by swapping,
+or by direct copying.  In either case, pages that were not in
+the tasks prior cpuset, or in the cpusets prior 'mems' setting,
+will not be moved.
+
 There is an exception to the above.  If hotplug functionality is used
 to remove all the CPUs that are currently assigned to a cpuset,
 then the kernel will automatically update the cpus_allowed of all
diff --git a/Documentation/dvb/README.dvb-usb b/Documentation/dvb/README.dvb-usb
index ac0797e..46b78b7 100644
--- a/Documentation/dvb/README.dvb-usb
+++ b/Documentation/dvb/README.dvb-usb
@@ -50,12 +50,12 @@
 0. History & News:
   2005-06-30 - added support for WideView WT-220U (Thanks to Steve Chang)
   2005-05-30 - added basic isochronous support to the dvb-usb-framework
-               added support for Conexant Hybrid reference design and Nebula DigiTV USB
+	       added support for Conexant Hybrid reference design and Nebula DigiTV USB
   2005-04-17 - all dibusb devices ported to make use of the dvb-usb-framework
   2005-04-02 - re-enabled and improved remote control code.
   2005-03-31 - ported the Yakumo/Hama/Typhoon DVB-T USB2.0 device to dvb-usb.
   2005-03-30 - first commit of the dvb-usb-module based on the dibusb-source. First device is a new driver for the
-               TwinhanDTV Alpha / MagicBox II USB2.0-only DVB-T device.
+	       TwinhanDTV Alpha / MagicBox II USB2.0-only DVB-T device.
 
   (change from dvb-dibusb to dvb-usb)
   2005-03-28 - added support for the AVerMedia AverTV DVB-T USB2.0 device (Thanks to Glen Harris and Jiun-Kuei Jung, AVerMedia)
@@ -64,50 +64,50 @@
   2005-02-02 - added support for the Hauppauge Win-TV Nova-T USB2
   2005-01-31 - distorted streaming is gone for USB1.1 devices
   2005-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb
-             - first almost working version for HanfTek UMT-010
-             - found out, that Yakumo/HAMA/Typhoon are predecessors of the HanfTek UMT-010
+	     - first almost working version for HanfTek UMT-010
+	     - found out, that Yakumo/HAMA/Typhoon are predecessors of the HanfTek UMT-010
   2005-01-10 - refactoring completed, now everything is very delightful
-             - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
-               Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich.
+	     - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a
+	       Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich.
   2004-12-29 - after several days of struggling around bug of no returning URBs fixed.
   2004-12-26 - refactored the dibusb-driver, splitted into separate files
-             - i2c-probing enabled
+	     - i2c-probing enabled
   2004-12-06 - possibility for demod i2c-address probing
-             - new usb IDs (Compro, Artec)
+	     - new usb IDs (Compro, Artec)
   2004-11-23 - merged changes from DiB3000MC_ver2.1
-             - revised the debugging
-             - possibility to deliver the complete TS for USB2.0
+	     - revised the debugging
+	     - possibility to deliver the complete TS for USB2.0
   2004-11-21 - first working version of the dib3000mc/p frontend driver.
   2004-11-12 - added additional remote control keys. Thanks to Uwe Hanke.
   2004-11-07 - added remote control support. Thanks to David Matthews.
   2004-11-05 - added support for a new devices (Grandtec/Avermedia/Artec)
-             - merged my changes (for dib3000mb/dibusb) to the FE_REFACTORING, because it became HEAD
-             - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems
-               better settled there (added xfer_ops-struct)
-             - created a common files for frontends (mc/p/mb)
+	     - merged my changes (for dib3000mb/dibusb) to the FE_REFACTORING, because it became HEAD
+	     - moved transfer control (pid filter, fifo control) from usb driver to frontend, it seems
+	       better settled there (added xfer_ops-struct)
+	     - created a common files for frontends (mc/p/mb)
   2004-09-28 - added support for a new device (Unkown, vendor ID is Hyper-Paltek)
   2004-09-20 - added support for a new device (Compro DVB-U2000), thanks
-               to Amaury Demol for reporting
-             - changed usb TS transfer method (several urbs, stopping transfer
-               before setting a new pid)
+	       to Amaury Demol for reporting
+	     - changed usb TS transfer method (several urbs, stopping transfer
+	       before setting a new pid)
   2004-09-13 - added support for a new device (Artec T1 USB TVBOX), thanks
-               to Christian Motschke for reporting
+	       to Christian Motschke for reporting
   2004-09-05 - released the dibusb device and dib3000mb-frontend driver
 
   (old news for vp7041.c)
   2004-07-15 - found out, by accident, that the device has a TUA6010XS for
-               PLL
+	       PLL
   2004-07-12 - figured out, that the driver should also work with the
-               CTS Portable (Chinese Television System)
+	       CTS Portable (Chinese Television System)
   2004-07-08 - firmware-extraction-2.422-problem solved, driver is now working
-               properly with firmware extracted from 2.422
-             - #if for 2.6.4 (dvb), compile issue
-             - changed firmware handling, see vp7041.txt sec 1.1
+	       properly with firmware extracted from 2.422
+	     - #if for 2.6.4 (dvb), compile issue
+	     - changed firmware handling, see vp7041.txt sec 1.1
   2004-07-02 - some tuner modifications, v0.1, cleanups, first public
   2004-06-28 - now using the dvb_dmx_swfilter_packets, everything
-               runs fine now
+	       runs fine now
   2004-06-27 - able to watch and switching channels (pre-alpha)
-             - no section filtering yet
+	     - no section filtering yet
   2004-06-06 - first TS received, but kernel oops :/
   2004-05-14 - firmware loader is working
   2004-05-11 - start writing the driver
diff --git a/Documentation/dvb/README.flexcop b/Documentation/dvb/README.flexcop
index a50c70f..5515469 100644
--- a/Documentation/dvb/README.flexcop
+++ b/Documentation/dvb/README.flexcop
@@ -174,7 +174,7 @@
 Everything which is identical in the following table, can be put into a common
 flexcop-module.
 
-                  PCI                  USB
+		  PCI                  USB
 -------------------------------------------------------------------------------
 Different:
 Register access:  accessing IO memory  USB control message
diff --git a/Documentation/dvb/avermedia.txt b/Documentation/dvb/avermedia.txt
index 09020eb..2dc260b 100644
--- a/Documentation/dvb/avermedia.txt
+++ b/Documentation/dvb/avermedia.txt
@@ -1,6 +1,6 @@
 
 HOWTO: Get An Avermedia DVB-T working under Linux
-           ______________________________________________
+	   ______________________________________________
 
    Table of Contents
    Assumptions and Introduction
diff --git a/Documentation/dvb/cards.txt b/Documentation/dvb/cards.txt
index 19329cf..9e10092 100644
--- a/Documentation/dvb/cards.txt
+++ b/Documentation/dvb/cards.txt
@@ -16,7 +16,7 @@
   shielding, and the whole metal box has its own part number.
 
 
-o Frontends drivers: 
+o Frontends drivers:
   - dvb_dummy_fe: for testing...
   DVB-S:
    - ves1x93		: Alps BSRV2 (ves1893 demodulator) and dbox2 (ves1993)
@@ -24,7 +24,7 @@
    - grundig_29504-491	: Grundig 29504-491 (Philips TDA8083 demodulator), tsa5522 PLL
    - mt312		: Zarlink mt312 or Mitel vp310 demodulator, sl1935 or tsa5059 PLL
    - stv0299		: Alps BSRU6 (tsa5059 PLL), LG TDQB-S00x (tsa5059 PLL),
-   			  LG TDQF-S001F (sl1935 PLL), Philips SU1278 (tua6100 PLL), 
+			  LG TDQF-S001F (sl1935 PLL), Philips SU1278 (tua6100 PLL),
 			  Philips SU1278SH (tsa5059 PLL), Samsung TBMU24112IMB
   DVB-C:
    - ves1820		: various (ves1820 demodulator, sp5659c or spXXXX PLL)
@@ -35,8 +35,8 @@
    - grundig_29504-401	: Grundig 29504-401 (LSI L64781 demodulator), tsa5060 PLL
    - tda1004x		: Philips tda10045h (td1344 or tdm1316l PLL)
    - nxt6000 		: Alps TDME7 (MITEL SP5659 PLL), Alps TDED4 (TI ALP510 PLL),
-               		  Comtech DVBT-6k07 (SP5730 PLL)
-               		  (NxtWave Communications NXT6000 demodulator)
+			  Comtech DVBT-6k07 (SP5730 PLL)
+			  (NxtWave Communications NXT6000 demodulator)
    - sp887x		: Microtune 7202D
    - dib3000mb	: DiBcom 3000-MB demodulator
   DVB-S/C/T:
diff --git a/Documentation/dvb/contributors.txt b/Documentation/dvb/contributors.txt
index 2cbd2d0..4c33cce 100644
--- a/Documentation/dvb/contributors.txt
+++ b/Documentation/dvb/contributors.txt
@@ -15,7 +15,7 @@
 
 Diego Picciani <d.picciani@novacomp.it>
   for CyberLogin for Linux which allows logging onto EON
-  (in case you are wondering where CyberLogin is, EON changed its login 
+  (in case you are wondering where CyberLogin is, EON changed its login
   procedure and CyberLogin is no longer used.)
 
 Martin Schaller <martin@smurf.franken.de>
@@ -57,7 +57,7 @@
 Davor Emard <emard@softhome.net>
   for his work on the budget drivers, the demux code,
   the module unloading problems, ...
-  
+
 Hans-Frieder Vogt <hfvogt@arcor.de>
   for his work on calculating and checking the crc's for the
   TechnoTrend/Hauppauge DEC driver firmware
diff --git a/Documentation/dvb/readme.txt b/Documentation/dvb/readme.txt
index 754c98c..f5c50b2 100644
--- a/Documentation/dvb/readme.txt
+++ b/Documentation/dvb/readme.txt
@@ -20,7 +20,7 @@
 
 What's inside this directory:
 
-"cards.txt" 
+"cards.txt"
 contains a list of supported hardware.
 
 "contributors.txt"
@@ -37,7 +37,7 @@
 contains detailed informations about the
 TT DEC2000/DEC3000 USB DVB hardware.
 
-"bt8xx.txt" 
+"bt8xx.txt"
 contains detailed installation instructions for the
 various bt8xx based "budget" DVB cards
 (Nebula, Pinnacle PCTV, Twinhan DST)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 9b74319..9474501 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -47,17 +47,6 @@
 
 ---------------------------
 
-What:	IEEE1394 Audio and Music Data Transmission Protocol driver,
-	Connection Management Procedures driver
-When:	November 2005
-Files:	drivers/ieee1394/{amdtp,cmp}*
-Why:	These are incomplete, have never worked, and are better implemented
-	in userland via raw1394 (see http://freebob.sourceforge.net/ for
-	example.)
-Who:	Jody McIntyre <scjody@steamballoon.com>
-
----------------------------
-
 What:	raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
 When:	November 2005
 Why:	Deprecated in favour of the new ioctl-based rawiso interface, which is
@@ -82,15 +71,6 @@
 
 ---------------------------
 
-What:	i2c sysfs name change: in1_ref, vid deprecated in favour of cpu0_vid
-When:	November 2005
-Files:	drivers/i2c/chips/adm1025.c, drivers/i2c/chips/adm1026.c
-Why:	Match the other drivers' name for the same function, duplicate names
-	will be available until removal of old names.
-Who:	Grant Coady <gcoady@gmail.com>
-
----------------------------
-
 What:	remove EXPORT_SYMBOL(panic_timeout)
 When:	April 2006
 Files:	kernel/panic.c
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
index bcfbab8..74052d2 100644
--- a/Documentation/filesystems/00-INDEX
+++ b/Documentation/filesystems/00-INDEX
@@ -12,14 +12,16 @@
 	- description of the CIFS filesystem
 coda.txt
 	- description of the CODA filesystem.
+configfs/
+	- directory containing configfs documentation and example code.
 cramfs.txt
 	- info on the cram filesystem for small storage (ROMs etc)
 devfs/
 	- directory containing devfs documentation.
+dlmfs.txt
+	- info on the userspace interface to the OCFS2 DLM.
 ext2.txt
 	- info, mount options and specifications for the Ext2 filesystem.
-fat_cvf.txt
-	- info on the Compressed Volume Files extension to the FAT filesystem
 hpfs.txt
 	- info and mount options for the OS/2 HPFS.
 isofs.txt
@@ -32,6 +34,8 @@
 	- info and mount options for the NTFS filesystem (Windows NT).
 proc.txt
 	- info on Linux's /proc filesystem.
+ocfs2.txt
+	- info and mount options for the OCFS2 clustered filesystem.
 romfs.txt
 	- Description of the ROMFS filesystem.
 smbfs.txt
diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt
new file mode 100644
index 0000000..c4ff96b
--- /dev/null
+++ b/Documentation/filesystems/configfs/configfs.txt
@@ -0,0 +1,434 @@
+
+configfs - Userspace-driven kernel object configuation.
+
+Joel Becker <joel.becker@oracle.com>
+
+Updated: 31 March 2005
+
+Copyright (c) 2005 Oracle Corporation,
+	Joel Becker <joel.becker@oracle.com>
+
+
+[What is configfs?]
+
+configfs is a ram-based filesystem that provides the converse of
+sysfs's functionality.  Where sysfs is a filesystem-based view of
+kernel objects, configfs is a filesystem-based manager of kernel
+objects, or config_items.
+
+With sysfs, an object is created in kernel (for example, when a device
+is discovered) and it is registered with sysfs.  Its attributes then
+appear in sysfs, allowing userspace to read the attributes via
+readdir(3)/read(2).  It may allow some attributes to be modified via
+write(2).  The important point is that the object is created and
+destroyed in kernel, the kernel controls the lifecycle of the sysfs
+representation, and sysfs is merely a window on all this.
+
+A configfs config_item is created via an explicit userspace operation:
+mkdir(2).  It is destroyed via rmdir(2).  The attributes appear at
+mkdir(2) time, and can be read or modified via read(2) and write(2).
+As with sysfs, readdir(3) queries the list of items and/or attributes.
+symlink(2) can be used to group items together.  Unlike sysfs, the
+lifetime of the representation is completely driven by userspace.  The
+kernel modules backing the items must respond to this.
+
+Both sysfs and configfs can and should exist together on the same
+system.  One is not a replacement for the other.
+
+[Using configfs]
+
+configfs can be compiled as a module or into the kernel.  You can access
+it by doing
+
+	mount -t configfs none /config
+
+The configfs tree will be empty unless client modules are also loaded.
+These are modules that register their item types with configfs as
+subsystems.  Once a client subsystem is loaded, it will appear as a
+subdirectory (or more than one) under /config.  Like sysfs, the
+configfs tree is always there, whether mounted on /config or not.
+
+An item is created via mkdir(2).  The item's attributes will also
+appear at this time.  readdir(3) can determine what the attributes are,
+read(2) can query their default values, and write(2) can store new
+values.  Like sysfs, attributes should be ASCII text files, preferably
+with only one value per file.  The same efficiency caveats from sysfs
+apply.  Don't mix more than one attribute in one attribute file.
+
+Like sysfs, configfs expects write(2) to store the entire buffer at
+once.  When writing to configfs attributes, userspace processes should
+first read the entire file, modify the portions they wish to change, and
+then write the entire buffer back.  Attribute files have a maximum size
+of one page (PAGE_SIZE, 4096 on i386).
+
+When an item needs to be destroyed, remove it with rmdir(2).  An
+item cannot be destroyed if any other item has a link to it (via
+symlink(2)).  Links can be removed via unlink(2).
+
+[Configuring FakeNBD: an Example]
+
+Imagine there's a Network Block Device (NBD) driver that allows you to
+access remote block devices.  Call it FakeNBD.  FakeNBD uses configfs
+for its configuration.  Obviously, there will be a nice program that
+sysadmins use to configure FakeNBD, but somehow that program has to tell
+the driver about it.  Here's where configfs comes in.
+
+When the FakeNBD driver is loaded, it registers itself with configfs.
+readdir(3) sees this just fine:
+
+	# ls /config
+	fakenbd
+
+A fakenbd connection can be created with mkdir(2).  The name is
+arbitrary, but likely the tool will make some use of the name.  Perhaps
+it is a uuid or a disk name:
+
+	# mkdir /config/fakenbd/disk1
+	# ls /config/fakenbd/disk1
+	target device rw
+
+The target attribute contains the IP address of the server FakeNBD will
+connect to.  The device attribute is the device on the server.
+Predictably, the rw attribute determines whether the connection is
+read-only or read-write.
+
+	# echo 10.0.0.1 > /config/fakenbd/disk1/target
+	# echo /dev/sda1 > /config/fakenbd/disk1/device
+	# echo 1 > /config/fakenbd/disk1/rw
+
+That's it.  That's all there is.  Now the device is configured, via the
+shell no less.
+
+[Coding With configfs]
+
+Every object in configfs is a config_item.  A config_item reflects an
+object in the subsystem.  It has attributes that match values on that
+object.  configfs handles the filesystem representation of that object
+and its attributes, allowing the subsystem to ignore all but the
+basic show/store interaction.
+
+Items are created and destroyed inside a config_group.  A group is a
+collection of items that share the same attributes and operations.
+Items are created by mkdir(2) and removed by rmdir(2), but configfs
+handles that.  The group has a set of operations to perform these tasks
+
+A subsystem is the top level of a client module.  During initialization,
+the client module registers the subsystem with configfs, the subsystem
+appears as a directory at the top of the configfs filesystem.  A
+subsystem is also a config_group, and can do everything a config_group
+can.
+
+[struct config_item]
+
+	struct config_item {
+		char                    *ci_name;
+		char                    ci_namebuf[UOBJ_NAME_LEN];
+		struct kref             ci_kref;
+		struct list_head        ci_entry;
+		struct config_item      *ci_parent;
+		struct config_group     *ci_group;
+		struct config_item_type *ci_type;
+		struct dentry           *ci_dentry;
+	};
+
+	void config_item_init(struct config_item *);
+	void config_item_init_type_name(struct config_item *,
+					const char *name,
+					struct config_item_type *type);
+	struct config_item *config_item_get(struct config_item *);
+	void config_item_put(struct config_item *);
+
+Generally, struct config_item is embedded in a container structure, a
+structure that actually represents what the subsystem is doing.  The
+config_item portion of that structure is how the object interacts with
+configfs.
+
+Whether statically defined in a source file or created by a parent
+config_group, a config_item must have one of the _init() functions
+called on it.  This initializes the reference count and sets up the
+appropriate fields.
+
+All users of a config_item should have a reference on it via
+config_item_get(), and drop the reference when they are done via
+config_item_put().
+
+By itself, a config_item cannot do much more than appear in configfs.
+Usually a subsystem wants the item to display and/or store attributes,
+among other things.  For that, it needs a type.
+
+[struct config_item_type]
+
+	struct configfs_item_operations {
+		void (*release)(struct config_item *);
+		ssize_t (*show_attribute)(struct config_item *,
+					  struct configfs_attribute *,
+					  char *);
+		ssize_t (*store_attribute)(struct config_item *,
+					   struct configfs_attribute *,
+					   const char *, size_t);
+		int (*allow_link)(struct config_item *src,
+				  struct config_item *target);
+		int (*drop_link)(struct config_item *src,
+				 struct config_item *target);
+	};
+
+	struct config_item_type {
+		struct module                           *ct_owner;
+		struct configfs_item_operations         *ct_item_ops;
+		struct configfs_group_operations        *ct_group_ops;
+		struct configfs_attribute               **ct_attrs;
+	};
+
+The most basic function of a config_item_type is to define what
+operations can be performed on a config_item.  All items that have been
+allocated dynamically will need to provide the ct_item_ops->release()
+method.  This method is called when the config_item's reference count
+reaches zero.  Items that wish to display an attribute need to provide
+the ct_item_ops->show_attribute() method.  Similarly, storing a new
+attribute value uses the store_attribute() method.
+
+[struct configfs_attribute]
+
+	struct configfs_attribute {
+		char                    *ca_name;
+		struct module           *ca_owner;
+		mode_t                  ca_mode;
+	};
+
+When a config_item wants an attribute to appear as a file in the item's
+configfs directory, it must define a configfs_attribute describing it.
+It then adds the attribute to the NULL-terminated array
+config_item_type->ct_attrs.  When the item appears in configfs, the
+attribute file will appear with the configfs_attribute->ca_name
+filename.  configfs_attribute->ca_mode specifies the file permissions.
+
+If an attribute is readable and the config_item provides a
+ct_item_ops->show_attribute() method, that method will be called
+whenever userspace asks for a read(2) on the attribute.  The converse
+will happen for write(2).
+
+[struct config_group]
+
+A config_item cannot live in a vaccum.  The only way one can be created
+is via mkdir(2) on a config_group.  This will trigger creation of a
+child item.
+
+	struct config_group {
+		struct config_item		cg_item;
+		struct list_head		cg_children;
+		struct configfs_subsystem 	*cg_subsys;
+		struct config_group		**default_groups;
+	};
+
+	void config_group_init(struct config_group *group);
+	void config_group_init_type_name(struct config_group *group,
+					 const char *name,
+					 struct config_item_type *type);
+
+
+The config_group structure contains a config_item.  Properly configuring
+that item means that a group can behave as an item in its own right.
+However, it can do more: it can create child items or groups.  This is
+accomplished via the group operations specified on the group's
+config_item_type.
+
+	struct configfs_group_operations {
+		struct config_item *(*make_item)(struct config_group *group,
+						 const char *name);
+		struct config_group *(*make_group)(struct config_group *group,
+						   const char *name);
+		int (*commit_item)(struct config_item *item);
+		void (*drop_item)(struct config_group *group,
+				  struct config_item *item);
+	};
+
+A group creates child items by providing the
+ct_group_ops->make_item() method.  If provided, this method is called from mkdir(2) in the group's directory.  The subsystem allocates a new
+config_item (or more likely, its container structure), initializes it,
+and returns it to configfs.  Configfs will then populate the filesystem
+tree to reflect the new item.
+
+If the subsystem wants the child to be a group itself, the subsystem
+provides ct_group_ops->make_group().  Everything else behaves the same,
+using the group _init() functions on the group.
+
+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.
+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
+config_item_put() on the item on behalf of the subsystem.
+
+IMPORTANT: drop_item() is void, and as such cannot fail.  When rmdir(2)
+is called, configfs WILL remove the item from the filesystem tree
+(assuming that it has no children to keep it busy).  The subsystem is
+responsible for responding to this.  If the subsystem has references to
+the item in other threads, the memory is safe.  It may take some time
+for the item to actually disappear from the subsystem's usage.  But it
+is gone from configfs.
+
+A config_group cannot be removed while it still has child items.  This
+is implemented in the configfs rmdir(2) code.  ->drop_item() will not be
+called, as the item has not been dropped.  rmdir(2) will fail, as the
+directory is not empty.
+
+[struct configfs_subsystem]
+
+A subsystem must register itself, ususally at module_init time.  This
+tells configfs to make the subsystem appear in the file tree.
+
+	struct configfs_subsystem {
+		struct config_group	su_group;
+		struct semaphore	su_sem;
+	};
+
+	int configfs_register_subsystem(struct configfs_subsystem *subsys);
+	void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
+
+	A subsystem consists of a toplevel config_group and a semaphore.
+The group is where child config_items are created.  For a subsystem,
+this group is usually defined statically.  Before calling
+configfs_register_subsystem(), the subsystem must have initialized the
+group via the usual group _init() functions, and it must also have
+initialized the semaphore.
+	When the register call returns, the subsystem is live, and it
+will be visible via configfs.  At that point, mkdir(2) can be called and
+the subsystem must be ready for it.
+
+[An Example]
+
+The best example of these basic concepts is the simple_children
+subsystem/group and the simple_child item in configfs_example.c  It
+shows a trivial object displaying and storing an attribute, and a simple
+group creating and destroying these children.
+
+[Hierarchy Navigation and the Subsystem Semaphore]
+
+There is an extra bonus that configfs provides.  The config_groups and
+config_items are arranged in a hierarchy due to the fact that they
+appear in a filesystem.  A subsystem is NEVER to touch the filesystem
+parts, but the subsystem might be interested in this hierarchy.  For
+this reason, the hierarchy is mirrored via the config_group->cg_children
+and config_item->ci_parent structure members.
+
+A subsystem can navigate the cg_children list and the ci_parent pointer
+to see the tree created by the subsystem.  This can race with configfs'
+management of the hierarchy, so configfs uses the subsystem semaphore to
+protect modifications.  Whenever a subsystem wants to navigate the
+hierarchy, it must do so under the protection of the subsystem
+semaphore.
+
+A subsystem will be prevented from acquiring the semaphore while a newly
+allocated item has not been linked into this hierarchy.   Similarly, it
+will not be able to acquire the semaphore while a dropping item has not
+yet been unlinked.  This means that an item's ci_parent pointer will
+never be NULL while the item is in configfs, and that an item will only
+be in its parent's cg_children list for the same duration.  This allows
+a subsystem to trust ci_parent and cg_children while they hold the
+semaphore.
+
+[Item Aggregation Via symlink(2)]
+
+configfs provides a simple group via the group->item parent/child
+relationship.  Often, however, a larger environment requires aggregation
+outside of the parent/child connection.  This is implemented via
+symlink(2).
+
+A config_item may provide the ct_item_ops->allow_link() and
+ct_item_ops->drop_link() methods.  If the ->allow_link() method exists,
+symlink(2) may be called with the config_item as the source of the link.
+These links are only allowed between configfs config_items.  Any
+symlink(2) attempt outside the configfs filesystem will be denied.
+
+When symlink(2) is called, the source config_item's ->allow_link()
+method is called with itself and a target item.  If the source item
+allows linking to target item, it returns 0.  A source item may wish to
+reject a link if it only wants links to a certain type of object (say,
+in its own subsystem).
+
+When unlink(2) is called on the symbolic link, the source item is
+notified via the ->drop_link() method.  Like the ->drop_item() method,
+this is a void function and cannot return failure.  The subsystem is
+responsible for responding to the change.
+
+A config_item cannot be removed while it links to any other item, nor
+can it be removed while an item links to it.  Dangling symlinks are not
+allowed in configfs.
+
+[Automatically Created Subgroups]
+
+A new config_group may want to have two types of child config_items.
+While this could be codified by magic names in ->make_item(), it is much
+more explicit to have a method whereby userspace sees this divergence.
+
+Rather than have a group where some items behave differently than
+others, configfs provides a method whereby one or many subgroups are
+automatically created inside the parent at its creation.  Thus,
+mkdir("parent) results in "parent", "parent/subgroup1", up through
+"parent/subgroupN".  Items of type 1 can now be created in
+"parent/subgroup1", and items of type N can be created in
+"parent/subgroupN".
+
+These automatic subgroups, or default groups, do not preclude other
+children of the parent group.  If ct_group_ops->make_group() exists,
+other child groups can be created on the parent group directly.
+
+A configfs subsystem specifies default groups by filling in the
+NULL-terminated array default_groups on the config_group structure.
+Each group in that array is populated in the configfs tree at the same
+time as the parent group.  Similarly, they are removed at the same time
+as the parent.  No extra notification is provided.  When a ->drop_item()
+method call notifies the subsystem the parent group is going away, it
+also means every default group child associated with that parent group.
+
+As a consequence of this, default_groups cannot be removed directly via
+rmdir(2).  They also are not considered when rmdir(2) on the parent
+group is checking for children.
+
+[Committable Items]
+
+NOTE: Committable items are currently unimplemented.
+
+Some config_items cannot have a valid initial state.  That is, no
+default values can be specified for the item's attributes such that the
+item can do its work.  Userspace must configure one or more attributes,
+after which the subsystem can start whatever entity this item
+represents.
+
+Consider the FakeNBD device from above.  Without a target address *and*
+a target device, the subsystem has no idea what block device to import.
+The simple example assumes that the subsystem merely waits until all the
+appropriate attributes are configured, and then connects.  This will,
+indeed, work, but now every attribute store must check if the attributes
+are initialized.  Every attribute store must fire off the connection if
+that condition is met.
+
+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
+initialized in a way that makes sense.  configfs provides this as
+committable items.
+
+configfs still uses only normal filesystem operations.  An item is
+committed via rename(2).  The item is moved from a directory where it
+can be modified to a directory where it cannot.
+
+Any group that provides the ct_group_ops->commit_item() method has
+committable items.  When this group appears in configfs, mkdir(2) will
+not work directly in the group.  Instead, the group will have two
+subdirectories: "live" and "pending".  The "live" directory does not
+support mkdir(2) or rmdir(2) either.  It only allows rename(2).  The
+"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()
+callback.  If all required attributes are filled to satisfaction, the
+method returns zero and the item is moved to the "live" directory.
+
+As rmdir(2) does not work in the "live" directory, an item must be
+shutdown, or "uncommitted".  Again, this is done via rename(2), this
+time from the "live" directory back to the "pending" one.  The subsystem
+is notified by the ct_group_ops->uncommit_object() method.
+
+
diff --git a/Documentation/filesystems/configfs/configfs_example.c b/Documentation/filesystems/configfs/configfs_example.c
new file mode 100644
index 0000000..f3c6e49
--- /dev/null
+++ b/Documentation/filesystems/configfs/configfs_example.c
@@ -0,0 +1,474 @@
+/*
+ * vim: noexpandtab ts=8 sts=0 sw=8:
+ *
+ * configfs_example.c - This file is a demonstration module containing
+ *      a number of configfs subsystems.
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <linux/configfs.h>
+
+
+
+/*
+ * 01-childless
+ *
+ * This first example is a childless subsystem.  It cannot create
+ * any config_items.  It just has attributes.
+ *
+ * Note that we are enclosing the configfs_subsystem inside a container.
+ * This is not necessary if a subsystem has no attributes directly
+ * on the subsystem.  See the next example, 02-simple-children, for
+ * such a subsystem.
+ */
+
+struct childless {
+	struct configfs_subsystem subsys;
+	int showme;
+	int storeme;
+};
+
+struct childless_attribute {
+	struct configfs_attribute attr;
+	ssize_t (*show)(struct childless *, char *);
+	ssize_t (*store)(struct childless *, const char *, size_t);
+};
+
+static inline struct childless *to_childless(struct config_item *item)
+{
+	return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL;
+}
+
+static ssize_t childless_showme_read(struct childless *childless,
+				     char *page)
+{
+	ssize_t pos;
+
+	pos = sprintf(page, "%d\n", childless->showme);
+	childless->showme++;
+
+	return pos;
+}
+
+static ssize_t childless_storeme_read(struct childless *childless,
+				      char *page)
+{
+	return sprintf(page, "%d\n", childless->storeme);
+}
+
+static ssize_t childless_storeme_write(struct childless *childless,
+				       const char *page,
+				       size_t count)
+{
+	unsigned long tmp;
+	char *p = (char *) page;
+
+	tmp = simple_strtoul(p, &p, 10);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	if (tmp > INT_MAX)
+		return -ERANGE;
+
+	childless->storeme = tmp;
+
+	return count;
+}
+
+static ssize_t childless_description_read(struct childless *childless,
+					  char *page)
+{
+	return sprintf(page,
+"[01-childless]\n"
+"\n"
+"The childless subsystem is the simplest possible subsystem in\n"
+"configfs.  It does not support the creation of child config_items.\n"
+"It only has a few attributes.  In fact, it isn't much different\n"
+"than a directory in /proc.\n");
+}
+
+static struct childless_attribute childless_attr_showme = {
+	.attr	= { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO },
+	.show	= childless_showme_read,
+};
+static struct childless_attribute childless_attr_storeme = {
+	.attr	= { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= childless_storeme_read,
+	.store	= childless_storeme_write,
+};
+static struct childless_attribute childless_attr_description = {
+	.attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO },
+	.show = childless_description_read,
+};
+
+static struct configfs_attribute *childless_attrs[] = {
+	&childless_attr_showme.attr,
+	&childless_attr_storeme.attr,
+	&childless_attr_description.attr,
+	NULL,
+};
+
+static ssize_t childless_attr_show(struct config_item *item,
+				   struct configfs_attribute *attr,
+				   char *page)
+{
+	struct childless *childless = to_childless(item);
+	struct childless_attribute *childless_attr =
+		container_of(attr, struct childless_attribute, attr);
+	ssize_t ret = 0;
+
+	if (childless_attr->show)
+		ret = childless_attr->show(childless, page);
+	return ret;
+}
+
+static ssize_t childless_attr_store(struct config_item *item,
+				    struct configfs_attribute *attr,
+				    const char *page, size_t count)
+{
+	struct childless *childless = to_childless(item);
+	struct childless_attribute *childless_attr =
+		container_of(attr, struct childless_attribute, attr);
+	ssize_t ret = -EINVAL;
+
+	if (childless_attr->store)
+		ret = childless_attr->store(childless, page, count);
+	return ret;
+}
+
+static struct configfs_item_operations childless_item_ops = {
+	.show_attribute		= childless_attr_show,
+	.store_attribute	= childless_attr_store,
+};
+
+static struct config_item_type childless_type = {
+	.ct_item_ops	= &childless_item_ops,
+	.ct_attrs	= childless_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+static struct childless childless_subsys = {
+	.subsys = {
+		.su_group = {
+			.cg_item = {
+				.ci_namebuf = "01-childless",
+				.ci_type = &childless_type,
+			},
+		},
+	},
+};
+
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * 02-simple-children
+ *
+ * This example merely has a simple one-attribute child.  Note that
+ * there is no extra attribute structure, as the child's attribute is
+ * known from the get-go.  Also, there is no container for the
+ * subsystem, as it has no attributes of its own.
+ */
+
+struct simple_child {
+	struct config_item item;
+	int storeme;
+};
+
+static inline struct simple_child *to_simple_child(struct config_item *item)
+{
+	return item ? container_of(item, struct simple_child, item) : NULL;
+}
+
+static struct configfs_attribute simple_child_attr_storeme = {
+	.ca_owner = THIS_MODULE,
+	.ca_name = "storeme",
+	.ca_mode = S_IRUGO | S_IWUSR,
+};
+
+static struct configfs_attribute *simple_child_attrs[] = {
+	&simple_child_attr_storeme,
+	NULL,
+};
+
+static ssize_t simple_child_attr_show(struct config_item *item,
+				      struct configfs_attribute *attr,
+				      char *page)
+{
+	ssize_t count;
+	struct simple_child *simple_child = to_simple_child(item);
+
+	count = sprintf(page, "%d\n", simple_child->storeme);
+
+	return count;
+}
+
+static ssize_t simple_child_attr_store(struct config_item *item,
+				       struct configfs_attribute *attr,
+				       const char *page, size_t count)
+{
+	struct simple_child *simple_child = to_simple_child(item);
+	unsigned long tmp;
+	char *p = (char *) page;
+
+	tmp = simple_strtoul(p, &p, 10);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	if (tmp > INT_MAX)
+		return -ERANGE;
+
+	simple_child->storeme = tmp;
+
+	return count;
+}
+
+static void simple_child_release(struct config_item *item)
+{
+	kfree(to_simple_child(item));
+}
+
+static struct configfs_item_operations simple_child_item_ops = {
+	.release		= simple_child_release,
+	.show_attribute		= simple_child_attr_show,
+	.store_attribute	= simple_child_attr_store,
+};
+
+static struct config_item_type simple_child_type = {
+	.ct_item_ops	= &simple_child_item_ops,
+	.ct_attrs	= simple_child_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+
+static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
+{
+	struct simple_child *simple_child;
+
+	simple_child = kmalloc(sizeof(struct simple_child), GFP_KERNEL);
+	if (!simple_child)
+		return NULL;
+
+	memset(simple_child, 0, sizeof(struct simple_child));
+
+	config_item_init_type_name(&simple_child->item, name,
+				   &simple_child_type);
+
+	simple_child->storeme = 0;
+
+	return &simple_child->item;
+}
+
+static struct configfs_attribute simple_children_attr_description = {
+	.ca_owner = THIS_MODULE,
+	.ca_name = "description",
+	.ca_mode = S_IRUGO,
+};
+
+static struct configfs_attribute *simple_children_attrs[] = {
+	&simple_children_attr_description,
+	NULL,
+};
+
+static ssize_t simple_children_attr_show(struct config_item *item,
+			   		 struct configfs_attribute *attr,
+			   		 char *page)
+{
+	return sprintf(page,
+"[02-simple-children]\n"
+"\n"
+"This subsystem allows the creation of child config_items.  These\n"
+"items have only one attribute that is readable and writeable.\n");
+}
+
+static struct configfs_item_operations simple_children_item_ops = {
+	.show_attribute	= simple_children_attr_show,
+};
+
+/*
+ * Note that, since no extra work is required on ->drop_item(),
+ * no ->drop_item() is provided.
+ */
+static struct configfs_group_operations simple_children_group_ops = {
+	.make_item	= simple_children_make_item,
+};
+
+static struct config_item_type simple_children_type = {
+	.ct_item_ops	= &simple_children_item_ops,
+	.ct_group_ops	= &simple_children_group_ops,
+	.ct_attrs	= simple_children_attrs,
+};
+
+static struct configfs_subsystem simple_children_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf = "02-simple-children",
+			.ci_type = &simple_children_type,
+		},
+	},
+};
+
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * 03-group-children
+ *
+ * This example reuses the simple_children group from above.  However,
+ * the simple_children group is not the subsystem itself, it is a
+ * child of the subsystem.  Creation of a group in the subsystem creates
+ * a new simple_children group.  That group can then have simple_child
+ * children of its own.
+ */
+
+struct simple_children {
+	struct config_group group;
+};
+
+static struct config_group *group_children_make_group(struct config_group *group, const char *name)
+{
+	struct simple_children *simple_children;
+
+	simple_children = kmalloc(sizeof(struct simple_children),
+				  GFP_KERNEL);
+	if (!simple_children)
+		return NULL;
+
+	memset(simple_children, 0, sizeof(struct simple_children));
+
+	config_group_init_type_name(&simple_children->group, name,
+				    &simple_children_type);
+
+	return &simple_children->group;
+}
+
+static struct configfs_attribute group_children_attr_description = {
+	.ca_owner = THIS_MODULE,
+	.ca_name = "description",
+	.ca_mode = S_IRUGO,
+};
+
+static struct configfs_attribute *group_children_attrs[] = {
+	&group_children_attr_description,
+	NULL,
+};
+
+static ssize_t group_children_attr_show(struct config_item *item,
+			   		struct configfs_attribute *attr,
+			   		char *page)
+{
+	return sprintf(page,
+"[03-group-children]\n"
+"\n"
+"This subsystem allows the creation of child config_groups.  These\n"
+"groups are like the subsystem simple-children.\n");
+}
+
+static struct configfs_item_operations group_children_item_ops = {
+	.show_attribute	= group_children_attr_show,
+};
+
+/*
+ * Note that, since no extra work is required on ->drop_item(),
+ * no ->drop_item() is provided.
+ */
+static struct configfs_group_operations group_children_group_ops = {
+	.make_group	= group_children_make_group,
+};
+
+static struct config_item_type group_children_type = {
+	.ct_item_ops	= &group_children_item_ops,
+	.ct_group_ops	= &group_children_group_ops,
+	.ct_attrs	= group_children_attrs,
+};
+
+static struct configfs_subsystem group_children_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf = "03-group-children",
+			.ci_type = &group_children_type,
+		},
+	},
+};
+
+/* ----------------------------------------------------------------- */
+
+/*
+ * We're now done with our subsystem definitions.
+ * For convenience in this module, here's a list of them all.  It
+ * allows the init function to easily register them.  Most modules
+ * will only have one subsystem, and will only call register_subsystem
+ * on it directly.
+ */
+static struct configfs_subsystem *example_subsys[] = {
+	&childless_subsys.subsys,
+	&simple_children_subsys,
+	&group_children_subsys,
+	NULL,
+};
+
+static int __init configfs_example_init(void)
+{
+	int ret;
+	int i;
+	struct configfs_subsystem *subsys;
+
+	for (i = 0; example_subsys[i]; i++) {
+		subsys = example_subsys[i];
+
+		config_group_init(&subsys->su_group);
+		init_MUTEX(&subsys->su_sem);
+		ret = configfs_register_subsystem(subsys);
+		if (ret) {
+			printk(KERN_ERR "Error %d while registering subsystem %s\n",
+			       ret,
+			       subsys->su_group.cg_item.ci_namebuf);
+			goto out_unregister;
+		}
+	}
+
+	return 0;
+
+out_unregister:
+	for (; i >= 0; i--) {
+		configfs_unregister_subsystem(example_subsys[i]);
+	}
+
+	return ret;
+}
+
+static void __exit configfs_example_exit(void)
+{
+	int i;
+
+	for (i = 0; example_subsys[i]; i++) {
+		configfs_unregister_subsystem(example_subsys[i]);
+	}
+}
+
+module_init(configfs_example_init);
+module_exit(configfs_example_exit);
+MODULE_LICENSE("GPL");
diff --git a/Documentation/filesystems/dlmfs.txt b/Documentation/filesystems/dlmfs.txt
new file mode 100644
index 0000000..9afab84
--- /dev/null
+++ b/Documentation/filesystems/dlmfs.txt
@@ -0,0 +1,130 @@
+dlmfs
+==================
+A minimal DLM userspace interface implemented via a virtual file
+system.
+
+dlmfs is built with OCFS2 as it requires most of its infrastructure.
+
+Project web page:    http://oss.oracle.com/projects/ocfs2
+Tools web page:      http://oss.oracle.com/projects/ocfs2-tools
+OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
+
+All code copyright 2005 Oracle except when otherwise noted.
+
+CREDITS
+=======
+
+Some code taken from ramfs which is Copyright (C) 2000 Linus Torvalds
+and Transmeta Corp.
+
+Mark Fasheh <mark.fasheh@oracle.com>
+
+Caveats
+=======
+- Right now it only works with the OCFS2 DLM, though support for other
+  DLM implementations should not be a major issue.
+
+Mount options
+=============
+None
+
+Usage
+=====
+
+If you're just interested in OCFS2, then please see ocfs2.txt. The
+rest of this document will be geared towards those who want to use
+dlmfs for easy to setup and easy to use clustered locking in
+userspace.
+
+Setup
+=====
+
+dlmfs requires that the OCFS2 cluster infrastructure be in
+place. Please download ocfs2-tools from the above url and configure a
+cluster.
+
+You'll want to start heartbeating on a volume which all the nodes in
+your lockspace can access. The easiest way to do this is via
+ocfs2_hb_ctl (distributed with ocfs2-tools). Right now it requires
+that an OCFS2 file system be in place so that it can automatically
+find it's heartbeat area, though it will eventually support heartbeat
+against raw disks.
+
+Please see the ocfs2_hb_ctl and mkfs.ocfs2 manual pages distributed
+with ocfs2-tools.
+
+Once you're heartbeating, DLM lock 'domains' can be easily created /
+destroyed and locks within them accessed.
+
+Locking
+=======
+
+Users may access dlmfs via standard file system calls, or they can use
+'libo2dlm' (distributed with ocfs2-tools) which abstracts the file
+system calls and presents a more traditional locking api.
+
+dlmfs handles lock caching automatically for the user, so a lock
+request for an already acquired lock will not generate another DLM
+call. Userspace programs are assumed to handle their own local
+locking.
+
+Two levels of locks are supported - Shared Read, and Exlcusive.
+Also supported is a Trylock operation.
+
+For information on the libo2dlm interface, please see o2dlm.h,
+distributed with ocfs2-tools.
+
+Lock value blocks can be read and written to a resource via read(2)
+and write(2) against the fd obtained via your open(2) call. The
+maximum currently supported LVB length is 64 bytes (though that is an
+OCFS2 DLM limitation). Through this mechanism, users of dlmfs can share
+small amounts of data amongst their nodes.
+
+mkdir(2) signals dlmfs to join a domain (which will have the same name
+as the resulting directory)
+
+rmdir(2) signals dlmfs to leave the domain
+
+Locks for a given domain are represented by regular inodes inside the
+domain directory.  Locking against them is done via the open(2) system
+call.
+
+The open(2) call will not return until your lock has been granted or
+an error has occurred, unless it has been instructed to do a trylock
+operation. If the lock succeeds, you'll get an fd.
+
+open(2) with O_CREAT to ensure the resource inode is created - dlmfs does
+not automatically create inodes for existing lock resources.
+
+Open Flag     Lock Request Type
+---------     -----------------
+O_RDONLY      Shared Read
+O_RDWR        Exclusive
+
+Open Flag     Resulting Locking Behavior
+---------     --------------------------
+O_NONBLOCK    Trylock operation
+
+You must provide exactly one of O_RDONLY or O_RDWR.
+
+If O_NONBLOCK is also provided and the trylock operation was valid but
+could not lock the resource then open(2) will return ETXTBUSY.
+
+close(2) drops the lock associated with your fd.
+
+Modes passed to mkdir(2) or open(2) are adhered to locally. Chown is
+supported locally as well. This means you can use them to restrict
+access to the resources via dlmfs on your local node only.
+
+The resource LVB may be read from the fd in either Shared Read or
+Exclusive modes via the read(2) system call. It can be written via
+write(2) only when open in Exclusive mode.
+
+Once written, an LVB will be visible to other nodes who obtain Read
+Only or higher level locks on the resource.
+
+See Also
+========
+http://opendlm.sourceforge.net/cvsmirror/opendlm/docs/dlmbook_final.pdf
+
+For more information on the VMS distributed locking API.
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index 9ab7f44..22e4040 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -22,6 +22,11 @@
 			the inode which will represent the ext3 file
 			system's journal file.
 
+journal_dev=devnum	When the external journal device's major/minor numbers
+			have changed, this option allows to specify the new
+			journal location. The journal device is identified
+			through its new major/minor numbers encoded in devnum.
+
 noload			Don't load the journal on mounting.
 
 data=journal		All data are committed into the journal prior
@@ -57,19 +62,19 @@
 			we'd like to get some feedback if it's the contrary for
 			you.
 
-user_xattr	(*)	Enables POSIX Extended Attributes. It's enabled by
-			default, however you need to confifure its support
-			(CONFIG_EXT3_FS_XATTR). This is neccesary if you want
-			to use POSIX Acces Control Lists support. You can visit
-			http://acl.bestbits.at to know more about POSIX Extended
-			attributes.
+user_xattr		Enables Extended User Attributes. Additionally, you need
+			to have extended attribute support enabled in the kernel
+			configuration (CONFIG_EXT3_FS_XATTR). See the attr(5)
+			manual page and http://acl.bestbits.at to learn more
+			about extended attributes.
 
-nouser_xattr		Disables POSIX Extended Attributes.
+nouser_xattr		Disables Extended User Attributes.
 
-acl		(*)	Enables POSIX Access Control Lists support. This is
-			enabled by default, however you need to configure
-			its support (CONFIG_EXT3_FS_POSIX_ACL). If you want
-			to know more about ACLs visit http://acl.bestbits.at
+acl			Enables POSIX Access Control Lists support.  Additionally,
+			you need to have ACL support enabled in the kernel
+			configuration (CONFIG_EXT3_FS_POSIX_ACL). See the acl(5)
+			manual page and http://acl.bestbits.at for more
+			information.
 
 noacl			This option disables POSIX Access Control List support.
 
diff --git a/Documentation/filesystems/ocfs2.txt b/Documentation/filesystems/ocfs2.txt
new file mode 100644
index 0000000..f2595ca
--- /dev/null
+++ b/Documentation/filesystems/ocfs2.txt
@@ -0,0 +1,55 @@
+OCFS2 filesystem
+==================
+OCFS2 is a general purpose extent based shared disk cluster file
+system with many similarities to ext3. It supports 64 bit inode
+numbers, and has automatically extending metadata groups which may
+also make it attractive for non-clustered use.
+
+You'll want to install the ocfs2-tools package in order to at least
+get "mount.ocfs2" and "ocfs2_hb_ctl".
+
+Project web page:    http://oss.oracle.com/projects/ocfs2
+Tools web page:      http://oss.oracle.com/projects/ocfs2-tools
+OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
+
+All code copyright 2005 Oracle except when otherwise noted.
+
+CREDITS:
+Lots of code taken from ext3 and other projects.
+
+Authors in alphabetical order:
+Joel Becker   <joel.becker@oracle.com>
+Zach Brown    <zach.brown@oracle.com>
+Mark Fasheh   <mark.fasheh@oracle.com>
+Kurt Hackel   <kurt.hackel@oracle.com>
+Sunil Mushran <sunil.mushran@oracle.com>
+Manish Singh  <manish.singh@oracle.com>
+
+Caveats
+=======
+Features which OCFS2 does not support yet:
+	- sparse files
+	- extended attributes
+	- shared writeable mmap
+	- loopback is supported, but data written will not
+	  be cluster coherent.
+	- quotas
+	- cluster aware flock
+	- Directory change notification (F_NOTIFY)
+	- Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
+	- POSIX ACLs
+	- readpages / writepages (not user visible)
+
+Mount options
+=============
+
+OCFS2 supports the following mount options:
+(*) == default
+
+barrier=1		This enables/disables barriers. barrier=0 disables it,
+			barrier=1 enables it.
+errors=remount-ro(*)	Remount the filesystem read-only on an error.
+errors=panic		Panic and halt the machine if an error occurs.
+intr		(*)	Allow signals to interrupt cluster operations.
+nointr			Do not allow signals to interrupt cluster
+			operations.
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index d477356..a4dcf42 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1302,6 +1302,23 @@
 unnecessary page faults in thrashing situation. The unit of the value is
 second. The value would be useful to tune thrashing behavior.
 
+drop_caches
+-----------
+
+Writing to this will cause the kernel to drop clean caches, dentries and
+inodes from memory, causing that memory to become free.
+
+To free pagecache:
+	echo 1 > /proc/sys/vm/drop_caches
+To free dentries and inodes:
+	echo 2 > /proc/sys/vm/drop_caches
+To free pagecache, dentries and inodes:
+	echo 3 > /proc/sys/vm/drop_caches
+
+As this is a non-destructive operation and dirty objects are not freeable, the
+user should run `sync' first.
+
+
 2.5 /proc/sys/dev - Device specific parameters
 ----------------------------------------------
 
diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
index b3404a0..60ab61e 100644
--- a/Documentation/filesystems/ramfs-rootfs-initramfs.txt
+++ b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
@@ -143,12 +143,26 @@
   dir /mnt 755 0 0
   file /init initramfs/init.sh 755 0 0
 
+Run "usr/gen_init_cpio" (after the kernel build) to get a usage message
+documenting the above file format.
+
 One advantage of the text file is that root access is not required to
 set permissions or create device nodes in the new archive.  (Note that those
 two example "file" entries expect to find files named "init.sh" and "busybox" in
 a directory called "initramfs", under the linux-2.6.* directory.  See
 Documentation/early-userspace/README for more details.)
 
+The kernel does not depend on external cpio tools, gen_init_cpio is created
+from usr/gen_init_cpio.c which is entirely self-contained, and the kernel's
+boot-time extractor is also (obviously) self-contained.  However, if you _do_
+happen to have cpio installed, the following command line can extract the
+generated cpio image back into its component files:
+
+  cpio -i -d -H newc -F initramfs_data.cpio --no-absolute-filenames
+
+Contents of initramfs:
+----------------------
+
 If you don't already understand what shared libraries, devices, and paths
 you need to get a minimal root filesystem up and running, here are some
 references:
@@ -161,13 +175,69 @@
 code against, along with some related utilities.  It is BSD licensed.
 
 I use uClibc (http://www.uclibc.org) and busybox (http://www.busybox.net)
-myself.  These are LGPL and GPL, respectively.
+myself.  These are LGPL and GPL, respectively.  (A self-contained initramfs
+package is planned for the busybox 1.2 release.)
 
 In theory you could use glibc, but that's not well suited for small embedded
 uses like this.  (A "hello world" program statically linked against glibc is
 over 400k.  With uClibc it's 7k.  Also note that glibc dlopens libnss to do
 name lookups, even when otherwise statically linked.)
 
+Why cpio rather than tar?
+-------------------------
+
+This decision was made back in December, 2001.  The discussion started here:
+
+  http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1538.html
+
+And spawned a second thread (specifically on tar vs cpio), starting here:
+
+  http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1587.html
+
+The quick and dirty summary version (which is no substitute for reading
+the above threads) is:
+
+1) cpio is a standard.  It's decades old (from the AT&T days), and already
+   widely used on Linux (inside RPM, Red Hat's device driver disks).  Here's
+   a Linux Journal article about it from 1996:
+
+      http://www.linuxjournal.com/article/1213
+
+   It's not as popular as tar because the traditional cpio command line tools
+   require _truly_hideous_ command line arguments.  But that says nothing
+   either way about the archive format, and there are alternative tools,
+   such as:
+
+     http://freshmeat.net/projects/afio/
+
+2) The cpio archive format chosen by the kernel is simpler and cleaner (and
+   thus easier to create and parse) than any of the (literally dozens of)
+   various tar archive formats.  The complete initramfs archive format is
+   explained in buffer-format.txt, created in usr/gen_init_cpio.c, and
+   extracted in init/initramfs.c.  All three together come to less than 26k
+   total of human-readable text.
+
+3) The GNU project standardizing on tar is approximately as relevant as
+   Windows standardizing on zip.  Linux is not part of either, and is free
+   to make its own technical decisions.
+
+4) Since this is a kernel internal format, it could easily have been
+   something brand new.  The kernel provides its own tools to create and
+   extract this format anyway.  Using an existing standard was preferable,
+   but not essential.
+
+5) Al Viro made the decision (quote: "tar is ugly as hell and not going to be
+   supported on the kernel side"):
+
+      http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1540.html
+
+   explained his reasoning:
+
+      http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1550.html
+      http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1638.html
+
+   and, most importantly, designed and implemented the initramfs code.
+
 Future directions:
 ------------------
 
diff --git a/Documentation/filesystems/relayfs.txt b/Documentation/filesystems/relayfs.txt
index d803abe..5832377 100644
--- a/Documentation/filesystems/relayfs.txt
+++ b/Documentation/filesystems/relayfs.txt
@@ -44,30 +44,41 @@
 collected by userspace, and not wait for it to consume it.
 
 relayfs itself does not provide for communication of such data between
-userspace and kernel, allowing the kernel side to remain simple and not
-impose a single interface on userspace. It does provide a separate
-helper though, described below.
+userspace and kernel, allowing the kernel side to remain simple and
+not impose a single interface on userspace. It does provide a set of
+examples and a separate helper though, described below.
 
-klog, relay-app & librelay
-==========================
+klog and relay-apps example code
+================================
 
-relayfs itself is ready to use, but to make things easier, two
-additional systems are provided.  klog is a simple wrapper to make
-writing formatted text or raw data to a channel simpler, regardless of
-whether a channel to write into exists or not, or whether relayfs is
-compiled into the kernel or is configured as a module.  relay-app is
-the kernel counterpart of userspace librelay.c, combined these two
-files provide glue to easily stream data to disk, without having to
-bother with housekeeping.  klog and relay-app can be used together,
-with klog providing high-level logging functions to the kernel and
-relay-app taking care of kernel-user control and disk-logging chores.
+relayfs itself is ready to use, but to make things easier, a couple
+simple utility functions and a set of examples are provided.
 
-It is possible to use relayfs without relay-app & librelay, but you'll
-have to implement communication between userspace and kernel, allowing
-both to convey the state of buffers (full, empty, amount of padding).
+The relay-apps example tarball, available on the relayfs sourceforge
+site, contains a set of self-contained examples, each consisting of a
+pair of .c files containing boilerplate code for each of the user and
+kernel sides of a relayfs application; combined these two sets of
+boilerplate code provide glue to easily stream data to disk, without
+having to bother with mundane housekeeping chores.
 
-klog, relay-app and librelay can be found in the relay-apps tarball on
-http://relayfs.sourceforge.net
+The 'klog debugging functions' patch (klog.patch in the relay-apps
+tarball) provides a couple of high-level logging functions to the
+kernel which allow writing formatted text or raw data to a channel,
+regardless of whether a channel to write into exists or not, or
+whether relayfs is compiled into the kernel or is configured as a
+module.  These functions allow you to put unconditional 'trace'
+statements anywhere in the kernel or kernel modules; only when there
+is a 'klog handler' registered will data actually be logged (see the
+klog and kleak examples for details).
+
+It is of course possible to use relayfs from scratch i.e. without
+using any of the relay-apps example code or klog, but you'll have to
+implement communication between userspace and kernel, allowing both to
+convey the state of buffers (full, empty, amount of padding).
+
+klog and the relay-apps examples can be found in the relay-apps
+tarball on http://relayfs.sourceforge.net
+
 
 The relayfs user space API
 ==========================
@@ -125,6 +136,8 @@
     relay_reset(chan)
     relayfs_create_dir(name, parent)
     relayfs_remove_dir(dentry)
+    relayfs_create_file(name, parent, mode, fops, data)
+    relayfs_remove_file(dentry)
 
   channel management typically called on instigation of userspace:
 
@@ -141,6 +154,8 @@
     subbuf_start(buf, subbuf, prev_subbuf, prev_padding)
     buf_mapped(buf, filp)
     buf_unmapped(buf, filp)
+    create_buf_file(filename, parent, mode, buf, is_global)
+    remove_buf_file(dentry)
 
   helper functions:
 
@@ -320,6 +335,71 @@
 to finalize and process the last sub-buffers before the channel is
 closed.
 
+Creating non-relay files
+------------------------
+
+relay_open() automatically creates files in the relayfs filesystem to
+represent the per-cpu kernel buffers; it's often useful for
+applications to be able to create their own files alongside the relay
+files in the relayfs filesystem as well e.g. 'control' files much like
+those created in /proc or debugfs for similar purposes, used to
+communicate control information between the kernel and user sides of a
+relayfs application.  For this purpose the relayfs_create_file() and
+relayfs_remove_file() API functions exist.  For relayfs_create_file(),
+the caller passes in a set of user-defined file operations to be used
+for the file and an optional void * to a user-specified data item,
+which will be accessible via inode->u.generic_ip (see the relay-apps
+tarball for examples).  The file_operations are a required parameter
+to relayfs_create_file() and thus the semantics of these files are
+completely defined by the caller.
+
+See the relay-apps tarball at http://relayfs.sourceforge.net for
+examples of how these non-relay files are meant to be used.
+
+Creating relay files in other filesystems
+-----------------------------------------
+
+By default of course, relay_open() creates relay files in the relayfs
+filesystem.  Because relay_file_operations is exported, however, it's
+also possible to create and use relay files in other pseudo-filesytems
+such as debugfs.
+
+For this purpose, two callback functions are provided,
+create_buf_file() and remove_buf_file().  create_buf_file() is called
+once for each per-cpu buffer from relay_open() to allow the client to
+create a file to be used to represent the corresponding buffer; if
+this callback is not defined, the default implementation will create
+and return a file in the relayfs filesystem to represent the buffer.
+The callback should return the dentry of the file created to represent
+the relay buffer.  Note that the parent directory passed to
+relay_open() (and passed along to the callback), if specified, must
+exist in the same filesystem the new relay file is created in.  If
+create_buf_file() is defined, remove_buf_file() must also be defined;
+it's responsible for deleting the file(s) created in create_buf_file()
+and is called during relay_close().
+
+The create_buf_file() implementation can also be defined in such a way
+as to allow the creation of a single 'global' buffer instead of the
+default per-cpu set.  This can be useful for applications interested
+mainly in seeing the relative ordering of system-wide events without
+the need to bother with saving explicit timestamps for the purpose of
+merging/sorting per-cpu files in a postprocessing step.
+
+To have relay_open() create a global buffer, the create_buf_file()
+implementation should set the value of the is_global outparam to a
+non-zero value in addition to creating the file that will be used to
+represent the single buffer.  In the case of a global buffer,
+create_buf_file() and remove_buf_file() will be called only once.  The
+normal channel-writing functions e.g. relay_write() can still be used
+- writes from any cpu will transparently end up in the global buffer -
+but since it is a global buffer, callers should make sure they use the
+proper locking for such a buffer, either by wrapping writes in a
+spinlock, or by copying a write function from relayfs_fs.h and
+creating a local version that internally does the proper locking.
+
+See the 'exported-relayfile' examples in the relay-apps tarball for
+examples of creating and using relay files in debugfs.
+
 Misc
 ----
 
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index ee4c0a8..e56e842 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -162,9 +162,8 @@
 a "struct super_operations" which describes the next level of the
 filesystem implementation.
 
-Usually, a filesystem uses generic one of the generic get_sb()
-implementations and provides a fill_super() method instead. The
-generic methods are:
+Usually, a filesystem uses one of the generic get_sb() implementations
+and provides a fill_super() method instead. The generic methods are:
 
   get_sb_bdev: mount a filesystem residing on a block device
 
diff --git a/Documentation/hwmon/w83627hf b/Documentation/hwmon/w83627hf
index 78f37c2..5d23776 100644
--- a/Documentation/hwmon/w83627hf
+++ b/Documentation/hwmon/w83627hf
@@ -54,13 +54,16 @@
 use the w83781d driver. However this is not the preferred method
 now that this ISA driver has been developed.
 
-Technically, the w83627thf does not support a VID reading. However, it's
-possible or even likely that your mainboard maker has routed these signals
-to a specific set of general purpose IO pins (the Asus P4C800-E is one such
-board). The w83627thf driver now interprets these as VID. If the VID on
-your board doesn't work, first see doc/vid in the lm_sensors package. If
-that still doesn't help, email us at lm-sensors@lm-sensors.org.
+The w83627_HF_ uses pins 110-106 as VID0-VID4. The w83627_THF_ uses the
+same pins as GPIO[0:4]. Technically, the w83627_THF_ does not support a
+VID reading. However the two chips have the identical 128 pin package. So,
+it is possible or even likely for a w83627thf to have the VID signals routed
+to these pins despite their not being labeled for that purpose. Therefore,
+the w83627thf driver interprets these as VID. If the VID on your board
+doesn't work, first see doc/vid in the lm_sensors package[1]. If that still
+doesn't help, you may just ignore the bogus VID reading with no harm done.
 
-For further information on this driver see the w83781d driver
-documentation.
+For further information on this driver see the w83781d driver documentation.
+
+[1] http://www2.lm-sensors.nu/~lm78/cvs/browse.cgi/lm_sensors2/doc/vid
 
diff --git a/Documentation/i2c/busses/i2c-nforce2 b/Documentation/i2c/busses/i2c-nforce2
index e379e18..d751282 100644
--- a/Documentation/i2c/busses/i2c-nforce2
+++ b/Documentation/i2c/busses/i2c-nforce2
@@ -5,7 +5,8 @@
   * nForce2 Ultra 400 MCP      10de:0084 
   * nForce3 Pro150 MCP         10de:00D4 
   * nForce3 250Gb MCP          10de:00E4 
-  * nForce4 MCP	       	       10de:0052
+  * nForce4 MCP                10de:0052
+  * nForce4 MCP-04             10de:0034
 
 Datasheet: not publically available, but seems to be similar to the
            AMD-8111 SMBus 2.0 adapter.
diff --git a/Documentation/i2c/busses/i2c-parport b/Documentation/i2c/busses/i2c-parport
index 9f1d008..d9f23c0 100644
--- a/Documentation/i2c/busses/i2c-parport
+++ b/Documentation/i2c/busses/i2c-parport
@@ -17,6 +17,7 @@
  * Velleman K8000 adapter
  * ELV adapter
  * Analog Devices evaluation boards (ADM1025, ADM1030, ADM1031, ADM1032)
+ * Barco LPT->DVI (K5800236) adapter
 
 These devices use different pinout configurations, so you have to tell
 the driver what you have, using the type module parameter. There is no
diff --git a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients
index 184fac2..f03c2a0 100644
--- a/Documentation/i2c/porting-clients
+++ b/Documentation/i2c/porting-clients
@@ -1,10 +1,13 @@
-Revision 5, 2005-07-29
+Revision 6, 2005-11-20
 Jean Delvare <khali@linux-fr.org>
 Greg KH <greg@kroah.com>
 
 This is a guide on how to convert I2C chip drivers from Linux 2.4 to
 Linux 2.6. I have been using existing drivers (lm75, lm78) as examples.
 Then I converted a driver myself (lm83) and updated this document.
+Note that this guide is strongly oriented towards hardware monitoring
+drivers. Many points are still valid for other type of drivers, but
+others may be irrelevant.
 
 There are two sets of points below. The first set concerns technical
 changes. The second set concerns coding policy. Both are mandatory.
@@ -22,16 +25,20 @@
   #include <linux/module.h>
   #include <linux/init.h>
   #include <linux/slab.h>
+  #include <linux/jiffies.h>
   #include <linux/i2c.h>
+  #include <linux/i2c-isa.h>	/* for ISA drivers */
   #include <linux/hwmon.h>	/* for hardware monitoring drivers */
   #include <linux/hwmon-sysfs.h>
   #include <linux/hwmon-vid.h>	/* if you need VRM support */
+  #include <linux/err.h>	/* for class registration */
   #include <asm/io.h>		/* if you have I/O operations */
   Please respect this inclusion order. Some extra headers may be
   required for a given driver (e.g. "lm75.h").
 
 * [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, ISA addresses
-  are no more handled by the i2c core.
+  are no more handled by the i2c core. Address ranges are no more
+  supported either, define each individual address separately.
   SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>.
 
 * [Client data] Get rid of sysctl_id. Try using standard names for
@@ -48,23 +55,23 @@
       int kind);
   static void lm75_init_client(struct i2c_client *client);
   static int lm75_detach_client(struct i2c_client *client);
-  static void lm75_update_client(struct i2c_client *client);
+  static struct lm75_data lm75_update_device(struct device *dev);
 
 * [Sysctl] All sysctl stuff is of course gone (defines, ctl_table
   and functions). Instead, you have to define show and set functions for
   each sysfs file. Only define set for writable values. Take a look at an
-  existing 2.6 driver for details (lm78 for example). Don't forget
+  existing 2.6 driver for details (it87 for example). Don't forget
   to define the attributes for each file (this is that step that
   links callback functions). Use the file names specified in
-  Documentation/i2c/sysfs-interface for the individual files. Also
+  Documentation/hwmon/sysfs-interface for the individual files. Also
   convert the units these files read and write to the specified ones.
   If you need to add a new type of file, please discuss it on the
   sensors mailing list <lm-sensors@lm-sensors.org> by providing a
-  patch to the Documentation/i2c/sysfs-interface file.
+  patch to the Documentation/hwmon/sysfs-interface file.
 
 * [Attach] For I2C drivers, the attach function should make sure
-  that the adapter's class has I2C_CLASS_HWMON, using the
-  following construct:
+  that the adapter's class has I2C_CLASS_HWMON (or whatever class is
+  suitable for your driver), using the following construct:
   if (!(adapter->class & I2C_CLASS_HWMON))
           return 0;
   ISA-only drivers of course don't need this.
@@ -72,63 +79,72 @@
 
 * [Detect] As mentioned earlier, the flags parameter is gone.
   The type_name and client_name strings are replaced by a single
-  name string, which will be filled with a lowercase, short string
-  (typically the driver name, e.g. "lm75").
+  name string, which will be filled with a lowercase, short string.
   In i2c-only drivers, drop the i2c_is_isa_adapter check, it's
   useless. Same for isa-only drivers, as the test would always be
   true. Only hybrid drivers (which are quite rare) still need it.
-  The errorN labels are reduced to the number needed. If that number
-  is 2 (i2c-only drivers), it is advised that the labels are named
-  exit and exit_free. For i2c+isa drivers, labels should be named
-  ERROR0, ERROR1 and ERROR2. Don't forget to properly set err before
+  The labels used for error paths are reduced to the number needed.
+  It is advised that the labels are given descriptive names such as
+  exit and exit_free. Don't forget to properly set err before
   jumping to error labels. By the way, labels should be left-aligned.
   Use kzalloc instead of kmalloc.
   Use i2c_set_clientdata to set the client data (as opposed to
   a direct access to client->data).
-  Use strlcpy instead of strcpy to copy the client name.
+  Use strlcpy instead of strcpy or snprintf to copy the client name.
   Replace the sysctl directory registration by calls to
   device_create_file. Move the driver initialization before any
   sysfs file creation.
+  Register the client with the hwmon class (using hwmon_device_register)
+  if applicable.
   Drop client->id.
   Drop any 24RF08 corruption prevention you find, as this is now done
   at the i2c-core level, and doing it twice voids it.
+  Don't add I2C_CLIENT_ALLOW_USE to client->flags, it's the default now.
 
 * [Init] Limits must not be set by the driver (can be done later in
   user-space). Chip should not be reset default (although a module
-  parameter may be used to force is), and initialization should be
+  parameter may be used to force it), and initialization should be
   limited to the strictly necessary steps.
 
-* [Detach] Get rid of data, remove the call to
-  i2c_deregister_entry. Do not log an error message if
-  i2c_detach_client fails, as i2c-core will now do it for you.
+* [Detach] Remove the call to i2c_deregister_entry. Do not log an
+  error message if i2c_detach_client fails, as i2c-core will now do
+  it for you.
+  Unregister from the hwmon class if applicable.
 
-* [Update] Don't access client->data directly, use
-  i2c_get_clientdata(client) instead.
+* [Update] The function prototype changed, it is now
+  passed a device structure, which you have to convert to a client
+  using to_i2c_client(dev). The update function should return a
+  pointer to the client data.
+  Don't access client->data directly, use i2c_get_clientdata(client)
+  instead.
+  Use time_after() instead of direct jiffies comparison.
 
-* [Interface] Init function should not print anything. Make sure
-  there is a MODULE_LICENSE() line, at the bottom of the file
-  (after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this order).
+* [Interface] Make sure there is a MODULE_LICENSE() line, at the bottom
+  of the file (after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this
+  order).
+
+* [Driver] The flags field of the i2c_driver structure is gone.
+  I2C_DF_NOTIFY is now the default behavior.
+  The i2c_driver structure has a driver member, which is itself a
+  structure, those name member should be initialized to a driver name
+  string. i2c_driver itself has no name member anymore.
 
 Coding policy:
 
 * [Copyright] Use (C), not (c), for copyright.
 
 * [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you
-  can. Calls to printk/pr_debug for debugging purposes are replaced
-  by calls to dev_dbg. Here is an example on how to call it (taken
-  from lm75_detect):
+  can. Calls to printk for debugging purposes are replaced by calls to
+  dev_dbg where possible, else to pr_debug. Here is an example of how
+  to call it (taken from lm75_detect):
   dev_dbg(&client->dev, "Starting lm75 update\n");
   Replace other printk calls with the dev_info, dev_err or dev_warn
   function, as appropriate.
 
-* [Constants] Constants defines (registers, conversions, initial
-  values) should be aligned. This greatly improves readability.
-  Same goes for variables declarations. Alignments are achieved by the
-  means of tabs, not spaces. Remember that tabs are set to 8 in the
-  Linux kernel code.
-
-* [Structure definition] The name field should be standardized. All
-  lowercase and as simple as the driver name itself (e.g. "lm75").
+* [Constants] Constants defines (registers, conversions) should be
+  aligned. This greatly improves readability.
+  Alignments are achieved by the means of tabs, not spaces. Remember
+  that tabs are set to 8 in the Linux kernel code.
 
 * [Layout] Avoid extra empty lines between comments and what they
   comment. Respect the coding style (see Documentation/CodingStyle),
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index d19993c..3a057c8 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -25,9 +25,9 @@
 address.
 
 static struct i2c_driver foo_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "Foo version 2.3 driver",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "foo",
+	},
 	.attach_adapter	= &foo_attach_adapter,
 	.detach_client	= &foo_detach_client,
 	.command	= &foo_command /* may be NULL */
@@ -36,10 +36,6 @@
 The name field must match the driver name, including the case. It must not
 contain spaces, and may be up to 31 characters long.
 
-Don't worry about the flags field; just put I2C_DF_NOTIFY into it. This
-means that your driver will be notified when new adapters are found.
-This is almost always what you want.
-
 All other fields are for call-back functions which will be explained 
 below.
 
@@ -496,17 +492,13 @@
 by `__init_data'.  Hose functions and structures can be removed after
 kernel booting (or module loading) is completed.
 
+
 Command function
 ================
 
 A generic ioctl-like function call back is supported. You will seldom
-need this. You may even set it to NULL.
-
-  /* No commands defined */
-  int foo_command(struct i2c_client *client, unsigned int cmd, void *arg)
-  {
-    return 0;
-  }
+need this, and its use is deprecated anyway, so newer design should not
+use it. Set it to NULL.
 
 
 Sending and receiving
diff --git a/Documentation/input/appletouch.txt b/Documentation/input/appletouch.txt
index b48d11d..4f7c633 100644
--- a/Documentation/input/appletouch.txt
+++ b/Documentation/input/appletouch.txt
@@ -3,7 +3,7 @@
 	Copyright (C) 2005 Stelian Pop <stelian@popies.net>
 
 appletouch is a Linux kernel driver for the USB touchpad found on post
-February 2005 Apple Alu Powerbooks.
+February 2005 and October 2005 Apple Aluminium Powerbooks.
 
 This driver is derived from Johannes Berg's appletrackpad driver[1], but it has
 been improved in some areas:
@@ -13,7 +13,8 @@
 
 Credits go to Johannes Berg for reverse-engineering the touchpad protocol,
 Frank Arnold for further improvements, and Alex Harper for some additional
-information about the inner workings of the touchpad sensors.
+information about the inner workings of the touchpad sensors. Michael
+Hanselmann added support for the October 2005 models.
 
 Usage:
 ------
diff --git a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt
index c91caf7..7e77f93 100644
--- a/Documentation/kbuild/modules.txt
+++ b/Documentation/kbuild/modules.txt
@@ -18,6 +18,7 @@
 	=== 5. Include files
 	   --- 5.1 How to include files from the kernel include dir
 	   --- 5.2 External modules using an include/ dir
+	   --- 5.3 External modules using several directories
 	=== 6. Module installation
 	   --- 6.1 INSTALL_MOD_PATH
 	   --- 6.2 INSTALL_MOD_DIR
@@ -38,7 +39,7 @@
 What is covered within this file is mainly information to authors
 of modules. The author of an external modules should supply
 a makefile that hides most of the complexity so one only has to type
-'make' to buld the module. A complete example will be present in
+'make' to build the module. A complete example will be present in
 chapter ¤. Creating a kbuild file for an external module".
 
 
@@ -69,7 +70,7 @@
 
 --- 2.2 Available targets
 
-	$KDIR refers to path to kernel source top-level directory
+	$KDIR refers to the path to the kernel source top-level directory
 
 	make -C $KDIR M=`pwd`
 		Will build the module(s) located in current directory.
@@ -87,11 +88,11 @@
 	make -C $KDIR M=$PWD modules_install
 		Install the external module(s).
 		Installation default is in /lib/modules/<kernel-version>/extra,
-		but may be prefixed with INSTALL_MOD_PATH - see separate chater.
+		but may be prefixed with INSTALL_MOD_PATH - see separate chapter.
 
 	make -C $KDIR M=$PWD clean
 		Remove all generated files for the module - the kernel
-		source directory is not moddified.
+		source directory is not modified.
 
 	make -C $KDIR M=`pwd` help
 		help will list the available target when building external
@@ -99,7 +100,7 @@
 
 --- 2.3 Available options:
 
-	$KDIR refer to path to kernel src
+	$KDIR refers to the path to the kernel source top-level directory
 
 	make -C $KDIR
 		Used to specify where to find the kernel source.
@@ -206,11 +207,11 @@
 
 		KERNELDIR := /lib/modules/`uname -r`/build
 		all::
-			$(MAKE) -C $KERNELDIR M=`pwd` $@
+			$(MAKE) -C $(KERNELDIR) M=`pwd` $@
 
 		# Module specific targets
 		genbin:
-			echo "X" > 8123_bini.o_shipped
+			echo "X" > 8123_bin.o_shipped
 
 		endif
 
@@ -341,13 +342,52 @@
 		EXTRA_CFLAGS := -Iinclude
 		8123-y := 8123_if.o 8123_pci.o 8123_bin.o
 
-	Note that in the assingment there is no space between -I and the path.
-	This is a kbuild limitation and no space must be present.
+	Note that in the assignment there is no space between -I and the path.
+	This is a kbuild limitation:  there must be no space present.
 
+--- 5.3 External modules using several directories
+
+	If an external module does not follow the usual kernel style but
+	decide to spread files over several directories then kbuild can
+	support this too.
+
+	Consider the following example:
+	
+	|
+	+- src/complex_main.c
+	|   +- hal/hardwareif.c
+	|   +- hal/include/hardwareif.h
+	+- include/complex.h
+	
+	To build a single module named complex.ko we then need the following
+	kbuild file:
+
+	Kbuild:
+		obj-m := complex.o
+		complex-y := src/complex_main.o
+		complex-y += src/hal/hardwareif.o
+
+		EXTRA_CFLAGS := -I$(src)/include
+		EXTRA_CFLAGS += -I$(src)src/hal/include
+
+
+	kbuild knows how to handle .o files located in another directory -
+	although this is NOT reccommended practice. The syntax is to specify
+	the directory relative to the directory where the Kbuild file is
+	located.
+
+	To find the .h files we have to explicitly tell kbuild where to look
+	for the .h files. When kbuild executes current directory is always
+	the root of the kernel tree (argument to -C) and therefore we have to
+	tell kbuild how to find the .h files using absolute paths.
+	$(src) will specify the absolute path to the directory where the
+	Kbuild file are located when being build as an external module.
+	Therefore -I$(src)/ is used to point out the directory of the Kbuild
+	file and any additional path are just appended.
 
 === 6. Module installation
 
-Modules which are included in the kernel is installed in the directory:
+Modules which are included in the kernel are installed in the directory:
 
 	/lib/modules/$(KERNELRELEASE)/kernel
 
@@ -365,7 +405,7 @@
 		=> Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
 
 	INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the
-	example above be specified on the commandline when calling make.
+	example above be specified on the command line when calling make.
 	INSTALL_MOD_PATH has effect both when installing modules included in
 	the kernel as well as when installing external modules.
 
@@ -384,7 +424,7 @@
 
 === 7. Module versioning
 
-Module versioning are enabled by the CONFIG_MODVERSIONS tag.
+Module versioning is enabled by the CONFIG_MODVERSIONS tag.
 
 Module versioning is used as a simple ABI consistency check. The Module
 versioning creates a CRC value of the full prototype for an exported symbol and
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 5dffcfe..acb010b 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -633,6 +633,14 @@
 	inport.irq=	[HW] Inport (ATI XL and Microsoft) busmouse driver
 			Format: <irq>
 
+	combined_mode=	[HW] control which driver uses IDE ports in combined
+			mode: legacy IDE driver, libata, or both
+			(in the libata case, libata.atapi_enabled=1 may be
+			useful as well).  Note that using the ide or libata
+			options may affect your device naming (e.g. by
+			changing hdc to sdb).
+			Format: combined (default), ide, or libata
+
 	inttest=	[IA64]
 
 	io7=		[HW] IO7 for Marvel based alpha systems
@@ -902,6 +910,14 @@
 	nfsroot=	[NFS] nfs root filesystem for disk-less boxes.
 			See Documentation/nfsroot.txt.
 
+	nfs.callback_tcpport=
+			[NFS] set the TCP port on which the NFSv4 callback
+			channel should listen.
+
+	nfs.idmap_cache_timeout=
+			[NFS] set the maximum lifetime for idmapper cache
+			entries.
+
 	nmi_watchdog=	[KNL,BUGS=IA-32] Debugging features for SMP kernels
 
 	no387		[BUGS=IA-32] Tells the kernel to use the 387 maths
@@ -1160,6 +1176,10 @@
 			Limit processor to maximum C-state
 			max_cstate=9 overrides any DMI blacklist limit.
 
+	processor.nocst	[HW,ACPI]
+			Ignore the _CST method to determine C-states,
+			instead using the legacy FADT method
+
 	prompt_ramdisk=	[RAM] List of RAM disks to prompt for floppy disk
 			before loading.
 			See Documentation/ramdisk.txt.
diff --git a/Documentation/keys-request-key.txt b/Documentation/keys-request-key.txt
index 5f2b9c5..22488d7 100644
--- a/Documentation/keys-request-key.txt
+++ b/Documentation/keys-request-key.txt
@@ -56,10 +56,12 @@
  (4) request_key() then forks and executes /sbin/request-key with a new session
      keyring that contains a link to auth key V.
 
- (5) /sbin/request-key execs an appropriate program to perform the actual
+ (5) /sbin/request-key assumes the authority associated with key U.
+
+ (6) /sbin/request-key execs an appropriate program to perform the actual
      instantiation.
 
- (6) The program may want to access another key from A's context (say a
+ (7) The program may want to access another key from A's context (say a
      Kerberos TGT key). It just requests the appropriate key, and the keyring
      search notes that the session keyring has auth key V in its bottom level.
 
@@ -67,19 +69,19 @@
      UID, GID, groups and security info of process A as if it was process A,
      and come up with key W.
 
- (7) The program then does what it must to get the data with which to
+ (8) The program then does what it must to get the data with which to
      instantiate key U, using key W as a reference (perhaps it contacts a
      Kerberos server using the TGT) and then instantiates key U.
 
- (8) Upon instantiating key U, auth key V is automatically revoked so that it
+ (9) Upon instantiating key U, auth key V is automatically revoked so that it
      may not be used again.
 
- (9) The program then exits 0 and request_key() deletes key V and returns key
+(10) The program then exits 0 and request_key() deletes key V and returns key
      U to the caller.
 
-This also extends further. If key W (step 5 above) didn't exist, key W would be
-created uninstantiated, another auth key (X) would be created [as per step 3]
-and another copy of /sbin/request-key spawned [as per step 4]; but the context
+This also extends further. If key W (step 7 above) didn't exist, key W would be
+created uninstantiated, another auth key (X) would be created (as per step 3)
+and another copy of /sbin/request-key spawned (as per step 4); but the context
 specified by auth key X will still be process A, as it was in auth key V.
 
 This is because process A's keyrings can't simply be attached to
@@ -138,8 +140,8 @@
 
  (3) The process's session keyring is searched.
 
- (4) If the process has a request_key() authorisation key in its session
-     keyring then:
+ (4) If the process has assumed the authority associated with a request_key()
+     authorisation key then:
 
      (a) If extant, the calling process's thread keyring is searched.
 
diff --git a/Documentation/keys.txt b/Documentation/keys.txt
index 3115488..aaa01b0 100644
--- a/Documentation/keys.txt
+++ b/Documentation/keys.txt
@@ -308,6 +308,8 @@
 	KEY_SPEC_USER_KEYRING		-4	UID-specific keyring
 	KEY_SPEC_USER_SESSION_KEYRING	-5	UID-session keyring
 	KEY_SPEC_GROUP_KEYRING		-6	GID-specific keyring
+	KEY_SPEC_REQKEY_AUTH_KEY	-7	assumed request_key()
+						  authorisation key
 
 
 The main syscalls are:
@@ -498,7 +500,11 @@
      keyring is full, error ENFILE will result.
 
      The link procedure checks the nesting of the keyrings, returning ELOOP if
-     it appears to deep or EDEADLK if the link would introduce a cycle.
+     it appears too deep or EDEADLK if the link would introduce a cycle.
+
+     Any links within the keyring to keys that match the new key in terms of
+     type and description will be discarded from the keyring as the new one is
+     added.
 
 
  (*) Unlink a key or keyring from another keyring:
@@ -628,6 +634,41 @@
      there is one, otherwise the user default session keyring.
 
 
+ (*) Set the timeout on a key.
+
+	long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout);
+
+     This sets or clears the timeout on a key. The timeout can be 0 to clear
+     the timeout or a number of seconds to set the expiry time that far into
+     the future.
+
+     The process must have attribute modification access on a key to set its
+     timeout. Timeouts may not be set with this function on negative, revoked
+     or expired keys.
+
+
+ (*) Assume the authority granted to instantiate a key
+
+	long keyctl(KEYCTL_ASSUME_AUTHORITY, key_serial_t key);
+
+     This assumes or divests the authority required to instantiate the
+     specified key. Authority can only be assumed if the thread has the
+     authorisation key associated with the specified key in its keyrings
+     somewhere.
+
+     Once authority is assumed, searches for keys will also search the
+     requester's keyrings using the requester's security label, UID, GID and
+     groups.
+
+     If the requested authority is unavailable, error EPERM will be returned,
+     likewise if the authority has been revoked because the target key is
+     already instantiated.
+
+     If the specified key is 0, then any assumed authority will be divested.
+
+     The assumed authorititive key is inherited across fork and exec.
+
+
 ===============
 KERNEL SERVICES
 ===============
@@ -860,24 +901,6 @@
      It is safe to sleep in this method.
 
 
- (*) int (*duplicate)(struct key *key, const struct key *source);
-
-     If this type of key can be duplicated, then this method should be
-     provided. It is called to copy the payload attached to the source into the
-     new key. The data length on the new key will have been updated and the
-     quota adjusted already.
-
-     This method will be called with the source key's semaphore read-locked to
-     prevent its payload from being changed, thus RCU constraints need not be
-     applied to the source key.
-
-     This method does not have to lock the destination key in order to attach a
-     payload. The fact that KEY_FLAG_INSTANTIATED is not set in key->flags
-     prevents anything else from gaining access to the key.
-
-     It is safe to sleep in this method.
-
-
  (*) int (*update)(struct key *key, const void *data, size_t datalen);
 
      If this type of key can be updated, then this method should be provided.
diff --git a/Documentation/md.txt b/Documentation/md.txt
index 23e6cce..03a13c4 100644
--- a/Documentation/md.txt
+++ b/Documentation/md.txt
@@ -51,6 +51,30 @@
 The kernel parameter "raid=partitionable" (or "raid=part") means
 that all auto-detected arrays are assembled as partitionable.
 
+Boot time assembly of degraded/dirty arrays
+-------------------------------------------
+
+If a raid5 or raid6 array is both dirty and degraded, it could have
+undetectable data corruption.  This is because the fact that it is
+'dirty' means that the parity cannot be trusted, and the fact that it
+is degraded means that some datablocks are missing and cannot reliably
+be reconstructed (due to no parity).
+
+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
+   mdadm --assemble --force ....
+
+This option is not really available if the array has the root
+filesystem on it.  In order to support this booting from such an
+array, md supports a module parameter "start_dirty_degraded" which,
+when set to 1, bypassed the checks and will allows dirty degraded
+arrays to be started.
+
+So, to boot with a root filesystem of a dirty degraded raid[56], use
+
+   md-mod.start_dirty_degraded=1
+
 
 Superblock formats
 ------------------
@@ -141,6 +165,70 @@
      in a fully functional array.  If this is not yet known, the file
      will be empty.  If an array is being resized (not currently
      possible) this will contain the larger of the old and new sizes.
+     Some raid level (RAID1) allow this value to be set while the
+     array is active.  This will reconfigure the array.   Otherwise
+     it can only be set while assembling an array.
+
+  chunk_size
+     This is the size if bytes for 'chunks' and is only relevant to
+     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
+     of 2.  This can only be set while assembling an array
+
+  component_size
+     For arrays with data redundancy (i.e. not raid0, linear, faulty,
+     multipath), all components must be the same size - or at least
+     there must a size that they all provide space for.  This is a key
+     part or the geometry of the array.  It is measured in sectors
+     and can be read from here.  Writing to this value may resize
+     the array if the personality supports it (raid1, raid5, raid6),
+     and if the component drives are large enough.
+
+  metadata_version
+     This indicates the format that is being used to record metadata
+     about the array.  It can be 0.90 (traditional format), 1.0, 1.1,
+     1.2 (newer format in varying locations) or "none" indicating that
+     the kernel isn't managing metadata at all.
+
+  level
+     The raid 'level' for this array.  The name will often (but not
+     always) be the same as the name of the module that implements the
+     level.  To be auto-loaded the module must have an alias
+        md-$LEVEL  e.g. md-raid5
+     This can be written only while the array is being assembled, not
+     after it is started.
+
+   new_dev
+     This file can be written but not read.  The value written should
+     be a block device number as major:minor.  e.g. 8:0
+     This will cause that device to be attached to the array, if it is
+     available.  It will then appear at md/dev-XXX (depending on the
+     name of the device) and further configuration is then possible.
+
+   sync_speed_min
+   sync_speed_max
+     This are similar to /proc/sys/dev/raid/speed_limit_{min,max}
+     however they only apply to the particular array.
+     If no value has been written to these, of if the word 'system'
+     is written, then the system-wide value is used.  If a value,
+     in kibibytes-per-second is written, then it is used.
+     When the files are read, they show the currently active value
+     followed by "(local)" or "(system)" depending on whether it is
+     a locally set or system-wide value.
+
+   sync_completed
+     This shows the number of sectors that have been completed of
+     whatever the current sync_action is, followed by the number of
+     sectors in total that could need to be processed.  The two
+     numbers are separated by a '/'  thus effectively showing one
+     value, a fraction of the process that is complete.
+
+   sync_speed
+     This shows the current actual speed, in K/sec, of the current
+     sync_action.  It is averaged over the last 30 seconds.
+
 
 As component devices are added to an md array, they appear in the 'md'
 directory as new directories named
@@ -167,6 +255,38 @@
 			 of being recoverred to
 	This list make grow in future.
 
+      errors
+	An approximate count of read errors that have been detected on
+	this device but have not caused the device to be evicted from
+	the array (either because they were corrected or because they
+	happened while the array was read-only).  When using version-1
+	metadata, this value persists across restarts of the array.
+
+	This value can be written while assembling an array thus
+	providing an ongoing count for arrays with metadata managed by
+	userspace.
+
+      slot
+        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
+	it currently fills.  This can only be set while assembling an
+	array.  A device for which this is set is assumed to be working.
+
+      offset
+        This gives the location in the device (in sectors from the
+        start) where data from the array will be stored.  Any part of
+        the device before this offset us not touched, unless it is
+        used for storing metadata (Formats 1.1 and 1.2).
+
+      size
+        The amount of the device, after the offset, that can be used
+        for storage of data.  This will normally be the same as the
+	component_size.  This can be written while assembling an
+        array.  If a value less than the current component_size is
+        written, component_size will be reduced to this value.
+
 
 An active md device will also contain and entry for each active device
 in the array.  These are named
diff --git a/Documentation/networking/gianfar.txt b/Documentation/networking/gianfar.txt
new file mode 100644
index 0000000..ad474ea
--- /dev/null
+++ b/Documentation/networking/gianfar.txt
@@ -0,0 +1,72 @@
+The Gianfar Ethernet Driver
+Sysfs File description
+
+Author: Andy Fleming <afleming@freescale.com>
+Updated: 2005-07-28
+
+SYSFS
+
+Several of the features of the gianfar driver are controlled
+through sysfs files.  These are:
+
+bd_stash:
+To stash RX Buffer Descriptors in the L2, echo 'on' or '1' to
+bd_stash, echo 'off' or '0' to disable
+
+rx_stash_len:
+To stash the first n bytes of the packet in L2, echo the number
+of bytes to buf_stash_len.  echo 0 to disable.
+
+WARNING: You could really screw these up if you set them too low or high!
+fifo_threshold:
+To change the number of bytes the controller needs in the
+fifo before it starts transmission, echo the number of bytes to 
+fifo_thresh.  Range should be 0-511.
+
+fifo_starve:
+When the FIFO has less than this many bytes during a transmit, it
+enters starve mode, and increases the priority of TX memory
+transactions.  To change, echo the number of bytes to
+fifo_starve.  Range should be 0-511.
+
+fifo_starve_off:
+Once in starve mode, the FIFO remains there until it has this
+many bytes.  To change, echo the number of bytes to
+fifo_starve_off.  Range should be 0-511.
+
+CHECKSUM OFFLOADING
+
+The eTSEC controller (first included in parts from late 2005 like
+the 8548) has the ability to perform TCP, UDP, and IP checksums
+in hardware.  The Linux kernel only offloads the TCP and UDP
+checksums (and always performs the pseudo header checksums), so
+the driver only supports checksumming for TCP/IP and UDP/IP
+packets.  Use ethtool to enable or disable this feature for RX
+and TX.
+
+VLAN
+
+In order to use VLAN, please consult Linux documentation on
+configuring VLANs.  The gianfar driver supports hardware insertion and
+extraction of VLAN headers, but not filtering.  Filtering will be
+done by the kernel.
+
+MULTICASTING
+
+The gianfar driver supports using the group hash table on the
+TSEC (and the extended hash table on the eTSEC) for multicast
+filtering.  On the eTSEC, the exact-match MAC registers are used
+before the hash tables.  See Linux documentation on how to join
+multicast groups.
+
+PADDING
+
+The gianfar driver supports padding received frames with 2 bytes
+to align the IP header to a 16-byte boundary, when supported by
+hardware.
+
+ETHTOOL
+
+The gianfar driver supports the use of ethtool for many
+configuration options.  You must run ethtool only on currently
+open interfaces.  See ethtool documentation for details.
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index ebc09a1..2b7cf19 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -46,6 +46,29 @@
 	for the hash secret) for IP fragments.
 	Default: 600
 
+ipfrag_max_dist - INTEGER
+	ipfrag_max_dist is a non-negative integer value which defines the 
+	maximum "disorder" which is allowed among fragments which share a 
+	common IP source address. Note that reordering of packets is 
+	not unusual, but if a large number of fragments arrive from a source 
+	IP address while a particular fragment queue remains incomplete, it 
+	probably indicates that one or more fragments belonging to that queue 
+	have been lost. When ipfrag_max_dist is positive, an additional check 
+	is done on fragments before they are added to a reassembly queue - if 
+	ipfrag_max_dist (or more) fragments have arrived from a particular IP 
+	address between additions to any IP fragment queue using that source 
+	address, it's presumed that one or more fragments in the queue are 
+	lost. The existing fragment queue will be dropped, and a new one 
+	started. An ipfrag_max_dist value of zero disables this check.
+
+	Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
+	result in unnecessarily dropping fragment queues when normal
+	reordering of packets occurs, which could lead to poor application 
+	performance. Using a very large value, e.g. 50000, increases the 
+	likelihood of incorrectly reassembling IP fragments that originate 
+	from different IP datagrams, which could result in data corruption.
+	Default: 64
+
 INET peer storage:
 
 inet_peer_threshold - INTEGER
diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt
index 403e7b4..97420f0 100644
--- a/Documentation/pcmcia/driver-changes.txt
+++ b/Documentation/pcmcia/driver-changes.txt
@@ -1,5 +1,16 @@
 This file details changes in 2.6 which affect PCMCIA card driver authors:
 
+* Unify detach and REMOVAL event code, as well as attach and INSERTION
+  code (as of 2.6.16)
+       void (*remove)          (struct pcmcia_device *dev);
+       int (*probe)            (struct pcmcia_device *dev);
+
+* Move suspend, resume and reset out of event handler (as of 2.6.16)
+       int (*suspend)          (struct pcmcia_device *dev);
+       int (*resume)           (struct pcmcia_device *dev);
+  should be initialized in struct pcmcia_driver, and handle
+  (SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
+
 * event handler initialization in struct pcmcia_driver (as of 2.6.13)
    The event handler is notified of all events, and must be initialized
    as the event() callback in the driver's struct pcmcia_driver.
diff --git a/Documentation/pm.txt b/Documentation/pm.txt
index 2ea1149..79c0f32 100644
--- a/Documentation/pm.txt
+++ b/Documentation/pm.txt
@@ -218,7 +218,7 @@
 Q: Who do I contact for additional information about
    enabling power management for my specific driver/device?
 
-ACPI Development mailing list: acpi-devel@lists.sourceforge.net
+ACPI Development mailing list: linux-acpi@vger.kernel.org
 
 System Interface -- OBSOLETE, DO NOT USE!
 ----------------*************************
diff --git a/Documentation/power/interface.txt b/Documentation/power/interface.txt
index f5ebda5..bd4ffb5 100644
--- a/Documentation/power/interface.txt
+++ b/Documentation/power/interface.txt
@@ -41,3 +41,14 @@
 It will only change to 'firmware' or 'platform' if the system supports
 it. 
 
+/sys/power/image_size controls the size of the image created by
+the suspend-to-disk mechanism.  It can be written a string
+representing a non-negative integer that will be used as an upper
+limit of the image size, in megabytes.  The suspend-to-disk mechanism will
+do its best to ensure the image size will not exceed that number.  However,
+if this turns out to be impossible, it will try to suspend anyway using the
+smallest image possible.  In particular, if "0" is written to this file, the
+suspend image will be as small as possible.
+
+Reading from this file will display the current image size limit, which
+is set to 500 MB by default.
diff --git a/Documentation/power/swsusp.txt b/Documentation/power/swsusp.txt
index b0d5084..cd0fcd8 100644
--- a/Documentation/power/swsusp.txt
+++ b/Documentation/power/swsusp.txt
@@ -27,6 +27,11 @@
 
 echo platform > /sys/power/disk; echo disk > /sys/power/state
 
+If you want to limit the suspend image size to N megabytes, do
+
+echo N > /sys/power/image_size
+
+before suspend (it is limited to 500 MB by default).
 
 Encrypted suspend image:
 ------------------------
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt
index e75d747..67a11a3 100644
--- a/Documentation/powerpc/eeh-pci-error-recovery.txt
+++ b/Documentation/powerpc/eeh-pci-error-recovery.txt
@@ -115,7 +115,7 @@
 At this time, a generic EEH recovery mechanism has been implemented,
 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 hotplug/udev
+infrastructure,  and percolates events up through the userspace/udev
 infrastructure.  Followiing is a detailed description of how this is
 accomplished.
 
@@ -172,7 +172,7 @@
 drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
 It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
 This last call causes the device driver for the card to be stopped,
-which causes hotplug events to go out to user space. This triggers
+which causes uevents to go out to user space. This triggers
 user-space scripts that might issue commands such as "ifdown eth0"
 for ethernet cards, and so on.  This handler then sleeps for 5 seconds,
 hoping to give the user-space scripts enough time to complete.
@@ -258,29 +258,30 @@
     calls
     pci_destroy_dev (struct pci_dev *) {
       calls
-      device_unregister (&dev->dev) {      // in /drivers/base/core.c
+      device_unregister (&dev->dev) {        // in /drivers/base/core.c
         calls
-        device_del(struct device * dev) {  // in /drivers/base/core.c
+        device_del(struct device * dev) {    // in /drivers/base/core.c
           calls
-          kobject_del() {                  //in /libs/kobject.c
+          kobject_del() {                    //in /libs/kobject.c
             calls
-            kobject_hotplug() {            // in /libs/kobject.c
+            kobject_uevent() {               // in /libs/kobject.c
               calls
-              kset_hotplug() {             // in /lib/kobject.c
+              kset_uevent() {                // in /lib/kobject.c
                 calls
-                kset->hotplug_ops->hotplug() which is really just
+                kset->uevent_ops->uevent()   // which is really just
                 a call to
-                dev_hotplug() {           // in /drivers/base/core.c
+                dev_uevent() {               // in /drivers/base/core.c
                   calls
-                  dev->bus->hotplug() which is really just a call to
-                  pci_hotplug () {      // in drivers/pci/hotplug.c
+                  dev->bus->uevent() which is really just a call to
+                  pci_uevent () {            // in drivers/pci/hotplug.c
                     which prints device name, etc....
                  }
                }
-               then kset_hotplug() calls
-                call_usermodehelper () with
-                   argv[0]=hotplug_path[] which is "/sbin/hotplug"
-             --> event to userspace,
+               then kobject_uevent() sends a netlink uevent to userspace
+               --> userspace uevent
+               (during early boot, nobody listens to netlink events and
+               kobject_uevent() executes uevent_helper[], which runs the
+               event process /sbin/hotplug)
            }
          }
          kobject_del() then calls sysfs_remove_dir(), which would
diff --git a/Documentation/scsi/ChangeLog.megaraid b/Documentation/scsi/ChangeLog.megaraid
index 5331d91..09f6300 100644
--- a/Documentation/scsi/ChangeLog.megaraid
+++ b/Documentation/scsi/ChangeLog.megaraid
@@ -1,3 +1,38 @@
+Release Date	: Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
+Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
+Older Version	: 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
+
+1.	Sorted out PCI IDs to remove megaraid support overlaps.
+	Based on the patch from Daniel, sorted out PCI IDs along with
+	charactor node name change from 'megadev' to 'megadev_legacy' to avoid
+	conflict.
+	---
+	Hopefully we'll be getting the build restriction zapped much sooner, 
+	but we should also be thinking about totally removing the hardware 
+	support overlap in the megaraid drivers.
+
+	This patch pencils in a date of Feb 06 for this, and performs some 
+	printk abuse in hope that existing legacy users might pick up on what's
+	going on.
+
+	Signed-off-by: Daniel Drake <dsd@gentoo.org>
+	---
+
+2.	Fixed a issue: megaraid always fails to reset handler.
+	---
+	I found that the megaraid driver always fails to reset the
+	adapter with the following message:
+		megaraid: resetting the host...
+		megaraid mbox: reset sequence completed successfully
+		megaraid: fast sync command timed out
+		megaraid: reservation reset failed
+	when the "Cluster mode" of the adapter BIOS is enabled.
+	So, whenever the reset occurs, the adapter goes to
+	offline and just become unavailable.
+
+	Jun'ichi Nomura [mailto:jnomura@mtc.biglobe.ne.jp]
+	---
+
 Release Date	: Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
 Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
 Older Version	: 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index 66565d4..8bbae3e 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -150,7 +150,8 @@
 LLD                   mid level                    LLD
 ===-------------------=========--------------------===------
 scsi_host_alloc()  -->
-scsi_add_host()  --------+
+scsi_add_host()  ---->
+scsi_scan_host()  -------+
                          |
                     slave_alloc()
                     slave_configure() -->  scsi_adjust_queue_depth()
@@ -196,7 +197,7 @@
 
 
 The hotplug concept may be extended to SCSI devices. Currently, when an
-HBA is added, the scsi_add_host() function causes a scan for SCSI devices
+HBA is added, the scsi_scan_host() function causes a scan for SCSI devices
 attached to the HBA's SCSI transport. On newer SCSI transports the HBA
 may become aware of a new SCSI device _after_ the scan has completed.
 An LLD can use this sequence to make the mid level aware of a SCSI device:
@@ -372,7 +373,7 @@
 Summary:
    scsi_activate_tcq - turn on tag command queueing
    scsi_add_device - creates new scsi device (lu) instance
-   scsi_add_host - perform sysfs registration and SCSI bus scan.
+   scsi_add_host - perform sysfs registration and set up transport class
    scsi_adjust_queue_depth - change the queue depth on a SCSI device
    scsi_assign_lock - replace default host_lock with given lock
    scsi_bios_ptable - return copy of block device's partition table
@@ -386,6 +387,7 @@
    scsi_remove_device - detach and remove a SCSI device
    scsi_remove_host - detach and remove all SCSI devices owned by host
    scsi_report_bus_reset - report scsi _bus_ reset observed
+   scsi_scan_host - scan SCSI bus
    scsi_track_queue_full - track successive QUEUE_FULL events 
    scsi_unblock_requests - allow further commands to be queued to given host
    scsi_unregister - [calls scsi_host_put()]
@@ -425,10 +427,10 @@
  *      Might block: yes
  *
  *      Notes: This call is usually performed internally during a scsi
- *      bus scan when an HBA is added (i.e. scsi_add_host()). So it
+ *      bus scan when an HBA is added (i.e. scsi_scan_host()). So it
  *      should only be called if the HBA becomes aware of a new scsi
- *      device (lu) after scsi_add_host() has completed. If successful
- *      this call we lead to slave_alloc() and slave_configure() callbacks
+ *      device (lu) after scsi_scan_host() has completed. If successful
+ *      this call can lead to slave_alloc() and slave_configure() callbacks
  *      into the LLD.
  *
  *      Defined in: drivers/scsi/scsi_scan.c
@@ -439,7 +441,7 @@
 
 
 /**
- * scsi_add_host - perform sysfs registration and SCSI bus scan.
+ * scsi_add_host - perform sysfs registration and set up transport class
  * @shost:   pointer to scsi host instance
  * @dev:     pointer to struct device of type scsi class
  *
@@ -448,7 +450,11 @@
  *      Might block: no
  *
  *      Notes: Only required in "hotplug initialization model" after a
- *      successful call to scsi_host_alloc().
+ *      successful call to scsi_host_alloc().  This function does not
+ *	scan the bus; this can be done by calling scsi_scan_host() or
+ *	in some other transport-specific way.  The LLD must set up
+ *	the transport template before calling this function and may only
+ *	access the transport class data after this function has been called.
  *
  *      Defined in: drivers/scsi/hosts.c
  **/
@@ -559,7 +565,7 @@
  *      area for the LLD's exclusive use.
  *      Both associated refcounting objects have their refcount set to 1.
  *      Full registration (in sysfs) and a bus scan are performed later when
- *      scsi_add_host() is called.
+ *      scsi_add_host() and scsi_scan_host() are called.
  *
  *      Defined in: drivers/scsi/hosts.c .
  **/
@@ -699,6 +705,19 @@
 
 
 /**
+ * scsi_scan_host - scan SCSI bus
+ * @shost: a pointer to a scsi host instance
+ *
+ *	Might block: yes
+ *
+ *	Notes: Should be called after scsi_add_host()
+ *
+ *	Defined in: drivers/scsi/scsi_scan.c
+ **/
+void scsi_scan_host(struct Scsi_Host *shost)
+
+
+/**
  * scsi_track_queue_full - track successive QUEUE_FULL events on given
  *                      device to determine if and when there is a need
  *                      to adjust the queue depth on the device.
@@ -1433,7 +1452,7 @@
         Christoph Hellwig <hch at infradead dot org>
         Doug Ledford <dledford at redhat dot com>
         Andries Brouwer <Andries dot Brouwer at cwi dot nl>
-        Randy Dunlap <rddunlap at osdl dot org>
+        Randy Dunlap <rdunlap at xenotime dot net>
         Alan Stern <stern at rowland dot harvard dot edu>
 
 
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 2f27f39..d257801 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -105,7 +105,7 @@
     Each of top level sound card module takes the following options.
 
     index	- index (slot #) of sound card
-		- Values: 0 through 7 or negative
+		- Values: 0 through 31 or negative
 		- If nonnegative, assign that index number
                 - if negative, interpret as a bitmask of permissible
 		  indices; the first free permitted index is assigned
@@ -134,7 +134,7 @@
     dma2	- second DMA # for AD1816A chip (PnP setup)
     clockfreq   - Clock frequency for AD1816A chip (default = 0, 33000Hz)
     
-    Module supports up to 8 cards, autoprobe and PnP.
+    This module supports multiple cards, autoprobe and PnP.
     
   Module snd-ad1848
   -----------------
@@ -145,9 +145,11 @@
     irq		- IRQ # for AD1848  chip
     dma1	- DMA # for AD1848 chip (0,1,3)
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards.  It does not support autoprobe
     thus main port must be specified!!! Other ports are optional.
     
+    The power-management is supported.
+
   Module snd-ad1889
   -----------------
 
@@ -156,7 +158,7 @@
     ac97_quirk  - AC'97 workaround for strange hardware
                   See the description of intel8x0 module for details.
 
-    This module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-ali5451
   ------------------
@@ -184,7 +186,9 @@
     mpu_irq	- IRQ # for MPU-401 (PnP setup)
     fm_port	- port # for OPL3 FM (PnP setup)
     
-    Module supports up to 8 cards, autoprobe and PnP.
+    This module supports multiple cards, autoprobe and PnP.
+
+    The power-management is supported.
 
   Module snd-als4000
   ------------------
@@ -194,7 +198,9 @@
     joystick_port - port # for legacy joystick support.
                     0 = disabled (default), 1 = auto-detect
     
-    Module supports up to 8 cards, autoprobe and PnP.
+    This module supports multiple cards, autoprobe and PnP.
+
+    The power-management is supported.
 
   Module snd-atiixp
   -----------------
@@ -213,6 +219,8 @@
     implementation depends on the motherboard, and you'll need to
     choose the correct one via spdif_aclink module option.
 
+    The power-management is supported.
+
   Module snd-atiixp-modem
   -----------------------
 
@@ -223,6 +231,8 @@
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
 
+    The power-management is supported.
+
   Module snd-au8810, snd-au8820, snd-au8830
   -----------------------------------------
 
@@ -263,8 +273,10 @@
     dma1	- 1st DMA # for AZT2320 (WSS) chip (PnP setup)
     dma2	- 2nd DMA # for AZT2320 (WSS) chip (PnP setup)
     
-    Module supports up to 8 cards, PnP and autoprobe.
+    This module supports multiple cards, PnP and autoprobe.
     
+    The power-management is supported.
+
   Module snd-azt3328
   ------------------
 
@@ -272,7 +284,7 @@
 
     joystick	- Enable joystick (default off)
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-bt87x
   ----------------
@@ -282,7 +294,7 @@
     digital_rate - Override the default digital rate (Hz)
     load_all	- Load the driver even if the card model isn't known
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
@@ -292,7 +304,7 @@
 
     Module for Creative Audigy LS and SB Live 24bit
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
 
   Module snd-cmi8330
@@ -308,7 +320,9 @@
     sbdma8	- 8bit DMA # for CMI8330 chip (SB16)
     sbdma16	- 16bit DMA # for CMI8330 chip (SB16)
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
+
+    The power-management is supported.
 
   Module snd-cmipci
   -----------------
@@ -321,8 +335,10 @@
                   (default = 1)
     joystick_port - Joystick port address (0 = disable, 1 = auto-detect)
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports autoprobe and multiple cards.
     
+    The power-management is supported.
+
   Module snd-cs4231
   -----------------
 
@@ -335,7 +351,7 @@
     dma1	- first DMA # for CS4231 chip
     dma2	- second DMA # for CS4231 chip
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards. This module does not support autoprobe
     thus main port must be specified!!! Other ports are optional.
 
     The power-management is supported.
@@ -355,7 +371,7 @@
     dma2	- second DMA # for Yamaha CS4232 chip (0,1,3), -1 = disable
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards. This module does not support autoprobe
     thus main port must be specified!!! Other ports are optional.
 
     The power-management is supported.
@@ -376,7 +392,7 @@
     dma2	- second DMA # for CS4236 chip (0,1,3), -1 = disable
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards. This module does not support autoprobe
     (if ISA PnP is not used) thus main port and control port must be
     specified!!! Other ports are optional.
 
@@ -389,7 +405,7 @@
 
     dual_codec	- Secondary codec ID (0 = disable, default)
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
     The power-management is supported.
 
@@ -403,13 +419,20 @@
     thinkpad         - Force to enable Thinkpad's CLKRUN control.
     mmap_valid       - Support OSS mmap mode (default = 0).
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     Usually external amp and CLKRUN controls are detected automatically
     from PCI sub vendor/device ids.  If they don't work, give the options
     above explicitly.
 
     The power-management is supported.
     
+  Module snd-cs5535audio
+  ----------------------
+
+    Module for multifunction CS5535 companion PCI device
+
+    This module supports multiple cards.
+
   Module snd-dt019x
   -----------------
 
@@ -423,9 +446,11 @@
     mpu_irq	- IRQ # for MPU-401 (PnP setup)
     dma8	- DMA # (PnP setup)
 
-    Module supports up to 8 cards.  This module is enabled only with
+    This module supports multiple cards.  This module is enabled only with
     ISA PnP support.
 
+    The power-management is supported.
+
   Module snd-dummy
   ----------------
 
@@ -433,6 +458,8 @@
     or input, but you may use this module for any application which
     requires a sound card (like RealPlayer).
 
+    The power-management is supported.
+
   Module snd-emu10k1
   ------------------
 
@@ -450,7 +477,7 @@
                        given in MB unit.  Default value is 128.
     enable_ir - enable IR
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
     Input & Output configurations 			[extin/extout]
 	* Creative Card wo/Digital out			[0x0003/0x1f03]
@@ -466,12 +493,14 @@
 	* Creative Card 5.1 (c) 2003			[0x3fc3/0x7cff]
         * Creative Card all ins and outs		[0x3fff/0x7fff]
     
+    The power-management is supported.
+
   Module snd-emu10k1x
   -------------------
 
     Module for Creative Emu10k1X (SB Live Dell OEM version)
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-ens1370
   ------------------
@@ -482,7 +511,7 @@
 
     joystick		- Enable joystick (default off)
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
   Module snd-ens1371
   ------------------
@@ -495,7 +524,7 @@
     joystick_port	- port # for joystick (0x200,0x208,0x210,0x218),
 			  0 = disable (default), 1 = auto-detect
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
   Module snd-es968
   ----------------
@@ -506,8 +535,10 @@
     irq		- IRQ # for ES968 (SB8) chip (PnP setup)
     dma1	- DMA # for ES968 (SB8) chip (PnP setup)
     
-    Module supports up to 8 cards, PnP and autoprobe.
+    This module supports multiple cards, PnP and autoprobe.
     
+    The power-management is supported.
+
   Module snd-es1688
   -----------------
 
@@ -519,7 +550,7 @@
     mpu_irq	- IRQ # for MPU-401 port (5,7,9,10)
     dma8	- DMA # for ES-1688 chip (0,1,3)
 
-    Module supports up to 8 cards and autoprobe (without MPU-401 port).
+    This module supports multiple cards and autoprobe (without MPU-401 port).
 
   Module snd-es18xx
   -----------------
@@ -534,8 +565,8 @@
     dma2	- first DMA # for ES-18xx chip (0,1,3)
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
 
-    Module supports up to 8 cards ISA PnP and autoprobe (without MPU-401 port
-    if native ISA PnP routines are not used).
+    This module supports multiple cards, ISA PnP and autoprobe (without MPU-401
+    port if native ISA PnP routines are not used).
     When dma2 is equal with dma1, the driver works as half-duplex.
 
     The power-management is supported.
@@ -545,7 +576,9 @@
 
     Module for sound cards based on ESS Solo-1 (ES1938,ES1946) chips.
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
+
+    The power-management is supported.
 
   Module snd-es1968
   -----------------
@@ -561,7 +594,7 @@
     enable_mpu		- enable MPU401 (0 = off, 1 = on, 2 = auto (default))
     joystick		- enable joystick (default off)       
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
     The power-management is supported.
 
@@ -577,8 +610,10 @@
                           - High 16-bits are video (radio) device number + 1
                           - example: 0x10002 (MediaForte 256-PCPR, device 1)
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
+    The power-management is supported.
+
   Module snd-gusclassic
   ---------------------
 
@@ -592,7 +627,7 @@
     voices	- GF1 voices limit (14-32)
     pcm_voices	- reserved PCM voices
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
   Module snd-gusextreme
   ---------------------
@@ -611,7 +646,7 @@
     voices	- GF1 voices limit (14-32)
     pcm_voices	- reserved PCM voices
 
-    Module supports up to 8 cards and autoprobe (without MPU-401 port).
+    This module supports multiple cards and autoprobe (without MPU-401 port).
 
   Module snd-gusmax
   -----------------
@@ -626,7 +661,7 @@
     voices	- GF1 voices limit (14-32)
     pcm_voices	- reserved PCM voices
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
   Module snd-hda-intel
   --------------------
@@ -688,12 +723,14 @@
 	    (Usually SD_LPLIB register is more accurate than the
 	    position buffer.)
 
+    The power-management is supported.
+
   Module snd-hdsp
   ---------------
 
     Module for RME Hammerfall DSP audio interface(s)
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
     Note: The firmware data can be automatically loaded via hotplug
           when CONFIG_FW_LOADER is set.  Otherwise, you need to load
@@ -751,7 +788,7 @@
     cs8427_timeout - reset timeout for the CS8427 chip (S/PDIF transciever)
                      in msec resolution, default value is 500 (0.5 sec)
 
-    Module supports up to 8 cards and autoprobe. Note: The consumer part
+    This module supports multiple cards and autoprobe. Note: The consumer part
     is not used with all Envy24 based cards (for example in the MidiMan Delta
     serie).
 
@@ -787,7 +824,7 @@
 		  aureon71, universe, k8x800, phase22, phase28, ms300,
 		  av710
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
     Note: The supported board is detected by reading EEPROM or PCI
 	  SSID (if EEPROM isn't available).  You can override the
@@ -839,6 +876,8 @@
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
 
+    The power-management is supported.
+
   Module snd-interwave
   --------------------
 
@@ -855,7 +894,7 @@
     effect	- 1 = InterWave effects enable (default 0);
                   requires 8 voices
 
-    Module supports up to 8 cards, autoprobe and ISA PnP.
+    This module supports multiple cards, autoprobe and ISA PnP.
 
   Module snd-interwave-stb
   ------------------------
@@ -875,14 +914,14 @@
     effect	- 1 = InterWave effects enable (default 0);
                   requires 8 voices
 
-    Module supports up to 8 cards, autoprobe and ISA PnP.
+    This module supports multiple cards, autoprobe and ISA PnP.
 
   Module snd-korg1212
   -------------------
 
     Module for Korg 1212 IO PCI card
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-maestro3
   -------------------
@@ -894,7 +933,7 @@
                        -1 for default pin (8 for allegro, 1 for
                        others) 
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports autoprobe and multiple chips.
 
     Note: the binding of amplifier is dependent on hardware.
     If there is no sound even though all channels are unmuted, try to
@@ -909,7 +948,7 @@
 
     Module for Digigram miXart8 sound cards.
 
-    Module supports multiple cards.
+    This module supports multiple cards.
     Note: One miXart8 board will be represented as 4 alsa cards.
           See MIXART.txt for details.
 
@@ -928,7 +967,7 @@
     irq		- IRQ number or -1 (disable)
     pnp		- PnP detection - 0 = disable, 1 = enable (default)
 
-    Module supports multiple devices (max 8) and PnP.
+    This module supports multiple devices and PnP.
     
   Module snd-mtpav
   ----------------
@@ -1014,7 +1053,7 @@
     dma2	- second DMA # for Yamaha OPL3-SA chip (0,1,3), -1 = disable
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     
-    Module supports up to 8 cards and ISA PnP. This module does not support
+    This module supports multiple cards and ISA PnP.  It does not support
     autoprobe (if ISA PnP is not used) thus all ports must be specified!!!
     
     The power-management is supported.
@@ -1064,6 +1103,13 @@
 
     This module supports only one card, autoprobe and PnP.
 
+  Module snd-pcxhr
+  ----------------
+
+    Module for Digigram PCXHR boards
+
+    This module supports multiple cards.
+
   Module snd-powermac (on ppc only)
   ---------------------------------
 
@@ -1084,20 +1130,22 @@
 
     For ARM architecture only.
 
+    The power-management is supported.
+
   Module snd-rme32
   ----------------
 
     Module for RME Digi32, Digi32 Pro and Digi32/8 (Sek'd Prodif32, 
     Prodif96 and Prodif Gold) sound cards.
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-rme96
   ----------------
 
     Module for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST sound cards.
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-rme9652
   ------------------
@@ -1107,7 +1155,7 @@
     precise_ptr	- Enable precise pointer (doesn't work reliably).
 		  (default = 0)
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
     Note: snd-page-alloc module does the job which snd-hammerfall-mem
           module did formerly.  It will allocate the buffers in advance
@@ -1124,6 +1172,8 @@
     Module supports only one card.
     Module has no enable and index options.
 
+    The power-management is supported.
+
   Module snd-sb8
   --------------
 
@@ -1135,8 +1185,10 @@
     irq		- IRQ # for SB DSP chip (5,7,9,10)
     dma8	- DMA # for SB DSP chip (1,3)
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
     
+    The power-management is supported.
+
   Module snd-sb16 and snd-sbawe
   -----------------------------
 
@@ -1155,7 +1207,7 @@
     csp		- ASP/CSP chip support - 0 = disable (default), 1 = enable
     isapnp	- ISA PnP detection - 0 = disable, 1 = enable (default)
     
-    Module supports up to 8 cards, autoprobe and ISA PnP.
+    This module supports multiple cards, autoprobe and ISA PnP.
 
     Note: To use Vibra16X cards in 16-bit half duplex mode, you must
           disable 16bit DMA with dma16 = -1 module parameter.
@@ -1163,6 +1215,8 @@
           half duplex mode through 8-bit DMA channel by disabling their
           16-bit DMA channel.
     
+    The power-management is supported.
+
   Module snd-sgalaxy
   ------------------
 
@@ -1173,7 +1227,9 @@
     irq		- IRQ # (7,9,10,11)
     dma1	- DMA #
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
+
+    The power-management is supported.
 
   Module snd-sscape
   -----------------
@@ -1185,7 +1241,7 @@
     mpu_irq	- MPU-401 IRQ # (PnP setup)
     dma		- DMA # (PnP setup)
 
-    Module supports up to 8 cards.  ISA PnP must be enabled.
+    This module supports multiple cards.  ISA PnP must be enabled.
     You need sscape_ctl tool in alsa-tools package for loading
     the microcode.
 
@@ -1194,21 +1250,21 @@
 
     Module for AMD7930 sound chips found on Sparcs.
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-sun-cs4231 (on sparc only)
   -------------------------------------
 
     Module for CS4231 sound chips found on Sparcs.
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-sun-dbri (on sparc only)
   -----------------------------------
 
     Module for DBRI sound chips found on Sparcs.
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-wavefront
   --------------------
@@ -1228,7 +1284,7 @@
     dma2            - DMA2 # for CS4232 PCM interface.
     isapnp          - ISA PnP detection - 0 = disable, 1 = enable (default)
 
-    Module supports up to 8 cards and ISA PnP.
+    This module supports multiple cards and ISA PnP.
 
   Module snd-sonicvibes
   ---------------------
@@ -1240,7 +1296,7 @@
                   - SoundCard must have onboard SRAM for this.
     mge       - Mic Gain Enable - 1 = enable, 0 = disable (default)
     
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
   Module snd-serial-u16550
   ------------------------
@@ -1259,7 +1315,7 @@
                   0 = Soundcanvas, 1 = MS-124T, 2 = MS-124W S/A,
 		  3 = MS-124W M/B, 4 = Generic
     
-    Module supports up to 8 cards. This module does not support autoprobe
+    This module supports multiple cards. This module does not support autoprobe
     thus the main port must be specified!!! Other options are optional.
 
   Module snd-trident
@@ -1278,7 +1334,7 @@
     pcm_channels   - max channels (voices) reserved for PCM
     wavetable_size - max wavetable size in kB (4-?kb)
 
-    Module supports up to 8 cards and autoprobe.
+    This module supports multiple cards and autoprobe.
 
     The power-management is supported.
 
@@ -1290,14 +1346,14 @@
     vid             - Vendor ID for the device (optional)
     pid             - Product ID for the device (optional)
 
-    This module supports up to 8 cards, autoprobe and hotplugging.
+    This module supports multiple devices, autoprobe and hotplugging.
 
   Module snd-usb-usx2y
   --------------------
 
     Module for Tascam USB US-122, US-224 and US-428 devices.
 
-    This module supports up to 8 cards, autoprobe and hotplugging.
+    This module supports multiple devices, autoprobe and hotplugging.
 
     Note: you need to load the firmware via usx2yloader utility included
           in alsa-tools and alsa-firmware packages.
@@ -1356,6 +1412,8 @@
     Note: for the MPU401 on VIA823x, use snd-mpu401 driver
 	  additionally.  The mpu_port option is for VIA686 chips only.
 
+    The power-management is supported.
+
   Module snd-via82xx-modem
   ------------------------
 
@@ -1368,6 +1426,8 @@
     Note: The default index value of this module is -2, i.e. the first
           slot is excluded.
 
+    The power-management is supported.
+
   Module snd-virmidi
   ------------------
 
@@ -1375,9 +1435,9 @@
     This module creates virtual rawmidi devices which communicate
     to the corresponding ALSA sequencer ports.
 
-    midi_devs	- MIDI devices # (1-8, default=4)
+    midi_devs	- MIDI devices # (1-4, default=4)
     
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
   Module snd-vx222
   ----------------
@@ -1387,7 +1447,7 @@
     mic		- Enable Microphone on V222 Mic (NYI)
     ibl		- Capture IBL size. (default = 0, minimum size)
 
-    Module supports up to 8 cards.
+    This module supports multiple cards.
 
     When the driver is compiled as a module and the hotplug firmware
     is supported, the firmware data is loaded via hotplug automatically.
@@ -1406,6 +1466,8 @@
     size is chosen.  The possible IBL values can be found in
     /proc/asound/cardX/vx-status proc file.
 
+    The power-management is supported.
+
   Module snd-vxpocket
   -------------------
 
@@ -1413,7 +1475,7 @@
 
     ibl      - Capture IBL size. (default = 0, minimum size)
 
-    Module supports up to 8 cards.  The module is compiled only when
+    This module supports multiple cards.  The module is compiled only when
     PCMCIA is supported on kernel.
 
     With the older 2.6.x kernel, to activate the driver via the card
@@ -1434,6 +1496,8 @@
     Note2: snd-vxp440 driver is merged to snd-vxpocket driver since
            ALSA 1.0.10.
 
+    The power-management is supported.
+
   Module snd-ymfpci
   -----------------
 
@@ -1447,7 +1511,7 @@
                     1 (auto-detect)
     rear_switch   - enable shared rear/line-in switch (bool)
 
-    Module supports autoprobe and multiple chips (max 8).
+    This module supports autoprobe and multiple chips.
 
     The power-management is supported.
 
@@ -1458,6 +1522,8 @@
 
     Note: the driver is build only when CONFIG_ISA is set.
 
+    The power-management is supported.
+
 
 AC97 Quirk Option
 =================
@@ -1474,7 +1540,7 @@
 
 The following strings are accepted:
     - default	Don't override the default setting
-    - disable	Disable the quirk
+    - none	Disable the quirk
     - hp_only	Bind Master and Headphone controls as a single control
     - swap_hp	Swap headphone and master controls
     - swap_surround  Swap master and surround controls
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 260334c..4963d83 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -18,8 +18,8 @@
       </affiliation>
      </author>
 
-     <date>October 6, 2005</date>
-     <edition>0.3.5</edition>
+     <date>November 17, 2005</date>
+     <edition>0.3.6</edition>
 
     <abstract>
       <para>
@@ -403,9 +403,8 @@
   static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 
   /* definition of the chip-specific record */
-  typedef struct snd_mychip mychip_t;
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
           // rest of implementation will be in the section
           // "PCI Resource Managements"
   };
@@ -413,7 +412,7 @@
   /* chip-specific destructor
    * (see "PCI Resource Managements")
    */
-  static int snd_mychip_free(mychip_t *chip)
+  static int snd_mychip_free(struct mychip *chip)
   {
           .... // will be implemented later...
   }
@@ -421,22 +420,21 @@
   /* component-destructor
    * (see "Management of Cards and Components")
    */
-  static int snd_mychip_dev_free(snd_device_t *device)
+  static int snd_mychip_dev_free(struct snd_device *device)
   {
-          mychip_t *chip = device->device_data;
-          return snd_mychip_free(chip);
+          return snd_mychip_free(device->device_data);
   }
 
   /* chip-specific constructor
    * (see "Management of Cards and Components")
    */
-  static int __devinit snd_mychip_create(snd_card_t *card,
+  static int __devinit snd_mychip_create(struct snd_card *card,
                                          struct pci_dev *pci,
-                                         mychip_t **rchip)
+                                         struct mychip **rchip)
   {
-          mychip_t *chip;
+          struct mychip *chip;
           int err;
-          static snd_device_ops_t ops = {
+          static struct snd_device_ops ops = {
                  .dev_free = snd_mychip_dev_free,
           };
 
@@ -474,8 +472,8 @@
                                const struct pci_device_id *pci_id)
   {
           static int dev;
-          snd_card_t *card;
-          mychip_t *chip;
+          struct snd_card *card;
+          struct mychip *chip;
           int err;
 
           /* (1) */
@@ -582,7 +580,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  snd_card_t *card;
+  struct snd_card *card;
   ....
   card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 ]]>
@@ -605,7 +603,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  mychip_t *chip;
+  struct mychip *chip;
   ....
   if ((err = snd_mychip_create(card, pci, &chip)) < 0) {
           snd_card_free(card);
@@ -806,7 +804,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_card_t *card;
+  struct snd_card *card;
   card = snd_card_new(index, id, module, extra_size);
 ]]>
           </programlisting>
@@ -830,7 +828,7 @@
       <para>
         After the card is created, you can attach the components
       (devices) to the card instance. On ALSA driver, a component is
-      represented as a <type>snd_device_t</type> object.
+      represented as a struct <structname>snd_device</structname> object.
       A component can be a PCM instance, a control interface, a raw
       MIDI interface, etc.  Each of such instances has one component
       entry.
@@ -891,14 +889,11 @@
       The chip-specific information, e.g. the i/o port address, its
       resource pointer, or the irq number, is stored in the
       chip-specific record.
-      Usually, the chip-specific record is typedef'ed as
-      <type>xxx_t</type> like the following:
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  typedef struct snd_mychip mychip_t;
-  struct snd_mychip {
+  struct mychip {
           ....
   };
 ]]>
@@ -918,12 +913,12 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(mychip_t));
+  card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct mychip));
 ]]>
             </programlisting>
           </informalexample>
 
-          whether <type>mychip_t</type> is the type of the chip record.
+          whether struct <structname>mychip</structname> is the type of the chip record.
         </para>
 
         <para>
@@ -932,7 +927,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  mychip_t *chip = (mychip_t *)card->private_data;
+  struct mychip *chip = (struct mychip *)card->private_data;
 ]]>
             </programlisting>
           </informalexample>
@@ -954,8 +949,8 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  snd_card_t *card;
-  mychip_t *chip;
+  struct snd_card *card;
+  struct mychip *chip;
   card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
   .....
   chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -971,8 +966,8 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
           ....
   };
 ]]>
@@ -1000,7 +995,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static snd_device_ops_t ops = {
+  static struct snd_device_ops ops = {
           .dev_free =        snd_mychip_dev_free,
   };
   ....
@@ -1018,10 +1013,9 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_mychip_dev_free(snd_device_t *device)
+  static int snd_mychip_dev_free(struct snd_device *device)
   {
-          mychip_t *chip = device->device_data;
-          return snd_mychip_free(chip);
+          return snd_mychip_free(device->device_data);
   }
 ]]>
             </programlisting>
@@ -1087,15 +1081,15 @@
           <title>PCI Resource Managements Example</title>
           <programlisting>
 <![CDATA[
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
           struct pci_dev *pci;
 
           unsigned long port;
           int irq;
   };
 
-  static int snd_mychip_free(mychip_t *chip)
+  static int snd_mychip_free(struct mychip *chip)
   {
           /* disable hardware here if any */
           .... // (not implemented in this document)
@@ -1113,13 +1107,13 @@
   }
 
   /* chip-specific constructor */
-  static int __devinit snd_mychip_create(snd_card_t *card,
+  static int __devinit snd_mychip_create(struct snd_card *card,
                                          struct pci_dev *pci,
-                                         mychip_t **rchip)
+                                         struct mychip **rchip)
   {
-          mychip_t *chip;
+          struct mychip *chip;
           int err;
-          static snd_device_ops_t ops = {
+          static struct snd_device_ops ops = {
                  .dev_free = snd_mychip_dev_free,
           };
 
@@ -1155,8 +1149,7 @@
           }
           chip->port = pci_resource_start(pci, 0);
           if (request_irq(pci->irq, snd_mychip_interrupt,
-                          SA_INTERRUPT|SA_SHIRQ, "My Chip",
-                          (void *)chip)) {
+                          SA_INTERRUPT|SA_SHIRQ, "My Chip", chip)) {
                   printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
                   snd_mychip_free(chip);
                   return -EBUSY;
@@ -1268,14 +1261,14 @@
 
       <para>
         Now assume that this PCI device has an I/O port with 8 bytes
-        and an interrupt. Then <type>mychip_t</type> will have the
+        and an interrupt. Then struct <structname>mychip</structname> will have the
         following fields: 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  struct snd_mychip {
-          snd_card_t *card;
+  struct mychip {
+          struct snd_card *card;
 
           unsigned long port;
           int irq;
@@ -1330,8 +1323,7 @@
           <programlisting>
 <![CDATA[
   if (request_irq(pci->irq, snd_mychip_interrupt,
-                  SA_INTERRUPT|SA_SHIRQ, "My Chip",
-                  (void *)chip)) {
+                  SA_INTERRUPT|SA_SHIRQ, "My Chip", chip)) {
           printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
           snd_mychip_free(chip);
           return -EBUSY;
@@ -1372,7 +1364,7 @@
   static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
   {
-          mychip_t *chip = dev_id;
+          struct mychip *chip = dev_id;
           ....
           return IRQ_HANDLED;
   }
@@ -1487,7 +1479,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  struct snd_mychip {
+  struct mychip {
           ....
           unsigned long iobase_phys;
           void __iomem *iobase_virt;
@@ -1517,7 +1509,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int snd_mychip_free(mychip_t *chip)
+  static int snd_mychip_free(struct mychip *chip)
   {
           ....
           if (chip->iobase_virt)
@@ -1537,7 +1529,7 @@
       <title>Registration of Device Struct</title>
       <para>
 	At some point, typically after calling <function>snd_device_new()</function>,
-	you need to register the <structname>struct device</structname> of the chip
+	you need to register the struct <structname>device</structname> of the chip
 	you're handling for udev and co.  ALSA provides a macro for compatibility with
 	older kernels.  Simply call like the following:
         <informalexample>
@@ -1739,7 +1731,7 @@
   ....
 
   /* hardware definition */
-  static snd_pcm_hardware_t snd_mychip_playback_hw = {
+  static struct snd_pcm_hardware snd_mychip_playback_hw = {
           .info = (SNDRV_PCM_INFO_MMAP |
                    SNDRV_PCM_INFO_INTERLEAVED |
                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1758,7 +1750,7 @@
   };
 
   /* hardware definition */
-  static snd_pcm_hardware_t snd_mychip_capture_hw = {
+  static struct snd_pcm_hardware snd_mychip_capture_hw = {
           .info = (SNDRV_PCM_INFO_MMAP |
                    SNDRV_PCM_INFO_INTERLEAVED |
                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1777,10 +1769,10 @@
   };
 
   /* open callback */
-  static int snd_mychip_playback_open(snd_pcm_substream_t *substream)
+  static int snd_mychip_playback_open(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           runtime->hw = snd_mychip_playback_hw;
           // more hardware-initialization will be done here
@@ -1788,19 +1780,19 @@
   }
 
   /* close callback */
-  static int snd_mychip_playback_close(snd_pcm_substream_t *substream)
+  static int snd_mychip_playback_close(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           // the hardware-specific codes will be here
           return 0;
 
   }
 
   /* open callback */
-  static int snd_mychip_capture_open(snd_pcm_substream_t *substream)
+  static int snd_mychip_capture_open(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           runtime->hw = snd_mychip_capture_hw;
           // more hardware-initialization will be done here
@@ -1808,33 +1800,33 @@
   }
 
   /* close callback */
-  static int snd_mychip_capture_close(snd_pcm_substream_t *substream)
+  static int snd_mychip_capture_close(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           // the hardware-specific codes will be here
           return 0;
 
   }
 
   /* hw_params callback */
-  static int snd_mychip_pcm_hw_params(snd_pcm_substream_t *substream,
-                               snd_pcm_hw_params_t * hw_params)
+  static int snd_mychip_pcm_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *hw_params)
   {
           return snd_pcm_lib_malloc_pages(substream,
                                      params_buffer_bytes(hw_params));
   }
 
   /* hw_free callback */
-  static int snd_mychip_pcm_hw_free(snd_pcm_substream_t *substream)
+  static int snd_mychip_pcm_hw_free(struct snd_pcm_substream *substream)
   {
           return snd_pcm_lib_free_pages(substream);
   }
 
   /* prepare callback */
-  static int snd_mychip_pcm_prepare(snd_pcm_substream_t *substream)
+  static int snd_mychip_pcm_prepare(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           /* set up the hardware with the current configuration
            * for example...
@@ -1849,7 +1841,7 @@
   }
 
   /* trigger callback */
-  static int snd_mychip_pcm_trigger(snd_pcm_substream_t *substream,
+  static int snd_mychip_pcm_trigger(struct snd_pcm_substream *substream,
                                     int cmd)
   {
           switch (cmd) {
@@ -1866,9 +1858,9 @@
 
   /* pointer callback */
   static snd_pcm_uframes_t
-  snd_mychip_pcm_pointer(snd_pcm_substream_t *substream)
+  snd_mychip_pcm_pointer(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           unsigned int current_ptr;
 
           /* get the current hardware pointer */
@@ -1877,7 +1869,7 @@
   }
 
   /* operators */
-  static snd_pcm_ops_t snd_mychip_playback_ops = {
+  static struct snd_pcm_ops snd_mychip_playback_ops = {
           .open =        snd_mychip_playback_open,
           .close =       snd_mychip_playback_close,
           .ioctl =       snd_pcm_lib_ioctl,
@@ -1889,7 +1881,7 @@
   };
 
   /* operators */
-  static snd_pcm_ops_t snd_mychip_capture_ops = {
+  static struct snd_pcm_ops snd_mychip_capture_ops = {
           .open =        snd_mychip_capture_open,
           .close =       snd_mychip_capture_close,
           .ioctl =       snd_pcm_lib_ioctl,
@@ -1905,9 +1897,9 @@
    */
 
   /* create a pcm device */
-  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
   {
-          snd_pcm_t *pcm;
+          struct snd_pcm *pcm;
           int err;
 
           if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
@@ -1944,9 +1936,9 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
   {
-          snd_pcm_t *pcm;
+          struct snd_pcm *pcm;
           int err;
 
           if ((err = snd_pcm_new(chip->card, "My Chip", 0, 1, 1,
@@ -1989,13 +1981,13 @@
       specify more numbers, but they must be handled properly in
       open/close, etc. callbacks.  When you need to know which
       substream you are referring to, then it can be obtained from
-      <type>snd_pcm_substream_t</type> data passed to each callback
+      struct <structname>snd_pcm_substream</structname> data passed to each callback
       as follows: 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_pcm_substream_t *substream;
+  struct snd_pcm_substream *substream;
   int index = substream->number;
 ]]>
           </programlisting>
@@ -2024,7 +2016,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static snd_pcm_ops_t snd_mychip_playback_ops = {
+  static struct snd_pcm_ops snd_mychip_playback_ops = {
           .open =        snd_mychip_pcm_open,
           .close =       snd_mychip_pcm_close,
           .ioctl =       snd_pcm_lib_ioctl,
@@ -2102,18 +2094,18 @@
           <title>PCM Instance with a Destructor</title>
           <programlisting>
 <![CDATA[
-  static void mychip_pcm_free(snd_pcm_t *pcm)
+  static void mychip_pcm_free(struct snd_pcm *pcm)
   {
-          mychip_t *chip = snd_pcm_chip(pcm);
+          struct mychip *chip = snd_pcm_chip(pcm);
           /* free your own data */
           kfree(chip->my_private_pcm_data);
           // do what you like else
           ....
   }
 
-  static int __devinit snd_mychip_new_pcm(mychip_t *chip)
+  static int __devinit snd_mychip_new_pcm(struct mychip *chip)
   {
-          snd_pcm_t *pcm;
+          struct snd_pcm *pcm;
           ....
           /* allocate your own data */
           chip->my_private_pcm_data = kmalloc(...);
@@ -2149,7 +2141,7 @@
 <![CDATA[
 struct _snd_pcm_runtime {
 	/* -- Status -- */
-	snd_pcm_substream_t *trigger_master;
+	struct snd_pcm_substream *trigger_master;
 	snd_timestamp_t trigger_tstamp;	/* trigger timestamp */
 	int overrange;
 	snd_pcm_uframes_t avail_max;
@@ -2192,8 +2184,8 @@
 	snd_pcm_sync_id_t sync;		/* hardware synchronization ID */
 
 	/* -- mmap -- */
-	volatile snd_pcm_mmap_status_t *status;
-	volatile snd_pcm_mmap_control_t *control;
+	volatile struct snd_pcm_mmap_status *status;
+	volatile struct snd_pcm_mmap_control *control;
 	atomic_t mmap_count;
 
 	/* -- locking / scheduling -- */
@@ -2204,15 +2196,15 @@
 
 	/* -- private section -- */
 	void *private_data;
-	void (*private_free)(snd_pcm_runtime_t *runtime);
+	void (*private_free)(struct snd_pcm_runtime *runtime);
 
 	/* -- hardware description -- */
-	snd_pcm_hardware_t hw;
-	snd_pcm_hw_constraints_t hw_constraints;
+	struct snd_pcm_hardware hw;
+	struct snd_pcm_hw_constraints hw_constraints;
 
 	/* -- interrupt callbacks -- */
-	void (*transfer_ack_begin)(snd_pcm_substream_t *substream);
-	void (*transfer_ack_end)(snd_pcm_substream_t *substream);
+	void (*transfer_ack_begin)(struct snd_pcm_substream *substream);
+	void (*transfer_ack_end)(struct snd_pcm_substream *substream);
 
 	/* -- timer -- */
 	unsigned int timer_resolution;	/* timer resolution */
@@ -2226,7 +2218,7 @@
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	/* -- OSS things -- */
-	snd_pcm_oss_runtime_t oss;
+	struct snd_pcm_oss_runtime oss;
 #endif
 };
 ]]>
@@ -2252,7 +2244,7 @@
 	<section id="pcm-interface-runtime-hw">
 	<title>Hardware Description</title>
 	<para>
-	  The hardware descriptor (<type>snd_pcm_hardware_t</type>)
+	  The hardware descriptor (struct <structname>snd_pcm_hardware</structname>)
 	contains the definitions of the fundamental hardware
 	configuration.  Above all, you'll need to define this in
 	<link linkend="pcm-interface-operators-open-callback"><citetitle>
@@ -2267,7 +2259,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct snd_pcm_runtime *runtime = substream->runtime;
           ...
           runtime->hw = snd_mychip_playback_hw; /* common definition */
           if (chip->model == VERY_OLD_ONE)
@@ -2282,7 +2274,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static snd_pcm_hardware_t snd_mychip_playback_hw = {
+  static struct snd_pcm_hardware snd_mychip_playback_hw = {
           .info = (SNDRV_PCM_INFO_MMAP |
                    SNDRV_PCM_INFO_INTERLEAVED |
                    SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -2337,9 +2329,14 @@
         <constant>PAUSE</constant> bit means that the pcm supports the
         <quote>pause</quote> operation, while the
         <constant>RESUME</constant> bit means that the pcm supports
-        the <quote>suspend/resume</quote> operation. If these flags
-        are set, the <structfield>trigger</structfield> callback below
-        must handle the corresponding commands. 
+        the full <quote>suspend/resume</quote> operation.
+	If <constant>PAUSE</constant> flag is set,
+	the <structfield>trigger</structfield> callback below
+        must handle the corresponding (pause push/release) commands.
+	The suspend/resume trigger commands can be defined even without
+	<constant>RESUME</constant> flag.  See <link
+	linkend="power-management"><citetitle>
+	Power Management</citetitle></link> section for details.
         </para>
 
 	<para>
@@ -2512,7 +2509,7 @@
 	<title>Running Status</title>
 	<para>
 	The running status can be referred via <constant>runtime-&gt;status</constant>.
-	This is the pointer to <type>snd_pcm_mmap_status_t</type>
+	This is the pointer to struct <structname>snd_pcm_mmap_status</structname>
 	record.  For example, you can get the current DMA hardware
 	pointer via <constant>runtime-&gt;status-&gt;hw_ptr</constant>.
 	</para>
@@ -2520,7 +2517,7 @@
 	<para>
 	The DMA application pointer can be referred via
 	<constant>runtime-&gt;control</constant>, which points
-	<type>snd_pcm_mmap_control_t</type> record.
+	struct <structname>snd_pcm_mmap_control</structname> record.
 	However, accessing directly to this value is not recommended.
 	</para>
 	</section>
@@ -2542,9 +2539,9 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_pcm_substream_t *substream)
+  static int snd_xxx_open(struct snd_pcm_substream *substream)
   {
-          my_pcm_data_t *data;
+          struct my_pcm_data *data;
           ....
           data = kmalloc(sizeof(*data), GFP_KERNEL);
           substream->runtime->private_data = data;
@@ -2586,7 +2583,7 @@
 
       <para>
         The callback function takes at least the argument with
-        <type>snd_pcm_substream_t</type> pointer. For retrieving the
+        <structname>snd_pcm_substream</structname> pointer. For retrieving the
         chip record from the given substream instance, you can use the
         following macro. 
 
@@ -2594,7 +2591,7 @@
           <programlisting>
 <![CDATA[
   int xxx() {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
+          struct mychip *chip = snd_pcm_substream_chip(substream);
           ....
   }
 ]]>
@@ -2616,7 +2613,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_pcm_substream_t *substream);
+  static int snd_xxx_open(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2631,10 +2628,10 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_pcm_substream_t *substream)
+  static int snd_xxx_open(struct snd_pcm_substream *substream)
   {
-          mychip_t *chip = snd_pcm_substream_chip(substream);
-          snd_pcm_runtime_t *runtime = substream->runtime;
+          struct mychip *chip = snd_pcm_substream_chip(substream);
+          struct snd_pcm_runtime *runtime = substream->runtime;
 
           runtime->hw = snd_mychip_playback_hw;
           return 0;
@@ -2667,7 +2664,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_close(snd_pcm_substream_t *substream);
+  static int snd_xxx_close(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2682,7 +2679,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_close(snd_pcm_substream_t *substream)
+  static int snd_xxx_close(struct snd_pcm_substream *substream)
   {
           ....
           kfree(substream->runtime->private_data);
@@ -2709,8 +2706,8 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_hw_params(snd_pcm_substream_t * substream,
-                               snd_pcm_hw_params_t * hw_params);
+  static int snd_xxx_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *hw_params);
 ]]>
             </programlisting>
           </informalexample>
@@ -2785,7 +2782,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_hw_free(snd_pcm_substream_t * substream);
+  static int snd_xxx_hw_free(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2820,7 +2817,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_prepare(snd_pcm_substream_t * substream);
+  static int snd_xxx_prepare(struct snd_pcm_substream *substream);
 ]]>
             </programlisting>
           </informalexample>
@@ -2869,7 +2866,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_xxx_trigger(snd_pcm_substream_t * substream, int cmd);
+  static int snd_xxx_trigger(struct snd_pcm_substream *substream, int cmd);
 ]]>
             </programlisting>
           </informalexample>
@@ -2911,8 +2908,8 @@
         </para>
 
         <para>
-          When the pcm supports the suspend/resume operation
-        (i.e. <constant>SNDRV_PCM_INFO_RESUME</constant> flag is set),
+          When the pcm supports the suspend/resume operation,
+	regardless of full or partial suspend/resume support,
         <constant>SUSPEND</constant> and <constant>RESUME</constant>
         commands must be handled, too.
         These commands are issued when the power-management status is
@@ -2921,6 +2918,8 @@
         do suspend and resume of the pcm substream, and usually, they
         are identical with <constant>STOP</constant> and
         <constant>START</constant> commands, respectively.
+	  See <link linkend="power-management"><citetitle>
+	Power Management</citetitle></link> section for details.
         </para>
 
         <para>
@@ -2939,7 +2938,7 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static snd_pcm_uframes_t snd_xxx_pointer(snd_pcm_substream_t * substream)
+  static snd_pcm_uframes_t snd_xxx_pointer(struct snd_pcm_substream *substream)
 ]]>
             </programlisting>
           </informalexample>
@@ -3067,7 +3066,7 @@
   static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
   {
-          mychip_t *chip = dev_id;
+          struct mychip *chip = dev_id;
           spin_lock(&chip->lock);
           ....
           if (pcm_irq_invoked(chip)) {
@@ -3111,7 +3110,7 @@
   static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
                                           struct pt_regs *regs)
   {
-          mychip_t *chip = dev_id;
+          struct mychip *chip = dev_id;
           spin_lock(&chip->lock);
           ....
           if (pcm_irq_invoked(chip)) {
@@ -3221,13 +3220,13 @@
 <![CDATA[
   static unsigned int rates[] =
           {4000, 10000, 22050, 44100};
-  static snd_pcm_hw_constraint_list_t constraints_rates = {
+  static struct snd_pcm_hw_constraint_list constraints_rates = {
           .count = ARRAY_SIZE(rates),
           .list = rates,
           .mask = 0,
   };
 
-  static int snd_mychip_pcm_open(snd_pcm_substream_t *substream)
+  static int snd_mychip_pcm_open(struct snd_pcm_substream *substream)
   {
           int err;
           ....
@@ -3249,19 +3248,20 @@
         You can even define your own constraint rules.
         For example, let's suppose my_chip can manage a substream of 1 channel
         if and only if the format is S16_LE, otherwise it supports any format
-        specified in the <type>snd_pcm_hardware_t</type> stucture (or in any
+        specified in the <structname>snd_pcm_hardware</structname> stucture (or in any
         other constraint_list). You can build a rule like this:
 
         <example>
 	  <title>Example of Hardware Constraints for Channels</title>
 	  <programlisting>
 <![CDATA[
-  static int hw_rule_format_by_channels(snd_pcm_hw_params_t *params,
-                                        snd_pcm_hw_rule_t *rule)
+  static int hw_rule_format_by_channels(struct snd_pcm_hw_params *params,
+                                        struct snd_pcm_hw_rule *rule)
   {
-          snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-          snd_mask_t *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
-          snd_mask_t fmt;
+          struct snd_interval *c = hw_param_interval(params,
+                SNDRV_PCM_HW_PARAM_CHANNELS);
+          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+          struct snd_mask fmt;
 
           snd_mask_any(&fmt);    /* Init the struct */
           if (c->min < 2) {
@@ -3298,12 +3298,13 @@
 	 <title>Example of Hardware Constraints for Channels</title>
 	 <programlisting>
 <![CDATA[
-  static int hw_rule_channels_by_format(snd_pcm_hw_params_t *params,
-                                        snd_pcm_hw_rule_t *rule)
+  static int hw_rule_channels_by_format(struct snd_pcm_hw_params *params,
+                                        struct snd_pcm_hw_rule *rule)
   {
-          snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-          snd_mask_t *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
-          snd_interval_t ch;
+          struct snd_interval *c = hw_param_interval(params,
+                        SNDRV_PCM_HW_PARAM_CHANNELS);
+          struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+          struct snd_interval ch;
 
           snd_interval_any(&ch);
           if (f->bits[0] == SNDRV_PCM_FMTBIT_S16_LE) {
@@ -3376,13 +3377,13 @@
       callbacks: <structfield>info</structfield>,
       <structfield>get</structfield> and
       <structfield>put</structfield>. Then, define a
-      <type>snd_kcontrol_new_t</type> record, such as: 
+      struct <structname>snd_kcontrol_new</structname> record, such as: 
 
         <example>
 	  <title>Definition of a Control</title>
           <programlisting>
 <![CDATA[
-  static snd_kcontrol_new_t my_control __devinitdata = {
+  static struct snd_kcontrol_new my_control __devinitdata = {
           .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
           .name = "PCM Playback Switch",
           .index = 0,
@@ -3599,7 +3600,7 @@
         <para>
           The <structfield>info</structfield> callback is used to get
         the detailed information of this control. This must store the
-        values of the given <type>snd_ctl_elem_info_t</type>
+        values of the given struct <structname>snd_ctl_elem_info</structname>
         object. For example, for a boolean control with a single
         element will be: 
 
@@ -3607,8 +3608,8 @@
 	    <title>Example of info callback</title>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_info(snd_kcontrol_t *kcontrol,
-                          snd_ctl_elem_info_t *uinfo)
+  static int snd_myctl_info(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_info *uinfo)
   {
           uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
           uinfo->count = 1;
@@ -3642,8 +3643,8 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_info(snd_kcontrol_t *kcontrol,
-                          snd_ctl_elem_info_t *uinfo)
+  static int snd_myctl_info(struct snd_kcontrol *kcontrol,
+                          struct snd_ctl_elem_info *uinfo)
   {
           static char *texts[4] = {
                   "First", "Second", "Third", "Fourth"
@@ -3678,10 +3679,10 @@
 	    <title>Example of get callback</title>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_get(snd_kcontrol_t *kcontrol,
-                           snd_ctl_elem_value_t *ucontrol)
+  static int snd_myctl_get(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
   {
-          mychip_t *chip = snd_kcontrol_chip(kcontrol);
+          struct mychip *chip = snd_kcontrol_chip(kcontrol);
           ucontrol->value.integer.value[0] = get_some_value(chip);
           return 0;
   }
@@ -3717,8 +3718,8 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  static int snd_sbmixer_get_single(snd_kcontrol_t *kcontrol,
-                                    snd_ctl_elem_value_t *ucontrol)
+  static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol,
+                                    struct snd_ctl_elem_value *ucontrol)
   {
           int reg = kcontrol->private_value & 0xff;
           int shift = (kcontrol->private_value >> 16) & 0xff;
@@ -3754,10 +3755,10 @@
 	    <title>Example of put callback</title>
             <programlisting>
 <![CDATA[
-  static int snd_myctl_put(snd_kcontrol_t *kcontrol,
-                           snd_ctl_elem_value_t *ucontrol)
+  static int snd_myctl_put(struct snd_kcontrol *kcontrol,
+                           struct snd_ctl_elem_value *ucontrol)
   {
-          mychip_t *chip = snd_kcontrol_chip(kcontrol);
+          struct mychip *chip = snd_kcontrol_chip(kcontrol);
           int changed = 0;
           if (chip->current_value !=
                ucontrol->value.integer.value[0]) {
@@ -3814,7 +3815,7 @@
         </informalexample>
 
         where <parameter>my_control</parameter> is the
-      <type>snd_kcontrol_new_t</type> object defined above, and chip
+      struct <structname>snd_kcontrol_new</structname> object defined above, and chip
       is the object pointer to be passed to
       kcontrol-&gt;private_data 
       which can be referred in callbacks. 
@@ -3822,7 +3823,7 @@
 
       <para>
         <function>snd_ctl_new1()</function> allocates a new
-      <type>snd_kcontrol_t</type> instance (that's why the definition
+      <structname>snd_kcontrol</structname> instance (that's why the definition
       of <parameter>my_control</parameter> can be with
       <parameter>__devinitdata</parameter> 
       prefix), and <function>snd_ctl_add</function> assigns the given
@@ -3849,7 +3850,7 @@
       control id pointer for the notification. The event-mask
       specifies the types of notification, for example, in the above
       example, the change of control values is notified.
-      The id pointer is the pointer of <type>snd_ctl_elem_id_t</type>
+      The id pointer is the pointer of struct <structname>snd_ctl_elem_id</structname>
       to be notified.
       You can find some examples in <filename>es1938.c</filename> or
       <filename>es1968.c</filename> for hardware volume interrupts. 
@@ -3882,35 +3883,35 @@
 	    <title>Example of AC97 Interface</title>
             <programlisting>
 <![CDATA[
-  struct snd_mychip {
+  struct mychip {
           ....
-          ac97_t *ac97;
+          struct snd_ac97 *ac97;
           ....
   };
 
-  static unsigned short snd_mychip_ac97_read(ac97_t *ac97,
+  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
                                              unsigned short reg)
   {
-          mychip_t *chip = ac97->private_data;
+          struct mychip *chip = ac97->private_data;
           ....
           // read a register value here from the codec
           return the_register_value;
   }
 
-  static void snd_mychip_ac97_write(ac97_t *ac97,
+  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
                                    unsigned short reg, unsigned short val)
   {
-          mychip_t *chip = ac97->private_data;
+          struct mychip *chip = ac97->private_data;
           ....
           // write the given register value to the codec
   }
 
-  static int snd_mychip_ac97(mychip_t *chip)
+  static int snd_mychip_ac97(struct mychip *chip)
   {
-          ac97_bus_t *bus;
-          ac97_template_t ac97;
+          struct snd_ac97_bus *bus;
+          struct snd_ac97_template ac97;
           int err;
-          static ac97_bus_ops_t ops = {
+          static struct snd_ac97_bus_ops ops = {
                   .write = snd_mychip_ac97_write,
                   .read = snd_mychip_ac97_read,
           };
@@ -3937,8 +3938,8 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  ac97_bus_t *bus;
-  static ac97_bus_ops_t ops = {
+  struct snd_ac97_bus *bus;
+  static struct snd_ac97_bus_ops ops = {
         .write = snd_mychip_ac97_write,
         .read = snd_mychip_ac97_read,
   };
@@ -3952,13 +3953,14 @@
       </para>
 
       <para>
-      And then call <function>snd_ac97_mixer()</function> with an <type>ac97_template_t</type>
+      And then call <function>snd_ac97_mixer()</function> with an
+      struct <structname>snd_ac97_template</structname>
       record together with the bus pointer created above.
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  ac97_template_t ac97;
+  struct snd_ac97_template ac97;
   int err;
 
   memset(&ac97, 0, sizeof(ac97));
@@ -3995,10 +3997,10 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static unsigned short snd_mychip_ac97_read(ac97_t *ac97,
+  static unsigned short snd_mychip_ac97_read(struct snd_ac97 *ac97,
                                              unsigned short reg)
   {
-          mychip_t *chip = ac97->private_data;
+          struct mychip *chip = ac97->private_data;
           ....
           return the_register_value;
   }
@@ -4016,7 +4018,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void snd_mychip_ac97_write(ac97_t *ac97,
+  static void snd_mychip_ac97_write(struct snd_ac97 *ac97,
                        unsigned short reg, unsigned short val)
 ]]>
           </programlisting>
@@ -4163,7 +4165,7 @@
       <title>Multiple Codecs</title>
       <para>
         When there are several codecs on the same card, you need to
-      call <function>snd_ac97_new()</function> multiple times with
+      call <function>snd_ac97_mixer()</function> multiple times with
       ac97.num=1 or greater. The <structfield>num</structfield> field
       specifies the codec 
       number. 
@@ -4212,7 +4214,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_rawmidi_t *rmidi;
+  struct snd_rawmidi *rmidi;
   snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, integrated,
                       irq, irq_flags, &rmidi);
 ]]>
@@ -4253,17 +4255,17 @@
         Usually, the port address corresponds to the command port and
         port + 1 corresponds to the data port. If not, you may change
         the <structfield>cport</structfield> field of
-        <type>mpu401_t</type> manually 
-        afterward. However, <type>mpu401_t</type> pointer is not
+        struct <structname>snd_mpu401</structname> manually 
+        afterward. However, <structname>snd_mpu401</structname> pointer is not
         returned explicitly by
         <function>snd_mpu401_uart_new()</function>. You need to cast
         rmidi-&gt;private_data to
-        <type>mpu401_t</type> explicitly, 
+        <structname>snd_mpu401</structname> explicitly, 
 
         <informalexample>
           <programlisting>
 <![CDATA[
-  mpu401_t *mpu;
+  struct snd_mpu401 *mpu;
   mpu = rmidi->private_data;
 ]]>
           </programlisting>
@@ -4359,7 +4361,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_rawmidi_t *rmidi;
+  struct snd_rawmidi *rmidi;
   err = snd_rawmidi_new(chip->card, "MyMIDI", 0, outs, ins, &rmidi);
   if (err < 0)
           return err;
@@ -4419,7 +4421,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static snd_rawmidi_ops_t snd_mymidi_output_ops = {
+  static struct snd_rawmidi_ops snd_mymidi_output_ops = {
           .open =    snd_mymidi_output_open,
           .close =   snd_mymidi_output_close,
           .trigger = snd_mymidi_output_trigger,
@@ -4439,9 +4441,9 @@
           <programlisting>
 <![CDATA[
   struct list_head *list;
-  snd_rawmidi_substream_t *substream;
+  struct snd_rawmidi_substream *substream;
   list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
-          substream = list_entry(list, snd_rawmidi_substream_t, list);
+          substream = list_entry(list, struct snd_rawmidi_substream, list);
           sprintf(substream->name, "My MIDI Port %d", substream->number + 1);
   }
   /* same for SNDRV_RAWMIDI_STREAM_INPUT */
@@ -4463,12 +4465,12 @@
 
       <para>
       If there is more than one port, your callbacks can determine the
-      port index from the snd_rawmidi_substream_t data passed to each
+      port index from the struct snd_rawmidi_substream data passed to each
       callback:
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_rawmidi_substream_t *substream;
+  struct snd_rawmidi_substream *substream;
   int index = substream->number;
 ]]>
           </programlisting>
@@ -4481,7 +4483,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int snd_xxx_open(snd_rawmidi_substream_t *substream);
+  static int snd_xxx_open(struct snd_rawmidi_substream *substream);
 ]]>
           </programlisting>
         </informalexample>
@@ -4499,7 +4501,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int snd_xxx_close(snd_rawmidi_substream_t *substream);
+  static int snd_xxx_close(struct snd_rawmidi_substream *substream);
 ]]>
           </programlisting>
         </informalexample>
@@ -4522,7 +4524,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void snd_xxx_output_trigger(snd_rawmidi_substream_t *substream, int up);
+  static void snd_xxx_output_trigger(struct snd_rawmidi_substream *substream, int up);
 ]]>
           </programlisting>
         </informalexample>
@@ -4547,7 +4549,7 @@
 <![CDATA[
   unsigned char data;
   while (snd_rawmidi_transmit_peek(substream, &data, 1) == 1) {
-          if (mychip_try_to_transmit(data))
+          if (snd_mychip_try_to_transmit(data))
                   snd_rawmidi_transmit_ack(substream, 1);
           else
                   break; /* hardware FIFO full */
@@ -4564,11 +4566,11 @@
           <informalexample>
             <programlisting>
 <![CDATA[
-  while (mychip_transmit_possible()) {
+  while (snd_mychip_transmit_possible()) {
           unsigned char data;
           if (snd_rawmidi_transmit(substream, &data, 1) != 1)
                   break; /* no more data */
-          mychip_transmit(data);
+          snd_mychip_transmit(data);
   }
 ]]>
             </programlisting>
@@ -4603,7 +4605,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void snd_xxx_input_trigger(snd_rawmidi_substream_t *substream, int up);
+  static void snd_xxx_input_trigger(struct snd_rawmidi_substream *substream, int up);
 ]]>
           </programlisting>
         </informalexample>
@@ -4647,7 +4649,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void snd_xxx_drain(snd_rawmidi_substream_t *substream);
+  static void snd_xxx_drain(struct snd_rawmidi_substream *substream);
 ]]>
           </programlisting>
         </informalexample>
@@ -4661,7 +4663,7 @@
 
         <para>
         This callback is optional.  If you do not set
-        <structfield>drain</structfield> in the snd_rawmidi_ops_t
+        <structfield>drain</structfield> in the struct snd_rawmidi_ops
         structure, ALSA will simply wait for 50&nbsp;milliseconds
         instead.
         </para>
@@ -4703,7 +4705,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  opl3_t *opl3;
+  struct snd_opl3 *opl3;
   snd_opl3_create(card, lport, rport, OPL3_HW_OPL3_XXX,
                   integrated, &opl3);
 ]]>
@@ -4736,7 +4738,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  opl3_t *opl3;
+  struct snd_opl3 *opl3;
   snd_opl3_new(card, OPL3_HW_OPL3_XXX, &opl3);
 ]]>
           </programlisting>
@@ -4767,7 +4769,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_hwdep_t *opl3hwdep;
+  struct snd_hwdep *opl3hwdep;
   snd_opl3_hwdep_new(opl3, 0, 1, &opl3hwdep);
 ]]>
           </programlisting>
@@ -4804,7 +4806,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_hwdep_t *hw;
+  struct snd_hwdep *hw;
   snd_hwdep_new(card, "My HWDEP", 0, &hw);
 ]]>
           </programlisting>
@@ -4823,7 +4825,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  mydata_t *p = kmalloc(sizeof(*p), GFP_KERNEL);
+  struct mydata *p = kmalloc(sizeof(*p), GFP_KERNEL);
   hw->private_data = p;
   hw->private_free = mydata_free;
 ]]>
@@ -4835,9 +4837,9 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static void mydata_free(snd_hwdep_t *hw)
+  static void mydata_free(struct snd_hwdep *hw)
   {
-          mydata_t *p = hw->private_data;
+          struct mydata *p = hw->private_data;
           kfree(p);
   }
 ]]>
@@ -5061,9 +5063,9 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int playback_copy(snd_pcm_substream_t *substream, int channel,
+  static int playback_copy(struct snd_pcm_substream *substream, int channel,
                snd_pcm_uframes_t pos, void *src, snd_pcm_uframes_t count);
-  static int capture_copy(snd_pcm_substream_t *substream, int channel,
+  static int capture_copy(struct snd_pcm_substream *substream, int channel,
                snd_pcm_uframes_t pos, void *dst, snd_pcm_uframes_t count);
 ]]>
           </programlisting>
@@ -5144,7 +5146,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  static int silence(snd_pcm_substream_t *substream, int channel,
+  static int silence(struct snd_pcm_substream *substream, int channel,
                      snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
 ]]>
           </programlisting>
@@ -5211,7 +5213,7 @@
         <informalexample>
           <programlisting>
 <![CDATA[
-  snd_pcm_sgbuf_t *sgbuf = (snd_pcm_sgbuf_t*)substream->dma_private;
+  struct snd_sg_buf *sgbuf = (struct snd_sg_buf_t*)substream->dma_private;
 ]]>
           </programlisting>
         </informalexample>
@@ -5266,7 +5268,7 @@
   #include <linux/vmalloc.h>
 
   /* get the physical page pointer on the given offset */
-  static struct page *mychip_page(snd_pcm_substream_t *substream,
+  static struct page *mychip_page(struct snd_pcm_substream *substream,
                                   unsigned long offset)
   {
           void *pageptr = substream->runtime->dma_area + offset;
@@ -5301,7 +5303,7 @@
       <informalexample>
         <programlisting>
 <![CDATA[
-  snd_info_entry_t *entry;
+  struct snd_info_entry *entry;
   int err = snd_card_proc_new(card, "my-file", &entry);
 ]]>
         </programlisting>
@@ -5345,8 +5347,8 @@
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void my_proc_read(snd_info_entry_t *entry,
-                           snd_info_buffer_t *buffer);
+  static void my_proc_read(struct snd_info_entry *entry,
+                           struct snd_info_buffer *buffer);
 ]]>
         </programlisting>
       </informalexample>
@@ -5361,10 +5363,10 @@
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void my_proc_read(snd_info_entry_t *entry,
-                           snd_info_buffer_t *buffer)
+  static void my_proc_read(struct snd_info_entry *entry,
+                           struct snd_info_buffer *buffer)
   {
-          chip_t *chip = entry->private_data;
+          struct my_chip *chip = entry->private_data;
 
           snd_iprintf(buffer, "This is my chip!\n");
           snd_iprintf(buffer, "Port = %ld\n", chip->port);
@@ -5453,7 +5455,7 @@
       <informalexample>
         <programlisting>
 <![CDATA[
-  static long my_file_io_read(snd_info_entry_t *entry,
+  static long my_file_io_read(struct snd_info_entry *entry,
                               void *file_private_data,
                               struct file *file,
                               char *buf,
@@ -5488,22 +5490,60 @@
       <constant>CONFIG_PM</constant>. 
     </para>
 
+	<para>
+	If the driver supports the suspend/resume
+	<emphasis>fully</emphasis>, that is, the device can be
+	properly resumed to the status at the suspend is called,
+	you can set <constant>SNDRV_PCM_INFO_RESUME</constant> flag
+	to pcm info field.  Usually, this is possible when the
+	registers of ths chip can be safely saved and restored to the
+	RAM.  If this is set, the trigger callback is called with
+	<constant>SNDRV_PCM_TRIGGER_RESUME</constant> after resume
+	callback is finished. 
+	</para>
+
+	<para>
+	Even if the driver doesn't support PM fully but only the
+	partial suspend/resume is possible, it's still worthy to
+	implement suspend/resume callbacks.  In such a case, applications
+	would reset the status by calling
+	<function>snd_pcm_prepare()</function> and restart the stream
+	appropriately.  Hence, you can define suspend/resume callbacks
+	below but don't set <constant>SNDRV_PCM_INFO_RESUME</constant>
+	info flag to the PCM.
+	</para>
+	
+	<para>
+	Note that the trigger with SUSPEND can be always called when
+	<function>snd_pcm_suspend_all</function> is called,
+	regardless of <constant>SNDRV_PCM_INFO_RESUME</constant> flag.
+	The <constant>RESUME</constant> flag affects only the behavior
+	of <function>snd_pcm_resume()</function>.
+	(Thus, in theory,
+	<constant>SNDRV_PCM_TRIGGER_RESUME</constant> isn't needed
+	to be handled in the trigger callback when no
+	<constant>SNDRV_PCM_INFO_RESUME</constant> flag is set.  But,
+	it's better to keep it for compatibility reason.)
+	</para>
     <para>
-      ALSA provides the common power-management layer. Each card driver
-      needs to have only low-level suspend and resume callbacks.
+      In the earlier version of ALSA drivers, a common
+      power-management layer was provided, but it has been removed.
+      The driver needs to define the suspend/resume hooks according to
+      the bus the device is assigned.  In the case of PCI driver, the
+      callbacks look like below:
 
       <informalexample>
         <programlisting>
 <![CDATA[
   #ifdef CONFIG_PM
-  static int snd_my_suspend(snd_card_t *card, pm_message_t state)
+  static int snd_my_suspend(struct pci_dev *pci, pm_message_t state)
   {
-          .... // do things for suspsend
+          .... /* do things for suspsend */
           return 0;
   }
-  static int snd_my_resume(snd_card_t *card)
+  static int snd_my_resume(struct pci_dev *pci)
   {
-          .... // do things for suspsend
+          .... /* do things for suspsend */
           return 0;
   }
   #endif
@@ -5516,11 +5556,18 @@
       The scheme of the real suspend job is as following.
 
       <orderedlist>
-        <listitem><para>Retrieve the chip data from pm_private_data field.</para></listitem>
+        <listitem><para>Retrieve the card and the chip data.</para></listitem>
+        <listitem><para>Call <function>snd_power_change_state()</function> with
+	  <constant>SNDRV_CTL_POWER_D3hot</constant> to change the
+	  power status.</para></listitem>
         <listitem><para>Call <function>snd_pcm_suspend_all()</function> to suspend the running PCM streams.</para></listitem>
+	<listitem><para>If AC97 codecs are used, call
+	<function>snd_ac97_resume()</function> for each codec.</para></listitem>
         <listitem><para>Save the register values if necessary.</para></listitem>
         <listitem><para>Stop the hardware if necessary.</para></listitem>
-        <listitem><para>Disable the PCI device by calling <function>pci_disable_device()</function>.</para></listitem>
+        <listitem><para>Disable the PCI device by calling
+	  <function>pci_disable_device()</function>.  Then, call
+          <function>pci_save_state()</function> at last.</para></listitem>
       </orderedlist>
     </para>
 
@@ -5530,18 +5577,24 @@
       <informalexample>
         <programlisting>
 <![CDATA[
-  static int mychip_suspend(snd_card_t *card, pm_message_t state)
+  static int mychip_suspend(strut pci_dev *pci, pm_message_t state)
   {
           /* (1) */
-          mychip_t *chip = card->pm_private_data;
+          struct snd_card *card = pci_get_drvdata(pci);
+          struct mychip *chip = card->private_data;
           /* (2) */
-          snd_pcm_suspend_all(chip->pcm);
+          snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
           /* (3) */
-          snd_mychip_save_registers(chip);
+          snd_pcm_suspend_all(chip->pcm);
           /* (4) */
-          snd_mychip_stop_hardware(chip);
+          snd_ac97_suspend(chip->ac97);
           /* (5) */
-          pci_disable_device(chip->pci);
+          snd_mychip_save_registers(chip);
+          /* (6) */
+          snd_mychip_stop_hardware(chip);
+          /* (7) */
+          pci_disable_device(pci);
+          pci_save_state(pci);
           return 0;
   }
 ]]>
@@ -5553,14 +5606,17 @@
     The scheme of the real resume job is as following.
 
     <orderedlist>
-    <listitem><para>Retrieve the chip data from pm_private_data field.</para></listitem>
-    <listitem><para>Enable the pci device again by calling
-    <function>pci_enable_device()</function>.</para></listitem>
+    <listitem><para>Retrieve the card and the chip data.</para></listitem>
+    <listitem><para>Set up PCI.  First, call <function>pci_restore_state()</function>.
+    	Then enable the pci device again by calling <function>pci_enable_device()</function>.
+	Call <function>pci_set_master()</function> if necessary, too.</para></listitem>
     <listitem><para>Re-initialize the chip.</para></listitem>
     <listitem><para>Restore the saved registers if necessary.</para></listitem>
     <listitem><para>Resume the mixer, e.g. calling
     <function>snd_ac97_resume()</function>.</para></listitem>
     <listitem><para>Restart the hardware (if any).</para></listitem>
+    <listitem><para>Call <function>snd_power_change_state()</function> with
+	<constant>SNDRV_CTL_POWER_D0</constant> to notify the processes.</para></listitem>
     </orderedlist>
     </para>
 
@@ -5570,12 +5626,15 @@
       <informalexample>
         <programlisting>
 <![CDATA[
-  static void mychip_resume(mychip_t *chip)
+  static int mychip_resume(struct pci_dev *pci)
   {
           /* (1) */
-          mychip_t *chip = card->pm_private_data;
+          struct snd_card *card = pci_get_drvdata(pci);
+          struct mychip *chip = card->private_data;
           /* (2) */
-          pci_enable_device(chip->pci);
+          pci_restore_state(pci);
+          pci_enable_device(pci);
+          pci_set_master(pci);
           /* (3) */
           snd_mychip_reinit_chip(chip);
           /* (4) */
@@ -5584,6 +5643,8 @@
           snd_ac97_resume(chip->ac97);
           /* (6) */
           snd_mychip_restart_chip(chip);
+          /* (7) */
+          snd_power_change_state(card, SNDRV_CTL_POWER_D0);
           return 0;
   }
 ]]>
@@ -5592,8 +5653,23 @@
     </para>
 
     <para>
-      OK, we have all callbacks now. Let's set up them now. In the
-      initialization of the card, add the following: 
+	As shown in the above, it's better to save registers after
+	suspending the PCM operations via
+	<function>snd_pcm_suspend_all()</function> or
+	<function>snd_pcm_suspend()</function>.  It means that the PCM
+	streams are already stoppped when the register snapshot is
+	taken.  But, remind that you don't have to restart the PCM
+	stream in the resume callback. It'll be restarted via 
+	trigger call with <constant>SNDRV_PCM_TRIGGER_RESUME</constant>
+	when necessary.
+    </para>
+
+    <para>
+      OK, we have all callbacks now. Let's set them up. In the
+      initialization of the card, make sure that you can get the chip
+      data from the card instance, typically via
+      <structfield>private_data</structfield> field, in case you
+      created the chip data individually.
 
       <informalexample>
         <programlisting>
@@ -5602,33 +5678,56 @@
                                const struct pci_device_id *pci_id)
   {
           ....
-          snd_card_t *card;
-          mychip_t *chip;
+          struct snd_card *card;
+          struct mychip *chip;
           ....
-          snd_card_set_pm_callback(card, snd_my_suspend, snd_my_resume, chip);
+          card = snd_card_new(index[dev], id[dev], THIS_MODULE, NULL);
+          ....
+          chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+          ....
+          card->private_data = chip;
           ....
   }
 ]]>
         </programlisting>
       </informalexample>
 
-    Here you don't have to put ifdef CONFIG_PM around, since it's already
-    checked in the header and expanded to empty if not needed.
+	When you created the chip data with
+	<function>snd_card_new()</function>, it's anyway accessible
+	via <structfield>private_data</structfield> field.
+
+      <informalexample>
+        <programlisting>
+<![CDATA[
+  static int __devinit snd_mychip_probe(struct pci_dev *pci,
+                               const struct pci_device_id *pci_id)
+  {
+          ....
+          struct snd_card *card;
+          struct mychip *chip;
+          ....
+          card = snd_card_new(index[dev], id[dev], THIS_MODULE,
+                              sizeof(struct mychip));
+          ....
+          chip = card->private_data;
+          ....
+  }
+]]>
+        </programlisting>
+      </informalexample>
+
     </para>
 
     <para>
-      If you need a space for saving the registers, you'll need to
-    allocate the buffer for it here, too, since it would be fatal
+      If you need a space for saving the registers, allocate the
+	buffer for it here, too, since it would be fatal
     if you cannot allocate a memory in the suspend phase.
     The allocated buffer should be released in the corresponding
     destructor.
     </para>
 
     <para>
-      And next, set suspend/resume callbacks to the pci_driver,
-      This can be done by passing a macro SND_PCI_PM_CALLBACKS
-      in the pci_driver struct.  This macro is expanded to the correct
-      (global) callbacks if CONFIG_PM is set.
+      And next, set suspend/resume callbacks to the pci_driver.
 
       <informalexample>
         <programlisting>
@@ -5638,7 +5737,10 @@
           .id_table = snd_my_ids,
           .probe = snd_my_probe,
           .remove = __devexit_p(snd_my_remove),
-          SND_PCI_PM_CALLBACKS
+  #ifdef CONFIG_PM
+          .suspend = snd_my_suspend,
+          .resume = snd_my_resume,
+  #endif
   };
 ]]>
         </programlisting>
diff --git a/Documentation/sound/alsa/Procfile.txt b/Documentation/sound/alsa/Procfile.txt
index 25c5d64..1fe4884 100644
--- a/Documentation/sound/alsa/Procfile.txt
+++ b/Documentation/sound/alsa/Procfile.txt
@@ -138,6 +138,22 @@
 	# echo 02 9f1f > /proc/asound/card0/codec97#0/ac97#0-0+regs
 
 
+USB Audio Streams
+-----------------
+
+card*/stream*
+	Shows the assignment and the current status of each audio stream
+	of the given card.  This information is very useful for debugging.
+
+
+HD-Audio Codecs
+---------------
+
+card*/codec#*
+	Shows the general codec information and the attribute of each
+	widget node.
+
+
 Sequencer Information
 ---------------------
 
diff --git a/Documentation/sound/alsa/hda_codec.txt b/Documentation/sound/alsa/hda_codec.txt
index e9d07b8..0be57ed 100644
--- a/Documentation/sound/alsa/hda_codec.txt
+++ b/Documentation/sound/alsa/hda_codec.txt
@@ -63,7 +63,7 @@
 the card instance, the template, and the pointer to store the
 resultant bus instance.
 
-int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp,
+int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
 		    struct hda_bus **busp);
 
 It returns zero if successful.  A negative return value means any
@@ -166,14 +166,14 @@
 
 struct hda_pcm_ops {
 	int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
-		    snd_pcm_substream_t *substream);
+		    struct snd_pcm_substream *substream);
 	int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
-		     snd_pcm_substream_t *substream);
+		     struct snd_pcm_substream *substream);
 	int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
 		       unsigned int stream_tag, unsigned int format,
-		       snd_pcm_substream_t *substream);
+		       struct snd_pcm_substream *substream);
 	int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
-		       snd_pcm_substream_t *substream);
+		       struct snd_pcm_substream *substream);
 };
 
 All are non-NULL, so you can call them safely without NULL check.
@@ -284,7 +284,7 @@
 returns the config field value.
 
 snd_hda_add_new_ctls() can be used to create and add control entries.
-Pass the zero-terminated array of snd_kcontrol_new_t.  The same array
+Pass the zero-terminated array of struct snd_kcontrol_new.  The same array
 can be passed to snd_hda_resume_ctls() for resume.
 Note that this will call control->put callback of these entries.  So,
 put callback should check codec->in_resume and force to restore the
@@ -292,7 +292,7 @@
 cached value.
 
 Macros HDA_CODEC_VOLUME(), HDA_CODEC_MUTE() and their variables can be
-used for the entry of snd_kcontrol_new_t.
+used for the entry of struct snd_kcontrol_new.
 
 The input MUX helper callbacks for such a control are provided, too:
 snd_hda_input_mux_info() and snd_hda_input_mux_put().  See
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt
index 2f1aae3..6910c01 100644
--- a/Documentation/sysctl/vm.txt
+++ b/Documentation/sysctl/vm.txt
@@ -26,12 +26,13 @@
 - min_free_kbytes
 - laptop_mode
 - block_dump
+- drop-caches
 
 ==============================================================
 
 dirty_ratio, dirty_background_ratio, dirty_expire_centisecs,
 dirty_writeback_centisecs, vfs_cache_pressure, laptop_mode,
-block_dump, swap_token_timeout:
+block_dump, swap_token_timeout, drop-caches:
 
 See Documentation/filesystems/proc.txt
 
@@ -102,3 +103,20 @@
 of kilobytes free.  The VM uses this number to compute a pages_min
 value for each lowmem zone in the system.  Each lowmem zone gets 
 a number of reserved free pages based proportionally on its size.
+
+==============================================================
+
+percpu_pagelist_fraction
+
+This is the fraction of pages at most (high mark pcp->high) in each zone that
+are allocated for each per cpu page list.  The min value for this is 8.  It
+means that we don't allow more than 1/8th of pages in each zone to be
+allocated in any single per_cpu_pagelist.  This entry only changes the value
+of hot per cpu pagelists.  User can specify a number like 100 to allocate
+1/100th of each zone to each per cpu page list.
+
+The batch value of each per cpu pagelist is also updated as a result.  It is
+set to pcp->high/4.  The upper limit of batch is (PAGE_SHIFT * 8)
+
+The initial value is zero.  Kernel does not use this value at boot time to set
+the high water marks for each per cpu page list.
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index baf17b3..ad0bedf 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -202,17 +202,13 @@
 
 *  I have more questions, who can I ask?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-You may feel free to send email to myrdraal@deathsdoor.com, and I will
-respond as soon as possible.
- -Myrdraal
-
 And I'll answer any questions about the registration system you got, also
 responding as soon as possible.
  -Crutcher
 
 *  Credits
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Written by Mydraal <myrdraal@deathsdoor.com>
+Written by Mydraal <vulpyne@vulpyne.net>
 Updated by Adam Sulmicki <adam@cfar.umd.edu>
 Updated by Jeremy M. Dolan <jmd@turbogeek.org> 2001/01/28 10:15:59
 Added to by Crutcher Dunnavant <crutcher+kernel@datastacks.com>
diff --git a/Documentation/usb/error-codes.txt b/Documentation/usb/error-codes.txt
index 1e36f16..867f4c3 100644
--- a/Documentation/usb/error-codes.txt
+++ b/Documentation/usb/error-codes.txt
@@ -46,8 +46,9 @@
 
 -EMSGSIZE	(a) endpoint maxpacket size is zero; it is not usable
 		    in the current interface altsetting.
-		(b) ISO packet is biger than endpoint maxpacket
-		(c) requested data transfer size is invalid (negative)
+		(b) ISO packet is larger than the endpoint maxpacket.
+		(c) requested data transfer length is invalid: negative
+		    or too large for the host controller.
 
 -ENOSPC		This request would overcommit the usb bandwidth reserved
 		for periodic transfers (interrupt, isochronous).
diff --git a/MAINTAINERS b/MAINTAINERS
index a74a0c7..76dc820 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -182,7 +182,7 @@
 ACPI
 P:	Len Brown
 M:	len.brown@intel.com
-L:	acpi-devel@lists.sourceforge.net
+L:	linux-acpi@vger.kernel.org
 W:	http://acpi.sourceforge.net/
 T:	git kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
 S:	Maintained
@@ -258,6 +258,13 @@
 M:	ink@jurassic.park.msu.ru
 S:	Maintained for 2.4; PCI support for 2.6.
 
+AMD GEODE PROCESSOR/CHIPSET SUPPORT
+P:      Jordan Crouse
+M:      info-linux@geode.amd.com
+L:	info-linux@geode.amd.com
+W:	http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
+S:	Supported
+
 APM DRIVER
 P:	Stephen Rothwell
 M:	sfr@canb.auug.org.au
@@ -536,6 +543,7 @@
 M:	mchehab@brturbo.com.br
 L:	video4linux-list@redhat.com
 W:	http://linuxtv.org
+T:	git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:	Maintained
 
 BUSLOGIC SCSI DRIVER
@@ -553,6 +561,11 @@
 T:	git kernel.org:/pub/scm/linux/kernel/git/sfrench/cifs-2.6.git
 S:	Supported	
 
+CONFIGFS
+P:	Joel Becker
+M:	Joel Becker <joel.becker@oracle.com>
+S:	Supported
+
 CIRRUS LOGIC GENERIC FBDEV DRIVER
 P:	Jeff Garzik
 M:	jgarzik@pobox.com
@@ -649,6 +662,11 @@
 T:	git kernel.org:/pub/scm/linux/kernel/git/herbert/crypto-2.6.git
 S:	Maintained
 
+CS5535 Audio ALSA driver
+P:	Jaya Kumar
+M:	jayakumar.alsa@gmail.com
+S:	Maintained
+
 CYBERPRO FB DRIVER
 P:	Russell King
 M:	rmk@arm.linux.org.uk
@@ -678,13 +696,6 @@
 W:	http://www.cyclades.com/
 S:	Supported
 
-DAC960 RAID CONTROLLER DRIVER
-P:	Dave Olien
-M	dmo@osdl.org
-W:	http://www.osdl.org/archive/dmo/DAC960
-L:	linux-kernel@vger.kernel.org
-S:	Maintained
-
 DAMA SLAVE for AX.25
 P:	Joerg Reuter
 M:	jreuter@yaina.de
@@ -833,6 +844,7 @@
 M: 	linux-dvb-maintainer@linuxtv.org
 L: 	linux-dvb@linuxtv.org (subscription required)
 W:	http://linuxtv.org/
+T:	git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:	Supported
 
 EATA-DMA SCSI DRIVER
@@ -915,7 +927,6 @@
 FARSYNC SYNCHRONOUS DRIVER
 P:	Kevin Curtis
 M:	kevin.curtis@farsite.co.uk
-M:	kevin.curtis@farsite.co.uk
 W:	http://www.farsite.co.uk/
 S:	Supported
 
@@ -1223,7 +1234,7 @@
 P:	Ben Collins
 M:	bcollins@debian.org
 P:	Jody McIntyre
-M:	scjody@steamballoon.com
+M:	scjody@modernduck.com
 L:	linux1394-devel@lists.sourceforge.net
 W:	http://www.linux1394.org/
 T:	git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git
@@ -1233,14 +1244,14 @@
 P:	Ben Collins
 M:	bcollins@debian.org
 P:	Jody McIntyre
-M:	scjody@steamballoon.com
+M:	scjody@modernduck.com
 L:	linux1394-devel@lists.sourceforge.net
 W:	http://www.linux1394.org/
 S:	Maintained
 
 IEEE 1394 PCILYNX DRIVER
 P:	Jody McIntyre
-M:	scjody@steamballoon.com
+M:	scjody@modernduck.com
 L:	linux1394-devel@lists.sourceforge.net
 W:	http://www.linux1394.org/
 S:	Maintained
@@ -1282,8 +1293,8 @@
 S:	Supported
 
 INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS
-P:	Vojtech Pavlik
-M:	vojtech@suse.cz
+P:	Dmitry Torokhov
+M:	dtor_core@ameritech.net
 L:	linux-input@atrey.karlin.mff.cuni.cz
 L:	linux-joystick@atrey.karlin.mff.cuni.cz
 T:	git kernel.org:/pub/scm/linux/kernel/git/dtor/input.git
@@ -1463,7 +1474,6 @@
 L:	kernel-janitors@osdl.org
 W:	http://www.kerneljanitors.org/
 W:	http://sf.net/projects/kernel-janitor/
-W:	http://developer.osdl.org/rddunlap/kj-patches/
 S:	Maintained
 
 KERNEL NFSD
@@ -1474,17 +1484,11 @@
 W:	http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
 S:	Maintained
 
-KERNEL EVENT LAYER (KOBJECT_UEVENT)
-P:	Robert Love
-M:	rml@novell.com
-L:	linux-kernel@vger.kernel.org
-S:	Maintained
-
 KEXEC
 P:	Eric Biederman
 P:	Randy Dunlap
 M:	ebiederm@xmission.com
-M:	rddunlap@osdl.org
+M:	rdunlap@xenotime.net
 W:	http://www.xmission.com/~ebiederm/files/kexec/
 L:	linux-kernel@vger.kernel.org
 L:	fastboot@osdl.org
@@ -1634,6 +1638,15 @@
 W:	http://ldm.sourceforge.net
 S:	Maintained
 
+LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
+P:	Eric Moore
+M:	Eric.Moore@lsil.com
+M:	support@lsil.com
+L:	mpt_linux_developer@lsil.com
+L:	linux-scsi@vger.kernel.org
+W:	http://www.lsilogic.com/support
+S:	Supported
+
 LSILOGIC/SYMBIOS/NCR 53C8XX and 53C1010 PCI-SCSI drivers
 P:	Matthew Wilcox
 M:	matthew@wil.cx
@@ -1889,6 +1902,15 @@
 L:	linux-nvidia@lists.surfsouth.com
 S:	Maintained
 
+ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
+P:	Mark Fasheh
+M:	mark.fasheh@oracle.com
+P:	Kurt Hackel
+M:	kurt.hackel@oracle.com
+L:	ocfs2-devel@oss.oracle.com
+W:	http://oss.oracle.com/projects/ocfs2/
+S:	Supported	
+
 OLYMPIC NETWORK DRIVER
 P:	Peter De Shrijver
 M:	p2@ace.ulyssis.student.kuleuven.ac.be
@@ -2576,7 +2598,6 @@
 UDF FILESYSTEM
 P:	Ben Fennema
 M:	bfennema@falcon.csc.calpoly.edu
-L:	linux_udf@hpesjro.fc.hp.com
 W:	http://linux-udf.sourceforge.net
 S:	Maintained
 
@@ -2629,6 +2650,12 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USB ISP116X DRIVER
+P:	Olav Kongas
+M:	ok@artecdesign.ee
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+
 USB KAWASAKI LSI DRIVER
 P:	Oliver Neukum
 M:	oliver@neukum.name
@@ -2640,7 +2667,7 @@
 P:	Matthew Dharm
 M:	mdharm-usb@one-eyed-alien.net
 L:	linux-usb-users@lists.sourceforge.net
-L:	linux-usb-devel@lists.sourceforge.net
+L:	usb-storage@lists.one-eyed-alien.net
 S:	Maintained
 W:	http://www.one-eyed-alien.net/~mdharm/linux-usb/
 
@@ -2885,6 +2912,13 @@
 M:	mchehab@brturbo.com.br
 L:	video4linux-list@redhat.com
 W:	http://linuxtv.org
+T:	git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
+S:	Maintained
+
+VT8231 HARDWARE MONITOR DRIVER
+P:	Roger Lucas
+M:	roger@planbit.co.uk
+L:	lm-sensors@lm-sensors.org
 S:	Maintained
 
 W1 DALLAS'S 1-WIRE BUS
diff --git a/Makefile b/Makefile
index e7a0443..599e744 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 15
-EXTRAVERSION =-rc2
-NAME=Affluent Albatross
+EXTRAVERSION =
+NAME=Sliding Snow Leopard
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
@@ -286,10 +286,6 @@
 cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
              > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)
 
-# For backward compatibility
-check_gcc = $(warning check_gcc is deprecated - use cc-option) \
-            $(call cc-option, $(1),$(2))
-
 # cc-option-yn
 # Usage: flag := $(call cc-option-yn, -march=winchip-c6)
 cc-option-yn = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
@@ -408,7 +404,7 @@
 # of make so .config is not included in this case either (for *config).
 
 no-dot-config-targets := clean mrproper distclean \
-			 cscope TAGS tags help %docs check% kernelrelease
+			 cscope TAGS tags help %docs check%
 
 config-targets := 0
 mixed-targets  := 0
@@ -481,18 +477,20 @@
 
 # Read in dependencies to all Kconfig* files, make sure to run
 # oldconfig if changes are detected.
--include .config.cmd
+-include .kconfig.d
 
 include .config
 
 # If .config needs to be updated, it will be done via the dependency
 # that autoconf has on .config.
 # To avoid any implicit rule to kick in, define an empty command
-.config: ;
+.config .kconfig.d: ;
 
 # If .config is newer than include/linux/autoconf.h, someone tinkered
-# with it and forgot to run make oldconfig
-include/linux/autoconf.h: .config
+# with it and forgot to run make oldconfig.
+# If kconfig.d is missing then we are probarly in a cleaned tree so
+# we execute the config step to be sure to catch updated Kconfig files
+include/linux/autoconf.h: .kconfig.d .config
 	$(Q)mkdir -p include/linux
 	$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
 else
@@ -1066,7 +1064,7 @@
 	@echo  '  all		  - Build all targets marked with [*]'
 	@echo  '* vmlinux	  - Build the bare kernel'
 	@echo  '* modules	  - Build all modules'
-	@echo  '  modules_install - Install all modules'
+	@echo  '  modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
 	@echo  '  dir/            - Build all files in dir and below'
 	@echo  '  dir/file.[ois]  - Build specified target only'
 	@echo  '  dir/file.ko     - Build module including final link'
@@ -1240,8 +1238,11 @@
 quiet_cmd_TAGS = MAKE   $@
 define cmd_TAGS
 	rm -f $@; \
-	ETAGSF=`etags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \
-	$(all-sources) | xargs etags $$ETAGSF -a
+	ETAGSF=`etags --version | grep -i exuberant >/dev/null &&     \
+                echo "-I __initdata,__exitdata,__acquires,__releases  \
+                      -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL              \
+                      --extra=+f --c-kinds=+px"`;                     \
+                $(all-sources) | xargs etags $$ETAGSF -a
 endef
 
 TAGS: FORCE
@@ -1251,8 +1252,11 @@
 quiet_cmd_tags = MAKE   $@
 define cmd_tags
 	rm -f $@; \
-	CTAGSF=`ctags --version | grep -i exuberant >/dev/null && echo "-I __initdata,__exitdata,EXPORT_SYMBOL,EXPORT_SYMBOL_GPL --extra=+f"`; \
-	$(all-sources) | xargs ctags $$CTAGSF -a
+	CTAGSF=`ctags --version | grep -i exuberant >/dev/null &&     \
+                echo "-I __initdata,__exitdata,__acquires,__releases  \
+                      -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL              \
+                      --extra=+f --c-kinds=+px"`;                     \
+                $(all-sources) | xargs ctags $$CTAGSF -a
 endef
 
 tags: FORCE
diff --git a/README b/README
index 61c4f74..cd5e2eb 100644
--- a/README
+++ b/README
@@ -183,11 +183,8 @@
 
 COMPILING the kernel:
 
- - Make sure you have gcc 2.95.3 available.
-   gcc 2.91.66 (egcs-1.1.2), and gcc 2.7.2.3 are known to miscompile
-   some parts of the kernel, and are *no longer supported*.
-   Also remember to upgrade your binutils package (for as/ld/nm and company)
-   if necessary. For more information, refer to Documentation/Changes.
+ - Make sure you have at least gcc 3.2 available.
+   For more information, refer to Documentation/Changes.
 
    Please note that you can still run a.out user programs with this kernel.
 
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 786491f..eedf41b 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -18,9 +18,6 @@
 	bool
 	default y
 
-config UID16
-	bool
-
 config RWSEM_GENERIC_SPINLOCK
 	bool
 
@@ -40,6 +37,19 @@
 	bool
 	default n
 
+config GENERIC_HARDIRQS
+	bool
+	default y
+
+config GENERIC_IRQ_PROBE
+	bool
+	default y
+
+config AUTO_IRQ_AFFINITY
+	bool
+	depends on SMP
+	default y
+
 source "init/Kconfig"
 
 
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 24ae9a3..f3e98f8 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -175,7 +175,6 @@
  */
 
 #ifdef CONFIG_SMP
-EXPORT_SYMBOL(synchronize_irq);
 EXPORT_SYMBOL(flush_tlb_mm);
 EXPORT_SYMBOL(flush_tlb_range);
 EXPORT_SYMBOL(flush_tlb_page);
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index b6114f5..76be5cf 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -32,214 +32,25 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-/*
- * Controller mappings for all interrupt sources:
- */
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
-	[0 ... NR_IRQS-1] = {
-		.handler = &no_irq_type,
-		.lock = SPIN_LOCK_UNLOCKED
-	}
-};
-
-static void register_irq_proc(unsigned int irq);
-
 volatile unsigned long irq_err_count;
 
-/*
- * Special irq handlers.
- */
-
-irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs)
-{
-	return IRQ_NONE;
-}
-
-/*
- * Generic no controller code
- */
-
-static void no_irq_enable_disable(unsigned int irq) { }
-static unsigned int no_irq_startup(unsigned int irq) { return 0; }
-
-static void
-no_irq_ack(unsigned int irq)
+void ack_bad_irq(unsigned int irq)
 {
 	irq_err_count++;
 	printk(KERN_CRIT "Unexpected IRQ trap at vector %u\n", irq);
 }
 
-struct hw_interrupt_type no_irq_type = {
-	.typename	= "none",
-	.startup	= no_irq_startup,
-	.shutdown	= no_irq_enable_disable,
-	.enable		= no_irq_enable_disable,
-	.disable	= no_irq_enable_disable,
-	.ack		= no_irq_ack,
-	.end		= no_irq_enable_disable,
-};
-
-int
-handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
-		 struct irqaction *action)
-{
-	int status = 1;	/* Force the "do bottom halves" bit */
-	int ret;
-
-	do {
-		if (!(action->flags & SA_INTERRUPT))
-			local_irq_enable();
-		else
-			local_irq_disable();
-
-		ret = action->handler(irq, action->dev_id, regs);
-		if (ret == IRQ_HANDLED)
-			status |= action->flags;
-		action = action->next;
-	} while (action);
-	if (status & SA_SAMPLE_RANDOM)
-		add_interrupt_randomness(irq);
-	local_irq_disable();
-
-	return status;
-}
-
-/*
- * Generic enable/disable code: this just calls
- * down into the PIC-specific version for the actual
- * hardware disable after having gotten the irq
- * controller lock. 
- */
-void inline
-disable_irq_nosync(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	if (!desc->depth++) {
-		desc->status |= IRQ_DISABLED;
-		desc->handler->disable(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/*
- * Synchronous version of the above, making sure the IRQ is
- * no longer running on any other IRQ..
- */
-void
-disable_irq(unsigned int irq)
-{
-	disable_irq_nosync(irq);
-	synchronize_irq(irq);
-}
-
-void
-enable_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	switch (desc->depth) {
-	case 1: {
-		unsigned int status = desc->status & ~IRQ_DISABLED;
-		desc->status = status;
-		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-			desc->status = status | IRQ_REPLAY;
-			hw_resend_irq(desc->handler,irq);
-		}
-		desc->handler->enable(irq);
-		/* fall-through */
-	}
-	default:
-		desc->depth--;
-		break;
-	case 0:
-		printk(KERN_ERR "enable_irq() unbalanced from %p\n",
-		       __builtin_return_address(0));
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-int
-setup_irq(unsigned int irq, struct irqaction * new)
-{
-	int shared = 0;
-	struct irqaction *old, **p;
-	unsigned long flags;
-	irq_desc_t *desc = irq_desc + irq;
-
-        if (desc->handler == &no_irq_type)
-		return -ENOSYS;
-
-	/*
-	 * Some drivers like serial.c use request_irq() heavily,
-	 * so we have to be careful not to interfere with a
-	 * running system.
-	 */
-	if (new->flags & SA_SAMPLE_RANDOM) {
-		/*
-		 * This function might sleep, we want to call it first,
-		 * outside of the atomic block.
-		 * Yes, this might clear the entropy pool if the wrong
-		 * driver is attempted to be loaded, without actually
-		 * installing a new handler, but is this really a problem,
-		 * only the sysadmin is able to do this.
-		 */
-		rand_initialize_irq(irq);
-	}
-
-	/*
-	 * The following block of code has to be executed atomically
-	 */
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ)) {
-			spin_unlock_irqrestore(&desc->lock,flags);
-			return -EBUSY;
-		}
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	*p = new;
-
-	if (!shared) {
-		desc->depth = 0;
-		desc->status &=
-		    ~(IRQ_DISABLED|IRQ_AUTODETECT|IRQ_WAITING|IRQ_INPROGRESS);
-		desc->handler->startup(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock,flags);
-
-	return 0;
-}
-
-static struct proc_dir_entry * root_irq_dir;
-static struct proc_dir_entry * irq_dir[NR_IRQS];
-
 #ifdef CONFIG_SMP 
-static struct proc_dir_entry * smp_affinity_entry[NR_IRQS];
 static char irq_user_affinity[NR_IRQS];
-static cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
 
-static void
-select_smp_affinity(int irq)
+int
+select_smp_affinity(unsigned int irq)
 {
 	static int last_cpu;
 	int cpu = last_cpu + 1;
 
-	if (! irq_desc[irq].handler->set_affinity || irq_user_affinity[irq])
-		return;
+	if (!irq_desc[irq].handler->set_affinity || irq_user_affinity[irq])
+		return 1;
 
 	while (!cpu_possible(cpu))
 		cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
@@ -247,208 +58,10 @@
 
 	irq_affinity[irq] = cpumask_of_cpu(cpu);
 	irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu));
+	return 0;
 }
-
-static int
-irq_affinity_read_proc (char *page, char **start, off_t off,
-			int count, int *eof, void *data)
-{
-	int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]);
-	if (count - len < 2)
-		return -EINVAL;
-	len += sprintf(page + len, "\n");
-	return len;
-}
-
-static int
-irq_affinity_write_proc(struct file *file, const char __user *buffer,
-			unsigned long count, void *data)
-{
-	int irq = (long) data, full_count = count, err;
-	cpumask_t new_value;
-
-	if (!irq_desc[irq].handler->set_affinity)
-		return -EIO;
-
-	err = cpumask_parse(buffer, count, new_value);
-
-	/* The special value 0 means release control of the
-	   affinity to kernel.  */
-	cpus_and(new_value, new_value, cpu_online_map);
-	if (cpus_empty(new_value)) {
-		irq_user_affinity[irq] = 0;
-		select_smp_affinity(irq);
-	}
-	/* Do not allow disabling IRQs completely - it's a too easy
-	   way to make the system unusable accidentally :-) At least
-	   one online CPU still has to be targeted.  */
-	else {
-		irq_affinity[irq] = new_value;
-		irq_user_affinity[irq] = 1;
-		irq_desc[irq].handler->set_affinity(irq, new_value);
-	}
-
-	return full_count;
-}
-
 #endif /* CONFIG_SMP */
 
-#define MAX_NAMELEN 10
-
-static void
-register_irq_proc (unsigned int irq)
-{
-	char name [MAX_NAMELEN];
-
-	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
-	    irq_dir[irq])
-		return;
-
-	memset(name, 0, MAX_NAMELEN);
-	sprintf(name, "%d", irq);
-
-	/* create /proc/irq/1234 */
-	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
-
-#ifdef CONFIG_SMP 
-	if (irq_desc[irq].handler->set_affinity) {
-		struct proc_dir_entry *entry;
-		/* create /proc/irq/1234/smp_affinity */
-		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
-
-		if (entry) {
-			entry->nlink = 1;
-			entry->data = (void *)(long)irq;
-			entry->read_proc = irq_affinity_read_proc;
-			entry->write_proc = irq_affinity_write_proc;
-		}
-
-		smp_affinity_entry[irq] = entry;
-	}
-#endif
-}
-
-void
-init_irq_proc (void)
-{
-	int i;
-
-	/* create /proc/irq */
-	root_irq_dir = proc_mkdir("irq", NULL);
-
-#ifdef CONFIG_SMP 
-	/* create /proc/irq/prof_cpu_mask */
-	create_prof_cpu_mask(root_irq_dir);
-#endif
-
-	/*
-	 * Create entries for all existing IRQs.
-	 */
-	for (i = 0; i < ACTUAL_NR_IRQS; i++) {
-		if (irq_desc[i].handler == &no_irq_type)
-			continue;
-		register_irq_proc(i);
-	}
-}
-
-int
-request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *),
-	    unsigned long irqflags, const char * devname, void *dev_id)
-{
-	int retval;
-	struct irqaction * action;
-
-	if (irq >= ACTUAL_NR_IRQS)
-		return -EINVAL;
-	if (!handler)
-		return -EINVAL;
-
-#if 1
-	/*
-	 * Sanity-check: shared interrupts should REALLY pass in
-	 * a real dev-ID, otherwise we'll have trouble later trying
-	 * to figure out which interrupt is which (messes up the
-	 * interrupt freeing logic etc).
-	 */
-	if ((irqflags & SA_SHIRQ) && !dev_id) {
-		printk(KERN_ERR
-		       "Bad boy: %s (at %p) called us without a dev_id!\n",
-		       devname, __builtin_return_address(0));
-	}
-#endif
-
-	action = (struct irqaction *)
-			kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-	if (!action)
-		return -ENOMEM;
-
-	action->handler = handler;
-	action->flags = irqflags;
-	cpus_clear(action->mask);
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
-#ifdef CONFIG_SMP
-	select_smp_affinity(irq);
-#endif
-
-	retval = setup_irq(irq, action);
-	if (retval)
-		kfree(action);
-	return retval;
-}
-
-EXPORT_SYMBOL(request_irq);
-
-void
-free_irq(unsigned int irq, void *dev_id)
-{
-	irq_desc_t *desc;
-	struct irqaction **p;
-	unsigned long flags;
-
-	if (irq >= ACTUAL_NR_IRQS) {
-		printk(KERN_CRIT "Trying to free IRQ%d\n", irq);
-		return;
-	}
-
-	desc = irq_desc + irq;
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	for (;;) {
-		struct irqaction * action = *p;
-		if (action) {
-			struct irqaction **pp = p;
-			p = &action->next;
-			if (action->dev_id != dev_id)
-				continue;
-
-			/* Found - now remove it from the list of entries.  */
-			*pp = action->next;
-			if (!desc->action) {
-				desc->status |= IRQ_DISABLED;
-				desc->handler->shutdown(irq);
-			}
-			spin_unlock_irqrestore(&desc->lock,flags);
-
-#ifdef CONFIG_SMP
-			/* Wait to make sure it's not being used on
-			   another CPU.  */
-			while (desc->status & IRQ_INPROGRESS)
-				barrier();
-#endif
-			kfree(action);
-			return;
-		}
-		printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
-		spin_unlock_irqrestore(&desc->lock,flags);
-		return;
-	}
-}
-
-EXPORT_SYMBOL(free_irq);
-
 int
 show_interrupts(struct seq_file *p, void *v)
 {
@@ -531,10 +144,6 @@
 	 * 0 return value means that this irq is already being
 	 * handled by some other CPU. (or is disabled)
 	 */
-	int cpu = smp_processor_id();
-	irq_desc_t *desc = irq_desc + irq;
-	struct irqaction * action;
-	unsigned int status;
 	static unsigned int illegal_count=0;
 	
 	if ((unsigned) irq > ACTUAL_NR_IRQS && illegal_count < MAX_ILLEGAL_IRQS ) {
@@ -546,229 +155,8 @@
 	}
 
 	irq_enter();
-	kstat_cpu(cpu).irqs[irq]++;
-	spin_lock_irq(&desc->lock); /* mask also the higher prio events */
-	desc->handler->ack(irq);
-	/*
-	 * REPLAY is when Linux resends an IRQ that was dropped earlier.
-	 * WAITING is used by probe to mark irqs that are being tested.
-	 */
-	status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
-	status |= IRQ_PENDING; /* we _want_ to handle it */
-
-	/*
-	 * If the IRQ is disabled for whatever reason, we cannot
-	 * use the action we have.
-	 */
-	action = NULL;
-	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
-		action = desc->action;
-		status &= ~IRQ_PENDING; /* we commit to handling */
-		status |= IRQ_INPROGRESS; /* we are handling it */
-	}
-	desc->status = status;
-
-	/*
-	 * If there is no IRQ handler or it was disabled, exit early.
-	 * Since we set PENDING, if another processor is handling
-	 * a different instance of this same irq, the other processor
-	 * will take care of it.
-	 */
-	if (!action)
-		goto out;
-
-	/*
-	 * Edge triggered interrupts need to remember pending events.
-	 * This applies to any hw interrupts that allow a second
-	 * instance of the same irq to arrive while we are in handle_irq
-	 * or in the handler. But the code here only handles the _second_
-	 * instance of the irq, not the third or fourth. So it is mostly
-	 * useful for irq hardware that does not mask cleanly in an
-	 * SMP environment.
-	 */
-	for (;;) {
-		spin_unlock(&desc->lock);
-		handle_IRQ_event(irq, regs, action);
-		spin_lock(&desc->lock);
-		
-		if (!(desc->status & IRQ_PENDING)
-		    || (desc->status & IRQ_LEVEL))
-			break;
-		desc->status &= ~IRQ_PENDING;
-	}
-	desc->status &= ~IRQ_INPROGRESS;
-out:
-	/*
-	 * The ->end() handler has to deal with interrupts which got
-	 * disabled while the handler was running.
-	 */
-	desc->handler->end(irq);
-	spin_unlock(&desc->lock);
-
+	local_irq_disable();
+	__do_IRQ(irq, regs);
+	local_irq_enable();
 	irq_exit();
 }
-
-/*
- * IRQ autodetection code..
- *
- * This depends on the fact that any interrupt that
- * comes in on to an unassigned handler will get stuck
- * with "IRQ_WAITING" cleared and the interrupt
- * disabled.
- */
-unsigned long
-probe_irq_on(void)
-{
-	int i;
-	irq_desc_t *desc;
-	unsigned long delay;
-	unsigned long val;
-
-	/* Something may have generated an irq long ago and we want to
-	   flush such a longstanding irq before considering it as spurious. */
-	for (i = NR_IRQS-1; i >= 0; i--) {
-		desc = irq_desc + i;
-
-		spin_lock_irq(&desc->lock);
-		if (!irq_desc[i].action) 
-			irq_desc[i].handler->startup(i);
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/* Wait for longstanding interrupts to trigger. */
-	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-		/* about 20ms delay */ barrier();
-
-	/* enable any unassigned irqs (we must startup again here because
-	   if a longstanding irq happened in the previous stage, it may have
-	   masked itself) first, enable any unassigned irqs. */
-	for (i = NR_IRQS-1; i >= 0; i--) {
-		desc = irq_desc + i;
-
-		spin_lock_irq(&desc->lock);
-		if (!desc->action) {
-			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
-			if (desc->handler->startup(i))
-				desc->status |= IRQ_PENDING;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	/*
-	 * Wait for spurious interrupts to trigger
-	 */
-	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ barrier();
-
-	/*
-	 * Now filter out any obviously spurious interrupts
-	 */
-	val = 0;
-	for (i=0; i<NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			/* It triggered already - consider it spurious. */
-			if (!(status & IRQ_WAITING)) {
-				desc->status = status & ~IRQ_AUTODETECT;
-				desc->handler->shutdown(i);
-			} else
-				if (i < 32)
-					val |= 1 << i;
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	return val;
-}
-
-EXPORT_SYMBOL(probe_irq_on);
-
-/*
- * Return a mask of triggered interrupts (this
- * can handle only legacy ISA interrupts).
- */
-unsigned int
-probe_irq_mask(unsigned long val)
-{
-	int i;
-	unsigned int mask;
-
-	mask = 0;
-	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			/* We only react to ISA interrupts */
-			if (!(status & IRQ_WAITING)) {
-				if (i < 16)
-					mask |= 1 << i;
-			}
-
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	return mask & val;
-}
-
-/*
- * Get the result of the IRQ probe.. A negative result means that
- * we have several candidates (but we return the lowest-numbered
- * one).
- */
-
-int
-probe_irq_off(unsigned long val)
-{
-	int i, irq_found, nr_irqs;
-
-	nr_irqs = 0;
-	irq_found = 0;
-	for (i=0; i<NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc + i;
-		unsigned int status;
-
-		spin_lock_irq(&desc->lock);
-		status = desc->status;
-
-		if (status & IRQ_AUTODETECT) {
-			if (!(status & IRQ_WAITING)) {
-				if (!nr_irqs)
-					irq_found = i;
-				nr_irqs++;
-			}
-			desc->status = status & ~IRQ_AUTODETECT;
-			desc->handler->shutdown(i);
-		}
-		spin_unlock_irq(&desc->lock);
-	}
-
-	if (nr_irqs > 1)
-		irq_found = -irq_found;
-	return irq_found;
-}
-
-EXPORT_SYMBOL(probe_irq_off);
-
-#ifdef CONFIG_SMP
-void synchronize_irq(unsigned int irq)
-{
-        /* is there anything to synchronize with? */
-	if (!irq_desc[irq].action)
-		return;
-
-	while (irq_desc[irq].status & IRQ_INPROGRESS)
-		barrier();
-}
-#endif
diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
index 4959b7a..11f996f 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -41,7 +41,7 @@
 #define CAT1(x,y)  x##y
 #define CAT(x,y)   CAT1(x,y)
 
-#define DO_DEFAULT_RTC rtc_port: 0x70
+#define DO_DEFAULT_RTC .rtc_port = 0x70
 
 #define DO_EV4_MMU							\
 	.max_asn =			EV4_MAX_ASN,			\
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index a868261..abb739b 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -43,6 +43,11 @@
 #include "proto.h"
 #include "pci_impl.h"
 
+/*
+ * Power off function, if any
+ */
+void (*pm_power_off)(void) = machine_power_off;
+
 void
 cpu_idle(void)
 {
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index bbd3753..9969d21 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -265,30 +265,16 @@
 	lock_kernel();
 	DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
 		      request, pid, addr, data));
-	ret = -EPERM;
 	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out_notsk;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out_notsk;
-		/* set the ptrace bit in the process ptrace flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
+		ret = ptrace_traceme();
 		goto out_notsk;
 	}
-	if (pid == 1)		/* you may not mess with init */
-		goto out_notsk;
 
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
 		goto out_notsk;
+	}
 
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4b15f5f..7a74e3e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -46,10 +46,6 @@
 	  <file:Documentation/mca.txt> (and especially the web page given
 	  there) before attempting to build an MCA bus kernel.
 
-config UID16
-	bool
-	default y
-
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
@@ -154,6 +150,7 @@
 	select FIQ
 	select TIMER_ACORN
 	select ARCH_MAY_HAVE_PC_FDC
+	select ISA_DMA_API
 	help
 	  On the Acorn Risc-PC, Linux can support the internal IDE disk and
 	  CD-ROM interface, serial and parallel port, and the floppy drive.
@@ -206,6 +203,7 @@
 
 config ARCH_H720X
 	bool "Hynix-HMS720x-based"
+	select ISA_DMA_API
 	help
 	  This enables support for systems based on the Hynix HMS720x
 
@@ -290,12 +288,14 @@
 	  (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
 	  newer boards don't support it.  If you have ISA, say Y, otherwise N.
 
+# Select ISA DMA controller support
 config ISA_DMA
 	bool
+	select ISA_DMA_API
 
+# Select ISA DMA interface
 config ISA_DMA_API
 	bool
-	default y
 
 config PCI
 	bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB
@@ -656,7 +656,6 @@
 
 config APM
 	tristate "Advanced Power Management Emulation"
-	depends on PM_LEGACY
 	---help---
 	  APM is a BIOS specification for saving power using several different
 	  techniques. This is mostly useful for battery powered laptops with
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 81bd219..afaf3a1 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -8,7 +8,7 @@
 # Copyright (C) 1995-2001 by Russell King
 
 LDFLAGS_vmlinux	:=-p --no-undefined -X
-CPPFLAGS_vmlinux.lds = -DKERNEL_RAM_ADDR=$(TEXTADDR)
+CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
 OBJCOPYFLAGS	:=-O binary -R .note -R .comment -S
 GZFLAGS		:=-9
 #CFLAGS		+=-pipe
@@ -65,7 +65,7 @@
 
 #Default value
 head-y		:= arch/arm/kernel/head.o arch/arm/kernel/init_task.o
-textaddr-y	:= 0xC0008000
+textofs-y	:= 0x00008000
 
  machine-$(CONFIG_ARCH_RPC)	   := rpc
  machine-$(CONFIG_ARCH_EBSA110)	   := ebsa110
@@ -73,22 +73,20 @@
   incdir-$(CONFIG_ARCH_CLPS7500)   := cl7500
  machine-$(CONFIG_FOOTBRIDGE)	   := footbridge
   incdir-$(CONFIG_FOOTBRIDGE)	   := ebsa285
-textaddr-$(CONFIG_ARCH_CO285)	   := 0x60008000
  machine-$(CONFIG_ARCH_CO285)	   := footbridge
   incdir-$(CONFIG_ARCH_CO285)	   := ebsa285
  machine-$(CONFIG_ARCH_SHARK)	   := shark
  machine-$(CONFIG_ARCH_SA1100)	   := sa1100
 ifeq ($(CONFIG_ARCH_SA1100),y)
 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
-textaddr-$(CONFIG_SA1111)	   := 0xc0208000
+ textofs-$(CONFIG_SA1111)	   := 0x00208000
 endif
  machine-$(CONFIG_ARCH_PXA)	   := pxa
  machine-$(CONFIG_ARCH_L7200)	   := l7200
  machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
  machine-$(CONFIG_ARCH_CAMELOT)	   := epxa10db
-textaddr-$(CONFIG_ARCH_CLPS711X)   := 0xc0028000
+ textofs-$(CONFIG_ARCH_CLPS711X)   := 0x00028000
  machine-$(CONFIG_ARCH_CLPS711X)   := clps711x
-textaddr-$(CONFIG_ARCH_FORTUNET)   := 0xc0008000
  machine-$(CONFIG_ARCH_IOP3XX)	   := iop3xx
  machine-$(CONFIG_ARCH_IXP4XX)	   := ixp4xx
  machine-$(CONFIG_ARCH_IXP2000)    := ixp2000
@@ -110,7 +108,8 @@
 export CFLAGS_3c589_cs.o
 endif
 
-TEXTADDR := $(textaddr-y)
+# The byte offset of the kernel image in RAM from the start of RAM.
+TEXT_OFFSET := $(textofs-y)
 
 ifeq ($(incdir-y),)
 incdir-y := $(machine-y)
@@ -123,7 +122,7 @@
 MACHINE  :=
 endif
   
-export	TEXTADDR GZFLAGS
+export	TEXT_OFFSET GZFLAGS
 
 # Do we have FASTFPE?
 FASTFPE		:=arch/arm/fastfpe
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 937a353..a174d63 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -15,7 +15,7 @@
 endif
 
 # Note: the following conditions must always be true:
-#   ZRELADDR == virt_to_phys(TEXTADDR)
+#   ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
 #   PARAMS_PHYS must be within 4MB of ZRELADDR
 #   INITRD_PHYS must be in RAM
 ZRELADDR    := $(zreladdr-y)
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 666ba39..d7509c7 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -23,5 +23,8 @@
 config SHARP_PARAM
 	bool
 
+config SHARPSL_PM
+	bool
+
 config SHARP_SCOOP
 	bool
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index a878865..ec8d17c 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -3,7 +3,6 @@
 #
 
 obj-y				+= rtctime.o
-obj-$(CONFIG_ARM_AMBA)		+= amba.o
 obj-$(CONFIG_ARM_GIC)		+= gic.o
 obj-$(CONFIG_ICST525)		+= icst525.o
 obj-$(CONFIG_ICST307)		+= icst307.o
@@ -13,4 +12,5 @@
 obj-$(CONFIG_TIMER_ACORN)	+= time-acorn.o
 obj-$(CONFIG_SHARP_LOCOMO)	+= locomo.o
 obj-$(CONFIG_SHARP_PARAM)	+= sharpsl_param.o
+obj-$(CONFIG_SHARPSL_PM)	+= sharpsl_pm.o
 obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 0c3cbd9..a2dfe0b 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -13,6 +13,7 @@
 
 #include <linux/device.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <asm/io.h>
 #include <asm/hardware/scoop.h>
@@ -33,7 +34,6 @@
 
 	SCOOP_REG(sdev->base,SCOOP_MCR) = 0x0100;  // 00
 	SCOOP_REG(sdev->base,SCOOP_CDR) = 0x0000;  // 04
-	SCOOP_REG(sdev->base,SCOOP_CPR) = 0x0000;  // 0C
 	SCOOP_REG(sdev->base,SCOOP_CCR) = 0x0000;  // 10
 	SCOOP_REG(sdev->base,SCOOP_IMR) = 0x0000;  // 18
 	SCOOP_REG(sdev->base,SCOOP_IRM) = 0x00FF;  // 14
@@ -154,6 +154,7 @@
 
 	SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140;
 	reset_scoop(&pdev->dev);
+	SCOOP_REG(devptr->base, SCOOP_CPR) = 0x0000;
 	SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff;
 	SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff;
 
diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c
new file mode 100644
index 0000000..978d32e
--- /dev/null
+++ b/arch/arm/common/sharpsl_pm.c
@@ -0,0 +1,839 @@
+/*
+ * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00
+ * series of PDAs
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * Based on code written by Sharp for 2.4 kernels
+ *
+ * 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.
+ *
+ */
+
+#undef DEBUG
+
+#include <linux/module.h>
+#include <linux/timer.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/apm_bios.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/apm.h>
+#include <asm/arch/pm.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/sharpsl.h>
+#include <asm/hardware/sharpsl_pm.h>
+
+/*
+ * Constants
+ */
+#define SHARPSL_CHARGE_ON_TIME_INTERVAL        (msecs_to_jiffies(1*60*1000))  /* 1 min */
+#define SHARPSL_CHARGE_FINISH_TIME             (msecs_to_jiffies(10*60*1000)) /* 10 min */
+#define SHARPSL_BATCHK_TIME                    (msecs_to_jiffies(15*1000))    /* 15 sec */
+#define SHARPSL_BATCHK_TIME_SUSPEND            (60*10)                        /* 10 min */
+#define SHARPSL_WAIT_CO_TIME                   15  /* 15 sec */
+#define SHARPSL_WAIT_DISCHARGE_ON              100 /* 100 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP   10  /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT   10  /* 10 msec */
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN   10  /* 10 msec */
+#define SHARPSL_CHARGE_WAIT_TIME               15  /* 15 msec */
+#define SHARPSL_CHARGE_CO_CHECK_TIME           5   /* 5 msec */
+#define SHARPSL_CHARGE_RETRY_CNT               1   /* eqv. 10 min */
+
+#define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
+#define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
+#define SHARPSL_CHARGE_ON_ACIN_HIGH    0x9b  /* 6V */
+#define SHARPSL_CHARGE_ON_ACIN_LOW     0x34  /* 2V */
+#define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
+#define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
+
+/*
+ * Prototypes
+ */
+static int sharpsl_off_charge_battery(void);
+static int sharpsl_check_battery_temp(void);
+static int sharpsl_check_battery_voltage(void);
+static int sharpsl_ac_check(void);
+static int sharpsl_fatal_check(void);
+static int sharpsl_average_value(int ad);
+static void sharpsl_average_clear(void);
+static void sharpsl_charge_toggle(void *private_);
+static void sharpsl_battery_thread(void *private_);
+
+
+/*
+ * Variables
+ */
+struct sharpsl_pm_status sharpsl_pm;
+DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
+DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
+
+
+static int get_percentage(int voltage)
+{
+	int i = sharpsl_pm.machinfo->bat_levels - 1;
+	struct battery_thresh *thresh;
+
+	if (sharpsl_pm.charge_mode == CHRG_ON)
+		thresh=sharpsl_pm.machinfo->bat_levels_acin;
+	else
+		thresh=sharpsl_pm.machinfo->bat_levels_noac;
+
+	while (i > 0 && (voltage > thresh[i].voltage))
+		i--;
+
+	return thresh[i].percentage;
+}
+
+static int get_apm_status(int voltage)
+{
+	int low_thresh, high_thresh;
+
+	if (sharpsl_pm.charge_mode == CHRG_ON) {
+		high_thresh = sharpsl_pm.machinfo->status_high_acin;
+		low_thresh = sharpsl_pm.machinfo->status_low_acin;
+	} else {
+		high_thresh = sharpsl_pm.machinfo->status_high_noac;
+		low_thresh = sharpsl_pm.machinfo->status_low_noac;
+	}
+
+	if (voltage >= high_thresh)
+		return APM_BATTERY_STATUS_HIGH;
+	if (voltage >= low_thresh)
+		return APM_BATTERY_STATUS_LOW;
+	return APM_BATTERY_STATUS_CRITICAL;
+}
+
+void sharpsl_battery_kick(void)
+{
+	schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
+}
+EXPORT_SYMBOL(sharpsl_battery_kick);
+
+
+static void sharpsl_battery_thread(void *private_)
+{
+	int voltage, percent, apm_status, i = 0;
+
+	if (!sharpsl_pm.machinfo)
+		return;
+
+	sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE);
+
+	/* Corgi cannot confirm when battery fully charged so periodically kick! */
+	if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
+			&& time_after(jiffies, sharpsl_pm.charge_start_time +  SHARPSL_CHARGE_ON_TIME_INTERVAL))
+		schedule_work(&toggle_charger);
+
+	while(1) {
+		voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
+
+		if (voltage > 0) break;
+		if (i++ > 5) {
+			voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
+			dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
+			break;
+		}
+	}
+
+	voltage = sharpsl_average_value(voltage);
+	apm_status = get_apm_status(voltage);
+	percent = get_percentage(voltage);
+
+	/* At low battery voltages, the voltage has a tendency to start
+           creeping back up so we try to avoid this here */
+	if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) ||  percent <= sharpsl_pm.battstat.mainbat_percent) {
+		sharpsl_pm.battstat.mainbat_voltage = voltage;
+		sharpsl_pm.battstat.mainbat_status = apm_status;
+		sharpsl_pm.battstat.mainbat_percent = percent;
+	}
+
+	dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage,
+			sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
+
+	/* If battery is low. limit backlight intensity to save power. */
+	if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
+			&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
+			(sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
+		if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
+			corgibl_limit_intensity(1);
+			sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
+		}
+	} else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
+		corgibl_limit_intensity(0);
+		sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
+	}
+
+	/* Suspend if critical battery level */
+	if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
+			&& (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
+			&& !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
+		sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
+		dev_err(sharpsl_pm.dev, "Fatal Off\n");
+		apm_queue_event(APM_CRITICAL_SUSPEND);
+	}
+
+	schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
+}
+
+void sharpsl_pm_led(int val)
+{
+	if (val == SHARPSL_LED_ERROR) {
+		dev_err(sharpsl_pm.dev, "Charging Error!\n");
+	} else if (val == SHARPSL_LED_ON) {
+		dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
+
+	} else {
+		dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
+
+	}
+}
+
+static void sharpsl_charge_on(void)
+{
+	dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
+
+	sharpsl_pm.full_count = 0;
+	sharpsl_pm.charge_mode = CHRG_ON;
+	schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250));
+	schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500));
+}
+
+static void sharpsl_charge_off(void)
+{
+	dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
+
+	sharpsl_pm.machinfo->charge(0);
+	sharpsl_pm_led(SHARPSL_LED_OFF);
+	sharpsl_pm.charge_mode = CHRG_OFF;
+
+	schedule_work(&sharpsl_bat);
+}
+
+static void sharpsl_charge_error(void)
+{
+	sharpsl_pm_led(SHARPSL_LED_ERROR);
+	sharpsl_pm.machinfo->charge(0);
+	sharpsl_pm.charge_mode = CHRG_ERROR;
+}
+
+static void sharpsl_charge_toggle(void *private_)
+{
+	dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
+
+	if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
+		sharpsl_charge_off();
+		return;
+	} else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
+		sharpsl_charge_error();
+		return;
+	}
+
+	sharpsl_pm_led(SHARPSL_LED_ON);
+	sharpsl_pm.machinfo->charge(0);
+	mdelay(SHARPSL_CHARGE_WAIT_TIME);
+	sharpsl_pm.machinfo->charge(1);
+
+	sharpsl_pm.charge_start_time = jiffies;
+}
+
+static void sharpsl_ac_timer(unsigned long data)
+{
+	int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
+
+	dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
+
+	sharpsl_average_clear();
+	if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
+		sharpsl_charge_on();
+	else if (sharpsl_pm.charge_mode == CHRG_ON)
+		sharpsl_charge_off();
+
+	schedule_work(&sharpsl_bat);
+}
+
+
+irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp)
+{
+	/* Delay the event slightly to debounce */
+	/* Must be a smaller delay than the chrg_full_isr below */
+	mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
+
+	return IRQ_HANDLED;
+}
+
+static void sharpsl_chrg_full_timer(unsigned long data)
+{
+	dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies);
+
+	sharpsl_pm.full_count++;
+
+	if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
+		dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
+		if (sharpsl_pm.charge_mode == CHRG_ON)
+			sharpsl_charge_off();
+	} else if (sharpsl_pm.full_count < 2) {
+		dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
+		schedule_work(&toggle_charger);
+	} else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
+		dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
+		schedule_work(&toggle_charger);
+	} else {
+		sharpsl_charge_off();
+		sharpsl_pm.charge_mode = CHRG_DONE;
+		dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n");
+	}
+}
+
+/* Charging Finished Interrupt (Not present on Corgi) */
+/* Can trigger at the same time as an AC staus change so
+   delay until after that has been processed */
+irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp)
+{
+	if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
+		return IRQ_HANDLED;
+
+	/* delay until after any ac interrupt */
+	mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500));
+
+	return IRQ_HANDLED;
+}
+
+irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
+{
+	int is_fatal = 0;
+
+	if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) {
+		dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
+		is_fatal = 1;
+	}
+
+	if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL)) {
+		dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
+		is_fatal = 1;
+	}
+
+	if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) {
+		sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
+		apm_queue_event(APM_CRITICAL_SUSPEND);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Maintain an average of the last 10 readings
+ */
+#define SHARPSL_CNV_VALUE_NUM    10
+static int sharpsl_ad_index;
+
+static void sharpsl_average_clear(void)
+{
+	sharpsl_ad_index = 0;
+}
+
+static int sharpsl_average_value(int ad)
+{
+	int i, ad_val = 0;
+	static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
+
+	if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) {
+		sharpsl_ad_index = 0;
+		return ad;
+	}
+
+	sharpsl_ad[sharpsl_ad_index] = ad;
+	sharpsl_ad_index++;
+	if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
+		for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
+			sharpsl_ad[i] = sharpsl_ad[i+1];
+		sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
+	}
+	for (i=0; i < sharpsl_ad_index; i++)
+		ad_val += sharpsl_ad[i];
+
+	return (ad_val / sharpsl_ad_index);
+}
+
+/*
+ * Take an array of 5 integers, remove the maximum and minimum values
+ * and return the average.
+ */
+static int get_select_val(int *val)
+{
+	int i, j, k, temp, sum = 0;
+
+	/* Find MAX val */
+	temp = val[0];
+	j=0;
+	for (i=1; i<5; i++) {
+		if (temp < val[i]) {
+			temp = val[i];
+			j = i;
+		}
+	}
+
+	/* Find MIN val */
+	temp = val[4];
+	k=4;
+	for (i=3; i>=0; i--) {
+		if (temp > val[i]) {
+			temp = val[i];
+			k = i;
+		}
+	}
+
+	for (i=0; i<5; i++)
+		if (i != j && i != k )
+			sum += val[i];
+
+	dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
+
+	return (sum/3);
+}
+
+static int sharpsl_check_battery_temp(void)
+{
+	int val, i, buff[5];
+
+	/* Check battery temperature */
+	for (i=0; i<5; i++) {
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
+		sharpsl_pm.machinfo->measure_temp(1);
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
+		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_TEMP);
+		sharpsl_pm.machinfo->measure_temp(0);
+	}
+
+	val = get_select_val(buff);
+
+	dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
+	if (val > SHARPSL_CHARGE_ON_TEMP)
+		return -1;
+
+	return 0;
+}
+
+static int sharpsl_check_battery_voltage(void)
+{
+	int val, i, buff[5];
+
+	/* disable charge, enable discharge */
+	sharpsl_pm.machinfo->charge(0);
+	sharpsl_pm.machinfo->discharge(1);
+	mdelay(SHARPSL_WAIT_DISCHARGE_ON);
+
+	if (sharpsl_pm.machinfo->discharge1)
+		sharpsl_pm.machinfo->discharge1(1);
+
+	/* Check battery voltage */
+	for (i=0; i<5; i++) {
+		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+	}
+
+	if (sharpsl_pm.machinfo->discharge1)
+		sharpsl_pm.machinfo->discharge1(0);
+
+	sharpsl_pm.machinfo->discharge(0);
+
+	val = get_select_val(buff);
+	dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
+
+	if (val < SHARPSL_CHARGE_ON_VOLT)
+		return -1;
+
+	return 0;
+}
+
+static int sharpsl_ac_check(void)
+{
+	int temp, i, buff[5];
+
+	for (i=0; i<5; i++) {
+		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT);
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
+	}
+
+	temp = get_select_val(buff);
+	dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
+
+	if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) {
+		dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	sharpsl_pm.flags |= SHARPSL_SUSPENDED;
+	flush_scheduled_work();
+
+	if (sharpsl_pm.charge_mode == CHRG_ON)
+		sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+	else
+		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
+
+	return 0;
+}
+
+static int sharpsl_pm_resume(struct platform_device *pdev)
+{
+	/* Clear the reset source indicators as they break the bootloader upon reboot */
+	RCSR = 0x0f;
+	sharpsl_average_clear();
+	sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;
+	sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;
+
+	return 0;
+}
+
+static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
+{
+	dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
+
+	dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
+	/* not charging and AC-IN! */
+
+	if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) {
+		dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
+		sharpsl_pm.charge_mode = CHRG_OFF;
+		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
+		sharpsl_off_charge_battery();
+	}
+
+	sharpsl_pm.machinfo->presuspend();
+
+	PEDR = 0xffffffff; /* clear it */
+
+	sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;
+	if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
+		RTSR &= RTSR_ALE;
+		RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
+		dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
+		sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
+	} else if (alarm_enable) {
+		RTSR &= RTSR_ALE;
+		RTAR = alarm_time;
+		dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
+	} else {
+		dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
+	}
+
+	pxa_pm_enter(state);
+
+	sharpsl_pm.machinfo->postsuspend();
+
+	dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
+}
+
+static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
+{
+	if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
+	{
+		if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
+			dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
+			corgi_goto_sleep(alarm_time, alarm_enable, state);
+			return 1;
+		}
+		if(sharpsl_off_charge_battery()) {
+			dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
+			corgi_goto_sleep(alarm_time, alarm_enable, state);
+			return 1;
+		}
+		dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
+	}
+
+	if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || (sharpsl_fatal_check() < 0) )
+	{
+		dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
+		corgi_goto_sleep(alarm_time, alarm_enable, state);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int corgi_pxa_pm_enter(suspend_state_t state)
+{
+	unsigned long alarm_time = RTAR;
+	unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);
+
+	dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");
+
+	corgi_goto_sleep(alarm_time, alarm_status, state);
+
+	while (corgi_enter_suspend(alarm_time,alarm_status,state))
+		{}
+
+	dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
+
+	return 0;
+}
+#endif
+
+
+/*
+ * Check for fatal battery errors
+ * Fatal returns -1
+ */
+static int sharpsl_fatal_check(void)
+{
+	int buff[5], temp, i, acin;
+
+	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
+
+	/* Check AC-Adapter */
+	acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
+
+	if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
+		sharpsl_pm.machinfo->charge(0);
+		udelay(100);
+		sharpsl_pm.machinfo->discharge(1);	/* enable discharge */
+		mdelay(SHARPSL_WAIT_DISCHARGE_ON);
+	}
+
+	if (sharpsl_pm.machinfo->discharge1)
+		sharpsl_pm.machinfo->discharge1(1);
+
+	/* Check battery : check inserting battery ? */
+	for (i=0; i<5; i++) {
+		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT);
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+	}
+
+	if (sharpsl_pm.machinfo->discharge1)
+		sharpsl_pm.machinfo->discharge1(0);
+
+	if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
+		udelay(100);
+		sharpsl_pm.machinfo->charge(1);
+		sharpsl_pm.machinfo->discharge(0);
+	}
+
+	temp = get_select_val(buff);
+	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT));
+
+	if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
+			(!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
+		return -1;
+	return 0;
+}
+
+static int sharpsl_off_charge_error(void)
+{
+	dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n");
+	sharpsl_pm.machinfo->charge(0);
+	sharpsl_pm_led(SHARPSL_LED_ERROR);
+	sharpsl_pm.charge_mode = CHRG_ERROR;
+	return 1;
+}
+
+/*
+ * Charging Control while suspended
+ * Return 1 - go straight to sleep
+ * Return 0 - sleep or wakeup depending on other factors
+ */
+static int sharpsl_off_charge_battery(void)
+{
+	int time;
+
+	dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);
+
+	if (sharpsl_pm.charge_mode == CHRG_OFF) {
+		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
+
+		/* AC Check */
+		if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
+			return sharpsl_off_charge_error();
+
+		/* Start Charging */
+		sharpsl_pm_led(SHARPSL_LED_ON);
+		sharpsl_pm.machinfo->charge(0);
+		mdelay(SHARPSL_CHARGE_WAIT_TIME);
+		sharpsl_pm.machinfo->charge(1);
+
+		sharpsl_pm.charge_mode = CHRG_ON;
+		sharpsl_pm.full_count = 0;
+
+		return 1;
+	} else if (sharpsl_pm.charge_mode != CHRG_ON) {
+		return 1;
+	}
+
+	if (sharpsl_pm.full_count == 0) {
+		int time;
+
+		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
+
+		if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
+			return sharpsl_off_charge_error();
+
+		sharpsl_pm.machinfo->charge(0);
+		mdelay(SHARPSL_CHARGE_WAIT_TIME);
+		sharpsl_pm.machinfo->charge(1);
+		sharpsl_pm.charge_mode = CHRG_ON;
+
+		mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+		time = RCNR;
+		while(1) {
+			/* Check if any wakeup event had occured */
+			if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+				return 0;
+			/* Check for timeout */
+			if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
+				return 1;
+			if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
+				dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
+	   			sharpsl_pm.full_count++;
+				sharpsl_pm.machinfo->charge(0);
+				mdelay(SHARPSL_CHARGE_WAIT_TIME);
+				sharpsl_pm.machinfo->charge(1);
+				return 1;
+			}
+		}
+	}
+
+	dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");
+
+	mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+	time = RCNR;
+	while(1) {
+		/* Check if any wakeup event had occured */
+		if (sharpsl_pm.machinfo->charger_wakeup() != 0)
+			return 0;
+		/* Check for timeout */
+		if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
+			if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {
+				dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");
+				sharpsl_pm.full_count = 0;
+			}
+			sharpsl_pm.full_count++;
+			return 1;
+		}
+		if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) {
+			dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
+			sharpsl_pm_led(SHARPSL_LED_OFF);
+			sharpsl_pm.machinfo->charge(0);
+			sharpsl_pm.charge_mode = CHRG_DONE;
+			return 1;
+		}
+	}
+}
+
+
+static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
+}
+
+static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
+}
+
+static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
+static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
+
+extern void (*apm_get_power_status)(struct apm_power_info *);
+
+static void sharpsl_apm_get_power_status(struct apm_power_info *info)
+{
+	info->ac_line_status = sharpsl_pm.battstat.ac_status;
+
+	if (sharpsl_pm.charge_mode == CHRG_ON)
+		info->battery_status = APM_BATTERY_STATUS_CHARGING;
+	else
+		info->battery_status = sharpsl_pm.battstat.mainbat_status;
+
+	info->battery_flag = (1 << info->battery_status);
+	info->battery_life = sharpsl_pm.battstat.mainbat_percent;
+}
+
+static struct pm_ops sharpsl_pm_ops = {
+	.pm_disk_mode	= PM_DISK_FIRMWARE,
+	.prepare	= pxa_pm_prepare,
+	.enter		= corgi_pxa_pm_enter,
+	.finish		= pxa_pm_finish,
+};
+
+static int __init sharpsl_pm_probe(struct platform_device *pdev)
+{
+	if (!pdev->dev.platform_data)
+		return -EINVAL;
+
+	sharpsl_pm.dev = &pdev->dev;
+	sharpsl_pm.machinfo = pdev->dev.platform_data;
+	sharpsl_pm.charge_mode = CHRG_OFF;
+	sharpsl_pm.flags = 0;
+
+	init_timer(&sharpsl_pm.ac_timer);
+	sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
+
+	init_timer(&sharpsl_pm.chrg_full_timer);
+	sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
+
+	sharpsl_pm.machinfo->init();
+
+	device_create_file(&pdev->dev, &dev_attr_battery_percentage);
+	device_create_file(&pdev->dev, &dev_attr_battery_voltage);
+
+	apm_get_power_status = sharpsl_apm_get_power_status;
+
+	pm_set_ops(&sharpsl_pm_ops);
+
+	mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
+
+	return 0;
+}
+
+static int sharpsl_pm_remove(struct platform_device *pdev)
+{
+	pm_set_ops(NULL);
+
+	device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
+	device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
+
+	sharpsl_pm.machinfo->exit();
+
+	del_timer_sync(&sharpsl_pm.chrg_full_timer);
+	del_timer_sync(&sharpsl_pm.ac_timer);
+
+	return 0;
+}
+
+static struct platform_driver sharpsl_pm_driver = {
+	.probe		= sharpsl_pm_probe,
+	.remove		= sharpsl_pm_remove,
+	.suspend	= sharpsl_pm_suspend,
+	.resume		= sharpsl_pm_resume,
+	.driver		= {
+		.name		= "sharpsl-pm",
+	},
+};
+
+static int __devinit sharpsl_pm_init(void)
+{
+	return platform_driver_register(&sharpsl_pm_driver);
+}
+
+static void sharpsl_pm_exit(void)
+{
+ 	platform_driver_unregister(&sharpsl_pm_driver);
+}
+
+late_initcall(sharpsl_pm_init);
+module_exit(sharpsl_pm_exit);
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index 24987c8..0622902 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc3
-# Sun Oct  9 15:46:42 2005
+# Linux kernel version: 2.6.15-rc2
+# Mon Nov 28 10:30:09 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -64,6 +64,23 @@
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System Type
 #
 # CONFIG_ARCH_CLPS7500 is not set
@@ -85,6 +102,7 @@
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_AAEC2000 is not set
@@ -98,12 +116,14 @@
 CONFIG_PXA_SHARPSL=y
 CONFIG_PXA_SHARPSL_25x=y
 # CONFIG_PXA_SHARPSL_27x is not set
-# CONFIG_MACH_POODLE is not set
+CONFIG_MACH_POODLE=y
 CONFIG_MACH_CORGI=y
 CONFIG_MACH_SHEPHERD=y
 CONFIG_MACH_HUSKY=y
+CONFIG_MACH_TOSA=y
 CONFIG_PXA25x=y
 CONFIG_PXA_SHARP_C7xx=y
+CONFIG_PXA_SSP=y
 
 #
 # Processor Type
@@ -155,6 +175,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -235,6 +256,10 @@
 CONFIG_IPV6_TUNNEL=m
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
 # CONFIG_NETFILTER_NETLINK is not set
 
 #
@@ -356,6 +381,10 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
 CONFIG_NET_CLS_ROUTE=y
 
@@ -413,6 +442,7 @@
 # CONFIG_SMC_IRCC_FIR is not set
 # CONFIG_ALI_FIR is not set
 # CONFIG_VIA_FIR is not set
+CONFIG_PXA_FICP=m
 CONFIG_BT=m
 CONFIG_BT_L2CAP=m
 CONFIG_BT_SCO=m
@@ -431,7 +461,6 @@
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_BCSP_TXCRC=y
 CONFIG_BT_HCIBCM203X=m
 CONFIG_BT_HCIBPA10X=m
 CONFIG_BT_HCIBFUSB=m
@@ -459,6 +488,11 @@
 # CONFIG_DEBUG_DRIVER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
@@ -477,6 +511,7 @@
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -532,6 +567,11 @@
 # CONFIG_MTD_NAND_NANDSIM is not set
 
 #
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
@@ -551,14 +591,6 @@
 # CONFIG_BLK_DEV_RAM is not set
 CONFIG_BLK_DEV_RAM_COUNT=16
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -625,6 +657,7 @@
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 
@@ -748,6 +781,7 @@
 # CONFIG_PPP_SYNC_TTY is not set
 # CONFIG_PPP_DEFLATE is not set
 CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
@@ -850,11 +884,15 @@
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -889,6 +927,7 @@
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -957,7 +996,10 @@
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_VIDEO_SAA5249 is not set
 # CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_EM28XX is not set
 # CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_VIDEO_AUDIO_DECODER is not set
+# CONFIG_VIDEO_DECODER is not set
 
 #
 # Radio Adapters
@@ -976,13 +1018,12 @@
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
+# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_PXA is not set
 CONFIG_FB_W100=y
-# CONFIG_FB_S1D13XXX is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -991,6 +1032,7 @@
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
@@ -1087,15 +1129,15 @@
 # USB Device Class drivers
 #
 # CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
-
-#
-# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
-#
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1107,7 +1149,6 @@
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
 
 #
 # USB Input Devices
@@ -1185,6 +1226,7 @@
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 # CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
 CONFIG_USB_SERIAL_BELKIN=m
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
@@ -1340,6 +1382,7 @@
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
 CONFIG_JFFS2_COMPRESSION_OPTIONS=y
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -1466,7 +1509,9 @@
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_WAITQ is not set
 CONFIG_DEBUG_ERRORS=y
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index f74c926..613afab 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc1-git5
-# Tue Sep 20 17:26:28 2005
+# Linux kernel version: 2.6.15
+# Tue Jan  3 03:20:40 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -33,6 +33,7 @@
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
@@ -42,7 +43,6 @@
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SHMEM=y
 CONFIG_CC_ALIGN_FUNCTIONS=0
 CONFIG_CC_ALIGN_LABELS=0
@@ -62,6 +62,23 @@
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System Type
 #
 # CONFIG_ARCH_CLPS7500 is not set
@@ -83,6 +100,7 @@
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_AAEC2000 is not set
@@ -102,6 +120,7 @@
 CONFIG_MACH_IXDP465=y
 CONFIG_ARCH_IXCDP1100=y
 CONFIG_ARCH_PRPMC1100=y
+CONFIG_MACH_NAS100D=y
 CONFIG_ARCH_IXDP4XX=y
 CONFIG_CPU_IXP46X=y
 # CONFIG_MACH_GTWX5715 is not set
@@ -155,6 +174,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -173,6 +193,7 @@
 # At least one emulation must be selected
 #
 CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
 # CONFIG_FPE_FASTFPE is not set
 
 #
@@ -187,6 +208,8 @@
 # Power management options
 #
 CONFIG_PM=y
+CONFIG_PM_LEGACY=y
+# CONFIG_PM_DEBUG is not set
 CONFIG_APM=y
 
 #
@@ -271,6 +294,10 @@
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 CONFIG_BRIDGE_NETFILTER=y
+
+#
+# Core Netfilter Configuration
+#
 # CONFIG_NETFILTER_NETLINK is not set
 
 #
@@ -286,6 +313,7 @@
 # CONFIG_IP_NF_NETBIOS_NS is not set
 # CONFIG_IP_NF_TFTP is not set
 # CONFIG_IP_NF_AMANDA is not set
+# CONFIG_IP_NF_PPTP is not set
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_LIMIT=m
@@ -319,6 +347,7 @@
 CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_IP_NF_TARGET_TCPMSS=m
+# CONFIG_IP_NF_TARGET_NFQUEUE is not set
 CONFIG_IP_NF_NAT=m
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -380,10 +409,18 @@
 CONFIG_ECONET_AUNUDP=y
 CONFIG_ECONET_NATIVE=y
 CONFIG_WAN_ROUTER=m
+
+#
+# QoS and/or fair queueing
+#
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 # CONFIG_NET_SCH_HFSC is not set
@@ -397,8 +434,10 @@
 CONFIG_NET_SCH_DSMARK=m
 # CONFIG_NET_SCH_NETEM is not set
 CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
+
+#
+# Classification
+#
 CONFIG_NET_CLS=y
 # CONFIG_NET_CLS_BASIC is not set
 CONFIG_NET_CLS_TCINDEX=m
@@ -407,13 +446,14 @@
 CONFIG_NET_CLS_FW=m
 CONFIG_NET_CLS_U32=m
 # CONFIG_CLS_U32_PERF is not set
-# CONFIG_NET_CLS_IND is not set
 # CONFIG_CLS_U32_MARK is not set
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
 # CONFIG_NET_EMATCH is not set
 # CONFIG_NET_CLS_ACT is not set
 CONFIG_NET_CLS_POLICE=y
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_ESTIMATOR=y
 
 #
 # Network testing
@@ -437,6 +477,11 @@
 # CONFIG_DEBUG_DRIVER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
@@ -458,6 +503,7 @@
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -492,7 +538,6 @@
 # CONFIG_MTD_PHYSMAP is not set
 # CONFIG_MTD_ARM_INTEGRATOR is not set
 CONFIG_MTD_IXP4XX=y
-# CONFIG_MTD_EDB7312 is not set
 # CONFIG_MTD_PCI is not set
 # CONFIG_MTD_PLATRAM is not set
 
@@ -523,6 +568,11 @@
 # CONFIG_MTD_NAND_NANDSIM is not set
 
 #
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
@@ -548,14 +598,6 @@
 CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -668,6 +710,7 @@
 CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_SMC91X is not set
 # CONFIG_DM9000 is not set
@@ -739,6 +782,7 @@
 #
 # Wireless 802.11b ISA/PCI cards support
 #
+# CONFIG_AIRO is not set
 CONFIG_HERMES=y
 # CONFIG_PLX_HERMES is not set
 # CONFIG_TMD_HERMES is not set
@@ -782,6 +826,7 @@
 #
 # ATM drivers
 #
+# CONFIG_ATM_DUMMY is not set
 CONFIG_ATM_TCP=m
 # CONFIG_ATM_LANAI is not set
 # CONFIG_ATM_ENI is not set
@@ -902,6 +947,7 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -954,6 +1000,7 @@
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -1036,6 +1083,10 @@
 # CONFIG_USB is not set
 
 #
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
 # USB Gadget Support
 #
 # CONFIG_USB_GADGET is not set
@@ -1110,6 +1161,7 @@
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -1190,7 +1242,9 @@
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_WAITQ is not set
 CONFIG_DEBUG_ERRORS=y
diff --git a/arch/arm/configs/poodle_defconfig b/arch/arm/configs/poodle_defconfig
deleted file mode 100644
index 7282290..0000000
--- a/arch/arm/configs/poodle_defconfig
+++ /dev/null
@@ -1,1015 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc3
-# Sun Oct  9 17:04:29 2005
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_AAEC2000 is not set
-
-#
-# Intel PXA2xx Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_MACH_MAINSTONE is not set
-# CONFIG_ARCH_PXA_IDP is not set
-CONFIG_PXA_SHARPSL=y
-CONFIG_PXA_SHARPSL_25x=y
-# CONFIG_PXA_SHARPSL_27x is not set
-CONFIG_MACH_POODLE=y
-# CONFIG_MACH_CORGI is not set
-# CONFIG_MACH_SHEPHERD is not set
-# CONFIG_MACH_HUSKY is not set
-CONFIG_PXA25x=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_TLB_V4WBI=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-CONFIG_XSCALE_PMU=y
-CONFIG_SHARP_LOCOMO=y
-CONFIG_SHARP_PARAM=y
-CONFIG_SHARP_SCOOP=y
-
-#
-# Bus support
-#
-CONFIG_ISA_DMA_API=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_PCMCIA=y
-CONFIG_PCMCIA_LOAD_CIS=y
-CONFIG_PCMCIA_IOCTL=y
-
-#
-# PC-card bridges
-#
-CONFIG_PCMCIA_PXA2XX=y
-
-#
-# Kernel Features
-#
-CONFIG_PREEMPT=y
-# CONFIG_NO_IDLE_HZ is not set
-# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2   debug"
-# CONFIG_XIP_KERNEL is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=m
-CONFIG_BINFMT_MISC=m
-# CONFIG_ARTHUR is not set
-
-#
-# Power management options
-#
-CONFIG_PM=y
-CONFIG_APM=y
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_SHARP_SL=y
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-# CONFIG_MTD_NAND_H1900 is not set
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-CONFIG_MTD_NAND_SHARPSL=y
-# CONFIG_MTD_NAND_NANDSIM is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# PHY device support
-#
-# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_SMC91X is not set
-# CONFIG_DM9000 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=y
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_TSDEV=y
-CONFIG_INPUT_TSDEV_SCREEN_X=240
-CONFIG_INPUT_TSDEV_SCREEN_Y=320
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_EVBUG=y
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_LOCOMO=y
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_CORGI is not set
-CONFIG_KEYBOARD_SPITZ=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-# CONFIG_I2C_CHARDEV is not set
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_PXA is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_ISA is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-CONFIG_I2C_DEBUG_CORE=y
-CONFIG_I2C_DEBUG_ALGO=y
-CONFIG_I2C_DEBUG_BUS=y
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Hardware Monitoring support
-#
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia Capabilities Port drivers
-#
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_MAESTRO is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
-# CONFIG_FB_MACMODES is not set
-CONFIG_FB_MODE_HELPERS=y
-# CONFIG_FB_TILEBLITTING is not set
-CONFIG_FB_PXA=y
-# CONFIG_FB_W100 is not set
-# CONFIG_FB_PXA_PARAMETERS is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_7x14 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-# CONFIG_FONT_MINI_4x6 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_10x18 is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-CONFIG_USB_GADGET_SELECTED=y
-# CONFIG_USB_GADGET_NET2280 is not set
-CONFIG_USB_GADGET_PXA2XX=y
-CONFIG_USB_PXA2XX=y
-# CONFIG_USB_PXA2XX_SMALL is not set
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
-# CONFIG_USB_ZERO is not set
-CONFIG_USB_ETH=y
-CONFIG_USB_ETH_RNDIS=y
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
-
-#
-# MMC/SD Card support
-#
-CONFIG_MMC=y
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_PXA=y
-# CONFIG_MMC_WBSD is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-CONFIG_JFFS2_RUBIN=y
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-CONFIG_CRAMFS=m
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_NFS_FS is not set
-# CONFIG_NFSD is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="cp437"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=y
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_WAITQ is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=y
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index 900e04f..9895539 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc3
-# Sun Oct  9 17:11:19 2005
+# Linux kernel version: 2.6.15-rc2
+# Mon Nov 28 10:26:52 2005
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
@@ -64,6 +64,23 @@
 CONFIG_KMOD=y
 
 #
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # System Type
 #
 # CONFIG_ARCH_CLPS7500 is not set
@@ -85,6 +102,7 @@
 # CONFIG_ARCH_LH7A40X is not set
 # CONFIG_ARCH_OMAP is not set
 # CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_REALVIEW is not set
 # CONFIG_ARCH_IMX is not set
 # CONFIG_ARCH_H720X is not set
 # CONFIG_ARCH_AAEC2000 is not set
@@ -98,10 +116,13 @@
 CONFIG_PXA_SHARPSL=y
 # CONFIG_PXA_SHARPSL_25x is not set
 CONFIG_PXA_SHARPSL_27x=y
+CONFIG_MACH_AKITA=y
 CONFIG_MACH_SPITZ=y
 CONFIG_MACH_BORZOI=y
 CONFIG_PXA27x=y
+CONFIG_IWMMXT=y
 CONFIG_PXA_SHARP_Cxx00=y
+CONFIG_PXA_SSP=y
 
 #
 # Processor Type
@@ -153,6 +174,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4096
 CONFIG_ALIGNMENT_TRAP=y
 
 #
@@ -233,6 +255,10 @@
 CONFIG_IPV6_TUNNEL=m
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
 # CONFIG_NETFILTER_NETLINK is not set
 
 #
@@ -354,6 +380,10 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
 CONFIG_NET_CLS_ROUTE=y
 
@@ -411,6 +441,7 @@
 # CONFIG_SMC_IRCC_FIR is not set
 # CONFIG_ALI_FIR is not set
 # CONFIG_VIA_FIR is not set
+CONFIG_PXA_FICP=m
 CONFIG_BT=m
 CONFIG_BT_L2CAP=m
 CONFIG_BT_SCO=m
@@ -429,7 +460,6 @@
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_BCSP_TXCRC=y
 CONFIG_BT_HCIBCM203X=m
 CONFIG_BT_HCIBPA10X=m
 CONFIG_BT_HCIBFUSB=m
@@ -457,6 +487,11 @@
 # CONFIG_DEBUG_DRIVER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
@@ -475,6 +510,7 @@
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
 
 #
 # RAM/ROM/Flash chip drivers
@@ -530,6 +566,11 @@
 # CONFIG_MTD_NAND_NANDSIM is not set
 
 #
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
@@ -549,14 +590,6 @@
 # CONFIG_BLK_DEV_RAM is not set
 CONFIG_BLK_DEV_RAM_COUNT=16
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -623,6 +656,7 @@
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 
@@ -746,6 +780,7 @@
 # CONFIG_PPP_SYNC_TTY is not set
 # CONFIG_PPP_DEFLATE is not set
 CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
 # CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 # CONFIG_SHAPER is not set
@@ -771,6 +806,7 @@
 # CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_POWER is not set
 
 #
 # Input Device Drivers
@@ -848,16 +884,37 @@
 # PCMCIA character devices
 #
 # CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
 # CONFIG_RAW_DRIVER is not set
 
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
 #
-# CONFIG_I2C is not set
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_PXA=y
+# CONFIG_I2C_PXA_SLAVE is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
 
 #
 # Hardware Monitoring support
@@ -891,14 +948,13 @@
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
-CONFIG_FB_SOFT_CURSOR=y
 # CONFIG_FB_MACMODES is not set
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
-CONFIG_FB_PXA=y
-# CONFIG_FB_W100 is not set
-# CONFIG_FB_PXA_PARAMETERS is not set
 # CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_PXA=y
+# CONFIG_FB_PXA_PARAMETERS is not set
+# CONFIG_FB_W100 is not set
 # CONFIG_FB_VIRTUAL is not set
 
 #
@@ -907,6 +963,7 @@
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
 CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
@@ -965,15 +1022,15 @@
 #
 # USB Device Class drivers
 #
-
-#
-# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
-#
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -985,7 +1042,6 @@
 # CONFIG_USB_STORAGE_SDDR09 is not set
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
 
 #
 # USB Input Devices
@@ -1058,6 +1114,7 @@
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 # CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
 CONFIG_USB_SERIAL_BELKIN=m
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
@@ -1218,6 +1275,7 @@
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
 CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
 CONFIG_JFFS2_COMPRESSION_OPTIONS=y
 CONFIG_JFFS2_ZLIB=y
 CONFIG_JFFS2_RTIME=y
@@ -1344,7 +1402,9 @@
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_WAITQ is not set
 CONFIG_DEBUG_ERRORS=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index c11169b..de94b0f 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -2,15 +2,16 @@
 # Makefile for the linux kernel.
 #
 
-AFLAGS_head.o := -DKERNEL_RAM_ADDR=$(TEXTADDR)
+AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
 
 # Object file lists.
 
-obj-y		:= compat.o dma.o entry-armv.o entry-common.o irq.o \
+obj-y		:= compat.o entry-armv.o entry-common.o irq.o \
 		   process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
 		   time.o traps.o
 
 obj-$(CONFIG_APM)		+= apm.o
+obj-$(CONFIG_ISA_DMA_API)	+= dma.o
 obj-$(CONFIG_ARCH_ACORN)	+= ecard.o 
 obj-$(CONFIG_FOOTBRIDGE)	+= isa.o
 obj-$(CONFIG_FIQ)		+= fiq.o
diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c
index a2843be..b9df1b7 100644
--- a/arch/arm/kernel/apm.c
+++ b/arch/arm/kernel/apm.c
@@ -20,7 +20,6 @@
 #include <linux/apm_bios.h>
 #include <linux/sched.h>
 #include <linux/pm.h>
-#include <linux/pm_legacy.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -81,6 +80,7 @@
  */
 static int suspends_pending;
 static int apm_disabled;
+static int arm_apm_active;
 
 static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
@@ -477,9 +477,9 @@
 		apm_event_t event;
 
 		wait_event_interruptible(kapmd_wait,
-				!queue_empty(&kapmd_queue) || !pm_active);
+				!queue_empty(&kapmd_queue) || !arm_apm_active);
 
-		if (!pm_active)
+		if (!arm_apm_active)
 			break;
 
 		spin_lock_irq(&kapmd_queue_lock);
@@ -522,16 +522,11 @@
 		return -ENODEV;
 	}
 
-	if (PM_IS_ACTIVE()) {
-		printk(KERN_NOTICE "apm: overridden by ACPI.\n");
-		return -EINVAL;
-	}
-
-	pm_active = 1;
+	arm_apm_active = 1;
 
 	ret = kernel_thread(kapmd, NULL, CLONE_KERNEL);
 	if (ret < 0) {
-		pm_active = 0;
+		arm_apm_active = 0;
 		return ret;
 	}
 
@@ -543,7 +538,7 @@
 	if (ret != 0) {
 		remove_proc_entry("apm", NULL);
 
-		pm_active = 0;
+		arm_apm_active = 0;
 		wake_up(&kapmd_wait);
 		wait_for_completion(&kapmd_exit);
 	}
@@ -556,7 +551,7 @@
 	misc_deregister(&apm_device);
 	remove_proc_entry("apm", NULL);
 
-	pm_active = 0;
+	arm_apm_active = 0;
 	wake_up(&kapmd_wait);
 	wait_for_completion(&kapmd_exit);
 }
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 04d3082..0abbce8 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -23,20 +23,15 @@
 #error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
 #endif
 /*
- * GCC 2.95.1, 2.95.2: ignores register clobber list in asm().
  * GCC 3.0, 3.1: general bad code generation.
  * GCC 3.2.0: incorrect function argument offset calculation.
  * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
  *            (http://gcc.gnu.org/PR8896) and incorrect structure
  *	      initialisation in fs/jffs2/erase.c
  */
-#if __GNUC__ < 2 || \
-   (__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \
-   (__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \
-					     __GNUC_PATCHLEVEL__ < 3) || \
-   (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
 #error Your compiler is too buggy; it is known to miscompile kernels.
-#error    Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3
+#error    Known good compilers: 3.3
 #endif
 
 /* Use marker if you need to separate the values later */
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 2ad4aa2..55076a7 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -131,7 +131,7 @@
 		.long	sys_wait4
 /* 115 */	.long	sys_swapoff
 		.long	sys_sysinfo
-		.long	sys_ipc_wrapper
+		.long	sys_ipc
 		.long	sys_fsync
 		.long	sys_sigreturn_wrapper
 /* 120 */	.long	sys_clone_wrapper
@@ -254,7 +254,7 @@
 		.long	sys_fremovexattr
 		.long	sys_tkill
 		.long	sys_sendfile64
-/* 240 */	.long	sys_futex_wrapper
+/* 240 */	.long	sys_futex
 		.long	sys_sched_setaffinity
 		.long	sys_sched_getaffinity
 		.long	sys_io_setup
@@ -284,7 +284,7 @@
 		.long	sys_fstatfs64
 		.long	sys_tgkill
 		.long	sys_utimes
-/* 270 */	.long	sys_arm_fadvise64_64_wrapper
+/* 270 */	.long	sys_arm_fadvise64_64
 		.long	sys_pciconfig_iobase
 		.long	sys_pciconfig_read
 		.long	sys_pciconfig_write
@@ -333,7 +333,7 @@
 		.long	sys_inotify_init
 		.long	sys_inotify_add_watch
 		.long	sys_inotify_rm_watch
-		.long	sys_mbind_wrapper
+		.long	sys_mbind
 /* 320 */	.long	sys_get_mempolicy
 		.long	sys_set_mempolicy
 __syscall_end:
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index e9a3630..0353276 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -18,7 +18,7 @@
  */
 #include <linux/ioport.h>
 #include <linux/init.h>
-#include <linux/pci.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/dma.h>
 #include <asm/io.h>
@@ -65,37 +65,41 @@
 {
 	if (dma->invalid) {
 		unsigned long address, length;
-		unsigned int mode, direction;
+		unsigned int mode;
+		enum dma_data_direction direction;
 
 		mode = channel & 3;
 		switch (dma->dma_mode & DMA_MODE_MASK) {
 		case DMA_MODE_READ:
 			mode |= ISA_DMA_MODE_READ;
-			direction = PCI_DMA_FROMDEVICE;
+			direction = DMA_FROM_DEVICE;
 			break;
 
 		case DMA_MODE_WRITE:
 			mode |= ISA_DMA_MODE_WRITE;
-			direction = PCI_DMA_TODEVICE;
+			direction = DMA_TO_DEVICE;
 			break;
 
 		case DMA_MODE_CASCADE:
 			mode |= ISA_DMA_MODE_CASCADE;
-			direction = PCI_DMA_BIDIRECTIONAL;
+			direction = DMA_BIDIRECTIONAL;
 			break;
 
 		default:
-			direction = PCI_DMA_NONE;
+			direction = DMA_NONE;
 			break;
 		}
 
-		if (!dma->using_sg) {
+		if (!dma->sg) {
 			/*
 			 * Cope with ISA-style drivers which expect cache
 			 * coherence.
 			 */
-			dma->buf.dma_address = pci_map_single(NULL,
-				dma->buf.__address, dma->buf.length,
+			dma->sg = &dma->buf;
+			dma->sgcount = 1;
+			dma->buf.length = dma->count;
+			dma->buf.dma_address = dma_map_single(NULL,
+				dma->addr, dma->count,
 				direction);
 		}
 
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 2b78838..5a0f4bc 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -12,8 +12,6 @@
  *  DMA facilities.
  */
 #include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mman.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/errno.h>
@@ -23,8 +21,7 @@
 #include <asm/mach/dma.h>
 
 DEFINE_SPINLOCK(dma_spin_lock);
-
-#if MAX_DMA_CHANNELS > 0
+EXPORT_SYMBOL(dma_spin_lock);
 
 static dma_t dma_chan[MAX_DMA_CHANNELS];
 
@@ -81,6 +78,7 @@
 busy:
 	return -EBUSY;
 }
+EXPORT_SYMBOL(request_dma);
 
 /*
  * Free DMA channel
@@ -112,6 +110,7 @@
 bad_dma:
 	printk(KERN_ERR "dma: trying to free DMA%d\n", channel);
 }
+EXPORT_SYMBOL(free_dma);
 
 /* Set DMA Scatter-Gather list
  */
@@ -125,15 +124,15 @@
 
 	dma->sg = sg;
 	dma->sgcount = nr_sg;
-	dma->using_sg = 1;
 	dma->invalid = 1;
 }
+EXPORT_SYMBOL(set_dma_sg);
 
 /* Set DMA address
  *
  * Copy address to the structure, and set the invalid bit
  */
-void set_dma_addr (dmach_t channel, unsigned long physaddr)
+void __set_dma_addr (dmach_t channel, void *addr)
 {
 	dma_t *dma = dma_chan + channel;
 
@@ -141,12 +140,11 @@
 		printk(KERN_ERR "dma%d: altering DMA address while "
 		       "DMA active\n", channel);
 
-	dma->sg = &dma->buf;
-	dma->sgcount = 1;
-	dma->buf.__address = bus_to_virt(physaddr);
-	dma->using_sg = 0;
+	dma->sg = NULL;
+	dma->addr = addr;
 	dma->invalid = 1;
 }
+EXPORT_SYMBOL(__set_dma_addr);
 
 /* Set DMA byte count
  *
@@ -160,12 +158,11 @@
 		printk(KERN_ERR "dma%d: altering DMA count while "
 		       "DMA active\n", channel);
 
-	dma->sg = &dma->buf;
-	dma->sgcount = 1;
-	dma->buf.length = count;
-	dma->using_sg = 0;
+	dma->sg = NULL;
+	dma->count = count;
 	dma->invalid = 1;
 }
+EXPORT_SYMBOL(set_dma_count);
 
 /* Set DMA direction mode
  */
@@ -180,6 +177,7 @@
 	dma->dma_mode = mode;
 	dma->invalid = 1;
 }
+EXPORT_SYMBOL(set_dma_mode);
 
 /* Enable DMA channel
  */
@@ -200,6 +198,7 @@
 	printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel);
 	BUG();
 }
+EXPORT_SYMBOL(enable_dma);
 
 /* Disable DMA channel
  */
@@ -220,6 +219,7 @@
 	printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel);
 	BUG();
 }
+EXPORT_SYMBOL(disable_dma);
 
 /*
  * Is the specified DMA channel active?
@@ -233,6 +233,7 @@
 {
 	printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel);
 }
+EXPORT_SYMBOL(set_dma_page);
 
 void set_dma_speed(dmach_t channel, int cycle_ns)
 {
@@ -243,6 +244,7 @@
 		ret = dma->d_ops->setspeed(channel, dma, cycle_ns);
 	dma->speed = ret;
 }
+EXPORT_SYMBOL(set_dma_speed);
 
 int get_dma_residue(dmach_t channel)
 {
@@ -254,49 +256,12 @@
 
 	return ret;
 }
+EXPORT_SYMBOL(get_dma_residue);
 
-void __init init_dma(void)
+static int __init init_dma(void)
 {
 	arch_dma_init(dma_chan);
-}
-
-#else
-
-int request_dma(dmach_t channel, const char *device_id)
-{
-	return -EINVAL;
-}
-
-int get_dma_residue(dmach_t channel)
-{
 	return 0;
 }
 
-#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a)
-GLOBAL_ALIAS(disable_dma, get_dma_residue);
-GLOBAL_ALIAS(enable_dma, get_dma_residue);
-GLOBAL_ALIAS(free_dma, get_dma_residue);
-GLOBAL_ALIAS(get_dma_list, get_dma_residue);
-GLOBAL_ALIAS(set_dma_mode, get_dma_residue);
-GLOBAL_ALIAS(set_dma_page, get_dma_residue);
-GLOBAL_ALIAS(set_dma_count, get_dma_residue);
-GLOBAL_ALIAS(set_dma_addr, get_dma_residue);
-GLOBAL_ALIAS(set_dma_sg, get_dma_residue);
-GLOBAL_ALIAS(set_dma_speed, get_dma_residue);
-GLOBAL_ALIAS(init_dma, get_dma_residue);
-
-#endif
-
-EXPORT_SYMBOL(request_dma);
-EXPORT_SYMBOL(free_dma);
-EXPORT_SYMBOL(enable_dma);
-EXPORT_SYMBOL(disable_dma);
-EXPORT_SYMBOL(set_dma_addr);
-EXPORT_SYMBOL(set_dma_count);
-EXPORT_SYMBOL(set_dma_mode);
-EXPORT_SYMBOL(set_dma_page);
-EXPORT_SYMBOL(get_dma_residue);
-EXPORT_SYMBOL(set_dma_sg);
-EXPORT_SYMBOL(set_dma_speed);
-
-EXPORT_SYMBOL(dma_spin_lock);
+core_initcall(init_dma);
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index d9fb819..a52baed 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -18,8 +18,6 @@
 #include <asm/memory.h>
 #include <asm/glue.h>
 #include <asm/vfpmacros.h>
-#include <asm/hardware.h>		/* should be moved into entry-macro.S */
-#include <asm/arch/irqs.h>		/* should be moved into entry-macro.S */
 #include <asm/arch/entry-macro.S>
 
 #include "entry-header.S"
@@ -614,6 +612,47 @@
 /*
  * Reference prototype:
  *
+ *	void __kernel_memory_barrier(void)
+ *
+ * Input:
+ *
+ *	lr = return address
+ *
+ * Output:
+ *
+ *	none
+ *
+ * Clobbered:
+ *
+ *	the Z flag might be lost
+ *
+ * Definition and user space usage example:
+ *
+ *	typedef void (__kernel_dmb_t)(void);
+ *	#define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0)
+ *
+ * Apply any needed memory barrier to preserve consistency with data modified
+ * manually and __kuser_cmpxchg usage.
+ *
+ * This could be used as follows:
+ *
+ * #define __kernel_dmb() \
+ *         asm volatile ( "mov r0, #0xffff0fff; mov lr, pc; sub pc, r0, #95" \
+ *	        : : : "lr","cc" )
+ */
+
+__kuser_memory_barrier:				@ 0xffff0fa0
+
+#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP)
+	mcr	p15, 0, r0, c7, c10, 5	@ dmb
+#endif
+	mov	pc, lr
+
+	.align	5
+
+/*
+ * Reference prototype:
+ *
  *	int __kernel_cmpxchg(int oldval, int newval, int *ptr)
  *
  * Input:
@@ -642,6 +681,8 @@
  * The C flag is also set if *ptr was changed to allow for assembly
  * optimization in the calling code.
  *
+ * Note: this routine already includes memory barriers as needed.
+ *
  * For example, a user space atomic_add implementation could look like this:
  *
  * #define atomic_add(ptr, val) \
@@ -698,10 +739,16 @@
 
 #else
 
+#ifdef CONFIG_SMP
+	mcr	p15, 0, r0, c7, c10, 5	@ dmb
+#endif
 	ldrex	r3, [r2]
 	subs	r3, r3, r0
 	strexeq	r3, r1, [r2]
 	rsbs	r0, r3, #0
+#ifdef CONFIG_SMP
+	mcr	p15, 0, r0, c7, c10, 5	@ dmb
+#endif
 	mov	pc, lr
 
 #endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index f7f18307..e2b4299 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -145,7 +145,7 @@
 #endif
 	enable_irq
 
-	str	r4, [sp, #-S_OFF]!		@ push fifth arg
+	stmdb	sp!, {r4, r5}			@ push fifth and sixth args
 
 	get_thread_info tsk
 	ldr	ip, [tsk, #TI_FLAGS]		@ check for syscall tracing
@@ -204,7 +204,7 @@
  * Special system call wrappers
  */
 @ r0 = syscall number
-@ r5 = syscall table
+@ r8 = syscall table
 		.type	sys_syscall, #function
 sys_syscall:
 		eor	scno, r0, #__NR_SYSCALL_BASE
@@ -255,22 +255,6 @@
 		ldr	r2, [sp, #S_OFF + S_SP]
 		b	do_sigaltstack
 
-sys_futex_wrapper:
-		str	r5, [sp, #4]		@ push sixth arg
-		b	sys_futex
-
-sys_arm_fadvise64_64_wrapper:
-		str	r5, [sp, #4]		@ push r5 to stack
-		b	sys_arm_fadvise64_64
-
-sys_mbind_wrapper:
-		str	r5, [sp, #4]
-		b	sys_mbind
-
-sys_ipc_wrapper:
-		str	r5, [sp, #4]		@ push sixth arg
-		b	sys_ipc
-
 /*
  * Note: off_4k (r5) is always units of 4K.  If we can't do the requested
  * offset, we return EINVAL.
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 8d87484..1e985f2 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -17,7 +17,6 @@
 
 #include <asm/assembler.h>
 #include <asm/domain.h>
-#include <asm/mach-types.h>
 #include <asm/procinfo.h>
 #include <asm/ptrace.h>
 #include <asm/asm-offsets.h>
@@ -34,6 +33,8 @@
 #define MACHINFO_PGOFFIO	12
 #define MACHINFO_NAME		16
 
+#define KERNEL_RAM_ADDR	(PAGE_OFFSET + TEXT_OFFSET)
+
 /*
  * swapper_pg_dir is the virtual address of the initial page table.
  * We place the page tables 16K below KERNEL_RAM_ADDR.  Therefore, we must
@@ -83,7 +84,7 @@
 						@ and irqs disabled
 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
 	movs	r10, r5				@ invalid processor (r5=0)?
-	beq	__error_p				@ yes, error 'p'
+	beq	__error_p			@ yes, error 'p'
 	bl	__lookup_machine_type		@ r5=machinfo
 	movs	r8, r5				@ invalid machine (r5=0)?
 	beq	__error_a			@ yes, error 'a'
@@ -343,16 +344,12 @@
 	bne	1b
 #if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS)
 	/*
-	 * If we're using the NetWinder, we need to map in
-	 * the 16550-type serial port for the debug messages
+	 * If we're using the NetWinder or CATS, we also need to map
+	 * in the 16550-type serial port for the debug messages
 	 */
-	teq	r1, #MACH_TYPE_NETWINDER
-	teqne	r1, #MACH_TYPE_CATS
-	bne	1f
 	add	r0, r4, #0xff000000 >> 18
 	orr	r3, r7, #0x7c000000
 	str	r3, [r0]
-1:
 #endif
 #ifdef CONFIG_ARCH_RPC
 	/*
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index d7099db..b5645c4 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -684,8 +684,12 @@
 	spin_lock_irqsave(&irq_controller_lock, flags);
 	p = &desc->action;
 	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ)) {
+		/*
+		 * Can't share interrupts unless both agree to and are
+		 * the same type.
+		 */
+		if (!(old->flags & new->flags & SA_SHIRQ) ||
+		    (~old->flags & new->flags) & SA_TRIGGER_MASK) {
 			spin_unlock_irqrestore(&irq_controller_lock, flags);
 			return -EBUSY;
 		}
@@ -705,6 +709,12 @@
 		desc->running = 0;
 		desc->pending = 0;
 		desc->disable_depth = 1;
+
+		if (new->flags & SA_TRIGGER_MASK) {
+			unsigned int type = new->flags & SA_TRIGGER_MASK;
+			desc->chip->set_type(irq, type);
+		}
+
 		if (!desc->noautoenable) {
 			desc->disable_depth = 0;
 			desc->chip->unmask(irq);
@@ -1027,7 +1037,6 @@
 void __init init_IRQ(void)
 {
 	struct irqdesc *desc;
-	extern void init_dma(void);
 	int irq;
 
 #ifdef CONFIG_SMP
@@ -1041,7 +1050,6 @@
 	}
 
 	init_arch_irq();
-	init_dma();
 }
 
 static int __init noirqdebug_setup(char *str)
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 6055e14..055bf5d 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -101,6 +101,8 @@
 			break;
 
 		case R_ARM_PC24:
+		case R_ARM_CALL:
+		case R_ARM_JUMP24:
 			offset = (*(u32 *)loc & 0x00ffffff) << 2;
 			if (offset & 0x02000000)
 				offset -= 0x04000000;
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 30494aa..54a21bd 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -28,10 +28,9 @@
 #include <linux/init.h>
 #include <linux/cpu.h>
 
-#include <asm/system.h>
-#include <asm/io.h>
 #include <asm/leds.h>
 #include <asm/processor.h>
+#include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/mach/time.h>
 
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 9a340e7..2b84f78 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -242,6 +242,15 @@
 		 */
 		long aluop1, aluop2, ccbit;
 
+	        if ((insn & 0x0fffffd0) == 0x012fff10) {
+		        /*
+			 * bx or blx
+			 */
+			alt = get_user_reg(child, insn & 15);
+			break;
+		}
+
+
 		if ((insn & 0xf000) != 0xf000)
 			break;
 
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 8577416..2cab741a 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -26,8 +26,6 @@
 
 #include <asm/cpu.h>
 #include <asm/elf.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
 #include <asm/procinfo.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index fc47291..d7d932c 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -29,9 +29,6 @@
 #include <linux/sysdev.h>
 #include <linux/timer.h>
 
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/leds.h>
 #include <asm/thread_info.h>
 #include <asm/mach/time.h>
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 45e9ea6..c9fe6f5 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -23,7 +23,6 @@
 
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
-#include <asm/io.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 9a47770..2b254e8 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -17,15 +17,13 @@
 jiffies = jiffies_64 + 4;
 #endif
 
-#ifdef CONFIG_XIP_KERNEL
-#define TEXTADDR  XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
-#else
-#define TEXTADDR  KERNEL_RAM_ADDR
-#endif
-
 SECTIONS
 {
-	. = TEXTADDR;
+#ifdef CONFIG_XIP_KERNEL
+	. = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR);
+#else
+	. = PAGE_OFFSET + TEXT_OFFSET;
+#endif
 	.init : {			/* Init code and data		*/
 		_stext = .;
 			_sinittext = .;
@@ -104,7 +102,7 @@
 
 #ifdef CONFIG_XIP_KERNEL
 	__data_loc = ALIGN(4);		/* location in binary */
-	. = KERNEL_RAM_ADDR;
+	. = PAGE_OFFSET + TEXT_OFFSET;
 #else
 	. = ALIGN(THREAD_SIZE);
 	__data_loc = .;
diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c
index 0340ddc..1c84c60 100644
--- a/arch/arm/mach-aaec2000/clock.c
+++ b/arch/arm/mach-aaec2000/clock.c
@@ -15,9 +15,9 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/string.h>
+#include <linux/clk.h>
 
 #include <asm/semaphore.h>
-#include <asm/hardware/clock.h>
 
 #include "clock.h"
 
@@ -58,17 +58,6 @@
 }
 EXPORT_SYMBOL(clk_disable);
 
-int clk_use(struct clk *clk)
-{
-	return 0;
-}
-EXPORT_SYMBOL(clk_use);
-
-void clk_unuse(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_unuse);
-
 unsigned long clk_get_rate(struct clk *clk)
 {
 	return clk->rate;
diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c
index 4e706d9..dce4815 100644
--- a/arch/arm/mach-aaec2000/core.c
+++ b/arch/arm/mach-aaec2000/core.c
@@ -20,11 +20,11 @@
 #include <linux/interrupt.h>
 #include <linux/timex.h>
 #include <linux/signal.h>
+#include <linux/amba/bus.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/sizes.h>
-#include <asm/hardware/amba.h>
 
 #include <asm/mach/flash.h>
 #include <asm/mach/irq.h>
diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h
index daefc0e..b6029a9 100644
--- a/arch/arm/mach-aaec2000/core.h
+++ b/arch/arm/mach-aaec2000/core.h
@@ -9,7 +9,7 @@
  *
  */
 
-#include <asm/hardware/amba_clcd.h>
+#include <linux/amba/clcd.h>
 
 struct sys_timer;
 
diff --git a/arch/arm/mach-clps711x/dma.c b/arch/arm/mach-clps711x/dma.c
deleted file mode 100644
index af5a4de..0000000
--- a/arch/arm/mach-clps711x/dma.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  linux/arch/arm/mach-clps711x/dma.c
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * 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/init.h>
-
-#include <asm/dma.h>
-#include <asm/mach/dma.h>
-
-void __init arch_dma_init(dma_t *dma)
-{
-}
diff --git a/arch/arm/mach-epxa10db/dma.c b/arch/arm/mach-epxa10db/dma.c
deleted file mode 100644
index 0151e9f..0000000
--- a/arch/arm/mach-epxa10db/dma.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  linux/arch/arm/mach-epxa10db/dma.c
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * 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/init.h>
-
-#include <asm/dma.h>
-#include <asm/mach/dma.h>
-
-void __init arch_dma_init(dma_t *dma)
-{
-}
diff --git a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c
index a6b1396..7a54578 100644
--- a/arch/arm/mach-footbridge/dma.c
+++ b/arch/arm/mach-footbridge/dma.c
@@ -15,6 +15,7 @@
 
 #include <asm/dma.h>
 #include <asm/io.h>
+#include <asm/scatterlist.h>
 
 #include <asm/mach/dma.h>
 #include <asm/hardware/dec21285.h>
diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c
index 775f85f..9e563de 100644
--- a/arch/arm/mach-footbridge/netwinder-hw.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -601,6 +601,7 @@
 EXPORT_SYMBOL(gpio_modify_op);
 EXPORT_SYMBOL(gpio_modify_io);
 EXPORT_SYMBOL(cpld_modify);
+EXPORT_SYMBOL(gpio_read);
 
 /*
  * Initialise any other hardware after we've got the PCI bus
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c
index 708e1b3..c9e0cd8 100644
--- a/arch/arm/mach-imx/mx1ads.c
+++ b/arch/arm/mach-imx/mx1ads.c
@@ -29,27 +29,27 @@
 #include "generic.h"
 #include <asm/serial.h>
 
-static struct resource mx1ads_resources[] = {
+static struct resource cs89x0_resources[] = {
 	[0] = {
-		.start	= IMX_CS4_VIRT,
-		.end	= IMX_CS4_VIRT + 16,
+		.start	= IMX_CS4_PHYS + 0x300,
+		.end	= IMX_CS4_PHYS + 0x300 + 16,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= 13,
-		.end	= 13,
+		.start	= IRQ_GPIOC(17),
+		.end	= IRQ_GPIOC(17),
 		.flags	= IORESOURCE_IRQ,
 	},
 };
 
-static struct platform_device mx1ads_device = {
-	.name		= "mx1ads",
-	.num_resources	= ARRAY_SIZE(mx1ads_resources),
-	.resource	= mx1ads_resources,
+static struct platform_device cs89x0_device = {
+	.name		= "cirrus-cs89x0",
+	.num_resources	= ARRAY_SIZE(cs89x0_resources),
+	.resource	= cs89x0_resources,
 };
 
 static struct platform_device *devices[] __initdata = {
-	&mx1ads_device,
+	&cs89x0_device,
 };
 
 static void __init
@@ -61,45 +61,10 @@
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
-static struct map_desc mx1ads_io_desc[] __initdata = {
-	{
-		.virtual	= IMX_CS0_VIRT,
-		.pfn		= __phys_to_pfn(IMX_CS0_PHYS),
-		.length		= IMX_CS0_SIZE,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= IMX_CS1_VIRT,
-		.pfn		= __phys_to_pfn(IMX_CS1_PHYS),
-		.length		= IMX_CS1_SIZE,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= IMX_CS2_VIRT,
-		.pfn		= __phys_to_pfn(IMX_CS2_PHYS),
-		.length		= IMX_CS2_SIZE,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= IMX_CS3_VIRT,
-		.pfn		= __phys_to_pfn(IMX_CS3_PHYS),
-		.length		= IMX_CS3_SIZE,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= IMX_CS4_VIRT,
-		.pfn		= __phys_to_pfn(IMX_CS4_PHYS),
-		.length		= IMX_CS4_SIZE,
-		.type		= MT_DEVICE
-	}, {
-		.virtual	= IMX_CS5_VIRT,
-		.pfn		= __phys_to_pfn(IMX_CS5_PHYS),
-		.length		= IMX_CS5_SIZE,
-		.type		= MT_DEVICE
-	}
-};
-
 static void __init
 mx1ads_map_io(void)
 {
 	imx_map_io();
-	iotable_init(mx1ads_io_desc, ARRAY_SIZE(mx1ads_io_desc));
 }
 
 MACHINE_START(MX1ADS, "Motorola MX1ADS")
diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c
index 73c3606..40684e0 100644
--- a/arch/arm/mach-integrator/clock.c
+++ b/arch/arm/mach-integrator/clock.c
@@ -14,9 +14,9 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/string.h>
+#include <linux/clk.h>
 
 #include <asm/semaphore.h>
-#include <asm/hardware/clock.h>
 #include <asm/hardware/icst525.h>
 
 #include "clock.h"
@@ -58,17 +58,6 @@
 }
 EXPORT_SYMBOL(clk_disable);
 
-int clk_use(struct clk *clk)
-{
-	return 0;
-}
-EXPORT_SYMBOL(clk_use);
-
-void clk_unuse(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_unuse);
-
 unsigned long clk_get_rate(struct clk *clk)
 {
 	return clk->rate;
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index dacbf50..20071a2 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -15,11 +15,11 @@
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
+#include <linux/amba/bus.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <asm/hardware/amba.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/arch/cm.h>
 #include <asm/system.h>
diff --git a/arch/arm/mach-integrator/dma.c b/arch/arm/mach-integrator/dma.c
deleted file mode 100644
index aae6f23..0000000
--- a/arch/arm/mach-integrator/dma.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  linux/arch/arm/mach-integrator/dma.c
- *
- *  Copyright (C) 1999 ARM Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * 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/slab.h>
-#include <linux/mman.h>
-#include <linux/init.h>
-
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/hardware.h>
-
-#include <asm/mach/dma.h>
-
-void __init arch_dma_init(dma_t *dma)
-{
-}
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index a4bafee..a85d471 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -18,11 +18,11 @@
 #include <linux/device.h>
 #include <linux/errno.h>
 #include <linux/mm.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
 
 #include <asm/io.h>
 #include <asm/hardware/icst525.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/amba_clcd.h>
 #include <asm/arch/lm.h>
 #include <asm/arch/impd1.h>
 #include <asm/sizes.h>
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 4c0f7c65..3afedeb 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -25,6 +25,8 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/kmi.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -32,8 +34,6 @@
 #include <asm/setup.h>
 #include <asm/param.h>		/* HZ */
 #include <asm/mach-types.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/amba_kmi.h>
 
 #include <asm/arch/lm.h>
 
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 93f7ccb..16cf248 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -16,15 +16,15 @@
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/sysdev.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/kmi.h>
+#include <linux/amba/clcd.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/amba_kmi.h>
-#include <asm/hardware/amba_clcd.h>
 #include <asm/hardware/icst525.h>
 
 #include <asm/arch/cm.h>
diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c
index 1a844ca..3c22c16 100644
--- a/arch/arm/mach-integrator/time.c
+++ b/arch/arm/mach-integrator/time.c
@@ -14,8 +14,8 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/amba/bus.h>
 
-#include <asm/hardware/amba.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -96,7 +96,8 @@
 	.set_alarm	= rtc_set_alarm,
 };
 
-static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id,
+				     struct pt_regs *regs)
 {
 	writel(0, rtc_base + RTC_EOI);
 	return IRQ_HANDLED;
@@ -124,7 +125,7 @@
 
 	xtime.tv_sec = __raw_readl(rtc_base + RTC_DR);
 
-	ret = request_irq(dev->irq[0], rtc_interrupt, SA_INTERRUPT,
+	ret = request_irq(dev->irq[0], arm_rtc_interrupt, SA_INTERRUPT,
 			  "rtc-pl030", dev);
 	if (ret)
 		goto map_out;
diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c
index 53f6061..e6ea1cb 100644
--- a/arch/arm/mach-iop3xx/iop331-setup.c
+++ b/arch/arm/mach-iop3xx/iop331-setup.c
@@ -18,7 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/serial.h>
 #include <linux/tty.h>
-#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
 
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -50,32 +50,74 @@
 	}
 };
 
-static struct uart_port iop331_serial_ports[] = {
-	{
-		.membase	= (char*)(IOP331_UART0_VIRT),
-		.mapbase	= (IOP331_UART0_PHYS),
-		.irq		= IRQ_IOP331_UART0,
-		.flags		= UPF_SKIP_TEST,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= IOP331_UART_XTAL,
-		.line		= 0,
-		.type		= PORT_XSCALE,
-		.fifosize	= 32
-	} , {
-		.membase	= (char*)(IOP331_UART1_VIRT),
-		.mapbase	= (IOP331_UART1_PHYS),
-		.irq		= IRQ_IOP331_UART1,
-		.flags		= UPF_SKIP_TEST,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= IOP331_UART_XTAL,
-		.line		= 1,
-		.type		= PORT_XSCALE,
-		.fifosize	= 32
+static struct resource iop33x_uart0_resources[] = {
+	[0] = {
+		.start = IOP331_UART0_PHYS,
+		.end = IOP331_UART0_PHYS + 0x3f,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP331_UART0,
+		.end = IRQ_IOP331_UART0,
+		.flags = IORESOURCE_IRQ
 	}
 };
 
+static struct resource iop33x_uart1_resources[] = {
+	[0] = {
+		.start = IOP331_UART1_PHYS,
+		.end = IOP331_UART1_PHYS + 0x3f,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_IOP331_UART1,
+		.end = IRQ_IOP331_UART1,
+		.flags = IORESOURCE_IRQ
+	}
+};
+
+static struct plat_serial8250_port iop33x_uart0_data[] = {
+	{
+       .membase     = (char*)(IOP331_UART0_VIRT),
+       .mapbase     = (IOP331_UART0_PHYS),
+       .irq         = IRQ_IOP331_UART0,
+       .uartclk     = IOP331_UART_XTAL,
+       .regshift    = 2,
+       .iotype      = UPIO_MEM,
+       .flags       = UPF_SKIP_TEST,
+	},
+	{  },
+};
+
+static struct plat_serial8250_port iop33x_uart1_data[] = {
+	{
+       .membase     = (char*)(IOP331_UART1_VIRT),
+       .mapbase     = (IOP331_UART1_PHYS),
+       .irq         = IRQ_IOP331_UART1,
+       .uartclk     = IOP331_UART_XTAL,
+       .regshift    = 2,
+       .iotype      = UPIO_MEM,
+       .flags       = UPF_SKIP_TEST,
+	},
+	{  },
+};
+
+static struct platform_device iop33x_uart0 = {
+       .name = "serial8250",
+       .id = 0,
+       .dev.platform_data = iop33x_uart0_data,
+       .num_resources = 2,
+       .resource = iop33x_uart0_resources,
+};
+
+static struct platform_device iop33x_uart1 = {
+       .name = "serial8250",
+       .id = 1,
+       .dev.platform_data = iop33x_uart1_data,
+       .num_resources = 2,
+       .resource = iop33x_uart1_resources,
+};
+
 static struct resource iop33x_i2c_0_resources[] = {
 	[0] = {
 		.start = 0xfffff680,
@@ -117,6 +159,8 @@
 };
 
 static struct platform_device *iop33x_devices[] __initdata = {
+	&iop33x_uart0,
+	&iop33x_uart1,
 	&iop33x_i2c_0_controller,
 	&iop33x_i2c_1_controller
 };
@@ -133,8 +177,6 @@
 void __init iop331_map_io(void)
 {
 	iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc));
-	early_serial_setup(&iop331_serial_ports[0]);
-	early_serial_setup(&iop331_serial_ports[1]);
 }
 
 #ifdef CONFIG_ARCH_IOP331
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 3852858..daadc78 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -71,6 +71,14 @@
 	  PrPCM1100 Processor Mezanine Module. For more information on
 	  this platform, see <file:Documentation/arm/IXP4xx>.
 
+config MACH_NAS100D
+	bool
+	prompt "NAS100D"
+	help
+	  Say 'Y' here if you want your kernel to support Iomega's
+	  NAS 100d device. For more information on this platform,
+	  see http://www.nslu2-linux.org/wiki/NAS100d/HomePage
+
 #
 # Avila and IXDP share the same source for now. Will change in future
 #
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 7a15629..0471044 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -9,4 +9,5 @@
 obj-$(CONFIG_ARCH_ADI_COYOTE)	+= coyote-pci.o coyote-setup.o
 obj-$(CONFIG_MACH_GTWX5715)	+= gtwx5715-pci.o gtwx5715-setup.o
 obj-$(CONFIG_MACH_NSLU2)	+= nslu2-pci.o nslu2-setup.o nslu2-power.o
+obj-$(CONFIG_MACH_NAS100D)	+= nas100d-pci.o nas100d-setup.o nas100d-power.o
 
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index 9795da2..6e3462e 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -341,6 +341,29 @@
 	return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M);
 }
 
+/*
+ * Only first 64MB of memory can be accessed via PCI.
+ * We use GFP_DMA to allocate safe buffers to do map/unmap.
+ * This is really ugly and we need a better way of specifying
+ * DMA-capable regions of memory.
+ */
+void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size,
+	unsigned long *zhole_size)
+{
+	unsigned int sz = SZ_64M >> PAGE_SHIFT;
+
+	/*
+	 * Only adjust if > 64M on current system
+	 */
+	if (node || (zone_size[0] <= sz))
+		return;
+
+	zone_size[1] = zone_size[0] - sz;
+	zone_size[0] = sz;
+	zhole_size[1] = zhole_size[0];
+	zhole_size[0] = 0;
+}
+
 void __init ixp4xx_pci_preinit(void)
 {  
 	unsigned long processor_id;
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index f3c687c..6b39369 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -142,6 +142,8 @@
 	*int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
 	    		(line * IXP4XX_GPIO_STYLE_SIZE));
 
+	*IXP4XX_GPIO_GPISR = (1 << line);
+
 	/* Set the new style */
 	*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
 
@@ -169,7 +171,7 @@
 	int line = (irq < 32) ? irq2gpio[irq] : -1;
 
 	if (line >= 0)
-		gpio_line_isr_clear(line);
+		*IXP4XX_GPIO_GPISR = (1 << line);
 }
 
 /*
@@ -330,11 +332,27 @@
 	&ixp46x_i2c_controller
 };
 
+unsigned long ixp4xx_exp_bus_size;
+
 void __init ixp4xx_sys_init(void)
 {
+	ixp4xx_exp_bus_size = SZ_16M;
+
 	if (cpu_is_ixp46x()) {
+		int region;
+
 		platform_add_devices(ixp46x_devices,
 				ARRAY_SIZE(ixp46x_devices));
+
+		for (region = 0; region < 7; region++) {
+			if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) {
+				ixp4xx_exp_bus_size = SZ_32M;
+				break;
+			}
+		}
 	}
+
+	printk("IXP4xx: Using %uMiB expansion bus window size\n",
+			ixp4xx_exp_bus_size >> 20);
 }
 
diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
index 60de8a9..e6b7fcd 100644
--- a/arch/arm/mach-ixp4xx/coyote-pci.c
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -33,9 +33,6 @@
 	set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW);
 	set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQT_LOW);
 
-	gpio_line_isr_clear(COYOTE_PCI_SLOT0_PIN);
-	gpio_line_isr_clear(COYOTE_PCI_SLOT1_PIN);
-
 	ixp4xx_pci_preinit();
 }
 
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index 050c927..679594a 100644
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -14,6 +14,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
+#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -30,8 +31,6 @@
 };
 
 static struct resource coyote_flash_resource = {
-	.start		= COYOTE_FLASH_BASE,
-	.end		= COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE - 1,
 	.flags		= IORESOURCE_MEM,
 };
 
@@ -81,6 +80,11 @@
 
 static void __init coyote_init(void)
 {
+	ixp4xx_sys_init();
+
+	coyote_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+	coyote_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
+
 	*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
 	*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
 
@@ -91,8 +95,6 @@
 		coyote_uart_data[0].irq = IRQ_IXP4XX_UART1;
 	}
 
-
-	ixp4xx_sys_init();
 	platform_add_devices(coyote_devices, ARRAY_SIZE(coyote_devices));
 }
 
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
index 29a6d02..0386704 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -27,6 +27,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
+#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -106,11 +107,9 @@
 	.width		= 2,
 };
 
-static struct resource gtwx5715_flash_resource = {
-	.start		= GTWX5715_FLASH_BASE,
-	.end		= GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE - 1,
+static struct gtw5715_flash_resource = {
 	.flags		= IORESOURCE_MEM,
-};
+}
 
 static struct platform_device gtwx5715_flash = {
 	.name		= "IXP4XX-Flash",
@@ -129,6 +128,14 @@
 
 static void __init gtwx5715_init(void)
 {
+	ixp4xx_sys_init();
+
+	if (!flash_resource)
+		printk(KERN_ERR "Could not allocate flash resource\n");
+
+	gtwx5715_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+	gtwx5715_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_8M - 1;
+
 	platform_add_devices(gtwx5715_devices, ARRAY_SIZE(gtwx5715_devices));
 }
 
diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
index f9a1d3e..da415d5 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -32,11 +32,6 @@
 	set_irq_type(IRQ_IXDP425_PCI_INTC, IRQT_LOW);
 	set_irq_type(IRQ_IXDP425_PCI_INTD, IRQT_LOW);
 
-	gpio_line_isr_clear(IXDP425_PCI_INTA_PIN);
-	gpio_line_isr_clear(IXDP425_PCI_INTB_PIN);
-	gpio_line_isr_clear(IXDP425_PCI_INTC_PIN);
-	gpio_line_isr_clear(IXDP425_PCI_INTD_PIN);
-
 	ixp4xx_pci_preinit();
 }
 
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 0a41080..c2e105c 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -14,6 +14,7 @@
 #include <linux/serial.h>
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
+#include <linux/slab.h>
 
 #include <asm/types.h>
 #include <asm/setup.h>
@@ -30,8 +31,6 @@
 };
 
 static struct resource ixdp425_flash_resource = {
-	.start		= IXDP425_FLASH_BASE,
-	.end		= IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE - 1,
 	.flags		= IORESOURCE_MEM,
 };
 
@@ -85,7 +84,7 @@
 	{
 		.mapbase	= IXP4XX_UART2_BASE_PHYS,
 		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
-		.irq		= IRQ_IXP4XX_UART1,
+		.irq		= IRQ_IXP4XX_UART2,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 		.iotype		= UPIO_MEM,
 		.regshift	= 2,
@@ -108,17 +107,13 @@
 	&ixdp425_uart
 };
 
-
 static void __init ixdp425_init(void)
 {
 	ixp4xx_sys_init();
 
-	/*
-	 * IXP465 has 32MB window
-	 */
-	if (machine_is_ixdp465()) {
-		ixdp425_flash_resource.end += IXDP425_FLASH_SIZE;
-	}
+	ixdp425_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+	ixdp425_flash_resource.end =
+		IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
 
 	platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
 }
diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
index fe5e766..526fb61 100644
--- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
@@ -32,9 +32,6 @@
 	set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW);
 	set_irq_type(IRQ_IXP4XX_GPIO7, IRQT_LOW);
 
-	gpio_line_isr_clear(6);
-	gpio_line_isr_clear(7);
-
 	ixp4xx_pci_preinit();
 }
 
diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c
new file mode 100644
index 0000000..26b7c00
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nas100d-pci.c
@@ -0,0 +1,71 @@
+/*
+ * arch/arm/mach-ixp4xx/nas100d-pci.c
+ *
+ * NAS 100d board-level PCI initialization
+ *
+ * based on ixdp425-pci.c:
+ *	Copyright (C) 2002 Intel Corporation.
+ *	Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Maintainer: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/mach/pci.h>
+#include <asm/mach-types.h>
+
+void __init nas100d_pci_preinit(void)
+{
+	set_irq_type(IRQ_NAS100D_PCI_INTA, IRQT_LOW);
+	set_irq_type(IRQ_NAS100D_PCI_INTB, IRQT_LOW);
+	set_irq_type(IRQ_NAS100D_PCI_INTC, IRQT_LOW);
+	set_irq_type(IRQ_NAS100D_PCI_INTD, IRQT_LOW);
+	set_irq_type(IRQ_NAS100D_PCI_INTE, IRQT_LOW);
+
+	ixp4xx_pci_preinit();
+}
+
+static int __init nas100d_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	static int pci_irq_table[NAS100D_PCI_MAX_DEV][NAS100D_PCI_IRQ_LINES] =
+	{
+		{ IRQ_NAS100D_PCI_INTA, -1, -1 },
+		{ IRQ_NAS100D_PCI_INTB, -1, -1 },
+		{ IRQ_NAS100D_PCI_INTC, IRQ_NAS100D_PCI_INTD, IRQ_NAS100D_PCI_INTE },
+	};
+
+	int irq = -1;
+
+	if (slot >= 1 && slot <= NAS100D_PCI_MAX_DEV &&
+		pin >= 1 && pin <= NAS100D_PCI_IRQ_LINES)
+		irq = pci_irq_table[slot-1][pin-1];
+
+	return irq;
+}
+
+struct hw_pci __initdata nas100d_pci = {
+	.nr_controllers = 1,
+	.preinit	= nas100d_pci_preinit,
+	.swizzle	= pci_std_swizzle,
+	.setup		= ixp4xx_setup,
+	.scan		= ixp4xx_scan_bus,
+	.map_irq	= nas100d_map_irq,
+};
+
+int __init nas100d_pci_init(void)
+{
+	if (machine_is_nas100d())
+		pci_common_init(&nas100d_pci);
+
+	return 0;
+}
+
+subsys_initcall(nas100d_pci_init);
diff --git a/arch/arm/mach-ixp4xx/nas100d-power.c b/arch/arm/mach-ixp4xx/nas100d-power.c
new file mode 100644
index 0000000..2bec69b
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nas100d-power.c
@@ -0,0 +1,67 @@
+/*
+ * arch/arm/mach-ixp4xx/nas100d-power.c
+ *
+ * NAS 100d Power/Reset driver
+ *
+ * Copyright (C) 2005 Tower Technologies
+ *
+ * based on nas100d-io.c
+ *  Copyright (C) 2004 Karen Spearel
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+
+extern void ctrl_alt_del(void);
+
+static irqreturn_t nas100d_reset_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	/* Signal init to do the ctrlaltdel action, this will bypass init if
+	 * it hasn't started and do a kernel_restart.
+	 */
+	ctrl_alt_del();
+
+	return IRQ_HANDLED;
+}
+
+static int __init nas100d_power_init(void)
+{
+	if (!(machine_is_nas100d()))
+		return 0;
+
+	set_irq_type(NAS100D_RB_IRQ, IRQT_LOW);
+
+	if (request_irq(NAS100D_RB_IRQ, &nas100d_reset_handler,
+		SA_INTERRUPT, "NAS100D reset button", NULL) < 0) {
+
+		printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
+			NAS100D_RB_IRQ);
+
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void __exit nas100d_power_exit(void)
+{
+	free_irq(NAS100D_RB_IRQ, NULL);
+}
+
+module_init(nas100d_power_init);
+module_exit(nas100d_power_exit);
+
+MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
+MODULE_DESCRIPTION("NAS100D Power/Reset driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
new file mode 100644
index 0000000..49998a8
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -0,0 +1,135 @@
+/*
+ * arch/arm/mach-ixp4xx/nas100d-setup.c
+ *
+ * NAS 100d board-setup
+ *
+ * based ixdp425-setup.c:
+ *      Copyright (C) 2003-2004 MontaVista Software, Inc.
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ * Author: Rod Whitby <rod@whitby.id.au>
+ * Maintainers: http://www.nslu2-linux.org/
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+
+static struct flash_platform_data nas100d_flash_data = {
+	.map_name		= "cfi_probe",
+	.width			= 2,
+};
+
+static struct resource nas100d_flash_resource = {
+	.flags			= IORESOURCE_MEM,
+};
+
+static struct platform_device nas100d_flash = {
+	.name			= "IXP4XX-Flash",
+	.id			= 0,
+	.dev.platform_data	= &nas100d_flash_data,
+	.num_resources		= 1,
+	.resource		= &nas100d_flash_resource,
+};
+
+static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = {
+	.sda_pin		= NAS100D_SDA_PIN,
+	.scl_pin		= NAS100D_SCL_PIN,
+};
+
+static struct platform_device nas100d_i2c_controller = {
+	.name			= "IXP4XX-I2C",
+	.id			= 0,
+	.dev.platform_data	= &nas100d_i2c_gpio_pins,
+	.num_resources		= 0,
+};
+
+static struct resource nas100d_uart_resources[] = {
+	{
+		.start		= IXP4XX_UART1_BASE_PHYS,
+		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM,
+	},
+	{
+		.start		= IXP4XX_UART2_BASE_PHYS,
+		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff,
+		.flags		= IORESOURCE_MEM,
+	}
+};
+
+static struct plat_serial8250_port nas100d_uart_data[] = {
+	{
+		.mapbase	= IXP4XX_UART1_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART1,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	},
+	{
+		.mapbase	= IXP4XX_UART2_BASE_PHYS,
+		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
+		.irq		= IRQ_IXP4XX_UART2,
+		.flags		= UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+		.uartclk	= IXP4XX_UART_XTAL,
+	},
+	{ }
+};
+
+static struct platform_device nas100d_uart = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev.platform_data	= nas100d_uart_data,
+	.num_resources		= 2,
+	.resource		= nas100d_uart_resources,
+};
+
+static struct platform_device *nas100d_devices[] __initdata = {
+	&nas100d_i2c_controller,
+	&nas100d_flash,
+	&nas100d_uart,
+};
+
+static void nas100d_power_off(void)
+{
+	/* This causes the box to drop the power and go dead. */
+
+	/* enable the pwr cntl gpio */
+	gpio_line_config(NAS100D_PO_GPIO, IXP4XX_GPIO_OUT);
+
+	/* do the deed */
+	gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH);
+}
+
+static void __init nas100d_init(void)
+{
+	ixp4xx_sys_init();
+
+	nas100d_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
+	nas100d_flash_resource.end =
+		IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
+
+	pm_power_off = nas100d_power_off;
+
+	platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices));
+}
+
+MACHINE_START(NAS100D, "Iomega NAS 100d")
+	/* Maintainer: www.nslu2-linux.org */
+	.phys_ram	= PHYS_OFFSET,
+	.phys_io	= IXP4XX_PERIPHERAL_BASE_PHYS,
+	.io_pg_offst	= ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
+	.boot_params	= 0x00000100,
+	.map_io		= ixp4xx_map_io,
+	.init_irq	= ixp4xx_init_irq,
+	.timer          = &ixp4xx_timer,
+	.init_machine	= nas100d_init,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c
index a575f2e..ece8604 100644
--- a/arch/arm/mach-ixp4xx/nslu2-pci.c
+++ b/arch/arm/mach-ixp4xx/nslu2-pci.c
@@ -28,14 +28,6 @@
 	set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW);
 	set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW);
 
-	gpio_line_isr_clear(NSLU2_PCI_INTA_PIN);
-	gpio_line_isr_clear(NSLU2_PCI_INTB_PIN);
-	gpio_line_isr_clear(NSLU2_PCI_INTC_PIN);
-
-	/* INTD is not configured as GPIO is used
-	 * for the power input button.
-	 */
-
 	ixp4xx_pci_preinit();
 }
 
diff --git a/arch/arm/mach-ixp4xx/nslu2-power.c b/arch/arm/mach-ixp4xx/nslu2-power.c
index 18fbc8c..b0ad9e9 100644
--- a/arch/arm/mach-ixp4xx/nslu2-power.c
+++ b/arch/arm/mach-ixp4xx/nslu2-power.c
@@ -54,9 +54,6 @@
 	set_irq_type(NSLU2_RB_IRQ, IRQT_LOW);
 	set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH);
 
-	gpio_line_isr_clear(NSLU2_RB_GPIO);
-	gpio_line_isr_clear(NSLU2_PB_GPIO);
-
 	if (request_irq(NSLU2_RB_IRQ, &nslu2_reset_handler,
 		SA_INTERRUPT, "NSLU2 reset button", NULL) < 0) {
 
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 540b20d..5c975eb 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/notifier.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
 #include <asm/mach-types.h>
@@ -30,7 +31,6 @@
 #include <asm/arch/usb.h>
 #include <asm/arch/board.h>
 #include <asm/arch/common.h>
-#include <asm/hardware/clock.h>
 
 static void __init omap_generic_init_irq(void)
 {
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 4277eee..9d862f8 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -16,9 +16,9 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
-#include <asm/hardware/clock.h>
 
 #include <asm/arch/usb.h>
 #include <asm/arch/clock.h>
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 6810cfb..7a68f09 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -17,10 +17,10 @@
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/clock.h>
 
 #include <asm/arch/board.h>
 #include <asm/arch/mux.h>
@@ -252,9 +252,8 @@
 		return;
 	}
 	omap_set_gpio_direction(gpio_nr, 1);
-	set_irq_type(OMAP_GPIO_IRQ(gpio_nr), IRQT_RISING);
 	ret = request_irq(OMAP_GPIO_IRQ(gpio_nr), &omap_serial_wake_interrupt,
-			  0, "serial wakeup", NULL);
+			  SA_TRIGGER_RISING, "serial wakeup", NULL);
 	if (ret) {
 		omap_free_gpio(gpio_nr);
 		printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n",
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 85818d9..5407b95 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -22,10 +22,10 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
 
-#include <asm/hardware/clock.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sram.h>
 #include <asm/arch/prcm.h>
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index f4df04f..e1bd46a 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -16,9 +16,9 @@
 #include <linux/init.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
-#include <asm/hardware/clock.h>
 
 #include <asm/arch/common.h>
 #include <asm/arch/board.h>
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 9ec1144..23d36b1 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -21,10 +21,11 @@
 #include <linux/time.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
+#include <linux/clk.h>
+
 #include <asm/mach/time.h>
 #include <asm/delay.h>
 #include <asm/io.h>
-#include <asm/hardware/clock.h>
 
 #define OMAP2_GP_TIMER1_BASE	0x48028000
 #define OMAP2_GP_TIMER2_BASE	0x4802a000
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index cd50664..c1d77f5 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -44,6 +44,7 @@
 config PXA_SHARPSL_27x
 	bool "Sharp PXA270 models (SL-Cxx00)"
 	select PXA27x
+	select IWMMXT
 
 endchoice
 
@@ -60,7 +61,6 @@
 	bool "Enable Sharp SL-C700 (Corgi) Support"
 	depends PXA_SHARPSL_25x
 	select PXA_SHARP_C7xx
-	select PXA_SSP
 
 config MACH_SHEPHERD
 	bool "Enable Sharp SL-C750 (Shepherd) Support"
@@ -77,6 +77,8 @@
 	depends PXA_SHARPSL_27x
 	select PXA_SHARP_Cxx00
 	select MACH_SPITZ
+	select I2C
+	select I2C_PXA
 
 config MACH_SPITZ
 	bool "Enable Sharp Zaurus SL-3000 (Spitz) Support"
@@ -90,7 +92,7 @@
 
 config MACH_TOSA
 	bool "Enable Sharp SL-6000x (Tosa) Support"
-	depends PXA_SHARPSL
+	depends PXA_SHARPSL_25x
 
 config PXA25x
 	bool
@@ -110,12 +112,14 @@
 config PXA_SHARP_C7xx
 	bool
 	select PXA_SSP
+	select SHARPSL_PM
 	help
 	  Enable support for all Sharp C7xx models
 
 config PXA_SHARP_Cxx00
 	bool
 	select PXA_SSP
+	select SHARPSL_PM
 	help
 	  Enable common support for Sharp Cxx00 models
 
diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c
index f6d73cc..1b39874 100644
--- a/arch/arm/mach-pxa/akita-ioexp.c
+++ b/arch/arm/mach-pxa/akita-ioexp.c
@@ -124,17 +124,16 @@
 }
 
 static struct i2c_driver max7310_i2c_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "akita-max7310",
+	.driver = {
+		.name	= "akita-max7310",
+	},
 	.id		= I2C_DRIVERID_AKITAIOEXP,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= max7310_attach_adapter,
 	.detach_client	= max7310_detach_client,
 };
 
 static struct i2c_client max7310_template = {
 	name:   "akita-max7310",
-	flags:  I2C_CLIENT_ALLOW_USE,
 	driver: &max7310_i2c_driver,
 };
 
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 100fb31..5a7b873 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -213,15 +213,14 @@
 
 	corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
-	err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int, SA_INTERRUPT,
-			     "MMC card detect", data);
+	err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int,
+			  SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+			  "MMC card detect", data);
 	if (err) {
 		printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
 		return -1;
 	}
 
-	set_irq_type(CORGI_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
-
 	return 0;
 }
 
diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
index 599be14..7a1ab73 100644
--- a/arch/arm/mach-pxa/corgi_pm.c
+++ b/arch/arm/mach-pxa/corgi_pm.c
@@ -33,19 +33,7 @@
 	pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT);
 	pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT);
 	pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN);
-}
-
-static void corgi_charge_led(int val)
-{
-	if (val == SHARPSL_LED_ERROR) {
-		dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
-	} else if (val == SHARPSL_LED_ON) {
-		dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
-		GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
-	} else {
-		dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
-		GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE);
-	}
+	sharpsl_pm_pxa_init();
 }
 
 static void corgi_measure_temp(int on)
@@ -138,15 +126,15 @@
 	dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR);
 
 	if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) {
-		if (STATUS_AC_IN()) {
+		if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
 			/* charge on */
 			dev_dbg(sharpsl_pm.dev, "ac insert\n");
 			sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
 		} else {
 			/* charge off */
 			dev_dbg(sharpsl_pm.dev, "ac remove\n");
-			CHARGE_LED_OFF();
-			CHARGE_OFF();
+			sharpsl_pm_led(SHARPSL_LED_OFF);
+			sharpsl_pm.machinfo->charge(0);
 			sharpsl_pm.charge_mode = CHRG_OFF;
 		}
 	}
@@ -172,23 +160,39 @@
 	return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) );
 }
 
-static int corgi_acin_status(void)
+unsigned long corgipm_read_devdata(int type)
 {
-	return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0);
+	switch(type) {
+	case SHARPSL_STATUS_ACIN:
+		return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0);
+	case SHARPSL_STATUS_LOCK:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock);
+	case SHARPSL_STATUS_CHRGFULL:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull);
+	case SHARPSL_STATUS_FATAL:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal);
+	case SHARPSL_ACIN_VOLT:
+		return sharpsl_pm_pxa_read_max1111(MAX1111_ACIN_VOLT);
+	case SHARPSL_BATT_TEMP:
+		return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_TEMP);
+	case SHARPSL_BATT_VOLT:
+	default:
+		return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_VOLT);
+	}
 }
 
 static struct sharpsl_charger_machinfo corgi_pm_machinfo = {
 	.init            = corgi_charger_init,
+	.exit            = sharpsl_pm_pxa_remove,
 	.gpio_batlock    = CORGI_GPIO_BAT_COVER,
 	.gpio_acin       = CORGI_GPIO_AC_IN,
 	.gpio_batfull    = CORGI_GPIO_CHRG_FULL,
-	.status_acin     = corgi_acin_status,
 	.discharge       = corgi_discharge,
 	.charge          = corgi_charge,
-	.chargeled       = corgi_charge_led,
 	.measure_temp    = corgi_measure_temp,
 	.presuspend      = corgi_presuspend,
 	.postsuspend     = corgi_postsuspend,
+	.read_devdata    = corgipm_read_devdata,
 	.charger_wakeup  = corgi_charger_wakeup,
 	.should_wakeup   = corgi_should_wakeup,
 	.bat_levels      = 40,
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index 07892f4..8da9d3e 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -43,6 +43,7 @@
 #include <asm/arch/pxafb.h>
 #include <asm/arch/mmc.h>
 #include <asm/arch/irda.h>
+#include <asm/arch/ohci.h>
 
 #include "generic.h"
 
@@ -393,6 +394,25 @@
 	&mst_flash_device[1],
 };
 
+static int mainstone_ohci_init(struct device *dev)
+{
+	/* setup Port1 GPIO pin. */
+	pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
+	pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
+
+	/* Set the Power Control Polarity Low and Power Sense
+	   Polarity Low to active low. */
+	UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
+		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+
+	return 0;
+}
+
+static struct pxaohci_platform_data mainstone_ohci_platform_data = {
+	.port_mode	= PMM_PERPORT_MODE,
+	.init		= mainstone_ohci_init,
+};
+
 static void __init mainstone_init(void)
 {
 	int SW7 = 0;  /* FIXME: get from SCR (Mst doc section 3.2.1.1) */
@@ -407,6 +427,12 @@
 	printk(KERN_NOTICE "Mainstone configured to boot from %s\n",
 	       mst_flash_data[0].name);
 
+	/* system bus arbiter setting
+	 * - Core_Park
+	 * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4
+	 */
+	ARB_CNTRL = ARB_CORE_PARK | 0x234;
+
 	/*
 	 * On Mainstone, we route AC97_SYSCLK via GPIO45 to
 	 * the audio daughter card
@@ -424,6 +450,7 @@
 
 	pxa_set_mci_info(&mainstone_mci_platform_data);
 	pxa_set_ficp_info(&mainstone_ficp_platform_data);
+	pxa_set_ohci_info(&mainstone_ohci_platform_data);
 }
 
 
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
index f74b9af..852ea72 100644
--- a/arch/arm/mach-pxa/pm.c
+++ b/arch/arm/mach-pxa/pm.c
@@ -155,19 +155,20 @@
 	PSPR = 0;
 
 	/* restore registers */
+	RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
+	RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
 	RESTORE(GAFR0_L); RESTORE(GAFR0_U);
 	RESTORE(GAFR1_L); RESTORE(GAFR1_U);
 	RESTORE(GAFR2_L); RESTORE(GAFR2_U);
-	RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2);
-	RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
 	RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
 	RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
 	RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2);
 
 #ifdef CONFIG_PXA27x
 	RESTORE(MDREFR);
-	RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3);
-	RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
+	RESTORE_GPLEVEL(3); RESTORE(GPDR3);
+	RESTORE(GAFR3_L); RESTORE(GAFR3_U);
+	RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3);
 	RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER);
 	RESTORE(PFER); RESTORE(PKWR);
 #endif
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index eef3de2..663c950 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -146,15 +146,14 @@
 
 	poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
-	err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, SA_INTERRUPT,
-			     "MMC card detect", data);
+	err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int,
+			  SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+			  "MMC card detect", data);
 	if (err) {
 		printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
 		return -1;
 	}
 
-	set_irq_type(POODLE_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
-
 	return 0;
 }
 
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index c722a9a..b41b1ef 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -21,6 +21,7 @@
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/arch/pxa-regs.h>
+#include <asm/arch/ohci.h>
 
 #include "generic.h"
 
@@ -194,6 +195,11 @@
 	.resource       = pxa27x_ohci_resources,
 };
 
+void __init pxa_set_ohci_info(struct pxaohci_platform_data *info)
+{
+	ohci_device.dev.platform_data = info;
+}
+
 static struct platform_device *devices[] __initdata = {
 	&ohci_device,
 };
diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h
index b0c40a1..da4769c 100644
--- a/arch/arm/mach-pxa/sharpsl.h
+++ b/arch/arm/mach-pxa/sharpsl.h
@@ -1,7 +1,17 @@
 /*
- * SharpSL SSP Driver
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * 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 <asm/hardware/sharpsl_pm.h>
+
+/*
+ * SharpSL SSP Driver
+ */
 struct corgissp_machinfo {
 	int port;
 	int cs_lcdcon;
@@ -14,18 +24,18 @@
 
 void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo);
 
+
 /*
  * SharpSL Backlight
  */
-
 void corgi_bl_set_intensity(int intensity);
 void spitz_bl_set_intensity(int intensity);
 void akita_bl_set_intensity(int intensity);
 
+
 /*
  * SharpSL Touchscreen Driver
  */
-
 unsigned long corgi_get_hsync_len(void);
 unsigned long spitz_get_hsync_len(void);
 void corgi_put_hsync(void);
@@ -33,89 +43,22 @@
 void corgi_wait_hsync(void);
 void spitz_wait_hsync(void);
 
+
 /*
  * SharpSL Battery/PM Driver
  */
 
-struct sharpsl_charger_machinfo {
-	void (*init)(void);
-	int gpio_acin;
-	int gpio_batfull;
-	int gpio_batlock;
-	int gpio_fatal;
-	int (*status_acin)(void);
-	void (*discharge)(int);
-	void (*discharge1)(int);
-	void (*charge)(int);
-	void (*chargeled)(int);
-	void (*measure_temp)(int);
-	void (*presuspend)(void);
-	void (*postsuspend)(void);
-	unsigned long (*charger_wakeup)(void);
-	int (*should_wakeup)(unsigned int resume_on_alarm);
-	int bat_levels;
-	struct battery_thresh *bat_levels_noac;
-	struct battery_thresh *bat_levels_acin;
-	int status_high_acin;
-	int status_low_acin;
-	int status_high_noac;
-	int status_low_noac;
-};
-
-struct battery_thresh {
-	int voltage;
-	int percentage;
-};
-
-struct battery_stat {
-	int ac_status;         /* APM AC Present/Not Present */
-	int mainbat_status;    /* APM Main Battery Status */
-	int mainbat_percent;   /* Main Battery Percentage Charge */
-	int mainbat_voltage;   /* Main Battery Voltage */
-};
-
-struct sharpsl_pm_status {
-	struct device *dev;
-	struct timer_list ac_timer;
-	struct timer_list chrg_full_timer;
-
-	int charge_mode;
-#define CHRG_ERROR    (-1)
-#define CHRG_OFF      (0)
-#define CHRG_ON       (1)
-#define CHRG_DONE     (2)
-
-	unsigned int flags;
-#define SHARPSL_SUSPENDED       (1 << 0)  /* Device is Suspended */
-#define SHARPSL_ALARM_ACTIVE    (1 << 1)  /* Alarm is for charging event (not user) */
-#define SHARPSL_BL_LIMIT        (1 << 2)  /* Backlight Intensity Limited */
-#define SHARPSL_APM_QUEUED      (1 << 3)  /* APM Event Queued */
-#define SHARPSL_DO_OFFLINE_CHRG (1 << 4)  /* Trigger the offline charger */
-
-	int full_count;
-	unsigned long charge_start_time;
-	struct sharpsl_charger_machinfo *machinfo;
-	struct battery_stat battstat;
-};
-
-extern struct sharpsl_pm_status sharpsl_pm;
-extern struct battery_thresh spitz_battery_levels_acin[];
-extern struct battery_thresh spitz_battery_levels_noac[];
-
 #define READ_GPIO_BIT(x)    (GPLR(x) & GPIO_bit(x))
 
-#define SHARPSL_LED_ERROR  2
-#define SHARPSL_LED_ON     1
-#define SHARPSL_LED_OFF    0
+/* MAX1111 Channel Definitions */
+#define MAX1111_BATT_VOLT   4u
+#define MAX1111_BATT_TEMP   2u
+#define MAX1111_ACIN_VOLT   6u
 
-#define CHARGE_ON()         sharpsl_pm.machinfo->charge(1)
-#define CHARGE_OFF()        sharpsl_pm.machinfo->charge(0)
-#define CHARGE_LED_ON()     sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ON)
-#define CHARGE_LED_OFF()    sharpsl_pm.machinfo->chargeled(SHARPSL_LED_OFF)
-#define CHARGE_LED_ERR()    sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR)
-#define DISCHARGE_ON()      sharpsl_pm.machinfo->discharge(1)
-#define DISCHARGE_OFF()     sharpsl_pm.machinfo->discharge(0)
-#define STATUS_AC_IN()      sharpsl_pm.machinfo->status_acin()
-#define STATUS_BATT_LOCKED()  READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock)
-#define STATUS_CHRG_FULL()  READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull)
-#define STATUS_FATAL()      READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal)
+extern struct battery_thresh spitz_battery_levels_acin[];
+extern struct battery_thresh spitz_battery_levels_noac[];
+void sharpsl_pm_pxa_init(void);
+void sharpsl_pm_pxa_remove(void);
+int sharpsl_pm_pxa_read_max1111(int channel);
+
+
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index c10be00..6d402b2 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -15,48 +15,20 @@
 #undef DEBUG
 
 #include <linux/module.h>
-#include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/apm_bios.h>
-#include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/scoop.h>
 #include <asm/mach-types.h>
 #include <asm/irq.h>
 #include <asm/apm.h>
-
 #include <asm/arch/pm.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/arch/sharpsl.h>
 #include "sharpsl.h"
 
-/*
- * Constants
- */
-#define SHARPSL_CHARGE_ON_TIME_INTERVAL        (msecs_to_jiffies(1*60*1000))  /* 1 min */
-#define SHARPSL_CHARGE_FINISH_TIME             (msecs_to_jiffies(10*60*1000)) /* 10 min */
-#define SHARPSL_BATCHK_TIME                    (msecs_to_jiffies(15*1000))    /* 15 sec */
-#define SHARPSL_BATCHK_TIME_SUSPEND            (60*10)                        /* 10 min */
-#define SHARPSL_WAIT_CO_TIME                   15  /* 15 sec */
-#define SHARPSL_WAIT_DISCHARGE_ON              100 /* 100 msec */
-#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP   10  /* 10 msec */
-#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT   10  /* 10 msec */
-#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN   10  /* 10 msec */
-#define SHARPSL_CHARGE_WAIT_TIME               15  /* 15 msec */
-#define SHARPSL_CHARGE_CO_CHECK_TIME           5   /* 5 msec */
-#define SHARPSL_CHARGE_RETRY_CNT               1   /* eqv. 10 min */
-
-#define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
-#define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
-#define SHARPSL_CHARGE_ON_ACIN_HIGH    0x9b  /* 6V */
-#define SHARPSL_CHARGE_ON_ACIN_LOW     0x34  /* 2V */
-#define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
-#define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
-
 struct battery_thresh spitz_battery_levels_acin[] = {
 	{ 213, 100},
 	{ 212,  98},
@@ -151,763 +123,17 @@
 #define MAXCTRL_SEL_SH   4
 #define MAXCTRL_STR      1u << 7
 
-/* MAX1111 Channel Definitions */
-#define BATT_AD    4u
-#define BATT_THM   2u
-#define JK_VAD     6u
-
-
-/*
- * Prototypes
- */
-static int sharpsl_read_main_battery(void);
-static int sharpsl_off_charge_battery(void);
-static int sharpsl_check_battery_temp(void);
-static int sharpsl_check_battery_voltage(void);
-static int sharpsl_ac_check(void);
-static int sharpsl_fatal_check(void);
-static int sharpsl_average_value(int ad);
-static void sharpsl_average_clear(void);
-static void sharpsl_charge_toggle(void *private_);
-static void sharpsl_battery_thread(void *private_);
-
-
-/*
- * Variables
- */
-struct sharpsl_pm_status sharpsl_pm;
-DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL);
-DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
-
-
-static int get_percentage(int voltage)
-{
-	int i = sharpsl_pm.machinfo->bat_levels - 1;
-	struct battery_thresh *thresh;
-
-	if (sharpsl_pm.charge_mode == CHRG_ON)
-		thresh=sharpsl_pm.machinfo->bat_levels_acin;
-	else
-		thresh=sharpsl_pm.machinfo->bat_levels_noac;
-
-	while (i > 0 && (voltage > thresh[i].voltage))
-		i--;
-
-	return thresh[i].percentage;
-}
-
-static int get_apm_status(int voltage)
-{
-	int low_thresh, high_thresh;
-
-	if (sharpsl_pm.charge_mode == CHRG_ON) {
-		high_thresh = sharpsl_pm.machinfo->status_high_acin;
-		low_thresh = sharpsl_pm.machinfo->status_low_acin;
-	} else {
-		high_thresh = sharpsl_pm.machinfo->status_high_noac;
-		low_thresh = sharpsl_pm.machinfo->status_low_noac;
-	}
-
-	if (voltage >= high_thresh)
-		return APM_BATTERY_STATUS_HIGH;
-	if (voltage >= low_thresh)
-		return APM_BATTERY_STATUS_LOW;
-	return APM_BATTERY_STATUS_CRITICAL;
-}
-
-void sharpsl_battery_kick(void)
-{
-	schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125));
-}
-EXPORT_SYMBOL(sharpsl_battery_kick);
-
-
-static void sharpsl_battery_thread(void *private_)
-{
-	int voltage, percent, apm_status, i = 0;
-
-	if (!sharpsl_pm.machinfo)
-		return;
-
-	sharpsl_pm.battstat.ac_status = (STATUS_AC_IN() ? APM_AC_ONLINE : APM_AC_OFFLINE);
-
-	/* Corgi cannot confirm when battery fully charged so periodically kick! */
-	if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON)
-			&& time_after(jiffies, sharpsl_pm.charge_start_time +  SHARPSL_CHARGE_ON_TIME_INTERVAL))
-		schedule_work(&toggle_charger);
-
-	while(1) {
-		voltage = sharpsl_read_main_battery();
-		if (voltage > 0) break;
-		if (i++ > 5) {
-			voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage;
-			dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n");
-			break;
-		}
-	}
-
-	voltage = sharpsl_average_value(voltage);
-	apm_status = get_apm_status(voltage);
-	percent = get_percentage(voltage);
-
-	/* At low battery voltages, the voltage has a tendency to start
-           creeping back up so we try to avoid this here */
-	if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) ||  percent <= sharpsl_pm.battstat.mainbat_percent) {
-		sharpsl_pm.battstat.mainbat_voltage = voltage;
-		sharpsl_pm.battstat.mainbat_status = apm_status;
-		sharpsl_pm.battstat.mainbat_percent = percent;
-	}
-
-	dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage,
-			sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies);
-
-	/* If battery is low. limit backlight intensity to save power. */
-	if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
-			&& ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) ||
-			(sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) {
-		if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) {
-			corgibl_limit_intensity(1);
-			sharpsl_pm.flags |= SHARPSL_BL_LIMIT;
-		}
-	} else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) {
-		corgibl_limit_intensity(0);
-		sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT;
-	}
-
-	/* Suspend if critical battery level */
-	if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE)
-			&& (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL)
-			&& !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) {
-		sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
-		dev_err(sharpsl_pm.dev, "Fatal Off\n");
-		apm_queue_event(APM_CRITICAL_SUSPEND);
-	}
-
-	schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
-}
-
-static void sharpsl_charge_on(void)
-{
-	dev_dbg(sharpsl_pm.dev, "Turning Charger On\n");
-
-	sharpsl_pm.full_count = 0;
-	sharpsl_pm.charge_mode = CHRG_ON;
-	schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250));
-	schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500));
-}
-
-static void sharpsl_charge_off(void)
-{
-	dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n");
-
-	CHARGE_OFF();
-	CHARGE_LED_OFF();
-	sharpsl_pm.charge_mode = CHRG_OFF;
-
-	schedule_work(&sharpsl_bat);
-}
-
-static void sharpsl_charge_error(void)
-{
-	CHARGE_LED_ERR();
-	CHARGE_OFF();
-	sharpsl_pm.charge_mode = CHRG_ERROR;
-}
-
-static void sharpsl_charge_toggle(void *private_)
-{
-	dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies);
-
-	if (STATUS_AC_IN() == 0) {
-		sharpsl_charge_off();
-		return;
-	} else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) {
-		sharpsl_charge_error();
-		return;
-	}
-
-	CHARGE_LED_ON();
-	CHARGE_OFF();
-	mdelay(SHARPSL_CHARGE_WAIT_TIME);
-	CHARGE_ON();
-
-	sharpsl_pm.charge_start_time = jiffies;
-}
-
-static void sharpsl_ac_timer(unsigned long data)
-{
-	int acin = STATUS_AC_IN();
-
-	dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin);
-
-	sharpsl_average_clear();
-	if (acin && (sharpsl_pm.charge_mode != CHRG_ON))
-		sharpsl_charge_on();
-	else if (sharpsl_pm.charge_mode == CHRG_ON)
-		sharpsl_charge_off();
-
-	schedule_work(&sharpsl_bat);
-}
-
-
-static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp)
-{
-	/* Delay the event slightly to debounce */
-	/* Must be a smaller delay than the chrg_full_isr below */
-	mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
-
-	return IRQ_HANDLED;
-}
-
-static void sharpsl_chrg_full_timer(unsigned long data)
-{
-	dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies);
-
-	sharpsl_pm.full_count++;
-
-	if (STATUS_AC_IN() == 0) {
-		dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n");
-		if (sharpsl_pm.charge_mode == CHRG_ON)
-			sharpsl_charge_off();
-	} else if (sharpsl_pm.full_count < 2) {
-		dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n");
-		schedule_work(&toggle_charger);
-	} else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) {
-		dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n");
-		schedule_work(&toggle_charger);
-	} else {
-		sharpsl_charge_off();
-		sharpsl_pm.charge_mode = CHRG_DONE;
-		dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n");
-	}
-}
-
-/* Charging Finished Interrupt (Not present on Corgi) */
-/* Can trigger at the same time as an AC staus change so
-   delay until after that has been processed */
-static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp)
-{
-	if (sharpsl_pm.flags & SHARPSL_SUSPENDED)
-		return IRQ_HANDLED;
-
-	/* delay until after any ac interrupt */
-	mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500));
-
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp)
-{
-	int is_fatal = 0;
-
-	if (STATUS_BATT_LOCKED() == 0) {
-		dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n");
-		is_fatal = 1;
-	}
-
-	if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL() == 0)) {
-		dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n");
-		is_fatal = 1;
-	}
-
-	if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) {
-		sharpsl_pm.flags |= SHARPSL_APM_QUEUED;
-		apm_queue_event(APM_CRITICAL_SUSPEND);
-	}
-
-	return IRQ_HANDLED;
-}
-
-/*
- * Maintain an average of the last 10 readings
- */
-#define SHARPSL_CNV_VALUE_NUM    10
-static int sharpsl_ad_index;
-
-static void sharpsl_average_clear(void)
-{
-	sharpsl_ad_index = 0;
-}
-
-static int sharpsl_average_value(int ad)
-{
-	int i, ad_val = 0;
-	static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
-
-	if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) {
-		sharpsl_ad_index = 0;
-		return ad;
-	}
-
-	sharpsl_ad[sharpsl_ad_index] = ad;
-	sharpsl_ad_index++;
-	if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) {
-		for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++)
-			sharpsl_ad[i] = sharpsl_ad[i+1];
-		sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1;
-	}
-	for (i=0; i < sharpsl_ad_index; i++)
-		ad_val += sharpsl_ad[i];
-
-	return (ad_val / sharpsl_ad_index);
-}
-
-
 /*
  * Read MAX1111 ADC
  */
-static int read_max1111(int channel)
+int sharpsl_pm_pxa_read_max1111(int channel)
 {
 	return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
 			| MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
 }
 
-static int sharpsl_read_main_battery(void)
+void sharpsl_pm_pxa_init(void)
 {
-	return read_max1111(BATT_AD);
-}
-
-static int sharpsl_read_temp(void)
-{
-	int temp;
-
-	sharpsl_pm.machinfo->measure_temp(1);
-
-	mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
-	temp = read_max1111(BATT_THM);
-
-	sharpsl_pm.machinfo->measure_temp(0);
-
-	return temp;
-}
-
-static int sharpsl_read_acin(void)
-{
-	return read_max1111(JK_VAD);
-}
-
-/*
- * Take an array of 5 integers, remove the maximum and minimum values
- * and return the average.
- */
-static int get_select_val(int *val)
-{
-	int i, j, k, temp, sum = 0;
-
-	/* Find MAX val */
-	temp = val[0];
-	j=0;
-	for (i=1; i<5; i++) {
-		if (temp < val[i]) {
-			temp = val[i];
-			j = i;
-		}
-	}
-
-	/* Find MIN val */
-	temp = val[4];
-	k=4;
-	for (i=3; i>=0; i--) {
-		if (temp > val[i]) {
-			temp = val[i];
-			k = i;
-		}
-	}
-
-	for (i=0; i<5; i++)
-		if (i != j && i != k )
-			sum += val[i];
-
-	dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]);
-
-	return (sum/3);
-}
-
-static int sharpsl_check_battery_temp(void)
-{
-	int val, i, buff[5];
-
-	/* Check battery temperature */
-	for (i=0; i<5; i++) {
-		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP);
-		buff[i] = sharpsl_read_temp();
-	}
-
-	val = get_select_val(buff);
-
-	dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val);
-	if (val > SHARPSL_CHARGE_ON_TEMP)
-		return -1;
-
-	return 0;
-}
-
-static int sharpsl_check_battery_voltage(void)
-{
-	int val, i, buff[5];
-
-	/* disable charge, enable discharge */
-	CHARGE_OFF();
-	DISCHARGE_ON();
-	mdelay(SHARPSL_WAIT_DISCHARGE_ON);
-
-	if (sharpsl_pm.machinfo->discharge1)
-		sharpsl_pm.machinfo->discharge1(1);
-
-	/* Check battery voltage */
-	for (i=0; i<5; i++) {
-		buff[i] = sharpsl_read_main_battery();
-		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
-	}
-
-	if (sharpsl_pm.machinfo->discharge1)
-		sharpsl_pm.machinfo->discharge1(0);
-
-	DISCHARGE_OFF();
-
-	val = get_select_val(buff);
-	dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val);
-
-	if (val < SHARPSL_CHARGE_ON_VOLT)
-		return -1;
-
-	return 0;
-}
-
-static int sharpsl_ac_check(void)
-{
-	int temp, i, buff[5];
-
-	for (i=0; i<5; i++) {
-		buff[i] = sharpsl_read_acin();
-		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
-	}
-
-	temp = get_select_val(buff);
-	dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp);
-
-	if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) {
-		dev_err(sharpsl_pm.dev, "Error: AC check failed.\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	sharpsl_pm.flags |= SHARPSL_SUSPENDED;
-	flush_scheduled_work();
-
-	if (sharpsl_pm.charge_mode == CHRG_ON)
-		sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
-	else
-		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
-
-	return 0;
-}
-
-static int sharpsl_pm_resume(struct platform_device *pdev)
-{
-	/* Clear the reset source indicators as they break the bootloader upon reboot */
-	RCSR = 0x0f;
-	sharpsl_average_clear();
-	sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED;
-	sharpsl_pm.flags &= ~SHARPSL_SUSPENDED;
-
-	return 0;
-}
-
-static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
-{
-	dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR);
-
-	dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG);
-	/* not charging and AC-IN! */
-
-	if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN() != 0)) {
-		dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n");
-		sharpsl_pm.charge_mode = CHRG_OFF;
-		sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG;
-		sharpsl_off_charge_battery();
-	}
-
-	sharpsl_pm.machinfo->presuspend();
-
-	PEDR = 0xffffffff; /* clear it */
-
-	sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE;
-	if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) {
-		RTSR &= RTSR_ALE;
-		RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND;
-		dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR);
-		sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE;
-	} else if (alarm_enable) {
-		RTSR &= RTSR_ALE;
-		RTAR = alarm_time;
-		dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR);
-	} else {
-		dev_dbg(sharpsl_pm.dev, "No alarms set.\n");
-	}
-
-	pxa_pm_enter(state);
-
-	sharpsl_pm.machinfo->postsuspend();
-
-	dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR);
-}
-
-static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state)
-{
-	if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) )
-	{
-		if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) {
-			dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n");
-			corgi_goto_sleep(alarm_time, alarm_enable, state);
-			return 1;
-		}
-		if(sharpsl_off_charge_battery()) {
-			dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n");
-			corgi_goto_sleep(alarm_time, alarm_enable, state);
-			return 1;
-		}
-		dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n");
-	}
-
-	if ((STATUS_BATT_LOCKED() == 0) || (sharpsl_fatal_check() < 0) )
-	{
-		dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n");
-		corgi_goto_sleep(alarm_time, alarm_enable, state);
-		return 1;
-	}
-
-	return 0;
-}
-
-static int corgi_pxa_pm_enter(suspend_state_t state)
-{
-	unsigned long alarm_time = RTAR;
-	unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0);
-
-	dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n");
-
-	corgi_goto_sleep(alarm_time, alarm_status, state);
-
-	while (corgi_enter_suspend(alarm_time,alarm_status,state))
-		{}
-
-	dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n");
-
-	return 0;
-}
-#endif
-
-
-/*
- * Check for fatal battery errors
- * Fatal returns -1
- */
-static int sharpsl_fatal_check(void)
-{
-	int buff[5], temp, i, acin;
-
-	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
-
-	/* Check AC-Adapter */
-	acin = STATUS_AC_IN();
-
-	if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
-		CHARGE_OFF();
-		udelay(100);
-		DISCHARGE_ON();	/* enable discharge */
-		mdelay(SHARPSL_WAIT_DISCHARGE_ON);
-	}
-
-	if (sharpsl_pm.machinfo->discharge1)
-		sharpsl_pm.machinfo->discharge1(1);
-
-	/* Check battery : check inserting battery ? */
-	for (i=0; i<5; i++) {
-		buff[i] = sharpsl_read_main_battery();
-		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
-	}
-
-	if (sharpsl_pm.machinfo->discharge1)
-		sharpsl_pm.machinfo->discharge1(0);
-
-	if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) {
-		udelay(100);
-		CHARGE_ON();
-		DISCHARGE_OFF();
-	}
-
-	temp = get_select_val(buff);
-	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_main_battery());
-
-	if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) ||
-			(!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT)))
-		return -1;
-	return 0;
-}
-
-static int sharpsl_off_charge_error(void)
-{
-	dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n");
-	CHARGE_OFF();
-	CHARGE_LED_ERR();
-	sharpsl_pm.charge_mode = CHRG_ERROR;
-	return 1;
-}
-
-/*
- * Charging Control while suspended
- * Return 1 - go straight to sleep
- * Return 0 - sleep or wakeup depending on other factors
- */
-static int sharpsl_off_charge_battery(void)
-{
-	int time;
-
-	dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode);
-
-	if (sharpsl_pm.charge_mode == CHRG_OFF) {
-		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
-
-		/* AC Check */
-		if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
-			return sharpsl_off_charge_error();
-
-		/* Start Charging */
-		CHARGE_LED_ON();
-		CHARGE_OFF();
-		mdelay(SHARPSL_CHARGE_WAIT_TIME);
-		CHARGE_ON();
-
-		sharpsl_pm.charge_mode = CHRG_ON;
-		sharpsl_pm.full_count = 0;
-
-		return 1;
-	} else if (sharpsl_pm.charge_mode != CHRG_ON) {
-		return 1;
-	}
-
-	if (sharpsl_pm.full_count == 0) {
-		int time;
-
-		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
-
-		if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
-			return sharpsl_off_charge_error();
-
-		CHARGE_OFF();
-		mdelay(SHARPSL_CHARGE_WAIT_TIME);
-		CHARGE_ON();
-		sharpsl_pm.charge_mode = CHRG_ON;
-
-		mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
-
-		time = RCNR;
-		while(1) {
-			/* Check if any wakeup event had occured */
-			if (sharpsl_pm.machinfo->charger_wakeup() != 0)
-				return 0;
-			/* Check for timeout */
-			if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
-				return 1;
-			if (STATUS_CHRG_FULL()) {
-				dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n");
-	   			sharpsl_pm.full_count++;
-				CHARGE_OFF();
-				mdelay(SHARPSL_CHARGE_WAIT_TIME);
-				CHARGE_ON();
-				return 1;
-			}
-		}
-	}
-
-	dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n");
-
-	mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
-
-	time = RCNR;
-	while(1) {
-		/* Check if any wakeup event had occured */
-		if (sharpsl_pm.machinfo->charger_wakeup() != 0)
-			return 0;
-		/* Check for timeout */
-		if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) {
-			if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) {
-				dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n");
-				sharpsl_pm.full_count = 0;
-			}
-			sharpsl_pm.full_count++;
-			return 1;
-		}
-		if (STATUS_CHRG_FULL()) {
-			dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n");
-			CHARGE_LED_OFF();
-			CHARGE_OFF();
-			sharpsl_pm.charge_mode = CHRG_DONE;
-			return 1;
-		}
-	}
-}
-
-
-static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent);
-}
-
-static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage);
-}
-
-static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
-static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
-
-extern void (*apm_get_power_status)(struct apm_power_info *);
-
-static void sharpsl_apm_get_power_status(struct apm_power_info *info)
-{
-	info->ac_line_status = sharpsl_pm.battstat.ac_status;
-
-	if (sharpsl_pm.charge_mode == CHRG_ON)
-		info->battery_status = APM_BATTERY_STATUS_CHARGING;
-	else
-		info->battery_status = sharpsl_pm.battstat.mainbat_status;
-
-	info->battery_flag = (1 << info->battery_status);
-	info->battery_life = sharpsl_pm.battstat.mainbat_percent;
-}
-
-static struct pm_ops sharpsl_pm_ops = {
-	.pm_disk_mode	= PM_DISK_FIRMWARE,
-	.prepare	= pxa_pm_prepare,
-	.enter		= corgi_pxa_pm_enter,
-	.finish		= pxa_pm_finish,
-};
-
-static int __init sharpsl_pm_probe(struct platform_device *pdev)
-{
-	if (!pdev->dev.platform_data)
-		return -EINVAL;
-
-	sharpsl_pm.dev = &pdev->dev;
-	sharpsl_pm.machinfo = pdev->dev.platform_data;
-	sharpsl_pm.charge_mode = CHRG_OFF;
-	sharpsl_pm.flags = 0;
-
-	sharpsl_pm.machinfo->init();
-
-	init_timer(&sharpsl_pm.ac_timer);
-	sharpsl_pm.ac_timer.function = sharpsl_ac_timer;
-
-	init_timer(&sharpsl_pm.chrg_full_timer);
-	sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer;
-
 	pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN);
 	pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN);
 	pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN);
@@ -938,26 +164,10 @@
 		}
 		else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING);
 	}
-
-	device_create_file(&pdev->dev, &dev_attr_battery_percentage);
-	device_create_file(&pdev->dev, &dev_attr_battery_voltage);
-
-	apm_get_power_status = sharpsl_apm_get_power_status;
-
-	pm_set_ops(&sharpsl_pm_ops);
-
-	mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250));
-
-	return 0;
 }
 
-static int sharpsl_pm_remove(struct platform_device *pdev)
+void sharpsl_pm_pxa_remove(void)
 {
-	pm_set_ops(NULL);
-
-	device_remove_file(&pdev->dev, &dev_attr_battery_percentage);
-	device_remove_file(&pdev->dev, &dev_attr_battery_voltage);
-
 	free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr);
 	free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr);
 
@@ -966,32 +176,4 @@
 
 	if (!machine_is_corgi())
 		free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr);
-
-	del_timer_sync(&sharpsl_pm.chrg_full_timer);
-	del_timer_sync(&sharpsl_pm.ac_timer);
-
-	return 0;
 }
-
-static struct platform_driver sharpsl_pm_driver = {
-	.probe		= sharpsl_pm_probe,
-	.remove		= sharpsl_pm_remove,
-	.suspend	= sharpsl_pm_suspend,
-	.resume		= sharpsl_pm_resume,
-	.driver		= {
-		.name		= "sharpsl-pm",
-	},
-};
-
-static int __devinit sharpsl_pm_init(void)
-{
-	return platform_driver_register(&sharpsl_pm_driver);
-}
-
-static void sharpsl_pm_exit(void)
-{
- 	platform_driver_unregister(&sharpsl_pm_driver);
-}
-
-late_initcall(sharpsl_pm_init);
-module_exit(sharpsl_pm_exit);
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 2df1b56..a9eacc0 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -36,6 +36,7 @@
 #include <asm/arch/irq.h>
 #include <asm/arch/irda.h>
 #include <asm/arch/mmc.h>
+#include <asm/arch/ohci.h>
 #include <asm/arch/udc.h>
 #include <asm/arch/pxafb.h>
 #include <asm/arch/akita.h>
@@ -126,10 +127,12 @@
 		        cpr &= ~0x0002;
 		if (device == SPITZ_PWR_SD)
 		        cpr &= ~0x0004;
-	        write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
 		if (!(cpr & 0x0002) && !(cpr & 0x0004)) {
+			write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, 0x0000);
 		        mdelay(1);
 		        reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER);
+		} else {
+		        write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr);
 		}
 	}
 }
@@ -293,15 +296,14 @@
 
 	spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250);
 
-	err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, SA_INTERRUPT,
-			     "MMC card detect", data);
+	err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int,
+			  SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+			  "MMC card detect", data);
 	if (err) {
 		printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
 		return -1;
 	}
 
-	set_irq_type(SPITZ_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE);
-
 	return 0;
 }
 
@@ -335,6 +337,35 @@
 
 
 /*
+ * USB Host (OHCI)
+ */
+static int spitz_ohci_init(struct device *dev)
+{
+	/* Only Port 2 is connected */
+	pxa_gpio_mode(SPITZ_GPIO_USB_CONNECT | GPIO_IN);
+	pxa_gpio_mode(SPITZ_GPIO_USB_HOST | GPIO_OUT);
+	pxa_gpio_mode(SPITZ_GPIO_USB_DEVICE | GPIO_IN);
+
+	/* Setup USB Port 2 Output Control Register */
+	UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE;
+
+	GPSR(SPITZ_GPIO_USB_HOST) = GPIO_bit(SPITZ_GPIO_USB_HOST);
+
+	UHCHR = (UHCHR) &
+		~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
+
+	UHCRHDA |= UHCRHDA_NOCP;
+
+	return 0;
+}
+
+static struct pxaohci_platform_data spitz_ohci_platform_data = {
+	.port_mode	= PMM_NPS_MODE,
+	.init		= spitz_ohci_init,
+};
+
+
+/*
  * Irda
  */
 static void spitz_irda_transceiver_mode(struct device *dev, int mode)
@@ -411,6 +442,7 @@
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 	pxa_set_mci_info(&spitz_mci_platform_data);
+	pxa_set_ohci_info(&spitz_ohci_platform_data);
 	pxa_set_ficp_info(&spitz_ficp_platform_data);
 	set_pxa_fb_parent(&spitzssp_device.dev);
 	set_pxa_fb_info(&spitz_pxafb_info);
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 3ce7486..5e5bdc8 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -33,19 +33,7 @@
 {
 	pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN);
 	pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN);
-}
-
-static void spitz_charge_led(int val)
-{
-	if (val == SHARPSL_LED_ERROR) {
-		dev_dbg(sharpsl_pm.dev, "Charge LED Error\n");
-	} else if (val == SHARPSL_LED_ON) {
-		dev_dbg(sharpsl_pm.dev, "Charge LED On\n");
-		set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
-	} else {
-		dev_dbg(sharpsl_pm.dev, "Charge LED Off\n");
-		reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE);
-	}
+	sharpsl_pm_pxa_init();
 }
 
 static void spitz_measure_temp(int on)
@@ -92,7 +80,7 @@
 
 static void spitz_presuspend(void)
 {
-	spitz_last_ac_status = STATUS_AC_IN();
+	spitz_last_ac_status = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
 
 	/* GPIO Sleep Register */
 	PGSR0 = 0x00144018;
@@ -138,7 +126,7 @@
 static int spitz_should_wakeup(unsigned int resume_on_alarm)
 {
 	int is_resume = 0;
-	int acin = STATUS_AC_IN();
+	int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
 
 	if (spitz_last_ac_status != acin) {
 		if (acin) {
@@ -148,8 +136,8 @@
 		} else {
 			/* charge off */
 			dev_dbg(sharpsl_pm.dev, "AC Removed\n");
-			CHARGE_LED_OFF();
-			CHARGE_OFF();
+			sharpsl_pm_led(SHARPSL_LED_OFF);
+			sharpsl_pm.machinfo->charge(0);
 			sharpsl_pm.charge_mode = CHRG_OFF;
 		}
 		spitz_last_ac_status = acin;
@@ -175,25 +163,41 @@
 	return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC));
 }
 
-static int spitz_acin_status(void)
+unsigned long spitzpm_read_devdata(int type)
 {
-	return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0);
+	switch(type) {
+	case SHARPSL_STATUS_ACIN:
+		return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0);
+	case SHARPSL_STATUS_LOCK:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock);
+	case SHARPSL_STATUS_CHRGFULL:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull);
+	case SHARPSL_STATUS_FATAL:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal);
+	case SHARPSL_ACIN_VOLT:
+		return sharpsl_pm_pxa_read_max1111(MAX1111_ACIN_VOLT);
+	case SHARPSL_BATT_TEMP:
+		return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_TEMP);
+	case SHARPSL_BATT_VOLT:
+	default:
+		return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_VOLT);
+	}
 }
 
 struct sharpsl_charger_machinfo spitz_pm_machinfo = {
 	.init             = spitz_charger_init,
+	.exit             = sharpsl_pm_pxa_remove,
 	.gpio_batlock     = SPITZ_GPIO_BAT_COVER,
 	.gpio_acin        = SPITZ_GPIO_AC_IN,
 	.gpio_batfull     = SPITZ_GPIO_CHRG_FULL,
 	.gpio_fatal       = SPITZ_GPIO_FATAL_BAT,
-	.status_acin      = spitz_acin_status,
 	.discharge        = spitz_discharge,
 	.discharge1       = spitz_discharge1,
 	.charge           = spitz_charge,
-	.chargeled        = spitz_charge_led,
 	.measure_temp     = spitz_measure_temp,
 	.presuspend       = spitz_presuspend,
 	.postsuspend      = spitz_postsuspend,
+	.read_devdata     = spitzpm_read_devdata,
 	.charger_wakeup   = spitz_charger_wakeup,
 	.should_wakeup    = spitz_should_wakeup,
 	.bat_levels       = 40,
diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c
index 002635c..ec3f7e7 100644
--- a/arch/arm/mach-realview/clock.c
+++ b/arch/arm/mach-realview/clock.c
@@ -13,9 +13,9 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/semaphore.h>
-#include <asm/hardware/clock.h>
 #include <asm/hardware/icst307.h>
 
 #include "clock.h"
@@ -57,17 +57,6 @@
 }
 EXPORT_SYMBOL(clk_disable);
 
-int clk_use(struct clk *clk)
-{
-	return 0;
-}
-EXPORT_SYMBOL(clk_use);
-
-void clk_unuse(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_unuse);
-
 unsigned long clk_get_rate(struct clk *clk)
 {
 	return clk->rate;
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index e2c6fa2..4a222f5 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -24,15 +24,14 @@
 #include <linux/dma-mapping.h>
 #include <linux/sysdev.h>
 #include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
 
 #include <asm/system.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
-#include <asm/mach-types.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/amba_clcd.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst307.h>
 
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index c06e604..93e86d9 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -22,7 +22,8 @@
 #ifndef __ASM_ARCH_REALVIEW_H
 #define __ASM_ARCH_REALVIEW_H
 
-#include <asm/hardware/amba.h>
+#include <linux/amba/bus.h>
+
 #include <asm/leds.h>
 #include <asm/io.h>
 
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c
index c9d7c59..caf6b8b 100644
--- a/arch/arm/mach-realview/localtimer.c
+++ b/arch/arm/mach-realview/localtimer.c
@@ -13,6 +13,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/smp.h>
+#include <linux/jiffies.h>
 
 #include <asm/mach/time.h>
 #include <asm/hardware/arm_twd.h>
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 7dc3250..112f759 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
+#include <linux/amba/bus.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -30,7 +31,6 @@
 #include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/hardware/gic.h>
-#include <asm/hardware/amba.h>
 #include <asm/hardware/icst307.h>
 
 #include <asm/mach/arch.h>
diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
index bc07474..bd86ffb 100644
--- a/arch/arm/mach-rpc/dma.c
+++ b/arch/arm/mach-rpc/dma.c
@@ -13,7 +13,7 @@
 #include <linux/mman.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/pci.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/page.h>
 #include <asm/dma.h>
@@ -148,11 +148,14 @@
 		 * Cope with ISA-style drivers which expect cache
 		 * coherence.
 		 */
-		if (!dma->using_sg) {
-			dma->buf.dma_address = pci_map_single(NULL,
-				dma->buf.__address, dma->buf.length,
+		if (!dma->sg) {
+			dma->sg = &dma->buf;
+			dma->sgcount = 1;
+			dma->buf.length = dma->count;
+			dma->buf.dma_address = dma_map_single(NULL,
+				dma->addr, dma->count,
 				dma->dma_mode == DMA_MODE_READ ?
-				PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+				DMA_FROM_DEVICE : DMA_TO_DEVICE);
 		}
 
 		iomd_writeb(DMA_CR_C, dma_base + CR);
@@ -239,7 +242,7 @@
 	unsigned int fiqhandler_length;
 	struct pt_regs regs;
 
-	if (dma->using_sg)
+	if (dma->sg)
 		BUG();
 
 	if (dma->dma_mode == DMA_MODE_READ) {
@@ -252,8 +255,8 @@
 		fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start;
 	}
 
-	regs.ARM_r9  = dma->buf.length;
-	regs.ARM_r10 = (unsigned long)dma->buf.__address;
+	regs.ARM_r9  = dma->count;
+	regs.ARM_r10 = (unsigned long)dma->addr;
 	regs.ARM_fp  = (unsigned long)FLOPPYDMA_BASE;
 
 	if (claim_fiq(&fh)) {
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index 82e8253..5830ae3 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -34,16 +34,15 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
-
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
-#include <asm/hardware/clock.h>
 #include <asm/arch/regs-clock.h>
 
 #include "clock.h"
@@ -151,18 +150,6 @@
 }
 
 
-int clk_use(struct clk *clk)
-{
-	atomic_inc(&clk->used);
-	return 0;
-}
-
-
-void clk_unuse(struct clk *clk)
-{
-	atomic_dec(&clk->used);
-}
-
 unsigned long clk_get_rate(struct clk *clk)
 {
 	if (IS_ERR(clk))
@@ -196,8 +183,6 @@
 EXPORT_SYMBOL(clk_put);
 EXPORT_SYMBOL(clk_enable);
 EXPORT_SYMBOL(clk_disable);
-EXPORT_SYMBOL(clk_use);
-EXPORT_SYMBOL(clk_unuse);
 EXPORT_SYMBOL(clk_get_rate);
 EXPORT_SYMBOL(clk_round_rate);
 EXPORT_SYMBOL(clk_set_rate);
@@ -370,7 +355,6 @@
 int s3c24xx_register_clock(struct clk *clk)
 {
 	clk->owner = THIS_MODULE;
-	atomic_set(&clk->used, 0);
 
 	if (clk->enable == NULL)
 		clk->enable = clk_null_enable;
diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h
index 7953b6f..177d5c8 100644
--- a/arch/arm/mach-s3c2410/clock.h
+++ b/arch/arm/mach-s3c2410/clock.h
@@ -16,7 +16,6 @@
 	struct clk           *parent;
 	const char           *name;
 	int		      id;
-	atomic_t              used;
 	unsigned long         rate;
 	unsigned long         ctrlbit;
 	int		    (*enable)(struct clk *, int enable);
diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c
index c67e097..b557a2b 100644
--- a/arch/arm/mach-s3c2410/s3c2440-clock.c
+++ b/arch/arm/mach-s3c2410/s3c2440-clock.c
@@ -29,16 +29,15 @@
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/sysdev.h>
-
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
 #include <asm/atomic.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
-#include <asm/hardware/clock.h>
 #include <asm/arch/regs-clock.h>
 
 #include "clock.h"
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c
index 4d63e71..b7fe6d9 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2410/s3c2440.c
@@ -28,6 +28,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
+#include <linux/clk.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -36,7 +37,6 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/hardware/clock.h>
 
 #include <asm/arch/regs-clock.h>
 #include <asm/arch/regs-serial.h>
diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c
index 8a00e3c..10a2976 100644
--- a/arch/arm/mach-s3c2410/time.c
+++ b/arch/arm/mach-s3c2410/time.c
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/system.h>
 #include <asm/leds.h>
@@ -35,7 +36,6 @@
 #include <asm/arch/regs-timer.h>
 #include <asm/arch/regs-irq.h>
 #include <asm/mach/time.h>
-#include <asm/hardware/clock.h>
 
 #include "clock.h"
 #include "cpu.h"
@@ -191,7 +191,6 @@
 		if (IS_ERR(clk))
 			panic("failed to get clock for system timer");
 
-		clk_use(clk);
 		clk_enable(clk);
 
 		pclk = clk_get_rate(clk);
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index 5098b50..495f8c6 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -84,13 +84,13 @@
 	int ret;
 
 	if (on) {
-		ret = request_irq(IRQ_USBOC, usb_simtec_ocirq, SA_INTERRUPT,
+		ret = request_irq(IRQ_USBOC, usb_simtec_ocirq,
+				  SA_INTERRUPT | SA_TRIGGER_RISING |
+				   SA_TRIGGER_FALLING,
 				  "USB Over-current", info);
 		if (ret != 0) {
 			printk(KERN_ERR "failed to request usb oc irq\n");
 		}
-
-		set_irq_type(IRQ_USBOC, IRQT_BOTHEDGE);
 	} else {
 		free_irq(IRQ_USBOC, info);
 	}
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 59c7964..786c853 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -135,29 +135,11 @@
 }
 
 /*
- * Called after processes are frozen, but before we shut down devices.
- */
-static int sa11x0_pm_prepare(suspend_state_t state)
-{
-	return 0;
-}
-
-/*
- * Called after devices are re-setup, but before processes are thawed.
- */
-static int sa11x0_pm_finish(suspend_state_t state)
-{
-	return 0;
-}
-
-/*
  * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
  */
 static struct pm_ops sa11x0_pm_ops = {
 	.pm_disk_mode	= PM_DISK_FIRMWARE,
-	.prepare	= sa11x0_pm_prepare,
 	.enter		= sa11x0_pm_enter,
-	.finish		= sa11x0_pm_finish,
 };
 
 static int __init sa11x0_pm_init(void)
diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c
index b96a2ea..dcf1001 100644
--- a/arch/arm/mach-versatile/clock.c
+++ b/arch/arm/mach-versatile/clock.c
@@ -14,9 +14,9 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/string.h>
+#include <linux/clk.h>
 
 #include <asm/semaphore.h>
-#include <asm/hardware/clock.h>
 #include <asm/hardware/icst307.h>
 
 #include "clock.h"
@@ -58,17 +58,6 @@
 }
 EXPORT_SYMBOL(clk_disable);
 
-int clk_use(struct clk *clk)
-{
-	return 0;
-}
-EXPORT_SYMBOL(clk_use);
-
-void clk_unuse(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_unuse);
-
 unsigned long clk_get_rate(struct clk *clk)
 {
 	return clk->rate;
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index a1ca466..9002374 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -25,14 +25,14 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/interrupt.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
 
 #include <asm/system.h>
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/leds.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/amba_clcd.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst307.h>
 
diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h
index 588c206..afcaa85 100644
--- a/arch/arm/mach-versatile/core.h
+++ b/arch/arm/mach-versatile/core.h
@@ -22,7 +22,7 @@
 #ifndef __ASM_ARCH_VERSATILE_H
 #define __ASM_ARCH_VERSATILE_H
 
-#include <asm/hardware/amba.h>
+#include <linux/amba/bus.h>
 
 extern void __init versatile_init(void);
 extern void __init versatile_init_irq(void);
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
index 8b0b3be..e74c8a2 100644
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -23,12 +23,12 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/sysdev.h>
+#include <linux/amba/bus.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/amba.h>
 
 #include <asm/mach/arch.h>
 
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index 7c3078c..22d5ca0 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -23,12 +23,12 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/sysdev.h>
+#include <linux/amba/bus.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/amba.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/mmc.h>
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 47b0b76..0513ed1 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -19,7 +19,6 @@
 #include <linux/dma-mapping.h>
 
 #include <asm/cacheflush.h>
-#include <asm/io.h>
 #include <asm/tlbflush.h>
 
 #define CONSISTENT_BASE	(0xffc00000)
@@ -66,6 +65,7 @@
 	unsigned long		vm_start;
 	unsigned long		vm_end;
 	struct page		*vm_pages;
+	int			vm_active;
 };
 
 static struct vm_region consistent_head = {
@@ -104,6 +104,7 @@
 	list_add_tail(&new->vm_list, &c->vm_list);
 	new->vm_start = addr;
 	new->vm_end = addr + size;
+	new->vm_active = 1;
 
 	spin_unlock_irqrestore(&consistent_lock, flags);
 	return new;
@@ -120,7 +121,7 @@
 	struct vm_region *c;
 	
 	list_for_each_entry(c, &head->vm_list, vm_list) {
-		if (c->vm_start == addr)
+		if (c->vm_active && c->vm_start == addr)
 			goto out;
 	}
 	c = NULL;
@@ -319,6 +320,7 @@
 
 /*
  * free a page as defined by the above mapping.
+ * Must not be called with IRQs disabled.
  */
 void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
 {
@@ -326,14 +328,18 @@
 	unsigned long flags, addr;
 	pte_t *ptep;
 
+	WARN_ON(irqs_disabled());
+
 	size = PAGE_ALIGN(size);
 
 	spin_lock_irqsave(&consistent_lock, flags);
-
 	c = vm_region_find(&consistent_head, (unsigned long)cpu_addr);
 	if (!c)
 		goto no_area;
 
+	c->vm_active = 0;
+	spin_unlock_irqrestore(&consistent_lock, flags);
+
 	if ((c->vm_end - c->vm_start) != size) {
 		printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
 		       __func__, c->vm_end - c->vm_start, size);
@@ -372,8 +378,8 @@
 
 	flush_tlb_kernel_range(c->vm_start, c->vm_end);
 
+	spin_lock_irqsave(&consistent_lock, flags);
 	list_del(&c->vm_list);
-
 	spin_unlock_irqrestore(&consistent_lock, flags);
 
 	kfree(c);
diff --git a/arch/arm/mm/discontig.c b/arch/arm/mm/discontig.c
index 0d097bb..1e56021 100644
--- a/arch/arm/mm/discontig.c
+++ b/arch/arm/mm/discontig.c
@@ -9,10 +9,8 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
 #include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/init.h>
+#include <linux/mmzone.h>
 #include <linux/bootmem.h>
 
 #if MAX_NUMNODES != 4 && MAX_NUMNODES != 16
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index c9a0398..330695b 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -155,14 +155,19 @@
  *  space mappings, we can be lazy and remember that we may have dirty
  *  kernel cache lines for later.  Otherwise, we assume we have
  *  aliasing mappings.
+ *
+ * Note that we disable the lazy flush for SMP.
  */
 void flush_dcache_page(struct page *page)
 {
 	struct address_space *mapping = page_mapping(page);
 
+#ifndef CONFIG_SMP
 	if (mapping && !mapping_mapped(mapping))
 		set_bit(PG_dcache_dirty, &page->flags);
-	else {
+	else
+#endif
+	{
 		__flush_dcache_page(mapping, page);
 		if (mapping && cache_is_vivt())
 			__flush_dcache_aliases(mapping, page);
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 9e50127..d0245a3 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -19,7 +19,6 @@
 
 #include <asm/pgalloc.h>
 #include <asm/page.h>
-#include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/tlbflush.h>
 
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 7ce39b9..84fd656 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -19,10 +19,10 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/string.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
 #include <asm/semaphore.h>
-#include <asm/hardware/clock.h>
 
 #include <asm/arch/clock.h>
 
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index ccdb4526..adffc5a 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -18,12 +18,12 @@
 #include <linux/tty.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_reg.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
-#include <asm/hardware/clock.h>
 #include <asm/io.h>
 #include <asm/setup.h>
 
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index fd894bb..98edc9f 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -19,13 +19,12 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
-#include <asm/hardware/clock.h>
-
 /* TODO: Add support for SDRAM timing changes */
 
 int omap_verify_speed(struct cpufreq_policy *policy)
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 76f721d..ca3681a 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -19,9 +19,9 @@
 #include <linux/ptrace.h>
 #include <linux/sysdev.h>
 #include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/clock.h>
 #include <asm/irq.h>
 #include <asm/arch/irqs.h>
 #include <asm/arch/gpio.h>
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index ea9475c..be0e0f3 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -19,6 +19,7 @@
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/delay.h>
 #include <asm/io.h>
@@ -30,8 +31,6 @@
 #include <asm/arch/dsp_common.h>
 #include <asm/arch/mcbsp.h>
 
-#include <asm/hardware/clock.h>
-
 #ifdef CONFIG_MCBSP_DEBUG
 #define DBG(x...)	printk(x)
 #else
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
index b861482..e40fcc8 100644
--- a/arch/arm/plat-omap/ocpi.c
+++ b/arch/arm/plat-omap/ocpi.c
@@ -31,9 +31,9 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/err.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
-#include <asm/hardware/clock.h>
 #include <asm/hardware.h>
 
 #define OCPI_BASE		0xfffec320
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 048c9c1..4654874 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Fri Nov 11 21:55:04 2005
+# Last update: Fri Nov 25 14:43:04 2005
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -857,12 +857,12 @@
 maestro			MACH_MAESTRO		MAESTRO			843
 tunge2			MACH_TUNGE2		TUNGE2			844
 ixbbm			MACH_IXBBM		IXBBM			845
-mx27			MACH_MX27		MX27			846
+mx27ads			MACH_MX27		MX27			846
 ax8004			MACH_AX8004		AX8004			847
 at91sam9261ek		MACH_AT91SAM9261EK	AT91SAM9261EK		848
 loft			MACH_LOFT		LOFT			849
 magpie			MACH_MAGPIE		MAGPIE			850
-mx21			MACH_MX21		MX21			851
+mx21ads			MACH_MX21		MX21			851
 mb87m3400		MACH_MB87M3400		MB87M3400		852
 mguard_delta		MACH_MGUARD_DELTA	MGUARD_DELTA		853
 davinci_dvdp		MACH_DAVINCI_DVDP	DAVINCI_DVDP		854
@@ -897,10 +897,16 @@
 mx21civ			MACH_MX21CIV		MX21CIV			883
 mahi_cdac		MACH_MAHI_CDAC		MAHI_CDAC		884
 xscale_palmtx		MACH_XSCALE_PALMTX	XSCALE_PALMTX		885
-arch_s3c2413		MACH_ARCH_S3C2413	ARCH_S3C2413		886
 s3c2413			MACH_S3C2413		S3C2413			887
 samsys_ep0		MACH_SAMSYS_EP0		SAMSYS_EP0		888
 wg302v1			MACH_WG302V1		WG302V1			889
 wg302v2			MACH_WG302V2		WG302V2			890
 eb42x			MACH_EB42X		EB42X			891
 iq331es			MACH_IQ331ES		IQ331ES			892
+cosydsp			MACH_COSYDSP		COSYDSP			893
+uplat7d			MACH_UPLAT7D		UPLAT7D			894
+ptdavinci		MACH_PTDAVINCI		PTDAVINCI		895
+mbus			MACH_MBUS		MBUS			896
+nadia2vb		MACH_NADIA2VB		NADIA2VB		897
+r1000			MACH_R1000		R1000			898
+hw90250			MACH_HW90250		HW90250			899
diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig
index 1f00b3d..274e070 100644
--- a/arch/arm26/Kconfig
+++ b/arch/arm26/Kconfig
@@ -34,10 +34,6 @@
         int
         default 9
 
-config UID16
-	bool
-	default y
-
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
diff --git a/arch/arm26/kernel/asm-offsets.c b/arch/arm26/kernel/asm-offsets.c
index 4ccacae..ac682d5 100644
--- a/arch/arm26/kernel/asm-offsets.c
+++ b/arch/arm26/kernel/asm-offsets.c
@@ -25,13 +25,6 @@
 #if defined(__APCS_32__) && defined(CONFIG_CPU_26)
 #error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26
 #endif
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)
-#error Sorry, your compiler is known to miscompile kernels.  Only use gcc 2.95.3 and later.
-#endif
-#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
-/* shame we can't detect the .1 or .2 releases */
-#warning GCC 2.95.2 and earlier miscompiles kernels.
-#endif
 
 /* Use marker if you need to separate the values later */
 
diff --git a/arch/arm26/nwfpe/fpmodule.c b/arch/arm26/nwfpe/fpmodule.c
index 528fa71..5258c60 100644
--- a/arch/arm26/nwfpe/fpmodule.c
+++ b/arch/arm26/nwfpe/fpmodule.c
@@ -46,10 +46,9 @@
 
 #ifdef MODULE
 void fp_send_sig(unsigned long sig, PTASK p, int priv);
-#if LINUX_VERSION_CODE > 0x20115
+
 MODULE_AUTHOR("Scott Bambrough <scottb@rebel.com>");
 MODULE_DESCRIPTION("NWFPE floating point emulator");
-#endif
 
 #else
 #define fp_send_sig	send_sig
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index e5979d6..b832619 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -9,10 +9,6 @@
 	bool
 	default y
 
-config UID16
-	bool
-	default y
-
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c
index b72e6a9..34528da 100644
--- a/arch/cris/arch-v10/kernel/kgdb.c
+++ b/arch/cris/arch-v10/kernel/kgdb.c
@@ -569,12 +569,6 @@
 	return x;
 }
 
-int
-double_this(int x)
-{
-        return 2 * x;
-}
-
 /********************************* Register image ****************************/
 /* Copy the content of a register image into another. The size n is
    the size of the register image. Due to struct assignment generation of
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index ec85c0d..61261b7 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -274,6 +274,11 @@
 
 endchoice
 
+config FRV_ONCPU_SERIAL
+	bool "Use on-CPU serial ports"
+	select SERIAL_8250
+	default y
+
 config PCI
 	bool "Use PCI"
 	depends on MB93090_MB00
@@ -305,23 +310,7 @@
 
 source "drivers/pci/Kconfig"
 
-config PCMCIA
-	tristate "Use PCMCIA"
-	help
-	  Say Y here if you want to attach PCMCIA- or PC-cards to your FR-V
-	  board.  These are credit-card size devices such as network cards,
-	  modems or hard drives often used with laptops computers.  There are
-	  actually two varieties of these cards: the older 16 bit PCMCIA cards
-	  and the newer 32 bit CardBus cards.  If you want to use CardBus
-	  cards, you need to say Y here and also to "CardBus support" below.
-
-	  To use your PC-cards, you will need supporting software from David
-	  Hinds pcmcia-cs package (see the file <file:Documentation/Changes>
-	  for location).  Please also read the PCMCIA-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as modules, choose M here: the
-	  modules will be called pcmcia_core and ds.
+source "drivers/pcmcia/Kconfig"
 
 #config MATH_EMULATION
 #	bool "Math emulation support (EXPERIMENTAL)"
diff --git a/arch/frv/Kconfig.debug b/arch/frv/Kconfig.debug
index 0034b65..211f01b 100644
--- a/arch/frv/Kconfig.debug
+++ b/arch/frv/Kconfig.debug
@@ -2,32 +2,10 @@
 
 source "lib/Kconfig.debug"
 
-config EARLY_PRINTK
-	bool "Early printk"
-	depends on EMBEDDED && DEBUG_KERNEL
-	default n
-	help
-	  Write kernel log output directly into the VGA buffer or to a serial
-	  port.
-
-	  This is useful for kernel debugging when your machine crashes very
-	  early before the console code is initialized. For normal operation
-	  it is not recommended because it looks ugly and doesn't cooperate
-	  with klogd/syslogd or the X server. You should normally N here,
-	  unless you want to debug such a crash.
-
 config DEBUG_STACKOVERFLOW
 	bool "Check for stack overflows"
 	depends on DEBUG_KERNEL
 
-config DEBUG_PAGEALLOC
-	bool "Page alloc debugging"
-	depends on DEBUG_KERNEL
-	help
-	  Unmap pages from the kernel linear mapping after free_pages().
-	  This results in a large slowdown, but helps to find certain types
-	  of memory corruptions.
-
 config GDBSTUB
 	bool "Remote GDB kernel debugging"
 	depends on DEBUG_KERNEL
diff --git a/arch/frv/Makefile b/arch/frv/Makefile
index 54046d2..90c0fb8 100644
--- a/arch/frv/Makefile
+++ b/arch/frv/Makefile
@@ -109,10 +109,10 @@
 	$(Q)$(MAKEBOOT) bootstrap
 
 archmrproper:
-	$(Q)$(MAKE) -C arch/frv/boot mrproper
+	$(Q)$(MAKE) $(build)=arch/frv/boot mrproper
 
 archclean:
-	$(Q)$(MAKE) -C arch/frv/boot clean
+	$(Q)$(MAKE) $(build)=arch/frv/boot clean
 
 archdep: scripts/mkdep symlinks
-	$(Q)$(MAKE) -C arch/frv/boot dep
+	$(Q)$(MAKE) $(build)=arch/frv/boot dep
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index 981c2c7..5a827b3 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -20,3 +20,5 @@
 obj-$(CONFIG_PM)		+= pm.o cmode.o
 obj-$(CONFIG_MB93093_PDK)	+= pm-mb93093.o
 obj-$(CONFIG_SYSCTL)		+= sysctl.o
+obj-$(CONFIG_FUTEX)		+= futex.o
+obj-$(CONFIG_MODULES)		+= module.o
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index ad10ea5..5f65483 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -1076,7 +1076,7 @@
 	LEDS		0x6410
 	ori.p		gr4,#0,gr8
 	call		do_notify_resume
-	bra		__entry_return_direct
+	bra		__entry_resume_userspace
 
 	# perform syscall entry tracing
 __syscall_trace_entry:
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
index 1a76d52..5f118c8 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -16,10 +16,11 @@
 #include <asm/semaphore.h>
 #include <asm/checksum.h>
 #include <asm/hardirq.h>
-#include <asm/current.h>
+#include <asm/cacheflush.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
 extern long __memcpy_user(void *dst, const void *src, size_t count);
+extern long __memset_user(void *dst, const void *src, size_t count);
 
 /* platform dependent support */
 
@@ -50,7 +51,11 @@
 EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
 EXPORT_SYMBOL(__page_offset);
 EXPORT_SYMBOL(__memcpy_user);
-EXPORT_SYMBOL(flush_dcache_page);
+EXPORT_SYMBOL(__memset_user);
+EXPORT_SYMBOL(frv_dcache_writeback);
+EXPORT_SYMBOL(frv_cache_invalidate);
+EXPORT_SYMBOL(frv_icache_invalidate);
+EXPORT_SYMBOL(frv_cache_wback_inv);
 
 #ifndef CONFIG_MMU
 EXPORT_SYMBOL(memory_start);
@@ -72,6 +77,9 @@
 EXPORT_SYMBOL(memscan);
 EXPORT_SYMBOL(memmove);
 
+EXPORT_SYMBOL(__outsl_ns);
+EXPORT_SYMBOL(__insl_ns);
+
 EXPORT_SYMBOL(get_wchan);
 
 #ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS
@@ -80,14 +88,13 @@
 EXPORT_SYMBOL(atomic_test_and_XOR_mask);
 EXPORT_SYMBOL(atomic_add_return);
 EXPORT_SYMBOL(atomic_sub_return);
-EXPORT_SYMBOL(__xchg_8);
-EXPORT_SYMBOL(__xchg_16);
 EXPORT_SYMBOL(__xchg_32);
-EXPORT_SYMBOL(__cmpxchg_8);
-EXPORT_SYMBOL(__cmpxchg_16);
 EXPORT_SYMBOL(__cmpxchg_32);
 #endif
 
+EXPORT_SYMBOL(__debug_bug_printk);
+EXPORT_SYMBOL(__delay_loops_MHz);
+
 /*
  * libgcc functions - functions that are used internally by the
  * compiler...  (prototypes are not correct though, but that
@@ -101,6 +108,8 @@
 extern void __lshrdi3(void);
 extern void __moddi3(void);
 extern void __muldi3(void);
+extern void __mulll(void);
+extern void __umulll(void);
 extern void __negdi2(void);
 extern void __ucmpdi2(void);
 extern void __udivdi3(void);
@@ -116,8 +125,10 @@
 EXPORT_SYMBOL(__lshrdi3);
 //EXPORT_SYMBOL(__moddi3);
 EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__mulll);
+EXPORT_SYMBOL(__umulll);
 EXPORT_SYMBOL(__negdi2);
-//EXPORT_SYMBOL(__ucmpdi2);
+EXPORT_SYMBOL(__ucmpdi2);
 //EXPORT_SYMBOL(__udivdi3);
 //EXPORT_SYMBOL(__udivmoddi4);
 //EXPORT_SYMBOL(__umoddi3);
diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c
new file mode 100644
index 0000000..eae874a
--- /dev/null
+++ b/arch/frv/kernel/futex.c
@@ -0,0 +1,242 @@
+/* futex.c: futex operations
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/futex.h>
+#include <asm/futex.h>
+#include <asm/errno.h>
+#include <asm/uaccess.h>
+
+/*
+ * the various futex operations; MMU fault checking is ignored under no-MMU
+ * conditions
+ */
+static inline int atomic_futex_op_xchg_set(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+static inline int atomic_futex_op_xchg_add(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	add		%1,%3,%3		\n"
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+static inline int atomic_futex_op_xchg_or(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	or		%1,%3,%3		\n"
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+static inline int atomic_futex_op_xchg_and(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	and		%1,%3,%3		\n"
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+static inline int atomic_futex_op_xchg_xor(int oparg, int __user *uaddr, int *_oldval)
+{
+	int oldval, ret;
+
+	asm("0:						\n"
+	    "	orcc		gr0,gr0,gr0,icc3	\n"	/* set ICC3.Z */
+	    "	ckeq		icc3,cc7		\n"
+	    "1:	ld.p		%M0,%1			\n"	/* LD.P/ORCR must be atomic */
+	    "	orcr		cc7,cc7,cc3		\n"	/* set CC3 to true */
+	    "	xor		%1,%3,%3		\n"
+	    "2:	cst.p		%3,%M0		,cc3,#1	\n"
+	    "	corcc		gr29,gr29,gr0	,cc3,#1	\n"	/* clear ICC3.Z if store happens */
+	    "	beq		icc3,#0,0b		\n"
+	    "	setlos		0,%2			\n"
+	    "3:						\n"
+	    ".subsection 2				\n"
+	    "4:	setlos		%5,%2			\n"
+	    "	bra		3b			\n"
+	    ".previous					\n"
+	    ".section __ex_table,\"a\"			\n"
+	    "	.balign		8			\n"
+	    "	.long		1b,4b			\n"
+	    "	.long		2b,4b			\n"
+	    ".previous"
+	    : "+U"(*uaddr), "=&r"(oldval), "=&r"(ret), "=r"(oparg)
+	    : "3"(oparg), "i"(-EFAULT)
+	    : "memory", "cc7", "cc3", "icc3"
+	    );
+
+	*_oldval = oldval;
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * do the futex operations
+ */
+int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
+{
+	int op = (encoded_op >> 28) & 7;
+	int cmp = (encoded_op >> 24) & 15;
+	int oparg = (encoded_op << 8) >> 20;
+	int cmparg = (encoded_op << 20) >> 20;
+	int oldval = 0, ret;
+
+	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+		oparg = 1 << oparg;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	inc_preempt_count();
+
+	switch (op) {
+	case FUTEX_OP_SET:
+		ret = atomic_futex_op_xchg_set(oparg, uaddr, &oldval);
+		break;
+	case FUTEX_OP_ADD:
+		ret = atomic_futex_op_xchg_add(oparg, uaddr, &oldval);
+		break;
+	case FUTEX_OP_OR:
+		ret = atomic_futex_op_xchg_or(oparg, uaddr, &oldval);
+		break;
+	case FUTEX_OP_ANDN:
+		ret = atomic_futex_op_xchg_and(~oparg, uaddr, &oldval);
+		break;
+	case FUTEX_OP_XOR:
+		ret = atomic_futex_op_xchg_xor(oparg, uaddr, &oldval);
+		break;
+	default:
+		ret = -ENOSYS;
+		break;
+	}
+
+	dec_preempt_count();
+
+	if (!ret) {
+		switch (cmp) {
+		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+		default: ret = -ENOSYS; break;
+		}
+	}
+
+	return ret;
+
+} /* end futex_atomic_op_inuser() */
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 8c524cd..59580c5 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -32,6 +32,7 @@
 #include <linux/irq.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/module.h>
 
 #include <asm/atomic.h>
 #include <asm/io.h>
@@ -178,6 +179,8 @@
 	spin_unlock_irqrestore(&level->lock, flags);
 }
 
+EXPORT_SYMBOL(disable_irq_nosync);
+
 /**
  *	disable_irq - disable an irq and wait for completion
  *	@irq: Interrupt to disable
@@ -204,6 +207,8 @@
 #endif
 }
 
+EXPORT_SYMBOL(disable_irq);
+
 /**
  *	enable_irq - enable handling of an irq
  *	@irq: Interrupt to enable
@@ -268,6 +273,8 @@
 	spin_unlock_irqrestore(&level->lock, flags);
 }
 
+EXPORT_SYMBOL(enable_irq);
+
 /*****************************************************************************/
 /*
  * handles all normal device IRQ's
@@ -425,6 +432,8 @@
 	return retval;
 }
 
+EXPORT_SYMBOL(request_irq);
+
 /**
  *	free_irq - free an interrupt
  *	@irq: Interrupt line to free
@@ -496,6 +505,8 @@
 	}
 }
 
+EXPORT_SYMBOL(free_irq);
+
 /*
  * IRQ autodetection code..
  *
@@ -519,6 +530,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL(probe_irq_on);
+
 /*
  * Return a mask of triggered interrupts (this
  * can handle only legacy ISA interrupts).
@@ -542,6 +555,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL(probe_irq_mask);
+
 /*
  * Return the one interrupt that triggered (this can
  * handle any interrupt source).
@@ -571,6 +586,8 @@
 	return -1;
 }
 
+EXPORT_SYMBOL(probe_irq_off);
+
 /* this was setup_x86_irq but it seems pretty generic */
 int setup_irq(unsigned int irq, struct irqaction *new)
 {
diff --git a/arch/frv/kernel/module.c b/arch/frv/kernel/module.c
new file mode 100644
index 0000000..850d168
--- /dev/null
+++ b/arch/frv/kernel/module.c
@@ -0,0 +1,80 @@
+/* module.c: FRV specific module loading bits
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ * - Derived from arch/i386/kernel/module.c, Copyright (C) 2001 Rusty Russell.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt...)
+#endif
+
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+
+	return vmalloc_exec(size);
+}
+
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
+/* We don't need anything special. */
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+			      Elf_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *mod)
+{
+	return 0;
+}
+
+int apply_relocate(Elf32_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
+	return -ENOEXEC;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name);
+	return -ENOEXEC;
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+	return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+}
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index 712c3c2..f0b8fff 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -13,6 +13,7 @@
 
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/module.h>
 #include <linux/pm.h>
 #include <linux/pm_legacy.h>
 #include <linux/sched.h>
@@ -27,6 +28,7 @@
 #include "local.h"
 
 void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
 
 extern void frv_change_cmode(int);
 
diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c
index 5cba9c1..7971d68 100644
--- a/arch/frv/kernel/semaphore.c
+++ b/arch/frv/kernel/semaphore.c
@@ -20,7 +20,7 @@
 	struct task_struct	*task;
 };
 
-#if SEM_DEBUG
+#if SEMAPHORE_DEBUG
 void semtrace(struct semaphore *sem, const char *str)
 {
 	if (sem->debug)
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c
index 767ebb5..5908dea 100644
--- a/arch/frv/kernel/setup.c
+++ b/arch/frv/kernel/setup.c
@@ -787,6 +787,7 @@
 #endif
 
 	/* register those serial ports that are available */
+#ifdef CONFIG_FRV_ONCPU_SERIAL
 #ifndef CONFIG_GDBSTUB_UART0
 	__reg(UART0_BASE + UART_IER * 8) = 0;
 	early_serial_setup(&__frv_uart0);
@@ -795,6 +796,7 @@
 	__reg(UART1_BASE + UART_IER * 8) = 0;
 	early_serial_setup(&__frv_uart1);
 #endif
+#endif
 
 #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH)
 	/* we need to initialize the Flashrom device here since we might
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index d4ccc07..5b7146f 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -35,7 +35,7 @@
 	unsigned long	GOT;
 };
 
-asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
+static int do_signal(sigset_t *oldset);
 
 /*
  * Atomically swap in the new signal mask, and wait for a signal.
@@ -55,7 +55,7 @@
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
-		if (do_signal(__frame, &saveset))
+		if (do_signal(&saveset))
 			/* return the signal number as the return value of this function
 			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
 			 *   as entry.S sets regs->gr8 to the return value of the system call
@@ -91,7 +91,7 @@
 	while (1) {
 		current->state = TASK_INTERRUPTIBLE;
 		schedule();
-		if (do_signal(__frame, &saveset))
+		if (do_signal(&saveset))
 			/* return the signal number as the return value of this function
 			 * - this is an utterly evil hack. syscalls should not invoke do_signal()
 			 *   as entry.S sets regs->gr8 to the return value of the system call
@@ -276,13 +276,12 @@
  * Determine which stack to use..
  */
 static inline void __user *get_sigframe(struct k_sigaction *ka,
-					struct pt_regs *regs,
 					size_t frame_size)
 {
 	unsigned long sp;
 
 	/* Default to using normal stack */
-	sp = regs->sp;
+	sp = __frame->sp;
 
 	/* This is the X/Open sanctioned signal stack switching.  */
 	if (ka->sa.sa_flags & SA_ONSTACK) {
@@ -291,18 +290,19 @@
 	}
 
 	return (void __user *) ((sp - frame_size) & ~7UL);
+
 } /* end get_sigframe() */
 
 /*****************************************************************************/
 /*
  *
  */
-static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
+static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
 {
 	struct sigframe __user *frame;
 	int rsig;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, sizeof(*frame));
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
@@ -346,47 +346,51 @@
 	}
 
 	/* set up registers for signal handler */
-	regs->sp   = (unsigned long) frame;
-	regs->lr   = (unsigned long) &frame->retcode;
-	regs->gr8  = sig;
+	__frame->sp   = (unsigned long) frame;
+	__frame->lr   = (unsigned long) &frame->retcode;
+	__frame->gr8  = sig;
 
 	if (get_personality & FDPIC_FUNCPTRS) {
 		struct fdpic_func_descriptor __user *funcptr =
 			(struct fdpic_func_descriptor *) ka->sa.sa_handler;
-		__get_user(regs->pc, &funcptr->text);
-		__get_user(regs->gr15, &funcptr->GOT);
+		__get_user(__frame->pc, &funcptr->text);
+		__get_user(__frame->gr15, &funcptr->GOT);
 	} else {
-		regs->pc   = (unsigned long) ka->sa.sa_handler;
-		regs->gr15 = 0;
+		__frame->pc   = (unsigned long) ka->sa.sa_handler;
+		__frame->gr15 = 0;
 	}
 
 	set_fs(USER_DS);
 
+	/* the tracer may want to single-step inside the handler */
+	if (test_thread_flag(TIF_SINGLESTEP))
+		ptrace_notify(SIGTRAP);
+
 #if DEBUG_SIG
 	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
-		sig, current->comm, current->pid, frame, regs->pc, frame->pretcode);
+	       sig, current->comm, current->pid, frame, __frame->pc,
+	       frame->pretcode);
 #endif
 
-	return;
+	return 1;
 
 give_sigsegv:
-	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
-
 	force_sig(SIGSEGV, current);
+	return 0;
+
 } /* end setup_frame() */
 
 /*****************************************************************************/
 /*
  *
  */
-static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-			   sigset_t *set, struct pt_regs * regs)
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+			  sigset_t *set)
 {
 	struct rt_sigframe __user *frame;
 	int rsig;
 
-	frame = get_sigframe(ka, regs, sizeof(*frame));
+	frame = get_sigframe(ka, sizeof(*frame));
 
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
@@ -409,7 +413,7 @@
 	if (__put_user(0, &frame->uc.uc_flags) ||
 	    __put_user(0, &frame->uc.uc_link) ||
 	    __put_user((void*)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
-	    __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) ||
+	    __put_user(sas_ss_flags(__frame->sp), &frame->uc.uc_stack.ss_flags) ||
 	    __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size))
 		goto give_sigsegv;
 
@@ -440,34 +444,38 @@
 	}
 
 	/* Set up registers for signal handler */
-	regs->sp  = (unsigned long) frame;
-	regs->lr   = (unsigned long) &frame->retcode;
-	regs->gr8 = sig;
-	regs->gr9 = (unsigned long) &frame->info;
+	__frame->sp  = (unsigned long) frame;
+	__frame->lr   = (unsigned long) &frame->retcode;
+	__frame->gr8 = sig;
+	__frame->gr9 = (unsigned long) &frame->info;
 
 	if (get_personality & FDPIC_FUNCPTRS) {
 		struct fdpic_func_descriptor *funcptr =
 			(struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
-		__get_user(regs->pc, &funcptr->text);
-		__get_user(regs->gr15, &funcptr->GOT);
+		__get_user(__frame->pc, &funcptr->text);
+		__get_user(__frame->gr15, &funcptr->GOT);
 	} else {
-		regs->pc   = (unsigned long) ka->sa.sa_handler;
-		regs->gr15 = 0;
+		__frame->pc   = (unsigned long) ka->sa.sa_handler;
+		__frame->gr15 = 0;
 	}
 
 	set_fs(USER_DS);
 
+	/* the tracer may want to single-step inside the handler */
+	if (test_thread_flag(TIF_SINGLESTEP))
+		ptrace_notify(SIGTRAP);
+
 #if DEBUG_SIG
 	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
-		sig, current->comm, current->pid, frame, regs->pc, frame->pretcode);
+	       sig, current->comm, current->pid, frame, __frame->pc,
+	       frame->pretcode);
 #endif
 
-	return;
+	return 1;
 
 give_sigsegv:
-	if (sig == SIGSEGV)
-		ka->sa.sa_handler = SIG_DFL;
 	force_sig(SIGSEGV, current);
+	return 0;
 
 } /* end setup_rt_frame() */
 
@@ -475,43 +483,51 @@
 /*
  * OK, we're invoking a handler
  */
-static void handle_signal(unsigned long sig, siginfo_t *info,
-			  struct k_sigaction *ka, sigset_t *oldset,
-			  struct pt_regs *regs)
+static int handle_signal(unsigned long sig, siginfo_t *info,
+			 struct k_sigaction *ka, sigset_t *oldset)
 {
+	int ret;
+
 	/* Are we from a system call? */
-	if (in_syscall(regs)) {
+	if (in_syscall(__frame)) {
 		/* If so, check system call restarting.. */
-		switch (regs->gr8) {
+		switch (__frame->gr8) {
 		case -ERESTART_RESTARTBLOCK:
 		case -ERESTARTNOHAND:
-			regs->gr8 = -EINTR;
+			__frame->gr8 = -EINTR;
 			break;
 
 		case -ERESTARTSYS:
 			if (!(ka->sa.sa_flags & SA_RESTART)) {
-				regs->gr8 = -EINTR;
+				__frame->gr8 = -EINTR;
 				break;
 			}
+
 			/* fallthrough */
 		case -ERESTARTNOINTR:
-			regs->gr8 = regs->orig_gr8;
-			regs->pc -= 4;
+			__frame->gr8 = __frame->orig_gr8;
+			__frame->pc -= 4;
 		}
 	}
 
 	/* Set up the stack frame */
 	if (ka->sa.sa_flags & SA_SIGINFO)
-		setup_rt_frame(sig, ka, info, oldset, regs);
+		ret = setup_rt_frame(sig, ka, info, oldset);
 	else
-		setup_frame(sig, ka, oldset, regs);
+		ret = setup_frame(sig, ka, oldset);
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
-	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked, sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	if (ret) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked, &current->blocked,
+			  &ka->sa.sa_mask);
+		if (!(ka->sa.sa_flags & SA_NODEFER))
+			sigaddset(&current->blocked, sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+
+	return ret;
+
 } /* end handle_signal() */
 
 /*****************************************************************************/
@@ -520,7 +536,7 @@
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-int do_signal(struct pt_regs *regs, sigset_t *oldset)
+static int do_signal(sigset_t *oldset)
 {
 	struct k_sigaction ka;
 	siginfo_t info;
@@ -532,7 +548,7 @@
 	 * kernel mode. Just return without doing anything
 	 * if so.
 	 */
-	if (!user_mode(regs))
+	if (!user_mode(__frame))
 		return 1;
 
 	if (try_to_freeze())
@@ -541,30 +557,29 @@
 	if (!oldset)
 		oldset = &current->blocked;
 
-	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-	if (signr > 0) {
-		handle_signal(signr, &info, &ka, oldset, regs);
-		return 1;
-	}
+	signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
+	if (signr > 0)
+		return handle_signal(signr, &info, &ka, oldset);
 
- no_signal:
+no_signal:
 	/* Did we come from a system call? */
-	if (regs->syscallno >= 0) {
+	if (__frame->syscallno >= 0) {
 		/* Restart the system call - no handlers present */
-		if (regs->gr8 == -ERESTARTNOHAND ||
-		    regs->gr8 == -ERESTARTSYS ||
-		    regs->gr8 == -ERESTARTNOINTR) {
-			regs->gr8 = regs->orig_gr8;
-			regs->pc -= 4;
+		if (__frame->gr8 == -ERESTARTNOHAND ||
+		    __frame->gr8 == -ERESTARTSYS ||
+		    __frame->gr8 == -ERESTARTNOINTR) {
+			__frame->gr8 = __frame->orig_gr8;
+			__frame->pc -= 4;
 		}
 
-		if (regs->gr8 == -ERESTART_RESTARTBLOCK){
-			regs->gr8 = __NR_restart_syscall;
-			regs->pc -= 4;
+		if (__frame->gr8 == -ERESTART_RESTARTBLOCK){
+			__frame->gr8 = __NR_restart_syscall;
+			__frame->pc -= 4;
 		}
 	}
 
 	return 0;
+
 } /* end do_signal() */
 
 /*****************************************************************************/
@@ -580,6 +595,6 @@
 
 	/* deal with pending signal delivery */
 	if (thread_info_flags & _TIF_SIGPENDING)
-		do_signal(__frame, NULL);
+		do_signal(NULL);
 
 } /* end do_notify_resume() */
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index 2e97412..24cf85f 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -189,6 +189,8 @@
 	tv->tv_usec = usec;
 }
 
+EXPORT_SYMBOL(do_gettimeofday);
+
 int do_settimeofday(struct timespec *tv)
 {
 	time_t wtm_sec, sec = tv->tv_sec;
@@ -218,6 +220,7 @@
 	clock_was_set();
 	return 0;
 }
+
 EXPORT_SYMBOL(do_settimeofday);
 
 /*
diff --git a/arch/frv/kernel/traps.c b/arch/frv/kernel/traps.c
index 89073ca..9eb84b2 100644
--- a/arch/frv/kernel/traps.c
+++ b/arch/frv/kernel/traps.c
@@ -19,6 +19,7 @@
 #include <linux/string.h>
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <linux/module.h>
 
 #include <asm/setup.h>
 #include <asm/fpu.h>
@@ -250,6 +251,8 @@
 	show_stack(NULL, NULL);
 }
 
+EXPORT_SYMBOL(dump_stack);
+
 void show_stack(struct task_struct *task, unsigned long *sp)
 {
 }
diff --git a/arch/frv/kernel/uaccess.c b/arch/frv/kernel/uaccess.c
index f3fd58a..9b751c0 100644
--- a/arch/frv/kernel/uaccess.c
+++ b/arch/frv/kernel/uaccess.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <asm/uaccess.h>
 
 /*****************************************************************************/
@@ -58,8 +59,11 @@
 		memset(p, 0, count); /* clear remainder of buffer [security] */
 
 	return err;
+
 } /* end strncpy_from_user() */
 
+EXPORT_SYMBOL(strncpy_from_user);
+
 /*****************************************************************************/
 /*
  * Return the size of a string (including the ending 0)
@@ -92,4 +96,7 @@
 	}
 
 	return p - src + 1; /* return length including NUL */
+
 } /* end strnlen_user() */
+
+EXPORT_SYMBOL(strnlen_user);
diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S
index fceafd2..f474534 100644
--- a/arch/frv/kernel/vmlinux.lds.S
+++ b/arch/frv/kernel/vmlinux.lds.S
@@ -112,6 +112,7 @@
 #endif
 	)
 	SCHED_TEXT
+	LOCK_TEXT
 	*(.fixup)
 	*(.gnu.warning)
 	*(.exitcall.exit)
diff --git a/arch/frv/lib/Makefile b/arch/frv/lib/Makefile
index 19be262..08be305 100644
--- a/arch/frv/lib/Makefile
+++ b/arch/frv/lib/Makefile
@@ -3,6 +3,6 @@
 #
 
 lib-y := \
-	__ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o \
+	__ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \
 	checksum.o memcpy.o memset.o atomic-ops.o \
 	outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o
diff --git a/arch/frv/lib/__ucmpdi2.S b/arch/frv/lib/__ucmpdi2.S
new file mode 100644
index 0000000..d892f16
--- /dev/null
+++ b/arch/frv/lib/__ucmpdi2.S
@@ -0,0 +1,45 @@
+/* __ucmpdi2.S: 64-bit unsigned compare
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+        .text
+        .p2align	4
+
+###############################################################################
+#
+# int __ucmpdi2(unsigned long long a [GR8:GR9],
+#		unsigned long long b [GR10:GR11])
+#
+# - returns 0, 1, or 2 as a <, =, > b respectively.
+#
+###############################################################################
+        .globl		__ucmpdi2
+        .type		__ucmpdi2,@function
+__ucmpdi2:
+	or.p		gr8,gr0,gr4
+	subcc		gr8,gr10,gr0,icc0
+	setlos.p	#0,gr8
+	bclr		icc0,#2			; a.msw < b.msw
+
+	setlos.p	#2,gr8
+	bhilr		icc0,#0			; a.msw > b.msw
+
+	subcc.p		gr9,gr11,gr0,icc1
+	setlos		#0,gr8
+	setlos.p	#2,gr9
+	setlos		#1,gr7
+	cknc		icc1,cc6
+	cor.p		gr9,gr0,gr8,		cc6,#1
+	cckls		icc1,cc4,		cc6,#1
+	andcr		cc6,cc4,cc4
+	cor		gr7,gr0,gr8,		cc4,#1
+	bralr
+	.size		__ucmpdi2, .-__ucmpdi2
diff --git a/arch/frv/lib/atomic-ops.S b/arch/frv/lib/atomic-ops.S
index b03d510..545cd32 100644
--- a/arch/frv/lib/atomic-ops.S
+++ b/arch/frv/lib/atomic-ops.S
@@ -129,48 +129,6 @@
 
 ###############################################################################
 #
-# uint8_t __xchg_8(uint8_t i, uint8_t *v)
-#
-###############################################################################
-	.globl		__xchg_8
-        .type		__xchg_8,@function
-__xchg_8:
-	or.p		gr8,gr8,gr10
-0:
-	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
-	ckeq		icc3,cc7
-	ldub.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
-	orcr		cc7,cc7,cc3			/* set CC3 to true */
-	cstb.p		gr10,@(gr9,gr0)		,cc3,#1
-	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
-	beq		icc3,#0,0b
-	bralr
-
-	.size		__xchg_8, .-__xchg_8
-
-###############################################################################
-#
-# uint16_t __xchg_16(uint16_t i, uint16_t *v)
-#
-###############################################################################
-	.globl		__xchg_16
-        .type		__xchg_16,@function
-__xchg_16:
-	or.p		gr8,gr8,gr10
-0:
-	orcc		gr0,gr0,gr0,icc3		/* set ICC3.Z */
-	ckeq		icc3,cc7
-	lduh.p		@(gr9,gr0),gr8			/* LD.P/ORCR must be atomic */
-	orcr		cc7,cc7,cc3			/* set CC3 to true */
-	csth.p		gr10,@(gr9,gr0)		,cc3,#1
-	corcc		gr29,gr29,gr0		,cc3,#1	/* clear ICC3.Z if store happens */
-	beq		icc3,#0,0b
-	bralr
-
-	.size		__xchg_16, .-__xchg_16
-
-###############################################################################
-#
 # uint32_t __xchg_32(uint32_t i, uint32_t *v)
 #
 ###############################################################################
@@ -192,56 +150,6 @@
 
 ###############################################################################
 #
-# uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new)
-#
-###############################################################################
-	.globl		__cmpxchg_8
-        .type		__cmpxchg_8,@function
-__cmpxchg_8:
-	or.p		gr8,gr8,gr11
-0:
-	orcc		gr0,gr0,gr0,icc3
-	ckeq		icc3,cc7
-	ldub.p		@(gr11,gr0),gr8
-	orcr		cc7,cc7,cc3
-	sub		gr8,gr9,gr7
-	sllicc		gr7,#24,gr0,icc0
-	bne		icc0,#0,1f
-	cstb.p		gr10,@(gr11,gr0)	,cc3,#1
-	corcc		gr29,gr29,gr0		,cc3,#1
-	beq		icc3,#0,0b
-1:
-	bralr
-
-	.size		__cmpxchg_8, .-__cmpxchg_8
-
-###############################################################################
-#
-# uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new)
-#
-###############################################################################
-	.globl		__cmpxchg_16
-        .type		__cmpxchg_16,@function
-__cmpxchg_16:
-	or.p		gr8,gr8,gr11
-0:
-	orcc		gr0,gr0,gr0,icc3
-	ckeq		icc3,cc7
-	lduh.p		@(gr11,gr0),gr8
-	orcr		cc7,cc7,cc3
-	sub		gr8,gr9,gr7
-	sllicc		gr7,#16,gr0,icc0
-	bne		icc0,#0,1f
-	csth.p		gr10,@(gr11,gr0)	,cc3,#1
-	corcc		gr29,gr29,gr0		,cc3,#1
-	beq		icc3,#0,0b
-1:
-	bralr
-
-	.size		__cmpxchg_16, .-__cmpxchg_16
-
-###############################################################################
-#
 # uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new)
 #
 ###############################################################################
diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c
index 7bf5bd6..20e7dfc 100644
--- a/arch/frv/lib/checksum.c
+++ b/arch/frv/lib/checksum.c
@@ -33,6 +33,7 @@
 
 #include <net/checksum.h>
 #include <asm/checksum.h>
+#include <linux/module.h>
 
 static inline unsigned short from32to16(unsigned long x)
 {
@@ -115,34 +116,52 @@
 	return result;
 }
 
+EXPORT_SYMBOL(csum_partial);
+
 /*
  * this routine is used for miscellaneous IP-like checksums, mainly
  * in icmp.c
  */
 unsigned short ip_compute_csum(const unsigned char * buff, int len)
 {
-	return ~do_csum(buff,len);
+	return ~do_csum(buff, len);
 }
 
+EXPORT_SYMBOL(ip_compute_csum);
+
 /*
  * copy from fs while checksumming, otherwise like csum_partial
  */
-
 unsigned int
-csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err)
+csum_partial_copy_from_user(const char __user *src, char *dst,
+			    int len, int sum, int *csum_err)
 {
-	if (csum_err) *csum_err = 0;
-	memcpy(dst, src, len);
+	int rem;
+
+	if (csum_err)
+		*csum_err = 0;
+
+	rem = copy_from_user(dst, src, len);
+	if (rem != 0) {
+		if (csum_err)
+			*csum_err = -EFAULT;
+		memset(dst + len - rem, 0, rem);
+		len = rem;
+	}
+
 	return csum_partial(dst, len, sum);
 }
 
+EXPORT_SYMBOL(csum_partial_copy_from_user);
+
 /*
  * copy from ds while checksumming, otherwise like csum_partial
  */
-
 unsigned int
 csum_partial_copy(const char *src, char *dst, int len, int sum)
 {
 	memcpy(dst, src, len);
 	return csum_partial(dst, len, sum);
 }
+
+EXPORT_SYMBOL(csum_partial_copy);
diff --git a/arch/frv/mb93090-mb00/Makefile b/arch/frv/mb93090-mb00/Makefile
index 3faf0f8..76595e8 100644
--- a/arch/frv/mb93090-mb00/Makefile
+++ b/arch/frv/mb93090-mb00/Makefile
@@ -3,7 +3,7 @@
 #
 
 ifeq "$(CONFIG_PCI)" "y"
-obj-y := pci-frv.o pci-irq.o pci-vdk.o
+obj-y := pci-frv.o pci-irq.o pci-vdk.o pci-iomap.o
 
 ifeq "$(CONFIG_MMU)" "y"
 obj-y += pci-dma.o
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 2082a96..4985466 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -83,6 +83,8 @@
 	return NULL;
 }
 
+EXPORT_SYMBOL(dma_alloc_coherent);
+
 void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
 {
 	struct dma_alloc_record *rec;
@@ -102,6 +104,8 @@
 	BUG();
 }
 
+EXPORT_SYMBOL(dma_free_coherent);
+
 /*
  * Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
@@ -120,6 +124,8 @@
 	return virt_to_bus(ptr);
 }
 
+EXPORT_SYMBOL(dma_map_single);
+
 /*
  * Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scather-gather version of the
@@ -150,3 +156,5 @@
 
 	return nents;
 }
+
+EXPORT_SYMBOL(dma_map_sg);
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 86fbdad..671ce1e 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -28,11 +28,15 @@
 	return ret;
 }
 
+EXPORT_SYMBOL(dma_alloc_coherent);
+
 void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
 {
 	consistent_free(vaddr);
 }
 
+EXPORT_SYMBOL(dma_free_coherent);
+
 /*
  * Map a single buffer of the indicated size for DMA in streaming mode.
  * The 32-bit bus address to use is returned.
@@ -51,6 +55,8 @@
 	return virt_to_bus(ptr);
 }
 
+EXPORT_SYMBOL(dma_map_single);
+
 /*
  * Map a set of buffers described by scatterlist in streaming
  * mode for DMA.  This is the scather-gather version of the
@@ -96,6 +102,8 @@
 	return nents;
 }
 
+EXPORT_SYMBOL(dma_map_sg);
+
 dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
 			size_t size, enum dma_data_direction direction)
 {
@@ -103,3 +111,5 @@
 	flush_dcache_page(page);
 	return (dma_addr_t) page_to_phys(page) + offset;
 }
+
+EXPORT_SYMBOL(dma_map_page);
diff --git a/arch/frv/mb93090-mb00/pci-iomap.c b/arch/frv/mb93090-mb00/pci-iomap.c
new file mode 100644
index 0000000..068fa04
--- /dev/null
+++ b/arch/frv/mb93090-mb00/pci-iomap.c
@@ -0,0 +1,29 @@
+/* pci-iomap.c: description
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <linux/pci.h>
+#include <linux/module.h>
+
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+	unsigned long start = pci_resource_start(dev, bar);
+	unsigned long len = pci_resource_len(dev, bar);
+	unsigned long flags = pci_resource_flags(dev, bar);
+
+	if (!len || !start)
+		return NULL;
+
+	if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM))
+		return (void __iomem *) start;
+
+	return NULL;
+}
+
+EXPORT_SYMBOL(pci_iomap);
diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c
index af981bd..24622d8 100644
--- a/arch/frv/mb93090-mb00/pci-irq.c
+++ b/arch/frv/mb93090-mb00/pci-irq.c
@@ -60,7 +60,7 @@
 	}
 }
 
-void __init pcibios_penalize_isa_irq(int irq, int active)
+void __init pcibios_penalize_isa_irq(int irq)
 {
 }
 
diff --git a/arch/frv/mm/cache-page.c b/arch/frv/mm/cache-page.c
index 683b5e3..0261cbe 100644
--- a/arch/frv/mm/cache-page.c
+++ b/arch/frv/mm/cache-page.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/highmem.h>
+#include <linux/module.h>
 #include <asm/pgalloc.h>
 
 /*****************************************************************************/
@@ -38,6 +39,8 @@
 
 } /* end flush_dcache_page() */
 
+EXPORT_SYMBOL(flush_dcache_page);
+
 /*****************************************************************************/
 /*
  * ICI takes a virtual address and the page may not currently have one
@@ -64,3 +67,5 @@
 	}
 
 } /* end flush_icache_user_range() */
+
+EXPORT_SYMBOL(flush_icache_user_range);
diff --git a/arch/frv/mm/extable.c b/arch/frv/mm/extable.c
index 41be112..caacf03 100644
--- a/arch/frv/mm/extable.c
+++ b/arch/frv/mm/extable.c
@@ -43,7 +43,7 @@
  */
 unsigned long search_exception_table(unsigned long pc)
 {
-	unsigned long ret = 0;
+	const struct exception_table_entry *extab;
 
 	/* determine if the fault lay during a memcpy_user or a memset_user */
 	if (__frame->lr == (unsigned long) &__memset_user_error_lr &&
@@ -55,9 +55,10 @@
 		 */
 		return (unsigned long) &__memset_user_error_handler;
 	}
-	else if (__frame->lr == (unsigned long) &__memcpy_user_error_lr &&
-		 (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end
-		 ) {
+
+	if (__frame->lr == (unsigned long) &__memcpy_user_error_lr &&
+	    (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end
+	    ) {
 		/* the fault occurred in a protected memset
 		 * - we search for the return address (in LR) instead of the program counter
 		 * - it was probably during a copy_to/from_user()
@@ -65,27 +66,10 @@
 		return (unsigned long) &__memcpy_user_error_handler;
 	}
 
-#ifndef CONFIG_MODULES
-	/* there is only the kernel to search.  */
-	ret = search_one_table(__start___ex_table, __stop___ex_table - 1, pc);
-	return ret;
+	extab = search_exception_tables(pc);
+	if (extab)
+		return extab->fixup;
 
-#else
-	/* the kernel is the last "module" -- no need to treat it special */
-	unsigned long flags;
-	struct module *mp;
+	return 0;
 
-	spin_lock_irqsave(&modlist_lock, flags);
-
-	for (mp = module_list; mp != NULL; mp = mp->next) {
-		if (mp->ex_table_start == NULL || !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING)))
-			continue;
-		ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, pc);
-		if (ret)
-			break;
-	}
-
-	spin_unlock_irqrestore(&modlist_lock, flags);
-	return ret;
-#endif
 } /* end search_exception_table() */
diff --git a/arch/frv/mm/highmem.c b/arch/frv/mm/highmem.c
index 7dc8fbf..7f77db7 100644
--- a/arch/frv/mm/highmem.c
+++ b/arch/frv/mm/highmem.c
@@ -9,6 +9,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 #include <linux/highmem.h>
+#include <linux/module.h>
 
 void *kmap(struct page *page)
 {
@@ -18,6 +19,8 @@
 	return kmap_high(page);
 }
 
+EXPORT_SYMBOL(kmap);
+
 void kunmap(struct page *page)
 {
 	if (in_interrupt())
@@ -27,7 +30,12 @@
 	kunmap_high(page);
 }
 
+EXPORT_SYMBOL(kunmap);
+
 struct page *kmap_atomic_to_page(void *ptr)
 {
 	return virt_to_page(ptr);
 }
+
+
+EXPORT_SYMBOL(kmap_atomic_to_page);
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c
index 7943315..765088ea 100644
--- a/arch/frv/mm/init.c
+++ b/arch/frv/mm/init.c
@@ -108,7 +108,7 @@
 
 	memset((void *) empty_zero_page, 0, PAGE_SIZE);
 
-#if CONFIG_HIGHMEM
+#ifdef CONFIG_HIGHMEM
 	if (num_physpages - num_mappedpages) {
 		pgd_t *pge;
 		pud_t *pue;
diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c
index 2c67dfe..f76dd03 100644
--- a/arch/frv/mm/pgalloc.c
+++ b/arch/frv/mm/pgalloc.c
@@ -85,7 +85,7 @@
 	struct page *page = virt_to_page(pgd);
 	page->index = (unsigned long) pgd_list;
 	if (pgd_list)
-		pgd_list->private = (unsigned long) &page->index;
+		set_page_private(pgd_list, (unsigned long) &page->index);
 	pgd_list = page;
 	set_page_private(page, (unsigned long)&pgd_list);
 }
@@ -94,10 +94,10 @@
 {
 	struct page *next, **pprev, *page = virt_to_page(pgd);
 	next = (struct page *) page->index;
-	pprev = (struct page **)page_private(page);
+	pprev = (struct page **) page_private(page);
 	*pprev = next;
 	if (next)
-		next->private = (unsigned long) pprev;
+		set_page_private(next, (unsigned long) pprev);
 }
 
 void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused)
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 26698a4..80940d7 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -21,10 +21,6 @@
 	bool
 	default n
 
-config UID16
-	bool
-	default y
-
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index 6004bb0..d849c68 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -29,10 +29,6 @@
 config SBUS
 	bool
 
-config UID16
-	bool
-	default y
-
 config GENERIC_ISA_DMA
 	bool
 	default y
@@ -464,7 +460,6 @@
 	depends on SMP && HIGHMEM64G && (X86_NUMAQ || X86_GENERICARCH || (X86_SUMMIT && ACPI))
 	default n if X86_PC
 	default y if (X86_NUMAQ || X86_SUMMIT)
-	select SPARSEMEM_STATIC
 
 # Need comments to help the hapless user trying to turn on NUMA support
 comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support"
@@ -493,6 +488,10 @@
 	depends on NUMA
 	default y
 
+config ARCH_FLATMEM_ENABLE
+	def_bool y
+	depends on (ARCH_SELECT_MEMORY_MODEL && X86_PC)
+
 config ARCH_DISCONTIGMEM_ENABLE
 	def_bool y
 	depends on NUMA
@@ -503,7 +502,8 @@
 
 config ARCH_SPARSEMEM_ENABLE
 	def_bool y
-	depends on NUMA
+	depends on (NUMA || (X86_PC && EXPERIMENTAL))
+	select SPARSEMEM_STATIC
 
 config ARCH_SELECT_MEMORY_MODEL
 	def_bool y
@@ -626,10 +626,6 @@
 	and passes the first three arguments of a function call in registers.
 	This will probably break binary only modules.
 
-	This feature is only enabled for gcc-3.0 and later - earlier compilers
-	generate incorrect output with certain kernel constructs when
-	-mregparm=3 is used.
-
 config SECCOMP
 	bool "Enable seccomp to safely compute untrusted bytecode"
 	depends on PROC_FS
@@ -699,7 +695,7 @@
 
 config APM
 	tristate "APM (Advanced Power Management) BIOS support"
-	depends on PM && PM_LEGACY
+	depends on PM
 	---help---
 	  APM is a BIOS specification for saving power using several different
 	  techniques. This is mostly useful for battery powered laptops with
diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu
index 53bbb3c..79603b3 100644
--- a/arch/i386/Kconfig.cpu
+++ b/arch/i386/Kconfig.cpu
@@ -39,6 +39,7 @@
 	  - "Winchip-2" for IDT Winchip 2.
 	  - "Winchip-2A" for IDT Winchips with 3dNow! capabilities.
 	  - "GeodeGX1" for Geode GX1 (Cyrix MediaGX).
+	  - "Geode GX/LX" For AMD Geode GX and LX processors.
 	  - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
 	  - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above).
 
@@ -171,6 +172,11 @@
 	help
 	  Select this for a Geode GX1 (Cyrix MediaGX) chip.
 
+config MGEODE_LX
+       bool "Geode GX/LX"
+       help
+         Select this for AMD Geode GX and LX processors.
+
 config MCYRIXIII
 	bool "CyrixIII/VIA-C3"
 	help
@@ -220,8 +226,8 @@
 config X86_L1_CACHE_SHIFT
 	int
 	default "7" if MPENTIUM4 || X86_GENERIC
-	default "4" if X86_ELAN || M486 || M386
-	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1
+	default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
+	default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
 	default "6" if MK7 || MK8 || MPENTIUMM
 
 config RWSEM_GENERIC_SPINLOCK
@@ -290,12 +296,12 @@
 
 config X86_USE_PPRO_CHECKSUM
 	bool
-	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON
+	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX
 	default y
 
 config X86_USE_3DNOW
 	bool
-	depends on MCYRIXIII || MK7
+	depends on MCYRIXIII || MK7 || MGEODE_LX
 	default y
 
 config X86_OOSTORE
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug
index c48b424..bf32ecc 100644
--- a/arch/i386/Kconfig.debug
+++ b/arch/i386/Kconfig.debug
@@ -42,6 +42,16 @@
 	  This results in a large slowdown, but helps to find certain types
 	  of memory corruptions.
 
+config DEBUG_RODATA
+	bool "Write protect kernel read-only data structures"
+	depends on DEBUG_KERNEL
+	help
+	  Mark the kernel read-only data as write-protected in the pagetables,
+	  in order to catch accidental (and incorrect) writes to such const
+	  data. This option may have a slight performance impact because a
+	  portion of the kernel code won't be covered by a 2MB TLB anymore.
+	  If in doubt, say "N".
+
 config 4KSTACKS
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
 	depends on DEBUG_KERNEL
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index d121ea1..b84119f 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -37,10 +37,7 @@
 # CPU-specific tuning. Anything which can be shared with UML should go here.
 include $(srctree)/arch/i386/Makefile.cpu
 
-# -mregparm=3 works ok on gcc-3.0 and later
-#
-GCC_VERSION			:= $(call cc-version)
-cflags-$(CONFIG_REGPARM) 	+= $(shell if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;)
+cflags-$(CONFIG_REGPARM) 	+= -mregparm=3
 
 # Disable unit-at-a-time mode, it makes gcc use a lot more stack
 # due to the lack of sharing of stacklots.
diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu
index 8e51456..dcd936e 100644
--- a/arch/i386/Makefile.cpu
+++ b/arch/i386/Makefile.cpu
@@ -1,7 +1,7 @@
 # CPU tuning section - shared with UML.
 # Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML.
 
-#-mtune exists since gcc 3.4, and some -mcpu flavors didn't exist in gcc 2.95.
+#-mtune exists since gcc 3.4
 HAS_MTUNE	:= $(call cc-option-yn, -mtune=i386)
 ifeq ($(HAS_MTUNE),y)
 tune		= $(call cc-option,-mtune=$(1),)
@@ -14,7 +14,7 @@
 cflags-$(CONFIG_M486)		+= -march=i486
 cflags-$(CONFIG_M586)		+= -march=i586
 cflags-$(CONFIG_M586TSC)	+= -march=i586
-cflags-$(CONFIG_M586MMX)	+= $(call cc-option,-march=pentium-mmx,-march=i586)
+cflags-$(CONFIG_M586MMX)	+= -march=pentium-mmx
 cflags-$(CONFIG_M686)		+= -march=i686
 cflags-$(CONFIG_MPENTIUMII)	+= -march=i686 $(call tune,pentium2)
 cflags-$(CONFIG_MPENTIUMIII)	+= -march=i686 $(call tune,pentium3)
@@ -23,8 +23,8 @@
 cflags-$(CONFIG_MK6)		+= -march=k6
 # Please note, that patches that add -march=athlon-xp and friends are pointless.
 # They make zero difference whatsosever to performance at this time.
-cflags-$(CONFIG_MK7)		+= $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)
-cflags-$(CONFIG_MK8)		+= $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4))
+cflags-$(CONFIG_MK7)		+= -march=athlon
+cflags-$(CONFIG_MK8)		+= $(call cc-option,-march=k8,-march=athlon)
 cflags-$(CONFIG_MCRUSOE)	+= -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
 cflags-$(CONFIG_MEFFICEON)	+= -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
 cflags-$(CONFIG_MWINCHIPC6)	+= $(call cc-option,-march=winchip-c6,-march=i586)
@@ -37,5 +37,5 @@
 cflags-$(CONFIG_X86_ELAN)	+= -march=i486
 
 # Geode GX1 support
-cflags-$(CONFIG_MGEODEGX1)		+= $(call cc-option,-march=pentium-mmx,-march=i486)
+cflags-$(CONFIG_MGEODEGX1)	+= -march=pentium-mmx
 
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
index 82a807f..f19f3a7 100644
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -11,7 +11,7 @@
 
 #include <linux/linkage.h>
 #include <linux/vmalloc.h>
-#include <linux/tty.h>
+#include <linux/screen_info.h>
 #include <asm/io.h>
 #include <asm/page.h>
 
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index f10de0f..be1880b 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -4,10 +4,10 @@
 
 extra-y := head.o init_task.o vmlinux.lds
 
-obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
+obj-y	:= process.o semaphore.o signal.o entry.o traps.o irq.o \
 		ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \
 		pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \
-		doublefault.o quirks.o i8237.o
+		quirks.o i8237.o
 
 obj-y				+= cpu/
 obj-y				+= timers/
@@ -33,6 +33,8 @@
 obj-$(CONFIG_ACPI_SRAT) 	+= srat.o
 obj-$(CONFIG_HPET_TIMER) 	+= time_hpet.o
 obj-$(CONFIG_EFI) 		+= efi.o efi_stub.o
+obj-$(CONFIG_DOUBLEFAULT) 	+= doublefault.o
+obj-$(CONFIG_VM86)		+= vm86.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 EXTRA_AFLAGS   := -traditional
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index 76b1135..447fa9e 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -638,6 +638,13 @@
 			return 0;
 
 		pmtmr_ioport = fadt->xpm_tmr_blk.address;
+		/*
+		 * "X" fields are optional extensions to the original V1.0
+		 * fields, so we must selectively expand V1.0 fields if the
+		 * corresponding X field is zero.
+	 	 */
+		if (!pmtmr_ioport)
+			pmtmr_ioport = fadt->V1_pm_tmr_blk;
 	} else {
 		/* FADT rev. 1 */
 		pmtmr_ioport = fadt->V1_pm_tmr_blk;
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 496a2c9..d8f94e7 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -721,7 +721,7 @@
 		apic_verbosity = APIC_VERBOSE;
 	else
 		printk(KERN_WARNING "APIC Verbosity level %s not recognised"
-				" use apic=verbose or apic=debug", str);
+				" use apic=verbose or apic=debug\n", str);
 
 	return 0;
 }
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index 1e60acb..9d88271 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -303,17 +303,6 @@
 #include "apm.h"
 
 /*
- * Define to make all _set_limit calls use 64k limits.  The APM 1.1 BIOS is
- * supposed to provide limit information that it recognizes.  Many machines
- * do this correctly, but many others do not restrict themselves to their
- * claimed limit.  When this happens, they will cause a segmentation
- * violation in the kernel at boot time.  Most BIOS's, however, will
- * respect a 64k limit, so we use that.  If you want to be pedantic and
- * hold your BIOS to its claims, then undefine this.
- */
-#define APM_RELAX_SEGMENTS
-
-/*
  * Define to re-initialize the interrupt 0 timer to 100 Hz after a suspend.
  * This patched by Chad Miller <cmiller@surfsouth.com>, original code by
  * David Chen <chen@ctpa04.mit.edu>
@@ -1075,22 +1064,23 @@
  
 static int apm_console_blank(int blank)
 {
-	int	error;
-	u_short	state;
+	int error, i;
+	u_short state;
+	static const u_short dev[3] = { 0x100, 0x1FF, 0x101 };
 
 	state = blank ? APM_STATE_STANDBY : APM_STATE_READY;
-	/* Blank the first display device */
-	error = set_power_state(0x100, state);
-	if ((error != APM_SUCCESS) && (error != APM_NO_ERROR)) {
-		/* try to blank them all instead */
-		error = set_power_state(0x1ff, state);
-		if ((error != APM_SUCCESS) && (error != APM_NO_ERROR))
-			/* try to blank device one instead */
-			error = set_power_state(0x101, state);
+
+	for (i = 0; i < ARRAY_SIZE(dev); i++) {
+		error = set_power_state(dev[i], state);
+
+		if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
+			return 1;
+
+		if (error == APM_NOT_ENGAGED)
+			break;
 	}
-	if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
-		return 1;
-	if (error == APM_NOT_ENGAGED) {
+
+	if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) {
 		static int tried;
 		int eng_error;
 		if (tried++ == 0) {
@@ -2233,8 +2223,8 @@
 static int __init apm_init(void)
 {
 	struct proc_dir_entry *apm_proc;
+	struct desc_struct *gdt;
 	int ret;
-	int i;
 
 	dmi_check_system(apm_dmi_table);
 
@@ -2301,7 +2291,9 @@
 		apm_info.disabled = 1;
 		return -ENODEV;
 	}
+#ifdef CONFIG_PM_LEGACY
 	pm_active = 1;
+#endif
 
 	/*
 	 * Set up a segment that references the real mode segment 0x40
@@ -2312,45 +2304,30 @@
 	set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
 	_set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
 
+	/*
+	 * Set up the long jump entry point to the APM BIOS, which is called
+	 * from inline assembly.
+	 */
 	apm_bios_entry.offset = apm_info.bios.offset;
 	apm_bios_entry.segment = APM_CS;
 
-	for (i = 0; i < NR_CPUS; i++) {
-		struct desc_struct *gdt = get_cpu_gdt_table(i);
-		set_base(gdt[APM_CS >> 3],
-			 __va((unsigned long)apm_info.bios.cseg << 4));
-		set_base(gdt[APM_CS_16 >> 3],
-			 __va((unsigned long)apm_info.bios.cseg_16 << 4));
-		set_base(gdt[APM_DS >> 3],
-			 __va((unsigned long)apm_info.bios.dseg << 4));
-#ifndef APM_RELAX_SEGMENTS
-		if (apm_info.bios.version == 0x100) {
-#endif
-			/* For ASUS motherboard, Award BIOS rev 110 (and others?) */
-			_set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 - 1);
-			/* For some unknown machine. */
-			_set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1);
-			/* For the DEC Hinote Ultra CT475 (and others?) */
-			_set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1);
-#ifndef APM_RELAX_SEGMENTS
-		} else {
-			_set_limit((char *)&gdt[APM_CS >> 3],
-				(apm_info.bios.cseg_len - 1) & 0xffff);
-			_set_limit((char *)&gdt[APM_CS_16 >> 3],
-				(apm_info.bios.cseg_16_len - 1) & 0xffff);
-			_set_limit((char *)&gdt[APM_DS >> 3],
-				(apm_info.bios.dseg_len - 1) & 0xffff);
-		      /* workaround for broken BIOSes */
-	                if (apm_info.bios.cseg_len <= apm_info.bios.offset)
-        	                _set_limit((char *)&gdt[APM_CS >> 3], 64 * 1024 -1);
-                       if (apm_info.bios.dseg_len <= 0x40) { /* 0x40 * 4kB == 64kB */
-                        	/* for the BIOS that assumes granularity = 1 */
-                        	gdt[APM_DS >> 3].b |= 0x800000;
-                        	printk(KERN_NOTICE "apm: we set the granularity of dseg.\n");
-        	        }
-		}
-#endif
-	}
+	/*
+	 * The APM 1.1 BIOS is supposed to provide limit information that it
+	 * recognizes.  Many machines do this correctly, but many others do
+	 * not restrict themselves to their claimed limit.  When this happens,
+	 * they will cause a segmentation violation in the kernel at boot time.
+	 * Most BIOS's, however, will respect a 64k limit, so we use that.
+	 *
+	 * Note we only set APM segments on CPU zero, since we pin the APM
+	 * code to that CPU.
+	 */
+	gdt = get_cpu_gdt_table(0);
+	set_base(gdt[APM_CS >> 3],
+		 __va((unsigned long)apm_info.bios.cseg << 4));
+	set_base(gdt[APM_CS_16 >> 3],
+		 __va((unsigned long)apm_info.bios.cseg_16 << 4));
+	set_base(gdt[APM_DS >> 3],
+		 __va((unsigned long)apm_info.bios.dseg << 4));
 
 	apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info);
 	if (apm_proc)
@@ -2407,7 +2384,9 @@
 	exit_kapmd = 1;
 	while (kapmd_running)
 		schedule();
+#ifdef CONFIG_PM_LEGACY
 	pm_active = 0;
+#endif
 }
 
 module_init(apm_init);
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index e344ef88..e7697e0 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -161,8 +161,13 @@
 					set_bit(X86_FEATURE_K6_MTRR, c->x86_capability);
 				break;
 			}
-			break;
 
+			if (c->x86_model == 10) {
+				/* AMD Geode LX is model 10 */
+				/* placeholder for any needed mods */
+				break;
+			}
+			break;
 		case 6: /* An Athlon/Duron */
  
 			/* Bit 15 of Athlon specific MSR 15, needs to be 0
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index 31e344b..1704008 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -18,9 +18,6 @@
 
 #include "cpu.h"
 
-DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
-EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);
-
 DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
 EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
 
@@ -599,11 +596,6 @@
 	load_idt(&idt_descr);
 
 	/*
-	 * Delete NT
-	 */
-	__asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
-
-	/*
 	 * Set up and load the per-CPU TSS and LDT
 	 */
 	atomic_inc(&init_mm.mm_count);
@@ -617,8 +609,10 @@
 	load_TR_desc();
 	load_LDT(&init_mm.context);
 
+#ifdef CONFIG_DOUBLEFAULT
 	/* Set up doublefault TSS pointer in the GDT */
 	__set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss);
+#endif
 
 	/* Clear %fs and %gs. */
 	asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
index 04a4053..2b62dee 100644
--- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
+++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
@@ -177,9 +177,10 @@
  */
 static int nforce2_set_fsb(unsigned int fsb)
 {
-	u32 pll, temp = 0;
+	u32 temp = 0;
 	unsigned int tfsb;
 	int diff;
+	int pll = 0;
 
 	if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
 		printk(KERN_ERR "cpufreq: FSB %d is out of range!\n", fsb);
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index 68a1fc8..0fbbd4c 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -45,7 +45,7 @@
 
 #define PFX "powernow-k8: "
 #define BFX PFX "BIOS error: "
-#define VERSION "version 1.50.4"
+#define VERSION "version 1.60.0"
 #include "powernow-k8.h"
 
 /* serialize freq changes  */
@@ -216,10 +216,10 @@
 
 	do {
 		wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
-                if (i++ > 100) {
-                        printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
-                        return 1;
-                }
+		if (i++ > 100) {
+			printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n");
+			return 1;
+		}
 	} while (query_current_values_with_pending_wait(data));
 
 	if (savefid != data->currfid) {
@@ -336,7 +336,7 @@
 /* Phase 2 - core frequency transition */
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
 {
-	u32 vcoreqfid, vcocurrfid, vcofiddiff, savevid = data->currvid;
+	u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid;
 
 	if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
 		printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n",
@@ -359,9 +359,11 @@
 	    : vcoreqfid - vcocurrfid;
 
 	while (vcofiddiff > 2) {
+		(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
+
 		if (reqfid > data->currfid) {
 			if (data->currfid > LO_FID_TABLE_TOP) {
-				if (write_new_fid(data, data->currfid + 2)) {
+				if (write_new_fid(data, data->currfid + fid_interval)) {
 					return 1;
 				}
 			} else {
@@ -371,7 +373,7 @@
 				}
 			}
 		} else {
-			if (write_new_fid(data, data->currfid - 2))
+			if (write_new_fid(data, data->currfid - fid_interval))
 				return 1;
 		}
 
@@ -464,7 +466,7 @@
 	set_cpus_allowed(current, cpumask_of_cpu(cpu));
 
 	if (smp_processor_id() != cpu) {
-		printk(KERN_ERR "limiting to cpu %u failed\n", cpu);
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", cpu);
 		goto out;
 	}
 
@@ -474,7 +476,7 @@
 	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
 	if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
 	    ((eax & CPUID_XFAM) != CPUID_XFAM_K8) ||
-	    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_F)) {
+	    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) {
 		printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
 		goto out;
 	}
@@ -517,22 +519,24 @@
 			printk(KERN_ERR BFX "maxvid exceeded with pstate %d\n", j);
 			return -ENODEV;
 		}
-		if ((pst[j].fid > MAX_FID)
-		    || (pst[j].fid & 1)
-		    || (j && (pst[j].fid < HI_FID_TABLE_BOTTOM))) {
+		if (pst[j].fid > MAX_FID) {
+			printk(KERN_ERR BFX "maxfid exceeded with pstate %d\n", j);
+			return -ENODEV;
+		}
+		if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
 			/* Only first fid is allowed to be in "low" range */
-			printk(KERN_ERR PFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
+			printk(KERN_ERR BFX "two low fids - %d : 0x%x\n", j, pst[j].fid);
 			return -EINVAL;
 		}
 		if (pst[j].fid < lastfid)
 			lastfid = pst[j].fid;
 	}
 	if (lastfid & 1) {
-		printk(KERN_ERR PFX "lastfid invalid\n");
+		printk(KERN_ERR BFX "lastfid invalid\n");
 		return -EINVAL;
 	}
 	if (lastfid > LO_FID_TABLE_TOP)
-		printk(KERN_INFO PFX  "first fid not from lo freq table\n");
+		printk(KERN_INFO BFX  "first fid not from lo freq table\n");
 
 	return 0;
 }
@@ -631,7 +635,7 @@
 
 		dprintk("table vers: 0x%x\n", psb->tableversion);
 		if (psb->tableversion != PSB_VERSION_1_4) {
-			printk(KERN_INFO BFX "PSB table is not v1.4\n");
+			printk(KERN_ERR BFX "PSB table is not v1.4\n");
 			return -ENODEV;
 		}
 
@@ -689,7 +693,7 @@
 	 * BIOS and Kernel Developer's Guide, which is available on
 	 * www.amd.com
 	 */
-	printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n");
+	printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n");
 	return -ENODEV;
 }
 
@@ -912,7 +916,7 @@
 	set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 
 	if (smp_processor_id() != pol->cpu) {
-		printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
 		goto err_out;
 	}
 
@@ -982,6 +986,9 @@
 	cpumask_t oldmask = CPU_MASK_ALL;
 	int rc, i;
 
+	if (!cpu_online(pol->cpu))
+		return -ENODEV;
+
 	if (!check_supported_cpu(pol->cpu))
 		return -ENODEV;
 
@@ -1021,7 +1028,7 @@
 	set_cpus_allowed(current, cpumask_of_cpu(pol->cpu));
 
 	if (smp_processor_id() != pol->cpu) {
-		printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu);
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
 		goto err_out;
 	}
 
@@ -1162,10 +1169,9 @@
 	cpufreq_unregister_driver(&cpufreq_amd64_driver);
 }
 
-MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com.");
+MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>");
 MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
 MODULE_LICENSE("GPL");
 
 late_initcall(powernowk8_init);
 module_exit(powernowk8_exit);
-
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
index b1e85bb..d0de37d 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
@@ -42,7 +42,7 @@
 #define CPUID_XFAM			0x0ff00000	/* extended family */
 #define CPUID_XFAM_K8			0
 #define CPUID_XMOD			0x000f0000	/* extended model */
-#define CPUID_XMOD_REV_F		0x00040000
+#define CPUID_XMOD_REV_G		0x00060000
 #define CPUID_USE_XFAM_XMOD		0x00000f00
 #define CPUID_GET_MAX_CAPABILITIES	0x80000000
 #define CPUID_FREQ_VOLT_CAPABILITIES	0x80000007
@@ -86,13 +86,14 @@
  *   low fid table
  * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry
  *   in the low fid table
- * - the parts can only step at 200 MHz intervals, so 1.9 GHz is never valid
+ * - the parts can only step at <= 200 MHz intervals, odd fid values are
+ *   supported in revision G and later revisions.
  * - lowest frequency must be >= interprocessor hypertransport link speed
  *   (only applies to MP systems obviously)
  */
 
 /* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
-#define LO_FID_TABLE_TOP     6	/* fid values marking the boundary    */
+#define LO_FID_TABLE_TOP     7	/* fid values marking the boundary    */
 #define HI_FID_TABLE_BOTTOM  8	/* between the low and high tables    */
 
 #define LO_VCOFREQ_TABLE_TOP    1400	/* corresponding vco frequency values */
@@ -106,7 +107,7 @@
 #define MIN_FREQ 800	/* Min and max freqs, per spec */
 #define MAX_FREQ 5000
 
-#define INVALID_FID_MASK 0xffffffc1  /* not a valid fid if these bits are set */
+#define INVALID_FID_MASK 0xffffffc0  /* not a valid fid if these bits are set */
 #define INVALID_VID_MASK 0xffffffc0  /* not a valid vid if these bits are set */
 
 #define VID_OFF 0x3f
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
index 5b7d18a..b425cd3d1 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
@@ -40,6 +40,7 @@
  */
 static unsigned int speedstep_processor = 0;
 
+static u32 pmbase;
 
 /*
  *   There are only two frequency states for each processor. Values
@@ -56,6 +57,33 @@
 
 
 /**
+ * speedstep_find_register - read the PMBASE address
+ *
+ * Returns: -ENODEV if no register could be found
+ */
+static int speedstep_find_register (void)
+{
+	if (!speedstep_chipset_dev)
+		return -ENODEV;
+
+	/* get PMBASE */
+	pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
+	if (!(pmbase & 0x01)) {
+		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
+		return -ENODEV;
+	}
+
+	pmbase &= 0xFFFFFFFE;
+	if (!pmbase) {
+		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
+		return -ENODEV;
+	}
+
+	dprintk("pmbase is 0x%x\n", pmbase);
+	return 0;
+}
+
+/**
  * speedstep_set_state - set the SpeedStep state
  * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
  *
@@ -63,27 +91,13 @@
  */
 static void speedstep_set_state (unsigned int state)
 {
-	u32 pmbase;
 	u8 pm2_blk;
 	u8 value;
 	unsigned long flags;
 
-	if (!speedstep_chipset_dev || (state > 0x1))
+	if (state > 0x1)
 		return;
 
-	/* get PMBASE */
-	pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
-	if (!(pmbase & 0x01)) {
-		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-		return;
-	}
-
-	pmbase &= 0xFFFFFFFE;
-	if (!pmbase) {
-		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-		return;
-	}
-
 	/* Disable IRQs */
 	local_irq_save(flags);
 
@@ -315,10 +329,11 @@
 	cpus_allowed = current->cpus_allowed;
 	set_cpus_allowed(current, policy->cpus);
 
-	/* detect low and high frequency */
+	/* detect low and high frequency and transition latency */
 	result = speedstep_get_freqs(speedstep_processor,
 				     &speedstep_freqs[SPEEDSTEP_LOW].frequency,
 				     &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+				     &policy->cpuinfo.transition_latency,
 				     &speedstep_set_state);
 	set_cpus_allowed(current, cpus_allowed);
 	if (result)
@@ -335,7 +350,6 @@
 
 	/* cpuinfo and default policy values */
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
 	policy->cur = speed;
 
 	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
@@ -400,6 +414,9 @@
 		return -EINVAL;
 	}
 
+	if (speedstep_find_register())
+		return -ENODEV;
+
 	return cpufreq_register_driver(&speedstep_driver);
 }
 
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
index d368b3f..7c47005 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
@@ -320,11 +320,13 @@
 unsigned int speedstep_get_freqs(unsigned int processor,
 				  unsigned int *low_speed,
 				  unsigned int *high_speed,
+				  unsigned int *transition_latency,
 				  void (*set_state) (unsigned int state))
 {
 	unsigned int prev_speed;
 	unsigned int ret = 0;
 	unsigned long flags;
+	struct timeval tv1, tv2;
 
 	if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
 		return -EINVAL;
@@ -337,7 +339,7 @@
 		return -EIO;
 
 	dprintk("previous speed is %u\n", prev_speed);
-	
+
 	local_irq_save(flags);
 
 	/* switch to low state */
@@ -350,8 +352,17 @@
 
 	dprintk("low speed is %u\n", *low_speed);
 
+	/* start latency measurement */
+	if (transition_latency)
+		do_gettimeofday(&tv1);
+
 	/* switch to high state */
 	set_state(SPEEDSTEP_HIGH);
+
+	/* end latency measurement */
+	if (transition_latency)
+		do_gettimeofday(&tv2);
+
 	*high_speed = speedstep_get_processor_frequency(processor);
 	if (!*high_speed) {
 		ret = -EIO;
@@ -369,6 +380,25 @@
 	if (*high_speed != prev_speed)
 		set_state(SPEEDSTEP_LOW);
 
+	if (transition_latency) {
+		*transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
+			tv2.tv_usec - tv1.tv_usec;
+		dprintk("transition latency is %u uSec\n", *transition_latency);
+
+		/* convert uSec to nSec and add 20% for safety reasons */
+		*transition_latency *= 1200;
+
+		/* check if the latency measurement is too high or too low
+		 * and set it to a safe value (500uSec) in that case
+		 */
+		if (*transition_latency > 10000000 || *transition_latency < 50000) {
+			printk (KERN_WARNING "speedstep: frequency transition measured seems out of "
+					"range (%u nSec), falling back to a safe one of %u nSec.\n",
+					*transition_latency, 500000);
+			*transition_latency = 500000;
+		}
+	}
+
  out:
 	local_irq_restore(flags);
 	return (ret);
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
index 261a2c9..6a727fd 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
@@ -44,4 +44,5 @@
 extern unsigned int speedstep_get_freqs(unsigned int processor,
 	  unsigned int *low_speed,
 	  unsigned int *high_speed,
+	  unsigned int *transition_latency,
 	  void (*set_state) (unsigned int state));
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
index 2718fb6..28cc5d5 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
@@ -269,6 +269,7 @@
 		result = speedstep_get_freqs(speedstep_processor,
 				&speedstep_freqs[SPEEDSTEP_LOW].frequency,
 				&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+				NULL,
 				&speedstep_set_state);
 
 		if (result) {
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c
index ff87cc2..7501597 100644
--- a/arch/i386/kernel/cpu/cyrix.c
+++ b/arch/i386/kernel/cpu/cyrix.c
@@ -343,6 +343,31 @@
 }
 
 /*
+ * Handle National Semiconductor branded processors
+ */
+static void __devinit init_nsc(struct cpuinfo_x86 *c)
+{
+	/* There may be GX1 processors in the wild that are branded
+	 * NSC and not Cyrix.
+	 *
+	 * This function only handles the GX processor, and kicks every
+	 * thing else to the Cyrix init function above - that should
+	 * cover any processors that might have been branded differently
+	 * after NSC aquired Cyrix.
+	 *
+	 * If this breaks your GX1 horribly, please e-mail
+	 * info-linux@ldcmail.amd.com to tell us.
+	 */
+
+	/* Handle the GX (Formally known as the GX2) */
+
+	if (c->x86 == 5 && c->x86_model == 5)
+		display_cacheinfo(c);
+	else
+		init_cyrix(c);
+}
+
+/*
  * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected
  * by the fact that they preserve the flags across the division of 5/2.
  * PII and PPro exhibit this behavior too, but they have cpuid available.
@@ -422,7 +447,7 @@
 static struct cpu_dev nsc_cpu_dev __initdata = {
 	.c_vendor	= "NSC",
 	.c_ident 	= { "Geode by NSC" },
-	.c_init		= init_cyrix,
+	.c_init		= init_nsc,
 	.c_identify	= generic_identify,
 };
 
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index e792131..6d91b27 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -3,6 +3,7 @@
 #include <linux/string.h>
 #include <asm/semaphore.h>
 #include <linux/seq_file.h>
+#include <linux/cpufreq.h>
 
 /*
  *	Get CPU information for use by the procfs.
@@ -86,8 +87,11 @@
 		seq_printf(m, "stepping\t: unknown\n");
 
 	if ( cpu_has(c, X86_FEATURE_TSC) ) {
+		unsigned int freq = cpufreq_quick_get(n);
+		if (!freq)
+			freq = cpu_khz;
 		seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
-			cpu_khz / 1000, (cpu_khz % 1000));
+			freq / 1000, (freq % 1000));
 	}
 
 	/* Cache size */
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 13bae79..006141d 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -117,14 +117,13 @@
 {
 	char __user *tmp = buf;
 	u32 data[4];
-	size_t rv;
 	u32 reg = *ppos;
 	int cpu = iminor(file->f_dentry->d_inode);
 
 	if (count % 16)
 		return -EINVAL;	/* Invalid chunk size */
 
-	for (rv = 0; count; count -= 16) {
+	for (; count; count -= 16) {
 		do_cpuid(cpu, reg, data);
 		if (copy_to_user(tmp, &data, 16))
 			return -EFAULT;
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index e50b9315..4d70472 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -323,6 +323,7 @@
 
 	ALIGN
 work_notifysig_v86:
+#ifdef CONFIG_VM86
 	pushl %ecx			# save ti_flags for do_notify_resume
 	call save_v86_state		# %eax contains pt_regs pointer
 	popl %ecx
@@ -330,6 +331,7 @@
 	xorl %edx, %edx
 	call do_notify_resume
 	jmp resume_userspace
+#endif
 
 	# perform syscall exit tracing
 	ALIGN
@@ -657,6 +659,7 @@
 	pushl $do_spurious_interrupt_bug
 	jmp error_code
 
+.section .rodata,"a"
 #include "syscall_table.S"
 
 syscall_table_size=(.-sys_call_table)
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index e437fb3..5884469 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -504,19 +504,24 @@
 	.quad 0x0000000000000000	/* 0x80 TSS descriptor */
 	.quad 0x0000000000000000	/* 0x88 LDT descriptor */
 
-	/* Segments used for calling PnP BIOS */
-	.quad 0x00c09a0000000000	/* 0x90 32-bit code */
-	.quad 0x00809a0000000000	/* 0x98 16-bit code */
-	.quad 0x0080920000000000	/* 0xa0 16-bit data */
-	.quad 0x0080920000000000	/* 0xa8 16-bit data */
-	.quad 0x0080920000000000	/* 0xb0 16-bit data */
+	/*
+	 * Segments used for calling PnP BIOS have byte granularity.
+	 * They code segments and data segments have fixed 64k limits,
+	 * the transfer segment sizes are set at run time.
+	 */
+	.quad 0x00409a000000ffff	/* 0x90 32-bit code */
+	.quad 0x00009a000000ffff	/* 0x98 16-bit code */
+	.quad 0x000092000000ffff	/* 0xa0 16-bit data */
+	.quad 0x0000920000000000	/* 0xa8 16-bit data */
+	.quad 0x0000920000000000	/* 0xb0 16-bit data */
+
 	/*
 	 * The APM segments have byte granularity and their bases
-	 * and limits are set at run time.
+	 * are set at run time.  All have 64k limits.
 	 */
-	.quad 0x00409a0000000000	/* 0xb8 APM CS    code */
-	.quad 0x00009a0000000000	/* 0xc0 APM CS 16 code (16 bit) */
-	.quad 0x0040920000000000	/* 0xc8 APM DS    data */
+	.quad 0x00409a000000ffff	/* 0xb8 APM CS    code */
+	.quad 0x00009a000000ffff	/* 0xc0 APM CS 16 code (16 bit) */
+	.quad 0x004092000000ffff	/* 0xc8 APM DS    data */
 
 	.quad 0x0000920000000000	/* 0xd0 - ESPFIX 16-bit SS */
 	.quad 0x0000000000000000	/* 0xd8 - unused */
@@ -525,3 +530,5 @@
 	.quad 0x0000000000000000	/* 0xf0 - unused */
 	.quad 0x0000000000000000	/* 0xf8 - GDT entry 31: double-fault TSS */
 
+	/* Be sure this is zeroed to avoid false validations in Xen */
+	.fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 180f070..3999bec 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -3,8 +3,7 @@
 #include <asm/checksum.h>
 #include <asm/desc.h>
 
-/* This is definitely a GPL-only symbol */
-EXPORT_SYMBOL_GPL(cpu_gdt_table);
+EXPORT_SYMBOL_GPL(cpu_gdt_descr);
 
 EXPORT_SYMBOL(__down_failed);
 EXPORT_SYMBOL(__down_failed_interruptible);
diff --git a/arch/i386/kernel/init_task.c b/arch/i386/kernel/init_task.c
index 9caa8e8..cff95d1 100644
--- a/arch/i386/kernel/init_task.c
+++ b/arch/i386/kernel/init_task.c
@@ -42,5 +42,5 @@
  * per-CPU TSS segments. Threads are completely 'soft' on Linux,
  * no more per-task TSS's.
  */ 
-DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = INIT_TSS;
+DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
 
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index cc5d7ac..7554f8f 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -1722,8 +1722,8 @@
 		entry.dest_mode       = 0; /* Physical */
 		entry.delivery_mode   = dest_ExtINT; /* ExtInt */
 		entry.vector          = 0;
-		entry.dest.physical.physical_dest = 0;
-
+		entry.dest.physical.physical_dest =
+					GET_APIC_ID(apic_read(APIC_ID));
 
 		/*
 		 * Add it to the IO-APIC irq-routing table:
@@ -2009,7 +2009,7 @@
 {
 	int irq = vector_to_irq(vector);
 
-	move_irq(vector);
+	move_native_irq(vector);
 	ack_edge_ioapic_irq(irq);
 }
 
@@ -2024,7 +2024,7 @@
 {
 	int irq = vector_to_irq(vector);
 
-	move_irq(vector);
+	move_native_irq(vector);
 	end_level_ioapic_irq(irq);
 }
 
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 1a201a93..f3a9c78 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -19,7 +19,7 @@
 #include <linux/cpu.h>
 #include <linux/delay.h>
 
-DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp;
+DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp;
 EXPORT_PER_CPU_SYMBOL(irq_stat);
 
 #ifndef CONFIG_X86_LOCAL_APIC
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index 32b0c24..19edcd5 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -191,7 +191,7 @@
 			 */
 			save_previous_kprobe(kcb);
 			set_current_kprobe(p, regs, kcb);
-			p->nmissed++;
+			kprobes_inc_nmissed_count(p);
 			prepare_singlestep(p, regs);
 			kcb->kprobe_status = KPROBE_REENTER;
 			return 1;
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 1ca5269b1..91a6401 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -38,6 +38,12 @@
 int smp_found_config;
 unsigned int __initdata maxcpus = NR_CPUS;
 
+#ifdef CONFIG_HOTPLUG_CPU
+#define CPU_HOTPLUG_ENABLED	(1)
+#else
+#define CPU_HOTPLUG_ENABLED	(0)
+#endif
+
 /*
  * Various Linux-internal data structures created from the
  * MP-table.
@@ -219,14 +225,18 @@
 	cpu_set(num_processors, cpu_possible_map);
 	num_processors++;
 
-	if ((num_processors > 8) &&
-	    ((APIC_XAPIC(ver) &&
-	     (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)) ||
-	     (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)))
-		def_to_bigsmp = 1;
-	else
-		def_to_bigsmp = 0;
-
+	if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) {
+		switch (boot_cpu_data.x86_vendor) {
+		case X86_VENDOR_INTEL:
+			if (!APIC_XAPIC(ver)) {
+				def_to_bigsmp = 0;
+				break;
+			}
+			/* If P4 and above fall through */
+		case X86_VENDOR_AMD:
+			def_to_bigsmp = 1;
+		}
+	}
 	bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
 }
 
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 44470fe..1d0a55e 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -172,7 +172,6 @@
 {
 	u32 __user *tmp = (u32 __user *) buf;
 	u32 data[2];
-	size_t rv;
 	u32 reg = *ppos;
 	int cpu = iminor(file->f_dentry->d_inode);
 	int err;
@@ -180,7 +179,7 @@
 	if (count % 8)
 		return -EINVAL;	/* Invalid chunk size */
 
-	for (rv = 0; count; count -= 8) {
+	for (; count; count -= 8) {
 		err = do_rdmsr(cpu, reg, &data[0], &data[1]);
 		if (err)
 			return err;
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index df6c2bc..035928f 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -48,6 +48,7 @@
 #include <asm/processor.h>
 #include <asm/i387.h>
 #include <asm/desc.h>
+#include <asm/vm86.h>
 #ifdef CONFIG_MATH_EMULATION
 #include <asm/math_emu.h>
 #endif
@@ -308,9 +309,7 @@
 	cr0 = read_cr0();
 	cr2 = read_cr2();
 	cr3 = read_cr3();
-	if (current_cpu_data.x86 > 4) {
-		cr4 = read_cr4();
-	}
+	cr4 = read_cr4_safe();
 	printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
 	show_trace(NULL, &regs->esp);
 }
@@ -404,17 +403,7 @@
 
 void release_thread(struct task_struct *dead_task)
 {
-	if (dead_task->mm) {
-		// temporary debugging check
-		if (dead_task->mm->context.size) {
-			printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
-					dead_task->comm,
-					dead_task->mm->context.ldt,
-					dead_task->mm->context.size);
-			BUG();
-		}
-	}
-
+	BUG_ON(dead_task->mm);
 	release_vm86_irqs(dead_task);
 }
 
@@ -554,7 +543,9 @@
 	struct pt_regs ptregs;
 	
 	ptregs = *(struct pt_regs *)
-		((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs));
+		((unsigned long)tsk->thread_info +
+		/* see comments in copy_thread() about -8 */
+		THREAD_SIZE - sizeof(ptregs) - 8);
 	ptregs.xcs &= 0xffff;
 	ptregs.xds &= 0xffff;
 	ptregs.xes &= 0xffff;
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 5ffbb4b..5c1fb6a 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -32,9 +32,12 @@
  * in exit.c or in signal.c.
  */
 
-/* determines which flags the user has access to. */
-/* 1 = access 0 = no access */
-#define FLAG_MASK 0x00044dd5
+/*
+ * Determines which flags the user has access to [1 = access, 0 = no access].
+ * Prohibits changing ID(21), VIP(20), VIF(19), VM(17), IOPL(12-13), IF(9).
+ * Also masks reserved bits (31-22, 15, 5, 3, 1).
+ */
+#define FLAG_MASK 0x00054dd5
 
 /* set's the trap flag. */
 #define TRAP_FLAG 0x100
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c
index 350ea66..2fa5803 100644
--- a/arch/i386/kernel/reboot.c
+++ b/arch/i386/kernel/reboot.c
@@ -111,6 +111,14 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
 		},
 	},
+	{	/* Handle problems with rebooting on HP laptops */
+		.callback = set_bios_reboot,
+		.ident = "HP Compaq Laptop",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
+		},
+	},
 	{ }
 };
 
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index fdfcb0c..27c956d 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -954,6 +954,12 @@
 	return 0;
 }
 
+static int __init
+efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg)
+{
+	memory_present(0, start, end);
+	return 0;
+}
 
 /*
  * Find the highest page frame number we have available
@@ -965,6 +971,7 @@
 	max_pfn = 0;
 	if (efi_enabled) {
 		efi_memmap_walk(efi_find_max_pfn, &max_pfn);
+		efi_memmap_walk(efi_memory_present_wrapper, NULL);
 		return;
 	}
 
@@ -979,6 +986,7 @@
 			continue;
 		if (end > max_pfn)
 			max_pfn = end;
+		memory_present(0, start, end);
 	}
 }
 
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index d16520d..b3c2e2c 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -903,6 +903,12 @@
 	unsigned long start_eip;
 	unsigned short nmi_high = 0, nmi_low = 0;
 
+	if (!cpu_gdt_descr[cpu].address &&
+	    !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
+		printk("Failed to allocate GDT for CPU %d\n", cpu);
+		return 1;
+	}
+
 	++cpucount;
 
 	/*
@@ -1338,8 +1344,7 @@
 	if (cpu == 0)
 		return -EBUSY;
 
-	/* We enable the timer again on the exit path of the death loop */
-	disable_APIC_timer();
+	clear_local_APIC();
 	/* Allow any queued timer interrupts to get serviced */
 	local_irq_enable();
 	mdelay(1);
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S
index 9b21a31..6ff3e52 100644
--- a/arch/i386/kernel/syscall_table.S
+++ b/arch/i386/kernel/syscall_table.S
@@ -1,4 +1,3 @@
-.data
 ENTRY(sys_call_table)
 	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
 	.long sys_exit
@@ -294,3 +293,4 @@
 	.long sys_inotify_init
 	.long sys_inotify_add_watch
 	.long sys_inotify_rm_watch
+	.long sys_migrate_pages
diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c
index 9caeaa3..a529f0c 100644
--- a/arch/i386/kernel/time_hpet.c
+++ b/arch/i386/kernel/time_hpet.c
@@ -259,8 +259,6 @@
 #include <linux/mc146818rtc.h>
 #include <linux/rtc.h>
 
-extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
 #define DEFAULT_RTC_INT_FREQ 	64
 #define RTC_NUM_INTS 		1
 
diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
index d395e3b..47675bb 100644
--- a/arch/i386/kernel/timers/timer_tsc.c
+++ b/arch/i386/kernel/timers/timer_tsc.c
@@ -330,7 +330,9 @@
 	unsigned int cpu_khz_old = cpu_khz;
 
 	if (cpu_has_tsc) {
+		local_irq_disable();
 		init_cpu_khz();
+		local_irq_enable();
 		cpu_data[0].loops_per_jiffy =
 		    cpufreq_scale(cpu_data[0].loops_per_jiffy,
 			          cpu_khz_old,
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index c34d1bf..53ad954e 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -306,14 +306,17 @@
 		.lock_owner_depth =	0
 	};
 	static int die_counter;
+	unsigned long flags;
 
 	if (die.lock_owner != raw_smp_processor_id()) {
 		console_verbose();
-		spin_lock_irq(&die.lock);
+		spin_lock_irqsave(&die.lock, flags);
 		die.lock_owner = smp_processor_id();
 		die.lock_owner_depth = 0;
 		bust_spinlocks(1);
 	}
+	else
+		local_save_flags(flags);
 
 	if (++die.lock_owner_depth < 3) {
 		int nl = 0;
@@ -340,7 +343,7 @@
 
 	bust_spinlocks(0);
 	die.lock_owner = -1;
-	spin_unlock_irq(&die.lock);
+	spin_unlock_irqrestore(&die.lock, flags);
 
 	if (kexec_should_crash(current))
 		crash_kexec(regs);
@@ -452,7 +455,7 @@
 #endif
 DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
 DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
-DO_ERROR_INFO( 6, SIGILL,  "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
+DO_ERROR_INFO( 6, SIGILL,  "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip)
 DO_ERROR( 9, SIGFPE,  "coprocessor segment overrun", coprocessor_segment_overrun)
 DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
@@ -650,13 +653,6 @@
 
 	cpu = smp_processor_id();
 
-#ifdef CONFIG_HOTPLUG_CPU
-	if (!cpu_online(cpu)) {
-		nmi_exit();
-		return;
-	}
-#endif
-
 	++nmi_count(cpu);
 
 	if (!rcu_dereference(nmi_callback)(regs, cpu))
@@ -1082,9 +1078,9 @@
 	set_trap_gate(0,&divide_error);
 	set_intr_gate(1,&debug);
 	set_intr_gate(2,&nmi);
-	set_system_intr_gate(3, &int3); /* int3-5 can be called from all */
+	set_system_intr_gate(3, &int3); /* int3/4 can be called from all */
 	set_system_gate(4,&overflow);
-	set_system_gate(5,&bounds);
+	set_trap_gate(5,&bounds);
 	set_trap_gate(6,&invalid_op);
 	set_trap_gate(7,&device_not_available);
 	set_task_gate(8,GDT_ENTRY_DOUBLEFAULT_TSS);
@@ -1102,6 +1098,28 @@
 #endif
 	set_trap_gate(19,&simd_coprocessor_error);
 
+	if (cpu_has_fxsr) {
+		/*
+		 * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
+		 * Generates a compile-time "error: zero width for bit-field" if
+		 * the alignment is wrong.
+		 */
+		struct fxsrAlignAssert {
+			int _:!(offsetof(struct task_struct,
+					thread.i387.fxsave) & 15);
+		};
+
+		printk(KERN_INFO "Enabling fast FPU save and restore... ");
+		set_in_cr4(X86_CR4_OSFXSR);
+		printk("done.\n");
+	}
+	if (cpu_has_xmm) {
+		printk(KERN_INFO "Enabling unmasked SIMD FPU exception "
+				"support... ");
+		set_in_cr4(X86_CR4_OSXMMEXCPT);
+		printk("done.\n");
+	}
+
 	set_system_gate(SYSCALL_VECTOR,&system_call);
 
 	/*
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 06e26f0..7df494b 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -735,6 +735,30 @@
 	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (__init_end - __init_begin) >> 10);
 }
 
+#ifdef CONFIG_DEBUG_RODATA
+
+extern char __start_rodata, __end_rodata;
+void mark_rodata_ro(void)
+{
+	unsigned long addr = (unsigned long)&__start_rodata;
+
+	for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
+		change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO);
+
+	printk ("Write protecting the kernel read-only data: %luk\n",
+			(unsigned long)(&__end_rodata - &__start_rodata) >> 10);
+
+	/*
+	 * change_page_attr() requires a global_flush_tlb() call after it.
+	 * We do this after the printk so that if something went wrong in the
+	 * change, the printk gets out at least to give a better debug hint
+	 * of who is the culprit.
+	 */
+	global_flush_tlb();
+}
+#endif
+
+
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index 5d09de8..247fde7 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -223,9 +223,15 @@
 }
 EXPORT_SYMBOL(ioremap_nocache);
 
+/**
+ * iounmap - Free a IO remapping
+ * @addr: virtual address from ioremap_*
+ *
+ * Caller must ensure there is only one unmapping for the same pointer.
+ */
 void iounmap(volatile void __iomem *addr)
 {
-	struct vm_struct *p;
+	struct vm_struct *p, *o;
 
 	if ((void __force *)addr <= high_memory)
 		return;
@@ -239,22 +245,37 @@
 			addr < phys_to_virt(ISA_END_ADDRESS))
 		return;
 
-	write_lock(&vmlist_lock);
-	p = __remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr));
-	if (!p) { 
-		printk(KERN_WARNING "iounmap: bad address %p\n", addr);
+	addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr);
+
+	/* Use the vm area unlocked, assuming the caller
+	   ensures there isn't another iounmap for the same address
+	   in parallel. Reuse of the virtual address is prevented by
+	   leaving it in the global lists until we're done with it.
+	   cpa takes care of the direct mappings. */
+	read_lock(&vmlist_lock);
+	for (p = vmlist; p; p = p->next) {
+		if (p->addr == addr)
+			break;
+	}
+	read_unlock(&vmlist_lock);
+
+	if (!p) {
+		printk("iounmap: bad address %p\n", addr);
 		dump_stack();
-		goto out_unlock;
+		return;
 	}
 
+	/* Reset the direct mapping. Can block */
 	if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
 		change_page_attr(virt_to_page(__va(p->phys_addr)),
 				 p->size >> PAGE_SHIFT,
 				 PAGE_KERNEL);
 		global_flush_tlb();
 	} 
-out_unlock:
-	write_unlock(&vmlist_lock);
+
+	/* Finally remove it */
+	o = remove_vm_area((void *)addr);
+	BUG_ON(p != o || o == NULL);
 	kfree(p); 
 }
 EXPORT_SYMBOL(iounmap);
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c
index f600fc2..c30a16d 100644
--- a/arch/i386/mm/pageattr.c
+++ b/arch/i386/mm/pageattr.c
@@ -13,6 +13,7 @@
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
 #include <asm/pgalloc.h>
+#include <asm/sections.h>
 
 static DEFINE_SPINLOCK(cpa_lock);
 static struct list_head df_list = LIST_HEAD_INIT(df_list);
@@ -36,7 +37,8 @@
         return pte_offset_kernel(pmd, address);
 } 
 
-static struct page *split_large_page(unsigned long address, pgprot_t prot)
+static struct page *split_large_page(unsigned long address, pgprot_t prot,
+					pgprot_t ref_prot)
 { 
 	int i; 
 	unsigned long addr;
@@ -54,7 +56,7 @@
 	pbase = (pte_t *)page_address(base);
 	for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
                set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT,
-                                          addr == address ? prot : PAGE_KERNEL));
+                                          addr == address ? prot : ref_prot));
 	}
 	return base;
 } 
@@ -98,11 +100,18 @@
  */
 static inline void revert_page(struct page *kpte_page, unsigned long address)
 {
-	pte_t *linear = (pte_t *) 
+	pgprot_t ref_prot;
+	pte_t *linear;
+
+	ref_prot =
+	((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
+		? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
+
+	linear = (pte_t *)
 		pmd_offset(pud_offset(pgd_offset_k(address), address), address);
 	set_pmd_pte(linear,  address,
 		    pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
-			    PAGE_KERNEL_LARGE));
+			    ref_prot));
 }
 
 static int
@@ -123,10 +132,16 @@
 		if ((pte_val(*kpte) & _PAGE_PSE) == 0) { 
 			set_pte_atomic(kpte, mk_pte(page, prot)); 
 		} else {
-			struct page *split = split_large_page(address, prot); 
+			pgprot_t ref_prot;
+			struct page *split;
+
+			ref_prot =
+			((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
+				? PAGE_KERNEL_EXEC : PAGE_KERNEL;
+			split = split_large_page(address, prot, ref_prot);
 			if (!split)
 				return -ENOMEM;
-			set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
+			set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
 			kpte_page = split;
 		}	
 		get_page(kpte_page);
diff --git a/arch/i386/pci/Makefile b/arch/i386/pci/Makefile
index ead6122..5461d4d 100644
--- a/arch/i386/pci/Makefile
+++ b/arch/i386/pci/Makefile
@@ -1,7 +1,7 @@
 obj-y				:= i386.o
 
 obj-$(CONFIG_PCI_BIOS)		+= pcbios.o
-obj-$(CONFIG_PCI_MMCONFIG)	+= mmconfig.o
+obj-$(CONFIG_PCI_MMCONFIG)	+= mmconfig.o direct.o
 obj-$(CONFIG_PCI_DIRECT)	+= direct.o
 
 pci-y				:= fixup.o
diff --git a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c
index 94331d6..e3ac502 100644
--- a/arch/i386/pci/direct.c
+++ b/arch/i386/pci/direct.c
@@ -13,7 +13,7 @@
 #define PCI_CONF1_ADDRESS(bus, devfn, reg) \
 	(0x80000000 | (bus << 16) | (devfn << 8) | (reg & ~3))
 
-static int pci_conf1_read(unsigned int seg, unsigned int bus,
+int pci_conf1_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	unsigned long flags;
@@ -42,7 +42,7 @@
 	return 0;
 }
 
-static int pci_conf1_write(unsigned int seg, unsigned int bus,
+int pci_conf1_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	unsigned long flags;
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
index 19e6f48..ee8e016 100644
--- a/arch/i386/pci/irq.c
+++ b/arch/i386/pci/irq.c
@@ -846,7 +846,7 @@
 	 * reported by the device if possible.
 	 */
 	newirq = dev->irq;
-	if (!((1 << newirq) & mask)) {
+	if (newirq && !((1 << newirq) & mask)) {
 		if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
 		else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, pci_name(dev));
 	}
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index dfbf80c..4bb4d4b 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -19,21 +19,25 @@
 /* The base address of the last MMCONFIG device accessed */
 static u32 mmcfg_last_accessed_device;
 
+static DECLARE_BITMAP(fallback_slots, 32);
+
 /*
  * Functions for accessing PCI configuration space with MMCONFIG accesses
  */
-static u32 get_base_addr(unsigned int seg, int bus)
+static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
 {
 	int cfg_num = -1;
 	struct acpi_table_mcfg_config *cfg;
 
+	if (seg == 0 && bus == 0 &&
+	    test_bit(PCI_SLOT(devfn), fallback_slots))
+		return 0;
+
 	while (1) {
 		++cfg_num;
 		if (cfg_num >= pci_mmcfg_config_num) {
-			/* something bad is going on, no cfg table is found. */
-			/* so we fall back to the old way we used to do this */
-			/* and just rely on the first entry to be correct. */
-			return pci_mmcfg_config[0].base_address;
+			/* Not found - fallback to type 1 */
+			return 0;
 		}
 		cfg = &pci_mmcfg_config[cfg_num];
 		if (cfg->pci_segment_group_number != seg)
@@ -44,9 +48,9 @@
 	}
 }
 
-static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn)
+static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
 {
-	u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12);
+	u32 dev_base = base | (bus << 20) | (devfn << 12);
 	if (dev_base != mmcfg_last_accessed_device) {
 		mmcfg_last_accessed_device = dev_base;
 		set_fixmap_nocache(FIX_PCIE_MCFG, dev_base);
@@ -57,13 +61,18 @@
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
 	unsigned long flags;
+	u32 base;
 
 	if (!value || (bus > 255) || (devfn > 255) || (reg > 4095))
 		return -EINVAL;
 
+	base = get_base_addr(seg, bus, devfn);
+	if (!base)
+		return pci_conf1_read(seg,bus,devfn,reg,len,value);
+
 	spin_lock_irqsave(&pci_config_lock, flags);
 
-	pci_exp_set_dev_base(seg, bus, devfn);
+	pci_exp_set_dev_base(base, bus, devfn);
 
 	switch (len) {
 	case 1:
@@ -86,13 +95,18 @@
 			   unsigned int devfn, int reg, int len, u32 value)
 {
 	unsigned long flags;
+	u32 base;
 
 	if ((bus > 255) || (devfn > 255) || (reg > 4095)) 
 		return -EINVAL;
 
+	base = get_base_addr(seg, bus, devfn);
+	if (!base)
+		return pci_conf1_write(seg,bus,devfn,reg,len,value);
+
 	spin_lock_irqsave(&pci_config_lock, flags);
 
-	pci_exp_set_dev_base(seg, bus, devfn);
+	pci_exp_set_dev_base(base, bus, devfn);
 
 	switch (len) {
 	case 1:
@@ -116,6 +130,37 @@
 	.write =	pci_mmcfg_write,
 };
 
+/* K8 systems have some devices (typically in the builtin northbridge)
+   that are only accessible using type1
+   Normally this can be expressed in the MCFG by not listing them
+   and assigning suitable _SEGs, but this isn't implemented in some BIOS.
+   Instead try to discover all devices on bus 0 that are unreachable using MM
+   and fallback for them.
+   We only do this for bus 0/seg 0 */
+static __init void unreachable_devices(void)
+{
+	int i;
+	unsigned long flags;
+
+	for (i = 0; i < 32; i++) {
+		u32 val1;
+		u32 addr;
+
+		pci_conf1_read(0, 0, PCI_DEVFN(i, 0), 0, 4, &val1);
+		if (val1 == 0xffffffff)
+			continue;
+
+		/* Locking probably not needed, but safer */
+		spin_lock_irqsave(&pci_config_lock, flags);
+		addr = get_base_addr(0, 0, PCI_DEVFN(i, 0));
+		if (addr != 0)
+			pci_exp_set_dev_base(addr, 0, PCI_DEVFN(i, 0));
+		if (addr == 0 || readl((u32 __iomem *)mmcfg_virt_addr) != val1)
+			set_bit(i, fallback_slots);
+		spin_unlock_irqrestore(&pci_config_lock, flags);
+	}
+}
+
 static int __init pci_mmcfg_init(void)
 {
 	if ((pci_probe & PCI_PROBE_MMCONF) == 0)
@@ -131,6 +176,8 @@
 	raw_pci_ops = &pci_mmcfg;
 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 
+	unreachable_devices();
+
  out:
 	return 0;
 }
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h
index 127d53a..f550781 100644
--- a/arch/i386/pci/pci.h
+++ b/arch/i386/pci/pci.h
@@ -74,3 +74,10 @@
 
 extern int (*pcibios_enable_irq)(struct pci_dev *dev);
 extern void (*pcibios_disable_irq)(struct pci_dev *dev);
+
+extern int pci_conf1_write(unsigned int seg, unsigned int bus,
+			   unsigned int devfn, int reg, int len, u32 value);
+extern int pci_conf1_read(unsigned int seg, unsigned int bus,
+			  unsigned int devfn, int reg, int len, u32 *value);
+
+
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index b76ce1f..199eeaf 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -58,7 +58,7 @@
 	bool
 	select GENERIC_ALLOCATOR
 
-config ZONE_DMA_IS_DMA32
+config DMA_IS_DMA32
 	bool
 	default y
 
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index 67932ad..57b047c 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -37,10 +37,6 @@
 		ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
 endif
 
-ifneq ($(shell if [ $(GCC_VERSION) -lt 0300 ] ; then echo "bad"; fi ;),)
-$(error Sorry, your compiler is too old.  GCC v2.96 is known to generate bad code.)
-endif
-
 ifeq ($(GCC_VERSION),0304)
 	cflags-$(CONFIG_ITANIUM)	+= -mtune=merced
 	cflags-$(CONFIG_MCKINLEY)	+= -mtune=mckinley
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index 87cfd31..ff8bb37 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc6
-# Tue Aug 16 14:40:41 2005
+# Linux kernel version: 2.6.15-rc4
+# Fri Dec  2 10:33:48 2005
 #
 
 #
@@ -16,6 +16,7 @@
 # General setup
 #
 CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -26,6 +27,7 @@
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
@@ -56,11 +58,29 @@
 CONFIG_STOP_MACHINE=y
 
 #
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Processor type and features
 #
 CONFIG_IA64=y
 CONFIG_64BIT=y
 CONFIG_MMU=y
+CONFIG_SWIOTLB=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
@@ -68,6 +88,7 @@
 CONFIG_GENERIC_IOMAP=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 CONFIG_IA64_UNCACHED_ALLOCATOR=y
+CONFIG_ZONE_DMA_IS_DMA32=y
 # CONFIG_IA64_GENERIC is not set
 # CONFIG_IA64_DIG is not set
 # CONFIG_IA64_HP_ZX1 is not set
@@ -87,16 +108,12 @@
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_IA64_L1_CACHE_SHIFT=7
-CONFIG_NUMA=y
-CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_HOLES_IN_ZONE=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 # CONFIG_IA64_CYCLONE is not set
 CONFIG_IOSAPIC=y
 CONFIG_IA64_SGI_SN_XP=m
-CONFIG_FORCE_MAX_ZONEORDER=18
+CONFIG_FORCE_MAX_ZONEORDER=17
 CONFIG_SMP=y
-CONFIG_NR_CPUS=512
+CONFIG_NR_CPUS=1024
 # CONFIG_HOTPLUG_CPU is not set
 CONFIG_SCHED_SMT=y
 CONFIG_PREEMPT=y
@@ -107,7 +124,17 @@
 CONFIG_DISCONTIGMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 CONFIG_NEED_MULTIPLE_NODES=y
-CONFIG_HAVE_DEC_LOCK=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_NUMA=y
+CONFIG_VIRTUAL_MEM_MAP=y
+CONFIG_HOLES_IN_ZONE=y
+CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
@@ -126,28 +153,35 @@
 # Power management and ACPI
 #
 CONFIG_PM=y
-CONFIG_ACPI=y
+# CONFIG_PM_LEGACY is not set
+# CONFIG_PM_DEBUG is not set
 
 #
 # ACPI (Advanced Configuration and Power Interface) Support
 #
+CONFIG_ACPI=y
 # CONFIG_ACPI_BUTTON is not set
 # CONFIG_ACPI_FAN is not set
 # CONFIG_ACPI_PROCESSOR is not set
 CONFIG_ACPI_NUMA=y
+CONFIG_ACPI_BLACKLIST_YEAR=0
 # CONFIG_ACPI_DEBUG is not set
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_SYSTEM=y
 # CONFIG_ACPI_CONTAINER is not set
 
 #
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
 # Bus options (PCI, PCMCIA)
 #
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY_PROC=y
-CONFIG_PCI_NAMES=y
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -191,8 +225,8 @@
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_BIC=y
 CONFIG_IPV6=m
@@ -205,6 +239,11 @@
 # CONFIG_NETFILTER is not set
 
 #
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
 # SCTP Configuration (EXPERIMENTAL)
 #
 # CONFIG_IP_SCTP is not set
@@ -220,8 +259,11 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -230,6 +272,7 @@
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -244,6 +287,11 @@
 # CONFIG_DEBUG_DRIVER is not set
 
 #
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
@@ -275,16 +323,7 @@
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 CONFIG_ATA_OVER_ETH=m
 
 #
@@ -349,6 +388,7 @@
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 CONFIG_SCSI=y
 CONFIG_SCSI_PROC_FS=y
 
@@ -375,11 +415,13 @@
 #
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SCSI_FC_ATTRS=y
-# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=m
+CONFIG_SCSI_SAS_ATTRS=y
 
 #
 # SCSI low-level drivers
 #
+CONFIG_ISCSI_TCP=m
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -389,15 +431,19 @@
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
 CONFIG_SCSI_SATA=y
 # CONFIG_SCSI_SATA_AHCI is not set
 # CONFIG_SCSI_SATA_SVW is not set
 # CONFIG_SCSI_ATA_PIIX is not set
+# CONFIG_SCSI_SATA_MV is not set
 # CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
+# CONFIG_SCSI_PDC_ADMA is not set
 # CONFIG_SCSI_SATA_QSTOR is not set
+# CONFIG_SCSI_SATA_PROMISE is not set
 # CONFIG_SCSI_SATA_SX4 is not set
 # CONFIG_SCSI_SATA_SIL is not set
+# CONFIG_SCSI_SATA_SIL24 is not set
 # CONFIG_SCSI_SATA_SIS is not set
 # CONFIG_SCSI_SATA_ULI is not set
 # CONFIG_SCSI_SATA_VIA is not set
@@ -411,7 +457,6 @@
 # CONFIG_SCSI_IPR is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 CONFIG_SCSI_QLOGIC_1280=y
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 CONFIG_SCSI_QLA2XXX=y
 # CONFIG_SCSI_QLA21XX is not set
 CONFIG_SCSI_QLA22XX=y
@@ -451,6 +496,7 @@
 CONFIG_FUSION=y
 CONFIG_FUSION_SPI=y
 CONFIG_FUSION_FC=y
+CONFIG_FUSION_SAS=y
 CONFIG_FUSION_MAX_SGE=128
 CONFIG_FUSION_CTL=m
 
@@ -479,6 +525,10 @@
 # CONFIG_ARCNET is not set
 
 #
+# PHY device support
+#
+
+#
 # Ethernet (10 or 100Mbit)
 #
 # CONFIG_NET_ETHERNET is not set
@@ -493,6 +543,7 @@
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
 # CONFIG_SKGE is not set
 # CONFIG_SK98LIN is not set
 CONFIG_TIGON3=y
@@ -501,10 +552,10 @@
 #
 # Ethernet (10000 Mbit)
 #
+CONFIG_CHELSIO_T1=m
 # CONFIG_IXGB is not set
 CONFIG_S2IO=m
 # CONFIG_S2IO_NAPI is not set
-# CONFIG_2BUFF_MODE is not set
 
 #
 # Token Ring devices
@@ -583,6 +634,7 @@
 CONFIG_SERIAL_NONSTANDARD=y
 # CONFIG_ROCKETPORT is not set
 # CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
 # CONFIG_MOXA_SMARTIO is not set
 # CONFIG_ISI is not set
 # CONFIG_SYNCLINKMP is not set
@@ -629,7 +681,8 @@
 #
 # Ftape, the floppy tape device driver
 #
-# CONFIG_AGP is not set
+CONFIG_AGP=y
+CONFIG_AGP_SGI_TIOCA=y
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=m
 # CONFIG_HPET is not set
@@ -641,12 +694,12 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
 #
 # CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
 
 #
 # Dallas's 1-wire bus
@@ -657,12 +710,17 @@
 # Hardware Monitoring support
 #
 # CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
 
 #
 # Misc devices
 #
 
 #
+# Multimedia Capabilities Port drivers
+#
+
+#
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
@@ -721,12 +779,15 @@
 #
 # USB Device Class drivers
 #
-# CONFIG_USB_BLUETOOTH_TTY is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
 #
 # CONFIG_USB_STORAGE is not set
 
@@ -751,9 +812,11 @@
 # CONFIG_USB_MTOUCH is not set
 # CONFIG_USB_ITMTOUCH is not set
 # CONFIG_USB_EGALAX is not set
+# CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
 # CONFIG_USB_KEYSPAN_REMOTE is not set
+# CONFIG_USB_APPLETOUCH is not set
 
 #
 # USB Imaging devices
@@ -824,11 +887,13 @@
 # InfiniBand support
 #
 CONFIG_INFINIBAND=m
-CONFIG_INFINIBAND_USER_VERBS=m
+# CONFIG_INFINIBAND_USER_MAD is not set
+CONFIG_INFINIBAND_USER_ACCESS=m
 CONFIG_INFINIBAND_MTHCA=m
 # CONFIG_INFINIBAND_MTHCA_DEBUG is not set
 CONFIG_INFINIBAND_IPOIB=m
 # CONFIG_INFINIBAND_IPOIB_DEBUG is not set
+CONFIG_INFINIBAND_SRP=m
 
 #
 # SN Devices
@@ -858,16 +923,12 @@
 CONFIG_REISERFS_FS_SECURITY=y
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-
-#
-# XFS support
-#
 CONFIG_XFS_FS=y
 CONFIG_XFS_EXPORT=y
-CONFIG_XFS_RT=y
 CONFIG_XFS_QUOTA=y
 # CONFIG_XFS_SECURITY is not set
 CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_RT=y
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_INOTIFY=y
@@ -878,6 +939,7 @@
 CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=m
 CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=m
 
 #
 # CD-ROM/DVD Filesystems
@@ -904,13 +966,11 @@
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_TMPFS_SECURITY=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
+CONFIG_RELAYFS_FS=m
 
 #
 # Miscellaneous filesystems
@@ -959,6 +1019,7 @@
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -1028,18 +1089,21 @@
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=m
 CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
+CONFIG_LIBCRC32C=m
 CONFIG_ZLIB_INFLATE=m
 CONFIG_ZLIB_DEFLATE=m
 CONFIG_GENERIC_ALLOCATOR=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
 
 #
-# Profiling support
+# Instrumentation Support
 #
 # CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
 
 #
 # Kernel hacking
@@ -1048,6 +1112,7 @@
 CONFIG_DEBUG_KERNEL=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_LOG_BUF_SHIFT=20
+CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 CONFIG_DEBUG_PREEMPT=y
@@ -1056,7 +1121,8 @@
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_FS is not set
-# CONFIG_KPROBES is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 # CONFIG_IA64_PRINT_HAZARDS is not set
@@ -1097,7 +1163,7 @@
 # CONFIG_CRYPTO_ANUBIS is not set
 CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
+CONFIG_CRYPTO_CRC32C=m
 # CONFIG_CRYPTO_TEST is not set
 
 #
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index 9bc8bca..b1e8f09 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc1
-# Wed Sep 14 15:17:57 2005
+# Linux kernel version: 2.6.15-rc4
+# Fri Dec  2 16:06:32 2005
 #
 
 #
@@ -59,17 +59,36 @@
 CONFIG_STOP_MACHINE=y
 
 #
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Processor type and features
 #
 CONFIG_IA64=y
 CONFIG_64BIT=y
 CONFIG_MMU=y
+CONFIG_SWIOTLB=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_TIME_INTERPOLATION=y
 CONFIG_EFI=y
 CONFIG_GENERIC_IOMAP=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ZONE_DMA_IS_DMA32=y
 # CONFIG_IA64_GENERIC is not set
 CONFIG_IA64_DIG=y
 # CONFIG_IA64_HP_ZX1 is not set
@@ -82,18 +101,16 @@
 # CONFIG_IA64_PAGE_SIZE_8KB is not set
 CONFIG_IA64_PAGE_SIZE_16KB=y
 # CONFIG_IA64_PAGE_SIZE_64KB is not set
+CONFIG_PGTABLE_3=y
+# CONFIG_PGTABLE_4 is not set
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
 CONFIG_IA64_L1_CACHE_SHIFT=7
-# CONFIG_NUMA is not set
-CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_HOLES_IN_ZONE=y
 CONFIG_IA64_CYCLONE=y
 CONFIG_IOSAPIC=y
-# CONFIG_IA64_SGI_SN_XP is not set
-CONFIG_FORCE_MAX_ZONEORDER=18
+CONFIG_FORCE_MAX_ZONEORDER=17
 CONFIG_SMP=y
 CONFIG_NR_CPUS=4
 CONFIG_HOTPLUG_CPU=y
@@ -106,7 +123,13 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_HAVE_DEC_LOCK=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_VIRTUAL_MEM_MAP=y
+CONFIG_HOLES_IN_ZONE=y
 CONFIG_IA32_SUPPORT=y
 CONFIG_COMPAT=y
 CONFIG_IA64_MCA_RECOVERY=y
@@ -118,7 +141,6 @@
 #
 CONFIG_EFI_VARS=y
 CONFIG_EFI_PCDP=y
-# CONFIG_DELL_RBU is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 
@@ -126,6 +148,7 @@
 # Power management and ACPI
 #
 CONFIG_PM=y
+CONFIG_PM_LEGACY=y
 # CONFIG_PM_DEBUG is not set
 
 #
@@ -226,14 +249,16 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NETFILTER_NETLINK is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
@@ -295,14 +320,6 @@
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -400,6 +417,7 @@
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_3W_9XXX is not set
 # CONFIG_SCSI_ACARD is not set
@@ -409,6 +427,7 @@
 # CONFIG_SCSI_AIC79XX is not set
 # CONFIG_MEGARAID_NEWGEN is not set
 # CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -424,7 +443,6 @@
 CONFIG_SCSI_QLOGIC_FC=y
 # CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
 CONFIG_SCSI_QLOGIC_1280=y
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
 CONFIG_SCSI_QLA2XXX=y
 CONFIG_SCSI_QLA21XX=m
 CONFIG_SCSI_QLA22XX=m
@@ -463,6 +481,7 @@
 CONFIG_FUSION=y
 CONFIG_FUSION_SPI=y
 CONFIG_FUSION_FC=y
+# CONFIG_FUSION_SAS is not set
 CONFIG_FUSION_MAX_SGE=128
 CONFIG_FUSION_CTL=y
 
@@ -503,6 +522,7 @@
 CONFIG_MII=m
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
 
 #
@@ -727,6 +747,7 @@
 # TPM devices
 #
 # CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
 
 #
 # I2C support
@@ -812,12 +833,15 @@
 #
 # USB Device Class drivers
 #
-# CONFIG_USB_BLUETOOTH_TTY is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
 #
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
 #
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -1123,9 +1147,10 @@
 CONFIG_GENERIC_PENDING_IRQ=y
 
 #
-# Profiling support
+# Instrumentation Support
 #
 # CONFIG_PROFILING is not set
+# CONFIG_KPROBES is not set
 
 #
 # Kernel hacking
@@ -1142,7 +1167,8 @@
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set
-# CONFIG_KPROBES is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_IA64_GRANULE_16MB=y
 # CONFIG_IA64_GRANULE_64MB is not set
 # CONFIG_IA64_PRINT_HAZARDS is not set
diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index a7280d9..4e7a6a1 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -261,8 +261,6 @@
 {
 	set_personality(PER_LINUX32);
 	current->thread.map_base  = IA32_PAGE_OFFSET/3;
-	current->thread.task_size = IA32_PAGE_OFFSET;	/* use what Linux/x86 uses... */
-	set_fs(USER_DS);				/* set addr limit for new TASK_SIZE */
 }
 
 static unsigned long
diff --git a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
index e3e9290..68ceb4e 100644
--- a/arch/ia64/ia32/ia32priv.h
+++ b/arch/ia64/ia32/ia32priv.h
@@ -305,7 +305,6 @@
 #define ELF_DATA	ELFDATA2LSB
 #define ELF_ARCH	EM_386
 
-#define IA32_PAGE_OFFSET	0xc0000000
 #define IA32_STACK_TOP		IA32_PAGE_OFFSET
 #define IA32_GATE_OFFSET	IA32_PAGE_OFFSET
 #define IA32_GATE_END		IA32_PAGE_OFFSET + PAGE_SIZE
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index dc28271..9f8e8d5 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -1761,21 +1761,15 @@
 
 	lock_kernel();
 	if (request == PTRACE_TRACEME) {
-		ret = sys_ptrace(request, pid, addr, data);
+		ret = ptrace_traceme();
 		goto out;
 	}
 
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
 		goto out;
-	ret = -EPERM;
-	if (pid == 1)		/* no messing around with init! */
-		goto out_tsk;
+	}
 
 	if (request == PTRACE_ATTACH) {
 		ret = sys_ptrace(request, pid, addr, data);
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index a3aa45c..c485a3b 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -247,6 +247,32 @@
 
 static kern_memdesc_t *kern_memmap;
 
+#define efi_md_size(md)	(md->num_pages << EFI_PAGE_SHIFT)
+
+static inline u64
+kmd_end(kern_memdesc_t *kmd)
+{
+	return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT));
+}
+
+static inline u64
+efi_md_end(efi_memory_desc_t *md)
+{
+	return (md->phys_addr + efi_md_size(md));
+}
+
+static inline int
+efi_wb(efi_memory_desc_t *md)
+{
+	return (md->attribute & EFI_MEMORY_WB);
+}
+
+static inline int
+efi_uc(efi_memory_desc_t *md)
+{
+	return (md->attribute & EFI_MEMORY_UC);
+}
+
 static void
 walk (efi_freemem_callback_t callback, void *arg, u64 attr)
 {
@@ -595,8 +621,8 @@
 	return 0;
 }
 
-u32
-efi_mem_type (unsigned long phys_addr)
+static efi_memory_desc_t *
+efi_memory_descriptor (unsigned long phys_addr)
 {
 	void *efi_map_start, *efi_map_end, *p;
 	efi_memory_desc_t *md;
@@ -610,55 +636,117 @@
 		md = p;
 
 		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
-			 return md->type;
+			 return md;
 	}
 	return 0;
 }
 
+static int
+efi_memmap_has_mmio (void)
+{
+	void *efi_map_start, *efi_map_end, *p;
+	efi_memory_desc_t *md;
+	u64 efi_desc_size;
+
+	efi_map_start = __va(ia64_boot_param->efi_memmap);
+	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
+	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+
+	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
+		md = p;
+
+		if (md->type == EFI_MEMORY_MAPPED_IO)
+			return 1;
+	}
+	return 0;
+}
+
+u32
+efi_mem_type (unsigned long phys_addr)
+{
+	efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);
+
+	if (md)
+		return md->type;
+	return 0;
+}
+
 u64
 efi_mem_attributes (unsigned long phys_addr)
 {
-	void *efi_map_start, *efi_map_end, *p;
-	efi_memory_desc_t *md;
-	u64 efi_desc_size;
+	efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);
 
-	efi_map_start = __va(ia64_boot_param->efi_memmap);
-	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
-	efi_desc_size = ia64_boot_param->efi_memdesc_size;
-
-	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
-		md = p;
-
-		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT))
-			return md->attribute;
-	}
+	if (md)
+		return md->attribute;
 	return 0;
 }
 EXPORT_SYMBOL(efi_mem_attributes);
 
+/*
+ * Determines whether the memory at phys_addr supports the desired
+ * attribute (WB, UC, etc).  If this returns 1, the caller can safely
+ * access *size bytes at phys_addr with the specified attribute.
+ */
+static int
+efi_mem_attribute_range (unsigned long phys_addr, unsigned long *size, u64 attr)
+{
+	efi_memory_desc_t *md = efi_memory_descriptor(phys_addr);
+	unsigned long md_end;
+
+	if (!md || (md->attribute & attr) != attr)
+		return 0;
+
+	do {
+		md_end = efi_md_end(md);
+		if (phys_addr + *size <= md_end)
+			return 1;
+
+		md = efi_memory_descriptor(md_end);
+		if (!md || (md->attribute & attr) != attr) {
+			*size = md_end - phys_addr;
+			return 1;
+		}
+	} while (md);
+	return 0;
+}
+
+/*
+ * For /dev/mem, we only allow read & write system calls to access
+ * write-back memory, because read & write don't allow the user to
+ * control access size.
+ */
 int
 valid_phys_addr_range (unsigned long phys_addr, unsigned long *size)
 {
-	void *efi_map_start, *efi_map_end, *p;
-	efi_memory_desc_t *md;
-	u64 efi_desc_size;
+	return efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB);
+}
 
-	efi_map_start = __va(ia64_boot_param->efi_memmap);
-	efi_map_end   = efi_map_start + ia64_boot_param->efi_memmap_size;
-	efi_desc_size = ia64_boot_param->efi_memdesc_size;
+/*
+ * We allow mmap of anything in the EFI memory map that supports
+ * either write-back or uncacheable access.  For uncacheable regions,
+ * the supported access sizes are system-dependent, and the user is
+ * responsible for using the correct size.
+ *
+ * Note that this doesn't currently allow access to hot-added memory,
+ * because that doesn't appear in the boot-time EFI memory map.
+ */
+int
+valid_mmap_phys_addr_range (unsigned long phys_addr, unsigned long *size)
+{
+	if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB))
+		return 1;
 
-	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
-		md = p;
+	if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_UC))
+		return 1;
 
-		if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) {
-			if (!(md->attribute & EFI_MEMORY_WB))
-				return 0;
+	/*
+	 * Some firmware doesn't report MMIO regions in the EFI memory map.
+	 * The Intel BigSur (a.k.a. HP i2000) has this problem.  In this
+	 * case, we can't use the EFI memory map to validate mmap requests.
+	 */
+	if (!efi_memmap_has_mmio())
+		return 1;
 
-			if (*size > md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr)
-				*size = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr;
-			return 1;
-		}
-	}
 	return 0;
 }
 
@@ -707,32 +795,6 @@
 	return 0;
 }
 
-#define efi_md_size(md)	(md->num_pages << EFI_PAGE_SHIFT)
-
-static inline u64
-kmd_end(kern_memdesc_t *kmd)
-{
-	return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT));
-}
-
-static inline u64
-efi_md_end(efi_memory_desc_t *md)
-{
-	return (md->phys_addr + efi_md_size(md));
-}
-
-static inline int
-efi_wb(efi_memory_desc_t *md)
-{
-	return (md->attribute & EFI_MEMORY_WB);
-}
-
-static inline int
-efi_uc(efi_memory_desc_t *md)
-{
-	return (md->attribute & EFI_MEMORY_UC);
-}
-
 /*
  * Look for the first granule aligned memory descriptor memory
  * that is big enough to hold EFI memory map. Make sure this
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 0741b066..7a6ffd6 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1600,5 +1600,6 @@
 	data8 sys_inotify_init
 	data8 sys_inotify_add_watch
 	data8 sys_inotify_rm_watch
+	data8 sys_migrate_pages			// 1280
 
 	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index bfe65b2..fbc7ea3 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -1060,7 +1060,7 @@
 	 * the clobber lists for spin_lock() in include/asm-ia64/spinlock.h.
 	 */
 
-#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
 
 GLOBAL_ENTRY(ia64_spinlock_contention_pre3_4)
 	.prologue
diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
index 0157281..e72de58 100644
--- a/arch/ia64/kernel/ia64_ksyms.c
+++ b/arch/ia64/kernel/ia64_ksyms.c
@@ -42,6 +42,7 @@
 
 #ifdef CONFIG_VIRTUAL_MEM_MAP
 #include <linux/bootmem.h>
+EXPORT_SYMBOL(min_low_pfn);	/* defined by bootmem.c, but not exported by generic code */
 EXPORT_SYMBOL(max_low_pfn);	/* defined by bootmem.c, but not exported by generic code */
 #endif
 
@@ -102,7 +103,7 @@
 
 #ifdef ASM_SUPPORTED
 # ifdef CONFIG_SMP
-#  if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#  if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
 /*
  * This is not a normal routine and we don't want a function descriptor for it, so we use
  * a fake declaration here.
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 801eeae..89a7040 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -630,7 +630,7 @@
 			 */
 			save_previous_kprobe(kcb);
 			set_current_kprobe(p, kcb);
-			p->nmissed++;
+			kprobes_inc_nmissed_count(p);
 			prepare_ss(p, regs);
 			kcb->kprobe_status = KPROBE_REENTER;
 			return 1;
@@ -740,7 +740,7 @@
 	switch(val) {
 	case DIE_BREAK:
 		/* err is break number from ia64_bad_break() */
-		if (args->err == 0x80200 || args->err == 0x80300)
+		if (args->err == 0x80200 || args->err == 0x80300 || args->err == 0)
 			if (pre_kprobes_handler(args))
 				ret = NOTIFY_STOP;
 		break;
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 2e33665..e9904c7 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -721,8 +721,13 @@
 	/* drop floating-point and debug-register state if it exists: */
 	current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
 	ia64_drop_fpu(current);
-	if (IS_IA32_PROCESS(ia64_task_regs(current)))
+#ifdef CONFIG_IA32_SUPPORT
+	if (IS_IA32_PROCESS(ia64_task_regs(current))) {
 		ia32_drop_partial_page_list(current);
+		current->thread.task_size = IA32_PAGE_OFFSET;
+		set_fs(USER_DS);
+	}
+#endif
 }
 
 /*
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 4b19d04..8d88eee 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -1422,14 +1422,7 @@
 	lock_kernel();
 	ret = -EPERM;
 	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
+		ret = ptrace_traceme();
 		goto out;
 	}
 
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c
index ca68e6e..1461dc6 100644
--- a/arch/ia64/kernel/salinfo.c
+++ b/arch/ia64/kernel/salinfo.c
@@ -293,7 +293,7 @@
 		if (file->f_flags & O_NONBLOCK)
 			return -EAGAIN;
 		if (down_interruptible(&data->sem))
-			return -ERESTARTSYS;
+			return -EINTR;
 	}
 
 	n = data->cpu_check;
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 5add0bc..c33305d 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -43,6 +43,7 @@
 #include <linux/initrd.h>
 #include <linux/platform.h>
 #include <linux/pm.h>
+#include <linux/cpufreq.h>
 
 #include <asm/ia32.h>
 #include <asm/machvec.h>
@@ -517,6 +518,7 @@
 	char family[32], features[128], *cp, sep;
 	struct cpuinfo_ia64 *c = v;
 	unsigned long mask;
+	unsigned long proc_freq;
 	int i;
 
 	mask = c->features;
@@ -549,6 +551,10 @@
 		sprintf(cp, " 0x%lx", mask);
 	}
 
+	proc_freq = cpufreq_quick_get(cpunum);
+	if (!proc_freq)
+		proc_freq = c->proc_freq / 1000;
+
 	seq_printf(m,
 		   "processor  : %d\n"
 		   "vendor     : %s\n"
@@ -565,7 +571,7 @@
 		   "BogoMIPS   : %lu.%02lu\n",
 		   cpunum, c->vendor, family, c->model, c->revision, c->archrev,
 		   features, c->ppn, c->number,
-		   c->proc_freq / 1000000, c->proc_freq % 1000000,
+		   proc_freq / 1000, proc_freq % 1000,
 		   c->itc_freq / 1000000, c->itc_freq % 1000000,
 		   lpj*HZ/500000, (lpj*HZ/5000) % 100);
 #ifdef CONFIG_SMP
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index 5b7e736..028a2b9 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -249,3 +249,32 @@
 	 */
 	set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec);
 }
+
+#define SMALLUSECS 100
+
+void
+udelay (unsigned long usecs)
+{
+	unsigned long start;
+	unsigned long cycles;
+	unsigned long smallusecs;
+
+	/*
+	 * Execute the non-preemptible delay loop (because the ITC might
+	 * not be synchronized between CPUS) in relatively short time
+	 * chunks, allowing preemption between the chunks.
+	 */
+	while (usecs > 0) {
+		smallusecs = (usecs > SMALLUSECS) ? SMALLUSECS : usecs;
+		preempt_disable();
+		cycles = smallusecs*local_cpu_data->cyc_per_usec;
+		start = ia64_get_itc();
+
+		while (ia64_get_itc() - start < cycles)
+			cpu_relax();
+
+		preempt_enable();
+		usecs -= smallusecs;
+	}
+}
+EXPORT_SYMBOL(udelay);
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index fba5fdd..d3e0ecb 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -132,24 +132,6 @@
 	siginfo_t siginfo;
 	int sig, code;
 
-	/* break.b always sets cr.iim to 0, which causes problems for
-	 * debuggers.  Get the real break number from the original instruction,
-	 * but only for kernel code.  User space break.b is left alone, to
-	 * preserve the existing behaviour.  All break codings have the same
-	 * format, so there is no need to check the slot type.
-	 */
-	if (break_num == 0 && !user_mode(regs)) {
-		struct ia64_psr *ipsr = ia64_psr(regs);
-		unsigned long *bundle = (unsigned long *)regs->cr_iip;
-		unsigned long slot;
-		switch (ipsr->ri) {
-		      case 0:  slot = (bundle[0] >>  5); break;
-		      case 1:  slot = (bundle[0] >> 46) | (bundle[1] << 18); break;
-		      default: slot = (bundle[1] >> 23); break;
-		}
-		break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff);
-	}
-
 	/* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */
 	siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri);
 	siginfo.si_imm = break_num;
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index c6d4044..b631cf8 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -53,7 +53,7 @@
 	if ((status != PAL_VISIBILITY_OK) &&
 	    (status != PAL_VISIBILITY_OK_REMOTE_NEEDED))
 		printk(KERN_DEBUG "pal_prefetch_visibility() returns %i on "
-		       "CPU %i\n", status, get_cpu());
+		       "CPU %i\n", status, raw_smp_processor_id());
 }
 
 
@@ -63,7 +63,7 @@
 	status = ia64_pal_mc_drain();
 	if (status)
 		printk(KERN_WARNING "ia64_pal_mc_drain() failed with %i on "
-		       "CPU %i\n", status, get_cpu());
+		       "CPU %i\n", status, raw_smp_processor_id());
 }
 
 
@@ -105,7 +105,7 @@
 	status = ia64_pal_prefetch_visibility(PAL_VISIBILITY_PHYSICAL);
 
 	dprintk(KERN_INFO "pal_prefetch_visibility() returns %i on cpu %i\n",
-		status, get_cpu());
+		status, raw_smp_processor_id());
 
 	if (!status) {
 		status = smp_call_function(uncached_ipi_visibility, NULL, 0, 1);
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 30d8564..73af626 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -177,6 +177,9 @@
 	}
   . = ALIGN(PAGE_SIZE);		/* make sure the gate page doesn't expose kernel data */
 
+  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET)
+        { *(.data.read_mostly) }
+
   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET)
         { *(.data.cacheline_aligned) }
 
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 0f776b0..c87d6d1 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -50,8 +50,10 @@
  * To prevent cache aliasing effects, align per-node structures so that they
  * start at addresses that are strided by node number.
  */
+#define MAX_NODE_ALIGN_OFFSET	(32 * 1024 * 1024)
 #define NODEDATA_ALIGN(addr, node)						\
-	((((addr) + 1024*1024-1) & ~(1024*1024-1)) + (node)*PERCPU_PAGE_SIZE)
+	((((addr) + 1024*1024-1) & ~(1024*1024-1)) + 				\
+	     (((node)*PERCPU_PAGE_SIZE) & (MAX_NODE_ALIGN_OFFSET - 1)))
 
 /**
  * build_node_maps - callback to setup bootmem structs for each node
diff --git a/arch/ia64/oprofile/backtrace.c b/arch/ia64/oprofile/backtrace.c
index b7dabbf..adb0156 100644
--- a/arch/ia64/oprofile/backtrace.c
+++ b/arch/ia64/oprofile/backtrace.c
@@ -32,7 +32,7 @@
 	u64 *prev_pfs_loc;	/* state for WAR for old spinlock ool code */
 } ia64_backtrace_t;
 
-#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
 /*
  * Returns non-zero if the PC is in the spinlock contention out-of-line code
  * with non-standard calling sequence (on older compilers).
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 20d76fa..30dbc98 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -700,7 +700,7 @@
  */
 int ia64_pci_legacy_write(struct pci_dev *bus, u16 port, u32 val, u8 size)
 {
-	int ret = 0;
+	int ret = size;
 
 	switch (size) {
 	case 1:
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 05e4ea8..318087e 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/bootmem.h>
@@ -147,6 +147,24 @@
 }
 
 /*
+ * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified
+ *			  device.
+ */
+inline struct pcidev_info *
+sn_pcidev_info_get(struct pci_dev *dev)
+{
+	struct pcidev_info *pcidev;
+
+	list_for_each_entry(pcidev,
+			    &(SN_PCI_CONTROLLER(dev)->pcidev_info), pdi_list) {
+		if (pcidev->pdi_linux_pcidev == dev) {
+			return pcidev;
+		}
+	}
+	return NULL;
+}
+
+/*
  * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for 
  *	each node in the system.
  */
@@ -229,6 +247,50 @@
 
 }
 
+/*
+ * sn_pci_window_fixup() - Create a pci_window for each device resource.
+ *			   Until ACPI support is added, we need this code
+ *			   to setup pci_windows for use by
+ *			   pcibios_bus_to_resource(),
+ *			   pcibios_resource_to_bus(), etc.
+ */
+static void
+sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
+		    int64_t * pci_addrs)
+{
+	struct pci_controller *controller = PCI_CONTROLLER(dev->bus);
+	unsigned int i;
+	unsigned int idx;
+	unsigned int new_count;
+	struct pci_window *new_window;
+
+	if (count == 0)
+		return;
+	idx = controller->windows;
+	new_count = controller->windows + count;
+	new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL);
+	if (new_window == NULL)
+		BUG();
+	if (controller->window) {
+		memcpy(new_window, controller->window,
+		       sizeof(struct pci_window) * controller->windows);
+		kfree(controller->window);
+	}
+
+	/* Setup a pci_window for each device resource. */
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		if (pci_addrs[i] == -1)
+			continue;
+
+		new_window[idx].offset = dev->resource[i].start - pci_addrs[i];
+		new_window[idx].resource = dev->resource[i];
+		idx++;
+	}
+
+	controller->windows = new_count;
+	controller->window = new_window;
+}
+
 void sn_pci_unfixup_slot(struct pci_dev *dev)
 {
 	struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev;
@@ -246,21 +308,23 @@
  */
 void sn_pci_fixup_slot(struct pci_dev *dev)
 {
+	unsigned int count = 0;
 	int idx;
 	int segment = pci_domain_nr(dev->bus);
 	int status = 0;
 	struct pcibus_bussoft *bs;
  	struct pci_bus *host_pci_bus;
  	struct pci_dev *host_pci_dev;
+	struct pcidev_info *pcidev_info;
+	int64_t pci_addrs[PCI_ROM_RESOURCE + 1];
  	struct sn_irq_info *sn_irq_info;
  	unsigned long size;
  	unsigned int bus_no, devfn;
 
 	pci_dev_get(dev); /* for the sysdata pointer */
-	dev->sysdata = kmalloc(sizeof(struct pcidev_info), GFP_KERNEL);
-	if (SN_PCIDEV_INFO(dev) <= 0)
+	pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
+	if (pcidev_info <= 0)
 		BUG();		/* Cannot afford to run out of memory */
-	memset(SN_PCIDEV_INFO(dev), 0, sizeof(struct pcidev_info));
 
 	sn_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
 	if (sn_irq_info <= 0)
@@ -270,22 +334,34 @@
 	/* Call to retrieve pci device information needed by kernel. */
 	status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, 
 				     dev->devfn,
-				     (u64) __pa(SN_PCIDEV_INFO(dev)),
+				     (u64) __pa(pcidev_info),
 				     (u64) __pa(sn_irq_info));
 	if (status)
 		BUG(); /* Cannot get platform pci device information */
 
+	/* Add pcidev_info to list in sn_pci_controller struct */
+	list_add_tail(&pcidev_info->pdi_list,
+		      &(SN_PCI_CONTROLLER(dev->bus)->pcidev_info));
+
 	/* Copy over PIO Mapped Addresses */
 	for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
 		unsigned long start, end, addr;
 
-		if (!SN_PCIDEV_INFO(dev)->pdi_pio_mapped_addr[idx])
+		if (!pcidev_info->pdi_pio_mapped_addr[idx]) {
+			pci_addrs[idx] = -1;
 			continue;
+		}
 
 		start = dev->resource[idx].start;
 		end = dev->resource[idx].end;
 		size = end - start;
-		addr = SN_PCIDEV_INFO(dev)->pdi_pio_mapped_addr[idx];
+		if (size == 0) {
+			pci_addrs[idx] = -1;
+			continue;
+		}
+		pci_addrs[idx] = start;
+		count++;
+		addr = pcidev_info->pdi_pio_mapped_addr[idx];
 		addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET;
 		dev->resource[idx].start = addr;
 		dev->resource[idx].end = addr + size;
@@ -294,23 +370,27 @@
 		else
 			dev->resource[idx].parent = &iomem_resource;
 	}
+	/* Create a pci_window in the pci_controller struct for
+	 * each device resource.
+	 */
+	if (count > 0)
+		sn_pci_window_fixup(dev, count, pci_addrs);
 
 	/*
 	 * Using the PROMs values for the PCI host bus, get the Linux
  	 * PCI host_pci_dev struct and set up host bus linkages
  	 */
 
- 	bus_no = (SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32) & 0xff;
- 	devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff;
+	bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff;
+	devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff;
  	host_pci_bus = pci_find_bus(segment, bus_no);
  	host_pci_dev = pci_get_slot(host_pci_bus, devfn);
 
-	SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev;
-	SN_PCIDEV_INFO(dev)->pdi_host_pcidev_info =
-	    					SN_PCIDEV_INFO(host_pci_dev);
-	SN_PCIDEV_INFO(dev)->pdi_linux_pcidev = dev;
+	pcidev_info->host_pci_dev = host_pci_dev;
+	pcidev_info->pdi_linux_pcidev = dev;
+	pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev);
 	bs = SN_PCIBUS_BUSSOFT(dev->bus);
-	SN_PCIDEV_INFO(dev)->pdi_pcibus_info = bs;
+	pcidev_info->pdi_pcibus_info = bs;
 
 	if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) {
 		SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type];
@@ -320,11 +400,11 @@
 
 	/* Only set up IRQ stuff if this device has a host bus context */
 	if (bs && sn_irq_info->irq_irq) {
-		SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = sn_irq_info;
-		dev->irq = SN_PCIDEV_INFO(dev)->pdi_sn_irq_info->irq_irq;
+		pcidev_info->pdi_sn_irq_info = sn_irq_info;
+		dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq;
 		sn_irq_fixup(dev, sn_irq_info);
 	} else {
-		SN_PCIDEV_INFO(dev)->pdi_sn_irq_info = NULL;
+		pcidev_info->pdi_sn_irq_info = NULL;
 		kfree(sn_irq_info);
 	}
 }
@@ -338,6 +418,7 @@
 	int status = 0;
 	int nasid, cnode;
 	struct pci_controller *controller;
+	struct sn_pci_controller *sn_controller;
 	struct pcibus_bussoft *prom_bussoft_ptr;
 	struct hubdev_info *hubdev_info;
 	void *provider_soft = NULL;
@@ -349,10 +430,15 @@
 		return;		/*bus # does not exist */
 	prom_bussoft_ptr = __va(prom_bussoft_ptr);
 
- 	controller = kzalloc(sizeof(struct pci_controller), GFP_KERNEL);
+	/* Allocate a sn_pci_controller, which has a pci_controller struct
+	 * as the first member.
+	 */
+	sn_controller = kzalloc(sizeof(struct sn_pci_controller), GFP_KERNEL);
+	if (!sn_controller)
+		BUG();
+	INIT_LIST_HEAD(&sn_controller->pcidev_info);
+	controller = &sn_controller->pci_controller;
 	controller->segment = segment;
- 	if (!controller)
- 		BUG();
 
 	if (bus == NULL) {
  		bus = pci_scan_bus(busnum, &pci_root_ops, controller);
@@ -390,6 +476,29 @@
 	}
 
 	/*
+	 * Setup pci_windows for legacy IO and MEM space.
+	 * (Temporary until ACPI support is in place.)
+	 */
+	controller->window = kcalloc(2, sizeof(struct pci_window), GFP_KERNEL);
+	if (controller->window == NULL)
+		BUG();
+	controller->window[0].offset = prom_bussoft_ptr->bs_legacy_io;
+	controller->window[0].resource.name = "legacy_io";
+	controller->window[0].resource.flags = IORESOURCE_IO;
+	controller->window[0].resource.start = prom_bussoft_ptr->bs_legacy_io;
+	controller->window[0].resource.end =
+	    controller->window[0].resource.start + 0xffff;
+	controller->window[0].resource.parent = &ioport_resource;
+	controller->window[1].offset = prom_bussoft_ptr->bs_legacy_mem;
+	controller->window[1].resource.name = "legacy_mem";
+	controller->window[1].resource.flags = IORESOURCE_MEM;
+	controller->window[1].resource.start = prom_bussoft_ptr->bs_legacy_mem;
+	controller->window[1].resource.end =
+	    controller->window[1].resource.start + (1024 * 1024) - 1;
+	controller->window[1].resource.parent = &iomem_resource;
+	controller->windows = 2;
+
+	/*
 	 * Generic bus fixup goes here.  Don't reference prom_bussoft_ptr
 	 * after this point.
 	 */
@@ -421,7 +530,7 @@
 
 error_return:
 
-	kfree(controller);
+	kfree(sn_controller);
 	return;
 }
 
@@ -434,7 +543,7 @@
 		dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__);
 		return;
 	}
-	element->sysdata = dev->sysdata;
+	element->sysdata = SN_PCIDEV_INFO(dev);
 	list_add(&element->entry, &sn_sysdata_list);
 }
 
diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
index 3fa9506..bebbcc4 100644
--- a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
+++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
@@ -39,9 +39,13 @@
 	mov	r8=r0
 
 1:
+	cmp.ne  p8,p9=r0,ptc1		// Test for shub type (ptc1 non-null on shub1)
+					// p8 = 1 if shub1, p9 = 1 if shub2
+
 	add	scr2=ALIAS_OFFSET,piowc	// Address of WRITE_STATUS alias register 
-	;;
-	ld8.acq	scr1=[scr2];;
+	mov	scr1=7;;		// Clear DEADLOCK, WRITE_ERROR, MULTI_WRITE_ERROR
+(p8)	st8.rel	[scr2]=scr1;;
+(p9)	ld8.acq	scr1=[scr2];;
 
 5:	ld8.acq	scr1=[piowc];;		// Wait for PIOs to complete.
 	hint	@pause
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
index 5d54f5f..471bbaa 100644
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c
@@ -202,7 +202,7 @@
 		     unsigned long end, unsigned long nbits)
 {
 	int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0;
-	int mymm = (mm == current->active_mm);
+	int mymm = (mm == current->active_mm && current->mm);
 	volatile unsigned long *ptc0, *ptc1;
 	unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value;
 	short nasids[MAX_NUMNODES], nix;
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index 0d8592a..768c21d 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -65,7 +65,7 @@
 
 }
 
-static int tiocx_hotplug(struct device *dev, char **envp, int num_envp,
+static int tiocx_uevent(struct device *dev, char **envp, int num_envp,
 			 char *buffer, int buffer_size)
 {
 	return -ENODEV;
@@ -79,7 +79,7 @@
 struct bus_type tiocx_bus_type = {
 	.name = "tiocx",
 	.match = tiocx_match,
-	.hotplug = tiocx_hotplug,
+	.uevent = tiocx_uevent,
 };
 
 /**
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
index 5d53409..79fdb91 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_reg.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
@@ -25,7 +25,7 @@
  */
 void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 
 	if (pcibus_info) {
 		switch (pcibus_info->pbi_bridge_type) {
@@ -38,14 +38,14 @@
 		default:
 			panic
 			    ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 }
 
 void pcireg_control_bit_set(struct pcibus_info *pcibus_info, uint64_t bits)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 
 	if (pcibus_info) {
 		switch (pcibus_info->pbi_bridge_type) {
@@ -58,7 +58,7 @@
 		default:
 			panic
 			    ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 }
@@ -68,7 +68,7 @@
  */
 uint64_t pcireg_tflush_get(struct pcibus_info *pcibus_info)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 	uint64_t ret = 0;
 
 	if (pcibus_info) {
@@ -82,7 +82,7 @@
 		default:
 			panic
 			    ("pcireg_tflush_get: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 
@@ -98,7 +98,7 @@
  */
 uint64_t pcireg_intr_status_get(struct pcibus_info * pcibus_info)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 	uint64_t ret = 0;
 
 	if (pcibus_info) {
@@ -112,7 +112,7 @@
 		default:
 			panic
 			    ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 	return ret;
@@ -123,7 +123,7 @@
  */
 void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, uint64_t bits)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 
 	if (pcibus_info) {
 		switch (pcibus_info->pbi_bridge_type) {
@@ -136,14 +136,14 @@
 		default:
 			panic
 			    ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 }
 
 void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, uint64_t bits)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 
 	if (pcibus_info) {
 		switch (pcibus_info->pbi_bridge_type) {
@@ -156,7 +156,7 @@
 		default:
 			panic
 			    ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 }
@@ -167,7 +167,7 @@
 void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,
 			       uint64_t addr)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 
 	if (pcibus_info) {
 		switch (pcibus_info->pbi_bridge_type) {
@@ -186,7 +186,7 @@
 		default:
 			panic
 			    ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 }
@@ -196,7 +196,7 @@
  */
 void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 
 	if (pcibus_info) {
 		switch (pcibus_info->pbi_bridge_type) {
@@ -209,7 +209,7 @@
 		default:
 			panic
 			    ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 }
@@ -219,7 +219,7 @@
  */
 uint64_t pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 	uint64_t ret = 0;
 
 	if (pcibus_info) {
@@ -233,7 +233,7 @@
 			    __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]);
 			break;
 		default:
-		      panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", (void *)ptr);
+		      panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr);
 		}
 
 	}
@@ -244,7 +244,7 @@
 void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index,
 			uint64_t val)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
 
 	if (pcibus_info) {
 		switch (pcibus_info->pbi_bridge_type) {
@@ -257,15 +257,15 @@
 		default:
 			panic
 			    ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 }
 
-uint64_t *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
+uint64_t __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
 {
-	union br_ptr *ptr = (union br_ptr *)pcibus_info->pbi_buscommon.bs_base;
-	uint64_t *ret = (uint64_t *) 0;
+	union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
+	uint64_t __iomem *ret = NULL;
 
 	if (pcibus_info) {
 		switch (pcibus_info->pbi_bridge_type) {
@@ -278,7 +278,7 @@
 		default:
 			panic
 			    ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p",
-			     (void *)ptr);
+			     ptr);
 		}
 	}
 	return ret;
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 46b646a..27aa184 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -38,10 +38,10 @@
 	uint64_t offset;
 	struct page *tmp;
 	struct tioca_common *tioca_common;
-	struct tioca *ca_base;
+	struct tioca __iomem *ca_base;
 
 	tioca_common = tioca_kern->ca_common;
-	ca_base = (struct tioca *)tioca_common->ca_common.bs_base;
+	ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
 
 	if (list_empty(tioca_kern->ca_devices))
 		return 0;
@@ -215,7 +215,7 @@
 {
 	int cap_ptr;
 	uint32_t reg;
-	struct tioca *tioca_base;
+	struct tioca __iomem *tioca_base;
 	struct pci_dev *pdev;
 	struct tioca_common *common;
 
@@ -257,7 +257,7 @@
 	 * Set ca's fw to match
 	 */
 
-	tioca_base = (struct tioca *)common->ca_common.bs_base;
+	tioca_base = (struct tioca __iomem*)common->ca_common.bs_base;
 	__sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE);
 }
 
@@ -322,7 +322,7 @@
 tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr)
 {
 	struct tioca_common *tioca_common;
-	struct tioca *ca_base;
+	struct tioca __iomem *ca_base;
 	uint64_t ct_addr;
 	dma_addr_t bus_addr;
 	uint32_t node_upper;
@@ -330,7 +330,7 @@
 	struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
 
 	tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
-	ca_base = (struct tioca *)tioca_common->ca_common.bs_base;
+	ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
 
 	ct_addr = PHYS_TO_TIODMA(paddr);
 	if (!ct_addr)
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 4d100f3..fae67bb 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -81,6 +81,12 @@
 config PLAT_MAPPI3
        bool "Mappi-III(M3A-2170)"
 
+config PLAT_M32104UT
+	bool "M32104UT"
+	help
+	  The M3T-M32104UT is an reference board based on uT-Engine
+	  specification.  This board has a M32104 chip.
+
 endchoice
 
 choice
@@ -93,6 +99,10 @@
 config CHIP_M32102
 	bool "M32102"
 
+config CHIP_M32104
+	bool "M32104"
+	depends on PLAT_M32104UT
+
 config CHIP_VDEC2
        bool "VDEC2"
 
@@ -115,7 +125,7 @@
 
 config ISA_M32R
         bool
-	depends on CHIP_M32102
+	depends on CHIP_M32102 || CHIP_M32104
 	default y
 
 config ISA_M32R2
@@ -140,6 +150,7 @@
 	default "50000000" if PLAT_MAPPI3
 	default "50000000" if PLAT_M32700UT
 	default "50000000" if PLAT_OPSPUT
+	default "54000000" if PLAT_M32104UT
 	default "33333333" if PLAT_OAKS32R
 	default "20000000" if PLAT_MAPPI2
 
@@ -157,6 +168,7 @@
 	default "08000000" if PLAT_USRV
 	default "08000000" if PLAT_M32700UT
 	default "08000000" if PLAT_OPSPUT
+	default "04000000" if PLAT_M32104UT
 	default "01000000" if PLAT_OAKS32R
 
 config MEMORY_SIZE
@@ -166,6 +178,7 @@
 	default "02000000" if PLAT_USRV
 	default "01000000" if PLAT_M32700UT
 	default "01000000" if PLAT_OPSPUT
+	default "01000000" if PLAT_M32104UT
 	default "00800000" if PLAT_OAKS32R
 
 config NOHIGHMEM
@@ -174,21 +187,22 @@
 
 config ARCH_DISCONTIGMEM_ENABLE
 	bool "Internal RAM Support"
-	depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP
+	depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104
 	default y
 
 source "mm/Kconfig"
 
 config IRAM_START
 	hex "Internal memory start address (hex)"
-	default "00f00000"
-	depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP) && DISCONTIGMEM
+	default "00f00000" if !CHIP_M32104
+	default "00700000" if CHIP_M32104
+	depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104) && DISCONTIGMEM
 
 config IRAM_SIZE
 	hex "Internal memory size (hex)"
-	depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP) && DISCONTIGMEM
+	depends on (CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104) && DISCONTIGMEM
 	default "00080000" if CHIP_M32700
-	default "00010000" if CHIP_M32102 || CHIP_OPSP
+	default "00010000" if CHIP_M32102 || CHIP_OPSP || CHIP_M32104
 	default "00008000" if CHIP_VDEC2
 
 #
diff --git a/arch/m32r/boot/compressed/head.S b/arch/m32r/boot/compressed/head.S
index 07cfd6a..234d8b1 100644
--- a/arch/m32r/boot/compressed/head.S
+++ b/arch/m32r/boot/compressed/head.S
@@ -143,6 +143,11 @@
 	ldi	r0, -2
 	ldi	r1, 0x0100	; invalidate
 	stb	r1, @r0
+#elif defined(CONFIG_CHIP_M32104)
+	/* Cache flush */
+	ldi	r0, -2
+	ldi	r1, 0x0700	; invalidate i-cache, copy back d-cache
+	sth	r1, @r0
 #else
 #error "put your cache flush function, please"
 #endif
diff --git a/arch/m32r/boot/setup.S b/arch/m32r/boot/setup.S
index 5d25643..3985425 100644
--- a/arch/m32r/boot/setup.S
+++ b/arch/m32r/boot/setup.S
@@ -1,11 +1,10 @@
 /*
  *  linux/arch/m32r/boot/setup.S -- A setup code.
  *
- *  Copyright (C) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
- *  and Hitoshi Yamamoto
+ *  Copyright (C) 2001-2005   Hiroyuki Kondo, Hirokazu Takata,
+ *                            Hitoshi Yamamoto, Hayato Fujiwara
  *
  */
-/* $Id$ */
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
@@ -80,6 +79,20 @@
 	ldi	r1, #0x101		; cache on (with invalidation)
 ;	ldi	r1, #0x00		; cache off
 	st	r1, @r0
+#elif defined(CONFIG_CHIP_M32104)
+	ldi	r0, #-96		; DNCR0
+	seth	r1, #0x0060		;  from 0x00600000
+	or3	r1, r1, #0x0005		;  size 2MB
+	st	r1, @r0
+	seth	r1, #0x0100		;  from 0x01000000
+	or3	r1, r1, #0x0003		;  size 16MB
+	st	r1, @+r0
+	seth	r1, #0x0200		;  from 0x02000000
+	or3	r1, r1, #0x0002		;  size 32MB
+	st	r1, @+r0
+	ldi	r0, #-4              ;LDIMM	(r0, M32R_MCCR)
+	ldi	r1, #0x703		; cache on (with invalidation)
+	st	r1, @r0
 #else
 #error unknown chip configuration
 #endif
@@ -115,10 +128,15 @@
 	st      r1, @(MATM_offset,r0)		; Set MATM (T bit ON)
 	ld      r0, @(MATM_offset,r0)		; Check
 #else
+#if defined(CONFIG_CHIP_M32700)
 	seth	r0,#high(M32R_MCDCAR)
 	or3	r0,r0,#low(M32R_MCDCAR)
 	ld24	r1,#0x8080
 	st	r1,@r0
+#elif defined(CONFIG_CHIP_M32104)
+	LDIMM	(r2, eit_vector)		; set EVB(cr5)
+	mvtc    r2, cr5
+#endif
 #endif	/* CONFIG_MMU */
 	jmp	r13
 	nop
diff --git a/arch/m32r/kernel/Makefile b/arch/m32r/kernel/Makefile
index 6c6b6c3..5a2fa88 100644
--- a/arch/m32r/kernel/Makefile
+++ b/arch/m32r/kernel/Makefile
@@ -16,5 +16,6 @@
 obj-$(CONFIG_PLAT_OPSPUT)	+= setup_opsput.o io_opsput.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_PLAT_OAKS32R)	+= setup_oaks32r.o io_oaks32r.o
+obj-$(CONFIG_PLAT_M32104UT)	+= setup_m32104ut.o io_m32104ut.o
 
 EXTRA_AFLAGS	:= -traditional
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S
index 396c942..3871b65 100644
--- a/arch/m32r/kernel/entry.S
+++ b/arch/m32r/kernel/entry.S
@@ -315,7 +315,7 @@
 	mv	r1, sp			; arg1(regs)
 #if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \
 	|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
-	|| defined(CONFIG_CHIP_OPSP)
+	|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
 
 ;    GET_ICU_STATUS;
 	seth	r0, #shigh(M32R_ICU_ISTS_ADDR)
@@ -541,7 +541,20 @@
 	bra	check_end
 	.fillinsn
 check_end:
-#endif  /* CONFIG_PLAT_OPSPUT */
+#elif defined(CONFIG_PLAT_M32104UT)
+	add3	r2, r0, #-(M32R_IRQ_INT1)       ; INT1# interrupt
+	bnez	r2, check_end
+	; read ICU status register of PLD
+	seth	r0, #high(PLD_ICUISTS)
+	or3	r0, r0, #low(PLD_ICUISTS)
+	lduh	r0, @r0
+	slli	r0, #21
+	srli	r0, #27                         ; ISN
+	addi	r0, #(M32104UT_PLD_IRQ_BASE)
+	bra	check_end
+	.fillinsn
+check_end:
+#endif  /* CONFIG_PLAT_M32104UT */
 	bl	do_IRQ
 #endif  /* CONFIG_SMP */
 	ld	r14, @sp+
@@ -651,8 +664,6 @@
 /* void rie_handler(int error_code) */
 	SWITCH_TO_KERNEL_STACK
 	SAVE_ALL
-	mvfc	r0, bpc
-	ld	r1, @r0
 	ldi	r1, #0x20			; error_code
 	mv	r0, sp				; pt_regs
 	bl	do_rie_handler
diff --git a/arch/m32r/kernel/io_m32104ut.c b/arch/m32r/kernel/io_m32104ut.c
new file mode 100644
index 0000000..d26adab
--- /dev/null
+++ b/arch/m32r/kernel/io_m32104ut.c
@@ -0,0 +1,298 @@
+/*
+ *  linux/arch/m32r/kernel/io_m32104ut.c
+ *
+ *  Typical I/O routines for M32104UT board.
+ *
+ *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Mamoru Sakugawa,
+ *                           Naoto Sugai, Hayato Fujiwara
+ */
+
+#include <linux/config.h>
+#include <asm/m32r.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+#include <linux/types.h>
+
+#define M32R_PCC_IOMAP_SIZE 0x1000
+
+#define M32R_PCC_IOSTART0 0x1000
+#define M32R_PCC_IOEND0   (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1)
+
+extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int);
+extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int);
+extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int);
+extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
+#endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */
+
+#define PORT2ADDR(port)  _port2addr(port)
+
+static inline void *_port2addr(unsigned long port)
+{
+	return (void *)(port | NONCACHE_OFFSET);
+}
+
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+static inline void *__port2addr_ata(unsigned long port)
+{
+	static int	dummy_reg;
+
+	switch (port) {
+	case 0x1f0:	return (void *)(0x0c002000 | NONCACHE_OFFSET);
+	case 0x1f1:	return (void *)(0x0c012800 | NONCACHE_OFFSET);
+	case 0x1f2:	return (void *)(0x0c012002 | NONCACHE_OFFSET);
+	case 0x1f3:	return (void *)(0x0c012802 | NONCACHE_OFFSET);
+	case 0x1f4:	return (void *)(0x0c012004 | NONCACHE_OFFSET);
+	case 0x1f5:	return (void *)(0x0c012804 | NONCACHE_OFFSET);
+	case 0x1f6:	return (void *)(0x0c012006 | NONCACHE_OFFSET);
+	case 0x1f7:	return (void *)(0x0c012806 | NONCACHE_OFFSET);
+	case 0x3f6:	return (void *)(0x0c01200e | NONCACHE_OFFSET);
+	default: 	return (void *)&dummy_reg;
+	}
+}
+#endif
+
+/*
+ * M32104T-LAN is located in the extended bus space
+ * from 0x01000000 to 0x01ffffff on physical address.
+ * The base address of LAN controller(LAN91C111) is 0x300.
+ */
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
+static inline void *_port2addr_ne(unsigned long port)
+{
+	return (void *)(port + NONCACHE_OFFSET + 0x01000000);
+}
+
+static inline void delay(void)
+{
+	__asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
+}
+
+/*
+ * NIC I/O function
+ */
+
+#define PORT2ADDR_NE(port)  _port2addr_ne(port)
+
+static inline unsigned char _ne_inb(void *portp)
+{
+	return *(volatile unsigned char *)portp;
+}
+
+static inline unsigned short _ne_inw(void *portp)
+{
+	return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp);
+}
+
+static inline void _ne_insb(void *portp, void *addr, unsigned long count)
+{
+	unsigned char *buf = (unsigned char *)addr;
+
+	while (count--)
+		*buf++ = _ne_inb(portp);
+}
+
+static inline void _ne_outb(unsigned char b, void *portp)
+{
+	*(volatile unsigned char *)portp = b;
+}
+
+static inline void _ne_outw(unsigned short w, void *portp)
+{
+	*(volatile unsigned short *)portp = cpu_to_le16(w);
+}
+
+unsigned char _inb(unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		return _ne_inb(PORT2ADDR_NE(port));
+
+	return *(volatile unsigned char *)PORT2ADDR(port);
+}
+
+unsigned short _inw(unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		return _ne_inw(PORT2ADDR_NE(port));
+
+	return *(volatile unsigned short *)PORT2ADDR(port);
+}
+
+unsigned long _inl(unsigned long port)
+{
+	return *(volatile unsigned long *)PORT2ADDR(port);
+}
+
+unsigned char _inb_p(unsigned long port)
+{
+	unsigned char v = _inb(port);
+	delay();
+	return (v);
+}
+
+unsigned short _inw_p(unsigned long port)
+{
+	unsigned short v = _inw(port);
+	delay();
+	return (v);
+}
+
+unsigned long _inl_p(unsigned long port)
+{
+	unsigned long v = _inl(port);
+	delay();
+	return (v);
+}
+
+void _outb(unsigned char b, unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		_ne_outb(b, PORT2ADDR_NE(port));
+	else
+		*(volatile unsigned char *)PORT2ADDR(port) = b;
+}
+
+void _outw(unsigned short w, unsigned long port)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		_ne_outw(w, PORT2ADDR_NE(port));
+	else
+		*(volatile unsigned short *)PORT2ADDR(port) = w;
+}
+
+void _outl(unsigned long l, unsigned long port)
+{
+	*(volatile unsigned long *)PORT2ADDR(port) = l;
+}
+
+void _outb_p(unsigned char b, unsigned long port)
+{
+	_outb(b, port);
+	delay();
+}
+
+void _outw_p(unsigned short w, unsigned long port)
+{
+	_outw(w, port);
+	delay();
+}
+
+void _outl_p(unsigned long l, unsigned long port)
+{
+	_outl(l, port);
+	delay();
+}
+
+void _insb(unsigned int port, void *addr, unsigned long count)
+{
+	if (port >= LAN_IOSTART && port < LAN_IOEND)
+		_ne_insb(PORT2ADDR_NE(port), addr, count);
+	else {
+		unsigned char *buf = addr;
+		unsigned char *portp = PORT2ADDR(port);
+		while (count--)
+			*buf++ = *(volatile unsigned char *)portp;
+	}
+}
+
+void _insw(unsigned int port, void *addr, unsigned long count)
+{
+	unsigned short *buf = addr;
+	unsigned short *portp;
+
+	if (port >= LAN_IOSTART && port < LAN_IOEND) {
+		/*
+		 * This portion is only used by smc91111.c to read data
+		 * from the DATA_REG. Do not swap the data.
+		 */
+		portp = PORT2ADDR_NE(port);
+		while (count--)
+			*buf++ = *(volatile unsigned short *)portp;
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short),
+				count, 1);
+#endif
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		portp = __port2addr_ata(port);
+		while (count--)
+			*buf++ = *(volatile unsigned short *)portp;
+#endif
+	} else {
+		portp = PORT2ADDR(port);
+		while (count--)
+			*buf++ = *(volatile unsigned short *)portp;
+	}
+}
+
+void _insl(unsigned int port, void *addr, unsigned long count)
+{
+	unsigned long *buf = addr;
+	unsigned long *portp;
+
+	portp = PORT2ADDR(port);
+	while (count--)
+		*buf++ = *(volatile unsigned long *)portp;
+}
+
+void _outsb(unsigned int port, const void *addr, unsigned long count)
+{
+	const unsigned char *buf = addr;
+	unsigned char *portp;
+
+	if (port >= LAN_IOSTART && port < LAN_IOEND) {
+		portp = PORT2ADDR_NE(port);
+		while (count--)
+			_ne_outb(*buf++, portp);
+	} else {
+		portp = PORT2ADDR(port);
+		while (count--)
+			*(volatile unsigned char *)portp = *buf++;
+	}
+}
+
+void _outsw(unsigned int port, const void *addr, unsigned long count)
+{
+	const unsigned short *buf = addr;
+	unsigned short *portp;
+
+	if (port >= LAN_IOSTART && port < LAN_IOEND) {
+		/*
+		 * This portion is only used by smc91111.c to write data
+		 * into the DATA_REG. Do not swap the data.
+		 */
+		portp = PORT2ADDR_NE(port);
+		while (count--)
+			*(volatile unsigned short *)portp = *buf++;
+#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+		portp = __port2addr_ata(port);
+		while (count--)
+			*(volatile unsigned short *)portp = *buf++;
+#endif
+#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
+	} else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
+		pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short),
+				 count, 1);
+#endif
+	} else {
+		portp = PORT2ADDR(port);
+		while (count--)
+			*(volatile unsigned short *)portp = *buf++;
+	}
+}
+
+void _outsl(unsigned int port, const void *addr, unsigned long count)
+{
+	const unsigned long *buf = addr;
+	unsigned char *portp;
+
+	portp = PORT2ADDR(port);
+	while (count--)
+		*(volatile unsigned long *)portp = *buf++;
+}
diff --git a/arch/m32r/kernel/io_m32700ut.c b/arch/m32r/kernel/io_m32700ut.c
index eda9f96..939932d 100644
--- a/arch/m32r/kernel/io_m32700ut.c
+++ b/arch/m32r/kernel/io_m32700ut.c
@@ -36,7 +36,7 @@
 
 static inline void *_port2addr(unsigned long port)
 {
-	return (void *)(port + NONCACHE_OFFSET);
+	return (void *)(port | NONCACHE_OFFSET);
 }
 
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
@@ -45,15 +45,15 @@
 	static int	dummy_reg;
 
 	switch (port) {
-	case 0x1f0:	return (void *)0xac002000;
-	case 0x1f1:	return (void *)0xac012800;
-	case 0x1f2:	return (void *)0xac012002;
-	case 0x1f3:	return (void *)0xac012802;
-	case 0x1f4:	return (void *)0xac012004;
-	case 0x1f5:	return (void *)0xac012804;
-	case 0x1f6:	return (void *)0xac012006;
-	case 0x1f7:	return (void *)0xac012806;
-	case 0x3f6:	return (void *)0xac01200e;
+	case 0x1f0:	return (void *)(0x0c002000 | NONCACHE_OFFSET);
+	case 0x1f1:	return (void *)(0x0c012800 | NONCACHE_OFFSET);
+	case 0x1f2:	return (void *)(0x0c012002 | NONCACHE_OFFSET);
+	case 0x1f3:	return (void *)(0x0c012802 | NONCACHE_OFFSET);
+	case 0x1f4:	return (void *)(0x0c012004 | NONCACHE_OFFSET);
+	case 0x1f5:	return (void *)(0x0c012804 | NONCACHE_OFFSET);
+	case 0x1f6:	return (void *)(0x0c012006 | NONCACHE_OFFSET);
+	case 0x1f7:	return (void *)(0x0c012806 | NONCACHE_OFFSET);
+	case 0x3f6:	return (void *)(0x0c01200e | NONCACHE_OFFSET);
 	default: 	return (void *)&dummy_reg;
 	}
 }
@@ -64,8 +64,8 @@
  * from 0x10000000 to 0x13ffffff on physical address.
  * The base address of LAN controller(LAN91C111) is 0x300.
  */
-#define LAN_IOSTART	0xa0000300
-#define LAN_IOEND	0xa0000320
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
 static inline void *_port2addr_ne(unsigned long port)
 {
 	return (void *)(port + 0x10000000);
diff --git a/arch/m32r/kernel/io_mappi.c b/arch/m32r/kernel/io_mappi.c
index 3c3da04..a662b53 100644
--- a/arch/m32r/kernel/io_mappi.c
+++ b/arch/m32r/kernel/io_mappi.c
@@ -31,7 +31,7 @@
 
 static inline void *_port2addr(unsigned long port)
 {
-	return (void *)(port | (NONCACHE_OFFSET));
+	return (void *)(port | NONCACHE_OFFSET);
 }
 
 static inline void *_port2addr_ne(unsigned long port)
diff --git a/arch/m32r/kernel/io_mappi2.c b/arch/m32r/kernel/io_mappi2.c
index df3c729..e72d725 100644
--- a/arch/m32r/kernel/io_mappi2.c
+++ b/arch/m32r/kernel/io_mappi2.c
@@ -33,7 +33,7 @@
 
 static inline void *_port2addr(unsigned long port)
 {
-	return (void *)(port | (NONCACHE_OFFSET));
+	return (void *)(port | NONCACHE_OFFSET);
 }
 
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
@@ -42,22 +42,22 @@
 	static int	dummy_reg;
 
 	switch (port) {
-	case 0x1f0:	return (void *)0xac002000;
-	case 0x1f1:	return (void *)0xac012800;
-	case 0x1f2:	return (void *)0xac012002;
-	case 0x1f3:	return (void *)0xac012802;
-	case 0x1f4:	return (void *)0xac012004;
-	case 0x1f5:	return (void *)0xac012804;
-	case 0x1f6:	return (void *)0xac012006;
-	case 0x1f7:	return (void *)0xac012806;
-	case 0x3f6:	return (void *)0xac01200e;
+	case 0x1f0:	return (void *)(0x0c002000 | NONCACHE_OFFSET);
+	case 0x1f1:	return (void *)(0x0c012800 | NONCACHE_OFFSET);
+	case 0x1f2:	return (void *)(0x0c012002 | NONCACHE_OFFSET);
+	case 0x1f3:	return (void *)(0x0c012802 | NONCACHE_OFFSET);
+	case 0x1f4:	return (void *)(0x0c012004 | NONCACHE_OFFSET);
+	case 0x1f5:	return (void *)(0x0c012804 | NONCACHE_OFFSET);
+	case 0x1f6:	return (void *)(0x0c012006 | NONCACHE_OFFSET);
+	case 0x1f7:	return (void *)(0x0c012806 | NONCACHE_OFFSET);
+	case 0x3f6:	return (void *)(0x0c01200e | NONCACHE_OFFSET);
 	default: 	return (void *)&dummy_reg;
 	}
 }
 #endif
 
-#define LAN_IOSTART	0xa0000300
-#define LAN_IOEND	0xa0000320
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
 #ifdef CONFIG_CHIP_OPSP
 static inline void *_port2addr_ne(unsigned long port)
 {
diff --git a/arch/m32r/kernel/io_mappi3.c b/arch/m32r/kernel/io_mappi3.c
index 6716ffe..ed6da93 100644
--- a/arch/m32r/kernel/io_mappi3.c
+++ b/arch/m32r/kernel/io_mappi3.c
@@ -33,31 +33,52 @@
 
 static inline void *_port2addr(unsigned long port)
 {
-	return (void *)(port + NONCACHE_OFFSET);
+	return (void *)(port | NONCACHE_OFFSET);
 }
 
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
+#if defined(CONFIG_IDE)
 static inline void *__port2addr_ata(unsigned long port)
 {
 	static int	dummy_reg;
 
 	switch (port) {
-	case 0x1f0:	return (void *)0xb4002000;
-	case 0x1f1:	return (void *)0xb4012800;
-	case 0x1f2:	return (void *)0xb4012002;
-	case 0x1f3:	return (void *)0xb4012802;
-	case 0x1f4:	return (void *)0xb4012004;
-	case 0x1f5:	return (void *)0xb4012804;
-	case 0x1f6:	return (void *)0xb4012006;
-	case 0x1f7:	return (void *)0xb4012806;
-	case 0x3f6:	return (void *)0xb401200e;
+	  /* IDE0 CF */
+	case 0x1f0:	return (void *)(0x14002000 | NONCACHE_OFFSET);
+	case 0x1f1:	return (void *)(0x14012800 | NONCACHE_OFFSET);
+	case 0x1f2:	return (void *)(0x14012002 | NONCACHE_OFFSET);
+	case 0x1f3:	return (void *)(0x14012802 | NONCACHE_OFFSET);
+	case 0x1f4:	return (void *)(0x14012004 | NONCACHE_OFFSET);
+	case 0x1f5:	return (void *)(0x14012804 | NONCACHE_OFFSET);
+	case 0x1f6:	return (void *)(0x14012006 | NONCACHE_OFFSET);
+	case 0x1f7:	return (void *)(0x14012806 | NONCACHE_OFFSET);
+	case 0x3f6:	return (void *)(0x1401200e | NONCACHE_OFFSET);
+	  /* IDE1 IDE */
+	case 0x170:	/* Data 16bit */
+			return (void *)(0x14810000 | NONCACHE_OFFSET);
+	case 0x171:	/* Features / Error */
+			return (void *)(0x14810002 | NONCACHE_OFFSET);
+	case 0x172:	/* Sector count */
+			return (void *)(0x14810004 | NONCACHE_OFFSET);
+	case 0x173:	/* Sector number */
+			return (void *)(0x14810006 | NONCACHE_OFFSET);
+	case 0x174:	/* Cylinder low */
+			return (void *)(0x14810008 | NONCACHE_OFFSET);
+	case 0x175:	/* Cylinder high */
+			return (void *)(0x1481000a | NONCACHE_OFFSET);
+	case 0x176:	/* Device head */
+			return (void *)(0x1481000c | NONCACHE_OFFSET);
+	case 0x177:	/* Command     */
+			return (void *)(0x1481000e | NONCACHE_OFFSET);
+	case 0x376:	/* Device control / Alt status */
+			return (void *)(0x1480800c | NONCACHE_OFFSET);
+
 	default: 	return (void *)&dummy_reg;
 	}
 }
 #endif
 
-#define LAN_IOSTART	0xa0000300
-#define LAN_IOEND	0xa0000320
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
 static inline void *_port2addr_ne(unsigned long port)
 {
 	return (void *)(port + 0x10000000);
@@ -108,8 +129,9 @@
 {
 	if (port >= LAN_IOSTART && port < LAN_IOEND)
 		return _ne_inb(PORT2ADDR_NE(port));
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+	else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+		  ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
 		return *(volatile unsigned char *)__port2addr_ata(port);
 	}
 #endif
@@ -127,8 +149,9 @@
 {
 	if (port >= LAN_IOSTART && port < LAN_IOEND)
 		return _ne_inw(PORT2ADDR_NE(port));
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+	else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+		  ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
 		return *(volatile unsigned short *)__port2addr_ata(port);
 	}
 #endif
@@ -185,8 +208,9 @@
 	if (port >= LAN_IOSTART && port < LAN_IOEND)
 		_ne_outb(b, PORT2ADDR_NE(port));
 	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+	if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+		  ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
 		*(volatile unsigned char *)__port2addr_ata(port) = b;
 	} else
 #endif
@@ -203,8 +227,9 @@
 	if (port >= LAN_IOSTART && port < LAN_IOEND)
 		_ne_outw(w, PORT2ADDR_NE(port));
 	else
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+	if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+		  ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
 		*(volatile unsigned short *)__port2addr_ata(port) = w;
 	} else
 #endif
@@ -253,8 +278,9 @@
 {
 	if (port >= LAN_IOSTART && port < LAN_IOEND)
 		_ne_insb(PORT2ADDR_NE(port), addr, count);
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+	else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+		  ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
 		unsigned char *buf = addr;
 		unsigned char *portp = __port2addr_ata(port);
 		while (count--)
@@ -289,8 +315,9 @@
 		pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short),
 				count, 1);
 #endif
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+	} else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+		  ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
 		portp = __port2addr_ata(port);
 		while (count--)
 			*buf++ = *(volatile unsigned short *)portp;
@@ -321,8 +348,9 @@
 		portp = PORT2ADDR_NE(port);
 		while (count--)
 			_ne_outb(*buf++, portp);
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+	} else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+		  ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
 		portp = __port2addr_ata(port);
 		while (count--)
 			*(volatile unsigned char *)portp = *buf++;
@@ -348,8 +376,9 @@
 		portp = PORT2ADDR_NE(port);
 		while (count--)
 			*(volatile unsigned short *)portp = *buf++;
-#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
-	} else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
+#if defined(CONFIG_IDE)
+	} else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) ||
+		  ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){
 		portp = __port2addr_ata(port);
 		while (count--)
 			*(volatile unsigned short *)portp = *buf++;
diff --git a/arch/m32r/kernel/io_oaks32r.c b/arch/m32r/kernel/io_oaks32r.c
index 8be3239..910dd13 100644
--- a/arch/m32r/kernel/io_oaks32r.c
+++ b/arch/m32r/kernel/io_oaks32r.c
@@ -16,7 +16,7 @@
 
 static inline void *_port2addr(unsigned long port)
 {
-	return (void *)(port | (NONCACHE_OFFSET));
+	return (void *)(port | NONCACHE_OFFSET);
 }
 
 static inline  void *_port2addr_ne(unsigned long port)
diff --git a/arch/m32r/kernel/io_opsput.c b/arch/m32r/kernel/io_opsput.c
index 4793bd1..bec6929 100644
--- a/arch/m32r/kernel/io_opsput.c
+++ b/arch/m32r/kernel/io_opsput.c
@@ -36,7 +36,7 @@
 
 static inline void *_port2addr(unsigned long port)
 {
-	return (void *)(port | (NONCACHE_OFFSET));
+	return (void *)(port | NONCACHE_OFFSET);
 }
 
 /*
@@ -44,8 +44,8 @@
  * from 0x10000000 to 0x13ffffff on physical address.
  * The base address of LAN controller(LAN91C111) is 0x300.
  */
-#define LAN_IOSTART	0xa0000300
-#define LAN_IOEND	0xa0000320
+#define LAN_IOSTART	(0x300 | NONCACHE_OFFSET)
+#define LAN_IOEND	(0x320 | NONCACHE_OFFSET)
 static inline void *_port2addr_ne(unsigned long port)
 {
 	return (void *)(port + 0x10000000);
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index cc4b571..3bf55d9 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -50,6 +50,10 @@
  * Powermanagement idle function, if any..
  */
 void (*pm_idle)(void) = NULL;
+EXPORT_SYMBOL(pm_idle);
+
+void (*pm_power_off)(void) = NULL;
+EXPORT_SYMBOL(pm_power_off);
 
 void disable_hlt(void)
 {
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 078d2a0..9b75caa 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -762,28 +762,16 @@
 	int ret;
 
 	lock_kernel();
-	ret = -EPERM;
 	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
+		ret = ptrace_traceme();
 		goto out;
 	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
 
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
 		goto out;
+	}
 
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c
index f722ec8..c2e4dcc 100644
--- a/arch/m32r/kernel/setup.c
+++ b/arch/m32r/kernel/setup.c
@@ -320,6 +320,9 @@
 #elif defined(CONFIG_CHIP_MP)
 	seq_printf(m, "cpu family\t: M32R-MP\n"
 		"cache size\t: I-xxKB/D-xxKB\n");
+#elif  defined(CONFIG_CHIP_M32104)
+	seq_printf(m,"cpu family\t: M32104\n"
+		"cache size\t: I-8KB/D-8KB\n");
 #else
 	seq_printf(m, "cpu family\t: Unknown\n");
 #endif
@@ -340,6 +343,8 @@
 	seq_printf(m, "Machine\t\t: uServer\n");
 #elif defined(CONFIG_PLAT_OAKS32R)
 	seq_printf(m, "Machine\t\t: OAKS32R\n");
+#elif  defined(CONFIG_PLAT_M32104UT)
+	seq_printf(m, "Machine\t\t: M3T-M32104UT uT Engine board\n");
 #else
 	seq_printf(m, "Machine\t\t: Unknown\n");
 #endif
@@ -389,7 +394,7 @@
  */
 #if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2)	\
 	|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
-	|| defined(CONFIG_CHIP_OPSP)
+	|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
 void __init cpu_init (void)
 {
 	int cpu_id = smp_processor_id();
diff --git a/arch/m32r/kernel/setup_m32104ut.c b/arch/m32r/kernel/setup_m32104ut.c
new file mode 100644
index 0000000..6328e13
--- /dev/null
+++ b/arch/m32r/kernel/setup_m32104ut.c
@@ -0,0 +1,156 @@
+/*
+ *  linux/arch/m32r/kernel/setup_m32104ut.c
+ *
+ *  Setup routines for M32104UT Board
+ *
+ *  Copyright (c) 2002-2005  Hiroyuki Kondo, Hirokazu Takata,
+ *                           Hitoshi Yamamoto, Mamoru Sakugawa,
+ *                           Naoto Sugai, Hayato Fujiwara
+ */
+
+#include <linux/config.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/system.h>
+#include <asm/m32r.h>
+#include <asm/io.h>
+
+#define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
+
+icu_data_t icu_data[NR_IRQS];
+
+static void disable_m32104ut_irq(unsigned int irq)
+{
+	unsigned long port, data;
+
+	port = irq2port(irq);
+	data = icu_data[irq].icucr|M32R_ICUCR_ILEVEL7;
+	outl(data, port);
+}
+
+static void enable_m32104ut_irq(unsigned int irq)
+{
+	unsigned long port, data;
+
+	port = irq2port(irq);
+	data = icu_data[irq].icucr|M32R_ICUCR_IEN|M32R_ICUCR_ILEVEL6;
+	outl(data, port);
+}
+
+static void mask_and_ack_m32104ut(unsigned int irq)
+{
+	disable_m32104ut_irq(irq);
+}
+
+static void end_m32104ut_irq(unsigned int irq)
+{
+	enable_m32104ut_irq(irq);
+}
+
+static unsigned int startup_m32104ut_irq(unsigned int irq)
+{
+	enable_m32104ut_irq(irq);
+	return (0);
+}
+
+static void shutdown_m32104ut_irq(unsigned int irq)
+{
+	unsigned long port;
+
+	port = irq2port(irq);
+	outl(M32R_ICUCR_ILEVEL7, port);
+}
+
+static struct hw_interrupt_type m32104ut_irq_type =
+{
+	.typename = "M32104UT-IRQ",
+	.startup = startup_m32104ut_irq,
+	.shutdown = shutdown_m32104ut_irq,
+	.enable = enable_m32104ut_irq,
+	.disable = disable_m32104ut_irq,
+	.ack = mask_and_ack_m32104ut,
+	.end = end_m32104ut_irq
+};
+
+void __init init_IRQ(void)
+{
+	static int once = 0;
+
+	if (once)
+		return;
+	else
+		once++;
+
+#if defined(CONFIG_SMC91X)
+	/* INT#0: LAN controller on M32104UT-LAN (SMC91C111)*/
+	irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_INT0].handler = &m32104ut_irq_type;
+	irq_desc[M32R_IRQ_INT0].action = 0;
+	irq_desc[M32R_IRQ_INT0].depth = 1;
+	icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD11; /* "H" level sense */
+	disable_m32104ut_irq(M32R_IRQ_INT0);
+#endif  /* CONFIG_SMC91X */
+
+	/* MFT2 : system timer */
+	irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_MFT2].handler = &m32104ut_irq_type;
+	irq_desc[M32R_IRQ_MFT2].action = 0;
+	irq_desc[M32R_IRQ_MFT2].depth = 1;
+	icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN;
+	disable_m32104ut_irq(M32R_IRQ_MFT2);
+
+#ifdef CONFIG_SERIAL_M32R_SIO
+	/* SIO0_R : uart receive data */
+	irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_SIO0_R].handler = &m32104ut_irq_type;
+	irq_desc[M32R_IRQ_SIO0_R].action = 0;
+	irq_desc[M32R_IRQ_SIO0_R].depth = 1;
+	icu_data[M32R_IRQ_SIO0_R].icucr = M32R_ICUCR_IEN;
+	disable_m32104ut_irq(M32R_IRQ_SIO0_R);
+
+	/* SIO0_S : uart send data */
+	irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED;
+	irq_desc[M32R_IRQ_SIO0_S].handler = &m32104ut_irq_type;
+	irq_desc[M32R_IRQ_SIO0_S].action = 0;
+	irq_desc[M32R_IRQ_SIO0_S].depth = 1;
+	icu_data[M32R_IRQ_SIO0_S].icucr = M32R_ICUCR_IEN;
+	disable_m32104ut_irq(M32R_IRQ_SIO0_S);
+#endif /* CONFIG_SERIAL_M32R_SIO */
+}
+
+#if defined(CONFIG_SMC91X)
+
+#define LAN_IOSTART     0x300
+#define LAN_IOEND       0x320
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.start  = (LAN_IOSTART),
+		.end    = (LAN_IOEND),
+		.flags  = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start  = M32R_IRQ_INT0,
+		.end    = M32R_IRQ_INT0,
+		.flags  = IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= 0,
+	.num_resources  = ARRAY_SIZE(smc91x_resources),
+	.resource       = smc91x_resources,
+};
+#endif
+
+static int __init platform_init(void)
+{
+#if defined(CONFIG_SMC91X)
+	platform_device_register(&smc91x_device);
+#endif
+	return 0;
+}
+arch_initcall(platform_init);
diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c
index cb76916..fad1fc9 100644
--- a/arch/m32r/kernel/setup_m32700ut.c
+++ b/arch/m32r/kernel/setup_m32700ut.c
@@ -26,15 +26,7 @@
  */
 #define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
 
-#ifndef CONFIG_SMP
-typedef struct {
-	unsigned long icucr;  /* ICU Control Register */
-} icu_data_t;
-static icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
-#else
 icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
-#endif /* CONFIG_SMP */
-
 
 static void disable_m32700ut_irq(unsigned int irq)
 {
diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c
index 501d798..00f2532 100644
--- a/arch/m32r/kernel/setup_mappi.c
+++ b/arch/m32r/kernel/setup_mappi.c
@@ -19,12 +19,6 @@
 
 #define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
 
-#ifndef CONFIG_SMP
-typedef struct {
-	unsigned long icucr;  /* ICU Control Register */
-} icu_data_t;
-#endif /* CONFIG_SMP */
-
 icu_data_t icu_data[NR_IRQS];
 
 static void disable_mappi_irq(unsigned int irq)
diff --git a/arch/m32r/kernel/setup_mappi2.c b/arch/m32r/kernel/setup_mappi2.c
index 7f2db5b..eebc9d8 100644
--- a/arch/m32r/kernel/setup_mappi2.c
+++ b/arch/m32r/kernel/setup_mappi2.c
@@ -19,12 +19,6 @@
 
 #define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
 
-#ifndef CONFIG_SMP
-typedef struct {
-	unsigned long icucr;  /* ICU Control Register */
-} icu_data_t;
-#endif /* CONFIG_SMP */
-
 icu_data_t icu_data[NR_IRQS];
 
 static void disable_mappi2_irq(unsigned int irq)
diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c
index 9c79341..d2ff021 100644
--- a/arch/m32r/kernel/setup_mappi3.c
+++ b/arch/m32r/kernel/setup_mappi3.c
@@ -19,12 +19,6 @@
 
 #define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
 
-#ifndef CONFIG_SMP
-typedef struct {
-	unsigned long icucr;  /* ICU Control Register */
-} icu_data_t;
-#endif /* CONFIG_SMP */
-
 icu_data_t icu_data[NR_IRQS];
 
 static void disable_mappi3_irq(unsigned int irq)
@@ -151,7 +145,7 @@
 	disable_mappi3_irq(M32R_IRQ_INT1);
 #endif /* CONFIG_USB */
 
-	/* ICUCR40: CFC IREQ */
+	/* CFC IREQ */
 	irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED;
 	irq_desc[PLD_IRQ_CFIREQ].handler = &mappi3_irq_type;
 	irq_desc[PLD_IRQ_CFIREQ].action = 0;
@@ -160,7 +154,7 @@
 	disable_mappi3_irq(PLD_IRQ_CFIREQ);
 
 #if defined(CONFIG_M32R_CFC)
-	/* ICUCR41: CFC Insert */
+	/* ICUCR41: CFC Insert & eject */
 	irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED;
 	irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi3_irq_type;
 	irq_desc[PLD_IRQ_CFC_INSERT].action = 0;
@@ -168,14 +162,16 @@
 	icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00;
 	disable_mappi3_irq(PLD_IRQ_CFC_INSERT);
 
-	/* ICUCR42: CFC Eject */
-	irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED;
-	irq_desc[PLD_IRQ_CFC_EJECT].handler = &mappi3_irq_type;
-	irq_desc[PLD_IRQ_CFC_EJECT].action = 0;
-	irq_desc[PLD_IRQ_CFC_EJECT].depth = 1;	/* disable nested irq */
-	icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
-	disable_mappi3_irq(PLD_IRQ_CFC_EJECT);
 #endif /* CONFIG_M32R_CFC */
+
+	/* IDE IREQ */
+	irq_desc[PLD_IRQ_IDEIREQ].status = IRQ_DISABLED;
+	irq_desc[PLD_IRQ_IDEIREQ].handler = &mappi3_irq_type;
+	irq_desc[PLD_IRQ_IDEIREQ].action = 0;
+	irq_desc[PLD_IRQ_IDEIREQ].depth = 1;	/* disable nested irq */
+	icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10;
+	disable_mappi3_irq(PLD_IRQ_IDEIREQ);
+
 }
 
 #if defined(CONFIG_SMC91X)
diff --git a/arch/m32r/kernel/setup_oaks32r.c b/arch/m32r/kernel/setup_oaks32r.c
index 45add5b..0e9e635 100644
--- a/arch/m32r/kernel/setup_oaks32r.c
+++ b/arch/m32r/kernel/setup_oaks32r.c
@@ -18,12 +18,6 @@
 
 #define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
 
-#ifndef CONFIG_SMP
-typedef struct {
-	unsigned long icucr;  /* ICU Control Register */
-} icu_data_t;
-#endif /* CONFIG_SMP */
-
 icu_data_t icu_data[NR_IRQS];
 
 static void disable_oaks32r_irq(unsigned int irq)
diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c
index 1fbb140..548e8fc 100644
--- a/arch/m32r/kernel/setup_opsput.c
+++ b/arch/m32r/kernel/setup_opsput.c
@@ -27,15 +27,7 @@
  */
 #define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
 
-#ifndef CONFIG_SMP
-typedef struct {
-	unsigned long icucr;  /* ICU Control Register */
-} icu_data_t;
-static icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
-#else
 icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ];
-#endif /* CONFIG_SMP */
-
 
 static void disable_opsput_irq(unsigned int irq)
 {
diff --git a/arch/m32r/kernel/setup_usrv.c b/arch/m32r/kernel/setup_usrv.c
index 634741b..64be659 100644
--- a/arch/m32r/kernel/setup_usrv.c
+++ b/arch/m32r/kernel/setup_usrv.c
@@ -18,12 +18,6 @@
 
 #define irq2port(x) (M32R_ICU_CR1_PORTL + ((x - 1) * sizeof(unsigned long)))
 
-#if !defined(CONFIG_SMP)
-typedef struct {
-	unsigned long icucr;	/* ICU Control Register */
-} icu_data_t;
-#endif /* CONFIG_SMP */
-
 icu_data_t icu_data[M32700UT_NUM_CPU_IRQ];
 
 static void disable_mappi_irq(unsigned int irq)
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index e0500e1..fe55b28 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -41,7 +41,8 @@
 		return -EFAULT;
 	local_irq_save(flags);
 	oldval = *addr;
-	*addr = 1;
+	if (!oldval)
+		*addr = 1;
 	local_irq_restore(flags);
 	return oldval;
 }
@@ -59,7 +60,8 @@
 
 	_raw_spin_lock(&tas_lock);
 	oldval = *addr;
-	*addr = 1;
+	if (!oldval)
+		*addr = 1;
 	_raw_spin_unlock(&tas_lock);
 
 	return oldval;
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index 2ebce20..b8e68b5 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -57,7 +57,7 @@
 
 #if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
 	|| defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
-	|| defined(CONFIG_CHIP_OPSP)
+	|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
 #ifndef CONFIG_SMP
 
 	unsigned long count;
@@ -268,7 +268,7 @@
 
 #if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
 	|| defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
-	|| defined(CONFIG_CHIP_OPSP)
+	|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
 
 	/* M32102 MFT setup */
 	setup_irq(M32R_IRQ_MFT2, &irq0);
diff --git a/arch/m32r/m32104ut/defconfig.m32104ut b/arch/m32r/m32104ut/defconfig.m32104ut
new file mode 100644
index 0000000..454de33
--- /dev/null
+++ b/arch/m32r/m32104ut/defconfig.m32104ut
@@ -0,0 +1,657 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.14
+# Wed Nov  9 16:04:51 2005
+#
+CONFIG_M32R=y
+# CONFIG_UID16 is not set
+CONFIG_GENERIC_ISA_DMA=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+# CONFIG_KOBJECT_UEVENT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+# CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Processor type and features
+#
+# CONFIG_PLAT_MAPPI is not set
+# CONFIG_PLAT_USRV is not set
+# CONFIG_PLAT_M32700UT is not set
+# CONFIG_PLAT_OPSPUT is not set
+# CONFIG_PLAT_OAKS32R is not set
+# CONFIG_PLAT_MAPPI2 is not set
+# CONFIG_PLAT_MAPPI3 is not set
+CONFIG_PLAT_M32104UT=y
+# CONFIG_CHIP_M32700 is not set
+# CONFIG_CHIP_M32102 is not set
+CONFIG_CHIP_M32104=y
+# CONFIG_CHIP_VDEC2 is not set
+# CONFIG_CHIP_OPSP is not set
+CONFIG_ISA_M32R=y
+CONFIG_BUS_CLOCK=54000000
+CONFIG_TIMER_DIVIDE=128
+# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_MEMORY_START=04000000
+CONFIG_MEMORY_SIZE=01000000
+CONFIG_NOHIGHMEM=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+# CONFIG_PREEMPT is not set
+# CONFIG_SMP is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_ISA is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_IOCTL=y
+
+#
+# PC-card bridges
+#
+
+#
+# PCI Hotplug Support
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_SMC91X=y
+# CONFIG_NE2000 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_M32R_SIO=y
+CONFIG_SERIAL_M32R_SIO_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+CONFIG_SOFT_WATCHDOG=y
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia Capabilities Port drivers
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB_ARCH_HAS_HCD is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+
+#
+# SN Devices
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=932
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+CONFIG_NLS_CODEPAGE_932=y
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
diff --git a/arch/m32r/mm/cache.c b/arch/m32r/mm/cache.c
index 31b0789..9f54dd9 100644
--- a/arch/m32r/mm/cache.c
+++ b/arch/m32r/mm/cache.c
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/m32r/mm/cache.c
  *
- *  Copyright (C) 2002  Hirokazu Takata
+ *  Copyright (C) 2002-2005  Hirokazu Takata, Hayato Fujiwara
  */
 
 #include <linux/config.h>
@@ -9,7 +9,8 @@
 
 #undef MCCR
 
-#if defined(CONFIG_CHIP_XNUX2) || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_OPSP)
+#if defined(CONFIG_CHIP_XNUX2) || defined(CONFIG_CHIP_M32700) \
+	|| defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_OPSP)
 /* Cache Control Register */
 #define MCCR		((volatile unsigned long*)0xfffffffc)
 #define MCCR_CC		(1UL << 7)	/* Cache mode modify bit */
@@ -26,7 +27,17 @@
 #define MCCR		((volatile unsigned char*)0xfffffffe)
 #define MCCR_IIV	(1UL << 0)	/* I-cache invalidate */
 #define MCCR_ICACHE_INV		MCCR_IIV
-#endif /* CONFIG_CHIP_XNUX2 || CONFIG_CHIP_M32700 */
+#elif defined(CONFIG_CHIP_M32104)
+#define MCCR		((volatile unsigned short*)0xfffffffe)
+#define MCCR_IIV	(1UL << 8)	/* I-cache invalidate */
+#define MCCR_DIV	(1UL << 9)	/* D-cache invalidate */
+#define MCCR_DCB	(1UL << 10)	/* D-cache copy back */
+#define MCCR_ICM	(1UL << 0)	/* I-cache mode [0:off,1:on] */
+#define MCCR_DCM	(1UL << 1)	/* D-cache mode [0:off,1:on] */
+#define MCCR_ICACHE_INV		MCCR_IIV
+#define MCCR_DCACHE_CB		MCCR_DCB
+#define MCCR_DCACHE_CBINV	(MCCR_DIV|MCCR_DCB)
+#endif
 
 #ifndef MCCR
 #error Unknown cache type.
@@ -37,29 +48,42 @@
 void _flush_cache_all(void)
 {
 #if defined(CONFIG_CHIP_M32102)
+	unsigned char mccr;
 	*MCCR = MCCR_ICACHE_INV;
+#elif defined(CONFIG_CHIP_M32104)
+	unsigned short mccr;
+
+	/* Copyback and invalidate D-cache */
+	/* Invalidate I-cache */
+	*MCCR |= (MCCR_ICACHE_INV | MCCR_DCACHE_CBINV);
 #else
 	unsigned long mccr;
 
 	/* Copyback and invalidate D-cache */
 	/* Invalidate I-cache */
 	*MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CBINV;
-	while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
 #endif
+	while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
 }
 
 /* Copy back D-cache and invalidate I-cache all */
 void _flush_cache_copyback_all(void)
 {
 #if defined(CONFIG_CHIP_M32102)
+	unsigned char mccr;
 	*MCCR = MCCR_ICACHE_INV;
+#elif defined(CONFIG_CHIP_M32104)
+	unsigned short mccr;
+
+	/* Copyback and invalidate D-cache */
+	/* Invalidate I-cache */
+	*MCCR |= (MCCR_ICACHE_INV | MCCR_DCACHE_CB);
 #else
 	unsigned long mccr;
 
 	/* Copyback D-cache */
 	/* Invalidate I-cache */
 	*MCCR = MCCR_ICACHE_INV | MCCR_DCACHE_CB;
-	while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
-
 #endif
+	while ((mccr = *MCCR) & MCCR_IIV); /* loop while invalidating... */
 }
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 1dd5d18..96b9198 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -10,10 +10,6 @@
 	bool
 	default y
 
-config UID16
-	bool
-	default y
-
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index b964981..e2a6e86 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -17,10 +17,6 @@
 	bool
 	default n
 
-config UID16
-	bool
-	default y
-
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c
index e93a5ad..b2c62ee 100644
--- a/arch/m68knommu/kernel/m68k_ksyms.c
+++ b/arch/m68knommu/kernel/m68k_ksyms.c
@@ -38,8 +38,6 @@
 
 EXPORT_SYMBOL(ip_fast_csum);
 
-EXPORT_SYMBOL(mach_enable_irq);
-EXPORT_SYMBOL(mach_disable_irq);
 EXPORT_SYMBOL(kernel_thread);
 
 /* Networking helper routines. */
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index abb80fa..93120b9 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -65,8 +65,6 @@
 /* machine dependent irq functions */
 void (*mach_init_IRQ) (void) = NULL;
 irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
-void (*mach_enable_irq) (unsigned int) = NULL;
-void (*mach_disable_irq) (unsigned int) = NULL;
 int (*mach_get_irq_list) (struct seq_file *, void *) = NULL;
 void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL;
 void (*mach_trap_init) (void);
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index e380a83..b50be44 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -6,8 +6,6 @@
 
 mainmenu "Linux/MIPS Kernel Configuration"
 
-source "init/Kconfig"
-
 menu "Machine selection"
 
 choice
@@ -1643,6 +1641,8 @@
 	bool
 	default y
 
+source "init/Kconfig"
+
 menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
 
 config HW_HAS_EISA
diff --git a/arch/mips/au1000/db1x00/board_setup.c b/arch/mips/au1000/db1x00/board_setup.c
index ac05ba0..f00ec3b 100644
--- a/arch/mips/au1000/db1x00/board_setup.c
+++ b/arch/mips/au1000/db1x00/board_setup.c
@@ -45,13 +45,12 @@
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-db1x00/db1x00.h>
 
-/* not correct for db1550 */
-static BCSR * const bcsr = (BCSR *)0xAE000000;
+static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 
 void board_reset (void)
 {
 	/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
-	au_writel(0x00000000, 0xAE00001C);
+	bcsr->swreset = 0x0000;
 }
 
 void __init board_setup(void)
@@ -75,7 +74,7 @@
 	bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
 	au_sync();
 #endif
-	au_writel(0, 0xAE000010); /* turn off pcmcia power */
+	bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */
 
 #ifdef CONFIG_MIPS_MIRAGE
 	/* enable GPIO[31:0] inputs */
diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c
index 4b9d5e4..41e0522 100644
--- a/arch/mips/au1000/db1x00/init.c
+++ b/arch/mips/au1000/db1x00/init.c
@@ -61,7 +61,17 @@
 	prom_envp = (char **) fw_arg2;
 
 	mips_machgroup = MACH_GROUP_ALCHEMY;
-	mips_machtype = MACH_DB1000;	/* set the platform # */
+
+	/* Set the platform # */
+#if	defined (CONFIG_MIPS_DB1550)
+	mips_machtype = MACH_DB1550;
+#elif	defined (CONFIG_MIPS_DB1500)
+	mips_machtype = MACH_DB1500;
+#elif	defined (CONFIG_MIPS_DB1100)
+	mips_machtype = MACH_DB1100;
+#else
+	mips_machtype = MACH_DB1000;
+#endif
 
 	prom_init_cmdline();
 
diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig
index 7499075..89c2157 100644
--- a/arch/mips/configs/atlas_defconfig
+++ b/arch/mips/configs/atlas_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Thu Nov 10 12:14:02 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:05:52 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -215,6 +146,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index ea4b756..069f9d1 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -1,83 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:04:36 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:05:54 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_CPUSETS is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -224,6 +152,78 @@
 # CONFIG_PREEMPT_BKL is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -318,7 +318,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig
index a86cc9d..5261e29 100644
--- a/arch/mips/configs/capcella_defconfig
+++ b/arch/mips/configs/capcella_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:04:39 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:05:55 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -206,6 +137,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -294,7 +294,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig
index 3558c79..216f402 100644
--- a/arch/mips/configs/cobalt_defconfig
+++ b/arch/mips/configs/cobalt_defconfig
@@ -1,74 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:04:42 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:05:57 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -196,6 +133,69 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -280,7 +280,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 3b103fe..18ac792 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:11:04 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:05:59 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -202,6 +133,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -320,7 +320,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -668,6 +667,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index 79cdd94..4f55f74 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:11:07 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:00 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -202,6 +133,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_MMU=y
@@ -309,7 +309,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -636,6 +635,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index b6bad69..0e5de7d 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:11:10 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:03 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -203,6 +133,76 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_MMU=y
@@ -314,7 +314,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -475,7 +474,6 @@
 CONFIG_BLK_DEV_IDE_AU1XXX=y
 CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA=y
 # CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA is not set
-# CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON is not set
 CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ=128
 # CONFIG_IDE_ARM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
@@ -709,6 +707,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index dbaf189..86e7be8 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:11:15 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:05 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -204,6 +135,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -328,7 +328,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 59c1ef21..ea5ab0c 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:11:18 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:07 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -203,6 +134,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -327,7 +327,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/ddb5476_defconfig b/arch/mips/configs/ddb5476_defconfig
index 4ba29e6..bea00a9 100644
--- a/arch/mips/configs/ddb5476_defconfig
+++ b/arch/mips/configs/ddb5476_defconfig
@@ -1,74 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:04 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:09 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -197,6 +134,69 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -285,7 +285,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig
index ea4e904..61f7171 100644
--- a/arch/mips/configs/ddb5477_defconfig
+++ b/arch/mips/configs/ddb5477_defconfig
@@ -1,74 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:08 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:11 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -197,6 +134,69 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -284,7 +284,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 1ac6c9b..08a4de6 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Fri Nov 11 13:29:30 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:13 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -202,6 +132,76 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_TC=y
@@ -286,7 +286,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -531,6 +530,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig
index a89d2f6..c9070ce 100644
--- a/arch/mips/configs/e55_defconfig
+++ b/arch/mips/configs/e55_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:15 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:14 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -204,6 +135,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_ISA=y
@@ -286,7 +286,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -577,6 +576,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig
index e6c3c27..14e3815 100644
--- a/arch/mips/configs/ev64120_defconfig
+++ b/arch/mips/configs/ev64120_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Wed Nov  9 11:05:12 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:16 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_KMOD is not set
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -205,6 +136,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -291,7 +291,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/ev96100_defconfig b/arch/mips/configs/ev96100_defconfig
index 52ca6bf..5108195 100644
--- a/arch/mips/configs/ev96100_defconfig
+++ b/arch/mips/configs/ev96100_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:22 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:18 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_KMOD is not set
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -209,6 +140,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -293,7 +293,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -531,6 +530,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig
index 79e3fe7..67979e3 100644
--- a/arch/mips/configs/ip22_defconfig
+++ b/arch/mips/configs/ip22_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Thu Nov 10 13:38:41 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:20 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -211,6 +141,76 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_EISA=y
@@ -779,6 +779,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 72998ec..03af44d 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -1,82 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Sun Nov 13 23:56:52 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:21 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_CPUSETS=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -213,6 +142,77 @@
 # CONFIG_MIPS_INSANE_LARGE is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 955e30f..cba2a49 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -1,74 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:32 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:24 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -202,6 +139,69 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -294,7 +294,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/it8172_defconfig b/arch/mips/configs/it8172_defconfig
index f631385..e7ee167 100644
--- a/arch/mips/configs/it8172_defconfig
+++ b/arch/mips/configs/it8172_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Thu Nov 10 13:42:45 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:26 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -205,6 +135,76 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -290,7 +290,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -628,6 +627,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/ivr_defconfig b/arch/mips/configs/ivr_defconfig
index 8d94ac7..138c8a6 100644
--- a/arch/mips/configs/ivr_defconfig
+++ b/arch/mips/configs/ivr_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:38 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:27 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -202,6 +132,76 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -289,7 +289,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig
index a8b4c9a..6238e0d 100644
--- a/arch/mips/configs/jaguar-atx_defconfig
+++ b/arch/mips/configs/jaguar-atx_defconfig
@@ -1,78 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:41 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:29 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -209,6 +142,73 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -283,7 +283,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig
index c0ac5c7..a8ded3d 100644
--- a/arch/mips/configs/jmr3927_defconfig
+++ b/arch/mips/configs/jmr3927_defconfig
@@ -1,74 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:44 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:31 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -193,6 +130,69 @@
 CONFIG_RTC_DS1742=y
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -280,7 +280,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig
index f2bd620..a7ad99b 100644
--- a/arch/mips/configs/lasat200_defconfig
+++ b/arch/mips/configs/lasat200_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:47 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:33 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -208,6 +139,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -291,7 +291,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index e48e1de..d1c4421 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Thu Nov 10 13:42:55 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:35 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -221,6 +152,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 04abd1b..ac39ab7 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:05:55 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:37 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -208,6 +138,76 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_MMU=y
@@ -558,6 +558,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig
index 46814be..2b5ea37 100644
--- a/arch/mips/configs/mpc30x_defconfig
+++ b/arch/mips/configs/mpc30x_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:12:01 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:39 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -206,6 +137,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -304,7 +304,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig
index e12118c..9081ea5 100644
--- a/arch/mips/configs/ocelot_3_defconfig
+++ b/arch/mips/configs/ocelot_3_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Thu Nov 10 14:01:36 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:41 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -212,6 +142,76 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -333,7 +333,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig
index 99f0c98..570fc4d 100644
--- a/arch/mips/configs/ocelot_c_defconfig
+++ b/arch/mips/configs/ocelot_c_defconfig
@@ -1,73 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:06:05 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:43 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -199,6 +137,68 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -290,7 +290,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig
index 11c7d74..6634ab2 100644
--- a/arch/mips/configs/ocelot_defconfig
+++ b/arch/mips/configs/ocelot_defconfig
@@ -1,74 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:06:08 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:44 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -205,6 +142,69 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -289,7 +289,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -527,6 +526,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig
index 9ced1a9..4c396e1 100644
--- a/arch/mips/configs/ocelot_g_defconfig
+++ b/arch/mips/configs/ocelot_g_defconfig
@@ -1,73 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:06:11 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:46 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -202,6 +140,68 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -293,7 +293,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index dbcaa77..883626a 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:12:31 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:48 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -204,6 +135,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -322,7 +322,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -662,6 +661,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index 5b685ce..f8fbc77 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:14:25 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:50 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -203,6 +134,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -328,7 +328,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index f8f32e9..3d694cd 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:15:34 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:52 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -203,6 +134,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -328,7 +328,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig
index 5820e5f..fba624a 100644
--- a/arch/mips/configs/pnx8550-jbs_defconfig
+++ b/arch/mips/configs/pnx8550-jbs_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:06:25 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:54 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -203,6 +133,76 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -289,7 +289,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig
index a4ebb53..d9a0d2f 100644
--- a/arch/mips/configs/pnx8550-v2pci_defconfig
+++ b/arch/mips/configs/pnx8550-v2pci_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Thu Nov 10 14:02:38 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:06:58 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -204,6 +135,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -321,7 +321,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig
index 5d39162..dee4460 100644
--- a/arch/mips/configs/qemu_defconfig
+++ b/arch/mips/configs/qemu_defconfig
@@ -1,73 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:06:31 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:07:00 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-# CONFIG_SWAP is not set
-# CONFIG_SYSVIPC is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-# CONFIG_BUG is not set
-# CONFIG_BASE_FULL is not set
-# CONFIG_FUTEX is not set
-# CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SHMEM is not set
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-CONFIG_TINY_SHMEM=y
-CONFIG_BASE_SMALL=1
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -192,6 +130,68 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+# CONFIG_BUG is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+# CONFIG_SHMEM is not set
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=1
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_ISA=y
@@ -258,7 +258,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 047e0b4..1cc1450 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Thu Nov 10 14:02:45 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:07:03 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-# CONFIG_KOBJECT_UEVENT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-# CONFIG_FUTEX is not set
-# CONFIG_EPOLL is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -212,6 +143,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+# CONFIG_KOBJECT_UEVENT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -333,7 +333,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index 5545806..30975b3 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -1,82 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Thu Nov 10 14:02:50 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:07:06 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -214,6 +143,77 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_EISA=y
@@ -1199,6 +1199,7 @@
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_AIRPRIME=m
+CONFIG_USB_SERIAL_ANYDATA=m
 CONFIG_USB_SERIAL_BELKIN=m
 CONFIG_USB_SERIAL_WHITEHEAT=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
@@ -1230,7 +1231,6 @@
 CONFIG_USB_SERIAL_KLSI=m
 CONFIG_USB_SERIAL_KOBIL_SCT=m
 CONFIG_USB_SERIAL_MCT_U232=m
-# CONFIG_USB_SERIAL_NOKIA_DKU2 is not set
 CONFIG_USB_SERIAL_PL2303=m
 CONFIG_USB_SERIAL_HP4X=m
 CONFIG_USB_SERIAL_SAFE=m
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index dc453a1..63f1be1 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:06:43 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:07:09 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_CPUSETS=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -226,6 +156,76 @@
 CONFIG_PREEMPT_BKL=y
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_CPUSETS=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -318,7 +318,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig
index aa27d58..41dd708 100644
--- a/arch/mips/configs/sead_defconfig
+++ b/arch/mips/configs/sead_defconfig
@@ -1,71 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:06:45 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:07:10 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -197,6 +137,66 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_MMU=y
@@ -363,6 +363,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig
index ddc7e45..8396946 100644
--- a/arch/mips/configs/tb0226_defconfig
+++ b/arch/mips/configs/tb0226_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:06:49 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:07:12 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -207,6 +138,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -301,7 +301,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig
index e8c82f0..ce7b9ed 100644
--- a/arch/mips/configs/tb0229_defconfig
+++ b/arch/mips/configs/tb0229_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Wed Nov  9 11:11:47 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:07:15 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -207,6 +138,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -302,7 +302,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig
index 125b299..02b2551 100644
--- a/arch/mips/configs/workpad_defconfig
+++ b/arch/mips/configs/workpad_defconfig
@@ -1,80 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 11:17:02 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:07:17 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -204,6 +135,75 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_ISA=y
@@ -297,7 +297,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -609,6 +608,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig
index d90790b..d51d5d1 100644
--- a/arch/mips/configs/yosemite_defconfig
+++ b/arch/mips/configs/yosemite_defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Mon Nov  7 23:06:59 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:07:19 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-# CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_CPUSETS is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -208,6 +138,76 @@
 CONFIG_PREEMPT_BKL=y
 
 #
+# Code maturity level options
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_CLEAN_COMPILE=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+CONFIG_HOTPLUG=y
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+# CONFIG_CPUSETS is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_PCI=y
@@ -284,7 +284,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index e9086da..2a1b844 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -1,81 +1,11 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14
-# Thu Nov 10 12:13:58 2005
+# Linux kernel version: 2.6.15-rc2
+# Thu Nov 24 01:05:49 2005
 #
 CONFIG_MIPS=y
 
 #
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_HOTPLUG is not set
-CONFIG_KOBJECT_UEVENT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-
-#
-# Block layer
-#
-# CONFIG_LBD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
 # Machine selection
 #
 # CONFIG_MIPS_MTX1 is not set
@@ -211,6 +141,76 @@
 # CONFIG_PREEMPT is not set
 
 #
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_CLEAN_COMPILE=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_AUDIT is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_KOBJECT_UEVENT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_EMBEDDED=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_OBSOLETE_MODPARM=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Bus options (PCI, PCMCIA, EISA, ISA, TC)
 #
 CONFIG_HW_HAS_EISA=y
@@ -779,6 +779,7 @@
 #
 # TPM devices
 #
+# CONFIG_TCG_TPM is not set
 # CONFIG_TELCLOCK is not set
 
 #
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c
index 7cbe144..2810727 100644
--- a/arch/mips/jmr3927/rbhma3100/irq.c
+++ b/arch/mips/jmr3927/rbhma3100/irq.c
@@ -113,7 +113,8 @@
 
 static void jmr3927_irq_end(unsigned int irq)
 {
-	jmr3927_irq_enable(irq);
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		jmr3927_irq_enable(irq);
 }
 
 static void jmr3927_irq_disable(unsigned int irq_nr)
@@ -121,7 +122,7 @@
 	struct tb_irq_space* sp;
 	unsigned long flags;
 
-	spinlock_irqsave(&jmr3927_irq_lock, flags);
+	spin_lock_irqsave(&jmr3927_irq_lock, flags);
 	for (sp = tb_irq_spaces; sp; sp = sp->next) {
 		if (sp->start_irqno <= irq_nr &&
 		    irq_nr < sp->start_irqno + sp->nr_irqs) {
@@ -131,7 +132,7 @@
 			break;
 		}
 	}
-	spinlock_irqrestore(&jmr3927_irq_lock, flags);
+	spin_unlock_irqrestore(&jmr3927_irq_lock, flags);
 }
 
 static void jmr3927_irq_enable(unsigned int irq_nr)
@@ -139,7 +140,7 @@
 	struct tb_irq_space* sp;
 	unsigned long flags;
 
-	spinlock_irqsave(&jmr3927_irq_lock, flags);
+	spin_lock_irqsave(&jmr3927_irq_lock, flags);
 	for (sp = tb_irq_spaces; sp; sp = sp->next) {
 		if (sp->start_irqno <= irq_nr &&
 		    irq_nr < sp->start_irqno + sp->nr_irqs) {
@@ -149,7 +150,7 @@
 			break;
 		}
 	}
-	spinlock_irqrestore(&jmr3927_irq_lock, flags);
+	spin_unlock_irqrestore(&jmr3927_irq_lock, flags);
 }
 
 /*
@@ -205,7 +206,10 @@
 	/* update IRCSR */
 	tx3927_ircptr->imr = 0;
 	tx3927_ircptr->imr = irc_elevel;
+	/* flush write buffer */
+	(void)tx3927_ircptr->ssr;
 }
+
 static void unmask_irq_irc(int irq_nr, int space_id)
 {
 	volatile unsigned long *ilrp = &tx3927_ircptr->ilr[irq_nr / 2];
@@ -276,7 +280,7 @@
 	do_IRQ(irq + JMR3927_IRQ_IRC, regs);
 }
 
-static void jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t jmr3927_ioc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned char istat = jmr3927_ioc_reg_in(JMR3927_IOC_INTS2_ADDR);
 	int i;
@@ -287,13 +291,14 @@
 			do_IRQ(irq, regs);
 		}
 	}
+	return IRQ_HANDLED;
 }
 
 static struct irqaction ioc_action = {
 	jmr3927_ioc_interrupt, 0, CPU_MASK_NONE, "IOC", NULL, NULL,
 };
 
-static void jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t jmr3927_isac_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned char istat = jmr3927_isac_reg_in(JMR3927_ISAC_INTS2_ADDR);
 	int i;
@@ -304,6 +309,7 @@
 			do_IRQ(irq, regs);
 		}
 	}
+	return IRQ_HANDLED;
 }
 
 static struct irqaction isac_action = {
@@ -311,19 +317,23 @@
 };
 
 
-static void jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+static irqreturn_t jmr3927_isaerr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 {
 	printk(KERN_WARNING "ISA error interrupt (irq 0x%x).\n", irq);
+
+	return IRQ_HANDLED;
 }
 static struct irqaction isaerr_action = {
 	jmr3927_isaerr_interrupt, 0, CPU_MASK_NONE, "ISA error", NULL, NULL,
 };
 
-static void jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+static irqreturn_t jmr3927_pcierr_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 {
 	printk(KERN_WARNING "PCI error interrupt (irq 0x%x).\n", irq);
 	printk(KERN_WARNING "pcistat:%02x, lbstat:%04lx\n",
 	       tx3927_pcicptr->pcistat, tx3927_pcicptr->lbstat);
+
+	return IRQ_HANDLED;
 }
 static struct irqaction pcierr_action = {
 	jmr3927_pcierr_interrupt, 0, CPU_MASK_NONE, "PCI error", NULL, NULL,
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 55ad0a5..4763957 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -60,6 +60,8 @@
 #include <asm/mipsregs.h>
 #include <asm/traps.h>
 
+extern void puts(unsigned char *cp);
+
 /* Tick Timer divider */
 #define JMR3927_TIMER_CCD	0	/* 1/2 */
 #define JMR3927_TIMER_CLK	(JMR3927_IMCLK / (2 << JMR3927_TIMER_CCD))
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index a263fb7..5e1b08b 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -417,7 +417,7 @@
 	case PRID_IMP_R10000:
 		c->cputype = CPU_R10000;
 		c->isa_level = MIPS_CPU_ISA_IV;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
 		             MIPS_CPU_FPU | MIPS_CPU_32FPR |
 			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
 		             MIPS_CPU_LLSC;
@@ -426,7 +426,7 @@
 	case PRID_IMP_R12000:
 		c->cputype = CPU_R12000;
 		c->isa_level = MIPS_CPU_ISA_IV;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
+		c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
 		             MIPS_CPU_FPU | MIPS_CPU_32FPR |
 			     MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
 		             MIPS_CPU_LLSC;
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index dd118c6..08273a2 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -279,8 +279,6 @@
 	/*
 	 * Don't let your children do this ...
 	 */
-	if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
-		do_syscall_trace(regs, 1);
 	__asm__ __volatile__(
 		"move\t$29,%0\n\t"
 		"j\tsyscall_exit"
@@ -783,8 +781,6 @@
 	/*
 	 * Don't let your children do this ...
 	 */
-	if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
-		do_syscall_trace(regs, 1);
 	__asm__ __volatile__(
 		"move\t$29,%0\n\t"
 		"j\tsyscall_exit"
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 330cf84..60353f5 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -420,7 +420,7 @@
 		goto out;
 	pos = merge_64(a4, a5);
 	ret = rw_verify_area(READ, file, &pos, count);
-	if (ret)
+	if (ret < 0)
 		goto out;
 	ret = -EINVAL;
 	if (!file->f_op || !(read = file->f_op->read))
@@ -455,7 +455,7 @@
 		goto out;
 	pos = merge_64(a4, a5);
 	ret = rw_verify_area(WRITE, file, &pos, count);
-	if (ret)
+	if (ret < 0)
 		goto out;
 	ret = -EINVAL;
 	if (!file->f_op || !(write = file->f_op->write))
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 9a9b049..7e55457 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -57,30 +57,16 @@
 	       (unsigned long) data);
 #endif
 	lock_kernel();
-	ret = -EPERM;
 	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
+		ret = ptrace_traceme();
 		goto out;
 	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
 
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
+		goto out;
+	}
 
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index 4dd8e8b..a42e0e8 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -94,11 +94,13 @@
 	li	a1, 0
 	jal	do_syscall_trace
 
+	move	t0, s0
+	RESTORE_STATIC
 	lw	a0, PT_R4(sp)		# Restore argument registers
 	lw	a1, PT_R5(sp)
 	lw	a2, PT_R6(sp)
 	lw	a3, PT_R7(sp)
-	jalr	s0
+	jalr	t0
 
 	li	t0, -EMAXERRNO - 1	# error?
 	sltu	t0, t0, v0
@@ -241,19 +243,7 @@
 	sw	zero, PT_R7(sp)		# success
 	sw	v0, PT_R2(sp)		# result
 
-	/* Success, so skip usual error handling garbage.  */
-	lw	a2, TI_FLAGS($28)	# syscall tracing enabled?
-	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
-	and	t0, a2, t0
-	bnez	t0, 1f
-
-	j	o32_syscall_exit
-
-1:	SAVE_STATIC
-	move	a0, sp
-	li	a1, 1
-	jal	do_syscall_trace
-	j	syscall_exit
+	j	o32_syscall_exit	# continue like a normal syscall
 
 no_mem:	li	v0, -ENOMEM
 	jr	ra
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 9085838..47bfbd4 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -93,13 +93,15 @@
 	li	a1, 0
 	jal	do_syscall_trace
 
+	move	t0, s0
+	RESTORE_STATIC
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
 	ld	a3, PT_R7(sp)
 	ld	a4, PT_R8(sp)
 	ld	a5, PT_R9(sp)
-	jalr	s0
+	jalr	t0
 
 	li	t0, -EMAXERRNO - 1	# error?
 	sltu	t0, t0, v0
@@ -174,19 +176,7 @@
 	sd	zero, PT_R7(sp)		# success
 	sd	v0, PT_R2(sp)		# result
 
-	/* Success, so skip usual error handling garbage.  */
-	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
-	LONG_L	a2, TI_FLAGS($28)	# syscall tracing enabled?
-	and	t0, a2, t0
-	bnez	t0, 1f
-
-	j	n64_syscall_exit
-
-1:	SAVE_STATIC
-	move	a0, sp
-	li	a1, 1
-	jal	do_syscall_trace
-	j	syscall_exit
+	j	n64_syscall_exit	# continue like a normal syscall
 
 no_mem:	li	v0, -ENOMEM
 	jr	ra
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 7e66eb8..b465ced 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -90,13 +90,15 @@
 	li	a1, 0
 	jal	do_syscall_trace
 
+	move	t0, s0
+	RESTORE_STATIC
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
 	ld	a3, PT_R7(sp)
 	ld	a4, PT_R8(sp)
 	ld	a5, PT_R9(sp)
-	jalr	s0
+	jalr	t0
 
 	li	t0, -EMAXERRNO - 1	# error?
 	sltu	t0, t0, v0
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 5a16401..3d338ca 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -124,6 +124,8 @@
 	li	a1, 0
 	jal	do_syscall_trace
 
+	move	t0, s0
+	RESTORE_STATIC
 	ld	a0, PT_R4(sp)		# Restore argument registers
 	ld	a1, PT_R5(sp)
 	ld	a2, PT_R6(sp)
@@ -132,7 +134,7 @@
 	ld	a5, PT_R9(sp)
 	ld	a6, PT_R10(sp)
 	ld	a7, PT_R11(sp)		# For indirect syscalls
-	jalr	s0
+	jalr	t0
 
 	li	t0, -EMAXERRNO - 1	# error?
 	sltu	t0, t0, v0
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 05e09ee..7d1800f 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -220,8 +220,6 @@
 	/*
 	 * Don't let your children do this ...
 	 */
-	if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
-		do_syscall_trace(&regs, 1);
 	__asm__ __volatile__(
 		"move\t$29, %0\n\t"
 		"j\tsyscall_exit"
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index e315d3f..c856dbc 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -497,8 +497,6 @@
 	/*
 	 * Don't let your children do this ...
 	 */
-	if (current_thread_info()->flags & TIF_SYSCALL_TRACE)
-		do_syscall_trace(&regs, 1);
 	__asm__ __volatile__(
 		"move\t$29, %0\n\t"
 		"j\tsyscall_exit"
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 6f3ff96..7058893 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -534,13 +534,14 @@
 		switch (rd) {
 			case 29:
 				regs->regs[rt] = ti->tp_value;
-				break;
+				return 0;
 			default:
 				return -EFAULT;
 		}
 	}
 
-	return 0;
+	/* Not ours.  */
+	return -EFAULT;
 }
 
 asmlinkage void do_ov(struct pt_regs *regs)
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index f75ab74..4ee91c9 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -67,8 +67,8 @@
 
 	page = virt_to_page(empty_zero_page);
 	while (page < virt_to_page(empty_zero_page + (PAGE_SIZE << order))) {
-		set_bit(PG_reserved, &page->flags);
-		set_page_count(page, 0);
+		SetPageReserved(page);
+		set_page_count(page, 1);
 		page++;
 	}
 
diff --git a/arch/mips/qemu/q-firmware.c b/arch/mips/qemu/q-firmware.c
index 5980f02b..fb2a8673 100644
--- a/arch/mips/qemu/q-firmware.c
+++ b/arch/mips/qemu/q-firmware.c
@@ -1,7 +1,18 @@
 #include <linux/init.h>
+#include <linux/string.h>
+#include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 
 void __init prom_init(void)
 {
-	add_memory_region(0x0<<20, 0x10<<20, BOOT_MEM_RAM);
+	int *cmdline;
+
+	cmdline = (int *) (CKSEG0 + (0x10 << 20) - 260);
+	if (*cmdline == 0x12345678) {
+		if (*(char *)(cmdline + 1))
+			strcpy (arcs_cmdline, (char *)(cmdline + 1));
+		add_memory_region(0x0<<20, cmdline[-1], BOOT_MEM_RAM);
+	} else {
+		add_memory_region(0x0<<20, 0x10<<20, BOOT_MEM_RAM);
+	}
 }
diff --git a/arch/mips/sgi-ip27/ip27-berr.c b/arch/mips/sgi-ip27/ip27-berr.c
index 07631a9..ce907ed 100644
--- a/arch/mips/sgi-ip27/ip27-berr.c
+++ b/arch/mips/sgi-ip27/ip27-berr.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/signal.h>	/* for SIGBUS */
+#include <linux/sched.h>	/* schow_regs(), force_sig() */
 
 #include <asm/module.h>
 #include <asm/sn/addrs.h>
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 874a283..e77a06e 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -19,9 +19,6 @@
 config STACK_GROWSUP
 	def_bool y
 
-config UID16
-	bool
-
 config RWSEM_GENERIC_SPINLOCK
 	def_bool y
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index bb2efdd..331483a 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -26,9 +26,6 @@
 	bool
 	default y
 
-config UID16
-	bool
-
 config GENERIC_HARDIRQS
 	bool
 	default y
@@ -227,7 +224,7 @@
 	  If you don't know what to do here, say N.
 
 config NR_CPUS
-	int "Maximum number of CPUs (2-32)"
+	int "Maximum number of CPUs (2-128)"
 	range 2 128
 	depends on SMP
 	default "32" if PPC64
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index 4b43341..b657f7e 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 14:36:20 2005
+# Linux kernel version: 2.6.15-rc5
+# Tue Dec 20 15:59:26 2005
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -53,6 +53,7 @@
 # CONFIG_IKCONFIG is not set
 # CONFIG_CPUSETS is not set
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
@@ -151,7 +152,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PPC_64K_PAGES is not set
 CONFIG_SCHED_SMT=y
 CONFIG_PROC_DEVICETREE=y
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
index e7c23e3..3c22ccb 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 14:39:20 2005
+# Linux kernel version: 2.6.15-rc5
+# Tue Dec 20 15:59:30 2005
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -53,6 +53,7 @@
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
@@ -162,7 +163,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PPC_64K_PAGES is not set
 # CONFIG_SCHED_SMT is not set
 CONFIG_PROC_DEVICETREE=y
@@ -1203,6 +1204,7 @@
 CONFIG_USB_SERIAL=m
 CONFIG_USB_SERIAL_GENERIC=y
 # CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
 CONFIG_USB_SERIAL_BELKIN=m
 CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
 # CONFIG_USB_SERIAL_CP2101 is not set
@@ -1233,7 +1235,6 @@
 CONFIG_USB_SERIAL_KLSI=m
 CONFIG_USB_SERIAL_KOBIL_SCT=m
 CONFIG_USB_SERIAL_MCT_U232=m
-# CONFIG_USB_SERIAL_NOKIA_DKU2 is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_HP4X is not set
 CONFIG_USB_SERIAL_SAFE=m
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig
index 5d08667..751a622 100644
--- a/arch/powerpc/configs/iseries_defconfig
+++ b/arch/powerpc/configs/iseries_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 14:38:09 2005
+# Linux kernel version: 2.6.15-rc5
+# Tue Dec 20 15:59:32 2005
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -55,6 +55,7 @@
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
@@ -144,7 +145,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PPC_64K_PAGES is not set
 # CONFIG_SCHED_SMT is not set
 CONFIG_PROC_DEVICETREE=y
diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig
index 92e4261..07b6d3d 100644
--- a/arch/powerpc/configs/maple_defconfig
+++ b/arch/powerpc/configs/maple_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 14:38:58 2005
+# Linux kernel version: 2.6.15-rc5
+# Tue Dec 20 15:59:36 2005
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -53,6 +53,7 @@
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
@@ -149,7 +150,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PPC_64K_PAGES is not set
 # CONFIG_SCHED_SMT is not set
 CONFIG_PROC_DEVICETREE=y
@@ -242,7 +243,6 @@
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -794,6 +794,7 @@
 # CONFIG_USB_SERIAL_CONSOLE is not set
 CONFIG_USB_SERIAL_GENERIC=y
 # CONFIG_USB_SERIAL_AIRPRIME is not set
+# CONFIG_USB_SERIAL_ANYDATA is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
 # CONFIG_USB_SERIAL_CP2101 is not set
@@ -824,7 +825,6 @@
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_NOKIA_DKU2 is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index b5ba3bb..509399e 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Fri Nov 18 16:23:24 2005
+# Linux kernel version: 2.6.15-rc5
+# Tue Dec 20 15:59:38 2005
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -54,6 +54,7 @@
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CPUSETS=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
@@ -176,7 +177,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPARSEMEM_EXTREME=y
 # CONFIG_MEMORY_HOTPLUG is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PPC_64K_PAGES is not set
 # CONFIG_SCHED_SMT is not set
 CONFIG_PROC_DEVICETREE=y
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index b589b19..a50ce0f 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.15-rc1
-# Tue Nov 15 14:36:55 2005
+# Linux kernel version: 2.6.15-rc5
+# Tue Dec 20 15:59:40 2005
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -55,6 +55,7 @@
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CPUSETS=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
@@ -163,7 +164,7 @@
 # CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPARSEMEM_EXTREME=y
 # CONFIG_MEMORY_HOTPLUG is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4096
+CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
 # CONFIG_PPC_64K_PAGES is not set
 CONFIG_SCHED_SMT=y
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 2d22bf0..bce33a3 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -183,8 +183,8 @@
 	ld	r13,GPR13(r1)		/* returning to usermode */
 1:	ld	r2,GPR2(r1)
 	li	r12,MSR_RI
-	andc	r10,r10,r12
-	mtmsrd	r10,1			/* clear MSR.RI */
+	andc	r11,r10,r12
+	mtmsrd	r11,1			/* clear MSR.RI */
 	ld	r1,GPR1(r1)
 	mtlr	r4
 	mtcr	r5
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 511af54..5368f9c 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -177,7 +177,7 @@
 			save_previous_kprobe(kcb);
 			set_current_kprobe(p, regs, kcb);
 			kcb->kprobe_saved_msr = regs->msr;
-			p->nmissed++;
+			kprobes_inc_nmissed_count(p);
 			prepare_singlestep(p, regs);
 			kcb->kprobe_status = KPROBE_REENTER;
 			return 1;
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index af4d1bc..94db257 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -163,15 +163,13 @@
 EXPORT_SYMBOL(giveup_spe);
 #endif /* CONFIG_SPE */
 
-#ifdef CONFIG_PPC64
-EXPORT_SYMBOL(__flush_icache_range);
-#else
+#ifndef CONFIG_PPC64
 EXPORT_SYMBOL(flush_instruction_cache);
-EXPORT_SYMBOL(flush_icache_range);
 EXPORT_SYMBOL(flush_tlb_kernel_range);
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(_tlbie);
 #endif
+EXPORT_SYMBOL(__flush_icache_range);
 EXPORT_SYMBOL(flush_dcache_range);
 
 #ifdef CONFIG_SMP
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index a5a7542..105d560 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -201,6 +201,28 @@
 }
 #endif /* CONFIG_SPE */
 
+/*
+ * If we are doing lazy switching of CPU state (FP, altivec or SPE),
+ * and the current task has some state, discard it.
+ */
+static inline void discard_lazy_cpu_state(void)
+{
+#ifndef CONFIG_SMP
+	preempt_disable();
+	if (last_task_used_math == current)
+		last_task_used_math = NULL;
+#ifdef CONFIG_ALTIVEC
+	if (last_task_used_altivec == current)
+		last_task_used_altivec = NULL;
+#endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_SPE
+	if (last_task_used_spe == current)
+		last_task_used_spe = NULL;
+#endif
+	preempt_enable();
+#endif /* CONFIG_SMP */
+}
+
 int set_dabr(unsigned long dabr)
 {
 	if (ppc_md.set_dabr)
@@ -434,19 +456,7 @@
 void exit_thread(void)
 {
 	kprobe_flush_task(current);
-
-#ifndef CONFIG_SMP
-	if (last_task_used_math == current)
-		last_task_used_math = NULL;
-#ifdef CONFIG_ALTIVEC
-	if (last_task_used_altivec == current)
-		last_task_used_altivec = NULL;
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-	if (last_task_used_spe == current)
-		last_task_used_spe = NULL;
-#endif
-#endif /* CONFIG_SMP */
+	discard_lazy_cpu_state();
 }
 
 void flush_thread(void)
@@ -458,18 +468,7 @@
 		t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT);
 #endif
 
-#ifndef CONFIG_SMP
-	if (last_task_used_math == current)
-		last_task_used_math = NULL;
-#ifdef CONFIG_ALTIVEC
-	if (last_task_used_altivec == current)
-		last_task_used_altivec = NULL;
-#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SPE
-	if (last_task_used_spe == current)
-		last_task_used_spe = NULL;
-#endif
-#endif /* CONFIG_SMP */
+	discard_lazy_cpu_state();
 
 #ifdef CONFIG_PPC64	/* for now */
 	if (current->thread.dabr) {
@@ -635,18 +634,7 @@
 	}
 #endif
 
-#ifndef CONFIG_SMP
-	if (last_task_used_math == current)
-		last_task_used_math = NULL;
-#ifdef CONFIG_ALTIVEC
-	if (last_task_used_altivec == current)
-		last_task_used_altivec = NULL;
-#endif
-#ifdef CONFIG_SPE
-	if (last_task_used_spe == current)
-		last_task_used_spe = NULL;
-#endif
-#endif /* CONFIG_SMP */
+	discard_lazy_cpu_state();
 	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
 	current->thread.fpscr.val = 0;
 #ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 4ce0105..bcdc209 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -265,7 +265,7 @@
 	va_end(list);
 
 	for (i = 0; i < nret; i++)
-		rets[nargs+i] = 0;
+		args.args[nargs+i] = 0;
 
 	if (enter_prom(&args, RELOC(prom_entry)) < 0)
 		return PROM_ERROR;
diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c
index 6176264..826ee3d 100644
--- a/arch/powerpc/kernel/ptrace32.c
+++ b/arch/powerpc/kernel/ptrace32.c
@@ -45,33 +45,19 @@
 		       unsigned long data)
 {
 	struct task_struct *child;
-	int ret = -EPERM;
+	int ret;
 
 	lock_kernel();
 	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
+		ret = ptrace_traceme();
 		goto out;
 	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
 
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
+		goto out;
+	}
 
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 608fee7..e3fb783 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -102,7 +102,15 @@
 dev_t boot_dev;
 u64 ppc64_pft_size;
 
-struct ppc64_caches ppc64_caches;
+/* Pick defaults since we might want to patch instructions
+ * before we've read this from the device tree.
+ */
+struct ppc64_caches ppc64_caches = {
+	.dline_size = 0x80,
+	.log_dline_size = 7,
+	.iline_size = 0x80,
+	.log_iline_size = 7
+};
 EXPORT_SYMBOL_GPL(ppc64_caches);
 
 /*
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index f72ced1..91b93d9 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -247,7 +247,7 @@
 #define OVERRIDE_MACHINE    0
 #endif
 
-static inline int override_machine(char *mach)
+static inline int override_machine(char __user *mach)
 {
 	if (OVERRIDE_MACHINE) {
 		/* change ppc64 to ppc */
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index b44b36e..f0c47da 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -145,8 +145,7 @@
 			struct page *pg = virt_to_page(vdso32_kbase +
 						       i*PAGE_SIZE);
 			struct page *upg = (vma && vma->vm_mm) ?
-				follow_page(vma->vm_mm, vma->vm_start +
-					    i*PAGE_SIZE, 0)
+				follow_page(vma, vma->vm_start + i*PAGE_SIZE, 0)
 				: NULL;
 			dump_one_vdso_page(pg, upg);
 		}
@@ -157,8 +156,7 @@
 			struct page *pg = virt_to_page(vdso64_kbase +
 						       i*PAGE_SIZE);
 			struct page *upg = (vma && vma->vm_mm) ?
-				follow_page(vma->vm_mm, vma->vm_start +
-					    i*PAGE_SIZE, 0)
+				follow_page(vma, vma->vm_start + i*PAGE_SIZE, 0)
 				: NULL;
 			dump_one_vdso_page(pg, upg);
 		}
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 71a6add..13c4149 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -293,6 +293,6 @@
 
 struct bus_type vio_bus_type = {
 	.name = "vio",
-	.hotplug = vio_hotplug,
+	.uevent = vio_hotplug,
 	.match = vio_bus_match,
 };
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 706e8a6..a606504 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -514,7 +514,7 @@
 #undef KB
 #undef MB
 
-void __init htab_initialize_secondary(void)
+void htab_initialize_secondary(void)
 {
 	if (!platform_is_lpar())
 		mtspr(SPRN_SDR1, _SDR1);
@@ -601,7 +601,7 @@
 	/* Handle hugepage regions */
 	if (unlikely(in_hugepage_area(mm->context, ea))) {
 		DBG_LOW(" -> huge page !\n");
-		return hash_huge_page(mm, access, ea, vsid, local);
+		return hash_huge_page(mm, access, ea, vsid, local, trap);
 	}
 
 	/* Get PTE and page size from page tables */
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 6bc9dba..54131b8 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -148,43 +148,63 @@
 	return 0;
 }
 
+struct slb_flush_info {
+	struct mm_struct *mm;
+	u16 newareas;
+};
+
 static void flush_low_segments(void *parm)
 {
-	u16 areas = (unsigned long) parm;
+	struct slb_flush_info *fi = parm;
 	unsigned long i;
 
+	BUILD_BUG_ON((sizeof(fi->newareas)*8) != NUM_LOW_AREAS);
+
+	if (current->active_mm != fi->mm)
+		return;
+
+	/* Only need to do anything if this CPU is working in the same
+	 * mm as the one which has changed */
+
+	/* update the paca copy of the context struct */
+	get_paca()->context = current->active_mm->context;
+
 	asm volatile("isync" : : : "memory");
-
-	BUILD_BUG_ON((sizeof(areas)*8) != NUM_LOW_AREAS);
-
 	for (i = 0; i < NUM_LOW_AREAS; i++) {
-		if (! (areas & (1U << i)))
+		if (! (fi->newareas & (1U << i)))
 			continue;
 		asm volatile("slbie %0"
 			     : : "r" ((i << SID_SHIFT) | SLBIE_C));
 	}
-
 	asm volatile("isync" : : : "memory");
 }
 
 static void flush_high_segments(void *parm)
 {
-	u16 areas = (unsigned long) parm;
+	struct slb_flush_info *fi = parm;
 	unsigned long i, j;
 
+
+	BUILD_BUG_ON((sizeof(fi->newareas)*8) != NUM_HIGH_AREAS);
+
+	if (current->active_mm != fi->mm)
+		return;
+
+	/* Only need to do anything if this CPU is working in the same
+	 * mm as the one which has changed */
+
+	/* update the paca copy of the context struct */
+	get_paca()->context = current->active_mm->context;
+
 	asm volatile("isync" : : : "memory");
-
-	BUILD_BUG_ON((sizeof(areas)*8) != NUM_HIGH_AREAS);
-
 	for (i = 0; i < NUM_HIGH_AREAS; i++) {
-		if (! (areas & (1U << i)))
+		if (! (fi->newareas & (1U << i)))
 			continue;
 		for (j = 0; j < (1UL << (HTLB_AREA_SHIFT-SID_SHIFT)); j++)
 			asm volatile("slbie %0"
 				     :: "r" (((i << HTLB_AREA_SHIFT)
-					     + (j << SID_SHIFT)) | SLBIE_C));
+					      + (j << SID_SHIFT)) | SLBIE_C));
 	}
-
 	asm volatile("isync" : : : "memory");
 }
 
@@ -229,6 +249,7 @@
 static int open_low_hpage_areas(struct mm_struct *mm, u16 newareas)
 {
 	unsigned long i;
+	struct slb_flush_info fi;
 
 	BUILD_BUG_ON((sizeof(newareas)*8) != NUM_LOW_AREAS);
 	BUILD_BUG_ON((sizeof(mm->context.low_htlb_areas)*8) != NUM_LOW_AREAS);
@@ -244,19 +265,20 @@
 
 	mm->context.low_htlb_areas |= newareas;
 
-	/* update the paca copy of the context struct */
-	get_paca()->context = mm->context;
-
 	/* the context change must make it to memory before the flush,
 	 * so that further SLB misses do the right thing. */
 	mb();
-	on_each_cpu(flush_low_segments, (void *)(unsigned long)newareas, 0, 1);
+
+	fi.mm = mm;
+	fi.newareas = newareas;
+	on_each_cpu(flush_low_segments, &fi, 0, 1);
 
 	return 0;
 }
 
 static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas)
 {
+	struct slb_flush_info fi;
 	unsigned long i;
 
 	BUILD_BUG_ON((sizeof(newareas)*8) != NUM_HIGH_AREAS);
@@ -280,7 +302,10 @@
 	/* the context change must make it to memory before the flush,
 	 * so that further SLB misses do the right thing. */
 	mb();
-	on_each_cpu(flush_high_segments, (void *)(unsigned long)newareas, 0, 1);
+
+	fi.mm = mm;
+	fi.newareas = newareas;
+	on_each_cpu(flush_high_segments, &fi, 0, 1);
 
 	return 0;
 }
@@ -639,8 +664,36 @@
 	return -ENOMEM;
 }
 
+/*
+ * Called by asm hashtable.S for doing lazy icache flush
+ */
+static unsigned int hash_huge_page_do_lazy_icache(unsigned long rflags,
+						  pte_t pte, int trap)
+{
+	struct page *page;
+	int i;
+
+	if (!pfn_valid(pte_pfn(pte)))
+		return rflags;
+
+	page = pte_page(pte);
+
+	/* page is dirty */
+	if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) {
+		if (trap == 0x400) {
+			for (i = 0; i < (HPAGE_SIZE / PAGE_SIZE); i++)
+				__flush_dcache_icache(page_address(page+i));
+			set_bit(PG_arch_1, &page->flags);
+		} else {
+			rflags |= HPTE_R_N;
+		}
+	}
+	return rflags;
+}
+
 int hash_huge_page(struct mm_struct *mm, unsigned long access,
-		   unsigned long ea, unsigned long vsid, int local)
+		   unsigned long ea, unsigned long vsid, int local,
+		   unsigned long trap)
 {
 	pte_t *ptep;
 	unsigned long old_pte, new_pte;
@@ -691,6 +744,11 @@
 	rflags = 0x2 | (!(new_pte & _PAGE_RW));
  	/* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */
 	rflags |= ((new_pte & _PAGE_EXEC) ? 0 : HPTE_R_N);
+	if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+		/* No CPU has hugepages but lacks no execute, so we
+		 * don't need to worry about that case */
+		rflags = hash_huge_page_do_lazy_icache(rflags, __pte(old_pte),
+						       trap);
 
 	/* Check if pte already has an hpte (case 2) */
 	if (unlikely(old_pte & _PAGE_HASHPTE)) {
@@ -703,7 +761,8 @@
 		slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
 		slot += (old_pte & _PAGE_F_GIX) >> 12;
 
-		if (ppc_md.hpte_updatepp(slot, rflags, va, 1, local) == -1)
+		if (ppc_md.hpte_updatepp(slot, rflags, va, mmu_huge_psize,
+					 local) == -1)
 			old_pte &= ~_PAGE_HPTEFLAGS;
 	}
 
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index f72cf87..ba7a305 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -125,7 +125,7 @@
 
 	/* We didnt find a matching region, return start/end as 0 */
 	if (*start_pfn == -1UL)
-		start_pfn = 0;
+		*start_pfn = 0;
 }
 
 static inline void map_cpu_to_node(int cpu, int node)
diff --git a/arch/powerpc/mm/stab.c b/arch/powerpc/mm/stab.c
index cfbb4e1..51e7951 100644
--- a/arch/powerpc/mm/stab.c
+++ b/arch/powerpc/mm/stab.c
@@ -288,11 +288,6 @@
 		return;
 	}
 #endif /* CONFIG_PPC_ISERIES */
-#ifdef CONFIG_PPC_PSERIES
-	if (platform_is_lpar()) {
-		plpar_hcall_norets(H_SET_ASR, stabreal);
-		return;
-	}
-#endif
+
 	mtspr(SPRN_ASR, stabreal);
 }
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 0d7fa00..f6e22da 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -1650,11 +1650,19 @@
 	 */
 
 	if (macio->type == macio_intrepid) {
-		if (enable)
-			UN_OUT(UNI_N_CLOCK_SPREADING, 2);
-		else
-			UN_OUT(UNI_N_CLOCK_SPREADING, 0);
-		mdelay(40);
+		struct device_node *clock =
+			of_find_node_by_path("/uni-n@f8000000/hw-clock");
+		if (clock && get_property(clock, "platform-do-clockspreading",
+					  NULL)) {
+			printk(KERN_INFO "%sabling clock spreading on Intrepid"
+			       " ASIC\n", enable ? "En" : "Dis");
+			if (enable)
+				UN_OUT(UNI_N_CLOCK_SPREADING, 2);
+			else
+				UN_OUT(UNI_N_CLOCK_SPREADING, 0);
+			mdelay(40);
+		}
+		of_node_put(clock);
 	}
 
 	while (machine_is_compatible("PowerBook5,2") ||
@@ -1724,6 +1732,9 @@
 			pmac_low_i2c_close(ui2c);
 			break;
 		}
+		printk(KERN_INFO "%sabling clock spreading on i2c clock chip\n",
+		       enable ? "En" : "Dis");
+
 		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
 		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
 		DBG("write result: %d,", rc);
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index c78f2b2..2043659 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -109,6 +109,9 @@
 	u64 rc;
 	union tce_entry tce;
 
+	tcenum <<= TCE_PAGE_FACTOR;
+	npages <<= TCE_PAGE_FACTOR;
+
 	tce.te_word = 0;
 	tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
 	tce.te_rdwr = 1;
@@ -143,10 +146,7 @@
 	union tce_entry tce, *tcep;
 	long l, limit;
 
-	tcenum <<= TCE_PAGE_FACTOR;
-	npages <<= TCE_PAGE_FACTOR;
-
-	if (npages == 1)
+	if (TCE_PAGE_FACTOR == 0 && npages == 1)
 		return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
 					   direction);
 
@@ -164,6 +164,9 @@
 		__get_cpu_var(tce_page) = tcep;
 	}
 
+	tcenum <<= TCE_PAGE_FACTOR;
+	npages <<= TCE_PAGE_FACTOR;
+
 	tce.te_word = 0;
 	tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT;
 	tce.te_rdwr = 1;
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index a50e5f3..cf1bc11 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -298,18 +298,6 @@
 	if (!(vflags & HPTE_V_BOLTED))
 		DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
 
-#if 1
-	{
-		int i;
-		for (i=0;i<8;i++) {
-			unsigned long w0, w1;
-			plpar_pte_read(0, hpte_group, &w0, &w1);
-			BUG_ON (HPTE_V_COMPARE(hpte_v, w0)
-				&& (w0 & HPTE_V_VALID));
-		}
-	}
-#endif
-
 	/* Now fill in the actual HPTE */
 	/* Set CEC cookie to 0         */
 	/* Zero page = 0               */
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 72ac180..0377dec 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -48,11 +48,6 @@
 	.set_affinity = xics_set_affinity
 };
 
-static struct hw_interrupt_type xics_8259_pic = {
-	.typename = " XICS/8259",
-	.ack = xics_mask_and_ack_irq,
-};
-
 /* This is used to map real irq numbers to virtual */
 static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC);
 
@@ -367,12 +362,7 @@
 	/* for sanity, this had better be < NR_IRQS - 16 */
 	if (vec == xics_irq_8259_cascade_real) {
 		irq = i8259_irq(regs);
-		if (irq == -1) {
-			/* Spurious cascaded interrupt.  Still must ack xics */
-			xics_end_irq(irq_offset_up(xics_irq_8259_cascade));
-
-			irq = -1;
-		}
+		xics_end_irq(irq_offset_up(xics_irq_8259_cascade));
 	} else if (vec == XICS_IRQ_SPURIOUS) {
 		irq = -1;
 	} else {
@@ -542,6 +532,7 @@
 		xics_irq_8259_cascade_real = *ireg;
 		xics_irq_8259_cascade
 			= virt_irq_create_mapping(xics_irq_8259_cascade_real);
+		i8259_init(0, 0);
 		of_node_put(np);
 	}
 
@@ -565,12 +556,7 @@
 #endif /* CONFIG_SMP */
 	}
 
-	xics_8259_pic.enable = i8259_pic.enable;
-	xics_8259_pic.disable = i8259_pic.disable;
-	xics_8259_pic.end = i8259_pic.end;
-	for (i = 0; i < 16; ++i)
-		get_irq_desc(i)->handler = &xics_8259_pic;
-	for (; i < NR_IRQS; ++i)
+	for (i = irq_offset_value(); i < NR_IRQS; ++i)
 		get_irq_desc(i)->handler = &xics_pic;
 
 	xics_setup_cpu();
@@ -590,7 +576,6 @@
 				no_action, 0, "8259 cascade", NULL))
 			printk(KERN_ERR "xics_setup_i8259: couldn't get 8259 "
 					"cascade\n");
-		i8259_init(0, 0);
 	}
 	return 0;
 }
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 8fa51b0..e396f45 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -8,9 +8,6 @@
 	bool
 	default y
 
-config UID16
-	bool
-
 config GENERIC_HARDIRQS
 	bool
 	default y
@@ -767,14 +764,14 @@
 	  on it (826x, 827x, 8560).
 
 config PPC_CHRP
-	bool "  Common Hardware Reference Platform (CHRP) based machines"
+	bool
 	depends on PPC_MULTIPLATFORM
 	select PPC_I8259
 	select PPC_INDIRECT_PCI
 	default y
 
 config PPC_PMAC
-	bool "  Apple PowerMac based machines"
+	bool
 	depends on PPC_MULTIPLATFORM
 	select PPC_INDIRECT_PCI
 	default y
@@ -785,7 +782,7 @@
 	default y
 
 config PPC_PREP
-	bool "  PowerPC Reference Platform (PReP) based machines"
+	bool
 	depends on PPC_MULTIPLATFORM
 	select PPC_I8259
 	select PPC_INDIRECT_PCI
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
index 82df88b..9533f8d 100644
--- a/arch/ppc/boot/simple/Makefile
+++ b/arch/ppc/boot/simple/Makefile
@@ -190,6 +190,8 @@
 boot-$(CONFIG_REDWOOD_6)	+= embed_config.o
 boot-$(CONFIG_8xx)		+= embed_config.o
 boot-$(CONFIG_8260)		+= embed_config.o
+boot-$(CONFIG_EP405)		+= embed_config.o
+boot-$(CONFIG_XILINX_ML300)	+= embed_config.o
 boot-$(CONFIG_BSEIP)		+= iic.o
 boot-$(CONFIG_MBX)		+= iic.o pci.o qspan_pci.o
 boot-$(CONFIG_MV64X60)		+= misc-mv64x60.o
@@ -262,11 +264,11 @@
 		skip=64 bs=1k
 
 $(images)/zImage-TREE: $(obj)/zvmlinux $(MKTREE)
-	$(MKTREE) $(obj)/zvmlinux $(images)/zImage.$(end-y) $(ENTRYPOINT)
+	$(MKTREE) $(obj)/zvmlinux $(images)/zImage.$(end-y) $(entrypoint-y)
 
 $(images)/zImage.initrd-TREE: $(obj)/zvmlinux.initrd $(MKTREE)
 	$(MKTREE) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(end-y) \
-		$(ENTRYPOINT)
+		$(entrypoint-y)
 
 $(images)/zImage-PPLUS: $(obj)/zvmlinux $(MKPREP) $(MKBUGBOOT)
 	$(MKPREP) -pbp $(obj)/zvmlinux $(images)/zImage.$(end-y)
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index 821a75e..1be3ca5 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -37,7 +37,6 @@
 void default_idle(void)
 {
 	void (*powersave)(void);
-	int cpu = smp_processor_id();
 
 	powersave = ppc_md.power_save;
 
@@ -47,7 +46,8 @@
 #ifdef CONFIG_SMP
 		else {
 			set_thread_flag(TIF_POLLING_NRFLAG);
-			while (!need_resched() && !cpu_is_offline(cpu))
+			while (!need_resched() &&
+					!cpu_is_offline(smp_processor_id()))
 				barrier();
 			clear_thread_flag(TIF_POLLING_NRFLAG);
 		}
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 66073f7..bb6a5c6 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -184,7 +184,7 @@
 
 EXPORT_SYMBOL(flush_instruction_cache);
 EXPORT_SYMBOL(giveup_fpu);
-EXPORT_SYMBOL(flush_icache_range);
+EXPORT_SYMBOL(__flush_icache_range);
 EXPORT_SYMBOL(flush_dcache_range);
 EXPORT_SYMBOL(flush_icache_user_range);
 EXPORT_SYMBOL(flush_dcache_page);
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index cb1c7b9..25cbdc8 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -417,6 +417,7 @@
 
 void exit_thread(void)
 {
+	preempt_disable();
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
 	if (last_task_used_altivec == current)
@@ -425,10 +426,12 @@
 	if (last_task_used_spe == current)
 		last_task_used_spe = NULL;
 #endif
+	preempt_enable();
 }
 
 void flush_thread(void)
 {
+	preempt_disable();
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
 	if (last_task_used_altivec == current)
@@ -437,6 +440,7 @@
 	if (last_task_used_spe == current)
 		last_task_used_spe = NULL;
 #endif
+	preempt_enable();
 }
 
 void
@@ -535,6 +539,7 @@
 	regs->nip = nip;
 	regs->gpr[1] = sp;
 	regs->msr = MSR_USER;
+	preempt_disable();
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
 	if (last_task_used_altivec == current)
@@ -543,6 +548,7 @@
 	if (last_task_used_spe == current)
 		last_task_used_spe = NULL;
 #endif
+	preempt_enable();
 	memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
 	current->thread.fpscr.val = 0;
 #ifdef CONFIG_ALTIVEC
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index 43b8fc2..becbfa3 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -301,6 +301,10 @@
 
 	/* Probe platform for CPUs: always linear. */
 	num_cpus = smp_ops->probe();
+	
+	if (num_cpus < 2)
+		smp_tb_synchronized = 1;
+	
 	for (i = 0; i < num_cpus; ++i)
 		cpu_set(i, cpu_possible_map);
 
diff --git a/arch/ppc/platforms/4xx/ibm440gx.c b/arch/ppc/platforms/4xx/ibm440gx.c
index 956f45e..d24c09e 100644
--- a/arch/ppc/platforms/4xx/ibm440gx.c
+++ b/arch/ppc/platforms/4xx/ibm440gx.c
@@ -58,7 +58,6 @@
 	.wol_irq        = 65,  		/* WOL interrupt number */
 	.mdio_idx       = -1,           /* No shared MDIO */
 	.tah_idx	= 0,		/* TAH device index */
-	.jumbo		= 1,		/* Jumbo frames supported */
 };
 
 static struct ocp_func_emac_data ibm440gx_emac3_def = {
@@ -72,7 +71,6 @@
 	.wol_irq        = 67,  		/* WOL interrupt number */
 	.mdio_idx       = -1,           /* No shared MDIO */
 	.tah_idx	= 1,		/* TAH device index */
-	.jumbo		= 1,		/* Jumbo frames supported */
 };
 OCP_SYSFS_EMAC_DATA()
 
diff --git a/arch/ppc/platforms/4xx/ibm440sp.c b/arch/ppc/platforms/4xx/ibm440sp.c
index feb17e4..71a0117 100644
--- a/arch/ppc/platforms/4xx/ibm440sp.c
+++ b/arch/ppc/platforms/4xx/ibm440sp.c
@@ -31,7 +31,6 @@
 	.wol_irq        = 61,  		/* WOL interrupt number */
 	.mdio_idx       = -1,           /* No shared MDIO */
 	.tah_idx	= -1,		/* No TAH */
-	.jumbo		= 1,		/* Jumbo frames supported */
 };
 OCP_SYSFS_EMAC_DATA()
 
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index d8991b8..5e8cc5e 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -130,10 +130,11 @@
 }
 
 #ifdef CONFIG_CPM2
-static void cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs)
 {
 	while((irq = cpm2_get_irq(regs)) >= 0)
 		__do_IRQ(irq, regs);
+	return IRQ_HANDLED;
 }
 
 static struct irqaction cpm2_irqaction = {
diff --git a/arch/ppc/platforms/lite5200.c b/arch/ppc/platforms/lite5200.c
index d44cc99..7ed52dc3 100644
--- a/arch/ppc/platforms/lite5200.c
+++ b/arch/ppc/platforms/lite5200.c
@@ -196,8 +196,10 @@
 	mpc52xx_set_bat();
 
 	/* No ISA bus by default */
+#ifdef CONFIG_PCI
 	isa_io_base		= 0;
 	isa_mem_base		= 0;
+#endif
 
 	/* Powersave */
 	/* This is provided as an example on how to do it. But you
diff --git a/arch/ppc/platforms/mpc5200.c b/arch/ppc/platforms/mpc5200.c
deleted file mode 100644
index a58db43..0000000
--- a/arch/ppc/platforms/mpc5200.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * arch/ppc/platforms/mpc5200.c
- *
- * OCP Definitions for the boards based on MPC5200 processor. Contains
- * definitions for every common peripherals. (Mostly all but PSCs)
- * 
- * Maintainer : Sylvain Munaut <tnt@246tNt.com>
- *
- * Copyright 2004 Sylvain Munaut <tnt@246tNt.com>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <asm/ocp.h>
-#include <asm/mpc52xx.h>
-
-
-static struct ocp_fs_i2c_data mpc5200_i2c_def = {
-        .flags  = FS_I2C_CLOCK_5200,
-};
-
-
-/* Here is the core_ocp struct.
- * With all the devices common to all board. Even if port multiplexing is
- * not setup for them (if the user don't want them, just don't select the
- * config option). The potentially conflicting devices (like PSCs) goes in
- * board specific file.
- */
-struct ocp_def core_ocp[] = {
-	{
-		.vendor         = OCP_VENDOR_FREESCALE,
-		.function       = OCP_FUNC_IIC,
-		.index          = 0,
-		.paddr          = MPC52xx_I2C1,
-		.irq            = OCP_IRQ_NA,   /* MPC52xx_IRQ_I2C1 - Buggy */
-		.pm             = OCP_CPM_NA,
-		.additions      = &mpc5200_i2c_def,
-	},
-	{
-		.vendor         = OCP_VENDOR_FREESCALE,
-		.function       = OCP_FUNC_IIC,
-		.index          = 1,
-		.paddr          = MPC52xx_I2C2,
-		.irq            = OCP_IRQ_NA,   /* MPC52xx_IRQ_I2C2 - Buggy */
-		.pm             = OCP_CPM_NA,
-		.additions      = &mpc5200_i2c_def,
-	},
-	{	/* Terminating entry */
-		.vendor		= OCP_VENDOR_INVALID
-	}
-};
diff --git a/arch/ppc/platforms/pmac_feature.c b/arch/ppc/platforms/pmac_feature.c
index 1e69b05..6b7b3a1 100644
--- a/arch/ppc/platforms/pmac_feature.c
+++ b/arch/ppc/platforms/pmac_feature.c
@@ -1606,11 +1606,19 @@
 	 */
 
 	if (macio->type == macio_intrepid) {
-		if (enable)
-			UN_OUT(UNI_N_CLOCK_SPREADING, 2);
-		else
-			UN_OUT(UNI_N_CLOCK_SPREADING, 0);
-		mdelay(40);
+		struct device_node *clock =
+			of_find_node_by_path("/uni-n@f8000000/hw-clock");
+		if (clock && get_property(clock, "platform-do-clockspreading",
+					  NULL)) {
+			printk(KERN_INFO "%sabling clock spreading on Intrepid"
+			       " ASIC\n", enable ? "En" : "Dis");
+			if (enable)
+				UN_OUT(UNI_N_CLOCK_SPREADING, 2);
+			else
+				UN_OUT(UNI_N_CLOCK_SPREADING, 0);
+			mdelay(40);
+		}
+		of_node_put(clock);
 	}
 
 	while (machine_is_compatible("PowerBook5,2") ||
@@ -1680,6 +1688,8 @@
 			pmac_low_i2c_close(ui2c);
 			break;
 		}
+		printk(KERN_INFO "%sabling clock spreading on i2c clock chip\n",
+		       enable ? "En" : "Dis");
 		pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub);
 		rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9);
 		DBG("write result: %d,", rc);
diff --git a/arch/ppc/syslib/m82xx_pci.c b/arch/ppc/syslib/m82xx_pci.c
index 1d1c395..1941a8c 100644
--- a/arch/ppc/syslib/m82xx_pci.c
+++ b/arch/ppc/syslib/m82xx_pci.c
@@ -248,7 +248,8 @@
 	pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) *
 			( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1);
 	freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div));
-	time = (int)666666/freq;
+	time = (int)66666666/freq;
+
 	/* due to PCI Local Bus spec, some devices needs to wait such a long
 	time after RST 	deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */
 	printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq,
diff --git a/arch/ppc/syslib/mpc52xx_pci.c b/arch/ppc/syslib/mpc52xx_pci.c
index 4ac1908..313c96e 100644
--- a/arch/ppc/syslib/mpc52xx_pci.c
+++ b/arch/ppc/syslib/mpc52xx_pci.c
@@ -24,6 +24,12 @@
 #include <asm/machdep.h>
 
 
+/* This macro is defined to activate the workaround for the bug
+   435 of the MPC5200 (L25R). With it activated, we don't do any
+   32 bits configuration access during type-1 cycles */
+#define MPC5200_BUG_435_WORKAROUND
+
+
 static int
 mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
 				int offset, int len, u32 *val)
@@ -40,17 +46,39 @@
 		((bus->number - hose->bus_offset) << 16) |
 		(devfn << 8) |
 		(offset & 0xfc));
+	mb();
 
-	value = in_le32(hose->cfg_data);
+#ifdef MPC5200_BUG_435_WORKAROUND
+	if (bus->number != hose->bus_offset) {
+		switch (len) {
+			case 1:
+				value = in_8(((u8 __iomem *)hose->cfg_data) + (offset & 3));
+				break;
+			case 2:
+				value = in_le16(((u16 __iomem *)hose->cfg_data) + ((offset>>1) & 1));
+				break;
 
-	if (len != 4) {
-		value >>= ((offset & 0x3) << 3);
-		value &= 0xffffffff >> (32 - (len << 3));
+			default:
+				value = in_le16((u16 __iomem *)hose->cfg_data) |
+					(in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
+				break;
+		}
+	}
+	else
+#endif
+	{
+		value = in_le32(hose->cfg_data);
+
+		if (len != 4) {
+			value >>= ((offset & 0x3) << 3);
+			value &= 0xffffffff >> (32 - (len << 3));
+		}
 	}
 
 	*val = value;
 
 	out_be32(hose->cfg_addr, 0);
+	mb();
 
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -71,21 +99,48 @@
 		((bus->number - hose->bus_offset) << 16) |
 		(devfn << 8) |
 		(offset & 0xfc));
+	mb();
 
-	if (len != 4) {
-		value = in_le32(hose->cfg_data);
+#ifdef MPC5200_BUG_435_WORKAROUND
+	if (bus->number != hose->bus_offset) {
+		switch (len) {
+			case 1:
+				out_8(((u8 __iomem *)hose->cfg_data) +
+					(offset & 3), val);
+				break;
+			case 2:
+				out_le16(((u16 __iomem *)hose->cfg_data) +
+					((offset>>1) & 1), val);
+				break;
 
-		offset = (offset & 0x3) << 3;
-		mask = (0xffffffff >> (32 - (len << 3)));
-		mask <<= offset;
-
-		value &= ~mask;
-		val = value | ((val << offset) & mask);
+			default:
+				out_le16((u16 __iomem *)hose->cfg_data,
+					(u16)val);
+				out_le16(((u16 __iomem *)hose->cfg_data) + 1,
+					(u16)(val>>16));
+				break;
+		}
 	}
+	else
+#endif
+	{
+		if (len != 4) {
+			value = in_le32(hose->cfg_data);
 
-	out_le32(hose->cfg_data, val);
+			offset = (offset & 0x3) << 3;
+			mask = (0xffffffff >> (32 - (len << 3)));
+			mask <<= offset;
+
+			value &= ~mask;
+			val = value | ((val << offset) & mask);
+		}
+
+		out_le32(hose->cfg_data, val);
+	}
+	mb();
 
 	out_be32(hose->cfg_addr, 0);
+	mb();
 
 	return PCIBIOS_SUCCESSFUL;
 }
@@ -99,9 +154,12 @@
 static void __init
 mpc52xx_pci_setup(struct mpc52xx_pci __iomem *pci_regs)
 {
+	u32 tmp;
 
 	/* Setup control regs */
-		/* Nothing to do afaik */
+	tmp = in_be32(&pci_regs->scr);
+	tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+	out_be32(&pci_regs->scr, tmp);
 
 	/* Setup windows */
 	out_be32(&pci_regs->iw0btar, MPC52xx_PCI_IWBTAR_TRANSLATION(
@@ -142,16 +200,15 @@
 	/* Not necessary and can be a bad thing if for example the bootloader
 	   is displaying a splash screen or ... Just left here for
 	   documentation purpose if anyone need it */
-#if 0
-	u32 tmp;
 	tmp = in_be32(&pci_regs->gscr);
+#if 0
 	out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
 	udelay(50);
-	out_be32(&pci_regs->gscr, tmp);
 #endif
+	out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
 }
 
-static void __init
+static void
 mpc52xx_pci_fixup_resources(struct pci_dev *dev)
 {
 	int i;
diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c
index bb237458..a4a4b02 100644
--- a/arch/ppc/syslib/mpc52xx_setup.c
+++ b/arch/ppc/syslib/mpc52xx_setup.c
@@ -84,9 +84,11 @@
 void __init
 mpc52xx_map_io(void)
 {
-	/* Here we only map the MBAR */
+	/* Here we map the MBAR and the whole upper zone. MBAR is only
+	   64k but we can't map only 64k with BATs. Map the whole
+	   0xf0000000 range is ok and helps eventual lpb devices placed there */
 	io_block_mapping(
-		MPC52xx_MBAR_VIRT, MPC52xx_MBAR, MPC52xx_MBAR_SIZE, _PAGE_IO);
+		MPC52xx_MBAR_VIRT, MPC52xx_MBAR, 0x10000000, _PAGE_IO);
 }
 
 
diff --git a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c
index f15e642..05ccd59 100644
--- a/arch/ppc/syslib/ppc4xx_dma.c
+++ b/arch/ppc/syslib/ppc4xx_dma.c
@@ -30,6 +30,7 @@
 
 #include <asm/system.h>
 #include <asm/io.h>
+#include <asm/dma.h>
 #include <asm/ppc4xx_dma.h>
 
 ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS];
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 477ac27..6fe532d 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -23,14 +23,14 @@
 
 mainmenu "Linux Kernel Configuration"
 
-config ARCH_S390
+config S390
 	bool
 	default y
 
 config UID16
 	bool
 	default y
-	depends on ARCH_S390X = 'n'
+	depends on !64BIT
 
 source "init/Kconfig"
 
@@ -38,20 +38,12 @@
 
 comment "Processor type and features"
 
-config ARCH_S390X
+config 64BIT
 	bool "64 bit kernel"
 	help
 	  Select this option if you have a 64 bit IBM zSeries machine
 	  and want to use the 64 bit addressing mode.
 
-config 64BIT
-	def_bool ARCH_S390X
-
-config ARCH_S390_31
-	bool
-	depends on ARCH_S390X = 'n'
-	default y
-
 config SMP
 	bool "Symmetric multi-processing support"
 	---help---
@@ -101,20 +93,15 @@
 	  on older S/390 machines. Say Y unless you know your machine doesn't
 	  need this.
 
-config S390_SUPPORT
+config COMPAT
 	bool "Kernel support for 31 bit emulation"
-	depends on ARCH_S390X
+	depends on 64BIT
 	help
 	  Select this option if you want to enable your system kernel to
 	  handle system-calls from ELF binaries for 31 bit ESA.  This option
 	  (and some other stuff like libraries and such) is needed for
 	  executing 31 bit applications.  It is safe to say "Y".
 
-config COMPAT
-	bool
-	depends on S390_SUPPORT
-	default y
-
 config SYSVIPC_COMPAT
 	bool
 	depends on COMPAT && SYSVIPC
@@ -122,7 +109,7 @@
 
 config BINFMT_ELF32
 	tristate "Kernel support for 31 bit ELF binaries"
-	depends on S390_SUPPORT
+	depends on COMPAT
 	help
 	  This allows you to run 32-bit Linux/ELF binaries on your zSeries
 	  in 64 bit mode. Everybody wants this; say Y.
@@ -135,7 +122,7 @@
 
 config MARCH_G5
 	bool "S/390 model G5 and G6"
-	depends on ARCH_S390_31
+	depends on !64BIT
 	help
 	  Select this to build a 31 bit kernel that works
 	  on all S/390 and zSeries machines.
@@ -240,8 +227,8 @@
 config QDIO
 	tristate "QDIO support"
 	---help---
-	  This driver provides the Queued Direct I/O base support for the
-	  IBM S/390 (G5 and G6) and eServer zSeries (z800, z890, z900 and z990).
+	  This driver provides the Queued Direct I/O base support for
+	  IBM mainframes.
 
 	  For details please refer to the documentation provided by IBM at
 	  <http://www10.software.ibm.com/developerworks/opensource/linux390>
@@ -263,7 +250,8 @@
 	bool "Extended debugging information"
 	depends on QDIO
 	help
-	  Say Y here to get extended debugging output in /proc/s390dbf/qdio...
+	  Say Y here to get extended debugging output in
+	    /sys/kernel/debug/s390dbf/qdio...
 	  Warning: this option reduces the performance of the QDIO module.
 
 	  If unsure, say N.
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 73a09a6..6c6b197 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -13,16 +13,14 @@
 # Copyright (C) 1994 by Linus Torvalds
 #
 
-ifdef CONFIG_ARCH_S390_31
+ifndef CONFIG_64BIT
 LDFLAGS		:= -m elf_s390
 CFLAGS		+= -m31
 AFLAGS		+= -m31
 UTS_MACHINE	:= s390
 STACK_SIZE	:= 8192
 CHECKFLAGS	+= -D__s390__
-endif
-
-ifdef CONFIG_ARCH_S390X
+else
 LDFLAGS		:= -m elf64_s390
 MODFLAGS	+= -fpic -D__PIC__
 CFLAGS		+= -m64
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c
index dee6ab54..d06a8d7 100644
--- a/arch/s390/appldata/appldata_base.c
+++ b/arch/s390/appldata/appldata_base.c
@@ -40,7 +40,7 @@
 
 #define TOD_MICRO	0x01000			/* nr. of TOD clock units
 						   for 1 microsecond */
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 
 #define APPLDATA_START_INTERVAL_REC 0x00   	/* Function codes for */
 #define APPLDATA_STOP_REC	    0x01	/* DIAG 0xDC	  */
@@ -54,13 +54,13 @@
 #define APPLDATA_GEN_EVENT_RECORD   0x82
 #define APPLDATA_START_CONFIG_REC   0x83
 
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 
 /*
  * Parameter list for DIAGNOSE X'DC'
  */
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 struct appldata_parameter_list {
 	u16 diag;		/* The DIAGNOSE code X'00DC'          */
 	u8  function;		/* The function code for the DIAGNOSE */
@@ -82,7 +82,7 @@
 	u64 product_id_addr;
 	u64 buffer_addr;
 };
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 /*
  * /proc entries (sysctl)
diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c
index e0a476b..99ddd3b 100644
--- a/arch/s390/appldata/appldata_os.c
+++ b/arch/s390/appldata/appldata_os.c
@@ -141,19 +141,19 @@
 	j = 0;
 	for_each_online_cpu(i) {
 		os_data->os_cpu[j].per_cpu_user =
-					kstat_cpu(i).cpustat.user;
+			cputime_to_jiffies(kstat_cpu(i).cpustat.user);
 		os_data->os_cpu[j].per_cpu_nice =
-					kstat_cpu(i).cpustat.nice;
+			cputime_to_jiffies(kstat_cpu(i).cpustat.nice);
 		os_data->os_cpu[j].per_cpu_system =
-					kstat_cpu(i).cpustat.system;
+			cputime_to_jiffies(kstat_cpu(i).cpustat.system);
 		os_data->os_cpu[j].per_cpu_idle =
-					kstat_cpu(i).cpustat.idle;
+			cputime_to_jiffies(kstat_cpu(i).cpustat.idle);
 		os_data->os_cpu[j].per_cpu_irq =
-					kstat_cpu(i).cpustat.irq;
+			cputime_to_jiffies(kstat_cpu(i).cpustat.irq);
 		os_data->os_cpu[j].per_cpu_softirq =
-					kstat_cpu(i).cpustat.softirq;
+			cputime_to_jiffies(kstat_cpu(i).cpustat.softirq);
 		os_data->os_cpu[j].per_cpu_iowait =
-					kstat_cpu(i).cpustat.iowait;
+			cputime_to_jiffies(kstat_cpu(i).cpustat.iowait);
 		j++;
 	}
 
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile
index 96a05e6..bfe2541 100644
--- a/arch/s390/crypto/Makefile
+++ b/arch/s390/crypto/Makefile
@@ -2,7 +2,9 @@
 # Cryptographic API
 #
 
-obj-$(CONFIG_CRYPTO_SHA1_Z990) += sha1_z990.o
-obj-$(CONFIG_CRYPTO_DES_Z990) += des_z990.o des_check_key.o
+obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o
+obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o
+obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o des_check_key.o
+obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
 
-obj-$(CONFIG_CRYPTO_TEST) += crypt_z990_query.o
+obj-$(CONFIG_CRYPTO_TEST) += crypt_s390_query.o
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
new file mode 100644
index 0000000..7a1033d
--- /dev/null
+++ b/arch/s390/crypto/aes_s390.c
@@ -0,0 +1,248 @@
+/*
+ * Cryptographic API.
+ *
+ * s390 implementation of the AES Cipher Algorithm.
+ *
+ * s390 Version:
+ *   Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation
+ *   Author(s): Jan Glauber (jang@de.ibm.com)
+ *
+ * Derived from "crypto/aes.c"
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/crypto.h>
+#include "crypt_s390.h"
+
+#define AES_MIN_KEY_SIZE	16
+#define AES_MAX_KEY_SIZE	32
+
+/* data block size for all key lengths */
+#define AES_BLOCK_SIZE		16
+
+int has_aes_128 = 0;
+int has_aes_192 = 0;
+int has_aes_256 = 0;
+
+struct s390_aes_ctx {
+	u8 iv[AES_BLOCK_SIZE];
+	u8 key[AES_MAX_KEY_SIZE];
+	int key_len;
+};
+
+static int aes_set_key(void *ctx, const u8 *in_key, unsigned int key_len,
+		       u32 *flags)
+{
+	struct s390_aes_ctx *sctx = ctx;
+
+	switch (key_len) {
+	case 16:
+		if (!has_aes_128)
+			goto fail;
+		break;
+	case 24:
+		if (!has_aes_192)
+			goto fail;
+
+		break;
+	case 32:
+		if (!has_aes_256)
+			goto fail;
+		break;
+	default:
+		/* invalid key length */
+		goto fail;
+		break;
+	}
+
+	sctx->key_len = key_len;
+	memcpy(sctx->key, in_key, key_len);
+	return 0;
+fail:
+	*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+	return -EINVAL;
+}
+
+static void aes_encrypt(void *ctx, u8 *out, const u8 *in)
+{
+	const struct s390_aes_ctx *sctx = ctx;
+
+	switch (sctx->key_len) {
+	case 16:
+		crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in,
+			      AES_BLOCK_SIZE);
+		break;
+	case 24:
+		crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in,
+			      AES_BLOCK_SIZE);
+		break;
+	case 32:
+		crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in,
+			      AES_BLOCK_SIZE);
+		break;
+	}
+}
+
+static void aes_decrypt(void *ctx, u8 *out, const u8 *in)
+{
+	const struct s390_aes_ctx *sctx = ctx;
+
+	switch (sctx->key_len) {
+	case 16:
+		crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in,
+			      AES_BLOCK_SIZE);
+		break;
+	case 24:
+		crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in,
+			      AES_BLOCK_SIZE);
+		break;
+	case 32:
+		crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in,
+			      AES_BLOCK_SIZE);
+		break;
+	}
+}
+
+static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+
+	switch (sctx->key_len) {
+	case 16:
+		crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
+		break;
+	case 24:
+		crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
+		break;
+	case 32:
+		crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
+		break;
+	}
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+
+	switch (sctx->key_len) {
+	case 16:
+		crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
+		break;
+	case 24:
+		crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
+		break;
+	case 32:
+		crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
+		break;
+	}
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+
+	memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
+	switch (sctx->key_len) {
+	case 16:
+		crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
+		break;
+	case 24:
+		crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
+		break;
+	case 32:
+		crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
+		break;
+	}
+	memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);
+
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
+				    const u8 *in, unsigned int nbytes)
+{
+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+
+	memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
+	switch (sctx->key_len) {
+	case 16:
+		crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
+		break;
+	case 24:
+		crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
+		break;
+	case 32:
+		crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
+		break;
+	}
+	return nbytes & ~(AES_BLOCK_SIZE - 1);
+}
+
+
+static struct crypto_alg aes_alg = {
+	.cra_name		=	"aes",
+	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct s390_aes_ctx),
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(aes_alg.cra_list),
+	.cra_u			=	{
+		.cipher = {
+			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
+			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
+			.cia_setkey		=	aes_set_key,
+			.cia_encrypt		=	aes_encrypt,
+			.cia_decrypt		=	aes_decrypt,
+			.cia_encrypt_ecb	=	aes_encrypt_ecb,
+			.cia_decrypt_ecb	=	aes_decrypt_ecb,
+			.cia_encrypt_cbc	=	aes_encrypt_cbc,
+			.cia_decrypt_cbc	=	aes_decrypt_cbc,
+		}
+	}
+};
+
+static int __init aes_init(void)
+{
+	int ret;
+
+	if (crypt_s390_func_available(KM_AES_128_ENCRYPT))
+		has_aes_128 = 1;
+	if (crypt_s390_func_available(KM_AES_192_ENCRYPT))
+		has_aes_192 = 1;
+	if (crypt_s390_func_available(KM_AES_256_ENCRYPT))
+		has_aes_256 = 1;
+
+	if (!has_aes_128 && !has_aes_192 && !has_aes_256)
+		return -ENOSYS;
+
+	ret = crypto_register_alg(&aes_alg);
+	if (ret != 0)
+		printk(KERN_INFO "crypt_s390: aes_s390 couldn't be loaded.\n");
+	return ret;
+}
+
+static void __exit aes_fini(void)
+{
+	crypto_unregister_alg(&aes_alg);
+}
+
+module_init(aes_init);
+module_exit(aes_fini);
+
+MODULE_ALIAS("aes");
+
+MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm");
+MODULE_LICENSE("GPL");
+
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h
new file mode 100644
index 0000000..d1c259a
--- /dev/null
+++ b/arch/s390/crypto/crypt_s390.h
@@ -0,0 +1,397 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for s390 cryptographic instructions.
+ *
+ *   Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation
+ *   Author(s): Thomas Spatzier (tspat@de.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.
+ *
+ */
+#ifndef _CRYPTO_ARCH_S390_CRYPT_S390_H
+#define _CRYPTO_ARCH_S390_CRYPT_S390_H
+
+#include <asm/errno.h>
+
+#define CRYPT_S390_OP_MASK 0xFF00
+#define CRYPT_S390_FUNC_MASK 0x00FF
+
+/* s930 cryptographic operations */
+enum crypt_s390_operations {
+	CRYPT_S390_KM   = 0x0100,
+	CRYPT_S390_KMC  = 0x0200,
+	CRYPT_S390_KIMD = 0x0300,
+	CRYPT_S390_KLMD = 0x0400,
+	CRYPT_S390_KMAC = 0x0500
+};
+
+/* function codes for KM (CIPHER MESSAGE) instruction
+ * 0x80 is the decipher modifier bit
+ */
+enum crypt_s390_km_func {
+	KM_QUERY	    = CRYPT_S390_KM | 0x0,
+	KM_DEA_ENCRYPT      = CRYPT_S390_KM | 0x1,
+	KM_DEA_DECRYPT      = CRYPT_S390_KM | 0x1 | 0x80,
+	KM_TDEA_128_ENCRYPT = CRYPT_S390_KM | 0x2,
+	KM_TDEA_128_DECRYPT = CRYPT_S390_KM | 0x2 | 0x80,
+	KM_TDEA_192_ENCRYPT = CRYPT_S390_KM | 0x3,
+	KM_TDEA_192_DECRYPT = CRYPT_S390_KM | 0x3 | 0x80,
+	KM_AES_128_ENCRYPT  = CRYPT_S390_KM | 0x12,
+	KM_AES_128_DECRYPT  = CRYPT_S390_KM | 0x12 | 0x80,
+	KM_AES_192_ENCRYPT  = CRYPT_S390_KM | 0x13,
+	KM_AES_192_DECRYPT  = CRYPT_S390_KM | 0x13 | 0x80,
+	KM_AES_256_ENCRYPT  = CRYPT_S390_KM | 0x14,
+	KM_AES_256_DECRYPT  = CRYPT_S390_KM | 0x14 | 0x80,
+};
+
+/* function codes for KMC (CIPHER MESSAGE WITH CHAINING)
+ * instruction
+ */
+enum crypt_s390_kmc_func {
+	KMC_QUERY            = CRYPT_S390_KMC | 0x0,
+	KMC_DEA_ENCRYPT      = CRYPT_S390_KMC | 0x1,
+	KMC_DEA_DECRYPT      = CRYPT_S390_KMC | 0x1 | 0x80,
+	KMC_TDEA_128_ENCRYPT = CRYPT_S390_KMC | 0x2,
+	KMC_TDEA_128_DECRYPT = CRYPT_S390_KMC | 0x2 | 0x80,
+	KMC_TDEA_192_ENCRYPT = CRYPT_S390_KMC | 0x3,
+	KMC_TDEA_192_DECRYPT = CRYPT_S390_KMC | 0x3 | 0x80,
+	KMC_AES_128_ENCRYPT  = CRYPT_S390_KMC | 0x12,
+	KMC_AES_128_DECRYPT  = CRYPT_S390_KMC | 0x12 | 0x80,
+	KMC_AES_192_ENCRYPT  = CRYPT_S390_KMC | 0x13,
+	KMC_AES_192_DECRYPT  = CRYPT_S390_KMC | 0x13 | 0x80,
+	KMC_AES_256_ENCRYPT  = CRYPT_S390_KMC | 0x14,
+	KMC_AES_256_DECRYPT  = CRYPT_S390_KMC | 0x14 | 0x80,
+};
+
+/* function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
+ * instruction
+ */
+enum crypt_s390_kimd_func {
+	KIMD_QUERY   = CRYPT_S390_KIMD | 0,
+	KIMD_SHA_1   = CRYPT_S390_KIMD | 1,
+	KIMD_SHA_256 = CRYPT_S390_KIMD | 2,
+};
+
+/* function codes for KLMD (COMPUTE LAST MESSAGE DIGEST)
+ * instruction
+ */
+enum crypt_s390_klmd_func {
+	KLMD_QUERY   = CRYPT_S390_KLMD | 0,
+	KLMD_SHA_1   = CRYPT_S390_KLMD | 1,
+	KLMD_SHA_256 = CRYPT_S390_KLMD | 2,
+};
+
+/* function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE)
+ * instruction
+ */
+enum crypt_s390_kmac_func {
+	KMAC_QUERY    = CRYPT_S390_KMAC | 0,
+	KMAC_DEA      = CRYPT_S390_KMAC | 1,
+	KMAC_TDEA_128 = CRYPT_S390_KMAC | 2,
+	KMAC_TDEA_192 = CRYPT_S390_KMAC | 3
+};
+
+/* status word for s390 crypto instructions' QUERY functions */
+struct crypt_s390_query_status {
+	u64 high;
+	u64 low;
+};
+
+/*
+ * Standard fixup and ex_table sections for crypt_s390 inline functions.
+ * label 0: the s390 crypto operation
+ * label 1: just after 1 to catch illegal operation exception
+ *          (unsupported model)
+ * label 6: the return point after fixup
+ * label 7: set error value if exception _in_ crypto operation
+ * label 8: set error value if illegal operation exception
+ * [ret] is the variable to receive the error code
+ * [ERR] is the error code value
+ */
+#ifndef CONFIG_64BIT
+#define __crypt_s390_fixup \
+	".section .fixup,\"ax\" \n"	\
+	"7:	lhi	%0,%h[e1] \n"	\
+	"	bras	1,9f \n"	\
+	"	.long	6b \n"		\
+	"8:	lhi	%0,%h[e2] \n"	\
+	"	bras	1,9f \n"	\
+	"	.long	6b \n"		\
+	"9:	l	1,0(1) \n"	\
+	"	br	1 \n"		\
+	".previous \n"			\
+	".section __ex_table,\"a\" \n"	\
+	"	.align	4 \n"		\
+	"	.long	0b,7b \n"	\
+	"	.long	1b,8b \n"	\
+	".previous"
+#else /* CONFIG_64BIT */
+#define __crypt_s390_fixup \
+	".section .fixup,\"ax\" \n"	\
+	"7:	lhi	%0,%h[e1] \n"	\
+	"	jg	6b \n"		\
+	"8:	lhi	%0,%h[e2] \n"	\
+	"	jg	6b \n"		\
+	".previous\n"			\
+	".section __ex_table,\"a\" \n"	\
+	"	.align	8 \n"		\
+	"	.quad	0b,7b \n"	\
+	"	.quad	1b,8b \n"	\
+	".previous"
+#endif /* CONFIG_64BIT */
+
+/*
+ * Standard code for setting the result of s390 crypto instructions.
+ * %0: the register which will receive the result
+ * [result]: the register containing the result (e.g. second operand length
+ * to compute number of processed bytes].
+ */
+#ifndef CONFIG_64BIT
+#define __crypt_s390_set_result \
+	"	lr	%0,%[result] \n"
+#else /* CONFIG_64BIT */
+#define __crypt_s390_set_result \
+	"	lgr	%0,%[result] \n"
+#endif
+
+/*
+ * Executes the KM (CIPHER MESSAGE) operation of the CPU.
+ * @param func: the function code passed to KM; see crypt_s390_km_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param dest: address of destination memory area
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * 	for encryption/decryption funcs
+ */
+static inline int
+crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len)
+{
+	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
+	register void* __param asm("1") = param;
+	register u8* __dest asm("4") = dest;
+	register const u8* __src asm("2") = src;
+	register long __src_len asm("3") = src_len;
+	int ret;
+
+	ret = 0;
+	__asm__ __volatile__ (
+		"0:	.insn	rre,0xB92E0000,%1,%2 \n" /* KM opcode */
+		"1:	brc	1,0b \n" /* handle partial completion */
+		__crypt_s390_set_result
+		"6:	\n"
+		__crypt_s390_fixup
+		: "+d" (ret), "+a" (__dest), "+a" (__src),
+		  [result] "+d" (__src_len)
+		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+		  "a" (__param)
+		: "cc", "memory"
+	);
+	if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
+		ret = src_len - ret;
+	}
+	return ret;
+}
+
+/*
+ * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the CPU.
+ * @param func: the function code passed to KM; see crypt_s390_kmc_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param dest: address of destination memory area
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * 	for encryption/decryption funcs
+ */
+static inline int
+crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
+{
+	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
+	register void* __param asm("1") = param;
+	register u8* __dest asm("4") = dest;
+	register const u8* __src asm("2") = src;
+	register long __src_len asm("3") = src_len;
+	int ret;
+
+	ret = 0;
+	__asm__ __volatile__ (
+		"0:	.insn	rre,0xB92F0000,%1,%2 \n" /* KMC opcode */
+		"1:	brc	1,0b \n" /* handle partial completion */
+		__crypt_s390_set_result
+		"6:	\n"
+		__crypt_s390_fixup
+		: "+d" (ret), "+a" (__dest), "+a" (__src),
+		  [result] "+d" (__src_len)
+		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+		  "a" (__param)
+		: "cc", "memory"
+	);
+	if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
+		ret = src_len - ret;
+	}
+	return ret;
+}
+
+/*
+ * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
+ * of the CPU.
+ * @param func: the function code passed to KM; see crypt_s390_kimd_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * 	for digest funcs
+ */
+static inline int
+crypt_s390_kimd(long func, void* param, const u8* src, long src_len)
+{
+	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
+	register void* __param asm("1") = param;
+	register const u8* __src asm("2") = src;
+	register long __src_len asm("3") = src_len;
+	int ret;
+
+	ret = 0;
+	__asm__ __volatile__ (
+		"0:	.insn	rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */
+		"1:	brc	1,0b \n" /* handle partical completion */
+		__crypt_s390_set_result
+		"6:	\n"
+		__crypt_s390_fixup
+		: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
+		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+		  "a" (__param)
+		: "cc", "memory"
+	);
+	if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){
+		ret = src_len - ret;
+	}
+	return ret;
+}
+
+/*
+ * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the CPU.
+ * @param func: the function code passed to KM; see crypt_s390_klmd_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * 	for digest funcs
+ */
+static inline int
+crypt_s390_klmd(long func, void* param, const u8* src, long src_len)
+{
+	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
+	register void* __param asm("1") = param;
+	register const u8* __src asm("2") = src;
+	register long __src_len asm("3") = src_len;
+	int ret;
+
+	ret = 0;
+	__asm__ __volatile__ (
+		"0:	.insn	rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */
+		"1:	brc	1,0b \n" /* handle partical completion */
+		__crypt_s390_set_result
+		"6:	\n"
+		__crypt_s390_fixup
+		: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
+		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+		  "a" (__param)
+		: "cc", "memory"
+	);
+	if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
+		ret = src_len - ret;
+	}
+	return ret;
+}
+
+/*
+ * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
+ * of the CPU.
+ * @param func: the function code passed to KM; see crypt_s390_klmd_func
+ * @param param: address of parameter block; see POP for details on each func
+ * @param src: address of source memory area
+ * @param src_len: length of src operand in bytes
+ * @returns < zero for failure, 0 for the query func, number of processed bytes
+ * 	for digest funcs
+ */
+static inline int
+crypt_s390_kmac(long func, void* param, const u8* src, long src_len)
+{
+	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
+	register void* __param asm("1") = param;
+	register const u8* __src asm("2") = src;
+	register long __src_len asm("3") = src_len;
+	int ret;
+
+	ret = 0;
+	__asm__ __volatile__ (
+		"0:	.insn	rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */
+		"1:	brc	1,0b \n" /* handle partical completion */
+		__crypt_s390_set_result
+		"6:	\n"
+		__crypt_s390_fixup
+		: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
+		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
+		  "a" (__param)
+		: "cc", "memory"
+	);
+	if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){
+		ret = src_len - ret;
+	}
+	return ret;
+}
+
+/**
+ * Tests if a specific crypto function is implemented on the machine.
+ * @param func:	the function code of the specific function; 0 if op in general
+ * @return	1 if func available; 0 if func or op in general not available
+ */
+static inline int
+crypt_s390_func_available(int func)
+{
+	int ret;
+
+	struct crypt_s390_query_status status = {
+		.high = 0,
+		.low = 0
+	};
+	switch (func & CRYPT_S390_OP_MASK){
+		case CRYPT_S390_KM:
+			ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
+			break;
+		case CRYPT_S390_KMC:
+			ret = crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
+			break;
+		case CRYPT_S390_KIMD:
+			ret = crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
+			break;
+		case CRYPT_S390_KLMD:
+			ret = crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
+			break;
+		case CRYPT_S390_KMAC:
+			ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
+			break;
+		default:
+			ret = 0;
+			return ret;
+	}
+	if (ret >= 0){
+		func &= CRYPT_S390_FUNC_MASK;
+		func &= 0x7f; //mask modifier bit
+		if (func < 64){
+			ret = (status.high >> (64 - func - 1)) & 0x1;
+		} else {
+			ret = (status.low >> (128 - func - 1)) & 0x1;
+		}
+	} else {
+		ret = 0;
+	}
+	return ret;
+}
+
+#endif // _CRYPTO_ARCH_S390_CRYPT_S390_H
diff --git a/arch/s390/crypto/crypt_s390_query.c b/arch/s390/crypto/crypt_s390_query.c
new file mode 100644
index 0000000..def02bd
--- /dev/null
+++ b/arch/s390/crypto/crypt_s390_query.c
@@ -0,0 +1,129 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for s390 cryptographic instructions.
+ * Testing module for querying processor crypto capabilities.
+ *
+ * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Thomas Spatzier (tspat@de.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.
+ *
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/errno.h>
+#include "crypt_s390.h"
+
+static void query_available_functions(void)
+{
+	printk(KERN_INFO "#####################\n");
+
+	/* query available KM functions */
+	printk(KERN_INFO "KM_QUERY: %d\n",
+		crypt_s390_func_available(KM_QUERY));
+	printk(KERN_INFO "KM_DEA: %d\n",
+		crypt_s390_func_available(KM_DEA_ENCRYPT));
+	printk(KERN_INFO "KM_TDEA_128: %d\n",
+		crypt_s390_func_available(KM_TDEA_128_ENCRYPT));
+	printk(KERN_INFO "KM_TDEA_192: %d\n",
+		crypt_s390_func_available(KM_TDEA_192_ENCRYPT));
+	printk(KERN_INFO "KM_AES_128: %d\n",
+		crypt_s390_func_available(KM_AES_128_ENCRYPT));
+	printk(KERN_INFO "KM_AES_192: %d\n",
+		crypt_s390_func_available(KM_AES_192_ENCRYPT));
+	printk(KERN_INFO "KM_AES_256: %d\n",
+		crypt_s390_func_available(KM_AES_256_ENCRYPT));
+
+	/* query available KMC functions */
+	printk(KERN_INFO "KMC_QUERY: %d\n",
+		crypt_s390_func_available(KMC_QUERY));
+	printk(KERN_INFO "KMC_DEA: %d\n",
+		crypt_s390_func_available(KMC_DEA_ENCRYPT));
+	printk(KERN_INFO "KMC_TDEA_128: %d\n",
+		crypt_s390_func_available(KMC_TDEA_128_ENCRYPT));
+	printk(KERN_INFO "KMC_TDEA_192: %d\n",
+		crypt_s390_func_available(KMC_TDEA_192_ENCRYPT));
+	printk(KERN_INFO "KMC_AES_128: %d\n",
+		crypt_s390_func_available(KMC_AES_128_ENCRYPT));
+	printk(KERN_INFO "KMC_AES_192: %d\n",
+		crypt_s390_func_available(KMC_AES_192_ENCRYPT));
+	printk(KERN_INFO "KMC_AES_256: %d\n",
+		crypt_s390_func_available(KMC_AES_256_ENCRYPT));
+
+	/* query available KIMD fucntions */
+	printk(KERN_INFO "KIMD_QUERY: %d\n",
+		crypt_s390_func_available(KIMD_QUERY));
+	printk(KERN_INFO "KIMD_SHA_1: %d\n",
+		crypt_s390_func_available(KIMD_SHA_1));
+	printk(KERN_INFO "KIMD_SHA_256: %d\n",
+		crypt_s390_func_available(KIMD_SHA_256));
+
+	/* query available KLMD functions */
+	printk(KERN_INFO "KLMD_QUERY: %d\n",
+		crypt_s390_func_available(KLMD_QUERY));
+	printk(KERN_INFO "KLMD_SHA_1: %d\n",
+		crypt_s390_func_available(KLMD_SHA_1));
+	printk(KERN_INFO "KLMD_SHA_256: %d\n",
+		crypt_s390_func_available(KLMD_SHA_256));
+
+	/* query available KMAC functions */
+	printk(KERN_INFO "KMAC_QUERY: %d\n",
+		crypt_s390_func_available(KMAC_QUERY));
+	printk(KERN_INFO "KMAC_DEA: %d\n",
+		crypt_s390_func_available(KMAC_DEA));
+	printk(KERN_INFO "KMAC_TDEA_128: %d\n",
+		crypt_s390_func_available(KMAC_TDEA_128));
+	printk(KERN_INFO "KMAC_TDEA_192: %d\n",
+		crypt_s390_func_available(KMAC_TDEA_192));
+}
+
+static int init(void)
+{
+	struct crypt_s390_query_status status = {
+		.high = 0,
+		.low = 0
+	};
+
+	printk(KERN_INFO "crypt_s390: querying available crypto functions\n");
+	crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
+	printk(KERN_INFO "KM:\t%016llx %016llx\n",
+			(unsigned long long) status.high,
+			(unsigned long long) status.low);
+	status.high = status.low = 0;
+	crypt_s390_kmc(KMC_QUERY, &status, NULL, NULL, 0);
+	printk(KERN_INFO "KMC:\t%016llx %016llx\n",
+			(unsigned long long) status.high,
+			(unsigned long long) status.low);
+	status.high = status.low = 0;
+	crypt_s390_kimd(KIMD_QUERY, &status, NULL, 0);
+	printk(KERN_INFO "KIMD:\t%016llx %016llx\n",
+			(unsigned long long) status.high,
+			(unsigned long long) status.low);
+	status.high = status.low = 0;
+	crypt_s390_klmd(KLMD_QUERY, &status, NULL, 0);
+	printk(KERN_INFO "KLMD:\t%016llx %016llx\n",
+			(unsigned long long) status.high,
+			(unsigned long long) status.low);
+	status.high = status.low = 0;
+	crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
+	printk(KERN_INFO "KMAC:\t%016llx %016llx\n",
+			(unsigned long long) status.high,
+			(unsigned long long) status.low);
+
+	query_available_functions();
+	return -ECANCELED;
+}
+
+static void __exit cleanup(void)
+{
+}
+
+module_init(init);
+module_exit(cleanup);
+
+MODULE_LICENSE("GPL");
diff --git a/arch/s390/crypto/crypt_z990.h b/arch/s390/crypto/crypt_z990.h
deleted file mode 100644
index 4df660b..0000000
--- a/arch/s390/crypto/crypt_z990.h
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Support for z990 cryptographic instructions.
- *
- *   Copyright (C) 2003 IBM Deutschland GmbH, IBM Corporation
- *   Author(s): Thomas Spatzier (tspat@de.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.
- *
- */
-#ifndef _CRYPTO_ARCH_S390_CRYPT_Z990_H
-#define _CRYPTO_ARCH_S390_CRYPT_Z990_H
-
-#include <asm/errno.h>
-
-#define CRYPT_Z990_OP_MASK 0xFF00
-#define CRYPT_Z990_FUNC_MASK 0x00FF
-
-
-/*z990 cryptographic operations*/
-enum crypt_z990_operations {
-	CRYPT_Z990_KM   = 0x0100,
-	CRYPT_Z990_KMC  = 0x0200,
-	CRYPT_Z990_KIMD = 0x0300,
-	CRYPT_Z990_KLMD = 0x0400,
-	CRYPT_Z990_KMAC = 0x0500
-};
-
-/*function codes for KM (CIPHER MESSAGE) instruction*/
-enum crypt_z990_km_func {
-	KM_QUERY            = CRYPT_Z990_KM | 0,
-	KM_DEA_ENCRYPT      = CRYPT_Z990_KM | 1,
-	KM_DEA_DECRYPT      = CRYPT_Z990_KM | 1 | 0x80, //modifier bit->decipher
-	KM_TDEA_128_ENCRYPT = CRYPT_Z990_KM | 2,
-	KM_TDEA_128_DECRYPT = CRYPT_Z990_KM | 2 | 0x80,
-	KM_TDEA_192_ENCRYPT = CRYPT_Z990_KM | 3,
-	KM_TDEA_192_DECRYPT = CRYPT_Z990_KM | 3 | 0x80,
-};
-
-/*function codes for KMC (CIPHER MESSAGE WITH CHAINING) instruction*/
-enum crypt_z990_kmc_func {
-	KMC_QUERY            = CRYPT_Z990_KMC | 0,
-	KMC_DEA_ENCRYPT      = CRYPT_Z990_KMC | 1,
-	KMC_DEA_DECRYPT      = CRYPT_Z990_KMC | 1 | 0x80, //modifier bit->decipher
-	KMC_TDEA_128_ENCRYPT = CRYPT_Z990_KMC | 2,
-	KMC_TDEA_128_DECRYPT = CRYPT_Z990_KMC | 2 | 0x80,
-	KMC_TDEA_192_ENCRYPT = CRYPT_Z990_KMC | 3,
-	KMC_TDEA_192_DECRYPT = CRYPT_Z990_KMC | 3 | 0x80,
-};
-
-/*function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) instruction*/
-enum crypt_z990_kimd_func {
-	KIMD_QUERY   = CRYPT_Z990_KIMD | 0,
-	KIMD_SHA_1   = CRYPT_Z990_KIMD | 1,
-};
-
-/*function codes for KLMD (COMPUTE LAST MESSAGE DIGEST) instruction*/
-enum crypt_z990_klmd_func {
-	KLMD_QUERY   = CRYPT_Z990_KLMD | 0,
-	KLMD_SHA_1   = CRYPT_Z990_KLMD | 1,
-};
-
-/*function codes for KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) instruction*/
-enum crypt_z990_kmac_func {
-	KMAC_QUERY    = CRYPT_Z990_KMAC | 0,
-	KMAC_DEA      = CRYPT_Z990_KMAC | 1,
-	KMAC_TDEA_128 = CRYPT_Z990_KMAC | 2,
-	KMAC_TDEA_192 = CRYPT_Z990_KMAC | 3
-};
-
-/*status word for z990 crypto instructions' QUERY functions*/
-struct crypt_z990_query_status {
-	u64 high;
-	u64 low;
-};
-
-/*
- * Standard fixup and ex_table sections for crypt_z990 inline functions.
- * label 0: the z990 crypto operation
- * label 1: just after 1 to catch illegal operation exception on non-z990
- * label 6: the return point after fixup
- * label 7: set error value if exception _in_ crypto operation
- * label 8: set error value if illegal operation exception
- * [ret] is the variable to receive the error code
- * [ERR] is the error code value
- */
-#ifndef __s390x__
-#define __crypt_z990_fixup \
-	".section .fixup,\"ax\" \n"	\
-	"7:	lhi	%0,%h[e1] \n"	\
-	"	bras	1,9f \n"	\
-	"	.long	6b \n"		\
-	"8:	lhi	%0,%h[e2] \n"	\
-	"	bras	1,9f \n"	\
-	"	.long	6b \n"		\
-	"9:	l	1,0(1) \n"	\
-	"	br	1 \n"		\
-	".previous \n"			\
-	".section __ex_table,\"a\" \n"	\
-	"	.align	4 \n"		\
-	"	.long	0b,7b \n"	\
-	"	.long	1b,8b \n"	\
-	".previous"
-#else /* __s390x__ */
-#define __crypt_z990_fixup \
-	".section .fixup,\"ax\" \n"	\
-	"7:	lhi	%0,%h[e1] \n"	\
-	"	jg	6b \n"		\
-	"8:	lhi	%0,%h[e2] \n"	\
-	"	jg	6b \n"		\
-	".previous\n"			\
-	".section __ex_table,\"a\" \n"	\
-	"	.align	8 \n"		\
-	"	.quad	0b,7b \n"	\
-	"	.quad	1b,8b \n"	\
-	".previous"
-#endif /* __s390x__ */
-
-/*
- * Standard code for setting the result of z990 crypto instructions.
- * %0: the register which will receive the result
- * [result]: the register containing the result (e.g. second operand length
- * to compute number of processed bytes].
- */
-#ifndef __s390x__
-#define __crypt_z990_set_result \
-	"	lr	%0,%[result] \n"
-#else /* __s390x__ */
-#define __crypt_z990_set_result \
-	"	lgr	%0,%[result] \n"
-#endif
-
-/*
- * Executes the KM (CIPHER MESSAGE) operation of the z990 CPU.
- * @param func: the function code passed to KM; see crypt_z990_km_func
- * @param param: address of parameter block; see POP for details on each func
- * @param dest: address of destination memory area
- * @param src: address of source memory area
- * @param src_len: length of src operand in bytes
- * @returns < zero for failure, 0 for the query func, number of processed bytes
- * 	for encryption/decryption funcs
- */
-static inline int
-crypt_z990_km(long func, void* param, u8* dest, const u8* src, long src_len)
-{
-	register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
-	register void* __param asm("1") = param;
-	register u8* __dest asm("4") = dest;
-	register const u8* __src asm("2") = src;
-	register long __src_len asm("3") = src_len;
-	int ret;
-
-	ret = 0;
-	__asm__ __volatile__ (
-		"0:	.insn	rre,0xB92E0000,%1,%2 \n" //KM opcode
-		"1:	brc	1,0b \n" //handle partial completion
-		__crypt_z990_set_result
-		"6:	\n"
-		__crypt_z990_fixup
-		: "+d" (ret), "+a" (__dest), "+a" (__src),
-		  [result] "+d" (__src_len)
-		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-		  "a" (__param)
-		: "cc", "memory"
-	);
-	if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){
-		ret = src_len - ret;
-	}
-	return ret;
-}
-
-/*
- * Executes the KMC (CIPHER MESSAGE WITH CHAINING) operation of the z990 CPU.
- * @param func: the function code passed to KM; see crypt_z990_kmc_func
- * @param param: address of parameter block; see POP for details on each func
- * @param dest: address of destination memory area
- * @param src: address of source memory area
- * @param src_len: length of src operand in bytes
- * @returns < zero for failure, 0 for the query func, number of processed bytes
- * 	for encryption/decryption funcs
- */
-static inline int
-crypt_z990_kmc(long func, void* param, u8* dest, const u8* src, long src_len)
-{
-	register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
-	register void* __param asm("1") = param;
-	register u8* __dest asm("4") = dest;
-	register const u8* __src asm("2") = src;
-	register long __src_len asm("3") = src_len;
-	int ret;
-
-	ret = 0;
-	__asm__ __volatile__ (
-		"0:	.insn	rre,0xB92F0000,%1,%2 \n" //KMC opcode
-		"1:	brc	1,0b \n" //handle partial completion
-		__crypt_z990_set_result
-		"6:	\n"
-		__crypt_z990_fixup
-		: "+d" (ret), "+a" (__dest), "+a" (__src),
-		  [result] "+d" (__src_len)
-		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-		  "a" (__param)
-		: "cc", "memory"
-	);
-	if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){
-		ret = src_len - ret;
-	}
-	return ret;
-}
-
-/*
- * Executes the KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST) operation
- * of the z990 CPU.
- * @param func: the function code passed to KM; see crypt_z990_kimd_func
- * @param param: address of parameter block; see POP for details on each func
- * @param src: address of source memory area
- * @param src_len: length of src operand in bytes
- * @returns < zero for failure, 0 for the query func, number of processed bytes
- * 	for digest funcs
- */
-static inline int
-crypt_z990_kimd(long func, void* param, const u8* src, long src_len)
-{
-	register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
-	register void* __param asm("1") = param;
-	register const u8* __src asm("2") = src;
-	register long __src_len asm("3") = src_len;
-	int ret;
-
-	ret = 0;
-	__asm__ __volatile__ (
-		"0:	.insn	rre,0xB93E0000,%1,%1 \n" //KIMD opcode
-		"1:	brc	1,0b \n" /*handle partical completion of kimd*/
-		__crypt_z990_set_result
-		"6:	\n"
-		__crypt_z990_fixup
-		: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
-		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-		  "a" (__param)
-		: "cc", "memory"
-	);
-	if (ret >= 0 && (func & CRYPT_Z990_FUNC_MASK)){
-		ret = src_len - ret;
-	}
-	return ret;
-}
-
-/*
- * Executes the KLMD (COMPUTE LAST MESSAGE DIGEST) operation of the z990 CPU.
- * @param func: the function code passed to KM; see crypt_z990_klmd_func
- * @param param: address of parameter block; see POP for details on each func
- * @param src: address of source memory area
- * @param src_len: length of src operand in bytes
- * @returns < zero for failure, 0 for the query func, number of processed bytes
- * 	for digest funcs
- */
-static inline int
-crypt_z990_klmd(long func, void* param, const u8* src, long src_len)
-{
-	register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
-	register void* __param asm("1") = param;
-	register const u8* __src asm("2") = src;
-	register long __src_len asm("3") = src_len;
-	int ret;
-
-	ret = 0;
-	__asm__ __volatile__ (
-		"0:	.insn	rre,0xB93F0000,%1,%1 \n" //KLMD opcode
-		"1:	brc	1,0b \n" /*handle partical completion of klmd*/
-		__crypt_z990_set_result
-		"6:	\n"
-		__crypt_z990_fixup
-		: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
-		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-		  "a" (__param)
-		: "cc", "memory"
-	);
-	if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){
-		ret = src_len - ret;
-	}
-	return ret;
-}
-
-/*
- * Executes the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) operation
- * of the z990 CPU.
- * @param func: the function code passed to KM; see crypt_z990_klmd_func
- * @param param: address of parameter block; see POP for details on each func
- * @param src: address of source memory area
- * @param src_len: length of src operand in bytes
- * @returns < zero for failure, 0 for the query func, number of processed bytes
- * 	for digest funcs
- */
-static inline int
-crypt_z990_kmac(long func, void* param, const u8* src, long src_len)
-{
-	register long __func asm("0") = func & CRYPT_Z990_FUNC_MASK;
-	register void* __param asm("1") = param;
-	register const u8* __src asm("2") = src;
-	register long __src_len asm("3") = src_len;
-	int ret;
-
-	ret = 0;
-	__asm__ __volatile__ (
-		"0:	.insn	rre,0xB91E0000,%5,%5 \n" //KMAC opcode
-		"1:	brc	1,0b \n" /*handle partical completion of klmd*/
-		__crypt_z990_set_result
-		"6:	\n"
-		__crypt_z990_fixup
-		: "+d" (ret), "+a" (__src), [result] "+d" (__src_len)
-		: [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func),
-		  "a" (__param)
-		: "cc", "memory"
-	);
-	if (ret >= 0 && func & CRYPT_Z990_FUNC_MASK){
-		ret = src_len - ret;
-	}
-	return ret;
-}
-
-/**
- * Tests if a specific z990 crypto function is implemented on the machine.
- * @param func:	the function code of the specific function; 0 if op in general
- * @return	1 if func available; 0 if func or op in general not available
- */
-static inline int
-crypt_z990_func_available(int func)
-{
-	int ret;
-
-	struct crypt_z990_query_status status = {
-		.high = 0,
-		.low = 0
-	};
-	switch (func & CRYPT_Z990_OP_MASK){
-		case CRYPT_Z990_KM:
-			ret = crypt_z990_km(KM_QUERY, &status, NULL, NULL, 0);
-			break;
-		case CRYPT_Z990_KMC:
-			ret = crypt_z990_kmc(KMC_QUERY, &status, NULL, NULL, 0);
-			break;
-		case CRYPT_Z990_KIMD:
-			ret = crypt_z990_kimd(KIMD_QUERY, &status, NULL, 0);
-			break;
-		case CRYPT_Z990_KLMD:
-			ret = crypt_z990_klmd(KLMD_QUERY, &status, NULL, 0);
-			break;
-		case CRYPT_Z990_KMAC:
-			ret = crypt_z990_kmac(KMAC_QUERY, &status, NULL, 0);
-			break;
-		default:
-			ret = 0;
-			return ret;
-	}
-	if (ret >= 0){
-		func &= CRYPT_Z990_FUNC_MASK;
-		func &= 0x7f; //mask modifier bit
-		if (func < 64){
-			ret = (status.high >> (64 - func - 1)) & 0x1;
-		} else {
-			ret = (status.low >> (128 - func - 1)) & 0x1;
-		}
-	} else {
-		ret = 0;
-	}
-	return ret;
-}
-
-
-#endif // _CRYPTO_ARCH_S390_CRYPT_Z990_H
diff --git a/arch/s390/crypto/crypt_z990_query.c b/arch/s390/crypto/crypt_z990_query.c
deleted file mode 100644
index 7133983..0000000
--- a/arch/s390/crypto/crypt_z990_query.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Support for z990 cryptographic instructions.
- * Testing module for querying processor crypto capabilities.
- *
- * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Thomas Spatzier (tspat@de.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.
- *
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <asm/errno.h>
-#include "crypt_z990.h"
-
-static void
-query_available_functions(void)
-{
-	printk(KERN_INFO "#####################\n");
-	//query available KM functions
-	printk(KERN_INFO "KM_QUERY: %d\n",
-			crypt_z990_func_available(KM_QUERY));
-	printk(KERN_INFO "KM_DEA: %d\n",
-			crypt_z990_func_available(KM_DEA_ENCRYPT));
-	printk(KERN_INFO "KM_TDEA_128: %d\n",
-			crypt_z990_func_available(KM_TDEA_128_ENCRYPT));
-	printk(KERN_INFO "KM_TDEA_192: %d\n",
-			crypt_z990_func_available(KM_TDEA_192_ENCRYPT));
-	//query available KMC functions
-	printk(KERN_INFO "KMC_QUERY: %d\n",
-			crypt_z990_func_available(KMC_QUERY));
-	printk(KERN_INFO "KMC_DEA: %d\n",
-			crypt_z990_func_available(KMC_DEA_ENCRYPT));
-	printk(KERN_INFO "KMC_TDEA_128: %d\n",
-			crypt_z990_func_available(KMC_TDEA_128_ENCRYPT));
-	printk(KERN_INFO "KMC_TDEA_192: %d\n",
-			crypt_z990_func_available(KMC_TDEA_192_ENCRYPT));
-	//query available KIMD fucntions
-	printk(KERN_INFO "KIMD_QUERY: %d\n",
-			crypt_z990_func_available(KIMD_QUERY));
-	printk(KERN_INFO "KIMD_SHA_1: %d\n",
-			crypt_z990_func_available(KIMD_SHA_1));
-	//query available KLMD functions
-	printk(KERN_INFO "KLMD_QUERY: %d\n",
-			crypt_z990_func_available(KLMD_QUERY));
-	printk(KERN_INFO "KLMD_SHA_1: %d\n",
-			crypt_z990_func_available(KLMD_SHA_1));
-	//query available KMAC functions
-	printk(KERN_INFO "KMAC_QUERY: %d\n",
-			crypt_z990_func_available(KMAC_QUERY));
-	printk(KERN_INFO "KMAC_DEA: %d\n",
-			crypt_z990_func_available(KMAC_DEA));
-	printk(KERN_INFO "KMAC_TDEA_128: %d\n",
-			crypt_z990_func_available(KMAC_TDEA_128));
-	printk(KERN_INFO "KMAC_TDEA_192: %d\n",
-			crypt_z990_func_available(KMAC_TDEA_192));
-}
-
-static int
-init(void)
-{
-	struct crypt_z990_query_status status = {
-		.high = 0,
-		.low = 0
-	};
-
-	printk(KERN_INFO "crypt_z990: querying available crypto functions\n");
-	crypt_z990_km(KM_QUERY, &status, NULL, NULL, 0);
-	printk(KERN_INFO "KM: %016llx %016llx\n",
-			(unsigned long long) status.high,
-			(unsigned long long) status.low);
-	status.high = status.low = 0;
-	crypt_z990_kmc(KMC_QUERY, &status, NULL, NULL, 0);
-	printk(KERN_INFO "KMC: %016llx %016llx\n",
-			(unsigned long long) status.high,
-			(unsigned long long) status.low);
-	status.high = status.low = 0;
-	crypt_z990_kimd(KIMD_QUERY, &status, NULL, 0);
-	printk(KERN_INFO "KIMD: %016llx %016llx\n",
-			(unsigned long long) status.high,
-			(unsigned long long) status.low);
-	status.high = status.low = 0;
-	crypt_z990_klmd(KLMD_QUERY, &status, NULL, 0);
-	printk(KERN_INFO "KLMD: %016llx %016llx\n",
-			(unsigned long long) status.high,
-			(unsigned long long) status.low);
-	status.high = status.low = 0;
-	crypt_z990_kmac(KMAC_QUERY, &status, NULL, 0);
-	printk(KERN_INFO "KMAC: %016llx %016llx\n",
-			(unsigned long long) status.high,
-			(unsigned long long) status.low);
-
-	query_available_functions();
-	return -1;
-}
-
-static void __exit
-cleanup(void)
-{
-}
-
-module_init(init);
-module_exit(cleanup);
-
-MODULE_LICENSE("GPL");
diff --git a/arch/s390/crypto/des_z990.c b/arch/s390/crypto/des_s390.c
similarity index 81%
rename from arch/s390/crypto/des_z990.c
rename to arch/s390/crypto/des_s390.c
index 813cf37..a38bb2a 100644
--- a/arch/s390/crypto/des_z990.c
+++ b/arch/s390/crypto/des_s390.c
@@ -1,7 +1,7 @@
 /*
  * Cryptographic API.
  *
- * z990 implementation of the DES Cipher Algorithm.
+ * s390 implementation of the DES Cipher Algorithm.
  *
  * Copyright (c) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
  * Author(s): Thomas Spatzier (tspat@de.ibm.com)
@@ -19,7 +19,7 @@
 #include <linux/errno.h>
 #include <asm/scatterlist.h>
 #include <linux/crypto.h>
-#include "crypt_z990.h"
+#include "crypt_s390.h"
 #include "crypto_des.h"
 
 #define DES_BLOCK_SIZE 8
@@ -31,17 +31,17 @@
 #define DES3_192_KEY_SIZE	(3 * DES_KEY_SIZE)
 #define DES3_192_BLOCK_SIZE	DES_BLOCK_SIZE
 
-struct crypt_z990_des_ctx {
+struct crypt_s390_des_ctx {
 	u8 iv[DES_BLOCK_SIZE];
 	u8 key[DES_KEY_SIZE];
 };
 
-struct crypt_z990_des3_128_ctx {
+struct crypt_s390_des3_128_ctx {
 	u8 iv[DES_BLOCK_SIZE];
 	u8 key[DES3_128_KEY_SIZE];
 };
 
-struct crypt_z990_des3_192_ctx {
+struct crypt_s390_des3_192_ctx {
 	u8 iv[DES_BLOCK_SIZE];
 	u8 key[DES3_192_KEY_SIZE];
 };
@@ -49,7 +49,7 @@
 static int
 des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
 {
-	struct crypt_z990_des_ctx *dctx;
+	struct crypt_s390_des_ctx *dctx;
 	int ret;
 
 	dctx = ctx;
@@ -65,26 +65,26 @@
 static void
 des_encrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	struct crypt_z990_des_ctx *dctx;
+	struct crypt_s390_des_ctx *dctx;
 
 	dctx = ctx;
-	crypt_z990_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+	crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
 }
 
 static void
 des_decrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	struct crypt_z990_des_ctx *dctx;
+	struct crypt_s390_des_ctx *dctx;
 
 	dctx = ctx;
-	crypt_z990_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+	crypt_s390_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
 }
 
 static struct crypto_alg des_alg = {
 	.cra_name		=	"des",
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	DES_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct crypt_z990_des_ctx),
+	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
 	.cra_u			=	{ .cipher = {
@@ -111,7 +111,7 @@
 des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
 {
 	int i, ret;
-	struct crypt_z990_des3_128_ctx *dctx;
+	struct crypt_s390_des3_128_ctx *dctx;
 	const u8* temp_key = key;
 
 	dctx = ctx;
@@ -132,20 +132,20 @@
 static void
 des3_128_encrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	struct crypt_z990_des3_128_ctx *dctx;
+	struct crypt_s390_des3_128_ctx *dctx;
 
 	dctx = ctx;
-	crypt_z990_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src,
+	crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src,
 			DES3_128_BLOCK_SIZE);
 }
 
 static void
 des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	struct crypt_z990_des3_128_ctx *dctx;
+	struct crypt_s390_des3_128_ctx *dctx;
 
 	dctx = ctx;
-	crypt_z990_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src,
+	crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src,
 			DES3_128_BLOCK_SIZE);
 }
 
@@ -153,7 +153,7 @@
 	.cra_name		=	"des3_ede128",
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	DES3_128_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct crypt_z990_des3_128_ctx),
+	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_128_ctx),
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(des3_128_alg.cra_list),
 	.cra_u			=	{ .cipher = {
@@ -181,7 +181,7 @@
 des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
 {
 	int i, ret;
-	struct crypt_z990_des3_192_ctx *dctx;
+	struct crypt_s390_des3_192_ctx *dctx;
 	const u8* temp_key;
 
 	dctx = ctx;
@@ -206,20 +206,20 @@
 static void
 des3_192_encrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	struct crypt_z990_des3_192_ctx *dctx;
+	struct crypt_s390_des3_192_ctx *dctx;
 
 	dctx = ctx;
-	crypt_z990_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
+	crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
 			DES3_192_BLOCK_SIZE);
 }
 
 static void
 des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
 {
-	struct crypt_z990_des3_192_ctx *dctx;
+	struct crypt_s390_des3_192_ctx *dctx;
 
 	dctx = ctx;
-	crypt_z990_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
+	crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
 			DES3_192_BLOCK_SIZE);
 }
 
@@ -227,7 +227,7 @@
 	.cra_name		=	"des3_ede",
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	DES3_192_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct crypt_z990_des3_192_ctx),
+	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(des3_192_alg.cra_list),
 	.cra_u			=	{ .cipher = {
@@ -245,9 +245,9 @@
 {
 	int ret;
 
-	if (!crypt_z990_func_available(KM_DEA_ENCRYPT) ||
-	    !crypt_z990_func_available(KM_TDEA_128_ENCRYPT) ||
-	    !crypt_z990_func_available(KM_TDEA_192_ENCRYPT)){
+	if (!crypt_s390_func_available(KM_DEA_ENCRYPT) ||
+	    !crypt_s390_func_available(KM_TDEA_128_ENCRYPT) ||
+	    !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)){
 		return -ENOSYS;
 	}
 
@@ -262,7 +262,7 @@
 		return -EEXIST;
 	}
 
-	printk(KERN_INFO "crypt_z990: des_z990 loaded.\n");
+	printk(KERN_INFO "crypt_s390: des_s390 loaded.\n");
 	return 0;
 }
 
diff --git a/arch/s390/crypto/sha1_z990.c b/arch/s390/crypto/sha1_s390.c
similarity index 82%
rename from arch/s390/crypto/sha1_z990.c
rename to arch/s390/crypto/sha1_s390.c
index 298174d..98c896b 100644
--- a/arch/s390/crypto/sha1_z990.c
+++ b/arch/s390/crypto/sha1_s390.c
@@ -1,7 +1,7 @@
 /*
  * Cryptographic API.
  *
- * z990 implementation of the SHA1 Secure Hash Algorithm.
+ * s390 implementation of the SHA1 Secure Hash Algorithm.
  *
  * Derived from cryptoapi implementation, adapted for in-place
  * scatterlist interface.  Originally based on the public domain
@@ -28,22 +28,22 @@
 #include <linux/crypto.h>
 #include <asm/scatterlist.h>
 #include <asm/byteorder.h>
-#include "crypt_z990.h"
+#include "crypt_s390.h"
 
 #define SHA1_DIGEST_SIZE	20
 #define SHA1_BLOCK_SIZE		64
 
-struct crypt_z990_sha1_ctx {
-        u64 count;
-        u32 state[5];
+struct crypt_s390_sha1_ctx {
+	u64 count;
+	u32 state[5];
 	u32 buf_len;
-        u8 buffer[2 * SHA1_BLOCK_SIZE];
+	u8 buffer[2 * SHA1_BLOCK_SIZE];
 };
 
 static void
 sha1_init(void *ctx)
 {
-	static const struct crypt_z990_sha1_ctx initstate = {
+	static const struct crypt_s390_sha1_ctx initstate = {
 		.state = {
 			0x67452301,
 			0xEFCDAB89,
@@ -58,7 +58,7 @@
 static void
 sha1_update(void *ctx, const u8 *data, unsigned int len)
 {
-	struct crypt_z990_sha1_ctx *sctx;
+	struct crypt_s390_sha1_ctx *sctx;
 	long imd_len;
 
 	sctx = ctx;
@@ -69,7 +69,7 @@
 		//complete full block and hash
 		memcpy(sctx->buffer + sctx->buf_len, data,
 				SHA1_BLOCK_SIZE - sctx->buf_len);
-		crypt_z990_kimd(KIMD_SHA_1, sctx->state, sctx->buffer,
+		crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer,
 				SHA1_BLOCK_SIZE);
 		data += SHA1_BLOCK_SIZE - sctx->buf_len;
 		len -= SHA1_BLOCK_SIZE - sctx->buf_len;
@@ -79,7 +79,7 @@
 	//rest of data contains full blocks?
 	imd_len = len & ~0x3ful;
 	if (imd_len){
-		crypt_z990_kimd(KIMD_SHA_1, sctx->state, data, imd_len);
+		crypt_s390_kimd(KIMD_SHA_1, sctx->state, data, imd_len);
 		data += imd_len;
 		len -= imd_len;
 	}
@@ -92,7 +92,7 @@
 
 
 static void
-pad_message(struct crypt_z990_sha1_ctx* sctx)
+pad_message(struct crypt_s390_sha1_ctx* sctx)
 {
 	int index;
 
@@ -113,11 +113,11 @@
 static void
 sha1_final(void* ctx, u8 *out)
 {
-	struct crypt_z990_sha1_ctx *sctx = ctx;
+	struct crypt_s390_sha1_ctx *sctx = ctx;
 
 	//must perform manual padding
 	pad_message(sctx);
-	crypt_z990_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, sctx->buf_len);
+	crypt_s390_kimd(KIMD_SHA_1, sctx->state, sctx->buffer, sctx->buf_len);
 	//copy digest to out
 	memcpy(out, sctx->state, SHA1_DIGEST_SIZE);
 	/* Wipe context */
@@ -128,7 +128,7 @@
 	.cra_name	=	"sha1",
 	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
 	.cra_blocksize	=	SHA1_BLOCK_SIZE,
-	.cra_ctxsize	=	sizeof(struct crypt_z990_sha1_ctx),
+	.cra_ctxsize	=	sizeof(struct crypt_s390_sha1_ctx),
 	.cra_module	=	THIS_MODULE,
 	.cra_list       =       LIST_HEAD_INIT(alg.cra_list),
 	.cra_u		=	{ .digest = {
@@ -143,10 +143,10 @@
 {
 	int ret = -ENOSYS;
 
-	if (crypt_z990_func_available(KIMD_SHA_1)){
+	if (crypt_s390_func_available(KIMD_SHA_1)){
 		ret = crypto_register_alg(&alg);
 		if (ret == 0){
-			printk(KERN_INFO "crypt_z990: sha1_z990 loaded.\n");
+			printk(KERN_INFO "crypt_s390: sha1_s390 loaded.\n");
 		}
 	}
 	return ret;
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
new file mode 100644
index 0000000..b75bdbd
--- /dev/null
+++ b/arch/s390/crypto/sha256_s390.c
@@ -0,0 +1,151 @@
+/*
+ * Cryptographic API.
+ *
+ * s390 implementation of the SHA256 Secure Hash Algorithm.
+ *
+ * s390 Version:
+ *   Copyright (C) 2005 IBM Deutschland GmbH, IBM Corporation
+ *   Author(s): Jan Glauber (jang@de.ibm.com)
+ *
+ * Derived from "crypto/sha256.c"
+ * and "arch/s390/crypto/sha1_s390.c"
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/crypto.h>
+
+#include "crypt_s390.h"
+
+#define SHA256_DIGEST_SIZE	32
+#define SHA256_BLOCK_SIZE	64
+
+struct s390_sha256_ctx {
+	u64 count;
+	u32 state[8];
+	u8 buf[2 * SHA256_BLOCK_SIZE];
+};
+
+static void sha256_init(void *ctx)
+{
+	struct s390_sha256_ctx *sctx = ctx;
+
+	sctx->state[0] = 0x6a09e667;
+	sctx->state[1] = 0xbb67ae85;
+	sctx->state[2] = 0x3c6ef372;
+	sctx->state[3] = 0xa54ff53a;
+	sctx->state[4] = 0x510e527f;
+	sctx->state[5] = 0x9b05688c;
+	sctx->state[6] = 0x1f83d9ab;
+	sctx->state[7] = 0x5be0cd19;
+	sctx->count = 0;
+	memset(sctx->buf, 0, sizeof(sctx->buf));
+}
+
+static void sha256_update(void *ctx, const u8 *data, unsigned int len)
+{
+	struct s390_sha256_ctx *sctx = ctx;
+	unsigned int index;
+
+	/* how much is already in the buffer? */
+	index = sctx->count / 8 & 0x3f;
+
+	/* update message bit length */
+	sctx->count += len * 8;
+
+	/* process one block */
+	if ((index + len) >= SHA256_BLOCK_SIZE) {
+		memcpy(sctx->buf + index, data, SHA256_BLOCK_SIZE - index);
+		crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
+				SHA256_BLOCK_SIZE);
+		data += SHA256_BLOCK_SIZE - index;
+		len -= SHA256_BLOCK_SIZE - index;
+	}
+
+	/* anything left? */
+	if (len)
+		memcpy(sctx->buf + index , data, len);
+}
+
+static void pad_message(struct s390_sha256_ctx* sctx)
+{
+	int index, end;
+
+	index = sctx->count / 8 & 0x3f;
+	end = index < 56 ? SHA256_BLOCK_SIZE : 2 * SHA256_BLOCK_SIZE;
+
+	/* start pad with 1 */
+	sctx->buf[index] = 0x80;
+
+	/* pad with zeros */
+	index++;
+	memset(sctx->buf + index, 0x00, end - index - 8);
+
+	/* append message length */
+	memcpy(sctx->buf + end - 8, &sctx->count, sizeof sctx->count);
+
+	sctx->count = end * 8;
+}
+
+/* Add padding and return the message digest */
+static void sha256_final(void* ctx, u8 *out)
+{
+	struct s390_sha256_ctx *sctx = ctx;
+
+	/* must perform manual padding */
+	pad_message(sctx);
+
+	crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
+			sctx->count / 8);
+
+	/* copy digest to out */
+	memcpy(out, sctx->state, SHA256_DIGEST_SIZE);
+
+	/* wipe context */
+	memset(sctx, 0, sizeof *sctx);
+}
+
+static struct crypto_alg alg = {
+	.cra_name	=	"sha256",
+	.cra_flags	=	CRYPTO_ALG_TYPE_DIGEST,
+	.cra_blocksize	=	SHA256_BLOCK_SIZE,
+	.cra_ctxsize	=	sizeof(struct s390_sha256_ctx),
+	.cra_module	=	THIS_MODULE,
+	.cra_list	=	LIST_HEAD_INIT(alg.cra_list),
+	.cra_u		=	{ .digest = {
+	.dia_digestsize	=	SHA256_DIGEST_SIZE,
+	.dia_init   	= 	sha256_init,
+	.dia_update 	=	sha256_update,
+	.dia_final  	=	sha256_final } }
+};
+
+static int init(void)
+{
+	int ret;
+
+	if (!crypt_s390_func_available(KIMD_SHA_256))
+		return -ENOSYS;
+
+	ret = crypto_register_alg(&alg);
+	if (ret != 0)
+		printk(KERN_INFO "crypt_s390: sha256_s390 couldn't be loaded.");
+	return ret;
+}
+
+static void __exit fini(void)
+{
+	crypto_unregister_alg(&alg);
+}
+
+module_init(init);
+module_exit(fini);
+
+MODULE_ALIAS("sha256");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SHA256 Secure Hash Algorithm");
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 45d44c6..7d23edc 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,12 +1,12 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc1
-# Wed Sep 14 16:46:19 2005
+# Linux kernel version: 2.6.15-rc2
+# Mon Nov 21 13:51:30 2005
 #
 CONFIG_MMU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_ARCH_S390=y
+CONFIG_S390=y
 CONFIG_UID16=y
 
 #
@@ -65,15 +65,31 @@
 CONFIG_STOP_MACHINE=y
 
 #
+# Block layer
+#
+# CONFIG_LBD is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+
+#
 # Base setup
 #
 
 #
 # Processor type and features
 #
-# CONFIG_ARCH_S390X is not set
 # CONFIG_64BIT is not set
-CONFIG_ARCH_S390_31=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 CONFIG_HOTPLUG_CPU=y
@@ -97,6 +113,7 @@
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
 # CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
 
 #
 # I/O subsystem configuration
@@ -188,10 +205,18 @@
 # CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_CLK_JIFFIES=y
 # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
 # CONFIG_NET_SCH_CLK_CPU is not set
+
+#
+# Queueing/Scheduling
+#
 CONFIG_NET_SCH_CBQ=m
 # CONFIG_NET_SCH_HTB is not set
 # CONFIG_NET_SCH_HFSC is not set
@@ -204,8 +229,10 @@
 CONFIG_NET_SCH_DSMARK=m
 # CONFIG_NET_SCH_NETEM is not set
 # CONFIG_NET_SCH_INGRESS is not set
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
+
+#
+# Classification
+#
 CONFIG_NET_CLS=y
 # CONFIG_NET_CLS_BASIC is not set
 CONFIG_NET_CLS_TCINDEX=m
@@ -214,18 +241,18 @@
 CONFIG_NET_CLS_FW=m
 CONFIG_NET_CLS_U32=m
 # CONFIG_CLS_U32_PERF is not set
-# CONFIG_NET_CLS_IND is not set
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
 # CONFIG_NET_EMATCH is not set
 # CONFIG_NET_CLS_ACT is not set
 CONFIG_NET_CLS_POLICE=y
+# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_ESTIMATOR=y
 
 #
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
-# CONFIG_NETFILTER_NETLINK is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
@@ -276,6 +303,7 @@
 #
 # SCSI low-level drivers
 #
+# CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_SATA is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_ZFCP=y
@@ -292,7 +320,6 @@
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 
 #
@@ -305,15 +332,8 @@
 CONFIG_DASD_ECKD=y
 CONFIG_DASD_FBA=y
 CONFIG_DASD_DIAG=y
+CONFIG_DASD_EER=m
 # CONFIG_DASD_CMB is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
 # CONFIG_ATA_OVER_ETH is not set
 
 #
@@ -378,7 +398,6 @@
 # CONFIG_VMLOGRDR is not set
 # CONFIG_VMCP is not set
 # CONFIG_MONREADER is not set
-# CONFIG_DCSS_SHM is not set
 
 #
 # Cryptographic devices
@@ -593,6 +612,8 @@
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_DEBUG_FS=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_RCU_TORTURE_TEST is not set
 
 #
 # Security options
@@ -609,17 +630,19 @@
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA1_Z990 is not set
+# CONFIG_CRYPTO_SHA1_S390 is not set
 # CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA256_S390 is not set
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
 # CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_DES_Z990 is not set
+# CONFIG_CRYPTO_DES_S390 is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
 # CONFIG_CRYPTO_TWOFISH is not set
 # CONFIG_CRYPTO_SERPENT is not set
 # CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_AES_S390 is not set
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
 # CONFIG_CRYPTO_TEA is not set
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index 7434c32..4865e4b 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -8,31 +8,26 @@
             setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
             semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o
 
+obj-y	+= $(if $(CONFIG_64BIT),entry64.o,entry.o)
+obj-y	+= $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
+
 extra-y				+= head.o init_task.o vmlinux.lds
 
 obj-$(CONFIG_MODULES)		+= s390_ksyms.o module.o
 obj-$(CONFIG_SMP)		+= smp.o
 
-obj-$(CONFIG_S390_SUPPORT)	+= compat_linux.o compat_signal.o \
+obj-$(CONFIG_COMPAT)		+= compat_linux.o compat_signal.o \
 					compat_ioctl.o compat_wrapper.o \
 					compat_exec_domain.o
 obj-$(CONFIG_BINFMT_ELF32)	+= binfmt_elf32.o
 
-obj-$(CONFIG_ARCH_S390_31)	+= entry.o reipl.o
-obj-$(CONFIG_ARCH_S390X)	+= entry64.o reipl64.o
-
 obj-$(CONFIG_VIRT_TIMER)	+= vtime.o
 
 # Kexec part
 S390_KEXEC_OBJS := machine_kexec.o crash.o
-ifeq ($(CONFIG_ARCH_S390X),y)
-S390_KEXEC_OBJS += relocate_kernel64.o
-else
-S390_KEXEC_OBJS += relocate_kernel.o
-endif
+S390_KEXEC_OBJS += $(if $(CONFIG_64BIT),relocate_kernel64.o,relocate_kernel.o)
 obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS)
 
-
 #
 # This is just to get the dependencies...
 #
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index ed877d0..41b197a 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -279,7 +279,7 @@
 
 static inline long get_tv32(struct timeval *o, struct compat_timeval *i)
 {
-	return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
+	return (!access_ok(VERIFY_READ, o, sizeof(*o)) ||
 		(__get_user(o->tv_sec, &i->tv_sec) ||
 		 __get_user(o->tv_usec, &i->tv_usec)));
 }
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 4ff6808..fa2b3bc 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -467,8 +467,6 @@
 	if (err)
 		goto badframe; 
 
-	/* It is more difficult to avoid calling this function than to
-	   call it and ignore errors.  */
 	set_fs (KERNEL_DS);
 	do_sigaltstack((stack_t __user *)&st, NULL, regs->gprs[15]);
 	set_fs (old_fs);
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index d47fecb..4ef44e5 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -39,7 +39,7 @@
 
 	if (response != NULL && rlen > 0) {
 		memset(response, 0, rlen);
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 		asm volatile (	"lra	2,0(%2)\n"
 				"lr	4,%3\n"
 				"o	4,%6\n"
@@ -55,7 +55,7 @@
 				: "a" (cpcmd_buf), "d" (cmdlen),
 				"a" (response), "d" (rlen), "m" (mask)
 				: "cc", "2", "3", "4", "5" );
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
                 asm volatile (	"lrag	2,0(%2)\n"
 				"lgr	4,%3\n"
 				"o	4,%6\n"
@@ -73,11 +73,11 @@
 				: "a" (cpcmd_buf), "d" (cmdlen),
 				"a" (response), "d" (rlen), "m" (mask)
 				: "cc", "2", "3", "4", "5" );
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
                 EBCASC(response, rlen);
         } else {
 		return_len = 0;
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
                 asm volatile (	"lra	2,0(%1)\n"
 				"lr	3,%2\n"
 				"diag	2,3,0x8\n"
@@ -85,7 +85,7 @@
 				: "=d" (return_code)
 				: "a" (cpcmd_buf), "d" (cmdlen)
 				: "2", "3"  );
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
                 asm volatile (	"lrag	2,0(%1)\n"
 				"lgr	3,%2\n"
 				"sam31\n"
@@ -95,7 +95,7 @@
 				: "=d" (return_code)
 				: "a" (cpcmd_buf), "d" (cmdlen)
 				: "2", "3" );
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
         }
 	spin_unlock_irqrestore(&cpcmd_lock, flags);
 	if (response_code != NULL)
@@ -105,7 +105,7 @@
 
 EXPORT_SYMBOL(__cpcmd);
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
 {
 	char *lowbuf;
@@ -129,4 +129,4 @@
 }
 
 EXPORT_SYMBOL(cpcmd);
-#endif		/* CONFIG_ARCH_S390X */
+#endif		/* CONFIG_64BIT */
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 4eb71ff..369ab44 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -213,7 +213,7 @@
 	mvc	SP_ARGS(8,%r15),SP_R7(%r15)
 sysc_do_restart:
 	larl    %r10,sys_call_table
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 	tm	__TI_flags+5(%r9),(_TIF_31BIT>>16)  # running in 31 bit mode ?
 	jno	sysc_noemu
 	larl    %r10,sys_call_table_emu  # use 31 bit emulation system calls
@@ -361,7 +361,7 @@
         la      %r2,SP_PTREGS(%r15)    # load pt_regs
         jg      sys_clone              # branch to sys_clone
 
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 sys32_clone_glue: 
         la      %r2,SP_PTREGS(%r15)    # load pt_regs
         jg      sys32_clone            # branch to sys32_clone
@@ -383,7 +383,7 @@
         bnz     0(%r12)               # it did fail -> store result in gpr2
         b       6(%r12)               # SKIP STG 2,SP_R2(15) in
                                       # system_call/sysc_tracesys
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 sys32_execve_glue:        
         la      %r2,SP_PTREGS(%r15)   # load pt_regs
 	lgr     %r12,%r14             # save return address
@@ -398,7 +398,7 @@
         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
         jg      sys_sigreturn         # branch to sys_sigreturn
 
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 sys32_sigreturn_glue:     
         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
         jg      sys32_sigreturn       # branch to sys32_sigreturn
@@ -408,7 +408,7 @@
         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
         jg      sys_rt_sigreturn      # branch to sys_sigreturn
 
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 sys32_rt_sigreturn_glue:     
         la      %r2,SP_PTREGS(%r15)   # load pt_regs as parameter
         jg      sys32_rt_sigreturn    # branch to sys32_sigreturn
@@ -429,7 +429,7 @@
 	la      %r14,6(%r14)          # skip store of return value
         jg      sys_sigsuspend        # branch to sys_sigsuspend
 
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 sys32_sigsuspend_glue:    
 	llgfr	%r4,%r4               # unsigned long			
         lgr     %r5,%r4               # move mask back
@@ -449,7 +449,7 @@
 	la      %r14,6(%r14)          # skip store of return value
         jg      sys_rt_sigsuspend     # branch to sys_rt_sigsuspend
 
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 sys32_rt_sigsuspend_glue: 
 	llgfr	%r3,%r3               # size_t			
         lgr     %r4,%r3               # move sigsetsize parameter
@@ -464,7 +464,7 @@
         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
         jg      sys_sigaltstack       # branch to sys_sigreturn
 
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 sys32_sigaltstack_glue:
         la      %r4,SP_PTREGS(%r15)   # load pt_regs as parameter
         jg      sys32_sigaltstack_wrapper # branch to sys_sigreturn
@@ -1009,7 +1009,7 @@
 #include "syscalls.S"
 #undef SYSCALL
 
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 
 #define SYSCALL(esa,esame,emu)	.long emu
 	.globl  sys_call_table_emu
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index d31a97c..ea88d06 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -30,7 +30,7 @@
 #include <asm/thread_info.h>
 #include <asm/page.h>
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 #define ARCH_OFFSET	4
 #else
 #define ARCH_OFFSET	0
@@ -539,7 +539,7 @@
 	.word 0
 .endm
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 #include "head64.S"
 #else
 #include "head31.S"
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 5aa71b0..f0ed5c6 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -85,7 +85,7 @@
 		pfault_fini();
 #endif
 
-	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid))
+	if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1)
 		signal_processor(smp_processor_id(), sigp_stop);
 
 	/* Wait for all other cpus to enter stopped state */
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 607d506..c271cda 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -37,11 +37,11 @@
 #define DEBUGP(fmt , ...)
 #endif
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 #define PLT_ENTRY_SIZE 12
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 #define PLT_ENTRY_SIZE 20
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 void *module_alloc(unsigned long size)
 {
@@ -294,17 +294,17 @@
 			unsigned int *ip;
 			ip = me->module_core + me->arch.plt_offset +
 				info->plt_offset;
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 			ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
 			ip[1] = 0x100607f1;
 			ip[2] = val;
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 			ip[0] = 0x0d10e310; /* basr 1,0; lg 1,10(1); br 1 */
 			ip[1] = 0x100a0004;
 			ip[2] = 0x07f10000;
 			ip[3] = (unsigned int) (val >> 32);
 			ip[4] = (unsigned int) val;
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 			info->plt_initialized = 1;
 		}
 		if (r_type == R_390_PLTOFF16 ||
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 78b64fe5..a942bf2 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -235,7 +235,7 @@
 	/* Save access registers to new thread structure. */
 	save_access_regs(&p->thread.acrs[0]);
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
         /*
 	 * save fprs to current->thread.fp_regs to merge them with
 	 * the emulated registers and then copy the result to the child.
@@ -247,7 +247,7 @@
 	/* Set a new TLS ?  */
 	if (clone_flags & CLONE_SETTLS)
 		p->thread.acrs[0] = regs->gprs[6];
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 	/* Save the fpu registers to new thread structure. */
 	save_fp_regs(&p->thread.fp_regs);
         p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _REGION_TABLE;
@@ -260,7 +260,7 @@
 			p->thread.acrs[1] = (unsigned int) regs->gprs[6];
 		}
 	}
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 	/* start new process with ar4 pointing to the correct address space */
 	p->thread.mm_segment = get_fs();
         /* Don't copy debug registers */
@@ -339,16 +339,16 @@
  */
 int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
 {
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
         /*
 	 * save fprs to current->thread.fp_regs to merge them with
 	 * the emulated registers and then copy the result to the dump.
 	 */
 	save_fp_regs(&current->thread.fp_regs);
 	memcpy(fpregs, &current->thread.fp_regs, sizeof(s390_fp_regs));
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 	save_fp_regs(fpregs);
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 	return 1;
 }
 
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 06afa31..cc02232 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -42,7 +42,7 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 #include "compat_ptrace.h"
 #endif
 
@@ -59,7 +59,7 @@
 	
 	if (per_info->single_step) {
 		per_info->control_regs.bits.starting_addr = 0;
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 		if (test_thread_flag(TIF_31BIT))
 			per_info->control_regs.bits.ending_addr = 0x7fffffffUL;
 		else
@@ -112,7 +112,7 @@
 	clear_single_step(child);
 }
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 # define __ADDR_MASK 3
 #else
 # define __ADDR_MASK 7
@@ -138,7 +138,7 @@
 	 * an alignment of 4. Programmers from hell...
 	 */
 	mask = __ADDR_MASK;
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 	if (addr >= (addr_t) &dummy->regs.acrs &&
 	    addr < (addr_t) &dummy->regs.orig_gpr2)
 		mask = 3;
@@ -160,7 +160,7 @@
 		 * access registers are stored in the thread structure
 		 */
 		offset = addr - (addr_t) &dummy->regs.acrs;
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 		/*
 		 * Very special case: old & broken 64 bit gdb reading
 		 * from acrs[15]. Result is a 64 bit value. Read the
@@ -218,7 +218,7 @@
 	 * an alignment of 4. Programmers from hell indeed...
 	 */
 	mask = __ADDR_MASK;
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 	if (addr >= (addr_t) &dummy->regs.acrs &&
 	    addr < (addr_t) &dummy->regs.orig_gpr2)
 		mask = 3;
@@ -231,13 +231,13 @@
 		 * psw and gprs are stored on the stack
 		 */
 		if (addr == (addr_t) &dummy->regs.psw.mask &&
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 		    data != PSW_MASK_MERGE(PSW_USER32_BITS, data) &&
 #endif
 		    data != PSW_MASK_MERGE(PSW_USER_BITS, data))
 			/* Invalid psw mask. */
 			return -EINVAL;
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 		if (addr == (addr_t) &dummy->regs.psw.addr)
 			/* I'd like to reject addresses without the
 			   high order bit but older gdb's rely on it */
@@ -250,7 +250,7 @@
 		 * access registers are stored in the thread structure
 		 */
 		offset = addr - (addr_t) &dummy->regs.acrs;
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 		/*
 		 * Very special case: old & broken 64 bit gdb writing
 		 * to acrs[15] with a 64 bit value. Ignore the lower
@@ -357,7 +357,7 @@
 	return ptrace_request(child, request, addr, data);
 }
 
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 /*
  * Now the fun part starts... a 31 bit program running in the
  * 31 bit emulation tracing another program. PTRACE_PEEKTEXT,
@@ -629,7 +629,7 @@
 			return peek_user(child, addr, data);
 		if (request == PTRACE_POKEUSR && addr == PT_IEEE_IP)
 			return poke_user(child, addr, data);
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 		if (request == PTRACE_PEEKUSR &&
 		    addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT))
 			return peek_user_emu31(child, addr, data);
@@ -695,7 +695,7 @@
 
 	/* Do requests that differ for 31/64 bit */
 	default:
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 		if (test_thread_flag(TIF_31BIT))
 			return do_ptrace_emu31(child, request, addr, data);
 #endif
@@ -712,35 +712,18 @@
 	int ret;
 
 	lock_kernel();
-
 	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		ret = -EPERM;
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
+		 ret = ptrace_traceme();
+		 goto out;
+	}
+
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
 		goto out;
 	}
 
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out;
-
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-
 	ret = do_ptrace(child, request, addr, data);
-
 	put_task_struct(child);
 out:
 	unlock_kernel();
diff --git a/arch/s390/kernel/reipl_diag.c b/arch/s390/kernel/reipl_diag.c
index 83cb42b..1f33951 100644
--- a/arch/s390/kernel/reipl_diag.c
+++ b/arch/s390/kernel/reipl_diag.c
@@ -26,7 +26,7 @@
 		"   st   %%r4,%0\n"
 		"   st   %%r5,%1\n"
                 ".section __ex_table,\"a\"\n"
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
                 "   .align 8\n"
                 "   .quad 0b, 0b\n"
 #else
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 31e7b19..b03847d 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -427,7 +427,7 @@
 		__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;
 	lc->current_task = (unsigned long) init_thread_union.thread_info.task;
 	lc->thread_info = (unsigned long) &init_thread_union;
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 	if (MACHINE_HAS_IEEE) {
 		lc->extended_save_area_addr = (__u32)
 			__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);
@@ -562,21 +562,21 @@
         /*
          * print what head.S has found out about the machine
          */
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 	printk((MACHINE_IS_VM) ?
 	       "We are running under VM (31 bit mode)\n" :
 	       "We are running native (31 bit mode)\n");
 	printk((MACHINE_HAS_IEEE) ?
 	       "This machine has an IEEE fpu\n" :
 	       "This machine has no IEEE fpu\n");
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 	printk((MACHINE_IS_VM) ?
 	       "We are running under VM (64 bit mode)\n" :
 	       "We are running native (64 bit mode)\n");
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
         ROOT_DEV = Root_RAM0;
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 	memory_end = memory_size & ~0x400000UL;  /* align memory end to 4MB */
         /*
          * We need some free virtual space to be able to do vmalloc.
@@ -585,9 +585,9 @@
          */
         if (memory_end > 1920*1024*1024)
                 memory_end = 1920*1024*1024;
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 	memory_end = memory_size & ~0x200000UL;  /* detected in head.s */
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 	init_mm.start_code = PAGE_OFFSET;
 	init_mm.end_code = (unsigned long) &_etext;
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 6e0110d..6ae4a77 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -254,9 +254,9 @@
 	if (restore_sigregs(regs, &frame->uc.uc_mcontext))
 		goto badframe;
 
-	/* It is more difficult to avoid calling this function than to
-	   call it and ignore errors.  */
-	do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]);
+	if (do_sigaltstack(&frame->uc.uc_stack, NULL,
+			   regs->gprs[15]) == -EFAULT)
+		goto badframe;
 	return regs->gprs[2];
 
 badframe:
@@ -501,7 +501,7 @@
 
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
-#ifdef CONFIG_S390_SUPPORT
+#ifdef CONFIG_COMPAT
 		if (test_thread_flag(TIF_31BIT)) {
 			extern void handle_signal32(unsigned long sig,
 						    struct k_sigaction *ka,
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 5856b3f..e10f4ca 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -263,7 +263,7 @@
 	int cpu;
 	static atomic_t cpuid = ATOMIC_INIT(-1);
 
-	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid))
+	if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1)
 		signal_processor(smp_processor_id(), sigp_stop);
 
 	/* Wait for all other cpus to enter stopped state */
@@ -313,7 +313,7 @@
 {
 	static atomic_t cpuid = ATOMIC_INIT(-1);
 
-	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) {
+	if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) == -1) {
 		smp_send_stop();
 		if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
 			cpcmd(vmhalt_cmd, NULL, 0, NULL);
@@ -332,7 +332,7 @@
 {
 	static atomic_t cpuid = ATOMIC_INIT(-1);
 
-	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid) == 0) {
+	if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) == -1) {
 		smp_send_stop();
 		if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
 			cpcmd(vmpoff_cmd, NULL, 0, NULL);
@@ -402,7 +402,7 @@
         }
 }
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 /*
  * this function sends a 'purge tlb' signal to another CPU.
  */
@@ -416,7 +416,7 @@
         on_each_cpu(smp_ptlb_callback, NULL, 0, 1);
 }
 EXPORT_SYMBOL(smp_ptlb_all);
-#endif /* ! CONFIG_ARCH_S390X */
+#endif /* ! CONFIG_64BIT */
 
 /*
  * this function sends a 'reschedule' IPI to another CPU.
@@ -783,7 +783,7 @@
 		if (stack == 0ULL)
 			panic("smp_boot_cpus failed to allocate memory\n");
 		lowcore_ptr[i]->panic_stack = stack + (PAGE_SIZE);
-#ifndef __s390x__
+#ifndef CONFIG_64BIT
 		if (MACHINE_HAS_IEEE) {
 			lowcore_ptr[i]->extended_save_area_addr =
 				(__u32) __get_free_pages(GFP_KERNEL,0);
@@ -793,7 +793,7 @@
 		}
 #endif
 	}
-#ifndef __s390x__
+#ifndef CONFIG_64BIT
 	if (MACHINE_HAS_IEEE)
 		ctl_set_bit(14, 29); /* enable extended save area */
 #endif
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index efe6b83..6a63553 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -26,9 +26,7 @@
 #include <linux/mman.h>
 #include <linux/file.h>
 #include <linux/utsname.h>
-#ifdef CONFIG_ARCH_S390X
 #include <linux/personality.h>
-#endif /* CONFIG_ARCH_S390X */
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
@@ -121,7 +119,7 @@
 	return error;
 }
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 struct sel_arg_struct {
 	unsigned long n;
 	fd_set *inp, *outp, *exp;
@@ -138,7 +136,7 @@
 	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
 
 }
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 /*
  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
@@ -211,7 +209,7 @@
 	return -EINVAL;
 }
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 asmlinkage long s390x_newuname(struct new_utsname __user *name)
 {
 	int ret = sys_newuname(name);
@@ -235,12 +233,12 @@
 
 	return ret;
 }
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 /*
  * Wrapper function for sys_fadvise64/fadvise64_64
  */
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 
 asmlinkage long
 s390_fadvise64(int fd, u32 offset_high, u32 offset_low, size_t len, int advice)
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index c5bd36f..95d1099 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -67,13 +67,13 @@
 
 #define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 #define FOURLONG "%08lx %08lx %08lx %08lx\n"
 static int kstack_depth_to_print = 12;
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 #define FOURLONG "%016lx %016lx %016lx %016lx\n"
 static int kstack_depth_to_print = 20;
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 /*
  * For show_trace we have tree different stack to consider:
@@ -702,12 +702,12 @@
         pgm_check_table[0x11] = &do_dat_exception;
         pgm_check_table[0x12] = &translation_exception;
         pgm_check_table[0x13] = &special_op_exception;
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
         pgm_check_table[0x38] = &do_dat_exception;
 	pgm_check_table[0x39] = &do_dat_exception;
 	pgm_check_table[0x3A] = &do_dat_exception;
         pgm_check_table[0x3B] = &do_dat_exception;
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
         pgm_check_table[0x15] = &operand_exception;
         pgm_check_table[0x1C] = &space_switch_exception;
         pgm_check_table[0x1D] = &hfp_sqrt_exception;
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 89fdb38..9289fac 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -5,7 +5,7 @@
 #include <asm-generic/vmlinux.lds.h>
 #include <linux/config.h>
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 OUTPUT_FORMAT("elf32-s390", "elf32-s390", "elf32-s390")
 OUTPUT_ARCH(s390)
 ENTRY(_start)
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index b701efa..d9b97b3 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,6 +4,5 @@
 
 EXTRA_AFLAGS := -traditional
 
-lib-y += delay.o string.o
-lib-$(CONFIG_ARCH_S390_31) += uaccess.o spinlock.o
-lib-$(CONFIG_ARCH_S390X) += uaccess64.o spinlock.o
+lib-y += delay.o string.o spinlock.o
+lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index 2dc14e9..68d79c5 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -29,7 +29,7 @@
 static inline void
 _diag44(void)
 {
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 	if (MACHINE_HAS_DIAG44)
 #endif
 		asm volatile("diag 0,0,0x44");
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index 506a33b..a9566bc 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -143,7 +143,7 @@
 	rx = (unsigned long) parameter;
 	ry = (unsigned long) func;
 	__asm__ __volatile__(
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 		"   sam31\n" // switch to 31 bit
 		"   diag    %0,%1,0x64\n"
 		"   sam64\n" // switch back to 64 bit
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index fb2607c..81ade40 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -31,17 +31,17 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 #define __FAIL_ADDR_MASK 0x7ffff000
 #define __FIXUP_MASK 0x7fffffff
 #define __SUBCODE_MASK 0x0200
 #define __PF_RES_FIELD 0ULL
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 #define __FAIL_ADDR_MASK -4096L
 #define __FIXUP_MASK ~0L
 #define __SUBCODE_MASK 0x0600
 #define __PF_RES_FIELD 0x8000000000000000ULL
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 #ifdef CONFIG_SYSCTL
 extern int sysctl_userprocess_debug;
@@ -393,11 +393,11 @@
 		"2:\n"
 		".section __ex_table,\"a\"\n"
 		"   .align 4\n"
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 		"   .long  0b,1b\n"
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 		"   .quad  0b,1b\n"
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 		".previous"
                 : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" );
         __ctl_set_bit(0, 9);
@@ -417,11 +417,11 @@
 		"0:\n"
 		".section __ex_table,\"a\"\n"
 		"   .align 4\n"
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 		"   .long  0b,0b\n"
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 		"   .quad  0b,0b\n"
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 		".previous"
 		: : "a" (&refbk), "m" (refbk) : "cc" );
 }
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 6ec5cd9..df95338 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -44,7 +44,7 @@
 {
         if (addr >= 0x7ff00000)
                 return;
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
         asm volatile (
 		"   sam31\n"
 		"   diag %0,%0,0x10\n"
@@ -106,7 +106,7 @@
  * paging_init() sets up the page tables
  */
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 void __init paging_init(void)
 {
         pgd_t * pg_dir;
@@ -175,7 +175,7 @@
         return;
 }
 
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 void __init paging_init(void)
 {
         pgd_t * pg_dir;
@@ -256,7 +256,7 @@
 
         return;
 }
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 
 void __init mem_init(void)
 {
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index fb187e5..356257c 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -50,7 +50,7 @@
 
 static inline int mmap_is_legacy(void)
 {
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 	/*
 	 * Force standard allocation for 64 bit programs.
 	 */
diff --git a/arch/s390/oprofile/Makefile b/arch/s390/oprofile/Makefile
index ec34927..537b2d8 100644
--- a/arch/s390/oprofile/Makefile
+++ b/arch/s390/oprofile/Makefile
@@ -6,4 +6,4 @@
 		oprofilefs.o oprofile_stats.o  \
 		timer_int.o )
 
-oprofile-y				:= $(DRIVER_OBJS) init.o
+oprofile-y				:= $(DRIVER_OBJS) init.o backtrace.o
diff --git a/arch/s390/oprofile/backtrace.c b/arch/s390/oprofile/backtrace.c
new file mode 100644
index 0000000..bc4b84a
--- /dev/null
+++ b/arch/s390/oprofile/backtrace.c
@@ -0,0 +1,79 @@
+/**
+ * arch/s390/oprofile/backtrace.c
+ *
+ * S390 Version
+ *   Copyright (C) 2005 IBM Corporation, IBM Deutschland Entwicklung GmbH.
+ *   Author(s): Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+ */
+
+#include <linux/oprofile.h>
+
+#include <asm/processor.h> /* for struct stack_frame */
+
+static unsigned long
+__show_trace(unsigned int *depth, unsigned long sp,
+	     unsigned long low, unsigned long high)
+{
+	struct stack_frame *sf;
+	struct pt_regs *regs;
+
+	while (*depth) {
+		sp = sp & PSW_ADDR_INSN;
+		if (sp < low || sp > high - sizeof(*sf))
+			return sp;
+		sf = (struct stack_frame *) sp;
+		(*depth)--;
+		oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN);
+
+		/* Follow the backchain.  */
+		while (*depth) {
+			low = sp;
+			sp = sf->back_chain & PSW_ADDR_INSN;
+			if (!sp)
+				break;
+			if (sp <= low || sp > high - sizeof(*sf))
+				return sp;
+			sf = (struct stack_frame *) sp;
+			(*depth)--;
+			oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN);
+
+		}
+
+		if (*depth == 0)
+			break;
+
+		/* Zero backchain detected, check for interrupt frame.  */
+		sp = (unsigned long) (sf + 1);
+		if (sp <= low || sp > high - sizeof(*regs))
+			return sp;
+		regs = (struct pt_regs *) sp;
+		(*depth)--;
+		oprofile_add_trace(sf->gprs[8] & PSW_ADDR_INSN);
+		low = sp;
+		sp = regs->gprs[15];
+	}
+	return sp;
+}
+
+void s390_backtrace(struct pt_regs * const regs, unsigned int depth)
+{
+	unsigned long head;
+	struct stack_frame* head_sf;
+
+	if (user_mode (regs))
+		return;
+
+	head = regs->gprs[15];
+	head_sf = (struct stack_frame*)head;
+
+	if (!head_sf->back_chain)
+		return;
+
+	head = head_sf->back_chain;
+
+	head = __show_trace(&depth, head, S390_lowcore.async_stack - ASYNC_SIZE,
+			    S390_lowcore.async_stack);
+
+	__show_trace(&depth, head, S390_lowcore.thread_info,
+		     S390_lowcore.thread_info + THREAD_SIZE);
+}
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c
index a65ead0..7a99511 100644
--- a/arch/s390/oprofile/init.c
+++ b/arch/s390/oprofile/init.c
@@ -12,8 +12,12 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 
+
+extern void s390_backtrace(struct pt_regs * const regs, unsigned int depth);
+
 int __init oprofile_arch_init(struct oprofile_operations* ops)
 {
+	ops->backtrace = s390_backtrace;
 	return -ENODEV;
 }
 
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 64f5ae0..8cf6d43 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -14,10 +14,6 @@
 	  gaming console.  The SuperH port has a home page at
 	  <http://www.linux-sh.org/>.
 
-config UID16
-	bool
-	default y
-
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
diff --git a/arch/sh64/kernel/time.c b/arch/sh64/kernel/time.c
index 870fe53..1195af3 100644
--- a/arch/sh64/kernel/time.c
+++ b/arch/sh64/kernel/time.c
@@ -417,7 +417,7 @@
 	/*
 	** Regardless the toolchain, force the compiler to use the
 	** arbitrary register r3 as a clock tick counter.
-	** NOTE: r3 must be in accordance with rtc_interrupt()
+	** NOTE: r3 must be in accordance with sh64_rtc_interrupt()
 	*/
 	register unsigned long long  __rtc_irq_flag __asm__ ("r3");
 
@@ -482,7 +482,8 @@
 #endif
 }
 
-static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id,
+				      struct pt_regs *regs)
 {
 	ctrl_outb(0, RCR1);	/* Disable Carry Interrupts */
 	regs->regs[3] = 1;	/* Using r3 */
@@ -491,7 +492,7 @@
 }
 
 static struct irqaction irq0  = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL};
-static struct irqaction irq1  = { rtc_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "rtc", NULL, NULL};
+static struct irqaction irq1  = { sh64_rtc_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "rtc", NULL, NULL};
 
 void __init time_init(void)
 {
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 3cfb8be..f944b58 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -9,10 +9,6 @@
 	bool
 	default y
 
-config UID16
-	bool
-	default y
-
 config HIGHMEM
 	bool
 	default y
@@ -55,6 +51,10 @@
 	depends on SMP
 	default "32"
 
+config SPARC
+	bool
+	default y
+
 # Identify this as a Sparc32 build
 config SPARC32
 	bool
diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
index dea48f6..4cdbb2d 100644
--- a/arch/sparc/Makefile
+++ b/arch/sparc/Makefile
@@ -34,7 +34,7 @@
 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
 INIT_Y		:= $(patsubst %/, %/built-in.o, $(init-y))
 CORE_Y		:= $(core-y)
-CORE_Y		+= kernel/ mm/ fs/ ipc/ security/ crypto/
+CORE_Y		+= kernel/ mm/ fs/ ipc/ security/ crypto/ block/
 CORE_Y		:= $(patsubst %/, %/built-in.o, $(CORE_Y))
 DRIVERS_Y	:= $(patsubst %/, %/built-in.o, $(drivers-y))
 NET_Y		:= $(patsubst %/, %/built-in.o, $(net-y))
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
index 1754192..5c3529c 100644
--- a/arch/sparc/kernel/ebus.c
+++ b/arch/sparc/kernel/ebus.c
@@ -22,7 +22,7 @@
 #include <asm/oplib.h>
 #include <asm/bpp.h>
 
-struct linux_ebus *ebus_chain = 0;
+struct linux_ebus *ebus_chain = NULL;
 
 /* We are together with pcic.c under CONFIG_PCI. */
 extern unsigned int pcic_pin_to_irq(unsigned int, char *name);
@@ -46,7 +46,7 @@
 	{ "SUNW,CS4231",	 0 },
 	{ "parallel",		 0 },
 	{ "se",			 2 },
-	{ 0, 0 }
+	{ NULL, 0 }
 };
 
 /*
@@ -55,7 +55,7 @@
  */
 static struct ebus_system_entry ebus_blacklist[] = {
 	{ "SUNW,JavaEngine1", je1_1 },
-	{ 0, 0 }
+	{ NULL, NULL }
 };
 
 static struct ebus_device_irq *ebus_blackp = NULL;
@@ -233,7 +233,7 @@
 			ebus_alloc(sizeof(struct linux_ebus_child));
 
 		child = dev->children;
-		child->next = 0;
+		child->next = NULL;
 		child->parent = dev;
 		child->bus = dev->bus;
 		fill_ebus_child(node, &regs[0], child);
@@ -243,7 +243,7 @@
 				ebus_alloc(sizeof(struct linux_ebus_child));
 
 			child = child->next;
-			child->next = 0;
+			child->next = NULL;
 			child->parent = dev;
 			child->bus = dev->bus;
 			fill_ebus_child(node, &regs[0], child);
@@ -275,7 +275,7 @@
 		}
 	}
 
-	pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
+	pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL);
 	if (!pdev) {
 		return;
 	}
@@ -284,7 +284,7 @@
 
 	ebus_chain = ebus = (struct linux_ebus *)
 			ebus_alloc(sizeof(struct linux_ebus));
-	ebus->next = 0;
+	ebus->next = NULL;
 
 	while (ebusnd) {
 
@@ -325,8 +325,8 @@
 				ebus_alloc(sizeof(struct linux_ebus_device));
 
 		dev = ebus->devices;
-		dev->next = 0;
-		dev->children = 0;
+		dev->next = NULL;
+		dev->children = NULL;
 		dev->bus = ebus;
 		fill_ebus_device(nd, dev);
 
@@ -335,8 +335,8 @@
 				ebus_alloc(sizeof(struct linux_ebus_device));
 
 			dev = dev->next;
-			dev->next = 0;
-			dev->children = 0;
+			dev->next = NULL;
+			dev->children = NULL;
 			dev->bus = ebus;
 			fill_ebus_device(nd, dev);
 		}
@@ -353,7 +353,7 @@
 		ebus->next = (struct linux_ebus *)
 			ebus_alloc(sizeof(struct linux_ebus));
 		ebus = ebus->next;
-		ebus->next = 0;
+		ebus->next = NULL;
 		++num_ebus;
 	}
 	if (pdev)
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c
index 2a3afca..313d162 100644
--- a/arch/sparc/kernel/led.c
+++ b/arch/sparc/kernel/led.c
@@ -55,7 +55,7 @@
 	return len;
 }
 
-static int led_write_proc(struct file *file, const char *buffer,
+static int led_write_proc(struct file *file, const char __user *buffer,
 			  unsigned long count, void *data)
 {
 	char *buf = NULL;
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index cccfc12..42002b7 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -161,7 +161,7 @@
 static int pcic0_up;
 static struct linux_pcic pcic0;
 
-void * __iomem pcic_regs;
+void __iomem *pcic_regs;
 volatile int pcic_speculative;
 volatile int pcic_trapped;
 
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index 475c4c1..fc470c0 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -286,40 +286,17 @@
 			       s, (int) request, (int) pid, addr, data, addr2);
 	}
 #endif
+
 	if (request == PTRACE_TRACEME) {
-		int my_ret;
-
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED) {
-			pt_error_return(regs, EPERM);
-			goto out;
-		}
-		my_ret = security_ptrace(current->parent, current);
-		if (my_ret) {
-			pt_error_return(regs, -my_ret);
-			goto out;
-		}
-
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
+		ret = ptrace_traceme();
 		pt_succ_return(regs, 0);
 		goto out;
 	}
-#ifndef ALLOW_INIT_TRACING
-	if (pid == 1) {
-		/* Can't dork with init. */
-		pt_error_return(regs, EPERM);
-		goto out;
-	}
-#endif
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
 
-	if (!child) {
-		pt_error_return(regs, ESRCH);
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
+		pt_error_return(regs, -ret);
 		goto out;
 	}
 
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index 81c894a..d07ae02 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -894,7 +894,7 @@
 		ret = ARG_MAX;
 		break;
 	case _SC_CHILD_MAX:
-		ret = CHILD_MAX;
+		ret = -1; /* no limit */
 		break;
 	case _SC_CLK_TCK:
 		ret = HZ;
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 24814d5..7dadcdb 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -49,7 +49,7 @@
 enum sparc_clock_type sp_clock_typ;
 DEFINE_SPINLOCK(mostek_lock);
 void __iomem *mstk48t02_regs = NULL;
-static struct mostek48t08 *mstk48t08_regs = NULL;
+static struct mostek48t08 __iomem *mstk48t08_regs = NULL;
 static int set_rtc_mmss(unsigned long);
 static int sbus_do_settimeofday(struct timespec *tv);
 
@@ -342,7 +342,7 @@
 		/* XXX r/o attribute is somewhere in r.flags */
 		r.flags = clk_reg[0].which_io;
 		r.start = clk_reg[0].phys_addr;
-		mstk48t08_regs = (struct mostek48t08 *) sbus_ioremap(&r, 0,
+		mstk48t08_regs = sbus_ioremap(&r, 0,
 		    sizeof(struct mostek48t08), "mk48t08");
 
 		mstk48t02_regs = &mstk48t08_regs->regs;
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 38938d2..346c19a 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -85,19 +85,9 @@
   }
   _end = . ;
   PROVIDE (end = .);
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
-  .debug          0 : { *(.debug) }
-  .debug_srcinfo  0 : { *(.debug_srcinfo) }
-  .debug_aranges  0 : { *(.debug_aranges) }
-  .debug_pubnames 0 : { *(.debug_pubnames) }
-  .debug_sfnames  0 : { *(.debug_sfnames) }
-  .line           0 : { *(.line) }
   /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) }
+
+  STABS_DEBUG
+
+  DWARF_DEBUG
 }
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c
index cb3cf0f..de84f85 100644
--- a/arch/sparc/lib/atomic32.c
+++ b/arch/sparc/lib/atomic32.c
@@ -66,7 +66,6 @@
 	return ret != u;
 }
 
-static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
 /* Atomic operations are already serializing */
 void atomic_set(atomic_t *v, int i)
 {
diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c
index 0410bae..2cb0728 100644
--- a/arch/sparc/mm/generic.c
+++ b/arch/sparc/mm/generic.c
@@ -32,9 +32,7 @@
 	if (end > PMD_SIZE)
 		end = PMD_SIZE;
 	do {
-		pte_t oldpage = *pte;
-		pte_clear(mm, address, pte);
-		set_pte(pte, mk_pte_io(offset, prot, space));
+		set_pte_at(mm, address, pte, mk_pte_io(offset, prot, space));
 		address += PAGE_SIZE;
 		offset += PAGE_SIZE;
 		pte++;
@@ -63,7 +61,7 @@
 }
 
 int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
-			unsigned long pfn, unsigned long size, pgprot_t prot)
+		       unsigned long pfn, unsigned long size, pgprot_t prot)
 {
 	int error = 0;
 	pgd_t * dir;
@@ -74,7 +72,9 @@
 	unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
 
 	/* See comment in mm/memory.c remap_pfn_range */
-	vma->vm_flags |= VM_IO | VM_RESERVED | VM_UNPAGED;
+	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+	vma->vm_pgoff = (offset >> PAGE_SHIFT) |
+		((unsigned long)space << 28UL);
 
 	prot = __pgprot(pg_iobits);
 	offset -= from;
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 1d56039..731f196 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -497,7 +497,7 @@
 	patch_kernel_fault_handler();
 }
 
-volatile unsigned long *sun4c_memerr_reg = NULL;
+volatile unsigned long __iomem *sun4c_memerr_reg = NULL;
 
 void __init sun4c_probe_memerr_reg(void)
 {
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 3fded69..b775ceb 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -5,6 +5,10 @@
 
 mainmenu "Linux/UltraSPARC Kernel Configuration"
 
+config SPARC
+	bool
+	default y
+
 config SPARC64
 	bool
 	default y
@@ -305,11 +309,6 @@
 	depends on SPARC32_COMPAT
 	default y
 
-config UID16
-	bool
-	depends on SPARC32_COMPAT
-	default y
-
 config BINFMT_ELF32
 	tristate "Kernel support for 32-bit ELF binaries"
 	depends on SPARC32_COMPAT
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index 43fe382..cad10c5 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -17,7 +17,6 @@
 NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow)
 NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
 UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
-INLINE_LIMIT := $(call cc-option-yn, -m64 -finline-limit=100000)
 
 export NEW_GCC
 
@@ -49,10 +48,6 @@
   AFLAGS += -m64 -mcpu=ultrasparc $(CC_UNDECL)
 endif
 
-ifeq ($(INLINE_LIMIT),y)
-  CFLAGS := $(CFLAGS) -finline-limit=100000
-endif
-
 ifeq ($(CONFIG_MCOUNT),y)
   CFLAGS := $(CFLAGS) -pg
 endif
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 96bd09b..a97b0f0 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -138,7 +138,7 @@
 			 */
 			save_previous_kprobe(kcb);
 			set_current_kprobe(p, regs, kcb);
-			p->nmissed++;
+			kprobes_inc_nmissed_count(p);
 			kcb->kprobe_status = KPROBE_REENTER;
 			prepare_singlestep(p, regs, kcb);
 			return 1;
diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
index 774ecbb..84d3df2 100644
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -198,39 +198,15 @@
 	}
 #endif
 	if (request == PTRACE_TRACEME) {
-		int ret;
-
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED) {
-			pt_error_return(regs, EPERM);
-			goto out;
-		}
-		ret = security_ptrace(current->parent, current);
-		if (ret) {
-			pt_error_return(regs, -ret);
-			goto out;
-		}
-
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
+		ret = ptrace_traceme();
 		pt_succ_return(regs, 0);
 		goto out;
 	}
-#ifndef ALLOW_INIT_TRACING
-	if (pid == 1) {
-		/* Can't dork with init. */
-		pt_error_return(regs, EPERM);
-		goto out;
-	}
-#endif
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
 
-	if (!child) {
-		pt_error_return(regs, ESRCH);
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
+		pt_error_return(regs, -ret);
 		goto out;
 	}
 
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index d0592ed..bfa4aa6 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -854,7 +854,7 @@
 		ret = ARG_MAX;
 		break;
 	case _SC_CHILD_MAX:
-		ret = CHILD_MAX;
+		ret = -1; /* no limit */
 		break;
 	case _SC_CLK_TCK:
 		ret = HZ;
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S
index 2af0cf0..467d13a 100644
--- a/arch/sparc64/kernel/vmlinux.lds.S
+++ b/arch/sparc64/kernel/vmlinux.lds.S
@@ -90,19 +90,9 @@
   }
   _end = . ;
   PROVIDE (end = .);
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
-  .debug          0 : { *(.debug) }
-  .debug_srcinfo  0 : { *(.debug_srcinfo) }
-  .debug_aranges  0 : { *(.debug_aranges) }
-  .debug_pubnames 0 : { *(.debug_pubnames) }
-  .debug_sfnames  0 : { *(.debug_sfnames) }
-  .line           0 : { *(.line) }
   /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) }
+
+  STABS_DEBUG
+
+  DWARF_DEBUG
 }
diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c
index 8fd4cb1..580b63d 100644
--- a/arch/sparc64/mm/generic.c
+++ b/arch/sparc64/mm/generic.c
@@ -15,6 +15,15 @@
 #include <asm/page.h>
 #include <asm/tlbflush.h>
 
+static inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space)
+{
+	pte_t pte;
+	pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E) &
+			~(unsigned long)_PAGE_CACHE);
+	pte_val(pte) |= (((unsigned long)space) << 32);
+	return pte;
+}
+
 /* Remap IO memory, the same way as remap_pfn_range(), but use
  * the obio memory space.
  *
@@ -68,6 +77,7 @@
 			BUG_ON(!pte_none(*pte));
 			set_pte_at(mm, address, pte, entry);
 			address += PAGE_SIZE;
+			pte_val(entry) += PAGE_SIZE;
 			pte++;
 		} while (address < curend);
 	} while (address < end);
@@ -126,9 +136,13 @@
 	struct mm_struct *mm = vma->vm_mm;
 	int space = GET_IOSPACE(pfn);
 	unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+	unsigned long phys_base;
+
+	phys_base = offset | (((unsigned long) space) << 32UL);
 
 	/* See comment in mm/memory.c remap_pfn_range */
-	vma->vm_flags |= VM_IO | VM_RESERVED | VM_UNPAGED;
+	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+	vma->vm_pgoff = phys_base >> PAGE_SHIFT;
 
 	prot = __pgprot(pg_iobits);
 	offset -= from;
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 302efbc..3ab4677 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -353,7 +353,7 @@
 {
 	switch (id) {
 	case SOLARIS_CONFIG_NGROUPS:	return NGROUPS_MAX;
-	case SOLARIS_CONFIG_CHILD_MAX:	return CHILD_MAX;
+	case SOLARIS_CONFIG_CHILD_MAX:	return -1; /* no limit */
 	case SOLARIS_CONFIG_OPEN_FILES:	return OPEN_MAX;
 	case SOLARIS_CONFIG_POSIX_VER:	return 199309;
 	case SOLARIS_CONFIG_PAGESIZE:	return PAGE_SIZE;
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 563301f..b4ff2e5 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -22,10 +22,6 @@
 config PCI
 	bool
 
-config UID16
-	bool
-	default y
-
 config GENERIC_CALIBRATE_DELAY
 	bool
 	default y
@@ -83,7 +79,7 @@
         of physical memory.
 
 config MODE_SKAS
-	bool "Separate Kernel Address Space support"
+	bool "Separate Kernel Address Space support" if MODE_TT
 	default y
 	help
 	This option controls whether skas (separate kernel address space)
@@ -289,6 +285,8 @@
 
 source "drivers/net/Kconfig"
 
+source "drivers/connector/Kconfig"
+
 source "fs/Kconfig"
 
 source "security/Kconfig"
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 4f118d5..38df311 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -12,3 +12,7 @@
 
 ELF_ARCH := i386:x86-64
 ELF_FORMAT := elf64-x86-64
+
+# Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example.
+
+LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 5b58fad..cd13b91 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -58,7 +58,7 @@
 {
 	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
-	return(NULL);
+	return NULL;
 }
 
 static int not_configged_open(int input, int output, int primary, void *data,
@@ -66,7 +66,7 @@
 {
 	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
-	return(-ENODEV);
+	return -ENODEV;
 }
 
 static void not_configged_close(int fd, void *data)
@@ -79,21 +79,21 @@
 {
 	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
-	return(-EIO);
+	return -EIO;
 }
 
 static int not_configged_write(int fd, const char *buf, int len, void *data)
 {
 	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
-	return(-EIO);
+	return -EIO;
 }
 
 static int not_configged_console_write(int fd, const char *buf, int len)
 {
 	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
-	return(-EIO);
+	return -EIO;
 }
 
 static int not_configged_window_size(int fd, void *data, unsigned short *rows,
@@ -101,7 +101,7 @@
 {
 	my_puts("Using a channel type which is configured out of "
 	       "UML\n");
-	return(-ENODEV);
+	return -ENODEV;
 }
 
 static void not_configged_free(void *data)
@@ -135,17 +135,17 @@
 	n = os_read_file(fd, c_out, sizeof(*c_out));
 
 	if(n == -EAGAIN)
-		return(0);
+		return 0;
 	else if(n == 0)
-		return(-EIO);
-	return(n);
+		return -EIO;
+	return n;
 }
 
 /* XXX Trivial wrapper around os_write_file */
 
 int generic_write(int fd, const char *buf, int n, void *unused)
 {
-	return(os_write_file(fd, buf, n));
+	return os_write_file(fd, buf, n);
 }
 
 int generic_window_size(int fd, void *unused, unsigned short *rows_out,
@@ -156,14 +156,14 @@
 
 	ret = os_window_size(fd, &rows, &cols);
 	if(ret < 0)
-		return(ret);
+		return ret;
 
 	ret = ((*rows_out != rows) || (*cols_out != cols));
 
 	*rows_out = rows;
 	*cols_out = cols;
 
-	return(ret);
+	return ret;
 }
 
 void generic_free(void *data)
@@ -186,25 +186,29 @@
 		}
 	}
 
-	if((tty->flip.flag_buf_ptr == NULL) || 
+	if((tty->flip.flag_buf_ptr == NULL) ||
 	   (tty->flip.char_buf_ptr == NULL))
 		return;
 	tty_insert_flip_char(tty, ch, TTY_NORMAL);
 }
 
-static int open_one_chan(struct chan *chan, int input, int output, int primary)
+static int open_one_chan(struct chan *chan)
 {
 	int fd;
 
-	if(chan->opened) return(0);
-	if(chan->ops->open == NULL) fd = 0;
-	else fd = (*chan->ops->open)(input, output, primary, chan->data,
-				     &chan->dev);
-	if(fd < 0) return(fd);
+	if(chan->opened)
+		return 0;
+
+	if(chan->ops->open == NULL)
+		fd = 0;
+	else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary,
+				     chan->data, &chan->dev);
+	if(fd < 0)
+		return fd;
 	chan->fd = fd;
 
 	chan->opened = 1;
-	return(0);
+	return 0;
 }
 
 int open_chan(struct list_head *chans)
@@ -215,11 +219,11 @@
 
 	list_for_each(ele, chans){
 		chan = list_entry(ele, struct chan, list);
-		ret = open_one_chan(chan, chan->input, chan->output,
-				    chan->primary);
-		if(chan->primary) err = ret;
+		ret = open_one_chan(chan);
+		if(chan->primary)
+			err = ret;
 	}
-	return(err);
+	return err;
 }
 
 void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
@@ -236,20 +240,65 @@
 	}
 }
 
-void enable_chan(struct list_head *chans, struct tty_struct *tty)
+void enable_chan(struct line *line)
 {
 	struct list_head *ele;
 	struct chan *chan;
 
-	list_for_each(ele, chans){
+	list_for_each(ele, &line->chan_list){
 		chan = list_entry(ele, struct chan, list);
-		if(!chan->opened) continue;
+		if(open_one_chan(chan))
+			continue;
 
-		line_setup_irq(chan->fd, chan->input, chan->output, tty);
+		if(chan->enabled)
+			continue;
+		line_setup_irq(chan->fd, chan->input, chan->output, line,
+			       chan);
+		chan->enabled = 1;
 	}
 }
 
-void close_chan(struct list_head *chans)
+static LIST_HEAD(irqs_to_free);
+
+void free_irqs(void)
+{
+	struct chan *chan;
+
+	while(!list_empty(&irqs_to_free)){
+		chan = list_entry(irqs_to_free.next, struct chan, free_list);
+		list_del(&chan->free_list);
+
+		if(chan->input)
+			free_irq(chan->line->driver->read_irq, chan);
+		if(chan->output)
+			free_irq(chan->line->driver->write_irq, chan);
+		chan->enabled = 0;
+	}
+}
+
+static void close_one_chan(struct chan *chan, int delay_free_irq)
+{
+	if(!chan->opened)
+		return;
+
+	if(delay_free_irq){
+		list_add(&chan->free_list, &irqs_to_free);
+	}
+	else {
+		if(chan->input)
+			free_irq(chan->line->driver->read_irq, chan);
+		if(chan->output)
+			free_irq(chan->line->driver->write_irq, chan);
+		chan->enabled = 0;
+	}
+	if(chan->ops->close != NULL)
+		(*chan->ops->close)(chan->fd, chan->data);
+
+	chan->opened = 0;
+	chan->fd = -1;
+}
+
+void close_chan(struct list_head *chans, int delay_free_irq)
 {
 	struct chan *chan;
 
@@ -259,15 +308,37 @@
 	 * so it must be the last closed.
 	 */
 	list_for_each_entry_reverse(chan, chans, list) {
-		if(!chan->opened) continue;
-		if(chan->ops->close != NULL)
-			(*chan->ops->close)(chan->fd, chan->data);
-		chan->opened = 0;
-		chan->fd = -1;
+		close_one_chan(chan, delay_free_irq);
 	}
 }
 
-int write_chan(struct list_head *chans, const char *buf, int len, 
+void deactivate_chan(struct list_head *chans, int irq)
+{
+	struct list_head *ele;
+
+	struct chan *chan;
+	list_for_each(ele, chans) {
+		chan = list_entry(ele, struct chan, list);
+
+		if(chan->enabled && chan->input)
+			deactivate_fd(chan->fd, irq);
+	}
+}
+
+void reactivate_chan(struct list_head *chans, int irq)
+{
+	struct list_head *ele;
+	struct chan *chan;
+
+	list_for_each(ele, chans) {
+		chan = list_entry(ele, struct chan, list);
+
+		if(chan->enabled && chan->input)
+			reactivate_fd(chan->fd, irq);
+	}
+}
+
+int write_chan(struct list_head *chans, const char *buf, int len,
 	       int write_irq)
 {
 	struct list_head *ele;
@@ -285,7 +356,7 @@
 				reactivate_fd(chan->fd, write_irq);
 		}
 	}
-	return(ret);
+	return ret;
 }
 
 int console_write_chan(struct list_head *chans, const char *buf, int len)
@@ -301,19 +372,18 @@
 		n = chan->ops->console_write(chan->fd, buf, len);
 		if(chan->primary) ret = n;
 	}
-	return(ret);
+	return ret;
 }
 
-int console_open_chan(struct line *line, struct console *co, struct chan_opts *opts)
+int console_open_chan(struct line *line, struct console *co,
+		      struct chan_opts *opts)
 {
-	if (!list_empty(&line->chan_list))
-		return 0;
+	int err;
 
-	if (0 != parse_chan_pair(line->init_str, &line->chan_list,
-				 line->init_pri, co->index, opts))
-		return -1;
-	if (0 != open_chan(&line->chan_list))
-		return -1;
+	err = open_chan(&line->chan_list);
+	if(err)
+		return err;
+
 	printk("Console initialized on /dev/%s%d\n",co->name,co->index);
 	return 0;
 }
@@ -327,32 +397,36 @@
 	list_for_each(ele, chans){
 		chan = list_entry(ele, struct chan, list);
 		if(chan->primary){
-			if(chan->ops->window_size == NULL) return(0);
-			return(chan->ops->window_size(chan->fd, chan->data,
-						      rows_out, cols_out));
+			if(chan->ops->window_size == NULL)
+				return 0;
+			return chan->ops->window_size(chan->fd, chan->data,
+						      rows_out, cols_out);
 		}
 	}
-	return(0);
+	return 0;
 }
 
-void free_one_chan(struct chan *chan)
+void free_one_chan(struct chan *chan, int delay_free_irq)
 {
 	list_del(&chan->list);
+
+	close_one_chan(chan, delay_free_irq);
+
 	if(chan->ops->free != NULL)
 		(*chan->ops->free)(chan->data);
-	free_irq_by_fd(chan->fd);
+
 	if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
 	kfree(chan);
 }
 
-void free_chan(struct list_head *chans)
+void free_chan(struct list_head *chans, int delay_free_irq)
 {
 	struct list_head *ele, *next;
 	struct chan *chan;
 
 	list_for_each_safe(ele, next, chans){
 		chan = list_entry(ele, struct chan, list);
-		free_one_chan(chan);
+		free_one_chan(chan, delay_free_irq);
 	}
 }
 
@@ -363,23 +437,23 @@
 
 	if(chan == NULL){
 		CONFIG_CHUNK(str, size, n, "none", 1);
-		return(n);
+		return n;
 	}
 
 	CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
 
 	if(chan->dev == NULL){
 		CONFIG_CHUNK(str, size, n, "", 1);
-		return(n);
+		return n;
 	}
 
 	CONFIG_CHUNK(str, size, n, ":", 0);
 	CONFIG_CHUNK(str, size, n, chan->dev, 0);
 
-	return(n);
+	return n;
 }
 
-static int chan_pair_config_string(struct chan *in, struct chan *out, 
+static int chan_pair_config_string(struct chan *in, struct chan *out,
 				   char *str, int size, char **error_out)
 {
 	int n;
@@ -390,7 +464,7 @@
 
 	if(in == out){
 		CONFIG_CHUNK(str, size, n, "", 1);
-		return(n);
+		return n;
 	}
 
 	CONFIG_CHUNK(str, size, n, ",", 1);
@@ -399,10 +473,10 @@
 	size -= n;
 	CONFIG_CHUNK(str, size, n, "", 1);
 
-	return(n);
+	return n;
 }
 
-int chan_config_string(struct list_head *chans, char *str, int size, 
+int chan_config_string(struct list_head *chans, char *str, int size,
 		       char **error_out)
 {
 	struct list_head *ele;
@@ -418,7 +492,7 @@
 			out = chan;
 	}
 
-	return(chan_pair_config_string(in, out, str, size, error_out));
+	return chan_pair_config_string(in, out, str, size, error_out);
 }
 
 struct chan_type {
@@ -462,7 +536,7 @@
 #endif
 };
 
-static struct chan *parse_chan(char *str, int pri, int device, 
+static struct chan *parse_chan(struct line *line, char *str, int device,
 			       struct chan_opts *opts)
 {
 	struct chan_type *entry;
@@ -484,36 +558,42 @@
 	if(ops == NULL){
 		my_printf("parse_chan couldn't parse \"%s\"\n",
 		       str);
-		return(NULL);
+		return NULL;
 	}
-	if(ops->init == NULL) return(NULL); 
+	if(ops->init == NULL)
+		return NULL;
 	data = (*ops->init)(str, device, opts);
-	if(data == NULL) return(NULL);
+	if(data == NULL)
+		return NULL;
 
 	chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
-	if(chan == NULL) return(NULL);
+	if(chan == NULL)
+		return NULL;
 	*chan = ((struct chan) { .list	 	= LIST_HEAD_INIT(chan->list),
+				 .free_list 	=
+				 	LIST_HEAD_INIT(chan->free_list),
+				 .line		= line,
 				 .primary	= 1,
 				 .input		= 0,
 				 .output 	= 0,
 				 .opened  	= 0,
+				 .enabled  	= 0,
 				 .fd 		= -1,
-				 .pri 		= pri,
 				 .ops 		= ops,
 				 .data 		= data });
-	return(chan);
+	return chan;
 }
 
-int parse_chan_pair(char *str, struct list_head *chans, int pri, int device,
+int parse_chan_pair(char *str, struct line *line, int device,
 		    struct chan_opts *opts)
 {
+	struct list_head *chans = &line->chan_list;
 	struct chan *new, *chan;
 	char *in, *out;
 
 	if(!list_empty(chans)){
 		chan = list_entry(chans->next, struct chan, list);
-		if(chan->pri >= pri) return(0);
-		free_chan(chans);
+		free_chan(chans, 0);
 		INIT_LIST_HEAD(chans);
 	}
 
@@ -522,24 +602,30 @@
 		in = str;
 		*out = '\0';
 		out++;
-		new = parse_chan(in, pri, device, opts);
-		if(new == NULL) return(-1);
+		new = parse_chan(line, in, device, opts);
+		if(new == NULL)
+			return -1;
+
 		new->input = 1;
 		list_add(&new->list, chans);
 
-		new = parse_chan(out, pri, device, opts);
-		if(new == NULL) return(-1);
+		new = parse_chan(line, out, device, opts);
+		if(new == NULL)
+			return -1;
+
 		list_add(&new->list, chans);
 		new->output = 1;
 	}
 	else {
-		new = parse_chan(str, pri, device, opts);
-		if(new == NULL) return(-1);
+		new = parse_chan(line, str, device, opts);
+		if(new == NULL)
+			return -1;
+
 		list_add(&new->list, chans);
 		new->input = 1;
 		new->output = 1;
 	}
-	return(0);
+	return 0;
 }
 
 int chan_out_fd(struct list_head *chans)
@@ -550,9 +636,9 @@
 	list_for_each(ele, chans){
 		chan = list_entry(ele, struct chan, list);
 		if(chan->primary && chan->output)
-			return(chan->fd);
+			return chan->fd;
 	}
-	return(-1);
+	return -1;
 }
 
 void chan_interrupt(struct list_head *chans, struct work_struct *task,
@@ -567,9 +653,9 @@
 		chan = list_entry(ele, struct chan, list);
 		if(!chan->input || (chan->ops->read == NULL)) continue;
 		do {
-			if((tty != NULL) && 
+			if((tty != NULL) &&
 			   (tty->flip.count >= TTY_FLIPBUF_SIZE)){
-				schedule_work(task);
+				schedule_delayed_work(task, 1);
 				goto out;
 			}
 			err = chan->ops->read(chan->fd, &c, chan->data);
@@ -582,29 +668,12 @@
 			if(chan->primary){
 				if(tty != NULL)
 					tty_hangup(tty);
-				line_disable(tty, irq);
-				close_chan(chans);
-				free_chan(chans);
+				close_chan(chans, 1);
 				return;
 			}
-			else {
-				if(chan->ops->close != NULL)
-					chan->ops->close(chan->fd, chan->data);
-				free_one_chan(chan);
-			}
+			else close_one_chan(chan, 1);
 		}
 	}
  out:
 	if(tty) tty_flip_buffer_push(tty);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index e0fdffa..46ceb25 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -23,8 +23,9 @@
 
 static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
 {
-	struct tty_struct *tty = data;
-	struct line *line = tty->driver_data;
+	struct chan *chan = data;
+	struct line *line = chan->line;
+	struct tty_struct *tty = line->tty;
 
 	if (line)
 		chan_interrupt(&line->chan_list, &line->task, tty, irq);
@@ -33,10 +34,11 @@
 
 static void line_timer_cb(void *arg)
 {
-	struct tty_struct *tty = arg;
-	struct line *line = tty->driver_data;
+	struct line *line = arg;
 
-	line_interrupt(line->driver->read_irq, arg, NULL);
+	if(!line->throttled)
+		chan_interrupt(&line->chan_list, &line->task, line->tty,
+			       line->driver->read_irq);
 }
 
 /* Returns the free space inside the ring buffer of this line.
@@ -124,7 +126,8 @@
 	if (len < end){
 		memcpy(line->tail, buf, len);
 		line->tail += len;
-	} else {
+	}
+	else {
 		/* The circular buffer is wrapping */
 		memcpy(line->tail, buf, end);
 		buf += end;
@@ -170,7 +173,7 @@
 	}
 
 	count = line->tail - line->head;
-	n = write_chan(&line->chan_list, line->head, count, 
+	n = write_chan(&line->chan_list, line->head, count,
 		       line->driver->write_irq);
 
 	if(n < 0)
@@ -227,7 +230,7 @@
 		if (err <= 0 && (err != -EAGAIN || !ret))
 			ret = err;
 	} else {
-		n = write_chan(&line->chan_list, buf, len, 
+		n = write_chan(&line->chan_list, buf, len,
 			       line->driver->write_irq);
 		if (n < 0) {
 			ret = n;
@@ -338,11 +341,36 @@
 	return ret;
 }
 
+void line_throttle(struct tty_struct *tty)
+{
+	struct line *line = tty->driver_data;
+
+	deactivate_chan(&line->chan_list, line->driver->read_irq);
+	line->throttled = 1;
+}
+
+void line_unthrottle(struct tty_struct *tty)
+{
+	struct line *line = tty->driver_data;
+
+	line->throttled = 0;
+	chan_interrupt(&line->chan_list, &line->task, tty,
+		       line->driver->read_irq);
+
+	/* Maybe there is enough stuff pending that calling the interrupt
+	 * throttles us again.  In this case, line->throttled will be 1
+	 * again and we shouldn't turn the interrupt back on.
+	 */
+	if(!line->throttled)
+		reactivate_chan(&line->chan_list, line->driver->read_irq);
+}
+
 static irqreturn_t line_write_interrupt(int irq, void *data,
 					struct pt_regs *unused)
 {
-	struct tty_struct *tty = data;
-	struct line *line = tty->driver_data;
+	struct chan *chan = data;
+	struct line *line = chan->line;
+	struct tty_struct *tty = line->tty;
 	int err;
 
 	/* Interrupts are enabled here because we registered the interrupt with
@@ -364,7 +392,7 @@
 	if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
 	   (tty->ldisc.write_wakeup != NULL))
 		(tty->ldisc.write_wakeup)(tty);
-	
+
 	/* BLOCKING mode
 	 * In blocking mode, everything sleeps on tty->write_wait.
 	 * Sleeping in the console driver would break non-blocking
@@ -376,53 +404,29 @@
 	return IRQ_HANDLED;
 }
 
-int line_setup_irq(int fd, int input, int output, struct tty_struct *tty)
+int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
 {
-	struct line *line = tty->driver_data;
 	struct line_driver *driver = line->driver;
 	int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM;
 
 	if (input)
 		err = um_request_irq(driver->read_irq, fd, IRQ_READ,
-				       line_interrupt, flags, 
-				       driver->read_irq_name, tty);
+				       line_interrupt, flags,
+				       driver->read_irq_name, data);
 	if (err)
 		return err;
 	if (output)
 		err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
-					line_write_interrupt, flags, 
-					driver->write_irq_name, tty);
+					line_write_interrupt, flags,
+					driver->write_irq_name, data);
 	line->have_irq = 1;
 	return err;
 }
 
-void line_disable(struct tty_struct *tty, int current_irq)
-{
-	struct line *line = tty->driver_data;
-
-	if(!line->have_irq)
-		return;
-
-	if(line->driver->read_irq == current_irq)
-		free_irq_later(line->driver->read_irq, tty);
-	else {
-		free_irq(line->driver->read_irq, tty);
-	}
-
-	if(line->driver->write_irq == current_irq)
-		free_irq_later(line->driver->write_irq, tty);
-	else {
-		free_irq(line->driver->write_irq, tty);
-	}
-
-	line->have_irq = 0;
-}
-
-int line_open(struct line *lines, struct tty_struct *tty,
-	      struct chan_opts *opts)
+int line_open(struct line *lines, struct tty_struct *tty)
 {
 	struct line *line;
-	int err = 0;
+	int err = -ENODEV;
 
 	line = &lines[tty->index];
 	tty->driver_data = line;
@@ -430,31 +434,29 @@
 	/* The IRQ which takes this lock is not yet enabled and won't be run
 	 * before the end, so we don't need to use spin_lock_irq.*/
 	spin_lock(&line->lock);
-	if (tty->count == 1) {
-		if (!line->valid) {
-			err = -ENODEV;
-			goto out;
+
+	tty->driver_data = line;
+	line->tty = tty;
+	if(!line->valid)
+		goto out;
+
+	if(tty->count == 1){
+		/* Here the device is opened, if necessary, and interrupt
+		 * is registered.
+		 */
+		enable_chan(line);
+		INIT_WORK(&line->task, line_timer_cb, line);
+
+		if(!line->sigio){
+			chan_enable_winch(&line->chan_list, tty);
+			line->sigio = 1;
 		}
-		if (list_empty(&line->chan_list)) {
-			err = parse_chan_pair(line->init_str, &line->chan_list,
-					      line->init_pri, tty->index, opts);
-			if(err) goto out;
-			err = open_chan(&line->chan_list);
-			if(err) goto out;
-		}
-		/* Here the interrupt is registered.*/
-		enable_chan(&line->chan_list, tty);
-		INIT_WORK(&line->task, line_timer_cb, tty);
+
+		chan_window_size(&line->chan_list, &tty->winsize.ws_row,
+				 &tty->winsize.ws_col);
 	}
 
-	if(!line->sigio){
-		chan_enable_winch(&line->chan_list, tty);
-		line->sigio = 1;
-	}
-	chan_window_size(&line->chan_list, &tty->winsize.ws_row,
-			 &tty->winsize.ws_col);
-	line->count++;
-
+	err = 0;
 out:
 	spin_unlock(&line->lock);
 	return err;
@@ -474,15 +476,14 @@
 	/* We ignore the error anyway! */
 	flush_buffer(line);
 
-	line->count--;
-	if (tty->count == 1) {
-		line_disable(tty, -1);
+	if(tty->count == 1){
+		line->tty = NULL;
 		tty->driver_data = NULL;
-	}
 
-        if((line->count == 0) && line->sigio){
-                unregister_winch(tty);
-                line->sigio = 0;
+		if(line->sigio){
+			unregister_winch(tty);
+			line->sigio = 0;
+		}
         }
 
 	spin_unlock_irq(&line->lock);
@@ -493,17 +494,15 @@
 	int i;
 
 	for(i = 0; i < nlines; i++)
-		close_chan(&lines[i].chan_list);
+		close_chan(&lines[i].chan_list, 0);
 }
 
 /* Common setup code for both startup command line and mconsole initialization.
  * @lines contains the the array (of size @num) to modify;
  * @init is the setup string;
- * @all_allowed is a boolean saying if we can setup the whole @lines
- * at once. For instance, it will be usually true for startup init. (where we
- * can use con=xterm) and false for mconsole.*/
+ */
 
-int line_setup(struct line *lines, unsigned int num, char *init, int all_allowed)
+int line_setup(struct line *lines, unsigned int num, char *init)
 {
 	int i, n;
 	char *end;
@@ -512,10 +511,11 @@
 		/* We said con=/ssl= instead of con#=, so we are configuring all
 		 * consoles at once.*/
 		n = -1;
-	} else {
+	}
+	else {
 		n = simple_strtoul(init, &end, 0);
 		if(*end != '='){
-			printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 
+			printk(KERN_ERR "line_setup failed to parse \"%s\"\n",
 			       init);
 			return 0;
 		}
@@ -527,8 +527,9 @@
 		printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
 		       n, num - 1);
 		return 0;
-	} else if (n >= 0){
-		if (lines[n].count > 0) {
+	}
+	else if (n >= 0){
+		if (lines[n].tty != NULL) {
 			printk("line_setup - device %d is open\n", n);
 			return 0;
 		}
@@ -539,13 +540,10 @@
 			else {
 				lines[n].init_str = init;
 				lines[n].valid = 1;
-			}	
+			}
 		}
-	} else if(!all_allowed){
-		printk("line_setup - can't configure all devices from "
-		       "mconsole\n");
-		return 0;
-	} else {
+	}
+	else {
 		for(i = 0; i < num; i++){
 			if(lines[i].init_pri <= INIT_ALL){
 				lines[i].init_pri = INIT_ALL;
@@ -557,18 +555,33 @@
 			}
 		}
 	}
-	return 1;
+	return n == -1 ? num : n;
 }
 
-int line_config(struct line *lines, unsigned int num, char *str)
+int line_config(struct line *lines, unsigned int num, char *str,
+		struct chan_opts *opts)
 {
-	char *new = uml_strdup(str);
+	struct line *line;
+	char *new;
+	int n;
 
-	if(new == NULL){
-		printk("line_config - uml_strdup failed\n");
-		return -ENOMEM;
+	if(*str == '='){
+		printk("line_config - can't configure all devices from "
+		       "mconsole\n");
+		return 1;
 	}
-	return !line_setup(lines, num, new, 0);
+
+	new = kstrdup(str, GFP_KERNEL);
+	if(new == NULL){
+		printk("line_config - kstrdup failed\n");
+		return 1;
+	}
+	n = line_setup(lines, num, new);
+	if(n < 0)
+		return 1;
+
+	line = &lines[n];
+	return parse_chan_pair(line->init_str, line, n, opts);
 }
 
 int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
@@ -594,7 +607,7 @@
 	spin_lock(&line->lock);
 	if(!line->valid)
 		CONFIG_CHUNK(str, size, n, "none", 1);
-	else if(line->count == 0)
+	else if(line->tty == NULL)
 		CONFIG_CHUNK(str, size, n, line->init_str, 1);
 	else n = chan_config_string(&line->chan_list, str, size, error_out);
 	spin_unlock(&line->lock);
@@ -619,14 +632,18 @@
 
 int line_remove(struct line *lines, unsigned int num, int n)
 {
+	int err;
 	char config[sizeof("conxxxx=none\0")];
 
 	sprintf(config, "%d=none", n);
-	return !line_setup(lines, num, config, 0);
+	err = line_setup(lines, num, config);
+	if(err >= 0)
+		err = 0;
+	return err;
 }
 
 struct tty_driver *line_register_devfs(struct lines *set,
-			 struct line_driver *line_driver, 
+			 struct line_driver *line_driver,
 			 struct tty_operations *ops, struct line *lines,
 			 int nlines)
 {
@@ -655,7 +672,7 @@
 	}
 
 	for(i = 0; i < nlines; i++){
-		if(!lines[i].valid) 
+		if(!lines[i].valid)
 			tty_unregister_device(driver, i);
 	}
 
@@ -663,24 +680,28 @@
 	return driver;
 }
 
-static spinlock_t winch_handler_lock;
-LIST_HEAD(winch_handlers);
+static DEFINE_SPINLOCK(winch_handler_lock);
+static LIST_HEAD(winch_handlers);
 
-void lines_init(struct line *lines, int nlines)
+void lines_init(struct line *lines, int nlines, struct chan_opts *opts)
 {
 	struct line *line;
 	int i;
 
-	spin_lock_init(&winch_handler_lock);
 	for(i = 0; i < nlines; i++){
 		line = &lines[i];
 		INIT_LIST_HEAD(&line->chan_list);
-		spin_lock_init(&line->lock);
-		if(line->init_str != NULL){
-			line->init_str = uml_strdup(line->init_str);
-			if(line->init_str == NULL)
-				printk("lines_init - uml_strdup returned "
-				       "NULL\n");
+
+		if(line->init_str == NULL)
+			continue;
+
+		line->init_str = kstrdup(line->init_str, GFP_KERNEL);
+		if(line->init_str == NULL)
+			printk("lines_init - kstrdup returned NULL\n");
+
+		if(parse_chan_pair(line->init_str, line, i, opts)){
+			printk("parse_chan_pair failed for device %d\n", i);
+			line->valid = 0;
 		}
 	}
 }
@@ -717,8 +738,7 @@
 	tty  = winch->tty;
 	if (tty != NULL) {
 		line = tty->driver_data;
-		chan_window_size(&line->chan_list,
-				 &tty->winsize.ws_row, 
+		chan_window_size(&line->chan_list, &tty->winsize.ws_row,
 				 &tty->winsize.ws_col);
 		kill_pg(tty->pgrp, SIGWINCH, 1);
 	}
@@ -749,60 +769,54 @@
 	spin_unlock(&winch_handler_lock);
 
 	if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
-			  SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
+			  SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM,
 			  "winch", winch) < 0)
 		printk("register_winch_irq - failed to register IRQ\n");
 }
 
+static void free_winch(struct winch *winch)
+{
+	list_del(&winch->list);
+
+	if(winch->pid != -1)
+		os_kill_process(winch->pid, 1);
+	if(winch->fd != -1)
+		os_close_file(winch->fd);
+
+	free_irq(WINCH_IRQ, winch);
+	kfree(winch);
+}
+
 static void unregister_winch(struct tty_struct *tty)
 {
 	struct list_head *ele;
-	struct winch *winch, *found = NULL;
+	struct winch *winch;
 
 	spin_lock(&winch_handler_lock);
+
 	list_for_each(ele, &winch_handlers){
 		winch = list_entry(ele, struct winch, list);
                 if(winch->tty == tty){
-                        found = winch;
-                        break;
+			free_winch(winch);
+			break;
                 }
         }
-        if(found == NULL)
-		goto err;
-
-	list_del(&winch->list);
-	spin_unlock(&winch_handler_lock);
-
-        if(winch->pid != -1)
-                os_kill_process(winch->pid, 1);
-
-        free_irq(WINCH_IRQ, winch);
-        kfree(winch);
-
-	return;
-err:
 	spin_unlock(&winch_handler_lock);
 }
 
-/* XXX: No lock as it's an exitcall... is this valid? Depending on cleanup
- * order... are we sure that nothing else is done on the list? */
 static void winch_cleanup(void)
 {
-	struct list_head *ele;
+	struct list_head *ele, *next;
 	struct winch *winch;
 
-	list_for_each(ele, &winch_handlers){
+	spin_lock(&winch_handler_lock);
+
+	list_for_each_safe(ele, next, &winch_handlers){
 		winch = list_entry(ele, struct winch, list);
-		if(winch->fd != -1){
-			/* Why is this different from the above free_irq(),
-			 * which deactivates SIGIO? This searches the FD
-			 * somewhere else and removes it from the list... */
-			deactivate_fd(winch->fd, WINCH_IRQ);
-			os_close_file(winch->fd);
-		}
-		if(winch->pid != -1) 
-			os_kill_process(winch->pid, 1);
+		free_winch(winch);
 	}
+
+	spin_unlock(&winch_handler_lock);
 }
 __uml_exitcall(winch_cleanup);
 
@@ -811,10 +825,10 @@
 	char *umid, *title;
 	int len;
 
-	umid = get_umid(1);
-	if(umid == NULL)
+	umid = get_umid();
+	if(*umid == '\0')
 		return base;
-	
+
 	len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
 	title = kmalloc(len, GFP_KERNEL);
 	if(title == NULL){
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 12c9536..be61012 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -20,6 +20,7 @@
 #include "linux/namei.h"
 #include "linux/proc_fs.h"
 #include "linux/syscalls.h"
+#include "linux/console.h"
 #include "asm/irq.h"
 #include "asm/uaccess.h"
 #include "user_util.h"
@@ -34,7 +35,7 @@
 #include "irq_kern.h"
 #include "choose-mode.h"
 
-static int do_unlink_socket(struct notifier_block *notifier, 
+static int do_unlink_socket(struct notifier_block *notifier,
 			    unsigned long what, void *data)
 {
 	return(mconsole_unlink_socket());
@@ -46,12 +47,12 @@
 	.priority		= 0,
 };
 
-/* Safe without explicit locking for now.  Tasklets provide their own 
+/* Safe without explicit locking for now.  Tasklets provide their own
  * locking, and the interrupt handler is safe because it can't interrupt
  * itself and it can only happen on CPU 0.
  */
 
-LIST_HEAD(mc_requests);
+static LIST_HEAD(mc_requests);
 
 static void mc_work_proc(void *unused)
 {
@@ -60,7 +61,7 @@
 
 	while(!list_empty(&mc_requests)){
 		local_save_flags(flags);
-		req = list_entry(mc_requests.next, struct mconsole_entry, 
+		req = list_entry(mc_requests.next, struct mconsole_entry,
 				 list);
 		list_del(&req->list);
 		local_irq_restore(flags);
@@ -69,7 +70,7 @@
 	}
 }
 
-DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
+static DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
 
 static irqreturn_t mconsole_interrupt(int irq, void *dev_id,
 				      struct pt_regs *regs)
@@ -103,8 +104,8 @@
 {
 	char version[256];
 
-	sprintf(version, "%s %s %s %s %s", system_utsname.sysname, 
-		system_utsname.nodename, system_utsname.release, 
+	sprintf(version, "%s %s %s %s %s", system_utsname.sysname,
+		system_utsname.nodename, system_utsname.release,
 		system_utsname.version, system_utsname.machine);
 	mconsole_reply(req, version, 0, 0);
 }
@@ -348,7 +349,7 @@
 
 #define CONFIG_BUF_SIZE 64
 
-static void mconsole_get_config(int (*get_config)(char *, char *, int, 
+static void mconsole_get_config(int (*get_config)(char *, char *, int,
 						  char **),
 				struct mc_request *req, char *name)
 {
@@ -389,7 +390,6 @@
  out:
 	if(buf != default_buf)
 		kfree(buf);
-	
 }
 
 void mconsole_config(struct mc_request *req)
@@ -420,9 +420,9 @@
 
 void mconsole_remove(struct mc_request *req)
 {
-	struct mc_device *dev;	
+	struct mc_device *dev;
 	char *ptr = req->request.data, *err_msg = "";
-        char error[256];
+	char error[256];
 	int err, start, end, n;
 
 	ptr += strlen("remove");
@@ -433,37 +433,112 @@
 		return;
 	}
 
-        ptr = &ptr[strlen(dev->name)];
+	ptr = &ptr[strlen(dev->name)];
 
-        err = 1;
-        n = (*dev->id)(&ptr, &start, &end);
-        if(n < 0){
-                err_msg = "Couldn't parse device number";
-                goto out;
-        }
-        else if((n < start) || (n > end)){
-                sprintf(error, "Invalid device number - must be between "
-                        "%d and %d", start, end);
-                err_msg = error;
-                goto out;
-        }
+	err = 1;
+	n = (*dev->id)(&ptr, &start, &end);
+	if(n < 0){
+		err_msg = "Couldn't parse device number";
+		goto out;
+	}
+	else if((n < start) || (n > end)){
+		sprintf(error, "Invalid device number - must be between "
+			"%d and %d", start, end);
+		err_msg = error;
+		goto out;
+	}
 
 	err = (*dev->remove)(n);
-        switch(err){
-        case -ENODEV:
-                err_msg = "Device doesn't exist";
-                break;
-        case -EBUSY:
-                err_msg = "Device is currently open";
-                break;
-        default:
-                break;
-        }
- out:
+	switch(err){
+	case -ENODEV:
+		err_msg = "Device doesn't exist";
+		break;
+	case -EBUSY:
+		err_msg = "Device is currently open";
+		break;
+	default:
+		break;
+	}
+out:
 	mconsole_reply(req, err_msg, err, 0);
 }
 
+static DEFINE_SPINLOCK(console_lock);
+static LIST_HEAD(clients);
+static char console_buf[MCONSOLE_MAX_DATA];
+static int console_index = 0;
+
+static void console_write(struct console *console, const char *string,
+			  unsigned len)
+{
+	struct list_head *ele;
+	int n;
+
+	if(list_empty(&clients))
+		return;
+
+	while(1){
+		n = min(len, ARRAY_SIZE(console_buf) - console_index);
+		strncpy(&console_buf[console_index], string, n);
+		console_index += n;
+		string += n;
+		len -= n;
+		if(len == 0)
+			return;
+
+		list_for_each(ele, &clients){
+			struct mconsole_entry *entry;
+
+			entry = list_entry(ele, struct mconsole_entry, list);
+			mconsole_reply_len(&entry->request, console_buf,
+					   console_index, 0, 1);
+		}
+
+		console_index = 0;
+	}
+}
+
+static struct console mc_console = { .name	= "mc",
+				     .write	= console_write,
+				     .flags	= CON_PRINTBUFFER | CON_ENABLED,
+				     .index	= -1 };
+
+static int mc_add_console(void)
+{
+	register_console(&mc_console);
+	return 0;
+}
+
+late_initcall(mc_add_console);
+
+static void with_console(struct mc_request *req, void (*proc)(void *),
+			 void *arg)
+{
+	struct mconsole_entry entry;
+	unsigned long flags;
+
+	INIT_LIST_HEAD(&entry.list);
+	entry.request = *req;
+	list_add(&entry.list, &clients);
+	spin_lock_irqsave(&console_lock, flags);
+
+	(*proc)(arg);
+
+	mconsole_reply_len(req, console_buf, console_index, 0, 0);
+	console_index = 0;
+
+	spin_unlock_irqrestore(&console_lock, flags);
+	list_del(&entry.list);
+}
+
 #ifdef CONFIG_MAGIC_SYSRQ
+static void sysrq_proc(void *arg)
+{
+	char *op = arg;
+
+	handle_sysrq(*op, &current->thread.regs, NULL);
+}
+
 void mconsole_sysrq(struct mc_request *req)
 {
 	char *ptr = req->request.data;
@@ -471,8 +546,13 @@
 	ptr += strlen("sysrq");
 	while(isspace(*ptr)) ptr++;
 
-	mconsole_reply(req, "", 0, 0);
-	handle_sysrq(*ptr, &current->thread.regs, NULL);
+	/* With 'b', the system will shut down without a chance to reply,
+	 * so in this case, we reply first.
+	 */
+	if(*ptr == 'b')
+		mconsole_reply(req, "", 0, 0);
+
+	with_console(req, sysrq_proc, ptr);
 }
 #else
 void mconsole_sysrq(struct mc_request *req)
@@ -481,6 +561,14 @@
 }
 #endif
 
+static void stack_proc(void *arg)
+{
+	struct task_struct *from = current, *to = arg;
+
+	to->thread.saved_task = from;
+	switch_to(from, to, from);
+}
+
 /* Mconsole stack trace
  *  Added by Allan Graves, Jeff Dike
  *  Dumps a stacks registers to the linux console.
@@ -488,37 +576,34 @@
  */
 void do_stack(struct mc_request *req)
 {
-        char *ptr = req->request.data;
-        int pid_requested= -1;
-        struct task_struct *from = NULL;
+	char *ptr = req->request.data;
+	int pid_requested= -1;
+	struct task_struct *from = NULL;
 	struct task_struct *to = NULL;
 
-        /* Would be nice:
-         * 1) Send showregs output to mconsole.
+	/* Would be nice:
+	 * 1) Send showregs output to mconsole.
 	 * 2) Add a way to stack dump all pids.
 	 */
 
-        ptr += strlen("stack");
-        while(isspace(*ptr)) ptr++;
+	ptr += strlen("stack");
+	while(isspace(*ptr)) ptr++;
 
-        /* Should really check for multiple pids or reject bad args here */
-        /* What do the arguments in mconsole_reply mean? */
-        if(sscanf(ptr, "%d", &pid_requested) == 0){
-                mconsole_reply(req, "Please specify a pid", 1, 0);
-                return;
-        }
+	/* Should really check for multiple pids or reject bad args here */
+	/* What do the arguments in mconsole_reply mean? */
+	if(sscanf(ptr, "%d", &pid_requested) == 0){
+		mconsole_reply(req, "Please specify a pid", 1, 0);
+		return;
+	}
 
-        from = current;
-        to = find_task_by_pid(pid_requested);
+	from = current;
 
-        if((to == NULL) || (pid_requested == 0)) {
-                mconsole_reply(req, "Couldn't find that pid", 1, 0);
-                return;
-        }
-        to->thread.saved_task = current;
-
-        switch_to(from, to, from);
-        mconsole_reply(req, "Stack Dumped to console and message log", 0, 0);
+	to = find_task_by_pid(pid_requested);
+	if((to == NULL) || (pid_requested == 0)) {
+		mconsole_reply(req, "Couldn't find that pid", 1, 0);
+		return;
+	}
+	with_console(req, stack_proc, to);
 }
 
 void mconsole_stack(struct mc_request *req)
@@ -534,9 +619,9 @@
 /* Changed by mconsole_setup, which is __setup, and called before SMP is
  * active.
  */
-static char *notify_socket = NULL; 
+static char *notify_socket = NULL;
 
-int mconsole_init(void)
+static int mconsole_init(void)
 {
 	/* long to avoid size mismatch warnings from gcc */
 	long sock;
@@ -563,16 +648,16 @@
 	}
 
 	if(notify_socket != NULL){
-		notify_socket = uml_strdup(notify_socket);
+		notify_socket = kstrdup(notify_socket, GFP_KERNEL);
 		if(notify_socket != NULL)
 			mconsole_notify(notify_socket, MCONSOLE_SOCKET,
-					mconsole_socket_name, 
+					mconsole_socket_name,
 					strlen(mconsole_socket_name) + 1);
 		else printk(KERN_ERR "mconsole_setup failed to strdup "
 			    "string\n");
 	}
 
-	printk("mconsole (version %d) initialized on %s\n", 
+	printk("mconsole (version %d) initialized on %s\n",
 	       MCONSOLE_VERSION, mconsole_socket_name);
 	return(0);
 }
@@ -585,7 +670,7 @@
 	char *buf;
 
 	buf = kmalloc(count + 1, GFP_KERNEL);
-	if(buf == NULL) 
+	if(buf == NULL)
 		return(-ENOMEM);
 
 	if(copy_from_user(buf, buffer, count)){
@@ -661,7 +746,7 @@
 
 	if(notify_socket == NULL) return(0);
 
-	mconsole_notify(notify_socket, MCONSOLE_PANIC, message, 
+	mconsole_notify(notify_socket, MCONSOLE_PANIC, message,
 			strlen(message) + 1);
 	return(0);
 }
@@ -686,14 +771,3 @@
 }
 
 EXPORT_SYMBOL(mconsole_notify_socket);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 310c1f8..4b109fe 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -122,12 +122,12 @@
 	return(1);
 }
 
-int mconsole_reply(struct mc_request *req, char *str, int err, int more)
+int mconsole_reply_len(struct mc_request *req, const char *str, int total,
+		       int err, int more)
 {
 	struct mconsole_reply reply;
-	int total, len, n;
+	int len, n;
 
-	total = strlen(str);
 	do {
 		reply.err = err;
 
@@ -155,6 +155,12 @@
 	return(0);
 }
 
+int mconsole_reply(struct mc_request *req, const char *str, int err, int more)
+{
+	return mconsole_reply_len(req, str, strlen(str), err, more);
+}
+
+
 int mconsole_unlink_socket(void)
 {
 	unlink(mconsole_socket_name);
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 84c73a3..fb1f9fb 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -34,7 +34,7 @@
 #define DRIVER_NAME "uml-netdev"
 
 static DEFINE_SPINLOCK(opened_lock);
-LIST_HEAD(opened);
+static LIST_HEAD(opened);
 
 static int uml_net_rx(struct net_device *dev)
 {
@@ -150,6 +150,7 @@
 	if(lp->close != NULL)
 		(*lp->close)(lp->fd, &lp->user);
 	lp->fd = -1;
+	list_del(&lp->list);
 
 	spin_unlock(&lp->lock);
 	return 0;
@@ -266,7 +267,7 @@
 }
 
 static DEFINE_SPINLOCK(devices_lock);
-static struct list_head devices = LIST_HEAD_INIT(devices);
+static LIST_HEAD(devices);
 
 static struct platform_driver uml_net_driver = {
 	.driver = {
@@ -586,7 +587,7 @@
 	err = eth_parse(str, &n, &str);
 	if(err) return(err);
 
-	str = uml_strdup(str);
+	str = kstrdup(str, GFP_KERNEL);
 	if(str == NULL){
 		printk(KERN_ERR "net_config failed to strdup string\n");
 		return(-1);
@@ -715,6 +716,7 @@
 
 	list_for_each(ele, &opened){
 		lp = list_entry(ele, struct uml_net_private, list);
+		free_irq(lp->dev->irq, lp->dev);
 		if((lp->close != NULL) && (lp->fd >= 0))
 			(*lp->close)(lp->fd, &lp->user);
 		if(lp->remove != NULL) (*lp->remove)(&lp->user);
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 62e04ec..a32ef55 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -69,7 +69,7 @@
 		.name  		= "ssl",
 		.config 	= ssl_config,
 		.get_config 	= ssl_get_config,
-                .id		= line_id,
+		.id		= line_id,
 		.remove 	= ssl_remove,
 	},
 };
@@ -84,26 +84,23 @@
 
 static int ssl_config(char *str)
 {
-	return(line_config(serial_lines, 
-			   sizeof(serial_lines)/sizeof(serial_lines[0]), str));
+	return line_config(serial_lines, ARRAY_SIZE(serial_lines), str, &opts);
 }
 
 static int ssl_get_config(char *dev, char *str, int size, char **error_out)
 {
-	return(line_get_config(dev, serial_lines, 
-			       sizeof(serial_lines)/sizeof(serial_lines[0]), 
-			       str, size, error_out));
+	return line_get_config(dev, serial_lines, ARRAY_SIZE(serial_lines), str,
+			       size, error_out);
 }
 
 static int ssl_remove(int n)
 {
-        return line_remove(serial_lines,
-                           sizeof(serial_lines)/sizeof(serial_lines[0]), n);
+	return line_remove(serial_lines, ARRAY_SIZE(serial_lines), n);
 }
 
 int ssl_open(struct tty_struct *tty, struct file *filp)
 {
-	return line_open(serial_lines, tty, &opts);
+	return line_open(serial_lines, tty);
 }
 
 #if 0
@@ -112,16 +109,6 @@
 	return;
 }
 
-static void ssl_throttle(struct tty_struct * tty)
-{
-	printk(KERN_ERR "Someone should implement ssl_throttle\n");
-}
-
-static void ssl_unthrottle(struct tty_struct * tty)
-{
-	printk(KERN_ERR "Someone should implement ssl_unthrottle\n");
-}
-
 static void ssl_stop(struct tty_struct *tty)
 {
 	printk(KERN_ERR "Someone should implement ssl_stop\n");
@@ -148,9 +135,9 @@
 	.flush_chars 		= line_flush_chars,
 	.set_termios 		= line_set_termios,
 	.ioctl 	 		= line_ioctl,
+	.throttle 		= line_throttle,
+	.unthrottle 		= line_unthrottle,
 #if 0
-	.throttle 		= ssl_throttle,
-	.unthrottle 		= ssl_unthrottle,
 	.stop 	 		= ssl_stop,
 	.start 	 		= ssl_start,
 	.hangup 	 	= ssl_hangup,
@@ -183,7 +170,7 @@
 {
 	struct line *line = &serial_lines[co->index];
 
-	return console_open_chan(line,co,&opts);
+	return console_open_chan(line, co, &opts);
 }
 
 static struct console ssl_cons = {
@@ -199,12 +186,13 @@
 {
 	char *new_title;
 
-	printk(KERN_INFO "Initializing software serial port version %d\n", 
+	printk(KERN_INFO "Initializing software serial port version %d\n",
 	       ssl_version);
 	ssl_driver = line_register_devfs(&lines, &driver, &ssl_ops,
-					 serial_lines, ARRAY_SIZE(serial_lines));
+					 serial_lines,
+					 ARRAY_SIZE(serial_lines));
 
-	lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]));
+	lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
 
 	new_title = add_xterm_umid(opts.xterm_title);
 	if (new_title != NULL)
@@ -212,7 +200,7 @@
 
 	ssl_init_done = 1;
 	register_console(&ssl_cons);
-	return(0);
+	return 0;
 }
 late_initcall(ssl_init);
 
@@ -220,16 +208,13 @@
 {
 	if (!ssl_init_done)
 		return;
-	close_lines(serial_lines,
-		    sizeof(serial_lines)/sizeof(serial_lines[0]));
+	close_lines(serial_lines, ARRAY_SIZE(serial_lines));
 }
 __uml_exitcall(ssl_exit);
 
 static int ssl_chan_setup(char *str)
 {
-	return(line_setup(serial_lines,
-			  sizeof(serial_lines)/sizeof(serial_lines[0]),
-			  str, 1));
+	return line_setup(serial_lines, ARRAY_SIZE(serial_lines), str);
 }
 
 __setup("ssl", ssl_chan_setup);
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 005aa63..61db8b2 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -75,7 +75,7 @@
 		.name  		= "con",
 		.config 	= con_config,
 		.get_config 	= con_get_config,
-                .id		= line_id,
+		.id		= line_id,
 		.remove 	= con_remove,
 	},
 };
@@ -86,28 +86,27 @@
  * individual elements are protected by individual semaphores.
  */
 struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
-			      [ 1 ... MAX_TTYS - 1 ] = 
+			      [ 1 ... MAX_TTYS - 1 ] =
 			      LINE_INIT(CONFIG_CON_CHAN, &driver) };
 
 static int con_config(char *str)
 {
-	return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
+	return line_config(vts, ARRAY_SIZE(vts), str, &opts);
 }
 
 static int con_get_config(char *dev, char *str, int size, char **error_out)
 {
-	return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str, 
-			       size, error_out));
+	return line_get_config(dev, vts, ARRAY_SIZE(vts), str, size, error_out);
 }
 
 static int con_remove(int n)
 {
-        return line_remove(vts, sizeof(vts)/sizeof(vts[0]), n);
+	return line_remove(vts, ARRAY_SIZE(vts), n);
 }
 
 static int con_open(struct tty_struct *tty, struct file *filp)
 {
-	return line_open(vts, tty, &opts);
+	return line_open(vts, tty);
 }
 
 static int con_init_done = 0;
@@ -117,16 +116,18 @@
 	.close 	 		= line_close,
 	.write 	 		= line_write,
 	.put_char 		= line_put_char,
- 	.write_room		= line_write_room,
+	.write_room		= line_write_room,
 	.chars_in_buffer 	= line_chars_in_buffer,
 	.flush_buffer 		= line_flush_buffer,
 	.flush_chars 		= line_flush_chars,
 	.set_termios 		= line_set_termios,
 	.ioctl 	 		= line_ioctl,
+	.throttle 		= line_throttle,
+	.unthrottle 		= line_unthrottle,
 };
 
 static void uml_console_write(struct console *console, const char *string,
-			  unsigned len)
+			      unsigned len)
 {
 	struct line *line = &vts[console->index];
 	unsigned long flags;
@@ -146,7 +147,7 @@
 {
 	struct line *line = &vts[co->index];
 
-	return console_open_chan(line,co,&opts);
+	return console_open_chan(line, co, &opts);
 }
 
 static struct console stdiocons = {
@@ -156,7 +157,7 @@
 	.setup		= uml_console_setup,
 	.flags		= CON_PRINTBUFFER,
 	.index		= -1,
-	.data           = &vts,
+	.data		= &vts,
 };
 
 int stdio_init(void)
@@ -166,11 +167,11 @@
 	console_driver = line_register_devfs(&console_lines, &driver,
 					     &console_ops, vts,
 					     ARRAY_SIZE(vts));
-	if (NULL == console_driver)
+	if (console_driver == NULL)
 		return -1;
 	printk(KERN_INFO "Initialized stdio console driver\n");
 
-	lines_init(vts, sizeof(vts)/sizeof(vts[0]));
+	lines_init(vts, ARRAY_SIZE(vts), &opts);
 
 	new_title = add_xterm_umid(opts.xterm_title);
 	if(new_title != NULL)
@@ -178,7 +179,7 @@
 
 	con_init_done = 1;
 	register_console(&stdiocons);
-	return(0);
+	return 0;
 }
 late_initcall(stdio_init);
 
@@ -186,13 +187,13 @@
 {
 	if (!con_init_done)
 		return;
-	close_lines(vts, sizeof(vts)/sizeof(vts[0]));
+	close_lines(vts, ARRAY_SIZE(vts));
 }
 __uml_exitcall(console_exit);
 
 static int console_chan_setup(char *str)
 {
-	return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
+	return line_setup(vts, ARRAY_SIZE(vts), str);
 }
 __setup("con", console_chan_setup);
 __channel_help(console_chan_setup, "con");
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 9389891..3a93c6f 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -117,6 +117,7 @@
 static int ubd_release(struct inode * inode, struct file * file);
 static int ubd_ioctl(struct inode * inode, struct file * file,
 		     unsigned int cmd, unsigned long arg);
+static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
 #define MAX_DEV (8)
 
@@ -125,6 +126,7 @@
         .open		= ubd_open,
         .release	= ubd_release,
         .ioctl		= ubd_ioctl,
+	.getgeo		= ubd_getgeo,
 };
 
 /* Protected by the queue_lock */
@@ -706,7 +708,7 @@
 {
 	int n, err;
 
-	str = uml_strdup(str);
+	str = kstrdup(str, GFP_KERNEL);
 	if(str == NULL){
 		printk(KERN_ERR "ubd_config failed to strdup string\n");
 		return(1);
@@ -1058,6 +1060,16 @@
 	}
 }
 
+static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct ubd *dev = bdev->bd_disk->private_data;
+
+	geo->heads = 128;
+	geo->sectors = 32;
+	geo->cylinders = dev->size / (128 * 32 * 512);
+	return 0;
+}
+
 static int ubd_ioctl(struct inode * inode, struct file * file,
 		     unsigned int cmd, unsigned long arg)
 {
@@ -1070,16 +1082,7 @@
 	};
 
 	switch (cmd) {
-	        struct hd_geometry g;
 		struct cdrom_volctrl volume;
-	case HDIO_GETGEO:
-		if(!loc) return(-EINVAL);
-		g.heads = 128;
-		g.sectors = 32;
-		g.cylinders = dev->size / (128 * 32 * 512);
-		g.start = get_start_sect(inode->i_bdev);
-		return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
-
 	case HDIO_GET_IDENTITY:
 		ubd_id.cyls = dev->size / (128 * 32 * 512);
 		if(copy_to_user((char __user *) arg, (char *) &ubd_id,
@@ -1387,15 +1390,6 @@
 			printk("io_thread - write failed, fd = %d, err = %d\n",
 			       kernel_fd, -n);
 	}
-}
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+	return 0;
+}
diff --git a/arch/um/include/chan_kern.h b/arch/um/include/chan_kern.h
index da9a671..1bb5e9d 100644
--- a/arch/um/include/chan_kern.h
+++ b/arch/um/include/chan_kern.h
@@ -14,21 +14,23 @@
 
 struct chan {
 	struct list_head list;
+	struct list_head free_list;
+	struct line *line;
 	char *dev;
 	unsigned int primary:1;
 	unsigned int input:1;
 	unsigned int output:1;
 	unsigned int opened:1;
+	unsigned int enabled:1;
 	int fd;
-	enum chan_init_pri pri;
 	struct chan_ops *ops;
 	void *data;
 };
 
 extern void chan_interrupt(struct list_head *chans, struct work_struct *task,
 			   struct tty_struct *tty, int irq);
-extern int parse_chan_pair(char *str, struct list_head *chans, int pri, 
-			   int device, struct chan_opts *opts);
+extern int parse_chan_pair(char *str, struct line *line, int device,
+			   struct chan_opts *opts);
 extern int open_chan(struct list_head *chans);
 extern int write_chan(struct list_head *chans, const char *buf, int len,
 			     int write_irq);
@@ -36,9 +38,11 @@
 			      int len);
 extern int console_open_chan(struct line *line, struct console *co,
 			     struct chan_opts *opts);
-extern void close_chan(struct list_head *chans);
+extern void deactivate_chan(struct list_head *chans, int irq);
+extern void reactivate_chan(struct list_head *chans, int irq);
 extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty);
-extern void enable_chan(struct list_head *chans, struct tty_struct *tty);
+extern void enable_chan(struct line *line);
+extern void close_chan(struct list_head *chans, int delay_free_irq);
 extern int chan_window_size(struct list_head *chans, 
 			     unsigned short *rows_out, 
 			     unsigned short *cols_out);
@@ -47,14 +51,3 @@
 			      char **error_out);
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/choose-mode.h b/arch/um/include/choose-mode.h
index f25fa83..b87b36a 100644
--- a/arch/um/include/choose-mode.h
+++ b/arch/um/include/choose-mode.h
@@ -23,6 +23,9 @@
 
 #elif defined(UML_CONFIG_MODE_TT)
 #define CHOOSE_MODE(tt, skas) (tt)
+
+#else
+#error CONFIG_MODE_SKAS and CONFIG_MODE_TT are both disabled
 #endif
 
 #define CHOOSE_MODE_PROC(tt, skas, args...) \
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index f724b71..b61deb8 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -18,19 +18,8 @@
 extern void forward_interrupts(int pid);
 extern void init_irq_signals(int on_sigstack);
 extern void forward_ipi(int fd, int pid);
-extern void free_irq_later(int irq, void *dev_id);
 extern int activate_ipi(int fd, int pid);
 extern unsigned long irq_lock(void);
 extern void irq_unlock(unsigned long flags);
-#endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+#endif
diff --git a/arch/um/include/kern.h b/arch/um/include/kern.h
index 1e31707..7d223be 100644
--- a/arch/um/include/kern.h
+++ b/arch/um/include/kern.h
@@ -17,7 +17,7 @@
 
 extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
 extern int sleep(int);
-extern int printf(char *fmt, ...);
+extern int printf(const char *fmt, ...);
 extern char *strerror(int errnum);
 extern char *ptsname(int __fd);
 extern int munmap(void *, int);
@@ -35,15 +35,6 @@
 extern int pipe(int *);
 extern int sched_yield(void);
 extern int ptrace(int op, int pid, long addr, long data);
+
 #endif
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index e5fec55..8f4e46d 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -10,6 +10,19 @@
 #include "sysdep/ptrace.h"
 #include "sysdep/faultinfo.h"
 
+typedef void (*kern_hndl)(int, union uml_pt_regs *);
+
+struct kern_handlers {
+	kern_hndl relay_signal;
+	kern_hndl winch;
+	kern_hndl bus_handler;
+	kern_hndl page_fault;
+	kern_hndl sigio_handler;
+	kern_hndl timer_handler;
+};
+
+extern struct kern_handlers handlinfo_kern;
+
 extern int ncpus;
 extern char *linux_prog;
 extern char *gdb_init;
@@ -51,8 +64,6 @@
 extern int set_signals(int enable);
 extern void force_sigbus(void);
 extern int pid_to_processor_id(int pid);
-extern void block_signals(void);
-extern void unblock_signals(void);
 extern void deliver_signals(void *t);
 extern int next_syscall_index(int max);
 extern int next_trap_index(int max);
@@ -111,6 +122,8 @@
 extern void free_irq(unsigned int, void *);
 extern int um_in_interrupt(void);
 extern int cpu(void);
+extern void segv_handler(int sig, union uml_pt_regs *regs);
+extern void sigio_handler(int sig, union uml_pt_regs *regs);
 
 #endif
 
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 5323d22..6f4d680 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -32,11 +32,13 @@
 };
 
 struct line {
+	struct tty_struct *tty;
 	char *init_str;
 	int init_pri;
 	struct list_head chan_list;
 	int valid;
 	int count;
+	int throttled;
 	/*This lock is actually, mostly, local to*/
 	spinlock_t lock;
 
@@ -58,14 +60,15 @@
 #define LINE_INIT(str, d) \
 	{ init_str :	str, \
 	  init_pri :	INIT_STATIC, \
-	  chan_list : 	{ }, \
 	  valid :	1, \
+	  throttled :	0, \
+	  lock :	SPIN_LOCK_UNLOCKED, \
 	  buffer :	NULL, \
 	  head :	NULL, \
 	  tail :	NULL, \
 	  sigio :	0, \
- 	  driver :	d, \
-          have_irq :	0 }
+	  driver :	d, \
+	  have_irq :	0 }
 
 struct lines {
 	int num;
@@ -74,11 +77,11 @@
 #define LINES_INIT(n) {  num :		n }
 
 extern void line_close(struct tty_struct *tty, struct file * filp);
-extern int line_open(struct line *lines, struct tty_struct *tty, 
-		     struct chan_opts *opts);
-extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init,
-		      int all_allowed);
-extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len);
+extern int line_open(struct line *lines, struct tty_struct *tty);
+extern int line_setup(struct line *lines, unsigned int sizeof_lines,
+		      char *init);
+extern int line_write(struct tty_struct *tty, const unsigned char *buf,
+		      int len);
 extern void line_put_char(struct tty_struct *tty, unsigned char ch);
 extern void line_set_termios(struct tty_struct *tty, struct termios * old);
 extern int line_chars_in_buffer(struct tty_struct *tty);
@@ -87,23 +90,27 @@
 extern int line_write_room(struct tty_struct *tty);
 extern int line_ioctl(struct tty_struct *tty, struct file * file,
 		      unsigned int cmd, unsigned long arg);
+extern void line_throttle(struct tty_struct *tty);
+extern void line_unthrottle(struct tty_struct *tty);
 
 extern char *add_xterm_umid(char *base);
-extern int line_setup_irq(int fd, int input, int output, struct tty_struct *tty);
+extern int line_setup_irq(int fd, int input, int output, struct line *line,
+			  void *data);
 extern void line_close_chan(struct line *line);
-extern void line_disable(struct tty_struct *tty, int current_irq);
-extern struct tty_driver * line_register_devfs(struct lines *set, 
-				struct line_driver *line_driver, 
+extern struct tty_driver * line_register_devfs(struct lines *set,
+				struct line_driver *line_driver,
 				struct tty_operations *driver,
 				struct line *lines,
 				int nlines);
-extern void lines_init(struct line *lines, int nlines);
+extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts);
 extern void close_lines(struct line *lines, int nlines);
 
-extern int line_config(struct line *lines, unsigned int sizeof_lines, char *str);
+extern int line_config(struct line *lines, unsigned int sizeof_lines,
+		       char *str, struct chan_opts *opts);
 extern int line_id(char **str, int *start_out, int *end_out);
 extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n);
-extern int line_get_config(char *dev, struct line *lines, unsigned int sizeof_lines, char *str,
+extern int line_get_config(char *dev, struct line *lines,
+			   unsigned int sizeof_lines, char *str,
 			   int size, char **error_out);
 
 #endif
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index b1b512f..58f67d3 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -32,7 +32,7 @@
 
 struct mconsole_notify {
 	u32 magic;
-	u32 version;	
+	u32 version;
 	enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
 	       MCONSOLE_USER_NOTIFY } type;
 	u32 len;
@@ -66,7 +66,9 @@
 extern char mconsole_socket_name[];
 
 extern int mconsole_unlink_socket(void);
-extern int mconsole_reply(struct mc_request *req, char *reply, int err,
+extern int mconsole_reply_len(struct mc_request *req, const char *reply,
+			      int len, int err, int more);
+extern int mconsole_reply(struct mc_request *req, const char *str, int err,
 			  int more);
 
 extern void mconsole_version(struct mc_request *req);
@@ -84,7 +86,7 @@
 extern void mconsole_stack(struct mc_request *req);
 
 extern int mconsole_get_request(int fd, struct mc_request *req);
-extern int mconsole_notify(char *sock_name, int type, const void *data, 
+extern int mconsole_notify(char *sock_name, int type, const void *data,
 			   int len);
 extern char *mconsole_notify_socket(void);
 extern void lock_notify(void);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 2cccfa5..dd72d66 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -9,6 +9,8 @@
 #include "uml-config.h"
 #include "asm/types.h"
 #include "../os/include/file.h"
+#include "sysdep/ptrace.h"
+#include "kern_util.h"
 
 #define OS_TYPE_FILE 1 
 #define OS_TYPE_DIR 2 
@@ -213,15 +215,24 @@
 			     int stack_order);
 extern int helper_wait(int pid);
 
-#endif
+/* umid.c */
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
+extern int umid_file_name(char *name, char *buf, int len);
+extern int set_umid(char *name);
+extern char *get_umid(void);
+
+/* signal.c */
+extern void set_sigstack(void *sig_stack, int size);
+extern void remove_sigstack(void);
+extern void set_handler(int sig, void (*handler)(int), int flags, ...);
+extern int change_sig(int signal, int on);
+extern void block_signals(void);
+extern void unblock_signals(void);
+extern int get_signals(void);
+extern int set_signals(int enable);
+
+/* trap.c */
+extern void os_fill_handlinfo(struct kern_handlers h);
+extern void do_longjmp(void *p, int val);
+
+#endif
diff --git a/arch/um/include/signal_user.h b/arch/um/include/signal_user.h
deleted file mode 100644
index b075e54..0000000
--- a/arch/um/include/signal_user.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* 
- * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __SIGNAL_USER_H__
-#define __SIGNAL_USER_H__
-
-extern int signal_stack_size;
-
-extern int change_sig(int signal, int on);
-extern void set_sigstack(void *stack, int size);
-extern void set_handler(int sig, void (*handler)(int), int flags, ...);
-extern int set_signals(int enable);
-extern int get_signals(void);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h
index 6ba8cbb..b492b12 100644
--- a/arch/um/include/sysdep-i386/stub.h
+++ b/arch/um/include/sysdep-i386/stub.h
@@ -6,8 +6,12 @@
 #ifndef __SYSDEP_STUB_H
 #define __SYSDEP_STUB_H
 
+#include <sys/mman.h>
 #include <asm/ptrace.h>
 #include <asm/unistd.h>
+#include "stub-data.h"
+#include "kern_constants.h"
+#include "uml-config.h"
 
 extern void stub_segv_handler(int sig);
 extern void stub_clone_handler(void);
@@ -76,23 +80,22 @@
 	return ret;
 }
 
-static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
-				 long arg4, long arg5, long arg6)
-{
-	long ret;
-
-	__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; "
-			"int $0x80 ; pop %%ebp"
-			: "=a" (ret)
-			: "g" (syscall), "b" (arg1), "c" (arg2), "d" (arg3),
-			  "S" (arg4), "D" (arg5), "0" (arg6));
-
-	return ret;
-}
-
 static inline void trap_myself(void)
 {
 	__asm("int3");
 }
 
+static inline void remap_stack(int fd, unsigned long offset)
+{
+	__asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;"
+			  "movl %7, %%ebx ; movl %%eax, (%%ebx)"
+			  : : "g" (STUB_MMAP_NR), "b" (UML_CONFIG_STUB_DATA), 
+			    "c" (UM_KERN_PAGE_SIZE), 
+			    "d" (PROT_READ | PROT_WRITE),
+			    "S" (MAP_FIXED | MAP_SHARED), "D" (fd), 
+			    "a" (offset), 
+			    "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) 
+			  : "memory");
+}
+
 #endif
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h
index c41689c..92e989f 100644
--- a/arch/um/include/sysdep-x86_64/stub.h
+++ b/arch/um/include/sysdep-x86_64/stub.h
@@ -6,8 +6,12 @@
 #ifndef __SYSDEP_STUB_H
 #define __SYSDEP_STUB_H
 
+#include <sys/mman.h>
 #include <asm/unistd.h>
 #include <sysdep/ptrace_user.h>
+#include "stub-data.h"
+#include "kern_constants.h"
+#include "uml-config.h"
 
 extern void stub_segv_handler(int sig);
 extern void stub_clone_handler(void);
@@ -81,23 +85,23 @@
 	return ret;
 }
 
-static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
-				 long arg4, long arg5, long arg6)
-{
-	long ret;
-
-	__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; "
-		"movq %7, %%r9; " __syscall : "=a" (ret)
-		: "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
-		  "g" (arg4), "g" (arg5), "g" (arg6)
-		: __syscall_clobber, "r10", "r8", "r9" );
-
-	return ret;
-}
-
 static inline void trap_myself(void)
 {
 	__asm("int3");
 }
 
+static inline void remap_stack(long fd, unsigned long offset)
+{
+	__asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; "
+			  "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; "
+			  "movq %%rax, (%%rbx)": 
+			  : "a" (STUB_MMAP_NR), "D" (UML_CONFIG_STUB_DATA), 
+			    "S" (UM_KERN_PAGE_SIZE), 
+			    "d" (PROT_READ | PROT_WRITE), 
+                            "g" (MAP_FIXED | MAP_SHARED), "g" (fd), 
+			    "g" (offset),
+			    "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err)
+			  : __syscall_clobber, "r10", "r8", "r9" );
+}
+
 #endif
diff --git a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
index f8760a3..4567f1e 100644
--- a/arch/um/include/um_uaccess.h
+++ b/arch/um/include/um_uaccess.h
@@ -17,6 +17,8 @@
 #include "uaccess-skas.h"
 #endif
 
+#include "asm/fixmap.h"
+
 #define __under_task_size(addr, size) \
 	(((unsigned long) (addr) < TASK_SIZE) && \
          (((unsigned long) (addr) + (size)) < TASK_SIZE))
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index bb505e0..c1dbd77 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -23,12 +23,7 @@
 
 extern struct cpu_task cpu_tasks[];
 
-struct signal_info {
-	void (*handler)(int, union uml_pt_regs *);
-	int is_irq;
-};
-
-extern struct signal_info sig_info[];
+extern void (*sig_info[])(int, union uml_pt_regs *);
 
 extern unsigned long low_physmem;
 extern unsigned long high_physmem;
@@ -64,8 +59,6 @@
 extern void setup_hostinfo(void);
 extern void do_exec(int old_pid, int new_pid);
 extern void tracer_panic(char *msg, ...);
-extern char *get_umid(int only_if_set);
-extern void do_longjmp(void *p, int val);
 extern int detach(int pid, int sig);
 extern int attach(int pid);
 extern void kill_child_dead(int pid);
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index 3de9d21..193cc2b7 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -9,9 +9,9 @@
 obj-y = config.o exec_kern.o exitcode.o \
 	init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \
 	process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
-	signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \
-	time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o \
-	umid.o user_util.o
+	signal_kern.o smp.o syscall_kern.o sysrq.o time.o \
+	time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o \
+	user_util.o
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
 obj-$(CONFIG_GPROF)	+= gprof_syms.o
@@ -24,7 +24,7 @@
 
 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
 
-USER_OBJS := $(user-objs-y) config.o time.o tty_log.o umid.o user_util.o
+USER_OBJS := $(user-objs-y) config.o time.o tty_log.o user_util.o
 
 include arch/um/scripts/Makefile.rules
 
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
index c3ccaf2..0e32f5f 100644
--- a/arch/um/kernel/irq_user.c
+++ b/arch/um/kernel/irq_user.c
@@ -15,7 +15,6 @@
 #include "kern_util.h"
 #include "user.h"
 #include "process.h"
-#include "signal_user.h"
 #include "sigio.h"
 #include "irq_user.h"
 #include "os.h"
@@ -29,7 +28,6 @@
 	int pid;
 	int events;
 	int current_events;
-	int freed;
 };
 
 static struct irq_fd *active_fds = NULL;
@@ -41,9 +39,11 @@
 
 extern int io_count, intr_count;
 
+extern void free_irqs(void);
+
 void sigio_handler(int sig, union uml_pt_regs *regs)
 {
-	struct irq_fd *irq_fd, *next;
+	struct irq_fd *irq_fd;
 	int i, n;
 
 	if(smp_sigio_handler()) return;
@@ -66,29 +66,15 @@
 			irq_fd = irq_fd->next;
 		}
 
-		for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
-			next = irq_fd->next;
+		for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
 			if(irq_fd->current_events != 0){
 				irq_fd->current_events = 0;
 				do_IRQ(irq_fd->irq, regs);
-
-				/* This is here because the next irq may be
-				 * freed in the handler.  If a console goes
-				 * away, both the read and write irqs will be
-				 * freed.  After do_IRQ, ->next will point to
-				 * a good IRQ.
-				 * Irqs can't be freed inside their handlers,
-				 * so the next best thing is to have them
-				 * marked as needing freeing, so that they
-				 * can be freed here.
-				 */
-				next = irq_fd->next;
-				if(irq_fd->freed){
-					free_irq(irq_fd->irq, irq_fd->id);
-				}
 			}
 		}
 	}
+
+	free_irqs();
 }
 
 int activate_ipi(int fd, int pid)
@@ -136,8 +122,7 @@
 				     .irq 		= irq,
 				     .pid  		= pid,
 				     .events 		= events,
-				     .current_events 	= 0,
-				     .freed 		= 0  } );
+				     .current_events 	= 0 } );
 
 	/* Critical section - locked by a spinlock because this stuff can
 	 * be changed from interrupt handlers.  The stuff above is done 
@@ -313,26 +298,6 @@
 	return(irq);
 }
 
-void free_irq_later(int irq, void *dev_id)
-{
-	struct irq_fd *irq_fd;
-	unsigned long flags;
-
-	flags = irq_lock();
-	for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
-		if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
-			break;
-	}
-	if(irq_fd == NULL){
-		printk("free_irq_later found no irq, irq = %d, "
-		       "dev_id = 0x%p\n", irq, dev_id);
-		goto out;
-	}
-	irq_fd->freed = 1;
- out:
-	irq_unlock(flags);
-}
-
 void reactivate_fd(int fd, int irqnum)
 {
 	struct irq_fd *irq;
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 34b54a3..d2d3f25 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -36,7 +36,6 @@
 #include "kern_util.h"
 #include "kern.h"
 #include "signal_kern.h"
-#include "signal_user.h"
 #include "init.h"
 #include "irq_user.h"
 #include "mem_user.h"
@@ -324,10 +323,6 @@
 	return(stack != (unsigned long) current_thread);
 }
 
-extern void remove_umid_dir(void);
-
-__uml_exitcall(remove_umid_dir);
-
 extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
 
 void do_uml_exitcalls(void)
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index a637e88..6f1a3a2 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -12,6 +12,8 @@
 #include "mode.h"
 #include "choose-mode.h"
 
+void (*pm_power_off)(void);
+
 #ifdef CONFIG_SMP
 static void kill_idlers(int me)
 {
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
index 48b1f64..62e5cfd 100644
--- a/arch/um/kernel/sigio_user.c
+++ b/arch/um/kernel/sigio_user.c
@@ -216,6 +216,8 @@
 				       "err = %d\n", -n);
 		}
 	}
+
+	return 0;
 }
 
 static int need_poll(int n)
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
index 03618bd..7b0e0e8 100644
--- a/arch/um/kernel/signal_kern.c
+++ b/arch/um/kernel/signal_kern.c
@@ -22,7 +22,6 @@
 #include "asm/ucontext.h"
 #include "kern_util.h"
 #include "signal_kern.h"
-#include "signal_user.h"
 #include "kern.h"
 #include "frame_kern.h"
 #include "sigcontext.h"
diff --git a/arch/um/kernel/signal_user.c b/arch/um/kernel/signal_user.c
deleted file mode 100644
index 62f4578..0000000
--- a/arch/um/kernel/signal_user.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <sys/mman.h>
-#include "user_util.h"
-#include "kern_util.h"
-#include "user.h"
-#include "signal_user.h"
-#include "signal_kern.h"
-#include "sysdep/sigcontext.h"
-#include "sigcontext.h"
-
-void set_sigstack(void *sig_stack, int size)
-{
-	stack_t stack = ((stack_t) { .ss_flags	= 0,
-				     .ss_sp	= (__ptr_t) sig_stack,
-				     .ss_size 	= size - sizeof(void *) });
-
-	if(sigaltstack(&stack, NULL) != 0)
-		panic("enabling signal stack failed, errno = %d\n", errno);
-}
-
-void set_handler(int sig, void (*handler)(int), int flags, ...)
-{
-	struct sigaction action;
-	va_list ap;
-	int mask;
-
-	va_start(ap, flags);
-	action.sa_handler = handler;
-	sigemptyset(&action.sa_mask);
-	while((mask = va_arg(ap, int)) != -1){
-		sigaddset(&action.sa_mask, mask);
-	}
-	va_end(ap);
-	action.sa_flags = flags;
-	action.sa_restorer = NULL;
-	if(sigaction(sig, &action, NULL) < 0)
-		panic("sigaction failed");
-}
-
-int change_sig(int signal, int on)
-{
-	sigset_t sigset, old;
-
-	sigemptyset(&sigset);
-	sigaddset(&sigset, signal);
-	sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
-	return(!sigismember(&old, signal));
-}
-
-/* Both here and in set/get_signal we don't touch SIGPROF, because we must not
- * disable profiling; it's safe because the profiling code does not interact
- * with the kernel code at all.*/
-
-static void change_signals(int type)
-{
-	sigset_t mask;
-
-	sigemptyset(&mask);
-	sigaddset(&mask, SIGVTALRM);
-	sigaddset(&mask, SIGALRM);
-	sigaddset(&mask, SIGIO);
-	if(sigprocmask(type, &mask, NULL) < 0)
-		panic("Failed to change signal mask - errno = %d", errno);
-}
-
-void block_signals(void)
-{
-	change_signals(SIG_BLOCK);
-}
-
-void unblock_signals(void)
-{
-	change_signals(SIG_UNBLOCK);
-}
-
-/* These are the asynchronous signals.  SIGVTALRM and SIGARLM are handled
- * together under SIGVTALRM_BIT.  SIGPROF is excluded because we want to
- * be able to profile all of UML, not just the non-critical sections.  If
- * profiling is not thread-safe, then that is not my problem.  We can disable
- * profiling when SMP is enabled in that case.
- */
-#define SIGIO_BIT 0
-#define SIGVTALRM_BIT 1
-
-static int enable_mask(sigset_t *mask)
-{
-	int sigs;
-
-	sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
-	sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
-	sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
-	return(sigs);
-}
-
-int get_signals(void)
-{
-	sigset_t mask;
-	
-	if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
-		panic("Failed to get signal mask");
-	return(enable_mask(&mask));
-}
-
-int set_signals(int enable)
-{
-	sigset_t mask;
-	int ret;
-
-	sigemptyset(&mask);
-	if(enable & (1 << SIGIO_BIT)) 
-		sigaddset(&mask, SIGIO);
-	if(enable & (1 << SIGVTALRM_BIT)){
-		sigaddset(&mask, SIGVTALRM);
-		sigaddset(&mask, SIGALRM);
-	}
-
-	/* This is safe - sigprocmask is guaranteed to copy locally the
-	 * value of new_set, do his work and then, at the end, write to
-	 * old_set.
-	 */
-	if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
-		panic("Failed to enable signals");
-	ret = enable_mask(&mask);
-	sigemptyset(&mask);
-	if((enable & (1 << SIGIO_BIT)) == 0) 
-		sigaddset(&mask, SIGIO);
-	if((enable & (1 << SIGVTALRM_BIT)) == 0){
-		sigaddset(&mask, SIGVTALRM);
-		sigaddset(&mask, SIGALRM);
-	}
-	if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
-		panic("Failed to block signals");
-
-	return(ret);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index 8de471b..7a9fc16 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -4,7 +4,7 @@
 #
 
 obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
-	syscall.o tlb.o trap_user.o uaccess.o
+	syscall.o tlb.o uaccess.o
 
 USER_OBJS := process.o clone.o
 
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
index cb37ce9..47b812b 100644
--- a/arch/um/kernel/skas/clone.c
+++ b/arch/um/kernel/skas/clone.c
@@ -18,11 +18,10 @@
  * on some systems.
  */
 
-#define STUB_DATA(field) (((struct stub_data *) UML_CONFIG_STUB_DATA)->field)
-
 void __attribute__ ((__section__ (".__syscall_stub")))
 stub_clone_handler(void)
 {
+	struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA;
 	long err;
 
 	err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
@@ -35,17 +34,21 @@
 	if(err)
 		goto out;
 
-	err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL,
-			    (long) &STUB_DATA(timer), 0);
+	err = stub_syscall3(__NR_setitimer, ITIMER_VIRTUAL, 
+			    (long) &data->timer, 0);
 	if(err)
 		goto out;
 
-	err = stub_syscall6(STUB_MMAP_NR, UML_CONFIG_STUB_DATA,
-			    UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
-			    MAP_FIXED | MAP_SHARED, STUB_DATA(fd),
-			    STUB_DATA(offset));
+	remap_stack(data->fd, data->offset);
+	goto done;
+
  out:
-	/* save current result. Parent: pid; child: retcode of mmap */
-	STUB_DATA(err) = err;
+	/* save current result. 
+	 * Parent: pid; 
+	 * child: retcode of mmap already saved and it jumps around this 
+	 * assignment
+	 */
+	data->err = err;
+ done:
 	trap_myself();
 }
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index daa2f85..01d489d 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -22,7 +22,6 @@
 extern int user_thread(unsigned long stack, int flags);
 extern void userspace(union uml_pt_regs *regs);
 extern void new_thread_proc(void *stack, void (*handler)(int sig));
-extern void remove_sigstack(void);
 extern void new_thread_handler(int sig);
 extern void handle_syscall(union uml_pt_regs *regs);
 extern int map(struct mm_id * mm_idp, unsigned long virt,
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h
index f611f83..64516c5 100644
--- a/arch/um/kernel/skas/include/uaccess-skas.h
+++ b/arch/um/kernel/skas/include/uaccess-skas.h
@@ -7,7 +7,6 @@
 #define __SKAS_UACCESS_H
 
 #include "asm/errno.h"
-#include "asm/fixmap.h"
 
 /* No SKAS-specific checking. */
 #define access_ok_skas(type, addr, size) 0
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 599d679..9264d40 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -31,7 +31,6 @@
 #include "proc_mm.h"
 #include "skas_ptrace.h"
 #include "chan_user.h"
-#include "signal_user.h"
 #include "registers.h"
 #include "mem.h"
 #include "uml-config.h"
@@ -514,16 +513,6 @@
 	siglongjmp(**switch_buf, 1);
 }
 
-void remove_sigstack(void)
-{
-	stack_t stack = ((stack_t) { .ss_flags	= SS_DISABLE,
-				     .ss_sp	= NULL,
-				     .ss_size	= 0 });
-
-	if(sigaltstack(&stack, NULL) != 0)
-		panic("disabling signal stack failed, errno = %d\n", errno);
-}
-
 void initial_thread_cb_skas(void (*proc)(void *), void *arg)
 {
 	sigjmp_buf here;
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 9c99025..09790cc 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -14,7 +14,6 @@
 #include "asm/atomic.h"
 #include "kern_util.h"
 #include "time_user.h"
-#include "signal_user.h"
 #include "skas.h"
 #include "os.h"
 #include "user_util.h"
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
deleted file mode 100644
index 9950a67..0000000
--- a/arch/um/kernel/skas/trap_user.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/* 
- * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
- * Licensed under the GPL
- */
-
-#include <signal.h>
-#include <errno.h>
-#include "signal_user.h"
-#include "user_util.h"
-#include "kern_util.h"
-#include "task.h"
-#include "sigcontext.h"
-#include "skas.h"
-#include "ptrace_user.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/ptrace_user.h"
-
-void sig_handler_common_skas(int sig, void *sc_ptr)
-{
-	struct sigcontext *sc = sc_ptr;
-	struct skas_regs *r;
-	struct signal_info *info;
-	int save_errno = errno;
-	int save_user;
-
-	/* This is done because to allow SIGSEGV to be delivered inside a SEGV
-	 * handler.  This can happen in copy_user, and if SEGV is disabled,
-	 * the process will die.
-	 * XXX Figure out why this is better than SA_NODEFER
-	 */
-	if(sig == SIGSEGV)
-		change_sig(SIGSEGV, 1);
-
-	r = &TASK_REGS(get_current())->skas;
-	save_user = r->is_user;
-	r->is_user = 0;
-        if ( sig == SIGFPE || sig == SIGSEGV ||
-             sig == SIGBUS || sig == SIGILL ||
-             sig == SIGTRAP ) {
-                GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
-        }
-
-	change_sig(SIGUSR1, 1);
-	info = &sig_info[sig];
-	if(!info->is_irq) unblock_signals();
-
-	(*info->handler)(sig, (union uml_pt_regs *) r);
-
-	errno = save_errno;
-	r->is_user = save_user;
-}
-
-extern int ptrace_faultinfo;
-
-void user_signal(int sig, union uml_pt_regs *regs, int pid)
-{
-	struct signal_info *info;
-        int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
-                    (sig == SIGILL) || (sig == SIGTRAP));
-
-	if (segv)
-		get_skas_faultinfo(pid, &regs->skas.faultinfo);
-	info = &sig_info[sig];
-	(*info->handler)(sig, regs);
-
-	unblock_signals();
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index c40b611..11f518a 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -14,9 +14,9 @@
 #include "kern_util.h"
 #include "user.h"
 #include "process.h"
-#include "signal_user.h"
 #include "time_user.h"
 #include "kern_constants.h"
+#include "os.h"
 
 /* XXX This really needs to be declared and initialized in a kernel file since
  * it's in <linux/time.h>
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index 0d4c10a..d56046c 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -26,9 +26,13 @@
 #include "mconsole_kern.h"
 #include "mem.h"
 #include "mem_kern.h"
+#include "sysdep/sigcontext.h"
+#include "sysdep/ptrace.h"
+#include "os.h"
 #ifdef CONFIG_MODE_SKAS
 #include "skas.h"
 #endif
+#include "os.h"
 
 /* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */
 int handle_page_fault(unsigned long address, unsigned long ip, 
@@ -125,6 +129,25 @@
 	goto out;
 }
 
+void segv_handler(int sig, union uml_pt_regs *regs)
+{
+	struct faultinfo * fi = UPT_FAULTINFO(regs);
+
+	if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
+		bad_segv(*fi, UPT_IP(regs));
+		return;
+	}
+	segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
+}
+
+struct kern_handlers handlinfo_kern = {
+	.relay_signal = relay_signal,
+	.winch = winch,
+	.bus_handler = relay_signal,
+	.page_fault = segv_handler,
+	.sigio_handler = sigio_handler,
+	.timer_handler = timer_handler
+};
 /*
  * We give a *copy* of the faultinfo in the regs to segv.
  * This must be done, since nesting SEGVs could overwrite
diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
deleted file mode 100644
index e9ccd6b..0000000
--- a/arch/um/kernel/trap_user.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <stdlib.h>
-#include <errno.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-#include <asm/page.h>
-#include <asm/unistd.h>
-#include <asm/ptrace.h>
-#include "init.h"
-#include "sysdep/ptrace.h"
-#include "sigcontext.h"
-#include "sysdep/sigcontext.h"
-#include "irq_user.h"
-#include "signal_user.h"
-#include "time_user.h"
-#include "task.h"
-#include "mode.h"
-#include "choose-mode.h"
-#include "kern_util.h"
-#include "user_util.h"
-#include "os.h"
-
-void kill_child_dead(int pid)
-{
-	kill(pid, SIGKILL);
-	kill(pid, SIGCONT);
-	do {
-		int n;
-		CATCH_EINTR(n = waitpid(pid, NULL, 0));
-		if (n > 0)
-			kill(pid, SIGCONT);
-		else
-			break;
-	} while(1);
-}
-
-void segv_handler(int sig, union uml_pt_regs *regs)
-{
-        struct faultinfo * fi = UPT_FAULTINFO(regs);
-
-        if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){
-                bad_segv(*fi, UPT_IP(regs));
-		return;
-	}
-        segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
-}
-
-void usr2_handler(int sig, union uml_pt_regs *regs)
-{
-	CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
-}
-
-struct signal_info sig_info[] = {
-	[ SIGTRAP ] { .handler 		= relay_signal,
-		      .is_irq 		= 0 },
-	[ SIGFPE ] { .handler 		= relay_signal,
-		     .is_irq 		= 0 },
-	[ SIGILL ] { .handler 		= relay_signal,
-		     .is_irq 		= 0 },
-	[ SIGWINCH ] { .handler		= winch,
-		       .is_irq		= 1 },
-	[ SIGBUS ] { .handler 		= bus_handler,
-		     .is_irq 		= 0 },
-	[ SIGSEGV] { .handler 		= segv_handler,
-		     .is_irq 		= 0 },
-	[ SIGIO ] { .handler 		= sigio_handler,
-		    .is_irq 		= 1 },
-	[ SIGVTALRM ] { .handler 	= timer_handler,
-			.is_irq 	= 1 },
-        [ SIGALRM ] { .handler          = timer_handler,
-                      .is_irq           = 1 },
-	[ SIGUSR2 ] { .handler 		= usr2_handler,
-		      .is_irq 		= 0 },
-};
-
-void do_longjmp(void *b, int val)
-{
-	sigjmp_buf *buf = b;
-
-	siglongjmp(*buf, val);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
index 065b504..136e54c 100644
--- a/arch/um/kernel/tt/exec_kern.c
+++ b/arch/um/kernel/tt/exec_kern.c
@@ -14,7 +14,6 @@
 #include "kern_util.h"
 #include "irq_user.h"
 #include "time_user.h"
-#include "signal_user.h"
 #include "mem_user.h"
 #include "os.h"
 #include "tlb.h"
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
index cfaa373..14d4622 100644
--- a/arch/um/kernel/tt/process_kern.c
+++ b/arch/um/kernel/tt/process_kern.c
@@ -13,7 +13,6 @@
 #include "asm/ptrace.h"
 #include "asm/tlbflush.h"
 #include "irq_user.h"
-#include "signal_user.h"
 #include "kern_util.h"
 #include "user_util.h"
 #include "os.h"
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index d11e739..71daae2 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -19,7 +19,6 @@
 #include "sigcontext.h"
 #include "sysdep/sigcontext.h"
 #include "os.h"
-#include "signal_user.h"
 #include "user_util.h"
 #include "mem_user.h"
 #include "process.h"
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index fc10861..a414c52 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -8,18 +8,18 @@
 #include <signal.h>
 #include "sysdep/ptrace.h"
 #include "sysdep/sigcontext.h"
-#include "signal_user.h"
 #include "user_util.h"
 #include "kern_util.h"
 #include "task.h"
 #include "tt.h"
+#include "os.h"
 
 void sig_handler_common_tt(int sig, void *sc_ptr)
 {
 	struct sigcontext *sc = sc_ptr;
 	struct tt_regs save_regs, *r;
-	struct signal_info *info;
 	int save_errno = errno, is_user;
+	void (*handler)(int, union uml_pt_regs *);
 
 	/* This is done because to allow SIGSEGV to be delivered inside a SEGV
 	 * handler.  This can happen in copy_user, and if SEGV is disabled,
@@ -40,10 +40,14 @@
 	if(sig != SIGUSR2) 
 		r->syscall = -1;
 
-	info = &sig_info[sig];
-	if(!info->is_irq) unblock_signals();
+	handler = sig_info[sig];
 
-	(*info->handler)(sig, (union uml_pt_regs *) r);
+	/* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
+	if (sig != SIGIO && sig != SIGWINCH &&
+	    sig != SIGVTALRM && sig != SIGALRM)
+		unblock_signals();
+
+	handler(sig, (union uml_pt_regs *) r);
 
 	if(is_user){
 		interrupt_end();
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 142a949..73747ac 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -146,8 +146,8 @@
 
 	if(CHOOSE_MODE(honeypot, 0)) return;
 
-	umid = get_umid(1);
-	if(umid != NULL){
+	umid = get_umid();
+	if(*umid != '\0'){
 		snprintf(argv1_begin, 
 			 (argv1_end - argv1_begin) * sizeof(*ptr), 
 			 "(%s) ", umid);
@@ -363,6 +363,11 @@
 	uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0,
 				     &host_task_size, &task_size);
 
+	/*
+ 	 * Setting up handlers to 'sig_info' struct
+ 	 */
+	os_fill_handlinfo(handlinfo_kern);
+
 	brk_start = (unsigned long) sbrk(0);
 	CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
 	/* Increase physical memory size for exec-shield users
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
index 0b21d59..4eaee82 100644
--- a/arch/um/kernel/umid.c
+++ b/arch/um/kernel/umid.c
@@ -3,61 +3,30 @@
  * Licensed under the GPL
  */
 
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include "user.h"
-#include "umid.h"
+#include "asm/errno.h"
 #include "init.h"
 #include "os.h"
-#include "user_util.h"
-#include "choose-mode.h"
+#include "kern.h"
+#include "linux/kernel.h"
 
-#define UMID_LEN 64
-#define UML_DIR "~/.uml/"
-
-/* Changed by set_umid and make_umid, which are run early in boot */
-static char umid[UMID_LEN] = { 0 };
-
-/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
-static char *uml_dir = UML_DIR;
-
-/* Changed by set_umid */
-static int umid_is_random = 1;
+/* Changed by set_umid_arg */
 static int umid_inited = 0;
-/* Have we created the files? Should we remove them? */
-static int umid_owned = 0;
-
-static int make_umid(int (*printer)(const char *fmt, ...));
-
-static int __init set_umid(char *name, int is_random,
-			   int (*printer)(const char *fmt, ...))
-{
-	if(umid_inited){
-		(*printer)("Unique machine name can't be set twice\n");
-		return(-1);
-	}
-
-	if(strlen(name) > UMID_LEN - 1)
-		(*printer)("Unique machine name is being truncated to %d "
-			   "characters\n", UMID_LEN);
-	strlcpy(umid, name, sizeof(umid));
-
-	umid_is_random = is_random;
-	umid_inited = 1;
-	return 0;
-}
 
 static int __init set_umid_arg(char *name, int *add)
 {
+	int err;
+
+	if(umid_inited)
+		return 0;
+
 	*add = 0;
-	return(set_umid(name, 0, printf));
+	err = set_umid(name);
+	if(err == -EEXIST)
+		printf("umid '%s' already in use\n", name);
+	else if(!err)
+		umid_inited = 1;
+
+	return 0;
 }
 
 __uml_setup("umid=", set_umid_arg,
@@ -66,265 +35,3 @@
 "    is used for naming the pid file and management console socket.\n\n"
 );
 
-int __init umid_file_name(char *name, char *buf, int len)
-{
-	int n;
-
-	if(!umid_inited && make_umid(printk)) return(-1);
-
-	n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
-	if(n > len){
-		printk("umid_file_name : buffer too short\n");
-		return(-1);
-	}
-
-	sprintf(buf, "%s%s/%s", uml_dir, umid, name);
-	return(0);
-}
-
-extern int tracing_pid;
-
-static void __init create_pid_file(void)
-{
-	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
-	char pid[sizeof("nnnnn\0")];
-	int fd, n;
-
-	if(umid_file_name("pid", file, sizeof(file)))
-		return;
-
-	fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
-			  0644);
-	if(fd < 0){
-		printf("Open of machine pid file \"%s\" failed: %s\n",
-		       file, strerror(-fd));
-		return;
-	}
-
-	sprintf(pid, "%d\n", os_getpid());
-	n = os_write_file(fd, pid, strlen(pid));
-	if(n != strlen(pid))
-		printf("Write of pid file failed - err = %d\n", -n);
-	os_close_file(fd);
-}
-
-static int actually_do_remove(char *dir)
-{
-	DIR *directory;
-	struct dirent *ent;
-	int len;
-	char file[256];
-
-	directory = opendir(dir);
-	if(directory == NULL){
-		printk("actually_do_remove : couldn't open directory '%s', "
-		       "errno = %d\n", dir, errno);
-		return(1);
-	}
-	while((ent = readdir(directory)) != NULL){
-		if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
-			continue;
-		len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
-		if(len > sizeof(file)){
-			printk("Not deleting '%s' from '%s' - name too long\n",
-			       ent->d_name, dir);
-			continue;
-		}
-		sprintf(file, "%s/%s", dir, ent->d_name);
-		if(unlink(file) < 0){
-			printk("actually_do_remove : couldn't remove '%s' "
-			       "from '%s', errno = %d\n", ent->d_name, dir, 
-			       errno);
-			return(1);
-		}
-	}
-	if(rmdir(dir) < 0){
-		printk("actually_do_remove : couldn't rmdir '%s', "
-		       "errno = %d\n", dir, errno);
-		return(1);
-	}
-	return(0);
-}
-
-void remove_umid_dir(void)
-{
-	char dir[strlen(uml_dir) + UMID_LEN + 1];
-	if (!umid_owned)
-		return;
-
-	sprintf(dir, "%s%s", uml_dir, umid);
-	actually_do_remove(dir);
-}
-
-char *get_umid(int only_if_set)
-{
-	if(only_if_set && umid_is_random)
-		return NULL;
-	return umid;
-}
-
-static int not_dead_yet(char *dir)
-{
-	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
-	char pid[sizeof("nnnnn\0")], *end;
-	int dead, fd, p, n;
-
-	sprintf(file, "%s/pid", dir);
-	dead = 0;
-	fd = os_open_file(file, of_read(OPENFLAGS()), 0);
-	if(fd < 0){
-		if(fd != -ENOENT){
-			printk("not_dead_yet : couldn't open pid file '%s', "
-			       "err = %d\n", file, -fd);
-			return(1);
-		}
-		dead = 1;
-	}
-	if(fd > 0){
-		n = os_read_file(fd, pid, sizeof(pid));
-		if(n < 0){
-			printk("not_dead_yet : couldn't read pid file '%s', "
-			       "err = %d\n", file, -n);
-			return(1);
-		}
-		p = strtoul(pid, &end, 0);
-		if(end == pid){
-			printk("not_dead_yet : couldn't parse pid file '%s', "
-			       "errno = %d\n", file, errno);
-			dead = 1;
-		}
-		if(((kill(p, 0) < 0) && (errno == ESRCH)) ||
-		   (p == CHOOSE_MODE(tracing_pid, os_getpid())))
-			dead = 1;
-	}
-	if(!dead)
-		return(1);
-	return(actually_do_remove(dir));
-}
-
-static int __init set_uml_dir(char *name, int *add)
-{
-	if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
-		uml_dir = malloc(strlen(name) + 2);
-		if(uml_dir == NULL){
-			printf("Failed to malloc uml_dir - error = %d\n",
-			       errno);
-			uml_dir = name;
-			/* Return 0 here because do_initcalls doesn't look at
-			 * the return value.
-			 */
-			return(0);
-		}
-		sprintf(uml_dir, "%s/", name);
-	}
-	else uml_dir = name;
-	return(0);
-}
-
-static int __init make_uml_dir(void)
-{
-	char dir[MAXPATHLEN + 1] = { '\0' };
-	int len;
-
-	if(*uml_dir == '~'){
-		char *home = getenv("HOME");
-
-		if(home == NULL){
-			printf("make_uml_dir : no value in environment for "
-			       "$HOME\n");
-			exit(1);
-		}
-		strlcpy(dir, home, sizeof(dir));
-		uml_dir++;
-	}
-	strlcat(dir, uml_dir, sizeof(dir));
-	len = strlen(dir);
-	if (len > 0 && dir[len - 1] != '/')
-		strlcat(dir, "/", sizeof(dir));
-
-	uml_dir = malloc(strlen(dir) + 1);
-	if (uml_dir == NULL) {
-		printf("make_uml_dir : malloc failed, errno = %d\n", errno);
-		exit(1);
-	}
-	strcpy(uml_dir, dir);
-	
-	if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
-	        printf("Failed to mkdir %s: %s\n", uml_dir, strerror(errno));
-		return(-1);
-	}
-	return 0;
-}
-
-static int __init make_umid(int (*printer)(const char *fmt, ...))
-{
-	int fd, err;
-	char tmp[strlen(uml_dir) + UMID_LEN + 1];
-
-	strlcpy(tmp, uml_dir, sizeof(tmp));
-
-	if(!umid_inited){
-		strcat(tmp, "XXXXXX");
-		fd = mkstemp(tmp);
-		if(fd < 0){
-			(*printer)("make_umid - mkstemp(%s) failed: %s\n",
-				   tmp,strerror(errno));
-			return(1);
-		}
-
-		os_close_file(fd);
-		/* There's a nice tiny little race between this unlink and
-		 * the mkdir below.  It'd be nice if there were a mkstemp
-		 * for directories.
-		 */
-		unlink(tmp);
-		set_umid(&tmp[strlen(uml_dir)], 1, printer);
-	}
-	
-	sprintf(tmp, "%s%s", uml_dir, umid);
-
-	err = mkdir(tmp, 0777);
-	if(err < 0){
-		if(errno == EEXIST){
-			if(not_dead_yet(tmp)){
-				(*printer)("umid '%s' is in use\n", umid);
-				umid_owned = 0;
-				return(-1);
-			}
-			err = mkdir(tmp, 0777);
-		}
-	}
-	if(err < 0){
-		(*printer)("Failed to create %s - errno = %d\n", umid, errno);
-		return(-1);
-	}
-
-	umid_owned = 1;
-	return 0;
-}
-
-__uml_setup("uml_dir=", set_uml_dir,
-"uml_dir=<directory>\n"
-"    The location to place the pid and umid files.\n\n"
-);
-
-static int __init make_umid_setup(void)
-{
-	/* one function with the ordering we need ... */
-	make_uml_dir();
-	make_umid(printf);
-	create_pid_file();
-	return 0;
-}
-__uml_postsetup(make_umid_setup);
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index b83ac8e..40c7d6b 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -4,11 +4,13 @@
 #
 
 obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
-	start_up.o time.o tt.o tty.o uaccess.o user_syms.o drivers/ \
-	sys-$(SUBARCH)/
+	start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \
+	drivers/ sys-$(SUBARCH)/
+
+obj-$(CONFIG_MODE_SKAS) += skas/
 
 USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
-	start_up.o time.o tt.o tty.o uaccess.o
+	start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o
 
 elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
 CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index ffa759a..f897140 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -16,12 +16,12 @@
 #include "mode.h"
 
 struct aio_thread_req {
-        enum aio_type type;
-        int io_fd;
-        unsigned long long offset;
-        char *buf;
-        int len;
-        struct aio_context *aio;
+	enum aio_type type;
+	int io_fd;
+	unsigned long long offset;
+	char *buf;
+	int len;
+	struct aio_context *aio;
 };
 
 static int aio_req_fd_r = -1;
@@ -38,18 +38,18 @@
 
 static long io_setup(int n, aio_context_t *ctxp)
 {
-        return syscall(__NR_io_setup, n, ctxp);
+	return syscall(__NR_io_setup, n, ctxp);
 }
 
 static long io_submit(aio_context_t ctx, long nr, struct iocb **iocbpp)
 {
-        return syscall(__NR_io_submit, ctx, nr, iocbpp);
+	return syscall(__NR_io_submit, ctx, nr, iocbpp);
 }
 
 static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
-                         struct io_event *events, struct timespec *timeout)
+			 struct io_event *events, struct timespec *timeout)
 {
-        return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout);
+	return syscall(__NR_io_getevents, ctx_id, min_nr, nr, events, timeout);
 }
 
 #endif
@@ -66,243 +66,245 @@
  */
 
 static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf,
-                  int len, unsigned long long offset, struct aio_context *aio)
+		  int len, unsigned long long offset, struct aio_context *aio)
 {
-        struct iocb iocb, *iocbp = &iocb;
-        char c;
-        int err;
+	struct iocb iocb, *iocbp = &iocb;
+	char c;
+	int err;
 
-        iocb = ((struct iocb) { .aio_data 	= (unsigned long) aio,
-                                .aio_reqprio	= 0,
-                                .aio_fildes	= fd,
-                                .aio_buf	= (unsigned long) buf,
-                                .aio_nbytes	= len,
-                                .aio_offset	= offset,
-                                .aio_reserved1	= 0,
-                                .aio_reserved2	= 0,
-                                .aio_reserved3	= 0 });
+	iocb = ((struct iocb) { .aio_data 	= (unsigned long) aio,
+				.aio_reqprio	= 0,
+				.aio_fildes	= fd,
+				.aio_buf	= (unsigned long) buf,
+				.aio_nbytes	= len,
+				.aio_offset	= offset,
+				.aio_reserved1	= 0,
+				.aio_reserved2	= 0,
+				.aio_reserved3	= 0 });
 
-        switch(type){
-        case AIO_READ:
-                iocb.aio_lio_opcode = IOCB_CMD_PREAD;
-                err = io_submit(ctx, 1, &iocbp);
-                break;
-        case AIO_WRITE:
-                iocb.aio_lio_opcode = IOCB_CMD_PWRITE;
-                err = io_submit(ctx, 1, &iocbp);
-                break;
-        case AIO_MMAP:
-                iocb.aio_lio_opcode = IOCB_CMD_PREAD;
-                iocb.aio_buf = (unsigned long) &c;
-                iocb.aio_nbytes = sizeof(c);
-                err = io_submit(ctx, 1, &iocbp);
-                break;
-        default:
-                printk("Bogus op in do_aio - %d\n", type);
-                err = -EINVAL;
-                break;
-        }
+	switch(type){
+	case AIO_READ:
+		iocb.aio_lio_opcode = IOCB_CMD_PREAD;
+		err = io_submit(ctx, 1, &iocbp);
+		break;
+	case AIO_WRITE:
+		iocb.aio_lio_opcode = IOCB_CMD_PWRITE;
+		err = io_submit(ctx, 1, &iocbp);
+		break;
+	case AIO_MMAP:
+		iocb.aio_lio_opcode = IOCB_CMD_PREAD;
+		iocb.aio_buf = (unsigned long) &c;
+		iocb.aio_nbytes = sizeof(c);
+		err = io_submit(ctx, 1, &iocbp);
+		break;
+	default:
+		printk("Bogus op in do_aio - %d\n", type);
+		err = -EINVAL;
+		break;
+	}
 
-        if(err > 0)
-                err = 0;
+	if(err > 0)
+		err = 0;
 	else
 		err = -errno;
 
-        return err;
+	return err;
 }
 
 static aio_context_t ctx = 0;
 
 static int aio_thread(void *arg)
 {
-        struct aio_thread_reply reply;
-        struct io_event event;
-        int err, n, reply_fd;
+	struct aio_thread_reply reply;
+	struct io_event event;
+	int err, n, reply_fd;
 
-        signal(SIGWINCH, SIG_IGN);
+	signal(SIGWINCH, SIG_IGN);
 
-        while(1){
-                n = io_getevents(ctx, 1, 1, &event, NULL);
-                if(n < 0){
-                        if(errno == EINTR)
-                                continue;
-                        printk("aio_thread - io_getevents failed, "
-                               "errno = %d\n", errno);
-                }
-                else {
-                        reply = ((struct aio_thread_reply)
-				 { .data = (void *) (long) event.data,
-				   .err	= event.res });
+	while(1){
+		n = io_getevents(ctx, 1, 1, &event, NULL);
+		if(n < 0){
+			if(errno == EINTR)
+				continue;
+			printk("aio_thread - io_getevents failed, "
+			       "errno = %d\n", errno);
+		}
+		else {
+			reply = ((struct aio_thread_reply)
+				{ .data = (void *) (long) event.data,
+						.err	= event.res });
 			reply_fd = ((struct aio_context *) reply.data)->reply_fd;
 			err = os_write_file(reply_fd, &reply, sizeof(reply));
-                        if(err != sizeof(reply))
+			if(err != sizeof(reply))
 				printk("aio_thread - write failed, fd = %d, "
-                                       "err = %d\n", aio_req_fd_r, -err);
-                }
-        }
-        return 0;
+				       "err = %d\n", aio_req_fd_r, -err);
+		}
+	}
+	return 0;
 }
 
 #endif
 
 static int do_not_aio(struct aio_thread_req *req)
 {
-        char c;
-        int err;
+	char c;
+	int err;
 
-        switch(req->type){
-        case AIO_READ:
-                err = os_seek_file(req->io_fd, req->offset);
-                if(err)
-                        goto out;
+	switch(req->type){
+	case AIO_READ:
+		err = os_seek_file(req->io_fd, req->offset);
+		if(err)
+			goto out;
 
-                err = os_read_file(req->io_fd, req->buf, req->len);
-                break;
-        case AIO_WRITE:
-                err = os_seek_file(req->io_fd, req->offset);
-                if(err)
-                        goto out;
+		err = os_read_file(req->io_fd, req->buf, req->len);
+		break;
+	case AIO_WRITE:
+		err = os_seek_file(req->io_fd, req->offset);
+		if(err)
+			goto out;
 
-                err = os_write_file(req->io_fd, req->buf, req->len);
-                break;
-        case AIO_MMAP:
-                err = os_seek_file(req->io_fd, req->offset);
-                if(err)
-                        goto out;
+		err = os_write_file(req->io_fd, req->buf, req->len);
+		break;
+	case AIO_MMAP:
+		err = os_seek_file(req->io_fd, req->offset);
+		if(err)
+			goto out;
 
-                err = os_read_file(req->io_fd, &c, sizeof(c));
-                break;
-        default:
-                printk("do_not_aio - bad request type : %d\n", req->type);
-                err = -EINVAL;
-                break;
-        }
+		err = os_read_file(req->io_fd, &c, sizeof(c));
+		break;
+	default:
+		printk("do_not_aio - bad request type : %d\n", req->type);
+		err = -EINVAL;
+		break;
+	}
 
- out:
-        return err;
+out:
+	return err;
 }
 
 static int not_aio_thread(void *arg)
 {
-        struct aio_thread_req req;
-        struct aio_thread_reply reply;
-        int err;
+	struct aio_thread_req req;
+	struct aio_thread_reply reply;
+	int err;
 
-        signal(SIGWINCH, SIG_IGN);
-        while(1){
-                err = os_read_file(aio_req_fd_r, &req, sizeof(req));
-                if(err != sizeof(req)){
-                        if(err < 0)
-                                printk("not_aio_thread - read failed, "
-                                       "fd = %d, err = %d\n", aio_req_fd_r,
-                                       -err);
-                        else {
-                                printk("not_aio_thread - short read, fd = %d, "
-                                       "length = %d\n", aio_req_fd_r, err);
-                        }
-                        continue;
-                }
-                err = do_not_aio(&req);
-                reply = ((struct aio_thread_reply) { .data 	= req.aio,
-                                                     .err	= err });
-                err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
-                if(err != sizeof(reply))
-                        printk("not_aio_thread - write failed, fd = %d, "
-                               "err = %d\n", aio_req_fd_r, -err);
-        }
+	signal(SIGWINCH, SIG_IGN);
+	while(1){
+		err = os_read_file(aio_req_fd_r, &req, sizeof(req));
+		if(err != sizeof(req)){
+			if(err < 0)
+				printk("not_aio_thread - read failed, "
+				       "fd = %d, err = %d\n", aio_req_fd_r,
+				       -err);
+			else {
+				printk("not_aio_thread - short read, fd = %d, "
+				       "length = %d\n", aio_req_fd_r, err);
+			}
+			continue;
+		}
+		err = do_not_aio(&req);
+		reply = ((struct aio_thread_reply) { .data 	= req.aio,
+					 .err	= err });
+		err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
+		if(err != sizeof(reply))
+			printk("not_aio_thread - write failed, fd = %d, "
+			       "err = %d\n", aio_req_fd_r, -err);
+	}
+
+	return 0;
 }
 
 static int aio_pid = -1;
 
 static int init_aio_24(void)
 {
-        unsigned long stack;
-        int fds[2], err;
+	unsigned long stack;
+	int fds[2], err;
 
-        err = os_pipe(fds, 1, 1);
-        if(err)
-                goto out;
+	err = os_pipe(fds, 1, 1);
+	if(err)
+		goto out;
 
-        aio_req_fd_w = fds[0];
-        aio_req_fd_r = fds[1];
-        err = run_helper_thread(not_aio_thread, NULL,
-                                CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
-        if(err < 0)
-                goto out_close_pipe;
+	aio_req_fd_w = fds[0];
+	aio_req_fd_r = fds[1];
+	err = run_helper_thread(not_aio_thread, NULL,
+				CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
+	if(err < 0)
+		goto out_close_pipe;
 
-        aio_pid = err;
-        goto out;
+	aio_pid = err;
+	goto out;
 
- out_close_pipe:
-        os_close_file(fds[0]);
-        os_close_file(fds[1]);
-        aio_req_fd_w = -1;
-        aio_req_fd_r = -1;
- out:
+out_close_pipe:
+	os_close_file(fds[0]);
+	os_close_file(fds[1]);
+	aio_req_fd_w = -1;
+	aio_req_fd_r = -1;
+out:
 #ifndef HAVE_AIO_ABI
 	printk("/usr/include/linux/aio_abi.h not present during build\n");
 #endif
 	printk("2.6 host AIO support not used - falling back to I/O "
 	       "thread\n");
-        return 0;
+	return 0;
 }
 
 #ifdef HAVE_AIO_ABI
 #define DEFAULT_24_AIO 0
 static int init_aio_26(void)
 {
-        unsigned long stack;
-        int err;
+	unsigned long stack;
+	int err;
 
-        if(io_setup(256, &ctx)){
+	if(io_setup(256, &ctx)){
 		err = -errno;
-                printk("aio_thread failed to initialize context, err = %d\n",
-                       errno);
-                return err;
-        }
+		printk("aio_thread failed to initialize context, err = %d\n",
+		       errno);
+		return err;
+	}
 
-        err = run_helper_thread(aio_thread, NULL,
-                                CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
-        if(err < 0)
-                return err;
+	err = run_helper_thread(aio_thread, NULL,
+				CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
+	if(err < 0)
+		return err;
 
-        aio_pid = err;
+	aio_pid = err;
 
 	printk("Using 2.6 host AIO\n");
-        return 0;
+	return 0;
 }
 
 static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
 			 unsigned long long offset, struct aio_context *aio)
 {
-        struct aio_thread_reply reply;
-        int err;
+	struct aio_thread_reply reply;
+	int err;
 
-        err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
-        if(err){
-                reply = ((struct aio_thread_reply) { .data = aio,
-                                                     .err  = err });
-                err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
-                if(err != sizeof(reply))
-                        printk("submit_aio_26 - write failed, "
-                               "fd = %d, err = %d\n", aio->reply_fd, -err);
-                else err = 0;
-        }
+	err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
+	if(err){
+		reply = ((struct aio_thread_reply) { .data = aio,
+					 .err  = err });
+		err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
+		if(err != sizeof(reply))
+			printk("submit_aio_26 - write failed, "
+			       "fd = %d, err = %d\n", aio->reply_fd, -err);
+		else err = 0;
+	}
 
-        return err;
+	return err;
 }
 
 #else
 #define DEFAULT_24_AIO 1
 static int init_aio_26(void)
 {
-        return -ENOSYS;
+	return -ENOSYS;
 }
 
 static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
 			 unsigned long long offset, struct aio_context *aio)
 {
-        return -ENOSYS;
+	return -ENOSYS;
 }
 #endif
 
@@ -310,8 +312,8 @@
 
 static int __init set_aio_24(char *name, int *add)
 {
-        aio_24 = 1;
-        return 0;
+	aio_24 = 1;
+	return 0;
 }
 
 __uml_setup("aio=2.4", set_aio_24,
@@ -328,28 +330,27 @@
 
 static int init_aio(void)
 {
-        int err;
+	int err;
 
-        CHOOSE_MODE(({
-                if(!aio_24){
-                        printk("Disabling 2.6 AIO in tt mode\n");
-                        aio_24 = 1;
-                } }), (void) 0);
+	CHOOSE_MODE(({ if(!aio_24){
+			    printk("Disabling 2.6 AIO in tt mode\n");
+			    aio_24 = 1;
+		    } }), (void) 0);
 
-        if(!aio_24){
-                err = init_aio_26();
-                if(err && (errno == ENOSYS)){
-                        printk("2.6 AIO not supported on the host - "
-                               "reverting to 2.4 AIO\n");
-                        aio_24 = 1;
-                }
-                else return err;
-        }
+	if(!aio_24){
+		err = init_aio_26();
+		if(err && (errno == ENOSYS)){
+			printk("2.6 AIO not supported on the host - "
+			       "reverting to 2.4 AIO\n");
+			aio_24 = 1;
+		}
+		else return err;
+	}
 
-        if(aio_24)
-                return init_aio_24();
+	if(aio_24)
+		return init_aio_24();
 
-        return 0;
+	return 0;
 }
 
 /* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
@@ -362,8 +363,8 @@
 
 static void exit_aio(void)
 {
-        if(aio_pid != -1)
-                os_kill_process(aio_pid, 1);
+	if(aio_pid != -1)
+		os_kill_process(aio_pid, 1);
 }
 
 __uml_exitcall(exit_aio);
@@ -371,30 +372,30 @@
 static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
 			 unsigned long long offset, struct aio_context *aio)
 {
-        struct aio_thread_req req = { .type 		= type,
-                                      .io_fd		= io_fd,
-                                      .offset		= offset,
-                                      .buf		= buf,
-                                      .len		= len,
-                                      .aio		= aio,
-        };
-        int err;
+	struct aio_thread_req req = { .type 		= type,
+				      .io_fd		= io_fd,
+				      .offset		= offset,
+				      .buf		= buf,
+				      .len		= len,
+				      .aio		= aio,
+	};
+	int err;
 
-        err = os_write_file(aio_req_fd_w, &req, sizeof(req));
-        if(err == sizeof(req))
-                err = 0;
+	err = os_write_file(aio_req_fd_w, &req, sizeof(req));
+	if(err == sizeof(req))
+		err = 0;
 
-        return err;
+	return err;
 }
 
 int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
-               unsigned long long offset, int reply_fd,
-               struct aio_context *aio)
+	       unsigned long long offset, int reply_fd,
+	       struct aio_context *aio)
 {
-        aio->reply_fd = reply_fd;
-        if(aio_24)
-                return submit_aio_24(type, io_fd, buf, len, offset, aio);
-        else {
-                return submit_aio_26(type, io_fd, buf, len, offset, aio);
-        }
+	aio->reply_fd = reply_fd;
+	if(aio_24)
+		return submit_aio_24(type, io_fd, buf, len, offset, aio);
+	else {
+		return submit_aio_26(type, io_fd, buf, len, offset, aio);
+	}
 }
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 23da27d..172c847 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -16,7 +16,6 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "mem_user.h"
-#include "signal_user.h"
 #include "time_user.h"
 #include "irq_user.h"
 #include "user.h"
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index d9c5238..39815c6 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -15,7 +15,6 @@
 #include "os.h"
 #include "user.h"
 #include "user_util.h"
-#include "signal_user.h"
 #include "process.h"
 #include "irq_user.h"
 #include "kern_util.h"
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index c7bfd5e..c1f46a0f 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -4,9 +4,22 @@
  */
 
 #include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <string.h>
+#include <sys/mman.h>
+#include "user_util.h"
+#include "kern_util.h"
+#include "user.h"
+#include "signal_kern.h"
+#include "sysdep/sigcontext.h"
+#include "sysdep/signal.h"
+#include "sigcontext.h"
 #include "time_user.h"
 #include "mode.h"
-#include "sysdep/signal.h"
 
 void sig_handler(ARCH_SIGHDLR_PARAM)
 {
@@ -36,13 +49,138 @@
 		switch_timers(1);
 }
 
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
+void set_sigstack(void *sig_stack, int size)
+{
+	stack_t stack = ((stack_t) { .ss_flags	= 0,
+				     .ss_sp	= (__ptr_t) sig_stack,
+				     .ss_size 	= size - sizeof(void *) });
+
+	if(sigaltstack(&stack, NULL) != 0)
+		panic("enabling signal stack failed, errno = %d\n", errno);
+}
+
+void remove_sigstack(void)
+{
+	stack_t stack = ((stack_t) { .ss_flags	= SS_DISABLE,
+				     .ss_sp	= NULL,
+				     .ss_size	= 0 });
+
+	if(sigaltstack(&stack, NULL) != 0)
+		panic("disabling signal stack failed, errno = %d\n", errno);
+}
+
+void set_handler(int sig, void (*handler)(int), int flags, ...)
+{
+	struct sigaction action;
+	va_list ap;
+	int mask;
+
+	va_start(ap, flags);
+	action.sa_handler = handler;
+	sigemptyset(&action.sa_mask);
+	while((mask = va_arg(ap, int)) != -1){
+		sigaddset(&action.sa_mask, mask);
+	}
+	va_end(ap);
+	action.sa_flags = flags;
+	action.sa_restorer = NULL;
+	if(sigaction(sig, &action, NULL) < 0)
+		panic("sigaction failed");
+}
+
+int change_sig(int signal, int on)
+{
+	sigset_t sigset, old;
+
+	sigemptyset(&sigset);
+	sigaddset(&sigset, signal);
+	sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
+	return(!sigismember(&old, signal));
+}
+
+/* Both here and in set/get_signal we don't touch SIGPROF, because we must not
+ * disable profiling; it's safe because the profiling code does not interact
+ * with the kernel code at all.*/
+
+static void change_signals(int type)
+{
+	sigset_t mask;
+
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGVTALRM);
+	sigaddset(&mask, SIGALRM);
+	sigaddset(&mask, SIGIO);
+	if(sigprocmask(type, &mask, NULL) < 0)
+		panic("Failed to change signal mask - errno = %d", errno);
+}
+
+void block_signals(void)
+{
+	change_signals(SIG_BLOCK);
+}
+
+void unblock_signals(void)
+{
+	change_signals(SIG_UNBLOCK);
+}
+
+/* These are the asynchronous signals.  SIGVTALRM and SIGARLM are handled
+ * together under SIGVTALRM_BIT.  SIGPROF is excluded because we want to
+ * be able to profile all of UML, not just the non-critical sections.  If
+ * profiling is not thread-safe, then that is not my problem.  We can disable
+ * profiling when SMP is enabled in that case.
  */
+#define SIGIO_BIT 0
+#define SIGVTALRM_BIT 1
+
+static int enable_mask(sigset_t *mask)
+{
+	int sigs;
+
+	sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT;
+	sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT;
+	sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT;
+	return(sigs);
+}
+
+int get_signals(void)
+{
+	sigset_t mask;
+
+	if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0)
+		panic("Failed to get signal mask");
+	return(enable_mask(&mask));
+}
+
+int set_signals(int enable)
+{
+	sigset_t mask;
+	int ret;
+
+	sigemptyset(&mask);
+	if(enable & (1 << SIGIO_BIT))
+		sigaddset(&mask, SIGIO);
+	if(enable & (1 << SIGVTALRM_BIT)){
+		sigaddset(&mask, SIGVTALRM);
+		sigaddset(&mask, SIGALRM);
+	}
+
+	/* This is safe - sigprocmask is guaranteed to copy locally the
+	 * value of new_set, do his work and then, at the end, write to
+	 * old_set.
+	 */
+	if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
+		panic("Failed to enable signals");
+	ret = enable_mask(&mask);
+	sigemptyset(&mask);
+	if((enable & (1 << SIGIO_BIT)) == 0)
+		sigaddset(&mask, SIGIO);
+	if((enable & (1 << SIGVTALRM_BIT)) == 0){
+		sigaddset(&mask, SIGVTALRM);
+		sigaddset(&mask, SIGALRM);
+	}
+	if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0)
+		panic("Failed to block signals");
+
+	return(ret);
+}
diff --git a/arch/um/os-Linux/skas/Makefile b/arch/um/os-Linux/skas/Makefile
new file mode 100644
index 0000000..eab5386
--- /dev/null
+++ b/arch/um/os-Linux/skas/Makefile
@@ -0,0 +1,10 @@
+#
+# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
+# Licensed under the GPL
+#
+
+obj-y := trap.o
+
+USER_OBJS := trap.o
+
+include arch/um/scripts/Makefile.rules
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
new file mode 100644
index 0000000..9ad5fbec
--- /dev/null
+++ b/arch/um/os-Linux/skas/trap.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#include <signal.h>
+#include <errno.h>
+#include "user_util.h"
+#include "kern_util.h"
+#include "task.h"
+#include "sigcontext.h"
+#include "skas.h"
+#include "ptrace_user.h"
+#include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
+#include "os.h"
+
+void sig_handler_common_skas(int sig, void *sc_ptr)
+{
+	struct sigcontext *sc = sc_ptr;
+	struct skas_regs *r;
+	void (*handler)(int, union uml_pt_regs *);
+	int save_errno = errno;
+	int save_user;
+
+	/* This is done because to allow SIGSEGV to be delivered inside a SEGV
+	 * handler.  This can happen in copy_user, and if SEGV is disabled,
+	 * the process will die.
+	 * XXX Figure out why this is better than SA_NODEFER
+	 */
+	if(sig == SIGSEGV)
+		change_sig(SIGSEGV, 1);
+
+	r = &TASK_REGS(get_current())->skas;
+	save_user = r->is_user;
+	r->is_user = 0;
+	if ( sig == SIGFPE || sig == SIGSEGV ||
+	     sig == SIGBUS || sig == SIGILL ||
+	     sig == SIGTRAP ) {
+		GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
+	}
+
+	change_sig(SIGUSR1, 1);
+
+	handler = sig_info[sig];
+
+	/* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
+	if (sig != SIGIO && sig != SIGWINCH &&
+	    sig != SIGVTALRM && sig != SIGALRM)
+		unblock_signals();
+
+	handler(sig, (union uml_pt_regs *) r);
+
+	errno = save_errno;
+	r->is_user = save_user;
+}
+
+extern int ptrace_faultinfo;
+
+void user_signal(int sig, union uml_pt_regs *regs, int pid)
+{
+	void (*handler)(int, union uml_pt_regs *);
+	int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
+		    (sig == SIGILL) || (sig == SIGTRAP));
+
+	if (segv)
+		get_skas_faultinfo(pid, &regs->skas.faultinfo);
+
+	handler = sig_info[sig];
+	handler(sig, (union uml_pt_regs *) regs);
+
+	unblock_signals();
+}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 37517d4..b47e5e7 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -24,7 +24,6 @@
 #include "kern_util.h"
 #include "user.h"
 #include "signal_kern.h"
-#include "signal_user.h"
 #include "sysdep/ptrace.h"
 #include "sysdep/sigcontext.h"
 #include "irq_user.h"
@@ -116,16 +115,16 @@
 	if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
 		int exit_with = WEXITSTATUS(status);
 		if (exit_with == 2)
-			printk("check_ptrace : child exited with status 2. "
+			printf("check_ptrace : child exited with status 2. "
 			       "Serious trouble happening! Try updating your "
 			       "host skas patch!\nDisabling SYSEMU support.");
-		printk("check_ptrace : child exited with exitcode %d, while "
+		printf("check_ptrace : child exited with exitcode %d, while "
 		      "expecting %d; status 0x%x", exit_with,
 		      exitcode, status);
 		if (mustpanic)
 			panic("\n");
 		else
-			printk("\n");
+			printf("\n");
 		ret = -1;
 	}
 
@@ -183,7 +182,7 @@
 	void *stack;
  	int pid, n, status, count=0;
 
-	printk("Checking syscall emulation patch for ptrace...");
+	printf("Checking syscall emulation patch for ptrace...");
 	sysemu_supported = 0;
 	pid = start_ptraced_child(&stack);
 
@@ -207,10 +206,10 @@
 		goto fail_stopped;
 
 	sysemu_supported = 1;
-	printk("OK\n");
+	printf("OK\n");
 	set_using_sysemu(!force_sysemu_disabled);
 
-	printk("Checking advanced syscall emulation patch for ptrace...");
+	printf("Checking advanced syscall emulation patch for ptrace...");
 	pid = start_ptraced_child(&stack);
 
 	if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
@@ -246,7 +245,7 @@
 		goto fail_stopped;
 
 	sysemu_supported = 2;
-	printk("OK\n");
+	printf("OK\n");
 
 	if ( !force_sysemu_disabled )
 		set_using_sysemu(sysemu_supported);
@@ -255,7 +254,7 @@
 fail:
 	stop_ptraced_child(pid, stack, 1, 0);
 fail_stopped:
-	printk("missing\n");
+	printf("missing\n");
 }
 
 static void __init check_ptrace(void)
@@ -263,7 +262,7 @@
 	void *stack;
 	int pid, syscall, n, status;
 
-	printk("Checking that ptrace can change system call numbers...");
+	printf("Checking that ptrace can change system call numbers...");
 	pid = start_ptraced_child(&stack);
 
 	if(ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
@@ -292,7 +291,7 @@
 		}
 	}
 	stop_ptraced_child(pid, stack, 0, 1);
-	printk("OK\n");
+	printf("OK\n");
 	check_sysemu();
 }
 
@@ -472,6 +471,8 @@
 
 int have_devanon = 0;
 
+/* Runs on boot kernel stack - already safe to use printk. */
+
 void check_devanon(void)
 {
 	int fd;
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
new file mode 100644
index 0000000..321e1c8
--- /dev/null
+++ b/arch/um/os-Linux/trap.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <stdlib.h>
+#include <signal.h>
+#include <setjmp.h>
+#include "kern_util.h"
+#include "user_util.h"
+#include "os.h"
+#include "mode.h"
+
+void usr2_handler(int sig, union uml_pt_regs *regs)
+{
+	CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
+}
+
+void (*sig_info[NSIG])(int, union uml_pt_regs *);
+
+void os_fill_handlinfo(struct kern_handlers h)
+{
+	sig_info[SIGTRAP] = h.relay_signal;
+	sig_info[SIGFPE] = h.relay_signal;
+	sig_info[SIGILL] = h.relay_signal;
+	sig_info[SIGWINCH] = h.winch;
+	sig_info[SIGBUS] = h.bus_handler;
+	sig_info[SIGSEGV] = h.page_fault;
+	sig_info[SIGIO] = h.sigio_handler;
+	sig_info[SIGVTALRM] = h.timer_handler;
+	sig_info[SIGALRM] = h.timer_handler;
+	sig_info[SIGUSR2] = usr2_handler;
+}
+
+void do_longjmp(void *b, int val)
+{
+	sigjmp_buf *buf = b;
+
+	siglongjmp(*buf, val);
+}
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index a6db887..cb2648b 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -23,7 +23,6 @@
 #include "kern_util.h"
 #include "user.h"
 #include "signal_kern.h"
-#include "signal_user.h"
 #include "sysdep/ptrace.h"
 #include "sysdep/sigcontext.h"
 #include "irq_user.h"
@@ -50,6 +49,20 @@
 	return(0);
 }
 
+void kill_child_dead(int pid)
+{
+	kill(pid, SIGKILL);
+	kill(pid, SIGCONT);
+	do {
+		int n;
+		CATCH_EINTR(n = waitpid(pid, NULL, 0));
+		if (n > 0)
+			kill(pid, SIGCONT);
+		else
+			break;
+	} while(1);
+}
+
 /*
  *-------------------------
  * only for tt mode (will be deleted in future...)
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
new file mode 100644
index 0000000..ecf107a
--- /dev/null
+++ b/arch/um/os-Linux/umid.c
@@ -0,0 +1,335 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <dirent.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include "init.h"
+#include "os.h"
+#include "user.h"
+#include "mode.h"
+
+#define UML_DIR "~/.uml/"
+
+#define UMID_LEN 64
+
+/* Changed by set_umid, which is run early in boot */
+char umid[UMID_LEN] = { 0 };
+
+/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */
+static char *uml_dir = UML_DIR;
+
+static int __init make_uml_dir(void)
+{
+	char dir[512] = { '\0' };
+	int len, err;
+
+	if(*uml_dir == '~'){
+		char *home = getenv("HOME");
+
+		err = -ENOENT;
+		if(home == NULL){
+			printk("make_uml_dir : no value in environment for "
+			       "$HOME\n");
+			goto err;
+		}
+		strlcpy(dir, home, sizeof(dir));
+		uml_dir++;
+	}
+	strlcat(dir, uml_dir, sizeof(dir));
+	len = strlen(dir);
+	if (len > 0 && dir[len - 1] != '/')
+		strlcat(dir, "/", sizeof(dir));
+
+	err = -ENOMEM;
+	uml_dir = malloc(strlen(dir) + 1);
+	if (uml_dir == NULL) {
+		printf("make_uml_dir : malloc failed, errno = %d\n", errno);
+		goto err;
+	}
+	strcpy(uml_dir, dir);
+
+	if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
+	        printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
+		err = -errno;
+		goto err_free;
+	}
+	return 0;
+
+err_free:
+	free(uml_dir);
+err:
+	uml_dir = NULL;
+	return err;
+}
+
+static int actually_do_remove(char *dir)
+{
+	DIR *directory;
+	struct dirent *ent;
+	int len;
+	char file[256];
+
+	directory = opendir(dir);
+	if(directory == NULL)
+		return -errno;
+
+	while((ent = readdir(directory)) != NULL){
+		if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
+			continue;
+		len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1;
+		if(len > sizeof(file))
+			return -E2BIG;
+
+		sprintf(file, "%s/%s", dir, ent->d_name);
+		if(unlink(file) < 0)
+			return -errno;
+	}
+	if(rmdir(dir) < 0)
+		return -errno;
+
+	return 0;
+}
+
+/* This says that there isn't already a user of the specified directory even if
+ * there are errors during the checking.  This is because if these errors
+ * happen, the directory is unusable by the pre-existing UML, so we might as
+ * well take it over.  This could happen either by
+ * 	the existing UML somehow corrupting its umid directory
+ * 	something other than UML sticking stuff in the directory
+ *	this boot racing with a shutdown of the other UML
+ * In any of these cases, the directory isn't useful for anything else.
+ */
+
+static int not_dead_yet(char *dir)
+{
+	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
+	char pid[sizeof("nnnnn\0")], *end;
+	int dead, fd, p, n, err;
+
+	n = snprintf(file, sizeof(file), "%s/pid", dir);
+	if(n >= sizeof(file)){
+		printk("not_dead_yet - pid filename too long\n");
+		err = -E2BIG;
+		goto out;
+	}
+
+	dead = 0;
+	fd = open(file, O_RDONLY);
+	if(fd < 0){
+		if(fd != -ENOENT){
+			printk("not_dead_yet : couldn't open pid file '%s', "
+			       "err = %d\n", file, -fd);
+		}
+		goto out;
+	}
+
+	err = 0;
+	n = read(fd, pid, sizeof(pid));
+	if(n <= 0){
+		printk("not_dead_yet : couldn't read pid file '%s', "
+		       "err = %d\n", file, -n);
+		goto out_close;
+	}
+
+	p = strtoul(pid, &end, 0);
+	if(end == pid){
+		printk("not_dead_yet : couldn't parse pid file '%s', "
+		       "errno = %d\n", file, errno);
+		goto out_close;
+	}
+
+	if((kill(p, 0) == 0) || (errno != ESRCH))
+		return 1;
+
+	err = actually_do_remove(dir);
+	if(err)
+		printk("not_dead_yet - actually_do_remove failed with "
+		       "err = %d\n", err);
+
+	return err;
+
+ out_close:
+	close(fd);
+ out:
+	return 0;
+}
+
+static void __init create_pid_file(void)
+{
+	char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
+	char pid[sizeof("nnnnn\0")];
+	int fd, n;
+
+	if(umid_file_name("pid", file, sizeof(file)))
+		return;
+
+	fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
+	if(fd < 0){
+		printk("Open of machine pid file \"%s\" failed: %s\n",
+		       file, strerror(-fd));
+		return;
+	}
+
+	snprintf(pid, sizeof(pid), "%d\n", getpid());
+	n = write(fd, pid, strlen(pid));
+	if(n != strlen(pid))
+		printk("Write of pid file failed - err = %d\n", -n);
+
+	close(fd);
+}
+
+int __init set_umid(char *name)
+{
+	if(strlen(name) > UMID_LEN - 1)
+		return -E2BIG;
+
+	strlcpy(umid, name, sizeof(umid));
+
+	return 0;
+}
+
+static int umid_setup = 0;
+
+int __init make_umid(void)
+{
+	int fd, err;
+	char tmp[256];
+
+	if(umid_setup)
+		return 0;
+
+	make_uml_dir();
+
+	if(*umid == '\0'){
+		strlcpy(tmp, uml_dir, sizeof(tmp));
+		strlcat(tmp, "XXXXXX", sizeof(tmp));
+		fd = mkstemp(tmp);
+		if(fd < 0){
+			printk("make_umid - mkstemp(%s) failed: %s\n",
+			       tmp, strerror(errno));
+			err = -errno;
+			goto err;
+		}
+
+		close(fd);
+
+		set_umid(&tmp[strlen(uml_dir)]);
+
+		/* There's a nice tiny little race between this unlink and
+		 * the mkdir below.  It'd be nice if there were a mkstemp
+		 * for directories.
+		 */
+		if(unlink(tmp)){
+			err = -errno;
+			goto err;
+		}
+	}
+
+	snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid);
+	err = mkdir(tmp, 0777);
+	if(err < 0){
+		err = -errno;
+		if(errno != EEXIST)
+			goto err;
+
+		if(not_dead_yet(tmp) < 0)
+			goto err;
+
+		err = mkdir(tmp, 0777);
+	}
+	if(err < 0){
+		printk("Failed to create '%s' - err = %d\n", umid, err);
+		goto err_rmdir;
+	}
+
+	umid_setup = 1;
+
+	create_pid_file();
+
+	return 0;
+
+ err_rmdir:
+	rmdir(tmp);
+ err:
+	return err;
+}
+
+static int __init make_umid_init(void)
+{
+	make_umid();
+
+	return 0;
+}
+
+__initcall(make_umid_init);
+
+int __init umid_file_name(char *name, char *buf, int len)
+{
+	int n, err;
+
+	err = make_umid();
+	if(err)
+		return err;
+
+	n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name);
+	if(n >= len){
+		printk("umid_file_name : buffer too short\n");
+		return -E2BIG;
+	}
+
+	return 0;
+}
+
+char *get_umid(void)
+{
+	return umid;
+}
+
+static int __init set_uml_dir(char *name, int *add)
+{
+	if(*name == '\0'){
+		printf("uml_dir can't be an empty string\n");
+		return 0;
+	}
+
+	if(name[strlen(name) - 1] == '/'){
+		uml_dir = name;
+		return 0;
+	}
+
+	uml_dir = malloc(strlen(name) + 2);
+	if(uml_dir == NULL){
+		printf("Failed to malloc uml_dir - error = %d\n", errno);
+
+		/* Return 0 here because do_initcalls doesn't look at
+		 * the return value.
+		 */
+		return 0;
+	}
+	sprintf(uml_dir, "%s/", name);
+
+	return 0;
+}
+
+__uml_setup("uml_dir=", set_uml_dir,
+"uml_dir=<directory>\n"
+"    The location to place the pid and umid files.\n\n"
+);
+
+static void remove_umid_dir(void)
+{
+	char dir[strlen(uml_dir) + UMID_LEN + 1], err;
+
+	sprintf(dir, "%s%s", uml_dir, umid);
+	err = actually_do_remove(dir);
+	if(err)
+		printf("remove_umid_dir - actually_do_remove failed with "
+		       "err = %d\n", err);
+}
+
+__uml_exitcall(remove_umid_dir);
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
index 56d3f87..8da6ab3 100644
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -34,6 +34,11 @@
        int sym(void);                  \
        EXPORT_SYMBOL(sym);
 
+extern void readdir64(void) __attribute__((weak));
+EXPORT_SYMBOL(readdir64);
+extern void truncate64(void) __attribute__((weak));
+EXPORT_SYMBOL(truncate64);
+
 #ifdef SUBARCH_i386
 EXPORT_SYMBOL(vsyscall_ehdr);
 EXPORT_SYMBOL(vsyscall_end);
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index b3fbf12..2e41cab 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -21,11 +21,6 @@
 endef
 
 
-# The stubs and unmap.o can't try to call mcount or update basic block data
-define unprofile
-	$(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
-endef
-
 # cmd_make_link checks to see if the $(foo-dir) variable starts with a /.  If
 # so, it's considered to be a path relative to $(srcdir) rather than
 # $(srcdir)/arch/$(SUBARCH).  This is because x86_64 wants to get ldt.c from
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 150059d..f5fd5b0 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,6 +1,8 @@
-obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
-	ptrace_user.o semaphore.o signal.o sigcontext.o stub.o stub_segv.o \
-	syscalls.o sysrq.o sys_call_table.o
+obj-y := bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
+	ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o \
+	sys_call_table.o
+
+obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
 
 obj-$(CONFIG_HIGHMEM) += highmem.o
 obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 16bc1992..7cd1a82 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -10,7 +10,6 @@
 #include "asm/uaccess.h"
 #include "asm/unistd.h"
 #include "frame_kern.h"
-#include "signal_user.h"
 #include "sigcontext.h"
 #include "registers.h"
 #include "mode.h"
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 00b2025..a351091 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -6,8 +6,9 @@
 
 #XXX: why into lib-y?
 lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \
-	ptrace.o ptrace_user.o sigcontext.o signal.o stub.o \
-	stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o
+	ptrace.o ptrace_user.o sigcontext.o signal.o syscalls.o \
+	syscall_table.o sysrq.o thunk.o
+lib-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
 
 obj-y := ksyms.o
 obj-$(CONFIG_MODULES) += module.o um_module.o
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index 3108659..0449463 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -10,9 +10,6 @@
 config MMU
        	bool
 	default n
-config UID16
-	bool
-	default n
 config RWSEM_GENERIC_SPINLOCK
 	bool
 	default y
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 6ece645..4f3e925 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -542,11 +542,6 @@
 	depends on COMPAT && SYSVIPC
 	default y
 
-config UID16
-	bool
-	depends on IA32_EMULATION
-	default y
-
 endmenu
 
 source "net/Kconfig"
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug
index e2c6e64a..fcb06a5 100644
--- a/arch/x86_64/Kconfig.debug
+++ b/arch/x86_64/Kconfig.debug
@@ -9,6 +9,16 @@
 	  Fill __init and __initdata at the end of boot. This helps debugging
 	  illegal uses of __init and __initdata after initialization.
 
+config DEBUG_RODATA
+       bool "Write protect kernel read-only data structures"
+       depends on DEBUG_KERNEL
+       help
+	 Mark the kernel read-only data as write-protected in the pagetables,
+	 in order to catch accidental (and incorrect) writes to such const data.
+	 This option may have a slight performance impact because a portion
+	 of the kernel code won't be covered by a 2MB TLB anymore.
+	 If in doubt, say "N".
+
 config IOMMU_DEBUG
        depends on GART_IOMMU && DEBUG_KERNEL
        bool "Enable IOMMU debugging"
diff --git a/arch/x86_64/boot/.gitignore b/arch/x86_64/boot/.gitignore
new file mode 100644
index 0000000..495f20c
--- /dev/null
+++ b/arch/x86_64/boot/.gitignore
@@ -0,0 +1,3 @@
+bootsect
+bzImage
+setup
diff --git a/arch/x86_64/boot/compressed/misc.c b/arch/x86_64/boot/compressed/misc.c
index 0e10fd8..cf4b88c 100644
--- a/arch/x86_64/boot/compressed/misc.c
+++ b/arch/x86_64/boot/compressed/misc.c
@@ -9,7 +9,7 @@
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  */
 
-#include "miscsetup.h"
+#include <linux/screen_info.h>
 #include <asm/io.h>
 #include <asm/page.h>
 
diff --git a/arch/x86_64/boot/compressed/miscsetup.h b/arch/x86_64/boot/compressed/miscsetup.h
deleted file mode 100644
index bb16205..0000000
--- a/arch/x86_64/boot/compressed/miscsetup.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#define NULL 0
-//typedef unsigned int size_t; 
-
-
-struct screen_info {
-	unsigned char  orig_x;			/* 0x00 */
-	unsigned char  orig_y;			/* 0x01 */
-	unsigned short dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
-	unsigned short orig_video_page;		/* 0x04 */
-	unsigned char  orig_video_mode;		/* 0x06 */
-	unsigned char  orig_video_cols;		/* 0x07 */
-	unsigned short unused2;			/* 0x08 */
-	unsigned short orig_video_ega_bx;	/* 0x0a */
-	unsigned short unused3;			/* 0x0c */
-	unsigned char  orig_video_lines;	/* 0x0e */
-	unsigned char  orig_video_isVGA;	/* 0x0f */
-	unsigned short orig_video_points;	/* 0x10 */
-
-	/* VESA graphic mode -- linear frame buffer */
-	unsigned short lfb_width;		/* 0x12 */
-	unsigned short lfb_height;		/* 0x14 */
-	unsigned short lfb_depth;		/* 0x16 */
-	unsigned long  lfb_base;		/* 0x18 */
-	unsigned long  lfb_size;		/* 0x1c */
-	unsigned short dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
-	unsigned short lfb_linelength;		/* 0x24 */
-	unsigned char  red_size;		/* 0x26 */
-	unsigned char  red_pos;			/* 0x27 */
-	unsigned char  green_size;		/* 0x28 */
-	unsigned char  green_pos;		/* 0x29 */
-	unsigned char  blue_size;		/* 0x2a */
-	unsigned char  blue_pos;		/* 0x2b */
-	unsigned char  rsvd_size;		/* 0x2c */
-	unsigned char  rsvd_pos;		/* 0x2d */
-	unsigned short vesapm_seg;		/* 0x2e */
-	unsigned short vesapm_off;		/* 0x30 */
-	unsigned short pages;			/* 0x32 */
-						/* 0x34 -- 0x3f reserved for future expansion */
-};
diff --git a/arch/x86_64/boot/tools/.gitignore b/arch/x86_64/boot/tools/.gitignore
new file mode 100644
index 0000000..378eac2
--- /dev/null
+++ b/arch/x86_64/boot/tools/.gitignore
@@ -0,0 +1 @@
+build
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index 830feb2..2b760d0 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -217,8 +217,7 @@
 	if (!tsk_used_math(tsk))
 		return 0;
 	if (!regs)
-		regs = (struct pt_regs *)tsk->thread.rsp0;
-	--regs;
+		regs = ((struct pt_regs *)tsk->thread.rsp0) - 1;
 	if (tsk == current)
 		unlazy_fpu(tsk);
 	set_fs(KERNEL_DS); 
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index e0eb0c7..1f0ff5a 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -341,7 +341,7 @@
 	jmp  ia32_sysret	/* misbalances the return cache */
 	CFI_ENDPROC
 
-	.data
+	.section .rodata,"a"
 	.align 8
 	.globl ia32_sys_call_table
 ia32_sys_call_table:
@@ -643,6 +643,7 @@
 	.quad sys_inotify_init
 	.quad sys_inotify_add_watch
 	.quad sys_inotify_rm_watch
+	.quad sys_migrate_pages
 ia32_syscall_end:		
 	.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
 		.quad ni_syscall
diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c
index 2a925e2..5f4cdfa 100644
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -196,36 +196,6 @@
 
 #undef R32
 
-static struct task_struct *find_target(int request, int pid, int *err)
-{ 
-	struct task_struct *child;
-
-	*err = -EPERM; 
-	if (pid == 1)
-		return NULL; 
-
-	*err = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (child) { 
-		*err = -EPERM;
-		if (child->pid == 1) 
-			goto out;
-		*err = ptrace_check_attach(child, request == PTRACE_KILL); 
-		if (*err < 0) 
-			goto out;
-		return child; 
-	} 
- out:
-	if (child)
-	put_task_struct(child);
-	return NULL; 
-	
-} 
-
 asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
 {
 	struct task_struct *child;
@@ -254,9 +224,16 @@
 		break;
 	} 
 
-	child = find_target(request, pid, &ret);
-	if (!child)
-		return ret;
+	if (request == PTRACE_TRACEME)
+		return ptrace_traceme();
+
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child))
+		return PTR_ERR(child);
+
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out;
 
 	childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs)); 
 
@@ -373,6 +350,7 @@
 		break;
 	}
 
+ out:
 	put_task_struct(child);
 	return ret;
 }
diff --git a/arch/x86_64/kernel/init_task.c b/arch/x86_64/kernel/init_task.c
index e0ba5c1..ce31d90 100644
--- a/arch/x86_64/kernel/init_task.c
+++ b/arch/x86_64/kernel/init_task.c
@@ -44,6 +44,6 @@
  * section. Since TSS's are completely CPU-local, we want them
  * on exact cacheline boundaries, to eliminate cacheline ping-pong.
  */ 
-DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = INIT_TSS;
+DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
 
 #define ALIGN_TO_4K __attribute__((section(".data.init_task")))
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index dddeb67..afe11f4 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -329,7 +329,7 @@
 				 */
 				save_previous_kprobe(kcb);
 				set_current_kprobe(p, regs, kcb);
-				p->nmissed++;
+				kprobes_inc_nmissed_count(p);
 				prepare_singlestep(p, regs);
 				kcb->kprobe_status = KPROBE_REENTER;
 				return 1;
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 7519fc5..3060ed9 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -157,7 +157,7 @@
 DECLARE_PER_CPU(int, cpu_state);
 
 #include <asm/nmi.h>
-/* We don't actually take CPU down, just spin without interrupts. */
+/* We halt the CPU with physical CPU hotplug */
 static inline void play_dead(void)
 {
 	idle_task_exit();
@@ -166,8 +166,9 @@
 	/* Ack it */
 	__get_cpu_var(cpu_state) = CPU_DEAD;
 
+	local_irq_disable();
 	while (1)
-		safe_halt();
+		halt();
 }
 #else
 static inline void play_dead(void)
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 750e01d..64c4534 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -42,6 +42,7 @@
 #include <linux/edd.h>
 #include <linux/mmzone.h>
 #include <linux/kexec.h>
+#include <linux/cpufreq.h>
 
 #include <asm/mtrr.h>
 #include <asm/uaccess.h>
@@ -1256,8 +1257,11 @@
 		seq_printf(m, "stepping\t: unknown\n");
 	
 	if (cpu_has(c,X86_FEATURE_TSC)) {
+		unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
+		if (!freq)
+			freq = cpu_khz;
 		seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
-			     cpu_khz / 1000, (cpu_khz % 1000));
+			     freq / 1000, (freq % 1000));
 	}
 
 	/* Cache size */
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 683c33f..ecbd7b8 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -1181,7 +1181,7 @@
 	if (cpu == 0)
 		return -EBUSY;
 
-	disable_APIC_timer();
+	clear_local_APIC();
 
 	/*
 	 * HACK:
diff --git a/arch/x86_64/kernel/syscall.c b/arch/x86_64/kernel/syscall.c
index e263685..7c176b3 100644
--- a/arch/x86_64/kernel/syscall.c
+++ b/arch/x86_64/kernel/syscall.c
@@ -19,7 +19,7 @@
 
 extern void sys_ni_syscall(void);
 
-sys_call_ptr_t sys_call_table[__NR_syscall_max+1] __cacheline_aligned = { 
+const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
 	/* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ 
 	[0 ... __NR_syscall_max] = &sys_ni_syscall,
 #include <asm-x86_64/unistd.h>
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index fdaddc4..43c9fa0 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -59,7 +59,7 @@
 unsigned int cpu_khz;					/* TSC clocks / usec, not used here */
 static unsigned long hpet_period;			/* fsecs / HPET clock */
 unsigned long hpet_tick;				/* HPET clocks / interrupt */
-static int hpet_use_timer;
+static int hpet_use_timer;				/* Use counter of hpet for time keeping, otherwise PIT */
 unsigned long vxtime_hz = PIT_TICK_RATE;
 int report_lost_ticks;				/* command line option */
 unsigned long long monotonic_base;
@@ -908,12 +908,14 @@
 	if (!hpet_init())
                 vxtime_hz = (1000000000000000L + hpet_period / 2) /
 			hpet_period;
+	else
+		vxtime.hpet_address = 0;
 
 	if (hpet_use_timer) {
 		cpu_khz = hpet_calibrate_tsc();
 		timename = "HPET";
 #ifdef CONFIG_X86_PM_TIMER
-	} else if (pmtmr_ioport) {
+	} else if (pmtmr_ioport && !vxtime.hpet_address) {
 		vxtime_hz = PM_TIMER_FREQUENCY;
 		timename = "PM";
 		pit_init();
@@ -1073,8 +1075,6 @@
  */
 #include <linux/rtc.h>
 
-extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
 #define DEFAULT_RTC_INT_FREQ 	64
 #define RTC_NUM_INTS 		1
 
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 286f6a6..1faae5f 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -348,7 +348,7 @@
 	}
 
 	/* Compute holes */
-	w = 0;
+	w = start_pfn;
 	for (i = 0; i < MAX_NR_ZONES; i++) {
 		unsigned long s = w;
 		w += z[i];
@@ -498,6 +498,29 @@
 	printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10);
 }
 
+#ifdef CONFIG_DEBUG_RODATA
+
+extern char __start_rodata, __end_rodata;
+void mark_rodata_ro(void)
+{
+	unsigned long addr = (unsigned long)&__start_rodata;
+
+	for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE)
+		change_page_attr_addr(addr, 1, PAGE_KERNEL_RO);
+
+	printk ("Write protecting the kernel read-only data: %luk\n",
+			(&__end_rodata - &__start_rodata) >> 10);
+
+	/*
+	 * change_page_attr_addr() requires a global_flush_tlb() call after it.
+	 * We do this after the printk so that if something went wrong in the
+	 * change, the printk gets out at least to give a better debug hint
+	 * of who is the culprit.
+	 */
+	global_flush_tlb();
+}
+#endif
+
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index ecf7acb..ae20706 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -247,9 +247,15 @@
 	return __ioremap(phys_addr, size, _PAGE_PCD);
 }
 
+/**
+ * iounmap - Free a IO remapping
+ * @addr: virtual address from ioremap_*
+ *
+ * Caller must ensure there is only one unmapping for the same pointer.
+ */
 void iounmap(volatile void __iomem *addr)
 {
-	struct vm_struct *p;
+	struct vm_struct *p, *o;
 
 	if (addr <= high_memory) 
 		return; 
@@ -257,12 +263,31 @@
 		addr < phys_to_virt(ISA_END_ADDRESS))
 		return;
 
-	write_lock(&vmlist_lock);
-	p = __remove_vm_area((void *)((unsigned long)addr & PAGE_MASK));
-	if (!p)
+	addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr);
+	/* Use the vm area unlocked, assuming the caller
+	   ensures there isn't another iounmap for the same address
+	   in parallel. Reuse of the virtual address is prevented by
+	   leaving it in the global lists until we're done with it.
+	   cpa takes care of the direct mappings. */
+	read_lock(&vmlist_lock);
+	for (p = vmlist; p; p = p->next) {
+		if (p->addr == addr)
+			break;
+	}
+	read_unlock(&vmlist_lock);
+
+	if (!p) {
 		printk("iounmap: bad address %p\n", addr);
-	else if (p->flags >> 20)
+		dump_stack();
+		return;
+	}
+
+	/* Reset the direct mapping. Can block */
+	if (p->flags >> 20)
 		ioremap_change_attr(p->phys_addr, p->size, 0);
-	write_unlock(&vmlist_lock);
+
+	/* Finally remove it */
+	o = remove_vm_area((void *)addr);
+	BUG_ON(p != o || o == NULL);
 	kfree(p); 
 }
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index a828a01..15b67d2 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -53,6 +53,8 @@
 	int res = -1;
 	unsigned long addr, end;
 
+	if (shift >= 64)
+		return -1;
 	memset(memnodemap, 0xff, sizeof(memnodemap));
 	for (i = 0; i < numnodes; i++) {
 		addr = nodes[i].start;
@@ -65,7 +67,7 @@
 			if (memnodemap[addr >> shift] != 0xff)
 				return -1;
 			memnodemap[addr >> shift] = i;
-			addr += (1 << shift);
+                       addr += (1UL << shift);
 		} while (addr < end);
 		res = 1;
 	} 
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index b90e8fe..35f1f1a 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -128,6 +128,7 @@
 	pte_t *kpte; 
 	struct page *kpte_page;
 	unsigned kpte_flags;
+	pgprot_t ref_prot2;
 	kpte = lookup_address(address);
 	if (!kpte) return 0;
 	kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
@@ -140,10 +141,14 @@
  			 * split_large_page will take the reference for this change_page_attr
  			 * on the split page.
  			 */
-			struct page *split = split_large_page(address, prot, ref_prot); 
+
+			struct page *split;
+			ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE));
+
+			split = split_large_page(address, prot, ref_prot2);
 			if (!split)
 				return -ENOMEM;
-			set_pte(kpte,mk_pte(split, ref_prot));
+			set_pte(kpte,mk_pte(split, ref_prot2));
 			kpte_page = split;
 		}	
 		get_page(kpte_page);
diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile
index bb34e5e..a8f75a2 100644
--- a/arch/x86_64/pci/Makefile
+++ b/arch/x86_64/pci/Makefile
@@ -11,7 +11,7 @@
 obj-$(CONFIG_ACPI)	+= acpi.o
 obj-y			+= legacy.o irq.o common.o
 # mmconfig has a 64bit special
-obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o
+obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o
 
 obj-$(CONFIG_NUMA)	+= k8-bus.o
 
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c
index a0838c4..f16c0d5 100644
--- a/arch/x86_64/pci/mmconfig.c
+++ b/arch/x86_64/pci/mmconfig.c
@@ -8,18 +8,21 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/acpi.h>
+#include <linux/bitmap.h>
 #include "pci.h"
 
 #define MMCONFIG_APER_SIZE (256*1024*1024)
 
+static DECLARE_BITMAP(fallback_slots, 32);
+
 /* Static virtual mapping of the MMCONFIG aperture */
 struct mmcfg_virt {
 	struct acpi_table_mcfg_config *cfg;
-	char *virt;
+	char __iomem *virt;
 };
 static struct mmcfg_virt *pci_mmcfg_virt;
 
-static char *get_virt(unsigned int seg, int bus)
+static char __iomem *get_virt(unsigned int seg, unsigned bus)
 {
 	int cfg_num = -1;
 	struct acpi_table_mcfg_config *cfg;
@@ -27,10 +30,9 @@
 	while (1) {
 		++cfg_num;
 		if (cfg_num >= pci_mmcfg_config_num) {
-			/* something bad is going on, no cfg table is found. */
-			/* so we fall back to the old way we used to do this */
-			/* and just rely on the first entry to be correct. */
-			return pci_mmcfg_virt[0].virt;
+			/* Not found - fall back to type 1. This happens
+			   e.g. on the internal devices of a K8 northbridge. */
+			return NULL;
 		}
 		cfg = pci_mmcfg_virt[cfg_num].cfg;
 		if (cfg->pci_segment_group_number != seg)
@@ -41,20 +43,30 @@
 	}
 }
 
-static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
+static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
 {
-
-	return get_virt(seg, bus) + ((bus << 20) | (devfn << 12));
+	char __iomem *addr;
+	if (seg == 0 && bus == 0 && test_bit(PCI_SLOT(devfn), &fallback_slots))
+		return NULL;
+	addr = get_virt(seg, bus);
+	if (!addr)
+		return NULL;
+ 	return addr + ((bus << 20) | (devfn << 12));
 }
 
 static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
 			  unsigned int devfn, int reg, int len, u32 *value)
 {
-	char *addr = pci_dev_base(seg, bus, devfn);
+	char __iomem *addr;
 
+	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
 	if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095)))
 		return -EINVAL;
 
+	addr = pci_dev_base(seg, bus, devfn);
+	if (!addr)
+		return pci_conf1_read(seg,bus,devfn,reg,len,value);
+
 	switch (len) {
 	case 1:
 		*value = readb(addr + reg);
@@ -73,11 +85,16 @@
 static int pci_mmcfg_write(unsigned int seg, unsigned int bus,
 			   unsigned int devfn, int reg, int len, u32 value)
 {
-	char *addr = pci_dev_base(seg, bus, devfn);
+	char __iomem *addr;
 
+	/* Why do we have this when nobody checks it. How about a BUG()!? -AK */
 	if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095)))
 		return -EINVAL;
 
+	addr = pci_dev_base(seg, bus, devfn);
+	if (!addr)
+		return pci_conf1_write(seg,bus,devfn,reg,len,value);
+
 	switch (len) {
 	case 1:
 		writeb(value, addr + reg);
@@ -98,6 +115,30 @@
 	.write =	pci_mmcfg_write,
 };
 
+/* K8 systems have some devices (typically in the builtin northbridge)
+   that are only accessible using type1
+   Normally this can be expressed in the MCFG by not listing them
+   and assigning suitable _SEGs, but this isn't implemented in some BIOS.
+   Instead try to discover all devices on bus 0 that are unreachable using MM
+   and fallback for them.
+   We only do this for bus 0/seg 0 */
+static __init void unreachable_devices(void)
+{
+	int i;
+	for (i = 0; i < 32; i++) {
+		u32 val1;
+		char __iomem *addr;
+
+		pci_conf1_read(0, 0, PCI_DEVFN(i,0), 0, 4, &val1);
+		if (val1 == 0xffffffff)
+			continue;
+		addr = pci_dev_base(0, 0, PCI_DEVFN(i, 0));
+		if (addr == NULL|| readl(addr) != val1) {
+			set_bit(i, &fallback_slots);
+		}
+	}
+}
+
 static int __init pci_mmcfg_init(void)
 {
 	int i;
@@ -128,6 +169,8 @@
 		printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address);
 	}
 
+	unreachable_devices();
+
 	raw_pci_ops = &pci_mmcfg;
 	pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 
diff --git a/block/Kconfig b/block/Kconfig
index eb48edb..377f6dd 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -5,7 +5,7 @@
 #for instance.
 config LBD
 	bool "Support for Large Block Devices"
-	depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML
+	depends on X86 || (MIPS && 32BIT) || PPC32 || (S390 && !64BIT) || SUPERH || UML
 	help
 	  Say Y here if you want to attach large (bigger than 2TB) discs to
 	  your machine, or if you want to have a raid or loopback device
diff --git a/block/as-iosched.c b/block/as-iosched.c
index 43fa204..8da3cf6 100644
--- a/block/as-iosched.c
+++ b/block/as-iosched.c
@@ -182,6 +182,9 @@
 
 static kmem_cache_t *arq_pool;
 
+static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq);
+static void as_antic_stop(struct as_data *ad);
+
 /*
  * IO Context helper functions
  */
@@ -370,7 +373,7 @@
  * existing request against the same sector), which can happen when using
  * direct IO, then return the alias.
  */
-static struct as_rq *as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
+static struct as_rq *__as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
 {
 	struct rb_node **p = &ARQ_RB_ROOT(ad, arq)->rb_node;
 	struct rb_node *parent = NULL;
@@ -397,6 +400,16 @@
 	return NULL;
 }
 
+static void as_add_arq_rb(struct as_data *ad, struct as_rq *arq)
+{
+	struct as_rq *alias;
+
+	while ((unlikely(alias = __as_add_arq_rb(ad, arq)))) {
+		as_move_to_dispatch(ad, alias);
+		as_antic_stop(ad);
+	}
+}
+
 static inline void as_del_arq_rb(struct as_data *ad, struct as_rq *arq)
 {
 	if (!ON_RB(&arq->rb_node)) {
@@ -1133,23 +1146,6 @@
 	/*
 	 * take it off the sort and fifo list, add to dispatch queue
 	 */
-	while (!list_empty(&rq->queuelist)) {
-		struct request *__rq = list_entry_rq(rq->queuelist.next);
-		struct as_rq *__arq = RQ_DATA(__rq);
-
-		list_del(&__rq->queuelist);
-
-		elv_dispatch_add_tail(ad->q, __rq);
-
-		if (__arq->io_context && __arq->io_context->aic)
-			atomic_inc(&__arq->io_context->aic->nr_dispatched);
-
-		WARN_ON(__arq->state != AS_RQ_QUEUED);
-		__arq->state = AS_RQ_DISPATCHED;
-
-		ad->nr_dispatched++;
-	}
-
 	as_remove_queued_request(ad->q, rq);
 	WARN_ON(arq->state != AS_RQ_QUEUED);
 
@@ -1326,49 +1322,12 @@
 }
 
 /*
- * Add arq to a list behind alias
- */
-static inline void
-as_add_aliased_request(struct as_data *ad, struct as_rq *arq,
-				struct as_rq *alias)
-{
-	struct request  *req = arq->request;
-	struct list_head *insert = alias->request->queuelist.prev;
-
-	/*
-	 * Transfer list of aliases
-	 */
-	while (!list_empty(&req->queuelist)) {
-		struct request *__rq = list_entry_rq(req->queuelist.next);
-		struct as_rq *__arq = RQ_DATA(__rq);
-
-		list_move_tail(&__rq->queuelist, &alias->request->queuelist);
-
-		WARN_ON(__arq->state != AS_RQ_QUEUED);
-	}
-
-	/*
-	 * Another request with the same start sector on the rbtree.
-	 * Link this request to that sector. They are untangled in
-	 * as_move_to_dispatch
-	 */
-	list_add(&arq->request->queuelist, insert);
-
-	/*
-	 * Don't want to have to handle merges.
-	 */
-	as_del_arq_hash(arq);
-	arq->request->flags |= REQ_NOMERGE;
-}
-
-/*
  * add arq to rbtree and fifo
  */
 static void as_add_request(request_queue_t *q, struct request *rq)
 {
 	struct as_data *ad = q->elevator->elevator_data;
 	struct as_rq *arq = RQ_DATA(rq);
-	struct as_rq *alias;
 	int data_dir;
 
 	arq->state = AS_RQ_NEW;
@@ -1387,33 +1346,17 @@
 		atomic_inc(&arq->io_context->aic->nr_queued);
 	}
 
-	alias = as_add_arq_rb(ad, arq);
-	if (!alias) {
-		/*
-		 * set expire time (only used for reads) and add to fifo list
-		 */
-		arq->expires = jiffies + ad->fifo_expire[data_dir];
-		list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
+	as_add_arq_rb(ad, arq);
+	if (rq_mergeable(arq->request))
+		as_add_arq_hash(ad, arq);
 
-		if (rq_mergeable(arq->request))
-			as_add_arq_hash(ad, arq);
-		as_update_arq(ad, arq); /* keep state machine up to date */
+	/*
+	 * set expire time (only used for reads) and add to fifo list
+	 */
+	arq->expires = jiffies + ad->fifo_expire[data_dir];
+	list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]);
 
-	} else {
-		as_add_aliased_request(ad, arq, alias);
-
-		/*
-		 * have we been anticipating this request?
-		 * or does it come from the same process as the one we are
-		 * anticipating for?
-		 */
-		if (ad->antic_status == ANTIC_WAIT_REQ
-				|| ad->antic_status == ANTIC_WAIT_NEXT) {
-			if (as_can_break_anticipation(ad, arq))
-				as_antic_stop(ad);
-		}
-	}
-
+	as_update_arq(ad, arq); /* keep state machine up to date */
 	arq->state = AS_RQ_QUEUED;
 }
 
@@ -1536,23 +1479,8 @@
 	 * if the merge was a front merge, we need to reposition request
 	 */
 	if (rq_rb_key(req) != arq->rb_key) {
-		struct as_rq *alias, *next_arq = NULL;
-
-		if (ad->next_arq[arq->is_sync] == arq)
-			next_arq = as_find_next_arq(ad, arq);
-
-		/*
-		 * Note! We should really be moving any old aliased requests
-		 * off this request and try to insert them into the rbtree. We
-		 * currently don't bother. Ditto the next function.
-		 */
 		as_del_arq_rb(ad, arq);
-		if ((alias = as_add_arq_rb(ad, arq))) {
-			list_del_init(&arq->fifo);
-			as_add_aliased_request(ad, arq, alias);
-			if (next_arq)
-				ad->next_arq[arq->is_sync] = next_arq;
-		}
+		as_add_arq_rb(ad, arq);
 		/*
 		 * Note! At this stage of this and the next function, our next
 		 * request may not be optimal - eg the request may have "grown"
@@ -1579,18 +1507,8 @@
 	as_add_arq_hash(ad, arq);
 
 	if (rq_rb_key(req) != arq->rb_key) {
-		struct as_rq *alias, *next_arq = NULL;
-
-		if (ad->next_arq[arq->is_sync] == arq)
-			next_arq = as_find_next_arq(ad, arq);
-
 		as_del_arq_rb(ad, arq);
-		if ((alias = as_add_arq_rb(ad, arq))) {
-			list_del_init(&arq->fifo);
-			as_add_aliased_request(ad, arq, alias);
-			if (next_arq)
-				ad->next_arq[arq->is_sync] = next_arq;
-		}
+		as_add_arq_rb(ad, arq);
 	}
 
 	/*
@@ -1610,18 +1528,6 @@
 	}
 
 	/*
-	 * Transfer list of aliases
-	 */
-	while (!list_empty(&next->queuelist)) {
-		struct request *__rq = list_entry_rq(next->queuelist.next);
-		struct as_rq *__arq = RQ_DATA(__rq);
-
-		list_move_tail(&__rq->queuelist, &req->queuelist);
-
-		WARN_ON(__arq->state != AS_RQ_QUEUED);
-	}
-
-	/*
 	 * kill knowledge of next, this one is a goner
 	 */
 	as_remove_queued_request(q, next);
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index ee0bb41..74fae2d 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -25,15 +25,15 @@
 /*
  * tunables
  */
-static int cfq_quantum = 4;		/* max queue in one round of service */
-static int cfq_queued = 8;		/* minimum rq allocate limit per-queue*/
-static int cfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
-static int cfq_back_max = 16 * 1024;	/* maximum backwards seek, in KiB */
-static int cfq_back_penalty = 2;	/* penalty of a backwards seek */
+static const int cfq_quantum = 4;		/* max queue in one round of service */
+static const int cfq_queued = 8;		/* minimum rq allocate limit per-queue*/
+static const int cfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
+static const int cfq_back_max = 16 * 1024;	/* maximum backwards seek, in KiB */
+static const int cfq_back_penalty = 2;		/* penalty of a backwards seek */
 
-static int cfq_slice_sync = HZ / 10;
+static const int cfq_slice_sync = HZ / 10;
 static int cfq_slice_async = HZ / 25;
-static int cfq_slice_async_rq = 2;
+static const int cfq_slice_async_rq = 2;
 static int cfq_slice_idle = HZ / 100;
 
 #define CFQ_IDLE_GRACE		(HZ / 10)
@@ -45,7 +45,7 @@
 /*
  * disable queueing at the driver/hardware level
  */
-static int cfq_max_depth = 2;
+static const int cfq_max_depth = 2;
 
 /*
  * for the hash of cfqq inside the cfqd
diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c
index 9cbec09..27e494b 100644
--- a/block/deadline-iosched.c
+++ b/block/deadline-iosched.c
@@ -19,10 +19,10 @@
 /*
  * See Documentation/block/deadline-iosched.txt
  */
-static int read_expire = HZ / 2;  /* max time before a read is submitted. */
-static int write_expire = 5 * HZ; /* ditto for writes, these limits are SOFT! */
-static int writes_starved = 2;    /* max times reads can starve a write */
-static int fifo_batch = 16;       /* # of sequential requests treated as one
+static const int read_expire = HZ / 2;  /* max time before a read is submitted. */
+static const int write_expire = 5 * HZ; /* ditto for writes, these limits are SOFT! */
+static const int writes_starved = 2;    /* max times reads can starve a write */
+static const int fifo_batch = 16;       /* # of sequential requests treated as one
 				     by the above parameters. For throughput. */
 
 static const int deadline_hash_shift = 5;
diff --git a/block/elevator.c b/block/elevator.c
index 6c3fc8a..39dcccc 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -304,15 +304,7 @@
 
 	rq->flags &= ~REQ_STARTED;
 
-	/*
-	 * if this is the flush, requeue the original instead and drop the flush
-	 */
-	if (rq->flags & REQ_BAR_FLUSH) {
-		clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
-		rq = rq->end_io_data;
-	}
-
-	__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+	__elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE, 0);
 }
 
 static void elv_drain_elevator(request_queue_t *q)
@@ -332,8 +324,19 @@
 void __elv_add_request(request_queue_t *q, struct request *rq, int where,
 		       int plug)
 {
+	struct list_head *pos;
+	unsigned ordseq;
+
+	if (q->ordcolor)
+		rq->flags |= REQ_ORDERED_COLOR;
+
 	if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) {
 		/*
+		 * toggle ordered color
+		 */
+		q->ordcolor ^= 1;
+
+		/*
 		 * barriers implicitly indicate back insertion
 		 */
 		if (where == ELEVATOR_INSERT_SORT)
@@ -393,6 +396,30 @@
 		q->elevator->ops->elevator_add_req_fn(q, rq);
 		break;
 
+	case ELEVATOR_INSERT_REQUEUE:
+		/*
+		 * If ordered flush isn't in progress, we do front
+		 * insertion; otherwise, requests should be requeued
+		 * in ordseq order.
+		 */
+		rq->flags |= REQ_SOFTBARRIER;
+
+		if (q->ordseq == 0) {
+			list_add(&rq->queuelist, &q->queue_head);
+			break;
+		}
+
+		ordseq = blk_ordered_req_seq(rq);
+
+		list_for_each(pos, &q->queue_head) {
+			struct request *pos_rq = list_entry_rq(pos);
+			if (ordseq <= blk_ordered_req_seq(pos_rq))
+				break;
+		}
+
+		list_add_tail(&rq->queuelist, pos);
+		break;
+
 	default:
 		printk(KERN_ERR "%s: bad insertion point %d\n",
 		       __FUNCTION__, where);
@@ -422,25 +449,16 @@
 {
 	struct request *rq;
 
-	if (unlikely(list_empty(&q->queue_head) &&
-		     !q->elevator->ops->elevator_dispatch_fn(q, 0)))
-		return NULL;
+	while (1) {
+		while (!list_empty(&q->queue_head)) {
+			rq = list_entry_rq(q->queue_head.next);
+			if (blk_do_ordered(q, &rq))
+				return rq;
+		}
 
-	rq = list_entry_rq(q->queue_head.next);
-
-	/*
-	 * if this is a barrier write and the device has to issue a
-	 * flush sequence to support it, check how far we are
-	 */
-	if (blk_fs_request(rq) && blk_barrier_rq(rq)) {
-		BUG_ON(q->ordered == QUEUE_ORDERED_NONE);
-
-		if (q->ordered == QUEUE_ORDERED_FLUSH &&
-		    !blk_barrier_preflush(rq))
-			rq = blk_start_pre_flush(q, rq);
+		if (!q->elevator->ops->elevator_dispatch_fn(q, 0))
+			return NULL;
 	}
-
-	return rq;
 }
 
 struct request *elv_next_request(request_queue_t *q)
@@ -498,7 +516,7 @@
 			blkdev_dequeue_request(rq);
 			rq->flags |= REQ_QUIET;
 			end_that_request_chunk(rq, 0, nr_bytes);
-			end_that_request_last(rq);
+			end_that_request_last(rq, 0);
 		} else {
 			printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__,
 								ret);
@@ -593,7 +611,21 @@
 	 * request is released from the driver, io must be done
 	 */
 	if (blk_account_rq(rq)) {
+		struct request *first_rq = list_entry_rq(q->queue_head.next);
+
 		q->in_flight--;
+
+		/*
+		 * Check if the queue is waiting for fs requests to be
+		 * drained for flush sequence.
+		 */
+		if (q->ordseq && q->in_flight == 0 &&
+		    blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN &&
+		    blk_ordered_req_seq(first_rq) > QUEUE_ORDSEQ_DRAIN) {
+			blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0);
+			q->request_fn(q);
+		}
+
 		if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn)
 			e->ops->elevator_completed_req_fn(q, rq);
 	}
diff --git a/block/genhd.c b/block/genhd.c
index f04609d..f1ed83f 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -358,7 +358,7 @@
 static ssize_t disk_uevent_store(struct gendisk * disk,
 				 const char *buf, size_t count)
 {
-	kobject_hotplug(&disk->kobj, KOBJ_ADD);
+	kobject_uevent(&disk->kobj, KOBJ_ADD);
 	return count;
 }
 static ssize_t disk_dev_read(struct gendisk * disk, char *page)
@@ -455,14 +455,14 @@
 
 extern struct kobj_type ktype_part;
 
-static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
+static int block_uevent_filter(struct kset *kset, struct kobject *kobj)
 {
 	struct kobj_type *ktype = get_ktype(kobj);
 
 	return ((ktype == &ktype_block) || (ktype == &ktype_part));
 }
 
-static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
+static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
 			 int num_envp, char *buffer, int buffer_size)
 {
 	struct kobj_type *ktype = get_ktype(kobj);
@@ -474,40 +474,40 @@
 
 	if (ktype == &ktype_block) {
 		disk = container_of(kobj, struct gendisk, kobj);
-		add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
-				    &length, "MINOR=%u", disk->first_minor);
+		add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+			       &length, "MINOR=%u", disk->first_minor);
 	} else if (ktype == &ktype_part) {
 		disk = container_of(kobj->parent, struct gendisk, kobj);
 		part = container_of(kobj, struct hd_struct, kobj);
-		add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
-				    &length, "MINOR=%u",
-				    disk->first_minor + part->partno);
+		add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+			       &length, "MINOR=%u",
+			       disk->first_minor + part->partno);
 	} else
 		return 0;
 
-	add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &length,
-			    "MAJOR=%u", disk->major);
+	add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+		       "MAJOR=%u", disk->major);
 
 	/* add physical device, backing this device  */
 	physdev = disk->driverfs_dev;
 	if (physdev) {
 		char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
 
-		add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
-				    &length, "PHYSDEVPATH=%s", path);
+		add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+			       &length, "PHYSDEVPATH=%s", path);
 		kfree(path);
 
 		if (physdev->bus)
-			add_hotplug_env_var(envp, num_envp, &i,
-					    buffer, buffer_size, &length,
-					    "PHYSDEVBUS=%s",
-					    physdev->bus->name);
+			add_uevent_var(envp, num_envp, &i,
+				       buffer, buffer_size, &length,
+				       "PHYSDEVBUS=%s",
+				       physdev->bus->name);
 
 		if (physdev->driver)
-			add_hotplug_env_var(envp, num_envp, &i,
-					    buffer, buffer_size, &length,
-					    "PHYSDEVDRIVER=%s",
-					    physdev->driver->name);
+			add_uevent_var(envp, num_envp, &i,
+				       buffer, buffer_size, &length,
+				       "PHYSDEVDRIVER=%s",
+				       physdev->driver->name);
 	}
 
 	/* terminate, set to next free slot, shrink available space */
@@ -520,13 +520,13 @@
 	return 0;
 }
 
-static struct kset_hotplug_ops block_hotplug_ops = {
-	.filter		= block_hotplug_filter,
-	.hotplug	= block_hotplug,
+static struct kset_uevent_ops block_uevent_ops = {
+	.filter		= block_uevent_filter,
+	.uevent		= block_uevent,
 };
 
 /* declare block_subsys. */
-static decl_subsys(block, &ktype_block, &block_hotplug_ops);
+static decl_subsys(block, &ktype_block, &block_uevent_ops);
 
 
 /*
diff --git a/block/ioctl.c b/block/ioctl.c
index 6e27847..82030e1 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -1,6 +1,7 @@
 #include <linux/sched.h>		/* for capable() */
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
+#include <linux/hdreg.h>
 #include <linux/backing-dev.h>
 #include <linux/buffer_head.h>
 #include <linux/smp_lock.h>
@@ -245,6 +246,27 @@
 		set_device_ro(bdev, n);
 		unlock_kernel();
 		return 0;
+	case HDIO_GETGEO: {
+		struct hd_geometry geo;
+
+		if (!arg)
+			return -EINVAL;
+		if (!disk->fops->getgeo)
+			return -ENOTTY;
+
+		/*
+		 * We need to set the startsect first, the driver may
+		 * want to override it.
+		 */
+		geo.start = get_start_sect(bdev);
+		ret = disk->fops->getgeo(bdev, &geo);
+		if (ret)
+			return ret;
+		if (copy_to_user((struct hd_geometry __user *)arg, &geo,
+					sizeof(geo)))
+			return -EFAULT;
+		return 0;
+	}
 	}
 
 	lock_kernel();
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 99c9ca6..91d3b48 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -36,6 +36,8 @@
 static void blk_unplug_work(void *data);
 static void blk_unplug_timeout(unsigned long data);
 static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io);
+static void init_request_from_bio(struct request *req, struct bio *bio);
+static int __make_request(request_queue_t *q, struct bio *bio);
 
 /*
  * For the allocated request tables
@@ -239,7 +241,7 @@
 	q->backing_dev_info.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
 	q->backing_dev_info.state = 0;
 	q->backing_dev_info.capabilities = BDI_CAP_MAP_COPY;
-	blk_queue_max_sectors(q, MAX_SECTORS);
+	blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
 	blk_queue_hardsect_size(q, 512);
 	blk_queue_dma_alignment(q, 511);
 	blk_queue_congestion_threshold(q);
@@ -288,8 +290,8 @@
 
 /**
  * blk_queue_ordered - does this queue support ordered writes
- * @q:     the request queue
- * @flag:  see below
+ * @q:        the request queue
+ * @ordered:  one of QUEUE_ORDERED_*
  *
  * Description:
  *   For journalled file systems, doing ordered writes on a commit
@@ -298,28 +300,30 @@
  *   feature should call this function and indicate so.
  *
  **/
-void blk_queue_ordered(request_queue_t *q, int flag)
+int blk_queue_ordered(request_queue_t *q, unsigned ordered,
+		      prepare_flush_fn *prepare_flush_fn)
 {
-	switch (flag) {
-		case QUEUE_ORDERED_NONE:
-			if (q->flush_rq)
-				kmem_cache_free(request_cachep, q->flush_rq);
-			q->flush_rq = NULL;
-			q->ordered = flag;
-			break;
-		case QUEUE_ORDERED_TAG:
-			q->ordered = flag;
-			break;
-		case QUEUE_ORDERED_FLUSH:
-			q->ordered = flag;
-			if (!q->flush_rq)
-				q->flush_rq = kmem_cache_alloc(request_cachep,
-								GFP_KERNEL);
-			break;
-		default:
-			printk("blk_queue_ordered: bad value %d\n", flag);
-			break;
+	if (ordered & (QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_POSTFLUSH) &&
+	    prepare_flush_fn == NULL) {
+		printk(KERN_ERR "blk_queue_ordered: prepare_flush_fn required\n");
+		return -EINVAL;
 	}
+
+	if (ordered != QUEUE_ORDERED_NONE &&
+	    ordered != QUEUE_ORDERED_DRAIN &&
+	    ordered != QUEUE_ORDERED_DRAIN_FLUSH &&
+	    ordered != QUEUE_ORDERED_DRAIN_FUA &&
+	    ordered != QUEUE_ORDERED_TAG &&
+	    ordered != QUEUE_ORDERED_TAG_FLUSH &&
+	    ordered != QUEUE_ORDERED_TAG_FUA) {
+		printk(KERN_ERR "blk_queue_ordered: bad value %d\n", ordered);
+		return -EINVAL;
+	}
+
+	q->next_ordered = ordered;
+	q->prepare_flush_fn = prepare_flush_fn;
+
+	return 0;
 }
 
 EXPORT_SYMBOL(blk_queue_ordered);
@@ -344,167 +348,265 @@
 /*
  * Cache flushing for ordered writes handling
  */
-static void blk_pre_flush_end_io(struct request *flush_rq)
+inline unsigned blk_ordered_cur_seq(request_queue_t *q)
 {
-	struct request *rq = flush_rq->end_io_data;
+	if (!q->ordseq)
+		return 0;
+	return 1 << ffz(q->ordseq);
+}
+
+unsigned blk_ordered_req_seq(struct request *rq)
+{
 	request_queue_t *q = rq->q;
 
-	elv_completed_request(q, flush_rq);
+	BUG_ON(q->ordseq == 0);
 
-	rq->flags |= REQ_BAR_PREFLUSH;
+	if (rq == &q->pre_flush_rq)
+		return QUEUE_ORDSEQ_PREFLUSH;
+	if (rq == &q->bar_rq)
+		return QUEUE_ORDSEQ_BAR;
+	if (rq == &q->post_flush_rq)
+		return QUEUE_ORDSEQ_POSTFLUSH;
 
-	if (!flush_rq->errors)
-		elv_requeue_request(q, rq);
-	else {
-		q->end_flush_fn(q, flush_rq);
-		clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
-		q->request_fn(q);
-	}
+	if ((rq->flags & REQ_ORDERED_COLOR) ==
+	    (q->orig_bar_rq->flags & REQ_ORDERED_COLOR))
+		return QUEUE_ORDSEQ_DRAIN;
+	else
+		return QUEUE_ORDSEQ_DONE;
 }
 
-static void blk_post_flush_end_io(struct request *flush_rq)
+void blk_ordered_complete_seq(request_queue_t *q, unsigned seq, int error)
 {
-	struct request *rq = flush_rq->end_io_data;
-	request_queue_t *q = rq->q;
+	struct request *rq;
+	int uptodate;
 
-	elv_completed_request(q, flush_rq);
+	if (error && !q->orderr)
+		q->orderr = error;
 
-	rq->flags |= REQ_BAR_POSTFLUSH;
+	BUG_ON(q->ordseq & seq);
+	q->ordseq |= seq;
 
-	q->end_flush_fn(q, flush_rq);
-	clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
-	q->request_fn(q);
-}
-
-struct request *blk_start_pre_flush(request_queue_t *q, struct request *rq)
-{
-	struct request *flush_rq = q->flush_rq;
-
-	BUG_ON(!blk_barrier_rq(rq));
-
-	if (test_and_set_bit(QUEUE_FLAG_FLUSH, &q->queue_flags))
-		return NULL;
-
-	rq_init(q, flush_rq);
-	flush_rq->elevator_private = NULL;
-	flush_rq->flags = REQ_BAR_FLUSH;
-	flush_rq->rq_disk = rq->rq_disk;
-	flush_rq->rl = NULL;
+	if (blk_ordered_cur_seq(q) != QUEUE_ORDSEQ_DONE)
+		return;
 
 	/*
-	 * prepare_flush returns 0 if no flush is needed, just mark both
-	 * pre and post flush as done in that case
+	 * Okay, sequence complete.
 	 */
-	if (!q->prepare_flush_fn(q, flush_rq)) {
-		rq->flags |= REQ_BAR_PREFLUSH | REQ_BAR_POSTFLUSH;
-		clear_bit(QUEUE_FLAG_FLUSH, &q->queue_flags);
-		return rq;
+	rq = q->orig_bar_rq;
+	uptodate = q->orderr ? q->orderr : 1;
+
+	q->ordseq = 0;
+
+	end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
+	end_that_request_last(rq, uptodate);
+}
+
+static void pre_flush_end_io(struct request *rq, int error)
+{
+	elv_completed_request(rq->q, rq);
+	blk_ordered_complete_seq(rq->q, QUEUE_ORDSEQ_PREFLUSH, error);
+}
+
+static void bar_end_io(struct request *rq, int error)
+{
+	elv_completed_request(rq->q, rq);
+	blk_ordered_complete_seq(rq->q, QUEUE_ORDSEQ_BAR, error);
+}
+
+static void post_flush_end_io(struct request *rq, int error)
+{
+	elv_completed_request(rq->q, rq);
+	blk_ordered_complete_seq(rq->q, QUEUE_ORDSEQ_POSTFLUSH, error);
+}
+
+static void queue_flush(request_queue_t *q, unsigned which)
+{
+	struct request *rq;
+	rq_end_io_fn *end_io;
+
+	if (which == QUEUE_ORDERED_PREFLUSH) {
+		rq = &q->pre_flush_rq;
+		end_io = pre_flush_end_io;
+	} else {
+		rq = &q->post_flush_rq;
+		end_io = post_flush_end_io;
 	}
 
+	rq_init(q, rq);
+	rq->flags = REQ_HARDBARRIER;
+	rq->elevator_private = NULL;
+	rq->rq_disk = q->bar_rq.rq_disk;
+	rq->rl = NULL;
+	rq->end_io = end_io;
+	q->prepare_flush_fn(q, rq);
+
+	__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+}
+
+static inline struct request *start_ordered(request_queue_t *q,
+					    struct request *rq)
+{
+	q->bi_size = 0;
+	q->orderr = 0;
+	q->ordered = q->next_ordered;
+	q->ordseq |= QUEUE_ORDSEQ_STARTED;
+
 	/*
-	 * some drivers dequeue requests right away, some only after io
-	 * completion. make sure the request is dequeued.
+	 * Prep proxy barrier request.
 	 */
-	if (!list_empty(&rq->queuelist))
-		blkdev_dequeue_request(rq);
+	blkdev_dequeue_request(rq);
+	q->orig_bar_rq = rq;
+	rq = &q->bar_rq;
+	rq_init(q, rq);
+	rq->flags = bio_data_dir(q->orig_bar_rq->bio);
+	rq->flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0;
+	rq->elevator_private = NULL;
+	rq->rl = NULL;
+	init_request_from_bio(rq, q->orig_bar_rq->bio);
+	rq->end_io = bar_end_io;
 
-	flush_rq->end_io_data = rq;
-	flush_rq->end_io = blk_pre_flush_end_io;
+	/*
+	 * Queue ordered sequence.  As we stack them at the head, we
+	 * need to queue in reverse order.  Note that we rely on that
+	 * no fs request uses ELEVATOR_INSERT_FRONT and thus no fs
+	 * request gets inbetween ordered sequence.
+	 */
+	if (q->ordered & QUEUE_ORDERED_POSTFLUSH)
+		queue_flush(q, QUEUE_ORDERED_POSTFLUSH);
+	else
+		q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH;
 
-	__elv_add_request(q, flush_rq, ELEVATOR_INSERT_FRONT, 0);
-	return flush_rq;
+	__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
+
+	if (q->ordered & QUEUE_ORDERED_PREFLUSH) {
+		queue_flush(q, QUEUE_ORDERED_PREFLUSH);
+		rq = &q->pre_flush_rq;
+	} else
+		q->ordseq |= QUEUE_ORDSEQ_PREFLUSH;
+
+	if ((q->ordered & QUEUE_ORDERED_TAG) || q->in_flight == 0)
+		q->ordseq |= QUEUE_ORDSEQ_DRAIN;
+	else
+		rq = NULL;
+
+	return rq;
 }
 
-static void blk_start_post_flush(request_queue_t *q, struct request *rq)
+int blk_do_ordered(request_queue_t *q, struct request **rqp)
 {
-	struct request *flush_rq = q->flush_rq;
+	struct request *rq = *rqp, *allowed_rq;
+	int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq);
 
-	BUG_ON(!blk_barrier_rq(rq));
+	if (!q->ordseq) {
+		if (!is_barrier)
+			return 1;
 
-	rq_init(q, flush_rq);
-	flush_rq->elevator_private = NULL;
-	flush_rq->flags = REQ_BAR_FLUSH;
-	flush_rq->rq_disk = rq->rq_disk;
-	flush_rq->rl = NULL;
-
-	if (q->prepare_flush_fn(q, flush_rq)) {
-		flush_rq->end_io_data = rq;
-		flush_rq->end_io = blk_post_flush_end_io;
-
-		__elv_add_request(q, flush_rq, ELEVATOR_INSERT_FRONT, 0);
-		q->request_fn(q);
+		if (q->next_ordered != QUEUE_ORDERED_NONE) {
+			*rqp = start_ordered(q, rq);
+			return 1;
+		} else {
+			/*
+			 * This can happen when the queue switches to
+			 * ORDERED_NONE while this request is on it.
+			 */
+			blkdev_dequeue_request(rq);
+			end_that_request_first(rq, -EOPNOTSUPP,
+					       rq->hard_nr_sectors);
+			end_that_request_last(rq, -EOPNOTSUPP);
+			*rqp = NULL;
+			return 0;
+		}
 	}
-}
 
-static inline int blk_check_end_barrier(request_queue_t *q, struct request *rq,
-					int sectors)
-{
-	if (sectors > rq->nr_sectors)
-		sectors = rq->nr_sectors;
-
-	rq->nr_sectors -= sectors;
-	return rq->nr_sectors;
-}
-
-static int __blk_complete_barrier_rq(request_queue_t *q, struct request *rq,
-				     int sectors, int queue_locked)
-{
-	if (q->ordered != QUEUE_ORDERED_FLUSH)
-		return 0;
-	if (!blk_fs_request(rq) || !blk_barrier_rq(rq))
-		return 0;
-	if (blk_barrier_postflush(rq))
-		return 0;
-
-	if (!blk_check_end_barrier(q, rq, sectors)) {
-		unsigned long flags = 0;
-
-		if (!queue_locked)
-			spin_lock_irqsave(q->queue_lock, flags);
-
-		blk_start_post_flush(q, rq);
-
-		if (!queue_locked)
-			spin_unlock_irqrestore(q->queue_lock, flags);
+	if (q->ordered & QUEUE_ORDERED_TAG) {
+		if (is_barrier && rq != &q->bar_rq)
+			*rqp = NULL;
+		return 1;
 	}
 
+	switch (blk_ordered_cur_seq(q)) {
+	case QUEUE_ORDSEQ_PREFLUSH:
+		allowed_rq = &q->pre_flush_rq;
+		break;
+	case QUEUE_ORDSEQ_BAR:
+		allowed_rq = &q->bar_rq;
+		break;
+	case QUEUE_ORDSEQ_POSTFLUSH:
+		allowed_rq = &q->post_flush_rq;
+		break;
+	default:
+		allowed_rq = NULL;
+		break;
+	}
+
+	if (rq != allowed_rq &&
+	    (blk_fs_request(rq) || rq == &q->pre_flush_rq ||
+	     rq == &q->post_flush_rq))
+		*rqp = NULL;
+
 	return 1;
 }
 
-/**
- * blk_complete_barrier_rq - complete possible barrier request
- * @q:  the request queue for the device
- * @rq:  the request
- * @sectors:  number of sectors to complete
- *
- * Description:
- *   Used in driver end_io handling to determine whether to postpone
- *   completion of a barrier request until a post flush has been done. This
- *   is the unlocked variant, used if the caller doesn't already hold the
- *   queue lock.
- **/
-int blk_complete_barrier_rq(request_queue_t *q, struct request *rq, int sectors)
+static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error)
 {
-	return __blk_complete_barrier_rq(q, rq, sectors, 0);
-}
-EXPORT_SYMBOL(blk_complete_barrier_rq);
+	request_queue_t *q = bio->bi_private;
+	struct bio_vec *bvec;
+	int i;
 
-/**
- * blk_complete_barrier_rq_locked - complete possible barrier request
- * @q:  the request queue for the device
- * @rq:  the request
- * @sectors:  number of sectors to complete
- *
- * Description:
- *   See blk_complete_barrier_rq(). This variant must be used if the caller
- *   holds the queue lock.
- **/
-int blk_complete_barrier_rq_locked(request_queue_t *q, struct request *rq,
-				   int sectors)
-{
-	return __blk_complete_barrier_rq(q, rq, sectors, 1);
+	/*
+	 * This is dry run, restore bio_sector and size.  We'll finish
+	 * this request again with the original bi_end_io after an
+	 * error occurs or post flush is complete.
+	 */
+	q->bi_size += bytes;
+
+	if (bio->bi_size)
+		return 1;
+
+	/* Rewind bvec's */
+	bio->bi_idx = 0;
+	bio_for_each_segment(bvec, bio, i) {
+		bvec->bv_len += bvec->bv_offset;
+		bvec->bv_offset = 0;
+	}
+
+	/* Reset bio */
+	set_bit(BIO_UPTODATE, &bio->bi_flags);
+	bio->bi_size = q->bi_size;
+	bio->bi_sector -= (q->bi_size >> 9);
+	q->bi_size = 0;
+
+	return 0;
 }
-EXPORT_SYMBOL(blk_complete_barrier_rq_locked);
+
+static inline int ordered_bio_endio(struct request *rq, struct bio *bio,
+				    unsigned int nbytes, int error)
+{
+	request_queue_t *q = rq->q;
+	bio_end_io_t *endio;
+	void *private;
+
+	if (&q->bar_rq != rq)
+		return 0;
+
+	/*
+	 * Okay, this is the barrier request in progress, dry finish it.
+	 */
+	if (error && !q->orderr)
+		q->orderr = error;
+
+	endio = bio->bi_end_io;
+	private = bio->bi_private;
+	bio->bi_end_io = flush_dry_bio_endio;
+	bio->bi_private = q;
+
+	bio_endio(bio, nbytes, error);
+
+	bio->bi_end_io = endio;
+	bio->bi_private = private;
+
+	return 1;
+}
 
 /**
  * blk_queue_bounce_limit - set bounce buffer limit for queue
@@ -555,7 +657,12 @@
 		printk("%s: set to minimum %d\n", __FUNCTION__, max_sectors);
 	}
 
-	q->max_sectors = q->max_hw_sectors = max_sectors;
+	if (BLK_DEF_MAX_SECTORS > max_sectors)
+		q->max_hw_sectors = q->max_sectors = max_sectors;
+ 	else {
+		q->max_sectors = BLK_DEF_MAX_SECTORS;
+		q->max_hw_sectors = max_sectors;
+	}
 }
 
 EXPORT_SYMBOL(blk_queue_max_sectors);
@@ -657,8 +764,8 @@
 void blk_queue_stack_limits(request_queue_t *t, request_queue_t *b)
 {
 	/* zero is "infinity" */
-	t->max_sectors = t->max_hw_sectors =
-		min_not_zero(t->max_sectors,b->max_sectors);
+	t->max_sectors = min_not_zero(t->max_sectors,b->max_sectors);
+	t->max_hw_sectors = min_not_zero(t->max_hw_sectors,b->max_hw_sectors);
 
 	t->max_phys_segments = min(t->max_phys_segments,b->max_phys_segments);
 	t->max_hw_segments = min(t->max_hw_segments,b->max_hw_segments);
@@ -1034,12 +1141,13 @@
 
 EXPORT_SYMBOL(blk_queue_invalidate_tags);
 
-static char *rq_flags[] = {
+static const char * const rq_flags[] = {
 	"REQ_RW",
 	"REQ_FAILFAST",
 	"REQ_SORTED",
 	"REQ_SOFTBARRIER",
 	"REQ_HARDBARRIER",
+	"REQ_FUA",
 	"REQ_CMD",
 	"REQ_NOMERGE",
 	"REQ_STARTED",
@@ -1059,6 +1167,7 @@
 	"REQ_PM_SUSPEND",
 	"REQ_PM_RESUME",
 	"REQ_PM_SHUTDOWN",
+	"REQ_ORDERED_COLOR",
 };
 
 void blk_dump_rq_flags(struct request *rq, char *msg)
@@ -1293,9 +1402,15 @@
 static int ll_back_merge_fn(request_queue_t *q, struct request *req, 
 			    struct bio *bio)
 {
+	unsigned short max_sectors;
 	int len;
 
-	if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
+	if (unlikely(blk_pc_request(req)))
+		max_sectors = q->max_hw_sectors;
+	else
+		max_sectors = q->max_sectors;
+
+	if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
 		req->flags |= REQ_NOMERGE;
 		if (req == q->last_merge)
 			q->last_merge = NULL;
@@ -1325,9 +1440,16 @@
 static int ll_front_merge_fn(request_queue_t *q, struct request *req, 
 			     struct bio *bio)
 {
+	unsigned short max_sectors;
 	int len;
 
-	if (req->nr_sectors + bio_sectors(bio) > q->max_sectors) {
+	if (unlikely(blk_pc_request(req)))
+		max_sectors = q->max_hw_sectors;
+	else
+		max_sectors = q->max_sectors;
+
+
+	if (req->nr_sectors + bio_sectors(bio) > max_sectors) {
 		req->flags |= REQ_NOMERGE;
 		if (req == q->last_merge)
 			q->last_merge = NULL;
@@ -1623,8 +1745,6 @@
 	if (q->queue_tags)
 		__blk_queue_free_tags(q);
 
-	blk_queue_ordered(q, QUEUE_ORDERED_NONE);
-
 	kmem_cache_free(requestq_cachep, q);
 }
 
@@ -1649,8 +1769,6 @@
 	return 0;
 }
 
-static int __make_request(request_queue_t *, struct bio *);
-
 request_queue_t *blk_alloc_queue(gfp_t gfp_mask)
 {
 	return blk_alloc_queue_node(gfp_mask, -1);
@@ -1890,40 +2008,40 @@
 {
 	struct request *rq = NULL;
 	struct request_list *rl = &q->rq;
-	struct io_context *ioc = current_io_context(GFP_ATOMIC);
-	int priv;
+	struct io_context *ioc = NULL;
+	int may_queue, priv;
 
-	if (rl->count[rw]+1 >= q->nr_requests) {
-		/*
-		 * The queue will fill after this allocation, so set it as
-		 * full, and mark this process as "batching". This process
-		 * will be allowed to complete a batch of requests, others
-		 * will be blocked.
-		 */
-		if (!blk_queue_full(q, rw)) {
-			ioc_set_batching(q, ioc);
-			blk_set_queue_full(q, rw);
+	may_queue = elv_may_queue(q, rw, bio);
+	if (may_queue == ELV_MQUEUE_NO)
+		goto rq_starved;
+
+	if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) {
+		if (rl->count[rw]+1 >= q->nr_requests) {
+			ioc = current_io_context(GFP_ATOMIC);
+			/*
+			 * The queue will fill after this allocation, so set
+			 * it as full, and mark this process as "batching".
+			 * This process will be allowed to complete a batch of
+			 * requests, others will be blocked.
+			 */
+			if (!blk_queue_full(q, rw)) {
+				ioc_set_batching(q, ioc);
+				blk_set_queue_full(q, rw);
+			} else {
+				if (may_queue != ELV_MQUEUE_MUST
+						&& !ioc_batching(q, ioc)) {
+					/*
+					 * The queue is full and the allocating
+					 * process is not a "batcher", and not
+					 * exempted by the IO scheduler
+					 */
+					goto out;
+				}
+			}
 		}
+		set_queue_congested(q, rw);
 	}
 
-	switch (elv_may_queue(q, rw, bio)) {
-		case ELV_MQUEUE_NO:
-			goto rq_starved;
-		case ELV_MQUEUE_MAY:
-			break;
-		case ELV_MQUEUE_MUST:
-			goto get_rq;
-	}
-
-	if (blk_queue_full(q, rw) && !ioc_batching(q, ioc)) {
-		/*
-		 * The queue is full and the allocating process is not a
-		 * "batcher", and not exempted by the IO scheduler
-		 */
-		goto out;
-	}
-
-get_rq:
 	/*
 	 * Only allow batching queuers to allocate up to 50% over the defined
 	 * limit of requests, otherwise we could have thousands of requests
@@ -1934,8 +2052,6 @@
 
 	rl->count[rw]++;
 	rl->starved[rw] = 0;
-	if (rl->count[rw] >= queue_congestion_on_threshold(q))
-		set_queue_congested(q, rw);
 
 	priv = !test_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags);
 	if (priv)
@@ -1944,7 +2060,7 @@
 	spin_unlock_irq(q->queue_lock);
 
 	rq = blk_alloc_request(q, rw, bio, priv, gfp_mask);
-	if (!rq) {
+	if (unlikely(!rq)) {
 		/*
 		 * Allocation failed presumably due to memory. Undo anything
 		 * we might have messed up.
@@ -1969,6 +2085,12 @@
 		goto out;
 	}
 
+	/*
+	 * ioc may be NULL here, and ioc_batching will be false. That's
+	 * OK, if the queue is under the request limit then requests need
+	 * not count toward the nr_batch_requests limit. There will always
+	 * be some limit enforced by BLK_BATCH_TIME.
+	 */
 	if (ioc_batching(q, ioc))
 		ioc->nr_batch_requests--;
 	
@@ -2144,7 +2266,7 @@
 	struct bio *bio;
 	int reading;
 
-	if (len > (q->max_sectors << 9))
+	if (len > (q->max_hw_sectors << 9))
 		return -EINVAL;
 	if (!len || !ubuf)
 		return -EINVAL;
@@ -2259,7 +2381,7 @@
 {
 	struct bio *bio;
 
-	if (len > (q->max_sectors << 9))
+	if (len > (q->max_hw_sectors << 9))
 		return -EINVAL;
 	if (!len || !kbuf)
 		return -EINVAL;
@@ -2295,7 +2417,7 @@
  */
 void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk,
 			   struct request *rq, int at_head,
-			   void (*done)(struct request *))
+			   rq_end_io_fn *done)
 {
 	int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
 
@@ -2306,6 +2428,8 @@
 	generic_unplug_device(q);
 }
 
+EXPORT_SYMBOL_GPL(blk_execute_rq_nowait);
+
 /**
  * blk_execute_rq - insert a request into queue for execution
  * @q:		queue to insert the request in
@@ -2444,7 +2568,7 @@
 /*
  * queue lock must be held
  */
-static void __blk_put_request(request_queue_t *q, struct request *req)
+void __blk_put_request(request_queue_t *q, struct request *req)
 {
 	struct request_list *rl = req->rl;
 
@@ -2473,6 +2597,8 @@
 	}
 }
 
+EXPORT_SYMBOL_GPL(__blk_put_request);
+
 void blk_put_request(struct request *req)
 {
 	unsigned long flags;
@@ -2495,7 +2621,7 @@
  * blk_end_sync_rq - executes a completion event on a request
  * @rq: request to complete
  */
-void blk_end_sync_rq(struct request *rq)
+void blk_end_sync_rq(struct request *rq, int error)
 {
 	struct completion *waiting = rq->waiting;
 
@@ -2633,6 +2759,36 @@
 
 EXPORT_SYMBOL(blk_attempt_remerge);
 
+static void init_request_from_bio(struct request *req, struct bio *bio)
+{
+	req->flags |= REQ_CMD;
+
+	/*
+	 * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
+	 */
+	if (bio_rw_ahead(bio) || bio_failfast(bio))
+		req->flags |= REQ_FAILFAST;
+
+	/*
+	 * REQ_BARRIER implies no merging, but lets make it explicit
+	 */
+	if (unlikely(bio_barrier(bio)))
+		req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
+
+	req->errors = 0;
+	req->hard_sector = req->sector = bio->bi_sector;
+	req->hard_nr_sectors = req->nr_sectors = bio_sectors(bio);
+	req->current_nr_sectors = req->hard_cur_sectors = bio_cur_sectors(bio);
+	req->nr_phys_segments = bio_phys_segments(req->q, bio);
+	req->nr_hw_segments = bio_hw_segments(req->q, bio);
+	req->buffer = bio_data(bio);	/* see ->buffer comment above */
+	req->waiting = NULL;
+	req->bio = req->biotail = bio;
+	req->ioprio = bio_prio(bio);
+	req->rq_disk = bio->bi_bdev->bd_disk;
+	req->start_time = jiffies;
+}
+
 static int __make_request(request_queue_t *q, struct bio *bio)
 {
 	struct request *req;
@@ -2658,7 +2814,7 @@
 	spin_lock_prefetch(q->queue_lock);
 
 	barrier = bio_barrier(bio);
-	if (unlikely(barrier) && (q->ordered == QUEUE_ORDERED_NONE)) {
+	if (unlikely(barrier) && (q->next_ordered == QUEUE_ORDERED_NONE)) {
 		err = -EOPNOTSUPP;
 		goto end_io;
 	}
@@ -2728,33 +2884,7 @@
 	 * We don't worry about that case for efficiency. It won't happen
 	 * often, and the elevators are able to handle it.
 	 */
-
-	req->flags |= REQ_CMD;
-
-	/*
-	 * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
-	 */
-	if (bio_rw_ahead(bio) || bio_failfast(bio))
-		req->flags |= REQ_FAILFAST;
-
-	/*
-	 * REQ_BARRIER implies no merging, but lets make it explicit
-	 */
-	if (unlikely(barrier))
-		req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE);
-
-	req->errors = 0;
-	req->hard_sector = req->sector = sector;
-	req->hard_nr_sectors = req->nr_sectors = nr_sectors;
-	req->current_nr_sectors = req->hard_cur_sectors = cur_nr_sectors;
-	req->nr_phys_segments = bio_phys_segments(q, bio);
-	req->nr_hw_segments = bio_hw_segments(q, bio);
-	req->buffer = bio_data(bio);	/* see ->buffer comment above */
-	req->waiting = NULL;
-	req->bio = req->biotail = bio;
-	req->ioprio = prio;
-	req->rq_disk = bio->bi_bdev->bd_disk;
-	req->start_time = jiffies;
+	init_request_from_bio(req, bio);
 
 	spin_lock_irq(q->queue_lock);
 	if (elv_queue_empty(q))
@@ -3045,7 +3175,8 @@
 		if (nr_bytes >= bio->bi_size) {
 			req->bio = bio->bi_next;
 			nbytes = bio->bi_size;
-			bio_endio(bio, nbytes, error);
+			if (!ordered_bio_endio(req, bio, nbytes, error))
+				bio_endio(bio, nbytes, error);
 			next_idx = 0;
 			bio_nbytes = 0;
 		} else {
@@ -3100,7 +3231,8 @@
 	 * if the request wasn't completed, update state
 	 */
 	if (bio_nbytes) {
-		bio_endio(bio, bio_nbytes, error);
+		if (!ordered_bio_endio(req, bio, bio_nbytes, error))
+			bio_endio(bio, bio_nbytes, error);
 		bio->bi_idx += next_idx;
 		bio_iovec(bio)->bv_offset += nr_bytes;
 		bio_iovec(bio)->bv_len -= nr_bytes;
@@ -3157,9 +3289,17 @@
 /*
  * queue lock must be held
  */
-void end_that_request_last(struct request *req)
+void end_that_request_last(struct request *req, int uptodate)
 {
 	struct gendisk *disk = req->rq_disk;
+	int error;
+
+	/*
+	 * extend uptodate bool to allow < 0 value to be direct io error
+	 */
+	error = 0;
+	if (end_io_error(uptodate))
+		error = !uptodate ? -EIO : uptodate;
 
 	if (unlikely(laptop_mode) && blk_fs_request(req))
 		laptop_io_completion();
@@ -3174,7 +3314,7 @@
 		disk->in_flight--;
 	}
 	if (req->end_io)
-		req->end_io(req);
+		req->end_io(req, error);
 	else
 		__blk_put_request(req->q, req);
 }
@@ -3186,7 +3326,7 @@
 	if (!end_that_request_first(req, uptodate, req->hard_cur_sectors)) {
 		add_disk_randomness(req->rq_disk);
 		blkdev_dequeue_request(req);
-		end_that_request_last(req);
+		end_that_request_last(req, uptodate);
 	}
 }
 
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 382dea7..c2ac36d 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -46,7 +46,7 @@
 
 static int sg_get_version(int __user *p)
 {
-	static int sg_version_num = 30527;
+	static const int sg_version_num = 30527;
 	return put_user(sg_version_num, p);
 }
 
@@ -233,7 +233,7 @@
 	if (verify_command(file, cmd))
 		return -EPERM;
 
-	if (hdr->dxfer_len > (q->max_sectors << 9))
+	if (hdr->dxfer_len > (q->max_hw_sectors << 9))
 		return -EIO;
 
 	if (hdr->dxfer_len)
@@ -442,11 +442,37 @@
 	return err;
 }
 
+
+/* Send basic block requests */
+static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int cmd, int data)
+{
+	struct request *rq;
+	int err;
+
+	rq = blk_get_request(q, WRITE, __GFP_WAIT);
+	rq->flags |= REQ_BLOCK_PC;
+	rq->data = NULL;
+	rq->data_len = 0;
+	rq->timeout = BLK_DEFAULT_TIMEOUT;
+	memset(rq->cmd, 0, sizeof(rq->cmd));
+	rq->cmd[0] = cmd;
+	rq->cmd[4] = data;
+	rq->cmd_len = 6;
+	err = blk_execute_rq(q, bd_disk, rq, 0);
+	blk_put_request(rq);
+
+	return err;
+}
+
+static inline int blk_send_start_stop(request_queue_t *q, struct gendisk *bd_disk, int data)
+{
+	return __blk_send_generic(q, bd_disk, GPCMD_START_STOP_UNIT, data);
+}
+
 int scsi_cmd_ioctl(struct file *file, struct gendisk *bd_disk, unsigned int cmd, void __user *arg)
 {
 	request_queue_t *q;
-	struct request *rq;
-	int close = 0, err;
+	int err;
 
 	q = bd_disk->queue;
 	if (!q)
@@ -564,19 +590,10 @@
 			err = sg_scsi_ioctl(file, q, bd_disk, arg);
 			break;
 		case CDROMCLOSETRAY:
-			close = 1;
+			err = blk_send_start_stop(q, bd_disk, 0x03);
+			break;
 		case CDROMEJECT:
-			rq = blk_get_request(q, WRITE, __GFP_WAIT);
-			rq->flags |= REQ_BLOCK_PC;
-			rq->data = NULL;
-			rq->data_len = 0;
-			rq->timeout = BLK_DEFAULT_TIMEOUT;
-			memset(rq->cmd, 0, sizeof(rq->cmd));
-			rq->cmd[0] = GPCMD_START_STOP_UNIT;
-			rq->cmd[4] = 0x02 + (close != 0);
-			rq->cmd_len = 6;
-			err = blk_execute_rq(q, bd_disk, rq, 0);
-			blk_put_request(rq);
+			err = blk_send_start_stop(q, bd_disk, 0x02);
 			break;
 		default:
 			err = -ENOTTY;
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 89299f4..52e1d41 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -40,10 +40,11 @@
 	help
 	  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
 
-config CRYPTO_SHA1_Z990
-	tristate "SHA1 digest algorithm for IBM zSeries z990"
-	depends on CRYPTO && ARCH_S390
+config CRYPTO_SHA1_S390
+	tristate "SHA1 digest algorithm (s390)"
+	depends on CRYPTO && S390
 	help
+	  This is the s390 hardware accelerated implementation of the
 	  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
 
 config CRYPTO_SHA256
@@ -55,6 +56,16 @@
 	  This version of SHA implements a 256 bit hash with 128 bits of
 	  security against collision attacks.
 
+config CRYPTO_SHA256_S390
+	tristate "SHA256 digest algorithm (s390)"
+	depends on CRYPTO && S390
+	help
+	  This is the s390 hardware accelerated implementation of the
+	  SHA256 secure hash standard (DFIPS 180-2).
+
+	  This version of SHA implements a 256 bit hash with 128 bits of
+	  security against collision attacks.
+
 config CRYPTO_SHA512
 	tristate "SHA384 and SHA512 digest algorithms"
 	depends on CRYPTO
@@ -98,9 +109,9 @@
 	help
 	  DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
 
-config CRYPTO_DES_Z990
-	tristate "DES and Triple DES cipher algorithms for IBM zSeries z990"
-	depends on CRYPTO && ARCH_S390
+config CRYPTO_DES_S390
+	tristate "DES and Triple DES cipher algorithms (s390)"
+	depends on CRYPTO && S390
 	help
 	  DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
 
@@ -204,6 +215,26 @@
 
 	  See <http://csrc.nist.gov/encryption/aes/> for more information.
 
+config CRYPTO_AES_S390
+	tristate "AES cipher algorithms (s390)"
+	depends on CRYPTO && S390
+	help
+	  This is the s390 hardware accelerated implementation of the
+	  AES cipher algorithms (FIPS-197). AES uses the Rijndael
+	  algorithm.
+
+	  Rijndael appears to be consistently a very good performer in
+	  both hardware and software across a wide range of computing
+	  environments regardless of its use in feedback or non-feedback
+	  modes. Its key setup time is excellent, and its key agility is
+	  good. Rijndael's very low memory requirements make it very well
+	  suited for restricted-space environments, in which it also
+	  demonstrates excellent performance. Rijndael's operations are
+	  among the easiest to defend against power and timing attacks.
+
+	  On s390 the System z9-109 currently only supports the key size
+	  of 128 bit.
+
 config CRYPTO_CAST5
 	tristate "CAST5 (CAST-128) cipher algorithm"
 	depends on CRYPTO
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 53f4ee8..49e344f 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -805,6 +805,8 @@
 		//AES
 		test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
 		test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
+		test_cipher ("aes", MODE_CBC, ENCRYPT, aes_cbc_enc_tv_template, AES_CBC_ENC_TEST_VECTORS);
+		test_cipher ("aes", MODE_CBC, DECRYPT, aes_cbc_dec_tv_template, AES_CBC_DEC_TEST_VECTORS);
 
 		//CAST5
 		test_cipher ("cast5", MODE_ECB, ENCRYPT, cast5_enc_tv_template, CAST5_ENC_TEST_VECTORS);
@@ -910,6 +912,8 @@
 	case 10:
 		test_cipher ("aes", MODE_ECB, ENCRYPT, aes_enc_tv_template, AES_ENC_TEST_VECTORS);
 		test_cipher ("aes", MODE_ECB, DECRYPT, aes_dec_tv_template, AES_DEC_TEST_VECTORS);
+		test_cipher ("aes", MODE_CBC, ENCRYPT, aes_cbc_enc_tv_template, AES_CBC_ENC_TEST_VECTORS);
+		test_cipher ("aes", MODE_CBC, DECRYPT, aes_cbc_dec_tv_template, AES_CBC_DEC_TEST_VECTORS);
 		break;
 
 	case 11:
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index 522ffd4..733d07e 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -1836,6 +1836,8 @@
  */
 #define AES_ENC_TEST_VECTORS 3
 #define AES_DEC_TEST_VECTORS 3
+#define AES_CBC_ENC_TEST_VECTORS 2
+#define AES_CBC_DEC_TEST_VECTORS 2
 
 static struct cipher_testvec aes_enc_tv_template[] = {
 	{ /* From FIPS-197 */
@@ -1911,6 +1913,68 @@
 	},
 };
 
+static struct cipher_testvec aes_cbc_enc_tv_template[] = {
+	{ /* From RFC 3602 */
+		.key    = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
+			    0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
+		.klen   = 16,
+		.iv	= { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
+			    0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
+		.input	= { "Single block msg" },
+		.ilen   = 16,
+		.result = { 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8,
+			    0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a },
+		.rlen   = 16,
+	}, {
+		.key    = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
+			    0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
+		.klen   = 16,
+		.iv     = { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
+			    0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
+		.input  = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+			    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+			    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+		.ilen   = 32,
+		.result = { 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a,
+			    0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,
+			    0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
+			    0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 },
+		.rlen   = 32,
+	},
+};
+
+static struct cipher_testvec aes_cbc_dec_tv_template[] = {
+	{ /* From RFC 3602 */
+		.key    = { 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
+			    0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06 },
+		.klen   = 16,
+		.iv     = { 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
+			    0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41 },
+		.input  = { 0xe3, 0x53, 0x77, 0x9c, 0x10, 0x79, 0xae, 0xb8,
+			    0x27, 0x08, 0x94, 0x2d, 0xbe, 0x77, 0x18, 0x1a },
+		.ilen   = 16,
+		.result = { "Single block msg" },
+		.rlen   = 16,
+	}, {
+		.key    = { 0xc2, 0x86, 0x69, 0x6d, 0x88, 0x7c, 0x9a, 0xa0,
+			    0x61, 0x1b, 0xbb, 0x3e, 0x20, 0x25, 0xa4, 0x5a },
+		.klen   = 16,
+		.iv     = { 0x56, 0x2e, 0x17, 0x99, 0x6d, 0x09, 0x3d, 0x28,
+			    0xdd, 0xb3, 0xba, 0x69, 0x5a, 0x2e, 0x6f, 0x58 },
+		.input  = { 0xd2, 0x96, 0xcd, 0x94, 0xc2, 0xcc, 0xcf, 0x8a,
+			    0x3a, 0x86, 0x30, 0x28, 0xb5, 0xe1, 0xdc, 0x0a,
+			    0x75, 0x86, 0x60, 0x2d, 0x25, 0x3c, 0xff, 0xf9,
+			    0x1b, 0x82, 0x66, 0xbe, 0xa6, 0xd6, 0x1a, 0xb1 },
+		.ilen   = 32,
+		.result = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+			    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+			    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+		.rlen   = 32,
+	},
+};
+
 /* Cast5 test vectors from RFC 2144 */
 #define CAST5_ENC_TEST_VECTORS	3
 #define CAST5_DEC_TEST_VECTORS	3
diff --git a/drivers/Makefile b/drivers/Makefile
index fac1e16..7fc3f0f 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -5,7 +5,7 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-obj-$(CONFIG_PCI)		+= pci/ usb/
+obj-$(CONFIG_PCI)		+= pci/
 obj-$(CONFIG_PARISC)		+= parisc/
 obj-$(CONFIG_RAPIDIO)		+= rapidio/
 obj-y				+= video/
@@ -13,6 +13,7 @@
 # PnP must come after ACPI since it will eventually need to check if acpi
 # was used and do nothing if so
 obj-$(CONFIG_PNP)		+= pnp/
+obj-$(CONFIG_ARM_AMBA)		+= amba/
 
 # char/ comes before serial/ etc so that the VT console is the boot-time
 # default.
@@ -49,6 +50,7 @@
 obj-$(CONFIG_PARIDE) 		+= block/paride/
 obj-$(CONFIG_TC)		+= tc/
 obj-$(CONFIG_USB)		+= usb/
+obj-$(CONFIG_PCI)		+= usb/
 obj-$(CONFIG_USB_GADGET)	+= usb/gadget/
 obj-$(CONFIG_GAMEPORT)		+= input/gameport/
 obj-$(CONFIG_INPUT)		+= input/
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index 4b65f74..ce074f6 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -129,19 +129,6 @@
 #define MAJOR_NR	MFM_ACORN_MAJOR
 #define QUEUE (mfm_queue)
 #define CURRENT elv_next_request(mfm_queue)
-/*
- * This sort of stuff should be in a header file shared with ide.c, hd.c, xd.c etc
- */
-#ifndef HDIO_GETGEO
-#define HDIO_GETGEO 0x301
-struct hd_geometry {
-	unsigned char heads;
-	unsigned char sectors;
-	unsigned short cylinders;
-	unsigned long start;
-};
-#endif
-
 
 /*
  * Configuration section
@@ -1153,22 +1140,13 @@
  * The 'front' end of the mfm driver follows...
  */
 
-static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg)
+static int mfm_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	struct mfm_info *p = inode->i_bdev->bd_disk->private_data;
-	struct hd_geometry *geo = (struct hd_geometry *) arg;
-	if (cmd != HDIO_GETGEO)
-		return -EINVAL;
-	if (!arg)
-		return -EINVAL;
-	if (put_user (p->heads, &geo->heads))
-		return -EFAULT;
-	if (put_user (p->sectors, &geo->sectors))
-		return -EFAULT;
-	if (put_user (p->cylinders, &geo->cylinders))
-		return -EFAULT;
-	if (put_user (get_start_sect(inode->i_bdev), &geo->start))
-		return -EFAULT;
+	struct mfm_info *p = bdev->bd_disk->private_data;
+
+	geo->heads = p->heads;
+	geo->sectors = p->sectors;
+	geo->cylinders = p->cylinders;
 	return 0;
 }
 
@@ -1219,7 +1197,7 @@
 static struct block_device_operations mfm_fops =
 {
 	.owner		= THIS_MODULE,
-	.ioctl		= mfm_ioctl,
+	.getgeo		= mfm_getgeo,
 };
 
 /*
diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
index e26f007..9b49f31 100644
--- a/drivers/acorn/char/pcf8583.c
+++ b/drivers/acorn/char/pcf8583.c
@@ -257,9 +257,10 @@
 }
 
 static struct i2c_driver pcf8583_driver = {
-	.name		= "PCF8583",
+	.driver = {
+		.name	= "PCF8583",
+	},
 	.id		= I2C_DRIVERID_PCF8583,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= pcf8583_probe,
 	.detach_client	= pcf8583_detach,
 	.command	= pcf8583_command
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index fe1e812..6d61945 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -168,7 +168,6 @@
 config ACPI_ASUS
         tristate "ASUS/Medion Laptop Extras"
 	depends on X86
-	default y
         ---help---
           This driver provides support for extra features of ACPI-compatible
           ASUS laptops. As some of Medion laptops are made by ASUS, it may also
@@ -197,7 +196,6 @@
 config ACPI_IBM
 	tristate "IBM ThinkPad Laptop Extras"
 	depends on X86
-	default y
 	---help---
 	  This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
 	  support for Fn-Fx key combinations, Bluetooth control, video
@@ -210,7 +208,6 @@
 config ACPI_TOSHIBA
 	tristate "Toshiba Laptop Extras"
 	depends on X86
-	default y
 	---help---
 	  This driver adds support for access to certain system settings
 	  on "legacy free" Toshiba laptops.  These laptops can be recognized by
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index a182434..5984b4f 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -16,7 +16,7 @@
 # ACPI Boot-Time Table Parsing
 #
 obj-y				+= tables.o
-obj-y				+= blacklist.o
+obj-$(CONFIG_X86)		+= blacklist.o
 
 #
 # ACPI Core Subsystem (Interpreter)
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 27ec12c..b69a8ca 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -172,21 +172,21 @@
 			if (ACPI_FAILURE(status) || !device) {
 				result = container_device_add(&device, handle);
 				if (!result)
-					kobject_hotplug(&device->kobj,
-							KOBJ_ONLINE);
+					kobject_uevent(&device->kobj,
+						       KOBJ_ONLINE);
 				else
 					printk("Failed to add container\n");
 			}
 		} else {
 			if (ACPI_SUCCESS(status)) {
 				/* device exist and this is a remove request */
-				kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+				kobject_uevent(&device->kobj, KOBJ_OFFLINE);
 			}
 		}
 		break;
 	case ACPI_NOTIFY_EJECT_REQUEST:
 		if (!acpi_bus_get_device(handle, &device) && device) {
-			kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+			kobject_uevent(&device->kobj, KOBJ_OFFLINE);
 		}
 		break;
 	default:
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index e3cd0b1..20c9a37 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -204,11 +204,13 @@
 
 	return AE_OK;
 }
+EXPORT_SYMBOL_GPL(acpi_os_map_memory);
 
 void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
 {
 	iounmap(virt);
 }
+EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
 
 #ifdef ACPI_FUTURE_USAGE
 acpi_status
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 82292b7..78927c0 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -316,7 +316,7 @@
 	if (!link || !irq)
 		return_VALUE(-EINVAL);
 
-	resource = kmalloc(sizeof(*resource) + 1, GFP_KERNEL);
+	resource = kmalloc(sizeof(*resource) + 1, GFP_ATOMIC);
 	if (!resource)
 		return_VALUE(-ENOMEM);
 
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 4217925..1278aca 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -543,6 +543,8 @@
 	return_VALUE(0);
 }
 
+static void *processor_device_array[NR_CPUS];
+
 static int acpi_processor_start(struct acpi_device *device)
 {
 	int result = 0;
@@ -561,6 +563,19 @@
 
 	BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
 
+	/*
+	 * Buggy BIOS check
+	 * ACPI id of processors can be reported wrongly by the BIOS.
+	 * Don't trust it blindly
+	 */
+	if (processor_device_array[pr->id] != NULL &&
+	    processor_device_array[pr->id] != (void *)device) {
+		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "BIOS reporting wrong ACPI id"
+			"for the processor\n"));
+		return_VALUE(-ENODEV);
+	}
+	processor_device_array[pr->id] = (void *)device;
+
 	processors[pr->id] = pr;
 
 	result = acpi_processor_add_fs(device);
@@ -733,7 +748,7 @@
 		return_VALUE(-ENODEV);
 
 	if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
-		kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE);
+		kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
 	}
 	return_VALUE(0);
 }
@@ -773,13 +788,13 @@
 		}
 
 		if (pr->id >= 0 && (pr->id < NR_CPUS)) {
-			kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+			kobject_uevent(&device->kobj, KOBJ_OFFLINE);
 			break;
 		}
 
 		result = acpi_processor_start(device);
 		if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
-			kobject_hotplug(&device->kobj, KOBJ_ONLINE);
+			kobject_uevent(&device->kobj, KOBJ_ONLINE);
 		} else {
 			ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
 					  "Device [%s] failed to start\n",
@@ -803,7 +818,7 @@
 		}
 
 		if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
-			kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
+			kobject_uevent(&device->kobj, KOBJ_OFFLINE);
 		break;
 	default:
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 70d8a6e..807b0df 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -169,15 +169,11 @@
 
 static void acpi_safe_halt(void)
 {
-	int polling = test_thread_flag(TIF_POLLING_NRFLAG);
-	if (polling) {
-		clear_thread_flag(TIF_POLLING_NRFLAG);
-		smp_mb__after_clear_bit();
-	}
+	clear_thread_flag(TIF_POLLING_NRFLAG);
+	smp_mb__after_clear_bit();
 	if (!need_resched())
 		safe_halt();
-	if (polling)
-		set_thread_flag(TIF_POLLING_NRFLAG);
+	set_thread_flag(TIF_POLLING_NRFLAG);
 }
 
 static atomic_t c3_cpu_count;
@@ -278,6 +274,17 @@
 		}
 	}
 
+#ifdef CONFIG_HOTPLUG_CPU
+	/*
+	 * Check for P_LVL2_UP flag before entering C2 and above on
+	 * an SMP system. We do it here instead of doing it at _CST/P_LVL
+	 * detection phase, to work cleanly with logical CPU hotplug.
+	 */
+	if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && 
+	    !pr->flags.has_cst && !acpi_fadt.plvl2_up)
+		cx = &pr->power.states[ACPI_STATE_C1];
+#endif
+
 	cx->usage++;
 
 	/*
@@ -285,6 +292,16 @@
 	 * ------
 	 * Invoke the current Cx state to put the processor to sleep.
 	 */
+	if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) {
+		clear_thread_flag(TIF_POLLING_NRFLAG);
+		smp_mb__after_clear_bit();
+		if (need_resched()) {
+			set_thread_flag(TIF_POLLING_NRFLAG);
+			local_irq_enable();
+			return;
+		}
+	}
+
 	switch (cx->type) {
 
 	case ACPI_STATE_C1:
@@ -317,6 +334,7 @@
 		t2 = inl(acpi_fadt.xpm_tmr_blk.address);
 		/* Re-enable interrupts */
 		local_irq_enable();
+		set_thread_flag(TIF_POLLING_NRFLAG);
 		/* Compute time (ticks) that we were actually asleep */
 		sleep_ticks =
 		    ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
@@ -356,6 +374,7 @@
 
 		/* Re-enable interrupts */
 		local_irq_enable();
+		set_thread_flag(TIF_POLLING_NRFLAG);
 		/* Compute time (ticks) that we were actually asleep */
 		sleep_ticks =
 		    ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
@@ -368,6 +387,15 @@
 
 	next_state = pr->power.state;
 
+#ifdef CONFIG_HOTPLUG_CPU
+	/* Don't do promotion/demotion */
+	if ((cx->type == ACPI_STATE_C1) && (num_online_cpus() > 1) &&
+	    !pr->flags.has_cst && !acpi_fadt.plvl2_up) {
+		next_state = cx;
+		goto end;
+	}
+#endif
+
 	/*
 	 * Promotion?
 	 * ----------
@@ -534,6 +562,15 @@
 	pr->power.states[ACPI_STATE_C0].valid = 1;
 	pr->power.states[ACPI_STATE_C1].valid = 1;
 
+#ifndef CONFIG_HOTPLUG_CPU
+	/*
+	 * Check for P_LVL2_UP flag before entering C2 and above on
+	 * an SMP system. 
+	 */
+	if ((num_online_cpus() > 1) && !acpi_fadt.plvl2_up)
+		return_VALUE(-ENODEV);
+#endif
+
 	/* determine C2 and C3 address from pblk */
 	pr->power.states[ACPI_STATE_C2].address = pr->pblk + 4;
 	pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5;
@@ -690,7 +727,7 @@
 
 	/* Validate number of power states discovered */
 	if (pr->power.count < 2)
-		status = -ENODEV;
+		status = -EFAULT;
 
       end:
 	acpi_os_free(buffer.pointer);
@@ -841,11 +878,11 @@
 	 * this function */
 
 	result = acpi_processor_get_power_info_cst(pr);
-	if ((result) || (acpi_processor_power_verify(pr) < 2)) {
+	if (result == -ENODEV)
 		result = acpi_processor_get_power_info_fadt(pr);
-		if ((result) || (acpi_processor_power_verify(pr) < 2))
-			result = acpi_processor_get_power_info_default_c1(pr);
-	}
+
+	if ((result) || (acpi_processor_power_verify(pr) < 2))
+		result = acpi_processor_get_power_info_default_c1(pr);
 
 	/*
 	 * Set Default Policy
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 37528c3..dc9817c 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -101,11 +101,9 @@
 static int cpu_has_cpufreq(unsigned int cpu)
 {
 	struct cpufreq_policy policy;
-	if (!acpi_thermal_cpufreq_is_init)
-		return -ENODEV;
-	if (!cpufreq_get_policy(&policy, cpu))
-		return -ENODEV;
-	return 0;
+	if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu))
+		return 0;
+	return 1;
 }
 
 static int acpi_thermal_cpufreq_increase(unsigned int cpu)
@@ -127,13 +125,13 @@
 	if (!cpu_has_cpufreq(cpu))
 		return -ENODEV;
 
-	if (cpufreq_thermal_reduction_pctg[cpu] >= 20) {
+	if (cpufreq_thermal_reduction_pctg[cpu] > 20)
 		cpufreq_thermal_reduction_pctg[cpu] -= 20;
-		cpufreq_update_policy(cpu);
-		return 0;
-	}
-
-	return -ERANGE;
+	else
+		cpufreq_thermal_reduction_pctg[cpu] = 0;
+	cpufreq_update_policy(cpu);
+	/* We reached max freq again and can leave passive mode */
+	return !cpufreq_thermal_reduction_pctg[cpu];
 }
 
 static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb,
@@ -200,7 +198,7 @@
 	int result = 0;
 	struct acpi_processor *pr = NULL;
 	struct acpi_device *device = NULL;
-	int tx = 0;
+	int tx = 0, max_tx_px = 0;
 
 	ACPI_FUNCTION_TRACE("acpi_processor_set_thermal_limit");
 
@@ -259,19 +257,27 @@
 		/* if going down: T-states first, P-states later */
 
 		if (pr->flags.throttling) {
-			if (tx == 0)
+			if (tx == 0) {
+				max_tx_px = 1;
 				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 						  "At minimum throttling state\n"));
-			else {
+			} else {
 				tx--;
 				goto end;
 			}
 		}
 
 		result = acpi_thermal_cpufreq_decrease(pr->id);
-		if (result == -ERANGE)
+		if (result) {
+			/*
+			 * We only could get -ERANGE, 1 or 0.
+			 * In the first two cases we reached max freq again.
+			 */
 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 					  "At minimum performance state\n"));
+			max_tx_px = 1;
+		} else
+			max_tx_px = 0;
 
 		break;
 	}
@@ -290,8 +296,10 @@
 				  pr->limit.thermal.px, pr->limit.thermal.tx));
 	} else
 		result = 0;
-
-	return_VALUE(result);
+	if (max_tx_px)
+		return_VALUE(1);
+	else
+		return_VALUE(result);
 }
 
 int acpi_processor_get_limit_info(struct acpi_processor *pr)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 23e2c69..3b26a71 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -78,7 +78,7 @@
 	.release = acpi_device_release,
 };
 
-static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
+static int namespace_uevent(struct kset *kset, struct kobject *kobj,
 			     char **envp, int num_envp, char *buffer,
 			     int buffer_size)
 {
@@ -89,8 +89,8 @@
 	if (!dev->driver)
 		return 0;
 
-	if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
-				"PHYSDEVDRIVER=%s", dev->driver->name))
+	if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
+			   "PHYSDEVDRIVER=%s", dev->driver->name))
 		return -ENOMEM;
 
 	envp[i] = NULL;
@@ -98,8 +98,8 @@
 	return 0;
 }
 
-static struct kset_hotplug_ops namespace_hotplug_ops = {
-	.hotplug = &namespace_hotplug,
+static struct kset_uevent_ops namespace_uevent_ops = {
+	.uevent = &namespace_uevent,
 };
 
 static struct kset acpi_namespace_kset = {
@@ -108,7 +108,7 @@
 		 },
 	.subsys = &acpi_subsys,
 	.ktype = &ktype_acpi_ns,
-	.hotplug_ops = &namespace_hotplug_ops,
+	.uevent_ops = &namespace_uevent_ops,
 };
 
 static void acpi_device_register(struct acpi_device *device,
@@ -347,7 +347,7 @@
 }
 
 /* --------------------------------------------------------------------------
-		ACPI hotplug sysfs device file support
+		ACPI sysfs device file support
    -------------------------------------------------------------------------- */
 static ssize_t acpi_eject_store(struct acpi_device *device,
 				const char *buf, size_t count);
@@ -475,8 +475,10 @@
 static DECLARE_MUTEX(acpi_bus_drivers_lock);
 
 /**
- * acpi_bus_match 
- * --------------
+ * acpi_bus_match - match device IDs to driver's supported IDs
+ * @device: the device that we are trying to match to a driver
+ * @driver: driver whose device id table is being checked
+ *
  * Checks the device's hardware (_HID) or compatible (_CID) ids to see if it
  * matches the specified driver's criteria.
  */
@@ -489,8 +491,10 @@
 }
 
 /**
- * acpi_bus_driver_init 
- * --------------------
+ * acpi_bus_driver_init - add a device to a driver
+ * @device: the device to add and initialize
+ * @driver: driver for the device
+ *
  * Used to initialize a device via its device driver.  Called whenever a 
  * driver is bound to a device.  Invokes the driver's add() and start() ops.
  */
@@ -603,8 +607,9 @@
 }
 
 /**
- * acpi_bus_register_driver 
- * ------------------------ 
+ * acpi_bus_register_driver - register a driver with the ACPI bus
+ * @driver: driver being registered
+ *
  * Registers a driver with the ACPI bus.  Searches the namespace for all
  * devices that match the driver's criteria and binds.  Returns the
  * number of devices that were claimed by the driver, or a negative
@@ -633,8 +638,9 @@
 EXPORT_SYMBOL(acpi_bus_register_driver);
 
 /**
- * acpi_bus_unregister_driver 
- * --------------------------
+ * acpi_bus_unregister_driver - unregisters a driver with the APIC bus
+ * @driver: driver to unregister
+ *
  * Unregisters a driver with the ACPI bus.  Searches the namespace for all
  * devices that match the driver's criteria and unbinds.
  */
@@ -660,8 +666,9 @@
 EXPORT_SYMBOL(acpi_bus_unregister_driver);
 
 /**
- * acpi_bus_find_driver 
- * --------------------
+ * acpi_bus_find_driver - check if there is a driver installed for the device
+ * @device: device that we are trying to find a supporting driver for
+ *
  * Parses the list of registered drivers looking for a driver applicable for
  * the specified device.
  */
@@ -1110,7 +1117,7 @@
 	 *
 	 * TBD: Assumes LDM provides driver hot-plug capability.
 	 */
-	result = acpi_bus_find_driver(device);
+	acpi_bus_find_driver(device);
 
       end:
 	if (!result)
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index a2bf25b..31d4f3f 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -37,7 +37,7 @@
 
 #define PREFIX			"ACPI: "
 
-#define ACPI_MAX_TABLES		256
+#define ACPI_MAX_TABLES		128
 
 static char *acpi_table_signatures[ACPI_TABLE_COUNT] = {
 	[ACPI_TABLE_UNKNOWN] = "????",
@@ -74,7 +74,7 @@
 static unsigned long sdt_pa;	/* Physical Address */
 static unsigned long sdt_count;	/* Table count */
 
-static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES];
+static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata;
 
 void acpi_table_print(struct acpi_table_header *header, unsigned long phys_addr)
 {
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index a24847c0..19f3ea4 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -72,7 +72,7 @@
 #define _COMPONENT		ACPI_THERMAL_COMPONENT
 ACPI_MODULE_NAME("acpi_thermal")
 
-    MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME);
 MODULE_LICENSE("GPL");
 
@@ -517,9 +517,9 @@
 	return_VALUE(0);
 }
 
-static int acpi_thermal_passive(struct acpi_thermal *tz)
+static void acpi_thermal_passive(struct acpi_thermal *tz)
 {
-	int result = 0;
+	int result = 1;
 	struct acpi_thermal_passive *passive = NULL;
 	int trend = 0;
 	int i = 0;
@@ -527,7 +527,7 @@
 	ACPI_FUNCTION_TRACE("acpi_thermal_passive");
 
 	if (!tz || !tz->trips.passive.flags.valid)
-		return_VALUE(-EINVAL);
+		return;
 
 	passive = &(tz->trips.passive);
 
@@ -547,7 +547,7 @@
 				  trend, passive->tc1, tz->temperature,
 				  tz->last_temperature, passive->tc2,
 				  tz->temperature, passive->temperature));
-		tz->trips.passive.flags.enabled = 1;
+		passive->flags.enabled = 1;
 		/* Heating up? */
 		if (trend > 0)
 			for (i = 0; i < passive->devices.count; i++)
@@ -556,12 +556,32 @@
 								 handles[i],
 								 ACPI_PROCESSOR_LIMIT_INCREMENT);
 		/* Cooling off? */
-		else if (trend < 0)
+		else if (trend < 0) {
 			for (i = 0; i < passive->devices.count; i++)
-				acpi_processor_set_thermal_limit(passive->
-								 devices.
-								 handles[i],
-								 ACPI_PROCESSOR_LIMIT_DECREMENT);
+				/*
+				 * assume that we are on highest
+				 * freq/lowest thrott and can leave
+				 * passive mode, even in error case
+				 */
+				if (!acpi_processor_set_thermal_limit
+				    (passive->devices.handles[i],
+				     ACPI_PROCESSOR_LIMIT_DECREMENT))
+					result = 0;
+			/*
+			 * Leave cooling mode, even if the temp might
+			 * higher than trip point This is because some
+			 * machines might have long thermal polling
+			 * frequencies (tsp) defined. We will fall back
+			 * into passive mode in next cycle (probably quicker)
+			 */
+			if (result) {
+				passive->flags.enabled = 0;
+				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+						  "Disabling passive cooling, still above threshold,"
+						  " but we are cooling down\n"));
+			}
+		}
+		return;
 	}
 
 	/*
@@ -571,23 +591,21 @@
 	 * and avoid thrashing around the passive trip point.  Note that we
 	 * assume symmetry.
 	 */
-	else if (tz->trips.passive.flags.enabled) {
-		for (i = 0; i < passive->devices.count; i++)
-			result =
-			    acpi_processor_set_thermal_limit(passive->devices.
-							     handles[i],
-							     ACPI_PROCESSOR_LIMIT_DECREMENT);
-		if (result == 1) {
-			tz->trips.passive.flags.enabled = 0;
-			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-					  "Disabling passive cooling (zone is cool)\n"));
-		}
+	if (!passive->flags.enabled)
+		return;
+	for (i = 0; i < passive->devices.count; i++)
+		if (!acpi_processor_set_thermal_limit
+		    (passive->devices.handles[i],
+		     ACPI_PROCESSOR_LIMIT_DECREMENT))
+			result = 0;
+	if (result) {
+		passive->flags.enabled = 0;
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				  "Disabling passive cooling (zone is cool)\n"));
 	}
-
-	return_VALUE(0);
 }
 
-static int acpi_thermal_active(struct acpi_thermal *tz)
+static void acpi_thermal_active(struct acpi_thermal *tz)
 {
 	int result = 0;
 	struct acpi_thermal_active *active = NULL;
@@ -598,74 +616,66 @@
 	ACPI_FUNCTION_TRACE("acpi_thermal_active");
 
 	if (!tz)
-		return_VALUE(-EINVAL);
+		return;
 
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
-
 		active = &(tz->trips.active[i]);
 		if (!active || !active->flags.valid)
 			break;
-
-		/*
-		 * Above Threshold?
-		 * ----------------
-		 * If not already enabled, turn ON all cooling devices
-		 * associated with this active threshold.
-		 */
 		if (tz->temperature >= active->temperature) {
+			/*
+			 * Above Threshold?
+			 * ----------------
+			 * If not already enabled, turn ON all cooling devices
+			 * associated with this active threshold.
+			 */
 			if (active->temperature > maxtemp)
-				tz->state.active_index = i, maxtemp =
-				    active->temperature;
-			if (!active->flags.enabled) {
-				for (j = 0; j < active->devices.count; j++) {
-					result =
-					    acpi_bus_set_power(active->devices.
-							       handles[j],
-							       ACPI_STATE_D0);
-					if (result) {
-						ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-								  "Unable to turn cooling device [%p] 'on'\n",
-								  active->
-								  devices.
-								  handles[j]));
-						continue;
-					}
-					active->flags.enabled = 1;
-					ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-							  "Cooling device [%p] now 'on'\n",
+				tz->state.active_index = i;
+			maxtemp = active->temperature;
+			if (active->flags.enabled)
+				continue;
+			for (j = 0; j < active->devices.count; j++) {
+				result =
+				    acpi_bus_set_power(active->devices.
+						       handles[j],
+						       ACPI_STATE_D0);
+				if (result) {
+					ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+							  "Unable to turn cooling device [%p] 'on'\n",
 							  active->devices.
 							  handles[j]));
+					continue;
 				}
+				active->flags.enabled = 1;
+				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+						  "Cooling device [%p] now 'on'\n",
+						  active->devices.handles[j]));
 			}
+			continue;
 		}
+		if (!active->flags.enabled)
+			continue;
 		/*
 		 * Below Threshold?
 		 * ----------------
 		 * Turn OFF all cooling devices associated with this
 		 * threshold.
 		 */
-		else if (active->flags.enabled) {
-			for (j = 0; j < active->devices.count; j++) {
-				result =
-				    acpi_bus_set_power(active->devices.
-						       handles[j],
-						       ACPI_STATE_D3);
-				if (result) {
-					ACPI_DEBUG_PRINT((ACPI_DB_WARN,
-							  "Unable to turn cooling device [%p] 'off'\n",
-							  active->devices.
-							  handles[j]));
-					continue;
-				}
-				active->flags.enabled = 0;
-				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-						  "Cooling device [%p] now 'off'\n",
+		for (j = 0; j < active->devices.count; j++) {
+			result = acpi_bus_set_power(active->devices.handles[j],
+						    ACPI_STATE_D3);
+			if (result) {
+				ACPI_DEBUG_PRINT((ACPI_DB_WARN,
+						  "Unable to turn cooling device [%p] 'off'\n",
 						  active->devices.handles[j]));
+				continue;
 			}
+			active->flags.enabled = 0;
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					  "Cooling device [%p] now 'off'\n",
+					  active->devices.handles[j]));
 		}
 	}
-
-	return_VALUE(0);
 }
 
 static void acpi_thermal_check(void *context);
@@ -744,15 +754,12 @@
 	 * Again, separated from the above two to allow independent policy
 	 * decisions.
 	 */
-	if (tz->trips.critical.flags.enabled)
-		tz->state.critical = 1;
-	if (tz->trips.hot.flags.enabled)
-		tz->state.hot = 1;
-	if (tz->trips.passive.flags.enabled)
-		tz->state.passive = 1;
+	tz->state.critical = tz->trips.critical.flags.enabled;
+	tz->state.hot = tz->trips.hot.flags.enabled;
+	tz->state.passive = tz->trips.passive.flags.enabled;
+	tz->state.active = 0;
 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
-		if (tz->trips.active[i].flags.enabled)
-			tz->state.active = 1;
+		tz->state.active |= tz->trips.active[i].flags.enabled;
 
 	/*
 	 * Calculate Sleep Time
diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c
index 0c5abc5..2ce872d 100644
--- a/drivers/acpi/utilities/utmisc.c
+++ b/drivers/acpi/utilities/utmisc.c
@@ -84,14 +84,14 @@
 
 	/* Find a free owner ID */
 
-	for (i = 0; i < 32; i++) {
-		if (!(acpi_gbl_owner_id_mask & (1 << i))) {
+	for (i = 0; i < 64; i++) {
+		if (!(acpi_gbl_owner_id_mask & (1ULL << i))) {
 			ACPI_DEBUG_PRINT((ACPI_DB_VALUES,
-					  "Current owner_id mask: %8.8X New ID: %2.2X\n",
+					  "Current owner_id mask: %16.16LX New ID: %2.2X\n",
 					  acpi_gbl_owner_id_mask,
 					  (unsigned int)(i + 1)));
 
-			acpi_gbl_owner_id_mask |= (1 << i);
+			acpi_gbl_owner_id_mask |= (1ULL << i);
 			*owner_id = (acpi_owner_id) (i + 1);
 			goto exit;
 		}
@@ -106,7 +106,7 @@
 	 */
 	*owner_id = 0;
 	status = AE_OWNER_ID_LIMIT;
-	ACPI_REPORT_ERROR(("Could not allocate new owner_id (32 max), AE_OWNER_ID_LIMIT\n"));
+	ACPI_REPORT_ERROR(("Could not allocate new owner_id (64 max), AE_OWNER_ID_LIMIT\n"));
 
       exit:
 	(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
@@ -123,7 +123,7 @@
  *              control method or unloading a table. Either way, we would
  *              ignore any error anyway.
  *
- * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 32
+ * DESCRIPTION: Release a table or method owner ID.  Valid IDs are 1 - 64
  *
  ******************************************************************************/
 
@@ -140,7 +140,7 @@
 
 	/* Zero is not a valid owner_iD */
 
-	if ((owner_id == 0) || (owner_id > 32)) {
+	if ((owner_id == 0) || (owner_id > 64)) {
 		ACPI_REPORT_ERROR(("Invalid owner_id: %2.2X\n", owner_id));
 		return_VOID;
 	}
@@ -158,8 +158,8 @@
 
 	/* Free the owner ID only if it is valid */
 
-	if (acpi_gbl_owner_id_mask & (1 << owner_id)) {
-		acpi_gbl_owner_id_mask ^= (1 << owner_id);
+	if (acpi_gbl_owner_id_mask & (1ULL << owner_id)) {
+		acpi_gbl_owner_id_mask ^= (1ULL << owner_id);
 	}
 
 	(void)acpi_ut_release_mutex(ACPI_MTX_CACHES);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index f051b15..d10668f 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -812,7 +812,7 @@
 
 	ACPI_FUNCTION_TRACE("acpi_video_device_write_brightness");
 
-	if (!dev || count + 1 > sizeof str)
+	if (!dev || !dev->brightness || count + 1 > sizeof str)
 		return_VALUE(-EINVAL);
 
 	if (copy_from_user(str, buffer, count))
diff --git a/drivers/amba/Makefile b/drivers/amba/Makefile
new file mode 100644
index 0000000..40fe740
--- /dev/null
+++ b/drivers/amba/Makefile
@@ -0,0 +1,2 @@
+obj-y		+= bus.o
+
diff --git a/arch/arm/common/amba.c b/drivers/amba/bus.c
similarity index 97%
rename from arch/arm/common/amba.c
rename to drivers/amba/bus.c
index e101311..1bbdd16 100644
--- a/arch/arm/common/amba.c
+++ b/drivers/amba/bus.c
@@ -12,10 +12,10 @@
 #include <linux/device.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/amba/bus.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/hardware/amba.h>
 #include <asm/sizes.h>
 
 #define to_amba_device(d)	container_of(d, struct amba_device, dev)
@@ -45,7 +45,7 @@
 }
 
 #ifdef CONFIG_HOTPLUG
-static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
+static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
 {
 	struct amba_device *pcdev = to_amba_device(dev);
 
@@ -58,7 +58,7 @@
 	return 0;
 }
 #else
-#define amba_hotplug NULL
+#define amba_uevent NULL
 #endif
 
 static int amba_suspend(struct device *dev, pm_message_t state)
@@ -88,7 +88,7 @@
 static struct bus_type amba_bustype = {
 	.name		= "amba",
 	.match		= amba_match,
-	.hotplug	= amba_hotplug,
+	.uevent		= amba_uevent,
 	.suspend	= amba_suspend,
 	.resume		= amba_resume,
 };
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index 489de81..01a9f1c 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -5,6 +5,13 @@
 menu "ATM drivers"
 	depends on NETDEVICES && ATM
 
+config ATM_DUMMY
+	tristate "Dummy ATM driver"
+	depends on ATM
+	help
+	  Dummy ATM driver. Useful for proxy signalling, testing,
+	  and development.  If unsure, say N.
+
 config ATM_TCP
 	tristate "ATM over TCP"
 	depends on INET && ATM
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile
index 5b77188..b5077ce 100644
--- a/drivers/atm/Makefile
+++ b/drivers/atm/Makefile
@@ -31,6 +31,7 @@
   obj-$(CONFIG_ATM_IDT77252)	+= suni.o
 endif
 
+obj-$(CONFIG_ATM_DUMMY)		+= adummy.o
 obj-$(CONFIG_ATM_TCP)		+= atmtcp.o
 obj-$(CONFIG_ATM_FIRESTREAM)	+= firestream.o
 obj-$(CONFIG_ATM_LANAI)		+= lanai.o
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
new file mode 100644
index 0000000..d1387cf
--- /dev/null
+++ b/drivers/atm/adummy.c
@@ -0,0 +1,168 @@
+/*
+ * adummy.c: a dummy ATM driver
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/uaccess.h>
+
+#include <linux/atmdev.h>
+#include <linux/atm.h>
+#include <linux/sonet.h>
+
+/* version definition */
+
+#define DRV_VERSION "1.0"
+
+#define DEV_LABEL "adummy"
+
+#define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data)
+
+struct adummy_dev {
+	struct atm_dev *atm_dev;
+
+	struct list_head entry;
+};
+
+/* globals */
+
+static LIST_HEAD(adummy_devs);
+
+static int __init
+adummy_start(struct atm_dev *dev)
+{
+	dev->ci_range.vpi_bits = 4;
+	dev->ci_range.vci_bits = 12;
+
+	return 0;
+}
+
+static int
+adummy_open(struct atm_vcc *vcc)
+{
+	short vpi = vcc->vpi;
+	int vci = vcc->vci;
+
+	if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
+		return 0;
+
+	set_bit(ATM_VF_ADDR, &vcc->flags);
+	set_bit(ATM_VF_READY, &vcc->flags);
+
+	return 0;
+}
+
+static void
+adummy_close(struct atm_vcc *vcc)
+{
+	clear_bit(ATM_VF_READY, &vcc->flags);
+	clear_bit(ATM_VF_ADDR, &vcc->flags);
+}
+
+static int
+adummy_send(struct atm_vcc *vcc, struct sk_buff *skb)
+{
+	if (vcc->pop)
+		vcc->pop(vcc, skb);
+	else
+		dev_kfree_skb_any(skb);
+	atomic_inc(&vcc->stats->tx);
+
+	return 0;
+}
+
+static int
+adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
+{
+	int left = *pos;
+
+	if (!left--)
+		return sprintf(page, "version %s\n", DRV_VERSION);
+
+	return 0;
+}
+
+static struct atmdev_ops adummy_ops =
+{
+	.open =		adummy_open,
+	.close =	adummy_close,	
+	.send =		adummy_send,
+	.proc_read =	adummy_proc_read,
+	.owner =	THIS_MODULE
+};
+
+static int __init adummy_init(void)
+{
+	struct atm_dev *atm_dev;
+	struct adummy_dev *adummy_dev;
+	int err = 0;
+
+	printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
+
+	adummy_dev = (struct adummy_dev *) kmalloc(sizeof(struct adummy_dev),
+						   GFP_KERNEL);
+	if (!adummy_dev) {
+		printk(KERN_ERR DEV_LABEL ": kmalloc() failed\n");
+		err = -ENOMEM;
+		goto out;
+	}
+	memset(adummy_dev, 0, sizeof(struct adummy_dev));
+
+	atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL);
+	if (!atm_dev) {
+		printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
+		err = -ENODEV;
+		goto out_kfree;
+	}
+
+	adummy_dev->atm_dev = atm_dev;
+	atm_dev->dev_data = adummy_dev;
+
+	if (adummy_start(atm_dev)) {
+		printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n");
+		err = -ENODEV;
+		goto out_unregister;
+	}
+
+	list_add(&adummy_dev->entry, &adummy_devs);
+out:
+	return err;
+
+out_unregister:
+	atm_dev_deregister(atm_dev);
+out_kfree:
+	kfree(adummy_dev);
+	goto out;
+}
+
+static void __exit adummy_cleanup(void)
+{
+	struct adummy_dev *adummy_dev, *next;
+
+	list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) {
+		atm_dev_deregister(adummy_dev->atm_dev);
+		kfree(adummy_dev);
+	}
+}
+
+module_init(adummy_init);
+module_exit(adummy_cleanup);
+
+MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
+MODULE_DESCRIPTION("dummy ATM driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/atm/atmdev_init.c b/drivers/atm/atmdev_init.c
deleted file mode 100644
index 0e09e5c..0000000
--- a/drivers/atm/atmdev_init.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* drivers/atm/atmdev_init.c - ATM device driver initialization */
- 
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
- 
-
-#include <linux/config.h>
-#include <linux/init.h>
-
-
-#ifdef CONFIG_ATM_ZATM
-extern int zatm_detect(void);
-#endif
-#ifdef CONFIG_ATM_AMBASSADOR
-extern int amb_detect(void);
-#endif
-#ifdef CONFIG_ATM_HORIZON
-extern int hrz_detect(void);
-#endif
-#ifdef CONFIG_ATM_FORE200E
-extern int fore200e_detect(void);
-#endif
-#ifdef CONFIG_ATM_LANAI
-extern int lanai_detect(void);
-#endif
-
-
-/*
- * For historical reasons, atmdev_init returns the number of devices found.
- * Note that some detections may not go via atmdev_init (e.g. eni.c), so this
- * number is meaningless.
- */
-
-int __init atmdev_init(void)
-{
-	int devs;
-
-	devs = 0;
-#ifdef CONFIG_ATM_ZATM
-	devs += zatm_detect();
-#endif
-#ifdef CONFIG_ATM_AMBASSADOR
-	devs += amb_detect();
-#endif
-#ifdef CONFIG_ATM_HORIZON
-	devs += hrz_detect();
-#endif
-#ifdef CONFIG_ATM_FORE200E
-	devs += fore200e_detect();
-#endif
-#ifdef CONFIG_ATM_LANAI
-	devs += lanai_detect();
-#endif
-	return devs;
-}
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
index 57f1810..fc518d8 100644
--- a/drivers/atm/atmtcp.c
+++ b/drivers/atm/atmtcp.c
@@ -246,10 +246,6 @@
 {
 	struct atm_dev *atmtcp_dev;
 	struct atmtcp_dev_data *dev_data;
-	struct sock *s;
-	struct hlist_node *node;
-	struct atm_vcc *walk;
-	int i;
 
 	atmtcp_dev = (struct atm_dev *) vcc->dev_data;
 	dev_data = PRIV(atmtcp_dev);
@@ -257,20 +253,8 @@
 	if (dev_data->persist) return;
 	atmtcp_dev->dev_data = NULL;
 	kfree(dev_data);
-	shutdown_atm_dev(atmtcp_dev);
+	atm_dev_deregister(atmtcp_dev);
 	vcc->dev_data = NULL;
-	read_lock(&vcc_sklist_lock);
-	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
-		struct hlist_head *head = &vcc_hash[i];
-
-		sk_for_each(s, node, head) {
-			walk = atm_sk(s);
-			if (walk->dev != atmtcp_dev)
-				continue;
-			wake_up(s->sk_sleep);
-		}
-	}
-	read_unlock(&vcc_sklist_lock);
 	module_put(THIS_MODULE);
 }
 
@@ -450,7 +434,7 @@
 	if (PRIV(dev)->vcc) return 0;
 	kfree(dev_data);
 	atm_dev_put(dev);
-	shutdown_atm_dev(dev);
+	atm_dev_deregister(dev);
 	return 0;
 }
 
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
index 51ec147..69f4c7c 100644
--- a/drivers/atm/lanai.c
+++ b/drivers/atm/lanai.c
@@ -39,7 +39,7 @@
  * o  lanai_change_qos() isn't written yet
  *
  * o  There aren't any ioctl's yet -- I'd like to eventually support
- *    setting loopback and LED modes that way.  (see lanai_ioctl)
+ *    setting loopback and LED modes that way.
  *
  * o  If the segmentation engine or DMA gets shut down we should restart
  *    card as per section 17.0i.  (see lanai_reset)
@@ -305,7 +305,7 @@
  * vci with their bit set
  */
 static void vci_bitfield_iterate(struct lanai_dev *lanai,
-	/*const*/ unsigned long *lp,
+	const unsigned long *lp,
 	void (*func)(struct lanai_dev *,vci_t vci))
 {
 	vci_t vci = find_first_bit(lp, NUM_VCI);
@@ -951,7 +951,7 @@
 /* read a big-endian 4-byte value out of eeprom */
 static inline u32 eeprom_be4(const struct lanai_dev *lanai, int address)
 {
-	return be32_to_cpup((u32 *) (&lanai->eeprom[address]));
+	return be32_to_cpup((const u32 *) &lanai->eeprom[address]);
 }
 
 /* Checksum/validate EEPROM contents */
@@ -1160,7 +1160,7 @@
 }
 
 /* test if VCC is currently backlogged */
-static inline int vcc_is_backlogged(/*const*/ struct lanai_vcc *lvcc)
+static inline int vcc_is_backlogged(const struct lanai_vcc *lvcc)
 {
 	return !skb_queue_empty(&lvcc->tx.backlog);
 }
@@ -1395,7 +1395,8 @@
 {
 	int size;
 	struct sk_buff *skb;
-	/*const*/ u32 *x, *end = &lvcc->rx.buf.start[endptr * 4];
+	const u32 *x;
+	u32 *end = &lvcc->rx.buf.start[endptr * 4];
 	int n = ((unsigned long) end) - ((unsigned long) lvcc->rx.buf.ptr);
 	if (n < 0)
 		n += lanai_buf_size(&lvcc->rx.buf);
@@ -2111,7 +2112,7 @@
  * shifted by that much as we compute
  *
  */
-static int pcr_to_cbricg(/*const*/ struct atm_qos *qos)
+static int pcr_to_cbricg(const struct atm_qos *qos)
 {
 	int rounddown = 0;	/* 1 = Round PCR down, i.e. round ICG _up_ */
 	int x, icg, pcr = atm_pcr_goal(&qos->txtp);
@@ -2434,93 +2435,6 @@
 	return result;
 }
 
-#if 0
-/* ioctl operations for card */
-/* NOTE: these are all DEBUGGING ONLY currently */
-static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void __user *arg)
-{
-	int result = 0;
-	struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
-	switch(cmd) {
-		case 2106275:
-			shutdown_atm_dev(atmdev);
-			return 0;
-		case 2200000: {
-			unsigned long flags;
-			spin_lock_irqsave(&lanai->servicelock, flags);
-			run_service(lanai);
-			spin_unlock_irqrestore(&lanai->servicelock, flags);
-			return 0; }
-		case 2200002:
-			get_statistics(lanai);
-			return 0;
-		case 2200003: {
-			unsigned int i;
-			for (i = 0; i <= 0x5C ; i += 4) {
-				if (i==0x48) /* Write-only butt reg */
-					continue;
-				printk(KERN_CRIT DEV_LABEL "  0x%02X: "
-				    "0x%08X\n", i,
-				    (unsigned int) readl(lanai->base + i));
-				barrier(); mb();
-				pcistatus_check(lanai, 0);
-				barrier(); mb();
-			}
-			return 0; }
-		case 2200004: {
-			u8 b;
-			u16 w;
-			u32 dw;
-			struct pci_dev *pci = lanai->pci;
-			(void) pci_read_config_word(pci, PCI_VENDOR_ID, &w);
-			DPRINTK("vendor = 0x%X\n", (unsigned int) w);
-			(void) pci_read_config_word(pci, PCI_DEVICE_ID, &w);
-			DPRINTK("device = 0x%X\n", (unsigned int) w);
-			(void) pci_read_config_word(pci, PCI_COMMAND, &w);
-			DPRINTK("command = 0x%X\n", (unsigned int) w);
-			(void) pci_read_config_word(pci, PCI_STATUS, &w);
-			DPRINTK("status = 0x%X\n", (unsigned int) w);
-			(void) pci_read_config_dword(pci,
-			    PCI_CLASS_REVISION, &dw);
-			DPRINTK("class/revision = 0x%X\n", (unsigned int) dw);
-			(void) pci_read_config_byte(pci,
-			    PCI_CACHE_LINE_SIZE, &b);
-			DPRINTK("cache line size = 0x%X\n", (unsigned int) b);
-			(void) pci_read_config_byte(pci, PCI_LATENCY_TIMER, &b);
-			DPRINTK("latency = %d (0x%X)\n",
-			    (int) b, (unsigned int) b);
-			(void) pci_read_config_byte(pci, PCI_HEADER_TYPE, &b);
-			DPRINTK("header type = 0x%X\n", (unsigned int) b);
-			(void) pci_read_config_byte(pci, PCI_BIST, &b);
-			DPRINTK("bist = 0x%X\n", (unsigned int) b);
-			/* skipping a few here */
-			(void) pci_read_config_byte(pci,
-			    PCI_INTERRUPT_LINE, &b);
-			DPRINTK("pci_int_line = 0x%X\n", (unsigned int) b);
-			(void) pci_read_config_byte(pci,
-			    PCI_INTERRUPT_PIN, &b);
-			DPRINTK("pci_int_pin = 0x%X\n", (unsigned int) b);
-			(void) pci_read_config_byte(pci, PCI_MIN_GNT, &b);
-			DPRINTK("min_gnt = 0x%X\n", (unsigned int) b);
-			(void) pci_read_config_byte(pci, PCI_MAX_LAT, &b);
-			DPRINTK("max_lat = 0x%X\n", (unsigned int) b); }
-			return 0;
-#ifdef USE_POWERDOWN
-		case 2200005:
-			DPRINTK("Coming out of powerdown\n");
-			lanai->conf1 &= ~CONFIG1_POWERDOWN;
-			conf1_write(lanai);
-			return 0;
-#endif
-		default:
-			result = -ENOIOCTLCMD;
-	}
-	return result;
-}
-#else /* !0 */
-#define lanai_ioctl NULL
-#endif /* 0 */
-
 static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb)
 {
 	struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
@@ -2678,7 +2592,6 @@
 	.dev_close	= lanai_dev_close,
 	.open		= lanai_open,
 	.close		= lanai_close,
-	.ioctl		= lanai_ioctl,
 	.getsockopt	= NULL,
 	.setsockopt	= NULL,
 	.send		= lanai_send,
@@ -2760,6 +2673,7 @@
 	 * gone, so there isn't much to do
 	 */
 	DPRINTK("cleanup_module()\n");
+	pci_unregister_driver(&lanai_driver);
 }
 
 module_init(lanai_module_init);
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
index c57e20dcb..074abc8 100644
--- a/drivers/atm/nicstar.c
+++ b/drivers/atm/nicstar.c
@@ -2126,8 +2126,7 @@
 
    if (!ns_rsqe_valid(card->rsq.next))
       return;
-   while (ns_rsqe_valid(card->rsq.next))
-   {
+   do {
       dequeue_rx(card, card->rsq.next);
       ns_rsqe_init(card->rsq.next);
       previous = card->rsq.next;
@@ -2135,7 +2134,7 @@
          card->rsq.next = card->rsq.base;
       else
          card->rsq.next++;
-   }
+   } while (ns_rsqe_valid(card->rsq.next));
    writel((((u32) previous) - ((u32) card->rsq.base)),
           card->membase + RSQH);
 }
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 934149c..f0eff3d 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -19,11 +19,11 @@
 	  If unsure say Y here.
 
 config FW_LOADER
-	tristate "Hotplug firmware loading support"
+	tristate "Userspace firmware loading support"
 	select HOTPLUG
 	---help---
 	  This option is provided for the case where no in-kernel-tree modules
-	  require hotplug firmware loading support, but a module built outside
+	  require userspace firmware loading support, but a module built outside
 	  the kernel tree does.
 
 config DEBUG_DRIVER
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index fa601b0..29f6af5 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -152,7 +152,11 @@
 
 	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
 	if (dev && dev->driver == drv) {
+		if (dev->parent)	/* Needed for USB */
+			down(&dev->parent->sem);
 		device_release_driver(dev);
+		if (dev->parent)
+			up(&dev->parent->sem);
 		err = count;
 	}
 	put_device(dev);
@@ -175,9 +179,13 @@
 
 	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
 	if (dev && dev->driver == NULL) {
+		if (dev->parent)	/* Needed for USB */
+			down(&dev->parent->sem);
 		down(&dev->sem);
 		err = driver_probe_device(drv, dev);
 		up(&dev->sem);
+		if (dev->parent)
+			up(&dev->parent->sem);
 	}
 	put_device(dev);
 	put_bus(bus);
@@ -420,6 +428,26 @@
 	}
 }
 
+#ifdef CONFIG_HOTPLUG
+/*
+ * Thanks to drivers making their tables __devinit, we can't allow manual
+ * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
+ */
+static void add_bind_files(struct device_driver *drv)
+{
+	driver_create_file(drv, &driver_attr_unbind);
+	driver_create_file(drv, &driver_attr_bind);
+}
+
+static void remove_bind_files(struct device_driver *drv)
+{
+	driver_remove_file(drv, &driver_attr_bind);
+	driver_remove_file(drv, &driver_attr_unbind);
+}
+#else
+static inline void add_bind_files(struct device_driver *drv) {}
+static inline void remove_bind_files(struct device_driver *drv) {}
+#endif
 
 /**
  *	bus_add_driver - Add a driver to the bus.
@@ -449,8 +477,7 @@
 		module_add_driver(drv->owner, drv);
 
 		driver_add_attrs(bus, drv);
-		driver_create_file(drv, &driver_attr_unbind);
-		driver_create_file(drv, &driver_attr_bind);
+		add_bind_files(drv);
 	}
 	return error;
 }
@@ -468,8 +495,7 @@
 void bus_remove_driver(struct device_driver * drv)
 {
 	if (drv->bus) {
-		driver_remove_file(drv, &driver_attr_bind);
-		driver_remove_file(drv, &driver_attr_unbind);
+		remove_bind_files(drv);
 		driver_remove_attrs(drv->bus, drv);
 		klist_remove(&drv->knode_bus);
 		pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
@@ -484,8 +510,13 @@
 /* Helper for bus_rescan_devices's iter */
 static int bus_rescan_devices_helper(struct device *dev, void *data)
 {
-	if (!dev->driver)
+	if (!dev->driver) {
+		if (dev->parent)	/* Needed for USB */
+			down(&dev->parent->sem);
 		device_attach(dev);
+		if (dev->parent)
+			up(&dev->parent->sem);
+	}
 	return 0;
 }
 
diff --git a/drivers/base/class.c b/drivers/base/class.c
index db65fd0..df7fdab 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -178,7 +178,7 @@
 }
 
 /* needed to allow these devices to have parent class devices */
-static int class_device_create_hotplug(struct class_device *class_dev,
+static int class_device_create_uevent(struct class_device *class_dev,
 				       char **envp, int num_envp,
 				       char *buffer, int buffer_size)
 {
@@ -331,7 +331,7 @@
 	.release	= class_dev_release,
 };
 
-static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
+static int class_uevent_filter(struct kset *kset, struct kobject *kobj)
 {
 	struct kobj_type *ktype = get_ktype(kobj);
 
@@ -343,14 +343,14 @@
 	return 0;
 }
 
-static const char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
+static const char *class_uevent_name(struct kset *kset, struct kobject *kobj)
 {
 	struct class_device *class_dev = to_class_dev(kobj);
 
 	return class_dev->class->name;
 }
 
-static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
+static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
 			 int num_envp, char *buffer, int buffer_size)
 {
 	struct class_device *class_dev = to_class_dev(kobj);
@@ -365,29 +365,29 @@
 		struct device *dev = class_dev->dev;
 		char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
 
-		add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
-				    &length, "PHYSDEVPATH=%s", path);
+		add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+			       &length, "PHYSDEVPATH=%s", path);
 		kfree(path);
 
 		if (dev->bus)
-			add_hotplug_env_var(envp, num_envp, &i,
-					    buffer, buffer_size, &length,
-					    "PHYSDEVBUS=%s", dev->bus->name);
+			add_uevent_var(envp, num_envp, &i,
+				       buffer, buffer_size, &length,
+				       "PHYSDEVBUS=%s", dev->bus->name);
 
 		if (dev->driver)
-			add_hotplug_env_var(envp, num_envp, &i,
-					    buffer, buffer_size, &length,
-					    "PHYSDEVDRIVER=%s", dev->driver->name);
+			add_uevent_var(envp, num_envp, &i,
+				       buffer, buffer_size, &length,
+				       "PHYSDEVDRIVER=%s", dev->driver->name);
 	}
 
 	if (MAJOR(class_dev->devt)) {
-		add_hotplug_env_var(envp, num_envp, &i,
-				    buffer, buffer_size, &length,
-				    "MAJOR=%u", MAJOR(class_dev->devt));
+		add_uevent_var(envp, num_envp, &i,
+			       buffer, buffer_size, &length,
+			       "MAJOR=%u", MAJOR(class_dev->devt));
 
-		add_hotplug_env_var(envp, num_envp, &i,
-				    buffer, buffer_size, &length,
-				    "MINOR=%u", MINOR(class_dev->devt));
+		add_uevent_var(envp, num_envp, &i,
+			       buffer, buffer_size, &length,
+			       "MINOR=%u", MINOR(class_dev->devt));
 	}
 
 	/* terminate, set to next free slot, shrink available space */
@@ -397,30 +397,30 @@
 	buffer = &buffer[length];
 	buffer_size -= length;
 
-	if (class_dev->hotplug) {
+	if (class_dev->uevent) {
 		/* have the class device specific function add its stuff */
-		retval = class_dev->hotplug(class_dev, envp, num_envp,
+		retval = class_dev->uevent(class_dev, envp, num_envp,
 					    buffer, buffer_size);
 		if (retval)
-			pr_debug("class_dev->hotplug() returned %d\n", retval);
-	} else if (class_dev->class->hotplug) {
+			pr_debug("class_dev->uevent() returned %d\n", retval);
+	} else if (class_dev->class->uevent) {
 		/* have the class specific function add its stuff */
-		retval = class_dev->class->hotplug(class_dev, envp, num_envp,
+		retval = class_dev->class->uevent(class_dev, envp, num_envp,
 						   buffer, buffer_size);
 		if (retval)
-			pr_debug("class->hotplug() returned %d\n", retval);
+			pr_debug("class->uevent() returned %d\n", retval);
 	}
 
 	return retval;
 }
 
-static struct kset_hotplug_ops class_hotplug_ops = {
-	.filter =	class_hotplug_filter,
-	.name =		class_hotplug_name,
-	.hotplug =	class_hotplug,
+static struct kset_uevent_ops class_uevent_ops = {
+	.filter =	class_uevent_filter,
+	.name =		class_uevent_name,
+	.uevent =	class_uevent,
 };
 
-static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
+static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops);
 
 
 static int class_device_add_attrs(struct class_device * cd)
@@ -464,7 +464,7 @@
 static ssize_t store_uevent(struct class_device *class_dev,
 			    const char *buf, size_t count)
 {
-	kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+	kobject_uevent(&class_dev->kobj, KOBJ_ADD);
 	return count;
 }
 
@@ -559,7 +559,7 @@
 				  class_name);
 	}
 
-	kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+	kobject_uevent(&class_dev->kobj, KOBJ_ADD);
 
 	/* notify any interfaces this device is now here */
 	if (parent_class) {
@@ -632,7 +632,7 @@
 	class_dev->class = cls;
 	class_dev->parent = parent;
 	class_dev->release = class_device_create_release;
-	class_dev->hotplug = class_device_create_hotplug;
+	class_dev->uevent = class_device_create_uevent;
 
 	va_start(args, fmt);
 	vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@@ -674,7 +674,7 @@
 		class_device_remove_file(class_dev, class_dev->devt_attr);
 	class_device_remove_attrs(class_dev);
 
-	kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
+	kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
 	kobject_del(&class_dev->kobj);
 
 	class_device_put(parent_device);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 8615b42..fd80599 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -90,7 +90,7 @@
 };
 
 
-static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
+static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
 {
 	struct kobj_type *ktype = get_ktype(kobj);
 
@@ -102,14 +102,14 @@
 	return 0;
 }
 
-static const char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
+static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
 {
 	struct device *dev = to_dev(kobj);
 
 	return dev->bus->name;
 }
 
-static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
+static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
 			int num_envp, char *buffer, int buffer_size)
 {
 	struct device *dev = to_dev(kobj);
@@ -119,15 +119,15 @@
 
 	/* add bus name of physical device */
 	if (dev->bus)
-		add_hotplug_env_var(envp, num_envp, &i,
-				    buffer, buffer_size, &length,
-				    "PHYSDEVBUS=%s", dev->bus->name);
+		add_uevent_var(envp, num_envp, &i,
+			       buffer, buffer_size, &length,
+			       "PHYSDEVBUS=%s", dev->bus->name);
 
 	/* add driver name of physical device */
 	if (dev->driver)
-		add_hotplug_env_var(envp, num_envp, &i,
-				    buffer, buffer_size, &length,
-				    "PHYSDEVDRIVER=%s", dev->driver->name);
+		add_uevent_var(envp, num_envp, &i,
+			       buffer, buffer_size, &length,
+			       "PHYSDEVDRIVER=%s", dev->driver->name);
 
 	/* terminate, set to next free slot, shrink available space */
 	envp[i] = NULL;
@@ -136,11 +136,11 @@
 	buffer = &buffer[length];
 	buffer_size -= length;
 
-	if (dev->bus && dev->bus->hotplug) {
+	if (dev->bus && dev->bus->uevent) {
 		/* have the bus specific function add its stuff */
-		retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size);
+		retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
 			if (retval) {
-			pr_debug ("%s - hotplug() returned %d\n",
+			pr_debug ("%s - uevent() returned %d\n",
 				  __FUNCTION__, retval);
 		}
 	}
@@ -148,16 +148,16 @@
 	return retval;
 }
 
-static struct kset_hotplug_ops device_hotplug_ops = {
-	.filter =	dev_hotplug_filter,
-	.name =		dev_hotplug_name,
-	.hotplug =	dev_hotplug,
+static struct kset_uevent_ops device_uevent_ops = {
+	.filter =	dev_uevent_filter,
+	.name =		dev_uevent_name,
+	.uevent =	dev_uevent,
 };
 
 static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 {
-	kobject_hotplug(&dev->kobj, KOBJ_ADD);
+	kobject_uevent(&dev->kobj, KOBJ_ADD);
 	return count;
 }
 
@@ -165,7 +165,7 @@
  *	device_subsys - structure to be registered with kobject core.
  */
 
-decl_subsys(devices, &ktype_device, &device_hotplug_ops);
+decl_subsys(devices, &ktype_device, &device_uevent_ops);
 
 
 /**
@@ -274,7 +274,7 @@
 	dev->uevent_attr.store = store_uevent;
 	device_create_file(dev, &dev->uevent_attr);
 
-	kobject_hotplug(&dev->kobj, KOBJ_ADD);
+	kobject_uevent(&dev->kobj, KOBJ_ADD);
 	if ((error = device_pm_add(dev)))
 		goto PMError;
 	if ((error = bus_add_device(dev)))
@@ -291,7 +291,7 @@
  BusError:
 	device_pm_remove(dev);
  PMError:
-	kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
+	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
 	kobject_del(&dev->kobj);
  Error:
 	if (parent)
@@ -374,7 +374,7 @@
 		platform_notify_remove(dev);
 	bus_remove_device(dev);
 	device_pm_remove(dev);
-	kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
+	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
 	kobject_del(&dev->kobj);
 	if (parent)
 		put_device(parent);
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index a958447..281d267 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -41,14 +41,14 @@
 	case '0':
 		ret = cpu_down(cpu->sysdev.id);
 		if (!ret)
-			kobject_hotplug(&dev->kobj, KOBJ_OFFLINE);
+			kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
 		break;
 	case '1':
 		ret = smp_prepare_cpu(cpu->sysdev.id);
 		if (!ret)
 			ret = cpu_up(cpu->sysdev.id);
 		if (!ret)
-			kobject_hotplug(&dev->kobj, KOBJ_ONLINE);
+			kobject_uevent(&dev->kobj, KOBJ_ONLINE);
 		break;
 	default:
 		ret = -EINVAL;
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 3b419c9..2b90501 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -65,7 +65,8 @@
  *	This function returns 1 if a match is found, an error if one
  *	occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
  *
- *	This function must be called with @dev->sem held.
+ *	This function must be called with @dev->sem held.  When called
+ *	for a USB interface, @dev->parent->sem must be held as well.
  */
 int driver_probe_device(struct device_driver * drv, struct device * dev)
 {
@@ -123,6 +124,8 @@
  *
  *	Returns 1 if the device was bound to a driver;
  *	0 if no matching device was found; error code otherwise.
+ *
+ *	When called for a USB interface, @dev->parent->sem must be held.
  */
 int device_attach(struct device * dev)
 {
@@ -152,10 +155,14 @@
 	 * is an error.
 	 */
 
+	if (dev->parent)	/* Needed for USB */
+		down(&dev->parent->sem);
 	down(&dev->sem);
 	if (!dev->driver)
 		driver_probe_device(drv, dev);
 	up(&dev->sem);
+	if (dev->parent)
+		up(&dev->parent->sem);
 
 	return 0;
 }
@@ -181,6 +188,8 @@
  *	Manually detach device from driver.
  *
  *	__device_release_driver() must be called with @dev->sem held.
+ *	When called for a USB interface, @dev->parent->sem must be held
+ *	as well.
  */
 
 static void __device_release_driver(struct device * dev)
@@ -233,10 +242,14 @@
 		get_device(dev);
 		spin_unlock(&drv->klist_devices.k_lock);
 
+		if (dev->parent)	/* Needed for USB */
+			down(&dev->parent->sem);
 		down(&dev->sem);
 		if (dev->driver == drv)
 			__device_release_driver(dev);
 		up(&dev->sem);
+		if (dev->parent)
+			up(&dev->parent->sem);
 		put_device(dev);
 	}
 }
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 59dacb6..5b3d5e9 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -85,17 +85,17 @@
 static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
 
 static void  fw_class_dev_release(struct class_device *class_dev);
-int firmware_class_hotplug(struct class_device *dev, char **envp,
+int firmware_class_uevent(struct class_device *dev, char **envp,
 			   int num_envp, char *buffer, int buffer_size);
 
 static struct class firmware_class = {
 	.name		= "firmware",
-	.hotplug	= firmware_class_hotplug,
+	.uevent	= firmware_class_uevent,
 	.release	= fw_class_dev_release,
 };
 
 int
-firmware_class_hotplug(struct class_device *class_dev, char **envp,
+firmware_class_uevent(struct class_device *class_dev, char **envp,
 		       int num_envp, char *buffer, int buffer_size)
 {
 	struct firmware_priv *fw_priv = class_get_devdata(class_dev);
@@ -104,13 +104,12 @@
 	if (!test_bit(FW_STATUS_READY, &fw_priv->status))
 		return -ENODEV;
 
-	if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
-			"FIRMWARE=%s", fw_priv->fw_id))
+	if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
+			   "FIRMWARE=%s", fw_priv->fw_id))
 		return -ENOMEM;
-	if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
-			"TIMEOUT=%i", loading_timeout))
+	if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
+			   "TIMEOUT=%i", loading_timeout))
 		return -ENOMEM;
-
 	envp[i] = NULL;
 
 	return 0;
@@ -352,7 +351,7 @@
 
 static int
 fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
-		      const char *fw_name, struct device *device, int hotplug)
+		      const char *fw_name, struct device *device, int uevent)
 {
 	struct class_device *class_dev;
 	struct firmware_priv *fw_priv;
@@ -384,7 +383,7 @@
 		goto error_unreg;
 	}
 
-	if (hotplug)
+	if (uevent)
                 set_bit(FW_STATUS_READY, &fw_priv->status);
         else
                 set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
@@ -399,7 +398,7 @@
 
 static int
 _request_firmware(const struct firmware **firmware_p, const char *name,
-		 struct device *device, int hotplug)
+		 struct device *device, int uevent)
 {
 	struct class_device *class_dev;
 	struct firmware_priv *fw_priv;
@@ -418,19 +417,19 @@
 	}
 
 	retval = fw_setup_class_device(firmware, &class_dev, name, device,
-		hotplug);
+				       uevent);
 	if (retval)
 		goto error_kfree_fw;
 
 	fw_priv = class_get_devdata(class_dev);
 
-	if (hotplug) {
+	if (uevent) {
 		if (loading_timeout > 0) {
 			fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
 			add_timer(&fw_priv->timeout);
 		}
 
-		kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+		kobject_uevent(&class_dev->kobj, KOBJ_ADD);
 		wait_for_completion(&fw_priv->completion);
 		set_bit(FW_STATUS_DONE, &fw_priv->status);
 		del_timer_sync(&fw_priv->timeout);
@@ -456,7 +455,7 @@
 }
 
 /**
- * request_firmware: - request firmware to hotplug and wait for it
+ * request_firmware: - send firmware request and wait for it
  * @firmware_p: pointer to firmware image
  * @name: name of firmware file
  * @device: device for which firmware is being loaded
@@ -466,7 +465,7 @@
  *
  *      Should be called from user context where sleeping is allowed.
  *
- *      @name will be used as $FIRMWARE in the hotplug environment and
+ *      @name will be used as $FIRMWARE in the uevent environment and
  *      should be distinctive enough not to be confused with any other
  *      firmware image for this or any other device.
  **/
@@ -474,8 +473,8 @@
 request_firmware(const struct firmware **firmware_p, const char *name,
                  struct device *device)
 {
-        int hotplug = 1;
-        return _request_firmware(firmware_p, name, device, hotplug);
+        int uevent = 1;
+        return _request_firmware(firmware_p, name, device, uevent);
 }
 
 /**
@@ -518,7 +517,7 @@
 	struct device *device;
 	void *context;
 	void (*cont)(const struct firmware *fw, void *context);
-	int hotplug;
+	int uevent;
 };
 
 static int
@@ -533,7 +532,7 @@
 	}
 	daemonize("%s/%s", "firmware", fw_work->name);
 	ret = _request_firmware(&fw, fw_work->name, fw_work->device,
-		fw_work->hotplug);
+		fw_work->uevent);
 	if (ret < 0)
 		fw_work->cont(NULL, fw_work->context);
 	else {
@@ -548,7 +547,7 @@
 /**
  * request_firmware_nowait: asynchronous version of request_firmware
  * @module: module requesting the firmware
- * @hotplug: invokes hotplug event to copy the firmware image if this flag
+ * @uevent: sends uevent to copy the firmware image if this flag
  *	is non-zero else the firmware copy must be done manually.
  * @name: name of firmware file
  * @device: device for which firmware is being loaded
@@ -562,7 +561,7 @@
  **/
 int
 request_firmware_nowait(
-	struct module *module, int hotplug,
+	struct module *module, int uevent,
 	const char *name, struct device *device, void *context,
 	void (*cont)(const struct firmware *fw, void *context))
 {
@@ -583,7 +582,7 @@
 		.device = device,
 		.context = context,
 		.cont = cont,
-		.hotplug = hotplug,
+		.uevent = uevent,
 	};
 
 	ret = kernel_thread(request_firmware_work_func, fw_work,
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index b7ddd65..58801d7 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -28,14 +28,13 @@
 static struct sysdev_class memory_sysdev_class = {
 	set_kset_name(MEMORY_CLASS_NAME),
 };
-EXPORT_SYMBOL(memory_sysdev_class);
 
-static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj)
+static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
 {
 	return MEMORY_CLASS_NAME;
 }
 
-static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
+static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp,
 			int num_envp, char *buffer, int buffer_size)
 {
 	int retval = 0;
@@ -43,19 +42,19 @@
 	return retval;
 }
 
-static struct kset_hotplug_ops memory_hotplug_ops = {
-	.name		= memory_hotplug_name,
-	.hotplug	= memory_hotplug,
+static struct kset_uevent_ops memory_uevent_ops = {
+	.name		= memory_uevent_name,
+	.uevent		= memory_uevent,
 };
 
 static struct notifier_block *memory_chain;
 
-static int register_memory_notifier(struct notifier_block *nb)
+int register_memory_notifier(struct notifier_block *nb)
 {
         return notifier_chain_register(&memory_chain, nb);
 }
 
-static void unregister_memory_notifier(struct notifier_block *nb)
+void unregister_memory_notifier(struct notifier_block *nb)
 {
         notifier_chain_unregister(&memory_chain, nb);
 }
@@ -63,8 +62,7 @@
 /*
  * register_memory - Setup a sysfs device for a memory block
  */
-static int
-register_memory(struct memory_block *memory, struct mem_section *section,
+int register_memory(struct memory_block *memory, struct mem_section *section,
 		struct node *root)
 {
 	int error;
@@ -432,7 +430,7 @@
 	unsigned int i;
 	int ret;
 
-	memory_sysdev_class.kset.hotplug_ops = &memory_hotplug_ops;
+	memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops;
 	ret = sysdev_class_register(&memory_sysdev_class);
 
 	/*
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 8827daf..0f81731 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -25,6 +25,7 @@
 struct device platform_bus = {
 	.bus_id		= "platform",
 };
+EXPORT_SYMBOL_GPL(platform_bus);
 
 /**
  *	platform_get_resource - get a resource for a device
@@ -49,6 +50,7 @@
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(platform_get_resource);
 
 /**
  *	platform_get_irq - get an IRQ for a device
@@ -61,6 +63,7 @@
 
 	return r ? r->start : 0;
 }
+EXPORT_SYMBOL_GPL(platform_get_irq);
 
 /**
  *	platform_get_resource_byname - get a resource for a device by name
@@ -84,6 +87,7 @@
 	}
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(platform_get_resource_byname);
 
 /**
  *	platform_get_irq - get an IRQ for a device
@@ -96,6 +100,7 @@
 
 	return r ? r->start : 0;
 }
+EXPORT_SYMBOL_GPL(platform_get_irq_byname);
 
 /**
  *	platform_add_devices - add a numbers of platform devices
@@ -117,6 +122,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(platform_add_devices);
 
 struct platform_object {
 	struct platform_device pdev;
@@ -168,7 +174,7 @@
 		pa->pdev.dev.release = platform_device_release;
 	}
 
-	return pa ? &pa->pdev : NULL;	
+	return pa ? &pa->pdev : NULL;
 }
 EXPORT_SYMBOL_GPL(platform_device_alloc);
 
@@ -257,7 +263,7 @@
 				p = &ioport_resource;
 		}
 
-		if (p && request_resource(p, r)) {
+		if (p && insert_resource(p, r)) {
 			printk(KERN_ERR
 			       "%s: failed to claim resource %d\n",
 			       pdev->dev.bus_id, i);
@@ -282,24 +288,13 @@
 EXPORT_SYMBOL_GPL(platform_device_add);
 
 /**
- *	platform_device_register - add a platform-level device
- *	@pdev:	platform device we're adding
- *
- */
-int platform_device_register(struct platform_device * pdev)
-{
-	device_initialize(&pdev->dev);
-	return platform_device_add(pdev);
-}
-
-/**
- *	platform_device_unregister - remove a platform-level device
+ *	platform_device_del - remove a platform-level device
  *	@pdev:	platform device we're removing
  *
  *	Note that this function will also release all memory- and port-based
  *	resources owned by the device (@dev->resource).
  */
-void platform_device_unregister(struct platform_device * pdev)
+void platform_device_del(struct platform_device *pdev)
 {
 	int i;
 
@@ -310,9 +305,37 @@
 				release_resource(r);
 		}
 
-		device_unregister(&pdev->dev);
+		device_del(&pdev->dev);
 	}
 }
+EXPORT_SYMBOL_GPL(platform_device_del);
+
+/**
+ *	platform_device_register - add a platform-level device
+ *	@pdev:	platform device we're adding
+ *
+ */
+int platform_device_register(struct platform_device * pdev)
+{
+	device_initialize(&pdev->dev);
+	return platform_device_add(pdev);
+}
+EXPORT_SYMBOL_GPL(platform_device_register);
+
+/**
+ *	platform_device_unregister - unregister a platform-level device
+ *	@pdev:	platform device we're unregistering
+ *
+ *	Unregistration is done in 2 steps. Fisrt we release all resources
+ *	and remove it from the sybsystem, then we drop reference count by
+ *	calling platform_device_put().
+ */
+void platform_device_unregister(struct platform_device * pdev)
+{
+	platform_device_del(pdev);
+	platform_device_put(pdev);
+}
+EXPORT_SYMBOL_GPL(platform_device_unregister);
 
 /**
  *	platform_device_register_simple
@@ -355,6 +378,7 @@
 	platform_device_put(pdev);
 	return ERR_PTR(retval);
 }
+EXPORT_SYMBOL_GPL(platform_device_register_simple);
 
 static int platform_drv_probe(struct device *_dev)
 {
@@ -476,6 +500,7 @@
 	.suspend	= platform_suspend,
 	.resume		= platform_resume,
 };
+EXPORT_SYMBOL_GPL(platform_bus_type);
 
 int __init platform_bus_init(void)
 {
@@ -504,14 +529,3 @@
 }
 EXPORT_SYMBOL_GPL(dma_get_required_mask);
 #endif
-
-EXPORT_SYMBOL_GPL(platform_bus);
-EXPORT_SYMBOL_GPL(platform_bus_type);
-EXPORT_SYMBOL_GPL(platform_add_devices);
-EXPORT_SYMBOL_GPL(platform_device_register);
-EXPORT_SYMBOL_GPL(platform_device_register_simple);
-EXPORT_SYMBOL_GPL(platform_device_unregister);
-EXPORT_SYMBOL_GPL(platform_get_irq);
-EXPORT_SYMBOL_GPL(platform_get_resource);
-EXPORT_SYMBOL_GPL(platform_get_irq_byname);
-EXPORT_SYMBOL_GPL(platform_get_resource_byname);
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
index adbc3148..96370ec 100644
--- a/drivers/base/power/runtime.c
+++ b/drivers/base/power/runtime.c
@@ -62,8 +62,10 @@
 	up(&dpm_sem);
 	return error;
 }
+EXPORT_SYMBOL(dpm_runtime_suspend);
 
 
+#if 0
 /**
  *	dpm_set_power_state - Update power_state field.
  *	@dev:	Device.
@@ -80,3 +82,4 @@
 	dev->power.power_state = state;
 	up(&dpm_sem);
 }
+#endif  /*  0  */
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 70eaa5c..4a7bb7d 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -92,34 +92,28 @@
 	return 0;
 }
 
-static int DAC960_ioctl(struct inode *inode, struct file *file,
-			unsigned int cmd, unsigned long arg)
+static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	struct gendisk *disk = inode->i_bdev->bd_disk;
+	struct gendisk *disk = bdev->bd_disk;
 	DAC960_Controller_T *p = disk->queue->queuedata;
 	int drive_nr = (long)disk->private_data;
-	struct hd_geometry g;
-	struct hd_geometry __user *loc = (struct hd_geometry __user *)arg;
-
-	if (cmd != HDIO_GETGEO || !loc)
-		return -EINVAL;
 
 	if (p->FirmwareType == DAC960_V1_Controller) {
-		g.heads = p->V1.GeometryTranslationHeads;
-		g.sectors = p->V1.GeometryTranslationSectors;
-		g.cylinders = p->V1.LogicalDriveInformation[drive_nr].
-			LogicalDriveSize / (g.heads * g.sectors);
+		geo->heads = p->V1.GeometryTranslationHeads;
+		geo->sectors = p->V1.GeometryTranslationSectors;
+		geo->cylinders = p->V1.LogicalDriveInformation[drive_nr].
+			LogicalDriveSize / (geo->heads * geo->sectors);
 	} else {
 		DAC960_V2_LogicalDeviceInfo_T *i =
 			p->V2.LogicalDeviceInformation[drive_nr];
 		switch (i->DriveGeometry) {
 		case DAC960_V2_Geometry_128_32:
-			g.heads = 128;
-			g.sectors = 32;
+			geo->heads = 128;
+			geo->sectors = 32;
 			break;
 		case DAC960_V2_Geometry_255_63:
-			g.heads = 255;
-			g.sectors = 63;
+			geo->heads = 255;
+			geo->sectors = 63;
 			break;
 		default:
 			DAC960_Error("Illegal Logical Device Geometry %d\n",
@@ -127,12 +121,11 @@
 			return -EINVAL;
 		}
 
-		g.cylinders = i->ConfigurableDeviceSize / (g.heads * g.sectors);
+		geo->cylinders = i->ConfigurableDeviceSize /
+			(geo->heads * geo->sectors);
 	}
 	
-	g.start = get_start_sect(inode->i_bdev);
-
-	return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
+	return 0;
 }
 
 static int DAC960_media_changed(struct gendisk *disk)
@@ -157,7 +150,7 @@
 static struct block_device_operations DAC960_BlockDeviceOperations = {
 	.owner			= THIS_MODULE,
 	.open			= DAC960_open,
-	.ioctl			= DAC960_ioctl,
+	.getgeo			= DAC960_getgeo,
 	.media_changed		= DAC960_media_changed,
 	.revalidate_disk	= DAC960_revalidate_disk,
 };
@@ -3471,7 +3464,7 @@
 
 	 if (!end_that_request_first(Request, UpToDate, Command->BlockCount)) {
 
- 	 	end_that_request_last(Request);
+ 	 	end_that_request_last(Request, UpToDate);
 
 		if (Command->Completion) {
 			complete(Command->Completion);
@@ -3767,7 +3760,7 @@
 	      if (SenseKey == DAC960_SenseKey_VendorSpecific &&
 		  AdditionalSenseCode == 0x80 &&
 		  AdditionalSenseCodeQualifier <
-		  sizeof(DAC960_EventMessages) / sizeof(char *))
+		  ARRAY_SIZE(DAC960_EventMessages))
 		DAC960_Critical("Physical Device %d:%d %s\n", Controller,
 				EventLogEntry->Channel,
 				EventLogEntry->TargetID,
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 7b1cd93..139cbba 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -117,7 +117,7 @@
 
 config PARIDE
 	tristate "Parallel port IDE device support"
-	depends on PARPORT
+	depends on PARPORT_PC
 	---help---
 	  There are many external CD-ROM and disk devices that connect through
 	  your computer's parallel port. Most of them are actually IDE devices
@@ -358,7 +358,8 @@
 	  This driver supports certain USB attached storage devices
 	  such as flash keys.
 
-	  Warning: Enabling this cripples the usb-storage driver.
+	  If you enable this driver, it is recommended to avoid conflicts
+	  with usb-storage by enabling USB_LIBUSUAL.
 
 	  If unsure, say N.
 
diff --git a/drivers/block/acsi.c b/drivers/block/acsi.c
index 5d2d649..196c0ec 100644
--- a/drivers/block/acsi.c
+++ b/drivers/block/acsi.c
@@ -1079,6 +1079,19 @@
  *
  ***********************************************************************/
 
+static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct acsi_info_struct *aip = bdev->bd_disk->private_data;
+
+	/*
+	 * Just fake some geometry here, it's nonsense anyway
+	 * To make it easy, use Adaptec's usual 64/32 mapping
+	 */
+	geo->heads = 64;
+	geo->sectors = 32;
+	geo->cylinders = aip->size >> 11;
+	return 0;
+}
 
 static int acsi_ioctl( struct inode *inode, struct file *file,
 					   unsigned int cmd, unsigned long arg )
@@ -1086,18 +1099,6 @@
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct acsi_info_struct *aip = disk->private_data;
 	switch (cmd) {
-	  case HDIO_GETGEO:
-		/* HDIO_GETGEO is supported more for getting the partition's
-		 * start sector... */
-	  { struct hd_geometry *geo = (struct hd_geometry *)arg;
-	    /* just fake some geometry here, it's nonsense anyway; to make it
-		 * easy, use Adaptec's usual 64/32 mapping */
-	    put_user( 64, &geo->heads );
-	    put_user( 32, &geo->sectors );
-	    put_user( aip->size >> 11, &geo->cylinders );
-		put_user(get_start_sect(inode->i_bdev), &geo->start);
-		return 0;
-	  }
 	  case SCSI_IOCTL_GET_IDLUN:
 		/* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
 		put_user( aip->target | (aip->lun << 8),
@@ -1592,6 +1593,7 @@
 	.open		= acsi_open,
 	.release	= acsi_release,
 	.ioctl		= acsi_ioctl,
+	.getgeo		= acsi_getgeo,
 	.media_changed	= acsi_media_change,
 	.revalidate_disk= acsi_revalidate,
 };
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 0acbfff..3c679d3 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -131,7 +131,7 @@
 { FD_DD_5,	"DD 5.25", 40, 2, 14716, 13630, 1, 40, 81, 6, 30, 2},
 { FD_NODRIVE, "No Drive", 0, 0,     0,     0, 0,  0,  0,  0,  0, 0}
 };
-static int num_dr_types = sizeof(drive_types) / sizeof(drive_types[0]);
+static int num_dr_types = ARRAY_SIZE(drive_types);
 
 static int amiga_read(int), dos_read(int);
 static void amiga_write(int), dos_write(int);
@@ -1424,6 +1424,16 @@
 	redo_fd_request();
 }
 
+static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	int drive = MINOR(bdev->bd_dev) & 3;
+
+	geo->heads = unit[drive].type->heads;
+	geo->sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
+	geo->cylinders = unit[drive].type->tracks;
+	return 0;
+}
+
 static int fd_ioctl(struct inode *inode, struct file *filp,
 		    unsigned int cmd, unsigned long param)
 {
@@ -1431,18 +1441,6 @@
 	static struct floppy_struct getprm;
 
 	switch(cmd){
-	case HDIO_GETGEO:
-	{
-		struct hd_geometry loc;
-		loc.heads = unit[drive].type->heads;
-		loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
-		loc.cylinders = unit[drive].type->tracks;
-		loc.start = 0;
-		if (copy_to_user((void *)param, (void *)&loc,
-				 sizeof(struct hd_geometry)))
-			return -EFAULT;
-		break;
-	}
 	case FDFMTBEG:
 		get_fdc(drive);
 		if (fd_ref[drive] > 1) {
@@ -1652,6 +1650,7 @@
 	.open		= floppy_open,
 	.release	= floppy_release,
 	.ioctl		= fd_ioctl,
+	.getgeo		= fd_getgeo,
 	.media_changed	= amiga_floppy_change,
 };
 
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 0e97fcb..c05ee8b 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -169,38 +169,26 @@
 	return 0;
 }
 
-/* This ioctl implementation expects userland to have the device node
- * permissions set so that only priviledged users can open an aoe
- * block device directly.
- */
 static int
-aoeblk_ioctl(struct inode *inode, struct file *filp, uint cmd, ulong arg)
+aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	struct aoedev *d;
+	struct aoedev *d = bdev->bd_disk->private_data;
 
-	if (!arg)
-		return -EINVAL;
-
-	d = inode->i_bdev->bd_disk->private_data;
 	if ((d->flags & DEVFL_UP) == 0) {
 		printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n");
 		return -ENODEV;
 	}
 
-	if (cmd == HDIO_GETGEO) {
-		d->geo.start = get_start_sect(inode->i_bdev);
-		if (!copy_to_user((void __user *) arg, &d->geo, sizeof d->geo))
-			return 0;
-		return -EFAULT;
-	}
-	printk(KERN_INFO "aoe: aoeblk_ioctl: unknown ioctl %d\n", cmd);
-	return -EINVAL;
+	geo->cylinders = d->geo.cylinders;
+	geo->heads = d->geo.heads;
+	geo->sectors = d->geo.sectors;
+	return 0;
 }
 
 static struct block_device_operations aoe_bdops = {
 	.open = aoeblk_open,
 	.release = aoeblk_release,
-	.ioctl = aoeblk_ioctl,
+	.getgeo = aoeblk_getgeo,
 	.owner = THIS_MODULE,
 };
 
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 22bda05..3aa68a5 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -181,7 +181,7 @@
 	{  6, TYPE_HD },	/* 31: H1640    <- was H1600 == h1600 for PC */
 };
 
-#define NUM_DISK_MINORS (sizeof(minor2disktype)/sizeof(*minor2disktype))
+#define NUM_DISK_MINORS ARRAY_SIZE(minor2disktype)
 
 /*
  * Maximum disk size (in kilobytes). This default is used whenever the
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index a9e33db..88452c7 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1,6 +1,6 @@
 /*
  *    Disk Array driver for HP SA 5xxx and 6xxx Controllers
- *    Copyright 2000, 2005 Hewlett-Packard Development Company, L.P.
+ *    Copyright 2000, 2006 Hewlett-Packard Development Company, L.P.
  *
  *    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
@@ -47,12 +47,12 @@
 #include <linux/completion.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 2.6.8)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,8)
+#define DRIVER_NAME "HP CISS Driver (v 2.6.10)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,10)
 
 /* Embedded module documentation macros - see modules.h */
 MODULE_AUTHOR("Hewlett-Packard Company");
-MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.8");
+MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.10");
 MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
 			" SA6i P600 P800 P400 P400i E200 E200i");
 MODULE_LICENSE("GPL");
@@ -103,7 +103,7 @@
 };
 MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
 
-#define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type))
+#define NR_PRODUCTS ARRAY_SIZE(products)
 
 /*  board_id = Subsystem Device ID & Vendor ID
  *  product = Marketing Name for the board
@@ -153,6 +153,7 @@
 static int cciss_release(struct inode *inode, struct file *filep);
 static int cciss_ioctl(struct inode *inode, struct file *filep, 
 		unsigned int cmd, unsigned long arg);
+static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
 static int revalidate_allvol(ctlr_info_t *host);
 static int cciss_revalidate(struct gendisk *disk);
@@ -166,7 +167,7 @@
 			unsigned int block_size, InquiryData_struct *inq_buff,
 			drive_info_struct *drv);
 static void cciss_getgeometry(int cntl_num);
-
+static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, __u32);
 static void start_io( ctlr_info_t *h);
 static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size,
 	unsigned int use_unit_num, unsigned int log_unit, __u8 page_code,
@@ -194,6 +195,7 @@
 	.open		= cciss_open, 
 	.release       	= cciss_release,
         .ioctl		= cciss_ioctl,
+        .getgeo		= cciss_getgeo,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl   = cciss_compat_ioctl,
 #endif
@@ -282,7 +284,7 @@
                 h->product_name,
                 (unsigned long)h->board_id,
 		h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3],
-                (unsigned int)h->intr,
+                (unsigned int)h->intr[SIMPLE_MODE_INT],
                 h->num_luns, 
 		h->Qdepth, h->commands_outstanding,
 		h->maxQsinceinit, h->max_outstanding, h->maxSG);
@@ -633,6 +635,20 @@
 	return err;
 }
 #endif
+
+static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	drive_info_struct *drv = get_drv(bdev->bd_disk);
+
+	if (!drv->cylinders)
+		return -ENXIO;
+
+	geo->heads = drv->heads;
+	geo->sectors = drv->sectors;
+	geo->cylinders = drv->cylinders;
+	return 0;
+}
+
 /*
  * ioctl 
  */
@@ -651,21 +667,6 @@
 #endif /* CCISS_DEBUG */ 
 	
 	switch(cmd) {
-	case HDIO_GETGEO:
-	{
-                struct hd_geometry driver_geo;
-                if (drv->cylinders) {
-                        driver_geo.heads = drv->heads;
-                        driver_geo.sectors = drv->sectors;
-                        driver_geo.cylinders = drv->cylinders;
-                } else
-			return -ENXIO;
-                driver_geo.start= get_start_sect(inode->i_bdev);
-                if (copy_to_user(argp, &driver_geo, sizeof(struct hd_geometry)))
-                        return  -EFAULT;
-                return(0);
-	}
-
 	case CCISS_GETPCIINFO:
 	{
 		cciss_pci_info_struct pciinfo;
@@ -1146,7 +1147,6 @@
 				del_gendisk(disk);
 			if (q)
 				blk_cleanup_queue(q);
-			put_disk(disk);
 		}
 	}
 
@@ -1465,9 +1465,10 @@
 			request_queue_t *q = disk->queue;
 			if (disk->flags & GENHD_FL_UP)
 				del_gendisk(disk);
-			if (q)	
+			if (q) {
 				blk_cleanup_queue(q);
-			put_disk(disk);	
+				drv->queue = NULL;
+			}
 		}
 	}
 
@@ -2310,7 +2311,7 @@
 	printk("Done with %p\n", cmd->rq);
 #endif /* CCISS_DEBUG */ 
 
-	end_that_request_last(cmd->rq);
+	end_that_request_last(cmd->rq, status ? 1 : -EIO);
 	cmd_free(h,cmd,1);
 }
 
@@ -2661,6 +2662,60 @@
 	return -1;
 }
 
+/* If MSI/MSI-X is supported by the kernel we will try to enable it on
+ * controllers that are capable. If not, we use IO-APIC mode.
+ */
+
+static void __devinit cciss_interrupt_mode(ctlr_info_t *c, struct pci_dev *pdev, __u32 board_id)
+{
+#ifdef CONFIG_PCI_MSI
+        int err;
+        struct msix_entry cciss_msix_entries[4] = {{0,0}, {0,1},
+						   {0,2}, {0,3}};
+
+	/* Some boards advertise MSI but don't really support it */
+	if ((board_id == 0x40700E11) ||
+		(board_id == 0x40800E11) ||
+		(board_id == 0x40820E11) ||
+		(board_id == 0x40830E11))
+		goto default_int_mode;
+
+        if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) {
+                err = pci_enable_msix(pdev, cciss_msix_entries, 4);
+                if (!err) {
+                        c->intr[0] = cciss_msix_entries[0].vector;
+                        c->intr[1] = cciss_msix_entries[1].vector;
+                        c->intr[2] = cciss_msix_entries[2].vector;
+                        c->intr[3] = cciss_msix_entries[3].vector;
+                        c->msix_vector = 1;
+                        return;
+                }
+                if (err > 0) {
+                        printk(KERN_WARNING "cciss: only %d MSI-X vectors "
+                                        "available\n", err);
+                } else {
+                        printk(KERN_WARNING "cciss: MSI-X init failed %d\n",
+						err);
+                }
+        }
+        if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) {
+                if (!pci_enable_msi(pdev)) {
+                        c->intr[SIMPLE_MODE_INT] = pdev->irq;
+                        c->msi_vector = 1;
+                        return;
+                } else {
+                        printk(KERN_WARNING "cciss: MSI init failed\n");
+        		c->intr[SIMPLE_MODE_INT] = pdev->irq;
+                        return;
+                }
+        }
+#endif /* CONFIG_PCI_MSI */
+	/* if we get here we're going to use the default interrupt mode */
+default_int_mode:
+        c->intr[SIMPLE_MODE_INT] = pdev->irq;
+	return;
+}
+
 static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 {
 	ushort subsystem_vendor_id, subsystem_device_id, command;
@@ -2721,7 +2776,10 @@
 	printk("board_id = %x\n", board_id);
 #endif /* CCISS_DEBUG */ 
 
-	c->intr = pdev->irq;
+/* If the kernel supports MSI/MSI-X we will try to enable that functionality,
+ * else we use the IO-APIC interrupt assigned to us by system ROM.
+ */
+	cciss_interrupt_mode(c, pdev, board_id);
 
 	/*
 	 * Memory base addr is first addr , the second points to the config
@@ -2775,7 +2833,7 @@
 	c->board_id = board_id;
 
 #ifdef CCISS_DEBUG
-	print_cfg_table(c->cfgtable); 
+	print_cfg_table(c->cfgtable);
 #endif /* CCISS_DEBUG */
 
 	for(i=0; i<NR_PRODUCTS; i++) {
@@ -3060,7 +3118,7 @@
 	 * 8 controller support.
 	 */
 	if (i < MAX_CTLR_ORIG)
-		hba[i]->major = MAJOR_NR + i;
+		hba[i]->major = COMPAQ_CISS_MAJOR + i;
 	rc = register_blkdev(hba[i]->major, hba[i]->devname);
 	if(rc == -EBUSY || rc == -EINVAL) {
 		printk(KERN_ERR
@@ -3075,11 +3133,11 @@
 
 	/* make sure the board interrupts are off */
 	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
-	if( request_irq(hba[i]->intr, do_cciss_intr, 
+	if( request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr,
 		SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
 			hba[i]->devname, hba[i])) {
 		printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
-			hba[i]->intr, hba[i]->devname);
+			hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname);
 		goto clean2;
 	}
 	hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL);
@@ -3185,7 +3243,7 @@
 			NR_CMDS * sizeof( ErrorInfo_struct),
 			hba[i]->errinfo_pool,
 			hba[i]->errinfo_pool_dhandle);
-	free_irq(hba[i]->intr, hba[i]);
+	free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]);
 clean2:
 	unregister_blkdev(hba[i]->major, hba[i]->devname);
 clean1:
@@ -3226,7 +3284,15 @@
 		printk(KERN_WARNING "Error Flushing cache on controller %d\n", 
 			i);
 	}
-	free_irq(hba[i]->intr, hba[i]);
+	free_irq(hba[i]->intr[2], hba[i]);
+
+#ifdef CONFIG_PCI_MSI
+        if (hba[i]->msix_vector)
+                pci_disable_msix(hba[i]->pdev);
+        else if (hba[i]->msi_vector)
+                pci_disable_msi(hba[i]->pdev);
+#endif /* CONFIG_PCI_MSI */
+
 	pci_set_drvdata(pdev, NULL);
 	iounmap(hba[i]->vaddr);
 	cciss_unregister_scsi(i);  /* unhook from SCSI subsystem */
@@ -3243,7 +3309,6 @@
 				del_gendisk(disk);
 			if (q)
 				blk_cleanup_queue(q);
-			put_disk(disk);
 		}
 	}
 
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 3b0858c..b24fc05 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -13,8 +13,6 @@
 #define IO_OK		0
 #define IO_ERROR	1
 
-#define MAJOR_NR COMPAQ_CISS_MAJOR
-
 struct ctlr_info;
 typedef struct ctlr_info ctlr_info_t;
 
@@ -65,7 +63,6 @@
 	unsigned long io_mem_addr;
 	unsigned long io_mem_length;
 	CfgTable_struct __iomem *cfgtable;
-	unsigned int intr;
 	int	interrupts_enabled;
 	int	major;
 	int 	max_commands;
@@ -74,6 +71,13 @@
 	int	num_luns;
 	int 	highest_lun;
 	int	usage_count;  /* number of opens all all minor devices */
+#	define DOORBELL_INT	0
+#	define PERF_MODE_INT	1
+#	define SIMPLE_MODE_INT	2
+#	define MEMQ_MODE_INT	3
+	unsigned int intr[4];
+	unsigned int msix_vector;
+	unsigned int msi_vector;
 
 	// information about each logical volume
 	drive_info_struct drv[CISS_MAX_LUN];
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 2942d32..9e35de0 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -714,7 +714,7 @@
 	((struct cciss_scsi_adapter_data_t *) 
 		hba[ctlr]->scsi_ctlr)->scsi_host = (void *) sh;
 	sh->hostdata[0] = (unsigned long) hba[ctlr];
-	sh->irq = hba[ctlr]->intr;
+	sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT];
 	sh->unique_id = sh->irq;
 	error = scsi_add_host(sh, &hba[ctlr]->pdev->dev);
 	if (error)
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index cf1822a..862b9ab 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -72,11 +72,11 @@
 
 static int eisa[8];
 
-#define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type))
+#define NR_PRODUCTS ARRAY_SIZE(products)
 
 /*  board_id = Subsystem Device ID & Vendor ID
  *  product = Marketing Name for the board
- *  access = Address of the struct of function pointers 
+ *  access = Address of the struct of function pointers
  */
 static struct board_type products[] = {
 	{ 0x0040110E, "IDA",			&smart1_access },
@@ -160,6 +160,7 @@
 static int ida_open(struct inode *inode, struct file *filep);
 static int ida_release(struct inode *inode, struct file *filep);
 static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg);
+static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io);
 
 static void do_ida_request(request_queue_t *q);
@@ -199,6 +200,7 @@
 	.open		= ida_open,
 	.release	= ida_release,
 	.ioctl		= ida_ioctl,
+	.getgeo		= ida_getgeo,
 	.revalidate_disk= ida_revalidate,
 };
 
@@ -1036,7 +1038,7 @@
 	complete_buffers(cmd->rq->bio, ok);
 
         DBGPX(printk("Done with %p\n", cmd->rq););
-	end_that_request_last(cmd->rq);
+	end_that_request_last(cmd->rq, ok ? 1 : -EIO);
 }
 
 /*
@@ -1124,6 +1126,23 @@
 	h->misc_tflags = 0;
 }
 
+static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	drv_info_t *drv = get_drv(bdev->bd_disk);
+
+	if (drv->cylinders) {
+		geo->heads = drv->heads;
+		geo->sectors = drv->sectors;
+		geo->cylinders = drv->cylinders;
+	} else {
+		geo->heads = 0xff;
+		geo->sectors = 0x3f;
+		geo->cylinders = drv->nr_blks / (0xff*0x3f);
+	}
+
+	return 0;
+}
+
 /*
  *  ida_ioctl does some miscellaneous stuff like reporting drive geometry,
  *  setting readahead and submitting commands from userspace to the controller.
@@ -1133,27 +1152,10 @@
 	drv_info_t *drv = get_drv(inode->i_bdev->bd_disk);
 	ctlr_info_t *host = get_host(inode->i_bdev->bd_disk);
 	int error;
-	int diskinfo[4];
-	struct hd_geometry __user *geo = (struct hd_geometry __user *)arg;
 	ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg;
 	ida_ioctl_t *my_io;
 
 	switch(cmd) {
-	case HDIO_GETGEO:
-		if (drv->cylinders) {
-			diskinfo[0] = drv->heads;
-			diskinfo[1] = drv->sectors;
-			diskinfo[2] = drv->cylinders;
-		} else {
-			diskinfo[0] = 0xff;
-			diskinfo[1] = 0x3f;
-			diskinfo[2] = drv->nr_blks / (0xff*0x3f);
-		}
-		put_user(diskinfo[0], &geo->heads);
-		put_user(diskinfo[1], &geo->sectors);
-		put_user(diskinfo[2], &geo->cylinders);
-		put_user(get_start_sect(inode->i_bdev), &geo->start);
-		return 0;
 	case IDAGETDRVINFO:
 		if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t)))
 			return -EFAULT;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index f7e765a..374621a 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -479,7 +479,6 @@
 	{ 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5"    */
 };
 
-#define	NUMBER(x)	(sizeof(x) / sizeof(*(x)))
 #define SECTSIZE (_FD_SECTSIZE(*floppy))
 
 /* Auto-detection: Disk type used until the next media change occurs. */
@@ -2301,7 +2300,7 @@
 	add_disk_randomness(req->rq_disk);
 	floppy_off((long)req->rq_disk->private_data);
 	blkdev_dequeue_request(req);
-	end_that_request_last(req);
+	end_that_request_last(req, uptodate);
 
 	/* We're done with the request */
 	current_req = NULL;
@@ -3445,6 +3444,23 @@
 	return 0;
 }
 
+static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	int drive = (long)bdev->bd_disk->private_data;
+	int type = ITYPE(drive_state[drive].fd_device);
+	struct floppy_struct *g;
+	int ret;
+
+	ret = get_floppy_geometry(drive, type, &g);
+	if (ret)
+		return ret;
+
+	geo->heads = g->head;
+	geo->sectors = g->sect;
+	geo->cylinders = g->track;
+	return 0;
+}
+
 static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 		    unsigned long param)
 {
@@ -3474,23 +3490,6 @@
 		cmd = FDEJECT;
 	}
 
-	/* generic block device ioctls */
-	switch (cmd) {
-		/* the following have been inspired by the corresponding
-		 * code for other block devices. */
-		struct floppy_struct *g;
-	case HDIO_GETGEO:
-		{
-			struct hd_geometry loc;
-			ECALL(get_floppy_geometry(drive, type, &g));
-			loc.heads = g->head;
-			loc.sectors = g->sect;
-			loc.cylinders = g->track;
-			loc.start = 0;
-			return _COPYOUT(loc);
-		}
-	}
-
 	/* convert the old style command into a new style command */
 	if ((cmd & 0xff00) == 0x0200) {
 		ECALL(normalize_ioctl(&cmd, &size));
@@ -3645,7 +3644,7 @@
 		const char *name = NULL;
 		static char temparea[32];
 
-		if (type < NUMBER(default_drive_params)) {
+		if (type < ARRAY_SIZE(default_drive_params)) {
 			params = &default_drive_params[type].params;
 			if (type) {
 				name = default_drive_params[type].name;
@@ -3938,6 +3937,7 @@
 	.open		= floppy_open,
 	.release	= floppy_release,
 	.ioctl		= fd_ioctl,
+	.getgeo		= fd_getgeo,
 	.media_changed	= check_floppy_change,
 	.revalidate_disk = floppy_revalidate,
 };
@@ -3960,7 +3960,7 @@
 {
 	int base_minor = (drive < 4) ? drive : (124 + drive);
 
-	if (UDP->cmos < NUMBER(default_drive_params)) {
+	if (UDP->cmos < ARRAY_SIZE(default_drive_params)) {
 		int i = 0;
 		do {
 			int minor = base_minor + (table_sup[UDP->cmos][i] << 2);
@@ -4218,7 +4218,7 @@
 	    !(allowed_drive_mask & (1 << drive)) ||
 	    fdc_state[FDC(drive)].version == FDC_NONE)
 		return NULL;
-	if (((*part >> 2) & 0x1f) >= NUMBER(floppy_type))
+	if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type))
 		return NULL;
 	*part = 0;
 	return get_disk(disks[drive]);
@@ -4570,7 +4570,7 @@
 {
 	int i;
 
-	if (UDP->cmos < NUMBER(default_drive_params)) {
+	if (UDP->cmos < ARRAY_SIZE(default_drive_params)) {
 		i = 0;
 		do {
 			devfs_remove("floppy/%d%s", drive,
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 96c664a..a452b13 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -213,7 +213,7 @@
 	struct address_space_operations *aops = mapping->a_ops;
 	pgoff_t index;
 	unsigned offset, bv_offs;
-	int len, ret = 0;
+	int len, ret;
 
 	down(&mapping->host->i_sem);
 	index = pos >> PAGE_CACHE_SHIFT;
@@ -232,9 +232,15 @@
 		page = grab_cache_page(mapping, index);
 		if (unlikely(!page))
 			goto fail;
-		if (unlikely(aops->prepare_write(file, page, offset,
-				offset + size)))
+		ret = aops->prepare_write(file, page, offset,
+					  offset + size);
+		if (unlikely(ret)) {
+			if (ret == AOP_TRUNCATED_PAGE) {
+				page_cache_release(page);
+				continue;
+			}
 			goto unlock;
+		}
 		transfer_result = lo_do_transfer(lo, WRITE, page, offset,
 				bvec->bv_page, bv_offs, size, IV);
 		if (unlikely(transfer_result)) {
@@ -251,9 +257,15 @@
 			kunmap_atomic(kaddr, KM_USER0);
 		}
 		flush_dcache_page(page);
-		if (unlikely(aops->commit_write(file, page, offset,
-				offset + size)))
+		ret = aops->commit_write(file, page, offset,
+					 offset + size);
+		if (unlikely(ret)) {
+			if (ret == AOP_TRUNCATED_PAGE) {
+				page_cache_release(page);
+				continue;
+			}
 			goto unlock;
+		}
 		if (unlikely(transfer_result))
 			goto unlock;
 		bv_offs += size;
@@ -264,6 +276,7 @@
 		unlock_page(page);
 		page_cache_release(page);
 	}
+	ret = 0;
 out:
 	up(&mapping->host->i_sem);
 	return ret;
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 9e268dd..6997d8e 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -54,11 +54,15 @@
 #include <linux/errno.h>
 #include <linux/file.h>
 #include <linux/ioctl.h>
+#include <linux/compiler.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
 #include <net/sock.h>
 
 #include <linux/devfs_fs_kernel.h>
 
 #include <asm/uaccess.h>
+#include <asm/system.h>
 #include <asm/types.h>
 
 #include <linux/nbd.h>
@@ -136,7 +140,7 @@
 
 	spin_lock_irqsave(q->queue_lock, flags);
 	if (!end_that_request_first(req, uptodate, req->nr_sectors)) {
-		end_that_request_last(req);
+		end_that_request_last(req, uptodate);
 	}
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
@@ -170,7 +174,6 @@
 		msg.msg_namelen = 0;
 		msg.msg_control = NULL;
 		msg.msg_controllen = 0;
-		msg.msg_namelen = 0;
 		msg.msg_flags = msg_flags | MSG_NOSIGNAL;
 
 		if (send)
@@ -230,14 +233,6 @@
 	request.len = htonl(size);
 	memcpy(request.handle, &req, sizeof(req));
 
-	down(&lo->tx_lock);
-
-	if (!sock || !lo->sock) {
-		printk(KERN_ERR "%s: Attempted send on closed socket\n",
-				lo->disk->disk_name);
-		goto error_out;
-	}
-
 	dprintk(DBG_TX, "%s: request %p: sending control (%s@%llu,%luB)\n",
 			lo->disk->disk_name, req,
 			nbdcmd_to_ascii(nbd_cmd(req)),
@@ -276,11 +271,9 @@
 			}
 		}
 	}
-	up(&lo->tx_lock);
 	return 0;
 
 error_out:
-	up(&lo->tx_lock);
 	return 1;
 }
 
@@ -289,9 +282,14 @@
 	struct request *req;
 	struct list_head *tmp;
 	struct request *xreq;
+	int err;
 
 	memcpy(&xreq, handle, sizeof(xreq));
 
+	err = wait_event_interruptible(lo->active_wq, lo->active_req != xreq);
+	if (unlikely(err))
+		goto out;
+
 	spin_lock(&lo->queue_lock);
 	list_for_each(tmp, &lo->queue_head) {
 		req = list_entry(tmp, struct request, queuelist);
@@ -302,7 +300,11 @@
 		return req;
 	}
 	spin_unlock(&lo->queue_lock);
-	return NULL;
+
+	err = -ENOENT;
+
+out:
+	return ERR_PTR(err);
 }
 
 static inline int sock_recv_bvec(struct socket *sock, struct bio_vec *bvec)
@@ -331,7 +333,11 @@
 		goto harderror;
 	}
 	req = nbd_find_request(lo, reply.handle);
-	if (req == NULL) {
+	if (unlikely(IS_ERR(req))) {
+		result = PTR_ERR(req);
+		if (result != -ENOENT)
+			goto harderror;
+
 		printk(KERN_ERR "%s: Unexpected reply (%p)\n",
 				lo->disk->disk_name, reply.handle);
 		result = -EBADR;
@@ -395,19 +401,24 @@
 
 	BUG_ON(lo->magic != LO_MAGIC);
 
-	do {
-		req = NULL;
-		spin_lock(&lo->queue_lock);
-		if (!list_empty(&lo->queue_head)) {
-			req = list_entry(lo->queue_head.next, struct request, queuelist);
-			list_del_init(&req->queuelist);
-		}
-		spin_unlock(&lo->queue_lock);
-		if (req) {
-			req->errors++;
-			nbd_end_request(req);
-		}
-	} while (req);
+	/*
+	 * Because we have set lo->sock to NULL under the tx_lock, all
+	 * modifications to the list must have completed by now.  For
+	 * the same reason, the active_req must be NULL.
+	 *
+	 * As a consequence, we don't need to take the spin lock while
+	 * purging the list here.
+	 */
+	BUG_ON(lo->sock);
+	BUG_ON(lo->active_req);
+
+	while (!list_empty(&lo->queue_head)) {
+		req = list_entry(lo->queue_head.next, struct request,
+				 queuelist);
+		list_del_init(&req->queuelist);
+		req->errors++;
+		nbd_end_request(req);
+	}
 }
 
 /*
@@ -435,11 +446,6 @@
 
 		BUG_ON(lo->magic != LO_MAGIC);
 
-		if (!lo->file) {
-			printk(KERN_ERR "%s: Request when not-ready\n",
-					lo->disk->disk_name);
-			goto error_out;
-		}
 		nbd_cmd(req) = NBD_CMD_READ;
 		if (rq_data_dir(req) == WRITE) {
 			nbd_cmd(req) = NBD_CMD_WRITE;
@@ -453,32 +459,34 @@
 		req->errors = 0;
 		spin_unlock_irq(q->queue_lock);
 
-		spin_lock(&lo->queue_lock);
-
-		if (!lo->file) {
-			spin_unlock(&lo->queue_lock);
-			printk(KERN_ERR "%s: failed between accept and semaphore, file lost\n",
-					lo->disk->disk_name);
+		down(&lo->tx_lock);
+		if (unlikely(!lo->sock)) {
+			up(&lo->tx_lock);
+			printk(KERN_ERR "%s: Attempted send on closed socket\n",
+			       lo->disk->disk_name);
 			req->errors++;
 			nbd_end_request(req);
 			spin_lock_irq(q->queue_lock);
 			continue;
 		}
 
-		list_add(&req->queuelist, &lo->queue_head);
-		spin_unlock(&lo->queue_lock);
+		lo->active_req = req;
 
 		if (nbd_send_req(lo, req) != 0) {
 			printk(KERN_ERR "%s: Request send failed\n",
 					lo->disk->disk_name);
-			if (nbd_find_request(lo, (char *)&req) != NULL) {
-				/* we still own req */
-				req->errors++;
-				nbd_end_request(req);
-			} else /* we're racing with nbd_clear_que */
-				printk(KERN_DEBUG "nbd: can't find req\n");
+			req->errors++;
+			nbd_end_request(req);
+		} else {
+			spin_lock(&lo->queue_lock);
+			list_add(&req->queuelist, &lo->queue_head);
+			spin_unlock(&lo->queue_lock);
 		}
 
+		lo->active_req = NULL;
+		up(&lo->tx_lock);
+		wake_up_all(&lo->active_wq);
+
 		spin_lock_irq(q->queue_lock);
 		continue;
 
@@ -529,17 +537,10 @@
 		down(&lo->tx_lock);
 		lo->sock = NULL;
 		up(&lo->tx_lock);
-		spin_lock(&lo->queue_lock);
 		file = lo->file;
 		lo->file = NULL;
-		spin_unlock(&lo->queue_lock);
 		nbd_clear_que(lo);
-		spin_lock(&lo->queue_lock);
-		if (!list_empty(&lo->queue_head)) {
-			printk(KERN_ERR "nbd: disconnect: some requests are in progress -> please try again.\n");
-			error = -EBUSY;
-		}
-		spin_unlock(&lo->queue_lock);
+		BUG_ON(!list_empty(&lo->queue_head));
 		if (file)
 			fput(file);
 		return error;
@@ -598,24 +599,19 @@
 			lo->sock = NULL;
 		}
 		up(&lo->tx_lock);
-		spin_lock(&lo->queue_lock);
 		file = lo->file;
 		lo->file = NULL;
-		spin_unlock(&lo->queue_lock);
 		nbd_clear_que(lo);
 		printk(KERN_WARNING "%s: queue cleared\n", lo->disk->disk_name);
 		if (file)
 			fput(file);
 		return lo->harderror;
 	case NBD_CLEAR_QUE:
-		down(&lo->tx_lock);
-		if (lo->sock) {
-			up(&lo->tx_lock);
-			return 0; /* probably should be error, but that would
-				   * break "nbd-client -d", so just return 0 */
-		}
-		up(&lo->tx_lock);
-		nbd_clear_que(lo);
+		/*
+		 * This is for compatibility only.  The queue is always cleared
+		 * by NBD_DO_IT or NBD_CLEAR_SOCK.
+		 */
+		BUG_ON(!lo->sock && !list_empty(&lo->queue_head));
 		return 0;
 	case NBD_PRINT_DEBUG:
 		printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n",
@@ -688,6 +684,7 @@
 		spin_lock_init(&nbd_dev[i].queue_lock);
 		INIT_LIST_HEAD(&nbd_dev[i].queue_head);
 		init_MUTEX(&nbd_dev[i].tx_lock);
+		init_waitqueue_head(&nbd_dev[i].active_wq);
 		nbd_dev[i].blksize = 1024;
 		nbd_dev[i].bytesize = 0x7ffffc00ULL << 10; /* 2TB */
 		disk->major = NBD_MAJOR;
diff --git a/drivers/block/paride/Kconfig b/drivers/block/paride/Kconfig
index 17ff405..c0d2854 100644
--- a/drivers/block/paride/Kconfig
+++ b/drivers/block/paride/Kconfig
@@ -4,11 +4,12 @@
 # PARIDE doesn't need PARPORT, but if PARPORT is configured as a module,
 # PARIDE must also be a module.  The bogus CONFIG_PARIDE_PARPORT option
 # controls the choices given to the user ...
+# PARIDE only supports PC style parports. Tough for USB or other parports...
 config PARIDE_PARPORT
 	tristate
 	depends on PARIDE!=n
-	default m if PARPORT=m
-	default y if PARPORT!=m
+	default m if PARPORT_PC=m
+	default y if PARPORT_PC!=m
 
 comment "Parallel IDE high-level drivers"
 	depends on PARIDE
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index fa49d62..62d2464 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -747,32 +747,33 @@
 	return 0;
 }
 
+static int pd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct pd_unit *disk = bdev->bd_disk->private_data;
+
+	if (disk->alt_geom) {
+		geo->heads = PD_LOG_HEADS;
+		geo->sectors = PD_LOG_SECTS;
+		geo->cylinders = disk->capacity / (geo->heads * geo->sectors);
+	} else {
+		geo->heads = disk->heads;
+		geo->sectors = disk->sectors;
+		geo->cylinders = disk->cylinders;
+	}
+
+	return 0;
+}
+
 static int pd_ioctl(struct inode *inode, struct file *file,
 	 unsigned int cmd, unsigned long arg)
 {
 	struct pd_unit *disk = inode->i_bdev->bd_disk->private_data;
-	struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;
-	struct hd_geometry g;
 
 	switch (cmd) {
 	case CDROMEJECT:
 		if (disk->access == 1)
 			pd_special_command(disk, pd_eject);
 		return 0;
-	case HDIO_GETGEO:
-		if (disk->alt_geom) {
-			g.heads = PD_LOG_HEADS;
-			g.sectors = PD_LOG_SECTS;
-			g.cylinders = disk->capacity / (g.heads * g.sectors);
-		} else {
-			g.heads = disk->heads;
-			g.sectors = disk->sectors;
-			g.cylinders = disk->cylinders;
-		}
-		g.start = get_start_sect(inode->i_bdev);
-		if (copy_to_user(geo, &g, sizeof(struct hd_geometry)))
-			return -EFAULT;
-		return 0;
 	default:
 		return -EINVAL;
 	}
@@ -815,6 +816,7 @@
 	.open		= pd_open,
 	.release	= pd_release,
 	.ioctl		= pd_ioctl,
+	.getgeo		= pd_getgeo,
 	.media_changed	= pd_check_media,
 	.revalidate_disk= pd_revalidate
 };
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index e9746af2..852b564 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -205,6 +205,7 @@
 static void do_pf_request(request_queue_t * q);
 static int pf_ioctl(struct inode *inode, struct file *file,
 		    unsigned int cmd, unsigned long arg);
+static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
 static int pf_release(struct inode *inode, struct file *file);
 
@@ -266,6 +267,7 @@
 	.open		= pf_open,
 	.release	= pf_release,
 	.ioctl		= pf_ioctl,
+	.getgeo		= pf_getgeo,
 	.media_changed	= pf_check_media,
 };
 
@@ -313,34 +315,34 @@
 	return 0;
 }
 
+static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct pf_unit *pf = bdev->bd_disk->private_data;
+	sector_t capacity = get_capacity(pf->disk);
+
+	if (capacity < PF_FD_MAX) {
+		geo->cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT);
+		geo->heads = PF_FD_HDS;
+		geo->sectors = PF_FD_SPT;
+	} else {
+		geo->cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT);
+		geo->heads = PF_HD_HDS;
+		geo->sectors = PF_HD_SPT;
+	}
+
+	return 0;
+}
+
 static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct pf_unit *pf = inode->i_bdev->bd_disk->private_data;
-	struct hd_geometry __user *geo = (struct hd_geometry __user *) arg;
-	struct hd_geometry g;
-	sector_t capacity;
 
-	if (cmd == CDROMEJECT) {
-		if (pf->access == 1) {
-			pf_eject(pf);
-			return 0;
-		}
-		return -EBUSY;
-	}
-	if (cmd != HDIO_GETGEO)
+	if (cmd != CDROMEJECT)
 		return -EINVAL;
-	capacity = get_capacity(pf->disk);
-	if (capacity < PF_FD_MAX) {
-		g.cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT);
-		g.heads = PF_FD_HDS;
-		g.sectors = PF_FD_SPT;
-	} else {
-		g.cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT);
-		g.heads = PF_HD_HDS;
-		g.sectors = PF_HD_SPT;
-	}
-	if (copy_to_user(geo, &g, sizeof(g)))
-		return -EFAULT;
+
+	if (pf->access != 1)
+		return -EBUSY;
+	pf_eject(pf);
 	return 0;
 }
 
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index c0233ef..51b7a5c 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1955,9 +1955,12 @@
 	if ((ret = blkdev_get(pd->bdev, FMODE_READ, O_RDONLY)))
 		goto out;
 
+	if ((ret = bd_claim(pd->bdev, pd)))
+		goto out_putdev;
+
 	if ((ret = pkt_get_last_written(pd, &lba))) {
 		printk("pktcdvd: pkt_get_last_written failed\n");
-		goto out_putdev;
+		goto out_unclaim;
 	}
 
 	set_capacity(pd->disk, lba << 2);
@@ -1967,7 +1970,7 @@
 	q = bdev_get_queue(pd->bdev);
 	if (write) {
 		if ((ret = pkt_open_write(pd)))
-			goto out_putdev;
+			goto out_unclaim;
 		/*
 		 * Some CDRW drives can not handle writes larger than one packet,
 		 * even if the size is a multiple of the packet size.
@@ -1982,13 +1985,15 @@
 	}
 
 	if ((ret = pkt_set_segment_merging(pd, q)))
-		goto out_putdev;
+		goto out_unclaim;
 
 	if (write)
 		printk("pktcdvd: %lukB available on disc\n", lba << 1);
 
 	return 0;
 
+out_unclaim:
+	bd_release(pd->bdev);
 out_putdev:
 	blkdev_put(pd->bdev);
 out:
@@ -2007,6 +2012,7 @@
 	pkt_lock_door(pd, 0);
 
 	pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
+	bd_release(pd->bdev);
 	blkdev_put(pd->bdev);
 }
 
diff --git a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
index 29d1518..43415f6 100644
--- a/drivers/block/ps2esdi.c
+++ b/drivers/block/ps2esdi.c
@@ -81,8 +81,7 @@
 static void ps2esdi_normal_interrupt_handler(u_int);
 static void ps2esdi_initial_reset_int_handler(u_int);
 static void ps2esdi_geometry_int_handler(u_int);
-static int ps2esdi_ioctl(struct inode *inode, struct file *file,
-			 u_int cmd, u_long arg);
+static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
 static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
 
@@ -132,7 +131,7 @@
 static struct block_device_operations ps2esdi_fops =
 {
 	.owner		= THIS_MODULE,
-	.ioctl		= ps2esdi_ioctl,
+	.getgeo		= ps2esdi_getgeo,
 };
 
 static struct gendisk *ps2esdi_gendisk[2];
@@ -1058,21 +1057,13 @@
 
 }
 
-static int ps2esdi_ioctl(struct inode *inode,
-			 struct file *file, u_int cmd, u_long arg)
+static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	struct ps2esdi_i_struct *p = inode->i_bdev->bd_disk->private_data;
-	struct ps2esdi_geometry geom;
+	struct ps2esdi_i_struct *p = bdev->bd_disk->private_data;
 
-	if (cmd != HDIO_GETGEO)
-		return -EINVAL;
-	memset(&geom, 0, sizeof(geom));
-	geom.heads = p->head;
-	geom.sectors = p->sect;
-	geom.cylinders = p->cyl;
-	geom.start = get_start_sect(inode->i_bdev);
-	if (copy_to_user((void __user *)arg, &geom, sizeof(geom)))
-		return -EFAULT;
+	geo->heads = p->head;
+	geo->sectors = p->sect;
+	geo->cylinders = p->cyl;
 	return 0;
 }
 
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 68c60a5..ffd6abd 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -154,7 +154,7 @@
 
 /*
  * ->writepage to the the blockdev's mapping has to redirty the page so that the
- * VM doesn't go and steal it.  We return WRITEPAGE_ACTIVATE so that the VM
+ * VM doesn't go and steal it.  We return AOP_WRITEPAGE_ACTIVATE so that the VM
  * won't try to (pointlessly) write the page again for a while.
  *
  * Really, these pages should not be on the LRU at all.
@@ -165,7 +165,7 @@
 		make_page_uptodate(page);
 	SetPageDirty(page);
 	if (wbc->for_reclaim)
-		return WRITEPAGE_ACTIVATE;
+		return AOP_WRITEPAGE_ACTIVATE;
 	unlock_page(page);
 	return 0;
 }
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 1ded3b4..c0cdc18 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -407,8 +407,7 @@
 
 static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static void carm_remove_one (struct pci_dev *pdev);
-static int carm_bdev_ioctl(struct inode *ino, struct file *fil,
-			   unsigned int cmd, unsigned long arg);
+static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo);
 
 static struct pci_device_id carm_pci_tbl[] = {
 	{ PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
@@ -426,7 +425,7 @@
 
 static struct block_device_operations carm_bd_ops = {
 	.owner		= THIS_MODULE,
-	.ioctl		= carm_bdev_ioctl,
+	.getgeo		= carm_bdev_getgeo,
 };
 
 static unsigned int carm_host_id;
@@ -434,32 +433,14 @@
 
 
 
-static int carm_bdev_ioctl(struct inode *ino, struct file *fil,
-			   unsigned int cmd, unsigned long arg)
+static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	void __user *usermem = (void __user *) arg;
-	struct carm_port *port = ino->i_bdev->bd_disk->private_data;
-	struct hd_geometry geom;
+	struct carm_port *port = bdev->bd_disk->private_data;
 
-	switch (cmd) {
-	case HDIO_GETGEO:
-		if (!usermem)
-			return -EINVAL;
-
-		geom.heads = (u8) port->dev_geom_head;
-		geom.sectors = (u8) port->dev_geom_sect;
-		geom.cylinders = port->dev_geom_cyl;
-		geom.start = get_start_sect(ino->i_bdev);
-
-		if (copy_to_user(usermem, &geom, sizeof(geom)))
-			return -EFAULT;
-		return 0;
-
-	default:
-		break;
-	}
-
-	return -EOPNOTSUPP;
+	geo->heads = (u8) port->dev_geom_head;
+	geo->sectors = (u8) port->dev_geom_sect;
+	geo->cylinders = port->dev_geom_cyl;
+	return 0;
 }
 
 static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE };
@@ -770,7 +751,7 @@
 	rc = end_that_request_first(req, uptodate, req->hard_nr_sectors);
 	assert(rc == 0);
 
-	end_that_request_last(req);
+	end_that_request_last(req, uptodate);
 
 	rc = carm_put_request(host, crq);
 	assert(rc == 0);
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index bfb23d5..a05fe58 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -9,7 +9,6 @@
  *
  * TODO (sorted by decreasing priority)
  *  -- Kill first_open (Al Viro fixed the block layer now)
- *  -- Do resets with usb_device_reset (needs a thread context, use khubd)
  *  -- set readonly flag for CDs, set removable flag for CF readers
  *  -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
  *  -- special case some senses, e.g. 3a/0 -> no media present, reduce retries
@@ -29,6 +28,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/usb.h>
+#include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/devfs_fs_kernel.h>
 #include <linux/timer.h>
@@ -107,16 +107,6 @@
  */
 
 /*
- * Definitions which have to be scattered once we understand the layout better.
- */
-
-/* Transport (despite PR in the name) */
-#define US_PR_BULK	0x50		/* bulk only */
-
-/* Protocol */
-#define US_SC_SCSI	0x06		/* Transparent */
-
-/*
  * This many LUNs per USB device.
  * Every one of them takes a host, see UB_MAX_HOSTS.
  */
@@ -125,7 +115,7 @@
 /*
  */
 
-#define UB_MINORS_PER_MAJOR	8
+#define UB_PARTS_PER_LUN      8
 
 #define UB_MAX_CDB_SIZE      16		/* Corresponds to Bulk */
 
@@ -245,6 +235,13 @@
 	void *back;
 };
 
+struct ub_request {
+	struct request *rq;
+	unsigned int current_try;
+	unsigned int nsg;		/* sgv[nsg] */
+	struct scatterlist sgv[UB_MAX_REQ_SG];
+};
+
 /*
  */
 struct ub_capacity {
@@ -340,6 +337,8 @@
 	int readonly;
 	int first_open;			/* Kludge. See ub_bd_open. */
 
+	struct ub_request urq;
+
 	/* Use Ingo's mempool if or when we have more than one command. */
 	/*
 	 * Currently we never need more than one command for the whole device.
@@ -360,6 +359,7 @@
 	atomic_t poison;		/* The USB device is disconnected */
 	int openc;			/* protected by ub_lock! */
 					/* kref is too implicit for our taste */
+	int reset;			/* Reset is running */
 	unsigned int tagcnt;
 	char name[12];
 	struct usb_device *dev;
@@ -387,6 +387,9 @@
 	struct bulk_cs_wrap work_bcs;
 	struct usb_ctrlrequest work_cr;
 
+	struct work_struct reset_work;
+	wait_queue_head_t reset_wait;
+
 	int sg_stat[6];
 	struct ub_scsi_trace tr;
 };
@@ -395,12 +398,14 @@
  */
 static void ub_cleanup(struct ub_dev *sc);
 static int ub_request_fn_1(struct ub_lun *lun, struct request *rq);
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq);
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq);
+static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq);
+static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq);
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_end_rq(struct request *rq, int uptodate);
+static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_request *urq, struct ub_scsi_cmd *cmd);
 static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
 static void ub_urb_complete(struct urb *urb, struct pt_regs *pt);
 static void ub_scsi_action(unsigned long _dev);
@@ -415,6 +420,8 @@
 static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd,
     int stalled_pipe);
 static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd);
+static void ub_reset_enter(struct ub_dev *sc);
+static void ub_reset_task(void *arg);
 static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun);
 static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_capacity *ret);
@@ -422,13 +429,18 @@
 
 /*
  */
+#ifdef CONFIG_USB_LIBUSUAL
+
+#define ub_usb_ids  storage_usb_ids
+#else
+
 static struct usb_device_id ub_usb_ids[] = {
-	// { USB_DEVICE_VER(0x0781, 0x0002, 0x0009, 0x0009) },	/* SDDR-31 */
 	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
 	{ }
 };
 
 MODULE_DEVICE_TABLE(usb, ub_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
 
 /*
  * Find me a way to identify "next free minor" for add_disk(),
@@ -522,6 +534,9 @@
 	spin_lock_irqsave(&sc->lock, flags);
 
 	cnt += sprintf(page + cnt,
+	    "poison %d reset %d\n",
+	    atomic_read(&sc->poison), sc->reset);
+	cnt += sprintf(page + cnt,
 	    "qlen %d qmax %d\n",
 	    sc->cmd_queue.qlen, sc->cmd_queue.qmax);
 	cnt += sprintf(page + cnt,
@@ -770,7 +785,8 @@
 {
 	struct ub_dev *sc = lun->udev;
 	struct ub_scsi_cmd *cmd;
-	int rc;
+	struct ub_request *urq;
+	int n_elem;
 
 	if (atomic_read(&sc->poison) || lun->changed) {
 		blkdev_dequeue_request(rq);
@@ -778,66 +794,71 @@
 		return 0;
 	}
 
+	if (lun->urq.rq != NULL)
+		return -1;
 	if ((cmd = ub_get_cmd(lun)) == NULL)
 		return -1;
 	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
 
 	blkdev_dequeue_request(rq);
-	if (blk_pc_request(rq)) {
-		rc = ub_cmd_build_packet(sc, lun, cmd, rq);
-	} else {
-		rc = ub_cmd_build_block(sc, lun, cmd, rq);
-	}
-	if (rc != 0) {
-		ub_put_cmd(lun, cmd);
-		ub_end_rq(rq, 0);
-		return 0;
-	}
-	cmd->state = UB_CMDST_INIT;
-	cmd->lun = lun;
-	cmd->done = ub_rw_cmd_done;
-	cmd->back = rq;
 
-	cmd->tag = sc->tagcnt++;
-	if (ub_submit_scsi(sc, cmd) != 0) {
-		ub_put_cmd(lun, cmd);
-		ub_end_rq(rq, 0);
-		return 0;
-	}
-
-	return 0;
-}
-
-static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq)
-{
-	int ub_dir;
-	int n_elem;
-	unsigned int block, nblks;
-
-	if (rq_data_dir(rq) == WRITE)
-		ub_dir = UB_DIR_WRITE;
-	else
-		ub_dir = UB_DIR_READ;
-	cmd->dir = ub_dir;
+	urq = &lun->urq;
+	memset(urq, 0, sizeof(struct ub_request));
+	urq->rq = rq;
 
 	/*
 	 * get scatterlist from block layer
 	 */
-	n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
-	if (n_elem <= 0) {
+	n_elem = blk_rq_map_sg(lun->disk->queue, rq, &urq->sgv[0]);
+	if (n_elem < 0) {
 		printk(KERN_INFO "%s: failed request map (%d)\n",
-		    sc->name, n_elem); /* P3 */
-		return -1;		/* request with no s/g entries? */
+		    lun->name, n_elem); /* P3 */
+		goto drop;
 	}
 	if (n_elem > UB_MAX_REQ_SG) {	/* Paranoia */
 		printk(KERN_WARNING "%s: request with %d segments\n",
-		    sc->name, n_elem);
-		return -1;
+		    lun->name, n_elem);
+		goto drop;
 	}
-	cmd->nsg = n_elem;
+	urq->nsg = n_elem;
 	sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
 
+	if (blk_pc_request(rq)) {
+		ub_cmd_build_packet(sc, lun, cmd, urq);
+	} else {
+		ub_cmd_build_block(sc, lun, cmd, urq);
+	}
+	cmd->state = UB_CMDST_INIT;
+	cmd->lun = lun;
+	cmd->done = ub_rw_cmd_done;
+	cmd->back = urq;
+
+	cmd->tag = sc->tagcnt++;
+	if (ub_submit_scsi(sc, cmd) != 0)
+		goto drop;
+
+	return 0;
+
+drop:
+	ub_put_cmd(lun, cmd);
+	ub_end_rq(rq, 0);
+	return 0;
+}
+
+static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq)
+{
+	struct request *rq = urq->rq;
+	unsigned int block, nblks;
+
+	if (rq_data_dir(rq) == WRITE)
+		cmd->dir = UB_DIR_WRITE;
+	else
+		cmd->dir = UB_DIR_READ;
+
+	cmd->nsg = urq->nsg;
+	memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
+
 	/*
 	 * build the command
 	 *
@@ -847,7 +868,7 @@
 	block = rq->sector >> lun->capacity.bshift;
 	nblks = rq->nr_sectors >> lun->capacity.bshift;
 
-	cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10;
+	cmd->cdb[0] = (cmd->dir == UB_DIR_READ)? READ_10: WRITE_10;
 	/* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */
 	cmd->cdb[2] = block >> 24;
 	cmd->cdb[3] = block >> 16;
@@ -858,14 +879,12 @@
 	cmd->cdb_len = 10;
 
 	cmd->len = rq->nr_sectors * 512;
-
-	return 0;
 }
 
-static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
-    struct ub_scsi_cmd *cmd, struct request *rq)
+static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_scsi_cmd *cmd, struct ub_request *urq)
 {
-	int n_elem;
+	struct request *rq = urq->rq;
 
 	if (rq->data_len == 0) {
 		cmd->dir = UB_DIR_NONE;
@@ -874,40 +893,26 @@
 			cmd->dir = UB_DIR_WRITE;
 		else
 			cmd->dir = UB_DIR_READ;
-
 	}
 
-	/*
-	 * get scatterlist from block layer
-	 */
-	n_elem = blk_rq_map_sg(lun->disk->queue, rq, &cmd->sgv[0]);
-	if (n_elem < 0) {
-		printk(KERN_INFO "%s: failed request map (%d)\n",
-		    sc->name, n_elem); /* P3 */
-		return -1;
-	}
-	if (n_elem > UB_MAX_REQ_SG) {	/* Paranoia */
-		printk(KERN_WARNING "%s: request with %d segments\n",
-		    sc->name, n_elem);
-		return -1;
-	}
-	cmd->nsg = n_elem;
-	sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
+	cmd->nsg = urq->nsg;
+	memcpy(cmd->sgv, urq->sgv, sizeof(struct scatterlist) * cmd->nsg);
 
 	memcpy(&cmd->cdb, rq->cmd, rq->cmd_len);
 	cmd->cdb_len = rq->cmd_len;
 
 	cmd->len = rq->data_len;
-
-	return 0;
 }
 
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 {
-	struct request *rq = cmd->back;
 	struct ub_lun *lun = cmd->lun;
+	struct ub_request *urq = cmd->back;
+	struct request *rq;
 	int uptodate;
 
+	rq = urq->rq;
+
 	if (cmd->error == 0) {
 		uptodate = 1;
 
@@ -928,9 +933,16 @@
 				rq->errors = SAM_STAT_CHECK_CONDITION;
 			else
 				rq->errors = DID_ERROR << 16;
+		} else {
+			if (cmd->error == -EIO) {
+				if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0)
+					return;
+			}
 		}
 	}
 
+	urq->rq = NULL;
+
 	ub_put_cmd(lun, cmd);
 	ub_end_rq(rq, uptodate);
 	blk_start_queue(lun->disk->queue);
@@ -938,11 +950,43 @@
 
 static void ub_end_rq(struct request *rq, int uptodate)
 {
-	int rc;
+	end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
+	end_that_request_last(rq, uptodate);
+}
 
-	rc = end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
-	// assert(rc == 0);
-	end_that_request_last(rq);
+static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
+    struct ub_request *urq, struct ub_scsi_cmd *cmd)
+{
+
+	if (atomic_read(&sc->poison))
+		return -ENXIO;
+
+	ub_reset_enter(sc);
+
+	if (urq->current_try >= 3)
+		return -EIO;
+	urq->current_try++;
+	/* P3 */ printk("%s: dir %c len/act %d/%d "
+	    "[sense %x %02x %02x] retry %d\n",
+	    sc->name, UB_DIR_CHAR(cmd->dir), cmd->len, cmd->act_len,
+	    cmd->key, cmd->asc, cmd->ascq, urq->current_try);
+
+	memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+	ub_cmd_build_block(sc, lun, cmd, urq);
+
+	cmd->state = UB_CMDST_INIT;
+	cmd->lun = lun;
+	cmd->done = ub_rw_cmd_done;
+	cmd->back = urq;
+
+	cmd->tag = sc->tagcnt++;
+
+#if 0 /* Wasteful */
+	return ub_submit_scsi(sc, cmd);
+#else
+	ub_cmdq_add(sc, cmd);
+	return 0;
+#endif
 }
 
 /*
@@ -1075,7 +1119,7 @@
 	struct ub_scsi_cmd *cmd;
 	int rc;
 
-	while ((cmd = ub_cmdq_peek(sc)) != NULL) {
+	while (!sc->reset && (cmd = ub_cmdq_peek(sc)) != NULL) {
 		if (cmd->state == UB_CMDST_DONE) {
 			ub_cmdq_pop(sc);
 			(*cmd->done)(sc, cmd);
@@ -1098,11 +1142,12 @@
 {
 	struct urb *urb = &sc->work_urb;
 	struct bulk_cs_wrap *bcs;
+	int len;
 	int rc;
 
 	if (atomic_read(&sc->poison)) {
-		/* A little too simplistic, I feel... */
-		goto Bad_End;
+		ub_state_done(sc, cmd, -ENODEV);
+		return;
 	}
 
 	if (cmd->state == UB_CMDST_CLEAR) {
@@ -1110,7 +1155,6 @@
 			/*
 			 * STALL while clearning STALL.
 			 * The control pipe clears itself - nothing to do.
-			 * XXX Might try to reset the device here and retry.
 			 */
 			printk(KERN_NOTICE "%s: stall on control pipe\n",
 			    sc->name);
@@ -1129,11 +1173,6 @@
 
 	} else if (cmd->state == UB_CMDST_CLR2STS) {
 		if (urb->status == -EPIPE) {
-			/*
-			 * STALL while clearning STALL.
-			 * The control pipe clears itself - nothing to do.
-			 * XXX Might try to reset the device here and retry.
-			 */
 			printk(KERN_NOTICE "%s: stall on control pipe\n",
 			    sc->name);
 			goto Bad_End;
@@ -1151,11 +1190,6 @@
 
 	} else if (cmd->state == UB_CMDST_CLRRS) {
 		if (urb->status == -EPIPE) {
-			/*
-			 * STALL while clearning STALL.
-			 * The control pipe clears itself - nothing to do.
-			 * XXX Might try to reset the device here and retry.
-			 */
 			printk(KERN_NOTICE "%s: stall on control pipe\n",
 			    sc->name);
 			goto Bad_End;
@@ -1172,7 +1206,12 @@
 		ub_state_stat_counted(sc, cmd);
 
 	} else if (cmd->state == UB_CMDST_CMD) {
-		if (urb->status == -EPIPE) {
+		switch (urb->status) {
+		case 0:
+			break;
+		case -EOVERFLOW:
+			goto Bad_End;
+		case -EPIPE:
 			rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe);
 			if (rc != 0) {
 				printk(KERN_NOTICE "%s: "
@@ -1182,17 +1221,20 @@
 				 * This is typically ENOMEM or some other such shit.
 				 * Retrying is pointless. Just do Bad End on it...
 				 */
-				goto Bad_End;
+				ub_state_done(sc, cmd, rc);
+				return;
 			}
 			cmd->state = UB_CMDST_CLEAR;
 			ub_cmdtr_state(sc, cmd);
 			return;
-		}
-		if (urb->status != 0) {
+		case -ESHUTDOWN:	/* unplug */
+		case -EILSEQ:		/* unplug timeout on uhci */
+			ub_state_done(sc, cmd, -ENODEV);
+			return;
+		default:
 			goto Bad_End;
 		}
 		if (urb->actual_length != US_BULK_CB_WRAP_LEN) {
-			/* XXX Must do reset here to unconfuse the device */
 			goto Bad_End;
 		}
 
@@ -1211,11 +1253,8 @@
 				printk(KERN_NOTICE "%s: "
 				    "unable to submit clear (%d)\n",
 				    sc->name, rc);
-				/*
-				 * This is typically ENOMEM or some other such shit.
-				 * Retrying is pointless. Just do Bad End on it...
-				 */
-				goto Bad_End;
+				ub_state_done(sc, cmd, rc);
+				return;
 			}
 			cmd->state = UB_CMDST_CLR2STS;
 			ub_cmdtr_state(sc, cmd);
@@ -1224,14 +1263,50 @@
 		if (urb->status == -EOVERFLOW) {
 			/*
 			 * A babble? Failure, but we must transfer CSW now.
-			 * XXX This is going to end in perpetual babble. Reset.
 			 */
 			cmd->error = -EOVERFLOW;	/* A cheap trick... */
 			ub_state_stat(sc, cmd);
 			return;
 		}
-		if (urb->status != 0)
-			goto Bad_End;
+
+		if (cmd->dir == UB_DIR_WRITE) {
+			/*
+			 * Do not continue writes in case of a failure.
+			 * Doing so would cause sectors to be mixed up,
+			 * which is worse than sectors lost.
+			 *
+			 * We must try to read the CSW, or many devices
+			 * get confused.
+			 */
+			len = urb->actual_length;
+			if (urb->status != 0 ||
+			    len != cmd->sgv[cmd->current_sg].length) {
+				cmd->act_len += len;
+				ub_cmdtr_act_len(sc, cmd);
+
+				cmd->error = -EIO;
+				ub_state_stat(sc, cmd);
+				return;
+			}
+
+		} else {
+			/*
+			 * If an error occurs on read, we record it, and
+			 * continue to fetch data in order to avoid bubble.
+			 *
+			 * As a small shortcut, we stop if we detect that
+			 * a CSW mixed into data.
+			 */
+			if (urb->status != 0)
+				cmd->error = -EIO;
+
+			len = urb->actual_length;
+			if (urb->status != 0 ||
+			    len != cmd->sgv[cmd->current_sg].length) {
+				if ((len & 0x1FF) == US_BULK_CS_WRAP_LEN)
+					goto Bad_End;
+			}
+		}
 
 		cmd->act_len += urb->actual_length;
 		ub_cmdtr_act_len(sc, cmd);
@@ -1249,11 +1324,8 @@
 				printk(KERN_NOTICE "%s: "
 				    "unable to submit clear (%d)\n",
 				    sc->name, rc);
-				/*
-				 * This is typically ENOMEM or some other such shit.
-				 * Retrying is pointless. Just do Bad End on it...
-				 */
-				goto Bad_End;
+				ub_state_done(sc, cmd, rc);
+				return;
 			}
 
 			/*
@@ -1266,14 +1338,8 @@
 			ub_cmdtr_state(sc, cmd);
 			return;
 		}
-		if (urb->status == -EOVERFLOW) {
-			/*
-			 * XXX We are screwed here. Retrying is pointless,
-			 * because the pipelined data will not get in until
-			 * we read with a big enough buffer. We must reset XXX.
-			 */
-			goto Bad_End;
-		}
+
+		/* Catch everything, including -EOVERFLOW and other nasties. */
 		if (urb->status != 0)
 			goto Bad_End;
 
@@ -1319,15 +1385,15 @@
 			return;
 		}
 
-		rc = le32_to_cpu(bcs->Residue);
-		if (rc != cmd->len - cmd->act_len) {
+		len = le32_to_cpu(bcs->Residue);
+		if (len != cmd->len - cmd->act_len) {
 			/*
 			 * It is all right to transfer less, the caller has
 			 * to check. But it's not all right if the device
 			 * counts disagree with our counts.
 			 */
 			/* P3 */ printk("%s: resid %d len %d act %d\n",
-			    sc->name, rc, cmd->len, cmd->act_len);
+			    sc->name, len, cmd->len, cmd->act_len);
 			goto Bad_End;
 		}
 
@@ -1338,13 +1404,13 @@
 			ub_state_sense(sc, cmd);
 			return;
 		case US_BULK_STAT_PHASE:
-			/* XXX We must reset the transport here */
 			/* P3 */ printk("%s: status PHASE\n", sc->name);
 			goto Bad_End;
 		default:
 			printk(KERN_INFO "%s: unknown CSW status 0x%x\n",
 			    sc->name, bcs->Status);
-			goto Bad_End;
+			ub_state_done(sc, cmd, -EINVAL);
+			return;
 		}
 
 		/* Not zeroing error to preserve a babble indicator */
@@ -1364,7 +1430,8 @@
 		printk(KERN_WARNING "%s: "
 		    "wrong command state %d\n",
 		    sc->name, cmd->state);
-		goto Bad_End;
+		ub_state_done(sc, cmd, -EINVAL);
+		return;
 	}
 	return;
 
@@ -1612,6 +1679,93 @@
 }
 
 /*
+ * Reset management
+ */
+
+static void ub_reset_enter(struct ub_dev *sc)
+{
+
+	if (sc->reset) {
+		/* This happens often on multi-LUN devices. */
+		return;
+	}
+	sc->reset = 1;
+
+#if 0 /* Not needed because the disconnect waits for us. */
+	unsigned long flags;
+	spin_lock_irqsave(&ub_lock, flags);
+	sc->openc++;
+	spin_unlock_irqrestore(&ub_lock, flags);
+#endif
+
+#if 0 /* We let them stop themselves. */
+	struct list_head *p;
+	struct ub_lun *lun;
+	list_for_each(p, &sc->luns) {
+		lun = list_entry(p, struct ub_lun, link);
+		blk_stop_queue(lun->disk->queue);
+	}
+#endif
+
+	schedule_work(&sc->reset_work);
+}
+
+static void ub_reset_task(void *arg)
+{
+	struct ub_dev *sc = arg;
+	unsigned long flags;
+	struct list_head *p;
+	struct ub_lun *lun;
+	int lkr, rc;
+
+	if (!sc->reset) {
+		printk(KERN_WARNING "%s: Running reset unrequested\n",
+		    sc->name);
+		return;
+	}
+
+	if (atomic_read(&sc->poison)) {
+		printk(KERN_NOTICE "%s: Not resetting disconnected device\n",
+		    sc->name); /* P3 This floods. Remove soon. XXX */
+	} else if (sc->dev->actconfig->desc.bNumInterfaces != 1) {
+		printk(KERN_NOTICE "%s: Not resetting multi-interface device\n",
+		    sc->name); /* P3 This floods. Remove soon. XXX */
+	} else {
+		if ((lkr = usb_lock_device_for_reset(sc->dev, sc->intf)) < 0) {
+			printk(KERN_NOTICE
+			    "%s: usb_lock_device_for_reset failed (%d)\n",
+			    sc->name, lkr);
+		} else {
+			rc = usb_reset_device(sc->dev);
+			if (rc < 0) {
+				printk(KERN_NOTICE "%s: "
+				    "usb_lock_device_for_reset failed (%d)\n",
+				    sc->name, rc);
+			}
+
+			if (lkr)
+				usb_unlock_device(sc->dev);
+		}
+	}
+
+	/*
+	 * In theory, no commands can be running while reset is active,
+	 * so nobody can ask for another reset, and so we do not need any
+	 * queues of resets or anything. We do need a spinlock though,
+	 * to interact with block layer.
+	 */
+	spin_lock_irqsave(&sc->lock, flags);
+	sc->reset = 0;
+	tasklet_schedule(&sc->tasklet);
+	list_for_each(p, &sc->luns) {
+		lun = list_entry(p, struct ub_lun, link);
+		blk_start_queue(lun->disk->queue);
+	}
+	wake_up(&sc->reset_wait);
+	spin_unlock_irqrestore(&sc->lock, flags);
+}
+
+/*
  * This is called from a process context.
  */
 static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun)
@@ -2146,7 +2300,7 @@
 	if (ep_in == NULL || ep_out == NULL) {
 		printk(KERN_NOTICE "%s: failed endpoint check\n",
 		    sc->name);
-		return -EIO;
+		return -ENODEV;
 	}
 
 	/* Calculate and store the pipe values */
@@ -2172,6 +2326,9 @@
 	int rc;
 	int i;
 
+	if (usb_usual_check_type(dev_id, USB_US_TYPE_UB))
+		return -ENXIO;
+
 	rc = -ENOMEM;
 	if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)
 		goto err_core;
@@ -2181,6 +2338,8 @@
 	usb_init_urb(&sc->work_urb);
 	tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
 	atomic_set(&sc->poison, 0);
+	INIT_WORK(&sc->reset_work, ub_reset_task, sc);
+	init_waitqueue_head(&sc->reset_wait);
 
 	init_timer(&sc->work_timer);
 	sc->work_timer.data = (unsigned long) sc;
@@ -2201,7 +2360,8 @@
 
 	/* XXX Verify that we can handle the device (from descriptors) */
 
-	ub_get_pipes(sc, sc->dev, intf);
+	if (ub_get_pipes(sc, sc->dev, intf) != 0)
+		goto err_dev_desc;
 
 	if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0)
 		goto err_diag;
@@ -2272,6 +2432,7 @@
 
 	/* device_remove_file(&sc->intf->dev, &dev_attr_diag); */
 err_diag:
+err_dev_desc:
 	usb_set_intfdata(intf, NULL);
 	// usb_put_intf(sc->intf);
 	usb_put_dev(sc->dev);
@@ -2309,14 +2470,14 @@
 	ub_revalidate(sc, lun);
 
 	rc = -ENOMEM;
-	if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL)
+	if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL)
 		goto err_diskalloc;
 
 	lun->disk = disk;
 	sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
 	sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
 	disk->major = UB_MAJOR;
-	disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;
+	disk->first_minor = lun->id * UB_PARTS_PER_LUN;
 	disk->fops = &ub_bd_fops;
 	disk->private_data = lun;
 	disk->driverfs_dev = &sc->intf->dev;
@@ -2380,6 +2541,11 @@
 	atomic_set(&sc->poison, 1);
 
 	/*
+	 * Wait for reset to end, if any.
+	 */
+	wait_event(sc->reset_wait, !sc->reset);
+
+	/*
 	 * Blow away queued commands.
 	 *
 	 * Actually, this never works, because before we get here
@@ -2392,7 +2558,7 @@
 	{
 		struct ub_scsi_cmd *cmd;
 		int cnt = 0;
-		while ((cmd = ub_cmdq_pop(sc)) != NULL) {
+		while ((cmd = ub_cmdq_peek(sc)) != NULL) {
 			cmd->error = -ENOTCONN;
 			cmd->state = UB_CMDST_DONE;
 			ub_cmdtr_state(sc, cmd);
@@ -2461,7 +2627,6 @@
 }
 
 static struct usb_driver ub_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ub",
 	.probe =	ub_probe,
 	.disconnect =	ub_disconnect,
@@ -2479,6 +2644,7 @@
 	if ((rc = usb_register(&ub_driver)) != 0)
 		goto err_register;
 
+	usb_usual_set_present(USB_US_TYPE_UB);
 	return 0;
 
 err_register:
@@ -2494,6 +2660,7 @@
 
 	devfs_remove(DEVFS_NAME);
 	unregister_blkdev(UB_MAJOR, DRV_NAME);
+	usb_usual_clear_present(USB_US_TYPE_UB);
 }
 
 module_init(ub_init);
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 0f48301..15299e7 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -809,34 +809,23 @@
 	set_capacity(disk, card->mm_size << 1);
 	return 0;
 }
-/*
------------------------------------------------------------------------------------
---                            mm_ioctl
------------------------------------------------------------------------------------
-*/
-static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
+
+static int mm_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	if (cmd == HDIO_GETGEO) {
-		struct cardinfo *card = i->i_bdev->bd_disk->private_data;
-		int size = card->mm_size * (1024 / MM_HARDSECT);
-		struct hd_geometry geo;
-		/*
-		 * get geometry: we have to fake one...  trim the size to a
-		 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
-		 * whatever cylinders.
-		 */
-		geo.heads     = 64;
-		geo.sectors   = 32;
-		geo.start     = get_start_sect(i->i_bdev);
-		geo.cylinders = size / (geo.heads * geo.sectors);
+	struct cardinfo *card = bdev->bd_disk->private_data;
+	int size = card->mm_size * (1024 / MM_HARDSECT);
 
-		if (copy_to_user((void __user *) arg, &geo, sizeof(geo)))
-			return -EFAULT;
-		return 0;
-	}
-
-	return -EINVAL;
+	/*
+	 * get geometry: we have to fake one...  trim the size to a
+	 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
+	 * whatever cylinders.
+	 */
+	geo->heads     = 64;
+	geo->sectors   = 32;
+	geo->cylinders = size / (geo->heads * geo->sectors);
+	return 0;
 }
+
 /*
 -----------------------------------------------------------------------------------
 --                                mm_check_change
@@ -855,7 +844,7 @@
 */
 static struct block_device_operations mm_fops = {
 	.owner		= THIS_MODULE,
-	.ioctl		= mm_ioctl,
+	.getgeo		= mm_getgeo,
 	.revalidate_disk= mm_revalidate,
 	.media_changed	= mm_check_change,
 };
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index 2d518aa..d1aaf31b 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -247,43 +247,17 @@
 
 /* External ioctl entry point.
  */
-static int viodasd_ioctl(struct inode *ino, struct file *fil,
-			 unsigned int cmd, unsigned long arg)
+static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	unsigned char sectors;
-	unsigned char heads;
-	unsigned short cylinders;
-	struct hd_geometry *geo;
-	struct gendisk *gendisk;
-	struct viodasd_device *d;
+	struct gendisk *disk = bdev->bd_disk;
+	struct viodasd_device *d = disk->private_data;
 
-	switch (cmd) {
-	case HDIO_GETGEO:
-		geo = (struct hd_geometry *)arg;
-		if (geo == NULL)
-			return -EINVAL;
-		if (!access_ok(VERIFY_WRITE, geo, sizeof(*geo)))
-			return -EFAULT;
-		gendisk = ino->i_bdev->bd_disk;
-		d = gendisk->private_data;
-		sectors = d->sectors;
-		if (sectors == 0)
-			sectors = 32;
-		heads = d->tracks;
-		if (heads == 0)
-			heads = 64;
-		cylinders = d->cylinders;
-		if (cylinders == 0)
-			cylinders = get_capacity(gendisk) / (sectors * heads);
-		if (__put_user(sectors, &geo->sectors) ||
-		    __put_user(heads, &geo->heads) ||
-		    __put_user(cylinders, &geo->cylinders) ||
-		    __put_user(get_start_sect(ino->i_bdev), &geo->start))
-			return -EFAULT;
-		return 0;
-	}
+	geo->sectors = d->sectors ? d->sectors : 0;
+	geo->heads = d->tracks ? d->tracks  : 64;
+	geo->cylinders = d->cylinders ? d->cylinders :
+		get_capacity(disk) / (geo->cylinders * geo->heads);
 
-	return -EINVAL;
+	return 0;
 }
 
 /*
@@ -293,7 +267,7 @@
 	.owner = THIS_MODULE,
 	.open = viodasd_open,
 	.release = viodasd_release,
-	.ioctl = viodasd_ioctl,
+	.getgeo = viodasd_getgeo,
 };
 
 /*
@@ -305,7 +279,7 @@
 	if (end_that_request_first(req, uptodate, num_sectors))
 		return;
 	add_disk_randomness(req->rq_disk);
-	end_that_request_last(req);
+	end_that_request_last(req, uptodate);
 }
 
 /*
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 68b6d7b..cbce7c5 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -128,9 +128,12 @@
 
 static struct gendisk *xd_gendisk[2];
 
+static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
+
 static struct block_device_operations xd_fops = {
 	.owner	= THIS_MODULE,
 	.ioctl	= xd_ioctl,
+	.getgeo = xd_getgeo,
 };
 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
 static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
@@ -276,11 +279,11 @@
 		return(1);
 	}
 
-	for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])); i++) {
+	for (i = 0; i < ARRAY_SIZE(xd_bases); i++) {
 		void __iomem *p = ioremap(xd_bases[i], 0x2000);
 		if (!p)
 			continue;
-		for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])); j++) {
+		for (j = 1; j < ARRAY_SIZE(xd_sigs); j++) {
 			const char *s = xd_sigs[j].string;
 			if (check_signature(p + xd_sigs[j].offset, s, strlen(s))) {
 				*controller = j;
@@ -330,22 +333,20 @@
 	}
 }
 
+static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	XD_INFO *p = bdev->bd_disk->private_data;
+
+	geo->heads = p->heads;
+	geo->sectors = p->sectors;
+	geo->cylinders = p->cylinders;
+	return 0;
+}
+
 /* xd_ioctl: handle device ioctl's */
 static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
 {
-	XD_INFO *p = inode->i_bdev->bd_disk->private_data;
-
 	switch (cmd) {
-		case HDIO_GETGEO:
-		{
-			struct hd_geometry g;
-			struct hd_geometry __user *geom= (void __user *)arg;
-			g.heads = p->heads;
-			g.sectors = p->sectors;
-			g.cylinders = p->cylinders;
-			g.start = get_start_sect(inode->i_bdev);
-			return copy_to_user(geom, &g, sizeof(g)) ? -EFAULT : 0;
-		}
 		case HDIO_SET_DMA:
 			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
 			if (xdc_busy) return -EBUSY;
@@ -1017,7 +1018,7 @@
 		case 2: if ((integers[2] > 0) && (integers[2] < 16))
 				xd_irq = integers[2];
 		case 1: xd_override = 1;
-			if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
+			if ((integers[1] >= 0) && (integers[1] < ARRAY_SIZE(xd_sigs)))
 				xd_type = integers[1];
 		case 0: break;
 		default:printk("xd: too many parameters for xd\n");
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 8e7fb35..3e7a067 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -275,7 +275,6 @@
 }
 
 static struct usb_driver bcm203x_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "bcm203x",
 	.probe		= bcm203x_probe,
 	.disconnect	= bcm203x_disconnect,
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 067e278..8947c88 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -768,7 +768,6 @@
 }
 
 static struct usb_driver bfusb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "bfusb",
 	.probe		= bfusb_probe,
 	.disconnect	= bfusb_disconnect,
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index f36c563..9888bc1 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -87,14 +87,8 @@
 
 static void bluecard_config(dev_link_t *link);
 static void bluecard_release(dev_link_t *link);
-static int bluecard_event(event_t event, int priority, event_callback_args_t *args);
 
-static dev_info_t dev_info = "bluecard_cs";
-
-static dev_link_t *bluecard_attach(void);
-static void bluecard_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
+static void bluecard_detach(struct pcmcia_device *p_dev);
 
 
 /* Default baud rate: 57600, 115200, 230400 or 460800 */
@@ -862,17 +856,15 @@
 	return 0;
 }
 
-static dev_link_t *bluecard_attach(void)
+static int bluecard_attach(struct pcmcia_device *p_dev)
 {
 	bluecard_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 
 	link = &info->link;
 	link->priv = info;
@@ -889,50 +881,24 @@
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		bluecard_detach(link);
-		return NULL;
-	}
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	bluecard_config(link);
 
-	return link;
+	return 0;
 }
 
 
-static void bluecard_detach(dev_link_t *link)
+static void bluecard_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	bluecard_info_t *info = link->priv;
-	dev_link_t **linkp;
-	int ret;
-
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-
-	if (*linkp == NULL)
-		return;
 
 	if (link->state & DEV_CONFIG)
 		bluecard_release(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
-
 	kfree(info);
 }
 
@@ -1045,39 +1011,24 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-
-static int bluecard_event(event_t event, int priority, event_callback_args_t *args)
+static int bluecard_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	bluecard_info_t *info = link->priv;
+	dev_link_t *link = dev_to_instance(dev);
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			bluecard_close(info);
-			bluecard_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		bluecard_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int bluecard_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
 
 	return 0;
 }
@@ -1095,10 +1046,11 @@
 	.drv		= {
 		.name	= "bluecard_cs",
 	},
-	.attach		= bluecard_attach,
-	.event		= bluecard_event,
-	.detach		= bluecard_detach,
+	.probe		= bluecard_attach,
+	.remove		= bluecard_detach,
 	.id_table	= bluecard_ids,
+	.suspend	= bluecard_suspend,
+	.resume		= bluecard_resume,
 };
 
 static int __init init_bluecard_cs(void)
@@ -1110,7 +1062,6 @@
 static void __exit exit_bluecard_cs(void)
 {
 	pcmcia_unregister_driver(&bluecard_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_bluecard_cs);
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 3947963..9446960 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -619,7 +619,6 @@
 }
 
 static struct usb_driver bpa10x_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "bpa10x",
 	.probe		= bpa10x_probe,
 	.disconnect	= bpa10x_disconnect,
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index d2a0add..e522d19 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -90,14 +90,8 @@
 
 static void bt3c_config(dev_link_t *link);
 static void bt3c_release(dev_link_t *link);
-static int bt3c_event(event_t event, int priority, event_callback_args_t *args);
 
-static dev_info_t dev_info = "bt3c_cs";
-
-static dev_link_t *bt3c_attach(void);
-static void bt3c_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
+static void bt3c_detach(struct pcmcia_device *p_dev);
 
 
 /* Transmit states  */
@@ -663,17 +657,15 @@
 	return 0;
 }
 
-static dev_link_t *bt3c_attach(void)
+static int bt3c_attach(struct pcmcia_device *p_dev)
 {
 	bt3c_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 
 	link = &info->link;
 	link->priv = info;
@@ -690,50 +682,24 @@
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		bt3c_detach(link);
-		return NULL;
-	}
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	bt3c_config(link);
 
-	return link;
+	return 0;
 }
 
 
-static void bt3c_detach(dev_link_t *link)
+static void bt3c_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	bt3c_info_t *info = link->priv;
-	dev_link_t **linkp;
-	int ret;
-
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-
-	if (*linkp == NULL)
-		return;
 
 	if (link->state & DEV_CONFIG)
 		bt3c_release(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
-
 	kfree(info);
 }
 
@@ -891,43 +857,29 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-
-static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
+static int bt3c_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	bt3c_info_t *info = link->priv;
+	dev_link_t *link = dev_to_instance(dev);
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			bt3c_close(info);
-			bt3c_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		bt3c_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
 	return 0;
 }
 
+static int bt3c_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
+
+
 static struct pcmcia_device_id bt3c_ids[] = {
 	PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
 	PCMCIA_DEVICE_NULL
@@ -939,10 +891,11 @@
 	.drv		= {
 		.name	= "bt3c_cs",
 	},
-	.attach		= bt3c_attach,
-	.event		= bt3c_event,
-	.detach		= bt3c_detach,
+	.probe		= bt3c_attach,
+	.remove		= bt3c_detach,
 	.id_table	= bt3c_ids,
+	.suspend	= bt3c_suspend,
+	.resume		= bt3c_resume,
 };
 
 static int __init init_bt3c_cs(void)
@@ -954,7 +907,6 @@
 static void __exit exit_bt3c_cs(void)
 {
 	pcmcia_unregister_driver(&bt3c_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_bt3c_cs);
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 529a28a..7b4bff4 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -86,14 +86,8 @@
 
 static void btuart_config(dev_link_t *link);
 static void btuart_release(dev_link_t *link);
-static int btuart_event(event_t event, int priority, event_callback_args_t *args);
 
-static dev_info_t dev_info = "btuart_cs";
-
-static dev_link_t *btuart_attach(void);
-static void btuart_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
+static void btuart_detach(struct pcmcia_device *p_dev);
 
 
 /* Maximum baud rate */
@@ -582,17 +576,15 @@
 	return 0;
 }
 
-static dev_link_t *btuart_attach(void)
+static int btuart_attach(struct pcmcia_device *p_dev)
 {
 	btuart_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 
 	link = &info->link;
 	link->priv = info;
@@ -609,50 +601,24 @@
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		btuart_detach(link);
-		return NULL;
-	}
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	btuart_config(link);
 
-	return link;
+	return 0;
 }
 
 
-static void btuart_detach(dev_link_t *link)
+static void btuart_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	btuart_info_t *info = link->priv;
-	dev_link_t **linkp;
-	int ret;
-
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-
-	if (*linkp == NULL)
-		return;
 
 	if (link->state & DEV_CONFIG)
 		btuart_release(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
-
 	kfree(info);
 }
 
@@ -811,43 +777,29 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-
-static int btuart_event(event_t event, int priority, event_callback_args_t *args)
+static int btuart_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	btuart_info_t *info = link->priv;
+	dev_link_t *link = dev_to_instance(dev);
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			btuart_close(info);
-			btuart_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		btuart_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
 	return 0;
 }
 
+static int btuart_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
+
+
 static struct pcmcia_device_id btuart_ids[] = {
 	/* don't use this driver. Use serial_cs + hci_uart instead */
 	PCMCIA_DEVICE_NULL
@@ -859,10 +811,11 @@
 	.drv		= {
 		.name	= "btuart_cs",
 	},
-	.attach		= btuart_attach,
-	.event		= btuart_event,
-	.detach		= btuart_detach,
+	.probe		= btuart_attach,
+	.remove		= btuart_detach,
 	.id_table	= btuart_ids,
+	.suspend	= btuart_suspend,
+	.resume		= btuart_resume,
 };
 
 static int __init init_btuart_cs(void)
@@ -874,7 +827,6 @@
 static void __exit exit_btuart_cs(void)
 {
 	pcmcia_unregister_driver(&btuart_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_btuart_cs);
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index dec5980..0449bc4 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -89,14 +89,8 @@
 
 static void dtl1_config(dev_link_t *link);
 static void dtl1_release(dev_link_t *link);
-static int dtl1_event(event_t event, int priority, event_callback_args_t *args);
 
-static dev_info_t dev_info = "dtl1_cs";
-
-static dev_link_t *dtl1_attach(void);
-static void dtl1_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
+static void dtl1_detach(struct pcmcia_device *p_dev);
 
 
 /* Transmit states  */
@@ -561,17 +555,15 @@
 	return 0;
 }
 
-static dev_link_t *dtl1_attach(void)
+static int dtl1_attach(struct pcmcia_device *p_dev)
 {
 	dtl1_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	/* Create new info device */
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 
 	link = &info->link;
 	link->priv = info;
@@ -588,50 +580,24 @@
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		dtl1_detach(link);
-		return NULL;
-	}
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	dtl1_config(link);
 
-	return link;
+	return 0;
 }
 
 
-static void dtl1_detach(dev_link_t *link)
+static void dtl1_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dtl1_info_t *info = link->priv;
-	dev_link_t **linkp;
-	int ret;
-
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-
-	if (*linkp == NULL)
-		return;
 
 	if (link->state & DEV_CONFIG)
 		dtl1_release(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
-
 	kfree(info);
 }
 
@@ -763,46 +729,33 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-
-static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
+static int dtl1_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	dtl1_info_t *info = link->priv;
+	dev_link_t *link = dev_to_instance(dev);
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			dtl1_close(info);
-			dtl1_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		dtl1_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
 	return 0;
 }
 
+static int dtl1_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
+
+
 static struct pcmcia_device_id dtl1_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
 	PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
+	PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),
 	PCMCIA_DEVICE_NULL
 };
 MODULE_DEVICE_TABLE(pcmcia, dtl1_ids);
@@ -812,10 +765,11 @@
 	.drv		= {
 		.name	= "dtl1_cs",
 	},
-	.attach		= dtl1_attach,
-	.event		= dtl1_event,
-	.detach		= dtl1_detach,
+	.probe		= dtl1_attach,
+	.remove		= dtl1_detach,
 	.id_table	= dtl1_ids,
+	.suspend	= dtl1_suspend,
+	.resume		= dtl1_resume,
 };
 
 static int __init init_dtl1_cs(void)
@@ -827,7 +781,6 @@
 static void __exit exit_dtl1_cs(void)
 {
 	pcmcia_unregister_driver(&dtl1_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_dtl1_cs);
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 057cb2b..92382e8 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -1044,7 +1044,6 @@
 }
 
 static struct usb_driver hci_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "hci_usb",
 	.probe		= hci_usb_probe,
 	.disconnect	= hci_usb_disconnect,
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
index ac96de1..378e88d 100644
--- a/drivers/cdrom/cdu31a.c
+++ b/drivers/cdrom/cdu31a.c
@@ -1402,7 +1402,7 @@
 			if (!end_that_request_first(req, 1, nblock)) {
 				spin_lock_irq(q->queue_lock);
 				blkdev_dequeue_request(req);
-				end_that_request_last(req);
+				end_that_request_last(req, 1);
 				spin_unlock_irq(q->queue_lock);
 			}
 			continue;
diff --git a/drivers/char/.gitignore b/drivers/char/.gitignore
index 2b6b1d7..73dfdce 100644
--- a/drivers/char/.gitignore
+++ b/drivers/char/.gitignore
@@ -1,3 +1,3 @@
 consolemap_deftbl.c
 defkeymap.c
-
+qtronixmap.c
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 970f70d..dd7e690 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -220,6 +220,14 @@
 	  The module will be called synclinkmp.  If you want to do that, say M
 	  here.
 
+config SYNCLINK_GT
+	tristate "SyncLink GT/AC support"
+	depends on SERIAL_NONSTANDARD
+	help
+	  Support for SyncLink GT and SyncLink AC families of
+	  synchronous and asynchronous serial adapters
+	  manufactured by Microgate Systems, Ltd. (www.microgate.com)
+
 config N_HDLC
 	tristate "HDLC line discipline support"
 	depends on SERIAL_NONSTANDARD
@@ -687,7 +695,7 @@
 
 config RTC
 	tristate "Enhanced Real Time Clock Support"
-	depends on !PPC32 && !PARISC && !IA64 && !M68K
+	depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV
 	---help---
 	  If you say Y here and create a character special file /dev/rtc with
 	  major number 10 and minor number 135 using mknod ("man mknod"), you
@@ -735,7 +743,7 @@
 
 config GEN_RTC
 	tristate "Generic /dev/rtc emulation"
-	depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC32 && !SPARC64
+	depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV
 	---help---
 	  If you say Y here and create a character special file /dev/rtc with
 	  major number 10 and minor number 135 using mknod ("man mknod"), you
@@ -943,6 +951,15 @@
           Applications should simply open the device (eg /dev/hda1)
           with the O_DIRECT flag.
 
+config MAX_RAW_DEVS
+	int "Maximum number of RAW devices to support (1-8192)"
+	depends on RAW_DRIVER
+	default "256"
+	help
+	  The maximum number of RAW devices that are supported.
+	  Default is 256. Increase this number in case you need lots of
+	  raw devices.
+
 config HPET
 	bool "HPET - High Precision Event Timer" if (X86 || IA64)
 	default n
@@ -974,18 +991,9 @@
 	  exposed to the user.  If this applies to your hardware,
 	  say N here.
 
-config MAX_RAW_DEVS
-	int "Maximum number of RAW devices to support (1-8192)"
-	depends on RAW_DRIVER
-	default "256"
-	help
-	  The maximum number of RAW devices that are supported.
-	  Default is 256. Increase this number in case you need lots of
-	  raw devices.
-
 config HANGCHECK_TIMER
 	tristate "Hangcheck timer"
-	depends on X86 || IA64 || PPC64 || ARCH_S390
+	depends on X86 || IA64 || PPC64 || S390
 	help
 	  The hangcheck-timer module detects when the system has gone
 	  out to lunch past a certain margin.  It can reboot the system
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 4aeae68..d973d14 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -36,6 +36,7 @@
 obj-$(CONFIG_ISI)		+= isicom.o
 obj-$(CONFIG_SYNCLINK)		+= synclink.o
 obj-$(CONFIG_SYNCLINKMP)	+= synclinkmp.o
+obj-$(CONFIG_SYNCLINK_GT)	+= synclink_gt.o
 obj-$(CONFIG_N_HDLC)		+= n_hdlc.o
 obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
 obj-$(CONFIG_SX)		+= sx.o generic_serial.o
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 3f8f7fa..268f78d 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/jiffies.h>
 #include <linux/agp_backend.h>
 #include "agp.h"
 
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index bdd168d..bd958d6 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -432,7 +432,10 @@
 
 	if (ctx.handle != DRM_KERNEL_CONTEXT) {
 		if (dev->driver->context_ctor)
-			dev->driver->context_ctor(dev, ctx.handle);
+			if (!dev->driver->context_ctor(dev, ctx.handle)) {
+				DRM_DEBUG( "Running out of ctxs or memory.\n");
+				return -ENOMEM;
+			}
 	}
 
 	ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST);
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 03839ea..342302d 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -1311,7 +1311,7 @@
 
 static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
 {
-	drm_radeon_private_t *dev_priv = dev->dev_private;;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
 	DRM_DEBUG("\n");
 
 	dev_priv->is_pci = init->is_pci;
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 7bda7e3..d92ccee 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -379,6 +379,7 @@
 #	define RADEON_PLL_WR_EN			(1 << 7)
 #define RADEON_CLOCK_CNTL_INDEX		0x0008
 #define RADEON_CONFIG_APER_SIZE		0x0108
+#define RADEON_CONFIG_MEMSIZE		0x00f8
 #define RADEON_CRTC_OFFSET		0x0224
 #define RADEON_CRTC_OFFSET_CNTL		0x0228
 #	define RADEON_CRTC_TILE_EN		(1 << 15)
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index 66e53dd..40a67c8 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -120,7 +120,7 @@
 #if defined(CONFIG_X86)
 # define HAVE_MONOTONIC
 # define TIMER_FREQ 1000000000ULL
-#elif defined(CONFIG_ARCH_S390)
+#elif defined(CONFIG_S390)
 /* FA240000 is 1 Second in the IBM time universe (Page 4-38 Principles of Op for zSeries */
 # define TIMER_FREQ 0xFA240000ULL
 #elif defined(CONFIG_IA64)
diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c
index 6f673d2..b3bc2e3 100644
--- a/drivers/char/hw_random.c
+++ b/drivers/char/hw_random.c
@@ -1,4 +1,9 @@
 /*
+        Added support for the AMD Geode LX RNG
+	(c) Copyright 2004-2005 Advanced Micro Devices, Inc.
+
+	derived from
+
  	Hardware driver for the Intel/AMD/VIA Random Number Generators (RNG)
 	(c) Copyright 2003 Red Hat Inc <jgarzik@redhat.com>
  
@@ -95,6 +100,11 @@
 static u32 via_data_read (void);
 #endif
 
+static int __init geode_init(struct pci_dev *dev);
+static void geode_cleanup(void);
+static unsigned int geode_data_present (void);
+static u32 geode_data_read (void);
+
 struct rng_operations {
 	int (*init) (struct pci_dev *dev);
 	void (*cleanup) (void);
@@ -122,6 +132,7 @@
 	rng_hw_intel,
 	rng_hw_amd,
 	rng_hw_via,
+	rng_hw_geode,
 };
 
 static struct rng_operations rng_vendor_ops[] = {
@@ -139,6 +150,9 @@
 	/* rng_hw_via */
 	{ via_init, via_cleanup, via_data_present, via_data_read, 1 },
 #endif
+
+	/* rng_hw_geode */
+	{ geode_init, geode_cleanup, geode_data_present, geode_data_read, 4 }
 };
 
 /*
@@ -155,10 +169,14 @@
 
 	{ 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
 	{ 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
+	{ 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
 	{ 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
 	{ 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
 	{ 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel },
 
+	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_geode },
+
 	{ 0, },	/* terminate list */
 };
 MODULE_DEVICE_TABLE (pci, rng_pci_tbl);
@@ -460,6 +478,57 @@
 }
 #endif
 
+/***********************************************************************
+ *
+ * AMD Geode RNG operations
+ *
+ */
+
+static void __iomem *geode_rng_base = NULL;
+
+#define GEODE_RNG_DATA_REG   0x50
+#define GEODE_RNG_STATUS_REG 0x54
+
+static u32 geode_data_read(void)
+{
+	u32 val;
+
+	assert(geode_rng_base != NULL);
+	val = readl(geode_rng_base + GEODE_RNG_DATA_REG);
+	return val;
+}
+
+static unsigned int geode_data_present(void)
+{
+	u32 val;
+
+	assert(geode_rng_base != NULL);
+	val = readl(geode_rng_base + GEODE_RNG_STATUS_REG);
+	return val;
+}
+
+static void geode_cleanup(void)
+{
+	iounmap(geode_rng_base);
+  	geode_rng_base = NULL;
+}
+
+static int geode_init(struct pci_dev *dev)
+{
+	unsigned long rng_base = pci_resource_start(dev, 0);
+
+	if (rng_base == 0)
+		return 1;
+
+	geode_rng_base = ioremap(rng_base, 0x58);
+
+	if (geode_rng_base == NULL) {
+		printk(KERN_ERR PFX "Cannot ioremap RNG memory\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
 
 /***********************************************************************
  *
@@ -574,7 +643,7 @@
 
 	DPRINTK ("ENTER\n");
 
-	/* Probe for Intel, AMD RNGs */
+	/* Probe for Intel, AMD, Geode RNGs */
 	for_each_pci_dev(pdev) {
 		ent = pci_match_id(rng_pci_tbl, pdev);
 		if (ent) {
diff --git a/drivers/char/ip2/i2pack.h b/drivers/char/ip2/i2pack.h
index e9b87a7..00342a6 100644
--- a/drivers/char/ip2/i2pack.h
+++ b/drivers/char/ip2/i2pack.h
@@ -358,7 +358,7 @@
 #define MB_OUT_STRIPPED    0x40  // Board has read all output from fifo 
 #define MB_FATAL_ERROR     0x20  // Board has encountered a fatal error
 
-#pragma pack(4)                  // Reset padding to command-line default
+#pragma pack()                  // Reset padding to command-line default
 
 #endif      // I2PACK_H
 
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 6b302a9..561430e 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -787,7 +787,6 @@
 	int              i;
 	unsigned long    flags;
 	struct cmd_rcvr  *rcvr;
-	struct list_head *entry1, *entry2;
 	struct cmd_rcvr  *rcvrs = NULL;
 
 	user->valid = 1;
@@ -812,8 +811,7 @@
 	 * synchronize_rcu()) then free everything in that list.
 	 */
 	down(&intf->cmd_rcvrs_lock);
-	list_for_each_safe_rcu(entry1, entry2, &intf->cmd_rcvrs) {
-		rcvr = list_entry(entry1, struct cmd_rcvr, link);
+	list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
 		if (rcvr->user == user) {
 			list_del_rcu(&rcvr->link);
 			rcvr->next = rcvrs;
@@ -2986,7 +2984,7 @@
 	msg.cmd = 2; /* Platform event command. */
 	msg.data = data;
 	msg.data_len = 8;
-	data[0] = 0x21; /* Kernel generator ID, IPMI table 5-4 */
+	data[0] = 0x41; /* Kernel generator ID, IPMI table 5-4 */
 	data[1] = 0x03; /* This is for IPMI 1.0. */
 	data[2] = 0x20; /* OS Critical Stop, IPMI table 36-3 */
 	data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 01a1f6b..beea450 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2399,7 +2399,8 @@
 			new_smi->handlers->cleanup(new_smi->si_sm);
 		kfree(new_smi->si_sm);
 	}
-	new_smi->io_cleanup(new_smi);
+	if (new_smi->io_cleanup)
+		new_smi->io_cleanup(new_smi);
 
 	return rv;
 }
@@ -2518,7 +2519,8 @@
 
 	kfree(to_clean->si_sm);
 
-	to_clean->io_cleanup(to_clean);
+	if (to_clean->io_cleanup)
+		to_clean->io_cleanup(to_clean);
 }
 
 static __exit void cleanup_ipmi_si(void)
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 449d029..8b603b2 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -930,8 +930,8 @@
 }
 
 #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
-    defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) ||\
-    defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
+    defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
+    defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
     (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
 
 #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
@@ -958,7 +958,7 @@
 extern int mac_hid_mouse_emulate_buttons(int, int, int);
 #endif /* CONFIG_MAC_EMUMOUSEBTN */
 
-#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
+#ifdef CONFIG_SPARC
 static int sparc_l1_a_state = 0;
 extern void sun_do_break(void);
 #endif
@@ -1045,7 +1045,7 @@
 
 	if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
 		sysrq_alt = down;
-#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
+#ifdef CONFIG_SPARC
 	if (keycode == KEY_STOP)
 		sparc_l1_a_state = down;
 #endif
@@ -1072,7 +1072,7 @@
 		return;
 	}
 #endif
-#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
+#ifdef CONFIG_SPARC
 	if (keycode == KEY_A && sparc_l1_a_state) {
 		sparc_l1_a_state = 0;
 		sun_do_break();
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 29c3b63..5b2d180 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -101,6 +101,11 @@
 
 	return 1;
 }
+
+static inline int valid_mmap_phys_addr_range(unsigned long addr, size_t *size)
+{
+	return 1;
+}
 #endif
 
 /*
@@ -228,26 +233,36 @@
 	return written;
 }
 
+#ifndef __HAVE_PHYS_MEM_ACCESS_PROT
+static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+				     unsigned long size, pgprot_t vma_prot)
+{
+#ifdef pgprot_noncached
+	unsigned long offset = pfn << PAGE_SHIFT;
+
+	if (uncached_access(file, offset))
+		return pgprot_noncached(vma_prot);
+#endif
+	return vma_prot;
+}
+#endif
+
 static int mmap_mem(struct file * file, struct vm_area_struct * vma)
 {
-#if defined(__HAVE_PHYS_MEM_ACCESS_PROT)
-	vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
-						 vma->vm_end - vma->vm_start,
-						 vma->vm_page_prot);
-#elif defined(pgprot_noncached)
-	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-	int uncached;
+	size_t size = vma->vm_end - vma->vm_start;
 
-	uncached = uncached_access(file, offset);
-	if (uncached)
-		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-#endif
+	if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, &size))
+		return -EINVAL;
+
+	vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
+						 size,
+						 vma->vm_page_prot);
 
 	/* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
 	if (remap_pfn_range(vma,
 			    vma->vm_start,
 			    vma->vm_pgoff,
-			    vma->vm_end-vma->vm_start,
+			    size,
 			    vma->vm_page_prot))
 		return -EAGAIN;
 	return 0;
@@ -591,7 +606,7 @@
 
 		if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
 			goto out_up;
-		if (vma->vm_flags & (VM_SHARED | VM_HUGETLB | VM_UNPAGED))
+		if (vma->vm_flags & (VM_SHARED | VM_HUGETLB))
 			break;
 		count = vma->vm_end - addr;
 		if (count > size)
@@ -817,7 +832,7 @@
 			  size_t count, loff_t *ppos)
 {
 	char *tmp;
-	int ret;
+	ssize_t ret;
 
 	tmp = kmalloc(count + 1, GFP_KERNEL);
 	if (tmp == NULL)
@@ -826,6 +841,9 @@
 	if (!copy_from_user(tmp, buf, count)) {
 		tmp[count] = 0;
 		ret = printk("%s", tmp);
+		if (ret > count)
+			/* printk can add a prefix */
+			ret = count;
 	}
 	kfree(tmp);
 	return ret;
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
index 78c89a3..c923781 100644
--- a/drivers/char/mmtimer.c
+++ b/drivers/char/mmtimer.c
@@ -1,11 +1,11 @@
 /*
- * Intel Multimedia Timer device implementation for SGI SN platforms.
+ * Timer device implementation for SGI SN platforms.
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2004 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2006 Silicon Graphics, Inc.  All rights reserved.
  *
  * This driver exports an API that should be supportable by any HPET or IA-PC
  * multimedia timer.  The code below is currently specific to the SGI Altix
@@ -45,7 +45,7 @@
 /* name of the device, usually in /dev */
 #define MMTIMER_NAME "mmtimer"
 #define MMTIMER_DESC "SGI Altix RTC Timer"
-#define MMTIMER_VERSION "2.0"
+#define MMTIMER_VERSION "2.1"
 
 #define RTC_BITS 55 /* 55 bits for this implementation */
 
@@ -227,10 +227,7 @@
 	struct tasklet_struct tasklet;
 } mmtimer_t;
 
-/*
- * Total number of comparators is comparators/node * MAX nodes/running kernel
- */
-static mmtimer_t timers[NUM_COMPARATORS*MAX_COMPACT_NODES];
+static mmtimer_t ** timers;
 
 /**
  * mmtimer_ioctl - ioctl interface for /dev/mmtimer
@@ -441,29 +438,29 @@
 mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int i;
-	mmtimer_t *base = timers + cpu_to_node(smp_processor_id()) *
-						NUM_COMPARATORS;
 	unsigned long expires = 0;
 	int result = IRQ_NONE;
+	unsigned indx = cpu_to_node(smp_processor_id());
 
 	/*
 	 * Do this once for each comparison register
 	 */
 	for (i = 0; i < NUM_COMPARATORS; i++) {
+		mmtimer_t *base = timers[indx] + i;
 		/* Make sure this doesn't get reused before tasklet_sched */
-		spin_lock(&base[i].lock);
-		if (base[i].cpu == smp_processor_id()) {
-			if (base[i].timer)
-				expires = base[i].timer->it.mmtimer.expires;
+		spin_lock(&base->lock);
+		if (base->cpu == smp_processor_id()) {
+			if (base->timer)
+				expires = base->timer->it.mmtimer.expires;
 			/* expires test won't work with shared irqs */
 			if ((mmtimer_int_pending(i) > 0) ||
 				(expires && (expires < rtc_time()))) {
 				mmtimer_clr_int_pending(i);
-				tasklet_schedule(&base[i].tasklet);
+				tasklet_schedule(&base->tasklet);
 				result = IRQ_HANDLED;
 			}
 		}
-		spin_unlock(&base[i].lock);
+		spin_unlock(&base->lock);
 		expires = 0;
 	}
 	return result;
@@ -523,7 +520,7 @@
 {
 	int i = timr->it.mmtimer.clock;
 	cnodeid_t nodeid = timr->it.mmtimer.node;
-	mmtimer_t *t = timers + nodeid * NUM_COMPARATORS +i;
+	mmtimer_t *t = timers[nodeid] + i;
 	unsigned long irqflags;
 
 	if (i != TIMER_OFF) {
@@ -609,11 +606,11 @@
 	preempt_disable();
 
 	nodeid =  cpu_to_node(smp_processor_id());
-	base = timers + nodeid * NUM_COMPARATORS;
 retry:
 	/* Don't use an allocated timer, or a deleted one that's pending */
 	for(i = 0; i< NUM_COMPARATORS; i++) {
-		if (!base[i].timer && !base[i].tasklet.state) {
+		base = timers[nodeid] + i;
+		if (!base->timer && !base->tasklet.state) {
 			break;
 		}
 	}
@@ -623,14 +620,14 @@
 		return -EBUSY;
 	}
 
-	spin_lock_irqsave(&base[i].lock, irqflags);
+	spin_lock_irqsave(&base->lock, irqflags);
 
-	if (base[i].timer || base[i].tasklet.state != 0) {
-		spin_unlock_irqrestore(&base[i].lock, irqflags);
+	if (base->timer || base->tasklet.state != 0) {
+		spin_unlock_irqrestore(&base->lock, irqflags);
 		goto retry;
 	}
-	base[i].timer = timr;
-	base[i].cpu = smp_processor_id();
+	base->timer = timr;
+	base->cpu = smp_processor_id();
 
 	timr->it.mmtimer.clock = i;
 	timr->it.mmtimer.node = nodeid;
@@ -645,11 +642,11 @@
 		}
 	} else {
 		timr->it.mmtimer.expires -= period;
-		if (reschedule_periodic_timer(base+i))
+		if (reschedule_periodic_timer(base))
 			err = -EINVAL;
 	}
 
-	spin_unlock_irqrestore(&base[i].lock, irqflags);
+	spin_unlock_irqrestore(&base->lock, irqflags);
 
 	preempt_enable();
 
@@ -675,6 +672,7 @@
 static int __init mmtimer_init(void)
 {
 	unsigned i;
+	cnodeid_t node, maxn = -1;
 
 	if (!ia64_platform_is("sn2"))
 		return -1;
@@ -691,14 +689,6 @@
 	mmtimer_femtoperiod = ((unsigned long)1E15 + sn_rtc_cycles_per_second /
 			       2) / sn_rtc_cycles_per_second;
 
-	for (i=0; i< NUM_COMPARATORS*MAX_COMPACT_NODES; i++) {
-		spin_lock_init(&timers[i].lock);
-		timers[i].timer = NULL;
-		timers[i].cpu = 0;
-		timers[i].i = i % NUM_COMPARATORS;
-		tasklet_init(&timers[i].tasklet, mmtimer_tasklet, (unsigned long) (timers+i));
-	}
-
 	if (request_irq(SGI_MMTIMER_VECTOR, mmtimer_interrupt, SA_PERCPU_IRQ, MMTIMER_NAME, NULL)) {
 		printk(KERN_WARNING "%s: unable to allocate interrupt.",
 			MMTIMER_NAME);
@@ -712,6 +702,40 @@
 		return -1;
 	}
 
+	/* Get max numbered node, calculate slots needed */
+	for_each_online_node(node) {
+		maxn = node;
+	}
+	maxn++;
+
+	/* Allocate list of node ptrs to mmtimer_t's */
+	timers = kmalloc(sizeof(mmtimer_t *)*maxn, GFP_KERNEL);
+	if (timers == NULL) {
+		printk(KERN_ERR "%s: failed to allocate memory for device\n",
+				MMTIMER_NAME);
+		return -1;
+	}
+
+	/* Allocate mmtimer_t's for each online node */
+	for_each_online_node(node) {
+		timers[node] = kmalloc_node(sizeof(mmtimer_t)*NUM_COMPARATORS, GFP_KERNEL, node);
+		if (timers[node] == NULL) {
+			printk(KERN_ERR "%s: failed to allocate memory for device\n",
+				MMTIMER_NAME);
+			return -1;
+		}
+		for (i=0; i< NUM_COMPARATORS; i++) {
+			mmtimer_t * base = timers[node] + i;
+
+			spin_lock_init(&base->lock);
+			base->timer = NULL;
+			base->cpu = 0;
+			base->i = i;
+			tasklet_init(&base->tasklet, mmtimer_tasklet,
+				(unsigned long) (base));
+		}
+	}
+
 	sgi_clock_period = sgi_clock.res = NSEC_PER_SEC / sn_rtc_cycles_per_second;
 	register_posix_clock(CLOCK_SGI_CYCLE, &sgi_clock);
 
diff --git a/drivers/char/mwave/mwavepub.h b/drivers/char/mwave/mwavepub.h
index f1f9da7..60c961ae 100644
--- a/drivers/char/mwave/mwavepub.h
+++ b/drivers/char/mwave/mwavepub.h
@@ -69,7 +69,7 @@
 typedef struct _MW_READWRITE {
 	unsigned short usDspAddress;	/* The dsp address */
 	unsigned long ulDataLength;	/* The size in bytes of the data or user buffer */
-	void *pBuf;		/* Input:variable sized buffer */
+	void __user *pBuf;		/* Input:variable sized buffer */
 } MW_READWRITE, *pMW_READWRITE;
 
 #define IOCTL_MW_RESET           _IO(MWAVE_MINOR,1)
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index c3660d8..a133a62 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -562,7 +562,7 @@
 }	/* end of n_hdlc_tty_receive() */
 
 /**
- * n_hdlc_tty_read - Called to retreive one frame of data (if available)
+ * n_hdlc_tty_read - Called to retrieve one frame of data (if available)
  * @tty - pointer to tty instance data
  * @file - pointer to open file object
  * @buf - pointer to returned data buffer
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index ef011ef..649677b 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -66,7 +66,6 @@
 #define	T_100MSEC	msecs_to_jiffies(100)
 #define	T_500MSEC	msecs_to_jiffies(500)
 
-static void cm4000_detach(dev_link_t *link);
 static void cm4000_release(dev_link_t *link);
 
 static int major;		/* major number we get from the kernel */
@@ -156,7 +155,6 @@
 		/*sbuf*/ 512*sizeof(char) - 			\
 		/*queue*/ 4*sizeof(wait_queue_head_t))
 
-static dev_info_t dev_info = MODULE_NAME;
 static dev_link_t *dev_table[CM4000_MAX_DEV];
 
 /* This table doesn't use spaces after the comma between fields and thus
@@ -1444,6 +1442,7 @@
 	dev_link_t *link;
 	int size;
 	int rc;
+	void __user *argp = (void __user *)arg;
 #ifdef PCMCIA_DEBUG
 	char *ioctl_names[CM_IOC_MAXNR + 1] = {
 		[_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
@@ -1481,11 +1480,11 @@
 	      _IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd);
 
 	if (_IOC_DIR(cmd) & _IOC_READ) {
-		if (!access_ok(VERIFY_WRITE, (void *)arg, size))
+		if (!access_ok(VERIFY_WRITE, argp, size))
 			return -EFAULT;
 	}
 	if (_IOC_DIR(cmd) & _IOC_WRITE) {
-		if (!access_ok(VERIFY_READ, (void *)arg, size))
+		if (!access_ok(VERIFY_READ, argp, size))
 			return -EFAULT;
 	}
 
@@ -1506,14 +1505,14 @@
 				status |= CM_NO_READER;
 			if (test_bit(IS_BAD_CARD, &dev->flags))
 				status |= CM_BAD_CARD;
-			if (copy_to_user((int *)arg, &status, sizeof(int)))
+			if (copy_to_user(argp, &status, sizeof(int)))
 				return -EFAULT;
 		}
 		return 0;
 	case CM_IOCGATR:
 		DEBUGP(4, dev, "... in CM_IOCGATR\n");
 		{
-			struct atreq *atreq = (struct atreq *) arg;
+			struct atreq __user *atreq = argp;
 			int tmp;
 			/* allow nonblocking io and being interrupted */
 			if (wait_event_interruptible
@@ -1597,7 +1596,7 @@
 		{
 			struct ptsreq krnptsreq;
 
-			if (copy_from_user(&krnptsreq, (struct ptsreq *) arg,
+			if (copy_from_user(&krnptsreq, argp,
 					   sizeof(struct ptsreq)))
 				return -EFAULT;
 
@@ -1641,7 +1640,7 @@
 			int old_pc_debug = 0;
 
 			old_pc_debug = pc_debug;
-			if (copy_from_user(&pc_debug, (int *)arg, sizeof(int)))
+			if (copy_from_user(&pc_debug, argp, sizeof(int)))
 				return -EFAULT;
 
 			if (old_pc_debug != pc_debug)
@@ -1863,68 +1862,36 @@
 	link->state &= ~DEV_CONFIG_PENDING;
 }
 
-static int cm4000_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int cm4000_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct cm4000_dev *dev;
-	int devno;
 
-	link = args->client_data;
 	dev = link->priv;
 
-	DEBUGP(3, dev, "-> cm4000_event\n");
-	for (devno = 0; devno < CM4000_MAX_DEV; devno++)
-		if (dev_table[devno] == link)
-			break;
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+	stop_monitor(dev);
 
-	if (devno == CM4000_MAX_DEV)
-		return CS_BAD_ADAPTER;
+	return 0;
+}
 
-	switch (event) {
-	case CS_EVENT_CARD_INSERTION:
-		DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		cm4000_config(link, devno);
-		break;
-	case CS_EVENT_CARD_REMOVAL:
-		DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
-		link->state &= ~DEV_PRESENT;
-		stop_monitor(dev);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
-		      "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
-		link->state |= DEV_SUSPEND;
-		/* fall-through */
-	case CS_EVENT_RESET_PHYSICAL:
-		DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
-		if (link->state & DEV_CONFIG) {
-			DEBUGP(5, dev, "ReleaseConfiguration\n");
-			pcmcia_release_configuration(link->handle);
-		}
-		stop_monitor(dev);
-		break;
-	case CS_EVENT_PM_RESUME:
-		DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
-		      "(fall-through to CS_EVENT_CARD_RESET)\n");
-		link->state &= ~DEV_SUSPEND;
-		/* fall-through */
-	case CS_EVENT_CARD_RESET:
-		DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
-		if ((link->state & DEV_CONFIG)) {
-			DEBUGP(5, dev, "RequestConfiguration\n");
-			pcmcia_request_configuration(link->handle, &link->conf);
-		}
-		if (link->open)
-			start_monitor(dev);
-		break;
-	default:
-		DEBUGP(5, dev, "unknown event %.2x\n", event);
-		break;
-	}
-	DEBUGP(3, dev, "<- cm4000_event\n");
-	return CS_SUCCESS;
+static int cm4000_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct cm4000_dev *dev;
+
+	dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	if (link->open)
+		start_monitor(dev);
+
+	return 0;
 }
 
 static void cm4000_release(dev_link_t *link)
@@ -1934,11 +1901,10 @@
 	pcmcia_release_io(link->handle, &link->io);
 }
 
-static dev_link_t *cm4000_attach(void)
+static int cm4000_attach(struct pcmcia_device *p_dev)
 {
 	struct cm4000_dev *dev;
 	dev_link_t *link;
-	client_reg_t client_reg;
 	int i;
 
 	for (i = 0; i < CM4000_MAX_DEV; i++)
@@ -1947,76 +1913,55 @@
 
 	if (i == CM4000_MAX_DEV) {
 		printk(KERN_NOTICE MODULE_NAME ": all devices in use\n");
-		return NULL;
+		return -ENODEV;
 	}
 
 	/* create a new cm4000_cs device */
 	dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL);
 	if (dev == NULL)
-		return NULL;
+		return -ENOMEM;
 
 	link = &dev->link;
 	link->priv = dev;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	dev_table[i] = link;
 
-	/* register with card services */
-	client_reg.dev_info = &dev_info;
-	client_reg.EventMask =
-	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-	    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-
-	i = pcmcia_register_client(&link->handle, &client_reg);
-	if (i) {
-		cs_error(link->handle, RegisterClient, i);
-		cm4000_detach(link);
-		return NULL;
-	}
-
 	init_waitqueue_head(&dev->devq);
 	init_waitqueue_head(&dev->ioq);
 	init_waitqueue_head(&dev->atrq);
 	init_waitqueue_head(&dev->readq);
 
-	return link;
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	cm4000_config(link, i);
+
+	return 0;
 }
 
-static void cm4000_detach_by_devno(int devno, dev_link_t * link)
+static void cm4000_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct cm4000_dev *dev = link->priv;
-
-	DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno);
-
-	if (link->state & DEV_CONFIG) {
-		DEBUGP(5, dev, "device still configured (try to release it)\n");
-		cm4000_release(link);
-	}
-
-	if (link->handle) {
-		pcmcia_deregister_client(link->handle);
-	}
-
-	dev_table[devno] = NULL;
-	kfree(dev);
-	return;
-}
-
-static void cm4000_detach(dev_link_t * link)
-{
-	int i;
+	int devno;
 
 	/* find device */
-	for (i = 0; i < CM4000_MAX_DEV; i++)
-		if (dev_table[i] == link)
+	for (devno = 0; devno < CM4000_MAX_DEV; devno++)
+		if (dev_table[devno] == link)
 			break;
-
-	if (i == CM4000_MAX_DEV)
+	if (devno == CM4000_MAX_DEV)
 		return;
 
-	cm4000_detach_by_devno(i, link);
+	link->state &= ~DEV_PRESENT;
+	stop_monitor(dev);
+
+	if (link->state & DEV_CONFIG)
+ 		cm4000_release(link);
+
+	dev_table[devno] = NULL;
+ 	kfree(dev);
+
 	return;
 }
 
@@ -2041,9 +1986,10 @@
 	.drv	  = {
 		.name = "cm4000_cs",
 		},
-	.attach   = cm4000_attach,
-	.detach   = cm4000_detach,
-	.event	  = cm4000_event,
+	.probe    = cm4000_attach,
+	.remove   = cm4000_detach,
+	.suspend  = cm4000_suspend,
+	.resume   = cm4000_resume,
 	.id_table = cm4000_ids,
 };
 
@@ -2063,13 +2009,8 @@
 
 static void __exit cmm_exit(void)
 {
-	int i;
-
 	printk(KERN_INFO MODULE_NAME ": unloading\n");
 	pcmcia_unregister_driver(&cm4000_driver);
-	for (i = 0; i < CM4000_MAX_DEV; i++)
-		if (dev_table[i])
-			cm4000_detach_by_devno(i, dev_table[i]);
 	unregister_chrdev(major, DEVICE_NAME);
 };
 
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 4c698d9..46eb371 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -65,7 +65,6 @@
 #define POLL_PERIOD 				msecs_to_jiffies(10)
 
 static void reader_release(dev_link_t *link);
-static void reader_detach(dev_link_t *link);
 
 static int major;
 
@@ -86,7 +85,6 @@
 	struct timer_list 	poll_timer;
 };
 
-static dev_info_t dev_info = MODULE_NAME;
 static dev_link_t *dev_table[CM_MAX_DEV];
 
 #ifndef PCMCIA_DEBUG
@@ -629,65 +627,26 @@
 	link->state &= ~DEV_CONFIG_PENDING;
 }
 
-static int reader_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int reader_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link;
-	struct reader_dev *dev;
-	int devno;
+	dev_link_t *link = dev_to_instance(p_dev);
 
-	link = args->client_data;
-	dev = link->priv;
-	DEBUGP(3, dev, "-> reader_event\n");
-	for (devno = 0; devno < CM_MAX_DEV; devno++) {
-		if (dev_table[devno] == link)
-			break;
-	}
-	if (devno == CM_MAX_DEV)
-		return CS_BAD_ADAPTER;
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-	switch (event) {
-		case CS_EVENT_CARD_INSERTION:
-			DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n");
-			link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-			reader_config(link, devno);
-			break;
-		case CS_EVENT_CARD_REMOVAL:
-			DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
-			link->state &= ~DEV_PRESENT;
-			break;
-		case CS_EVENT_PM_SUSPEND:
-			DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
-			      "(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
-			link->state |= DEV_SUSPEND;
+	return 0;
+}
 
-		case CS_EVENT_RESET_PHYSICAL:
-			DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
-			if (link->state & DEV_CONFIG) {
-		  		DEBUGP(5, dev, "ReleaseConfiguration\n");
-		  		pcmcia_release_configuration(link->handle);
-			}
-			break;
-		case CS_EVENT_PM_RESUME:
-			DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
-			      "(fall-through to CS_EVENT_CARD_RESET)\n");
-			link->state &= ~DEV_SUSPEND;
+static int reader_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
 
-		case CS_EVENT_CARD_RESET:
-			DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
-			if ((link->state & DEV_CONFIG)) {
-				DEBUGP(5, dev, "RequestConfiguration\n");
-		  		pcmcia_request_configuration(link->handle,
-							     &link->conf);
-			}
-			break;
-		default:
-			DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
-			       event);
-			break;
-	}
-	DEBUGP(3, dev, "<- reader_event\n");
-	return CS_SUCCESS;
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
 }
 
 static void reader_release(dev_link_t *link)
@@ -697,11 +656,10 @@
 	pcmcia_release_io(link->handle, &link->io);
 }
 
-static dev_link_t *reader_attach(void)
+static int reader_attach(struct pcmcia_device *p_dev)
 {
 	struct reader_dev *dev;
 	dev_link_t *link;
-	client_reg_t client_reg;
 	int i;
 
 	for (i = 0; i < CM_MAX_DEV; i++) {
@@ -710,11 +668,11 @@
 	}
 
 	if (i == CM_MAX_DEV)
-		return NULL;
+		return -ENODEV;
 
 	dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL);
 	if (dev == NULL)
-		return NULL;
+		return -ENOMEM;
 
 	dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
 	dev->buffer_status = 0;
@@ -725,20 +683,6 @@
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	dev_table[i] = link;
 
-	client_reg.dev_info = &dev_info;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-	client_reg.EventMask=
-		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-		CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	i = pcmcia_register_client(&link->handle, &client_reg);
-	if (i) {
-		cs_error(link->handle, RegisterClient, i);
-		reader_detach(link);
-		return NULL;
-	}
 	init_waitqueue_head(&dev->devq);
 	init_waitqueue_head(&dev->poll_wait);
 	init_waitqueue_head(&dev->read_wait);
@@ -746,39 +690,37 @@
 	init_timer(&dev->poll_timer);
 	dev->poll_timer.function = &cm4040_do_poll;
 
-	return link;
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	reader_config(link, i);
+
+	return 0;
 }
 
-static void reader_detach_by_devno(int devno, dev_link_t *link)
+static void reader_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct reader_dev *dev = link->priv;
-
-	if (link->state & DEV_CONFIG) {
-		DEBUGP(5, dev, "device still configured (try to release it)\n");
-		reader_release(link);
-	}
-
-	pcmcia_deregister_client(link->handle);
-	dev_table[devno] = NULL;
-	DEBUGP(5, dev, "freeing dev=%p\n", dev);
-	cm4040_stop_poll(dev);
-	kfree(dev);
-	return;
-}
-
-static void reader_detach(dev_link_t *link)
-{
-	int i;
+	int devno;
 
 	/* find device */
-	for (i = 0; i < CM_MAX_DEV; i++) {
-		if (dev_table[i] == link)
+	for (devno = 0; devno < CM_MAX_DEV; devno++) {
+		if (dev_table[devno] == link)
 			break;
 	}
-	if (i == CM_MAX_DEV)
+	if (devno == CM_MAX_DEV)
 		return;
 
-	reader_detach_by_devno(i, link);
+	link->state &= ~DEV_PRESENT;
+
+	if (link->state & DEV_CONFIG)
+		reader_release(link);
+
+	dev_table[devno] = NULL;
+	kfree(dev);
+
 	return;
 }
 
@@ -804,9 +746,10 @@
   	.drv		= {
 		.name	= "cm4040_cs",
 	},
-	.attach		= reader_attach,
-	.detach		= reader_detach,
-	.event		= reader_event,
+	.probe		= reader_attach,
+	.remove		= reader_detach,
+	.suspend	= reader_suspend,
+	.resume		= reader_resume,
 	.id_table	= cm4040_ids,
 };
 
@@ -825,14 +768,8 @@
 
 static void __exit cm4040_exit(void)
 {
-	int i;
-
 	printk(KERN_INFO MODULE_NAME ": unloading\n");
 	pcmcia_unregister_driver(&reader_driver);
-	for (i = 0; i < CM_MAX_DEV; i++) {
-		if (dev_table[i])
-			reader_detach_by_devno(i, dev_table[i]);
-	}
 	unregister_chrdev(major, DEVICE_NAME);
 }
 
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 2c326ea..cf45b10 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -486,13 +486,7 @@
 
 static void mgslpc_config(dev_link_t *link);
 static void mgslpc_release(u_long arg);
-static int  mgslpc_event(event_t event, int priority,
-			 event_callback_args_t *args);
-static dev_link_t *mgslpc_attach(void);
-static void mgslpc_detach(dev_link_t *);
-
-static dev_info_t dev_info = "synclink_cs";
-static dev_link_t *dev_list = NULL;
+static void mgslpc_detach(struct pcmcia_device *p_dev);
 
 /*
  * 1st function defined in .text section. Calling this function in
@@ -539,12 +533,10 @@
 	}
 }
 
-static dev_link_t *mgslpc_attach(void)
+static int mgslpc_attach(struct pcmcia_device *p_dev)
 {
     MGSLPC_INFO *info;
     dev_link_t *link;
-    client_reg_t client_reg;
-    int ret;
     
     if (debug_level >= DEBUG_LEVEL_INFO)
 	    printk("mgslpc_attach\n");
@@ -552,7 +544,7 @@
     info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
     if (!info) {
 	    printk("Error can't allocate device instance data\n");
-	    return NULL;
+	    return -ENOMEM;
     }
 
     memset(info, 0, sizeof(MGSLPC_INFO));
@@ -587,24 +579,15 @@
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	    cs_error(link->handle, RegisterClient, ret);
-	    mgslpc_detach(link);
-	    return NULL;
-    }
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    mgslpc_config(link);
 
     mgslpc_add_device(info);
 
-    return link;
+    return 0;
 }
 
 /* Card has been inserted.
@@ -736,85 +719,50 @@
 	    pcmcia_release_io(link->handle, &link->io);
     if (link->irq.AssignedIRQ)
 	    pcmcia_release_irq(link->handle, &link->irq);
-    if (link->state & DEV_STALE_LINK)
-	    mgslpc_detach(link);
 }
 
-static void mgslpc_detach(dev_link_t *link)
+static void mgslpc_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     if (debug_level >= DEBUG_LEVEL_INFO)
 	    printk("mgslpc_detach(0x%p)\n", link);
-    
-    /* find device */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	    if (*linkp == link) break;
-    if (*linkp == NULL)
-	    return;
 
     if (link->state & DEV_CONFIG) {
-	    /* device is configured/active, mark it so when
-	     * release() is called a proper detach() occurs.
-	     */
-	    if (debug_level >= DEBUG_LEVEL_INFO)
-		    printk(KERN_DEBUG "synclinkpc: detach postponed, '%s' "
-			   "still locked\n", link->dev->dev_name);
-	    link->state |= DEV_STALE_LINK;
-	    return;
+	    ((MGSLPC_INFO *)link->priv)->stop = 1;
+	    mgslpc_release((u_long)link);
     }
 
-    /* Break the link with Card Services */
-    if (link->handle)
-	    pcmcia_deregister_client(link->handle);
-    
-    /* Unlink device structure, and free it */
-    *linkp = link->next;
     mgslpc_remove_device((MGSLPC_INFO *)link->priv);
 }
 
-static int mgslpc_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int mgslpc_suspend(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
-    MGSLPC_INFO *info = link->priv;
-    
-    if (debug_level >= DEBUG_LEVEL_INFO)
-	    printk("mgslpc_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	    link->state &= ~DEV_PRESENT;
-	    if (link->state & DEV_CONFIG) {
-		    ((MGSLPC_INFO *)link->priv)->stop = 1;
-		    mgslpc_release((u_long)link);
-	    }
-	    break;
-    case CS_EVENT_CARD_INSERTION:
-	    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	    mgslpc_config(link);
-	    break;
-    case CS_EVENT_PM_SUSPEND:
-	    link->state |= DEV_SUSPEND;
-	    /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	    /* Mark the device as stopped, to block IO until later */
-	    info->stop = 1;
-	    if (link->state & DEV_CONFIG)
-		    pcmcia_release_configuration(link->handle);
-	    break;
-    case CS_EVENT_PM_RESUME:
-	    link->state &= ~DEV_SUSPEND;
-	    /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	    if (link->state & DEV_CONFIG)
-		    pcmcia_request_configuration(link->handle, &link->conf);
-	    info->stop = 0;
-	    break;
-    }
-    return 0;
+	dev_link_t *link = dev_to_instance(dev);
+	MGSLPC_INFO *info = link->priv;
+
+	link->state |= DEV_SUSPEND;
+	info->stop = 1;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
 }
 
+static int mgslpc_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	MGSLPC_INFO *info = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+	info->stop = 0;
+
+	return 0;
+}
+
+
 static inline int mgslpc_paranoia_check(MGSLPC_INFO *info,
 					char *name, const char *routine)
 {
@@ -3091,10 +3039,11 @@
 	.drv		= {
 		.name	= "synclink_cs",
 	},
-	.attach		= mgslpc_attach,
-	.event		= mgslpc_event,
-	.detach		= mgslpc_detach,
+	.probe		= mgslpc_attach,
+	.remove		= mgslpc_detach,
 	.id_table	= mgslpc_ids,
+	.suspend	= mgslpc_suspend,
+	.resume		= mgslpc_resume,
 };
 
 static struct tty_operations mgslpc_ops = {
@@ -3138,7 +3087,6 @@
 	}
 
 	pcmcia_unregister_driver(&mgslpc_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 static int __init synclink_cs_init(void)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7999da2..bdfdfd2 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1554,10 +1554,8 @@
 
 EXPORT_SYMBOL(secure_tcp_sequence_number);
 
-
-
-/* Generate secure starting point for ephemeral TCP port search */
-u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
+/* Generate secure starting point for ephemeral IPV4 transport port search */
+u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
 {
 	struct keydata *keyptr = get_keyptr();
 	u32 hash[4];
@@ -1575,7 +1573,7 @@
 }
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
+u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dport)
 {
 	struct keydata *keyptr = get_keyptr();
 	u32 hash[12];
@@ -1586,7 +1584,7 @@
 
 	return twothirdsMD4Transform(daddr, hash);
 }
-EXPORT_SYMBOL(secure_tcpv6_port_ephemeral);
+EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
 #endif
 
 #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
index 3df7a57..2e30865 100644
--- a/drivers/char/s3c2410-rtc.c
+++ b/drivers/char/s3c2410-rtc.c
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/rtc.h>
 #include <linux/bcd.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
 #include <asm/uaccess.h>
@@ -33,7 +34,6 @@
 
 #include <asm/mach/time.h>
 
-#include <asm/hardware/clock.h>
 #include <asm/arch/regs-rtc.h>
 
 /* need this for the RTC_AF definitions */
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 51a0737..f8dd852 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -471,7 +471,6 @@
 
 static struct sonypi_device {
 	struct pci_dev *dev;
-	struct platform_device *pdev;
 	u16 irq;
 	u16 bits;
 	u16 ioport1;
@@ -511,6 +510,11 @@
 #define SONYPI_ACPI_ACTIVE 0
 #endif				/* CONFIG_ACPI */
 
+#ifdef CONFIG_ACPI
+static struct acpi_device *sonypi_acpi_device;
+static int acpi_enabled;
+#endif
+
 static int sonypi_ec_write(u8 addr, u8 value)
 {
 #ifdef CONFIG_ACPI_EC
@@ -864,6 +868,11 @@
 	if (useinput)
 		sonypi_report_input_event(event);
 
+#ifdef CONFIG_ACPI
+	if (acpi_enabled)
+		acpi_bus_generate_event(sonypi_acpi_device, 1, event);
+#endif
+
 	kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event));
 	kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN);
 	wake_up_interruptible(&sonypi_device.fifo_proc_list);
@@ -1165,45 +1174,38 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int old_camera_power;
-
-static int sonypi_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef CONFIG_ACPI
+static int sonypi_acpi_add(struct acpi_device *device)
 {
-	old_camera_power = sonypi_device.camera_power;
-	sonypi_disable();
-
+	sonypi_acpi_device = device;
+	strcpy(acpi_device_name(device), "Sony laptop hotkeys");
+	strcpy(acpi_device_class(device), "sony/hotkey");
 	return 0;
 }
 
-static int sonypi_resume(struct platform_device *dev)
+static int sonypi_acpi_remove(struct acpi_device *device, int type)
 {
-	sonypi_enable(old_camera_power);
+	sonypi_acpi_device = NULL;
 	return 0;
 }
-#endif
 
-static void sonypi_shutdown(struct platform_device *dev)
-{
-	sonypi_disable();
-}
-
-static struct platform_driver sonypi_driver = {
-#ifdef CONFIG_PM
-	.suspend	= sonypi_suspend,
-	.resume		= sonypi_resume,
-#endif
-	.shutdown	= sonypi_shutdown,
-	.driver		= {
-		.name	= "sonypi",
+static struct acpi_driver sonypi_acpi_driver = {
+	.name           = "sonypi",
+	.class          = "hkey",
+	.ids            = "SNY6001",
+	.ops            = {
+		           .add = sonypi_acpi_add,
+			   .remove = sonypi_acpi_remove,
 	},
 };
+#endif
 
 static int __devinit sonypi_create_input_devices(void)
 {
 	struct input_dev *jog_dev;
 	struct input_dev *key_dev;
 	int i;
+	int error;
 
 	sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
 	if (!jog_dev)
@@ -1219,9 +1221,8 @@
 
 	sonypi_device.input_key_dev = key_dev = input_allocate_device();
 	if (!key_dev) {
-		input_free_device(jog_dev);
-		sonypi_device.input_jog_dev = NULL;
-		return -ENOMEM;
+		error = -ENOMEM;
+		goto err_free_jogdev;
 	}
 
 	key_dev->name = "Sony Vaio Keys";
@@ -1234,136 +1235,67 @@
 		if (sonypi_inputkeys[i].inputev)
 			set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
 
-	input_register_device(jog_dev);
-	input_register_device(key_dev);
+	error = input_register_device(jog_dev);
+	if (error)
+		goto err_free_keydev;
+
+	error = input_register_device(key_dev);
+	if (error)
+		goto err_unregister_jogdev;
 
 	return 0;
+
+ err_unregister_jogdev:
+	input_unregister_device(jog_dev);
+	/* Set to NULL so we don't free it again below */
+	jog_dev = NULL;
+ err_free_keydev:
+	input_free_device(key_dev);
+	sonypi_device.input_key_dev = NULL;
+ err_free_jogdev:
+	input_free_device(jog_dev);
+	sonypi_device.input_jog_dev = NULL;
+
+	return error;
 }
 
-static int __devinit sonypi_probe(void)
+static int __devinit sonypi_setup_ioports(struct sonypi_device *dev,
+				const struct sonypi_ioport_list *ioport_list)
 {
-	int i, ret;
-	struct sonypi_ioport_list *ioport_list;
-	struct sonypi_irq_list *irq_list;
-	struct pci_dev *pcidev;
+	while (ioport_list->port1) {
 
-	if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
-				     PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
-		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1;
-	else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
-					  PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
-		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
-	else
-		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
-
-	sonypi_device.dev = pcidev;
-
-	spin_lock_init(&sonypi_device.fifo_lock);
-	sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
-					 &sonypi_device.fifo_lock);
-	if (IS_ERR(sonypi_device.fifo)) {
-		printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
-		ret = PTR_ERR(sonypi_device.fifo);
-		goto out_fifo;
-	}
-
-	init_waitqueue_head(&sonypi_device.fifo_proc_list);
-	init_MUTEX(&sonypi_device.lock);
-	sonypi_device.bluetooth_power = -1;
-
-	if (pcidev && pci_enable_device(pcidev)) {
-		printk(KERN_ERR "sonypi: pci_enable_device failed\n");
-		ret = -EIO;
-		goto out_pcienable;
-	}
-
-	if (minor != -1)
-		sonypi_misc_device.minor = minor;
-	if ((ret = misc_register(&sonypi_misc_device))) {
-		printk(KERN_ERR "sonypi: misc_register failed\n");
-		goto out_miscreg;
-	}
-
-
-	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) {
-		ioport_list = sonypi_type1_ioport_list;
-		sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
-		sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET;
-		irq_list = sonypi_type1_irq_list;
-	} else if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
-		ioport_list = sonypi_type2_ioport_list;
-		sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
-		sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET;
-		irq_list = sonypi_type2_irq_list;
-	} else {
-		ioport_list = sonypi_type3_ioport_list;
-		sonypi_device.region_size = SONYPI_TYPE3_REGION_SIZE;
-		sonypi_device.evtype_offset = SONYPI_TYPE3_EVTYPE_OFFSET;
-		irq_list = sonypi_type3_irq_list;
-	}
-
-	for (i = 0; ioport_list[i].port1; i++) {
-		if (request_region(ioport_list[i].port1,
+		if (request_region(ioport_list->port1,
 				   sonypi_device.region_size,
 				   "Sony Programable I/O Device")) {
-			/* get the ioport */
-			sonypi_device.ioport1 = ioport_list[i].port1;
-			sonypi_device.ioport2 = ioport_list[i].port2;
-			break;
+			dev->ioport1 = ioport_list->port1;
+			dev->ioport2 = ioport_list->port2;
+			return 0;
 		}
-	}
-	if (!sonypi_device.ioport1) {
-		printk(KERN_ERR "sonypi: request_region failed\n");
-		ret = -ENODEV;
-		goto out_reqreg;
+		ioport_list++;
 	}
 
-	for (i = 0; irq_list[i].irq; i++) {
+	return -EBUSY;
+}
 
-		sonypi_device.irq = irq_list[i].irq;
-		sonypi_device.bits = irq_list[i].bits;
+static int __devinit sonypi_setup_irq(struct sonypi_device *dev,
+				      const struct sonypi_irq_list *irq_list)
+{
+	while (irq_list->irq) {
 
-		if (!request_irq(sonypi_device.irq, sonypi_irq,
-				 SA_SHIRQ, "sonypi", sonypi_irq))
-			break;
-	}
-
-	if (!irq_list[i].irq) {
-		printk(KERN_ERR "sonypi: request_irq failed\n");
-		ret = -ENODEV;
-		goto out_reqirq;
-	}
-
-	if (useinput) {
-
-		ret = sonypi_create_input_devices();
-		if (ret)
-			goto out_inputdevices;
-
-		spin_lock_init(&sonypi_device.input_fifo_lock);
-		sonypi_device.input_fifo =
-			kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
-				    &sonypi_device.input_fifo_lock);
-		if (IS_ERR(sonypi_device.input_fifo)) {
-			printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
-			ret = PTR_ERR(sonypi_device.input_fifo);
-			goto out_infifo;
+		if (!request_irq(irq_list->irq, sonypi_irq,
+				 SA_SHIRQ, "sonypi", sonypi_irq)) {
+			dev->irq = irq_list->irq;
+			dev->bits = irq_list->bits;
+			return 0;
 		}
-
-		INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL);
+		irq_list++;
 	}
 
-	sonypi_device.pdev = platform_device_register_simple("sonypi", -1,
-							     NULL, 0);
-	if (IS_ERR(sonypi_device.pdev)) {
-		ret = PTR_ERR(sonypi_device.pdev);
-		goto out_platformdev;
-	}
+	return -EBUSY;
+}
 
-	sonypi_enable(0);
-
-	printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver"
-	       "v%s.\n", SONYPI_DRIVER_VERSION);
+static void __devinit sonypi_display_info(void)
+{
 	printk(KERN_INFO "sonypi: detected type%d model, "
 	       "verbose = %d, fnkeyinit = %s, camera = %s, "
 	       "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n",
@@ -1382,55 +1314,196 @@
 	if (minor == -1)
 		printk(KERN_INFO "sonypi: device allocated minor is %d\n",
 		       sonypi_misc_device.minor);
+}
+
+static int __devinit sonypi_probe(struct platform_device *dev)
+{
+	const struct sonypi_ioport_list *ioport_list;
+	const struct sonypi_irq_list *irq_list;
+	struct pci_dev *pcidev;
+	int error;
+
+	spin_lock_init(&sonypi_device.fifo_lock);
+	sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
+					 &sonypi_device.fifo_lock);
+	if (IS_ERR(sonypi_device.fifo)) {
+		printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
+		return PTR_ERR(sonypi_device.fifo);
+	}
+
+	init_waitqueue_head(&sonypi_device.fifo_proc_list);
+	init_MUTEX(&sonypi_device.lock);
+	sonypi_device.bluetooth_power = -1;
+
+	if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+				     PCI_DEVICE_ID_INTEL_82371AB_3, NULL)))
+		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1;
+	else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+					  PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
+		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
+	else
+		sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
+
+	if (pcidev && pci_enable_device(pcidev)) {
+		printk(KERN_ERR "sonypi: pci_enable_device failed\n");
+		error = -EIO;
+		goto err_put_pcidev;
+	}
+
+	sonypi_device.dev = pcidev;
+
+	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) {
+		ioport_list = sonypi_type1_ioport_list;
+		sonypi_device.region_size = SONYPI_TYPE1_REGION_SIZE;
+		sonypi_device.evtype_offset = SONYPI_TYPE1_EVTYPE_OFFSET;
+		irq_list = sonypi_type1_irq_list;
+	} else if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
+		ioport_list = sonypi_type2_ioport_list;
+		sonypi_device.region_size = SONYPI_TYPE2_REGION_SIZE;
+		sonypi_device.evtype_offset = SONYPI_TYPE2_EVTYPE_OFFSET;
+		irq_list = sonypi_type2_irq_list;
+	} else {
+		ioport_list = sonypi_type3_ioport_list;
+		sonypi_device.region_size = SONYPI_TYPE3_REGION_SIZE;
+		sonypi_device.evtype_offset = SONYPI_TYPE3_EVTYPE_OFFSET;
+		irq_list = sonypi_type3_irq_list;
+	}
+
+	error = sonypi_setup_ioports(&sonypi_device, ioport_list);
+	if (error) {
+		printk(KERN_ERR "sonypi: failed to request ioports\n");
+		goto err_disable_pcidev;
+	}
+
+	error = sonypi_setup_irq(&sonypi_device, irq_list);
+	if (error) {
+		printk(KERN_ERR "sonypi: request_irq failed\n");
+		goto err_free_ioports;
+	}
+
+	if (minor != -1)
+		sonypi_misc_device.minor = minor;
+	error = misc_register(&sonypi_misc_device);
+	if (error) {
+		printk(KERN_ERR "sonypi: misc_register failed\n");
+		goto err_free_irq;
+	}
+
+	sonypi_display_info();
+
+	if (useinput) {
+
+		error = sonypi_create_input_devices();
+		if (error) {
+			printk(KERN_ERR
+				"sonypi: failed to create input devices\n");
+			goto err_miscdev_unregister;
+		}
+
+		spin_lock_init(&sonypi_device.input_fifo_lock);
+		sonypi_device.input_fifo =
+			kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL,
+				    &sonypi_device.input_fifo_lock);
+		if (IS_ERR(sonypi_device.input_fifo)) {
+			printk(KERN_ERR "sonypi: kfifo_alloc failed\n");
+			error = PTR_ERR(sonypi_device.input_fifo);
+			goto err_inpdev_unregister;
+		}
+
+		INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL);
+	}
+
+	sonypi_enable(0);
 
 	return 0;
 
-out_platformdev:
-	kfifo_free(sonypi_device.input_fifo);
-out_infifo:
+ err_inpdev_unregister:
 	input_unregister_device(sonypi_device.input_key_dev);
 	input_unregister_device(sonypi_device.input_jog_dev);
-out_inputdevices:
-	free_irq(sonypi_device.irq, sonypi_irq);
-out_reqirq:
-	release_region(sonypi_device.ioport1, sonypi_device.region_size);
-out_reqreg:
+ err_miscdev_unregister:
 	misc_deregister(&sonypi_misc_device);
-out_miscreg:
+ err_free_irq:
+	free_irq(sonypi_device.irq, sonypi_irq);
+ err_free_ioports:
+	release_region(sonypi_device.ioport1, sonypi_device.region_size);
+ err_disable_pcidev:
 	if (pcidev)
 		pci_disable_device(pcidev);
-out_pcienable:
+ err_put_pcidev:
+	pci_dev_put(pcidev);
 	kfifo_free(sonypi_device.fifo);
-out_fifo:
-	pci_dev_put(sonypi_device.dev);
-	return ret;
+
+	return error;
 }
 
-static void __devexit sonypi_remove(void)
+static int __devexit sonypi_remove(struct platform_device *dev)
 {
 	sonypi_disable();
 
 	synchronize_sched();  /* Allow sonypi interrupt to complete. */
 	flush_scheduled_work();
 
-	platform_device_unregister(sonypi_device.pdev);
-
 	if (useinput) {
 		input_unregister_device(sonypi_device.input_key_dev);
 		input_unregister_device(sonypi_device.input_jog_dev);
 		kfifo_free(sonypi_device.input_fifo);
 	}
 
+	misc_deregister(&sonypi_misc_device);
+
 	free_irq(sonypi_device.irq, sonypi_irq);
 	release_region(sonypi_device.ioport1, sonypi_device.region_size);
-	misc_deregister(&sonypi_misc_device);
-	if (sonypi_device.dev)
+
+	if (sonypi_device.dev) {
 		pci_disable_device(sonypi_device.dev);
+		pci_dev_put(sonypi_device.dev);
+	}
+
 	kfifo_free(sonypi_device.fifo);
-	pci_dev_put(sonypi_device.dev);
-	printk(KERN_INFO "sonypi: removed.\n");
+
+	return 0;
 }
 
+#ifdef CONFIG_PM
+static int old_camera_power;
+
+static int sonypi_suspend(struct platform_device *dev, pm_message_t state)
+{
+	old_camera_power = sonypi_device.camera_power;
+	sonypi_disable();
+
+	return 0;
+}
+
+static int sonypi_resume(struct platform_device *dev)
+{
+	sonypi_enable(old_camera_power);
+	return 0;
+}
+#else
+#define sonypi_suspend	NULL
+#define sonypi_resume	NULL
+#endif
+
+static void sonypi_shutdown(struct platform_device *dev)
+{
+	sonypi_disable();
+}
+
+static struct platform_driver sonypi_driver = {
+	.driver		= {
+		.name	= "sonypi",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sonypi_probe,
+	.remove		= __devexit_p(sonypi_remove),
+	.shutdown	= sonypi_shutdown,
+	.suspend	= sonypi_suspend,
+	.resume		= sonypi_resume,
+};
+
+static struct platform_device *sonypi_platform_device;
+
 static struct dmi_system_id __initdata sonypi_dmi_table[] = {
 	{
 		.ident = "Sony Vaio",
@@ -1451,26 +1524,52 @@
 
 static int __init sonypi_init(void)
 {
-	int ret;
+	int error;
+
+	printk(KERN_INFO
+		"sonypi: Sony Programmable I/O Controller Driver v%s.\n",
+		SONYPI_DRIVER_VERSION);
 
 	if (!dmi_check_system(sonypi_dmi_table))
 		return -ENODEV;
 
-	ret = platform_driver_register(&sonypi_driver);
-	if (ret)
-		return ret;
+	error = platform_driver_register(&sonypi_driver);
+	if (error)
+		return error;
 
-	ret = sonypi_probe();
-	if (ret)
-		platform_driver_unregister(&sonypi_driver);
+	sonypi_platform_device = platform_device_alloc("sonypi", -1);
+	if (!sonypi_platform_device) {
+		error = -ENOMEM;
+		goto err_driver_unregister;
+	}
 
-	return ret;
+	error = platform_device_add(sonypi_platform_device);
+	if (error)
+		goto err_free_device;
+
+#ifdef CONFIG_ACPI
+	if (acpi_bus_register_driver(&sonypi_acpi_driver) > 0)
+		acpi_enabled = 1;
+#endif
+
+	return 0;
+
+ err_free_device:
+	platform_device_put(sonypi_platform_device);
+ err_driver_unregister:
+	platform_driver_unregister(&sonypi_driver);
+	return error;
 }
 
 static void __exit sonypi_exit(void)
 {
+#ifdef CONFIG_ACPI
+	if (acpi_enabled)
+		acpi_bus_unregister_driver(&sonypi_acpi_driver);
+#endif
+	platform_device_unregister(sonypi_platform_device);
 	platform_driver_unregister(&sonypi_driver);
-	sonypi_remove();
+	printk(KERN_INFO "sonypi: removed.\n");
 }
 
 module_init(sonypi_init);
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
new file mode 100644
index 0000000..2b9cde9
--- /dev/null
+++ b/drivers/char/synclink_gt.c
@@ -0,0 +1,4501 @@
+/*
+ * $Id: synclink_gt.c,v 4.20 2005/11/08 19:51:55 paulkf Exp $
+ *
+ * Device driver for Microgate SyncLink GT serial adapters.
+ *
+ * written by Paul Fulghum for Microgate Corporation
+ * paulkf@microgate.com
+ *
+ * Microgate and SyncLink are trademarks of Microgate Corporation
+ *
+ * This code is released under the GNU General Public License (GPL)
+ *
+ * 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.
+ */
+
+/*
+ * DEBUG OUTPUT DEFINITIONS
+ *
+ * uncomment lines below to enable specific types of debug output
+ *
+ * DBGINFO   information - most verbose output
+ * DBGERR    serious errors
+ * DBGBH     bottom half service routine debugging
+ * DBGISR    interrupt service routine debugging
+ * DBGDATA   output receive and transmit data
+ * DBGTBUF   output transmit DMA buffers and registers
+ * DBGRBUF   output receive DMA buffers and registers
+ */
+
+#define DBGINFO(fmt) if (debug_level >= DEBUG_LEVEL_INFO) printk fmt
+#define DBGERR(fmt) if (debug_level >= DEBUG_LEVEL_ERROR) printk fmt
+#define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt
+#define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt
+#define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label))
+//#define DBGTBUF(info) dump_tbufs(info)
+//#define DBGRBUF(info) dump_rbufs(info)
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/ioctl.h>
+#include <linux/termios.h>
+#include <linux/bitops.h>
+#include <linux/workqueue.h>
+#include <linux/hdlc.h>
+
+#include <asm/serial.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/dma.h>
+#include <asm/types.h>
+#include <asm/uaccess.h>
+
+#include "linux/synclink.h"
+
+#ifdef CONFIG_HDLC_MODULE
+#define CONFIG_HDLC 1
+#endif
+
+/*
+ * module identification
+ */
+static char *driver_name     = "SyncLink GT";
+static char *driver_version  = "$Revision: 4.20 $";
+static char *tty_driver_name = "synclink_gt";
+static char *tty_dev_prefix  = "ttySLG";
+MODULE_LICENSE("GPL");
+#define MGSL_MAGIC 0x5401
+#define MAX_DEVICES 12
+
+static struct pci_device_id pci_table[] = {
+	{PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+	{PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+	{PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+	{0,}, /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, pci_table);
+
+static int  init_one(struct pci_dev *dev,const struct pci_device_id *ent);
+static void remove_one(struct pci_dev *dev);
+static struct pci_driver pci_driver = {
+	.name		= "synclink_gt",
+	.id_table	= pci_table,
+	.probe		= init_one,
+	.remove		= __devexit_p(remove_one),
+};
+
+static int pci_registered;
+
+/*
+ * module configuration and status
+ */
+static struct slgt_info *slgt_device_list;
+static int slgt_device_count;
+
+static int ttymajor;
+static int debug_level;
+static int maxframe[MAX_DEVICES];
+static int dosyncppp[MAX_DEVICES];
+
+module_param(ttymajor, int, 0);
+module_param(debug_level, int, 0);
+module_param_array(maxframe, int, NULL, 0);
+module_param_array(dosyncppp, int, NULL, 0);
+
+MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned");
+MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail");
+MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)");
+MODULE_PARM_DESC(dosyncppp, "Enable synchronous net device, 0=disable 1=enable");
+
+/*
+ * tty support and callbacks
+ */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+static struct tty_driver *serial_driver;
+
+static int  open(struct tty_struct *tty, struct file * filp);
+static void close(struct tty_struct *tty, struct file * filp);
+static void hangup(struct tty_struct *tty);
+static void set_termios(struct tty_struct *tty, struct termios *old_termios);
+
+static int  write(struct tty_struct *tty, const unsigned char *buf, int count);
+static void put_char(struct tty_struct *tty, unsigned char ch);
+static void send_xchar(struct tty_struct *tty, char ch);
+static void wait_until_sent(struct tty_struct *tty, int timeout);
+static int  write_room(struct tty_struct *tty);
+static void flush_chars(struct tty_struct *tty);
+static void flush_buffer(struct tty_struct *tty);
+static void tx_hold(struct tty_struct *tty);
+static void tx_release(struct tty_struct *tty);
+
+static int  ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
+static int  read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
+static int  chars_in_buffer(struct tty_struct *tty);
+static void throttle(struct tty_struct * tty);
+static void unthrottle(struct tty_struct * tty);
+static void set_break(struct tty_struct *tty, int break_state);
+
+/*
+ * generic HDLC support and callbacks
+ */
+#ifdef CONFIG_HDLC
+#define dev_to_port(D) (dev_to_hdlc(D)->priv)
+static void hdlcdev_tx_done(struct slgt_info *info);
+static void hdlcdev_rx(struct slgt_info *info, char *buf, int size);
+static int  hdlcdev_init(struct slgt_info *info);
+static void hdlcdev_exit(struct slgt_info *info);
+#endif
+
+
+/*
+ * device specific structures, macros and functions
+ */
+
+#define SLGT_MAX_PORTS 4
+#define SLGT_REG_SIZE  256
+
+/*
+ * DMA buffer descriptor and access macros
+ */
+struct slgt_desc
+{
+	unsigned short count;
+	unsigned short status;
+	unsigned int pbuf;  /* physical address of data buffer */
+	unsigned int next;  /* physical address of next descriptor */
+
+	/* driver book keeping */
+	char *buf;          /* virtual  address of data buffer */
+    	unsigned int pdesc; /* physical address of this descriptor */
+	dma_addr_t buf_dma_addr;
+};
+
+#define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b))
+#define set_desc_next(a,b) (a).next   = cpu_to_le32((unsigned int)(b))
+#define set_desc_count(a,b)(a).count  = cpu_to_le16((unsigned short)(b))
+#define set_desc_eof(a,b)  (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0))
+#define desc_count(a)      (le16_to_cpu((a).count))
+#define desc_status(a)     (le16_to_cpu((a).status))
+#define desc_complete(a)   (le16_to_cpu((a).status) & BIT15)
+#define desc_eof(a)        (le16_to_cpu((a).status) & BIT2)
+#define desc_crc_error(a)  (le16_to_cpu((a).status) & BIT1)
+#define desc_abort(a)      (le16_to_cpu((a).status) & BIT0)
+#define desc_residue(a)    ((le16_to_cpu((a).status) & 0x38) >> 3)
+
+struct _input_signal_events {
+	int ri_up;
+	int ri_down;
+	int dsr_up;
+	int dsr_down;
+	int dcd_up;
+	int dcd_down;
+	int cts_up;
+	int cts_down;
+};
+
+/*
+ * device instance data structure
+ */
+struct slgt_info {
+	void *if_ptr;		/* General purpose pointer (used by SPPP) */
+
+	struct slgt_info *next_device;	/* device list link */
+
+	int magic;
+	int flags;
+
+	char device_name[25];
+	struct pci_dev *pdev;
+
+	int port_count;  /* count of ports on adapter */
+	int adapter_num; /* adapter instance number */
+	int port_num;    /* port instance number */
+
+	/* array of pointers to port contexts on this adapter */
+	struct slgt_info *port_array[SLGT_MAX_PORTS];
+
+	int			count;		/* count of opens */
+	int			line;		/* tty line instance number */
+	unsigned short		close_delay;
+	unsigned short		closing_wait;	/* time to wait before closing */
+
+	struct mgsl_icount	icount;
+
+	struct tty_struct 	*tty;
+	int			timeout;
+	int			x_char;		/* xon/xoff character */
+	int			blocked_open;	/* # of blocked opens */
+	unsigned int		read_status_mask;
+	unsigned int 		ignore_status_mask;
+
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+
+	wait_queue_head_t	status_event_wait_q;
+	wait_queue_head_t	event_wait_q;
+	struct timer_list	tx_timer;
+	struct timer_list	rx_timer;
+
+	spinlock_t lock;	/* spinlock for synchronizing with ISR */
+
+	struct work_struct task;
+	u32 pending_bh;
+	int bh_requested;
+	int bh_running;
+
+	int isr_overflow;
+	int irq_requested;	/* nonzero if IRQ requested */
+	int irq_occurred;	/* for diagnostics use */
+
+	/* device configuration */
+
+	unsigned int bus_type;
+	unsigned int irq_level;
+	unsigned long irq_flags;
+
+	unsigned char __iomem * reg_addr;  /* memory mapped registers address */
+	u32 phys_reg_addr;
+	u32 reg_offset;
+	int reg_addr_requested;
+
+	MGSL_PARAMS params;       /* communications parameters */
+	u32 idle_mode;
+	u32 max_frame_size;       /* as set by device config */
+
+	unsigned int raw_rx_size;
+	unsigned int if_mode;
+
+	/* device status */
+
+	int rx_enabled;
+	int rx_restart;
+
+	int tx_enabled;
+	int tx_active;
+
+	unsigned char signals;    /* serial signal states */
+	unsigned int init_error;  /* initialization error */
+
+	unsigned char *tx_buf;
+	int tx_count;
+
+	char flag_buf[MAX_ASYNC_BUFFER_SIZE];
+	char char_buf[MAX_ASYNC_BUFFER_SIZE];
+	BOOLEAN drop_rts_on_tx_done;
+	struct	_input_signal_events	input_signal_events;
+
+	int dcd_chkcount;	/* check counts to prevent */
+	int cts_chkcount;	/* too many IRQs if a signal */
+	int dsr_chkcount;	/* is floating */
+	int ri_chkcount;
+
+	char *bufs;		/* virtual address of DMA buffer lists */
+	dma_addr_t bufs_dma_addr; /* physical address of buffer descriptors */
+
+	unsigned int rbuf_count;
+	struct slgt_desc *rbufs;
+	unsigned int rbuf_current;
+	unsigned int rbuf_index;
+
+	unsigned int tbuf_count;
+	struct slgt_desc *tbufs;
+	unsigned int tbuf_current;
+	unsigned int tbuf_start;
+
+	unsigned char *tmp_rbuf;
+	unsigned int tmp_rbuf_count;
+
+	/* SPPP/Cisco HDLC device parts */
+
+	int netcount;
+	int dosyncppp;
+	spinlock_t netlock;
+#ifdef CONFIG_HDLC
+	struct net_device *netdev;
+#endif
+
+};
+
+static MGSL_PARAMS default_params = {
+	.mode            = MGSL_MODE_HDLC,
+	.loopback        = 0,
+	.flags           = HDLC_FLAG_UNDERRUN_ABORT15,
+	.encoding        = HDLC_ENCODING_NRZI_SPACE,
+	.clock_speed     = 0,
+	.addr_filter     = 0xff,
+	.crc_type        = HDLC_CRC_16_CCITT,
+	.preamble_length = HDLC_PREAMBLE_LENGTH_8BITS,
+	.preamble        = HDLC_PREAMBLE_PATTERN_NONE,
+	.data_rate       = 9600,
+	.data_bits       = 8,
+	.stop_bits       = 1,
+	.parity          = ASYNC_PARITY_NONE
+};
+
+
+#define BH_RECEIVE  1
+#define BH_TRANSMIT 2
+#define BH_STATUS   4
+#define IO_PIN_SHUTDOWN_LIMIT 100
+
+#define DMABUFSIZE 256
+#define DESC_LIST_SIZE 4096
+
+#define MASK_PARITY  BIT1
+#define MASK_FRAMING BIT2
+#define MASK_BREAK   BIT3
+#define MASK_OVERRUN BIT4
+
+#define GSR   0x00 /* global status */
+#define TDR   0x80 /* tx data */
+#define RDR   0x80 /* rx data */
+#define TCR   0x82 /* tx control */
+#define TIR   0x84 /* tx idle */
+#define TPR   0x85 /* tx preamble */
+#define RCR   0x86 /* rx control */
+#define VCR   0x88 /* V.24 control */
+#define CCR   0x89 /* clock control */
+#define BDR   0x8a /* baud divisor */
+#define SCR   0x8c /* serial control */
+#define SSR   0x8e /* serial status */
+#define RDCSR 0x90 /* rx DMA control/status */
+#define TDCSR 0x94 /* tx DMA control/status */
+#define RDDAR 0x98 /* rx DMA descriptor address */
+#define TDDAR 0x9c /* tx DMA descriptor address */
+
+#define RXIDLE      BIT14
+#define RXBREAK     BIT14
+#define IRQ_TXDATA  BIT13
+#define IRQ_TXIDLE  BIT12
+#define IRQ_TXUNDER BIT11 /* HDLC */
+#define IRQ_RXDATA  BIT10
+#define IRQ_RXIDLE  BIT9  /* HDLC */
+#define IRQ_RXBREAK BIT9  /* async */
+#define IRQ_RXOVER  BIT8
+#define IRQ_DSR     BIT7
+#define IRQ_CTS     BIT6
+#define IRQ_DCD     BIT5
+#define IRQ_RI      BIT4
+#define IRQ_ALL     0x3ff0
+#define IRQ_MASTER  BIT0
+
+#define slgt_irq_on(info, mask) \
+	wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) | (mask)))
+#define slgt_irq_off(info, mask) \
+	wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) & ~(mask)))
+
+static __u8  rd_reg8(struct slgt_info *info, unsigned int addr);
+static void  wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value);
+static __u16 rd_reg16(struct slgt_info *info, unsigned int addr);
+static void  wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value);
+static __u32 rd_reg32(struct slgt_info *info, unsigned int addr);
+static void  wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value);
+
+static void  msc_set_vcr(struct slgt_info *info);
+
+static int  startup(struct slgt_info *info);
+static int  block_til_ready(struct tty_struct *tty, struct file * filp,struct slgt_info *info);
+static void shutdown(struct slgt_info *info);
+static void program_hw(struct slgt_info *info);
+static void change_params(struct slgt_info *info);
+
+static int  register_test(struct slgt_info *info);
+static int  irq_test(struct slgt_info *info);
+static int  loopback_test(struct slgt_info *info);
+static int  adapter_test(struct slgt_info *info);
+
+static void reset_adapter(struct slgt_info *info);
+static void reset_port(struct slgt_info *info);
+static void async_mode(struct slgt_info *info);
+static void hdlc_mode(struct slgt_info *info);
+
+static void rx_stop(struct slgt_info *info);
+static void rx_start(struct slgt_info *info);
+static void reset_rbufs(struct slgt_info *info);
+static void free_rbufs(struct slgt_info *info, unsigned int first, unsigned int last);
+static void rdma_reset(struct slgt_info *info);
+static int  rx_get_frame(struct slgt_info *info);
+static int  rx_get_buf(struct slgt_info *info);
+
+static void tx_start(struct slgt_info *info);
+static void tx_stop(struct slgt_info *info);
+static void tx_set_idle(struct slgt_info *info);
+static unsigned int free_tbuf_count(struct slgt_info *info);
+static void reset_tbufs(struct slgt_info *info);
+static void tdma_reset(struct slgt_info *info);
+static void tx_load(struct slgt_info *info, const char *buf, unsigned int count);
+
+static void get_signals(struct slgt_info *info);
+static void set_signals(struct slgt_info *info);
+static void enable_loopback(struct slgt_info *info);
+static void set_rate(struct slgt_info *info, u32 data_rate);
+
+static int  bh_action(struct slgt_info *info);
+static void bh_handler(void* context);
+static void bh_transmit(struct slgt_info *info);
+static void isr_serial(struct slgt_info *info);
+static void isr_rdma(struct slgt_info *info);
+static void isr_txeom(struct slgt_info *info, unsigned short status);
+static void isr_tdma(struct slgt_info *info);
+static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+
+static int  alloc_dma_bufs(struct slgt_info *info);
+static void free_dma_bufs(struct slgt_info *info);
+static int  alloc_desc(struct slgt_info *info);
+static void free_desc(struct slgt_info *info);
+static int  alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count);
+static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count);
+
+static int  alloc_tmp_rbuf(struct slgt_info *info);
+static void free_tmp_rbuf(struct slgt_info *info);
+
+static void tx_timeout(unsigned long context);
+static void rx_timeout(unsigned long context);
+
+/*
+ * ioctl handlers
+ */
+static int  get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount);
+static int  get_params(struct slgt_info *info, MGSL_PARAMS __user *params);
+static int  set_params(struct slgt_info *info, MGSL_PARAMS __user *params);
+static int  get_txidle(struct slgt_info *info, int __user *idle_mode);
+static int  set_txidle(struct slgt_info *info, int idle_mode);
+static int  tx_enable(struct slgt_info *info, int enable);
+static int  tx_abort(struct slgt_info *info);
+static int  rx_enable(struct slgt_info *info, int enable);
+static int  modem_input_wait(struct slgt_info *info,int arg);
+static int  wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr);
+static int  tiocmget(struct tty_struct *tty, struct file *file);
+static int  tiocmset(struct tty_struct *tty, struct file *file,
+		     unsigned int set, unsigned int clear);
+static void set_break(struct tty_struct *tty, int break_state);
+static int  get_interface(struct slgt_info *info, int __user *if_mode);
+static int  set_interface(struct slgt_info *info, int if_mode);
+
+/*
+ * driver functions
+ */
+static void add_device(struct slgt_info *info);
+static void device_init(int adapter_num, struct pci_dev *pdev);
+static int  claim_resources(struct slgt_info *info);
+static void release_resources(struct slgt_info *info);
+
+/*
+ * DEBUG OUTPUT CODE
+ */
+#ifndef DBGINFO
+#define DBGINFO(fmt)
+#endif
+#ifndef DBGERR
+#define DBGERR(fmt)
+#endif
+#ifndef DBGBH
+#define DBGBH(fmt)
+#endif
+#ifndef DBGISR
+#define DBGISR(fmt)
+#endif
+
+#ifdef DBGDATA
+static void trace_block(struct slgt_info *info, const char *data, int count, const char *label)
+{
+	int i;
+	int linecount;
+	printk("%s %s data:\n",info->device_name, label);
+	while(count) {
+		linecount = (count > 16) ? 16 : count;
+		for(i=0; i < linecount; i++)
+			printk("%02X ",(unsigned char)data[i]);
+		for(;i<17;i++)
+			printk("   ");
+		for(i=0;i<linecount;i++) {
+			if (data[i]>=040 && data[i]<=0176)
+				printk("%c",data[i]);
+			else
+				printk(".");
+		}
+		printk("\n");
+		data  += linecount;
+		count -= linecount;
+	}
+}
+#else
+#define DBGDATA(info, buf, size, label)
+#endif
+
+#ifdef DBGTBUF
+static void dump_tbufs(struct slgt_info *info)
+{
+	int i;
+	printk("tbuf_current=%d\n", info->tbuf_current);
+	for (i=0 ; i < info->tbuf_count ; i++) {
+		printk("%d: count=%04X status=%04X\n",
+			i, le16_to_cpu(info->tbufs[i].count), le16_to_cpu(info->tbufs[i].status));
+	}
+}
+#else
+#define DBGTBUF(info)
+#endif
+
+#ifdef DBGRBUF
+static void dump_rbufs(struct slgt_info *info)
+{
+	int i;
+	printk("rbuf_current=%d\n", info->rbuf_current);
+	for (i=0 ; i < info->rbuf_count ; i++) {
+		printk("%d: count=%04X status=%04X\n",
+			i, le16_to_cpu(info->rbufs[i].count), le16_to_cpu(info->rbufs[i].status));
+	}
+}
+#else
+#define DBGRBUF(info)
+#endif
+
+static inline int sanity_check(struct slgt_info *info, char *devname, const char *name)
+{
+#ifdef SANITY_CHECK
+	if (!info) {
+		printk("null struct slgt_info for (%s) in %s\n", devname, name);
+		return 1;
+	}
+	if (info->magic != MGSL_MAGIC) {
+		printk("bad magic number struct slgt_info (%s) in %s\n", devname, name);
+		return 1;
+	}
+#else
+	if (!info)
+		return 1;
+#endif
+	return 0;
+}
+
+/**
+ * line discipline callback wrappers
+ *
+ * The wrappers maintain line discipline references
+ * while calling into the line discipline.
+ *
+ * ldisc_receive_buf  - pass receive data to line discipline
+ */
+static void ldisc_receive_buf(struct tty_struct *tty,
+			      const __u8 *data, char *flags, int count)
+{
+	struct tty_ldisc *ld;
+	if (!tty)
+		return;
+	ld = tty_ldisc_ref(tty);
+	if (ld) {
+		if (ld->receive_buf)
+			ld->receive_buf(tty, data, flags, count);
+		tty_ldisc_deref(ld);
+	}
+}
+
+/* tty callbacks */
+
+static int open(struct tty_struct *tty, struct file *filp)
+{
+	struct slgt_info *info;
+	int retval, line;
+	unsigned long flags;
+
+	line = tty->index;
+	if ((line < 0) || (line >= slgt_device_count)) {
+		DBGERR(("%s: open with invalid line #%d.\n", driver_name, line));
+		return -ENODEV;
+	}
+
+	info = slgt_device_list;
+	while(info && info->line != line)
+		info = info->next_device;
+	if (sanity_check(info, tty->name, "open"))
+		return -ENODEV;
+	if (info->init_error) {
+		DBGERR(("%s init error=%d\n", info->device_name, info->init_error));
+		return -ENODEV;
+	}
+
+	tty->driver_data = info;
+	info->tty = tty;
+
+	DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->count));
+
+	/* If port is closing, signal caller to try again */
+	if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		retval = ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+		goto cleanup;
+	}
+
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+	spin_lock_irqsave(&info->netlock, flags);
+	if (info->netcount) {
+		retval = -EBUSY;
+		spin_unlock_irqrestore(&info->netlock, flags);
+		goto cleanup;
+	}
+	info->count++;
+	spin_unlock_irqrestore(&info->netlock, flags);
+
+	if (info->count == 1) {
+		/* 1st open on this device, init hardware */
+		retval = startup(info);
+		if (retval < 0)
+			goto cleanup;
+	}
+
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+		DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval));
+		goto cleanup;
+	}
+
+	retval = 0;
+
+cleanup:
+	if (retval) {
+		if (tty->count == 1)
+			info->tty = NULL; /* tty layer will release tty struct */
+		if(info->count)
+			info->count--;
+	}
+
+	DBGINFO(("%s open rc=%d\n", info->device_name, retval));
+	return retval;
+}
+
+static void close(struct tty_struct *tty, struct file *filp)
+{
+	struct slgt_info *info = tty->driver_data;
+
+	if (sanity_check(info, tty->name, "close"))
+		return;
+	DBGINFO(("%s close entry, count=%d\n", info->device_name, info->count));
+
+	if (!info->count)
+		return;
+
+	if (tty_hung_up_p(filp))
+		goto cleanup;
+
+	if ((tty->count == 1) && (info->count != 1)) {
+		/*
+		 * tty->count is 1 and the tty structure will be freed.
+		 * info->count should be one in this case.
+		 * if it's not, correct it so that the port is shutdown.
+		 */
+		DBGERR(("%s close: bad refcount; tty->count=1, "
+		       "info->count=%d\n", info->device_name, info->count));
+		info->count = 1;
+	}
+
+	info->count--;
+
+	/* if at least one open remaining, leave hardware active */
+	if (info->count)
+		goto cleanup;
+
+	info->flags |= ASYNC_CLOSING;
+
+	/* set tty->closing to notify line discipline to
+	 * only process XON/XOFF characters. Only the N_TTY
+	 * discipline appears to use this (ppp does not).
+	 */
+	tty->closing = 1;
+
+	/* wait for transmit data to clear all layers */
+
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) {
+		DBGINFO(("%s call tty_wait_until_sent\n", info->device_name));
+		tty_wait_until_sent(tty, info->closing_wait);
+	}
+
+ 	if (info->flags & ASYNC_INITIALIZED)
+ 		wait_until_sent(tty, info->timeout);
+	if (tty->driver->flush_buffer)
+		tty->driver->flush_buffer(tty);
+	tty_ldisc_flush(tty);
+
+	shutdown(info);
+
+	tty->closing = 0;
+	info->tty = NULL;
+
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			msleep_interruptible(jiffies_to_msecs(info->close_delay));
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
+
+	wake_up_interruptible(&info->close_wait);
+
+cleanup:
+	DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->count));
+}
+
+static void hangup(struct tty_struct *tty)
+{
+	struct slgt_info *info = tty->driver_data;
+
+	if (sanity_check(info, tty->name, "hangup"))
+		return;
+	DBGINFO(("%s hangup\n", info->device_name));
+
+	flush_buffer(tty);
+	shutdown(info);
+
+	info->count = 0;
+	info->flags &= ~ASYNC_NORMAL_ACTIVE;
+	info->tty = NULL;
+
+	wake_up_interruptible(&info->open_wait);
+}
+
+static void set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	DBGINFO(("%s set_termios\n", tty->driver->name));
+
+	/* just return if nothing has changed */
+	if ((tty->termios->c_cflag == old_termios->c_cflag)
+	    && (RELEVANT_IFLAG(tty->termios->c_iflag)
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+		return;
+
+	change_params(info);
+
+	/* Handle transition to B0 status */
+	if (old_termios->c_cflag & CBAUD &&
+	    !(tty->termios->c_cflag & CBAUD)) {
+		info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
+		spin_lock_irqsave(&info->lock,flags);
+		set_signals(info);
+		spin_unlock_irqrestore(&info->lock,flags);
+	}
+
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    tty->termios->c_cflag & CBAUD) {
+		info->signals |= SerialSignal_DTR;
+ 		if (!(tty->termios->c_cflag & CRTSCTS) ||
+ 		    !test_bit(TTY_THROTTLED, &tty->flags)) {
+			info->signals |= SerialSignal_RTS;
+ 		}
+		spin_lock_irqsave(&info->lock,flags);
+	 	set_signals(info);
+		spin_unlock_irqrestore(&info->lock,flags);
+	}
+
+	/* Handle turning off CRTSCTS */
+	if (old_termios->c_cflag & CRTSCTS &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		tx_release(tty);
+	}
+}
+
+static int write(struct tty_struct *tty,
+		 const unsigned char *buf, int count)
+{
+	int ret = 0;
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "write"))
+		goto cleanup;
+	DBGINFO(("%s write count=%d\n", info->device_name, count));
+
+	if (!tty || !info->tx_buf)
+		goto cleanup;
+
+	if (count > info->max_frame_size) {
+		ret = -EIO;
+		goto cleanup;
+	}
+
+	if (!count)
+		goto cleanup;
+
+	if (info->params.mode == MGSL_MODE_RAW) {
+		unsigned int bufs_needed = (count/DMABUFSIZE);
+		unsigned int bufs_free = free_tbuf_count(info);
+		if (count % DMABUFSIZE)
+			++bufs_needed;
+		if (bufs_needed > bufs_free)
+			goto cleanup;
+	} else {
+		if (info->tx_active)
+			goto cleanup;
+		if (info->tx_count) {
+			/* send accumulated data from send_char() calls */
+			/* as frame and wait before accepting more data. */
+			tx_load(info, info->tx_buf, info->tx_count);
+			goto start;
+		}
+	}
+
+	ret = info->tx_count = count;
+	tx_load(info, buf, count);
+	goto start;
+
+start:
+ 	if (info->tx_count && !tty->stopped && !tty->hw_stopped) {
+		spin_lock_irqsave(&info->lock,flags);
+		if (!info->tx_active)
+		 	tx_start(info);
+		spin_unlock_irqrestore(&info->lock,flags);
+ 	}
+
+cleanup:
+	DBGINFO(("%s write rc=%d\n", info->device_name, ret));
+	return ret;
+}
+
+static void put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "put_char"))
+		return;
+	DBGINFO(("%s put_char(%d)\n", info->device_name, ch));
+	if (!tty || !info->tx_buf)
+		return;
+	spin_lock_irqsave(&info->lock,flags);
+	if (!info->tx_active && (info->tx_count < info->max_frame_size))
+		info->tx_buf[info->tx_count++] = ch;
+	spin_unlock_irqrestore(&info->lock,flags);
+}
+
+static void send_xchar(struct tty_struct *tty, char ch)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "send_xchar"))
+		return;
+	DBGINFO(("%s send_xchar(%d)\n", info->device_name, ch));
+	info->x_char = ch;
+	if (ch) {
+		spin_lock_irqsave(&info->lock,flags);
+		if (!info->tx_enabled)
+		 	tx_start(info);
+		spin_unlock_irqrestore(&info->lock,flags);
+	}
+}
+
+static void wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+
+	if (!info )
+		return;
+	if (sanity_check(info, tty->name, "wait_until_sent"))
+		return;
+	DBGINFO(("%s wait_until_sent entry\n", info->device_name));
+	if (!(info->flags & ASYNC_INITIALIZED))
+		goto exit;
+
+	orig_jiffies = jiffies;
+
+	/* Set check interval to 1/5 of estimated time to
+	 * send a character, and make it at least 1. The check
+	 * interval should also be less than the timeout.
+	 * Note: use tight timings here to satisfy the NIST-PCTS.
+	 */
+
+	if (info->params.data_rate) {
+	       	char_time = info->timeout/(32 * 5);
+		if (!char_time)
+			char_time++;
+	} else
+		char_time = 1;
+
+	if (timeout)
+		char_time = min_t(unsigned long, char_time, timeout);
+
+	while (info->tx_active) {
+		msleep_interruptible(jiffies_to_msecs(char_time));
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+
+exit:
+	DBGINFO(("%s wait_until_sent exit\n", info->device_name));
+}
+
+static int write_room(struct tty_struct *tty)
+{
+	struct slgt_info *info = tty->driver_data;
+	int ret;
+
+	if (sanity_check(info, tty->name, "write_room"))
+		return 0;
+	ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE;
+	DBGINFO(("%s write_room=%d\n", info->device_name, ret));
+	return ret;
+}
+
+static void flush_chars(struct tty_struct *tty)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "flush_chars"))
+		return;
+	DBGINFO(("%s flush_chars entry tx_count=%d\n", info->device_name, info->tx_count));
+
+	if (info->tx_count <= 0 || tty->stopped ||
+	    tty->hw_stopped || !info->tx_buf)
+		return;
+
+	DBGINFO(("%s flush_chars start transmit\n", info->device_name));
+
+	spin_lock_irqsave(&info->lock,flags);
+	if (!info->tx_active && info->tx_count) {
+		tx_load(info, info->tx_buf,info->tx_count);
+	 	tx_start(info);
+	}
+	spin_unlock_irqrestore(&info->lock,flags);
+}
+
+static void flush_buffer(struct tty_struct *tty)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "flush_buffer"))
+		return;
+	DBGINFO(("%s flush_buffer\n", info->device_name));
+
+	spin_lock_irqsave(&info->lock,flags);
+	if (!info->tx_active)
+		info->tx_count = 0;
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	wake_up_interruptible(&tty->write_wait);
+	tty_wakeup(tty);
+}
+
+/*
+ * throttle (stop) transmitter
+ */
+static void tx_hold(struct tty_struct *tty)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "tx_hold"))
+		return;
+	DBGINFO(("%s tx_hold\n", info->device_name));
+	spin_lock_irqsave(&info->lock,flags);
+	if (info->tx_enabled && info->params.mode == MGSL_MODE_ASYNC)
+	 	tx_stop(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+}
+
+/*
+ * release (start) transmitter
+ */
+static void tx_release(struct tty_struct *tty)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "tx_release"))
+		return;
+	DBGINFO(("%s tx_release\n", info->device_name));
+	spin_lock_irqsave(&info->lock,flags);
+	if (!info->tx_active && info->tx_count) {
+		tx_load(info, info->tx_buf, info->tx_count);
+	 	tx_start(info);
+	}
+	spin_unlock_irqrestore(&info->lock,flags);
+}
+
+/*
+ * Service an IOCTL request
+ *
+ * Arguments
+ *
+ * 	tty	pointer to tty instance data
+ * 	file	pointer to associated file object for device
+ * 	cmd	IOCTL command code
+ * 	arg	command argument/context
+ *
+ * Return 0 if success, otherwise error code
+ */
+static int ioctl(struct tty_struct *tty, struct file *file,
+		 unsigned int cmd, unsigned long arg)
+{
+	struct slgt_info *info = tty->driver_data;
+	struct mgsl_icount cnow;	/* kernel counter temps */
+	struct serial_icounter_struct __user *p_cuser;	/* user space */
+	unsigned long flags;
+	void __user *argp = (void __user *)arg;
+
+	if (sanity_check(info, tty->name, "ioctl"))
+		return -ENODEV;
+	DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd));
+
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+
+	switch (cmd) {
+	case MGSL_IOCGPARAMS:
+		return get_params(info, argp);
+	case MGSL_IOCSPARAMS:
+		return set_params(info, argp);
+	case MGSL_IOCGTXIDLE:
+		return get_txidle(info, argp);
+	case MGSL_IOCSTXIDLE:
+		return set_txidle(info, (int)arg);
+	case MGSL_IOCTXENABLE:
+		return tx_enable(info, (int)arg);
+	case MGSL_IOCRXENABLE:
+		return rx_enable(info, (int)arg);
+	case MGSL_IOCTXABORT:
+		return tx_abort(info);
+	case MGSL_IOCGSTATS:
+		return get_stats(info, argp);
+	case MGSL_IOCWAITEVENT:
+		return wait_mgsl_event(info, argp);
+	case TIOCMIWAIT:
+		return modem_input_wait(info,(int)arg);
+	case MGSL_IOCGIF:
+		return get_interface(info, argp);
+	case MGSL_IOCSIF:
+		return set_interface(info,(int)arg);
+	case TIOCGICOUNT:
+		spin_lock_irqsave(&info->lock,flags);
+		cnow = info->icount;
+		spin_unlock_irqrestore(&info->lock,flags);
+		p_cuser = argp;
+		if (put_user(cnow.cts, &p_cuser->cts) ||
+		    put_user(cnow.dsr, &p_cuser->dsr) ||
+		    put_user(cnow.rng, &p_cuser->rng) ||
+		    put_user(cnow.dcd, &p_cuser->dcd) ||
+		    put_user(cnow.rx, &p_cuser->rx) ||
+		    put_user(cnow.tx, &p_cuser->tx) ||
+		    put_user(cnow.frame, &p_cuser->frame) ||
+		    put_user(cnow.overrun, &p_cuser->overrun) ||
+		    put_user(cnow.parity, &p_cuser->parity) ||
+		    put_user(cnow.brk, &p_cuser->brk) ||
+		    put_user(cnow.buf_overrun, &p_cuser->buf_overrun))
+			return -EFAULT;
+		return 0;
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+/*
+ * proc fs support
+ */
+static inline int line_info(char *buf, struct slgt_info *info)
+{
+	char stat_buf[30];
+	int ret;
+	unsigned long flags;
+
+	ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
+		      info->device_name, info->phys_reg_addr,
+		      info->irq_level, info->max_frame_size);
+
+	/* output current serial signal states */
+	spin_lock_irqsave(&info->lock,flags);
+	get_signals(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+	if (info->signals & SerialSignal_RTS)
+		strcat(stat_buf, "|RTS");
+	if (info->signals & SerialSignal_CTS)
+		strcat(stat_buf, "|CTS");
+	if (info->signals & SerialSignal_DTR)
+		strcat(stat_buf, "|DTR");
+	if (info->signals & SerialSignal_DSR)
+		strcat(stat_buf, "|DSR");
+	if (info->signals & SerialSignal_DCD)
+		strcat(stat_buf, "|CD");
+	if (info->signals & SerialSignal_RI)
+		strcat(stat_buf, "|RI");
+
+	if (info->params.mode != MGSL_MODE_ASYNC) {
+		ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+			       info->icount.txok, info->icount.rxok);
+		if (info->icount.txunder)
+			ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+		if (info->icount.txabort)
+			ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+		if (info->icount.rxshort)
+			ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+		if (info->icount.rxlong)
+			ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+		if (info->icount.rxover)
+			ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+		if (info->icount.rxcrc)
+			ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+	} else {
+		ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+			       info->icount.tx, info->icount.rx);
+		if (info->icount.frame)
+			ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+		if (info->icount.parity)
+			ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+		if (info->icount.brk)
+			ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+		if (info->icount.overrun)
+			ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+	}
+
+	/* Append serial signal status to end */
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+
+	ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+		       info->tx_active,info->bh_requested,info->bh_running,
+		       info->pending_bh);
+
+	return ret;
+}
+
+/* Called to print information about devices
+ */
+static int read_proc(char *page, char **start, off_t off, int count,
+		     int *eof, void *data)
+{
+	int len = 0, l;
+	off_t	begin = 0;
+	struct slgt_info *info;
+
+	len += sprintf(page, "synclink_gt driver:%s\n", driver_version);
+
+	info = slgt_device_list;
+	while( info ) {
+		l = line_info(page + len, info);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+		info = info->next_device;
+	}
+
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * return count of bytes in transmit buffer
+ */
+static int chars_in_buffer(struct tty_struct *tty)
+{
+	struct slgt_info *info = tty->driver_data;
+	if (sanity_check(info, tty->name, "chars_in_buffer"))
+		return 0;
+	DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, info->tx_count));
+	return info->tx_count;
+}
+
+/*
+ * signal remote device to throttle send data (our receive data)
+ */
+static void throttle(struct tty_struct * tty)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "throttle"))
+		return;
+	DBGINFO(("%s throttle\n", info->device_name));
+	if (I_IXOFF(tty))
+		send_xchar(tty, STOP_CHAR(tty));
+ 	if (tty->termios->c_cflag & CRTSCTS) {
+		spin_lock_irqsave(&info->lock,flags);
+		info->signals &= ~SerialSignal_RTS;
+	 	set_signals(info);
+		spin_unlock_irqrestore(&info->lock,flags);
+	}
+}
+
+/*
+ * signal remote device to stop throttling send data (our receive data)
+ */
+static void unthrottle(struct tty_struct * tty)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "unthrottle"))
+		return;
+	DBGINFO(("%s unthrottle\n", info->device_name));
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			send_xchar(tty, START_CHAR(tty));
+	}
+ 	if (tty->termios->c_cflag & CRTSCTS) {
+		spin_lock_irqsave(&info->lock,flags);
+		info->signals |= SerialSignal_RTS;
+	 	set_signals(info);
+		spin_unlock_irqrestore(&info->lock,flags);
+	}
+}
+
+/*
+ * set or clear transmit break condition
+ * break_state	-1=set break condition, 0=clear
+ */
+static void set_break(struct tty_struct *tty, int break_state)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned short value;
+	unsigned long flags;
+
+	if (sanity_check(info, tty->name, "set_break"))
+		return;
+	DBGINFO(("%s set_break(%d)\n", info->device_name, break_state));
+
+	spin_lock_irqsave(&info->lock,flags);
+	value = rd_reg16(info, TCR);
+ 	if (break_state == -1)
+		value |= BIT6;
+	else
+		value &= ~BIT6;
+	wr_reg16(info, TCR, value);
+	spin_unlock_irqrestore(&info->lock,flags);
+}
+
+#ifdef CONFIG_HDLC
+
+/**
+ * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
+ * set encoding and frame check sequence (FCS) options
+ *
+ * dev       pointer to network device structure
+ * encoding  serial encoding setting
+ * parity    FCS setting
+ *
+ * returns 0 if success, otherwise error code
+ */
+static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
+			  unsigned short parity)
+{
+	struct slgt_info *info = dev_to_port(dev);
+	unsigned char  new_encoding;
+	unsigned short new_crctype;
+
+	/* return error if TTY interface open */
+	if (info->count)
+		return -EBUSY;
+
+	DBGINFO(("%s hdlcdev_attach\n", info->device_name));
+
+	switch (encoding)
+	{
+	case ENCODING_NRZ:        new_encoding = HDLC_ENCODING_NRZ; break;
+	case ENCODING_NRZI:       new_encoding = HDLC_ENCODING_NRZI_SPACE; break;
+	case ENCODING_FM_MARK:    new_encoding = HDLC_ENCODING_BIPHASE_MARK; break;
+	case ENCODING_FM_SPACE:   new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break;
+	case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break;
+	default: return -EINVAL;
+	}
+
+	switch (parity)
+	{
+	case PARITY_NONE:            new_crctype = HDLC_CRC_NONE; break;
+	case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break;
+	case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break;
+	default: return -EINVAL;
+	}
+
+	info->params.encoding = new_encoding;
+	info->params.crc_type = new_crctype;;
+
+	/* if network interface up, reprogram hardware */
+	if (info->netcount)
+		program_hw(info);
+
+	return 0;
+}
+
+/**
+ * called by generic HDLC layer to send frame
+ *
+ * skb  socket buffer containing HDLC frame
+ * dev  pointer to network device structure
+ *
+ * returns 0 if success, otherwise error code
+ */
+static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct slgt_info *info = dev_to_port(dev);
+	struct net_device_stats *stats = hdlc_stats(dev);
+	unsigned long flags;
+
+	DBGINFO(("%s hdlc_xmit\n", dev->name));
+
+	/* stop sending until this frame completes */
+	netif_stop_queue(dev);
+
+	/* copy data to device buffers */
+	info->tx_count = skb->len;
+	tx_load(info, skb->data, skb->len);
+
+	/* update network statistics */
+	stats->tx_packets++;
+	stats->tx_bytes += skb->len;
+
+	/* done with socket buffer, so free it */
+	dev_kfree_skb(skb);
+
+	/* save start time for transmit timeout detection */
+	dev->trans_start = jiffies;
+
+	/* start hardware transmitter if necessary */
+	spin_lock_irqsave(&info->lock,flags);
+	if (!info->tx_active)
+	 	tx_start(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	return 0;
+}
+
+/**
+ * called by network layer when interface enabled
+ * claim resources and initialize hardware
+ *
+ * dev  pointer to network device structure
+ *
+ * returns 0 if success, otherwise error code
+ */
+static int hdlcdev_open(struct net_device *dev)
+{
+	struct slgt_info *info = dev_to_port(dev);
+	int rc;
+	unsigned long flags;
+
+	DBGINFO(("%s hdlcdev_open\n", dev->name));
+
+	/* generic HDLC layer open processing */
+	if ((rc = hdlc_open(dev)))
+		return rc;
+
+	/* arbitrate between network and tty opens */
+	spin_lock_irqsave(&info->netlock, flags);
+	if (info->count != 0 || info->netcount != 0) {
+		DBGINFO(("%s hdlc_open busy\n", dev->name));
+		spin_unlock_irqrestore(&info->netlock, flags);
+		return -EBUSY;
+	}
+	info->netcount=1;
+	spin_unlock_irqrestore(&info->netlock, flags);
+
+	/* claim resources and init adapter */
+	if ((rc = startup(info)) != 0) {
+		spin_lock_irqsave(&info->netlock, flags);
+		info->netcount=0;
+		spin_unlock_irqrestore(&info->netlock, flags);
+		return rc;
+	}
+
+	/* assert DTR and RTS, apply hardware settings */
+	info->signals |= SerialSignal_RTS + SerialSignal_DTR;
+	program_hw(info);
+
+	/* enable network layer transmit */
+	dev->trans_start = jiffies;
+	netif_start_queue(dev);
+
+	/* inform generic HDLC layer of current DCD status */
+	spin_lock_irqsave(&info->lock, flags);
+	get_signals(info);
+	spin_unlock_irqrestore(&info->lock, flags);
+	hdlc_set_carrier(info->signals & SerialSignal_DCD, dev);
+
+	return 0;
+}
+
+/**
+ * called by network layer when interface is disabled
+ * shutdown hardware and release resources
+ *
+ * dev  pointer to network device structure
+ *
+ * returns 0 if success, otherwise error code
+ */
+static int hdlcdev_close(struct net_device *dev)
+{
+	struct slgt_info *info = dev_to_port(dev);
+	unsigned long flags;
+
+	DBGINFO(("%s hdlcdev_close\n", dev->name));
+
+	netif_stop_queue(dev);
+
+	/* shutdown adapter and release resources */
+	shutdown(info);
+
+	hdlc_close(dev);
+
+	spin_lock_irqsave(&info->netlock, flags);
+	info->netcount=0;
+	spin_unlock_irqrestore(&info->netlock, flags);
+
+	return 0;
+}
+
+/**
+ * called by network layer to process IOCTL call to network device
+ *
+ * dev  pointer to network device structure
+ * ifr  pointer to network interface request structure
+ * cmd  IOCTL command code
+ *
+ * returns 0 if success, otherwise error code
+ */
+static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	const size_t size = sizeof(sync_serial_settings);
+	sync_serial_settings new_line;
+	sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
+	struct slgt_info *info = dev_to_port(dev);
+	unsigned int flags;
+
+	DBGINFO(("%s hdlcdev_ioctl\n", dev->name));
+
+	/* return error if TTY interface open */
+	if (info->count)
+		return -EBUSY;
+
+	if (cmd != SIOCWANDEV)
+		return hdlc_ioctl(dev, ifr, cmd);
+
+	switch(ifr->ifr_settings.type) {
+	case IF_GET_IFACE: /* return current sync_serial_settings */
+
+		ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
+		if (ifr->ifr_settings.size < size) {
+			ifr->ifr_settings.size = size; /* data size wanted */
+			return -ENOBUFS;
+		}
+
+		flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
+					      HDLC_FLAG_RXC_BRG    | HDLC_FLAG_RXC_TXCPIN |
+					      HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
+					      HDLC_FLAG_TXC_BRG    | HDLC_FLAG_TXC_RXCPIN);
+
+		switch (flags){
+		case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break;
+		case (HDLC_FLAG_RXC_BRG    | HDLC_FLAG_TXC_BRG):    new_line.clock_type = CLOCK_INT; break;
+		case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG):    new_line.clock_type = CLOCK_TXINT; break;
+		case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break;
+		default: new_line.clock_type = CLOCK_DEFAULT;
+		}
+
+		new_line.clock_rate = info->params.clock_speed;
+		new_line.loopback   = info->params.loopback ? 1:0;
+
+		if (copy_to_user(line, &new_line, size))
+			return -EFAULT;
+		return 0;
+
+	case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */
+
+		if(!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		if (copy_from_user(&new_line, line, size))
+			return -EFAULT;
+
+		switch (new_line.clock_type)
+		{
+		case CLOCK_EXT:      flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break;
+		case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break;
+		case CLOCK_INT:      flags = HDLC_FLAG_RXC_BRG    | HDLC_FLAG_TXC_BRG;    break;
+		case CLOCK_TXINT:    flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG;    break;
+		case CLOCK_DEFAULT:  flags = info->params.flags &
+					     (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
+					      HDLC_FLAG_RXC_BRG    | HDLC_FLAG_RXC_TXCPIN |
+					      HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
+					      HDLC_FLAG_TXC_BRG    | HDLC_FLAG_TXC_RXCPIN); break;
+		default: return -EINVAL;
+		}
+
+		if (new_line.loopback != 0 && new_line.loopback != 1)
+			return -EINVAL;
+
+		info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
+					HDLC_FLAG_RXC_BRG    | HDLC_FLAG_RXC_TXCPIN |
+					HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
+					HDLC_FLAG_TXC_BRG    | HDLC_FLAG_TXC_RXCPIN);
+		info->params.flags |= flags;
+
+		info->params.loopback = new_line.loopback;
+
+		if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG))
+			info->params.clock_speed = new_line.clock_rate;
+		else
+			info->params.clock_speed = 0;
+
+		/* if network interface up, reprogram hardware */
+		if (info->netcount)
+			program_hw(info);
+		return 0;
+
+	default:
+		return hdlc_ioctl(dev, ifr, cmd);
+	}
+}
+
+/**
+ * called by network layer when transmit timeout is detected
+ *
+ * dev  pointer to network device structure
+ */
+static void hdlcdev_tx_timeout(struct net_device *dev)
+{
+	struct slgt_info *info = dev_to_port(dev);
+	struct net_device_stats *stats = hdlc_stats(dev);
+	unsigned long flags;
+
+	DBGINFO(("%s hdlcdev_tx_timeout\n", dev->name));
+
+	stats->tx_errors++;
+	stats->tx_aborted_errors++;
+
+	spin_lock_irqsave(&info->lock,flags);
+	tx_stop(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	netif_wake_queue(dev);
+}
+
+/**
+ * called by device driver when transmit completes
+ * reenable network layer transmit if stopped
+ *
+ * info  pointer to device instance information
+ */
+static void hdlcdev_tx_done(struct slgt_info *info)
+{
+	if (netif_queue_stopped(info->netdev))
+		netif_wake_queue(info->netdev);
+}
+
+/**
+ * called by device driver when frame received
+ * pass frame to network layer
+ *
+ * info  pointer to device instance information
+ * buf   pointer to buffer contianing frame data
+ * size  count of data bytes in buf
+ */
+static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
+{
+	struct sk_buff *skb = dev_alloc_skb(size);
+	struct net_device *dev = info->netdev;
+	struct net_device_stats *stats = hdlc_stats(dev);
+
+	DBGINFO(("%s hdlcdev_rx\n", dev->name));
+
+	if (skb == NULL) {
+		DBGERR(("%s: can't alloc skb, drop packet\n", dev->name));
+		stats->rx_dropped++;
+		return;
+	}
+
+	memcpy(skb_put(skb, size),buf,size);
+
+	skb->protocol = hdlc_type_trans(skb, info->netdev);
+
+	stats->rx_packets++;
+	stats->rx_bytes += size;
+
+	netif_rx(skb);
+
+	info->netdev->last_rx = jiffies;
+}
+
+/**
+ * called by device driver when adding device instance
+ * do generic HDLC initialization
+ *
+ * info  pointer to device instance information
+ *
+ * returns 0 if success, otherwise error code
+ */
+static int hdlcdev_init(struct slgt_info *info)
+{
+	int rc;
+	struct net_device *dev;
+	hdlc_device *hdlc;
+
+	/* allocate and initialize network and HDLC layer objects */
+
+	if (!(dev = alloc_hdlcdev(info))) {
+		printk(KERN_ERR "%s hdlc device alloc failure\n", info->device_name);
+		return -ENOMEM;
+	}
+
+	/* for network layer reporting purposes only */
+	dev->mem_start = info->phys_reg_addr;
+	dev->mem_end   = info->phys_reg_addr + SLGT_REG_SIZE - 1;
+	dev->irq       = info->irq_level;
+
+	/* network layer callbacks and settings */
+	dev->do_ioctl       = hdlcdev_ioctl;
+	dev->open           = hdlcdev_open;
+	dev->stop           = hdlcdev_close;
+	dev->tx_timeout     = hdlcdev_tx_timeout;
+	dev->watchdog_timeo = 10*HZ;
+	dev->tx_queue_len   = 50;
+
+	/* generic HDLC layer callbacks and settings */
+	hdlc         = dev_to_hdlc(dev);
+	hdlc->attach = hdlcdev_attach;
+	hdlc->xmit   = hdlcdev_xmit;
+
+	/* register objects with HDLC layer */
+	if ((rc = register_hdlc_device(dev))) {
+		printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__);
+		free_netdev(dev);
+		return rc;
+	}
+
+	info->netdev = dev;
+	return 0;
+}
+
+/**
+ * called by device driver when removing device instance
+ * do generic HDLC cleanup
+ *
+ * info  pointer to device instance information
+ */
+static void hdlcdev_exit(struct slgt_info *info)
+{
+	unregister_hdlc_device(info->netdev);
+	free_netdev(info->netdev);
+	info->netdev = NULL;
+}
+
+#endif /* ifdef CONFIG_HDLC */
+
+/*
+ * get async data from rx DMA buffers
+ */
+static void rx_async(struct slgt_info *info)
+{
+ 	struct tty_struct *tty = info->tty;
+ 	struct mgsl_icount *icount = &info->icount;
+	unsigned int start, end;
+	unsigned char *p;
+	unsigned char status;
+	struct slgt_desc *bufs = info->rbufs;
+	int i, count;
+
+	start = end = info->rbuf_current;
+
+	while(desc_complete(bufs[end])) {
+		count = desc_count(bufs[end]) - info->rbuf_index;
+		p     = bufs[end].buf + info->rbuf_index;
+
+		DBGISR(("%s rx_async count=%d\n", info->device_name, count));
+		DBGDATA(info, p, count, "rx");
+
+		for(i=0 ; i < count; i+=2, p+=2) {
+			if (tty) {
+				if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+					tty_flip_buffer_push(tty);
+				if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+					break;
+				*tty->flip.char_buf_ptr = *p;
+				*tty->flip.flag_buf_ptr = 0;
+			}
+			icount->rx++;
+
+			if ((status = *(p+1) & (BIT9 + BIT8))) {
+				if (status & BIT9)
+					icount->parity++;
+				else if (status & BIT8)
+					icount->frame++;
+				/* discard char if tty control flags say so */
+				if (status & info->ignore_status_mask)
+					continue;
+				if (tty) {
+					if (status & BIT9)
+						*tty->flip.flag_buf_ptr = TTY_PARITY;
+					else if (status & BIT8)
+						*tty->flip.flag_buf_ptr = TTY_FRAME;
+				}
+			}
+			if (tty) {
+				tty->flip.flag_buf_ptr++;
+				tty->flip.char_buf_ptr++;
+				tty->flip.count++;
+			}
+		}
+
+		if (i < count) {
+			/* receive buffer not completed */
+			info->rbuf_index += i;
+			info->rx_timer.expires = jiffies + 1;
+			add_timer(&info->rx_timer);
+			break;
+		}
+
+		info->rbuf_index = 0;
+		free_rbufs(info, end, end);
+
+		if (++end == info->rbuf_count)
+			end = 0;
+
+		/* if entire list searched then no frame available */
+		if (end == start)
+			break;
+	}
+
+	if (tty && tty->flip.count)
+		tty_flip_buffer_push(tty);
+}
+
+/*
+ * return next bottom half action to perform
+ */
+static int bh_action(struct slgt_info *info)
+{
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(&info->lock,flags);
+
+	if (info->pending_bh & BH_RECEIVE) {
+		info->pending_bh &= ~BH_RECEIVE;
+		rc = BH_RECEIVE;
+	} else if (info->pending_bh & BH_TRANSMIT) {
+		info->pending_bh &= ~BH_TRANSMIT;
+		rc = BH_TRANSMIT;
+	} else if (info->pending_bh & BH_STATUS) {
+		info->pending_bh &= ~BH_STATUS;
+		rc = BH_STATUS;
+	} else {
+		/* Mark BH routine as complete */
+		info->bh_running   = 0;
+		info->bh_requested = 0;
+		rc = 0;
+	}
+
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	return rc;
+}
+
+/*
+ * perform bottom half processing
+ */
+static void bh_handler(void* context)
+{
+	struct slgt_info *info = context;
+	int action;
+
+	if (!info)
+		return;
+	info->bh_running = 1;
+
+	while((action = bh_action(info))) {
+		switch (action) {
+		case BH_RECEIVE:
+			DBGBH(("%s bh receive\n", info->device_name));
+			switch(info->params.mode) {
+			case MGSL_MODE_ASYNC:
+				rx_async(info);
+				break;
+			case MGSL_MODE_HDLC:
+				while(rx_get_frame(info));
+				break;
+			case MGSL_MODE_RAW:
+				while(rx_get_buf(info));
+				break;
+			}
+			/* restart receiver if rx DMA buffers exhausted */
+			if (info->rx_restart)
+				rx_start(info);
+			break;
+		case BH_TRANSMIT:
+			bh_transmit(info);
+			break;
+		case BH_STATUS:
+			DBGBH(("%s bh status\n", info->device_name));
+			info->ri_chkcount = 0;
+			info->dsr_chkcount = 0;
+			info->dcd_chkcount = 0;
+			info->cts_chkcount = 0;
+			break;
+		default:
+			DBGBH(("%s unknown action\n", info->device_name));
+			break;
+		}
+	}
+	DBGBH(("%s bh_handler exit\n", info->device_name));
+}
+
+static void bh_transmit(struct slgt_info *info)
+{
+	struct tty_struct *tty = info->tty;
+
+	DBGBH(("%s bh_transmit\n", info->device_name));
+	if (tty) {
+		tty_wakeup(tty);
+		wake_up_interruptible(&tty->write_wait);
+	}
+}
+
+static void dsr_change(struct slgt_info *info)
+{
+	get_signals(info);
+	DBGISR(("dsr_change %s signals=%04X\n", info->device_name, info->signals));
+	if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
+		slgt_irq_off(info, IRQ_DSR);
+		return;
+	}
+	info->icount.dsr++;
+	if (info->signals & SerialSignal_DSR)
+		info->input_signal_events.dsr_up++;
+	else
+		info->input_signal_events.dsr_down++;
+	wake_up_interruptible(&info->status_event_wait_q);
+	wake_up_interruptible(&info->event_wait_q);
+	info->pending_bh |= BH_STATUS;
+}
+
+static void cts_change(struct slgt_info *info)
+{
+	get_signals(info);
+	DBGISR(("cts_change %s signals=%04X\n", info->device_name, info->signals));
+	if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
+		slgt_irq_off(info, IRQ_CTS);
+		return;
+	}
+	info->icount.cts++;
+	if (info->signals & SerialSignal_CTS)
+		info->input_signal_events.cts_up++;
+	else
+		info->input_signal_events.cts_down++;
+	wake_up_interruptible(&info->status_event_wait_q);
+	wake_up_interruptible(&info->event_wait_q);
+	info->pending_bh |= BH_STATUS;
+
+	if (info->flags & ASYNC_CTS_FLOW) {
+		if (info->tty) {
+			if (info->tty->hw_stopped) {
+				if (info->signals & SerialSignal_CTS) {
+		 			info->tty->hw_stopped = 0;
+					info->pending_bh |= BH_TRANSMIT;
+					return;
+				}
+			} else {
+				if (!(info->signals & SerialSignal_CTS))
+		 			info->tty->hw_stopped = 1;
+			}
+		}
+	}
+}
+
+static void dcd_change(struct slgt_info *info)
+{
+	get_signals(info);
+	DBGISR(("dcd_change %s signals=%04X\n", info->device_name, info->signals));
+	if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
+		slgt_irq_off(info, IRQ_DCD);
+		return;
+	}
+	info->icount.dcd++;
+	if (info->signals & SerialSignal_DCD) {
+		info->input_signal_events.dcd_up++;
+	} else {
+		info->input_signal_events.dcd_down++;
+	}
+#ifdef CONFIG_HDLC
+	if (info->netcount)
+		hdlc_set_carrier(info->signals & SerialSignal_DCD, info->netdev);
+#endif
+	wake_up_interruptible(&info->status_event_wait_q);
+	wake_up_interruptible(&info->event_wait_q);
+	info->pending_bh |= BH_STATUS;
+
+	if (info->flags & ASYNC_CHECK_CD) {
+		if (info->signals & SerialSignal_DCD)
+			wake_up_interruptible(&info->open_wait);
+		else {
+			if (info->tty)
+				tty_hangup(info->tty);
+		}
+	}
+}
+
+static void ri_change(struct slgt_info *info)
+{
+	get_signals(info);
+	DBGISR(("ri_change %s signals=%04X\n", info->device_name, info->signals));
+	if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) {
+		slgt_irq_off(info, IRQ_RI);
+		return;
+	}
+	info->icount.dcd++;
+	if (info->signals & SerialSignal_RI) {
+		info->input_signal_events.ri_up++;
+	} else {
+		info->input_signal_events.ri_down++;
+	}
+	wake_up_interruptible(&info->status_event_wait_q);
+	wake_up_interruptible(&info->event_wait_q);
+	info->pending_bh |= BH_STATUS;
+}
+
+static void isr_serial(struct slgt_info *info)
+{
+	unsigned short status = rd_reg16(info, SSR);
+
+	DBGISR(("%s isr_serial status=%04X\n", info->device_name, status));
+
+	wr_reg16(info, SSR, status); /* clear pending */
+
+	info->irq_occurred = 1;
+
+	if (info->params.mode == MGSL_MODE_ASYNC) {
+		if (status & IRQ_TXIDLE) {
+			if (info->tx_count)
+				isr_txeom(info, status);
+		}
+		if ((status & IRQ_RXBREAK) && (status & RXBREAK)) {
+			info->icount.brk++;
+			/* process break detection if tty control allows */
+			if (info->tty) {
+				if (!(status & info->ignore_status_mask)) {
+					if (info->read_status_mask & MASK_BREAK) {
+						*info->tty->flip.flag_buf_ptr = TTY_BREAK;
+						if (info->flags & ASYNC_SAK)
+							do_SAK(info->tty);
+					}
+				}
+			}
+		}
+	} else {
+		if (status & (IRQ_TXIDLE + IRQ_TXUNDER))
+			isr_txeom(info, status);
+
+		if (status & IRQ_RXIDLE) {
+			if (status & RXIDLE)
+				info->icount.rxidle++;
+			else
+				info->icount.exithunt++;
+			wake_up_interruptible(&info->event_wait_q);
+		}
+
+		if (status & IRQ_RXOVER)
+			rx_start(info);
+	}
+
+	if (status & IRQ_DSR)
+		dsr_change(info);
+	if (status & IRQ_CTS)
+		cts_change(info);
+	if (status & IRQ_DCD)
+		dcd_change(info);
+	if (status & IRQ_RI)
+		ri_change(info);
+}
+
+static void isr_rdma(struct slgt_info *info)
+{
+	unsigned int status = rd_reg32(info, RDCSR);
+
+	DBGISR(("%s isr_rdma status=%08x\n", info->device_name, status));
+
+	/* RDCSR (rx DMA control/status)
+	 *
+	 * 31..07  reserved
+	 * 06      save status byte to DMA buffer
+	 * 05      error
+	 * 04      eol (end of list)
+	 * 03      eob (end of buffer)
+	 * 02      IRQ enable
+	 * 01      reset
+	 * 00      enable
+	 */
+	wr_reg32(info, RDCSR, status);	/* clear pending */
+
+	if (status & (BIT5 + BIT4)) {
+		DBGISR(("%s isr_rdma rx_restart=1\n", info->device_name));
+		info->rx_restart = 1;
+	}
+	info->pending_bh |= BH_RECEIVE;
+}
+
+static void isr_tdma(struct slgt_info *info)
+{
+	unsigned int status = rd_reg32(info, TDCSR);
+
+	DBGISR(("%s isr_tdma status=%08x\n", info->device_name, status));
+
+	/* TDCSR (tx DMA control/status)
+	 *
+	 * 31..06  reserved
+	 * 05      error
+	 * 04      eol (end of list)
+	 * 03      eob (end of buffer)
+	 * 02      IRQ enable
+	 * 01      reset
+	 * 00      enable
+	 */
+	wr_reg32(info, TDCSR, status);	/* clear pending */
+
+	if (status & (BIT5 + BIT4 + BIT3)) {
+		// another transmit buffer has completed
+		// run bottom half to get more send data from user
+		info->pending_bh |= BH_TRANSMIT;
+	}
+}
+
+static void isr_txeom(struct slgt_info *info, unsigned short status)
+{
+	DBGISR(("%s txeom status=%04x\n", info->device_name, status));
+
+	slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER);
+	tdma_reset(info);
+	reset_tbufs(info);
+	if (status & IRQ_TXUNDER) {
+		unsigned short val = rd_reg16(info, TCR);
+		wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */
+		wr_reg16(info, TCR, val); /* clear reset bit */
+	}
+
+	if (info->tx_active) {
+		if (info->params.mode != MGSL_MODE_ASYNC) {
+			if (status & IRQ_TXUNDER)
+				info->icount.txunder++;
+			else if (status & IRQ_TXIDLE)
+				info->icount.txok++;
+		}
+
+		info->tx_active = 0;
+		info->tx_count = 0;
+
+		del_timer(&info->tx_timer);
+
+		if (info->params.mode != MGSL_MODE_ASYNC && info->drop_rts_on_tx_done) {
+			info->signals &= ~SerialSignal_RTS;
+			info->drop_rts_on_tx_done = 0;
+			set_signals(info);
+		}
+
+#ifdef CONFIG_HDLC
+		if (info->netcount)
+			hdlcdev_tx_done(info);
+		else
+#endif
+		{
+			if (info->tty && (info->tty->stopped || info->tty->hw_stopped)) {
+				tx_stop(info);
+				return;
+			}
+			info->pending_bh |= BH_TRANSMIT;
+		}
+	}
+}
+
+/* interrupt service routine
+ *
+ * 	irq	interrupt number
+ * 	dev_id	device ID supplied during interrupt registration
+ * 	regs	interrupted processor context
+ */
+static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct slgt_info *info;
+	unsigned int gsr;
+	unsigned int i;
+
+	DBGISR(("slgt_interrupt irq=%d entry\n", irq));
+
+	info = dev_id;
+	if (!info)
+		return IRQ_NONE;
+
+	spin_lock(&info->lock);
+
+	while((gsr = rd_reg32(info, GSR) & 0xffffff00)) {
+		DBGISR(("%s gsr=%08x\n", info->device_name, gsr));
+		info->irq_occurred = 1;
+		for(i=0; i < info->port_count ; i++) {
+			if (info->port_array[i] == NULL)
+				continue;
+			if (gsr & (BIT8 << i))
+				isr_serial(info->port_array[i]);
+			if (gsr & (BIT16 << (i*2)))
+				isr_rdma(info->port_array[i]);
+			if (gsr & (BIT17 << (i*2)))
+				isr_tdma(info->port_array[i]);
+		}
+	}
+
+	for(i=0; i < info->port_count ; i++) {
+		struct slgt_info *port = info->port_array[i];
+
+		if (port && (port->count || port->netcount) &&
+		    port->pending_bh && !port->bh_running &&
+		    !port->bh_requested) {
+			DBGISR(("%s bh queued\n", port->device_name));
+			schedule_work(&port->task);
+			port->bh_requested = 1;
+		}
+	}
+
+	spin_unlock(&info->lock);
+
+	DBGISR(("slgt_interrupt irq=%d exit\n", irq));
+	return IRQ_HANDLED;
+}
+
+static int startup(struct slgt_info *info)
+{
+	DBGINFO(("%s startup\n", info->device_name));
+
+	if (info->flags & ASYNC_INITIALIZED)
+		return 0;
+
+	if (!info->tx_buf) {
+		info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL);
+		if (!info->tx_buf) {
+			DBGERR(("%s can't allocate tx buffer\n", info->device_name));
+			return -ENOMEM;
+		}
+	}
+
+	info->pending_bh = 0;
+
+	memset(&info->icount, 0, sizeof(info->icount));
+
+	/* program hardware for current parameters */
+	change_params(info);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags |= ASYNC_INITIALIZED;
+
+	return 0;
+}
+
+/*
+ *  called by close() and hangup() to shutdown hardware
+ */
+static void shutdown(struct slgt_info *info)
+{
+	unsigned long flags;
+
+	if (!(info->flags & ASYNC_INITIALIZED))
+		return;
+
+	DBGINFO(("%s shutdown\n", info->device_name));
+
+	/* clear status wait queue because status changes */
+	/* can't happen after shutting down the hardware */
+	wake_up_interruptible(&info->status_event_wait_q);
+	wake_up_interruptible(&info->event_wait_q);
+
+	del_timer_sync(&info->tx_timer);
+	del_timer_sync(&info->rx_timer);
+
+	kfree(info->tx_buf);
+	info->tx_buf = NULL;
+
+	spin_lock_irqsave(&info->lock,flags);
+
+	tx_stop(info);
+	rx_stop(info);
+
+	slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
+
+ 	if (!info->tty || info->tty->termios->c_cflag & HUPCL) {
+ 		info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
+		set_signals(info);
+	}
+
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	if (info->tty)
+		set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+}
+
+static void program_hw(struct slgt_info *info)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&info->lock,flags);
+
+	rx_stop(info);
+	tx_stop(info);
+
+	if (info->params.mode == MGSL_MODE_HDLC ||
+	    info->params.mode == MGSL_MODE_RAW ||
+	    info->netcount)
+		hdlc_mode(info);
+	else
+		async_mode(info);
+
+	set_signals(info);
+
+	info->dcd_chkcount = 0;
+	info->cts_chkcount = 0;
+	info->ri_chkcount = 0;
+	info->dsr_chkcount = 0;
+
+	slgt_irq_on(info, IRQ_DCD | IRQ_CTS | IRQ_DSR);
+	get_signals(info);
+
+	if (info->netcount ||
+	    (info->tty && info->tty->termios->c_cflag & CREAD))
+		rx_start(info);
+
+	spin_unlock_irqrestore(&info->lock,flags);
+}
+
+/*
+ * reconfigure adapter based on new parameters
+ */
+static void change_params(struct slgt_info *info)
+{
+	unsigned cflag;
+	int bits_per_char;
+
+	if (!info->tty || !info->tty->termios)
+		return;
+	DBGINFO(("%s change_params\n", info->device_name));
+
+	cflag = info->tty->termios->c_cflag;
+
+	/* if B0 rate (hangup) specified then negate DTR and RTS */
+	/* otherwise assert DTR and RTS */
+ 	if (cflag & CBAUD)
+		info->signals |= SerialSignal_RTS + SerialSignal_DTR;
+	else
+		info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
+
+	/* byte size and parity */
+
+	switch (cflag & CSIZE) {
+	case CS5: info->params.data_bits = 5; break;
+	case CS6: info->params.data_bits = 6; break;
+	case CS7: info->params.data_bits = 7; break;
+	case CS8: info->params.data_bits = 8; break;
+	default:  info->params.data_bits = 7; break;
+	}
+
+	info->params.stop_bits = (cflag & CSTOPB) ? 2 : 1;
+
+	if (cflag & PARENB)
+		info->params.parity = (cflag & PARODD) ? ASYNC_PARITY_ODD : ASYNC_PARITY_EVEN;
+	else
+		info->params.parity = ASYNC_PARITY_NONE;
+
+	/* calculate number of jiffies to transmit a full
+	 * FIFO (32 bytes) at specified data rate
+	 */
+	bits_per_char = info->params.data_bits +
+			info->params.stop_bits + 1;
+
+	info->params.data_rate = tty_get_baud_rate(info->tty);
+
+	if (info->params.data_rate) {
+		info->timeout = (32*HZ*bits_per_char) /
+				info->params.data_rate;
+	}
+	info->timeout += HZ/50;		/* Add .02 seconds of slop */
+
+	if (cflag & CRTSCTS)
+		info->flags |= ASYNC_CTS_FLOW;
+	else
+		info->flags &= ~ASYNC_CTS_FLOW;
+
+	if (cflag & CLOCAL)
+		info->flags &= ~ASYNC_CHECK_CD;
+	else
+		info->flags |= ASYNC_CHECK_CD;
+
+	/* process tty input control flags */
+
+	info->read_status_mask = IRQ_RXOVER;
+	if (I_INPCK(info->tty))
+		info->read_status_mask |= MASK_PARITY | MASK_FRAMING;
+ 	if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
+ 		info->read_status_mask |= MASK_BREAK;
+	if (I_IGNPAR(info->tty))
+		info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING;
+	if (I_IGNBRK(info->tty)) {
+		info->ignore_status_mask |= MASK_BREAK;
+		/* If ignoring parity and break indicators, ignore
+		 * overruns too.  (For real raw support).
+		 */
+		if (I_IGNPAR(info->tty))
+			info->ignore_status_mask |= MASK_OVERRUN;
+	}
+
+	program_hw(info);
+}
+
+static int get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount)
+{
+	DBGINFO(("%s get_stats\n",  info->device_name));
+	if (!user_icount) {
+		memset(&info->icount, 0, sizeof(info->icount));
+	} else {
+		if (copy_to_user(user_icount, &info->icount, sizeof(struct mgsl_icount)))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+static int get_params(struct slgt_info *info, MGSL_PARAMS __user *user_params)
+{
+	DBGINFO(("%s get_params\n", info->device_name));
+	if (copy_to_user(user_params, &info->params, sizeof(MGSL_PARAMS)))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params)
+{
+ 	unsigned long flags;
+	MGSL_PARAMS tmp_params;
+
+	DBGINFO(("%s set_params\n", info->device_name));
+	if (copy_from_user(&tmp_params, new_params, sizeof(MGSL_PARAMS)))
+		return -EFAULT;
+
+	spin_lock_irqsave(&info->lock, flags);
+	memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
+	spin_unlock_irqrestore(&info->lock, flags);
+
+ 	change_params(info);
+
+	return 0;
+}
+
+static int get_txidle(struct slgt_info *info, int __user *idle_mode)
+{
+	DBGINFO(("%s get_txidle=%d\n", info->device_name, info->idle_mode));
+	if (put_user(info->idle_mode, idle_mode))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_txidle(struct slgt_info *info, int idle_mode)
+{
+ 	unsigned long flags;
+	DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode));
+	spin_lock_irqsave(&info->lock,flags);
+	info->idle_mode = idle_mode;
+	tx_set_idle(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+	return 0;
+}
+
+static int tx_enable(struct slgt_info *info, int enable)
+{
+ 	unsigned long flags;
+	DBGINFO(("%s tx_enable(%d)\n", info->device_name, enable));
+	spin_lock_irqsave(&info->lock,flags);
+	if (enable) {
+		if (!info->tx_enabled)
+			tx_start(info);
+	} else {
+		if (info->tx_enabled)
+			tx_stop(info);
+	}
+	spin_unlock_irqrestore(&info->lock,flags);
+	return 0;
+}
+
+/*
+ * abort transmit HDLC frame
+ */
+static int tx_abort(struct slgt_info *info)
+{
+ 	unsigned long flags;
+	DBGINFO(("%s tx_abort\n", info->device_name));
+	spin_lock_irqsave(&info->lock,flags);
+	tdma_reset(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+	return 0;
+}
+
+static int rx_enable(struct slgt_info *info, int enable)
+{
+ 	unsigned long flags;
+	DBGINFO(("%s rx_enable(%d)\n", info->device_name, enable));
+	spin_lock_irqsave(&info->lock,flags);
+	if (enable) {
+		if (!info->rx_enabled)
+			rx_start(info);
+	} else {
+		if (info->rx_enabled)
+			rx_stop(info);
+	}
+	spin_unlock_irqrestore(&info->lock,flags);
+	return 0;
+}
+
+/*
+ *  wait for specified event to occur
+ */
+static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr)
+{
+ 	unsigned long flags;
+	int s;
+	int rc=0;
+	struct mgsl_icount cprev, cnow;
+	int events;
+	int mask;
+	struct	_input_signal_events oldsigs, newsigs;
+	DECLARE_WAITQUEUE(wait, current);
+
+	if (get_user(mask, mask_ptr))
+		return -EFAULT;
+
+	DBGINFO(("%s wait_mgsl_event(%d)\n", info->device_name, mask));
+
+	spin_lock_irqsave(&info->lock,flags);
+
+	/* return immediately if state matches requested events */
+	get_signals(info);
+	s = info->signals;
+
+	events = mask &
+		( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
+ 		  ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) +
+		  ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) +
+		  ((s & SerialSignal_RI)  ? MgslEvent_RiActive :MgslEvent_RiInactive) );
+	if (events) {
+		spin_unlock_irqrestore(&info->lock,flags);
+		goto exit;
+	}
+
+	/* save current irq counts */
+	cprev = info->icount;
+	oldsigs = info->input_signal_events;
+
+	/* enable hunt and idle irqs if needed */
+	if (mask & (MgslEvent_ExitHuntMode+MgslEvent_IdleReceived)) {
+		unsigned short val = rd_reg16(info, SCR);
+		if (!(val & IRQ_RXIDLE))
+			wr_reg16(info, SCR, (unsigned short)(val | IRQ_RXIDLE));
+	}
+
+	set_current_state(TASK_INTERRUPTIBLE);
+	add_wait_queue(&info->event_wait_q, &wait);
+
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	for(;;) {
+		schedule();
+		if (signal_pending(current)) {
+			rc = -ERESTARTSYS;
+			break;
+		}
+
+		/* get current irq counts */
+		spin_lock_irqsave(&info->lock,flags);
+		cnow = info->icount;
+		newsigs = info->input_signal_events;
+		set_current_state(TASK_INTERRUPTIBLE);
+		spin_unlock_irqrestore(&info->lock,flags);
+
+		/* if no change, wait aborted for some reason */
+		if (newsigs.dsr_up   == oldsigs.dsr_up   &&
+		    newsigs.dsr_down == oldsigs.dsr_down &&
+		    newsigs.dcd_up   == oldsigs.dcd_up   &&
+		    newsigs.dcd_down == oldsigs.dcd_down &&
+		    newsigs.cts_up   == oldsigs.cts_up   &&
+		    newsigs.cts_down == oldsigs.cts_down &&
+		    newsigs.ri_up    == oldsigs.ri_up    &&
+		    newsigs.ri_down  == oldsigs.ri_down  &&
+		    cnow.exithunt    == cprev.exithunt   &&
+		    cnow.rxidle      == cprev.rxidle) {
+			rc = -EIO;
+			break;
+		}
+
+		events = mask &
+			( (newsigs.dsr_up   != oldsigs.dsr_up   ? MgslEvent_DsrActive:0)   +
+			  (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) +
+			  (newsigs.dcd_up   != oldsigs.dcd_up   ? MgslEvent_DcdActive:0)   +
+			  (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) +
+			  (newsigs.cts_up   != oldsigs.cts_up   ? MgslEvent_CtsActive:0)   +
+			  (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) +
+			  (newsigs.ri_up    != oldsigs.ri_up    ? MgslEvent_RiActive:0)    +
+			  (newsigs.ri_down  != oldsigs.ri_down  ? MgslEvent_RiInactive:0)  +
+			  (cnow.exithunt    != cprev.exithunt   ? MgslEvent_ExitHuntMode:0) +
+			  (cnow.rxidle      != cprev.rxidle     ? MgslEvent_IdleReceived:0) );
+		if (events)
+			break;
+
+		cprev = cnow;
+		oldsigs = newsigs;
+	}
+
+	remove_wait_queue(&info->event_wait_q, &wait);
+	set_current_state(TASK_RUNNING);
+
+
+	if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) {
+		spin_lock_irqsave(&info->lock,flags);
+		if (!waitqueue_active(&info->event_wait_q)) {
+			/* disable enable exit hunt mode/idle rcvd IRQs */
+			wr_reg16(info, SCR,
+				(unsigned short)(rd_reg16(info, SCR) & ~IRQ_RXIDLE));
+		}
+		spin_unlock_irqrestore(&info->lock,flags);
+	}
+exit:
+	if (rc == 0)
+		rc = put_user(events, mask_ptr);
+	return rc;
+}
+
+static int get_interface(struct slgt_info *info, int __user *if_mode)
+{
+	DBGINFO(("%s get_interface=%x\n", info->device_name, info->if_mode));
+	if (put_user(info->if_mode, if_mode))
+		return -EFAULT;
+	return 0;
+}
+
+static int set_interface(struct slgt_info *info, int if_mode)
+{
+ 	unsigned long flags;
+	unsigned char val;
+
+	DBGINFO(("%s set_interface=%x)\n", info->device_name, if_mode));
+	spin_lock_irqsave(&info->lock,flags);
+	info->if_mode = if_mode;
+
+	msc_set_vcr(info);
+
+	/* TCR (tx control) 07  1=RTS driver control */
+	val = rd_reg16(info, TCR);
+	if (info->if_mode & MGSL_INTERFACE_RTS_EN)
+		val |= BIT7;
+	else
+		val &= ~BIT7;
+	wr_reg16(info, TCR, val);
+
+	spin_unlock_irqrestore(&info->lock,flags);
+	return 0;
+}
+
+static int modem_input_wait(struct slgt_info *info,int arg)
+{
+ 	unsigned long flags;
+	int rc;
+	struct mgsl_icount cprev, cnow;
+	DECLARE_WAITQUEUE(wait, current);
+
+	/* save current irq counts */
+	spin_lock_irqsave(&info->lock,flags);
+	cprev = info->icount;
+	add_wait_queue(&info->status_event_wait_q, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	for(;;) {
+		schedule();
+		if (signal_pending(current)) {
+			rc = -ERESTARTSYS;
+			break;
+		}
+
+		/* get new irq counts */
+		spin_lock_irqsave(&info->lock,flags);
+		cnow = info->icount;
+		set_current_state(TASK_INTERRUPTIBLE);
+		spin_unlock_irqrestore(&info->lock,flags);
+
+		/* if no change, wait aborted for some reason */
+		if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+		    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
+			rc = -EIO;
+			break;
+		}
+
+		/* check for change in caller specified modem input */
+		if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) ||
+		    (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) ||
+		    (arg & TIOCM_CD  && cnow.dcd != cprev.dcd) ||
+		    (arg & TIOCM_CTS && cnow.cts != cprev.cts)) {
+			rc = 0;
+			break;
+		}
+
+		cprev = cnow;
+	}
+	remove_wait_queue(&info->status_event_wait_q, &wait);
+	set_current_state(TASK_RUNNING);
+	return rc;
+}
+
+/*
+ *  return state of serial control and status signals
+ */
+static int tiocmget(struct tty_struct *tty, struct file *file)
+{
+	struct slgt_info *info = tty->driver_data;
+	unsigned int result;
+ 	unsigned long flags;
+
+	spin_lock_irqsave(&info->lock,flags);
+ 	get_signals(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	result = ((info->signals & SerialSignal_RTS) ? TIOCM_RTS:0) +
+		((info->signals & SerialSignal_DTR) ? TIOCM_DTR:0) +
+		((info->signals & SerialSignal_DCD) ? TIOCM_CAR:0) +
+		((info->signals & SerialSignal_RI)  ? TIOCM_RNG:0) +
+		((info->signals & SerialSignal_DSR) ? TIOCM_DSR:0) +
+		((info->signals & SerialSignal_CTS) ? TIOCM_CTS:0);
+
+	DBGINFO(("%s tiocmget value=%08X\n", info->device_name, result));
+	return result;
+}
+
+/*
+ * set modem control signals (DTR/RTS)
+ *
+ * 	cmd	signal command: TIOCMBIS = set bit TIOCMBIC = clear bit
+ *		TIOCMSET = set/clear signal values
+ * 	value	bit mask for command
+ */
+static int tiocmset(struct tty_struct *tty, struct file *file,
+		    unsigned int set, unsigned int clear)
+{
+	struct slgt_info *info = tty->driver_data;
+ 	unsigned long flags;
+
+	DBGINFO(("%s tiocmset(%x,%x)\n", info->device_name, set, clear));
+
+	if (set & TIOCM_RTS)
+		info->signals |= SerialSignal_RTS;
+	if (set & TIOCM_DTR)
+		info->signals |= SerialSignal_DTR;
+	if (clear & TIOCM_RTS)
+		info->signals &= ~SerialSignal_RTS;
+	if (clear & TIOCM_DTR)
+		info->signals &= ~SerialSignal_DTR;
+
+	spin_lock_irqsave(&info->lock,flags);
+ 	set_signals(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+	return 0;
+}
+
+/*
+ *  block current process until the device is ready to open
+ */
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
+			   struct slgt_info *info)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int		retval;
+	int		do_clocal = 0, extra_count = 0;
+	unsigned long	flags;
+
+	DBGINFO(("%s block_til_ready\n", tty->driver->name));
+
+	if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
+		/* nonblock mode is set or port is not enabled */
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+		return 0;
+	}
+
+	if (tty->termios->c_cflag & CLOCAL)
+		do_clocal = 1;
+
+	/* Wait for carrier detect and the line to become
+	 * free (i.e., not in use by the callout).  While we are in
+	 * this loop, info->count is dropped by one, so that
+	 * close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+
+	retval = 0;
+	add_wait_queue(&info->open_wait, &wait);
+
+	spin_lock_irqsave(&info->lock, flags);
+	if (!tty_hung_up_p(filp)) {
+		extra_count = 1;
+		info->count--;
+	}
+	spin_unlock_irqrestore(&info->lock, flags);
+	info->blocked_open++;
+
+	while (1) {
+		if ((tty->termios->c_cflag & CBAUD)) {
+			spin_lock_irqsave(&info->lock,flags);
+			info->signals |= SerialSignal_RTS + SerialSignal_DTR;
+		 	set_signals(info);
+			spin_unlock_irqrestore(&info->lock,flags);
+		}
+
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){
+			retval = (info->flags & ASYNC_HUP_NOTIFY) ?
+					-EAGAIN : -ERESTARTSYS;
+			break;
+		}
+
+		spin_lock_irqsave(&info->lock,flags);
+	 	get_signals(info);
+		spin_unlock_irqrestore(&info->lock,flags);
+
+ 		if (!(info->flags & ASYNC_CLOSING) &&
+ 		    (do_clocal || (info->signals & SerialSignal_DCD)) ) {
+ 			break;
+		}
+
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+
+		DBGINFO(("%s block_til_ready wait\n", tty->driver->name));
+		schedule();
+	}
+
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&info->open_wait, &wait);
+
+	if (extra_count)
+		info->count++;
+	info->blocked_open--;
+
+	if (!retval)
+		info->flags |= ASYNC_NORMAL_ACTIVE;
+
+	DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval));
+	return retval;
+}
+
+static int alloc_tmp_rbuf(struct slgt_info *info)
+{
+	info->tmp_rbuf = kmalloc(info->max_frame_size, GFP_KERNEL);
+	if (info->tmp_rbuf == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+static void free_tmp_rbuf(struct slgt_info *info)
+{
+	kfree(info->tmp_rbuf);
+	info->tmp_rbuf = NULL;
+}
+
+/*
+ * allocate DMA descriptor lists.
+ */
+static int alloc_desc(struct slgt_info *info)
+{
+	unsigned int i;
+	unsigned int pbufs;
+
+	/* allocate memory to hold descriptor lists */
+	info->bufs = pci_alloc_consistent(info->pdev, DESC_LIST_SIZE, &info->bufs_dma_addr);
+	if (info->bufs == NULL)
+		return -ENOMEM;
+
+	memset(info->bufs, 0, DESC_LIST_SIZE);
+
+	info->rbufs = (struct slgt_desc*)info->bufs;
+	info->tbufs = ((struct slgt_desc*)info->bufs) + info->rbuf_count;
+
+	pbufs = (unsigned int)info->bufs_dma_addr;
+
+	/*
+	 * Build circular lists of descriptors
+	 */
+
+	for (i=0; i < info->rbuf_count; i++) {
+		/* physical address of this descriptor */
+		info->rbufs[i].pdesc = pbufs + (i * sizeof(struct slgt_desc));
+
+		/* physical address of next descriptor */
+		if (i == info->rbuf_count - 1)
+			info->rbufs[i].next = cpu_to_le32(pbufs);
+		else
+			info->rbufs[i].next = cpu_to_le32(pbufs + ((i+1) * sizeof(struct slgt_desc)));
+		set_desc_count(info->rbufs[i], DMABUFSIZE);
+	}
+
+	for (i=0; i < info->tbuf_count; i++) {
+		/* physical address of this descriptor */
+		info->tbufs[i].pdesc = pbufs + ((info->rbuf_count + i) * sizeof(struct slgt_desc));
+
+		/* physical address of next descriptor */
+		if (i == info->tbuf_count - 1)
+			info->tbufs[i].next = cpu_to_le32(pbufs + info->rbuf_count * sizeof(struct slgt_desc));
+		else
+			info->tbufs[i].next = cpu_to_le32(pbufs + ((info->rbuf_count + i + 1) * sizeof(struct slgt_desc)));
+	}
+
+	return 0;
+}
+
+static void free_desc(struct slgt_info *info)
+{
+	if (info->bufs != NULL) {
+		pci_free_consistent(info->pdev, DESC_LIST_SIZE, info->bufs, info->bufs_dma_addr);
+		info->bufs  = NULL;
+		info->rbufs = NULL;
+		info->tbufs = NULL;
+	}
+}
+
+static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count)
+{
+	int i;
+	for (i=0; i < count; i++) {
+		if ((bufs[i].buf = pci_alloc_consistent(info->pdev, DMABUFSIZE, &bufs[i].buf_dma_addr)) == NULL)
+			return -ENOMEM;
+		bufs[i].pbuf  = cpu_to_le32((unsigned int)bufs[i].buf_dma_addr);
+	}
+	return 0;
+}
+
+static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count)
+{
+	int i;
+	for (i=0; i < count; i++) {
+		if (bufs[i].buf == NULL)
+			continue;
+		pci_free_consistent(info->pdev, DMABUFSIZE, bufs[i].buf, bufs[i].buf_dma_addr);
+		bufs[i].buf = NULL;
+	}
+}
+
+static int alloc_dma_bufs(struct slgt_info *info)
+{
+	info->rbuf_count = 32;
+	info->tbuf_count = 32;
+
+	if (alloc_desc(info) < 0 ||
+	    alloc_bufs(info, info->rbufs, info->rbuf_count) < 0 ||
+	    alloc_bufs(info, info->tbufs, info->tbuf_count) < 0 ||
+	    alloc_tmp_rbuf(info) < 0) {
+		DBGERR(("%s DMA buffer alloc fail\n", info->device_name));
+		return -ENOMEM;
+	}
+	reset_rbufs(info);
+	return 0;
+}
+
+static void free_dma_bufs(struct slgt_info *info)
+{
+	if (info->bufs) {
+		free_bufs(info, info->rbufs, info->rbuf_count);
+		free_bufs(info, info->tbufs, info->tbuf_count);
+		free_desc(info);
+	}
+	free_tmp_rbuf(info);
+}
+
+static int claim_resources(struct slgt_info *info)
+{
+	if (request_mem_region(info->phys_reg_addr, SLGT_REG_SIZE, "synclink_gt") == NULL) {
+		DBGERR(("%s reg addr conflict, addr=%08X\n",
+			info->device_name, info->phys_reg_addr));
+		info->init_error = DiagStatus_AddressConflict;
+		goto errout;
+	}
+	else
+		info->reg_addr_requested = 1;
+
+	info->reg_addr = ioremap(info->phys_reg_addr, PAGE_SIZE);
+	if (!info->reg_addr) {
+		DBGERR(("%s cant map device registers, addr=%08X\n",
+			info->device_name, info->phys_reg_addr));
+		info->init_error = DiagStatus_CantAssignPciResources;
+		goto errout;
+	}
+	info->reg_addr += info->reg_offset;
+	return 0;
+
+errout:
+	release_resources(info);
+	return -ENODEV;
+}
+
+static void release_resources(struct slgt_info *info)
+{
+	if (info->irq_requested) {
+		free_irq(info->irq_level, info);
+		info->irq_requested = 0;
+	}
+
+	if (info->reg_addr_requested) {
+		release_mem_region(info->phys_reg_addr, SLGT_REG_SIZE);
+		info->reg_addr_requested = 0;
+	}
+
+	if (info->reg_addr) {
+		iounmap(info->reg_addr - info->reg_offset);
+		info->reg_addr = NULL;
+	}
+}
+
+/* Add the specified device instance data structure to the
+ * global linked list of devices and increment the device count.
+ */
+static void add_device(struct slgt_info *info)
+{
+	char *devstr;
+
+	info->next_device = NULL;
+	info->line = slgt_device_count;
+	sprintf(info->device_name, "%s%d", tty_dev_prefix, info->line);
+
+	if (info->line < MAX_DEVICES) {
+		if (maxframe[info->line])
+			info->max_frame_size = maxframe[info->line];
+		info->dosyncppp = dosyncppp[info->line];
+	}
+
+	slgt_device_count++;
+
+	if (!slgt_device_list)
+		slgt_device_list = info;
+	else {
+		struct slgt_info *current_dev = slgt_device_list;
+		while(current_dev->next_device)
+			current_dev = current_dev->next_device;
+		current_dev->next_device = info;
+	}
+
+	if (info->max_frame_size < 4096)
+		info->max_frame_size = 4096;
+	else if (info->max_frame_size > 65535)
+		info->max_frame_size = 65535;
+
+	switch(info->pdev->device) {
+	case SYNCLINK_GT_DEVICE_ID:
+		devstr = "GT";
+		break;
+	case SYNCLINK_GT4_DEVICE_ID:
+		devstr = "GT4";
+		break;
+	case SYNCLINK_AC_DEVICE_ID:
+		devstr = "AC";
+		info->params.mode = MGSL_MODE_ASYNC;
+		break;
+	default:
+		devstr = "(unknown model)";
+	}
+	printk("SyncLink %s %s IO=%08x IRQ=%d MaxFrameSize=%u\n",
+		devstr, info->device_name, info->phys_reg_addr,
+		info->irq_level, info->max_frame_size);
+
+#ifdef CONFIG_HDLC
+	hdlcdev_init(info);
+#endif
+}
+
+/*
+ *  allocate device instance structure, return NULL on failure
+ */
+static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
+{
+	struct slgt_info *info;
+
+	info = kmalloc(sizeof(struct slgt_info), GFP_KERNEL);
+
+	if (!info) {
+		DBGERR(("%s device alloc failed adapter=%d port=%d\n",
+			driver_name, adapter_num, port_num));
+	} else {
+		memset(info, 0, sizeof(struct slgt_info));
+		info->magic = MGSL_MAGIC;
+		INIT_WORK(&info->task, bh_handler, info);
+		info->max_frame_size = 4096;
+		info->raw_rx_size = DMABUFSIZE;
+		info->close_delay = 5*HZ/10;
+		info->closing_wait = 30*HZ;
+		init_waitqueue_head(&info->open_wait);
+		init_waitqueue_head(&info->close_wait);
+		init_waitqueue_head(&info->status_event_wait_q);
+		init_waitqueue_head(&info->event_wait_q);
+		spin_lock_init(&info->netlock);
+		memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS));
+		info->idle_mode = HDLC_TXIDLE_FLAGS;
+		info->adapter_num = adapter_num;
+		info->port_num = port_num;
+
+		init_timer(&info->tx_timer);
+		info->tx_timer.data = (unsigned long)info;
+		info->tx_timer.function = tx_timeout;
+
+		init_timer(&info->rx_timer);
+		info->rx_timer.data = (unsigned long)info;
+		info->rx_timer.function = rx_timeout;
+
+		/* Copy configuration info to device instance data */
+		info->pdev = pdev;
+		info->irq_level = pdev->irq;
+		info->phys_reg_addr = pci_resource_start(pdev,0);
+
+		/* veremap works on page boundaries
+		 * map full page starting at the page boundary
+		 */
+		info->reg_offset    = info->phys_reg_addr & (PAGE_SIZE-1);
+		info->phys_reg_addr &= ~(PAGE_SIZE-1);
+
+		info->bus_type = MGSL_BUS_TYPE_PCI;
+		info->irq_flags = SA_SHIRQ;
+
+		info->init_error = -1; /* assume error, set to 0 on successful init */
+	}
+
+	return info;
+}
+
+static void device_init(int adapter_num, struct pci_dev *pdev)
+{
+	struct slgt_info *port_array[SLGT_MAX_PORTS];
+	int i;
+	int port_count = 1;
+
+	if (pdev->device == SYNCLINK_GT4_DEVICE_ID)
+		port_count = 4;
+
+	/* allocate device instances for all ports */
+	for (i=0; i < port_count; ++i) {
+		port_array[i] = alloc_dev(adapter_num, i, pdev);
+		if (port_array[i] == NULL) {
+			for (--i; i >= 0; --i)
+				kfree(port_array[i]);
+			return;
+		}
+	}
+
+	/* give copy of port_array to all ports and add to device list  */
+	for (i=0; i < port_count; ++i) {
+		memcpy(port_array[i]->port_array, port_array, sizeof(port_array));
+		add_device(port_array[i]);
+		port_array[i]->port_count = port_count;
+		spin_lock_init(&port_array[i]->lock);
+	}
+
+	/* Allocate and claim adapter resources */
+	if (!claim_resources(port_array[0])) {
+
+		alloc_dma_bufs(port_array[0]);
+
+		/* copy resource information from first port to others */
+		for (i = 1; i < port_count; ++i) {
+			port_array[i]->lock      = port_array[0]->lock;
+			port_array[i]->irq_level = port_array[0]->irq_level;
+			port_array[i]->reg_addr  = port_array[0]->reg_addr;
+			alloc_dma_bufs(port_array[i]);
+		}
+
+		if (request_irq(port_array[0]->irq_level,
+					slgt_interrupt,
+					port_array[0]->irq_flags,
+					port_array[0]->device_name,
+					port_array[0]) < 0) {
+			DBGERR(("%s request_irq failed IRQ=%d\n",
+				port_array[0]->device_name,
+				port_array[0]->irq_level));
+		} else {
+			port_array[0]->irq_requested = 1;
+			adapter_test(port_array[0]);
+			for (i=1 ; i < port_count ; i++)
+				port_array[i]->init_error = port_array[0]->init_error;
+		}
+	}
+}
+
+static int __devinit init_one(struct pci_dev *dev,
+			      const struct pci_device_id *ent)
+{
+	if (pci_enable_device(dev)) {
+		printk("error enabling pci device %p\n", dev);
+		return -EIO;
+	}
+	pci_set_master(dev);
+	device_init(slgt_device_count, dev);
+	return 0;
+}
+
+static void __devexit remove_one(struct pci_dev *dev)
+{
+}
+
+static struct tty_operations ops = {
+	.open = open,
+	.close = close,
+	.write = write,
+	.put_char = put_char,
+	.flush_chars = flush_chars,
+	.write_room = write_room,
+	.chars_in_buffer = chars_in_buffer,
+	.flush_buffer = flush_buffer,
+	.ioctl = ioctl,
+	.throttle = throttle,
+	.unthrottle = unthrottle,
+	.send_xchar = send_xchar,
+	.break_ctl = set_break,
+	.wait_until_sent = wait_until_sent,
+ 	.read_proc = read_proc,
+	.set_termios = set_termios,
+	.stop = tx_hold,
+	.start = tx_release,
+	.hangup = hangup,
+	.tiocmget = tiocmget,
+	.tiocmset = tiocmset,
+};
+
+static void slgt_cleanup(void)
+{
+	int rc;
+	struct slgt_info *info;
+	struct slgt_info *tmp;
+
+	printk("unload %s %s\n", driver_name, driver_version);
+
+	if (serial_driver) {
+		if ((rc = tty_unregister_driver(serial_driver)))
+			DBGERR(("tty_unregister_driver error=%d\n", rc));
+		put_tty_driver(serial_driver);
+	}
+
+	/* reset devices */
+	info = slgt_device_list;
+	while(info) {
+		reset_port(info);
+		info = info->next_device;
+	}
+
+	/* release devices */
+	info = slgt_device_list;
+	while(info) {
+#ifdef CONFIG_HDLC
+		hdlcdev_exit(info);
+#endif
+		free_dma_bufs(info);
+		free_tmp_rbuf(info);
+		if (info->port_num == 0)
+			release_resources(info);
+		tmp = info;
+		info = info->next_device;
+		kfree(tmp);
+	}
+
+	if (pci_registered)
+		pci_unregister_driver(&pci_driver);
+}
+
+/*
+ *  Driver initialization entry point.
+ */
+static int __init slgt_init(void)
+{
+	int rc;
+
+ 	printk("%s %s\n", driver_name, driver_version);
+
+	slgt_device_count = 0;
+	if ((rc = pci_register_driver(&pci_driver)) < 0) {
+		printk("%s pci_register_driver error=%d\n", driver_name, rc);
+		return rc;
+	}
+	pci_registered = 1;
+
+	if (!slgt_device_list) {
+		printk("%s no devices found\n",driver_name);
+		return -ENODEV;
+	}
+
+	serial_driver = alloc_tty_driver(MAX_DEVICES);
+	if (!serial_driver) {
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	/* Initialize the tty_driver structure */
+
+	serial_driver->owner = THIS_MODULE;
+	serial_driver->driver_name = tty_driver_name;
+	serial_driver->name = tty_dev_prefix;
+	serial_driver->major = ttymajor;
+	serial_driver->minor_start = 64;
+	serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver->subtype = SERIAL_TYPE_NORMAL;
+	serial_driver->init_termios = tty_std_termios;
+	serial_driver->init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver->flags = TTY_DRIVER_REAL_RAW;
+	tty_set_operations(serial_driver, &ops);
+	if ((rc = tty_register_driver(serial_driver)) < 0) {
+		DBGERR(("%s can't register serial driver\n", driver_name));
+		put_tty_driver(serial_driver);
+		serial_driver = NULL;
+		goto error;
+	}
+
+ 	printk("%s %s, tty major#%d\n",
+		driver_name, driver_version,
+		serial_driver->major);
+
+	return 0;
+
+error:
+	slgt_cleanup();
+	return rc;
+}
+
+static void __exit slgt_exit(void)
+{
+	slgt_cleanup();
+}
+
+module_init(slgt_init);
+module_exit(slgt_exit);
+
+/*
+ * register access routines
+ */
+
+#define CALC_REGADDR() \
+	unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \
+	if (addr >= 0x80) \
+		reg_addr += (info->port_num) * 32;
+
+static __u8 rd_reg8(struct slgt_info *info, unsigned int addr)
+{
+	CALC_REGADDR();
+	return readb((void __iomem *)reg_addr);
+}
+
+static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value)
+{
+	CALC_REGADDR();
+	writeb(value, (void __iomem *)reg_addr);
+}
+
+static __u16 rd_reg16(struct slgt_info *info, unsigned int addr)
+{
+	CALC_REGADDR();
+	return readw((void __iomem *)reg_addr);
+}
+
+static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value)
+{
+	CALC_REGADDR();
+	writew(value, (void __iomem *)reg_addr);
+}
+
+static __u32 rd_reg32(struct slgt_info *info, unsigned int addr)
+{
+	CALC_REGADDR();
+	return readl((void __iomem *)reg_addr);
+}
+
+static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value)
+{
+	CALC_REGADDR();
+	writel(value, (void __iomem *)reg_addr);
+}
+
+static void rdma_reset(struct slgt_info *info)
+{
+	unsigned int i;
+
+	/* set reset bit */
+	wr_reg32(info, RDCSR, BIT1);
+
+	/* wait for enable bit cleared */
+	for(i=0 ; i < 1000 ; i++)
+		if (!(rd_reg32(info, RDCSR) & BIT0))
+			break;
+}
+
+static void tdma_reset(struct slgt_info *info)
+{
+	unsigned int i;
+
+	/* set reset bit */
+	wr_reg32(info, TDCSR, BIT1);
+
+	/* wait for enable bit cleared */
+	for(i=0 ; i < 1000 ; i++)
+		if (!(rd_reg32(info, TDCSR) & BIT0))
+			break;
+}
+
+/*
+ * enable internal loopback
+ * TxCLK and RxCLK are generated from BRG
+ * and TxD is looped back to RxD internally.
+ */
+static void enable_loopback(struct slgt_info *info)
+{
+	/* SCR (serial control) BIT2=looopback enable */
+	wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT2));
+
+	if (info->params.mode != MGSL_MODE_ASYNC) {
+		/* CCR (clock control)
+		 * 07..05  tx clock source (010 = BRG)
+		 * 04..02  rx clock source (010 = BRG)
+		 * 01      auxclk enable   (0 = disable)
+		 * 00      BRG enable      (1 = enable)
+		 *
+		 * 0100 1001
+		 */
+		wr_reg8(info, CCR, 0x49);
+
+		/* set speed if available, otherwise use default */
+		if (info->params.clock_speed)
+			set_rate(info, info->params.clock_speed);
+		else
+			set_rate(info, 3686400);
+	}
+}
+
+/*
+ *  set baud rate generator to specified rate
+ */
+static void set_rate(struct slgt_info *info, u32 rate)
+{
+	unsigned int div;
+	static unsigned int osc = 14745600;
+
+	/* div = osc/rate - 1
+	 *
+	 * Round div up if osc/rate is not integer to
+	 * force to next slowest rate.
+	 */
+
+	if (rate) {
+		div = osc/rate;
+		if (!(osc % rate) && div)
+			div--;
+		wr_reg16(info, BDR, (unsigned short)div);
+	}
+}
+
+static void rx_stop(struct slgt_info *info)
+{
+	unsigned short val;
+
+	/* disable and reset receiver */
+	val = rd_reg16(info, RCR) & ~BIT1;          /* clear enable bit */
+	wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */
+	wr_reg16(info, RCR, val);                  /* clear reset bit */
+
+	slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA + IRQ_RXIDLE);
+
+	/* clear pending rx interrupts */
+	wr_reg16(info, SSR, IRQ_RXIDLE + IRQ_RXOVER);
+
+	rdma_reset(info);
+
+	info->rx_enabled = 0;
+	info->rx_restart = 0;
+}
+
+static void rx_start(struct slgt_info *info)
+{
+	unsigned short val;
+
+	slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA);
+
+	/* clear pending rx overrun IRQ */
+	wr_reg16(info, SSR, IRQ_RXOVER);
+
+	/* reset and disable receiver */
+	val = rd_reg16(info, RCR) & ~BIT1; /* clear enable bit */
+	wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */
+	wr_reg16(info, RCR, val);                  /* clear reset bit */
+
+	rdma_reset(info);
+	reset_rbufs(info);
+
+	/* set 1st descriptor address */
+	wr_reg32(info, RDDAR, info->rbufs[0].pdesc);
+
+	if (info->params.mode != MGSL_MODE_ASYNC) {
+		/* enable rx DMA and DMA interrupt */
+		wr_reg32(info, RDCSR, (BIT2 + BIT0));
+	} else {
+		/* enable saving of rx status, rx DMA and DMA interrupt */
+		wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0));
+	}
+
+	slgt_irq_on(info, IRQ_RXOVER);
+
+	/* enable receiver */
+	wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | BIT1));
+
+	info->rx_restart = 0;
+	info->rx_enabled = 1;
+}
+
+static void tx_start(struct slgt_info *info)
+{
+	if (!info->tx_enabled) {
+		wr_reg16(info, TCR,
+			(unsigned short)(rd_reg16(info, TCR) | BIT1));
+		info->tx_enabled = TRUE;
+	}
+
+	if (info->tx_count) {
+		info->drop_rts_on_tx_done = 0;
+
+		if (info->params.mode != MGSL_MODE_ASYNC) {
+			if (info->params.flags & HDLC_FLAG_AUTO_RTS) {
+				get_signals(info);
+				if (!(info->signals & SerialSignal_RTS)) {
+					info->signals |= SerialSignal_RTS;
+					set_signals(info);
+					info->drop_rts_on_tx_done = 1;
+				}
+			}
+
+			slgt_irq_off(info, IRQ_TXDATA);
+			slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE);
+			/* clear tx idle and underrun status bits */
+			wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER));
+
+			if (!(rd_reg32(info, TDCSR) & BIT0)) {
+				/* tx DMA stopped, restart tx DMA */
+				tdma_reset(info);
+				/* set 1st descriptor address */
+				wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
+				if (info->params.mode == MGSL_MODE_RAW)
+					wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */
+				else
+					wr_reg32(info, TDCSR, BIT0); /* DMA enable */
+			}
+
+			if (info->params.mode != MGSL_MODE_RAW) {
+				info->tx_timer.expires = jiffies + msecs_to_jiffies(5000);
+				add_timer(&info->tx_timer);
+			}
+		} else {
+			tdma_reset(info);
+			/* set 1st descriptor address */
+			wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc);
+
+			slgt_irq_off(info, IRQ_TXDATA);
+			slgt_irq_on(info, IRQ_TXIDLE);
+			/* clear tx idle status bit */
+			wr_reg16(info, SSR, IRQ_TXIDLE);
+
+			/* enable tx DMA */
+			wr_reg32(info, TDCSR, BIT0);
+		}
+
+		info->tx_active = 1;
+	}
+}
+
+static void tx_stop(struct slgt_info *info)
+{
+	unsigned short val;
+
+	del_timer(&info->tx_timer);
+
+	tdma_reset(info);
+
+	/* reset and disable transmitter */
+	val = rd_reg16(info, TCR) & ~BIT1;          /* clear enable bit */
+	wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */
+	wr_reg16(info, TCR, val);                  /* clear reset */
+
+	slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER);
+
+	/* clear tx idle and underrun status bit */
+	wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER));
+
+	reset_tbufs(info);
+
+	info->tx_enabled = 0;
+	info->tx_active  = 0;
+}
+
+static void reset_port(struct slgt_info *info)
+{
+	if (!info->reg_addr)
+		return;
+
+	tx_stop(info);
+	rx_stop(info);
+
+	info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
+	set_signals(info);
+
+	slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
+}
+
+static void reset_adapter(struct slgt_info *info)
+{
+	int i;
+	for (i=0; i < info->port_count; ++i) {
+		if (info->port_array[i])
+			reset_port(info->port_array[i]);
+	}
+}
+
+static void async_mode(struct slgt_info *info)
+{
+  	unsigned short val;
+
+	slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
+	tx_stop(info);
+	rx_stop(info);
+
+	/* TCR (tx control)
+	 *
+	 * 15..13  mode, 010=async
+	 * 12..10  encoding, 000=NRZ
+	 * 09      parity enable
+	 * 08      1=odd parity, 0=even parity
+	 * 07      1=RTS driver control
+	 * 06      1=break enable
+	 * 05..04  character length
+	 *         00=5 bits
+	 *         01=6 bits
+	 *         10=7 bits
+	 *         11=8 bits
+	 * 03      0=1 stop bit, 1=2 stop bits
+	 * 02      reset
+	 * 01      enable
+	 * 00      auto-CTS enable
+	 */
+	val = 0x4000;
+
+	if (info->if_mode & MGSL_INTERFACE_RTS_EN)
+		val |= BIT7;
+
+	if (info->params.parity != ASYNC_PARITY_NONE) {
+		val |= BIT9;
+		if (info->params.parity == ASYNC_PARITY_ODD)
+			val |= BIT8;
+	}
+
+	switch (info->params.data_bits)
+	{
+	case 6: val |= BIT4; break;
+	case 7: val |= BIT5; break;
+	case 8: val |= BIT5 + BIT4; break;
+	}
+
+	if (info->params.stop_bits != 1)
+		val |= BIT3;
+
+	if (info->params.flags & HDLC_FLAG_AUTO_CTS)
+		val |= BIT0;
+
+	wr_reg16(info, TCR, val);
+
+	/* RCR (rx control)
+	 *
+	 * 15..13  mode, 010=async
+	 * 12..10  encoding, 000=NRZ
+	 * 09      parity enable
+	 * 08      1=odd parity, 0=even parity
+	 * 07..06  reserved, must be 0
+	 * 05..04  character length
+	 *         00=5 bits
+	 *         01=6 bits
+	 *         10=7 bits
+	 *         11=8 bits
+	 * 03      reserved, must be zero
+	 * 02      reset
+	 * 01      enable
+	 * 00      auto-DCD enable
+	 */
+	val = 0x4000;
+
+	if (info->params.parity != ASYNC_PARITY_NONE) {
+		val |= BIT9;
+		if (info->params.parity == ASYNC_PARITY_ODD)
+			val |= BIT8;
+	}
+
+	switch (info->params.data_bits)
+	{
+	case 6: val |= BIT4; break;
+	case 7: val |= BIT5; break;
+	case 8: val |= BIT5 + BIT4; break;
+	}
+
+	if (info->params.flags & HDLC_FLAG_AUTO_DCD)
+		val |= BIT0;
+
+	wr_reg16(info, RCR, val);
+
+	/* CCR (clock control)
+	 *
+	 * 07..05  011 = tx clock source is BRG/16
+	 * 04..02  010 = rx clock source is BRG
+	 * 01      0 = auxclk disabled
+	 * 00      1 = BRG enabled
+	 *
+	 * 0110 1001
+	 */
+	wr_reg8(info, CCR, 0x69);
+
+	msc_set_vcr(info);
+
+	tx_set_idle(info);
+
+	/* SCR (serial control)
+	 *
+	 * 15  1=tx req on FIFO half empty
+	 * 14  1=rx req on FIFO half full
+	 * 13  tx data  IRQ enable
+	 * 12  tx idle  IRQ enable
+	 * 11  rx break on IRQ enable
+	 * 10  rx data  IRQ enable
+	 * 09  rx break off IRQ enable
+	 * 08  overrun  IRQ enable
+	 * 07  DSR      IRQ enable
+	 * 06  CTS      IRQ enable
+	 * 05  DCD      IRQ enable
+	 * 04  RI       IRQ enable
+	 * 03  reserved, must be zero
+	 * 02  1=txd->rxd internal loopback enable
+	 * 01  reserved, must be zero
+	 * 00  1=master IRQ enable
+	 */
+	val = BIT15 + BIT14 + BIT0;
+	wr_reg16(info, SCR, val);
+
+	slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER);
+
+	set_rate(info, info->params.data_rate * 16);
+
+	if (info->params.loopback)
+		enable_loopback(info);
+}
+
+static void hdlc_mode(struct slgt_info *info)
+{
+	unsigned short val;
+
+	slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
+	tx_stop(info);
+	rx_stop(info);
+
+	/* TCR (tx control)
+	 *
+	 * 15..13  mode, 000=HDLC 001=raw sync
+	 * 12..10  encoding
+	 * 09      CRC enable
+	 * 08      CRC32
+	 * 07      1=RTS driver control
+	 * 06      preamble enable
+	 * 05..04  preamble length
+	 * 03      share open/close flag
+	 * 02      reset
+	 * 01      enable
+	 * 00      auto-CTS enable
+	 */
+	val = 0;
+
+	if (info->params.mode == MGSL_MODE_RAW)
+		val |= BIT13;
+	if (info->if_mode & MGSL_INTERFACE_RTS_EN)
+		val |= BIT7;
+
+	switch(info->params.encoding)
+	{
+	case HDLC_ENCODING_NRZB:          val |= BIT10; break;
+	case HDLC_ENCODING_NRZI_MARK:     val |= BIT11; break;
+	case HDLC_ENCODING_NRZI:          val |= BIT11 + BIT10; break;
+	case HDLC_ENCODING_BIPHASE_MARK:  val |= BIT12; break;
+	case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break;
+	case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break;
+	case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
+	}
+
+	switch (info->params.crc_type)
+	{
+	case HDLC_CRC_16_CCITT: val |= BIT9; break;
+	case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
+	}
+
+	if (info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE)
+		val |= BIT6;
+
+	switch (info->params.preamble_length)
+	{
+	case HDLC_PREAMBLE_LENGTH_16BITS: val |= BIT5; break;
+	case HDLC_PREAMBLE_LENGTH_32BITS: val |= BIT4; break;
+	case HDLC_PREAMBLE_LENGTH_64BITS: val |= BIT5 + BIT4; break;
+	}
+
+	if (info->params.flags & HDLC_FLAG_AUTO_CTS)
+		val |= BIT0;
+
+	wr_reg16(info, TCR, val);
+
+	/* TPR (transmit preamble) */
+
+	switch (info->params.preamble)
+	{
+	case HDLC_PREAMBLE_PATTERN_FLAGS: val = 0x7e; break;
+	case HDLC_PREAMBLE_PATTERN_ONES:  val = 0xff; break;
+	case HDLC_PREAMBLE_PATTERN_ZEROS: val = 0x00; break;
+	case HDLC_PREAMBLE_PATTERN_10:    val = 0x55; break;
+	case HDLC_PREAMBLE_PATTERN_01:    val = 0xaa; break;
+	default:                          val = 0x7e; break;
+	}
+	wr_reg8(info, TPR, (unsigned char)val);
+
+	/* RCR (rx control)
+	 *
+	 * 15..13  mode, 000=HDLC 001=raw sync
+	 * 12..10  encoding
+	 * 09      CRC enable
+	 * 08      CRC32
+	 * 07..03  reserved, must be 0
+	 * 02      reset
+	 * 01      enable
+	 * 00      auto-DCD enable
+	 */
+	val = 0;
+
+	if (info->params.mode == MGSL_MODE_RAW)
+		val |= BIT13;
+
+	switch(info->params.encoding)
+	{
+	case HDLC_ENCODING_NRZB:          val |= BIT10; break;
+	case HDLC_ENCODING_NRZI_MARK:     val |= BIT11; break;
+	case HDLC_ENCODING_NRZI:          val |= BIT11 + BIT10; break;
+	case HDLC_ENCODING_BIPHASE_MARK:  val |= BIT12; break;
+	case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break;
+	case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break;
+	case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break;
+	}
+
+	switch (info->params.crc_type)
+	{
+	case HDLC_CRC_16_CCITT: val |= BIT9; break;
+	case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break;
+	}
+
+	if (info->params.flags & HDLC_FLAG_AUTO_DCD)
+		val |= BIT0;
+
+	wr_reg16(info, RCR, val);
+
+	/* CCR (clock control)
+	 *
+	 * 07..05  tx clock source
+	 * 04..02  rx clock source
+	 * 01      auxclk enable
+	 * 00      BRG enable
+	 */
+	val = 0;
+
+	if (info->params.flags & HDLC_FLAG_TXC_BRG)
+	{
+		// when RxC source is DPLL, BRG generates 16X DPLL
+		// reference clock, so take TxC from BRG/16 to get
+		// transmit clock at actual data rate
+		if (info->params.flags & HDLC_FLAG_RXC_DPLL)
+			val |= BIT6 + BIT5;	/* 011, txclk = BRG/16 */
+		else
+			val |= BIT6;	/* 010, txclk = BRG */
+	}
+	else if (info->params.flags & HDLC_FLAG_TXC_DPLL)
+		val |= BIT7;	/* 100, txclk = DPLL Input */
+	else if (info->params.flags & HDLC_FLAG_TXC_RXCPIN)
+		val |= BIT5;	/* 001, txclk = RXC Input */
+
+	if (info->params.flags & HDLC_FLAG_RXC_BRG)
+		val |= BIT3;	/* 010, rxclk = BRG */
+	else if (info->params.flags & HDLC_FLAG_RXC_DPLL)
+		val |= BIT4;	/* 100, rxclk = DPLL */
+	else if (info->params.flags & HDLC_FLAG_RXC_TXCPIN)
+		val |= BIT2;	/* 001, rxclk = TXC Input */
+
+	if (info->params.clock_speed)
+		val |= BIT1 + BIT0;
+
+	wr_reg8(info, CCR, (unsigned char)val);
+
+	if (info->params.flags & (HDLC_FLAG_TXC_DPLL + HDLC_FLAG_RXC_DPLL))
+	{
+		// program DPLL mode
+		switch(info->params.encoding)
+		{
+		case HDLC_ENCODING_BIPHASE_MARK:
+		case HDLC_ENCODING_BIPHASE_SPACE:
+			val = BIT7; break;
+		case HDLC_ENCODING_BIPHASE_LEVEL:
+		case HDLC_ENCODING_DIFF_BIPHASE_LEVEL:
+			val = BIT7 + BIT6; break;
+		default: val = BIT6;	// NRZ encodings
+		}
+		wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | val));
+
+		// DPLL requires a 16X reference clock from BRG
+		set_rate(info, info->params.clock_speed * 16);
+	}
+	else
+		set_rate(info, info->params.clock_speed);
+
+	tx_set_idle(info);
+
+	msc_set_vcr(info);
+
+	/* SCR (serial control)
+	 *
+	 * 15  1=tx req on FIFO half empty
+	 * 14  1=rx req on FIFO half full
+	 * 13  tx data  IRQ enable
+	 * 12  tx idle  IRQ enable
+	 * 11  underrun IRQ enable
+	 * 10  rx data  IRQ enable
+	 * 09  rx idle  IRQ enable
+	 * 08  overrun  IRQ enable
+	 * 07  DSR      IRQ enable
+	 * 06  CTS      IRQ enable
+	 * 05  DCD      IRQ enable
+	 * 04  RI       IRQ enable
+	 * 03  reserved, must be zero
+	 * 02  1=txd->rxd internal loopback enable
+	 * 01  reserved, must be zero
+	 * 00  1=master IRQ enable
+	 */
+	wr_reg16(info, SCR, BIT15 + BIT14 + BIT0);
+
+	if (info->params.loopback)
+		enable_loopback(info);
+}
+
+/*
+ *  set transmit idle mode
+ */
+static void tx_set_idle(struct slgt_info *info)
+{
+	unsigned char val = 0xff;
+
+	switch(info->idle_mode)
+	{
+	case HDLC_TXIDLE_FLAGS:          val = 0x7e; break;
+	case HDLC_TXIDLE_ALT_ZEROS_ONES: val = 0xaa; break;
+	case HDLC_TXIDLE_ZEROS:          val = 0x00; break;
+	case HDLC_TXIDLE_ONES:           val = 0xff; break;
+	case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break;
+	case HDLC_TXIDLE_SPACE:          val = 0x00; break;
+	case HDLC_TXIDLE_MARK:           val = 0xff; break;
+	}
+
+	wr_reg8(info, TIR, val);
+}
+
+/*
+ * get state of V24 status (input) signals
+ */
+static void get_signals(struct slgt_info *info)
+{
+	unsigned short status = rd_reg16(info, SSR);
+
+	/* clear all serial signals except DTR and RTS */
+	info->signals &= SerialSignal_DTR + SerialSignal_RTS;
+
+	if (status & BIT3)
+		info->signals |= SerialSignal_DSR;
+	if (status & BIT2)
+		info->signals |= SerialSignal_CTS;
+	if (status & BIT1)
+		info->signals |= SerialSignal_DCD;
+	if (status & BIT0)
+		info->signals |= SerialSignal_RI;
+}
+
+/*
+ * set V.24 Control Register based on current configuration
+ */
+static void msc_set_vcr(struct slgt_info *info)
+{
+	unsigned char val = 0;
+
+	/* VCR (V.24 control)
+	 *
+	 * 07..04  serial IF select
+	 * 03      DTR
+	 * 02      RTS
+	 * 01      LL
+	 * 00      RL
+	 */
+
+	switch(info->if_mode & MGSL_INTERFACE_MASK)
+	{
+	case MGSL_INTERFACE_RS232:
+		val |= BIT5; /* 0010 */
+		break;
+	case MGSL_INTERFACE_V35:
+		val |= BIT7 + BIT6 + BIT5; /* 1110 */
+		break;
+	case MGSL_INTERFACE_RS422:
+		val |= BIT6; /* 0100 */
+		break;
+	}
+
+	if (info->signals & SerialSignal_DTR)
+		val |= BIT3;
+	if (info->signals & SerialSignal_RTS)
+		val |= BIT2;
+	if (info->if_mode & MGSL_INTERFACE_LL)
+		val |= BIT1;
+	if (info->if_mode & MGSL_INTERFACE_RL)
+		val |= BIT0;
+	wr_reg8(info, VCR, val);
+}
+
+/*
+ * set state of V24 control (output) signals
+ */
+static void set_signals(struct slgt_info *info)
+{
+	unsigned char val = rd_reg8(info, VCR);
+	if (info->signals & SerialSignal_DTR)
+		val |= BIT3;
+	else
+		val &= ~BIT3;
+	if (info->signals & SerialSignal_RTS)
+		val |= BIT2;
+	else
+		val &= ~BIT2;
+	wr_reg8(info, VCR, val);
+}
+
+/*
+ * free range of receive DMA buffers (i to last)
+ */
+static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last)
+{
+	int done = 0;
+
+	while(!done) {
+		/* reset current buffer for reuse */
+		info->rbufs[i].status = 0;
+		if (info->params.mode == MGSL_MODE_RAW)
+			set_desc_count(info->rbufs[i], info->raw_rx_size);
+		else
+			set_desc_count(info->rbufs[i], DMABUFSIZE);
+
+		if (i == last)
+			done = 1;
+		if (++i == info->rbuf_count)
+			i = 0;
+	}
+	info->rbuf_current = i;
+}
+
+/*
+ * mark all receive DMA buffers as free
+ */
+static void reset_rbufs(struct slgt_info *info)
+{
+	free_rbufs(info, 0, info->rbuf_count - 1);
+}
+
+/*
+ * pass receive HDLC frame to upper layer
+ *
+ * return 1 if frame available, otherwise 0
+ */
+static int rx_get_frame(struct slgt_info *info)
+{
+	unsigned int start, end;
+	unsigned short status;
+	unsigned int framesize = 0;
+	int rc = 0;
+	unsigned long flags;
+	struct tty_struct *tty = info->tty;
+	unsigned char addr_field = 0xff;
+
+check_again:
+
+	framesize = 0;
+	addr_field = 0xff;
+	start = end = info->rbuf_current;
+
+	for (;;) {
+		if (!desc_complete(info->rbufs[end]))
+			goto cleanup;
+
+		if (framesize == 0 && info->params.addr_filter != 0xff)
+			addr_field = info->rbufs[end].buf[0];
+
+		framesize += desc_count(info->rbufs[end]);
+
+		if (desc_eof(info->rbufs[end]))
+			break;
+
+		if (++end == info->rbuf_count)
+			end = 0;
+
+		if (end == info->rbuf_current) {
+			if (info->rx_enabled){
+				spin_lock_irqsave(&info->lock,flags);
+				rx_start(info);
+				spin_unlock_irqrestore(&info->lock,flags);
+			}
+			goto cleanup;
+		}
+	}
+
+	/* status
+	 *
+	 * 15      buffer complete
+	 * 14..06  reserved
+	 * 05..04  residue
+	 * 02      eof (end of frame)
+	 * 01      CRC error
+	 * 00      abort
+	 */
+	status = desc_status(info->rbufs[end]);
+
+	/* ignore CRC bit if not using CRC (bit is undefined) */
+	if (info->params.crc_type == HDLC_CRC_NONE)
+		status &= ~BIT1;
+
+	if (framesize == 0 ||
+		 (addr_field != 0xff && addr_field != info->params.addr_filter)) {
+		free_rbufs(info, start, end);
+		goto check_again;
+	}
+
+	if (framesize < 2 || status & (BIT1+BIT0)) {
+		if (framesize < 2 || (status & BIT0))
+			info->icount.rxshort++;
+		else
+			info->icount.rxcrc++;
+		framesize = 0;
+
+#ifdef CONFIG_HDLC
+		{
+			struct net_device_stats *stats = hdlc_stats(info->netdev);
+			stats->rx_errors++;
+			stats->rx_frame_errors++;
+		}
+#endif
+	} else {
+		/* adjust frame size for CRC, if any */
+		if (info->params.crc_type == HDLC_CRC_16_CCITT)
+			framesize -= 2;
+		else if (info->params.crc_type == HDLC_CRC_32_CCITT)
+			framesize -= 4;
+	}
+
+	DBGBH(("%s rx frame status=%04X size=%d\n",
+		info->device_name, status, framesize));
+	DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx");
+
+	if (framesize) {
+		if (framesize > info->max_frame_size)
+			info->icount.rxlong++;
+		else {
+			/* copy dma buffer(s) to contiguous temp buffer */
+			int copy_count = framesize;
+			int i = start;
+			unsigned char *p = info->tmp_rbuf;
+			info->tmp_rbuf_count = framesize;
+
+			info->icount.rxok++;
+
+			while(copy_count) {
+				int partial_count = min(copy_count, DMABUFSIZE);
+				memcpy(p, info->rbufs[i].buf, partial_count);
+				p += partial_count;
+				copy_count -= partial_count;
+				if (++i == info->rbuf_count)
+					i = 0;
+			}
+
+#ifdef CONFIG_HDLC
+			if (info->netcount)
+				hdlcdev_rx(info,info->tmp_rbuf, framesize);
+			else
+#endif
+				ldisc_receive_buf(tty, info->tmp_rbuf, info->flag_buf, framesize);
+		}
+	}
+	free_rbufs(info, start, end);
+	rc = 1;
+
+cleanup:
+	return rc;
+}
+
+/*
+ * pass receive buffer (RAW synchronous mode) to tty layer
+ * return 1 if buffer available, otherwise 0
+ */
+static int rx_get_buf(struct slgt_info *info)
+{
+	unsigned int i = info->rbuf_current;
+
+	if (!desc_complete(info->rbufs[i]))
+		return 0;
+	DBGDATA(info, info->rbufs[i].buf, desc_count(info->rbufs[i]), "rx");
+	DBGINFO(("rx_get_buf size=%d\n", desc_count(info->rbufs[i])));
+	ldisc_receive_buf(info->tty, info->rbufs[i].buf,
+			  info->flag_buf, desc_count(info->rbufs[i]));
+	free_rbufs(info, i, i);
+	return 1;
+}
+
+static void reset_tbufs(struct slgt_info *info)
+{
+	unsigned int i;
+	info->tbuf_current = 0;
+	for (i=0 ; i < info->tbuf_count ; i++) {
+		info->tbufs[i].status = 0;
+		info->tbufs[i].count  = 0;
+	}
+}
+
+/*
+ * return number of free transmit DMA buffers
+ */
+static unsigned int free_tbuf_count(struct slgt_info *info)
+{
+	unsigned int count = 0;
+	unsigned int i = info->tbuf_current;
+
+	do
+	{
+		if (desc_count(info->tbufs[i]))
+			break; /* buffer in use */
+		++count;
+		if (++i == info->tbuf_count)
+			i=0;
+	} while (i != info->tbuf_current);
+
+	/* last buffer with zero count may be in use, assume it is */
+	if (count)
+		--count;
+
+	return count;
+}
+
+/*
+ * load transmit DMA buffer(s) with data
+ */
+static void tx_load(struct slgt_info *info, const char *buf, unsigned int size)
+{
+	unsigned short count;
+	unsigned int i;
+	struct slgt_desc *d;
+
+	if (size == 0)
+		return;
+
+	DBGDATA(info, buf, size, "tx");
+
+	info->tbuf_start = i = info->tbuf_current;
+
+	while (size) {
+		d = &info->tbufs[i];
+		if (++i == info->tbuf_count)
+			i = 0;
+
+		count = (unsigned short)((size > DMABUFSIZE) ? DMABUFSIZE : size);
+		memcpy(d->buf, buf, count);
+
+		size -= count;
+		buf  += count;
+
+		if (!size && info->params.mode != MGSL_MODE_RAW)
+			set_desc_eof(*d, 1); /* HDLC: set EOF of last desc */
+		else
+			set_desc_eof(*d, 0);
+
+		set_desc_count(*d, count);
+	}
+
+	info->tbuf_current = i;
+}
+
+static int register_test(struct slgt_info *info)
+{
+	static unsigned short patterns[] =
+		{0x0000, 0xffff, 0xaaaa, 0x5555, 0x6969, 0x9696};
+	static unsigned int count = sizeof(patterns)/sizeof(patterns[0]);
+	unsigned int i;
+	int rc = 0;
+
+	for (i=0 ; i < count ; i++) {
+		wr_reg16(info, TIR, patterns[i]);
+		wr_reg16(info, BDR, patterns[(i+1)%count]);
+		if ((rd_reg16(info, TIR) != patterns[i]) ||
+		    (rd_reg16(info, BDR) != patterns[(i+1)%count])) {
+			rc = -ENODEV;
+			break;
+		}
+	}
+
+	info->init_error = rc ? 0 : DiagStatus_AddressFailure;
+	return rc;
+}
+
+static int irq_test(struct slgt_info *info)
+{
+	unsigned long timeout;
+	unsigned long flags;
+	struct tty_struct *oldtty = info->tty;
+	u32 speed = info->params.data_rate;
+
+	info->params.data_rate = 921600;
+	info->tty = NULL;
+
+	spin_lock_irqsave(&info->lock, flags);
+	async_mode(info);
+	slgt_irq_on(info, IRQ_TXIDLE);
+
+	/* enable transmitter */
+	wr_reg16(info, TCR,
+		(unsigned short)(rd_reg16(info, TCR) | BIT1));
+
+	/* write one byte and wait for tx idle */
+	wr_reg16(info, TDR, 0);
+
+	/* assume failure */
+	info->init_error = DiagStatus_IrqFailure;
+	info->irq_occurred = FALSE;
+
+	spin_unlock_irqrestore(&info->lock, flags);
+
+	timeout=100;
+	while(timeout-- && !info->irq_occurred)
+		msleep_interruptible(10);
+
+	spin_lock_irqsave(&info->lock,flags);
+	reset_port(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	info->params.data_rate = speed;
+	info->tty = oldtty;
+
+	info->init_error = info->irq_occurred ? 0 : DiagStatus_IrqFailure;
+	return info->irq_occurred ? 0 : -ENODEV;
+}
+
+static int loopback_test_rx(struct slgt_info *info)
+{
+	unsigned char *src, *dest;
+	int count;
+
+	if (desc_complete(info->rbufs[0])) {
+		count = desc_count(info->rbufs[0]);
+		src   = info->rbufs[0].buf;
+		dest  = info->tmp_rbuf;
+
+		for( ; count ; count-=2, src+=2) {
+			/* src=data byte (src+1)=status byte */
+			if (!(*(src+1) & (BIT9 + BIT8))) {
+				*dest = *src;
+				dest++;
+				info->tmp_rbuf_count++;
+			}
+		}
+		DBGDATA(info, info->tmp_rbuf, info->tmp_rbuf_count, "rx");
+		return 1;
+	}
+	return 0;
+}
+
+static int loopback_test(struct slgt_info *info)
+{
+#define TESTFRAMESIZE 20
+
+	unsigned long timeout;
+	u16 count = TESTFRAMESIZE;
+	unsigned char buf[TESTFRAMESIZE];
+	int rc = -ENODEV;
+	unsigned long flags;
+
+	struct tty_struct *oldtty = info->tty;
+	MGSL_PARAMS params;
+
+	memcpy(&params, &info->params, sizeof(params));
+
+	info->params.mode = MGSL_MODE_ASYNC;
+	info->params.data_rate = 921600;
+	info->params.loopback = 1;
+	info->tty = NULL;
+
+	/* build and send transmit frame */
+	for (count = 0; count < TESTFRAMESIZE; ++count)
+		buf[count] = (unsigned char)count;
+
+	info->tmp_rbuf_count = 0;
+	memset(info->tmp_rbuf, 0, TESTFRAMESIZE);
+
+	/* program hardware for HDLC and enabled receiver */
+	spin_lock_irqsave(&info->lock,flags);
+	async_mode(info);
+	rx_start(info);
+	info->tx_count = count;
+	tx_load(info, buf, count);
+	tx_start(info);
+	spin_unlock_irqrestore(&info->lock, flags);
+
+	/* wait for receive complete */
+	for (timeout = 100; timeout; --timeout) {
+		msleep_interruptible(10);
+		if (loopback_test_rx(info)) {
+			rc = 0;
+			break;
+		}
+	}
+
+	/* verify received frame length and contents */
+	if (!rc && (info->tmp_rbuf_count != count ||
+		  memcmp(buf, info->tmp_rbuf, count))) {
+		rc = -ENODEV;
+	}
+
+	spin_lock_irqsave(&info->lock,flags);
+	reset_adapter(info);
+	spin_unlock_irqrestore(&info->lock,flags);
+
+	memcpy(&info->params, &params, sizeof(info->params));
+	info->tty = oldtty;
+
+	info->init_error = rc ? DiagStatus_DmaFailure : 0;
+	return rc;
+}
+
+static int adapter_test(struct slgt_info *info)
+{
+	DBGINFO(("testing %s\n", info->device_name));
+	if ((info->init_error = register_test(info)) < 0) {
+		printk("register test failure %s addr=%08X\n",
+			info->device_name, info->phys_reg_addr);
+	} else if ((info->init_error = irq_test(info)) < 0) {
+		printk("IRQ test failure %s IRQ=%d\n",
+			info->device_name, info->irq_level);
+	} else if ((info->init_error = loopback_test(info)) < 0) {
+		printk("loopback test failure %s\n", info->device_name);
+	}
+	return info->init_error;
+}
+
+/*
+ * transmit timeout handler
+ */
+static void tx_timeout(unsigned long context)
+{
+	struct slgt_info *info = (struct slgt_info*)context;
+	unsigned long flags;
+
+	DBGINFO(("%s tx_timeout\n", info->device_name));
+	if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) {
+		info->icount.txtimeout++;
+	}
+	spin_lock_irqsave(&info->lock,flags);
+	info->tx_active = 0;
+	info->tx_count = 0;
+	spin_unlock_irqrestore(&info->lock,flags);
+
+#ifdef CONFIG_HDLC
+	if (info->netcount)
+		hdlcdev_tx_done(info);
+	else
+#endif
+		bh_transmit(info);
+}
+
+/*
+ * receive buffer polling timer
+ */
+static void rx_timeout(unsigned long context)
+{
+	struct slgt_info *info = (struct slgt_info*)context;
+	unsigned long flags;
+
+	DBGINFO(("%s rx_timeout\n", info->device_name));
+	spin_lock_irqsave(&info->lock, flags);
+	info->pending_bh |= BH_RECEIVE;
+	spin_unlock_irqrestore(&info->lock, flags);
+	bh_handler(info);
+}
+
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index 2392e40..ba4582d 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -2,6 +2,9 @@
 # Makefile for the kernel tpm device drivers.
 #
 obj-$(CONFIG_TCG_TPM) += tpm.o
+ifdef CONFIG_ACPI
+	obj-$(CONFIG_TCG_TPM) += tpm_bios.o
+endif
 obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
 obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
 obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index a9be0e8..5a38704 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -466,6 +466,7 @@
 	kfree(chip->vendor->miscdev.name);
 
 	sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
+	tpm_bios_log_teardown(chip->bios_dir);
 
 	dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
 		~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
@@ -593,6 +594,8 @@
 
 	sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
 
+	chip->bios_dir = tpm_bios_log_setup(devname);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(tpm_register_hardware);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 159882c..fd3a4be 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -82,6 +82,8 @@
 
 	struct tpm_vendor_specific *vendor;
 
+	struct dentry **bios_dir;
+
 	struct list_head list;
 };
 
@@ -107,3 +109,16 @@
 extern void tpm_remove_hardware(struct device *);
 extern int tpm_pm_suspend(struct device *, pm_message_t);
 extern int tpm_pm_resume(struct device *);
+
+#ifdef CONFIG_ACPI
+extern struct dentry ** tpm_bios_log_setup(char *);
+extern void tpm_bios_log_teardown(struct dentry **);
+#else
+static inline struct dentry* tpm_bios_log_setup(char *name)
+{
+	return NULL;
+}
+static inline void tpm_bios_log_teardown(struct dentry **dir)
+{
+}
+#endif
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c
new file mode 100644
index 0000000..aedf7a8
--- /dev/null
+++ b/drivers/char/tpm/tpm_bios.c
@@ -0,0 +1,540 @@
+/*
+ * Copyright (C) 2005 IBM Corporation
+ *
+ * Authors:
+ *	Seiji Munetoh <munetoh@jp.ibm.com>
+ *	Stefan Berger <stefanb@us.ibm.com>
+ *	Reiner Sailer <sailer@watson.ibm.com>
+ *	Kylene Hall <kjhall@us.ibm.com>
+ *
+ * Access to the eventlog extended by the TCG BIOS of PC platform
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/seq_file.h>
+#include <linux/fs.h>
+#include <linux/security.h>
+#include <linux/module.h>
+#include <acpi/acpi.h>
+#include <acpi/actypes.h>
+#include <acpi/actbl.h>
+#include "tpm.h"
+
+#define TCG_EVENT_NAME_LEN_MAX	255
+#define MAX_TEXT_EVENT		1000	/* Max event string length */
+#define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
+
+struct tpm_bios_log {
+	void *bios_event_log;
+	void *bios_event_log_end;
+};
+
+struct acpi_tcpa {
+	struct acpi_table_header hdr;
+	u16 reserved;
+	u32 log_max_len __attribute__ ((packed));
+	u32 log_start_addr __attribute__ ((packed));
+};
+
+struct tcpa_event {
+	u32 pcr_index;
+	u32 event_type;
+	u8 pcr_value[20];	/* SHA1 */
+	u32 event_size;
+	u8 event_data[0];
+};
+
+enum tcpa_event_types {
+	PREBOOT = 0,
+	POST_CODE,
+	UNUSED,
+	NO_ACTION,
+	SEPARATOR,
+	ACTION,
+	EVENT_TAG,
+	SCRTM_CONTENTS,
+	SCRTM_VERSION,
+	CPU_MICROCODE,
+	PLATFORM_CONFIG_FLAGS,
+	TABLE_OF_DEVICES,
+	COMPACT_HASH,
+	IPL,
+	IPL_PARTITION_DATA,
+	NONHOST_CODE,
+	NONHOST_CONFIG,
+	NONHOST_INFO,
+};
+
+static const char* tcpa_event_type_strings[] = {
+	"PREBOOT",
+	"POST CODE",
+	"",
+	"NO ACTION",
+	"SEPARATOR",
+	"ACTION",
+	"EVENT TAG",
+	"S-CRTM Contents",
+	"S-CRTM Version",
+	"CPU Microcode",
+	"Platform Config Flags",
+	"Table of Devices",
+	"Compact Hash",
+	"IPL",
+	"IPL Partition Data",
+	"Non-Host Code",
+	"Non-Host Config",
+	"Non-Host Info"
+};
+
+enum tcpa_pc_event_ids {
+	SMBIOS = 1,
+	BIS_CERT,
+	POST_BIOS_ROM,
+	ESCD,
+	CMOS,
+	NVRAM,
+	OPTION_ROM_EXEC,
+	OPTION_ROM_CONFIG,
+	OPTION_ROM_MICROCODE,
+	S_CRTM_VERSION,
+	S_CRTM_CONTENTS,
+	POST_CONTENTS,
+};
+
+static const char* tcpa_pc_event_id_strings[] = {
+	""
+	"SMBIOS",
+	"BIS Certificate",
+	"POST BIOS ",
+	"ESCD ",
+	"CMOS",
+	"NVRAM",
+	"Option ROM",
+	"Option ROM config",
+	"Option ROM microcode",
+	"S-CRTM Version",
+	"S-CRTM Contents",
+	"S-CRTM POST Contents",
+};
+
+/* returns pointer to start of pos. entry of tcg log */
+static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos)
+{
+	loff_t i;
+	struct tpm_bios_log *log = m->private;
+	void *addr = log->bios_event_log;
+	void *limit = log->bios_event_log_end;
+	struct tcpa_event *event;
+
+	/* read over *pos measurements */
+	for (i = 0; i < *pos; i++) {
+		event = addr;
+
+		if ((addr + sizeof(struct tcpa_event)) < limit) {
+			if (event->event_type == 0 && event->event_size == 0)
+				return NULL;
+			addr += sizeof(struct tcpa_event) + event->event_size;
+		}
+	}
+
+	/* now check if current entry is valid */
+	if ((addr + sizeof(struct tcpa_event)) >= limit)
+		return NULL;
+
+	event = addr;
+
+	if ((event->event_type == 0 && event->event_size == 0) ||
+	    ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit))
+		return NULL;
+
+	return addr;
+}
+
+static void *tpm_bios_measurements_next(struct seq_file *m, void *v,
+					loff_t *pos)
+{
+	struct tcpa_event *event = v;
+	struct tpm_bios_log *log = m->private;
+	void *limit = log->bios_event_log_end;
+
+	v += sizeof(struct tcpa_event) + event->event_size;
+
+	/* now check if current entry is valid */
+	if ((v + sizeof(struct tcpa_event)) >= limit)
+		return NULL;
+
+	event = v;
+
+	if (event->event_type == 0 && event->event_size == 0)
+		return NULL;
+
+	if ((event->event_type == 0 && event->event_size == 0) ||
+	    ((v + sizeof(struct tcpa_event) + event->event_size) >= limit))
+		return NULL;
+
+	(*pos)++;
+	return v;
+}
+
+static void tpm_bios_measurements_stop(struct seq_file *m, void *v)
+{
+}
+
+static int get_event_name(char *dest, struct tcpa_event *event,
+			unsigned char * event_entry)
+{
+	const char *name = "";
+	char data[40] = "";
+	int i, n_len = 0, d_len = 0;
+	u32 event_id, event_data_size;
+
+	switch(event->event_type) {
+	case PREBOOT:
+	case POST_CODE:
+	case UNUSED:
+	case NO_ACTION:
+	case SCRTM_CONTENTS:
+	case SCRTM_VERSION:
+	case CPU_MICROCODE:
+	case PLATFORM_CONFIG_FLAGS:
+	case TABLE_OF_DEVICES:
+	case COMPACT_HASH:
+	case IPL:
+	case IPL_PARTITION_DATA:
+	case NONHOST_CODE:
+	case NONHOST_CONFIG:
+	case NONHOST_INFO:
+		name = tcpa_event_type_strings[event->event_type];
+		n_len = strlen(name);
+		break;
+	case SEPARATOR:
+	case ACTION:
+		if (MAX_TEXT_EVENT > event->event_size) {
+			name = event_entry;
+			n_len = event->event_size;
+		}
+		break;
+	case EVENT_TAG:
+		event_id = be32_to_cpu(event_entry);
+		event_data_size = be32_to_cpu(&event_entry[4]);
+
+		/* ToDo Row data -> Base64 */
+
+		switch (event_id) {
+		case SMBIOS:
+		case BIS_CERT:
+		case CMOS:
+		case NVRAM:
+		case OPTION_ROM_EXEC:
+		case OPTION_ROM_CONFIG:
+		case OPTION_ROM_MICROCODE:
+		case S_CRTM_VERSION:
+		case S_CRTM_CONTENTS:
+		case POST_CONTENTS:
+			name = tcpa_pc_event_id_strings[event_id];
+			n_len = strlen(name);
+			break;
+		case POST_BIOS_ROM:
+		case ESCD:
+			name = tcpa_pc_event_id_strings[event_id];
+			n_len = strlen(name);
+			for (i = 0; i < 20; i++)
+				d_len += sprintf(data, "%02x",
+						event_entry[8 + i]);
+			break;
+		default:
+			break;
+		}
+	default:
+		break;
+	}
+
+	return snprintf(dest, MAX_TEXT_EVENT, "[%.*s%.*s]",
+			n_len, name, d_len, data);
+
+}
+
+static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
+{
+
+	char *eventname;
+	char data[4];
+	u32 help;
+	int i, len;
+	struct tcpa_event *event = (struct tcpa_event *) v;
+	unsigned char *event_entry =
+	    (unsigned char *) (v + sizeof(struct tcpa_event));
+
+	eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
+	if (!eventname) {
+		printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
+		       __func__);
+		return -ENOMEM;
+	}
+
+	/* 1st: PCR used is in little-endian format (4 bytes) */
+	help = le32_to_cpu(event->pcr_index);
+	memcpy(data, &help, 4);
+	for (i = 0; i < 4; i++)
+		seq_putc(m, data[i]);
+
+	/* 2nd: SHA1 (20 bytes) */
+	for (i = 0; i < 20; i++)
+		seq_putc(m, event->pcr_value[i]);
+
+	/* 3rd: event type identifier (4 bytes) */
+	help = le32_to_cpu(event->event_type);
+	memcpy(data, &help, 4);
+	for (i = 0; i < 4; i++)
+		seq_putc(m, data[i]);
+
+	len = 0;
+
+	len += get_event_name(eventname, event, event_entry);
+
+	/* 4th:  filename <= 255 + \'0' delimiter */
+	if (len > TCG_EVENT_NAME_LEN_MAX)
+		len = TCG_EVENT_NAME_LEN_MAX;
+
+	for (i = 0; i < len; i++)
+		seq_putc(m, eventname[i]);
+
+	/* 5th: delimiter */
+	seq_putc(m, '\0');
+
+	return 0;
+}
+
+static int tpm_bios_measurements_release(struct inode *inode,
+					 struct file *file)
+{
+	struct seq_file *seq = file->private_data;
+	struct tpm_bios_log *log = seq->private;
+
+	if (log) {
+		kfree(log->bios_event_log);
+		kfree(log);
+	}
+
+	return seq_release(inode, file);
+}
+
+static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
+{
+	int len = 0;
+	int i;
+	char *eventname;
+	struct tcpa_event *event = v;
+	unsigned char *event_entry =
+	    (unsigned char *) (v + sizeof(struct tcpa_event));
+
+	eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
+	if (!eventname) {
+		printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
+		       __func__);
+		return -EFAULT;
+	}
+
+	seq_printf(m, "%2d ", event->pcr_index);
+
+	/* 2nd: SHA1 */
+	for (i = 0; i < 20; i++)
+		seq_printf(m, "%02x", event->pcr_value[i]);
+
+	/* 3rd: event type identifier */
+	seq_printf(m, " %02x", event->event_type);
+
+	len += get_event_name(eventname, event, event_entry);
+
+	/* 4th: eventname <= max + \'0' delimiter */
+	seq_printf(m, " %s\n", eventname);
+
+	return 0;
+}
+
+static struct seq_operations tpm_ascii_b_measurments_seqops = {
+	.start = tpm_bios_measurements_start,
+	.next = tpm_bios_measurements_next,
+	.stop = tpm_bios_measurements_stop,
+	.show = tpm_ascii_bios_measurements_show,
+};
+
+static struct seq_operations tpm_binary_b_measurments_seqops = {
+	.start = tpm_bios_measurements_start,
+	.next = tpm_bios_measurements_next,
+	.stop = tpm_bios_measurements_stop,
+	.show = tpm_binary_bios_measurements_show,
+};
+
+/* read binary bios log */
+static int read_log(struct tpm_bios_log *log)
+{
+	struct acpi_tcpa *buff;
+	acpi_status status;
+	void *virt;
+
+	if (log->bios_event_log != NULL) {
+		printk(KERN_ERR
+		       "%s: ERROR - Eventlog already initialized\n",
+		       __func__);
+		return -EFAULT;
+	}
+
+	/* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */
+	status = acpi_get_firmware_table(ACPI_TCPA_SIG, 1,
+					 ACPI_LOGICAL_ADDRESSING,
+					 (struct acpi_table_header **)
+					 &buff);
+
+	if (ACPI_FAILURE(status)) {
+		printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n",
+		       __func__);
+		return -EIO;
+	}
+
+	if (buff->log_max_len == 0) {
+		printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
+		return -EIO;
+	}
+
+	/* malloc EventLog space */
+	log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
+	if (!log->bios_event_log) {
+		printk
+		    ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
+		     __func__);
+		return -ENOMEM;
+	}
+
+	log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
+
+	acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt);
+
+	memcpy(log->bios_event_log, virt, buff->log_max_len);
+
+	acpi_os_unmap_memory(virt, buff->log_max_len);
+	return 0;
+}
+
+static int tpm_ascii_bios_measurements_open(struct inode *inode,
+					    struct file *file)
+{
+	int err;
+	struct tpm_bios_log *log;
+	struct seq_file *seq;
+
+	log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
+	if (!log)
+		return -ENOMEM;
+
+	if ((err = read_log(log)))
+		return err;
+
+	/* now register seq file */
+	err = seq_open(file, &tpm_ascii_b_measurments_seqops);
+	if (!err) {
+		seq = file->private_data;
+		seq->private = log;
+	} else {
+		kfree(log->bios_event_log);
+		kfree(log);
+	}
+	return err;
+}
+
+struct file_operations tpm_ascii_bios_measurements_ops = {
+	.open = tpm_ascii_bios_measurements_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = tpm_bios_measurements_release,
+};
+
+static int tpm_binary_bios_measurements_open(struct inode *inode,
+					     struct file *file)
+{
+	int err;
+	struct tpm_bios_log *log;
+	struct seq_file *seq;
+
+	log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL);
+	if (!log)
+		return -ENOMEM;
+
+	if ((err = read_log(log)))
+		return err;
+
+	/* now register seq file */
+	err = seq_open(file, &tpm_binary_b_measurments_seqops);
+	if (!err) {
+		seq = file->private_data;
+		seq->private = log;
+	} else {
+		kfree(log->bios_event_log);
+		kfree(log);
+	}
+	return err;
+}
+
+struct file_operations tpm_binary_bios_measurements_ops = {
+	.open = tpm_binary_bios_measurements_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = tpm_bios_measurements_release,
+};
+
+struct dentry **tpm_bios_log_setup(char *name)
+{
+	struct dentry **ret = NULL, *tpm_dir, *bin_file, *ascii_file;
+
+	tpm_dir = securityfs_create_dir(name, NULL);
+	if (!tpm_dir)
+		goto out;
+
+	bin_file =
+	    securityfs_create_file("binary_bios_measurements",
+				   S_IRUSR | S_IRGRP, tpm_dir, NULL,
+				   &tpm_binary_bios_measurements_ops);
+	if (!bin_file)
+		goto out_tpm;
+
+	ascii_file =
+	    securityfs_create_file("ascii_bios_measurements",
+				   S_IRUSR | S_IRGRP, tpm_dir, NULL,
+				   &tpm_ascii_bios_measurements_ops);
+	if (!ascii_file)
+		goto out_bin;
+
+	ret = kmalloc(3 * sizeof(struct dentry *), GFP_KERNEL);
+	if (!ret)
+		goto out_ascii;
+
+	ret[0] = ascii_file;
+	ret[1] = bin_file;
+	ret[2] = tpm_dir;
+
+	return ret;
+
+out_ascii:
+	securityfs_remove(ascii_file);
+out_bin:
+	securityfs_remove(bin_file);
+out_tpm:
+	securityfs_remove(tpm_dir);
+out:
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(tpm_bios_log_setup);
+
+void tpm_bios_log_teardown(struct dentry **lst)
+{
+	int i;
+
+	for (i = 0; i < 3; i++)
+		securityfs_remove(lst[i]);
+}
+EXPORT_SYMBOL_GPL(tpm_bios_log_teardown);
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index f66c7ad..3c1dafa 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -419,7 +419,7 @@
 			while (this_round > 1) {
 				unsigned short w;
 
-				w = get_unaligned(((const unsigned short *)con_buf0));
+				w = get_unaligned(((unsigned short *)con_buf0));
 				vcs_scr_writew(vc, w, org++);
 				con_buf0 += 2;
 				this_round -= 2;
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index 9ac6d43..a5b18e0 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -718,7 +718,7 @@
 	},
 };
 
-static int __devinit vr41xx_giu_init(void)
+static int __init vr41xx_giu_init(void)
 {
 	int retval;
 
@@ -733,7 +733,7 @@
 	return retval;
 }
 
-static void __devexit vr41xx_giu_exit(void)
+static void __exit vr41xx_giu_exit(void)
 {
 	platform_driver_unregister(&giu_device_driver);
 
diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig
index 344001b..a654479 100644
--- a/drivers/char/watchdog/Kconfig
+++ b/drivers/char/watchdog/Kconfig
@@ -438,7 +438,7 @@
 
 config ZVM_WATCHDOG
 	tristate "z/VM Watchdog Timer"
-	depends on WATCHDOG && ARCH_S390
+	depends on WATCHDOG && S390
 	help
 	  IBM s/390 and zSeries machines running under z/VM 5.1 or later
 	  provide a virtual watchdog timer to their guest that cause a
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index 65830ec..b664060 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -72,7 +72,7 @@
 /*
  * booke_wdt_write:
  */
-static ssize_t booke_wdt_write (struct file *file, const char *buf,
+static ssize_t booke_wdt_write (struct file *file, const char __user *buf,
 				size_t count, loff_t *ppos)
 {
 	booke_wdt_ping();
@@ -92,14 +92,15 @@
 			    unsigned int cmd, unsigned long arg)
 {
 	u32 tmp = 0;
+	u32 __user *p = (u32 __user *)arg;
 
 	switch (cmd) {
 	case WDIOC_GETSUPPORT:
-		if (copy_to_user ((struct watchdog_info *) arg, &ident,
+		if (copy_to_user ((struct watchdog_info __user *) arg, &ident,
 				sizeof(struct watchdog_info)))
 			return -EFAULT;
 	case WDIOC_GETSTATUS:
-		return put_user(ident.options, (u32 *) arg);
+		return put_user(ident.options, p);
 	case WDIOC_GETBOOTSTATUS:
 		/* XXX: something is clearing TSR */
 		tmp = mfspr(SPRN_TSR) & TSR_WRS(3);
@@ -109,14 +110,14 @@
 		booke_wdt_ping();
 		return 0;
 	case WDIOC_SETTIMEOUT:
-		if (get_user(booke_wdt_period, (u32 *) arg))
+		if (get_user(booke_wdt_period, p))
 			return -EFAULT;
 		mtspr(SPRN_TCR, (mfspr(SPRN_TCR)&~WDTP(0))|WDTP(booke_wdt_period));
 		return 0;
 	case WDIOC_GETTIMEOUT:
-		return put_user(booke_wdt_period, (u32 *) arg);
+		return put_user(booke_wdt_period, p);
 	case WDIOC_SETOPTIONS:
-		if (get_user(tmp, (u32 *) arg))
+		if (get_user(tmp, p))
 			return -EINVAL;
 		if (tmp == WDIOS_ENABLECARD) {
 			booke_wdt_ping();
@@ -172,7 +173,7 @@
 	int ret = 0;
 
 	printk (KERN_INFO "PowerPC Book-E Watchdog Timer Loaded\n");
-	ident.firmware_version = cpu_specs[0].pvr_value;
+	ident.firmware_version = cur_cpu_spec->pvr_value;
 
 	ret = misc_register(&booke_wdt_miscdev);
 	if (ret) {
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c
index b5be8b1..3800835 100644
--- a/drivers/char/watchdog/ixp4xx_wdt.c
+++ b/drivers/char/watchdog/ixp4xx_wdt.c
@@ -186,8 +186,8 @@
 	unsigned long processor_id;
 
 	asm("mrc p15, 0, %0, cr0, cr0, 0;" : "=r"(processor_id) :);
-	if (!(processor_id & 0xf)) {
-		printk("IXP4XXX Watchdog: Rev. A0 CPU detected - "
+	if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
+		printk("IXP4XXX Watchdog: Rev. A0 IXP42x CPU detected - "
 			"watchdog disabled\n");
 
 		return -ENODEV;
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index 9defcf8..b4d8434 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -180,10 +180,6 @@
 {
 	struct mpcore_wdt *wdt = file->private_data;
 
-	/*  Can't seek (pwrite) on this device  */
-	if (ppos != &file->f_pos)
-		return -ESPIPE;
-
 	/*
 	 *	Refresh the timer.
 	 */
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 092e9b1..1533f56 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -151,7 +151,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver usb_pcwd_driver = {
-	.owner =	THIS_MODULE,
 	.name =		DRIVER_NAME,
 	.probe =	usb_pcwd_probe,
 	.disconnect =	usb_pcwd_disconnect,
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index eb667da..9dc5473 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -46,12 +46,12 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
+#include <linux/clk.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
 #include <asm/arch/map.h>
-#include <asm/hardware/clock.h>
 
 #undef S3C24XX_VA_WATCHDOG
 #define S3C24XX_VA_WATCHDOG (0)
@@ -397,7 +397,6 @@
 		return -ENOENT;
 	}
 
-	clk_use(wdt_clock);
 	clk_enable(wdt_clock);
 
 	/* see if we can actually set the requested timer margin, and if
@@ -444,7 +443,6 @@
 
 	if (wdt_clock != NULL) {
 		clk_disable(wdt_clock);
-		clk_unuse(wdt_clock);
 		clk_put(wdt_clock);
 		wdt_clock = NULL;
 	}
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
index 619e2ff..dacfe31 100644
--- a/drivers/char/watchdog/wdrtas.c
+++ b/drivers/char/watchdog/wdrtas.c
@@ -320,7 +320,7 @@
 wdrtas_ioctl(struct inode *inode, struct file *file,
 	     unsigned int cmd, unsigned long arg)
 {
-	int __user *argp = (void *)arg;
+	int __user *argp = (void __user *)arg;
 	int i;
 	static struct watchdog_info wdinfo = {
 		.options = WDRTAS_SUPPORTED_MASK,
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
index 44d49df..3843900 100644
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/char/watchdog/wdt977.c
@@ -1,5 +1,5 @@
 /*
- *	Wdt977	0.03:	A Watchdog Device for Netwinder W83977AF chip
+ *	Wdt977	0.04:	A Watchdog Device for Netwinder W83977AF chip
  *
  *	(c) Copyright 1998 Rebel.com (Woody Suwalski <woody@netwinder.org>)
  *
@@ -18,6 +18,8 @@
  *				    from minutes to seconds.
  *      07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in
  *                                    nwwatchdog_init.
+ *      25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks
+ *				    remove limitiation to be used on Netwinders only
  */
 
 #include <linux/module.h>
@@ -28,6 +30,7 @@
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 #include <linux/watchdog.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
@@ -37,8 +40,18 @@
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
 
-#define PFX "Wdt977: "
-#define WATCHDOG_MINOR	130
+#define WATCHDOG_VERSION  "0.04"
+#define WATCHDOG_NAME     "Wdt977"
+#define PFX WATCHDOG_NAME ": "
+#define DRIVER_VERSION    WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n"
+
+#define IO_INDEX_PORT	0x370		/* on some systems it can be 0x3F0 */
+#define IO_DATA_PORT	(IO_INDEX_PORT+1)
+
+#define UNLOCK_DATA	0x87
+#define LOCK_DATA	0xAA
+#define DEVICE_REGISTER	0x07
+
 
 #define	DEFAULT_TIMEOUT	60			/* default timeout in seconds */
 
@@ -47,6 +60,7 @@
 static	unsigned long timer_alive;
 static	int testmode;
 static	char expect_close;
+static	spinlock_t spinlock;
 
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")");
@@ -63,9 +77,13 @@
 
 static int wdt977_start(void)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&spinlock, flags);
+
 	/* unlock the SuperIO chip */
-	outb(0x87,0x370);
-	outb(0x87,0x370);
+	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
+	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
 
 	/* select device Aux2 (device=8) and set watchdog regs F2, F3 and F4
 	 * F2 has the timeout in minutes
@@ -73,28 +91,29 @@
 	 *   at timeout, and to reset timer on kbd/mouse activity (not impl.)
 	 * F4 is used to just clear the TIMEOUT'ed state (bit 0)
 	 */
-	outb(0x07,0x370);
-	outb(0x08,0x371);
-	outb(0xF2,0x370);
-	outb(timeoutM,0x371);
-	outb(0xF3,0x370);
-	outb(0x00,0x371);	/* another setting is 0E for kbd/mouse/LED */
-	outb(0xF4,0x370);
-	outb(0x00,0x371);
+	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
+	outb_p(0x08, IO_DATA_PORT);
+	outb_p(0xF2, IO_INDEX_PORT);
+	outb_p(timeoutM, IO_DATA_PORT);
+	outb_p(0xF3, IO_INDEX_PORT);
+	outb_p(0x00, IO_DATA_PORT);	/* another setting is 0E for kbd/mouse/LED */
+	outb_p(0xF4, IO_INDEX_PORT);
+	outb_p(0x00, IO_DATA_PORT);
 
 	/* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */
 	/* in test mode watch the bit 1 on F4 to indicate "triggered" */
 	if (!testmode)
 	{
-		outb(0x07,0x370);
-		outb(0x07,0x371);
-		outb(0xE6,0x370);
-		outb(0x08,0x371);
+		outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
+		outb_p(0x07, IO_DATA_PORT);
+		outb_p(0xE6, IO_INDEX_PORT);
+		outb_p(0x08, IO_DATA_PORT);
 	}
 
 	/* lock the SuperIO chip */
-	outb(0xAA,0x370);
+	outb_p(LOCK_DATA, IO_INDEX_PORT);
 
+	spin_unlock_irqrestore(&spinlock, flags);
 	printk(KERN_INFO PFX "activated.\n");
 
 	return 0;
@@ -106,35 +125,39 @@
 
 static int wdt977_stop(void)
 {
+	unsigned long flags;
+	spin_lock_irqsave(&spinlock, flags);
+
 	/* unlock the SuperIO chip */
-	outb(0x87,0x370);
-	outb(0x87,0x370);
+	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
+	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
 
 	/* select device Aux2 (device=8) and set watchdog regs F2,F3 and F4
 	* F3 is reset to its default state
 	* F4 can clear the TIMEOUT'ed state (bit 0) - back to default
 	* We can not use GP17 as a PowerLed, as we use its usage as a RedLed
 	*/
-	outb(0x07,0x370);
-	outb(0x08,0x371);
-	outb(0xF2,0x370);
-	outb(0xFF,0x371);
-	outb(0xF3,0x370);
-	outb(0x00,0x371);
-	outb(0xF4,0x370);
-	outb(0x00,0x371);
-	outb(0xF2,0x370);
-	outb(0x00,0x371);
+	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
+	outb_p(0x08, IO_DATA_PORT);
+	outb_p(0xF2, IO_INDEX_PORT);
+	outb_p(0xFF, IO_DATA_PORT);
+	outb_p(0xF3, IO_INDEX_PORT);
+	outb_p(0x00, IO_DATA_PORT);
+	outb_p(0xF4, IO_INDEX_PORT);
+	outb_p(0x00, IO_DATA_PORT);
+	outb_p(0xF2, IO_INDEX_PORT);
+	outb_p(0x00, IO_DATA_PORT);
 
 	/* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */
-	outb(0x07,0x370);
-	outb(0x07,0x371);
-	outb(0xE6,0x370);
-	outb(0x08,0x371);
+	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
+	outb_p(0x07, IO_DATA_PORT);
+	outb_p(0xE6, IO_INDEX_PORT);
+	outb_p(0x08, IO_DATA_PORT);
 
 	/* lock the SuperIO chip */
-	outb(0xAA,0x370);
+	outb_p(LOCK_DATA, IO_INDEX_PORT);
 
+	spin_unlock_irqrestore(&spinlock, flags);
 	printk(KERN_INFO PFX "shutdown.\n");
 
 	return 0;
@@ -147,19 +170,23 @@
 
 static int wdt977_keepalive(void)
 {
+	unsigned long flags;
+	spin_lock_irqsave(&spinlock, flags);
+
 	/* unlock the SuperIO chip */
-	outb(0x87,0x370);
-	outb(0x87,0x370);
+	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
+	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
 
 	/* select device Aux2 (device=8) and kicks watchdog reg F2 */
 	/* F2 has the timeout in minutes */
-	outb(0x07,0x370);
-	outb(0x08,0x371);
-	outb(0xF2,0x370);
-	outb(timeoutM,0x371);
+	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
+	outb_p(0x08, IO_DATA_PORT);
+	outb_p(0xF2, IO_INDEX_PORT);
+	outb_p(timeoutM, IO_DATA_PORT);
 
 	/* lock the SuperIO chip */
-	outb(0xAA,0x370);
+	outb_p(LOCK_DATA, IO_INDEX_PORT);
+	spin_unlock_irqrestore(&spinlock, flags);
 
 	return 0;
 }
@@ -198,22 +225,26 @@
 static int wdt977_get_status(int *status)
 {
 	int new_status;
+	unsigned long flags;
 
-	*status=0;
+	spin_lock_irqsave(&spinlock, flags);
 
 	/* unlock the SuperIO chip */
-	outb(0x87,0x370);
-	outb(0x87,0x370);
+	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
+	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
 
 	/* select device Aux2 (device=8) and read watchdog reg F4 */
-	outb(0x07,0x370);
-	outb(0x08,0x371);
-	outb(0xF4,0x370);
-	new_status = inb(0x371);
+	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
+	outb_p(0x08, IO_DATA_PORT);
+	outb_p(0xF4, IO_INDEX_PORT);
+	new_status = inb_p(IO_DATA_PORT);
 
 	/* lock the SuperIO chip */
-	outb(0xAA,0x370);
+	outb_p(LOCK_DATA, IO_INDEX_PORT);
 
+	spin_unlock_irqrestore(&spinlock, flags);
+
+	*status=0;
 	if (new_status & 1)
 		*status |= WDIOF_CARDRESET;
 
@@ -249,8 +280,8 @@
 		wdt977_stop();
 		clear_bit(0,&timer_alive);
 	} else {
-		printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
 		wdt977_keepalive();
+		printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n");
 	}
 	expect_close = 0;
 	return 0;
@@ -271,14 +302,17 @@
 static ssize_t wdt977_write(struct file *file, const char __user *buf,
 			    size_t count, loff_t *ppos)
 {
-	if (count) {
-		if (!nowayout) {
+	if (count)
+	{
+		if (!nowayout)
+		{
 			size_t i;
 
 			/* In case it was set long ago */
 			expect_close = 0;
 
-			for (i = 0; i != count; i++) {
+			for (i = 0; i != count; i++)
+			{
 				char c;
 				if (get_user(c, buf + i))
 					return -EFAULT;
@@ -287,6 +321,7 @@
 			}
 		}
 
+		/* someone wrote to us, we should restart timer */
 		wdt977_keepalive();
 	}
 	return count;
@@ -308,7 +343,7 @@
 				WDIOF_MAGICCLOSE |
 				WDIOF_KEEPALIVEPING,
 	.firmware_version =	1,
-	.identity =		"Winbond 83977",
+	.identity =		WATCHDOG_NAME,
 };
 
 static int wdt977_ioctl(struct inode *inode, struct file *file,
@@ -405,50 +440,81 @@
 	.notifier_call = wdt977_notify_sys,
 };
 
-static int __init nwwatchdog_init(void)
+static int __init wd977_init(void)
 {
-	int retval;
-	if (!machine_is_netwinder())
-		return -ENODEV;
+	int rc;
+
+	//if (!machine_is_netwinder())
+	//	return -ENODEV;
+
+	printk(KERN_INFO PFX DRIVER_VERSION);
+
+	spin_lock_init(&spinlock);
 
 	/* Check that the timeout value is within it's range ; if not reset to the default */
-	if (wdt977_set_timeout(timeout)) {
+	if (wdt977_set_timeout(timeout))
+	{
 		wdt977_set_timeout(DEFAULT_TIMEOUT);
 		printk(KERN_INFO PFX "timeout value must be 60<timeout<15300, using %d\n",
 			DEFAULT_TIMEOUT);
 	}
 
-	retval = register_reboot_notifier(&wdt977_notifier);
-	if (retval) {
-		printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
-			retval);
-		return retval;
+	/* on Netwinder the IOports are already reserved by
+	 * arch/arm/mach-footbridge/netwinder-hw.c
+	 */
+	if (!machine_is_netwinder())
+	{
+		if (!request_region(IO_INDEX_PORT, 2, WATCHDOG_NAME))
+		{
+			printk(KERN_ERR PFX "I/O address 0x%04x already in use\n",
+				IO_INDEX_PORT);
+			rc = -EIO;
+			goto err_out;
+		}
 	}
 
-	retval = misc_register(&wdt977_miscdev);
-	if (retval) {
+	rc = misc_register(&wdt977_miscdev);
+	if (rc)
+	{
 		printk(KERN_ERR PFX "cannot register miscdev on minor=%d (err=%d)\n",
-			WATCHDOG_MINOR, retval);
-		unregister_reboot_notifier(&wdt977_notifier);
-		return retval;
+			wdt977_miscdev.minor, rc);
+		goto err_out_region;
 	}
 
-	printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d, testmode = %i)\n",
+	rc = register_reboot_notifier(&wdt977_notifier);
+	if (rc)
+	{
+		printk(KERN_ERR PFX "cannot register reboot notifier (err=%d)\n",
+			rc);
+		goto err_out_miscdev;
+	}
+
+	printk(KERN_INFO PFX "initialized. timeout=%d sec (nowayout=%d, testmode=%i)\n",
 		timeout, nowayout, testmode);
 
 	return 0;
+
+err_out_miscdev:
+        misc_deregister(&wdt977_miscdev);
+err_out_region:
+	if (!machine_is_netwinder())
+	        release_region(IO_INDEX_PORT,2);
+err_out:
+	return rc;
 }
 
-static void __exit nwwatchdog_exit(void)
+static void __exit wd977_exit(void)
 {
+	wdt977_stop();
 	misc_deregister(&wdt977_miscdev);
 	unregister_reboot_notifier(&wdt977_notifier);
+	release_region(IO_INDEX_PORT,2);
 }
 
-module_init(nwwatchdog_init);
-module_exit(nwwatchdog_exit);
+module_init(wd977_init);
+module_exit(wd977_exit);
 
-MODULE_AUTHOR("Woody Suwalski <woody@netwinder.org>");
+MODULE_AUTHOR("Woody Suwalski <woodys@xandros.com>");
 MODULE_DESCRIPTION("W83977AF Watchdog driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index fcdf0ff..385e529 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -34,14 +34,14 @@
 static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
 static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
 
-/* proc_counts is used as the sequence number of the netlink message */
+/* proc_event_counts is used as the sequence number of the netlink message */
 static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };
 
 static inline void get_seq(__u32 *ts, int *cpu)
 {
 	*ts = get_cpu_var(proc_event_counts)++;
 	*cpu = smp_processor_id();
-	put_cpu_var(proc_counts);
+	put_cpu_var(proc_event_counts);
 }
 
 void proc_fork_connector(struct task_struct *task)
@@ -56,6 +56,7 @@
 	msg = (struct cn_msg*)buffer;
 	ev = (struct proc_event*)msg->data;
 	get_seq(&msg->seq, &ev->cpu);
+	getnstimestamp(&ev->timestamp);
 	ev->what = PROC_EVENT_FORK;
 	ev->event_data.fork.parent_pid = task->real_parent->pid;
 	ev->event_data.fork.parent_tgid = task->real_parent->tgid;
@@ -81,6 +82,7 @@
 	msg = (struct cn_msg*)buffer;
 	ev = (struct proc_event*)msg->data;
 	get_seq(&msg->seq, &ev->cpu);
+	getnstimestamp(&ev->timestamp);
 	ev->what = PROC_EVENT_EXEC;
 	ev->event_data.exec.process_pid = task->pid;
 	ev->event_data.exec.process_tgid = task->tgid;
@@ -114,6 +116,7 @@
 	} else
 	     	return;
 	get_seq(&msg->seq, &ev->cpu);
+	getnstimestamp(&ev->timestamp);
 
 	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
 	msg->ack = 0; /* not used */
@@ -133,6 +136,7 @@
 	msg = (struct cn_msg*)buffer;
 	ev = (struct proc_event*)msg->data;
 	get_seq(&msg->seq, &ev->cpu);
+	getnstimestamp(&ev->timestamp);
 	ev->what = PROC_EVENT_EXIT;
 	ev->event_data.exit.process_pid = task->pid;
 	ev->event_data.exit.process_tgid = task->tgid;
@@ -165,6 +169,7 @@
 	msg = (struct cn_msg*)buffer;
 	ev = (struct proc_event*)msg->data;
 	msg->seq = rcvd_seq;
+	getnstimestamp(&ev->timestamp);
 	ev->cpu = -1;
 	ev->what = PROC_EVENT_NONE;
 	ev->event_data.ack.err = err;
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 1c0f62d..a9163d0 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -823,6 +823,30 @@
 
 
 /** 
+ * cpufreq_quick_get - get the CPU frequency (in kHz) frpm policy->cur
+ * @cpu: CPU number
+ *
+ * This is the last known freq, without actually getting it from the driver.
+ * Return value will be same as what is shown in scaling_cur_freq in sysfs.
+ */
+unsigned int cpufreq_quick_get(unsigned int cpu)
+{
+	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+	unsigned int ret = 0;
+
+	if (policy) {
+		down(&policy->lock);
+		ret = policy->cur;
+		up(&policy->lock);
+		cpufreq_cpu_put(policy);
+	}
+
+	return (ret);
+}
+EXPORT_SYMBOL(cpufreq_quick_get);
+
+
+/** 
  * cpufreq_get - get the current CPU frequency (in kHz)
  * @cpu: CPU number
  *
@@ -1113,21 +1137,13 @@
 {
 	int retval = -EINVAL;
 
-	/*
-	 * If we are already in context of hotplug thread, we dont need to
-	 * acquire the hotplug lock. Otherwise acquire cpucontrol to prevent
-	 * hotplug from removing this cpu that we are working on.
-	 */
-	if (!current_in_cpu_hotplug())
-		lock_cpu_hotplug();
-
+	lock_cpu_hotplug();
 	dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
 		target_freq, relation);
 	if (cpu_online(policy->cpu) && cpufreq_driver->target)
 		retval = cpufreq_driver->target(policy, target_freq, relation);
 
-	if (!current_in_cpu_hotplug())
-		unlock_cpu_hotplug();
+	unlock_cpu_hotplug();
 
 	return retval;
 }
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
index 2ed5c43..39543a2 100644
--- a/drivers/cpufreq/cpufreq_conservative.c
+++ b/drivers/cpufreq/cpufreq_conservative.c
@@ -93,7 +93,7 @@
 {
 	return	kstat_cpu(cpu).cpustat.idle +
 		kstat_cpu(cpu).cpustat.iowait +
-		( !dbs_tuners_ins.ignore_nice ? 
+		( dbs_tuners_ins.ignore_nice ?
 		  kstat_cpu(cpu).cpustat.nice :
 		  0);
 }
@@ -127,7 +127,7 @@
 show_one(sampling_down_factor, sampling_down_factor);
 show_one(up_threshold, up_threshold);
 show_one(down_threshold, down_threshold);
-show_one(ignore_nice, ignore_nice);
+show_one(ignore_nice_load, ignore_nice);
 show_one(freq_step, freq_step);
 
 static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, 
@@ -207,7 +207,7 @@
 	return count;
 }
 
-static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
+static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
 		const char *buf, size_t count)
 {
 	unsigned int input;
@@ -272,7 +272,7 @@
 define_one_rw(sampling_down_factor);
 define_one_rw(up_threshold);
 define_one_rw(down_threshold);
-define_one_rw(ignore_nice);
+define_one_rw(ignore_nice_load);
 define_one_rw(freq_step);
 
 static struct attribute * dbs_attributes[] = {
@@ -282,7 +282,7 @@
 	&sampling_down_factor.attr,
 	&up_threshold.attr,
 	&down_threshold.attr,
-	&ignore_nice.attr,
+	&ignore_nice_load.attr,
 	&freq_step.attr,
 	NULL
 };
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 1774111..e69fd8d 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -89,7 +89,7 @@
 {
 	return	kstat_cpu(cpu).cpustat.idle +
 		kstat_cpu(cpu).cpustat.iowait +
-		( !dbs_tuners_ins.ignore_nice ? 
+		( dbs_tuners_ins.ignore_nice ?
 		  kstat_cpu(cpu).cpustat.nice :
 		  0);
 }
@@ -122,7 +122,7 @@
 show_one(sampling_rate, sampling_rate);
 show_one(sampling_down_factor, sampling_down_factor);
 show_one(up_threshold, up_threshold);
-show_one(ignore_nice, ignore_nice);
+show_one(ignore_nice_load, ignore_nice);
 
 static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, 
 		const char *buf, size_t count)
@@ -182,7 +182,7 @@
 	return count;
 }
 
-static ssize_t store_ignore_nice(struct cpufreq_policy *policy,
+static ssize_t store_ignore_nice_load(struct cpufreq_policy *policy,
 		const char *buf, size_t count)
 {
 	unsigned int input;
@@ -223,7 +223,7 @@
 define_one_rw(sampling_rate);
 define_one_rw(sampling_down_factor);
 define_one_rw(up_threshold);
-define_one_rw(ignore_nice);
+define_one_rw(ignore_nice_load);
 
 static struct attribute * dbs_attributes[] = {
 	&sampling_rate_max.attr,
@@ -231,7 +231,7 @@
 	&sampling_rate.attr,
 	&sampling_down_factor.attr,
 	&up_threshold.attr,
-	&ignore_nice.attr,
+	&ignore_nice_load.attr,
 	NULL
 };
 
diff --git a/drivers/fc4/Kconfig b/drivers/fc4/Kconfig
index f00c02a..345dbe6 100644
--- a/drivers/fc4/Kconfig
+++ b/drivers/fc4/Kconfig
@@ -26,7 +26,7 @@
 
 config FC4_SOC
 	tristate "Sun SOC/Sbus"
-	depends on FC4!=n && (SPARC32 || SPARC64)
+	depends on FC4!=n && SPARC
 	help
 	  Serial Optical Channel is an interface card with one or two Fibre
 	  Optic ports, each of which can be connected to a disk array. Note
@@ -38,7 +38,7 @@
 
 config FC4_SOCAL
 	tristate "Sun SOC+ (aka SOCAL)"
-	depends on FC4!=n && (SPARC32 || SPARC64)
+	depends on FC4!=n && SPARC
 	---help---
 	  Serial Optical Channel Plus is an interface card with up to two
 	  Fibre Optic ports. This card supports FC Arbitrated Loop (usually
@@ -62,7 +62,7 @@
 	  be called pluto.
 
 config SCSI_FCAL
-	tristate "Sun Enterprise Network Array (A5000 and EX500)" if SPARC32 || SPARC64
+	tristate "Sun Enterprise Network Array (A5000 and EX500)" if SPARC
 	depends on FC4!=n && SCSI
 	help
 	  This driver drives FC-AL disks connected through a Fibre Channel
@@ -75,7 +75,7 @@
 
 config SCSI_FCAL
 	prompt "Generic FC-AL disk driver"
-	depends on FC4!=n && SCSI && !SPARC32 && !SPARC64
+	depends on FC4!=n && SCSI && !SPARC
 
 endmenu
 
diff --git a/drivers/firmware/dell_rbu.c b/drivers/firmware/dell_rbu.c
index 6d83299..dfedb77 100644
--- a/drivers/firmware/dell_rbu.c
+++ b/drivers/firmware/dell_rbu.c
@@ -105,8 +105,8 @@
 	int ordernum = 0;
 	int retval = 0;
 	unsigned int packet_array_size = 0;
-	void **invalid_addr_packet_array = 0;
-	void *packet_data_temp_buf = 0;
+	void **invalid_addr_packet_array = NULL;
+	void *packet_data_temp_buf = NULL;
 	unsigned int idx = 0;
 
 	pr_debug("create_packet: entry \n");
@@ -178,7 +178,7 @@
 						packet_data_temp_buf),
 					allocation_floor);
 			invalid_addr_packet_array[idx++] = packet_data_temp_buf;
-			packet_data_temp_buf = 0;
+			packet_data_temp_buf = NULL;
 		}
 	}
 	spin_lock(&rbu_data.lock);
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index db358cf..c582959 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -350,6 +350,18 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called via686a.
 
+config SENSORS_VT8231
+	tristate "VT8231"
+	depends on HWMON && I2C && PCI && EXPERIMENTAL
+	select HWMON_VID
+	select I2C_ISA
+	help
+	  If you say yes here then you get support for the integrated sensors
+	  in the VIA VT8231 device.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called vt8231.
+
 config SENSORS_W83781D
 	tristate "Winbond W83781D, W83782D, W83783S, W83627HF, Asus AS99127F"
 	depends on HWMON && I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index f7d6a2f..06d4a1d 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -40,6 +40,7 @@
 obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
 obj-$(CONFIG_SENSORS_SMSC47M1)	+= smsc47m1.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
+obj-$(CONFIG_SENSORS_VT8231)	+= vt8231.o
 obj-$(CONFIG_SENSORS_W83627EHF)	+= w83627ehf.o
 obj-$(CONFIG_SENSORS_W83L785TS)	+= w83l785ts.o
 
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index 8102876..6656127 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -126,10 +126,10 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver adm1021_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "adm1021",
+	.driver = {
+		.name	= "adm1021",
+	},
 	.id		= I2C_DRIVERID_ADM1021,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= adm1021_attach_adapter,
 	.detach_client	= adm1021_detach_client,
 };
diff --git a/drivers/hwmon/adm1025.c b/drivers/hwmon/adm1025.c
index 3ec1242..9331c56 100644
--- a/drivers/hwmon/adm1025.c
+++ b/drivers/hwmon/adm1025.c
@@ -118,10 +118,10 @@
  */
 
 static struct i2c_driver adm1025_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "adm1025",
+	.driver = {
+		.name	= "adm1025",
+	},
 	.id		= I2C_DRIVERID_ADM1025,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= adm1025_attach_adapter,
 	.detach_client	= adm1025_detach_client,
 };
@@ -287,8 +287,6 @@
 	struct adm1025_data *data = adm1025_update_device(dev);
 	return sprintf(buf, "%u\n", vid_from_reg(data->vid, data->vrm));
 }
-/* in1_ref is deprecated in favour of cpu0_vid, remove after 2005-11-11 */
-static DEVICE_ATTR(in1_ref, S_IRUGO, show_vid, NULL);
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
 
 static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf)
@@ -444,8 +442,6 @@
 	device_create_file(&new_client->dev, &dev_attr_temp1_max);
 	device_create_file(&new_client->dev, &dev_attr_temp2_max);
 	device_create_file(&new_client->dev, &dev_attr_alarms);
-	/* in1_ref is deprecated, remove after 2005-11-11 */
-	device_create_file(&new_client->dev, &dev_attr_in1_ref);
 	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
 	device_create_file(&new_client->dev, &dev_attr_vrm);
 
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index e0f5654..fefe6e7 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -308,9 +308,9 @@
 
 
 static struct i2c_driver adm1026_driver = {
-	.owner          = THIS_MODULE,
-	.name           = "adm1026",
-	.flags          = I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "adm1026",
+	},
 	.attach_adapter = adm1026_attach_adapter,
 	.detach_client  = adm1026_detach_client,
 };
@@ -1227,8 +1227,6 @@
 	struct adm1026_data *data = adm1026_update_device(dev);
 	return sprintf(buf,"%d\n", vid_from_reg(data->vid & 0x3f, data->vrm));
 }
-/* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */
-static DEVICE_ATTR(vid, S_IRUGO, show_vid_reg, NULL);
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
 
 static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
@@ -1673,8 +1671,6 @@
 	device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable);
 	device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable);
 	device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable);
-	/* vid deprecated in favour of cpu0_vid, remove after 2005-11-11 */
-	device_create_file(&new_client->dev, &dev_attr_vid);
 	device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
 	device_create_file(&new_client->dev, &dev_attr_vrm);
 	device_create_file(&new_client->dev, &dev_attr_alarms);
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c
index 7c545d5..d063979 100644
--- a/drivers/hwmon/adm1031.c
+++ b/drivers/hwmon/adm1031.c
@@ -105,9 +105,9 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver adm1031_driver = {
-	.owner = THIS_MODULE,
-	.name = "adm1031",
-	.flags = I2C_DF_NOTIFY,
+	.driver = {
+		.name = "adm1031",
+	},
 	.attach_adapter = adm1031_attach_adapter,
 	.detach_client = adm1031_detach_client,
 };
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index 11dc95f..5ddc22f 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -137,10 +137,10 @@
 
 /* driver data */
 static struct i2c_driver adm9240_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "adm9240",
+	.driver = {
+		.name	= "adm9240",
+	},
 	.id		= I2C_DRIVERID_ADM9240,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= adm9240_attach_adapter,
 	.detach_client	= adm9240_detach_client,
 };
diff --git a/drivers/hwmon/asb100.c b/drivers/hwmon/asb100.c
index 52c4697..ae9de63 100644
--- a/drivers/hwmon/asb100.c
+++ b/drivers/hwmon/asb100.c
@@ -217,10 +217,10 @@
 static void asb100_init_client(struct i2c_client *client);
 
 static struct i2c_driver asb100_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "asb100",
+	.driver = {
+		.name	= "asb100",
+	},
 	.id		= I2C_DRIVERID_ASB100,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= asb100_attach_adapter,
 	.detach_client	= asb100_detach_client,
 };
diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c
index 53324f5..b0c4900 100644
--- a/drivers/hwmon/atxp1.c
+++ b/drivers/hwmon/atxp1.c
@@ -50,9 +50,9 @@
 static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind);
 
 static struct i2c_driver atxp1_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "atxp1",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "atxp1",
+	},
 	.attach_adapter = atxp1_attach_adapter,
 	.detach_client	= atxp1_detach_client,
 };
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index 34f71b7..203f9c7 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -89,10 +89,10 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver ds1621_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "ds1621",
+	.driver = {
+		.name	= "ds1621",
+	},
 	.id		= I2C_DRIVERID_DS1621,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= ds1621_attach_adapter,
 	.detach_client	= ds1621_detach_client,
 };
diff --git a/drivers/hwmon/fscher.c b/drivers/hwmon/fscher.c
index a02e1c3..2540918 100644
--- a/drivers/hwmon/fscher.c
+++ b/drivers/hwmon/fscher.c
@@ -118,10 +118,10 @@
  */
  
 static struct i2c_driver fscher_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "fscher",
+	.driver = {
+		.name	= "fscher",
+	},
 	.id		= I2C_DRIVERID_FSCHER,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= fscher_attach_adapter,
 	.detach_client	= fscher_detach_client,
 };
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c
index 64e4edc..6d0146b 100644
--- a/drivers/hwmon/fscpos.c
+++ b/drivers/hwmon/fscpos.c
@@ -100,10 +100,10 @@
  * Driver data (common to all clients)
  */
 static struct i2c_driver fscpos_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "fscpos",
+	.driver = {
+		.name	= "fscpos",
+	},
 	.id		= I2C_DRIVERID_FSCPOS,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= fscpos_attach_adapter,
 	.detach_client	= fscpos_detach_client,
 };
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
index 2f178db..9e685e3 100644
--- a/drivers/hwmon/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
@@ -151,10 +151,10 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver gl518_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "gl518sm",
+	.driver = {
+		.name	= "gl518sm",
+	},
 	.id		= I2C_DRIVERID_GL518,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= gl518_attach_adapter,
 	.detach_client	= gl518_detach_client,
 };
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index c39ba12..baee60e 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -109,10 +109,10 @@
 
 /* Driver data */
 static struct i2c_driver gl520_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "gl520sm",
+	.driver = {
+		.name	= "gl520sm",
+	},
 	.id		= I2C_DRIVERID_GL520,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= gl520_attach_adapter,
 	.detach_client	= gl520_detach_client,
 };
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index 312769a..e497274 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -49,20 +49,22 @@
         . . . .
        11110  =  0.800 V
        11111  =  0.000 V (off)
+
+    The 17 specification is in fact Intel Mobile Voltage Positioning -
+    (IMVP-II). You can find more information in the datasheet of Max1718
+    http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452
+
 */
 
 /* vrm is the VRM/VRD document version multiplied by 10.
    val is the 4-, 5- or 6-bit VID code.
    Returned value is in mV to avoid floating point in the kernel. */
-int vid_from_reg(int val, int vrm)
+int vid_from_reg(int val, u8 vrm)
 {
 	int vid;
 
 	switch(vrm) {
 
-	case  0:
-		return 0;
-
 	case 100:               /* VRD 10.0 */
 		if((val & 0x1f) == 0x1f)
 			return 0;
@@ -91,10 +93,16 @@
 	case 84:		/* VRM 8.4 */
 		val &= 0x0f;
 				/* fall through */
-	default:		/* VRM 8.2 */
+	case 82:		/* VRM 8.2 */
 		return(val == 0x1f ? 0 :
 		       val & 0x10  ? 5100 - (val) * 100 :
 		                     2050 - (val) * 50);
+	case 17:		/* Intel IMVP-II */
+		return(val & 0x10 ? 975 - (val & 0xF) * 25 :
+				    1750 - val * 50);
+	default:		/* report 0 for unknown */
+		printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n");
+		return 0;
 	}
 }
 
@@ -108,30 +116,36 @@
 	u8 vendor;
 	u8 eff_family;
 	u8 eff_model;
-	int vrm_type;
+	u8 eff_stepping;
+	u8 vrm_type;
 };
 
 #define ANY 0xFF
 
 #ifdef CONFIG_X86
 
+/* the stepping parameter is highest acceptable stepping for current line */
+
 static struct vrm_model vrm_models[] = {
-	{X86_VENDOR_AMD, 0x6, ANY, 90},		/* Athlon Duron etc */
-	{X86_VENDOR_AMD, 0xF, ANY, 24},		/* Athlon 64, Opteron */
-	{X86_VENDOR_INTEL, 0x6, 0x9, 85},	/* 0.13um too */
-	{X86_VENDOR_INTEL, 0x6, 0xB, 85},	/* Tualatin */
-	{X86_VENDOR_INTEL, 0x6, ANY, 82},	/* any P6 */
-	{X86_VENDOR_INTEL, 0x7, ANY, 0},	/* Itanium */
-	{X86_VENDOR_INTEL, 0xF, 0x0, 90},	/* P4 */
-	{X86_VENDOR_INTEL, 0xF, 0x1, 90},	/* P4 Willamette */
-	{X86_VENDOR_INTEL, 0xF, 0x2, 90},	/* P4 Northwood */
-	{X86_VENDOR_INTEL, 0xF, 0x3, 100},	/* P4 Prescott */
-	{X86_VENDOR_INTEL, 0xF, 0x4, 100},	/* P4 Prescott */
-	{X86_VENDOR_INTEL, 0x10,ANY, 0},	/* Itanium 2 */
-	{X86_VENDOR_UNKNOWN, ANY, ANY, 0}	/* stop here */
+	{X86_VENDOR_AMD, 0x6, ANY, ANY, 90},		/* Athlon Duron etc */
+	{X86_VENDOR_AMD, 0xF, ANY, ANY, 24},		/* Athlon 64, Opteron and above VRM 24 */
+	{X86_VENDOR_INTEL, 0x6, 0x9, ANY, 85},		/* 0.13um too */
+	{X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85},		/* Tualatin */
+	{X86_VENDOR_INTEL, 0x6, ANY, ANY, 82},		/* any P6 */
+	{X86_VENDOR_INTEL, 0x7, ANY, ANY, 0},		/* Itanium */
+	{X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90},		/* P4 */
+	{X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90},		/* P4 Willamette */
+	{X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90},		/* P4 Northwood */
+	{X86_VENDOR_INTEL, 0xF, ANY, ANY, 100},		/* Prescott and above assume VRD 10 */
+	{X86_VENDOR_INTEL, 0x10, ANY, ANY, 0},		/* Itanium 2 */
+	{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85},	/* Eden ESP/Ezra */
+	{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85},	/* Ezra T */
+	{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85},	/* Nemiah */
+	{X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17},	/* C3-M */
+	{X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0}		/* stop here */
 };
 
-static int find_vrm(u8 eff_family, u8 eff_model, u8 vendor)
+static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor)
 {
 	int i = 0;
 
@@ -139,7 +153,8 @@
 		if (vrm_models[i].vendor==vendor)
 			if ((vrm_models[i].eff_family==eff_family)
 			 && ((vrm_models[i].eff_model==eff_model) ||
-			     (vrm_models[i].eff_model==ANY)))
+			     (vrm_models[i].eff_model==ANY)) &&
+			     (eff_stepping <= vrm_models[i].eff_stepping))
 				return vrm_models[i].vrm_type;
 		i++;
 	}
@@ -147,12 +162,11 @@
 	return 0;
 }
 
-int vid_which_vrm(void)
+u8 vid_which_vrm(void)
 {
 	struct cpuinfo_x86 *c = cpu_data;
 	u32 eax;
-	u8 eff_family, eff_model;
-	int vrm_ret;
+	u8 eff_family, eff_model, eff_stepping, vrm_ret;
 
 	if (c->x86 < 6)		/* Any CPU with family lower than 6 */
 		return 0;	/* doesn't have VID and/or CPUID */
@@ -160,20 +174,21 @@
 	eax = cpuid_eax(1);
 	eff_family = ((eax & 0x00000F00)>>8);
 	eff_model  = ((eax & 0x000000F0)>>4);
+	eff_stepping = eax & 0xF;
 	if (eff_family == 0xF) {	/* use extended model & family */
 		eff_family += ((eax & 0x00F00000)>>20);
 		eff_model += ((eax & 0x000F0000)>>16)<<4;
 	}
-	vrm_ret = find_vrm(eff_family,eff_model,c->x86_vendor);
+	vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor);
 	if (vrm_ret == 0)
 		printk(KERN_INFO "hwmon-vid: Unknown VRM version of your "
 		       "x86 CPU\n");
 	return vrm_ret;
 }
 
-/* and now something completely different for the non-x86 world */
+/* and now for something completely different for the non-x86 world */
 #else
-int vid_which_vrm(void)
+u8 vid_which_vrm(void)
 {
 	printk(KERN_INFO "hwmon-vid: Unknown VRM version of your CPU\n");
 	return 0;
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index a61f5d0..0da7c9c 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -213,7 +213,7 @@
 	u8 sensor;		/* Register value */
 	u8 fan_div[3];		/* Register encoding, shifted right */
 	u8 vid;			/* Register encoding, combined */
-	int vrm;
+	u8 vrm;
 	u32 alarms;		/* Register encoding, combined */
 	u8 fan_main_ctrl;	/* Register value */
 	u8 manual_pwm_ctl[3];   /* manual PWM value set by user */
@@ -234,17 +234,18 @@
 
 
 static struct i2c_driver it87_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "it87",
+	.driver = {
+		.name	= "it87",
+	},
 	.id		= I2C_DRIVERID_IT87,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= it87_attach_adapter,
 	.detach_client	= it87_detach_client,
 };
 
 static struct i2c_driver it87_isa_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "it87-isa",
+	.driver = {
+		.name	= "it87-isa",
+	},
 	.attach_adapter	= it87_isa_attach_adapter,
 	.detach_client	= it87_detach_client,
 };
@@ -668,7 +669,7 @@
 show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct it87_data *data = it87_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) data->vrm);
+	return sprintf(buf, "%u\n", data->vrm);
 }
 static ssize_t
 store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
@@ -761,7 +762,8 @@
 
 	/* Reserve the ISA region */
 	if (is_isa)
-		if (!request_region(address, IT87_EXTENT, it87_isa_driver.name))
+		if (!request_region(address, IT87_EXTENT,
+				    it87_isa_driver.driver.name))
 			goto ERROR0;
 
 	/* For now, we presume we have a valid client. We create the
diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c
index 954ec24..6b1aa7e 100644
--- a/drivers/hwmon/lm63.c
+++ b/drivers/hwmon/lm63.c
@@ -139,9 +139,9 @@
  */
 
 static struct i2c_driver lm63_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm63",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "lm63",
+	},
 	.attach_adapter	= lm63_attach_adapter,
 	.detach_client	= lm63_detach_client,
 };
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index d70f4c8..74ca2c8 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -66,10 +66,10 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver lm75_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm75",
+	.driver = {
+		.name	= "lm75",
+	},
 	.id		= I2C_DRIVERID_LM75,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= lm75_attach_adapter,
 	.detach_client	= lm75_detach_client,
 };
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c
index 9380fda..a2f420d 100644
--- a/drivers/hwmon/lm77.c
+++ b/drivers/hwmon/lm77.c
@@ -74,9 +74,9 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver lm77_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm77",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "lm77",
+	},
 	.attach_adapter = lm77_attach_adapter,
 	.detach_client	= lm77_detach_client,
 };
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index 78cdd50..e404001 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -164,17 +164,18 @@
 
 
 static struct i2c_driver lm78_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm78",
+	.driver = {
+		.name	= "lm78",
+	},
 	.id		= I2C_DRIVERID_LM78,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= lm78_attach_adapter,
 	.detach_client	= lm78_detach_client,
 };
 
 static struct i2c_driver lm78_isa_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm78-isa",
+	.driver = {
+		.name	= "lm78-isa",
+	},
 	.attach_adapter	= lm78_isa_attach_adapter,
 	.detach_client	= lm78_detach_client,
 };
@@ -497,7 +498,7 @@
 	/* Reserve the ISA region */
 	if (is_isa)
 		if (!request_region(address, LM78_EXTENT,
-				    lm78_isa_driver.name)) {
+				    lm78_isa_driver.driver.name)) {
 			err = -EBUSY;
 			goto ERROR0;
 		}
diff --git a/drivers/hwmon/lm80.c b/drivers/hwmon/lm80.c
index c359fde..c9a7cde 100644
--- a/drivers/hwmon/lm80.c
+++ b/drivers/hwmon/lm80.c
@@ -143,10 +143,10 @@
  */
 
 static struct i2c_driver lm80_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm80",
+	.driver = {
+		.name	= "lm80",
+	},
 	.id		= I2C_DRIVERID_LM80,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= lm80_attach_adapter,
 	.detach_client	= lm80_detach_client,
 };
diff --git a/drivers/hwmon/lm83.c b/drivers/hwmon/lm83.c
index 9a70611..26dfa9e 100644
--- a/drivers/hwmon/lm83.c
+++ b/drivers/hwmon/lm83.c
@@ -124,10 +124,10 @@
  */
  
 static struct i2c_driver lm83_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm83",
+	.driver = {
+		.name	= "lm83",
+	},
 	.id		= I2C_DRIVERID_LM83,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= lm83_attach_adapter,
 	.detach_client	= lm83_detach_client,
 };
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index d1070ed..7389a01 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -380,10 +380,10 @@
 
 
 static struct i2c_driver lm85_driver = {
-	.owner          = THIS_MODULE,
-	.name           = "lm85",
+	.driver = {
+		.name   = "lm85",
+	},
 	.id             = I2C_DRIVERID_LM85,
-	.flags          = I2C_DF_NOTIFY,
 	.attach_adapter = lm85_attach_adapter,
 	.detach_client  = lm85_detach_client,
 };
@@ -443,7 +443,17 @@
 static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct lm85_data *data = lm85_update_device(dev);
-	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));
+	int vid;
+
+	if (data->type == adt7463 && (data->vid & 0x80)) {
+		/* 6-pin VID (VRM 10) */
+		vid = vid_from_reg(data->vid & 0x3f, data->vrm);
+	} else {
+		/* 5-pin VID (VRM 9) */
+		vid = vid_from_reg(data->vid & 0x1f, data->vrm);
+	}
+
+	return sprintf(buf, "%d\n", vid);
 }
 
 static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
@@ -1176,17 +1186,14 @@
 	device_create_file(&new_client->dev, &dev_attr_in1_input);
 	device_create_file(&new_client->dev, &dev_attr_in2_input);
 	device_create_file(&new_client->dev, &dev_attr_in3_input);
-	device_create_file(&new_client->dev, &dev_attr_in4_input);
 	device_create_file(&new_client->dev, &dev_attr_in0_min);
 	device_create_file(&new_client->dev, &dev_attr_in1_min);
 	device_create_file(&new_client->dev, &dev_attr_in2_min);
 	device_create_file(&new_client->dev, &dev_attr_in3_min);
-	device_create_file(&new_client->dev, &dev_attr_in4_min);
 	device_create_file(&new_client->dev, &dev_attr_in0_max);
 	device_create_file(&new_client->dev, &dev_attr_in1_max);
 	device_create_file(&new_client->dev, &dev_attr_in2_max);
 	device_create_file(&new_client->dev, &dev_attr_in3_max);
-	device_create_file(&new_client->dev, &dev_attr_in4_max);
 	device_create_file(&new_client->dev, &dev_attr_temp1_input);
 	device_create_file(&new_client->dev, &dev_attr_temp2_input);
 	device_create_file(&new_client->dev, &dev_attr_temp3_input);
@@ -1224,6 +1231,15 @@
 	device_create_file(&new_client->dev, &dev_attr_temp2_auto_temp_crit);
 	device_create_file(&new_client->dev, &dev_attr_temp3_auto_temp_crit);
 
+	/* The ADT7463 has an optional VRM 10 mode where pin 21 is used
+	   as a sixth digital VID input rather than an analog input. */
+	data->vid = lm85_read_value(new_client, LM85_REG_VID);
+	if (!(kind == adt7463 && (data->vid & 0x80))) {
+		device_create_file(&new_client->dev, &dev_attr_in4_input);
+		device_create_file(&new_client->dev, &dev_attr_in4_min);
+		device_create_file(&new_client->dev, &dev_attr_in4_max);
+	}
+
 	return 0;
 
 	/* Error out and cleanup code */
@@ -1382,11 +1398,18 @@
 		   irrelevant. So it is left in 4*/
 		data->adc_scale = (data->type == emc6d102 ) ? 16 : 4;
 
-		for (i = 0; i <= 4; ++i) {
+		data->vid = lm85_read_value(client, LM85_REG_VID);
+
+		for (i = 0; i <= 3; ++i) {
 			data->in[i] =
 			    lm85_read_value(client, LM85_REG_IN(i));
 		}
 
+		if (!(data->type == adt7463 && (data->vid & 0x80))) {
+			data->in[4] = lm85_read_value(client,
+				      LM85_REG_IN(4));
+		}
+
 		for (i = 0; i <= 3; ++i) {
 			data->fan[i] =
 			    lm85_read_value(client, LM85_REG_FAN(i));
@@ -1450,13 +1473,20 @@
 		/* Things that don't change often */
 		dev_dbg(&client->dev, "Reading config values\n");
 
-		for (i = 0; i <= 4; ++i) {
+		for (i = 0; i <= 3; ++i) {
 			data->in_min[i] =
 			    lm85_read_value(client, LM85_REG_IN_MIN(i));
 			data->in_max[i] =
 			    lm85_read_value(client, LM85_REG_IN_MAX(i));
 		}
 
+		if (!(data->type == adt7463 && (data->vid & 0x80))) {
+			data->in_min[4] = lm85_read_value(client,
+					  LM85_REG_IN_MIN(4));
+			data->in_max[4] = lm85_read_value(client,
+					  LM85_REG_IN_MAX(4));
+		}
+
 		if ( data->type == emc6d100 ) {
 			for (i = 5; i <= 7; ++i) {
 				data->in_min[i] =
@@ -1478,8 +1508,6 @@
 			    lm85_read_value(client, LM85_REG_TEMP_MAX(i));
 		}
 
-		data->vid = lm85_read_value(client, LM85_REG_VID);
-
 		for (i = 0; i <= 2; ++i) {
 			int val ;
 			data->autofan[i].config =
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
index eeec1817..6ba34c3 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -161,10 +161,10 @@
  */
 
 static struct i2c_driver lm87_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm87",
+	.driver = {
+		.name	= "lm87",
+	},
 	.id		= I2C_DRIVERID_LM87,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= lm87_attach_adapter,
 	.detach_client	= lm87_detach_client,
 };
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index 83cf2e1..56794644 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -186,10 +186,10 @@
  */
 
 static struct i2c_driver lm90_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm90",
+	.driver = {
+		.name	= "lm90",
+	},
 	.id		= I2C_DRIVERID_LM90,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= lm90_attach_adapter,
 	.detach_client	= lm90_detach_client,
 };
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
index 7a4b3701..b0c4cb7 100644
--- a/drivers/hwmon/lm92.c
+++ b/drivers/hwmon/lm92.c
@@ -410,10 +410,10 @@
  */
 
 static struct i2c_driver lm92_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "lm92",
+	.driver = {
+		.name	= "lm92",
+	},
 	.id		= I2C_DRIVERID_LM92,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= lm92_attach_adapter,
 	.detach_client	= lm92_detach_client,
 };
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 69e7e12..3abe330 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -90,9 +90,9 @@
  */
 
 static struct i2c_driver max1619_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "max1619",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "max1619",
+	},
 	.attach_adapter	= max1619_attach_adapter,
 	.detach_client	= max1619_detach_client,
 };
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 17f745a..f161e88 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -236,8 +236,9 @@
  */
 
 static struct i2c_driver pc87360_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "pc87360",
+	.driver = {
+		.name	= "pc87360",
+	},
 	.attach_adapter	= pc87360_detect,
 	.detach_client	= pc87360_detach_client,
 };
@@ -798,7 +799,7 @@
 	for (i = 0; i < 3; i++) {
 		if (((data->address[i] = extra_isa[i]))
 		 && !request_region(extra_isa[i], PC87360_EXTENT,
-		 		    pc87360_driver.name)) {
+		 		    pc87360_driver.driver.name)) {
 			dev_err(&new_client->dev, "Region 0x%x-0x%x already "
 				"in use!\n", extra_isa[i],
 				extra_isa[i]+PC87360_EXTENT-1);
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 9c6cade..8be5189 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -198,8 +198,9 @@
 static void sis5595_init_client(struct i2c_client *client);
 
 static struct i2c_driver sis5595_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "sis5595",
+	.driver = {
+		.name	= "sis5595",
+	},
 	.attach_adapter	= sis5595_detect,
 	.detach_client	= sis5595_detach_client,
 };
@@ -484,7 +485,8 @@
 	if (force_addr)
 		address = force_addr & ~(SIS5595_EXTENT - 1);
 	/* Reserve the ISA region */
-	if (!request_region(address, SIS5595_EXTENT, sis5595_driver.name)) {
+	if (!request_region(address, SIS5595_EXTENT,
+			    sis5595_driver.driver.name)) {
 		err = -EBUSY;
 		goto exit;
 	}
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 2a3e21b..8663bbb 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -226,8 +226,9 @@
 static int smsc47b397_detect(struct i2c_adapter *adapter);
 
 static struct i2c_driver smsc47b397_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "smsc47b397",
+	.driver = {
+		.name	= "smsc47b397",
+	},
 	.attach_adapter	= smsc47b397_detect,
 	.detach_client	= smsc47b397_detach_client,
 };
@@ -238,7 +239,8 @@
 	struct smsc47b397_data *data;
 	int err = 0;
 
-	if (!request_region(address, SMSC_EXTENT, smsc47b397_driver.name)) {
+	if (!request_region(address, SMSC_EXTENT,
+			    smsc47b397_driver.driver.name)) {
 		dev_err(&adapter->dev, "Region 0x%x already in use!\n",
 			address);
 		return -EBUSY;
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index 5905c1a..d1e3ec0 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -126,8 +126,9 @@
 
 
 static struct i2c_driver smsc47m1_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "smsc47m1",
+	.driver = {
+		.name	= "smsc47m1",
+	},
 	.attach_adapter	= smsc47m1_detect,
 	.detach_client	= smsc47m1_detach_client,
 };
@@ -394,7 +395,7 @@
 	int err = 0;
 	int fan1, fan2, pwm1, pwm2;
 
-	if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) {
+	if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.driver.name)) {
 		dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
 		return -EBUSY;
 	}
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index 6f696f8..cb01848 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -572,8 +572,9 @@
 /* The driver. I choose to use type i2c_driver, as at is identical to both
    smbus_driver and isa_driver, and clients could be of either kind */
 static struct i2c_driver via686a_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "via686a",
+	.driver = {
+		.name	= "via686a",
+	},
 	.attach_adapter	= via686a_detect,
 	.detach_client	= via686a_detach_client,
 };
@@ -615,7 +616,8 @@
 	}
 
 	/* Reserve the ISA region */
-	if (!request_region(address, VIA686A_EXTENT, via686a_driver.name)) {
+	if (!request_region(address, VIA686A_EXTENT,
+			    via686a_driver.driver.name)) {
 		dev_err(&adapter->dev, "region 0x%x already in use!\n",
 			address);
 		return -ENODEV;
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
new file mode 100644
index 0000000..d00a726
--- /dev/null
+++ b/drivers/hwmon/vt8231.c
@@ -0,0 +1,862 @@
+/*
+	vt8231.c - Part of lm_sensors, Linux kernel modules
+				for hardware monitoring
+
+	Copyright (c) 2005 Roger Lucas <roger@planbit.co.uk>
+	Copyright (c) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
+			   Aaron M. Marsh <amarsh@sdf.lonestar.org>
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This 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.
+*/
+
+/* Supports VIA VT8231 South Bridge embedded sensors
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/i2c-isa.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon-vid.h>
+#include <linux/err.h>
+#include <asm/io.h>
+
+static int force_addr;
+module_param(force_addr, int, 0);
+MODULE_PARM_DESC(force_addr, "Initialize the base address of the sensors");
+
+/* Device address
+   Note that we can't determine the ISA address until we have initialized
+   our module */
+static unsigned short isa_address;
+
+#define VT8231_EXTENT 0x80
+#define VT8231_BASE_REG 0x70
+#define VT8231_ENABLE_REG 0x74
+
+/* The VT8231 registers
+
+   The reset value for the input channel configuration is used (Reg 0x4A=0x07)
+   which sets the selected inputs marked with '*' below if multiple options are
+   possible:
+
+	            Voltage Mode	  Temperature Mode
+	Sensor	      Linux Id	      Linux Id        VIA Id
+	--------      --------	      --------        ------
+	CPU Diode	N/A		temp1		0
+	UIC1		in0		temp2 *		1
+	UIC2		in1 *		temp3   	2
+	UIC3		in2 *		temp4		3
+	UIC4		in3 *		temp5		4
+	UIC5		in4 *		temp6		5
+	3.3V		in5		N/A
+
+   Note that the BIOS may set the configuration register to a different value
+   to match the motherboard configuration.
+*/
+
+/* fans numbered 0-1 */
+#define VT8231_REG_FAN_MIN(nr)	(0x3b + (nr))
+#define VT8231_REG_FAN(nr)	(0x29 + (nr))
+
+/* Voltage inputs numbered 0-5 */
+
+static const u8 regvolt[]    = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26 };
+static const u8 regvoltmax[] = { 0x3d, 0x2b, 0x2d, 0x2f, 0x31, 0x33 };
+static const u8 regvoltmin[] = { 0x3e, 0x2c, 0x2e, 0x30, 0x32, 0x34 };
+
+/* Temperatures are numbered 1-6 according to the Linux kernel specification.
+**
+** In the VIA datasheet, however, the temperatures are numbered from zero.
+** Since it is important that this driver can easily be compared to the VIA
+** datasheet, we will use the VIA numbering within this driver and map the
+** kernel sysfs device name to the VIA number in the sysfs callback.
+*/
+
+#define VT8231_REG_TEMP_LOW01	0x49
+#define VT8231_REG_TEMP_LOW25	0x4d
+
+static const u8 regtemp[]    = { 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25 };
+static const u8 regtempmax[] = { 0x39, 0x3d, 0x2b, 0x2d, 0x2f, 0x31 };
+static const u8 regtempmin[] = { 0x3a, 0x3e, 0x2c, 0x2e, 0x30, 0x32 };
+
+#define TEMP_FROM_REG(reg)		(((253 * 4 - (reg)) * 550 + 105) / 210)
+#define TEMP_MAXMIN_FROM_REG(reg)	(((253 - (reg)) * 2200 + 105) / 210)
+#define TEMP_MAXMIN_TO_REG(val)		(253 - ((val) * 210 + 1100) / 2200)
+
+#define VT8231_REG_CONFIG 0x40
+#define VT8231_REG_ALARM1 0x41
+#define VT8231_REG_ALARM2 0x42
+#define VT8231_REG_FANDIV 0x47
+#define VT8231_REG_UCH_CONFIG 0x4a
+#define VT8231_REG_TEMP1_CONFIG 0x4b
+#define VT8231_REG_TEMP2_CONFIG 0x4c
+
+/* temps 0-5 as numbered in VIA datasheet - see later for mapping to Linux
+** numbering
+*/
+#define ISTEMP(i, ch_config) ((i) == 0 ? 1 : \
+			      ((ch_config) >> ((i)+1)) & 0x01)
+/* voltages 0-5 */
+#define ISVOLT(i, ch_config) ((i) == 5 ? 1 : \
+			      !(((ch_config) >> ((i)+2)) & 0x01))
+
+#define DIV_FROM_REG(val) (1 << (val))
+
+/* NB  The values returned here are NOT temperatures.  The calibration curves
+**     for the thermistor curves are board-specific and must go in the
+**     sensors.conf file.  Temperature sensors are actually ten bits, but the
+**     VIA datasheet only considers the 8 MSBs obtained from the regtemp[]
+**     register.  The temperature value returned should have a magnitude of 3,
+**     so we use the VIA scaling as the "true" scaling and use the remaining 2
+**     LSBs as fractional precision.
+**
+**     All the on-chip hardware temperature comparisons for the alarms are only
+**     8-bits wide, and compare against the 8 MSBs of the temperature.  The bits
+**     in the registers VT8231_REG_TEMP_LOW01 and VT8231_REG_TEMP_LOW25 are
+**     ignored.
+*/
+
+/******** FAN RPM CONVERSIONS ********
+** This chip saturates back at 0, not at 255 like many the other chips.
+** So, 0 means 0 RPM
+*/
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+	if (rpm == 0)
+		return 0;
+	return SENSORS_LIMIT(1310720 / (rpm * div), 1, 255);
+}
+
+#define FAN_FROM_REG(val, div) ((val) == 0 ? 0 : 1310720 / ((val) * (div)))
+
+struct vt8231_data {
+	struct i2c_client client;
+	struct semaphore update_lock;
+	struct class_device *class_dev;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u8 in[6];		/* Register value */
+	u8 in_max[6];		/* Register value */
+	u8 in_min[6];		/* Register value */
+	u16 temp[6];		/* Register value 10 bit, right aligned */
+	u8 temp_max[6];		/* Register value */
+	u8 temp_min[6];		/* Register value */
+	u8 fan[2];		/* Register value */
+	u8 fan_min[2];		/* Register value */
+	u8 fan_div[2];		/* Register encoding, shifted right */
+	u16 alarms;		/* Register encoding */
+	u8 uch_config;
+};
+
+static struct pci_dev *s_bridge;
+static int vt8231_detect(struct i2c_adapter *adapter);
+static int vt8231_detach_client(struct i2c_client *client);
+static struct vt8231_data *vt8231_update_device(struct device *dev);
+static void vt8231_init_client(struct i2c_client *client);
+
+static inline int vt8231_read_value(struct i2c_client *client, u8 reg)
+{
+	return inb_p(client->addr + reg);
+}
+
+static inline void vt8231_write_value(struct i2c_client *client, u8 reg,
+					u8 value)
+{
+	outb_p(value, client->addr + reg);
+}
+
+/* following are the sysfs callback functions */
+static ssize_t show_in(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct vt8231_data *data = vt8231_update_device(dev);
+
+	return sprintf(buf, "%d\n", ((data->in[nr] - 3) * 10000) / 958);
+}
+
+static ssize_t show_in_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct vt8231_data *data = vt8231_update_device(dev);
+
+	return sprintf(buf, "%d\n", ((data->in_min[nr] - 3) * 10000) / 958);
+}
+
+static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct vt8231_data *data = vt8231_update_device(dev);
+
+	return sprintf(buf, "%d\n", (((data->in_max[nr] - 3) * 10000) / 958));
+}
+
+static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255);
+	vt8231_write_value(client, regvoltmin[nr], data->in_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255);
+	vt8231_write_value(client, regvoltmax[nr], data->in_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+/* Special case for input 5 as this has 3.3V scaling built into the chip */
+static ssize_t show_in5(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct vt8231_data *data = vt8231_update_device(dev);
+
+	return sprintf(buf, "%d\n",
+		(((data->in[5] - 3) * 10000 * 54) / (958 * 34)));
+}
+
+static ssize_t show_in5_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct vt8231_data *data = vt8231_update_device(dev);
+
+	return sprintf(buf, "%d\n",
+		(((data->in_min[5] - 3) * 10000 * 54) / (958 * 34)));
+}
+
+static ssize_t show_in5_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct vt8231_data *data = vt8231_update_device(dev);
+
+	return sprintf(buf, "%d\n",
+		(((data->in_max[5] - 3) * 10000 * 54) / (958 * 34)));
+}
+
+static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3,
+					0, 255);
+	vt8231_write_value(client, regvoltmin[5], data->in_min[5]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3,
+					0, 255);
+	vt8231_write_value(client, regvoltmax[5], data->in_max[5]);
+	up(&data->update_lock);
+	return count;
+}
+
+#define define_voltage_sysfs(offset)				\
+static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,		\
+		show_in, NULL, offset);				\
+static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_in_min, set_in_min, offset);		\
+static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_in_max, set_in_max, offset)
+
+define_voltage_sysfs(0);
+define_voltage_sysfs(1);
+define_voltage_sysfs(2);
+define_voltage_sysfs(3);
+define_voltage_sysfs(4);
+
+static DEVICE_ATTR(in5_input, S_IRUGO, show_in5, NULL);
+static DEVICE_ATTR(in5_min, S_IRUGO | S_IWUSR, show_in5_min, set_in5_min);
+static DEVICE_ATTR(in5_max, S_IRUGO | S_IWUSR, show_in5_max, set_in5_max);
+
+/* Temperatures */
+static ssize_t show_temp0(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", data->temp[0] * 250);
+}
+
+static ssize_t show_temp0_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", data->temp_max[0] * 1000);
+}
+
+static ssize_t show_temp0_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", data->temp_min[0] * 1000);
+}
+
+static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255);
+	vt8231_write_value(client, regtempmax[0], data->temp_max[0]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255);
+	vt8231_write_value(client, regtempmin[0], data->temp_min[0]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr]));
+}
+
+static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_MAXMIN_FROM_REG(data->temp_max[nr]));
+}
+
+static ssize_t show_temp_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", TEMP_MAXMIN_FROM_REG(data->temp_min[nr]));
+}
+
+static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255);
+	vt8231_write_value(client, regtempmax[nr], data->temp_max[nr]);
+	up(&data->update_lock);
+	return count;
+}
+static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	int val = simple_strtol(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255);
+	vt8231_write_value(client, regtempmin[nr], data->temp_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+/* Note that these map the Linux temperature sensor numbering (1-6) to the VIA
+** temperature sensor numbering (0-5)
+*/
+#define define_temperature_sysfs(offset)				\
+static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO,		\
+		show_temp, NULL, offset - 1);				\
+static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR,	\
+		show_temp_max, set_temp_max, offset - 1);		\
+static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR,	\
+		show_temp_min, set_temp_min, offset - 1)
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp0, NULL);
+static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp0_max, set_temp0_max);
+static DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, show_temp0_min, set_temp0_min);
+
+define_temperature_sysfs(2);
+define_temperature_sysfs(3);
+define_temperature_sysfs(4);
+define_temperature_sysfs(5);
+define_temperature_sysfs(6);
+
+#define CFG_INFO_TEMP(id)	{ &sensor_dev_attr_temp##id##_input.dev_attr, \
+				&sensor_dev_attr_temp##id##_min.dev_attr, \
+				&sensor_dev_attr_temp##id##_max.dev_attr }
+#define CFG_INFO_VOLT(id)	{ &sensor_dev_attr_in##id##_input.dev_attr, \
+				&sensor_dev_attr_in##id##_min.dev_attr, \
+				&sensor_dev_attr_in##id##_max.dev_attr }
+
+struct str_device_attr_table {
+	struct device_attribute *input;
+	struct device_attribute *min;
+	struct device_attribute *max;
+};
+
+static struct str_device_attr_table cfg_info_temp[] = {
+	{ &dev_attr_temp1_input, &dev_attr_temp1_min, &dev_attr_temp1_max },
+	CFG_INFO_TEMP(2),
+	CFG_INFO_TEMP(3),
+	CFG_INFO_TEMP(4),
+	CFG_INFO_TEMP(5),
+	CFG_INFO_TEMP(6)
+};
+
+static struct str_device_attr_table cfg_info_volt[] = {
+	CFG_INFO_VOLT(0),
+	CFG_INFO_VOLT(1),
+	CFG_INFO_VOLT(2),
+	CFG_INFO_VOLT(3),
+	CFG_INFO_VOLT(4),
+	{ &dev_attr_in5_input, &dev_attr_in5_min, &dev_attr_in5_max }
+};
+
+/* Fans */
+static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+				DIV_FROM_REG(data->fan_div[nr])));
+}
+
+static ssize_t show_fan_min(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
+			DIV_FROM_REG(data->fan_div[nr])));
+}
+
+static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
+}
+
+static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	int nr = sensor_attr->index;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	int val = simple_strtoul(buf, NULL, 10);
+
+	down(&data->update_lock);
+	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+	vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
+	return count;
+}
+
+static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int nr = sensor_attr->index;
+	int old = vt8231_read_value(client, VT8231_REG_FANDIV);
+	long min = FAN_FROM_REG(data->fan_min[nr],
+				 DIV_FROM_REG(data->fan_div[nr]));
+
+	down(&data->update_lock);
+	switch (val) {
+	case 1: data->fan_div[nr] = 0; break;
+	case 2: data->fan_div[nr] = 1; break;
+	case 4: data->fan_div[nr] = 2; break;
+	case 8: data->fan_div[nr] = 3; break;
+	default:
+		dev_err(&client->dev, "fan_div value %ld not supported."
+		        "Choose one of 1, 2, 4 or 8!\n", val);
+		up(&data->update_lock);
+		return -EINVAL;
+	}
+
+	/* Correct the fan minimum speed */
+	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+	vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]);
+
+	old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
+	vt8231_write_value(client, VT8231_REG_FANDIV, old);
+	up(&data->update_lock);
+	return count;
+}
+
+
+#define define_fan_sysfs(offset)					\
+static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,			\
+		show_fan, NULL, offset - 1);				\
+static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,		\
+		show_fan_div, set_fan_div, offset - 1);			\
+static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,		\
+		show_fan_min, set_fan_min, offset - 1)
+
+define_fan_sysfs(1);
+define_fan_sysfs(2);
+
+/* Alarms */
+static ssize_t show_alarms(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct vt8231_data *data = vt8231_update_device(dev);
+	return sprintf(buf, "%d\n", data->alarms);
+}
+
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+static struct i2c_driver vt8231_driver = {
+	.driver = {
+		.name	= "vt8231",
+	},
+	.attach_adapter	= vt8231_detect,
+	.detach_client	= vt8231_detach_client,
+};
+
+static struct pci_device_id vt8231_pci_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
+
+static int __devinit vt8231_pci_probe(struct pci_dev *dev,
+			 	      const struct pci_device_id *id);
+
+static struct pci_driver vt8231_pci_driver = {
+	.name		= "vt8231",
+	.id_table	= vt8231_pci_ids,
+	.probe		= vt8231_pci_probe,
+};
+
+int vt8231_detect(struct i2c_adapter *adapter)
+{
+	struct i2c_client *client;
+	struct vt8231_data *data;
+	int err = 0, i;
+	u16 val;
+
+	/* 8231 requires multiple of 256 */
+	if (force_addr)	{
+		isa_address = force_addr & 0xFF00;
+		dev_warn(&adapter->dev, "forcing ISA address 0x%04X\n",
+				 isa_address);
+		if (PCIBIOS_SUCCESSFUL != pci_write_config_word(s_bridge,
+						VT8231_BASE_REG, isa_address))
+			return -ENODEV;
+	}
+
+	if (PCIBIOS_SUCCESSFUL !=
+		pci_read_config_word(s_bridge, VT8231_ENABLE_REG, &val))
+		return -ENODEV;
+
+	if (!(val & 0x0001)) {
+		dev_warn(&adapter->dev, "enabling sensors\n");
+		if (PCIBIOS_SUCCESSFUL !=
+			pci_write_config_word(s_bridge, VT8231_ENABLE_REG,
+							  val | 0x0001))
+			return -ENODEV;
+	}
+
+	/* Reserve the ISA region */
+	if (!request_region(isa_address, VT8231_EXTENT,
+			    vt8231_pci_driver.name)) {
+		dev_err(&adapter->dev, "region 0x%x already in use!\n",
+			   isa_address);
+		return -ENODEV;
+	}
+
+	if (!(data = kzalloc(sizeof(struct vt8231_data), GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto exit_release;
+	}
+
+	client = &data->client;
+	i2c_set_clientdata(client, data);
+	client->addr = isa_address;
+	client->adapter = adapter;
+	client->driver = &vt8231_driver;
+	client->dev.parent = &adapter->dev;
+
+	/* Fill in the remaining client fields and put into the global list */
+	strlcpy(client->name, "vt8231", I2C_NAME_SIZE);
+
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(client)))
+		goto exit_free;
+
+	vt8231_init_client(client);
+
+	/* Register sysfs hooks */
+	data->class_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->class_dev)) {
+		err = PTR_ERR(data->class_dev);
+		goto exit_detach;
+	}
+
+	/* Must update device information to find out the config field */
+	data->uch_config = vt8231_read_value(client, VT8231_REG_UCH_CONFIG);
+
+	for (i = 0; i < ARRAY_SIZE(cfg_info_temp); i++) {
+		if (ISTEMP(i, data->uch_config)) {
+			device_create_file(&client->dev,
+					   cfg_info_temp[i].input);
+			device_create_file(&client->dev, cfg_info_temp[i].max);
+			device_create_file(&client->dev, cfg_info_temp[i].min);
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(cfg_info_volt); i++) {
+		if (ISVOLT(i, data->uch_config)) {
+			device_create_file(&client->dev,
+					   cfg_info_volt[i].input);
+			device_create_file(&client->dev, cfg_info_volt[i].max);
+			device_create_file(&client->dev, cfg_info_volt[i].min);
+		}
+	}
+
+	device_create_file(&client->dev, &sensor_dev_attr_fan1_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_fan2_input.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_fan1_min.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_fan2_min.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_fan1_div.dev_attr);
+	device_create_file(&client->dev, &sensor_dev_attr_fan2_div.dev_attr);
+
+	device_create_file(&client->dev, &dev_attr_alarms);
+	return 0;
+
+exit_detach:
+	i2c_detach_client(client);
+exit_free:
+	kfree(data);
+exit_release:
+	release_region(isa_address, VT8231_EXTENT);
+	return err;
+}
+
+static int vt8231_detach_client(struct i2c_client *client)
+{
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	int err;
+
+	hwmon_device_unregister(data->class_dev);
+
+	if ((err = i2c_detach_client(client))) {
+		return err;
+	}
+
+	release_region(client->addr, VT8231_EXTENT);
+	kfree(data);
+
+	return 0;
+}
+
+static void vt8231_init_client(struct i2c_client *client)
+{
+	vt8231_write_value(client, VT8231_REG_TEMP1_CONFIG, 0);
+	vt8231_write_value(client, VT8231_REG_TEMP2_CONFIG, 0);
+}
+
+static struct vt8231_data *vt8231_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct vt8231_data *data = i2c_get_clientdata(client);
+	int i;
+	u16 low;
+
+	down(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		for (i = 0; i < 6; i++) {
+			if (ISVOLT(i, data->uch_config)) {
+				data->in[i] = vt8231_read_value(client,
+						regvolt[i]);
+				data->in_min[i] = vt8231_read_value(client,
+						regvoltmin[i]);
+				data->in_max[i] = vt8231_read_value(client,
+						regvoltmax[i]);
+			}
+		}
+		for (i = 0; i < 2; i++) {
+			data->fan[i] = vt8231_read_value(client,
+						VT8231_REG_FAN(i));
+			data->fan_min[i] = vt8231_read_value(client,
+						VT8231_REG_FAN_MIN(i));
+		}
+
+		low = vt8231_read_value(client, VT8231_REG_TEMP_LOW01);
+		low = (low >> 6) | ((low & 0x30) >> 2)
+		    | (vt8231_read_value(client, VT8231_REG_TEMP_LOW25) << 4);
+		for (i = 0; i < 6; i++) {
+			if (ISTEMP(i, data->uch_config)) {
+				data->temp[i] = (vt8231_read_value(client,
+						       regtemp[i]) << 2)
+						| ((low >> (2 * i)) & 0x03);
+				data->temp_max[i] = vt8231_read_value(client,
+						      regtempmax[i]);
+				data->temp_min[i] = vt8231_read_value(client,
+						      regtempmin[i]);
+			}
+		}
+
+		i = vt8231_read_value(client, VT8231_REG_FANDIV);
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = i >> 6;
+		data->alarms = vt8231_read_value(client, VT8231_REG_ALARM1) |
+			(vt8231_read_value(client, VT8231_REG_ALARM2) << 8);
+
+		/* Set alarm flags correctly */
+		if (!data->fan[0] && data->fan_min[0]) {
+			data->alarms |= 0x40;
+		} else if (data->fan[0] && !data->fan_min[0]) {
+			data->alarms &= ~0x40;
+		}
+
+		if (!data->fan[1] && data->fan_min[1]) {
+			data->alarms |= 0x80;
+		} else if (data->fan[1] && !data->fan_min[1]) {
+			data->alarms &= ~0x80;
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	up(&data->update_lock);
+
+	return data;
+}
+
+static int __devinit vt8231_pci_probe(struct pci_dev *dev,
+				const struct pci_device_id *id)
+{
+	u16 val;
+
+	if (PCIBIOS_SUCCESSFUL != pci_read_config_word(dev, VT8231_BASE_REG,
+							&val))
+		return -ENODEV;
+
+	isa_address = val & ~(VT8231_EXTENT - 1);
+	if (isa_address == 0 && force_addr == 0) {
+		dev_err(&dev->dev, "base address not set -\
+				 upgrade BIOS or use force_addr=0xaddr\n");
+		return -ENODEV;
+	}
+
+	s_bridge = pci_dev_get(dev);
+
+	if (i2c_isa_add_driver(&vt8231_driver)) {
+		pci_dev_put(s_bridge);
+		s_bridge = NULL;
+	}
+
+	/* Always return failure here.  This is to allow other drivers to bind
+	 * to this pci device.  We don't really want to have control over the
+	 * pci device, we only wanted to read as few register values from it.
+	 */
+	return -ENODEV;
+}
+
+static int __init sm_vt8231_init(void)
+{
+	return pci_module_init(&vt8231_pci_driver);
+}
+
+static void __exit sm_vt8231_exit(void)
+{
+	pci_unregister_driver(&vt8231_pci_driver);
+	if (s_bridge != NULL) {
+		i2c_isa_del_driver(&vt8231_driver);
+		pci_dev_put(s_bridge);
+		s_bridge = NULL;
+	}
+}
+
+MODULE_AUTHOR("Roger Lucas <roger@planbit.co.uk>");
+MODULE_DESCRIPTION("VT8231 sensors");
+MODULE_LICENSE("GPL");
+
+module_init(sm_vt8231_init);
+module_exit(sm_vt8231_exit);
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index eee22a5..12d79f5 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -676,7 +676,7 @@
 	int i, err = 0;
 
 	if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
-	                    w83627ehf_driver.name)) {
+	                    w83627ehf_driver.driver.name)) {
 		err = -EBUSY;
 		goto exit;
 	}
@@ -785,8 +785,9 @@
 }
 
 static struct i2c_driver w83627ehf_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "w83627ehf",
+	.driver = {
+		.name	= "w83627ehf",
+	},
 	.attach_adapter	= w83627ehf_detect,
 	.detach_client	= w83627ehf_detach_client,
 };
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index bbb3dcd..7ea441d 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -332,8 +332,9 @@
 static void w83627hf_init_client(struct i2c_client *client);
 
 static struct i2c_driver w83627hf_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "w83627hf",
+	.driver = {
+		.name	= "w83627hf",
+	},
 	.attach_adapter	= w83627hf_detect,
 	.detach_client	= w83627hf_detach_client,
 };
@@ -1009,7 +1010,7 @@
 		address = force_addr & WINB_ALIGNMENT;
 
 	if (!request_region(address + WINB_REGION_OFFSET, WINB_REGION_SIZE,
-	                    w83627hf_driver.name)) {
+	                    w83627hf_driver.driver.name)) {
 		err = -EBUSY;
 		goto ERROR0;
 	}
@@ -1122,11 +1123,10 @@
 	if (kind != w83697hf)
 		device_create_file_temp(new_client, 3);
 
-	if (kind != w83697hf)
+	if (kind != w83697hf && data->vid != 0xff) {
 		device_create_file_vid(new_client);
-
-	if (kind != w83697hf)
 		device_create_file_vrm(new_client);
+	}
 
 	device_create_file_fan_div(new_client, 1);
 	device_create_file_fan_div(new_client, 2);
@@ -1232,7 +1232,7 @@
 
 	/* Make sure the pins are configured for input
 	   There must be at least five (VRM 9), and possibly 6 (VRM 10) */
-	sel = superio_inb(W83627THF_GPIO5_IOSR);
+	sel = superio_inb(W83627THF_GPIO5_IOSR) & 0x3f;
 	if ((sel & 0x1f) != 0x1f) {
 		dev_dbg(&client->dev, "GPIO5 not configured for VID "
 			"function\n");
@@ -1323,19 +1323,18 @@
 		int hi = w83627hf_read_value(client, W83781D_REG_CHIPID);
 		data->vid = (lo & 0x0f) | ((hi & 0x01) << 4);
 	} else if (w83627thf == data->type) {
-		data->vid = w83627thf_read_gpio5(client) & 0x3f;
+		data->vid = w83627thf_read_gpio5(client);
 	}
 
 	/* Read VRM & OVT Config only once */
 	if (w83627thf == data->type || w83637hf == data->type) {
 		data->vrm_ovt = 
 			w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG);
-		data->vrm = (data->vrm_ovt & 0x01) ? 90 : 82;
-	} else {
-		/* Convert VID to voltage based on default VRM */
-		data->vrm = vid_which_vrm();
 	}
 
+	/* Convert VID to voltage based on VRM */
+	data->vrm = vid_which_vrm();
+
 	tmp = w83627hf_read_value(client, W83781D_REG_SCFG1);
 	for (i = 1; i <= 3; i++) {
 		if (!(tmp & BIT_SCFG1[i - 1])) {
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index ffdb3a0..5571148 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -269,17 +269,18 @@
 static void w83781d_init_client(struct i2c_client *client);
 
 static struct i2c_driver w83781d_driver = {
-	.owner = THIS_MODULE,
-	.name = "w83781d",
+	.driver = {
+		.name = "w83781d",
+	},
 	.id = I2C_DRIVERID_W83781D,
-	.flags = I2C_DF_NOTIFY,
 	.attach_adapter = w83781d_attach_adapter,
 	.detach_client = w83781d_detach_client,
 };
 
 static struct i2c_driver w83781d_isa_driver = {
-	.owner = THIS_MODULE,
-	.name = "w83781d-isa",
+	.driver = {
+		.name = "w83781d-isa",
+	},
 	.attach_adapter = w83781d_isa_attach_adapter,
 	.detach_client = w83781d_detach_client,
 };
@@ -1012,7 +1013,7 @@
 	
 	if (is_isa)
 		if (!request_region(address, W83781D_EXTENT,
-				    w83781d_isa_driver.name)) {
+				    w83781d_isa_driver.driver.name)) {
 			dev_dbg(&adapter->dev, "Request of region "
 				"0x%x-0x%x for w83781d failed\n", address,
 				address + W83781D_EXTENT - 1);
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 4be59db..b176bf0 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -193,6 +193,7 @@
 	  0xE2 }	/* (bit3-0) SmartFanII: Fan3 Level 3 */
 };
 
+#define W83792D_REG_GPIO_EN		0x1A
 #define W83792D_REG_CONFIG		0x40
 #define W83792D_REG_VID_FANDIV		0x47
 #define W83792D_REG_CHIPID		0x49
@@ -257,7 +258,7 @@
 {
 	int i;
 	val = SENSORS_LIMIT(val, 1, 128) >> 1;
-	for (i = 0; i < 6; i++) {
+	for (i = 0; i < 7; i++) {
 		if (val == 0)
 			break;
 		val >>= 1;
@@ -268,7 +269,6 @@
 struct w83792d_data {
 	struct i2c_client client;
 	struct class_device *class_dev;
-	struct semaphore lock;
 	enum chips type;
 
 	struct semaphore update_lock;
@@ -281,7 +281,7 @@
 	u8 in[9];		/* Register value */
 	u8 in_max[9];		/* Register value */
 	u8 in_min[9];		/* Register value */
-	u8 low_bits[2];		/* Additional resolution to voltage in0-6 */
+	u16 low_bits;		/* Additional resolution to voltage in6-0 */
 	u8 fan[7];		/* Register value */
 	u8 fan_min[7];		/* Register value */
 	u8 temp1[3];		/* current, over, thyst */
@@ -316,45 +316,17 @@
 static void w83792d_init_client(struct i2c_client *client);
 
 static struct i2c_driver w83792d_driver = {
-	.owner = THIS_MODULE,
-	.name = "w83792d",
-	.flags = I2C_DF_NOTIFY,
+	.driver = {
+		.name = "w83792d",
+	},
 	.attach_adapter = w83792d_attach_adapter,
 	.detach_client = w83792d_detach_client,
 };
 
-static long in_count_from_reg(int nr, struct w83792d_data *data)
+static inline long in_count_from_reg(int nr, struct w83792d_data *data)
 {
-	u16 vol_count = data->in[nr];
-	u16 low_bits = 0;
-	vol_count = (vol_count << 2);
-	switch (nr)
-	{
-	case 0:  /* vin0 */
-		low_bits = (data->low_bits[0]) & 0x03;
-		break;
-	case 1:  /* vin1 */
-		low_bits = ((data->low_bits[0]) & 0x0c) >> 2;
-		break;
-	case 2:  /* vin2 */
-		low_bits = ((data->low_bits[0]) & 0x30) >> 4;
-		break;
-	case 3:  /* vin3 */
-		low_bits = ((data->low_bits[0]) & 0xc0) >> 6;
-		break;
-	case 4:  /* vin4 */
-		low_bits = (data->low_bits[1]) & 0x03;
-		break;
-	case 5:  /* vin5 */
-		low_bits = ((data->low_bits[1]) & 0x0c) >> 2;
-		break;
-	case 6:  /* vin6 */
-		low_bits = ((data->low_bits[1]) & 0x30) >> 4;
-	default:
-		break;
-	}
-	vol_count = vol_count | low_bits;
-	return vol_count;
+	/* in7 and in8 do not have low bits, but the formula still works */
+	return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03));
 }
 
 /* following are the sysfs callback functions */
@@ -1191,7 +1163,6 @@
 	new_client = &data->client;
 	i2c_set_clientdata(new_client, data);
 	new_client->addr = address;
-	init_MUTEX(&data->lock);
 	new_client->adapter = adapter;
 	new_client->driver = &w83792d_driver;
 	new_client->flags = 0;
@@ -1242,7 +1213,7 @@
 			goto ERROR1;
 		}
 		val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID);
-		if (val1 == 0x7a && address >= 0x2c) {
+		if (val1 == 0x7a) {
 			kind = w83792d;
 		} else {
 			if (kind == 0)
@@ -1282,8 +1253,8 @@
 	w83792d_init_client(new_client);
 
 	/* A few vars need to be filled upon startup */
-	for (i = 1; i <= 7; i++) {
-		data->fan_min[i - 1] = w83792d_read_value(new_client,
+	for (i = 0; i < 7; i++) {
+		data->fan_min[i] = w83792d_read_value(new_client,
 					W83792D_REG_FAN_MIN[i]);
 	}
 
@@ -1306,10 +1277,20 @@
 	device_create_file_fan(new_client, 1);
 	device_create_file_fan(new_client, 2);
 	device_create_file_fan(new_client, 3);
-	device_create_file_fan(new_client, 4);
-	device_create_file_fan(new_client, 5);
-	device_create_file_fan(new_client, 6);
-	device_create_file_fan(new_client, 7);
+
+	/* Read GPIO enable register to check if pins for fan 4,5 are used as
+	   GPIO */
+	val1 = w83792d_read_value(new_client, W83792D_REG_GPIO_EN);
+	if (!(val1 & 0x40))
+		device_create_file_fan(new_client, 4);
+	if (!(val1 & 0x20))
+		device_create_file_fan(new_client, 5);
+
+	val1 = w83792d_read_value(new_client, W83792D_REG_PIN);
+	if (val1 & 0x40)
+		device_create_file_fan(new_client, 6);
+	if (val1 & 0x04)
+		device_create_file_fan(new_client, 7);
 
 	device_create_file_temp1(new_client);		/* Temp1 */
 	device_create_file_temp_add(new_client, 2);	/* Temp2 */
@@ -1405,26 +1386,17 @@
 	return 0;
 }
 
-/* The SMBus locks itself, usually, but nothing may access the Winbond between
-   bank switches. ISA access must always be locked explicitly!
-   We ignore the W83792D BUSY flag at this moment - it could lead to deadlocks,
-   would slow down the W83792D access and should not be necessary.
-   There are some ugly typecasts here, but the good news is - they should
-   nowhere else be necessary! */
-static int
-w83792d_read_value(struct i2c_client *client, u8 reg)
+/* The SMBus locks itself. The Winbond W83792D chip has a bank register,
+   but the driver only accesses registers in bank 0, so we don't have
+   to switch banks and lock access between switches. */
+static int w83792d_read_value(struct i2c_client *client, u8 reg)
 {
-	int res=0;
-	res = i2c_smbus_read_byte_data(client, reg);
-
-	return res;
+	return i2c_smbus_read_byte_data(client, reg);
 }
 
-static int
-w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
+static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
 {
-	i2c_smbus_write_byte_data(client, reg,  value);
-	return 0;
+	return i2c_smbus_write_byte_data(client, reg, value);
 }
 
 static void
@@ -1481,10 +1453,10 @@
 			data->in_min[i] = w83792d_read_value(client,
 						W83792D_REG_IN_MIN[i]);
 		}
-		data->low_bits[0] = w83792d_read_value(client,
-						W83792D_REG_LOW_BITS1);
-		data->low_bits[1] = w83792d_read_value(client,
-						W83792D_REG_LOW_BITS2);
+		data->low_bits = w83792d_read_value(client,
+						W83792D_REG_LOW_BITS1) +
+				 (w83792d_read_value(client,
+						W83792D_REG_LOW_BITS2) << 8);
 		for (i = 0; i < 7; i++) {
 			/* Update the Fan measured value and limits */
 			data->fan[i] = w83792d_read_value(client,
@@ -1495,7 +1467,7 @@
 			pwm_array_tmp[i] = w83792d_read_value(client,
 						W83792D_REG_PWM[i]);
 			data->pwm[i] = pwm_array_tmp[i] & 0x0f;
-			data->pwm_mode[i] = (pwm_array_tmp[i] >> 7) & 0x01;
+			data->pwm_mode[i] = pwm_array_tmp[i] >> 7;
 		}
 
 		reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG);
@@ -1596,8 +1568,8 @@
 		dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]);
 		dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]);
 	}
-	dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits[0]);
-	dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits[1]);
+	dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits & 0xff);
+	dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits >> 8);
 	dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n");
 	for (i=0; i<7; i++) {
 		dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]);
diff --git a/drivers/hwmon/w83l785ts.c b/drivers/hwmon/w83l785ts.c
index f495b63..f66c0cf 100644
--- a/drivers/hwmon/w83l785ts.c
+++ b/drivers/hwmon/w83l785ts.c
@@ -92,10 +92,10 @@
  */
  
 static struct i2c_driver w83l785ts_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "w83l785ts",
+	.driver = {
+		.name	= "w83l785ts",
+	},
 	.id		= I2C_DRIVERID_W83L785TS,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= w83l785ts_attach_adapter,
 	.detach_client	= w83l785ts_detach_client,
 };
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index ac3eafa..1c752dd 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -468,8 +468,7 @@
 		return -1;
 	}
 
-	if (hwpec)
-		outb_p(1, SMBAUXCTL);	/* enable hardware PEC */
+	outb_p(hwpec, SMBAUXCTL);	/* enable/disable hardware PEC */
 
 	if(block)
 		ret = i801_block_transaction(data, read_write, size, hwpec);
@@ -478,9 +477,6 @@
 		ret = i801_transaction();
 	}
 
-	if (hwpec)
-		outb_p(0, SMBAUXCTL);	/* disable hardware PEC */
-
 	if(block)
 		return ret;
 	if(ret)
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 1a58725..87fae93 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -725,6 +725,7 @@
 	strcpy(adap->name, "IBM IIC");
 	i2c_set_adapdata(adap, dev);
 	adap->id = I2C_HW_OCP;
+	adap->class = I2C_CLASS_HWMON;
 	adap->algo = &iic_algo;
 	adap->client_register = NULL;
 	adap->client_unregister = NULL;
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c
index 03672c9..9f2ffef 100644
--- a/drivers/i2c/busses/i2c-isa.c
+++ b/drivers/i2c/busses/i2c-isa.c
@@ -92,15 +92,13 @@
 	int res;
 
 	/* Add the driver to the list of i2c drivers in the driver core */
-	driver->driver.name = driver->name;
-	driver->driver.owner = driver->owner;
 	driver->driver.bus = &i2c_bus_type;
 	driver->driver.probe = i2c_isa_device_probe;
 	driver->driver.remove = i2c_isa_device_remove;
 	res = driver_register(&driver->driver);
 	if (res)
 		return res;
-	dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->name);
+	dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name);
 
 	/* Now look for clients */
 	driver->attach_adapter(&isa_adapter);
@@ -124,14 +122,14 @@
 		if ((res = driver->detach_client(client))) {
 			dev_err(&isa_adapter.dev, "Failed, driver "
 				"%s not unregistered!\n",
-				driver->name);
+				driver->driver.name);
 			return res;
 		}
 	}
 
 	/* Get the driver off the core list */
 	driver_unregister(&driver->driver);
-	dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->name);
+	dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->driver.name);
 
 	return 0;
 }
@@ -176,7 +174,7 @@
 	list_for_each_safe(item, _n, &isa_adapter.clients) {
 		client = list_entry(item, struct i2c_client, list);
 		dev_err(&isa_adapter.dev, "Driver %s still has an active "
-			"ISA client at 0x%x\n", client->driver->name,
+			"ISA client at 0x%x\n", client->driver->driver.name,
 			client->addr);
 	}
 	if (client != NULL)
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index afd7634..22781d8 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -1,6 +1,4 @@
 /*
- * drivers/i2c/busses/i2c-mv64xxx.c
- * 
  * Driver for the i2c controller on the Marvell line of host bridges for MIPS
  * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0).
  *
@@ -65,7 +63,6 @@
 	MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
 	MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK,
 	MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA,
-	MV64XXX_I2C_STATE_ABORTING,
 };
 
 /* Driver actions */
@@ -85,6 +82,7 @@
 	int			irq;
 	u32			state;
 	u32			action;
+	u32			aborting;
 	u32			cntl_bits;
 	void __iomem		*reg_base;
 	u32			reg_base_p;
@@ -122,12 +120,6 @@
 		return;
 	}
 
-	if (drv_data->state == MV64XXX_I2C_STATE_ABORTING) {
-		drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
-		drv_data->state = MV64XXX_I2C_STATE_IDLE;
-		return;
-	}
-
 	/* The status from the ctlr [mostly] tells us what to do next */
 	switch (status) {
 	/* Start condition interrupt */
@@ -148,14 +140,16 @@
 		/* FALLTHRU */
 	case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
 	case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
-		if (drv_data->bytes_left > 0) {
+		if ((drv_data->bytes_left == 0)
+				|| (drv_data->aborting
+					&& (drv_data->byte_posn != 0))) {
+			drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
+			drv_data->state = MV64XXX_I2C_STATE_IDLE;
+		} else {
 			drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA;
 			drv_data->state =
 				MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK;
 			drv_data->bytes_left--;
-		} else {
-			drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP;
-			drv_data->state = MV64XXX_I2C_STATE_IDLE;
 		}
 		break;
 
@@ -184,7 +178,7 @@
 		}
 		drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA;
 
-		if (drv_data->bytes_left == 1)
+		if ((drv_data->bytes_left == 1) || drv_data->aborting)
 			drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK;
 		break;
 
@@ -320,6 +314,7 @@
 	drv_data->msg = msg;
 	drv_data->byte_posn = 0;
 	drv_data->bytes_left = msg->len;
+	drv_data->aborting = 0;
 	drv_data->rc = 0;
 	drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK |
 		MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN;
@@ -359,17 +354,19 @@
 	}
 
 	if (abort && drv_data->block) {
-		drv_data->state = MV64XXX_I2C_STATE_ABORTING;
+		drv_data->aborting = 1;
 		spin_unlock_irqrestore(&drv_data->lock, flags);
 
 		time_left = wait_event_timeout(drv_data->waitq,
 			!drv_data->block,
 			msecs_to_jiffies(drv_data->adapter.timeout));
 
-		if (time_left <= 0) {
+		if ((time_left <= 0) && drv_data->block) {
 			drv_data->state = MV64XXX_I2C_STATE_IDLE;
 			dev_err(&drv_data->adapter.dev,
-				"mv64xxx: I2C bus locked\n");
+				"mv64xxx: I2C bus locked, block: %d, "
+				"time_left: %d\n", drv_data->block,
+				(int)time_left);
 		}
 	} else
 		spin_unlock_irqrestore(&drv_data->lock, flags);
@@ -510,7 +507,7 @@
 		goto exit_kfree;
 	}
 
-	strncpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
+	strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter",
 		I2C_NAME_SIZE);
 
 	init_waitqueue_head(&drv_data->waitq);
@@ -529,14 +526,15 @@
 	i2c_set_adapdata(&drv_data->adapter, drv_data);
 
 	if (request_irq(drv_data->irq, mv64xxx_i2c_intr, 0,
-		MV64XXX_I2C_CTLR_NAME, drv_data)) {
-
-		dev_err(dev, "mv64xxx: Can't register intr handler "
-			"irq: %d\n", drv_data->irq);
+			MV64XXX_I2C_CTLR_NAME, drv_data)) {
+		dev_err(&drv_data->adapter.dev,
+			"mv64xxx: Can't register intr handler irq: %d\n",
+			drv_data->irq);
 		rc = -EINVAL;
 		goto exit_unmap_regs;
 	} else if ((rc = i2c_add_adapter(&drv_data->adapter)) != 0) {
-		dev_err(dev, "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
+		dev_err(&drv_data->adapter.dev,
+			"mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
 		goto exit_free_irq;
 	}
 
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index 4d18e6e5..2d80eb2 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -30,6 +30,7 @@
     nForce3 Pro150 MCP		00D4
     nForce3 250Gb MCP		00E4
     nForce4 MCP			0052
+    nForce4 MCP-04		0034
 
     This driver supports the 2 SMBuses that are included in the MCP of the
     nForce2/3/4 chipsets.
@@ -257,6 +258,7 @@
 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) },
 	{ 0 }
 };
 
diff --git a/drivers/i2c/busses/i2c-parport.h b/drivers/i2c/busses/i2c-parport.h
index f63a537..d702e5e 100644
--- a/drivers/i2c/busses/i2c-parport.h
+++ b/drivers/i2c/busses/i2c-parport.h
@@ -80,6 +80,14 @@
 		.setscl	= { 0x01, DATA, 1 },
 		.getsda	= { 0x10, STAT, 1 },
 	},
+	/* type 6: Barco LPT->DVI (K5800236) adapter */
+	{
+		.setsda	= { 0x02, DATA, 1 },
+		.setscl	= { 0x01, DATA, 1 },
+		.getsda	= { 0x20, STAT, 0 },
+		.getscl	= { 0x40, STAT, 0 },
+		.init	= { 0xfc, DATA, 0 },
+	},
 };
 
 static int type;
@@ -91,4 +99,6 @@
 	" 2 = Velleman K8000 adapter\n"
 	" 3 = ELV adapter\n"
 	" 4 = ADM1032 evaluation board\n"
-	" 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n");
+	" 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n"
+	" 6 = Barco LPT->DVI (K5800236) adapter\n"
+);
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 58cfd31..f7d40f8 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -34,12 +34,12 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 
-#include <asm/hardware/clock.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/regs-iic.h>
 #include <asm/arch/iic.h>
@@ -738,7 +738,6 @@
 {
 	if (i2c->clk != NULL && !IS_ERR(i2c->clk)) {
 		clk_disable(i2c->clk);
-		clk_unuse(i2c->clk);
 		clk_put(i2c->clk);
 		i2c->clk = NULL;
 	}
@@ -778,7 +777,6 @@
 
 	dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
 
-	clk_use(i2c->clk);
 	clk_enable(i2c->clk);
 
 	/* map the registers */
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c
index 02682fb..93d483b 100644
--- a/drivers/i2c/chips/ds1337.c
+++ b/drivers/i2c/chips/ds1337.c
@@ -52,9 +52,9 @@
  * Driver data (common to all clients)
  */
 static struct i2c_driver ds1337_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "ds1337",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "ds1337",
+	},
 	.attach_adapter	= ds1337_attach_adapter,
 	.detach_client	= ds1337_detach_client,
 	.command	= ds1337_command,
@@ -337,13 +337,38 @@
 
 static void ds1337_init_client(struct i2c_client *client)
 {
-	s32 val;
+	u8 status, control;
 
-	/* Ensure that device is set in 24-hour mode */
-	val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
-	if ((val >= 0) && (val & (1 << 6)))
-		i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
-					  val & 0x3f);
+	/* On some boards, the RTC isn't configured by boot firmware.
+	 * Handle that case by starting/configuring the RTC now.
+	 */
+	status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
+	control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+
+	if ((status & 0x80) || (control & 0x80)) {
+		/* RTC not running */
+		u8 buf[16];
+		struct i2c_msg msg[1];
+
+		dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
+
+		/* Initialize all, including STATUS and CONTROL to zero */
+		memset(buf, 0, sizeof(buf));
+		msg[0].addr = client->addr;
+		msg[0].flags = 0;
+		msg[0].len = sizeof(buf);
+		msg[0].buf = &buf[0];
+
+		i2c_transfer(client->adapter, msg, 1);
+	} else {
+		/* Running: ensure that device is set in 24-hour mode */
+		s32 val;
+
+		val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR);
+		if ((val >= 0) && (val & (1 << 6)))
+			i2c_smbus_write_byte_data(client, DS1337_REG_HOUR,
+						  val & 0x3f);
+	}
 }
 
 static int ds1337_detach_client(struct i2c_client *client)
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c
index da488b7..0710b9d 100644
--- a/drivers/i2c/chips/ds1374.c
+++ b/drivers/i2c/chips/ds1374.c
@@ -232,10 +232,10 @@
 }
 
 static struct i2c_driver ds1374_driver = {
-	.owner = THIS_MODULE,
-	.name = DS1374_DRV_NAME,
+	.driver = {
+		.name	= DS1374_DRV_NAME,
+	},
 	.id = I2C_DRIVERID_DS1374,
-	.flags = I2C_DF_NOTIFY,
 	.attach_adapter = ds1374_attach,
 	.detach_client = ds1374_detach,
 };
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
index 4baf573..41116b7 100644
--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -68,10 +68,10 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver eeprom_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "eeprom",
+	.driver = {
+		.name	= "eeprom",
+	},
 	.id		= I2C_DRIVERID_EEPROM,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= eeprom_attach_adapter,
 	.detach_client	= eeprom_detach_client,
 };
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
index d2a100d..1251c7f 100644
--- a/drivers/i2c/chips/isp1301_omap.c
+++ b/drivers/i2c/chips/isp1301_omap.c
@@ -1632,11 +1632,11 @@
 }
 
 static struct i2c_driver isp1301_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "isp1301_omap",
+	.driver = {
+		.name	= "isp1301_omap",
+	},
 	.id		= 1301,		/* FIXME "official", i2c-ids.h */
 	.class		= I2C_CLASS_HWMON,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= isp1301_scan_bus,
 	.detach_client	= isp1301_detach_client,
 };
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c
index 3df309a..2dc3d48 100644
--- a/drivers/i2c/chips/m41t00.c
+++ b/drivers/i2c/chips/m41t00.c
@@ -211,10 +211,10 @@
 }
 
 static struct i2c_driver m41t00_driver = {
-	.owner		= THIS_MODULE,
-	.name		= M41T00_DRV_NAME,
+	.driver = {
+		.name	= M41T00_DRV_NAME,
+	},
 	.id		= I2C_DRIVERID_STM41T00,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= m41t00_attach,
 	.detach_client	= m41t00_detach,
 };
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c
index b376a00..6d3ff58 100644
--- a/drivers/i2c/chips/max6875.c
+++ b/drivers/i2c/chips/max6875.c
@@ -67,9 +67,9 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver max6875_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "max6875",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "max6875",
+	},
 	.attach_adapter	= max6875_attach_adapter,
 	.detach_client	= max6875_detach_client,
 };
diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c
index 59a9303..54b6e6a 100644
--- a/drivers/i2c/chips/pca9539.c
+++ b/drivers/i2c/chips/pca9539.c
@@ -38,9 +38,9 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver pca9539_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "pca9539",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "pca9539",
+	},
 	.attach_adapter	= pca9539_attach_adapter,
 	.detach_client	= pca9539_detach_client,
 };
diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c
index c323c2d..c3e6449 100644
--- a/drivers/i2c/chips/pcf8574.c
+++ b/drivers/i2c/chips/pcf8574.c
@@ -65,10 +65,10 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver pcf8574_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "pcf8574",
+	.driver = {
+		.name	= "pcf8574",
+	},
 	.id		= I2C_DRIVERID_PCF8574,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= pcf8574_attach_adapter,
 	.detach_client	= pcf8574_detach_client,
 };
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
index ce420a6..36cff09 100644
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/i2c/chips/pcf8591.c
@@ -88,10 +88,10 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver pcf8591_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "pcf8591",
+	.driver = {
+		.name	= "pcf8591",
+	},
 	.id		= I2C_DRIVERID_PCF8591,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= pcf8591_attach_adapter,
 	.detach_client	= pcf8591_detach_client,
 };
diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c
index 916cdc1..ceaa6b0 100644
--- a/drivers/i2c/chips/rtc8564.c
+++ b/drivers/i2c/chips/rtc8564.c
@@ -14,6 +14,7 @@
  */
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/bcd.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/string.h>
@@ -52,9 +53,6 @@
 #define CTRL1(c) _rtc8564_ctrl1(c)
 #define CTRL2(c) _rtc8564_ctrl2(c)
 
-#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
-#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
-
 static int debug;;
 module_param(debug, int, S_IRUGO | S_IWUSR);
 
@@ -157,7 +155,6 @@
 
 	strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE);
 	i2c_set_clientdata(new_client, d);
-	new_client->flags = I2C_CLIENT_ALLOW_USE;
 	new_client->addr = addr;
 	new_client->adapter = adap;
 	new_client->driver = &rtc8564_driver;
@@ -224,16 +221,16 @@
 		return ret;
 
 	/* century stored in minute alarm reg */
-	dt->year = BCD_TO_BIN(buf[RTC8564_REG_YEAR]);
-	dt->year += 100 * BCD_TO_BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
-	dt->mday = BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f);
-	dt->wday = BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7);
-	dt->mon = BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
+	dt->year = BCD2BIN(buf[RTC8564_REG_YEAR]);
+	dt->year += 100 * BCD2BIN(buf[RTC8564_REG_AL_MIN] & 0x3f);
+	dt->mday = BCD2BIN(buf[RTC8564_REG_DAY] & 0x3f);
+	dt->wday = BCD2BIN(buf[RTC8564_REG_WDAY] & 7);
+	dt->mon = BCD2BIN(buf[RTC8564_REG_MON_CENT] & 0x1f);
 
-	dt->secs = BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f);
+	dt->secs = BCD2BIN(buf[RTC8564_REG_SEC] & 0x7f);
 	dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80;
-	dt->mins = BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f);
-	dt->hours = BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f);
+	dt->mins = BCD2BIN(buf[RTC8564_REG_MIN] & 0x7f);
+	dt->hours = BCD2BIN(buf[RTC8564_REG_HR] & 0x3f);
 
 	_DBGRTCTM(2, *dt);
 
@@ -255,18 +252,18 @@
 
 	buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP;
 	buf[RTC8564_REG_CTRL2] = CTRL2(client);
-	buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->secs);
-	buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->mins);
-	buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->hours);
+	buf[RTC8564_REG_SEC] = BIN2BCD(dt->secs);
+	buf[RTC8564_REG_MIN] = BIN2BCD(dt->mins);
+	buf[RTC8564_REG_HR] = BIN2BCD(dt->hours);
 
 	if (datetoo) {
 		len += 5;
-		buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->mday);
-		buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->wday);
-		buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->mon) & 0x1f;
+		buf[RTC8564_REG_DAY] = BIN2BCD(dt->mday);
+		buf[RTC8564_REG_WDAY] = BIN2BCD(dt->wday);
+		buf[RTC8564_REG_MON_CENT] = BIN2BCD(dt->mon) & 0x1f;
 		/* century stored in minute alarm reg */
-		buf[RTC8564_REG_YEAR] = BIN_TO_BCD(dt->year % 100);
-		buf[RTC8564_REG_AL_MIN] = BIN_TO_BCD(dt->year / 100);
+		buf[RTC8564_REG_YEAR] = BIN2BCD(dt->year % 100);
+		buf[RTC8564_REG_AL_MIN] = BIN2BCD(dt->year / 100);
 	}
 
 	ret = rtc8564_write(client, 0, buf, len);
@@ -361,10 +358,10 @@
 }
 
 static struct i2c_driver rtc8564_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "RTC8564",
+	.driver = {
+		.name	= "RTC8564",
+	},
 	.id		= I2C_DRIVERID_RTC8564,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter = rtc8564_probe,
 	.detach_client	= rtc8564_detach,
 	.command	= rtc8564_command
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c
index 280dd7a..1af3dfb 100644
--- a/drivers/i2c/chips/tps65010.c
+++ b/drivers/i2c/chips/tps65010.c
@@ -494,6 +494,7 @@
 {
 	struct tps65010		*tps;
 	int			status;
+	unsigned long		irqflags;
 
 	if (the_tps) {
 		dev_dbg(&bus->dev, "only one %s for now\n", DRIVER_NAME);
@@ -520,13 +521,14 @@
 	}
 
 #ifdef	CONFIG_ARM
+	irqflags = SA_SAMPLE_RANDOM | SA_TRIGGER_LOW;
 	if (machine_is_omap_h2()) {
 		tps->model = TPS65010;
 		omap_cfg_reg(W4_GPIO58);
 		tps->irq = OMAP_GPIO_IRQ(58);
 		omap_request_gpio(58);
 		omap_set_gpio_direction(58, 1);
-		set_irq_type(tps->irq, IRQT_FALLING);
+		irqflags |= SA_TRIGGER_FALLING;
 	}
 	if (machine_is_omap_osk()) {
 		tps->model = TPS65010;
@@ -534,7 +536,7 @@
 		tps->irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1));
 		omap_request_gpio(OMAP_MPUIO(1));
 		omap_set_gpio_direction(OMAP_MPUIO(1), 1);
-		set_irq_type(tps->irq, IRQT_FALLING);
+		irqflags |= SA_TRIGGER_FALLING;
 	}
 	if (machine_is_omap_h3()) {
 		tps->model = TPS65013;
@@ -542,13 +544,12 @@
 		// FIXME set up this board's IRQ ...
 	}
 #else
-#define set_irq_type(num,trigger)	do{}while(0)
+	irqflags = SA_SAMPLE_RANDOM;
 #endif
 
 	if (tps->irq > 0) {
-		set_irq_type(tps->irq, IRQT_LOW);
 		status = request_irq(tps->irq, tps65010_irq,
-			SA_SAMPLE_RANDOM, DRIVER_NAME, tps);
+			irqflags, DRIVER_NAME, tps);
 		if (status < 0) {
 			dev_dbg(&tps->client.dev, "can't get IRQ %d, err %d\n",
 					tps->irq, status);
@@ -637,9 +638,9 @@
 }
 
 static struct i2c_driver tps65010_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "tps65010",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "tps65010",
+	},
 	.attach_adapter	= tps65010_scan_bus,
 	.detach_client	= __exit_p(tps65010_detach_client),
 };
diff --git a/drivers/i2c/chips/x1205.c b/drivers/i2c/chips/x1205.c
index 7da366c..245fffa 100644
--- a/drivers/i2c/chips/x1205.c
+++ b/drivers/i2c/chips/x1205.c
@@ -105,9 +105,9 @@
 	void *arg);
 
 static struct i2c_driver x1205_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "x1205",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "x1205",
+	},
 	.attach_adapter = &x1205_attach,
 	.detach_client	= &x1205_detach,
 };
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 82ea1b7..52b7747 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -197,7 +197,7 @@
 	/* inform drivers of new adapters */
 	list_for_each(item,&drivers) {
 		driver = list_entry(item, struct i2c_driver, list);
-		if (driver->flags & I2C_DF_NOTIFY)
+		if (driver->attach_adapter)
 			/* We ignore the return code; if it fails, too bad */
 			driver->attach_adapter(adap);
 	}
@@ -235,7 +235,8 @@
 		if (driver->detach_adapter)
 			if ((res = driver->detach_adapter(adap))) {
 				dev_err(&adap->dev, "detach_adapter failed "
-					"for driver [%s]\n", driver->name);
+					"for driver [%s]\n",
+					driver->driver.name);
 				goto out_unlock;
 			}
 	}
@@ -245,10 +246,6 @@
 	list_for_each_safe(item, _n, &adap->clients) {
 		client = list_entry(item, struct i2c_client, list);
 
-		/* detaching devices is unconditional of the set notify
-		 * flag, as _all_ clients that reside on the adapter
-		 * must be deleted, as this would cause invalid states.
-		 */
 		if ((res=client->driver->detach_client(client))) {
 			dev_err(&adap->dev, "detach_client failed for client "
 				"[%s] at address 0x%02x\n", client->name,
@@ -286,7 +283,7 @@
  * chips.
  */
 
-int i2c_add_driver(struct i2c_driver *driver)
+int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
 {
 	struct list_head   *item;
 	struct i2c_adapter *adapter;
@@ -295,8 +292,7 @@
 	down(&core_lists);
 
 	/* add the driver to the list of i2c drivers in the driver core */
-	driver->driver.owner = driver->owner;
-	driver->driver.name = driver->name;
+	driver->driver.owner = owner;
 	driver->driver.bus = &i2c_bus_type;
 	driver->driver.probe = i2c_device_probe;
 	driver->driver.remove = i2c_device_remove;
@@ -306,10 +302,10 @@
 		goto out_unlock;
 	
 	list_add_tail(&driver->list,&drivers);
-	pr_debug("i2c-core: driver [%s] registered\n", driver->name);
+	pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
 
 	/* now look for instances of driver on our adapters */
-	if (driver->flags & I2C_DF_NOTIFY) {
+	if (driver->attach_adapter) {
 		list_for_each(item,&adapters) {
 			adapter = list_entry(item, struct i2c_adapter, list);
 			driver->attach_adapter(adapter);
@@ -320,6 +316,7 @@
 	up(&core_lists);
 	return res;
 }
+EXPORT_SYMBOL(i2c_register_driver);
 
 int i2c_del_driver(struct i2c_driver *driver)
 {
@@ -334,17 +331,14 @@
 	/* Have a look at each adapter, if clients of this driver are still
 	 * attached. If so, detach them to be able to kill the driver 
 	 * afterwards.
-	 *
-	 * Removing clients does not depend on the notify flag, else
-	 * invalid operation might (will!) result, when using stale client
-	 * pointers.
 	 */
 	list_for_each(item1,&adapters) {
 		adap = list_entry(item1, struct i2c_adapter, list);
 		if (driver->detach_adapter) {
 			if ((res = driver->detach_adapter(adap))) {
 				dev_err(&adap->dev, "detach_adapter failed "
-					"for driver [%s]\n", driver->name);
+					"for driver [%s]\n",
+					driver->driver.name);
 				goto out_unlock;
 			}
 		} else {
@@ -368,7 +362,7 @@
 
 	driver_unregister(&driver->driver);
 	list_del(&driver->list);
-	pr_debug("i2c-core: driver [%s] unregistered\n", driver->name);
+	pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
 
  out_unlock:
 	up(&core_lists);
@@ -419,8 +413,7 @@
 		}
 	}
 
-	if (client->flags & I2C_CLIENT_ALLOW_USE)
-		client->usage_count = 0;
+	client->usage_count = 0;
 
 	client->dev.parent = &client->adapter->dev;
 	client->dev.driver = &client->driver->driver;
@@ -443,8 +436,7 @@
 	struct i2c_adapter *adapter = client->adapter;
 	int res = 0;
 	
-	if ((client->flags & I2C_CLIENT_ALLOW_USE)
-	 && (client->usage_count > 0)) {
+	if (client->usage_count > 0) {
 		dev_warn(&client->dev, "Client [%s] still busy, "
 			 "can't detach\n", client->name);
 		return -EBUSY;
@@ -475,10 +467,10 @@
 static int i2c_inc_use_client(struct i2c_client *client)
 {
 
-	if (!try_module_get(client->driver->owner))
+	if (!try_module_get(client->driver->driver.owner))
 		return -ENODEV;
 	if (!try_module_get(client->adapter->owner)) {
-		module_put(client->driver->owner);
+		module_put(client->driver->driver.owner);
 		return -ENODEV;
 	}
 
@@ -487,7 +479,7 @@
 
 static void i2c_dec_use_client(struct i2c_client *client)
 {
-	module_put(client->driver->owner);
+	module_put(client->driver->driver.owner);
 	module_put(client->adapter->owner);
 }
 
@@ -499,33 +491,20 @@
 	if (ret)
 		return ret;
 
-	if (client->flags & I2C_CLIENT_ALLOW_USE) {
-		if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)
-			client->usage_count++;
-		else if (client->usage_count > 0) 
-			goto busy;
-		else 
-			client->usage_count++;
-	}
+	client->usage_count++;
 
 	return 0;
- busy:
-	i2c_dec_use_client(client);
-	return -EBUSY;
 }
 
 int i2c_release_client(struct i2c_client *client)
 {
-	if(client->flags & I2C_CLIENT_ALLOW_USE) {
-		if(client->usage_count>0)
-			client->usage_count--;
-		else {
-			pr_debug("i2c-core: %s used one too many times\n",
-				__FUNCTION__);
-			return -EPERM;
-		}
+	if (!client->usage_count) {
+		pr_debug("i2c-core: %s used one too many times\n",
+			 __FUNCTION__);
+		return -EPERM;
 	}
 	
+	client->usage_count--;
 	i2c_dec_use_client(client);
 	
 	return 0;
@@ -539,14 +518,14 @@
 	down(&adap->clist_lock);
 	list_for_each(item,&adap->clients) {
 		client = list_entry(item, struct i2c_client, list);
-		if (!try_module_get(client->driver->owner))
+		if (!try_module_get(client->driver->driver.owner))
 			continue;
 		if (NULL != client->driver->command) {
 			up(&adap->clist_lock);
 			client->driver->command(client,cmd,arg);
 			down(&adap->clist_lock);
 		}
-		module_put(client->driver->owner);
+		module_put(client->driver->driver.owner);
        }
        up(&adap->clist_lock);
 }
@@ -1147,7 +1126,6 @@
 
 EXPORT_SYMBOL(i2c_add_adapter);
 EXPORT_SYMBOL(i2c_del_adapter);
-EXPORT_SYMBOL(i2c_add_driver);
 EXPORT_SYMBOL(i2c_del_driver);
 EXPORT_SYMBOL(i2c_attach_client);
 EXPORT_SYMBOL(i2c_detach_client);
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 8af0bd1..ed7eed3 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -42,8 +42,7 @@
 struct i2c_dev {
 	int minor;
 	struct i2c_adapter *adap;
-	struct class_device class_dev;
-	struct completion released;	/* FIXME, we need a class_device_unregister() */
+	struct class_device *class_dev;
 };
 #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev)
 
@@ -105,7 +104,10 @@
 
 static ssize_t show_adapter_name(struct class_device *class_dev, char *buf)
 {
-	struct i2c_dev *i2c_dev = to_i2c_dev(class_dev);
+	struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt));
+
+	if (!i2c_dev)
+		return -ENODEV;
 	return sprintf(buf, "%s\n", i2c_dev->adap->name);
 }
 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL);
@@ -408,21 +410,12 @@
 	.release	= i2cdev_release,
 };
 
-static void release_i2c_dev(struct class_device *dev)
-{
-	struct i2c_dev *i2c_dev = to_i2c_dev(dev);
-	complete(&i2c_dev->released);
-}
-
-static struct class i2c_dev_class = {
-	.name		= "i2c-dev",
-	.release	= &release_i2c_dev,
-};
+static struct class *i2c_dev_class;
 
 static int i2cdev_attach_adapter(struct i2c_adapter *adap)
 {
 	struct i2c_dev *i2c_dev;
-	int retval;
+	struct device *dev;
 
 	i2c_dev = get_free_i2c_dev(adap);
 	if (IS_ERR(i2c_dev))
@@ -434,21 +427,20 @@
 	/* register this i2c device with the driver core */
 	i2c_dev->adap = adap;
 	if (adap->dev.parent == &platform_bus)
-		i2c_dev->class_dev.dev = &adap->dev;
+		dev = &adap->dev;
 	else
-		i2c_dev->class_dev.dev = adap->dev.parent;
-	i2c_dev->class_dev.class = &i2c_dev_class;
-	i2c_dev->class_dev.devt = MKDEV(I2C_MAJOR, i2c_dev->minor);
-	snprintf(i2c_dev->class_dev.class_id, BUS_ID_SIZE, "i2c-%d", i2c_dev->minor);
-	retval = class_device_register(&i2c_dev->class_dev);
-	if (retval)
+		dev = adap->dev.parent;
+	i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL,
+						 MKDEV(I2C_MAJOR, i2c_dev->minor),
+						 dev, "i2c-%d", i2c_dev->minor);
+	if (!i2c_dev->class_dev)
 		goto error;
-	class_device_create_file(&i2c_dev->class_dev, &class_device_attr_name);
+	class_device_create_file(i2c_dev->class_dev, &class_device_attr_name);
 	return 0;
 error:
 	return_i2c_dev(i2c_dev);
 	kfree(i2c_dev);
-	return retval;
+	return -ENODEV;
 }
 
 static int i2cdev_detach_adapter(struct i2c_adapter *adap)
@@ -459,10 +451,8 @@
 	if (!i2c_dev)
 		return -ENODEV;
 
-	init_completion(&i2c_dev->released);
 	return_i2c_dev(i2c_dev);
-	class_device_unregister(&i2c_dev->class_dev);
-	wait_for_completion(&i2c_dev->released);
+	class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, i2c_dev->minor));
 	kfree(i2c_dev);
 
 	pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name);
@@ -474,21 +464,14 @@
 	return 0;
 }
 
-static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
-                           void *arg)
-{
-	return -1;
-}
-
 static struct i2c_driver i2cdev_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "dev_driver",
+	.driver = {
+		.name	= "dev_driver",
+	},
 	.id		= I2C_DRIVERID_I2CDEV,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= i2cdev_attach_adapter,
 	.detach_adapter	= i2cdev_detach_adapter,
 	.detach_client	= i2cdev_detach_client,
-	.command	= i2cdev_command,
 };
 
 static struct i2c_client i2cdev_client_template = {
@@ -507,8 +490,8 @@
 	if (res)
 		goto out;
 
-	res = class_register(&i2c_dev_class);
-	if (res)
+	i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
+	if (IS_ERR(i2c_dev_class))
 		goto out_unreg_chrdev;
 
 	res = i2c_add_driver(&i2cdev_driver);
@@ -518,7 +501,7 @@
 	return 0;
 
 out_unreg_class:
-	class_unregister(&i2c_dev_class);
+	class_destroy(i2c_dev_class);
 out_unreg_chrdev:
 	unregister_chrdev(I2C_MAJOR, "i2c");
 out:
@@ -529,7 +512,7 @@
 static void __exit i2c_dev_exit(void)
 {
 	i2c_del_driver(&i2cdev_driver);
-	class_unregister(&i2c_dev_class);
+	class_destroy(i2c_dev_class);
 	unregister_chrdev(I2C_MAJOR,"i2c");
 }
 
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 31e649a..1c81174 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -807,14 +807,6 @@
        depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
 endchoice
 
-config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
-        bool "Enable burstable Mode on DbDMA"
-        default false
-        depends BLK_DEV_IDE_AU1XXX
-        help
-          This option enable the burstable Flag on DbDMA controller
-          (cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY").
-
 config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
        int "Maximum transfer size (KB) per request (up to 128)"
        default "128"
@@ -940,7 +932,7 @@
 
 config BLK_DEV_MPC8xx_IDE
 	bool "MPC8xx IDE support"
-	depends on 8xx
+	depends on 8xx && IDE=y && BLK_DEV_IDE=y
 	help
 	  This option provides support for IDE on Motorola MPC8xx Systems.
 	  Please see 'Type of MPC8xx IDE interface' for details.
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 9455e42..d31117e 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -614,7 +614,7 @@
 			 */
 			spin_lock_irqsave(&ide_lock, flags);
 			end_that_request_chunk(failed, 0, failed->data_len);
-			end_that_request_last(failed);
+			end_that_request_last(failed, 0);
 			spin_unlock_irqrestore(&ide_lock, flags);
 		}
 
@@ -1292,7 +1292,6 @@
 	struct cdrom_info *info = drive->driver_data;
 
 	info->dma = 0;
-	info->cmd = 0;
 	info->start_seek = jiffies;
 	return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
 }
@@ -1344,8 +1343,6 @@
 	    (rq->nr_sectors & (sectors_per_frame - 1)))
 		info->dma = 0;
 
-	info->cmd = READ;
-
 	/* Start sending the read request to the drive. */
 	return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation);
 }
@@ -1484,7 +1481,6 @@
 	struct cdrom_info *info = drive->driver_data;
 
 	info->dma = 0;
-	info->cmd = 0;
 	rq->flags &= ~REQ_FAILED;
 	len = rq->data_len;
 
@@ -1739,7 +1735,7 @@
 
 	spin_lock_irqsave(&ide_lock, flags);
 	blkdev_dequeue_request(rq);
-	end_that_request_last(rq);
+	end_that_request_last(rq, 1);
 	HWGROUP(drive)->rq = NULL;
 	spin_unlock_irqrestore(&ide_lock, flags);
 	return ide_stopped;
@@ -1891,7 +1887,6 @@
 	/* use dma, if possible. we don't need to check more, since we
 	 * know that the transfer is always (at least!) frame aligned */
 	info->dma = drive->using_dma ? 1 : 0;
-	info->cmd = WRITE;
 
 	info->devinfo.media_written = 1;
 
@@ -1916,7 +1911,6 @@
 	rq->flags |= REQ_QUIET;
 
 	info->dma = 0;
-	info->cmd = 0;
 
 	/*
 	 * sg request
@@ -1925,7 +1919,6 @@
 		int mask = drive->queue->dma_alignment;
 		unsigned long addr = (unsigned long) page_address(bio_page(rq->bio));
 
-		info->cmd = rq_data_dir(rq);
 		info->dma = drive->using_dma;
 
 		/*
@@ -3516,6 +3509,7 @@
 	return driver_register(&ide_cdrom_driver.gen_driver);
 }
 
+MODULE_ALIAS("ide:*m-cdrom*");
 module_init(ide_cdrom_init);
 module_exit(ide_cdrom_exit);
 MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 7ca3e5a..ad1f2ed 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -480,7 +480,6 @@
 
 	struct request request_sense_request;
 	int dma;
-	int cmd;
 	unsigned long last_block;
 	unsigned long start_seek;
 	/* Buffer to hold mechanism status and changer slot table. */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index f4e3d35..cab362e 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -681,50 +681,9 @@
 
 #endif	/* CONFIG_PROC_FS */
 
-static void idedisk_end_flush(request_queue_t *q, struct request *flush_rq)
+static void idedisk_prepare_flush(request_queue_t *q, struct request *rq)
 {
 	ide_drive_t *drive = q->queuedata;
-	struct request *rq = flush_rq->end_io_data;
-	int good_sectors = rq->hard_nr_sectors;
-	int bad_sectors;
-	sector_t sector;
-
-	if (flush_rq->errors & ABRT_ERR) {
-		printk(KERN_ERR "%s: barrier support doesn't work\n", drive->name);
-		blk_queue_ordered(drive->queue, QUEUE_ORDERED_NONE);
-		blk_queue_issue_flush_fn(drive->queue, NULL);
-		good_sectors = 0;
-	} else if (flush_rq->errors) {
-		good_sectors = 0;
-		if (blk_barrier_preflush(rq)) {
-			sector = ide_get_error_location(drive,flush_rq->buffer);
-			if ((sector >= rq->hard_sector) &&
-			    (sector < rq->hard_sector + rq->hard_nr_sectors))
-				good_sectors = sector - rq->hard_sector;
-		}
-	}
-
-	if (flush_rq->errors)
-		printk(KERN_ERR "%s: failed barrier write: "
-				"sector=%Lx(good=%d/bad=%d)\n",
-				drive->name, (unsigned long long)rq->sector,
-				good_sectors,
-				(int) (rq->hard_nr_sectors-good_sectors));
-
-	bad_sectors = rq->hard_nr_sectors - good_sectors;
-
-	if (good_sectors)
-		__ide_end_request(drive, rq, 1, good_sectors);
-	if (bad_sectors)
-		__ide_end_request(drive, rq, 0, bad_sectors);
-}
-
-static int idedisk_prepare_flush(request_queue_t *q, struct request *rq)
-{
-	ide_drive_t *drive = q->queuedata;
-
-	if (!drive->wcache)
-		return 0;
 
 	memset(rq->cmd, 0, sizeof(rq->cmd));
 
@@ -735,9 +694,8 @@
 		rq->cmd[0] = WIN_FLUSH_CACHE;
 
 
-	rq->flags |= REQ_DRIVE_TASK | REQ_SOFTBARRIER;
+	rq->flags |= REQ_DRIVE_TASK;
 	rq->buffer = rq->cmd;
-	return 1;
 }
 
 static int idedisk_issue_flush(request_queue_t *q, struct gendisk *disk,
@@ -794,27 +752,64 @@
 	return 0;
 }
 
+static void update_ordered(ide_drive_t *drive)
+{
+	struct hd_driveid *id = drive->id;
+	unsigned ordered = QUEUE_ORDERED_NONE;
+	prepare_flush_fn *prep_fn = NULL;
+	issue_flush_fn *issue_fn = NULL;
+
+	if (drive->wcache) {
+		unsigned long long capacity;
+		int barrier;
+		/*
+		 * We must avoid issuing commands a drive does not
+		 * understand or we may crash it. We check flush cache
+		 * is supported. We also check we have the LBA48 flush
+		 * cache if the drive capacity is too large. By this
+		 * time we have trimmed the drive capacity if LBA48 is
+		 * not available so we don't need to recheck that.
+		 */
+		capacity = idedisk_capacity(drive);
+		barrier = ide_id_has_flush_cache(id) &&
+			(drive->addressing == 0 || capacity <= (1ULL << 28) ||
+			 ide_id_has_flush_cache_ext(id));
+
+		printk(KERN_INFO "%s: cache flushes %ssupported\n",
+		       drive->name, barrier ? "" : "not");
+
+		if (barrier) {
+			ordered = QUEUE_ORDERED_DRAIN_FLUSH;
+			prep_fn = idedisk_prepare_flush;
+			issue_fn = idedisk_issue_flush;
+		}
+	} else
+		ordered = QUEUE_ORDERED_DRAIN;
+
+	blk_queue_ordered(drive->queue, ordered, prep_fn);
+	blk_queue_issue_flush_fn(drive->queue, issue_fn);
+}
+
 static int write_cache(ide_drive_t *drive, int arg)
 {
 	ide_task_t args;
-	int err;
+	int err = 1;
 
-	if (!ide_id_has_flush_cache(drive->id))
-		return 1;
-
-	memset(&args, 0, sizeof(ide_task_t));
-	args.tfRegister[IDE_FEATURE_OFFSET]	= (arg) ?
+	if (ide_id_has_flush_cache(drive->id)) {
+		memset(&args, 0, sizeof(ide_task_t));
+		args.tfRegister[IDE_FEATURE_OFFSET]	= (arg) ?
 			SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
-	args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SETFEATURES;
-	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
-	args.handler				= &task_no_data_intr;
+		args.tfRegister[IDE_COMMAND_OFFSET]	= WIN_SETFEATURES;
+		args.command_type		= IDE_DRIVE_TASK_NO_DATA;
+		args.handler			= &task_no_data_intr;
+		err = ide_raw_taskfile(drive, &args, NULL);
+		if (err == 0)
+			drive->wcache = arg;
+	}
 
-	err = ide_raw_taskfile(drive, &args, NULL);
-	if (err)
-		return err;
+	update_ordered(drive);
 
-	drive->wcache = arg;
-	return 0;
+	return err;
 }
 
 static int do_idedisk_flushcache (ide_drive_t *drive)
@@ -888,7 +883,6 @@
 {
 	struct hd_driveid *id = drive->id;
 	unsigned long long capacity;
-	int barrier;
 
 	idedisk_add_settings(drive);
 
@@ -992,31 +986,6 @@
 		drive->wcache = 1;
 
 	write_cache(drive, 1);
-
-	/*
-	 * We must avoid issuing commands a drive does not understand
-	 * or we may crash it. We check flush cache is supported. We also
-	 * check we have the LBA48 flush cache if the drive capacity is
-	 * too large. By this time we have trimmed the drive capacity if
-	 * LBA48 is not available so we don't need to recheck that.
-	 */
-	barrier = 0;
-	if (ide_id_has_flush_cache(id))
-		barrier = 1;
-	if (drive->addressing == 1) {
-		/* Can't issue the correct flush ? */
-		if (capacity > (1ULL << 28) && !ide_id_has_flush_cache_ext(id))
-			barrier = 0;
-	}
-
-	printk(KERN_INFO "%s: cache flushes %ssupported\n",
-		drive->name, barrier ? "" : "not ");
-	if (barrier) {
-		blk_queue_ordered(drive->queue, QUEUE_ORDERED_FLUSH);
-		drive->queue->prepare_flush_fn = idedisk_prepare_flush;
-		drive->queue->end_flush_fn = idedisk_end_flush;
-		blk_queue_issue_flush_fn(drive->queue, idedisk_issue_flush);
-	}
 }
 
 static void ide_cacheflush_p(ide_drive_t *drive)
@@ -1034,12 +1003,12 @@
 	struct ide_disk_obj *idkp = drive->driver_data;
 	struct gendisk *g = idkp->disk;
 
-	ide_cacheflush_p(drive);
-
 	ide_unregister_subdriver(drive, idkp->driver);
 
 	del_gendisk(g);
 
+	ide_cacheflush_p(drive);
+
 	ide_disk_put(idkp);
 
 	return 0;
@@ -1161,6 +1130,17 @@
 	return 0;
 }
 
+static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
+	ide_drive_t *drive = idkp->drive;
+
+	geo->heads = drive->bios_head;
+	geo->sectors = drive->bios_sect;
+	geo->cylinders = (u16)drive->bios_cyl; /* truncate */
+	return 0;
+}
+
 static int idedisk_ioctl(struct inode *inode, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
@@ -1195,6 +1175,7 @@
 	.open		= idedisk_open,
 	.release	= idedisk_release,
 	.ioctl		= idedisk_ioctl,
+	.getgeo		= idedisk_getgeo,
 	.media_changed	= idedisk_media_changed,
 	.revalidate_disk= idedisk_revalidate_disk
 };
@@ -1271,6 +1252,7 @@
 	return driver_register(&idedisk_driver.gen_driver);
 }
 
+MODULE_ALIAS("ide:*m-disk*");
 module_init(idedisk_init);
 module_exit(idedisk_exit);
 MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 1e15313..0523da7 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -90,11 +90,6 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
-struct drive_list_entry {
-	const char *id_model;
-	const char *id_firmware;
-};
-
 static const struct drive_list_entry drive_whitelist [] = {
 
 	{ "Micropolis 2112A"	,       "ALL"		},
@@ -139,7 +134,7 @@
 };
 
 /**
- *	in_drive_list	-	look for drive in black/white list
+ *	ide_in_drive_list	-	look for drive in black/white list
  *	@id: drive identifier
  *	@drive_table: list to inspect
  *
@@ -147,7 +142,7 @@
  *	Returns 1 if the drive is found in the table.
  */
 
-static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
+int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
 {
 	for ( ; drive_table->id_model ; drive_table++)
 		if ((!strcmp(drive_table->id_model, id->model)) &&
@@ -157,6 +152,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(ide_in_drive_list);
+
 /**
  *	ide_dma_intr	-	IDE DMA interrupt handler
  *	@drive: the drive the interrupt is for
@@ -663,7 +660,7 @@
 {
 	struct hd_driveid *id = drive->id;
 
-	int blacklist = in_drive_list(id, drive_blacklist);
+	int blacklist = ide_in_drive_list(id, drive_blacklist);
 	if (blacklist) {
 		printk(KERN_WARNING "%s: Disabling (U)DMA for %s (blacklisted)\n",
 				    drive->name, id->model);
@@ -677,7 +674,7 @@
 int __ide_dma_good_drive (ide_drive_t *drive)
 {
 	struct hd_driveid *id = drive->id;
-	return in_drive_list(id, drive_whitelist);
+	return ide_in_drive_list(id, drive_whitelist);
 }
 
 EXPORT_SYMBOL(__ide_dma_good_drive);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 9e293c8..5945f55 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -2031,6 +2031,17 @@
 	return 0;
 }
 
+static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk);
+	ide_drive_t *drive = floppy->drive;
+
+	geo->heads = drive->bios_head;
+	geo->sectors = drive->bios_sect;
+	geo->cylinders = (u16)drive->bios_cyl; /* truncate */
+	return 0;
+}
+
 static int idefloppy_ioctl(struct inode *inode, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
@@ -2120,6 +2131,7 @@
 	.open		= idefloppy_open,
 	.release	= idefloppy_release,
 	.ioctl		= idefloppy_ioctl,
+	.getgeo		= idefloppy_getgeo,
 	.media_changed	= idefloppy_media_changed,
 	.revalidate_disk= idefloppy_revalidate_disk
 };
@@ -2197,6 +2209,7 @@
 	return driver_register(&idefloppy_driver.gen_driver);
 }
 
+MODULE_ALIAS("ide:*m-floppy*");
 module_init(idefloppy_init);
 module_exit(idefloppy_exit);
 MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index ecfafcd..b5dc6df 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -89,7 +89,7 @@
 
 		blkdev_dequeue_request(rq);
 		HWGROUP(drive)->rq = NULL;
-		end_that_request_last(rq);
+		end_that_request_last(rq, uptodate);
 		ret = 0;
 	}
 	return ret;
@@ -119,10 +119,7 @@
 	if (!nr_sectors)
 		nr_sectors = rq->hard_cur_sectors;
 
-	if (blk_complete_barrier_rq_locked(drive->queue, rq, nr_sectors))
-		ret = rq->nr_sectors != 0;
-	else
-		ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
+	ret = __ide_end_request(drive, rq, uptodate, nr_sectors);
 
 	spin_unlock_irqrestore(&ide_lock, flags);
 	return ret;
@@ -247,7 +244,7 @@
 	}
 	blkdev_dequeue_request(rq);
 	HWGROUP(drive)->rq = NULL;
-	end_that_request_last(rq);
+	end_that_request_last(rq, 1);
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
@@ -379,7 +376,7 @@
 	blkdev_dequeue_request(rq);
 	HWGROUP(drive)->rq = NULL;
 	rq->errors = err;
-	end_that_request_last(rq);
+	end_that_request_last(rq, !rq->errors);
 	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 7d7944e..fab9b2b 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -4947,6 +4947,7 @@
 	return error;
 }
 
+MODULE_ALIAS("ide:*m-tape*");
 module_init(idetape_init);
 module_exit(idetape_exit);
 MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 8af179b..b069b13 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1278,19 +1278,6 @@
 	up(&ide_setting_sem);
 
 	switch (cmd) {
-		case HDIO_GETGEO:
-		{
-			struct hd_geometry geom;
-			if (!p || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL;
-			geom.heads = drive->bios_head;
-			geom.sectors = drive->bios_sect;
-			geom.cylinders = (u16)drive->bios_cyl; /* truncate */
-			geom.start = get_start_sect(bdev);
-			if (copy_to_user(p, &geom, sizeof(struct hd_geometry)))
-				return -EFAULT;
-			return 0;
-		}
-
 		case HDIO_OBSOLETE_IDENTITY:
 		case HDIO_GET_IDENTITY:
 			if (bdev != bdev->bd_contains)
@@ -1904,9 +1891,69 @@
 	return 1;
 }
 
+static char *media_string(ide_drive_t *drive)
+{
+	switch (drive->media) {
+	case ide_disk:
+		return "disk";
+	case ide_cdrom:
+		return "cdrom";
+	case ide_tape:
+		return "tape";
+	case ide_floppy:
+		return "floppy";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	ide_drive_t *drive = to_ide_device(dev);
+	return sprintf(buf, "%s\n", media_string(drive));
+}
+
+static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	ide_drive_t *drive = to_ide_device(dev);
+	return sprintf(buf, "%s\n", drive->name);
+}
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	ide_drive_t *drive = to_ide_device(dev);
+	return sprintf(buf, "ide:m-%s\n", media_string(drive));
+}
+
+static struct device_attribute ide_dev_attrs[] = {
+	__ATTR_RO(media),
+	__ATTR_RO(drivename),
+	__ATTR_RO(modalias),
+	__ATTR_NULL
+};
+
+static int ide_uevent(struct device *dev, char **envp, int num_envp,
+		      char *buffer, int buffer_size)
+{
+	ide_drive_t *drive = to_ide_device(dev);
+	int i = 0;
+	int length = 0;
+
+	add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+		       "MEDIA=%s", media_string(drive));
+	add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+		       "DRIVENAME=%s", drive->name);
+	add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
+		       "MODALIAS=ide:m-%s", media_string(drive));
+	envp[i] = NULL;
+	return 0;
+}
+
 struct bus_type ide_bus_type = {
 	.name		= "ide",
 	.match		= ide_bus_match,
+	.uevent		= ide_uevent,
+	.dev_attrs	= ide_dev_attrs,
 	.suspend	= generic_ide_suspend,
 	.resume		= generic_ide_resume,
 };
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c
index 242029c..6439dec6 100644
--- a/drivers/ide/legacy/hd.c
+++ b/drivers/ide/legacy/hd.c
@@ -658,22 +658,14 @@
 	enable_irq(HD_IRQ);
 }
 
-static int hd_ioctl(struct inode * inode, struct file * file,
-	unsigned int cmd, unsigned long arg)
+static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data;
-	struct hd_geometry __user *loc = (struct hd_geometry __user *) arg;
-	struct hd_geometry g; 
+	struct hd_i_struct *disk = bdev->bd_disk->private_data;
 
-	if (cmd != HDIO_GETGEO)
-		return -EINVAL;
-	if (!loc)
-		return -EINVAL;
-	g.heads = disk->head;
-	g.sectors = disk->sect;
-	g.cylinders = disk->cyl;
-	g.start = get_start_sect(inode->i_bdev);
-	return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
+	geo->heads = disk->head;
+	geo->sectors = disk->sect;
+	geo->cylinders = disk->cyl;
+	return 0;
 }
 
 /*
@@ -695,7 +687,7 @@
 }
 
 static struct block_device_operations hd_fops = {
-	.ioctl =	hd_ioctl,
+	.getgeo =	hd_getgeo,
 };
 
 /*
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index ef79805..4c2af90 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -88,15 +88,12 @@
 } ide_info_t;
 
 static void ide_release(dev_link_t *);
-static int ide_event(event_t event, int priority,
-		     event_callback_args_t *args);
+static void ide_config(dev_link_t *);
 
-static dev_info_t dev_info = "ide-cs";
+static void ide_detach(struct pcmcia_device *p_dev);
 
-static dev_link_t *ide_attach(void);
-static void ide_detach(dev_link_t *);
 
-static dev_link_t *dev_list = NULL;
+
 
 /*======================================================================
 
@@ -106,18 +103,17 @@
 
 ======================================================================*/
 
-static dev_link_t *ide_attach(void)
+static int ide_attach(struct pcmcia_device *p_dev)
 {
     ide_info_t *info;
     dev_link_t *link;
-    client_reg_t client_reg;
-    int ret;
-    
+
     DEBUG(0, "ide_attach()\n");
 
     /* Create new ide device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
+    if (!info)
+	return -ENOMEM;
     link = &info->link; link->priv = info;
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -128,21 +124,14 @@
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	ide_detach(link);
-	return NULL;
-    }
-    
-    return link;
+
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    ide_config(link);
+
+    return 0;
 } /* ide_attach */
 
 /*======================================================================
@@ -154,32 +143,16 @@
 
 ======================================================================*/
 
-static void ide_detach(dev_link_t *link)
+static void ide_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
-    int ret;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "ide_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
 
     if (link->state & DEV_CONFIG)
 	ide_release(link);
-    
-    if (link->handle) {
-	ret = pcmcia_deregister_client(link->handle);
-	if (ret != CS_SUCCESS)
-	    cs_error(link->handle, DeregisterClient, ret);
-    }
-    
-    /* Unlink, free device structure */
-    *linkp = link->next;
+
     kfree(link->priv);
-    
 } /* ide_detach */
 
 static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
@@ -406,6 +379,28 @@
 
 } /* ide_release */
 
+static int ide_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int ide_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -415,48 +410,15 @@
     
 ======================================================================*/
 
-int ide_event(event_t event, int priority,
-	      event_callback_args_t *args)
-{
-    dev_link_t *link = args->client_data;
-
-    DEBUG(1, "ide_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-		ide_release(link);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	ide_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (DEV_OK(link))
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	break;
-    }
-    return 0;
-} /* ide_event */
-
 static struct pcmcia_device_id ide_ids[] = {
 	PCMCIA_DEVICE_FUNC_ID(4),
+	PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000),	/* Hitachi */
 	PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
 	PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),
 	PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),	/* Toshiba */
 	PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
 	PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),	/* Samsung */
+ 	PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),	/* Hitachi */
 	PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
 	PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200),	/* Lexar */
 	PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0),
@@ -471,6 +433,8 @@
 	PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),
 	PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),
 	PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e),
+	PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae),
+	PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),
 	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -494,10 +458,11 @@
 	.drv		= {
 		.name	= "ide-cs",
 	},
-	.attach		= ide_attach,
-	.event		= ide_event,
-	.detach		= ide_detach,
+	.probe		= ide_attach,
+	.remove		= ide_detach,
 	.id_table       = ide_ids,
+	.suspend	= ide_suspend,
+	.resume		= ide_resume,
 };
 
 static int __init init_ide_cs(void)
@@ -508,7 +473,6 @@
 static void __exit exit_ide_cs(void)
 {
 	pcmcia_unregister_driver(&ide_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 late_initcall(init_ide_cs);
diff --git a/drivers/ide/mips/Makefile b/drivers/ide/mips/Makefile
index 578e52a..677c7b2 100644
--- a/drivers/ide/mips/Makefile
+++ b/drivers/ide/mips/Makefile
@@ -1 +1,4 @@
 obj-$(CONFIG_BLK_DEV_IDE_SWARM)		+= swarm.o
+obj-$(CONFIG_BLK_DEV_IDE_AU1XXX)	+= au1xxx-ide.o
+
+EXTRA_CFLAGS    := -Idrivers/ide
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 2b6327c..32431dc 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -31,865 +31,638 @@
  */
 #undef REALLY_SLOW_IO           /* most systems can safely undef this */
 
-#include <linux/config.h>       /* for CONFIG_BLK_DEV_IDEPCI */
 #include <linux/types.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
+#include <linux/platform_device.h>
+
 #include <linux/init.h>
 #include <linux/ide.h>
 #include <linux/sysdev.h>
 
 #include <linux/dma-mapping.h>
 
+#include "ide-timing.h"
+
 #include <asm/io.h>
 #include <asm/mach-au1x00/au1xxx.h>
 #include <asm/mach-au1x00/au1xxx_dbdma.h>
 
-#if CONFIG_PM
-#include <asm/mach-au1x00/au1xxx_pm.h>
-#endif
-
 #include <asm/mach-au1x00/au1xxx_ide.h>
 
 #define DRV_NAME	"au1200-ide"
 #define DRV_VERSION	"1.0"
-#define DRV_AUTHOR	"AMD PCS / Pete Popov <ppopov@embeddedalley.com>"
-#define DRV_DESC	"Au1200 IDE"
+#define DRV_AUTHOR	"Enrico Walther <enrico.walther@amd.com> / Pete Popov <ppopov@embeddedalley.com>"
+
+/* enable the burstmode in the dbdma */
+#define IDE_AU1XXX_BURSTMODE	1
 
 static _auide_hwif auide_hwif;
-static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED;
-static int dbdma_init_done = 0;
+static int dbdma_init_done;
 
-/*
- * local I/O functions
- */
-u8 auide_inb(unsigned long port)
-{
-        return (au_readb(port));
-}
-
-u16 auide_inw(unsigned long port)
-{
-        return (au_readw(port));
-}
-
-u32 auide_inl(unsigned long port)
-{
-        return (au_readl(port));
-}
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
 
 void auide_insw(unsigned long port, void *addr, u32 count)
 {
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
+	_auide_hwif *ahwif = &auide_hwif;
+	chan_tab_t *ctp;
+	au1x_ddma_desc_t *dp;
 
-        _auide_hwif *ahwif = &auide_hwif;
-        chan_tab_t *ctp;
-        au1x_ddma_desc_t *dp;
-
-        if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
-				DDMA_FLAGS_NOIE)) {
-                printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
-                return;
-        }
-        ctp = *((chan_tab_t **)ahwif->rx_chan);
-        dp = ctp->cur_ptr;
-        while (dp->dscr_cmd0 & DSCR_CMD0_V)
-                ;
-        ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
-#else
-        while (count--)
-        {
-                *(u16 *)addr = au_readw(port);
-                addr +=2 ;
-        }
-#endif
-}
-
-void auide_insl(unsigned long port, void *addr, u32 count)
-{
-        while (count--)
-        {
-                *(u32 *)addr = au_readl(port);
-                /* NOTE: For IDE interfaces over PCMCIA,
-                 * 32-bit access does not work
-                 */
-                addr += 4;
-        }
-}
-
-void auide_outb(u8 addr, unsigned long port)
-{
-        return (au_writeb(addr, port));
-}
-
-void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
-{
-        return (au_writeb(addr, port));
-}
-
-void auide_outw(u16 addr, unsigned long port)
-{
-        return (au_writew(addr, port));
-}
-
-void auide_outl(u32 addr, unsigned long port)
-{
-        return (au_writel(addr, port));
+	if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1, 
+			   DDMA_FLAGS_NOIE)) {
+		printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+		return;
+	}
+	ctp = *((chan_tab_t **)ahwif->rx_chan);
+	dp = ctp->cur_ptr;
+	while (dp->dscr_cmd0 & DSCR_CMD0_V)
+		;
+	ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
 }
 
 void auide_outsw(unsigned long port, void *addr, u32 count)
 {
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
-        _auide_hwif *ahwif = &auide_hwif;
-        chan_tab_t *ctp;
-        au1x_ddma_desc_t *dp;
+	_auide_hwif *ahwif = &auide_hwif;
+	chan_tab_t *ctp;
+	au1x_ddma_desc_t *dp;
 
-        if(!put_source_flags(ahwif->tx_chan, (void*)addr,
-                                          count << 1, DDMA_FLAGS_NOIE)) {
-                printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
-                return;
-        }
-        ctp = *((chan_tab_t **)ahwif->tx_chan);
-        dp = ctp->cur_ptr;
-        while (dp->dscr_cmd0 & DSCR_CMD0_V)
-                ;
-        ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
-#else
-        while (count--)
-        {
-                au_writew(*(u16 *)addr, port);
-                addr += 2;
-        }
+	if(!put_source_flags(ahwif->tx_chan, (void*)addr,
+			     count << 1, DDMA_FLAGS_NOIE)) {
+		printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+		return;
+	}
+	ctp = *((chan_tab_t **)ahwif->tx_chan);
+	dp = ctp->cur_ptr;
+	while (dp->dscr_cmd0 & DSCR_CMD0_V)
+		;
+	ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
+}
+
 #endif
-}
-
-void auide_outsl(unsigned long port, void *addr, u32 count)
-{
-        while (count--)
-        {
-                au_writel(*(u32 *)addr, port);
-                /* NOTE: For IDE interfaces over PCMCIA,
-                 * 32-bit access does not work
-                 */
-                addr += 4;
-        }
-}
 
 static void auide_tune_drive(ide_drive_t *drive, byte pio)
 {
-        int mem_sttime;
-        int mem_stcfg;
-        unsigned long flags;
-        u8 speed;
+	int mem_sttime;
+	int mem_stcfg;
+	u8 speed;
 
-        /* get the best pio mode for the drive */
-        pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+	/* get the best pio mode for the drive */
+	pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
 
-        printk("%s: setting Au1XXX IDE to PIO mode%d\n",
-                drive->name, pio);
+	printk(KERN_INFO "%s: setting Au1XXX IDE to PIO mode%d\n",
+	       drive->name, pio);
 
-        spin_lock_irqsave(&ide_tune_drive_spin_lock, flags);
+	mem_sttime = 0;
+	mem_stcfg  = au_readl(MEM_STCFG2);
 
-        mem_sttime = 0;
-        mem_stcfg  = au_readl(MEM_STCFG2);
+	/* set pio mode! */
+	switch(pio) {
+	case 0:
+		mem_sttime = SBC_IDE_TIMING(PIO0);
 
-        /* set pio mode! */
-        switch(pio) {
-                case 0:
-                        /* set timing parameters for RCS2# */
-                        mem_sttime =   SBC_IDE_PIO0_TWCS
-                                     | SBC_IDE_PIO0_TCSH
-                                     | SBC_IDE_PIO0_TCSOFF
-                                     | SBC_IDE_PIO0_TWP
-                                     | SBC_IDE_PIO0_TCSW
-                                     | SBC_IDE_PIO0_TPM
-                                     | SBC_IDE_PIO0_TA;
-                        /* set configuration for RCS2# */
-                        mem_stcfg |= TS_MASK;
-                        mem_stcfg &= ~TCSOE_MASK;
-                        mem_stcfg &= ~TOECS_MASK;
-                        mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
+		/* set configuration for RCS2# */
+		mem_stcfg |= TS_MASK;
+		mem_stcfg &= ~TCSOE_MASK;
+		mem_stcfg &= ~TOECS_MASK;
+		mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
+		break;
 
-                        au_writel(mem_sttime,MEM_STTIME2);
-                        au_writel(mem_stcfg,MEM_STCFG2);
-                        break;
+	case 1:
+		mem_sttime = SBC_IDE_TIMING(PIO1);
 
-                case 1:
-                        /* set timing parameters for RCS2# */
-                        mem_sttime =   SBC_IDE_PIO1_TWCS
-                                     | SBC_IDE_PIO1_TCSH
-                                     | SBC_IDE_PIO1_TCSOFF
-                                     | SBC_IDE_PIO1_TWP
-                                     | SBC_IDE_PIO1_TCSW
-                                     | SBC_IDE_PIO1_TPM
-                                     | SBC_IDE_PIO1_TA;
-                        /* set configuration for RCS2# */
-                        mem_stcfg |= TS_MASK;
-                        mem_stcfg &= ~TCSOE_MASK;
-                        mem_stcfg &= ~TOECS_MASK;
-                        mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
-                        break;
+		/* set configuration for RCS2# */
+		mem_stcfg |= TS_MASK;
+		mem_stcfg &= ~TCSOE_MASK;
+		mem_stcfg &= ~TOECS_MASK;
+		mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
+		break;
 
-                case 2:
-                        /* set timing parameters for RCS2# */
-                        mem_sttime =   SBC_IDE_PIO2_TWCS
-                                     | SBC_IDE_PIO2_TCSH
-                                     | SBC_IDE_PIO2_TCSOFF
-                                     | SBC_IDE_PIO2_TWP
-                                     | SBC_IDE_PIO2_TCSW
-                                     | SBC_IDE_PIO2_TPM
-                                     | SBC_IDE_PIO2_TA;
-                        /* set configuration for RCS2# */
-                        mem_stcfg &= ~TS_MASK;
-                        mem_stcfg &= ~TCSOE_MASK;
-                        mem_stcfg &= ~TOECS_MASK;
-                        mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
-                        break;
+	case 2:
+		mem_sttime = SBC_IDE_TIMING(PIO2);
 
-                case 3:
-                        /* set timing parameters for RCS2# */
-                        mem_sttime =   SBC_IDE_PIO3_TWCS
-                                     | SBC_IDE_PIO3_TCSH
-                                     | SBC_IDE_PIO3_TCSOFF
-                                     | SBC_IDE_PIO3_TWP
-                                     | SBC_IDE_PIO3_TCSW
-                                     | SBC_IDE_PIO3_TPM
-                                     | SBC_IDE_PIO3_TA;
-                        /* set configuration for RCS2# */
-                        mem_stcfg |= TS_MASK;
-                        mem_stcfg &= ~TS_MASK;
-                        mem_stcfg &= ~TCSOE_MASK;
-                        mem_stcfg &= ~TOECS_MASK;
-                        mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
+		/* set configuration for RCS2# */
+		mem_stcfg &= ~TS_MASK;
+		mem_stcfg &= ~TCSOE_MASK;
+		mem_stcfg &= ~TOECS_MASK;
+		mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
+		break;
 
-                        break;
+	case 3:
+		mem_sttime = SBC_IDE_TIMING(PIO3);
 
-                case 4:
-                        /* set timing parameters for RCS2# */
-                        mem_sttime =   SBC_IDE_PIO4_TWCS
-                                     | SBC_IDE_PIO4_TCSH
-                                     | SBC_IDE_PIO4_TCSOFF
-                                     | SBC_IDE_PIO4_TWP
-                                     | SBC_IDE_PIO4_TCSW
-                                     | SBC_IDE_PIO4_TPM
-                                     | SBC_IDE_PIO4_TA;
-                        /* set configuration for RCS2# */
-                        mem_stcfg &= ~TS_MASK;
-                        mem_stcfg &= ~TCSOE_MASK;
-                        mem_stcfg &= ~TOECS_MASK;
-                        mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
-                        break;
-        }
+		/* set configuration for RCS2# */
+		mem_stcfg &= ~TS_MASK;
+		mem_stcfg &= ~TCSOE_MASK;
+		mem_stcfg &= ~TOECS_MASK;
+		mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
 
-        au_writel(mem_sttime,MEM_STTIME2);
-        au_writel(mem_stcfg,MEM_STCFG2);
+		break;
 
-        spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags);
+	case 4:
+		mem_sttime = SBC_IDE_TIMING(PIO4);
 
-        speed = pio + XFER_PIO_0;
-        ide_config_drive_speed(drive, speed);
+		/* set configuration for RCS2# */
+		mem_stcfg &= ~TS_MASK;
+		mem_stcfg &= ~TCSOE_MASK;
+		mem_stcfg &= ~TOECS_MASK;
+		mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
+		break;
+	}
+
+	au_writel(mem_sttime,MEM_STTIME2);
+	au_writel(mem_stcfg,MEM_STCFG2);
+
+	speed = pio + XFER_PIO_0;
+	ide_config_drive_speed(drive, speed);
 }
 
 static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
 {
-        u8 mode = 0;
-        int mem_sttime;
-        int mem_stcfg;
-        unsigned long flags;
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-        struct hd_driveid *id = drive->id;
+	int mem_sttime;
+	int mem_stcfg;
+	unsigned long mode;
 
-        /*
-         * Now see what the current drive is capable of,
-         * selecting UDMA only if the mate said it was ok.
-         */
-        if (id && (id->capability & 1) && drive->autodma &&
-            !__ide_dma_bad_drive(drive)) {
-                if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
-                        if      (id->dma_mword & 4)
-                                mode = XFER_MW_DMA_2;
-                        else if (id->dma_mword & 2)
-                                mode = XFER_MW_DMA_1;
-                        else if (id->dma_mword & 1)
-                                mode = XFER_MW_DMA_0;
-                }
-        }
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+	if (ide_use_dma(drive))
+		mode = ide_dma_speed(drive, 0);
 #endif
 
-        spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags);
+	mem_sttime = 0;
+	mem_stcfg  = au_readl(MEM_STCFG2);
 
-        mem_sttime = 0;
-        mem_stcfg  = au_readl(MEM_STCFG2);
-
-        switch(speed) {
-                case XFER_PIO_4:
-                case XFER_PIO_3:
-                case XFER_PIO_2:
-                case XFER_PIO_1:
-                case XFER_PIO_0:
-                        auide_tune_drive(drive, (speed - XFER_PIO_0));
-                        break;
+	if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
+		auide_tune_drive(drive, speed - XFER_PIO_0);
+		return 0;
+	}
+	      
+	switch(speed) {
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-                case XFER_MW_DMA_2:
-                        /* set timing parameters for RCS2# */
-                        mem_sttime =   SBC_IDE_MDMA2_TWCS
-                                     | SBC_IDE_MDMA2_TCSH
-                                     | SBC_IDE_MDMA2_TCSOFF
-                                     | SBC_IDE_MDMA2_TWP
-                                     | SBC_IDE_MDMA2_TCSW
-                                     | SBC_IDE_MDMA2_TPM
-                                     | SBC_IDE_MDMA2_TA;
-                        /* set configuration for RCS2# */
-                        mem_stcfg &= ~TS_MASK;
-                        mem_stcfg &= ~TCSOE_MASK;
-                        mem_stcfg &= ~TOECS_MASK;
-                        mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
+	case XFER_MW_DMA_2:
+		mem_sttime = SBC_IDE_TIMING(MDMA2);
 
-                        mode = XFER_MW_DMA_2;
-                        break;
-                case XFER_MW_DMA_1:
-                        /* set timing parameters for RCS2# */
-                        mem_sttime =   SBC_IDE_MDMA1_TWCS
-                                     | SBC_IDE_MDMA1_TCSH
-                                     | SBC_IDE_MDMA1_TCSOFF
-                                     | SBC_IDE_MDMA1_TWP
-                                     | SBC_IDE_MDMA1_TCSW
-                                     | SBC_IDE_MDMA1_TPM
-                                     | SBC_IDE_MDMA1_TA;
-                        /* set configuration for RCS2# */
-                        mem_stcfg &= ~TS_MASK;
-                        mem_stcfg &= ~TCSOE_MASK;
-                        mem_stcfg &= ~TOECS_MASK;
-                        mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
+		/* set configuration for RCS2# */
+		mem_stcfg &= ~TS_MASK;
+		mem_stcfg &= ~TCSOE_MASK;
+		mem_stcfg &= ~TOECS_MASK;
+		mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
 
-                        mode = XFER_MW_DMA_1;
-                        break;
-                case XFER_MW_DMA_0:
-                        /* set timing parameters for RCS2# */
-                        mem_sttime =   SBC_IDE_MDMA0_TWCS
-                                     | SBC_IDE_MDMA0_TCSH
-                                     | SBC_IDE_MDMA0_TCSOFF
-                                     | SBC_IDE_MDMA0_TWP
-                                     | SBC_IDE_MDMA0_TCSW
-                                     | SBC_IDE_MDMA0_TPM
-                                     | SBC_IDE_MDMA0_TA;
-                        /* set configuration for RCS2# */
-                        mem_stcfg |= TS_MASK;
-                        mem_stcfg &= ~TCSOE_MASK;
-                        mem_stcfg &= ~TOECS_MASK;
-                        mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
+		mode = XFER_MW_DMA_2;
+		break;
+	case XFER_MW_DMA_1:
+		mem_sttime = SBC_IDE_TIMING(MDMA1);
 
-                        mode = XFER_MW_DMA_0;
-                        break;
+		/* set configuration for RCS2# */
+		mem_stcfg &= ~TS_MASK;
+		mem_stcfg &= ~TCSOE_MASK;
+		mem_stcfg &= ~TOECS_MASK;
+		mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
+
+		mode = XFER_MW_DMA_1;
+		break;
+	case XFER_MW_DMA_0:
+		mem_sttime = SBC_IDE_TIMING(MDMA0);
+
+		/* set configuration for RCS2# */
+		mem_stcfg |= TS_MASK;
+		mem_stcfg &= ~TCSOE_MASK;
+		mem_stcfg &= ~TOECS_MASK;
+		mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
+
+		mode = XFER_MW_DMA_0;
+		break;
 #endif
-                default:
-                        return 1;
-        }
+	default:
+		return 1;
+	}
+	
+	if (ide_config_drive_speed(drive, mode))
+		return 1;
 
-        /*
-         * Tell the drive to switch to the new mode; abort on failure.
-         */
-        if (!mode || ide_config_drive_speed(drive, mode))
-        {
-                return 1;       /* failure */
-        }
+	au_writel(mem_sttime,MEM_STTIME2);
+	au_writel(mem_stcfg,MEM_STCFG2);
 
-
-        au_writel(mem_sttime,MEM_STTIME2);
-        au_writel(mem_stcfg,MEM_STCFG2);
-
-        spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags);
-
-        return 0;
+	return 0;
 }
 
 /*
  * Multi-Word DMA + DbDMA functions
  */
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
 
-static int in_drive_list(struct hd_driveid *id,
-                         const struct drive_list_entry *drive_table)
-{
-        for ( ; drive_table->id_model ; drive_table++){
-                if ((!strcmp(drive_table->id_model, id->model)) &&
-                        ((strstr(drive_table->id_firmware, id->fw_rev)) ||
-                        (!strcmp(drive_table->id_firmware, "ALL")))
-                )
-                        return 1;
-        }
-        return 0;
-}
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
 
 static int auide_build_sglist(ide_drive_t *drive,  struct request *rq)
 {
-        ide_hwif_t *hwif = drive->hwif;
-        _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
-        struct scatterlist *sg = hwif->sg_table;
+	ide_hwif_t *hwif = drive->hwif;
+	_auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+	struct scatterlist *sg = hwif->sg_table;
 
-        ide_map_sg(drive, rq);
+	ide_map_sg(drive, rq);
 
-        if (rq_data_dir(rq) == READ)
-                hwif->sg_dma_direction = DMA_FROM_DEVICE;
-        else
-                hwif->sg_dma_direction = DMA_TO_DEVICE;
+	if (rq_data_dir(rq) == READ)
+		hwif->sg_dma_direction = DMA_FROM_DEVICE;
+	else
+		hwif->sg_dma_direction = DMA_TO_DEVICE;
 
-        return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
-                          hwif->sg_dma_direction);
+	return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
+			  hwif->sg_dma_direction);
 }
 
 static int auide_build_dmatable(ide_drive_t *drive)
 {
-        int i, iswrite, count = 0;
-        ide_hwif_t *hwif = HWIF(drive);
+	int i, iswrite, count = 0;
+	ide_hwif_t *hwif = HWIF(drive);
 
-        struct request *rq = HWGROUP(drive)->rq;
+	struct request *rq = HWGROUP(drive)->rq;
 
-        _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
-        struct scatterlist *sg;
+	_auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+	struct scatterlist *sg;
 
-        iswrite = (rq_data_dir(rq) == WRITE);
-        /* Save for interrupt context */
-        ahwif->drive = drive;
+	iswrite = (rq_data_dir(rq) == WRITE);
+	/* Save for interrupt context */
+	ahwif->drive = drive;
 
-        /* Build sglist */
-        hwif->sg_nents = i = auide_build_sglist(drive, rq);
+	/* Build sglist */
+	hwif->sg_nents = i = auide_build_sglist(drive, rq);
 
-        if (!i)
-                return 0;
+	if (!i)
+		return 0;
 
-        /* fill the descriptors */
-        sg = hwif->sg_table;
-        while (i && sg_dma_len(sg)) {
-                u32 cur_addr;
-                u32 cur_len;
+	/* fill the descriptors */
+	sg = hwif->sg_table;
+	while (i && sg_dma_len(sg)) {
+		u32 cur_addr;
+		u32 cur_len;
 
-                cur_addr = sg_dma_address(sg);
-                cur_len = sg_dma_len(sg);
+		cur_addr = sg_dma_address(sg);
+		cur_len = sg_dma_len(sg);
 
-                while (cur_len) {
-                        u32 flags = DDMA_FLAGS_NOIE;
-                        unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
+		while (cur_len) {
+			u32 flags = DDMA_FLAGS_NOIE;
+			unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
 
-                        if (++count >= PRD_ENTRIES) {
-                                printk(KERN_WARNING "%s: DMA table too small\n",
-                                drive->name);
-                                goto use_pio_instead;
-                        }
+			if (++count >= PRD_ENTRIES) {
+				printk(KERN_WARNING "%s: DMA table too small\n",
+				       drive->name);
+				goto use_pio_instead;
+			}
 
-                        /* Lets enable intr for the last descriptor only */
-                        if (1==i)
-                                flags = DDMA_FLAGS_IE;
-                        else
-                                flags = DDMA_FLAGS_NOIE;
+			/* Lets enable intr for the last descriptor only */
+			if (1==i)
+				flags = DDMA_FLAGS_IE;
+			else
+				flags = DDMA_FLAGS_NOIE;
 
-                        if (iswrite) {
-				if(!put_source_flags(ahwif->tx_chan,
-						(void*)(page_address(sg->page)
-							+ sg->offset),
-						tc, flags)) {
-					printk(KERN_ERR "%s failed %d\n",
-							__FUNCTION__, __LINE__);
+			if (iswrite) {
+				if(!put_source_flags(ahwif->tx_chan, 
+						     (void*)(page_address(sg->page) 
+							     + sg->offset), 
+						     tc, flags)) { 
+					printk(KERN_ERR "%s failed %d\n", 
+					       __FUNCTION__, __LINE__);
 				}
-                        } else
+			} else 
 			{
-				if(!put_dest_flags(ahwif->rx_chan,
-						(void*)(page_address(sg->page)
-							+ sg->offset),
-						tc, flags)) {
-					printk(KERN_ERR "%s failed %d\n",
-							__FUNCTION__, __LINE__);
+				if(!put_dest_flags(ahwif->rx_chan, 
+						   (void*)(page_address(sg->page) 
+							   + sg->offset), 
+						   tc, flags)) { 
+					printk(KERN_ERR "%s failed %d\n", 
+					       __FUNCTION__, __LINE__);
 				}
-                        }
+			}
 
-                        cur_addr += tc;
-                        cur_len -= tc;
-                }
-                sg++;
-                i--;
-        }
+			cur_addr += tc;
+			cur_len -= tc;
+		}
+		sg++;
+		i--;
+	}
 
-        if (count)
-                return 1;
+	if (count)
+		return 1;
 
-use_pio_instead:
-        dma_unmap_sg(ahwif->dev,
-                     hwif->sg_table,
-                     hwif->sg_nents,
-                     hwif->sg_dma_direction);
+ use_pio_instead:
+	dma_unmap_sg(ahwif->dev,
+		     hwif->sg_table,
+		     hwif->sg_nents,
+		     hwif->sg_dma_direction);
 
-        return 0; /* revert to PIO for this request */
+	return 0; /* revert to PIO for this request */
 }
 
 static int auide_dma_end(ide_drive_t *drive)
 {
-        ide_hwif_t *hwif = HWIF(drive);
-        _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+	ide_hwif_t *hwif = HWIF(drive);
+	_auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
 
-        if (hwif->sg_nents) {
-                dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
-                             hwif->sg_dma_direction);
-                hwif->sg_nents = 0;
-        }
+	if (hwif->sg_nents) {
+		dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
+			     hwif->sg_dma_direction);
+		hwif->sg_nents = 0;
+	}
 
-        return 0;
+	return 0;
 }
 
 static void auide_dma_start(ide_drive_t *drive )
 {
-//      printk("%s\n", __FUNCTION__);
 }
 
-ide_startstop_t auide_dma_intr(ide_drive_t *drive)
-{
-        //printk("%s\n", __FUNCTION__);
-
-        u8 stat = 0, dma_stat = 0;
-
-        dma_stat = HWIF(drive)->ide_dma_end(drive);
-        stat = HWIF(drive)->INB(IDE_STATUS_REG);        /* get drive status */
-        if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
-                if (!dma_stat) {
-                        struct request *rq = HWGROUP(drive)->rq;
-
-                        ide_end_request(drive, 1, rq->nr_sectors);
-                        return ide_stopped;
-                }
-                printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
-                                 drive->name, dma_stat);
-        }
-        return ide_error(drive, "dma_intr", stat);
-}
 
 static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
 {
-        //printk("%s\n", __FUNCTION__);
-
-        /* issue cmd to drive */
-        ide_execute_command(drive, command, &auide_dma_intr,
-                            (2*WAIT_CMD), NULL);
+	/* issue cmd to drive */
+	ide_execute_command(drive, command, &ide_dma_intr,
+			    (2*WAIT_CMD), NULL);
 }
 
 static int auide_dma_setup(ide_drive_t *drive)
-{
-//      printk("%s\n", __FUNCTION__);
+{       	
+	struct request *rq = HWGROUP(drive)->rq;
 
-        if (drive->media != ide_disk)
-                return 1;
+	if (!auide_build_dmatable(drive)) {
+		ide_map_sg(drive, rq);
+		return 1;
+	}
 
-        if (!auide_build_dmatable(drive))
-                        /* try PIO instead of DMA */
-                        return 1;
-
-        drive->waiting_for_dma = 1;
-
-        return 0;
+	drive->waiting_for_dma = 1;
+	return 0;
 }
 
 static int auide_dma_check(ide_drive_t *drive)
 {
-//      printk("%s\n", __FUNCTION__);
+	u8 speed;
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-        if( !dbdma_init_done ){
-                auide_hwif.white_list = in_drive_list(drive->id,
-                                                      dma_white_list);
-                auide_hwif.black_list = in_drive_list(drive->id,
-                                                      dma_black_list);
-                auide_hwif.drive = drive;
-                auide_ddma_init(&auide_hwif);
-                dbdma_init_done = 1;
-        }
+
+	if( dbdma_init_done == 0 ){
+		auide_hwif.white_list = ide_in_drive_list(drive->id,
+							  dma_white_list);
+		auide_hwif.black_list = ide_in_drive_list(drive->id,
+							  dma_black_list);
+		auide_hwif.drive = drive;
+		auide_ddma_init(&auide_hwif);
+		dbdma_init_done = 1;
+	}
 #endif
 
-        /* Is the drive in our DMA black list? */
-        if ( auide_hwif.black_list ) {
-                drive->using_dma = 0;
-                printk("%s found in dma_blacklist[]! Disabling DMA.\n",
-                drive->id->model);
-        }
-        else
-                drive->using_dma = 1;
+	/* Is the drive in our DMA black list? */
 
-        return HWIF(drive)->ide_dma_host_on(drive);
+	if ( auide_hwif.black_list ) {
+		drive->using_dma = 0;
+
+		/* Borrowed the warning message from ide-dma.c */
+
+		printk(KERN_WARNING "%s: Disabling DMA for %s (blacklisted)\n",
+		       drive->name, drive->id->model);	       
+	}
+	else
+		drive->using_dma = 1;
+
+	speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
+	
+	if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+		return HWIF(drive)->ide_dma_on(drive);
+
+	return HWIF(drive)->ide_dma_off_quietly(drive);
 }
 
 static int auide_dma_test_irq(ide_drive_t *drive)
-{
-//      printk("%s\n", __FUNCTION__);
-
-        if (!drive->waiting_for_dma)
-                printk(KERN_WARNING "%s: ide_dma_test_irq \
+{	
+	if (drive->waiting_for_dma == 0)
+		printk(KERN_WARNING "%s: ide_dma_test_irq \
                                      called while not waiting\n", drive->name);
 
-        /* If dbdma didn't execute the STOP command yet, the
-         * active bit is still set
+	/* If dbdma didn't execute the STOP command yet, the
+	 * active bit is still set
 	 */
-        drive->waiting_for_dma++;
-        if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
-                printk(KERN_WARNING "%s: timeout waiting for ddma to \
+	drive->waiting_for_dma++;
+	if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
+		printk(KERN_WARNING "%s: timeout waiting for ddma to \
                                      complete\n", drive->name);
-                return 1;
-        }
-        udelay(10);
-        return 0;
+		return 1;
+	}
+	udelay(10);
+	return 0;
 }
 
 static int auide_dma_host_on(ide_drive_t *drive)
 {
-//      printk("%s\n", __FUNCTION__);
-        return 0;
+	return 0;
 }
 
 static int auide_dma_on(ide_drive_t *drive)
 {
-//      printk("%s\n", __FUNCTION__);
-        drive->using_dma = 1;
-        return auide_dma_host_on(drive);
+	drive->using_dma = 1;
+	return auide_dma_host_on(drive);
 }
 
 
 static int auide_dma_host_off(ide_drive_t *drive)
 {
-//      printk("%s\n", __FUNCTION__);
-        return 0;
+	return 0;
 }
 
 static int auide_dma_off_quietly(ide_drive_t *drive)
 {
-//      printk("%s\n", __FUNCTION__);
-        drive->using_dma = 0;
-        return auide_dma_host_off(drive);
+	drive->using_dma = 0;
+	return auide_dma_host_off(drive);
 }
 
 static int auide_dma_lostirq(ide_drive_t *drive)
 {
-//      printk("%s\n", __FUNCTION__);
-
-        printk(KERN_ERR "%s: IRQ lost\n", drive->name);
-        return 0;
+	printk(KERN_ERR "%s: IRQ lost\n", drive->name);
+	return 0;
 }
 
 static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs)
 {
-//      printk("%s\n", __FUNCTION__);
-
-        _auide_hwif *ahwif = (_auide_hwif*)param;
-        ahwif->drive->waiting_for_dma = 0;
-        return;
+	_auide_hwif *ahwif = (_auide_hwif*)param;
+	ahwif->drive->waiting_for_dma = 0;
 }
 
 static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs)
 {
-//      printk("%s\n", __FUNCTION__);
-
-        _auide_hwif *ahwif = (_auide_hwif*)param;
-        ahwif->drive->waiting_for_dma = 0;
-        return;
+	_auide_hwif *ahwif = (_auide_hwif*)param;
+	ahwif->drive->waiting_for_dma = 0;
 }
 
+#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+
+static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
+{
+	dev->dev_id          = dev_id;
+	dev->dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
+	dev->dev_intlevel    = 0;
+	dev->dev_intpolarity = 0;
+	dev->dev_tsize       = tsize;
+	dev->dev_devwidth    = devwidth;
+	dev->dev_flags       = flags;
+}
+  
+#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
+
 static int auide_dma_timeout(ide_drive_t *drive)
 {
 //      printk("%s\n", __FUNCTION__);
 
-        printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
+	printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
 
-        if (HWIF(drive)->ide_dma_test_irq(drive))
-                return 0;
+	if (HWIF(drive)->ide_dma_test_irq(drive))
+		return 0;
 
-        return HWIF(drive)->ide_dma_end(drive);
+	return HWIF(drive)->ide_dma_end(drive);
 }
-#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
+					
 
+static int auide_ddma_init(_auide_hwif *auide) {
+	
+	dbdev_tab_t source_dev_tab, target_dev_tab;
+	u32 dev_id, tsize, devwidth, flags;
+	ide_hwif_t *hwif = auide->hwif;
 
+	dev_id   = AU1XXX_ATA_DDMA_REQ;
+
+	if (auide->white_list || auide->black_list) {
+		tsize    = 8;
+		devwidth = 32;
+	}
+	else { 
+		tsize    = 1;
+		devwidth = 16;
+		
+		printk(KERN_ERR "au1xxx-ide: %s is not on ide driver whitelist.\n",auide_hwif.drive->id->model);
+		printk(KERN_ERR "            please read 'Documentation/mips/AU1xxx_IDE.README'");
+	}
+
+#ifdef IDE_AU1XXX_BURSTMODE 
+	flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
+#else
+	flags = DEV_FLAGS_SYNC;
+#endif
+
+	/* setup dev_tab for tx channel */
+	auide_init_dbdma_dev( &source_dev_tab,
+			      dev_id,
+			      tsize, devwidth, DEV_FLAGS_OUT | flags);
+ 	auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+
+	auide_init_dbdma_dev( &source_dev_tab,
+			      dev_id,
+			      tsize, devwidth, DEV_FLAGS_IN | flags);
+ 	auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+	
+	/* We also need to add a target device for the DMA */
+	auide_init_dbdma_dev( &target_dev_tab,
+			      (u32)DSCR_CMD0_ALWAYS,
+			      tsize, devwidth, DEV_FLAGS_ANYUSE);
+	auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);	
+ 
+	/* Get a channel for TX */
+	auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
+						 auide->tx_dev_id,
+						 auide_ddma_tx_callback,
+						 (void*)auide);
+ 
+	/* Get a channel for RX */
+	auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+						 auide->target_dev_id,
+						 auide_ddma_rx_callback,
+						 (void*)auide);
+
+	auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
+							     NUM_DESCRIPTORS);
+	auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
+							     NUM_DESCRIPTORS);
+ 
+	hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
+						PRD_ENTRIES * PRD_BYTES,        /* 1 Page */
+						&hwif->dmatable_dma, GFP_KERNEL);
+	
+	au1xxx_dbdma_start( auide->tx_chan );
+	au1xxx_dbdma_start( auide->rx_chan );
+ 
+	return 0;
+} 
+#else
+ 
 static int auide_ddma_init( _auide_hwif *auide )
 {
-//      printk("%s\n", __FUNCTION__);
+	dbdev_tab_t source_dev_tab;
+	int flags;
 
-        dbdev_tab_t source_dev_tab;
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
-        dbdev_tab_t target_dev_tab;
-        ide_hwif_t *hwif = auide->hwif;
-        char warning_output [2][80];
-        int i;
-#endif
-
-        /* Add our custom device to DDMA device table */
-        /* Create our new device entries in the table */
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
-        source_dev_tab.dev_id = AU1XXX_ATA_DDMA_REQ;
-
-        if( auide->white_list || auide->black_list ){
-                source_dev_tab.dev_tsize       = 8;
-                source_dev_tab.dev_devwidth    = 32;
-                source_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
-                source_dev_tab.dev_intlevel    = 0;
-                source_dev_tab.dev_intpolarity = 0;
-
-                /* init device table for target - static bus controller - */
-                target_dev_tab.dev_id          = DSCR_CMD0_ALWAYS;
-                target_dev_tab.dev_tsize       = 8;
-                target_dev_tab.dev_devwidth    = 32;
-                target_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
-                target_dev_tab.dev_intlevel    = 0;
-                target_dev_tab.dev_intpolarity = 0;
-                target_dev_tab.dev_flags       = DEV_FLAGS_ANYUSE;
-        }
-        else{
-                source_dev_tab.dev_tsize       = 1;
-                source_dev_tab.dev_devwidth    = 16;
-                source_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
-                source_dev_tab.dev_intlevel    = 0;
-                source_dev_tab.dev_intpolarity = 0;
-
-                /* init device table for target - static bus controller - */
-                target_dev_tab.dev_id          = DSCR_CMD0_ALWAYS;
-                target_dev_tab.dev_tsize       = 1;
-                target_dev_tab.dev_devwidth    = 16;
-                target_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
-                target_dev_tab.dev_intlevel    = 0;
-                target_dev_tab.dev_intpolarity = 0;
-                target_dev_tab.dev_flags       = DEV_FLAGS_ANYUSE;
-
-                sprintf(&warning_output[0][0],
-                        "%s is not on ide driver white list.",
-                        auide_hwif.drive->id->model);
-                for ( i=strlen(&warning_output[0][0]) ; i<76; i++ ){
-                        sprintf(&warning_output[0][i]," ");
-                }
-
-                sprintf(&warning_output[1][0],
-                "To add %s please read 'Documentation/mips/AU1xxx_IDE.README'.",
-                        auide_hwif.drive->id->model);
-                for ( i=strlen(&warning_output[1][0]) ; i<76; i++ ){
-                        sprintf(&warning_output[1][i]," ");
-                }
-
-                printk("\n****************************************");
-                printk("****************************************\n");
-                printk("* %s *\n",&warning_output[0][0]);
-                printk("* Switch to safe MWDMA Mode!            ");
-                printk("                                       *\n");
-                printk("* %s *\n",&warning_output[1][0]);
-                printk("****************************************");
-                printk("****************************************\n\n");
-        }
+#ifdef IDE_AU1XXX_BURSTMODE 
+	flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;
 #else
-        source_dev_tab.dev_id = DSCR_CMD0_ALWAYS;
-        source_dev_tab.dev_tsize       = 8;
-        source_dev_tab.dev_devwidth    = 32;
-        source_dev_tab.dev_physaddr    = (u32)AU1XXX_ATA_PHYS_ADDR;
-        source_dev_tab.dev_intlevel    = 0;
-        source_dev_tab.dev_intpolarity = 0;
+	flags = DEV_FLAGS_SYNC;
 #endif
 
-#if CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
-        /* set flags for tx channel */
-        source_dev_tab.dev_flags =  DEV_FLAGS_OUT
-                                  | DEV_FLAGS_SYNC
-                                  | DEV_FLAGS_BURSTABLE;
-        auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
-        /* set flags for rx channel */
-        source_dev_tab.dev_flags =  DEV_FLAGS_IN
-                                  | DEV_FLAGS_SYNC
-                                  | DEV_FLAGS_BURSTABLE;
-        auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
-#else
-        /* set flags for tx channel */
-        source_dev_tab.dev_flags = DEV_FLAGS_OUT | DEV_FLAGS_SYNC;
-        auide->tx_dev_id         = au1xxx_ddma_add_device( &source_dev_tab );
-        /* set flags for rx channel */
-        source_dev_tab.dev_flags = DEV_FLAGS_IN | DEV_FLAGS_SYNC;
-        auide->rx_dev_id         = au1xxx_ddma_add_device( &source_dev_tab );
-#endif
+	/* setup dev_tab for tx channel */
+	auide_init_dbdma_dev( &source_dev_tab,
+			      (u32)DSCR_CMD0_ALWAYS,
+			      8, 32, DEV_FLAGS_OUT | flags);
+ 	auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
 
-#if  defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
-
-        auide->target_dev_id           = au1xxx_ddma_add_device(&target_dev_tab);
-
-        /* Get a channel for TX */
-        auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id,
-                                                 auide->tx_dev_id,
-                                                 auide_ddma_tx_callback,
-                                                 (void*)auide);
-        /* Get a channel for RX */
-        auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
-                                                 auide->target_dev_id,
-                                                 auide_ddma_rx_callback,
-                                                 (void*)auide);
-#else   /* CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA */
-        /*
-         * Note: if call back is not enabled, update ctp->cur_ptr manually
-         */
-        auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
-                                                 auide->tx_dev_id,
-                                                 NULL,
-                                                 (void*)auide);
-        auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
-                                                 DSCR_CMD0_ALWAYS,
-                                                 NULL,
-                                                 (void*)auide);
-#endif
-        auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
-                                                             NUM_DESCRIPTORS);
-        auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
-                                                             NUM_DESCRIPTORS);
-
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
-        hwif->dmatable_cpu = dma_alloc_coherent(auide->dev,
-                                                PRD_ENTRIES * PRD_BYTES,        /* 1 Page */
-                                                &hwif->dmatable_dma, GFP_KERNEL);
-
-        auide->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
-                                GFP_KERNEL|GFP_DMA);
-        if (auide->sg_table == NULL) {
-                return -ENOMEM;
-        }
-#endif
-        au1xxx_dbdma_start( auide->tx_chan );
-        au1xxx_dbdma_start( auide->rx_chan );
-        return 0;
+	auide_init_dbdma_dev( &source_dev_tab,
+			      (u32)DSCR_CMD0_ALWAYS,
+			      8, 32, DEV_FLAGS_IN | flags);
+ 	auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
+	
+	/* Get a channel for TX */
+	auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS,
+						 auide->tx_dev_id,
+						 NULL,
+						 (void*)auide);
+ 
+	/* Get a channel for RX */
+	auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id,
+						 DSCR_CMD0_ALWAYS,
+						 NULL,
+						 (void*)auide);
+ 
+	auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan,
+							     NUM_DESCRIPTORS);
+	auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan,
+							     NUM_DESCRIPTORS);
+ 
+	au1xxx_dbdma_start( auide->tx_chan );
+	au1xxx_dbdma_start( auide->rx_chan );
+ 	
+	return 0;
 }
+#endif
 
 static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
 {
-        int i;
-#define ide_ioreg_t unsigned long
-        ide_ioreg_t *ata_regs = hw->io_ports;
+	int i;
+	unsigned long *ata_regs = hw->io_ports;
 
-	/* fixme */
-        for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
-                *ata_regs++ = (ide_ioreg_t) ahwif->regbase
-                            + (ide_ioreg_t)(i << AU1XXX_ATA_REG_OFFSET);
-        }
+	/* FIXME? */
+	for (i = 0; i < IDE_CONTROL_OFFSET; i++) {
+		*ata_regs++ = ahwif->regbase + (i << AU1XXX_ATA_REG_OFFSET);
+	}
 
-        /* set the Alternative Status register */
-        *ata_regs = (ide_ioreg_t) ahwif->regbase
-                  + (ide_ioreg_t)(14 << AU1XXX_ATA_REG_OFFSET);
+	/* set the Alternative Status register */
+	*ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET);
 }
 
 static int au_ide_probe(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-        _auide_hwif *ahwif = &auide_hwif;
-        ide_hwif_t *hwif;
+	_auide_hwif *ahwif = &auide_hwif;
+	ide_hwif_t *hwif;
 	struct resource *res;
 	int ret = 0;
 
 #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
-        char *mode = "MWDMA2";
+	char *mode = "MWDMA2";
 #elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
-        char *mode = "PIO+DDMA(offload)";
+	char *mode = "PIO+DDMA(offload)";
 #endif
 
-        memset(&auide_hwif, 0, sizeof(_auide_hwif));
-        auide_hwif.dev                  = 0;
+	memset(&auide_hwif, 0, sizeof(_auide_hwif));
+	auide_hwif.dev                  = 0;
 
 	ahwif->dev = dev;
 	ahwif->irq = platform_get_irq(pdev, 0);
@@ -902,11 +675,11 @@
 		goto out;
 	}
 
-        if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
+	if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
 		pr_debug("%s: request_mem_region failed\n", DRV_NAME);
-                ret =  -EBUSY;
+		ret =  -EBUSY;
 		goto out;
-        }
+	}
 
 	ahwif->regbase = (u32)ioremap(res->start, res->end-res->start);
 	if (ahwif->regbase == 0) {
@@ -914,130 +687,92 @@
 		goto out;
 	}
 
-        hwif                            = &ide_hwifs[pdev->id];
-	hw_regs_t *hw 			= &hwif->hw;
-        hwif->irq = hw->irq             = ahwif->irq;
-        hwif->chipset                   = ide_au1xxx;
+	/* FIXME:  This might possibly break PCMCIA IDE devices */
 
-        auide_setup_ports(hw, ahwif);
+	hwif                            = &ide_hwifs[pdev->id];
+	hw_regs_t *hw 			= &hwif->hw;
+	hwif->irq = hw->irq             = ahwif->irq;
+	hwif->chipset                   = ide_au1xxx;
+
+	auide_setup_ports(hw, ahwif);
 	memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
 
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
-        hwif->rqsize = CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ;
-        hwif->rqsize                    = ((hwif->rqsize > AU1XXX_ATA_RQSIZE)
-                                        || (hwif->rqsize < 32)) ? AU1XXX_ATA_RQSIZE : hwif->rqsize;
-#else /* if kernel config is not set */
-        hwif->rqsize                    = AU1XXX_ATA_RQSIZE;
-#endif
-
-        hwif->ultra_mask                = 0x0;  /* Disable Ultra DMA */
+	hwif->ultra_mask                = 0x0;  /* Disable Ultra DMA */
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-        hwif->mwdma_mask                = 0x07; /* Multimode-2 DMA  */
-        hwif->swdma_mask                = 0x07;
+	hwif->mwdma_mask                = 0x07; /* Multimode-2 DMA  */
+	hwif->swdma_mask                = 0x00;
 #else
-        hwif->mwdma_mask                = 0x0;
-        hwif->swdma_mask                = 0x0;
+	hwif->mwdma_mask                = 0x0;
+	hwif->swdma_mask                = 0x0;
 #endif
-        //hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
-        hwif->noprobe = 0;
-        hwif->drives[0].unmask          = 1;
-        hwif->drives[1].unmask          = 1;
 
-        /* hold should be on in all cases */
-        hwif->hold                      = 1;
-        hwif->mmio                      = 2;
+	hwif->noprobe = 0;
+	hwif->drives[0].unmask          = 1;
+	hwif->drives[1].unmask          = 1;
 
-        /* set up local I/O function entry points */
-        hwif->INB                       = auide_inb;
-        hwif->INW                       = auide_inw;
-        hwif->INL                       = auide_inl;
-        hwif->INSW                      = auide_insw;
-        hwif->INSL                      = auide_insl;
-        hwif->OUTB                      = auide_outb;
-        hwif->OUTBSYNC                  = auide_outbsync;
-        hwif->OUTW                      = auide_outw;
-        hwif->OUTL                      = auide_outl;
-        hwif->OUTSW                     = auide_outsw;
-        hwif->OUTSL                     = auide_outsl;
+	/* hold should be on in all cases */
+	hwif->hold                      = 1;
+	hwif->mmio                      = 2;
 
-        hwif->tuneproc                  = &auide_tune_drive;
-        hwif->speedproc                 = &auide_tune_chipset;
+	/* If the user has selected DDMA assisted copies,
+	   then set up a few local I/O function entry points 
+	*/
+
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA	
+	hwif->INSW                      = auide_insw;
+	hwif->OUTSW                     = auide_outsw;
+#endif
+
+	hwif->tuneproc                  = &auide_tune_drive;
+	hwif->speedproc                 = &auide_tune_chipset;
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-        hwif->ide_dma_off_quietly       = &auide_dma_off_quietly;
-        hwif->ide_dma_timeout           = &auide_dma_timeout;
+	hwif->ide_dma_off_quietly       = &auide_dma_off_quietly;
+	hwif->ide_dma_timeout           = &auide_dma_timeout;
 
-        hwif->ide_dma_check             = &auide_dma_check;
-        hwif->dma_exec_cmd              = &auide_dma_exec_cmd;
-        hwif->dma_start                 = &auide_dma_start;
-        hwif->ide_dma_end               = &auide_dma_end;
-        hwif->dma_setup                 = &auide_dma_setup;
-        hwif->ide_dma_test_irq          = &auide_dma_test_irq;
-        hwif->ide_dma_host_off          = &auide_dma_host_off;
-        hwif->ide_dma_host_on           = &auide_dma_host_on;
-        hwif->ide_dma_lostirq           = &auide_dma_lostirq;
-        hwif->ide_dma_on                = &auide_dma_on;
+	hwif->ide_dma_check             = &auide_dma_check;
+	hwif->dma_exec_cmd              = &auide_dma_exec_cmd;
+	hwif->dma_start                 = &auide_dma_start;
+	hwif->ide_dma_end               = &auide_dma_end;
+	hwif->dma_setup                 = &auide_dma_setup;
+	hwif->ide_dma_test_irq          = &auide_dma_test_irq;
+	hwif->ide_dma_host_off          = &auide_dma_host_off;
+	hwif->ide_dma_host_on           = &auide_dma_host_on;
+	hwif->ide_dma_lostirq           = &auide_dma_lostirq;
+	hwif->ide_dma_on                = &auide_dma_on;
 
-        hwif->autodma                   = 1;
-        hwif->drives[0].autodma         = hwif->autodma;
-        hwif->drives[1].autodma         = hwif->autodma;
-        hwif->atapi_dma                 = 1;
-        hwif->drives[0].using_dma       = 1;
-        hwif->drives[1].using_dma       = 1;
+	hwif->autodma                   = 1;
+	hwif->drives[0].autodma         = hwif->autodma;
+	hwif->drives[1].autodma         = hwif->autodma;
+	hwif->atapi_dma                 = 1;
+
 #else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
-        hwif->autodma                   = 0;
-        hwif->channel                   = 0;
-        hwif->hold                      = 1;
-        hwif->select_data               = 0;    /* no chipset-specific code */
-        hwif->config_data               = 0;    /* no chipset-specific code */
+	hwif->autodma                   = 0;
+	hwif->channel                   = 0;
+	hwif->hold                      = 1;
+	hwif->select_data               = 0;    /* no chipset-specific code */
+	hwif->config_data               = 0;    /* no chipset-specific code */
 
-        hwif->drives[0].autodma         = 0;
-        hwif->drives[0].drive_data      = 0;    /* no drive data */
-        hwif->drives[0].using_dma       = 0;
-        hwif->drives[0].waiting_for_dma = 0;
-        hwif->drives[0].autotune        = 1;    /* 1=autotune, 2=noautotune, 0=default */
-        /* secondary hdd not supported */
-        hwif->drives[1].autodma         = 0;
-
-        hwif->drives[1].drive_data      = 0;
-        hwif->drives[1].using_dma       = 0;
-        hwif->drives[1].waiting_for_dma = 0;
-        hwif->drives[1].autotune        = 2;   /* 1=autotune, 2=noautotune, 0=default */
+	hwif->drives[0].autodma         = 0;
+	hwif->drives[0].autotune        = 1;    /* 1=autotune, 2=noautotune, 0=default */
 #endif
-        hwif->drives[0].io_32bit        = 0;   /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
-        hwif->drives[1].io_32bit        = 0;   /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
+	hwif->drives[0].no_io_32bit     = 1;   
 
-        /*Register Driver with PM Framework*/
-#ifdef CONFIG_PM
-        auide_hwif.pm.lock    = SPIN_LOCK_UNLOCKED;
-        auide_hwif.pm.stopped = 0;
+	auide_hwif.hwif                 = hwif;
+	hwif->hwif_data                 = &auide_hwif;
 
-        auide_hwif.pm.dev = new_au1xxx_power_device( "ide",
-                                                &au1200ide_pm_callback,
-                                                NULL);
-        if ( auide_hwif.pm.dev == NULL )
-                printk(KERN_INFO "Unable to create a power management \
-                                device entry for the au1200-IDE.\n");
-        else
-                printk(KERN_INFO "Power management device entry for the \
-                                au1200-IDE loaded.\n");
-#endif
-
-        auide_hwif.hwif                 = hwif;
-        hwif->hwif_data                 = &auide_hwif;
-
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
-        auide_ddma_init(&auide_hwif);
-        dbdma_init_done = 1;
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA           
+	auide_ddma_init(&auide_hwif);
+	dbdma_init_done = 1;
 #endif
 
 	probe_hwif_init(hwif);
 	dev_set_drvdata(dev, hwif);
 
-        printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
+	printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode );
 
-out:
-        return ret;
+ out:
+	return ret;
 }
 
 static int au_ide_remove(struct device *dev)
@@ -1045,7 +780,7 @@
 	struct platform_device *pdev = to_platform_device(dev);
 	struct resource *res;
 	ide_hwif_t *hwif = dev_get_drvdata(dev);
-        _auide_hwif *ahwif = &auide_hwif;
+	_auide_hwif *ahwif = &auide_hwif;
 
 	ide_unregister(hwif - ide_hwifs);
 
@@ -1069,180 +804,11 @@
 	return driver_register(&au1200_ide_driver);
 }
 
-static void __init au_ide_exit(void)
+static void __exit au_ide_exit(void)
 {
 	driver_unregister(&au1200_ide_driver);
 }
 
-#ifdef CONFIG_PM
-int au1200ide_pm_callback( au1xxx_power_dev_t *dev,\
-                        au1xxx_request_t request, void *data) {
-
-        unsigned int d, err = 0;
-        unsigned long flags;
-
-        spin_lock_irqsave(auide_hwif.pm.lock, flags);
-
-        switch (request){
-                case AU1XXX_PM_SLEEP:
-                        err = au1xxxide_pm_sleep(dev);
-                        break;
-                case AU1XXX_PM_WAKEUP:
-                        d = *((unsigned int*)data);
-                        if ( d > 0 && d <= 99) {
-                                err = au1xxxide_pm_standby(dev);
-                        }
-                        else {
-                                err = au1xxxide_pm_resume(dev);
-                        }
-                        break;
-                case AU1XXX_PM_GETSTATUS:
-                        err = au1xxxide_pm_getstatus(dev);
-                        break;
-                case AU1XXX_PM_ACCESS:
-                        err = au1xxxide_pm_access(dev);
-                        break;
-                case AU1XXX_PM_IDLE:
-                        err = au1xxxide_pm_idle(dev);
-                        break;
-                case AU1XXX_PM_CLEANUP:
-                        err = au1xxxide_pm_cleanup(dev);
-                        break;
-                default:
-                        err = -1;
-                        break;
-        }
-
-        spin_unlock_irqrestore(auide_hwif.pm.lock, flags);
-
-        return err;
-}
-
-static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ) {
-        return 0;
-}
-
-static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ) {
-
-        int retval;
-        ide_hwif_t *hwif = auide_hwif.hwif;
-        struct request rq;
-        struct request_pm_state rqpm;
-        ide_task_t args;
-
-        if(auide_hwif.pm.stopped)
-                return -1;
-
-        /*
-         * wait until hard disc is ready
-         */
-        if ( wait_for_ready(&hwif->drives[0], 35000) ) {
-                printk("Wait for drive sleep timeout!\n");
-                retval = -1;
-        }
-
-        /*
-         * sequenz to tell the high level ide driver that pm is resuming
-         */
-        memset(&rq, 0, sizeof(rq));
-        memset(&rqpm, 0, sizeof(rqpm));
-        memset(&args, 0, sizeof(args));
-        rq.flags = REQ_PM_SUSPEND;
-        rq.special = &args;
-        rq.pm = &rqpm;
-        rqpm.pm_step = ide_pm_state_start_suspend;
-        rqpm.pm_state = PMSG_SUSPEND;
-
-        retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_wait);
-
-        if (wait_for_ready (&hwif->drives[0], 35000)) {
-                printk("Wait for drive sleep timeout!\n");
-                retval = -1;
-        }
-
-        /*
-         * stop dbdma channels
-         */
-        au1xxx_dbdma_reset(auide_hwif.tx_chan);
-        au1xxx_dbdma_reset(auide_hwif.rx_chan);
-
-        auide_hwif.pm.stopped = 1;
-
-        return retval;
-}
-
-static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ) {
-
-        int retval;
-        ide_hwif_t *hwif = auide_hwif.hwif;
-        struct request rq;
-        struct request_pm_state rqpm;
-        ide_task_t args;
-
-        if(!auide_hwif.pm.stopped)
-                return -1;
-
-        /*
-         * start dbdma channels
-         */
-        au1xxx_dbdma_start(auide_hwif.tx_chan);
-        au1xxx_dbdma_start(auide_hwif.rx_chan);
-
-        /*
-         * wait until hard disc is ready
-         */
-        if (wait_for_ready ( &hwif->drives[0], 35000)) {
-                printk("Wait for drive wake up timeout!\n");
-                retval = -1;
-        }
-
-        /*
-         * sequenz to tell the high level ide driver that pm is resuming
-         */
-        memset(&rq, 0, sizeof(rq));
-        memset(&rqpm, 0, sizeof(rqpm));
-        memset(&args, 0, sizeof(args));
-        rq.flags = REQ_PM_RESUME;
-        rq.special = &args;
-        rq.pm = &rqpm;
-        rqpm.pm_step = ide_pm_state_start_resume;
-        rqpm.pm_state = PMSG_ON;
-
-        retval = ide_do_drive_cmd(&hwif->drives[0], &rq, ide_head_wait);
-
-        /*
-        * wait for hard disc
-        */
-        if ( wait_for_ready(&hwif->drives[0], 35000) ) {
-                printk("Wait for drive wake up timeout!\n");
-                retval = -1;
-        }
-
-        auide_hwif.pm.stopped = 0;
-
-        return retval;
-}
-
-static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ) {
-        return dev->cur_state;
-}
-
-static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ) {
-        if (dev->cur_state != AWAKE_STATE)
-                return 0;
-        else
-                return -1;
-}
-
-static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ) {
-        return 0;
-}
-
-static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ) {
-        return 0;
-}
-#endif /* CONFIG_PM */
-
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("AU1200 IDE driver");
 
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index ff2e217..0d3073f 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -69,7 +69,7 @@
 static u8 svwks_ratemask (ide_drive_t *drive)
 {
 	struct pci_dev *dev     = HWIF(drive)->pci_dev;
-	u8 mode;
+	u8 mode = 0;
 
 	if (!svwks_revision)
 		pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision);
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index af526b6..4ee597d 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -622,12 +622,18 @@
 	ide_hwif_t *hwif;
 	int h;
 
+	/*
+	 * Find an empty HWIF; if none available, return -ENOMEM.
+	 */
 	for (h = 0; h < MAX_HWIFS; ++h) {
 		hwif = &ide_hwifs[h];
-		/* Find an empty HWIF */
 		if (hwif->chipset == ide_unknown)
 			break;
 	}
+	if (h == MAX_HWIFS) {
+		printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name);
+		return -ENOMEM;
+	}
 
 	/*  Get the CmdBlk and CtrlBlk Base Registers */
 	base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET;
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 7161ce0..86fb1e0 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -80,6 +80,7 @@
 	u16 flags;
 } via_isa_bridges[] = {
 	{ "vt6410",	PCI_DEVICE_ID_VIA_6410,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
+	{ "vt8251",	PCI_DEVICE_ID_VIA_8251,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8237",	PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8235",	PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
 	{ "vt8233a",	PCI_DEVICE_ID_VIA_8233A,    0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
diff --git a/drivers/ieee1394/.gitignore b/drivers/ieee1394/.gitignore
new file mode 100644
index 0000000..33da10a
--- /dev/null
+++ b/drivers/ieee1394/.gitignore
@@ -0,0 +1 @@
+oui.c
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig
index 25103a0..39142e2 100644
--- a/drivers/ieee1394/Kconfig
+++ b/drivers/ieee1394/Kconfig
@@ -169,27 +169,4 @@
 	  To compile this driver as a module, say M here: the
 	  module will be called raw1394.
 
-config IEEE1394_CMP
-	tristate "IEC61883-1 Plug support"
-	depends on IEEE1394
-	help
-	  This option enables the Connection Management Procedures
-	  (IEC61883-1) driver, which implements input and output plugs.
-
-	  To compile this driver as a module, say M here: the
-	  module will be called cmp.
-
-config IEEE1394_AMDTP
-	tristate "IEC61883-6 (Audio transmission) support"
-	depends on IEEE1394 && IEEE1394_OHCI1394 && IEEE1394_CMP
-	help
-	  This option enables the Audio & Music Data Transmission Protocol
-	  (IEC61883-6) driver, which implements audio transmission over
-	  IEEE1394.
-
-	  The userspace interface is documented in amdtp.h.
-
-	  To compile this driver as a module, say M here: the
-	  module will be called amdtp.
-
 endmenu
diff --git a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile
index e8b4d48..6f53611 100644
--- a/drivers/ieee1394/Makefile
+++ b/drivers/ieee1394/Makefile
@@ -14,8 +14,6 @@
 obj-$(CONFIG_IEEE1394_SBP2) += sbp2.o
 obj-$(CONFIG_IEEE1394_DV1394) += dv1394.o
 obj-$(CONFIG_IEEE1394_ETH1394) += eth1394.o
-obj-$(CONFIG_IEEE1394_AMDTP) += amdtp.o
-obj-$(CONFIG_IEEE1394_CMP) += cmp.o
 
 quiet_cmd_oui2c = OUI2C   $@
       cmd_oui2c = $(CONFIG_SHELL) $(srctree)/$(src)/oui2c.sh < $< > $@
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
index 61ddd5d..1577354 100644
--- a/drivers/ieee1394/csr1212.c
+++ b/drivers/ieee1394/csr1212.c
@@ -1261,7 +1261,7 @@
 		return CSR1212_EINVAL;
 #endif
 
-	cr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
+	cr = CSR1212_MALLOC(sizeof(*cr));
 	if (!cr)
 		return CSR1212_ENOMEM;
 
@@ -1393,8 +1393,7 @@
 	case CSR1212_KV_TYPE_LEAF:
 		if (kv->key.id != CSR1212_KV_ID_EXTENDED_ROM) {
 			kv->value.leaf.data = CSR1212_MALLOC(quads_to_bytes(kvi_len));
-			if (!kv->value.leaf.data)
-			{
+			if (!kv->value.leaf.data) {
 				ret = CSR1212_ENOMEM;
 				goto fail;
 			}
@@ -1462,7 +1461,7 @@
 		cache->next = NULL;
 		csr->cache_tail = cache;
 		cache->filled_head =
-			CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
+			CSR1212_MALLOC(sizeof(*cache->filled_head));
 		if (!cache->filled_head) {
 			return CSR1212_ENOMEM;
 		}
@@ -1484,7 +1483,7 @@
 	/* Now seach read portions of the cache to see if it is there. */
 	for (cr = cache->filled_head; cr; cr = cr->next) {
 		if (cache_index < cr->offset_start) {
-			newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
+			newcr = CSR1212_MALLOC(sizeof(*newcr));
 			if (!newcr)
 				return CSR1212_ENOMEM;
 
@@ -1508,7 +1507,7 @@
 
 	if (!cr) {
 		cr = cache->filled_tail;
-		newcr = CSR1212_MALLOC(sizeof(struct csr1212_cache_region));
+		newcr = CSR1212_MALLOC(sizeof(*newcr));
 		if (!newcr)
 			return CSR1212_ENOMEM;
 
@@ -1611,15 +1610,17 @@
 	csr->root_kv->valid = 0;
 	csr->root_kv->next = csr->root_kv;
 	csr->root_kv->prev = csr->root_kv;
-	csr1212_get_keyval(csr, csr->root_kv);
+	ret = _csr1212_read_keyval(csr, csr->root_kv);
+	if (ret != CSR1212_SUCCESS)
+		return ret;
 
 	/* Scan through the Root directory finding all extended ROM regions
 	 * and make cache regions for them */
 	for (dentry = csr->root_kv->value.directory.dentries_head;
 	     dentry; dentry = dentry->next) {
-		if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM) {
-			csr1212_get_keyval(csr, dentry->kv);
-
+		if (dentry->kv->key.id == CSR1212_KV_ID_EXTENDED_ROM &&
+			!dentry->kv->valid) {
+			ret = _csr1212_read_keyval(csr, dentry->kv);
 			if (ret != CSR1212_SUCCESS)
 				return ret;
 		}
diff --git a/drivers/ieee1394/csr1212.h b/drivers/ieee1394/csr1212.h
index 28c5f4b..cecd587 100644
--- a/drivers/ieee1394/csr1212.h
+++ b/drivers/ieee1394/csr1212.h
@@ -646,7 +646,7 @@
 {
 	struct csr1212_csr_rom_cache *cache;
 
-	cache = CSR1212_MALLOC(sizeof(struct csr1212_csr_rom_cache) + size);
+	cache = CSR1212_MALLOC(sizeof(*cache) + size);
 	if (!cache)
 		return NULL;
 
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index b79ddb4..9fb2769 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -23,7 +23,8 @@
 	prog->bus_addr = 0;
 }
 
-int  dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes, struct pci_dev *dev)
+int dma_prog_region_alloc(struct dma_prog_region *prog, unsigned long n_bytes,
+			  struct pci_dev *dev)
 {
 	/* round up to page size */
 	n_bytes = PAGE_ALIGN(n_bytes);
@@ -32,7 +33,8 @@
 
 	prog->kvirt = pci_alloc_consistent(dev, n_bytes, &prog->bus_addr);
 	if (!prog->kvirt) {
-		printk(KERN_ERR "dma_prog_region_alloc: pci_alloc_consistent() failed\n");
+		printk(KERN_ERR
+		       "dma_prog_region_alloc: pci_alloc_consistent() failed\n");
 		dma_prog_region_free(prog);
 		return -ENOMEM;
 	}
@@ -45,7 +47,8 @@
 void dma_prog_region_free(struct dma_prog_region *prog)
 {
 	if (prog->kvirt) {
-		pci_free_consistent(prog->dev, prog->n_pages << PAGE_SHIFT, prog->kvirt, prog->bus_addr);
+		pci_free_consistent(prog->dev, prog->n_pages << PAGE_SHIFT,
+				    prog->kvirt, prog->bus_addr);
 	}
 
 	prog->kvirt = NULL;
@@ -65,7 +68,8 @@
 	dma->sglist = NULL;
 }
 
-int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes, struct pci_dev *dev, int direction)
+int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
+		     struct pci_dev *dev, int direction)
 {
 	unsigned int i;
 
@@ -95,14 +99,16 @@
 
 	/* fill scatter/gather list with pages */
 	for (i = 0; i < dma->n_pages; i++) {
-		unsigned long va = (unsigned long) dma->kvirt + (i << PAGE_SHIFT);
+		unsigned long va =
+		    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
 		dma->sglist[i].page = vmalloc_to_page((void *)va);
 		dma->sglist[i].length = PAGE_SIZE;
 	}
 
 	/* map sglist to the IOMMU */
-	dma->n_dma_pages = pci_map_sg(dev, dma->sglist, dma->n_pages, direction);
+	dma->n_dma_pages =
+	    pci_map_sg(dev, dma->sglist, dma->n_pages, direction);
 
 	if (dma->n_dma_pages == 0) {
 		printk(KERN_ERR "dma_region_alloc: pci_map_sg() failed\n");
@@ -114,7 +120,7 @@
 
 	return 0;
 
-err:
+      err:
 	dma_region_free(dma);
 	return -ENOMEM;
 }
@@ -122,7 +128,8 @@
 void dma_region_free(struct dma_region *dma)
 {
 	if (dma->n_dma_pages) {
-		pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages, dma->direction);
+		pci_unmap_sg(dma->dev, dma->sglist, dma->n_pages,
+			     dma->direction);
 		dma->n_dma_pages = 0;
 		dma->dev = NULL;
 	}
@@ -137,7 +144,8 @@
 
 /* find the scatterlist index and remaining offset corresponding to a
    given offset from the beginning of the buffer */
-static inline int dma_region_find(struct dma_region *dma, unsigned long offset, unsigned long *rem)
+static inline int dma_region_find(struct dma_region *dma, unsigned long offset,
+				  unsigned long *rem)
 {
 	int i;
 	unsigned long off = offset;
@@ -156,15 +164,18 @@
 	return i;
 }
 
-dma_addr_t dma_region_offset_to_bus(struct dma_region *dma, unsigned long offset)
+dma_addr_t dma_region_offset_to_bus(struct dma_region * dma,
+				    unsigned long offset)
 {
 	unsigned long rem = 0;
 
-	struct scatterlist *sg = &dma->sglist[dma_region_find(dma, offset, &rem)];
+	struct scatterlist *sg =
+	    &dma->sglist[dma_region_find(dma, offset, &rem)];
 	return sg_dma_address(sg) + rem;
 }
 
-void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset, unsigned long len)
+void dma_region_sync_for_cpu(struct dma_region *dma, unsigned long offset,
+			     unsigned long len)
 {
 	int first, last;
 	unsigned long rem;
@@ -175,10 +186,12 @@
 	first = dma_region_find(dma, offset, &rem);
 	last = dma_region_find(dma, offset + len - 1, &rem);
 
-	pci_dma_sync_sg_for_cpu(dma->dev, &dma->sglist[first], last - first + 1, dma->direction);
+	pci_dma_sync_sg_for_cpu(dma->dev, &dma->sglist[first], last - first + 1,
+				dma->direction);
 }
 
-void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset, unsigned long len)
+void dma_region_sync_for_device(struct dma_region *dma, unsigned long offset,
+				unsigned long len)
 {
 	int first, last;
 	unsigned long rem;
@@ -189,44 +202,47 @@
 	first = dma_region_find(dma, offset, &rem);
 	last = dma_region_find(dma, offset + len - 1, &rem);
 
-	pci_dma_sync_sg_for_device(dma->dev, &dma->sglist[first], last - first + 1, dma->direction);
+	pci_dma_sync_sg_for_device(dma->dev, &dma->sglist[first],
+				   last - first + 1, dma->direction);
 }
 
 #ifdef CONFIG_MMU
 
 /* nopage() handler for mmap access */
 
-static struct page*
-dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int *type)
+static struct page *dma_region_pagefault(struct vm_area_struct *area,
+					 unsigned long address, int *type)
 {
 	unsigned long offset;
 	unsigned long kernel_virt_addr;
 	struct page *ret = NOPAGE_SIGBUS;
 
-	struct dma_region *dma = (struct dma_region*) area->vm_private_data;
+	struct dma_region *dma = (struct dma_region *)area->vm_private_data;
 
 	if (!dma->kvirt)
 		goto out;
 
-	if ( (address < (unsigned long) area->vm_start) ||
-	    (address > (unsigned long) area->vm_start + (dma->n_pages << PAGE_SHIFT)) )
+	if ((address < (unsigned long)area->vm_start) ||
+	    (address >
+	     (unsigned long)area->vm_start + (dma->n_pages << PAGE_SHIFT)))
 		goto out;
 
 	if (type)
 		*type = VM_FAULT_MINOR;
 	offset = address - area->vm_start;
-	kernel_virt_addr = (unsigned long) dma->kvirt + offset;
-	ret = vmalloc_to_page((void*) kernel_virt_addr);
+	kernel_virt_addr = (unsigned long)dma->kvirt + offset;
+	ret = vmalloc_to_page((void *)kernel_virt_addr);
 	get_page(ret);
-out:
+      out:
 	return ret;
 }
 
 static struct vm_operations_struct dma_region_vm_ops = {
-	.nopage	= dma_region_pagefault,
+	.nopage = dma_region_pagefault,
 };
 
-int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma)
+int dma_region_mmap(struct dma_region *dma, struct file *file,
+		    struct vm_area_struct *vma)
 {
 	unsigned long size;
 
@@ -250,11 +266,12 @@
 	return 0;
 }
 
-#else /* CONFIG_MMU */
+#else				/* CONFIG_MMU */
 
-int dma_region_mmap(struct dma_region *dma, struct file *file, struct vm_area_struct *vma)
+int dma_region_mmap(struct dma_region *dma, struct file *file,
+		    struct vm_area_struct *vma)
 {
 	return -EINVAL;
 }
 
-#endif /* CONFIG_MMU */
+#endif				/* CONFIG_MMU */
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index cbbbe14..196db74 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -123,15 +123,6 @@
 
 #include "ohci1394.h"
 
-#ifndef virt_to_page
-#define virt_to_page(x) MAP_NR(x)
-#endif
-
-#ifndef vmalloc_32
-#define vmalloc_32(x) vmalloc(x)
-#endif
-
-
 /* DEBUG LEVELS:
    0 - no debugging messages
    1 - some debugging messages, but none during DMA frame transmission
@@ -2218,14 +2209,12 @@
 	unsigned long flags;
 	int i;
 
-	video = kmalloc(sizeof(struct video_card), GFP_KERNEL);
+	video = kzalloc(sizeof(*video), GFP_KERNEL);
 	if (!video) {
 		printk(KERN_ERR "dv1394: cannot allocate video_card\n");
 		goto err;
 	}
 
-	memset(video, 0, sizeof(struct video_card));
-
 	video->ohci = ohci;
 	/* lower 2 bits of id indicate which of four "plugs"
 	   per host */
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index c9e92d8..30fa0d4 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -88,9 +88,6 @@
 	printk(KERN_ERR "%s:%s[%d]: " fmt "\n", driver_name, __FUNCTION__, __LINE__, ## args)
 #define TRACE() printk(KERN_ERR "%s:%s[%d] ---- TRACE\n", driver_name, __FUNCTION__, __LINE__)
 
-static char version[] __devinitdata =
-	"$Rev: 1312 $ Ben Collins <bcollins@debian.org>";
-
 struct fragment_info {
 	struct list_head list;
 	int offset;
@@ -355,12 +352,12 @@
 	if (!hi)
 		return -ENOENT;
 
-	new_node = kmalloc(sizeof(struct eth1394_node_ref),
+	new_node = kmalloc(sizeof(*new_node),
 			   in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
 	if (!new_node)
 		return -ENOMEM;
 
-	node_info = kmalloc(sizeof(struct eth1394_node_info),
+	node_info = kmalloc(sizeof(*node_info),
 			    in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
 	if (!node_info) {
 		kfree(new_node);
@@ -436,12 +433,12 @@
 	node = eth1394_find_node(&priv->ip_node_list, ud);
 
 	if (!node) {
-		node = kmalloc(sizeof(struct eth1394_node_ref),
+		node = kmalloc(sizeof(*node),
 			       in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
 		if (!node)
 			return -ENOMEM;
 
-		node_info = kmalloc(sizeof(struct eth1394_node_info),
+		node_info = kmalloc(sizeof(*node_info),
 				    in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
 		if (!node_info) {
 			kfree(node);
@@ -566,7 +563,6 @@
 	struct eth1394_host_info *hi = NULL;
 	struct net_device *dev = NULL;
 	struct eth1394_priv *priv;
-	static int version_printed = 0;
 	u64 fifo_addr;
 
 	if (!(host->config_roms & HPSB_CONFIG_ROM_ENTRY_IP1394))
@@ -581,9 +577,6 @@
 	if (fifo_addr == ~0ULL)
 		goto out;
 
-	if (version_printed++ == 0)
-		ETH1394_PRINT_G (KERN_INFO, "%s\n", version);
-
 	/* We should really have our own alloc_hpsbdev() function in
 	 * net_init.c instead of calling the one for ethernet then hijacking
 	 * it for ourselves.  That way we'd be a real networking device. */
@@ -1021,7 +1014,7 @@
 		}
 	}
 
-	new = kmalloc(sizeof(struct fragment_info), GFP_ATOMIC);
+	new = kmalloc(sizeof(*new), GFP_ATOMIC);
 	if (!new)
 		return -ENOMEM;
 
@@ -1040,7 +1033,7 @@
 {
 	struct partial_datagram *new;
 
-	new = kmalloc(sizeof(struct partial_datagram), GFP_ATOMIC);
+	new = kmalloc(sizeof(*new), GFP_ATOMIC);
 	if (!new)
 		return -ENOMEM;
 
@@ -1768,7 +1761,6 @@
 static void ether1394_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	strcpy (info->driver, driver_name);
-	strcpy (info->version, "$Rev: 1312 $");
 	/* FIXME XXX provide sane businfo */
 	strcpy (info->bus_info, "ieee1394");
 }
diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c
index 997e1bf..734b121 100644
--- a/drivers/ieee1394/highlevel.c
+++ b/drivers/ieee1394/highlevel.c
@@ -101,12 +101,10 @@
 		return NULL;
 	}
 
-	hi = kmalloc(sizeof(*hi) + data_size, GFP_ATOMIC);
+	hi = kzalloc(sizeof(*hi) + data_size, GFP_ATOMIC);
 	if (!hi)
 		return NULL;
 
-	memset(hi, 0, sizeof(*hi) + data_size);
-
 	if (data_size) {
 		data = hi->data = hi + 1;
 		hi->size = data_size;
@@ -326,11 +324,9 @@
 		return retval;
 	}
 
-	as = (struct hpsb_address_serve *)
-		kmalloc(sizeof(struct hpsb_address_serve), GFP_KERNEL);
-	if (as == NULL) {
+	as = kmalloc(sizeof(*as), GFP_KERNEL);
+	if (!as)
 		return retval;
-	}
 
 	INIT_LIST_HEAD(&as->host_list);
 	INIT_LIST_HEAD(&as->hl_list);
@@ -383,11 +379,9 @@
                 return 0;
         }
 
-        as = (struct hpsb_address_serve *)
-                kmalloc(sizeof(struct hpsb_address_serve), GFP_ATOMIC);
-        if (as == NULL) {
-                return 0;
-        }
+	as = kmalloc(sizeof(*as), GFP_ATOMIC);
+	if (!as)
+		return 0;
 
         INIT_LIST_HEAD(&as->host_list);
         INIT_LIST_HEAD(&as->hl_list);
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
index aeeaeb6..ba09741 100644
--- a/drivers/ieee1394/hosts.c
+++ b/drivers/ieee1394/hosts.c
@@ -61,12 +61,12 @@
 
 static int dummy_transmit_packet(struct hpsb_host *h, struct hpsb_packet *p)
 {
-        return 0;
+	return 0;
 }
 
 static int dummy_devctl(struct hpsb_host *h, enum devctl_cmd c, int arg)
 {
-        return -1;
+	return -1;
 }
 
 static int dummy_isoctl(struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg)
@@ -75,9 +75,9 @@
 }
 
 static struct hpsb_host_driver dummy_driver = {
-        .transmit_packet = dummy_transmit_packet,
-        .devctl =          dummy_devctl,
-	.isoctl =          dummy_isoctl
+	.transmit_packet = dummy_transmit_packet,
+	.devctl =	   dummy_devctl,
+	.isoctl =	   dummy_isoctl
 };
 
 static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
@@ -110,13 +110,13 @@
 struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
 				  struct device *dev)
 {
-        struct hpsb_host *h;
+	struct hpsb_host *h;
 	int i;
 	int hostnum = 0;
 
-        h = kmalloc(sizeof(struct hpsb_host) + extra, SLAB_KERNEL);
-        if (!h) return NULL;
-        memset(h, 0, sizeof(struct hpsb_host) + extra);
+	h = kzalloc(sizeof(*h) + extra, SLAB_KERNEL);
+	if (!h)
+		return NULL;
 
 	h->csr.rom = csr1212_create_csr(&csr_bus_ops, CSR_BUS_INFO_SIZE, h);
 	if (!h->csr.rom) {
@@ -125,7 +125,7 @@
 	}
 
 	h->hostdata = h + 1;
-        h->driver = drv;
+	h->driver = drv;
 
 	skb_queue_head_init(&h->pending_packet_queue);
 	INIT_LIST_HEAD(&h->addr_space);
@@ -145,8 +145,8 @@
 	h->timeout.function = abort_timedouts;
 	h->timeout_interval = HZ / 20; // 50ms by default
 
-        h->topology_map = h->csr.topology_map + 3;
-        h->speed_map = (u8 *)(h->csr.speed_map + 2);
+	h->topology_map = h->csr.topology_map + 3;
+	h->speed_map = (u8 *)(h->csr.speed_map + 2);
 
 	down(&host_num_alloc);
 
@@ -186,14 +186,14 @@
 
 void hpsb_remove_host(struct hpsb_host *host)
 {
-        host->is_shutdown = 1;
+	host->is_shutdown = 1;
 
 	cancel_delayed_work(&host->delayed_reset);
 	flush_scheduled_work();
 
-        host->driver = &dummy_driver;
+	host->driver = &dummy_driver;
 
-        highlevel_remove_host(host);
+	highlevel_remove_host(host);
 
 	hpsb_remove_extra_config_roms(host);
 
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h
index 38f4211..07d188c 100644
--- a/drivers/ieee1394/hosts.h
+++ b/drivers/ieee1394/hosts.h
@@ -17,46 +17,47 @@
 struct hpsb_iso;
 
 struct hpsb_host {
-        struct list_head host_list;
+	struct list_head host_list;
 
-        void *hostdata;
+	void *hostdata;
 
-        atomic_t generation;
+	atomic_t generation;
 
 	struct sk_buff_head pending_packet_queue;
 
 	struct timer_list timeout;
 	unsigned long timeout_interval;
 
-        unsigned char iso_listen_count[64];
+	unsigned char iso_listen_count[64];
 
-        int node_count; /* number of identified nodes on this bus */
-        int selfid_count; /* total number of SelfIDs received */
+	int node_count; /* number of identified nodes on this bus */
+	int selfid_count; /* total number of SelfIDs received */
 	int nodes_active; /* number of nodes that are actually active */
 
-        nodeid_t node_id; /* node ID of this host */
-        nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
-        nodeid_t busmgr_id; /* ID of this bus' bus manager */
+	nodeid_t node_id; /* node ID of this host */
+	nodeid_t irm_id; /* ID of this bus' isochronous resource manager */
+	nodeid_t busmgr_id; /* ID of this bus' bus manager */
 
-        /* this nodes state */
-        unsigned in_bus_reset:1;
-        unsigned is_shutdown:1;
+	/* this nodes state */
+	unsigned in_bus_reset:1;
+	unsigned is_shutdown:1;
+	unsigned resume_packet_sent:1;
 
-        /* this nodes' duties on the bus */
-        unsigned is_root:1;
-        unsigned is_cycmst:1;
-        unsigned is_irm:1;
-        unsigned is_busmgr:1;
+	/* this nodes' duties on the bus */
+	unsigned is_root:1;
+	unsigned is_cycmst:1;
+	unsigned is_irm:1;
+	unsigned is_busmgr:1;
 
-        int reset_retries;
-        quadlet_t *topology_map;
-        u8 *speed_map;
-        struct csr_control csr;
+	int reset_retries;
+	quadlet_t *topology_map;
+	u8 *speed_map;
+	struct csr_control csr;
 
 	/* Per node tlabel pool allocation */
 	struct hpsb_tlabel_pool tpool[64];
 
-        struct hpsb_host_driver *driver;
+	struct hpsb_host_driver *driver;
 
 	struct pci_dev *pdev;
 
@@ -76,34 +77,34 @@
 
 
 enum devctl_cmd {
-        /* Host is requested to reset its bus and cancel all outstanding async
-         * requests.  If arg == 1, it shall also attempt to become root on the
-         * bus.  Return void. */
-        RESET_BUS,
+	/* Host is requested to reset its bus and cancel all outstanding async
+	 * requests.  If arg == 1, it shall also attempt to become root on the
+	 * bus.  Return void. */
+	RESET_BUS,
 
-        /* Arg is void, return value is the hardware cycle counter value. */
-        GET_CYCLE_COUNTER,
+	/* Arg is void, return value is the hardware cycle counter value. */
+	GET_CYCLE_COUNTER,
 
-        /* Set the hardware cycle counter to the value in arg, return void.
-         * FIXME - setting is probably not required. */
-        SET_CYCLE_COUNTER,
+	/* Set the hardware cycle counter to the value in arg, return void.
+	 * FIXME - setting is probably not required. */
+	SET_CYCLE_COUNTER,
 
-        /* Configure hardware for new bus ID in arg, return void. */
-        SET_BUS_ID,
+	/* Configure hardware for new bus ID in arg, return void. */
+	SET_BUS_ID,
 
-        /* If arg true, start sending cycle start packets, stop if arg == 0.
-         * Return void. */
-        ACT_CYCLE_MASTER,
+	/* If arg true, start sending cycle start packets, stop if arg == 0.
+	 * Return void. */
+	ACT_CYCLE_MASTER,
 
-        /* Cancel all outstanding async requests without resetting the bus.
-         * Return void. */
-        CANCEL_REQUESTS,
+	/* Cancel all outstanding async requests without resetting the bus.
+	 * Return void. */
+	CANCEL_REQUESTS,
 
-        /* Start or stop receiving isochronous channel in arg.  Return void.
-         * This acts as an optimization hint, hosts are not required not to
-         * listen on unrequested channels. */
-        ISO_LISTEN_CHANNEL,
-        ISO_UNLISTEN_CHANNEL
+	/* Start or stop receiving isochronous channel in arg.  Return void.
+	 * This acts as an optimization hint, hosts are not required not to
+	 * listen on unrequested channels. */
+	ISO_LISTEN_CHANNEL,
+	ISO_UNLISTEN_CHANNEL
 };
 
 enum isoctl_cmd {
@@ -134,13 +135,13 @@
 };
 
 enum reset_types {
-        /* 166 microsecond reset -- only type of reset available on
-           non-1394a capable controllers */
-        LONG_RESET,
+	/* 166 microsecond reset -- only type of reset available on
+	   non-1394a capable controllers */
+	LONG_RESET,
 
-        /* Short (arbitrated) reset -- only available on 1394a capable
-           controllers */
-        SHORT_RESET,
+	/* Short (arbitrated) reset -- only available on 1394a capable
+	   controllers */
+	SHORT_RESET,
 
 	/* Variants that set force_root before issueing the bus reset */
 	LONG_RESET_FORCE_ROOT, SHORT_RESET_FORCE_ROOT,
@@ -158,22 +159,22 @@
 	 * reads to the ConfigROM on its own. */
 	void (*set_hw_config_rom) (struct hpsb_host *host, quadlet_t *config_rom);
 
-        /* This function shall implement packet transmission based on
-         * packet->type.  It shall CRC both parts of the packet (unless
-         * packet->type == raw) and do byte-swapping as necessary or instruct
-         * the hardware to do so.  It can return immediately after the packet
-         * was queued for sending.  After sending, hpsb_sent_packet() has to be
-         * called.  Return 0 on success, negative errno on failure.
-         * NOTE: The function must be callable in interrupt context.
-         */
-        int (*transmit_packet) (struct hpsb_host *host,
-                                struct hpsb_packet *packet);
+	/* This function shall implement packet transmission based on
+	 * packet->type.  It shall CRC both parts of the packet (unless
+	 * packet->type == raw) and do byte-swapping as necessary or instruct
+	 * the hardware to do so.  It can return immediately after the packet
+	 * was queued for sending.  After sending, hpsb_sent_packet() has to be
+	 * called.  Return 0 on success, negative errno on failure.
+	 * NOTE: The function must be callable in interrupt context.
+	 */
+	int (*transmit_packet) (struct hpsb_host *host,
+				struct hpsb_packet *packet);
 
-        /* This function requests miscellanous services from the driver, see
-         * above for command codes and expected actions.  Return -1 for unknown
-         * command, though that should never happen.
-         */
-        int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg);
+	/* This function requests miscellanous services from the driver, see
+	 * above for command codes and expected actions.  Return -1 for unknown
+	 * command, though that should never happen.
+	 */
+	int (*devctl) (struct hpsb_host *host, enum devctl_cmd command, int arg);
 
 	 /* ISO transmission/reception functions. Return 0 on success, -1
 	  * (or -EXXX errno code) on failure. If the low-level driver does not
@@ -181,15 +182,15 @@
 	  */
 	int (*isoctl) (struct hpsb_iso *iso, enum isoctl_cmd command, unsigned long arg);
 
-        /* This function is mainly to redirect local CSR reads/locks to the iso
-         * management registers (bus manager id, bandwidth available, channels
-         * available) to the hardware registers in OHCI.  reg is 0,1,2,3 for bus
-         * mgr, bwdth avail, ch avail hi, ch avail lo respectively (the same ids
-         * as OHCI uses).  data and compare are the new data and expected data
-         * respectively, return value is the old value.
-         */
-        quadlet_t (*hw_csr_reg) (struct hpsb_host *host, int reg,
-                                 quadlet_t data, quadlet_t compare);
+	/* This function is mainly to redirect local CSR reads/locks to the iso
+	 * management registers (bus manager id, bandwidth available, channels
+	 * available) to the hardware registers in OHCI.  reg is 0,1,2,3 for bus
+	 * mgr, bwdth avail, ch avail hi, ch avail lo respectively (the same ids
+	 * as OHCI uses).  data and compare are the new data and expected data
+	 * respectively, return value is the old value.
+	 */
+	quadlet_t (*hw_csr_reg) (struct hpsb_host *host, int reg,
+				 quadlet_t data, quadlet_t compare);
 };
 
 
diff --git a/drivers/ieee1394/ieee1394-ioctl.h b/drivers/ieee1394/ieee1394-ioctl.h
index f92b566..1567039 100644
--- a/drivers/ieee1394/ieee1394-ioctl.h
+++ b/drivers/ieee1394/ieee1394-ioctl.h
@@ -7,14 +7,6 @@
 #include <linux/ioctl.h>
 #include <linux/types.h>
 
-
-/* AMDTP Gets 6 */
-#define AMDTP_IOC_CHANNEL	_IOW('#', 0x00, struct amdtp_ioctl)
-#define AMDTP_IOC_PLUG		_IOW('#', 0x01, struct amdtp_ioctl)
-#define AMDTP_IOC_PING		_IOW('#', 0x02, struct amdtp_ioctl)
-#define AMDTP_IOC_ZAP		_IO ('#', 0x03)
-
-
 /* DV1394 Gets 10 */
 
 /* Get the driver ready to transmit video.  pass a struct dv1394_init* as
diff --git a/drivers/ieee1394/ieee1394.h b/drivers/ieee1394/ieee1394.h
index b634a9b..936d776 100644
--- a/drivers/ieee1394/ieee1394.h
+++ b/drivers/ieee1394/ieee1394.h
@@ -62,6 +62,7 @@
 extern const char *hpsb_speedto_str[];
 
 
+/* 1394a cable PHY packets */
 #define SELFID_PWRCL_NO_POWER    0x0
 #define SELFID_PWRCL_PROVIDE_15W 0x1
 #define SELFID_PWRCL_PROVIDE_30W 0x2
@@ -76,8 +77,24 @@
 #define SELFID_PORT_NCONN        0x1
 #define SELFID_PORT_NONE         0x0
 
+#define PHYPACKET_LINKON			0x40000000
+#define PHYPACKET_PHYCONFIG_R			0x00800000
+#define PHYPACKET_PHYCONFIG_T			0x00400000
+#define EXTPHYPACKET_TYPE_PING			0x00000000
+#define EXTPHYPACKET_TYPE_REMOTEACCESS_BASE	0x00040000
+#define EXTPHYPACKET_TYPE_REMOTEACCESS_PAGED	0x00140000
+#define EXTPHYPACKET_TYPE_REMOTEREPLY_BASE	0x000C0000
+#define EXTPHYPACKET_TYPE_REMOTEREPLY_PAGED	0x001C0000
+#define EXTPHYPACKET_TYPE_REMOTECOMMAND		0x00200000
+#define EXTPHYPACKET_TYPE_REMOTECONFIRMATION	0x00280000
+#define EXTPHYPACKET_TYPE_RESUME		0x003C0000
 
-/* 1394a PHY bitmasks */
+#define EXTPHYPACKET_TYPEMASK			0xC0FC0000
+
+#define PHYPACKET_PORT_SHIFT     24
+#define PHYPACKET_GAPCOUNT_SHIFT 16
+
+/* 1394a PHY register map bitmasks */
 #define PHY_00_PHYSICAL_ID       0xFC
 #define PHY_00_R                 0x02 /* Root */
 #define PHY_00_PS                0x01 /* Power Status*/
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 32a1e01..25ef5a8 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -179,34 +179,34 @@
 
 int hpsb_reset_bus(struct hpsb_host *host, int type)
 {
-        if (!host->in_bus_reset) {
-                host->driver->devctl(host, RESET_BUS, type);
-                return 0;
-        } else {
-                return 1;
-        }
+	if (!host->in_bus_reset) {
+		host->driver->devctl(host, RESET_BUS, type);
+		return 0;
+	} else {
+		return 1;
+	}
 }
 
 
 int hpsb_bus_reset(struct hpsb_host *host)
 {
-        if (host->in_bus_reset) {
-                HPSB_NOTICE("%s called while bus reset already in progress",
+	if (host->in_bus_reset) {
+		HPSB_NOTICE("%s called while bus reset already in progress",
 			    __FUNCTION__);
-                return 1;
-        }
+		return 1;
+	}
 
-        abort_requests(host);
-        host->in_bus_reset = 1;
-        host->irm_id = -1;
+	abort_requests(host);
+	host->in_bus_reset = 1;
+	host->irm_id = -1;
 	host->is_irm = 0;
-        host->busmgr_id = -1;
+	host->busmgr_id = -1;
 	host->is_busmgr = 0;
 	host->is_cycmst = 0;
-        host->node_count = 0;
-        host->selfid_count = 0;
+	host->node_count = 0;
+	host->selfid_count = 0;
 
-        return 0;
+	return 0;
 }
 
 
@@ -216,150 +216,156 @@
  */
 static int check_selfids(struct hpsb_host *host)
 {
-        int nodeid = -1;
-        int rest_of_selfids = host->selfid_count;
-        struct selfid *sid = (struct selfid *)host->topology_map;
-        struct ext_selfid *esid;
-        int esid_seq = 23;
+	int nodeid = -1;
+	int rest_of_selfids = host->selfid_count;
+	struct selfid *sid = (struct selfid *)host->topology_map;
+	struct ext_selfid *esid;
+	int esid_seq = 23;
 
 	host->nodes_active = 0;
 
-        while (rest_of_selfids--) {
-                if (!sid->extended) {
-                        nodeid++;
-                        esid_seq = 0;
+	while (rest_of_selfids--) {
+		if (!sid->extended) {
+			nodeid++;
+			esid_seq = 0;
 
-                        if (sid->phy_id != nodeid) {
-                                HPSB_INFO("SelfIDs failed monotony check with "
-                                          "%d", sid->phy_id);
-                                return 0;
-                        }
+			if (sid->phy_id != nodeid) {
+				HPSB_INFO("SelfIDs failed monotony check with "
+					  "%d", sid->phy_id);
+				return 0;
+			}
 
 			if (sid->link_active) {
 				host->nodes_active++;
 				if (sid->contender)
 					host->irm_id = LOCAL_BUS | sid->phy_id;
 			}
-                } else {
-                        esid = (struct ext_selfid *)sid;
+		} else {
+			esid = (struct ext_selfid *)sid;
 
-                        if ((esid->phy_id != nodeid)
-                            || (esid->seq_nr != esid_seq)) {
-                                HPSB_INFO("SelfIDs failed monotony check with "
-                                          "%d/%d", esid->phy_id, esid->seq_nr);
-                                return 0;
-                        }
-                        esid_seq++;
-                }
-                sid++;
-        }
+			if ((esid->phy_id != nodeid)
+			    || (esid->seq_nr != esid_seq)) {
+				HPSB_INFO("SelfIDs failed monotony check with "
+					  "%d/%d", esid->phy_id, esid->seq_nr);
+				return 0;
+			}
+			esid_seq++;
+		}
+		sid++;
+	}
 
-        esid = (struct ext_selfid *)(sid - 1);
-        while (esid->extended) {
-                if ((esid->porta == 0x2) || (esid->portb == 0x2)
-                    || (esid->portc == 0x2) || (esid->portd == 0x2)
-                    || (esid->porte == 0x2) || (esid->portf == 0x2)
-                    || (esid->portg == 0x2) || (esid->porth == 0x2)) {
+	esid = (struct ext_selfid *)(sid - 1);
+	while (esid->extended) {
+		if ((esid->porta == SELFID_PORT_PARENT) ||
+		    (esid->portb == SELFID_PORT_PARENT) ||
+		    (esid->portc == SELFID_PORT_PARENT) ||
+		    (esid->portd == SELFID_PORT_PARENT) ||
+		    (esid->porte == SELFID_PORT_PARENT) ||
+		    (esid->portf == SELFID_PORT_PARENT) ||
+		    (esid->portg == SELFID_PORT_PARENT) ||
+		    (esid->porth == SELFID_PORT_PARENT)) {
 			HPSB_INFO("SelfIDs failed root check on "
 				  "extended SelfID");
 			return 0;
-                }
-                esid--;
-        }
+		}
+		esid--;
+	}
 
-        sid = (struct selfid *)esid;
-        if ((sid->port0 == 0x2) || (sid->port1 == 0x2) || (sid->port2 == 0x2)) {
+	sid = (struct selfid *)esid;
+	if ((sid->port0 == SELFID_PORT_PARENT) ||
+	    (sid->port1 == SELFID_PORT_PARENT) ||
+	    (sid->port2 == SELFID_PORT_PARENT)) {
 		HPSB_INFO("SelfIDs failed root check");
 		return 0;
-        }
+	}
 
 	host->node_count = nodeid + 1;
-        return 1;
+	return 1;
 }
 
 static void build_speed_map(struct hpsb_host *host, int nodecount)
 {
 	u8 speedcap[nodecount];
 	u8 cldcnt[nodecount];
-        u8 *map = host->speed_map;
-        struct selfid *sid;
-        struct ext_selfid *esid;
-        int i, j, n;
+	u8 *map = host->speed_map;
+	struct selfid *sid;
+	struct ext_selfid *esid;
+	int i, j, n;
 
-        for (i = 0; i < (nodecount * 64); i += 64) {
-                for (j = 0; j < nodecount; j++) {
-                        map[i+j] = IEEE1394_SPEED_MAX;
-                }
-        }
+	for (i = 0; i < (nodecount * 64); i += 64) {
+		for (j = 0; j < nodecount; j++) {
+			map[i+j] = IEEE1394_SPEED_MAX;
+		}
+	}
 
-        for (i = 0; i < nodecount; i++) {
-                cldcnt[i] = 0;
-        }
+	for (i = 0; i < nodecount; i++) {
+		cldcnt[i] = 0;
+	}
 
-        /* find direct children count and speed */
-        for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1],
-                     n = nodecount - 1;
-             (void *)sid >= (void *)host->topology_map; sid--) {
-                if (sid->extended) {
-                        esid = (struct ext_selfid *)sid;
+	/* find direct children count and speed */
+	for (sid = (struct selfid *)&host->topology_map[host->selfid_count-1],
+		     n = nodecount - 1;
+	     (void *)sid >= (void *)host->topology_map; sid--) {
+		if (sid->extended) {
+			esid = (struct ext_selfid *)sid;
 
-                        if (esid->porta == 0x3) cldcnt[n]++;
-                        if (esid->portb == 0x3) cldcnt[n]++;
-                        if (esid->portc == 0x3) cldcnt[n]++;
-                        if (esid->portd == 0x3) cldcnt[n]++;
-                        if (esid->porte == 0x3) cldcnt[n]++;
-                        if (esid->portf == 0x3) cldcnt[n]++;
-                        if (esid->portg == 0x3) cldcnt[n]++;
-                        if (esid->porth == 0x3) cldcnt[n]++;
+			if (esid->porta == SELFID_PORT_CHILD) cldcnt[n]++;
+			if (esid->portb == SELFID_PORT_CHILD) cldcnt[n]++;
+			if (esid->portc == SELFID_PORT_CHILD) cldcnt[n]++;
+			if (esid->portd == SELFID_PORT_CHILD) cldcnt[n]++;
+			if (esid->porte == SELFID_PORT_CHILD) cldcnt[n]++;
+			if (esid->portf == SELFID_PORT_CHILD) cldcnt[n]++;
+			if (esid->portg == SELFID_PORT_CHILD) cldcnt[n]++;
+			if (esid->porth == SELFID_PORT_CHILD) cldcnt[n]++;
                 } else {
-                        if (sid->port0 == 0x3) cldcnt[n]++;
-                        if (sid->port1 == 0x3) cldcnt[n]++;
-                        if (sid->port2 == 0x3) cldcnt[n]++;
+			if (sid->port0 == SELFID_PORT_CHILD) cldcnt[n]++;
+			if (sid->port1 == SELFID_PORT_CHILD) cldcnt[n]++;
+			if (sid->port2 == SELFID_PORT_CHILD) cldcnt[n]++;
 
-                        speedcap[n] = sid->speed;
-                        n--;
-                }
-        }
+			speedcap[n] = sid->speed;
+			n--;
+		}
+	}
 
-        /* set self mapping */
-        for (i = 0; i < nodecount; i++) {
-                map[64*i + i] = speedcap[i];
-        }
+	/* set self mapping */
+	for (i = 0; i < nodecount; i++) {
+		map[64*i + i] = speedcap[i];
+	}
 
-        /* fix up direct children count to total children count;
-         * also fix up speedcaps for sibling and parent communication */
-        for (i = 1; i < nodecount; i++) {
-                for (j = cldcnt[i], n = i - 1; j > 0; j--) {
-                        cldcnt[i] += cldcnt[n];
-                        speedcap[n] = min(speedcap[n], speedcap[i]);
-                        n -= cldcnt[n] + 1;
-                }
-        }
+	/* fix up direct children count to total children count;
+	 * also fix up speedcaps for sibling and parent communication */
+	for (i = 1; i < nodecount; i++) {
+		for (j = cldcnt[i], n = i - 1; j > 0; j--) {
+			cldcnt[i] += cldcnt[n];
+			speedcap[n] = min(speedcap[n], speedcap[i]);
+			n -= cldcnt[n] + 1;
+		}
+	}
 
-        for (n = 0; n < nodecount; n++) {
-                for (i = n - cldcnt[n]; i <= n; i++) {
-                        for (j = 0; j < (n - cldcnt[n]); j++) {
-                                map[j*64 + i] = map[i*64 + j] =
-                                        min(map[i*64 + j], speedcap[n]);
-                        }
-                        for (j = n + 1; j < nodecount; j++) {
-                                map[j*64 + i] = map[i*64 + j] =
-                                        min(map[i*64 + j], speedcap[n]);
-                        }
-                }
-        }
+	for (n = 0; n < nodecount; n++) {
+		for (i = n - cldcnt[n]; i <= n; i++) {
+			for (j = 0; j < (n - cldcnt[n]); j++) {
+				map[j*64 + i] = map[i*64 + j] =
+					min(map[i*64 + j], speedcap[n]);
+			}
+			for (j = n + 1; j < nodecount; j++) {
+				map[j*64 + i] = map[i*64 + j] =
+					min(map[i*64 + j], speedcap[n]);
+			}
+		}
+	}
 }
 
 
 void hpsb_selfid_received(struct hpsb_host *host, quadlet_t sid)
 {
-        if (host->in_bus_reset) {
-                HPSB_VERBOSE("Including SelfID 0x%x", sid);
-                host->topology_map[host->selfid_count++] = sid;
-        } else {
-                HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d",
+	if (host->in_bus_reset) {
+		HPSB_VERBOSE("Including SelfID 0x%x", sid);
+		host->topology_map[host->selfid_count++] = sid;
+	} else {
+		HPSB_NOTICE("Spurious SelfID packet (0x%08x) received from bus %d",
 			    sid, NODEID_TO_BUS(host->node_id));
-        }
+	}
 }
 
 void hpsb_selfid_complete(struct hpsb_host *host, int phyid, int isroot)
@@ -367,50 +373,50 @@
 	if (!host->in_bus_reset)
 		HPSB_NOTICE("SelfID completion called outside of bus reset!");
 
-        host->node_id = LOCAL_BUS | phyid;
-        host->is_root = isroot;
+	host->node_id = LOCAL_BUS | phyid;
+	host->is_root = isroot;
 
-        if (!check_selfids(host)) {
-                if (host->reset_retries++ < 20) {
-                        /* selfid stage did not complete without error */
-                        HPSB_NOTICE("Error in SelfID stage, resetting");
+	if (!check_selfids(host)) {
+		if (host->reset_retries++ < 20) {
+			/* selfid stage did not complete without error */
+			HPSB_NOTICE("Error in SelfID stage, resetting");
 			host->in_bus_reset = 0;
 			/* this should work from ohci1394 now... */
-                        hpsb_reset_bus(host, LONG_RESET);
-                        return;
-                } else {
-                        HPSB_NOTICE("Stopping out-of-control reset loop");
-                        HPSB_NOTICE("Warning - topology map and speed map will not be valid");
+			hpsb_reset_bus(host, LONG_RESET);
+			return;
+		} else {
+			HPSB_NOTICE("Stopping out-of-control reset loop");
+			HPSB_NOTICE("Warning - topology map and speed map will not be valid");
 			host->reset_retries = 0;
-                }
-        } else {
+		}
+	} else {
 		host->reset_retries = 0;
-                build_speed_map(host, host->node_count);
-        }
+		build_speed_map(host, host->node_count);
+	}
 
 	HPSB_VERBOSE("selfid_complete called with successful SelfID stage "
 		     "... irm_id: 0x%X node_id: 0x%X",host->irm_id,host->node_id);
 
-        /* irm_id is kept up to date by check_selfids() */
-        if (host->irm_id == host->node_id) {
-                host->is_irm = 1;
-        } else {
-                host->is_busmgr = 0;
-                host->is_irm = 0;
-        }
+	/* irm_id is kept up to date by check_selfids() */
+	if (host->irm_id == host->node_id) {
+		host->is_irm = 1;
+	} else {
+		host->is_busmgr = 0;
+		host->is_irm = 0;
+	}
 
-        if (isroot) {
+	if (isroot) {
 		host->driver->devctl(host, ACT_CYCLE_MASTER, 1);
 		host->is_cycmst = 1;
 	}
 	atomic_inc(&host->generation);
 	host->in_bus_reset = 0;
-        highlevel_host_reset(host);
+	highlevel_host_reset(host);
 }
 
 
 void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
-                      int ackcode)
+		      int ackcode)
 {
 	unsigned long flags;
 
@@ -457,6 +463,7 @@
 int hpsb_send_phy_config(struct hpsb_host *host, int rootid, int gapcnt)
 {
 	struct hpsb_packet *packet;
+	quadlet_t d = 0;
 	int retval = 0;
 
 	if (rootid >= ALL_NODES || rootid < -1 || gapcnt > 0x3f || gapcnt < -1 ||
@@ -466,26 +473,16 @@
 		return -EINVAL;
 	}
 
-	packet = hpsb_alloc_packet(0);
+	if (rootid != -1)
+		d |= PHYPACKET_PHYCONFIG_R | rootid << PHYPACKET_PORT_SHIFT;
+	if (gapcnt != -1)
+		d |= PHYPACKET_PHYCONFIG_T | gapcnt << PHYPACKET_GAPCOUNT_SHIFT;
+
+	packet = hpsb_make_phypacket(host, d);
 	if (!packet)
 		return -ENOMEM;
 
-	packet->host = host;
-	packet->header_size = 8;
-	packet->data_size = 0;
-	packet->expect_response = 0;
-	packet->no_waiter = 0;
-	packet->type = hpsb_raw;
-	packet->header[0] = 0;
-	if (rootid != -1)
-		packet->header[0] |= rootid << 24 | 1 << 23;
-	if (gapcnt != -1)
-		packet->header[0] |= gapcnt << 16 | 1 << 22;
-
-	packet->header[1] = ~packet->header[0];
-
 	packet->generation = get_hpsb_generation(host);
-
 	retval = hpsb_send_packet_and_wait(packet);
 	hpsb_free_packet(packet);
 
@@ -510,13 +507,13 @@
 {
 	struct hpsb_host *host = packet->host;
 
-        if (host->is_shutdown)
+	if (host->is_shutdown)
 		return -EINVAL;
 	if (host->in_bus_reset ||
 	    (packet->generation != get_hpsb_generation(host)))
-                return -EAGAIN;
+		return -EAGAIN;
 
-        packet->state = hpsb_queued;
+	packet->state = hpsb_queued;
 
 	/* This just seems silly to me */
 	WARN_ON(packet->no_waiter && packet->expect_response);
@@ -530,42 +527,42 @@
 		skb_queue_tail(&host->pending_packet_queue, packet->skb);
 	}
 
-        if (packet->node_id == host->node_id) {
+	if (packet->node_id == host->node_id) {
 		/* it is a local request, so handle it locally */
 
-                quadlet_t *data;
-                size_t size = packet->data_size + packet->header_size;
+		quadlet_t *data;
+		size_t size = packet->data_size + packet->header_size;
 
-                data = kmalloc(size, GFP_ATOMIC);
-                if (!data) {
-                        HPSB_ERR("unable to allocate memory for concatenating header and data");
-                        return -ENOMEM;
-                }
+		data = kmalloc(size, GFP_ATOMIC);
+		if (!data) {
+			HPSB_ERR("unable to allocate memory for concatenating header and data");
+			return -ENOMEM;
+		}
 
-                memcpy(data, packet->header, packet->header_size);
+		memcpy(data, packet->header, packet->header_size);
 
-                if (packet->data_size)
+		if (packet->data_size)
 			memcpy(((u8*)data) + packet->header_size, packet->data, packet->data_size);
 
-                dump_packet("send packet local", packet->header, packet->header_size, -1);
+		dump_packet("send packet local", packet->header, packet->header_size, -1);
 
-                hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE);
-                hpsb_packet_received(host, data, size, 0);
+		hpsb_packet_sent(host, packet, packet->expect_response ? ACK_PENDING : ACK_COMPLETE);
+		hpsb_packet_received(host, data, size, 0);
 
-                kfree(data);
+		kfree(data);
 
-                return 0;
-        }
+		return 0;
+	}
 
-        if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
-                packet->speed_code =
-                        host->speed_map[NODEID_TO_NODE(host->node_id) * 64
-                                       + NODEID_TO_NODE(packet->node_id)];
-        }
+	if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {
+		packet->speed_code =
+			host->speed_map[NODEID_TO_NODE(host->node_id) * 64
+				       + NODEID_TO_NODE(packet->node_id)];
+	}
 
-        dump_packet("send packet", packet->header, packet->header_size, packet->speed_code);
+	dump_packet("send packet", packet->header, packet->header_size, packet->speed_code);
 
-        return host->driver->transmit_packet(host, packet);
+	return host->driver->transmit_packet(host, packet);
 }
 
 /* We could just use complete() directly as the packet complete
@@ -593,81 +590,81 @@
 
 static void send_packet_nocare(struct hpsb_packet *packet)
 {
-        if (hpsb_send_packet(packet) < 0) {
-                hpsb_free_packet(packet);
-        }
+	if (hpsb_send_packet(packet) < 0) {
+		hpsb_free_packet(packet);
+	}
 }
 
 
 static void handle_packet_response(struct hpsb_host *host, int tcode,
 				   quadlet_t *data, size_t size)
 {
-        struct hpsb_packet *packet = NULL;
+	struct hpsb_packet *packet = NULL;
 	struct sk_buff *skb;
-        int tcode_match = 0;
-        int tlabel;
-        unsigned long flags;
+	int tcode_match = 0;
+	int tlabel;
+	unsigned long flags;
 
-        tlabel = (data[0] >> 10) & 0x3f;
+	tlabel = (data[0] >> 10) & 0x3f;
 
 	spin_lock_irqsave(&host->pending_packet_queue.lock, flags);
 
 	skb_queue_walk(&host->pending_packet_queue, skb) {
 		packet = (struct hpsb_packet *)skb->data;
-                if ((packet->tlabel == tlabel)
-                    && (packet->node_id == (data[1] >> 16))){
-                        break;
-                }
+		if ((packet->tlabel == tlabel)
+		    && (packet->node_id == (data[1] >> 16))){
+			break;
+		}
 
 		packet = NULL;
-        }
+	}
 
 	if (packet == NULL) {
-                HPSB_DEBUG("unsolicited response packet received - no tlabel match");
-                dump_packet("contents", data, 16, -1);
+		HPSB_DEBUG("unsolicited response packet received - no tlabel match");
+		dump_packet("contents", data, 16, -1);
 		spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
-                return;
-        }
+		return;
+	}
 
-        switch (packet->tcode) {
-        case TCODE_WRITEQ:
-        case TCODE_WRITEB:
-                if (tcode != TCODE_WRITE_RESPONSE)
+	switch (packet->tcode) {
+	case TCODE_WRITEQ:
+	case TCODE_WRITEB:
+		if (tcode != TCODE_WRITE_RESPONSE)
 			break;
 		tcode_match = 1;
 		memcpy(packet->header, data, 12);
-                break;
-        case TCODE_READQ:
-                if (tcode != TCODE_READQ_RESPONSE)
+		break;
+	case TCODE_READQ:
+		if (tcode != TCODE_READQ_RESPONSE)
 			break;
 		tcode_match = 1;
 		memcpy(packet->header, data, 16);
-                break;
-        case TCODE_READB:
-                if (tcode != TCODE_READB_RESPONSE)
+		break;
+	case TCODE_READB:
+		if (tcode != TCODE_READB_RESPONSE)
 			break;
 		tcode_match = 1;
 		BUG_ON(packet->skb->len - sizeof(*packet) < size - 16);
 		memcpy(packet->header, data, 16);
 		memcpy(packet->data, data + 4, size - 16);
-                break;
-        case TCODE_LOCK_REQUEST:
-                if (tcode != TCODE_LOCK_RESPONSE)
+		break;
+	case TCODE_LOCK_REQUEST:
+		if (tcode != TCODE_LOCK_RESPONSE)
 			break;
 		tcode_match = 1;
 		size = min((size - 16), (size_t)8);
 		BUG_ON(packet->skb->len - sizeof(*packet) < size);
 		memcpy(packet->header, data, 16);
 		memcpy(packet->data, data + 4, size);
-                break;
-        }
+		break;
+	}
 
-        if (!tcode_match) {
+	if (!tcode_match) {
 		spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);
-                HPSB_INFO("unsolicited response packet received - tcode mismatch");
-                dump_packet("contents", data, 16, -1);
-                return;
-        }
+		HPSB_INFO("unsolicited response packet received - tcode mismatch");
+		dump_packet("contents", data, 16, -1);
+		return;
+	}
 
 	__skb_unlink(skb, &host->pending_packet_queue);
 
@@ -686,27 +683,27 @@
 static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,
 					       quadlet_t *data, size_t dsize)
 {
-        struct hpsb_packet *p;
+	struct hpsb_packet *p;
 
-        p = hpsb_alloc_packet(dsize);
-        if (unlikely(p == NULL)) {
-                /* FIXME - send data_error response */
-                return NULL;
-        }
+	p = hpsb_alloc_packet(dsize);
+	if (unlikely(p == NULL)) {
+		/* FIXME - send data_error response */
+		return NULL;
+	}
 
-        p->type = hpsb_async;
-        p->state = hpsb_unused;
-        p->host = host;
-        p->node_id = data[1] >> 16;
-        p->tlabel = (data[0] >> 10) & 0x3f;
-        p->no_waiter = 1;
+	p->type = hpsb_async;
+	p->state = hpsb_unused;
+	p->host = host;
+	p->node_id = data[1] >> 16;
+	p->tlabel = (data[0] >> 10) & 0x3f;
+	p->no_waiter = 1;
 
 	p->generation = get_hpsb_generation(host);
 
 	if (dsize % 4)
 		p->data[dsize / 4] = 0;
 
-        return p;
+	return p;
 }
 
 #define PREP_ASYNC_HEAD_RCODE(tc) \
@@ -717,7 +714,7 @@
 	packet->header[2] = 0
 
 static void fill_async_readquad_resp(struct hpsb_packet *packet, int rcode,
-                              quadlet_t data)
+			      quadlet_t data)
 {
 	PREP_ASYNC_HEAD_RCODE(TCODE_READQ_RESPONSE);
 	packet->header[3] = data;
@@ -726,7 +723,7 @@
 }
 
 static void fill_async_readblock_resp(struct hpsb_packet *packet, int rcode,
-                               int length)
+			       int length)
 {
 	if (rcode != RCODE_COMPLETE)
 		length = 0;
@@ -746,7 +743,7 @@
 }
 
 static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extcode,
-                          int length)
+			  int length)
 {
 	if (rcode != RCODE_COMPLETE)
 		length = 0;
@@ -758,184 +755,184 @@
 }
 
 #define PREP_REPLY_PACKET(length) \
-                packet = create_reply_packet(host, data, length); \
-                if (packet == NULL) break
+		packet = create_reply_packet(host, data, length); \
+		if (packet == NULL) break
 
 static void handle_incoming_packet(struct hpsb_host *host, int tcode,
 				   quadlet_t *data, size_t size, int write_acked)
 {
-        struct hpsb_packet *packet;
-        int length, rcode, extcode;
-        quadlet_t buffer;
-        nodeid_t source = data[1] >> 16;
-        nodeid_t dest = data[0] >> 16;
-        u16 flags = (u16) data[0];
-        u64 addr;
+	struct hpsb_packet *packet;
+	int length, rcode, extcode;
+	quadlet_t buffer;
+	nodeid_t source = data[1] >> 16;
+	nodeid_t dest = data[0] >> 16;
+	u16 flags = (u16) data[0];
+	u64 addr;
 
-        /* big FIXME - no error checking is done for an out of bounds length */
+	/* big FIXME - no error checking is done for an out of bounds length */
 
-        switch (tcode) {
-        case TCODE_WRITEQ:
-                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
-                rcode = highlevel_write(host, source, dest, data+3,
+	switch (tcode) {
+	case TCODE_WRITEQ:
+		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+		rcode = highlevel_write(host, source, dest, data+3,
 					addr, 4, flags);
 
-                if (!write_acked
-                    && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
-                    && (rcode >= 0)) {
-                        /* not a broadcast write, reply */
-                        PREP_REPLY_PACKET(0);
-                        fill_async_write_resp(packet, rcode);
-                        send_packet_nocare(packet);
-                }
-                break;
+		if (!write_acked
+		    && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
+		    && (rcode >= 0)) {
+			/* not a broadcast write, reply */
+			PREP_REPLY_PACKET(0);
+			fill_async_write_resp(packet, rcode);
+			send_packet_nocare(packet);
+		}
+		break;
 
-        case TCODE_WRITEB:
-                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
-                rcode = highlevel_write(host, source, dest, data+4,
+	case TCODE_WRITEB:
+		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+		rcode = highlevel_write(host, source, dest, data+4,
 					addr, data[3]>>16, flags);
 
-                if (!write_acked
-                    && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
-                    && (rcode >= 0)) {
-                        /* not a broadcast write, reply */
-                        PREP_REPLY_PACKET(0);
-                        fill_async_write_resp(packet, rcode);
-                        send_packet_nocare(packet);
-                }
-                break;
+		if (!write_acked
+		    && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
+		    && (rcode >= 0)) {
+			/* not a broadcast write, reply */
+			PREP_REPLY_PACKET(0);
+			fill_async_write_resp(packet, rcode);
+			send_packet_nocare(packet);
+		}
+		break;
 
-        case TCODE_READQ:
-                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
-                rcode = highlevel_read(host, source, &buffer, addr, 4, flags);
+	case TCODE_READQ:
+		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+		rcode = highlevel_read(host, source, &buffer, addr, 4, flags);
 
-                if (rcode >= 0) {
-                        PREP_REPLY_PACKET(0);
-                        fill_async_readquad_resp(packet, rcode, buffer);
-                        send_packet_nocare(packet);
-                }
-                break;
+		if (rcode >= 0) {
+			PREP_REPLY_PACKET(0);
+			fill_async_readquad_resp(packet, rcode, buffer);
+			send_packet_nocare(packet);
+		}
+		break;
 
-        case TCODE_READB:
-                length = data[3] >> 16;
-                PREP_REPLY_PACKET(length);
+	case TCODE_READB:
+		length = data[3] >> 16;
+		PREP_REPLY_PACKET(length);
 
-                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
-                rcode = highlevel_read(host, source, packet->data, addr,
-                                       length, flags);
+		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+		rcode = highlevel_read(host, source, packet->data, addr,
+				       length, flags);
 
-                if (rcode >= 0) {
-                        fill_async_readblock_resp(packet, rcode, length);
-                        send_packet_nocare(packet);
-                } else {
-                        hpsb_free_packet(packet);
-                }
-                break;
+		if (rcode >= 0) {
+			fill_async_readblock_resp(packet, rcode, length);
+			send_packet_nocare(packet);
+		} else {
+			hpsb_free_packet(packet);
+		}
+		break;
 
-        case TCODE_LOCK_REQUEST:
-                length = data[3] >> 16;
-                extcode = data[3] & 0xffff;
-                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
+	case TCODE_LOCK_REQUEST:
+		length = data[3] >> 16;
+		extcode = data[3] & 0xffff;
+		addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
 
-                PREP_REPLY_PACKET(8);
+		PREP_REPLY_PACKET(8);
 
-                if ((extcode == 0) || (extcode >= 7)) {
-                        /* let switch default handle error */
-                        length = 0;
-                }
+		if ((extcode == 0) || (extcode >= 7)) {
+			/* let switch default handle error */
+			length = 0;
+		}
 
-                switch (length) {
-                case 4:
-                        rcode = highlevel_lock(host, source, packet->data, addr,
-                                               data[4], 0, extcode,flags);
-                        fill_async_lock_resp(packet, rcode, extcode, 4);
-                        break;
-                case 8:
-                        if ((extcode != EXTCODE_FETCH_ADD)
-                            && (extcode != EXTCODE_LITTLE_ADD)) {
-                                rcode = highlevel_lock(host, source,
-                                                       packet->data, addr,
-                                                       data[5], data[4],
-                                                       extcode, flags);
-                                fill_async_lock_resp(packet, rcode, extcode, 4);
-                        } else {
-                                rcode = highlevel_lock64(host, source,
-                                             (octlet_t *)packet->data, addr,
-                                             *(octlet_t *)(data + 4), 0ULL,
-                                             extcode, flags);
-                                fill_async_lock_resp(packet, rcode, extcode, 8);
-                        }
-                        break;
-                case 16:
-                        rcode = highlevel_lock64(host, source,
-                                                 (octlet_t *)packet->data, addr,
-                                                 *(octlet_t *)(data + 6),
-                                                 *(octlet_t *)(data + 4),
-                                                 extcode, flags);
-                        fill_async_lock_resp(packet, rcode, extcode, 8);
-                        break;
-                default:
-                        rcode = RCODE_TYPE_ERROR;
-                        fill_async_lock_resp(packet, rcode,
-                                             extcode, 0);
-                }
+		switch (length) {
+		case 4:
+			rcode = highlevel_lock(host, source, packet->data, addr,
+					       data[4], 0, extcode,flags);
+			fill_async_lock_resp(packet, rcode, extcode, 4);
+			break;
+		case 8:
+			if ((extcode != EXTCODE_FETCH_ADD)
+			    && (extcode != EXTCODE_LITTLE_ADD)) {
+				rcode = highlevel_lock(host, source,
+						       packet->data, addr,
+						       data[5], data[4],
+						       extcode, flags);
+				fill_async_lock_resp(packet, rcode, extcode, 4);
+			} else {
+				rcode = highlevel_lock64(host, source,
+					     (octlet_t *)packet->data, addr,
+					     *(octlet_t *)(data + 4), 0ULL,
+					     extcode, flags);
+				fill_async_lock_resp(packet, rcode, extcode, 8);
+			}
+			break;
+		case 16:
+			rcode = highlevel_lock64(host, source,
+						 (octlet_t *)packet->data, addr,
+						 *(octlet_t *)(data + 6),
+						 *(octlet_t *)(data + 4),
+						 extcode, flags);
+			fill_async_lock_resp(packet, rcode, extcode, 8);
+			break;
+		default:
+			rcode = RCODE_TYPE_ERROR;
+			fill_async_lock_resp(packet, rcode,
+					     extcode, 0);
+		}
 
-                if (rcode >= 0) {
-                        send_packet_nocare(packet);
-                } else {
-                        hpsb_free_packet(packet);
-                }
-                break;
-        }
+		if (rcode >= 0) {
+			send_packet_nocare(packet);
+		} else {
+			hpsb_free_packet(packet);
+		}
+		break;
+	}
 
 }
 #undef PREP_REPLY_PACKET
 
 
 void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
-                          int write_acked)
+			  int write_acked)
 {
-        int tcode;
+	int tcode;
 
-        if (host->in_bus_reset) {
-                HPSB_INFO("received packet during reset; ignoring");
-                return;
-        }
+	if (host->in_bus_reset) {
+		HPSB_INFO("received packet during reset; ignoring");
+		return;
+	}
 
-        dump_packet("received packet", data, size, -1);
+	dump_packet("received packet", data, size, -1);
 
-        tcode = (data[0] >> 4) & 0xf;
+	tcode = (data[0] >> 4) & 0xf;
 
-        switch (tcode) {
-        case TCODE_WRITE_RESPONSE:
-        case TCODE_READQ_RESPONSE:
-        case TCODE_READB_RESPONSE:
-        case TCODE_LOCK_RESPONSE:
-                handle_packet_response(host, tcode, data, size);
-                break;
+	switch (tcode) {
+	case TCODE_WRITE_RESPONSE:
+	case TCODE_READQ_RESPONSE:
+	case TCODE_READB_RESPONSE:
+	case TCODE_LOCK_RESPONSE:
+		handle_packet_response(host, tcode, data, size);
+		break;
 
-        case TCODE_WRITEQ:
-        case TCODE_WRITEB:
-        case TCODE_READQ:
-        case TCODE_READB:
-        case TCODE_LOCK_REQUEST:
-                handle_incoming_packet(host, tcode, data, size, write_acked);
-                break;
+	case TCODE_WRITEQ:
+	case TCODE_WRITEB:
+	case TCODE_READQ:
+	case TCODE_READB:
+	case TCODE_LOCK_REQUEST:
+		handle_incoming_packet(host, tcode, data, size, write_acked);
+		break;
 
 
-        case TCODE_ISO_DATA:
-                highlevel_iso_receive(host, data, size);
-                break;
+	case TCODE_ISO_DATA:
+		highlevel_iso_receive(host, data, size);
+		break;
 
-        case TCODE_CYCLE_START:
-                /* simply ignore this packet if it is passed on */
-                break;
+	case TCODE_CYCLE_START:
+		/* simply ignore this packet if it is passed on */
+		break;
 
-        default:
-                HPSB_NOTICE("received packet with bogus transaction code %d",
-                            tcode);
-                break;
-        }
+	default:
+		HPSB_NOTICE("received packet with bogus transaction code %d",
+			    tcode);
+		break;
+	}
 }
 
 
@@ -1030,10 +1027,10 @@
 
 	daemonize("khpsbpkt");
 
+	current->flags |= PF_NOFREEZE;
+
 	while (1) {
 		if (down_interruptible(&khpsbpkt_sig)) {
-			if (try_to_freeze())
-				continue;
 			printk("khpsbpkt: received unexpected signal?!\n" );
 			break;
 		}
@@ -1129,7 +1126,7 @@
 		   nodemgr implements functionality required of ieee1394a-2000
 		   IRMs */
 		hpsb_disable_irm = 1;
-                      
+
 		return 0;
 	}
 
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index 0b31429..b354660 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -10,8 +10,8 @@
 
 
 struct hpsb_packet {
-        /* This struct is basically read-only for hosts with the exception of
-         * the data buffer contents and xnext - see below. */
+	/* This struct is basically read-only for hosts with the exception of
+	 * the data buffer contents and xnext - see below. */
 
 	/* This can be used for host driver internal linking.
 	 *
@@ -21,47 +21,47 @@
 	 * driver_list when free'ing it. */
 	struct list_head driver_list;
 
-        nodeid_t node_id;
+	nodeid_t node_id;
 
-        /* Async and Iso types should be clear, raw means send-as-is, do not
-         * CRC!  Byte swapping shall still be done in this case. */
-        enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type;
+	/* Async and Iso types should be clear, raw means send-as-is, do not
+	 * CRC!  Byte swapping shall still be done in this case. */
+	enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type;
 
-        /* Okay, this is core internal and a no care for hosts.
-         * queued   = queued for sending
-         * pending  = sent, waiting for response
-         * complete = processing completed, successful or not
-         */
-        enum {
-                hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete
-        } __attribute__((packed)) state;
+	/* Okay, this is core internal and a no care for hosts.
+	 * queued   = queued for sending
+	 * pending  = sent, waiting for response
+	 * complete = processing completed, successful or not
+	 */
+	enum {
+		hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete
+	} __attribute__((packed)) state;
 
-        /* These are core internal. */
-        signed char tlabel;
+	/* These are core internal. */
+	signed char tlabel;
 	signed char ack_code;
 	unsigned char tcode;
 
-        unsigned expect_response:1;
-        unsigned no_waiter:1;
+	unsigned expect_response:1;
+	unsigned no_waiter:1;
 
-        /* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */
-        unsigned speed_code:2;
+	/* Speed to transmit with: 0 = 100Mbps, 1 = 200Mbps, 2 = 400Mbps */
+	unsigned speed_code:2;
 
-        /*
-         * *header and *data are guaranteed to be 32-bit DMAable and may be
-         * overwritten to allow in-place byte swapping.  Neither of these is
-         * CRCed (the sizes also don't include CRC), but contain space for at
-         * least one additional quadlet to allow in-place CRCing.  The memory is
-         * also guaranteed to be DMA mappable.
-         */
-        quadlet_t *header;
-        quadlet_t *data;
-        size_t header_size;
-        size_t data_size;
+	/*
+	 * *header and *data are guaranteed to be 32-bit DMAable and may be
+	 * overwritten to allow in-place byte swapping.  Neither of these is
+	 * CRCed (the sizes also don't include CRC), but contain space for at
+	 * least one additional quadlet to allow in-place CRCing.  The memory is
+	 * also guaranteed to be DMA mappable.
+	 */
+	quadlet_t *header;
+	quadlet_t *data;
+	size_t header_size;
+	size_t data_size;
 
 
-        struct hpsb_host *host;
-        unsigned int generation;
+	struct hpsb_host *host;
+	unsigned int generation;
 
 	atomic_t refcnt;
 
@@ -73,10 +73,10 @@
 	/* XXX This is just a hack at the moment */
 	struct sk_buff *skb;
 
-        /* Store jiffies for implementing bus timeouts. */
-        unsigned long sendtime;
+	/* Store jiffies for implementing bus timeouts. */
+	unsigned long sendtime;
 
-        quadlet_t embedded_header[5];
+	quadlet_t embedded_header[5];
 };
 
 /* Set a task for when a packet completes */
@@ -102,7 +102,7 @@
  */
 static inline unsigned int get_hpsb_generation(struct hpsb_host *host)
 {
-        return atomic_read(&host->generation);
+	return atomic_read(&host->generation);
 }
 
 /*
@@ -157,7 +157,7 @@
  * from within a transmit packet routine.
  */
 void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
-                      int ackcode);
+		      int ackcode);
 
 /*
  * Hand over received packet to the core.  The contents of data are expected to
@@ -171,7 +171,7 @@
  * packet type.
  */
 void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,
-                          int write_acked);
+			  int write_acked);
 
 
 /*
@@ -197,20 +197,20 @@
  * Block 15 (240-255)  reserved for drivers under development, etc.
  */
 
-#define IEEE1394_MAJOR               171
+#define IEEE1394_MAJOR			 171
 
-#define IEEE1394_MINOR_BLOCK_RAW1394       0
-#define IEEE1394_MINOR_BLOCK_VIDEO1394     1
-#define IEEE1394_MINOR_BLOCK_DV1394        2
-#define IEEE1394_MINOR_BLOCK_AMDTP         3
+#define IEEE1394_MINOR_BLOCK_RAW1394	   0
+#define IEEE1394_MINOR_BLOCK_VIDEO1394	   1
+#define IEEE1394_MINOR_BLOCK_DV1394	   2
+#define IEEE1394_MINOR_BLOCK_AMDTP	   3
 #define IEEE1394_MINOR_BLOCK_EXPERIMENTAL 15
 
-#define IEEE1394_CORE_DEV		MKDEV(IEEE1394_MAJOR, 0)
-#define IEEE1394_RAW1394_DEV		MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)
-#define IEEE1394_VIDEO1394_DEV		MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
-#define IEEE1394_DV1394_DEV		MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16)
-#define IEEE1394_AMDTP_DEV		MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16)
-#define IEEE1394_EXPERIMENTAL_DEV	MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
+#define IEEE1394_CORE_DEV	  MKDEV(IEEE1394_MAJOR, 0)
+#define IEEE1394_RAW1394_DEV	  MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16)
+#define IEEE1394_VIDEO1394_DEV	  MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_VIDEO1394 * 16)
+#define IEEE1394_DV1394_DEV	  MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16)
+#define IEEE1394_AMDTP_DEV	  MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_AMDTP * 16)
+#define IEEE1394_EXPERIMENTAL_DEV MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_EXPERIMENTAL * 16)
 
 /* return the index (within a minor number block) of a file */
 static inline unsigned char ieee1394_file_to_instance(struct file *file)
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c
index 0aa8763..3fe2f6c 100644
--- a/drivers/ieee1394/ieee1394_transactions.c
+++ b/drivers/ieee1394/ieee1394_transactions.c
@@ -22,7 +22,7 @@
 #include "ieee1394_core.h"
 #include "highlevel.h"
 #include "nodemgr.h"
-
+#include "ieee1394_transactions.h"
 
 #define PREP_ASYNC_HEAD_ADDRESS(tc) \
         packet->tcode = tc; \
@@ -31,80 +31,82 @@
         packet->header[1] = (packet->host->node_id << 16) | (addr >> 32); \
         packet->header[2] = addr & 0xffffffff
 
-
 static void fill_async_readquad(struct hpsb_packet *packet, u64 addr)
 {
-        PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
-        packet->header_size = 12;
-        packet->data_size = 0;
-        packet->expect_response = 1;
+	PREP_ASYNC_HEAD_ADDRESS(TCODE_READQ);
+	packet->header_size = 12;
+	packet->data_size = 0;
+	packet->expect_response = 1;
 }
 
-static void fill_async_readblock(struct hpsb_packet *packet, u64 addr, int length)
+static void fill_async_readblock(struct hpsb_packet *packet, u64 addr,
+				 int length)
 {
-        PREP_ASYNC_HEAD_ADDRESS(TCODE_READB);
-        packet->header[3] = length << 16;
-        packet->header_size = 16;
-        packet->data_size = 0;
-        packet->expect_response = 1;
+	PREP_ASYNC_HEAD_ADDRESS(TCODE_READB);
+	packet->header[3] = length << 16;
+	packet->header_size = 16;
+	packet->data_size = 0;
+	packet->expect_response = 1;
 }
 
-static void fill_async_writequad(struct hpsb_packet *packet, u64 addr, quadlet_t data)
+static void fill_async_writequad(struct hpsb_packet *packet, u64 addr,
+				 quadlet_t data)
 {
-        PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEQ);
-        packet->header[3] = data;
-        packet->header_size = 16;
-        packet->data_size = 0;
-        packet->expect_response = 1;
+	PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEQ);
+	packet->header[3] = data;
+	packet->header_size = 16;
+	packet->data_size = 0;
+	packet->expect_response = 1;
 }
 
-static void fill_async_writeblock(struct hpsb_packet *packet, u64 addr, int length)
+static void fill_async_writeblock(struct hpsb_packet *packet, u64 addr,
+				  int length)
 {
-        PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEB);
-        packet->header[3] = length << 16;
-        packet->header_size = 16;
-        packet->expect_response = 1;
-        packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
+	PREP_ASYNC_HEAD_ADDRESS(TCODE_WRITEB);
+	packet->header[3] = length << 16;
+	packet->header_size = 16;
+	packet->expect_response = 1;
+	packet->data_size = length + (length % 4 ? 4 - (length % 4) : 0);
 }
 
 static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode,
-                     int length)
+			    int length)
 {
-        PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST);
-        packet->header[3] = (length << 16) | extcode;
-        packet->header_size = 16;
-        packet->data_size = length;
-        packet->expect_response = 1;
+	PREP_ASYNC_HEAD_ADDRESS(TCODE_LOCK_REQUEST);
+	packet->header[3] = (length << 16) | extcode;
+	packet->header_size = 16;
+	packet->data_size = length;
+	packet->expect_response = 1;
 }
 
 static void fill_iso_packet(struct hpsb_packet *packet, int length, int channel,
-                     int tag, int sync)
+			    int tag, int sync)
 {
-        packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
-                | (TCODE_ISO_DATA << 4) | sync;
+	packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
+	    | (TCODE_ISO_DATA << 4) | sync;
 
-        packet->header_size = 4;
-        packet->data_size = length;
-        packet->type = hpsb_iso;
-        packet->tcode = TCODE_ISO_DATA;
+	packet->header_size = 4;
+	packet->data_size = length;
+	packet->type = hpsb_iso;
+	packet->tcode = TCODE_ISO_DATA;
 }
 
 static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data)
 {
-        packet->header[0] = data;
-        packet->header[1] = ~data;
-        packet->header_size = 8;
-        packet->data_size = 0;
-        packet->expect_response = 0;
-        packet->type = hpsb_raw;             /* No CRC added */
-        packet->speed_code = IEEE1394_SPEED_100; /* Force speed to be 100Mbps */
+	packet->header[0] = data;
+	packet->header[1] = ~data;
+	packet->header_size = 8;
+	packet->data_size = 0;
+	packet->expect_response = 0;
+	packet->type = hpsb_raw;	/* No CRC added */
+	packet->speed_code = IEEE1394_SPEED_100;	/* Force speed to be 100Mbps */
 }
 
 static void fill_async_stream_packet(struct hpsb_packet *packet, int length,
 				     int channel, int tag, int sync)
 {
 	packet->header[0] = (length << 16) | (tag << 14) | (channel << 8)
-	                  | (TCODE_STREAM_DATA << 4) | sync;
+	    | (TCODE_STREAM_DATA << 4) | sync;
 
 	packet->header_size = 4;
 	packet->data_size = length;
@@ -171,99 +173,96 @@
  */
 void hpsb_free_tlabel(struct hpsb_packet *packet)
 {
-        unsigned long flags;
+	unsigned long flags;
 	struct hpsb_tlabel_pool *tp;
 
 	tp = &packet->host->tpool[packet->node_id & NODE_MASK];
 
 	BUG_ON(packet->tlabel > 63 || packet->tlabel < 0);
 
-        spin_lock_irqsave(&tp->lock, flags);
+	spin_lock_irqsave(&tp->lock, flags);
 	BUG_ON(!test_and_clear_bit(packet->tlabel, tp->pool));
-        spin_unlock_irqrestore(&tp->lock, flags);
+	spin_unlock_irqrestore(&tp->lock, flags);
 
 	up(&tp->count);
 }
 
-
-
 int hpsb_packet_success(struct hpsb_packet *packet)
 {
-        switch (packet->ack_code) {
-        case ACK_PENDING:
-                switch ((packet->header[1] >> 12) & 0xf) {
-                case RCODE_COMPLETE:
-                        return 0;
-                case RCODE_CONFLICT_ERROR:
-                        return -EAGAIN;
-                case RCODE_DATA_ERROR:
-                        return -EREMOTEIO;
-                case RCODE_TYPE_ERROR:
-                        return -EACCES;
-                case RCODE_ADDRESS_ERROR:
-                        return -EINVAL;
-                default:
-                        HPSB_ERR("received reserved rcode %d from node %d",
-                                 (packet->header[1] >> 12) & 0xf,
-                                 packet->node_id);
-                        return -EAGAIN;
-                }
-                HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__);
+	switch (packet->ack_code) {
+	case ACK_PENDING:
+		switch ((packet->header[1] >> 12) & 0xf) {
+		case RCODE_COMPLETE:
+			return 0;
+		case RCODE_CONFLICT_ERROR:
+			return -EAGAIN;
+		case RCODE_DATA_ERROR:
+			return -EREMOTEIO;
+		case RCODE_TYPE_ERROR:
+			return -EACCES;
+		case RCODE_ADDRESS_ERROR:
+			return -EINVAL;
+		default:
+			HPSB_ERR("received reserved rcode %d from node %d",
+				 (packet->header[1] >> 12) & 0xf,
+				 packet->node_id);
+			return -EAGAIN;
+		}
+		HPSB_PANIC("reached unreachable code 1 in %s", __FUNCTION__);
 
-        case ACK_BUSY_X:
-        case ACK_BUSY_A:
-        case ACK_BUSY_B:
-                return -EBUSY;
+	case ACK_BUSY_X:
+	case ACK_BUSY_A:
+	case ACK_BUSY_B:
+		return -EBUSY;
 
-        case ACK_TYPE_ERROR:
-                return -EACCES;
+	case ACK_TYPE_ERROR:
+		return -EACCES;
 
-        case ACK_COMPLETE:
-                if (packet->tcode == TCODE_WRITEQ
-                    || packet->tcode == TCODE_WRITEB) {
-                        return 0;
-                } else {
-                        HPSB_ERR("impossible ack_complete from node %d "
-                                 "(tcode %d)", packet->node_id, packet->tcode);
-                        return -EAGAIN;
-                }
+	case ACK_COMPLETE:
+		if (packet->tcode == TCODE_WRITEQ
+		    || packet->tcode == TCODE_WRITEB) {
+			return 0;
+		} else {
+			HPSB_ERR("impossible ack_complete from node %d "
+				 "(tcode %d)", packet->node_id, packet->tcode);
+			return -EAGAIN;
+		}
 
+	case ACK_DATA_ERROR:
+		if (packet->tcode == TCODE_WRITEB
+		    || packet->tcode == TCODE_LOCK_REQUEST) {
+			return -EAGAIN;
+		} else {
+			HPSB_ERR("impossible ack_data_error from node %d "
+				 "(tcode %d)", packet->node_id, packet->tcode);
+			return -EAGAIN;
+		}
 
-        case ACK_DATA_ERROR:
-                if (packet->tcode == TCODE_WRITEB
-                    || packet->tcode == TCODE_LOCK_REQUEST) {
-                        return -EAGAIN;
-                } else {
-                        HPSB_ERR("impossible ack_data_error from node %d "
-                                 "(tcode %d)", packet->node_id, packet->tcode);
-                        return -EAGAIN;
-                }
+	case ACK_ADDRESS_ERROR:
+		return -EINVAL;
 
-        case ACK_ADDRESS_ERROR:
-                return -EINVAL;
+	case ACK_TARDY:
+	case ACK_CONFLICT_ERROR:
+	case ACKX_NONE:
+	case ACKX_SEND_ERROR:
+	case ACKX_ABORTED:
+	case ACKX_TIMEOUT:
+		/* error while sending */
+		return -EAGAIN;
 
-        case ACK_TARDY:
-        case ACK_CONFLICT_ERROR:
-        case ACKX_NONE:
-        case ACKX_SEND_ERROR:
-        case ACKX_ABORTED:
-        case ACKX_TIMEOUT:
-                /* error while sending */
-                return -EAGAIN;
+	default:
+		HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
+			 packet->ack_code, packet->node_id, packet->tcode);
+		return -EAGAIN;
+	}
 
-        default:
-                HPSB_ERR("got invalid ack %d from node %d (tcode %d)",
-                         packet->ack_code, packet->node_id, packet->tcode);
-                return -EAGAIN;
-        }
-
-        HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
+	HPSB_PANIC("reached unreachable code 2 in %s", __FUNCTION__);
 }
 
 struct hpsb_packet *hpsb_make_readpacket(struct hpsb_host *host, nodeid_t node,
 					 u64 addr, size_t length)
 {
-        struct hpsb_packet *packet;
+	struct hpsb_packet *packet;
 
 	if (length == 0)
 		return NULL;
@@ -288,8 +287,9 @@
 	return packet;
 }
 
-struct hpsb_packet *hpsb_make_writepacket (struct hpsb_host *host, nodeid_t node,
-					   u64 addr, quadlet_t *buffer, size_t length)
+struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node,
+					  u64 addr, quadlet_t * buffer,
+					  size_t length)
 {
 	struct hpsb_packet *packet;
 
@@ -300,7 +300,7 @@
 	if (!packet)
 		return NULL;
 
-	if (length % 4) { /* zero padding bytes */
+	if (length % 4) {	/* zero padding bytes */
 		packet->data[length >> 2] = 0;
 	}
 	packet->host = host;
@@ -322,8 +322,9 @@
 	return packet;
 }
 
-struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 *buffer, int length,
-                                           int channel, int tag, int sync)
+struct hpsb_packet *hpsb_make_streampacket(struct hpsb_host *host, u8 * buffer,
+					   int length, int channel, int tag,
+					   int sync)
 {
 	struct hpsb_packet *packet;
 
@@ -334,7 +335,7 @@
 	if (!packet)
 		return NULL;
 
-	if (length % 4) { /* zero padding bytes */
+	if (length % 4) {	/* zero padding bytes */
 		packet->data[length >> 2] = 0;
 	}
 	packet->host = host;
@@ -352,14 +353,15 @@
 }
 
 struct hpsb_packet *hpsb_make_lockpacket(struct hpsb_host *host, nodeid_t node,
-                                         u64 addr, int extcode, quadlet_t *data,
-					 quadlet_t arg)
+					 u64 addr, int extcode,
+					 quadlet_t * data, quadlet_t arg)
 {
 	struct hpsb_packet *p;
 	u32 length;
 
 	p = hpsb_alloc_packet(8);
-	if (!p) return NULL;
+	if (!p)
+		return NULL;
 
 	p->host = host;
 	p->node_id = node;
@@ -388,15 +390,16 @@
 	return p;
 }
 
-struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node,
-                                           u64 addr, int extcode, octlet_t *data,
-					   octlet_t arg)
+struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host,
+					   nodeid_t node, u64 addr, int extcode,
+					   octlet_t * data, octlet_t arg)
 {
 	struct hpsb_packet *p;
 	u32 length;
 
 	p = hpsb_alloc_packet(16);
-	if (!p) return NULL;
+	if (!p)
+		return NULL;
 
 	p->host = host;
 	p->node_id = node;
@@ -429,18 +432,18 @@
 	return p;
 }
 
-struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host,
-                                        quadlet_t data)
+struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data)
 {
-        struct hpsb_packet *p;
+	struct hpsb_packet *p;
 
-        p = hpsb_alloc_packet(0);
-        if (!p) return NULL;
+	p = hpsb_alloc_packet(0);
+	if (!p)
+		return NULL;
 
-        p->host = host;
-        fill_phy_packet(p, data);
+	p->host = host;
+	fill_phy_packet(p, data);
 
-        return p;
+	return p;
 }
 
 struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host,
@@ -450,7 +453,8 @@
 	struct hpsb_packet *p;
 
 	p = hpsb_alloc_packet(length);
-	if (!p) return NULL;
+	if (!p)
+		return NULL;
 
 	p->host = host;
 	fill_iso_packet(p, length, channel, tag, sync);
@@ -466,47 +470,46 @@
  */
 
 int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation,
-	      u64 addr, quadlet_t *buffer, size_t length)
+	      u64 addr, quadlet_t * buffer, size_t length)
 {
-        struct hpsb_packet *packet;
-        int retval = 0;
+	struct hpsb_packet *packet;
+	int retval = 0;
 
-        if (length == 0)
-                return -EINVAL;
+	if (length == 0)
+		return -EINVAL;
 
-	BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
+	BUG_ON(in_interrupt());	// We can't be called in an interrupt, yet
 
 	packet = hpsb_make_readpacket(host, node, addr, length);
 
-        if (!packet) {
-                return -ENOMEM;
-        }
+	if (!packet) {
+		return -ENOMEM;
+	}
 
 	packet->generation = generation;
-        retval = hpsb_send_packet_and_wait(packet);
+	retval = hpsb_send_packet_and_wait(packet);
 	if (retval < 0)
 		goto hpsb_read_fail;
 
-        retval = hpsb_packet_success(packet);
+	retval = hpsb_packet_success(packet);
 
-        if (retval == 0) {
-                if (length == 4) {
-                        *buffer = packet->header[3];
-                } else {
-                        memcpy(buffer, packet->data, length);
-                }
-        }
+	if (retval == 0) {
+		if (length == 4) {
+			*buffer = packet->header[3];
+		} else {
+			memcpy(buffer, packet->data, length);
+		}
+	}
 
-hpsb_read_fail:
-        hpsb_free_tlabel(packet);
-        hpsb_free_packet(packet);
+      hpsb_read_fail:
+	hpsb_free_tlabel(packet);
+	hpsb_free_packet(packet);
 
-        return retval;
+	return retval;
 }
 
-
 int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation,
-	       u64 addr, quadlet_t *buffer, size_t length)
+	       u64 addr, quadlet_t * buffer, size_t length)
 {
 	struct hpsb_packet *packet;
 	int retval;
@@ -514,62 +517,61 @@
 	if (length == 0)
 		return -EINVAL;
 
-	BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
+	BUG_ON(in_interrupt());	// We can't be called in an interrupt, yet
 
-	packet = hpsb_make_writepacket (host, node, addr, buffer, length);
+	packet = hpsb_make_writepacket(host, node, addr, buffer, length);
 
 	if (!packet)
 		return -ENOMEM;
 
 	packet->generation = generation;
-        retval = hpsb_send_packet_and_wait(packet);
+	retval = hpsb_send_packet_and_wait(packet);
 	if (retval < 0)
 		goto hpsb_write_fail;
 
-        retval = hpsb_packet_success(packet);
+	retval = hpsb_packet_success(packet);
 
-hpsb_write_fail:
-        hpsb_free_tlabel(packet);
-        hpsb_free_packet(packet);
+      hpsb_write_fail:
+	hpsb_free_tlabel(packet);
+	hpsb_free_packet(packet);
 
-        return retval;
+	return retval;
 }
 
 #if 0
 
 int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation,
-	      u64 addr, int extcode, quadlet_t *data, quadlet_t arg)
+	      u64 addr, int extcode, quadlet_t * data, quadlet_t arg)
 {
-        struct hpsb_packet *packet;
-        int retval = 0;
+	struct hpsb_packet *packet;
+	int retval = 0;
 
-	BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet
+	BUG_ON(in_interrupt());	// We can't be called in an interrupt, yet
 
 	packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg);
-        if (!packet)
-                return -ENOMEM;
+	if (!packet)
+		return -ENOMEM;
 
 	packet->generation = generation;
-        retval = hpsb_send_packet_and_wait(packet);
+	retval = hpsb_send_packet_and_wait(packet);
 	if (retval < 0)
 		goto hpsb_lock_fail;
 
-        retval = hpsb_packet_success(packet);
+	retval = hpsb_packet_success(packet);
 
-        if (retval == 0) {
-                *data = packet->data[0];
-        }
+	if (retval == 0) {
+		*data = packet->data[0];
+	}
 
-hpsb_lock_fail:
-        hpsb_free_tlabel(packet);
-        hpsb_free_packet(packet);
+      hpsb_lock_fail:
+	hpsb_free_tlabel(packet);
+	hpsb_free_packet(packet);
 
-        return retval;
+	return retval;
 }
 
-
 int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation,
-		   quadlet_t *buffer, size_t length, u32 specifier_id,
+		   quadlet_t * buffer, size_t length, u32 specifier_id,
 		   unsigned int version)
 {
 	struct hpsb_packet *packet;
@@ -586,7 +588,8 @@
 		return -ENOMEM;
 
 	packet->data[0] = cpu_to_be32((host->node_id << 16) | specifier_id_hi);
-	packet->data[1] = cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff));
+	packet->data[1] =
+	    cpu_to_be32((specifier_id_lo << 24) | (version & 0x00ffffff));
 
 	memcpy(&(packet->data[2]), buffer, length - 8);
 
@@ -601,4 +604,4 @@
 	return retval;
 }
 
-#endif  /*  0  */
+#endif				/*  0  */
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c
index 615541b..f26680e 100644
--- a/drivers/ieee1394/iso.c
+++ b/drivers/ieee1394/iso.c
@@ -36,20 +36,22 @@
 	kfree(iso);
 }
 
-static struct hpsb_iso* hpsb_iso_common_init(struct hpsb_host *host, enum hpsb_iso_type type,
+static struct hpsb_iso *hpsb_iso_common_init(struct hpsb_host *host,
+					     enum hpsb_iso_type type,
 					     unsigned int data_buf_size,
 					     unsigned int buf_packets,
-					     int channel,
-					     int dma_mode,
+					     int channel, int dma_mode,
 					     int irq_interval,
-					     void (*callback)(struct hpsb_iso*))
+					     void (*callback) (struct hpsb_iso
+							       *))
 {
 	struct hpsb_iso *iso;
 	int dma_direction;
 
 	/* make sure driver supports the ISO API */
 	if (!host->driver->isoctl) {
-		printk(KERN_INFO "ieee1394: host driver '%s' does not support the rawiso API\n",
+		printk(KERN_INFO
+		       "ieee1394: host driver '%s' does not support the rawiso API\n",
 		       host->driver->name);
 		return NULL;
 	}
@@ -59,12 +61,13 @@
 	if (buf_packets < 2)
 		buf_packets = 2;
 
-	if ((dma_mode < HPSB_ISO_DMA_DEFAULT) || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
-		dma_mode=HPSB_ISO_DMA_DEFAULT;
+	if ((dma_mode < HPSB_ISO_DMA_DEFAULT)
+	    || (dma_mode > HPSB_ISO_DMA_PACKET_PER_BUFFER))
+		dma_mode = HPSB_ISO_DMA_DEFAULT;
 
 	if ((irq_interval < 0) || (irq_interval > buf_packets / 4))
- 		irq_interval = buf_packets / 4;
-	if (irq_interval == 0)     /* really interrupt for each packet*/
+		irq_interval = buf_packets / 4;
+	if (irq_interval == 0)	/* really interrupt for each packet */
 		irq_interval = 1;
 
 	if (channel < -1 || channel >= 64)
@@ -76,7 +79,10 @@
 
 	/* allocate and write the struct hpsb_iso */
 
-	iso = kmalloc(sizeof(*iso) + buf_packets * sizeof(struct hpsb_iso_packet_info), GFP_KERNEL);
+	iso =
+	    kmalloc(sizeof(*iso) +
+		    buf_packets * sizeof(struct hpsb_iso_packet_info),
+		    GFP_KERNEL);
 	if (!iso)
 		return NULL;
 
@@ -111,17 +117,18 @@
 	iso->prebuffer = 0;
 
 	/* allocate the packet buffer */
-	if (dma_region_alloc(&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
+	if (dma_region_alloc
+	    (&iso->data_buf, iso->buf_size, host->pdev, dma_direction))
 		goto err;
 
 	return iso;
 
-err:
+      err:
 	hpsb_iso_shutdown(iso);
 	return NULL;
 }
 
-int hpsb_iso_n_ready(struct hpsb_iso* iso)
+int hpsb_iso_n_ready(struct hpsb_iso *iso)
 {
 	unsigned long flags;
 	int val;
@@ -133,18 +140,19 @@
 	return val;
 }
 
-
-struct hpsb_iso* hpsb_iso_xmit_init(struct hpsb_host *host,
+struct hpsb_iso *hpsb_iso_xmit_init(struct hpsb_host *host,
 				    unsigned int data_buf_size,
 				    unsigned int buf_packets,
 				    int channel,
 				    int speed,
 				    int irq_interval,
-				    void (*callback)(struct hpsb_iso*))
+				    void (*callback) (struct hpsb_iso *))
 {
 	struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_XMIT,
 						    data_buf_size, buf_packets,
-						    channel, HPSB_ISO_DMA_DEFAULT, irq_interval, callback);
+						    channel,
+						    HPSB_ISO_DMA_DEFAULT,
+						    irq_interval, callback);
 	if (!iso)
 		return NULL;
 
@@ -157,22 +165,23 @@
 	iso->flags |= HPSB_ISO_DRIVER_INIT;
 	return iso;
 
-err:
+      err:
 	hpsb_iso_shutdown(iso);
 	return NULL;
 }
 
-struct hpsb_iso* hpsb_iso_recv_init(struct hpsb_host *host,
+struct hpsb_iso *hpsb_iso_recv_init(struct hpsb_host *host,
 				    unsigned int data_buf_size,
 				    unsigned int buf_packets,
 				    int channel,
 				    int dma_mode,
 				    int irq_interval,
-				    void (*callback)(struct hpsb_iso*))
+				    void (*callback) (struct hpsb_iso *))
 {
 	struct hpsb_iso *iso = hpsb_iso_common_init(host, HPSB_ISO_RECV,
 						    data_buf_size, buf_packets,
-						    channel, dma_mode, irq_interval, callback);
+						    channel, dma_mode,
+						    irq_interval, callback);
 	if (!iso)
 		return NULL;
 
@@ -183,7 +192,7 @@
 	iso->flags |= HPSB_ISO_DRIVER_INIT;
 	return iso;
 
-err:
+      err:
 	hpsb_iso_shutdown(iso);
 	return NULL;
 }
@@ -197,16 +206,17 @@
 
 int hpsb_iso_recv_unlisten_channel(struct hpsb_iso *iso, unsigned char channel)
 {
-       if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
-               return -EINVAL;
-       return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
+	if (iso->type != HPSB_ISO_RECV || iso->channel != -1 || channel >= 64)
+		return -EINVAL;
+	return iso->host->driver->isoctl(iso, RECV_UNLISTEN_CHANNEL, channel);
 }
 
 int hpsb_iso_recv_set_channel_mask(struct hpsb_iso *iso, u64 mask)
 {
 	if (iso->type != HPSB_ISO_RECV || iso->channel != -1)
 		return -EINVAL;
-	return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK, (unsigned long) &mask);
+	return iso->host->driver->isoctl(iso, RECV_SET_CHANNEL_MASK,
+					 (unsigned long)&mask);
 }
 
 int hpsb_iso_recv_flush(struct hpsb_iso *iso)
@@ -283,7 +293,9 @@
 
 	isoctl_args[2] = sync;
 
-	retval = iso->host->driver->isoctl(iso, RECV_START, (unsigned long) &isoctl_args[0]);
+	retval =
+	    iso->host->driver->isoctl(iso, RECV_START,
+				      (unsigned long)&isoctl_args[0]);
 	if (retval)
 		return retval;
 
@@ -296,7 +308,8 @@
 
 static int hpsb_iso_check_offset_len(struct hpsb_iso *iso,
 				     unsigned int offset, unsigned short len,
-				     unsigned int *out_offset, unsigned short *out_len)
+				     unsigned int *out_offset,
+				     unsigned short *out_len)
 {
 	if (offset >= iso->buf_size)
 		return -EFAULT;
@@ -316,8 +329,8 @@
 	return 0;
 }
 
-
-int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len, u8 tag, u8 sy)
+int hpsb_iso_xmit_queue_packet(struct hpsb_iso *iso, u32 offset, u16 len,
+			       u8 tag, u8 sy)
 {
 	struct hpsb_iso_packet_info *info;
 	unsigned long flags;
@@ -334,7 +347,8 @@
 	info = &iso->infos[iso->first_packet];
 
 	/* check for bogus offset/length */
-	if (hpsb_iso_check_offset_len(iso, offset, len, &info->offset, &info->len))
+	if (hpsb_iso_check_offset_len
+	    (iso, offset, len, &info->offset, &info->len))
 		return -EFAULT;
 
 	info->tag = tag;
@@ -342,13 +356,13 @@
 
 	spin_lock_irqsave(&iso->lock, flags);
 
-	rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long) info);
+	rv = iso->host->driver->isoctl(iso, XMIT_QUEUE, (unsigned long)info);
 	if (rv)
 		goto out;
 
 	/* increment cursors */
-	iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
-	iso->xmit_cycle = (iso->xmit_cycle+1) % 8000;
+	iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
+	iso->xmit_cycle = (iso->xmit_cycle + 1) % 8000;
 	iso->n_ready_packets--;
 
 	if (iso->prebuffer != 0) {
@@ -359,7 +373,7 @@
 		}
 	}
 
-out:
+      out:
 	spin_unlock_irqrestore(&iso->lock, flags);
 	return rv;
 }
@@ -369,7 +383,9 @@
 	if (iso->type != HPSB_ISO_XMIT)
 		return -EINVAL;
 
-	return wait_event_interruptible(iso->waitq, hpsb_iso_n_ready(iso) == iso->buf_packets);
+	return wait_event_interruptible(iso->waitq,
+					hpsb_iso_n_ready(iso) ==
+					iso->buf_packets);
 }
 
 void hpsb_iso_packet_sent(struct hpsb_iso *iso, int cycle, int error)
@@ -396,7 +412,8 @@
 }
 
 void hpsb_iso_packet_received(struct hpsb_iso *iso, u32 offset, u16 len,
-			      u16 total_len, u16 cycle, u8 channel, u8 tag, u8 sy)
+			      u16 total_len, u16 cycle, u8 channel, u8 tag,
+			      u8 sy)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&iso->lock, flags);
@@ -416,7 +433,7 @@
 		info->tag = tag;
 		info->sy = sy;
 
-		iso->pkt_dma = (iso->pkt_dma+1) % iso->buf_packets;
+		iso->pkt_dma = (iso->pkt_dma + 1) % iso->buf_packets;
 		iso->n_ready_packets++;
 	}
 
@@ -435,20 +452,21 @@
 	spin_lock_irqsave(&iso->lock, flags);
 	for (i = 0; i < n_packets; i++) {
 		rv = iso->host->driver->isoctl(iso, RECV_RELEASE,
-					       (unsigned long) &iso->infos[iso->first_packet]);
+					       (unsigned long)&iso->infos[iso->
+									  first_packet]);
 		if (rv)
 			break;
 
-		iso->first_packet = (iso->first_packet+1) % iso->buf_packets;
+		iso->first_packet = (iso->first_packet + 1) % iso->buf_packets;
 		iso->n_ready_packets--;
 
 		/* release memory from packets discarded when queue was full  */
-		if (iso->n_ready_packets == 0) { /* Release only after all prior packets handled */
+		if (iso->n_ready_packets == 0) {	/* Release only after all prior packets handled */
 			if (iso->bytes_discarded != 0) {
 				struct hpsb_iso_packet_info inf;
 				inf.total_len = iso->bytes_discarded;
 				iso->host->driver->isoctl(iso, RECV_RELEASE,
-							(unsigned long) &inf);
+							  (unsigned long)&inf);
 				iso->bytes_discarded = 0;
 			}
 		}
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 7fff5a1..082c7fd 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -121,8 +121,8 @@
 };
 
 static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
-static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
-			   char *buffer, int buffer_size);
+static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
+			  char *buffer, int buffer_size);
 static void nodemgr_resume_ne(struct node_entry *ne);
 static void nodemgr_remove_ne(struct node_entry *ne);
 static struct node_entry *find_entry_by_guid(u64 guid);
@@ -162,7 +162,7 @@
 static struct class nodemgr_ud_class = {
 	.name		= "ieee1394",
 	.release	= ud_cls_release,
-	.hotplug	= nodemgr_hotplug,
+	.uevent		= nodemgr_uevent,
 };
 
 static struct hpsb_highlevel nodemgr_highlevel;
@@ -743,21 +743,20 @@
 					      unsigned int generation)
 {
 	struct hpsb_host *host = hi->host;
-        struct node_entry *ne;
+	struct node_entry *ne;
 
-	ne = kmalloc(sizeof(struct node_entry), GFP_KERNEL);
-        if (!ne) return NULL;
-
-	memset(ne, 0, sizeof(struct node_entry));
+	ne = kzalloc(sizeof(*ne), GFP_KERNEL);
+	if (!ne)
+		return NULL;
 
 	ne->tpool = &host->tpool[nodeid & NODE_MASK];
 
-        ne->host = host;
-        ne->nodeid = nodeid;
+	ne->host = host;
+	ne->nodeid = nodeid;
 	ne->generation = generation;
 	ne->needs_probe = 1;
 
-        ne->guid = guid;
+	ne->guid = guid;
 	ne->guid_vendor_id = (guid >> 40) & 0xffffff;
 	ne->guid_vendor_oui = nodemgr_find_oui_name(ne->guid_vendor_id);
 	ne->csr = csr;
@@ -787,7 +786,7 @@
 		   (host->node_id == nodeid) ? "Host" : "Node",
 		   NODE_BUS_ARGS(host, nodeid), (unsigned long long)guid);
 
-        return ne;
+	return ne;
 }
 
 
@@ -872,12 +871,10 @@
 	struct csr1212_keyval *kv;
 	u8 last_key_id = 0;
 
-	ud = kmalloc(sizeof(struct unit_directory), GFP_KERNEL);
+	ud = kzalloc(sizeof(*ud), GFP_KERNEL);
 	if (!ud)
 		goto unit_directory_error;
 
-	memset (ud, 0, sizeof(struct unit_directory));
-
 	ud->ne = ne;
 	ud->ignore_driver = ignore_drivers;
 	ud->address = ud_kv->offset + CSR1212_CONFIG_ROM_SPACE_BASE;
@@ -937,10 +934,10 @@
 			/* Logical Unit Number */
 			if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
 				if (ud->flags & UNIT_DIRECTORY_HAS_LUN) {
-					ud_child = kmalloc(sizeof(struct unit_directory), GFP_KERNEL);
+					ud_child = kmalloc(sizeof(*ud_child), GFP_KERNEL);
 					if (!ud_child)
 						goto unit_directory_error;
-					memcpy(ud_child, ud, sizeof(struct unit_directory));
+					memcpy(ud_child, ud, sizeof(*ud_child));
 					nodemgr_register_device(ne, ud_child, &ne->device);
 					ud_child = NULL;
 					
@@ -966,7 +963,7 @@
 				if (ud_child == NULL)
 					break;
 				
-				/* inherit unspecified values so hotplug picks it up */
+				/* inherit unspecified values, the driver core picks it up */
 				if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) &&
 				    !(ud_child->flags & UNIT_DIRECTORY_MODEL_ID))
 				{
@@ -1062,8 +1059,8 @@
 
 #ifdef CONFIG_HOTPLUG
 
-static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
-			   char *buffer, int buffer_size)
+static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
+			  char *buffer, int buffer_size)
 {
 	struct unit_directory *ud;
 	int i = 0;
@@ -1112,8 +1109,8 @@
 
 #else
 
-static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
-			   char *buffer, int buffer_size)
+static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
+			  char *buffer, int buffer_size)
 {
 	return -ENODEV;
 }
@@ -1200,7 +1197,7 @@
 	struct csr1212_csr *csr;
 	struct nodemgr_csr_info *ci;
 
-	ci = kmalloc(sizeof(struct nodemgr_csr_info), GFP_KERNEL);
+	ci = kmalloc(sizeof(*ci), GFP_KERNEL);
 	if (!ci)
 		return;
 
@@ -1349,6 +1346,33 @@
 }
 
 
+/* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3.  This
+ * seems like an optional service but in the end it is practically mandatory
+ * as a consequence of these clauses.
+ *
+ * Note that we cannot do a broadcast write to all nodes at once because some
+ * pre-1394a devices would hang. */
+static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
+{
+	const u64 bc_addr = (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL);
+	quadlet_t bc_remote, bc_local;
+	int ret;
+
+	if (!ne->host->is_irm || ne->generation != generation ||
+	    ne->nodeid == ne->host->node_id)
+		return;
+
+	bc_local = cpu_to_be32(ne->host->csr.broadcast_channel);
+
+	/* Check if the register is implemented and 1394a compliant. */
+	ret = hpsb_read(ne->host, ne->nodeid, generation, bc_addr, &bc_remote,
+			sizeof(bc_remote));
+	if (!ret && bc_remote & cpu_to_be32(0x80000000) &&
+	    bc_remote != bc_local)
+		hpsb_node_write(ne, bc_addr, &bc_local, sizeof(bc_local));
+}
+
+
 static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
 {
 	struct device *dev;
@@ -1360,6 +1384,8 @@
 	if (!dev)
 		return;
 
+	nodemgr_irm_write_bc(ne, generation);
+
 	/* If "needs_probe", then this is either a new or changed node we
 	 * rescan totally. If the generation matches for an existing node
 	 * (one that existed prior to the bus reset) we send update calls
@@ -1381,14 +1407,28 @@
 	struct hpsb_host *host = hi->host;
 	struct class *class = &nodemgr_ne_class;
 	struct class_device *cdev;
+	struct node_entry *ne;
 
 	/* Do some processing of the nodes we've probed. This pulls them
 	 * into the sysfs layer if needed, and can result in processing of
 	 * unit-directories, or just updating the node and it's
-	 * unit-directories. */
+	 * unit-directories.
+	 *
+	 * Run updates before probes. Usually, updates are time-critical
+	 * while probes are time-consuming. (Well, those probes need some
+	 * improvement...) */
+
 	down_read(&class->subsys.rwsem);
-	list_for_each_entry(cdev, &class->children, node)
-		nodemgr_probe_ne(hi, container_of(cdev, struct node_entry, class_dev), generation);
+	list_for_each_entry(cdev, &class->children, node) {
+		ne = container_of(cdev, struct node_entry, class_dev);
+		if (!ne->needs_probe)
+			nodemgr_probe_ne(hi, ne, generation);
+	}
+	list_for_each_entry(cdev, &class->children, node) {
+		ne = container_of(cdev, struct node_entry, class_dev);
+		if (ne->needs_probe)
+			nodemgr_probe_ne(hi, ne, generation);
+	}
         up_read(&class->subsys.rwsem);
 
 
@@ -1413,9 +1453,26 @@
 	return;
 }
 
-/* Because we are a 1394a-2000 compliant IRM, we need to inform all the other
- * nodes of the broadcast channel.  (Really we're only setting the validity
- * bit). Other IRM responsibilities go in here as well. */
+static int nodemgr_send_resume_packet(struct hpsb_host *host)
+{
+	struct hpsb_packet *packet;
+	int ret = 1;
+
+	packet = hpsb_make_phypacket(host,
+			EXTPHYPACKET_TYPE_RESUME |
+			NODEID_TO_NODE(host->node_id) << PHYPACKET_PORT_SHIFT);
+	if (packet) {
+		packet->no_waiter = 1;
+		packet->generation = get_hpsb_generation(host);
+		ret = hpsb_send_packet(packet);
+	}
+	if (ret)
+		HPSB_WARN("fw-host%d: Failed to broadcast resume packet",
+			  host->id);
+	return ret;
+}
+
+/* Perform a few high-level IRM responsibilities. */
 static int nodemgr_do_irm_duties(struct hpsb_host *host, int cycles)
 {
 	quadlet_t bc;
@@ -1424,13 +1481,8 @@
 	if (!host->is_irm || host->irm_id == (nodeid_t)-1)
 		return 1;
 
-	host->csr.broadcast_channel |= 0x40000000;  /* set validity bit */
-
-	bc = cpu_to_be32(host->csr.broadcast_channel);
-
-	hpsb_write(host, LOCAL_BUS | ALL_NODES, get_hpsb_generation(host),
-		   (CSR_REGISTER_BASE | CSR_BROADCAST_CHANNEL),
-		   &bc, sizeof(quadlet_t));
+	/* We are a 1394a-2000 compliant IRM. Set the validity bit. */
+	host->csr.broadcast_channel |= 0x40000000;
 
 	/* If there is no bus manager then we should set the root node's
 	 * force_root bit to promote bus stability per the 1394
@@ -1463,6 +1515,13 @@
 		}
 	}
 
+	/* Some devices suspend their ports while being connected to an inactive
+	 * host adapter, i.e. if connected before the low-level driver is
+	 * loaded.  They become visible either when physically unplugged and
+	 * replugged, or when receiving a resume packet.  Send one once. */
+	if (!host->resume_packet_sent && !nodemgr_send_resume_packet(host))
+		host->resume_packet_sent = 1;
+
 	return 1;
 }
 
@@ -1571,8 +1630,8 @@
 
 		/* Scan our nodes to get the bus options and create node
 		 * entries. This does not do the sysfs stuff, since that
-		 * would trigger hotplug callbacks and such, which is a
-		 * bad idea at this point. */
+		 * would trigger uevents and such, which is a bad idea at
+		 * this point. */
 		nodemgr_node_scan(hi, generation);
 
 		/* This actually does the full probe, with sysfs
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index 3a2f0c0..0b26616 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -151,24 +151,6 @@
 }
 
 /*
- * Returns a node entry (which has its reference count incremented) or NULL if
- * the GUID in question is not known.  Getting a valid entry does not mean that
- * the node with this GUID is currently accessible (might be powered down).
- */
-struct node_entry *hpsb_guid_get_entry(u64 guid);
-
-/* Same as above, but use the nodeid to get an node entry. This is not
- * fool-proof by itself, since the nodeid can change.  */
-struct node_entry *hpsb_nodeid_get_entry(struct hpsb_host *host, nodeid_t nodeid);
-
-/*
- * If the entry refers to a local host, this function will return the pointer
- * to the hpsb_host structure.  It will return NULL otherwise.  Once you have
- * established it is a local host, you can use that knowledge from then on (the
- * GUID won't wander to an external node).  */
-struct hpsb_host *hpsb_get_host_by_ne(struct node_entry *ne);
-
-/*
  * This will fill in the given, pre-initialised hpsb_packet with the current
  * information from the node entry (host, node ID, generation number).  It will
  * return false if the node owning the GUID is not accessible (and not modify the
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 4cf9b8f..b6b96fa 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -161,9 +161,6 @@
 #define PRINT(level, fmt, args...) \
 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
 
-static char version[] __devinitdata =
-	"$Rev: 1313 $ Ben Collins <bcollins@debian.org>";
-
 /* Module Parameters */
 static int phys_dma = 1;
 module_param(phys_dma, int, 0644);
@@ -587,12 +584,13 @@
 	sprintf (irq_buf, "%s", __irq_itoa(ohci->dev->irq));
 #endif
 	PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s]  "
-	      "MMIO=[%lx-%lx]  Max Packet=[%d]",
+	      "MMIO=[%lx-%lx]  Max Packet=[%d]  IR/IT contexts=[%d/%d]",
 	      ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10),
 	      ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf,
 	      pci_resource_start(ohci->dev, 0),
 	      pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1,
-	      ohci->max_packet_size);
+	      ohci->max_packet_size,
+	      ohci->nb_iso_rcv_ctx, ohci->nb_iso_xmit_ctx);
 
 	/* Check all of our ports to make sure that if anything is
 	 * connected, we enable that port. */
@@ -2960,28 +2958,23 @@
 	d->ctrlClear = 0;
 	d->cmdPtr = 0;
 
-	d->buf_cpu = kmalloc(d->num_desc * sizeof(quadlet_t*), GFP_ATOMIC);
-	d->buf_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_ATOMIC);
+	d->buf_cpu = kzalloc(d->num_desc * sizeof(*d->buf_cpu), GFP_ATOMIC);
+	d->buf_bus = kzalloc(d->num_desc * sizeof(*d->buf_bus), GFP_ATOMIC);
 
 	if (d->buf_cpu == NULL || d->buf_bus == NULL) {
 		PRINT(KERN_ERR, "Failed to allocate dma buffer");
 		free_dma_rcv_ctx(d);
 		return -ENOMEM;
 	}
-	memset(d->buf_cpu, 0, d->num_desc * sizeof(quadlet_t*));
-	memset(d->buf_bus, 0, d->num_desc * sizeof(dma_addr_t));
 
-	d->prg_cpu = kmalloc(d->num_desc * sizeof(struct dma_cmd*),
-				GFP_ATOMIC);
-	d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_ATOMIC);
+	d->prg_cpu = kzalloc(d->num_desc * sizeof(*d->prg_cpu), GFP_ATOMIC);
+	d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_ATOMIC);
 
 	if (d->prg_cpu == NULL || d->prg_bus == NULL) {
 		PRINT(KERN_ERR, "Failed to allocate dma prg");
 		free_dma_rcv_ctx(d);
 		return -ENOMEM;
 	}
-	memset(d->prg_cpu, 0, d->num_desc * sizeof(struct dma_cmd*));
-	memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));
 
 	d->spb = kmalloc(d->split_buf_size, GFP_ATOMIC);
 
@@ -3093,17 +3086,14 @@
 	d->ctrlClear = 0;
 	d->cmdPtr = 0;
 
-	d->prg_cpu = kmalloc(d->num_desc * sizeof(struct at_dma_prg*),
-			     GFP_KERNEL);
-	d->prg_bus = kmalloc(d->num_desc * sizeof(dma_addr_t), GFP_KERNEL);
+	d->prg_cpu = kzalloc(d->num_desc * sizeof(*d->prg_cpu), GFP_KERNEL);
+	d->prg_bus = kzalloc(d->num_desc * sizeof(*d->prg_bus), GFP_KERNEL);
 
 	if (d->prg_cpu == NULL || d->prg_bus == NULL) {
 		PRINT(KERN_ERR, "Failed to allocate at dma prg");
 		free_dma_trm_ctx(d);
 		return -ENOMEM;
 	}
-	memset(d->prg_cpu, 0, d->num_desc * sizeof(struct at_dma_prg*));
-	memset(d->prg_bus, 0, d->num_desc * sizeof(dma_addr_t));
 
 	len = sprintf(pool_name, "ohci1394_trm_prg");
 	sprintf(pool_name+len, "%d", num_allocs);
@@ -3201,8 +3191,6 @@
 	.hw_csr_reg =		ohci_hw_csr_reg,
 };
 
-
-
 /***********************************
  * PCI Driver Interface functions  *
  ***********************************/
@@ -3217,15 +3205,10 @@
 static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
 					const struct pci_device_id *ent)
 {
-	static int version_printed = 0;
-
 	struct hpsb_host *host;
 	struct ti_ohci *ohci;	/* shortcut to currently handled device */
 	unsigned long ohci_base;
 
-	if (version_printed++ == 0)
-		PRINT_G(KERN_INFO, "%s", version);
-
         if (pci_enable_device(dev))
 		FAIL(-ENXIO, "Failed to enable OHCI hardware");
         pci_set_master(dev);
@@ -3369,13 +3352,8 @@
 	/* Determine the number of available IR and IT contexts. */
 	ohci->nb_iso_rcv_ctx =
 		get_nb_iso_ctx(ohci, OHCI1394_IsoRecvIntMaskSet);
-	DBGMSG("%d iso receive contexts available",
-	       ohci->nb_iso_rcv_ctx);
-
 	ohci->nb_iso_xmit_ctx =
 		get_nb_iso_ctx(ohci, OHCI1394_IsoXmitIntMaskSet);
-	DBGMSG("%d iso transmit contexts available",
-	       ohci->nb_iso_xmit_ctx);
 
 	/* Set the usage bits for non-existent contexts so they can't
 	 * be allocated */
@@ -3606,8 +3584,6 @@
 	.suspend =	ohci1394_pci_suspend,
 };
 
-
-
 /***********************************
  * OHCI1394 Video Interface        *
  ***********************************/
@@ -3714,7 +3690,6 @@
 EXPORT_SYMBOL(ohci1394_register_iso_tasklet);
 EXPORT_SYMBOL(ohci1394_unregister_iso_tasklet);
 
-
 /***********************************
  * General module initialization   *
  ***********************************/
diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h
index cc66c1c..7df0962 100644
--- a/drivers/ieee1394/ohci1394.h
+++ b/drivers/ieee1394/ohci1394.h
@@ -219,8 +219,8 @@
 
 	int self_id_errors;
 
-	/* Tasklets for iso receive and transmit, used by video1394,
-	 * amdtp and dv1394 */
+	/* Tasklets for iso receive and transmit, used by video1394
+	 * and dv1394 */
 
 	struct list_head iso_tasklet_list;
 	spinlock_t iso_tasklet_list_lock;
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c
index 6b1ab87..e2edc41 100644
--- a/drivers/ieee1394/pcilynx.c
+++ b/drivers/ieee1394/pcilynx.c
@@ -1435,7 +1435,7 @@
         	struct i2c_algo_bit_data i2c_adapter_data;
 
         	error = -ENOMEM;
-		i2c_ad = kmalloc(sizeof(struct i2c_adapter), SLAB_KERNEL);
+		i2c_ad = kmalloc(sizeof(*i2c_ad), SLAB_KERNEL);
         	if (!i2c_ad) FAIL("failed to allocate I2C adapter memory");
 
 		memcpy(i2c_ad, &bit_ops, sizeof(struct i2c_adapter));
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 24411e6..b052356 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -102,12 +102,9 @@
 {
 	struct pending_request *req;
 
-	req = (struct pending_request *)kmalloc(sizeof(struct pending_request),
-						flags);
-	if (req != NULL) {
-		memset(req, 0, sizeof(struct pending_request));
+	req = kzalloc(sizeof(*req), flags);
+	if (req)
 		INIT_LIST_HEAD(&req->list);
-	}
 
 	return req;
 }
@@ -192,9 +189,9 @@
 	struct host_info *hi;
 	unsigned long flags;
 
-	hi = (struct host_info *)kmalloc(sizeof(struct host_info), GFP_KERNEL);
+	hi = kmalloc(sizeof(*hi), GFP_KERNEL);
 
-	if (hi != NULL) {
+	if (hi) {
 		INIT_LIST_HEAD(&hi->list);
 		hi->host = host;
 		INIT_LIST_HEAD(&hi->file_info_list);
@@ -315,8 +312,8 @@
 				break;
 
 			if (!ibs) {
-				ibs = kmalloc(sizeof(struct iso_block_store)
-					      + length, SLAB_ATOMIC);
+				ibs = kmalloc(sizeof(*ibs) + length,
+					      SLAB_ATOMIC);
 				if (!ibs) {
 					kfree(req);
 					break;
@@ -376,8 +373,8 @@
 				break;
 
 			if (!ibs) {
-				ibs = kmalloc(sizeof(struct iso_block_store)
-					      + length, SLAB_ATOMIC);
+				ibs = kmalloc(sizeof(*ibs) + length,
+					      SLAB_ATOMIC);
 				if (!ibs) {
 					kfree(req);
 					break;
@@ -502,10 +499,9 @@
 	switch (req->req.type) {
 	case RAW1394_REQ_LIST_CARDS:
 		spin_lock_irqsave(&host_info_lock, flags);
-		khl = kmalloc(sizeof(struct raw1394_khost_list) * host_count,
-			      SLAB_ATOMIC);
+		khl = kmalloc(sizeof(*khl) * host_count, SLAB_ATOMIC);
 
-		if (khl != NULL) {
+		if (khl) {
 			req->req.misc = host_count;
 			req->data = (quadlet_t *) khl;
 
@@ -517,7 +513,7 @@
 		}
 		spin_unlock_irqrestore(&host_info_lock, flags);
 
-		if (khl != NULL) {
+		if (khl) {
 			req->req.error = RAW1394_ERROR_NONE;
 			req->req.length = min(req->req.length,
 					      (u32) (sizeof
@@ -1647,13 +1643,13 @@
 		return (-EINVAL);
 	}
 	/* addr-list-entry for fileinfo */
-	addr = (struct arm_addr *)kmalloc(sizeof(struct arm_addr), SLAB_KERNEL);
+	addr = kmalloc(sizeof(*addr), SLAB_KERNEL);
 	if (!addr) {
 		req->req.length = 0;
 		return (-ENOMEM);
 	}
 	/* allocation of addr_space_buffer */
-	addr->addr_space_buffer = (u8 *) vmalloc(req->req.length);
+	addr->addr_space_buffer = vmalloc(req->req.length);
 	if (!(addr->addr_space_buffer)) {
 		kfree(addr);
 		req->req.length = 0;
@@ -2122,8 +2118,7 @@
 		return -ENOMEM;
 	}
 
-	cache->filled_head =
-	    kmalloc(sizeof(struct csr1212_cache_region), GFP_KERNEL);
+	cache->filled_head = kmalloc(sizeof(*cache->filled_head), GFP_KERNEL);
 	if (!cache->filled_head) {
 		csr1212_release_keyval(fi->csr1212_dirs[dr]);
 		fi->csr1212_dirs[dr] = NULL;
@@ -2136,7 +2131,6 @@
 			   req->req.length)) {
 		csr1212_release_keyval(fi->csr1212_dirs[dr]);
 		fi->csr1212_dirs[dr] = NULL;
-		CSR1212_FREE(cache);
 		ret = -EFAULT;
 	} else {
 		cache->len = req->req.length;
@@ -2172,7 +2166,7 @@
 		}
 	}
 	kfree(cache->filled_head);
-	kfree(cache);
+	CSR1212_FREE(cache);
 
 	if (ret >= 0) {
 		/* we have to free the request, because we queue no response,
@@ -2488,8 +2482,8 @@
 
 	/* ensure user-supplied buffer is accessible and big enough */
 	if (!access_ok(VERIFY_WRITE, upackets.infos,
-			upackets.n_packets *
-			sizeof(struct raw1394_iso_packet_info)))
+		       upackets.n_packets *
+		       sizeof(struct raw1394_iso_packet_info)))
 		return -EFAULT;
 
 	/* copy the packet_infos out */
@@ -2522,8 +2516,8 @@
 
 	/* ensure user-supplied buffer is accessible and big enough */
 	if (!access_ok(VERIFY_READ, upackets.infos,
-			upackets.n_packets *
-			sizeof(struct raw1394_iso_packet_info)))
+		       upackets.n_packets *
+		       sizeof(struct raw1394_iso_packet_info)))
 		return -EFAULT;
 
 	/* copy the infos structs in and queue the packets */
@@ -2684,11 +2678,10 @@
 {
 	struct file_info *fi;
 
-	fi = kmalloc(sizeof(struct file_info), SLAB_KERNEL);
-	if (fi == NULL)
+	fi = kzalloc(sizeof(*fi), SLAB_KERNEL);
+	if (!fi)
 		return -ENOMEM;
 
-	memset(fi, 0, sizeof(struct file_info));
 	fi->notification = (u8) RAW1394_NOTIFY_ON;	/* busreset notification */
 
 	INIT_LIST_HEAD(&fi->list);
@@ -2748,8 +2741,7 @@
 						    list) {
 					entry = fi_hlp->addr_list.next;
 					while (entry != &(fi_hlp->addr_list)) {
-						arm_addr = list_entry(entry,
-								      struct
+						arm_addr = list_entry(entry, struct
 								      arm_addr,
 								      addr_list);
 						if (arm_addr->start ==
@@ -2912,16 +2904,17 @@
 
 	hpsb_register_highlevel(&raw1394_highlevel);
 
-	if (IS_ERR(class_device_create(hpsb_protocol_class, NULL, MKDEV(
-		IEEE1394_MAJOR,	IEEE1394_MINOR_BLOCK_RAW1394 * 16), 
-		NULL, RAW1394_DEVICE_NAME))) {
+	if (IS_ERR
+	    (class_device_create
+	     (hpsb_protocol_class, NULL,
+	      MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL,
+	      RAW1394_DEVICE_NAME))) {
 		ret = -EFAULT;
 		goto out_unreg;
 	}
-	
-	devfs_mk_cdev(MKDEV(
-		IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
-		S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME);
+
+	devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
+		      S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME);
 
 	cdev_init(&raw1394_cdev, &raw1394_fops);
 	raw1394_cdev.owner = THIS_MODULE;
@@ -2943,20 +2936,22 @@
 
 	goto out;
 
-out_dev:
+      out_dev:
 	devfs_remove(RAW1394_DEVICE_NAME);
 	class_device_destroy(hpsb_protocol_class,
-		MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
-out_unreg:
+			     MKDEV(IEEE1394_MAJOR,
+				   IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+      out_unreg:
 	hpsb_unregister_highlevel(&raw1394_highlevel);
-out:
+      out:
 	return ret;
 }
 
 static void __exit cleanup_raw1394(void)
 {
 	class_device_destroy(hpsb_protocol_class,
-		MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16));
+			     MKDEV(IEEE1394_MAJOR,
+				   IEEE1394_MINOR_BLOCK_RAW1394 * 16));
 	cdev_del(&raw1394_cdev);
 	devfs_remove(RAW1394_DEVICE_NAME);
 	hpsb_unregister_highlevel(&raw1394_highlevel);
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index f7e18cc..18d7eda 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -80,9 +80,6 @@
 #include "ieee1394_transactions.h"
 #include "sbp2.h"
 
-static char version[] __devinitdata =
-	"$Rev: 1306 $ Ben Collins <bcollins@debian.org>";
-
 /*
  * Module load parameter definitions
  */
@@ -151,18 +148,15 @@
 module_param(force_inquiry_hack, int, 0444);
 MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)");
 
-
 /*
  * Export information about protocols/devices supported by this driver.
  */
 static struct ieee1394_device_id sbp2_id_table[] = {
 	{
-		.match_flags =IEEE1394_MATCH_SPECIFIER_ID |
-		              IEEE1394_MATCH_VERSION,
-		.specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
-		.version =    SBP2_SW_VERSION_ENTRY & 0xffffff
-	},
-	{ }
+	 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
+	 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
+	 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
+	{}
 };
 
 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
@@ -221,7 +215,6 @@
 
 #define SBP2_ERR(fmt, args...)		HPSB_ERR("sbp2: "fmt, ## args)
 
-
 /*
  * Globals
  */
@@ -254,8 +247,8 @@
 
 #ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
 static struct hpsb_address_ops sbp2_physdma_ops = {
-        .read = sbp2_handle_physdma_read,
-        .write = sbp2_handle_physdma_write,
+	.read = sbp2_handle_physdma_read,
+	.write = sbp2_handle_physdma_write,
 };
 #endif
 
@@ -287,7 +280,6 @@
  * General utility functions
  **************************************/
 
-
 #ifndef __BIG_ENDIAN
 /*
  * Converts a buffer from be32 to cpu byte ordering. Length is in bytes.
@@ -324,7 +316,8 @@
 /*
  * Debug packet dump routine. Length is in bytes.
  */
-static void sbp2util_packet_dump(void *buffer, int length, char *dump_name, u32 dump_phys_addr)
+static void sbp2util_packet_dump(void *buffer, int length, char *dump_name,
+				 u32 dump_phys_addr)
 {
 	int i;
 	unsigned char *dump = buffer;
@@ -345,7 +338,7 @@
 			printk("  ");
 		if ((i & 0xf) == 0)
 			printk("\n   ");
-		printk("%02x ", (int) dump[i]);
+		printk("%02x ", (int)dump[i]);
 	}
 	printk("\n");
 
@@ -364,9 +357,9 @@
 
 	for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) {
 		if (msleep_interruptible(100))	/* 100ms */
-			return(1);
+			return 1;
 	}
-	return ((i > 0) ? 0:1);
+	return (i > 0) ? 0 : 1;
 }
 
 /* Free's an allocated packet */
@@ -380,21 +373,22 @@
  * subaction and returns immediately. Can be used from interrupts.
  */
 static int sbp2util_node_write_no_wait(struct node_entry *ne, u64 addr,
-				quadlet_t *buffer, size_t length)
+				       quadlet_t *buffer, size_t length)
 {
 	struct hpsb_packet *packet;
 
 	packet = hpsb_make_writepacket(ne->host, ne->nodeid,
 				       addr, buffer, length);
-        if (!packet)
-                return -ENOMEM;
+	if (!packet)
+		return -ENOMEM;
 
-	hpsb_set_packet_complete_task(packet, (void (*)(void*))sbp2_free_packet,
+	hpsb_set_packet_complete_task(packet,
+				      (void (*)(void *))sbp2_free_packet,
 				      packet);
 
 	hpsb_node_fill_packet(ne, packet);
 
-        if (hpsb_send_packet(packet) < 0) {
+	if (hpsb_send_packet(packet) < 0) {
 		sbp2_free_packet(packet);
 		return -EIO;
 	}
@@ -417,22 +411,22 @@
 
 	spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
 	for (i = 0; i < orbs; i++) {
-		command = (struct sbp2_command_info *)
-		    kmalloc(sizeof(struct sbp2_command_info), GFP_ATOMIC);
+		command = kzalloc(sizeof(*command), GFP_ATOMIC);
 		if (!command) {
-			spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
-			return(-ENOMEM);
+			spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock,
+					       flags);
+			return -ENOMEM;
 		}
-		memset(command, '\0', sizeof(struct sbp2_command_info));
 		command->command_orb_dma =
-			pci_map_single (hi->host->pdev, &command->command_orb,
-					sizeof(struct sbp2_command_orb),
-					PCI_DMA_BIDIRECTIONAL);
+		    pci_map_single(hi->host->pdev, &command->command_orb,
+				   sizeof(struct sbp2_command_orb),
+				   PCI_DMA_BIDIRECTIONAL);
 		SBP2_DMA_ALLOC("single command orb DMA");
 		command->sge_dma =
-			pci_map_single (hi->host->pdev, &command->scatter_gather_element,
-					sizeof(command->scatter_gather_element),
-					PCI_DMA_BIDIRECTIONAL);
+		    pci_map_single(hi->host->pdev,
+				   &command->scatter_gather_element,
+				   sizeof(command->scatter_gather_element),
+				   PCI_DMA_BIDIRECTIONAL);
 		SBP2_DMA_ALLOC("scatter_gather_element");
 		INIT_LIST_HEAD(&command->list);
 		list_add_tail(&command->list, &scsi_id->sbp2_command_orb_completed);
@@ -488,7 +482,7 @@
 		list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) {
 			if (command->command_orb_dma == orb) {
 				spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
-				return (command);
+				return command;
 			}
 		}
 	}
@@ -496,7 +490,7 @@
 
 	SBP2_ORB_DEBUG("could not match command orb %x", (unsigned int)orb);
 
-	return(NULL);
+	return NULL;
 }
 
 /*
@@ -513,12 +507,12 @@
 		list_for_each_entry(command, &scsi_id->sbp2_command_orb_inuse, list) {
 			if (command->Current_SCpnt == SCpnt) {
 				spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
-				return (command);
+				return command;
 			}
 		}
 	}
 	spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
-	return(NULL);
+	return NULL;
 }
 
 /*
@@ -545,7 +539,7 @@
 		SBP2_ERR("sbp2util_allocate_command_orb - No orbs available!");
 	}
 	spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
-	return (command);
+	return command;
 }
 
 /* Free our DMA's */
@@ -587,7 +581,8 @@
 /*
  * This function moves a command to the completed orb list.
  */
-static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, struct sbp2_command_info *command)
+static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id,
+					    struct sbp2_command_info *command)
 {
 	unsigned long flags;
 
@@ -606,8 +601,6 @@
 	return scsi_id && scsi_id->ne && !scsi_id->ne->in_limbo;
 }
 
-
-
 /*********************************************
  * IEEE-1394 core driver stack related section
  *********************************************/
@@ -627,14 +620,14 @@
 	if (ud->flags & UNIT_DIRECTORY_HAS_LUN_DIRECTORY)
 		return -ENODEV;
 
-        scsi_id = sbp2_alloc_device(ud);
+	scsi_id = sbp2_alloc_device(ud);
 
-        if (!scsi_id)
-                return -ENOMEM;
+	if (!scsi_id)
+		return -ENOMEM;
 
-        sbp2_parse_unit_directory(scsi_id, ud);
+	sbp2_parse_unit_directory(scsi_id, ud);
 
-        return sbp2_start_device(scsi_id);
+	return sbp2_start_device(scsi_id);
 }
 
 static int sbp2_remove(struct device *dev)
@@ -719,12 +712,11 @@
 
 	SBP2_DEBUG("sbp2_alloc_device");
 
-	scsi_id = kmalloc(sizeof(*scsi_id), GFP_KERNEL);
+	scsi_id = kzalloc(sizeof(*scsi_id), GFP_KERNEL);
 	if (!scsi_id) {
 		SBP2_ERR("failed to create scsi_id");
 		goto failed_alloc;
 	}
-	memset(scsi_id, 0, sizeof(*scsi_id));
 
 	scsi_id->ne = ud->ne;
 	scsi_id->ud = ud;
@@ -735,7 +727,7 @@
 	INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
 	INIT_LIST_HEAD(&scsi_id->scsi_list);
 	spin_lock_init(&scsi_id->sbp2_command_orb_lock);
-	scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED;
+	scsi_id->sbp2_lun = 0;
 
 	ud->device.driver_data = scsi_id;
 
@@ -769,7 +761,7 @@
 
 	/* Register our host with the SCSI stack. */
 	scsi_host = scsi_host_alloc(&scsi_driver_template,
-				    sizeof (unsigned long));
+				    sizeof(unsigned long));
 	if (!scsi_host) {
 		SBP2_ERR("failed to register scsi host");
 		goto failed_alloc;
@@ -790,7 +782,6 @@
 	return NULL;
 }
 
-
 static void sbp2_host_reset(struct hpsb_host *host)
 {
 	struct sbp2scsi_host_info *hi;
@@ -804,7 +795,6 @@
 	}
 }
 
-
 /*
  * This function is where we first pull the node unique ids, and then
  * allocate memory and register a SBP-2 device.
@@ -818,7 +808,8 @@
 
 	/* Login FIFO DMA */
 	scsi_id->login_response =
-		pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_login_response),
+		pci_alloc_consistent(hi->host->pdev,
+				     sizeof(struct sbp2_login_response),
 				     &scsi_id->login_response_dma);
 	if (!scsi_id->login_response)
 		goto alloc_fail;
@@ -826,7 +817,8 @@
 
 	/* Query logins ORB DMA */
 	scsi_id->query_logins_orb =
-		pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_query_logins_orb),
+		pci_alloc_consistent(hi->host->pdev,
+				     sizeof(struct sbp2_query_logins_orb),
 				     &scsi_id->query_logins_orb_dma);
 	if (!scsi_id->query_logins_orb)
 		goto alloc_fail;
@@ -834,7 +826,8 @@
 
 	/* Query logins response DMA */
 	scsi_id->query_logins_response =
-		pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_query_logins_response),
+		pci_alloc_consistent(hi->host->pdev,
+				     sizeof(struct sbp2_query_logins_response),
 				     &scsi_id->query_logins_response_dma);
 	if (!scsi_id->query_logins_response)
 		goto alloc_fail;
@@ -842,7 +835,8 @@
 
 	/* Reconnect ORB DMA */
 	scsi_id->reconnect_orb =
-		pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_reconnect_orb),
+		pci_alloc_consistent(hi->host->pdev,
+				     sizeof(struct sbp2_reconnect_orb),
 				     &scsi_id->reconnect_orb_dma);
 	if (!scsi_id->reconnect_orb)
 		goto alloc_fail;
@@ -850,7 +844,8 @@
 
 	/* Logout ORB DMA */
 	scsi_id->logout_orb =
-		pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_logout_orb),
+		pci_alloc_consistent(hi->host->pdev,
+				     sizeof(struct sbp2_logout_orb),
 				     &scsi_id->logout_orb_dma);
 	if (!scsi_id->logout_orb)
 		goto alloc_fail;
@@ -858,58 +853,11 @@
 
 	/* Login ORB DMA */
 	scsi_id->login_orb =
-		pci_alloc_consistent(hi->host->pdev, sizeof(struct sbp2_login_orb),
+		pci_alloc_consistent(hi->host->pdev,
+				     sizeof(struct sbp2_login_orb),
 				     &scsi_id->login_orb_dma);
-	if (!scsi_id->login_orb) {
-alloc_fail:
-		if (scsi_id->query_logins_response) {
-			pci_free_consistent(hi->host->pdev,
-					    sizeof(struct sbp2_query_logins_response),
-					    scsi_id->query_logins_response,
-					    scsi_id->query_logins_response_dma);
-			SBP2_DMA_FREE("query logins response DMA");
-		}
-
-		if (scsi_id->query_logins_orb) {
-			pci_free_consistent(hi->host->pdev,
-					    sizeof(struct sbp2_query_logins_orb),
-					    scsi_id->query_logins_orb,
-					    scsi_id->query_logins_orb_dma);
-			SBP2_DMA_FREE("query logins ORB DMA");
-		}
-
-		if (scsi_id->logout_orb) {
-			pci_free_consistent(hi->host->pdev,
-					sizeof(struct sbp2_logout_orb),
-					scsi_id->logout_orb,
-					scsi_id->logout_orb_dma);
-			SBP2_DMA_FREE("logout ORB DMA");
-		}
-
-		if (scsi_id->reconnect_orb) {
-			pci_free_consistent(hi->host->pdev,
-					sizeof(struct sbp2_reconnect_orb),
-					scsi_id->reconnect_orb,
-					scsi_id->reconnect_orb_dma);
-			SBP2_DMA_FREE("reconnect ORB DMA");
-		}
-
-		if (scsi_id->login_response) {
-			pci_free_consistent(hi->host->pdev,
-					sizeof(struct sbp2_login_response),
-					scsi_id->login_response,
-					scsi_id->login_response_dma);
-			SBP2_DMA_FREE("login FIFO DMA");
-		}
-
-		list_del(&scsi_id->scsi_list);
-
-		kfree(scsi_id);
-
-		SBP2_ERR ("Could not allocate memory for scsi_id");
-
-		return -ENOMEM;
-	}
+	if (!scsi_id->login_orb)
+		goto alloc_fail;
 	SBP2_DMA_ALLOC("consistent DMA region for login ORB");
 
 	SBP2_DEBUG("New SBP-2 device inserted, SCSI ID = %x", scsi_id->ud->id);
@@ -935,7 +883,7 @@
 		sbp2_remove_device(scsi_id);
 		return -EINTR;
 	}
-	
+
 	/*
 	 * Login to the sbp-2 device
 	 */
@@ -964,10 +912,17 @@
 	error = scsi_add_device(scsi_id->scsi_host, 0, scsi_id->ud->id, 0);
 	if (error) {
 		SBP2_ERR("scsi_add_device failed");
+		sbp2_logout_device(scsi_id);
+		sbp2_remove_device(scsi_id);
 		return error;
 	}
 
 	return 0;
+
+alloc_fail:
+	SBP2_ERR("Could not allocate memory for scsi_id");
+	sbp2_remove_device(scsi_id);
+	return -ENOMEM;
 }
 
 /*
@@ -1054,51 +1009,44 @@
  * This function deals with physical dma write requests (for adapters that do not support
  * physical dma in hardware). Mostly just here for debugging...
  */
-static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data,
-                                     u64 addr, size_t length, u16 flags)
+static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid,
+				     int destid, quadlet_t *data, u64 addr,
+				     size_t length, u16 flags)
 {
 
-        /*
-         * Manually put the data in the right place.
-         */
-        memcpy(bus_to_virt((u32)addr), data, length);
-	sbp2util_packet_dump(data, length, "sbp2 phys dma write by device", (u32)addr);
-        return(RCODE_COMPLETE);
+	/*
+	 * Manually put the data in the right place.
+	 */
+	memcpy(bus_to_virt((u32) addr), data, length);
+	sbp2util_packet_dump(data, length, "sbp2 phys dma write by device",
+			     (u32) addr);
+	return RCODE_COMPLETE;
 }
 
 /*
  * This function deals with physical dma read requests (for adapters that do not support
  * physical dma in hardware). Mostly just here for debugging...
  */
-static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_t *data,
-                                    u64 addr, size_t length, u16 flags)
+static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid,
+				    quadlet_t *data, u64 addr, size_t length,
+				    u16 flags)
 {
 
-        /*
-         * Grab data from memory and send a read response.
-         */
-        memcpy(data, bus_to_virt((u32)addr), length);
-	sbp2util_packet_dump(data, length, "sbp2 phys dma read by device", (u32)addr);
-        return(RCODE_COMPLETE);
+	/*
+	 * Grab data from memory and send a read response.
+	 */
+	memcpy(data, bus_to_virt((u32) addr), length);
+	sbp2util_packet_dump(data, length, "sbp2 phys dma read by device",
+			     (u32) addr);
+	return RCODE_COMPLETE;
 }
 #endif
 
-
 /**************************************
  * SBP-2 protocol related section
  **************************************/
 
 /*
- * This function determines if we should convert scsi commands for a particular sbp2 device type
- */
-static __inline__ int sbp2_command_conversion_device_type(u8 device_type)
-{
-	return (((device_type == TYPE_DISK) ||
-		 (device_type == TYPE_RBC) ||
-		 (device_type == TYPE_ROM)) ? 1:0);
-}
-
-/*
  * This function queries the device for the maximum concurrent logins it
  * supports.
  */
@@ -1120,11 +1068,7 @@
 
 	scsi_id->query_logins_orb->lun_misc = ORB_SET_FUNCTION(SBP2_QUERY_LOGINS_REQUEST);
 	scsi_id->query_logins_orb->lun_misc |= ORB_SET_NOTIFY(1);
-	if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
-		scsi_id->query_logins_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun);
-		SBP2_DEBUG("sbp2_query_logins: set lun to %d",
-			   ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun));
-	}
+	scsi_id->query_logins_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_lun);
 	SBP2_DEBUG("sbp2_query_logins: lun_misc initialized");
 
 	scsi_id->query_logins_orb->reserved_resp_length =
@@ -1161,12 +1105,12 @@
 
 	if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 2*HZ)) {
 		SBP2_INFO("Error querying logins to SBP-2 device - timed out");
-		return(-EIO);
+		return -EIO;
 	}
 
 	if (scsi_id->status_block.ORB_offset_lo != scsi_id->query_logins_orb_dma) {
 		SBP2_INFO("Error querying logins to SBP-2 device - timed out");
-		return(-EIO);
+		return -EIO;
 	}
 
 	if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) ||
@@ -1174,7 +1118,7 @@
 	    STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
 
 		SBP2_INFO("Error querying logins to SBP-2 device - timed out");
-		return(-EIO);
+		return -EIO;
 	}
 
 	sbp2util_cpu_to_be32_buffer(scsi_id->query_logins_response, sizeof(struct sbp2_query_logins_response));
@@ -1191,7 +1135,7 @@
 	SBP2_DEBUG("Number of active logins: %d", active_logins);
 
 	if (active_logins >= max_logins) {
-		return(-EIO);
+		return -EIO;
 	}
 
 	return 0;
@@ -1210,13 +1154,13 @@
 
 	if (!scsi_id->login_orb) {
 		SBP2_DEBUG("sbp2_login_device: login_orb not alloc'd!");
-		return(-EIO);
+		return -EIO;
 	}
 
 	if (!exclusive_login) {
 		if (sbp2_query_logins(scsi_id)) {
 			SBP2_INFO("Device does not support any more concurrent logins");
-			return(-EIO);
+			return -EIO;
 		}
 	}
 
@@ -1233,12 +1177,7 @@
 	scsi_id->login_orb->lun_misc |= ORB_SET_RECONNECT(0);	/* One second reconnect time */
 	scsi_id->login_orb->lun_misc |= ORB_SET_EXCLUSIVE(exclusive_login);	/* Exclusive access to device */
 	scsi_id->login_orb->lun_misc |= ORB_SET_NOTIFY(1);	/* Notify us of login complete */
-	/* Set the lun if we were able to pull it from the device's unit directory */
-	if (scsi_id->sbp2_device_type_and_lun != SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
-		scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun);
-		SBP2_DEBUG("sbp2_query_logins: set lun to %d",
-			   ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun));
-	}
+	scsi_id->login_orb->lun_misc |= ORB_SET_LUN(scsi_id->sbp2_lun);
 	SBP2_DEBUG("sbp2_login_device: lun_misc initialized");
 
 	scsi_id->login_orb->passwd_resp_lengths =
@@ -1288,7 +1227,7 @@
 	 */
 	if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 20*HZ)) {
 		SBP2_ERR("Error logging into SBP-2 device - login timed-out");
-		return(-EIO);
+		return -EIO;
 	}
 
 	/*
@@ -1296,7 +1235,7 @@
 	 */
 	if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) {
 		SBP2_ERR("Error logging into SBP-2 device - login timed-out");
-		return(-EIO);
+		return -EIO;
 	}
 
 	/*
@@ -1307,7 +1246,7 @@
 	    STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
 
 		SBP2_ERR("Error logging into SBP-2 device - login failed");
-		return(-EIO);
+		return -EIO;
 	}
 
 	/*
@@ -1331,7 +1270,7 @@
 
 	SBP2_INFO("Logged into SBP-2 device");
 
-	return(0);
+	return 0;
 
 }
 
@@ -1385,8 +1324,7 @@
 	atomic_set(&scsi_id->sbp2_login_complete, 0);
 
 	error = hpsb_node_write(scsi_id->ne,
-	                            scsi_id->sbp2_management_agent_addr,
-	                            data, 8);
+				scsi_id->sbp2_management_agent_addr, data, 8);
 	if (error)
 		return error;
 
@@ -1396,7 +1334,7 @@
 
 	SBP2_INFO("Logged out of SBP-2 device");
 
-	return(0);
+	return 0;
 
 }
 
@@ -1456,8 +1394,7 @@
 	atomic_set(&scsi_id->sbp2_login_complete, 0);
 
 	error = hpsb_node_write(scsi_id->ne,
-	                            scsi_id->sbp2_management_agent_addr,
-	                            data, 8);
+				scsi_id->sbp2_management_agent_addr, data, 8);
 	if (error)
 		return error;
 
@@ -1466,7 +1403,7 @@
 	 */
 	if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) {
 		SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
-		return(-EIO);
+		return -EIO;
 	}
 
 	/*
@@ -1474,7 +1411,7 @@
 	 */
 	if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) {
 		SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out");
-		return(-EIO);
+		return -EIO;
 	}
 
 	/*
@@ -1485,12 +1422,12 @@
 	    STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) {
 
 		SBP2_ERR("Error reconnecting to SBP-2 device - reconnect failed");
-		return(-EIO);
+		return -EIO;
 	}
 
 	HPSB_DEBUG("Reconnected to SBP-2 device");
 
-	return(0);
+	return 0;
 
 }
 
@@ -1513,10 +1450,9 @@
 		SBP2_ERR("sbp2_set_busy_timeout error");
 	}
 
-	return(0);
+	return 0;
 }
 
-
 /*
  * This function is called to parse sbp2 device's config rom unit
  * directory. Used to determine things like sbp2 management agent offset,
@@ -1529,7 +1465,7 @@
 	struct csr1212_dentry *dentry;
 	u64 management_agent_addr;
 	u32 command_set_spec_id, command_set, unit_characteristics,
-		firmware_revision, workarounds;
+	    firmware_revision, workarounds;
 	int i;
 
 	SBP2_DEBUG("sbp2_parse_unit_directory");
@@ -1547,13 +1483,14 @@
 			if (kv->key.type == CSR1212_KV_TYPE_CSR_OFFSET) {
 				/* Save off the management agent address */
 				management_agent_addr =
-					CSR1212_REGISTER_SPACE_BASE +
-					(kv->value.csr_offset << 2);
+				    CSR1212_REGISTER_SPACE_BASE +
+				    (kv->value.csr_offset << 2);
 
 				SBP2_DEBUG("sbp2_management_agent_addr = %x",
-					   (unsigned int) management_agent_addr);
+					   (unsigned int)management_agent_addr);
 			} else if (kv->key.type == CSR1212_KV_TYPE_IMMEDIATE) {
-				scsi_id->sbp2_device_type_and_lun = kv->value.immediate;
+				scsi_id->sbp2_lun =
+				    ORB_SET_LUN(kv->value.immediate);
 			}
 			break;
 
@@ -1561,14 +1498,14 @@
 			/* Command spec organization */
 			command_set_spec_id = kv->value.immediate;
 			SBP2_DEBUG("sbp2_command_set_spec_id = %x",
-				   (unsigned int) command_set_spec_id);
+				   (unsigned int)command_set_spec_id);
 			break;
 
 		case SBP2_COMMAND_SET_KEY:
 			/* Command set used by sbp2 device */
 			command_set = kv->value.immediate;
 			SBP2_DEBUG("sbp2_command_set = %x",
-				   (unsigned int) command_set);
+				   (unsigned int)command_set);
 			break;
 
 		case SBP2_UNIT_CHARACTERISTICS_KEY:
@@ -1578,7 +1515,7 @@
 			 */
 			unit_characteristics = kv->value.immediate;
 			SBP2_DEBUG("sbp2_unit_characteristics = %x",
-				   (unsigned int) unit_characteristics);
+				   (unsigned int)unit_characteristics);
 			break;
 
 		case SBP2_FIRMWARE_REVISION_KEY:
@@ -1586,9 +1523,10 @@
 			firmware_revision = kv->value.immediate;
 			if (force_inquiry_hack)
 				SBP2_INFO("sbp2_firmware_revision = %x",
-				   (unsigned int) firmware_revision);
-			else	SBP2_DEBUG("sbp2_firmware_revision = %x",
-				   (unsigned int) firmware_revision);
+					  (unsigned int)firmware_revision);
+			else
+				SBP2_DEBUG("sbp2_firmware_revision = %x",
+					   (unsigned int)firmware_revision);
 			break;
 
 		default:
@@ -1646,7 +1584,7 @@
 		scsi_id->sbp2_firmware_revision = firmware_revision;
 		scsi_id->workarounds = workarounds;
 		if (ud->flags & UNIT_DIRECTORY_HAS_LUN)
-			scsi_id->sbp2_device_type_and_lun = ud->lun;
+			scsi_id->sbp2_lun = ORB_SET_LUN(ud->lun);
 	}
 }
 
@@ -1666,8 +1604,9 @@
 	SBP2_DEBUG("sbp2_max_speed_and_size");
 
 	/* Initial setting comes from the hosts speed map */
-	scsi_id->speed_code = hi->host->speed_map[NODEID_TO_NODE(hi->host->node_id) * 64
-						  + NODEID_TO_NODE(scsi_id->ne->nodeid)];
+	scsi_id->speed_code =
+	    hi->host->speed_map[NODEID_TO_NODE(hi->host->node_id) * 64 +
+				NODEID_TO_NODE(scsi_id->ne->nodeid)];
 
 	/* Bump down our speed if the user requested it */
 	if (scsi_id->speed_code > max_speed) {
@@ -1678,15 +1617,16 @@
 
 	/* Payload size is the lesser of what our speed supports and what
 	 * our host supports.  */
-	scsi_id->max_payload_size = min(sbp2_speedto_max_payload[scsi_id->speed_code],
-					(u8)(hi->host->csr.max_rec - 1));
+	scsi_id->max_payload_size =
+	    min(sbp2_speedto_max_payload[scsi_id->speed_code],
+		(u8) (hi->host->csr.max_rec - 1));
 
 	HPSB_DEBUG("Node " NODE_BUS_FMT ": Max speed [%s] - Max payload [%u]",
 		   NODE_BUS_ARGS(hi->host, scsi_id->ne->nodeid),
 		   hpsb_speedto_str[scsi_id->speed_code],
-		   1 << ((u32)scsi_id->max_payload_size + 2));
+		   1 << ((u32) scsi_id->max_payload_size + 2));
 
-	return(0);
+	return 0;
 }
 
 /*
@@ -1721,30 +1661,187 @@
 	 */
 	scsi_id->last_orb = NULL;
 
-	return(0);
+	return 0;
+}
+
+static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
+				     struct sbp2scsi_host_info *hi,
+				     struct sbp2_command_info *command,
+				     unsigned int scsi_use_sg,
+				     struct scatterlist *sgpnt,
+				     u32 orb_direction,
+				     enum dma_data_direction dma_dir)
+{
+	command->dma_dir = dma_dir;
+	orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
+	orb->misc |= ORB_SET_DIRECTION(orb_direction);
+
+	/* Special case if only one element (and less than 64KB in size) */
+	if ((scsi_use_sg == 1) &&
+	    (sgpnt[0].length <= SBP2_MAX_SG_ELEMENT_LENGTH)) {
+
+		SBP2_DEBUG("Only one s/g element");
+		command->dma_size = sgpnt[0].length;
+		command->dma_type = CMD_DMA_PAGE;
+		command->cmd_dma = pci_map_page(hi->host->pdev,
+						sgpnt[0].page,
+						sgpnt[0].offset,
+						command->dma_size,
+						command->dma_dir);
+		SBP2_DMA_ALLOC("single page scatter element");
+
+		orb->data_descriptor_lo = command->cmd_dma;
+		orb->misc |= ORB_SET_DATA_SIZE(command->dma_size);
+
+	} else {
+		struct sbp2_unrestricted_page_table *sg_element =
+					&command->scatter_gather_element[0];
+		u32 sg_count, sg_len;
+		dma_addr_t sg_addr;
+		int i, count = pci_map_sg(hi->host->pdev, sgpnt, scsi_use_sg,
+					  dma_dir);
+
+		SBP2_DMA_ALLOC("scatter list");
+
+		command->dma_size = scsi_use_sg;
+		command->sge_buffer = sgpnt;
+
+		/* use page tables (s/g) */
+		orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
+		orb->data_descriptor_lo = command->sge_dma;
+
+		/*
+		 * Loop through and fill out our sbp-2 page tables
+		 * (and split up anything too large)
+		 */
+		for (i = 0, sg_count = 0 ; i < count; i++, sgpnt++) {
+			sg_len = sg_dma_len(sgpnt);
+			sg_addr = sg_dma_address(sgpnt);
+			while (sg_len) {
+				sg_element[sg_count].segment_base_lo = sg_addr;
+				if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
+					sg_element[sg_count].length_segment_base_hi =
+						PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
+					sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
+					sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
+				} else {
+					sg_element[sg_count].length_segment_base_hi =
+						PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
+					sg_len = 0;
+				}
+				sg_count++;
+			}
+		}
+
+		/* Number of page table (s/g) elements */
+		orb->misc |= ORB_SET_DATA_SIZE(sg_count);
+
+		sbp2util_packet_dump(sg_element,
+				     (sizeof(struct sbp2_unrestricted_page_table)) * sg_count,
+				     "sbp2 s/g list", command->sge_dma);
+
+		/* Byte swap page tables if necessary */
+		sbp2util_cpu_to_be32_buffer(sg_element,
+					    (sizeof(struct sbp2_unrestricted_page_table)) *
+					    sg_count);
+	}
+}
+
+static void sbp2_prep_command_orb_no_sg(struct sbp2_command_orb *orb,
+					struct sbp2scsi_host_info *hi,
+					struct sbp2_command_info *command,
+					struct scatterlist *sgpnt,
+					u32 orb_direction,
+					unsigned int scsi_request_bufflen,
+					void *scsi_request_buffer,
+					enum dma_data_direction dma_dir)
+{
+	command->dma_dir = dma_dir;
+	command->dma_size = scsi_request_bufflen;
+	command->dma_type = CMD_DMA_SINGLE;
+	command->cmd_dma = pci_map_single(hi->host->pdev, scsi_request_buffer,
+					  command->dma_size, command->dma_dir);
+	orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
+	orb->misc |= ORB_SET_DIRECTION(orb_direction);
+
+	SBP2_DMA_ALLOC("single bulk");
+
+	/*
+	 * Handle case where we get a command w/o s/g enabled (but
+	 * check for transfers larger than 64K)
+	 */
+	if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) {
+
+		orb->data_descriptor_lo = command->cmd_dma;
+		orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen);
+
+	} else {
+		struct sbp2_unrestricted_page_table *sg_element =
+			&command->scatter_gather_element[0];
+		u32 sg_count, sg_len;
+		dma_addr_t sg_addr;
+
+		/*
+		 * Need to turn this into page tables, since the
+		 * buffer is too large.
+		 */
+		orb->data_descriptor_lo = command->sge_dma;
+
+		/* Use page tables (s/g) */
+		orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
+
+		/*
+		 * fill out our sbp-2 page tables (and split up
+		 * the large buffer)
+		 */
+		sg_count = 0;
+		sg_len = scsi_request_bufflen;
+		sg_addr = command->cmd_dma;
+		while (sg_len) {
+			sg_element[sg_count].segment_base_lo = sg_addr;
+			if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
+				sg_element[sg_count].length_segment_base_hi =
+					PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
+				sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
+				sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
+			} else {
+				sg_element[sg_count].length_segment_base_hi =
+					PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
+				sg_len = 0;
+			}
+			sg_count++;
+		}
+
+		/* Number of page table (s/g) elements */
+		orb->misc |= ORB_SET_DATA_SIZE(sg_count);
+
+		sbp2util_packet_dump(sg_element,
+				     (sizeof(struct sbp2_unrestricted_page_table)) * sg_count,
+				     "sbp2 s/g list", command->sge_dma);
+
+		/* Byte swap page tables if necessary */
+		sbp2util_cpu_to_be32_buffer(sg_element,
+					    (sizeof(struct sbp2_unrestricted_page_table)) *
+					     sg_count);
+	}
 }
 
 /*
  * This function is called to create the actual command orb and s/g list
  * out of the scsi command itself.
  */
-static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
-				   struct sbp2_command_info *command,
-				   unchar *scsi_cmd,
-				   unsigned int scsi_use_sg,
-				   unsigned int scsi_request_bufflen,
-				   void *scsi_request_buffer,
-				   enum dma_data_direction dma_dir)
-
+static void sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
+				    struct sbp2_command_info *command,
+				    unchar *scsi_cmd,
+				    unsigned int scsi_use_sg,
+				    unsigned int scsi_request_bufflen,
+				    void *scsi_request_buffer,
+				    enum dma_data_direction dma_dir)
 {
 	struct sbp2scsi_host_info *hi = scsi_id->hi;
-	struct scatterlist *sgpnt = (struct scatterlist *) scsi_request_buffer;
+	struct scatterlist *sgpnt = (struct scatterlist *)scsi_request_buffer;
 	struct sbp2_command_orb *command_orb = &command->command_orb;
-	struct sbp2_unrestricted_page_table *scatter_gather_element =
-		&command->scatter_gather_element[0];
-	u32 sg_count, sg_len, orb_direction;
-	dma_addr_t sg_addr;
-	int i;
+	u32 orb_direction;
 
 	/*
 	 * Set-up our command ORB..
@@ -1758,222 +1855,42 @@
 	command_orb->next_ORB_lo = 0x0;
 	command_orb->misc = ORB_SET_MAX_PAYLOAD(scsi_id->max_payload_size);
 	command_orb->misc |= ORB_SET_SPEED(scsi_id->speed_code);
-	command_orb->misc |= ORB_SET_NOTIFY(1);		/* Notify us when complete */
+	command_orb->misc |= ORB_SET_NOTIFY(1);	/* Notify us when complete */
 
-	/*
-	 * Get the direction of the transfer. If the direction is unknown, then use our
-	 * goofy table as a back-up.
-	 */
-	switch (dma_dir) {
-		case DMA_NONE:
-			orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER;
-			break;
-		case DMA_TO_DEVICE:
-			orb_direction = ORB_DIRECTION_WRITE_TO_MEDIA;
-			break;
-		case DMA_FROM_DEVICE:
-			orb_direction = ORB_DIRECTION_READ_FROM_MEDIA;
-			break;
-		case DMA_BIDIRECTIONAL:
-		default:
-			SBP2_ERR("SCSI data transfer direction not specified. "
-				 "Update the SBP2 direction table in sbp2.h if "
-				 "necessary for your application");
-			__scsi_print_command(scsi_cmd);
-			orb_direction = sbp2scsi_direction_table[*scsi_cmd];
-			break;
+	if (dma_dir == DMA_NONE)
+		orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER;
+	else if (dma_dir == DMA_TO_DEVICE && scsi_request_bufflen)
+		orb_direction = ORB_DIRECTION_WRITE_TO_MEDIA;
+	else if (dma_dir == DMA_FROM_DEVICE && scsi_request_bufflen)
+		orb_direction = ORB_DIRECTION_READ_FROM_MEDIA;
+	else {
+		SBP2_WARN("Falling back to DMA_NONE");
+		orb_direction = ORB_DIRECTION_NO_DATA_TRANSFER;
 	}
 
-	/*
-	 * Set-up our pagetable stuff... unfortunately, this has become
-	 * messier than I'd like. Need to clean this up a bit.   ;-)
-	 */
+	/* Set-up our pagetable stuff */
 	if (orb_direction == ORB_DIRECTION_NO_DATA_TRANSFER) {
-
 		SBP2_DEBUG("No data transfer");
-
-		/*
-		 * Handle no data transfer
-		 */
 		command_orb->data_descriptor_hi = 0x0;
 		command_orb->data_descriptor_lo = 0x0;
 		command_orb->misc |= ORB_SET_DIRECTION(1);
-
 	} else if (scsi_use_sg) {
-
 		SBP2_DEBUG("Use scatter/gather");
-
-		/*
-		 * Special case if only one element (and less than 64KB in size)
-		 */
-		if ((scsi_use_sg == 1) && (sgpnt[0].length <= SBP2_MAX_SG_ELEMENT_LENGTH)) {
-
-			SBP2_DEBUG("Only one s/g element");
-			command->dma_dir = dma_dir;
-			command->dma_size = sgpnt[0].length;
-			command->dma_type = CMD_DMA_PAGE;
-			command->cmd_dma = pci_map_page(hi->host->pdev,
-							sgpnt[0].page,
-							sgpnt[0].offset,
-							command->dma_size,
-							command->dma_dir);
-			SBP2_DMA_ALLOC("single page scatter element");
-
-			command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
-			command_orb->data_descriptor_lo = command->cmd_dma;
-			command_orb->misc |= ORB_SET_DATA_SIZE(command->dma_size);
-			command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
-
-		} else {
-			int count = pci_map_sg(hi->host->pdev, sgpnt, scsi_use_sg, dma_dir);
-			SBP2_DMA_ALLOC("scatter list");
-
-			command->dma_size = scsi_use_sg;
-			command->dma_dir = dma_dir;
-			command->sge_buffer = sgpnt;
-
-			/* use page tables (s/g) */
-			command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
-			command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
-			command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
-			command_orb->data_descriptor_lo = command->sge_dma;
-
-			/*
-			 * Loop through and fill out our sbp-2 page tables
-			 * (and split up anything too large)
-			 */
-			for (i = 0, sg_count = 0 ; i < count; i++, sgpnt++) {
-				sg_len = sg_dma_len(sgpnt);
-				sg_addr = sg_dma_address(sgpnt);
-				while (sg_len) {
-					scatter_gather_element[sg_count].segment_base_lo = sg_addr;
-					if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
-						scatter_gather_element[sg_count].length_segment_base_hi =
-							PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
-						sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
-						sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
-					} else {
-						scatter_gather_element[sg_count].length_segment_base_hi =
-							PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
-						sg_len = 0;
-					}
-					sg_count++;
-				}
-			}
-
-			/* Number of page table (s/g) elements */
-			command_orb->misc |= ORB_SET_DATA_SIZE(sg_count);
-
-			sbp2util_packet_dump(scatter_gather_element,
-					     (sizeof(struct sbp2_unrestricted_page_table)) * sg_count,
-					     "sbp2 s/g list", command->sge_dma);
-
-			/*
-			 * Byte swap page tables if necessary
-			 */
-			sbp2util_cpu_to_be32_buffer(scatter_gather_element,
-						    (sizeof(struct sbp2_unrestricted_page_table)) *
-						    sg_count);
-
-		}
-
+		sbp2_prep_command_orb_sg(command_orb, hi, command, scsi_use_sg,
+					 sgpnt, orb_direction, dma_dir);
 	} else {
-
 		SBP2_DEBUG("No scatter/gather");
-
-		command->dma_dir = dma_dir;
-		command->dma_size = scsi_request_bufflen;
-		command->dma_type = CMD_DMA_SINGLE;
-		command->cmd_dma = pci_map_single (hi->host->pdev, scsi_request_buffer,
-						   command->dma_size,
-						   command->dma_dir);
-		SBP2_DMA_ALLOC("single bulk");
-
-		/*
-		 * Handle case where we get a command w/o s/g enabled (but
-		 * check for transfers larger than 64K)
-		 */
-		if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) {
-
-			command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
-			command_orb->data_descriptor_lo = command->cmd_dma;
-			command_orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen);
-			command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
-
-			/*
-			 * Sanity, in case our direction table is not
-			 * up-to-date
-			 */
-			if (!scsi_request_bufflen) {
-				command_orb->data_descriptor_hi = 0x0;
-				command_orb->data_descriptor_lo = 0x0;
-				command_orb->misc |= ORB_SET_DIRECTION(1);
-			}
-
-		} else {
-			/*
-			 * Need to turn this into page tables, since the
-			 * buffer is too large.
-			 */
-			command_orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
-			command_orb->data_descriptor_lo = command->sge_dma;
-
-			/* Use page tables (s/g) */
-			command_orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
-			command_orb->misc |= ORB_SET_DIRECTION(orb_direction);
-
-			/*
-			 * fill out our sbp-2 page tables (and split up
-			 * the large buffer)
-			 */
-			sg_count = 0;
-			sg_len = scsi_request_bufflen;
-			sg_addr = command->cmd_dma;
-			while (sg_len) {
-				scatter_gather_element[sg_count].segment_base_lo = sg_addr;
-				if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
-					scatter_gather_element[sg_count].length_segment_base_hi =
-						PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
-					sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
-					sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
-				} else {
-					scatter_gather_element[sg_count].length_segment_base_hi =
-						PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
-					sg_len = 0;
-				}
-				sg_count++;
-			}
-
-			/* Number of page table (s/g) elements */
-			command_orb->misc |= ORB_SET_DATA_SIZE(sg_count);
-
-			sbp2util_packet_dump(scatter_gather_element,
-					     (sizeof(struct sbp2_unrestricted_page_table)) * sg_count,
-					     "sbp2 s/g list", command->sge_dma);
-
-			/*
-			 * Byte swap page tables if necessary
-			 */
-			sbp2util_cpu_to_be32_buffer(scatter_gather_element,
-						    (sizeof(struct sbp2_unrestricted_page_table)) *
-						     sg_count);
-
-		}
-
+		sbp2_prep_command_orb_no_sg(command_orb, hi, command, sgpnt,
+					    orb_direction, scsi_request_bufflen,
+					    scsi_request_buffer, dma_dir);
 	}
 
-	/*
-	 * Byte swap command ORB if necessary
-	 */
+	/* Byte swap command ORB if necessary */
 	sbp2util_cpu_to_be32_buffer(command_orb, sizeof(struct sbp2_command_orb));
 
-	/*
-	 * Put our scsi command in the command ORB
-	 */
+	/* Put our scsi command in the command ORB */
 	memset(command_orb->cdb, 0, 12);
 	memcpy(command_orb->cdb, scsi_cmd, COMMAND_SIZE(*scsi_cmd));
-
-	return(0);
 }
 
 /*
@@ -1989,7 +1906,7 @@
 
 	outstanding_orb_incr;
 	SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x",
-			command_orb, global_outstanding_command_orbs);
+		       command_orb, global_outstanding_command_orbs);
 
 	pci_dma_sync_single_for_device(hi->host->pdev, command->command_orb_dma,
 				       sizeof(struct sbp2_command_orb),
@@ -2034,10 +1951,11 @@
 		 * both by the sbp2 device and us.
 		 */
 		scsi_id->last_orb->next_ORB_lo =
-			cpu_to_be32(command->command_orb_dma);
+		    cpu_to_be32(command->command_orb_dma);
 		/* Tells hardware that this pointer is valid */
 		scsi_id->last_orb->next_ORB_hi = 0x0;
-		pci_dma_sync_single_for_device(hi->host->pdev, scsi_id->last_orb_dma,
+		pci_dma_sync_single_for_device(hi->host->pdev,
+					       scsi_id->last_orb_dma,
 					       sizeof(struct sbp2_command_orb),
 					       PCI_DMA_BIDIRECTIONAL);
 
@@ -2051,14 +1969,14 @@
 
 		if (sbp2util_node_write_no_wait(ne, addr, &data, 4) < 0) {
 			SBP2_ERR("sbp2util_node_write_no_wait failed");
-			return(-EIO);
+			return -EIO;
 		}
 
 		scsi_id->last_orb = command_orb;
 		scsi_id->last_orb_dma = command->command_orb_dma;
 
 	}
-       	return(0);
+	return 0;
 }
 
 /*
@@ -2085,7 +2003,7 @@
 	 */
 	command = sbp2util_allocate_command_orb(scsi_id, SCpnt, done);
 	if (!command) {
-		return(-EIO);
+		return -EIO;
 	}
 
 	/*
@@ -2106,11 +2024,6 @@
 	sbp2_create_command_orb(scsi_id, command, cmd, SCpnt->use_sg,
 				request_bufflen, SCpnt->request_buffer,
 				SCpnt->sc_data_direction);
-	/*
-	 * Update our cdb if necessary (to handle sbp2 RBC command set
-	 * differences). This is where the command set hacks go!   =)
-	 */
-	sbp2_check_sbp2_command(scsi_id, command->command_orb.cdb);
 
 	sbp2util_packet_dump(&command->command_orb, sizeof(struct sbp2_command_orb),
 			     "sbp2 command orb", command->command_orb_dma);
@@ -2125,112 +2038,7 @@
 	 */
 	sbp2_link_orb_command(scsi_id, command);
 
-	return(0);
-}
-
-
-/*
- * This function deals with command set differences between Linux scsi
- * command set and sbp2 RBC command set.
- */
-static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd)
-{
-	unchar new_cmd[16];
-	u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
-
-	SBP2_DEBUG("sbp2_check_sbp2_command");
-
-	switch (*cmd) {
-
-		case READ_6:
-
-			if (sbp2_command_conversion_device_type(device_type)) {
-
-				SBP2_DEBUG("Convert READ_6 to READ_10");
-
-				/*
-				 * Need to turn read_6 into read_10
-				 */
-				new_cmd[0] = 0x28;
-				new_cmd[1] = (cmd[1] & 0xe0);
-				new_cmd[2] = 0x0;
-				new_cmd[3] = (cmd[1] & 0x1f);
-				new_cmd[4] = cmd[2];
-				new_cmd[5] = cmd[3];
-				new_cmd[6] = 0x0;
-				new_cmd[7] = 0x0;
-				new_cmd[8] = cmd[4];
-				new_cmd[9] = cmd[5];
-
-				memcpy(cmd, new_cmd, 10);
-
-			}
-
-			break;
-
-		case WRITE_6:
-
-			if (sbp2_command_conversion_device_type(device_type)) {
-
-				SBP2_DEBUG("Convert WRITE_6 to WRITE_10");
-
-				/*
-				 * Need to turn write_6 into write_10
-				 */
-				new_cmd[0] = 0x2a;
-				new_cmd[1] = (cmd[1] & 0xe0);
-				new_cmd[2] = 0x0;
-				new_cmd[3] = (cmd[1] & 0x1f);
-				new_cmd[4] = cmd[2];
-				new_cmd[5] = cmd[3];
-				new_cmd[6] = 0x0;
-				new_cmd[7] = 0x0;
-				new_cmd[8] = cmd[4];
-				new_cmd[9] = cmd[5];
-
-				memcpy(cmd, new_cmd, 10);
-
-			}
-
-			break;
-
-		case MODE_SENSE:
-
-			if (sbp2_command_conversion_device_type(device_type)) {
-
-				SBP2_DEBUG("Convert MODE_SENSE_6 to MODE_SENSE_10");
-
-				/*
-				 * Need to turn mode_sense_6 into mode_sense_10
-				 */
-				new_cmd[0] = 0x5a;
-				new_cmd[1] = cmd[1];
-				new_cmd[2] = cmd[2];
-				new_cmd[3] = 0x0;
-				new_cmd[4] = 0x0;
-				new_cmd[5] = 0x0;
-				new_cmd[6] = 0x0;
-				new_cmd[7] = 0x0;
-				new_cmd[8] = cmd[4];
-				new_cmd[9] = cmd[5];
-
-				memcpy(cmd, new_cmd, 10);
-
-			}
-
-			break;
-
-		case MODE_SELECT:
-
-			/*
-			 * TODO. Probably need to change mode select to 10 byte version
-			 */
-
-		default:
-			break;
-	}
-
-	return;
+	return 0;
 }
 
 /*
@@ -2260,80 +2068,40 @@
 	sense_data[14] = sbp2_status[20];
 	sense_data[15] = sbp2_status[21];
 
-	return(sbp2_status[8] & 0x3f);	/* return scsi status */
+	return sbp2_status[8] & 0x3f;	/* return scsi status */
 }
 
 /*
  * This function is called after a command is completed, in order to do any necessary SBP-2
  * response data translations for the SCSI stack
  */
-static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, 
+static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
 				     struct scsi_cmnd *SCpnt)
 {
 	u8 *scsi_buf = SCpnt->request_buffer;
-	u8 device_type = SBP2_DEVICE_TYPE (scsi_id->sbp2_device_type_and_lun);
 
 	SBP2_DEBUG("sbp2_check_sbp2_response");
 
 	switch (SCpnt->cmnd[0]) {
 
-		case INQUIRY:
+	case INQUIRY:
+		/*
+		 * Make sure data length is ok. Minimum length is 36 bytes
+		 */
+		if (scsi_buf[4] == 0) {
+			scsi_buf[4] = 36 - 5;
+		}
 
-			/*
-			 * If scsi_id->sbp2_device_type_and_lun is uninitialized, then fill 
-			 * this information in from the inquiry response data. Lun is set to zero.
-			 */
-			if (scsi_id->sbp2_device_type_and_lun == SBP2_DEVICE_TYPE_LUN_UNINITIALIZED) {
-				SBP2_DEBUG("Creating sbp2_device_type_and_lun from scsi inquiry data");
-				scsi_id->sbp2_device_type_and_lun = (scsi_buf[0] & 0x1f) << 16;
-			}
+		/*
+		 * Fix ansi revision and response data format
+		 */
+		scsi_buf[2] |= 2;
+		scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2;
 
-			/*
-			 * Make sure data length is ok. Minimum length is 36 bytes
-			 */
-			if (scsi_buf[4] == 0) {
-				scsi_buf[4] = 36 - 5;
-			}
+		break;
 
-			/*
-			 * Check for Simple Direct Access Device and change it to TYPE_DISK
-			 */
-			if ((scsi_buf[0] & 0x1f) == TYPE_RBC) {
-				SBP2_DEBUG("Changing TYPE_RBC to TYPE_DISK");
-				scsi_buf[0] &= 0xe0;
-			}
-
-			/*
-			 * Fix ansi revision and response data format
-			 */
-			scsi_buf[2] |= 2;
-			scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2;
-
-			break;
-
-		case MODE_SENSE:
-
-			if (sbp2_command_conversion_device_type(device_type)) {
-
-				SBP2_DEBUG("Modify mode sense response (10 byte version)");
-
-				scsi_buf[0] = scsi_buf[1];	/* Mode data length */
-				scsi_buf[1] = scsi_buf[2];	/* Medium type */
-				scsi_buf[2] = scsi_buf[3];	/* Device specific parameter */
-				scsi_buf[3] = scsi_buf[7];	/* Block descriptor length */
-				memcpy(scsi_buf + 4, scsi_buf + 8, scsi_buf[0]);
-			}
-
-			break;
-
-		case MODE_SELECT:
-
-			/*
-			 * TODO. Probably need to change mode select to 10 byte version
-			 */
-
-		default:
-			break;
+	default:
+		break;
 	}
 	return;
 }
@@ -2358,14 +2126,14 @@
 
 	if (!host) {
 		SBP2_ERR("host is NULL - this is bad!");
-		return(RCODE_ADDRESS_ERROR);
+		return RCODE_ADDRESS_ERROR;
 	}
 
 	hi = hpsb_get_hostinfo(&sbp2_highlevel, host);
 
 	if (!hi) {
 		SBP2_ERR("host info is NULL - this is bad!");
-		return(RCODE_ADDRESS_ERROR);
+		return RCODE_ADDRESS_ERROR;
 	}
 
 	/*
@@ -2382,7 +2150,7 @@
 
 	if (!scsi_id) {
 		SBP2_ERR("scsi_id is NULL - device is gone?");
-		return(RCODE_ADDRESS_ERROR);
+		return RCODE_ADDRESS_ERROR;
 	}
 
 	/*
@@ -2480,10 +2248,9 @@
 		SBP2_ORB_DEBUG("command orb completed");
 	}
 
-	return(RCODE_COMPLETE);
+	return RCODE_COMPLETE;
 }
 
-
 /**************************************
  * SCSI interface related section
  **************************************/
@@ -2541,6 +2308,16 @@
 	}
 
 	/*
+	 * Bidirectional commands are not yet implemented,
+	 * and unknown transfer direction not handled.
+	 */
+	if (SCpnt->sc_data_direction == DMA_BIDIRECTIONAL) {
+		SBP2_ERR("Cannot handle DMA_BIDIRECTIONAL - rejecting command");
+		result = DID_ERROR << 16;
+		goto done;
+	}
+
+	/*
 	 * Try and send our SCSI command
 	 */
 	if (sbp2_send_command(scsi_id, SCpnt, done)) {
@@ -2616,55 +2393,56 @@
 	 * complete the command, just let it get retried at the end of the
 	 * bus reset.
 	 */
-	if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
+	if (!hpsb_node_entry_valid(scsi_id->ne)
+	    && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
 		SBP2_ERR("Bus reset in progress - retry command later");
 		return;
 	}
- 
+
 	/*
 	 * Switch on scsi status
 	 */
 	switch (scsi_status) {
-		case SBP2_SCSI_STATUS_GOOD:
-			SCpnt->result = DID_OK;
-			break;
+	case SBP2_SCSI_STATUS_GOOD:
+		SCpnt->result = DID_OK;
+		break;
 
-		case SBP2_SCSI_STATUS_BUSY:
-			SBP2_ERR("SBP2_SCSI_STATUS_BUSY");
-			SCpnt->result = DID_BUS_BUSY << 16;
-			break;
+	case SBP2_SCSI_STATUS_BUSY:
+		SBP2_ERR("SBP2_SCSI_STATUS_BUSY");
+		SCpnt->result = DID_BUS_BUSY << 16;
+		break;
 
-		case SBP2_SCSI_STATUS_CHECK_CONDITION:
-			SBP2_DEBUG("SBP2_SCSI_STATUS_CHECK_CONDITION");
-			SCpnt->result = CHECK_CONDITION << 1;
+	case SBP2_SCSI_STATUS_CHECK_CONDITION:
+		SBP2_DEBUG("SBP2_SCSI_STATUS_CHECK_CONDITION");
+		SCpnt->result = CHECK_CONDITION << 1;
 
-			/*
-			 * Debug stuff
-			 */
+		/*
+		 * Debug stuff
+		 */
 #if CONFIG_IEEE1394_SBP2_DEBUG >= 1
-			scsi_print_command(SCpnt);
-			scsi_print_sense("bh", SCpnt);
+		scsi_print_command(SCpnt);
+		scsi_print_sense("bh", SCpnt);
 #endif
 
-			break;
+		break;
 
-		case SBP2_SCSI_STATUS_SELECTION_TIMEOUT:
-			SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
-			SCpnt->result = DID_NO_CONNECT << 16;
-			scsi_print_command(SCpnt);
-			break;
+	case SBP2_SCSI_STATUS_SELECTION_TIMEOUT:
+		SBP2_ERR("SBP2_SCSI_STATUS_SELECTION_TIMEOUT");
+		SCpnt->result = DID_NO_CONNECT << 16;
+		scsi_print_command(SCpnt);
+		break;
 
-		case SBP2_SCSI_STATUS_CONDITION_MET:
-		case SBP2_SCSI_STATUS_RESERVATION_CONFLICT:
-		case SBP2_SCSI_STATUS_COMMAND_TERMINATED:
-			SBP2_ERR("Bad SCSI status = %x", scsi_status);
-			SCpnt->result = DID_ERROR << 16;
-			scsi_print_command(SCpnt);
-			break;
+	case SBP2_SCSI_STATUS_CONDITION_MET:
+	case SBP2_SCSI_STATUS_RESERVATION_CONFLICT:
+	case SBP2_SCSI_STATUS_COMMAND_TERMINATED:
+		SBP2_ERR("Bad SCSI status = %x", scsi_status);
+		SCpnt->result = DID_ERROR << 16;
+		scsi_print_command(SCpnt);
+		break;
 
-		default:
-			SBP2_ERR("Unsupported SCSI status = %x", scsi_status);
-			SCpnt->result = DID_ERROR << 16;
+	default:
+		SBP2_ERR("Unsupported SCSI status = %x", scsi_status);
+		SCpnt->result = DID_ERROR << 16;
 	}
 
 	/*
@@ -2678,7 +2456,8 @@
 	 * If a bus reset is in progress and there was an error, complete
 	 * the command as busy so that it will get retried.
 	 */
-	if (!hpsb_node_entry_valid(scsi_id->ne) && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
+	if (!hpsb_node_entry_valid(scsi_id->ne)
+	    && (scsi_status != SBP2_SCSI_STATUS_GOOD)) {
 		SBP2_ERR("Completing command with busy (bus reset)");
 		SCpnt->result = DID_BUS_BUSY << 16;
 	}
@@ -2699,31 +2478,29 @@
 	/*
 	 * Tell scsi stack that we're done with this command
 	 */
-	done (SCpnt);
+	done(SCpnt);
 }
 
-
 static int sbp2scsi_slave_alloc(struct scsi_device *sdev)
 {
 	((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = sdev;
 	return 0;
 }
 
-
 static int sbp2scsi_slave_configure(struct scsi_device *sdev)
 {
 	blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
+	sdev->use_10_for_rw = 1;
+	sdev->use_10_for_ms = 1;
 	return 0;
 }
 
-
 static void sbp2scsi_slave_destroy(struct scsi_device *sdev)
 {
 	((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = NULL;
 	return;
 }
 
-
 /*
  * Called by scsi stack when something has really gone wrong.  Usually
  * called when a command has timed-out for some reason.
@@ -2769,7 +2546,7 @@
 		sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY);
 	}
 
-	return(SUCCESS);
+	return SUCCESS;
 }
 
 /*
@@ -2779,28 +2556,20 @@
 {
 	struct scsi_id_instance_data *scsi_id =
 		(struct scsi_id_instance_data *)SCpnt->device->host->hostdata[0];
-	unsigned long flags;
 
 	SBP2_ERR("reset requested");
 
-	spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
-
 	if (sbp2util_node_is_available(scsi_id)) {
 		SBP2_ERR("Generating sbp2 fetch agent reset");
 		sbp2_agent_reset(scsi_id, 0);
 	}
 
-	spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
-
 	return SUCCESS;
 }
 
-static const char *sbp2scsi_info (struct Scsi_Host *host)
-{
-        return "SCSI emulation for IEEE-1394 SBP-2 Devices";
-}
-
-static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
 {
 	struct scsi_device *sdev;
 	struct scsi_id_instance_data *scsi_id;
@@ -2812,10 +2581,7 @@
 	if (!(scsi_id = (struct scsi_id_instance_data *)sdev->host->hostdata[0]))
 		return 0;
 
-	if (scsi_id->sbp2_device_type_and_lun == SBP2_DEVICE_TYPE_LUN_UNINITIALIZED)
-		lun = 0;
-	else
-		lun = ORB_SET_LUN(scsi_id->sbp2_device_type_and_lun);
+	lun = ORB_SET_LUN(scsi_id->sbp2_lun);
 
 	return sprintf(buf, "%016Lx:%d:%d\n", (unsigned long long)scsi_id->ne->guid,
 		       scsi_id->ud->id, lun);
@@ -2837,12 +2603,9 @@
 	.module =			THIS_MODULE,
 	.name =				"SBP-2 IEEE-1394",
 	.proc_name =			SBP2_DEVICE_NAME,
-	.info =				sbp2scsi_info,
 	.queuecommand =			sbp2scsi_queuecommand,
 	.eh_abort_handler =		sbp2scsi_abort,
 	.eh_device_reset_handler =	sbp2scsi_reset,
-	.eh_bus_reset_handler =		sbp2scsi_reset,
-	.eh_host_reset_handler =	sbp2scsi_reset,
 	.slave_alloc =			sbp2scsi_slave_alloc,
 	.slave_configure =		sbp2scsi_slave_configure,
 	.slave_destroy =		sbp2scsi_slave_destroy,
@@ -2861,8 +2624,6 @@
 
 	SBP2_DEBUG("sbp2_module_init");
 
-	printk(KERN_INFO "sbp2: %s\n", version);
-
 	/* Module load debug option to force one command at a time (serializing I/O) */
 	if (serialize_io) {
 		SBP2_INFO("Driver forced to serialize I/O (serialize_io=1)");
@@ -2874,7 +2635,6 @@
 	/* Set max sectors (module load option). Default is 255 sectors. */
 	scsi_driver_template.max_sectors = max_sectors;
 
-
 	/* Register our high level driver with 1394 stack */
 	hpsb_register_highlevel(&sbp2_highlevel);
 
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index cd425be..900ea1d 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -119,8 +119,8 @@
 struct sbp2_reconnect_orb {
 	u32 reserved1;
 	u32 reserved2;
-        u32 reserved3;
-        u32 reserved4;
+	u32 reserved3;
+	u32 reserved4;
 	u32 login_ID_misc;
 	u32 reserved5;
 	u32 status_FIFO_hi;
@@ -130,8 +130,8 @@
 struct sbp2_logout_orb {
 	u32 reserved1;
 	u32 reserved2;
-        u32 reserved3;
-        u32 reserved4;
+	u32 reserved3;
+	u32 reserved4;
 	u32 login_ID_misc;
 	u32 reserved5;
 	u32 status_FIFO_hi;
@@ -188,7 +188,7 @@
 struct sbp2_status_block {
 	u32 ORB_offset_hi_misc;
 	u32 ORB_offset_lo;
-        u8 command_set_dependent[24];
+	u8 command_set_dependent[24];
 };
 
 /*
@@ -211,7 +211,7 @@
  * specified for write posting, where the ohci controller will
  * automatically send an ack_complete when the status is written by the
  * sbp2 device... saving a split transaction.   =)
- */ 
+ */
 #define SBP2_STATUS_FIFO_ADDRESS				0xfffe00000000ULL
 #define SBP2_STATUS_FIFO_ADDRESS_HI                             0xfffe
 #define SBP2_STATUS_FIFO_ADDRESS_LO                             0x0
@@ -229,9 +229,6 @@
 #define SBP2_DEVICE_TYPE_AND_LUN_KEY				0x14
 #define SBP2_FIRMWARE_REVISION_KEY				0x3c
 
-#define SBP2_DEVICE_TYPE(q)					(((q) >> 16) & 0x1f)
-#define SBP2_DEVICE_LUN(q)					((q) & 0xffff)
-
 #define SBP2_AGENT_STATE_OFFSET					0x00ULL
 #define SBP2_AGENT_RESET_OFFSET					0x04ULL
 #define SBP2_ORB_POINTER_OFFSET					0x08ULL
@@ -256,8 +253,6 @@
  */
 #define SBP2_128KB_BROKEN_FIRMWARE				0xa0b800
 
-#define SBP2_DEVICE_TYPE_LUN_UNINITIALIZED			0xffffffff
-
 /*
  * SCSI specific stuff
  */
@@ -265,45 +260,7 @@
 #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
 #define SBP2_MAX_UDS_PER_NODE		16	/* Maximum scsi devices per node */
 #define SBP2_MAX_SECTORS		255	/* Max sectors supported */
-
-/*
- * SCSI direction table...
- * (now used as a back-up in case the direction passed down from above is "unknown")
- *
- * DIN = IN data direction
- * DOU = OUT data direction
- * DNO = No data transfer
- * DUN = Unknown data direction
- *
- * Opcode 0xec (Teac specific "opc execute") possibly should be DNO,
- * but we'll change it when somebody reports a problem with this.
- */
-#define DIN				ORB_DIRECTION_READ_FROM_MEDIA
-#define DOU				ORB_DIRECTION_WRITE_TO_MEDIA
-#define DNO				ORB_DIRECTION_NO_DATA_TRANSFER
-#define DUN				DIN
-
-static unchar sbp2scsi_direction_table[0x100] = {
-	DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN,
-	DNO,DIN,DIN,DOU,DIN,DOU,DNO,DNO,DOU,DNO,DIN,DNO,DIN,DOU,DNO,DUN,
-	DIN,DUN,DIN,DIN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU,
-	DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU,
-	DOU,DOU,DIN,DIN,DIN,DNO,DIN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DNO,DUN,
-	DUN,DIN,DIN,DNO,DNO,DOU,DUN,DUN,DNO,DIN,DIN,DNO,DIN,DOU,DUN,DUN,
-	DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
-	DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
-	DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
-	DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
-	DUN,DNO,DOU,DOU,DIN,DNO,DNO,DNO,DIN,DNO,DOU,DUN,DNO,DIN,DOU,DOU,
-	DOU,DOU,DOU,DNO,DUN,DIN,DOU,DIN,DIN,DIN,DNO,DNO,DNO,DIN,DIN,DUN,
-	DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
-	DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,
-	DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN,
-	DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN
-};
-
-/* This should be safe */
-#define SBP2_MAX_CMDS		8
+#define SBP2_MAX_CMDS			8	/* This should be safe */
 
 /* This is the two dma types we use for cmd_dma below */
 enum cmd_dma_types {
@@ -338,10 +295,8 @@
 #define SBP2_BREAKAGE_128K_MAX_TRANSFER		0x1
 #define SBP2_BREAKAGE_INQUIRY_HACK		0x2
 
-
 struct sbp2scsi_host_info;
 
-
 /*
  * Information needed on a per scsi id basis (one for each sbp2 device)
  */
@@ -379,7 +334,7 @@
 	u32 sbp2_command_set_spec_id;
 	u32 sbp2_command_set;
 	u32 sbp2_unit_characteristics;
-	u32 sbp2_device_type_and_lun;
+	u32 sbp2_lun;
 	u32 sbp2_firmware_revision;
 
 	/*
@@ -411,7 +366,6 @@
 	u32 workarounds;
 };
 
-
 /* Sbp2 host data structure (one per IEEE1394 host) */
 struct sbp2scsi_host_info {
 	struct hpsb_host *host;		/* IEEE1394 host */
@@ -456,20 +410,12 @@
 static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
 				    quadlet_t *data, u64 addr, size_t length, u16 flags);
 static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait);
-static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
-				   struct sbp2_command_info *command,
-				   unchar *scsi_cmd,
-				   unsigned int scsi_use_sg,
-				   unsigned int scsi_request_bufflen,
-				   void *scsi_request_buffer,
-				   enum dma_data_direction dma_dir);
 static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
 				 struct sbp2_command_info *command);
 static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
 			     struct scsi_cmnd *SCpnt,
 			     void (*done)(struct scsi_cmnd *));
 static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data);
-static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd);
 static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id,
 				     struct scsi_cmnd *SCpnt);
 static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id,
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 23911da..608479b 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -19,12 +19,6 @@
  *
  * NOTES:
  *
- * jds -- add private data to file to keep track of iso contexts associated
- * with each open -- so release won't kill all iso transfers.
- * 
- * Damien Douxchamps: Fix failure when the number of DMA pages per frame is
- * one.
- * 
  * ioctl return codes:
  * EFAULT is only for invalid address for the argp
  * EINVAL for out of range values
@@ -34,12 +28,6 @@
  * ENOTTY for unsupported ioctl request
  *
  */
-
-/* Markus Tavenrath <speedygoo@speedygoo.de> :
-   - fixed checks for valid buffer-numbers in video1394_icotl
-   - changed the ways the dma prg's are used, now it's possible to use
-     even a single dma buffer
-*/
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -77,14 +65,6 @@
 
 #define ISO_CHANNELS 64
 
-#ifndef virt_to_page
-#define virt_to_page(x) MAP_NR(x)
-#endif
-
-#ifndef vmalloc_32
-#define vmalloc_32(x) vmalloc(x)
-#endif
-
 struct it_dma_prg {
 	struct dma_cmd begin;
 	quadlet_t data[4];
@@ -206,14 +186,12 @@
 	struct dma_iso_ctx *d;
 	int i;
 
-	d = kmalloc(sizeof(struct dma_iso_ctx), GFP_KERNEL);
-	if (d == NULL) {
+	d = kzalloc(sizeof(*d), GFP_KERNEL);
+	if (!d) {
 		PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma_iso_ctx");
 		return NULL;
 	}
 
-	memset(d, 0, sizeof *d);
-
 	d->ohci = ohci;
 	d->type = type;
 	d->channel = channel;
@@ -251,9 +229,8 @@
 	}
 	d->ctx = d->iso_tasklet.context;
 
-	d->prg_reg = kmalloc(d->num_desc * sizeof(struct dma_prog_region),
-			GFP_KERNEL);
-	if (d->prg_reg == NULL) {
+	d->prg_reg = kmalloc(d->num_desc * sizeof(*d->prg_reg), GFP_KERNEL);
+	if (!d->prg_reg) {
 		PRINT(KERN_ERR, ohci->host->id, "Failed to allocate ir prg regs");
 		free_dma_iso_ctx(d);
 		return NULL;
@@ -268,15 +245,14 @@
 		d->cmdPtr = OHCI1394_IsoRcvCommandPtr+32*d->ctx;
 		d->ctxMatch = OHCI1394_IsoRcvContextMatch+32*d->ctx;
 
-		d->ir_prg = kmalloc(d->num_desc * sizeof(struct dma_cmd *),
+		d->ir_prg = kzalloc(d->num_desc * sizeof(*d->ir_prg),
 				    GFP_KERNEL);
 
-		if (d->ir_prg == NULL) {
+		if (!d->ir_prg) {
 			PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma ir prg");
 			free_dma_iso_ctx(d);
 			return NULL;
 		}
-		memset(d->ir_prg, 0, d->num_desc * sizeof(struct dma_cmd *));
 
 		d->nb_cmd = d->buf_size / PAGE_SIZE + 1;
 		d->left_size = (d->frame_size % PAGE_SIZE) ?
@@ -297,16 +273,15 @@
 		d->ctrlClear = OHCI1394_IsoXmitContextControlClear+16*d->ctx;
 		d->cmdPtr = OHCI1394_IsoXmitCommandPtr+16*d->ctx;
 
-		d->it_prg = kmalloc(d->num_desc * sizeof(struct it_dma_prg *),
+		d->it_prg = kzalloc(d->num_desc * sizeof(*d->it_prg),
 				    GFP_KERNEL);
 
-		if (d->it_prg == NULL) {
+		if (!d->it_prg) {
 			PRINT(KERN_ERR, ohci->host->id,
 			      "Failed to allocate dma it prg");
 			free_dma_iso_ctx(d);
 			return NULL;
 		}
-		memset(d->it_prg, 0, d->num_desc*sizeof(struct it_dma_prg *));
 
 		d->packet_size = packet_size;
 
@@ -337,47 +312,24 @@
 		}
 	}
 
-	d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int),
-				   GFP_KERNEL);
-	d->buffer_prg_assignment = kmalloc(d->num_desc * sizeof(unsigned int),
-				   GFP_KERNEL);
-	d->buffer_time = kmalloc(d->num_desc * sizeof(struct timeval),
-				   GFP_KERNEL);
-	d->last_used_cmd = kmalloc(d->num_desc * sizeof(unsigned int),
-				   GFP_KERNEL);
-	d->next_buffer = kmalloc(d->num_desc * sizeof(int),
-				 GFP_KERNEL);
+	d->buffer_status =
+	    kzalloc(d->num_desc * sizeof(*d->buffer_status), GFP_KERNEL);
+	d->buffer_prg_assignment =
+	    kzalloc(d->num_desc * sizeof(*d->buffer_prg_assignment), GFP_KERNEL);
+	d->buffer_time =
+	    kzalloc(d->num_desc * sizeof(*d->buffer_time), GFP_KERNEL);
+	d->last_used_cmd =
+	    kzalloc(d->num_desc * sizeof(*d->last_used_cmd), GFP_KERNEL);
+	d->next_buffer =
+	    kzalloc(d->num_desc * sizeof(*d->next_buffer), GFP_KERNEL);
 
-	if (d->buffer_status == NULL) {
-		PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_status");
+	if (!d->buffer_status || !d->buffer_prg_assignment || !d->buffer_time ||
+	    !d->last_used_cmd || !d->next_buffer) {
+		PRINT(KERN_ERR, ohci->host->id,
+		      "Failed to allocate dma_iso_ctx member");
 		free_dma_iso_ctx(d);
 		return NULL;
 	}
-	if (d->buffer_prg_assignment == NULL) {
-		PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_prg_assignment");
-		free_dma_iso_ctx(d);
-		return NULL;
-	}
-	if (d->buffer_time == NULL) {
-		PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_time");
-		free_dma_iso_ctx(d);
-		return NULL;
-	}
-	if (d->last_used_cmd == NULL) {
-		PRINT(KERN_ERR, ohci->host->id, "Failed to allocate last_used_cmd");
-		free_dma_iso_ctx(d);
-		return NULL;
-	}
-	if (d->next_buffer == NULL) {
-		PRINT(KERN_ERR, ohci->host->id, "Failed to allocate next_buffer");
-		free_dma_iso_ctx(d);
-		return NULL;
-	}
-	memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int));
-	memset(d->buffer_prg_assignment, 0, d->num_desc * sizeof(unsigned int));
-	memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval));
-	memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int));
-	memset(d->next_buffer, -1, d->num_desc * sizeof(int));
 
         spin_lock_init(&d->lock);
 
@@ -539,7 +491,7 @@
 		if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) {
 			reset_ir_status(d, i);
 			d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY;
-			do_gettimeofday(&d->buffer_time[i]);
+			do_gettimeofday(&d->buffer_time[d->buffer_prg_assignment[i]]);
 		}
 	}
 
@@ -1046,7 +998,6 @@
 
 		/* set time of buffer */
 		v.filltime = d->buffer_time[v.buffer];
-//		printk("Buffer %d time %d\n", v.buffer, (d->buffer_time[v.buffer]).tv_usec);
 
 		/*
 		 * Look ahead to see how many more buffers have been received
@@ -1085,7 +1036,7 @@
 		}
 
 		if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) {
-			int buf_size = d->nb_cmd * sizeof(unsigned int);
+			int buf_size = d->nb_cmd * sizeof(*psizes);
 			struct video1394_queue_variable __user *p = argp;
 			unsigned int __user *qv;
 
@@ -1104,7 +1055,7 @@
 
 		spin_lock_irqsave(&d->lock,flags);
 
-		// last_buffer is last_prg
+		/* last_buffer is last_prg */
 		next_prg = (d->last_buffer + 1) % d->num_desc;
 		if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) {
 			PRINT(KERN_ERR, ohci->host->id,
@@ -1251,13 +1202,12 @@
         if (ohci == NULL)
                 return -EIO;
 
-	ctx = kmalloc(sizeof(struct file_ctx), GFP_KERNEL);
-	if (ctx == NULL)  {
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)  {
 		PRINT(KERN_ERR, ohci->host->id, "Cannot malloc file_ctx");
 		return -ENOMEM;
 	}
 
-	memset(ctx, 0, sizeof(struct file_ctx));
 	ctx->ohci = ohci;
 	INIT_LIST_HEAD(&ctx->context_list);
 	ctx->current_ctx = NULL;
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 08648b1a..1f1743c 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -434,24 +434,24 @@
 	kfree(dev);
 }
 
-static int ib_device_hotplug(struct class_device *cdev, char **envp,
-			     int num_envp, char *buf, int size)
+static int ib_device_uevent(struct class_device *cdev, char **envp,
+			    int num_envp, char *buf, int size)
 {
 	struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
 	int i = 0, len = 0;
 
-	if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len,
-				"NAME=%s", dev->name))
+	if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
+			   "NAME=%s", dev->name))
 		return -ENOMEM;
 
 	/*
-	 * It might be nice to pass the node GUID to hotplug, but
+	 * It might be nice to pass the node GUID with the event, but
 	 * right now the only way to get it is to query the device
 	 * provider, and this can crash during device removal because
 	 * we are will be running after driver removal has started.
 	 * We could add a node_guid field to struct ib_device, or we
-	 * could just let the hotplug script read the node GUID from
-	 * sysfs when devices are added.
+	 * could just let userspace read the node GUID from sysfs when
+	 * devices are added.
 	 */
 
 	envp[i] = NULL;
@@ -653,7 +653,7 @@
 static struct class ib_class = {
 	.name    = "infiniband",
 	.release = ib_device_release,
-	.hotplug = ib_device_hotplug,
+	.uevent = ib_device_uevent,
 };
 
 int ib_device_register_sysfs(struct ib_device *device)
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h
index 497ff79..795b379 100644
--- a/drivers/infiniband/hw/mthca/mthca_dev.h
+++ b/drivers/infiniband/hw/mthca/mthca_dev.h
@@ -43,6 +43,7 @@
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/timer.h>
 #include <asm/semaphore.h>
 
 #include "mthca_provider.h"
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 475d98f..780009c 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -47,6 +47,8 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 
+#include <net/dst.h>
+
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
 MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index ef3ee03..ed0c2ea 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -43,6 +43,8 @@
 #include <linux/delay.h>
 #include <linux/completion.h>
 
+#include <net/dst.h>
+
 #include "ipoib.h"
 
 #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index ee9fe22..dd488d3 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -39,6 +39,7 @@
 #include <linux/string.h>
 #include <linux/parser.h>
 #include <linux/random.h>
+#include <linux/jiffies.h>
 
 #include <asm/atomic.h>
 
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 9f2352bd..f7490a015 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -146,6 +146,7 @@
 }
 
 #ifdef CONFIG_COMPAT
+
 struct input_event_compat {
 	struct compat_timeval time;
 	__u16 type;
@@ -157,7 +158,7 @@
 #  define COMPAT_TEST test_thread_flag(TIF_IA32)
 #elif defined(CONFIG_IA64)
 #  define COMPAT_TEST IS_IA32_PROCESS(ia64_task_regs(current))
-#elif defined(CONFIG_ARCH_S390)
+#elif defined(CONFIG_S390)
 #  define COMPAT_TEST test_thread_flag(TIF_31BIT)
 #elif defined(CONFIG_MIPS)
 #  define COMPAT_TEST (current->thread.mflags & MF_32BIT_ADDR)
@@ -165,22 +166,80 @@
 #  define COMPAT_TEST test_thread_flag(TIF_32BIT)
 #endif
 
-static ssize_t evdev_write_compat(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
+static inline size_t evdev_event_size(void)
 {
-	struct evdev_list *list = file->private_data;
-	struct input_event_compat event;
-	int retval = 0;
+	return COMPAT_TEST ?
+		sizeof(struct input_event_compat) : sizeof(struct input_event);
+}
 
-	while (retval < count) {
-		if (copy_from_user(&event, buffer + retval, sizeof(struct input_event_compat)))
+static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
+{
+	if (COMPAT_TEST) {
+		struct input_event_compat compat_event;
+
+		if (copy_from_user(&compat_event, buffer, sizeof(struct input_event_compat)))
 			return -EFAULT;
-		input_event(list->evdev->handle.dev, event.type, event.code, event.value);
-		retval += sizeof(struct input_event_compat);
+
+		event->time.tv_sec = compat_event.time.tv_sec;
+		event->time.tv_usec = compat_event.time.tv_usec;
+		event->type = compat_event.type;
+		event->code = compat_event.code;
+		event->value = compat_event.value;
+
+	} else {
+		if (copy_from_user(event, buffer, sizeof(struct input_event)))
+			return -EFAULT;
 	}
 
-	return retval;
+	return 0;
 }
-#endif
+
+static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
+{
+	if (COMPAT_TEST) {
+		struct input_event_compat compat_event;
+
+		compat_event.time.tv_sec = event->time.tv_sec;
+		compat_event.time.tv_usec = event->time.tv_usec;
+		compat_event.type = event->type;
+		compat_event.code = event->code;
+		compat_event.value = event->value;
+
+		if (copy_to_user(buffer, &compat_event, sizeof(struct input_event_compat)))
+			return -EFAULT;
+
+	} else {
+		if (copy_to_user(buffer, event, sizeof(struct input_event)))
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
+#else
+
+static inline size_t evdev_event_size(void)
+{
+	return sizeof(struct input_event);
+}
+
+static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
+{
+	if (copy_from_user(event, buffer, sizeof(struct input_event)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
+{
+	if (copy_to_user(buffer, event, sizeof(struct input_event)))
+		return -EFAULT;
+
+	return 0;
+}
+
+#endif /* CONFIG_COMPAT */
 
 static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
 {
@@ -188,75 +247,26 @@
 	struct input_event event;
 	int retval = 0;
 
-	if (!list->evdev->exist) return -ENODEV;
-
-#ifdef CONFIG_COMPAT
-	if (COMPAT_TEST)
-		return evdev_write_compat(file, buffer, count, ppos);
-#endif
-
-	while (retval < count) {
-
-		if (copy_from_user(&event, buffer + retval, sizeof(struct input_event)))
-			return -EFAULT;
-		input_event(list->evdev->handle.dev, event.type, event.code, event.value);
-		retval += sizeof(struct input_event);
-	}
-
-	return retval;
-}
-
-#ifdef CONFIG_COMPAT
-static ssize_t evdev_read_compat(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
-{
-	struct evdev_list *list = file->private_data;
-	int retval;
-
-	if (count < sizeof(struct input_event_compat))
-		return -EINVAL;
-
-	if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK))
-		return -EAGAIN;
-
-	retval = wait_event_interruptible(list->evdev->wait,
-		list->head != list->tail || (!list->evdev->exist));
-
-	if (retval)
-		return retval;
-
 	if (!list->evdev->exist)
 		return -ENODEV;
 
-	while (list->head != list->tail && retval + sizeof(struct input_event_compat) <= count) {
-		struct input_event *event = (struct input_event *) list->buffer + list->tail;
-		struct input_event_compat event_compat;
-		event_compat.time.tv_sec = event->time.tv_sec;
-		event_compat.time.tv_usec = event->time.tv_usec;
-		event_compat.type = event->type;
-		event_compat.code = event->code;
-		event_compat.value = event->value;
+	while (retval < count) {
 
-		if (copy_to_user(buffer + retval, &event_compat,
-			sizeof(struct input_event_compat))) return -EFAULT;
-		list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
-		retval += sizeof(struct input_event_compat);
+		if (evdev_event_from_user(buffer + retval, &event))
+			return -EFAULT;
+		input_event(list->evdev->handle.dev, event.type, event.code, event.value);
+		retval += evdev_event_size();
 	}
 
 	return retval;
 }
-#endif
 
 static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
 {
 	struct evdev_list *list = file->private_data;
 	int retval;
 
-#ifdef CONFIG_COMPAT
-	if (COMPAT_TEST)
-		return evdev_read_compat(file, buffer, count, ppos);
-#endif
-
-	if (count < sizeof(struct input_event))
+	if (count < evdev_event_size())
 		return -EINVAL;
 
 	if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK))
@@ -271,11 +281,15 @@
 	if (!list->evdev->exist)
 		return -ENODEV;
 
-	while (list->head != list->tail && retval + sizeof(struct input_event) <= count) {
-		if (copy_to_user(buffer + retval, list->buffer + list->tail,
-			sizeof(struct input_event))) return -EFAULT;
+	while (list->head != list->tail && retval + evdev_event_size() <= count) {
+
+		struct input_event *event = (struct input_event *) list->buffer + list->tail;
+
+		if (evdev_event_to_user(buffer + retval, event))
+			return -EFAULT;
+
 		list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
-		retval += sizeof(struct input_event);
+		retval += evdev_event_size();
 	}
 
 	return retval;
@@ -290,17 +304,95 @@
 		(list->evdev->exist ? 0 : (POLLHUP | POLLERR));
 }
 
-static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+#ifdef CONFIG_COMPAT
+
+#define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
+#define NBITS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
+
+#ifdef __BIG_ENDIAN
+static int bits_to_user(unsigned long *bits, unsigned int maxbit,
+			unsigned int maxlen, void __user *p, int compat)
+{
+	int len, i;
+
+	if (compat) {
+		len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t);
+		if (len < maxlen)
+			len = maxlen;
+
+		for (i = 0; i < len / sizeof(compat_long_t); i++)
+			if (copy_to_user((compat_long_t __user *) p + i,
+					 (compat_long_t *) bits +
+						i + 1 - ((i % 2) << 1),
+					 sizeof(compat_long_t)))
+				return -EFAULT;
+	} else {
+		len = NBITS(maxbit) * sizeof(long);
+		if (len > maxlen)
+			len = maxlen;
+
+		if (copy_to_user(p, bits, len))
+			return -EFAULT;
+	}
+
+	return len;
+}
+#else
+static int bits_to_user(unsigned long *bits, unsigned int maxbit,
+			unsigned int maxlen, void __user *p, int compat)
+{
+	int len = compat ?
+			NBITS_COMPAT(maxbit) * sizeof(compat_long_t) :
+			NBITS(maxbit) * sizeof(long);
+
+	if (len > maxlen)
+		len = maxlen;
+
+	return copy_to_user(p, bits, len) ? -EFAULT : len;
+}
+#endif /* __BIG_ENDIAN */
+
+#else
+
+static int bits_to_user(unsigned long *bits, unsigned int maxbit,
+			unsigned int maxlen, void __user *p, int compat)
+{
+	int len = NBITS(maxbit) * sizeof(long);
+
+	if (len > maxlen)
+		len = maxlen;
+
+	return copy_to_user(p, bits, len) ? -EFAULT : len;
+}
+
+#endif /* CONFIG_COMPAT */
+
+static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
+{
+	int len;
+
+	if (!str)
+		return -ENOENT;
+
+	len = strlen(str) + 1;
+	if (len > maxlen)
+		len = maxlen;
+
+	return copy_to_user(p, str, len) ? -EFAULT : len;
+}
+
+static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
+				void __user *p, int compat_mode)
 {
 	struct evdev_list *list = file->private_data;
 	struct evdev *evdev = list->evdev;
 	struct input_dev *dev = evdev->handle.dev;
 	struct input_absinfo abs;
-	void __user *p = (void __user *)arg;
-	int __user *ip = (int __user *)arg;
+	int __user *ip = (int __user *)p;
 	int i, t, u, v;
 
-	if (!evdev->exist) return -ENODEV;
+	if (!evdev->exist)
+		return -ENODEV;
 
 	switch (cmd) {
 
@@ -308,26 +400,39 @@
 			return put_user(EV_VERSION, ip);
 
 		case EVIOCGID:
-			return copy_to_user(p, &dev->id, sizeof(struct input_id)) ? -EFAULT : 0;
+			if (copy_to_user(p, &dev->id, sizeof(struct input_id)))
+				return -EFAULT;
+
+			return 0;
 
 		case EVIOCGKEYCODE:
-			if (get_user(t, ip)) return -EFAULT;
-			if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL;
-			if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) return -EFAULT;
+			if (get_user(t, ip))
+				return -EFAULT;
+			if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
+				return -EINVAL;
+			if (put_user(INPUT_KEYCODE(dev, t), ip + 1))
+				return -EFAULT;
 			return 0;
 
 		case EVIOCSKEYCODE:
-			if (get_user(t, ip)) return -EFAULT;
-			if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) return -EINVAL;
-			if (get_user(v, ip + 1)) return -EFAULT;
-			if (v < 0 || v > KEY_MAX) return -EINVAL;
-			if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) return -EINVAL;
+			if (get_user(t, ip))
+				return -EFAULT;
+			if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
+				return -EINVAL;
+			if (get_user(v, ip + 1))
+				return -EFAULT;
+			if (v < 0 || v > KEY_MAX)
+				return -EINVAL;
+			if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8)))
+				return -EINVAL;
+
 			u = SET_INPUT_KEYCODE(dev, t, v);
 			clear_bit(u, dev->keybit);
 			set_bit(v, dev->keybit);
 			for (i = 0; i < dev->keycodemax; i++)
-				if (INPUT_KEYCODE(dev,i) == u)
+				if (INPUT_KEYCODE(dev, i) == u)
 					set_bit(u, dev->keybit);
+
 			return 0;
 
 		case EVIOCSFF:
@@ -338,17 +443,17 @@
 				if (copy_from_user(&effect, p, sizeof(effect)))
 					return -EFAULT;
 				err = dev->upload_effect(dev, &effect);
-				if (put_user(effect.id, &(((struct ff_effect __user *)arg)->id)))
+				if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
 					return -EFAULT;
 				return err;
-			}
-			else return -ENOSYS;
+			} else
+				return -ENOSYS;
 
 		case EVIOCRMFF:
-			if (dev->erase_effect) {
-				return dev->erase_effect(dev, (int)arg);
-			}
-			else return -ENOSYS;
+			if (!dev->erase_effect)
+				return -ENOSYS;
+
+			return dev->erase_effect(dev, (int)(unsigned long) p);
 
 		case EVIOCGEFFECTS:
 			if (put_user(dev->ff_effects_max, ip))
@@ -356,7 +461,7 @@
 			return 0;
 
 		case EVIOCGRAB:
-			if (arg) {
+			if (p) {
 				if (evdev->grab)
 					return -EBUSY;
 				if (input_grab_device(&evdev->handle))
@@ -395,62 +500,33 @@
 						case EV_SW:  bits = dev->swbit;  len = SW_MAX;  break;
 						default: return -EINVAL;
 					}
-					len = NBITS(len) * sizeof(long);
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, bits, len) ? -EFAULT : len;
+					return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
 				}
 
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
-					int len;
-					len = NBITS(KEY_MAX) * sizeof(long);
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->key, len) ? -EFAULT : len;
-				}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
+					return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
+							    p, compat_mode);
 
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
-					int len;
-					len = NBITS(LED_MAX) * sizeof(long);
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->led, len) ? -EFAULT : len;
-				}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
+					return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
+							    p, compat_mode);
 
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
-					int len;
-					len = NBITS(SND_MAX) * sizeof(long);
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
-				}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
+					return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
+							    p, compat_mode);
 
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0))) {
-					int len;
-					len = NBITS(SW_MAX) * sizeof(long);
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->sw, len) ? -EFAULT : len;
-				}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
+					return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
+							    p, compat_mode);
 
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
-					int len;
-					if (!dev->name) return -ENOENT;
-					len = strlen(dev->name) + 1;
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->name, len) ? -EFAULT : len;
-				}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
+					return str_to_user(dev->name, _IOC_SIZE(cmd), p);
 
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
-					int len;
-					if (!dev->phys) return -ENOENT;
-					len = strlen(dev->phys) + 1;
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
-				}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
+					return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
 
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
-					int len;
-					if (!dev->uniq) return -ENOENT;
-					len = strlen(dev->uniq) + 1;
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
-				}
+				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
+					return str_to_user(dev->uniq, _IOC_SIZE(cmd), p);
 
 				if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
 
@@ -492,158 +568,15 @@
 	return -EINVAL;
 }
 
+static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	return evdev_ioctl_handler(file, cmd, (void __user *)arg, 0);
+}
+
 #ifdef CONFIG_COMPAT
-
-#define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
-#define NBITS_COMPAT(x) ((((x)-1)/BITS_PER_LONG_COMPAT)+1)
-#define OFF_COMPAT(x)  ((x)%BITS_PER_LONG_COMPAT)
-#define BIT_COMPAT(x)  (1UL<<OFF_COMPAT(x))
-#define LONG_COMPAT(x) ((x)/BITS_PER_LONG_COMPAT)
-#define test_bit_compat(bit, array) ((array[LONG_COMPAT(bit)] >> OFF_COMPAT(bit)) & 1)
-
-#ifdef __BIG_ENDIAN
-#define bit_to_user(bit, max) \
-do { \
-	int i; \
-	int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
-	if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
-	for (i = 0; i < len / sizeof(compat_long_t); i++) \
-		if (copy_to_user((compat_long_t __user *) p + i, \
-				 (compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \
-				 sizeof(compat_long_t))) \
-			return -EFAULT; \
-	return len; \
-} while (0)
-#else
-#define bit_to_user(bit, max) \
-do { \
-	int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
-	if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
-	return copy_to_user(p, (bit), len) ? -EFAULT : len; \
-} while (0)
-#endif
-
 static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	struct evdev_list *list = file->private_data;
-	struct evdev *evdev = list->evdev;
-	struct input_dev *dev = evdev->handle.dev;
-	struct input_absinfo abs;
-	void __user *p = compat_ptr(arg);
-
-	if (!evdev->exist) return -ENODEV;
-
-	switch (cmd) {
-
-		case EVIOCGVERSION:
-		case EVIOCGID:
-		case EVIOCGKEYCODE:
-		case EVIOCSKEYCODE:
-		case EVIOCSFF:
-		case EVIOCRMFF:
-		case EVIOCGEFFECTS:
-		case EVIOCGRAB:
-			return evdev_ioctl(file, cmd, (unsigned long) p);
-
-		default:
-
-			if (_IOC_TYPE(cmd) != 'E')
-				return -EINVAL;
-
-			if (_IOC_DIR(cmd) == _IOC_READ) {
-
-				if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
-					long *bits;
-					int max;
-
-					switch (_IOC_NR(cmd) & EV_MAX) {
-						case      0: bits = dev->evbit;  max = EV_MAX;  break;
-						case EV_KEY: bits = dev->keybit; max = KEY_MAX; break;
-						case EV_REL: bits = dev->relbit; max = REL_MAX; break;
-						case EV_ABS: bits = dev->absbit; max = ABS_MAX; break;
-						case EV_MSC: bits = dev->mscbit; max = MSC_MAX; break;
-						case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
-						case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
-						case EV_FF:  bits = dev->ffbit;  max = FF_MAX;  break;
-						case EV_SW:  bits = dev->swbit;  max = SW_MAX;  break;
-						default: return -EINVAL;
-					}
-					bit_to_user(bits, max);
-				}
-
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
-					bit_to_user(dev->key, KEY_MAX);
-
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
-					bit_to_user(dev->led, LED_MAX);
-
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
-					bit_to_user(dev->snd, SND_MAX);
-
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
-					bit_to_user(dev->sw, SW_MAX);
-
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
-					int len;
-					if (!dev->name) return -ENOENT;
-					len = strlen(dev->name) + 1;
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->name, len) ? -EFAULT : len;
-				}
-
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
-					int len;
-					if (!dev->phys) return -ENOENT;
-					len = strlen(dev->phys) + 1;
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
-				}
-
-				if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
-					int len;
-					if (!dev->uniq) return -ENOENT;
-					len = strlen(dev->uniq) + 1;
-					if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
-					return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
-				}
-
-				if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
-
-					int t = _IOC_NR(cmd) & ABS_MAX;
-
-					abs.value = dev->abs[t];
-					abs.minimum = dev->absmin[t];
-					abs.maximum = dev->absmax[t];
-					abs.fuzz = dev->absfuzz[t];
-					abs.flat = dev->absflat[t];
-
-					if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
-						return -EFAULT;
-
-					return 0;
-				}
-			}
-
-			if (_IOC_DIR(cmd) == _IOC_WRITE) {
-
-				if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
-
-					int t = _IOC_NR(cmd) & ABS_MAX;
-
-					if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
-						return -EFAULT;
-
-					dev->abs[t] = abs.value;
-					dev->absmin[t] = abs.minimum;
-					dev->absmax[t] = abs.maximum;
-					dev->absfuzz[t] = abs.fuzz;
-					dev->absflat[t] = abs.flat;
-
-					return 0;
-				}
-			}
-	}
-	return -EINVAL;
+	return evdev_ioctl_handler(file, cmd, compat_ptr(arg), 1);
 }
 #endif
 
diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig
index 7524bd7..d279454 100644
--- a/drivers/input/gameport/Kconfig
+++ b/drivers/input/gameport/Kconfig
@@ -52,5 +52,12 @@
 config GAMEPORT_FM801
 	tristate "ForteMedia FM801 gameport support"
 	depends on PCI
+	help
+	  Say Y here if you have ForteMedia FM801 PCI audio controller
+	  (Abit AU10, Genius Sound Maker, HP Workstation zx2000,
+	  and others), and want to use its gameport.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called fm801-gp.
 
 endif
diff --git a/drivers/input/input.c b/drivers/input/input.c
index bdd2a7f..ef5824c 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -18,7 +18,6 @@
 #include <linux/random.h>
 #include <linux/major.h>
 #include <linux/proc_fs.h>
-#include <linux/kobject_uevent.h>
 #include <linux/interrupt.h>
 #include <linux/poll.h>
 #include <linux/device.h>
@@ -529,10 +528,49 @@
 INPUT_DEV_STRING_ATTR_SHOW(phys);
 INPUT_DEV_STRING_ATTR_SHOW(uniq);
 
+static int print_modalias_bits(char *buf, char prefix, unsigned long *arr,
+			       unsigned int min, unsigned int max)
+{
+	int len, i;
+
+	len = sprintf(buf, "%c", prefix);
+	for (i = min; i < max; i++)
+		if (arr[LONG(i)] & BIT(i))
+			len += sprintf(buf+len, "%X,", i);
+	return len;
+}
+
+static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
+{
+	struct input_dev *id = to_input_dev(dev);
+	ssize_t len = 0;
+
+	len += sprintf(buf+len, "input:b%04Xv%04Xp%04Xe%04X-",
+		       id->id.bustype,
+		       id->id.vendor,
+		       id->id.product,
+		       id->id.version);
+
+	len += print_modalias_bits(buf+len, 'e', id->evbit, 0, EV_MAX);
+	len += print_modalias_bits(buf+len, 'k', id->keybit,
+				   KEY_MIN_INTERESTING, KEY_MAX);
+	len += print_modalias_bits(buf+len, 'r', id->relbit, 0, REL_MAX);
+	len += print_modalias_bits(buf+len, 'a', id->absbit, 0, ABS_MAX);
+	len += print_modalias_bits(buf+len, 'm', id->mscbit, 0, MSC_MAX);
+	len += print_modalias_bits(buf+len, 'l', id->ledbit, 0, LED_MAX);
+	len += print_modalias_bits(buf+len, 's', id->sndbit, 0, SND_MAX);
+	len += print_modalias_bits(buf+len, 'f', id->ffbit, 0, FF_MAX);
+	len += print_modalias_bits(buf+len, 'w', id->swbit, 0, SW_MAX);
+	len += sprintf(buf+len, "\n");
+	return len;
+}
+static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
+
 static struct attribute *input_dev_attrs[] = {
 	&class_device_attr_name.attr,
 	&class_device_attr_phys.attr,
 	&class_device_attr_uniq.attr,
+	&class_device_attr_modalias.attr,
 	NULL
 };
 
@@ -611,10 +649,10 @@
 }
 
 /*
- * Input hotplugging interface - loading event handlers based on
+ * Input uevent interface - loading event handlers based on
  * device bitfields.
  */
-static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
+static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
 				    char *buffer, int buffer_size, int *cur_len,
 				    const char *name, unsigned long *bitmap, int max)
 {
@@ -639,7 +677,7 @@
 
 #define INPUT_ADD_HOTPLUG_VAR(fmt, val...)				\
 	do {								\
-		int err = add_hotplug_env_var(envp, num_envp, &i,	\
+		int err = add_uevent_var(envp, num_envp, &i,	\
 					buffer, buffer_size, &len,	\
 					fmt, val);			\
 		if (err)						\
@@ -648,15 +686,15 @@
 
 #define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max)				\
 	do {								\
-		int err = input_add_hotplug_bm_var(envp, num_envp, &i,	\
+		int err = input_add_uevent_bm_var(envp, num_envp, &i,	\
 					buffer, buffer_size, &len,	\
 					name, bm, max);			\
 		if (err)						\
 			return err;					\
 	} while (0)
 
-static int input_dev_hotplug(struct class_device *cdev, char **envp,
-			     int num_envp, char *buffer, int buffer_size)
+static int input_dev_uevent(struct class_device *cdev, char **envp,
+			    int num_envp, char *buffer, int buffer_size)
 {
 	struct input_dev *dev = to_input_dev(cdev);
 	int i = 0;
@@ -698,7 +736,7 @@
 struct class input_class = {
 	.name			= "input",
 	.release		= input_dev_release,
-	.hotplug		= input_dev_hotplug,
+	.uevent			= input_dev_uevent,
 };
 
 struct input_dev *input_allocate_device(void)
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 64b4a30..bc2fce6 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -235,7 +235,6 @@
 MODULE_DEVICE_TABLE (usb, iforce_usb_ids);
 
 struct usb_driver iforce_usb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"iforce",
 	.probe =	iforce_usb_probe,
 	.disconnect =	iforce_usb_disconnect,
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
index 99a642d..1849b17 100644
--- a/drivers/input/joystick/warrior.c
+++ b/drivers/input/joystick/warrior.c
@@ -172,7 +172,7 @@
 	input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8);
 	input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0);
 	input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
-	input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
+	input_set_abs_params(input_dev, ABS_HAT0Y, -1, 1, 0, 0);
 
 	serio_set_drvdata(serio, warrior);
 
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index a0256f8..ffacf6e 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -321,7 +321,7 @@
 	switch (code) {
 		case ATKBD_RET_BAT:
 			atkbd->enabled = 0;
-			serio_rescan(atkbd->ps2dev.serio);
+			serio_reconnect(atkbd->ps2dev.serio);
 			goto out;
 		case ATKBD_RET_EMUL0:
 			atkbd->emul = 1;
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index 64672d4..e301ee4 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -19,7 +19,6 @@
 #include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/irq.h>
 
 #include <asm/arch/corgi.h>
 #include <asm/arch/hardware.h>
@@ -343,10 +342,9 @@
 	for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) {
 		pxa_gpio_mode(CORGI_GPIO_KEY_SENSE(i) | GPIO_IN);
 		if (request_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd_interrupt,
-						SA_INTERRUPT, "corgikbd", corgikbd))
+				SA_INTERRUPT | SA_TRIGGER_RISING,
+				"corgikbd", corgikbd))
 			printk(KERN_WARNING "corgikbd: Can't get IRQ: %d!\n", i);
-		else
-			set_irq_type(CORGI_IRQ_GPIO_KEY_SENSE(i),IRQT_RISING);
 	}
 
 	/* Set Strobe lines as outputs - set high */
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 6a15fe3..83999d5 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -19,7 +19,6 @@
 #include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <asm/irq.h>
 
 #include <asm/arch/spitz.h>
 #include <asm/arch/hardware.h>
@@ -407,10 +406,9 @@
 	for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) {
 		pxa_gpio_mode(spitz_senses[i] | GPIO_IN);
 		if (request_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd_interrupt,
-						SA_INTERRUPT, "Spitzkbd Sense", spitzkbd))
+				SA_INTERRUPT|SA_TRIGGER_RISING,
+				"Spitzkbd Sense", spitzkbd))
 			printk(KERN_WARNING "spitzkbd: Can't get Sense IRQ: %d!\n", i);
-		else
-			set_irq_type(IRQ_GPIO(spitz_senses[i]),IRQT_RISING);
 	}
 
 	/* Set Strobe lines as outputs - set high */
@@ -422,15 +420,18 @@
 	pxa_gpio_mode(SPITZ_GPIO_SWA | GPIO_IN);
 	pxa_gpio_mode(SPITZ_GPIO_SWB | GPIO_IN);
 
-	request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd Sync", spitzkbd);
-	request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd PwrOn", spitzkbd);
-	request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWA", spitzkbd);
-	request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWB", spitzkbd);
-
-	set_irq_type(SPITZ_IRQ_GPIO_SYNC, IRQT_BOTHEDGE);
-	set_irq_type(SPITZ_IRQ_GPIO_ON_KEY, IRQT_BOTHEDGE);
-	set_irq_type(SPITZ_IRQ_GPIO_SWA, IRQT_BOTHEDGE);
-	set_irq_type(SPITZ_IRQ_GPIO_SWB, IRQT_BOTHEDGE);
+	request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt,
+		    SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+		    "Spitzkbd Sync", spitzkbd);
+	request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt,
+		    SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+		    "Spitzkbd PwrOn", spitzkbd);
+	request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr,
+		    SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+		    "Spitzkbd SWA", spitzkbd);
+	request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr,
+		    SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING,
+		    "Spitzkbd SWB", spitzkbd);
 
 	printk(KERN_INFO "input: Spitz Keyboard Registered\n");
 
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 07813fc..e08dbe0 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -26,7 +26,7 @@
 
 config INPUT_SPARCSPKR
 	tristate "SPARC Speaker support"
-	depends on PCI && (SPARC32 || SPARC64)
+	depends on PCI && SPARC
 	help
 	  Say Y here if you want the standard Speaker on Sparc PCI systems
 	  to be used for bells and whistles.
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c
index 1cd7657..1be9639 100644
--- a/drivers/input/misc/hp_sdc_rtc.c
+++ b/drivers/input/misc/hp_sdc_rtc.c
@@ -60,8 +60,6 @@
 
 static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait);
 
-static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin);
-
 static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
 			       size_t count, loff_t *ppos);
 
@@ -387,11 +385,6 @@
 	return 0;
 }
 
-static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin)
-{
-        return -ESPIPE;
-}
-
 static ssize_t hp_sdc_rtc_read(struct file *file, char *buf,
 			       size_t count, loff_t *ppos) {
 	ssize_t retval;
@@ -679,7 +672,7 @@
 
 static struct file_operations hp_sdc_rtc_fops = {
         .owner =	THIS_MODULE,
-        .llseek =	hp_sdc_rtc_llseek,
+        .llseek =	no_llseek,
         .read =		hp_sdc_rtc_read,
         .poll =		hp_sdc_rtc_poll,
         .ioctl =	hp_sdc_rtc_ioctl,
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c
index 04489ad..8d6c383 100644
--- a/drivers/input/misc/m68kspkr.c
+++ b/drivers/input/misc/m68kspkr.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/input.h>
+#include <linux/platform_device.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
 
@@ -24,7 +25,7 @@
 MODULE_DESCRIPTION("m68k beeper driver");
 MODULE_LICENSE("GPL");
 
-static struct input_dev *m68kspkr_dev;
+static struct platform_device *m68kspkr_platform_device;
 
 static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
@@ -47,36 +48,103 @@
 	return 0;
 }
 
-static int __init m68kspkr_init(void)
+static int __devinit m68kspkr_probe(struct platform_device *dev)
 {
-        if (!mach_beep) {
-		printk(KERN_INFO "m68kspkr: no lowlevel beep support\n");
-		return -ENODEV;
-        }
+	struct input_dev *input_dev;
+	int err;
 
-	m68kspkr_dev = input_allocate_device();
-	if (!m68kspkr_dev)
+	input_dev = input_allocate_device();
+	if (!input_dev)
 		return -ENOMEM;
 
-	m68kspkr_dev->name = "m68k beeper";
-	m68kspkr_dev->phys = "m68k/generic";
-	m68kspkr_dev->id.bustype = BUS_HOST;
-	m68kspkr_dev->id.vendor = 0x001f;
-	m68kspkr_dev->id.product = 0x0001;
-	m68kspkr_dev->id.version = 0x0100;
+	input_dev->name = "m68k beeper";
+	input_dev->phys = "m68k/generic";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->id.vendor  = 0x001f;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &dev->dev;
 
-	m68kspkr_dev->evbit[0] = BIT(EV_SND);
-	m68kspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
-	m68kspkr_dev->event = m68kspkr_event;
+	input_dev->evbit[0] = BIT(EV_SND);
+	input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	input_dev->event = m68kspkr_event;
 
-	input_register_device(m68kspkr_dev);
+	err = input_register_device(input_dev);
+	if (err) {
+		input_free_device(input_dev);
+		return err;
+	}
+
+	platform_set_drvdata(dev, input_dev);
 
 	return 0;
 }
 
+static int __devexit m68kspkr_remove(struct platform_device *dev)
+{
+	struct input_dev *input_dev = platform_get_drvdata(dev);
+
+	input_unregister_device(input_dev);
+	platform_set_drvdata(dev, NULL);
+	/* turn off the speaker */
+	m68kspkr_event(NULL, EV_SND, SND_BELL, 0);
+
+	return 0;
+}
+
+static void m68kspkr_shutdown(struct platform_device *dev)
+{
+	/* turn off the speaker */
+	m68kspkr_event(NULL, EV_SND, SND_BELL, 0);
+}
+
+static struct platform_driver m68kspkr_platform_driver = {
+	.driver		= {
+		.name	= "m68kspkr",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= m68kspkr_probe,
+	.remove		= __devexit_p(m68kspkr_remove),
+	.shutdown	= m68kspkr_shutdown,
+};
+
+static int __init m68kspkr_init(void)
+{
+	int err;
+
+	if (!mach_beep) {
+		printk(KERN_INFO "m68kspkr: no lowlevel beep support\n");
+		return -ENODEV;
+        }
+
+	err = platform_driver_register(&m68kspkr_platform_driver);
+	if (err)
+		return err;
+
+	m68kspkr_platform_device = platform_device_alloc("m68kspkr", -1);
+	if (!m68kspkr_platform_device) {
+		err = -ENOMEM;
+		goto err_unregister_driver;
+	}
+
+	err = platform_device_add(m68kspkr_platform_device);
+	if (err)
+		goto err_free_device;
+
+	return 0;
+
+ err_free_device:
+	platform_device_put(m68kspkr_platform_device);
+ err_unregister_driver:
+	platform_driver_unregister(&m68kspkr_platform_driver);
+
+	return err;
+}
+
 static void __exit m68kspkr_exit(void)
 {
-        input_unregister_device(m68kspkr_dev);
+	platform_device_unregister(m68kspkr_platform_device);
+	platform_driver_unregister(&m68kspkr_platform_driver);
 }
 
 module_init(m68kspkr_init);
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index 68ac97f..1ef477f 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/input.h>
+#include <linux/platform_device.h>
 #include <asm/8253pit.h>
 #include <asm/io.h>
 
@@ -23,8 +24,7 @@
 MODULE_DESCRIPTION("PC Speaker beeper driver");
 MODULE_LICENSE("GPL");
 
-static struct input_dev *pcspkr_dev;
-
+static struct platform_device *pcspkr_platform_device;
 static DEFINE_SPINLOCK(i8253_beep_lock);
 
 static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -64,8 +64,11 @@
 	return 0;
 }
 
-static int __init pcspkr_init(void)
+static int __devinit pcspkr_probe(struct platform_device *dev)
 {
+	struct input_dev *pcspkr_dev;
+	int err;
+
 	pcspkr_dev = input_allocate_device();
 	if (!pcspkr_dev)
 		return -ENOMEM;
@@ -76,21 +79,92 @@
 	pcspkr_dev->id.vendor = 0x001f;
 	pcspkr_dev->id.product = 0x0001;
 	pcspkr_dev->id.version = 0x0100;
+	pcspkr_dev->cdev.dev = &dev->dev;
 
 	pcspkr_dev->evbit[0] = BIT(EV_SND);
 	pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
 	pcspkr_dev->event = pcspkr_event;
 
-	input_register_device(pcspkr_dev);
+	err = input_register_device(pcspkr_dev);
+	if (err) {
+		input_free_device(pcspkr_dev);
+		return err;
+	}
+
+	platform_set_drvdata(dev, pcspkr_dev);
 
 	return 0;
 }
 
-static void __exit pcspkr_exit(void)
+static int __devexit pcspkr_remove(struct platform_device *dev)
 {
-        input_unregister_device(pcspkr_dev);
+	struct input_dev *pcspkr_dev = platform_get_drvdata(dev);
+
+	input_unregister_device(pcspkr_dev);
+	platform_set_drvdata(dev, NULL);
 	/* turn off the speaker */
 	pcspkr_event(NULL, EV_SND, SND_BELL, 0);
+
+	return 0;
+}
+
+static int pcspkr_suspend(struct platform_device *dev, pm_message_t state)
+{
+	pcspkr_event(NULL, EV_SND, SND_BELL, 0);
+
+	return 0;
+}
+
+static void pcspkr_shutdown(struct platform_device *dev)
+{
+	/* turn off the speaker */
+	pcspkr_event(NULL, EV_SND, SND_BELL, 0);
+}
+
+static struct platform_driver pcspkr_platform_driver = {
+	.driver		= {
+		.name	= "pcspkr",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pcspkr_probe,
+	.remove		= __devexit_p(pcspkr_remove),
+	.suspend	= pcspkr_suspend,
+	.shutdown	= pcspkr_shutdown,
+};
+
+
+static int __init pcspkr_init(void)
+{
+	int err;
+
+	err = platform_driver_register(&pcspkr_platform_driver);
+	if (err)
+		return err;
+
+	pcspkr_platform_device = platform_device_alloc("pcspkr", -1);
+	if (!pcspkr_platform_device) {
+		err = -ENOMEM;
+		goto err_unregister_driver;
+	}
+
+	err = platform_device_add(pcspkr_platform_device);
+	if (err)
+		goto err_free_device;
+
+	return 0;
+
+ err_free_device:
+	platform_device_put(pcspkr_platform_device);
+ err_unregister_driver:
+	platform_driver_unregister(&pcspkr_platform_driver);
+
+	return err;
+}
+
+static void __exit pcspkr_exit(void)
+{
+	platform_device_unregister(pcspkr_platform_device);
+	platform_driver_unregister(&pcspkr_platform_driver);
 }
 
 module_init(pcspkr_init);
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index 29d97b1..f0fd2c4 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/input.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/ebus.h>
@@ -20,22 +21,10 @@
 MODULE_DESCRIPTION("Sparc Speaker beeper driver");
 MODULE_LICENSE("GPL");
 
+const char *beep_name;
 static unsigned long beep_iobase;
-static struct input_dev *sparcspkr_dev;
-
-DEFINE_SPINLOCK(beep_lock);
-
-static void __init init_sparcspkr_struct(void)
-{
-	sparcspkr_dev->evbit[0] = BIT(EV_SND);
-	sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
-
-	sparcspkr_dev->phys = "sparc/input0";
-	sparcspkr_dev->id.bustype = BUS_ISA;
-	sparcspkr_dev->id.vendor = 0x001f;
-	sparcspkr_dev->id.product = 0x0001;
-	sparcspkr_dev->id.version = 0x0100;
-}
+static int (*beep_event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
+static DEFINE_SPINLOCK(beep_lock);
 
 static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
@@ -59,39 +48,16 @@
 	/* EBUS speaker only has on/off state, the frequency does not
 	 * appear to be programmable.
 	 */
-	if (count) {
-		if (beep_iobase & 0x2UL)
-			outb(1, beep_iobase);
-		else
-			outl(1, beep_iobase);
-	} else {
-		if (beep_iobase & 0x2UL)
-			outb(0, beep_iobase);
-		else
-			outl(0, beep_iobase);
-	}
+	if (beep_iobase & 0x2UL)
+		outb(!!count, beep_iobase);
+	else
+		outl(!!count, beep_iobase);
 
 	spin_unlock_irqrestore(&beep_lock, flags);
 
 	return 0;
 }
 
-static int __init init_ebus_beep(struct linux_ebus_device *edev)
-{
-	beep_iobase = edev->resource[0].start;
-
-	sparcspkr_dev = input_allocate_device();
-	if (!sparcspkr_dev)
-		return -ENOMEM;
-
-	sparcspkr_dev->name = "Sparc EBUS Speaker";
-	sparcspkr_dev->event = ebus_spkr_event;
-
-	input_register_device(sparcspkr_dev);
-
-	return 0;
-}
-
 #ifdef CONFIG_SPARC64
 static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
@@ -129,30 +95,103 @@
 
 	return 0;
 }
+#endif
 
-static int __init init_isa_beep(struct sparc_isa_device *isa_dev)
+static int __devinit sparcspkr_probe(struct platform_device *dev)
 {
-	beep_iobase = isa_dev->resource.start;
+	struct input_dev *input_dev;
+	int error;
 
-	sparcspkr_dev = input_allocate_device();
-	if (!sparcspkr_dev)
+	input_dev = input_allocate_device();
+	if (!input_dev)
 		return -ENOMEM;
 
-	init_sparcspkr_struct();
+	input_dev->name = beep_name;
+	input_dev->phys = "sparc/input0";
+	input_dev->id.bustype = BUS_ISA;
+	input_dev->id.vendor = 0x001f;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &dev->dev;
 
-	sparcspkr_dev->name = "Sparc ISA Speaker";
-	sparcspkr_dev->event = isa_spkr_event;
+	input_dev->evbit[0] = BIT(EV_SND);
+	input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
 
-	input_register_device(sparcspkr_dev);
+	input_dev->event = beep_event;
+
+	error = input_register_device(input_dev);
+	if (error) {
+		input_free_device(input_dev);
+		return error;
+	}
+
+	platform_set_drvdata(dev, input_dev);
 
 	return 0;
 }
-#endif
+
+static int __devexit sparcspkr_remove(struct platform_device *dev)
+{
+	struct input_dev *input_dev = platform_get_drvdata(dev);
+
+	input_unregister_device(input_dev);
+	platform_set_drvdata(dev, NULL);
+	/* turn off the speaker */
+	beep_event(NULL, EV_SND, SND_BELL, 0);
+
+	return 0;
+}
+
+static void sparcspkr_shutdown(struct platform_device *dev)
+{
+	/* turn off the speaker */
+	beep_event(NULL, EV_SND, SND_BELL, 0);
+}
+
+static struct platform_driver sparcspkr_platform_driver = {
+	.driver		= {
+		.name	= "sparcspkr",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sparcspkr_probe,
+	.remove		= __devexit_p(sparcspkr_remove),
+	.shutdown	= sparcspkr_shutdown,
+};
+
+static struct platform_device *sparcspkr_platform_device;
+
+static int __init sparcspkr_drv_init(void)
+{
+	int error;
+
+	error = platform_driver_register(&sparcspkr_platform_driver);
+	if (error)
+		return error;
+
+	sparcspkr_platform_device = platform_device_alloc("sparcspkr", -1);
+	if (!sparcspkr_platform_device) {
+		error = -ENOMEM;
+		goto err_unregister_driver;
+	}
+
+	error = platform_device_add(sparcspkr_platform_device);
+	if (error)
+		goto err_free_device;
+
+	return 0;
+
+ err_free_device:
+	platform_device_put(sparcspkr_platform_device);
+ err_unregister_driver:
+	platform_driver_unregister(&sparcspkr_platform_driver);
+
+	return error;
+}
 
 static int __init sparcspkr_init(void)
 {
 	struct linux_ebus *ebus;
-	struct linux_ebus_device *edev = NULL;
+	struct linux_ebus_device *edev;
 #ifdef CONFIG_SPARC64
 	struct sparc_isa_bridge *isa_br;
 	struct sparc_isa_device *isa_dev;
@@ -160,8 +199,12 @@
 
 	for_each_ebus(ebus) {
 		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "beep"))
-				return init_ebus_beep(edev);
+			if (!strcmp(edev->prom_name, "beep")) {
+				beep_name = "Sparc EBUS Speaker";
+				beep_event = ebus_spkr_event;
+				beep_iobase = edev->resource[0].start;
+				return sparcspkr_drv_init();
+			}
 		}
 	}
 #ifdef CONFIG_SPARC64
@@ -170,8 +213,12 @@
 			/* A hack, the beep device's base lives in
 			 * the DMA isa node.
 			 */
-			if (!strcmp(isa_dev->prom_name, "dma"))
-				return init_isa_beep(isa_dev);
+			if (!strcmp(isa_dev->prom_name, "dma")) {
+				beep_name = "Sparc ISA Speaker";
+				beep_event = isa_spkr_event,
+				beep_iobase = isa_dev->resource.start;
+				return sparcspkr_drv_init();
+			}
 		}
 	}
 #endif
@@ -181,7 +228,8 @@
 
 static void __exit sparcspkr_exit(void)
 {
-	input_unregister_device(sparcspkr_dev);
+	platform_device_unregister(sparcspkr_platform_device);
+	platform_driver_unregister(&sparcspkr_platform_driver);
 }
 
 module_init(sparcspkr_init);
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 49d0416..a05b855 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -174,7 +174,7 @@
 	return regs.eax;
 }
 
-static void __init bios_attach(void)
+static void __devinit bios_attach(void)
 {
 	struct regs regs;
 
@@ -194,7 +194,7 @@
 	call_bios(&regs);
 }
 
-static u8 __init bios_get_cmos_address(void)
+static u8 __devinit bios_get_cmos_address(void)
 {
 	struct regs regs;
 
@@ -206,7 +206,7 @@
 	return regs.ecx;
 }
 
-static u16 __init bios_get_default_setting(u8 subsys)
+static u16 __devinit bios_get_default_setting(u8 subsys)
 {
 	struct regs regs;
 
@@ -296,6 +296,16 @@
 	{ KE_END, 0 }
 };
 
+static struct key_entry keymap_acer_travelmate_240[] = {
+	{ KE_KEY, 0x31, KEY_MAIL },
+	{ KE_KEY, 0x36, KEY_WWW },
+	{ KE_KEY, 0x11, KEY_PROG1 },
+	{ KE_KEY, 0x12, KEY_PROG2 },
+	{ KE_BLUETOOTH, 0x44, 0 },
+	{ KE_WIFI, 0x30, 0 },
+	{ KE_END, 0 }
+};
+
 /*
  * If your machine is not here (which is currently rather likely), please send
  * a list of buttons and their key codes (reported when loading this module
@@ -320,7 +330,16 @@
 		},
 		.driver_data = keymap_acer_aspire_1500
 	},
-	{ 0, }
+	{
+		.callback = dmi_matched,
+		.ident = "Acer TravelMate 240",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 240"),
+		},
+		.driver_data = keymap_acer_travelmate_240
+	},
+	{ NULL, }
 };
 
 static int __init select_keymap(void)
@@ -348,7 +367,7 @@
 
 static struct input_dev *input_dev;
 
-static int __init setup_input_dev(void)
+static int __devinit setup_input_dev(void)
 {
 	const struct key_entry *key;
 	int error;
@@ -447,6 +466,52 @@
 	mod_timer(&poll_timer, jiffies + HZ / POLL_FREQUENCY);
 }
 
+static int __devinit wistron_probe(struct platform_device *dev)
+{
+	int err = setup_input_dev();
+	if (err)
+		return err;
+
+	bios_attach();
+	cmos_address = bios_get_cmos_address();
+
+	if (have_wifi) {
+		u16 wifi = bios_get_default_setting(WIFI);
+		if (wifi & 1)
+			wifi_enabled = (wifi & 2) ? 1 : 0;
+		else
+			have_wifi = 0;
+
+		if (have_wifi)
+			bios_set_state(WIFI, wifi_enabled);
+	}
+
+	if (have_bluetooth) {
+		u16 bt = bios_get_default_setting(BLUETOOTH);
+		if (bt & 1)
+			bluetooth_enabled = (bt & 2) ? 1 : 0;
+		else
+			have_bluetooth = 0;
+
+		if (have_bluetooth)
+			bios_set_state(BLUETOOTH, bluetooth_enabled);
+	}
+
+	poll_bios(1); /* Flush stale event queue and arm timer */
+
+	return 0;
+}
+
+static int __devexit wistron_remove(struct platform_device *dev)
+{
+	del_timer_sync(&poll_timer);
+	input_unregister_device(input_dev);
+	bios_detach();
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
 static int wistron_suspend(struct platform_device *dev, pm_message_t state)
 {
 	del_timer_sync(&poll_timer);
@@ -472,13 +537,20 @@
 
 	return 0;
 }
+#else
+#define wistron_suspend		NULL
+#define wistron_resume		NULL
+#endif
 
 static struct platform_driver wistron_driver = {
-	.suspend	= wistron_suspend,
-	.resume		= wistron_resume,
 	.driver		= {
 		.name	= "wistron-bios",
+		.owner	= THIS_MODULE,
 	},
+	.probe		= wistron_probe,
+	.remove		= __devexit_p(wistron_remove),
+	.suspend	= wistron_suspend,
+	.resume		= wistron_resume,
 };
 
 static int __init wb_module_init(void)
@@ -493,55 +565,27 @@
 	if (err)
 		return err;
 
-	bios_attach();
-	cmos_address = bios_get_cmos_address();
-
 	err = platform_driver_register(&wistron_driver);
 	if (err)
-		goto err_detach_bios;
+		goto err_unmap_bios;
 
-	wistron_device = platform_device_register_simple("wistron-bios", -1, NULL, 0);
-	if (IS_ERR(wistron_device)) {
-		err = PTR_ERR(wistron_device);
+	wistron_device = platform_device_alloc("wistron-bios", -1);
+	if (!wistron_device) {
+		err = -ENOMEM;
 		goto err_unregister_driver;
 	}
 
-	if (have_wifi) {
-		u16 wifi = bios_get_default_setting(WIFI);
-		if (wifi & 1)
-			wifi_enabled = (wifi & 2) ? 1 : 0;
-		else
-			have_wifi = 0;
-
-		if (have_wifi)
-			bios_set_state(WIFI, wifi_enabled);
-	}
-
-	if (have_bluetooth) {
-		u16 bt = bios_get_default_setting(BLUETOOTH);
-		if (bt & 1)
-			bluetooth_enabled = (bt & 2) ? 1 : 0;
-		else
-			have_bluetooth = 0;
-
-		if (have_bluetooth)
-			bios_set_state(BLUETOOTH, bluetooth_enabled);
-	}
-
-	err = setup_input_dev();
+	err = platform_device_add(wistron_device);
 	if (err)
-		goto err_unregister_device;
-
-	poll_bios(1); /* Flush stale event queue and arm timer */
+		goto err_free_device;
 
 	return 0;
 
- err_unregister_device:
-	platform_device_unregister(wistron_device);
+ err_free_device:
+	platform_device_put(wistron_device);
  err_unregister_driver:
 	platform_driver_unregister(&wistron_driver);
- err_detach_bios:
-	bios_detach();
+ err_unmap_bios:
 	unmap_bios();
 
 	return err;
@@ -549,11 +593,8 @@
 
 static void __exit wb_module_exit(void)
 {
-	del_timer_sync(&poll_timer);
-	input_unregister_device(input_dev);
 	platform_device_unregister(wistron_device);
 	platform_driver_unregister(&wistron_driver);
-	bios_detach();
 	unmap_bios();
 }
 
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 4acc7fd..2447433 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -40,9 +40,10 @@
 	{ { 0x33, 0x02, 0x0a },	0x88, 0xf8, ALPS_OLDPROTO },		/* UMAX-530T */
 	{ { 0x53, 0x02, 0x0a },	0xf8, 0xf8, 0 },
 	{ { 0x53, 0x02, 0x14 },	0xf8, 0xf8, 0 },
+	{ { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 },			/* HP ze1115 */
 	{ { 0x63, 0x02, 0x0a },	0xf8, 0xf8, 0 },
 	{ { 0x63, 0x02, 0x14 },	0xf8, 0xf8, 0 },
-	{ { 0x63, 0x02, 0x28 },	0xf8, 0xf8, 0 },
+	{ { 0x63, 0x02, 0x28 },	0xf8, 0xf8, ALPS_FW_BK_2 },		/* Fujitsu Siemens S6010 */
 	{ { 0x63, 0x02, 0x3c },	0x8f, 0x8f, ALPS_WHEEL },		/* Toshiba Satellite S2400-103 */
 	{ { 0x63, 0x02, 0x50 },	0xef, 0xef, ALPS_FW_BK_1 },		/* NEC Versa L320 */
 	{ { 0x63, 0x02, 0x64 },	0xf8, 0xf8, 0 },
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index 5599142..5ccc3ef 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -27,6 +27,13 @@
                        DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK B Series"),
                },
        },
+       {
+               .ident = "Lifebook B142",
+               .matches = {
+                       DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
+               },
+
+       },
        { }
 };
 
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 31a59f7..025a71d 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -226,7 +226,9 @@
 		{ 80,	PS2PP_KIND_WHEEL,	PS2PP_SIDE_BTN | PS2PP_WHEEL },
 		{ 81,	PS2PP_KIND_WHEEL,	PS2PP_WHEEL },
 		{ 83,	PS2PP_KIND_WHEEL,	PS2PP_WHEEL },
+		{ 85,	PS2PP_KIND_WHEEL,	PS2PP_WHEEL },
 		{ 86,	PS2PP_KIND_WHEEL,	PS2PP_WHEEL },
+		{ 87,	PS2PP_KIND_WHEEL,	PS2PP_WHEEL },
 		{ 88,	PS2PP_KIND_WHEEL,	PS2PP_WHEEL },
 		{ 96,	0,			0 },
 		{ 97,	PS2PP_KIND_TP3,		PS2PP_WHEEL | PS2PP_HWHEEL },
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 6ee9999..4d5ecc0 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -527,11 +527,15 @@
 	if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0)
 		return PSMOUSE_PS2PP;
 
+	if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0)
+		return PSMOUSE_TRACKPOINT;
+
 /*
  * Reset to defaults in case the device got confused by extended
- * protocol probes.
+ * protocol probes. Note that we do full reset becuase some mice
+ * put themselves to sleep when see PSMOUSE_RESET_DIS.
  */
-	ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
+	psmouse_reset(psmouse);
 
 	if (max_proto >= PSMOUSE_IMEX && im_explorer_detect(psmouse, set_properties) == 0)
 		return PSMOUSE_IMEX;
@@ -540,12 +544,6 @@
 		return PSMOUSE_IMPS;
 
 /*
- * Try to initialize the IBM TrackPoint
- */
-	if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0)
-		return PSMOUSE_TRACKPOINT;
-
-/*
  * Okay, all failed, we have a standard mouse here. The number of the buttons
  * is still a question, though. We assume 3.
  */
@@ -559,7 +557,6 @@
  * extensions.
  */
 		psmouse_reset(psmouse);
-		ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS);
 	}
 
 	return PSMOUSE_PS2;
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
index 4bf58436..2f9a04a 100644
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -95,7 +95,7 @@
 
 	input_sync(dev);
 
-	if (++sermouse->count == (5 - ((sermouse->type == SERIO_SUN) << 1)))
+	if (++sermouse->count == 5)
 		sermouse->count = 0;
 }
 
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 2d0af44..81fd7a9 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -40,15 +40,15 @@
 #endif
 
 static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X;
-module_param(xres, uint, 0);
+module_param(xres, uint, 0644);
 MODULE_PARM_DESC(xres, "Horizontal screen resolution");
 
 static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
-module_param(yres, uint, 0);
+module_param(yres, uint, 0644);
 MODULE_PARM_DESC(yres, "Vertical screen resolution");
 
 static unsigned tap_time = 200;
-module_param(tap_time, uint, 0);
+module_param(tap_time, uint, 0644);
 MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
 
 struct mousedev_hw_data {
@@ -155,7 +155,7 @@
 	switch (code) {
 		case ABS_X:
 			size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
-			if (size == 0) size = xres;
+			if (size == 0) size = xres ? : 1;
 			if (value > dev->absmax[ABS_X]) value = dev->absmax[ABS_X];
 			if (value < dev->absmin[ABS_X]) value = dev->absmin[ABS_X];
 			mousedev->packet.x = ((value - dev->absmin[ABS_X]) * xres) / size;
@@ -164,7 +164,7 @@
 
 		case ABS_Y:
 			size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
-			if (size == 0) size = yres;
+			if (size == 0) size = yres ? : 1;
 			if (value > dev->absmax[ABS_Y]) value = dev->absmax[ABS_Y];
 			if (value < dev->absmin[ABS_Y]) value = dev->absmin[ABS_Y];
 			mousedev->packet.y = yres - ((value - dev->absmin[ABS_Y]) * yres) / size;
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index 9b1ab5e..3df5eed 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -19,12 +19,12 @@
 #include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/err.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/kmi.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/amba_kmi.h>
-#include <asm/hardware/clock.h>
 
 #define KMI_BASE	(kmi->base)
 
@@ -72,13 +72,9 @@
 	unsigned int divisor;
 	int ret;
 
-	ret = clk_use(kmi->clk);
-	if (ret)
-		goto out;
-
 	ret = clk_enable(kmi->clk);
 	if (ret)
-		goto clk_unuse;
+		goto out;
 
 	divisor = clk_get_rate(kmi->clk) / 8000000 - 1;
 	writeb(divisor, KMICLKDIV);
@@ -97,8 +93,6 @@
 
  clk_disable:
 	clk_disable(kmi->clk);
- clk_unuse:
-	clk_unuse(kmi->clk);
  out:
 	return ret;
 }
@@ -111,7 +105,6 @@
 
 	free_irq(kmi->irq, kmi);
 	clk_disable(kmi->clk);
-	clk_unuse(kmi->clk);
 }
 
 static int amba_kmi_probe(struct amba_device *dev, void *id)
diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c
index 4da6c86..096b6a0 100644
--- a/drivers/input/serio/ct82c710.c
+++ b/drivers/input/serio/ct82c710.c
@@ -154,7 +154,7 @@
  * See if we can find a 82C710 device. Read mouse address.
  */
 
-static int __init ct82c710_probe(void)
+static int __init ct82c710_detect(void)
 {
 	outb_p(0x55, 0x2fa);				/* Any value except 9, ff or 36 */
 	outb_p(0xaa, 0x3fa);				/* Inverse of 55 */
@@ -163,7 +163,7 @@
 	outb_p(0x1b, 0x2fa);				/* Inverse of e4 */
 	outb_p(0x0f, 0x390);				/* Write index */
 	if (inb_p(0x391) != 0xe4)			/* Config address found? */
-		return -1;				/* No: no 82C710 here */
+		return -ENODEV;				/* No: no 82C710 here */
 
 	outb_p(0x0d, 0x390);				/* Write index */
 	ct82c710_iores.start = inb_p(0x391) << 2;	/* Get mouse I/O address */
@@ -175,51 +175,88 @@
 	return 0;
 }
 
-static struct serio * __init ct82c710_allocate_port(void)
+static int __devinit ct82c710_probe(struct platform_device *dev)
 {
-	struct serio *serio;
+	ct82c710_port = kzalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!ct82c710_port)
+		return -ENOMEM;
 
-	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
-	if (serio) {
-		memset(serio, 0, sizeof(struct serio));
-		serio->id.type = SERIO_8042;
-		serio->open = ct82c710_open;
-		serio->close = ct82c710_close;
-		serio->write = ct82c710_write;
-		serio->dev.parent = &ct82c710_device->dev;
-		strlcpy(serio->name, "C&T 82c710 mouse port", sizeof(serio->name));
-		snprintf(serio->phys, sizeof(serio->phys), "isa%04lx/serio0", CT82C710_DATA);
-	}
+	ct82c710_port->id.type = SERIO_8042;
+	ct82c710_port->dev.parent = &dev->dev;
+	ct82c710_port->open = ct82c710_open;
+	ct82c710_port->close = ct82c710_close;
+	ct82c710_port->write = ct82c710_write;
+	strlcpy(ct82c710_port->name, "C&T 82c710 mouse port",
+		sizeof(ct82c710_port->name));
+	snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys),
+		 "isa%04lx/serio0", CT82C710_DATA);
 
-	return serio;
+	serio_register_port(ct82c710_port);
+
+	return 0;
 }
 
+static int __devexit ct82c710_remove(struct platform_device *dev)
+{
+	serio_unregister_port(ct82c710_port);
+
+	return 0;
+}
+
+static struct platform_driver ct82c710_driver = {
+	.driver		= {
+		.name	= "ct82c710",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ct82c710_probe,
+	.remove		= __devexit_p(ct82c710_remove),
+};
+
+
 static int __init ct82c710_init(void)
 {
-	if (ct82c710_probe())
-		return -ENODEV;
+	int error;
 
-	ct82c710_device = platform_device_register_simple("ct82c710", -1, &ct82c710_iores, 1);
-	if (IS_ERR(ct82c710_device))
-		return PTR_ERR(ct82c710_device);
+	error = ct82c710_detect();
+	if (error)
+		return error;
 
-	if (!(ct82c710_port = ct82c710_allocate_port())) {
-		platform_device_unregister(ct82c710_device);
-		return -ENOMEM;
+	error = platform_driver_register(&ct82c710_driver);
+	if (error)
+		return error;
+
+	ct82c710_device = platform_device_alloc("ct82c710", -1);
+	if (!ct82c710_device) {
+		error = -ENOMEM;
+		goto err_unregister_driver;
 	}
 
+	error = platform_device_add_resources(ct82c710_device, &ct82c710_iores, 1);
+	if (error)
+		goto err_free_device;
+
+	error = platform_device_add(ct82c710_device);
+	if (error)
+		goto err_free_device;
+
 	serio_register_port(ct82c710_port);
 
 	printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n",
 		CT82C710_DATA, CT82C710_IRQ);
 
 	return 0;
+
+ err_free_device:
+	platform_device_put(ct82c710_device);
+ err_unregister_driver:
+	platform_driver_unregister(&ct82c710_driver);
+	return error;
 }
 
 static void __exit ct82c710_exit(void)
 {
-	serio_unregister_port(ct82c710_port);
 	platform_device_unregister(ct82c710_device);
+	platform_driver_unregister(&ct82c710_driver);
 }
 
 module_init(ct82c710_init);
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 273bb3b..2d2f9fb 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -84,6 +84,14 @@
 			DMI_MATCH(DMI_PRODUCT_VERSION, "DL760"),
 		},
 	},
+	{
+		.ident = "OQO Model 01",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "OQO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"),
+			DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
+		},
+	},
 	{ }
 };
 
@@ -158,6 +166,13 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"),
 		},
 	},
+	{
+		.ident = "Sharp Actius MM20",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"),
+		},
+	},
 	{ }
 };
 
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index ac86c1d..a7d91d5 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -572,7 +572,7 @@
  * LCS/Telegraphics.
  */
 
-static int __init i8042_check_mux(void)
+static int __devinit i8042_check_mux(void)
 {
 	unsigned char mux_version;
 
@@ -600,7 +600,7 @@
  * the presence of an AUX interface.
  */
 
-static int __init i8042_check_aux(void)
+static int __devinit i8042_check_aux(void)
 {
 	unsigned char param;
 	static int i8042_check_aux_cookie;
@@ -678,7 +678,7 @@
  * registers it, and reports to the user.
  */
 
-static int __init i8042_port_register(struct i8042_port *port)
+static int __devinit i8042_port_register(struct i8042_port *port)
 {
 	i8042_ctr &= ~port->disable;
 
@@ -956,7 +956,6 @@
 	panic_blink = i8042_panic_blink;
 
 	return 0;
-
 }
 
 /*
@@ -969,16 +968,7 @@
 	i8042_controller_cleanup();
 }
 
-static struct platform_driver i8042_driver = {
-	.suspend	= i8042_suspend,
-	.resume		= i8042_resume,
-	.shutdown	= i8042_shutdown,
-	.driver		= {
-		.name	= "i8042",
-	},
-};
-
-static int __init i8042_create_kbd_port(void)
+static int __devinit i8042_create_kbd_port(void)
 {
 	struct serio *serio;
 	struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
@@ -1003,7 +993,7 @@
 	return i8042_port_register(port);
 }
 
-static int __init i8042_create_aux_port(void)
+static int __devinit i8042_create_aux_port(void)
 {
 	struct serio *serio;
 	struct i8042_port *port = &i8042_ports[I8042_AUX_PORT_NO];
@@ -1028,7 +1018,7 @@
 	return i8042_port_register(port);
 }
 
-static int __init i8042_create_mux_port(int index)
+static int __devinit i8042_create_mux_port(int index)
 {
 	struct serio *serio;
 	struct i8042_port *port = &i8042_ports[I8042_MUX_PORT_NO + index];
@@ -1057,37 +1047,16 @@
 	return i8042_port_register(port);
 }
 
-static int __init i8042_init(void)
+static int __devinit i8042_probe(struct platform_device *dev)
 {
 	int i, have_ports = 0;
 	int err;
 
-	dbg_init();
-
 	init_timer(&i8042_timer);
 	i8042_timer.function = i8042_timer_func;
 
-	err = i8042_platform_init();
-	if (err)
-		return err;
-
-	i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
-	i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
-
-	if (i8042_controller_init()) {
-		err = -ENODEV;
-		goto err_platform_exit;
-	}
-
-	err = platform_driver_register(&i8042_driver);
-	if (err)
-		goto err_controller_cleanup;
-
-	i8042_platform_device = platform_device_register_simple("i8042", -1, NULL, 0);
-	if (IS_ERR(i8042_platform_device)) {
-		err = PTR_ERR(i8042_platform_device);
-		goto err_unregister_driver;
-	}
+	if (i8042_controller_init())
+		return -ENODEV;
 
 	if (!i8042_noaux && !i8042_check_aux()) {
 		if (!i8042_nomux && !i8042_check_mux()) {
@@ -1113,30 +1082,23 @@
 
 	if (!have_ports) {
 		err = -ENODEV;
-		goto err_unregister_device;
+		goto err_controller_cleanup;
 	}
 
 	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
-
 	return 0;
 
  err_unregister_ports:
 	for (i = 0; i < I8042_NUM_PORTS; i++)
 		if (i8042_ports[i].serio)
 			serio_unregister_port(i8042_ports[i].serio);
- err_unregister_device:
-	platform_device_unregister(i8042_platform_device);
- err_unregister_driver:
-	platform_driver_unregister(&i8042_driver);
  err_controller_cleanup:
 	i8042_controller_cleanup();
- err_platform_exit:
-	i8042_platform_exit();
 
 	return err;
 }
 
-static void __exit i8042_exit(void)
+static int __devexit i8042_remove(struct platform_device *dev)
 {
 	int i;
 
@@ -1148,6 +1110,62 @@
 
 	del_timer_sync(&i8042_timer);
 
+	return 0;
+}
+
+static struct platform_driver i8042_driver = {
+	.driver		= {
+		.name	= "i8042",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= i8042_probe,
+	.remove		= __devexit_p(i8042_remove),
+	.suspend	= i8042_suspend,
+	.resume		= i8042_resume,
+	.shutdown	= i8042_shutdown,
+};
+
+static int __init i8042_init(void)
+{
+	int err;
+
+	dbg_init();
+
+	err = i8042_platform_init();
+	if (err)
+		return err;
+
+	i8042_ports[I8042_AUX_PORT_NO].irq = I8042_AUX_IRQ;
+	i8042_ports[I8042_KBD_PORT_NO].irq = I8042_KBD_IRQ;
+
+	err = platform_driver_register(&i8042_driver);
+	if (err)
+		goto err_platform_exit;
+
+	i8042_platform_device = platform_device_alloc("i8042", -1);
+	if (!i8042_platform_device) {
+		err = -ENOMEM;
+		goto err_unregister_driver;
+	}
+
+	err = platform_device_add(i8042_platform_device);
+	if (err)
+		goto err_free_device;
+
+	return 0;
+
+ err_free_device:
+	platform_device_put(i8042_platform_device);
+ err_unregister_driver:
+	platform_driver_unregister(&i8042_driver);
+ err_platform_exit:
+	i8042_platform_exit();
+
+	return err;
+}
+
+static void __exit i8042_exit(void)
+{
 	platform_device_unregister(i8042_platform_device);
 	platform_driver_unregister(&i8042_driver);
 
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index 1383503..cbbf384 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -21,7 +21,7 @@
 #include "i8042-ip22io.h"
 #elif defined(CONFIG_PPC)
 #include "i8042-ppcio.h"
-#elif defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
+#elif defined(CONFIG_SPARC)
 #include "i8042-sparcio.h"
 #elif defined(CONFIG_X86) || defined(CONFIG_IA64)
 #include "i8042-x86ia64io.h"
diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c
index d857f70..f08a5d0 100644
--- a/drivers/input/serio/maceps2.c
+++ b/drivers/input/serio/maceps2.c
@@ -118,13 +118,12 @@
 }
 
 
-static struct serio * __init maceps2_allocate_port(int idx)
+static struct serio * __devinit maceps2_allocate_port(int idx)
 {
 	struct serio *serio;
 
-	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
+	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
 	if (serio) {
-		memset(serio, 0, sizeof(struct serio));
 		serio->id.type		= SERIO_8042;
 		serio->write		= maceps2_write;
 		serio->open		= maceps2_open;
@@ -138,24 +137,13 @@
 	return serio;
 }
 
-
-static int __init maceps2_init(void)
+static int __devinit maceps2_probe(struct platform_device *dev)
 {
-	maceps2_device = platform_device_register_simple("maceps2", -1, NULL, 0);
-	if (IS_ERR(maceps2_device))
-		return PTR_ERR(maceps2_device);
-
-	port_data[0].port = &mace->perif.ps2.keyb;
-	port_data[0].irq  = MACEISA_KEYB_IRQ;
-	port_data[1].port = &mace->perif.ps2.mouse;
-	port_data[1].irq  = MACEISA_MOUSE_IRQ;
-
 	maceps2_port[0] = maceps2_allocate_port(0);
 	maceps2_port[1] = maceps2_allocate_port(1);
 	if (!maceps2_port[0] || !maceps2_port[1]) {
 		kfree(maceps2_port[0]);
 		kfree(maceps2_port[1]);
-		platform_device_unregister(maceps2_device);
 		return -ENOMEM;
 	}
 
@@ -165,11 +153,59 @@
 	return 0;
 }
 
-static void __exit maceps2_exit(void)
+static int __devexit maceps2_remove(struct platform_device *dev)
 {
 	serio_unregister_port(maceps2_port[0]);
 	serio_unregister_port(maceps2_port[1]);
+
+	return 0;
+}
+
+static struct platform_driver maceps2_driver = {
+	.driver		= {
+		.name	= "maceps2",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= maceps2_probe,
+	.remove		= __devexit_p(maceps2_remove),
+};
+
+static int __init maceps2_init(void)
+{
+	int error;
+
+	error = platform_driver_register(&maceps2_driver);
+	if (error)
+		return error;
+
+	maceps2_device = platform_device_alloc("maceps2", -1);
+	if (!maceps2_device) {
+		error = -ENOMEM;
+		goto err_unregister_driver;
+	}
+
+	port_data[0].port = &mace->perif.ps2.keyb;
+	port_data[0].irq  = MACEISA_KEYB_IRQ;
+	port_data[1].port = &mace->perif.ps2.mouse;
+	port_data[1].irq  = MACEISA_MOUSE_IRQ;
+
+	error = platform_device_add(maceps2_device);
+	if (error)
+		goto err_free_device;
+
+	return 0;
+
+ err_free_device:
+	platform_device_put(maceps2_device);
+ err_unregister_driver:
+	platform_driver_unregister(&maceps2_driver);
+	return error;
+}
+
+static void __exit maceps2_exit(void)
+{
 	platform_device_unregister(maceps2_device);
+	platform_driver_unregister(&maceps2_driver);
 }
 
 module_init(maceps2_init);
diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c
index b44d255..d3827c5 100644
--- a/drivers/input/serio/q40kbd.c
+++ b/drivers/input/serio/q40kbd.c
@@ -75,13 +75,13 @@
 
 static void q40kbd_flush(void)
 {
- 	int maxread = 100;
+	int maxread = 100;
 	unsigned long flags;
 
 	spin_lock_irqsave(&q40kbd_lock, flags);
 
- 	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
- 		master_inb(KEYCODE_REG);
+	while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)))
+		master_inb(KEYCODE_REG);
 
 	spin_unlock_irqrestore(&q40kbd_lock, flags);
 }
@@ -97,14 +97,14 @@
 
 	if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) {
 		printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD);
-		return -1;
+		return -EBUSY;
 	}
 
- 	/* off we go */
- 	master_outb(-1, KEYBOARD_UNLOCK_REG);
- 	master_outb(1, KEY_IRQ_ENABLE_REG);
+	/* off we go */
+	master_outb(-1, KEYBOARD_UNLOCK_REG);
+	master_outb(1, KEY_IRQ_ENABLE_REG);
 
- 	return 0;
+	return 0;
 }
 
 static void q40kbd_close(struct serio *port)
@@ -116,37 +116,18 @@
 	q40kbd_flush();
 }
 
-static struct serio * __init q40kbd_allocate_port(void)
+static int __devinit q40kbd_probe(struct platform_device *dev)
 {
-	struct serio *serio;
-
-	serio = kmalloc(sizeof(struct serio), GFP_KERNEL);
-	if (serio) {
-		memset(serio, 0, sizeof(struct serio));
-		serio->id.type		= SERIO_8042;
-		serio->open		= q40kbd_open;
-		serio->close		= q40kbd_close;
-		serio->dev.parent	= &q40kbd_device->dev;
-		strlcpy(serio->name, "Q40 Kbd Port", sizeof(serio->name));
-		strlcpy(serio->phys, "Q40", sizeof(serio->phys));
-	}
-
-	return serio;
-}
-
-static int __init q40kbd_init(void)
-{
-	if (!MACH_IS_Q40)
-		return -EIO;
-
-	q40kbd_device = platform_device_register_simple("q40kbd", -1, NULL, 0);
-	if (IS_ERR(q40kbd_device))
-		return PTR_ERR(q40kbd_device);
-
-	if (!(q40kbd_port = q40kbd_allocate_port())) {
-		platform_device_unregister(q40kbd_device);
+	q40kbd_port = kzalloc(sizeof(struct serio), GFP_KERNEL);
+	if (!q40kbd_port)
 		return -ENOMEM;
-	}
+
+	q40kbd_port->id.type	= SERIO_8042;
+	q40kbd_port->open	= q40kbd_open;
+	q40kbd_port->close	= q40kbd_close;
+	q40kbd_port->dev.parent	= &dev->dev;
+	strlcpy(q40kbd_port->name, "Q40 Kbd Port", sizeof(q40kbd_port->name));
+	strlcpy(q40kbd_port->phys, "Q40", sizeof(q40kbd_port->phys));
 
 	serio_register_port(q40kbd_port);
 	printk(KERN_INFO "serio: Q40 kbd registered\n");
@@ -154,10 +135,54 @@
 	return 0;
 }
 
-static void __exit q40kbd_exit(void)
+static int __devexit q40kbd_remove(struct platform_device *dev)
 {
 	serio_unregister_port(q40kbd_port);
+
+	return 0;
+}
+
+static struct platform_driver q40kbd_driver = {
+	.driver		= {
+		.name	= "q40kbd",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= q40kbd_probe,
+	.remove		= __devexit_p(q40kbd_remove),
+};
+
+static int __init q40kbd_init(void)
+{
+	int error;
+
+	if (!MACH_IS_Q40)
+		return -EIO;
+
+	error = platform_driver_register(&q40kbd_driver);
+	if (error)
+		return error;
+
+	q40kbd_device = platform_device_alloc("q40kbd", -1);
+	if (!q40kbd_device)
+		goto err_unregister_driver;
+
+	error = platform_device_add(q40kbd_device);
+	if (error)
+		goto err_free_device;
+
+	return 0;
+
+ err_free_device:
+	platform_device_put(q40kbd_device);
+ err_unregister_driver:
+	platform_driver_unregister(&q40kbd_driver);
+	return error;
+}
+
+static void __exit q40kbd_exit(void)
+{
 	platform_device_unregister(q40kbd_device);
+	platform_driver_unregister(&q40kbd_driver);
 }
 
 module_init(q40kbd_init);
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index fbb69ef..8e530cc 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -800,16 +800,16 @@
 
 #ifdef CONFIG_HOTPLUG
 
-#define SERIO_ADD_HOTPLUG_VAR(fmt, val...)				\
+#define SERIO_ADD_UEVENT_VAR(fmt, val...)				\
 	do {								\
-		int err = add_hotplug_env_var(envp, num_envp, &i,	\
+		int err = add_uevent_var(envp, num_envp, &i,	\
 					buffer, buffer_size, &len,	\
 					fmt, val);			\
 		if (err)						\
 			return err;					\
 	} while (0)
 
-static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
 {
 	struct serio *serio;
 	int i = 0;
@@ -820,21 +820,21 @@
 
 	serio = to_serio_port(dev);
 
-	SERIO_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type);
-	SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto);
-	SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id);
-	SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra);
-	SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
+	SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type);
+	SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto);
+	SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id);
+	SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
+	SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
 				serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
 	envp[i] = NULL;
 
 	return 0;
 }
-#undef SERIO_ADD_HOTPLUG_VAR
+#undef SERIO_ADD_UEVENT_VAR
 
 #else
 
-static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
 {
 	return -ENODEV;
 }
@@ -908,7 +908,7 @@
 	serio_bus.dev_attrs = serio_device_attrs;
 	serio_bus.drv_attrs = serio_driver_attrs;
 	serio_bus.match = serio_bus_match;
-	serio_bus.hotplug = serio_hotplug;
+	serio_bus.uevent = serio_uevent;
 	serio_bus.resume = serio_resume;
 	bus_register(&serio_bus);
 
diff --git a/drivers/isdn/act2000/act2000.h b/drivers/isdn/act2000/act2000.h
index b091d1a..d4c5051 100644
--- a/drivers/isdn/act2000/act2000.h
+++ b/drivers/isdn/act2000/act2000.h
@@ -181,17 +181,17 @@
 	char regname[35];		/* Name used for request_region     */
 } act2000_card;
 
-extern __inline__ void act2000_schedule_tx(act2000_card *card)
+static inline void act2000_schedule_tx(act2000_card *card)
 {
         schedule_work(&card->snd_tq);
 }
 
-extern __inline__ void act2000_schedule_rx(act2000_card *card)
+static inline void act2000_schedule_rx(act2000_card *card)
 {
         schedule_work(&card->rcv_tq);
 }
 
-extern __inline__ void act2000_schedule_poll(act2000_card *card)
+static inline void act2000_schedule_poll(act2000_card *card)
 {
         schedule_work(&card->poll_tq);
 }
diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h
index f6d5f53..49f453c 100644
--- a/drivers/isdn/act2000/capi.h
+++ b/drivers/isdn/act2000/capi.h
@@ -78,29 +78,29 @@
 typedef struct actcapi_msn {
 	__u8 eaz;
 	__u8 len;                            /* Length of MSN                */
-	__u8 msn[15] __attribute__ ((packed));
-} actcapi_msn;
+	__u8 msn[15];
+}  __attribute__((packed)) actcapi_msn;
 
 typedef struct actcapi_dlpd {
 	__u8 len;                            /* Length of structure          */
-	__u16 dlen __attribute__ ((packed)); /* Data Length                  */
-	__u8 laa __attribute__ ((packed));   /* Link Address A               */
+	__u16 dlen;                          /* Data Length                  */
+	__u8 laa;                            /* Link Address A               */
 	__u8 lab;                            /* Link Address B               */
 	__u8 modulo;                         /* Modulo Mode                  */
 	__u8 win;                            /* Window size                  */
 	__u8 xid[100];                       /* XID Information              */
-} actcapi_dlpd;
+} __attribute__((packed)) actcapi_dlpd;
 
 typedef struct actcapi_ncpd {
 	__u8   len;                          /* Length of structure          */
-	__u16  lic __attribute__ ((packed));
-	__u16  hic __attribute__ ((packed));
-	__u16  ltc __attribute__ ((packed));
-	__u16  htc __attribute__ ((packed));
-	__u16  loc __attribute__ ((packed));
-	__u16  hoc __attribute__ ((packed));
-	__u8   modulo __attribute__ ((packed));
-} actcapi_ncpd;
+	__u16  lic;
+	__u16  hic;
+	__u16  ltc;
+	__u16  htc;
+	__u16  loc;
+	__u16  hoc;
+	__u8   modulo;
+} __attribute__((packed)) actcapi_ncpd;
 #define actcapi_ncpi actcapi_ncpd
 
 /*
@@ -168,19 +168,19 @@
 			__u16 manuf_msg;
 			__u16 controller;
 			actcapi_msn msnmap;
-		} manufacturer_req_msn;
+		} __attribute ((packed)) manufacturer_req_msn;
 		/* TODO: TraceInit-req/conf/ind/resp and
 		 *       TraceDump-req/conf/ind/resp
 		 */
 		struct connect_req {
 			__u8  controller;
 			__u8  bchan;
-			__u32 infomask __attribute__ ((packed));
+			__u32 infomask;
 			__u8  si1;
 			__u8  si2;
 			__u8  eaz;
 			actcapi_addr addr;
-		} connect_req;
+		} __attribute__ ((packed)) connect_req;
 		struct connect_conf {
 			__u16 plci;
 			__u16 info;
@@ -192,7 +192,7 @@
 			__u8  si2;
 			__u8  eaz;
 			actcapi_addr addr;
-		} connect_ind;
+		} __attribute__ ((packed)) connect_ind;
 		struct connect_resp {
 			__u16 plci;
 			__u8  rejectcause;
@@ -200,14 +200,14 @@
 		struct connect_active_ind {
 			__u16 plci;
 			actcapi_addr addr;
-		} connect_active_ind;
+		} __attribute__ ((packed)) connect_active_ind;
 		struct connect_active_resp {
 			__u16 plci;
 		} connect_active_resp;
 		struct connect_b3_req {
 			__u16 plci;
 			actcapi_ncpi ncpi;
-		} connect_b3_req;
+		} __attribute__ ((packed)) connect_b3_req;
 		struct connect_b3_conf {
 			__u16 plci;
 			__u16 ncci;
@@ -217,12 +217,12 @@
 			__u16 ncci;
 			__u16 plci;
 			actcapi_ncpi ncpi;
-		} connect_b3_ind;
+		} __attribute__ ((packed)) connect_b3_ind;
 		struct connect_b3_resp {
 			__u16 ncci;
 			__u8  rejectcause;
-			actcapi_ncpi ncpi __attribute__ ((packed));
-		} connect_b3_resp;
+			actcapi_ncpi ncpi;
+		} __attribute__ ((packed)) connect_b3_resp;
 		struct disconnect_req {
 			__u16 plci;
 			__u8  cause;
@@ -241,14 +241,14 @@
 		struct connect_b3_active_ind {
 			__u16 ncci;
 			actcapi_ncpi ncpi;
-		} connect_b3_active_ind;
+		} __attribute__ ((packed)) connect_b3_active_ind;
 		struct connect_b3_active_resp {
 			__u16 ncci;
 		} connect_b3_active_resp;
 		struct disconnect_b3_req {
 			__u16 ncci;
 			actcapi_ncpi ncpi;
-		} disconnect_b3_req;
+		} __attribute__ ((packed)) disconnect_b3_req;
 		struct disconnect_b3_conf {
 			__u16 ncci;
 			__u16 info;
@@ -257,7 +257,7 @@
 			__u16 ncci;
 			__u16 info;
 			actcapi_ncpi ncpi;
-		} disconnect_b3_ind;
+		} __attribute__ ((packed)) disconnect_b3_ind;
 		struct disconnect_b3_resp {
 			__u16 ncci;
 		} disconnect_b3_resp;
@@ -265,7 +265,7 @@
 			__u16 plci;
 			actcapi_infonr nr;
 			actcapi_infoel el;
-		} info_ind;
+		} __attribute__ ((packed)) info_ind;
 		struct info_resp {
 			__u16 plci;
 		} info_resp;
@@ -279,8 +279,8 @@
 		struct select_b2_protocol_req {
 			__u16 plci;
 			__u8  protocol;
-			actcapi_dlpd dlpd __attribute__ ((packed));
-		} select_b2_protocol_req;
+			actcapi_dlpd dlpd;
+		} __attribute__ ((packed)) select_b2_protocol_req;
 		struct select_b2_protocol_conf {
 			__u16 plci;
 			__u16 info;
@@ -288,49 +288,49 @@
 		struct select_b3_protocol_req {
 			__u16 plci;
 			__u8  protocol;
-			actcapi_ncpd ncpd __attribute__ ((packed));
-		} select_b3_protocol_req;
+			actcapi_ncpd ncpd;
+		} __attribute__ ((packed)) select_b3_protocol_req;
 		struct select_b3_protocol_conf {
 			__u16 plci;
 			__u16 info;
 		} select_b3_protocol_conf;
 		struct listen_req {
 			__u8  controller;
-			__u32 infomask __attribute__ ((packed));  
-			__u16 eazmask __attribute__ ((packed));
-			__u16 simask __attribute__ ((packed));
-		} listen_req;
+			__u32 infomask;
+			__u16 eazmask;
+			__u16 simask;
+		} __attribute__ ((packed)) listen_req;
 		struct listen_conf {
 			__u8  controller;
-			__u16 info __attribute__ ((packed));
-		} listen_conf;
+			__u16 info;
+		} __attribute__ ((packed)) listen_conf;
 		struct data_b3_req {
 			__u16 fakencci;
 			__u16 datalen;
 			__u32 unused;
 			__u8  blocknr;
-			__u16 flags __attribute__ ((packed));
-		} data_b3_req;
+			__u16 flags;
+		} __attribute ((packed)) data_b3_req;
 		struct data_b3_ind {
 			__u16 fakencci;
 			__u16 datalen;
 			__u32 unused;
 			__u8  blocknr;
-			__u16 flags __attribute__ ((packed));
-		} data_b3_ind;
+			__u16 flags;
+		} __attribute__ ((packed)) data_b3_ind;
 		struct data_b3_resp {
 			__u16 ncci;
 			__u8  blocknr;
-		} data_b3_resp;
+		} __attribute__ ((packed)) data_b3_resp;
 		struct data_b3_conf {
 			__u16 ncci;
 			__u8  blocknr;
-			__u16 info __attribute__ ((packed));
-		} data_b3_conf;
+			__u16 info;
+		} __attribute__ ((packed)) data_b3_conf;
 	} msg;
-} actcapi_msg;
+} __attribute__ ((packed)) actcapi_msg;
 
-extern __inline__ unsigned short
+static inline unsigned short
 actcapi_nextsmsg(act2000_card *card)
 {
 	unsigned long flags;
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 7b564c0..207cae3 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -17,6 +17,8 @@
 #include <linux/ctype.h>
 #include <linux/sched.h>	/* current */
 
+#include "capifs.h"
+
 MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index 27391c3..2a2b03f 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -53,8 +53,6 @@
 
 static void avmcs_config(dev_link_t *link);
 static void avmcs_release(dev_link_t *link);
-static int avmcs_event(event_t event, int priority,
-			  event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -62,16 +60,7 @@
    needed to manage one actual PCMCIA card.
 */
 
-static dev_link_t *avmcs_attach(void);
-static void avmcs_detach(dev_link_t *);
-
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "avm_cs";
+static void avmcs_detach(struct pcmcia_device *p_dev);
 
 /*
    A linked list of "instances" of the skeleton device.  Each actual
@@ -83,15 +72,7 @@
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -118,13 +99,11 @@
     
 ======================================================================*/
 
-static dev_link_t *avmcs_attach(void)
+static int avmcs_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret;
-    
+
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
     if (!link)
@@ -155,25 +134,19 @@
         goto err_kfree;
     memset(local, 0, sizeof(local_info_t));
     link->priv = local;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	avmcs_detach(link);
-	goto err;
-    }
-    return link;
+
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    avmcs_config(link);
+
+    return 0;
 
  err_kfree:
     kfree(link);
  err:
-    return NULL;
+    return -EINVAL;
 } /* avmcs_attach */
 
 /*======================================================================
@@ -185,33 +158,13 @@
 
 ======================================================================*/
 
-static void avmcs_detach(dev_link_t *link)
+static void avmcs_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
+    if (link->state & DEV_CONFIG)
+	avmcs_release(link);
 
-    /*
-       If the device is currently configured and active, we won't
-       actually delete it yet.  Instead, it is marked so that when
-       the release() function is called, that will trigger a proper
-       detach().
-    */
-    if (link->state & DEV_CONFIG) {
-	link->state |= DEV_STALE_LINK;
-	return;
-    }
-
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
-    /* Unlink device structure, free pieces */
-    *linkp = link->next;
     kfree(link->priv);
     kfree(link);
 } /* avmcs_detach */
@@ -424,12 +377,30 @@
     pcmcia_release_io(link->handle, &link->io);
     pcmcia_release_irq(link->handle, &link->irq);
     link->state &= ~DEV_CONFIG;
-    
-    if (link->state & DEV_STALE_LINK)
-	avmcs_detach(link);
-    
 } /* avmcs_release */
 
+static int avmcs_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int avmcs_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
+
 /*======================================================================
 
     The card status event handler.  Mostly, this schedules other
@@ -444,38 +415,6 @@
     
 ======================================================================*/
 
-static int avmcs_event(event_t event, int priority,
-			  event_callback_args_t *args)
-{
-    dev_link_t *link = args->client_data;
-
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-		avmcs_release(link);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	avmcs_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (link->state & DEV_CONFIG)
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	break;
-    }
-    return 0;
-} /* avmcs_event */
 
 static struct pcmcia_device_id avmcs_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
@@ -490,10 +429,11 @@
 	.drv	= {
 		.name	= "avm_cs",
 	},
-	.attach	= avmcs_attach,
-	.event	= avmcs_event,
-	.detach	= avmcs_detach,
+	.probe = avmcs_attach,
+	.remove	= avmcs_detach,
 	.id_table = avmcs_ids,
+	.suspend= avmcs_suspend,
+	.resume = avmcs_resume,
 };
 
 static int __init avmcs_init(void)
@@ -504,7 +444,6 @@
 static void __exit avmcs_exit(void)
 {
 	pcmcia_unregister_driver(&avmcs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(avmcs_init);
diff --git a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c
index cccfabc..11e6f93 100644
--- a/drivers/isdn/hardware/eicon/os_4bri.c
+++ b/drivers/isdn/hardware/eicon/os_4bri.c
@@ -16,6 +16,7 @@
 #include "diva_pci.h"
 #include "mi_pc.h"
 #include "dsrv4bri.h"
+#include "helpers.h"
 
 static void *diva_xdiLoadFileFile = NULL;
 static dword diva_xdiLoadFileLength = 0;
@@ -815,7 +816,7 @@
 	return (ret);
 }
 
-void *xdiLoadFile(char *FileName, unsigned long *FileLength,
+void *xdiLoadFile(char *FileName, dword *FileLength,
 		  unsigned long lim)
 {
 	void *ret = diva_xdiLoadFileFile;
diff --git a/drivers/isdn/hardware/eicon/os_bri.c b/drivers/isdn/hardware/eicon/os_bri.c
index 4cc44a5..f31bba5 100644
--- a/drivers/isdn/hardware/eicon/os_bri.c
+++ b/drivers/isdn/hardware/eicon/os_bri.c
@@ -16,6 +16,7 @@
 #include "diva_pci.h"
 #include "mi_pc.h"
 #include "pc_maint.h"
+#include "dsrv_bri.h"
 
 /*
 **  IMPORTS
diff --git a/drivers/isdn/hardware/eicon/os_pri.c b/drivers/isdn/hardware/eicon/os_pri.c
index 8ac207f..a296a84 100644
--- a/drivers/isdn/hardware/eicon/os_pri.c
+++ b/drivers/isdn/hardware/eicon/os_pri.c
@@ -18,6 +18,7 @@
 #include "pc_maint.h"
 #include "dsp_tst.h"
 #include "diva_dma.h"
+#include "dsrv_pri.h"
 
 /* --------------------------------------------------------------------------
    OS Dependent part of XDI driver for DIVA PRI Adapter
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index c821059..0ef5601 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -110,7 +110,7 @@
 
 config HISAX_TELESPCI
 	bool "Teles PCI"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
 	help
 	  This enables HiSax support for the Teles PCI.
 	  See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -238,7 +238,7 @@
 
 config HISAX_NETJET
 	bool "NETjet card"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
 	help
 	  This enables HiSax support for the NetJet from Traverse
 	  Technologies.
@@ -249,7 +249,7 @@
 
 config HISAX_NETJET_U
 	bool "NETspider U card"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
 	help
 	  This enables HiSax support for the Netspider U interface ISDN card
 	  from Traverse Technologies.
@@ -317,7 +317,7 @@
 
 config HISAX_HFC_PCI
 	bool "HFC PCI-Bus cards"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
 	help
 	  This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 
@@ -344,7 +344,7 @@
 
 config HISAX_ENTERNOW_PCI
 	bool "Formula-n enter:now PCI card"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV))
 	help
 	  This enables HiSax support for the Formula-n enter:now PCI
 	  ISDN card.
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 5f5a5ae7..969da40 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -69,8 +69,6 @@
 
 static void avma1cs_config(dev_link_t *link);
 static void avma1cs_release(dev_link_t *link);
-static int avma1cs_event(event_t event, int priority,
-			  event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -78,16 +76,8 @@
    needed to manage one actual PCMCIA card.
 */
 
-static dev_link_t *avma1cs_attach(void);
-static void avma1cs_detach(dev_link_t *);
+static void avma1cs_detach(struct pcmcia_device *p_dev);
 
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "avma1_cs";
 
 /*
    A linked list of "instances" of the skeleton device.  Each actual
@@ -99,15 +89,7 @@
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -134,26 +116,24 @@
     
 ======================================================================*/
 
-static dev_link_t *avma1cs_attach(void)
+static int avma1cs_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret;
-    
+
     DEBUG(0, "avma1cs_attach()\n");
 
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
     if (!link)
-	return NULL;
+	return -ENOMEM;
     memset(link, 0, sizeof(struct dev_link_t));
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
     if (!local) {
 	kfree(link);
-	return NULL;
+	return -ENOMEM;
     }
     memset(local, 0, sizeof(local_info_t));
     link->priv = local;
@@ -178,20 +158,13 @@
     link->conf.ConfigIndex = 1;
     link->conf.Present = PRESENT_OPTION;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	avma1cs_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    avma1cs_config(link);
+
+    return 0;
 } /* avma1cs_attach */
 
 /*======================================================================
@@ -203,42 +176,17 @@
 
 ======================================================================*/
 
-static void avma1cs_detach(dev_link_t *link)
+static void avma1cs_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "avma1cs_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
 
-    /*
-       If the device is currently configured and active, we won't
-       actually delete it yet.  Instead, it is marked so that when
-       the release() function is called, that will trigger a proper
-       detach().
-    */
-    if (link->state & DEV_CONFIG) {
-#ifdef PCMCIA_DEBUG
-	printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' "
-	       "still locked\n", link->dev->dev_name);
-#endif
-	link->state |= DEV_STALE_LINK;
-	return;
-    }
+    if (link->state & DEV_CONFIG)
+	    avma1cs_release(link);
 
-    /* Break the link with Card Services */
-    if (link->handle)
-    	pcmcia_deregister_client(link->handle);
-    
-    /* Unlink device structure, free pieces */
-    *linkp = link->next;
     kfree(link->priv);
     kfree(link);
-    
 } /* avma1cs_detach */
 
 /*======================================================================
@@ -440,58 +388,30 @@
     pcmcia_release_io(link->handle, &link->io);
     pcmcia_release_irq(link->handle, &link->irq);
     link->state &= ~DEV_CONFIG;
-    
-    if (link->state & DEV_STALE_LINK)
-	avma1cs_detach(link);
 } /* avma1cs_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
-    
-======================================================================*/
-
-static int avma1cs_event(event_t event, int priority,
-			  event_callback_args_t *args)
+static int avma1cs_suspend(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 
-    DEBUG(1, "avma1cs_event(0x%06x)\n", event);
-    
-    switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-	    if (link->state & DEV_CONFIG)
-		avma1cs_release(link);
-	    break;
-	case CS_EVENT_CARD_INSERTION:
-	    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	    avma1cs_config(link);
-	    break;
-	case CS_EVENT_PM_SUSPEND:
-	    link->state |= DEV_SUSPEND;
-	    /* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-	    if (link->state & DEV_CONFIG)
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
 		pcmcia_release_configuration(link->handle);
-	    break;
-	case CS_EVENT_PM_RESUME:
-	    link->state &= ~DEV_SUSPEND;
-	    /* Fall through... */
-	case CS_EVENT_CARD_RESET:
- 	    if (link->state & DEV_CONFIG)
+
+	return 0;
+}
+
+static int avma1cs_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
 		pcmcia_request_configuration(link->handle, &link->conf);
-	    break;
-    }
-    return 0;
-} /* avma1cs_event */
+
+	return 0;
+}
+
 
 static struct pcmcia_device_id avma1cs_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
@@ -505,10 +425,11 @@
 	.drv		= {
 		.name	= "avma1_cs",
 	},
-	.attach		= avma1cs_attach,
-	.event		= avma1cs_event,
-	.detach		= avma1cs_detach,
+	.probe		= avma1cs_attach,
+	.remove		= avma1cs_detach,
 	.id_table	= avma1cs_ids,
+	.suspend	= avma1cs_suspend,
+	.resume		= avma1cs_resume,
 };
  
 /*====================================================================*/
@@ -521,7 +442,6 @@
 static void __exit exit_avma1_cs(void)
 {
 	pcmcia_unregister_driver(&avma1cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_avma1_cs);
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 6fc6868..062fb8f 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -96,8 +96,6 @@
 
 static void elsa_cs_config(dev_link_t *link);
 static void elsa_cs_release(dev_link_t *link);
-static int elsa_cs_event(event_t event, int priority,
-                          event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -105,39 +103,9 @@
    needed to manage one actual PCMCIA card.
 */
 
-static dev_link_t *elsa_cs_attach(void);
-static void elsa_cs_detach(dev_link_t *);
+static void elsa_cs_detach(struct pcmcia_device *p_dev);
 
 /*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "elsa_cs";
-
-/*
-   A linked list of "instances" of the elsa_cs device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-
-   You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
-   device numbers are used to derive the corresponding array index.
-*/
-
-static dev_link_t *dev_list = NULL;
-
-/*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
-   To simplify the data structure handling, we actually include the
-   dev_link_t structure in the device's private data structure.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -171,18 +139,16 @@
 
 ======================================================================*/
 
-static dev_link_t *elsa_cs_attach(void)
+static int elsa_cs_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret;
 
     DEBUG(0, "elsa_cs_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
-    if (!local) return NULL;
+    if (!local) return -ENOMEM;
     memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
     link = &local->link; link->priv = local;
@@ -207,20 +173,13 @@
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-        cs_error(link->handle, RegisterClient, ret);
-        elsa_cs_detach(link);
-        return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    elsa_cs_config(link);
+
+    return 0;
 } /* elsa_cs_attach */
 
 /*======================================================================
@@ -232,32 +191,18 @@
 
 ======================================================================*/
 
-static void elsa_cs_detach(dev_link_t *link)
+static void elsa_cs_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
     local_info_t *info = link->priv;
-    int ret;
 
     DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-        if (*linkp == link) break;
-    if (*linkp == NULL)
-        return;
-
-    if (link->state & DEV_CONFIG)
-        elsa_cs_release(link);
-
-    /* Break the link with Card Services */
-    if (link->handle) {
-        ret = pcmcia_deregister_client(link->handle);
-	if (ret != CS_SUCCESS)
-	    cs_error(link->handle, DeregisterClient, ret);
+    if (link->state & DEV_CONFIG) {
+	    info->busy = 1;
+	    elsa_cs_release(link);
     }
 
-    /* Unlink device structure and free it */
-    *linkp = link->next;
     kfree(info);
 
 } /* elsa_cs_detach */
@@ -447,60 +392,31 @@
     link->state &= ~DEV_CONFIG;
 } /* elsa_cs_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
-
-======================================================================*/
-
-static int elsa_cs_event(event_t event, int priority,
-                          event_callback_args_t *args)
+static int elsa_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    local_info_t *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
 
-    DEBUG(1, "elsa_cs_event(%d)\n", event);
-
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
-        if (link->state & DEV_CONFIG) {
-            ((local_info_t*)link->priv)->busy = 1;
-	    elsa_cs_release(link);
-        }
-        break;
-    case CS_EVENT_CARD_INSERTION:
-        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-        elsa_cs_config(link);
-        break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        /* Mark the device as stopped, to block IO until later */
+	link->state |= DEV_SUSPEND;
         dev->busy = 1;
-        if (link->state & DEV_CONFIG)
-            pcmcia_release_configuration(link->handle);
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG)
-            pcmcia_request_configuration(link->handle, &link->conf);
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int elsa_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
         dev->busy = 0;
-        break;
-    }
-    return 0;
-} /* elsa_cs_event */
+
+	return 0;
+}
 
 static struct pcmcia_device_id elsa_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),
@@ -514,10 +430,11 @@
 	.drv		= {
 		.name	= "elsa_cs",
 	},
-	.attach		= elsa_cs_attach,
-	.event		= elsa_cs_event,
-	.detach		= elsa_cs_detach,
+	.probe		= elsa_cs_attach,
+	.remove		= elsa_cs_detach,
 	.id_table	= elsa_ids,
+	.suspend	= elsa_suspend,
+	.resume		= elsa_resume,
 };
 
 static int __init init_elsa_cs(void)
@@ -528,7 +445,6 @@
 static void __exit exit_elsa_cs(void)
 {
 	pcmcia_unregister_driver(&elsa_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_elsa_cs);
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index f8457ef..ca5b4a3 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -1715,7 +1715,6 @@
 /* our driver information structure */
 /************************************/
 static struct usb_driver hfc_drv = {
-	.owner = THIS_MODULE,
 	.name  = "hfc_usb",
 	.id_table = hfcusb_idtab,
 	.probe = hfc_usb_probe,
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 26c545f..1b85ce1 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -396,17 +396,17 @@
 
 struct hdlc_stat_reg {
 #ifdef __BIG_ENDIAN
-	u_char fill __attribute__((packed));
-	u_char mode __attribute__((packed));
-	u_char xml  __attribute__((packed));
-	u_char cmd  __attribute__((packed));
+	u_char fill;
+	u_char mode;
+	u_char xml;
+	u_char cmd;
 #else
-	u_char cmd  __attribute__((packed));
-	u_char xml  __attribute__((packed));
-	u_char mode __attribute__((packed));
-	u_char fill __attribute__((packed));
+	u_char cmd;
+	u_char xml;
+	u_char mode;
+	u_char fill;
 #endif
-};
+} __attribute__((packed));
 
 struct hdlc_hw {
 	union {
diff --git a/drivers/isdn/hisax/hisax_fcpcipnp.h b/drivers/isdn/hisax/hisax_fcpcipnp.h
index bd8a22e..21fbcedf 100644
--- a/drivers/isdn/hisax/hisax_fcpcipnp.h
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.h
@@ -12,17 +12,17 @@
 
 struct hdlc_stat_reg {
 #ifdef __BIG_ENDIAN
-	u_char fill __attribute__((packed));
-	u_char mode __attribute__((packed));
-	u_char xml  __attribute__((packed));
-	u_char cmd  __attribute__((packed));
+	u_char fill;
+	u_char mode;
+	u_char xml;
+	u_char cmd;
 #else
-	u_char cmd  __attribute__((packed));
-	u_char xml  __attribute__((packed));
-	u_char mode __attribute__((packed));
-	u_char fill __attribute__((packed));
+	u_char cmd;
+	u_char xml;
+	u_char mode;
+	u_char fill;
 #endif
-};
+} __attribute__((packed));
 
 struct fritz_bcs {
 	struct hisax_b_if b_if;
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index dc334aa..6f5213a 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -97,8 +97,6 @@
 
 static void sedlbauer_config(dev_link_t *link);
 static void sedlbauer_release(dev_link_t *link);
-static int sedlbauer_event(event_t event, int priority,
-		       event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -106,8 +104,7 @@
    needed to manage one actual PCMCIA card.
 */
 
-static dev_link_t *sedlbauer_attach(void);
-static void sedlbauer_detach(dev_link_t *);
+static void sedlbauer_detach(struct pcmcia_device *p_dev);
 
 /*
    You'll also need to prototype all the functions that will actually
@@ -117,35 +114,6 @@
 */
 
 /*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "sedlbauer_cs";
-
-/*
-   A linked list of "instances" of the sedlbauer device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-
-   You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
-   device numbers are used to derive the corresponding array index.
-*/
-
-static dev_link_t *dev_list = NULL;
-
-/*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
-   To simplify the data structure handling, we actually include the
-   dev_link_t structure in the device's private data structure.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -180,18 +148,16 @@
     
 ======================================================================*/
 
-static dev_link_t *sedlbauer_attach(void)
+static int sedlbauer_attach(struct pcmcia_device *p_dev)
 {
     local_info_t *local;
     dev_link_t *link;
-    client_reg_t client_reg;
-    int ret;
     
     DEBUG(0, "sedlbauer_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
-    if (!local) return NULL;
+    if (!local) return -ENOMEM;
     memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
     link = &local->link; link->priv = local;
@@ -221,20 +187,13 @@
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	sedlbauer_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    sedlbauer_config(link);
+
+    return 0;
 } /* sedlbauer_attach */
 
 /*======================================================================
@@ -246,39 +205,17 @@
 
 ======================================================================*/
 
-static void sedlbauer_detach(dev_link_t *link)
+static void sedlbauer_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
 
-    /*
-       If the device is currently configured and active, we won't
-       actually delete it yet.  Instead, it is marked so that when
-       the release() function is called, that will trigger a proper
-       detach().
-    */
     if (link->state & DEV_CONFIG) {
-#ifdef PCMCIA_DEBUG
-	printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' "
-	       "still locked\n", link->dev->dev_name);
-#endif
-	link->state |= DEV_STALE_LINK;
-	return;
+	    ((local_info_t *)link->priv)->stop = 1;
+	    sedlbauer_release(link);
     }
 
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
-    /* Unlink device structure, and free it */
-    *linkp = link->next;
     /* This points to the parent local_info_t struct */
     kfree(link->priv);
 } /* sedlbauer_detach */
@@ -547,68 +484,34 @@
     if (link->irq.AssignedIRQ)
 	pcmcia_release_irq(link->handle, &link->irq);
     link->state &= ~DEV_CONFIG;
-    
-    if (link->state & DEV_STALE_LINK)
-	sedlbauer_detach(link);
-    
 } /* sedlbauer_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.
-
-    When a CARD_REMOVAL event is received, we immediately set a
-    private flag to block future accesses to this device.  All the
-    functions that actually access the device should check this flag
-    to make sure the card is still present.
-    
-======================================================================*/
-
-static int sedlbauer_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int sedlbauer_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    local_info_t *dev = link->priv;
-    
-    DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG) {
-	    ((local_info_t *)link->priv)->stop = 1;
-	    sedlbauer_release(link);
-	}
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	sedlbauer_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
+
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	/* Mark the device as stopped, to block IO until later */
 	dev->stop = 1;
 	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int sedlbauer_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG)
-	    pcmcia_request_configuration(link->handle, &link->conf);
+		pcmcia_request_configuration(link->handle, &link->conf);
 	dev->stop = 0;
-	/*
-	  In a normal driver, additional code may go here to restore
-	  the device state and restart IO. 
-	*/
-	break;
-    }
-    return 0;
-} /* sedlbauer_event */
+
+	return 0;
+}
+
 
 static struct pcmcia_device_id sedlbauer_ids[] = {
 	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
@@ -627,10 +530,11 @@
 	.drv		= {
 		.name	= "sedlbauer_cs",
 	},
-	.attach		= sedlbauer_attach,
-	.event		= sedlbauer_event,
-	.detach		= sedlbauer_detach,
+	.probe		= sedlbauer_attach,
+	.remove		= sedlbauer_detach,
 	.id_table	= sedlbauer_ids,
+	.suspend	= sedlbauer_suspend,
+	.resume		= sedlbauer_resume,
 };
 
 static int __init init_sedlbauer_cs(void)
@@ -641,7 +545,6 @@
 static void __exit exit_sedlbauer_cs(void)
 {
 	pcmcia_unregister_driver(&sedlbauer_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_sedlbauer_cs);
diff --git a/drivers/isdn/hisax/st5481_init.c b/drivers/isdn/hisax/st5481_init.c
index 8e192a3..99cb0f3 100644
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -180,7 +180,6 @@
 MODULE_DEVICE_TABLE (usb, st5481_ids);
 
 static struct usb_driver st5481_usb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"st5481_usb",
 	.probe =	probe_st5481,
 	.disconnect =	disconnect_st5481,
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 0ddef1b..4e5c14c 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -77,8 +77,6 @@
 
 static void teles_cs_config(dev_link_t *link);
 static void teles_cs_release(dev_link_t *link);
-static int teles_cs_event(event_t event, int priority,
-                          event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -86,16 +84,7 @@
    needed to manage one actual PCMCIA card.
 */
 
-static dev_link_t *teles_attach(void);
-static void teles_detach(dev_link_t *);
-
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "teles_cs";
+static void teles_detach(struct pcmcia_device *p_dev);
 
 /*
    A linked list of "instances" of the teles_cs device.  Each actual
@@ -107,18 +96,7 @@
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
-   To simplify the data structure handling, we actually include the
-   dev_link_t structure in the device's private data structure.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -152,18 +130,16 @@
 
 ======================================================================*/
 
-static dev_link_t *teles_attach(void)
+static int teles_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     local_info_t *local;
-    int ret;
 
     DEBUG(0, "teles_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
-    if (!local) return NULL;
+    if (!local) return -ENOMEM;
     memset(local, 0, sizeof(local_info_t));
     local->cardnr = -1;
     link = &local->link; link->priv = local;
@@ -188,20 +164,13 @@
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-        cs_error(link->handle, RegisterClient, ret);
-        teles_detach(link);
-        return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    teles_cs_config(link);
+
+    return 0;
 } /* teles_attach */
 
 /*======================================================================
@@ -213,32 +182,18 @@
 
 ======================================================================*/
 
-static void teles_detach(dev_link_t *link)
+static void teles_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
+    dev_link_t *link = dev_to_instance(p_dev);
     local_info_t *info = link->priv;
-    int ret;
 
     DEBUG(0, "teles_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-        if (*linkp == link) break;
-    if (*linkp == NULL)
-        return;
-
-    if (link->state & DEV_CONFIG)
-        teles_cs_release(link);
-
-    /* Break the link with Card Services */
-    if (link->handle) {
-        ret = pcmcia_deregister_client(link->handle);
-	if (ret != CS_SUCCESS)
-	    cs_error(link->handle, DeregisterClient, ret);
+    if (link->state & DEV_CONFIG) {
+	    info->busy = 1;
+	    teles_cs_release(link);
     }
 
-    /* Unlink device structure and free it */
-    *linkp = link->next;
     kfree(info);
 
 } /* teles_detach */
@@ -428,60 +383,32 @@
     link->state &= ~DEV_CONFIG;
 } /* teles_cs_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
-
-======================================================================*/
-
-static int teles_cs_event(event_t event, int priority,
-                          event_callback_args_t *args)
+static int teles_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    local_info_t *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
 
-    DEBUG(1, "teles_cs_event(%d)\n", event);
-
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
-        if (link->state & DEV_CONFIG) {
-            ((local_info_t*)link->priv)->busy = 1;
-	    teles_cs_release(link);
-        }
-        break;
-    case CS_EVENT_CARD_INSERTION:
-        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-        teles_cs_config(link);
-        break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        /* Mark the device as stopped, to block IO until later */
+	link->state |= DEV_SUSPEND;
         dev->busy = 1;
-        if (link->state & DEV_CONFIG)
-            pcmcia_release_configuration(link->handle);
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG)
-            pcmcia_request_configuration(link->handle, &link->conf);
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int teles_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
         dev->busy = 0;
-        break;
-    }
-    return 0;
-} /* teles_cs_event */
+
+	return 0;
+}
+
 
 static struct pcmcia_device_id teles_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119),
@@ -494,10 +421,11 @@
 	.drv		= {
 		.name	= "teles_cs",
 	},
-	.attach		= teles_attach,
-	.event		= teles_cs_event,
-	.detach		= teles_detach,
+	.probe		= teles_attach,
+	.remove		= teles_detach,
 	.id_table       = teles_ids,
+	.suspend	= teles_suspend,
+	.resume		= teles_resume,
 };
 
 static int __init init_teles_cs(void)
@@ -508,7 +436,6 @@
 static void __exit exit_teles_cs(void)
 {
 	pcmcia_unregister_driver(&teles_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_teles_cs);
diff --git a/drivers/isdn/sc/command.c b/drivers/isdn/sc/command.c
index 19f2fcf..b4b2433 100644
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -43,7 +43,6 @@
                 RspMessage *, int);
 extern int sendmessage(int, unsigned int, unsigned int, unsigned int,
                 unsigned int, unsigned int, unsigned int, unsigned int *);
-extern inline void pullphone(char *, char *);
 
 #ifdef DEBUG
 /*
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index c34c96d..228e185 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -128,7 +128,7 @@
 	return 0;
 }
 
-static int macio_hotplug (struct device *dev, char **envp, int num_envp,
+static int macio_uevent(struct device *dev, char **envp, int num_envp,
                           char *buffer, int buffer_size)
 {
 	struct macio_dev * macio_dev;
@@ -203,7 +203,7 @@
 struct bus_type macio_bus_type = {
        .name	= "macio",
        .match	= macio_bus_match,
-       .hotplug = macio_hotplug,
+       .uevent = macio_uevent,
        .suspend	= macio_device_suspend,
        .resume	= macio_device_resume,
        .dev_attrs = macio_dev_attrs,
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index f386966..5ebfd1d 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -52,6 +52,7 @@
 
 static int limit_adjust = 0;
 static int fan_speed = -1;
+static int verbose = 0;
 
 MODULE_AUTHOR("Colin Leroy <colin@colino.net>");
 MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and "
@@ -66,6 +67,10 @@
 MODULE_PARM_DESC(fan_speed,"Specify starting fan speed (0-255) "
 		 "(default 64)");
 
+module_param(verbose, bool, 0);
+MODULE_PARM_DESC(verbose,"Verbose log operations "
+		 "(default 0)");
+
 struct thermostat {
 	struct i2c_client	clt;
 	u8			temps[3];
@@ -149,13 +154,13 @@
 	if (thread_therm != NULL) {
 		kthread_stop(thread_therm);
 	}
-		
+
 	printk(KERN_INFO "adt746x: Putting max temperatures back from "
 			 "%d, %d, %d to %d, %d, %d\n",
 		th->limits[0], th->limits[1], th->limits[2],
 		th->initial_limits[0], th->initial_limits[1],
 		th->initial_limits[2]);
-	
+
 	for (i = 0; i < 3; i++)
 		write_reg(th, LIMIT_REG[i], th->initial_limits[i]);
 
@@ -171,9 +176,9 @@
 }
 
 static struct i2c_driver thermostat_driver = {  
-	.owner		= THIS_MODULE,
-	.name		= "therm_adt746x",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "therm_adt746x",
+	},
 	.attach_adapter	= attach_thermostat,
 	.detach_adapter	= detach_thermostat,
 };
@@ -212,12 +217,14 @@
 		return;
 	
 	if (th->last_speed[fan] != speed) {
-		if (speed == -1)
-			printk(KERN_DEBUG "adt746x: Setting speed to automatic "
-				"for %s fan.\n", sensor_location[fan+1]);
-		else
-			printk(KERN_DEBUG "adt746x: Setting speed to %d "
-				"for %s fan.\n", speed, sensor_location[fan+1]);
+		if (verbose) {
+			if (speed == -1)
+				printk(KERN_DEBUG "adt746x: Setting speed to automatic "
+					"for %s fan.\n", sensor_location[fan+1]);
+			else
+				printk(KERN_DEBUG "adt746x: Setting speed to %d "
+					"for %s fan.\n", speed, sensor_location[fan+1]);
+		}
 	} else
 		return;
 	
@@ -298,10 +305,11 @@
 			if (new_speed > 255)
 				new_speed = 255;
 
-			printk(KERN_DEBUG "adt746x: setting fans speed to %d "
-					 "(limit exceeded by %d on %s) \n",
-					new_speed, var,
-					sensor_location[fan_number+1]);
+			if (verbose)
+				printk(KERN_DEBUG "adt746x: Setting fans speed to %d "
+						 "(limit exceeded by %d on %s) \n",
+						new_speed, var,
+						sensor_location[fan_number+1]);
 			write_both_fan_speed(th, new_speed);
 			th->last_var[fan_number] = var;
 		} else if (var < -2) {
@@ -309,8 +317,9 @@
 			 * so cold (lastvar >= -1) */
 			if (i == 2 && lastvar < -1) {
 				if (th->last_speed[fan_number] != 0)
-					printk(KERN_DEBUG "adt746x: Stopping "
-						"fans.\n");
+					if (verbose)
+						printk(KERN_DEBUG "adt746x: Stopping "
+							"fans.\n");
 				write_both_fan_speed(th, 0);
 			}
 		}
@@ -406,7 +415,7 @@
 		th->initial_limits[i] = read_reg(th, LIMIT_REG[i]);
 		set_limit(th, i);
 	}
-	
+
 	printk(KERN_INFO "adt746x: Lowering max temperatures from %d, %d, %d"
 			 " to %d, %d, %d\n",
 			 th->initial_limits[0], th->initial_limits[1],
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 3fc8cdd..8d0958c 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -283,9 +283,9 @@
 
 static struct i2c_driver therm_pm72_driver =
 {
-	.owner		= THIS_MODULE,
-	.name		= "therm_pm72",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "therm_pm72",
+	},
 	.attach_adapter	= therm_pm72_attach,
 	.detach_adapter	= therm_pm72_detach,
 };
@@ -923,7 +923,7 @@
 	if (temp_combi >= ((state0->mpu.tmax + 8) << 16)) {
 		printk(KERN_WARNING "Warning ! Temperature way above maximum (%d) !\n",
 		       temp_combi >> 16);
-		state0->overtemp = CPU_MAX_OVERTEMP;
+		state0->overtemp += CPU_MAX_OVERTEMP / 4;
 	} else if (temp_combi > (state0->mpu.tmax << 16))
 		state0->overtemp++;
 	else
@@ -933,7 +933,7 @@
 	if (state0->overtemp > 0) {
 		state0->rpm = state0->mpu.rmaxn_exhaust_fan;
 		state0->intake_rpm = intake = state0->mpu.rmaxn_intake_fan;
-		pump = state0->pump_min;
+		pump = state0->pump_max;
 		goto do_set_fans;
 	}
 
@@ -998,7 +998,7 @@
 		printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum"
 		       " (%d) !\n",
 		       state->index, temp >> 16);
-		state->overtemp = CPU_MAX_OVERTEMP;
+		state->overtemp += CPU_MAX_OVERTEMP / 4;
 	} else if (temp > (state->mpu.tmax << 16))
 		state->overtemp++;
 	else
@@ -1060,7 +1060,7 @@
 		printk(KERN_WARNING "Warning ! CPU %d temperature way above maximum"
 		       " (%d) !\n",
 		       state->index, temp >> 16);
-		state->overtemp = CPU_MAX_OVERTEMP;
+		state->overtemp = CPU_MAX_OVERTEMP / 4;
 	} else if (temp > (state->mpu.tmax << 16))
 		state->overtemp++;
 	else
@@ -1988,18 +1988,13 @@
 
 static int fcu_of_probe(struct of_device* dev, const struct of_device_id *match)
 {
-	int rc;
-
 	state = state_detached;
 
 	/* Lookup the fans in the device tree */
 	fcu_lookup_fans(dev->node);
 
 	/* Add the driver */
-	rc = i2c_add_driver(&therm_pm72_driver);
-	if (rc < 0)
-		return rc;
-	return 0;
+	return i2c_add_driver(&therm_pm72_driver);
 }
 
 static int fcu_of_remove(struct of_device* dev)
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 6aaa1df..3d9dd2e 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -354,10 +354,10 @@
 }
 
 static struct i2c_driver g4fan_driver = {  
-	.owner		= THIS_MODULE,
-	.name		= "therm_windtunnel",
+	.driver = {
+		.name	= "therm_windtunnel",
+	},
 	.id		= I2C_DRIVERID_G4FAN,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter = do_attach,
 	.detach_client	= do_detach,
 };
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index a0a41ad..57460e4 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -47,9 +47,9 @@
 static int wf_lm75_detach(struct i2c_client *client);
 
 static struct i2c_driver wf_lm75_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "wf_lm75",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "wf_lm75",
+	},
 	.attach_adapter	= wf_lm75_attach,
 	.detach_client	= wf_lm75_detach,
 };
@@ -240,12 +240,7 @@
 
 static int __init wf_lm75_sensor_init(void)
 {
-	int rc;
-
-	rc = i2c_add_driver(&wf_lm75_driver);
-	if (rc < 0)
-		return rc;
-	return 0;
+	return i2c_add_driver(&wf_lm75_driver);
 }
 
 static void __exit wf_lm75_sensor_exit(void)
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c
index 322c74b2..80ddf97 100644
--- a/drivers/macintosh/windfarm_pm81.c
+++ b/drivers/macintosh/windfarm_pm81.c
@@ -207,7 +207,7 @@
 	},
 	/* Model ID 3 */
 	{
-		.model_id	= 2,
+		.model_id	= 3,
 		.itarget	= 0x350000,
 		.gd		= 0x08e00000,
 		.gp		= 0x00566666,
@@ -219,7 +219,7 @@
 	},
 	/* Model ID 5 */
 	{
-		.model_id	= 2,
+		.model_id	= 5,
 		.itarget	= 0x3a0000,
 		.gd		= 0x15400000,
 		.gp		= 0x00233333,
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c
index 2c3158c..4d81160 100644
--- a/drivers/macintosh/windfarm_smu_controls.c
+++ b/drivers/macintosh/windfarm_smu_controls.c
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/wait.h>
+#include <linux/completion.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c
index b558cc2..1a00d9c 100644
--- a/drivers/macintosh/windfarm_smu_sensors.c
+++ b/drivers/macintosh/windfarm_smu_sensors.c
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/wait.h>
+#include <linux/completion.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
diff --git a/drivers/md/.gitignore b/drivers/md/.gitignore
new file mode 100644
index 0000000..a7afec6
--- /dev/null
+++ b/drivers/md/.gitignore
@@ -0,0 +1,4 @@
+mktables
+raid6altivec*.c
+raid6int*.c
+raid6tables.c
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 252d55d..76a189c 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -315,6 +315,8 @@
 	if (bitmap->file == NULL)
 		return write_sb_page(bitmap->mddev, bitmap->offset, page, wait);
 
+	flush_dcache_page(page); /* make sure visible to anyone reading the file */
+
 	if (wait)
 		lock_page(page);
 	else {
@@ -341,7 +343,7 @@
 		/* add to list to be waited for by daemon */
 		struct page_list *item = mempool_alloc(bitmap->write_pool, GFP_NOIO);
 		item->page = page;
-		page_cache_get(page);
+		get_page(page);
 		spin_lock(&bitmap->write_lock);
 		list_add(&item->list, &bitmap->complete_pages);
 		spin_unlock(&bitmap->write_lock);
@@ -357,10 +359,10 @@
 	struct inode *inode = file->f_mapping->host;
 	struct page *page = NULL;
 	loff_t isize = i_size_read(inode);
-	unsigned long end_index = isize >> PAGE_CACHE_SHIFT;
+	unsigned long end_index = isize >> PAGE_SHIFT;
 
-	PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_CACHE_SIZE,
-			(unsigned long long)index << PAGE_CACHE_SHIFT);
+	PRINTK("read bitmap file (%dB @ %Lu)\n", (int)PAGE_SIZE,
+			(unsigned long long)index << PAGE_SHIFT);
 
 	page = read_cache_page(inode->i_mapping, index,
 			(filler_t *)inode->i_mapping->a_ops->readpage, file);
@@ -368,7 +370,7 @@
 		goto out;
 	wait_on_page_locked(page);
 	if (!PageUptodate(page) || PageError(page)) {
-		page_cache_release(page);
+		put_page(page);
 		page = ERR_PTR(-EIO);
 		goto out;
 	}
@@ -376,14 +378,14 @@
 	if (index > end_index) /* we have read beyond EOF */
 		*bytes_read = 0;
 	else if (index == end_index) /* possible short read */
-		*bytes_read = isize & ~PAGE_CACHE_MASK;
+		*bytes_read = isize & ~PAGE_MASK;
 	else
-		*bytes_read = PAGE_CACHE_SIZE; /* got a full page */
+		*bytes_read = PAGE_SIZE; /* got a full page */
 out:
 	if (IS_ERR(page))
 		printk(KERN_ALERT "md: bitmap read error: (%dB @ %Lu): %ld\n",
-			(int)PAGE_CACHE_SIZE,
-			(unsigned long long)index << PAGE_CACHE_SHIFT,
+			(int)PAGE_SIZE,
+			(unsigned long long)index << PAGE_SHIFT,
 			PTR_ERR(page));
 	return page;
 }
@@ -406,11 +408,11 @@
 		return 0;
 	}
 	spin_unlock_irqrestore(&bitmap->lock, flags);
-	sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+	sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
 	sb->events = cpu_to_le64(bitmap->mddev->events);
 	if (!bitmap->mddev->degraded)
 		sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
-	kunmap(bitmap->sb_page);
+	kunmap_atomic(sb, KM_USER0);
 	return write_page(bitmap, bitmap->sb_page, 1);
 }
 
@@ -421,7 +423,7 @@
 
 	if (!bitmap || !bitmap->sb_page)
 		return;
-	sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+	sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
 	printk(KERN_DEBUG "%s: bitmap file superblock:\n", bmname(bitmap));
 	printk(KERN_DEBUG "         magic: %08x\n", le32_to_cpu(sb->magic));
 	printk(KERN_DEBUG "       version: %d\n", le32_to_cpu(sb->version));
@@ -440,7 +442,7 @@
 	printk(KERN_DEBUG "     sync size: %llu KB\n",
 			(unsigned long long)le64_to_cpu(sb->sync_size)/2);
 	printk(KERN_DEBUG "max write behind: %d\n", le32_to_cpu(sb->write_behind));
-	kunmap(bitmap->sb_page);
+	kunmap_atomic(sb, KM_USER0);
 }
 
 /* read the superblock from the bitmap file and initialize some bitmap fields */
@@ -466,7 +468,7 @@
 		return err;
 	}
 
-	sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+	sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
 
 	if (bytes_read < sizeof(*sb)) { /* short read */
 		printk(KERN_INFO "%s: bitmap file superblock truncated\n",
@@ -485,12 +487,12 @@
 	else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
 		 le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
 		reason = "unrecognized superblock version";
-	else if (chunksize < 512 || chunksize > (1024 * 1024 * 4))
-		reason = "bitmap chunksize out of range (512B - 4MB)";
+	else if (chunksize < PAGE_SIZE)
+		reason = "bitmap chunksize too small";
 	else if ((1 << ffz(~chunksize)) != chunksize)
 		reason = "bitmap chunksize not a power of 2";
-	else if (daemon_sleep < 1 || daemon_sleep > 15)
-		reason = "daemon sleep period out of range (1-15s)";
+	else if (daemon_sleep < 1 || daemon_sleep > MAX_SCHEDULE_TIMEOUT / HZ)
+		reason = "daemon sleep period out of range";
 	else if (write_behind > COUNTER_MAX)
 		reason = "write-behind limit out of range (0 - 16383)";
 	if (reason) {
@@ -535,7 +537,7 @@
 		bitmap->events_cleared = bitmap->mddev->events;
 	err = 0;
 out:
-	kunmap(bitmap->sb_page);
+	kunmap_atomic(sb, KM_USER0);
 	if (err)
 		bitmap_print_sb(bitmap);
 	return err;
@@ -558,9 +560,9 @@
 		spin_unlock_irqrestore(&bitmap->lock, flags);
 		return;
 	}
-	page_cache_get(bitmap->sb_page);
+	get_page(bitmap->sb_page);
 	spin_unlock_irqrestore(&bitmap->lock, flags);
-	sb = (bitmap_super_t *)kmap(bitmap->sb_page);
+	sb = (bitmap_super_t *)kmap_atomic(bitmap->sb_page, KM_USER0);
 	switch (op) {
 		case MASK_SET: sb->state |= bits;
 				break;
@@ -568,8 +570,8 @@
 				break;
 		default: BUG();
 	}
-	kunmap(bitmap->sb_page);
-	page_cache_release(bitmap->sb_page);
+	kunmap_atomic(sb, KM_USER0);
+	put_page(bitmap->sb_page);
 }
 
 /*
@@ -622,12 +624,11 @@
 
 	while (pages--)
 		if (map[pages]->index != 0) /* 0 is sb_page, release it below */
-			page_cache_release(map[pages]);
+			put_page(map[pages]);
 	kfree(map);
 	kfree(attr);
 
-	if (sb_page)
-		page_cache_release(sb_page);
+	safe_put_page(sb_page);
 }
 
 static void bitmap_stop_daemon(struct bitmap *bitmap);
@@ -654,7 +655,7 @@
 
 	while ((item = dequeue_page(bitmap))) {
 		/* don't bother to wait */
-		page_cache_release(item->page);
+		put_page(item->page);
 		mempool_free(item, bitmap->write_pool);
 	}
 
@@ -763,7 +764,7 @@
 
 	/* make sure the page stays cached until it gets written out */
 	if (! (get_page_attr(bitmap, page) & BITMAP_PAGE_DIRTY))
-		page_cache_get(page);
+		get_page(page);
 
  	/* set the bit */
 	kaddr = kmap_atomic(page, KM_USER0);
@@ -854,6 +855,7 @@
 	unsigned long bytes, offset, dummy;
 	int outofdate;
 	int ret = -ENOSPC;
+	void *paddr;
 
 	chunks = bitmap->chunks;
 	file = bitmap->file;
@@ -887,12 +889,10 @@
 	if (!bitmap->filemap)
 		goto out;
 
-	bitmap->filemap_attr = kmalloc(sizeof(long) * num_pages, GFP_KERNEL);
+	bitmap->filemap_attr = kzalloc(sizeof(long) * num_pages, GFP_KERNEL);
 	if (!bitmap->filemap_attr)
 		goto out;
 
-	memset(bitmap->filemap_attr, 0, sizeof(long) * num_pages);
-
 	oldindex = ~0L;
 
 	for (i = 0; i < chunks; i++) {
@@ -901,8 +901,6 @@
 		bit = file_page_offset(i);
 		if (index != oldindex) { /* this is a new page, read it in */
 			/* unmap the old page, we're done with it */
-			if (oldpage != NULL)
-				kunmap(oldpage);
 			if (index == 0) {
 				/*
 				 * if we're here then the superblock page
@@ -925,30 +923,32 @@
 
 			oldindex = index;
 			oldpage = page;
-			kmap(page);
 
 			if (outofdate) {
 				/*
 				 * if bitmap is out of date, dirty the
 			 	 * whole page and write it out
 				 */
-				memset(page_address(page) + offset, 0xff,
+				paddr = kmap_atomic(page, KM_USER0);
+				memset(paddr + offset, 0xff,
 				       PAGE_SIZE - offset);
+				kunmap_atomic(paddr, KM_USER0);
 				ret = write_page(bitmap, page, 1);
 				if (ret) {
-					kunmap(page);
 					/* release, page not in filemap yet */
-					page_cache_release(page);
+					put_page(page);
 					goto out;
 				}
 			}
 
 			bitmap->filemap[bitmap->file_pages++] = page;
 		}
+		paddr = kmap_atomic(page, KM_USER0);
 		if (bitmap->flags & BITMAP_HOSTENDIAN)
-			b = test_bit(bit, page_address(page));
+			b = test_bit(bit, paddr);
 		else
-			b = ext2_test_bit(bit, page_address(page));
+			b = ext2_test_bit(bit, paddr);
+		kunmap_atomic(paddr, KM_USER0);
 		if (b) {
 			/* if the disk bit is set, set the memory bit */
 			bitmap_set_memory_bits(bitmap, i << CHUNK_BLOCK_SHIFT(bitmap),
@@ -963,9 +963,6 @@
 	ret = 0;
 	bitmap_mask_state(bitmap, BITMAP_STALE, MASK_UNSET);
 
-	if (page) /* unmap the last page */
-		kunmap(page);
-
 	if (bit_cnt) { /* Kick recovery if any bits were set */
 		set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery);
 		md_wakeup_thread(bitmap->mddev->thread);
@@ -1021,6 +1018,7 @@
 	int err = 0;
 	int blocks;
 	int attr;
+	void *paddr;
 
 	if (bitmap == NULL)
 		return 0;
@@ -1043,7 +1041,7 @@
 			/* skip this page unless it's marked as needing cleaning */
 			if (!((attr=get_page_attr(bitmap, page)) & BITMAP_PAGE_CLEAN)) {
 				if (attr & BITMAP_PAGE_NEEDWRITE) {
-					page_cache_get(page);
+					get_page(page);
 					clear_page_attr(bitmap, page, BITMAP_PAGE_NEEDWRITE);
 				}
 				spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1057,13 +1055,13 @@
 					default:
 						bitmap_file_kick(bitmap);
 					}
-					page_cache_release(page);
+					put_page(page);
 				}
 				continue;
 			}
 
 			/* grab the new page, sync and release the old */
-			page_cache_get(page);
+			get_page(page);
 			if (lastpage != NULL) {
 				if (get_page_attr(bitmap, lastpage) & BITMAP_PAGE_NEEDWRITE) {
 					clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
@@ -1077,14 +1075,12 @@
 					set_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
 					spin_unlock_irqrestore(&bitmap->lock, flags);
 				}
-				kunmap(lastpage);
-				page_cache_release(lastpage);
+				put_page(lastpage);
 				if (err)
 					bitmap_file_kick(bitmap);
 			} else
 				spin_unlock_irqrestore(&bitmap->lock, flags);
 			lastpage = page;
-			kmap(page);
 /*
 			printk("bitmap clean at page %lu\n", j);
 */
@@ -1107,10 +1103,12 @@
 						  -1);
 
 				/* clear the bit */
+				paddr = kmap_atomic(page, KM_USER0);
 				if (bitmap->flags & BITMAP_HOSTENDIAN)
-					clear_bit(file_page_offset(j), page_address(page));
+					clear_bit(file_page_offset(j), paddr);
 				else
-					ext2_clear_bit(file_page_offset(j), page_address(page));
+					ext2_clear_bit(file_page_offset(j), paddr);
+				kunmap_atomic(paddr, KM_USER0);
 			}
 		}
 		spin_unlock_irqrestore(&bitmap->lock, flags);
@@ -1118,7 +1116,6 @@
 
 	/* now sync the final page */
 	if (lastpage != NULL) {
-		kunmap(lastpage);
 		spin_lock_irqsave(&bitmap->lock, flags);
 		if (get_page_attr(bitmap, lastpage) &BITMAP_PAGE_NEEDWRITE) {
 			clear_page_attr(bitmap, lastpage, BITMAP_PAGE_NEEDWRITE);
@@ -1133,7 +1130,7 @@
 			spin_unlock_irqrestore(&bitmap->lock, flags);
 		}
 
-		page_cache_release(lastpage);
+		put_page(lastpage);
 	}
 
 	return err;
@@ -1184,7 +1181,7 @@
 		PRINTK("finished page writeback: %p\n", page);
 
 		err = PageError(page);
-		page_cache_release(page);
+		put_page(page);
 		if (err) {
 			printk(KERN_WARNING "%s: bitmap file writeback "
 			       "failed (page %lu): %d\n",
@@ -1530,6 +1527,8 @@
 		return;
 
 	mddev->bitmap = NULL; /* disconnect from the md device */
+	if (mddev->thread)
+		mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
 
 	bitmap_free(bitmap);
 }
@@ -1555,12 +1554,10 @@
 
 	BUG_ON(file && mddev->bitmap_offset);
 
-	bitmap = kmalloc(sizeof(*bitmap), GFP_KERNEL);
+	bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL);
 	if (!bitmap)
 		return -ENOMEM;
 
-	memset(bitmap, 0, sizeof(*bitmap));
-
 	spin_lock_init(&bitmap->lock);
 	bitmap->mddev = mddev;
 
@@ -1601,12 +1598,11 @@
 #ifdef INJECT_FATAL_FAULT_1
 	bitmap->bp = NULL;
 #else
-	bitmap->bp = kmalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL);
+	bitmap->bp = kzalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL);
 #endif
 	err = -ENOMEM;
 	if (!bitmap->bp)
 		goto error;
-	memset(bitmap->bp, 0, pages * sizeof(*bitmap->bp));
 
 	bitmap->flags |= BITMAP_ACTIVE;
 
@@ -1636,6 +1632,8 @@
 
 	if (IS_ERR(bitmap->writeback_daemon))
 		return PTR_ERR(bitmap->writeback_daemon);
+	mddev->thread->timeout = bitmap->daemon_sleep * HZ;
+
 	return bitmap_update_sb(bitmap);
 
  error:
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index cf66310..a601a42 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -690,6 +690,8 @@
 bad2:
 	crypto_free_tfm(tfm);
 bad1:
+	/* Must zero key material before freeing */
+	memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
 	kfree(cc);
 	return -EINVAL;
 }
@@ -706,6 +708,9 @@
 		cc->iv_gen_ops->dtr(cc);
 	crypto_free_tfm(cc->tfm);
 	dm_put_device(ti, cc->dev);
+
+	/* Must zero key material before freeing */
+	memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
 	kfree(cc);
 }
 
diff --git a/drivers/md/dm-io.h b/drivers/md/dm-io.h
index 1a77f32..f9035bf 100644
--- a/drivers/md/dm-io.h
+++ b/drivers/md/dm-io.h
@@ -9,9 +9,6 @@
 
 #include "dm.h"
 
-/* FIXME make this configurable */
-#define DM_MAX_IO_REGIONS 8
-
 struct io_region {
 	struct block_device *bdev;
 	sector_t sector;
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 07d44e1..561bda5 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -270,6 +270,7 @@
 {
 	char *new_name, *old_name;
 	struct hash_cell *hc;
+	struct dm_table *table;
 
 	/*
 	 * duplicate new.
@@ -317,6 +318,15 @@
 	/* rename the device node in devfs */
 	register_with_devfs(hc);
 
+	/*
+	 * Wake up any dm event waiters.
+	 */
+	table = dm_get_table(hc->md);
+	if (table) {
+		dm_table_event(table);
+		dm_table_put(table);
+	}
+
 	up_write(&_hash_lock);
 	kfree(old_name);
 	return 0;
@@ -683,14 +693,18 @@
 static int do_suspend(struct dm_ioctl *param)
 {
 	int r = 0;
+	int do_lockfs = 1;
 	struct mapped_device *md;
 
 	md = find_device(param);
 	if (!md)
 		return -ENXIO;
 
+	if (param->flags & DM_SKIP_LOCKFS_FLAG)
+		do_lockfs = 0;
+
 	if (!dm_suspended(md))
-		r = dm_suspend(md);
+		r = dm_suspend(md, do_lockfs);
 
 	if (!r)
 		r = __dev_status(md, param);
@@ -702,6 +716,7 @@
 static int do_resume(struct dm_ioctl *param)
 {
 	int r = 0;
+	int do_lockfs = 1;
 	struct hash_cell *hc;
 	struct mapped_device *md;
 	struct dm_table *new_map;
@@ -727,8 +742,10 @@
 	/* Do we need to load a new map ? */
 	if (new_map) {
 		/* Suspend if it isn't already suspended */
+		if (param->flags & DM_SKIP_LOCKFS_FLAG)
+			do_lockfs = 0;
 		if (!dm_suspended(md))
-			dm_suspend(md);
+			dm_suspend(md, do_lockfs);
 
 		r = dm_swap_table(md, new_map);
 		if (r) {
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index a76349c..efe4adf 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -573,7 +573,7 @@
 					     lc->sync_search);
 		lc->sync_search = *region + 1;
 
-		if (*region == lc->region_count)
+		if (*region >= lc->region_count)
 			return 0;
 
 	} while (log_test_bit(lc->recovering_bits, *region));
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 6b0fc16..6cfa8d4 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -562,6 +562,8 @@
 	region_t nr_regions;
 	int in_sync;
 
+	struct mirror *default_mirror;	/* Default mirror */
+
 	unsigned int nr_mirrors;
 	struct mirror mirror[0];
 };
@@ -611,7 +613,7 @@
 	unsigned long flags = 0;
 
 	/* fill in the source */
-	m = ms->mirror + DEFAULT_MIRROR;
+	m = ms->default_mirror;
 	from.bdev = m->dev->bdev;
 	from.sector = m->offset + region_to_sector(reg->rh, reg->key);
 	if (reg->key == (ms->nr_regions - 1)) {
@@ -627,7 +629,7 @@
 
 	/* fill in the destinations */
 	for (i = 0, dest = to; i < ms->nr_mirrors; i++) {
-		if (i == DEFAULT_MIRROR)
+		if (&ms->mirror[i] == ms->default_mirror)
 			continue;
 
 		m = ms->mirror + i;
@@ -682,7 +684,7 @@
 static struct mirror *choose_mirror(struct mirror_set *ms, sector_t sector)
 {
 	/* FIXME: add read balancing */
-	return ms->mirror + DEFAULT_MIRROR;
+	return ms->default_mirror;
 }
 
 /*
@@ -709,7 +711,7 @@
 		if (rh_in_sync(&ms->rh, region, 0))
 			m = choose_mirror(ms, bio->bi_sector);
 		else
-			m = ms->mirror + DEFAULT_MIRROR;
+			m = ms->default_mirror;
 
 		map_bio(ms, m, bio);
 		generic_make_request(bio);
@@ -833,7 +835,7 @@
 		rh_delay(&ms->rh, bio);
 
 	while ((bio = bio_list_pop(&nosync))) {
-		map_bio(ms, ms->mirror + DEFAULT_MIRROR, bio);
+		map_bio(ms, ms->default_mirror, bio);
 		generic_make_request(bio);
 	}
 }
@@ -900,6 +902,7 @@
 	ms->nr_mirrors = nr_mirrors;
 	ms->nr_regions = dm_sector_div_up(ti->len, region_size);
 	ms->in_sync = 0;
+	ms->default_mirror = &ms->mirror[DEFAULT_MIRROR];
 
 	if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) {
 		ti->error = "dm-mirror: Error creating dirty region hash";
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index ab54f99..4b9dd8f 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -371,6 +371,20 @@
 	return (n + size) & ~size;
 }
 
+static void read_snapshot_metadata(struct dm_snapshot *s)
+{
+	if (s->have_metadata)
+		return;
+
+	if (s->store.read_metadata(&s->store)) {
+		down_write(&s->lock);
+		s->valid = 0;
+		up_write(&s->lock);
+	}
+
+	s->have_metadata = 1;
+}
+
 /*
  * Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
  */
@@ -848,16 +862,7 @@
 {
 	struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
 
-	if (s->have_metadata)
-		return;
-
-	if (s->store.read_metadata(&s->store)) {
-		down_write(&s->lock);
-		s->valid = 0;
-		up_write(&s->lock);
-	}
-
-	s->have_metadata = 1;
+	read_snapshot_metadata(s);
 }
 
 static int snapshot_status(struct dm_target *ti, status_type_t type,
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index a6d3baa..a6f2dc6 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -638,7 +638,7 @@
 static void check_for_valid_limits(struct io_restrictions *rs)
 {
 	if (!rs->max_sectors)
-		rs->max_sectors = MAX_SECTORS;
+		rs->max_sectors = SAFE_MAX_SECTORS;
 	if (!rs->max_phys_segments)
 		rs->max_phys_segments = MAX_PHYS_SEGMENTS;
 	if (!rs->max_hw_segments)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 930b9fc..0e48151 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -55,6 +55,7 @@
  */
 #define DMF_BLOCK_IO 0
 #define DMF_SUSPENDED 1
+#define DMF_FROZEN 2
 
 struct mapped_device {
 	struct rw_semaphore io_lock;
@@ -97,7 +98,7 @@
 	 * freeze/thaw support require holding onto a super block
 	 */
 	struct super_block *frozen_sb;
-	struct block_device *frozen_bdev;
+	struct block_device *suspended_bdev;
 };
 
 #define MIN_IOS 256
@@ -836,9 +837,9 @@
 {
 	set_capacity(md->disk, size);
 
-	down(&md->frozen_bdev->bd_inode->i_sem);
-	i_size_write(md->frozen_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
-	up(&md->frozen_bdev->bd_inode->i_sem);
+	down(&md->suspended_bdev->bd_inode->i_sem);
+	i_size_write(md->suspended_bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
+	up(&md->suspended_bdev->bd_inode->i_sem);
 }
 
 static int __bind(struct mapped_device *md, struct dm_table *t)
@@ -902,10 +903,9 @@
 	return create_aux(minor, 1, result);
 }
 
-void *dm_get_mdptr(dev_t dev)
+static struct mapped_device *dm_find_md(dev_t dev)
 {
 	struct mapped_device *md;
-	void *mdptr = NULL;
 	unsigned minor = MINOR(dev);
 
 	if (MAJOR(dev) != _major || minor >= (1 << MINORBITS))
@@ -914,12 +914,32 @@
 	down(&_minor_lock);
 
 	md = idr_find(&_minor_idr, minor);
-
-	if (md && (dm_disk(md)->first_minor == minor))
-		mdptr = md->interface_ptr;
+	if (!md || (dm_disk(md)->first_minor != minor))
+		md = NULL;
 
 	up(&_minor_lock);
 
+	return md;
+}
+
+struct mapped_device *dm_get_md(dev_t dev)
+{
+	struct mapped_device *md = dm_find_md(dev);
+
+	if (md)
+		dm_get(md);
+
+	return md;
+}
+
+void *dm_get_mdptr(dev_t dev)
+{
+	struct mapped_device *md;
+	void *mdptr = NULL;
+
+	md = dm_find_md(dev);
+	if (md)
+		mdptr = md->interface_ptr;
 	return mdptr;
 }
 
@@ -991,43 +1011,33 @@
  */
 static int lock_fs(struct mapped_device *md)
 {
-	int r = -ENOMEM;
-
-	md->frozen_bdev = bdget_disk(md->disk, 0);
-	if (!md->frozen_bdev) {
-		DMWARN("bdget failed in lock_fs");
-		goto out;
-	}
+	int r;
 
 	WARN_ON(md->frozen_sb);
 
-	md->frozen_sb = freeze_bdev(md->frozen_bdev);
+	md->frozen_sb = freeze_bdev(md->suspended_bdev);
 	if (IS_ERR(md->frozen_sb)) {
 		r = PTR_ERR(md->frozen_sb);
-		goto out_bdput;
+		md->frozen_sb = NULL;
+		return r;
 	}
 
+	set_bit(DMF_FROZEN, &md->flags);
+
 	/* don't bdput right now, we don't want the bdev
-	 * to go away while it is locked.  We'll bdput
-	 * in unlock_fs
+	 * to go away while it is locked.
 	 */
 	return 0;
-
-out_bdput:
-	bdput(md->frozen_bdev);
-	md->frozen_sb = NULL;
-	md->frozen_bdev = NULL;
-out:
-	return r;
 }
 
 static void unlock_fs(struct mapped_device *md)
 {
-	thaw_bdev(md->frozen_bdev, md->frozen_sb);
-	bdput(md->frozen_bdev);
+	if (!test_bit(DMF_FROZEN, &md->flags))
+		return;
 
+	thaw_bdev(md->suspended_bdev, md->frozen_sb);
 	md->frozen_sb = NULL;
-	md->frozen_bdev = NULL;
+	clear_bit(DMF_FROZEN, &md->flags);
 }
 
 /*
@@ -1037,7 +1047,7 @@
  * dm_bind_table, dm_suspend must be called to flush any in
  * flight bios and ensure that any further io gets deferred.
  */
-int dm_suspend(struct mapped_device *md)
+int dm_suspend(struct mapped_device *md, int do_lockfs)
 {
 	struct dm_table *map = NULL;
 	DECLARE_WAITQUEUE(wait, current);
@@ -1053,10 +1063,19 @@
 	/* This does not get reverted if there's an error later. */
 	dm_table_presuspend_targets(map);
 
-	/* Flush I/O to the device. */
-	r = lock_fs(md);
-	if (r)
+	md->suspended_bdev = bdget_disk(md->disk, 0);
+	if (!md->suspended_bdev) {
+		DMWARN("bdget failed in dm_suspend");
+		r = -ENOMEM;
 		goto out;
+	}
+
+	/* Flush I/O to the device. */
+	if (do_lockfs) {
+		r = lock_fs(md);
+		if (r)
+			goto out;
+	}
 
 	/*
 	 * First we set the BLOCK_IO flag so no more ios will be mapped.
@@ -1105,6 +1124,11 @@
 	r = 0;
 
 out:
+	if (r && md->suspended_bdev) {
+		bdput(md->suspended_bdev);
+		md->suspended_bdev = NULL;
+	}
+
 	dm_table_put(map);
 	up(&md->suspend_lock);
 	return r;
@@ -1135,6 +1159,9 @@
 
 	unlock_fs(md);
 
+	bdput(md->suspended_bdev);
+	md->suspended_bdev = NULL;
+
 	clear_bit(DMF_SUSPENDED, &md->flags);
 
 	dm_table_unplug_all(map);
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index e38c3fc..4eaf075 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -28,7 +28,7 @@
  * in types.h.
  */
 #ifdef CONFIG_LBD
-#define SECTOR_FORMAT "%Lu"
+#define SECTOR_FORMAT "%llu"
 #else
 #define SECTOR_FORMAT "%lu"
 #endif
@@ -58,6 +58,7 @@
 int dm_create_with_minor(unsigned int minor, struct mapped_device **md);
 void dm_set_mdptr(struct mapped_device *md, void *ptr);
 void *dm_get_mdptr(dev_t dev);
+struct mapped_device *dm_get_md(dev_t dev);
 
 /*
  * Reference counting for md.
@@ -68,7 +69,7 @@
 /*
  * A device can still be used while suspended, but I/O is deferred.
  */
-int dm_suspend(struct mapped_device *md);
+int dm_suspend(struct mapped_device *md, int with_lockfs);
 int dm_resume(struct mapped_device *md);
 
 /*
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 0248f8e..a7a5ab5 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -316,9 +316,10 @@
 	return 0;
 }
 
-static mdk_personality_t faulty_personality =
+static struct mdk_personality faulty_personality =
 {
 	.name		= "faulty",
+	.level		= LEVEL_FAULTY,
 	.owner		= THIS_MODULE,
 	.make_request	= make_request,
 	.run		= run,
@@ -329,15 +330,17 @@
 
 static int __init raid_init(void)
 {
-	return register_md_personality(FAULTY, &faulty_personality);
+	return register_md_personality(&faulty_personality);
 }
 
 static void raid_exit(void)
 {
-	unregister_md_personality(FAULTY);
+	unregister_md_personality(&faulty_personality);
 }
 
 module_init(raid_init);
 module_exit(raid_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("md-personality-10"); /* faulty */
+MODULE_ALIAS("md-faulty");
+MODULE_ALIAS("md-level--5");
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
index eb70364..ca99979 100644
--- a/drivers/md/kcopyd.c
+++ b/drivers/md/kcopyd.c
@@ -561,11 +561,13 @@
  * Cancels a kcopyd job, eg. someone might be deactivating a
  * mirror.
  */
+#if 0
 int kcopyd_cancel(struct kcopyd_job *job, int block)
 {
 	/* FIXME: finish */
 	return -1;
 }
+#endif  /*  0  */
 
 /*-----------------------------------------------------------------
  * Unit setup
@@ -684,4 +686,3 @@
 EXPORT_SYMBOL(kcopyd_client_create);
 EXPORT_SYMBOL(kcopyd_client_destroy);
 EXPORT_SYMBOL(kcopyd_copy);
-EXPORT_SYMBOL(kcopyd_cancel);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 946efef..7775854 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -121,11 +121,10 @@
 	sector_t curr_offset;
 	struct list_head *tmp;
 
-	conf = kmalloc (sizeof (*conf) + mddev->raid_disks*sizeof(dev_info_t),
+	conf = kzalloc (sizeof (*conf) + mddev->raid_disks*sizeof(dev_info_t),
 			GFP_KERNEL);
 	if (!conf)
 		goto out;
-	memset(conf, 0, sizeof(*conf) + mddev->raid_disks*sizeof(dev_info_t));
 	mddev->private = conf;
 
 	cnt = 0;
@@ -352,9 +351,10 @@
 }
 
 
-static mdk_personality_t linear_personality=
+static struct mdk_personality linear_personality =
 {
 	.name		= "linear",
+	.level		= LEVEL_LINEAR,
 	.owner		= THIS_MODULE,
 	.make_request	= linear_make_request,
 	.run		= linear_run,
@@ -364,16 +364,18 @@
 
 static int __init linear_init (void)
 {
-	return register_md_personality (LINEAR, &linear_personality);
+	return register_md_personality (&linear_personality);
 }
 
 static void linear_exit (void)
 {
-	unregister_md_personality (LINEAR);
+	unregister_md_personality (&linear_personality);
 }
 
 
 module_init(linear_init);
 module_exit(linear_exit);
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("md-personality-1"); /* LINEAR */
+MODULE_ALIAS("md-personality-1"); /* LINEAR - deprecated*/
+MODULE_ALIAS("md-linear");
+MODULE_ALIAS("md-level--1");
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 78c7418..e423a16 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -42,6 +42,7 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/buffer_head.h> /* for invalidate_bdev */
 #include <linux/suspend.h>
+#include <linux/poll.h>
 
 #include <linux/init.h>
 
@@ -67,7 +68,7 @@
 static void autostart_arrays (int part);
 #endif
 
-static mdk_personality_t *pers[MAX_PERSONALITY];
+static LIST_HEAD(pers_list);
 static DEFINE_SPINLOCK(pers_lock);
 
 /*
@@ -80,10 +81,22 @@
  * idle IO detection.
  *
  * you can change it via /proc/sys/dev/raid/speed_limit_min and _max.
+ * or /sys/block/mdX/md/sync_speed_{min,max}
  */
 
 static int sysctl_speed_limit_min = 1000;
 static int sysctl_speed_limit_max = 200000;
+static inline int speed_min(mddev_t *mddev)
+{
+	return mddev->sync_speed_min ?
+		mddev->sync_speed_min : sysctl_speed_limit_min;
+}
+
+static inline int speed_max(mddev_t *mddev)
+{
+	return mddev->sync_speed_max ?
+		mddev->sync_speed_max : sysctl_speed_limit_max;
+}
 
 static struct ctl_table_header *raid_table_header;
 
@@ -134,6 +147,24 @@
 static int start_readonly;
 
 /*
+ * We have a system wide 'event count' that is incremented
+ * on any 'interesting' event, and readers of /proc/mdstat
+ * can use 'poll' or 'select' to find out when the event
+ * count increases.
+ *
+ * Events are:
+ *  start array, stop array, error, add device, remove device,
+ *  start build, activate spare
+ */
+static DECLARE_WAIT_QUEUE_HEAD(md_event_waiters);
+static atomic_t md_event_count;
+static void md_new_event(mddev_t *mddev)
+{
+	atomic_inc(&md_event_count);
+	wake_up(&md_event_waiters);
+}
+
+/*
  * Enables to iterate over all existing md arrays
  * all_mddevs_lock protects this list.
  */
@@ -209,12 +240,10 @@
 	}
 	spin_unlock(&all_mddevs_lock);
 
-	new = (mddev_t *) kmalloc(sizeof(*new), GFP_KERNEL);
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
 	if (!new)
 		return NULL;
 
-	memset(new, 0, sizeof(*new));
-
 	new->unit = unit;
 	if (MAJOR(unit) == MD_MAJOR)
 		new->md_minor = MINOR(unit);
@@ -262,7 +291,7 @@
 	md_wakeup_thread(mddev->thread);
 }
 
-mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
+static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
 {
 	mdk_rdev_t * rdev;
 	struct list_head *tmp;
@@ -286,6 +315,18 @@
 	return NULL;
 }
 
+static struct mdk_personality *find_pers(int level, char *clevel)
+{
+	struct mdk_personality *pers;
+	list_for_each_entry(pers, &pers_list, list) {
+		if (level != LEVEL_NONE && pers->level == level)
+			return pers;
+		if (strcmp(pers->name, clevel)==0)
+			return pers;
+	}
+	return NULL;
+}
+
 static inline sector_t calc_dev_sboffset(struct block_device *bdev)
 {
 	sector_t size = bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
@@ -320,7 +361,7 @@
 static void free_disk_sb(mdk_rdev_t * rdev)
 {
 	if (rdev->sb_page) {
-		page_cache_release(rdev->sb_page);
+		put_page(rdev->sb_page);
 		rdev->sb_loaded = 0;
 		rdev->sb_page = NULL;
 		rdev->sb_offset = 0;
@@ -461,6 +502,7 @@
 	bio_put(bio);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(sync_page_io);
 
 static int read_disk_sb(mdk_rdev_t * rdev, int size)
 {
@@ -665,6 +707,10 @@
 	}
 	rdev->size = calc_dev_size(rdev, sb->chunk_size);
 
+	if (rdev->size < sb->size && sb->level > 1)
+		/* "this cannot possibly happen" ... */
+		ret = -EINVAL;
+
  abort:
 	return ret;
 }
@@ -688,6 +734,7 @@
 		mddev->ctime = sb->ctime;
 		mddev->utime = sb->utime;
 		mddev->level = sb->level;
+		mddev->clevel[0] = 0;
 		mddev->layout = sb->layout;
 		mddev->raid_disks = sb->raid_disks;
 		mddev->size = sb->size;
@@ -714,9 +761,10 @@
 
 		if (sb->state & (1<<MD_SB_BITMAP_PRESENT) &&
 		    mddev->bitmap_file == NULL) {
-			if (mddev->level != 1 && mddev->level != 5 && mddev->level != 6) {
+			if (mddev->level != 1 && mddev->level != 5 && mddev->level != 6
+			    && mddev->level != 10) {
 				/* FIXME use a better test */
-				printk(KERN_WARNING "md: bitmaps only support for raid1\n");
+				printk(KERN_WARNING "md: bitmaps not supported for this level.\n");
 				return -EINVAL;
 			}
 			mddev->bitmap_offset = mddev->default_bitmap_offset;
@@ -968,6 +1016,7 @@
 	}
 	rdev->preferred_minor = 0xffff;
 	rdev->data_offset = le64_to_cpu(sb->data_offset);
+	atomic_set(&rdev->corrected_errors, le32_to_cpu(sb->cnt_corrected_read));
 
 	rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256;
 	bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1;
@@ -1006,6 +1055,9 @@
 	rdev->size = le64_to_cpu(sb->data_size)/2;
 	if (le32_to_cpu(sb->chunksize))
 		rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
+
+	if (le32_to_cpu(sb->size) > rdev->size*2)
+		return -EINVAL;
 	return 0;
 }
 
@@ -1023,12 +1075,12 @@
 		mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1);
 		mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1);
 		mddev->level = le32_to_cpu(sb->level);
+		mddev->clevel[0] = 0;
 		mddev->layout = le32_to_cpu(sb->layout);
 		mddev->raid_disks = le32_to_cpu(sb->raid_disks);
 		mddev->size = le64_to_cpu(sb->size)/2;
 		mddev->events = le64_to_cpu(sb->events);
 		mddev->bitmap_offset = 0;
-		mddev->default_bitmap_offset = 0;
 		mddev->default_bitmap_offset = 1024;
 		
 		mddev->recovery_cp = le64_to_cpu(sb->resync_offset);
@@ -1038,8 +1090,9 @@
 
 		if ((le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) &&
 		    mddev->bitmap_file == NULL ) {
-			if (mddev->level != 1) {
-				printk(KERN_WARNING "md: bitmaps only supported for raid1\n");
+			if (mddev->level != 1 && mddev->level != 5 && mddev->level != 6
+			    && mddev->level != 10) {
+				printk(KERN_WARNING "md: bitmaps not supported for this level.\n");
 				return -EINVAL;
 			}
 			mddev->bitmap_offset = (__s32)le32_to_cpu(sb->bitmap_offset);
@@ -1106,6 +1159,8 @@
 	else
 		sb->resync_offset = cpu_to_le64(0);
 
+	sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors);
+
 	if (mddev->bitmap && mddev->bitmap_file == NULL) {
 		sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
 		sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
@@ -1188,6 +1243,14 @@
 		MD_BUG();
 		return -EINVAL;
 	}
+	/* make sure rdev->size exceeds mddev->size */
+	if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
+		if (mddev->pers)
+			/* Cannot change size, so fail */
+			return -ENOSPC;
+		else
+			mddev->size = rdev->size;
+	}
 	same_pdev = match_dev_unit(mddev, rdev);
 	if (same_pdev)
 		printk(KERN_WARNING
@@ -1497,6 +1560,26 @@
 
 }
 
+/* words written to sysfs files may, or my not, be \n terminated.
+ * We want to accept with case. For this we use cmd_match.
+ */
+static int cmd_match(const char *cmd, const char *str)
+{
+	/* See if cmd, written into a sysfs file, matches
+	 * str.  They must either be the same, or cmd can
+	 * have a trailing newline
+	 */
+	while (*cmd && *str && *cmd == *str) {
+		cmd++;
+		str++;
+	}
+	if (*cmd == '\n')
+		cmd++;
+	if (*str || *cmd)
+		return 0;
+	return 1;
+}
+
 struct rdev_sysfs_entry {
 	struct attribute attr;
 	ssize_t (*show)(mdk_rdev_t *, char *);
@@ -1539,9 +1622,113 @@
 }
 static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super);
 
+static ssize_t
+errors_show(mdk_rdev_t *rdev, char *page)
+{
+	return sprintf(page, "%d\n", atomic_read(&rdev->corrected_errors));
+}
+
+static ssize_t
+errors_store(mdk_rdev_t *rdev, const char *buf, size_t len)
+{
+	char *e;
+	unsigned long n = simple_strtoul(buf, &e, 10);
+	if (*buf && (*e == 0 || *e == '\n')) {
+		atomic_set(&rdev->corrected_errors, n);
+		return len;
+	}
+	return -EINVAL;
+}
+static struct rdev_sysfs_entry rdev_errors =
+__ATTR(errors, 0644, errors_show, errors_store);
+
+static ssize_t
+slot_show(mdk_rdev_t *rdev, char *page)
+{
+	if (rdev->raid_disk < 0)
+		return sprintf(page, "none\n");
+	else
+		return sprintf(page, "%d\n", rdev->raid_disk);
+}
+
+static ssize_t
+slot_store(mdk_rdev_t *rdev, const char *buf, size_t len)
+{
+	char *e;
+	int slot = simple_strtoul(buf, &e, 10);
+	if (strncmp(buf, "none", 4)==0)
+		slot = -1;
+	else if (e==buf || (*e && *e!= '\n'))
+		return -EINVAL;
+	if (rdev->mddev->pers)
+		/* Cannot set slot in active array (yet) */
+		return -EBUSY;
+	if (slot >= rdev->mddev->raid_disks)
+		return -ENOSPC;
+	rdev->raid_disk = slot;
+	/* assume it is working */
+	rdev->flags = 0;
+	set_bit(In_sync, &rdev->flags);
+	return len;
+}
+
+
+static struct rdev_sysfs_entry rdev_slot =
+__ATTR(slot, 0644, slot_show, slot_store);
+
+static ssize_t
+offset_show(mdk_rdev_t *rdev, char *page)
+{
+	return sprintf(page, "%llu\n", (unsigned long long)rdev->data_offset);
+}
+
+static ssize_t
+offset_store(mdk_rdev_t *rdev, const char *buf, size_t len)
+{
+	char *e;
+	unsigned long long offset = simple_strtoull(buf, &e, 10);
+	if (e==buf || (*e && *e != '\n'))
+		return -EINVAL;
+	if (rdev->mddev->pers)
+		return -EBUSY;
+	rdev->data_offset = offset;
+	return len;
+}
+
+static struct rdev_sysfs_entry rdev_offset =
+__ATTR(offset, 0644, offset_show, offset_store);
+
+static ssize_t
+rdev_size_show(mdk_rdev_t *rdev, char *page)
+{
+	return sprintf(page, "%llu\n", (unsigned long long)rdev->size);
+}
+
+static ssize_t
+rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
+{
+	char *e;
+	unsigned long long size = simple_strtoull(buf, &e, 10);
+	if (e==buf || (*e && *e != '\n'))
+		return -EINVAL;
+	if (rdev->mddev->pers)
+		return -EBUSY;
+	rdev->size = size;
+	if (size < rdev->mddev->size || rdev->mddev->size == 0)
+		rdev->mddev->size = size;
+	return len;
+}
+
+static struct rdev_sysfs_entry rdev_size =
+__ATTR(size, 0644, rdev_size_show, rdev_size_store);
+
 static struct attribute *rdev_default_attrs[] = {
 	&rdev_state.attr,
 	&rdev_super.attr,
+	&rdev_errors.attr,
+	&rdev_slot.attr,
+	&rdev_offset.attr,
+	&rdev_size.attr,
 	NULL,
 };
 static ssize_t
@@ -1599,12 +1786,11 @@
 	mdk_rdev_t *rdev;
 	sector_t size;
 
-	rdev = (mdk_rdev_t *) kmalloc(sizeof(*rdev), GFP_KERNEL);
+	rdev = kzalloc(sizeof(*rdev), GFP_KERNEL);
 	if (!rdev) {
 		printk(KERN_ERR "md: could not alloc mem for new device!\n");
 		return ERR_PTR(-ENOMEM);
 	}
-	memset(rdev, 0, sizeof(*rdev));
 
 	if ((err = alloc_disk_sb(rdev)))
 		goto abort_free;
@@ -1622,6 +1808,7 @@
 	rdev->data_offset = 0;
 	atomic_set(&rdev->nr_pending, 0);
 	atomic_set(&rdev->read_errors, 0);
+	atomic_set(&rdev->corrected_errors, 0);
 
 	size = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
 	if (!size) {
@@ -1726,16 +1913,37 @@
 static ssize_t
 level_show(mddev_t *mddev, char *page)
 {
-	mdk_personality_t *p = mddev->pers;
-	if (p == NULL && mddev->raid_disks == 0)
-		return 0;
-	if (mddev->level >= 0)
-		return sprintf(page, "RAID-%d\n", mddev->level);
-	else
+	struct mdk_personality *p = mddev->pers;
+	if (p)
 		return sprintf(page, "%s\n", p->name);
+	else if (mddev->clevel[0])
+		return sprintf(page, "%s\n", mddev->clevel);
+	else if (mddev->level != LEVEL_NONE)
+		return sprintf(page, "%d\n", mddev->level);
+	else
+		return 0;
 }
 
-static struct md_sysfs_entry md_level = __ATTR_RO(level);
+static ssize_t
+level_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	int rv = len;
+	if (mddev->pers)
+		return -EBUSY;
+	if (len == 0)
+		return 0;
+	if (len >= sizeof(mddev->clevel))
+		return -ENOSPC;
+	strncpy(mddev->clevel, buf, len);
+	if (mddev->clevel[len-1] == '\n')
+		len--;
+	mddev->clevel[len] = 0;
+	mddev->level = LEVEL_NONE;
+	return rv;
+}
+
+static struct md_sysfs_entry md_level =
+__ATTR(level, 0644, level_show, level_store);
 
 static ssize_t
 raid_disks_show(mddev_t *mddev, char *page)
@@ -1745,7 +1953,197 @@
 	return sprintf(page, "%d\n", mddev->raid_disks);
 }
 
-static struct md_sysfs_entry md_raid_disks = __ATTR_RO(raid_disks);
+static int update_raid_disks(mddev_t *mddev, int raid_disks);
+
+static ssize_t
+raid_disks_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	/* can only set raid_disks if array is not yet active */
+	char *e;
+	int rv = 0;
+	unsigned long n = simple_strtoul(buf, &e, 10);
+
+	if (!*buf || (*e && *e != '\n'))
+		return -EINVAL;
+
+	if (mddev->pers)
+		rv = update_raid_disks(mddev, n);
+	else
+		mddev->raid_disks = n;
+	return rv ? rv : len;
+}
+static struct md_sysfs_entry md_raid_disks =
+__ATTR(raid_disks, 0644, raid_disks_show, raid_disks_store);
+
+static ssize_t
+chunk_size_show(mddev_t *mddev, char *page)
+{
+	return sprintf(page, "%d\n", mddev->chunk_size);
+}
+
+static ssize_t
+chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	/* can only set chunk_size if array is not yet active */
+	char *e;
+	unsigned long n = simple_strtoul(buf, &e, 10);
+
+	if (mddev->pers)
+		return -EBUSY;
+	if (!*buf || (*e && *e != '\n'))
+		return -EINVAL;
+
+	mddev->chunk_size = n;
+	return len;
+}
+static struct md_sysfs_entry md_chunk_size =
+__ATTR(chunk_size, 0644, chunk_size_show, chunk_size_store);
+
+static ssize_t
+null_show(mddev_t *mddev, char *page)
+{
+	return -EINVAL;
+}
+
+static ssize_t
+new_dev_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	/* buf must be %d:%d\n? giving major and minor numbers */
+	/* The new device is added to the array.
+	 * If the array has a persistent superblock, we read the
+	 * superblock to initialise info and check validity.
+	 * Otherwise, only checking done is that in bind_rdev_to_array,
+	 * which mainly checks size.
+	 */
+	char *e;
+	int major = simple_strtoul(buf, &e, 10);
+	int minor;
+	dev_t dev;
+	mdk_rdev_t *rdev;
+	int err;
+
+	if (!*buf || *e != ':' || !e[1] || e[1] == '\n')
+		return -EINVAL;
+	minor = simple_strtoul(e+1, &e, 10);
+	if (*e && *e != '\n')
+		return -EINVAL;
+	dev = MKDEV(major, minor);
+	if (major != MAJOR(dev) ||
+	    minor != MINOR(dev))
+		return -EOVERFLOW;
+
+
+	if (mddev->persistent) {
+		rdev = md_import_device(dev, mddev->major_version,
+					mddev->minor_version);
+		if (!IS_ERR(rdev) && !list_empty(&mddev->disks)) {
+			mdk_rdev_t *rdev0 = list_entry(mddev->disks.next,
+						       mdk_rdev_t, same_set);
+			err = super_types[mddev->major_version]
+				.load_super(rdev, rdev0, mddev->minor_version);
+			if (err < 0)
+				goto out;
+		}
+	} else
+		rdev = md_import_device(dev, -1, -1);
+
+	if (IS_ERR(rdev))
+		return PTR_ERR(rdev);
+	err = bind_rdev_to_array(rdev, mddev);
+ out:
+	if (err)
+		export_rdev(rdev);
+	return err ? err : len;
+}
+
+static struct md_sysfs_entry md_new_device =
+__ATTR(new_dev, 0200, null_show, new_dev_store);
+
+static ssize_t
+size_show(mddev_t *mddev, char *page)
+{
+	return sprintf(page, "%llu\n", (unsigned long long)mddev->size);
+}
+
+static int update_size(mddev_t *mddev, unsigned long size);
+
+static ssize_t
+size_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	/* If array is inactive, we can reduce the component size, but
+	 * not increase it (except from 0).
+	 * If array is active, we can try an on-line resize
+	 */
+	char *e;
+	int err = 0;
+	unsigned long long size = simple_strtoull(buf, &e, 10);
+	if (!*buf || *buf == '\n' ||
+	    (*e && *e != '\n'))
+		return -EINVAL;
+
+	if (mddev->pers) {
+		err = update_size(mddev, size);
+		md_update_sb(mddev);
+	} else {
+		if (mddev->size == 0 ||
+		    mddev->size > size)
+			mddev->size = size;
+		else
+			err = -ENOSPC;
+	}
+	return err ? err : len;
+}
+
+static struct md_sysfs_entry md_size =
+__ATTR(component_size, 0644, size_show, size_store);
+
+
+/* Metdata version.
+ * This is either 'none' for arrays with externally managed metadata,
+ * or N.M for internally known formats
+ */
+static ssize_t
+metadata_show(mddev_t *mddev, char *page)
+{
+	if (mddev->persistent)
+		return sprintf(page, "%d.%d\n",
+			       mddev->major_version, mddev->minor_version);
+	else
+		return sprintf(page, "none\n");
+}
+
+static ssize_t
+metadata_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	int major, minor;
+	char *e;
+	if (!list_empty(&mddev->disks))
+		return -EBUSY;
+
+	if (cmd_match(buf, "none")) {
+		mddev->persistent = 0;
+		mddev->major_version = 0;
+		mddev->minor_version = 90;
+		return len;
+	}
+	major = simple_strtoul(buf, &e, 10);
+	if (e==buf || *e != '.')
+		return -EINVAL;
+	buf = e+1;
+	minor = simple_strtoul(buf, &e, 10);
+	if (e==buf || *e != '\n')
+		return -EINVAL;
+	if (major >= sizeof(super_types)/sizeof(super_types[0]) ||
+	    super_types[major].name == NULL)
+		return -ENOENT;
+	mddev->major_version = major;
+	mddev->minor_version = minor;
+	mddev->persistent = 1;
+	return len;
+}
+
+static struct md_sysfs_entry md_metadata =
+__ATTR(metadata_version, 0644, metadata_show, metadata_store);
 
 static ssize_t
 action_show(mddev_t *mddev, char *page)
@@ -1772,31 +2170,27 @@
 	if (!mddev->pers || !mddev->pers->sync_request)
 		return -EINVAL;
 
-	if (strcmp(page, "idle")==0 || strcmp(page, "idle\n")==0) {
+	if (cmd_match(page, "idle")) {
 		if (mddev->sync_thread) {
 			set_bit(MD_RECOVERY_INTR, &mddev->recovery);
 			md_unregister_thread(mddev->sync_thread);
 			mddev->sync_thread = NULL;
 			mddev->recovery = 0;
 		}
-		return len;
-	}
-
-	if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
-	    test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
+	} else if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
+		   test_bit(MD_RECOVERY_NEEDED, &mddev->recovery))
 		return -EBUSY;
-	if (strcmp(page, "resync")==0 || strcmp(page, "resync\n")==0 ||
-	    strcmp(page, "recover")==0 || strcmp(page, "recover\n")==0)
+	else if (cmd_match(page, "resync") || cmd_match(page, "recover"))
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	else {
-		if (strcmp(page, "check")==0 || strcmp(page, "check\n")==0)
+		if (cmd_match(page, "check"))
 			set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
-		else if (strcmp(page, "repair")!=0 && strcmp(page, "repair\n")!=0)
+		else if (cmd_match(page, "repair"))
 			return -EINVAL;
 		set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
 		set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
-		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
+	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	md_wakeup_thread(mddev->thread);
 	return len;
 }
@@ -1815,15 +2209,107 @@
 static struct md_sysfs_entry
 md_mismatches = __ATTR_RO(mismatch_cnt);
 
+static ssize_t
+sync_min_show(mddev_t *mddev, char *page)
+{
+	return sprintf(page, "%d (%s)\n", speed_min(mddev),
+		       mddev->sync_speed_min ? "local": "system");
+}
+
+static ssize_t
+sync_min_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	int min;
+	char *e;
+	if (strncmp(buf, "system", 6)==0) {
+		mddev->sync_speed_min = 0;
+		return len;
+	}
+	min = simple_strtoul(buf, &e, 10);
+	if (buf == e || (*e && *e != '\n') || min <= 0)
+		return -EINVAL;
+	mddev->sync_speed_min = min;
+	return len;
+}
+
+static struct md_sysfs_entry md_sync_min =
+__ATTR(sync_speed_min, S_IRUGO|S_IWUSR, sync_min_show, sync_min_store);
+
+static ssize_t
+sync_max_show(mddev_t *mddev, char *page)
+{
+	return sprintf(page, "%d (%s)\n", speed_max(mddev),
+		       mddev->sync_speed_max ? "local": "system");
+}
+
+static ssize_t
+sync_max_store(mddev_t *mddev, const char *buf, size_t len)
+{
+	int max;
+	char *e;
+	if (strncmp(buf, "system", 6)==0) {
+		mddev->sync_speed_max = 0;
+		return len;
+	}
+	max = simple_strtoul(buf, &e, 10);
+	if (buf == e || (*e && *e != '\n') || max <= 0)
+		return -EINVAL;
+	mddev->sync_speed_max = max;
+	return len;
+}
+
+static struct md_sysfs_entry md_sync_max =
+__ATTR(sync_speed_max, S_IRUGO|S_IWUSR, sync_max_show, sync_max_store);
+
+
+static ssize_t
+sync_speed_show(mddev_t *mddev, char *page)
+{
+	unsigned long resync, dt, db;
+	resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
+	dt = ((jiffies - mddev->resync_mark) / HZ);
+	if (!dt) dt++;
+	db = resync - (mddev->resync_mark_cnt);
+	return sprintf(page, "%ld\n", db/dt/2); /* K/sec */
+}
+
+static struct md_sysfs_entry
+md_sync_speed = __ATTR_RO(sync_speed);
+
+static ssize_t
+sync_completed_show(mddev_t *mddev, char *page)
+{
+	unsigned long max_blocks, resync;
+
+	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
+		max_blocks = mddev->resync_max_sectors;
+	else
+		max_blocks = mddev->size << 1;
+
+	resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
+	return sprintf(page, "%lu / %lu\n", resync, max_blocks);
+}
+
+static struct md_sysfs_entry
+md_sync_completed = __ATTR_RO(sync_completed);
+
 static struct attribute *md_default_attrs[] = {
 	&md_level.attr,
 	&md_raid_disks.attr,
+	&md_chunk_size.attr,
+	&md_size.attr,
+	&md_metadata.attr,
+	&md_new_device.attr,
 	NULL,
 };
 
 static struct attribute *md_redundancy_attrs[] = {
 	&md_scan_mode.attr,
 	&md_mismatches.attr,
+	&md_sync_min.attr,
+	&md_sync_max.attr,
+	&md_sync_speed.attr,
+	&md_sync_completed.attr,
 	NULL,
 };
 static struct attribute_group md_redundancy_group = {
@@ -1938,14 +2424,16 @@
 	md_wakeup_thread(mddev->thread);
 }
 
+static int start_dirty_degraded;
 
 static int do_md_run(mddev_t * mddev)
 {
-	int pnum, err;
+	int err;
 	int chunk_size;
 	struct list_head *tmp;
 	mdk_rdev_t *rdev;
 	struct gendisk *disk;
+	struct mdk_personality *pers;
 	char b[BDEVNAME_SIZE];
 
 	if (list_empty(&mddev->disks))
@@ -1962,20 +2450,8 @@
 		analyze_sbs(mddev);
 
 	chunk_size = mddev->chunk_size;
-	pnum = level_to_pers(mddev->level);
 
-	if ((pnum != MULTIPATH) && (pnum != RAID1)) {
-		if (!chunk_size) {
-			/*
-			 * 'default chunksize' in the old md code used to
-			 * be PAGE_SIZE, baaad.
-			 * we abort here to be on the safe side. We don't
-			 * want to continue the bad practice.
-			 */
-			printk(KERN_ERR 
-				"no chunksize specified, see 'man raidtab'\n");
-			return -EINVAL;
-		}
+	if (chunk_size) {
 		if (chunk_size > MAX_CHUNK_SIZE) {
 			printk(KERN_ERR "too big chunk_size: %d > %d\n",
 				chunk_size, MAX_CHUNK_SIZE);
@@ -2011,10 +2487,10 @@
 	}
 
 #ifdef CONFIG_KMOD
-	if (!pers[pnum])
-	{
-		request_module("md-personality-%d", pnum);
-	}
+	if (mddev->level != LEVEL_NONE)
+		request_module("md-level-%d", mddev->level);
+	else if (mddev->clevel[0])
+		request_module("md-%s", mddev->clevel);
 #endif
 
 	/*
@@ -2036,30 +2512,39 @@
 		return -ENOMEM;
 
 	spin_lock(&pers_lock);
-	if (!pers[pnum] || !try_module_get(pers[pnum]->owner)) {
+	pers = find_pers(mddev->level, mddev->clevel);
+	if (!pers || !try_module_get(pers->owner)) {
 		spin_unlock(&pers_lock);
-		printk(KERN_WARNING "md: personality %d is not loaded!\n",
-		       pnum);
+		if (mddev->level != LEVEL_NONE)
+			printk(KERN_WARNING "md: personality for level %d is not loaded!\n",
+			       mddev->level);
+		else
+			printk(KERN_WARNING "md: personality for level %s is not loaded!\n",
+			       mddev->clevel);
 		return -EINVAL;
 	}
-
-	mddev->pers = pers[pnum];
+	mddev->pers = pers;
 	spin_unlock(&pers_lock);
+	mddev->level = pers->level;
+	strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
 
 	mddev->recovery = 0;
 	mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
 	mddev->barriers_work = 1;
+	mddev->ok_start_degraded = start_dirty_degraded;
 
 	if (start_readonly)
 		mddev->ro = 2; /* read-only, but switch on first write */
 
-	/* before we start the array running, initialise the bitmap */
-	err = bitmap_create(mddev);
-	if (err)
-		printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
-			mdname(mddev), err);
-	else
-		err = mddev->pers->run(mddev);
+	err = mddev->pers->run(mddev);
+	if (!err && mddev->pers->sync_request) {
+		err = bitmap_create(mddev);
+		if (err) {
+			printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
+			       mdname(mddev), err);
+			mddev->pers->stop(mddev);
+		}
+	}
 	if (err) {
 		printk(KERN_ERR "md: pers->run() failed ...\n");
 		module_put(mddev->pers->owner);
@@ -2105,6 +2590,7 @@
 	mddev->queue->make_request_fn = mddev->pers->make_request;
 
 	mddev->changed = 1;
+	md_new_event(mddev);
 	return 0;
 }
 
@@ -2232,6 +2718,7 @@
 		printk(KERN_INFO "md: %s switched to read-only mode.\n",
 			mdname(mddev));
 	err = 0;
+	md_new_event(mddev);
 out:
 	return err;
 }
@@ -2669,12 +3156,6 @@
 		if (info->state & (1<<MD_DISK_WRITEMOSTLY))
 			set_bit(WriteMostly, &rdev->flags);
 
-		err = bind_rdev_to_array(rdev, mddev);
-		if (err) {
-			export_rdev(rdev);
-			return err;
-		}
-
 		if (!mddev->persistent) {
 			printk(KERN_INFO "md: nonpersistent superblock ...\n");
 			rdev->sb_offset = rdev->bdev->bd_inode->i_size >> BLOCK_SIZE_BITS;
@@ -2682,8 +3163,11 @@
 			rdev->sb_offset = calc_dev_sboffset(rdev->bdev);
 		rdev->size = calc_dev_size(rdev, mddev->chunk_size);
 
-		if (!mddev->size || (mddev->size > rdev->size))
-			mddev->size = rdev->size;
+		err = bind_rdev_to_array(rdev, mddev);
+		if (err) {
+			export_rdev(rdev);
+			return err;
+		}
 	}
 
 	return 0;
@@ -2706,6 +3190,7 @@
 
 	kick_rdev_from_array(rdev);
 	md_update_sb(mddev);
+	md_new_event(mddev);
 
 	return 0;
 busy:
@@ -2754,15 +3239,6 @@
 	size = calc_dev_size(rdev, mddev->chunk_size);
 	rdev->size = size;
 
-	if (size < mddev->size) {
-		printk(KERN_WARNING 
-			"%s: disk size %llu blocks < array size %llu\n",
-			mdname(mddev), (unsigned long long)size,
-			(unsigned long long)mddev->size);
-		err = -ENOSPC;
-		goto abort_export;
-	}
-
 	if (test_bit(Faulty, &rdev->flags)) {
 		printk(KERN_WARNING 
 			"md: can not hot-add faulty %s disk to %s!\n",
@@ -2772,7 +3248,9 @@
 	}
 	clear_bit(In_sync, &rdev->flags);
 	rdev->desc_nr = -1;
-	bind_rdev_to_array(rdev, mddev);
+	err = bind_rdev_to_array(rdev, mddev);
+	if (err)
+		goto abort_export;
 
 	/*
 	 * The rest should better be atomic, we can have disk failures
@@ -2796,7 +3274,7 @@
 	 */
 	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	md_wakeup_thread(mddev->thread);
-
+	md_new_event(mddev);
 	return 0;
 
 abort_unbind_export:
@@ -2932,6 +3410,9 @@
 
 	mddev->sb_dirty      = 1;
 
+	mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
+	mddev->bitmap_offset = 0;
+
 	/*
 	 * Generate a 128 bit UUID
 	 */
@@ -2940,6 +3421,81 @@
 	return 0;
 }
 
+static int update_size(mddev_t *mddev, unsigned long size)
+{
+	mdk_rdev_t * rdev;
+	int rv;
+	struct list_head *tmp;
+
+	if (mddev->pers->resize == NULL)
+		return -EINVAL;
+	/* The "size" is the amount of each device that is used.
+	 * This can only make sense for arrays with redundancy.
+	 * linear and raid0 always use whatever space is available
+	 * We can only consider changing the size if no resync
+	 * or reconstruction is happening, and if the new size
+	 * is acceptable. It must fit before the sb_offset or,
+	 * if that is <data_offset, it must fit before the
+	 * size of each device.
+	 * If size is zero, we find the largest size that fits.
+	 */
+	if (mddev->sync_thread)
+		return -EBUSY;
+	ITERATE_RDEV(mddev,rdev,tmp) {
+		sector_t avail;
+		int fit = (size == 0);
+		if (rdev->sb_offset > rdev->data_offset)
+			avail = (rdev->sb_offset*2) - rdev->data_offset;
+		else
+			avail = get_capacity(rdev->bdev->bd_disk)
+				- rdev->data_offset;
+		if (fit && (size == 0 || size > avail/2))
+			size = avail/2;
+		if (avail < ((sector_t)size << 1))
+			return -ENOSPC;
+	}
+	rv = mddev->pers->resize(mddev, (sector_t)size *2);
+	if (!rv) {
+		struct block_device *bdev;
+
+		bdev = bdget_disk(mddev->gendisk, 0);
+		if (bdev) {
+			down(&bdev->bd_inode->i_sem);
+			i_size_write(bdev->bd_inode, mddev->array_size << 10);
+			up(&bdev->bd_inode->i_sem);
+			bdput(bdev);
+		}
+	}
+	return rv;
+}
+
+static int update_raid_disks(mddev_t *mddev, int raid_disks)
+{
+	int rv;
+	/* change the number of raid disks */
+	if (mddev->pers->reshape == NULL)
+		return -EINVAL;
+	if (raid_disks <= 0 ||
+	    raid_disks >= mddev->max_disks)
+		return -EINVAL;
+	if (mddev->sync_thread)
+		return -EBUSY;
+	rv = mddev->pers->reshape(mddev, raid_disks);
+	if (!rv) {
+		struct block_device *bdev;
+
+		bdev = bdget_disk(mddev->gendisk, 0);
+		if (bdev) {
+			down(&bdev->bd_inode->i_sem);
+			i_size_write(bdev->bd_inode, mddev->array_size << 10);
+			up(&bdev->bd_inode->i_sem);
+			bdput(bdev);
+		}
+	}
+	return rv;
+}
+
+
 /*
  * update_array_info is used to change the configuration of an
  * on-line array.
@@ -2988,71 +3544,12 @@
 		else
 			return mddev->pers->reconfig(mddev, info->layout, -1);
 	}
-	if (mddev->size != info->size) {
-		mdk_rdev_t * rdev;
-		struct list_head *tmp;
-		if (mddev->pers->resize == NULL)
-			return -EINVAL;
-		/* The "size" is the amount of each device that is used.
-		 * This can only make sense for arrays with redundancy.
-		 * linear and raid0 always use whatever space is available
-		 * We can only consider changing the size if no resync
-		 * or reconstruction is happening, and if the new size
-		 * is acceptable. It must fit before the sb_offset or,
-		 * if that is <data_offset, it must fit before the
-		 * size of each device.
-		 * If size is zero, we find the largest size that fits.
-		 */
-		if (mddev->sync_thread)
-			return -EBUSY;
-		ITERATE_RDEV(mddev,rdev,tmp) {
-			sector_t avail;
-			int fit = (info->size == 0);
-			if (rdev->sb_offset > rdev->data_offset)
-				avail = (rdev->sb_offset*2) - rdev->data_offset;
-			else
-				avail = get_capacity(rdev->bdev->bd_disk)
-					- rdev->data_offset;
-			if (fit && (info->size == 0 || info->size > avail/2))
-				info->size = avail/2;
-			if (avail < ((sector_t)info->size << 1))
-				return -ENOSPC;
-		}
-		rv = mddev->pers->resize(mddev, (sector_t)info->size *2);
-		if (!rv) {
-			struct block_device *bdev;
+	if (mddev->size != info->size)
+		rv = update_size(mddev, info->size);
 
-			bdev = bdget_disk(mddev->gendisk, 0);
-			if (bdev) {
-				down(&bdev->bd_inode->i_sem);
-				i_size_write(bdev->bd_inode, mddev->array_size << 10);
-				up(&bdev->bd_inode->i_sem);
-				bdput(bdev);
-			}
-		}
-	}
-	if (mddev->raid_disks    != info->raid_disks) {
-		/* change the number of raid disks */
-		if (mddev->pers->reshape == NULL)
-			return -EINVAL;
-		if (info->raid_disks <= 0 ||
-		    info->raid_disks >= mddev->max_disks)
-			return -EINVAL;
-		if (mddev->sync_thread)
-			return -EBUSY;
-		rv = mddev->pers->reshape(mddev, info->raid_disks);
-		if (!rv) {
-			struct block_device *bdev;
+	if (mddev->raid_disks    != info->raid_disks)
+		rv = update_raid_disks(mddev, info->raid_disks);
 
-			bdev = bdget_disk(mddev->gendisk, 0);
-			if (bdev) {
-				down(&bdev->bd_inode->i_sem);
-				i_size_write(bdev->bd_inode, mddev->array_size << 10);
-				up(&bdev->bd_inode->i_sem);
-				bdput(bdev);
-			}
-		}
-	}
 	if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) {
 		if (mddev->pers->quiesce == NULL)
 			return -EINVAL;
@@ -3101,12 +3598,21 @@
 	return 0;
 }
 
+static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	mddev_t *mddev = bdev->bd_disk->private_data;
+
+	geo->heads = 2;
+	geo->sectors = 4;
+	geo->cylinders = get_capacity(mddev->gendisk) / 8;
+	return 0;
+}
+
 static int md_ioctl(struct inode *inode, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
 	int err = 0;
 	void __user *argp = (void __user *)arg;
-	struct hd_geometry __user *loc = argp;
 	mddev_t *mddev = NULL;
 
 	if (!capable(CAP_SYS_ADMIN))
@@ -3268,24 +3774,6 @@
 	 * 4 sectors (with a BIG number of cylinders...). This drives
 	 * dosfs just mad... ;-)
 	 */
-		case HDIO_GETGEO:
-			if (!loc) {
-				err = -EINVAL;
-				goto abort_unlock;
-			}
-			err = put_user (2, (char __user *) &loc->heads);
-			if (err)
-				goto abort_unlock;
-			err = put_user (4, (char __user *) &loc->sectors);
-			if (err)
-				goto abort_unlock;
-			err = put_user(get_capacity(mddev->gendisk)/8,
-					(short __user *) &loc->cylinders);
-			if (err)
-				goto abort_unlock;
-			err = put_user (get_start_sect(inode->i_bdev),
-						(long __user *) &loc->start);
-			goto done_unlock;
 	}
 
 	/*
@@ -3414,6 +3902,7 @@
 	.open		= md_open,
 	.release	= md_release,
 	.ioctl		= md_ioctl,
+	.getgeo		= md_getgeo,
 	.media_changed	= md_media_changed,
 	.revalidate_disk= md_revalidate,
 };
@@ -3474,11 +3963,10 @@
 {
 	mdk_thread_t *thread;
 
-	thread = kmalloc(sizeof(mdk_thread_t), GFP_KERNEL);
+	thread = kzalloc(sizeof(mdk_thread_t), GFP_KERNEL);
 	if (!thread)
 		return NULL;
 
-	memset(thread, 0, sizeof(mdk_thread_t));
 	init_waitqueue_head(&thread->wqueue);
 
 	thread->run = run;
@@ -3522,6 +4010,7 @@
 	set_bit(MD_RECOVERY_INTR, &mddev->recovery);
 	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	md_wakeup_thread(mddev->thread);
+	md_new_event(mddev);
 }
 
 /* seq_file implementation /proc/mdstat */
@@ -3662,24 +4151,29 @@
 		mddev_put(mddev);
 }
 
+struct mdstat_info {
+	int event;
+};
+
 static int md_seq_show(struct seq_file *seq, void *v)
 {
 	mddev_t *mddev = v;
 	sector_t size;
 	struct list_head *tmp2;
 	mdk_rdev_t *rdev;
-	int i;
+	struct mdstat_info *mi = seq->private;
 	struct bitmap *bitmap;
 
 	if (v == (void*)1) {
+		struct mdk_personality *pers;
 		seq_printf(seq, "Personalities : ");
 		spin_lock(&pers_lock);
-		for (i = 0; i < MAX_PERSONALITY; i++)
-			if (pers[i])
-				seq_printf(seq, "[%s] ", pers[i]->name);
+		list_for_each_entry(pers, &pers_list, list)
+			seq_printf(seq, "[%s] ", pers->name);
 
 		spin_unlock(&pers_lock);
 		seq_printf(seq, "\n");
+		mi->event = atomic_read(&md_event_count);
 		return 0;
 	}
 	if (v == (void*)2) {
@@ -3788,47 +4282,68 @@
 static int md_seq_open(struct inode *inode, struct file *file)
 {
 	int error;
+	struct mdstat_info *mi = kmalloc(sizeof(*mi), GFP_KERNEL);
+	if (mi == NULL)
+		return -ENOMEM;
 
 	error = seq_open(file, &md_seq_ops);
+	if (error)
+		kfree(mi);
+	else {
+		struct seq_file *p = file->private_data;
+		p->private = mi;
+		mi->event = atomic_read(&md_event_count);
+	}
 	return error;
 }
 
+static int md_seq_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *m = file->private_data;
+	struct mdstat_info *mi = m->private;
+	m->private = NULL;
+	kfree(mi);
+	return seq_release(inode, file);
+}
+
+static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
+{
+	struct seq_file *m = filp->private_data;
+	struct mdstat_info *mi = m->private;
+	int mask;
+
+	poll_wait(filp, &md_event_waiters, wait);
+
+	/* always allow read */
+	mask = POLLIN | POLLRDNORM;
+
+	if (mi->event != atomic_read(&md_event_count))
+		mask |= POLLERR | POLLPRI;
+	return mask;
+}
+
 static struct file_operations md_seq_fops = {
 	.open           = md_seq_open,
 	.read           = seq_read,
 	.llseek         = seq_lseek,
-	.release	= seq_release,
+	.release	= md_seq_release,
+	.poll		= mdstat_poll,
 };
 
-int register_md_personality(int pnum, mdk_personality_t *p)
+int register_md_personality(struct mdk_personality *p)
 {
-	if (pnum >= MAX_PERSONALITY) {
-		printk(KERN_ERR
-		       "md: tried to install personality %s as nr %d, but max is %lu\n",
-		       p->name, pnum, MAX_PERSONALITY-1);
-		return -EINVAL;
-	}
-
 	spin_lock(&pers_lock);
-	if (pers[pnum]) {
-		spin_unlock(&pers_lock);
-		return -EBUSY;
-	}
-
-	pers[pnum] = p;
-	printk(KERN_INFO "md: %s personality registered as nr %d\n", p->name, pnum);
+	list_add_tail(&p->list, &pers_list);
+	printk(KERN_INFO "md: %s personality registered for level %d\n", p->name, p->level);
 	spin_unlock(&pers_lock);
 	return 0;
 }
 
-int unregister_md_personality(int pnum)
+int unregister_md_personality(struct mdk_personality *p)
 {
-	if (pnum >= MAX_PERSONALITY)
-		return -EINVAL;
-
-	printk(KERN_INFO "md: %s personality unregistered\n", pers[pnum]->name);
+	printk(KERN_INFO "md: %s personality unregistered\n", p->name);
 	spin_lock(&pers_lock);
-	pers[pnum] = NULL;
+	list_del_init(&p->list);
 	spin_unlock(&pers_lock);
 	return 0;
 }
@@ -4010,10 +4525,10 @@
 
 	printk(KERN_INFO "md: syncing RAID array %s\n", mdname(mddev));
 	printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed:"
-		" %d KB/sec/disc.\n", sysctl_speed_limit_min);
+		" %d KB/sec/disc.\n", speed_min(mddev));
 	printk(KERN_INFO "md: using maximum available idle IO bandwidth "
 	       "(but not more than %d KB/sec) for reconstruction.\n",
-	       sysctl_speed_limit_max);
+	       speed_max(mddev));
 
 	is_mddev_idle(mddev); /* this also initializes IO event counters */
 	/* we don't use the checkpoint if there's a bitmap */
@@ -4054,7 +4569,7 @@
 
 		skipped = 0;
 		sectors = mddev->pers->sync_request(mddev, j, &skipped,
-					    currspeed < sysctl_speed_limit_min);
+					    currspeed < speed_min(mddev));
 		if (sectors == 0) {
 			set_bit(MD_RECOVERY_ERR, &mddev->recovery);
 			goto out;
@@ -4067,7 +4582,11 @@
 
 		j += sectors;
 		if (j>1) mddev->curr_resync = j;
-
+		if (last_check == 0)
+			/* this is the earliers that rebuilt will be
+			 * visible in /proc/mdstat
+			 */
+			md_new_event(mddev);
 
 		if (last_check + window > io_sectors || j == max_sectors)
 			continue;
@@ -4115,8 +4634,8 @@
 		currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2
 			/((jiffies-mddev->resync_mark)/HZ +1) +1;
 
-		if (currspeed > sysctl_speed_limit_min) {
-			if ((currspeed > sysctl_speed_limit_max) ||
+		if (currspeed > speed_min(mddev)) {
+			if ((currspeed > speed_max(mddev)) ||
 					!is_mddev_idle(mddev)) {
 				msleep(500);
 				goto repeat;
@@ -4253,6 +4772,7 @@
 			mddev->recovery = 0;
 			/* flag recovery needed just to double check */
 			set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+			md_new_event(mddev);
 			goto unlock;
 		}
 		/* Clear some bits that don't mean anything, but
@@ -4290,6 +4810,7 @@
 						sprintf(nm, "rd%d", rdev->raid_disk);
 						sysfs_create_link(&mddev->kobj, &rdev->kobj, nm);
 						spares++;
+						md_new_event(mddev);
 					} else
 						break;
 				}
@@ -4322,9 +4843,9 @@
 					mdname(mddev));
 				/* leave the spares where they are, it shouldn't hurt */
 				mddev->recovery = 0;
-			} else {
+			} else
 				md_wakeup_thread(mddev->sync_thread);
-			}
+			md_new_event(mddev);
 		}
 	unlock:
 		mddev_unlock(mddev);
@@ -4501,12 +5022,14 @@
 	int num = simple_strtoul(val, &e, 10);
 	if (*val && (*e == '\0' || *e == '\n')) {
 		start_readonly = num;
-		return 0;;
+		return 0;
 	}
 	return -EINVAL;
 }
 
 module_param_call(start_ro, set_ro, get_ro, NULL, 0600);
+module_param(start_dirty_degraded, int, 0644);
+
 
 EXPORT_SYMBOL(register_md_personality);
 EXPORT_SYMBOL(unregister_md_personality);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 145cdc5..e6aa309 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -35,15 +35,10 @@
 #define	NR_RESERVED_BUFS	32
 
 
-static mdk_personality_t multipath_personality;
-
-
 static void *mp_pool_alloc(gfp_t gfp_flags, void *data)
 {
 	struct multipath_bh *mpb;
-	mpb = kmalloc(sizeof(*mpb), gfp_flags);
-	if (mpb) 
-		memset(mpb, 0, sizeof(*mpb));
+	mpb = kzalloc(sizeof(*mpb), gfp_flags);
 	return mpb;
 }
 
@@ -444,7 +439,7 @@
 	 * should be freed in multipath_stop()]
 	 */
 
-	conf = kmalloc(sizeof(multipath_conf_t), GFP_KERNEL);
+	conf = kzalloc(sizeof(multipath_conf_t), GFP_KERNEL);
 	mddev->private = conf;
 	if (!conf) {
 		printk(KERN_ERR 
@@ -452,9 +447,8 @@
 			mdname(mddev));
 		goto out;
 	}
-	memset(conf, 0, sizeof(*conf));
 
-	conf->multipaths = kmalloc(sizeof(struct multipath_info)*mddev->raid_disks,
+	conf->multipaths = kzalloc(sizeof(struct multipath_info)*mddev->raid_disks,
 				   GFP_KERNEL);
 	if (!conf->multipaths) {
 		printk(KERN_ERR 
@@ -462,7 +456,6 @@
 			mdname(mddev));
 		goto out_free_conf;
 	}
-	memset(conf->multipaths, 0, sizeof(struct multipath_info)*mddev->raid_disks);
 
 	conf->working_disks = 0;
 	ITERATE_RDEV(mddev,rdev,tmp) {
@@ -557,9 +550,10 @@
 	return 0;
 }
 
-static mdk_personality_t multipath_personality=
+static struct mdk_personality multipath_personality =
 {
 	.name		= "multipath",
+	.level		= LEVEL_MULTIPATH,
 	.owner		= THIS_MODULE,
 	.make_request	= multipath_make_request,
 	.run		= multipath_run,
@@ -572,15 +566,17 @@
 
 static int __init multipath_init (void)
 {
-	return register_md_personality (MULTIPATH, &multipath_personality);
+	return register_md_personality (&multipath_personality);
 }
 
 static void __exit multipath_exit (void)
 {
-	unregister_md_personality (MULTIPATH);
+	unregister_md_personality (&multipath_personality);
 }
 
 module_init(multipath_init);
 module_exit(multipath_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("md-personality-7"); /* MULTIPATH */
+MODULE_ALIAS("md-multipath");
+MODULE_ALIAS("md-level--4");
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index fece327..d03f99c 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -113,21 +113,16 @@
 	}
 	printk("raid0: FINAL %d zones\n", conf->nr_strip_zones);
 
-	conf->strip_zone = kmalloc(sizeof(struct strip_zone)*
+	conf->strip_zone = kzalloc(sizeof(struct strip_zone)*
 				conf->nr_strip_zones, GFP_KERNEL);
 	if (!conf->strip_zone)
 		return 1;
-	conf->devlist = kmalloc(sizeof(mdk_rdev_t*)*
+	conf->devlist = kzalloc(sizeof(mdk_rdev_t*)*
 				conf->nr_strip_zones*mddev->raid_disks,
 				GFP_KERNEL);
 	if (!conf->devlist)
 		return 1;
 
-	memset(conf->strip_zone, 0,sizeof(struct strip_zone)*
-				   conf->nr_strip_zones);
-	memset(conf->devlist, 0,
-	       sizeof(mdk_rdev_t*) * conf->nr_strip_zones * mddev->raid_disks);
-
 	/* The first zone must contain all devices, so here we check that
 	 * there is a proper alignment of slots to devices and find them all
 	 */
@@ -280,7 +275,11 @@
 	mdk_rdev_t *rdev;
 	struct list_head *tmp;
 
-	printk("%s: setting max_sectors to %d, segment boundary to %d\n",
+	if (mddev->chunk_size == 0) {
+		printk(KERN_ERR "md/raid0: non-zero chunk size required.\n");
+		return -EINVAL;
+	}
+	printk(KERN_INFO "%s: setting max_sectors to %d, segment boundary to %d\n",
 	       mdname(mddev),
 	       mddev->chunk_size >> 9,
 	       (mddev->chunk_size>>1)-1);
@@ -307,9 +306,6 @@
 	printk("raid0 : conf->hash_spacing is %llu blocks.\n",
 		(unsigned long long)conf->hash_spacing);
 	{
-#if __GNUC__ < 3
-		volatile
-#endif
 		sector_t s = mddev->array_size;
 		sector_t space = conf->hash_spacing;
 		int round;
@@ -361,7 +357,7 @@
 	 * chunksize should be used in that case.
 	 */
 	{
-		int stripe = mddev->raid_disks * mddev->chunk_size / PAGE_CACHE_SIZE;
+		int stripe = mddev->raid_disks * mddev->chunk_size / PAGE_SIZE;
 		if (mddev->queue->backing_dev_info.ra_pages < 2* stripe)
 			mddev->queue->backing_dev_info.ra_pages = 2* stripe;
 	}
@@ -440,9 +436,6 @@
  
 
 	{
-#if __GNUC__ < 3
-		volatile
-#endif
 		sector_t x = block >> conf->preshift;
 		sector_div(x, (u32)conf->hash_spacing);
 		zone = conf->hash_table[x];
@@ -512,9 +505,10 @@
 	return;
 }
 
-static mdk_personality_t raid0_personality=
+static struct mdk_personality raid0_personality=
 {
 	.name		= "raid0",
+	.level		= 0,
 	.owner		= THIS_MODULE,
 	.make_request	= raid0_make_request,
 	.run		= raid0_run,
@@ -524,15 +518,17 @@
 
 static int __init raid0_init (void)
 {
-	return register_md_personality (RAID0, &raid0_personality);
+	return register_md_personality (&raid0_personality);
 }
 
 static void raid0_exit (void)
 {
-	unregister_md_personality (RAID0);
+	unregister_md_personality (&raid0_personality);
 }
 
 module_init(raid0_init);
 module_exit(raid0_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("md-personality-2"); /* RAID0 */
+MODULE_ALIAS("md-raid0");
+MODULE_ALIAS("md-level-0");
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 2da9d3b..a06ff91 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -47,10 +47,11 @@
  */
 #define	NR_RAID1_BIOS 256
 
-static mdk_personality_t raid1_personality;
 
 static void unplug_slaves(mddev_t *mddev);
 
+static void allow_barrier(conf_t *conf);
+static void lower_barrier(conf_t *conf);
 
 static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
 {
@@ -59,10 +60,8 @@
 	int size = offsetof(r1bio_t, bios[pi->raid_disks]);
 
 	/* allocate a r1bio with room for raid_disks entries in the bios array */
-	r1_bio = kmalloc(size, gfp_flags);
-	if (r1_bio)
-		memset(r1_bio, 0, size);
-	else
+	r1_bio = kzalloc(size, gfp_flags);
+	if (!r1_bio)
 		unplug_slaves(pi->mddev);
 
 	return r1_bio;
@@ -104,15 +103,30 @@
 	}
 	/*
 	 * Allocate RESYNC_PAGES data pages and attach them to
-	 * the first bio;
+	 * the first bio.
+	 * If this is a user-requested check/repair, allocate
+	 * RESYNC_PAGES for each bio.
 	 */
-	bio = r1_bio->bios[0];
-	for (i = 0; i < RESYNC_PAGES; i++) {
-		page = alloc_page(gfp_flags);
-		if (unlikely(!page))
-			goto out_free_pages;
+	if (test_bit(MD_RECOVERY_REQUESTED, &pi->mddev->recovery))
+		j = pi->raid_disks;
+	else
+		j = 1;
+	while(j--) {
+		bio = r1_bio->bios[j];
+		for (i = 0; i < RESYNC_PAGES; i++) {
+			page = alloc_page(gfp_flags);
+			if (unlikely(!page))
+				goto out_free_pages;
 
-		bio->bi_io_vec[i].bv_page = page;
+			bio->bi_io_vec[i].bv_page = page;
+		}
+	}
+	/* If not user-requests, copy the page pointers to all bios */
+	if (!test_bit(MD_RECOVERY_REQUESTED, &pi->mddev->recovery)) {
+		for (i=0; i<RESYNC_PAGES ; i++)
+			for (j=1; j<pi->raid_disks; j++)
+				r1_bio->bios[j]->bi_io_vec[i].bv_page =
+					r1_bio->bios[0]->bi_io_vec[i].bv_page;
 	}
 
 	r1_bio->master_bio = NULL;
@@ -120,8 +134,10 @@
 	return r1_bio;
 
 out_free_pages:
-	for ( ; i > 0 ; i--)
-		__free_page(bio->bi_io_vec[i-1].bv_page);
+	for (i=0; i < RESYNC_PAGES ; i++)
+		for (j=0 ; j < pi->raid_disks; j++)
+			safe_put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
+	j = -1;
 out_free_bio:
 	while ( ++j < pi->raid_disks )
 		bio_put(r1_bio->bios[j]);
@@ -132,14 +148,16 @@
 static void r1buf_pool_free(void *__r1_bio, void *data)
 {
 	struct pool_info *pi = data;
-	int i;
+	int i,j;
 	r1bio_t *r1bio = __r1_bio;
-	struct bio *bio = r1bio->bios[0];
 
-	for (i = 0; i < RESYNC_PAGES; i++) {
-		__free_page(bio->bi_io_vec[i].bv_page);
-		bio->bi_io_vec[i].bv_page = NULL;
-	}
+	for (i = 0; i < RESYNC_PAGES; i++)
+		for (j = pi->raid_disks; j-- ;) {
+			if (j == 0 ||
+			    r1bio->bios[j]->bi_io_vec[i].bv_page !=
+			    r1bio->bios[0]->bi_io_vec[i].bv_page)
+				safe_put_page(r1bio->bios[j]->bi_io_vec[i].bv_page);
+		}
 	for (i=0 ; i < pi->raid_disks; i++)
 		bio_put(r1bio->bios[i]);
 
@@ -152,7 +170,7 @@
 
 	for (i = 0; i < conf->raid_disks; i++) {
 		struct bio **bio = r1_bio->bios + i;
-		if (*bio)
+		if (*bio && *bio != IO_BLOCKED)
 			bio_put(*bio);
 		*bio = NULL;
 	}
@@ -160,20 +178,13 @@
 
 static inline void free_r1bio(r1bio_t *r1_bio)
 {
-	unsigned long flags;
-
 	conf_t *conf = mddev_to_conf(r1_bio->mddev);
 
 	/*
 	 * Wake up any possible resync thread that waits for the device
 	 * to go idle.
 	 */
-	spin_lock_irqsave(&conf->resync_lock, flags);
-	if (!--conf->nr_pending) {
-		wake_up(&conf->wait_idle);
-		wake_up(&conf->wait_resume);
-	}
-	spin_unlock_irqrestore(&conf->resync_lock, flags);
+	allow_barrier(conf);
 
 	put_all_bios(conf, r1_bio);
 	mempool_free(r1_bio, conf->r1bio_pool);
@@ -182,22 +193,17 @@
 static inline void put_buf(r1bio_t *r1_bio)
 {
 	conf_t *conf = mddev_to_conf(r1_bio->mddev);
-	unsigned long flags;
+	int i;
+
+	for (i=0; i<conf->raid_disks; i++) {
+		struct bio *bio = r1_bio->bios[i];
+		if (bio->bi_end_io)
+			rdev_dec_pending(conf->mirrors[i].rdev, r1_bio->mddev);
+	}
 
 	mempool_free(r1_bio, conf->r1buf_pool);
 
-	spin_lock_irqsave(&conf->resync_lock, flags);
-	if (!conf->barrier)
-		BUG();
-	--conf->barrier;
-	wake_up(&conf->wait_resume);
-	wake_up(&conf->wait_idle);
-
-	if (!--conf->nr_pending) {
-		wake_up(&conf->wait_idle);
-		wake_up(&conf->wait_resume);
-	}
-	spin_unlock_irqrestore(&conf->resync_lock, flags);
+	lower_barrier(conf);
 }
 
 static void reschedule_retry(r1bio_t *r1_bio)
@@ -208,8 +214,10 @@
 
 	spin_lock_irqsave(&conf->device_lock, flags);
 	list_add(&r1_bio->retry_list, &conf->retry_list);
+	conf->nr_queued ++;
 	spin_unlock_irqrestore(&conf->device_lock, flags);
 
+	wake_up(&conf->wait_barrier);
 	md_wakeup_thread(mddev->thread);
 }
 
@@ -261,9 +269,9 @@
 	/*
 	 * this branch is our 'one mirror IO has finished' event handler:
 	 */
-	if (!uptodate)
-		md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
-	else
+	update_head_pos(mirror, r1_bio);
+
+	if (uptodate || conf->working_disks <= 1) {
 		/*
 		 * Set R1BIO_Uptodate in our master bio, so that
 		 * we will return a good error code for to the higher
@@ -273,16 +281,11 @@
 		 * user-side. So if something waits for IO, then it will
 		 * wait for the 'master' bio.
 		 */
-		set_bit(R1BIO_Uptodate, &r1_bio->state);
+		if (uptodate)
+			set_bit(R1BIO_Uptodate, &r1_bio->state);
 
-	update_head_pos(mirror, r1_bio);
-
-	/*
-	 * we have only one bio on the read side
-	 */
-	if (uptodate)
 		raid_end_bio_io(r1_bio);
-	else {
+	} else {
 		/*
 		 * oops, read error:
 		 */
@@ -320,7 +323,6 @@
 		 * this branch is our 'one mirror IO has finished' event handler:
 		 */
 		r1_bio->bios[mirror] = NULL;
-		bio_put(bio);
 		if (!uptodate) {
 			md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
 			/* an I/O failed, we can't clear the bitmap */
@@ -377,10 +379,9 @@
 		}
 		if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
 			/* free extra copy of the data pages */
-/* FIXME bio has been freed!!! */
 			int i = bio->bi_vcnt;
 			while (i--)
-				__free_page(bio->bi_io_vec[i].bv_page);
+				safe_put_page(bio->bi_io_vec[i].bv_page);
 		}
 		/* clear the bitmap if all writes complete successfully */
 		bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
@@ -391,6 +392,9 @@
 		raid_end_bio_io(r1_bio);
 	}
 
+	if (r1_bio->bios[mirror]==NULL)
+		bio_put(bio);
+
 	rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
 	return 0;
 }
@@ -432,11 +436,13 @@
 		new_disk = 0;
 
 		for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
+		     r1_bio->bios[new_disk] == IO_BLOCKED ||
 		     !rdev || !test_bit(In_sync, &rdev->flags)
 			     || test_bit(WriteMostly, &rdev->flags);
 		     rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) {
 
-			if (rdev && test_bit(In_sync, &rdev->flags))
+			if (rdev && test_bit(In_sync, &rdev->flags) &&
+				r1_bio->bios[new_disk] != IO_BLOCKED)
 				wonly_disk = new_disk;
 
 			if (new_disk == conf->raid_disks - 1) {
@@ -450,11 +456,13 @@
 
 	/* make sure the disk is operational */
 	for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
+	     r1_bio->bios[new_disk] == IO_BLOCKED ||
 	     !rdev || !test_bit(In_sync, &rdev->flags) ||
 		     test_bit(WriteMostly, &rdev->flags);
 	     rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) {
 
-		if (rdev && test_bit(In_sync, &rdev->flags))
+		if (rdev && test_bit(In_sync, &rdev->flags) &&
+		    r1_bio->bios[new_disk] != IO_BLOCKED)
 			wonly_disk = new_disk;
 
 		if (new_disk <= 0)
@@ -491,7 +499,7 @@
 
 		rdev = rcu_dereference(conf->mirrors[disk].rdev);
 
-		if (!rdev ||
+		if (!rdev || r1_bio->bios[disk] == IO_BLOCKED ||
 		    !test_bit(In_sync, &rdev->flags) ||
 		    test_bit(WriteMostly, &rdev->flags))
 			continue;
@@ -519,7 +527,7 @@
 			/* cannot risk returning a device that failed
 			 * before we inc'ed nr_pending
 			 */
-			atomic_dec(&rdev->nr_pending);
+			rdev_dec_pending(rdev, conf->mddev);
 			goto retry;
 		}
 		conf->next_seq_sect = this_sector + sectors;
@@ -592,42 +600,119 @@
 	return ret;
 }
 
-/*
- * Throttle resync depth, so that we can both get proper overlapping of
- * requests, but are still able to handle normal requests quickly.
+/* Barriers....
+ * Sometimes we need to suspend IO while we do something else,
+ * either some resync/recovery, or reconfigure the array.
+ * To do this we raise a 'barrier'.
+ * The 'barrier' is a counter that can be raised multiple times
+ * to count how many activities are happening which preclude
+ * normal IO.
+ * We can only raise the barrier if there is no pending IO.
+ * i.e. if nr_pending == 0.
+ * We choose only to raise the barrier if no-one is waiting for the
+ * barrier to go down.  This means that as soon as an IO request
+ * is ready, no other operations which require a barrier will start
+ * until the IO request has had a chance.
+ *
+ * So: regular IO calls 'wait_barrier'.  When that returns there
+ *    is no backgroup IO happening,  It must arrange to call
+ *    allow_barrier when it has finished its IO.
+ * backgroup IO calls must call raise_barrier.  Once that returns
+ *    there is no normal IO happeing.  It must arrange to call
+ *    lower_barrier when the particular background IO completes.
  */
 #define RESYNC_DEPTH 32
 
-static void device_barrier(conf_t *conf, sector_t sect)
+static void raise_barrier(conf_t *conf)
 {
 	spin_lock_irq(&conf->resync_lock);
-	wait_event_lock_irq(conf->wait_idle, !waitqueue_active(&conf->wait_resume),
-			    conf->resync_lock, raid1_unplug(conf->mddev->queue));
-	
-	if (!conf->barrier++) {
-		wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
-				    conf->resync_lock, raid1_unplug(conf->mddev->queue));
-		if (conf->nr_pending)
-			BUG();
-	}
-	wait_event_lock_irq(conf->wait_resume, conf->barrier < RESYNC_DEPTH,
-			    conf->resync_lock, raid1_unplug(conf->mddev->queue));
-	conf->next_resync = sect;
+
+	/* Wait until no block IO is waiting */
+	wait_event_lock_irq(conf->wait_barrier, !conf->nr_waiting,
+			    conf->resync_lock,
+			    raid1_unplug(conf->mddev->queue));
+
+	/* block any new IO from starting */
+	conf->barrier++;
+
+	/* No wait for all pending IO to complete */
+	wait_event_lock_irq(conf->wait_barrier,
+			    !conf->nr_pending && conf->barrier < RESYNC_DEPTH,
+			    conf->resync_lock,
+			    raid1_unplug(conf->mddev->queue));
+
 	spin_unlock_irq(&conf->resync_lock);
 }
 
+static void lower_barrier(conf_t *conf)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&conf->resync_lock, flags);
+	conf->barrier--;
+	spin_unlock_irqrestore(&conf->resync_lock, flags);
+	wake_up(&conf->wait_barrier);
+}
+
+static void wait_barrier(conf_t *conf)
+{
+	spin_lock_irq(&conf->resync_lock);
+	if (conf->barrier) {
+		conf->nr_waiting++;
+		wait_event_lock_irq(conf->wait_barrier, !conf->barrier,
+				    conf->resync_lock,
+				    raid1_unplug(conf->mddev->queue));
+		conf->nr_waiting--;
+	}
+	conf->nr_pending++;
+	spin_unlock_irq(&conf->resync_lock);
+}
+
+static void allow_barrier(conf_t *conf)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&conf->resync_lock, flags);
+	conf->nr_pending--;
+	spin_unlock_irqrestore(&conf->resync_lock, flags);
+	wake_up(&conf->wait_barrier);
+}
+
+static void freeze_array(conf_t *conf)
+{
+	/* stop syncio and normal IO and wait for everything to
+	 * go quite.
+	 * We increment barrier and nr_waiting, and then
+	 * wait until barrier+nr_pending match nr_queued+2
+	 */
+	spin_lock_irq(&conf->resync_lock);
+	conf->barrier++;
+	conf->nr_waiting++;
+	wait_event_lock_irq(conf->wait_barrier,
+			    conf->barrier+conf->nr_pending == conf->nr_queued+2,
+			    conf->resync_lock,
+			    raid1_unplug(conf->mddev->queue));
+	spin_unlock_irq(&conf->resync_lock);
+}
+static void unfreeze_array(conf_t *conf)
+{
+	/* reverse the effect of the freeze */
+	spin_lock_irq(&conf->resync_lock);
+	conf->barrier--;
+	conf->nr_waiting--;
+	wake_up(&conf->wait_barrier);
+	spin_unlock_irq(&conf->resync_lock);
+}
+
+
 /* duplicate the data pages for behind I/O */
 static struct page **alloc_behind_pages(struct bio *bio)
 {
 	int i;
 	struct bio_vec *bvec;
-	struct page **pages = kmalloc(bio->bi_vcnt * sizeof(struct page *),
+	struct page **pages = kzalloc(bio->bi_vcnt * sizeof(struct page *),
 					GFP_NOIO);
 	if (unlikely(!pages))
 		goto do_sync_io;
 
-	memset(pages, 0, bio->bi_vcnt * sizeof(struct page *));
-
 	bio_for_each_segment(bvec, bio, i) {
 		pages[i] = alloc_page(GFP_NOIO);
 		if (unlikely(!pages[i]))
@@ -643,7 +728,7 @@
 do_sync_io:
 	if (pages)
 		for (i = 0; i < bio->bi_vcnt && pages[i]; i++)
-			__free_page(pages[i]);
+			put_page(pages[i]);
 	kfree(pages);
 	PRINTK("%dB behind alloc failed, doing sync I/O\n", bio->bi_size);
 	return NULL;
@@ -677,10 +762,7 @@
 	 */
 	md_write_start(mddev, bio); /* wait on superblock update early */
 
-	spin_lock_irq(&conf->resync_lock);
-	wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock, );
-	conf->nr_pending++;
-	spin_unlock_irq(&conf->resync_lock);
+	wait_barrier(conf);
 
 	disk_stat_inc(mddev->gendisk, ios[rw]);
 	disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
@@ -748,7 +830,7 @@
 		    !test_bit(Faulty, &rdev->flags)) {
 			atomic_inc(&rdev->nr_pending);
 			if (test_bit(Faulty, &rdev->flags)) {
-				atomic_dec(&rdev->nr_pending);
+				rdev_dec_pending(rdev, mddev);
 				r1_bio->bios[i] = NULL;
 			} else
 				r1_bio->bios[i] = bio;
@@ -908,13 +990,8 @@
 
 static void close_sync(conf_t *conf)
 {
-	spin_lock_irq(&conf->resync_lock);
-	wait_event_lock_irq(conf->wait_resume, !conf->barrier,
-			    conf->resync_lock, 	raid1_unplug(conf->mddev->queue));
-	spin_unlock_irq(&conf->resync_lock);
-
-	if (conf->barrier) BUG();
-	if (waitqueue_active(&conf->wait_idle)) BUG();
+	wait_barrier(conf);
+	allow_barrier(conf);
 
 	mempool_destroy(conf->r1buf_pool);
 	conf->r1buf_pool = NULL;
@@ -953,9 +1030,6 @@
 	int mirror = 0;
 	mirror_info_t *p;
 
-	if (rdev->saved_raid_disk >= 0 &&
-	    conf->mirrors[rdev->saved_raid_disk].rdev == NULL)
-		mirror = rdev->saved_raid_disk;
 	for (mirror=0; mirror < mddev->raid_disks; mirror++)
 		if ( !(p=conf->mirrors+mirror)->rdev) {
 
@@ -972,7 +1046,10 @@
 			p->head_position = 0;
 			rdev->raid_disk = mirror;
 			found = 1;
-			if (rdev->saved_raid_disk != mirror)
+			/* As all devices are equivalent, we don't need a full recovery
+			 * if this was recently any drive of the array
+			 */
+			if (rdev->saved_raid_disk < 0)
 				conf->fullsync = 1;
 			rcu_assign_pointer(p->rdev, rdev);
 			break;
@@ -1014,28 +1091,27 @@
 
 static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error)
 {
-	int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
 	r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
-	conf_t *conf = mddev_to_conf(r1_bio->mddev);
+	int i;
 
 	if (bio->bi_size)
 		return 1;
 
-	if (r1_bio->bios[r1_bio->read_disk] != bio)
-		BUG();
-	update_head_pos(r1_bio->read_disk, r1_bio);
+	for (i=r1_bio->mddev->raid_disks; i--; )
+		if (r1_bio->bios[i] == bio)
+			break;
+	BUG_ON(i < 0);
+	update_head_pos(i, r1_bio);
 	/*
 	 * we have read a block, now it needs to be re-written,
 	 * or re-read if the read failed.
 	 * We don't do much here, just schedule handling by raid1d
 	 */
-	if (!uptodate) {
-		md_error(r1_bio->mddev,
-			 conf->mirrors[r1_bio->read_disk].rdev);
-	} else
+	if (test_bit(BIO_UPTODATE, &bio->bi_flags))
 		set_bit(R1BIO_Uptodate, &r1_bio->state);
-	rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);
-	reschedule_retry(r1_bio);
+
+	if (atomic_dec_and_test(&r1_bio->remaining))
+		reschedule_retry(r1_bio);
 	return 0;
 }
 
@@ -1065,7 +1141,6 @@
 		md_done_sync(mddev, r1_bio->sectors, uptodate);
 		put_buf(r1_bio);
 	}
-	rdev_dec_pending(conf->mirrors[mirror].rdev, mddev);
 	return 0;
 }
 
@@ -1078,34 +1153,173 @@
 
 	bio = r1_bio->bios[r1_bio->read_disk];
 
-/*
-	if (r1_bio->sector == 0) printk("First sync write startss\n");
-*/
+
+	if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
+		/* We have read all readable devices.  If we haven't
+		 * got the block, then there is no hope left.
+		 * If we have, then we want to do a comparison
+		 * and skip the write if everything is the same.
+		 * If any blocks failed to read, then we need to
+		 * attempt an over-write
+		 */
+		int primary;
+		if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) {
+			for (i=0; i<mddev->raid_disks; i++)
+				if (r1_bio->bios[i]->bi_end_io == end_sync_read)
+					md_error(mddev, conf->mirrors[i].rdev);
+
+			md_done_sync(mddev, r1_bio->sectors, 1);
+			put_buf(r1_bio);
+			return;
+		}
+		for (primary=0; primary<mddev->raid_disks; primary++)
+			if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
+			    test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) {
+				r1_bio->bios[primary]->bi_end_io = NULL;
+				rdev_dec_pending(conf->mirrors[primary].rdev, mddev);
+				break;
+			}
+		r1_bio->read_disk = primary;
+		for (i=0; i<mddev->raid_disks; i++)
+			if (r1_bio->bios[i]->bi_end_io == end_sync_read &&
+			    test_bit(BIO_UPTODATE, &r1_bio->bios[i]->bi_flags)) {
+				int j;
+				int vcnt = r1_bio->sectors >> (PAGE_SHIFT- 9);
+				struct bio *pbio = r1_bio->bios[primary];
+				struct bio *sbio = r1_bio->bios[i];
+				for (j = vcnt; j-- ; )
+					if (memcmp(page_address(pbio->bi_io_vec[j].bv_page),
+						   page_address(sbio->bi_io_vec[j].bv_page),
+						   PAGE_SIZE))
+						break;
+				if (j >= 0)
+					mddev->resync_mismatches += r1_bio->sectors;
+				if (j < 0 || test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) {
+					sbio->bi_end_io = NULL;
+					rdev_dec_pending(conf->mirrors[i].rdev, mddev);
+				} else {
+					/* fixup the bio for reuse */
+					sbio->bi_vcnt = vcnt;
+					sbio->bi_size = r1_bio->sectors << 9;
+					sbio->bi_idx = 0;
+					sbio->bi_phys_segments = 0;
+					sbio->bi_hw_segments = 0;
+					sbio->bi_hw_front_size = 0;
+					sbio->bi_hw_back_size = 0;
+					sbio->bi_flags &= ~(BIO_POOL_MASK - 1);
+					sbio->bi_flags |= 1 << BIO_UPTODATE;
+					sbio->bi_next = NULL;
+					sbio->bi_sector = r1_bio->sector +
+						conf->mirrors[i].rdev->data_offset;
+					sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
+				}
+			}
+	}
+	if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) {
+		/* ouch - failed to read all of that.
+		 * Try some synchronous reads of other devices to get
+		 * good data, much like with normal read errors.  Only
+		 * read into the pages we already have so they we don't
+		 * need to re-issue the read request.
+		 * We don't need to freeze the array, because being in an
+		 * active sync request, there is no normal IO, and
+		 * no overlapping syncs.
+		 */
+		sector_t sect = r1_bio->sector;
+		int sectors = r1_bio->sectors;
+		int idx = 0;
+
+		while(sectors) {
+			int s = sectors;
+			int d = r1_bio->read_disk;
+			int success = 0;
+			mdk_rdev_t *rdev;
+
+			if (s > (PAGE_SIZE>>9))
+				s = PAGE_SIZE >> 9;
+			do {
+				if (r1_bio->bios[d]->bi_end_io == end_sync_read) {
+					rdev = conf->mirrors[d].rdev;
+					if (sync_page_io(rdev->bdev,
+							 sect + rdev->data_offset,
+							 s<<9,
+							 bio->bi_io_vec[idx].bv_page,
+							 READ)) {
+						success = 1;
+						break;
+					}
+				}
+				d++;
+				if (d == conf->raid_disks)
+					d = 0;
+			} while (!success && d != r1_bio->read_disk);
+
+			if (success) {
+				int start = d;
+				/* write it back and re-read */
+				set_bit(R1BIO_Uptodate, &r1_bio->state);
+				while (d != r1_bio->read_disk) {
+					if (d == 0)
+						d = conf->raid_disks;
+					d--;
+					if (r1_bio->bios[d]->bi_end_io != end_sync_read)
+						continue;
+					rdev = conf->mirrors[d].rdev;
+					atomic_add(s, &rdev->corrected_errors);
+					if (sync_page_io(rdev->bdev,
+							 sect + rdev->data_offset,
+							 s<<9,
+							 bio->bi_io_vec[idx].bv_page,
+							 WRITE) == 0)
+						md_error(mddev, rdev);
+				}
+				d = start;
+				while (d != r1_bio->read_disk) {
+					if (d == 0)
+						d = conf->raid_disks;
+					d--;
+					if (r1_bio->bios[d]->bi_end_io != end_sync_read)
+						continue;
+					rdev = conf->mirrors[d].rdev;
+					if (sync_page_io(rdev->bdev,
+							 sect + rdev->data_offset,
+							 s<<9,
+							 bio->bi_io_vec[idx].bv_page,
+							 READ) == 0)
+						md_error(mddev, rdev);
+				}
+			} else {
+				char b[BDEVNAME_SIZE];
+				/* Cannot read from anywhere, array is toast */
+				md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
+				printk(KERN_ALERT "raid1: %s: unrecoverable I/O read error"
+				       " for block %llu\n",
+				       bdevname(bio->bi_bdev,b),
+				       (unsigned long long)r1_bio->sector);
+				md_done_sync(mddev, r1_bio->sectors, 0);
+				put_buf(r1_bio);
+				return;
+			}
+			sectors -= s;
+			sect += s;
+			idx ++;
+		}
+	}
+
 	/*
 	 * schedule writes
 	 */
-	if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) {
-		/*
-		 * There is no point trying a read-for-reconstruct as
-		 * reconstruct is about to be aborted
-		 */
-		char b[BDEVNAME_SIZE];
-		printk(KERN_ALERT "raid1: %s: unrecoverable I/O read error"
-			" for block %llu\n",
-			bdevname(bio->bi_bdev,b), 
-			(unsigned long long)r1_bio->sector);
-		md_done_sync(mddev, r1_bio->sectors, 0);
-		put_buf(r1_bio);
-		return;
-	}
-
 	atomic_set(&r1_bio->remaining, 1);
 	for (i = 0; i < disks ; i++) {
 		wbio = r1_bio->bios[i];
-		if (wbio->bi_end_io != end_sync_write)
+		if (wbio->bi_end_io == NULL ||
+		    (wbio->bi_end_io == end_sync_read &&
+		     (i == r1_bio->read_disk ||
+		      !test_bit(MD_RECOVERY_SYNC, &mddev->recovery))))
 			continue;
 
-		atomic_inc(&conf->mirrors[i].rdev->nr_pending);
+		wbio->bi_rw = WRITE;
+		wbio->bi_end_io = end_sync_write;
 		atomic_inc(&r1_bio->remaining);
 		md_sync_acct(conf->mirrors[i].rdev->bdev, wbio->bi_size >> 9);
 
@@ -1166,6 +1380,7 @@
 			break;
 		r1_bio = list_entry(head->prev, r1bio_t, retry_list);
 		list_del(head->prev);
+		conf->nr_queued--;
 		spin_unlock_irqrestore(&conf->device_lock, flags);
 
 		mddev = r1_bio->mddev;
@@ -1205,6 +1420,86 @@
 				}
 		} else {
 			int disk;
+
+			/* we got a read error. Maybe the drive is bad.  Maybe just
+			 * the block and we can fix it.
+			 * We freeze all other IO, and try reading the block from
+			 * other devices.  When we find one, we re-write
+			 * and check it that fixes the read error.
+			 * This is all done synchronously while the array is
+			 * frozen
+			 */
+			sector_t sect = r1_bio->sector;
+			int sectors = r1_bio->sectors;
+			freeze_array(conf);
+			if (mddev->ro == 0) while(sectors) {
+				int s = sectors;
+				int d = r1_bio->read_disk;
+				int success = 0;
+
+				if (s > (PAGE_SIZE>>9))
+					s = PAGE_SIZE >> 9;
+
+				do {
+					rdev = conf->mirrors[d].rdev;
+					if (rdev &&
+					    test_bit(In_sync, &rdev->flags) &&
+					    sync_page_io(rdev->bdev,
+							 sect + rdev->data_offset,
+							 s<<9,
+							 conf->tmppage, READ))
+						success = 1;
+					else {
+						d++;
+						if (d == conf->raid_disks)
+							d = 0;
+					}
+				} while (!success && d != r1_bio->read_disk);
+
+				if (success) {
+					/* write it back and re-read */
+					int start = d;
+					while (d != r1_bio->read_disk) {
+						if (d==0)
+							d = conf->raid_disks;
+						d--;
+						rdev = conf->mirrors[d].rdev;
+						atomic_add(s, &rdev->corrected_errors);
+						if (rdev &&
+						    test_bit(In_sync, &rdev->flags)) {
+							if (sync_page_io(rdev->bdev,
+									 sect + rdev->data_offset,
+									 s<<9, conf->tmppage, WRITE) == 0)
+								/* Well, this device is dead */
+								md_error(mddev, rdev);
+						}
+					}
+					d = start;
+					while (d != r1_bio->read_disk) {
+						if (d==0)
+							d = conf->raid_disks;
+						d--;
+						rdev = conf->mirrors[d].rdev;
+						if (rdev &&
+						    test_bit(In_sync, &rdev->flags)) {
+							if (sync_page_io(rdev->bdev,
+									 sect + rdev->data_offset,
+									 s<<9, conf->tmppage, READ) == 0)
+								/* Well, this device is dead */
+								md_error(mddev, rdev);
+						}
+					}
+				} else {
+					/* Cannot read from anywhere -- bye bye array */
+					md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
+					break;
+				}
+				sectors -= s;
+				sect += s;
+			}
+
+			unfreeze_array(conf);
+
 			bio = r1_bio->bios[r1_bio->read_disk];
 			if ((disk=read_balance(conf, r1_bio)) == -1) {
 				printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
@@ -1213,7 +1508,8 @@
 				       (unsigned long long)r1_bio->sector);
 				raid_end_bio_io(r1_bio);
 			} else {
-				r1_bio->bios[r1_bio->read_disk] = NULL;
+				r1_bio->bios[r1_bio->read_disk] =
+					mddev->ro ? IO_BLOCKED : NULL;
 				r1_bio->read_disk = disk;
 				bio_put(bio);
 				bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
@@ -1268,14 +1564,13 @@
 static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
 {
 	conf_t *conf = mddev_to_conf(mddev);
-	mirror_info_t *mirror;
 	r1bio_t *r1_bio;
 	struct bio *bio;
 	sector_t max_sector, nr_sectors;
-	int disk;
+	int disk = -1;
 	int i;
-	int wonly;
-	int write_targets = 0;
+	int wonly = -1;
+	int write_targets = 0, read_targets = 0;
 	int sync_blocks;
 	int still_degraded = 0;
 
@@ -1316,55 +1611,35 @@
 		return sync_blocks;
 	}
 	/*
-	 * If there is non-resync activity waiting for us then
-	 * put in a delay to throttle resync.
+	 * If there is non-resync activity waiting for a turn,
+	 * and resync is going fast enough,
+	 * then let it though before starting on this new sync request.
 	 */
-	if (!go_faster && waitqueue_active(&conf->wait_resume))
+	if (!go_faster && conf->nr_waiting)
 		msleep_interruptible(1000);
-	device_barrier(conf, sector_nr + RESYNC_SECTORS);
 
-	/*
-	 * If reconstructing, and >1 working disc,
-	 * could dedicate one to rebuild and others to
-	 * service read requests ..
-	 */
-	disk = conf->last_used;
-	/* make sure disk is operational */
-	wonly = disk;
-	while (conf->mirrors[disk].rdev == NULL ||
-	       !test_bit(In_sync, &conf->mirrors[disk].rdev->flags) ||
-	       test_bit(WriteMostly, &conf->mirrors[disk].rdev->flags)
-		) {
-		if (conf->mirrors[disk].rdev  &&
-		    test_bit(In_sync, &conf->mirrors[disk].rdev->flags))
-			wonly = disk;
-		if (disk <= 0)
-			disk = conf->raid_disks;
-		disk--;
-		if (disk == conf->last_used) {
-			disk = wonly;
-			break;
-		}
-	}
-	conf->last_used = disk;
-	atomic_inc(&conf->mirrors[disk].rdev->nr_pending);
+	raise_barrier(conf);
 
-
-	mirror = conf->mirrors + disk;
+	conf->next_resync = sector_nr;
 
 	r1_bio = mempool_alloc(conf->r1buf_pool, GFP_NOIO);
-
-	spin_lock_irq(&conf->resync_lock);
-	conf->nr_pending++;
-	spin_unlock_irq(&conf->resync_lock);
+	rcu_read_lock();
+	/*
+	 * If we get a correctably read error during resync or recovery,
+	 * we might want to read from a different device.  So we
+	 * flag all drives that could conceivably be read from for READ,
+	 * and any others (which will be non-In_sync devices) for WRITE.
+	 * If a read fails, we try reading from something else for which READ
+	 * is OK.
+	 */
 
 	r1_bio->mddev = mddev;
 	r1_bio->sector = sector_nr;
 	r1_bio->state = 0;
 	set_bit(R1BIO_IsSync, &r1_bio->state);
-	r1_bio->read_disk = disk;
 
 	for (i=0; i < conf->raid_disks; i++) {
+		mdk_rdev_t *rdev;
 		bio = r1_bio->bios[i];
 
 		/* take from bio_init */
@@ -1379,35 +1654,49 @@
 		bio->bi_end_io = NULL;
 		bio->bi_private = NULL;
 
-		if (i == disk) {
-			bio->bi_rw = READ;
-			bio->bi_end_io = end_sync_read;
-		} else if (conf->mirrors[i].rdev == NULL ||
-			   test_bit(Faulty, &conf->mirrors[i].rdev->flags)) {
+		rdev = rcu_dereference(conf->mirrors[i].rdev);
+		if (rdev == NULL ||
+			   test_bit(Faulty, &rdev->flags)) {
 			still_degraded = 1;
 			continue;
-		} else if (!test_bit(In_sync, &conf->mirrors[i].rdev->flags) ||
-			   sector_nr + RESYNC_SECTORS > mddev->recovery_cp   ||
-			   test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
+		} else if (!test_bit(In_sync, &rdev->flags)) {
 			bio->bi_rw = WRITE;
 			bio->bi_end_io = end_sync_write;
 			write_targets ++;
-		} else
-			/* no need to read or write here */
-			continue;
-		bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset;
-		bio->bi_bdev = conf->mirrors[i].rdev->bdev;
+		} else {
+			/* may need to read from here */
+			bio->bi_rw = READ;
+			bio->bi_end_io = end_sync_read;
+			if (test_bit(WriteMostly, &rdev->flags)) {
+				if (wonly < 0)
+					wonly = i;
+			} else {
+				if (disk < 0)
+					disk = i;
+			}
+			read_targets++;
+		}
+		atomic_inc(&rdev->nr_pending);
+		bio->bi_sector = sector_nr + rdev->data_offset;
+		bio->bi_bdev = rdev->bdev;
 		bio->bi_private = r1_bio;
 	}
+	rcu_read_unlock();
+	if (disk < 0)
+		disk = wonly;
+	r1_bio->read_disk = disk;
 
-	if (write_targets == 0) {
+	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && read_targets > 0)
+		/* extra read targets are also write targets */
+		write_targets += read_targets-1;
+
+	if (write_targets == 0 || read_targets == 0) {
 		/* There is nowhere to write, so all non-sync
 		 * drives must be failed - so we are finished
 		 */
 		sector_t rv = max_sector - sector_nr;
 		*skipped = 1;
 		put_buf(r1_bio);
-		rdev_dec_pending(conf->mirrors[disk].rdev, mddev);
 		return rv;
 	}
 
@@ -1435,10 +1724,10 @@
 		for (i=0 ; i < conf->raid_disks; i++) {
 			bio = r1_bio->bios[i];
 			if (bio->bi_end_io) {
-				page = r1_bio->bios[0]->bi_io_vec[bio->bi_vcnt].bv_page;
+				page = bio->bi_io_vec[bio->bi_vcnt].bv_page;
 				if (bio_add_page(bio, page, len, 0) == 0) {
 					/* stop here */
-					r1_bio->bios[0]->bi_io_vec[bio->bi_vcnt].bv_page = page;
+					bio->bi_io_vec[bio->bi_vcnt].bv_page = page;
 					while (i > 0) {
 						i--;
 						bio = r1_bio->bios[i];
@@ -1458,12 +1747,28 @@
 		sync_blocks -= (len>>9);
 	} while (r1_bio->bios[disk]->bi_vcnt < RESYNC_PAGES);
  bio_full:
-	bio = r1_bio->bios[disk];
 	r1_bio->sectors = nr_sectors;
 
-	md_sync_acct(mirror->rdev->bdev, nr_sectors);
+	/* For a user-requested sync, we read all readable devices and do a
+	 * compare
+	 */
+	if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
+		atomic_set(&r1_bio->remaining, read_targets);
+		for (i=0; i<conf->raid_disks; i++) {
+			bio = r1_bio->bios[i];
+			if (bio->bi_end_io == end_sync_read) {
+				md_sync_acct(conf->mirrors[i].rdev->bdev, nr_sectors);
+				generic_make_request(bio);
+			}
+		}
+	} else {
+		atomic_set(&r1_bio->remaining, 1);
+		bio = r1_bio->bios[r1_bio->read_disk];
+		md_sync_acct(conf->mirrors[r1_bio->read_disk].rdev->bdev,
+			     nr_sectors);
+		generic_make_request(bio);
 
-	generic_make_request(bio);
+	}
 
 	return nr_sectors;
 }
@@ -1486,18 +1791,19 @@
 	 * bookkeeping area. [whatever we allocate in run(),
 	 * should be freed in stop()]
 	 */
-	conf = kmalloc(sizeof(conf_t), GFP_KERNEL);
+	conf = kzalloc(sizeof(conf_t), GFP_KERNEL);
 	mddev->private = conf;
 	if (!conf)
 		goto out_no_mem;
 
-	memset(conf, 0, sizeof(*conf));
-	conf->mirrors = kmalloc(sizeof(struct mirror_info)*mddev->raid_disks, 
+	conf->mirrors = kzalloc(sizeof(struct mirror_info)*mddev->raid_disks,
 				 GFP_KERNEL);
 	if (!conf->mirrors)
 		goto out_no_mem;
 
-	memset(conf->mirrors, 0, sizeof(struct mirror_info)*mddev->raid_disks);
+	conf->tmppage = alloc_page(GFP_KERNEL);
+	if (!conf->tmppage)
+		goto out_no_mem;
 
 	conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
 	if (!conf->poolinfo)
@@ -1541,8 +1847,7 @@
 		mddev->recovery_cp = MaxSector;
 
 	spin_lock_init(&conf->resync_lock);
-	init_waitqueue_head(&conf->wait_idle);
-	init_waitqueue_head(&conf->wait_resume);
+	init_waitqueue_head(&conf->wait_barrier);
 
 	bio_list_init(&conf->pending_bio_list);
 	bio_list_init(&conf->flushing_bio_list);
@@ -1582,7 +1887,6 @@
 		       mdname(mddev));
 		goto out_free_conf;
 	}
-	if (mddev->bitmap) mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
 
 	printk(KERN_INFO 
 		"raid1: raid set %s active with %d out of %d mirrors\n",
@@ -1607,6 +1911,7 @@
 		if (conf->r1bio_pool)
 			mempool_destroy(conf->r1bio_pool);
 		kfree(conf->mirrors);
+		safe_put_page(conf->tmppage);
 		kfree(conf->poolinfo);
 		kfree(conf);
 		mddev->private = NULL;
@@ -1705,19 +2010,14 @@
 		kfree(newpoolinfo);
 		return -ENOMEM;
 	}
-	newmirrors = kmalloc(sizeof(struct mirror_info) * raid_disks, GFP_KERNEL);
+	newmirrors = kzalloc(sizeof(struct mirror_info) * raid_disks, GFP_KERNEL);
 	if (!newmirrors) {
 		kfree(newpoolinfo);
 		mempool_destroy(newpool);
 		return -ENOMEM;
 	}
-	memset(newmirrors, 0, sizeof(struct mirror_info)*raid_disks);
 
-	spin_lock_irq(&conf->resync_lock);
-	conf->barrier++;
-	wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
-			    conf->resync_lock, raid1_unplug(mddev->queue));
-	spin_unlock_irq(&conf->resync_lock);
+	raise_barrier(conf);
 
 	/* ok, everything is stopped */
 	oldpool = conf->r1bio_pool;
@@ -1737,12 +2037,7 @@
 	conf->raid_disks = mddev->raid_disks = raid_disks;
 
 	conf->last_used = 0; /* just make sure it is in-range */
-	spin_lock_irq(&conf->resync_lock);
-	conf->barrier--;
-	spin_unlock_irq(&conf->resync_lock);
-	wake_up(&conf->wait_resume);
-	wake_up(&conf->wait_idle);
-
+	lower_barrier(conf);
 
 	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	md_wakeup_thread(mddev->thread);
@@ -1757,33 +2052,19 @@
 
 	switch(state) {
 	case 1:
-		spin_lock_irq(&conf->resync_lock);
-		conf->barrier++;
-		wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
-				    conf->resync_lock, raid1_unplug(mddev->queue));
-		spin_unlock_irq(&conf->resync_lock);
+		raise_barrier(conf);
 		break;
 	case 0:
-		spin_lock_irq(&conf->resync_lock);
-		conf->barrier--;
-		spin_unlock_irq(&conf->resync_lock);
-		wake_up(&conf->wait_resume);
-		wake_up(&conf->wait_idle);
+		lower_barrier(conf);
 		break;
 	}
-	if (mddev->thread) {
-		if (mddev->bitmap)
-			mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
-		else
-			mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
-		md_wakeup_thread(mddev->thread);
-	}
 }
 
 
-static mdk_personality_t raid1_personality =
+static struct mdk_personality raid1_personality =
 {
 	.name		= "raid1",
+	.level		= 1,
 	.owner		= THIS_MODULE,
 	.make_request	= make_request,
 	.run		= run,
@@ -1801,15 +2082,17 @@
 
 static int __init raid_init(void)
 {
-	return register_md_personality(RAID1, &raid1_personality);
+	return register_md_personality(&raid1_personality);
 }
 
 static void raid_exit(void)
 {
-	unregister_md_personality(RAID1);
+	unregister_md_personality(&raid1_personality);
 }
 
 module_init(raid_init);
 module_exit(raid_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("md-personality-3"); /* RAID1 */
+MODULE_ALIAS("md-raid1");
+MODULE_ALIAS("md-level-1");
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 867f06a..9e658e5 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -18,7 +18,9 @@
  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#include "dm-bio-list.h"
 #include <linux/raid/raid10.h>
+#include <linux/raid/bitmap.h>
 
 /*
  * RAID10 provides a combination of RAID0 and RAID1 functionality.
@@ -47,6 +49,9 @@
 
 static void unplug_slaves(mddev_t *mddev);
 
+static void allow_barrier(conf_t *conf);
+static void lower_barrier(conf_t *conf);
+
 static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
 {
 	conf_t *conf = data;
@@ -54,10 +59,8 @@
 	int size = offsetof(struct r10bio_s, devs[conf->copies]);
 
 	/* allocate a r10bio with room for raid_disks entries in the bios array */
-	r10_bio = kmalloc(size, gfp_flags);
-	if (r10_bio)
-		memset(r10_bio, 0, size);
-	else
+	r10_bio = kzalloc(size, gfp_flags);
+	if (!r10_bio)
 		unplug_slaves(conf->mddev);
 
 	return r10_bio;
@@ -129,10 +132,10 @@
 
 out_free_pages:
 	for ( ; i > 0 ; i--)
-		__free_page(bio->bi_io_vec[i-1].bv_page);
+		safe_put_page(bio->bi_io_vec[i-1].bv_page);
 	while (j--)
 		for (i = 0; i < RESYNC_PAGES ; i++)
-			__free_page(r10_bio->devs[j].bio->bi_io_vec[i].bv_page);
+			safe_put_page(r10_bio->devs[j].bio->bi_io_vec[i].bv_page);
 	j = -1;
 out_free_bio:
 	while ( ++j < nalloc )
@@ -152,7 +155,7 @@
 		struct bio *bio = r10bio->devs[j].bio;
 		if (bio) {
 			for (i = 0; i < RESYNC_PAGES; i++) {
-				__free_page(bio->bi_io_vec[i].bv_page);
+				safe_put_page(bio->bi_io_vec[i].bv_page);
 				bio->bi_io_vec[i].bv_page = NULL;
 			}
 			bio_put(bio);
@@ -167,7 +170,7 @@
 
 	for (i = 0; i < conf->copies; i++) {
 		struct bio **bio = & r10_bio->devs[i].bio;
-		if (*bio)
+		if (*bio && *bio != IO_BLOCKED)
 			bio_put(*bio);
 		*bio = NULL;
 	}
@@ -175,20 +178,13 @@
 
 static inline void free_r10bio(r10bio_t *r10_bio)
 {
-	unsigned long flags;
-
 	conf_t *conf = mddev_to_conf(r10_bio->mddev);
 
 	/*
 	 * Wake up any possible resync thread that waits for the device
 	 * to go idle.
 	 */
-	spin_lock_irqsave(&conf->resync_lock, flags);
-	if (!--conf->nr_pending) {
-		wake_up(&conf->wait_idle);
-		wake_up(&conf->wait_resume);
-	}
-	spin_unlock_irqrestore(&conf->resync_lock, flags);
+	allow_barrier(conf);
 
 	put_all_bios(conf, r10_bio);
 	mempool_free(r10_bio, conf->r10bio_pool);
@@ -197,22 +193,10 @@
 static inline void put_buf(r10bio_t *r10_bio)
 {
 	conf_t *conf = mddev_to_conf(r10_bio->mddev);
-	unsigned long flags;
 
 	mempool_free(r10_bio, conf->r10buf_pool);
 
-	spin_lock_irqsave(&conf->resync_lock, flags);
-	if (!conf->barrier)
-		BUG();
-	--conf->barrier;
-	wake_up(&conf->wait_resume);
-	wake_up(&conf->wait_idle);
-
-	if (!--conf->nr_pending) {
-		wake_up(&conf->wait_idle);
-		wake_up(&conf->wait_resume);
-	}
-	spin_unlock_irqrestore(&conf->resync_lock, flags);
+	lower_barrier(conf);
 }
 
 static void reschedule_retry(r10bio_t *r10_bio)
@@ -223,6 +207,7 @@
 
 	spin_lock_irqsave(&conf->device_lock, flags);
 	list_add(&r10_bio->retry_list, &conf->retry_list);
+	conf->nr_queued ++;
 	spin_unlock_irqrestore(&conf->device_lock, flags);
 
 	md_wakeup_thread(mddev->thread);
@@ -268,9 +253,9 @@
 	/*
 	 * this branch is our 'one mirror IO has finished' event handler:
 	 */
-	if (!uptodate)
-		md_error(r10_bio->mddev, conf->mirrors[dev].rdev);
-	else
+	update_head_pos(slot, r10_bio);
+
+	if (uptodate) {
 		/*
 		 * Set R10BIO_Uptodate in our master bio, so that
 		 * we will return a good error code to the higher
@@ -281,15 +266,8 @@
 		 * wait for the 'master' bio.
 		 */
 		set_bit(R10BIO_Uptodate, &r10_bio->state);
-
-	update_head_pos(slot, r10_bio);
-
-	/*
-	 * we have only one bio on the read side
-	 */
-	if (uptodate)
 		raid_end_bio_io(r10_bio);
-	else {
+	} else {
 		/*
 		 * oops, read error:
 		 */
@@ -322,9 +300,11 @@
 	/*
 	 * this branch is our 'one mirror IO has finished' event handler:
 	 */
-	if (!uptodate)
+	if (!uptodate) {
 		md_error(r10_bio->mddev, conf->mirrors[dev].rdev);
-	else
+		/* an I/O failed, we can't clear the bitmap */
+		set_bit(R10BIO_Degraded, &r10_bio->state);
+	} else
 		/*
 		 * Set R10BIO_Uptodate in our master bio, so that
 		 * we will return a good error code for to the higher
@@ -344,6 +324,11 @@
 	 * already.
 	 */
 	if (atomic_dec_and_test(&r10_bio->remaining)) {
+		/* clear the bitmap if all writes complete successfully */
+		bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector,
+				r10_bio->sectors,
+				!test_bit(R10BIO_Degraded, &r10_bio->state),
+				0);
 		md_write_end(r10_bio->mddev);
 		raid_end_bio_io(r10_bio);
 	}
@@ -502,8 +487,9 @@
 	rcu_read_lock();
 	/*
 	 * Check if we can balance. We can balance on the whole
-	 * device if no resync is going on, or below the resync window.
-	 * We take the first readable disk when above the resync window.
+	 * device if no resync is going on (recovery is ok), or below
+	 * the resync window. We take the first readable disk when
+	 * above the resync window.
 	 */
 	if (conf->mddev->recovery_cp < MaxSector
 	    && (this_sector + sectors >= conf->next_resync)) {
@@ -512,6 +498,7 @@
 		disk = r10_bio->devs[slot].devnum;
 
 		while ((rdev = rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
+		       r10_bio->devs[slot].bio == IO_BLOCKED ||
 		       !test_bit(In_sync, &rdev->flags)) {
 			slot++;
 			if (slot == conf->copies) {
@@ -529,6 +516,7 @@
 	slot = 0;
 	disk = r10_bio->devs[slot].devnum;
 	while ((rdev=rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
+	       r10_bio->devs[slot].bio == IO_BLOCKED ||
 	       !test_bit(In_sync, &rdev->flags)) {
 		slot ++;
 		if (slot == conf->copies) {
@@ -549,10 +537,15 @@
 
 
 		if ((rdev=rcu_dereference(conf->mirrors[ndisk].rdev)) == NULL ||
+		    r10_bio->devs[nslot].bio == IO_BLOCKED ||
 		    !test_bit(In_sync, &rdev->flags))
 			continue;
 
-		if (!atomic_read(&rdev->nr_pending)) {
+		/* This optimisation is debatable, and completely destroys
+		 * sequential read speed for 'far copies' arrays.  So only
+		 * keep it for 'near' arrays, and review those later.
+		 */
+		if (conf->near_copies > 1 && !atomic_read(&rdev->nr_pending)) {
 			disk = ndisk;
 			slot = nslot;
 			break;
@@ -603,7 +596,10 @@
 
 static void raid10_unplug(request_queue_t *q)
 {
+	mddev_t *mddev = q->queuedata;
+
 	unplug_slaves(q->queuedata);
+	md_wakeup_thread(mddev->thread);
 }
 
 static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk,
@@ -636,27 +632,107 @@
 	return ret;
 }
 
-/*
- * Throttle resync depth, so that we can both get proper overlapping of
- * requests, but are still able to handle normal requests quickly.
+/* Barriers....
+ * Sometimes we need to suspend IO while we do something else,
+ * either some resync/recovery, or reconfigure the array.
+ * To do this we raise a 'barrier'.
+ * The 'barrier' is a counter that can be raised multiple times
+ * to count how many activities are happening which preclude
+ * normal IO.
+ * We can only raise the barrier if there is no pending IO.
+ * i.e. if nr_pending == 0.
+ * We choose only to raise the barrier if no-one is waiting for the
+ * barrier to go down.  This means that as soon as an IO request
+ * is ready, no other operations which require a barrier will start
+ * until the IO request has had a chance.
+ *
+ * So: regular IO calls 'wait_barrier'.  When that returns there
+ *    is no backgroup IO happening,  It must arrange to call
+ *    allow_barrier when it has finished its IO.
+ * backgroup IO calls must call raise_barrier.  Once that returns
+ *    there is no normal IO happeing.  It must arrange to call
+ *    lower_barrier when the particular background IO completes.
  */
 #define RESYNC_DEPTH 32
 
-static void device_barrier(conf_t *conf, sector_t sect)
+static void raise_barrier(conf_t *conf, int force)
+{
+	BUG_ON(force && !conf->barrier);
+	spin_lock_irq(&conf->resync_lock);
+
+	/* Wait until no block IO is waiting (unless 'force') */
+	wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting,
+			    conf->resync_lock,
+			    raid10_unplug(conf->mddev->queue));
+
+	/* block any new IO from starting */
+	conf->barrier++;
+
+	/* No wait for all pending IO to complete */
+	wait_event_lock_irq(conf->wait_barrier,
+			    !conf->nr_pending && conf->barrier < RESYNC_DEPTH,
+			    conf->resync_lock,
+			    raid10_unplug(conf->mddev->queue));
+
+	spin_unlock_irq(&conf->resync_lock);
+}
+
+static void lower_barrier(conf_t *conf)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&conf->resync_lock, flags);
+	conf->barrier--;
+	spin_unlock_irqrestore(&conf->resync_lock, flags);
+	wake_up(&conf->wait_barrier);
+}
+
+static void wait_barrier(conf_t *conf)
 {
 	spin_lock_irq(&conf->resync_lock);
-	wait_event_lock_irq(conf->wait_idle, !waitqueue_active(&conf->wait_resume),
-			    conf->resync_lock, unplug_slaves(conf->mddev));
-
-	if (!conf->barrier++) {
-		wait_event_lock_irq(conf->wait_idle, !conf->nr_pending,
-				    conf->resync_lock, unplug_slaves(conf->mddev));
-		if (conf->nr_pending)
-			BUG();
+	if (conf->barrier) {
+		conf->nr_waiting++;
+		wait_event_lock_irq(conf->wait_barrier, !conf->barrier,
+				    conf->resync_lock,
+				    raid10_unplug(conf->mddev->queue));
+		conf->nr_waiting--;
 	}
-	wait_event_lock_irq(conf->wait_resume, conf->barrier < RESYNC_DEPTH,
-			    conf->resync_lock, unplug_slaves(conf->mddev));
-	conf->next_resync = sect;
+	conf->nr_pending++;
+	spin_unlock_irq(&conf->resync_lock);
+}
+
+static void allow_barrier(conf_t *conf)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&conf->resync_lock, flags);
+	conf->nr_pending--;
+	spin_unlock_irqrestore(&conf->resync_lock, flags);
+	wake_up(&conf->wait_barrier);
+}
+
+static void freeze_array(conf_t *conf)
+{
+	/* stop syncio and normal IO and wait for everything to
+	 * go quiet.
+	 * We increment barrier and nr_waiting, and then
+	 * wait until barrier+nr_pending match nr_queued+2
+	 */
+	spin_lock_irq(&conf->resync_lock);
+	conf->barrier++;
+	conf->nr_waiting++;
+	wait_event_lock_irq(conf->wait_barrier,
+			    conf->barrier+conf->nr_pending == conf->nr_queued+2,
+			    conf->resync_lock,
+			    raid10_unplug(conf->mddev->queue));
+	spin_unlock_irq(&conf->resync_lock);
+}
+
+static void unfreeze_array(conf_t *conf)
+{
+	/* reverse the effect of the freeze */
+	spin_lock_irq(&conf->resync_lock);
+	conf->barrier--;
+	conf->nr_waiting--;
+	wake_up(&conf->wait_barrier);
 	spin_unlock_irq(&conf->resync_lock);
 }
 
@@ -670,6 +746,8 @@
 	int i;
 	int chunk_sects = conf->chunk_mask + 1;
 	const int rw = bio_data_dir(bio);
+	struct bio_list bl;
+	unsigned long flags;
 
 	if (unlikely(bio_barrier(bio))) {
 		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
@@ -715,10 +793,7 @@
 	 * thread has put up a bar for new requests.
 	 * Continue immediately if no resync is active currently.
 	 */
-	spin_lock_irq(&conf->resync_lock);
-	wait_event_lock_irq(conf->wait_resume, !conf->barrier, conf->resync_lock, );
-	conf->nr_pending++;
-	spin_unlock_irq(&conf->resync_lock);
+	wait_barrier(conf);
 
 	disk_stat_inc(mddev->gendisk, ios[rw]);
 	disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
@@ -730,6 +805,7 @@
 
 	r10_bio->mddev = mddev;
 	r10_bio->sector = bio->bi_sector;
+	r10_bio->state = 0;
 
 	if (rw == READ) {
 		/*
@@ -774,13 +850,16 @@
 		    !test_bit(Faulty, &rdev->flags)) {
 			atomic_inc(&rdev->nr_pending);
 			r10_bio->devs[i].bio = bio;
-		} else
+		} else {
 			r10_bio->devs[i].bio = NULL;
+			set_bit(R10BIO_Degraded, &r10_bio->state);
+		}
 	}
 	rcu_read_unlock();
 
-	atomic_set(&r10_bio->remaining, 1);
+	atomic_set(&r10_bio->remaining, 0);
 
+	bio_list_init(&bl);
 	for (i = 0; i < conf->copies; i++) {
 		struct bio *mbio;
 		int d = r10_bio->devs[i].devnum;
@@ -798,13 +877,14 @@
 		mbio->bi_private = r10_bio;
 
 		atomic_inc(&r10_bio->remaining);
-		generic_make_request(mbio);
+		bio_list_add(&bl, mbio);
 	}
 
-	if (atomic_dec_and_test(&r10_bio->remaining)) {
-		md_write_end(mddev);
-		raid_end_bio_io(r10_bio);
-	}
+	bitmap_startwrite(mddev->bitmap, bio->bi_sector, r10_bio->sectors, 0);
+	spin_lock_irqsave(&conf->device_lock, flags);
+	bio_list_merge(&conf->pending_bio_list, &bl);
+	blk_plug_device(mddev->queue);
+	spin_unlock_irqrestore(&conf->device_lock, flags);
 
 	return 0;
 }
@@ -893,13 +973,8 @@
 
 static void close_sync(conf_t *conf)
 {
-	spin_lock_irq(&conf->resync_lock);
-	wait_event_lock_irq(conf->wait_resume, !conf->barrier,
-			    conf->resync_lock, 	unplug_slaves(conf->mddev));
-	spin_unlock_irq(&conf->resync_lock);
-
-	if (conf->barrier) BUG();
-	if (waitqueue_active(&conf->wait_idle)) BUG();
+	wait_barrier(conf);
+	allow_barrier(conf);
 
 	mempool_destroy(conf->r10buf_pool);
 	conf->r10buf_pool = NULL;
@@ -967,7 +1042,12 @@
 	if (!enough(conf))
 		return 0;
 
-	for (mirror=0; mirror < mddev->raid_disks; mirror++)
+	if (rdev->saved_raid_disk >= 0 &&
+	    conf->mirrors[rdev->saved_raid_disk].rdev == NULL)
+		mirror = rdev->saved_raid_disk;
+	else
+		mirror = 0;
+	for ( ; mirror < mddev->raid_disks; mirror++)
 		if ( !(p=conf->mirrors+mirror)->rdev) {
 
 			blk_queue_stack_limits(mddev->queue,
@@ -983,6 +1063,8 @@
 			p->head_position = 0;
 			rdev->raid_disk = mirror;
 			found = 1;
+			if (rdev->saved_raid_disk != mirror)
+				conf->fullsync = 1;
 			rcu_assign_pointer(p->rdev, rdev);
 			break;
 		}
@@ -1023,7 +1105,6 @@
 
 static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error)
 {
-	int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
 	r10bio_t * r10_bio = (r10bio_t *)(bio->bi_private);
 	conf_t *conf = mddev_to_conf(r10_bio->mddev);
 	int i,d;
@@ -1038,9 +1119,16 @@
 		BUG();
 	update_head_pos(i, r10_bio);
 	d = r10_bio->devs[i].devnum;
-	if (!uptodate)
-		md_error(r10_bio->mddev,
-			 conf->mirrors[d].rdev);
+
+	if (test_bit(BIO_UPTODATE, &bio->bi_flags))
+		set_bit(R10BIO_Uptodate, &r10_bio->state);
+	else {
+		atomic_add(r10_bio->sectors,
+			   &conf->mirrors[d].rdev->corrected_errors);
+		if (!test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery))
+			md_error(r10_bio->mddev,
+				 conf->mirrors[d].rdev);
+	}
 
 	/* for reconstruct, we always reschedule after a read.
 	 * for resync, only after all reads
@@ -1128,23 +1216,32 @@
 	fbio = r10_bio->devs[i].bio;
 
 	/* now find blocks with errors */
-	for (i=first+1 ; i < conf->copies ; i++) {
-		int vcnt, j, d;
+	for (i=0 ; i < conf->copies ; i++) {
+		int  j, d;
+		int vcnt = r10_bio->sectors >> (PAGE_SHIFT-9);
 
-		if (!test_bit(BIO_UPTODATE, &r10_bio->devs[i].bio->bi_flags))
-			continue;
-		/* We know that the bi_io_vec layout is the same for
-		 * both 'first' and 'i', so we just compare them.
-		 * All vec entries are PAGE_SIZE;
-		 */
 		tbio = r10_bio->devs[i].bio;
-		vcnt = r10_bio->sectors >> (PAGE_SHIFT-9);
-		for (j = 0; j < vcnt; j++)
-			if (memcmp(page_address(fbio->bi_io_vec[j].bv_page),
-				   page_address(tbio->bi_io_vec[j].bv_page),
-				   PAGE_SIZE))
-				break;
-		if (j == vcnt)
+
+		if (tbio->bi_end_io != end_sync_read)
+			continue;
+		if (i == first)
+			continue;
+		if (test_bit(BIO_UPTODATE, &r10_bio->devs[i].bio->bi_flags)) {
+			/* We know that the bi_io_vec layout is the same for
+			 * both 'first' and 'i', so we just compare them.
+			 * All vec entries are PAGE_SIZE;
+			 */
+			for (j = 0; j < vcnt; j++)
+				if (memcmp(page_address(fbio->bi_io_vec[j].bv_page),
+					   page_address(tbio->bi_io_vec[j].bv_page),
+					   PAGE_SIZE))
+					break;
+			if (j == vcnt)
+				continue;
+			mddev->resync_mismatches += r10_bio->sectors;
+		}
+		if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
+			/* Don't fix anything. */
 			continue;
 		/* Ok, we need to write this bio
 		 * First we need to fixup bv_offset, bv_len and
@@ -1223,7 +1320,10 @@
 
 	atomic_inc(&conf->mirrors[d].rdev->nr_pending);
 	md_sync_acct(conf->mirrors[d].rdev->bdev, wbio->bi_size >> 9);
-	generic_make_request(wbio);
+	if (test_bit(R10BIO_Uptodate, &r10_bio->state))
+		generic_make_request(wbio);
+	else
+		bio_endio(wbio, wbio->bi_size, -EIO);
 }
 
 
@@ -1250,10 +1350,31 @@
 	for (;;) {
 		char b[BDEVNAME_SIZE];
 		spin_lock_irqsave(&conf->device_lock, flags);
+
+		if (conf->pending_bio_list.head) {
+			bio = bio_list_get(&conf->pending_bio_list);
+			blk_remove_plug(mddev->queue);
+			spin_unlock_irqrestore(&conf->device_lock, flags);
+			/* flush any pending bitmap writes to disk before proceeding w/ I/O */
+			if (bitmap_unplug(mddev->bitmap) != 0)
+				printk("%s: bitmap file write failed!\n", mdname(mddev));
+
+			while (bio) { /* submit pending writes */
+				struct bio *next = bio->bi_next;
+				bio->bi_next = NULL;
+				generic_make_request(bio);
+				bio = next;
+			}
+			unplug = 1;
+
+			continue;
+		}
+
 		if (list_empty(head))
 			break;
 		r10_bio = list_entry(head->prev, r10bio_t, retry_list);
 		list_del(head->prev);
+		conf->nr_queued--;
 		spin_unlock_irqrestore(&conf->device_lock, flags);
 
 		mddev = r10_bio->mddev;
@@ -1266,8 +1387,96 @@
 			unplug = 1;
 		} else {
 			int mirror;
+			/* we got a read error. Maybe the drive is bad.  Maybe just
+			 * the block and we can fix it.
+			 * We freeze all other IO, and try reading the block from
+			 * other devices.  When we find one, we re-write
+			 * and check it that fixes the read error.
+			 * This is all done synchronously while the array is
+			 * frozen.
+			 */
+			int sect = 0; /* Offset from r10_bio->sector */
+			int sectors = r10_bio->sectors;
+			freeze_array(conf);
+			if (mddev->ro == 0) while(sectors) {
+				int s = sectors;
+				int sl = r10_bio->read_slot;
+				int success = 0;
+
+				if (s > (PAGE_SIZE>>9))
+					s = PAGE_SIZE >> 9;
+
+				do {
+					int d = r10_bio->devs[sl].devnum;
+					rdev = conf->mirrors[d].rdev;
+					if (rdev &&
+					    test_bit(In_sync, &rdev->flags) &&
+					    sync_page_io(rdev->bdev,
+							 r10_bio->devs[sl].addr +
+							 sect + rdev->data_offset,
+							 s<<9,
+							 conf->tmppage, READ))
+						success = 1;
+					else {
+						sl++;
+						if (sl == conf->copies)
+							sl = 0;
+					}
+				} while (!success && sl != r10_bio->read_slot);
+
+				if (success) {
+					int start = sl;
+					/* write it back and re-read */
+					while (sl != r10_bio->read_slot) {
+						int d;
+						if (sl==0)
+							sl = conf->copies;
+						sl--;
+						d = r10_bio->devs[sl].devnum;
+						rdev = conf->mirrors[d].rdev;
+						atomic_add(s, &rdev->corrected_errors);
+						if (rdev &&
+						    test_bit(In_sync, &rdev->flags)) {
+							if (sync_page_io(rdev->bdev,
+									 r10_bio->devs[sl].addr +
+									 sect + rdev->data_offset,
+									 s<<9, conf->tmppage, WRITE) == 0)
+								/* Well, this device is dead */
+								md_error(mddev, rdev);
+						}
+					}
+					sl = start;
+					while (sl != r10_bio->read_slot) {
+						int d;
+						if (sl==0)
+							sl = conf->copies;
+						sl--;
+						d = r10_bio->devs[sl].devnum;
+						rdev = conf->mirrors[d].rdev;
+						if (rdev &&
+						    test_bit(In_sync, &rdev->flags)) {
+							if (sync_page_io(rdev->bdev,
+									 r10_bio->devs[sl].addr +
+									 sect + rdev->data_offset,
+									 s<<9, conf->tmppage, READ) == 0)
+								/* Well, this device is dead */
+								md_error(mddev, rdev);
+						}
+					}
+				} else {
+					/* Cannot read from anywhere -- bye bye array */
+					md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev);
+					break;
+				}
+				sectors -= s;
+				sect += s;
+			}
+
+			unfreeze_array(conf);
+
 			bio = r10_bio->devs[r10_bio->read_slot].bio;
-			r10_bio->devs[r10_bio->read_slot].bio = NULL;
+			r10_bio->devs[r10_bio->read_slot].bio =
+				mddev->ro ? IO_BLOCKED : NULL;
 			bio_put(bio);
 			mirror = read_balance(conf, r10_bio);
 			if (mirror == -1) {
@@ -1356,6 +1565,8 @@
 	sector_t max_sector, nr_sectors;
 	int disk;
 	int i;
+	int max_sync;
+	int sync_blocks;
 
 	sector_t sectors_skipped = 0;
 	int chunks_skipped = 0;
@@ -1369,6 +1580,29 @@
 	if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
 		max_sector = mddev->resync_max_sectors;
 	if (sector_nr >= max_sector) {
+		/* If we aborted, we need to abort the
+		 * sync on the 'current' bitmap chucks (there can
+		 * be several when recovering multiple devices).
+		 * as we may have started syncing it but not finished.
+		 * We can find the current address in
+		 * mddev->curr_resync, but for recovery,
+		 * we need to convert that to several
+		 * virtual addresses.
+		 */
+		if (mddev->curr_resync < max_sector) { /* aborted */
+			if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
+				bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
+						&sync_blocks, 1);
+			else for (i=0; i<conf->raid_disks; i++) {
+				sector_t sect =
+					raid10_find_virt(conf, mddev->curr_resync, i);
+				bitmap_end_sync(mddev->bitmap, sect,
+						&sync_blocks, 1);
+			}
+		} else /* completed sync */
+			conf->fullsync = 0;
+
+		bitmap_close_sync(mddev->bitmap);
 		close_sync(conf);
 		*skipped = 1;
 		return sectors_skipped;
@@ -1391,9 +1625,8 @@
 	 * If there is non-resync activity waiting for us then
 	 * put in a delay to throttle resync.
 	 */
-	if (!go_faster && waitqueue_active(&conf->wait_resume))
+	if (!go_faster && conf->nr_waiting)
 		msleep_interruptible(1000);
-	device_barrier(conf, sector_nr + RESYNC_SECTORS);
 
 	/* Again, very different code for resync and recovery.
 	 * Both must result in an r10bio with a list of bios that
@@ -1410,6 +1643,7 @@
 	 * end_sync_write if we will want to write.
 	 */
 
+	max_sync = RESYNC_PAGES << (PAGE_SHIFT-9);
 	if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
 		/* recovery... the complicated one */
 		int i, j, k;
@@ -1418,14 +1652,29 @@
 		for (i=0 ; i<conf->raid_disks; i++)
 			if (conf->mirrors[i].rdev &&
 			    !test_bit(In_sync, &conf->mirrors[i].rdev->flags)) {
+				int still_degraded = 0;
 				/* want to reconstruct this device */
 				r10bio_t *rb2 = r10_bio;
+				sector_t sect = raid10_find_virt(conf, sector_nr, i);
+				int must_sync;
+				/* Unless we are doing a full sync, we only need
+				 * to recover the block if it is set in the bitmap
+				 */
+				must_sync = bitmap_start_sync(mddev->bitmap, sect,
+							      &sync_blocks, 1);
+				if (sync_blocks < max_sync)
+					max_sync = sync_blocks;
+				if (!must_sync &&
+				    !conf->fullsync) {
+					/* yep, skip the sync_blocks here, but don't assume
+					 * that there will never be anything to do here
+					 */
+					chunks_skipped = -1;
+					continue;
+				}
 
 				r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
-				spin_lock_irq(&conf->resync_lock);
-				conf->nr_pending++;
-				if (rb2) conf->barrier++;
-				spin_unlock_irq(&conf->resync_lock);
+				raise_barrier(conf, rb2 != NULL);
 				atomic_set(&r10_bio->remaining, 0);
 
 				r10_bio->master_bio = (struct bio*)rb2;
@@ -1433,8 +1682,23 @@
 					atomic_inc(&rb2->remaining);
 				r10_bio->mddev = mddev;
 				set_bit(R10BIO_IsRecover, &r10_bio->state);
-				r10_bio->sector = raid10_find_virt(conf, sector_nr, i);
+				r10_bio->sector = sect;
+
 				raid10_find_phys(conf, r10_bio);
+				/* Need to check if this section will still be
+				 * degraded
+				 */
+				for (j=0; j<conf->copies;j++) {
+					int d = r10_bio->devs[j].devnum;
+					if (conf->mirrors[d].rdev == NULL ||
+					    test_bit(Faulty, &conf->mirrors[d].rdev->flags)) {
+						still_degraded = 1;
+						break;
+					}
+				}
+				must_sync = bitmap_start_sync(mddev->bitmap, sect,
+							      &sync_blocks, still_degraded);
+
 				for (j=0; j<conf->copies;j++) {
 					int d = r10_bio->devs[j].devnum;
 					if (conf->mirrors[d].rdev &&
@@ -1494,14 +1758,22 @@
 	} else {
 		/* resync. Schedule a read for every block at this virt offset */
 		int count = 0;
-		r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
 
-		spin_lock_irq(&conf->resync_lock);
-		conf->nr_pending++;
-		spin_unlock_irq(&conf->resync_lock);
+		if (!bitmap_start_sync(mddev->bitmap, sector_nr,
+				       &sync_blocks, mddev->degraded) &&
+		    !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
+			/* We can skip this block */
+			*skipped = 1;
+			return sync_blocks + sectors_skipped;
+		}
+		if (sync_blocks < max_sync)
+			max_sync = sync_blocks;
+		r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
 
 		r10_bio->mddev = mddev;
 		atomic_set(&r10_bio->remaining, 0);
+		raise_barrier(conf, 0);
+		conf->next_resync = sector_nr;
 
 		r10_bio->master_bio = NULL;
 		r10_bio->sector = sector_nr;
@@ -1554,6 +1826,8 @@
 	}
 
 	nr_sectors = 0;
+	if (sector_nr + max_sync < max_sector)
+		max_sector = sector_nr + max_sync;
 	do {
 		struct page *page;
 		int len = PAGE_SIZE;
@@ -1628,11 +1902,11 @@
 	int nc, fc;
 	sector_t stride, size;
 
-	if (mddev->level != 10) {
-		printk(KERN_ERR "raid10: %s: raid level not set correctly... (%d)\n",
-		       mdname(mddev), mddev->level);
-		goto out;
+	if (mddev->chunk_size == 0) {
+		printk(KERN_ERR "md/raid10: non-zero chunk size required.\n");
+		return -EINVAL;
 	}
+
 	nc = mddev->layout & 255;
 	fc = (mddev->layout >> 8) & 255;
 	if ((nc*fc) <2 || (nc*fc) > mddev->raid_disks ||
@@ -1646,22 +1920,24 @@
 	 * bookkeeping area. [whatever we allocate in run(),
 	 * should be freed in stop()]
 	 */
-	conf = kmalloc(sizeof(conf_t), GFP_KERNEL);
+	conf = kzalloc(sizeof(conf_t), GFP_KERNEL);
 	mddev->private = conf;
 	if (!conf) {
 		printk(KERN_ERR "raid10: couldn't allocate memory for %s\n",
 			mdname(mddev));
 		goto out;
 	}
-	memset(conf, 0, sizeof(*conf));
-	conf->mirrors = kmalloc(sizeof(struct mirror_info)*mddev->raid_disks,
+	conf->mirrors = kzalloc(sizeof(struct mirror_info)*mddev->raid_disks,
 				 GFP_KERNEL);
 	if (!conf->mirrors) {
 		printk(KERN_ERR "raid10: couldn't allocate memory for %s\n",
 		       mdname(mddev));
 		goto out_free_conf;
 	}
-	memset(conf->mirrors, 0, sizeof(struct mirror_info)*mddev->raid_disks);
+
+	conf->tmppage = alloc_page(GFP_KERNEL);
+	if (!conf->tmppage)
+		goto out_free_conf;
 
 	conf->near_copies = nc;
 	conf->far_copies = fc;
@@ -1709,8 +1985,7 @@
 	INIT_LIST_HEAD(&conf->retry_list);
 
 	spin_lock_init(&conf->resync_lock);
-	init_waitqueue_head(&conf->wait_idle);
-	init_waitqueue_head(&conf->wait_resume);
+	init_waitqueue_head(&conf->wait_barrier);
 
 	/* need to check that every block has at least one working mirror */
 	if (!enough(conf)) {
@@ -1759,7 +2034,7 @@
 	 * maybe...
 	 */
 	{
-		int stripe = conf->raid_disks * mddev->chunk_size / PAGE_CACHE_SIZE;
+		int stripe = conf->raid_disks * mddev->chunk_size / PAGE_SIZE;
 		stripe /= conf->near_copies;
 		if (mddev->queue->backing_dev_info.ra_pages < 2* stripe)
 			mddev->queue->backing_dev_info.ra_pages = 2* stripe;
@@ -1772,6 +2047,7 @@
 out_free_conf:
 	if (conf->r10bio_pool)
 		mempool_destroy(conf->r10bio_pool);
+	safe_put_page(conf->tmppage);
 	kfree(conf->mirrors);
 	kfree(conf);
 	mddev->private = NULL;
@@ -1794,10 +2070,31 @@
 	return 0;
 }
 
+static void raid10_quiesce(mddev_t *mddev, int state)
+{
+	conf_t *conf = mddev_to_conf(mddev);
 
-static mdk_personality_t raid10_personality =
+	switch(state) {
+	case 1:
+		raise_barrier(conf, 0);
+		break;
+	case 0:
+		lower_barrier(conf);
+		break;
+	}
+	if (mddev->thread) {
+		if (mddev->bitmap)
+			mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
+		else
+			mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
+		md_wakeup_thread(mddev->thread);
+	}
+}
+
+static struct mdk_personality raid10_personality =
 {
 	.name		= "raid10",
+	.level		= 10,
 	.owner		= THIS_MODULE,
 	.make_request	= make_request,
 	.run		= run,
@@ -1808,19 +2105,22 @@
 	.hot_remove_disk= raid10_remove_disk,
 	.spare_active	= raid10_spare_active,
 	.sync_request	= sync_request,
+	.quiesce	= raid10_quiesce,
 };
 
 static int __init raid_init(void)
 {
-	return register_md_personality(RAID10, &raid10_personality);
+	return register_md_personality(&raid10_personality);
 }
 
 static void raid_exit(void)
 {
-	unregister_md_personality(RAID10);
+	unregister_md_personality(&raid10_personality);
 }
 
 module_init(raid_init);
 module_exit(raid_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("md-personality-9"); /* RAID10 */
+MODULE_ALIAS("md-raid10");
+MODULE_ALIAS("md-level-10");
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index e2a4028..54f4a98 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -35,12 +35,10 @@
 #define STRIPE_SHIFT		(PAGE_SHIFT - 9)
 #define STRIPE_SECTORS		(STRIPE_SIZE>>9)
 #define	IO_THRESHOLD		1
-#define HASH_PAGES		1
-#define HASH_PAGES_ORDER	0
-#define NR_HASH			(HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *))
+#define NR_HASH			(PAGE_SIZE / sizeof(struct hlist_head))
 #define HASH_MASK		(NR_HASH - 1)
 
-#define stripe_hash(conf, sect)	((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK])
+#define stripe_hash(conf, sect)	(&((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK]))
 
 /* bio's attached to a stripe+device for I/O are linked together in bi_sector
  * order without overlap.  There may be several bio's per stripe+device, and
@@ -98,7 +96,7 @@
 			list_add_tail(&sh->lru, &conf->inactive_list);
 			atomic_dec(&conf->active_stripes);
 			if (!conf->inactive_blocked ||
-			    atomic_read(&conf->active_stripes) < (NR_STRIPES*3/4))
+			    atomic_read(&conf->active_stripes) < (conf->max_nr_stripes*3/4))
 				wake_up(&conf->wait_for_stripe);
 		}
 	}
@@ -113,29 +111,21 @@
 	spin_unlock_irqrestore(&conf->device_lock, flags);
 }
 
-static void remove_hash(struct stripe_head *sh)
+static inline void remove_hash(struct stripe_head *sh)
 {
 	PRINTK("remove_hash(), stripe %llu\n", (unsigned long long)sh->sector);
 
-	if (sh->hash_pprev) {
-		if (sh->hash_next)
-			sh->hash_next->hash_pprev = sh->hash_pprev;
-		*sh->hash_pprev = sh->hash_next;
-		sh->hash_pprev = NULL;
-	}
+	hlist_del_init(&sh->hash);
 }
 
-static __inline__ void insert_hash(raid5_conf_t *conf, struct stripe_head *sh)
+static inline void insert_hash(raid5_conf_t *conf, struct stripe_head *sh)
 {
-	struct stripe_head **shp = &stripe_hash(conf, sh->sector);
+	struct hlist_head *hp = stripe_hash(conf, sh->sector);
 
 	PRINTK("insert_hash(), stripe %llu\n", (unsigned long long)sh->sector);
 
 	CHECK_DEVLOCK();
-	if ((sh->hash_next = *shp) != NULL)
-		(*shp)->hash_pprev = &sh->hash_next;
-	*shp = sh;
-	sh->hash_pprev = shp;
+	hlist_add_head(&sh->hash, hp);
 }
 
 
@@ -167,7 +157,7 @@
 		if (!p)
 			continue;
 		sh->dev[i].page = NULL;
-		page_cache_release(p);
+		put_page(p);
 	}
 }
 
@@ -228,10 +218,11 @@
 static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector)
 {
 	struct stripe_head *sh;
+	struct hlist_node *hn;
 
 	CHECK_DEVLOCK();
 	PRINTK("__find_stripe, sector %llu\n", (unsigned long long)sector);
-	for (sh = stripe_hash(conf, sector); sh; sh = sh->hash_next)
+	hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash)
 		if (sh->sector == sector)
 			return sh;
 	PRINTK("__stripe %llu not in cache\n", (unsigned long long)sector);
@@ -264,7 +255,8 @@
 				conf->inactive_blocked = 1;
 				wait_event_lock_irq(conf->wait_for_stripe,
 						    !list_empty(&conf->inactive_list) &&
-						    (atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4)
+						    (atomic_read(&conf->active_stripes)
+						     < (conf->max_nr_stripes *3/4)
 						     || !conf->inactive_blocked),
 						    conf->device_lock,
 						    unplug_slaves(conf->mddev);
@@ -416,7 +408,7 @@
 		set_bit(R5_UPTODATE, &sh->dev[i].flags);
 #endif
 		if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
-			printk("R5: read error corrected!!\n");
+			printk(KERN_INFO "raid5: read error corrected!!\n");
 			clear_bit(R5_ReadError, &sh->dev[i].flags);
 			clear_bit(R5_ReWrite, &sh->dev[i].flags);
 		}
@@ -427,13 +419,14 @@
 		clear_bit(R5_UPTODATE, &sh->dev[i].flags);
 		atomic_inc(&conf->disks[i].rdev->read_errors);
 		if (conf->mddev->degraded)
-			printk("R5: read error not correctable.\n");
+			printk(KERN_WARNING "raid5: read error not correctable.\n");
 		else if (test_bit(R5_ReWrite, &sh->dev[i].flags))
 			/* Oh, no!!! */
-			printk("R5: read error NOT corrected!!\n");
+			printk(KERN_WARNING "raid5: read error NOT corrected!!\n");
 		else if (atomic_read(&conf->disks[i].rdev->read_errors)
 			 > conf->max_nr_stripes)
-			printk("raid5: Too many read errors, failing device.\n");
+			printk(KERN_WARNING
+			       "raid5: Too many read errors, failing device.\n");
 		else
 			retry = 1;
 		if (retry)
@@ -603,7 +596,7 @@
 			*dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
 			break;
 		default:
-			printk("raid5: unsupported algorithm %d\n",
+			printk(KERN_ERR "raid5: unsupported algorithm %d\n",
 				conf->algorithm);
 	}
 
@@ -644,7 +637,7 @@
 			i -= (sh->pd_idx + 1);
 			break;
 		default:
-			printk("raid5: unsupported algorithm %d\n",
+			printk(KERN_ERR "raid5: unsupported algorithm %d\n",
 				conf->algorithm);
 	}
 
@@ -653,7 +646,7 @@
 
 	check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
 	if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
-		printk("compute_blocknr: map not correct\n");
+		printk(KERN_ERR "compute_blocknr: map not correct\n");
 		return 0;
 	}
 	return r_sector;
@@ -736,7 +729,7 @@
 		if (test_bit(R5_UPTODATE, &sh->dev[i].flags))
 			ptr[count++] = p;
 		else
-			printk("compute_block() %d, stripe %llu, %d"
+			printk(KERN_ERR "compute_block() %d, stripe %llu, %d"
 				" not present\n", dd_idx,
 				(unsigned long long)sh->sector, i);
 
@@ -959,11 +952,11 @@
 	syncing = test_bit(STRIPE_SYNCING, &sh->state);
 	/* Now to look around and see what can be done */
 
+	rcu_read_lock();
 	for (i=disks; i--; ) {
 		mdk_rdev_t *rdev;
 		dev = &sh->dev[i];
 		clear_bit(R5_Insync, &dev->flags);
-		clear_bit(R5_Syncio, &dev->flags);
 
 		PRINTK("check %d: state 0x%lx read %p write %p written %p\n",
 			i, dev->flags, dev->toread, dev->towrite, dev->written);
@@ -1002,9 +995,9 @@
 				non_overwrite++;
 		}
 		if (dev->written) written++;
-		rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
+		rdev = rcu_dereference(conf->disks[i].rdev);
 		if (!rdev || !test_bit(In_sync, &rdev->flags)) {
-			/* The ReadError flag wil just be confusing now */
+			/* The ReadError flag will just be confusing now */
 			clear_bit(R5_ReadError, &dev->flags);
 			clear_bit(R5_ReWrite, &dev->flags);
 		}
@@ -1015,6 +1008,7 @@
 		} else
 			set_bit(R5_Insync, &dev->flags);
 	}
+	rcu_read_unlock();
 	PRINTK("locked=%d uptodate=%d to_read=%d"
 		" to_write=%d failed=%d failed_num=%d\n",
 		locked, uptodate, to_read, to_write, failed, failed_num);
@@ -1026,10 +1020,13 @@
 			int bitmap_end = 0;
 
 			if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
-				mdk_rdev_t *rdev = conf->disks[i].rdev;
+				mdk_rdev_t *rdev;
+				rcu_read_lock();
+				rdev = rcu_dereference(conf->disks[i].rdev);
 				if (rdev && test_bit(In_sync, &rdev->flags))
 					/* multiple read failures in one stripe */
 					md_error(conf->mddev, rdev);
+				rcu_read_unlock();
 			}
 
 			spin_lock_irq(&conf->device_lock);
@@ -1178,9 +1175,6 @@
 					locked++;
 					PRINTK("Reading block %d (sync=%d)\n", 
 						i, syncing);
-					if (syncing)
-						md_sync_acct(conf->disks[i].rdev->bdev,
-							     STRIPE_SECTORS);
 				}
 			}
 		}
@@ -1287,7 +1281,7 @@
 	 * is available
 	 */
 	if (syncing && locked == 0 &&
-	    !test_bit(STRIPE_INSYNC, &sh->state) && failed <= 1) {
+	    !test_bit(STRIPE_INSYNC, &sh->state)) {
 		set_bit(STRIPE_HANDLE, &sh->state);
 		if (failed == 0) {
 			char *pagea;
@@ -1305,27 +1299,25 @@
 				if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
 					/* don't try to repair!! */
 					set_bit(STRIPE_INSYNC, &sh->state);
+				else {
+					compute_block(sh, sh->pd_idx);
+					uptodate++;
+				}
 			}
 		}
 		if (!test_bit(STRIPE_INSYNC, &sh->state)) {
+			/* either failed parity check, or recovery is happening */
 			if (failed==0)
 				failed_num = sh->pd_idx;
-			/* should be able to compute the missing block and write it to spare */
-			if (!test_bit(R5_UPTODATE, &sh->dev[failed_num].flags)) {
-				if (uptodate+1 != disks)
-					BUG();
-				compute_block(sh, failed_num);
-				uptodate++;
-			}
-			if (uptodate != disks)
-				BUG();
 			dev = &sh->dev[failed_num];
+			BUG_ON(!test_bit(R5_UPTODATE, &dev->flags));
+			BUG_ON(uptodate != disks);
+
 			set_bit(R5_LOCKED, &dev->flags);
 			set_bit(R5_Wantwrite, &dev->flags);
 			clear_bit(STRIPE_DEGRADED, &sh->state);
 			locked++;
 			set_bit(STRIPE_INSYNC, &sh->state);
-			set_bit(R5_Syncio, &dev->flags);
 		}
 	}
 	if (syncing && locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) {
@@ -1391,7 +1383,7 @@
 		rcu_read_unlock();
  
 		if (rdev) {
-			if (test_bit(R5_Syncio, &sh->dev[i].flags))
+			if (syncing)
 				md_sync_acct(rdev->bdev, STRIPE_SECTORS);
 
 			bi->bi_bdev = rdev->bdev;
@@ -1408,6 +1400,9 @@
 			bi->bi_io_vec[0].bv_offset = 0;
 			bi->bi_size = STRIPE_SIZE;
 			bi->bi_next = NULL;
+			if (rw == WRITE &&
+			    test_bit(R5_ReWrite, &sh->dev[i].flags))
+				atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
 			generic_make_request(bi);
 		} else {
 			if (rw == 1)
@@ -1704,7 +1699,9 @@
 
 		if (conf->seq_flush - conf->seq_write > 0) {
 			int seq = conf->seq_flush;
+			spin_unlock_irq(&conf->device_lock);
 			bitmap_unplug(mddev->bitmap);
+			spin_lock_irq(&conf->device_lock);
 			conf->seq_write = seq;
 			activate_bit_delay(conf);
 		}
@@ -1819,21 +1816,21 @@
 	struct list_head *tmp;
 
 	if (mddev->level != 5 && mddev->level != 4) {
-		printk("raid5: %s: raid level not set to 4/5 (%d)\n", mdname(mddev), mddev->level);
+		printk(KERN_ERR "raid5: %s: raid level not set to 4/5 (%d)\n",
+		       mdname(mddev), mddev->level);
 		return -EIO;
 	}
 
-	mddev->private = kmalloc (sizeof (raid5_conf_t)
-				  + mddev->raid_disks * sizeof(struct disk_info),
-				  GFP_KERNEL);
+	mddev->private = kzalloc(sizeof (raid5_conf_t)
+				 + mddev->raid_disks * sizeof(struct disk_info),
+				 GFP_KERNEL);
 	if ((conf = mddev->private) == NULL)
 		goto abort;
-	memset (conf, 0, sizeof (*conf) + mddev->raid_disks * sizeof(struct disk_info) );
+
 	conf->mddev = mddev;
 
-	if ((conf->stripe_hashtbl = (struct stripe_head **) __get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER)) == NULL)
+	if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)
 		goto abort;
-	memset(conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE);
 
 	spin_lock_init(&conf->device_lock);
 	init_waitqueue_head(&conf->wait_for_stripe);
@@ -1900,10 +1897,17 @@
 
 	if (mddev->degraded == 1 &&
 	    mddev->recovery_cp != MaxSector) {
-		printk(KERN_ERR 
-			"raid5: cannot start dirty degraded array for %s\n",
-			mdname(mddev));
-		goto abort;
+		if (mddev->ok_start_degraded)
+			printk(KERN_WARNING
+			       "raid5: starting dirty degraded array: %s"
+			       "- data corruption possible.\n",
+			       mdname(mddev));
+		else {
+			printk(KERN_ERR
+			       "raid5: cannot start dirty degraded array for %s\n",
+			       mdname(mddev));
+			goto abort;
+		}
 	}
 
 	{
@@ -1915,7 +1919,7 @@
 			goto abort;
 		}
 	}
-memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
+	memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
 		 conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
 	if (grow_stripes(conf, conf->max_nr_stripes)) {
 		printk(KERN_ERR 
@@ -1945,7 +1949,7 @@
 	 */
 	{
 		int stripe = (mddev->raid_disks-1) * mddev->chunk_size
-			/ PAGE_CACHE_SIZE;
+			/ PAGE_SIZE;
 		if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe)
 			mddev->queue->backing_dev_info.ra_pages = 2 * stripe;
 	}
@@ -1953,9 +1957,6 @@
 	/* Ok, everything is just fine now */
 	sysfs_create_group(&mddev->kobj, &raid5_attrs_group);
 
-	if (mddev->bitmap)
-		mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
-
 	mddev->queue->unplug_fn = raid5_unplug_device;
 	mddev->queue->issue_flush_fn = raid5_issue_flush;
 
@@ -1964,9 +1965,7 @@
 abort:
 	if (conf) {
 		print_raid5_conf(conf);
-		if (conf->stripe_hashtbl)
-			free_pages((unsigned long) conf->stripe_hashtbl,
-							HASH_PAGES_ORDER);
+		kfree(conf->stripe_hashtbl);
 		kfree(conf);
 	}
 	mddev->private = NULL;
@@ -1983,7 +1982,7 @@
 	md_unregister_thread(mddev->thread);
 	mddev->thread = NULL;
 	shrink_stripes(conf);
-	free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
+	kfree(conf->stripe_hashtbl);
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
 	sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
 	kfree(conf);
@@ -2011,12 +2010,12 @@
 static void printall (raid5_conf_t *conf)
 {
 	struct stripe_head *sh;
+	struct hlist_node *hn;
 	int i;
 
 	spin_lock_irq(&conf->device_lock);
 	for (i = 0; i < NR_HASH; i++) {
-		sh = conf->stripe_hashtbl[i];
-		for (; sh; sh = sh->hash_next) {
+		hlist_for_each_entry(sh, hn, &conf->stripe_hashtbl[i], hash) {
 			if (sh->raid_conf != conf)
 				continue;
 			print_sh(sh);
@@ -2189,17 +2188,12 @@
 		spin_unlock_irq(&conf->device_lock);
 		break;
 	}
-	if (mddev->thread) {
-		if (mddev->bitmap)
-			mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
-		else
-			mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
-		md_wakeup_thread(mddev->thread);
-	}
 }
-static mdk_personality_t raid5_personality=
+
+static struct mdk_personality raid5_personality =
 {
 	.name		= "raid5",
+	.level		= 5,
 	.owner		= THIS_MODULE,
 	.make_request	= make_request,
 	.run		= run,
@@ -2214,17 +2208,42 @@
 	.quiesce	= raid5_quiesce,
 };
 
-static int __init raid5_init (void)
+static struct mdk_personality raid4_personality =
 {
-	return register_md_personality (RAID5, &raid5_personality);
+	.name		= "raid4",
+	.level		= 4,
+	.owner		= THIS_MODULE,
+	.make_request	= make_request,
+	.run		= run,
+	.stop		= stop,
+	.status		= status,
+	.error_handler	= error,
+	.hot_add_disk	= raid5_add_disk,
+	.hot_remove_disk= raid5_remove_disk,
+	.spare_active	= raid5_spare_active,
+	.sync_request	= sync_request,
+	.resize		= raid5_resize,
+	.quiesce	= raid5_quiesce,
+};
+
+static int __init raid5_init(void)
+{
+	register_md_personality(&raid5_personality);
+	register_md_personality(&raid4_personality);
+	return 0;
 }
 
-static void raid5_exit (void)
+static void raid5_exit(void)
 {
-	unregister_md_personality (RAID5);
+	unregister_md_personality(&raid5_personality);
+	unregister_md_personality(&raid4_personality);
 }
 
 module_init(raid5_init);
 module_exit(raid5_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("md-personality-4"); /* RAID5 */
+MODULE_ALIAS("md-raid5");
+MODULE_ALIAS("md-raid4");
+MODULE_ALIAS("md-level-5");
+MODULE_ALIAS("md-level-4");
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index eae5a35..8c823d6 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -40,12 +40,10 @@
 #define STRIPE_SHIFT		(PAGE_SHIFT - 9)
 #define STRIPE_SECTORS		(STRIPE_SIZE>>9)
 #define	IO_THRESHOLD		1
-#define HASH_PAGES		1
-#define HASH_PAGES_ORDER	0
-#define NR_HASH			(HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *))
+#define NR_HASH			(PAGE_SIZE / sizeof(struct hlist_head))
 #define HASH_MASK		(NR_HASH - 1)
 
-#define stripe_hash(conf, sect)	((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK])
+#define stripe_hash(conf, sect)	(&((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK]))
 
 /* bio's attached to a stripe+device for I/O are linked together in bi_sector
  * order without overlap.  There may be several bio's per stripe+device, and
@@ -132,29 +130,21 @@
 	spin_unlock_irqrestore(&conf->device_lock, flags);
 }
 
-static void remove_hash(struct stripe_head *sh)
+static inline void remove_hash(struct stripe_head *sh)
 {
 	PRINTK("remove_hash(), stripe %llu\n", (unsigned long long)sh->sector);
 
-	if (sh->hash_pprev) {
-		if (sh->hash_next)
-			sh->hash_next->hash_pprev = sh->hash_pprev;
-		*sh->hash_pprev = sh->hash_next;
-		sh->hash_pprev = NULL;
-	}
+	hlist_del_init(&sh->hash);
 }
 
-static __inline__ void insert_hash(raid6_conf_t *conf, struct stripe_head *sh)
+static inline void insert_hash(raid6_conf_t *conf, struct stripe_head *sh)
 {
-	struct stripe_head **shp = &stripe_hash(conf, sh->sector);
+	struct hlist_head *hp = stripe_hash(conf, sh->sector);
 
 	PRINTK("insert_hash(), stripe %llu\n", (unsigned long long)sh->sector);
 
 	CHECK_DEVLOCK();
-	if ((sh->hash_next = *shp) != NULL)
-		(*shp)->hash_pprev = &sh->hash_next;
-	*shp = sh;
-	sh->hash_pprev = shp;
+	hlist_add_head(&sh->hash, hp);
 }
 
 
@@ -186,7 +176,7 @@
 		if (!p)
 			continue;
 		sh->dev[i].page = NULL;
-		page_cache_release(p);
+		put_page(p);
 	}
 }
 
@@ -247,10 +237,11 @@
 static struct stripe_head *__find_stripe(raid6_conf_t *conf, sector_t sector)
 {
 	struct stripe_head *sh;
+	struct hlist_node *hn;
 
 	CHECK_DEVLOCK();
 	PRINTK("__find_stripe, sector %llu\n", (unsigned long long)sector);
-	for (sh = stripe_hash(conf, sector); sh; sh = sh->hash_next)
+	hlist_for_each_entry (sh, hn,  stripe_hash(conf, sector), hash)
 		if (sh->sector == sector)
 			return sh;
 	PRINTK("__stripe %llu not in cache\n", (unsigned long long)sector);
@@ -367,8 +358,8 @@
 	conf->slab_cache = NULL;
 }
 
-static int raid6_end_read_request (struct bio * bi, unsigned int bytes_done,
-				   int error)
+static int raid6_end_read_request(struct bio * bi, unsigned int bytes_done,
+				  int error)
 {
  	struct stripe_head *sh = bi->bi_private;
 	raid6_conf_t *conf = sh->raid_conf;
@@ -420,9 +411,35 @@
 #else
 		set_bit(R5_UPTODATE, &sh->dev[i].flags);
 #endif
+		if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
+			printk(KERN_INFO "raid6: read error corrected!!\n");
+			clear_bit(R5_ReadError, &sh->dev[i].flags);
+			clear_bit(R5_ReWrite, &sh->dev[i].flags);
+		}
+		if (atomic_read(&conf->disks[i].rdev->read_errors))
+			atomic_set(&conf->disks[i].rdev->read_errors, 0);
 	} else {
-		md_error(conf->mddev, conf->disks[i].rdev);
+		int retry = 0;
 		clear_bit(R5_UPTODATE, &sh->dev[i].flags);
+		atomic_inc(&conf->disks[i].rdev->read_errors);
+		if (conf->mddev->degraded)
+			printk(KERN_WARNING "raid6: read error not correctable.\n");
+		else if (test_bit(R5_ReWrite, &sh->dev[i].flags))
+			/* Oh, no!!! */
+			printk(KERN_WARNING "raid6: read error NOT corrected!!\n");
+		else if (atomic_read(&conf->disks[i].rdev->read_errors)
+			 > conf->max_nr_stripes)
+			printk(KERN_WARNING
+			       "raid6: Too many read errors, failing device.\n");
+		else
+			retry = 1;
+		if (retry)
+			set_bit(R5_ReadError, &sh->dev[i].flags);
+		else {
+			clear_bit(R5_ReadError, &sh->dev[i].flags);
+			clear_bit(R5_ReWrite, &sh->dev[i].flags);
+			md_error(conf->mddev, conf->disks[i].rdev);
+		}
 	}
 	rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
 #if 0
@@ -805,7 +822,7 @@
 }
 
 /* Compute one missing block */
-static void compute_block_1(struct stripe_head *sh, int dd_idx)
+static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
 {
 	raid6_conf_t *conf = sh->raid_conf;
 	int i, count, disks = conf->raid_disks;
@@ -821,7 +838,7 @@
 		compute_parity(sh, UPDATE_PARITY);
 	} else {
 		ptr[0] = page_address(sh->dev[dd_idx].page);
-		memset(ptr[0], 0, STRIPE_SIZE);
+		if (!nozero) memset(ptr[0], 0, STRIPE_SIZE);
 		count = 1;
 		for (i = disks ; i--; ) {
 			if (i == dd_idx || i == qd_idx)
@@ -838,7 +855,8 @@
 		}
 		if (count != 1)
 			xor_block(count, STRIPE_SIZE, ptr);
-		set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags);
+		if (!nozero) set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags);
+		else clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags);
 	}
 }
 
@@ -871,7 +889,7 @@
 			return;
 		} else {
 			/* We're missing D+Q; recompute D from P */
-			compute_block_1(sh, (dd_idx1 == qd_idx) ? dd_idx2 : dd_idx1);
+			compute_block_1(sh, (dd_idx1 == qd_idx) ? dd_idx2 : dd_idx1, 0);
 			compute_parity(sh, UPDATE_PARITY); /* Is this necessary? */
 			return;
 		}
@@ -982,6 +1000,12 @@
 }
 
 
+static int page_is_zero(struct page *p)
+{
+	char *a = page_address(p);
+	return ((*(u32*)a) == 0 &&
+		memcmp(a, a+4, STRIPE_SIZE-4)==0);
+}
 /*
  * handle_stripe - do things to a stripe.
  *
@@ -1000,7 +1024,7 @@
  *
  */
 
-static void handle_stripe(struct stripe_head *sh)
+static void handle_stripe(struct stripe_head *sh, struct page *tmp_page)
 {
 	raid6_conf_t *conf = sh->raid_conf;
 	int disks = conf->raid_disks;
@@ -1027,11 +1051,11 @@
 	syncing = test_bit(STRIPE_SYNCING, &sh->state);
 	/* Now to look around and see what can be done */
 
+	rcu_read_lock();
 	for (i=disks; i--; ) {
 		mdk_rdev_t *rdev;
 		dev = &sh->dev[i];
 		clear_bit(R5_Insync, &dev->flags);
-		clear_bit(R5_Syncio, &dev->flags);
 
 		PRINTK("check %d: state 0x%lx read %p write %p written %p\n",
 			i, dev->flags, dev->toread, dev->towrite, dev->written);
@@ -1070,14 +1094,21 @@
 				non_overwrite++;
 		}
 		if (dev->written) written++;
-		rdev = conf->disks[i].rdev; /* FIXME, should I be looking rdev */
+		rdev = rcu_dereference(conf->disks[i].rdev);
 		if (!rdev || !test_bit(In_sync, &rdev->flags)) {
+			/* The ReadError flag will just be confusing now */
+			clear_bit(R5_ReadError, &dev->flags);
+			clear_bit(R5_ReWrite, &dev->flags);
+		}
+		if (!rdev || !test_bit(In_sync, &rdev->flags)
+		    || test_bit(R5_ReadError, &dev->flags)) {
 			if ( failed < 2 )
 				failed_num[failed] = i;
 			failed++;
 		} else
 			set_bit(R5_Insync, &dev->flags);
 	}
+	rcu_read_unlock();
 	PRINTK("locked=%d uptodate=%d to_read=%d"
 	       " to_write=%d failed=%d failed_num=%d,%d\n",
 	       locked, uptodate, to_read, to_write, failed,
@@ -1088,6 +1119,17 @@
 	if (failed > 2 && to_read+to_write+written) {
 		for (i=disks; i--; ) {
 			int bitmap_end = 0;
+
+			if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
+				mdk_rdev_t *rdev;
+				rcu_read_lock();
+				rdev = rcu_dereference(conf->disks[i].rdev);
+				if (rdev && test_bit(In_sync, &rdev->flags))
+					/* multiple read failures in one stripe */
+					md_error(conf->mddev, rdev);
+				rcu_read_unlock();
+			}
+
 			spin_lock_irq(&conf->device_lock);
 			/* fail all writes first */
 			bi = sh->dev[i].towrite;
@@ -1123,7 +1165,8 @@
 			}
 
 			/* fail any reads if this device is non-operational */
-			if (!test_bit(R5_Insync, &sh->dev[i].flags)) {
+			if (!test_bit(R5_Insync, &sh->dev[i].flags) ||
+			    test_bit(R5_ReadError, &sh->dev[i].flags)) {
 				bi = sh->dev[i].toread;
 				sh->dev[i].toread = NULL;
 				if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
@@ -1228,7 +1271,7 @@
 				if (uptodate == disks-1) {
 					PRINTK("Computing stripe %llu block %d\n",
 					       (unsigned long long)sh->sector, i);
-					compute_block_1(sh, i);
+					compute_block_1(sh, i, 0);
 					uptodate++;
 				} else if ( uptodate == disks-2 && failed >= 2 ) {
 					/* Computing 2-failure is *very* expensive; only do it if failed >= 2 */
@@ -1259,9 +1302,6 @@
 					locked++;
 					PRINTK("Reading block %d (sync=%d)\n",
 						i, syncing);
-					if (syncing)
-						md_sync_acct(conf->disks[i].rdev->bdev,
-							     STRIPE_SECTORS);
 				}
 			}
 		}
@@ -1323,7 +1363,7 @@
 				/* We have failed blocks and need to compute them */
 				switch ( failed ) {
 				case 0:	BUG();
-				case 1: compute_block_1(sh, failed_num[0]); break;
+				case 1: compute_block_1(sh, failed_num[0], 0); break;
 				case 2: compute_block_2(sh, failed_num[0], failed_num[1]); break;
 				default: BUG();	/* This request should have been failed? */
 				}
@@ -1338,12 +1378,10 @@
 					       (unsigned long long)sh->sector, i);
 					locked++;
 					set_bit(R5_Wantwrite, &sh->dev[i].flags);
-#if 0 /**** FIX: I don't understand the logic here... ****/
-					if (!test_bit(R5_Insync, &sh->dev[i].flags)
-					    || ((i==pd_idx || i==qd_idx) && failed == 0)) /* FIX? */
-						set_bit(STRIPE_INSYNC, &sh->state);
-#endif
 				}
+			/* after a RECONSTRUCT_WRITE, the stripe MUST be in-sync */
+			set_bit(STRIPE_INSYNC, &sh->state);
+
 			if (test_and_clear_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) {
 				atomic_dec(&conf->preread_active_stripes);
 				if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD)
@@ -1356,84 +1394,119 @@
 	 * Any reads will already have been scheduled, so we just see if enough data
 	 * is available
 	 */
-	if (syncing && locked == 0 &&
-	    !test_bit(STRIPE_INSYNC, &sh->state) && failed <= 2) {
+	if (syncing && locked == 0 && !test_bit(STRIPE_INSYNC, &sh->state)) {
+		int update_p = 0, update_q = 0;
+		struct r5dev *dev;
+
 		set_bit(STRIPE_HANDLE, &sh->state);
-#if 0 /* RAID-6: Don't support CHECK PARITY yet */
-		if (failed == 0) {
-			char *pagea;
-			if (uptodate != disks)
-				BUG();
-			compute_parity(sh, CHECK_PARITY);
-			uptodate--;
-			pagea = page_address(sh->dev[pd_idx].page);
-			if ((*(u32*)pagea) == 0 &&
-			    !memcmp(pagea, pagea+4, STRIPE_SIZE-4)) {
-				/* parity is correct (on disc, not in buffer any more) */
-				set_bit(STRIPE_INSYNC, &sh->state);
+
+		BUG_ON(failed>2);
+		BUG_ON(uptodate < disks);
+		/* Want to check and possibly repair P and Q.
+		 * However there could be one 'failed' device, in which
+		 * case we can only check one of them, possibly using the
+		 * other to generate missing data
+		 */
+
+		/* If !tmp_page, we cannot do the calculations,
+		 * but as we have set STRIPE_HANDLE, we will soon be called
+		 * by stripe_handle with a tmp_page - just wait until then.
+		 */
+		if (tmp_page) {
+			if (failed == q_failed) {
+				/* The only possible failed device holds 'Q', so it makes
+				 * sense to check P (If anything else were failed, we would
+				 * have used P to recreate it).
+				 */
+				compute_block_1(sh, pd_idx, 1);
+				if (!page_is_zero(sh->dev[pd_idx].page)) {
+					compute_block_1(sh,pd_idx,0);
+					update_p = 1;
+				}
 			}
-		}
-#endif
-		if (!test_bit(STRIPE_INSYNC, &sh->state)) {
-			int failed_needupdate[2];
-			struct r5dev *adev, *bdev;
-
-			if ( failed < 1 )
-				failed_num[0] = pd_idx;
-			if ( failed < 2 )
-				failed_num[1] = (failed_num[0] == qd_idx) ? pd_idx : qd_idx;
-
-			failed_needupdate[0] = !test_bit(R5_UPTODATE, &sh->dev[failed_num[0]].flags);
-			failed_needupdate[1] = !test_bit(R5_UPTODATE, &sh->dev[failed_num[1]].flags);
-
-			PRINTK("sync: failed=%d num=%d,%d fnu=%u%u\n",
-			       failed, failed_num[0], failed_num[1], failed_needupdate[0], failed_needupdate[1]);
-
-#if 0  /* RAID-6: This code seems to require that CHECK_PARITY destroys the uptodateness of the parity */
-			/* should be able to compute the missing block(s) and write to spare */
-			if ( failed_needupdate[0] ^ failed_needupdate[1] ) {
-				if (uptodate+1 != disks)
-					BUG();
-				compute_block_1(sh, failed_needupdate[0] ? failed_num[0] : failed_num[1]);
-				uptodate++;
-			} else if ( failed_needupdate[0] & failed_needupdate[1] ) {
-				if (uptodate+2 != disks)
-					BUG();
-				compute_block_2(sh, failed_num[0], failed_num[1]);
-				uptodate += 2;
+			if (!q_failed && failed < 2) {
+				/* q is not failed, and we didn't use it to generate
+				 * anything, so it makes sense to check it
+				 */
+				memcpy(page_address(tmp_page),
+				       page_address(sh->dev[qd_idx].page),
+				       STRIPE_SIZE);
+				compute_parity(sh, UPDATE_PARITY);
+				if (memcmp(page_address(tmp_page),
+					   page_address(sh->dev[qd_idx].page),
+					   STRIPE_SIZE)!= 0) {
+					clear_bit(STRIPE_INSYNC, &sh->state);
+					update_q = 1;
+				}
 			}
-#else
-			compute_block_2(sh, failed_num[0], failed_num[1]);
-			uptodate += failed_needupdate[0] + failed_needupdate[1];
-#endif
+			if (update_p || update_q) {
+				conf->mddev->resync_mismatches += STRIPE_SECTORS;
+				if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery))
+					/* don't try to repair!! */
+					update_p = update_q = 0;
+			}
 
-			if (uptodate != disks)
-				BUG();
+			/* now write out any block on a failed drive,
+			 * or P or Q if they need it
+			 */
 
-			PRINTK("Marking for sync stripe %llu blocks %d,%d\n",
-			       (unsigned long long)sh->sector, failed_num[0], failed_num[1]);
+			if (failed == 2) {
+				dev = &sh->dev[failed_num[1]];
+				locked++;
+				set_bit(R5_LOCKED, &dev->flags);
+				set_bit(R5_Wantwrite, &dev->flags);
+			}
+			if (failed >= 1) {
+				dev = &sh->dev[failed_num[0]];
+				locked++;
+				set_bit(R5_LOCKED, &dev->flags);
+				set_bit(R5_Wantwrite, &dev->flags);
+			}
 
-			/**** FIX: Should we really do both of these unconditionally? ****/
-			adev = &sh->dev[failed_num[0]];
-			locked += !test_bit(R5_LOCKED, &adev->flags);
-			set_bit(R5_LOCKED, &adev->flags);
-			set_bit(R5_Wantwrite, &adev->flags);
-			bdev = &sh->dev[failed_num[1]];
-			locked += !test_bit(R5_LOCKED, &bdev->flags);
-			set_bit(R5_LOCKED, &bdev->flags);
+			if (update_p) {
+				dev = &sh->dev[pd_idx];
+				locked ++;
+				set_bit(R5_LOCKED, &dev->flags);
+				set_bit(R5_Wantwrite, &dev->flags);
+			}
+			if (update_q) {
+				dev = &sh->dev[qd_idx];
+				locked++;
+				set_bit(R5_LOCKED, &dev->flags);
+				set_bit(R5_Wantwrite, &dev->flags);
+			}
 			clear_bit(STRIPE_DEGRADED, &sh->state);
-			set_bit(R5_Wantwrite, &bdev->flags);
 
 			set_bit(STRIPE_INSYNC, &sh->state);
-			set_bit(R5_Syncio, &adev->flags);
-			set_bit(R5_Syncio, &bdev->flags);
 		}
 	}
+
 	if (syncing && locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) {
 		md_done_sync(conf->mddev, STRIPE_SECTORS,1);
 		clear_bit(STRIPE_SYNCING, &sh->state);
 	}
 
+	/* If the failed drives are just a ReadError, then we might need
+	 * to progress the repair/check process
+	 */
+	if (failed <= 2 && ! conf->mddev->ro)
+		for (i=0; i<failed;i++) {
+			dev = &sh->dev[failed_num[i]];
+			if (test_bit(R5_ReadError, &dev->flags)
+			    && !test_bit(R5_LOCKED, &dev->flags)
+			    && test_bit(R5_UPTODATE, &dev->flags)
+				) {
+				if (!test_bit(R5_ReWrite, &dev->flags)) {
+					set_bit(R5_Wantwrite, &dev->flags);
+					set_bit(R5_ReWrite, &dev->flags);
+					set_bit(R5_LOCKED, &dev->flags);
+				} else {
+					/* let's read it back */
+					set_bit(R5_Wantread, &dev->flags);
+					set_bit(R5_LOCKED, &dev->flags);
+				}
+			}
+		}
 	spin_unlock(&sh->lock);
 
 	while ((bi=return_bi)) {
@@ -1472,7 +1545,7 @@
 		rcu_read_unlock();
 
 		if (rdev) {
-			if (test_bit(R5_Syncio, &sh->dev[i].flags))
+			if (syncing)
 				md_sync_acct(rdev->bdev, STRIPE_SECTORS);
 
 			bi->bi_bdev = rdev->bdev;
@@ -1489,6 +1562,9 @@
 			bi->bi_io_vec[0].bv_offset = 0;
 			bi->bi_size = STRIPE_SIZE;
 			bi->bi_next = NULL;
+			if (rw == WRITE &&
+			    test_bit(R5_ReWrite, &sh->dev[i].flags))
+				atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
 			generic_make_request(bi);
 		} else {
 			if (rw == 1)
@@ -1664,7 +1740,7 @@
 			}
 			finish_wait(&conf->wait_for_overlap, &w);
 			raid6_plug_device(conf);
-			handle_stripe(sh);
+			handle_stripe(sh, NULL);
 			release_stripe(sh);
 		} else {
 			/* cannot get stripe for read-ahead, just give-up */
@@ -1702,6 +1778,8 @@
 	int data_disks = raid_disks - 2;
 	sector_t max_sector = mddev->size << 1;
 	int sync_blocks;
+	int still_degraded = 0;
+	int i;
 
 	if (sector_nr >= max_sector) {
 		/* just being told to finish up .. nothing much to do */
@@ -1710,7 +1788,7 @@
 		if (mddev->curr_resync < max_sector) /* aborted */
 			bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
 					&sync_blocks, 1);
-		else /* compelted sync */
+		else /* completed sync */
 			conf->fullsync = 0;
 		bitmap_close_sync(mddev->bitmap);
 
@@ -1726,6 +1804,7 @@
 		return rv;
 	}
 	if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
+	    !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
 	    !conf->fullsync && sync_blocks >= STRIPE_SECTORS) {
 		/* we can skip this block, and probably more */
 		sync_blocks /= STRIPE_SECTORS;
@@ -1748,13 +1827,22 @@
 		 */
 		schedule_timeout_uninterruptible(1);
 	}
-	bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
+	/* Need to check if array will still be degraded after recovery/resync
+	 * We don't need to check the 'failed' flag as when that gets set,
+	 * recovery aborts.
+	 */
+	for (i=0; i<mddev->raid_disks; i++)
+		if (conf->disks[i].rdev == NULL)
+			still_degraded = 1;
+
+	bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded);
+
 	spin_lock(&sh->lock);
 	set_bit(STRIPE_SYNCING, &sh->state);
 	clear_bit(STRIPE_INSYNC, &sh->state);
 	spin_unlock(&sh->lock);
 
-	handle_stripe(sh);
+	handle_stripe(sh, NULL);
 	release_stripe(sh);
 
 	return STRIPE_SECTORS;
@@ -1784,7 +1872,9 @@
 
 		if (conf->seq_flush - conf->seq_write > 0) {
 			int seq = conf->seq_flush;
+			spin_unlock_irq(&conf->device_lock);
 			bitmap_unplug(mddev->bitmap);
+			spin_lock_irq(&conf->device_lock);
 			conf->seq_write = seq;
 			activate_bit_delay(conf);
 		}
@@ -1808,7 +1898,7 @@
 		spin_unlock_irq(&conf->device_lock);
 
 		handled++;
-		handle_stripe(sh);
+		handle_stripe(sh, conf->spare_page);
 		release_stripe(sh);
 
 		spin_lock_irq(&conf->device_lock);
@@ -1835,17 +1925,19 @@
 		return -EIO;
 	}
 
-	mddev->private = kmalloc (sizeof (raid6_conf_t)
-				  + mddev->raid_disks * sizeof(struct disk_info),
-				  GFP_KERNEL);
+	mddev->private = kzalloc(sizeof (raid6_conf_t)
+				 + mddev->raid_disks * sizeof(struct disk_info),
+				 GFP_KERNEL);
 	if ((conf = mddev->private) == NULL)
 		goto abort;
-	memset (conf, 0, sizeof (*conf) + mddev->raid_disks * sizeof(struct disk_info) );
 	conf->mddev = mddev;
 
-	if ((conf->stripe_hashtbl = (struct stripe_head **) __get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER)) == NULL)
+	if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)
 		goto abort;
-	memset(conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE);
+
+	conf->spare_page = alloc_page(GFP_KERNEL);
+	if (!conf->spare_page)
+		goto abort;
 
 	spin_lock_init(&conf->device_lock);
 	init_waitqueue_head(&conf->wait_for_stripe);
@@ -1916,13 +2008,18 @@
 		goto abort;
 	}
 
-#if 0				/* FIX: For now */
 	if (mddev->degraded > 0 &&
 	    mddev->recovery_cp != MaxSector) {
-		printk(KERN_ERR "raid6: cannot start dirty degraded array for %s\n", mdname(mddev));
-		goto abort;
+		if (mddev->ok_start_degraded)
+			printk(KERN_WARNING "raid6: starting dirty degraded array:%s"
+			       "- data corruption possible.\n",
+			       mdname(mddev));
+		else {
+			printk(KERN_ERR "raid6: cannot start dirty degraded array"
+			       " for %s\n", mdname(mddev));
+			goto abort;
+		}
 	}
-#endif
 
 	{
 		mddev->thread = md_register_thread(raid6d, mddev, "%s_raid6");
@@ -1964,7 +2061,7 @@
 	 */
 	{
 		int stripe = (mddev->raid_disks-2) * mddev->chunk_size
-			/ PAGE_CACHE_SIZE;
+			/ PAGE_SIZE;
 		if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe)
 			mddev->queue->backing_dev_info.ra_pages = 2 * stripe;
 	}
@@ -1972,18 +2069,14 @@
 	/* Ok, everything is just fine now */
 	mddev->array_size =  mddev->size * (mddev->raid_disks - 2);
 
-	if (mddev->bitmap)
-		mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
-
 	mddev->queue->unplug_fn = raid6_unplug_device;
 	mddev->queue->issue_flush_fn = raid6_issue_flush;
 	return 0;
 abort:
 	if (conf) {
 		print_raid6_conf(conf);
-		if (conf->stripe_hashtbl)
-			free_pages((unsigned long) conf->stripe_hashtbl,
-							HASH_PAGES_ORDER);
+		safe_put_page(conf->spare_page);
+		kfree(conf->stripe_hashtbl);
 		kfree(conf);
 	}
 	mddev->private = NULL;
@@ -2000,7 +2093,7 @@
 	md_unregister_thread(mddev->thread);
 	mddev->thread = NULL;
 	shrink_stripes(conf);
-	free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
+	kfree(conf->stripe_hashtbl);
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
 	kfree(conf);
 	mddev->private = NULL;
@@ -2027,12 +2120,13 @@
 static void printall (struct seq_file *seq, raid6_conf_t *conf)
 {
 	struct stripe_head *sh;
+	struct hlist_node *hn;
 	int i;
 
 	spin_lock_irq(&conf->device_lock);
 	for (i = 0; i < NR_HASH; i++) {
 		sh = conf->stripe_hashtbl[i];
-		for (; sh; sh = sh->hash_next) {
+		hlist_for_each_entry(sh, hn, &conf->stripe_hashtbl[i], hash) {
 			if (sh->raid_conf != conf)
 				continue;
 			print_sh(seq, sh);
@@ -2145,9 +2239,15 @@
 		/* no point adding a device */
 		return 0;
 	/*
-	 * find the disk ...
+	 * find the disk ... but prefer rdev->saved_raid_disk
+	 * if possible.
 	 */
-	for (disk=0; disk < mddev->raid_disks; disk++)
+	if (rdev->saved_raid_disk >= 0 &&
+	    conf->disks[rdev->saved_raid_disk].rdev == NULL)
+		disk = rdev->saved_raid_disk;
+	else
+		disk = 0;
+	for ( ; disk < mddev->raid_disks; disk++)
 		if ((p=conf->disks + disk)->rdev == NULL) {
 			clear_bit(In_sync, &rdev->flags);
 			rdev->raid_disk = disk;
@@ -2204,17 +2304,12 @@
 		spin_unlock_irq(&conf->device_lock);
 		break;
 	}
-	if (mddev->thread) {
-		if (mddev->bitmap)
-			mddev->thread->timeout = mddev->bitmap->daemon_sleep * HZ;
-		else
-			mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
-		md_wakeup_thread(mddev->thread);
-	}
 }
-static mdk_personality_t raid6_personality=
+
+static struct mdk_personality raid6_personality =
 {
 	.name		= "raid6",
+	.level		= 6,
 	.owner		= THIS_MODULE,
 	.make_request	= make_request,
 	.run		= run,
@@ -2229,7 +2324,7 @@
 	.quiesce	= raid6_quiesce,
 };
 
-static int __init raid6_init (void)
+static int __init raid6_init(void)
 {
 	int e;
 
@@ -2237,15 +2332,17 @@
 	if ( e )
 		return e;
 
-	return register_md_personality (RAID6, &raid6_personality);
+	return register_md_personality(&raid6_personality);
 }
 
 static void raid6_exit (void)
 {
-	unregister_md_personality (RAID6);
+	unregister_md_personality(&raid6_personality);
 }
 
 module_init(raid6_init);
 module_exit(raid6_exit);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("md-personality-8"); /* RAID6 */
+MODULE_ALIAS("md-raid6");
+MODULE_ALIAS("md-level-6");
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index caebd0a..6a901a0 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -1,12 +1,12 @@
 config VIDEO_SAA7146
-        tristate
+	tristate
 	select I2C
 
 config VIDEO_SAA7146_VV
-        tristate
+	tristate
 	select VIDEO_BUF
 	select VIDEO_VIDEOBUF
 	select VIDEO_SAA7146
 
 config VIDEO_VIDEOBUF
-        tristate
+	tristate
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index 97b4341..bd458cb 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,5 +1,5 @@
-saa7146-objs    := saa7146_i2c.o saa7146_core.o 
-saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o  
+saa7146-objs    := saa7146_i2c.o saa7146_core.o
+saa7146_vv-objs := saa7146_vv_ksyms.o saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
 
 obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
 obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index 7972c73..97fa3fc 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -313,6 +313,7 @@
 	if (ir_codes)
 		memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
 
+
 	dev->keycode     = ir->ir_codes;
 	dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
 	dev->keycodemax  = IR_KEYTAB_SIZE;
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 206cc2f..2899d34 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -174,8 +174,8 @@
 
 int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
 {
-        u32          *cpu;
-        dma_addr_t   dma_addr;
+	u32          *cpu;
+	dma_addr_t   dma_addr;
 
 	cpu = pci_alloc_consistent(pci, PAGE_SIZE, &dma_addr);
 	if (NULL == cpu) {
@@ -405,7 +405,7 @@
 
 	pci_set_drvdata(pci, dev);
 
-        init_MUTEX(&dev->lock);
+	init_MUTEX(&dev->lock);
 	spin_lock_init(&dev->int_slock);
 	spin_lock_init(&dev->slock);
 
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 3788898..09ec964 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -1,6 +1,6 @@
 #include <media/saa7146_vv.h>
 
-#define BOARD_CAN_DO_VBI(dev)   (dev->revision != 0 && dev->vv_data->vbi_minor != -1) 
+#define BOARD_CAN_DO_VBI(dev)   (dev->revision != 0 && dev->vv_data->vbi_minor != -1)
 
 /****************************************************************************/
 /* resource management functions, shamelessly stolen from saa7134 driver */
@@ -102,9 +102,9 @@
 	/* finish current buffer */
 	if (NULL == q->curr) {
 		DEB_D(("aiii. no current buffer\n"));
-		return;	
+		return;
 	}
-			
+
 	q->curr->vb.state = state;
 	do_gettimeofday(&q->curr->vb.ts);
 	wake_up(&q->curr->vb.done);
@@ -143,13 +143,13 @@
 			// fixme: fix this for vflip != 0
 
 			saa7146_write(dev, PROT_ADDR1, 0);
-			saa7146_write(dev, MC2, (MASK_02|MASK_18));		
+			saa7146_write(dev, MC2, (MASK_02|MASK_18));
 
 			/* write the address of the rps-program */
 			saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
 			/* turn on rps */
 			saa7146_write(dev, MC1, (MASK_12 | MASK_28));
-				
+
 /*
 			printk("vdma%d.base_even:     0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
 			printk("vdma%d.base_odd:      0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
@@ -246,7 +246,7 @@
 		goto out;
 	}
 	memset(fh,0,sizeof(*fh));
-	
+
 	file->private_data = fh;
 	fh->dev = dev;
 	fh->type = type;
@@ -275,7 +275,7 @@
 		file->private_data = NULL;
 	}
 	up(&saa7146_devices_lock);
-        return result;
+	return result;
 }
 
 static int fops_release(struct inode *inode, struct file *file)
@@ -405,7 +405,7 @@
 static void vv_callback(struct saa7146_dev *dev, unsigned long status)
 {
 	u32 isr = status;
-	
+
 	DEB_INT(("dev:%p, isr:0x%08x\n",dev,(u32)status));
 
 	if (0 != (isr & (MASK_27))) {
@@ -454,11 +454,11 @@
 	   handle different devices that might need different
 	   configuration data) */
 	dev->ext_vv_data = ext_vv;
-	
+
 	vv->video_minor = -1;
 	vv->vbi_minor = -1;
 
-	vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);	
+	vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);
 	if( NULL == vv->d_clipping.cpu_addr ) {
 		ERR(("out of memory. aborting.\n"));
 		kfree(vv);
@@ -468,7 +468,7 @@
 
 	saa7146_video_uops.init(dev,vv);
 	saa7146_vbi_uops.init(dev,vv);
-	
+
 	dev->vv_data = vv;
 	dev->vv_callback = &vv_callback;
 
@@ -480,12 +480,12 @@
 	struct saa7146_vv *vv = dev->vv_data;
 
 	DEB_EE(("dev:%p\n",dev));
- 
+
 	pci_free_consistent(dev->pci, SAA7146_RPS_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
- 	kfree(vv);
+	kfree(vv);
 	dev->vv_data = NULL;
 	dev->vv_callback = NULL;
-	
+
 	return 0;
 }
 
@@ -498,7 +498,7 @@
 	DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));
 
 	// released by vfd->release
- 	vfd = video_device_alloc();
+	vfd = video_device_alloc();
 	if (vfd == NULL)
 		return -ENOMEM;
 
@@ -530,7 +530,7 @@
 int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
 {
 	struct saa7146_vv *vv = dev->vv_data;
-	
+
 	DEB_EE(("dev:%p\n",dev));
 
 	if( VFL_TYPE_GRABBER == (*vid)->type ) {
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index fec6bea..8aabdd8fb 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -276,8 +276,8 @@
 	int i = 0, count = 0;
 	u32* buffer = dev->d_i2c.cpu_addr;
 	int err = 0;
-        int address_err = 0;
-        int short_delay = 0;
+	int address_err = 0;
+	int short_delay = 0;
 
 	if (down_interruptible (&dev->i2c_lock))
 		return -ERESTARTSYS;
@@ -325,7 +325,7 @@
 					if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
 						goto out;
 					}
-				        address_err++;
+					address_err++;
 				}
 				DEB_I2C(("error while sending message(s). starting again.\n"));
 				break;
@@ -336,14 +336,14 @@
 			break;
 		}
 
-	        /* delay a bit before retrying */
-	        msleep(10);
+		/* delay a bit before retrying */
+		msleep(10);
 
 	} while (err != num && retries--);
 
-        /* if every retry had an address error, exit right away */
-        if (address_err == retries) {
-	        goto out;
+	/* if every retry had an address error, exit right away */
+	if (address_err == retries) {
+		goto out;
 	}
 
 	/* if any things had to be read, get the results */
diff --git a/drivers/media/common/saa7146_vbi.c b/drivers/media/common/saa7146_vbi.c
index cb86a97..063986e 100644
--- a/drivers/media/common/saa7146_vbi.c
+++ b/drivers/media/common/saa7146_vbi.c
@@ -6,8 +6,8 @@
 {
 	struct saa7146_vv *vv = dev->vv_data;
 
-        u32          *cpu;
-        dma_addr_t   dma_addr;
+	u32          *cpu;
+	dma_addr_t   dma_addr;
 
 	int count = 0;
 	int i;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 8dd4d15..1d96102 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -150,23 +150,23 @@
 	maxh  = vv->standard->v_max_out;
 
 	if (V4L2_FIELD_ANY == field) {
-                field = (win->w.height > maxh/2)
-                        ? V4L2_FIELD_INTERLACED
-                        : V4L2_FIELD_TOP;
-	        }
-        switch (field) {
-        case V4L2_FIELD_TOP:
-        case V4L2_FIELD_BOTTOM:
-        case V4L2_FIELD_ALTERNATE:
-                maxh = maxh / 2;
-                break;
-        case V4L2_FIELD_INTERLACED:
-                break;
-        default: {
+		field = (win->w.height > maxh/2)
+		        ? V4L2_FIELD_INTERLACED
+		        : V4L2_FIELD_TOP;
+		}
+	switch (field) {
+	case V4L2_FIELD_TOP:
+	case V4L2_FIELD_BOTTOM:
+	case V4L2_FIELD_ALTERNATE:
+		maxh = maxh / 2;
+		break;
+	case V4L2_FIELD_INTERLACED:
+		break;
+	default: {
 		DEB_D(("no known field mode '%d'.\n",field));
-                return -EINVAL;
+		return -EINVAL;
 	}
-        }
+	}
 
 	win->field = field;
 	if (win->w.width > maxw)
@@ -887,7 +887,7 @@
 
 		DEB_EE(("VIDIOC_QUERYCAP\n"));
 
-                strcpy(cap->driver, "saa7146 v4l2");
+		strcpy(cap->driver, "saa7146 v4l2");
 		strlcpy(cap->card, dev->ext->name, sizeof(cap->card));
 		sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci));
 		cap->version = SAA7146_VERSION_CODE;
@@ -1011,19 +1011,19 @@
 		err = set_control(fh,arg);
 		return err;
 	}
-        case VIDIOC_G_PARM:
-        {
-                struct v4l2_streamparm *parm = arg;
+	case VIDIOC_G_PARM:
+	{
+		struct v4l2_streamparm *parm = arg;
 		if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) {
 			return -EINVAL;
 		}
-                memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm));
+		memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm));
 		parm->parm.capture.readbuffers = 1;
 		// fixme: only for PAL!
 		parm->parm.capture.timeperframe.numerator = 1;
 		parm->parm.capture.timeperframe.denominator = 25;
-                return 0;
-        }
+		return 0;
+	}
 	case VIDIOC_G_FMT:
 	{
 		struct v4l2_format *f = arg;
@@ -1383,7 +1383,7 @@
 
 static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
 {
-        INIT_LIST_HEAD(&vv->video_q.queue);
+	INIT_LIST_HEAD(&vv->video_q.queue);
 
 	init_timer(&vv->video_q.timeout);
 	vv->video_q.timeout.function = saa7146_buffer_timeout;
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index a94912a..344a3c8 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -132,7 +132,7 @@
  * I2C-channel of the flexcop.
  */
 int flexcop_i2c_request(struct flexcop_device*, flexcop_access_op_t,
-		        flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
+			flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
 
 /* from flexcop-sram.c */
 int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target);
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index a353303..21a9045 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -298,7 +298,7 @@
 }
 
 static int lgdt3303_pll_set(struct dvb_frontend* fe,
-                            struct dvb_frontend_parameters* params)
+		            struct dvb_frontend_parameters* params)
 {
 	struct flexcop_device *fc = fe->dvb->priv;
 	u8 buf[4];
@@ -332,7 +332,7 @@
 			return -EREMOTEIO;
 	}
 
-        return 0;
+	return 0;
 }
 
 static struct lgdt330x_config air2pc_atsc_hd5000_config = {
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
index 75cf237..b386cc6 100644
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -19,7 +19,7 @@
 	flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff);
 }
 
-void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
+static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
 {
 	flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff);
 }
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index 0a78ba3..a6c91db 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -544,7 +544,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver flexcop_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "b2c2_flexcop_usb",
 	.probe		= flexcop_usb_probe,
 	.disconnect = flexcop_usb_disconnect,
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index e6541af..2239651 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -406,7 +406,7 @@
 	}
 	dprintk(verbose, DST_CA_DEBUG, 1, " ");
 
-	if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) {
+	if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) {
 		result = -EFAULT;
 		goto free_mem_and_exit;
 	}
@@ -579,7 +579,7 @@
 	return 0;
 }
 
-static int dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
+static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset)
 {
 	int bytes_read = 0;
 
@@ -588,7 +588,7 @@
 	return bytes_read;
 }
 
-static int dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
+static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset)
 {
 	dprintk(verbose, DST_CA_DEBUG, 1, " Device write.");
 
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 2e39809..77977e9 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -556,9 +556,9 @@
 	dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
 		__FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
 	if ((err = i2c_transfer(card->i2c_adapter, &msg, 1)) != 1) {
-	        printk(KERN_WARNING "dvb-bt8xx: %s error "
-		        "(addr %02x <- %02x, err = %i)\n",
-		        __FUNCTION__, buf[0], buf[1], err);
+		printk(KERN_WARNING "dvb-bt8xx: %s error "
+			"(addr %02x <- %02x, err = %i)\n",
+			__FUNCTION__, buf[0], buf[1], err);
 		if (err < 0)
 			return err;
 		else
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 336fc28..1d69bf0 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -60,7 +60,7 @@
 #define dprintk(level, args...)						\
 do {									\
 	if ((debug & level)) {						\
-		printk("%s: %s(): ", __stringify(KBUILD_MODNAME),	\
+		printk("%s: %s(): ", KBUILD_MODNAME,			\
 		       __FUNCTION__);					\
 		printk(args); }						\
 } while (0)
@@ -986,7 +986,6 @@
 MODULE_DEVICE_TABLE(usb, cinergyt2_table);
 
 static struct usb_driver cinergyt2_driver = {
-	.owner	= THIS_MODULE,
 	.name	= "cinergyT2",
 	.probe	= cinergyt2_probe,
 	.disconnect	= cinergyt2_disconnect,
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index 7d7b006..9f02582 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -86,25 +86,25 @@
 
 enum dmx_ts_pes
 {  /* also send packets to decoder (if it exists) */
-        DMX_TS_PES_AUDIO0,
+	DMX_TS_PES_AUDIO0,
 	DMX_TS_PES_VIDEO0,
 	DMX_TS_PES_TELETEXT0,
 	DMX_TS_PES_SUBTITLE0,
 	DMX_TS_PES_PCR0,
 
-        DMX_TS_PES_AUDIO1,
+	DMX_TS_PES_AUDIO1,
 	DMX_TS_PES_VIDEO1,
 	DMX_TS_PES_TELETEXT1,
 	DMX_TS_PES_SUBTITLE1,
 	DMX_TS_PES_PCR1,
 
-        DMX_TS_PES_AUDIO2,
+	DMX_TS_PES_AUDIO2,
 	DMX_TS_PES_VIDEO2,
 	DMX_TS_PES_TELETEXT2,
 	DMX_TS_PES_SUBTITLE2,
 	DMX_TS_PES_PCR2,
 
-        DMX_TS_PES_AUDIO3,
+	DMX_TS_PES_AUDIO3,
 	DMX_TS_PES_VIDEO3,
 	DMX_TS_PES_TELETEXT3,
 	DMX_TS_PES_SUBTITLE3,
@@ -121,17 +121,17 @@
 
 
 struct dmx_ts_feed {
-        int is_filtering; /* Set to non-zero when filtering in progress */
-        struct dmx_demux *parent; /* Back-pointer */
-        void *priv; /* Pointer to private data of the API client */
-        int (*set) (struct dmx_ts_feed *feed,
+	int is_filtering; /* Set to non-zero when filtering in progress */
+	struct dmx_demux *parent; /* Back-pointer */
+	void *priv; /* Pointer to private data of the API client */
+	int (*set) (struct dmx_ts_feed *feed,
 		    u16 pid,
 		    int type,
 		    enum dmx_ts_pes pes_type,
 		    size_t circular_buffer_size,
 		    struct timespec timeout);
-        int (*start_filtering) (struct dmx_ts_feed* feed);
-        int (*stop_filtering) (struct dmx_ts_feed* feed);
+	int (*start_filtering) (struct dmx_ts_feed* feed);
+	int (*stop_filtering) (struct dmx_ts_feed* feed);
 };
 
 /*--------------------------------------------------------------------------*/
@@ -139,35 +139,35 @@
 /*--------------------------------------------------------------------------*/
 
 struct dmx_section_filter {
-        u8 filter_value [DMX_MAX_FILTER_SIZE];
-        u8 filter_mask [DMX_MAX_FILTER_SIZE];
-        u8 filter_mode [DMX_MAX_FILTER_SIZE];
-        struct dmx_section_feed* parent; /* Back-pointer */
-        void* priv; /* Pointer to private data of the API client */
+	u8 filter_value [DMX_MAX_FILTER_SIZE];
+	u8 filter_mask [DMX_MAX_FILTER_SIZE];
+	u8 filter_mode [DMX_MAX_FILTER_SIZE];
+	struct dmx_section_feed* parent; /* Back-pointer */
+	void* priv; /* Pointer to private data of the API client */
 };
 
 struct dmx_section_feed {
-        int is_filtering; /* Set to non-zero when filtering in progress */
-        struct dmx_demux* parent; /* Back-pointer */
-        void* priv; /* Pointer to private data of the API client */
+	int is_filtering; /* Set to non-zero when filtering in progress */
+	struct dmx_demux* parent; /* Back-pointer */
+	void* priv; /* Pointer to private data of the API client */
 
-        int check_crc;
+	int check_crc;
 	u32 crc_val;
 
-        u8 *secbuf;
-        u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
-        u16 secbufp, seclen, tsfeedp;
+	u8 *secbuf;
+	u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
+	u16 secbufp, seclen, tsfeedp;
 
-        int (*set) (struct dmx_section_feed* feed,
+	int (*set) (struct dmx_section_feed* feed,
 		    u16 pid,
 		    size_t circular_buffer_size,
 		    int check_crc);
-        int (*allocate_filter) (struct dmx_section_feed* feed,
+	int (*allocate_filter) (struct dmx_section_feed* feed,
 				struct dmx_section_filter** filter);
-        int (*release_filter) (struct dmx_section_feed* feed,
+	int (*release_filter) (struct dmx_section_feed* feed,
 			       struct dmx_section_filter* filter);
-        int (*start_filtering) (struct dmx_section_feed* feed);
-        int (*stop_filtering) (struct dmx_section_feed* feed);
+	int (*start_filtering) (struct dmx_section_feed* feed);
+	int (*stop_filtering) (struct dmx_section_feed* feed);
 };
 
 /*--------------------------------------------------------------------------*/
@@ -205,10 +205,10 @@
 };
 
 struct dmx_frontend {
-        struct list_head connectivity_list; /* List of front-ends that can
+	struct list_head connectivity_list; /* List of front-ends that can
 					       be connected to a particular
 					       demux */
-        enum dmx_frontend_source source;
+	enum dmx_frontend_source source;
 };
 
 /*--------------------------------------------------------------------------*/
@@ -240,38 +240,38 @@
 #define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list)
 
 struct dmx_demux {
-        u32 capabilities;            /* Bitfield of capability flags */
-        struct dmx_frontend* frontend;    /* Front-end connected to the demux */
-        void* priv;                  /* Pointer to private data of the API client */
-        int (*open) (struct dmx_demux* demux);
-        int (*close) (struct dmx_demux* demux);
-        int (*write) (struct dmx_demux* demux, const char* buf, size_t count);
-        int (*allocate_ts_feed) (struct dmx_demux* demux,
+	u32 capabilities;            /* Bitfield of capability flags */
+	struct dmx_frontend* frontend;    /* Front-end connected to the demux */
+	void* priv;                  /* Pointer to private data of the API client */
+	int (*open) (struct dmx_demux* demux);
+	int (*close) (struct dmx_demux* demux);
+	int (*write) (struct dmx_demux* demux, const char* buf, size_t count);
+	int (*allocate_ts_feed) (struct dmx_demux* demux,
 				 struct dmx_ts_feed** feed,
 				 dmx_ts_cb callback);
-        int (*release_ts_feed) (struct dmx_demux* demux,
+	int (*release_ts_feed) (struct dmx_demux* demux,
 				struct dmx_ts_feed* feed);
-        int (*allocate_section_feed) (struct dmx_demux* demux,
+	int (*allocate_section_feed) (struct dmx_demux* demux,
 				      struct dmx_section_feed** feed,
 				      dmx_section_cb callback);
-        int (*release_section_feed) (struct dmx_demux* demux,
+	int (*release_section_feed) (struct dmx_demux* demux,
 				     struct dmx_section_feed* feed);
-        int (*add_frontend) (struct dmx_demux* demux,
+	int (*add_frontend) (struct dmx_demux* demux,
 			     struct dmx_frontend* frontend);
-        int (*remove_frontend) (struct dmx_demux* demux,
+	int (*remove_frontend) (struct dmx_demux* demux,
 				struct dmx_frontend* frontend);
-        struct list_head* (*get_frontends) (struct dmx_demux* demux);
-        int (*connect_frontend) (struct dmx_demux* demux,
+	struct list_head* (*get_frontends) (struct dmx_demux* demux);
+	int (*connect_frontend) (struct dmx_demux* demux,
 				 struct dmx_frontend* frontend);
-        int (*disconnect_frontend) (struct dmx_demux* demux);
+	int (*disconnect_frontend) (struct dmx_demux* demux);
 
-        int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
+	int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
 
 	int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps);
 
 	int (*set_source) (struct dmx_demux* demux, const dmx_source_t *src);
 
-        int (*get_stc) (struct dmx_demux* demux, unsigned int num,
+	int (*get_stc) (struct dmx_demux* demux, unsigned int num,
 			u64 *stc, unsigned int *base);
 };
 
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 8028c3a5e..7b8373a 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -947,7 +947,7 @@
 
 	case DMX_GET_STC:
 		if (!dmxdev->demux->get_stc) {
-		        ret=-EINVAL;
+			ret=-EINVAL;
 			break;
 		}
 		ret = dmxdev->demux->get_stc(dmxdev->demux,
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index 395a9cd..fd72920 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -53,51 +53,51 @@
 };
 
 struct dmxdev_buffer {
-        u8 *data;
-        int size;
-        int pread;
-        int pwrite;
+	u8 *data;
+	int size;
+	int pread;
+	int pwrite;
 	wait_queue_head_t queue;
-        int error;
+	int error;
 };
 
 struct dmxdev_filter {
 	struct dvb_device *dvbdev;
 
-        union {
-	        struct dmx_section_filter *sec;
+	union {
+		struct dmx_section_filter *sec;
 	} filter;
 
-        union {
-                struct dmx_ts_feed *ts;
-                struct dmx_section_feed *sec;
+	union {
+		struct dmx_ts_feed *ts;
+		struct dmx_section_feed *sec;
 	} feed;
 
-        union {
-	        struct dmx_sct_filter_params sec;
-	        struct dmx_pes_filter_params pes;
+	union {
+		struct dmx_sct_filter_params sec;
+		struct dmx_pes_filter_params pes;
 	} params;
 
-        int type;
-        enum dmxdev_state state;
-        struct dmxdev *dev;
-        struct dmxdev_buffer buffer;
+	int type;
+	enum dmxdev_state state;
+	struct dmxdev *dev;
+	struct dmxdev_buffer buffer;
 
 	struct semaphore mutex;
 
-        /* only for sections */
-        struct timer_list timer;
-        int todo;
-        u8 secheader[3];
+	/* only for sections */
+	struct timer_list timer;
+	int todo;
+	u8 secheader[3];
 
-        u16 pid;
+	u16 pid;
 };
 
 
 struct dmxdev_dvr {
-        int state;
-        struct dmxdev *dev;
-        struct dmxdev_buffer buffer;
+	int state;
+	struct dmxdev *dev;
+	struct dmxdev_buffer buffer;
 };
 
 
@@ -105,16 +105,16 @@
 	struct dvb_device *dvbdev;
 	struct dvb_device *dvr_dvbdev;
 
-        struct dmxdev_filter *filter;
-        struct dmxdev_dvr *dvr;
-        struct dmx_demux *demux;
+	struct dmxdev_filter *filter;
+	struct dmxdev_dvr *dvr;
+	struct dmx_demux *demux;
 
-        int filternum;
-        int capabilities;
+	int filternum;
+	int capabilities;
 #define DMXDEV_CAP_DUPLEX 1
-        struct dmx_frontend *dvr_orig_fe;
+	struct dmx_frontend *dvr_orig_fe;
 
-        struct dmxdev_buffer dvr_buffer;
+	struct dmxdev_buffer dvr_buffer;
 #define DVR_BUFFER_SIZE (10*188*1024)
 
 	struct semaphore mutex;
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 2aa767f..5956c35 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -35,7 +35,7 @@
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
-#include <linux/rwsem.h>
+#include <linux/spinlock.h>
 #include <linux/sched.h>
 
 #include "dvb_ca_en50221.h"
@@ -111,9 +111,6 @@
 	/* size of the buffer to use when talking to the CAM */
 	int link_buf_size;
 
-	/* semaphore for syncing access to slot structure */
-	struct rw_semaphore sem;
-
 	/* buffer for incoming packets */
 	struct dvb_ringbuffer rx_buffer;
 
@@ -501,7 +498,7 @@
 	/* process the CFTABLE_ENTRY tuples, and any after those */
 	while ((!end_chain) && (address < 0x1000)) {
 		if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType,
-						        &tupleLength, tuple)) < 0)
+							&tupleLength, tuple)) < 0)
 			return status;
 		switch (tupleType) {
 		case 0x1B:	// CISTPL_CFTABLE_ENTRY
@@ -602,14 +599,11 @@
 	if (ebuf == NULL) {
 		int buf_free;
 
-		down_read(&ca->slot_info[slot].sem);
 		if (ca->slot_info[slot].rx_buffer.data == NULL) {
-			up_read(&ca->slot_info[slot].sem);
 			status = -EIO;
 			goto exit;
 		}
 		buf_free = dvb_ringbuffer_free(&ca->slot_info[slot].rx_buffer);
-		up_read(&ca->slot_info[slot].sem);
 
 		if (buf_free < (ca->slot_info[slot].link_buf_size + DVB_RINGBUFFER_PKTHDRSIZE)) {
 			status = -EAGAIN;
@@ -680,14 +674,11 @@
 
 	/* OK, add it to the receive buffer, or copy into external buffer if supplied */
 	if (ebuf == NULL) {
-		down_read(&ca->slot_info[slot].sem);
 		if (ca->slot_info[slot].rx_buffer.data == NULL) {
-			up_read(&ca->slot_info[slot].sem);
 			status = -EIO;
 			goto exit;
 		}
 		dvb_ringbuffer_pkt_write(&ca->slot_info[slot].rx_buffer, buf, bytes_read);
-		up_read(&ca->slot_info[slot].sem);
 	} else {
 		memcpy(ebuf, buf, bytes_read);
 	}
@@ -802,12 +793,8 @@
 {
 	dprintk("%s\n", __FUNCTION__);
 
-	down_write(&ca->slot_info[slot].sem);
 	ca->pub->slot_shutdown(ca->pub, slot);
 	ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE;
-	vfree(ca->slot_info[slot].rx_buffer.data);
-	ca->slot_info[slot].rx_buffer.data = NULL;
-	up_write(&ca->slot_info[slot].sem);
 
 	/* need to wake up all processes to check if they're now
 	   trying to write to a defunct CAM */
@@ -893,7 +880,7 @@
 
 	case DVB_CA_SLOTSTATE_RUNNING:
 		if (ca->open)
-			dvb_ca_en50221_read_data(ca, slot, NULL, 0);
+			dvb_ca_en50221_thread_wakeup(ca);
 		break;
 	}
 }
@@ -1127,16 +1114,16 @@
 					break;
 				}
 
-				rxbuf = vmalloc(RX_BUFFER_SIZE);
-				if (rxbuf == NULL) {
-					printk("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->dvbdev->adapter->num);
-					ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
-					dvb_ca_en50221_thread_update_delay(ca);
-					break;
+				if (ca->slot_info[slot].rx_buffer.data == NULL) {
+					rxbuf = vmalloc(RX_BUFFER_SIZE);
+					if (rxbuf == NULL) {
+						printk("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->dvbdev->adapter->num);
+						ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID;
+						dvb_ca_en50221_thread_update_delay(ca);
+						break;
+					}
+					dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE);
 				}
-				down_write(&ca->slot_info[slot].sem);
-				dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE);
-				up_write(&ca->slot_info[slot].sem);
 
 				ca->pub->slot_ts_enable(ca->pub, slot);
 				ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING;
@@ -1148,11 +1135,7 @@
 				if (!ca->open)
 					continue;
 
-				// no need to poll if the CAM supports IRQs
-				if (ca->slot_info[slot].da_irq_supported)
-					break;
-
-				// poll mode
+				// poll slots for data
 				pktcount = 0;
 				while ((status = dvb_ca_en50221_read_data(ca, slot, NULL, 0)) > 0) {
 					if (!ca->open)
@@ -1367,12 +1350,13 @@
 /**
  * Condition for waking up in dvb_ca_en50221_io_read_condition
  */
-static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, int *result, int *_slot)
+static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
+					    int *result, int *_slot)
 {
 	int slot;
 	int slot_count = 0;
 	int idx;
-	int fraglen;
+	size_t fraglen;
 	int connection_id = -1;
 	int found = 0;
 	u8 hdr[2];
@@ -1382,10 +1366,7 @@
 		if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING)
 			goto nextslot;
 
-		down_read(&ca->slot_info[slot].sem);
-
 		if (ca->slot_info[slot].rx_buffer.data == NULL) {
-			up_read(&ca->slot_info[slot].sem);
 			return 0;
 		}
 
@@ -1403,10 +1384,7 @@
 			idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen);
 		}
 
-		if (!found)
-			up_read(&ca->slot_info[slot].sem);
-
-	      nextslot:
+nextslot:
 		slot = (slot + 1) % ca->slot_count;
 		slot_count++;
 	}
@@ -1511,8 +1489,7 @@
 		goto exit;
 	status = pktlen;
 
-      exit:
-	up_read(&ca->slot_info[slot].sem);
+exit:
 	return status;
 }
 
@@ -1544,11 +1521,11 @@
 	for (i = 0; i < ca->slot_count; i++) {
 
 		if (ca->slot_info[i].slot_state == DVB_CA_SLOTSTATE_RUNNING) {
-			down_write(&ca->slot_info[i].sem);
 			if (ca->slot_info[i].rx_buffer.data != NULL) {
+				/* it is safe to call this here without locks because
+				 * ca->open == 0. Data is not read in this case */
 				dvb_ringbuffer_flush(&ca->slot_info[i].rx_buffer);
 			}
-			up_write(&ca->slot_info[i].sem);
 		}
 	}
 
@@ -1607,7 +1584,6 @@
 	dprintk("%s\n", __FUNCTION__);
 
 	if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
-		up_read(&ca->slot_info[slot].sem);
 		mask |= POLLIN;
 	}
 
@@ -1619,7 +1595,6 @@
 	poll_wait(file, &ca->wait_queue, wait);
 
 	if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) {
-		up_read(&ca->slot_info[slot].sem);
 		mask |= POLLIN;
 	}
 
@@ -1709,7 +1684,6 @@
 		ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE;
 		atomic_set(&ca->slot_info[i].camchange_count, 0);
 		ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED;
-		init_rwsem(&ca->slot_info[i].sem);
 	}
 
 	if (signal_pending(current)) {
@@ -1729,7 +1703,7 @@
 	ca->thread_pid = ret;
 	return 0;
 
-      error:
+error:
 	if (ca != NULL) {
 		if (ca->dvbdev != NULL)
 			dvb_unregister_device(ca->dvbdev);
@@ -1771,6 +1745,9 @@
 
 	for (i = 0; i < ca->slot_count; i++) {
 		dvb_ca_en50221_slot_shutdown(ca, i);
+		if (ca->slot_info[i].rx_buffer.data != NULL) {
+			vfree(ca->slot_info[i].rx_buffer.data);
+		}
 	}
 	kfree(ca->slot_info);
 	dvb_unregister_device(ca->dvbdev);
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c
index bd51439..c49fd0b 100644
--- a/drivers/media/dvb/dvb-core/dvb_filter.c
+++ b/drivers/media/dvb/dvb-core/dvb_filter.c
@@ -72,12 +72,12 @@
 	u8 pct;
 
 	if (pr) printk( "Pic header: ");
-        pic->temporal_reference[field] = (( headr[0] << 2 ) |
+	pic->temporal_reference[field] = (( headr[0] << 2 ) |
 					  (headr[1] & 0x03) )& 0x03ff;
 	if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]);
 
 	pct = ( headr[1] >> 2 ) & 0x07;
-        pic->picture_coding_type[field] = pct;
+	pic->picture_coding_type[field] = pct;
 	if (pr) {
 		switch(pct){
 			case I_FRAME:
@@ -93,17 +93,17 @@
 	}
 
 
-        pic->vinfo.vbv_delay  = (( headr[1] >> 5 ) | ( headr[2] << 3) |
+	pic->vinfo.vbv_delay  = (( headr[1] >> 5 ) | ( headr[2] << 3) |
 				 ( (headr[3] & 0x1F) << 11) ) & 0xffff;
 
 	if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay);
 
-        pic->picture_header_parameter = ( headr[3] & 0xe0 ) |
+	pic->picture_header_parameter = ( headr[3] & 0xe0 ) |
 		((headr[4] & 0x80) >> 3);
 
-        if ( pct == B_FRAME ){
-                pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f;
-        }
+	if ( pct == B_FRAME ){
+		pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f;
+	}
 	if (pr) printk( " pic head param: 0x%x",
 			pic->picture_header_parameter);
 
@@ -124,18 +124,18 @@
 		       ((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F),
 		       ((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F));
 
-        if ( ( headr[3] & 0x40 ) != 0 ){
-                pic->closed_gop = 1;
-        } else {
-                pic->closed_gop = 0;
-        }
+	if ( ( headr[3] & 0x40 ) != 0 ){
+		pic->closed_gop = 1;
+	} else {
+		pic->closed_gop = 0;
+	}
 	if (pr) printk("closed: %d", pic->closed_gop);
 
-        if ( ( headr[3] & 0x20 ) != 0 ){
-                pic->broken_link = 1;
-        } else {
-                pic->broken_link = 0;
-        }
+	if ( ( headr[3] & 0x20 ) != 0 ){
+		pic->broken_link = 1;
+	} else {
+		pic->broken_link = 0;
+	}
 	if (pr) printk(" broken: %d\n", pic->broken_link);
 
 	return 0;
@@ -146,7 +146,7 @@
 /* needs 8 byte input */
 static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr)
 {
-        int sw;
+	int sw;
 	int form = -1;
 
 	if (pr) printk("Reading sequence header\n");
@@ -154,9 +154,9 @@
 	vi->horizontal_size	= ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
 	vi->vertical_size	= ((headr[1] &0x0F) << 8) | (headr[2]);
 
-        sw = (int)((headr[3]&0xF0) >> 4) ;
+	sw = (int)((headr[3]&0xF0) >> 4) ;
 
-        switch( sw ){
+	switch( sw ){
 	case 1:
 		if (pr)
 			printk("Videostream: ASPECT: 1:1");
@@ -165,84 +165,84 @@
 	case 2:
 		if (pr)
 			printk("Videostream: ASPECT: 4:3");
-                vi->aspect_ratio = 133;
+		vi->aspect_ratio = 133;
 		break;
 	case 3:
 		if (pr)
 			printk("Videostream: ASPECT: 16:9");
-                vi->aspect_ratio = 177;
+		vi->aspect_ratio = 177;
 		break;
 	case 4:
 		if (pr)
 			printk("Videostream: ASPECT: 2.21:1");
-                vi->aspect_ratio = 221;
+		vi->aspect_ratio = 221;
 		break;
 
-        case 5 ... 15:
+	case 5 ... 15:
 		if (pr)
 			printk("Videostream: ASPECT: reserved");
-                vi->aspect_ratio = 0;
+		vi->aspect_ratio = 0;
 		break;
 
-        default:
-                vi->aspect_ratio = 0;
-                return -1;
+	default:
+		vi->aspect_ratio = 0;
+		return -1;
 	}
 
 	if (pr)
 		printk("  Size = %dx%d",vi->horizontal_size,vi->vertical_size);
 
-        sw = (int)(headr[3]&0x0F);
+	sw = (int)(headr[3]&0x0F);
 
-        switch ( sw ) {
+	switch ( sw ) {
 	case 1:
 		if (pr)
 			printk("  FRate: 23.976 fps");
-                vi->framerate = 23976;
+		vi->framerate = 23976;
 		form = -1;
 		break;
 	case 2:
 		if (pr)
 			printk("  FRate: 24 fps");
-                vi->framerate = 24000;
+		vi->framerate = 24000;
 		form = -1;
 		break;
 	case 3:
 		if (pr)
 			printk("  FRate: 25 fps");
-                vi->framerate = 25000;
+		vi->framerate = 25000;
 		form = VIDEO_MODE_PAL;
 		break;
 	case 4:
 		if (pr)
 			printk("  FRate: 29.97 fps");
-                vi->framerate = 29970;
+		vi->framerate = 29970;
 		form = VIDEO_MODE_NTSC;
 		break;
 	case 5:
 		if (pr)
 			printk("  FRate: 30 fps");
-                vi->framerate = 30000;
+		vi->framerate = 30000;
 		form = VIDEO_MODE_NTSC;
 		break;
 	case 6:
 		if (pr)
 			printk("  FRate: 50 fps");
-                vi->framerate = 50000;
+		vi->framerate = 50000;
 		form = VIDEO_MODE_PAL;
 		break;
 	case 7:
 		if (pr)
 			printk("  FRate: 60 fps");
-                vi->framerate = 60000;
+		vi->framerate = 60000;
 		form = VIDEO_MODE_NTSC;
 		break;
 	}
 
 	vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03);
 
-        vi->vbv_buffer_size
-                = (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5);
+	vi->vbv_buffer_size
+		= (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5);
 
 	if (pr){
 		printk("  BRate: %d Mbit/s",4*(vi->bit_rate)/10000);
@@ -250,7 +250,7 @@
 		printk("\n");
 	}
 
-        vi->video_format = form;
+	vi->video_format = form;
 
 	return 0;
 }
@@ -308,7 +308,7 @@
 	if (!found) return -1;
 
 	if (c+3 >= count) return -1;
-        headr = mbuf+c;
+	headr = mbuf+c;
 
 	ai->layer = (headr[1] & 0x06) >> 1;
 
@@ -368,7 +368,7 @@
 	if (c+5 >= count) return -1;
 
 	ai->layer = 0;  // 0 for AC3
-        headr = mbuf+c+2;
+	headr = mbuf+c+2;
 
 	frame = (headr[2]&0x3f);
 	ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
@@ -396,159 +396,159 @@
 #if 0
 static u8 *skip_pes_header(u8 **bufp)
 {
-        u8 *inbuf = *bufp;
-        u8 *buf = inbuf;
-        u8 *pts = NULL;
-        int skip = 0;
+	u8 *inbuf = *bufp;
+	u8 *buf = inbuf;
+	u8 *pts = NULL;
+	int skip = 0;
 
 	static const int mpeg1_skip_table[16] = {
 		1, 0xffff,      5,     10, 0xffff, 0xffff, 0xffff, 0xffff,
-	        0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
 	};
 
 
-        if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
-                if (buf[7] & PTS_ONLY)
-                        pts = buf+9;
-                else pts = NULL;
-                buf = inbuf + 9 + inbuf[8];
-        } else {        /* mpeg1 */
-                for (buf = inbuf + 6; *buf == 0xff; buf++)
-                        if (buf == inbuf + 6 + 16) {
-                                break;
-                        }
-                if ((*buf & 0xc0) == 0x40)
-                        buf += 2;
-                skip = mpeg1_skip_table [*buf >> 4];
-                if (skip == 5 || skip == 10) pts = buf;
-                else pts = NULL;
+	if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
+		if (buf[7] & PTS_ONLY)
+		        pts = buf+9;
+		else pts = NULL;
+		buf = inbuf + 9 + inbuf[8];
+	} else {        /* mpeg1 */
+		for (buf = inbuf + 6; *buf == 0xff; buf++)
+		        if (buf == inbuf + 6 + 16) {
+		                break;
+		        }
+		if ((*buf & 0xc0) == 0x40)
+		        buf += 2;
+		skip = mpeg1_skip_table [*buf >> 4];
+		if (skip == 5 || skip == 10) pts = buf;
+		else pts = NULL;
 
-                buf += mpeg1_skip_table [*buf >> 4];
-        }
+		buf += mpeg1_skip_table [*buf >> 4];
+	}
 
-        *bufp = buf;
-        return pts;
+	*bufp = buf;
+	return pts;
 }
 #endif
 
 #if 0
 static void initialize_quant_matrix( u32 *matrix )
 {
-        int i;
+	int i;
 
-        matrix[0]  = 0x08101013;
-        matrix[1]  = 0x10131616;
-        matrix[2]  = 0x16161616;
-        matrix[3]  = 0x1a181a1b;
-        matrix[4]  = 0x1b1b1a1a;
-        matrix[5]  = 0x1a1a1b1b;
-        matrix[6]  = 0x1b1d1d1d;
-        matrix[7]  = 0x2222221d;
-        matrix[8]  = 0x1d1d1b1b;
-        matrix[9]  = 0x1d1d2020;
-        matrix[10] = 0x22222526;
-        matrix[11] = 0x25232322;
-        matrix[12] = 0x23262628;
-        matrix[13] = 0x28283030;
-        matrix[14] = 0x2e2e3838;
-        matrix[15] = 0x3a454553;
+	matrix[0]  = 0x08101013;
+	matrix[1]  = 0x10131616;
+	matrix[2]  = 0x16161616;
+	matrix[3]  = 0x1a181a1b;
+	matrix[4]  = 0x1b1b1a1a;
+	matrix[5]  = 0x1a1a1b1b;
+	matrix[6]  = 0x1b1d1d1d;
+	matrix[7]  = 0x2222221d;
+	matrix[8]  = 0x1d1d1b1b;
+	matrix[9]  = 0x1d1d2020;
+	matrix[10] = 0x22222526;
+	matrix[11] = 0x25232322;
+	matrix[12] = 0x23262628;
+	matrix[13] = 0x28283030;
+	matrix[14] = 0x2e2e3838;
+	matrix[15] = 0x3a454553;
 
-        for ( i = 16 ; i < 32 ; i++ )
-                matrix[i] = 0x10101010;
+	for ( i = 16 ; i < 32 ; i++ )
+		matrix[i] = 0x10101010;
 }
 #endif
 
 #if 0
 static void initialize_mpg_picture(struct mpg_picture *pic)
 {
-        int i;
+	int i;
 
-        /* set MPEG1 */
-        pic->mpeg1_flag = 1;
-        pic->profile_and_level = 0x4A ;        /* MP@LL */
-        pic->progressive_sequence = 1;
-        pic->low_delay = 0;
+	/* set MPEG1 */
+	pic->mpeg1_flag = 1;
+	pic->profile_and_level = 0x4A ;        /* MP@LL */
+	pic->progressive_sequence = 1;
+	pic->low_delay = 0;
 
-        pic->sequence_display_extension_flag = 0;
-        for ( i = 0 ; i < 4 ; i++ ){
-                pic->frame_centre_horizontal_offset[i] = 0;
-                pic->frame_centre_vertical_offset[i] = 0;
-        }
-        pic->last_frame_centre_horizontal_offset = 0;
-        pic->last_frame_centre_vertical_offset = 0;
+	pic->sequence_display_extension_flag = 0;
+	for ( i = 0 ; i < 4 ; i++ ){
+		pic->frame_centre_horizontal_offset[i] = 0;
+		pic->frame_centre_vertical_offset[i] = 0;
+	}
+	pic->last_frame_centre_horizontal_offset = 0;
+	pic->last_frame_centre_vertical_offset = 0;
 
-        pic->picture_display_extension_flag[0] = 0;
-        pic->picture_display_extension_flag[1] = 0;
-        pic->sequence_header_flag = 0;
+	pic->picture_display_extension_flag[0] = 0;
+	pic->picture_display_extension_flag[1] = 0;
+	pic->sequence_header_flag = 0;
 	pic->gop_flag = 0;
-        pic->sequence_end_flag = 0;
+	pic->sequence_end_flag = 0;
 }
 #endif
 
 #if 0
 static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic )
 {
-        int16_t last_h_offset;
-        int16_t last_v_offset;
+	int16_t last_h_offset;
+	int16_t last_v_offset;
 
-        int16_t *p_h_offset;
-        int16_t *p_v_offset;
+	int16_t *p_h_offset;
+	int16_t *p_v_offset;
 
-        if ( pic->mpeg1_flag ){
-                pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE;
-                pic->top_field_first = 0;
-                pic->repeat_first_field = 0;
-                pic->progressive_frame = 1;
-                pic->picture_coding_parameter = 0x000010;
-        }
+	if ( pic->mpeg1_flag ){
+		pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE;
+		pic->top_field_first = 0;
+		pic->repeat_first_field = 0;
+		pic->progressive_frame = 1;
+		pic->picture_coding_parameter = 0x000010;
+	}
 
-        /* Reset flag */
-        pic->picture_display_extension_flag[field_type] = 0;
+	/* Reset flag */
+	pic->picture_display_extension_flag[field_type] = 0;
 
-        last_h_offset = pic->last_frame_centre_horizontal_offset;
-        last_v_offset = pic->last_frame_centre_vertical_offset;
-        if ( field_type == FIRST_FIELD ){
-                p_h_offset = pic->frame_centre_horizontal_offset;
-                p_v_offset = pic->frame_centre_vertical_offset;
-                *p_h_offset = last_h_offset;
-                *(p_h_offset + 1) = last_h_offset;
-                *(p_h_offset + 2) = last_h_offset;
-                *p_v_offset = last_v_offset;
-                *(p_v_offset + 1) = last_v_offset;
-                *(p_v_offset + 2) = last_v_offset;
-        } else {
-                pic->frame_centre_horizontal_offset[3] = last_h_offset;
-                pic->frame_centre_vertical_offset[3] = last_v_offset;
-        }
+	last_h_offset = pic->last_frame_centre_horizontal_offset;
+	last_v_offset = pic->last_frame_centre_vertical_offset;
+	if ( field_type == FIRST_FIELD ){
+		p_h_offset = pic->frame_centre_horizontal_offset;
+		p_v_offset = pic->frame_centre_vertical_offset;
+		*p_h_offset = last_h_offset;
+		*(p_h_offset + 1) = last_h_offset;
+		*(p_h_offset + 2) = last_h_offset;
+		*p_v_offset = last_v_offset;
+		*(p_v_offset + 1) = last_v_offset;
+		*(p_v_offset + 2) = last_v_offset;
+	} else {
+		pic->frame_centre_horizontal_offset[3] = last_h_offset;
+		pic->frame_centre_vertical_offset[3] = last_v_offset;
+	}
 }
 #endif
 
 #if 0
 static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type)
 {
-        pic->picture_header = 0;
-        pic->sequence_header_data
-                = ( INIT_HORIZONTAL_SIZE << 20 )
-                        | ( INIT_VERTICAL_SIZE << 8 )
-                        | ( INIT_ASPECT_RATIO << 4 )
-                        | ( INIT_FRAME_RATE );
-        pic->mpeg1_flag = 0;
-        pic->vinfo.horizontal_size
-                = INIT_DISP_HORIZONTAL_SIZE;
-        pic->vinfo.vertical_size
-                = INIT_DISP_VERTICAL_SIZE;
-        pic->picture_display_extension_flag[field_type]
-                = 0;
-        pic->pts_flag[field_type] = 0;
+	pic->picture_header = 0;
+	pic->sequence_header_data
+		= ( INIT_HORIZONTAL_SIZE << 20 )
+		        | ( INIT_VERTICAL_SIZE << 8 )
+		        | ( INIT_ASPECT_RATIO << 4 )
+		        | ( INIT_FRAME_RATE );
+	pic->mpeg1_flag = 0;
+	pic->vinfo.horizontal_size
+		= INIT_DISP_HORIZONTAL_SIZE;
+	pic->vinfo.vertical_size
+		= INIT_DISP_VERTICAL_SIZE;
+	pic->picture_display_extension_flag[field_type]
+		= 0;
+	pic->pts_flag[field_type] = 0;
 
-        pic->sequence_gop_header = 0;
-        pic->picture_header = 0;
-        pic->sequence_header_flag = 0;
-        pic->gop_flag = 0;
-        pic->sequence_end_flag = 0;
-        pic->sequence_display_extension_flag = 0;
-        pic->last_frame_centre_horizontal_offset = 0;
-        pic->last_frame_centre_vertical_offset = 0;
+	pic->sequence_gop_header = 0;
+	pic->picture_header = 0;
+	pic->sequence_header_flag = 0;
+	pic->gop_flag = 0;
+	pic->sequence_end_flag = 0;
+	pic->sequence_display_extension_flag = 0;
+	pic->last_frame_centre_horizontal_offset = 0;
+	pic->last_frame_centre_vertical_offset = 0;
 	pic->channel = chan;
 }
 #endif
@@ -588,11 +588,11 @@
 		buf[1]&=~0x40;
 	}
 	if (!len)
-	        return 0;
+		return 0;
 	buf[3]=0x30|((p2ts->cc++)&0x0f);
 	rest=183-len;
 	if (rest) {
-	        buf[5]=0x00;
+		buf[5]=0x00;
 		if (rest-1)
 			memset(buf+6, 0xff, rest-1);
 	}
diff --git a/drivers/media/dvb/dvb-core/dvb_filter.h b/drivers/media/dvb/dvb-core/dvb_filter.h
index b0848f7..375e3be 100644
--- a/drivers/media/dvb/dvb-core/dvb_filter.h
+++ b/drivers/media/dvb/dvb-core/dvb_filter.h
@@ -29,8 +29,8 @@
 
 struct dvb_filter_pes2ts {
 	unsigned char buf[188];
-        unsigned char cc;
-        dvb_filter_pes2ts_cb_t *cb;
+	unsigned char cc;
+	dvb_filter_pes2ts_cb_t *cb;
 	void *priv;
 };
 
@@ -162,7 +162,7 @@
 	u32 bit_rate;
 	u32 comp_bit_rate;
 	u32 vbv_buffer_size;
-        s16 vbv_delay;
+	s16 vbv_delay;
 	u32 CSPF;
 	u32 off;
 };
@@ -173,60 +173,60 @@
 #define VIDEO_FRAME_PICTURE 0x03
 
 struct mpg_picture {
-        int       channel;
+	int       channel;
 	struct dvb_video_info vinfo;
-        u32      *sequence_gop_header;
-        u32      *picture_header;
-        s32       time_code;
-        int       low_delay;
-        int       closed_gop;
-        int       broken_link;
-        int       sequence_header_flag;
-        int       gop_flag;
-        int       sequence_end_flag;
+	u32      *sequence_gop_header;
+	u32      *picture_header;
+	s32       time_code;
+	int       low_delay;
+	int       closed_gop;
+	int       broken_link;
+	int       sequence_header_flag;
+	int       gop_flag;
+	int       sequence_end_flag;
 
-        u8        profile_and_level;
-        s32       picture_coding_parameter;
-        u32       matrix[32];
-        s8        matrix_change_flag;
+	u8        profile_and_level;
+	s32       picture_coding_parameter;
+	u32       matrix[32];
+	s8        matrix_change_flag;
 
-        u8        picture_header_parameter;
+	u8        picture_header_parameter;
   /* bit 0 - 2: bwd f code
      bit 3    : fpb vector
      bit 4 - 6: fwd f code
      bit 7    : fpf vector */
 
-        int       mpeg1_flag;
-        int       progressive_sequence;
-        int       sequence_display_extension_flag;
-        u32       sequence_header_data;
-        s16       last_frame_centre_horizontal_offset;
-        s16       last_frame_centre_vertical_offset;
+	int       mpeg1_flag;
+	int       progressive_sequence;
+	int       sequence_display_extension_flag;
+	u32       sequence_header_data;
+	s16       last_frame_centre_horizontal_offset;
+	s16       last_frame_centre_vertical_offset;
 
-        u32       pts[2]; /* [0] 1st field, [1] 2nd field */
-        int       top_field_first;
-        int       repeat_first_field;
-        int       progressive_frame;
-        int       bank;
-        int       forward_bank;
-        int       backward_bank;
-        int       compress;
-        s16       frame_centre_horizontal_offset[OFF_SIZE];
-                  /* [0-2] 1st field, [3] 2nd field */
-        s16       frame_centre_vertical_offset[OFF_SIZE];
-                  /* [0-2] 1st field, [3] 2nd field */
-        s16       temporal_reference[2];
-                  /* [0] 1st field, [1] 2nd field */
+	u32       pts[2]; /* [0] 1st field, [1] 2nd field */
+	int       top_field_first;
+	int       repeat_first_field;
+	int       progressive_frame;
+	int       bank;
+	int       forward_bank;
+	int       backward_bank;
+	int       compress;
+	s16       frame_centre_horizontal_offset[OFF_SIZE];
+		  /* [0-2] 1st field, [3] 2nd field */
+	s16       frame_centre_vertical_offset[OFF_SIZE];
+		  /* [0-2] 1st field, [3] 2nd field */
+	s16       temporal_reference[2];
+		  /* [0] 1st field, [1] 2nd field */
 
-        s8        picture_coding_type[2];
-                  /* [0] 1st field, [1] 2nd field */
-        s8        picture_structure[2];
-                  /* [0] 1st field, [1] 2nd field */
-        s8        picture_display_extension_flag[2];
-                  /* [0] 1st field, [1] 2nd field */
-                  /* picture_display_extenion() 0:no 1:exit*/
-        s8        pts_flag[2];
-                  /* [0] 1st field, [1] 2nd field */
+	s8        picture_coding_type[2];
+		  /* [0] 1st field, [1] 2nd field */
+	s8        picture_structure[2];
+		  /* [0] 1st field, [1] 2nd field */
+	s8        picture_display_extension_flag[2];
+		  /* [0] 1st field, [1] 2nd field */
+		  /* picture_display_extenion() 0:no 1:exit*/
+	s8        pts_flag[2];
+		  /* [0] 1st field, [1] 2nd field */
 };
 
 struct dvb_audio_info {
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 6ffa6b2..95ea509 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -372,10 +372,10 @@
 
 	snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num);
 
-        lock_kernel();
-        daemonize(name);
-        sigfillset(&current->blocked);
-        unlock_kernel();
+	lock_kernel();
+	daemonize(name);
+	sigfillset(&current->blocked);
+	unlock_kernel();
 
 	fepriv->status = 0;
 	dvb_frontend_init(fe);
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 348c9b0..1e0840d 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -41,10 +41,10 @@
 #include "dvbdev.h"
 
 struct dvb_frontend_tune_settings {
-        int min_delay_ms;
-        int step_size;
-        int max_drift;
-        struct dvb_frontend_parameters parameters;
+	int min_delay_ms;
+	int step_size;
+	int max_drift;
+	struct dvb_frontend_parameters parameters;
 };
 
 struct dvb_frontend;
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 8793549..86bba81 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -151,6 +151,8 @@
 	unsigned char ule_bridged;		/* Whether the ULE_BRIDGED extension header was found. */
 	int ule_sndu_remain;			/* Nr. of bytes still required for current ULE SNDU. */
 	unsigned long ts_count;			/* Current ts cell counter. */
+
+	struct semaphore mutex;
 };
 
 
@@ -711,7 +713,7 @@
 	if (buffer1_len > 32768)
 		printk(KERN_WARNING "length > 32k: %zu.\n", buffer1_len);
 	/* printk("TS callback: %u bytes, %u TS cells @ %p.\n",
-	          buffer1_len, buffer1_len / TS_SZ, buffer1); */
+		  buffer1_len, buffer1_len / TS_SZ, buffer1); */
 	dvb_net_ule(dev, buffer1, buffer1_len);
 	return 0;
 }
@@ -719,8 +721,8 @@
 
 static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
 {
-        u8 *eth;
-        struct sk_buff *skb;
+	u8 *eth;
+	struct sk_buff *skb;
 	struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats);
 	int snap = 0;
 
@@ -752,7 +754,7 @@
 			return;
 		}
 		snap = 8;
-        }
+	}
 	if (pkt[7]) {
 		/* FIXME: assemble datagram from multiple sections */
 		stats->rx_errors++;
@@ -776,14 +778,14 @@
 	memcpy(eth + 14, pkt + 12 + snap, pkt_len - 12 - 4 - snap);
 
 	/* create ethernet header: */
-        eth[0]=pkt[0x0b];
-        eth[1]=pkt[0x0a];
-        eth[2]=pkt[0x09];
-        eth[3]=pkt[0x08];
-        eth[4]=pkt[0x04];
-        eth[5]=pkt[0x03];
+	eth[0]=pkt[0x0b];
+	eth[1]=pkt[0x0a];
+	eth[2]=pkt[0x09];
+	eth[3]=pkt[0x08];
+	eth[4]=pkt[0x04];
+	eth[5]=pkt[0x03];
 
-        eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;
+	eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;
 
 	if (snap) {
 		eth[12] = pkt[18];
@@ -805,7 +807,7 @@
 
 	stats->rx_packets++;
 	stats->rx_bytes+=skb->len;
-        netif_rx(skb);
+	netif_rx(skb);
 }
 
 static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len,
@@ -813,7 +815,7 @@
 		 struct dmx_section_filter *filter,
 		 enum dmx_success success)
 {
-        struct net_device *dev = filter->priv;
+	struct net_device *dev = filter->priv;
 
 	/**
 	 * we rely on the DVB API definition where exactly one complete
@@ -881,12 +883,13 @@
 
 static int dvb_net_feed_start(struct net_device *dev)
 {
-	int ret, i;
+	int ret = 0, i;
 	struct dvb_net_priv *priv = dev->priv;
-        struct dmx_demux *demux = priv->demux;
-        unsigned char *mac = (unsigned char *) dev->dev_addr;
+	struct dmx_demux *demux = priv->demux;
+	unsigned char *mac = (unsigned char *) dev->dev_addr;
 
 	dprintk("%s: rx_mode %i\n", __FUNCTION__, priv->rx_mode);
+	down(&priv->mutex);
 	if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0])
 		printk("%s: BUG %d\n", __FUNCTION__, __LINE__);
 
@@ -900,7 +903,7 @@
 					 dvb_net_sec_callback);
 		if (ret<0) {
 			printk("%s: could not allocate section feed\n", dev->name);
-			return ret;
+			goto error;
 		}
 
 		ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 1);
@@ -909,7 +912,7 @@
 			printk("%s: could not set section feed\n", dev->name);
 			priv->demux->release_section_feed(priv->demux, priv->secfeed);
 			priv->secfeed=NULL;
-			return ret;
+			goto error;
 		}
 
 		if (priv->rx_mode != RX_MODE_PROMISC) {
@@ -948,7 +951,7 @@
 		ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback);
 		if (ret < 0) {
 			printk("%s: could not allocate ts feed\n", dev->name);
-			return ret;
+			goto error;
 		}
 
 		/* Set netdevice pointer for ts decaps callback. */
@@ -962,23 +965,26 @@
 			printk("%s: could not set ts feed\n", dev->name);
 			priv->demux->release_ts_feed(priv->demux, priv->tsfeed);
 			priv->tsfeed = NULL;
-			return ret;
+			goto error;
 		}
 
 		dprintk("%s: start filtering\n", __FUNCTION__);
 		priv->tsfeed->start_filtering(priv->tsfeed);
 	} else
-		return -EINVAL;
+		ret = -EINVAL;
 
-	return 0;
+error:
+	up(&priv->mutex);
+	return ret;
 }
 
 static int dvb_net_feed_stop(struct net_device *dev)
 {
 	struct dvb_net_priv *priv = dev->priv;
-	int i;
+	int i, ret = 0;
 
 	dprintk("%s\n", __FUNCTION__);
+	down(&priv->mutex);
 	if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) {
 		if (priv->secfeed) {
 			if (priv->secfeed->is_filtering) {
@@ -1019,8 +1025,9 @@
 		else
 			printk("%s: no ts feed to stop\n", dev->name);
 	} else
-		return -EINVAL;
-	return 0;
+		ret = -EINVAL;
+	up(&priv->mutex);
+	return ret;
 }
 
 
@@ -1044,8 +1051,8 @@
 	struct dvb_net_priv *priv = dev->priv;
 
 	dvb_net_feed_stop(dev);
-
 	priv->rx_mode = RX_MODE_UNI;
+	spin_lock_bh(&dev->xmit_lock);
 
 	if (dev->flags & IFF_PROMISC) {
 		dprintk("%s: promiscuous mode\n", dev->name);
@@ -1070,6 +1077,7 @@
 		}
 	}
 
+	spin_unlock_bh(&dev->xmit_lock);
 	dvb_net_feed_start(dev);
 }
 
@@ -1121,12 +1129,12 @@
 	struct dvb_net_priv *priv = dev->priv;
 
 	priv->in_use--;
-        return dvb_net_feed_stop(dev);
+	return dvb_net_feed_stop(dev);
 }
 
 static struct net_device_stats * dvb_net_get_stats(struct net_device *dev)
 {
-        return &((struct dvb_net_priv*) dev->priv)->stats;
+	return &((struct dvb_net_priv*) dev->priv)->stats;
 }
 
 static void dvb_net_setup(struct net_device *dev)
@@ -1200,6 +1208,7 @@
 
 	INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
 	INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
+	init_MUTEX(&priv->mutex);
 
 	net->base_addr = pid;
 
@@ -1351,10 +1360,10 @@
 };
 
 static struct dvb_device dvbdev_net = {
-        .priv = NULL,
-        .users = 1,
-        .writers = 1,
-        .fops = &dvb_net_fops,
+	.priv = NULL,
+	.users = 1,
+	.writers = 1,
+	.fops = &dvb_net_fops,
 };
 
 
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index fb6d94a..283c6e9 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -42,216 +42,216 @@
 
 void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
 {
-        rbuf->pread=rbuf->pwrite=0;
-        rbuf->data=data;
-        rbuf->size=len;
+	rbuf->pread=rbuf->pwrite=0;
+	rbuf->data=data;
+	rbuf->size=len;
 
-        init_waitqueue_head(&rbuf->queue);
+	init_waitqueue_head(&rbuf->queue);
 
-        spin_lock_init(&(rbuf->lock));
+	spin_lock_init(&(rbuf->lock));
 }
 
 
 
 int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
 {
-        return (rbuf->pread==rbuf->pwrite);
+	return (rbuf->pread==rbuf->pwrite);
 }
 
 
 
 ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
 {
-        ssize_t free;
+	ssize_t free;
 
-        free = rbuf->pread - rbuf->pwrite;
-        if (free <= 0)
-                free += rbuf->size;
-        return free-1;
+	free = rbuf->pread - rbuf->pwrite;
+	if (free <= 0)
+		free += rbuf->size;
+	return free-1;
 }
 
 
 
 ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf)
 {
-        ssize_t avail;
+	ssize_t avail;
 
-        avail = rbuf->pwrite - rbuf->pread;
-        if (avail < 0)
-                avail += rbuf->size;
-        return avail;
+	avail = rbuf->pwrite - rbuf->pread;
+	if (avail < 0)
+		avail += rbuf->size;
+	return avail;
 }
 
 
 
 void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
 {
-        rbuf->pread = rbuf->pwrite;
+	rbuf->pread = rbuf->pwrite;
 }
 
 
 
 void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
 {
-        unsigned long flags;
+	unsigned long flags;
 
-        spin_lock_irqsave(&rbuf->lock, flags);
-        dvb_ringbuffer_flush(rbuf);
-        spin_unlock_irqrestore(&rbuf->lock, flags);
+	spin_lock_irqsave(&rbuf->lock, flags);
+	dvb_ringbuffer_flush(rbuf);
+	spin_unlock_irqrestore(&rbuf->lock, flags);
 
-        wake_up(&rbuf->queue);
+	wake_up(&rbuf->queue);
 }
 
 
 
 ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem)
 {
-        size_t todo = len;
-        size_t split;
+	size_t todo = len;
+	size_t split;
 
-        split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
-        if (split > 0) {
-                if (!usermem)
-                        memcpy(buf, rbuf->data+rbuf->pread, split);
-                else
-                        if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
-                                return -EFAULT;
-                buf += split;
-                todo -= split;
-                rbuf->pread = 0;
-        }
-        if (!usermem)
-                memcpy(buf, rbuf->data+rbuf->pread, todo);
-        else
-                if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
-                        return -EFAULT;
+	split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
+	if (split > 0) {
+		if (!usermem)
+		        memcpy(buf, rbuf->data+rbuf->pread, split);
+		else
+		        if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
+		                return -EFAULT;
+		buf += split;
+		todo -= split;
+		rbuf->pread = 0;
+	}
+	if (!usermem)
+		memcpy(buf, rbuf->data+rbuf->pread, todo);
+	else
+		if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
+		        return -EFAULT;
 
-        rbuf->pread = (rbuf->pread + todo) % rbuf->size;
+	rbuf->pread = (rbuf->pread + todo) % rbuf->size;
 
-        return len;
+	return len;
 }
 
 
 
 ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len)
 {
-        size_t todo = len;
-        size_t split;
+	size_t todo = len;
+	size_t split;
 
-        split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
+	split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
 
-        if (split > 0) {
-                memcpy(rbuf->data+rbuf->pwrite, buf, split);
-                buf += split;
-                todo -= split;
-                rbuf->pwrite = 0;
-        }
-        memcpy(rbuf->data+rbuf->pwrite, buf, todo);
-        rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
+	if (split > 0) {
+		memcpy(rbuf->data+rbuf->pwrite, buf, split);
+		buf += split;
+		todo -= split;
+		rbuf->pwrite = 0;
+	}
+	memcpy(rbuf->data+rbuf->pwrite, buf, todo);
+	rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
 
-        return len;
+	return len;
 }
 
 ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
 {
-        int status;
-        ssize_t oldpwrite = rbuf->pwrite;
+	int status;
+	ssize_t oldpwrite = rbuf->pwrite;
 
-        DVB_RINGBUFFER_WRITE_BYTE(rbuf, len >> 8);
-        DVB_RINGBUFFER_WRITE_BYTE(rbuf, len & 0xff);
-        DVB_RINGBUFFER_WRITE_BYTE(rbuf, PKT_READY);
-        status = dvb_ringbuffer_write(rbuf, buf, len);
+	DVB_RINGBUFFER_WRITE_BYTE(rbuf, len >> 8);
+	DVB_RINGBUFFER_WRITE_BYTE(rbuf, len & 0xff);
+	DVB_RINGBUFFER_WRITE_BYTE(rbuf, PKT_READY);
+	status = dvb_ringbuffer_write(rbuf, buf, len);
 
-        if (status < 0) rbuf->pwrite = oldpwrite;
-        return status;
+	if (status < 0) rbuf->pwrite = oldpwrite;
+	return status;
 }
 
 ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
-                                int offset, u8* buf, size_t len, int usermem)
+		                int offset, u8* buf, size_t len, int usermem)
 {
-        size_t todo;
-        size_t split;
-        size_t pktlen;
+	size_t todo;
+	size_t split;
+	size_t pktlen;
 
-        pktlen = rbuf->data[idx] << 8;
-        pktlen |= rbuf->data[(idx + 1) % rbuf->size];
-        if (offset > pktlen) return -EINVAL;
-        if ((offset + len) > pktlen) len = pktlen - offset;
+	pktlen = rbuf->data[idx] << 8;
+	pktlen |= rbuf->data[(idx + 1) % rbuf->size];
+	if (offset > pktlen) return -EINVAL;
+	if ((offset + len) > pktlen) len = pktlen - offset;
 
-        idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
-        todo = len;
-        split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
-        if (split > 0) {
-                if (!usermem)
-                        memcpy(buf, rbuf->data+idx, split);
-                else
-                        if (copy_to_user(buf, rbuf->data+idx, split))
-                                return -EFAULT;
-                buf += split;
-                todo -= split;
-                idx = 0;
-        }
-        if (!usermem)
-                memcpy(buf, rbuf->data+idx, todo);
-        else
-                if (copy_to_user(buf, rbuf->data+idx, todo))
-                        return -EFAULT;
+	idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
+	todo = len;
+	split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
+	if (split > 0) {
+		if (!usermem)
+		        memcpy(buf, rbuf->data+idx, split);
+		else
+		        if (copy_to_user(buf, rbuf->data+idx, split))
+		                return -EFAULT;
+		buf += split;
+		todo -= split;
+		idx = 0;
+	}
+	if (!usermem)
+		memcpy(buf, rbuf->data+idx, todo);
+	else
+		if (copy_to_user(buf, rbuf->data+idx, todo))
+		        return -EFAULT;
 
-        return len;
+	return len;
 }
 
 void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
 {
-        size_t pktlen;
+	size_t pktlen;
 
-        rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED;
+	rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED;
 
-        // clean up disposed packets
-        while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
-                if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
-                        pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
-                        pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
-                        DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
-                } else {
-                        // first packet is not disposed, so we stop cleaning now
-                        break;
-                }
-        }
+	// clean up disposed packets
+	while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
+		if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
+		        pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
+		        pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
+		        DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
+		} else {
+		        // first packet is not disposed, so we stop cleaning now
+		        break;
+		}
+	}
 }
 
 ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen)
 {
-        int consumed;
-        int curpktlen;
-        int curpktstatus;
+	int consumed;
+	int curpktlen;
+	int curpktstatus;
 
-        if (idx == -1) {
+	if (idx == -1) {
 	       idx = rbuf->pread;
 	} else {
-                curpktlen = rbuf->data[idx] << 8;
-                curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
-	        idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
+		curpktlen = rbuf->data[idx] << 8;
+		curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
+		idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
 	}
 
-        consumed = (idx - rbuf->pread) % rbuf->size;
+	consumed = (idx - rbuf->pread) % rbuf->size;
 
-        while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
+	while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
 
-                curpktlen = rbuf->data[idx] << 8;
-                curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
-                curpktstatus = rbuf->data[(idx + 2) % rbuf->size];
+		curpktlen = rbuf->data[idx] << 8;
+		curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
+		curpktstatus = rbuf->data[(idx + 2) % rbuf->size];
 
-                if (curpktstatus == PKT_READY) {
-                        *pktlen = curpktlen;
-                        return idx;
-                }
+		if (curpktstatus == PKT_READY) {
+		        *pktlen = curpktlen;
+		        return idx;
+		}
 
-                consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE;
-                idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
-        }
+		consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE;
+		idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
+	}
 
-        // no packets available
-        return -1;
+	// no packets available
+	return -1;
 }
 
 
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
index d18e9c4..fa476f6 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -31,13 +31,13 @@
 #include <linux/wait.h>
 
 struct dvb_ringbuffer {
-        u8               *data;
-        ssize_t           size;
-        ssize_t           pread;
-        ssize_t           pwrite;
+	u8               *data;
+	ssize_t           size;
+	ssize_t           pread;
+	ssize_t           pwrite;
 
-        wait_queue_head_t queue;
-        spinlock_t        lock;
+	wait_queue_head_t queue;
+	spinlock_t        lock;
 };
 
 #define DVB_RINGBUFFER_PKTHDRSIZE 3
@@ -106,7 +106,7 @@
 ** returns number of bytes transferred or -EFAULT
 */
 extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf,
-                                   size_t len, int usermem);
+		                   size_t len, int usermem);
 
 
 /* write routines & macros */
@@ -121,7 +121,7 @@
 ** returns number of bytes transferred or -EFAULT
 */
 extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
-                                    size_t len);
+		                    size_t len);
 
 
 /**
@@ -133,7 +133,7 @@
  * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
  */
 extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
-                                        size_t len);
+		                        size_t len);
 
 /**
  * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this
@@ -149,7 +149,7 @@
  * returns Number of bytes read, or -EFAULT.
  */
 extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
-                                       int offset, u8* buf, size_t len, int usermem);
+		                       int offset, u8* buf, size_t len, int usermem);
 
 /**
  * Dispose of a packet in the ring buffer.
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 477b4fa..a4aee86 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -47,7 +47,7 @@
 static DECLARE_MUTEX(dvbdev_register_lock);
 
 static const char * const dnames[] = {
-        "video", "audio", "sec", "frontend", "demux", "dvr", "ca",
+	"video", "audio", "sec", "frontend", "demux", "dvr", "ca",
 	"net", "osd"
 };
 
@@ -90,15 +90,15 @@
 
 		file->private_data = dvbdev;
 		old_fops = file->f_op;
-                file->f_op = fops_get(dvbdev->fops);
-                if(file->f_op->open)
-                        err = file->f_op->open(inode,file);
-                if (err) {
-                        fops_put(file->f_op);
-                        file->f_op = fops_get(old_fops);
-                }
-                fops_put(old_fops);
-                return err;
+		file->f_op = fops_get(dvbdev->fops);
+		if(file->f_op->open)
+		        err = file->f_op->open(inode,file);
+		if (err) {
+		        fops_put(file->f_op);
+		        file->f_op = fops_get(old_fops);
+		}
+		fops_put(old_fops);
+		return err;
 	}
 	return -ENODEV;
 }
@@ -117,21 +117,21 @@
 
 int dvb_generic_open(struct inode *inode, struct file *file)
 {
-        struct dvb_device *dvbdev = file->private_data;
+	struct dvb_device *dvbdev = file->private_data;
 
-        if (!dvbdev)
-                return -ENODEV;
+	if (!dvbdev)
+		return -ENODEV;
 
 	if (!dvbdev->users)
-                return -EBUSY;
+		return -EBUSY;
 
 	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
-                if (!dvbdev->readers)
-		        return -EBUSY;
+		if (!dvbdev->readers)
+			return -EBUSY;
 		dvbdev->readers--;
 	} else {
-                if (!dvbdev->writers)
-		        return -EBUSY;
+		if (!dvbdev->writers)
+			return -EBUSY;
 		dvbdev->writers--;
 	}
 
@@ -143,10 +143,10 @@
 
 int dvb_generic_release(struct inode *inode, struct file *file)
 {
-        struct dvb_device *dvbdev = file->private_data;
+	struct dvb_device *dvbdev = file->private_data;
 
 	if (!dvbdev)
-                return -ENODEV;
+		return -ENODEV;
 
 	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
 		dvbdev->readers++;
@@ -163,10 +163,10 @@
 int dvb_generic_ioctl(struct inode *inode, struct file *file,
 		      unsigned int cmd, unsigned long arg)
 {
-        struct dvb_device *dvbdev = file->private_data;
+	struct dvb_device *dvbdev = file->private_data;
 
-        if (!dvbdev)
-	        return -ENODEV;
+	if (!dvbdev)
+		return -ENODEV;
 
 	if (!dvbdev->kernel_ioctl)
 		return -EINVAL;
@@ -334,63 +334,63 @@
    to the v4l "videodev.o" module, which is unnecessary for some
    cards (ie. the budget dvb-cards don't need the v4l module...) */
 int dvb_usercopy(struct inode *inode, struct file *file,
-	             unsigned int cmd, unsigned long arg,
+		     unsigned int cmd, unsigned long arg,
 		     int (*func)(struct inode *inode, struct file *file,
 		     unsigned int cmd, void *arg))
 {
-        char    sbuf[128];
-        void    *mbuf = NULL;
-        void    *parg = NULL;
-        int     err  = -EINVAL;
+	char    sbuf[128];
+	void    *mbuf = NULL;
+	void    *parg = NULL;
+	int     err  = -EINVAL;
 
-        /*  Copy arguments into temp kernel buffer  */
-        switch (_IOC_DIR(cmd)) {
-        case _IOC_NONE:
+	/*  Copy arguments into temp kernel buffer  */
+	switch (_IOC_DIR(cmd)) {
+	case _IOC_NONE:
 		/*
 		 * For this command, the pointer is actually an integer
 		 * argument.
 		 */
 		parg = (void *) arg;
 		break;
-        case _IOC_READ: /* some v4l ioctls are marked wrong ... */
-        case _IOC_WRITE:
-        case (_IOC_WRITE | _IOC_READ):
-                if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
-                        parg = sbuf;
-                } else {
-                        /* too big to allocate from stack */
-                        mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
-                        if (NULL == mbuf)
-                                return -ENOMEM;
-                        parg = mbuf;
-                }
+	case _IOC_READ: /* some v4l ioctls are marked wrong ... */
+	case _IOC_WRITE:
+	case (_IOC_WRITE | _IOC_READ):
+		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
+		        parg = sbuf;
+		} else {
+		        /* too big to allocate from stack */
+		        mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
+		        if (NULL == mbuf)
+		                return -ENOMEM;
+		        parg = mbuf;
+		}
 
-                err = -EFAULT;
-                if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
-                        goto out;
-                break;
-        }
+		err = -EFAULT;
+		if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
+		        goto out;
+		break;
+	}
 
-        /* call driver */
-        if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD)
-                err = -EINVAL;
+	/* call driver */
+	if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD)
+		err = -EINVAL;
 
-        if (err < 0)
-                goto out;
+	if (err < 0)
+		goto out;
 
-        /*  Copy results into user buffer  */
-        switch (_IOC_DIR(cmd))
-        {
-        case _IOC_READ:
-        case (_IOC_WRITE | _IOC_READ):
-                if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
-                        err = -EFAULT;
-                break;
-        }
+	/*  Copy results into user buffer  */
+	switch (_IOC_DIR(cmd))
+	{
+	case _IOC_READ:
+	case (_IOC_WRITE | _IOC_READ):
+		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
+		        err = -EFAULT;
+		break;
+	}
 
 out:
-        kfree(mbuf);
-        return err;
+	kfree(mbuf);
+	return err;
 }
 
 static int __init init_dvbdev(void)
@@ -427,10 +427,10 @@
 
 static void __exit exit_dvbdev(void)
 {
-        devfs_remove("dvb");
+	devfs_remove("dvb");
 	class_destroy(dvb_class);
 	cdev_del(&dvb_device_cdev);
-        unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
+	unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
 }
 
 module_init(init_dvbdev);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index a251867..0cc6e4a 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -68,8 +68,8 @@
 	int writers;
 	int users;
 
-        /* don't really need those !? -- FIXME: use video_usercopy  */
-        int (*kernel_ioctl)(struct inode *inode, struct file *file,
+	/* don't really need those !? -- FIXME: use video_usercopy  */
+	int (*kernel_ioctl)(struct inode *inode, struct file *file,
 			    unsigned int cmd, void *arg);
 
 	void *priv;
@@ -97,7 +97,7 @@
 generic_usercopy()  someday... */
 
 extern int dvb_usercopy(struct inode *inode, struct file *file,
-	                    unsigned int cmd, unsigned long arg,
+		            unsigned int cmd, unsigned long arg,
 			    int (*func)(struct inode *inode, struct file *file,
 			    unsigned int cmd, void *arg));
 
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index 49f541d..ce44aa6 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -65,7 +65,7 @@
 
 };
 
-int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
 	u8 key[5];
 	if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
@@ -144,7 +144,6 @@
 };
 
 static struct usb_driver a800_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_a800",
 	.probe		= a800_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 3fe383f..d05fab0 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -241,7 +241,6 @@
 };
 
 static struct usb_driver cxusb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_cxusb",
 	.probe		= cxusb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 00b9464..269d899 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -21,9 +21,9 @@
 int dibusb_streaming_ctrl(struct dvb_usb_device *d, int onoff)
 {
 	if (d->priv != NULL) {
-		struct dib_fe_xfer_ops *ops = d->priv;
-		if (ops->fifo_ctrl != NULL)
-			if (ops->fifo_ctrl(d->fe,onoff)) {
+		struct dibusb_state *st = d->priv;
+		if (st->ops.fifo_ctrl != NULL)
+			if (st->ops.fifo_ctrl(d->fe,onoff)) {
 				err("error while controlling the fifo of the demod.");
 				return -ENODEV;
 			}
@@ -35,9 +35,9 @@
 int dibusb_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff)
 {
 	if (d->priv != NULL) {
-		struct dib_fe_xfer_ops *ops = d->priv;
-		if (d->pid_filtering && ops->pid_ctrl != NULL)
-			ops->pid_ctrl(d->fe,index,pid,onoff);
+		struct dibusb_state *st = d->priv;
+		if (st->ops.pid_ctrl != NULL)
+			st->ops.pid_ctrl(d->fe,index,pid,onoff);
 	}
 	return 0;
 }
@@ -46,9 +46,9 @@
 int dibusb_pid_filter_ctrl(struct dvb_usb_device *d, int onoff)
 {
 	if (d->priv != NULL) {
-		struct dib_fe_xfer_ops *ops = d->priv;
-		if (ops->pid_parse != NULL)
-			if (ops->pid_parse(d->fe,onoff) < 0)
+		struct dibusb_state *st = d->priv;
+		if (st->ops.pid_parse != NULL)
+			if (st->ops.pid_parse(d->fe,onoff) < 0)
 				err("could not handle pid_parser");
 	}
 	return 0;
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index aa271a2..52ac3e5 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -373,7 +373,6 @@
 };
 
 static struct usb_driver dibusb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_dibusb_mb",
 	.probe		= dibusb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
index 6a0912e..55802fb 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mc.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -82,7 +82,6 @@
 };
 
 static struct usb_driver dibusb_mc_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_dibusb_mc",
 	.probe		= dibusb_mc_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 74545f8..450417a 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -148,7 +148,7 @@
 };
 
 /* TODO is it really the NEC protocol ? */
-int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
+static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
 	u8 key[5];
 
@@ -233,7 +233,6 @@
 };
 
 static struct usb_driver digitv_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_digitv",
 	.probe		= digitv_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index b595476..6e2bac8 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -198,7 +198,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver dtt200u_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_dtt200u",
 	.probe		= dtt200u_usb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index a902059..dd8e0b9 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -23,7 +23,7 @@
 MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
 
 /* general initialization functions */
-int dvb_usb_exit(struct dvb_usb_device *d)
+static int dvb_usb_exit(struct dvb_usb_device *d)
 {
 	deb_info("state before exiting everything: %x\n",d->state);
 	dvb_usb_remote_exit(d);
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
index 1841a66..fac48fc 100644
--- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -202,7 +202,6 @@
 };
 
 static struct usb_driver nova_t_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_nova_t_usb2",
 	.probe		= nova_t_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index 6fd6765..14f1911 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -128,7 +128,6 @@
 };
 
 static struct usb_driver umt_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_umt_010",
 	.probe		= umt_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
index f20d8db..104b5d0 100644
--- a/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -190,7 +190,7 @@
 }
 
 static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
-		                    struct dvb_diseqc_master_cmd *m)
+			            struct dvb_diseqc_master_cmd *m)
 {
 	struct vp702x_fe_state *st = fe->demodulator_priv;
 	u8 cmd[8],ibuf[10];
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
index de13c04..afa00fd 100644
--- a/drivers/media/dvb/dvb-usb/vp702x.c
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -256,7 +256,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver vp702x_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb-usb-vp702x",
 	.probe 		= vp702x_usb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
index 2746edf..83f1de1 100644
--- a/drivers/media/dvb/dvb-usb/vp7045-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -58,7 +58,7 @@
 	struct vp7045_fe_state *state = fe->demodulator_priv;
 	*ber = (vp7045_read_reg(state->d, 0x0D) << 16) |
 	       (vp7045_read_reg(state->d, 0x0E) << 8) |
-	        vp7045_read_reg(state->d, 0x0F);
+		vp7045_read_reg(state->d, 0x0F);
 	return 0;
 }
 
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 75765e3..3835235 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -253,7 +253,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver vp7045_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "dvb_usb_vp7045",
 	.probe		= vp7045_usb_probe,
 	.disconnect = dvb_usb_device_exit,
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c
index 72a2b54..8e0f4b3 100644
--- a/drivers/media/dvb/frontends/at76c651.c
+++ b/drivers/media/dvb/frontends/at76c651.c
@@ -361,9 +361,9 @@
 
 static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *fesettings)
 {
-        fesettings->min_delay_ms = 50;
-        fesettings->step_size = 0;
-        fesettings->max_drift = 0;
+	fesettings->min_delay_ms = 50;
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
 	return 0;
 }
 
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
index f6d4ee7..8ceb9a3 100644
--- a/drivers/media/dvb/frontends/bcm3510.c
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -69,7 +69,7 @@
 #define dbufout(b,l,m) {\
 	    int i; \
 	    for (i = 0; i < l; i++) \
-	        m("%02x ",b[i]); \
+		m("%02x ",b[i]); \
 }
 #define deb_info(args...) dprintk(0x01,args)
 #define deb_i2c(args...)  dprintk(0x02,args)
@@ -827,7 +827,7 @@
 		.type = FE_ATSC,
 		.frequency_min =  54000000,
 		.frequency_max = 803000000,
-                /* stepsize is just a guess */
+		/* stepsize is just a guess */
 		.frequency_stepsize = 0,
 		.caps =
 			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
index 0c2ed44..755f774 100644
--- a/drivers/media/dvb/frontends/cx22700.c
+++ b/drivers/media/dvb/frontends/cx22700.c
@@ -355,10 +355,10 @@
 
 static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
 {
-        fesettings->min_delay_ms = 150;
-        fesettings->step_size = 166667;
-        fesettings->max_drift = 166667*2;
-        return 0;
+	fesettings->min_delay_ms = 150;
+	fesettings->step_size = 166667;
+	fesettings->max_drift = 166667*2;
+	return 0;
 }
 
 static void cx22700_release(struct dvb_frontend* fe)
@@ -407,7 +407,7 @@
 		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 		      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 		      FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-	              FE_CAN_RECOVER
+		      FE_CAN_RECOVER
 	},
 
 	.release = cx22700_release,
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index 9f63929..5de0e6d3 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -2,12 +2,12 @@
     Conexant 22702 DVB OFDM demodulator driver
 
     based on:
-        Alps TDMB7 DVB OFDM demodulator driver
+	Alps TDMB7 DVB OFDM demodulator driver
 
     Copyright (C) 2001-2002 Convergence Integrated Media GmbH
 	  Holger Waechtler <holger@convergence.de>
 
-    Copyright (C) 2004 Steven Toth <steve@toth.demon.co.uk>
+    Copyright (C) 2004 Steven Toth <stoth@hauppauge.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
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 11f8680..5633976 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -2,12 +2,12 @@
     Conexant 22702 DVB OFDM demodulator driver
 
     based on:
-        Alps TDMB7 DVB OFDM demodulator driver
+	Alps TDMB7 DVB OFDM demodulator driver
 
     Copyright (C) 2001-2002 Convergence Integrated Media GmbH
 	  Holger Waechtler <holger@convergence.de>
 
-    Copyright (C) 2004 Steven Toth <steve@toth.demon.co.uk>
+    Copyright (C) 2004 Steven Toth <stoth@hauppauge.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
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index 654d7dc..0c4db80 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -55,81 +55,81 @@
 	} while (0)
 
 static struct {u8 reg; u8 data;} cx24110_regdata[]=
-                      /* Comments beginning with @ denote this value should
-                         be the default */
-        {{0x09,0x01}, /* SoftResetAll */
-         {0x09,0x00}, /* release reset */
-         {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
-         {0x02,0x17}, /* middle byte " */
-         {0x03,0x29}, /* LSB         " */
-         {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */
-         {0x06,0xa5}, /* @ PLL 60MHz */
-         {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
-         {0x0a,0x00}, /* @ partial chip disables, do not set */
-         {0x0b,0x01}, /* set output clock in gapped mode, start signal low
-                         active for first byte */
-         {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
-         {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
-         {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
-                         to avoid starting the BER counter. Reset the
-                         CRC test bit. Finite counting selected */
-         {0x15,0xff}, /* @ size of the limited time window for RS BER
-                         estimation. It is <value>*256 RS blocks, this
-                         gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
-         {0x16,0x00}, /* @ enable all RS output ports */
-         {0x17,0x04}, /* @ time window allowed for the RS to sync */
-         {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
-                         for automatically */
-                      /* leave the current code rate and normalization
-                         registers as they are after reset... */
-         {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
-                         only once */
-         {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
-                         estimation. It is <value>*65536 channel bits, i.e.
-                         approx. 38ms at 27.5MS/s, rate 3/4 */
-         {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
-                      /* leave front-end AGC parameters at default values */
-                      /* leave decimation AGC parameters at default values */
-         {0x35,0x40}, /* disable all interrupts. They are not connected anyway */
-         {0x36,0xff}, /* clear all interrupt pending flags */
-         {0x37,0x00}, /* @ fully enable AutoAcqq state machine */
-         {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */
-                      /* leave the equalizer parameters on their default values */
-                      /* leave the final AGC parameters on their default values */
-         {0x41,0x00}, /* @ MSB of front-end derotator frequency */
-         {0x42,0x00}, /* @ middle bytes " */
-         {0x43,0x00}, /* @ LSB          " */
-                      /* leave the carrier tracking loop parameters on default */
-                      /* leave the bit timing loop parameters at gefault */
-         {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
-                      /* the cx24108 data sheet for symbol rates above 15MS/s */
-         {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
-         {0x61,0x95}, /* GPIO pins 1-4 have special function */
-         {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */
-         {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */
-         {0x64,0x20}, /* GPIO 6 is input, all others are outputs */
-         {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */
-         {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */
-         {0x73,0x00}, /* @ disable several demod bypasses */
-         {0x74,0x00}, /* @  " */
-         {0x75,0x00}  /* @  " */
-                      /* the remaining registers are for SEC */
+		      /* Comments beginning with @ denote this value should
+		         be the default */
+	{{0x09,0x01}, /* SoftResetAll */
+	 {0x09,0x00}, /* release reset */
+	 {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
+	 {0x02,0x17}, /* middle byte " */
+	 {0x03,0x29}, /* LSB         " */
+	 {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */
+	 {0x06,0xa5}, /* @ PLL 60MHz */
+	 {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
+	 {0x0a,0x00}, /* @ partial chip disables, do not set */
+	 {0x0b,0x01}, /* set output clock in gapped mode, start signal low
+		         active for first byte */
+	 {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
+	 {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
+	 {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
+		         to avoid starting the BER counter. Reset the
+		         CRC test bit. Finite counting selected */
+	 {0x15,0xff}, /* @ size of the limited time window for RS BER
+		         estimation. It is <value>*256 RS blocks, this
+		         gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
+	 {0x16,0x00}, /* @ enable all RS output ports */
+	 {0x17,0x04}, /* @ time window allowed for the RS to sync */
+	 {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
+		         for automatically */
+		      /* leave the current code rate and normalization
+		         registers as they are after reset... */
+	 {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
+		         only once */
+	 {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
+		         estimation. It is <value>*65536 channel bits, i.e.
+		         approx. 38ms at 27.5MS/s, rate 3/4 */
+	 {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
+		      /* leave front-end AGC parameters at default values */
+		      /* leave decimation AGC parameters at default values */
+	 {0x35,0x40}, /* disable all interrupts. They are not connected anyway */
+	 {0x36,0xff}, /* clear all interrupt pending flags */
+	 {0x37,0x00}, /* @ fully enable AutoAcqq state machine */
+	 {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */
+		      /* leave the equalizer parameters on their default values */
+		      /* leave the final AGC parameters on their default values */
+	 {0x41,0x00}, /* @ MSB of front-end derotator frequency */
+	 {0x42,0x00}, /* @ middle bytes " */
+	 {0x43,0x00}, /* @ LSB          " */
+		      /* leave the carrier tracking loop parameters on default */
+		      /* leave the bit timing loop parameters at gefault */
+	 {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
+		      /* the cx24108 data sheet for symbol rates above 15MS/s */
+	 {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
+	 {0x61,0x95}, /* GPIO pins 1-4 have special function */
+	 {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */
+	 {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */
+	 {0x64,0x20}, /* GPIO 6 is input, all others are outputs */
+	 {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */
+	 {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */
+	 {0x73,0x00}, /* @ disable several demod bypasses */
+	 {0x74,0x00}, /* @  " */
+	 {0x75,0x00}  /* @  " */
+		      /* the remaining registers are for SEC */
 	};
 
 
 static int cx24110_writereg (struct cx24110_state* state, int reg, int data)
 {
-        u8 buf [] = { reg, data };
+	u8 buf [] = { reg, data };
 	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
 	int err;
 
-        if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+	if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
 		dprintk ("%s: writereg error (err == %i, reg == 0x%02x,"
 			 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
 		return -EREMOTEIO;
 	}
 
-        return 0;
+	return 0;
 }
 
 static int cx24110_readreg (struct cx24110_state* state, u8 reg)
@@ -153,27 +153,27 @@
 
 	switch (inversion) {
 	case INVERSION_OFF:
-                cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
-                /* AcqSpectrInvDis on. No idea why someone should want this */
-                cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7);
-                /* Initial value 0 at start of acq */
-                cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef);
-                /* current value 0 */
-                /* The cx24110 manual tells us this reg is read-only.
-                   But what the heck... set it ayways */
-                break;
+		cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
+		/* AcqSpectrInvDis on. No idea why someone should want this */
+		cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7);
+		/* Initial value 0 at start of acq */
+		cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef);
+		/* current value 0 */
+		/* The cx24110 manual tells us this reg is read-only.
+		   But what the heck... set it ayways */
+		break;
 	case INVERSION_ON:
-                cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
-                /* AcqSpectrInvDis on. No idea why someone should want this */
-                cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08);
-                /* Initial value 1 at start of acq */
-                cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10);
-                /* current value 1 */
-                break;
+		cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
+		/* AcqSpectrInvDis on. No idea why someone should want this */
+		cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08);
+		/* Initial value 1 at start of acq */
+		cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10);
+		/* current value 1 */
+		break;
 	case INVERSION_AUTO:
-                cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe);
-                /* AcqSpectrInvDis off. Leave initial & current states as is */
-                break;
+		cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe);
+		/* AcqSpectrInvDis off. Leave initial & current states as is */
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -185,18 +185,18 @@
 {
 /* fixme (low): error handling */
 
-        static const int rate[]={-1,1,2,3,5,7,-1};
-        static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
-        static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
+	static const int rate[]={-1,1,2,3,5,7,-1};
+	static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
+	static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
 
-        /* Well, the AutoAcq engine of the cx24106 and 24110 automatically
-           searches all enabled viterbi rates, and can handle non-standard
-           rates as well. */
+	/* Well, the AutoAcq engine of the cx24106 and 24110 automatically
+	   searches all enabled viterbi rates, and can handle non-standard
+	   rates as well. */
 
-        if (fec>FEC_AUTO)
-                fec=FEC_AUTO;
+	if (fec>FEC_AUTO)
+		fec=FEC_AUTO;
 
-        if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */
+	if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */
 		cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf);
 		/* clear AcqVitDis bit */
 		cx24110_writereg(state,0x18,0xae);
@@ -208,7 +208,7 @@
 		cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06);
 		/* set the puncture registers for code rate 3/4 */
 		return 0;
-        } else {
+	} else {
 		cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20);
 		/* set AcqVitDis bit */
 		if(rate[fec]>0) {
@@ -219,10 +219,10 @@
 			cx24110_writereg(state,0x1a,g1[fec]);
 			cx24110_writereg(state,0x1b,g2[fec]);
 			/* not sure if this is the right way: I always used AutoAcq mode */
-           } else
+	   } else
 		   return -EOPNOTSUPP;
 /* fixme (low): which is the correct return code? */
-        };
+	};
 	return 0;
 }
 
@@ -245,72 +245,72 @@
 static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
 {
 /* fixme (low): add error handling */
-        u32 ratio;
-        u32 tmp, fclk, BDRI;
+	u32 ratio;
+	u32 tmp, fclk, BDRI;
 
-        static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
-        int i;
+	static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
+	int i;
 
 dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate);
-        if (srate>90999000UL/2)
-                srate=90999000UL/2;
-        if (srate<500000)
-                srate=500000;
+	if (srate>90999000UL/2)
+		srate=90999000UL/2;
+	if (srate<500000)
+		srate=500000;
 
-        for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(srate>bands[i]);i++)
+	for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(srate>bands[i]);i++)
 		;
-        /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz,
-           and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult,
-           R06[3:0] PLLphaseDetGain */
-        tmp=cx24110_readreg(state,0x07)&0xfc;
-        if(srate<90999000UL/4) { /* sample rate 45MHz*/
+	/* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz,
+	   and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult,
+	   R06[3:0] PLLphaseDetGain */
+	tmp=cx24110_readreg(state,0x07)&0xfc;
+	if(srate<90999000UL/4) { /* sample rate 45MHz*/
 		cx24110_writereg(state,0x07,tmp);
 		cx24110_writereg(state,0x06,0x78);
 		fclk=90999000UL/2;
-        } else if(srate<60666000UL/2) { /* sample rate 60MHz */
+	} else if(srate<60666000UL/2) { /* sample rate 60MHz */
 		cx24110_writereg(state,0x07,tmp|0x1);
 		cx24110_writereg(state,0x06,0xa5);
 		fclk=60666000UL;
-        } else if(srate<80888000UL/2) { /* sample rate 80MHz */
+	} else if(srate<80888000UL/2) { /* sample rate 80MHz */
 		cx24110_writereg(state,0x07,tmp|0x2);
 		cx24110_writereg(state,0x06,0x87);
 		fclk=80888000UL;
-        } else { /* sample rate 90MHz */
+	} else { /* sample rate 90MHz */
 		cx24110_writereg(state,0x07,tmp|0x3);
 		cx24110_writereg(state,0x06,0x78);
 		fclk=90999000UL;
-        };
-        dprintk("cx24110 debug: fclk %d Hz\n",fclk);
-        /* we need to divide two integers with approx. 27 bits in 32 bit
-           arithmetic giving a 25 bit result */
-        /* the maximum dividend is 90999000/2, 0x02b6446c, this number is
-           also the most complex divisor. Hence, the dividend has,
-           assuming 32bit unsigned arithmetic, 6 clear bits on top, the
-           divisor 2 unused bits at the bottom. Also, the quotient is
-           always less than 1/2. Borrowed from VES1893.c, of course */
+	};
+	dprintk("cx24110 debug: fclk %d Hz\n",fclk);
+	/* we need to divide two integers with approx. 27 bits in 32 bit
+	   arithmetic giving a 25 bit result */
+	/* the maximum dividend is 90999000/2, 0x02b6446c, this number is
+	   also the most complex divisor. Hence, the dividend has,
+	   assuming 32bit unsigned arithmetic, 6 clear bits on top, the
+	   divisor 2 unused bits at the bottom. Also, the quotient is
+	   always less than 1/2. Borrowed from VES1893.c, of course */
 
-        tmp=srate<<6;
-        BDRI=fclk>>2;
-        ratio=(tmp/BDRI);
+	tmp=srate<<6;
+	BDRI=fclk>>2;
+	ratio=(tmp/BDRI);
 
-        tmp=(tmp%BDRI)<<8;
-        ratio=(ratio<<8)+(tmp/BDRI);
+	tmp=(tmp%BDRI)<<8;
+	ratio=(ratio<<8)+(tmp/BDRI);
 
-        tmp=(tmp%BDRI)<<8;
-        ratio=(ratio<<8)+(tmp/BDRI);
+	tmp=(tmp%BDRI)<<8;
+	ratio=(ratio<<8)+(tmp/BDRI);
 
-        tmp=(tmp%BDRI)<<1;
-        ratio=(ratio<<1)+(tmp/BDRI);
+	tmp=(tmp%BDRI)<<1;
+	ratio=(ratio<<1)+(tmp/BDRI);
 
-        dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]);
-        dprintk("fclk = %d\n", fclk);
-        dprintk("ratio= %08x\n", ratio);
+	dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]);
+	dprintk("fclk = %d\n", fclk);
+	dprintk("ratio= %08x\n", ratio);
 
-        cx24110_writereg(state, 0x1, (ratio>>16)&0xff);
-        cx24110_writereg(state, 0x2, (ratio>>8)&0xff);
-        cx24110_writereg(state, 0x3, (ratio)&0xff);
+	cx24110_writereg(state, 0x1, (ratio>>16)&0xff);
+	cx24110_writereg(state, 0x2, (ratio>>8)&0xff);
+	cx24110_writereg(state, 0x3, (ratio)&0xff);
 
-        return 0;
+	return 0;
 
 }
 
@@ -324,48 +324,48 @@
 
 	dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data);
 
-        cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
-        cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
+	cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
+	cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
 
-        /* if the auto tuner writer is still busy, clear it out */
-        while (cx24110_readreg(state,0x6d)&0x80)
+	/* if the auto tuner writer is still busy, clear it out */
+	while (cx24110_readreg(state,0x6d)&0x80)
 		cx24110_writereg(state,0x72,0);
 
-        /* write the topmost 8 bits */
-        cx24110_writereg(state,0x72,(data>>24)&0xff);
+	/* write the topmost 8 bits */
+	cx24110_writereg(state,0x72,(data>>24)&0xff);
 
-        /* wait for the send to be completed */
-        while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
+	/* wait for the send to be completed */
+	while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
 		;
 
-        /* send another 8 bytes */
-        cx24110_writereg(state,0x72,(data>>16)&0xff);
-        while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
+	/* send another 8 bytes */
+	cx24110_writereg(state,0x72,(data>>16)&0xff);
+	while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
 		;
 
-        /* and the topmost 5 bits of this byte */
-        cx24110_writereg(state,0x72,(data>>8)&0xff);
-        while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
+	/* and the topmost 5 bits of this byte */
+	cx24110_writereg(state,0x72,(data>>8)&0xff);
+	while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
 		;
 
-        /* now strobe the enable line once */
-        cx24110_writereg(state,0x6d,0x32);
-        cx24110_writereg(state,0x6d,0x30);
+	/* now strobe the enable line once */
+	cx24110_writereg(state,0x6d,0x32);
+	cx24110_writereg(state,0x6d,0x30);
 
-        return 0;
+	return 0;
 }
 
 static int cx24110_initfe(struct dvb_frontend* fe)
 {
 	struct cx24110_state *state = fe->demodulator_priv;
 /* fixme (low): error handling */
-        int i;
+	int i;
 
 	dprintk("%s: init chip\n", __FUNCTION__);
 
-        for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);i++) {
+	for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);i++) {
 		cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
-        };
+	};
 
 	if (state->config->pll_init) state->config->pll_init(fe);
 
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index 19b4bf7..1c7c912 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -2,7 +2,7 @@
     driver for LSI L64781 COFDM demodulator
 
     Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
-                       Marko Kohtala <marko.kohtala@luukku.com>
+		       Marko Kohtala <marko.kohtala@luukku.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
@@ -433,7 +433,7 @@
 {
 	struct l64781_state* state = fe->demodulator_priv;
 
-        reset_and_configure (state);
+	reset_and_configure (state);
 
 	/* Power up */
 	l64781_writereg (state, 0x3e, 0xa5);
@@ -456,9 +456,9 @@
 	l64781_writereg (state, 0x0d, 0x8c);
 
 	/* With ppm=8000, it seems the DTR_SENSITIVITY will result in
-           value of 2 with all possible bandwidths and guard
-           intervals, which is the initial value anyway. */
-        /*l64781_writereg (state, 0x19, 0x92);*/
+	   value of 2 with all possible bandwidths and guard
+	   intervals, which is the initial value anyway. */
+	/*l64781_writereg (state, 0x19, 0x92);*/
 
 	/* Everything is two's complement, soft bit and CSI_OUT too */
 	l64781_writereg (state, 0x1e, 0x09);
@@ -477,10 +477,10 @@
 static int l64781_get_tune_settings(struct dvb_frontend* fe,
 				    struct dvb_frontend_tune_settings* fesettings)
 {
-        fesettings->min_delay_ms = 4000;
-        fesettings->step_size = 0;
-        fesettings->max_drift = 0;
-        return 0;
+	fesettings->min_delay_ms = 4000;
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
+	return 0;
 }
 
 static void l64781_release(struct dvb_frontend* fe)
@@ -522,7 +522,7 @@
 
 	/* The chip always responds to reads */
 	if (i2c_transfer(state->i2c, msg, 2) != 2) {
-	        dprintk("No response to read on I2C bus\n");
+		dprintk("No response to read on I2C bus\n");
 		goto error;
 	}
 
@@ -531,7 +531,7 @@
 
 	/* Reading the POWER_DOWN register always returns 0 */
 	if (reg0x3e != 0) {
-	        dprintk("Device doesn't look like L64781\n");
+		dprintk("Device doesn't look like L64781\n");
 		goto error;
 	}
 
@@ -540,7 +540,7 @@
 
 	/* Responds to all reads with 0 */
 	if (l64781_readreg(state, 0x1a) != 0) {
-	        dprintk("Read 1 returned unexpcted value\n");
+		dprintk("Read 1 returned unexpcted value\n");
 		goto error;
 	}
 
@@ -549,7 +549,7 @@
 
 	/* Responds with register default value */
 	if (l64781_readreg(state, 0x1a) != 0xa1) {
-	        dprintk("Read 2 returned unexpcted value\n");
+		dprintk("Read 2 returned unexpcted value\n");
 		goto error;
 	}
 
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
index 7e30fb0..947f65f 100644
--- a/drivers/media/dvb/frontends/l64781.h
+++ b/drivers/media/dvb/frontends/l64781.h
@@ -2,7 +2,7 @@
     driver for LSI L64781 COFDM demodulator
 
     Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
-                       Marko Kohtala <marko.kohtala@luukku.com>
+		       Marko Kohtala <marko.kohtala@luukku.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
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index 6a33f5a..cb5301865 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -301,10 +301,10 @@
 	static u8 lgdt3303_8vsb_44_data[] = {
 		0x04, 0x00,
 		0x0d, 0x40,
-        0x0e, 0x87,
-        0x0f, 0x8e,
-        0x10, 0x01,
-        0x47, 0x8b };
+	0x0e, 0x87,
+	0x0f, 0x8e,
+	0x10, 0x01,
+	0x47, 0x8b };
 
 	/*
 	 * Array of byte pairs <address, value>
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
index 9c67f40..8d67228 100644
--- a/drivers/media/dvb/frontends/mt312.c
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -554,7 +554,7 @@
 	if ((ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf))) < 0)
 		return ret;
 
-        mt312_reset(state, 0);
+	mt312_reset(state, 0);
 
 	return 0;
 }
@@ -695,7 +695,7 @@
 		    FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
 		    FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
 		    FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS |
-	            FE_CAN_RECOVER
+		    FE_CAN_RECOVER
 	},
 
 	.release = mt312_release,
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c
index 30786b1..52c4160 100644
--- a/drivers/media/dvb/frontends/nxt2002.c
+++ b/drivers/media/dvb/frontends/nxt2002.c
@@ -527,7 +527,7 @@
 	else
 		snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
 
-        /* the value reported back from the frontend will be FFFF=32db 0000=0db */
+	/* the value reported back from the frontend will be FFFF=32db 0000=0db */
 
 	*snr = snrdb * (0xFFFF/32000);
 
@@ -646,7 +646,7 @@
 	memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops));
 	state->initialised = 0;
 
-        /* Check the first 5 registers to ensure this a revision we can handle */
+	/* Check the first 5 registers to ensure this a revision we can handle */
 
 	i2c_readbytes(state, 0x00, buf, 5);
 	if (buf[0] != 0x04) goto error;		/* device id */
@@ -672,7 +672,7 @@
 		.type = FE_ATSC,
 		.frequency_min =  54000000,
 		.frequency_max = 860000000,
-                /* stepsize is just a guess */
+		/* stepsize is just a guess */
 		.frequency_stepsize = 166666,
 		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
index bad0933..aeafef4 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -44,6 +44,8 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/string.h>
 
 #include "dvb_frontend.h"
 #include "dvb-pll.h"
@@ -337,7 +339,7 @@
 	switch (state->demod_chip) {
 		case NXT2004:
 			if (i2c_writebytes(state, state->config->pll_address, data, 4))
-	        	        printk(KERN_WARNING "nxt200x: error writing to tuner\n");
+				printk(KERN_WARNING "nxt200x: error writing to tuner\n");
 			/* wait until we have a lock */
 			while (count < 20) {
 				i2c_readbytes(state, state->config->pll_address, &buf, 1);
@@ -495,7 +497,7 @@
 
 	/* calculate firmware CRC */
 	for (position = 0; position < fw->size; position++) {
-	        crc = nxt200x_crc(crc, fw->data[position]);
+		crc = nxt200x_crc(crc, fw->data[position]);
 	}
 
 	buf[0] = rambase >> 8;
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
index 88a57b7..a458a3b 100644
--- a/drivers/media/dvb/frontends/nxt6000.c
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -574,11 +574,11 @@
 		.symbol_rate_max = 9360000,	/* FIXME */
 		.symbol_rate_tolerance = 4000,
 		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
-	                FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
-	                FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
-	                FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
-	                FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
-	                FE_CAN_HIERARCHY_AUTO,
+		        FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
+		        FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
+		        FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+		        FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+		        FE_CAN_HIERARCHY_AUTO,
 	},
 
 	.release = nxt6000_release,
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
index 78bded8..80e0f28 100644
--- a/drivers/media/dvb/frontends/or51132.c
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -503,7 +503,7 @@
 	rcvr_stat = rec_buf[1];
 	usK = (rcvr_stat & 0x10) ? 3 : 0;
 
-        /* The value reported back from the frontend will be FFFF=100% 0000=0% */
+	/* The value reported back from the frontend will be FFFF=100% 0000=0% */
 	signal_strength = (((8952 - i20Log10(snr_equ) - usK*100)/3+5)*65535)/1000;
 	if (signal_strength > 0xffff)
 		*strength = 0xffff;
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index f265418..1871509 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -494,7 +494,7 @@
 }
 
 static void s5h1420_setfec_inversion(struct s5h1420_state* state,
-			   	     struct dvb_frontend_parameters *p)
+				     struct dvb_frontend_parameters *p)
 {
 	u8 inversion = 0;
 
@@ -521,8 +521,8 @@
 
 		case FEC_3_4:
 			s5h1420_writereg(state, 0x30, 0x04);
-                        s5h1420_writereg(state, 0x31, 0x12 | inversion);
-                        break;
+		        s5h1420_writereg(state, 0x31, 0x12 | inversion);
+		        break;
 
 		case FEC_5_6:
 			s5h1420_writereg(state, 0x30, 0x08);
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index 872028d..73296f1 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -39,6 +39,6 @@
 };
 
 extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
-             struct i2c_adapter* i2c);
+	     struct i2c_adapter* i2c);
 
 #endif // S5H1420_H
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
index 1c6b2e9..fc06cd6 100644
--- a/drivers/media/dvb/frontends/sp8870.c
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -67,16 +67,16 @@
 
 static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
 {
-        u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
+	u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
 	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
 	int err;
 
-        if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
 		dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
 		return -EREMOTEIO;
 	}
 
-        return 0;
+	return 0;
 }
 
 static int sp8870_readreg (struct sp8870_state* state, u16 reg)
@@ -305,7 +305,7 @@
 static int sp8870_init (struct dvb_frontend* fe)
 {
 	struct sp8870_state* state = fe->demodulator_priv;
-        const struct firmware *fw = NULL;
+	const struct firmware *fw = NULL;
 
 	sp8870_wake_up(state);
 	if (state->initialised) return 0;
@@ -534,10 +534,10 @@
 
 static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
 {
-        fesettings->min_delay_ms = 350;
-        fesettings->step_size = 0;
-        fesettings->max_drift = 0;
-        return 0;
+	fesettings->min_delay_ms = 350;
+	fesettings->step_size = 0;
+	fesettings->max_drift = 0;
+	return 0;
 }
 
 static void sp8870_release(struct dvb_frontend* fe)
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index 73384e7..e3b6657 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -80,7 +80,7 @@
 	u8 b1 [2];
 	int ret;
 	struct i2c_msg msg[] = {{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
-		         { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};
+			 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};
 
 	if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
 		printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
@@ -498,7 +498,7 @@
 static int sp887x_init(struct dvb_frontend* fe)
 {
 	struct sp887x_state* state = fe->demodulator_priv;
-        const struct firmware *fw = NULL;
+	const struct firmware *fw = NULL;
 	int ret;
 
 	if (!state->initialised) {
@@ -528,10 +528,10 @@
 
 static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
 {
-        fesettings->min_delay_ms = 350;
-        fesettings->step_size = 166666*2;
-        fesettings->max_drift = (166666*2)+1;
-        return 0;
+	fesettings->min_delay_ms = 350;
+	fesettings->step_size = 166666*2;
+	fesettings->max_drift = (166666*2)+1;
+	return 0;
 }
 
 static void sp887x_release(struct dvb_frontend* fe)
@@ -581,7 +581,7 @@
 		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 			FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
-	                FE_CAN_RECOVER
+		        FE_CAN_RECOVER
 	},
 
 	.release = sp887x_release,
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 29c4866..177d71d 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -95,7 +95,7 @@
 
 int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 
 	return stv0299_writeregI(state, reg, data);
 }
@@ -220,7 +220,7 @@
 
 static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 	u64 big = srate;
 	u32 ratio;
 
@@ -271,7 +271,7 @@
 static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
 				    struct dvb_diseqc_master_cmd *m)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 	u8 val;
 	int i;
 
@@ -301,7 +301,7 @@
 
 static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 	u8 val;
 
 	dprintk ("%s\n", __FUNCTION__);
@@ -328,7 +328,7 @@
 
 static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 	u8 val;
 
 	if (stv0299_wait_diseqc_idle (state, 100) < 0)
@@ -350,7 +350,7 @@
 
 static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 	u8 reg0x08;
 	u8 reg0x0c;
 
@@ -442,7 +442,7 @@
 
 static int stv0299_init (struct dvb_frontend* fe)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 	int i;
 
 	dprintk("stv0299: init chip\n");
@@ -461,7 +461,7 @@
 
 static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 
 	u8 signal = 0xff - stv0299_readreg (state, 0x18);
 	u8 sync = stv0299_readreg (state, 0x1b);
@@ -489,7 +489,7 @@
 
 static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 
 	if (state->errmode != STATUS_BER) return 0;
 	*ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
@@ -499,7 +499,7 @@
 
 static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 
 	s32 signal =  0xffff - ((stv0299_readreg (state, 0x18) << 8)
 			       | stv0299_readreg (state, 0x19));
@@ -516,7 +516,7 @@
 
 static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 
 	s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
 			   | stv0299_readreg (state, 0x25));
@@ -528,7 +528,7 @@
 
 static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 
 	if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0;
 	else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e);
@@ -538,7 +538,7 @@
 
 static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 	int invval = 0;
 
 	dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__);
@@ -571,7 +571,7 @@
 
 static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 	s32 derot_freq;
 	int invval;
 
@@ -596,7 +596,7 @@
 
 static int stv0299_sleep(struct dvb_frontend* fe)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 
 	stv0299_writeregI(state, 0x02, 0x80);
 	state->initialised = 0;
@@ -606,7 +606,7 @@
 
 static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
 {
-        struct stv0299_state* state = fe->demodulator_priv;
+	struct stv0299_state* state = fe->demodulator_priv;
 
 	fesettings->min_delay_ms = state->config->min_delay_ms;
 	if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
@@ -658,7 +658,7 @@
 
 	/* create dvb_frontend */
 	state->frontend.ops = &state->ops;
-        state->frontend.demodulator_priv = state;
+	state->frontend.demodulator_priv = state;
 	return &state->frontend;
 
 error:
@@ -714,7 +714,7 @@
 
 MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver");
 MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
-              "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy");
+	      "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy");
 MODULE_LICENSE("GPL");
 
 EXPORT_SYMBOL(stv0299_writereg);
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index eaf130e..425cd19 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -1,10 +1,10 @@
 /*
     TDA10021  - Single Chip Cable Channel Receiver driver module
-               used on the the Siemens DVB-C cards
+	       used on the the Siemens DVB-C cards
 
     Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
     Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
-                   Support for TDA10021
+		   Support for TDA10021
 
     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
@@ -76,9 +76,9 @@
 
 static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
 {
-        u8 buf[] = { reg, data };
+	u8 buf[] = { reg, data };
 	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
-        int ret;
+	int ret;
 
 	ret = i2c_transfer (state->i2c, &msg, 1);
 	if (ret != 1)
@@ -95,7 +95,7 @@
 	u8 b0 [] = { reg };
 	u8 b1 [] = { 0 };
 	struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
-	                          { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+		                  { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 	int ret;
 
 	ret = i2c_transfer (state->i2c, msg, 2);
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h
index 7d6a51c..53be939 100644
--- a/drivers/media/dvb/frontends/tda10021.h
+++ b/drivers/media/dvb/frontends/tda10021.h
@@ -1,10 +1,10 @@
 /*
     TDA10021  - Single Chip Cable Channel Receiver driver module
-               used on the the Siemens DVB-C cards
+	       used on the the Siemens DVB-C cards
 
     Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
     Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
-                   Support for TDA10021
+		   Support for TDA10021
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 7968743..dd02aff 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -475,7 +475,7 @@
 		ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
 		if (ret) {
 			printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
-   	   		return ret;
+			return ret;
 		}
 		tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
 		ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
index c05cf186..91baa9c 100644
--- a/drivers/media/dvb/frontends/tda8083.c
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -66,13 +66,13 @@
 	u8 buf [] = { reg, data };
 	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
 
-        ret = i2c_transfer(state->i2c, &msg, 1);
+	ret = i2c_transfer(state->i2c, &msg, 1);
 
-        if (ret != 1)
-                dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
+	if (ret != 1)
+		dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
 			__FUNCTION__, reg, ret);
 
-        return (ret != 1) ? -1 : 0;
+	return (ret != 1) ? -1 : 0;
 }
 
 static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len)
@@ -87,7 +87,7 @@
 		dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
 			__FUNCTION__, reg1, ret);
 
-        return ret == 2 ? 0 : -1;
+	return ret == 2 ? 0 : -1;
 }
 
 static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
@@ -132,14 +132,14 @@
 
 static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate)
 {
-        u32 ratio;
+	u32 ratio;
 	u32 tmp;
 	u8 filter;
 
 	if (srate > 32000000)
-                srate = 32000000;
-        if (srate < 500000)
-                srate = 500000;
+		srate = 32000000;
+	if (srate < 500000)
+		srate = 500000;
 
 	filter = 0;
 	if (srate < 24000000)
@@ -174,7 +174,7 @@
 	unsigned long start = jiffies;
 
 	while (jiffies - start < timeout &&
-               !(tda8083_readreg(state, 0x02) & 0x80))
+	       !(tda8083_readreg(state, 0x02) & 0x80))
 	{
 		msleep(50);
 	};
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
index c6d2766..ad8647a3 100644
--- a/drivers/media/dvb/frontends/ves1820.c
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -140,25 +140,25 @@
 	/* yeuch! */
 	fpxin = state->config->xin * 10;
 	fptmp = fpxin; do_div(fptmp, 123);
-	if (symbolrate < fptmp);
+	if (symbolrate < fptmp)
 		SFIL = 1;
 	fptmp = fpxin; do_div(fptmp, 160);
-	if (symbolrate < fptmp);
+	if (symbolrate < fptmp)
 		SFIL = 0;
 	fptmp = fpxin; do_div(fptmp, 246);
-	if (symbolrate < fptmp);
+	if (symbolrate < fptmp)
 		SFIL = 1;
 	fptmp = fpxin; do_div(fptmp, 320);
-	if (symbolrate < fptmp);
+	if (symbolrate < fptmp)
 		SFIL = 0;
 	fptmp = fpxin; do_div(fptmp, 492);
-	if (symbolrate < fptmp);
+	if (symbolrate < fptmp)
 		SFIL = 1;
 	fptmp = fpxin; do_div(fptmp, 640);
-	if (symbolrate < fptmp);
+	if (symbolrate < fptmp)
 		SFIL = 0;
 	fptmp = fpxin; do_div(fptmp, 984);
-	if (symbolrate < fptmp);
+	if (symbolrate < fptmp)
 		SFIL = 1;
 
 	fin = state->config->xin >> 4;
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index d8bf658..fa5034a 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -81,6 +81,7 @@
 	tristate "Budget cards with onboard CI connector"
 	depends on DVB_CORE && PCI
 	select VIDEO_SAA7146
+	select DVB_STV0297
 	select DVB_STV0299
 	select DVB_TDA1004X
 	help
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index 87ea527..7dae91e 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -176,6 +176,9 @@
 		}
 	}
 
+	if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000e)
+		av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, SpdifSwitch, 1, 0); // SPDIF on
+
 	ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
 	if (ret < 0)
 		printk("dvb-ttpci:cannot set volume :%d\n",ret);
@@ -217,10 +220,10 @@
 
 	dprintk(4, "%p\n",av7110);
 
-        lock_kernel();
-        daemonize("arm_mon");
-        sigfillset(&current->blocked);
-        unlock_kernel();
+	lock_kernel();
+	daemonize("arm_mon");
+	sigfillset(&current->blocked);
+	unlock_kernel();
 
 	av7110->arm_thread = current;
 
@@ -1535,7 +1538,7 @@
 	buf[2] = ((div & 0x18000) >> 10) | 0x95;
 	buf[3] = (pwr << 6) | 0x30;
 
-        // NOTE: since we're using a prescaler of 2, we set the
+	// NOTE: since we're using a prescaler of 2, we set the
 	// divisor frequency to 62.5kHz and divide by 125 above
 
 	if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
@@ -1811,7 +1814,7 @@
 static int philips_cd1516_pll_set(struct dvb_frontend* fe,
 				  struct dvb_frontend_parameters* params)
 {
-        struct av7110* av7110 = fe->dvb->priv;
+	struct av7110* av7110 = fe->dvb->priv;
 	u32 div;
 	u32 f = params->frequency;
 	u8 data[4];
@@ -2202,7 +2205,7 @@
 	struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
 				 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
 
-        if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
+	if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
 		pwm = 0x48;
 
 	return pwm;
@@ -2245,7 +2248,7 @@
 			}
 
 			// Try the grundig 29504-451
-                        av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
+		        av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
 			if (av7110->fe) {
 				av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
 				av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
@@ -2271,12 +2274,12 @@
 		case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
 
 			// ALPS TDLB7
-                        av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
+		        av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
 			break;
 
 		case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
 
-                        av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
+		        av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
 			break;
 
 		case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */
@@ -2421,9 +2424,9 @@
 
 	dprintk(4, "dev: %p\n", dev);
 
-        /* Set RPS_IRQ to 1 to track rps1 activity.
-         * Enabling this won't send any interrupt to PC CPU.
-         */
+	/* Set RPS_IRQ to 1 to track rps1 activity.
+	 * Enabling this won't send any interrupt to PC CPU.
+	 */
 #define RPS_IRQ 0
 
 	if (budgetpatch == 1) {
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index c3801e3..6079e88 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -40,6 +40,7 @@
 
 #include "av7110.h"
 #include "av7110_hw.h"
+#include "av7110_ca.h"
 
 
 void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 7442f56..87106e8 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -1203,15 +1203,15 @@
 
 int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap)
 {
-        switch (cap->cmd) {
-        case OSD_CAP_MEMSIZE:
-                if (FW_4M_SDRAM(av7110->arm_app))
-                        cap->val = 1000000;
-                else
-                        cap->val = 92000;
-                return 0;
-        default:
-                return -EINVAL;
-        }
+	switch (cap->cmd) {
+	case OSD_CAP_MEMSIZE:
+		if (FW_4M_SDRAM(av7110->arm_app))
+		        cap->val = 1000000;
+		else
+		        cap->val = 92000;
+		return 0;
+	default:
+		return -EINVAL;
+	}
 }
 #endif /* CONFIG_DVB_AV7110_OSD */
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index fedd20f..2a5e87b 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -143,7 +143,8 @@
 	MainSwitch,
 	ADSwitch,
 	SendDiSEqC,
-	SetRegister
+	SetRegister,
+	SpdifSwitch
 };
 
 enum av7110_request_command {
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index 6af74f7..b5aea41 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -120,8 +120,8 @@
 
 static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
 {
-        u8 buf [] = { reg, data };
-        struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };
+	u8 buf [] = { reg, data };
+	struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };
 
 	if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
 		return -1;
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index aa75dc0..9f51bae 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1020,6 +1020,8 @@
 
 static struct saa7146_extension budget_extension = {
 	.name = "budget_av",
+	.flags = SAA7146_I2C_SHORT_DELAY,
+
 	.pci_tbl = pci_tbl,
 
 	.module = THIS_MODULE,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 75fb92d..b9b3cd9 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -1166,7 +1166,7 @@
 
 static struct saa7146_extension budget_extension = {
 	.name = "budget_ci dvb\0",
-	.flags = 0,
+	.flags = SAA7146_I2C_SHORT_DELAY,
 
 	.module = THIS_MODULE,
 	.pci_tbl = &pci_tbl[0],
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index 0498a05..017fcbc 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -87,7 +87,7 @@
 	 *      Pitch: 188, NumBytes3: 188, NumLines3: 1024
 	 */
 
-        switch(budget->card->type) {
+	switch(budget->card->type) {
 	case BUDGET_FS_ACTIVY:
 		saa7146_write(dev, DD1_INIT, 0x04000000);
 		saa7146_write(dev, MC2, (MASK_09 | MASK_25));
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 755df81..fc416cf 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -45,11 +45,11 @@
 //MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC);
 
 static struct pci_device_id pci_tbl[] = {
-        MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
+	MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
 //        MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
-        {
-                .vendor    = 0,
-        }
+	{
+		.vendor    = 0,
+	}
 };
 
 /* those lines are for budget-patch to be tried
@@ -165,57 +165,57 @@
 
 static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
 {
-        int i;
+	int i;
 
-        dprintk(2, "budget: %p\n", budget);
+	dprintk(2, "budget: %p\n", budget);
 
-        for (i = 2; i < length; i++)
-        {
-                  ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
-                  msleep(5);
-        }
-        if (length)
-                  ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
-        else
-                  ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
-        msleep(5);
-        ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
-        msleep(5);
-        return 0;
+	for (i = 2; i < length; i++)
+	{
+		  ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
+		  msleep(5);
+	}
+	if (length)
+		  ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
+	else
+		  ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
+	msleep(5);
+	ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
+	msleep(5);
+	return 0;
 }
 
 static void av7110_set22k(struct budget_patch *budget, int state)
 {
-        u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
+	u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
 
-        dprintk(2, "budget: %p\n", budget);
-        budget_av7110_send_fw_cmd(budget, buf, 2);
+	dprintk(2, "budget: %p\n", budget);
+	budget_av7110_send_fw_cmd(budget, buf, 2);
 }
 
 static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
 {
-        int i;
-        u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
-                16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+	int i;
+	u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
+		16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
-        dprintk(2, "budget: %p\n", budget);
+	dprintk(2, "budget: %p\n", budget);
 
-        if (len>10)
-                len=10;
+	if (len>10)
+		len=10;
 
-        buf[1] = len+2;
-        buf[2] = len;
+	buf[1] = len+2;
+	buf[2] = len;
 
-        if (burst != -1)
-                buf[3]=burst ? 0x01 : 0x00;
-        else
-                buf[3]=0xffff;
+	if (burst != -1)
+		buf[3]=burst ? 0x01 : 0x00;
+	else
+		buf[3]=0xffff;
 
-        for (i=0; i<len; i++)
-                buf[i+4]=msg[i];
+	for (i=0; i<len; i++)
+		buf[i+4]=msg[i];
 
-        budget_av7110_send_fw_cmd(budget, buf, 18);
-        return 0;
+	budget_av7110_send_fw_cmd(budget, buf, 18);
+	return 0;
 }
 
 static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
@@ -276,7 +276,7 @@
 	buf[2] = ((div & 0x18000) >> 10) | 0x95;
 	buf[3] = (pwr << 6) | 0x30;
 
-        // NOTE: since we're using a prescaler of 2, we set the
+	// NOTE: since we're using a prescaler of 2, we set the
 	// divisor frequency to 62.5kHz and divide by 125 above
 
 	if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
@@ -294,7 +294,7 @@
 	0x01, 0x15,
 	0x02, 0x00,
 	0x03, 0x00,
-        0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+	0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
 	0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
 	0x06, 0x40,   /* DAC not used, set to high impendance mode */
 	0x07, 0x00,   /* DAC LSB */
@@ -413,7 +413,7 @@
 {
 	switch(budget->dev->pci->subsystem_device) {
 	case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
-        case 0x1013: // SATELCO Multimedia PCI
+	case 0x1013: // SATELCO Multimedia PCI
 
 		// try the ALPS BSRV2 first of all
 		budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
@@ -463,8 +463,8 @@
 /* written by Emard */
 static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
 {
-        struct budget_patch *budget;
-        int err;
+	struct budget_patch *budget;
+	int err;
 	int count = 0;
 	int detected = 0;
 
@@ -472,12 +472,12 @@
 #define RPS_IRQ 0
 #define HPS_SETUP 0
 #if PATCH_RESET
-        saa7146_write(dev, MC1, MASK_31);
-        msleep(40);
+	saa7146_write(dev, MC1, MASK_31);
+	msleep(40);
 #endif
 #if HPS_SETUP
-        // initialize registers. Better to have it like this
-        // than leaving something unconfigured
+	// initialize registers. Better to have it like this
+	// than leaving something unconfigured
 	saa7146_write(dev, DD1_STREAM_B, 0);
 	// port B VSYNC at rising edge
 	saa7146_write(dev, DD1_INIT, 0x00000200);  // have this in budget-core too!
@@ -486,29 +486,29 @@
 	// debi config
 	// saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18);
 
-        // zero all HPS registers
-        saa7146_write(dev, HPS_H_PRESCALE, 0);                  // r68
-        saa7146_write(dev, HPS_H_SCALE, 0);                     // r6c
-        saa7146_write(dev, BCS_CTRL, 0);                        // r70
-        saa7146_write(dev, HPS_V_SCALE, 0);                     // r60
-        saa7146_write(dev, HPS_V_GAIN, 0);                      // r64
-        saa7146_write(dev, CHROMA_KEY_RANGE, 0);                // r74
-        saa7146_write(dev, CLIP_FORMAT_CTRL, 0);                // r78
-        // Set HPS prescaler for port B input
-        saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
-        saa7146_write(dev, MC2,
-          0 * (MASK_08 | MASK_24)  |   // BRS control
-          0 * (MASK_09 | MASK_25)  |   // a
-          0 * (MASK_10 | MASK_26)  |   // b
-          1 * (MASK_06 | MASK_22)  |   // HPS_CTRL1
-          1 * (MASK_05 | MASK_21)  |   // HPS_CTRL2
-          0 * (MASK_01 | MASK_15)      // DEBI
-           );
+	// zero all HPS registers
+	saa7146_write(dev, HPS_H_PRESCALE, 0);                  // r68
+	saa7146_write(dev, HPS_H_SCALE, 0);                     // r6c
+	saa7146_write(dev, BCS_CTRL, 0);                        // r70
+	saa7146_write(dev, HPS_V_SCALE, 0);                     // r60
+	saa7146_write(dev, HPS_V_GAIN, 0);                      // r64
+	saa7146_write(dev, CHROMA_KEY_RANGE, 0);                // r74
+	saa7146_write(dev, CLIP_FORMAT_CTRL, 0);                // r78
+	// Set HPS prescaler for port B input
+	saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
+	saa7146_write(dev, MC2,
+	  0 * (MASK_08 | MASK_24)  |   // BRS control
+	  0 * (MASK_09 | MASK_25)  |   // a
+	  0 * (MASK_10 | MASK_26)  |   // b
+	  1 * (MASK_06 | MASK_22)  |   // HPS_CTRL1
+	  1 * (MASK_05 | MASK_21)  |   // HPS_CTRL2
+	  0 * (MASK_01 | MASK_15)      // DEBI
+	   );
 #endif
 	// Disable RPS1 and RPS0
-        saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
-        // RPS1 timeout disable
-        saa7146_write(dev, RPS_TOV1, 0);
+	saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
+	// RPS1 timeout disable
+	saa7146_write(dev, RPS_TOV1, 0);
 
 	// code for autodetection
 	// will wait for VBI_B event (vertical blank at port B)
@@ -521,38 +521,38 @@
 	WRITE_RPS1(cpu_to_le32(CMD_UPLOAD |
 	  MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 ));
 #endif
-        WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
-        WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
-        WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
-        WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+	WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
+	WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
+	WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
+	WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
 #if RPS_IRQ
-        // issue RPS1 interrupt to increment counter
-        WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
-        // at least a NOP is neede between two interrupts
-        WRITE_RPS1(cpu_to_le32(CMD_NOP));
-        // interrupt again
-        WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+	// issue RPS1 interrupt to increment counter
+	WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+	// at least a NOP is neede between two interrupts
+	WRITE_RPS1(cpu_to_le32(CMD_NOP));
+	// interrupt again
+	WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
 #endif
-        WRITE_RPS1(cpu_to_le32(CMD_STOP));
+	WRITE_RPS1(cpu_to_le32(CMD_STOP));
 
 #if RPS_IRQ
-        // set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
-        // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
-        // use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
-        saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
-        // set event counter 1 treshold to maximum allowed value        (rEC p55)
-        saa7146_write(dev, ECT1R,  0x3fff );
+	// set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
+	// use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
+	// use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
+	saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
+	// set event counter 1 treshold to maximum allowed value        (rEC p55)
+	saa7146_write(dev, ECT1R,  0x3fff );
 #endif
-        // Fix VSYNC level
-        saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-        // Set RPS1 Address register to point to RPS code               (r108 p42)
-        saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
-        // Enable RPS1,                                                 (rFC p33)
-        saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
+	// Fix VSYNC level
+	saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+	// Set RPS1 Address register to point to RPS code               (r108 p42)
+	saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+	// Enable RPS1,                                                 (rFC p33)
+	saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
 
 
-        mdelay(50);
-        saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
+	mdelay(50);
+	saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
 	mdelay(150);
 
 
@@ -560,17 +560,17 @@
 		detected = 1;
 
 #if RPS_IRQ
-        printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
+	printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
 #endif
 	// Disable RPS1
-        saa7146_write(dev, MC1, ( MASK_29 ));
+	saa7146_write(dev, MC1, ( MASK_29 ));
 
 	if(detected == 0)
-                printk("budget-patch not detected or saa7146 in non-default state.\n"
-                       "try enabling ressetting of 7146 with MASK_31 in MC1 register\n");
+		printk("budget-patch not detected or saa7146 in non-default state.\n"
+		       "try enabling ressetting of 7146 with MASK_31 in MC1 register\n");
 
 	else
-                printk("BUDGET-PATCH DETECTED.\n");
+		printk("BUDGET-PATCH DETECTED.\n");
 
 
 /*      OLD (Original design by Roberto Deza):
@@ -641,83 +641,83 @@
 */
 
 	// Setup RPS1 "program" (p35)
-        count = 0;
+	count = 0;
 
 
-        // Wait Source Line Counter Threshold                           (p36)
-        WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
-        // Set GPIO3=1                                                  (p42)
-        WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
-        WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
-        WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
+	// Wait Source Line Counter Threshold                           (p36)
+	WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
+	// Set GPIO3=1                                                  (p42)
+	WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
+	WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
+	WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
 #if RPS_IRQ
-        // issue RPS1 interrupt
-        WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+	// issue RPS1 interrupt
+	WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
 #endif
-        // Wait reset Source Line Counter Threshold                     (p36)
-        WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
-        // Set GPIO3=0                                                  (p42)
-        WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
-        WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
-        WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
+	// Wait reset Source Line Counter Threshold                     (p36)
+	WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
+	// Set GPIO3=0                                                  (p42)
+	WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
+	WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
+	WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
 #if RPS_IRQ
-        // issue RPS1 interrupt
-        WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
+	// issue RPS1 interrupt
+	WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
 #endif
-        // Jump to begin of RPS program                                 (p37)
-        WRITE_RPS1(cpu_to_le32(CMD_JUMP));
-        WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
+	// Jump to begin of RPS program                                 (p37)
+	WRITE_RPS1(cpu_to_le32(CMD_JUMP));
+	WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
 
-        // Fix VSYNC level
-        saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
-        // Set RPS1 Address register to point to RPS code               (r108 p42)
-        saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
-        // Set Source Line Counter Threshold, using BRS                 (rCC p43)
-        // It generates HS event every TS_HEIGHT lines
-        // this is related to TS_WIDTH set in register
-        // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE
-        // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188
-        //,then RPS_THRESH1
-        // should be set to trigger every TS_HEIGHT (512) lines.
-        //
-        saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
+	// Fix VSYNC level
+	saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
+	// Set RPS1 Address register to point to RPS code               (r108 p42)
+	saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
+	// Set Source Line Counter Threshold, using BRS                 (rCC p43)
+	// It generates HS event every TS_HEIGHT lines
+	// this is related to TS_WIDTH set in register
+	// NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE
+	// low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188
+	//,then RPS_THRESH1
+	// should be set to trigger every TS_HEIGHT (512) lines.
+	//
+	saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
 
-        // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
-        // Enable RPS1                                                  (rFC p33)
-        saa7146_write(dev, MC1, (MASK_13 | MASK_29));
+	// saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
+	// Enable RPS1                                                  (rFC p33)
+	saa7146_write(dev, MC1, (MASK_13 | MASK_29));
 
 
-        if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
-                return -ENOMEM;
+	if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
+		return -ENOMEM;
 
-        dprintk(2, "budget: %p\n", budget);
+	dprintk(2, "budget: %p\n", budget);
 
-        if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
-                kfree (budget);
-                return err;
-        }
+	if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
+		kfree (budget);
+		return err;
+	}
 
 
-        dev->ext_priv = budget;
+	dev->ext_priv = budget;
 
 	budget->dvb_adapter.priv = budget;
 	frontend_init(budget);
 
-        return 0;
+	return 0;
 }
 
 static int budget_patch_detach (struct saa7146_dev* dev)
 {
-        struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
-        int err;
+	struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
+	int err;
 
 	if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
 
-        err = ttpci_budget_deinit (budget);
+	err = ttpci_budget_deinit (budget);
 
-        kfree (budget);
+	kfree (budget);
 
-        return err;
+	return err;
 }
 
 static int __init budget_patch_init(void)
@@ -727,20 +727,20 @@
 
 static void __exit budget_patch_exit(void)
 {
-        saa7146_unregister_extension(&budget_extension);
+	saa7146_unregister_extension(&budget_extension);
 }
 
 static struct saa7146_extension budget_extension = {
-        .name           = "budget_patch dvb\0",
-        .flags          = 0,
+	.name           = "budget_patch dvb\0",
+	.flags          = 0,
 
-        .module         = THIS_MODULE,
-        .pci_tbl        = pci_tbl,
-        .attach         = budget_patch_attach,
-        .detach         = budget_patch_detach,
+	.module         = THIS_MODULE,
+	.pci_tbl        = pci_tbl,
+	.attach         = budget_patch_attach,
+	.detach         = budget_patch_detach,
 
-        .irq_mask       = MASK_10,
-        .irq_func       = ttpci_budget_irq10_handler,
+	.irq_mask       = MASK_10,
+	.irq_func       = ttpci_budget_irq10_handler,
 };
 
 module_init(budget_patch_init);
@@ -749,4 +749,4 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
 MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 "
-                   "based so-called Budget Patch cards");
+		   "based so-called Budget Patch cards");
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c
index 4fd8bbc..fafe640 100644
--- a/drivers/media/dvb/ttpci/budget.c
+++ b/drivers/media/dvb/ttpci/budget.c
@@ -256,7 +256,7 @@
 	buf[2] = ((div & 0x18000) >> 10) | 0x95;
 	buf[3] = (pwr << 6) | 0x30;
 
-        // NOTE: since we're using a prescaler of 2, we set the
+	// NOTE: since we're using a prescaler of 2, we set the
 	// divisor frequency to 62.5kHz and divide by 125 above
 
 	if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
@@ -565,7 +565,7 @@
 	struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
 				 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
 
-        if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
+	if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
 		pwm = 0x48;
 
 	return pwm;
@@ -593,7 +593,7 @@
 		budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
 		if (budget->dvb_frontend) {
 			budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
-		        budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
+			budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
 			budget->dvb_frontend->ops->set_tone = budget_set_tone;
 			break;
 		}
@@ -738,7 +738,7 @@
 
 static struct saa7146_extension budget_extension = {
 	.name		= "budget dvb\0",
-	.flags		= 0,
+	.flags		= SAA7146_I2C_SHORT_DELAY,
 
 	.module		= THIS_MODULE,
 	.pci_tbl	= pci_tbl,
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h
index c6ef496b..c8d48cf 100644
--- a/drivers/media/dvb/ttpci/budget.h
+++ b/drivers/media/dvb/ttpci/budget.h
@@ -19,7 +19,7 @@
 #endif
 
 #define dprintk(level,args...) \
-            do { if ((budget_debug & level)) { printk("%s: %s(): ",__stringify(KBUILD_MODNAME), __FUNCTION__); printk(args); } } while (0)
+	    do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __FUNCTION__); printk(args); } } while (0)
 
 struct budget_info {
 	char *name;
diff --git a/drivers/media/dvb/ttpci/fdump.c b/drivers/media/dvb/ttpci/fdump.c
index 0b478db..c90001d 100644
--- a/drivers/media/dvb/ttpci/fdump.c
+++ b/drivers/media/dvb/ttpci/fdump.c
@@ -36,7 +36,7 @@
     }
 
     fprintf(fd_out, "\n};\n\n");
-    
+
     fclose(fd_in);
     fclose(fd_out);
 
diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c
index e9a8457..18aa22b 100644
--- a/drivers/media/dvb/ttpci/ttpci-eeprom.c
+++ b/drivers/media/dvb/ttpci/ttpci-eeprom.c
@@ -13,7 +13,7 @@
     Holger Waechtler	Convergence
 
     Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de>
-                            Metzler Brothers Systementwicklung GbR
+		            Metzler Brothers Systementwicklung GbR
 
     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
@@ -37,6 +37,7 @@
 #include <linux/string.h>
 #include <linux/i2c.h>
 
+#include "ttpci-eeprom.h"
 
 #if 1
 #define dprintk(x...) do { printk(x); } while (0)
@@ -47,41 +48,41 @@
 
 static int check_mac_tt(u8 *buf)
 {
-        int i;
-        u16 tmp = 0xffff;
+	int i;
+	u16 tmp = 0xffff;
 
-        for (i = 0; i < 8; i++) {
-                tmp  = (tmp << 8) | ((tmp >> 8) ^ buf[i]);
-                tmp ^= (tmp >> 4) & 0x0f;
-                tmp ^= (tmp << 12) ^ ((tmp & 0xff) << 5);
-        }
-        tmp ^= 0xffff;
-        return (((tmp >> 8) ^ buf[8]) | ((tmp & 0xff) ^ buf[9]));
+	for (i = 0; i < 8; i++) {
+		tmp  = (tmp << 8) | ((tmp >> 8) ^ buf[i]);
+		tmp ^= (tmp >> 4) & 0x0f;
+		tmp ^= (tmp << 12) ^ ((tmp & 0xff) << 5);
+	}
+	tmp ^= 0xffff;
+	return (((tmp >> 8) ^ buf[8]) | ((tmp & 0xff) ^ buf[9]));
 }
 
 static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC)
 {
-        u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c,
+	u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c,
 		       0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6,
 		       0x1d, 0x36, 0x64, 0x78};
-        u8 data[20];
-        int i;
+	u8 data[20];
+	int i;
 
 	/* In case there is a sig check failure have the orig contents available */
 	memcpy(data, encodedMAC, 20);
 
 	for (i = 0; i < 20; i++)
-                data[i] ^= xor[i];
-        for (i = 0; i < 10; i++)
-                data[i] = ((data[2 * i + 1] << 8) | data[2 * i])
+		data[i] ^= xor[i];
+	for (i = 0; i < 10; i++)
+		data[i] = ((data[2 * i + 1] << 8) | data[2 * i])
 			>> ((data[2 * i + 1] >> 6) & 3);
 
-        if (check_mac_tt(data))
-                return -ENODEV;
+	if (check_mac_tt(data))
+		return -ENODEV;
 
 	decodedMAC[0] = data[2]; decodedMAC[1] = data[1]; decodedMAC[2] = data[0];
 	decodedMAC[3] = data[6]; decodedMAC[4] = data[5]; decodedMAC[5] = data[4];
-        return 0;
+	return 0;
 }
 
 static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC)
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index fd53d60..104df61 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -225,8 +225,8 @@
 
 	err = ttusb_result(ttusb, b, 0x20);
 
-        /* check if the i2c transaction was successful */
-        if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
+	/* check if the i2c transaction was successful */
+	if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
 
 	if (rcv_len > 0) {
 
@@ -489,27 +489,27 @@
 
 static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 {
-        struct  ttusb* ttusb = (struct ttusb*)  fe->dvb->priv;
-        int ret;
-        u8 data[1];
-        struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
+	struct  ttusb* ttusb = (struct ttusb*)  fe->dvb->priv;
+	int ret;
+	u8 data[1];
+	struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) };
 
-        switch(voltage) {
-        case SEC_VOLTAGE_OFF:
-                data[0] = 0x00;
-                break;
-        case SEC_VOLTAGE_13:
-                data[0] = 0x44;
-                break;
-        case SEC_VOLTAGE_18:
-                data[0] = 0x4c;
-                break;
-        default:
-                return -EINVAL;
-        };
+	switch(voltage) {
+	case SEC_VOLTAGE_OFF:
+		data[0] = 0x00;
+		break;
+	case SEC_VOLTAGE_13:
+		data[0] = 0x44;
+		break;
+	case SEC_VOLTAGE_18:
+		data[0] = 0x4c;
+		break;
+	default:
+		return -EINVAL;
+	};
 
-        ret = i2c_transfer(&ttusb->i2c_adap, &msg, 1);
-        return (ret != 1) ? -EIO : 0;
+	ret = i2c_transfer(&ttusb->i2c_adap, &msg, 1);
+	return (ret != 1) ? -EIO : 0;
 }
 
 static int ttusb_update_lnb(struct ttusb *ttusb)
@@ -1184,45 +1184,45 @@
 };
 
 static u8 alps_bsbe1_inittab[] = {
-        0x01, 0x15,
-        0x02, 0x30,
-        0x03, 0x00,
-        0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
-        0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */
-        0x06, 0x40,             /* DAC not used, set to high impendance mode */
-        0x07, 0x00,             /* DAC LSB */
-        0x08, 0x40,             /* DiSEqC off, LNB power on OP2/LOCK pin on */
-        0x09, 0x00,             /* FIFO */
-        0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
-        0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */
-        0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */
-        0x10, 0x3f,             // AGC2  0x3d
-        0x11, 0x84,
-        0x12, 0xb9,
-        0x15, 0xc9,             // lock detector threshold
-        0x16, 0x00,
-        0x17, 0x00,
-        0x18, 0x00,
-        0x19, 0x00,
-        0x1a, 0x00,
-        0x1f, 0x50,
-        0x20, 0x00,
-        0x21, 0x00,
-        0x22, 0x00,
-        0x23, 0x00,
-        0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0
-        0x29, 0x1e,             // 1/2 threshold
-        0x2a, 0x14,             // 2/3 threshold
-        0x2b, 0x0f,             // 3/4 threshold
-        0x2c, 0x09,             // 5/6 threshold
-        0x2d, 0x05,             // 7/8 threshold
-        0x2e, 0x01,
-        0x31, 0x1f,             // test all FECs
-        0x32, 0x19,             // viterbi and synchro search
-        0x33, 0xfc,             // rs control
-        0x34, 0x93,             // error control
-        0x0f, 0x92,
-        0xff, 0xff
+	0x01, 0x15,
+	0x02, 0x30,
+	0x03, 0x00,
+	0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
+	0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */
+	0x06, 0x40,             /* DAC not used, set to high impendance mode */
+	0x07, 0x00,             /* DAC LSB */
+	0x08, 0x40,             /* DiSEqC off, LNB power on OP2/LOCK pin on */
+	0x09, 0x00,             /* FIFO */
+	0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
+	0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */
+	0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */
+	0x10, 0x3f,             // AGC2  0x3d
+	0x11, 0x84,
+	0x12, 0xb9,
+	0x15, 0xc9,             // lock detector threshold
+	0x16, 0x00,
+	0x17, 0x00,
+	0x18, 0x00,
+	0x19, 0x00,
+	0x1a, 0x00,
+	0x1f, 0x50,
+	0x20, 0x00,
+	0x21, 0x00,
+	0x22, 0x00,
+	0x23, 0x00,
+	0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0
+	0x29, 0x1e,             // 1/2 threshold
+	0x2a, 0x14,             // 2/3 threshold
+	0x2b, 0x0f,             // 3/4 threshold
+	0x2c, 0x09,             // 5/6 threshold
+	0x2d, 0x05,             // 7/8 threshold
+	0x2e, 0x01,
+	0x31, 0x1f,             // test all FECs
+	0x32, 0x19,             // viterbi and synchro search
+	0x33, 0xfc,             // rs control
+	0x34, 0x93,             // error control
+	0x0f, 0x92,
+	0xff, 0xff
 };
 
 static u8 alps_bsru6_inittab[] = {
@@ -1350,7 +1350,7 @@
 	u32 div;
 	struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
 
-        div = params->frequency / 125;
+	div = params->frequency / 125;
 
 	buf[0] = (div >> 8) & 0x7f;
 	buf[1] = div & 0xff;
@@ -1487,7 +1487,7 @@
 
 	udev = interface_to_usbdev(intf);
 
-        if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
+	if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
 
 	if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
 		return -ENOMEM;
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h b/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h
index 95ee799..8c3cd54 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-dspbootcode.h
@@ -2,1643 +2,1643 @@
 #include <asm/types.h>
 
 static u8 dsp_bootcode [] = {
-	0x08, 0xaa, 0x00, 0x18, 0x00, 0x03, 0x08, 0x00, 
-	0x00, 0x10, 0x00, 0x00, 0x01, 0x80, 0x18, 0x5f, 
-	0x00, 0x00, 0x01, 0x80, 0x77, 0x18, 0x2a, 0xeb, 
-	0x6b, 0xf8, 0x00, 0x18, 0x03, 0xff, 0x68, 0xf8, 
-	0x00, 0x18, 0xff, 0xfe, 0xf7, 0xb8, 0xf7, 0xbe, 
-	0xf6, 0xb9, 0xf4, 0xa0, 0xf6, 0xb7, 0xf6, 0xb5, 
-	0xf6, 0xb6, 0xf0, 0x20, 0x19, 0xdf, 0xf1, 0x00, 
-	0x00, 0x01, 0xf8, 0x4d, 0x01, 0xab, 0xf6, 0xb8, 
-	0xf0, 0x20, 0x19, 0xdf, 0xf0, 0x73, 0x01, 0xa5, 
-	0x7e, 0xf8, 0x00, 0x12, 0xf0, 0x00, 0x00, 0x01, 
-	0x47, 0xf8, 0x00, 0x11, 0x7e, 0x92, 0x00, 0xf8, 
-	0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x7e, 0xf8, 
-	0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x6c, 0x89, 
-	0x01, 0x9a, 0xf7, 0xb8, 0xee, 0xfc, 0xf0, 0x20, 
-	0xff, 0xff, 0xf1, 0x00, 0x00, 0x01, 0xf8, 0x4d, 
-	0x01, 0xbf, 0xf2, 0x73, 0x01, 0xb9, 0x4e, 0x02, 
-	0xf4, 0x95, 0xf5, 0xe3, 0x56, 0x02, 0x7e, 0x00, 
-	0x11, 0x00, 0xfa, 0x4c, 0x01, 0xb7, 0x6b, 0x03, 
-	0x00, 0x01, 0xf6, 0xb8, 0xee, 0x04, 0xf0, 0x74, 
-	0x0d, 0xa7, 0xf0, 0x74, 0x01, 0xc5, 0x4a, 0x11, 
-	0x4a, 0x16, 0x72, 0x11, 0x2a, 0xe6, 0x10, 0xf8, 
-	0x00, 0x11, 0xfa, 0x45, 0x01, 0xdb, 0xf4, 0x95, 
-	0xee, 0xff, 0x48, 0x11, 0xf0, 0x00, 0x2a, 0xc6, 
-	0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0xee, 
-	0xff, 0xff, 0xf4, 0xe3, 0x6c, 0xe9, 0xff, 0xff, 
-	0x01, 0xd5, 0x10, 0xf8, 0x2a, 0xe7, 0xf8, 0x45, 
-	0x01, 0xe2, 0x10, 0xf8, 0x2a, 0xe7, 0xf4, 0xe3, 
-	0xf0, 0x74, 0x01, 0xff, 0xee, 0x01, 0x8a, 0x16, 
-	0x8a, 0x11, 0xfc, 0x00, 0xf7, 0xb8, 0xe9, 0x20, 
-	0x4a, 0x11, 0x09, 0xf8, 0x2a, 0xe6, 0xf8, 0x4e, 
-	0x01, 0xf3, 0xf2, 0x73, 0x01, 0xfd, 0xf4, 0x95, 
-	0xe8, 0x01, 0x72, 0x11, 0x2a, 0xe6, 0x49, 0x11, 
-	0x80, 0xe1, 0x2a, 0xc6, 0xf3, 0x00, 0x00, 0x01, 
-	0xe8, 0x00, 0x81, 0xf8, 0x2a, 0xe6, 0x8a, 0x11, 
-	0xfc, 0x00, 0xf4, 0x95, 0xf0, 0x73, 0x02, 0x00, 
-	0x10, 0xf8, 0x2a, 0x0f, 0xfc, 0x00, 0x4a, 0x11, 
-	0xf0, 0x74, 0x02, 0x02, 0x80, 0xf8, 0x2a, 0x10, 
-	0x73, 0x08, 0x00, 0x09, 0x40, 0xf8, 0x2a, 0x15, 
-	0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-	0x03, 0xe8, 0xf5, 0xa9, 0xf8, 0x30, 0x02, 0x21, 
-	0x71, 0xf8, 0x2a, 0x10, 0x2a, 0x15, 0x56, 0xf8, 
-	0x2a, 0x0c, 0xf0, 0xe3, 0x4e, 0xf8, 0x2a, 0x16, 
-	0xe8, 0x00, 0x4e, 0xf8, 0x2a, 0x0c, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d, 
-	0x68, 0xf8, 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 
-	0x00, 0x07, 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 
-	0xff, 0xfc, 0x6b, 0xf8, 0x2a, 0x0f, 0x00, 0x01, 
-	0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x06, 0xf4, 0xeb, 
-	0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x0f, 0x00, 0x00, 
-	0x76, 0x00, 0x00, 0x00, 0xfb, 0x80, 0x19, 0x4c, 
-	0xf4, 0x95, 0xe8, 0x00, 0x80, 0xf8, 0x2a, 0x11, 
-	0xf9, 0x80, 0x19, 0x07, 0x80, 0xf8, 0x2a, 0x0e, 
-	0xf9, 0x80, 0x16, 0x66, 0x76, 0x00, 0x2a, 0x12, 
-	0x10, 0xf8, 0x2a, 0x11, 0xf9, 0x80, 0x18, 0xe3, 
-	0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x66, 
-	0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x87, 
-	0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf6, 0xb8, 
-	0xf4, 0x95, 0xf0, 0x20, 0x80, 0x00, 0x11, 0xf8, 
-	0x2a, 0x5a, 0xf8, 0x4d, 0x02, 0x93, 0x11, 0xf8, 
-	0x2a, 0x9f, 0xf8, 0x4c, 0x02, 0x7c, 0x77, 0x12, 
-	0x2a, 0x39, 0x49, 0x12, 0x01, 0xf8, 0x2a, 0x9f, 
-	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81, 
-	0x00, 0x11, 0x6c, 0xe1, 0xff, 0xab, 0x02, 0x93, 
-	0x6b, 0xf8, 0x2a, 0x9f, 0x00, 0x01, 0xe9, 0x05, 
-	0x01, 0xe2, 0x00, 0x03, 0x81, 0xf8, 0x2a, 0xa0, 
-	0xf0, 0x73, 0x02, 0x95, 0x72, 0x11, 0x2a, 0x9f, 
-	0xf4, 0x95, 0x10, 0xe1, 0x2a, 0x39, 0x6b, 0xf8, 
-	0x2a, 0x9f, 0x00, 0x01, 0x11, 0xf8, 0x2a, 0x9f, 
-	0x09, 0xf8, 0x2a, 0xa0, 0xf8, 0x4c, 0x02, 0x93, 
-	0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00, 0x76, 0xf8, 
-	0x2a, 0x9f, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa0, 
-	0x00, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x48, 0x11, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-	0x10, 0xf8, 0x2a, 0x5a, 0xf8, 0x44, 0x02, 0xb2, 
-	0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x01, 0xf0, 0x74, 
-	0x02, 0x58, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-	0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30, 0x02, 0xb2, 
-	0x48, 0x11, 0xf0, 0x30, 0x00, 0xff, 0x80, 0x00, 
-	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0xd6, 
-	0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95, 
-	0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b, 
-	0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11, 
-	0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15, 
-	0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19, 
-	0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a, 
-	0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8, 
-	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-	0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe, 
-	0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xfd, 
-	0xf0, 0x74, 0x02, 0x58, 0x88, 0x11, 0xf4, 0x95, 
-	0x77, 0x10, 0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30, 
-	0x02, 0xef, 0x48, 0x11, 0xf0, 0x30, 0x00, 0xff, 
-	0x80, 0x00, 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 
-	0x18, 0xd6, 0xee, 0x03, 0x8a, 0x18, 0xf4, 0x95, 
-	0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d, 0x8a, 0x1a, 
-	0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e, 0x8a, 0x19, 
-	0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x15, 
-	0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12, 0x8a, 0x11, 
-	0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b, 
-	0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08, 0xf4, 0xeb, 
-	0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 
-	0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 
-	0x00, 0x01, 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2, 
-	0x00, 0x02, 0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1, 
-	0x00, 0x03, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 
-	0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95, 
-	0xf4, 0x95, 0x10, 0x81, 0x6f, 0xf8, 0x2a, 0x9e, 
-	0x0c, 0x88, 0xe8, 0xff, 0x18, 0xe1, 0x00, 0x01, 
-	0x1a, 0xf8, 0x2a, 0x9e, 0xf0, 0x30, 0x1f, 0xff, 
-	0x80, 0xf8, 0x2a, 0x9e, 0x8a, 0x11, 0xfc, 0x00, 
-	0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 
-	0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x11, 0xe2, 
-	0x00, 0x01, 0x81, 0xe1, 0x00, 0x01, 0x11, 0xe2, 
-	0x00, 0x02, 0x81, 0xe1, 0x00, 0x02, 0x76, 0xe1, 
-	0x00, 0x03, 0x00, 0x02, 0x48, 0x08, 0x6f, 0xe1, 
-	0x00, 0x04, 0x0c, 0x98, 0xf0, 0x30, 0x00, 0xff, 
-	0x80, 0xe1, 0x00, 0x05, 0x76, 0xe1, 0x00, 0x06, 
-	0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 
-	0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 
-	0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 0x00, 0x01, 
-	0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 0x00, 0x02, 
-	0x76, 0xe1, 0x00, 0x03, 0x00, 0x04, 0x48, 0x11, 
-	0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 0xf4, 0x95, 
-	0x77, 0x13, 0x2a, 0x76, 0xe9, 0x00, 0xe5, 0x98, 
-	0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 0x48, 0x0b, 
-	0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x03, 0x71, 
-	0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xf0, 
-	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81, 
-	0x00, 0x14, 0x71, 0xe1, 0x00, 0x01, 0x00, 0x15, 
-	0x49, 0x11, 0xf3, 0x00, 0x00, 0x02, 0x89, 0x11, 
-	0xe7, 0x82, 0x6d, 0xea, 0x00, 0x04, 0xe7, 0x83, 
-	0x6d, 0xeb, 0x00, 0x0a, 0x77, 0x1a, 0x00, 0x05, 
-	0xf0, 0x72, 0x03, 0xaa, 0x11, 0x81, 0xf2, 0xe8, 
-	0x80, 0x82, 0xe9, 0xff, 0x19, 0xe1, 0x00, 0x01, 
-	0xf1, 0xa0, 0x81, 0x92, 0x11, 0xe1, 0x00, 0x0c, 
-	0xf2, 0xe8, 0x80, 0x83, 0xe9, 0xff, 0x19, 0xe1, 
-	0x00, 0x0d, 0xf1, 0xa0, 0x81, 0x93, 0x6d, 0xe9, 
-	0x00, 0x02, 0x48, 0x18, 0x49, 0x18, 0x70, 0x00, 
-	0x00, 0x15, 0xf0, 0x00, 0x00, 0x04, 0xf3, 0x00, 
-	0x00, 0x0a, 0x80, 0x01, 0x81, 0x02, 0xf2, 0x74, 
-	0x0e, 0x54, 0xf4, 0x95, 0x48, 0x14, 0xee, 0x10, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf0, 0x74, 
-	0x0c, 0x5e, 0x80, 0xf8, 0x2a, 0x5c, 0x77, 0x12, 
-	0x2a, 0x39, 0x76, 0x82, 0x00, 0x55, 0x77, 0x11, 
-	0x2a, 0x18, 0x10, 0xe1, 0x00, 0x01, 0x80, 0xe2, 
-	0x00, 0x01, 0x10, 0xe1, 0x00, 0x02, 0x80, 0xe2, 
-	0x00, 0x02, 0x76, 0xe2, 0x00, 0x03, 0x00, 0x1c, 
-	0xf6, 0xb8, 0x56, 0xf8, 0x2a, 0x16, 0xf0, 0xf0, 
-	0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x07, 0x56, 0xf8, 
-	0x2a, 0x16, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80, 
-	0x80, 0xe2, 0x00, 0x06, 0x56, 0xf8, 0x2a, 0x16, 
-	0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 
-	0x00, 0x05, 0x57, 0xf8, 0x2a, 0x16, 0xe8, 0xff, 
-	0xf2, 0x80, 0x80, 0xe2, 0x00, 0x04, 0x56, 0xf8, 
-	0x27, 0x6c, 0xf0, 0xf0, 0xf0, 0xf8, 0x80, 0xe2, 
-	0x00, 0x0b, 0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf0, 
-	0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0a, 
-	0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf8, 0xe8, 0xff, 
-	0xf2, 0x80, 0x80, 0xe2, 0x00, 0x09, 0xe8, 0xff, 
-	0x57, 0xf8, 0x27, 0x6c, 0xf2, 0x80, 0x80, 0xe2, 
-	0x00, 0x08, 0x56, 0xf8, 0x27, 0x6a, 0xf0, 0xf0, 
-	0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x0f, 0x56, 0xf8, 
-	0x27, 0x6a, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80, 
-	0x80, 0xe2, 0x00, 0x0e, 0x56, 0xf8, 0x27, 0x6a, 
-	0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 
-	0x00, 0x0d, 0x57, 0xf8, 0x27, 0x6a, 0xe8, 0xff, 
-	0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0c, 0x76, 0xe2, 
-	0x00, 0x13, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x12, 
-	0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x5c, 0x0c, 0x58, 
-	0x80, 0xe2, 0x00, 0x11, 0xe8, 0xff, 0x18, 0xf8, 
-	0x2a, 0x5c, 0x80, 0xe2, 0x00, 0x10, 0x76, 0xe2, 
-	0x00, 0x17, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x16, 
-	0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x9e, 0x0c, 0x58, 
-	0x80, 0xe2, 0x00, 0x15, 0xe8, 0xff, 0x18, 0xf8, 
-	0x2a, 0x9e, 0x80, 0xe2, 0x00, 0x14, 0x76, 0xe2, 
-	0x00, 0x1b, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1a, 
-	0x00, 0x00, 0x76, 0xe2, 0x00, 0x19, 0x00, 0x00, 
-	0x70, 0xe2, 0x00, 0x18, 0x27, 0x6e, 0x76, 0xe2, 
-	0x00, 0x1f, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1e, 
-	0x00, 0x00, 0x76, 0xe2, 0x00, 0x1d, 0x00, 0x00, 
-	0x76, 0xe2, 0x00, 0x1c, 0x00, 0x00, 0x76, 0xe2, 
-	0x00, 0x20, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-	0x10, 0xf8, 0x2a, 0x38, 0xf8, 0x45, 0x04, 0xed, 
-	0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x02, 
-	0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x08, 
-	0x6d, 0xe9, 0xff, 0xdf, 0xf6, 0xa9, 0xf8, 0x20, 
-	0x04, 0x75, 0xf0, 0x73, 0x04, 0x7d, 0xf0, 0x10, 
-	0x00, 0x21, 0xf0, 0x00, 0x1a, 0x83, 0x48, 0x08, 
-	0x7e, 0xf8, 0x00, 0x08, 0xf4, 0xe2, 0xf0, 0x74, 
-	0x03, 0x0a, 0xf0, 0x73, 0x04, 0xea, 0x48, 0x12, 
-	0xf2, 0x74, 0x03, 0x23, 0xf0, 0x00, 0x00, 0x04, 
-	0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 
-	0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 
-	0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48, 
-	0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x69, 
-	0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36, 
-	0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 
-	0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48, 
-	0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x41, 
-	0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36, 
-	0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0x57, 
-	0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8, 0x2a, 0x1c, 
-	0xf0, 0x74, 0x12, 0xa4, 0xf2, 0x74, 0x03, 0x36, 
-	0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea, 
-	0x48, 0x12, 0xf2, 0x74, 0x03, 0x80, 0xf0, 0x00, 
-	0x00, 0x04, 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 
-	0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8, 
-	0x2a, 0x1c, 0xf0, 0x74, 0x12, 0xc5, 0xf2, 0x74, 
-	0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73, 
-	0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 0xe8, 0xff, 
-	0x6f, 0xe1, 0x00, 0x06, 0x0d, 0x48, 0x18, 0xe1, 
-	0x00, 0x07, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0xf2, 0xa0, 0x70, 0x00, 0x00, 0x12, 0x80, 0x01, 
-	0x10, 0xe1, 0x00, 0x04, 0xf0, 0x74, 0x0e, 0x7a, 
-	0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 
-	0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0xbc, 
-	0x76, 0xf8, 0x2a, 0x38, 0x00, 0x00, 0xee, 0x02, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 
-	0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 
-	0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 
-	0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 
-	0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x09, 
-	0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 
-	0xf4, 0x95, 0x77, 0x13, 0x2a, 0x86, 0xe9, 0x00, 
-	0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 
-	0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 
-	0x05, 0x0a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 
-	0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-	0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 
-	0x77, 0x13, 0x2a, 0x18, 0x10, 0xe3, 0x00, 0x01, 
-	0x80, 0xe1, 0x00, 0x01, 0x10, 0xe3, 0x00, 0x02, 
-	0x80, 0xe1, 0x00, 0x02, 0x13, 0xe3, 0x00, 0x03, 
-	0x81, 0xe1, 0x00, 0x03, 0x48, 0x11, 0x77, 0x11, 
-	0x00, 0x00, 0xf8, 0x4d, 0x05, 0x44, 0xf0, 0x00, 
-	0x00, 0x04, 0x88, 0x12, 0x48, 0x13, 0xf0, 0x00, 
-	0x00, 0x04, 0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95, 
-	0xe5, 0x98, 0x6d, 0x91, 0xf6, 0xb8, 0x48, 0x11, 
-	0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x05, 0x3a, 
-	0xf0, 0x20, 0x2a, 0x39, 0x49, 0x11, 0xf5, 0x00, 
-	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x76, 0xe1, 
-	0x00, 0x04, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 
-	0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 
-	0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 
-	0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 
-	0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x0c, 
-	0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 
-	0xf4, 0x95, 0x77, 0x13, 0x2a, 0x7a, 0xe9, 0x00, 
-	0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 
-	0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 
-	0x05, 0x6a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 
-	0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-	0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 
-	0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 
-	0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 
-	0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 
-	0x00, 0x19, 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 
-	0x88, 0x12, 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x5d, 
-	0xe9, 0x00, 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 
-	0xf6, 0xb8, 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 
-	0xf8, 0x43, 0x05, 0x93, 0x76, 0x82, 0x00, 0xaa, 
-	0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 
-	0x4a, 0x11, 0x88, 0x11, 0x10, 0xf8, 0x2a, 0x38, 
-	0xf8, 0x44, 0x05, 0xe3, 0x10, 0xf8, 0x2a, 0xa1, 
-	0xf8, 0x44, 0x05, 0xba, 0x6c, 0xe1, 0xff, 0x56, 
-	0x05, 0xe3, 0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95, 
-	0x70, 0xe2, 0x2a, 0x18, 0x00, 0x11, 0x6b, 0xf8, 
-	0x2a, 0xa1, 0x00, 0x01, 0xf0, 0x73, 0x05, 0xe3, 
-	0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95, 0x70, 0xe2, 
-	0x2a, 0x18, 0x00, 0x11, 0x10, 0xf8, 0x2a, 0xa1, 
-	0xf0, 0x00, 0x00, 0x01, 0x88, 0x12, 0xf4, 0x95, 
-	0xf4, 0x95, 0x6e, 0xe2, 0xff, 0xfc, 0x05, 0xd1, 
-	0x73, 0x12, 0x2a, 0xa1, 0x48, 0x11, 0xf0, 0x00, 
-	0x00, 0x05, 0x80, 0xf8, 0x2a, 0xa2, 0x10, 0xf8, 
-	0x2a, 0xa1, 0x08, 0xf8, 0x2a, 0xa2, 0xf8, 0x44, 
-	0x05, 0xe3, 0x6c, 0xe1, 0xff, 0xab, 0x05, 0xdd, 
-	0x76, 0xf8, 0x2a, 0x38, 0x00, 0x01, 0x76, 0xf8, 
-	0x2a, 0xa1, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa2, 
-	0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95, 
-	0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b, 
-	0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11, 
-	0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15, 
-	0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19, 
-	0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a, 
-	0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8, 
-	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-	0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe, 
-	0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xff, 
-	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0x04, 
-	0xf0, 0x74, 0x05, 0xa2, 0xee, 0x01, 0x8a, 0x18, 
-	0xf4, 0x95, 0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d, 
-	0x8a, 0x1a, 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e, 
-	0x8a, 0x19, 0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16, 
-	0x8a, 0x15, 0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12, 
-	0x8a, 0x11, 0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c, 
-	0x8a, 0x0b, 0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08, 
-	0xf4, 0xeb, 0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x38, 
-	0x00, 0x00, 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00, 
-	0xe8, 0x01, 0x4e, 0x00, 0xfb, 0x80, 0x17, 0xd6, 
-	0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x2a, 0x5b, 
-	0x76, 0x00, 0x2a, 0x8f, 0xf9, 0x80, 0x16, 0xaa, 
-	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x5c, 
-	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x6f, 
-	0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1a, 
-	0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1a, 
-	0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1b, 
-	0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1b, 
-	0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 
-	0x13, 0x02, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d, 
-	0x06, 0x6a, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 
-	0xf4, 0x95, 0xf0, 0x72, 0x06, 0x69, 0x1c, 0x91, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 
-	0x12, 0x03, 0x11, 0x02, 0xf8, 0x45, 0x06, 0x79, 
-	0xf0, 0x10, 0x00, 0x01, 0x88, 0x1a, 0xf4, 0x95, 
-	0xf0, 0x72, 0x06, 0x78, 0x81, 0x91, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 
-	0x00, 0x11, 0x11, 0x03, 0x61, 0xf8, 0x00, 0x11, 
-	0x00, 0x01, 0xf8, 0x30, 0x06, 0x91, 0xf6, 0xb8, 
-	0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11, 
-	0xf3, 0xe8, 0xe8, 0xff, 0x18, 0x81, 0xf1, 0xa0, 
-	0x81, 0x81, 0xf0, 0x73, 0x06, 0x9d, 0xf6, 0xb8, 
-	0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11, 
-	0xf3, 0x30, 0x00, 0xff, 0xf0, 0x20, 0xff, 0x00, 
-	0x18, 0x81, 0xf1, 0xa0, 0x81, 0x81, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x11, 0x02, 
-	0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20, 
-	0x06, 0xb1, 0x49, 0x0b, 0xf6, 0x1f, 0x88, 0x11, 
-	0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf2, 0x73, 
-	0x06, 0xb8, 0xf0, 0x30, 0x00, 0xff, 0x49, 0x0b, 
-	0xf6, 0x1f, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 
-	0x12, 0x81, 0xf4, 0x78, 0x8a, 0x11, 0xfc, 0x00, 
-	0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x12, 
-	0x13, 0x03, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d, 
-	0x06, 0xcc, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 
-	0xf4, 0x95, 0xf0, 0x72, 0x06, 0xcb, 0x11, 0x92, 
-	0xf2, 0xc0, 0x81, 0x91, 0x8a, 0x11, 0xfc, 0x00, 
-	0x88, 0x12, 0x12, 0x02, 0x71, 0x01, 0x00, 0x13, 
-	0xf8, 0x45, 0x06, 0xdb, 0xf0, 0x10, 0x00, 0x01, 
-	0x88, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x06, 0xda, 
-	0xe5, 0x98, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-	0x88, 0x11, 0x11, 0x04, 0x10, 0x06, 0x71, 0x05, 
-	0x00, 0x12, 0x61, 0xf8, 0x00, 0x12, 0x00, 0x01, 
-	0xf8, 0x20, 0x06, 0xea, 0xf0, 0x00, 0x00, 0x01, 
-	0xf6, 0xb8, 0xf0, 0x00, 0x00, 0x01, 0x6f, 0xf8, 
-	0x00, 0x12, 0x0f, 0x1f, 0x48, 0x08, 0x81, 0x00, 
-	0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xba, 
-	0xf4, 0x95, 0x48, 0x11, 0xee, 0x02, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x88, 0x12, 
-	0x11, 0x04, 0x10, 0x06, 0x71, 0x05, 0x00, 0x13, 
-	0x61, 0xf8, 0x00, 0x13, 0x00, 0x01, 0xf8, 0x20, 
-	0x07, 0x09, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00, 
-	0x00, 0x01, 0x88, 0x11, 0xf6, 0xb8, 0x6f, 0xf8, 
-	0x00, 0x13, 0x0f, 0x1f, 0x81, 0x00, 0x48, 0x11, 
-	0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xce, 
-	0xf4, 0x95, 0x48, 0x12, 0x48, 0x11, 0xf0, 0x30, 
-	0xff, 0xfe, 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 
-	0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xfc, 
-	0xf4, 0x95, 0x80, 0x02, 0x71, 0x08, 0x00, 0x16, 
-	0x10, 0x09, 0x71, 0x0b, 0x00, 0x17, 0x80, 0x03, 
-	0x71, 0x0a, 0x00, 0x11, 0x48, 0x17, 0xf8, 0x45, 
-	0x07, 0x3f, 0x70, 0x00, 0x00, 0x11, 0x10, 0x03, 
-	0xf0, 0x74, 0x06, 0x9f, 0x80, 0x01, 0x70, 0x00, 
-	0x00, 0x16, 0x10, 0x02, 0xf0, 0x74, 0x06, 0x7b, 
-	0x6d, 0x91, 0x6d, 0x96, 0x6c, 0xef, 0xff, 0xff, 
-	0x07, 0x2f, 0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-	0x10, 0xf8, 0x2a, 0xe8, 0x08, 0xf8, 0x2a, 0xe9, 
-	0xf8, 0x45, 0x07, 0x64, 0x76, 0x00, 0x00, 0x01, 
-	0x62, 0xf8, 0x2a, 0xe9, 0x00, 0x5e, 0xf2, 0x74, 
-	0x12, 0x0b, 0xf0, 0x00, 0x30, 0x40, 0x72, 0x11, 
-	0x2a, 0xe9, 0x77, 0x10, 0x00, 0x0f, 0xf5, 0xa9, 
-	0xf8, 0x20, 0x07, 0x61, 0x6b, 0xf8, 0x2a, 0xe9, 
-	0x00, 0x01, 0xf0, 0x73, 0x07, 0x64, 0x76, 0xf8, 
-	0x2a, 0xe9, 0x00, 0x00, 0xee, 0x02, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xe8, 0x00, 
-	0x75, 0xf8, 0x00, 0x08, 0x00, 0x08, 0xe8, 0x00, 
-	0x75, 0xf8, 0x00, 0x08, 0x00, 0x09, 0xf6, 0xb8, 
-	0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f, 0x75, 0xf8, 
-	0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20, 0x0c, 0x30, 
-	0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c, 0x76, 0xf8, 
-	0x2a, 0xe8, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xe9, 
-	0x00, 0x00, 0x6c, 0x81, 0x07, 0x92, 0x76, 0xf8, 
-	0x2a, 0xea, 0x00, 0x00, 0xfb, 0x80, 0x16, 0x76, 
-	0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00, 0x75, 0xf8, 
-	0x00, 0x08, 0x00, 0x00, 0xf0, 0x73, 0x07, 0xa8, 
-	0x76, 0xf8, 0x2a, 0xea, 0x00, 0x01, 0xfb, 0x80, 
-	0x16, 0x66, 0xf4, 0x95, 0xe8, 0x10, 0xfb, 0x80, 
-	0x16, 0x87, 0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00, 
-	0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0xf6, 0xb8, 
-	0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff, 0x75, 0xf8, 
-	0x00, 0x08, 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 
-	0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 
-	0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8, 
-	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-	0x10, 0xf8, 0x2a, 0xea, 0xf8, 0x45, 0x07, 0xe1, 
-	0x10, 0xf8, 0x2a, 0xe8, 0xf0, 0x00, 0x00, 0x01, 
-	0xf0, 0x30, 0x00, 0x0f, 0x80, 0xf8, 0x2a, 0xe8, 
-	0x10, 0xf8, 0x2a, 0xe8, 0xf8, 0x44, 0x07, 0xd6, 
-	0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f, 
-	0x75, 0xf8, 0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20, 
-	0x0c, 0x30, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c, 
-	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 
-	0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff, 
-	0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0x8a, 0x1d, 
-	0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0a, 0x8a, 0x09, 
-	0x8a, 0x08, 0xf4, 0xeb, 0xee, 0xff, 0xf2, 0x74, 
-	0x07, 0x67, 0xf4, 0x95, 0xe8, 0x01, 0xee, 0x01, 
-	0xfc, 0x00, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8, 
-	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-	0x8a, 0x1d, 0x8a, 0x07, 0xf4, 0xeb, 0x4a, 0x11, 
-	0x77, 0x11, 0x00, 0x28, 0x76, 0x81, 0x24, 0x00, 
-	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-	0xf2, 0x74, 0x07, 0x67, 0xf4, 0x95, 0xe8, 0x00, 
-	0x77, 0x11, 0x00, 0x1d, 0x68, 0x81, 0x00, 0x7f, 
-	0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0x80, 
-	0x77, 0x11, 0x00, 0x1d, 0xf0, 0x30, 0x01, 0x00, 
-	0x1a, 0x81, 0x80, 0x81, 0xf0, 0x74, 0x0a, 0x33, 
-	0xf0, 0x74, 0x11, 0xac, 0xf9, 0x80, 0x13, 0x25, 
-	0xf9, 0x80, 0x16, 0x53, 0xf9, 0x80, 0x17, 0x82, 
-	0xf0, 0x74, 0x06, 0x2f, 0xf9, 0x80, 0x14, 0xb2, 
-	0xf9, 0x80, 0x19, 0x10, 0xf0, 0x74, 0x0d, 0xe3, 
-	0xf0, 0x74, 0x07, 0xe8, 0xf0, 0x74, 0x02, 0x36, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x60, 0xf8, 
-	0x27, 0x7b, 0xff, 0xff, 0xf8, 0x30, 0x08, 0x39, 
-	0x71, 0xf8, 0x27, 0x7b, 0x27, 0x79, 0x60, 0xf8, 
-	0x27, 0x79, 0xff, 0xff, 0xf8, 0x30, 0x08, 0xb2, 
-	0x10, 0xf8, 0x29, 0x86, 0x08, 0xf8, 0x27, 0x79, 
-	0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11, 0xf4, 0x95, 
-	0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x30, 
-	0x08, 0x58, 0x10, 0xf8, 0x27, 0x79, 0x08, 0xf8, 
-	0x27, 0x7a, 0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11, 
-	0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 
-	0xf8, 0x20, 0x08, 0x63, 0x76, 0xf8, 0x27, 0x79, 
-	0xff, 0xff, 0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff, 
-	0xf7, 0xb8, 0xf2, 0x73, 0x08, 0xd9, 0xf0, 0x20, 
-	0xff, 0xff, 0xf6, 0xb8, 0x56, 0xf8, 0x27, 0x74, 
-	0xf0, 0xf9, 0x88, 0x11, 0x56, 0xf8, 0x27, 0x72, 
-	0xf0, 0xf9, 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 
-	0xe7, 0x20, 0xf4, 0xa9, 0xf8, 0x30, 0x08, 0x8f, 
-	0xf1, 0x20, 0x27, 0x7c, 0x48, 0x11, 0xf6, 0x00, 
-	0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x83, 
-	0x08, 0xf8, 0x27, 0x79, 0xf0, 0x30, 0x7f, 0xff, 
-	0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 
-	0xf5, 0xab, 0xf8, 0x30, 0x08, 0x8f, 0x6d, 0x91, 
-	0x48, 0x11, 0xf0, 0x30, 0x01, 0xff, 0x88, 0x11, 
-	0xf4, 0x95, 0xe7, 0x20, 0xf7, 0xa9, 0xf8, 0x30, 
-	0x08, 0x74, 0x6d, 0x89, 0x48, 0x11, 0xf0, 0x30, 
-	0x01, 0xff, 0xf0, 0xe7, 0xf4, 0x95, 0x48, 0x08, 
-	0x4e, 0xf8, 0x27, 0x74, 0x48, 0x08, 0xf1, 0xf9, 
-	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1, 
-	0x27, 0x7c, 0x27, 0x7a, 0x60, 0xf8, 0x27, 0x7b, 
-	0xff, 0xff, 0xf8, 0x30, 0x08, 0xab, 0x48, 0x08, 
-	0x4e, 0xf8, 0x27, 0x72, 0x76, 0xf8, 0x27, 0x7b, 
-	0xff, 0xff, 0x76, 0xf8, 0x27, 0x79, 0xff, 0xff, 
-	0xf2, 0x73, 0x08, 0xd9, 0xf4, 0x95, 0xe8, 0x00, 
-	0x44, 0xf8, 0x27, 0x73, 0x40, 0xf8, 0x27, 0x75, 
-	0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-	0x80, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xd8, 
-	0xf6, 0xb8, 0x10, 0xf8, 0x27, 0x73, 0xf0, 0x00, 
-	0x80, 0x00, 0x48, 0x08, 0x4e, 0xf8, 0x27, 0x74, 
-	0x48, 0x08, 0xf0, 0xf9, 0x88, 0x11, 0xf4, 0x95, 
-	0xf4, 0x95, 0x71, 0xe1, 0x27, 0x7c, 0x27, 0x7a, 
-	0xf7, 0xb8, 0x57, 0xf8, 0x27, 0x74, 0xf0, 0x62, 
-	0xff, 0xff, 0xf0, 0x40, 0xff, 0x80, 0xf2, 0x80, 
-	0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfb, 
-	0x11, 0xf8, 0x27, 0x71, 0x09, 0xf8, 0x27, 0x73, 
-	0x89, 0x11, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 
-	0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xed, 0xf2, 0x73, 
-	0x09, 0x0e, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0x20, 
-	0x76, 0x00, 0x00, 0x41, 0xf0, 0x74, 0x12, 0xee, 
-	0x88, 0x16, 0xf4, 0x95, 0xf7, 0xb8, 0x6d, 0x96, 
-	0x10, 0xf8, 0x00, 0x16, 0xf8, 0x47, 0x09, 0x0a, 
-	0xe7, 0x61, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 
-	0x00, 0x80, 0x76, 0x02, 0x00, 0xff, 0x76, 0x03, 
-	0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 
-	0xe8, 0x00, 0x6c, 0xe9, 0xff, 0xff, 0x08, 0xfb, 
-	0x73, 0x16, 0x00, 0x0e, 0xf0, 0x66, 0x00, 0x41, 
-	0xee, 0x05, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 
-	0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x13, 
-	0xf6, 0xb8, 0x77, 0x11, 0x7f, 0xff, 0x57, 0xf8, 
-	0x27, 0x72, 0x48, 0x11, 0xf2, 0x80, 0xf0, 0x00, 
-	0x80, 0x00, 0x88, 0x11, 0xf6, 0x40, 0xf0, 0xe0, 
-	0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80, 0x80, 0xf8, 
-	0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x57, 0xf8, 
-	0x27, 0x72, 0x48, 0x12, 0xf2, 0x80, 0x88, 0x12, 
-	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x09, 0x38, 
-	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-	0xf0, 0x73, 0x09, 0x3d, 0xf0, 0x20, 0x80, 0x01, 
-	0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x70, 0x81, 
-	0x00, 0x13, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-	0xf0, 0x30, 0x7f, 0xff, 0x11, 0xf8, 0x29, 0x86, 
-	0xf5, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11, 
-	0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 
-	0xf8, 0x20, 0x09, 0x54, 0xf2, 0x73, 0x09, 0x67, 
-	0xf4, 0x95, 0xe8, 0x02, 0x6f, 0xf8, 0x27, 0x7a, 
-	0x0d, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11, 
-	0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 
-	0xf8, 0x20, 0x09, 0x64, 0xf2, 0x73, 0x09, 0x67, 
-	0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x27, 0x7b, 
-	0xe8, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-	0x11, 0xf8, 0x29, 0x86, 0xf5, 0x20, 0xf3, 0x30, 
-	0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-	0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x7a, 
-	0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x02, 
-	0x6f, 0xf8, 0x27, 0x7a, 0x0d, 0x20, 0xf3, 0x30, 
-	0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-	0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x8a, 
-	0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x01, 
-	0x80, 0xf8, 0x27, 0x79, 0xe8, 0x00, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 
-	0x00, 0x12, 0x88, 0x11, 0xf6, 0xb8, 0x57, 0xf8, 
-	0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80, 
-	0xf0, 0x00, 0x80, 0x00, 0x80, 0x81, 0x57, 0xf8, 
-	0x27, 0x72, 0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80, 
-	0x80, 0xf8, 0x27, 0x78, 0x77, 0x11, 0x80, 0x00, 
-	0x48, 0x11, 0x57, 0xf8, 0x27, 0x72, 0xf2, 0x80, 
-	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 
-	0x09, 0xb5, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 
-	0x00, 0x01, 0xf0, 0x73, 0x09, 0xba, 0xf0, 0x20, 
-	0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-	0x45, 0xf8, 0x27, 0x71, 0x43, 0xf8, 0x27, 0x73, 
-	0x83, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0xe7, 0x20, 
-	0xf6, 0xa9, 0xf8, 0x30, 0x09, 0xc9, 0xf2, 0x73, 
-	0x09, 0xe4, 0x77, 0x12, 0x00, 0x00, 0x57, 0xf8, 
-	0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80, 
-	0x49, 0x12, 0xf5, 0x00, 0xf3, 0x00, 0x80, 0x00, 
-	0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00, 0xf8, 0x30, 
-	0x09, 0xdc, 0xf1, 0x20, 0x80, 0x00, 0xf5, 0x20, 
-	0x89, 0x12, 0xf4, 0x95, 0x48, 0x12, 0x6f, 0xf8, 
-	0x27, 0x73, 0x0d, 0x00, 0xf4, 0x95, 0x49, 0x0b, 
-	0x4f, 0xf8, 0x27, 0x72, 0x8a, 0x11, 0xfe, 0x00, 
-	0x48, 0x12, 0xf4, 0x95, 0x4a, 0x11, 0x4a, 0x16, 
-	0x4a, 0x17, 0xee, 0xfc, 0xf4, 0x95, 0x71, 0x08, 
-	0x00, 0x16, 0x88, 0x17, 0xf0, 0x74, 0x08, 0x30, 
-	0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74, 
-	0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 
-	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0a, 0x0a, 
-	0xf2, 0x74, 0x08, 0xdb, 0xf4, 0x95, 0x48, 0x16, 
-	0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74, 
-	0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 
-	0x10, 0x02, 0x70, 0x01, 0x00, 0x11, 0x80, 0x00, 
-	0xf2, 0x74, 0x06, 0xce, 0xf4, 0x95, 0x48, 0x17, 
-	0x49, 0x11, 0x48, 0x17, 0xf6, 0x00, 0x88, 0x17, 
-	0xe7, 0x60, 0xf5, 0xa9, 0xf8, 0x20, 0x0a, 0x2d, 
-	0x48, 0x16, 0xf6, 0x20, 0x88, 0x11, 0x48, 0x18, 
-	0x70, 0x00, 0x00, 0x11, 0xf2, 0x74, 0x09, 0x8f, 
-	0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 0x70, 0x01, 
-	0x00, 0x11, 0x10, 0x02, 0x80, 0x00, 0xf2, 0x74, 
-	0x06, 0xce, 0xf4, 0x95, 0x48, 0x17, 0xee, 0x04, 
-	0x48, 0x16, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 
-	0xfc, 0x00, 0xee, 0xfd, 0xe8, 0x00, 0x4e, 0xf8, 
-	0x27, 0x70, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x72, 
-	0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00, 
-	0x4e, 0xf8, 0x27, 0x76, 0x76, 0xf8, 0x27, 0x79, 
-	0xff, 0xff, 0x76, 0xf8, 0x27, 0x7a, 0x00, 0x00, 
-	0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff, 0x76, 0xf8, 
-	0x27, 0x78, 0x00, 0x00, 0xe8, 0x00, 0x75, 0xf8, 
-	0x00, 0x08, 0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 
-	0x76, 0x01, 0x02, 0x00, 0xf2, 0x74, 0x12, 0xdc, 
-	0xf0, 0x20, 0x27, 0x7c, 0xee, 0x03, 0xfc, 0x00, 
-	0x4a, 0x11, 0xee, 0xfc, 0xf4, 0x95, 0x4e, 0x00, 
-	0x77, 0x12, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x12, 
-	0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x12, 
-	0xf0, 0xe0, 0xf1, 0xf1, 0x4f, 0x02, 0xe9, 0x01, 
-	0xf4, 0x95, 0x48, 0x0b, 0xf5, 0x40, 0x56, 0x02, 
-	0xf1, 0x80, 0x81, 0xf8, 0x27, 0x78, 0x77, 0x11, 
-	0x80, 0x00, 0x56, 0x00, 0x49, 0x11, 0xf1, 0x80, 
-	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 
-	0x0a, 0x81, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 
-	0x00, 0x01, 0xf0, 0x73, 0x0a, 0x86, 0xf0, 0x20, 
-	0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-	0x10, 0x82, 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 
-	0x4a, 0x11, 0xee, 0xfe, 0xf4, 0x95, 0x4e, 0x00, 
-	0x77, 0x11, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x11, 
-	0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x11, 
-	0xf0, 0xe0, 0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80, 
-	0x80, 0xf8, 0x27, 0x78, 0x56, 0x00, 0xf1, 0x20, 
-	0x80, 0x00, 0xf1, 0x80, 0xf4, 0x95, 0x49, 0x0b, 
-	0xf8, 0x4d, 0x0a, 0xab, 0xf0, 0x20, 0x80, 0x01, 
-	0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf0, 0x73, 
-	0x0a, 0xaf, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 
-	0x00, 0x01, 0xee, 0x02, 0x48, 0x11, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0x88, 0x12, 0x13, 0x02, 
-	0x77, 0x11, 0x00, 0x00, 0xf8, 0x4d, 0x0a, 0xcb, 
-	0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 0xf4, 0x95, 
-	0xf0, 0x72, 0x0a, 0xca, 0x48, 0x11, 0x1c, 0xf8, 
-	0x29, 0x7e, 0x88, 0x11, 0x11, 0xf8, 0x29, 0x7e, 
-	0xf2, 0x00, 0x00, 0x01, 0x80, 0xf8, 0x29, 0x7e, 
-	0x81, 0x92, 0x48, 0x11, 0x8a, 0x11, 0xfc, 0x00, 
-	0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x11, 
-	0x88, 0x12, 0xf6, 0xb8, 0xf0, 0x20, 0x7f, 0xff, 
-	0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0xf0, 0x00, 
-	0x80, 0x00, 0x80, 0x82, 0x57, 0xf8, 0x27, 0x70, 
-	0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80, 0x80, 0xf8, 
-	0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x48, 0x12, 
-	0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0x88, 0x12, 
-	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x0a, 0xf4, 
-	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 
-	0xf0, 0x73, 0x0a, 0xf9, 0xf0, 0x20, 0x80, 0x01, 
-	0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x45, 0xf8, 
-	0x27, 0x75, 0xe7, 0x10, 0x43, 0xf8, 0x27, 0x71, 
-	0x83, 0xf8, 0x00, 0x12, 0x6d, 0xe8, 0x00, 0x04, 
-	0x6d, 0x8a, 0xf6, 0xaa, 0xf8, 0x30, 0x0b, 0x0a, 
-	0xf2, 0x73, 0x0b, 0x25, 0x77, 0x11, 0x00, 0x00, 
-	0x57, 0xf8, 0x27, 0x70, 0xf0, 0x20, 0x7f, 0xff, 
-	0xf2, 0x80, 0x49, 0x11, 0xf5, 0x00, 0xf3, 0x00, 
-	0x80, 0x00, 0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00, 
-	0xf8, 0x30, 0x0b, 0x1d, 0xf1, 0x20, 0x80, 0x00, 
-	0xf5, 0x20, 0x89, 0x11, 0xf4, 0x95, 0x48, 0x11, 
-	0x6f, 0xf8, 0x27, 0x71, 0x0d, 0x00, 0xf4, 0x95, 
-	0x49, 0x0b, 0x4f, 0xf8, 0x27, 0x70, 0x48, 0x11, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 
-	0x4a, 0x17, 0xee, 0xf0, 0x88, 0x17, 0x10, 0x17, 
-	0x80, 0x05, 0x10, 0x16, 0x80, 0x06, 0x10, 0x15, 
-	0x80, 0x07, 0x71, 0x14, 0x00, 0x11, 0x10, 0x05, 
-	0xf0, 0x30, 0x00, 0x01, 0x88, 0x10, 0x10, 0x06, 
-	0xf0, 0x30, 0x00, 0x01, 0x80, 0x08, 0x49, 0x11, 
-	0x10, 0x05, 0xf6, 0x01, 0x80, 0x09, 0x10, 0x06, 
-	0x61, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf8, 0x20, 
-	0x0b, 0x4b, 0x10, 0x09, 0xf0, 0x00, 0x00, 0x01, 
-	0x80, 0x09, 0x71, 0x08, 0x00, 0x12, 0xf4, 0xaa, 
-	0xf8, 0x30, 0x0b, 0x54, 0x10, 0x09, 0xf0, 0x00, 
-	0x00, 0x01, 0x80, 0x09, 0x12, 0x09, 0x49, 0x11, 
-	0xf4, 0x7f, 0x80, 0x09, 0xf6, 0x20, 0x80, 0x0a, 
-	0x56, 0xf8, 0x27, 0x70, 0x4e, 0x0c, 0x10, 0x09, 
-	0x80, 0x00, 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 
-	0xf0, 0x00, 0x00, 0x04, 0x88, 0x16, 0xf4, 0x95, 
-	0xf4, 0x95, 0x6c, 0x86, 0x0b, 0x6d, 0xf2, 0x73, 
-	0x0c, 0x59, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0xb8, 
-	0xf4, 0x95, 0x56, 0x0c, 0xf0, 0xf9, 0x88, 0x12, 
-	0xf4, 0x95, 0xf4, 0x95, 0x70, 0xe2, 0x27, 0x7c, 
-	0x29, 0x86, 0xe8, 0x00, 0x80, 0x0e, 0x48, 0x11, 
-	0xf8, 0x45, 0x0b, 0xcc, 0x77, 0x10, 0x00, 0x01, 
-	0xf4, 0xa9, 0xf8, 0x30, 0x0b, 0x89, 0x6c, 0xe1, 
-	0xff, 0xfd, 0x0b, 0x8b, 0x10, 0xe7, 0x00, 0x02, 
-	0x80, 0x0e, 0xf0, 0x73, 0x0b, 0x8b, 0x10, 0x87, 
-	0x80, 0x0e, 0xe7, 0x10, 0xf5, 0xae, 0xf8, 0x20, 
-	0x0b, 0xb2, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 
-	0x00, 0x16, 0x10, 0x04, 0xf0, 0x74, 0x06, 0xce, 
-	0x48, 0x17, 0x49, 0x16, 0xf6, 0x00, 0x88, 0x17, 
-	0x48, 0x11, 0xf6, 0x20, 0x88, 0x11, 0x10, 0x09, 
-	0xf6, 0x20, 0x80, 0x00, 0x48, 0x18, 0xf2, 0x74, 
-	0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x16, 
-	0x10, 0x04, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 
-	0x00, 0x11, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11, 
-	0x00, 0x04, 0x80, 0x04, 0xf0, 0x73, 0x0b, 0xbc, 
-	0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 0x00, 0x11, 
-	0x10, 0x04, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11, 
-	0x00, 0x04, 0x80, 0x04, 0x49, 0x11, 0x48, 0x16, 
-	0xf6, 0x20, 0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95, 
-	0x6c, 0x86, 0x0b, 0xcc, 0x10, 0x0a, 0x80, 0x00, 
-	0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 
-	0x00, 0x04, 0x88, 0x16, 0x12, 0x0a, 0xf8, 0x45, 
-	0x0c, 0x33, 0x71, 0x0a, 0x00, 0x10, 0xf4, 0xae, 
-	0xf8, 0x30, 0x0c, 0x1c, 0x48, 0x16, 0xf0, 0xe1, 
-	0x88, 0x11, 0x12, 0x08, 0xf8, 0x45, 0x0b, 0xdb, 
-	0x6d, 0x89, 0x12, 0x07, 0xf8, 0x45, 0x0b, 0xe9, 
-	0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11, 
-	0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74, 
-	0x06, 0xdc, 0xf0, 0x73, 0x0b, 0xef, 0x48, 0x11, 
-	0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74, 
-	0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e, 
-	0x10, 0x06, 0x49, 0x11, 0xf6, 0x00, 0x80, 0x06, 
-	0x10, 0x05, 0xf6, 0x20, 0x88, 0x11, 0xf0, 0x00, 
-	0x00, 0x01, 0x48, 0x08, 0x6f, 0x00, 0x0c, 0x9f, 
-	0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 
-	0x00, 0x04, 0x12, 0x07, 0xf8, 0x45, 0x0c, 0x11, 
-	0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11, 
-	0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74, 
-	0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x17, 0x48, 0x11, 
-	0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74, 
-	0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e, 
-	0xf0, 0x73, 0x0c, 0x33, 0x12, 0x07, 0xf8, 0x45, 
-	0x0c, 0x2a, 0x10, 0x07, 0x80, 0x00, 0x10, 0x06, 
-	0x80, 0x01, 0x10, 0x05, 0x80, 0x02, 0x10, 0x04, 
-	0xf0, 0x74, 0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x30, 
-	0x12, 0x05, 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 
-	0xf0, 0x74, 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 
-	0x81, 0x0e, 0x76, 0x00, 0x00, 0x01, 0x48, 0x18, 
-	0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 
-	0x71, 0x04, 0x00, 0x11, 0x70, 0x81, 0x29, 0x86, 
-	0x10, 0x0e, 0x1c, 0xf8, 0x29, 0x86, 0x80, 0x0e, 
-	0x76, 0x00, 0x00, 0x01, 0x48, 0x18, 0xf2, 0x74, 
-	0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x10, 0x0e, 
-	0x71, 0x04, 0x00, 0x11, 0x80, 0x81, 0x10, 0xf8, 
-	0x29, 0x86, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x30, 
-	0x7f, 0xff, 0x80, 0xf8, 0x29, 0x86, 0x10, 0x09, 
-	0xf0, 0x00, 0x00, 0x02, 0x80, 0x09, 0xee, 0x10, 
-	0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 
-	0x10, 0xf8, 0x27, 0x75, 0x08, 0xf8, 0x27, 0x71, 
-	0xf0, 0x10, 0x00, 0x01, 0x48, 0x08, 0xfc, 0x00, 
-	0x4a, 0x11, 0x4a, 0x16, 0xee, 0xff, 0xf4, 0x95, 
-	0x71, 0x04, 0x00, 0x16, 0xf0, 0x00, 0x00, 0x01, 
-	0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c, 0x6d, 0xee, 
-	0xff, 0xfd, 0x48, 0x16, 0xf8, 0x45, 0x0c, 0x99, 
-	0x56, 0xf8, 0x29, 0x7c, 0xf0, 0x74, 0x0a, 0x5a, 
-	0x88, 0x11, 0x10, 0xf8, 0x29, 0x7d, 0xf0, 0x00, 
-	0x00, 0x01, 0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c, 
-	0x10, 0xf8, 0x29, 0x82, 0xf0, 0x00, 0x00, 0x01, 
-	0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xa9, 
-	0xfa, 0x30, 0x0c, 0x96, 0x80, 0xf8, 0x29, 0x82, 
-	0x56, 0xf8, 0x29, 0x80, 0xf0, 0x00, 0x00, 0x01, 
-	0x4e, 0xf8, 0x29, 0x80, 0x73, 0x11, 0x29, 0x82, 
-	0x6c, 0xee, 0xff, 0xff, 0x0c, 0x76, 0xee, 0x01, 
-	0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-	0x76, 0xf8, 0x29, 0x84, 0x00, 0x00, 0x76, 0xf8, 
-	0x29, 0x85, 0x00, 0x01, 0xe8, 0x00, 0x4e, 0xf8, 
-	0x2a, 0x0c, 0x76, 0xf8, 0x29, 0x86, 0x00, 0x00, 
-	0x76, 0xf8, 0x29, 0x87, 0x00, 0x00, 0x77, 0x11, 
-	0x29, 0x88, 0x76, 0x81, 0xaa, 0xaa, 0x76, 0xe1, 
-	0x00, 0x01, 0xaa, 0xaa, 0x76, 0xe1, 0x00, 0x02, 
-	0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-	0xee, 0xfc, 0xf4, 0x95, 0x71, 0x06, 0x00, 0x14, 
-	0x71, 0x07, 0x00, 0x13, 0x71, 0x08, 0x00, 0x12, 
-	0x71, 0x09, 0x00, 0x15, 0x77, 0x10, 0x00, 0xff, 
-	0xf4, 0xaa, 0xf8, 0x30, 0x0d, 0x44, 0x49, 0x13, 
-	0x53, 0xf8, 0x2a, 0x0c, 0x4f, 0xf8, 0x2a, 0x0c, 
-	0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d, 
-	0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x01, 
-	0x71, 0xe1, 0x24, 0x00, 0x00, 0x11, 0xf4, 0xa9, 
-	0xf8, 0x30, 0x0d, 0x17, 0x77, 0x10, 0x00, 0x02, 
-	0xf4, 0xa9, 0xf8, 0x30, 0x0c, 0xec, 0x77, 0x11, 
-	0x29, 0x8a, 0x76, 0x81, 0x00, 0x00, 0xe8, 0x00, 
-	0x77, 0x14, 0x00, 0x00, 0x77, 0x13, 0x00, 0x00, 
-	0xf0, 0x73, 0x0d, 0x48, 0x6c, 0x83, 0x0c, 0xfa, 
-	0x77, 0x11, 0x29, 0x8a, 0x48, 0x12, 0xf0, 0xe8, 
-	0xf0, 0x40, 0x80, 0x00, 0x80, 0x81, 0xe8, 0x00, 
-	0x77, 0x14, 0x00, 0x00, 0xf0, 0x73, 0x0d, 0x48, 
-	0x49, 0x13, 0xf3, 0x40, 0x80, 0x00, 0x81, 0xf8, 
-	0x29, 0x8a, 0x61, 0xf8, 0x00, 0x15, 0x00, 0x01, 
-	0xf8, 0x20, 0x0d, 0x07, 0x69, 0xf8, 0x29, 0x8a, 
-	0x40, 0x00, 0x61, 0xf8, 0x00, 0x14, 0x00, 0x01, 
-	0xf8, 0x20, 0x0d, 0x0f, 0x69, 0xf8, 0x29, 0x8a, 
-	0x20, 0x00, 0x77, 0x11, 0x29, 0x8a, 0x49, 0x12, 
-	0xf3, 0xe8, 0x1b, 0x81, 0x81, 0x81, 0xf0, 0x73, 
-	0x0d, 0x48, 0x11, 0xf8, 0x29, 0x84, 0xf8, 0x4c, 
-	0x0d, 0x37, 0x77, 0x11, 0x29, 0x88, 0x76, 0x81, 
-	0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85, 0xf3, 0x10, 
-	0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00, 0x81, 0xe1, 
-	0x00, 0x01, 0x76, 0x00, 0x00, 0x02, 0x80, 0x01, 
-	0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 0x00, 0x13, 
-	0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0x48, 0x11, 
-	0x71, 0xf8, 0x29, 0x85, 0x29, 0x84, 0xf0, 0x73, 
-	0x0d, 0x73, 0x76, 0x00, 0x00, 0x00, 0x80, 0x01, 
-	0x76, 0x02, 0x00, 0x00, 0x70, 0x03, 0x00, 0x13, 
-	0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0xe8, 0x00, 
-	0xf0, 0x73, 0x0d, 0x73, 0x77, 0x11, 0x29, 0x8a, 
-	0x70, 0x81, 0x00, 0x13, 0x11, 0xf8, 0x29, 0x84, 
-	0xf8, 0x4c, 0x0d, 0x68, 0x77, 0x11, 0x29, 0x88, 
-	0x76, 0x81, 0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85, 
-	0xf3, 0x10, 0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00, 
-	0x81, 0xe1, 0x00, 0x01, 0x76, 0x00, 0x00, 0x03, 
-	0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 
-	0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 
-	0x48, 0x11, 0x71, 0xf8, 0x29, 0x85, 0x29, 0x84, 
-	0xf0, 0x73, 0x0d, 0x73, 0x76, 0x00, 0x00, 0x01, 
-	0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 
-	0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 
-	0x48, 0x11, 0x6b, 0xf8, 0x29, 0x84, 0xff, 0xff, 
-	0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-	0xf5, 0x40, 0xf4, 0x95, 0x48, 0x0b, 0xf4, 0x78, 
-	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe1, 
-	0xff, 0xb9, 0x0d, 0x88, 0xf2, 0x73, 0x0d, 0xa5, 
-	0xf4, 0x95, 0xe8, 0x60, 0xf2, 0x00, 0x00, 0x06, 
-	0x61, 0xf8, 0x00, 0x11, 0x00, 0x20, 0xf8, 0x30, 
-	0x0d, 0x98, 0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01, 
-	0xf8, 0x20, 0x0d, 0xa3, 0xf2, 0x00, 0x00, 0x07, 
-	0xf0, 0x73, 0x0d, 0xa3, 0x61, 0xf8, 0x00, 0x0b, 
-	0x00, 0x01, 0xf8, 0x20, 0x0d, 0xa1, 0xf2, 0x73, 
-	0x0d, 0xa3, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00, 
-	0x00, 0x02, 0x48, 0x08, 0xf4, 0x7f, 0x8a, 0x11, 
-	0xfc, 0x00, 0xee, 0xff, 0xf0, 0x74, 0x07, 0xfd, 
-	0xf0, 0x74, 0x07, 0x44, 0xf0, 0x74, 0x0d, 0xb4, 
-	0xf0, 0x74, 0x02, 0x05, 0xf0, 0x74, 0x04, 0x60, 
-	0xf0, 0x73, 0x0d, 0xaa, 0xee, 0xfd, 0x10, 0xf8, 
-	0x2a, 0xa3, 0xf8, 0x44, 0x0d, 0xcb, 0x10, 0xf8, 
-	0x2a, 0xa4, 0xf8, 0x45, 0x0d, 0xd7, 0x76, 0x00, 
-	0x02, 0x00, 0xf2, 0x74, 0x09, 0xe8, 0xf0, 0x20, 
-	0x22, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00, 
-	0x76, 0xf8, 0x2a, 0xa7, 0x00, 0x00, 0xf0, 0x73, 
-	0x0d, 0xd7, 0x76, 0x00, 0x02, 0x00, 0xf2, 0x74, 
-	0x09, 0xe8, 0xf0, 0x20, 0x20, 0x00, 0x76, 0xf8, 
-	0x2a, 0xa3, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa7, 
-	0x00, 0x01, 0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0, 
-	0xf0, 0x10, 0x3a, 0x98, 0xf8, 0x47, 0x0d, 0xe1, 
-	0x76, 0xf8, 0x27, 0x6e, 0x00, 0x00, 0xee, 0x03, 
-	0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x77, 0x11, 
-	0x20, 0x00, 0x76, 0x00, 0xaa, 0xaa, 0x76, 0x01, 
-	0x02, 0x00, 0xf2, 0x74, 0x06, 0x6c, 0xf4, 0x95, 
-	0x48, 0x11, 0x76, 0x00, 0x55, 0x55, 0x76, 0x01, 
-	0x02, 0x00, 0x48, 0x11, 0xf2, 0x74, 0x06, 0x6c, 
-	0xf0, 0x00, 0x02, 0x00, 0x76, 0xf8, 0x2a, 0xa3, 
-	0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00, 
-	0xe8, 0x00, 0x4e, 0x00, 0xfb, 0x80, 0x15, 0x3e, 
-	0xf4, 0x95, 0xe8, 0x04, 0x80, 0xf8, 0x2a, 0xa5, 
-	0x76, 0x00, 0x2a, 0xa8, 0xf9, 0x80, 0x14, 0x87, 
-	0x76, 0x00, 0x2a, 0xad, 0xfb, 0x80, 0x13, 0x62, 
-	0xf4, 0x95, 0xe8, 0x02, 0x10, 0xf8, 0x2a, 0xa5, 
-	0xf9, 0x80, 0x14, 0x63, 0xfb, 0x80, 0x16, 0x66, 
-	0xf4, 0x95, 0xe8, 0x1c, 0xfb, 0x80, 0x16, 0x87, 
-	0xf4, 0x95, 0xe8, 0x1c, 0xe8, 0x01, 0x4e, 0x00, 
-	0xfb, 0x80, 0x17, 0xd6, 0xf4, 0x95, 0xe8, 0x00, 
-	0x80, 0xf8, 0x2a, 0xa6, 0x76, 0x00, 0x2a, 0xb7, 
-	0xf9, 0x80, 0x16, 0xaa, 0x10, 0xf8, 0x2a, 0xa6, 
-	0xf9, 0x80, 0x17, 0x5c, 0x10, 0xf8, 0x2a, 0xa6, 
-	0xf9, 0x80, 0x17, 0x6f, 0xee, 0x02, 0x8a, 0x11, 
-	0xfc, 0x00, 0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09, 
-	0x4a, 0x0a, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8, 
-	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07, 
-	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc, 
-	0x10, 0xf8, 0x2a, 0xa7, 0xf8, 0x44, 0x0e, 0x4b, 
-	0x76, 0xf8, 0x2a, 0xa3, 0x00, 0x01, 0xf0, 0x73, 
-	0x0e, 0x4e, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x01, 
-	0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x0a, 0x8a, 0x09, 
-	0x8a, 0x08, 0xf4, 0xeb, 0x4a, 0x11, 0x4a, 0x16, 
-	0x4a, 0x17, 0xee, 0xfe, 0x88, 0x0e, 0x71, 0x08, 
-	0x00, 0x16, 0x71, 0x06, 0x00, 0x17, 0x11, 0x07, 
-	0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00, 0x25, 0xa0, 
-	0x88, 0x11, 0x76, 0x01, 0x00, 0x06, 0x81, 0x00, 
-	0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00, 0x00, 0x01, 
-	0x76, 0x01, 0x00, 0x06, 0x70, 0x00, 0x00, 0x16, 
-	0x48, 0x11, 0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00, 
-	0x00, 0x07, 0x70, 0x81, 0x00, 0x17, 0xee, 0x02, 
-	0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 
-	0x4a, 0x11, 0x88, 0x0e, 0x71, 0x02, 0x00, 0x12, 
-	0x11, 0x03, 0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00, 
-	0x24, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x70, 0x81, 
-	0x00, 0x12, 0x6e, 0xe2, 0xff, 0xfe, 0x0e, 0x8d, 
-	0xf4, 0x95, 0xe8, 0x00, 0xe8, 0x01, 0x80, 0xe1, 
-	0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 
-	0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 
-	0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0c, 
-	0x00, 0x00, 0x81, 0xe1, 0x00, 0x01, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc, 0x88, 0x0e, 
-	0xf4, 0x95, 0xf1, 0x66, 0x00, 0x0d, 0xf3, 0x00, 
-	0x24, 0x00, 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 
-	0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1, 
-	0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 
-	0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 
-	0x00, 0x00, 0x80, 0x02, 0x76, 0x03, 0x00, 0x00, 
-	0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0xe8, 0x00, 
-	0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-	0x88, 0x19, 0xf4, 0x95, 0x73, 0x19, 0x00, 0x0e, 
-	0xf1, 0x66, 0x00, 0x0d, 0xf2, 0x00, 0x24, 0x00, 
-	0x77, 0x15, 0x25, 0xa0, 0x77, 0x14, 0x00, 0x00, 
-	0x77, 0x1a, 0x00, 0x1f, 0xf0, 0x72, 0x0f, 0x14, 
-	0xf6, 0xb8, 0x49, 0x19, 0x09, 0x85, 0xf8, 0x4c, 
-	0x0f, 0x13, 0xf1, 0x00, 0x00, 0x05, 0x89, 0x11, 
-	0x49, 0x15, 0xf3, 0x00, 0x00, 0x01, 0x89, 0x13, 
-	0x49, 0x15, 0xf3, 0x00, 0x00, 0x07, 0x89, 0x12, 
-	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10, 
-	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13, 
-	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x11, 
-	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0f, 0x13, 
-	0x6d, 0x94, 0x6d, 0xed, 0x00, 0x0d, 0x48, 0x14, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 
-	0x4a, 0x17, 0xee, 0xf8, 0x88, 0x17, 0x10, 0x0d, 
-	0x80, 0x04, 0x10, 0x0c, 0x80, 0x05, 0x71, 0x0e, 
-	0x00, 0x16, 0x73, 0x17, 0x00, 0x0e, 0xf0, 0x66, 
-	0x00, 0x0d, 0xf0, 0x00, 0x24, 0x00, 0x88, 0x11, 
-	0x10, 0xf8, 0x27, 0x63, 0xf8, 0x45, 0x0f, 0x32, 
-	0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17, 
-	0x10, 0xf8, 0x27, 0x60, 0xf8, 0x44, 0x0f, 0x3d, 
-	0x60, 0xe1, 0x00, 0x02, 0x00, 0x01, 0xf8, 0x20, 
-	0x0f, 0x6d, 0xf0, 0x73, 0x11, 0x33, 0x10, 0x04, 
-	0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f, 
-	0x11, 0x04, 0xf3, 0x00, 0x00, 0x01, 0x81, 0x04, 
-	0x6d, 0x8e, 0x77, 0x10, 0x00, 0x01, 0x71, 0xe1, 
-	0x00, 0x02, 0x00, 0x12, 0xf4, 0xaa, 0xf8, 0x30, 
-	0x0f, 0x62, 0x77, 0x10, 0x00, 0x02, 0xf4, 0xaa, 
-	0xf8, 0x30, 0x0f, 0x6d, 0x45, 0xe1, 0x00, 0x0b, 
-	0x88, 0x10, 0x43, 0xe1, 0x00, 0x0c, 0x83, 0xf8, 
-	0x00, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xaa, 
-	0xf8, 0x30, 0x0f, 0x6d, 0xf0, 0x73, 0x0f, 0x96, 
-	0xf5, 0x00, 0x81, 0x04, 0x49, 0x16, 0xf5, 0x20, 
-	0x89, 0x16, 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00, 
-	0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x48, 0x16, 
-	0xf8, 0x45, 0x11, 0x33, 0xf7, 0xb8, 0x71, 0xe1, 
-	0x00, 0x02, 0x00, 0x12, 0x10, 0xf8, 0x00, 0x12, 
-	0xf0, 0x10, 0x00, 0x03, 0xf8, 0x46, 0x0f, 0x8c, 
-	0x10, 0xf8, 0x00, 0x12, 0xf0, 0x10, 0x00, 0x03, 
-	0xf8, 0x45, 0x10, 0x16, 0x77, 0x10, 0x00, 0x01, 
-	0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0x9c, 0x77, 0x10, 
-	0x00, 0x02, 0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0xa8, 
-	0xf0, 0x73, 0x0f, 0x96, 0x77, 0x10, 0x00, 0x04, 
-	0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xb7, 0x77, 0x10, 
-	0x00, 0x05, 0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xbc, 
-	0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17, 
-	0xf0, 0x73, 0x11, 0x31, 0x76, 0xe1, 0x00, 0x0c, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00, 
-	0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 
-	0x00, 0x02, 0x00, 0x02, 0x11, 0xe1, 0x00, 0x0c, 
-	0xe8, 0x03, 0xf6, 0x20, 0x89, 0x12, 0xf4, 0x95, 
-	0x77, 0x10, 0x00, 0x03, 0xf5, 0xaa, 0xf8, 0x30, 
-	0x0f, 0xb6, 0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01, 
-	0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf5, 0xae, 
-	0xf8, 0x20, 0x0f, 0xbd, 0x48, 0x16, 0x80, 0x06, 
-	0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x03, 
-	0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xc8, 0x6b, 0xf8, 
-	0x27, 0x6f, 0x00, 0x01, 0x12, 0x06, 0xf8, 0x45, 
-	0x10, 0x00, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00, 
-	0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02, 
-	0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74, 
-	0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06, 
-	0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04, 
-	0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1, 
-	0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04, 
-	0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 
-	0x88, 0x16, 0x89, 0x13, 0xf4, 0x95, 0x77, 0x10, 
-	0x00, 0x03, 0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xf5, 
-	0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01, 0x77, 0x10, 
-	0x00, 0x0c, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x13, 
-	0xf6, 0xab, 0xf8, 0x20, 0x10, 0x00, 0x6b, 0xf8, 
-	0x27, 0x6f, 0x00, 0x01, 0x6c, 0xe2, 0xff, 0xfd, 
-	0x11, 0x31, 0xf6, 0xb8, 0x6f, 0xe1, 0x00, 0x05, 
-	0x0c, 0x48, 0x6f, 0xe1, 0x00, 0x06, 0x0c, 0x18, 
-	0xf0, 0x30, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x03, 
-	0x80, 0xe1, 0x00, 0x0b, 0x76, 0xe1, 0x00, 0x02, 
-	0x00, 0x03, 0x48, 0x16, 0xf8, 0x45, 0x11, 0x33, 
-	0x71, 0xe1, 0x00, 0x0c, 0x00, 0x12, 0x10, 0xe1, 
-	0x00, 0x0b, 0x49, 0x12, 0xf6, 0x20, 0x88, 0x13, 
-	0xe8, 0x0c, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95, 
-	0xf4, 0x95, 0xf5, 0xab, 0xf8, 0x20, 0x10, 0x27, 
-	0x48, 0x13, 0x80, 0x06, 0x88, 0x10, 0xf4, 0x95, 
-	0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0x30, 
-	0x70, 0x06, 0x00, 0x16, 0x12, 0x06, 0xf8, 0x45, 
-	0x10, 0x5f, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00, 
-	0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02, 
-	0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74, 
-	0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06, 
-	0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04, 
-	0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1, 
-	0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04, 
-	0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 
-	0x88, 0x16, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x0c, 
-	0x71, 0xe1, 0x00, 0x04, 0x00, 0x13, 0xf6, 0xab, 
-	0xf8, 0x20, 0x10, 0x5f, 0x6b, 0xf8, 0x27, 0x6f, 
-	0x00, 0x01, 0x77, 0x10, 0x00, 0x0c, 0xf6, 0xaa, 
-	0xf8, 0x20, 0x10, 0x6b, 0xf2, 0x74, 0x0e, 0x9f, 
-	0xf4, 0x95, 0x48, 0x17, 0x71, 0xe1, 0x00, 0x0c, 
-	0x00, 0x12, 0x77, 0x10, 0x00, 0x0c, 0xf4, 0xaa, 
-	0xf8, 0x30, 0x10, 0x7c, 0x77, 0x10, 0x00, 0x0c, 
-	0x71, 0xe1, 0x00, 0x0b, 0x00, 0x13, 0xf6, 0xab, 
-	0xf8, 0x30, 0x10, 0xb4, 0xe7, 0x30, 0xf7, 0xaa, 
-	0xf8, 0x30, 0x10, 0xb4, 0xf2, 0x74, 0x0e, 0xc1, 
-	0xf4, 0x95, 0x48, 0x17, 0x88, 0x12, 0xf4, 0x95, 
-	0xf4, 0x95, 0x6c, 0x82, 0x10, 0x8d, 0x76, 0xe1, 
-	0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 
-	0x00, 0x05, 0xf0, 0x73, 0x10, 0xb4, 0x76, 0xe1, 
-	0x00, 0x02, 0x00, 0x04, 0x77, 0x10, 0x00, 0x0c, 
-	0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf5, 0xaa, 
-	0xf8, 0x20, 0x10, 0x9a, 0xf0, 0x73, 0x10, 0x9c, 
-	0x77, 0x12, 0x00, 0x0c, 0x76, 0x00, 0x00, 0x00, 
-	0x70, 0x01, 0x00, 0x12, 0x70, 0x02, 0x00, 0x17, 
-	0x76, 0x03, 0x00, 0x01, 0x48, 0x11, 0xf2, 0x74, 
-	0x0c, 0xb9, 0xf0, 0x00, 0x00, 0x05, 0x76, 0xe1, 
-	0x00, 0x04, 0x00, 0x00, 0x77, 0x10, 0x00, 0x0c, 
-	0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf6, 0xaa, 
-	0xf8, 0x20, 0x11, 0x1c, 0x48, 0x16, 0xf8, 0x45, 
-	0x11, 0x33, 0x60, 0xe1, 0x00, 0x02, 0x00, 0x05, 
-	0xf8, 0x20, 0x10, 0xdf, 0x10, 0xe1, 0x00, 0x0b, 
-	0x08, 0xe1, 0x00, 0x0c, 0x11, 0xe1, 0x00, 0x04, 
-	0xf8, 0x4d, 0x10, 0xc7, 0x6b, 0xf8, 0x27, 0x6f, 
-	0x00, 0x01, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 
-	0xf5, 0xae, 0xf8, 0x20, 0x10, 0xcf, 0x48, 0x16, 
-	0xf4, 0x95, 0x48, 0x08, 0xf8, 0x45, 0x11, 0x16, 
-	0x6f, 0xe1, 0x00, 0x0c, 0x0d, 0x00, 0x81, 0xe1, 
-	0x00, 0x0c, 0x11, 0x04, 0xf5, 0x00, 0x81, 0x04, 
-	0x49, 0x16, 0xf5, 0x20, 0x89, 0x16, 0xf0, 0x73, 
-	0x11, 0x0e, 0x10, 0xe1, 0x00, 0x0b, 0x71, 0xe1, 
-	0x00, 0x0c, 0x00, 0x12, 0x88, 0x10, 0xf4, 0x95, 
-	0xf4, 0x95, 0xf6, 0xaa, 0xf8, 0x30, 0x11, 0x16, 
-	0x49, 0x12, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95, 
-	0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0xf3, 
-	0x48, 0x16, 0x80, 0x06, 0x48, 0x08, 0xf8, 0x45, 
-	0x11, 0x16, 0x10, 0x04, 0x70, 0x02, 0x00, 0x17, 
-	0x80, 0x00, 0x76, 0x03, 0x00, 0x00, 0x10, 0x06, 
-	0x80, 0x01, 0x10, 0x05, 0xf0, 0x74, 0x0c, 0xb9, 
-	0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1, 
-	0x00, 0x0c, 0x11, 0x06, 0x10, 0x04, 0xf6, 0x00, 
-	0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 0x88, 0x16, 
-	0x10, 0xe1, 0x00, 0x0c, 0x08, 0xe1, 0x00, 0x0b, 
-	0xf8, 0x45, 0x11, 0x1c, 0xf0, 0x73, 0x11, 0x31, 
-	0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17, 
-	0xf0, 0x73, 0x11, 0x33, 0x76, 0xe1, 0x00, 0x0c, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00, 
-	0x76, 0xe1, 0x00, 0x02, 0x00, 0x01, 0x10, 0x04, 
-	0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f, 
-	0x88, 0x12, 0xf4, 0x95, 0x77, 0x10, 0x00, 0xff, 
-	0xf4, 0xaa, 0xf8, 0x30, 0x11, 0x33, 0x6c, 0x86, 
-	0x0f, 0x70, 0xee, 0x08, 0x8a, 0x17, 0x8a, 0x16, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc, 
-	0xf4, 0x95, 0x71, 0x06, 0x00, 0x12, 0x88, 0x11, 
-	0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d, 
-	0xf3, 0x00, 0x24, 0x00, 0x89, 0x14, 0x13, 0x81, 
-	0xf7, 0x7a, 0xf3, 0x30, 0x00, 0x01, 0x81, 0xf8, 
-	0x27, 0x60, 0x13, 0xe1, 0x00, 0x01, 0xf7, 0x7c, 
-	0xf3, 0x30, 0x00, 0x03, 0x81, 0xf8, 0x27, 0x61, 
-	0xe9, 0x0f, 0x19, 0xe1, 0x00, 0x01, 0x81, 0xf8, 
-	0x27, 0x62, 0x71, 0xe4, 0x00, 0x03, 0x00, 0x13, 
-	0xf6, 0xb8, 0x49, 0x13, 0xf3, 0x00, 0x00, 0x01, 
-	0xf3, 0x30, 0x00, 0x0f, 0x49, 0x0b, 0x09, 0xf8, 
-	0x27, 0x62, 0xf8, 0x4d, 0x11, 0x75, 0x77, 0x10, 
-	0x00, 0xff, 0xf4, 0xab, 0xf8, 0x30, 0x11, 0x75, 
-	0x57, 0xf8, 0x27, 0x6c, 0xf3, 0x00, 0x00, 0x01, 
-	0x4f, 0xf8, 0x27, 0x6c, 0x76, 0xf8, 0x27, 0x63, 
-	0x00, 0x01, 0xf0, 0x73, 0x11, 0x78, 0x76, 0xf8, 
-	0x27, 0x63, 0x00, 0x00, 0x70, 0xe4, 0x00, 0x03, 
-	0x27, 0x62, 0x76, 0xf8, 0x27, 0x64, 0x00, 0x00, 
-	0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8, 0x00, 0x0b, 
-	0x00, 0x02, 0xf8, 0x20, 0x11, 0x8d, 0xe9, 0x01, 
-	0x6f, 0xe1, 0x00, 0x02, 0x0f, 0x18, 0x81, 0xf8, 
-	0x27, 0x64, 0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8, 
-	0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20, 0x11, 0xa9, 
-	0x10, 0xf8, 0x27, 0x64, 0xf1, 0x00, 0x00, 0x04, 
-	0x89, 0x13, 0xe9, 0xb8, 0xf5, 0x20, 0x81, 0xf8, 
-	0x27, 0x65, 0x60, 0x84, 0x00, 0x02, 0xf8, 0x20, 
-	0x11, 0xa9, 0x70, 0x00, 0x00, 0x11, 0x70, 0x01, 
-	0x00, 0x13, 0x70, 0x02, 0x27, 0x65, 0xf2, 0x74, 
-	0x0f, 0x18, 0xf4, 0x95, 0x48, 0x12, 0xee, 0x04, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 
-	0x4a, 0x17, 0xee, 0xfc, 0xe8, 0x00, 0x4e, 0xf8, 
-	0x27, 0x66, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x68, 
-	0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x6c, 0xe8, 0x00, 
-	0x4e, 0xf8, 0x27, 0x6a, 0x77, 0x12, 0x27, 0x40, 
-	0x77, 0x11, 0x24, 0x00, 0x77, 0x1a, 0x00, 0x1f, 
-	0xf0, 0x72, 0x11, 0xdb, 0x70, 0x92, 0x00, 0x11, 
-	0x76, 0xe1, 0x00, 0x01, 0xff, 0xff, 0x76, 0x81, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 0x00, 0x00, 
-	0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 0x76, 0xe1, 
-	0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 
-	0x6d, 0xe9, 0x00, 0x0d, 0xf0, 0x20, 0x25, 0xa0, 
-	0xf1, 0x00, 0x00, 0x07, 0x89, 0x11, 0xf1, 0x00, 
-	0x00, 0x01, 0x81, 0x02, 0x88, 0x16, 0xf4, 0x95, 
-	0x77, 0x17, 0x00, 0x20, 0x76, 0x86, 0x00, 0xff, 
-	0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 
-	0x10, 0x02, 0xf0, 0x74, 0x06, 0x6c, 0x76, 0x00, 
-	0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74, 
-	0x06, 0x6c, 0xf4, 0x95, 0x48, 0x11, 0x10, 0x02, 
-	0xf0, 0x00, 0x00, 0x0d, 0x80, 0x02, 0x6d, 0xe9, 
-	0x00, 0x0d, 0x6d, 0xee, 0x00, 0x0d, 0x6c, 0xef, 
-	0xff, 0xff, 0x11, 0xe8, 0xf0, 0x74, 0x0c, 0x9d, 
-	0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 
-	0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 
-	0xee, 0xfa, 0x88, 0x11, 0x10, 0x0a, 0x49, 0x11, 
-	0xf8, 0x4d, 0x12, 0x9f, 0x48, 0x08, 0xf8, 0x45, 
-	0x12, 0x9f, 0x80, 0x04, 0x12, 0x81, 0xf5, 0x78, 
-	0x89, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe2, 
-	0xff, 0xb9, 0x12, 0x8a, 0x61, 0xf8, 0x00, 0x08, 
-	0x00, 0x80, 0xf8, 0x30, 0x12, 0x8a, 0x13, 0xe1, 
-	0x00, 0x01, 0xf0, 0xe8, 0xf7, 0x78, 0xf1, 0xa0, 
-	0xf2, 0x30, 0x1f, 0xff, 0x88, 0x17, 0xf4, 0x95, 
-	0x77, 0x12, 0x24, 0x00, 0x77, 0x16, 0x00, 0x00, 
-	0x77, 0x13, 0x00, 0x20, 0xf6, 0xb8, 0x48, 0x17, 
-	0x08, 0xe2, 0x00, 0x01, 0xf8, 0x45, 0x12, 0x42, 
-	0x6d, 0xea, 0x00, 0x0d, 0x6d, 0x96, 0x6c, 0xeb, 
-	0xff, 0xff, 0x12, 0x34, 0xf0, 0x73, 0x12, 0x90, 
-	0x56, 0xf8, 0x27, 0x6a, 0xf0, 0x00, 0x00, 0x01, 
-	0x4e, 0xf8, 0x27, 0x6a, 0x60, 0x82, 0x00, 0x01, 
-	0xf8, 0x30, 0x12, 0x54, 0x70, 0x00, 0x00, 0x16, 
-	0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11, 
-	0xf0, 0x73, 0x12, 0x90, 0x70, 0x00, 0x00, 0x16, 
-	0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11, 
-	0x72, 0x10, 0x2a, 0x9e, 0xf4, 0x95, 0xf4, 0xaf, 
-	0xf8, 0x30, 0x12, 0x6e, 0x76, 0x00, 0x00, 0x00, 
-	0x76, 0x01, 0x00, 0xbc, 0x70, 0x02, 0x00, 0x16, 
-	0x76, 0x03, 0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9, 
-	0xf4, 0x95, 0x48, 0x11, 0xf0, 0x73, 0x12, 0x90, 
-	0x10, 0xf8, 0x27, 0x6e, 0xf8, 0x44, 0x12, 0x90, 
-	0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0xbc, 
-	0x70, 0x02, 0x00, 0x16, 0x76, 0x03, 0x00, 0x00, 
-	0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0x48, 0x11, 
-	0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0, 0xf0, 0x10, 
-	0x13, 0x88, 0xf8, 0x42, 0x12, 0x90, 0x76, 0xf8, 
-	0x27, 0x6e, 0x00, 0x01, 0xf0, 0x73, 0x12, 0x90, 
-	0x56, 0xf8, 0x27, 0x66, 0xf0, 0x00, 0x00, 0x01, 
-	0x4e, 0xf8, 0x27, 0x66, 0x6d, 0xe9, 0x00, 0x5e, 
-	0x56, 0xf8, 0x27, 0x68, 0xf0, 0x00, 0x00, 0x01, 
-	0x4e, 0xf8, 0x27, 0x68, 0x71, 0x04, 0x00, 0x12, 
-	0x6e, 0xea, 0xff, 0xff, 0x12, 0x18, 0x70, 0x04, 
-	0x00, 0x12, 0xee, 0x06, 0x8a, 0x17, 0x8a, 0x16, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 
-	0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d, 
-	0xf0, 0x00, 0x25, 0xa0, 0x88, 0x11, 0xf4, 0x95, 
-	0xf4, 0x95, 0x76, 0x81, 0x00, 0xff, 0x76, 0x00, 
-	0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74, 
-	0x06, 0x6c, 0xf0, 0x00, 0x00, 0x01, 0x76, 0x00, 
-	0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0x48, 0x11, 
-	0xf2, 0x74, 0x06, 0x6c, 0xf0, 0x00, 0x00, 0x07, 
-	0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 
-	0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d, 
-	0xf0, 0x00, 0x24, 0x00, 0x88, 0x11, 0xf4, 0x95, 
-	0xf4, 0x95, 0x76, 0xe1, 0x00, 0x01, 0xff, 0xff, 
-	0x76, 0x81, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 
-	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 
-	0x13, 0x03, 0x88, 0x11, 0xfa, 0x4d, 0x12, 0xec, 
-	0x71, 0x02, 0x00, 0x12, 0xf3, 0x10, 0x00, 0x01, 
-	0x89, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x12, 0xeb, 
-	0x70, 0x91, 0x00, 0x12, 0x8a, 0x11, 0xfc, 0x00, 
-	0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d, 
-	0xf7, 0xb8, 0xee, 0xfe, 0x10, 0xf8, 0x00, 0x08, 
-	0x11, 0x06, 0xf1, 0xc0, 0x83, 0x00, 0xf4, 0x85, 
-	0x11, 0x06, 0xf7, 0x85, 0x81, 0x06, 0xf6, 0xb8, 
-	0xec, 0x0f, 0x1e, 0x06, 0x61, 0x00, 0x80, 0x00, 
-	0xf8, 0x20, 0x13, 0x05, 0xf4, 0x84, 0xee, 0x02, 
-	0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00, 
-	0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d, 
-	0xee, 0xfe, 0xf7, 0xb8, 0x80, 0x00, 0x10, 0xf8, 
-	0x00, 0x08, 0xf4, 0x85, 0x11, 0x06, 0xf7, 0x85, 
-	0x81, 0x06, 0xf6, 0xb8, 0xec, 0x0f, 0x1e, 0x06, 
-	0xf0, 0xf0, 0x61, 0x00, 0x80, 0x00, 0xf8, 0x20, 
-	0x13, 0x20, 0xf4, 0x84, 0xee, 0x02, 0x8a, 0x0d, 
-	0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00, 0x4a, 0x11, 
-	0x77, 0x11, 0x00, 0x7b, 0x76, 0x81, 0x2e, 0xec, 
-	0x77, 0x11, 0x00, 0x7b, 0xee, 0xff, 0x71, 0x81, 
-	0x00, 0x11, 0xee, 0x01, 0x76, 0xe1, 0x00, 0x01, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 
-	0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1, 
-	0x00, 0x62, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x76, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0x92, 0x00, 0x00, 
-	0x76, 0xe1, 0x00, 0x94, 0x00, 0x00, 0x76, 0xe1, 
-	0x00, 0xb0, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xb3, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0xbe, 0x00, 0x00, 
-	0x76, 0xe1, 0x00, 0xbf, 0x00, 0x00, 0x76, 0xe1, 
-	0x00, 0xc1, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xc3, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0xc5, 0x00, 0x00, 
-	0x76, 0xe1, 0x00, 0xc7, 0x00, 0x00, 0x76, 0x81, 
-	0x00, 0x00, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-	0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xff, 
-	0xf4, 0x95, 0x71, 0x06, 0x00, 0x16, 0xfb, 0x80, 
-	0x16, 0xa2, 0x88, 0x17, 0xf4, 0x95, 0xf7, 0xb8, 
-	0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02, 
-	0xfa, 0x46, 0x13, 0x88, 0x77, 0x11, 0x00, 0x00, 
-	0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02, 
-	0xf8, 0x45, 0x13, 0xf9, 0x10, 0xf8, 0x00, 0x17, 
-	0xf8, 0x45, 0x14, 0x39, 0x10, 0xf8, 0x00, 0x17, 
-	0xf0, 0x10, 0x00, 0x01, 0xf8, 0x45, 0x14, 0x1f, 
-	0xf0, 0x73, 0x14, 0x52, 0x10, 0xf8, 0x00, 0x17, 
-	0xf0, 0x10, 0x00, 0x03, 0xf8, 0x45, 0x13, 0xd3, 
-	0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x06, 
-	0xf8, 0x44, 0x14, 0x52, 0x77, 0x12, 0x00, 0x7b, 
-	0x71, 0x82, 0x00, 0x14, 0x61, 0xe4, 0x00, 0x07, 
-	0x00, 0x40, 0xf8, 0x30, 0x14, 0x52, 0x49, 0x14, 
-	0x48, 0x17, 0xf6, 0x00, 0x88, 0x12, 0xf4, 0x95, 
-	0x77, 0x13, 0x00, 0x55, 0x77, 0x11, 0x00, 0x57, 
-	0x6d, 0xea, 0x00, 0x3b, 0xe5, 0x01, 0x10, 0xe6, 
-	0x00, 0x06, 0x80, 0x81, 0x48, 0x14, 0x00, 0xf8, 
-	0x00, 0x17, 0x88, 0x12, 0xf4, 0x95, 0x77, 0x11, 
-	0x00, 0x55, 0x10, 0xe2, 0x00, 0x40, 0x80, 0x81, 
-	0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x07, 
-	0x80, 0x81, 0x77, 0x11, 0x00, 0x55, 0x10, 0xe2, 
-	0x00, 0x45, 0x80, 0x81, 0x10, 0xe6, 0x00, 0x08, 
-	0x77, 0x11, 0x00, 0x57, 0x80, 0x81, 0x77, 0x11, 
-	0x00, 0x55, 0x10, 0xe2, 0x00, 0x4a, 0x80, 0x81, 
-	0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x09, 
-	0x80, 0x81, 0xf2, 0x73, 0x14, 0x52, 0x77, 0x11, 
-	0x03, 0xc0, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82, 
-	0xf0, 0x00, 0x00, 0x07, 0x88, 0x13, 0xf4, 0x95, 
-	0xf4, 0x95, 0x96, 0x1b, 0xf8, 0x30, 0x14, 0x52, 
-	0x10, 0xe3, 0x00, 0x35, 0x77, 0x12, 0x00, 0x55, 
-	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6, 
-	0x00, 0x04, 0x80, 0x82, 0x77, 0x12, 0x00, 0x55, 
-	0x10, 0xe3, 0x00, 0x37, 0x80, 0x82, 0x77, 0x12, 
-	0x00, 0x57, 0x10, 0xe6, 0x00, 0x05, 0x80, 0x82, 
-	0x48, 0x11, 0xf0, 0x40, 0x00, 0x10, 0xf2, 0x73, 
-	0x14, 0x50, 0xf0, 0x40, 0x00, 0x20, 0x77, 0x12, 
-	0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07, 
-	0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0d, 
-	0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x34, 
-	0x77, 0x13, 0x00, 0x55, 0x80, 0x83, 0x77, 0x13, 
-	0x00, 0x57, 0x10, 0xe6, 0x00, 0x02, 0x80, 0x83, 
-	0x10, 0xe2, 0x00, 0x36, 0x77, 0x12, 0x00, 0x55, 
-	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6, 
-	0x00, 0x03, 0x80, 0x82, 0x48, 0x11, 0xf0, 0x40, 
-	0x00, 0x04, 0xf2, 0x73, 0x14, 0x50, 0xf0, 0x40, 
-	0x00, 0x08, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82, 
-	0xf0, 0x00, 0x00, 0x07, 0x88, 0x12, 0xf4, 0x95, 
-	0xf4, 0x95, 0x96, 0x0e, 0xf8, 0x30, 0x14, 0x52, 
-	0x10, 0xe2, 0x00, 0x33, 0x77, 0x12, 0x00, 0x55, 
-	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6, 
-	0x00, 0x01, 0x80, 0x82, 0x48, 0x11, 0xf2, 0x73, 
-	0x14, 0x50, 0xf0, 0x40, 0x00, 0x02, 0x77, 0x12, 
-	0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07, 
-	0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0f, 
-	0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x32, 
-	0x77, 0x12, 0x00, 0x55, 0x77, 0x13, 0x00, 0x57, 
-	0x80, 0x82, 0x48, 0x11, 0xe7, 0x62, 0xf0, 0x40, 
-	0x00, 0x01, 0xe5, 0x01, 0x88, 0x11, 0xf4, 0x95, 
-	0x77, 0x12, 0x00, 0x7b, 0x48, 0x11, 0x71, 0x82, 
-	0x00, 0x12, 0x1a, 0xe2, 0x00, 0x07, 0x80, 0xe2, 
-	0x00, 0x07, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 
-	0x8a, 0x17, 0x48, 0x11, 0x8a, 0x16, 0x8a, 0x11, 
-	0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0x77, 0x0e, 
-	0x00, 0x05, 0x77, 0x12, 0x00, 0x55, 0xe8, 0x04, 
-	0xf6, 0xb8, 0x28, 0xe1, 0x00, 0x02, 0xee, 0xff, 
-	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0xf0, 0x20, 
-	0x80, 0x00, 0xee, 0x01, 0x1a, 0x82, 0x77, 0x12, 
-	0x00, 0x57, 0x80, 0x82, 0xe8, 0x01, 0x32, 0xe1, 
-	0x00, 0x02, 0xf5, 0x82, 0x77, 0x11, 0x00, 0x54, 
-	0xf6, 0x93, 0x18, 0x81, 0x77, 0x11, 0x00, 0x54, 
-	0xf2, 0xa0, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 
-	0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 
-	0x71, 0x04, 0x00, 0x11, 0xfb, 0x80, 0x16, 0xa2, 
-	0x88, 0x16, 0xf4, 0x95, 0x77, 0x12, 0x00, 0x55, 
-	0x10, 0xe6, 0x00, 0x03, 0x80, 0x82, 0x77, 0x12, 
-	0x00, 0x56, 0x10, 0xe1, 0x00, 0x02, 0x77, 0x13, 
-	0x00, 0x56, 0x80, 0x82, 0x77, 0x12, 0x00, 0x56, 
-	0x10, 0xe1, 0x00, 0x03, 0x80, 0x82, 0x10, 0xe1, 
-	0x00, 0x04, 0x77, 0x12, 0x00, 0x56, 0x80, 0x82, 
-	0x77, 0x12, 0x00, 0x56, 0x10, 0xe1, 0x00, 0x01, 
-	0x80, 0x82, 0xe7, 0x12, 0xe5, 0x01, 0xf9, 0x80, 
-	0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 
-	0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xf9, 
-	0x77, 0x11, 0x00, 0x7b, 0x76, 0x00, 0x00, 0x16, 
-	0x76, 0x01, 0x00, 0x17, 0x76, 0x02, 0x00, 0x1a, 
-	0x76, 0x03, 0x00, 0x1b, 0x76, 0x04, 0x00, 0x1c, 
-	0x76, 0x05, 0x00, 0x1d, 0x71, 0x81, 0x00, 0x17, 
-	0x71, 0xe7, 0x00, 0x06, 0x00, 0x11, 0x10, 0x81, 
-	0xf8, 0x44, 0x14, 0xdf, 0xf9, 0x80, 0x16, 0x53, 
-	0xf6, 0xb8, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x20, 
-	0xff, 0xff, 0xf6, 0xb8, 0xfb, 0x80, 0x16, 0x08, 
-	0xf0, 0x20, 0xff, 0xff, 0x77, 0x11, 0x00, 0x7b, 
-	0x71, 0x81, 0x00, 0x17, 0x76, 0xe7, 0x00, 0x06, 
-	0x00, 0x01, 0x48, 0x17, 0x77, 0x16, 0x00, 0x00, 
-	0x77, 0x10, 0x00, 0x04, 0x77, 0x15, 0x00, 0x03, 
-	0x77, 0x14, 0x00, 0x02, 0x77, 0x13, 0x00, 0x01, 
-	0xf0, 0x00, 0x00, 0x39, 0x76, 0xe7, 0x00, 0x08, 
-	0x00, 0x1f, 0x76, 0xe7, 0x00, 0x07, 0x00, 0x00, 
-	0x88, 0x0e, 0x77, 0x1a, 0x00, 0x05, 0x48, 0x17, 
-	0xf0, 0x00, 0x00, 0x09, 0x88, 0x12, 0x48, 0x18, 
-	0x88, 0x19, 0xe8, 0x00, 0xf0, 0x72, 0x15, 0x2c, 
-	0x73, 0x19, 0x00, 0x11, 0x76, 0x82, 0x00, 0x00, 
-	0x11, 0x91, 0x73, 0x11, 0x00, 0x19, 0x70, 0xe2, 
-	0x00, 0x03, 0x00, 0x16, 0x70, 0xe2, 0x00, 0x04, 
-	0x00, 0x13, 0x70, 0xe2, 0x00, 0x05, 0x00, 0x14, 
-	0x81, 0xe2, 0x00, 0x01, 0x70, 0xe2, 0x00, 0x06, 
-	0x00, 0x15, 0x70, 0xe2, 0x00, 0x07, 0x00, 0x10, 
-	0x80, 0xe2, 0x00, 0x02, 0x73, 0x0e, 0x00, 0x11, 
-	0xf1, 0x00, 0x00, 0x1e, 0x6d, 0xee, 0x00, 0x05, 
-	0x6d, 0xeb, 0x00, 0x05, 0x6d, 0xec, 0x00, 0x05, 
-	0x6d, 0xed, 0x00, 0x05, 0x6d, 0xe8, 0x00, 0x05, 
-	0xf0, 0x00, 0x00, 0x01, 0x81, 0x91, 0x6d, 0xea, 
-	0x00, 0x08, 0x73, 0x11, 0x00, 0x0e, 0xee, 0x07, 
-	0x76, 0xe7, 0x00, 0x41, 0x00, 0x24, 0x76, 0xe7, 
-	0x00, 0x46, 0x00, 0x25, 0x76, 0xe7, 0x00, 0x4b, 
-	0x00, 0x26, 0x76, 0xe7, 0x00, 0x50, 0x00, 0x27, 
-	0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 
-	0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfe, 0x88, 0x11, 
-	0x56, 0x06, 0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2, 
-	0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11, 0xf0, 0x10, 
-	0xff, 0xff, 0xfa, 0x45, 0x15, 0x60, 0x77, 0x16, 
-	0xff, 0xff, 0x77, 0x12, 0x00, 0x7b, 0x49, 0x11, 
-	0x10, 0x82, 0xf6, 0x03, 0xf0, 0x00, 0x00, 0x09, 
-	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 
-	0xf8, 0x44, 0x15, 0x71, 0xf2, 0x73, 0x15, 0x71, 
-	0xf4, 0x95, 0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b, 
-	0x10, 0x81, 0xf0, 0x00, 0x00, 0x09, 0x88, 0x11, 
-	0xf4, 0x95, 0x77, 0x12, 0x00, 0x06, 0x10, 0x81, 
-	0xf8, 0x45, 0x15, 0x5c, 0x6e, 0xea, 0xff, 0xff, 
-	0x15, 0x69, 0x6d, 0xe9, 0x00, 0x08, 0x76, 0x86, 
-	0x00, 0x01, 0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80, 
-	0x10, 0xf8, 0x00, 0x0b, 0xf8, 0x45, 0x15, 0x7e, 
-	0xfb, 0x80, 0x15, 0x85, 0xf4, 0x95, 0x48, 0x16, 
-	0xf9, 0x80, 0x16, 0x9a, 0xee, 0x02, 0x48, 0x16, 
-	0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 
-	0xee, 0xff, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 
-	0xf4, 0x95, 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 
-	0xf8, 0x30, 0x15, 0xc4, 0x10, 0xe1, 0x00, 0x03, 
-	0x77, 0x12, 0x00, 0x55, 0x80, 0x82, 0x77, 0x12, 
-	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, 
-	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, 
-	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, 
-	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12, 
-	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1, 
-	0x00, 0x02, 0xf0, 0x00, 0x00, 0x08, 0x32, 0xf8, 
-	0x00, 0x08, 0x77, 0x12, 0x00, 0x54, 0xe8, 0x01, 
-	0xf4, 0x82, 0xf4, 0x93, 0x18, 0x82, 0x77, 0x12, 
-	0x00, 0x54, 0xf0, 0x40, 0x00, 0x00, 0x80, 0x82, 
-	0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x76, 
-	0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x66, 
-	0xf0, 0x73, 0x16, 0x03, 0x77, 0x11, 0x00, 0x7b, 
-	0x71, 0x81, 0x00, 0x11, 0x71, 0xe1, 0x00, 0x07, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1, 
-	0x00, 0x09, 0xf9, 0x80, 0x15, 0x85, 0x77, 0x11, 
-	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1, 
-	0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00, 
-	0x00, 0x08, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81, 
-	0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80, 
-	0x15, 0x85, 0xf0, 0x00, 0x00, 0x10, 0x77, 0x11, 
-	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1, 
-	0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00, 
-	0x00, 0x18, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81, 
-	0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80, 
-	0x15, 0x85, 0xf0, 0x00, 0x00, 0x20, 0x77, 0x11, 
-	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1, 
-	0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00, 
-	0x00, 0x28, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 
-	0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 
-	0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 
-	0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 
-	0x16, 0x41, 0x77, 0x11, 0x00, 0x55, 0x76, 0x81, 
-	0x00, 0x1e, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81, 
-	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0xf2, 0x73, 
-	0x16, 0x4e, 0x76, 0x81, 0x00, 0x00, 0x77, 0x11, 
-	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x71, 0xe1, 
-	0x00, 0x07, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 
-	0x10, 0xe1, 0x00, 0x39, 0xf9, 0x80, 0x16, 0x08, 
-	0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 
-	0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b, 
-	0x10, 0x81, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x11, 
-	0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44, 
-	0x16, 0x63, 0xf4, 0x95, 0xee, 0xff, 0x76, 0x81, 
-	0x00, 0x01, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4, 
-	0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8, 
-	0x00, 0x08, 0xee, 0xff, 0x77, 0x11, 0x00, 0x01, 
-	0xe8, 0x01, 0xee, 0x01, 0xf4, 0x82, 0x1a, 0x81, 
-	0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-	0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8, 
-	0x00, 0x08, 0xee, 0xff, 0xe8, 0x01, 0x77, 0x11, 
-	0x00, 0x00, 0xf4, 0x82, 0xee, 0x01, 0xf4, 0x93, 
-	0x18, 0x81, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 
-	0xf4, 0xe4, 0x4a, 0x11, 0xf0, 0x10, 0x00, 0x10, 
-	0x77, 0x11, 0x00, 0x00, 0x32, 0xf8, 0x00, 0x08, 
-	0xee, 0xff, 0x11, 0x81, 0xe8, 0x01, 0xee, 0x01, 
-	0x77, 0x11, 0x00, 0x00, 0xf4, 0x82, 0xf2, 0xa0, 
-	0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-	0xf2, 0x73, 0x16, 0x9e, 0xf6, 0xbb, 0xf4, 0x95, 
-	0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4, 
-	0xf2, 0x73, 0x16, 0xa6, 0xf7, 0xbb, 0xf4, 0x95, 
-	0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4, 
-	0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 0x71, 0x04, 
-	0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 
-	0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x0e, 0x10, 0xe6, 0x00, 0x0e, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 
-	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x0d, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 
-	0x10, 0xe6, 0x00, 0x0d, 0x80, 0x82, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0c, 
-	0x10, 0xe6, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x0b, 0x10, 0xe6, 
-	0x00, 0x0b, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 
-	0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x10, 0xe6, 0x00, 0x0a, 0x80, 0x82, 
-	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x09, 0x10, 0xe6, 0x00, 0x09, 0x71, 0xe1, 
-	0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x08, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 
-	0x00, 0x08, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x07, 0x10, 0xe6, 
-	0x00, 0x07, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 
-	0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x10, 0xe6, 0x00, 0x06, 0x80, 0x82, 
-	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x05, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 
-	0x10, 0xe6, 0x00, 0x05, 0x80, 0x82, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x04, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 
-	0x00, 0x04, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x03, 0x71, 0xe1, 
-	0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 0x00, 0x03, 
-	0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x02, 0x10, 0xe6, 0x00, 0x02, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 
-	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x01, 0x10, 0xe6, 0x00, 0x01, 0x71, 0xe1, 
-	0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x13, 0xe7, 0x62, 
-	0xe5, 0x01, 0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16, 
-	0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 
-	0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 
-	0x00, 0x12, 0xee, 0xff, 0x76, 0x82, 0x00, 0x00, 
-	0xee, 0x01, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x11, 
-	0x69, 0x81, 0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95, 
-	0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95, 
-	0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0xee, 0xff, 0x76, 0x82, 0x00, 0x01, 0xee, 0x01, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x11, 0x69, 0x81, 
-	0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-	0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 
-	0xf0, 0x00, 0x00, 0x94, 0x88, 0x11, 0xf4, 0x95, 
-	0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44, 0x17, 0x9c, 
-	0xf4, 0x95, 0xee, 0xff, 0xf9, 0x80, 0x16, 0x53, 
-	0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00, 
-	0x00, 0x94, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 
-	0x76, 0x81, 0x00, 0x01, 0xee, 0x01, 0x76, 0xe1, 
-	0x00, 0x01, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 
-	0x00, 0x21, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x20, 
-	0x76, 0xe1, 0x00, 0x04, 0x00, 0x23, 0x76, 0xe1, 
-	0x00, 0x05, 0x00, 0x22, 0x76, 0xe1, 0x00, 0x06, 
-	0x00, 0x38, 0x76, 0xe1, 0x00, 0x07, 0x00, 0x39, 
-	0x76, 0xe1, 0x00, 0x08, 0x00, 0x15, 0x76, 0xe1, 
-	0x00, 0x09, 0x00, 0x14, 0x76, 0xe1, 0x00, 0x0a, 
-	0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x41, 
-	0x76, 0xe1, 0x00, 0x0c, 0x00, 0x40, 0x76, 0xe1, 
-	0x00, 0x0d, 0x00, 0x43, 0x76, 0xe1, 0x00, 0x0e, 
-	0x00, 0x42, 0x76, 0xe1, 0x00, 0x0f, 0x00, 0x48, 
-	0x76, 0xe1, 0x00, 0x10, 0x00, 0x49, 0x76, 0xe1, 
-	0x00, 0x11, 0x00, 0x1b, 0x76, 0xe1, 0x00, 0x12, 
-	0x00, 0x1a, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4, 
-	0x4a, 0x11, 0xee, 0xfd, 0x88, 0x11, 0x56, 0x06, 
-	0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2, 0x77, 0x12, 
-	0x00, 0x7b, 0x77, 0x0e, 0x00, 0x09, 0x10, 0x82, 
-	0x28, 0xf8, 0x00, 0x11, 0xf0, 0x00, 0x00, 0x95, 
-	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 
-	0xf8, 0x45, 0x17, 0xf0, 0xf2, 0x73, 0x17, 0xfd, 
-	0x77, 0x11, 0xff, 0xff, 0x76, 0x81, 0x00, 0x01, 
-	0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80, 0x10, 0xf8, 
-	0x00, 0x0b, 0xf8, 0x45, 0x17, 0xfd, 0xfb, 0x80, 
-	0x18, 0x10, 0xf4, 0x95, 0x48, 0x11, 0xf9, 0x80, 
-	0x16, 0x9a, 0xee, 0x03, 0x48, 0x11, 0x8a, 0x11, 
-	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 
-	0xf4, 0x95, 0xee, 0xff, 0x71, 0xe1, 0x00, 0x01, 
-	0x00, 0x11, 0xee, 0x01, 0x10, 0x81, 0x8a, 0x11, 
-	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 
-	0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 
-	0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 
-	0x18, 0xc3, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x01, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x02, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x03, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x04, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x05, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x01, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x07, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-	0x20, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x08, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x09, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0b, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 
-	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0d, 
-	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82, 
-	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 
-	0x76, 0x82, 0x00, 0x0e, 0x71, 0xe1, 0x00, 0x06, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1, 
-	0x00, 0x07, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1, 
-	0x00, 0x08, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1, 
-	0x00, 0x07, 0xf9, 0x80, 0x16, 0x66, 0x10, 0xe1, 
-	0x00, 0x08, 0xf9, 0x80, 0x16, 0x66, 0xf0, 0x73, 
-	0x18, 0xd1, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 
-	0xfb, 0x80, 0x18, 0x10, 0xf0, 0x00, 0x00, 0x95, 
-	0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xfb, 0x80, 
-	0x18, 0x10, 0xf0, 0x00, 0x00, 0x9e, 0xf9, 0x80, 
-	0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4, 
-	0x4a, 0x11, 0x88, 0x11, 0xee, 0xff, 0xf4, 0x95, 
-	0x10, 0x04, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x11, 
-	0xee, 0x01, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 
-	0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 
-	0x71, 0x04, 0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2, 
-	0x88, 0x11, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x02, 
-	0x00, 0x12, 0x76, 0x82, 0x00, 0x10, 0x10, 0xe6, 
-	0x00, 0x01, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x12, 
-	0x80, 0x82, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12, 
-	0x10, 0xe6, 0x00, 0x02, 0x80, 0x82, 0xe7, 0x62, 
-	0x71, 0xe1, 0x00, 0x02, 0x00, 0x13, 0xe5, 0x01, 
-	0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11, 
-	0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xee, 0xff, 
-	0xee, 0x01, 0x10, 0xe1, 0x00, 0x01, 0x8a, 0x11, 
-	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11, 
-	0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3, 
-	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 
-	0xfa, 0x44, 0x19, 0x2a, 0xf4, 0x95, 0xee, 0xff, 
-	0xf9, 0x80, 0x16, 0x53, 0x77, 0x11, 0x00, 0x7b, 
-	0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3, 0x88, 0x11, 
-	0xf4, 0x95, 0xf4, 0x95, 0x76, 0x81, 0x00, 0x01, 
-	0xee, 0x01, 0x76, 0xe1, 0x00, 0x01, 0x00, 0x00, 
-	0x76, 0xe1, 0x00, 0x02, 0x00, 0x13, 0x76, 0xe1, 
-	0x00, 0x03, 0x00, 0x26, 0x76, 0xe1, 0x00, 0x04, 
-	0x00, 0x25, 0x76, 0xe1, 0x00, 0x05, 0x00, 0x24, 
-	0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1, 
-	0x00, 0x07, 0x00, 0x17, 0x76, 0xe1, 0x00, 0x08, 
-	0x00, 0x32, 0x76, 0xe1, 0x00, 0x09, 0x00, 0x31, 
-	0x76, 0xe1, 0x00, 0x0a, 0x00, 0x30, 0x8a, 0x11, 
-	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 
-	0x4a, 0x17, 0xee, 0xff, 0xf4, 0x95, 0x71, 0x06, 
-	0x00, 0x17, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 
-	0xf4, 0x95, 0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11, 
-	0xf0, 0x10, 0xff, 0xff, 0xfa, 0x45, 0x19, 0x73, 
-	0x77, 0x16, 0xff, 0xff, 0x77, 0x12, 0x00, 0x7b, 
-	0x77, 0x0e, 0x00, 0x05, 0x10, 0x82, 0x28, 0xf8, 
-	0x00, 0x11, 0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11, 
-	0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf8, 0x44, 
-	0x19, 0x84, 0xf2, 0x73, 0x19, 0x84, 0xf4, 0x95, 
-	0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 
-	0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11, 0xf4, 0x95, 
-	0x77, 0x12, 0x00, 0x02, 0x10, 0x81, 0xf8, 0x45, 
-	0x19, 0x6f, 0x6e, 0xea, 0xff, 0xff, 0x19, 0x7c, 
-	0x6d, 0xe9, 0x00, 0x05, 0x61, 0xf8, 0x00, 0x17, 
-	0x00, 0x01, 0xfa, 0x20, 0x19, 0x8f, 0x76, 0x86, 
-	0x00, 0x01, 0xfb, 0x80, 0x19, 0x97, 0xf4, 0x95, 
-	0x48, 0x16, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 
-	0x8a, 0x17, 0x48, 0x16, 0x8a, 0x16, 0x8a, 0x11, 
-	0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 0xfb, 0x80, 
-	0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 
-	0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 0x19, 0xcc, 
-	0x71, 0xe1, 0x00, 0x02, 0x00, 0x12, 0x69, 0x82, 
-	0x00, 0x10, 0x71, 0xe1, 0x00, 0x02, 0x00, 0x12, 
-	0x68, 0x82, 0xf7, 0xff, 0x71, 0xe1, 0x00, 0x02, 
-	0x00, 0x12, 0x68, 0x82, 0xfb, 0xff, 0x71, 0xe1, 
-	0x00, 0x02, 0x00, 0x12, 0x68, 0x82, 0xff, 0xf0, 
-	0x71, 0xe1, 0x00, 0x03, 0x00, 0x12, 0x76, 0x82, 
-	0xff, 0xff, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12, 
-	0x76, 0x82, 0xff, 0xff, 0x71, 0xe1, 0x00, 0x02, 
-	0x00, 0x12, 0x69, 0x82, 0x00, 0x20, 0x71, 0xe1, 
-	0x00, 0x02, 0x00, 0x11, 0xf2, 0x73, 0x19, 0xda, 
-	0x68, 0x81, 0xff, 0xef, 0x77, 0x11, 0x00, 0x7b, 
-	0x10, 0x81, 0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00, 
-	0x00, 0xb4, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 
-	0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00, 0x00, 0xb9, 
-	0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 
-	0xf4, 0xe4, 0x00, 0xa4, 0x00, 0x00, 0x19, 0xdf, 
-	0x00, 0x01, 0x2a, 0xe6, 0x00, 0x00, 0x00, 0x01, 
-	0x2a, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x2a, 0x12, 
-	0x0c, 0x01, 0xc3, 0x4f, 0x00, 0x00, 0x00, 0x01, 
-	0x2a, 0x15, 0x00, 0x00, 0x00, 0x02, 0x2a, 0x16, 
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x2a, 0x5d, 
-	0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 
-	0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 
-	0x00, 0x74, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65, 
-	0x00, 0x63, 0x00, 0x68, 0x00, 0x6e, 0x00, 0x6f, 
-	0x00, 0x54, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 
-	0x00, 0x64, 0x00, 0x20, 0x00, 0x41, 0x00, 0x47, 
-	0x00, 0x00, 0x00, 0x04, 0x2a, 0x76, 0x00, 0x30, 
-	0x00, 0x2e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, 
-	0x2a, 0x7a, 0x00, 0x46, 0x00, 0x65, 0x00, 0x62, 
-	0x00, 0x20, 0x00, 0x32, 0x00, 0x37, 0x00, 0x20, 
-	0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 
-	0x00, 0x00, 0x00, 0x09, 0x2a, 0x86, 0x00, 0x31, 
-	0x00, 0x34, 0x00, 0x3a, 0x00, 0x33, 0x00, 0x35, 
-	0x00, 0x3a, 0x00, 0x33, 0x00, 0x33, 0x00, 0x00, 
-	0x00, 0x0f, 0x2a, 0x8f, 0x00, 0x00, 0x00, 0x00, 
-	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-	0x00, 0x00, 0x00, 0x01, 0x2a, 0x9e, 0x00, 0x00, 
-	0x00, 0x01, 0x2a, 0x9f, 0x00, 0x00, 0x00, 0x01, 
-	0x2a, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x2a, 0xa1, 
-	0x00, 0x00, 0x00, 0x01, 0x2a, 0xa2, 0x00, 0x00, 
-	0x00, 0x01, 0x29, 0x7e, 0x00, 0x00, 0x00, 0x02, 
-	0x29, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
-	0x29, 0x82, 0xff, 0xff, 0x00, 0x01, 0x2a, 0xa7, 
-	0x00, 0x00, 0x00, 0x05, 0x2a, 0xa8, 0x71, 0x41, 
-	0x20, 0x00, 0x20, 0x00, 0x00, 0x23, 0x04, 0x00, 
-	0x00, 0x0a, 0x2a, 0xad, 0x00, 0x00, 0x00, 0x00, 
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-	0x00, 0x0f, 0x2a, 0xb7, 0x00, 0x00, 0x00, 0x00, 
-	0x00, 0x00, 0x00, 0x40, 0x00, 0xa0, 0x82, 0x40, 
-	0x00, 0x08, 0x30, 0x7f, 0x00, 0x80, 0x01, 0x80, 
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
-	0x00, 0x00, 0x00, 0x01, 0x27, 0x6e, 0x00, 0x00, 
-	0x00, 0x01, 0x27, 0x6f, 0x00, 0x00, 0x00, 0x00, 
-	0x00, 0x09, 0x00, 0x00, 0x1a, 0x83, 0x04, 0xe8, 
-	0x04, 0xcf, 0x04, 0xc5, 0x04, 0xba, 0x04, 0xb0, 
-	0x04, 0xac, 0x04, 0x9c, 0x04, 0x8c, 0x04, 0x81, 
-	0x00, 0x78, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xaa, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x02, 0x23, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x05, 0xe5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x02, 0xb5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x0e, 0x33, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73, 
-	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0x00, 0x00, 
+	0x08, 0xaa, 0x00, 0x18, 0x00, 0x03, 0x08, 0x00,
+	0x00, 0x10, 0x00, 0x00, 0x01, 0x80, 0x18, 0x5f,
+	0x00, 0x00, 0x01, 0x80, 0x77, 0x18, 0x2a, 0xeb,
+	0x6b, 0xf8, 0x00, 0x18, 0x03, 0xff, 0x68, 0xf8,
+	0x00, 0x18, 0xff, 0xfe, 0xf7, 0xb8, 0xf7, 0xbe,
+	0xf6, 0xb9, 0xf4, 0xa0, 0xf6, 0xb7, 0xf6, 0xb5,
+	0xf6, 0xb6, 0xf0, 0x20, 0x19, 0xdf, 0xf1, 0x00,
+	0x00, 0x01, 0xf8, 0x4d, 0x01, 0xab, 0xf6, 0xb8,
+	0xf0, 0x20, 0x19, 0xdf, 0xf0, 0x73, 0x01, 0xa5,
+	0x7e, 0xf8, 0x00, 0x12, 0xf0, 0x00, 0x00, 0x01,
+	0x47, 0xf8, 0x00, 0x11, 0x7e, 0x92, 0x00, 0xf8,
+	0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x7e, 0xf8,
+	0x00, 0x11, 0xf0, 0x00, 0x00, 0x01, 0x6c, 0x89,
+	0x01, 0x9a, 0xf7, 0xb8, 0xee, 0xfc, 0xf0, 0x20,
+	0xff, 0xff, 0xf1, 0x00, 0x00, 0x01, 0xf8, 0x4d,
+	0x01, 0xbf, 0xf2, 0x73, 0x01, 0xb9, 0x4e, 0x02,
+	0xf4, 0x95, 0xf5, 0xe3, 0x56, 0x02, 0x7e, 0x00,
+	0x11, 0x00, 0xfa, 0x4c, 0x01, 0xb7, 0x6b, 0x03,
+	0x00, 0x01, 0xf6, 0xb8, 0xee, 0x04, 0xf0, 0x74,
+	0x0d, 0xa7, 0xf0, 0x74, 0x01, 0xc5, 0x4a, 0x11,
+	0x4a, 0x16, 0x72, 0x11, 0x2a, 0xe6, 0x10, 0xf8,
+	0x00, 0x11, 0xfa, 0x45, 0x01, 0xdb, 0xf4, 0x95,
+	0xee, 0xff, 0x48, 0x11, 0xf0, 0x00, 0x2a, 0xc6,
+	0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0xee,
+	0xff, 0xff, 0xf4, 0xe3, 0x6c, 0xe9, 0xff, 0xff,
+	0x01, 0xd5, 0x10, 0xf8, 0x2a, 0xe7, 0xf8, 0x45,
+	0x01, 0xe2, 0x10, 0xf8, 0x2a, 0xe7, 0xf4, 0xe3,
+	0xf0, 0x74, 0x01, 0xff, 0xee, 0x01, 0x8a, 0x16,
+	0x8a, 0x11, 0xfc, 0x00, 0xf7, 0xb8, 0xe9, 0x20,
+	0x4a, 0x11, 0x09, 0xf8, 0x2a, 0xe6, 0xf8, 0x4e,
+	0x01, 0xf3, 0xf2, 0x73, 0x01, 0xfd, 0xf4, 0x95,
+	0xe8, 0x01, 0x72, 0x11, 0x2a, 0xe6, 0x49, 0x11,
+	0x80, 0xe1, 0x2a, 0xc6, 0xf3, 0x00, 0x00, 0x01,
+	0xe8, 0x00, 0x81, 0xf8, 0x2a, 0xe6, 0x8a, 0x11,
+	0xfc, 0x00, 0xf4, 0x95, 0xf0, 0x73, 0x02, 0x00,
+	0x10, 0xf8, 0x2a, 0x0f, 0xfc, 0x00, 0x4a, 0x11,
+	0xf0, 0x74, 0x02, 0x02, 0x80, 0xf8, 0x2a, 0x10,
+	0x73, 0x08, 0x00, 0x09, 0x40, 0xf8, 0x2a, 0x15,
+	0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10,
+	0x03, 0xe8, 0xf5, 0xa9, 0xf8, 0x30, 0x02, 0x21,
+	0x71, 0xf8, 0x2a, 0x10, 0x2a, 0x15, 0x56, 0xf8,
+	0x2a, 0x0c, 0xf0, 0xe3, 0x4e, 0xf8, 0x2a, 0x16,
+	0xe8, 0x00, 0x4e, 0xf8, 0x2a, 0x0c, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d,
+	0x68, 0xf8, 0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8,
+	0x00, 0x07, 0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d,
+	0xff, 0xfc, 0x6b, 0xf8, 0x2a, 0x0f, 0x00, 0x01,
+	0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x06, 0xf4, 0xeb,
+	0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x0f, 0x00, 0x00,
+	0x76, 0x00, 0x00, 0x00, 0xfb, 0x80, 0x19, 0x4c,
+	0xf4, 0x95, 0xe8, 0x00, 0x80, 0xf8, 0x2a, 0x11,
+	0xf9, 0x80, 0x19, 0x07, 0x80, 0xf8, 0x2a, 0x0e,
+	0xf9, 0x80, 0x16, 0x66, 0x76, 0x00, 0x2a, 0x12,
+	0x10, 0xf8, 0x2a, 0x11, 0xf9, 0x80, 0x18, 0xe3,
+	0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x66,
+	0x10, 0xf8, 0x2a, 0x0e, 0xf9, 0x80, 0x16, 0x87,
+	0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf6, 0xb8,
+	0xf4, 0x95, 0xf0, 0x20, 0x80, 0x00, 0x11, 0xf8,
+	0x2a, 0x5a, 0xf8, 0x4d, 0x02, 0x93, 0x11, 0xf8,
+	0x2a, 0x9f, 0xf8, 0x4c, 0x02, 0x7c, 0x77, 0x12,
+	0x2a, 0x39, 0x49, 0x12, 0x01, 0xf8, 0x2a, 0x9f,
+	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81,
+	0x00, 0x11, 0x6c, 0xe1, 0xff, 0xab, 0x02, 0x93,
+	0x6b, 0xf8, 0x2a, 0x9f, 0x00, 0x01, 0xe9, 0x05,
+	0x01, 0xe2, 0x00, 0x03, 0x81, 0xf8, 0x2a, 0xa0,
+	0xf0, 0x73, 0x02, 0x95, 0x72, 0x11, 0x2a, 0x9f,
+	0xf4, 0x95, 0x10, 0xe1, 0x2a, 0x39, 0x6b, 0xf8,
+	0x2a, 0x9f, 0x00, 0x01, 0x11, 0xf8, 0x2a, 0x9f,
+	0x09, 0xf8, 0x2a, 0xa0, 0xf8, 0x4c, 0x02, 0x93,
+	0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00, 0x76, 0xf8,
+	0x2a, 0x9f, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa0,
+	0x00, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x48, 0x11,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
+	0x10, 0xf8, 0x2a, 0x5a, 0xf8, 0x44, 0x02, 0xb2,
+	0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x01, 0xf0, 0x74,
+	0x02, 0x58, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10,
+	0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30, 0x02, 0xb2,
+	0x48, 0x11, 0xf0, 0x30, 0x00, 0xff, 0x80, 0x00,
+	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0xd6,
+	0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95,
+	0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b,
+	0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11,
+	0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15,
+	0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19,
+	0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a,
+	0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8,
+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
+	0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe,
+	0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xfd,
+	0xf0, 0x74, 0x02, 0x58, 0x88, 0x11, 0xf4, 0x95,
+	0x77, 0x10, 0x80, 0x00, 0xf4, 0xa9, 0xf8, 0x30,
+	0x02, 0xef, 0x48, 0x11, 0xf0, 0x30, 0x00, 0xff,
+	0x80, 0x00, 0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80,
+	0x18, 0xd6, 0xee, 0x03, 0x8a, 0x18, 0xf4, 0x95,
+	0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d, 0x8a, 0x1a,
+	0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e, 0x8a, 0x19,
+	0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x15,
+	0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12, 0x8a, 0x11,
+	0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b,
+	0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08, 0xf4, 0xeb,
+	0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81,
+	0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2,
+	0x00, 0x01, 0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2,
+	0x00, 0x02, 0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1,
+	0x00, 0x03, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x04,
+	0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95,
+	0xf4, 0x95, 0x10, 0x81, 0x6f, 0xf8, 0x2a, 0x9e,
+	0x0c, 0x88, 0xe8, 0xff, 0x18, 0xe1, 0x00, 0x01,
+	0x1a, 0xf8, 0x2a, 0x9e, 0xf0, 0x30, 0x1f, 0xff,
+	0x80, 0xf8, 0x2a, 0x9e, 0x8a, 0x11, 0xfc, 0x00,
+	0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39, 0x76, 0x81,
+	0x00, 0x55, 0x77, 0x12, 0x2a, 0x18, 0x11, 0xe2,
+	0x00, 0x01, 0x81, 0xe1, 0x00, 0x01, 0x11, 0xe2,
+	0x00, 0x02, 0x81, 0xe1, 0x00, 0x02, 0x76, 0xe1,
+	0x00, 0x03, 0x00, 0x02, 0x48, 0x08, 0x6f, 0xe1,
+	0x00, 0x04, 0x0c, 0x98, 0xf0, 0x30, 0x00, 0xff,
+	0x80, 0xe1, 0x00, 0x05, 0x76, 0xe1, 0x00, 0x06,
+	0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11, 0x2a, 0x39,
+	0x76, 0x81, 0x00, 0x55, 0x77, 0x12, 0x2a, 0x18,
+	0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1, 0x00, 0x01,
+	0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1, 0x00, 0x02,
+	0x76, 0xe1, 0x00, 0x03, 0x00, 0x04, 0x48, 0x11,
+	0xf0, 0x00, 0x00, 0x04, 0x88, 0x12, 0xf4, 0x95,
+	0x77, 0x13, 0x2a, 0x76, 0xe9, 0x00, 0xe5, 0x98,
+	0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8, 0x48, 0x0b,
+	0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x03, 0x71,
+	0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xf0,
+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0x81,
+	0x00, 0x14, 0x71, 0xe1, 0x00, 0x01, 0x00, 0x15,
+	0x49, 0x11, 0xf3, 0x00, 0x00, 0x02, 0x89, 0x11,
+	0xe7, 0x82, 0x6d, 0xea, 0x00, 0x04, 0xe7, 0x83,
+	0x6d, 0xeb, 0x00, 0x0a, 0x77, 0x1a, 0x00, 0x05,
+	0xf0, 0x72, 0x03, 0xaa, 0x11, 0x81, 0xf2, 0xe8,
+	0x80, 0x82, 0xe9, 0xff, 0x19, 0xe1, 0x00, 0x01,
+	0xf1, 0xa0, 0x81, 0x92, 0x11, 0xe1, 0x00, 0x0c,
+	0xf2, 0xe8, 0x80, 0x83, 0xe9, 0xff, 0x19, 0xe1,
+	0x00, 0x0d, 0xf1, 0xa0, 0x81, 0x93, 0x6d, 0xe9,
+	0x00, 0x02, 0x48, 0x18, 0x49, 0x18, 0x70, 0x00,
+	0x00, 0x15, 0xf0, 0x00, 0x00, 0x04, 0xf3, 0x00,
+	0x00, 0x0a, 0x80, 0x01, 0x81, 0x02, 0xf2, 0x74,
+	0x0e, 0x54, 0xf4, 0x95, 0x48, 0x14, 0xee, 0x10,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf0, 0x74,
+	0x0c, 0x5e, 0x80, 0xf8, 0x2a, 0x5c, 0x77, 0x12,
+	0x2a, 0x39, 0x76, 0x82, 0x00, 0x55, 0x77, 0x11,
+	0x2a, 0x18, 0x10, 0xe1, 0x00, 0x01, 0x80, 0xe2,
+	0x00, 0x01, 0x10, 0xe1, 0x00, 0x02, 0x80, 0xe2,
+	0x00, 0x02, 0x76, 0xe2, 0x00, 0x03, 0x00, 0x1c,
+	0xf6, 0xb8, 0x56, 0xf8, 0x2a, 0x16, 0xf0, 0xf0,
+	0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x07, 0x56, 0xf8,
+	0x2a, 0x16, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80,
+	0x80, 0xe2, 0x00, 0x06, 0x56, 0xf8, 0x2a, 0x16,
+	0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2,
+	0x00, 0x05, 0x57, 0xf8, 0x2a, 0x16, 0xe8, 0xff,
+	0xf2, 0x80, 0x80, 0xe2, 0x00, 0x04, 0x56, 0xf8,
+	0x27, 0x6c, 0xf0, 0xf0, 0xf0, 0xf8, 0x80, 0xe2,
+	0x00, 0x0b, 0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf0,
+	0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0a,
+	0x56, 0xf8, 0x27, 0x6c, 0xf1, 0xf8, 0xe8, 0xff,
+	0xf2, 0x80, 0x80, 0xe2, 0x00, 0x09, 0xe8, 0xff,
+	0x57, 0xf8, 0x27, 0x6c, 0xf2, 0x80, 0x80, 0xe2,
+	0x00, 0x08, 0x56, 0xf8, 0x27, 0x6a, 0xf0, 0xf0,
+	0xf0, 0xf8, 0x80, 0xe2, 0x00, 0x0f, 0x56, 0xf8,
+	0x27, 0x6a, 0xf1, 0xf0, 0xe8, 0xff, 0xf2, 0x80,
+	0x80, 0xe2, 0x00, 0x0e, 0x56, 0xf8, 0x27, 0x6a,
+	0xf1, 0xf8, 0xe8, 0xff, 0xf2, 0x80, 0x80, 0xe2,
+	0x00, 0x0d, 0x57, 0xf8, 0x27, 0x6a, 0xe8, 0xff,
+	0xf2, 0x80, 0x80, 0xe2, 0x00, 0x0c, 0x76, 0xe2,
+	0x00, 0x13, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x12,
+	0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x5c, 0x0c, 0x58,
+	0x80, 0xe2, 0x00, 0x11, 0xe8, 0xff, 0x18, 0xf8,
+	0x2a, 0x5c, 0x80, 0xe2, 0x00, 0x10, 0x76, 0xe2,
+	0x00, 0x17, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x16,
+	0x00, 0x00, 0x6f, 0xf8, 0x2a, 0x9e, 0x0c, 0x58,
+	0x80, 0xe2, 0x00, 0x15, 0xe8, 0xff, 0x18, 0xf8,
+	0x2a, 0x9e, 0x80, 0xe2, 0x00, 0x14, 0x76, 0xe2,
+	0x00, 0x1b, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1a,
+	0x00, 0x00, 0x76, 0xe2, 0x00, 0x19, 0x00, 0x00,
+	0x70, 0xe2, 0x00, 0x18, 0x27, 0x6e, 0x76, 0xe2,
+	0x00, 0x1f, 0x00, 0x00, 0x76, 0xe2, 0x00, 0x1e,
+	0x00, 0x00, 0x76, 0xe2, 0x00, 0x1d, 0x00, 0x00,
+	0x76, 0xe2, 0x00, 0x1c, 0x00, 0x00, 0x76, 0xe2,
+	0x00, 0x20, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
+	0x10, 0xf8, 0x2a, 0x38, 0xf8, 0x45, 0x04, 0xed,
+	0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x02,
+	0x88, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x08,
+	0x6d, 0xe9, 0xff, 0xdf, 0xf6, 0xa9, 0xf8, 0x20,
+	0x04, 0x75, 0xf0, 0x73, 0x04, 0x7d, 0xf0, 0x10,
+	0x00, 0x21, 0xf0, 0x00, 0x1a, 0x83, 0x48, 0x08,
+	0x7e, 0xf8, 0x00, 0x08, 0xf4, 0xe2, 0xf0, 0x74,
+	0x03, 0x0a, 0xf0, 0x73, 0x04, 0xea, 0x48, 0x12,
+	0xf2, 0x74, 0x03, 0x23, 0xf0, 0x00, 0x00, 0x04,
+	0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00,
+	0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18,
+	0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48,
+	0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x69,
+	0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36,
+	0xf0, 0x73, 0x04, 0xea, 0x77, 0x11, 0x2a, 0x18,
+	0xe8, 0xff, 0x6f, 0xe1, 0x00, 0x04, 0x0d, 0x48,
+	0x18, 0xe1, 0x00, 0x05, 0xf2, 0x74, 0x09, 0x41,
+	0xf4, 0x95, 0xf2, 0xa0, 0xf0, 0x74, 0x03, 0x36,
+	0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0x57,
+	0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8, 0x2a, 0x1c,
+	0xf0, 0x74, 0x12, 0xa4, 0xf2, 0x74, 0x03, 0x36,
+	0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea,
+	0x48, 0x12, 0xf2, 0x74, 0x03, 0x80, 0xf0, 0x00,
+	0x00, 0x04, 0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95,
+	0xe8, 0x00, 0xf0, 0x73, 0x04, 0xea, 0x10, 0xf8,
+	0x2a, 0x1c, 0xf0, 0x74, 0x12, 0xc5, 0xf2, 0x74,
+	0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00, 0xf0, 0x73,
+	0x04, 0xea, 0x77, 0x11, 0x2a, 0x18, 0xe8, 0xff,
+	0x6f, 0xe1, 0x00, 0x06, 0x0d, 0x48, 0x18, 0xe1,
+	0x00, 0x07, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0xf2, 0xa0, 0x70, 0x00, 0x00, 0x12, 0x80, 0x01,
+	0x10, 0xe1, 0x00, 0x04, 0xf0, 0x74, 0x0e, 0x7a,
+	0xf2, 0x74, 0x03, 0x36, 0xf4, 0x95, 0xe8, 0x00,
+	0xf0, 0x73, 0x04, 0xea, 0xf0, 0x74, 0x03, 0xbc,
+	0x76, 0xf8, 0x2a, 0x38, 0x00, 0x00, 0xee, 0x02,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11,
+	0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12,
+	0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1,
+	0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1,
+	0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x09,
+	0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12,
+	0xf4, 0x95, 0x77, 0x13, 0x2a, 0x86, 0xe9, 0x00,
+	0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8,
+	0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43,
+	0x05, 0x0a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74,
+	0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
+	0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55,
+	0x77, 0x13, 0x2a, 0x18, 0x10, 0xe3, 0x00, 0x01,
+	0x80, 0xe1, 0x00, 0x01, 0x10, 0xe3, 0x00, 0x02,
+	0x80, 0xe1, 0x00, 0x02, 0x13, 0xe3, 0x00, 0x03,
+	0x81, 0xe1, 0x00, 0x03, 0x48, 0x11, 0x77, 0x11,
+	0x00, 0x00, 0xf8, 0x4d, 0x05, 0x44, 0xf0, 0x00,
+	0x00, 0x04, 0x88, 0x12, 0x48, 0x13, 0xf0, 0x00,
+	0x00, 0x04, 0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95,
+	0xe5, 0x98, 0x6d, 0x91, 0xf6, 0xb8, 0x48, 0x11,
+	0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43, 0x05, 0x3a,
+	0xf0, 0x20, 0x2a, 0x39, 0x49, 0x11, 0xf5, 0x00,
+	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x76, 0xe1,
+	0x00, 0x04, 0x00, 0xaa, 0xf0, 0x74, 0x02, 0x98,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x77, 0x11,
+	0x2a, 0x39, 0x76, 0x81, 0x00, 0x55, 0x77, 0x12,
+	0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01, 0x80, 0xe1,
+	0x00, 0x01, 0x10, 0xe2, 0x00, 0x02, 0x80, 0xe1,
+	0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x0c,
+	0x48, 0x11, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x12,
+	0xf4, 0x95, 0x77, 0x13, 0x2a, 0x7a, 0xe9, 0x00,
+	0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01, 0xf6, 0xb8,
+	0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c, 0xf8, 0x43,
+	0x05, 0x6a, 0x76, 0x82, 0x00, 0xaa, 0xf0, 0x74,
+	0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
+	0x77, 0x11, 0x2a, 0x39, 0x76, 0x81, 0x00, 0x55,
+	0x77, 0x12, 0x2a, 0x18, 0x10, 0xe2, 0x00, 0x01,
+	0x80, 0xe1, 0x00, 0x01, 0x10, 0xe2, 0x00, 0x02,
+	0x80, 0xe1, 0x00, 0x02, 0x76, 0xe1, 0x00, 0x03,
+	0x00, 0x19, 0x48, 0x11, 0xf0, 0x00, 0x00, 0x04,
+	0x88, 0x12, 0xf4, 0x95, 0x77, 0x13, 0x2a, 0x5d,
+	0xe9, 0x00, 0xe5, 0x98, 0xf3, 0x00, 0x00, 0x01,
+	0xf6, 0xb8, 0x48, 0x0b, 0x08, 0xf8, 0x2a, 0x3c,
+	0xf8, 0x43, 0x05, 0x93, 0x76, 0x82, 0x00, 0xaa,
+	0xf0, 0x74, 0x02, 0x98, 0x8a, 0x11, 0xfc, 0x00,
+	0x4a, 0x11, 0x88, 0x11, 0x10, 0xf8, 0x2a, 0x38,
+	0xf8, 0x44, 0x05, 0xe3, 0x10, 0xf8, 0x2a, 0xa1,
+	0xf8, 0x44, 0x05, 0xba, 0x6c, 0xe1, 0xff, 0x56,
+	0x05, 0xe3, 0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95,
+	0x70, 0xe2, 0x2a, 0x18, 0x00, 0x11, 0x6b, 0xf8,
+	0x2a, 0xa1, 0x00, 0x01, 0xf0, 0x73, 0x05, 0xe3,
+	0x72, 0x12, 0x2a, 0xa1, 0xf4, 0x95, 0x70, 0xe2,
+	0x2a, 0x18, 0x00, 0x11, 0x10, 0xf8, 0x2a, 0xa1,
+	0xf0, 0x00, 0x00, 0x01, 0x88, 0x12, 0xf4, 0x95,
+	0xf4, 0x95, 0x6e, 0xe2, 0xff, 0xfc, 0x05, 0xd1,
+	0x73, 0x12, 0x2a, 0xa1, 0x48, 0x11, 0xf0, 0x00,
+	0x00, 0x05, 0x80, 0xf8, 0x2a, 0xa2, 0x10, 0xf8,
+	0x2a, 0xa1, 0x08, 0xf8, 0x2a, 0xa2, 0xf8, 0x44,
+	0x05, 0xe3, 0x6c, 0xe1, 0xff, 0xab, 0x05, 0xdd,
+	0x76, 0xf8, 0x2a, 0x38, 0x00, 0x01, 0x76, 0xf8,
+	0x2a, 0xa1, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa2,
+	0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0xf4, 0x95,
+	0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a, 0x4a, 0x0b,
+	0x4a, 0x0c, 0x4a, 0x0d, 0x4a, 0x10, 0x4a, 0x11,
+	0x4a, 0x12, 0x4a, 0x13, 0x4a, 0x14, 0x4a, 0x15,
+	0x4a, 0x16, 0x4a, 0x17, 0x4a, 0x17, 0x4a, 0x19,
+	0x4a, 0x0e, 0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1a,
+	0x4a, 0x1d, 0x4a, 0x1b, 0x4a, 0x1c, 0x68, 0xf8,
+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
+	0x48, 0x18, 0x68, 0xf8, 0x00, 0x18, 0xff, 0xfe,
+	0xf4, 0x95, 0xf4, 0x95, 0x4a, 0x08, 0xee, 0xff,
+	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x18, 0x04,
+	0xf0, 0x74, 0x05, 0xa2, 0xee, 0x01, 0x8a, 0x18,
+	0xf4, 0x95, 0x8a, 0x1c, 0x8a, 0x1b, 0x8a, 0x1d,
+	0x8a, 0x1a, 0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0e,
+	0x8a, 0x19, 0x8a, 0x17, 0x8a, 0x17, 0x8a, 0x16,
+	0x8a, 0x15, 0x8a, 0x14, 0x8a, 0x13, 0x8a, 0x12,
+	0x8a, 0x11, 0x8a, 0x10, 0x8a, 0x0d, 0x8a, 0x0c,
+	0x8a, 0x0b, 0x8a, 0x0a, 0x8a, 0x09, 0x8a, 0x08,
+	0xf4, 0xeb, 0xee, 0xfd, 0x76, 0xf8, 0x2a, 0x38,
+	0x00, 0x00, 0x76, 0xf8, 0x2a, 0x5a, 0x00, 0x00,
+	0xe8, 0x01, 0x4e, 0x00, 0xfb, 0x80, 0x17, 0xd6,
+	0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x2a, 0x5b,
+	0x76, 0x00, 0x2a, 0x8f, 0xf9, 0x80, 0x16, 0xaa,
+	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x5c,
+	0x10, 0xf8, 0x2a, 0x5b, 0xf9, 0x80, 0x17, 0x6f,
+	0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1a,
+	0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1a,
+	0xfb, 0x80, 0x16, 0x66, 0xf4, 0x95, 0xe8, 0x1b,
+	0xfb, 0x80, 0x16, 0x87, 0xf4, 0x95, 0xe8, 0x1b,
+	0xee, 0x03, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95,
+	0x13, 0x02, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d,
+	0x06, 0x6a, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a,
+	0xf4, 0x95, 0xf0, 0x72, 0x06, 0x69, 0x1c, 0x91,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11,
+	0x12, 0x03, 0x11, 0x02, 0xf8, 0x45, 0x06, 0x79,
+	0xf0, 0x10, 0x00, 0x01, 0x88, 0x1a, 0xf4, 0x95,
+	0xf0, 0x72, 0x06, 0x78, 0x81, 0x91, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02,
+	0x00, 0x11, 0x11, 0x03, 0x61, 0xf8, 0x00, 0x11,
+	0x00, 0x01, 0xf8, 0x30, 0x06, 0x91, 0xf6, 0xb8,
+	0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11,
+	0xf3, 0xe8, 0xe8, 0xff, 0x18, 0x81, 0xf1, 0xa0,
+	0x81, 0x81, 0xf0, 0x73, 0x06, 0x9d, 0xf6, 0xb8,
+	0x6f, 0xf8, 0x00, 0x11, 0x0c, 0x1f, 0x88, 0x11,
+	0xf3, 0x30, 0x00, 0xff, 0xf0, 0x20, 0xff, 0x00,
+	0x18, 0x81, 0xf1, 0xa0, 0x81, 0x81, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x11, 0x02,
+	0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20,
+	0x06, 0xb1, 0x49, 0x0b, 0xf6, 0x1f, 0x88, 0x11,
+	0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf2, 0x73,
+	0x06, 0xb8, 0xf0, 0x30, 0x00, 0xff, 0x49, 0x0b,
+	0xf6, 0x1f, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95,
+	0x12, 0x81, 0xf4, 0x78, 0x8a, 0x11, 0xfc, 0x00,
+	0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x12,
+	0x13, 0x03, 0x88, 0x11, 0xe8, 0x00, 0xf8, 0x4d,
+	0x06, 0xcc, 0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a,
+	0xf4, 0x95, 0xf0, 0x72, 0x06, 0xcb, 0x11, 0x92,
+	0xf2, 0xc0, 0x81, 0x91, 0x8a, 0x11, 0xfc, 0x00,
+	0x88, 0x12, 0x12, 0x02, 0x71, 0x01, 0x00, 0x13,
+	0xf8, 0x45, 0x06, 0xdb, 0xf0, 0x10, 0x00, 0x01,
+	0x88, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x06, 0xda,
+	0xe5, 0x98, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
+	0x88, 0x11, 0x11, 0x04, 0x10, 0x06, 0x71, 0x05,
+	0x00, 0x12, 0x61, 0xf8, 0x00, 0x12, 0x00, 0x01,
+	0xf8, 0x20, 0x06, 0xea, 0xf0, 0x00, 0x00, 0x01,
+	0xf6, 0xb8, 0xf0, 0x00, 0x00, 0x01, 0x6f, 0xf8,
+	0x00, 0x12, 0x0f, 0x1f, 0x48, 0x08, 0x81, 0x00,
+	0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xba,
+	0xf4, 0x95, 0x48, 0x11, 0xee, 0x02, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x88, 0x12,
+	0x11, 0x04, 0x10, 0x06, 0x71, 0x05, 0x00, 0x13,
+	0x61, 0xf8, 0x00, 0x13, 0x00, 0x01, 0xf8, 0x20,
+	0x07, 0x09, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00,
+	0x00, 0x01, 0x88, 0x11, 0xf6, 0xb8, 0x6f, 0xf8,
+	0x00, 0x13, 0x0f, 0x1f, 0x81, 0x00, 0x48, 0x11,
+	0xf4, 0x7f, 0x80, 0x01, 0xf2, 0x74, 0x06, 0xce,
+	0xf4, 0x95, 0x48, 0x12, 0x48, 0x11, 0xf0, 0x30,
+	0xff, 0xfe, 0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00,
+	0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xfc,
+	0xf4, 0x95, 0x80, 0x02, 0x71, 0x08, 0x00, 0x16,
+	0x10, 0x09, 0x71, 0x0b, 0x00, 0x17, 0x80, 0x03,
+	0x71, 0x0a, 0x00, 0x11, 0x48, 0x17, 0xf8, 0x45,
+	0x07, 0x3f, 0x70, 0x00, 0x00, 0x11, 0x10, 0x03,
+	0xf0, 0x74, 0x06, 0x9f, 0x80, 0x01, 0x70, 0x00,
+	0x00, 0x16, 0x10, 0x02, 0xf0, 0x74, 0x06, 0x7b,
+	0x6d, 0x91, 0x6d, 0x96, 0x6c, 0xef, 0xff, 0xff,
+	0x07, 0x2f, 0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
+	0x10, 0xf8, 0x2a, 0xe8, 0x08, 0xf8, 0x2a, 0xe9,
+	0xf8, 0x45, 0x07, 0x64, 0x76, 0x00, 0x00, 0x01,
+	0x62, 0xf8, 0x2a, 0xe9, 0x00, 0x5e, 0xf2, 0x74,
+	0x12, 0x0b, 0xf0, 0x00, 0x30, 0x40, 0x72, 0x11,
+	0x2a, 0xe9, 0x77, 0x10, 0x00, 0x0f, 0xf5, 0xa9,
+	0xf8, 0x20, 0x07, 0x61, 0x6b, 0xf8, 0x2a, 0xe9,
+	0x00, 0x01, 0xf0, 0x73, 0x07, 0x64, 0x76, 0xf8,
+	0x2a, 0xe9, 0x00, 0x00, 0xee, 0x02, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0x88, 0x11, 0xe8, 0x00,
+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x08, 0xe8, 0x00,
+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x09, 0xf6, 0xb8,
+	0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f, 0x75, 0xf8,
+	0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20, 0x0c, 0x30,
+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c, 0x76, 0xf8,
+	0x2a, 0xe8, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xe9,
+	0x00, 0x00, 0x6c, 0x81, 0x07, 0x92, 0x76, 0xf8,
+	0x2a, 0xea, 0x00, 0x00, 0xfb, 0x80, 0x16, 0x76,
+	0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00, 0x75, 0xf8,
+	0x00, 0x08, 0x00, 0x00, 0xf0, 0x73, 0x07, 0xa8,
+	0x76, 0xf8, 0x2a, 0xea, 0x00, 0x01, 0xfb, 0x80,
+	0x16, 0x66, 0xf4, 0x95, 0xe8, 0x10, 0xfb, 0x80,
+	0x16, 0x87, 0xf4, 0x95, 0xe8, 0x10, 0xe8, 0x00,
+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0xf6, 0xb8,
+	0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff, 0x75, 0xf8,
+	0x00, 0x08, 0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00,
+	0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09, 0x4a, 0x0a,
+	0x4a, 0x06, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8,
+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
+	0x10, 0xf8, 0x2a, 0xea, 0xf8, 0x45, 0x07, 0xe1,
+	0x10, 0xf8, 0x2a, 0xe8, 0xf0, 0x00, 0x00, 0x01,
+	0xf0, 0x30, 0x00, 0x0f, 0x80, 0xf8, 0x2a, 0xe8,
+	0x10, 0xf8, 0x2a, 0xe8, 0xf8, 0x44, 0x07, 0xd6,
+	0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xfc, 0x3f,
+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x0d, 0xf0, 0x20,
+	0x0c, 0x30, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x0c,
+	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x00,
+	0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0xff,
+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x00, 0x8a, 0x1d,
+	0x8a, 0x07, 0x8a, 0x06, 0x8a, 0x0a, 0x8a, 0x09,
+	0x8a, 0x08, 0xf4, 0xeb, 0xee, 0xff, 0xf2, 0x74,
+	0x07, 0x67, 0xf4, 0x95, 0xe8, 0x01, 0xee, 0x01,
+	0xfc, 0x00, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8,
+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
+	0x8a, 0x1d, 0x8a, 0x07, 0xf4, 0xeb, 0x4a, 0x11,
+	0x77, 0x11, 0x00, 0x28, 0x76, 0x81, 0x24, 0x00,
+	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
+	0xf2, 0x74, 0x07, 0x67, 0xf4, 0x95, 0xe8, 0x00,
+	0x77, 0x11, 0x00, 0x1d, 0x68, 0x81, 0x00, 0x7f,
+	0xf6, 0xb8, 0xf4, 0x95, 0xf0, 0x20, 0xff, 0x80,
+	0x77, 0x11, 0x00, 0x1d, 0xf0, 0x30, 0x01, 0x00,
+	0x1a, 0x81, 0x80, 0x81, 0xf0, 0x74, 0x0a, 0x33,
+	0xf0, 0x74, 0x11, 0xac, 0xf9, 0x80, 0x13, 0x25,
+	0xf9, 0x80, 0x16, 0x53, 0xf9, 0x80, 0x17, 0x82,
+	0xf0, 0x74, 0x06, 0x2f, 0xf9, 0x80, 0x14, 0xb2,
+	0xf9, 0x80, 0x19, 0x10, 0xf0, 0x74, 0x0d, 0xe3,
+	0xf0, 0x74, 0x07, 0xe8, 0xf0, 0x74, 0x02, 0x36,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x60, 0xf8,
+	0x27, 0x7b, 0xff, 0xff, 0xf8, 0x30, 0x08, 0x39,
+	0x71, 0xf8, 0x27, 0x7b, 0x27, 0x79, 0x60, 0xf8,
+	0x27, 0x79, 0xff, 0xff, 0xf8, 0x30, 0x08, 0xb2,
+	0x10, 0xf8, 0x29, 0x86, 0x08, 0xf8, 0x27, 0x79,
+	0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11, 0xf4, 0x95,
+	0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x30,
+	0x08, 0x58, 0x10, 0xf8, 0x27, 0x79, 0x08, 0xf8,
+	0x27, 0x7a, 0xf0, 0x30, 0x7f, 0xff, 0x88, 0x11,
+	0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9,
+	0xf8, 0x20, 0x08, 0x63, 0x76, 0xf8, 0x27, 0x79,
+	0xff, 0xff, 0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff,
+	0xf7, 0xb8, 0xf2, 0x73, 0x08, 0xd9, 0xf0, 0x20,
+	0xff, 0xff, 0xf6, 0xb8, 0x56, 0xf8, 0x27, 0x74,
+	0xf0, 0xf9, 0x88, 0x11, 0x56, 0xf8, 0x27, 0x72,
+	0xf0, 0xf9, 0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95,
+	0xe7, 0x20, 0xf4, 0xa9, 0xf8, 0x30, 0x08, 0x8f,
+	0xf1, 0x20, 0x27, 0x7c, 0x48, 0x11, 0xf6, 0x00,
+	0x88, 0x13, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x83,
+	0x08, 0xf8, 0x27, 0x79, 0xf0, 0x30, 0x7f, 0xff,
+	0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x40, 0x00,
+	0xf5, 0xab, 0xf8, 0x30, 0x08, 0x8f, 0x6d, 0x91,
+	0x48, 0x11, 0xf0, 0x30, 0x01, 0xff, 0x88, 0x11,
+	0xf4, 0x95, 0xe7, 0x20, 0xf7, 0xa9, 0xf8, 0x30,
+	0x08, 0x74, 0x6d, 0x89, 0x48, 0x11, 0xf0, 0x30,
+	0x01, 0xff, 0xf0, 0xe7, 0xf4, 0x95, 0x48, 0x08,
+	0x4e, 0xf8, 0x27, 0x74, 0x48, 0x08, 0xf1, 0xf9,
+	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1,
+	0x27, 0x7c, 0x27, 0x7a, 0x60, 0xf8, 0x27, 0x7b,
+	0xff, 0xff, 0xf8, 0x30, 0x08, 0xab, 0x48, 0x08,
+	0x4e, 0xf8, 0x27, 0x72, 0x76, 0xf8, 0x27, 0x7b,
+	0xff, 0xff, 0x76, 0xf8, 0x27, 0x79, 0xff, 0xff,
+	0xf2, 0x73, 0x08, 0xd9, 0xf4, 0x95, 0xe8, 0x00,
+	0x44, 0xf8, 0x27, 0x73, 0x40, 0xf8, 0x27, 0x75,
+	0x82, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0x77, 0x10,
+	0x80, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xd8,
+	0xf6, 0xb8, 0x10, 0xf8, 0x27, 0x73, 0xf0, 0x00,
+	0x80, 0x00, 0x48, 0x08, 0x4e, 0xf8, 0x27, 0x74,
+	0x48, 0x08, 0xf0, 0xf9, 0x88, 0x11, 0xf4, 0x95,
+	0xf4, 0x95, 0x71, 0xe1, 0x27, 0x7c, 0x27, 0x7a,
+	0xf7, 0xb8, 0x57, 0xf8, 0x27, 0x74, 0xf0, 0x62,
+	0xff, 0xff, 0xf0, 0x40, 0xff, 0x80, 0xf2, 0x80,
+	0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfb,
+	0x11, 0xf8, 0x27, 0x71, 0x09, 0xf8, 0x27, 0x73,
+	0x89, 0x11, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95,
+	0xf6, 0xa9, 0xf8, 0x20, 0x08, 0xed, 0xf2, 0x73,
+	0x09, 0x0e, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0x20,
+	0x76, 0x00, 0x00, 0x41, 0xf0, 0x74, 0x12, 0xee,
+	0x88, 0x16, 0xf4, 0x95, 0xf7, 0xb8, 0x6d, 0x96,
+	0x10, 0xf8, 0x00, 0x16, 0xf8, 0x47, 0x09, 0x0a,
+	0xe7, 0x61, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01,
+	0x00, 0x80, 0x76, 0x02, 0x00, 0xff, 0x76, 0x03,
+	0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95,
+	0xe8, 0x00, 0x6c, 0xe9, 0xff, 0xff, 0x08, 0xfb,
+	0x73, 0x16, 0x00, 0x0e, 0xf0, 0x66, 0x00, 0x41,
+	0xee, 0x05, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00,
+	0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x13,
+	0xf6, 0xb8, 0x77, 0x11, 0x7f, 0xff, 0x57, 0xf8,
+	0x27, 0x72, 0x48, 0x11, 0xf2, 0x80, 0xf0, 0x00,
+	0x80, 0x00, 0x88, 0x11, 0xf6, 0x40, 0xf0, 0xe0,
+	0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80, 0x80, 0xf8,
+	0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x57, 0xf8,
+	0x27, 0x72, 0x48, 0x12, 0xf2, 0x80, 0x88, 0x12,
+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x09, 0x38,
+	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
+	0xf0, 0x73, 0x09, 0x3d, 0xf0, 0x20, 0x80, 0x01,
+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x70, 0x81,
+	0x00, 0x13, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
+	0xf0, 0x30, 0x7f, 0xff, 0x11, 0xf8, 0x29, 0x86,
+	0xf5, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11,
+	0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9,
+	0xf8, 0x20, 0x09, 0x54, 0xf2, 0x73, 0x09, 0x67,
+	0xf4, 0x95, 0xe8, 0x02, 0x6f, 0xf8, 0x27, 0x7a,
+	0x0d, 0x20, 0xf3, 0x30, 0x7f, 0xff, 0x89, 0x11,
+	0xf4, 0x95, 0x77, 0x10, 0x40, 0x00, 0xf6, 0xa9,
+	0xf8, 0x20, 0x09, 0x64, 0xf2, 0x73, 0x09, 0x67,
+	0xf4, 0x95, 0xe8, 0x01, 0x80, 0xf8, 0x27, 0x7b,
+	0xe8, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
+	0x11, 0xf8, 0x29, 0x86, 0xf5, 0x20, 0xf3, 0x30,
+	0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10,
+	0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x7a,
+	0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x02,
+	0x6f, 0xf8, 0x27, 0x7a, 0x0d, 0x20, 0xf3, 0x30,
+	0x7f, 0xff, 0x89, 0x11, 0xf4, 0x95, 0x77, 0x10,
+	0x40, 0x00, 0xf6, 0xa9, 0xf8, 0x20, 0x09, 0x8a,
+	0xf2, 0x73, 0x09, 0x8d, 0xf4, 0x95, 0xe8, 0x01,
+	0x80, 0xf8, 0x27, 0x79, 0xe8, 0x00, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02,
+	0x00, 0x12, 0x88, 0x11, 0xf6, 0xb8, 0x57, 0xf8,
+	0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80,
+	0xf0, 0x00, 0x80, 0x00, 0x80, 0x81, 0x57, 0xf8,
+	0x27, 0x72, 0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80,
+	0x80, 0xf8, 0x27, 0x78, 0x77, 0x11, 0x80, 0x00,
+	0x48, 0x11, 0x57, 0xf8, 0x27, 0x72, 0xf2, 0x80,
+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81,
+	0x09, 0xb5, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08,
+	0x00, 0x01, 0xf0, 0x73, 0x09, 0xba, 0xf0, 0x20,
+	0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
+	0x45, 0xf8, 0x27, 0x71, 0x43, 0xf8, 0x27, 0x73,
+	0x83, 0xf8, 0x00, 0x11, 0xf4, 0x95, 0xe7, 0x20,
+	0xf6, 0xa9, 0xf8, 0x30, 0x09, 0xc9, 0xf2, 0x73,
+	0x09, 0xe4, 0x77, 0x12, 0x00, 0x00, 0x57, 0xf8,
+	0x27, 0x72, 0xf0, 0x20, 0x7f, 0xff, 0xf2, 0x80,
+	0x49, 0x12, 0xf5, 0x00, 0xf3, 0x00, 0x80, 0x00,
+	0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00, 0xf8, 0x30,
+	0x09, 0xdc, 0xf1, 0x20, 0x80, 0x00, 0xf5, 0x20,
+	0x89, 0x12, 0xf4, 0x95, 0x48, 0x12, 0x6f, 0xf8,
+	0x27, 0x73, 0x0d, 0x00, 0xf4, 0x95, 0x49, 0x0b,
+	0x4f, 0xf8, 0x27, 0x72, 0x8a, 0x11, 0xfe, 0x00,
+	0x48, 0x12, 0xf4, 0x95, 0x4a, 0x11, 0x4a, 0x16,
+	0x4a, 0x17, 0xee, 0xfc, 0xf4, 0x95, 0x71, 0x08,
+	0x00, 0x16, 0x88, 0x17, 0xf0, 0x74, 0x08, 0x30,
+	0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74,
+	0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11,
+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0a, 0x0a,
+	0xf2, 0x74, 0x08, 0xdb, 0xf4, 0x95, 0x48, 0x16,
+	0x48, 0x18, 0x70, 0x00, 0x00, 0x16, 0xf2, 0x74,
+	0x09, 0x8f, 0xf0, 0x00, 0x00, 0x02, 0x88, 0x11,
+	0x10, 0x02, 0x70, 0x01, 0x00, 0x11, 0x80, 0x00,
+	0xf2, 0x74, 0x06, 0xce, 0xf4, 0x95, 0x48, 0x17,
+	0x49, 0x11, 0x48, 0x17, 0xf6, 0x00, 0x88, 0x17,
+	0xe7, 0x60, 0xf5, 0xa9, 0xf8, 0x20, 0x0a, 0x2d,
+	0x48, 0x16, 0xf6, 0x20, 0x88, 0x11, 0x48, 0x18,
+	0x70, 0x00, 0x00, 0x11, 0xf2, 0x74, 0x09, 0x8f,
+	0xf0, 0x00, 0x00, 0x02, 0x88, 0x11, 0x70, 0x01,
+	0x00, 0x11, 0x10, 0x02, 0x80, 0x00, 0xf2, 0x74,
+	0x06, 0xce, 0xf4, 0x95, 0x48, 0x17, 0xee, 0x04,
+	0x48, 0x16, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11,
+	0xfc, 0x00, 0xee, 0xfd, 0xe8, 0x00, 0x4e, 0xf8,
+	0x27, 0x70, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x72,
+	0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x74, 0xe8, 0x00,
+	0x4e, 0xf8, 0x27, 0x76, 0x76, 0xf8, 0x27, 0x79,
+	0xff, 0xff, 0x76, 0xf8, 0x27, 0x7a, 0x00, 0x00,
+	0x76, 0xf8, 0x27, 0x7b, 0xff, 0xff, 0x76, 0xf8,
+	0x27, 0x78, 0x00, 0x00, 0xe8, 0x00, 0x75, 0xf8,
+	0x00, 0x08, 0x00, 0x01, 0x76, 0x00, 0x00, 0x00,
+	0x76, 0x01, 0x02, 0x00, 0xf2, 0x74, 0x12, 0xdc,
+	0xf0, 0x20, 0x27, 0x7c, 0xee, 0x03, 0xfc, 0x00,
+	0x4a, 0x11, 0xee, 0xfc, 0xf4, 0x95, 0x4e, 0x00,
+	0x77, 0x12, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x12,
+	0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x12,
+	0xf0, 0xe0, 0xf1, 0xf1, 0x4f, 0x02, 0xe9, 0x01,
+	0xf4, 0x95, 0x48, 0x0b, 0xf5, 0x40, 0x56, 0x02,
+	0xf1, 0x80, 0x81, 0xf8, 0x27, 0x78, 0x77, 0x11,
+	0x80, 0x00, 0x56, 0x00, 0x49, 0x11, 0xf1, 0x80,
+	0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81,
+	0x0a, 0x81, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08,
+	0x00, 0x01, 0xf0, 0x73, 0x0a, 0x86, 0xf0, 0x20,
+	0x80, 0x01, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
+	0x10, 0x82, 0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00,
+	0x4a, 0x11, 0xee, 0xfe, 0xf4, 0x95, 0x4e, 0x00,
+	0x77, 0x11, 0x7f, 0xff, 0xf6, 0xb8, 0x49, 0x11,
+	0xf1, 0x80, 0xf3, 0x00, 0x80, 0x00, 0x89, 0x11,
+	0xf0, 0xe0, 0xf1, 0xf1, 0xe8, 0x01, 0xf2, 0x80,
+	0x80, 0xf8, 0x27, 0x78, 0x56, 0x00, 0xf1, 0x20,
+	0x80, 0x00, 0xf1, 0x80, 0xf4, 0x95, 0x49, 0x0b,
+	0xf8, 0x4d, 0x0a, 0xab, 0xf0, 0x20, 0x80, 0x01,
+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf0, 0x73,
+	0x0a, 0xaf, 0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08,
+	0x00, 0x01, 0xee, 0x02, 0x48, 0x11, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0x88, 0x12, 0x13, 0x02,
+	0x77, 0x11, 0x00, 0x00, 0xf8, 0x4d, 0x0a, 0xcb,
+	0xf3, 0x10, 0x00, 0x01, 0x89, 0x1a, 0xf4, 0x95,
+	0xf0, 0x72, 0x0a, 0xca, 0x48, 0x11, 0x1c, 0xf8,
+	0x29, 0x7e, 0x88, 0x11, 0x11, 0xf8, 0x29, 0x7e,
+	0xf2, 0x00, 0x00, 0x01, 0x80, 0xf8, 0x29, 0x7e,
+	0x81, 0x92, 0x48, 0x11, 0x8a, 0x11, 0xfc, 0x00,
+	0x4a, 0x11, 0xf4, 0x95, 0x71, 0x02, 0x00, 0x11,
+	0x88, 0x12, 0xf6, 0xb8, 0xf0, 0x20, 0x7f, 0xff,
+	0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0xf0, 0x00,
+	0x80, 0x00, 0x80, 0x82, 0x57, 0xf8, 0x27, 0x70,
+	0xe8, 0x01, 0xf3, 0xf1, 0xf2, 0x80, 0x80, 0xf8,
+	0x27, 0x78, 0x77, 0x12, 0x80, 0x00, 0x48, 0x12,
+	0x57, 0xf8, 0x27, 0x70, 0xf2, 0x80, 0x88, 0x12,
+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x82, 0x0a, 0xf4,
+	0xe8, 0x00, 0x75, 0xf8, 0x00, 0x08, 0x00, 0x01,
+	0xf0, 0x73, 0x0a, 0xf9, 0xf0, 0x20, 0x80, 0x01,
+	0x75, 0xf8, 0x00, 0x08, 0x00, 0x01, 0x45, 0xf8,
+	0x27, 0x75, 0xe7, 0x10, 0x43, 0xf8, 0x27, 0x71,
+	0x83, 0xf8, 0x00, 0x12, 0x6d, 0xe8, 0x00, 0x04,
+	0x6d, 0x8a, 0xf6, 0xaa, 0xf8, 0x30, 0x0b, 0x0a,
+	0xf2, 0x73, 0x0b, 0x25, 0x77, 0x11, 0x00, 0x00,
+	0x57, 0xf8, 0x27, 0x70, 0xf0, 0x20, 0x7f, 0xff,
+	0xf2, 0x80, 0x49, 0x11, 0xf5, 0x00, 0xf3, 0x00,
+	0x80, 0x00, 0x61, 0xf8, 0x00, 0x0b, 0x80, 0x00,
+	0xf8, 0x30, 0x0b, 0x1d, 0xf1, 0x20, 0x80, 0x00,
+	0xf5, 0x20, 0x89, 0x11, 0xf4, 0x95, 0x48, 0x11,
+	0x6f, 0xf8, 0x27, 0x71, 0x0d, 0x00, 0xf4, 0x95,
+	0x49, 0x0b, 0x4f, 0xf8, 0x27, 0x70, 0x48, 0x11,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16,
+	0x4a, 0x17, 0xee, 0xf0, 0x88, 0x17, 0x10, 0x17,
+	0x80, 0x05, 0x10, 0x16, 0x80, 0x06, 0x10, 0x15,
+	0x80, 0x07, 0x71, 0x14, 0x00, 0x11, 0x10, 0x05,
+	0xf0, 0x30, 0x00, 0x01, 0x88, 0x10, 0x10, 0x06,
+	0xf0, 0x30, 0x00, 0x01, 0x80, 0x08, 0x49, 0x11,
+	0x10, 0x05, 0xf6, 0x01, 0x80, 0x09, 0x10, 0x06,
+	0x61, 0xf8, 0x00, 0x08, 0x00, 0x01, 0xf8, 0x20,
+	0x0b, 0x4b, 0x10, 0x09, 0xf0, 0x00, 0x00, 0x01,
+	0x80, 0x09, 0x71, 0x08, 0x00, 0x12, 0xf4, 0xaa,
+	0xf8, 0x30, 0x0b, 0x54, 0x10, 0x09, 0xf0, 0x00,
+	0x00, 0x01, 0x80, 0x09, 0x12, 0x09, 0x49, 0x11,
+	0xf4, 0x7f, 0x80, 0x09, 0xf6, 0x20, 0x80, 0x0a,
+	0x56, 0xf8, 0x27, 0x70, 0x4e, 0x0c, 0x10, 0x09,
+	0x80, 0x00, 0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce,
+	0xf0, 0x00, 0x00, 0x04, 0x88, 0x16, 0xf4, 0x95,
+	0xf4, 0x95, 0x6c, 0x86, 0x0b, 0x6d, 0xf2, 0x73,
+	0x0c, 0x59, 0xf4, 0x95, 0xe8, 0x00, 0xf6, 0xb8,
+	0xf4, 0x95, 0x56, 0x0c, 0xf0, 0xf9, 0x88, 0x12,
+	0xf4, 0x95, 0xf4, 0x95, 0x70, 0xe2, 0x27, 0x7c,
+	0x29, 0x86, 0xe8, 0x00, 0x80, 0x0e, 0x48, 0x11,
+	0xf8, 0x45, 0x0b, 0xcc, 0x77, 0x10, 0x00, 0x01,
+	0xf4, 0xa9, 0xf8, 0x30, 0x0b, 0x89, 0x6c, 0xe1,
+	0xff, 0xfd, 0x0b, 0x8b, 0x10, 0xe7, 0x00, 0x02,
+	0x80, 0x0e, 0xf0, 0x73, 0x0b, 0x8b, 0x10, 0x87,
+	0x80, 0x0e, 0xe7, 0x10, 0xf5, 0xae, 0xf8, 0x20,
+	0x0b, 0xb2, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01,
+	0x00, 0x16, 0x10, 0x04, 0xf0, 0x74, 0x06, 0xce,
+	0x48, 0x17, 0x49, 0x16, 0xf6, 0x00, 0x88, 0x17,
+	0x48, 0x11, 0xf6, 0x20, 0x88, 0x11, 0x10, 0x09,
+	0xf6, 0x20, 0x80, 0x00, 0x48, 0x18, 0xf2, 0x74,
+	0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x16,
+	0x10, 0x04, 0x70, 0x00, 0x00, 0x17, 0x70, 0x01,
+	0x00, 0x11, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11,
+	0x00, 0x04, 0x80, 0x04, 0xf0, 0x73, 0x0b, 0xbc,
+	0x70, 0x00, 0x00, 0x17, 0x70, 0x01, 0x00, 0x11,
+	0x10, 0x04, 0xf0, 0x74, 0x06, 0xce, 0x48, 0x11,
+	0x00, 0x04, 0x80, 0x04, 0x49, 0x11, 0x48, 0x16,
+	0xf6, 0x20, 0x88, 0x16, 0xf4, 0x95, 0xf4, 0x95,
+	0x6c, 0x86, 0x0b, 0xcc, 0x10, 0x0a, 0x80, 0x00,
+	0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00,
+	0x00, 0x04, 0x88, 0x16, 0x12, 0x0a, 0xf8, 0x45,
+	0x0c, 0x33, 0x71, 0x0a, 0x00, 0x10, 0xf4, 0xae,
+	0xf8, 0x30, 0x0c, 0x1c, 0x48, 0x16, 0xf0, 0xe1,
+	0x88, 0x11, 0x12, 0x08, 0xf8, 0x45, 0x0b, 0xdb,
+	0x6d, 0x89, 0x12, 0x07, 0xf8, 0x45, 0x0b, 0xe9,
+	0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11,
+	0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74,
+	0x06, 0xdc, 0xf0, 0x73, 0x0b, 0xef, 0x48, 0x11,
+	0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74,
+	0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e,
+	0x10, 0x06, 0x49, 0x11, 0xf6, 0x00, 0x80, 0x06,
+	0x10, 0x05, 0xf6, 0x20, 0x88, 0x11, 0xf0, 0x00,
+	0x00, 0x01, 0x48, 0x08, 0x6f, 0x00, 0x0c, 0x9f,
+	0x48, 0x18, 0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00,
+	0x00, 0x04, 0x12, 0x07, 0xf8, 0x45, 0x0c, 0x11,
+	0x10, 0x07, 0x80, 0x00, 0x70, 0x02, 0x00, 0x11,
+	0x10, 0x06, 0x80, 0x01, 0x10, 0x04, 0xf0, 0x74,
+	0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x17, 0x48, 0x11,
+	0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04, 0xf0, 0x74,
+	0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0, 0x81, 0x0e,
+	0xf0, 0x73, 0x0c, 0x33, 0x12, 0x07, 0xf8, 0x45,
+	0x0c, 0x2a, 0x10, 0x07, 0x80, 0x00, 0x10, 0x06,
+	0x80, 0x01, 0x10, 0x05, 0x80, 0x02, 0x10, 0x04,
+	0xf0, 0x74, 0x06, 0xdc, 0xf0, 0x73, 0x0c, 0x30,
+	0x12, 0x05, 0x6f, 0x00, 0x0c, 0x9f, 0x10, 0x04,
+	0xf0, 0x74, 0x0a, 0xb3, 0x11, 0x0e, 0xf1, 0xc0,
+	0x81, 0x0e, 0x76, 0x00, 0x00, 0x01, 0x48, 0x18,
+	0xf2, 0x74, 0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04,
+	0x71, 0x04, 0x00, 0x11, 0x70, 0x81, 0x29, 0x86,
+	0x10, 0x0e, 0x1c, 0xf8, 0x29, 0x86, 0x80, 0x0e,
+	0x76, 0x00, 0x00, 0x01, 0x48, 0x18, 0xf2, 0x74,
+	0x0a, 0xce, 0xf0, 0x00, 0x00, 0x04, 0x10, 0x0e,
+	0x71, 0x04, 0x00, 0x11, 0x80, 0x81, 0x10, 0xf8,
+	0x29, 0x86, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x30,
+	0x7f, 0xff, 0x80, 0xf8, 0x29, 0x86, 0x10, 0x09,
+	0xf0, 0x00, 0x00, 0x02, 0x80, 0x09, 0xee, 0x10,
+	0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00,
+	0x10, 0xf8, 0x27, 0x75, 0x08, 0xf8, 0x27, 0x71,
+	0xf0, 0x10, 0x00, 0x01, 0x48, 0x08, 0xfc, 0x00,
+	0x4a, 0x11, 0x4a, 0x16, 0xee, 0xff, 0xf4, 0x95,
+	0x71, 0x04, 0x00, 0x16, 0xf0, 0x00, 0x00, 0x01,
+	0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c, 0x6d, 0xee,
+	0xff, 0xfd, 0x48, 0x16, 0xf8, 0x45, 0x0c, 0x99,
+	0x56, 0xf8, 0x29, 0x7c, 0xf0, 0x74, 0x0a, 0x5a,
+	0x88, 0x11, 0x10, 0xf8, 0x29, 0x7d, 0xf0, 0x00,
+	0x00, 0x01, 0x48, 0x08, 0x4e, 0xf8, 0x29, 0x7c,
+	0x10, 0xf8, 0x29, 0x82, 0xf0, 0x00, 0x00, 0x01,
+	0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xa9,
+	0xfa, 0x30, 0x0c, 0x96, 0x80, 0xf8, 0x29, 0x82,
+	0x56, 0xf8, 0x29, 0x80, 0xf0, 0x00, 0x00, 0x01,
+	0x4e, 0xf8, 0x29, 0x80, 0x73, 0x11, 0x29, 0x82,
+	0x6c, 0xee, 0xff, 0xff, 0x0c, 0x76, 0xee, 0x01,
+	0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
+	0x76, 0xf8, 0x29, 0x84, 0x00, 0x00, 0x76, 0xf8,
+	0x29, 0x85, 0x00, 0x01, 0xe8, 0x00, 0x4e, 0xf8,
+	0x2a, 0x0c, 0x76, 0xf8, 0x29, 0x86, 0x00, 0x00,
+	0x76, 0xf8, 0x29, 0x87, 0x00, 0x00, 0x77, 0x11,
+	0x29, 0x88, 0x76, 0x81, 0xaa, 0xaa, 0x76, 0xe1,
+	0x00, 0x01, 0xaa, 0xaa, 0x76, 0xe1, 0x00, 0x02,
+	0x00, 0x00, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
+	0xee, 0xfc, 0xf4, 0x95, 0x71, 0x06, 0x00, 0x14,
+	0x71, 0x07, 0x00, 0x13, 0x71, 0x08, 0x00, 0x12,
+	0x71, 0x09, 0x00, 0x15, 0x77, 0x10, 0x00, 0xff,
+	0xf4, 0xaa, 0xf8, 0x30, 0x0d, 0x44, 0x49, 0x13,
+	0x53, 0xf8, 0x2a, 0x0c, 0x4f, 0xf8, 0x2a, 0x0c,
+	0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d,
+	0x89, 0x11, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x01,
+	0x71, 0xe1, 0x24, 0x00, 0x00, 0x11, 0xf4, 0xa9,
+	0xf8, 0x30, 0x0d, 0x17, 0x77, 0x10, 0x00, 0x02,
+	0xf4, 0xa9, 0xf8, 0x30, 0x0c, 0xec, 0x77, 0x11,
+	0x29, 0x8a, 0x76, 0x81, 0x00, 0x00, 0xe8, 0x00,
+	0x77, 0x14, 0x00, 0x00, 0x77, 0x13, 0x00, 0x00,
+	0xf0, 0x73, 0x0d, 0x48, 0x6c, 0x83, 0x0c, 0xfa,
+	0x77, 0x11, 0x29, 0x8a, 0x48, 0x12, 0xf0, 0xe8,
+	0xf0, 0x40, 0x80, 0x00, 0x80, 0x81, 0xe8, 0x00,
+	0x77, 0x14, 0x00, 0x00, 0xf0, 0x73, 0x0d, 0x48,
+	0x49, 0x13, 0xf3, 0x40, 0x80, 0x00, 0x81, 0xf8,
+	0x29, 0x8a, 0x61, 0xf8, 0x00, 0x15, 0x00, 0x01,
+	0xf8, 0x20, 0x0d, 0x07, 0x69, 0xf8, 0x29, 0x8a,
+	0x40, 0x00, 0x61, 0xf8, 0x00, 0x14, 0x00, 0x01,
+	0xf8, 0x20, 0x0d, 0x0f, 0x69, 0xf8, 0x29, 0x8a,
+	0x20, 0x00, 0x77, 0x11, 0x29, 0x8a, 0x49, 0x12,
+	0xf3, 0xe8, 0x1b, 0x81, 0x81, 0x81, 0xf0, 0x73,
+	0x0d, 0x48, 0x11, 0xf8, 0x29, 0x84, 0xf8, 0x4c,
+	0x0d, 0x37, 0x77, 0x11, 0x29, 0x88, 0x76, 0x81,
+	0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85, 0xf3, 0x10,
+	0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00, 0x81, 0xe1,
+	0x00, 0x01, 0x76, 0x00, 0x00, 0x02, 0x80, 0x01,
+	0x70, 0x02, 0x00, 0x14, 0x70, 0x03, 0x00, 0x13,
+	0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0x48, 0x11,
+	0x71, 0xf8, 0x29, 0x85, 0x29, 0x84, 0xf0, 0x73,
+	0x0d, 0x73, 0x76, 0x00, 0x00, 0x00, 0x80, 0x01,
+	0x76, 0x02, 0x00, 0x00, 0x70, 0x03, 0x00, 0x13,
+	0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95, 0xe8, 0x00,
+	0xf0, 0x73, 0x0d, 0x73, 0x77, 0x11, 0x29, 0x8a,
+	0x70, 0x81, 0x00, 0x13, 0x11, 0xf8, 0x29, 0x84,
+	0xf8, 0x4c, 0x0d, 0x68, 0x77, 0x11, 0x29, 0x88,
+	0x76, 0x81, 0xaa, 0xaa, 0x11, 0xf8, 0x29, 0x85,
+	0xf3, 0x10, 0x00, 0x01, 0xf3, 0x40, 0xaa, 0x00,
+	0x81, 0xe1, 0x00, 0x01, 0x76, 0x00, 0x00, 0x03,
+	0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03,
+	0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95,
+	0x48, 0x11, 0x71, 0xf8, 0x29, 0x85, 0x29, 0x84,
+	0xf0, 0x73, 0x0d, 0x73, 0x76, 0x00, 0x00, 0x01,
+	0x80, 0x01, 0x70, 0x02, 0x00, 0x14, 0x70, 0x03,
+	0x00, 0x13, 0xf2, 0x74, 0x0b, 0x28, 0xf4, 0x95,
+	0x48, 0x11, 0x6b, 0xf8, 0x29, 0x84, 0xff, 0xff,
+	0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
+	0xf5, 0x40, 0xf4, 0x95, 0x48, 0x0b, 0xf4, 0x78,
+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe1,
+	0xff, 0xb9, 0x0d, 0x88, 0xf2, 0x73, 0x0d, 0xa5,
+	0xf4, 0x95, 0xe8, 0x60, 0xf2, 0x00, 0x00, 0x06,
+	0x61, 0xf8, 0x00, 0x11, 0x00, 0x20, 0xf8, 0x30,
+	0x0d, 0x98, 0x61, 0xf8, 0x00, 0x0b, 0x00, 0x01,
+	0xf8, 0x20, 0x0d, 0xa3, 0xf2, 0x00, 0x00, 0x07,
+	0xf0, 0x73, 0x0d, 0xa3, 0x61, 0xf8, 0x00, 0x0b,
+	0x00, 0x01, 0xf8, 0x20, 0x0d, 0xa1, 0xf2, 0x73,
+	0x0d, 0xa3, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x00,
+	0x00, 0x02, 0x48, 0x08, 0xf4, 0x7f, 0x8a, 0x11,
+	0xfc, 0x00, 0xee, 0xff, 0xf0, 0x74, 0x07, 0xfd,
+	0xf0, 0x74, 0x07, 0x44, 0xf0, 0x74, 0x0d, 0xb4,
+	0xf0, 0x74, 0x02, 0x05, 0xf0, 0x74, 0x04, 0x60,
+	0xf0, 0x73, 0x0d, 0xaa, 0xee, 0xfd, 0x10, 0xf8,
+	0x2a, 0xa3, 0xf8, 0x44, 0x0d, 0xcb, 0x10, 0xf8,
+	0x2a, 0xa4, 0xf8, 0x45, 0x0d, 0xd7, 0x76, 0x00,
+	0x02, 0x00, 0xf2, 0x74, 0x09, 0xe8, 0xf0, 0x20,
+	0x22, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00,
+	0x76, 0xf8, 0x2a, 0xa7, 0x00, 0x00, 0xf0, 0x73,
+	0x0d, 0xd7, 0x76, 0x00, 0x02, 0x00, 0xf2, 0x74,
+	0x09, 0xe8, 0xf0, 0x20, 0x20, 0x00, 0x76, 0xf8,
+	0x2a, 0xa3, 0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa7,
+	0x00, 0x01, 0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0,
+	0xf0, 0x10, 0x3a, 0x98, 0xf8, 0x47, 0x0d, 0xe1,
+	0x76, 0xf8, 0x27, 0x6e, 0x00, 0x00, 0xee, 0x03,
+	0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe, 0x77, 0x11,
+	0x20, 0x00, 0x76, 0x00, 0xaa, 0xaa, 0x76, 0x01,
+	0x02, 0x00, 0xf2, 0x74, 0x06, 0x6c, 0xf4, 0x95,
+	0x48, 0x11, 0x76, 0x00, 0x55, 0x55, 0x76, 0x01,
+	0x02, 0x00, 0x48, 0x11, 0xf2, 0x74, 0x06, 0x6c,
+	0xf0, 0x00, 0x02, 0x00, 0x76, 0xf8, 0x2a, 0xa3,
+	0x00, 0x00, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x00,
+	0xe8, 0x00, 0x4e, 0x00, 0xfb, 0x80, 0x15, 0x3e,
+	0xf4, 0x95, 0xe8, 0x04, 0x80, 0xf8, 0x2a, 0xa5,
+	0x76, 0x00, 0x2a, 0xa8, 0xf9, 0x80, 0x14, 0x87,
+	0x76, 0x00, 0x2a, 0xad, 0xfb, 0x80, 0x13, 0x62,
+	0xf4, 0x95, 0xe8, 0x02, 0x10, 0xf8, 0x2a, 0xa5,
+	0xf9, 0x80, 0x14, 0x63, 0xfb, 0x80, 0x16, 0x66,
+	0xf4, 0x95, 0xe8, 0x1c, 0xfb, 0x80, 0x16, 0x87,
+	0xf4, 0x95, 0xe8, 0x1c, 0xe8, 0x01, 0x4e, 0x00,
+	0xfb, 0x80, 0x17, 0xd6, 0xf4, 0x95, 0xe8, 0x00,
+	0x80, 0xf8, 0x2a, 0xa6, 0x76, 0x00, 0x2a, 0xb7,
+	0xf9, 0x80, 0x16, 0xaa, 0x10, 0xf8, 0x2a, 0xa6,
+	0xf9, 0x80, 0x17, 0x5c, 0x10, 0xf8, 0x2a, 0xa6,
+	0xf9, 0x80, 0x17, 0x6f, 0xee, 0x02, 0x8a, 0x11,
+	0xfc, 0x00, 0xf4, 0x95, 0x4a, 0x08, 0x4a, 0x09,
+	0x4a, 0x0a, 0x4a, 0x07, 0x4a, 0x1d, 0x68, 0xf8,
+	0x00, 0x07, 0x7d, 0x3f, 0x69, 0xf8, 0x00, 0x07,
+	0x40, 0x00, 0x68, 0xf8, 0x00, 0x1d, 0xff, 0xfc,
+	0x10, 0xf8, 0x2a, 0xa7, 0xf8, 0x44, 0x0e, 0x4b,
+	0x76, 0xf8, 0x2a, 0xa3, 0x00, 0x01, 0xf0, 0x73,
+	0x0e, 0x4e, 0x76, 0xf8, 0x2a, 0xa4, 0x00, 0x01,
+	0x8a, 0x1d, 0x8a, 0x07, 0x8a, 0x0a, 0x8a, 0x09,
+	0x8a, 0x08, 0xf4, 0xeb, 0x4a, 0x11, 0x4a, 0x16,
+	0x4a, 0x17, 0xee, 0xfe, 0x88, 0x0e, 0x71, 0x08,
+	0x00, 0x16, 0x71, 0x06, 0x00, 0x17, 0x11, 0x07,
+	0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00, 0x25, 0xa0,
+	0x88, 0x11, 0x76, 0x01, 0x00, 0x06, 0x81, 0x00,
+	0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00, 0x00, 0x01,
+	0x76, 0x01, 0x00, 0x06, 0x70, 0x00, 0x00, 0x16,
+	0x48, 0x11, 0xf2, 0x74, 0x06, 0xce, 0xf0, 0x00,
+	0x00, 0x07, 0x70, 0x81, 0x00, 0x17, 0xee, 0x02,
+	0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xfc, 0x00,
+	0x4a, 0x11, 0x88, 0x0e, 0x71, 0x02, 0x00, 0x12,
+	0x11, 0x03, 0xf0, 0x66, 0x00, 0x0d, 0xf0, 0x00,
+	0x24, 0x00, 0x88, 0x11, 0xf4, 0x95, 0x70, 0x81,
+	0x00, 0x12, 0x6e, 0xe2, 0xff, 0xfe, 0x0e, 0x8d,
+	0xf4, 0x95, 0xe8, 0x00, 0xe8, 0x01, 0x80, 0xe1,
+	0x00, 0x02, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff,
+	0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1,
+	0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0c,
+	0x00, 0x00, 0x81, 0xe1, 0x00, 0x01, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc, 0x88, 0x0e,
+	0xf4, 0x95, 0xf1, 0x66, 0x00, 0x0d, 0xf3, 0x00,
+	0x24, 0x00, 0x89, 0x11, 0xf4, 0x95, 0xf4, 0x95,
+	0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1,
+	0x00, 0x0b, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
+	0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 0x76, 0x01,
+	0x00, 0x00, 0x80, 0x02, 0x76, 0x03, 0x00, 0x00,
+	0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0xe8, 0x00,
+	0xee, 0x04, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
+	0x88, 0x19, 0xf4, 0x95, 0x73, 0x19, 0x00, 0x0e,
+	0xf1, 0x66, 0x00, 0x0d, 0xf2, 0x00, 0x24, 0x00,
+	0x77, 0x15, 0x25, 0xa0, 0x77, 0x14, 0x00, 0x00,
+	0x77, 0x1a, 0x00, 0x1f, 0xf0, 0x72, 0x0f, 0x14,
+	0xf6, 0xb8, 0x49, 0x19, 0x09, 0x85, 0xf8, 0x4c,
+	0x0f, 0x13, 0xf1, 0x00, 0x00, 0x05, 0x89, 0x11,
+	0x49, 0x15, 0xf3, 0x00, 0x00, 0x01, 0x89, 0x13,
+	0x49, 0x15, 0xf3, 0x00, 0x00, 0x07, 0x89, 0x12,
+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x10,
+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x80, 0x0f, 0x13,
+	0x11, 0x93, 0x1d, 0x91, 0x19, 0x92, 0x89, 0x11,
+	0xf4, 0x95, 0xf4, 0x95, 0x6c, 0x81, 0x0f, 0x13,
+	0x6d, 0x94, 0x6d, 0xed, 0x00, 0x0d, 0x48, 0x14,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16,
+	0x4a, 0x17, 0xee, 0xf8, 0x88, 0x17, 0x10, 0x0d,
+	0x80, 0x04, 0x10, 0x0c, 0x80, 0x05, 0x71, 0x0e,
+	0x00, 0x16, 0x73, 0x17, 0x00, 0x0e, 0xf0, 0x66,
+	0x00, 0x0d, 0xf0, 0x00, 0x24, 0x00, 0x88, 0x11,
+	0x10, 0xf8, 0x27, 0x63, 0xf8, 0x45, 0x0f, 0x32,
+	0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17,
+	0x10, 0xf8, 0x27, 0x60, 0xf8, 0x44, 0x0f, 0x3d,
+	0x60, 0xe1, 0x00, 0x02, 0x00, 0x01, 0xf8, 0x20,
+	0x0f, 0x6d, 0xf0, 0x73, 0x11, 0x33, 0x10, 0x04,
+	0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f,
+	0x11, 0x04, 0xf3, 0x00, 0x00, 0x01, 0x81, 0x04,
+	0x6d, 0x8e, 0x77, 0x10, 0x00, 0x01, 0x71, 0xe1,
+	0x00, 0x02, 0x00, 0x12, 0xf4, 0xaa, 0xf8, 0x30,
+	0x0f, 0x62, 0x77, 0x10, 0x00, 0x02, 0xf4, 0xaa,
+	0xf8, 0x30, 0x0f, 0x6d, 0x45, 0xe1, 0x00, 0x0b,
+	0x88, 0x10, 0x43, 0xe1, 0x00, 0x0c, 0x83, 0xf8,
+	0x00, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xaa,
+	0xf8, 0x30, 0x0f, 0x6d, 0xf0, 0x73, 0x0f, 0x96,
+	0xf5, 0x00, 0x81, 0x04, 0x49, 0x16, 0xf5, 0x20,
+	0x89, 0x16, 0x76, 0xe1, 0x00, 0x0c, 0x00, 0x00,
+	0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x48, 0x16,
+	0xf8, 0x45, 0x11, 0x33, 0xf7, 0xb8, 0x71, 0xe1,
+	0x00, 0x02, 0x00, 0x12, 0x10, 0xf8, 0x00, 0x12,
+	0xf0, 0x10, 0x00, 0x03, 0xf8, 0x46, 0x0f, 0x8c,
+	0x10, 0xf8, 0x00, 0x12, 0xf0, 0x10, 0x00, 0x03,
+	0xf8, 0x45, 0x10, 0x16, 0x77, 0x10, 0x00, 0x01,
+	0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0x9c, 0x77, 0x10,
+	0x00, 0x02, 0xf4, 0xaa, 0xf8, 0x30, 0x0f, 0xa8,
+	0xf0, 0x73, 0x0f, 0x96, 0x77, 0x10, 0x00, 0x04,
+	0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xb7, 0x77, 0x10,
+	0x00, 0x05, 0xf4, 0xaa, 0xf8, 0x30, 0x10, 0xbc,
+	0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17,
+	0xf0, 0x73, 0x11, 0x31, 0x76, 0xe1, 0x00, 0x0c,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00,
+	0x76, 0xe1, 0x00, 0x04, 0x00, 0x00, 0x76, 0xe1,
+	0x00, 0x02, 0x00, 0x02, 0x11, 0xe1, 0x00, 0x0c,
+	0xe8, 0x03, 0xf6, 0x20, 0x89, 0x12, 0xf4, 0x95,
+	0x77, 0x10, 0x00, 0x03, 0xf5, 0xaa, 0xf8, 0x30,
+	0x0f, 0xb6, 0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01,
+	0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95, 0xf5, 0xae,
+	0xf8, 0x20, 0x0f, 0xbd, 0x48, 0x16, 0x80, 0x06,
+	0x88, 0x13, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x03,
+	0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xc8, 0x6b, 0xf8,
+	0x27, 0x6f, 0x00, 0x01, 0x12, 0x06, 0xf8, 0x45,
+	0x10, 0x00, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00,
+	0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02,
+	0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74,
+	0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06,
+	0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04,
+	0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1,
+	0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04,
+	0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20,
+	0x88, 0x16, 0x89, 0x13, 0xf4, 0x95, 0x77, 0x10,
+	0x00, 0x03, 0xf6, 0xab, 0xf8, 0x20, 0x0f, 0xf5,
+	0x6b, 0xf8, 0x27, 0x6f, 0x00, 0x01, 0x77, 0x10,
+	0x00, 0x0c, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x13,
+	0xf6, 0xab, 0xf8, 0x20, 0x10, 0x00, 0x6b, 0xf8,
+	0x27, 0x6f, 0x00, 0x01, 0x6c, 0xe2, 0xff, 0xfd,
+	0x11, 0x31, 0xf6, 0xb8, 0x6f, 0xe1, 0x00, 0x05,
+	0x0c, 0x48, 0x6f, 0xe1, 0x00, 0x06, 0x0c, 0x18,
+	0xf0, 0x30, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x03,
+	0x80, 0xe1, 0x00, 0x0b, 0x76, 0xe1, 0x00, 0x02,
+	0x00, 0x03, 0x48, 0x16, 0xf8, 0x45, 0x11, 0x33,
+	0x71, 0xe1, 0x00, 0x0c, 0x00, 0x12, 0x10, 0xe1,
+	0x00, 0x0b, 0x49, 0x12, 0xf6, 0x20, 0x88, 0x13,
+	0xe8, 0x0c, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95,
+	0xf4, 0x95, 0xf5, 0xab, 0xf8, 0x20, 0x10, 0x27,
+	0x48, 0x13, 0x80, 0x06, 0x88, 0x10, 0xf4, 0x95,
+	0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0x30,
+	0x70, 0x06, 0x00, 0x16, 0x12, 0x06, 0xf8, 0x45,
+	0x10, 0x5f, 0x10, 0xe1, 0x00, 0x04, 0x80, 0x00,
+	0x10, 0x05, 0x80, 0x01, 0x10, 0x04, 0x80, 0x02,
+	0x10, 0x06, 0x80, 0x03, 0x48, 0x11, 0xf2, 0x74,
+	0x07, 0x1e, 0xf0, 0x00, 0x00, 0x05, 0x10, 0x06,
+	0x00, 0xe1, 0x00, 0x04, 0x80, 0xe1, 0x00, 0x04,
+	0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1,
+	0x00, 0x0c, 0x88, 0x12, 0x11, 0x06, 0x10, 0x04,
+	0xf6, 0x00, 0x80, 0x04, 0x48, 0x16, 0xf6, 0x20,
+	0x88, 0x16, 0xf4, 0x95, 0x77, 0x10, 0x00, 0x0c,
+	0x71, 0xe1, 0x00, 0x04, 0x00, 0x13, 0xf6, 0xab,
+	0xf8, 0x20, 0x10, 0x5f, 0x6b, 0xf8, 0x27, 0x6f,
+	0x00, 0x01, 0x77, 0x10, 0x00, 0x0c, 0xf6, 0xaa,
+	0xf8, 0x20, 0x10, 0x6b, 0xf2, 0x74, 0x0e, 0x9f,
+	0xf4, 0x95, 0x48, 0x17, 0x71, 0xe1, 0x00, 0x0c,
+	0x00, 0x12, 0x77, 0x10, 0x00, 0x0c, 0xf4, 0xaa,
+	0xf8, 0x30, 0x10, 0x7c, 0x77, 0x10, 0x00, 0x0c,
+	0x71, 0xe1, 0x00, 0x0b, 0x00, 0x13, 0xf6, 0xab,
+	0xf8, 0x30, 0x10, 0xb4, 0xe7, 0x30, 0xf7, 0xaa,
+	0xf8, 0x30, 0x10, 0xb4, 0xf2, 0x74, 0x0e, 0xc1,
+	0xf4, 0x95, 0x48, 0x17, 0x88, 0x12, 0xf4, 0x95,
+	0xf4, 0x95, 0x6c, 0x82, 0x10, 0x8d, 0x76, 0xe1,
+	0x00, 0x04, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
+	0x00, 0x05, 0xf0, 0x73, 0x10, 0xb4, 0x76, 0xe1,
+	0x00, 0x02, 0x00, 0x04, 0x77, 0x10, 0x00, 0x0c,
+	0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf5, 0xaa,
+	0xf8, 0x20, 0x10, 0x9a, 0xf0, 0x73, 0x10, 0x9c,
+	0x77, 0x12, 0x00, 0x0c, 0x76, 0x00, 0x00, 0x00,
+	0x70, 0x01, 0x00, 0x12, 0x70, 0x02, 0x00, 0x17,
+	0x76, 0x03, 0x00, 0x01, 0x48, 0x11, 0xf2, 0x74,
+	0x0c, 0xb9, 0xf0, 0x00, 0x00, 0x05, 0x76, 0xe1,
+	0x00, 0x04, 0x00, 0x00, 0x77, 0x10, 0x00, 0x0c,
+	0x71, 0xe1, 0x00, 0x0b, 0x00, 0x12, 0xf6, 0xaa,
+	0xf8, 0x20, 0x11, 0x1c, 0x48, 0x16, 0xf8, 0x45,
+	0x11, 0x33, 0x60, 0xe1, 0x00, 0x02, 0x00, 0x05,
+	0xf8, 0x20, 0x10, 0xdf, 0x10, 0xe1, 0x00, 0x0b,
+	0x08, 0xe1, 0x00, 0x0c, 0x11, 0xe1, 0x00, 0x04,
+	0xf8, 0x4d, 0x10, 0xc7, 0x6b, 0xf8, 0x27, 0x6f,
+	0x00, 0x01, 0x88, 0x10, 0xf4, 0x95, 0xf4, 0x95,
+	0xf5, 0xae, 0xf8, 0x20, 0x10, 0xcf, 0x48, 0x16,
+	0xf4, 0x95, 0x48, 0x08, 0xf8, 0x45, 0x11, 0x16,
+	0x6f, 0xe1, 0x00, 0x0c, 0x0d, 0x00, 0x81, 0xe1,
+	0x00, 0x0c, 0x11, 0x04, 0xf5, 0x00, 0x81, 0x04,
+	0x49, 0x16, 0xf5, 0x20, 0x89, 0x16, 0xf0, 0x73,
+	0x11, 0x0e, 0x10, 0xe1, 0x00, 0x0b, 0x71, 0xe1,
+	0x00, 0x0c, 0x00, 0x12, 0x88, 0x10, 0xf4, 0x95,
+	0xf4, 0x95, 0xf6, 0xaa, 0xf8, 0x30, 0x11, 0x16,
+	0x49, 0x12, 0xf6, 0x20, 0x88, 0x10, 0xf4, 0x95,
+	0xf4, 0x95, 0xf5, 0xae, 0xf8, 0x20, 0x10, 0xf3,
+	0x48, 0x16, 0x80, 0x06, 0x48, 0x08, 0xf8, 0x45,
+	0x11, 0x16, 0x10, 0x04, 0x70, 0x02, 0x00, 0x17,
+	0x80, 0x00, 0x76, 0x03, 0x00, 0x00, 0x10, 0x06,
+	0x80, 0x01, 0x10, 0x05, 0xf0, 0x74, 0x0c, 0xb9,
+	0x10, 0x06, 0x00, 0xe1, 0x00, 0x0c, 0x80, 0xe1,
+	0x00, 0x0c, 0x11, 0x06, 0x10, 0x04, 0xf6, 0x00,
+	0x80, 0x04, 0x48, 0x16, 0xf6, 0x20, 0x88, 0x16,
+	0x10, 0xe1, 0x00, 0x0c, 0x08, 0xe1, 0x00, 0x0b,
+	0xf8, 0x45, 0x11, 0x1c, 0xf0, 0x73, 0x11, 0x31,
+	0xf2, 0x74, 0x0e, 0x9f, 0xf4, 0x95, 0x48, 0x17,
+	0xf0, 0x73, 0x11, 0x33, 0x76, 0xe1, 0x00, 0x0c,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x00,
+	0x76, 0xe1, 0x00, 0x02, 0x00, 0x01, 0x10, 0x04,
+	0x80, 0x00, 0x10, 0x05, 0xf0, 0x74, 0x06, 0x9f,
+	0x88, 0x12, 0xf4, 0x95, 0x77, 0x10, 0x00, 0xff,
+	0xf4, 0xaa, 0xf8, 0x30, 0x11, 0x33, 0x6c, 0x86,
+	0x0f, 0x70, 0xee, 0x08, 0x8a, 0x17, 0x8a, 0x16,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfc,
+	0xf4, 0x95, 0x71, 0x06, 0x00, 0x12, 0x88, 0x11,
+	0x73, 0x12, 0x00, 0x0e, 0xf1, 0x66, 0x00, 0x0d,
+	0xf3, 0x00, 0x24, 0x00, 0x89, 0x14, 0x13, 0x81,
+	0xf7, 0x7a, 0xf3, 0x30, 0x00, 0x01, 0x81, 0xf8,
+	0x27, 0x60, 0x13, 0xe1, 0x00, 0x01, 0xf7, 0x7c,
+	0xf3, 0x30, 0x00, 0x03, 0x81, 0xf8, 0x27, 0x61,
+	0xe9, 0x0f, 0x19, 0xe1, 0x00, 0x01, 0x81, 0xf8,
+	0x27, 0x62, 0x71, 0xe4, 0x00, 0x03, 0x00, 0x13,
+	0xf6, 0xb8, 0x49, 0x13, 0xf3, 0x00, 0x00, 0x01,
+	0xf3, 0x30, 0x00, 0x0f, 0x49, 0x0b, 0x09, 0xf8,
+	0x27, 0x62, 0xf8, 0x4d, 0x11, 0x75, 0x77, 0x10,
+	0x00, 0xff, 0xf4, 0xab, 0xf8, 0x30, 0x11, 0x75,
+	0x57, 0xf8, 0x27, 0x6c, 0xf3, 0x00, 0x00, 0x01,
+	0x4f, 0xf8, 0x27, 0x6c, 0x76, 0xf8, 0x27, 0x63,
+	0x00, 0x01, 0xf0, 0x73, 0x11, 0x78, 0x76, 0xf8,
+	0x27, 0x63, 0x00, 0x00, 0x70, 0xe4, 0x00, 0x03,
+	0x27, 0x62, 0x76, 0xf8, 0x27, 0x64, 0x00, 0x00,
+	0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8, 0x00, 0x0b,
+	0x00, 0x02, 0xf8, 0x20, 0x11, 0x8d, 0xe9, 0x01,
+	0x6f, 0xe1, 0x00, 0x02, 0x0f, 0x18, 0x81, 0xf8,
+	0x27, 0x64, 0x11, 0xf8, 0x27, 0x61, 0x61, 0xf8,
+	0x00, 0x0b, 0x00, 0x01, 0xf8, 0x20, 0x11, 0xa9,
+	0x10, 0xf8, 0x27, 0x64, 0xf1, 0x00, 0x00, 0x04,
+	0x89, 0x13, 0xe9, 0xb8, 0xf5, 0x20, 0x81, 0xf8,
+	0x27, 0x65, 0x60, 0x84, 0x00, 0x02, 0xf8, 0x20,
+	0x11, 0xa9, 0x70, 0x00, 0x00, 0x11, 0x70, 0x01,
+	0x00, 0x13, 0x70, 0x02, 0x27, 0x65, 0xf2, 0x74,
+	0x0f, 0x18, 0xf4, 0x95, 0x48, 0x12, 0xee, 0x04,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16,
+	0x4a, 0x17, 0xee, 0xfc, 0xe8, 0x00, 0x4e, 0xf8,
+	0x27, 0x66, 0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x68,
+	0xe8, 0x00, 0x4e, 0xf8, 0x27, 0x6c, 0xe8, 0x00,
+	0x4e, 0xf8, 0x27, 0x6a, 0x77, 0x12, 0x27, 0x40,
+	0x77, 0x11, 0x24, 0x00, 0x77, 0x1a, 0x00, 0x1f,
+	0xf0, 0x72, 0x11, 0xdb, 0x70, 0x92, 0x00, 0x11,
+	0x76, 0xe1, 0x00, 0x01, 0xff, 0xff, 0x76, 0x81,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x02, 0x00, 0x00,
+	0x76, 0xe1, 0x00, 0x03, 0x00, 0xff, 0x76, 0xe1,
+	0x00, 0x0c, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00,
+	0x6d, 0xe9, 0x00, 0x0d, 0xf0, 0x20, 0x25, 0xa0,
+	0xf1, 0x00, 0x00, 0x07, 0x89, 0x11, 0xf1, 0x00,
+	0x00, 0x01, 0x81, 0x02, 0x88, 0x16, 0xf4, 0x95,
+	0x77, 0x17, 0x00, 0x20, 0x76, 0x86, 0x00, 0xff,
+	0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0x06,
+	0x10, 0x02, 0xf0, 0x74, 0x06, 0x6c, 0x76, 0x00,
+	0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74,
+	0x06, 0x6c, 0xf4, 0x95, 0x48, 0x11, 0x10, 0x02,
+	0xf0, 0x00, 0x00, 0x0d, 0x80, 0x02, 0x6d, 0xe9,
+	0x00, 0x0d, 0x6d, 0xee, 0x00, 0x0d, 0x6c, 0xef,
+	0xff, 0xff, 0x11, 0xe8, 0xf0, 0x74, 0x0c, 0x9d,
+	0xee, 0x04, 0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11,
+	0xfc, 0x00, 0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17,
+	0xee, 0xfa, 0x88, 0x11, 0x10, 0x0a, 0x49, 0x11,
+	0xf8, 0x4d, 0x12, 0x9f, 0x48, 0x08, 0xf8, 0x45,
+	0x12, 0x9f, 0x80, 0x04, 0x12, 0x81, 0xf5, 0x78,
+	0x89, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x6c, 0xe2,
+	0xff, 0xb9, 0x12, 0x8a, 0x61, 0xf8, 0x00, 0x08,
+	0x00, 0x80, 0xf8, 0x30, 0x12, 0x8a, 0x13, 0xe1,
+	0x00, 0x01, 0xf0, 0xe8, 0xf7, 0x78, 0xf1, 0xa0,
+	0xf2, 0x30, 0x1f, 0xff, 0x88, 0x17, 0xf4, 0x95,
+	0x77, 0x12, 0x24, 0x00, 0x77, 0x16, 0x00, 0x00,
+	0x77, 0x13, 0x00, 0x20, 0xf6, 0xb8, 0x48, 0x17,
+	0x08, 0xe2, 0x00, 0x01, 0xf8, 0x45, 0x12, 0x42,
+	0x6d, 0xea, 0x00, 0x0d, 0x6d, 0x96, 0x6c, 0xeb,
+	0xff, 0xff, 0x12, 0x34, 0xf0, 0x73, 0x12, 0x90,
+	0x56, 0xf8, 0x27, 0x6a, 0xf0, 0x00, 0x00, 0x01,
+	0x4e, 0xf8, 0x27, 0x6a, 0x60, 0x82, 0x00, 0x01,
+	0xf8, 0x30, 0x12, 0x54, 0x70, 0x00, 0x00, 0x16,
+	0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11,
+	0xf0, 0x73, 0x12, 0x90, 0x70, 0x00, 0x00, 0x16,
+	0xf2, 0x74, 0x11, 0x38, 0xf4, 0x95, 0x48, 0x11,
+	0x72, 0x10, 0x2a, 0x9e, 0xf4, 0x95, 0xf4, 0xaf,
+	0xf8, 0x30, 0x12, 0x6e, 0x76, 0x00, 0x00, 0x00,
+	0x76, 0x01, 0x00, 0xbc, 0x70, 0x02, 0x00, 0x16,
+	0x76, 0x03, 0x00, 0x00, 0xf2, 0x74, 0x0c, 0xb9,
+	0xf4, 0x95, 0x48, 0x11, 0xf0, 0x73, 0x12, 0x90,
+	0x10, 0xf8, 0x27, 0x6e, 0xf8, 0x44, 0x12, 0x90,
+	0x76, 0x00, 0x00, 0x00, 0x76, 0x01, 0x00, 0xbc,
+	0x70, 0x02, 0x00, 0x16, 0x76, 0x03, 0x00, 0x00,
+	0xf2, 0x74, 0x0c, 0xb9, 0xf4, 0x95, 0x48, 0x11,
+	0xf0, 0x74, 0x0c, 0x5e, 0xf0, 0xe0, 0xf0, 0x10,
+	0x13, 0x88, 0xf8, 0x42, 0x12, 0x90, 0x76, 0xf8,
+	0x27, 0x6e, 0x00, 0x01, 0xf0, 0x73, 0x12, 0x90,
+	0x56, 0xf8, 0x27, 0x66, 0xf0, 0x00, 0x00, 0x01,
+	0x4e, 0xf8, 0x27, 0x66, 0x6d, 0xe9, 0x00, 0x5e,
+	0x56, 0xf8, 0x27, 0x68, 0xf0, 0x00, 0x00, 0x01,
+	0x4e, 0xf8, 0x27, 0x68, 0x71, 0x04, 0x00, 0x12,
+	0x6e, 0xea, 0xff, 0xff, 0x12, 0x18, 0x70, 0x04,
+	0x00, 0x12, 0xee, 0x06, 0x8a, 0x17, 0x8a, 0x16,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xee, 0xfe,
+	0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d,
+	0xf0, 0x00, 0x25, 0xa0, 0x88, 0x11, 0xf4, 0x95,
+	0xf4, 0x95, 0x76, 0x81, 0x00, 0xff, 0x76, 0x00,
+	0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0xf2, 0x74,
+	0x06, 0x6c, 0xf0, 0x00, 0x00, 0x01, 0x76, 0x00,
+	0x00, 0x00, 0x76, 0x01, 0x00, 0x06, 0x48, 0x11,
+	0xf2, 0x74, 0x06, 0x6c, 0xf0, 0x00, 0x00, 0x07,
+	0xee, 0x02, 0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11,
+	0x88, 0x0e, 0xf4, 0x95, 0xf0, 0x66, 0x00, 0x0d,
+	0xf0, 0x00, 0x24, 0x00, 0x88, 0x11, 0xf4, 0x95,
+	0xf4, 0x95, 0x76, 0xe1, 0x00, 0x01, 0xff, 0xff,
+	0x76, 0x81, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x03, 0x00, 0xff,
+	0x8a, 0x11, 0xfc, 0x00, 0x4a, 0x11, 0xf4, 0x95,
+	0x13, 0x03, 0x88, 0x11, 0xfa, 0x4d, 0x12, 0xec,
+	0x71, 0x02, 0x00, 0x12, 0xf3, 0x10, 0x00, 0x01,
+	0x89, 0x1a, 0xf4, 0x95, 0xf0, 0x72, 0x12, 0xeb,
+	0x70, 0x91, 0x00, 0x12, 0x8a, 0x11, 0xfc, 0x00,
+	0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d,
+	0xf7, 0xb8, 0xee, 0xfe, 0x10, 0xf8, 0x00, 0x08,
+	0x11, 0x06, 0xf1, 0xc0, 0x83, 0x00, 0xf4, 0x85,
+	0x11, 0x06, 0xf7, 0x85, 0x81, 0x06, 0xf6, 0xb8,
+	0xec, 0x0f, 0x1e, 0x06, 0x61, 0x00, 0x80, 0x00,
+	0xf8, 0x20, 0x13, 0x05, 0xf4, 0x84, 0xee, 0x02,
+	0x8a, 0x0d, 0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00,
+	0xf4, 0x95, 0x4a, 0x0b, 0x4a, 0x0c, 0x4a, 0x0d,
+	0xee, 0xfe, 0xf7, 0xb8, 0x80, 0x00, 0x10, 0xf8,
+	0x00, 0x08, 0xf4, 0x85, 0x11, 0x06, 0xf7, 0x85,
+	0x81, 0x06, 0xf6, 0xb8, 0xec, 0x0f, 0x1e, 0x06,
+	0xf0, 0xf0, 0x61, 0x00, 0x80, 0x00, 0xf8, 0x20,
+	0x13, 0x20, 0xf4, 0x84, 0xee, 0x02, 0x8a, 0x0d,
+	0x8a, 0x0c, 0x8a, 0x0b, 0xfc, 0x00, 0x4a, 0x11,
+	0x77, 0x11, 0x00, 0x7b, 0x76, 0x81, 0x2e, 0xec,
+	0x77, 0x11, 0x00, 0x7b, 0xee, 0xff, 0x71, 0x81,
+	0x00, 0x11, 0xee, 0x01, 0x76, 0xe1, 0x00, 0x01,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x04, 0x00, 0x00,
+	0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1,
+	0x00, 0x62, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x76,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x92, 0x00, 0x00,
+	0x76, 0xe1, 0x00, 0x94, 0x00, 0x00, 0x76, 0xe1,
+	0x00, 0xb0, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xb3,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0xbe, 0x00, 0x00,
+	0x76, 0xe1, 0x00, 0xbf, 0x00, 0x00, 0x76, 0xe1,
+	0x00, 0xc1, 0x00, 0x00, 0x76, 0xe1, 0x00, 0xc3,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0xc5, 0x00, 0x00,
+	0x76, 0xe1, 0x00, 0xc7, 0x00, 0x00, 0x76, 0x81,
+	0x00, 0x00, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
+	0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xff,
+	0xf4, 0x95, 0x71, 0x06, 0x00, 0x16, 0xfb, 0x80,
+	0x16, 0xa2, 0x88, 0x17, 0xf4, 0x95, 0xf7, 0xb8,
+	0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02,
+	0xfa, 0x46, 0x13, 0x88, 0x77, 0x11, 0x00, 0x00,
+	0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x02,
+	0xf8, 0x45, 0x13, 0xf9, 0x10, 0xf8, 0x00, 0x17,
+	0xf8, 0x45, 0x14, 0x39, 0x10, 0xf8, 0x00, 0x17,
+	0xf0, 0x10, 0x00, 0x01, 0xf8, 0x45, 0x14, 0x1f,
+	0xf0, 0x73, 0x14, 0x52, 0x10, 0xf8, 0x00, 0x17,
+	0xf0, 0x10, 0x00, 0x03, 0xf8, 0x45, 0x13, 0xd3,
+	0x10, 0xf8, 0x00, 0x17, 0xf0, 0x10, 0x00, 0x06,
+	0xf8, 0x44, 0x14, 0x52, 0x77, 0x12, 0x00, 0x7b,
+	0x71, 0x82, 0x00, 0x14, 0x61, 0xe4, 0x00, 0x07,
+	0x00, 0x40, 0xf8, 0x30, 0x14, 0x52, 0x49, 0x14,
+	0x48, 0x17, 0xf6, 0x00, 0x88, 0x12, 0xf4, 0x95,
+	0x77, 0x13, 0x00, 0x55, 0x77, 0x11, 0x00, 0x57,
+	0x6d, 0xea, 0x00, 0x3b, 0xe5, 0x01, 0x10, 0xe6,
+	0x00, 0x06, 0x80, 0x81, 0x48, 0x14, 0x00, 0xf8,
+	0x00, 0x17, 0x88, 0x12, 0xf4, 0x95, 0x77, 0x11,
+	0x00, 0x55, 0x10, 0xe2, 0x00, 0x40, 0x80, 0x81,
+	0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x07,
+	0x80, 0x81, 0x77, 0x11, 0x00, 0x55, 0x10, 0xe2,
+	0x00, 0x45, 0x80, 0x81, 0x10, 0xe6, 0x00, 0x08,
+	0x77, 0x11, 0x00, 0x57, 0x80, 0x81, 0x77, 0x11,
+	0x00, 0x55, 0x10, 0xe2, 0x00, 0x4a, 0x80, 0x81,
+	0x77, 0x11, 0x00, 0x57, 0x10, 0xe6, 0x00, 0x09,
+	0x80, 0x81, 0xf2, 0x73, 0x14, 0x52, 0x77, 0x11,
+	0x03, 0xc0, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82,
+	0xf0, 0x00, 0x00, 0x07, 0x88, 0x13, 0xf4, 0x95,
+	0xf4, 0x95, 0x96, 0x1b, 0xf8, 0x30, 0x14, 0x52,
+	0x10, 0xe3, 0x00, 0x35, 0x77, 0x12, 0x00, 0x55,
+	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6,
+	0x00, 0x04, 0x80, 0x82, 0x77, 0x12, 0x00, 0x55,
+	0x10, 0xe3, 0x00, 0x37, 0x80, 0x82, 0x77, 0x12,
+	0x00, 0x57, 0x10, 0xe6, 0x00, 0x05, 0x80, 0x82,
+	0x48, 0x11, 0xf0, 0x40, 0x00, 0x10, 0xf2, 0x73,
+	0x14, 0x50, 0xf0, 0x40, 0x00, 0x20, 0x77, 0x12,
+	0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07,
+	0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0d,
+	0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x34,
+	0x77, 0x13, 0x00, 0x55, 0x80, 0x83, 0x77, 0x13,
+	0x00, 0x57, 0x10, 0xe6, 0x00, 0x02, 0x80, 0x83,
+	0x10, 0xe2, 0x00, 0x36, 0x77, 0x12, 0x00, 0x55,
+	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6,
+	0x00, 0x03, 0x80, 0x82, 0x48, 0x11, 0xf0, 0x40,
+	0x00, 0x04, 0xf2, 0x73, 0x14, 0x50, 0xf0, 0x40,
+	0x00, 0x08, 0x77, 0x12, 0x00, 0x7b, 0x10, 0x82,
+	0xf0, 0x00, 0x00, 0x07, 0x88, 0x12, 0xf4, 0x95,
+	0xf4, 0x95, 0x96, 0x0e, 0xf8, 0x30, 0x14, 0x52,
+	0x10, 0xe2, 0x00, 0x33, 0x77, 0x12, 0x00, 0x55,
+	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0x10, 0xe6,
+	0x00, 0x01, 0x80, 0x82, 0x48, 0x11, 0xf2, 0x73,
+	0x14, 0x50, 0xf0, 0x40, 0x00, 0x02, 0x77, 0x12,
+	0x00, 0x7b, 0x10, 0x82, 0xf0, 0x00, 0x00, 0x07,
+	0x88, 0x12, 0xf4, 0x95, 0xf4, 0x95, 0x96, 0x0f,
+	0xf8, 0x30, 0x14, 0x52, 0x10, 0xe2, 0x00, 0x32,
+	0x77, 0x12, 0x00, 0x55, 0x77, 0x13, 0x00, 0x57,
+	0x80, 0x82, 0x48, 0x11, 0xe7, 0x62, 0xf0, 0x40,
+	0x00, 0x01, 0xe5, 0x01, 0x88, 0x11, 0xf4, 0x95,
+	0x77, 0x12, 0x00, 0x7b, 0x48, 0x11, 0x71, 0x82,
+	0x00, 0x12, 0x1a, 0xe2, 0x00, 0x07, 0x80, 0xe2,
+	0x00, 0x07, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01,
+	0x8a, 0x17, 0x48, 0x11, 0x8a, 0x16, 0x8a, 0x11,
+	0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0x77, 0x0e,
+	0x00, 0x05, 0x77, 0x12, 0x00, 0x55, 0xe8, 0x04,
+	0xf6, 0xb8, 0x28, 0xe1, 0x00, 0x02, 0xee, 0xff,
+	0x80, 0x82, 0x77, 0x12, 0x00, 0x57, 0xf0, 0x20,
+	0x80, 0x00, 0xee, 0x01, 0x1a, 0x82, 0x77, 0x12,
+	0x00, 0x57, 0x80, 0x82, 0xe8, 0x01, 0x32, 0xe1,
+	0x00, 0x02, 0xf5, 0x82, 0x77, 0x11, 0x00, 0x54,
+	0xf6, 0x93, 0x18, 0x81, 0x77, 0x11, 0x00, 0x54,
+	0xf2, 0xa0, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95,
+	0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95,
+	0x71, 0x04, 0x00, 0x11, 0xfb, 0x80, 0x16, 0xa2,
+	0x88, 0x16, 0xf4, 0x95, 0x77, 0x12, 0x00, 0x55,
+	0x10, 0xe6, 0x00, 0x03, 0x80, 0x82, 0x77, 0x12,
+	0x00, 0x56, 0x10, 0xe1, 0x00, 0x02, 0x77, 0x13,
+	0x00, 0x56, 0x80, 0x82, 0x77, 0x12, 0x00, 0x56,
+	0x10, 0xe1, 0x00, 0x03, 0x80, 0x82, 0x10, 0xe1,
+	0x00, 0x04, 0x77, 0x12, 0x00, 0x56, 0x80, 0x82,
+	0x77, 0x12, 0x00, 0x56, 0x10, 0xe1, 0x00, 0x01,
+	0x80, 0x82, 0xe7, 0x12, 0xe5, 0x01, 0xf9, 0x80,
+	0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4,
+	0x4a, 0x11, 0x4a, 0x16, 0x4a, 0x17, 0xee, 0xf9,
+	0x77, 0x11, 0x00, 0x7b, 0x76, 0x00, 0x00, 0x16,
+	0x76, 0x01, 0x00, 0x17, 0x76, 0x02, 0x00, 0x1a,
+	0x76, 0x03, 0x00, 0x1b, 0x76, 0x04, 0x00, 0x1c,
+	0x76, 0x05, 0x00, 0x1d, 0x71, 0x81, 0x00, 0x17,
+	0x71, 0xe7, 0x00, 0x06, 0x00, 0x11, 0x10, 0x81,
+	0xf8, 0x44, 0x14, 0xdf, 0xf9, 0x80, 0x16, 0x53,
+	0xf6, 0xb8, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x20,
+	0xff, 0xff, 0xf6, 0xb8, 0xfb, 0x80, 0x16, 0x08,
+	0xf0, 0x20, 0xff, 0xff, 0x77, 0x11, 0x00, 0x7b,
+	0x71, 0x81, 0x00, 0x17, 0x76, 0xe7, 0x00, 0x06,
+	0x00, 0x01, 0x48, 0x17, 0x77, 0x16, 0x00, 0x00,
+	0x77, 0x10, 0x00, 0x04, 0x77, 0x15, 0x00, 0x03,
+	0x77, 0x14, 0x00, 0x02, 0x77, 0x13, 0x00, 0x01,
+	0xf0, 0x00, 0x00, 0x39, 0x76, 0xe7, 0x00, 0x08,
+	0x00, 0x1f, 0x76, 0xe7, 0x00, 0x07, 0x00, 0x00,
+	0x88, 0x0e, 0x77, 0x1a, 0x00, 0x05, 0x48, 0x17,
+	0xf0, 0x00, 0x00, 0x09, 0x88, 0x12, 0x48, 0x18,
+	0x88, 0x19, 0xe8, 0x00, 0xf0, 0x72, 0x15, 0x2c,
+	0x73, 0x19, 0x00, 0x11, 0x76, 0x82, 0x00, 0x00,
+	0x11, 0x91, 0x73, 0x11, 0x00, 0x19, 0x70, 0xe2,
+	0x00, 0x03, 0x00, 0x16, 0x70, 0xe2, 0x00, 0x04,
+	0x00, 0x13, 0x70, 0xe2, 0x00, 0x05, 0x00, 0x14,
+	0x81, 0xe2, 0x00, 0x01, 0x70, 0xe2, 0x00, 0x06,
+	0x00, 0x15, 0x70, 0xe2, 0x00, 0x07, 0x00, 0x10,
+	0x80, 0xe2, 0x00, 0x02, 0x73, 0x0e, 0x00, 0x11,
+	0xf1, 0x00, 0x00, 0x1e, 0x6d, 0xee, 0x00, 0x05,
+	0x6d, 0xeb, 0x00, 0x05, 0x6d, 0xec, 0x00, 0x05,
+	0x6d, 0xed, 0x00, 0x05, 0x6d, 0xe8, 0x00, 0x05,
+	0xf0, 0x00, 0x00, 0x01, 0x81, 0x91, 0x6d, 0xea,
+	0x00, 0x08, 0x73, 0x11, 0x00, 0x0e, 0xee, 0x07,
+	0x76, 0xe7, 0x00, 0x41, 0x00, 0x24, 0x76, 0xe7,
+	0x00, 0x46, 0x00, 0x25, 0x76, 0xe7, 0x00, 0x4b,
+	0x00, 0x26, 0x76, 0xe7, 0x00, 0x50, 0x00, 0x27,
+	0x8a, 0x17, 0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4,
+	0x4a, 0x11, 0x4a, 0x16, 0xee, 0xfe, 0x88, 0x11,
+	0x56, 0x06, 0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2,
+	0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11, 0xf0, 0x10,
+	0xff, 0xff, 0xfa, 0x45, 0x15, 0x60, 0x77, 0x16,
+	0xff, 0xff, 0x77, 0x12, 0x00, 0x7b, 0x49, 0x11,
+	0x10, 0x82, 0xf6, 0x03, 0xf0, 0x00, 0x00, 0x09,
+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81,
+	0xf8, 0x44, 0x15, 0x71, 0xf2, 0x73, 0x15, 0x71,
+	0xf4, 0x95, 0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b,
+	0x10, 0x81, 0xf0, 0x00, 0x00, 0x09, 0x88, 0x11,
+	0xf4, 0x95, 0x77, 0x12, 0x00, 0x06, 0x10, 0x81,
+	0xf8, 0x45, 0x15, 0x5c, 0x6e, 0xea, 0xff, 0xff,
+	0x15, 0x69, 0x6d, 0xe9, 0x00, 0x08, 0x76, 0x86,
+	0x00, 0x01, 0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80,
+	0x10, 0xf8, 0x00, 0x0b, 0xf8, 0x45, 0x15, 0x7e,
+	0xfb, 0x80, 0x15, 0x85, 0xf4, 0x95, 0x48, 0x16,
+	0xf9, 0x80, 0x16, 0x9a, 0xee, 0x02, 0x48, 0x16,
+	0x8a, 0x16, 0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11,
+	0xee, 0xff, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11,
+	0xf4, 0x95, 0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9,
+	0xf8, 0x30, 0x15, 0xc4, 0x10, 0xe1, 0x00, 0x03,
+	0x77, 0x12, 0x00, 0x55, 0x80, 0x82, 0x77, 0x12,
+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x77, 0x12,
+	0x00, 0x56, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1,
+	0x00, 0x02, 0xf0, 0x00, 0x00, 0x08, 0x32, 0xf8,
+	0x00, 0x08, 0x77, 0x12, 0x00, 0x54, 0xe8, 0x01,
+	0xf4, 0x82, 0xf4, 0x93, 0x18, 0x82, 0x77, 0x12,
+	0x00, 0x54, 0xf0, 0x40, 0x00, 0x00, 0x80, 0x82,
+	0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x76,
+	0x10, 0xe1, 0x00, 0x01, 0xf9, 0x80, 0x16, 0x66,
+	0xf0, 0x73, 0x16, 0x03, 0x77, 0x11, 0x00, 0x7b,
+	0x71, 0x81, 0x00, 0x11, 0x71, 0xe1, 0x00, 0x07,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1,
+	0x00, 0x09, 0xf9, 0x80, 0x15, 0x85, 0x77, 0x11,
+	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1,
+	0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00,
+	0x00, 0x08, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81,
+	0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80,
+	0x15, 0x85, 0xf0, 0x00, 0x00, 0x10, 0x77, 0x11,
+	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1,
+	0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00,
+	0x00, 0x18, 0x77, 0x11, 0x00, 0x7b, 0x71, 0x81,
+	0x00, 0x11, 0x10, 0xe1, 0x00, 0x09, 0xfb, 0x80,
+	0x15, 0x85, 0xf0, 0x00, 0x00, 0x20, 0x77, 0x11,
+	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x10, 0xe1,
+	0x00, 0x09, 0xfb, 0x80, 0x15, 0x85, 0xf0, 0x00,
+	0x00, 0x28, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01,
+	0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff,
+	0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95,
+	0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30,
+	0x16, 0x41, 0x77, 0x11, 0x00, 0x55, 0x76, 0x81,
+	0x00, 0x1e, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0x76, 0x81,
+	0x00, 0x00, 0x77, 0x11, 0x00, 0x56, 0xf2, 0x73,
+	0x16, 0x4e, 0x76, 0x81, 0x00, 0x00, 0x77, 0x11,
+	0x00, 0x7b, 0x71, 0x81, 0x00, 0x11, 0x71, 0xe1,
+	0x00, 0x07, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00,
+	0x10, 0xe1, 0x00, 0x39, 0xf9, 0x80, 0x16, 0x08,
+	0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11,
+	0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b,
+	0x10, 0x81, 0xf0, 0x00, 0x00, 0x04, 0x88, 0x11,
+	0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44,
+	0x16, 0x63, 0xf4, 0x95, 0xee, 0xff, 0x76, 0x81,
+	0x00, 0x01, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4,
+	0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8,
+	0x00, 0x08, 0xee, 0xff, 0x77, 0x11, 0x00, 0x01,
+	0xe8, 0x01, 0xee, 0x01, 0xf4, 0x82, 0x1a, 0x81,
+	0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
+	0xf0, 0x10, 0x00, 0x10, 0x4a, 0x11, 0x32, 0xf8,
+	0x00, 0x08, 0xee, 0xff, 0xe8, 0x01, 0x77, 0x11,
+	0x00, 0x00, 0xf4, 0x82, 0xee, 0x01, 0xf4, 0x93,
+	0x18, 0x81, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95,
+	0xf4, 0xe4, 0x4a, 0x11, 0xf0, 0x10, 0x00, 0x10,
+	0x77, 0x11, 0x00, 0x00, 0x32, 0xf8, 0x00, 0x08,
+	0xee, 0xff, 0x11, 0x81, 0xe8, 0x01, 0xee, 0x01,
+	0x77, 0x11, 0x00, 0x00, 0xf4, 0x82, 0xf2, 0xa0,
+	0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
+	0xf2, 0x73, 0x16, 0x9e, 0xf6, 0xbb, 0xf4, 0x95,
+	0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4,
+	0xf2, 0x73, 0x16, 0xa6, 0xf7, 0xbb, 0xf4, 0x95,
+	0xf4, 0x95, 0xf4, 0x95, 0xf4, 0x95, 0xf4, 0xe4,
+	0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95, 0x71, 0x04,
+	0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11,
+	0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x0e, 0x10, 0xe6, 0x00, 0x0e,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82,
+	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x0d, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
+	0x10, 0xe6, 0x00, 0x0d, 0x80, 0x82, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0c,
+	0x10, 0xe6, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x0b, 0x10, 0xe6,
+	0x00, 0x0b, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
+	0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x10, 0xe6, 0x00, 0x0a, 0x80, 0x82,
+	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x09, 0x10, 0xe6, 0x00, 0x09, 0x71, 0xe1,
+	0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x08,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6,
+	0x00, 0x08, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x07, 0x10, 0xe6,
+	0x00, 0x07, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
+	0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x10, 0xe6, 0x00, 0x06, 0x80, 0x82,
+	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x05, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x12,
+	0x10, 0xe6, 0x00, 0x05, 0x80, 0x82, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x04,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x10, 0xe6,
+	0x00, 0x04, 0x80, 0x82, 0x71, 0xe1, 0x00, 0x05,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x03, 0x71, 0xe1,
+	0x00, 0x06, 0x00, 0x12, 0x10, 0xe6, 0x00, 0x03,
+	0x80, 0x82, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x02, 0x10, 0xe6, 0x00, 0x02,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x80, 0x82,
+	0x71, 0xe1, 0x00, 0x05, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x01, 0x10, 0xe6, 0x00, 0x01, 0x71, 0xe1,
+	0x00, 0x06, 0x00, 0x12, 0x80, 0x82, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x00,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x13, 0xe7, 0x62,
+	0xe5, 0x01, 0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16,
+	0x8a, 0x11, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11,
+	0xf4, 0x95, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05,
+	0x00, 0x12, 0xee, 0xff, 0x76, 0x82, 0x00, 0x00,
+	0xee, 0x01, 0x71, 0xe1, 0x00, 0x06, 0x00, 0x11,
+	0x69, 0x81, 0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95,
+	0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xf4, 0x95,
+	0xf4, 0x95, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0xee, 0xff, 0x76, 0x82, 0x00, 0x01, 0xee, 0x01,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x11, 0x69, 0x81,
+	0x00, 0x01, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
+	0x4a, 0x11, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
+	0xf0, 0x00, 0x00, 0x94, 0x88, 0x11, 0xf4, 0x95,
+	0xf4, 0x95, 0x10, 0x81, 0xfa, 0x44, 0x17, 0x9c,
+	0xf4, 0x95, 0xee, 0xff, 0xf9, 0x80, 0x16, 0x53,
+	0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00,
+	0x00, 0x94, 0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95,
+	0x76, 0x81, 0x00, 0x01, 0xee, 0x01, 0x76, 0xe1,
+	0x00, 0x01, 0x00, 0x00, 0x76, 0xe1, 0x00, 0x02,
+	0x00, 0x21, 0x76, 0xe1, 0x00, 0x03, 0x00, 0x20,
+	0x76, 0xe1, 0x00, 0x04, 0x00, 0x23, 0x76, 0xe1,
+	0x00, 0x05, 0x00, 0x22, 0x76, 0xe1, 0x00, 0x06,
+	0x00, 0x38, 0x76, 0xe1, 0x00, 0x07, 0x00, 0x39,
+	0x76, 0xe1, 0x00, 0x08, 0x00, 0x15, 0x76, 0xe1,
+	0x00, 0x09, 0x00, 0x14, 0x76, 0xe1, 0x00, 0x0a,
+	0x00, 0x00, 0x76, 0xe1, 0x00, 0x0b, 0x00, 0x41,
+	0x76, 0xe1, 0x00, 0x0c, 0x00, 0x40, 0x76, 0xe1,
+	0x00, 0x0d, 0x00, 0x43, 0x76, 0xe1, 0x00, 0x0e,
+	0x00, 0x42, 0x76, 0xe1, 0x00, 0x0f, 0x00, 0x48,
+	0x76, 0xe1, 0x00, 0x10, 0x00, 0x49, 0x76, 0xe1,
+	0x00, 0x11, 0x00, 0x1b, 0x76, 0xe1, 0x00, 0x12,
+	0x00, 0x1a, 0x8a, 0x11, 0xf4, 0x95, 0xf4, 0xe4,
+	0x4a, 0x11, 0xee, 0xfd, 0x88, 0x11, 0x56, 0x06,
+	0x4e, 0x00, 0xf9, 0x80, 0x16, 0xa2, 0x77, 0x12,
+	0x00, 0x7b, 0x77, 0x0e, 0x00, 0x09, 0x10, 0x82,
+	0x28, 0xf8, 0x00, 0x11, 0xf0, 0x00, 0x00, 0x95,
+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81,
+	0xf8, 0x45, 0x17, 0xf0, 0xf2, 0x73, 0x17, 0xfd,
+	0x77, 0x11, 0xff, 0xff, 0x76, 0x81, 0x00, 0x01,
+	0xe9, 0x01, 0x56, 0x00, 0xf1, 0x80, 0x10, 0xf8,
+	0x00, 0x0b, 0xf8, 0x45, 0x17, 0xfd, 0xfb, 0x80,
+	0x18, 0x10, 0xf4, 0x95, 0x48, 0x11, 0xf9, 0x80,
+	0x16, 0x9a, 0xee, 0x03, 0x48, 0x11, 0x8a, 0x11,
+	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11,
+	0xf4, 0x95, 0xee, 0xff, 0x71, 0xe1, 0x00, 0x01,
+	0x00, 0x11, 0xee, 0x01, 0x10, 0x81, 0x8a, 0x11,
+	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff,
+	0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95,
+	0x77, 0x10, 0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30,
+	0x18, 0xc3, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x00, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x01,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x02, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x03,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x04, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x05,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x06, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x01, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x07,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
+	0x20, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x08, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x09,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x0a, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0b,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x0c, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x71, 0xe1,
+	0x00, 0x05, 0x00, 0x12, 0x76, 0x82, 0x00, 0x0d,
+	0x71, 0xe1, 0x00, 0x06, 0x00, 0x12, 0x76, 0x82,
+	0x00, 0x00, 0x71, 0xe1, 0x00, 0x05, 0x00, 0x12,
+	0x76, 0x82, 0x00, 0x0e, 0x71, 0xe1, 0x00, 0x06,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x00, 0x10, 0xe1,
+	0x00, 0x07, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1,
+	0x00, 0x08, 0xf9, 0x80, 0x16, 0x76, 0x10, 0xe1,
+	0x00, 0x07, 0xf9, 0x80, 0x16, 0x66, 0x10, 0xe1,
+	0x00, 0x08, 0xf9, 0x80, 0x16, 0x66, 0xf0, 0x73,
+	0x18, 0xd1, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
+	0xfb, 0x80, 0x18, 0x10, 0xf0, 0x00, 0x00, 0x95,
+	0x77, 0x11, 0x00, 0x7b, 0x10, 0x81, 0xfb, 0x80,
+	0x18, 0x10, 0xf0, 0x00, 0x00, 0x9e, 0xf9, 0x80,
+	0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11, 0xf4, 0xe4,
+	0x4a, 0x11, 0x88, 0x11, 0xee, 0xff, 0xf4, 0x95,
+	0x10, 0x04, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x11,
+	0xee, 0x01, 0x80, 0x81, 0x8a, 0x11, 0xf4, 0x95,
+	0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16, 0xf4, 0x95,
+	0x71, 0x04, 0x00, 0x16, 0xfb, 0x80, 0x16, 0xa2,
+	0x88, 0x11, 0xf4, 0x95, 0x71, 0xe1, 0x00, 0x02,
+	0x00, 0x12, 0x76, 0x82, 0x00, 0x10, 0x10, 0xe6,
+	0x00, 0x01, 0x71, 0xe1, 0x00, 0x03, 0x00, 0x12,
+	0x80, 0x82, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12,
+	0x10, 0xe6, 0x00, 0x02, 0x80, 0x82, 0xe7, 0x62,
+	0x71, 0xe1, 0x00, 0x02, 0x00, 0x13, 0xe5, 0x01,
+	0xf9, 0x80, 0x16, 0x9a, 0x8a, 0x16, 0x8a, 0x11,
+	0xf4, 0xe4, 0x4a, 0x11, 0x88, 0x11, 0xee, 0xff,
+	0xee, 0x01, 0x10, 0xe1, 0x00, 0x01, 0x8a, 0x11,
+	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x77, 0x11,
+	0x00, 0x7b, 0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3,
+	0x88, 0x11, 0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81,
+	0xfa, 0x44, 0x19, 0x2a, 0xf4, 0x95, 0xee, 0xff,
+	0xf9, 0x80, 0x16, 0x53, 0x77, 0x11, 0x00, 0x7b,
+	0x10, 0x81, 0xf0, 0x00, 0x00, 0xb3, 0x88, 0x11,
+	0xf4, 0x95, 0xf4, 0x95, 0x76, 0x81, 0x00, 0x01,
+	0xee, 0x01, 0x76, 0xe1, 0x00, 0x01, 0x00, 0x00,
+	0x76, 0xe1, 0x00, 0x02, 0x00, 0x13, 0x76, 0xe1,
+	0x00, 0x03, 0x00, 0x26, 0x76, 0xe1, 0x00, 0x04,
+	0x00, 0x25, 0x76, 0xe1, 0x00, 0x05, 0x00, 0x24,
+	0x76, 0xe1, 0x00, 0x06, 0x00, 0x00, 0x76, 0xe1,
+	0x00, 0x07, 0x00, 0x17, 0x76, 0xe1, 0x00, 0x08,
+	0x00, 0x32, 0x76, 0xe1, 0x00, 0x09, 0x00, 0x31,
+	0x76, 0xe1, 0x00, 0x0a, 0x00, 0x30, 0x8a, 0x11,
+	0xf4, 0x95, 0xf4, 0xe4, 0x4a, 0x11, 0x4a, 0x16,
+	0x4a, 0x17, 0xee, 0xff, 0xf4, 0x95, 0x71, 0x06,
+	0x00, 0x17, 0xfb, 0x80, 0x16, 0xa2, 0x88, 0x11,
+	0xf4, 0x95, 0xf7, 0xb8, 0x10, 0xf8, 0x00, 0x11,
+	0xf0, 0x10, 0xff, 0xff, 0xfa, 0x45, 0x19, 0x73,
+	0x77, 0x16, 0xff, 0xff, 0x77, 0x12, 0x00, 0x7b,
+	0x77, 0x0e, 0x00, 0x05, 0x10, 0x82, 0x28, 0xf8,
+	0x00, 0x11, 0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11,
+	0xf4, 0x95, 0xf4, 0x95, 0x10, 0x81, 0xf8, 0x44,
+	0x19, 0x84, 0xf2, 0x73, 0x19, 0x84, 0xf4, 0x95,
+	0xe7, 0x16, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
+	0xf0, 0x00, 0x00, 0xb4, 0x88, 0x11, 0xf4, 0x95,
+	0x77, 0x12, 0x00, 0x02, 0x10, 0x81, 0xf8, 0x45,
+	0x19, 0x6f, 0x6e, 0xea, 0xff, 0xff, 0x19, 0x7c,
+	0x6d, 0xe9, 0x00, 0x05, 0x61, 0xf8, 0x00, 0x17,
+	0x00, 0x01, 0xfa, 0x20, 0x19, 0x8f, 0x76, 0x86,
+	0x00, 0x01, 0xfb, 0x80, 0x19, 0x97, 0xf4, 0x95,
+	0x48, 0x16, 0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01,
+	0x8a, 0x17, 0x48, 0x16, 0x8a, 0x16, 0x8a, 0x11,
+	0xf4, 0xe4, 0x4a, 0x11, 0xee, 0xff, 0xfb, 0x80,
+	0x16, 0xa2, 0x88, 0x11, 0xf4, 0x95, 0x77, 0x10,
+	0xff, 0xff, 0xf4, 0xa9, 0xf8, 0x30, 0x19, 0xcc,
+	0x71, 0xe1, 0x00, 0x02, 0x00, 0x12, 0x69, 0x82,
+	0x00, 0x10, 0x71, 0xe1, 0x00, 0x02, 0x00, 0x12,
+	0x68, 0x82, 0xf7, 0xff, 0x71, 0xe1, 0x00, 0x02,
+	0x00, 0x12, 0x68, 0x82, 0xfb, 0xff, 0x71, 0xe1,
+	0x00, 0x02, 0x00, 0x12, 0x68, 0x82, 0xff, 0xf0,
+	0x71, 0xe1, 0x00, 0x03, 0x00, 0x12, 0x76, 0x82,
+	0xff, 0xff, 0x71, 0xe1, 0x00, 0x04, 0x00, 0x12,
+	0x76, 0x82, 0xff, 0xff, 0x71, 0xe1, 0x00, 0x02,
+	0x00, 0x12, 0x69, 0x82, 0x00, 0x20, 0x71, 0xe1,
+	0x00, 0x02, 0x00, 0x11, 0xf2, 0x73, 0x19, 0xda,
+	0x68, 0x81, 0xff, 0xef, 0x77, 0x11, 0x00, 0x7b,
+	0x10, 0x81, 0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00,
+	0x00, 0xb4, 0x77, 0x11, 0x00, 0x7b, 0x10, 0x81,
+	0xfb, 0x80, 0x19, 0x97, 0xf0, 0x00, 0x00, 0xb9,
+	0xf9, 0x80, 0x16, 0x9a, 0xee, 0x01, 0x8a, 0x11,
+	0xf4, 0xe4, 0x00, 0xa4, 0x00, 0x00, 0x19, 0xdf,
+	0x00, 0x01, 0x2a, 0xe6, 0x00, 0x00, 0x00, 0x01,
+	0x2a, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x2a, 0x12,
+	0x0c, 0x01, 0xc3, 0x4f, 0x00, 0x00, 0x00, 0x01,
+	0x2a, 0x15, 0x00, 0x00, 0x00, 0x02, 0x2a, 0x16,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x2a, 0x5d,
+	0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79,
+	0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68,
+	0x00, 0x74, 0x00, 0x20, 0x00, 0x54, 0x00, 0x65,
+	0x00, 0x63, 0x00, 0x68, 0x00, 0x6e, 0x00, 0x6f,
+	0x00, 0x54, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e,
+	0x00, 0x64, 0x00, 0x20, 0x00, 0x41, 0x00, 0x47,
+	0x00, 0x00, 0x00, 0x04, 0x2a, 0x76, 0x00, 0x30,
+	0x00, 0x2e, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c,
+	0x2a, 0x7a, 0x00, 0x46, 0x00, 0x65, 0x00, 0x62,
+	0x00, 0x20, 0x00, 0x32, 0x00, 0x37, 0x00, 0x20,
+	0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31,
+	0x00, 0x00, 0x00, 0x09, 0x2a, 0x86, 0x00, 0x31,
+	0x00, 0x34, 0x00, 0x3a, 0x00, 0x33, 0x00, 0x35,
+	0x00, 0x3a, 0x00, 0x33, 0x00, 0x33, 0x00, 0x00,
+	0x00, 0x0f, 0x2a, 0x8f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01, 0x2a, 0x9e, 0x00, 0x00,
+	0x00, 0x01, 0x2a, 0x9f, 0x00, 0x00, 0x00, 0x01,
+	0x2a, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x2a, 0xa1,
+	0x00, 0x00, 0x00, 0x01, 0x2a, 0xa2, 0x00, 0x00,
+	0x00, 0x01, 0x29, 0x7e, 0x00, 0x00, 0x00, 0x02,
+	0x29, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+	0x29, 0x82, 0xff, 0xff, 0x00, 0x01, 0x2a, 0xa7,
+	0x00, 0x00, 0x00, 0x05, 0x2a, 0xa8, 0x71, 0x41,
+	0x20, 0x00, 0x20, 0x00, 0x00, 0x23, 0x04, 0x00,
+	0x00, 0x0a, 0x2a, 0xad, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x0f, 0x2a, 0xb7, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x40, 0x00, 0xa0, 0x82, 0x40,
+	0x00, 0x08, 0x30, 0x7f, 0x00, 0x80, 0x01, 0x80,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x01, 0x27, 0x6e, 0x00, 0x00,
+	0x00, 0x01, 0x27, 0x6f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x09, 0x00, 0x00, 0x1a, 0x83, 0x04, 0xe8,
+	0x04, 0xcf, 0x04, 0xc5, 0x04, 0xba, 0x04, 0xb0,
+	0x04, 0xac, 0x04, 0x9c, 0x04, 0x8c, 0x04, 0x81,
+	0x00, 0x78, 0x00, 0x00, 0x01, 0x00, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xaa, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x02, 0x23, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x05, 0xe5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x02, 0xb5, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x0e, 0x33, 0xf4, 0x95, 0xf4, 0x95, 0xf2, 0x73,
+	0x07, 0xef, 0xf4, 0x95, 0xf4, 0x95, 0x00, 0x00,
 };
 
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 832d179..8abc218 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1203,7 +1203,7 @@
 	input_dev->keycode = rc_keys;
 
 	for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
-                set_bit(rc_keys[i], input_dev->keybit);
+		set_bit(rc_keys[i], input_dev->keybit);
 
 	input_register_device(input_dev);
 
@@ -1529,7 +1529,7 @@
 	usb_free_urb(dec->irq_urb);
 
 	usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
-		           dec->irq_buffer, dec->irq_dma_handle);
+			   dec->irq_buffer, dec->irq_dma_handle);
 
 	if (dec->rc_input_dev) {
 		input_unregister_device(dec->rc_input_dev);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 1a3b3c7..fc87efc 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -26,15 +26,12 @@
 	  module will be called bttv.
 
 config VIDEO_BT848_DVB
-	tristate "DVB/ATSC Support for bt878 based TV cards"
+	bool "DVB/ATSC Support for bt878 based TV cards"
 	depends on VIDEO_BT848 && DVB_CORE
 	select DVB_BT8XX
 	---help---
 	  This adds support for DVB/ATSC cards based on the BT878 chip.
 
-	  To compile this driver as a module, choose M here: the
-	  module will be called dvb-bt8xx.
-
 config VIDEO_SAA6588
 	tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
 	depends on VIDEO_DEV && I2C && VIDEO_BT848
@@ -191,7 +188,7 @@
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called zr36067.
- 
+
 config VIDEO_ZORAN_BUZ
 	tristate "Iomega Buz support"
 	depends on VIDEO_ZORAN
@@ -207,8 +204,8 @@
 
 config VIDEO_ZORAN_DC30
 	tristate "Pinnacle/Miro DC30(+) support"
- 	depends on VIDEO_ZORAN
- 	help
+	depends on VIDEO_ZORAN
+	help
 	  Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback
 	  card. This also supports really old DC10 cards based on the
 	  zr36050 MJPEG codec and zr36016 VFE.
@@ -263,7 +260,7 @@
 	---help---
 	  This is a video4linux driver for the 'Multimedia eXtension Board'
 	  TV card by Siemens-Nixdorf.
-	  
+
 	  To compile this driver as a module, choose M here: the
 	  module will be called mxb.
 
@@ -277,7 +274,7 @@
 	  for SAA7146 bases boards, so if you have some unsupported
 	  saa7146 based, analog video card, chances are good that it
 	  will work with this skeleton driver.
-	  
+
 	  To compile this driver as a module, choose M here: the
 	  module will be called dpc7146.
 
@@ -288,7 +285,7 @@
 	---help---
 	  This is a video4linux driver for the Hexium HV-PCI6 and
 	  Orion frame grabber cards by Hexium.
-	  
+
 	  To compile this driver as a module, choose M here: the
 	  module will be called hexium_orion.
 
@@ -300,7 +297,7 @@
 	  This is a video4linux driver for the Hexium Gemini frame
 	  grabber card by Hexium. Please note that the Gemini Dual
 	  card is *not* fully supported.
-	  
+
 	  To compile this driver as a module, choose M here: the
 	  module will be called hexium_gemini.
 
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
index 1ca2b67..e61003d 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -420,7 +420,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_adv7170;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	if ((client->addr == I2C_ADV7170 >> 1) ||
 	    (client->addr == (I2C_ADV7170 >> 1) + 1)) {
 		dname = adv7170_name;
@@ -498,11 +497,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_adv7170 = {
-	.owner = THIS_MODULE,
-	.name = "adv7170",	/* name */
+	.driver = {
+		.name = "adv7170",	/* name */
+	},
 
 	.id = I2C_DRIVERID_ADV7170,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = adv7170_attach_adapter,
 	.detach_client = adv7170_detach_client,
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
index 173bca1..6d9536a 100644
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/video/adv7175.c
@@ -470,7 +470,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_adv7175;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	if ((client->addr == I2C_ADV7175 >> 1) ||
 	    (client->addr == (I2C_ADV7175 >> 1) + 1)) {
 		dname = adv7175_name;
@@ -548,11 +547,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_adv7175 = {
-	.owner = THIS_MODULE,
-	.name = "adv7175",	/* name */
+	.driver = {
+		.name = "adv7175",	/* name */
+	},
 
 	.id = I2C_DRIVERID_ADV7175,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = adv7175_attach_adapter,
 	.detach_client = adv7175_detach_client,
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index 3ee0afc..560b998 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -535,7 +535,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_bt819;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 
 	decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL);
 	if (decoder == NULL) {
@@ -623,11 +622,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_bt819 = {
-	.owner = THIS_MODULE,
-	.name = "bt819",
+	.driver = {
+		.name = "bt819",
+	},
 
 	.id = I2C_DRIVERID_BT819,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = bt819_attach_adapter,
 	.detach_client = bt819_detach_client,
diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c
index e406395..1c3ff5f 100644
--- a/drivers/media/video/bt832.c
+++ b/drivers/media/video/bt832.c
@@ -230,19 +230,18 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-	.owner          = THIS_MODULE,
-        .name           = "i2c bt832 driver",
-        .id             = -1, /* FIXME */
-        .flags          = I2C_DF_NOTIFY,
-        .attach_adapter = bt832_probe,
-        .detach_client  = bt832_detach,
-        .command        = bt832_command,
+	.driver = {
+		.name   = "i2c bt832 driver",
+	},
+	.id             = -1, /* FIXME */
+	.attach_adapter = bt832_probe,
+	.detach_client  = bt832_detach,
+	.command        = bt832_command,
 };
 static struct i2c_client client_template =
 {
 	.name       = "bt832",
-	.flags      = I2C_CLIENT_ALLOW_USE,
-        .driver     = &driver,
+	.driver     = &driver,
 };
 
 
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
index 8eb871d..6050806 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -323,7 +323,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_bt856;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
 
 	encoder = kmalloc(sizeof(struct bt856), GFP_KERNEL);
@@ -405,11 +404,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_bt856 = {
-	.owner = THIS_MODULE,
-	.name = "bt856",
+	.driver = {
+		.name = "bt856",
+	},
 
 	.id = I2C_DRIVERID_BT856,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = bt856_attach_adapter,
 	.detach_client = bt856_detach_client,
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c
index e31ebb1..012be63 100644
--- a/drivers/media/video/bttv-cards.c
+++ b/drivers/media/video/bttv-cards.c
@@ -2904,7 +2904,7 @@
  */
 
 /* Some Modular Technology cards have an eeprom, but no subsystem ID */
-void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
+static void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
 {
 	int type = -1;
 
@@ -3879,7 +3879,7 @@
  *                error. ERROR_CPLD_Check_Failed.
  */
 /* ----------------------------------------------------------------------- */
-void
+static void
 init_RTV24 (struct bttv *btv)
 {
 	uint32_t dataRead = 0;
@@ -4103,7 +4103,7 @@
 /* ----------------------------------------------------------------------- */
 /* winview                                                                 */
 
-void winview_audio(struct bttv *btv, struct video_audio *v, int set)
+static void winview_audio(struct bttv *btv, struct video_audio *v, int set)
 {
 	/* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
 	int bits_out, loops, vol, data;
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c
index 709099f..1ddf9ba 100644
--- a/drivers/media/video/bttv-driver.c
+++ b/drivers/media/video/bttv-driver.c
@@ -727,71 +727,71 @@
 
 static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout)
 {
-        unsigned char fl, fh, fi;
+	unsigned char fl, fh, fi;
 
-        /* prevent overflows */
-        fin/=4;
-        fout/=4;
+	/* prevent overflows */
+	fin/=4;
+	fout/=4;
 
-        fout*=12;
-        fi=fout/fin;
+	fout*=12;
+	fi=fout/fin;
 
-        fout=(fout%fin)*256;
-        fh=fout/fin;
+	fout=(fout%fin)*256;
+	fh=fout/fin;
 
-        fout=(fout%fin)*256;
-        fl=fout/fin;
+	fout=(fout%fin)*256;
+	fl=fout/fin;
 
-        btwrite(fl, BT848_PLL_F_LO);
-        btwrite(fh, BT848_PLL_F_HI);
-        btwrite(fi|BT848_PLL_X, BT848_PLL_XCI);
+	btwrite(fl, BT848_PLL_F_LO);
+	btwrite(fh, BT848_PLL_F_HI);
+	btwrite(fi|BT848_PLL_X, BT848_PLL_XCI);
 }
 
 static void set_pll(struct bttv *btv)
 {
-        int i;
+	int i;
 
-        if (!btv->pll.pll_crystal)
-                return;
+	if (!btv->pll.pll_crystal)
+		return;
 
 	if (btv->pll.pll_ofreq == btv->pll.pll_current) {
 		dprintk("bttv%d: PLL: no change required\n",btv->c.nr);
-                return;
-        }
+		return;
+	}
 
-        if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
-                /* no PLL needed */
-                if (btv->pll.pll_current == 0)
-                        return;
+	if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
+		/* no PLL needed */
+		if (btv->pll.pll_current == 0)
+			return;
 		bttv_printk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",
-                           btv->c.nr,btv->pll.pll_ifreq);
-                btwrite(0x00,BT848_TGCTRL);
-                btwrite(0x00,BT848_PLL_XCI);
-                btv->pll.pll_current = 0;
-                return;
-        }
+			btv->c.nr,btv->pll.pll_ifreq);
+		btwrite(0x00,BT848_TGCTRL);
+		btwrite(0x00,BT848_PLL_XCI);
+		btv->pll.pll_current = 0;
+		return;
+	}
 
 	bttv_printk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr,
-                   btv->pll.pll_ifreq, btv->pll.pll_ofreq);
+		btv->pll.pll_ifreq, btv->pll.pll_ofreq);
 	set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
 
-        for (i=0; i<10; i++) {
+	for (i=0; i<10; i++) {
 		/*  Let other people run while the PLL stabilizes */
 		bttv_printk(".");
 		msleep(10);
 
-                if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
+		if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
 			btwrite(0,BT848_DSTATUS);
-                } else {
-                        btwrite(0x08,BT848_TGCTRL);
-                        btv->pll.pll_current = btv->pll.pll_ofreq;
+		} else {
+			btwrite(0x08,BT848_TGCTRL);
+			btv->pll.pll_current = btv->pll.pll_ofreq;
 			bttv_printk(" ok\n");
-                        return;
-                }
-        }
-        btv->pll.pll_current = -1;
+			return;
+		}
+	}
+	btv->pll.pll_current = -1;
 	bttv_printk("failed\n");
-        return;
+	return;
 }
 
 /* used to switch between the bt848's analog/digital video capture modes */
@@ -1720,7 +1720,7 @@
 		memset(i,0,sizeof(*i));
 		i->index    = n;
 		i->type     = V4L2_INPUT_TYPE_CAMERA;
-		i->audioset = 1;
+		i->audioset = 0;
 		if (i->index == bttv_tvcards[btv->c.type].tuner) {
 			sprintf(i->name, "Television");
 			i->type  = V4L2_INPUT_TYPE_TUNER;
@@ -1771,12 +1771,20 @@
 		memset(t,0,sizeof(*t));
 		strcpy(t->name, "Television");
 		t->type       = V4L2_TUNER_ANALOG_TV;
-		t->rangehigh  = 0xffffffffUL;
 		t->capability = V4L2_TUNER_CAP_NORM;
 		t->rxsubchans = V4L2_TUNER_SUB_MONO;
 		if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)
 			t->signal = 0xffff;
 		{
+			struct video_tuner tuner;
+
+			memset(&tuner, 0, sizeof (tuner));
+			tuner.rangehigh = 0xffffffffUL;
+			bttv_call_i2c_clients(btv, VIDIOCGTUNER, &tuner);
+			t->rangelow = tuner.rangelow;
+			t->rangehigh = tuner.rangehigh;
+		}
+		{
 			/* Hmmm ... */
 			struct video_audio va;
 			memset(&va, 0, sizeof(struct video_audio));
@@ -1853,7 +1861,7 @@
 	}
 	case VIDIOC_LOG_STATUS:
 	{
-		bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, 0);
+		bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL);
 		return 0;
 	}
 
@@ -1956,7 +1964,7 @@
 	}
 
 	down(&fh->cap.lock);
-	kfree(fh->ov.clips);
+		kfree(fh->ov.clips);
 	fh->ov.clips    = clips;
 	fh->ov.nclips   = n;
 
@@ -2029,19 +2037,33 @@
 	return 0;
 }
 
+static void
+pix_format_set_size     (struct v4l2_pix_format *       f,
+			 const struct bttv_format *     fmt,
+			 unsigned int                   width,
+			 unsigned int                   height)
+{
+	f->width = width;
+	f->height = height;
+
+	if (fmt->flags & FORMAT_FLAGS_PLANAR) {
+		f->bytesperline = width; /* Y plane */
+		f->sizeimage = (width * height * fmt->depth) >> 3;
+	} else {
+		f->bytesperline = (width * fmt->depth) >> 3;
+		f->sizeimage = height * f->bytesperline;
+	}
+}
+
 static int bttv_g_fmt(struct bttv_fh *fh, struct v4l2_format *f)
 {
 	switch (f->type) {
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 		memset(&f->fmt.pix,0,sizeof(struct v4l2_pix_format));
-		f->fmt.pix.width        = fh->width;
-		f->fmt.pix.height       = fh->height;
+		pix_format_set_size (&f->fmt.pix, fh->fmt,
+				     fh->width, fh->height);
 		f->fmt.pix.field        = fh->cap.field;
 		f->fmt.pix.pixelformat  = fh->fmt->fourcc;
-		f->fmt.pix.bytesperline =
-			(f->fmt.pix.width * fh->fmt->depth) >> 3;
-		f->fmt.pix.sizeimage =
-			f->fmt.pix.height * f->fmt.pix.bytesperline;
 		return 0;
 	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
 		memset(&f->fmt.win,0,sizeof(struct v4l2_window));
@@ -2106,11 +2128,9 @@
 			f->fmt.pix.width = maxw;
 		if (f->fmt.pix.height > maxh)
 			f->fmt.pix.height = maxh;
-		f->fmt.pix.width &= ~0x03;
-		f->fmt.pix.bytesperline =
-			(f->fmt.pix.width * fmt->depth) >> 3;
-		f->fmt.pix.sizeimage =
-			f->fmt.pix.height * f->fmt.pix.bytesperline;
+		pix_format_set_size (&f->fmt.pix, fmt,
+				     f->fmt.pix.width & ~3,
+				     f->fmt.pix.height);
 
 		return 0;
 	}
@@ -2278,6 +2298,15 @@
 			retval = -EINVAL;
 			goto fh_unlock_and_return;
 		}
+		if (fmt->flags & FORMAT_FLAGS_RAW) {
+			/* VIDIOCMCAPTURE uses gbufsize, not RAW_BPL *
+			   RAW_LINES * 2. F1 is stored at offset 0, F2
+			   at buffer size / 2. */
+			fh->width = RAW_BPL;
+			fh->height = gbufsize / RAW_BPL;
+			btv->init.width  = RAW_BPL;
+			btv->init.height = gbufsize / RAW_BPL;
+		}
 		fh->ovfmt   = fmt;
 		fh->fmt     = fmt;
 		btv->init.ovfmt   = fmt;
@@ -2589,9 +2618,11 @@
 
 		if (0 == v4l2)
 			return -EINVAL;
-		strcpy(cap->driver,"bttv");
-		strlcpy(cap->card,btv->video_dev->name,sizeof(cap->card));
-		sprintf(cap->bus_info,"PCI:%s",pci_name(btv->c.pci));
+		memset(cap, 0, sizeof (*cap));
+		strlcpy(cap->driver, "bttv", sizeof (cap->driver));
+		strlcpy(cap->card, btv->video_dev->name, sizeof (cap->card));
+		snprintf(cap->bus_info, sizeof (cap->bus_info),
+			 "PCI:%s", pci_name(btv->c.pci));
 		cap->version = BTTV_VERSION_CODE;
 		cap->capabilities =
 			V4L2_CAP_VIDEO_CAPTURE |
@@ -2727,7 +2758,7 @@
 			fh->ov.w.height = fb->fmt.height;
 			btv->init.ov.w.width  = fb->fmt.width;
 			btv->init.ov.w.height = fb->fmt.height;
-			kfree(fh->ov.clips);
+				kfree(fh->ov.clips);
 			fh->ov.clips = NULL;
 			fh->ov.nclips = 0;
 
@@ -2952,6 +2983,8 @@
 			fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
 			field = videobuf_next_field(&fh->cap);
 			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
+				kfree (fh->cap.read_buf);
+				fh->cap.read_buf = NULL;
 				up(&fh->cap.lock);
 				return POLLERR;
 			}
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c
index 77619eb..d6418c0 100644
--- a/drivers/media/video/bttv-i2c.c
+++ b/drivers/media/video/bttv-i2c.c
@@ -300,7 +300,7 @@
 
 	if (bttv_debug)
 		printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
-			btv->c.nr,client->driver->name,client->addr,
+			btv->c.nr, client->driver->driver.name, client->addr,
 			client->name);
 	if (!client->driver->command)
 		return 0;
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 3aa9c6e..1e6a563 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -45,6 +45,7 @@
 #include <media/tveeprom.h>
 #include <media/ir-common.h>
 
+
 #include "bt848.h"
 #include "bttv.h"
 #include "btcx-risc.h"
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index ddf184f..6861d40 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -170,16 +170,9 @@
 		/* Does the error line indicate end of data? */
 		if (((i /*& 1*/) == 0) &&
 		    (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
-			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
-				DBG("%s: No more nibble data (%d bytes)\n",
-				port->name, i/2);
-
-			/* Go to reverse idle phase. */
-			parport_frob_control (port,
-					      PARPORT_CONTROL_AUTOFD,
-					      PARPORT_CONTROL_AUTOFD);
-			port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
-			break;
+			DBG("%s: No more nibble data (%d bytes)\n",
+			    port->name, i/2);
+			goto end_of_data;
 		}
 
 		/* Event 7: Set nAutoFd low. */
@@ -227,18 +220,21 @@
 			byte = nibble;
 	}
 
-	i /= 2; /* i is now in bytes */
-
 	if (i == len) {
 		/* Read the last nibble without checking data avail. */
-		port = port->physport;
-		if (parport_read_status (port) & PARPORT_STATUS_ERROR)
-			port->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
+		if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
+		end_of_data:
+			/* Go to reverse idle phase. */
+			parport_frob_control (port,
+					      PARPORT_CONTROL_AUTOFD,
+					      PARPORT_CONTROL_AUTOFD);
+			port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
+		}
 		else
-			port->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
+			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
 	}
 
-	return i;
+	return i/2;
 }
 
 /* CPiA nonstandard "Nibble Stream" mode (2 nibbles per cycle, instead of 1)
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
index 9774e94..1439cb7 100644
--- a/drivers/media/video/cpia_usb.c
+++ b/drivers/media/video/cpia_usb.c
@@ -582,7 +582,6 @@
 
 
 static struct usb_driver cpia_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "cpia",
 	.probe		= cpia_probe,
 	.disconnect	= cpia_disconnect,
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 780b352..643ead1 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -42,15 +42,16 @@
 #define cs53l32a_dbg(fmt, arg...) \
 	do { \
 		if (debug) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
+			       client->driver->driver.name, \
 			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
 	} while (0)
 
 #define cs53l32a_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
 		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 #define cs53l32a_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
 		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 
 static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
@@ -154,7 +155,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	snprintf(client->name, sizeof(client->name) - 1, "cs53l32a");
 
 	cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
@@ -216,13 +216,13 @@
 
 /* i2c implementation */
 static struct i2c_driver i2c_driver = {
-	.name = "cs53l32a",
+	.driver = {
+		.name = "cs53l32a",
+	},
 	.id = I2C_DRIVERID_CS53L32A,
-	.flags = I2C_DF_NOTIFY,
 	.attach_adapter = cs53l32a_probe,
 	.detach_client = cs53l32a_detach,
 	.command = cs53l32a_command,
-	.owner = THIS_MODULE,
 };
 
 
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index f6afeec..3b09f46 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -208,8 +208,11 @@
 
 static void input_change(struct i2c_client *client)
 {
+	struct cx25840_state *state = i2c_get_clientdata(client);
 	v4l2_std_id std = cx25840_get_v4lstd(client);
 
+	/* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC
+	   instead of V4L2_STD_PAL. Someone needs to test this. */
 	if (std & V4L2_STD_PAL) {
 		/* Follow tuner change procedure for PAL */
 		cx25840_write(client, 0x808, 0xff);
@@ -220,7 +223,32 @@
 		cx25840_write(client, 0x80b, 0x10);
 	} else if (std & V4L2_STD_NTSC) {
 		/* NTSC */
-		cx25840_write(client, 0x808, 0xf6);
+		if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) {
+			/* Certain Hauppauge PVR150 models have a hardware bug
+			   that causes audio to drop out. For these models the
+			   audio standard must be set explicitly.
+			   To be precise: it affects cards with tuner models
+			   85, 99 and 112 (model numbers from tveeprom). */
+			if (std == V4L2_STD_NTSC_M_JP) {
+				/* Japan uses EIAJ audio standard */
+				cx25840_write(client, 0x808, 0x2f);
+			} else {
+				/* Others use the BTSC audio standard */
+				cx25840_write(client, 0x808, 0x1f);
+			}
+			/* South Korea uses the A2-M (aka Zweiton M) audio
+			   standard, and should set 0x808 to 0x3f, but I don't
+			   know how to detect this. */
+		} else if (std == V4L2_STD_NTSC_M_JP) {
+			/* Japan uses EIAJ audio standard */
+			cx25840_write(client, 0x808, 0xf7);
+		} else {
+			/* Others use the BTSC audio standard */
+			cx25840_write(client, 0x808, 0xf6);
+		}
+		/* South Korea uses the A2-M (aka Zweiton M) audio standard,
+		   and should set 0x808 to 0xf8, but I don't know how to
+		   detect this. */
 		cx25840_write(client, 0x80b, 0x00);
 	}
 
@@ -241,7 +269,8 @@
 	case CX25840_TUNER:
 		cx25840_dbg("now setting Tuner input\n");
 
-		if (state->cardtype == CARDTYPE_PVR150) {
+		if (state->cardtype == CARDTYPE_PVR150 ||
+		    state->cardtype == CARDTYPE_PVR150_WORKAROUND) {
 			/* CH_SEL_ADC2=1 */
 			cx25840_and_or(client, 0x102, ~0x2, 0x02);
 		}
@@ -304,24 +333,30 @@
 
 static int set_v4lstd(struct i2c_client *client, v4l2_std_id std)
 {
-	u8 fmt;
+	u8 fmt=0; 	/* zero is autodetect */
 
-	switch (std) {
-	/* zero is autodetect */
-	case 0: fmt = 0x0; break;
-	/* default ntsc to ntsc-m */
-	case V4L2_STD_NTSC:
-	case V4L2_STD_NTSC_M: fmt = 0x1; break;
-	case V4L2_STD_NTSC_M_JP: fmt = 0x2; break;
-	case V4L2_STD_NTSC_443: fmt = 0x3; break;
-	case V4L2_STD_PAL: fmt = 0x4; break;
-	case V4L2_STD_PAL_M: fmt = 0x5; break;
-	case V4L2_STD_PAL_N: fmt = 0x6; break;
-	case V4L2_STD_PAL_Nc: fmt = 0x7; break;
-	case V4L2_STD_PAL_60: fmt = 0x8; break;
-	case V4L2_STD_SECAM: fmt = 0xc; break;
-	default:
-		return -ERANGE;
+	/* First tests should be against specific std */
+	if (std & V4L2_STD_NTSC_M_JP) {
+		fmt=0x2;
+	} else if (std & V4L2_STD_NTSC_443) {
+		fmt=0x3;
+	} else if (std & V4L2_STD_PAL_M) {
+		fmt=0x5;
+	} else if (std & V4L2_STD_PAL_N) {
+		fmt=0x6;
+	} else if (std & V4L2_STD_PAL_Nc) {
+		fmt=0x7;
+	} else if (std & V4L2_STD_PAL_60) {
+		fmt=0x8;
+	} else {
+		/* Then, test against generic ones */
+		if (std & V4L2_STD_NTSC) {
+			fmt=0x1;
+		} else if (std & V4L2_STD_PAL) {
+			fmt=0x4;
+		} else if (std & V4L2_STD_SECAM) {
+			fmt=0xc;
+		}
 	}
 
 	cx25840_and_or(client, 0x400, ~0xf, fmt);
@@ -363,6 +398,7 @@
 	case CX25840_CID_CARDTYPE:
 		switch (ctrl->value) {
 		case CARDTYPE_PVR150:
+		case CARDTYPE_PVR150_WORKAROUND:
 		case CARDTYPE_PG600:
 			state->cardtype = ctrl->value;
 			break;
@@ -714,7 +750,7 @@
 
 /* ----------------------------------------------------------------------- */
 
-struct i2c_driver i2c_driver_cx25840;
+static struct i2c_driver i2c_driver_cx25840;
 
 static int cx25840_detect_client(struct i2c_adapter *adapter, int address,
 				 int kind)
@@ -737,7 +773,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_cx25840;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	snprintf(client->name, sizeof(client->name) - 1, "cx25840");
 
 	cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1);
@@ -807,16 +842,16 @@
 
 /* ----------------------------------------------------------------------- */
 
-struct i2c_driver i2c_driver_cx25840 = {
-	.name = "cx25840",
+static struct i2c_driver i2c_driver_cx25840 = {
+	.driver = {
+		.name = "cx25840",
+	},
 
 	.id = I2C_DRIVERID_CX25840,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = cx25840_attach_adapter,
 	.detach_client = cx25840_detach_client,
 	.command = cx25840_command,
-	.owner = THIS_MODULE,
 };
 
 
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h
index 5c3f063..40aa59f 100644
--- a/drivers/media/video/cx25840/cx25840.h
+++ b/drivers/media/video/cx25840/cx25840.h
@@ -27,22 +27,30 @@
 extern int cx25840_debug;
 
 #define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \
-	printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_INFO "%s debug %d-%04x: " fmt, \
+	       client->driver->driver.name, \
 	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 
 #define cx25840_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
 	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 
 #define cx25840_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
 	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 
 #define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0)
 
+/* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a
+   hardware bug that is present in PVR150 (and possible PVR500) cards that
+   have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The
+   audio autodetect fails on some channels for these models and the workaround
+   is to select the audio standard explicitly. Many thanks to Hauppauge for
+   providing this information. */
 enum cx25840_cardtype {
 	CARDTYPE_PVR150,
-	CARDTYPE_PG600
+	CARDTYPE_PG600,
+	CARDTYPE_PVR150_WORKAROUND,
 };
 
 enum cx25840_input {
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 41818b6..85ba410 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -46,8 +46,8 @@
 	  If you are unsure, choose Y.
 
 config VIDEO_CX88_DVB_MT352
-	tristate "Zarlink MT352 DVB-T Support"
-	default m
+	bool "Zarlink MT352 DVB-T Support"
+	default y
 	depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
 	select DVB_MT352
 	---help---
@@ -55,8 +55,8 @@
 	  Connexant 2388x chip and the MT352 demodulator.
 
 config VIDEO_CX88_DVB_OR51132
-	tristate "OR51132 ATSC Support"
-	default m
+	bool "OR51132 ATSC Support"
+	default y
 	depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
 	select DVB_OR51132
 	---help---
@@ -64,8 +64,8 @@
 	  Connexant 2388x chip and the OR51132 demodulator.
 
 config VIDEO_CX88_DVB_CX22702
-	tristate "Conexant CX22702 DVB-T Support"
-	default m
+	bool "Conexant CX22702 DVB-T Support"
+	default y
 	depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
 	select DVB_CX22702
 	---help---
@@ -73,8 +73,8 @@
 	  Connexant 2388x chip and the CX22702 demodulator.
 
 config VIDEO_CX88_DVB_LGDT330X
-	tristate "LG Electronics DT3302/DT3303 ATSC Support"
-	default m
+	bool "LG Electronics DT3302/DT3303 ATSC Support"
+	default y
 	depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
 	select DVB_LGDT330X
 	---help---
@@ -82,8 +82,8 @@
 	  Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator.
 
 config VIDEO_CX88_DVB_NXT200X
-	tristate "NXT2002/NXT2004 ATSC Support"
-	default m
+	bool "NXT2002/NXT2004 ATSC Support"
+	default y
 	depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
 	select DVB_NXT200X
 	---help---
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile
index 0df40b7..54401b0 100644
--- a/drivers/media/video/cx88/Makefile
+++ b/drivers/media/video/cx88/Makefile
@@ -9,21 +9,12 @@
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
-ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
- EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
-endif
-ifneq ($(CONFIG_DVB_CX22702),n)
- EXTRA_CFLAGS += -DHAVE_CX22702=1
-endif
-ifneq ($(CONFIG_DVB_OR51132),n)
- EXTRA_CFLAGS += -DHAVE_OR51132=1
-endif
-ifneq ($(CONFIG_DVB_LGDT330X),n)
- EXTRA_CFLAGS += -DHAVE_LGDT330X=1
-endif
-ifneq ($(CONFIG_DVB_MT352),n)
- EXTRA_CFLAGS += -DHAVE_MT352=1
-endif
-ifneq ($(CONFIG_DVB_NXT200X),n)
- EXTRA_CFLAGS += -DHAVE_NXT200X=1
-endif
+
+extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1
+extra-cflags-$(CONFIG_DVB_CX22702)   += -DHAVE_CX22702=1
+extra-cflags-$(CONFIG_DVB_OR51132)   += -DHAVE_OR51132=1
+extra-cflags-$(CONFIG_DVB_LGDT330X)  += -DHAVE_LGDT330X=1
+extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
+extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 4ae3f78..74e57a5 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -616,6 +616,8 @@
 
 	retval = request_firmware(&firmware, BLACKBIRD_FIRM_ENC_FILENAME,
 				  &dev->pci->dev);
+
+
 	if (retval != 0) {
 		dprintk(0, "ERROR: Hotplug firmware request failed (%s).\n",
 			BLACKBIRD_FIRM_ENC_FILENAME);
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index f226863..951709a 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -567,6 +567,7 @@
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -711,6 +712,7 @@
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		.tda9887_conf   = TDA9887_PRESENT,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
@@ -1083,41 +1085,28 @@
 	tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data);
 	core->tuner_type = tv.tuner_type;
 	core->has_radio  = tv.has_radio;
-}
-
-static int hauppauge_eeprom_dvb(struct cx88_core *core, u8 *ee)
-{
-	int model;
-	int tuner;
 
 	/* Make sure we support the board model */
-	model = ee[0x1f] << 24 | ee[0x1e] << 16 | ee[0x1d] << 8 | ee[0x1c];
-	switch(model) {
-	case 90002:
-	case 90500:
-	case 90501:
+	switch (tv.model)
+	{
+	case 90002: /* Nova-T-PCI (9002) */
+	case 92001: /* Nova-S-Plus (Video and IR) */
+	case 92002: /* Nova-S-Plus (Video and IR) */
+	case 90003: /* Nova-T-PCI (9002 No RF out) */
+	case 90500: /* Nova-T-PCI (oem) */
+	case 90501: /* Nova-T-PCI (oem/IR) */
+	case 92000: /* Nova-SE2 (OEM, No Video or IR) */
+
 		/* known */
 		break;
 	default:
 		printk("%s: warning: unknown hauppauge model #%d\n",
-		       core->name, model);
+		       core->name, tv.model);
 		break;
 	}
 
-	/* Make sure we support the tuner */
-	tuner = ee[0x2d];
-	switch(tuner) {
-	case 0x4B: /* dtt 7595 */
-	case 0x4C: /* dtt 7592 */
-		break;
-	default:
-		printk("%s: error: unknown hauppauge tuner 0x%02x\n",
-		       core->name, tuner);
-		return -ENODEV;
-	}
-	printk(KERN_INFO "%s: hauppauge eeprom: model=%d, tuner=%d\n",
-	       core->name, model, tuner);
-	return 0;
+	printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n",
+			core->name, tv.model);
 }
 
 /* ----------------------------------------------------------------------- */
@@ -1201,7 +1190,7 @@
 
 void cx88_card_setup(struct cx88_core *core)
 {
-	static u8 eeprom[128];
+	static u8 eeprom[256];
 
 	if (0 == core->i2c_rc) {
 		core->i2c_client.addr = 0xa0 >> 1;
@@ -1224,7 +1213,7 @@
 		break;
 	case CX88_BOARD_HAUPPAUGE_DVB_T1:
 		if (0 == core->i2c_rc)
-			hauppauge_eeprom_dvb(core,eeprom);
+			hauppauge_eeprom(core,eeprom);
 		break;
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
 	case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index eb806af..bb6eb54 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -837,6 +837,29 @@
 	return -1;
 }
 
+int cx88_start_audio_dma(struct cx88_core *core)
+{
+	/* setup fifo + format */
+	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0);
+	cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0);
+
+	cx_write(MO_AUDD_LNGTH,    128); /* fifo bpl size */
+	cx_write(MO_AUDR_LNGTH,    128); /* fifo bpl size */
+
+	/* start dma */
+	cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */
+
+	return 0;
+}
+
+int cx88_stop_audio_dma(struct cx88_core *core)
+{
+	/* stop dma */
+	cx_write(MO_AUD_DMACNTRL, 0x0000);
+
+	return 0;
+}
+
 static int set_tvaudio(struct cx88_core *core)
 {
 	struct cx88_tvnorm *norm = core->tvnorm;
@@ -877,12 +900,16 @@
 	cx88_set_tvaudio(core);
 	/* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
 
-	cx_write(MO_AUDD_LNGTH,    128); /* fifo size */
-	cx_write(MO_AUDR_LNGTH,    128); /* fifo size */
-	cx_write(MO_AUD_DMACNTRL, 0x03); /* need audio fifo */
+/*
+   This should be needed only on cx88-alsa. It seems that some cx88 chips have
+   bugs and does require DMA enabled for it to work.
+ */
+	cx88_start_audio_dma(core);
 	return 0;
 }
 
+
+
 int cx88_set_tvnorm(struct cx88_core *core, struct cx88_tvnorm *norm)
 {
 	u32 fsc8;
@@ -1204,6 +1231,8 @@
 EXPORT_SYMBOL(cx88_vdev_init);
 EXPORT_SYMBOL(cx88_core_get);
 EXPORT_SYMBOL(cx88_core_put);
+EXPORT_SYMBOL(cx88_start_audio_dma);
+EXPORT_SYMBOL(cx88_stop_audio_dma);
 
 /*
  * Local variables:
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 9790d41..4a8fb16 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -94,7 +94,7 @@
 	struct cx88_core *core = i2c_get_adapdata(client->adapter);
 
 	dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
-		client->driver->name, client->addr, client->name);
+		client->driver->driver.name, client->addr, client->name);
 	if (!client->driver->command)
 		return 0;
 
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 38b12eb..461019d 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -453,7 +453,6 @@
 		input_dev->id.product = pci->device;
 	}
 	input_dev->cdev.dev = &pci->dev;
-
 	/* record handles to ourself */
 	ir->core = core;
 	core->ir = ir;
@@ -586,7 +585,6 @@
 MODULE_AUTHOR("Gerd Knorr, Pavel Machek, Chris Pascoe");
 MODULE_DESCRIPTION("input driver for cx88 GPIO-based IR remote controls");
 MODULE_LICENSE("GPL");
-
 /*
  * Local variables:
  * c-basic-offset: 8
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 6d9bec1..a1b120c 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -119,13 +119,10 @@
 
 static void set_audio_start(struct cx88_core *core, u32 mode)
 {
-	// mute
+	/* mute */
 	cx_write(AUD_VOL_CTL, (1 << 6));
 
-	// start programming
-	cx_write(MO_AUD_DMACNTRL, 0x0000);
-	msleep(100);
-	//cx_write(AUD_CTL, 0x0000);
+	/* start programming */
 	cx_write(AUD_INIT, mode);
 	cx_write(AUD_INIT_LD, 0x0001);
 	cx_write(AUD_SOFT_RESET, 0x0001);
@@ -135,17 +132,21 @@
 {
 	u32 volume;
 
+	/* restart dma; This avoids buzz in NICAM and is good in others  */
+	cx88_stop_audio_dma(core);
+	cx_write(AUD_RATE_THRES_DMD, 0x000000C0);
+	cx88_start_audio_dma(core);
+
 	if (cx88_boards[core->board].blackbird) {
-		// sets sound input from external adc
+		/* sets sound input from external adc */
 		cx_set(AUD_CTL, EN_I2SIN_ENABLE);
-		//cx_write(AUD_I2SINPUTCNTL, 0);
 		cx_write(AUD_I2SINPUTCNTL, 4);
 		cx_write(AUD_BAUDRATE, 1);
-		// 'pass-thru mode': this enables the i2s output to the mpeg encoder
+		/* 'pass-thru mode': this enables the i2s output to the mpeg encoder */
 		cx_set(AUD_CTL, EN_I2SOUT_ENABLE);
 		cx_write(AUD_I2SOUTPUTCNTL, 1);
 		cx_write(AUD_I2SCNTL, 0);
-		//cx_write(AUD_APB_IN_RATE_ADJ, 0);
+		/* cx_write(AUD_APB_IN_RATE_ADJ, 0); */
 	} else {
 		ctl |= EN_DAC_ENABLE;
 		cx_write(AUD_CTL, ctl);
@@ -153,7 +154,6 @@
 
 	/* finish programming */
 	cx_write(AUD_SOFT_RESET, 0x0000);
-	cx_write(MO_AUD_DMACNTRL, 0x0003);
 
 	/* unmute */
 	volume = cx_sread(SHADOW_AUD_VOL_CTL);
@@ -313,7 +313,6 @@
 		{AUD_RATE_ADJ3, 0x00000100},
 		{AUD_RATE_ADJ4, 0x00000400},
 		{AUD_RATE_ADJ5, 0x00001000},
-		//{ AUD_DMD_RA_DDS,        0x00c0d5ce },
 		{AUD_ERRLOGPERIOD_R, 0x00000fff},
 		{AUD_ERRINTRPTTHSHLD1_R, 0x000003ff},
 		{AUD_ERRINTRPTTHSHLD2_R, 0x000000ff},
@@ -351,12 +350,12 @@
 		set_audio_registers(core, nicam_l);
 		break;
 	case WW_I:
-		dprintk("%s PAL-I NICAM (status: devel)\n", __FUNCTION__);
+		dprintk("%s PAL-I NICAM (status: known-good)\n", __FUNCTION__);
 		set_audio_registers(core, nicam_bgdki_common);
 		set_audio_registers(core, nicam_i);
 		break;
 	default:
-		dprintk("%s PAL-BGDK NICAM (status: unknown)\n", __FUNCTION__);
+		dprintk("%s PAL-BGDK NICAM (status: known-good)\n", __FUNCTION__);
 		set_audio_registers(core, nicam_bgdki_common);
 		set_audio_registers(core, nicam_default);
 		break;
@@ -715,8 +714,7 @@
 		/* if bit1=1 then nicam is detected */
 		j += ((cx_read(AUD_NICAM_STATUS2) & 0x02) >> 1);
 
-		/* 3x detected: absolutly sure now */
-		if (j == 3) {
+		if (j == 1) {
 			dprintk("nicam is detected.\n");
 			return 1;
 		}
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index b19d3a9e..77beafc 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -411,7 +411,6 @@
 	struct videobuf_dvb        dvb;
 	void*                      fe_handle;
 	int                        (*fe_release)(void *handle);
-
 	/* for switching modulation types */
 	unsigned char              ts_gen_cntrl;
 
@@ -491,6 +490,10 @@
 extern void cx88_core_put(struct cx88_core *core,
 			  struct pci_dev *pci);
 
+extern int cx88_start_audio_dma(struct cx88_core *core);
+extern int cx88_stop_audio_dma(struct cx88_core *core);
+
+
 /* ----------------------------------------------------------- */
 /* cx88-vbi.c                                                  */
 
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index d54bc0127..0cfe754 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -32,7 +32,7 @@
 
 /* #define ENABLE_DEBUG_ISOC_FRAMES */
 
-unsigned int core_debug;
+static unsigned int core_debug;
 module_param(core_debug,int,0644);
 MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
 
@@ -41,7 +41,7 @@
 		printk(KERN_INFO "%s %s :"fmt, \
 			 dev->name, __FUNCTION__ , ##arg); } while (0)
 
-unsigned int reg_debug;
+static unsigned int reg_debug;
 module_param(reg_debug,int,0644);
 MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
 
@@ -50,7 +50,7 @@
 		printk(KERN_INFO "%s %s :"fmt, \
 			 dev->name, __FUNCTION__ , ##arg); } while (0)
 
-unsigned int isoc_debug;
+static unsigned int isoc_debug;
 module_param(isoc_debug,int,0644);
 MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]");
 
@@ -116,47 +116,6 @@
 	}
 }
 
-static void *rvmalloc(size_t size)
-{
-	void *mem;
-	unsigned long adr;
-
-	size = PAGE_ALIGN(size);
-
-	mem = vmalloc_32((unsigned long)size);
-	if (!mem)
-		return NULL;
-
-	memset(mem, 0, size);
-
-	adr = (unsigned long)mem;
-	while (size > 0) {
-		SetPageReserved(vmalloc_to_page((void *)adr));
-		adr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-
-	return mem;
-}
-
-static void rvfree(void *mem, size_t size)
-{
-	unsigned long adr;
-
-	if (!mem)
-		return;
-
-	size = PAGE_ALIGN(size);
-
-	adr = (unsigned long)mem;
-	while (size > 0) {
-		ClearPageReserved(vmalloc_to_page((void *)adr));
-		adr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-
-	vfree(mem);
-}
 
 /*
  * em28xx_request_buffers()
@@ -167,14 +126,16 @@
 	const size_t imagesize = PAGE_ALIGN(dev->frame_size);	/*needs to be page aligned cause the buffers can be mapped individually! */
 	void *buff = NULL;
 	u32 i;
-	em28xx_coredbg("requested %i buffers with size %i", count, imagesize);
+	em28xx_coredbg("requested %i buffers with size %zd", count, imagesize);
 	if (count > EM28XX_NUM_FRAMES)
 		count = EM28XX_NUM_FRAMES;
 
 	dev->num_frames = count;
 	while (dev->num_frames > 0) {
-		if ((buff = rvmalloc(dev->num_frames * imagesize)))
+		if ((buff = vmalloc_32(dev->num_frames * imagesize))) {
+			memset(buff, 0, dev->num_frames * imagesize);
 			break;
+		}
 		dev->num_frames--;
 	}
 
@@ -217,8 +178,7 @@
 void em28xx_release_buffers(struct em28xx *dev)
 {
 	if (dev->num_frames) {
-		rvfree(dev->frame[0].bufmem,
-		       dev->num_frames * PAGE_ALIGN(dev->frame[0].buf.length));
+		vfree(dev->frame[0].bufmem);
 		dev->num_frames = 0;
 	}
 }
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index b32d985..d14bcf4 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -41,7 +41,7 @@
 MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
 
 #define dprintk1(lvl,fmt, args...) if (i2c_debug>=lvl) do {\
-			printk(fmt , ##args); } while (0)
+			printk(fmt, ##args); } while (0)
 #define dprintk2(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
 			printk(KERN_DEBUG "%s at %s: " fmt, \
 			dev->name, __FUNCTION__ , ##args); } while (0)
@@ -497,7 +497,6 @@
 
 static struct i2c_client em28xx_client_template = {
 	.name = "em28xx internal",
-	.flags = I2C_CLIENT_ALLOW_USE,
 };
 
 /* ----------------------------------------------------------- */
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 57c1826b92..3a56120 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -189,16 +189,6 @@
 
 /*********************  v4l2 interface  ******************************************/
 
-static inline unsigned long kvirt_to_pa(unsigned long adr)
-{
-	unsigned long kva, ret;
-
-	kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
-	kva |= adr & (PAGE_SIZE - 1);
-	ret = __pa(kva);
-	return ret;
-}
-
 /*
  * em28xx_config()
  * inits registers with sane defaults
@@ -226,7 +216,7 @@
  * em28xx_config_i2c()
  * configure i2c attached devices
  */
-void em28xx_config_i2c(struct em28xx *dev)
+static void em28xx_config_i2c(struct em28xx *dev)
 {
 	struct v4l2_frequency f;
 	struct video_decoder_init em28xx_vdi = {.data = NULL };
@@ -616,7 +606,8 @@
 static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	unsigned long size = vma->vm_end - vma->vm_start,
-	    start = vma->vm_start, pos, page;
+	    start = vma->vm_start;
+	void *pos;
 	u32 i;
 
 	struct em28xx *dev = filp->private_data;
@@ -657,12 +648,10 @@
 	vma->vm_flags |= VM_IO;
 	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */
 
-	pos = (unsigned long)dev->frame[i].bufmem;
+	pos = dev->frame[i].bufmem;
 	while (size > 0) {	/* size is page-aligned */
-		page = vmalloc_to_pfn((void *)pos);
-		if (remap_pfn_range(vma, start, page, PAGE_SIZE,
-				    vma->vm_page_prot)) {
-			em28xx_videodbg("mmap: rename page map failed\n");
+		if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
+			em28xx_videodbg("mmap: vm_insert_page failed\n");
 			up(&dev->fileop_lock);
 			return -EAGAIN;
 		}
@@ -1895,7 +1884,6 @@
 }
 
 static struct usb_driver em28xx_usb_driver = {
-	.owner = THIS_MODULE,
 	.name = "em28xx",
 	.probe = em28xx_usb_probe,
 	.disconnect = em28xx_usb_disconnect,
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
index deeef12..bb5cbec 100644
--- a/drivers/media/video/indycam.c
+++ b/drivers/media/video/indycam.c
@@ -451,10 +451,10 @@
 }
 
 static struct i2c_driver i2c_driver_indycam = {
-	.owner		= THIS_MODULE,
-	.name		= "indycam",
+	.driver = {
+		.name 	= "indycam",
+	},
 	.id		= I2C_DRIVERID_INDYCAM,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter = indycam_probe,
 	.detach_client	= indycam_detach,
 	.command	= indycam_command,
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index 6345e29..de1385e 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -291,13 +291,12 @@
 	u32                     mask_keycode;
 	u32                     mask_keydown;
 	u32                     mask_keyup;
-	u32			polling;
+	u32                     polling;
 	u32                     last_gpio;
 	struct work_struct      work;
 	struct timer_list       timer;
 
 	/* RC5 gpio */
-
 	u32 rc5_gpio;
 	struct timer_list timer_end;	/* timer_end for code completion */
 	struct timer_list timer_keyup;	/* timer_end for key release */
@@ -647,7 +646,7 @@
 		driver.any_irq = ir_rc5_irq;
 		driver.gpio_irq = NULL;
 		ir->rc5_gpio = 1;
-		 break;
+		break;
 	}
 	if (NULL == ir_codes) {
 		kfree(ir);
@@ -657,7 +656,7 @@
 
 	if (ir->rc5_gpio) {
 		u32 gpio;
-		/* enable remote irq */
+	    	/* enable remote irq */
 		bttv_gpio_inout(sub->core, (1 << 4), 1 << 4);
 		gpio = bttv_gpio_read(sub->core);
 		bttv_gpio_write(sub->core, gpio & ~(1 << 4));
@@ -726,6 +725,7 @@
 		del_timer(&ir->timer);
 		flush_scheduled_work();
 	}
+
 	if (ir->rc5_gpio) {
 		u32 gpio;
 
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 801c736..3cc1d6a 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -40,6 +40,7 @@
 #include <linux/i2c.h>
 #include <linux/workqueue.h>
 #include <asm/semaphore.h>
+
 #include <media/ir-common.h>
 #include <media/ir-kbd-i2c.h>
 
@@ -277,9 +278,10 @@
 static int ir_probe(struct i2c_adapter *adap);
 
 static struct i2c_driver driver = {
-	.name           = "ir remote kbd driver",
-	.id             = I2C_DRIVERID_EXP3, /* FIXME */
-	.flags          = I2C_DF_NOTIFY,
+	.driver = {
+		.name   = "ir remote kbd driver",
+	},
+	.id             = I2C_DRIVERID_INFRARED,
 	.attach_adapter = ir_probe,
 	.detach_client  = ir_detach,
 };
@@ -296,15 +298,15 @@
 	IR_KEYTAB_TYPE *ir_codes = NULL;
 	char *name;
 	int ir_type;
-        struct IR_i2c *ir;
+	struct IR_i2c *ir;
 	struct input_dev *input_dev;
 
-	ir = kzalloc(sizeof(struct IR_i2c), GFP_KERNEL);
+	ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!ir || !input_dev) {
 		kfree(ir);
 		input_free_device(input_dev);
-                return -ENOMEM;
+		return -ENOMEM;
 	}
 
 	ir->c = client_template;
@@ -360,7 +362,7 @@
 	/* register i2c device
 	 * At device register, IR codes may be changed to be
 	 * board dependent.
-	*/
+	 */
 	i2c_attach_client(&ir->c);
 
 	/* If IR not supported or disabled, unregisters driver */
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index a23fb03..183253e 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -59,7 +59,8 @@
 #define msp3400_dbg(fmt, arg...) \
 	do { \
 		if (debug) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
+			       client->driver->driver.name, \
 			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
 	} while (0)
 
@@ -67,7 +68,8 @@
 #define msp3400_dbg_mediumvol(fmt, arg...) \
 	do { \
 		if (debug >= 2) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
+				client->driver->driver.name, \
 				i2c_adapter_id(client->adapter), client->addr , ## arg); \
 	} while (0)
 
@@ -75,18 +77,19 @@
 #define msp3400_dbg_highvol(fmt, arg...) \
 	do { \
 		if (debug >= 16) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
+				client->driver->driver.name, \
 				i2c_adapter_id(client->adapter), client->addr , ## arg); \
 	} while (0)
 
 #define msp3400_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
 		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 #define msp3400_warn(fmt, arg...) do { \
-	printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->driver.name, \
 		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 #define msp3400_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
 		i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 
 #define OPMODE_AUTO    -1
@@ -134,7 +137,7 @@
 	int rxsubchans;
 
 	int muted;
-	int left, right;        /* volume */
+	int left, right;	/* volume */
 	int bass, treble;
 
 	/* shadow register set */
@@ -882,6 +885,7 @@
 		msp->watch_stereo = 0;
 }
 
+
 static int msp3400c_thread(void *data)
 {
 	struct i2c_client *client = data;
@@ -889,6 +893,7 @@
 	struct CARRIER_DETECT *cd;
 	int count, max1,max2,val1,val2, val,this;
 
+
 	msp3400_info("msp3400 daemon started\n");
 	for (;;) {
 		msp3400_dbg_mediumvol("msp3400 thread: sleep\n");
@@ -1162,6 +1167,7 @@
 	int mode,val,i,std;
 
 	msp3400_info("msp3410 daemon started\n");
+
 	for (;;) {
 		msp3400_dbg_mediumvol("msp3410 thread: sleep\n");
 		msp34xx_sleep(msp,-1);
@@ -1384,6 +1390,7 @@
 	int val, std, i;
 
 	msp3400_info("msp34xxg daemon started\n");
+
 	msp->source = 1; /* default */
 	for (;;) {
 		msp3400_dbg_mediumvol("msp34xxg thread: sleep\n");
@@ -1557,14 +1564,12 @@
 static void msp_wake_thread(struct i2c_client *client);
 
 static struct i2c_driver driver = {
-	.owner          = THIS_MODULE,
-	.name           = "msp3400",
-        .id             = I2C_DRIVERID_MSP3400,
-        .flags          = I2C_DF_NOTIFY,
-        .attach_adapter = msp_probe,
-        .detach_client  = msp_detach,
-        .command        = msp_command,
+	.id             = I2C_DRIVERID_MSP3400,
+	.attach_adapter = msp_probe,
+	.detach_client  = msp_detach,
+	.command        = msp_command,
 	.driver = {
+		.name    = "i2c msp3400 driver",
 		.suspend = msp_suspend,
 		.resume  = msp_resume,
 	},
@@ -1573,8 +1578,7 @@
 static struct i2c_client client_template =
 {
 	.name      = "(unset)",
-	.flags     = I2C_CLIENT_ALLOW_USE,
-        .driver    = &driver,
+	.driver    = &driver,
 };
 
 static int msp_attach(struct i2c_adapter *adap, int addr, int kind)
diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c
index 2de34eb..428f1bb 100644
--- a/drivers/media/video/ovcamchip/ovcamchip_core.c
+++ b/drivers/media/video/ovcamchip/ovcamchip_core.c
@@ -410,11 +410,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-	.owner =		THIS_MODULE,
-	.name =			"ovcamchip",
+	.driver = {
+		.name =		"ovcamchip",
+	},
 	.id =			I2C_DRIVERID_OVCAMCHIP,
 	.class =		I2C_CLASS_CAM_DIGITAL,
-	.flags =		I2C_DF_NOTIFY,
 	.attach_adapter =	ovcamchip_attach,
 	.detach_client =	ovcamchip_detach,
 	.command =		ovcamchip_command,
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index b8054da..0aa9e72 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -151,25 +151,18 @@
 	return 0;
 }
 
-static int saa5246a_command(struct i2c_client *device, unsigned int cmd,
-	void *arg)
-{
-	return -EINVAL;
-}
-
 /*
  *	I2C interfaces
  */
 
 static struct i2c_driver i2c_driver_videotext =
 {
-	.owner 		= THIS_MODULE,
-	.name 		= IF_NAME,		/* name */
+	.driver = {
+		.name 	= IF_NAME,		/* name */
+	},
 	.id 		= I2C_DRIVERID_SAA5249, /* in i2c.h */
-	.flags 		= I2C_DF_NOTIFY,
 	.attach_adapter = saa5246a_probe,
 	.detach_client  = saa5246a_detach,
-	.command 	= saa5246a_command
 };
 
 static struct i2c_client client_template = {
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 7ffa2e9..a51c7bd 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -226,23 +226,16 @@
 	return 0;
 }
 
-static int saa5249_command(struct i2c_client *device,
-			     unsigned int cmd, void *arg)
-{
-	return -EINVAL;
-}
-
 /* new I2C driver support */
 
 static struct i2c_driver i2c_driver_videotext = 
 {
-	.owner 		= THIS_MODULE,
-	.name 		= IF_NAME,		/* name */
+	.driver = {
+		.name 	= IF_NAME,		/* name */
+	},
 	.id 		= I2C_DRIVERID_SAA5249, /* in i2c.h */
-	.flags 		= I2C_DF_NOTIFY,
 	.attach_adapter = saa5249_probe,
 	.detach_client  = saa5249_detach,
-	.command 	= saa5249_command
 };
 
 static struct i2c_client client_template = {
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index dca3ddf..d60a783 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -422,7 +422,6 @@
 	s->timer.function = saa6588_timer;
 	s->timer.data = (unsigned long)s;
 	schedule_work(&s->work);
-
 	return 0;
 }
 
@@ -496,10 +495,10 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-	.owner = THIS_MODULE,
-	.name = "i2c saa6588 driver",
+	.driver = {
+		.name = "i2c saa6588 driver",
+	},
 	.id = -1,		/* FIXME */
-	.flags = I2C_DF_NOTIFY,
 	.attach_adapter = saa6588_probe,
 	.detach_client = saa6588_detach,
 	.command = saa6588_command,
@@ -507,7 +506,6 @@
 
 static struct i2c_client client_template = {
 	.name = "saa6588",
-	.flags = I2C_CLIENT_ALLOW_USE,
 	.driver = &driver,
 };
 
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index e116bdb..619ff0b 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -501,7 +501,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_saa7110;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));
 
 	decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL);
@@ -587,11 +586,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_saa7110 = {
-	.owner = THIS_MODULE,
-	.name = "saa7110",
+	.driver = {
+		.name = "saa7110",
+	},
 
 	.id = I2C_DRIVERID_SAA7110,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = saa7110_attach_adapter,
 	.detach_client = saa7110_detach_client,
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
index fe8a5e4..acaeee5 100644
--- a/drivers/media/video/saa7111.c
+++ b/drivers/media/video/saa7111.c
@@ -518,7 +518,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_saa7111;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client)));
 
 	decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
@@ -590,11 +589,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_saa7111 = {
-	.owner = THIS_MODULE,
-	.name = "saa7111",
+	.driver = {
+		.name = "saa7111",
+	},
 
 	.id = I2C_DRIVERID_SAA7111A,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = saa7111_attach_adapter,
 	.detach_client = saa7111_detach_client,
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c
index d9f50e2..b7ac012 100644
--- a/drivers/media/video/saa7114.c
+++ b/drivers/media/video/saa7114.c
@@ -859,7 +859,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_saa7114;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
 
 	decoder = kmalloc(sizeof(struct saa7114), GFP_KERNEL);
@@ -1204,11 +1203,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_saa7114 = {
-	.owner = THIS_MODULE,
-	.name = "saa7114",
+	.driver = {
+		.name = "saa7114",
+	},
 
 	.id = I2C_DRIVERID_SAA7114,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = saa7114_attach_adapter,
 	.detach_client = saa7114_detach_client,
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 0235cef..29e28c7 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -52,15 +52,16 @@
 #define saa7115_dbg(fmt,arg...) \
 	do { \
 		if (debug) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
+			       client->driver->driver.name, \
 			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
 	} while (0)
 
 #define saa7115_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
 	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 #define saa7115_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
 	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 
 static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
@@ -771,17 +772,19 @@
 
 static void saa7115_log_status(struct i2c_client *client)
 {
-	static const char * const audclk_freq_strs[] = {
-		"44.1 kHz",
-		"48 kHz",
-		"32 kHz"
-	};
 	struct saa7115_state *state = i2c_get_clientdata(client);
+	char *audfreq = "undefined";
 	int reg1e, reg1f;
 	int signalOk;
 	int vcr;
 
-	saa7115_info("Audio frequency: %s\n", audclk_freq_strs[state->audclk_freq]);
+	switch (state->audclk_freq) {
+		case V4L2_AUDCLK_32_KHZ:  audfreq = "32 kHz"; break;
+		case V4L2_AUDCLK_441_KHZ: audfreq = "44.1 kHz"; break;
+		case V4L2_AUDCLK_48_KHZ:  audfreq = "48 kHz"; break;
+	}
+
+	saa7115_info("Audio frequency: %s\n", audfreq);
 	if (client->name[6] == '4') {
 		/* status for the saa7114 */
 		reg1f = saa7115_read(client, 0x1f);
@@ -1268,7 +1271,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_saa7115;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	snprintf(client->name, sizeof(client->name) - 1, "saa7115");
 
 	saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1);
@@ -1352,13 +1354,13 @@
 
 /* i2c implementation */
 static struct i2c_driver i2c_driver_saa7115 = {
-	.name = "saa7115",
+	.driver = {
+		.name = "saa7115",
+	},
 	.id = I2C_DRIVERID_SAA711X,
-	.flags = I2C_DF_NOTIFY,
 	.attach_adapter = saa7115_probe,
 	.detach_client = saa7115_detach,
 	.command = saa7115_command,
-	.owner = THIS_MODULE,
 };
 
 
diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c
index 25b30f3..8008537 100644
--- a/drivers/media/video/saa711x.c
+++ b/drivers/media/video/saa711x.c
@@ -59,7 +59,7 @@
 #define dprintk(num, format, args...) \
 	do { \
 		if (debug >= num) \
-			printk(format , ##args); \
+			printk(format, ##args); \
 	} while (0)
 
 /* ----------------------------------------------------------------------- */
@@ -323,7 +323,7 @@
 
 		case VIDEO_MODE_SECAM:
 			saa711x_write(client, 0x08,
-				      (decoder->reg[0x0e] & 0x3f) | 0x00);
+				      (decoder->reg[0x08] & 0x3f) | 0x00);
 			saa711x_write(client, 0x0e,
 				      (decoder->reg[0x0e] & 0x8f) | 0x50);
 			break;
@@ -494,7 +494,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_saa711x;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client)));
 	decoder = kmalloc(sizeof(struct saa711x), GFP_KERNEL);
 	if (decoder == NULL) {
@@ -565,11 +564,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_saa711x = {
-	.owner = THIS_MODULE,
-	.name = "saa711x",
+	.driver = {
+		.name = "saa711x",
+	},
 
 	.id = I2C_DRIVERID_SAA711X,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = saa711x_attach_adapter,
 	.detach_client = saa711x_detach_client,
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 843431f..bca6ed0 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -69,7 +69,8 @@
 #define saa7127_dbg(fmt, arg...) \
 	do { \
 		if (debug >= 1) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
+			       client->driver->driver.name, \
 			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
 	} while (0)
 
@@ -77,15 +78,16 @@
 #define saa7127_dbg_highvol(fmt, arg...) \
 	do { \
 		if (debug == 2) \
-			printk(KERN_INFO "%s debug %d-%04x: " fmt, client->driver->name, \
+			printk(KERN_INFO "%s debug %d-%04x: " fmt, \
+			       client->driver->driver.name, \
 			       i2c_adapter_id(client->adapter), client->addr , ## arg); \
 	} while (0)
 
 #define saa7127_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
 	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 #define saa7127_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
 	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 
 static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
@@ -223,7 +225,7 @@
 };
 
 #define SAA7127_50HZ_DAC_CONTROL 0x02
-struct i2c_reg_value saa7127_init_config_50hz[] = {
+static struct i2c_reg_value saa7127_init_config_50hz[] = {
 	{ SAA7127_REG_BURST_START, 			0x21 },
 	/* BURST_END is also used as a chip ID in saa7127_detect_client */
 	{ SAA7127_REG_BURST_END, 			0x1d },
@@ -389,7 +391,7 @@
 static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data *data)
 {
 	struct saa7127_state *state = i2c_get_clientdata(client);
-	u16 cc = data->data[0] << 8 | data->data[1];
+	u16 cc = data->data[1] << 8 | data->data[0];
 	int enable = (data->line != 0);
 
 	if (enable && (data->field != 0 || data->line != 21))
@@ -397,7 +399,7 @@
 	if (state->cc_enable != enable) {
 		saa7127_dbg("Turn CC %s\n", enable ? "on" : "off");
 		saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
-				(enable << 6) | 0x11);
+				(state->xds_enable << 7) | (enable << 6) | 0x11);
 		state->cc_enable = enable;
 	}
 	if (!enable)
@@ -423,7 +425,7 @@
 	if (state->xds_enable != enable) {
 		saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off");
 		saa7127_write(client, SAA7127_REG_CLOSED_CAPTION,
-				(enable << 7) | 0x11);
+				(enable << 7) | (state->cc_enable << 6) | 0x11);
 		state->xds_enable = enable;
 	}
 	if (!enable)
@@ -696,7 +698,7 @@
 
 /* ----------------------------------------------------------------------- */
 
-struct i2c_driver i2c_driver_saa7127;
+static struct i2c_driver i2c_driver_saa7127;
 
 /* ----------------------------------------------------------------------- */
 
@@ -719,7 +721,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_saa7127;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	snprintf(client->name, sizeof(client->name) - 1, "saa7127");
 
 	saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1);
@@ -818,14 +819,14 @@
 
 /* ----------------------------------------------------------------------- */
 
-struct i2c_driver i2c_driver_saa7127 = {
-	.name = "saa7127",
+static struct i2c_driver i2c_driver_saa7127 = {
+	.driver = {
+		.name = "saa7127",
+	},
 	.id = I2C_DRIVERID_SAA7127,
-	.flags = I2C_DF_NOTIFY,
 	.attach_adapter = saa7127_probe,
 	.detach_client = saa7127_detach,
 	.command = saa7127_command,
-	.owner = THIS_MODULE,
 };
 
 
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 7bdeabe..8a5c3e7 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -1,11 +1,10 @@
 config VIDEO_SAA7134
 	tristate "Philips SAA7134 support"
-	depends on VIDEO_DEV && PCI && I2C && SOUND && SND
+	depends on VIDEO_DEV && PCI && I2C
 	select VIDEO_BUF
 	select VIDEO_IR
 	select VIDEO_TUNER
 	select CRC32
-	select SND_PCM_OSS
 	---help---
 	  This is a video4linux driver for Philips SAA713x based
 	  TV cards.
@@ -13,6 +12,29 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called saa7134.
 
+config VIDEO_SAA7134_ALSA
+	tristate "Philips SAA7134 DMA audio support"
+	depends on VIDEO_SAA7134 && SND
+	select SND_PCM_OSS
+	---help---
+	  This is a video4linux driver for direct (DMA) audio in
+	  Philips SAA713x based TV cards using ALSA
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called saa7134-alsa.
+
+config VIDEO_SAA7134_OSS
+	tristate "Philips SAA7134 DMA audio support (OSS, DEPRECATED)"
+	depends on VIDEO_SAA7134 && SOUND_PRIME && !VIDEO_SAA7134_ALSA
+	---help---
+	  This is a video4linux driver for direct (DMA) audio in
+	  Philips SAA713x based TV cards using OSS
+
+	  This is deprecated in favor of the ALSA module
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called saa7134-oss.
+
 config VIDEO_SAA7134_DVB
 	tristate "DVB/ATSC Support for saa7134 based TV cards"
 	depends on VIDEO_SAA7134 && DVB_CORE
@@ -42,8 +64,8 @@
 	  If you are unsure, choose Y.
 
 config VIDEO_SAA7134_DVB_MT352
-	tristate "Zarlink MT352 DVB-T Support"
-	default m
+	bool "Zarlink MT352 DVB-T Support"
+	default y
 	depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
 	select DVB_MT352
 	---help---
@@ -51,8 +73,8 @@
 	  Philips saa7134 chip and the MT352 demodulator.
 
 config VIDEO_SAA7134_DVB_TDA1004X
-	tristate "Phillips TDA10045H/TDA10046H DVB-T Support"
-	default m
+	bool "Phillips TDA10045H/TDA10046H DVB-T Support"
+	default y
 	depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
 	select DVB_TDA1004X
 	---help---
@@ -60,8 +82,8 @@
 	  Philips saa7134 chip and the TDA10045H/TDA10046H demodulator.
 
 config VIDEO_SAA7134_DVB_NXT200X
-	tristate "NXT2002/NXT2004 ATSC Support"
-	default m
+	bool "NXT2002/NXT2004 ATSC Support"
+	default y
 	depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS
 	select DVB_NXT200X
 	---help---
diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile
index 4226b61..1ba9984 100644
--- a/drivers/media/video/saa7134/Makefile
+++ b/drivers/media/video/saa7134/Makefile
@@ -4,22 +4,20 @@
 		saa7134-video.o saa7134-input.o
 
 obj-$(CONFIG_VIDEO_SAA7134) +=  saa7134.o saa7134-empress.o \
-				saa6752hs.o saa7134-alsa.o \
-				saa7134-oss.o
+				saa6752hs.o
+
+obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
+obj-$(CONFIG_VIDEO_SAA7134_OSS) += saa7134-oss.o
+
 obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
 
 EXTRA_CFLAGS += -I$(src)/..
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
-ifneq ($(CONFIG_VIDEO_BUF_DVB),n)
- EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1
-endif
-ifneq ($(CONFIG_DVB_MT352),n)
- EXTRA_CFLAGS += -DHAVE_MT352=1
-endif
-ifneq ($(CONFIG_DVB_TDA1004X),n)
- EXTRA_CFLAGS += -DHAVE_TDA1004X=1
-endif
-ifneq ($(CONFIG_DVB_NXT200X),n)
- EXTRA_CFLAGS += -DHAVE_NXT200X=1
-endif
+
+extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1
+extra-cflags-$(CONFIG_DVB_MT352)     += -DHAVE_MT352=1
+extra-cflags-$(CONFIG_DVB_TDA1004X)  += -DHAVE_TDA1004X=1
+extra-cflags-$(CONFIG_DVB_NXT200X)   += -DHAVE_NXT200X=1
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index cdd1ed9..4615a98 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -523,7 +523,8 @@
 	h->standard = 0;
 
 	i2c_set_clientdata(&h->client, h);
-        i2c_attach_client(&h->client);
+	i2c_attach_client(&h->client);
+
 	return 0;
 }
 
@@ -596,20 +597,19 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-	.owner          = THIS_MODULE,
-        .name           = "i2c saa6752hs MPEG encoder",
-        .id             = I2C_DRIVERID_SAA6752HS,
-        .flags          = I2C_DF_NOTIFY,
-        .attach_adapter = saa6752hs_probe,
-        .detach_client  = saa6752hs_detach,
-        .command        = saa6752hs_command,
+	.driver = {
+		.name   = "i2c saa6752hs MPEG encoder",
+	},
+	.id             = I2C_DRIVERID_SAA6752HS,
+	.attach_adapter = saa6752hs_probe,
+	.detach_client  = saa6752hs_detach,
+	.command        = saa6752hs_command,
 };
 
 static struct i2c_client client_template =
 {
 	.name       = "saa6752hs",
-	.flags      = I2C_CLIENT_ALLOW_USE,
-        .driver     = &driver,
+	.driver     = &driver,
 };
 
 static int __init saa6752hs_init_module(void)
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index 5707c66..ade05f7 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -51,6 +51,7 @@
 #define MIXER_ADDR_LINE2	2
 #define MIXER_ADDR_LAST		2
 
+
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
 static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
@@ -58,14 +59,15 @@
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
 
-int position;
-
 #define dprintk(fmt, arg...)    if (debug) \
-        printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ## arg)
+	printk(KERN_DEBUG "%s/alsa: " fmt, dev->name , ##arg)
+
+
 
 /*
  * Main chip structure
  */
+
 typedef struct snd_card_saa7134 {
 	snd_card_t *card;
 	spinlock_t mixer_lock;
@@ -140,7 +142,8 @@
  *
  */
 
-void saa7134_irq_alsa_done(struct saa7134_dev *dev, unsigned long status)
+static void saa7134_irq_alsa_done(struct saa7134_dev *dev,
+				  unsigned long status)
 {
 	int next_blk, reg = 0;
 
@@ -209,8 +212,8 @@
 
 static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
-        struct saa7134_dmasound *dmasound = dev_id;
-        struct saa7134_dev *dev = dmasound->priv_data;
+	struct saa7134_dmasound *dmasound = dev_id;
+	struct saa7134_dev *dev = dmasound->priv_data;
 
 	unsigned long report, status;
 	int loop, handled = 0;
@@ -881,7 +884,7 @@
  *
  */
 
-int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
+static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
 {
 
 	snd_card_t *card;
@@ -945,6 +948,8 @@
 	sprintf(card->longname, "%s at 0x%lx irq %d",
 		chip->dev->name, chip->iobase, chip->irq);
 
+	printk(KERN_INFO "%s/alsa: %s registered as card %d\n",dev->name,card->longname,index[devnum]);
+
 	if ((err = snd_card_register(card)) == 0) {
 		snd_saa7134_cards[devnum] = card;
 		return 0;
@@ -955,6 +960,22 @@
 	return err;
 }
 
+
+static int alsa_device_init(struct saa7134_dev *dev)
+{
+	dev->dmasound.priv_data = dev;
+	alsa_card_saa7134_create(dev,dev->nr);
+	return 1;
+}
+
+static int alsa_device_exit(struct saa7134_dev *dev)
+{
+
+	snd_card_free(snd_saa7134_cards[dev->nr]);
+	snd_saa7134_cards[dev->nr] = NULL;
+	return 1;
+}
+
 /*
  * Module initializer
  *
@@ -968,16 +989,20 @@
 	struct saa7134_dev *dev = NULL;
 	struct list_head *list;
 
-	position = 0;
+	if (!dmasound_init && !dmasound_exit) {
+		dmasound_init = alsa_device_init;
+		dmasound_exit = alsa_device_exit;
+	} else {
+		printk(KERN_WARNING "saa7134 ALSA: can't load, DMA sound handler already assigned (probably to OSS)\n");
+		return -EBUSY;
+	}
 
-        printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
+	printk(KERN_INFO "saa7134 ALSA driver for DMA sound loaded\n");
 
 	list_for_each(list,&saa7134_devlist) {
 		dev = list_entry(list, struct saa7134_dev, devlist);
 		if (dev->dmasound.priv_data == NULL) {
-			dev->dmasound.priv_data = dev;
-			alsa_card_saa7134_create(dev,position);
-			position++;
+			alsa_device_init(dev);
 		} else {
 			printk(KERN_ERR "saa7134 ALSA: DMA sound is being handled by OSS. ignoring %s\n",dev->name);
 			return -EBUSY;
@@ -988,13 +1013,14 @@
 		printk(KERN_INFO "saa7134 ALSA: no saa7134 cards found\n");
 
 	return 0;
+
 }
 
 /*
  * Module destructor
  */
 
-void saa7134_alsa_exit(void)
+static void saa7134_alsa_exit(void)
 {
 	int idx;
 
@@ -1002,12 +1028,18 @@
 		snd_card_free(snd_saa7134_cards[idx]);
 	}
 
+	dmasound_init = NULL;
+	dmasound_exit = NULL;
 	printk(KERN_INFO "saa7134 ALSA driver for DMA sound unloaded\n");
 
 	return;
 }
 
-module_init(saa7134_alsa_init);
+/* We initialize this late, to make sure the sound system is up and running */
+late_initcall(saa7134_alsa_init);
 module_exit(saa7134_alsa_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ricardo Cerqueira");
+
+
+
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 75abc20..672fb20 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -976,7 +976,7 @@
 		.radio_type     = UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
-		.tda9887_conf   = TDA9887_PRESENT | TDA9887_INTERCARRIER,
+		.tda9887_conf   = TDA9887_PRESENT | TDA9887_INTERCARRIER | TDA9887_PORT2_ACTIVE,
 		.inputs         = {{
 			.name = name_tv,
 			.vmux = 3,
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 4275d2d..23d8747 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -71,6 +71,7 @@
 static unsigned int tuner[]    = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 static unsigned int card[]     = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
 
+
 module_param_array(video_nr, int, NULL, 0444);
 module_param_array(vbi_nr,   int, NULL, 0444);
 module_param_array(radio_nr, int, NULL, 0444);
@@ -88,6 +89,9 @@
 static LIST_HEAD(mops_list);
 static unsigned int saa7134_devcount;
 
+int (*dmasound_init)(struct saa7134_dev *dev);
+int (*dmasound_exit)(struct saa7134_dev *dev);
+
 #define dprintk(fmt, arg...)	if (core_debug) \
 	printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
 
@@ -184,8 +188,7 @@
 /* ----------------------------------------------------------- */
 /* delayed request_module                                      */
 
-#ifdef CONFIG_MODULES
-
+#if defined(CONFIG_MODULES) && defined(MODULE)
 static int need_empress;
 static int need_dvb;
 static int need_alsa;
@@ -234,9 +237,7 @@
 }
 
 #else
-
 #define request_module_depend(name,flag)
-
 #endif /* CONFIG_MODULES */
 
 /* ------------------------------------------------------------------ */
@@ -1017,6 +1018,10 @@
 	/* check for signal */
 	saa7134_irq_video_intl(dev);
 
+	if (dmasound_init && !dev->dmasound.priv_data) {
+		dmasound_init(dev);
+	}
+
 	return 0;
 
  fail4:
@@ -1040,6 +1045,11 @@
 	struct list_head *item;
 	struct saa7134_mpeg_ops *mops;
 
+	/* Release DMA sound modules if present */
+	if (dmasound_exit && dev->dmasound.priv_data) {
+		dmasound_exit(dev);
+	}
+
 	/* debugging ... */
 	if (irq_debug) {
 		u32 report = saa_readl(SAA7134_IRQ_REPORT);
@@ -1071,6 +1081,7 @@
 	saa7134_i2c_unregister(dev);
 	saa7134_unregister_video(dev);
 
+
 	/* the DMA sound modules should be unloaded before reaching
 	   this, but just in case they are still present... */
 	if (dev->dmasound.priv_data != NULL) {
@@ -1078,6 +1089,7 @@
 		dev->dmasound.priv_data = NULL;
 	}
 
+
 	/* release resources */
 	free_irq(pci_dev->irq, dev);
 	iounmap(dev->lmmio);
@@ -1149,10 +1161,10 @@
 
 static void saa7134_fini(void)
 {
-#ifdef CONFIG_MODULES
+#if defined(CONFIG_MODULES) && defined(MODULE)
 	if (pending_registered)
 		unregister_module_notifier(&pending_notifier);
-#endif
+#endif /* CONFIG_MODULES */
 	pci_unregister_driver(&saa7134_pci_driver);
 }
 
@@ -1168,6 +1180,8 @@
 
 /* ----------------- for the DMA sound modules --------------- */
 
+EXPORT_SYMBOL(dmasound_init);
+EXPORT_SYMBOL(dmasound_exit);
 EXPORT_SYMBOL(saa7134_pgtable_free);
 EXPORT_SYMBOL(saa7134_pgtable_build);
 EXPORT_SYMBOL(saa7134_pgtable_alloc);
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index e9ec69e..575f3e8 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -36,6 +36,7 @@
 MODULE_LICENSE("GPL");
 
 static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET };
+
 module_param_array(empress_nr, int, NULL, 0444);
 MODULE_PARM_DESC(empress_nr,"ts device number");
 
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 7575043..1792d03 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -333,7 +333,7 @@
 	struct tuner_setup tun_setup;
 
 	d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
-		 client->driver->name, client->addr, client->name);
+		client->driver->driver.name, client->addr, client->name);
 
 	/* Am I an i2c remote control? */
 
@@ -343,7 +343,7 @@
 		{
 			struct IR_i2c *ir = i2c_get_clientdata(client);
 			d1printk("%s i2c IR detected (%s).\n",
-				 client->driver->name,ir->phys);
+				 client->driver->driver.name, ir->phys);
 			saa7134_set_i2c_ir(dev,ir);
 			break;
 		}
diff --git a/drivers/media/video/saa7134/saa7134-oss.c b/drivers/media/video/saa7134/saa7134-oss.c
index fd9ed11..8badd2a 100644
--- a/drivers/media/video/saa7134/saa7134-oss.c
+++ b/drivers/media/video/saa7134/saa7134-oss.c
@@ -782,36 +782,36 @@
 
 static irqreturn_t saa7134_oss_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
-        struct saa7134_dmasound *dmasound = dev_id;
-        struct saa7134_dev *dev = dmasound->priv_data;
-        unsigned long report, status;
-        int loop, handled = 0;
+	struct saa7134_dmasound *dmasound = dev_id;
+	struct saa7134_dev *dev = dmasound->priv_data;
+	unsigned long report, status;
+	int loop, handled = 0;
 
-        for (loop = 0; loop < 10; loop++) {
-                report = saa_readl(SAA7134_IRQ_REPORT);
-                status = saa_readl(SAA7134_IRQ_STATUS);
+	for (loop = 0; loop < 10; loop++) {
+		report = saa_readl(SAA7134_IRQ_REPORT);
+		status = saa_readl(SAA7134_IRQ_STATUS);
 
-                if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
-                        handled = 1;
-                        saa_writel(SAA7134_IRQ_REPORT,report);
-                        saa7134_irq_oss_done(dev, status);
-                } else {
-                        goto out;
-                }
-        }
+		if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
+			handled = 1;
+			saa_writel(SAA7134_IRQ_REPORT,report);
+			saa7134_irq_oss_done(dev, status);
+		} else {
+			goto out;
+		}
+	}
 
-        if (loop == 10) {
-                dprintk("error! looping IRQ!");
-        }
+	if (loop == 10) {
+		dprintk("error! looping IRQ!");
+	}
 out:
-        return IRQ_RETVAL(handled);
+	return IRQ_RETVAL(handled);
 }
 
 int saa7134_oss_init1(struct saa7134_dev *dev)
 {
 
-        if ((request_irq(dev->pci->irq, saa7134_oss_irq,
-                         SA_SHIRQ | SA_INTERRUPT, dev->name,
+	if ((request_irq(dev->pci->irq, saa7134_oss_irq,
+			 SA_SHIRQ | SA_INTERRUPT, dev->name,
 			(void*) &dev->dmasound)) < 0)
 		return -1;
 
@@ -899,94 +899,120 @@
 	spin_unlock(&dev->slock);
 }
 
-int saa7134_dsp_create(struct saa7134_dev *dev)
+static int saa7134_dsp_create(struct saa7134_dev *dev)
 {
 	int err;
 
-                        err = dev->dmasound.minor_dsp =
-                                register_sound_dsp(&saa7134_dsp_fops,
-                                                   dsp_nr[dev->nr]);
-                        if (err < 0) {
-                                goto fail;
-                        }
-                        printk(KERN_INFO "%s: registered device dsp%d\n",
-                               dev->name,dev->dmasound.minor_dsp >> 4);
+	err = dev->dmasound.minor_dsp =
+		register_sound_dsp(&saa7134_dsp_fops,
+				   dsp_nr[dev->nr]);
+	if (err < 0) {
+		goto fail;
+	}
+	printk(KERN_INFO "%s: registered device dsp%d\n",
+	       dev->name,dev->dmasound.minor_dsp >> 4);
 
-                        err = dev->dmasound.minor_mixer =
-                                register_sound_mixer(&saa7134_mixer_fops,
-                                                     mixer_nr[dev->nr]);
-                        if (err < 0)
-                                goto fail;
-                        printk(KERN_INFO "%s: registered device mixer%d\n",
-                               dev->name,dev->dmasound.minor_mixer >> 4);
+	err = dev->dmasound.minor_mixer =
+		register_sound_mixer(&saa7134_mixer_fops,
+				     mixer_nr[dev->nr]);
+	if (err < 0)
+		goto fail;
+	printk(KERN_INFO "%s: registered device mixer%d\n",
+	       dev->name,dev->dmasound.minor_mixer >> 4);
 
 	return 0;
 
 fail:
-        unregister_sound_dsp(dev->dmasound.minor_dsp);
+	unregister_sound_dsp(dev->dmasound.minor_dsp);
 	return 0;
 
 
 }
 
+static int oss_device_init(struct saa7134_dev *dev)
+{
+	dev->dmasound.priv_data = dev;
+	saa7134_oss_init1(dev);
+	saa7134_dsp_create(dev);
+	return 1;
+}
+
+static int oss_device_exit(struct saa7134_dev *dev)
+{
+
+	unregister_sound_mixer(dev->dmasound.minor_mixer);
+	unregister_sound_dsp(dev->dmasound.minor_dsp);
+
+	saa7134_oss_fini(dev);
+
+	if (dev->pci->irq > 0) {
+		synchronize_irq(dev->pci->irq);
+		free_irq(dev->pci->irq,&dev->dmasound);
+	}
+
+	dev->dmasound.priv_data = NULL;
+	return 1;
+}
+
 static int saa7134_oss_init(void)
 {
-        struct saa7134_dev *dev = NULL;
-        struct list_head *list;
+	struct saa7134_dev *dev = NULL;
+	struct list_head *list;
 
-        printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n");
+	if (!dmasound_init && !dmasound_exit) {
+		dmasound_init = oss_device_init;
+		dmasound_exit = oss_device_exit;
+	} else {
+		printk(KERN_WARNING "saa7134 OSS: can't load, DMA sound handler already assigned (probably to ALSA)\n");
+		return -EBUSY;
+	}
 
-        list_for_each(list,&saa7134_devlist) {
-                dev = list_entry(list, struct saa7134_dev, devlist);
+	printk(KERN_INFO "saa7134 OSS driver for DMA sound loaded\n");
+
+
+	list_for_each(list,&saa7134_devlist) {
+		dev = list_entry(list, struct saa7134_dev, devlist);
 		if (dev->dmasound.priv_data == NULL) {
-			dev->dmasound.priv_data = dev;
-			saa7134_oss_init1(dev);
-			saa7134_dsp_create(dev);
+			oss_device_init(dev);
 		} else {
-                	printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name);
+			printk(KERN_ERR "saa7134 OSS: DMA sound is being handled by ALSA, ignoring %s\n",dev->name);
 			return -EBUSY;
 		}
-        }
+	}
 
-        if (dev == NULL)
-                printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n");
+	if (dev == NULL)
+		printk(KERN_INFO "saa7134 OSS: no saa7134 cards found\n");
 
-        return 0;
+	return 0;
 
 }
 
-void saa7134_oss_exit(void)
+static void saa7134_oss_exit(void)
 {
-        struct saa7134_dev *dev = NULL;
-        struct list_head *list;
+	struct saa7134_dev *dev = NULL;
+	struct list_head *list;
 
-        list_for_each(list,&saa7134_devlist) {
-                dev = list_entry(list, struct saa7134_dev, devlist);
+	list_for_each(list,&saa7134_devlist) {
+		dev = list_entry(list, struct saa7134_dev, devlist);
 
 		/* Device isn't registered by OSS, probably ALSA's */
 		if (!dev->dmasound.minor_dsp)
 			continue;
 
-                unregister_sound_mixer(dev->dmasound.minor_mixer);
-                unregister_sound_dsp(dev->dmasound.minor_dsp);
+		oss_device_exit(dev);
 
-		saa7134_oss_fini(dev);
+	}
 
-		if (dev->pci->irq > 0) {
-			synchronize_irq(dev->pci->irq);
-			free_irq(dev->pci->irq,&dev->dmasound);
-		}
+	dmasound_init = NULL;
+	dmasound_exit = NULL;
 
-        	dev->dmasound.priv_data = NULL;
+	printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n");
 
-        }
-
-        printk(KERN_INFO "saa7134 OSS driver for DMA sound unloaded\n");
-
-        return;
+	return;
 }
 
-module_init(saa7134_oss_init);
+/* We initialize this late, to make sure the sound system is up and running */
+late_initcall(saa7134_oss_init);
 module_exit(saa7134_oss_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 244e197..add49db 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -571,6 +571,10 @@
 
 int saa7134_set_dmabits(struct saa7134_dev *dev);
 
+extern int (*dmasound_init)(struct saa7134_dev *dev);
+extern int (*dmasound_exit)(struct saa7134_dev *dev);
+
+
 /* ----------------------------------------------------------- */
 /* saa7134-cards.c                                             */
 
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
index 132aa79..f72a9f7 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -415,7 +415,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_saa7185;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client)));
 
 	encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL);
@@ -487,11 +486,11 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver i2c_driver_saa7185 = {
-	.owner = THIS_MODULE,
-	.name = "saa7185",	/* name */
+	.driver = {
+		.name = "saa7185",	/* name */
+	},
 
 	.id = I2C_DRIVERID_SAA7185B,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = saa7185_attach_adapter,
 	.detach_client = saa7185_detach_client,
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index cbca896..41f6f05 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -788,10 +788,10 @@
 }
 
 static struct i2c_driver i2c_driver_saa7191 = {
-	.owner		= THIS_MODULE,
-	.name		= "saa7191",
+	.driver = {
+		.name 	= "saa7191",
+	},
 	.id		= I2C_DRIVERID_SAA7191,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter = saa7191_probe,
 	.detach_client	= saa7191_detach,
 	.command	= saa7191_command
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index d32737d..549c992 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -501,10 +501,10 @@
 }
 
 static struct i2c_driver driver = {
-	.owner           = THIS_MODULE,
-	.name            = "i2c tda7432 driver",
+	.driver = {
+		.name    = "i2c tda7432 driver",
+	},
 	.id              = I2C_DRIVERID_TDA7432,
-	.flags           = I2C_DF_NOTIFY,
 	.attach_adapter  = tda7432_probe,
 	.detach_client   = tda7432_detach,
 	.command         = tda7432_command,
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 1794686..ed4c0411 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -34,7 +34,7 @@
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
 #define dprintk(args...) \
-            do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
+            do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0)
 
 #define	SWITCH		0x00
 #define	LEVEL_ADJUST	0x02
@@ -221,10 +221,10 @@
 }
 
 static struct i2c_driver driver = {
-	.owner	= THIS_MODULE,
-	.name	= "tda9840",
+	.driver = {
+		.name	= "tda9840",
+	},
 	.id	= I2C_DRIVERID_TDA9840,
-	.flags	= I2C_DF_NOTIFY,
 	.attach_adapter	= attach,
 	.detach_client	= detach,
 	.command	= command,
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index a5e37dc..9c3ecf7 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -372,10 +372,10 @@
 
 
 static struct i2c_driver driver = {
-	.owner          = THIS_MODULE,
-	.name           = "i2c tda9875 driver",
+	.driver = {
+		.name   = "i2c tda9875 driver",
+	},
 	.id             = I2C_DRIVERID_TDA9875,
-	.flags          = I2C_DF_NOTIFY,
 	.attach_adapter = tda9875_probe,
 	.detach_client  = tda9875_detach,
 	.command        = tda9875_command,
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 4249127..7165a1b 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -12,6 +12,7 @@
 #include <media/audiochip.h>
 #include <media/tuner.h>
 
+
 /* Chips:
    TDA9885 (PAL, NTSC)
    TDA9886 (PAL, SECAM, NTSC)
@@ -818,14 +819,12 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-	.owner          = THIS_MODULE,
-        .name           = "i2c tda9887 driver",
-        .id             = -1, /* FIXME */
-        .flags          = I2C_DF_NOTIFY,
-        .attach_adapter = tda9887_probe,
-        .detach_client  = tda9887_detach,
-        .command        = tda9887_command,
+	.id             = -1, /* FIXME */
+	.attach_adapter = tda9887_probe,
+	.detach_client  = tda9887_detach,
+	.command        = tda9887_command,
 	.driver = {
+		.name    = "i2c tda9887 driver",
 		.suspend = tda9887_suspend,
 		.resume  = tda9887_resume,
 	},
@@ -833,8 +832,7 @@
 static struct i2c_client client_template =
 {
 	.name      = "tda9887",
-	.flags     = I2C_CLIENT_ALLOW_USE,
-        .driver    = &driver,
+	.driver    = &driver,
 };
 
 static int __init tda9887_init_module(void)
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index ee36883..bb35844 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -36,7 +36,7 @@
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
 #define dprintk(args...) \
-            do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
+            do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0)
 
 #define TEA6415C_NUM_INPUTS	8
 #define TEA6415C_NUM_OUTPUTS	6
@@ -190,10 +190,10 @@
 }
 
 static struct i2c_driver driver = {
-	.owner	= THIS_MODULE,
-	.name 	= "tea6415c",
+	.driver = {
+		.name 	= "tea6415c",
+	},
 	.id 	= I2C_DRIVERID_TEA6415C,
-	.flags 	= I2C_DF_NOTIFY,
 	.attach_adapter	= attach,
 	.detach_client	= detach,
 	.command	= command,
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index 17975c1..c4ba374 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -36,7 +36,7 @@
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
 #define dprintk(args...) \
-            do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
+            do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __FUNCTION__, __LINE__); printk(args); } } while (0)
 
 /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */
 static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END };
@@ -167,10 +167,10 @@
 }
 
 static struct i2c_driver driver = {
-	.owner	= THIS_MODULE,
-	.name	= "tea6420",
+	.driver = {
+		.name	= "tea6420",
+	},
 	.id	= I2C_DRIVERID_TEA6420,
-	.flags	= I2C_DF_NOTIFY,
 	.attach_adapter	= attach,
 	.detach_client	= detach,
 	.command	= command,
diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c
index 7920359..d97f668 100644
--- a/drivers/media/video/tuner-3036.c
+++ b/drivers/media/video/tuner-3036.c
@@ -175,10 +175,10 @@
 static struct i2c_driver 
 i2c_driver_tuner = 
 {
-	.owner		=	THIS_MODULE,
-	.name		=	"sab3036",
+	.driver = {
+		.name	=	"sab3036",
+	},
 	.id		=	I2C_DRIVERID_SAB3036,
-        .flags		=	I2C_DF_NOTIFY,
 	.attach_adapter =	tuner_probe,
 	.detach_client  =	tuner_detach,
 	.command	=	tuner_command
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index e58abdf..c13c7b9 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -206,7 +206,7 @@
 
 	set_freq(c, t->freq);
 	tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
-		  c->adapter->name, c->driver->name, c->addr << 1, type,
+		  c->adapter->name, c->driver->driver.name, c->addr << 1, type,
 		  t->mode_mask);
 }
 
@@ -742,21 +742,18 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-	.owner = THIS_MODULE,
-	.name = "tuner",
 	.id = I2C_DRIVERID_TUNER,
-	.flags = I2C_DF_NOTIFY,
 	.attach_adapter = tuner_probe,
 	.detach_client = tuner_detach,
 	.command = tuner_command,
 	.driver = {
+		   .name = "tuner",
 		   .suspend = tuner_suspend,
 		   .resume = tuner_resume,
 		   },
 };
 static struct i2c_client client_template = {
 	.name = "(tuner unset)",
-	.flags = I2C_CLIENT_ALLOW_USE,
 	.driver = &driver,
 };
 
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index c31bf28..0292c5a 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -188,7 +188,7 @@
 		buffer[1] = val;
 		if (2 != i2c_master_send(&chip->c,buffer,2)) {
 			tvaudio_warn("%s: I/O error (write reg%d=0x%x)\n",
-						chip->c.name, subaddr, val);
+			chip->c.name, subaddr, val);
 			return -1;
 		}
 	}
@@ -216,7 +216,7 @@
 		chip->c.name);
 		return -1;
 	}
-	tvaudio_dbg("%s: chip_read: 0x%x\n",chip->c.name,buffer);
+	tvaudio_dbg("%s: chip_read: 0x%x\n",chip->c.name, buffer);
 	return buffer;
 }
 
@@ -235,7 +235,7 @@
 		return -1;
 	}
 	tvaudio_dbg("%s: chip_read2: reg%d=0x%x\n",
-			chip->c.name,subaddr,read[0]);
+		chip->c.name, subaddr,read[0]);
 	return read[0];
 }
 
@@ -248,7 +248,7 @@
 
 	/* update our shadow register set; print bytes if (debug > 0) */
 	tvaudio_dbg("%s: chip_cmd(%s): reg=%d, data:",
-		chip->c.name,name,cmd->bytes[0]);
+		chip->c.name, name,cmd->bytes[0]);
 	for (i = 1; i < cmd->count; i++) {
 		if (debug)
 			printk(" 0x%x",cmd->bytes[i]);
@@ -322,7 +322,7 @@
 	int mode = desc->getmode(chip);
 
 	if (mode == chip->prevmode)
-		return;
+	return;
 
 	tvaudio_dbg("%s: thread checkmode\n", chip->c.name);
 	chip->prevmode = mode;
@@ -1506,18 +1506,18 @@
 		return -EIO;
 	}
 	tvaudio_info("%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name);
-        if (desc->flags) {
-                tvaudio_dbg("matches:%s%s%s.\n",
-                        (desc->flags & CHIP_HAS_VOLUME)     ? " volume"      : "",
-                        (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
-                        (desc->flags & CHIP_HAS_INPUTSEL)   ? " audiomux"    : "");
-        }
+	if (desc->flags) {
+		tvaudio_dbg("matches:%s%s%s.\n",
+			(desc->flags & CHIP_HAS_VOLUME)     ? " volume"      : "",
+			(desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "",
+			(desc->flags & CHIP_HAS_INPUTSEL)   ? " audiomux"    : "");
+	}
 
 	/* fill required data structures */
-	strcpy(chip->c.name,desc->name);
+	strcpy(chip->c.name, desc->name);
 	chip->type = desc-chiplist;
 	chip->shadow.count = desc->registers+1;
-        chip->prevmode = -1;
+	chip->prevmode = -1;
 	/* register */
 	i2c_attach_client(&chip->c);
 
@@ -1604,7 +1604,7 @@
 	struct CHIPSTATE *chip = i2c_get_clientdata(client);
 	struct CHIPDESC  *desc = chiplist + chip->type;
 
-	tvaudio_dbg("%s: chip_command 0x%x\n",chip->c.name,cmd);
+	tvaudio_dbg("%s: chip_command 0x%x\n", chip->c.name, cmd);
 
 	switch (cmd) {
 	case AUDC_SET_INPUT:
@@ -1624,7 +1624,7 @@
 
 	/* --- v4l ioctls --- */
 	/* take care: bttv does userspace copying, we'll get a
-					kernel pointer here... */
+	kernel pointer here... */
 	case VIDIOCGAUDIO:
 	{
 		struct video_audio *va = arg;
@@ -1702,10 +1702,10 @@
 
 
 static struct i2c_driver driver = {
-	.owner           = THIS_MODULE,
-	.name            = "generic i2c audio driver",
+	.driver = {
+		.name    = "generic i2c audio driver",
+	},
 	.id              = I2C_DRIVERID_TVAUDIO,
-	.flags           = I2C_DF_NOTIFY,
 	.attach_adapter  = chip_probe,
 	.detach_client   = chip_detach,
 	.command         = chip_command,
@@ -1714,7 +1714,6 @@
 static struct i2c_client client_template =
 {
 	.name       = "(unset)",
-	.flags      = I2C_CLIENT_ALLOW_USE,
 	.driver     = &driver,
 };
 
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 72e8741..8ac4cb8 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -81,7 +81,7 @@
 	{ 0x00000010, " PAL(I)" },
 	{ 0x00400000, " SECAM(L/L')" },
 	{ 0x00000e00, " PAL(D/K)" },
-	{ 0x03000000, " ATSC Digital" },
+	{ 0x03000000, " ATSC/DVB Digital" },
 };
 
 /* This is the full list of possible tuners. Many thanks to Hauppauge for
@@ -206,16 +206,30 @@
 	{ TUNER_ABSENT,        "TCL 2002MI_3H"},
 	{ TUNER_TCL_2002N,     "TCL 2002N 5H"},
 	/* 100-109 */
-	{ TUNER_ABSENT,        "Philips FMD1216ME"},
+	{ TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216ME"},
 	{ TUNER_TEA5767,       "Philips TEA5768HL FM Radio"},
 	{ TUNER_ABSENT,        "Panasonic ENV57H12D5"},
-	{ TUNER_ABSENT,        "TCL MFNM05-4"},
+	{ TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"},
 	{ TUNER_ABSENT,        "TCL MNM05-4"},
 	{ TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
 	{ TUNER_ABSENT,        "TCL MQNM05-4"},
 	{ TUNER_ABSENT,        "LG TAPC-W701D"},
 	{ TUNER_ABSENT,        "TCL 9886P-WM"},
 	{ TUNER_ABSENT,        "TCL 1676NM-WM"},
+	/* 110-119 */
+	{ TUNER_ABSENT,        "Thompson DTT75105"},
+	{ TUNER_ABSENT,        "Conexant_CX24109"},
+	{ TUNER_ABSENT,        "TCL M2523_5N_E"},
+	{ TUNER_ABSENT,        "TCL M2523_3DB_E"},
+	{ TUNER_ABSENT,        "Philips 8275A"},
+	{ TUNER_ABSENT,        "Microtune MT2060"},
+	{ TUNER_ABSENT,        "Philips FM1236 MK5"},
+	{ TUNER_ABSENT,        "Philips FM1216ME MK5"},
+	{ TUNER_ABSENT,        "TCL M2523_3DI_E"},
+	{ TUNER_ABSENT,        "Samsung THPD5222FG30A"},
+	/* 120-129 */
+	{ TUNER_ABSENT,        "Xceive XC3028"},
+	{ TUNER_ABSENT,        "Philips FQ1216LME MK5"},
 };
 
 static struct HAUPPAUGE_AUDIOIC
@@ -325,6 +339,7 @@
 		case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
 		case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
 		case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
+		case 105:
 		return 1;
 	}
 	return 0;
@@ -368,10 +383,15 @@
 	memset(tvee, 0, sizeof(*tvee));
 	done = len = beenhere = 0;
 
-	/* Hack for processing eeprom for em28xx */
-	if ((eeprom_data[0]==0x1a)&&(eeprom_data[1]==0xeb)&&
-				(eeprom_data[2]==0x67)&&(eeprom_data[3]==0x95))
-		start=0xa0;
+	/* Hack for processing eeprom for em28xx and cx 2388x*/
+	if ((eeprom_data[0] == 0x1a) && (eeprom_data[1] == 0xeb) &&
+			(eeprom_data[2] == 0x67) && (eeprom_data[3] == 0x95))
+		start=0xa0; /* Generic em28xx offset */
+	else if (((eeprom_data[0] & 0xf0) == 0x10) &&
+					(eeprom_data[1] == 0x00) &&
+					(eeprom_data[2] == 0x00) &&
+					(eeprom_data[8] == 0x84))
+		start=8; /* Generic cx2388x offset */
 	else
 		start=0;
 
@@ -448,6 +468,17 @@
 				eeprom_data[i+5] +
 				(eeprom_data[i+6] << 8) +
 				(eeprom_data[i+7] << 16);
+
+				if ( (eeprom_data[i + 8] && 0xf0) &&
+					(tvee->serial_number < 0xffffff) ) {
+					tvee->MAC_address[0] = 0x00;
+					tvee->MAC_address[1] = 0x0D;
+					tvee->MAC_address[2] = 0xFE;
+					tvee->MAC_address[3] = eeprom_data[i + 7];
+					tvee->MAC_address[4] = eeprom_data[i + 6];
+					tvee->MAC_address[5] = eeprom_data[i + 5];
+					tvee->has_MAC_address = 1;
+				}
 			break;
 
 		case 0x05:
@@ -466,11 +497,14 @@
 		case 0x06:
 			/* tag 'ModelRev' */
 			tvee->model =
-				eeprom_data[i+1] +
-				(eeprom_data[i+2] << 8);
-			tvee->revision = eeprom_data[i+5] +
-				(eeprom_data[i+6] << 8) +
-				(eeprom_data[i+7] << 16);
+				eeprom_data[i + 1] +
+				(eeprom_data[i + 2] << 8) +
+				(eeprom_data[i + 3] << 16) +
+				(eeprom_data[i + 4] << 24);
+			tvee->revision =
+				eeprom_data[i +5 ] +
+				(eeprom_data[i + 6] << 8) +
+				(eeprom_data[i + 7] << 16);
 			break;
 
 		case 0x07:
@@ -563,6 +597,8 @@
 		t_name2 = "unknown";
 	}
 
+	tvee->tuner_hauppauge_model = tuner1;
+	tvee->tuner2_hauppauge_model = tuner2;
 	tvee->tuner_formats = 0;
 	tvee->tuner2_formats = 0;
 	for (i = j = 0; i < 8; i++) {
@@ -578,6 +614,12 @@
 
 	tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
 		tvee->model, tvee->rev_str, tvee->serial_number);
+	if (tvee->has_MAC_address == 1) {
+		tveeprom_info("MAC address is %02X-%02X-%02X-%02X-%02X-%02X\n",
+			tvee->MAC_address[0], tvee->MAC_address[1],
+			tvee->MAC_address[2], tvee->MAC_address[3],
+			tvee->MAC_address[4], tvee->MAC_address[5]);
+	}
 	tveeprom_info("tuner model is %s (idx %d, type %d)\n",
 		t_name1, tuner1, tvee->tuner_type);
 	tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
@@ -709,9 +751,9 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver_tveeprom;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	snprintf(client->name, sizeof(client->name), "tveeprom");
-        i2c_attach_client(client);
+	i2c_attach_client(client);
+
 	return 0;
 }
 
@@ -736,10 +778,10 @@
 }
 
 static struct i2c_driver i2c_driver_tveeprom = {
-	.owner          = THIS_MODULE,
-	.name           = "tveeprom",
+	.driver = {
+		.name   = "tveeprom",
+	},
 	.id             = I2C_DRIVERID_TVEEPROM,
-	.flags          = I2C_DF_NOTIFY,
 	.attach_adapter = tveeprom_attach_adapter,
 	.detach_client  = tveeprom_detach_client,
 	.command        = tveeprom_command,
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c
index 8318bd1..e837f9f 100644
--- a/drivers/media/video/tvmixer.c
+++ b/drivers/media/video/tvmixer.c
@@ -228,16 +228,14 @@
 
 static struct i2c_driver driver = {
 #ifdef I2C_PEC
-	.owner           = THIS_MODULE,
-#endif
-	.name            = "tv card mixer driver",
-	.id              = I2C_DRIVERID_TVMIXER,
-#ifdef I2C_DF_DUMMY
-	.flags           = I2C_DF_DUMMY,
+	.driver = {
+		.name    = "tv card mixer driver",
+	},
 #else
-	.flags           = I2C_DF_NOTIFY,
-	.detach_adapter  = tvmixer_adapters,
+	.name            = "tv card mixer driver",
 #endif
+	.id              = I2C_DRIVERID_TVMIXER,
+	.detach_adapter  = tvmixer_adapters,
 	.attach_adapter  = tvmixer_adapters,
 	.detach_client   = tvmixer_clients,
 };
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 81e6d44..a60442e 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -31,7 +31,7 @@
 #define dprintk(num, format, args...) \
 	do { \
 		if (debug >= num) \
-			printk(format , ##args); \
+			printk(format, ##args); \
 	} while (0)
 
 /* supported controls */
@@ -714,7 +714,6 @@
 
 static struct i2c_client client_template = {
 	.name = "(unset)",
-	.flags = I2C_CLIENT_ALLOW_USE,
 	.driver = &driver,
 };
 
@@ -770,7 +769,6 @@
 
 	if (debug > 1)
 		dump_reg(client);
-
 	return 0;
 }
 
@@ -802,12 +800,12 @@
 /* ----------------------------------------------------------------------- */
 
 static struct i2c_driver driver = {
-	.owner = THIS_MODULE,
-	.name = "tvp5150",
+	.driver = {
+		.name = "tvp5150",
+	},
 
 	/* FIXME */
 	.id = I2C_DRIVERID_SAA7110,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = tvp5150_attach_adapter,
 	.detach_client = tvp5150_detach_client,
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 597b8db..62a7d63 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -191,9 +191,7 @@
 };
 
 char *v4l2_ioctl_names[256] = {
-#if __GNUC__ >= 3
 	[0 ... 255]                      = "UNKNOWN",
-#endif
 	[_IOC_NR(VIDIOC_QUERYCAP)]       = "VIDIOC_QUERYCAP",
 	[_IOC_NR(VIDIOC_RESERVED)]       = "VIDIOC_RESERVED",
 	[_IOC_NR(VIDIOC_ENUM_FMT)]       = "VIDIOC_ENUM_FMT",
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c
index 55f129e..0a4004a 100644
--- a/drivers/media/video/video-buf-dvb.c
+++ b/drivers/media/video/video-buf-dvb.c
@@ -13,6 +13,7 @@
  * (at your option) any later version.
  */
 
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
@@ -247,3 +248,4 @@
  * compile-command: "make DVB=1"
  * End:
  */
+
diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c
index acfd3a1..9a6bf28 100644
--- a/drivers/media/video/video-buf.c
+++ b/drivers/media/video/video-buf.c
@@ -753,10 +753,9 @@
 	int retval;
 
 	/* setup stuff */
-	retval = -ENOMEM;
 	q->read_buf = videobuf_alloc(q->msize);
 	if (NULL == q->read_buf)
-		goto done;
+		return -ENOMEM;
 
 	q->read_buf->memory = V4L2_MEMORY_USERPTR;
 	q->read_buf->baddr  = (unsigned long)data;
@@ -817,10 +816,14 @@
 		if (NULL == q->read_buf)
 			goto done;
 		q->read_buf->memory = V4L2_MEMORY_USERPTR;
+		q->read_buf->bsize = count; /* preferred size */
 		field = videobuf_next_field(q);
 		retval = q->ops->buf_prepare(q,q->read_buf,field);
-		if (0 != retval)
+		if (0 != retval) {
+			kfree (q->read_buf);
+			q->read_buf = NULL;
 			goto done;
+		}
 		spin_lock_irqsave(q->irqlock,flags);
 		q->ops->buf_queue(q,q->read_buf);
 		spin_unlock_irqrestore(q->irqlock,flags);
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 83c49f9..6de5b00 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -76,14 +76,14 @@
 }
 
 static struct class video_class = {
-        .name    = VIDEO_NAME,
+	.name    = VIDEO_NAME,
 	.release = video_release,
 };
 
 /*
- *	Active devices 
+ *	Active devices
  */
- 
+
 static struct video_device *video_device[VIDEO_NUM_DEVICES];
 static DECLARE_MUTEX(videodev_lock);
 
@@ -101,7 +101,7 @@
 	int err = 0;
 	struct video_device *vfl;
 	struct file_operations *old_fops;
-	
+
 	if(minor>=VIDEO_NUM_DEVICES)
 		return -ENODEV;
 	down(&videodev_lock);
@@ -189,7 +189,7 @@
 				return -ENOMEM;
 			parg = mbuf;
 		}
-		
+
 		err = -EFAULT;
 		if (_IOC_DIR(cmd) & _IOC_WRITE)
 			if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
@@ -240,7 +240,7 @@
 int video_exclusive_release(struct inode *inode, struct file *file)
 {
 	struct  video_device *vfl = video_devdata(file);
-	
+
 	vfl->users--;
 	return 0;
 }
@@ -253,7 +253,7 @@
  *	@type: type of device to register
  *	@nr:   which device number (0 == /dev/video0, 1 == /dev/video1, ...
  *             -1 == first free)
- *	
+ *
  *	The registration code assigns minor numbers based on the type
  *	requested. -ENFILE is returned in all the device slots for this
  *	category are full. If not then the minor field is set and the
@@ -269,7 +269,7 @@
  *
  *	%VFL_TYPE_VBI - Vertical blank data (undecoded)
  *
- *	%VFL_TYPE_RADIO - A radio card	
+ *	%VFL_TYPE_RADIO - A radio card
  */
 
 int video_register_device(struct video_device *vfd, int type, int nr)
@@ -278,7 +278,7 @@
 	int base;
 	int end;
 	char *name_base;
-	
+
 	switch(type)
 	{
 		case VFL_TYPE_GRABBER:
@@ -293,7 +293,7 @@
 			break;
 		case VFL_TYPE_VBI:
 			base=224;
-			end=240;
+			end=256;
 			name_base = "vbi";
 			break;
 		case VFL_TYPE_RADIO:
@@ -334,7 +334,7 @@
 	init_MUTEX(&vfd->lock);
 
 	/* sysfs class */
-        memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
+	memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
 	if (vfd->dev)
 		vfd->class_dev.dev = vfd->dev;
 	vfd->class_dev.class       = &video_class;
@@ -360,7 +360,7 @@
  *	This unregisters the passed device and deassigns the minor
  *	number. Future open calls will be met with errors.
  */
- 
+
 void video_unregister_device(struct video_device *vfd)
 {
 	down(&videodev_lock);
@@ -384,7 +384,7 @@
 /*
  *	Initialise video for linux
  */
- 
+
 static int __init videodev_init(void)
 {
 	int ret;
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 137b58f..8dcee8b 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -631,7 +631,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &vpx3220_i2c_driver;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 
 	/* Check for manufacture ID and part number */
 	if (kind < 0) {
@@ -722,11 +721,11 @@
  */
 
 static struct i2c_driver vpx3220_i2c_driver = {
-	.owner = THIS_MODULE,
-	.name = "vpx3220",
+	.driver = {
+		.name = "vpx3220",
+	},
 
 	.id = I2C_DRIVERID_VPX3220,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = vpx3220_attach_adapter,
 	.detach_client = vpx3220_detach_client,
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index a6936ad..bbfd55c 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -40,10 +40,10 @@
 MODULE_LICENSE("GPL");
 
 #define wm8775_err(fmt, arg...) do { \
-	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \
 	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 #define wm8775_info(fmt, arg...) do { \
-	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->name, \
+	printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \
 	       i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0)
 
 
@@ -168,7 +168,6 @@
 	client->addr = address;
 	client->adapter = adapter;
 	client->driver = &i2c_driver;
-	client->flags = I2C_CLIENT_ALLOW_USE;
 	snprintf(client->name, sizeof(client->name) - 1, "wm8775");
 
 	wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name);
@@ -233,15 +232,15 @@
 
 /* i2c implementation */
 static struct i2c_driver i2c_driver = {
-	.name = "wm8775",
+	.driver = {
+		.name = "wm8775",
+	},
 
 	.id = I2C_DRIVERID_WM8775,
-	.flags = I2C_DF_NOTIFY,
 
 	.attach_adapter = wm8775_probe,
 	.detach_client = wm8775_detach,
 	.command = wm8775_command,
-	.owner = THIS_MODULE,
 };
 
 
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 07bde9a..4034f1b 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -1311,7 +1311,7 @@
 		res = -ENODEV;
 		goto open_unlock_and_return;
 	}
-	if (!try_module_get(zr->decoder->driver->owner)) {
+	if (!try_module_get(zr->decoder->driver->driver.owner)) {
 		dprintk(1,
 			KERN_ERR
 			"%s: failed to grab ownership of i2c decoder\n",
@@ -1321,13 +1321,13 @@
 		goto open_unlock_and_return;
 	}
 	if (zr->encoder &&
-	    !try_module_get(zr->encoder->driver->owner)) {
+	    !try_module_get(zr->encoder->driver->driver.owner)) {
 		dprintk(1,
 			KERN_ERR
 			"%s: failed to grab ownership of i2c encoder\n",
 			ZR_DEVNAME(zr));
 		res = -EIO;
-		module_put(zr->decoder->driver->owner);
+		module_put(zr->decoder->driver->driver.owner);
 		module_put(THIS_MODULE);
 		goto open_unlock_and_return;
 	}
@@ -1393,9 +1393,9 @@
 open_unlock_and_return:
 	/* if we grabbed locks, release them accordingly */
 	if (have_module_locks) {
-		module_put(zr->decoder->driver->owner);
+		module_put(zr->decoder->driver->driver.owner);
 		if (zr->encoder) {
-			module_put(zr->encoder->driver->owner);
+			module_put(zr->encoder->driver->driver.owner);
 		}
 		module_put(THIS_MODULE);
 	}
@@ -1461,9 +1461,9 @@
 	kfree(fh);
 
 	/* release locks on the i2c modules */
-	module_put(zr->decoder->driver->owner);
+	module_put(zr->decoder->driver->driver.owner);
 	if (zr->encoder) {
-		 module_put(zr->encoder->driver->owner);
+		 module_put(zr->encoder->driver->driver.owner);
 	}
 	module_put(THIS_MODULE);
 
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 7402231..5378360 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -91,9 +91,9 @@
  *  Public data...
  */
 int mpt_lan_index = -1;
-static int mpt_stm_index = -1;
+int mpt_stm_index = -1;
 
-static struct proc_dir_entry *mpt_proc_root_dir;
+struct proc_dir_entry *mpt_proc_root_dir;
 
 #define WHOINIT_UNKNOWN		0xAA
 
@@ -313,13 +313,13 @@
 		u32	 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
 		if (ioc->bus_type == FC)
 			mpt_fc_log_info(ioc, log_info);
-		else if (ioc->bus_type == SCSI)
+		else if (ioc->bus_type == SPI)
 			mpt_sp_log_info(ioc, log_info);
 		else if (ioc->bus_type == SAS)
 			mpt_sas_log_info(ioc, log_info);
 	}
 	if (ioc_stat & MPI_IOCSTATUS_MASK) {
-		if (ioc->bus_type == SCSI &&
+		if (ioc->bus_type == SPI &&
 		    cb_idx != mpt_stm_index &&
 		    cb_idx != mpt_lan_index)
 			mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
@@ -1118,6 +1118,65 @@
 	return -1;
 }
 
+int
+mpt_alt_ioc_wait(MPT_ADAPTER *ioc)
+{
+	int loop_count = 30 * 4;  /* Wait 30 seconds */
+	int status = -1; /* -1 means failed to get board READY */
+
+	do {
+		spin_lock(&ioc->initializing_hba_lock);
+		if (ioc->initializing_hba_lock_flag == 0) {
+			ioc->initializing_hba_lock_flag=1;
+			spin_unlock(&ioc->initializing_hba_lock);
+			status = 0;
+			break;
+		}
+		spin_unlock(&ioc->initializing_hba_lock);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ/4);
+	} while (--loop_count);
+
+	return status;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery
+ *	@ioc: Pointer to MPT adapter structure
+ *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
+ *
+ *	This routine performs all the steps necessary to bring the IOC
+ *	to a OPERATIONAL state.
+ *
+ *      Special Note: This function was added with spin lock's so as to allow
+ *      the dv(domain validation) work thread to succeed on the other channel
+ *      that maybe occuring at the same time when this function is called.
+ *      Without this lock, the dv would fail when message frames were
+ *      requested during hba bringup on the alternate ioc.
+ */
+static int
+mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag)
+{
+	int r;
+
+	if(ioc->alt_ioc) {
+		if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0))
+			return r;
+	}
+
+	r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
+	    CAN_SLEEP);
+
+	if(ioc->alt_ioc) {
+		spin_lock(&ioc->alt_ioc->initializing_hba_lock);
+		ioc->alt_ioc->initializing_hba_lock_flag=0;
+		spin_unlock(&ioc->alt_ioc->initializing_hba_lock);
+	}
+
+return r;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	mpt_attach - Install a PCI intelligent MPT adapter.
@@ -1186,6 +1245,7 @@
 	ioc->pcidev = pdev;
 	ioc->diagPending = 0;
 	spin_lock_init(&ioc->diagLock);
+	spin_lock_init(&ioc->initializing_hba_lock);
 
 	/* Initialize the event logging.
 	 */
@@ -1316,7 +1376,7 @@
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
 		ioc->prod_name = "LSI53C1030";
-		ioc->bus_type = SCSI;
+		ioc->bus_type = SPI;
 		/* 1030 Chip Fix. Disable Split transactions
 		 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
 		 */
@@ -1329,7 +1389,7 @@
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
 		ioc->prod_name = "LSI53C1035";
-		ioc->bus_type = SCSI;
+		ioc->bus_type = SPI;
 	}
 	else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
 		ioc->prod_name = "LSISAS1064";
@@ -1408,8 +1468,7 @@
 	 */
 	mpt_detect_bound_ports(ioc, pdev);
 
-	if ((r = mpt_do_ioc_recovery(ioc,
-	  MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
+	if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){
 		printk(KERN_WARNING MYNAM
 		  ": WARNING - %s did not initialize properly! (%d)\n",
 		  ioc->name, r);
@@ -2983,7 +3042,7 @@
 	/* Clear the internal flash bad bit - autoincrementing register,
 	 * so must do two writes.
 	 */
-	if (ioc->bus_type == SCSI) {
+	if (ioc->bus_type == SPI) {
 		/*
 		 * 1030 and 1035 H/W errata, workaround to access
 		 * the ClearFlashBadSignatureBit
@@ -3093,7 +3152,7 @@
 	int cnt,cntdn;
 
 	dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
-	if (ioc->bus_type == SCSI) {
+	if (ioc->bus_type == SPI) {
 		/* Always issue a Msg Unit Reset first. This will clear some
 		 * SCSI bus hang conditions.
 		 */
@@ -3521,7 +3580,7 @@
 	dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
 		ioc->name, numSGE, num_sge, num_chain));
 
-	if (ioc->bus_type == SCSI)
+	if (ioc->bus_type == SPI)
 		num_chain *= MPT_SCSI_CAN_QUEUE;
 	else
 		num_chain *= MPT_FC_CAN_QUEUE;
@@ -6271,6 +6330,7 @@
 EXPORT_SYMBOL(mpt_suspend);
 #endif
 EXPORT_SYMBOL(ioc_list);
+EXPORT_SYMBOL(mpt_proc_root_dir);
 EXPORT_SYMBOL(mpt_register);
 EXPORT_SYMBOL(mpt_deregister);
 EXPORT_SYMBOL(mpt_event_register);
@@ -6288,6 +6348,7 @@
 EXPORT_SYMBOL(mpt_GetIocState);
 EXPORT_SYMBOL(mpt_print_ioc_summary);
 EXPORT_SYMBOL(mpt_lan_index);
+EXPORT_SYMBOL(mpt_stm_index);
 EXPORT_SYMBOL(mpt_HardResetHandler);
 EXPORT_SYMBOL(mpt_config);
 EXPORT_SYMBOL(mpt_toolbox);
@@ -6296,6 +6357,7 @@
 EXPORT_SYMBOL(mpt_alloc_fw_memory);
 EXPORT_SYMBOL(mpt_free_fw_memory);
 EXPORT_SYMBOL(mptbase_sas_persist_operation);
+EXPORT_SYMBOL(mpt_alt_ioc_wait);
 
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 8ad277a..6c48d1f 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.03.04"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.03.04"
+#define MPT_LINUX_VERSION_COMMON	"3.03.05"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.03.05"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -321,7 +321,7 @@
  *	Dynamic Multi-Pathing specific stuff...
  */
 
-/* VirtDevice negoFlags field */
+/* VirtTarget negoFlags field */
 #define MPT_TARGET_NO_NEGO_WIDE		0x01
 #define MPT_TARGET_NO_NEGO_SYNC		0x02
 #define MPT_TARGET_NO_NEGO_QAS		0x04
@@ -330,8 +330,7 @@
 /*
  *	VirtDevice - FC LUN device or SCSI target device
  */
-typedef struct _VirtDevice {
-	struct scsi_device	*device;
+typedef struct _VirtTarget {
 	u8			 tflags;
 	u8			 ioc_id;
 	u8			 target_id;
@@ -342,21 +341,18 @@
 	u8			 negoFlags;	/* bit field, see above */
 	u8			 raidVolume;	/* set, if RAID Volume */
 	u8			 type;		/* byte 0 of Inquiry data */
-	u8			 cflags;	/* controller flags */
-	u8			 rsvd1raid;
-	u16			 fc_phys_lun;
-	u16			 fc_xlat_lun;
 	u32			 num_luns;
 	u32			 luns[8];		/* Max LUNs is 256 */
-	u8			 pad[4];
 	u8			 inq_data[8];
-		/* IEEE Registered Extended Identifier
-		   obtained via INQUIRY VPD page 0x83 */
-		/* NOTE: Do not separate uniq_prepad and uniq_data
-		   as they are treateed as a single entity in the code */
-	u8			 uniq_prepad[8];
-	u8			 uniq_data[20];
-	u8			 pad2[4];
+} VirtTarget;
+
+typedef struct _VirtDevice {
+	VirtTarget	 	*vtarget;
+	u8			 ioc_id;
+	u8			 bus_id;
+	u8			 target_id;
+	u8			 configured_lun;
+	u32			 lun;
 } VirtDevice;
 
 /*
@@ -611,6 +607,8 @@
 	int			 DoneCtx;
 	int			 TaskCtx;
 	int			 InternalCtx;
+	spinlock_t		 initializing_hba_lock;
+	int 	 		 initializing_hba_lock_flag;
 	struct list_head	 list;
 	struct net_device	*netdev;
 	struct list_head	 sas_topology;
@@ -901,7 +899,7 @@
 
 typedef enum {
 	FC,
-	SCSI,
+	SPI,
 	SAS
 } BUS_TYPE;
 
@@ -910,7 +908,7 @@
 	int			  port;
 	u32			  pad0;
 	struct scsi_cmnd	**ScsiLookup;
-	VirtDevice		**Targets;
+	VirtTarget		**Targets;
 	MPT_LOCAL_REPLY		 *pLocal;		/* used for internal commands */
 	struct timer_list	  timer;
 		/* Pool of memory for holding SCpnts before doing
@@ -1001,13 +999,16 @@
 extern int	 mpt_findImVolumes(MPT_ADAPTER *ioc);
 extern int	 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
 extern int	 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
+extern int	 mpt_alt_ioc_wait(MPT_ADAPTER *ioc);
 
 /*
  *  Public data decl's...
  */
 extern struct list_head	  ioc_list;
+extern struct proc_dir_entry	*mpt_proc_root_dir;
 
 extern int		  mpt_lan_index;	/* needed by mptlan.c */
+extern int		  mpt_stm_index;	/* needed by mptstm.c */
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #endif		/* } __KERNEL__ */
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 602138f..959d2c59 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -1245,7 +1245,7 @@
 	MPT_ADAPTER		*ioc;
 	struct Scsi_Host	*sh;
 	MPT_SCSI_HOST		*hd;
-	VirtDevice		*vdev;
+	VirtTarget		*vdev;
 	char			*pmem;
 	int			*pdata;
 	IOCPage2_t		*pIoc2;
@@ -1822,7 +1822,7 @@
 	case MPI_FUNCTION_SCSI_IO_REQUEST:
 		if (ioc->sh) {
 			SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
-			VirtDevice	*pTarget = NULL;
+			VirtTarget	*pTarget = NULL;
 			MPT_SCSI_HOST	*hd = NULL;
 			int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
 			int scsidir = 0;
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index a628be9..ba61e18 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -84,13 +84,16 @@
 static int	mptfcInternalCtx = -1; /* Used only for internal commands */
 
 static struct scsi_host_template mptfc_driver_template = {
+	.module				= THIS_MODULE,
 	.proc_name			= "mptfc",
 	.proc_info			= mptscsih_proc_info,
 	.name				= "MPT FC Host",
 	.info				= mptscsih_info,
 	.queuecommand			= mptscsih_qcmd,
+	.target_alloc			= mptscsih_target_alloc,
 	.slave_alloc			= mptscsih_slave_alloc,
 	.slave_configure		= mptscsih_slave_configure,
+	.target_destroy			= mptscsih_target_destroy,
 	.slave_destroy			= mptscsih_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_abort_handler		= mptscsih_abort,
@@ -167,13 +170,15 @@
 		printk(MYIOC_s_WARN_FMT
 		  "Skipping because it's not operational!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptfc_probe;
 	}
 
 	if (!ioc->active) {
 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptfc_probe;
 	}
 
 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
@@ -198,7 +203,8 @@
 		printk(MYIOC_s_WARN_FMT
 			"Unable to register controller with SCSI subsystem\n",
 			ioc->name);
-                return -1;
+		error = -1;
+		goto out_mptfc_probe;
         }
 
 	spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -266,7 +272,7 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptfc_probe_failed;
+		goto out_mptfc_probe;
 	}
 
 	memset(mem, 0, sz);
@@ -284,14 +290,14 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptfc_probe_failed;
+		goto out_mptfc_probe;
 	}
 
 	memset(mem, 0, sz);
-	hd->Targets = (VirtDevice **) mem;
+	hd->Targets = (VirtTarget **) mem;
 
 	dprintk((KERN_INFO
-	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+	  "  vdev @ %p, sz=%d\n", hd->Targets, sz));
 
 	/* Clear the TM flags
 	 */
@@ -330,13 +336,13 @@
 	if(error) {
 		dprintk((KERN_ERR MYNAM
 		  "scsi_add_host failed\n"));
-		goto mptfc_probe_failed;
+		goto out_mptfc_probe;
 	}
 
 	scsi_scan_host(sh);
 	return 0;
 
-mptfc_probe_failed:
+out_mptfc_probe:
 
 	mptscsih_remove(pdev);
 	return error;
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index e0a8bb8..17e9757e 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -228,31 +228,35 @@
  * implement ->target_alloc.
  */
 static int
-mptsas_slave_alloc(struct scsi_device *device)
+mptsas_slave_alloc(struct scsi_device *sdev)
 {
-	struct Scsi_Host	*host = device->host;
+	struct Scsi_Host	*host = sdev->host;
 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
 	struct sas_rphy		*rphy;
 	struct mptsas_portinfo	*p;
+	VirtTarget		*vtarget;
 	VirtDevice		*vdev;
-	uint			target = device->id;
+	struct scsi_target 	*starget;
 	int i;
 
-	if ((vdev = hd->Targets[target]) != NULL)
-		goto out;
-
 	vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
 	if (!vdev) {
 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
 				hd->ioc->name, sizeof(VirtDevice));
 		return -ENOMEM;
 	}
-
 	memset(vdev, 0, sizeof(VirtDevice));
-	vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
 	vdev->ioc_id = hd->ioc->id;
+	sdev->hostdata = vdev;
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
+	vdev->vtarget = vtarget;
+	if (vtarget->num_luns == 0) {
+		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
+		hd->Targets[sdev->id] = vtarget;
+	}
 
-	rphy = dev_to_rphy(device->sdev_target->dev.parent);
+	rphy = dev_to_rphy(sdev->sdev_target->dev.parent);
 	list_for_each_entry(p, &hd->ioc->sas_topology, list) {
 		for (i = 0; i < p->num_phys; i++) {
 			if (p->phy_info[i].attached.sas_address ==
@@ -260,7 +264,7 @@
 				vdev->target_id =
 					p->phy_info[i].attached.target;
 				vdev->bus_id = p->phy_info[i].attached.bus;
-				hd->Targets[device->id] = vdev;
+				vdev->lun = sdev->lun;
 				goto out;
 			}
 		}
@@ -271,19 +275,24 @@
 	return -ENODEV;
 
  out:
-	vdev->num_luns++;
-	device->hostdata = vdev;
+	vtarget->ioc_id = vdev->ioc_id;
+	vtarget->target_id = vdev->target_id;
+	vtarget->bus_id = vdev->bus_id;
+	vtarget->num_luns++;
 	return 0;
 }
 
 static struct scsi_host_template mptsas_driver_template = {
+	.module				= THIS_MODULE,
 	.proc_name			= "mptsas",
 	.proc_info			= mptscsih_proc_info,
 	.name				= "MPT SPI Host",
 	.info				= mptscsih_info,
 	.queuecommand			= mptscsih_qcmd,
+	.target_alloc			= mptscsih_target_alloc,
 	.slave_alloc			= mptsas_slave_alloc,
 	.slave_configure		= mptscsih_slave_configure,
+	.target_destroy			= mptscsih_target_destroy,
 	.slave_destroy			= mptscsih_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_abort_handler		= mptscsih_abort,
@@ -986,7 +995,6 @@
 		goto out_free_port_info;
 
 	list_add_tail(&port_info->list, &ioc->sas_topology);
-
 	for (i = 0; i < port_info->num_phys; i++) {
 		mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
 			(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
@@ -1133,13 +1141,15 @@
 		printk(MYIOC_s_WARN_FMT
 		  "Skipping because it's not operational!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptsas_probe;
 	}
 
 	if (!ioc->active) {
 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptsas_probe;
 	}
 
 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
@@ -1163,7 +1173,8 @@
 		printk(MYIOC_s_WARN_FMT
 			"Unable to register controller with SCSI subsystem\n",
 			ioc->name);
-                return -1;
+		error = -1;
+		goto out_mptsas_probe;
         }
 
 	spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -1237,7 +1248,7 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptsas_probe_failed;
+		goto out_mptsas_probe;
 	}
 
 	memset(mem, 0, sz);
@@ -1255,14 +1266,14 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptsas_probe_failed;
+		goto out_mptsas_probe;
 	}
 
 	memset(mem, 0, sz);
-	hd->Targets = (VirtDevice **) mem;
+	hd->Targets = (VirtTarget **) mem;
 
 	dprintk((KERN_INFO
-	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+	  "  vtarget @ %p, sz=%d\n", hd->Targets, sz));
 
 	/* Clear the TM flags
 	 */
@@ -1308,14 +1319,14 @@
 	if (error) {
 		dprintk((KERN_ERR MYNAM
 		  "scsi_add_host failed\n"));
-		goto mptsas_probe_failed;
+		goto out_mptsas_probe;
 	}
 
 	mptsas_scan_sas_topology(ioc);
 
 	return 0;
 
-mptsas_probe_failed:
+out_mptsas_probe:
 
 	mptscsih_remove(pdev);
 	return error;
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 4330ed0..93a16fa 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -150,28 +150,29 @@
 int		mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 int		mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 
-static void	mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
-static void	mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
-static void	mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
+static void	mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen);
+static void	mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56);
 static void	mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
-static void	mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
+static void	mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
 static int	mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
 static int	mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
 int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
-static int	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
+static void	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
+static void	mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
+static int	mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
 
 static struct work_struct   mptscsih_persistTask;
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 static int	mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
 static void	mptscsih_domainValidation(void *hd);
-static int	mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
 static void	mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
 static int	mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
 static void	mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
 static void	mptscsih_fillbuf(char *buffer, int size, int index, int width);
 static void	mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
+static void	mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
 #endif
 
 void 		mptscsih_remove(struct pci_dev *);
@@ -627,7 +628,7 @@
 		dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
 			"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
 			"resid=%d bufflen=%d xfer_cnt=%d\n",
-			ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
+			ioc->id, sc->device->id, sc->device->lun,
 			status, scsi_state, scsi_status, sc->resid,
 			sc->request_bufflen, xfer_cnt));
 
@@ -641,7 +642,7 @@
 		    pScsiReply->ResponseInfo) {
 			printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
 			"FCP_ResponseInfo=%08xh\n",
-			ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
+			ioc->id, sc->device->id, sc->device->lun,
 			le32_to_cpu(pScsiReply->ResponseInfo));
 		}
 
@@ -677,8 +678,8 @@
 			sc->result = DID_RESET << 16;
 
 			/* GEM Workaround. */
-			if (ioc->bus_type == SCSI)
-				mptscsih_no_negotiate(hd, sc->device->id);
+			if (ioc->bus_type == SPI)
+				mptscsih_no_negotiate(hd, sc);
 			break;
 
 		case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:	/* 0x0049 */
@@ -892,16 +893,15 @@
  *		when a lun is disable by mid-layer.
  *		Do NOT access the referenced scsi_cmnd structure or
  *		members. Will cause either a paging or NULL ptr error.
- *	@hd: Pointer to a SCSI HOST structure
- *	@target: target id
- *	@lun: lun
+ *      @hd: Pointer to a SCSI HOST structure
+ *	@vdevice: per device private data
  *
  *	Returns: None.
  *
  *	Called from slave_destroy.
  */
 static void
-mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
+mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
 	SCSIIORequest_t	*mf = NULL;
 	int		 ii;
@@ -909,7 +909,7 @@
 	struct scsi_cmnd *sc;
 
 	dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
-			target, lun, max));
+			vdevice->target_id, vdevice->lun, max));
 
 	for (ii=0; ii < max; ii++) {
 		if ((sc = hd->ScsiLookup[ii]) != NULL) {
@@ -919,7 +919,7 @@
 			dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
 					hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
 
-			if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
+			if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
 				continue;
 
 			/* Cleanup
@@ -993,8 +993,10 @@
 	MPT_ADAPTER 		*ioc = pci_get_drvdata(pdev);
 	struct Scsi_Host 	*host = ioc->sh;
 	MPT_SCSI_HOST		*hd;
+#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 	int 		 	count;
 	unsigned long	 	flags;
+#endif	
 	int sz1;
 
 	if(!host) {
@@ -1075,11 +1077,6 @@
 
 	hd = (MPT_SCSI_HOST *)host->hostdata;
 
-	/* Flush the cache of this adapter
-	 */
-	if(hd != NULL)
-		mptscsih_synchronize_cache(hd, 0);
-
 }
 
 #ifdef CONFIG_PM
@@ -1286,7 +1283,7 @@
 	MPT_SCSI_HOST		*hd;
 	MPT_FRAME_HDR		*mf;
 	SCSIIORequest_t		*pScsiReq;
-	VirtDevice		*pTarget = SCpnt->device->hostdata;
+	VirtDevice		*vdev = SCpnt->device->hostdata;
 	int	 lun;
 	u32	 datalen;
 	u32	 scsictl;
@@ -1341,8 +1338,8 @@
 	/* Default to untagged. Once a target structure has been allocated,
 	 * use the Inquiry data to determine if device supports tagged.
 	 */
-	if (pTarget
-	    && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+	if (vdev
+	    && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
 	    && (SCpnt->device->tagged_supported)) {
 		scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
 	} else {
@@ -1351,8 +1348,8 @@
 
 	/* Use the above information to set up the message frame
 	 */
-	pScsiReq->TargetID = (u8) pTarget->target_id;
-	pScsiReq->Bus = pTarget->bus_id;
+	pScsiReq->TargetID = (u8) vdev->target_id;
+	pScsiReq->Bus = vdev->bus_id;
 	pScsiReq->ChainOffset = 0;
 	pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
 	pScsiReq->CDBLength = SCpnt->cmd_len;
@@ -1403,8 +1400,8 @@
 	SCpnt->host_scribble = NULL;
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
-	if (hd->ioc->bus_type == SCSI) {
-		int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
+	if (hd->ioc->bus_type == SPI) {
+		int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
 		int issueCmd = 1;
 
 		if (dvStatus || hd->ioc->spi_data.forceDv) {
@@ -1437,7 +1434,7 @@
 			/* Set the DV flags.
 			 */
 			if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
-				mptscsih_set_dvflags(hd, pScsiReq);
+				mptscsih_set_dvflags(hd, SCpnt);
 
 			if (!issueCmd)
 				goto fail;
@@ -1741,6 +1738,7 @@
 	u32		 ctx2abort;
 	int		 scpnt_idx;
 	int		 retval;
+	VirtDevice	 *vdev;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
@@ -1790,8 +1788,9 @@
 
 	hd->abortSCpnt = SCpnt;
 
+	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
-		SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
+		vdev->bus_id, vdev->target_id, vdev->lun,
 		ctx2abort, 2 /* 2 second timeout */);
 
 	printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
@@ -1822,6 +1821,7 @@
 {
 	MPT_SCSI_HOST	*hd;
 	int		 retval;
+	VirtDevice	 *vdev;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
@@ -1839,8 +1839,9 @@
 	       hd->ioc->name, SCpnt);
 	scsi_print_command(SCpnt);
 
+	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-		SCpnt->device->channel, SCpnt->device->id,
+		vdev->bus_id, vdev->target_id,
 		0, 0, 5 /* 5 second timeout */);
 
 	printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
@@ -1871,6 +1872,7 @@
 {
 	MPT_SCSI_HOST	*hd;
 	int		 retval;
+	VirtDevice	 *vdev;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
@@ -1888,8 +1890,9 @@
 	if (hd->timeouts < -1)
 		hd->timeouts++;
 
+	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-		SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
+		vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
 
 	printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
 		hd->ioc->name,
@@ -2151,23 +2154,36 @@
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	OS entry point to allow host driver to alloc memory
- *	for each scsi device. Called once per device the bus scan.
+ *	for each scsi target. Called once per device the bus scan.
  *	Return non-zero if allocation fails.
- *	Init memory once per id (not LUN).
  */
 int
-mptscsih_slave_alloc(struct scsi_device *device)
+mptscsih_target_alloc(struct scsi_target *starget)
 {
-	struct Scsi_Host	*host = device->host;
+	VirtTarget		*vtarget;
+
+	vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL);
+	if (!vtarget)
+		return -ENOMEM;
+	memset(vtarget, 0, sizeof(VirtTarget));
+	starget->hostdata = vtarget;
+	return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *	OS entry point to allow host driver to alloc memory
+ *	for each scsi device. Called once per device the bus scan.
+ *	Return non-zero if allocation fails.
+ */
+int
+mptscsih_slave_alloc(struct scsi_device *sdev)
+{
+	struct Scsi_Host	*host = sdev->host;
 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
+	VirtTarget		*vtarget;
 	VirtDevice		*vdev;
-	uint			target = device->id;
-
-	if (hd == NULL)
-		return -ENODEV;
-
-	if ((vdev = hd->Targets[target]) != NULL)
-		goto out;
+	struct scsi_target 	*starget;
 
 	vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
 	if (!vdev) {
@@ -2177,25 +2193,33 @@
 	}
 
 	memset(vdev, 0, sizeof(VirtDevice));
-	vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
 	vdev->ioc_id = hd->ioc->id;
-	vdev->target_id = device->id;
-	vdev->bus_id = device->channel;
-	vdev->raidVolume = 0;
-	hd->Targets[device->id] = vdev;
-	if (hd->ioc->bus_type == SCSI) {
-		if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
-			vdev->raidVolume = 1;
-			ddvtprintk((KERN_INFO
-			    "RAID Volume @ id %d\n", device->id));
-		}
-	} else {
-		vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
-	}
+	vdev->target_id = sdev->id;
+	vdev->bus_id = sdev->channel;
+	vdev->lun = sdev->lun;
+	sdev->hostdata = vdev;
 
- out:
-	vdev->num_luns++;
-	device->hostdata = vdev;
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
+	vdev->vtarget = vtarget;
+
+	if (vtarget->num_luns == 0) {
+		hd->Targets[sdev->id] = vtarget;
+		vtarget->ioc_id = hd->ioc->id;
+		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
+		vtarget->target_id = sdev->id;
+		vtarget->bus_id = sdev->channel;
+		if (hd->ioc->bus_type == SPI) {
+			if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
+				vtarget->raidVolume = 1;
+				ddvtprintk((KERN_INFO
+				    "RAID Volume @ id %d\n", sdev->id));
+			}
+		} else {
+			vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+		}
+	}
+	vtarget->num_luns++;
 	return 0;
 }
 
@@ -2204,40 +2228,52 @@
  *	Called if no device present or device being unloaded
  */
 void
-mptscsih_slave_destroy(struct scsi_device *device)
+mptscsih_target_destroy(struct scsi_target *starget)
 {
-	struct Scsi_Host	*host = device->host;
+	if (starget->hostdata)
+		kfree(starget->hostdata);
+	starget->hostdata = NULL;
+}
+
+/*
+ *	OS entry point to allow for host driver to free allocated memory
+ *	Called if no device present or device being unloaded
+ */
+void
+mptscsih_slave_destroy(struct scsi_device *sdev)
+{
+	struct Scsi_Host	*host = sdev->host;
 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
-	VirtDevice		*vdev;
-	uint			target = device->id;
-	uint			lun = device->lun;
+	VirtTarget		*vtarget;
+	VirtDevice		*vdevice;
+	struct scsi_target 	*starget;
 
-	if (hd == NULL)
-		return;
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
+	vdevice = sdev->hostdata;
 
-	mptscsih_search_running_cmds(hd, target, lun);
-
-	vdev = hd->Targets[target];
-	vdev->luns[0] &= ~(1 << lun);
-	if (--vdev->num_luns)
-		return;
-
-	kfree(hd->Targets[target]);
-	hd->Targets[target] = NULL;
-
-	if (hd->ioc->bus_type == SCSI) {
-		if (mptscsih_is_phys_disk(hd->ioc, target)) {
-			hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
-		} else {
-			hd->ioc->spi_data.dvStatus[target] =
-				MPT_SCSICFG_NEGOTIATE;
-
-			if (!hd->negoNvram) {
-				hd->ioc->spi_data.dvStatus[target] |=
-					MPT_SCSICFG_DV_NOT_DONE;
+	mptscsih_search_running_cmds(hd, vdevice);
+	vtarget->luns[0] &= ~(1 << vdevice->lun);
+	vtarget->num_luns--;
+	if (vtarget->num_luns == 0) {
+		mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
+		if (hd->ioc->bus_type == SPI) {
+			if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
+				hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
+			} else {
+				hd->ioc->spi_data.dvStatus[vtarget->target_id] =
+					MPT_SCSICFG_NEGOTIATE;
+				if (!hd->negoNvram) {
+					hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
+						MPT_SCSICFG_DV_NOT_DONE;
+				}
 			}
 		}
+		hd->Targets[sdev->id] = NULL;
 	}
+	mptscsih_synchronize_cache(hd, vdevice);
+	kfree(vdevice);
+	sdev->hostdata = NULL;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2251,22 +2287,21 @@
 int
 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
 {
-	MPT_SCSI_HOST	*hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
-	VirtDevice *pTarget;
-	int	max_depth;
-	int	tagged;
+	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
+	VirtTarget 		*vtarget;
+	struct scsi_target 	*starget;
+	int			max_depth;
+	int			tagged;
 
-	if (hd == NULL)
-		return 0;
-	if (!(pTarget = hd->Targets[sdev->id]))
-		return 0;
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
 
-	if (hd->ioc->bus_type == SCSI) {
-		if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
-			if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
+	if (hd->ioc->bus_type == SPI) {
+		if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
+			if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
 				max_depth = 1;
-			else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
-			         (pTarget->minSyncFactor <= MPT_ULTRA160 ))
+			else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
+			         (vtarget->minSyncFactor <= MPT_ULTRA160 ))
 				max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
 			else
 				max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
@@ -2295,64 +2330,58 @@
  *	Return non-zero if fails.
  */
 int
-mptscsih_slave_configure(struct scsi_device *device)
+mptscsih_slave_configure(struct scsi_device *sdev)
 {
-	struct Scsi_Host	*sh = device->host;
-	VirtDevice		*pTarget;
+	struct Scsi_Host	*sh = sdev->host;
+	VirtTarget		*vtarget;
+	VirtDevice		*vdevice;
+	struct scsi_target 	*starget;
 	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)sh->hostdata;
+	int			indexed_lun, lun_index;
 
-	if ((hd == NULL) || (hd->Targets == NULL)) {
-		return 0;
-	}
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
+	vdevice = sdev->hostdata;
 
 	dsprintk((MYIOC_s_INFO_FMT
 		"device @ %p, id=%d, LUN=%d, channel=%d\n",
-		hd->ioc->name, device, device->id, device->lun, device->channel));
-	dsprintk((MYIOC_s_INFO_FMT
-		"sdtr %d wdtr %d ppr %d inq length=%d\n",
-		hd->ioc->name, device->sdtr, device->wdtr,
-		device->ppr, device->inquiry_len));
+		hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
+	if (hd->ioc->bus_type == SPI)
+		dsprintk((MYIOC_s_INFO_FMT
+		    "sdtr %d wdtr %d ppr %d inq length=%d\n",
+		    hd->ioc->name, sdev->sdtr, sdev->wdtr,
+		    sdev->ppr, sdev->inquiry_len));
 
-	if (device->id > sh->max_id) {
+	if (sdev->id > sh->max_id) {
 		/* error case, should never happen */
-		scsi_adjust_queue_depth(device, 0, 1);
+		scsi_adjust_queue_depth(sdev, 0, 1);
 		goto slave_configure_exit;
 	}
 
-	pTarget = hd->Targets[device->id];
-
-	if (pTarget == NULL) {
-		/* Driver doesn't know about this device.
-		 * Kernel may generate a "Dummy Lun 0" which
-		 * may become a real Lun if a
-		 * "scsi add-single-device" command is executed
-		 * while the driver is active (hot-plug a
-		 * device).  LSI Raid controllers need
-		 * queue_depth set to DEV_HIGH for this reason.
-		 */
-		scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
-			MPT_SCSI_CMD_PER_DEV_HIGH);
-		goto slave_configure_exit;
-	}
-
-	mptscsih_initTarget(hd, device->channel, device->id, device->lun,
-		device->inquiry, device->inquiry_len );
-	mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH);
+	vdevice->configured_lun=1;
+	lun_index = (vdevice->lun >> 5);  /* 32 luns per lun_index */
+	indexed_lun = (vdevice->lun % 32);
+	vtarget->luns[lun_index] |= (1 << indexed_lun);
+	mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
+	    sdev->inquiry_len );
+	mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
 
 	dsprintk((MYIOC_s_INFO_FMT
 		"Queue depth=%d, tflags=%x\n",
-		hd->ioc->name, device->queue_depth, pTarget->tflags));
+		hd->ioc->name, sdev->queue_depth, vtarget->tflags));
 
-	dsprintk((MYIOC_s_INFO_FMT
-		"negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
-		hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
+	if (hd->ioc->bus_type == SPI)
+		dsprintk((MYIOC_s_INFO_FMT
+		    "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
+		    hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
+		    vtarget->minSyncFactor));
 
 slave_configure_exit:
 
 	dsprintk((MYIOC_s_INFO_FMT
 		"tagged %d, simple %d, ordered %d\n",
-		hd->ioc->name,device->tagged_supported, device->simple_tags,
-		device->ordered_tags));
+		hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
+		sdev->ordered_tags));
 
 	return 0;
 }
@@ -2370,16 +2399,14 @@
 static void
 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
 {
-	VirtDevice	*target;
+	VirtDevice	*vdev;
 	SCSIIORequest_t	*pReq;
 	u32		 sense_count = le32_to_cpu(pScsiReply->SenseCount);
-	int		 index;
 
 	/* Get target structure
 	 */
 	pReq = (SCSIIORequest_t *) mf;
-	index = (int) pReq->TargetID;
-	target = hd->Targets[index];
+	vdev = sc->device->hostdata;
 
 	if (sense_count) {
 		u8 *sense_data;
@@ -2393,7 +2420,7 @@
 		/* Log SMART data (asc = 0x5D, non-IM case only) if required.
 		 */
 		if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
-			if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
+			if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
 				int idx;
 				MPT_ADAPTER *ioc = hd->ioc;
 
@@ -2403,7 +2430,7 @@
 
 				ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
 					(MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
-					(pReq->Bus << 8) || pReq->TargetID;
+					(sc->device->channel << 8) || sc->device->id;
 
 				ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
 
@@ -2503,9 +2530,9 @@
 		/* 2. Chain Buffer initialization
 		 */
 
-		/* 4. Renegotiate to all devices, if SCSI
+		/* 4. Renegotiate to all devices, if SPI
 		 */
-		if (ioc->bus_type == SCSI) {
+		if (ioc->bus_type == SPI) {
 			dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
 			mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
 		}
@@ -2534,7 +2561,7 @@
 
 		/* 7. Set flag to force DV and re-read IOC Page 3
 		 */
-		if (ioc->bus_type == SCSI) {
+		if (ioc->bus_type == SPI) {
 			ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
 			ddvtprintk(("Set reload IOC Pg3 Flag\n"));
 		}
@@ -2576,7 +2603,7 @@
 		break;
 	case MPI_EVENT_IOC_BUS_RESET:			/* 04 */
 	case MPI_EVENT_EXT_BUS_RESET:			/* 05 */
-		if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
+		if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
 			hd->soft_resets++;
 		break;
 	case MPI_EVENT_LOGOUT:				/* 09 */
@@ -2597,11 +2624,11 @@
 
 	case MPI_EVENT_INTEGRATED_RAID:			/* 0B */
 	{
+#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 		pMpiEventDataRaid_t pRaidEventData =
 		    (pMpiEventDataRaid_t) pEvReply->Data;
-#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 		/* Domain Validation Needed */
-		if (ioc->bus_type == SCSI &&
+		if (ioc->bus_type == SPI &&
 		    pRaidEventData->ReasonCode ==
 		    MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
 			mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
@@ -2632,8 +2659,7 @@
 /*
  *	mptscsih_initTarget - Target, LUN alloc/free functionality.
  *	@hd: Pointer to MPT_SCSI_HOST structure
- *	@bus_id: Bus number (?)
- *	@target_id: SCSI target id
+ *	@vtarget: per target private data
  *	@lun: SCSI LUN id
  *	@data: Pointer to data
  *	@dlen: Number of INQUIRY bytes
@@ -2646,15 +2672,14 @@
  *
  */
 static void
-mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
+mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
 {
-	int		indexed_lun, lun_index;
-	VirtDevice	*vdev;
 	SpiCfgData	*pSpi;
 	char		data_56;
+	int		inq_len;
 
 	dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
-			hd->ioc->name, bus_id, target_id, lun, hd));
+		hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
 
 	/*
 	 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
@@ -2674,75 +2699,68 @@
 	if (data[0] & 0xe0)
 		return;
 
-	if ((vdev = hd->Targets[target_id]) == NULL) {
+	if (vtarget == NULL)
 		return;
-	}
 
-	lun_index = (lun >> 5);  /* 32 luns per lun_index */
-	indexed_lun = (lun % 32);
-	vdev->luns[lun_index] |= (1 << indexed_lun);
+	if (data)
+		vtarget->type = data[0];
 
-	if (hd->ioc->bus_type == SCSI) {
-		if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
-			/* Treat all Processors as SAF-TE if
-			 * command line option is set */
-			vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
-			mptscsih_writeIOCPage4(hd, target_id, bus_id);
-		}else if ((data[0] == TYPE_PROCESSOR) &&
-			!(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
-			if ( dlen > 49 ) {
-				vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
-				if ( data[44] == 'S' &&
-				     data[45] == 'A' &&
-				     data[46] == 'F' &&
-				     data[47] == '-' &&
-				     data[48] == 'T' &&
-				     data[49] == 'E' ) {
-					vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
-					mptscsih_writeIOCPage4(hd, target_id, bus_id);
-				}
+	if (hd->ioc->bus_type != SPI)
+		return;
+
+	if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
+		/* Treat all Processors as SAF-TE if
+		 * command line option is set */
+		vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+		mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
+	}else if ((data[0] == TYPE_PROCESSOR) &&
+		!(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
+		if ( dlen > 49 ) {
+			vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
+			if ( data[44] == 'S' &&
+			     data[45] == 'A' &&
+			     data[46] == 'F' &&
+			     data[47] == '-' &&
+			     data[48] == 'T' &&
+			     data[49] == 'E' ) {
+				vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
+				mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
 			}
 		}
-		if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
-			if ( dlen > 8 ) {
-				memcpy (vdev->inq_data, data, 8);
-			} else {
-				memcpy (vdev->inq_data, data, dlen);
-			}
+	}
+	if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
+		inq_len = dlen < 8 ? dlen : 8;
+		memcpy (vtarget->inq_data, data, inq_len);
+		/* If have not done DV, set the DV flag.
+		 */
+		pSpi = &hd->ioc->spi_data;
+		if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
+			if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
+				pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
+		}
+		vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
 
-			/* If have not done DV, set the DV flag.
+		data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
+		if (dlen > 56) {
+			if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
+			/* Update the target capabilities
 			 */
-			pSpi = &hd->ioc->spi_data;
-			if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
-				if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
-					pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
+				data_56 = data[56];
+				vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
 			}
-
-			vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
-
-
-			data_56 = 0x0F;  /* Default to full capabilities if Inq data length is < 57 */
-			if (dlen > 56) {
-				if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
-				/* Update the target capabilities
-				 */
-					data_56 = data[56];
-					vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
-				}
-			}
-			mptscsih_setTargetNegoParms(hd, vdev, data_56);
-		} else {
-			/* Initial Inquiry may not request enough data bytes to
-			 * obtain byte 57.  DV will; if target doesn't return
-			 * at least 57 bytes, data[56] will be zero. */
-			if (dlen > 56) {
-				if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
-				/* Update the target capabilities
-				 */
-					data_56 = data[56];
-					vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
-					mptscsih_setTargetNegoParms(hd, vdev, data_56);
-				}
+		}
+		mptscsih_setTargetNegoParms(hd, vtarget, data_56);
+	} else {
+		/* Initial Inquiry may not request enough data bytes to
+		 * obtain byte 57.  DV will; if target doesn't return
+		 * at least 57 bytes, data[56] will be zero. */
+		if (dlen > 56) {
+			if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
+			/* Update the target capabilities
+			 */
+				data_56 = data[56];
+				vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
+				mptscsih_setTargetNegoParms(hd, vtarget, data_56);
 			}
 		}
 	}
@@ -2755,12 +2773,12 @@
  *
  */
 static void
-mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
+mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
 {
 	SpiCfgData *pspi_data = &hd->ioc->spi_data;
 	int  id = (int) target->target_id;
 	int  nvram;
-	VirtDevice	*vdev;
+	VirtTarget	*vtarget;
 	int ii;
 	u8 width = MPT_NARROW;
 	u8 factor = MPT_ASYNC;
@@ -2905,9 +2923,9 @@
 
 			ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
 			for (ii = 0; ii < id; ii++) {
-				if ( (vdev = hd->Targets[ii]) ) {
-					vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
-					mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
+				if ( (vtarget = hd->Targets[ii]) ) {
+					vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+					mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
 				}
 			}
 		}
@@ -2926,105 +2944,17 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
- * Else set the NEED_DV flag after Read Capacity Issued (disks)
- * or Mode Sense (cdroms).
- *
- * Tapes, initTarget will set this flag on completion of Inquiry command.
- * Called only if DV_NOT_DONE flag is set
- */
-static void
-mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
-{
-	MPT_ADAPTER	*ioc = hd->ioc;
-	u8 cmd;
-	SpiCfgData	*pSpi;
-
-	ddvtprintk((MYIOC_s_NOTE_FMT
-		" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
-		hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
-
-	if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
-		return;
-
-	cmd = pReq->CDB[0];
-
-	if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
-		pSpi = &ioc->spi_data;
-		if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
-			/* Set NEED_DV for all hidden disks
-			 */
-			Ioc3PhysDisk_t *pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
-			int		numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
-
-			while (numPDisk) {
-				pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
-				ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
-				pPDisk++;
-				numPDisk--;
-			}
-		}
-		pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
-		ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
-	}
-}
-
-/* mptscsih_raid_set_dv_flags()
- *
- * New or replaced disk. Set DV flag and schedule DV.
- */
-static void
-mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
-{
-	MPT_ADAPTER	*ioc = hd->ioc;
-	SpiCfgData	*pSpi = &ioc->spi_data;
-	Ioc3PhysDisk_t	*pPDisk;
-	int		 numPDisk;
-
-	if (hd->negoNvram != 0)
-		return;
-
-	ddvtprintk(("DV requested for phys disk id %d\n", id));
-	if (ioc->raid_data.pIocPg3) {
-		pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
-		numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
-		while (numPDisk) {
-			if (id == pPDisk->PhysDiskNum) {
-				pSpi->dvStatus[pPDisk->PhysDiskID] =
-				    (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
-				pSpi->forceDv = MPT_SCSICFG_NEED_DV;
-				ddvtprintk(("NEED_DV set for phys disk id %d\n",
-				    pPDisk->PhysDiskID));
-				break;
-			}
-			pPDisk++;
-			numPDisk--;
-		}
-
-		if (numPDisk == 0) {
-			/* The physical disk that needs DV was not found
-			 * in the stored IOC Page 3. The driver must reload
-			 * this page. DV routine will set the NEED_DV flag for
-			 * all phys disks that have DV_NOT_DONE set.
-			 */
-			pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
-			ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
-		}
-	}
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * If no Target, bus reset on 1st I/O. Set the flag to
  * prevent any future negotiations to this device.
  */
 static void
-mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
+mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
 {
+	VirtDevice	*vdev;
 
-	if ((hd->Targets) && (hd->Targets[target_id] == NULL))
-		hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
-
+	if ((vdev = sc->device->hostdata) != NULL)
+		hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
 	return;
 }
 
@@ -3100,7 +3030,7 @@
 	MPT_ADAPTER		*ioc = hd->ioc;
 	Config_t		*pReq;
 	SCSIDevicePage1_t	*pData;
-	VirtDevice		*pTarget=NULL;
+	VirtTarget		*vtarget=NULL;
 	MPT_FRAME_HDR		*mf;
 	dma_addr_t		 dataDma;
 	u16			 req_idx;
@@ -3180,11 +3110,11 @@
 		/* If id is not a raid volume, get the updated
 		 * transmission settings from the target structure.
 		 */
-		if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
-			width = pTarget->maxWidth;
-			factor = pTarget->minSyncFactor;
-			offset = pTarget->maxOffset;
-			negoFlags = pTarget->negoFlags;
+		if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
+			width = vtarget->maxWidth;
+			factor = vtarget->minSyncFactor;
+			offset = vtarget->maxOffset;
+			negoFlags = vtarget->negoFlags;
 		}
 
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
@@ -3904,36 +3834,104 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
- *	@hd: Pointer to MPT_SCSI_HOST structure
- *	@portnum: IOC port number
+ *	mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
+ *	@hd: Pointer to a SCSI HOST structure
+ *	@vtarget: per device private data
  *
  *	Uses the ISR, but with special processing.
  *	MUST be single-threaded.
  *
- *	Return: 0 on completion
  */
-static int
-mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
+static void
+mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
 {
 	MPT_ADAPTER		*ioc= hd->ioc;
-	VirtDevice		*pTarget;
-	SCSIDevicePage1_t	*pcfg1Data = NULL;
-	INTERNAL_CMD		 iocmd;
+	SCSIDevicePage1_t	*pcfg1Data;
 	CONFIGPARMS		 cfg;
-	dma_addr_t		 cfg1_dma_addr = -1;
-	ConfigPageHeader_t	 header1;
-	int			 bus = 0;
-	int			 id = 0;
-	int			 lun;
-	int			 indexed_lun, lun_index;
-	int			 hostId = ioc->pfacts[portnum].PortSCSIID;
-	int			 max_id;
-	int			 requested, configuration, data;
-	int			 doConfig = 0;
+	dma_addr_t		 cfg1_dma_addr;
+	ConfigPageHeader_t	 header;
+	int			 id;
+	int			 requested, configuration, data,i;
 	u8			 flags, factor;
 
-	max_id = ioc->sh->max_id - 1;
+	if (ioc->bus_type != SPI)
+		return;
+
+	if (!ioc->spi_data.sdp1length)
+		return;
+
+	pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
+		 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
+
+	if (pcfg1Data == NULL)
+		return;
+
+	header.PageVersion = ioc->spi_data.sdp1version;
+	header.PageLength = ioc->spi_data.sdp1length;
+	header.PageNumber = 1;
+	header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
+	cfg.cfghdr.hdr = &header;
+	cfg.physAddr = cfg1_dma_addr;
+	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
+	cfg.dir = 1;
+	cfg.timeout = 0;
+
+	if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
+		for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+			id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
+			flags = hd->ioc->spi_data.noQas;
+			if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
+				data = hd->ioc->spi_data.nvram[id];
+				if (data & MPT_NVRAM_WIDE_DISABLE)
+					flags |= MPT_TARGET_NO_NEGO_WIDE;
+				factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
+				if ((factor == 0) || (factor == MPT_ASYNC))
+					flags |= MPT_TARGET_NO_NEGO_SYNC;
+			}
+			mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
+				&configuration, flags);
+			dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
+				"offset=0 negoFlags=%x request=%x config=%x\n",
+				id, flags, requested, configuration));
+			pcfg1Data->RequestedParameters = cpu_to_le32(requested);
+			pcfg1Data->Reserved = 0;
+			pcfg1Data->Configuration = cpu_to_le32(configuration);
+			cfg.pageAddr = (vtarget->bus_id<<8) | id;
+			mpt_config(hd->ioc, &cfg);
+		}
+	} else {
+		flags = vtarget->negoFlags;
+		mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
+				&configuration, flags);
+		dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
+			"offset=0 negoFlags=%x request=%x config=%x\n",
+			vtarget->target_id, flags, requested, configuration));
+		pcfg1Data->RequestedParameters = cpu_to_le32(requested);
+		pcfg1Data->Reserved = 0;
+		pcfg1Data->Configuration = cpu_to_le32(configuration);
+		cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
+		mpt_config(hd->ioc, &cfg);
+	}
+
+	if (pcfg1Data)
+		pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
+ *	@hd: Pointer to a SCSI HOST structure
+ *	@vtarget: per device private data
+ *	@lun: lun
+ *
+ *	Uses the ISR, but with special processing.
+ *	MUST be single-threaded.
+ *
+ */
+static void
+mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
+{
+	INTERNAL_CMD		 iocmd;
 
 	/* Following parameters will not change
 	 * in this routine.
@@ -3945,108 +3943,30 @@
 	iocmd.data_dma = -1;
 	iocmd.size = 0;
 	iocmd.rsvd = iocmd.rsvd2 = 0;
+	iocmd.bus = vdevice->bus_id;
+	iocmd.id = vdevice->target_id;
+	iocmd.lun = (u8)vdevice->lun;
 
-	/* No SCSI hosts
-	 */
-	if (hd->Targets == NULL)
+	if ((vdevice->vtarget->type & TYPE_DISK) &&
+	    (vdevice->configured_lun))
+		mptscsih_do_cmd(hd, &iocmd);
+}
+
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+/* Search IOC page 3 to determine if this is hidden physical disk
+ */
+static int
+mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
+{
+	int i;
+
+	if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
 		return 0;
 
-	/* Skip the host
-	 */
-	if (id == hostId)
-		id++;
-
-	/* Write SDP1 for all SCSI devices
-	 * Alloc memory and set up config buffer
-	 */
-	if (ioc->bus_type == SCSI) {
-		if (ioc->spi_data.sdp1length > 0) {
-			pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
-					 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
-
-			if (pcfg1Data != NULL) {
-				doConfig = 1;
-				header1.PageVersion = ioc->spi_data.sdp1version;
-				header1.PageLength = ioc->spi_data.sdp1length;
-				header1.PageNumber = 1;
-				header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
-				cfg.cfghdr.hdr = &header1;
-				cfg.physAddr = cfg1_dma_addr;
-				cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
-				cfg.dir = 1;
-				cfg.timeout = 0;
-			}
-		}
-	}
-
-	/* loop through all devices on this port
-	 */
-	while (bus < MPT_MAX_BUS) {
-		iocmd.bus = bus;
-		iocmd.id = id;
-		pTarget = hd->Targets[(int)id];
-
-		if (doConfig) {
-
-			/* Set the negotiation flags */
-			if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
-				flags = pTarget->negoFlags;
-			} else {
-				flags = hd->ioc->spi_data.noQas;
-				if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
-					data = hd->ioc->spi_data.nvram[id];
-
-					if (data & MPT_NVRAM_WIDE_DISABLE)
-						flags |= MPT_TARGET_NO_NEGO_WIDE;
-
-					factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
-					if ((factor == 0) || (factor == MPT_ASYNC))
-						flags |= MPT_TARGET_NO_NEGO_SYNC;
-				}
-			}
-
-			/* Force to async, narrow */
-			mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
-					&configuration, flags);
-			dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
-				"offset=0 negoFlags=%x request=%x config=%x\n",
-				id, flags, requested, configuration));
-			pcfg1Data->RequestedParameters = cpu_to_le32(requested);
-			pcfg1Data->Reserved = 0;
-			pcfg1Data->Configuration = cpu_to_le32(configuration);
-			cfg.pageAddr = (bus<<8) | id;
-			mpt_config(hd->ioc, &cfg);
-		}
-
-		/* If target Ptr NULL or if this target is NOT a disk, skip.
-		 */
-		if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
-			for (lun=0; lun <= MPT_LAST_LUN; lun++) {
-				/* If LUN present, issue the command
-				 */
-				lun_index = (lun >> 5);  /* 32 luns per lun_index */
-				indexed_lun = (lun % 32);
-				if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
-					iocmd.lun = lun;
-					(void) mptscsih_do_cmd(hd, &iocmd);
-				}
-			}
-		}
-
-		/* get next relevant device */
-		id++;
-
-		if (id == hostId)
-			id++;
-
-		if (id > max_id) {
-			id = 0;
-			bus++;
-		}
-	}
-
-	if (pcfg1Data) {
-		pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
+	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
+		if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
+			return 1;
 	}
 
 	return 0;
@@ -4101,8 +4021,8 @@
 
 			msleep(250);
 
-			/* DV only to SCSI adapters */
-			if (ioc->bus_type != SCSI)
+			/* DV only to SPI adapters */
+			if (ioc->bus_type != SPI)
 				continue;
 
 			/* Make sure everything looks ok */
@@ -4162,6 +4082,12 @@
 						}
 					}
 
+					if(mpt_alt_ioc_wait(hd->ioc)!=0) {
+						ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n",
+						    hd->ioc->name));
+						continue;
+					}
+
 					if (mptscsih_doDv(hd, 0, id) == 1) {
 						/* Untagged device was busy, try again
 						 */
@@ -4173,6 +4099,10 @@
 						hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
 					}
 
+					spin_lock(&hd->ioc->initializing_hba_lock);
+					hd->ioc->initializing_hba_lock_flag=0;
+					spin_unlock(&hd->ioc->initializing_hba_lock);
+
 					if (isPhysDisk) {
 						for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
 							if (hd->ioc->raid_data.isRaid & (1 << ii)) {
@@ -4195,32 +4125,12 @@
 	return;
 }
 
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-static int
-mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
-{
-	int i;
-
-	if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
-		return 0;
-
-	for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
-		if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
-			return 1;
-	}
-
-	return 0;
-}
-
 /* Write SDP1 if no QAS has been enabled
  */
 static void
 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
 {
-	VirtDevice *pTarget;
+	VirtTarget *vtarget;
 	int ii;
 
 	if (hd->Targets == NULL)
@@ -4233,11 +4143,11 @@
 		if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
 			continue;
 
-		pTarget = hd->Targets[ii];
+		vtarget = hd->Targets[ii];
 
-		if ((pTarget != NULL) && (!pTarget->raidVolume)) {
-			if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
-				pTarget->negoFlags |= hd->ioc->spi_data.noQas;
+		if ((vtarget != NULL) && (!vtarget->raidVolume)) {
+			if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
+				vtarget->negoFlags |= hd->ioc->spi_data.noQas;
 				dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
 				mptscsih_writeSDP1(hd, 0, ii, 0);
 			}
@@ -4277,7 +4187,7 @@
 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
 {
 	MPT_ADAPTER		*ioc = hd->ioc;
-	VirtDevice		*pTarget;
+	VirtTarget		*vtarget;
 	SCSIDevicePage1_t	*pcfg1Data;
 	SCSIDevicePage0_t	*pcfg0Data;
 	u8			*pbuf1;
@@ -4348,12 +4258,12 @@
 	iocmd.physDiskNum = -1;
 	iocmd.rsvd = iocmd.rsvd2 = 0;
 
-	pTarget = hd->Targets[id];
+	vtarget = hd->Targets[id];
 
 	/* Use tagged commands if possible.
 	 */
-	if (pTarget) {
-		if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
+	if (vtarget) {
+		if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
 			iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
 		else {
 			if (hd->ioc->facts.FWVersion.Word < 0x01000600)
@@ -4569,7 +4479,7 @@
 		/* Reset the size for disks
 		 */
 		inq0 = (*pbuf1) & 0x1F;
-		if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
+		if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
 			sz = 0x40;
 			iocmd.size = sz;
 		}
@@ -4579,8 +4489,7 @@
 		 */
 		if (inq0 == TYPE_PROCESSOR) {
 			mptscsih_initTarget(hd,
-				bus,
-				id,
+				vtarget,
 				lun,
 				pbuf1,
 				sz);
@@ -4594,22 +4503,22 @@
 			goto target_done;
 
 		if (sz == 0x40) {
-			if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
-				&& (pTarget->minSyncFactor > 0x09)) {
+			if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
+				&& (vtarget->minSyncFactor > 0x09)) {
 				if ((pbuf1[56] & 0x04) == 0)
 					;
 				else if ((pbuf1[56] & 0x01) == 1) {
-					pTarget->minSyncFactor =
+					vtarget->minSyncFactor =
 					    nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
 				} else {
-					pTarget->minSyncFactor =
+					vtarget->minSyncFactor =
 					    nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
 				}
 
-				dv.max.factor = pTarget->minSyncFactor;
+				dv.max.factor = vtarget->minSyncFactor;
 
 				if ((pbuf1[56] & 0x02) == 0) {
-					pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
+					vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
 					hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
 					ddvprintk((MYIOC_s_NOTE_FMT
 					    "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
@@ -4692,8 +4601,7 @@
 						    "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
 						hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
 						mptscsih_initTarget(hd,
-							bus,
-							id,
+							vtarget,
 							lun,
 							pbuf1,
 							sz);
@@ -5194,7 +5102,7 @@
 static void
 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
 {
-	VirtDevice		*pTarget;
+	VirtTarget		*vtarget;
 	SCSIDevicePage0_t	*pPage0;
 	SCSIDevicePage1_t	*pPage1;
 	int			val = 0, data, configuration;
@@ -5214,11 +5122,11 @@
 		 * already throttled back.
 		 */
 		negoFlags = hd->ioc->spi_data.noQas;
-		if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
-			width = pTarget->maxWidth;
-			offset = pTarget->maxOffset;
-			factor = pTarget->minSyncFactor;
-			negoFlags |= pTarget->negoFlags;
+		if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
+			width = vtarget->maxWidth;
+			offset = vtarget->maxOffset;
+			factor = vtarget->minSyncFactor;
+			negoFlags |= vtarget->negoFlags;
 		} else {
 			if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
 				data = hd->ioc->spi_data.nvram[id];
@@ -5420,11 +5328,11 @@
 		 * or overwrite nvram (phys disks only).
 		 */
 
-		if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
-			pTarget->maxWidth = dv->now.width;
-			pTarget->maxOffset = dv->now.offset;
-			pTarget->minSyncFactor = dv->now.factor;
-			pTarget->negoFlags = dv->now.flags;
+		if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
+			vtarget->maxWidth = dv->now.width;
+			vtarget->maxOffset = dv->now.offset;
+			vtarget->minSyncFactor = dv->now.factor;
+			vtarget->negoFlags = dv->now.flags;
 		} else {
 			/* Preserv all flags, use
 			 * read-modify-write algorithm
@@ -5578,6 +5486,94 @@
 		break;
 	}
 }
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
+ * Else set the NEED_DV flag after Read Capacity Issued (disks)
+ * or Mode Sense (cdroms).
+ *
+ * Tapes, initTarget will set this flag on completion of Inquiry command.
+ * Called only if DV_NOT_DONE flag is set
+ */
+static void
+mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
+{
+	MPT_ADAPTER	*ioc = hd->ioc;
+	u8 cmd;
+	SpiCfgData	*pSpi;
+
+	ddvtprintk((MYIOC_s_NOTE_FMT
+		" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
+		hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
+
+	if ((sc->device->lun != 0) || (hd->negoNvram != 0))
+		return;
+
+	cmd = sc->cmnd[0];
+
+	if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
+		pSpi = &ioc->spi_data;
+		if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
+			/* Set NEED_DV for all hidden disks
+			 */
+			Ioc3PhysDisk_t *pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
+			int		numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+
+			while (numPDisk) {
+				pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
+				ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
+				pPDisk++;
+				numPDisk--;
+			}
+		}
+		pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
+		ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
+	}
+}
+
+/* mptscsih_raid_set_dv_flags()
+ *
+ * New or replaced disk. Set DV flag and schedule DV.
+ */
+static void
+mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
+{
+	MPT_ADAPTER	*ioc = hd->ioc;
+	SpiCfgData	*pSpi = &ioc->spi_data;
+	Ioc3PhysDisk_t	*pPDisk;
+	int		 numPDisk;
+
+	if (hd->negoNvram != 0)
+		return;
+
+	ddvtprintk(("DV requested for phys disk id %d\n", id));
+	if (ioc->raid_data.pIocPg3) {
+		pPDisk =  ioc->raid_data.pIocPg3->PhysDisk;
+		numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+		while (numPDisk) {
+			if (id == pPDisk->PhysDiskNum) {
+				pSpi->dvStatus[pPDisk->PhysDiskID] =
+				    (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
+				pSpi->forceDv = MPT_SCSICFG_NEED_DV;
+				ddvtprintk(("NEED_DV set for phys disk id %d\n",
+				    pPDisk->PhysDiskID));
+				break;
+			}
+			pPDisk++;
+			numPDisk--;
+		}
+
+		if (numPDisk == 0) {
+			/* The physical disk that needs DV was not found
+			 * in the stored IOC Page 3. The driver must reload
+			 * this page. DV routine will set the NEED_DV flag for
+			 * all phys disks that have DV_NOT_DONE set.
+			 */
+			pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
+			ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
+		}
+	}
+}
 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
 
 EXPORT_SYMBOL(mptscsih_remove);
@@ -5589,7 +5585,9 @@
 EXPORT_SYMBOL(mptscsih_proc_info);
 EXPORT_SYMBOL(mptscsih_info);
 EXPORT_SYMBOL(mptscsih_qcmd);
+EXPORT_SYMBOL(mptscsih_target_alloc);
 EXPORT_SYMBOL(mptscsih_slave_alloc);
+EXPORT_SYMBOL(mptscsih_target_destroy);
 EXPORT_SYMBOL(mptscsih_slave_destroy);
 EXPORT_SYMBOL(mptscsih_slave_configure);
 EXPORT_SYMBOL(mptscsih_abort);
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 971fda4..d3cba12 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -91,7 +91,9 @@
 extern int mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int func);
 extern const char * mptscsih_info(struct Scsi_Host *SChost);
 extern int mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *));
+extern int mptscsih_target_alloc(struct scsi_target *starget);
 extern int mptscsih_slave_alloc(struct scsi_device *device);
+extern void mptscsih_target_destroy(struct scsi_target *starget);
 extern void mptscsih_slave_destroy(struct scsi_device *device);
 extern int mptscsih_slave_configure(struct scsi_device *device);
 extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 5c0e307..ce332a6 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -103,13 +103,16 @@
 static int	mptspiInternalCtx = -1; /* Used only for internal commands */
 
 static struct scsi_host_template mptspi_driver_template = {
+	.module				= THIS_MODULE,
 	.proc_name			= "mptspi",
 	.proc_info			= mptscsih_proc_info,
 	.name				= "MPT SPI Host",
 	.info				= mptscsih_info,
 	.queuecommand			= mptscsih_qcmd,
+	.target_alloc			= mptscsih_target_alloc,
 	.slave_alloc			= mptscsih_slave_alloc,
 	.slave_configure		= mptscsih_slave_configure,
+	.target_destroy			= mptscsih_target_destroy,
 	.slave_destroy			= mptscsih_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_abort_handler		= mptscsih_abort,
@@ -177,13 +180,15 @@
 		printk(MYIOC_s_WARN_FMT
 		  "Skipping because it's not operational!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptspi_probe;
 	}
 
 	if (!ioc->active) {
 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
 		  ioc->name);
-		return -ENODEV;
+		error = -ENODEV;
+		goto out_mptspi_probe;
 	}
 
 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
@@ -208,7 +213,8 @@
 		printk(MYIOC_s_WARN_FMT
 			"Unable to register controller with SCSI subsystem\n",
 			ioc->name);
-                return -1;
+		error = -1;
+		goto out_mptspi_probe;
         }
 
 	spin_lock_irqsave(&ioc->FreeQlock, flags);
@@ -286,7 +292,7 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptspi_probe_failed;
+		goto out_mptspi_probe;
 	}
 
 	memset(mem, 0, sz);
@@ -304,14 +310,14 @@
 	mem = kmalloc(sz, GFP_ATOMIC);
 	if (mem == NULL) {
 		error = -ENOMEM;
-		goto mptspi_probe_failed;
+		goto out_mptspi_probe;
 	}
 
 	memset(mem, 0, sz);
-	hd->Targets = (VirtDevice **) mem;
+	hd->Targets = (VirtTarget **) mem;
 
 	dprintk((KERN_INFO
-	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
+	  "  vdev @ %p, sz=%d\n", hd->Targets, sz));
 
 	/* Clear the TM flags
 	 */
@@ -385,13 +391,13 @@
 	if(error) {
 		dprintk((KERN_ERR MYNAM
 		  "scsi_add_host failed\n"));
-		goto mptspi_probe_failed;
+		goto out_mptspi_probe;
 	}
 
 	scsi_scan_host(sh);
 	return 0;
 
-mptspi_probe_failed:
+out_mptspi_probe:
 
 	mptscsih_remove(pdev);
 	return error;
diff --git a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
index 43a942a..fef6771 100644
--- a/drivers/message/i2o/Kconfig
+++ b/drivers/message/i2o/Kconfig
@@ -24,6 +24,18 @@
 
 	  If unsure, say N.
 
+config I2O_LCT_NOTIFY_ON_CHANGES
+	bool "Enable LCT notification"
+	depends on I2O
+	default y
+	---help---
+	  Only say N here if you have a I2O controller from SUN. The SUN
+	  firmware doesn't support LCT notification on changes. If this option
+	  is enabled on such a controller the driver will hang up in a endless
+	  loop. On all other controllers say Y.
+
+	  If unsure, say Y.
+
 config I2O_EXT_ADAPTEC
 	bool "Enable Adaptec extensions"
 	depends on I2O
diff --git a/drivers/message/i2o/bus-osm.c b/drivers/message/i2o/bus-osm.c
index 151b228..ac06f10 100644
--- a/drivers/message/i2o/bus-osm.c
+++ b/drivers/message/i2o/bus-osm.c
@@ -17,7 +17,7 @@
 #include <linux/i2o.h>
 
 #define OSM_NAME	"bus-osm"
-#define OSM_VERSION	"$Rev$"
+#define OSM_VERSION	"1.317"
 #define OSM_DESCRIPTION	"I2O Bus Adapter OSM"
 
 static struct i2o_driver i2o_bus_driver;
@@ -39,18 +39,18 @@
  */
 static int i2o_bus_scan(struct i2o_device *dev)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 
-	m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
+	msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
 		return -ETIMEDOUT;
 
-	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_BUS_SCAN << 24 | HOST_TID << 12 | dev->lct_data.tid,
-	       &msg->u.head[1]);
+	msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_BUS_SCAN << 24 | HOST_TID << 12 | dev->lct_data.
+			tid);
 
-	return i2o_msg_post_wait(dev->iop, m, 60);
+	return i2o_msg_post_wait(dev->iop, msg, 60);
 };
 
 /**
@@ -59,8 +59,9 @@
  *
  *	Returns count.
  */
-static ssize_t i2o_bus_store_scan(struct device *d, struct device_attribute *attr, const char *buf,
-				  size_t count)
+static ssize_t i2o_bus_store_scan(struct device *d,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
 {
 	struct i2o_device *i2o_dev = to_i2o_device(d);
 	int rc;
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c
index 10432f6..3bba7aa 100644
--- a/drivers/message/i2o/config-osm.c
+++ b/drivers/message/i2o/config-osm.c
@@ -22,7 +22,7 @@
 #include <asm/uaccess.h>
 
 #define OSM_NAME	"config-osm"
-#define OSM_VERSION	"1.248"
+#define OSM_VERSION	"1.323"
 #define OSM_DESCRIPTION	"I2O Configuration OSM"
 
 /* access mode user rw */
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
index 9eefedb..9062856 100644
--- a/drivers/message/i2o/core.h
+++ b/drivers/message/i2o/core.h
@@ -14,8 +14,6 @@
  */
 
 /* Exec-OSM */
-extern struct bus_type i2o_bus_type;
-
 extern struct i2o_driver i2o_exec_driver;
 extern int i2o_exec_lct_get(struct i2o_controller *);
 
@@ -23,6 +21,8 @@
 extern void __exit i2o_exec_exit(void);
 
 /* driver */
+extern struct bus_type i2o_bus_type;
+
 extern int i2o_driver_dispatch(struct i2o_controller *, u32);
 
 extern int __init i2o_driver_init(void);
@@ -33,19 +33,27 @@
 extern void __exit i2o_pci_exit(void);
 
 /* device */
+extern struct device_attribute i2o_device_attrs[];
+
 extern void i2o_device_remove(struct i2o_device *);
 extern int i2o_device_parse_lct(struct i2o_controller *);
 
 /* IOP */
 extern struct i2o_controller *i2o_iop_alloc(void);
-extern void i2o_iop_free(struct i2o_controller *);
+
+/**
+ *	i2o_iop_free - Free the i2o_controller struct
+ *	@c: I2O controller to free
+ */
+static inline void i2o_iop_free(struct i2o_controller *c)
+{
+	i2o_pool_free(&c->in_msg);
+	kfree(c);
+}
 
 extern int i2o_iop_add(struct i2o_controller *);
 extern void i2o_iop_remove(struct i2o_controller *);
 
-/* config */
-extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
-
 /* control registers relative to c->base */
 #define I2O_IRQ_STATUS	0x30
 #define I2O_IRQ_MASK	0x34
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index 8eb50cd..ee18305 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -35,18 +35,18 @@
 static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd,
 					 u32 type)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 
-	m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(cmd << 24 | HOST_TID << 12 | dev->lct_data.tid, &msg->u.head[1]);
-	writel(type, &msg->body[0]);
+	msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(cmd << 24 | HOST_TID << 12 | dev->lct_data.tid);
+	msg->body[0] = cpu_to_le32(type);
 
-	return i2o_msg_post_wait(dev->iop, m, 60);
+	return i2o_msg_post_wait(dev->iop, msg, 60);
 }
 
 /**
@@ -123,7 +123,6 @@
 	return rc;
 }
 
-
 /**
  *	i2o_device_release - release the memory for a I2O device
  *	@dev: I2O device which should be released
@@ -140,10 +139,10 @@
 	kfree(i2o_dev);
 }
 
-
 /**
- *	i2o_device_class_show_class_id - Displays class id of I2O device
- *	@cd: class device of which the class id should be displayed
+ *	i2o_device_show_class_id - Displays class id of I2O device
+ *	@dev: device of which the class id should be displayed
+ *	@attr: pointer to device attribute
  *	@buf: buffer into which the class id should be printed
  *
  *	Returns the number of bytes which are printed into the buffer.
@@ -159,15 +158,15 @@
 }
 
 /**
- *	i2o_device_class_show_tid - Displays TID of I2O device
- *	@cd: class device of which the TID should be displayed
- *	@buf: buffer into which the class id should be printed
+ *	i2o_device_show_tid - Displays TID of I2O device
+ *	@dev: device of which the TID should be displayed
+ *	@attr: pointer to device attribute
+ *	@buf: buffer into which the TID should be printed
  *
  *	Returns the number of bytes which are printed into the buffer.
  */
 static ssize_t i2o_device_show_tid(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
+				   struct device_attribute *attr, char *buf)
 {
 	struct i2o_device *i2o_dev = to_i2o_device(dev);
 
@@ -175,6 +174,7 @@
 	return strlen(buf) + 1;
 }
 
+/* I2O device attributes */
 struct device_attribute i2o_device_attrs[] = {
 	__ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL),
 	__ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL),
@@ -193,12 +193,10 @@
 {
 	struct i2o_device *dev;
 
-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev)
 		return ERR_PTR(-ENOMEM);
 
-	memset(dev, 0, sizeof(*dev));
-
 	INIT_LIST_HEAD(&dev->list);
 	init_MUTEX(&dev->lock);
 
@@ -209,66 +207,6 @@
 }
 
 /**
- *	i2o_setup_sysfs_links - Adds attributes to the I2O device
- *	@cd: I2O class device which is added to the I2O device class
- *
- *	This function get called when a I2O device is added to the class. It
- *	creates the attributes for each device and creates user/parent symlink
- *	if necessary.
- *
- *	Returns 0 on success or negative error code on failure.
- */
-static void i2o_setup_sysfs_links(struct i2o_device *i2o_dev)
-{
-	struct i2o_controller *c = i2o_dev->iop;
-	struct i2o_device *tmp;
-
-	/* create user entries for this device */
-	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
-	if (tmp && tmp != i2o_dev)
-		sysfs_create_link(&i2o_dev->device.kobj,
-				  &tmp->device.kobj, "user");
-
-	/* create user entries refering to this device */
-	list_for_each_entry(tmp, &c->devices, list)
-		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid &&
-		    tmp != i2o_dev)
-			sysfs_create_link(&tmp->device.kobj,
-					  &i2o_dev->device.kobj, "user");
-
-	/* create parent entries for this device */
-	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
-	if (tmp && tmp != i2o_dev)
-		sysfs_create_link(&i2o_dev->device.kobj,
-				  &tmp->device.kobj, "parent");
-
-	/* create parent entries refering to this device */
-	list_for_each_entry(tmp, &c->devices, list)
-		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid &&
-		    tmp != i2o_dev)
-		sysfs_create_link(&tmp->device.kobj,
-				  &i2o_dev->device.kobj, "parent");
-}
-
-static void i2o_remove_sysfs_links(struct i2o_device *i2o_dev)
-{
-	struct i2o_controller *c = i2o_dev->iop;
-	struct i2o_device *tmp;
-
-	sysfs_remove_link(&i2o_dev->device.kobj, "parent");
-	sysfs_remove_link(&i2o_dev->device.kobj, "user");
-
-	list_for_each_entry(tmp, &c->devices, list) {
-		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
-			sysfs_remove_link(&tmp->device.kobj, "parent");
-		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
-			sysfs_remove_link(&tmp->device.kobj, "user");
-	}
-}
-
-
-
-/**
  *	i2o_device_add - allocate a new I2O device and add it to the IOP
  *	@iop: I2O controller where the device is on
  *	@entry: LCT entry of the I2O device
@@ -282,33 +220,57 @@
 static struct i2o_device *i2o_device_add(struct i2o_controller *c,
 					 i2o_lct_entry * entry)
 {
-	struct i2o_device *dev;
+	struct i2o_device *i2o_dev, *tmp;
 
-	dev = i2o_device_alloc();
-	if (IS_ERR(dev)) {
+	i2o_dev = i2o_device_alloc();
+	if (IS_ERR(i2o_dev)) {
 		printk(KERN_ERR "i2o: unable to allocate i2o device\n");
-		return dev;
+		return i2o_dev;
 	}
 
-	dev->lct_data = *entry;
-	dev->iop = c;
+	i2o_dev->lct_data = *entry;
 
-	snprintf(dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit,
-		 dev->lct_data.tid);
+	snprintf(i2o_dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit,
+		 i2o_dev->lct_data.tid);
 
-	dev->device.parent = &c->device;
+	i2o_dev->iop = c;
+	i2o_dev->device.parent = &c->device;
 
-	device_register(&dev->device);
+	device_register(&i2o_dev->device);
 
-	list_add_tail(&dev->list, &c->devices);
+	list_add_tail(&i2o_dev->list, &c->devices);
 
-	i2o_setup_sysfs_links(dev);
+	/* create user entries for this device */
+	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
+	if (tmp && (tmp != i2o_dev))
+		sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
+				  "user");
 
-	i2o_driver_notify_device_add_all(dev);
+	/* create user entries refering to this device */
+	list_for_each_entry(tmp, &c->devices, list)
+	    if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+		&& (tmp != i2o_dev))
+		sysfs_create_link(&tmp->device.kobj,
+				  &i2o_dev->device.kobj, "user");
 
-	pr_debug("i2o: device %s added\n", dev->device.bus_id);
+	/* create parent entries for this device */
+	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
+	if (tmp && (tmp != i2o_dev))
+		sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
+				  "parent");
 
-	return dev;
+	/* create parent entries refering to this device */
+	list_for_each_entry(tmp, &c->devices, list)
+	    if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+		&& (tmp != i2o_dev))
+		sysfs_create_link(&tmp->device.kobj,
+				  &i2o_dev->device.kobj, "parent");
+
+	i2o_driver_notify_device_add_all(i2o_dev);
+
+	pr_debug("i2o: device %s added\n", i2o_dev->device.bus_id);
+
+	return i2o_dev;
 }
 
 /**
@@ -321,9 +283,22 @@
  */
 void i2o_device_remove(struct i2o_device *i2o_dev)
 {
+	struct i2o_device *tmp;
+	struct i2o_controller *c = i2o_dev->iop;
+
 	i2o_driver_notify_device_remove_all(i2o_dev);
-	i2o_remove_sysfs_links(i2o_dev);
+
+	sysfs_remove_link(&i2o_dev->device.kobj, "parent");
+	sysfs_remove_link(&i2o_dev->device.kobj, "user");
+
+	list_for_each_entry(tmp, &c->devices, list) {
+		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+			sysfs_remove_link(&tmp->device.kobj, "parent");
+		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+			sysfs_remove_link(&tmp->device.kobj, "user");
+	}
 	list_del(&i2o_dev->list);
+
 	device_unregister(&i2o_dev->device);
 }
 
@@ -341,36 +316,78 @@
 {
 	struct i2o_device *dev, *tmp;
 	i2o_lct *lct;
-	int i;
-	int max;
+	u32 *dlct = c->dlct.virt;
+	int max = 0, i = 0;
+	u16 table_size;
+	u32 buf;
 
 	down(&c->lct_lock);
 
 	kfree(c->lct);
 
-	lct = c->dlct.virt;
+	buf = le32_to_cpu(*dlct++);
+	table_size = buf & 0xffff;
 
-	c->lct = kmalloc(lct->table_size * 4, GFP_KERNEL);
-	if (!c->lct) {
+	lct = c->lct = kmalloc(table_size * 4, GFP_KERNEL);
+	if (!lct) {
 		up(&c->lct_lock);
 		return -ENOMEM;
 	}
 
-	if (lct->table_size * 4 > c->dlct.len) {
-		memcpy(c->lct, c->dlct.virt, c->dlct.len);
-		up(&c->lct_lock);
-		return -EAGAIN;
-	}
+	lct->lct_ver = buf >> 28;
+	lct->boot_tid = buf >> 16 & 0xfff;
+	lct->table_size = table_size;
+	lct->change_ind = le32_to_cpu(*dlct++);
+	lct->iop_flags = le32_to_cpu(*dlct++);
 
-	memcpy(c->lct, c->dlct.virt, lct->table_size * 4);
-
-	lct = c->lct;
-
-	max = (lct->table_size - 3) / 9;
+	table_size -= 3;
 
 	pr_debug("%s: LCT has %d entries (LCT size: %d)\n", c->name, max,
 		 lct->table_size);
 
+	while (table_size > 0) {
+		i2o_lct_entry *entry = &lct->lct_entry[max];
+		int found = 0;
+
+		buf = le32_to_cpu(*dlct++);
+		entry->entry_size = buf & 0xffff;
+		entry->tid = buf >> 16 & 0xfff;
+
+		entry->change_ind = le32_to_cpu(*dlct++);
+		entry->device_flags = le32_to_cpu(*dlct++);
+
+		buf = le32_to_cpu(*dlct++);
+		entry->class_id = buf & 0xfff;
+		entry->version = buf >> 12 & 0xf;
+		entry->vendor_id = buf >> 16;
+
+		entry->sub_class = le32_to_cpu(*dlct++);
+
+		buf = le32_to_cpu(*dlct++);
+		entry->user_tid = buf & 0xfff;
+		entry->parent_tid = buf >> 12 & 0xfff;
+		entry->bios_info = buf >> 24;
+
+		memcpy(&entry->identity_tag, dlct, 8);
+		dlct += 2;
+
+		entry->event_capabilities = le32_to_cpu(*dlct++);
+
+		/* add new devices, which are new in the LCT */
+		list_for_each_entry_safe(dev, tmp, &c->devices, list) {
+			if (entry->tid == dev->lct_data.tid) {
+				found = 1;
+				break;
+			}
+		}
+
+		if (!found)
+			i2o_device_add(c, entry);
+
+		table_size -= 9;
+		max++;
+	}
+
 	/* remove devices, which are not in the LCT anymore */
 	list_for_each_entry_safe(dev, tmp, &c->devices, list) {
 		int found = 0;
@@ -386,26 +403,11 @@
 			i2o_device_remove(dev);
 	}
 
-	/* add new devices, which are new in the LCT */
-	for (i = 0; i < max; i++) {
-		int found = 0;
-
-		list_for_each_entry_safe(dev, tmp, &c->devices, list) {
-			if (lct->lct_entry[i].tid == dev->lct_data.tid) {
-				found = 1;
-				break;
-			}
-		}
-
-		if (!found)
-			i2o_device_add(c, &lct->lct_entry[i]);
-	}
 	up(&c->lct_lock);
 
 	return 0;
 }
 
-
 /*
  *	Run time support routines
  */
@@ -419,13 +421,9 @@
  *	ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
  */
 int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
-			  int oplen, void *reslist, int reslen)
+		   int oplen, void *reslist, int reslen)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
-	u32 *res32 = (u32 *) reslist;
-	u32 *restmp = (u32 *) reslist;
-	int len = 0;
+	struct i2o_message *msg;
 	int i = 0;
 	int rc;
 	struct i2o_dma res;
@@ -437,26 +435,27 @@
 	if (i2o_dma_alloc(dev, &res, reslen, GFP_KERNEL))
 		return -ENOMEM;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY) {
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg)) {
 		i2o_dma_free(dev, &res);
-		return -ETIMEDOUT;
+		return PTR_ERR(msg);
 	}
 
 	i = 0;
-	writel(cmd << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid,
-	       &msg->u.head[1]);
-	writel(0, &msg->body[i++]);
-	writel(0x4C000000 | oplen, &msg->body[i++]);	/* OperationList */
-	memcpy_toio(&msg->body[i], oplist, oplen);
+	msg->u.head[1] =
+	    cpu_to_le32(cmd << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid);
+	msg->body[i++] = cpu_to_le32(0x00000000);
+	msg->body[i++] = cpu_to_le32(0x4C000000 | oplen);	/* OperationList */
+	memcpy(&msg->body[i], oplist, oplen);
 	i += (oplen / 4 + (oplen % 4 ? 1 : 0));
-	writel(0xD0000000 | res.len, &msg->body[i++]);	/* ResultList */
-	writel(res.phys, &msg->body[i++]);
+	msg->body[i++] = cpu_to_le32(0xD0000000 | res.len);	/* ResultList */
+	msg->body[i++] = cpu_to_le32(res.phys);
 
-	writel(I2O_MESSAGE_SIZE(i + sizeof(struct i2o_message) / 4) |
-	       SGL_OFFSET_5, &msg->u.head[0]);
+	msg->u.head[0] =
+	    cpu_to_le32(I2O_MESSAGE_SIZE(i + sizeof(struct i2o_message) / 4) |
+			SGL_OFFSET_5);
 
-	rc = i2o_msg_post_wait_mem(c, m, 10, &res);
+	rc = i2o_msg_post_wait_mem(c, msg, 10, &res);
 
 	/* This only looks like a memory leak - don't "fix" it. */
 	if (rc == -ETIMEDOUT)
@@ -465,36 +464,7 @@
 	memcpy(reslist, res.virt, res.len);
 	i2o_dma_free(dev, &res);
 
-	/* Query failed */
-	if (rc)
-		return rc;
-	/*
-	 * Calculate number of bytes of Result LIST
-	 * We need to loop through each Result BLOCK and grab the length
-	 */
-	restmp = res32 + 1;
-	len = 1;
-	for (i = 0; i < (res32[0] & 0X0000FFFF); i++) {
-		if (restmp[0] & 0x00FF0000) {	/* BlockStatus != SUCCESS */
-			printk(KERN_WARNING
-			       "%s - Error:\n  ErrorInfoSize = 0x%02x, "
-			       "BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
-			       (cmd ==
-				I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET" :
-			       "PARAMS_GET", res32[1] >> 24,
-			       (res32[1] >> 16) & 0xFF, res32[1] & 0xFFFF);
-
-			/*
-			 *      If this is the only request,than we return an error
-			 */
-			if ((res32[0] & 0x0000FFFF) == 1) {
-				return -((res32[1] >> 16) & 0xFF);	/* -BlockStatus */
-			}
-		}
-		len += restmp[0] & 0x0000FFFF;	/* Length of res BLOCK */
-		restmp += restmp[0] & 0x0000FFFF;	/* Skip to next BLOCK */
-	}
-	return (len << 2);	/* bytes used by result list */
+	return rc;
 }
 
 /*
@@ -503,28 +473,25 @@
 int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
 		       void *buf, int buflen)
 {
-	u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
+	u32 opblk[] = { cpu_to_le32(0x00000001),
+		cpu_to_le32((u16) group << 16 | I2O_PARAMS_FIELD_GET),
+		cpu_to_le32((s16) field << 16 | 0x00000001)
+	};
 	u8 *resblk;		/* 8 bytes for header */
-	int size;
-
-	if (field == -1)	/* whole group */
-		opblk[4] = -1;
+	int rc;
 
 	resblk = kmalloc(buflen + 8, GFP_KERNEL | GFP_ATOMIC);
 	if (!resblk)
 		return -ENOMEM;
 
-	size = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
-			      sizeof(opblk), resblk, buflen + 8);
+	rc = i2o_parm_issue(i2o_dev, I2O_CMD_UTIL_PARAMS_GET, opblk,
+			    sizeof(opblk), resblk, buflen + 8);
 
 	memcpy(buf, resblk + 8, buflen);	/* cut off header */
 
 	kfree(resblk);
 
-	if (size > buflen)
-		return buflen;
-
-	return size;
+	return rc;
 }
 
 /*
@@ -534,12 +501,12 @@
  *		else return specific fields
  *			ibuf contains fieldindexes
  *
- * 	if oper == I2O_PARAMS_LIST_GET, get from specific rows
- * 		if fieldcount == -1 return all fields
+ *	if oper == I2O_PARAMS_LIST_GET, get from specific rows
+ *		if fieldcount == -1 return all fields
  *			ibuf contains rowcount, keyvalues
- * 		else return specific fields
+ *		else return specific fields
  *			fieldcount is # of fieldindexes
- *  			ibuf contains fieldindexes, rowcount, keyvalues
+ *			ibuf contains fieldindexes, rowcount, keyvalues
  *
  *	You could also use directly function i2o_issue_params().
  */
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 0fb9c4e..6413022 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -61,12 +61,10 @@
 };
 
 /* I2O bus type */
-extern struct device_attribute i2o_device_attrs[];
-
 struct bus_type i2o_bus_type = {
 	.name = "i2o",
 	.match = i2o_bus_match,
-	.dev_attrs = i2o_device_attrs,
+	.dev_attrs = i2o_device_attrs
 };
 
 /**
@@ -219,14 +217,14 @@
 		/* cut of header from message size (in 32-bit words) */
 		size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5;
 
-		evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO);
+		evt = kzalloc(size * 4 + sizeof(*evt), GFP_ATOMIC);
 		if (!evt)
 			return -ENOMEM;
 
 		evt->size = size;
 		evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt);
 		evt->event_indicator = le32_to_cpu(msg->body[0]);
-		memcpy(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
+		memcpy(&evt->data, &msg->body[1], size * 4);
 
 		list_for_each_entry_safe(dev, tmp, &c->devices, list)
 		    if (dev->lct_data.tid == tid) {
@@ -349,12 +347,10 @@
 	osm_info("max drivers = %d\n", i2o_max_drivers);
 
 	i2o_drivers =
-	    kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
+	    kzalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL);
 	if (!i2o_drivers)
 		return -ENOMEM;
 
-	memset(i2o_drivers, 0, i2o_max_drivers * sizeof(*i2o_drivers));
-
 	rc = bus_register(&i2o_bus_type);
 
 	if (rc < 0)
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 9c339a2..9bb9859 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -33,7 +33,7 @@
 #include <linux/workqueue.h>
 #include <linux/string.h>
 #include <linux/slab.h>
-#include <linux/sched.h>   /* wait_event_interruptible_timeout() needs this */
+#include <linux/sched.h>	/* wait_event_interruptible_timeout() needs this */
 #include <asm/param.h>		/* HZ */
 #include "core.h"
 
@@ -75,11 +75,9 @@
 {
 	struct i2o_exec_wait *wait;
 
-	wait = kmalloc(sizeof(*wait), GFP_KERNEL);
+	wait = kzalloc(sizeof(*wait), GFP_KERNEL);
 	if (!wait)
-		return ERR_PTR(-ENOMEM);
-
-	memset(wait, 0, sizeof(*wait));
+		return NULL;
 
 	INIT_LIST_HEAD(&wait->list);
 
@@ -114,13 +112,12 @@
  *	Returns 0 on success, negative error code on timeout or positive error
  *	code from reply.
  */
-int i2o_msg_post_wait_mem(struct i2o_controller *c, u32 m, unsigned long
-			  timeout, struct i2o_dma *dma)
+int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg,
+			  unsigned long timeout, struct i2o_dma *dma)
 {
 	DECLARE_WAIT_QUEUE_HEAD(wq);
 	struct i2o_exec_wait *wait;
 	static u32 tcntxt = 0x80000000;
-	struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
 	int rc = 0;
 
 	wait = i2o_exec_wait_alloc();
@@ -138,15 +135,15 @@
 	 * We will only use transaction contexts >= 0x80000000 for POST WAIT,
 	 * so we could find a POST WAIT reply easier in the reply handler.
 	 */
-	writel(i2o_exec_driver.context, &msg->u.s.icntxt);
+	msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
 	wait->tcntxt = tcntxt++;
-	writel(wait->tcntxt, &msg->u.s.tcntxt);
+	msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt);
 
 	/*
 	 * Post the message to the controller. At some point later it will
 	 * return. If we time out before it returns then complete will be zero.
 	 */
-	i2o_msg_post(c, m);
+	i2o_msg_post(c, msg);
 
 	if (!wait->complete) {
 		wait->wq = &wq;
@@ -266,13 +263,14 @@
  *
  *	Returns number of bytes printed into buffer.
  */
-static ssize_t i2o_exec_show_vendor_id(struct device *d, struct device_attribute *attr, char *buf)
+static ssize_t i2o_exec_show_vendor_id(struct device *d,
+				       struct device_attribute *attr, char *buf)
 {
 	struct i2o_device *dev = to_i2o_device(d);
 	u16 id;
 
-	if (i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) {
-		sprintf(buf, "0x%04x", id);
+	if (!i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) {
+		sprintf(buf, "0x%04x", le16_to_cpu(id));
 		return strlen(buf) + 1;
 	}
 
@@ -286,13 +284,15 @@
  *
  *	Returns number of bytes printed into buffer.
  */
-static ssize_t i2o_exec_show_product_id(struct device *d, struct device_attribute *attr, char *buf)
+static ssize_t i2o_exec_show_product_id(struct device *d,
+					struct device_attribute *attr,
+					char *buf)
 {
 	struct i2o_device *dev = to_i2o_device(d);
 	u16 id;
 
-	if (i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) {
-		sprintf(buf, "0x%04x", id);
+	if (!i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) {
+		sprintf(buf, "0x%04x", le16_to_cpu(id));
 		return strlen(buf) + 1;
 	}
 
@@ -362,7 +362,9 @@
 	if (i2o_device_parse_lct(c) != -EAGAIN)
 		change_ind = c->lct->change_ind + 1;
 
+#ifdef CONFIG_I2O_LCT_NOTIFY_ON_CHANGES
 	i2o_exec_lct_notify(c, change_ind);
+#endif
 };
 
 /**
@@ -385,23 +387,22 @@
 	u32 context;
 
 	if (le32_to_cpu(msg->u.head[0]) & MSG_FAIL) {
+		struct i2o_message __iomem *pmsg;
+		u32 pm;
+
 		/*
 		 * If Fail bit is set we must take the transaction context of
 		 * the preserved message to find the right request again.
 		 */
-		struct i2o_message __iomem *pmsg;
-		u32 pm;
 
 		pm = le32_to_cpu(msg->body[3]);
-
 		pmsg = i2o_msg_in_to_virt(c, pm);
+		context = readl(&pmsg->u.s.tcntxt);
 
 		i2o_report_status(KERN_INFO, "i2o_core", msg);
 
-		context = readl(&pmsg->u.s.tcntxt);
-
 		/* Release the preserved msg */
-		i2o_msg_nop(c, pm);
+		i2o_msg_nop_mfa(c, pm);
 	} else
 		context = le32_to_cpu(msg->u.s.tcntxt);
 
@@ -462,25 +463,26 @@
  */
 int i2o_exec_lct_get(struct i2o_controller *c)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	int i = 0;
 	int rc = -EAGAIN;
 
 	for (i = 1; i <= I2O_LCT_GET_TRIES; i++) {
-		m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-		if (m == I2O_QUEUE_EMPTY)
-			return -ETIMEDOUT;
+		msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+		if (IS_ERR(msg))
+			return PTR_ERR(msg);
 
-		writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]);
-		writel(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | ADAPTER_TID,
-		       &msg->u.head[1]);
-		writel(0xffffffff, &msg->body[0]);
-		writel(0x00000000, &msg->body[1]);
-		writel(0xd0000000 | c->dlct.len, &msg->body[2]);
-		writel(c->dlct.phys, &msg->body[3]);
+		msg->u.head[0] =
+		    cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6);
+		msg->u.head[1] =
+		    cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 |
+				ADAPTER_TID);
+		msg->body[0] = cpu_to_le32(0xffffffff);
+		msg->body[1] = cpu_to_le32(0x00000000);
+		msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len);
+		msg->body[3] = cpu_to_le32(c->dlct.phys);
 
-		rc = i2o_msg_post_wait(c, m, I2O_TIMEOUT_LCT_GET);
+		rc = i2o_msg_post_wait(c, msg, I2O_TIMEOUT_LCT_GET);
 		if (rc < 0)
 			break;
 
@@ -506,29 +508,29 @@
 {
 	i2o_status_block *sb = c->status_block.virt;
 	struct device *dev;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 
 	dev = &c->pdev->dev;
 
-	if (i2o_dma_realloc(dev, &c->dlct, sb->expected_lct_size, GFP_KERNEL))
+	if (i2o_dma_realloc
+	    (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL))
 		return -ENOMEM;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]);
-	writel(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
-	writel(i2o_exec_driver.context, &msg->u.s.icntxt);
-	writel(0, &msg->u.s.tcntxt);	/* FIXME */
-	writel(0xffffffff, &msg->body[0]);
-	writel(change_ind, &msg->body[1]);
-	writel(0xd0000000 | c->dlct.len, &msg->body[2]);
-	writel(c->dlct.phys, &msg->body[3]);
+	msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6);
+	msg->u.head[1] = cpu_to_le32(I2O_CMD_LCT_NOTIFY << 24 | HOST_TID << 12 |
+				     ADAPTER_TID);
+	msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
+	msg->u.s.tcntxt = cpu_to_le32(0x00000000);
+	msg->body[0] = cpu_to_le32(0xffffffff);
+	msg->body[1] = cpu_to_le32(change_ind);
+	msg->body[2] = cpu_to_le32(0xd0000000 | c->dlct.len);
+	msg->body[3] = cpu_to_le32(c->dlct.phys);
 
-	i2o_msg_post(c, m);
+	i2o_msg_post(c, msg);
 
 	return 0;
 };
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index f283b5b..b09fb63 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -59,10 +59,12 @@
 #include <linux/blkdev.h>
 #include <linux/hdreg.h>
 
+#include <scsi/scsi.h>
+
 #include "i2o_block.h"
 
 #define OSM_NAME	"block-osm"
-#define OSM_VERSION	"1.287"
+#define OSM_VERSION	"1.325"
 #define OSM_DESCRIPTION	"I2O Block Device OSM"
 
 static struct i2o_driver i2o_block_driver;
@@ -130,20 +132,20 @@
  */
 static int i2o_block_device_flush(struct i2o_device *dev)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 
-	m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_BLOCK_CFLUSH << 24 | HOST_TID << 12 | dev->lct_data.tid,
-	       &msg->u.head[1]);
-	writel(60 << 16, &msg->body[0]);
+	msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_BLOCK_CFLUSH << 24 | HOST_TID << 12 | dev->
+			lct_data.tid);
+	msg->body[0] = cpu_to_le32(60 << 16);
 	osm_debug("Flushing...\n");
 
-	return i2o_msg_post_wait(dev->iop, m, 60);
+	return i2o_msg_post_wait(dev->iop, msg, 60);
 };
 
 /**
@@ -181,21 +183,21 @@
  */
 static int i2o_block_device_mount(struct i2o_device *dev, u32 media_id)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 
-	m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_BLOCK_MMOUNT << 24 | HOST_TID << 12 | dev->lct_data.tid,
-	       &msg->u.head[1]);
-	writel(-1, &msg->body[0]);
-	writel(0, &msg->body[1]);
+	msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_BLOCK_MMOUNT << 24 | HOST_TID << 12 | dev->
+			lct_data.tid);
+	msg->body[0] = cpu_to_le32(-1);
+	msg->body[1] = cpu_to_le32(0x00000000);
 	osm_debug("Mounting...\n");
 
-	return i2o_msg_post_wait(dev->iop, m, 2);
+	return i2o_msg_post_wait(dev->iop, msg, 2);
 };
 
 /**
@@ -210,20 +212,20 @@
  */
 static int i2o_block_device_lock(struct i2o_device *dev, u32 media_id)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 
-	m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg) == I2O_QUEUE_EMPTY)
+		return PTR_ERR(msg);
 
-	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_BLOCK_MLOCK << 24 | HOST_TID << 12 | dev->lct_data.tid,
-	       &msg->u.head[1]);
-	writel(-1, &msg->body[0]);
+	msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_BLOCK_MLOCK << 24 | HOST_TID << 12 | dev->
+			lct_data.tid);
+	msg->body[0] = cpu_to_le32(-1);
 	osm_debug("Locking...\n");
 
-	return i2o_msg_post_wait(dev->iop, m, 2);
+	return i2o_msg_post_wait(dev->iop, msg, 2);
 };
 
 /**
@@ -238,20 +240,20 @@
  */
 static int i2o_block_device_unlock(struct i2o_device *dev, u32 media_id)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 
-	m = i2o_msg_get_wait(dev->iop, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(dev->iop, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_BLOCK_MUNLOCK << 24 | HOST_TID << 12 | dev->lct_data.tid,
-	       &msg->u.head[1]);
-	writel(media_id, &msg->body[0]);
+	msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_BLOCK_MUNLOCK << 24 | HOST_TID << 12 | dev->
+			lct_data.tid);
+	msg->body[0] = cpu_to_le32(media_id);
 	osm_debug("Unlocking...\n");
 
-	return i2o_msg_post_wait(dev->iop, m, 2);
+	return i2o_msg_post_wait(dev->iop, msg, 2);
 };
 
 /**
@@ -267,21 +269,21 @@
 {
 	struct i2o_device *i2o_dev = dev->i2o_dev;
 	struct i2o_controller *c = i2o_dev->iop;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	int rc;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_BLOCK_POWER << 24 | HOST_TID << 12 | i2o_dev->lct_data.
-	       tid, &msg->u.head[1]);
-	writel(op << 24, &msg->body[0]);
+	msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_BLOCK_POWER << 24 | HOST_TID << 12 | i2o_dev->
+			lct_data.tid);
+	msg->body[0] = cpu_to_le32(op << 24);
 	osm_debug("Power...\n");
 
-	rc = i2o_msg_post_wait(c, m, 60);
+	rc = i2o_msg_post_wait(c, msg, 60);
 	if (!rc)
 		dev->power = op;
 
@@ -331,7 +333,7 @@
  */
 static inline int i2o_block_sglist_alloc(struct i2o_controller *c,
 					 struct i2o_block_request *ireq,
-					 u32 __iomem ** mptr)
+					 u32 ** mptr)
 {
 	int nents;
 	enum dma_data_direction direction;
@@ -466,7 +468,7 @@
 
 	spin_lock_irqsave(q->queue_lock, flags);
 
-	end_that_request_last(req);
+	end_that_request_last(req, uptodate);
 
 	if (likely(dev)) {
 		dev->open_queue_depth--;
@@ -660,6 +662,13 @@
 	return 0;
 }
 
+static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	i2o_block_biosparam(get_capacity(bdev->bd_disk),
+			    &geo->cylinders, &geo->heads, &geo->sectors);
+	return 0;
+}
+
 /**
  *	i2o_block_ioctl - Issue device specific ioctl calls.
  *	@cmd: ioctl command
@@ -674,7 +683,6 @@
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
 	struct i2o_block_device *dev = disk->private_data;
-	void __user *argp = (void __user *)arg;
 
 	/* Anyone capable of this syscall can do *real bad* things */
 
@@ -682,15 +690,6 @@
 		return -EPERM;
 
 	switch (cmd) {
-	case HDIO_GETGEO:
-		{
-			struct hd_geometry g;
-			i2o_block_biosparam(get_capacity(disk),
-					    &g.cylinders, &g.heads, &g.sectors);
-			g.start = get_start_sect(inode->i_bdev);
-			return copy_to_user(argp, &g, sizeof(g)) ? -EFAULT : 0;
-		}
-
 	case BLKI2OGRSTRAT:
 		return put_user(dev->rcache, (int __user *)arg);
 	case BLKI2OGWSTRAT:
@@ -745,10 +744,9 @@
 	struct i2o_block_device *dev = req->rq_disk->private_data;
 	struct i2o_controller *c;
 	int tid = dev->i2o_dev->lct_data.tid;
-	struct i2o_message __iomem *msg;
-	u32 __iomem *mptr;
+	struct i2o_message *msg;
+	u32 *mptr;
 	struct i2o_block_request *ireq = req->special;
-	u32 m;
 	u32 tcntxt;
 	u32 sgl_offset = SGL_OFFSET_8;
 	u32 ctl_flags = 0x00000000;
@@ -763,9 +761,9 @@
 
 	c = dev->i2o_dev->iop;
 
-	m = i2o_msg_get(c, &msg);
-	if (m == I2O_QUEUE_EMPTY) {
-		rc = -EBUSY;
+	msg = i2o_msg_get(c);
+	if (IS_ERR(msg)) {
+		rc = PTR_ERR(msg);
 		goto exit;
 	}
 
@@ -775,8 +773,8 @@
 		goto nop_msg;
 	}
 
-	writel(i2o_block_driver.context, &msg->u.s.icntxt);
-	writel(tcntxt, &msg->u.s.tcntxt);
+	msg->u.s.icntxt = cpu_to_le32(i2o_block_driver.context);
+	msg->u.s.tcntxt = cpu_to_le32(tcntxt);
 
 	mptr = &msg->body[0];
 
@@ -834,11 +832,11 @@
 
 		sgl_offset = SGL_OFFSET_12;
 
-		writel(I2O_CMD_PRIVATE << 24 | HOST_TID << 12 | tid,
-		       &msg->u.head[1]);
+		msg->u.head[1] =
+		    cpu_to_le32(I2O_CMD_PRIVATE << 24 | HOST_TID << 12 | tid);
 
-		writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++);
-		writel(tid, mptr++);
+		*mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC);
+		*mptr++ = cpu_to_le32(tid);
 
 		/*
 		 * ENABLE_DISCONNECT
@@ -846,29 +844,31 @@
 		 * RETURN_SENSE_DATA_IN_REPLY_MESSAGE_FRAME
 		 */
 		if (rq_data_dir(req) == READ) {
-			cmd[0] = 0x28;
+			cmd[0] = READ_10;
 			scsi_flags = 0x60a0000a;
 		} else {
-			cmd[0] = 0x2A;
+			cmd[0] = WRITE_10;
 			scsi_flags = 0xa0a0000a;
 		}
 
-		writel(scsi_flags, mptr++);
+		*mptr++ = cpu_to_le32(scsi_flags);
 
 		*((u32 *) & cmd[2]) = cpu_to_be32(req->sector * hwsec);
 		*((u16 *) & cmd[7]) = cpu_to_be16(req->nr_sectors * hwsec);
 
-		memcpy_toio(mptr, cmd, 10);
+		memcpy(mptr, cmd, 10);
 		mptr += 4;
-		writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++);
+		*mptr++ = cpu_to_le32(req->nr_sectors << KERNEL_SECTOR_SHIFT);
 	} else
 #endif
 	{
-		writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]);
-		writel(ctl_flags, mptr++);
-		writel(req->nr_sectors << KERNEL_SECTOR_SHIFT, mptr++);
-		writel((u32) (req->sector << KERNEL_SECTOR_SHIFT), mptr++);
-		writel(req->sector >> (32 - KERNEL_SECTOR_SHIFT), mptr++);
+		msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid);
+		*mptr++ = cpu_to_le32(ctl_flags);
+		*mptr++ = cpu_to_le32(req->nr_sectors << KERNEL_SECTOR_SHIFT);
+		*mptr++ =
+		    cpu_to_le32((u32) (req->sector << KERNEL_SECTOR_SHIFT));
+		*mptr++ =
+		    cpu_to_le32(req->sector >> (32 - KERNEL_SECTOR_SHIFT));
 	}
 
 	if (!i2o_block_sglist_alloc(c, ireq, &mptr)) {
@@ -876,13 +876,13 @@
 		goto context_remove;
 	}
 
-	writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) |
-	       sgl_offset, &msg->u.head[0]);
+	msg->u.head[0] =
+	    cpu_to_le32(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset);
 
 	list_add_tail(&ireq->queue, &dev->open_queue);
 	dev->open_queue_depth++;
 
-	i2o_msg_post(c, m);
+	i2o_msg_post(c, msg);
 
 	return 0;
 
@@ -890,7 +890,7 @@
 	i2o_cntxt_list_remove(c, req);
 
       nop_msg:
-	i2o_msg_nop(c, m);
+	i2o_msg_nop(c, msg);
 
       exit:
 	return rc;
@@ -959,6 +959,7 @@
 	.open = i2o_block_open,
 	.release = i2o_block_release,
 	.ioctl = i2o_block_ioctl,
+	.getgeo = i2o_block_getgeo,
 	.media_changed = i2o_block_media_changed
 };
 
@@ -978,13 +979,12 @@
 	struct request_queue *queue;
 	int rc;
 
-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
 		osm_err("Insufficient memory to allocate I2O Block disk.\n");
 		rc = -ENOMEM;
 		goto exit;
 	}
-	memset(dev, 0, sizeof(*dev));
 
 	INIT_LIST_HEAD(&dev->open_queue);
 	spin_lock_init(&dev->lock);
@@ -1049,8 +1049,8 @@
 	int rc;
 	u64 size;
 	u32 blocksize;
-	u32 flags, status;
 	u16 body_size = 4;
+	u16 power;
 	unsigned short max_sectors;
 
 #ifdef CONFIG_I2O_EXT_ADAPTEC
@@ -1108,22 +1108,20 @@
 	 *      Ask for the current media data. If that isn't supported
 	 *      then we ask for the device capacity data
 	 */
-	if (i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) ||
-	    i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4)) {
-		blk_queue_hardsect_size(queue, blocksize);
+	if (!i2o_parm_field_get(i2o_dev, 0x0004, 1, &blocksize, 4) ||
+	    !i2o_parm_field_get(i2o_dev, 0x0000, 3, &blocksize, 4)) {
+		blk_queue_hardsect_size(queue, le32_to_cpu(blocksize));
 	} else
 		osm_warn("unable to get blocksize of %s\n", gd->disk_name);
 
-	if (i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) ||
-	    i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8)) {
-		set_capacity(gd, size >> KERNEL_SECTOR_SHIFT);
+	if (!i2o_parm_field_get(i2o_dev, 0x0004, 0, &size, 8) ||
+	    !i2o_parm_field_get(i2o_dev, 0x0000, 4, &size, 8)) {
+		set_capacity(gd, le64_to_cpu(size) >> KERNEL_SECTOR_SHIFT);
 	} else
 		osm_warn("could not get size of %s\n", gd->disk_name);
 
-	if (!i2o_parm_field_get(i2o_dev, 0x0000, 2, &i2o_blk_dev->power, 2))
-		i2o_blk_dev->power = 0;
-	i2o_parm_field_get(i2o_dev, 0x0000, 5, &flags, 4);
-	i2o_parm_field_get(i2o_dev, 0x0000, 6, &status, 4);
+	if (!i2o_parm_field_get(i2o_dev, 0x0000, 2, &power, 2))
+		i2o_blk_dev->power = power;
 
 	i2o_event_register(i2o_dev, &i2o_block_driver, 0, 0xffffffff);
 
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 3c3a7ab..89daf67 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -36,12 +36,12 @@
 
 #include <asm/uaccess.h>
 
-#include "core.h"
-
 #define SG_TABLESIZE		30
 
-static int i2o_cfg_ioctl(struct inode *inode, struct file *fp, unsigned int cmd,
-			 unsigned long arg);
+extern int i2o_parm_issue(struct i2o_device *, int, void *, int, void *, int);
+
+static int i2o_cfg_ioctl(struct inode *, struct file *, unsigned int,
+			 unsigned long);
 
 static spinlock_t i2o_config_lock;
 
@@ -230,8 +230,7 @@
 	struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg;
 	unsigned char maxfrag = 0, curfrag = 1;
 	struct i2o_dma buffer;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	unsigned int status = 0, swlen = 0, fragsize = 8192;
 	struct i2o_controller *c;
 
@@ -257,31 +256,34 @@
 	if (!c)
 		return -ENXIO;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -EBUSY;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
 	if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) {
-		i2o_msg_nop(c, m);
+		i2o_msg_nop(c, msg);
 		return -ENOMEM;
 	}
 
 	__copy_from_user(buffer.virt, kxfer.buf, fragsize);
 
-	writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
-	writel(I2O_CMD_SW_DOWNLOAD << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
-	writel(i2o_config_driver.context, &msg->u.head[2]);
-	writel(0, &msg->u.head[3]);
-	writel((((u32) kxfer.flags) << 24) | (((u32) kxfer.sw_type) << 16) |
-	       (((u32) maxfrag) << 8) | (((u32) curfrag)), &msg->body[0]);
-	writel(swlen, &msg->body[1]);
-	writel(kxfer.sw_id, &msg->body[2]);
-	writel(0xD0000000 | fragsize, &msg->body[3]);
-	writel(buffer.phys, &msg->body[4]);
+	msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_SW_DOWNLOAD << 24 | HOST_TID << 12 |
+			ADAPTER_TID);
+	msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
+	msg->u.head[3] = cpu_to_le32(0);
+	msg->body[0] =
+	    cpu_to_le32((((u32) kxfer.flags) << 24) | (((u32) kxfer.
+							sw_type) << 16) |
+			(((u32) maxfrag) << 8) | (((u32) curfrag)));
+	msg->body[1] = cpu_to_le32(swlen);
+	msg->body[2] = cpu_to_le32(kxfer.sw_id);
+	msg->body[3] = cpu_to_le32(0xD0000000 | fragsize);
+	msg->body[4] = cpu_to_le32(buffer.phys);
 
 	osm_debug("swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
-	status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
+	status = i2o_msg_post_wait_mem(c, msg, 60, &buffer);
 
 	if (status != -ETIMEDOUT)
 		i2o_dma_free(&c->pdev->dev, &buffer);
@@ -302,8 +304,7 @@
 	struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg;
 	unsigned char maxfrag = 0, curfrag = 1;
 	struct i2o_dma buffer;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	unsigned int status = 0, swlen = 0, fragsize = 8192;
 	struct i2o_controller *c;
 	int ret = 0;
@@ -330,30 +331,30 @@
 	if (!c)
 		return -ENXIO;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -EBUSY;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
 	if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) {
-		i2o_msg_nop(c, m);
+		i2o_msg_nop(c, msg);
 		return -ENOMEM;
 	}
 
-	writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
-	writel(I2O_CMD_SW_UPLOAD << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
-	writel(i2o_config_driver.context, &msg->u.head[2]);
-	writel(0, &msg->u.head[3]);
-	writel((u32) kxfer.flags << 24 | (u32) kxfer.
-	       sw_type << 16 | (u32) maxfrag << 8 | (u32) curfrag,
-	       &msg->body[0]);
-	writel(swlen, &msg->body[1]);
-	writel(kxfer.sw_id, &msg->body[2]);
-	writel(0xD0000000 | fragsize, &msg->body[3]);
-	writel(buffer.phys, &msg->body[4]);
+	msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_7);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_SW_UPLOAD << 24 | HOST_TID << 12 | ADAPTER_TID);
+	msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
+	msg->u.head[3] = cpu_to_le32(0);
+	msg->body[0] =
+	    cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer.
+			sw_type << 16 | (u32) maxfrag << 8 | (u32) curfrag);
+	msg->body[1] = cpu_to_le32(swlen);
+	msg->body[2] = cpu_to_le32(kxfer.sw_id);
+	msg->body[3] = cpu_to_le32(0xD0000000 | fragsize);
+	msg->body[4] = cpu_to_le32(buffer.phys);
 
 	osm_debug("swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
-	status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
+	status = i2o_msg_post_wait_mem(c, msg, 60, &buffer);
 
 	if (status != I2O_POST_WAIT_OK) {
 		if (status != -ETIMEDOUT)
@@ -380,8 +381,7 @@
 	struct i2o_controller *c;
 	struct i2o_sw_xfer kxfer;
 	struct i2o_sw_xfer __user *pxfer = (struct i2o_sw_xfer __user *)arg;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	unsigned int swlen;
 	int token;
 
@@ -395,21 +395,21 @@
 	if (!c)
 		return -ENXIO;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -EBUSY;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_SW_REMOVE << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
-	writel(i2o_config_driver.context, &msg->u.head[2]);
-	writel(0, &msg->u.head[3]);
-	writel((u32) kxfer.flags << 24 | (u32) kxfer.sw_type << 16,
-	       &msg->body[0]);
-	writel(swlen, &msg->body[1]);
-	writel(kxfer.sw_id, &msg->body[2]);
+	msg->u.head[0] = cpu_to_le32(SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_SW_REMOVE << 24 | HOST_TID << 12 | ADAPTER_TID);
+	msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
+	msg->u.head[3] = cpu_to_le32(0);
+	msg->body[0] =
+	    cpu_to_le32((u32) kxfer.flags << 24 | (u32) kxfer.sw_type << 16);
+	msg->body[1] = cpu_to_le32(swlen);
+	msg->body[2] = cpu_to_le32(kxfer.sw_id);
 
-	token = i2o_msg_post_wait(c, m, 10);
+	token = i2o_msg_post_wait(c, msg, 10);
 
 	if (token != I2O_POST_WAIT_OK) {
 		osm_info("swdel failed, DetailedStatus = %d\n", token);
@@ -423,25 +423,24 @@
 {
 	int token;
 	int iop = (int)arg;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	struct i2o_controller *c;
 
 	c = i2o_find_iop(iop);
 	if (!c)
 		return -ENXIO;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -EBUSY;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_CONFIG_VALIDATE << 24 | HOST_TID << 12 | iop,
-	       &msg->u.head[1]);
-	writel(i2o_config_driver.context, &msg->u.head[2]);
-	writel(0, &msg->u.head[3]);
+	msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_CONFIG_VALIDATE << 24 | HOST_TID << 12 | iop);
+	msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
+	msg->u.head[3] = cpu_to_le32(0);
 
-	token = i2o_msg_post_wait(c, m, 10);
+	token = i2o_msg_post_wait(c, msg, 10);
 
 	if (token != I2O_POST_WAIT_OK) {
 		osm_info("Can't validate configuration, ErrorStatus = %d\n",
@@ -454,8 +453,7 @@
 
 static int i2o_cfg_evt_reg(unsigned long arg, struct file *fp)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	struct i2o_evt_id __user *pdesc = (struct i2o_evt_id __user *)arg;
 	struct i2o_evt_id kdesc;
 	struct i2o_controller *c;
@@ -474,18 +472,19 @@
 	if (!d)
 		return -ENODEV;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -EBUSY;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | kdesc.tid,
-	       &msg->u.head[1]);
-	writel(i2o_config_driver.context, &msg->u.head[2]);
-	writel(i2o_cntxt_list_add(c, fp->private_data), &msg->u.head[3]);
-	writel(kdesc.evt_mask, &msg->body[0]);
+	msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 |
+			kdesc.tid);
+	msg->u.head[2] = cpu_to_le32(i2o_config_driver.context);
+	msg->u.head[3] = cpu_to_le32(i2o_cntxt_list_add(c, fp->private_data));
+	msg->body[0] = cpu_to_le32(kdesc.evt_mask);
 
-	i2o_msg_post(c, m);
+	i2o_msg_post(c, msg);
 
 	return 0;
 }
@@ -537,7 +536,6 @@
 	u32 sg_index = 0;
 	i2o_status_block *sb;
 	struct i2o_message *msg;
-	u32 m;
 	unsigned int iop;
 
 	cmd = (struct i2o_cmd_passthru32 __user *)arg;
@@ -553,7 +551,7 @@
 		return -ENXIO;
 	}
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
 
 	sb = c->status_block.virt;
 
@@ -585,19 +583,15 @@
 	reply_size >>= 16;
 	reply_size <<= 2;
 
-	reply = kmalloc(reply_size, GFP_KERNEL);
+	reply = kzalloc(reply_size, GFP_KERNEL);
 	if (!reply) {
 		printk(KERN_WARNING "%s: Could not allocate reply buffer\n",
 		       c->name);
 		return -ENOMEM;
 	}
-	memset(reply, 0, reply_size);
 
 	sg_offset = (msg->u.head[0] >> 4) & 0x0f;
 
-	writel(i2o_config_driver.context, &msg->u.s.icntxt);
-	writel(i2o_cntxt_list_add(c, reply), &msg->u.s.tcntxt);
-
 	memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE);
 	if (sg_offset) {
 		struct sg_simple_element *sg;
@@ -631,7 +625,7 @@
 				goto cleanup;
 			}
 			sg_size = sg[i].flag_count & 0xffffff;
-			p = &(sg_list[sg_index++]);
+			p = &(sg_list[sg_index]);
 			/* Allocate memory for the transfer */
 			if (i2o_dma_alloc
 			    (&c->pdev->dev, p, sg_size,
@@ -642,6 +636,7 @@
 				rcode = -ENOMEM;
 				goto sg_list_cleanup;
 			}
+			sg_index++;
 			/* Copy in the user's SG buffer if necessary */
 			if (sg[i].
 			    flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
@@ -662,9 +657,11 @@
 		}
 	}
 
-	rcode = i2o_msg_post_wait(c, m, 60);
-	if (rcode)
+	rcode = i2o_msg_post_wait(c, msg, 60);
+	if (rcode) {
+		reply[4] = ((u32) rcode) << 24;
 		goto sg_list_cleanup;
+	}
 
 	if (sg_offset) {
 		u32 msg[I2O_OUTBOUND_MSG_FRAME_SIZE];
@@ -714,6 +711,7 @@
 		}
 	}
 
+      sg_list_cleanup:
 	/* Copy back the reply to user space */
 	if (reply_size) {
 		// we wrote our own values for context - now restore the user supplied ones
@@ -731,7 +729,6 @@
 		}
 	}
 
-      sg_list_cleanup:
 	for (i = 0; i < sg_index; i++)
 		i2o_dma_free(&c->pdev->dev, &sg_list[i]);
 
@@ -780,8 +777,7 @@
 	u32 i = 0;
 	void *p = NULL;
 	i2o_status_block *sb;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	unsigned int iop;
 
 	if (get_user(iop, &cmd->iop) || get_user(user_msg, &cmd->msg))
@@ -793,7 +789,7 @@
 		return -ENXIO;
 	}
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
 
 	sb = c->status_block.virt;
 
@@ -820,19 +816,15 @@
 	reply_size >>= 16;
 	reply_size <<= 2;
 
-	reply = kmalloc(reply_size, GFP_KERNEL);
+	reply = kzalloc(reply_size, GFP_KERNEL);
 	if (!reply) {
 		printk(KERN_WARNING "%s: Could not allocate reply buffer\n",
 		       c->name);
 		return -ENOMEM;
 	}
-	memset(reply, 0, reply_size);
 
 	sg_offset = (msg->u.head[0] >> 4) & 0x0f;
 
-	writel(i2o_config_driver.context, &msg->u.s.icntxt);
-	writel(i2o_cntxt_list_add(c, reply), &msg->u.s.tcntxt);
-
 	memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE);
 	if (sg_offset) {
 		struct sg_simple_element *sg;
@@ -894,9 +886,11 @@
 		}
 	}
 
-	rcode = i2o_msg_post_wait(c, m, 60);
-	if (rcode)
+	rcode = i2o_msg_post_wait(c, msg, 60);
+	if (rcode) {
+		reply[4] = ((u32) rcode) << 24;
 		goto sg_list_cleanup;
+	}
 
 	if (sg_offset) {
 		u32 msg[128];
@@ -946,6 +940,7 @@
 		}
 	}
 
+      sg_list_cleanup:
 	/* Copy back the reply to user space */
 	if (reply_size) {
 		// we wrote our own values for context - now restore the user supplied ones
@@ -962,7 +957,6 @@
 		}
 	}
 
-      sg_list_cleanup:
 	for (i = 0; i < sg_index; i++)
 		kfree(sg_list[i]);
 
diff --git a/drivers/message/i2o/i2o_lan.h b/drivers/message/i2o/i2o_lan.h
index 561d633..6502b81 100644
--- a/drivers/message/i2o/i2o_lan.h
+++ b/drivers/message/i2o/i2o_lan.h
@@ -103,14 +103,14 @@
 #define I2O_LAN_DSC_SUSPENDED			0x11
 
 struct i2o_packet_info {
-	u32 offset : 24;
-	u32 flags  : 8;
-	u32 len    : 24;
-	u32 status : 8;
+	u32 offset:24;
+	u32 flags:8;
+	u32 len:24;
+	u32 status:8;
 };
 
 struct i2o_bucket_descriptor {
-	u32 context; 			/* FIXME: 64bit support */
+	u32 context;		/* FIXME: 64bit support */
 	struct i2o_packet_info packet_info[1];
 };
 
@@ -127,14 +127,14 @@
 	u8 unit;
 	struct i2o_device *i2o_dev;
 
-	struct fddi_statistics stats;   /* see also struct net_device_stats */
-	unsigned short (*type_trans)(struct sk_buff *, struct net_device *);
-	atomic_t buckets_out;  		/* nbr of unused buckets on DDM */
-	atomic_t tx_out;		/* outstanding TXes */
-	u8 tx_count;  			/* packets in one TX message frame */
-	u16 tx_max_out;	   		/* DDM's Tx queue len */
-	u8 sgl_max;			/* max SGLs in one message frame */
-	u32 m;				/* IOP address of the batch msg frame */
+	struct fddi_statistics stats;	/* see also struct net_device_stats */
+	unsigned short (*type_trans) (struct sk_buff *, struct net_device *);
+	atomic_t buckets_out;	/* nbr of unused buckets on DDM */
+	atomic_t tx_out;	/* outstanding TXes */
+	u8 tx_count;		/* packets in one TX message frame */
+	u16 tx_max_out;		/* DDM's Tx queue len */
+	u8 sgl_max;		/* max SGLs in one message frame */
+	u32 m;			/* IOP address of the batch msg frame */
 
 	struct work_struct i2o_batch_send_task;
 	int send_active;
@@ -144,16 +144,16 @@
 
 	spinlock_t tx_lock;
 
-	u32 max_size_mc_table;		/* max number of multicast addresses */
+	u32 max_size_mc_table;	/* max number of multicast addresses */
 
 	/* LAN OSM configurable parameters are here: */
 
-	u16 max_buckets_out;		/* max nbr of buckets to send to DDM */
-	u16 bucket_thresh;		/* send more when this many used */
+	u16 max_buckets_out;	/* max nbr of buckets to send to DDM */
+	u16 bucket_thresh;	/* send more when this many used */
 	u16 rx_copybreak;
 
-	u8  tx_batch_mode;		/* Set when using batch mode sends */
-	u32 i2o_event_mask;		/* To turn on interesting event flags */
+	u8 tx_batch_mode;	/* Set when using batch mode sends */
+	u32 i2o_event_mask;	/* To turn on interesting event flags */
 };
 
-#endif /* _I2O_LAN_H */
+#endif				/* _I2O_LAN_H */
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index d559a17..2a0c42b 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -28,7 +28,7 @@
  */
 
 #define OSM_NAME	"proc-osm"
-#define OSM_VERSION	"1.145"
+#define OSM_VERSION	"1.316"
 #define OSM_DESCRIPTION	"I2O ProcFS OSM"
 
 #define I2O_MAX_MODULES 4
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index 9f1744c..f9e5a23 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -70,7 +70,7 @@
 #include <scsi/sg_request.h>
 
 #define OSM_NAME	"scsi-osm"
-#define OSM_VERSION	"1.282"
+#define OSM_VERSION	"1.316"
 #define OSM_DESCRIPTION	"I2O SCSI Peripheral OSM"
 
 static struct i2o_driver i2o_scsi_driver;
@@ -113,7 +113,7 @@
 
 	list_for_each_entry(i2o_dev, &c->devices, list)
 	    if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
-		if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
+		if (!i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
 		    && (type == 0x01))	/* SCSI bus */
 			max_channel++;
 	}
@@ -146,7 +146,7 @@
 	i = 0;
 	list_for_each_entry(i2o_dev, &c->devices, list)
 	    if (i2o_dev->lct_data.class_id == I2O_CLASS_BUS_ADAPTER) {
-		if (i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
+		if (!i2o_parm_field_get(i2o_dev, 0x0000, 0, &type, 1)
 		    && (type == 0x01))	/* only SCSI bus */
 			i2o_shost->channel[i++] = i2o_dev;
 
@@ -238,13 +238,15 @@
 			u8 type;
 			struct i2o_device *d = i2o_shost->channel[0];
 
-			if (i2o_parm_field_get(d, 0x0000, 0, &type, 1)
+			if (!i2o_parm_field_get(d, 0x0000, 0, &type, 1)
 			    && (type == 0x01))	/* SCSI bus */
-				if (i2o_parm_field_get(d, 0x0200, 4, &id, 4)) {
+				if (!i2o_parm_field_get(d, 0x0200, 4, &id, 4)) {
 					channel = 0;
 					if (i2o_dev->lct_data.class_id ==
 					    I2O_CLASS_RANDOM_BLOCK_STORAGE)
-						lun = i2o_shost->lun++;
+						lun =
+						    cpu_to_le64(i2o_shost->
+								lun++);
 					else
 						lun = 0;
 				}
@@ -253,10 +255,10 @@
 		break;
 
 	case I2O_CLASS_SCSI_PERIPHERAL:
-		if (i2o_parm_field_get(i2o_dev, 0x0000, 3, &id, 4) < 0)
+		if (i2o_parm_field_get(i2o_dev, 0x0000, 3, &id, 4))
 			return -EFAULT;
 
-		if (i2o_parm_field_get(i2o_dev, 0x0000, 4, &lun, 8) < 0)
+		if (i2o_parm_field_get(i2o_dev, 0x0000, 4, &lun, 8))
 			return -EFAULT;
 
 		parent = i2o_iop_find_device(c, i2o_dev->lct_data.parent_tid);
@@ -281,20 +283,22 @@
 		return -EFAULT;
 	}
 
-	if (id >= scsi_host->max_id) {
-		osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)", id,
-			 scsi_host->max_id);
+	if (le32_to_cpu(id) >= scsi_host->max_id) {
+		osm_warn("SCSI device id (%d) >= max_id of I2O host (%d)",
+			 le32_to_cpu(id), scsi_host->max_id);
 		return -EFAULT;
 	}
 
-	if (lun >= scsi_host->max_lun) {
-		osm_warn("SCSI device id (%d) >= max_lun of I2O host (%d)",
-			 (unsigned int)lun, scsi_host->max_lun);
+	if (le64_to_cpu(lun) >= scsi_host->max_lun) {
+		osm_warn("SCSI device lun (%lu) >= max_lun of I2O host (%d)",
+			 (long unsigned int)le64_to_cpu(lun),
+			 scsi_host->max_lun);
 		return -EFAULT;
 	}
 
 	scsi_dev =
-	    __scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev);
+	    __scsi_add_device(i2o_shost->scsi_host, channel, le32_to_cpu(id),
+			      le64_to_cpu(lun), i2o_dev);
 
 	if (IS_ERR(scsi_dev)) {
 		osm_warn("can not add SCSI device %03x\n",
@@ -305,8 +309,9 @@
 	sysfs_create_link(&i2o_dev->device.kobj, &scsi_dev->sdev_gendev.kobj,
 			  "scsi");
 
-	osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %d\n",
-		 i2o_dev->lct_data.tid, channel, id, (unsigned int)lun);
+	osm_info("device added (TID: %03x) channel: %d, id: %d, lun: %ld\n",
+		 i2o_dev->lct_data.tid, channel, le32_to_cpu(id),
+		 (long unsigned int)le64_to_cpu(lun));
 
 	return 0;
 };
@@ -510,8 +515,7 @@
 	struct i2o_controller *c;
 	struct i2o_device *i2o_dev;
 	int tid;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	/*
 	 * ENABLE_DISCONNECT
 	 * SIMPLE_TAG
@@ -519,7 +523,7 @@
 	 */
 	u32 scsi_flags = 0x20a00000;
 	u32 sgl_offset;
-	u32 __iomem *mptr;
+	u32 *mptr;
 	u32 cmd = I2O_CMD_SCSI_EXEC << 24;
 	int rc = 0;
 
@@ -576,8 +580,8 @@
 	 *      throw it back to the scsi layer
 	 */
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY) {
+	msg = i2o_msg_get(c);
+	if (IS_ERR(msg)) {
 		rc = SCSI_MLQUEUE_HOST_BUSY;
 		goto exit;
 	}
@@ -617,16 +621,16 @@
 		if (sgl_offset == SGL_OFFSET_10)
 			sgl_offset = SGL_OFFSET_12;
 		cmd = I2O_CMD_PRIVATE << 24;
-		writel(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC, mptr++);
-		writel(adpt_flags | tid, mptr++);
+		*mptr++ = cpu_to_le32(I2O_VENDOR_DPT << 16 | I2O_CMD_SCSI_EXEC);
+		*mptr++ = cpu_to_le32(adpt_flags | tid);
 	}
 #endif
 
-	writel(cmd | HOST_TID << 12 | tid, &msg->u.head[1]);
-	writel(i2o_scsi_driver.context, &msg->u.s.icntxt);
+	msg->u.head[1] = cpu_to_le32(cmd | HOST_TID << 12 | tid);
+	msg->u.s.icntxt = cpu_to_le32(i2o_scsi_driver.context);
 
 	/* We want the SCSI control block back */
-	writel(i2o_cntxt_list_add(c, SCpnt), &msg->u.s.tcntxt);
+	msg->u.s.tcntxt = cpu_to_le32(i2o_cntxt_list_add(c, SCpnt));
 
 	/* LSI_920_PCI_QUIRK
 	 *
@@ -649,15 +653,15 @@
 	   }
 	 */
 
-	writel(scsi_flags | SCpnt->cmd_len, mptr++);
+	*mptr++ = cpu_to_le32(scsi_flags | SCpnt->cmd_len);
 
 	/* Write SCSI command into the message - always 16 byte block */
-	memcpy_toio(mptr, SCpnt->cmnd, 16);
+	memcpy(mptr, SCpnt->cmnd, 16);
 	mptr += 4;
 
 	if (sgl_offset != SGL_OFFSET_0) {
 		/* write size of data addressed by SGL */
-		writel(SCpnt->request_bufflen, mptr++);
+		*mptr++ = cpu_to_le32(SCpnt->request_bufflen);
 
 		/* Now fill in the SGList and command */
 		if (SCpnt->use_sg) {
@@ -676,11 +680,11 @@
 	}
 
 	/* Stick the headers on */
-	writel(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset,
-	       &msg->u.head[0]);
+	msg->u.head[0] =
+	    cpu_to_le32(I2O_MESSAGE_SIZE(mptr - &msg->u.head[0]) | sgl_offset);
 
 	/* Queue the message */
-	i2o_msg_post(c, m);
+	i2o_msg_post(c, msg);
 
 	osm_debug("Issued %ld\n", SCpnt->serial_number);
 
@@ -688,7 +692,7 @@
 
       nomem:
 	rc = -ENOMEM;
-	i2o_msg_nop(c, m);
+	i2o_msg_nop(c, msg);
 
       exit:
 	return rc;
@@ -709,8 +713,7 @@
 {
 	struct i2o_device *i2o_dev;
 	struct i2o_controller *c;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	int tid;
 	int status = FAILED;
 
@@ -720,16 +723,16 @@
 	c = i2o_dev->iop;
 	tid = i2o_dev->lct_data.tid;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
 		return SCSI_MLQUEUE_HOST_BUSY;
 
-	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid,
-	       &msg->u.head[1]);
-	writel(i2o_cntxt_list_get_ptr(c, SCpnt), &msg->body[0]);
+	msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid);
+	msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt));
 
-	if (i2o_msg_post_wait(c, m, I2O_TIMEOUT_SCSI_SCB_ABORT))
+	if (i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT))
 		status = SUCCESS;
 
 	return status;
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 4eb5325..4921674 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -32,7 +32,7 @@
 #include "core.h"
 
 #define OSM_NAME	"i2o"
-#define OSM_VERSION	"1.288"
+#define OSM_VERSION	"1.325"
 #define OSM_DESCRIPTION	"I2O subsystem"
 
 /* global I2O controller list */
@@ -47,27 +47,6 @@
 static int i2o_hrt_get(struct i2o_controller *c);
 
 /**
- *	i2o_msg_nop - Returns a message which is not used
- *	@c: I2O controller from which the message was created
- *	@m: message which should be returned
- *
- *	If you fetch a message via i2o_msg_get, and can't use it, you must
- *	return the message with this function. Otherwise the message frame
- *	is lost.
- */
-void i2o_msg_nop(struct i2o_controller *c, u32 m)
-{
-	struct i2o_message __iomem *msg = i2o_msg_in_to_virt(c, m);
-
-	writel(THREE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
-	writel(0, &msg->u.head[2]);
-	writel(0, &msg->u.head[3]);
-	i2o_msg_post(c, m);
-};
-
-/**
  *	i2o_msg_get_wait - obtain an I2O message from the IOP
  *	@c: I2O controller
  *	@msg: pointer to a I2O message pointer
@@ -81,22 +60,21 @@
  *	address from the read port (see the i2o spec). If no message is
  *	available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
  */
-u32 i2o_msg_get_wait(struct i2o_controller *c,
-		     struct i2o_message __iomem ** msg, int wait)
+struct i2o_message *i2o_msg_get_wait(struct i2o_controller *c, int wait)
 {
 	unsigned long timeout = jiffies + wait * HZ;
-	u32 m;
+	struct i2o_message *msg;
 
-	while ((m = i2o_msg_get(c, msg)) == I2O_QUEUE_EMPTY) {
+	while (IS_ERR(msg = i2o_msg_get(c))) {
 		if (time_after(jiffies, timeout)) {
 			osm_debug("%s: Timeout waiting for message frame.\n",
 				  c->name);
-			return I2O_QUEUE_EMPTY;
+			return ERR_PTR(-ETIMEDOUT);
 		}
 		schedule_timeout_uninterruptible(1);
 	}
 
-	return m;
+	return msg;
 };
 
 #if BITS_PER_LONG == 64
@@ -301,8 +279,7 @@
  */
 static int i2o_iop_quiesce(struct i2o_controller *c)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	i2o_status_block *sb = c->status_block.virt;
 	int rc;
 
@@ -313,16 +290,17 @@
 	    (sb->iop_state != ADAPTER_STATE_OPERATIONAL))
 		return 0;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_SYS_QUIESCE << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
+	msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_SYS_QUIESCE << 24 | HOST_TID << 12 |
+			ADAPTER_TID);
 
 	/* Long timeout needed for quiesce if lots of devices */
-	if ((rc = i2o_msg_post_wait(c, m, 240)))
+	if ((rc = i2o_msg_post_wait(c, msg, 240)))
 		osm_info("%s: Unable to quiesce (status=%#x).\n", c->name, -rc);
 	else
 		osm_debug("%s: Quiesced.\n", c->name);
@@ -342,8 +320,7 @@
  */
 static int i2o_iop_enable(struct i2o_controller *c)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	i2o_status_block *sb = c->status_block.virt;
 	int rc;
 
@@ -353,16 +330,17 @@
 	if (sb->iop_state != ADAPTER_STATE_READY)
 		return -EINVAL;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_SYS_ENABLE << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
+	msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_SYS_ENABLE << 24 | HOST_TID << 12 |
+			ADAPTER_TID);
 
 	/* How long of a timeout do we need? */
-	if ((rc = i2o_msg_post_wait(c, m, 240)))
+	if ((rc = i2o_msg_post_wait(c, msg, 240)))
 		osm_err("%s: Could not enable (status=%#x).\n", c->name, -rc);
 	else
 		osm_debug("%s: Enabled.\n", c->name);
@@ -413,22 +391,22 @@
  */
 static int i2o_iop_clear(struct i2o_controller *c)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	int rc;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
 	/* Quiesce all IOPs first */
 	i2o_iop_quiesce_all();
 
-	writel(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_ADAPTER_CLEAR << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
+	msg->u.head[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_ADAPTER_CLEAR << 24 | HOST_TID << 12 |
+			ADAPTER_TID);
 
-	if ((rc = i2o_msg_post_wait(c, m, 30)))
+	if ((rc = i2o_msg_post_wait(c, msg, 30)))
 		osm_info("%s: Unable to clear (status=%#x).\n", c->name, -rc);
 	else
 		osm_debug("%s: Cleared.\n", c->name);
@@ -446,13 +424,13 @@
  *	Clear and (re)initialize IOP's outbound queue and post the message
  *	frames to the IOP.
  *
- *	Returns 0 on success or a negative errno code on failure.
+ *	Returns 0 on success or negative error code on failure.
  */
 static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
 {
-	volatile u8 *status = c->status.virt;
 	u32 m;
-	struct i2o_message __iomem *msg;
+	volatile u8 *status = c->status.virt;
+	struct i2o_message *msg;
 	ulong timeout;
 	int i;
 
@@ -460,23 +438,24 @@
 
 	memset(c->status.virt, 0, 4);
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6, &msg->u.head[0]);
-	writel(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
-	writel(i2o_exec_driver.context, &msg->u.s.icntxt);
-	writel(0x00000000, &msg->u.s.tcntxt);
-	writel(PAGE_SIZE, &msg->body[0]);
+	msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_6);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 |
+			ADAPTER_TID);
+	msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
+	msg->u.s.tcntxt = cpu_to_le32(0x00000000);
+	msg->body[0] = cpu_to_le32(PAGE_SIZE);
 	/* Outbound msg frame size in words and Initcode */
-	writel(I2O_OUTBOUND_MSG_FRAME_SIZE << 16 | 0x80, &msg->body[1]);
-	writel(0xd0000004, &msg->body[2]);
-	writel(i2o_dma_low(c->status.phys), &msg->body[3]);
-	writel(i2o_dma_high(c->status.phys), &msg->body[4]);
+	msg->body[1] = cpu_to_le32(I2O_OUTBOUND_MSG_FRAME_SIZE << 16 | 0x80);
+	msg->body[2] = cpu_to_le32(0xd0000004);
+	msg->body[3] = cpu_to_le32(i2o_dma_low(c->status.phys));
+	msg->body[4] = cpu_to_le32(i2o_dma_high(c->status.phys));
 
-	i2o_msg_post(c, m);
+	i2o_msg_post(c, msg);
 
 	timeout = jiffies + I2O_TIMEOUT_INIT_OUTBOUND_QUEUE * HZ;
 	while (*status <= I2O_CMD_IN_PROGRESS) {
@@ -511,34 +490,34 @@
 static int i2o_iop_reset(struct i2o_controller *c)
 {
 	volatile u8 *status = c->status.virt;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	unsigned long timeout;
 	i2o_status_block *sb = c->status_block.virt;
 	int rc = 0;
 
 	osm_debug("%s: Resetting controller\n", c->name);
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
 	memset(c->status_block.virt, 0, 8);
 
 	/* Quiesce all IOPs first */
 	i2o_iop_quiesce_all();
 
-	writel(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_ADAPTER_RESET << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
-	writel(i2o_exec_driver.context, &msg->u.s.icntxt);
-	writel(0, &msg->u.s.tcntxt);	//FIXME: use reasonable transaction context
-	writel(0, &msg->body[0]);
-	writel(0, &msg->body[1]);
-	writel(i2o_dma_low(c->status.phys), &msg->body[2]);
-	writel(i2o_dma_high(c->status.phys), &msg->body[3]);
+	msg->u.head[0] = cpu_to_le32(EIGHT_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_ADAPTER_RESET << 24 | HOST_TID << 12 |
+			ADAPTER_TID);
+	msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
+	msg->u.s.tcntxt = cpu_to_le32(0x00000000);
+	msg->body[0] = cpu_to_le32(0x00000000);
+	msg->body[1] = cpu_to_le32(0x00000000);
+	msg->body[2] = cpu_to_le32(i2o_dma_low(c->status.phys));
+	msg->body[3] = cpu_to_le32(i2o_dma_high(c->status.phys));
 
-	i2o_msg_post(c, m);
+	i2o_msg_post(c, msg);
 
 	/* Wait for a reply */
 	timeout = jiffies + I2O_TIMEOUT_RESET * HZ;
@@ -567,18 +546,15 @@
 		osm_debug("%s: Reset in progress, waiting for reboot...\n",
 			  c->name);
 
-		m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
-		while (m == I2O_QUEUE_EMPTY) {
+		while (IS_ERR(msg = i2o_msg_get_wait(c, I2O_TIMEOUT_RESET))) {
 			if (time_after(jiffies, timeout)) {
 				osm_err("%s: IOP reset timeout.\n", c->name);
-				rc = -ETIMEDOUT;
+				rc = PTR_ERR(msg);
 				goto exit;
 			}
 			schedule_timeout_uninterruptible(1);
-
-			m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
 		}
-		i2o_msg_nop(c, m);
+		i2o_msg_nop(c, msg);
 
 		/* from here all quiesce commands are safe */
 		c->no_quiesce = 0;
@@ -686,8 +662,7 @@
  */
 static int i2o_iop_systab_set(struct i2o_controller *c)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	i2o_status_block *sb = c->status_block.virt;
 	struct device *dev = &c->pdev->dev;
 	struct resource *root;
@@ -735,41 +710,38 @@
 		}
 	}
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
 	i2o_systab.phys = dma_map_single(dev, i2o_systab.virt, i2o_systab.len,
 					 PCI_DMA_TODEVICE);
 	if (!i2o_systab.phys) {
-		i2o_msg_nop(c, m);
+		i2o_msg_nop(c, msg);
 		return -ENOMEM;
 	}
 
-	writel(I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6, &msg->u.head[0]);
-	writel(I2O_CMD_SYS_TAB_SET << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
+	msg->u.head[0] = cpu_to_le32(I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_SYS_TAB_SET << 24 | HOST_TID << 12 |
+			ADAPTER_TID);
 
 	/*
 	 * Provide three SGL-elements:
 	 * System table (SysTab), Private memory space declaration and
 	 * Private i/o space declaration
-	 *
-	 * FIXME: is this still true?
-	 * Nasty one here. We can't use dma_alloc_coherent to send the
-	 * same table to everyone. We have to go remap it for them all
 	 */
 
-	writel(c->unit + 2, &msg->body[0]);
-	writel(0, &msg->body[1]);
-	writel(0x54000000 | i2o_systab.len, &msg->body[2]);
-	writel(i2o_systab.phys, &msg->body[3]);
-	writel(0x54000000 | sb->current_mem_size, &msg->body[4]);
-	writel(sb->current_mem_base, &msg->body[5]);
-	writel(0xd4000000 | sb->current_io_size, &msg->body[6]);
-	writel(sb->current_io_base, &msg->body[6]);
+	msg->body[0] = cpu_to_le32(c->unit + 2);
+	msg->body[1] = cpu_to_le32(0x00000000);
+	msg->body[2] = cpu_to_le32(0x54000000 | i2o_systab.len);
+	msg->body[3] = cpu_to_le32(i2o_systab.phys);
+	msg->body[4] = cpu_to_le32(0x54000000 | sb->current_mem_size);
+	msg->body[5] = cpu_to_le32(sb->current_mem_base);
+	msg->body[6] = cpu_to_le32(0xd4000000 | sb->current_io_size);
+	msg->body[6] = cpu_to_le32(sb->current_io_base);
 
-	rc = i2o_msg_post_wait(c, m, 120);
+	rc = i2o_msg_post_wait(c, msg, 120);
 
 	dma_unmap_single(dev, i2o_systab.phys, i2o_systab.len,
 			 PCI_DMA_TODEVICE);
@@ -780,8 +752,6 @@
 	else
 		osm_debug("%s: SysTab set.\n", c->name);
 
-	i2o_status_get(c);	// Entered READY state
-
 	return rc;
 }
 
@@ -791,7 +761,7 @@
  *
  *	Send the system table and enable the I2O controller.
  *
- *	Returns 0 on success or negativer error code on failure.
+ *	Returns 0 on success or negative error code on failure.
  */
 static int i2o_iop_online(struct i2o_controller *c)
 {
@@ -830,7 +800,6 @@
 	list_for_each_entry_safe(dev, tmp, &c->devices, list)
 	    i2o_device_remove(dev);
 
-	class_device_unregister(c->classdev);
 	device_del(&c->device);
 
 	/* Ask the IOP to switch to RESET state */
@@ -869,12 +838,11 @@
 	i2o_systab.len = sizeof(struct i2o_sys_tbl) + num_controllers *
 	    sizeof(struct i2o_sys_tbl_entry);
 
-	systab = i2o_systab.virt = kmalloc(i2o_systab.len, GFP_KERNEL);
+	systab = i2o_systab.virt = kzalloc(i2o_systab.len, GFP_KERNEL);
 	if (!systab) {
 		osm_err("unable to allocate memory for System Table\n");
 		return -ENOMEM;
 	}
-	memset(systab, 0, i2o_systab.len);
 
 	systab->version = I2OVERSION;
 	systab->change_ind = change_ind + 1;
@@ -952,30 +920,30 @@
  */
 int i2o_status_get(struct i2o_controller *c)
 {
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 	volatile u8 *status_block;
 	unsigned long timeout;
 
 	status_block = (u8 *) c->status_block.virt;
 	memset(c->status_block.virt, 0, sizeof(i2o_status_block));
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_STATUS_GET << 24 | HOST_TID << 12 | ADAPTER_TID,
-	       &msg->u.head[1]);
-	writel(i2o_exec_driver.context, &msg->u.s.icntxt);
-	writel(0, &msg->u.s.tcntxt);	// FIXME: use resonable transaction context
-	writel(0, &msg->body[0]);
-	writel(0, &msg->body[1]);
-	writel(i2o_dma_low(c->status_block.phys), &msg->body[2]);
-	writel(i2o_dma_high(c->status_block.phys), &msg->body[3]);
-	writel(sizeof(i2o_status_block), &msg->body[4]);	/* always 88 bytes */
+	msg->u.head[0] = cpu_to_le32(NINE_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_STATUS_GET << 24 | HOST_TID << 12 |
+			ADAPTER_TID);
+	msg->u.s.icntxt = cpu_to_le32(i2o_exec_driver.context);
+	msg->u.s.tcntxt = cpu_to_le32(0x00000000);
+	msg->body[0] = cpu_to_le32(0x00000000);
+	msg->body[1] = cpu_to_le32(0x00000000);
+	msg->body[2] = cpu_to_le32(i2o_dma_low(c->status_block.phys));
+	msg->body[3] = cpu_to_le32(i2o_dma_high(c->status_block.phys));
+	msg->body[4] = cpu_to_le32(sizeof(i2o_status_block));	/* always 88 bytes */
 
-	i2o_msg_post(c, m);
+	i2o_msg_post(c, msg);
 
 	/* Wait for a reply */
 	timeout = jiffies + I2O_TIMEOUT_STATUS_GET * HZ;
@@ -1002,7 +970,7 @@
  *	The HRT contains information about possible hidden devices but is
  *	mostly useless to us.
  *
- *	Returns 0 on success or negativer error code on failure.
+ *	Returns 0 on success or negative error code on failure.
  */
 static int i2o_hrt_get(struct i2o_controller *c)
 {
@@ -1013,20 +981,20 @@
 	struct device *dev = &c->pdev->dev;
 
 	for (i = 0; i < I2O_HRT_GET_TRIES; i++) {
-		struct i2o_message __iomem *msg;
-		u32 m;
+		struct i2o_message *msg;
 
-		m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-		if (m == I2O_QUEUE_EMPTY)
-			return -ETIMEDOUT;
+		msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+		if (IS_ERR(msg))
+			return PTR_ERR(msg);
 
-		writel(SIX_WORD_MSG_SIZE | SGL_OFFSET_4, &msg->u.head[0]);
-		writel(I2O_CMD_HRT_GET << 24 | HOST_TID << 12 | ADAPTER_TID,
-		       &msg->u.head[1]);
-		writel(0xd0000000 | c->hrt.len, &msg->body[0]);
-		writel(c->hrt.phys, &msg->body[1]);
+		msg->u.head[0] = cpu_to_le32(SIX_WORD_MSG_SIZE | SGL_OFFSET_4);
+		msg->u.head[1] =
+		    cpu_to_le32(I2O_CMD_HRT_GET << 24 | HOST_TID << 12 |
+				ADAPTER_TID);
+		msg->body[0] = cpu_to_le32(0xd0000000 | c->hrt.len);
+		msg->body[1] = cpu_to_le32(c->hrt.phys);
 
-		rc = i2o_msg_post_wait_mem(c, m, 20, &c->hrt);
+		rc = i2o_msg_post_wait_mem(c, msg, 20, &c->hrt);
 
 		if (rc < 0) {
 			osm_err("%s: Unable to get HRT (status=%#x)\n", c->name,
@@ -1051,15 +1019,6 @@
 }
 
 /**
- *	i2o_iop_free - Free the i2o_controller struct
- *	@c: I2O controller to free
- */
-void i2o_iop_free(struct i2o_controller *c)
-{
-	kfree(c);
-};
-
-/**
  *	i2o_iop_release - release the memory for a I2O controller
  *	@dev: I2O controller which should be released
  *
@@ -1073,14 +1032,11 @@
 	i2o_iop_free(c);
 };
 
-/* I2O controller class */
-static struct class *i2o_controller_class;
-
 /**
  *	i2o_iop_alloc - Allocate and initialize a i2o_controller struct
  *
  *	Allocate the necessary memory for a i2o_controller struct and
- *	initialize the lists.
+ *	initialize the lists and message mempool.
  *
  *	Returns a pointer to the I2O controller or a negative error code on
  *	failure.
@@ -1089,20 +1045,29 @@
 {
 	static int unit = 0;	/* 0 and 1 are NULL IOP and Local Host */
 	struct i2o_controller *c;
+	char poolname[32];
 
-	c = kmalloc(sizeof(*c), GFP_KERNEL);
+	c = kzalloc(sizeof(*c), GFP_KERNEL);
 	if (!c) {
 		osm_err("i2o: Insufficient memory to allocate a I2O controller."
 			"\n");
 		return ERR_PTR(-ENOMEM);
 	}
-	memset(c, 0, sizeof(*c));
+
+	c->unit = unit++;
+	sprintf(c->name, "iop%d", c->unit);
+
+	snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name);
+	if (i2o_pool_alloc
+	    (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4,
+	     I2O_MSG_INPOOL_MIN)) {
+		kfree(c);
+		return ERR_PTR(-ENOMEM);
+	};
 
 	INIT_LIST_HEAD(&c->devices);
 	spin_lock_init(&c->lock);
 	init_MUTEX(&c->lct_lock);
-	c->unit = unit++;
-	sprintf(c->name, "iop%d", c->unit);
 
 	device_initialize(&c->device);
 
@@ -1137,36 +1102,29 @@
 		goto iop_reset;
 	}
 
-	c->classdev = class_device_create(i2o_controller_class, NULL, MKDEV(0,0),
-			&c->device, "iop%d", c->unit);
-	if (IS_ERR(c->classdev)) {
-		osm_err("%s: could not add controller class\n", c->name);
-		goto device_del;
-	}
-
 	osm_info("%s: Activating I2O controller...\n", c->name);
 	osm_info("%s: This may take a few minutes if there are many devices\n",
 		 c->name);
 
 	if ((rc = i2o_iop_activate(c))) {
 		osm_err("%s: could not activate controller\n", c->name);
-		goto class_del;
+		goto device_del;
 	}
 
 	osm_debug("%s: building sys table...\n", c->name);
 
 	if ((rc = i2o_systab_build()))
-		goto class_del;
+		goto device_del;
 
 	osm_debug("%s: online controller...\n", c->name);
 
 	if ((rc = i2o_iop_online(c)))
-		goto class_del;
+		goto device_del;
 
 	osm_debug("%s: getting LCT...\n", c->name);
 
 	if ((rc = i2o_exec_lct_get(c)))
-		goto class_del;
+		goto device_del;
 
 	list_add(&c->list, &i2o_controllers);
 
@@ -1176,9 +1134,6 @@
 
 	return 0;
 
-      class_del:
-	class_device_unregister(c->classdev);
-
       device_del:
 	device_del(&c->device);
 
@@ -1199,28 +1154,27 @@
  *	is waited for, or expected. If you do not want further notifications,
  *	call the i2o_event_register again with a evt_mask of 0.
  *
- *	Returns 0 on success or -ETIMEDOUT if no message could be fetched for
- *	sending the request.
+ *	Returns 0 on success or negative error code on failure.
  */
 int i2o_event_register(struct i2o_device *dev, struct i2o_driver *drv,
 		       int tcntxt, u32 evt_mask)
 {
 	struct i2o_controller *c = dev->iop;
-	struct i2o_message __iomem *msg;
-	u32 m;
+	struct i2o_message *msg;
 
-	m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
-	if (m == I2O_QUEUE_EMPTY)
-		return -ETIMEDOUT;
+	msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
+	if (IS_ERR(msg))
+		return PTR_ERR(msg);
 
-	writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
-	writel(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | dev->lct_data.
-	       tid, &msg->u.head[1]);
-	writel(drv->context, &msg->u.s.icntxt);
-	writel(tcntxt, &msg->u.s.tcntxt);
-	writel(evt_mask, &msg->body[0]);
+	msg->u.head[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0);
+	msg->u.head[1] =
+	    cpu_to_le32(I2O_CMD_UTIL_EVT_REGISTER << 24 | HOST_TID << 12 | dev->
+			lct_data.tid);
+	msg->u.s.icntxt = cpu_to_le32(drv->context);
+	msg->u.s.tcntxt = cpu_to_le32(tcntxt);
+	msg->body[0] = cpu_to_le32(evt_mask);
 
-	i2o_msg_post(c, m);
+	i2o_msg_post(c, msg);
 
 	return 0;
 };
@@ -1239,14 +1193,8 @@
 
 	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
-	i2o_controller_class = class_create(THIS_MODULE, "i2o_controller");
-	if (IS_ERR(i2o_controller_class)) {
-		osm_err("can't register class i2o_controller\n");
-		goto exit;
-	}
-
 	if ((rc = i2o_driver_init()))
-		goto class_exit;
+		goto exit;
 
 	if ((rc = i2o_exec_init()))
 		goto driver_exit;
@@ -1262,9 +1210,6 @@
       driver_exit:
 	i2o_driver_exit();
 
-      class_exit:
-	class_destroy(i2o_controller_class);
-
       exit:
 	return rc;
 }
@@ -1279,7 +1224,6 @@
 	i2o_pci_exit();
 	i2o_exec_exit();
 	i2o_driver_exit();
-	class_destroy(i2o_controller_class);
 };
 
 module_init(i2o_iop_init);
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 81ef306..c5b656c 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -303,6 +303,7 @@
 	struct i2o_controller *c;
 	int rc;
 	struct pci_dev *i960 = NULL;
+	int pci_dev_busy = 0;
 
 	printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n");
 
@@ -338,7 +339,7 @@
 		       pci_name(pdev));
 
 	c->pdev = pdev;
-	c->device.parent = get_device(&pdev->dev);
+	c->device.parent = &pdev->dev;
 
 	/* Cards that fall apart if you hit them with large I/O loads... */
 	if (pdev->vendor == PCI_VENDOR_ID_NCR && pdev->device == 0x0630) {
@@ -395,6 +396,8 @@
 	if ((rc = i2o_pci_alloc(c))) {
 		printk(KERN_ERR "%s: DMA / IO allocation for I2O controller "
 		       " failed\n", c->name);
+		if (rc == -ENODEV)
+			pci_dev_busy = 1;
 		goto free_controller;
 	}
 
@@ -407,8 +410,6 @@
 	if ((rc = i2o_iop_add(c)))
 		goto uninstall;
 
-	get_device(&c->device);
-
 	if (i960)
 		pci_write_config_word(i960, 0x42, 0x03ff);
 
@@ -421,11 +422,11 @@
 	i2o_pci_free(c);
 
       free_controller:
-	put_device(c->device.parent);
 	i2o_iop_free(c);
 
       disable:
-	pci_disable_device(pdev);
+	if (!pci_dev_busy)
+		pci_disable_device(pdev);
 
 	return rc;
 }
@@ -450,7 +451,6 @@
 
 	printk(KERN_INFO "%s: Controller removed.\n", c->name);
 
-	put_device(c->device.parent);
 	put_device(&c->device);
 };
 
@@ -479,4 +479,5 @@
 {
 	pci_unregister_driver(&i2o_pci_driver);
 };
+
 MODULE_DEVICE_TABLE(pci, i2o_pci_ids);
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index e335d54..b42e0fb 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -27,7 +27,6 @@
 
 #include <asm/dma.h>
 #include <asm/hardware.h>
-#include <asm/irq.h>
 
 #include "ucb1x00.h"
 
@@ -507,14 +506,14 @@
 		goto err_free;
 	}
 
-	ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb);
+	ret = request_irq(ucb->irq, ucb1x00_irq, SA_TRIGGER_RISING,
+			  "UCB1x00", ucb);
 	if (ret) {
 		printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
 			ucb->irq, ret);
 		goto err_free;
 	}
 
-	set_irq_type(ucb->irq, IRQT_RISING);
 	mcp_set_drvdata(mcp, ucb);
 
 	ret = class_device_register(&ucb->cdev);
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index a984c0e..79fd062 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -32,7 +32,6 @@
 #include <linux/suspend.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
-#include <linux/delay.h>
 
 #include <asm/dma.h>
 #include <asm/semaphore.h>
@@ -59,16 +58,18 @@
 
 static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
 {
-	input_report_abs(ts->idev, ABS_X, x);
-	input_report_abs(ts->idev, ABS_Y, y);
-	input_report_abs(ts->idev, ABS_PRESSURE, pressure);
-	input_sync(ts->idev);
+	struct input_dev *idev = ts->idev;
+	input_report_abs(idev, ABS_X, x);
+	input_report_abs(idev, ABS_Y, y);
+	input_report_abs(idev, ABS_PRESSURE, pressure);
+	input_sync(idev);
 }
 
 static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
 {
-	input_report_abs(ts->idev, ABS_PRESSURE, 0);
-	input_sync(ts->idev);
+	struct input_dev *idev = ts->idev;
+	input_report_abs(idev, ABS_PRESSURE, 0);
+	input_sync(idev);
 }
 
 /*
@@ -297,7 +298,7 @@
 
 static int ucb1x00_ts_open(struct input_dev *idev)
 {
-	struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
+	struct ucb1x00_ts *ts = idev->private;
 	int ret = 0;
 
 	BUG_ON(ts->rtask);
@@ -334,7 +335,7 @@
  */
 static void ucb1x00_ts_close(struct input_dev *idev)
 {
-	struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
+	struct ucb1x00_ts *ts = idev->private;
 
 	if (ts->rtask)
 		kthread_stop(ts->rtask);
@@ -386,6 +387,7 @@
 	ts->ucb = dev->ucb;
 	ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
 
+	ts->idev->private = ts;
 	ts->idev->name       = "Touchscreen panel";
 	ts->idev->id.product = ts->ucb->id;
 	ts->idev->open       = ucb1x00_ts_open;
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
index d7e20a3..1cef238 100644
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -141,8 +141,8 @@
 };
 
 struct ibmasm_remote {
-	struct input_dev keybd_dev;
-	struct input_dev mouse_dev;
+	struct input_dev *keybd_dev;
+	struct input_dev *mouse_dev;
 };
 
 struct service_processor {
@@ -157,7 +157,7 @@
 	char			dirname[IBMASM_NAME_SIZE];
 	char			devname[IBMASM_NAME_SIZE];
 	unsigned int		number;
-	struct ibmasm_remote	*remote;
+	struct ibmasm_remote	remote;
 	int			serial_line;
 	struct device		*dev;
 };
diff --git a/drivers/misc/ibmasm/remote.c b/drivers/misc/ibmasm/remote.c
index d3c48d2..1abd0c5 100644
--- a/drivers/misc/ibmasm/remote.c
+++ b/drivers/misc/ibmasm/remote.c
@@ -203,9 +203,9 @@
 
 		print_input(&input);
 		if (input.type == INPUT_TYPE_MOUSE) {
-			send_mouse_event(&sp->remote->mouse_dev, regs, &input);
+			send_mouse_event(sp->remote.mouse_dev, regs, &input);
 		} else if (input.type == INPUT_TYPE_KEYBOARD) {
-			send_keyboard_event(&sp->remote->keybd_dev, regs, &input);
+			send_keyboard_event(sp->remote.keybd_dev, regs, &input);
 		} else
 			break;
 
@@ -217,56 +217,70 @@
 int ibmasm_init_remote_input_dev(struct service_processor *sp)
 {
 	/* set up the mouse input device */
-	struct ibmasm_remote *remote;
+	struct input_dev *mouse_dev, *keybd_dev;
 	struct pci_dev *pdev = to_pci_dev(sp->dev);
+	int error = -ENOMEM;
 	int i;
 
-	sp->remote = remote = kmalloc(sizeof(*remote), GFP_KERNEL);
-	if (!remote)
-		return -ENOMEM;
+	sp->remote.mouse_dev = mouse_dev = input_allocate_device();
+	sp->remote.keybd_dev = keybd_dev = input_allocate_device();
 
-	memset(remote, 0, sizeof(*remote));
+	if (!mouse_dev || !keybd_dev)
+		goto err_free_devices;
 
-	remote->mouse_dev.private = remote;
-	init_input_dev(&remote->mouse_dev);
-	remote->mouse_dev.id.vendor = pdev->vendor;
-	remote->mouse_dev.id.product = pdev->device;
-	remote->mouse_dev.evbit[0]  = BIT(EV_KEY) | BIT(EV_ABS);
-	remote->mouse_dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) |
+	mouse_dev->id.bustype = BUS_PCI;
+	mouse_dev->id.vendor = pdev->vendor;
+	mouse_dev->id.product = pdev->device;
+	mouse_dev->id.version = 1;
+	mouse_dev->evbit[0]  = BIT(EV_KEY) | BIT(EV_ABS);
+	mouse_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) |
 		BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-	set_bit(BTN_TOUCH, remote->mouse_dev.keybit);
-	remote->mouse_dev.name = remote_mouse_name;
-	input_set_abs_params(&remote->mouse_dev, ABS_X, 0, xmax, 0, 0);
-	input_set_abs_params(&remote->mouse_dev, ABS_Y, 0, ymax, 0, 0);
+	set_bit(BTN_TOUCH, mouse_dev->keybit);
+	mouse_dev->name = remote_mouse_name;
+	input_set_abs_params(mouse_dev, ABS_X, 0, xmax, 0, 0);
+	input_set_abs_params(mouse_dev, ABS_Y, 0, ymax, 0, 0);
 
-	remote->keybd_dev.private = remote;
-	init_input_dev(&remote->keybd_dev);
-	remote->keybd_dev.id.vendor = pdev->vendor;
-	remote->keybd_dev.id.product = pdev->device;
-	remote->keybd_dev.evbit[0]  = BIT(EV_KEY);
-	remote->keybd_dev.name = remote_keybd_name;
+	mouse_dev->id.bustype = BUS_PCI;
+	keybd_dev->id.vendor = pdev->vendor;
+	keybd_dev->id.product = pdev->device;
+	mouse_dev->id.version = 2;
+	keybd_dev->evbit[0]  = BIT(EV_KEY);
+	keybd_dev->name = remote_keybd_name;
 
-	for (i=0; i<XLATE_SIZE; i++) {
+	for (i = 0; i < XLATE_SIZE; i++) {
 		if (xlate_high[i])
-			set_bit(xlate_high[i], remote->keybd_dev.keybit);
+			set_bit(xlate_high[i], keybd_dev->keybit);
 		if (xlate[i])
-			set_bit(xlate[i], remote->keybd_dev.keybit);
+			set_bit(xlate[i], keybd_dev->keybit);
 	}
 
-	input_register_device(&remote->mouse_dev);
-	input_register_device(&remote->keybd_dev);
+	error = input_register_device(mouse_dev);
+	if (error)
+		goto err_free_devices;
+
+	error = input_register_device(keybd_dev);
+	if (error)
+		goto err_unregister_mouse_dev;
+
 	enable_mouse_interrupts(sp);
 
 	printk(KERN_INFO "ibmasm remote responding to events on RSA card %d\n", sp->number);
 
 	return 0;
+
+ err_unregister_mouse_dev:
+	input_unregister_device(mouse_dev);
+ err_free_devices:
+	input_free_device(mouse_dev);
+	input_free_device(keybd_dev);
+
+	return error;
 }
 
 void ibmasm_free_remote_input_dev(struct service_processor *sp)
 {
 	disable_mouse_interrupts(sp);
-	input_unregister_device(&sp->remote->keybd_dev);
-	input_unregister_device(&sp->remote->mouse_dev);
-	kfree(sp->remote);
+	input_unregister_device(sp->remote.mouse_dev);
+	input_unregister_device(sp->remote.keybd_dev);
 }
 
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index da52839..6696f71 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -550,6 +550,11 @@
 		csd->capacity	  = (1 + m) << (e + 2);
 
 		csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
+		csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
+		csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
+		csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
+		csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
+		csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
 	} else {
 		/*
 		 * We only understand CSD structure v1.1 and v1.2.
@@ -579,6 +584,11 @@
 		csd->capacity	  = (1 + m) << (e + 2);
 
 		csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
+		csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
+		csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
+		csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
+		csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
+		csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
 	}
 }
 
@@ -679,7 +689,15 @@
 }
 
 /*
- * Apply power to the MMC stack.
+ * Apply power to the MMC stack.  This is a two-stage process.
+ * First, we enable power to the card without the clock running.
+ * We then wait a bit for the power to stabilise.  Finally,
+ * enable the bus drivers and clock to the card.
+ *
+ * We must _NOT_ enable the clock prior to power stablising.
+ *
+ * If a host does all the power sequencing itself, ignore the
+ * initial MMC_POWER_UP stage.
  */
 static void mmc_power_up(struct mmc_host *host)
 {
@@ -816,7 +834,7 @@
 
 			cmd.opcode = SD_SEND_RELATIVE_ADDR;
 			cmd.arg = 0;
-			cmd.flags = MMC_RSP_R1;
+			cmd.flags = MMC_RSP_R6;
 
 			err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
 			if (err != MMC_ERR_NONE)
@@ -932,8 +950,9 @@
 
 		sg_init_one(&sg, (u8*)card->raw_scr, 8);
 
-		err = mmc_wait_for_req(host, &mrq);
-		if (err != MMC_ERR_NONE) {
+		mmc_wait_for_req(host, &mrq);
+
+		if (cmd.error != MMC_ERR_NONE || data.error != MMC_ERR_NONE) {
 			mmc_card_set_dead(card);
 			continue;
 		}
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c
index d91fcf7..d5f2898 100644
--- a/drivers/mmc/mmc_block.c
+++ b/drivers/mmc/mmc_block.c
@@ -54,6 +54,7 @@
 
 	unsigned int	usage;
 	unsigned int	block_bits;
+	unsigned int	read_only;
 };
 
 static DECLARE_MUTEX(open_lock);
@@ -85,12 +86,6 @@
 	up(&open_lock);
 }
 
-static inline int mmc_blk_readonly(struct mmc_card *card)
-{
-	return mmc_card_readonly(card) ||
-	       !(card->csd.cmdclass & CCC_BLOCK_WRITE);
-}
-
 static int mmc_blk_open(struct inode *inode, struct file *filp)
 {
 	struct mmc_blk_data *md;
@@ -102,8 +97,7 @@
 			check_disk_change(inode->i_bdev);
 		ret = 0;
 
-		if ((filp->f_mode & FMODE_WRITE) &&
-			mmc_blk_readonly(md->queue.card))
+		if ((filp->f_mode & FMODE_WRITE) && md->read_only)
 			ret = -EROFS;
 	}
 
@@ -119,31 +113,18 @@
 }
 
 static int
-mmc_blk_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+mmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	struct block_device *bdev = inode->i_bdev;
-
-	if (cmd == HDIO_GETGEO) {
-		struct hd_geometry geo;
-
-		memset(&geo, 0, sizeof(struct hd_geometry));
-
-		geo.cylinders	= get_capacity(bdev->bd_disk) / (4 * 16);
-		geo.heads	= 4;
-		geo.sectors	= 16;
-		geo.start	= get_start_sect(bdev);
-
-		return copy_to_user((void __user *)arg, &geo, sizeof(geo))
-			? -EFAULT : 0;
-	}
-
-	return -ENOTTY;
+	geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
+	geo->heads = 4;
+	geo->sectors = 16;
+	return 0;
 }
 
 static struct block_device_operations mmc_bdops = {
 	.open			= mmc_blk_open,
 	.release		= mmc_blk_release,
-	.ioctl			= mmc_blk_ioctl,
+	.getgeo			= mmc_blk_getgeo,
 	.owner			= THIS_MODULE,
 };
 
@@ -263,7 +244,7 @@
 			 */
 			add_disk_randomness(req->rq_disk);
 			blkdev_dequeue_request(req);
-			end_that_request_last(req);
+			end_that_request_last(req, 1);
 		}
 		spin_unlock_irq(&md->lock);
 	} while (ret);
@@ -289,7 +270,7 @@
 
 	add_disk_randomness(req->rq_disk);
 	blkdev_dequeue_request(req);
-	end_that_request_last(req);
+	end_that_request_last(req, 0);
 	spin_unlock_irq(&md->lock);
 
 	return 0;
@@ -299,6 +280,12 @@
 
 static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))];
 
+static inline int mmc_blk_readonly(struct mmc_card *card)
+{
+	return mmc_card_readonly(card) ||
+	       !(card->csd.cmdclass & CCC_BLOCK_WRITE);
+}
+
 static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
 {
 	struct mmc_blk_data *md;
@@ -310,59 +297,121 @@
 	__set_bit(devidx, dev_use);
 
 	md = kmalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
-	if (md) {
-		memset(md, 0, sizeof(struct mmc_blk_data));
-
-		md->disk = alloc_disk(1 << MMC_SHIFT);
-		if (md->disk == NULL) {
-			kfree(md);
-			md = ERR_PTR(-ENOMEM);
-			goto out;
-		}
-
-		spin_lock_init(&md->lock);
-		md->usage = 1;
-
-		ret = mmc_init_queue(&md->queue, card, &md->lock);
-		if (ret) {
-			put_disk(md->disk);
-			kfree(md);
-			md = ERR_PTR(ret);
-			goto out;
-		}
-		md->queue.prep_fn = mmc_blk_prep_rq;
-		md->queue.issue_fn = mmc_blk_issue_rq;
-		md->queue.data = md;
-
-		md->disk->major	= major;
-		md->disk->first_minor = devidx << MMC_SHIFT;
-		md->disk->fops = &mmc_bdops;
-		md->disk->private_data = md;
-		md->disk->queue = md->queue.queue;
-		md->disk->driverfs_dev = &card->dev;
-
-		/*
-		 * As discussed on lkml, GENHD_FL_REMOVABLE should:
-		 *
-		 * - be set for removable media with permanent block devices
-		 * - be unset for removable block devices with permanent media
-		 *
-		 * Since MMC block devices clearly fall under the second
-		 * case, we do not set GENHD_FL_REMOVABLE.  Userspace
-		 * should use the block device creation/destruction hotplug
-		 * messages to tell when the card is present.
-		 */
-
-		sprintf(md->disk->disk_name, "mmcblk%d", devidx);
-		sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
-
-		md->block_bits = card->csd.read_blkbits;
-
-		blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits);
-		set_capacity(md->disk, card->csd.capacity);
+	if (!md) {
+		ret = -ENOMEM;
+		goto out;
 	}
- out:
+
+	memset(md, 0, sizeof(struct mmc_blk_data));
+
+	/*
+	 * Set the read-only status based on the supported commands
+	 * and the write protect switch.
+	 */
+	md->read_only = mmc_blk_readonly(card);
+
+	/*
+	 * Figure out a workable block size.  MMC cards have:
+	 *  - two block sizes, one for read and one for write.
+	 *  - may support partial reads and/or writes
+	 *    (allows block sizes smaller than specified)
+	 */
+	md->block_bits = card->csd.read_blkbits;
+	if (card->csd.write_blkbits != card->csd.read_blkbits) {
+		if (card->csd.write_blkbits < card->csd.read_blkbits &&
+		    card->csd.read_partial) {
+			/*
+			 * write block size is smaller than read block
+			 * size, but we support partial reads, so choose
+			 * the smaller write block size.
+			 */
+			md->block_bits = card->csd.write_blkbits;
+		} else if (card->csd.write_blkbits > card->csd.read_blkbits &&
+			   card->csd.write_partial) {
+			/*
+			 * read block size is smaller than write block
+			 * size, but we support partial writes.  Use read
+			 * block size.
+			 */
+		} else {
+			/*
+			 * We don't support this configuration for writes.
+			 */
+			printk(KERN_ERR "%s: unable to select block size for "
+				"writing (rb%u wb%u rp%u wp%u)\n",
+				md->disk->disk_name,
+				1 << card->csd.read_blkbits,
+				1 << card->csd.write_blkbits,
+				card->csd.read_partial,
+				card->csd.write_partial);
+			md->read_only = 1;
+		}
+	}
+
+	/*
+	 * Refuse to allow block sizes smaller than 512 bytes.
+	 */
+	if (md->block_bits < 9) {
+		printk(KERN_ERR "%s: unable to support block size %u\n",
+			mmc_card_id(card), 1 << md->block_bits);
+		ret = -EINVAL;
+		goto err_kfree;
+	}
+
+	md->disk = alloc_disk(1 << MMC_SHIFT);
+	if (md->disk == NULL) {
+		ret = -ENOMEM;
+		goto err_kfree;
+	}
+
+	spin_lock_init(&md->lock);
+	md->usage = 1;
+
+	ret = mmc_init_queue(&md->queue, card, &md->lock);
+	if (ret)
+		goto err_putdisk;
+
+	md->queue.prep_fn = mmc_blk_prep_rq;
+	md->queue.issue_fn = mmc_blk_issue_rq;
+	md->queue.data = md;
+
+	md->disk->major	= major;
+	md->disk->first_minor = devidx << MMC_SHIFT;
+	md->disk->fops = &mmc_bdops;
+	md->disk->private_data = md;
+	md->disk->queue = md->queue.queue;
+	md->disk->driverfs_dev = &card->dev;
+
+	/*
+	 * As discussed on lkml, GENHD_FL_REMOVABLE should:
+	 *
+	 * - be set for removable media with permanent block devices
+	 * - be unset for removable block devices with permanent media
+	 *
+	 * Since MMC block devices clearly fall under the second
+	 * case, we do not set GENHD_FL_REMOVABLE.  Userspace
+	 * should use the block device creation/destruction hotplug
+	 * messages to tell when the card is present.
+	 */
+
+	sprintf(md->disk->disk_name, "mmcblk%d", devidx);
+	sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
+
+	blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits);
+
+	/*
+	 * The CSD capacity field is in units of read_blkbits.
+	 * set_capacity takes units of 512 bytes.
+	 */
+	set_capacity(md->disk, card->csd.capacity << (card->csd.read_blkbits - 9));
 	return md;
+
+ err_putdisk:
+	put_disk(md->disk);
+ err_kfree:
+	kfree(md);
+ out:
+	return ERR_PTR(ret);
 }
 
 static int
@@ -373,7 +422,7 @@
 
 	mmc_card_claim_host(card);
 	cmd.opcode = MMC_SET_BLOCKLEN;
-	cmd.arg = 1 << card->csd.read_blkbits;
+	cmd.arg = 1 << md->block_bits;
 	cmd.flags = MMC_RSP_R1;
 	err = mmc_wait_for_cmd(card->host, &cmd, 5);
 	mmc_card_release_host(card);
@@ -398,12 +447,6 @@
 	if (!(card->csd.cmdclass & CCC_BLOCK_READ))
 		return -ENODEV;
 
-	if (card->csd.read_blkbits < 9) {
-		printk(KERN_WARNING "%s: read blocksize too small (%u)\n",
-			mmc_card_id(card), 1 << card->csd.read_blkbits);
-		return -ENODEV;
-	}
-
 	md = mmc_blk_alloc(card);
 	if (IS_ERR(md))
 		return PTR_ERR(md);
@@ -412,10 +455,9 @@
 	if (err)
 		goto out;
 
-	printk(KERN_INFO "%s: %s %s %dKiB %s\n",
+	printk(KERN_INFO "%s: %s %s %luKiB %s\n",
 		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
-		(card->csd.capacity << card->csd.read_blkbits) / 1024,
-		mmc_blk_readonly(card)?"(ro)":"");
+		get_capacity(md->disk) >> 1, md->read_only ? "(ro)" : "");
 
 	mmc_set_drvdata(card, md);
 	add_disk(md->disk);
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c
index 3f4a66c..ec70166 100644
--- a/drivers/mmc/mmc_sysfs.c
+++ b/drivers/mmc/mmc_sysfs.c
@@ -80,7 +80,7 @@
 }
 
 static int
-mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf,
+mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
 		int buf_size)
 {
 	struct mmc_card *card = dev_to_mmc_card(dev);
@@ -140,7 +140,7 @@
 	.name		= "mmc",
 	.dev_attrs	= mmc_dev_attrs,
 	.match		= mmc_bus_match,
-	.hotplug	= mmc_bus_hotplug,
+	.uevent		= mmc_bus_uevent,
 	.suspend	= mmc_bus_suspend,
 	.resume		= mmc_bus_resume,
 };
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c
index 166c9b0..634ef53 100644
--- a/drivers/mmc/mmci.c
+++ b/drivers/mmc/mmci.c
@@ -19,13 +19,14 @@
 #include <linux/highmem.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/protocol.h>
+#include <linux/amba/bus.h>
+#include <linux/clk.h>
 
+#include <asm/cacheflush.h>
 #include <asm/div64.h>
 #include <asm/io.h>
 #include <asm/scatterlist.h>
 #include <asm/sizes.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/clock.h>
 #include <asm/mach/mmc.h>
 
 #include "mmci.h"
@@ -157,6 +158,13 @@
 		else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
 			data->error = MMC_ERR_FIFO;
 		status |= MCI_DATAEND;
+
+		/*
+		 * We hit an error condition.  Ensure that any data
+		 * partially written to a page is properly coherent.
+		 */
+		if (host->sg_len && data->flags & MMC_DATA_READ)
+			flush_dcache_page(host->sg_ptr->page);
 	}
 	if (status & MCI_DATAEND) {
 		mmci_stop_data(host);
@@ -292,7 +300,7 @@
 		/*
 		 * Unmap the buffer.
 		 */
-		mmci_kunmap_atomic(host, &flags);
+		mmci_kunmap_atomic(host, buffer, &flags);
 
 		host->sg_off += len;
 		host->size -= len;
@@ -301,6 +309,13 @@
 		if (remain)
 			break;
 
+		/*
+		 * If we were reading, and we have completed this
+		 * page, ensure that the data cache is coherent.
+		 */
+		if (status & MCI_RXACTIVE)
+			flush_dcache_page(host->sg_ptr->page);
+
 		if (!mmci_next_sg(host))
 			break;
 
@@ -479,13 +494,9 @@
 		goto host_free;
 	}
 
-	ret = clk_use(host->clk);
-	if (ret)
-		goto clk_free;
-
 	ret = clk_enable(host->clk);
 	if (ret)
-		goto clk_unuse;
+		goto clk_free;
 
 	host->plat = plat;
 	host->mclk = clk_get_rate(host->clk);
@@ -558,8 +569,6 @@
 	iounmap(host->base);
  clk_disable:
 	clk_disable(host->clk);
- clk_unuse:
-	clk_unuse(host->clk);
  clk_free:
 	clk_put(host->clk);
  host_free:
@@ -594,7 +603,6 @@
 
 		iounmap(host->base);
 		clk_disable(host->clk);
-		clk_unuse(host->clk);
 		clk_put(host->clk);
 
 		mmc_free_host(mmc);
diff --git a/drivers/mmc/mmci.h b/drivers/mmc/mmci.h
index 4589bbd..6d7eadc 100644
--- a/drivers/mmc/mmci.h
+++ b/drivers/mmc/mmci.h
@@ -172,8 +172,8 @@
 	return kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
 }
 
-static inline void mmci_kunmap_atomic(struct mmci_host *host, unsigned long *flags)
+static inline void mmci_kunmap_atomic(struct mmci_host *host, void *buffer, unsigned long *flags)
 {
-	kunmap_atomic(host->sg_ptr->page, KM_BIO_SRC_IRQ);
+	kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
 	local_irq_restore(*flags);
 }
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index c7eb7c2..4f13bd2 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1456,13 +1456,11 @@
 	 * Iterate through all ports, all codes to
 	 * find hardware that is in our known list.
 	 */
-	for (i = 0;i < sizeof(config_ports)/sizeof(int);i++)
-	{
+	for (i = 0; i < ARRAY_SIZE(config_ports); i++) {
 		if (!request_region(config_ports[i], 2, DRIVER_NAME))
 			continue;
 
-		for (j = 0;j < sizeof(unlock_codes)/sizeof(int);j++)
-		{
+		for (j = 0; j < ARRAY_SIZE(unlock_codes); j++) {
 			id = 0xFFFF;
 
 			host->config = config_ports[i];
@@ -1478,8 +1476,7 @@
 
 			wbsd_lock_config(host);
 
-			for (k = 0;k < sizeof(valid_ids)/sizeof(int);k++)
-			{
+			for (k = 0; k < ARRAY_SIZE(valid_ids); k++) {
 				if (id == valid_ids[k])
 				{
 					host->chip_id = id;
@@ -2090,10 +2087,20 @@
 		if (result < 0)
 			return result;
 
-		wbsd_device = platform_device_register_simple(DRIVER_NAME, -1,
-			NULL, 0);
-		if (IS_ERR(wbsd_device))
-			return PTR_ERR(wbsd_device);
+		wbsd_device = platform_device_alloc(DRIVER_NAME, -1);
+		if (!wbsd_device)
+		{
+			platform_driver_unregister(&wbsd_driver);
+			return -ENOMEM;
+		}
+
+		result = platform_device_add(wbsd_device);
+		if (result)
+		{
+			platform_device_put(wbsd_device);
+			platform_driver_unregister(&wbsd_driver);
+			return result;
+		}
 	}
 
 	return 0;
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 143f01a..69c0494 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -4,7 +4,7 @@
  *
  * (C) 2000 Red Hat. GPL'd
  *
- * $Id: cfi_cmdset_0001.c,v 1.185 2005/11/07 11:14:22 gleixner Exp $
+ * $Id: cfi_cmdset_0001.c,v 1.186 2005/11/23 22:07:52 nico Exp $
  *
  *
  * 10/10/2000	Nicolas Pitre <nico@cam.org>
@@ -644,9 +644,8 @@
 		 *
 		 * - contension arbitration is handled in the owner's context.
 		 *
-		 * The 'shared' struct can be read when its lock is taken.
-		 * However any writes to it can only be made when the current
-		 * owner's lock is also held.
+		 * The 'shared' struct can be read and/or written only when
+		 * its lock is taken.
 		 */
 		struct flchip_shared *shared = chip->priv;
 		struct flchip *contender;
@@ -675,14 +674,13 @@
 			}
 			timeo = jiffies + HZ;
 			spin_lock(&shared->lock);
+			spin_unlock(contender->mutex);
 		}
 
 		/* We now own it */
 		shared->writing = chip;
 		if (mode == FL_ERASING)
 			shared->erasing = chip;
-		if (contender && contender != chip)
-			spin_unlock(contender->mutex);
 		spin_unlock(&shared->lock);
 	}
 
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
index 90eb30e..e636aa8 100644
--- a/drivers/mtd/chips/cfi_probe.c
+++ b/drivers/mtd/chips/cfi_probe.c
@@ -1,7 +1,7 @@
 /*
    Common Flash Interface probe code.
    (C) 2000 Red Hat. GPL'd.
-   $Id: cfi_probe.c,v 1.84 2005/11/07 11:14:23 gleixner Exp $
+   $Id: cfi_probe.c,v 1.86 2005/11/29 14:48:31 gleixner Exp $
 */
 
 #include <linux/config.h>
@@ -230,8 +230,8 @@
 	cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
 	cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
-	cfi->mfr = cfi_read_query(map, base);
-	cfi->id = cfi_read_query(map, base + ofs_factor);
+	cfi->mfr = cfi_read_query16(map, base);
+	cfi->id = cfi_read_query16(map, base + ofs_factor);
 
 	/* Put it back into Read Mode */
 	cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
@@ -426,7 +426,7 @@
 	.module		= THIS_MODULE
 };
 
-int __init cfi_probe_init(void)
+static int __init cfi_probe_init(void)
 {
 	register_mtd_chip_driver(&cfi_chipdrv);
 	return 0;
diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c
index 2d26bde..36f61a6 100644
--- a/drivers/mtd/chips/sharp.c
+++ b/drivers/mtd/chips/sharp.c
@@ -4,7 +4,7 @@
  * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
  *           2000,2001 Lineo, Inc.
  *
- * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $
+ * $Id: sharp.c,v 1.17 2005/11/29 14:28:28 gleixner Exp $
  *
  * Devices supported:
  *   LH28F016SCT Symmetrical block flash memory, 2Mx8
@@ -160,22 +160,28 @@
 	return mtd;
 }
 
+static inline void sharp_send_cmd(struct map_info *map, unsigned long cmd, unsigned long adr)
+{
+	map_word map_cmd;
+	map_cmd.x[0] = cmd;
+	map_write(map, map_cmd, adr);
+}
+
 static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd)
 {
-	unsigned long tmp;
+	map_word tmp, read0, read4;
 	unsigned long base = 0;
-	u32 read0, read4;
 	int width = 4;
 
-	tmp = map_read32(map, base+0);
+	tmp = map_read(map, base+0);
 
-	map_write32(map, CMD_READ_ID, base+0);
+	sharp_send_cmd(map, CMD_READ_ID, base+0);
 
-	read0=map_read32(map, base+0);
-	read4=map_read32(map, base+4);
-	if(read0 == 0x89898989){
+	read0 = map_read(map, base+0);
+	read4 = map_read(map, base+4);
+	if(read0.x[0] == 0x89898989){
 		printk("Looks like sharp flash\n");
-		switch(read4){
+		switch(read4.x[0]){
 		case 0xaaaaaaaa:
 		case 0xa0a0a0a0:
 			/* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/
@@ -197,16 +203,16 @@
 			return width;
 #endif
 		default:
-			printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n",
-				read0,read4);
+			printk("Sort-of looks like sharp flash, 0x%08lx 0x%08lx\n",
+				read0.x[0], read4.x[0]);
 		}
-	}else if((map_read32(map, base+0) == CMD_READ_ID)){
+	}else if((map_read(map, base+0).x[0] == CMD_READ_ID)){
 		/* RAM, probably */
 		printk("Looks like RAM\n");
-		map_write32(map, tmp, base+0);
+		map_write(map, tmp, base+0);
 	}else{
-		printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n",
-			read0,read4);
+		printk("Doesn't look like sharp flash, 0x%08lx 0x%08lx\n",
+			read0.x[0], read4.x[0]);
 	}
 
 	return 0;
@@ -215,7 +221,8 @@
 /* This function returns with the chip->mutex lock held. */
 static int sharp_wait(struct map_info *map, struct flchip *chip)
 {
-	int status, i;
+	int i;
+	map_word status;
 	unsigned long timeo = jiffies + HZ;
 	DECLARE_WAITQUEUE(wait, current);
 	int adr = 0;
@@ -225,12 +232,12 @@
 
 	switch(chip->state){
 	case FL_READY:
-		map_write32(map,CMD_READ_STATUS,adr);
+		sharp_send_cmd(map, CMD_READ_STATUS, adr);
 		chip->state = FL_STATUS;
 	case FL_STATUS:
 		for(i=0;i<100;i++){
-			status = map_read32(map,adr);
-			if((status & SR_READY)==SR_READY)
+			status = map_read(map, adr);
+			if((status.x[0] & SR_READY)==SR_READY)
 				break;
 			udelay(1);
 		}
@@ -254,7 +261,7 @@
 		goto retry;
 	}
 
-	map_write32(map,CMD_RESET, adr);
+	sharp_send_cmd(map, CMD_RESET, adr);
 
 	chip->state = FL_READY;
 
@@ -351,37 +358,39 @@
 	int timeo;
 	int try;
 	int i;
-	int status = 0;
+	map_word data, status;
 
+	status.x[0] = 0;
 	ret = sharp_wait(map,chip);
 
 	for(try=0;try<10;try++){
-		map_write32(map,CMD_BYTE_WRITE,adr);
+		sharp_send_cmd(map, CMD_BYTE_WRITE, adr);
 		/* cpu_to_le32 -> hack to fix the writel be->le conversion */
-		map_write32(map,cpu_to_le32(datum),adr);
+		data.x[0] = cpu_to_le32(datum);
+		map_write(map, data, adr);
 
 		chip->state = FL_WRITING;
 
 		timeo = jiffies + (HZ/2);
 
-		map_write32(map,CMD_READ_STATUS,adr);
+		sharp_send_cmd(map, CMD_READ_STATUS, adr);
 		for(i=0;i<100;i++){
-			status = map_read32(map,adr);
-			if((status & SR_READY)==SR_READY)
+			status = map_read(map, adr);
+			if((status.x[0] & SR_READY) == SR_READY)
 				break;
 		}
 		if(i==100){
 			printk("sharp: timed out writing\n");
 		}
 
-		if(!(status&SR_ERRORS))
+		if(!(status.x[0] & SR_ERRORS))
 			break;
 
-		printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status);
+		printk("sharp: error writing byte at addr=%08lx status=%08lx\n", adr, status.x[0]);
 
-		map_write32(map,CMD_CLEAR_STATUS,adr);
+		sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
 	}
-	map_write32(map,CMD_RESET,adr);
+	sharp_send_cmd(map, CMD_RESET, adr);
 	chip->state = FL_READY;
 
 	wake_up(&chip->wq);
@@ -434,18 +443,18 @@
 {
 	int ret;
 	unsigned long timeo;
-	int status;
+	map_word status;
 	DECLARE_WAITQUEUE(wait, current);
 
-	map_write32(map,CMD_READ_STATUS,adr);
-	status = map_read32(map,adr);
+	sharp_send_cmd(map, CMD_READ_STATUS, adr);
+	status = map_read(map, adr);
 
 	timeo = jiffies + HZ;
 
 	while(time_before(jiffies, timeo)){
-		map_write32(map,CMD_READ_STATUS,adr);
-		status = map_read32(map,adr);
-		if((status & SR_READY)==SR_READY){
+		sharp_send_cmd(map, CMD_READ_STATUS, adr);
+		status = map_read(map, adr);
+		if((status.x[0] & SR_READY)==SR_READY){
 			ret = 0;
 			goto out;
 		}
@@ -476,7 +485,7 @@
 {
 	int ret;
 	//int timeo;
-	int status;
+	map_word status;
 	//int i;
 
 //printk("sharp_erase_oneblock()\n");
@@ -486,26 +495,26 @@
 	sharp_unlock_oneblock(map,chip,adr);
 #endif
 
-	map_write32(map,CMD_BLOCK_ERASE_1,adr);
-	map_write32(map,CMD_BLOCK_ERASE_2,adr);
+	sharp_send_cmd(map, CMD_BLOCK_ERASE_1, adr);
+	sharp_send_cmd(map, CMD_BLOCK_ERASE_2, adr);
 
 	chip->state = FL_ERASING;
 
 	ret = sharp_do_wait_for_ready(map,chip,adr);
 	if(ret<0)return ret;
 
-	map_write32(map,CMD_READ_STATUS,adr);
-	status = map_read32(map,adr);
+	sharp_send_cmd(map, CMD_READ_STATUS, adr);
+	status = map_read(map, adr);
 
-	if(!(status&SR_ERRORS)){
-		map_write32(map,CMD_RESET,adr);
+	if(!(status.x[0] & SR_ERRORS)){
+		sharp_send_cmd(map, CMD_RESET, adr);
 		chip->state = FL_READY;
 		//spin_unlock_bh(chip->mutex);
 		return 0;
 	}
 
-	printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status);
-	map_write32(map,CMD_CLEAR_STATUS,adr);
+	printk("sharp: error erasing block at addr=%08lx status=%08lx\n", adr, status.x[0]);
+	sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
 
 	//spin_unlock_bh(chip->mutex);
 
@@ -517,20 +526,20 @@
 	unsigned long adr)
 {
 	int i;
-	int status;
+	map_word status;
 
-	map_write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
-	map_write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
+	sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_1, adr);
+	sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_2, adr);
 
 	udelay(100);
 
-	status = map_read32(map,adr);
-	printk("status=%08x\n",status);
+	status = map_read(map, adr);
+	printk("status=%08lx\n", status.x[0]);
 
 	for(i=0;i<1000;i++){
-		//map_write32(map,CMD_READ_STATUS,adr);
-		status = map_read32(map,adr);
-		if((status & SR_READY)==SR_READY)
+		//sharp_send_cmd(map, CMD_READ_STATUS, adr);
+		status = map_read(map, adr);
+		if((status.x[0] & SR_READY) == SR_READY)
 			break;
 		udelay(100);
 	}
@@ -538,14 +547,14 @@
 		printk("sharp: timed out unlocking block\n");
 	}
 
-	if(!(status&SR_ERRORS)){
-		map_write32(map,CMD_RESET,adr);
+	if(!(status.x[0] & SR_ERRORS)){
+		sharp_send_cmd(map, CMD_RESET, adr);
 		chip->state = FL_READY;
 		return;
 	}
 
-	printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status);
-	map_write32(map,CMD_CLEAR_STATUS,adr);
+	printk("sharp: error unlocking block at addr=%08lx status=%08lx\n", adr, status.x[0]);
+	sharp_send_cmd(map, CMD_CLEAR_STATUS, adr);
 }
 #endif
 
diff --git a/drivers/mtd/devices/blkmtd.c b/drivers/mtd/devices/blkmtd.c
index f9db52f..04f864d 100644
--- a/drivers/mtd/devices/blkmtd.c
+++ b/drivers/mtd/devices/blkmtd.c
@@ -113,7 +113,7 @@
 			ClearPageUptodate(page);
 			SetPageError(page);
 		}
-		ClearPageDirty(page);
+		clear_page_dirty(page);
 		unlock_page(page);
 		page_cache_release(page);
 	} while (bvec >= bio->bi_io_vec);
@@ -289,7 +289,7 @@
 			BUG();
 		}
 		memcpy(page_address(page)+offset, buf, start_len);
-		SetPageDirty(page);
+		set_page_dirty(page);
 		SetPageUptodate(page);
 		buf += start_len;
 		thislen = start_len;
@@ -336,7 +336,7 @@
 			}
 			pagenr++;
 			pagecnt--;
-			SetPageDirty(page);
+			set_page_dirty(page);
 			SetPageUptodate(page);
 			pagesc--;
 			thislen += PAGE_SIZE;
@@ -357,7 +357,7 @@
 			BUG();
 		}
 		memcpy(page_address(page), buf, end_len);
-		SetPageDirty(page);
+		set_page_dirty(page);
 		SetPageUptodate(page);
 		DEBUG(3, "blkmtd: write: writing out partial end\n");
 		thislen += end_len;
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index 0aaa0ce..7ff403b 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -1,5 +1,5 @@
 /*
- * $Id: block2mtd.c,v 1.29 2005/11/07 11:14:24 gleixner Exp $
+ * $Id: block2mtd.c,v 1.30 2005/11/29 14:48:32 gleixner Exp $
  *
  * block2mtd.c - create an mtd from a block device
  *
@@ -19,7 +19,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/buffer_head.h>
 
-#define VERSION "$Revision: 1.29 $"
+#define VERSION "$Revision: 1.30 $"
 
 
 #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
@@ -40,7 +40,7 @@
 
 
 #define PAGE_READAHEAD 64
-void cache_readahead(struct address_space *mapping, int index)
+static void cache_readahead(struct address_space *mapping, int index)
 {
 	filler_t *filler = (filler_t*)mapping->a_ops->readpage;
 	int i, pagei;
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c
index f5026ce..0ff2e43 100644
--- a/drivers/mtd/devices/ms02-nv.c
+++ b/drivers/mtd/devices/ms02-nv.c
@@ -6,7 +6,7 @@
  *	as published by the Free Software Foundation; either version
  *	2 of the License, or (at your option) any later version.
  *
- *	$Id: ms02-nv.c,v 1.10 2005/06/20 12:24:41 macro Exp $
+ *	$Id: ms02-nv.c,v 1.11 2005/11/14 13:41:47 macro Exp $
  */
 
 #include <linux/init.h>
@@ -293,13 +293,13 @@
 
 	switch (mips_machtype) {
 	case MACH_DS5000_200:
-		csr = (volatile u32 *)KN02_CSR_BASE;
+		csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR);
 		if (*csr & KN02_CSR_BNK32M)
 			stride = 2;
 		break;
 	case MACH_DS5000_2X0:
 	case MACH_DS5900:
-		csr = (volatile u32 *)KN03_MCR_BASE;
+		csr = (volatile u32 *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_MCR);
 		if (*csr & KN03_MCR_BNK32M)
 			stride = 2;
 		break;
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
index de7e231..8a878b3 100644
--- a/drivers/mtd/ftl.c
+++ b/drivers/mtd/ftl.c
@@ -1,5 +1,5 @@
 /* This version ported to the Linux-MTD system by dwmw2@infradead.org
- * $Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $
+ * $Id: ftl.c,v 1.59 2005/11/29 14:48:31 gleixner Exp $
  *
  * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
@@ -1084,9 +1084,9 @@
 	.owner		= THIS_MODULE,
 };
 
-int init_ftl(void)
+static int init_ftl(void)
 {
-	DEBUG(0, "$Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $\n");
+	DEBUG(0, "$Id: ftl.c,v 1.59 2005/11/29 14:48:31 gleixner Exp $\n");
 
 	return register_mtd_blktrans(&ftl_tr);
 }
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 846a533..b9b77cf 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -62,7 +62,7 @@
 
 config MTD_SUN_UFLASH
 	tristate "Sun Microsystems userflash support"
-	depends on (SPARC32 || SPARC64) && MTD_CFI
+	depends on SPARC && MTD_CFI
 	help
 	  This provides a 'mapping' driver which supports the way in
 	  which user-programmable flash chips are connected on various
@@ -538,12 +538,6 @@
 	  This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02).
 	  If you have such a board, say 'Y'.
 
-config MTD_PQ2FADS
-	tristate "JEDEC flash SIMM mapped on PQ2FADS and 8272ADS boards"
-	depends on (ADS8272 || PQ2FADS) && MTD_PARTITIONS && MTD_JEDECPROBE && MTD_PHYSMAP && MTD_CFI_GEOMETRY && MTD_CFI_INTELEXT
-	help
-	 This enables access to flash SIMM on PQ2FADS-like boards
-
 config MTD_OMAP_NOR
 	tristate "TI OMAP board mappings"
 	depends on MTD_CFI && ARCH_OMAP
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 7d9e940..2f7e254 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -70,6 +70,5 @@
 obj-$(CONFIG_MTD_SHARP_SL)	+= sharpsl-flash.o
 obj-$(CONFIG_MTD_PLATRAM)	+= plat-ram.o
 obj-$(CONFIG_MTD_OMAP_NOR)	+= omap_nor.o
-obj-$(CONFIG_MTD_PQ2FADS)	+= pq2fads.o
 obj-$(CONFIG_MTD_MTX1)		+= mtx-1_flash.o
 obj-$(CONFIG_MTD_TQM834x)	+= tqm834x.o
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c
index a59f802..986c586 100644
--- a/drivers/mtd/maps/ixp4xx.c
+++ b/drivers/mtd/maps/ixp4xx.c
@@ -1,5 +1,5 @@
 /*
- * $Id: ixp4xx.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $
+ * $Id: ixp4xx.c,v 1.13 2005/11/16 16:23:21 dvrabel Exp $
  *
  * drivers/mtd/maps/ixp4xx.c
  *
@@ -34,10 +34,55 @@
 
 #include <linux/reboot.h>
 
+/*
+ * Read/write a 16 bit word from flash address 'addr'.
+ *
+ * When the cpu is in little-endian mode it swizzles the address lines
+ * ('address coherency') so we need to undo the swizzling to ensure commands
+ * and the like end up on the correct flash address.
+ *
+ * To further complicate matters, due to the way the expansion bus controller
+ * handles 32 bit reads, the byte stream ABCD is stored on the flash as:
+ *     D15    D0
+ *     +---+---+
+ *     | A | B | 0
+ *     +---+---+
+ *     | C | D | 2
+ *     +---+---+
+ * This means that on LE systems each 16 bit word must be swapped. Note that
+ * this requires CONFIG_MTD_CFI_BE_BYTE_SWAP to be enabled to 'unswap' the CFI
+ * data and other flash commands which are always in D7-D0.
+ */
 #ifndef __ARMEB__
+#ifndef CONFIG_MTD_CFI_BE_BYTE_SWAP
+#  error CONFIG_MTD_CFI_BE_BYTE_SWAP required
+#endif
+
+static inline u16 flash_read16(void __iomem *addr)
+{
+	return be16_to_cpu(__raw_readw((void __iomem *)((unsigned long)addr ^ 0x2)));
+}
+
+static inline void flash_write16(u16 d, void __iomem *addr)
+{
+	__raw_writew(cpu_to_be16(d), (void __iomem *)((unsigned long)addr ^ 0x2));
+}
+
 #define	BYTE0(h)	((h) & 0xFF)
 #define	BYTE1(h)	(((h) >> 8) & 0xFF)
+
 #else
+
+static inline u16 flash_read16(const void __iomem *addr)
+{
+	return __raw_readw(addr);
+}
+
+static inline void flash_write16(u16 d, void __iomem *addr)
+{
+	__raw_writew(d, addr);
+}
+
 #define	BYTE0(h)	(((h) >> 8) & 0xFF)
 #define	BYTE1(h)	((h) & 0xFF)
 #endif
@@ -45,7 +90,7 @@
 static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs)
 {
 	map_word val;
-	val.x[0] = le16_to_cpu(readw(map->virt + ofs));
+	val.x[0] = flash_read16(map->virt + ofs);
 	return val;
 }
 
@@ -57,19 +102,28 @@
 static void ixp4xx_copy_from(struct map_info *map, void *to,
 			     unsigned long from, ssize_t len)
 {
-	int i;
 	u8 *dest = (u8 *) to;
 	void __iomem *src = map->virt + from;
-	u16 data;
 
-	for (i = 0; i < (len / 2); i++) {
-		data = le16_to_cpu(readw(src + 2*i));
-		dest[i * 2] = BYTE0(data);
-		dest[i * 2 + 1] = BYTE1(data);
+	if (len <= 0)
+		return;
+
+	if (from & 1) {
+		*dest++ = BYTE1(flash_read16(src));
+                src++;
+		--len;
 	}
 
-	if (len & 1)
-		dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i)));
+	while (len >= 2) {
+		u16 data = flash_read16(src);
+		*dest++ = BYTE0(data);
+		*dest++ = BYTE1(data);
+		src += 2;
+		len -= 2;
+        }
+
+	if (len > 0)
+		*dest++ = BYTE0(flash_read16(src));
 }
 
 /*
@@ -79,7 +133,7 @@
 static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr)
 {
 	if (!(adr & 1))
-		writew(cpu_to_le16(d.x[0]), map->virt + adr);
+		flash_write16(d.x[0], map->virt + adr);
 }
 
 /*
@@ -87,7 +141,7 @@
  */
 static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr)
 {
-	writew(cpu_to_le16(d.x[0]), map->virt + adr);
+	flash_write16(d.x[0], map->virt + adr);
 }
 
 struct ixp4xx_flash_info {
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c
index f00ee7e..632eb2a 100644
--- a/drivers/mtd/maps/nettel.c
+++ b/drivers/mtd/maps/nettel.c
@@ -6,7 +6,7 @@
  *      (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
  *      (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
  *
- *	$Id: nettel.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $
+ *	$Id: nettel.c,v 1.12 2005/11/29 14:30:00 gleixner Exp $
  */
 
 /****************************************************************************/
@@ -479,7 +479,7 @@
 	}
 	if (nettel_intel_map.virt) {
 		iounmap(nettel_intel_map.virt);
-		nettel_intel_map.virt = 0;
+		nettel_intel_map.virt = NULL;
 	}
 #endif
 }
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index 8b3570b..21822c2 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -7,7 +7,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- *  $Id: pci.c,v 1.13 2005/11/07 11:14:27 gleixner Exp $
+ *  $Id: pci.c,v 1.14 2005/11/17 08:20:27 dwmw2 Exp $
  *
  * Generic PCI memory map driver.  We support the following boards:
  *  - Intel IQ80310 ATU.
@@ -102,7 +102,7 @@
 	memcpy_toio(map->base + map->translate(map, to), from, len);
 }
 
-static struct map_info mtd_pci_map = {
+static const struct map_info mtd_pci_map = {
 	.phys =		NO_XIP,
 	.copy_from =	mtd_pci_copyfrom,
 	.copy_to =	mtd_pci_copyto,
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index af24216..f0f8916 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -66,9 +66,6 @@
 };
 
 
-static dev_info_t dev_info = "pcmciamtd";
-static dev_link_t *dev_list;
-
 /* Module parameters */
 
 /* 2 = do 16-bit transfers, 1 = do 8-bit transfers */
@@ -691,55 +688,21 @@
 }
 
 
-/* The card status event handler.  Mostly, this schedules other
- * stuff to run after an event is received.  A CARD_REMOVAL event
- * also sets some flags to discourage the driver from trying
- * to talk to the card any more.
- */
-
-static int pcmciamtd_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int pcmciamtd_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
+	DEBUG(2, "EVENT_PM_RESUME");
 
-	DEBUG(1, "event=0x%06x", event);
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		DEBUG(2, "EVENT_CARD_REMOVAL");
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			struct pcmciamtd_dev *dev = link->priv;
-			if(dev->mtd_info) {
-				del_mtd_device(dev->mtd_info);
-				info("mtd%d: Removed", dev->mtd_info->index);
-			}
-			pcmciamtd_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		DEBUG(2, "EVENT_CARD_INSERTION");
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		pcmciamtd_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		DEBUG(2, "EVENT_PM_SUSPEND");
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		DEBUG(2, "EVENT_RESET_PHYSICAL");
-		/* get_lock(link); */
-		break;
-	case CS_EVENT_PM_RESUME:
-		DEBUG(2, "EVENT_PM_RESUME");
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		DEBUG(2, "EVENT_CARD_RESET");
-		/* free_lock(link); */
-		break;
-	default:
-		DEBUG(2, "Unknown event %d", event);
-	}
+	/* get_lock(link); */
+
+	return 0;
+}
+
+static int pcmciamtd_resume(struct pcmcia_device *dev)
+{
+	DEBUG(2, "EVENT_PM_SUSPEND");
+
+	/* free_lock(link); */
+
 	return 0;
 }
 
@@ -750,23 +713,21 @@
  * when the device is released.
  */
 
-static void pcmciamtd_detach(dev_link_t *link)
+static void pcmciamtd_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
+
 	DEBUG(3, "link=0x%p", link);
 
 	if(link->state & DEV_CONFIG) {
+		struct pcmciamtd_dev *dev = link->priv;
+		if(dev->mtd_info) {
+			del_mtd_device(dev->mtd_info);
+			info("mtd%d: Removed", dev->mtd_info->index);
+		}
+
 		pcmciamtd_release(link);
 	}
-
-	if (link->handle) {
-		int ret;
-		DEBUG(2, "Deregistering with card services");
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
-	link->state |= DEV_STALE_LINK;
 }
 
 
@@ -775,16 +736,14 @@
  * with Card Services.
  */
 
-static dev_link_t *pcmciamtd_attach(void)
+static int pcmciamtd_attach(struct pcmcia_device *p_dev)
 {
 	struct pcmciamtd_dev *dev;
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	/* Create new memory card device */
 	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-	if (!dev) return NULL;
+	if (!dev) return -ENOMEM;
 	DEBUG(1, "dev=0x%p", dev);
 
 	memset(dev, 0, sizeof(*dev));
@@ -794,22 +753,14 @@
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY;
 
-	link->next = dev_list;
-	dev_list = link;
+	link->next = NULL;
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	/* Register with Card Services */
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	DEBUG(2, "Calling RegisterClient");
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		pcmciamtd_detach(link);
-		return NULL;
-	}
-	DEBUG(2, "link = %p", link);
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	pcmciamtd_config(link);
+
+	return 0;
 }
 
 static struct pcmcia_device_id pcmciamtd_ids[] = {
@@ -843,11 +794,12 @@
 	.drv		= {
 		.name	= "pcmciamtd"
 	},
-	.attach		= pcmciamtd_attach,
-	.event		= pcmciamtd_event,
-	.detach		= pcmciamtd_detach,
+	.probe		= pcmciamtd_attach,
+	.remove		= pcmciamtd_detach,
 	.owner		= THIS_MODULE,
 	.id_table	= pcmciamtd_ids,
+	.suspend	= pcmciamtd_suspend,
+	.resume		= pcmciamtd_resume,
 };
 
 
@@ -875,7 +827,6 @@
 {
 	DEBUG(1, DRIVER_DESC " unloading");
 	pcmcia_unregister_driver(&pcmciamtd_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_pcmciamtd);
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 9ee760f..f49ebc3 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -1,5 +1,5 @@
 /*
- * $Id: physmap.c,v 1.38 2005/11/07 11:14:28 gleixner Exp $
+ * $Id: physmap.c,v 1.39 2005/11/29 14:49:36 gleixner Exp $
  *
  * Normal mappings of chips in physical memory
  *
@@ -19,6 +19,7 @@
 #include <linux/mtd/map.h>
 #include <linux/config.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
 
 static struct mtd_info *mymtd;
 
diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c
index 6fb9f3c..ed92afa 100644
--- a/drivers/mtd/maps/sc520cdp.c
+++ b/drivers/mtd/maps/sc520cdp.c
@@ -16,7 +16,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  *
- * $Id: sc520cdp.c,v 1.22 2005/11/07 11:14:28 gleixner Exp $
+ * $Id: sc520cdp.c,v 1.23 2005/11/17 08:20:27 dwmw2 Exp $
  *
  *
  * The SC520CDP is an evaluation board for the Elan SC520 processor available
@@ -164,7 +164,7 @@
 	unsigned long default_address;
 };
 
-static struct sc520_par_table par_table[NUM_FLASH_BANKS] =
+static const struct sc520_par_table par_table[NUM_FLASH_BANKS] =
 {
 	{	/* Flash Bank #0: selected by ROMCS0 */
 		SC520_PAR_ROMCS0,
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 339cb12..7f3ff50 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -194,6 +194,14 @@
 	return ret;
 }
 
+static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data;
+
+	if (dev->tr->getgeo)
+		return dev->tr->getgeo(dev, geo);
+	return -ENOTTY;
+}
 
 static int blktrans_ioctl(struct inode *inode, struct file *file,
 			      unsigned int cmd, unsigned long arg)
@@ -207,22 +215,6 @@
 			return tr->flush(dev);
 		/* The core code did the work, we had nothing to do. */
 		return 0;
-
-	case HDIO_GETGEO:
-		if (tr->getgeo) {
-			struct hd_geometry g;
-			int ret;
-
-			memset(&g, 0, sizeof(g));
-			ret = tr->getgeo(dev, &g);
-			if (ret)
-				return ret;
-
-			g.start = get_start_sect(inode->i_bdev);
-			if (copy_to_user((void __user *)arg, &g, sizeof(g)))
-				return -EFAULT;
-			return 0;
-		} /* else */
 	default:
 		return -ENOTTY;
 	}
@@ -233,6 +225,7 @@
 	.open		= blktrans_open,
 	.release	= blktrans_release,
 	.ioctl		= blktrans_ioctl,
+	.getgeo		= blktrans_getgeo,
 };
 
 int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index de45003..a0af92c 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -1486,7 +1486,7 @@
 /*
  * Module initialization function
  */
-int __init ns_init_module(void)
+static int __init ns_init_module(void)
 {
 	struct nand_chip *chip;
 	struct nandsim *nand;
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index d209214..5b55599 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -53,6 +53,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/clk.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
@@ -60,7 +61,6 @@
 #include <linux/mtd/partitions.h>
 
 #include <asm/io.h>
-#include <asm/hardware/clock.h>
 
 #include <asm/arch/regs-nand.h>
 #include <asm/arch/nand.h>
@@ -460,7 +460,6 @@
 
 	if (info->clk != NULL && !IS_ERR(info->clk)) {
 		clk_disable(info->clk);
-		clk_unuse(info->clk);
 		clk_put(info->clk);
 	}
 
@@ -598,7 +597,6 @@
 		goto exit_error;
 	}
 
-	clk_use(info->clk);
 	clk_enable(info->clk);
 
 	/* allocate and map the resource */
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 48cce43..af06a80 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -12,9 +12,10 @@
  *   This is a device driver for the OneNAND flash for generic boards.
  */
 
-#include <linux/device.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
@@ -39,7 +40,7 @@
 {
 	struct onenand_info *info;
 	struct platform_device *pdev = to_platform_device(dev);
-	struct onenand_platform_data *pdata = pdev->dev.platform_data;
+	struct flash_platform_data *pdata = pdev->dev.platform_data;
 	struct resource *res = pdev->resource;
 	unsigned long size = res->end - res->start + 1;
 	int err;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index f67d5d6..a53a73f 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -940,7 +940,7 @@
 	u_char *eccbuf, struct nand_oobinfo *oobsel)
 {
 	struct onenand_chip *this = mtd->priv;
-	unsigned char buffer[MAX_ONENAND_PAGESIZE], *pbuf;
+	unsigned char *pbuf;
 	size_t total_len, len;
 	int i, written = 0;
 	int ret = 0;
@@ -975,7 +975,7 @@
 	/* Loop until all keve's data has been written */
 	len = 0;
 	while (count) {
-		pbuf = buffer;
+		pbuf = this->page_buf;
 		/*
 		 * If the given tuple is >= pagesize then
 		 * write it out from the iov
@@ -995,7 +995,7 @@
 			int cnt = 0, thislen;
 			while (cnt < mtd->oobblock) {
 				thislen = min_t(int, mtd->oobblock - cnt, vecs->iov_len - len);
-				memcpy(buffer + cnt, vecs->iov_base + len, thislen);
+				memcpy(this->page_buf + cnt, vecs->iov_base + len, thislen);
 				cnt += thislen;
 				len += thislen;
 
@@ -1296,6 +1296,12 @@
 
 	/* Block lock scheme */
 	for (block = start; block < end; block++) {
+		/* Set block address */
+		value = onenand_block_address(this, block);
+		this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
+		/* Select DataRAM for DDP */
+		value = onenand_bufferram_address(this, block);
+		this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
 		/* Set start block address */
 		this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
 		/* Write unlock command */
@@ -1309,10 +1315,6 @@
 		    & ONENAND_CTRL_ONGO)
 			continue;
 
-		/* Set block address for read block status */
-		value = onenand_block_address(this, block);
-		this->write_word(value, this->base + ONENAND_REG_START_ADDRESS1);
-
 		/* Check lock status */
 		status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
 		if (!(status & ONENAND_WP_US))
@@ -1346,7 +1348,6 @@
 
 static const struct onenand_manufacturers onenand_manuf_ids[] = {
         {ONENAND_MFR_SAMSUNG, "Samsung"},
-        {ONENAND_MFR_UNKNOWN, "Unknown"}
 };
 
 /**
@@ -1357,17 +1358,22 @@
  */
 static int onenand_check_maf(int manuf)
 {
+	int size = ARRAY_SIZE(onenand_manuf_ids);
+	char *name;
         int i;
 
-        for (i = 0; onenand_manuf_ids[i].id; i++) {
+	for (i = 0; i < size; i++)
                 if (manuf == onenand_manuf_ids[i].id)
                         break;
-        }
 
-        printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n",
-                onenand_manuf_ids[i].name, manuf);
+	if (i < size)
+		name = onenand_manuf_ids[i].name;
+	else
+		name = "Unknown";
 
-        return (i != ONENAND_MFR_UNKNOWN);
+	printk(KERN_DEBUG "OneNAND Manufacturer: %s (0x%0x)\n", name, manuf);
+
+	return (i == size);
 }
 
 /**
@@ -1513,6 +1519,18 @@
 		this->read_bufferram = onenand_sync_read_bufferram;
 	}
 
+	/* Allocate buffers, if necessary */
+	if (!this->page_buf) {
+		size_t len;
+		len = mtd->oobblock + mtd->oobsize;
+		this->page_buf = kmalloc(len, GFP_KERNEL);
+		if (!this->page_buf) {
+			printk(KERN_ERR "onenand_scan(): Can't allocate page_buf\n");
+			return -ENOMEM;
+		}
+		this->options |= ONENAND_PAGEBUF_ALLOC;
+	}
+
 	this->state = FL_READY;
 	init_waitqueue_head(&this->wq);
 	spin_lock_init(&this->chip_lock);
@@ -1574,12 +1592,21 @@
  */
 void onenand_release(struct mtd_info *mtd)
 {
+	struct onenand_chip *this = mtd->priv;
+
 #ifdef CONFIG_MTD_PARTITIONS
 	/* Deregister partitions */
 	del_mtd_partitions (mtd);
 #endif
 	/* Deregister the device */
 	del_mtd_device (mtd);
+
+	/* Free bad block table memory, if allocated */
+	if (this->bbm)
+		kfree(this->bbm);
+	/* Buffer allocated by onenand_scan */
+	if (this->options & ONENAND_PAGEBUF_ALLOC)
+		kfree(this->page_buf);
 }
 
 EXPORT_SYMBOL_GPL(onenand_scan);
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index f40190f..4510d33 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -118,10 +118,10 @@
  */
 static inline int onenand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
 {
-	unsigned char data_buf[MAX_ONENAND_PAGESIZE];
+	struct onenand_chip *this = mtd->priv;
 
         bd->options &= ~NAND_BBT_SCANEMPTY;
-        return create_bbt(mtd, data_buf, bd, -1);
+	return create_bbt(mtd, this->page_buf, bd, -1);
 }
 
 /**
diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c
index 0ab8d29..a3e00a4 100644
--- a/drivers/mtd/rfd_ftl.c
+++ b/drivers/mtd/rfd_ftl.c
@@ -18,6 +18,7 @@
 #include <linux/mtd/blktrans.h>
 #include <linux/mtd/mtd.h>
 #include <linux/vmalloc.h>
+#include <linux/slab.h>
 #include <linux/jiffies.h>
 
 #include <asm/types.h>
@@ -30,11 +31,9 @@
 
 #define PREFIX "rfd_ftl: "
 
-/* Major device # for FTL device */
-
-/* A request for this major has been sent to device@lanana.org */
+/* This major has been assigned by device@lanana.org */
 #ifndef RFD_FTL_MAJOR
-#define RFD_FTL_MAJOR		95
+#define RFD_FTL_MAJOR		256
 #endif
 
 /* Maximum number of partitions in an FTL region */
diff --git a/drivers/net/3c527.h b/drivers/net/3c527.h
index c10f009..53b5b07 100644
--- a/drivers/net/3c527.h
+++ b/drivers/net/3c527.h
@@ -32,43 +32,43 @@
 
 struct mc32_mailbox
 {
-	u16	mbox __attribute((packed));
-	u16	data[1] __attribute((packed));
-};
+ 	u16 mbox;
+ 	u16 data[1];
+} __attribute((packed));
 
 struct skb_header
 {
-	u8	status __attribute((packed));
-	u8	control __attribute((packed));
-	u16	next __attribute((packed));	/* Do not change! */
-	u16	length __attribute((packed));
-	u32	data __attribute((packed));
-};
+	u8 status;
+	u8 control;
+	u16 next;	/* Do not change! */
+	u16 length;
+	u32 data;
+} __attribute((packed));
 
 struct mc32_stats
 {
 	/* RX Errors */
-	u32     rx_crc_errors       __attribute((packed)); 	
-	u32     rx_alignment_errors  __attribute((packed)); 	
-	u32     rx_overrun_errors    __attribute((packed));
-	u32     rx_tooshort_errors  __attribute((packed));
-	u32     rx_toolong_errors   __attribute((packed));
-	u32     rx_outofresource_errors  __attribute((packed)); 
+	u32 rx_crc_errors;
+	u32 rx_alignment_errors;
+	u32 rx_overrun_errors;
+	u32 rx_tooshort_errors;
+	u32 rx_toolong_errors;
+	u32 rx_outofresource_errors;
 
-	u32     rx_discarded   __attribute((packed));  /* via card pattern match filter */ 
+	u32 rx_discarded;  /* via card pattern match filter */
 
 	/* TX Errors */
-	u32     tx_max_collisions __attribute((packed)); 
-	u32     tx_carrier_errors __attribute((packed)); 
-	u32     tx_underrun_errors __attribute((packed)); 
-	u32     tx_cts_errors     __attribute((packed)); 
-	u32     tx_timeout_errors __attribute((packed)) ;
+	u32 tx_max_collisions;
+	u32 tx_carrier_errors;
+	u32 tx_underrun_errors;
+	u32 tx_cts_errors;
+	u32 tx_timeout_errors;
 	
 	/* various cruft */
-	u32     dataA[6] __attribute((packed));   
-        u16	dataB[5] __attribute((packed));   
-  	u32     dataC[14] __attribute((packed)); 	
-};
+	u32 dataA[6];
+	u16 dataB[5];
+	u32 dataC[14];
+} __attribute((packed));
 
 #define STATUS_MASK	0x0F
 #define COMPLETED	(1<<7)
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 30bee11..d2102a2 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -586,16 +586,16 @@
 	dma_addr_t tx_bufs_dma;
 	signed char phys[4];		/* MII device addresses. */
 	char twistie, twist_row, twist_col;	/* Twister tune state. */
-	unsigned int default_port:4;	/* Last dev->if_port value. */
+	unsigned int default_port : 4;	/* Last dev->if_port value. */
+	unsigned int have_thread : 1;
 	spinlock_t lock;
 	spinlock_t rx_lock;
 	chip_t chipset;
-	pid_t thr_pid;
-	wait_queue_head_t thr_wait;
-	struct completion thr_exited;
 	u32 rx_config;
 	struct rtl_extra_stats xstats;
-	int time_to_die;
+
+	struct work_struct thread;
+
 	struct mii_if_info mii;
 	unsigned int regs_len;
 	unsigned long fifo_copy_timeout;
@@ -620,7 +620,7 @@
 static int mdio_read (struct net_device *dev, int phy_id, int location);
 static void mdio_write (struct net_device *dev, int phy_id, int location,
 			int val);
-static void rtl8139_start_thread(struct net_device *dev);
+static void rtl8139_start_thread(struct rtl8139_private *tp);
 static void rtl8139_tx_timeout (struct net_device *dev);
 static void rtl8139_init_ring (struct net_device *dev);
 static int rtl8139_start_xmit (struct sk_buff *skb,
@@ -637,6 +637,7 @@
 static void rtl8139_set_rx_mode (struct net_device *dev);
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
+static void rtl8139_thread (void *_data);
 static struct ethtool_ops rtl8139_ethtool_ops;
 
 /* write MMIO register, with flush */
@@ -1007,8 +1008,7 @@
 		(debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
 	spin_lock_init (&tp->lock);
 	spin_lock_init (&tp->rx_lock);
-	init_waitqueue_head (&tp->thr_wait);
-	init_completion (&tp->thr_exited);
+	INIT_WORK(&tp->thread, rtl8139_thread, dev);
 	tp->mii.dev = dev;
 	tp->mii.mdio_read = mdio_read;
 	tp->mii.mdio_write = mdio_write;
@@ -1345,7 +1345,7 @@
 			dev->irq, RTL_R8 (MediaStatus),
 			tp->mii.full_duplex ? "full" : "half");
 
-	rtl8139_start_thread(dev);
+	rtl8139_start_thread(tp);
 
 	return 0;
 }
@@ -1594,55 +1594,43 @@
 		 RTL_R8 (Config1));
 }
 
-static int rtl8139_thread (void *data)
+static void rtl8139_thread (void *_data)
 {
-	struct net_device *dev = data;
+	struct net_device *dev = _data;
 	struct rtl8139_private *tp = netdev_priv(dev);
-	unsigned long timeout;
+	unsigned long thr_delay;
 
-	daemonize("%s", dev->name);
-	allow_signal(SIGTERM);
-
-	while (1) {
-		timeout = next_tick;
-		do {
-			timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
-			/* make swsusp happy with our thread */
-			try_to_freeze();
-		} while (!signal_pending (current) && (timeout > 0));
-
-		if (signal_pending (current)) {
-			flush_signals(current);
-		}
-
-		if (tp->time_to_die)
-			break;
-
-		if (rtnl_lock_interruptible ())
-			break;
+	if (rtnl_shlock_nowait() == 0) {
 		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
 		rtnl_unlock ();
+
+		thr_delay = next_tick;
+	} else {
+		/* unlikely race.  mitigate with fast poll. */
+		thr_delay = HZ / 2;
 	}
 
-	complete_and_exit (&tp->thr_exited, 0);
+	schedule_delayed_work(&tp->thread, thr_delay);
 }
 
-static void rtl8139_start_thread(struct net_device *dev)
+static void rtl8139_start_thread(struct rtl8139_private *tp)
 {
-	struct rtl8139_private *tp = netdev_priv(dev);
-
-	tp->thr_pid = -1;
 	tp->twistie = 0;
-	tp->time_to_die = 0;
 	if (tp->chipset == CH_8139_K)
 		tp->twistie = 1;
 	else if (tp->drv_flags & HAS_LNK_CHNG)
 		return;
 
-	tp->thr_pid = kernel_thread(rtl8139_thread, dev, CLONE_FS|CLONE_FILES);
-	if (tp->thr_pid < 0) {
-		printk (KERN_WARNING "%s: unable to start kernel thread\n",
-			dev->name);
+	tp->have_thread = 1;
+
+	schedule_delayed_work(&tp->thread, next_tick);
+}
+
+static void rtl8139_stop_thread(struct rtl8139_private *tp)
+{
+	if (tp->have_thread) {
+		cancel_rearming_delayed_work(&tp->thread);
+		tp->have_thread = 0;
 	}
 }
 
@@ -2224,22 +2212,12 @@
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
-	int ret = 0;
 	unsigned long flags;
 
 	netif_stop_queue (dev);
 
-	if (tp->thr_pid >= 0) {
-		tp->time_to_die = 1;
-		wmb();
-		ret = kill_proc (tp->thr_pid, SIGTERM, 1);
-		if (ret) {
-			printk (KERN_ERR "%s: unable to signal thread\n", dev->name);
-			return ret;
-		}
-		wait_for_completion (&tp->thr_exited);
-	}
-	
+	rtl8139_stop_thread(tp);
+
 	if (netif_msg_ifdown(tp))
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
 			dev->name, RTL_R16 (IntrStatus));
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ebd7313..1960961 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1374,7 +1374,7 @@
 
 config CS89x0
 	tristate "CS89x0 support"
-	depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105
+	depends on NET_PCI && (ISA || ARCH_IXDP2X01 || ARCH_PNX010X)
 	---help---
 	  Support for CS89x0 chipset based Ethernet cards. If you have a
 	  network (Ethernet) card of this type, say Y and read the
@@ -1901,6 +1901,8 @@
 
 	  If in doubt, say N.
 
+source "drivers/net/ixp2000/Kconfig"
+
 config MYRI_SBUS
 	tristate "MyriCOM Gigabit Ethernet support"
 	depends on SBUS
@@ -2008,7 +2010,18 @@
 
 	  It does not support the link failover and network management 
 	  features that "portable" vendor supplied sk98lin driver does.
-	
+
+
+config SKY2
+	tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
+	depends on PCI && EXPERIMENTAL
+	select CRC32
+	---help---
+	  This driver support the Marvell Yukon 2 Gigabit Ethernet adapter.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called sky2.  This is recommended.
+
 config SK98LIN
 	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
 	depends on PCI
@@ -2120,7 +2133,7 @@
 
 config SPIDER_NET
 	tristate "Spider Gigabit Ethernet driver"
-	depends on PCI && PPC_BPA
+	depends on PCI && PPC_CELL
 	help
 	  This driver supports the Gigabit Ethernet chips present on the
 	  Cell Processor-Based Blades from IBM.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 4cffd34..b74a7cb 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -13,7 +13,10 @@
 obj-$(CONFIG_BONDING) += bonding/
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
 
-gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
+gianfar_driver-objs := gianfar.o \
+		gianfar_ethtool.o \
+		gianfar_mii.o \
+		gianfar_sysfs.o
 
 #
 # link order important here
@@ -59,6 +62,7 @@
 obj-$(CONFIG_SPIDER_NET) += spidernet.o
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
+obj-$(CONFIG_SKY2) += sky2.o
 obj-$(CONFIG_SK98LIN) += sk98lin/
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
@@ -202,6 +206,7 @@
 obj-$(CONFIG_HAMRADIO) += hamradio/
 obj-$(CONFIG_IRDA) += irda/
 obj-$(CONFIG_ETRAX_ETHERNET) += cris/
+obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/
 
 obj-$(CONFIG_NETCONSOLE) += netconsole.o
 
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index c53848f..7aa49b9 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -28,8 +28,8 @@
 
 #define DRV_MODULE_NAME		"b44"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.96"
-#define DRV_MODULE_RELDATE	"Nov 8, 2005"
+#define DRV_MODULE_VERSION	"0.97"
+#define DRV_MODULE_RELDATE	"Nov 30, 2005"
 
 #define B44_DEF_MSG_ENABLE	  \
 	(NETIF_MSG_DRV		| \
@@ -1417,6 +1417,7 @@
 	add_timer(&bp->timer);
 
 	b44_enable_ints(bp);
+	netif_start_queue(dev);
 out:
 	return err;
 }
@@ -1837,12 +1838,15 @@
 {
 	struct mii_ioctl_data *data = if_mii(ifr);
 	struct b44 *bp = netdev_priv(dev);
-	int err;
+	int err = -EINVAL;
+
+	if (!netif_running(dev))
+		goto out;
 
 	spin_lock_irq(&bp->lock);
 	err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
 	spin_unlock_irq(&bp->lock);
-
+out:
 	return err;
 }
 
@@ -2113,6 +2117,7 @@
 	add_timer(&bp->timer);
 
 	b44_enable_ints(bp);
+	netif_wake_queue(dev);
 	return 0;
 }
 
diff --git a/drivers/net/bonding/Makefile b/drivers/net/bonding/Makefile
index cf50384..5cdae2b 100644
--- a/drivers/net/bonding/Makefile
+++ b/drivers/net/bonding/Makefile
@@ -4,5 +4,5 @@
 
 obj-$(CONFIG_BONDING) += bonding.o
 
-bonding-objs := bond_main.o bond_3ad.o bond_alb.o
+bonding-objs := bond_main.o bond_3ad.o bond_alb.o bond_sysfs.o
 
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index d2f34d5..f3f5825 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -18,38 +18,6 @@
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Amir Noam <amir.noam at intel dot com>
- *	- Added support for lacp_rate module param.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Based on discussion on mailing list, changed locking scheme
- *	  to use lock/unlock or lock_bh/unlock_bh appropriately instead
- *	  of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
- *	  hidden bugs and solves system hangs that occurred due to the fact
- *	  that holding lock_irqsave doesn't prevent softirqs from running.
- *	  This also increases total throughput since interrupts are not
- *	  blocked on each transmitted packets or monitor timeout.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Renamed bond_3ad_link_status_changed() to
- *	  bond_3ad_handle_link_change() for compatibility with TLB.
- *
- * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
- *	- Fix long fail over time when releasing last slave of an active
- *	  aggregator - send LACPDU on unbind of slave to tell partner this
- *	  port is no longer aggregatable.
- *
- * 2003/06/25 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
- *	- Send LACPDU as highest priority packet to further fix the above
- *	  problem on very high Tx traffic load where packets may get dropped
- *	  by the slave.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
  */
 
 //#define BONDING_DEBUG 1
@@ -1198,10 +1166,10 @@
 			// detect loopback situation
 			if (!MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->actor_system))) {
 				// INFO_RECEIVED_LOOPBACK_FRAMES
-				printk(KERN_ERR DRV_NAME ": An illegal loopback occurred on adapter (%s)\n",
-						port->slave->dev->name);
-				printk(KERN_ERR "Check the configuration to verify that all Adapters "
-						"are connected to 802.3ad compliant switch ports\n");
+				printk(KERN_ERR DRV_NAME ": %s: An illegal loopback occurred on "
+				       "adapter (%s). Check the configuration to verify that all "
+				       "Adapters are connected to 802.3ad compliant switch ports\n",
+				       port->slave->dev->master->name, port->slave->dev->name);
 				__release_rx_machine_lock(port);
 				return;
 			}
@@ -1378,8 +1346,9 @@
 			}
 		}
 		if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list
-			printk(KERN_WARNING DRV_NAME ": Warning: Port %d (on %s) was "
+			printk(KERN_WARNING DRV_NAME ": %s: Warning: Port %d (on %s) was "
 			       "related to aggregator %d but was not on its port list\n",
+			       port->slave->dev->master->name,
 			       port->actor_port_number, port->slave->dev->name,
 			       port->aggregator->aggregator_identifier);
 		}
@@ -1450,7 +1419,8 @@
 
 			dprintk("Port %d joined LAG %d(new LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier);
 		} else {
-			printk(KERN_ERR DRV_NAME ": Port %d (on %s) did not find a suitable aggregator\n",
+			printk(KERN_ERR DRV_NAME ": %s: Port %d (on %s) did not find a suitable aggregator\n",
+			       port->slave->dev->master->name,
 			       port->actor_port_number, port->slave->dev->name);
 		}
 	}
@@ -1582,8 +1552,9 @@
 
 		// check if any partner replys
 		if (best_aggregator->is_individual) {
-			printk(KERN_WARNING DRV_NAME ": Warning: No 802.3ad response from the link partner "
-					"for any adapters in the bond\n");
+			printk(KERN_WARNING DRV_NAME ": %s: Warning: No 802.3ad response from "
+			       "the link partner for any adapters in the bond\n",
+			       best_aggregator->slave->dev->master->name);
 		}
 
 		// check if there are more than one aggregator
@@ -1915,7 +1886,8 @@
 	struct aggregator *aggregator;
 
 	if (bond == NULL) {
-		printk(KERN_ERR "The slave %s is not attached to its bond\n", slave->dev->name);
+		printk(KERN_ERR DRV_NAME ": %s: The slave %s is not attached to its bond\n",
+		       slave->dev->master->name, slave->dev->name);
 		return -1;
 	}
 
@@ -1990,7 +1962,9 @@
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Trying to unbind an uninitialized port on %s\n", slave->dev->name);
+		printk(KERN_WARNING DRV_NAME ": Warning: %s: Trying to "
+		       "unbind an uninitialized port on %s\n",
+		       slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2021,7 +1995,8 @@
 				dprintk("Some port(s) related to LAG %d - replaceing with LAG %d\n", aggregator->aggregator_identifier, new_aggregator->aggregator_identifier);
 
 				if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) {
-					printk(KERN_INFO DRV_NAME ": Removing an active aggregator\n");
+					printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+					       aggregator->slave->dev->master->name);
 					// select new active aggregator
 					 select_new_active_agg = 1;
 				}
@@ -2051,15 +2026,17 @@
 					ad_agg_selection_logic(__get_first_agg(port));
 				}
 			} else {
-				printk(KERN_WARNING DRV_NAME ": Warning: unbinding aggregator, "
-				       "and could not find a new aggregator for its ports\n");
+				printk(KERN_WARNING DRV_NAME ": %s: Warning: unbinding aggregator, "
+				       "and could not find a new aggregator for its ports\n",
+				       slave->dev->master->name);
 			}
 		} else { // in case that the only port related to this aggregator is the one we want to remove
 			select_new_active_agg = aggregator->is_active;
 			// clear the aggregator
 			ad_clear_agg(aggregator);
 			if (select_new_active_agg) {
-				printk(KERN_INFO "Removing an active aggregator\n");
+				printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+				       slave->dev->master->name);
 				// select new active aggregator
 				ad_agg_selection_logic(__get_first_agg(port));
 			}
@@ -2085,7 +2062,8 @@
 					// clear the aggregator
 					ad_clear_agg(temp_aggregator);
 					if (select_new_active_agg) {
-						printk(KERN_INFO "Removing an active aggregator\n");
+						printk(KERN_INFO DRV_NAME ": %s: Removing an active aggregator\n",
+						       slave->dev->master->name);
 						// select new active aggregator
 						ad_agg_selection_logic(__get_first_agg(port));
 					}
@@ -2131,7 +2109,8 @@
 		// select the active aggregator for the bond
 		if ((port = __get_first_port(bond))) {
 			if (!port->slave) {
-				printk(KERN_WARNING DRV_NAME ": Warning: bond's first port is uninitialized\n");
+				printk(KERN_WARNING DRV_NAME ": %s: Warning: bond's first port is "
+				       "uninitialized\n", bond->dev->name);
 				goto re_arm;
 			}
 
@@ -2143,7 +2122,8 @@
 	// for each port run the state machines
 	for (port = __get_first_port(bond); port; port = __get_next_port(port)) {
 		if (!port->slave) {
-			printk(KERN_WARNING DRV_NAME ": Warning: Found an uninitialized port\n");
+			printk(KERN_WARNING DRV_NAME ": %s: Warning: Found an uninitialized "
+			       "port\n", bond->dev->name);
 			goto re_arm;
 		}
 
@@ -2184,7 +2164,8 @@
 		port = &(SLAVE_AD_INFO(slave).port);
 
 		if (!port->slave) {
-			printk(KERN_WARNING DRV_NAME ": Warning: port of slave %s is uninitialized\n", slave->dev->name);
+			printk(KERN_WARNING DRV_NAME ": %s: Warning: port of slave %s is "
+			       "uninitialized\n", slave->dev->name, slave->dev->master->name);
 			return;
 		}
 
@@ -2230,8 +2211,9 @@
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Warning: speed changed for uninitialized port on %s\n",
-		       slave->dev->name);
+		printk(KERN_WARNING DRV_NAME ": Warning: %s: speed "
+		       "changed for uninitialized port on %s\n",
+		       slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2257,8 +2239,9 @@
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Warning: duplex changed for uninitialized port on %s\n",
-		       slave->dev->name);
+		printk(KERN_WARNING DRV_NAME ": %s: Warning: duplex changed "
+		       "for uninitialized port on %s\n",
+		       slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2285,8 +2268,9 @@
 
 	// if slave is null, the whole port is not initialized
 	if (!port->slave) {
-		printk(KERN_WARNING DRV_NAME ": Warning: link status changed for uninitialized port on %s\n",
-			slave->dev->name);
+		printk(KERN_WARNING DRV_NAME ": Warning: %s: link status changed for "
+		       "uninitialized port on %s\n",
+			slave->dev->master->name, slave->dev->name);
 		return;
 	}
 
@@ -2363,7 +2347,8 @@
 	}
 
 	if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
-		printk(KERN_DEBUG "ERROR: bond_3ad_get_active_agg_info failed\n");
+		printk(KERN_DEBUG DRV_NAME ": %s: Error: "
+		       "bond_3ad_get_active_agg_info failed\n", dev->name);
 		goto out;
 	}
 
@@ -2372,7 +2357,9 @@
 
 	if (slaves_in_agg == 0) {
 		/*the aggregator is empty*/
-		printk(KERN_DEBUG "ERROR: active aggregator is empty\n");
+		printk(KERN_DEBUG DRV_NAME ": %s: Error: active "
+		       "aggregator is empty\n",
+		       dev->name);
 		goto out;
 	}
 
@@ -2390,7 +2377,8 @@
 	}
 
 	if (slave_agg_no >= 0) {
-		printk(KERN_ERR DRV_NAME ": Error: Couldn't find a slave to tx on for aggregator ID %d\n", agg_id);
+		printk(KERN_ERR DRV_NAME ": %s: Error: Couldn't find a slave to tx on "
+		       "for aggregator ID %d\n", dev->name, agg_id);
 		goto out;
 	}
 
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 673a30a..5ee2cef 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -18,19 +18,6 @@
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Amir Noam <amir.noam at intel dot com>
- *	- Added support for lacp_rate module param.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Renamed bond_3ad_link_status_changed() to
- *	  bond_3ad_handle_link_change() for compatibility with TLB.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
  */
 
 #ifndef __BOND_3AD_H__
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index f8fce39..854ddfb 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -18,25 +18,6 @@
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/06/25 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Fixed signed/unsigned calculation errors that caused load sharing
- *	  to collapse to one slave under very heavy UDP Tx stress.
- *
- * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
- *	- Add support for setting bond's MAC address with special
- *	  handling required for ALB/TLB.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
- *
- * 2003/12/30 - Amir Noam <amir.noam at intel dot com>
- *	- Fixed: Cannot remove and re-enslave the original active slave.
- *
- * 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Add capability to tag self generated packets in ALB/TLB modes.
  */
 
 //#define BONDING_DEBUG 1
@@ -198,20 +179,21 @@
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 	int size = TLB_HASH_TABLE_SIZE * sizeof(struct tlb_client_info);
+	struct tlb_client_info *new_hashtbl;
 	int i;
 
 	spin_lock_init(&(bond_info->tx_hashtbl_lock));
 
-	_lock_tx_hashtbl(bond);
-
-	bond_info->tx_hashtbl = kmalloc(size, GFP_KERNEL);
-	if (!bond_info->tx_hashtbl) {
+	new_hashtbl = kmalloc(size, GFP_KERNEL);
+	if (!new_hashtbl) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: %s: Failed to allocate TLB hash table\n",
+		       ": %s: Error: Failed to allocate TLB hash table\n",
 		       bond->dev->name);
-		_unlock_tx_hashtbl(bond);
 		return -1;
 	}
+	_lock_tx_hashtbl(bond);
+
+	bond_info->tx_hashtbl = new_hashtbl;
 
 	memset(bond_info->tx_hashtbl, 0, size);
 
@@ -513,7 +495,8 @@
 				 client_info->mac_dst);
 		if (!skb) {
 			printk(KERN_ERR DRV_NAME
-			       ": Error: failed to create an ARP packet\n");
+			       ": %s: Error: failed to create an ARP packet\n",
+			       client_info->slave->dev->master->name);
 			continue;
 		}
 
@@ -523,7 +506,8 @@
 			skb = vlan_put_tag(skb, client_info->vlan_id);
 			if (!skb) {
 				printk(KERN_ERR DRV_NAME
-				       ": Error: failed to insert VLAN tag\n");
+				       ": %s: Error: failed to insert VLAN tag\n",
+				       client_info->slave->dev->master->name);
 				continue;
 			}
 		}
@@ -606,8 +590,9 @@
 
 		if (!client_info->slave) {
 			printk(KERN_ERR DRV_NAME
-			       ": Error: found a client with no channel in "
-			       "the client's hash table\n");
+			       ": %s: Error: found a client with no channel in "
+			       "the client's hash table\n",
+			       bond->dev->name);
 			continue;
 		}
 		/*update all clients using this src_ip, that are not assigned
@@ -797,21 +782,22 @@
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 	struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
+	struct rlb_client_info	*new_hashtbl;
 	int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
 	int i;
 
 	spin_lock_init(&(bond_info->rx_hashtbl_lock));
 
-	_lock_rx_hashtbl(bond);
-
-	bond_info->rx_hashtbl = kmalloc(size, GFP_KERNEL);
-	if (!bond_info->rx_hashtbl) {
+	new_hashtbl = kmalloc(size, GFP_KERNEL);
+	if (!new_hashtbl) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: %s: Failed to allocate RLB hash table\n",
+		       ": %s: Error: Failed to allocate RLB hash table\n",
 		       bond->dev->name);
-		_unlock_rx_hashtbl(bond);
 		return -1;
 	}
+	_lock_rx_hashtbl(bond);
+
+	bond_info->rx_hashtbl = new_hashtbl;
 
 	bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
 
@@ -927,7 +913,8 @@
 			skb = vlan_put_tag(skb, vlan->vlan_id);
 			if (!skb) {
 				printk(KERN_ERR DRV_NAME
-				       ": Error: failed to insert VLAN tag\n");
+				       ": %s: Error: failed to insert VLAN tag\n",
+				       bond->dev->name);
 				continue;
 			}
 		}
@@ -956,11 +943,11 @@
 	s_addr.sa_family = dev->type;
 	if (dev_set_mac_address(dev, &s_addr)) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: dev_set_mac_address of dev %s failed! ALB "
+		       ": %s: Error: dev_set_mac_address of dev %s failed! ALB "
 		       "mode requires that the base driver support setting "
 		       "the hw address also when the network device's "
 		       "interface is open\n",
-		       dev->name);
+		       dev->master->name, dev->name);
 		return -EOPNOTSUPP;
 	}
 	return 0;
@@ -1153,16 +1140,16 @@
 				       bond->alb_info.rlb_enabled);
 
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning: the hw address of slave %s is in use by "
+		       ": %s: Warning: the hw address of slave %s is in use by "
 		       "the bond; giving it the hw address of %s\n",
-		       slave->dev->name, free_mac_slave->dev->name);
+		       bond->dev->name, slave->dev->name, free_mac_slave->dev->name);
 
 	} else if (has_bond_addr) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: the hw address of slave %s is in use by the "
+		       ": %s: Error: the hw address of slave %s is in use by the "
 		       "bond; couldn't find a slave with a free hw address to "
 		       "give it (this should not have happened)\n",
-		       slave->dev->name);
+		       bond->dev->name, slave->dev->name);
 		return -EFAULT;
 	}
 
@@ -1250,6 +1237,8 @@
 			tlb_deinitialize(bond);
 			return res;
 		}
+	} else {
+		bond->alb_info.rlb_enabled = 0;
 	}
 
 	return 0;
@@ -1409,7 +1398,7 @@
 		read_lock(&bond->curr_slave_lock);
 
 		bond_for_each_slave(bond, slave, i) {
-			alb_send_learning_packets(slave,slave->dev->dev_addr);
+			alb_send_learning_packets(slave, slave->dev->dev_addr);
 		}
 
 		read_unlock(&bond->curr_slave_lock);
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index e4091cd..28f2a2f 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -18,15 +18,6 @@
  * The full GNU General Public License is included in this distribution in the
  * file called LICENSE.
  *
- *
- * Changes:
- *
- * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
- *	- Add support for setting bond's MAC address with special
- *	  handling required for ALB/TLB.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
  */
 
 #ifndef __BOND_ALB_H__
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 94cec3c..2582d98 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -29,466 +29,6 @@
  *	b: if a hw mac address already is there, eth0's hw mac address
  *	   will then be set from bond0.
  *
- * v0.1 - first working version.
- * v0.2 - changed stats to be calculated by summing slaves stats.
- *
- * Changes:
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * - fix leaks on failure at bond_init
- *
- * 2000/09/30 - Willy Tarreau <willy at meta-x.org>
- *     - added trivial code to release a slave device.
- *     - fixed security bug (CAP_NET_ADMIN not checked)
- *     - implemented MII link monitoring to disable dead links :
- *       All MII capable slaves are checked every <miimon> milliseconds
- *       (100 ms seems good). This value can be changed by passing it to
- *       insmod. A value of zero disables the monitoring (default).
- *     - fixed an infinite loop in bond_xmit_roundrobin() when there's no
- *       good slave.
- *     - made the code hopefully SMP safe
- *
- * 2000/10/03 - Willy Tarreau <willy at meta-x.org>
- *     - optimized slave lists based on relevant suggestions from Thomas Davis
- *     - implemented active-backup method to obtain HA with two switches:
- *       stay as long as possible on the same active interface, while we
- *       also monitor the backup one (MII link status) because we want to know
- *       if we are able to switch at any time. ( pass "mode=1" to insmod )
- *     - lots of stress testings because we need it to be more robust than the
- *       wires ! :->
- *
- * 2000/10/09 - Willy Tarreau <willy at meta-x.org>
- *     - added up and down delays after link state change.
- *     - optimized the slaves chaining so that when we run forward, we never
- *       repass through the bond itself, but we can find it by searching
- *       backwards. Renders the deletion more difficult, but accelerates the
- *       scan.
- *     - smarter enslaving and releasing.
- *     - finer and more robust SMP locking
- *
- * 2000/10/17 - Willy Tarreau <willy at meta-x.org>
- *     - fixed two potential SMP race conditions
- *
- * 2000/10/18 - Willy Tarreau <willy at meta-x.org>
- *     - small fixes to the monitoring FSM in case of zero delays
- * 2000/11/01 - Willy Tarreau <willy at meta-x.org>
- *     - fixed first slave not automatically used in trunk mode.
- * 2000/11/10 : spelling of "EtherChannel" corrected.
- * 2000/11/13 : fixed a race condition in case of concurrent accesses to ioctl().
- * 2000/12/16 : fixed improper usage of rtnl_exlock_nowait().
- *
- * 2001/1/3 - Chad N. Tindel <ctindel at ieee dot org>
- *     - The bonding driver now simulates MII status monitoring, just like
- *       a normal network device.  It will show that the link is down iff
- *       every slave in the bond shows that their links are down.  If at least
- *       one slave is up, the bond's MII status will appear as up.
- *
- * 2001/2/7 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Applications can now query the bond from user space to get
- *       information which may be useful.  They do this by calling
- *       the BOND_INFO_QUERY ioctl.  Once the app knows how many slaves
- *       are in the bond, it can call the BOND_SLAVE_INFO_QUERY ioctl to
- *       get slave specific information (# link failures, etc).  See
- *       <linux/if_bonding.h> for more details.  The structs of interest
- *       are ifbond and ifslave.
- *
- * 2001/4/5 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Ported to 2.4 Kernel
- *
- * 2001/5/2 - Jeffrey E. Mast <jeff at mastfamily dot com>
- *     - When a device is detached from a bond, the slave device is no longer
- *       left thinking that is has a master.
- *
- * 2001/5/16 - Jeffrey E. Mast <jeff at mastfamily dot com>
- *     - memset did not appropriately initialized the bond rw_locks. Used
- *       rwlock_init to initialize to unlocked state to prevent deadlock when
- *       first attempting a lock
- *     - Called SET_MODULE_OWNER for bond device
- *
- * 2001/5/17 - Tim Anderson <tsa at mvista.com>
- *     - 2 paths for releasing for slave release; 1 through ioctl
- *       and 2) through close. Both paths need to release the same way.
- *     - the free slave in bond release is changing slave status before
- *       the free. The netdev_set_master() is intended to change slave state
- *       so it should not be done as part of the release process.
- *     - Simple rule for slave state at release: only the active in A/B and
- *       only one in the trunked case.
- *
- * 2001/6/01 - Tim Anderson <tsa at mvista.com>
- *     - Now call dev_close when releasing a slave so it doesn't screw up
- *       out routing table.
- *
- * 2001/6/01 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Added /proc support for getting bond and slave information.
- *       Information is in /proc/net/<bond device>/info.
- *     - Changed the locking when calling bond_close to prevent deadlock.
- *
- * 2001/8/05 - Janice Girouard <girouard at us.ibm.com>
- *     - correct problem where refcnt of slave is not incremented in bond_ioctl
- *       so the system hangs when halting.
- *     - correct locking problem when unable to malloc in bond_enslave.
- *     - adding bond_xmit_xor logic.
- *     - adding multiple bond device support.
- *
- * 2001/8/13 - Erik Habbinga <erik_habbinga at hp dot com>
- *     - correct locking problem with rtnl_exlock_nowait
- *
- * 2001/8/23 - Janice Girouard <girouard at us.ibm.com>
- *     - bzero initial dev_bonds, to correct oops
- *     - convert SIOCDEVPRIVATE to new MII ioctl calls
- *
- * 2001/9/13 - Takao Indoh <indou dot takao at jp dot fujitsu dot com>
- *     - Add the BOND_CHANGE_ACTIVE ioctl implementation
- *
- * 2001/9/14 - Mark Huth <mhuth at mvista dot com>
- *     - Change MII_LINK_READY to not check for end of auto-negotiation,
- *       but only for an up link.
- *
- * 2001/9/20 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Add the device field to bonding_t.  Previously the net_device
- *       corresponding to a bond wasn't available from the bonding_t
- *       structure.
- *
- * 2001/9/25 - Janice Girouard <girouard at us.ibm.com>
- *     - add arp_monitor for active backup mode
- *
- * 2001/10/23 - Takao Indoh <indou dot takao at jp dot fujitsu dot com>
- *     - Various memory leak fixes
- *
- * 2001/11/5 - Mark Huth <mark dot huth at mvista dot com>
- *     - Don't take rtnl lock in bond_mii_monitor as it deadlocks under
- *       certain hotswap conditions.
- *       Note:  this same change may be required in bond_arp_monitor ???
- *     - Remove possibility of calling bond_sethwaddr with NULL slave_dev ptr
- *     - Handle hot swap ethernet interface deregistration events to remove
- *       kernel oops following hot swap of enslaved interface
- *
- * 2002/1/2 - Chad N. Tindel <ctindel at ieee dot org>
- *     - Restore original slave flags at release time.
- *
- * 2002/02/18 - Erik Habbinga <erik_habbinga at hp dot com>
- *     - bond_release(): calling kfree on our_slave after call to
- *       bond_restore_slave_flags, not before
- *     - bond_enslave(): saving slave flags into original_flags before
- *       call to netdev_set_master, so the IFF_SLAVE flag doesn't end
- *       up in original_flags
- *
- * 2002/04/05 - Mark Smith <mark.smith at comdev dot cc> and
- *              Steve Mead <steve.mead at comdev dot cc>
- *     - Port Gleb Natapov's multicast support patchs from 2.4.12
- *       to 2.4.18 adding support for multicast.
- *
- * 2002/06/10 - Tony Cureington <tony.cureington * hp_com>
- *     - corrected uninitialized pointer (ifr.ifr_data) in bond_check_dev_link;
- *       actually changed function to use MIIPHY, then MIIREG, and finally
- *       ETHTOOL to determine the link status
- *     - fixed bad ifr_data pointer assignments in bond_ioctl
- *     - corrected mode 1 being reported as active-backup in bond_get_info;
- *       also added text to distinguish type of load balancing (rr or xor)
- *     - change arp_ip_target module param from "1-12s" (array of 12 ptrs)
- *       to "s" (a single ptr)
- *
- * 2002/08/30 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Removed acquisition of xmit_lock in set_multicast_list; caused
- *       deadlock on SMP (lock is held by caller).
- *     - Revamped SIOCGMIIPHY, SIOCGMIIREG portion of bond_check_dev_link().
- *
- * 2002/09/18 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - Fixed up bond_check_dev_link() (and callers): removed some magic
- *	 numbers, banished local MII_ defines, wrapped ioctl calls to
- *	 prevent EFAULT errors
- *
- * 2002/9/30 - Jay Vosburgh <fubar at us dot ibm dot com>
- *     - make sure the ip target matches the arp_target before saving the
- *	 hw address.
- *
- * 2002/9/30 - Dan Eisner <eisner at 2robots dot com>
- *     - make sure my_ip is set before taking down the link, since
- *	 not all switches respond if the source ip is not set.
- *
- * 2002/10/8 - Janice Girouard <girouard at us dot ibm dot com>
- *     - read in the local ip address when enslaving a device
- *     - add primary support
- *     - make sure 2*arp_interval has passed when a new device
- *       is brought on-line before taking it down.
- *
- * 2002/09/11 - Philippe De Muyter <phdm at macqel dot be>
- *     - Added bond_xmit_broadcast logic.
- *     - Added bond_mode() support function.
- *
- * 2002/10/26 - Laurent Deniel <laurent.deniel at free.fr>
- *     - allow to register multicast addresses only on active slave
- *       (useful in active-backup mode)
- *     - add multicast module parameter
- *     - fix deletion of multicast groups after unloading module
- *
- * 2002/11/06 - Kameshwara Rayaprolu <kameshwara.rao * wipro_com>
- *     - Changes to prevent panic from closing the device twice; if we close
- *       the device in bond_release, we must set the original_flags to down
- *       so it won't be closed again by the network layer.
- *
- * 2002/11/07 - Tony Cureington <tony.cureington * hp_com>
- *     - Fix arp_target_hw_addr memory leak
- *     - Created activebackup_arp_monitor function to handle arp monitoring
- *       in active backup mode - the bond_arp_monitor had several problems...
- *       such as allowing slaves to tx arps sequentially without any delay
- *       for a response
- *     - Renamed bond_arp_monitor to loadbalance_arp_monitor and re-wrote
- *       this function to just handle arp monitoring in load-balancing mode;
- *       it is a lot more compact now
- *     - Changes to ensure one and only one slave transmits in active-backup
- *       mode
- *     - Robustesize parameters; warn users about bad combinations of
- *       parameters; also if miimon is specified and a network driver does
- *       not support MII or ETHTOOL, inform the user of this
- *     - Changes to support link_failure_count when in arp monitoring mode
- *     - Fix up/down delay reported in /proc
- *     - Added version; log version; make version available from "modinfo -d"
- *     - Fixed problem in bond_check_dev_link - if the first IOCTL (SIOCGMIIPH)
- *	 failed, the ETHTOOL ioctl never got a chance
- *
- * 2002/11/16 - Laurent Deniel <laurent.deniel at free.fr>
- *     - fix multicast handling in activebackup_arp_monitor
- *     - remove one unnecessary and confusing curr_active_slave == slave test
- *	 in activebackup_arp_monitor
- *
- *  2002/11/17 - Laurent Deniel <laurent.deniel at free.fr>
- *     - fix bond_slave_info_query when slave_id = num_slaves
- *
- *  2002/11/19 - Janice Girouard <girouard at us dot ibm dot com>
- *     - correct ifr_data reference.  Update ifr_data reference
- *       to mii_ioctl_data struct values to avoid confusion.
- *
- *  2002/11/22 - Bert Barbe <bert.barbe at oracle dot com>
- *      - Add support for multiple arp_ip_target
- *
- *  2002/12/13 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- Changed to allow text strings for mode and multicast, e.g.,
- *	  insmod bonding mode=active-backup.  The numbers still work.
- *	  One change: an invalid choice will cause module load failure,
- *	  rather than the previous behavior of just picking one.
- *	- Minor cleanups; got rid of dup ctype stuff, atoi function
- *
- * 2003/02/07 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- Added use_carrier module parameter that causes miimon to
- *	  use netif_carrier_ok() test instead of MII/ETHTOOL ioctls.
- *	- Minor cleanups; consolidated ioctl calls to one function.
- *
- * 2003/02/07 - Tony Cureington <tony.cureington * hp_com>
- *	- Fix bond_mii_monitor() logic error that could result in
- *	  bonding round-robin mode ignoring links after failover/recovery
- *
- * 2003/03/17 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- kmalloc fix (GFP_KERNEL to GFP_ATOMIC) reported by
- *	  Shmulik dot Hen at intel.com.
- *	- Based on discussion on mailing list, changed use of
- *	  update_slave_cnt(), created wrapper functions for adding/removing
- *	  slaves, changed bond_xmit_xor() to check slave_cnt instead of
- *	  checking slave and slave->dev (which only worked by accident).
- *	- Misc code cleanup: get arp_send() prototype from header file,
- *	  add max_bonds to bonding.txt.
- *
- * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Make sure only bond_attach_slave() and bond_detach_slave() can
- *	  manipulate the slave list, including slave_cnt, even when in
- *	  bond_release_all().
- *	- Fixed hang in bond_release() with traffic running:
- *	  netdev_set_master() must not be called from within the bond lock.
- *
- * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Fixed hang in bond_enslave() with traffic running:
- *	  netdev_set_master() must not be called from within the bond lock.
- *
- * 2003/03/18 - Amir Noam <amir.noam at intel dot com>
- *	- Added support for getting slave's speed and duplex via ethtool.
- *	  Needed for 802.3ad and other future modes.
- *
- * 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Enable support of modes that need to use the unique mac address of
- *	  each slave.
- *	  * bond_enslave(): Moved setting the slave's mac address, and
- *	    openning it, from the application to the driver. This breaks
- *	    backward comaptibility with old versions of ifenslave that open
- *	     the slave before enalsving it !!!.
- *	  * bond_release(): The driver also takes care of closing the slave
- *	    and restoring its original mac address.
- *	- Removed the code that restores all base driver's flags.
- *	  Flags are automatically restored once all undo stages are done
- *	  properly.
- *	- Block possibility of enslaving before the master is up. This
- *	  prevents putting the system in an unstable state.
- *
- * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
- *		Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Added support for IEEE 802.3ad Dynamic link aggregation mode.
- *
- * 2003/05/01 - Amir Noam <amir.noam at intel dot com>
- *	- Added ABI version control to restore compatibility between
- *	  new/old ifenslave and new/old bonding.
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Fixed bug in bond_release_all(): save old value of curr_active_slave
- *	  before setting it to NULL.
- *	- Changed driver versioning scheme to include version number instead
- *	  of release date (that is already in another field). There are 3
- *	  fields X.Y.Z where:
- *		X - Major version - big behavior changes
- *		Y - Minor version - addition of features
- *		Z - Extra version - minor changes and bug fixes
- *	  The current version is 1.0.0 as a base line.
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Amir Noam <amir.noam at intel dot com>
- *	- Added support for lacp_rate module param.
- *	- Code beautification and style changes (mainly in comments).
- *	  new version - 1.0.1
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Based on discussion on mailing list, changed locking scheme
- *	  to use lock/unlock or lock_bh/unlock_bh appropriately instead
- *	  of lock_irqsave/unlock_irqrestore. The new scheme helps exposing
- *	  hidden bugs and solves system hangs that occurred due to the fact
- *	  that holding lock_irqsave doesn't prevent softirqs from running.
- *	  This also increases total throughput since interrupts are not
- *	  blocked on each transmitted packets or monitor timeout.
- *	  new version - 2.0.0
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Added support for Transmit load balancing mode.
- *	- Concentrate all assignments of curr_active_slave to a single point
- *	  so specific modes can take actions when the primary adapter is
- *	  changed.
- *	- Take the updelay parameter into consideration during bond_enslave
- *	  since some adapters loose their link during setting the device.
- *	- Renamed bond_3ad_link_status_changed() to
- *	  bond_3ad_handle_link_change() for compatibility with TLB.
- *	  new version - 2.1.0
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com>
- *	- Added support for Adaptive load balancing mode which is
- *	  equivalent to Transmit load balancing + Receive load balancing.
- *	  new version - 2.2.0
- *
- * 2003/05/15 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- Applied fix to activebackup_arp_monitor posted to bonding-devel
- *	  by Tony Cureington <tony.cureington * hp_com>.  Fixes ARP
- *	  monitor endless failover bug.  Version to 2.2.10
- *
- * 2003/05/20 - Amir Noam <amir.noam at intel dot com>
- *	- Fixed bug in ABI version control - Don't commit to a specific
- *	  ABI version if receiving unsupported ioctl commands.
- *
- * 2003/05/22 - Jay Vosburgh <fubar at us dot ibm dot com>
- *	- Fix ifenslave -c causing bond to loose existing routes;
- *	  added bond_set_mac_address() that doesn't require the
- *	  bond to be down.
- *	- In conjunction with fix for ifenslave -c, in
- *	  bond_change_active(), changing to the already active slave
- *	  is no longer an error (it successfully does nothing).
- *
- * 2003/06/30 - Amir Noam <amir.noam at intel dot com>
- * 	- Fixed bond_change_active() for ALB/TLB modes.
- *	  Version to 2.2.14.
- *
- * 2003/07/29 - Amir Noam <amir.noam at intel dot com>
- * 	- Fixed ARP monitoring bug.
- *	  Version to 2.2.15.
- *
- * 2003/07/31 - Willy Tarreau <willy at ods dot org>
- * 	- Fixed kernel panic when using ARP monitoring without
- *	  setting bond's IP address.
- *	  Version to 2.2.16.
- *
- * 2003/08/06 - Amir Noam <amir.noam at intel dot com>
- * 	- Back port from 2.6: use alloc_netdev(); fix /proc handling;
- *	  made stats a part of bond struct so no need to allocate
- *	  and free it separately; use standard list operations instead
- *	  of pre-allocated array of bonds.
- *	  Version to 2.3.0.
- *
- * 2003/08/07 - Jay Vosburgh <fubar at us dot ibm dot com>,
- *	       Amir Noam <amir.noam at intel dot com> and
- *	       Shmulik Hen <shmulik.hen at intel dot com>
- *	- Propagating master's settings: Distinguish between modes that
- *	  use a primary slave from those that don't, and propagate settings
- *	  accordingly; Consolidate change_active opeartions and add
- *	  reselect_active and find_best opeartions; Decouple promiscuous
- *	  handling from the multicast mode setting; Add support for changing
- *	  HW address and MTU with proper unwind; Consolidate procfs code,
- *	  add CHANGENAME handler; Enhance netdev notification handling.
- *	  Version to 2.4.0.
- *
- * 2003/09/15 - Stephen Hemminger <shemminger at osdl dot org>,
- *	       Amir Noam <amir.noam at intel dot com>
- *	- Convert /proc to seq_file interface.
- *	  Change /proc/net/bondX/info to /proc/net/bonding/bondX.
- *	  Set version to 2.4.1.
- *
- * 2003/11/20 - Amir Noam <amir.noam at intel dot com>
- *	- Fix /proc creation/destruction.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Massive cleanup - Set version to 2.5.0
- *	  Code changes:
- *	  o Consolidate format of prints and debug prints.
- *	  o Remove bonding_t/slave_t typedefs and consolidate all casts.
- *	  o Remove dead code and unnecessary checks.
- *	  o Consolidate starting/stopping timers.
- *	  o Consolidate handling of primary module param throughout the code.
- *	  o Removed multicast module param support - all settings are done
- *	    according to mode.
- *	  o Slave list iteration - bond is no longer part of the list,
- *	    added cyclic list iteration macros.
- *	  o Consolidate error handling in all xmit functions.
- *	  Style changes:
- *	  o Consolidate function naming and declarations.
- *	  o Consolidate function params and local variables names.
- *	  o Consolidate return values.
- *	  o Consolidate curly braces.
- *	  o Consolidate conditionals format.
- *	  o Change struct member names and types.
- *	  o Chomp trailing spaces, remove empty lines, fix indentations.
- *	  o Re-organize code according to context.
- *
- * 2003/12/30 - Amir Noam <amir.noam at intel dot com>
- *	- Fixed: Cannot remove and re-enslave the original active slave.
- *	- Fixed: Releasing the original active slave causes mac address
- *		 duplication.
- *	- Add support for slaves that use ethtool_ops.
- *	  Set version to 2.5.3.
- *
- * 2004/01/05 - Amir Noam <amir.noam at intel dot com>
- *	- Save bonding parameters per bond instead of using the global values.
- *	  Set version to 2.5.4.
- *
- * 2004/01/14 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Enhance VLAN support:
- *	  * Add support for VLAN hardware acceleration capable slaves.
- *	  * Add capability to tag self generated packets in ALB/TLB modes.
- *	  Set version to 2.6.0.
- * 2004/10/29 - Mitch Williams <mitch.a.williams at intel dot com>
- *      - Fixed bug when unloading module while using 802.3ad.  If
- *        spinlock debugging is turned on, this causes a stack dump.
- *        Solution is to move call to dev_remove_pack outside of the
- *        spinlock.
- *        Set version to 2.6.1.
- * 2005/06/05 - Jay Vosburgh <fubar@us.ibm.com>
- * 	- Support for generating gratuitous ARPs in active-backup mode.
- * 	  Includes support for VLAN tagging all bonding-generated ARPs
- * 	  as needed.  Set version to 2.6.2.
- * 2005/06/08 - Jason Gabler <jygabler at lbl dot gov>
- *	- alternate hashing policy support for mode 2
- *	  * Added kernel parameter "xmit_hash_policy" to allow the selection
- *	    of different hashing policies for mode 2.  The original mode 2
- *	    policy is the default, now found in xmit_hash_policy_layer2().
- *	  * Added xmit_hash_policy_layer34()
- *	- Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4.
- *	  Set version to 2.6.3.
- * 2005/09/26 - Jay Vosburgh <fubar@us.ibm.com>
- *	- Removed backwards compatibility for old ifenslaves.  Version 2.6.4.
  */
 
 //#define BONDING_DEBUG 1
@@ -557,6 +97,7 @@
 static char *xmit_hash_policy = NULL;
 static int arp_interval = BOND_LINK_ARP_INTERV;
 static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
+struct bond_params bonding_defaults;
 
 module_param(max_bonds, int, 0);
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -565,17 +106,24 @@
 module_param(updelay, int, 0);
 MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
 module_param(downdelay, int, 0);
-MODULE_PARM_DESC(downdelay, "Delay before considering link down, in milliseconds");
+MODULE_PARM_DESC(downdelay, "Delay before considering link down, "
+			    "in milliseconds");
 module_param(use_carrier, int, 0);
-MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)");
+MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; "
+			      "0 for off, 1 for on (default)");
 module_param(mode, charp, 0);
-MODULE_PARM_DESC(mode, "Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor");
+MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
+		       "1 for active-backup, 2 for balance-xor, "
+		       "3 for broadcast, 4 for 802.3ad, 5 for balance-tlb, "
+		       "6 for balance-alb");
 module_param(primary, charp, 0);
 MODULE_PARM_DESC(primary, "Primary network device to use");
 module_param(lacp_rate, charp, 0);
-MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
+MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
+			    "(slow/fast)");
 module_param(xmit_hash_policy, charp, 0);
-MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method : 0 for layer 2 (default), 1 for layer 3+4");
+MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)"
+				   ", 1 for layer 3+4");
 module_param(arp_interval, int, 0);
 MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
 module_param_array(arp_ip_target, charp, NULL, 0);
@@ -586,30 +134,27 @@
 static const char *version =
 	DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";
 
-static LIST_HEAD(bond_dev_list);
+LIST_HEAD(bond_dev_list);
 
 #ifdef CONFIG_PROC_FS
 static struct proc_dir_entry *bond_proc_dir = NULL;
 #endif
 
+extern struct rw_semaphore bonding_rwsem;
 static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
 static int arp_ip_count	= 0;
 static int bond_mode	= BOND_MODE_ROUNDROBIN;
 static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
 static int lacp_fast	= 0;
 
-struct bond_parm_tbl {
-	char *modename;
-	int mode;
-};
 
-static struct bond_parm_tbl bond_lacp_tbl[] = {
+struct bond_parm_tbl bond_lacp_tbl[] = {
 {	"slow",		AD_LACP_SLOW},
 {	"fast",		AD_LACP_FAST},
 {	NULL,		-1},
 };
 
-static struct bond_parm_tbl bond_mode_tbl[] = {
+struct bond_parm_tbl bond_mode_tbl[] = {
 {	"balance-rr",		BOND_MODE_ROUNDROBIN},
 {	"active-backup",	BOND_MODE_ACTIVEBACKUP},
 {	"balance-xor",		BOND_MODE_XOR},
@@ -620,7 +165,7 @@
 {	NULL,			-1},
 };
 
-static struct bond_parm_tbl xmit_hashtype_tbl[] = {
+struct bond_parm_tbl xmit_hashtype_tbl[] = {
 {	"layer2",		BOND_XMIT_POLICY_LAYER2},
 {	"layer3+4",		BOND_XMIT_POLICY_LAYER34},
 {	NULL,			-1},
@@ -628,12 +173,11 @@
 
 /*-------------------------- Forward declarations ---------------------------*/
 
-static inline void bond_set_mode_ops(struct bonding *bond, int mode);
 static void bond_send_gratuitous_arp(struct bonding *bond);
 
 /*---------------------------- General routines -----------------------------*/
 
-static const char *bond_mode_name(int mode)
+const char *bond_mode_name(int mode)
 {
 	switch (mode) {
 	case BOND_MODE_ROUNDROBIN :
@@ -910,7 +454,7 @@
 	res = bond_add_vlan(bond, vid);
 	if (res) {
 		printk(KERN_ERR DRV_NAME
-		       ": %s: Failed to add vlan id %d\n",
+		       ": %s: Error: Failed to add vlan id %d\n",
 		       bond_dev->name, vid);
 	}
 }
@@ -944,7 +488,7 @@
 	res = bond_del_vlan(bond, vid);
 	if (res) {
 		printk(KERN_ERR DRV_NAME
-		       ": %s: Failed to remove vlan id %d\n",
+		       ": %s: Error: Failed to remove vlan id %d\n",
 		       bond_dev->name, vid);
 	}
 }
@@ -1449,7 +993,7 @@
  *
  * Warning: Caller must hold curr_slave_lock for writing.
  */
-static void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
+void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 {
 	struct slave *old_active = bond->curr_active_slave;
 
@@ -1523,7 +1067,7 @@
  *
  * Warning: Caller must hold curr_slave_lock for writing.
  */
-static void bond_select_active_slave(struct bonding *bond)
+void bond_select_active_slave(struct bonding *bond)
 {
 	struct slave *best_slave;
 
@@ -1591,7 +1135,7 @@
 
 /*---------------------------------- IOCTL ----------------------------------*/
 
-static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
 {
 	dprintk("bond_dev=%p\n", bond_dev);
 	dprintk("slave_dev=%p\n", slave_dev);
@@ -1631,7 +1175,7 @@
 }
 
 /* enslave device <slave> to bond device <master> */
-static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *new_slave = NULL;
@@ -1644,8 +1188,8 @@
 	if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
 		slave_dev->do_ioctl == NULL) {
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning : no link monitoring support for %s\n",
-		       slave_dev->name);
+		       ": %s: Warning: no link monitoring support for %s\n",
+		       bond_dev->name, slave_dev->name);
 	}
 
 	/* bond must be initialized by bond_open() before enslaving */
@@ -1666,17 +1210,17 @@
 		dprintk("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
 		if (!list_empty(&bond->vlan_list)) {
 			printk(KERN_ERR DRV_NAME
-			       ": Error: cannot enslave VLAN "
+			       ": %s: Error: cannot enslave VLAN "
 			       "challenged slave %s on VLAN enabled "
-			       "bond %s\n", slave_dev->name,
+			       "bond %s\n", bond_dev->name, slave_dev->name,
 			       bond_dev->name);
 			return -EPERM;
 		} else {
 			printk(KERN_WARNING DRV_NAME
-			       ": Warning: enslaved VLAN challenged "
+			       ": %s: Warning: enslaved VLAN challenged "
 			       "slave %s. Adding VLANs will be blocked as "
 			       "long as %s is part of bond %s\n",
-			       slave_dev->name, slave_dev->name,
+			       bond_dev->name, slave_dev->name, slave_dev->name,
 			       bond_dev->name);
 			bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 		}
@@ -1706,12 +1250,11 @@
 
 	if (slave_dev->set_mac_address == NULL) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: The slave device you specified does "
-		       "not support setting the MAC address.\n");
-		printk(KERN_ERR
-		       "Your kernel likely does not support slave devices.\n");
-
-		res = -EOPNOTSUPP;
+			": %s: Error: The slave device you specified does "
+			"not support setting the MAC address. "
+			"Your kernel likely does not support slave "
+			"devices.\n", bond_dev->name);
+  		res = -EOPNOTSUPP;
 		goto err_undo_flags;
 	}
 
@@ -1827,21 +1370,21 @@
 			 * the messages for netif_carrier.
 			 */
 			printk(KERN_WARNING DRV_NAME
-			       ": Warning: MII and ETHTOOL support not "
+			       ": %s: Warning: MII and ETHTOOL support not "
 			       "available for interface %s, and "
 			       "arp_interval/arp_ip_target module parameters "
 			       "not specified, thus bonding will not detect "
 			       "link failures! see bonding.txt for details.\n",
-			       slave_dev->name);
+			       bond_dev->name, slave_dev->name);
 		} else if (link_reporting == -1) {
 			/* unable get link status using mii/ethtool */
 			printk(KERN_WARNING DRV_NAME
-			       ": Warning: can't get link status from "
+			       ": %s: Warning: can't get link status from "
 			       "interface %s; the network driver associated "
 			       "with this interface does not support MII or "
 			       "ETHTOOL link status reporting, thus miimon "
 			       "has no effect on this interface.\n",
-			       slave_dev->name);
+			       bond_dev->name, slave_dev->name);
 		}
 	}
 
@@ -1868,15 +1411,15 @@
 	if (bond_update_speed_duplex(new_slave) &&
 	    (new_slave->link != BOND_LINK_DOWN)) {
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning: failed to get speed and duplex from %s, "
+		       ": %s: Warning: failed to get speed and duplex from %s, "
 		       "assumed to be 100Mb/sec and Full.\n",
-		       new_slave->dev->name);
+		       bond_dev->name, new_slave->dev->name);
 
 		if (bond->params.mode == BOND_MODE_8023AD) {
-			printk(KERN_WARNING
-			       "Operation of 802.3ad mode requires ETHTOOL "
+			printk(KERN_WARNING DRV_NAME
+			       ": %s: Warning: Operation of 802.3ad mode requires ETHTOOL "
 			       "support in base driver for proper aggregator "
-			       "selection.\n");
+			       "selection.\n", bond_dev->name);
 		}
 	}
 
@@ -1958,6 +1501,10 @@
 
 	write_unlock_bh(&bond->lock);
 
+	res = bond_create_slave_symlinks(bond_dev, slave_dev);
+	if (res)
+		goto err_unset_master;
+
 	printk(KERN_INFO DRV_NAME
 	       ": %s: enslaving %s as a%s interface with a%s link.\n",
 	       bond_dev->name, slave_dev->name,
@@ -1999,7 +1546,7 @@
  *   for Bonded connections:
  *     The first up interface should be left on and all others downed.
  */
-static int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
+int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *slave, *oldcurrent;
@@ -2010,7 +1557,7 @@
 	if (!(slave_dev->flags & IFF_SLAVE) ||
 	    (slave_dev->master != bond_dev)) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: %s: cannot release %s.\n",
+		       ": %s: Error: cannot release %s.\n",
 		       bond_dev->name, slave_dev->name);
 		return -EINVAL;
 	}
@@ -2031,11 +1578,12 @@
 				 ETH_ALEN);
 	if (!mac_addr_differ && (bond->slave_cnt > 1)) {
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning: the permanent HWaddr of %s "
+		       ": %s: Warning: the permanent HWaddr of %s "
 		       "- %02X:%02X:%02X:%02X:%02X:%02X - is "
 		       "still in use by %s. Set the HWaddr of "
 		       "%s to a different address to avoid "
 		       "conflicts.\n",
+		       bond_dev->name,
 		       slave_dev->name,
 		       slave->perm_hwaddr[0],
 		       slave->perm_hwaddr[1],
@@ -2111,24 +1659,28 @@
 			bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 		} else {
 			printk(KERN_WARNING DRV_NAME
-			       ": Warning: clearing HW address of %s while it "
+			       ": %s: Warning: clearing HW address of %s while it "
 			       "still has VLANs.\n",
-			       bond_dev->name);
+			       bond_dev->name, bond_dev->name);
 			printk(KERN_WARNING DRV_NAME
-			       ": When re-adding slaves, make sure the bond's "
-			       "HW address matches its VLANs'.\n");
+			       ": %s: When re-adding slaves, make sure the bond's "
+			       "HW address matches its VLANs'.\n",
+			       bond_dev->name);
 		}
 	} else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
 		   !bond_has_challenged_slaves(bond)) {
 		printk(KERN_INFO DRV_NAME
-		       ": last VLAN challenged slave %s "
+		       ": %s: last VLAN challenged slave %s "
 		       "left bond %s. VLAN blocking is removed\n",
-		       slave_dev->name, bond_dev->name);
+		       bond_dev->name, slave_dev->name, bond_dev->name);
 		bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
 	}
 
 	write_unlock_bh(&bond->lock);
 
+	/* must do this from outside any spinlocks */
+	bond_destroy_slave_symlinks(bond_dev, slave_dev);
+
 	bond_del_vlans_from_slave(bond, slave_dev);
 
 	/* If the mode USES_PRIMARY, then we should only remove its
@@ -2220,6 +1772,7 @@
 		 */
 		write_unlock_bh(&bond->lock);
 
+		bond_destroy_slave_symlinks(bond_dev, slave_dev);
 		bond_del_vlans_from_slave(bond, slave_dev);
 
 		/* If the mode USES_PRIMARY, then we should only remove its
@@ -2274,12 +1827,13 @@
 		bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 	} else {
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning: clearing HW address of %s while it "
+		       ": %s: Warning: clearing HW address of %s while it "
 		       "still has VLANs.\n",
-		       bond_dev->name);
+		       bond_dev->name, bond_dev->name);
 		printk(KERN_WARNING DRV_NAME
-		       ": When re-adding slaves, make sure the bond's "
-		       "HW address matches its VLANs'.\n");
+		       ": %s: When re-adding slaves, make sure the bond's "
+		       "HW address matches its VLANs'.\n",
+		       bond_dev->name);
 	}
 
 	printk(KERN_INFO DRV_NAME
@@ -2397,7 +1951,7 @@
 /*-------------------------------- Monitoring -------------------------------*/
 
 /* this function is called regularly to monitor each slave's link. */
-static void bond_mii_monitor(struct net_device *bond_dev)
+void bond_mii_monitor(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *slave, *oldcurrent;
@@ -2596,8 +2150,11 @@
 			break;
 		default:
 			/* Should not happen */
-			printk(KERN_ERR "bonding: Error: %s  Illegal value (link=%d)\n",
-			       slave->dev->name, slave->link);
+			printk(KERN_ERR DRV_NAME
+			       ": %s: Error: %s Illegal value (link=%d)\n",
+			       bond_dev->name,
+			       slave->dev->name,
+			       slave->link);
 			goto out;
 		} /* end of switch (slave->link) */
 
@@ -2721,7 +2278,9 @@
 	struct flowi fl;
 	struct rtable *rt;
 
-	for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
+	for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+		if (!targets[i])
+			continue;
 		dprintk("basa: target %x\n", targets[i]);
 		if (list_empty(&bond->vlan_list)) {
 			dprintk("basa: empty vlan: arp_send\n");
@@ -2825,7 +2384,7 @@
  * arp is transmitted to generate traffic. see activebackup_arp_monitor for
  * arp monitoring in active backup mode.
  */
-static void bond_loadbalance_arp_mon(struct net_device *bond_dev)
+void bond_loadbalance_arp_mon(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *slave, *oldcurrent;
@@ -2963,7 +2522,7 @@
  * may have received.
  * see loadbalance_arp_monitor for arp monitoring in load balancing mode
  */
-static void bond_activebackup_arp_mon(struct net_device *bond_dev)
+void bond_activebackup_arp_mon(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *slave;
@@ -3249,6 +2808,8 @@
 {
 	struct bonding *bond = seq->private;
 	struct slave *curr;
+	int i;
+	u32 target;
 
 	read_lock(&bond->curr_slave_lock);
 	curr = bond->curr_active_slave;
@@ -3257,10 +2818,17 @@
 	seq_printf(seq, "Bonding Mode: %s\n",
 		   bond_mode_name(bond->params.mode));
 
+	if (bond->params.mode == BOND_MODE_XOR ||
+		bond->params.mode == BOND_MODE_8023AD) {
+		seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
+			xmit_hashtype_tbl[bond->params.xmit_policy].modename,
+			bond->params.xmit_policy);
+	}
+
 	if (USES_PRIMARY(bond->params.mode)) {
 		seq_printf(seq, "Primary Slave: %s\n",
-			   (bond->params.primary[0]) ?
-			   	bond->params.primary : "None");
+			   (bond->primary_slave) ?
+			   bond->primary_slave->dev->name : "None");
 
 		seq_printf(seq, "Currently Active Slave: %s\n",
 			   (curr) ? curr->dev->name : "None");
@@ -3273,6 +2841,27 @@
 	seq_printf(seq, "Down Delay (ms): %d\n",
 		   bond->params.downdelay * bond->params.miimon);
 
+
+	/* ARP information */
+	if(bond->params.arp_interval > 0) {
+		int printed=0;
+		seq_printf(seq, "ARP Polling Interval (ms): %d\n",
+				bond->params.arp_interval);
+
+		seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
+
+		for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) {
+			if (!bond->params.arp_targets[i])
+				continue;
+			if (printed)
+				seq_printf(seq, ",");
+			target = ntohl(bond->params.arp_targets[i]);
+			seq_printf(seq, " %d.%d.%d.%d", HIPQUAD(target));
+			printed = 1;
+		}
+		seq_printf(seq, "\n");
+	}
+
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		struct ad_info ad_info;
 
@@ -3478,7 +3067,10 @@
 	bond_remove_proc_entry(bond);
 	bond_create_proc_entry(bond);
 #endif
-
+	down_write(&(bonding_rwsem));
+        bond_destroy_sysfs_entry(bond);
+        bond_create_sysfs_entry(bond);
+	up_write(&(bonding_rwsem));
 	return NOTIFY_DONE;
 }
 
@@ -3955,6 +3547,7 @@
 		return -EPERM;
 	}
 
+	down_write(&(bonding_rwsem));
 	slave_dev = dev_get_by_name(ifr->ifr_slave);
 
 	dprintk("slave_dev=%p: \n", slave_dev);
@@ -3987,6 +3580,7 @@
 		dev_put(slave_dev);
 	}
 
+	up_write(&(bonding_rwsem));
 	return res;
 }
 
@@ -4071,6 +3665,7 @@
 	bond_for_each_slave(bond, slave, i) {
 		dprintk("s %p s->p %p c_m %p\n", slave,
 			slave->prev, slave->dev->change_mtu);
+
 		res = dev_set_mtu(slave->dev, new_mtu);
 
 		if (res) {
@@ -4397,8 +3992,9 @@
 				struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 				if (!skb2) {
 					printk(KERN_ERR DRV_NAME
-					       ": Error: bond_xmit_broadcast(): "
-					       "skb_clone() failed\n");
+					       ": %s: Error: bond_xmit_broadcast(): "
+					       "skb_clone() failed\n",
+					       bond_dev->name);
 					continue;
 				}
 
@@ -4431,7 +4027,7 @@
 /*
  * set bond mode specific net device operations
  */
-static inline void bond_set_mode_ops(struct bonding *bond, int mode)
+void bond_set_mode_ops(struct bonding *bond, int mode)
 {
 	struct net_device *bond_dev = bond->dev;
 
@@ -4467,7 +4063,8 @@
 	default:
 		/* Should never happen, mode already checked */
 		printk(KERN_ERR DRV_NAME
-		       ": Error: Unknown bonding mode %d\n",
+		       ": %s: Error: Unknown bonding mode %d\n",
+		       bond_dev->name,
 		       mode);
 		break;
 	}
@@ -4491,7 +4088,7 @@
  * Does not allocate but creates a /proc entry.
  * Allowed to fail.
  */
-static int __init bond_init(struct net_device *bond_dev, struct bond_params *params)
+static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 {
 	struct bonding *bond = bond_dev->priv;
 
@@ -4565,7 +4162,7 @@
 /* De-initialize device specific data.
  * Caller must hold rtnl_lock.
  */
-static inline void bond_deinit(struct net_device *bond_dev)
+void bond_deinit(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 
@@ -4601,7 +4198,7 @@
  * Convert string input module parms.  Accept either the
  * number of the mode or its string name.
  */
-static inline int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
 {
 	int i;
 
@@ -4670,7 +4267,7 @@
 	if (max_bonds < 1 || max_bonds > INT_MAX) {
 		printk(KERN_WARNING DRV_NAME
 		       ": Warning: max_bonds (%d) not in range %d-%d, so it "
-		       "was reset to BOND_DEFAULT_MAX_BONDS (%d)",
+		       "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
 		       max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
 		max_bonds = BOND_DEFAULT_MAX_BONDS;
 	}
@@ -4881,81 +4478,96 @@
 	return 0;
 }
 
+/* Create a new bond based on the specified name and bonding parameters.
+ * Caller must NOT hold rtnl_lock; we need to release it here before we
+ * set up our sysfs entries.
+ */
+int bond_create(char *name, struct bond_params *params, struct bonding **newbond)
+{
+	struct net_device *bond_dev;
+	int res;
+
+	rtnl_lock();
+	bond_dev = alloc_netdev(sizeof(struct bonding), name, ether_setup);
+	if (!bond_dev) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: eek! can't alloc netdev!\n",
+		       name);
+		res = -ENOMEM;
+		goto out_rtnl;
+	}
+
+	/* bond_init() must be called after dev_alloc_name() (for the
+	 * /proc files), but before register_netdevice(), because we
+	 * need to set function pointers.
+	 */
+
+	res = bond_init(bond_dev, params);
+	if (res < 0) {
+		goto out_netdev;
+	}
+
+	SET_MODULE_OWNER(bond_dev);
+
+	res = register_netdevice(bond_dev);
+	if (res < 0) {
+		goto out_bond;
+	}
+	if (newbond)
+		*newbond = bond_dev->priv;
+
+	rtnl_unlock(); /* allows sysfs registration of net device */
+	res = bond_create_sysfs_entry(bond_dev->priv);
+	goto done;
+out_bond:
+	bond_deinit(bond_dev);
+out_netdev:
+	free_netdev(bond_dev);
+out_rtnl:
+	rtnl_unlock();
+done:
+	return res;
+}
+
 static int __init bonding_init(void)
 {
-	struct bond_params params;
 	int i;
 	int res;
+	char new_bond_name[8];  /* Enough room for 999 bonds at init. */
 
 	printk(KERN_INFO "%s", version);
 
-	res = bond_check_params(&params);
+	res = bond_check_params(&bonding_defaults);
 	if (res) {
-		return res;
+		goto out;
 	}
 
-	rtnl_lock();
-
 #ifdef CONFIG_PROC_FS
 	bond_create_proc_dir();
 #endif
-
 	for (i = 0; i < max_bonds; i++) {
-		struct net_device *bond_dev;
-
-		bond_dev = alloc_netdev(sizeof(struct bonding), "", ether_setup);
-		if (!bond_dev) {
-			res = -ENOMEM;
-			goto out_err;
-		}
-
-		res = dev_alloc_name(bond_dev, "bond%d");
-		if (res < 0) {
-			free_netdev(bond_dev);
-			goto out_err;
-		}
-
-		/* bond_init() must be called after dev_alloc_name() (for the
-		 * /proc files), but before register_netdevice(), because we
-		 * need to set function pointers.
-		 */
-		res = bond_init(bond_dev, &params);
-		if (res < 0) {
-			free_netdev(bond_dev);
-			goto out_err;
-		}
-
-		SET_MODULE_OWNER(bond_dev);
-
-		res = register_netdevice(bond_dev);
-		if (res < 0) {
-			bond_deinit(bond_dev);
-			free_netdev(bond_dev);
-			goto out_err;
-		}
+		sprintf(new_bond_name, "bond%d",i);
+		res = bond_create(new_bond_name,&bonding_defaults, NULL);
+		if (res)
+			goto err;
 	}
 
-	rtnl_unlock();
+	res = bond_create_sysfs();
+	if (res)
+		goto err;
+
 	register_netdevice_notifier(&bond_netdev_notifier);
 	register_inetaddr_notifier(&bond_inetaddr_notifier);
 
-	return 0;
-
-out_err:
-	/*
-	 * rtnl_unlock() will run netdev_run_todo(), putting the
-	 * thus-far-registered bonding devices into a state which
-	 * unregigister_netdevice() will accept
-	 */
-	rtnl_unlock();
+	goto out;
+err:
 	rtnl_lock();
-
-	/* free and unregister all bonds that were successfully added */
 	bond_free_all();
-
+	bond_destroy_sysfs();
 	rtnl_unlock();
-
+out:
 	return res;
+
 }
 
 static void __exit bonding_exit(void)
@@ -4965,6 +4577,7 @@
 
 	rtnl_lock();
 	bond_free_all();
+	bond_destroy_sysfs();
 	rtnl_unlock();
 }
 
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
new file mode 100644
index 0000000..32d13da
--- /dev/null
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -0,0 +1,1358 @@
+
+/*
+ * Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) 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.
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/in.h>
+#include <linux/sysfs.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/inet.h>
+#include <linux/rtnetlink.h>
+
+/* #define BONDING_DEBUG 1 */
+#include "bonding.h"
+#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
+#define to_bond(cd)	((struct bonding *)(to_net_dev(cd)->priv))
+
+/*---------------------------- Declarations -------------------------------*/
+
+
+extern struct list_head bond_dev_list;
+extern struct bond_params bonding_defaults;
+extern struct bond_parm_tbl bond_mode_tbl[];
+extern struct bond_parm_tbl bond_lacp_tbl[];
+extern struct bond_parm_tbl xmit_hashtype_tbl[];
+
+static int expected_refcount = -1;
+static struct class *netdev_class;
+/*--------------------------- Data Structures -----------------------------*/
+
+/* Bonding sysfs lock.  Why can't we just use the subsytem lock?
+ * Because kobject_register tries to acquire the subsystem lock.  If
+ * we already hold the lock (which we would if the user was creating
+ * a new bond through the sysfs interface), we deadlock.
+ * This lock is only needed when deleting a bond - we need to make sure
+ * that we don't collide with an ongoing ioctl.
+ */
+
+struct rw_semaphore bonding_rwsem;
+
+
+
+
+/*------------------------------ Functions --------------------------------*/
+
+/*
+ * "show" function for the bond_masters attribute.
+ * The class parameter is ignored.
+ */
+static ssize_t bonding_show_bonds(struct class *cls, char *buffer)
+{
+	int res = 0;
+	struct bonding *bond;
+
+	down_read(&(bonding_rwsem));
+
+	list_for_each_entry(bond, &bond_dev_list, bond_list) {
+		if (res > (PAGE_SIZE - IFNAMSIZ)) {
+			/* not enough space for another interface name */
+			if ((PAGE_SIZE - res) > 10)
+				res = PAGE_SIZE - 10;
+			res += sprintf(buffer + res, "++more++");
+			break;
+		}
+		res += sprintf(buffer + res, "%s ",
+			       bond->dev->name);
+	}
+	res += sprintf(buffer + res, "\n");
+	res++;
+	up_read(&(bonding_rwsem));
+	return res;
+}
+
+/*
+ * "store" function for the bond_masters attribute.  This is what
+ * creates and deletes entire bonds.
+ *
+ * The class parameter is ignored.
+ *
+ */
+
+static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t count)
+{
+	char command[IFNAMSIZ + 1] = {0, };
+	char *ifname;
+	int res = count;
+	struct bonding *bond;
+	struct bonding *nxt;
+
+	down_write(&(bonding_rwsem));
+	sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
+	ifname = command + 1;
+	if ((strlen(command) <= 1) ||
+	    !dev_valid_name(ifname))
+		goto err_no_cmd;
+
+	if (command[0] == '+') {
+
+		/* Check to see if the bond already exists. */
+		list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+			if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
+				printk(KERN_ERR DRV_NAME
+					": cannot add bond %s; it already exists\n",
+					ifname);
+				res = -EPERM;
+				goto out;
+			}
+
+		printk(KERN_INFO DRV_NAME
+			": %s is being created...\n", ifname);
+		if (bond_create(ifname, &bonding_defaults, &bond)) {
+			printk(KERN_INFO DRV_NAME
+			": %s interface already exists. Bond creation failed.\n",
+			ifname);
+			res = -EPERM;
+		}
+		goto out;
+	}
+
+	if (command[0] == '-') {
+		list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list)
+			if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
+				rtnl_lock();
+				/* check the ref count on the bond's kobject.
+				 * If it's > expected, then there's a file open,
+				 * and we have to fail.
+				 */
+				if (atomic_read(&bond->dev->class_dev.kobj.kref.refcount)
+							> expected_refcount){
+					rtnl_unlock();
+					printk(KERN_INFO DRV_NAME
+						": Unable remove bond %s due to open references.\n",
+						ifname);
+					res = -EPERM;
+					goto out;
+				}
+				printk(KERN_INFO DRV_NAME
+					": %s is being deleted...\n",
+					bond->dev->name);
+				unregister_netdevice(bond->dev);
+				bond_deinit(bond->dev);
+		        	bond_destroy_sysfs_entry(bond);
+				rtnl_unlock();
+				goto out;
+			}
+
+		printk(KERN_ERR DRV_NAME
+			": unable to delete non-existent bond %s\n", ifname);
+		res = -ENODEV;
+		goto out;
+	}
+
+err_no_cmd:
+	printk(KERN_ERR DRV_NAME
+		": no command found in bonding_masters. Use +ifname or -ifname.\n");
+	res = -EPERM;
+
+	/* Always return either count or an error.  If you return 0, you'll
+	 * get called forever, which is bad.
+	 */
+out:
+	up_write(&(bonding_rwsem));
+	return res;
+}
+/* class attribute for bond_masters file.  This ends up in /sys/class/net */
+static CLASS_ATTR(bonding_masters,  S_IWUSR | S_IRUGO,
+		  bonding_show_bonds, bonding_store_bonds);
+
+int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave)
+{
+	char linkname[IFNAMSIZ+7];
+	int ret = 0;
+
+	/* first, create a link from the slave back to the master */
+	ret = sysfs_create_link(&(slave->class_dev.kobj), &(master->class_dev.kobj),
+				"master");
+	if (ret)
+		return ret;
+	/* next, create a link from the master to the slave */
+	sprintf(linkname,"slave_%s",slave->name);
+	ret = sysfs_create_link(&(master->class_dev.kobj), &(slave->class_dev.kobj),
+				linkname);
+	return ret;
+
+}
+
+void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave)
+{
+	char linkname[IFNAMSIZ+7];
+
+	sysfs_remove_link(&(slave->class_dev.kobj), "master");
+	sprintf(linkname,"slave_%s",slave->name);
+	sysfs_remove_link(&(master->class_dev.kobj), linkname);
+}
+
+
+/*
+ * Show the slaves in the current bond.
+ */
+static ssize_t bonding_show_slaves(struct class_device *cd, char *buf)
+{
+	struct slave *slave;
+	int i, res = 0;
+	struct bonding *bond = to_bond(cd);
+
+	read_lock_bh(&bond->lock);
+	bond_for_each_slave(bond, slave, i) {
+		if (res > (PAGE_SIZE - IFNAMSIZ)) {
+			/* not enough space for another interface name */
+			if ((PAGE_SIZE - res) > 10)
+				res = PAGE_SIZE - 10;
+			res += sprintf(buf + res, "++more++");
+			break;
+		}
+		res += sprintf(buf + res, "%s ", slave->dev->name);
+	}
+	read_unlock_bh(&bond->lock);
+	res += sprintf(buf + res, "\n");
+	res++;
+	return res;
+}
+
+/*
+ * Set the slaves in the current bond.  The bond interface must be
+ * up for this to succeed.
+ * This function is largely the same flow as bonding_update_bonds().
+ */
+static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer, size_t count)
+{
+	char command[IFNAMSIZ + 1] = { 0, };
+	char *ifname;
+	int i, res, found, ret = count;
+	struct slave *slave;
+	struct net_device *dev = 0;
+	struct bonding *bond = to_bond(cd);
+
+	/* Quick sanity check -- is the bond interface up? */
+	if (!(bond->dev->flags & IFF_UP)) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to update slaves because interface is down.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	/* Note:  We can't hold bond->lock here, as bond_create grabs it. */
+
+	sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
+	ifname = command + 1;
+	if ((strlen(command) <= 1) ||
+	    !dev_valid_name(ifname))
+		goto err_no_cmd;
+
+	if (command[0] == '+') {
+
+		/* Got a slave name in ifname.  Is it already in the list? */
+		found = 0;
+		read_lock_bh(&bond->lock);
+		bond_for_each_slave(bond, slave, i)
+			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
+				printk(KERN_ERR DRV_NAME
+				       ": %s: Interface %s is already enslaved!\n",
+				       bond->dev->name, ifname);
+				ret = -EPERM;
+				read_unlock_bh(&bond->lock);
+				goto out;
+			}
+
+		read_unlock_bh(&bond->lock);
+		printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
+		       bond->dev->name, ifname);
+		dev = dev_get_by_name(ifname);
+		if (!dev) {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Interface %s does not exist!\n",
+			       bond->dev->name, ifname);
+			ret = -EPERM;
+			goto out;
+		}
+		else
+			dev_put(dev);
+
+		if (dev->flags & IFF_UP) {
+			printk(KERN_ERR DRV_NAME
+			       ": %s: Error: Unable to enslave %s "
+			       "because it is already up.\n",
+			       bond->dev->name, dev->name);
+			ret = -EPERM;
+			goto out;
+		}
+		/* If this is the first slave, then we need to set
+		   the master's hardware address to be the same as the
+		   slave's. */
+		if (!(*((u32 *) & (bond->dev->dev_addr[0])))) {
+			memcpy(bond->dev->dev_addr, dev->dev_addr,
+			       dev->addr_len);
+		}
+
+		/* Set the slave's MTU to match the bond */
+		if (dev->mtu != bond->dev->mtu) {
+			if (dev->change_mtu) {
+				res = dev->change_mtu(dev,
+						      bond->dev->mtu);
+				if (res) {
+					ret = res;
+					goto out;
+				}
+			} else {
+				dev->mtu = bond->dev->mtu;
+			}
+		}
+		rtnl_lock();
+		res = bond_enslave(bond->dev, dev);
+		rtnl_unlock();
+		if (res) {
+			ret = res;
+		}
+		goto out;
+	}
+
+	if (command[0] == '-') {
+		dev = NULL;
+		bond_for_each_slave(bond, slave, i)
+			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
+				dev = slave->dev;
+				break;
+			}
+		if (dev) {
+			printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
+				bond->dev->name, dev->name);
+			rtnl_lock();
+			res = bond_release(bond->dev, dev);
+			rtnl_unlock();
+			if (res) {
+				ret = res;
+				goto out;
+			}
+			/* set the slave MTU to the default */
+			if (dev->change_mtu) {
+				dev->change_mtu(dev, 1500);
+			} else {
+				dev->mtu = 1500;
+			}
+		}
+		else {
+			printk(KERN_ERR DRV_NAME ": unable to remove non-existent slave %s for bond %s.\n",
+				ifname, bond->dev->name);
+			ret = -ENODEV;
+		}
+		goto out;
+	}
+
+err_no_cmd:
+	printk(KERN_ERR DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
+	ret = -EPERM;
+
+out:
+	return ret;
+}
+
+static CLASS_DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
+
+/*
+ * Show and set the bonding mode.  The bond interface must be down to
+ * change the mode.
+ */
+static ssize_t bonding_show_mode(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%s %d\n",
+			bond_mode_tbl[bond->params.mode].modename,
+			bond->params.mode) + 1;
+}
+
+static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->dev->flags & IFF_UP) {
+		printk(KERN_ERR DRV_NAME
+		       ": unable to update mode of %s because interface is up.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	new_value = bond_parse_parm((char *)buf, bond_mode_tbl);
+	if (new_value < 0)  {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Ignoring invalid mode value %.*s.\n",
+		       bond->dev->name,
+		       (int)strlen(buf) - 1, buf);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		bond->params.mode = new_value;
+		bond_set_mode_ops(bond, bond->params.mode);
+		printk(KERN_INFO DRV_NAME ": %s: setting mode to %s (%d).\n",
+			bond->dev->name, bond_mode_tbl[new_value].modename, new_value);
+	}
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
+
+/*
+ * Show and set the bonding transmit hash method.  The bond interface must be down to
+ * change the xmit hash policy.
+ */
+static ssize_t bonding_show_xmit_hash(struct class_device *cd, char *buf)
+{
+	int count;
+	struct bonding *bond = to_bond(cd);
+
+	if ((bond->params.mode != BOND_MODE_XOR) &&
+	    (bond->params.mode != BOND_MODE_8023AD)) {
+		// Not Applicable
+		count = sprintf(buf, "NA\n") + 1;
+	} else {
+		count = sprintf(buf, "%s %d\n",
+			xmit_hashtype_tbl[bond->params.xmit_policy].modename,
+			bond->params.xmit_policy) + 1;
+	}
+
+	return count;
+}
+
+static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->dev->flags & IFF_UP) {
+		printk(KERN_ERR DRV_NAME
+		       "%s: Interface is up. Unable to update xmit policy.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	if ((bond->params.mode != BOND_MODE_XOR) &&
+	    (bond->params.mode != BOND_MODE_8023AD)) {
+		printk(KERN_ERR DRV_NAME
+		       "%s: Transmit hash policy is irrelevant in this mode.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);
+	if (new_value < 0)  {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
+		       bond->dev->name,
+		       (int)strlen(buf) - 1, buf);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		bond->params.xmit_policy = new_value;
+		bond_set_mode_ops(bond, bond->params.mode);
+		printk(KERN_INFO DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
+			bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value);
+	}
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
+
+/*
+ * Show and set the arp timer interval.  There are two tricky bits
+ * here.  First, if ARP monitoring is activated, then we must disable
+ * MII monitoring.  Second, if the ARP timer isn't running, we must
+ * start it.
+ */
+static ssize_t bonding_show_arp_interval(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.arp_interval) + 1;
+}
+
+static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no arp_interval value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if (new_value < 0) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
+		       bond->dev->name, new_value, INT_MAX);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	printk(KERN_INFO DRV_NAME
+	       ": %s: Setting ARP monitoring interval to %d.\n",
+	       bond->dev->name, new_value);
+	bond->params.arp_interval = new_value;
+	if (bond->params.miimon) {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: ARP monitoring cannot be used with MII monitoring. "
+		       "%s Disabling MII monitoring.\n",
+		       bond->dev->name, bond->dev->name);
+		bond->params.miimon = 0;
+		/* Kill MII timer, else it brings bond's link down */
+		if (bond->arp_timer.function) {
+			printk(KERN_INFO DRV_NAME
+			": %s: Kill MII timer, else it brings bond's link down...\n",
+		       bond->dev->name);
+			del_timer_sync(&bond->mii_timer);
+		}
+	}
+	if (!bond->params.arp_targets[0]) {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: ARP monitoring has been set up, "
+		       "but no ARP targets have been specified.\n",
+		       bond->dev->name);
+	}
+	if (bond->dev->flags & IFF_UP) {
+		/* If the interface is up, we may need to fire off
+		 * the ARP timer.  If the interface is down, the
+		 * timer will get fired off when the open function
+		 * is called.
+		 */
+		if (bond->arp_timer.function) {
+			/* The timer's already set up, so fire it off */
+			mod_timer(&bond->arp_timer, jiffies + 1);
+		} else {
+			/* Set up the timer. */
+			init_timer(&bond->arp_timer);
+			bond->arp_timer.expires = jiffies + 1;
+			bond->arp_timer.data =
+				(unsigned long) bond->dev;
+			if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
+				bond->arp_timer.function =
+					(void *)
+					&bond_activebackup_arp_mon;
+			} else {
+				bond->arp_timer.function =
+					(void *)
+					&bond_loadbalance_arp_mon;
+			}
+			add_timer(&bond->arp_timer);
+		}
+	}
+
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
+
+/*
+ * Show and set the arp targets.
+ */
+static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf)
+{
+	int i, res = 0;
+	struct bonding *bond = to_bond(cd);
+
+	for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
+		if (bond->params.arp_targets[i])
+			res += sprintf(buf + res, "%u.%u.%u.%u ",
+			       NIPQUAD(bond->params.arp_targets[i]));
+	}
+	if (res)
+		res--;  /* eat the leftover space */
+	res += sprintf(buf + res, "\n");
+	res++;
+	return res;
+}
+
+static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *buf, size_t count)
+{
+	u32 newtarget;
+	int i = 0, done = 0, ret = count;
+	struct bonding *bond = to_bond(cd);
+	u32 *targets;
+
+	targets = bond->params.arp_targets;
+	newtarget = in_aton(buf + 1);
+	/* look for adds */
+	if (buf[0] == '+') {
+		if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {
+			printk(KERN_ERR DRV_NAME
+			       ": %s: invalid ARP target %u.%u.%u.%u specified for addition\n",
+ 			       bond->dev->name, NIPQUAD(newtarget));
+			ret = -EINVAL;
+			goto out;
+		}
+		/* look for an empty slot to put the target in, and check for dupes */
+		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+			if (targets[i] == newtarget) { /* duplicate */
+				printk(KERN_ERR DRV_NAME
+				       ": %s: ARP target %u.%u.%u.%u is already present\n",
+				       bond->dev->name, NIPQUAD(newtarget));
+				if (done)
+					targets[i] = 0;
+				ret = -EINVAL;
+				goto out;
+			}
+			if (targets[i] == 0 && !done) {
+				printk(KERN_INFO DRV_NAME
+				       ": %s: adding ARP target %d.%d.%d.%d.\n",
+				       bond->dev->name, NIPQUAD(newtarget));
+				done = 1;
+				targets[i] = newtarget;
+			}
+		}
+		if (!done) {
+			printk(KERN_ERR DRV_NAME
+			       ": %s: ARP target table is full!\n",
+			       bond->dev->name);
+			ret = -EINVAL;
+			goto out;
+		}
+
+	}
+	else if (buf[0] == '-')	{
+		if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {
+			printk(KERN_ERR DRV_NAME
+			       ": %s: invalid ARP target %d.%d.%d.%d specified for removal\n",
+			       bond->dev->name, NIPQUAD(newtarget));
+			ret = -EINVAL;
+			goto out;
+		}
+
+		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
+			if (targets[i] == newtarget) {
+				printk(KERN_INFO DRV_NAME
+				       ": %s: removing ARP target %d.%d.%d.%d.\n",
+				       bond->dev->name, NIPQUAD(newtarget));
+				targets[i] = 0;
+				done = 1;
+			}
+		}
+		if (!done) {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: unable to remove nonexistent ARP target %d.%d.%d.%d.\n",
+			       bond->dev->name, NIPQUAD(newtarget));
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+	else {
+		printk(KERN_ERR DRV_NAME ": no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
+			bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
+
+/*
+ * Show and set the up and down delays.  These must be multiples of the
+ * MII monitoring value, and are stored internally as the multiplier.
+ * Thus, we must translate to MS for the real world.
+ */
+static ssize_t bonding_show_downdelay(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1;
+}
+
+static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (!(bond->params.miimon)) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to set down delay as MII monitoring is disabled\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no down delay value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if (new_value < 0) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+		       bond->dev->name, new_value, 1, INT_MAX);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		if ((new_value % bond->params.miimon) != 0) {
+			printk(KERN_WARNING DRV_NAME
+			       ": %s: Warning: down delay (%d) is not a multiple "
+			       "of miimon (%d), delay rounded to %d ms\n",
+			       bond->dev->name, new_value, bond->params.miimon,
+			       (new_value / bond->params.miimon) *
+			       bond->params.miimon);
+		}
+		bond->params.downdelay = new_value / bond->params.miimon;
+		printk(KERN_INFO DRV_NAME ": %s: Setting down delay to %d.\n",
+		       bond->dev->name, bond->params.downdelay * bond->params.miimon);
+
+	}
+
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
+
+static ssize_t bonding_show_updelay(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1;
+
+}
+
+static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (!(bond->params.miimon)) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to set up delay as MII monitoring is disabled\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no up delay value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if (new_value < 0) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
+		       bond->dev->name, new_value, 1, INT_MAX);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		if ((new_value % bond->params.miimon) != 0) {
+			printk(KERN_WARNING DRV_NAME
+			       ": %s: Warning: up delay (%d) is not a multiple "
+			       "of miimon (%d), updelay rounded to %d ms\n",
+			       bond->dev->name, new_value, bond->params.miimon,
+			       (new_value / bond->params.miimon) *
+			       bond->params.miimon);
+		}
+		bond->params.updelay = new_value / bond->params.miimon;
+		printk(KERN_INFO DRV_NAME ": %s: Setting up delay to %d.\n",
+		       bond->dev->name, bond->params.updelay * bond->params.miimon);
+
+	}
+
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
+
+/*
+ * Show and set the LACP interval.  Interface must be down, and the mode
+ * must be set to 802.3ad mode.
+ */
+static ssize_t bonding_show_lacp(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%s %d\n",
+		bond_lacp_tbl[bond->params.lacp_fast].modename,
+		bond->params.lacp_fast) + 1;
+}
+
+static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->dev->flags & IFF_UP) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to update LACP rate because interface is up.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	if (bond->params.mode != BOND_MODE_8023AD) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	new_value = bond_parse_parm((char *)buf, bond_lacp_tbl);
+
+	if ((new_value == 1) || (new_value == 0)) {
+		bond->params.lacp_fast = new_value;
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Setting LACP rate to %s (%d).\n",
+		       bond->dev->name, bond_lacp_tbl[new_value].modename, new_value);
+	} else {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Ignoring invalid LACP rate value %.*s.\n",
+		     	bond->dev->name, (int)strlen(buf) - 1, buf);
+		ret = -EINVAL;
+	}
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
+
+/*
+ * Show and set the MII monitor interval.  There are two tricky bits
+ * here.  First, if MII monitoring is activated, then we must disable
+ * ARP monitoring.  Second, if the timer isn't running, we must
+ * start it.
+ */
+static ssize_t bonding_show_miimon(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.miimon) + 1;
+}
+
+static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no miimon value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if (new_value < 0) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Invalid miimon value %d not in range %d-%d; rejected.\n",
+		       bond->dev->name, new_value, 1, INT_MAX);
+		ret = -EINVAL;
+		goto out;
+	} else {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Setting MII monitoring interval to %d.\n",
+		       bond->dev->name, new_value);
+		bond->params.miimon = new_value;
+		if(bond->params.updelay)
+			printk(KERN_INFO DRV_NAME
+			      ": %s: Note: Updating updelay (to %d) "
+			      "since it is a multiple of the miimon value.\n",
+			      bond->dev->name,
+			      bond->params.updelay * bond->params.miimon);
+		if(bond->params.downdelay)
+			printk(KERN_INFO DRV_NAME
+			      ": %s: Note: Updating downdelay (to %d) "
+			      "since it is a multiple of the miimon value.\n",
+			      bond->dev->name,
+			      bond->params.downdelay * bond->params.miimon);
+		if (bond->params.arp_interval) {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: MII monitoring cannot be used with "
+			       "ARP monitoring. Disabling ARP monitoring...\n",
+			       bond->dev->name);
+			bond->params.arp_interval = 0;
+			/* Kill ARP timer, else it brings bond's link down */
+			if (bond->mii_timer.function) {
+				printk(KERN_INFO DRV_NAME
+				": %s: Kill ARP timer, else it brings bond's link down...\n",
+			       bond->dev->name);
+				del_timer_sync(&bond->arp_timer);
+			}
+		}
+
+		if (bond->dev->flags & IFF_UP) {
+			/* If the interface is up, we may need to fire off
+			 * the MII timer. If the interface is down, the
+			 * timer will get fired off when the open function
+			 * is called.
+			 */
+			if (bond->mii_timer.function) {
+				/* The timer's already set up, so fire it off */
+				mod_timer(&bond->mii_timer, jiffies + 1);
+			} else {
+				/* Set up the timer. */
+				init_timer(&bond->mii_timer);
+				bond->mii_timer.expires = jiffies + 1;
+				bond->mii_timer.data =
+					(unsigned long) bond->dev;
+				bond->mii_timer.function =
+					(void *) &bond_mii_monitor;
+				add_timer(&bond->mii_timer);
+			}
+		}
+	}
+out:
+	return ret;
+}
+static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
+
+/*
+ * Show and set the primary slave.  The store function is much
+ * simpler than bonding_store_slaves function because it only needs to
+ * handle one interface name.
+ * The bond must be a mode that supports a primary for this be
+ * set.
+ */
+static ssize_t bonding_show_primary(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->primary_slave)
+		count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1;
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+
+static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, size_t count)
+{
+	int i;
+	struct slave *slave;
+	struct bonding *bond = to_bond(cd);
+
+	write_lock_bh(&bond->lock);
+	if (!USES_PRIMARY(bond->params.mode)) {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Unable to set primary slave; %s is in mode %d\n",
+		       bond->dev->name, bond->dev->name, bond->params.mode);
+	} else {
+		bond_for_each_slave(bond, slave, i) {
+			if (strnicmp
+			    (slave->dev->name, buf,
+			     strlen(slave->dev->name)) == 0) {
+				printk(KERN_INFO DRV_NAME
+				       ": %s: Setting %s as primary slave.\n",
+				       bond->dev->name, slave->dev->name);
+				bond->primary_slave = slave;
+				bond_select_active_slave(bond);
+				goto out;
+			}
+		}
+
+		/* if we got here, then we didn't match the name of any slave */
+
+		if (strlen(buf) == 0 || buf[0] == '\n') {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Setting primary slave to None.\n",
+			       bond->dev->name);
+			bond->primary_slave = 0;
+				bond_select_active_slave(bond);
+		} else {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Unable to set %.*s as primary slave as it is not a slave.\n",
+			       bond->dev->name, (int)strlen(buf) - 1, buf);
+		}
+	}
+out:
+	write_unlock_bh(&bond->lock);
+	return count;
+}
+static CLASS_DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
+
+/*
+ * Show and set the use_carrier flag.
+ */
+static ssize_t bonding_show_carrier(struct class_device *cd, char *buf)
+{
+	struct bonding *bond = to_bond(cd);
+
+	return sprintf(buf, "%d\n", bond->params.use_carrier) + 1;
+}
+
+static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, size_t count)
+{
+	int new_value, ret = count;
+	struct bonding *bond = to_bond(cd);
+
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no use_carrier value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+	if ((new_value == 0) || (new_value == 1)) {
+		bond->params.use_carrier = new_value;
+		printk(KERN_INFO DRV_NAME ": %s: Setting use_carrier to %d.\n",
+		       bond->dev->name, new_value);
+	} else {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Ignoring invalid use_carrier value %d.\n",
+		       bond->dev->name, new_value);
+	}
+out:
+	return count;
+}
+static CLASS_DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
+
+
+/*
+ * Show and set currently active_slave.
+ */
+static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf)
+{
+	struct slave *curr;
+	struct bonding *bond = to_bond(cd);
+	int count;
+
+
+	read_lock(&bond->curr_slave_lock);
+	curr = bond->curr_active_slave;
+	read_unlock(&bond->curr_slave_lock);
+
+	if (USES_PRIMARY(bond->params.mode) && curr)
+		count = sprintf(buf, "%s\n", curr->dev->name) + 1;
+	else
+		count = sprintf(buf, "\n") + 1;
+	return count;
+}
+
+static ssize_t bonding_store_active_slave(struct class_device *cd, const char *buf, size_t count)
+{
+	int i;
+	struct slave *slave;
+        struct slave *old_active = NULL;
+        struct slave *new_active = NULL;
+	struct bonding *bond = to_bond(cd);
+
+	write_lock_bh(&bond->lock);
+	if (!USES_PRIMARY(bond->params.mode)) {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Unable to change active slave; %s is in mode %d\n",
+		       bond->dev->name, bond->dev->name, bond->params.mode);
+	} else {
+		bond_for_each_slave(bond, slave, i) {
+			if (strnicmp
+			    (slave->dev->name, buf,
+			     strlen(slave->dev->name)) == 0) {
+        			old_active = bond->curr_active_slave;
+        			new_active = slave;
+        			if (new_active && (new_active == old_active)) {
+					/* do nothing */
+					printk(KERN_INFO DRV_NAME
+				       	       ": %s: %s is already the current active slave.\n",
+				               bond->dev->name, slave->dev->name);
+					goto out;
+				}
+				else {
+        				if ((new_active) &&
+            				    (old_active) &&
+				            (new_active->link == BOND_LINK_UP) &&
+				            IS_UP(new_active->dev)) {
+						printk(KERN_INFO DRV_NAME
+				       	              ": %s: Setting %s as active slave.\n",
+				                      bond->dev->name, slave->dev->name);
+                				bond_change_active_slave(bond, new_active);
+        				}
+					else {
+						printk(KERN_INFO DRV_NAME
+				       	              ": %s: Could not set %s as active slave; "
+						      "either %s is down or the link is down.\n",
+				                      bond->dev->name, slave->dev->name,
+						      slave->dev->name);
+					}
+					goto out;
+				}
+			}
+		}
+
+		/* if we got here, then we didn't match the name of any slave */
+
+		if (strlen(buf) == 0 || buf[0] == '\n') {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Setting active slave to None.\n",
+			       bond->dev->name);
+			bond->primary_slave = 0;
+				bond_select_active_slave(bond);
+		} else {
+			printk(KERN_INFO DRV_NAME
+			       ": %s: Unable to set %.*s as active slave as it is not a slave.\n",
+			       bond->dev->name, (int)strlen(buf) - 1, buf);
+		}
+	}
+out:
+	write_unlock_bh(&bond->lock);
+	return count;
+
+}
+static CLASS_DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
+
+
+/*
+ * Show link status of the bond interface.
+ */
+static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf)
+{
+	struct slave *curr;
+	struct bonding *bond = to_bond(cd);
+
+	read_lock(&bond->curr_slave_lock);
+	curr = bond->curr_active_slave;
+	read_unlock(&bond->curr_slave_lock);
+
+	return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1;
+}
+static CLASS_DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
+
+
+/*
+ * Show current 802.3ad aggregator ID.
+ */
+static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.aggregator_id) + 1;
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
+
+
+/*
+ * Show number of active 802.3ad ports.
+ */
+static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0: ad_info.ports) + 1;
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
+
+
+/*
+ * Show current 802.3ad actor key.
+ */
+static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.actor_key) + 1;
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
+
+
+/*
+ * Show current 802.3ad partner key.
+ */
+static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.partner_key) + 1;
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
+
+
+/*
+ * Show current 802.3ad partner mac.
+ */
+static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf)
+{
+	int count = 0;
+	struct bonding *bond = to_bond(cd);
+
+	if (bond->params.mode == BOND_MODE_8023AD) {
+		struct ad_info ad_info;
+		if (!bond_3ad_get_active_agg_info(bond, &ad_info)) {
+			count = sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x\n",
+				       ad_info.partner_system[0],
+				       ad_info.partner_system[1],
+				       ad_info.partner_system[2],
+				       ad_info.partner_system[3],
+				       ad_info.partner_system[4],
+				       ad_info.partner_system[5]) + 1;
+		}
+	}
+	else
+		count = sprintf(buf, "\n") + 1;
+
+	return count;
+}
+static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
+
+
+
+static struct attribute *per_bond_attrs[] = {
+	&class_device_attr_slaves.attr,
+	&class_device_attr_mode.attr,
+	&class_device_attr_arp_interval.attr,
+	&class_device_attr_arp_ip_target.attr,
+	&class_device_attr_downdelay.attr,
+	&class_device_attr_updelay.attr,
+	&class_device_attr_lacp_rate.attr,
+	&class_device_attr_xmit_hash_policy.attr,
+	&class_device_attr_miimon.attr,
+	&class_device_attr_primary.attr,
+	&class_device_attr_use_carrier.attr,
+	&class_device_attr_active_slave.attr,
+	&class_device_attr_mii_status.attr,
+	&class_device_attr_ad_aggregator.attr,
+	&class_device_attr_ad_num_ports.attr,
+	&class_device_attr_ad_actor_key.attr,
+	&class_device_attr_ad_partner_key.attr,
+	&class_device_attr_ad_partner_mac.attr,
+	NULL,
+};
+
+static struct attribute_group bonding_group = {
+	.name = "bonding",
+	.attrs = per_bond_attrs,
+};
+
+/*
+ * Initialize sysfs.  This sets up the bonding_masters file in
+ * /sys/class/net.
+ */
+int bond_create_sysfs(void)
+{
+	int ret = 0;
+	struct bonding *firstbond;
+
+	init_rwsem(&bonding_rwsem);
+
+	/* get the netdev class pointer */
+	firstbond = container_of(bond_dev_list.next, struct bonding, bond_list);
+	if (!firstbond)
+		return -ENODEV;
+
+	netdev_class = firstbond->dev->class_dev.class;
+	if (!netdev_class)
+		return -ENODEV;
+
+	ret = class_create_file(netdev_class, &class_attr_bonding_masters);
+
+	return ret;
+
+}
+
+/*
+ * Remove /sys/class/net/bonding_masters.
+ */
+void bond_destroy_sysfs(void)
+{
+	if (netdev_class)
+		class_remove_file(netdev_class, &class_attr_bonding_masters);
+}
+
+/*
+ * Initialize sysfs for each bond.  This sets up and registers
+ * the 'bondctl' directory for each individual bond under /sys/class/net.
+ */
+int bond_create_sysfs_entry(struct bonding *bond)
+{
+	struct net_device *dev = bond->dev;
+	int err;
+
+	err = sysfs_create_group(&(dev->class_dev.kobj), &bonding_group);
+	if (err) {
+		printk(KERN_EMERG "eek! didn't create group!\n");
+	}
+
+	if (expected_refcount < 1)
+		expected_refcount = atomic_read(&bond->dev->class_dev.kobj.kref.refcount);
+
+	return err;
+}
+/*
+ * Remove sysfs entries for each bond.
+ */
+void bond_destroy_sysfs_entry(struct bonding *bond)
+{
+	struct net_device *dev = bond->dev;
+
+	sysfs_remove_group(&(dev->class_dev.kobj), &bonding_group);
+}
+
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 1433e91..015c7f1 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -10,25 +10,6 @@
  *	This software may be used and distributed according to the terms
  *	of the GNU Public License, incorporated herein by reference.
  *
- *
- * 2003/03/18 - Amir Noam <amir.noam at intel dot com>,
- *		Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Shmulik Hen <shmulik.hen at intel dot com>
- *	- Added support for IEEE 802.3ad Dynamic link aggregation mode.
- *
- * 2003/05/01 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and
- *		Amir Noam <amir.noam at intel dot com>
- *	- Code beautification and style changes (mainly in comments).
- *
- * 2003/05/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Added support for Transmit load balancing mode.
- *
- * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
- *	- Code cleanup and style changes
- *
- * 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
- *      - added "xmit_policy" kernel parameter for alternate hashing policy
- *	  support for mode 2
  */
 
 #ifndef _LINUX_BONDING_H
@@ -37,11 +18,12 @@
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
 #include <linux/if_bonding.h>
+#include <linux/kobject.h>
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION	"2.6.5"
-#define DRV_RELDATE	"November 4, 2005"
+#define DRV_VERSION	"3.0.0"
+#define DRV_RELDATE	"November 8, 2005"
 #define DRV_NAME	"bonding"
 #define DRV_DESCRIPTION	"Ethernet Channel Bonding Driver"
 
@@ -152,6 +134,11 @@
 	u32 arp_targets[BOND_MAX_ARP_TARGETS];
 };
 
+struct bond_parm_tbl {
+	char *modename;
+	int mode;
+};
+
 struct vlan_entry {
 	struct list_head vlan_list;
 	u32 vlan_ip;
@@ -159,7 +146,7 @@
 };
 
 struct slave {
-	struct net_device *dev; /* first - usefull for panic debug */
+	struct net_device *dev; /* first - useful for panic debug */
 	struct slave *next;
 	struct slave *prev;
 	s16    delay;
@@ -185,7 +172,7 @@
  *    beforehand.
  */
 struct bonding {
-	struct   net_device *dev; /* first - usefull for panic debug */
+	struct   net_device *dev; /* first - useful for panic debug */
 	struct   slave *first_slave;
 	struct   slave *curr_active_slave;
 	struct   slave *current_arp_slave;
@@ -255,6 +242,25 @@
 
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
+int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
+void bond_deinit(struct net_device *bond_dev);
+int bond_create_sysfs(void);
+void bond_destroy_sysfs(void);
+void bond_destroy_sysfs_entry(struct bonding *bond);
+int bond_create_sysfs_entry(struct bonding *bond);
+int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
+void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
+int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
+int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
+int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);
+void bond_mii_monitor(struct net_device *bond_dev);
+void bond_loadbalance_arp_mon(struct net_device *bond_dev);
+void bond_activebackup_arp_mon(struct net_device *bond_dev);
+void bond_set_mode_ops(struct bonding *bond, int mode);
+int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
+const char *bond_mode_name(int mode);
+void bond_select_active_slave(struct bonding *bond);
+void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 
 #endif /* _LINUX_BONDING_H */
 
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 53b41d9..2c5b849 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1332,8 +1332,8 @@
  *
  * This runs with softirqs disabled.
  */
-unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
-		       unsigned int qid, struct net_device *dev)
+static int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
+		     unsigned int qid, struct net_device *dev)
 {
 	struct sge *sge = adapter->sge;
 	struct cmdQ *q = &sge->cmdQ[qid];
@@ -1352,9 +1352,10 @@
 			set_bit(dev->if_port, &sge->stopped_tx_queues);
 			sge->stats.cmdQ_full[3]++;
 			spin_unlock(&q->lock);
-			CH_ERR("%s: Tx ring full while queue awake!\n",
-			       adapter->name);
-			return 1;
+			if (!netif_queue_stopped(dev))
+				CH_ERR("%s: Tx ring full while queue awake!\n",
+				       adapter->name);
+			return NETDEV_TX_BUSY;
 		}
 		if (unlikely(credits - count < q->stop_thres)) {
 			sge->stats.cmdQ_full[3]++;
@@ -1389,7 +1390,7 @@
 			writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL);
 		}
 	}
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 #define MK_ETH_TYPE_MSS(type, mss) (((mss) & 0x3FFF) | ((type) << 14))
@@ -1449,7 +1450,7 @@
 		if (unlikely(skb->len < ETH_HLEN ||
 			     skb->len > dev->mtu + eth_hdr_len(skb->data))) {
 			dev_kfree_skb_any(skb);
-			return NET_XMIT_SUCCESS;
+			return NETDEV_TX_OK;
 		}
 
 		/*
@@ -1467,7 +1468,7 @@
 			skb = skb_realloc_headroom(skb, sizeof(*cpl));
 			dev_kfree_skb_any(orig_skb);
 			if (!skb)
-				return -ENOMEM;
+				return NETDEV_TX_OK;
 		}
 
 		if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
@@ -1475,7 +1476,7 @@
 		    skb->nh.iph->protocol == IPPROTO_UDP)
 			if (unlikely(skb_checksum_help(skb, 0))) {
 				dev_kfree_skb_any(skb);
-				return -ENOMEM;
+				return NETDEV_TX_OK;
 			}
 
 		/* Hmmm, assuming to catch the gratious arp... and we'll use
diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h
index 434b255..6d0d24a 100644
--- a/drivers/net/chelsio/sge.h
+++ b/drivers/net/chelsio/sge.h
@@ -89,8 +89,6 @@
 int t1_sge_set_coalesce_params(struct sge *, struct sge_params *);
 void t1_sge_destroy(struct sge *);
 intr_handler_t t1_select_intr_handler(adapter_t *adapter);
-unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter,
-		       unsigned int qid, struct net_device *netdev);
 int t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
 void t1_set_vlan_accel(struct adapter *adapter, int on_off);
 void t1_sge_start(struct sge *);
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index a6078ad..907c010 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -175,7 +175,7 @@
 #include <asm/irq.h>
 static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
-#elif defined(CONFIG_ARCH_PNX0105)
+#elif defined(CONFIG_ARCH_PNX010X)
 #include <asm/irq.h>
 #include <asm/arch/gpio.h>
 #define CIRRUS_DEFAULT_BASE	IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000)	/* = Physical address 0x48200000 */
@@ -338,30 +338,86 @@
 }
 #endif
 
+#if defined(CONFIG_ARCH_IXDP2X01)
 static int
-readreg(struct net_device *dev, int portno)
+readword(unsigned long base_addr, int portno)
 {
-	outw(portno, dev->base_addr + ADD_PORT);
-	return inw(dev->base_addr + DATA_PORT);
+	return (u16)__raw_readl(base_addr + (portno << 1));
 }
 
 static void
-writereg(struct net_device *dev, int portno, int value)
+writeword(unsigned long base_addr, int portno, int value)
 {
-	outw(portno, dev->base_addr + ADD_PORT);
-	outw(value, dev->base_addr + DATA_PORT);
+	__raw_writel((u16)value, base_addr + (portno << 1));
 }
-
+#else
+#if defined(CONFIG_ARCH_PNX010X)
 static int
-readword(struct net_device *dev, int portno)
+readword(unsigned long base_addr, int portno)
 {
-	return inw(dev->base_addr + portno);
+	return inw(base_addr + (portno << 1));
 }
 
 static void
-writeword(struct net_device *dev, int portno, int value)
+writeword(unsigned long base_addr, int portno, int value)
 {
-	outw(value, dev->base_addr + portno);
+	outw(value, base_addr + (portno << 1));
+}
+#else
+static int
+readword(unsigned long base_addr, int portno)
+{
+	return inw(base_addr + portno);
+}
+
+static void
+writeword(unsigned long base_addr, int portno, int value)
+{
+	outw(value, base_addr + portno);
+}
+#endif
+#endif
+
+static void
+readwords(unsigned long base_addr, int portno, void *buf, int length)
+{
+	u8 *buf8 = (u8 *)buf;
+
+	do {
+		u32 tmp32;
+
+		tmp32 = readword(base_addr, portno);
+		*buf8++ = (u8)tmp32;
+		*buf8++ = (u8)(tmp32 >> 8);
+	} while (--length);
+}
+
+static void
+writewords(unsigned long base_addr, int portno, void *buf, int length)
+{
+	u8 *buf8 = (u8 *)buf;
+
+	do {
+		u32 tmp32;
+
+		tmp32 = *buf8++;
+		tmp32 |= (*buf8++) << 8;
+		writeword(base_addr, portno, tmp32);
+	} while (--length);
+}
+
+static int
+readreg(struct net_device *dev, int regno)
+{
+	writeword(dev->base_addr, ADD_PORT, regno);
+	return readword(dev->base_addr, DATA_PORT);
+}
+
+static void
+writereg(struct net_device *dev, int regno, int value)
+{
+	writeword(dev->base_addr, ADD_PORT, regno);
+	writeword(dev->base_addr, DATA_PORT, value);
 }
 
 static int __init
@@ -456,7 +512,7 @@
 #endif
         }
 
-#ifdef CONFIG_ARCH_PNX0105
+#ifdef CONFIG_ARCH_PNX010X
 	initialize_ebi();
 
 	/* Map GPIO registers for the pins connected to the CS8900a. */
@@ -491,8 +547,8 @@
 
 #ifdef CONFIG_SH_HICOSH4
 	/* truely reset the chip */
-	outw(0x0114, ioaddr + ADD_PORT);
-	outw(0x0040, ioaddr + DATA_PORT);
+	writeword(ioaddr, ADD_PORT, 0x0114);
+	writeword(ioaddr, DATA_PORT, 0x0040);
 #endif
 
 	/* if they give us an odd I/O address, then do ONE write to
@@ -503,24 +559,24 @@
 		if (net_debug > 1)
 			printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr);
 	        if ((ioaddr & 2) != 2)
-	        	if ((inw((ioaddr & ~3)+ ADD_PORT) & ADD_MASK) != ADD_SIG) {
+	        	if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) {
 				printk(KERN_ERR "%s: bad signature 0x%x\n",
-					dev->name, inw((ioaddr & ~3)+ ADD_PORT));
+					dev->name, readword(ioaddr & ~3, ADD_PORT));
 		        	retval = -ENODEV;
 				goto out2;
 			}
 	}
-	printk(KERN_DEBUG "PP_addr at %x: 0x%x\n",
-			ioaddr + ADD_PORT, inw(ioaddr + ADD_PORT));
+	printk(KERN_DEBUG "PP_addr at %x[%x]: 0x%x\n",
+			ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT));
 
 	ioaddr &= ~3;
-	outw(PP_ChipID, ioaddr + ADD_PORT);
+	writeword(ioaddr, ADD_PORT, PP_ChipID);
 
-	tmp = inw(ioaddr + DATA_PORT);
+	tmp = readword(ioaddr, DATA_PORT);
 	if (tmp != CHIP_EISA_ID_SIG) {
-		printk(KERN_DEBUG "%s: incorrect signature at %x: 0x%x!="
+		printk(KERN_DEBUG "%s: incorrect signature at %x[%x]: 0x%x!="
 			CHIP_EISA_ID_SIG_STR "\n",
-			dev->name, ioaddr + DATA_PORT, tmp);
+			dev->name, ioaddr, DATA_PORT, tmp);
   		retval = -ENODEV;
   		goto out2;
 	}
@@ -724,7 +780,7 @@
 	} else {
 		i = lp->isa_config & INT_NO_MASK;
 		if (lp->chip_type == CS8900) {
-#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
+#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX010X)
 		        i = cs8900_irq_map[0];
 #else
 			/* Translate the IRQ using the IRQ mapping table. */
@@ -790,7 +846,7 @@
 		goto out3;
 	return 0;
 out3:
-	outw(PP_ChipID, dev->base_addr + ADD_PORT);
+	writeword(dev->base_addr, ADD_PORT, PP_ChipID);
 out2:
 	release_region(ioaddr & ~3, NETCARD_IO_EXTENT);
 out1:
@@ -970,11 +1026,11 @@
 #ifndef CONFIG_ARCH_IXDP2X01
 	if (lp->chip_type != CS8900) {
 		/* Hardware problem requires PNP registers to be reconfigured after a reset */
-		outw(PP_CS8920_ISAINT, ioaddr + ADD_PORT);
+		writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT);
 		outb(dev->irq, ioaddr + DATA_PORT);
 		outb(0,      ioaddr + DATA_PORT + 1);
 
-		outw(PP_CS8920_ISAMemB, ioaddr + ADD_PORT);
+		writeword(ioaddr, ADD_PORT, PP_CS8920_ISAMemB);
 		outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT);
 		outb((dev->mem_start >> 8) & 0xff,   ioaddr + DATA_PORT + 1);
 	}
@@ -1104,8 +1160,8 @@
 	memcpy(test_packet,          dev->dev_addr, ETH_ALEN);
 	memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN);
 
-        writeword(dev, TX_CMD_PORT, TX_AFTER_ALL);
-        writeword(dev, TX_LEN_PORT, ETH_ZLEN);
+        writeword(dev->base_addr, TX_CMD_PORT, TX_AFTER_ALL);
+        writeword(dev->base_addr, TX_LEN_PORT, ETH_ZLEN);
 
 	/* Test to see if the chip has allocated memory for the packet */
 	while (jiffies - timenow < 5)
@@ -1115,7 +1171,7 @@
 		return 0;	/* this shouldn't happen */
 
 	/* Write the contents of the packet */
-	outsw(dev->base_addr + TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1);
+	writewords(dev->base_addr, TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1);
 
 	if (net_debug > 1) printk("Sending test packet ");
 	/* wait a couple of jiffies for packet to be received */
@@ -1200,7 +1256,7 @@
 	int i;
 	int ret;
 
-#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX0105) /* uses irq#1, so this won't work */
+#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) /* uses irq#1, so this won't work */
 	if (dev->irq < 2) {
 		/* Allow interrupts to be generated by the chip */
 /* Cirrus' release had this: */
@@ -1231,7 +1287,7 @@
 	else
 #endif
 	{
-#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105)
+#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X)
 		if (((1 << dev->irq) & lp->irq_map) == 0) {
 			printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
                                dev->name, dev->irq, lp->irq_map);
@@ -1316,7 +1372,7 @@
 	case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break;
         default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2);
         }
-#ifdef CONFIG_ARCH_PNX0105
+#ifdef CONFIG_ARCH_PNX010X
 	result = A_CNF_10B_T;
 #endif
         if (!result) {
@@ -1457,8 +1513,8 @@
 	netif_stop_queue(dev);
 
 	/* initiate a transmit sequence */
-	writeword(dev, TX_CMD_PORT, lp->send_cmd);
-	writeword(dev, TX_LEN_PORT, skb->len);
+	writeword(dev->base_addr, TX_CMD_PORT, lp->send_cmd);
+	writeword(dev->base_addr, TX_LEN_PORT, skb->len);
 
 	/* Test to see if the chip has allocated memory for the packet */
 	if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
@@ -1472,7 +1528,7 @@
 		return 1;
 	}
 	/* Write the contents of the packet */
-	outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
+	writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
 	spin_unlock_irq(&lp->lock);
 	lp->stats.tx_bytes += skb->len;
 	dev->trans_start = jiffies;
@@ -1512,7 +1568,7 @@
            course, if you're on a slow machine, and packets are arriving
            faster than you can read them off, you're screwed.  Hasta la
            vista, baby!  */
-	while ((status = readword(dev, ISQ_PORT))) {
+	while ((status = readword(dev->base_addr, ISQ_PORT))) {
 		if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status);
 		handled = 1;
 		switch(status & ISQ_EVENT_MASK) {
@@ -1606,8 +1662,8 @@
 	int status, length;
 
 	int ioaddr = dev->base_addr;
-	status = inw(ioaddr + RX_FRAME_PORT);
-	length = inw(ioaddr + RX_FRAME_PORT);
+	status = readword(ioaddr, RX_FRAME_PORT);
+	length = readword(ioaddr, RX_FRAME_PORT);
 
 	if ((status & RX_OK) == 0) {
 		count_rx_errors(status, lp);
@@ -1626,9 +1682,9 @@
 	skb_reserve(skb, 2);	/* longword align L3 header */
 	skb->dev = dev;
 
-	insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> 1);
+	readwords(ioaddr, RX_FRAME_PORT, skb_put(skb, length), length >> 1);
 	if (length & 1)
-		skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT);
+		skb->data[length-1] = readword(ioaddr, RX_FRAME_PORT);
 
 	if (net_debug > 3) {
 		printk(	"%s: received %d byte packet of type %x\n",
@@ -1901,7 +1957,7 @@
 cleanup_module(void)
 {
 	unregister_netdev(dev_cs89x0);
-	outw(PP_ChipID, dev_cs89x0->base_addr + ADD_PORT);
+	writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID);
 	release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
 	free_netdev(dev_cs89x0);
 }
diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h
index decea26..bd954aa 100644
--- a/drivers/net/cs89x0.h
+++ b/drivers/net/cs89x0.h
@@ -16,13 +16,6 @@
 
 #include <linux/config.h>
 
-#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
-/* IXDP2401/IXDP2801 uses dword-aligned register addressing */
-#define CS89x0_PORT(reg) ((reg) * 2)
-#else
-#define CS89x0_PORT(reg) (reg)
-#endif
-
 #define PP_ChipID 0x0000	/* offset   0h -> Corp -ID              */
 				/* offset   2h -> Model/Product Number  */
 				/* offset   3h -> Chip Revision Number  */
@@ -332,16 +325,16 @@
 #define RAM_SIZE	0x1000       /*  The card has 4k bytes or RAM */
 #define PKT_START PP_TxFrame  /*  Start of packet RAM */
 
-#define RX_FRAME_PORT	CS89x0_PORT(0x0000)
+#define RX_FRAME_PORT	0x0000
 #define TX_FRAME_PORT RX_FRAME_PORT
-#define TX_CMD_PORT	CS89x0_PORT(0x0004)
+#define TX_CMD_PORT	0x0004
 #define TX_NOW		0x0000       /*  Tx packet after   5 bytes copied */
 #define TX_AFTER_381	0x0040       /*  Tx packet after 381 bytes copied */
 #define TX_AFTER_ALL	0x00c0       /*  Tx packet after all bytes copied */
-#define TX_LEN_PORT	CS89x0_PORT(0x0006)
-#define ISQ_PORT	CS89x0_PORT(0x0008)
-#define ADD_PORT	CS89x0_PORT(0x000A)
-#define DATA_PORT	CS89x0_PORT(0x000C)
+#define TX_LEN_PORT	0x0006
+#define ISQ_PORT	0x0008
+#define ADD_PORT	0x000A
+#define DATA_PORT	0x000C
 
 #define EEPROM_WRITE_EN		0x00F0
 #define EEPROM_WRITE_DIS	0x0000
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 3f653a9..e02e9ba 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -188,11 +188,13 @@
 	/* array of buffer information structs */
 	struct e1000_buffer *buffer_info;
 
-	struct e1000_buffer previous_buffer_info;
 	spinlock_t tx_lock;
 	uint16_t tdh;
 	uint16_t tdt;
 	uint64_t pkt;
+
+	boolean_t last_tx_tso;
+
 };
 
 struct e1000_rx_ring {
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 8eae8ba..c88f1a3 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -562,10 +562,29 @@
                        struct ethtool_drvinfo *drvinfo)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
+	char firmware_version[32];
+	uint16_t eeprom_data;
 
 	strncpy(drvinfo->driver,  e1000_driver_name, 32);
 	strncpy(drvinfo->version, e1000_driver_version, 32);
-	strncpy(drvinfo->fw_version, "N/A", 32);
+	
+	/* EEPROM image version # is reported as firware version # for
+	 * 8257{1|2|3} controllers */
+	e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data);
+	switch (adapter->hw.mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+	case e1000_82573:
+		sprintf(firmware_version, "%d.%d-%d", 
+			(eeprom_data & 0xF000) >> 12,
+			(eeprom_data & 0x0FF0) >> 4,
+			eeprom_data & 0x000F);
+		break;
+	default:
+		sprintf(firmware_version, "n/a");
+	}
+
+	strncpy(drvinfo->fw_version, firmware_version, 32);
 	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
 	drvinfo->n_stats = E1000_STATS_LEN;
 	drvinfo->testinfo_len = E1000_TEST_LEN;
@@ -960,13 +979,21 @@
 		}
 	}
 
-	if(txdr->desc)
+	if(txdr->desc) {
 		pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma);
-	if(rxdr->desc)
+		txdr->desc = NULL;
+	}
+	if(rxdr->desc) {
 		pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
+		rxdr->desc = NULL;
+	}
 
 	kfree(txdr->buffer_info);
+	txdr->buffer_info = NULL;
+
 	kfree(rxdr->buffer_info);
+	rxdr->buffer_info = NULL;
+
 	return;
 }
 
@@ -1301,21 +1328,32 @@
 e1000_setup_loopback_test(struct e1000_adapter *adapter)
 {
 	uint32_t rctl;
+	struct e1000_hw *hw = &adapter->hw;
 
-	if(adapter->hw.media_type == e1000_media_type_fiber ||
-	   adapter->hw.media_type == e1000_media_type_internal_serdes) {
-		if(adapter->hw.mac_type == e1000_82545 ||
-		   adapter->hw.mac_type == e1000_82546 ||
-		   adapter->hw.mac_type == e1000_82545_rev_3 ||
-		   adapter->hw.mac_type == e1000_82546_rev_3)
+	if (hw->media_type == e1000_media_type_fiber ||
+	   hw->media_type == e1000_media_type_internal_serdes) {
+		switch (hw->mac_type) {
+		case e1000_82545:
+		case e1000_82546:
+		case e1000_82545_rev_3:
+		case e1000_82546_rev_3:
 			return e1000_set_phy_loopback(adapter);
-		else {
-			rctl = E1000_READ_REG(&adapter->hw, RCTL);
+			break;
+		case e1000_82571:
+		case e1000_82572:
+#define E1000_SERDES_LB_ON 0x410
+			e1000_set_phy_loopback(adapter);
+			E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_ON);
+			msec_delay(10);
+			return 0;
+			break;
+		default:
+			rctl = E1000_READ_REG(hw, RCTL);
 			rctl |= E1000_RCTL_LBM_TCVR;
-			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+			E1000_WRITE_REG(hw, RCTL, rctl);
 			return 0;
 		}
-	} else if(adapter->hw.media_type == e1000_media_type_copper)
+	} else if (hw->media_type == e1000_media_type_copper)
 		return e1000_set_phy_loopback(adapter);
 
 	return 7;
@@ -1326,25 +1364,36 @@
 {
 	uint32_t rctl;
 	uint16_t phy_reg;
+	struct e1000_hw *hw = &adapter->hw;
 
 	rctl = E1000_READ_REG(&adapter->hw, RCTL);
 	rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
 	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
 
-	if(adapter->hw.media_type == e1000_media_type_copper ||
-	   ((adapter->hw.media_type == e1000_media_type_fiber ||
-	     adapter->hw.media_type == e1000_media_type_internal_serdes) &&
-	    (adapter->hw.mac_type == e1000_82545 ||
-	     adapter->hw.mac_type == e1000_82546 ||
-	     adapter->hw.mac_type == e1000_82545_rev_3 ||
-	     adapter->hw.mac_type == e1000_82546_rev_3))) {
-		adapter->hw.autoneg = TRUE;
-		e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
-		if(phy_reg & MII_CR_LOOPBACK) {
-			phy_reg &= ~MII_CR_LOOPBACK;
-			e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);
-			e1000_phy_reset(&adapter->hw);
+	switch (hw->mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+		if (hw->media_type == e1000_media_type_fiber ||
+		   hw->media_type == e1000_media_type_internal_serdes){
+#define E1000_SERDES_LB_OFF 0x400
+			E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF);
+			msec_delay(10);
+			break;
 		}
+		/* fall thru for Cu adapters */
+	case e1000_82545:
+	case e1000_82546:
+	case e1000_82545_rev_3:
+	case e1000_82546_rev_3:
+	default:
+		hw->autoneg = TRUE;
+		e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
+		if (phy_reg & MII_CR_LOOPBACK) {
+			phy_reg &= ~MII_CR_LOOPBACK;
+			e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
+			e1000_phy_reset(hw);
+		}
+		break;
 	}
 }
 
@@ -1440,9 +1489,11 @@
 e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data)
 {
 	if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback;
-	if((*data = e1000_setup_loopback_test(adapter))) goto err_loopback;
+	if((*data = e1000_setup_loopback_test(adapter)))
+		goto err_loopback_setup;
 	*data = e1000_run_loopback_test(adapter);
 	e1000_loopback_cleanup(adapter);
+err_loopback_setup:
 	e1000_free_desc_rings(adapter);
 err_loopback:
 	return *data;
@@ -1671,6 +1722,14 @@
 		msleep_interruptible(data * 1000);
 		del_timer_sync(&adapter->blink_timer);
 	}
+	else if(adapter->hw.mac_type < e1000_82573) {
+		E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
+			E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK |
+			(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) |
+			(E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) |
+			(E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT)));
+		msleep_interruptible(data * 1000);
+	}
 	else {
 		E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE |
 			E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | 
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index a267c52..136fc03 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -563,11 +563,13 @@
             msec_delay(20);
             break;
         case e1000_82573:
-            udelay(10);
-            ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-            ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-            E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-            E1000_WRITE_FLUSH(hw);
+            if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) {
+                udelay(10);
+                ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+                E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+                E1000_WRITE_FLUSH(hw);
+            }
             /* fall through */
         case e1000_82571:
         case e1000_82572:
@@ -844,19 +846,27 @@
      * control setting, then the variable hw->fc will
      * be initialized based on a value in the EEPROM.
      */
-    if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) {
-        DEBUGOUT("EEPROM Read Error\n");
-        return -E1000_ERR_EEPROM;
-    }
-
-    if(hw->fc == e1000_fc_default) {
-        if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
-            hw->fc = e1000_fc_none;
-        else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
-                EEPROM_WORD0F_ASM_DIR)
-            hw->fc = e1000_fc_tx_pause;
-        else
+    if (hw->fc == e1000_fc_default) {
+        switch (hw->mac_type) {
+        case e1000_82573:
             hw->fc = e1000_fc_full;
+            break;
+        default:
+            ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
+                                        1, &eeprom_data);
+            if (ret_val) {
+                DEBUGOUT("EEPROM Read Error\n");
+                return -E1000_ERR_EEPROM;
+            }
+            if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
+                hw->fc = e1000_fc_none;
+            else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
+                    EEPROM_WORD0F_ASM_DIR)
+                hw->fc = e1000_fc_tx_pause;
+            else
+                hw->fc = e1000_fc_full;
+            break;
+        }
     }
 
     /* We want to save off the original Flow Control configuration just
@@ -2962,13 +2972,22 @@
     if(hw->mac_type > e1000_82543) {
         /* Read the device control register and assert the E1000_CTRL_PHY_RST
          * bit. Then, take it out of reset.
+         * For pre-e1000_82571 hardware, we delay for 10ms between the assert 
+         * and deassert.  For e1000_82571 hardware and later, we instead delay
+         * for 10ms after the deassertion.
          */
         ctrl = E1000_READ_REG(hw, CTRL);
         E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
         E1000_WRITE_FLUSH(hw);
-        msec_delay(10);
+        
+        if (hw->mac_type < e1000_82571) 
+            msec_delay(10);
+        
         E1000_WRITE_REG(hw, CTRL, ctrl);
         E1000_WRITE_FLUSH(hw);
+        
+        if (hw->mac_type >= e1000_82571)
+            msec_delay(10);
     } else {
         /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
          * bit to put the PHY into reset. Then, take it out of reset.
@@ -5278,11 +5297,15 @@
         hw->bus_speed = e1000_bus_speed_unknown;
         hw->bus_width = e1000_bus_width_unknown;
         break;
-    case e1000_82571:
     case e1000_82572:
     case e1000_82573:
         hw->bus_type = e1000_bus_type_pci_express;
         hw->bus_speed = e1000_bus_speed_2500;
+        hw->bus_width = e1000_bus_width_pciex_1;
+        break;
+    case e1000_82571:
+        hw->bus_type = e1000_bus_type_pci_express;
+        hw->bus_speed = e1000_bus_speed_2500;
         hw->bus_width = e1000_bus_width_pciex_4;
         break;
     default:
@@ -6650,6 +6673,12 @@
         break;
     }
 
+    /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
+     * Need to wait for PHY configuration completion before accessing NVM
+     * and PHY. */
+    if (hw->mac_type == e1000_82573)
+        msec_delay(25);
+
     return E1000_SUCCESS;
 }
 
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 76ce128..7caa357 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -123,6 +123,7 @@
     e1000_bus_width_32,
     e1000_bus_width_64,
     e1000_bus_width_pciex_1,
+    e1000_bus_width_pciex_2,
     e1000_bus_width_pciex_4,
     e1000_bus_width_reserved
 } e1000_bus_width;
@@ -149,6 +150,7 @@
     e1000_igp_cable_length_90  = 90,
     e1000_igp_cable_length_100 = 100,
     e1000_igp_cable_length_110 = 110,
+    e1000_igp_cable_length_115 = 115,
     e1000_igp_cable_length_120 = 120,
     e1000_igp_cable_length_130 = 130,
     e1000_igp_cable_length_140 = 140,
@@ -1457,6 +1459,7 @@
 #define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
 #define E1000_EECD_SHADV     0x00200000 /* Shadow RAM Data Valid */
 #define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
+#define E1000_EECD_SECVAL_SHIFT      22
 #define E1000_STM_OPCODE     0xDB00
 #define E1000_HICR_FW_RESET  0xC0
 
@@ -1951,7 +1954,6 @@
 
 #define E1000_MDALIGN          4096
 
-#define E1000_GCR_BEM32                 0x00400000
 #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
 /* Function Active and Power State to MNG */
 #define E1000_FACTPS_FUNC0_POWER_STATE_MASK         0x00000003
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 8b207f0..438a931 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -711,6 +711,7 @@
 		break;
 	case e1000_82546:
 	case e1000_82546_rev_3:
+	case e1000_82571:
 		if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
 		   && (adapter->hw.media_type == e1000_media_type_copper)) {
 			e1000_read_eeprom(&adapter->hw,
@@ -1158,7 +1159,6 @@
 		return -ENOMEM;
 	}
 	memset(txdr->buffer_info, 0, size);
-	memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer));
 
 	/* round up to nearest 4K */
 
@@ -1813,11 +1813,6 @@
 
 	/* Free all the Tx ring sk_buffs */
 
-	if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
-		e1000_unmap_and_free_tx_resource(adapter,
-				&tx_ring->previous_buffer_info);
-	}
-
 	for(i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
 		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -1832,6 +1827,7 @@
 
 	tx_ring->next_to_use = 0;
 	tx_ring->next_to_clean = 0;
+	tx_ring->last_tx_tso = 0;
 
 	writel(0, adapter->hw.hw_addr + tx_ring->tdh);
 	writel(0, adapter->hw.hw_addr + tx_ring->tdt);
@@ -2437,6 +2433,16 @@
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, max_per_txd);
 #ifdef NETIF_F_TSO
+		/* Workaround for Controller erratum --
+		 * descriptor for non-tso packet in a linear SKB that follows a
+		 * tso gets written back prematurely before the data is fully
+		 * DMAd to the controller */
+		if (!skb->data_len && tx_ring->last_tx_tso &&
+				!skb_shinfo(skb)->tso_size) {
+			tx_ring->last_tx_tso = 0;
+			size -= 4;
+		}
+
 		/* Workaround for premature desc write-backs
 		 * in TSO mode.  Append 4-byte sentinel desc */
 		if(unlikely(mss && !nr_frags && size == len && size > 8))
@@ -2621,19 +2627,7 @@
 			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
 			return 0;
 	}
-	if(htons(ETH_P_IP) == skb->protocol) {
-		const struct iphdr *ip = skb->nh.iph;
-		if(IPPROTO_UDP == ip->protocol) {
-			struct udphdr *udp = (struct udphdr *)(skb->h.uh);
-			if(ntohs(udp->dest) == 67) {
-				offset = (uint8_t *)udp + 8 - skb->data;
-				length = skb->len - offset;
-
-				return e1000_mng_write_dhcp_info(hw,
-						(uint8_t *)udp + 8, length);
-			}
-		}
-	} else if((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
+ 	if ((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) {
 		struct ethhdr *eth = (struct ethhdr *) skb->data;
 		if((htons(ETH_P_IP) == eth->h_proto)) {
 			const struct iphdr *ip = 
@@ -2705,6 +2699,14 @@
 	if(skb->ip_summed == CHECKSUM_HW)
 		count++;
 #endif
+
+#ifdef NETIF_F_TSO
+	/* Controller Erratum workaround */
+	if (!skb->data_len && tx_ring->last_tx_tso &&
+		!skb_shinfo(skb)->tso_size)
+		count++;
+#endif
+
 	count += TXD_USE_COUNT(len, max_txd_pwr);
 
 	if(adapter->pcix_82544)
@@ -2786,9 +2788,10 @@
 		return NETDEV_TX_OK;
 	}
 
-	if (likely(tso))
+	if (likely(tso)) {
+		tx_ring->last_tx_tso = 1;
 		tx_flags |= E1000_TX_FLAGS_TSO;
-	else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
+	} else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
 	/* Old method was to assume IPv4 packet by default if TSO was enabled.
@@ -3239,37 +3242,12 @@
 	eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
 	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-		/* Premature writeback of Tx descriptors clear (free buffers
-		 * and unmap pci_mapping) previous_buffer_info */
-		if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
-			e1000_unmap_and_free_tx_resource(adapter,
-					&tx_ring->previous_buffer_info);
-		}
-
 		for(cleaned = FALSE; !cleaned; ) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 			cleaned = (i == eop);
 
-#ifdef NETIF_F_TSO
-			if (!(netdev->features & NETIF_F_TSO)) {
-#endif
-				e1000_unmap_and_free_tx_resource(adapter,
-				                                 buffer_info);
-#ifdef NETIF_F_TSO
-			} else {
-				if (cleaned) {
-					memcpy(&tx_ring->previous_buffer_info,
-					       buffer_info,
-					       sizeof(struct e1000_buffer));
-					memset(buffer_info, 0,
-					       sizeof(struct e1000_buffer));
-				} else {
-					e1000_unmap_and_free_tx_resource(
-					    adapter, buffer_info);
-				}
-			}
-#endif
+			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
 
 			tx_desc->buffer_addr = 0;
 			tx_desc->lower.data = 0;
@@ -3330,12 +3308,6 @@
 			netif_stop_queue(netdev);
 		}
 	}
-#ifdef NETIF_F_TSO
-	if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
-	    time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ)))
-		e1000_unmap_and_free_tx_resource(
-		    adapter, &tx_ring->previous_buffer_info);
-#endif
 	return cleaned;
 }
 
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 525624f..c39344a 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -10,7 +10,7 @@
  * trademarks of NVIDIA Corporation in the United States and other
  * countries.
  *
- * Copyright (C) 2003,4 Manfred Spraul
+ * Copyright (C) 2003,4,5 Manfred Spraul
  * Copyright (C) 2004 Andrew de Quincey (wol support)
  * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane
  *		IRQ rate fixes, bigendian fixes, cleanups, verification)
@@ -100,6 +100,7 @@
  *	0.45: 18 Sep 2005: Remove nv_stop/start_rx from every link check
  *	0.46: 20 Oct 2005: Add irq optimization modes.
  *	0.47: 26 Oct 2005: Add phyaddr 0 in phy scan.
+ *	0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -111,7 +112,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION		"0.47"
+#define FORCEDETH_VERSION		"0.48"
 #define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
@@ -871,8 +872,8 @@
 		} else {
 			skb = np->rx_skbuff[nr];
 		}
-		np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len,
-						PCI_DMA_FROMDEVICE);
+		np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data,
+					skb->end-skb->data, PCI_DMA_FROMDEVICE);
 		if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
 			np->rx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]);
 			wmb();
@@ -999,7 +1000,7 @@
 		wmb();
 		if (np->rx_skbuff[i]) {
 			pci_unmap_single(np->pci_dev, np->rx_dma[i],
-						np->rx_skbuff[i]->len,
+						np->rx_skbuff[i]->end-np->rx_skbuff[i]->data,
 						PCI_DMA_FROMDEVICE);
 			dev_kfree_skb(np->rx_skbuff[i]);
 			np->rx_skbuff[i] = NULL;
@@ -1334,7 +1335,7 @@
 		 * the performance.
 		 */
 		pci_unmap_single(np->pci_dev, np->rx_dma[i],
-				np->rx_skbuff[i]->len,
+				np->rx_skbuff[i]->end-np->rx_skbuff[i]->data,
 				PCI_DMA_FROMDEVICE);
 
 		{
@@ -2455,7 +2456,7 @@
 		np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
 		dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
 #ifdef NETIF_F_TSO
-		dev->features |= NETIF_F_TSO;
+		/* disabled dev->features |= NETIF_F_TSO; */
 #endif
  	}
 
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 0f030b7..146f951 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2,7 +2,8 @@
  * drivers/net/gianfar.c
  *
  * Gianfar Ethernet Driver
- * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
+ * This driver is designed for the non-CPM ethernet controllers
+ * on the 85xx and 83xx family of integrated processors
  * Based on 8260_io/fcc_enet.c
  *
  * Author: Andy Fleming
@@ -22,8 +23,6 @@
  *  B-V +1.62
  *
  *  Theory of operation
- *  This driver is designed for the non-CPM ethernet controllers
- *  on the 85xx and 83xx family of integrated processors
  *
  *  The driver is initialized through platform_device.  Structures which
  *  define the configuration needed by the board are defined in a
@@ -110,7 +109,7 @@
 #endif
 
 const char gfar_driver_name[] = "Gianfar Ethernet";
-const char gfar_driver_version[] = "1.2";
+const char gfar_driver_version[] = "1.3";
 
 static int gfar_enet_open(struct net_device *dev);
 static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
@@ -139,6 +138,10 @@
 static void gfar_vlan_rx_register(struct net_device *netdev,
 		                struct vlan_group *grp);
 static void gfar_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
+void gfar_halt(struct net_device *dev);
+void gfar_start(struct net_device *dev);
+static void gfar_clear_exact_match(struct net_device *dev);
+static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
 
 extern struct ethtool_ops gfar_ethtool_ops;
 
@@ -146,12 +149,10 @@
 MODULE_DESCRIPTION("Gianfar Ethernet Driver");
 MODULE_LICENSE("GPL");
 
-int gfar_uses_fcb(struct gfar_private *priv)
+/* Returns 1 if incoming frames use an FCB */
+static inline int gfar_uses_fcb(struct gfar_private *priv)
 {
-	if (priv->vlan_enable || priv->rx_csum_enable)
-		return 1;
-	else
-		return 0;
+	return (priv->vlan_enable || priv->rx_csum_enable);
 }
 
 /* Set up the ethernet device structure, private data,
@@ -320,15 +321,10 @@
 	else
 		priv->padding = 0;
 
-	dev->hard_header_len += priv->padding;
-
 	if (dev->features & NETIF_F_IP_CSUM)
 		dev->hard_header_len += GMAC_FCB_LEN;
 
 	priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
-#ifdef CONFIG_GFAR_BUFSTASH
-	priv->rx_stash_size = STASH_LENGTH;
-#endif
 	priv->tx_ring_size = DEFAULT_TX_RING_SIZE;
 	priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
 
@@ -350,6 +346,9 @@
 		goto register_fail;
 	}
 
+	/* Create all the sysfs files */
+	gfar_init_sysfs(dev);
+
 	/* Print out the device info */
 	printk(KERN_INFO DEVICE_NAME, dev->name);
 	for (idx = 0; idx < 6; idx++)
@@ -357,8 +356,7 @@
 	printk("\n");
 
 	/* Even more device info helps when determining which kernel */
-	/* provided which set of benchmarks.  Since this is global for all */
-	/* devices, we only print it once */
+	/* provided which set of benchmarks. */
 #ifdef CONFIG_GFAR_NAPI
 	printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
 #else
@@ -463,19 +461,9 @@
 	/* Initialize the max receive buffer length */
 	gfar_write(&priv->regs->mrblr, priv->rx_buffer_size);
 
-#ifdef CONFIG_GFAR_BUFSTASH
-	/* If we are stashing buffers, we need to set the
-	 * extraction length to the size of the buffer */
-	gfar_write(&priv->regs->attreli, priv->rx_stash_size << 16);
-#endif
-
 	/* Initialize the Minimum Frame Length Register */
 	gfar_write(&priv->regs->minflr, MINFLR_INIT_SETTINGS);
 
-	/* Setup Attributes so that snooping is on for rx */
-	gfar_write(&priv->regs->attr, ATTR_INIT_SETTINGS);
-	gfar_write(&priv->regs->attreli, ATTRELI_INIT_SETTINGS);
-
 	/* Assign the TBI an address which won't conflict with the PHYs */
 	gfar_write(&priv->regs->tbipa, TBIPA_VALUE);
 }
@@ -577,8 +565,7 @@
 		for (i = 0; i < priv->rx_ring_size; i++) {
 			if (priv->rx_skbuff[i]) {
 				dma_unmap_single(NULL, rxbdp->bufPtr,
-						priv->rx_buffer_size
-						+ RXBUF_ALIGNMENT,
+						priv->rx_buffer_size,
 						DMA_FROM_DEVICE);
 
 				dev_kfree_skb_any(priv->rx_skbuff[i]);
@@ -636,6 +623,7 @@
 	struct gfar *regs = priv->regs;
 	int err = 0;
 	u32 rctrl = 0;
+	u32 attrs = 0;
 
 	gfar_write(&regs->imask, IMASK_INIT_CLEAR);
 
@@ -795,18 +783,50 @@
 	if (priv->rx_csum_enable)
 		rctrl |= RCTRL_CHECKSUMMING;
 
-	if (priv->extended_hash)
+	if (priv->extended_hash) {
 		rctrl |= RCTRL_EXTHASH;
 
+		gfar_clear_exact_match(dev);
+		rctrl |= RCTRL_EMEN;
+	}
+
 	if (priv->vlan_enable)
 		rctrl |= RCTRL_VLAN;
 
+	if (priv->padding) {
+		rctrl &= ~RCTRL_PAL_MASK;
+		rctrl |= RCTRL_PADDING(priv->padding);
+	}
+
 	/* Init rctrl based on our settings */
 	gfar_write(&priv->regs->rctrl, rctrl);
 
 	if (dev->features & NETIF_F_IP_CSUM)
 		gfar_write(&priv->regs->tctrl, TCTRL_INIT_CSUM);
 
+	/* Set the extraction length and index */
+	attrs = ATTRELI_EL(priv->rx_stash_size) |
+		ATTRELI_EI(priv->rx_stash_index);
+
+	gfar_write(&priv->regs->attreli, attrs);
+
+	/* Start with defaults, and add stashing or locking
+	 * depending on the approprate variables */
+	attrs = ATTR_INIT_SETTINGS;
+
+	if (priv->bd_stash_en)
+		attrs |= ATTR_BDSTASH;
+
+	if (priv->rx_stash_size != 0)
+		attrs |= ATTR_BUFSTASH;
+
+	gfar_write(&priv->regs->attr, attrs);
+
+	gfar_write(&priv->regs->fifo_tx_thr, priv->fifo_threshold);
+	gfar_write(&priv->regs->fifo_tx_starve, priv->fifo_starve);
+	gfar_write(&priv->regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
+
+	/* Start the controller */
 	gfar_start(dev);
 
 	return 0;
@@ -851,34 +871,32 @@
 	return err;
 }
 
-static struct txfcb *gfar_add_fcb(struct sk_buff *skb, struct txbd8 *bdp)
+static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb, struct txbd8 *bdp)
 {
 	struct txfcb *fcb = (struct txfcb *)skb_push (skb, GMAC_FCB_LEN);
 
 	memset(fcb, 0, GMAC_FCB_LEN);
 
-	/* Flag the bd so the controller looks for the FCB */
-	bdp->status |= TXBD_TOE;
-
 	return fcb;
 }
 
 static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb)
 {
-	int len;
+	u8 flags = 0;
 
 	/* If we're here, it's a IP packet with a TCP or UDP
 	 * payload.  We set it to checksum, using a pseudo-header
 	 * we provide
 	 */
-	fcb->ip = 1;
-	fcb->tup = 1;
-	fcb->ctu = 1;
-	fcb->nph = 1;
+	flags = TXFCB_DEFAULT;
 
-	/* Notify the controller what the protocol is */
-	if (skb->nh.iph->protocol == IPPROTO_UDP)
-		fcb->udp = 1;
+	/* Tell the controller what the protocol is */
+	/* And provide the already calculated phcs */
+	if (skb->nh.iph->protocol == IPPROTO_UDP) {
+		flags |= TXFCB_UDP;
+		fcb->phcs = skb->h.uh->check;
+	} else
+		fcb->phcs = skb->h.th->check;
 
 	/* l3os is the distance between the start of the
 	 * frame (skb->data) and the start of the IP hdr.
@@ -887,17 +905,12 @@
 	fcb->l3os = (u16)(skb->nh.raw - skb->data - GMAC_FCB_LEN);
 	fcb->l4os = (u16)(skb->h.raw - skb->nh.raw);
 
-	len = skb->nh.iph->tot_len - fcb->l4os;
-
-	/* Provide the pseudoheader csum */
-	fcb->phcs = ~csum_tcpudp_magic(skb->nh.iph->saddr,
-			skb->nh.iph->daddr, len,
-			skb->nh.iph->protocol, 0);
+	fcb->flags = flags;
 }
 
-void gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
+void inline gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
 {
-	fcb->vln = 1;
+	fcb->flags |= TXFCB_VLN;
 	fcb->vlctl = vlan_tx_tag_get(skb);
 }
 
@@ -908,6 +921,7 @@
 	struct gfar_private *priv = netdev_priv(dev);
 	struct txfcb *fcb = NULL;
 	struct txbd8 *txbdp;
+	u16 status;
 
 	/* Update transmit stats */
 	priv->stats.tx_bytes += skb->len;
@@ -919,19 +933,22 @@
 	txbdp = priv->cur_tx;
 
 	/* Clear all but the WRAP status flags */
-	txbdp->status &= TXBD_WRAP;
+	status = txbdp->status & TXBD_WRAP;
 
 	/* Set up checksumming */
-	if ((dev->features & NETIF_F_IP_CSUM)
-			&& (CHECKSUM_HW == skb->ip_summed)) {
+	if (likely((dev->features & NETIF_F_IP_CSUM)
+			&& (CHECKSUM_HW == skb->ip_summed))) {
 		fcb = gfar_add_fcb(skb, txbdp);
+		status |= TXBD_TOE;
 		gfar_tx_checksum(skb, fcb);
 	}
 
 	if (priv->vlan_enable &&
 			unlikely(priv->vlgrp && vlan_tx_tag_present(skb))) {
-		if (NULL == fcb)
+		if (unlikely(NULL == fcb)) {
 			fcb = gfar_add_fcb(skb, txbdp);
+			status |= TXBD_TOE;
+		}
 
 		gfar_tx_vlan(skb, fcb);
 	}
@@ -949,14 +966,16 @@
 	    (priv->skb_curtx + 1) & TX_RING_MOD_MASK(priv->tx_ring_size);
 
 	/* Flag the BD as interrupt-causing */
-	txbdp->status |= TXBD_INTERRUPT;
+	status |= TXBD_INTERRUPT;
 
 	/* Flag the BD as ready to go, last in frame, and  */
 	/* in need of CRC */
-	txbdp->status |= (TXBD_READY | TXBD_LAST | TXBD_CRC);
+	status |= (TXBD_READY | TXBD_LAST | TXBD_CRC);
 
 	dev->trans_start = jiffies;
 
+	txbdp->status = status;
+
 	/* If this was the last BD in the ring, the next one */
 	/* is at the beginning of the ring */
 	if (txbdp->status & TXBD_WRAP)
@@ -1010,21 +1029,7 @@
 /* Changes the mac address if the controller is not running. */
 int gfar_set_mac_address(struct net_device *dev)
 {
-	struct gfar_private *priv = netdev_priv(dev);
-	int i;
-	char tmpbuf[MAC_ADDR_LEN];
-	u32 tempval;
-
-	/* Now copy it into the mac registers backwards, cuz */
-	/* little endian is silly */
-	for (i = 0; i < MAC_ADDR_LEN; i++)
-		tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->dev_addr[i];
-
-	gfar_write(&priv->regs->macstnaddr1, *((u32 *) (tmpbuf)));
-
-	tempval = *((u32 *) (tmpbuf + 4));
-
-	gfar_write(&priv->regs->macstnaddr2, tempval);
+	gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
 
 	return 0;
 }
@@ -1110,7 +1115,7 @@
 	    INCREMENTAL_BUFFER_SIZE;
 
 	/* Only stop and start the controller if it isn't already
-	 * stopped */
+	 * stopped, and we changed something */
 	if ((oldsize != tempsize) && (dev->flags & IFF_UP))
 		stop_gfar(dev);
 
@@ -1220,6 +1225,7 @@
 
 struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
 {
+	unsigned int alignamount;
 	struct gfar_private *priv = netdev_priv(dev);
 	struct sk_buff *skb = NULL;
 	unsigned int timeout = SKB_ALLOC_TIMEOUT;
@@ -1231,18 +1237,18 @@
 	if (NULL == skb)
 		return NULL;
 
+	alignamount = RXBUF_ALIGNMENT -
+		(((unsigned) skb->data) & (RXBUF_ALIGNMENT - 1));
+
 	/* We need the data buffer to be aligned properly.  We will reserve
 	 * as many bytes as needed to align the data properly
 	 */
-	skb_reserve(skb,
-		    RXBUF_ALIGNMENT -
-		    (((unsigned) skb->data) & (RXBUF_ALIGNMENT - 1)));
+	skb_reserve(skb, alignamount);
 
 	skb->dev = dev;
 
 	bdp->bufPtr = dma_map_single(NULL, skb->data,
-			priv->rx_buffer_size + RXBUF_ALIGNMENT,
-			DMA_FROM_DEVICE);
+			priv->rx_buffer_size, DMA_FROM_DEVICE);
 
 	bdp->length = 0;
 
@@ -1350,7 +1356,7 @@
 	/* If valid headers were found, and valid sums
 	 * were verified, then we tell the kernel that no
 	 * checksumming is necessary.  Otherwise, it is */
-	if (fcb->cip && !fcb->eip && fcb->ctu && !fcb->etu)
+	if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU))
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	else
 		skb->ip_summed = CHECKSUM_NONE;
@@ -1401,7 +1407,7 @@
 		skb->protocol = eth_type_trans(skb, dev);
 
 		/* Send the packet up the stack */
-		if (unlikely(priv->vlgrp && fcb->vln))
+		if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN)))
 			ret = gfar_rx_vlan(skb, priv->vlgrp, fcb->vlctl);
 		else
 			ret = RECEIVE(skb);
@@ -1620,6 +1626,7 @@
 	spin_lock_irqsave(&priv->lock, flags);
 	if (phydev->link) {
 		u32 tempval = gfar_read(&regs->maccfg2);
+		u32 ecntrl = gfar_read(&regs->ecntrl);
 
 		/* Now we make sure that we can be in full duplex mode.
 		 * If not, we operate in half-duplex mode. */
@@ -1644,6 +1651,13 @@
 			case 10:
 				tempval =
 				    ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
+
+				/* Reduced mode distinguishes
+				 * between 10 and 100 */
+				if (phydev->speed == SPEED_100)
+					ecntrl |= ECNTRL_R100;
+				else
+					ecntrl &= ~(ECNTRL_R100);
 				break;
 			default:
 				if (netif_msg_link(priv))
@@ -1657,6 +1671,7 @@
 		}
 
 		gfar_write(&regs->maccfg2, tempval);
+		gfar_write(&regs->ecntrl, ecntrl);
 
 		if (!priv->oldlink) {
 			new_state = 1;
@@ -1721,6 +1736,9 @@
 		gfar_write(&regs->gaddr6, 0xffffffff);
 		gfar_write(&regs->gaddr7, 0xffffffff);
 	} else {
+		int em_num;
+		int idx;
+
 		/* zero out the hash */
 		gfar_write(&regs->igaddr0, 0x0);
 		gfar_write(&regs->igaddr1, 0x0);
@@ -1739,18 +1757,47 @@
 		gfar_write(&regs->gaddr6, 0x0);
 		gfar_write(&regs->gaddr7, 0x0);
 
+		/* If we have extended hash tables, we need to
+		 * clear the exact match registers to prepare for
+		 * setting them */
+		if (priv->extended_hash) {
+			em_num = GFAR_EM_NUM + 1;
+			gfar_clear_exact_match(dev);
+			idx = 1;
+		} else {
+			idx = 0;
+			em_num = 0;
+		}
+
 		if(dev->mc_count == 0)
 			return;
 
 		/* Parse the list, and set the appropriate bits */
 		for(mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
-			gfar_set_hash_for_addr(dev, mc_ptr->dmi_addr);
+			if (idx < em_num) {
+				gfar_set_mac_for_addr(dev, idx,
+						mc_ptr->dmi_addr);
+				idx++;
+			} else
+				gfar_set_hash_for_addr(dev, mc_ptr->dmi_addr);
 		}
 	}
 
 	return;
 }
 
+
+/* Clears each of the exact match registers to zero, so they
+ * don't interfere with normal reception */
+static void gfar_clear_exact_match(struct net_device *dev)
+{
+	int idx;
+	u8 zero_arr[MAC_ADDR_LEN] = {0,0,0,0,0,0};
+
+	for(idx = 1;idx < GFAR_EM_NUM + 1;idx++)
+		gfar_set_mac_for_addr(dev, idx, (u8 *)zero_arr);
+}
+
 /* Set the appropriate hash bit for the given addr */
 /* The algorithm works like so:
  * 1) Take the Destination Address (ie the multicast address), and
@@ -1781,6 +1828,32 @@
 	return;
 }
 
+
+/* There are multiple MAC Address register pairs on some controllers
+ * This function sets the numth pair to a given address
+ */
+static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	int idx;
+	char tmpbuf[MAC_ADDR_LEN];
+	u32 tempval;
+	u32 *macptr = &priv->regs->macstnaddr1;
+
+	macptr += num*2;
+
+	/* Now copy it into the mac registers backwards, cuz */
+	/* little endian is silly */
+	for (idx = 0; idx < MAC_ADDR_LEN; idx++)
+		tmpbuf[MAC_ADDR_LEN - 1 - idx] = addr[idx];
+
+	gfar_write(macptr, *((u32 *) (tmpbuf)));
+
+	tempval = *((u32 *) (tmpbuf + 4));
+
+	gfar_write(macptr+1, tempval);
+}
+
 /* GFAR error interrupt handler */
 static irqreturn_t gfar_error(int irq, void *dev_id, struct pt_regs *regs)
 {
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 5065ba8..94a91da 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -90,12 +90,26 @@
 #define GFAR_RX_MAX_RING_SIZE   256
 #define GFAR_TX_MAX_RING_SIZE   256
 
+#define GFAR_MAX_FIFO_THRESHOLD 511
+#define GFAR_MAX_FIFO_STARVE	511
+#define GFAR_MAX_FIFO_STARVE_OFF 511
+
 #define DEFAULT_RX_BUFFER_SIZE  1536
 #define TX_RING_MOD_MASK(size) (size-1)
 #define RX_RING_MOD_MASK(size) (size-1)
 #define JUMBO_BUFFER_SIZE 9728
 #define JUMBO_FRAME_SIZE 9600
 
+#define DEFAULT_FIFO_TX_THR 0x100
+#define DEFAULT_FIFO_TX_STARVE 0x40
+#define DEFAULT_FIFO_TX_STARVE_OFF 0x80
+#define DEFAULT_BD_STASH 1
+#define DEFAULT_STASH_LENGTH	64
+#define DEFAULT_STASH_INDEX	0
+
+/* The number of Exact Match registers */
+#define GFAR_EM_NUM	15
+
 /* Latency of interface clock in nanoseconds */
 /* Interface clock latency , in this case, means the
  * time described by a value of 1 in the interrupt
@@ -112,11 +126,11 @@
 
 #define DEFAULT_TX_COALESCE 1
 #define DEFAULT_TXCOUNT	16
-#define DEFAULT_TXTIME	400
+#define DEFAULT_TXTIME	4
 
 #define DEFAULT_RX_COALESCE 1
 #define DEFAULT_RXCOUNT	16
-#define DEFAULT_RXTIME	400
+#define DEFAULT_RXTIME	4
 
 #define TBIPA_VALUE		0x1f
 #define MIIMCFG_INIT_VALUE	0x00000007
@@ -147,6 +161,7 @@
 
 #define ECNTRL_INIT_SETTINGS	0x00001000
 #define ECNTRL_TBI_MODE         0x00000020
+#define ECNTRL_R100		0x00000008
 
 #define MRBLR_INIT_SETTINGS	DEFAULT_RX_BUFFER_SIZE
 
@@ -181,10 +196,12 @@
 #define RCTRL_PRSDEP_MASK	0x000000c0
 #define RCTRL_PRSDEP_INIT	0x000000c0
 #define RCTRL_PROM		0x00000008
+#define RCTRL_EMEN		0x00000002
 #define RCTRL_CHECKSUMMING	(RCTRL_IPCSEN \
 		| RCTRL_TUCSEN | RCTRL_PRSDEP_INIT)
 #define RCTRL_EXTHASH		(RCTRL_GHTX)
 #define RCTRL_VLAN		(RCTRL_PRSDEP_INIT)
+#define RCTRL_PADDING(x)	((x << 16) & RCTRL_PAL_MASK)
 
 
 #define RSTAT_CLEAR_RHALT       0x00800000
@@ -251,28 +268,26 @@
 		IMASK_XFUN | IMASK_RXC | IMASK_BABT | IMASK_DPE \
 		| IMASK_PERR)
 
+/* Fifo management */
+#define FIFO_TX_THR_MASK	0x01ff
+#define FIFO_TX_STARVE_MASK	0x01ff
+#define FIFO_TX_STARVE_OFF_MASK	0x01ff
 
 /* Attribute fields */
 
 /* This enables rx snooping for buffers and descriptors */
-#ifdef CONFIG_GFAR_BDSTASH
 #define ATTR_BDSTASH		0x00000800
-#else
-#define ATTR_BDSTASH		0x00000000
-#endif
 
-#ifdef CONFIG_GFAR_BUFSTASH
 #define ATTR_BUFSTASH		0x00004000
-#define STASH_LENGTH		64
-#else
-#define ATTR_BUFSTASH		0x00000000
-#endif
 
 #define ATTR_SNOOPING		0x000000c0
-#define ATTR_INIT_SETTINGS      (ATTR_SNOOPING \
-		| ATTR_BDSTASH | ATTR_BUFSTASH)
+#define ATTR_INIT_SETTINGS      ATTR_SNOOPING
 
 #define ATTRELI_INIT_SETTINGS   0x0
+#define ATTRELI_EL_MASK		0x3fff0000
+#define ATTRELI_EL(x) (x << 16)
+#define ATTRELI_EI_MASK		0x00003fff
+#define ATTRELI_EI(x) (x)
 
 
 /* TxBD status field bits */
@@ -328,6 +343,7 @@
 #define RXFCB_CTU		0x0400
 #define RXFCB_EIP		0x0200
 #define RXFCB_ETU		0x0100
+#define RXFCB_CSUM_MASK		0x0f00
 #define RXFCB_PERR_MASK		0x000c
 #define RXFCB_PERR_BADL3	0x0008
 
@@ -339,14 +355,7 @@
 };
 
 struct txfcb {
-	u8	vln:1,
-		ip:1,
-		ip6:1,
-		tup:1,
-		udp:1,
-		cip:1,
-		ctu:1,
-		nph:1;
+	u8	flags;
 	u8	reserved;
 	u8	l4os;	/* Level 4 Header Offset */
 	u8	l3os; 	/* Level 3 Header Offset */
@@ -362,14 +371,7 @@
 };
 
 struct rxfcb {
-	u16	vln:1,
-		ip:1,
-		ip6:1,
-		tup:1,
-		cip:1,
-		ctu:1,
-		eip:1,
-		etu:1;
+	u16	flags;
 	u8	rq;	/* Receive Queue index */
 	u8	pro;	/* Layer 4 Protocol */
 	u16	reserved;
@@ -688,12 +690,17 @@
 	spinlock_t lock;
 	unsigned int rx_buffer_size;
 	unsigned int rx_stash_size;
+	unsigned int rx_stash_index;
 	unsigned int tx_ring_size;
 	unsigned int rx_ring_size;
+	unsigned int fifo_threshold;
+	unsigned int fifo_starve;
+	unsigned int fifo_starve_off;
 
 	unsigned char vlan_enable:1,
 		rx_csum_enable:1,
-		extended_hash:1;
+		extended_hash:1,
+		bd_stash_en:1;
 	unsigned short padding;
 	struct vlan_group *vlgrp;
 	/* Info structure initialized by board setup code */
@@ -731,6 +738,6 @@
 extern void gfar_halt(struct net_device *dev);
 extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
 		int enable, u32 regnum, u32 read);
-void gfar_setup_stashing(struct net_device *dev);
+void gfar_init_sysfs(struct net_device *dev);
 
 #endif /* __GIANFAR_H */
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c
index cfa3cd7..765e810 100644
--- a/drivers/net/gianfar_ethtool.c
+++ b/drivers/net/gianfar_ethtool.c
@@ -125,7 +125,7 @@
 static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	
+
 	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
 		memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
 	else
diff --git a/drivers/net/gianfar_mii.h b/drivers/net/gianfar_mii.h
index e85eb21..d527cf2 100644
--- a/drivers/net/gianfar_mii.h
+++ b/drivers/net/gianfar_mii.h
@@ -24,6 +24,7 @@
 #define MII_READ_COMMAND       0x00000001
 
 #define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
+		| SUPPORTED_10baseT_Full \
 		| SUPPORTED_100baseT_Half \
 		| SUPPORTED_100baseT_Full \
 		| SUPPORTED_Autoneg \
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
new file mode 100644
index 0000000..10d34cb
--- /dev/null
+++ b/drivers/net/gianfar_sysfs.c
@@ -0,0 +1,311 @@
+/*
+ * drivers/net/gianfar_sysfs.c
+ *
+ * Gianfar Ethernet Driver
+ * This driver is designed for the non-CPM ethernet controllers
+ * on the 85xx and 83xx family of integrated processors
+ * Based on 8260_io/fcc_enet.c
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala (kumar.gala@freescale.com)
+ *
+ * Copyright (c) 2002-2005 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * Sysfs file creation and management
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+
+#include <asm/uaccess.h>
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include "gianfar.h"
+
+#define GFAR_ATTR(_name) \
+static ssize_t gfar_show_##_name(struct class_device *cdev, char *buf); \
+static ssize_t gfar_set_##_name(struct class_device *cdev, \
+		const char *buf, size_t count); \
+static CLASS_DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
+
+#define GFAR_CREATE_FILE(_dev, _name) \
+	class_device_create_file(&_dev->class_dev, &class_device_attr_##_name)
+
+GFAR_ATTR(bd_stash);
+GFAR_ATTR(rx_stash_size);
+GFAR_ATTR(rx_stash_index);
+GFAR_ATTR(fifo_threshold);
+GFAR_ATTR(fifo_starve);
+GFAR_ATTR(fifo_starve_off);
+
+#define to_net_dev(cd) container_of(cd, struct net_device, class_dev)
+
+static ssize_t gfar_show_bd_stash(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%s\n", priv->bd_stash_en? "on" : "off");
+}
+
+static ssize_t gfar_set_bd_stash(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	int new_setting = 0;
+	u32 temp;
+	unsigned long flags;
+
+	/* Find out the new setting */
+	if (!strncmp("on", buf, count-1) || !strncmp("1", buf, count-1))
+		new_setting = 1;
+	else if (!strncmp("off", buf, count-1) || !strncmp("0", buf, count-1))
+		new_setting = 0;
+	else
+		return count;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* Set the new stashing value */
+	priv->bd_stash_en = new_setting;
+
+	temp = gfar_read(&priv->regs->attr);
+	
+	if (new_setting)
+		temp |= ATTR_BDSTASH;
+	else
+		temp &= ~(ATTR_BDSTASH);
+
+	gfar_write(&priv->regs->attr, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+static ssize_t gfar_show_rx_stash_size(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->rx_stash_size);
+}
+
+static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned int length = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (length > priv->rx_buffer_size)
+		return count;
+
+	if (length == priv->rx_stash_size)
+		return count;
+
+	priv->rx_stash_size = length;
+
+	temp = gfar_read(&priv->regs->attreli);
+	temp &= ~ATTRELI_EL_MASK;
+	temp |= ATTRELI_EL(length);
+	gfar_write(&priv->regs->attreli, temp);
+
+	/* Turn stashing on/off as appropriate */
+	temp = gfar_read(&priv->regs->attr);
+
+	if (length)
+		temp |= ATTR_BUFSTASH;
+	else
+		temp &= ~(ATTR_BUFSTASH);
+
+	gfar_write(&priv->regs->attr, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+
+/* Stashing will only be enabled when rx_stash_size != 0 */
+static ssize_t gfar_show_rx_stash_index(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->rx_stash_index);
+}
+
+static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned short index = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (index > priv->rx_stash_size)
+		return count;
+
+	if (index == priv->rx_stash_index)
+		return count;
+
+	priv->rx_stash_index = index;
+
+	temp = gfar_read(&priv->regs->attreli);
+	temp &= ~ATTRELI_EI_MASK;
+	temp |= ATTRELI_EI(index);
+	gfar_write(&priv->regs->attreli, flags);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+static ssize_t gfar_show_fifo_threshold(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->fifo_threshold);
+}
+
+static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned int length = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	if (length > GFAR_MAX_FIFO_THRESHOLD)
+		return count;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->fifo_threshold = length;
+
+	temp = gfar_read(&priv->regs->fifo_tx_thr);
+	temp &= ~FIFO_TX_THR_MASK;
+	temp |= length;
+	gfar_write(&priv->regs->fifo_tx_thr, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+static ssize_t gfar_show_fifo_starve(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->fifo_starve);
+}
+
+
+static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned int num = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	if (num > GFAR_MAX_FIFO_STARVE)
+		return count;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->fifo_starve = num;
+
+	temp = gfar_read(&priv->regs->fifo_tx_starve);
+	temp &= ~FIFO_TX_STARVE_MASK;
+	temp |= num;
+	gfar_write(&priv->regs->fifo_tx_starve, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+static ssize_t gfar_show_fifo_starve_off(struct class_device *cdev, char *buf)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+
+	return sprintf(buf, "%d\n", priv->fifo_starve_off);
+}
+
+static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
+		const char *buf, size_t count)
+{
+	struct net_device *dev = to_net_dev(cdev);
+	struct gfar_private *priv = netdev_priv(dev);
+	unsigned int num = simple_strtoul(buf, NULL, 0);
+	u32 temp;
+	unsigned long flags;
+
+	if (num > GFAR_MAX_FIFO_STARVE_OFF)
+		return count;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	priv->fifo_starve_off = num;
+
+	temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
+	temp &= ~FIFO_TX_STARVE_OFF_MASK;
+	temp |= num;
+	gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return count;
+}
+
+void gfar_init_sysfs(struct net_device *dev)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+
+	/* Initialize the default values */
+	priv->rx_stash_size = DEFAULT_STASH_LENGTH;
+	priv->rx_stash_index = DEFAULT_STASH_INDEX;
+	priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
+	priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
+	priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
+	priv->bd_stash_en = DEFAULT_BD_STASH;
+
+	/* Create our sysfs files */
+	GFAR_CREATE_FILE(dev, bd_stash);
+	GFAR_CREATE_FILE(dev, rx_stash_size);
+	GFAR_CREATE_FILE(dev, rx_stash_index);
+	GFAR_CREATE_FILE(dev, fifo_threshold);
+	GFAR_CREATE_FILE(dev, fifo_starve);
+	GFAR_CREATE_FILE(dev, fifo_starve_off);
+
+}
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 3e9accf..41b3d83 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -524,6 +524,7 @@
 	ax->dev->trans_start = jiffies;
 	ax->xleft = count - actual;
 	ax->xhead = ax->xbuff + actual;
+	spin_unlock_bh(&ax->buflock);
 }
 
 /* Encapsulate an AX.25 packet and kick it into a TTY queue. */
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
index eb7d694..1da8a66 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ b/drivers/net/ibm_emac/ibm_emac_core.c
@@ -65,7 +65,7 @@
  */
 
 #define DRV_NAME        "emac"
-#define DRV_VERSION     "3.53"
+#define DRV_VERSION     "3.54"
 #define DRV_DESC        "PPC 4xx OCP EMAC driver"
 
 MODULE_DESCRIPTION(DRV_DESC);
@@ -158,6 +158,14 @@
 #define PHY_POLL_LINK_ON	HZ
 #define PHY_POLL_LINK_OFF	(HZ / 5)
 
+/* Graceful stop timeouts in us. 
+ * We should allow up to 1 frame time (full-duplex, ignoring collisions) 
+ */
+#define STOP_TIMEOUT_10		1230	
+#define STOP_TIMEOUT_100	124
+#define STOP_TIMEOUT_1000	13
+#define STOP_TIMEOUT_1000_JUMBO	73
+
 /* Please, keep in sync with struct ibm_emac_stats/ibm_emac_error_stats */
 static const char emac_stats_keys[EMAC_ETHTOOL_STATS_COUNT][ETH_GSTRING_LEN] = {
 	"rx_packets", "rx_bytes", "tx_packets", "tx_bytes", "rx_packets_csum",
@@ -222,10 +230,12 @@
 
 	r = in_be32(&p->mr0);
 	if (r & EMAC_MR0_TXE) {
-		int n = 300;
+		int n = dev->stop_timeout;
 		out_be32(&p->mr0, r & ~EMAC_MR0_TXE);
-		while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n)
+		while (!(in_be32(&p->mr0) & EMAC_MR0_TXI) && n) {
+			udelay(1);
 			--n;
+		}	
 		if (unlikely(!n))
 			emac_report_timeout_error(dev, "TX disable timeout");
 	}
@@ -248,9 +258,11 @@
 	if (!(r & EMAC_MR0_RXE)) {
 		if (unlikely(!(r & EMAC_MR0_RXI))) {
 			/* Wait if previous async disable is still in progress */
-			int n = 100;
-			while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+			int n = dev->stop_timeout;
+			while (!(r = in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {
+				udelay(1);
 				--n;
+			}	
 			if (unlikely(!n))
 				emac_report_timeout_error(dev,
 							  "RX disable timeout");
@@ -273,10 +285,12 @@
 
 	r = in_be32(&p->mr0);
 	if (r & EMAC_MR0_RXE) {
-		int n = 300;
+		int n = dev->stop_timeout;
 		out_be32(&p->mr0, r & ~EMAC_MR0_RXE);
-		while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n)
+		while (!(in_be32(&p->mr0) & EMAC_MR0_RXI) && n) {
+			udelay(1);
 			--n;
+		}	
 		if (unlikely(!n))
 			emac_report_timeout_error(dev, "RX disable timeout");
 	}
@@ -395,6 +409,7 @@
 	r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;
 	if (dev->phy.duplex == DUPLEX_FULL)
 		r |= EMAC_MR1_FDE;
+	dev->stop_timeout = STOP_TIMEOUT_10;
 	switch (dev->phy.speed) {
 	case SPEED_1000:
 		if (emac_phy_gpcs(dev->phy.mode)) {
@@ -409,12 +424,16 @@
 			r |= EMAC_MR1_MF_1000;
 		r |= EMAC_MR1_RFS_16K;
 		gige = 1;
-		
-		if (dev->ndev->mtu > ETH_DATA_LEN)
+
+		if (dev->ndev->mtu > ETH_DATA_LEN) {
 			r |= EMAC_MR1_JPSM;
+			dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO;
+		} else
+			dev->stop_timeout = STOP_TIMEOUT_1000;
 		break;
 	case SPEED_100:
 		r |= EMAC_MR1_MF_100;
+		dev->stop_timeout = STOP_TIMEOUT_100;
 		/* Fall through */
 	default:
 		r |= EMAC_MR1_RFS_4K;
@@ -2048,6 +2067,7 @@
 	dev->phy.duplex = DUPLEX_FULL;
 	dev->phy.autoneg = AUTONEG_DISABLE;
 	dev->phy.pause = dev->phy.asym_pause = 0;
+	dev->stop_timeout = STOP_TIMEOUT_100;
 	init_timer(&dev->link_timer);
 	dev->link_timer.function = emac_link_timer;
 	dev->link_timer.data = (unsigned long)dev;
diff --git a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h
index e9b44d0..911abba 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.h
+++ b/drivers/net/ibm_emac/ibm_emac_core.h
@@ -189,6 +189,8 @@
 	struct timer_list		link_timer;
 	int				reset_failed;
 
+	int				stop_timeout;	/* in us */
+
 	struct ibm_emac_error_stats	estats;
 	struct net_device_stats		nstats;
 
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index c22c051..fa176ff 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1539,7 +1539,6 @@
  * USB device callbacks
  */
 static struct usb_driver irda_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "irda-usb",
 	.probe		= irda_usb_probe,
 	.disconnect	= irda_usb_disconnect,
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 3961a75..31867e4 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -1152,7 +1152,6 @@
  * USB device callbacks
  */
 static struct usb_driver irda_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "stir4200",
 	.probe		= stir_probe,
 	.disconnect	= stir_disconnect,
diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h
index 741aecc..a82a4ba 100644
--- a/drivers/net/irda/vlsi_ir.h
+++ b/drivers/net/irda/vlsi_ir.h
@@ -577,8 +577,8 @@
 		struct {
 			u8		addr_res[3];
 			volatile u8	status;		/* descriptor status */
-		} rd_s __attribute__((packed));
-	} rd_u __attribute((packed));
+		} __attribute__((packed)) rd_s;
+	} __attribute((packed)) rd_u;
 } __attribute__ ((packed));
 
 #define rd_addr		rd_u.addr
diff --git a/drivers/net/ixp2000/Kconfig b/drivers/net/ixp2000/Kconfig
new file mode 100644
index 0000000..2fec241
--- /dev/null
+++ b/drivers/net/ixp2000/Kconfig
@@ -0,0 +1,6 @@
+config ENP2611_MSF_NET
+	tristate "Radisys ENP2611 MSF network interface support"
+	depends on ARCH_ENP2611
+	help
+	  This is a driver for the MSF network interface unit in
+	  the IXP2400 on the Radisys ENP2611 platform.
diff --git a/drivers/net/ixp2000/Makefile b/drivers/net/ixp2000/Makefile
new file mode 100644
index 0000000..fd38351
--- /dev/null
+++ b/drivers/net/ixp2000/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_ENP2611_MSF_NET) += enp2611_mod.o
+
+enp2611_mod-objs := caleb.o enp2611.o ixp2400-msf.o ixpdev.o pm3386.o
diff --git a/drivers/net/ixp2000/caleb.c b/drivers/net/ixp2000/caleb.c
new file mode 100644
index 0000000..3595e10
--- /dev/null
+++ b/drivers/net/ixp2000/caleb.c
@@ -0,0 +1,137 @@
+/*
+ * Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include "caleb.h"
+
+#define CALEB_IDLO		0x00
+#define CALEB_IDHI		0x01
+#define CALEB_RID		0x02
+#define CALEB_RESET		0x03
+#define CALEB_INTREN0		0x04
+#define CALEB_INTREN1		0x05
+#define CALEB_INTRSTAT0		0x06
+#define CALEB_INTRSTAT1		0x07
+#define CALEB_PORTEN		0x08
+#define CALEB_BURST		0x09
+#define CALEB_PORTPAUS		0x0A
+#define CALEB_PORTPAUSD		0x0B
+#define CALEB_PHY0RX		0x10
+#define CALEB_PHY1RX		0x11
+#define CALEB_PHY0TX		0x12
+#define CALEB_PHY1TX		0x13
+#define CALEB_IXPRX_HI_CNTR	0x15
+#define CALEB_PHY0RX_HI_CNTR	0x16
+#define CALEB_PHY1RX_HI_CNTR	0x17
+#define CALEB_IXPRX_CNTR	0x18
+#define CALEB_PHY0RX_CNTR	0x19
+#define CALEB_PHY1RX_CNTR	0x1A
+#define CALEB_IXPTX_CNTR	0x1B
+#define CALEB_PHY0TX_CNTR	0x1C
+#define CALEB_PHY1TX_CNTR	0x1D
+#define CALEB_DEBUG0		0x1E
+#define CALEB_DEBUG1		0x1F
+
+
+static u8 caleb_reg_read(int reg)
+{
+	u8 value;
+
+	value = *((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg));
+
+//	printk(KERN_INFO "caleb_reg_read(%d) = %.2x\n", reg, value);
+
+	return value;
+}
+
+static void caleb_reg_write(int reg, u8 value)
+{
+	u8 dummy;
+
+//	printk(KERN_INFO "caleb_reg_write(%d, %.2x)\n", reg, value);
+
+	*((volatile u8 *)(ENP2611_CALEB_VIRT_BASE + reg)) = value;
+
+	dummy = *((volatile u8 *)ENP2611_CALEB_VIRT_BASE);
+	__asm__ __volatile__("mov %0, %0" : "+r" (dummy));
+}
+
+
+void caleb_reset(void)
+{
+	/*
+	 * Perform a chip reset.
+	 */
+	caleb_reg_write(CALEB_RESET, 0x02);
+	udelay(1);
+
+	/*
+	 * Enable all interrupt sources.  This is needed to get
+	 * meaningful results out of the status bits (register 6
+	 * and 7.)
+	 */
+	caleb_reg_write(CALEB_INTREN0, 0xff);
+	caleb_reg_write(CALEB_INTREN1, 0x07);
+
+	/*
+	 * Set RX and TX FIFO thresholds to 1.5kb.
+	 */
+	caleb_reg_write(CALEB_PHY0RX, 0x11);
+	caleb_reg_write(CALEB_PHY1RX, 0x11);
+	caleb_reg_write(CALEB_PHY0TX, 0x11);
+	caleb_reg_write(CALEB_PHY1TX, 0x11);
+
+	/*
+	 * Program SPI-3 burst size.
+	 */
+	caleb_reg_write(CALEB_BURST, 0);	// 64-byte RBUF mpackets
+//	caleb_reg_write(CALEB_BURST, 1);	// 128-byte RBUF mpackets
+//	caleb_reg_write(CALEB_BURST, 2);	// 256-byte RBUF mpackets
+}
+
+void caleb_enable_rx(int port)
+{
+	u8 temp;
+
+	temp = caleb_reg_read(CALEB_PORTEN);
+	temp |= 1 << port;
+	caleb_reg_write(CALEB_PORTEN, temp);
+}
+
+void caleb_disable_rx(int port)
+{
+	u8 temp;
+
+	temp = caleb_reg_read(CALEB_PORTEN);
+	temp &= ~(1 << port);
+	caleb_reg_write(CALEB_PORTEN, temp);
+}
+
+void caleb_enable_tx(int port)
+{
+	u8 temp;
+
+	temp = caleb_reg_read(CALEB_PORTEN);
+	temp |= 1 << (port + 4);
+	caleb_reg_write(CALEB_PORTEN, temp);
+}
+
+void caleb_disable_tx(int port)
+{
+	u8 temp;
+
+	temp = caleb_reg_read(CALEB_PORTEN);
+	temp &= ~(1 << (port + 4));
+	caleb_reg_write(CALEB_PORTEN, temp);
+}
diff --git a/drivers/net/ixp2000/caleb.h b/drivers/net/ixp2000/caleb.h
new file mode 100644
index 0000000..e93a1ef
--- /dev/null
+++ b/drivers/net/ixp2000/caleb.h
@@ -0,0 +1,22 @@
+/*
+ * Helper functions for the SPI-3 bridge FPGA on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __CALEB_H
+#define __CALEB_H
+
+void caleb_reset(void);
+void caleb_enable_rx(int port);
+void caleb_disable_rx(int port);
+void caleb_enable_tx(int port);
+void caleb_disable_tx(int port);
+
+
+#endif
diff --git a/drivers/net/ixp2000/enp2611.c b/drivers/net/ixp2000/enp2611.c
new file mode 100644
index 0000000..d82651a
--- /dev/null
+++ b/drivers/net/ixp2000/enp2611.c
@@ -0,0 +1,245 @@
+/*
+ * IXP2400 MSF network device driver for the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <asm/arch/uengine.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include "ixpdev.h"
+#include "caleb.h"
+#include "ixp2400-msf.h"
+#include "pm3386.h"
+
+/***********************************************************************
+ * The Radisys ENP2611 is a PCI form factor board with three SFP GBIC
+ * slots, connected via two PMC/Sierra 3386s and an SPI-3 bridge FPGA
+ * to the IXP2400.
+ *
+ *                +-------------+
+ * SFP GBIC #0 ---+             |       +---------+
+ *                |  PM3386 #0  +-------+         |
+ * SFP GBIC #1 ---+             |       | "Caleb" |         +---------+
+ *                +-------------+       |         |         |         |
+ *                                      | SPI-3   +---------+ IXP2400 |
+ *                +-------------+       | bridge  |         |         |
+ * SFP GBIC #2 ---+             |       | FPGA    |         +---------+
+ *                |  PM3386 #1  +-------+         |
+ *                |             |       +---------+
+ *                +-------------+
+ *              ^                   ^                  ^
+ *              | 1.25Gbaud         | 104MHz           | 104MHz
+ *              | SERDES ea.        | SPI-3 ea.        | SPI-3
+ *
+ ***********************************************************************/
+static struct ixp2400_msf_parameters enp2611_msf_parameters =
+{
+	.rx_mode =		IXP2400_RX_MODE_UTOPIA_POS |
+				IXP2400_RX_MODE_1x32 |
+				IXP2400_RX_MODE_MPHY |
+				IXP2400_RX_MODE_MPHY_32 |
+				IXP2400_RX_MODE_MPHY_POLLED_STATUS |
+				IXP2400_RX_MODE_MPHY_LEVEL3 |
+				IXP2400_RX_MODE_RBUF_SIZE_64,
+
+	.rxclk01_multiplier =	IXP2400_PLL_MULTIPLIER_16,
+
+	.rx_poll_ports =	3,
+
+	.rx_channel_mode = {
+		IXP2400_PORT_RX_MODE_MASTER |
+		IXP2400_PORT_RX_MODE_POS_PHY |
+		IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+		IXP2400_PORT_RX_MODE_ODD_PARITY |
+		IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_RX_MODE_MASTER |
+		IXP2400_PORT_RX_MODE_POS_PHY |
+		IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+		IXP2400_PORT_RX_MODE_ODD_PARITY |
+		IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_RX_MODE_MASTER |
+		IXP2400_PORT_RX_MODE_POS_PHY |
+		IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+		IXP2400_PORT_RX_MODE_ODD_PARITY |
+		IXP2400_PORT_RX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_RX_MODE_MASTER |
+		IXP2400_PORT_RX_MODE_POS_PHY |
+		IXP2400_PORT_RX_MODE_POS_PHY_L3 |
+		IXP2400_PORT_RX_MODE_ODD_PARITY |
+		IXP2400_PORT_RX_MODE_2_CYCLE_DECODE
+	},
+
+	.tx_mode =		IXP2400_TX_MODE_UTOPIA_POS |
+				IXP2400_TX_MODE_1x32 |
+				IXP2400_TX_MODE_MPHY |
+				IXP2400_TX_MODE_MPHY_32 |
+				IXP2400_TX_MODE_MPHY_POLLED_STATUS |
+				IXP2400_TX_MODE_MPHY_LEVEL3 |
+				IXP2400_TX_MODE_TBUF_SIZE_64,
+
+	.txclk01_multiplier =	IXP2400_PLL_MULTIPLIER_16,
+
+	.tx_poll_ports =	3,
+
+	.tx_channel_mode = {
+		IXP2400_PORT_TX_MODE_MASTER |
+		IXP2400_PORT_TX_MODE_POS_PHY |
+		IXP2400_PORT_TX_MODE_ODD_PARITY |
+		IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_TX_MODE_MASTER |
+		IXP2400_PORT_TX_MODE_POS_PHY |
+		IXP2400_PORT_TX_MODE_ODD_PARITY |
+		IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_TX_MODE_MASTER |
+		IXP2400_PORT_TX_MODE_POS_PHY |
+		IXP2400_PORT_TX_MODE_ODD_PARITY |
+		IXP2400_PORT_TX_MODE_2_CYCLE_DECODE,
+
+		IXP2400_PORT_TX_MODE_MASTER |
+		IXP2400_PORT_TX_MODE_POS_PHY |
+		IXP2400_PORT_TX_MODE_ODD_PARITY |
+		IXP2400_PORT_TX_MODE_2_CYCLE_DECODE
+	}
+};
+
+struct enp2611_ixpdev_priv
+{
+	struct ixpdev_priv		ixpdev_priv;
+	struct net_device_stats		stats;
+};
+
+static struct net_device *nds[3];
+static struct timer_list link_check_timer;
+
+static struct net_device_stats *enp2611_get_stats(struct net_device *dev)
+{
+	struct enp2611_ixpdev_priv *ip = netdev_priv(dev);
+
+	pm3386_get_stats(ip->ixpdev_priv.channel, &(ip->stats));
+
+	return &(ip->stats);
+}
+
+/* @@@ Poll the SFP moddef0 line too.  */
+/* @@@ Try to use the pm3386 DOOL interrupt as well.  */
+static void enp2611_check_link_status(unsigned long __dummy)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		struct net_device *dev;
+		int status;
+
+		dev = nds[i];
+
+		status = pm3386_is_link_up(i);
+		if (status && !netif_carrier_ok(dev)) {
+			/* @@@ Should report autonegotiation status.  */
+			printk(KERN_INFO "%s: NIC Link is Up\n", dev->name);
+
+			pm3386_enable_tx(i);
+			caleb_enable_tx(i);
+			netif_carrier_on(dev);
+		} else if (!status && netif_carrier_ok(dev)) {
+			printk(KERN_INFO "%s: NIC Link is Down\n", dev->name);
+
+			netif_carrier_off(dev);
+			caleb_disable_tx(i);
+			pm3386_disable_tx(i);
+		}
+	}
+
+	link_check_timer.expires = jiffies + HZ / 10;
+	add_timer(&link_check_timer);
+}
+
+static void enp2611_set_port_admin_status(int port, int up)
+{
+	if (up) {
+		caleb_enable_rx(port);
+
+		pm3386_set_carrier(port, 1);
+		pm3386_enable_rx(port);
+	} else {
+		caleb_disable_tx(port);
+		pm3386_disable_tx(port);
+		/* @@@ Flush out pending packets.  */
+		pm3386_set_carrier(port, 0);
+
+		pm3386_disable_rx(port);
+		caleb_disable_rx(port);
+	}
+}
+
+static int __init enp2611_init_module(void)
+{ 
+	int i;
+
+	if (!machine_is_enp2611())
+		return -ENODEV;
+
+	caleb_reset();
+	pm3386_reset();
+
+	for (i = 0; i < 3; i++) {
+		nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv));
+		if (nds[i] == NULL) {
+			while (--i >= 0)
+				free_netdev(nds[i]);
+			return -ENOMEM;
+		}
+
+		SET_MODULE_OWNER(nds[i]);
+		nds[i]->get_stats = enp2611_get_stats;
+		pm3386_init_port(i);
+		pm3386_get_mac(i, nds[i]->dev_addr);
+	}
+
+	ixp2400_msf_init(&enp2611_msf_parameters);
+
+	if (ixpdev_init(3, nds, enp2611_set_port_admin_status)) {
+		for (i = 0; i < 3; i++)
+			free_netdev(nds[i]);
+		return -EINVAL;
+	}
+
+	init_timer(&link_check_timer);
+	link_check_timer.function = enp2611_check_link_status;
+	link_check_timer.expires = jiffies;
+	add_timer(&link_check_timer);
+
+	return 0;
+}
+
+static void __exit enp2611_cleanup_module(void)
+{
+	int i;
+
+	del_timer_sync(&link_check_timer);
+
+	ixpdev_deinit();
+	for (i = 0; i < 3; i++)
+		free_netdev(nds[i]);
+}
+
+module_init(enp2611_init_module);
+module_exit(enp2611_cleanup_module);
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ixp2000/ixp2400-msf.c b/drivers/net/ixp2000/ixp2400-msf.c
new file mode 100644
index 0000000..48a3a89
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400-msf.c
@@ -0,0 +1,213 @@
+/*
+ * Generic library functions for the MSF (Media and Switch Fabric) unit
+ * found on the Intel IXP2400 network processor.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/hardware.h>
+#include <asm/arch/ixp2000-regs.h>
+#include <asm/delay.h>
+#include <asm/io.h>
+#include "ixp2400-msf.h"
+
+/*
+ * This is the Intel recommended PLL init procedure as described on
+ * page 340 of the IXP2400/IXP2800 Programmer's Reference Manual.
+ */
+static void ixp2400_pll_init(struct ixp2400_msf_parameters *mp)
+{
+	int rx_dual_clock;
+	int tx_dual_clock;
+	u32 value;
+
+	/*
+	 * If the RX mode is not 1x32, we have to enable both RX PLLs
+	 * (#0 and #1.)  The same thing for the TX direction.
+	 */
+	rx_dual_clock = !!(mp->rx_mode & IXP2400_RX_MODE_WIDTH_MASK);
+	tx_dual_clock = !!(mp->tx_mode & IXP2400_TX_MODE_WIDTH_MASK);
+
+	/*
+	 * Read initial value.
+	 */
+	value = ixp2000_reg_read(IXP2000_MSF_CLK_CNTRL);
+
+	/*
+	 * Put PLLs in powerdown and bypass mode.
+	 */
+	value |= 0x0000f0f0;
+	ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+	/*
+	 * Set single or dual clock mode bits.
+	 */
+	value &= ~0x03000000;
+	value |= (rx_dual_clock << 24) | (tx_dual_clock << 25);
+
+	/*
+	 * Set multipliers.
+	 */
+	value &= ~0x00ff0000;
+	value |= mp->rxclk01_multiplier << 16;
+	value |= mp->rxclk23_multiplier << 18;
+	value |= mp->txclk01_multiplier << 20;
+	value |= mp->txclk23_multiplier << 22;
+
+	/*
+	 * And write value.
+	 */
+	ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+	/*
+	 * Disable PLL bypass mode.
+	 */
+	value &= ~(0x00005000 | rx_dual_clock << 13 | tx_dual_clock << 15);
+	ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+	/*
+	 * Turn on PLLs.
+	 */
+	value &= ~(0x00000050 | rx_dual_clock << 5 | tx_dual_clock << 7);
+	ixp2000_reg_write(IXP2000_MSF_CLK_CNTRL, value);
+
+	/*
+	 * Wait for PLLs to lock.  There are lock status bits, but IXP2400
+	 * erratum #65 says that these lock bits should not be relied upon
+	 * as they might not accurately reflect the true state of the PLLs.
+	 */
+	udelay(100);
+}
+
+/*
+ * Needed according to p480 of Programmer's Reference Manual.
+ */
+static void ixp2400_msf_free_rbuf_entries(struct ixp2400_msf_parameters *mp)
+{
+	int size_bits;
+	int i;
+
+	/*
+	 * Work around IXP2400 erratum #69 (silent RBUF-to-DRAM transfer
+	 * corruption) in the Intel-recommended way: do not add the RBUF
+	 * elements susceptible to corruption to the freelist.
+	 */
+	size_bits = mp->rx_mode & IXP2400_RX_MODE_RBUF_SIZE_MASK;
+	if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_64) {
+		for (i = 1; i < 128; i++) {
+			if (i == 9 || i == 18 || i == 27)
+				continue;
+			ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
+		}
+	} else if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_128) {
+		for (i = 1; i < 64; i++) {
+			if (i == 4 || i == 9 || i == 13)
+				continue;
+			ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
+		}
+	} else if (size_bits == IXP2400_RX_MODE_RBUF_SIZE_256) {
+		for (i = 1; i < 32; i++) {
+			if (i == 2 || i == 4 || i == 6)
+				continue;
+			ixp2000_reg_write(IXP2000_MSF_RBUF_ELEMENT_DONE, i);
+		}
+	}
+}
+
+static u32 ixp2400_msf_valid_channels(u32 reg)
+{
+	u32 channels;
+
+	channels = 0;
+	switch (reg & IXP2400_RX_MODE_WIDTH_MASK) {
+	case IXP2400_RX_MODE_1x32:
+		channels = 0x1;
+		if (reg & IXP2400_RX_MODE_MPHY &&
+		    !(reg & IXP2400_RX_MODE_MPHY_32))
+			channels = 0xf;
+		break;
+
+	case IXP2400_RX_MODE_2x16:
+		channels = 0x5;
+		break;
+
+	case IXP2400_RX_MODE_4x8:
+		channels = 0xf;
+		break;
+
+	case IXP2400_RX_MODE_1x16_2x8:
+		channels = 0xd;
+		break;
+	}
+
+	return channels;
+}
+
+static void ixp2400_msf_enable_rx(struct ixp2400_msf_parameters *mp)
+{
+	u32 value;
+
+	value = ixp2000_reg_read(IXP2000_MSF_RX_CONTROL) & 0x0fffffff;
+	value |= ixp2400_msf_valid_channels(mp->rx_mode) << 28;
+	ixp2000_reg_write(IXP2000_MSF_RX_CONTROL, value);
+}
+
+static void ixp2400_msf_enable_tx(struct ixp2400_msf_parameters *mp)
+{
+	u32 value;
+
+	value = ixp2000_reg_read(IXP2000_MSF_TX_CONTROL) & 0x0fffffff;
+	value |= ixp2400_msf_valid_channels(mp->tx_mode) << 28;
+	ixp2000_reg_write(IXP2000_MSF_TX_CONTROL, value);
+}
+
+
+void ixp2400_msf_init(struct ixp2400_msf_parameters *mp)
+{
+	u32 value;
+	int i;
+
+	/*
+	 * Init the RX/TX PLLs based on the passed parameter block.
+	 */
+	ixp2400_pll_init(mp);
+
+	/*
+	 * Reset MSF.  Bit 7 in IXP_RESET_0 resets the MSF.
+	 */
+	value = ixp2000_reg_read(IXP2000_RESET0);
+	ixp2000_reg_write(IXP2000_RESET0, value | 0x80);
+	ixp2000_reg_write(IXP2000_RESET0, value & ~0x80);
+
+	/*
+	 * Initialise the RX section.
+	 */
+	ixp2000_reg_write(IXP2000_MSF_RX_MPHY_POLL_LIMIT, mp->rx_poll_ports - 1);
+	ixp2000_reg_write(IXP2000_MSF_RX_CONTROL, mp->rx_mode);
+	for (i = 0; i < 4; i++) {
+		ixp2000_reg_write(IXP2000_MSF_RX_UP_CONTROL_0 + i,
+						mp->rx_channel_mode[i]);
+	}
+	ixp2400_msf_free_rbuf_entries(mp);
+	ixp2400_msf_enable_rx(mp);
+
+	/*
+	 * Initialise the TX section.
+	 */
+	ixp2000_reg_write(IXP2000_MSF_TX_MPHY_POLL_LIMIT, mp->tx_poll_ports - 1);
+	ixp2000_reg_write(IXP2000_MSF_TX_CONTROL, mp->tx_mode);
+	for (i = 0; i < 4; i++) {
+		ixp2000_reg_write(IXP2000_MSF_TX_UP_CONTROL_0 + i,
+						mp->tx_channel_mode[i]);
+	}
+	ixp2400_msf_enable_tx(mp);
+}
diff --git a/drivers/net/ixp2000/ixp2400-msf.h b/drivers/net/ixp2000/ixp2400-msf.h
new file mode 100644
index 0000000..3ac1af2
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400-msf.h
@@ -0,0 +1,115 @@
+/*
+ * Generic library functions for the MSF (Media and Switch Fabric) unit
+ * found on the Intel IXP2400 network processor.
+ *
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the
+ * License, or (at your option) any later version.
+ */
+
+#ifndef __IXP2400_MSF_H
+#define __IXP2400_MSF_H
+
+struct ixp2400_msf_parameters
+{
+	u32				rx_mode;
+	unsigned			rxclk01_multiplier:2;
+	unsigned			rxclk23_multiplier:2;
+	unsigned			rx_poll_ports:6;
+	u32				rx_channel_mode[4];
+
+	u32				tx_mode;
+	unsigned			txclk01_multiplier:2;
+	unsigned			txclk23_multiplier:2;
+	unsigned			tx_poll_ports:6;
+	u32				tx_channel_mode[4];
+};
+
+void ixp2400_msf_init(struct ixp2400_msf_parameters *mp);
+
+#define IXP2400_PLL_MULTIPLIER_48		0x00
+#define IXP2400_PLL_MULTIPLIER_24		0x01
+#define IXP2400_PLL_MULTIPLIER_16		0x02
+#define IXP2400_PLL_MULTIPLIER_12		0x03
+
+#define IXP2400_RX_MODE_CSIX			0x00400000
+#define IXP2400_RX_MODE_UTOPIA_POS		0x00000000
+#define IXP2400_RX_MODE_WIDTH_MASK		0x00300000
+#define IXP2400_RX_MODE_1x16_2x8		0x00300000
+#define IXP2400_RX_MODE_4x8			0x00200000
+#define IXP2400_RX_MODE_2x16			0x00100000
+#define IXP2400_RX_MODE_1x32			0x00000000
+#define IXP2400_RX_MODE_MPHY			0x00080000
+#define IXP2400_RX_MODE_SPHY			0x00000000
+#define IXP2400_RX_MODE_MPHY_32			0x00040000
+#define IXP2400_RX_MODE_MPHY_4			0x00000000
+#define IXP2400_RX_MODE_MPHY_POLLED_STATUS	0x00020000
+#define IXP2400_RX_MODE_MPHY_DIRECT_STATUS	0x00000000
+#define IXP2400_RX_MODE_CBUS_FULL_DUPLEX	0x00010000
+#define IXP2400_RX_MODE_CBUS_SIMPLEX		0x00000000
+#define IXP2400_RX_MODE_MPHY_LEVEL2		0x00004000
+#define IXP2400_RX_MODE_MPHY_LEVEL3		0x00000000
+#define IXP2400_RX_MODE_CBUS_8BIT		0x00002000
+#define IXP2400_RX_MODE_CBUS_4BIT		0x00000000
+#define IXP2400_RX_MODE_CSIX_SINGLE_FREELIST	0x00000200
+#define IXP2400_RX_MODE_CSIX_SPLIT_FREELISTS	0x00000000
+#define IXP2400_RX_MODE_RBUF_SIZE_MASK		0x0000000c
+#define IXP2400_RX_MODE_RBUF_SIZE_256		0x00000008
+#define IXP2400_RX_MODE_RBUF_SIZE_128		0x00000004
+#define IXP2400_RX_MODE_RBUF_SIZE_64		0x00000000
+
+#define IXP2400_PORT_RX_MODE_SLAVE		0x00000040
+#define IXP2400_PORT_RX_MODE_MASTER		0x00000000
+#define IXP2400_PORT_RX_MODE_POS_PHY_L3		0x00000020
+#define IXP2400_PORT_RX_MODE_POS_PHY_L2		0x00000000
+#define IXP2400_PORT_RX_MODE_POS_PHY		0x00000010
+#define IXP2400_PORT_RX_MODE_UTOPIA		0x00000000
+#define IXP2400_PORT_RX_MODE_EVEN_PARITY	0x0000000c
+#define IXP2400_PORT_RX_MODE_ODD_PARITY		0x00000008
+#define IXP2400_PORT_RX_MODE_NO_PARITY		0x00000000
+#define IXP2400_PORT_RX_MODE_UTOPIA_BIG_CELLS	0x00000002
+#define IXP2400_PORT_RX_MODE_UTOPIA_NORMAL_CELLS	0x00000000
+#define IXP2400_PORT_RX_MODE_2_CYCLE_DECODE	0x00000001
+#define IXP2400_PORT_RX_MODE_1_CYCLE_DECODE	0x00000000
+
+#define IXP2400_TX_MODE_CSIX			0x00400000
+#define IXP2400_TX_MODE_UTOPIA_POS		0x00000000
+#define IXP2400_TX_MODE_WIDTH_MASK		0x00300000
+#define IXP2400_TX_MODE_1x16_2x8		0x00300000
+#define IXP2400_TX_MODE_4x8			0x00200000
+#define IXP2400_TX_MODE_2x16			0x00100000
+#define IXP2400_TX_MODE_1x32			0x00000000
+#define IXP2400_TX_MODE_MPHY			0x00080000
+#define IXP2400_TX_MODE_SPHY			0x00000000
+#define IXP2400_TX_MODE_MPHY_32			0x00040000
+#define IXP2400_TX_MODE_MPHY_4			0x00000000
+#define IXP2400_TX_MODE_MPHY_POLLED_STATUS	0x00020000
+#define IXP2400_TX_MODE_MPHY_DIRECT_STATUS	0x00000000
+#define IXP2400_TX_MODE_CBUS_FULL_DUPLEX	0x00010000
+#define IXP2400_TX_MODE_CBUS_SIMPLEX		0x00000000
+#define IXP2400_TX_MODE_MPHY_LEVEL2		0x00004000
+#define IXP2400_TX_MODE_MPHY_LEVEL3		0x00000000
+#define IXP2400_TX_MODE_CBUS_8BIT		0x00002000
+#define IXP2400_TX_MODE_CBUS_4BIT		0x00000000
+#define IXP2400_TX_MODE_TBUF_SIZE_MASK		0x0000000c
+#define IXP2400_TX_MODE_TBUF_SIZE_256		0x00000008
+#define IXP2400_TX_MODE_TBUF_SIZE_128		0x00000004
+#define IXP2400_TX_MODE_TBUF_SIZE_64		0x00000000
+
+#define IXP2400_PORT_TX_MODE_SLAVE		0x00000040
+#define IXP2400_PORT_TX_MODE_MASTER		0x00000000
+#define IXP2400_PORT_TX_MODE_POS_PHY		0x00000010
+#define IXP2400_PORT_TX_MODE_UTOPIA		0x00000000
+#define IXP2400_PORT_TX_MODE_EVEN_PARITY	0x0000000c
+#define IXP2400_PORT_TX_MODE_ODD_PARITY		0x00000008
+#define IXP2400_PORT_TX_MODE_NO_PARITY		0x00000000
+#define IXP2400_PORT_TX_MODE_UTOPIA_BIG_CELLS	0x00000002
+#define IXP2400_PORT_TX_MODE_2_CYCLE_DECODE	0x00000001
+#define IXP2400_PORT_TX_MODE_1_CYCLE_DECODE	0x00000000
+
+
+#endif
diff --git a/drivers/net/ixp2000/ixp2400_rx.uc b/drivers/net/ixp2000/ixp2400_rx.uc
new file mode 100644
index 0000000..42a73e35
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400_rx.uc
@@ -0,0 +1,408 @@
+/*
+ * RX ucode for the Intel IXP2400 in POS-PHY mode.
+ * Copyright (C) 2004, 2005 Lennert Buytenhek
+ * Dedicated to Marija Kulikova.
+ *
+ * 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.
+ *
+ * Assumptions made in this code:
+ * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where
+ *   only one full element list is used.  This includes, for example,
+ *   1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4.  (This
+ *   is not an exhaustive list.)
+ * - The RBUF uses 64-byte mpackets.
+ * - RX descriptors reside in SRAM, and have the following format:
+ *	struct rx_desc
+ *	{
+ *	// to uengine
+ *		u32	buf_phys_addr;
+ *		u32	buf_length;
+ *
+ *	// from uengine
+ *		u32	channel;
+ *		u32	pkt_length;
+ *	};
+ * - Packet data resides in DRAM.
+ * - Packet buffer addresses are 8-byte aligned.
+ * - Scratch ring 0 is rx_pending.
+ * - Scratch ring 1 is rx_done, and has status condition 'full'.
+ * - The host triggers rx_done flush and rx_pending refill on seeing INTA.
+ * - This code is run on all eight threads of the microengine it runs on.
+ *
+ * Local memory is used for per-channel RX state.
+ */
+
+#define RX_THREAD_FREELIST_0		0x0030
+#define RBUF_ELEMENT_DONE		0x0044
+
+#define CHANNEL_FLAGS			*l$index0[0]
+#define CHANNEL_FLAG_RECEIVING		1
+#define PACKET_LENGTH			*l$index0[1]
+#define PACKET_CHECKSUM			*l$index0[2]
+#define BUFFER_HANDLE			*l$index0[3]
+#define BUFFER_START			*l$index0[4]
+#define BUFFER_LENGTH			*l$index0[5]
+
+#define CHANNEL_STATE_SIZE		24	// in bytes
+#define CHANNEL_STATE_SHIFT		5	// ceil(log2(state size))
+
+
+	.sig volatile sig1
+	.sig volatile sig2
+	.sig volatile sig3
+
+	.sig mpacket_arrived
+	.reg add_to_rx_freelist
+	.reg read $rsw0, $rsw1
+	.xfer_order $rsw0 $rsw1
+
+	.reg zero
+
+	/*
+	 * Initialise add_to_rx_freelist.
+	 */
+	.begin
+		.reg temp
+		.reg temp2
+
+		immed[add_to_rx_freelist, RX_THREAD_FREELIST_0]
+		immed_w1[add_to_rx_freelist, (&$rsw0 | (&mpacket_arrived << 12))]
+
+		local_csr_rd[ACTIVE_CTX_STS]
+		immed[temp, 0]
+		alu[temp2, temp, and, 0x1f]
+		alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<20]
+		alu[temp2, temp, and, 0x80]
+		alu_shf[add_to_rx_freelist, add_to_rx_freelist, or, temp2, <<18]
+	.end
+
+	immed[zero, 0]
+
+	/*
+	 * Skip context 0 initialisation?
+	 */
+	.begin
+		br!=ctx[0, mpacket_receive_loop#]
+	.end
+
+	/*
+	 * Initialise local memory.
+	 */
+	.begin
+		.reg addr
+		.reg temp
+
+		immed[temp, 0]
+	init_local_mem_loop#:
+		alu_shf[addr, --, b, temp, <<CHANNEL_STATE_SHIFT]
+		local_csr_wr[ACTIVE_LM_ADDR_0, addr]
+		nop
+		nop
+		nop
+
+		immed[CHANNEL_FLAGS, 0]
+
+		alu[temp, temp, +, 1]
+		alu[--, temp, and, 0x20]
+		beq[init_local_mem_loop#]
+	.end
+
+	/*
+	 * Initialise signal pipeline.
+	 */
+	.begin
+		local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]
+		.set_sig sig1
+
+		local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]
+		.set_sig sig2
+
+		local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]
+		.set_sig sig3
+	.end
+
+mpacket_receive_loop#:
+	/*
+	 * Synchronise and wait for mpacket.
+	 */
+	.begin
+		ctx_arb[sig1]
+		local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]
+
+		msf[fast_wr, --, add_to_rx_freelist, 0]
+		.set_sig mpacket_arrived
+		ctx_arb[mpacket_arrived]
+		.set $rsw0 $rsw1
+	.end
+
+	/*
+	 * We halt if we see {inbparerr,parerr,null,soperror}.
+	 */
+	.begin
+		alu_shf[--, 0x1b, and, $rsw0, >>8]
+		bne[abort_rswerr#]
+	.end
+
+	/*
+	 * Point local memory pointer to this channel's state area.
+	 */
+	.begin
+		.reg chanaddr
+
+		alu[chanaddr, $rsw0, and, 0x1f]
+		alu_shf[chanaddr, --, b, chanaddr, <<CHANNEL_STATE_SHIFT]
+		local_csr_wr[ACTIVE_LM_ADDR_0, chanaddr]
+		nop
+		nop
+		nop
+	.end
+
+	/*
+	 * Check whether we received a SOP mpacket while we were already
+	 * working on a packet, or a non-SOP mpacket while there was no
+	 * packet pending.  (SOP == RECEIVING -> abort)  If everything's
+	 * okay, update the RECEIVING flag to reflect our new state.
+	 */
+	.begin
+		.reg temp
+		.reg eop
+
+		#if CHANNEL_FLAG_RECEIVING != 1
+		#error CHANNEL_FLAG_RECEIVING is not 1
+		#endif
+
+		alu_shf[temp, 1, and, $rsw0, >>15]
+		alu[temp, temp, xor, CHANNEL_FLAGS]
+		alu[--, temp, and, CHANNEL_FLAG_RECEIVING]
+		beq[abort_proterr#]
+
+		alu_shf[eop, 1, and, $rsw0, >>14]
+		alu[CHANNEL_FLAGS, temp, xor, eop]
+	.end
+
+	/*
+	 * Copy the mpacket into the right spot, and in case of EOP,
+	 * write back the descriptor and pass the packet on.
+	 */
+	.begin
+		.reg buffer_offset
+		.reg _packet_length
+		.reg _packet_checksum
+		.reg _buffer_handle
+		.reg _buffer_start
+		.reg _buffer_length
+
+		/*
+		 * Determine buffer_offset, _packet_length and
+		 * _packet_checksum.
+		 */
+		.begin
+			.reg temp
+
+			alu[--, 1, and, $rsw0, >>15]
+			beq[not_sop#]
+
+			immed[PACKET_LENGTH, 0]
+			immed[PACKET_CHECKSUM, 0]
+
+		not_sop#:
+			alu[buffer_offset, --, b, PACKET_LENGTH]
+			alu_shf[temp, 0xff, and, $rsw0, >>16]
+			alu[_packet_length, buffer_offset, +, temp]
+			alu[PACKET_LENGTH, --, b, _packet_length]
+
+			immed[temp, 0xffff]
+			alu[temp, $rsw1, and, temp]
+			alu[_packet_checksum, PACKET_CHECKSUM, +, temp]
+			alu[PACKET_CHECKSUM, --, b, _packet_checksum]
+		.end
+
+		/*
+		 * Allocate buffer in case of SOP.
+		 */
+		.begin
+			.reg temp
+
+			alu[temp, 1, and, $rsw0, >>15]
+			beq[skip_buffer_alloc#]
+
+			.begin
+				.sig zzz
+				.reg read $stemp $stemp2
+				.xfer_order $stemp $stemp2
+
+			rx_nobufs#:
+				scratch[get, $stemp, zero, 0, 1], ctx_swap[zzz]
+				alu[_buffer_handle, --, b, $stemp]
+				beq[rx_nobufs#]
+
+				sram[read, $stemp, _buffer_handle, 0, 2],
+								ctx_swap[zzz]
+				alu[_buffer_start, --, b, $stemp]
+				alu[_buffer_length, --, b, $stemp2]
+			.end
+
+		skip_buffer_alloc#:
+		.end
+
+		/*
+		 * Resynchronise.
+		 */
+		.begin
+			ctx_arb[sig2]
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]
+		.end
+
+		/*
+		 * Synchronise buffer state.
+		 */
+		.begin
+			.reg temp
+
+			alu[temp, 1, and, $rsw0, >>15]
+			beq[copy_from_local_mem#]
+
+			alu[BUFFER_HANDLE, --, b, _buffer_handle]
+			alu[BUFFER_START, --, b, _buffer_start]
+			alu[BUFFER_LENGTH, --, b, _buffer_length]
+			br[sync_state_done#]
+
+		copy_from_local_mem#:
+			alu[_buffer_handle, --, b, BUFFER_HANDLE]
+			alu[_buffer_start, --, b, BUFFER_START]
+			alu[_buffer_length, --, b, BUFFER_LENGTH]
+
+		sync_state_done#:
+		.end
+
+#if 0
+		/*
+		 * Debug buffer state management.
+		 */
+		.begin
+			.reg temp
+
+			alu[temp, 1, and, $rsw0, >>14]
+			beq[no_poison#]
+			immed[BUFFER_HANDLE, 0xdead]
+			immed[BUFFER_START, 0xdead]
+			immed[BUFFER_LENGTH, 0xdead]
+		no_poison#:
+
+			immed[temp, 0xdead]
+			alu[--, _buffer_handle, -, temp]
+			beq[state_corrupted#]
+			alu[--, _buffer_start, -, temp]
+			beq[state_corrupted#]
+			alu[--, _buffer_length, -, temp]
+			beq[state_corrupted#]
+		.end
+#endif
+
+		/*
+		 * Check buffer length.
+		 */
+		.begin
+			alu[--, _buffer_length, -, _packet_length]
+			blo[buffer_overflow#]
+		.end
+
+		/*
+		 * Copy the mpacket and give back the RBUF element.
+		 */
+		.begin
+			.reg element
+			.reg xfer_size
+			.reg temp
+			.sig copy_sig
+
+			alu_shf[element, 0x7f, and, $rsw0, >>24]
+			alu_shf[xfer_size, 0xff, and, $rsw0, >>16]
+
+			alu[xfer_size, xfer_size, -, 1]
+			alu_shf[xfer_size, 0x10, or, xfer_size, >>3]
+			alu_shf[temp, 0x10, or, xfer_size, <<21]
+			alu_shf[temp, temp, or, element, <<11]
+			alu_shf[--, temp, or, 1, <<18]
+
+			dram[rbuf_rd, --, _buffer_start, buffer_offset, max_8],
+						indirect_ref, sig_done[copy_sig]
+			ctx_arb[copy_sig]
+
+			alu[temp, RBUF_ELEMENT_DONE, or, element, <<16]
+			msf[fast_wr, --, temp, 0]
+		.end
+
+		/*
+		 * If EOP, write back the packet descriptor.
+		 */
+		.begin
+			.reg write $stemp $stemp2
+			.xfer_order $stemp $stemp2
+			.sig zzz
+
+			alu_shf[--, 1, and, $rsw0, >>14]
+			beq[no_writeback#]
+
+			alu[$stemp, $rsw0, and, 0x1f]
+			alu[$stemp2, --, b, _packet_length]
+			sram[write, $stemp, _buffer_handle, 8, 2], ctx_swap[zzz]
+
+		no_writeback#:
+		.end
+
+		/*
+		 * Resynchronise.
+		 */
+		.begin
+			ctx_arb[sig3]
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]
+		.end
+
+		/*
+		 * If EOP, put the buffer back onto the scratch ring.
+		 */
+		.begin
+			.reg write $stemp
+			.sig zzz
+
+			br_inp_state[SCR_Ring1_Status, rx_done_ring_overflow#]
+
+			alu_shf[--, 1, and, $rsw0, >>14]
+			beq[mpacket_receive_loop#]
+
+			alu[--, 1, and, $rsw0, >>10]
+			bne[rxerr#]
+
+			alu[$stemp, --, b, _buffer_handle]
+			scratch[put, $stemp, zero, 4, 1], ctx_swap[zzz]
+			cap[fast_wr, 0, XSCALE_INT_A]
+			br[mpacket_receive_loop#]
+
+		rxerr#:
+			alu[$stemp, --, b, _buffer_handle]
+			scratch[put, $stemp, zero, 0, 1], ctx_swap[zzz]
+			br[mpacket_receive_loop#]
+		.end
+	.end
+
+
+abort_rswerr#:
+	halt
+
+abort_proterr#:
+	halt
+
+state_corrupted#:
+	halt
+
+buffer_overflow#:
+	halt
+
+rx_done_ring_overflow#:
+	halt
+
+
diff --git a/drivers/net/ixp2000/ixp2400_rx.ucode b/drivers/net/ixp2000/ixp2400_rx.ucode
new file mode 100644
index 0000000..e8aee2f
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400_rx.ucode
@@ -0,0 +1,130 @@
+static struct ixp2000_uengine_code ixp2400_rx =
+{
+	.cpu_model_bitmask	= 0x000003fe,
+	.cpu_min_revision	= 0,
+	.cpu_max_revision	= 255,
+
+	.uengine_parameters	= IXP2000_UENGINE_8_CONTEXTS |
+				  IXP2000_UENGINE_PRN_UPDATE_EVERY |
+				  IXP2000_UENGINE_NN_FROM_PREVIOUS |
+				  IXP2000_UENGINE_ASSERT_EMPTY_AT_0 |
+				  IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT |
+				  IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT,
+
+	.initial_reg_values	= (struct ixp2000_reg_value []) {
+		{ -1, -1 }
+	},
+
+	.num_insns		= 109,
+	.insns			= (u8 []) {
+		0xf0, 0x00, 0x0c, 0xc0, 0x05,
+		0xf4, 0x44, 0x0c, 0x00, 0x05,
+		0xfc, 0x04, 0x4c, 0x00, 0x00,
+		0xf0, 0x00, 0x00, 0x3b, 0x00,
+		0xb4, 0x40, 0xf0, 0x3b, 0x1f,
+		0x8a, 0xc0, 0x50, 0x3e, 0x05,
+		0xb4, 0x40, 0xf0, 0x3b, 0x80,
+		0x9a, 0xe0, 0x00, 0x3e, 0x05,
+		0xf0, 0x00, 0x00, 0x07, 0x00,
+		0xd8, 0x05, 0xc0, 0x00, 0x11,
+		0xf0, 0x00, 0x00, 0x0f, 0x00,
+		0x91, 0xb0, 0x20, 0x0e, 0x00,
+		0xfc, 0x06, 0x60, 0x0b, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x02, 0x00,
+		0xb0, 0xc0, 0x30, 0x0f, 0x01,
+		0xa4, 0x70, 0x00, 0x0f, 0x20,
+		0xd8, 0x02, 0xc0, 0x01, 0x00,
+		0xfc, 0x10, 0xac, 0x23, 0x08,
+		0xfc, 0x10, 0xac, 0x43, 0x10,
+		0xfc, 0x10, 0xac, 0x63, 0x18,
+		0xe0, 0x00, 0x00, 0x00, 0x02,
+		0xfc, 0x10, 0xae, 0x23, 0x88,
+		0x3d, 0x00, 0x04, 0x03, 0x20,
+		0xe0, 0x00, 0x00, 0x00, 0x10,
+		0x84, 0x82, 0x02, 0x01, 0x3b,
+		0xd8, 0x1a, 0x00, 0x01, 0x01,
+		0xb4, 0x00, 0x8c, 0x7d, 0x80,
+		0x91, 0xb0, 0x80, 0x22, 0x00,
+		0xfc, 0x06, 0x60, 0x23, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0xf0, 0x00, 0x0c, 0x03, 0x00,
+		0x94, 0xf0, 0x92, 0x01, 0x21,
+		0xac, 0x40, 0x60, 0x26, 0x00,
+		0xa4, 0x30, 0x0c, 0x04, 0x06,
+		0xd8, 0x1a, 0x40, 0x01, 0x00,
+		0x94, 0xe0, 0xa2, 0x01, 0x21,
+		0xac, 0x20, 0x00, 0x28, 0x06,
+		0x84, 0xf2, 0x02, 0x01, 0x21,
+		0xd8, 0x0b, 0x40, 0x01, 0x00,
+		0xf0, 0x00, 0x0c, 0x02, 0x01,
+		0xf0, 0x00, 0x0c, 0x02, 0x02,
+		0xa0, 0x00, 0x08, 0x04, 0x00,
+		0x95, 0x00, 0xc6, 0x01, 0xff,
+		0xa0, 0x80, 0x10, 0x30, 0x00,
+		0xa0, 0x60, 0x1c, 0x00, 0x01,
+		0xf0, 0x0f, 0xf0, 0x33, 0xff,
+		0xb4, 0x00, 0xc0, 0x31, 0x81,
+		0xb0, 0x80, 0xb0, 0x32, 0x02,
+		0xa0, 0x20, 0x20, 0x2c, 0x00,
+		0x94, 0xf0, 0xd2, 0x01, 0x21,
+		0xd8, 0x0f, 0x40, 0x01, 0x00,
+		0x19, 0x40, 0x10, 0x04, 0x20,
+		0xa0, 0x00, 0x26, 0x04, 0x00,
+		0xd8, 0x0d, 0xc0, 0x01, 0x00,
+		0x00, 0x42, 0x10, 0x80, 0x02,
+		0xb0, 0x00, 0x46, 0x04, 0x00,
+		0xb0, 0x00, 0x56, 0x08, 0x00,
+		0xe0, 0x00, 0x00, 0x00, 0x04,
+		0xfc, 0x10, 0xae, 0x43, 0x90,
+		0x84, 0xf0, 0x32, 0x01, 0x21,
+		0xd8, 0x11, 0x40, 0x01, 0x00,
+		0xa0, 0x60, 0x3c, 0x00, 0x02,
+		0xa0, 0x20, 0x40, 0x10, 0x00,
+		0xa0, 0x20, 0x50, 0x14, 0x00,
+		0xd8, 0x12, 0x00, 0x00, 0x18,
+		0xa0, 0x00, 0x28, 0x0c, 0x00,
+		0xb0, 0x00, 0x48, 0x10, 0x00,
+		0xb0, 0x00, 0x58, 0x14, 0x00,
+		0xaa, 0xf0, 0x00, 0x14, 0x01,
+		0xd8, 0x1a, 0xc0, 0x01, 0x05,
+		0x85, 0x80, 0x42, 0x01, 0xff,
+		0x95, 0x00, 0x66, 0x01, 0xff,
+		0xba, 0xc0, 0x60, 0x1b, 0x01,
+		0x9a, 0x30, 0x60, 0x19, 0x30,
+		0x9a, 0xb0, 0x70, 0x1a, 0x30,
+		0x9b, 0x50, 0x78, 0x1e, 0x04,
+		0x8a, 0xe2, 0x08, 0x1e, 0x21,
+		0x6a, 0x4e, 0x00, 0x13, 0x00,
+		0xe0, 0x00, 0x00, 0x00, 0x30,
+		0x9b, 0x00, 0x7a, 0x92, 0x04,
+		0x3d, 0x00, 0x04, 0x1f, 0x20,
+		0x84, 0xe2, 0x02, 0x01, 0x21,
+		0xd8, 0x16, 0x80, 0x01, 0x00,
+		0xa4, 0x18, 0x0c, 0x7d, 0x80,
+		0xa0, 0x58, 0x1c, 0x00, 0x01,
+		0x01, 0x42, 0x00, 0xa0, 0x02,
+		0xe0, 0x00, 0x00, 0x00, 0x08,
+		0xfc, 0x10, 0xae, 0x63, 0x98,
+		0xd8, 0x1b, 0x00, 0xc2, 0x14,
+		0x84, 0xe2, 0x02, 0x01, 0x21,
+		0xd8, 0x05, 0xc0, 0x01, 0x00,
+		0x84, 0xa2, 0x02, 0x01, 0x21,
+		0xd8, 0x19, 0x40, 0x01, 0x01,
+		0xa0, 0x58, 0x0c, 0x00, 0x02,
+		0x1a, 0x40, 0x00, 0x04, 0x24,
+		0x33, 0x00, 0x01, 0x2f, 0x20,
+		0xd8, 0x05, 0xc0, 0x00, 0x18,
+		0xa0, 0x58, 0x0c, 0x00, 0x02,
+		0x1a, 0x40, 0x00, 0x04, 0x20,
+		0xd8, 0x05, 0xc0, 0x00, 0x18,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+	}
+};
diff --git a/drivers/net/ixp2000/ixp2400_tx.uc b/drivers/net/ixp2000/ixp2400_tx.uc
new file mode 100644
index 0000000..d090d18
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400_tx.uc
@@ -0,0 +1,272 @@
+/*
+ * TX ucode for the Intel IXP2400 in POS-PHY mode.
+ * Copyright (C) 2004, 2005 Lennert Buytenhek
+ * Dedicated to Marija Kulikova.
+ *
+ * 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.
+ *
+ * Assumptions made in this code:
+ * - The IXP2400 MSF is configured for POS-PHY mode, in a mode where
+ *   only one TBUF partition is used.  This includes, for example,
+ *   1x32 SPHY and 1x32 MPHY32, but not 4x8 SPHY or 1x32 MPHY4. (This
+ *   is not an exhaustive list.)
+ * - The TBUF uses 64-byte mpackets.
+ * - TX descriptors reside in SRAM, and have the following format:
+ *	struct tx_desc
+ *	{
+ *	// to uengine
+ *		u32	buf_phys_addr;
+ *		u32	pkt_length;
+ *		u32	channel;
+ *	};
+ * - Packet data resides in DRAM.
+ * - Packet buffer addresses are 8-byte aligned.
+ * - Scratch ring 2 is tx_pending.
+ * - Scratch ring 3 is tx_done, and has status condition 'full'.
+ * - This code is run on all eight threads of the microengine it runs on.
+ */
+
+#define TX_SEQUENCE_0		0x0060
+#define TBUF_CTRL		0x1800
+
+#define PARTITION_SIZE		128
+#define PARTITION_THRESH	96
+
+
+	.sig volatile sig1
+	.sig volatile sig2
+	.sig volatile sig3
+
+	.reg @old_tx_seq_0
+	.reg @mpkts_in_flight
+	.reg @next_tbuf_mpacket
+
+	.reg @buffer_handle
+	.reg @buffer_start
+	.reg @packet_length
+	.reg @channel
+	.reg @packet_offset
+
+	.reg zero
+
+	immed[zero, 0]
+
+	/*
+	 * Skip context 0 initialisation?
+	 */
+	.begin
+		br!=ctx[0, mpacket_tx_loop#]
+	.end
+
+	/*
+	 * Wait until all pending TBUF elements have been transmitted.
+	 */
+	.begin
+		.reg read $tx
+		.sig zzz
+
+	loop_empty#:
+		msf[read, $tx, zero, TX_SEQUENCE_0, 1], ctx_swap[zzz]
+		alu_shf[--, --, b, $tx, >>31]
+		beq[loop_empty#]
+
+		alu[@old_tx_seq_0, --, b, $tx]
+	.end
+
+	immed[@mpkts_in_flight, 0]
+	alu[@next_tbuf_mpacket, @old_tx_seq_0, and, (PARTITION_SIZE - 1)]
+
+	immed[@buffer_handle, 0]
+
+	/*
+	 * Initialise signal pipeline.
+	 */
+	.begin
+		local_csr_wr[SAME_ME_SIGNAL, (&sig1 << 3)]
+		.set_sig sig1
+
+		local_csr_wr[SAME_ME_SIGNAL, (&sig2 << 3)]
+		.set_sig sig2
+
+		local_csr_wr[SAME_ME_SIGNAL, (&sig3 << 3)]
+		.set_sig sig3
+	.end
+
+mpacket_tx_loop#:
+	.begin
+		.reg tbuf_element_index
+		.reg buffer_handle
+		.reg sop_eop
+		.reg packet_data
+		.reg channel
+		.reg mpacket_size
+
+		/*
+		 * If there is no packet currently being transmitted,
+		 * dequeue the next TX descriptor, and fetch the buffer
+		 * address, packet length and destination channel number.
+		 */
+		.begin
+			.reg read $stemp $stemp2 $stemp3
+			.xfer_order $stemp $stemp2 $stemp3
+			.sig zzz
+
+			ctx_arb[sig1]
+
+			alu[--, --, b, @buffer_handle]
+			bne[already_got_packet#]
+
+		tx_nobufs#:
+			scratch[get, $stemp, zero, 8, 1], ctx_swap[zzz]
+			alu[@buffer_handle, --, b, $stemp]
+			beq[tx_nobufs#]
+
+			sram[read, $stemp, $stemp, 0, 3], ctx_swap[zzz]
+			alu[@buffer_start, --, b, $stemp]
+			alu[@packet_length, --, b, $stemp2]
+			beq[zero_byte_packet#]
+			alu[@channel, --, b, $stemp3]
+			immed[@packet_offset, 0]
+
+		already_got_packet#:
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig1 << 3))]
+		.end
+
+		/*
+		 * Determine tbuf element index, SOP/EOP flags, mpacket
+		 * offset and mpacket size and cache buffer_handle and
+		 * channel number.
+		 */
+		.begin
+			alu[tbuf_element_index, --, b, @next_tbuf_mpacket]
+			alu[@next_tbuf_mpacket, @next_tbuf_mpacket, +, 1]
+			alu[@next_tbuf_mpacket, @next_tbuf_mpacket, and,
+							(PARTITION_SIZE - 1)]
+
+			alu[buffer_handle, --, b, @buffer_handle]
+			immed[@buffer_handle, 0]
+
+			immed[sop_eop, 1]
+
+			alu[packet_data, --, b, @packet_offset]
+			bne[no_sop#]
+			alu[sop_eop, sop_eop, or, 2]
+		no_sop#:
+			alu[packet_data, packet_data, +, @buffer_start]
+
+			alu[channel, --, b, @channel]
+
+			alu[mpacket_size, @packet_length, -, @packet_offset]
+			alu[--, 64, -, mpacket_size]
+			bhs[eop#]
+			alu[@buffer_handle, --, b, buffer_handle]
+			immed[mpacket_size, 64]
+			alu[sop_eop, sop_eop, and, 2]
+		eop#:
+
+			alu[@packet_offset, @packet_offset, +, mpacket_size]
+		.end
+
+		/*
+		 * Wait until there's enough space in the TBUF.
+		 */
+		.begin
+			.reg read $tx
+			.reg temp
+			.sig zzz
+
+			ctx_arb[sig2]
+
+			br[test_space#]
+
+		loop_space#:
+			msf[read, $tx, zero, TX_SEQUENCE_0, 1], ctx_swap[zzz]
+
+			alu[temp, $tx, -, @old_tx_seq_0]
+			alu[temp, temp, and, 0xff]
+			alu[@mpkts_in_flight, @mpkts_in_flight, -, temp]
+
+			alu[@old_tx_seq_0, --, b, $tx]
+
+		test_space#:
+			alu[--, PARTITION_THRESH, -, @mpkts_in_flight]
+			blo[loop_space#]
+
+			alu[@mpkts_in_flight, @mpkts_in_flight, +, 1]
+
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig2 << 3))]
+		.end
+
+		/*
+		 * Copy the packet data to the TBUF.
+		 */
+		.begin
+			.reg temp
+			.sig copy_sig
+
+			alu[temp, mpacket_size, -, 1]
+			alu_shf[temp, 0x10, or, temp, >>3]
+			alu_shf[temp, 0x10, or, temp, <<21]
+			alu_shf[temp, temp, or, tbuf_element_index, <<11]
+			alu_shf[--, temp, or, 1, <<18]
+
+			dram[tbuf_wr, --, packet_data, 0, max_8],
+					indirect_ref, sig_done[copy_sig]
+			ctx_arb[copy_sig]
+		.end
+
+		/*
+		 * Mark TBUF element as ready-to-be-transmitted.
+		 */
+		.begin
+			.reg write $tsw $tsw2
+			.xfer_order $tsw $tsw2
+			.reg temp
+			.sig zzz
+
+			alu_shf[temp, channel, or, mpacket_size, <<24]
+			alu_shf[$tsw, temp, or, sop_eop, <<8]
+			immed[$tsw2, 0]
+
+			immed[temp, TBUF_CTRL]
+			alu_shf[temp, temp, or, tbuf_element_index, <<3]
+			msf[write, $tsw, temp, 0, 2], ctx_swap[zzz]
+		.end
+
+		/*
+		 * Resynchronise.
+		 */
+		.begin
+			ctx_arb[sig3]
+			local_csr_wr[SAME_ME_SIGNAL, (0x80 | (&sig3 << 3))]
+		.end
+
+		/*
+		 * If this was an EOP mpacket, recycle the TX buffer
+	 	 * and signal the host.
+		 */
+		.begin
+			.reg write $stemp
+			.sig zzz
+
+			alu[--, sop_eop, and, 1]
+			beq[mpacket_tx_loop#]
+
+		tx_done_ring_full#:
+			br_inp_state[SCR_Ring3_Status, tx_done_ring_full#]
+
+			alu[$stemp, --, b, buffer_handle]
+			scratch[put, $stemp, zero, 12, 1], ctx_swap[zzz]
+			cap[fast_wr, 0, XSCALE_INT_A]
+			br[mpacket_tx_loop#]
+		.end
+	.end
+
+
+zero_byte_packet#:
+	halt
+
+
diff --git a/drivers/net/ixp2000/ixp2400_tx.ucode b/drivers/net/ixp2000/ixp2400_tx.ucode
new file mode 100644
index 0000000..a433e24
--- /dev/null
+++ b/drivers/net/ixp2000/ixp2400_tx.ucode
@@ -0,0 +1,98 @@
+static struct ixp2000_uengine_code ixp2400_tx =
+{
+	.cpu_model_bitmask	= 0x000003fe,
+	.cpu_min_revision	= 0,
+	.cpu_max_revision	= 255,
+
+	.uengine_parameters	= IXP2000_UENGINE_8_CONTEXTS |
+				  IXP2000_UENGINE_PRN_UPDATE_EVERY |
+				  IXP2000_UENGINE_NN_FROM_PREVIOUS |
+				  IXP2000_UENGINE_ASSERT_EMPTY_AT_0 |
+				  IXP2000_UENGINE_LM_ADDR1_PER_CONTEXT |
+				  IXP2000_UENGINE_LM_ADDR0_PER_CONTEXT,
+
+	.initial_reg_values	= (struct ixp2000_reg_value []) {
+		{ -1, -1 }
+	},
+
+	.num_insns		= 77,
+	.insns			= (u8 []) {
+		0xf0, 0x00, 0x00, 0x07, 0x00,
+		0xd8, 0x03, 0x00, 0x00, 0x11,
+		0x3c, 0x40, 0x00, 0x04, 0xe0,
+		0x81, 0xf2, 0x02, 0x01, 0x00,
+		0xd8, 0x00, 0x80, 0x01, 0x00,
+		0xb0, 0x08, 0x06, 0x00, 0x00,
+		0xf0, 0x00, 0x0c, 0x00, 0x80,
+		0xb4, 0x49, 0x02, 0x03, 0x7f,
+		0xf0, 0x00, 0x02, 0x83, 0x00,
+		0xfc, 0x10, 0xac, 0x23, 0x08,
+		0xfc, 0x10, 0xac, 0x43, 0x10,
+		0xfc, 0x10, 0xac, 0x63, 0x18,
+		0xe0, 0x00, 0x00, 0x00, 0x02,
+		0xa0, 0x30, 0x02, 0x80, 0x00,
+		0xd8, 0x06, 0x00, 0x01, 0x01,
+		0x19, 0x40, 0x00, 0x04, 0x28,
+		0xb0, 0x0a, 0x06, 0x00, 0x00,
+		0xd8, 0x03, 0xc0, 0x01, 0x00,
+		0x00, 0x44, 0x00, 0x80, 0x80,
+		0xa0, 0x09, 0x06, 0x00, 0x00,
+		0xb0, 0x0b, 0x06, 0x04, 0x00,
+		0xd8, 0x13, 0x00, 0x01, 0x00,
+		0xb0, 0x0c, 0x06, 0x08, 0x00,
+		0xf0, 0x00, 0x0c, 0x00, 0xa0,
+		0xfc, 0x10, 0xae, 0x23, 0x88,
+		0xa0, 0x00, 0x12, 0x40, 0x00,
+		0xb0, 0xc9, 0x02, 0x43, 0x01,
+		0xb4, 0x49, 0x02, 0x43, 0x7f,
+		0xb0, 0x00, 0x22, 0x80, 0x00,
+		0xf0, 0x00, 0x02, 0x83, 0x00,
+		0xf0, 0x00, 0x0c, 0x04, 0x02,
+		0xb0, 0x40, 0x6c, 0x00, 0xa0,
+		0xd8, 0x08, 0x80, 0x01, 0x01,
+		0xaa, 0x00, 0x2c, 0x08, 0x02,
+		0xa0, 0xc0, 0x30, 0x18, 0x90,
+		0xa0, 0x00, 0x43, 0x00, 0x00,
+		0xba, 0xc0, 0x32, 0xc0, 0xa0,
+		0xaa, 0xb0, 0x00, 0x0f, 0x40,
+		0xd8, 0x0a, 0x80, 0x01, 0x04,
+		0xb0, 0x0a, 0x00, 0x08, 0x00,
+		0xf0, 0x00, 0x00, 0x0f, 0x40,
+		0xa4, 0x00, 0x2c, 0x08, 0x02,
+		0xa0, 0x8a, 0x00, 0x0c, 0xa0,
+		0xe0, 0x00, 0x00, 0x00, 0x04,
+		0xd8, 0x0c, 0x80, 0x00, 0x18,
+		0x3c, 0x40, 0x00, 0x04, 0xe0,
+		0xba, 0x80, 0x42, 0x01, 0x80,
+		0xb4, 0x40, 0x40, 0x13, 0xff,
+		0xaa, 0x88, 0x00, 0x10, 0x80,
+		0xb0, 0x08, 0x06, 0x00, 0x00,
+		0xaa, 0xf0, 0x0d, 0x80, 0x80,
+		0xd8, 0x0b, 0x40, 0x01, 0x05,
+		0xa0, 0x88, 0x0c, 0x04, 0x80,
+		0xfc, 0x10, 0xae, 0x43, 0x90,
+		0xba, 0xc0, 0x50, 0x0f, 0x01,
+		0x9a, 0x30, 0x50, 0x15, 0x30,
+		0x9a, 0xb0, 0x50, 0x16, 0x30,
+		0x9b, 0x50, 0x58, 0x16, 0x01,
+		0x8a, 0xe2, 0x08, 0x16, 0x21,
+		0x6b, 0x4e, 0x00, 0x83, 0x03,
+		0xe0, 0x00, 0x00, 0x00, 0x30,
+		0x9a, 0x80, 0x70, 0x0e, 0x04,
+		0x8b, 0x88, 0x08, 0x1e, 0x02,
+		0xf0, 0x00, 0x0c, 0x01, 0x81,
+		0xf0, 0x01, 0x80, 0x1f, 0x00,
+		0x9b, 0xd0, 0x78, 0x1e, 0x01,
+		0x3d, 0x42, 0x00, 0x1c, 0x20,
+		0xe0, 0x00, 0x00, 0x00, 0x08,
+		0xfc, 0x10, 0xae, 0x63, 0x98,
+		0xa4, 0x30, 0x0c, 0x04, 0x02,
+		0xd8, 0x03, 0x00, 0x01, 0x00,
+		0xd8, 0x11, 0xc1, 0x42, 0x14,
+		0xa0, 0x18, 0x00, 0x08, 0x00,
+		0x1a, 0x40, 0x00, 0x04, 0x2c,
+		0x33, 0x00, 0x01, 0x2f, 0x20,
+		0xd8, 0x03, 0x00, 0x00, 0x18,
+		0xe0, 0x00, 0x02, 0x00, 0x00,
+	}
+};
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
new file mode 100644
index 0000000..09f03f4
--- /dev/null
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -0,0 +1,421 @@
+/*
+ * IXP2000 MSF network device driver
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <asm/arch/uengine.h>
+#include <asm/mach-types.h>
+#include <asm/io.h>
+#include "ixp2400_rx.ucode"
+#include "ixp2400_tx.ucode"
+#include "ixpdev_priv.h"
+#include "ixpdev.h"
+
+#define DRV_MODULE_VERSION	"0.2"
+
+static int nds_count;
+static struct net_device **nds;
+static int nds_open;
+static void (*set_port_admin_status)(int port, int up);
+
+static struct ixpdev_rx_desc * const rx_desc =
+	(struct ixpdev_rx_desc *)(IXP2000_SRAM0_VIRT_BASE + RX_BUF_DESC_BASE);
+static struct ixpdev_tx_desc * const tx_desc =
+	(struct ixpdev_tx_desc *)(IXP2000_SRAM0_VIRT_BASE + TX_BUF_DESC_BASE);
+static int tx_pointer;
+
+
+static int ixpdev_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct ixpdev_priv *ip = netdev_priv(dev);
+	struct ixpdev_tx_desc *desc;
+	int entry;
+
+	if (unlikely(skb->len > PAGE_SIZE)) {
+		/* @@@ Count drops.  */
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+	entry = tx_pointer;
+	tx_pointer = (tx_pointer + 1) % TX_BUF_COUNT;
+
+	desc = tx_desc + entry;
+	desc->pkt_length = skb->len;
+	desc->channel = ip->channel;
+
+	skb_copy_and_csum_dev(skb, phys_to_virt(desc->buf_addr));
+	dev_kfree_skb(skb);
+
+	ixp2000_reg_write(RING_TX_PENDING,
+		TX_BUF_DESC_BASE + (entry * sizeof(struct ixpdev_tx_desc)));
+
+	dev->trans_start = jiffies;
+
+	local_irq_disable();
+	ip->tx_queue_entries++;
+	if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
+		netif_stop_queue(dev);
+	local_irq_enable();
+
+	return 0;
+}
+
+
+static int ixpdev_rx(struct net_device *dev, int *budget)
+{
+	while (*budget > 0) {
+		struct ixpdev_rx_desc *desc;
+		struct sk_buff *skb;
+		void *buf;
+		u32 _desc;
+
+		_desc = ixp2000_reg_read(RING_RX_DONE);
+		if (_desc == 0)
+			return 0;
+
+		desc = rx_desc +
+			((_desc - RX_BUF_DESC_BASE) / sizeof(struct ixpdev_rx_desc));
+		buf = phys_to_virt(desc->buf_addr);
+
+		if (desc->pkt_length < 4 || desc->pkt_length > PAGE_SIZE) {
+			printk(KERN_ERR "ixp2000: rx err, length %d\n",
+					desc->pkt_length);
+			goto err;
+		}
+
+		if (desc->channel < 0 || desc->channel >= nds_count) {
+			printk(KERN_ERR "ixp2000: rx err, channel %d\n",
+					desc->channel);
+			goto err;
+		}
+
+		/* @@@ Make FCS stripping configurable.  */
+		desc->pkt_length -= 4;
+
+		if (unlikely(!netif_running(nds[desc->channel])))
+			goto err;
+
+		skb = dev_alloc_skb(desc->pkt_length + 2);
+		if (likely(skb != NULL)) {
+			skb->dev = nds[desc->channel];
+			skb_reserve(skb, 2);
+			eth_copy_and_sum(skb, buf, desc->pkt_length, 0);
+			skb_put(skb, desc->pkt_length);
+			skb->protocol = eth_type_trans(skb, skb->dev);
+
+			skb->dev->last_rx = jiffies;
+
+			netif_receive_skb(skb);
+		}
+
+err:
+		ixp2000_reg_write(RING_RX_PENDING, _desc);
+		dev->quota--;
+		(*budget)--;
+	}
+
+	return 1;
+}
+
+/* dev always points to nds[0].  */
+static int ixpdev_poll(struct net_device *dev, int *budget)
+{
+	/* @@@ Have to stop polling when nds[0] is administratively
+	 * downed while we are polling.  */
+	do {
+		ixp2000_reg_write(IXP2000_IRQ_THD_RAW_STATUS_A_0, 0x00ff);
+
+		if (ixpdev_rx(dev, budget))
+			return 1;
+	} while (ixp2000_reg_read(IXP2000_IRQ_THD_RAW_STATUS_A_0) & 0x00ff);
+
+	netif_rx_complete(dev);
+	ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0x00ff);
+
+	return 0;
+}
+
+static void ixpdev_tx_complete(void)
+{
+	int channel;
+	u32 wake;
+
+	wake = 0;
+	while (1) {
+		struct ixpdev_priv *ip;
+		u32 desc;
+		int entry;
+
+		desc = ixp2000_reg_read(RING_TX_DONE);
+		if (desc == 0)
+			break;
+
+		/* @@@ Check whether entries come back in order.  */
+		entry = (desc - TX_BUF_DESC_BASE) / sizeof(struct ixpdev_tx_desc);
+		channel = tx_desc[entry].channel;
+
+		if (channel < 0 || channel >= nds_count) {
+			printk(KERN_ERR "ixp2000: txcomp channel index "
+					"out of bounds (%d, %.8i, %d)\n",
+					channel, (unsigned int)desc, entry);
+			continue;
+		}
+
+		ip = netdev_priv(nds[channel]);
+		if (ip->tx_queue_entries == TX_BUF_COUNT_PER_CHAN)
+			wake |= 1 << channel;
+		ip->tx_queue_entries--;
+	}
+
+	for (channel = 0; wake != 0; channel++) {
+		if (wake & (1 << channel)) {
+			netif_wake_queue(nds[channel]);
+			wake &= ~(1 << channel);
+		}
+	}
+}
+
+static irqreturn_t ixpdev_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32 status;
+
+	status = ixp2000_reg_read(IXP2000_IRQ_THD_STATUS_A_0);
+	if (status == 0)
+		return IRQ_NONE;
+
+	/*
+	 * Any of the eight receive units signaled RX?
+	 */
+	if (status & 0x00ff) {
+		ixp2000_reg_wrb(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0x00ff);
+		if (likely(__netif_rx_schedule_prep(nds[0]))) {
+			__netif_rx_schedule(nds[0]);
+		} else {
+			printk(KERN_CRIT "ixp2000: irq while polling!!\n");
+		}
+	}
+
+	/*
+	 * Any of the eight transmit units signaled TXdone?
+	 */
+	if (status & 0xff00) {
+		ixp2000_reg_wrb(IXP2000_IRQ_THD_RAW_STATUS_A_0, 0xff00);
+		ixpdev_tx_complete();
+	}
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ixpdev_poll_controller(struct net_device *dev)
+{
+	disable_irq(IRQ_IXP2000_THDA0);
+	ixpdev_interrupt(IRQ_IXP2000_THDA0, dev, NULL);
+	enable_irq(IRQ_IXP2000_THDA0);
+}
+#endif
+
+static int ixpdev_open(struct net_device *dev)
+{
+	struct ixpdev_priv *ip = netdev_priv(dev);
+	int err;
+
+	if (!nds_open++) {
+		err = request_irq(IRQ_IXP2000_THDA0, ixpdev_interrupt,
+					SA_SHIRQ, "ixp2000_eth", nds);
+		if (err) {
+			nds_open--;
+			return err;
+		}
+
+		ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_SET_A_0, 0xffff);
+	}
+
+	set_port_admin_status(ip->channel, 1);
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+static int ixpdev_close(struct net_device *dev)
+{
+	struct ixpdev_priv *ip = netdev_priv(dev);
+
+	netif_stop_queue(dev);
+	set_port_admin_status(ip->channel, 0);
+
+	if (!--nds_open) {
+		ixp2000_reg_write(IXP2000_IRQ_THD_ENABLE_CLEAR_A_0, 0xffff);
+		free_irq(IRQ_IXP2000_THDA0, nds);
+	}
+
+	return 0;
+}
+
+struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
+{
+	struct net_device *dev;
+	struct ixpdev_priv *ip;
+
+	dev = alloc_etherdev(sizeof_priv);
+	if (dev == NULL)
+		return NULL;
+
+	dev->hard_start_xmit = ixpdev_xmit;
+	dev->poll = ixpdev_poll;
+	dev->open = ixpdev_open;
+	dev->stop = ixpdev_close;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = ixpdev_poll_controller;
+#endif
+
+	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+	dev->weight = 64;
+
+	ip = netdev_priv(dev);
+	ip->channel = channel;
+	ip->tx_queue_entries = 0;
+
+	return dev;
+}
+
+int ixpdev_init(int __nds_count, struct net_device **__nds,
+		void (*__set_port_admin_status)(int port, int up))
+{
+	int i;
+	int err;
+
+	if (RX_BUF_COUNT > 192 || TX_BUF_COUNT > 192) {
+		static void __too_many_rx_or_tx_buffers(void);
+		__too_many_rx_or_tx_buffers();
+	}
+
+	printk(KERN_INFO "IXP2000 MSF ethernet driver %s\n", DRV_MODULE_VERSION);
+
+	nds_count = __nds_count;
+	nds = __nds;
+	set_port_admin_status = __set_port_admin_status;
+
+	for (i = 0; i < RX_BUF_COUNT; i++) {
+		void *buf;
+
+		buf = (void *)get_zeroed_page(GFP_KERNEL);
+		if (buf == NULL) {
+			err = -ENOMEM;
+			while (--i >= 0)
+				free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
+			goto err_out;
+		}
+		rx_desc[i].buf_addr = virt_to_phys(buf);
+		rx_desc[i].buf_length = PAGE_SIZE;
+	}
+
+	/* @@@ Maybe we shouldn't be preallocating TX buffers.  */
+	for (i = 0; i < TX_BUF_COUNT; i++) {
+		void *buf;
+
+		buf = (void *)get_zeroed_page(GFP_KERNEL);
+		if (buf == NULL) {
+			err = -ENOMEM;
+			while (--i >= 0)
+				free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+			goto err_free_rx;
+		}
+		tx_desc[i].buf_addr = virt_to_phys(buf);
+	}
+
+	/* 256 entries, ring status set means 'empty', base address 0x0000.  */
+	ixp2000_reg_write(RING_RX_PENDING_BASE, 0x44000000);
+	ixp2000_reg_write(RING_RX_PENDING_HEAD, 0x00000000);
+	ixp2000_reg_write(RING_RX_PENDING_TAIL, 0x00000000);
+
+	/* 256 entries, ring status set means 'full', base address 0x0400.  */
+	ixp2000_reg_write(RING_RX_DONE_BASE, 0x40000400);
+	ixp2000_reg_write(RING_RX_DONE_HEAD, 0x00000000);
+	ixp2000_reg_write(RING_RX_DONE_TAIL, 0x00000000);
+
+	for (i = 0; i < RX_BUF_COUNT; i++) {
+		ixp2000_reg_write(RING_RX_PENDING,
+			RX_BUF_DESC_BASE + (i * sizeof(struct ixpdev_rx_desc)));
+	}
+
+	ixp2000_uengine_load(0, &ixp2400_rx);
+	ixp2000_uengine_start_contexts(0, 0xff);
+
+	/* 256 entries, ring status set means 'empty', base address 0x0800.  */
+	ixp2000_reg_write(RING_TX_PENDING_BASE, 0x44000800);
+	ixp2000_reg_write(RING_TX_PENDING_HEAD, 0x00000000);
+	ixp2000_reg_write(RING_TX_PENDING_TAIL, 0x00000000);
+
+	/* 256 entries, ring status set means 'full', base address 0x0c00.  */
+	ixp2000_reg_write(RING_TX_DONE_BASE, 0x40000c00);
+	ixp2000_reg_write(RING_TX_DONE_HEAD, 0x00000000);
+	ixp2000_reg_write(RING_TX_DONE_TAIL, 0x00000000);
+
+	ixp2000_uengine_load(1, &ixp2400_tx);
+	ixp2000_uengine_start_contexts(1, 0xff);
+
+	for (i = 0; i < nds_count; i++) {
+		err = register_netdev(nds[i]);
+		if (err) {
+			while (--i >= 0)
+				unregister_netdev(nds[i]);
+			goto err_free_tx;
+		}
+	}
+
+	for (i = 0; i < nds_count; i++) {
+		printk(KERN_INFO "%s: IXP2000 MSF ethernet (port %d), "
+			"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", nds[i]->name, i,
+			nds[i]->dev_addr[0], nds[i]->dev_addr[1],
+			nds[i]->dev_addr[2], nds[i]->dev_addr[3],
+			nds[i]->dev_addr[4], nds[i]->dev_addr[5]);
+	}
+
+	return 0;
+
+err_free_tx:
+	for (i = 0; i < TX_BUF_COUNT; i++)
+		free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+
+err_free_rx:
+	for (i = 0; i < RX_BUF_COUNT; i++)
+		free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
+
+err_out:
+	return err;
+} 
+
+void ixpdev_deinit(void)
+{
+	int i;
+
+	/* @@@ Flush out pending packets.  */
+
+	for (i = 0; i < nds_count; i++)
+		unregister_netdev(nds[i]);
+
+	ixp2000_uengine_stop_contexts(1, 0xff);
+	ixp2000_uengine_stop_contexts(0, 0xff);
+	ixp2000_uengine_reset(0x3);
+
+	for (i = 0; i < TX_BUF_COUNT; i++)
+		free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr));
+
+	for (i = 0; i < RX_BUF_COUNT; i++)
+		free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr));
+}
diff --git a/drivers/net/ixp2000/ixpdev.h b/drivers/net/ixp2000/ixpdev.h
new file mode 100644
index 0000000..bd686cb
--- /dev/null
+++ b/drivers/net/ixp2000/ixpdev.h
@@ -0,0 +1,27 @@
+/*
+ * IXP2000 MSF network device driver
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __IXPDEV_H
+#define __IXPDEV_H
+
+struct ixpdev_priv
+{
+	int	channel;
+	int	tx_queue_entries;
+};
+
+struct net_device *ixpdev_alloc(int channel, int sizeof_priv);
+int ixpdev_init(int num_ports, struct net_device **nds,
+		void (*set_port_admin_status)(int port, int up));
+void ixpdev_deinit(void);
+
+
+#endif
diff --git a/drivers/net/ixp2000/ixpdev_priv.h b/drivers/net/ixp2000/ixpdev_priv.h
new file mode 100644
index 0000000..86aa08e
--- /dev/null
+++ b/drivers/net/ixp2000/ixpdev_priv.h
@@ -0,0 +1,57 @@
+/*
+ * IXP2000 MSF network device driver
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __IXPDEV_PRIV_H
+#define __IXPDEV_PRIV_H
+
+#define RX_BUF_DESC_BASE	0x00001000
+#define RX_BUF_COUNT		((3 * PAGE_SIZE) / (4 * sizeof(struct ixpdev_rx_desc)))
+#define TX_BUF_DESC_BASE	0x00002000
+#define TX_BUF_COUNT		((3 * PAGE_SIZE) / (4 * sizeof(struct ixpdev_tx_desc)))
+#define TX_BUF_COUNT_PER_CHAN	(TX_BUF_COUNT / 4)
+
+#define RING_RX_PENDING		((u32 *)IXP2000_SCRATCH_RING_VIRT_BASE)
+#define RING_RX_DONE		((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 4))
+#define RING_TX_PENDING		((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 8))
+#define RING_TX_DONE		((u32 *)(IXP2000_SCRATCH_RING_VIRT_BASE + 12))
+
+#define SCRATCH_REG(x)		((u32 *)(IXP2000_GLOBAL_REG_VIRT_BASE | 0x0800 | (x)))
+#define RING_RX_PENDING_BASE	SCRATCH_REG(0x00)
+#define RING_RX_PENDING_HEAD	SCRATCH_REG(0x04)
+#define RING_RX_PENDING_TAIL	SCRATCH_REG(0x08)
+#define RING_RX_DONE_BASE	SCRATCH_REG(0x10)
+#define RING_RX_DONE_HEAD	SCRATCH_REG(0x14)
+#define RING_RX_DONE_TAIL	SCRATCH_REG(0x18)
+#define RING_TX_PENDING_BASE	SCRATCH_REG(0x20)
+#define RING_TX_PENDING_HEAD	SCRATCH_REG(0x24)
+#define RING_TX_PENDING_TAIL	SCRATCH_REG(0x28)
+#define RING_TX_DONE_BASE	SCRATCH_REG(0x30)
+#define RING_TX_DONE_HEAD	SCRATCH_REG(0x34)
+#define RING_TX_DONE_TAIL	SCRATCH_REG(0x38)
+
+struct ixpdev_rx_desc
+{
+	u32	buf_addr;
+	u32	buf_length;
+	u32	channel;
+	u32	pkt_length;
+};
+
+struct ixpdev_tx_desc
+{
+	u32	buf_addr;
+	u32	pkt_length;
+	u32	channel;
+	u32	unused;
+};
+
+
+#endif
diff --git a/drivers/net/ixp2000/pm3386.c b/drivers/net/ixp2000/pm3386.c
new file mode 100644
index 0000000..5c7ab75
--- /dev/null
+++ b/drivers/net/ixp2000/pm3386.c
@@ -0,0 +1,334 @@
+/*
+ * Helper functions for the PM3386s on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <asm/io.h>
+#include "pm3386.h"
+
+/*
+ * Read from register 'reg' of PM3386 device 'pm'.
+ */
+static u16 pm3386_reg_read(int pm, int reg)
+{
+	void *_reg;
+	u16 value;
+
+	_reg = (void *)ENP2611_PM3386_0_VIRT_BASE;
+	if (pm == 1)
+		_reg = (void *)ENP2611_PM3386_1_VIRT_BASE;
+
+	value = *((volatile u16 *)(_reg + (reg << 1)));
+
+//	printk(KERN_INFO "pm3386_reg_read(%d, %.3x) = %.8x\n", pm, reg, value);
+
+	return value;
+}
+
+/*
+ * Write to register 'reg' of PM3386 device 'pm', and perform
+ * a readback from the identification register.
+ */
+static void pm3386_reg_write(int pm, int reg, u16 value)
+{
+	void *_reg;
+	u16 dummy;
+
+//	printk(KERN_INFO "pm3386_reg_write(%d, %.3x, %.8x)\n", pm, reg, value);
+
+	_reg = (void *)ENP2611_PM3386_0_VIRT_BASE;
+	if (pm == 1)
+		_reg = (void *)ENP2611_PM3386_1_VIRT_BASE;
+
+	*((volatile u16 *)(_reg + (reg << 1))) = value;
+
+	dummy = *((volatile u16 *)_reg);
+	__asm__ __volatile__("mov %0, %0" : "+r" (dummy));
+}
+
+/*
+ * Read from port 'port' register 'reg', where the registers
+ * for the different ports are 'spacing' registers apart.
+ */
+static u16 pm3386_port_reg_read(int port, int _reg, int spacing)
+{
+	int reg;
+
+	reg = _reg;
+	if (port & 1)
+		reg += spacing;
+
+	return pm3386_reg_read(port >> 1, reg);
+}
+
+/*
+ * Write to port 'port' register 'reg', where the registers
+ * for the different ports are 'spacing' registers apart.
+ */
+static void pm3386_port_reg_write(int port, int _reg, int spacing, u16 value)
+{
+	int reg;
+
+	reg = _reg;
+	if (port & 1)
+		reg += spacing;
+
+	pm3386_reg_write(port >> 1, reg, value);
+}
+
+
+void pm3386_reset(void)
+{
+	u8 mac[3][6];
+
+	/* Save programmed MAC addresses.  */
+	pm3386_get_mac(0, mac[0]);
+	pm3386_get_mac(1, mac[1]);
+	pm3386_get_mac(2, mac[2]);
+
+	/* Assert analog and digital reset.  */
+	pm3386_reg_write(0, 0x002, 0x0060);
+	pm3386_reg_write(1, 0x002, 0x0060);
+	mdelay(1);
+
+	/* Deassert analog reset.  */
+	pm3386_reg_write(0, 0x002, 0x0062);
+	pm3386_reg_write(1, 0x002, 0x0062);
+	mdelay(10);
+
+	/* Deassert digital reset.  */
+	pm3386_reg_write(0, 0x002, 0x0063);
+	pm3386_reg_write(1, 0x002, 0x0063);
+	mdelay(10);
+
+	/* Restore programmed MAC addresses.  */
+	pm3386_set_mac(0, mac[0]);
+	pm3386_set_mac(1, mac[1]);
+	pm3386_set_mac(2, mac[2]);
+
+	/* Disable carrier on all ports.  */
+	pm3386_set_carrier(0, 0);
+	pm3386_set_carrier(1, 0);
+	pm3386_set_carrier(2, 0);
+}
+
+static u16 swaph(u16 x)
+{
+	return ((x << 8) | (x >> 8)) & 0xffff;
+}
+
+void pm3386_init_port(int port)
+{
+	int pm = port >> 1;
+
+	/*
+	 * Work around ENP2611 bootloader programming MAC address
+	 * in reverse.
+	 */
+	if (pm3386_port_reg_read(port, 0x30a, 0x100) == 0x0000 &&
+	    (pm3386_port_reg_read(port, 0x309, 0x100) & 0xff00) == 0x5000) {
+		u16 temp[3];
+
+		temp[0] = pm3386_port_reg_read(port, 0x308, 0x100);
+		temp[1] = pm3386_port_reg_read(port, 0x309, 0x100);
+		temp[2] = pm3386_port_reg_read(port, 0x30a, 0x100);
+		pm3386_port_reg_write(port, 0x308, 0x100, swaph(temp[2]));
+		pm3386_port_reg_write(port, 0x309, 0x100, swaph(temp[1]));
+		pm3386_port_reg_write(port, 0x30a, 0x100, swaph(temp[0]));
+	}
+
+	/*
+	 * Initialise narrowbanding mode.  See application note 2010486
+	 * for more information.  (@@@ We also need to issue a reset
+	 * when ROOL or DOOL are detected.)
+	 */
+	pm3386_port_reg_write(port, 0x708, 0x10, 0xd055);
+	udelay(500);
+	pm3386_port_reg_write(port, 0x708, 0x10, 0x5055);
+
+	/*
+	 * SPI-3 ingress block.  Set 64 bytes SPI-3 burst size
+	 * towards SPI-3 bridge.
+	 */
+	pm3386_port_reg_write(port, 0x122, 0x20, 0x0002);
+
+	/*
+	 * Enable ingress protocol checking, and soft reset the
+	 * SPI-3 ingress block.
+	 */
+	pm3386_reg_write(pm, 0x103, 0x0003);
+	while (!(pm3386_reg_read(pm, 0x103) & 0x80))
+		;
+
+	/*
+	 * SPI-3 egress block.  Gather 12288 bytes of the current
+	 * packet in the TX fifo before initiating transmit on the
+	 * SERDES interface.  (Prevents TX underflows.)
+	 */
+	pm3386_port_reg_write(port, 0x221, 0x20, 0x0007);
+
+	/*
+	 * Enforce odd parity from the SPI-3 bridge, and soft reset
+	 * the SPI-3 egress block.
+	 */
+	pm3386_reg_write(pm, 0x203, 0x000d & ~(4 << (port & 1)));
+	while ((pm3386_reg_read(pm, 0x203) & 0x000c) != 0x000c)
+		;
+
+	/*
+	 * EGMAC block.  Set this channels to reject long preambles,
+	 * not send or transmit PAUSE frames, enable preamble checking,
+	 * disable frame length checking, enable FCS appending, enable
+	 * TX frame padding.
+	 */
+	pm3386_port_reg_write(port, 0x302, 0x100, 0x0113);
+
+	/*
+	 * Soft reset the EGMAC block.
+	 */
+	pm3386_port_reg_write(port, 0x301, 0x100, 0x8000);
+	pm3386_port_reg_write(port, 0x301, 0x100, 0x0000);
+
+	/*
+	 * Auto-sense autonegotiation status.
+	 */
+	pm3386_port_reg_write(port, 0x306, 0x100, 0x0100);
+
+	/*
+	 * Allow reception of jumbo frames.
+	 */
+	pm3386_port_reg_write(port, 0x310, 0x100, 9018);
+
+	/*
+	 * Allow transmission of jumbo frames.
+	 */
+	pm3386_port_reg_write(port, 0x336, 0x100, 9018);
+
+	/* @@@ Should set 0x337/0x437 (RX forwarding threshold.)  */
+
+	/*
+	 * Set autonegotiation parameters to 'no PAUSE, full duplex.'
+	 */
+	pm3386_port_reg_write(port, 0x31c, 0x100, 0x0020);
+
+	/*
+	 * Enable and restart autonegotiation.
+	 */
+	pm3386_port_reg_write(port, 0x318, 0x100, 0x0003);
+	pm3386_port_reg_write(port, 0x318, 0x100, 0x0002);
+}
+
+void pm3386_get_mac(int port, u8 *mac)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x308, 0x100);
+	mac[0] = temp & 0xff;
+	mac[1] = (temp >> 8) & 0xff;
+
+	temp = pm3386_port_reg_read(port, 0x309, 0x100);
+	mac[2] = temp & 0xff;
+	mac[3] = (temp >> 8) & 0xff;
+
+	temp = pm3386_port_reg_read(port, 0x30a, 0x100);
+	mac[4] = temp & 0xff;
+	mac[5] = (temp >> 8) & 0xff;
+}
+
+void pm3386_set_mac(int port, u8 *mac)
+{
+	pm3386_port_reg_write(port, 0x308, 0x100, (mac[1] << 8) | mac[0]);
+	pm3386_port_reg_write(port, 0x309, 0x100, (mac[3] << 8) | mac[2]);
+	pm3386_port_reg_write(port, 0x30a, 0x100, (mac[5] << 8) | mac[4]);
+}
+
+static u32 pm3386_get_stat(int port, u16 base)
+{
+	u32 value;
+
+	value = pm3386_port_reg_read(port, base, 0x100);
+	value |= pm3386_port_reg_read(port, base + 1, 0x100) << 16;
+
+	return value;
+}
+
+void pm3386_get_stats(int port, struct net_device_stats *stats)
+{
+	/*
+	 * Snapshot statistics counters.
+	 */
+	pm3386_port_reg_write(port, 0x500, 0x100, 0x0001);
+	while (pm3386_port_reg_read(port, 0x500, 0x100) & 0x0001)
+		;
+
+	memset(stats, 0, sizeof(*stats));
+
+	stats->rx_packets = pm3386_get_stat(port, 0x510);
+	stats->tx_packets = pm3386_get_stat(port, 0x590);
+	stats->rx_bytes = pm3386_get_stat(port, 0x514);
+	stats->tx_bytes = pm3386_get_stat(port, 0x594);
+	/* @@@ Add other stats.  */
+}
+
+void pm3386_set_carrier(int port, int state)
+{
+	pm3386_port_reg_write(port, 0x703, 0x10, state ? 0x1001 : 0x0000);
+}
+
+int pm3386_is_link_up(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x31a, 0x100);
+	temp = pm3386_port_reg_read(port, 0x31a, 0x100);
+
+	return !!(temp & 0x0002);
+}
+
+void pm3386_enable_rx(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x303, 0x100);
+	temp |= 0x1000;
+	pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+void pm3386_disable_rx(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x303, 0x100);
+	temp &= 0xefff;
+	pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+void pm3386_enable_tx(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x303, 0x100);
+	temp |= 0x4000;
+	pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+void pm3386_disable_tx(int port)
+{
+	u16 temp;
+
+	temp = pm3386_port_reg_read(port, 0x303, 0x100);
+	temp &= 0xbfff;
+	pm3386_port_reg_write(port, 0x303, 0x100, temp);
+}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ixp2000/pm3386.h b/drivers/net/ixp2000/pm3386.h
new file mode 100644
index 0000000..fe92bb0
--- /dev/null
+++ b/drivers/net/ixp2000/pm3386.h
@@ -0,0 +1,28 @@
+/*
+ * Helper functions for the PM3386s on the Radisys ENP2611
+ * Copyright (C) 2004, 2005 Lennert Buytenhek <buytenh@wantstofly.org>
+ * Dedicated to Marija Kulikova.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __PM3386_H
+#define __PM3386_H
+
+void pm3386_reset(void);
+void pm3386_init_port(int port);
+void pm3386_get_mac(int port, u8 *mac);
+void pm3386_set_mac(int port, u8 *mac);
+void pm3386_get_stats(int port, struct net_device_stats *stats);
+void pm3386_set_carrier(int port, int state);
+int pm3386_is_link_up(int port);
+void pm3386_enable_rx(int port);
+void pm3386_disable_rx(int port);
+void pm3386_enable_tx(int port);
+void pm3386_disable_tx(int port);
+
+
+#endif
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index b039bd8..272d331d 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -296,7 +296,7 @@
 	}
 
 	jazz_sonic_device = platform_device_alloc(jazz_sonic_string, 0);
-	if (!jazz_sonnic_device)
+	if (!jazz_sonic_device)
 		goto out_unregister;
 
 	if (platform_device_add(jazz_sonic_device)) {
@@ -307,7 +307,7 @@
 	return 0;
 
 out_unregister:
-	driver_unregister(&jazz_sonic_driver);
+	platform_driver_unregister(&jazz_sonic_driver);
 
 	return -ENOMEM;
 }
diff --git a/drivers/net/mipsnet.h b/drivers/net/mipsnet.h
index 8785359..026c732 100644
--- a/drivers/net/mipsnet.h
+++ b/drivers/net/mipsnet.h
@@ -1,28 +1,8 @@
-//
-// <COPYRIGHT CLASS="1B" YEAR="2005">
-// Unpublished work (c) MIPS Technologies, Inc.  All rights reserved.
-// Unpublished rights reserved under the copyright laws of the U.S.A. and
-//  other countries.
-//
-// PROPRIETARY / SECRET CONFIDENTIAL INFORMATION OF MIPS TECHNOLOGIES, INC.
-// FOR INTERNAL USE ONLY.
-//
-// Under no circumstances (contract or otherwise) may this information be
-// disclosed to, or copied, modified or used by anyone other than employees
-// or contractors of MIPS Technologies having a need to know.
-// </COPYRIGHT>
-//
-//++
-// File: MIPS_Net.h
-//
-// Description:
-//   The definition of the emulated MIPSNET device's interface.
-//
-// Notes: This include file needs to work from a Linux device drivers.
-//
-//--
-//
-
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
 #ifndef __MIPSNET_H
 #define __MIPSNET_H
 
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index f857ae9..b0c3b6a 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -115,6 +115,7 @@
 #include <linux/ethtool.h>
 #include <linux/timer.h>
 #include <linux/if_vlan.h>
+#include <linux/rtnetlink.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 71fd411..48774ef 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -227,8 +227,6 @@
 
 static void tc574_config(dev_link_t *link);
 static void tc574_release(dev_link_t *link);
-static int tc574_event(event_t event, int priority,
-					   event_callback_args_t *args);
 
 static void mdio_sync(kio_addr_t ioaddr, int bits);
 static int mdio_read(kio_addr_t ioaddr, int phy_id, int location);
@@ -250,12 +248,7 @@
 static struct ethtool_ops netdev_ethtool_ops;
 static void set_rx_mode(struct net_device *dev);
 
-static dev_info_t dev_info = "3c574_cs";
-
-static dev_link_t *tc574_attach(void);
-static void tc574_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void tc574_detach(struct pcmcia_device *p_dev);
 
 /*
 	tc574_attach() creates an "instance" of the driver, allocating
@@ -263,20 +256,18 @@
 	with Card Services.
 */
 
-static dev_link_t *tc574_attach(void)
+static int tc574_attach(struct pcmcia_device *p_dev)
 {
 	struct el3_private *lp;
-	client_reg_t client_reg;
 	dev_link_t *link;
 	struct net_device *dev;
-	int ret;
 
 	DEBUG(0, "3c574_attach()\n");
 
 	/* Create the PC card device object. */
 	dev = alloc_etherdev(sizeof(struct el3_private));
 	if (!dev)
-		return NULL;
+		return -ENOMEM;
 	lp = netdev_priv(dev);
 	link = &lp->link;
 	link->priv = dev;
@@ -307,20 +298,13 @@
 	dev->watchdog_timeo = TX_TIMEOUT;
 #endif
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		tc574_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	tc574_config(link);
+
+	return 0;
 } /* tc574_attach */
 
 /*
@@ -332,30 +316,19 @@
 
 */
 
-static void tc574_detach(dev_link_t *link)
+static void tc574_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
-	dev_link_t **linkp;
 
 	DEBUG(0, "3c574_detach(0x%p)\n", link);
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link) break;
-	if (*linkp == NULL)
-		return;
-
 	if (link->dev)
 		unregister_netdev(dev);
 
 	if (link->state & DEV_CONFIG)
 		tc574_release(link);
 
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
 	free_netdev(dev);
 } /* tc574_detach */
 
@@ -547,56 +520,37 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-/*
-	The card status event handler.  Mostly, this schedules other
-	stuff to run after an event is received.  A CARD_REMOVAL event
-	also sets some flags to discourage the net drivers from trying
-	to talk to the card any more.
-*/
-
-static int tc574_event(event_t event, int priority,
-					   event_callback_args_t *args)
+static int tc574_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 
-	DEBUG(1, "3c574_event(0x%06x)\n", event);
-
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		if (link->open)
 			netif_device_detach(dev);
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		tc574_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG) {
-			if (link->open)
-				netif_device_detach(dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			if (link->open) {
-				tc574_reset(dev);
-				netif_device_attach(dev);
-			}
-		}
-		break;
+		pcmcia_release_configuration(link->handle);
 	}
+
 	return 0;
-} /* tc574_event */
+}
+
+static int tc574_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			tc574_reset(dev);
+			netif_device_attach(dev);
+		}
+	}
+
+	return 0;
+}
 
 static void dump_status(struct net_device *dev)
 {
@@ -1292,10 +1246,11 @@
 	.drv		= {
 		.name	= "3c574_cs",
 	},
-	.attach		= tc574_attach,
-	.event		= tc574_event,
-	.detach		= tc574_detach,
+	.probe		= tc574_attach,
+	.remove		= tc574_detach,
 	.id_table       = tc574_ids,
+	.suspend	= tc574_suspend,
+	.resume		= tc574_resume,
 };
 
 static int __init init_tc574(void)
@@ -1306,7 +1261,6 @@
 static void __exit exit_tc574(void)
 {
 	pcmcia_unregister_driver(&tc574_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_tc574);
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index d83fdd8..1c3c9c6 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -143,8 +143,6 @@
 
 static void tc589_config(dev_link_t *link);
 static void tc589_release(dev_link_t *link);
-static int tc589_event(event_t event, int priority,
-		       event_callback_args_t *args);
 
 static u16 read_eeprom(kio_addr_t ioaddr, int index);
 static void tc589_reset(struct net_device *dev);
@@ -161,12 +159,7 @@
 static void set_multicast_list(struct net_device *dev);
 static struct ethtool_ops netdev_ethtool_ops;
 
-static dev_info_t dev_info = "3c589_cs";
-
-static dev_link_t *tc589_attach(void);
-static void tc589_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void tc589_detach(struct pcmcia_device *p_dev);
 
 /*======================================================================
 
@@ -176,20 +169,18 @@
 
 ======================================================================*/
 
-static dev_link_t *tc589_attach(void)
+static int tc589_attach(struct pcmcia_device *p_dev)
 {
     struct el3_private *lp;
-    client_reg_t client_reg;
     dev_link_t *link;
     struct net_device *dev;
-    int ret;
 
     DEBUG(0, "3c589_attach()\n");
-    
+
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(struct el3_private));
     if (!dev)
-	 return NULL;
+	 return -ENOMEM;
     lp = netdev_priv(dev);
     link = &lp->link;
     link->priv = dev;
@@ -206,7 +197,7 @@
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
     link->conf.Present = PRESENT_OPTION;
-    
+
     /* The EL3-specific entries in the device structure. */
     SET_MODULE_OWNER(dev);
     dev->hard_start_xmit = &el3_start_xmit;
@@ -221,20 +212,13 @@
 #endif
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	tc589_detach(link);
-	return NULL;
-    }
-    
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    tc589_config(link);
+
+    return 0;
 } /* tc589_attach */
 
 /*======================================================================
@@ -246,30 +230,19 @@
 
 ======================================================================*/
 
-static void tc589_detach(dev_link_t *link)
+static void tc589_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
-    dev_link_t **linkp;
-    
+
     DEBUG(0, "3c589_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
 
     if (link->dev)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
 	tc589_release(link);
-    
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
-    /* Unlink device structure, free bits */
-    *linkp = link->next;
+
     free_netdev(dev);
 } /* tc589_detach */
 
@@ -421,58 +394,37 @@
     link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-    
-======================================================================*/
-
-static int tc589_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int tc589_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
-    
-    DEBUG(1, "3c589_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	tc589_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int tc589_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		tc589_reset(dev);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			tc589_reset(dev);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* tc589_event */
+
+	return 0;
+}
 
 /*====================================================================*/
 
@@ -1067,10 +1019,11 @@
 	.drv		= {
 		.name	= "3c589_cs",
 	},
-	.attach		= tc589_attach,
-	.event		= tc589_event,
-	.detach		= tc589_detach,
+	.probe		= tc589_attach,
+	.remove		= tc589_detach,
         .id_table       = tc589_ids,
+	.suspend	= tc589_suspend,
+	.resume		= tc589_resume,
 };
 
 static int __init init_tc589(void)
@@ -1081,7 +1034,6 @@
 static void __exit exit_tc589(void)
 {
 	pcmcia_unregister_driver(&tc589_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_tc589);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 8bb4e85..01ddfc8 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -87,8 +87,6 @@
 
 static void axnet_config(dev_link_t *link);
 static void axnet_release(dev_link_t *link);
-static int axnet_event(event_t event, int priority,
-		       event_callback_args_t *args);
 static int axnet_open(struct net_device *dev);
 static int axnet_close(struct net_device *dev);
 static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -107,11 +105,7 @@
 static void block_output(struct net_device *dev, int count,
 			 const u_char *buf, const int start_page);
 
-static dev_link_t *axnet_attach(void);
-static void axnet_detach(dev_link_t *);
-
-static dev_info_t dev_info = "axnet_cs";
-static dev_link_t *dev_list;
+static void axnet_detach(struct pcmcia_device *p_dev);
 
 static void axdev_setup(struct net_device *dev);
 static void AX88190_init(struct net_device *dev, int startp);
@@ -147,13 +141,11 @@
 
 ======================================================================*/
 
-static dev_link_t *axnet_attach(void)
+static int axnet_attach(struct pcmcia_device *p_dev)
 {
     axnet_dev_t *info;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
 
     DEBUG(0, "axnet_attach()\n");
 
@@ -161,7 +153,7 @@
 			"eth%d", axdev_setup);
 
     if (!dev)
-	return NULL;
+	return -ENOMEM;
 
     info = PRIV(dev);
     link = &info->link;
@@ -176,20 +168,13 @@
     dev->do_ioctl = &axnet_ioctl;
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	axnet_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    axnet_config(link);
+
+    return 0;
 } /* axnet_attach */
 
 /*======================================================================
@@ -201,30 +186,19 @@
 
 ======================================================================*/
 
-static void axnet_detach(dev_link_t *link)
+static void axnet_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
-    dev_link_t **linkp;
 
     DEBUG(0, "axnet_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
-
     if (link->dev)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
 	axnet_release(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-
-    /* Unlink device structure, free bits */
-    *linkp = link->next;
     free_netdev(dev);
 } /* axnet_detach */
 
@@ -490,59 +464,39 @@
     link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-======================================================================*/
-
-static int axnet_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int axnet_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    DEBUG(2, "axnet_event(0x%06x)\n", event);
-
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	axnet_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int axnet_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		axnet_reset_8390(dev);
-		AX88190_init(dev, 1);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			axnet_reset_8390(dev);
+			AX88190_init(dev, 1);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* axnet_event */
+
+	return 0;
+}
+
 
 /*======================================================================
 
@@ -616,7 +570,7 @@
 
     link->open++;
 
-    request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev);
+    request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, "axnet_cs", dev);
 
     info->link_status = 0x00;
     init_timer(&info->watchdog);
@@ -877,10 +831,11 @@
 	.drv		= {
 		.name	= "axnet_cs",
 	},
-	.attach		= axnet_attach,
-	.event		= axnet_event,
-	.detach		= axnet_detach,
+	.probe		= axnet_attach,
+	.remove		= axnet_detach,
 	.id_table       = axnet_ids,
+	.suspend	= axnet_suspend,
+	.resume		= axnet_resume,
 };
 
 static int __init init_axnet_cs(void)
@@ -891,7 +846,6 @@
 static void __exit exit_axnet_cs(void)
 {
 	pcmcia_unregister_driver(&axnet_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_axnet_cs);
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index b9355d9..2827a48 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -120,15 +120,8 @@
 
 static void com20020_config(dev_link_t *link);
 static void com20020_release(dev_link_t *link);
-static int com20020_event(event_t event, int priority,
-                       event_callback_args_t *args);
 
-static dev_info_t dev_info = "com20020_cs";
-
-static dev_link_t *com20020_attach(void);
-static void com20020_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void com20020_detach(struct pcmcia_device *p_dev);
 
 /*====================================================================*/
 
@@ -145,21 +138,19 @@
 
 ======================================================================*/
 
-static dev_link_t *com20020_attach(void)
+static int com20020_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     com20020_dev_t *info;
     struct net_device *dev;
-    int ret;
     struct arcnet_local *lp;
-    
+
     DEBUG(0, "com20020_attach()\n");
 
     /* Create new network device */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
     if (!link)
-	return NULL;
+	return -ENOMEM;
 
     info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
     if (!info)
@@ -191,30 +182,19 @@
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-
     link->irq.Instance = info->dev = dev;
     link->priv = info;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-        cs_error(link->handle, RegisterClient, ret);
-        com20020_detach(link);
-        return NULL;
-    }
+    link->state |= DEV_PRESENT;
+    com20020_config(link);
 
-    return link;
+    return 0;
 
 fail_alloc_dev:
     kfree(info);
 fail_alloc_info:
     kfree(link);
-    return NULL;
+    return -ENOMEM;
 } /* com20020_attach */
 
 /*======================================================================
@@ -226,29 +206,21 @@
 
 ======================================================================*/
 
-static void com20020_detach(dev_link_t *link)
+static void com20020_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct com20020_dev_t *info = link->priv;
-    dev_link_t **linkp;
-    struct net_device *dev; 
-    
+    struct net_device *dev = info->dev;
+
     DEBUG(1,"detach...\n");
 
     DEBUG(0, "com20020_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-        if (*linkp == link) break;
-    if (*linkp == NULL)
-        return;
-
-    dev = info->dev;
-
     if (link->dev) {
 	DEBUG(1,"unregister...\n");
 
 	unregister_netdev(dev);
-	    
+
 	/*
 	 * this is necessary because we register our IRQ separately
 	 * from card services.
@@ -260,12 +232,8 @@
     if (link->state & DEV_CONFIG)
         com20020_release(link);
 
-    if (link->handle)
-        pcmcia_deregister_client(link->handle);
-
     /* Unlink device structure, free bits */
     DEBUG(1,"unlinking...\n");
-    *linkp = link->next;
     if (link->priv)
     {
 	dev = info->dev;
@@ -421,61 +389,41 @@
     link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
 }
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-======================================================================*/
-
-static int com20020_event(event_t event, int priority,
-			  event_callback_args_t *args)
+static int com20020_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    com20020_dev_t *info = link->priv;
-    struct net_device *dev = info->dev;
+	dev_link_t *link = dev_to_instance(p_dev);
+	com20020_dev_t *info = link->priv;
+	struct net_device *dev = info->dev;
 
-    DEBUG(1, "com20020_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
-        if (link->state & DEV_CONFIG)
-            netif_device_detach(dev);
-        break;
-    case CS_EVENT_CARD_INSERTION:
-        link->state |= DEV_PRESENT;
-	com20020_config(link); 
-	break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
+	link->state |= DEV_SUSPEND;
         if (link->state & DEV_CONFIG) {
-            if (link->open) {
-                netif_device_detach(dev);
-            }
-            pcmcia_release_configuration(link->handle);
+		if (link->open) {
+			netif_device_detach(dev);
+		}
+		pcmcia_release_configuration(link->handle);
         }
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
+
+	return 0;
+}
+
+static int com20020_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	com20020_dev_t *info = link->priv;
+	struct net_device *dev = info->dev;
+
+	link->state &= ~DEV_SUSPEND;
         if (link->state & DEV_CONFIG) {
-            pcmcia_request_configuration(link->handle, &link->conf);
-            if (link->open) {
-		int ioaddr = dev->base_addr;
-		struct arcnet_local *lp = dev->priv;
-		ARCRESET;
-            }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			int ioaddr = dev->base_addr;
+			struct arcnet_local *lp = dev->priv;
+			ARCRESET;
+		}
         }
-        break;
-    }
-    return 0;
-} /* com20020_event */
+
+	return 0;
+}
 
 static struct pcmcia_device_id com20020_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
@@ -488,10 +436,11 @@
 	.drv		= {
 		.name	= "com20020_cs",
 	},
-	.attach		= com20020_attach,
-	.event		= com20020_event,
-	.detach		= com20020_detach,
+	.probe		= com20020_attach,
+	.remove		= com20020_detach,
 	.id_table	= com20020_ids,
+	.suspend	= com20020_suspend,
+	.resume		= com20020_resume,
 };
 
 static int __init init_com20020_cs(void)
@@ -502,7 +451,6 @@
 static void __exit exit_com20020_cs(void)
 {
 	pcmcia_unregister_driver(&com20020_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_com20020_cs);
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 384a736..28fe2fb 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -88,10 +88,7 @@
 static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
 static int fmvj18x_setup_mfc(dev_link_t *link);
 static void fmvj18x_release(dev_link_t *link);
-static int fmvj18x_event(event_t event, int priority,
-			  event_callback_args_t *args);
-static dev_link_t *fmvj18x_attach(void);
-static void fmvj18x_detach(dev_link_t *);
+static void fmvj18x_detach(struct pcmcia_device *p_dev);
 
 /*
     LAN controller(MBH86960A) specific routines
@@ -108,9 +105,6 @@
 static void fjn_tx_timeout(struct net_device *dev);
 static struct ethtool_ops netdev_ethtool_ops;
 
-static dev_info_t dev_info = "fmvj18x_cs";
-static dev_link_t *dev_list;
-
 /*
     card type
  */
@@ -131,10 +125,9 @@
     u_short tx_queue_len;
     cardtype_t cardtype;
     u_short sent;
-    u_char mc_filter[8];
 } local_info_t;
 
-#define MC_FILTERBREAK 8
+#define MC_FILTERBREAK 64
 
 /*====================================================================*/
 /* 
@@ -235,20 +228,18 @@
 #define BANK_1U              0x24 /* bank 1 (CONFIG_1) */
 #define BANK_2U              0x28 /* bank 2 (CONFIG_1) */
 
-static dev_link_t *fmvj18x_attach(void)
+static int fmvj18x_attach(struct pcmcia_device *p_dev)
 {
     local_info_t *lp;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
-    
+
     DEBUG(0, "fmvj18x_attach()\n");
 
     /* Make up a FMVJ18x specific data structure */
     dev = alloc_etherdev(sizeof(local_info_t));
     if (!dev)
-	return NULL;
+	return -ENOMEM;
     lp = netdev_priv(dev);
     link = &lp->link;
     link->priv = dev;
@@ -263,7 +254,7 @@
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &fjn_interrupt;
     link->irq.Instance = dev;
-    
+
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
@@ -282,37 +273,24 @@
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	fmvj18x_detach(link);
-	return NULL;
-    }
 
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    fmvj18x_config(link);
+
+    return 0;
 } /* fmvj18x_attach */
 
 /*====================================================================*/
 
-static void fmvj18x_detach(dev_link_t *link)
+static void fmvj18x_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
-    dev_link_t **linkp;
-    
+
     DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
 
     if (link->dev)
 	unregister_netdev(dev);
@@ -320,12 +298,6 @@
     if (link->state & DEV_CONFIG)
 	fmvj18x_release(link);
 
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
-    /* Unlink device structure, free pieces */
-    *linkp = link->next;
     free_netdev(dev);
 } /* fmvj18x_detach */
 
@@ -714,51 +686,40 @@
     link->state &= ~DEV_CONFIG;
 }
 
-/*====================================================================*/
-
-static int fmvj18x_event(event_t event, int priority,
-			  event_callback_args_t *args)
+static int fmvj18x_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    DEBUG(1, "fmvj18x_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	fmvj18x_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+
+	return 0;
+}
+
+static int fmvj18x_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		fjn_reset(dev);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			fjn_reset(dev);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* fmvj18x_event */
+
+	return 0;
+}
+
+/*====================================================================*/
 
 static struct pcmcia_device_id fmvj18x_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004),
@@ -790,10 +751,11 @@
 	.drv		= {
 		.name	= "fmvj18x_cs",
 	},
-	.attach		= fmvj18x_attach,
-	.event		= fmvj18x_event,
-	.detach		= fmvj18x_detach,
+	.probe		= fmvj18x_attach,
+	.remove		= fmvj18x_detach,
 	.id_table       = fmvj18x_ids,
+	.suspend	= fmvj18x_suspend,
+	.resume		= fmvj18x_resume,
 };
 
 static int __init init_fmvj18x_cs(void)
@@ -804,7 +766,6 @@
 static void __exit exit_fmvj18x_cs(void)
 {
 	pcmcia_unregister_driver(&fmvj18x_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_fmvj18x_cs);
@@ -1005,15 +966,8 @@
     for (i = 0; i < 6; i++) 
         outb(dev->dev_addr[i], ioaddr + NODE_ID + i);
 
-    /* Switch to bank 1 */
-    if (lp->cardtype == MBH10302)
-	outb(BANK_1, ioaddr + CONFIG_1);
-    else
-	outb(BANK_1U, ioaddr + CONFIG_1);
-
-    /* set the multicast table to accept none. */
-    for (i = 0; i < 8; i++) 
-        outb(0x00, ioaddr + MAR_ADR + i);
+    /* (re)initialize the multicast table */
+    set_rx_mode(dev);
 
     /* Switch to bank 2 (runtime mode) */
     if (lp->cardtype == MBH10302)
@@ -1264,11 +1218,11 @@
 static void set_rx_mode(struct net_device *dev)
 {
     kio_addr_t ioaddr = dev->base_addr;
-    struct local_info_t *lp = netdev_priv(dev);
     u_char mc_filter[8];		 /* Multicast hash filter */
     u_long flags;
     int i;
     
+    int saved_bank;
     int saved_config_0 = inb(ioaddr + CONFIG_0);
      
     local_irq_save(flags); 
@@ -1306,15 +1260,13 @@
 	outb(2, ioaddr + RX_MODE);	/* Use normal mode. */
     }
 
-    if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
-	int saved_bank = inb(ioaddr + CONFIG_1);
-	/* Switch to bank 1 and set the multicast table. */
-	outb(0xe4, ioaddr + CONFIG_1);
-	for (i = 0; i < 8; i++)
-	    outb(mc_filter[i], ioaddr + MAR_ADR + i);
-	memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
-	outb(saved_bank, ioaddr + CONFIG_1);
-    }
+    /* Switch to bank 1 and set the multicast table. */
+    saved_bank = inb(ioaddr + CONFIG_1);
+    outb(0xe4, ioaddr + CONFIG_1);
+
+    for (i = 0; i < 8; i++)
+	outb(mc_filter[i], ioaddr + MAR_ADR + i);
+    outb(saved_bank, ioaddr + CONFIG_1);
 
     outb(saved_config_0, ioaddr + CONFIG_0);
 
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index b6c140e..b9c7e39 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -108,15 +108,7 @@
 static void ibmtr_config(dev_link_t *link);
 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
 static void ibmtr_release(dev_link_t *link);
-static int ibmtr_event(event_t event, int priority,
-                       event_callback_args_t *args);
-
-static dev_info_t dev_info = "ibmtr_cs";
-
-static dev_link_t *ibmtr_attach(void);
-static void ibmtr_detach(dev_link_t *);
-
-static dev_link_t *dev_list;
+static void ibmtr_detach(struct pcmcia_device *p_dev);
 
 /*====================================================================*/
 
@@ -146,25 +138,23 @@
 
 ======================================================================*/
 
-static dev_link_t *ibmtr_attach(void)
+static int ibmtr_attach(struct pcmcia_device *p_dev)
 {
     ibmtr_dev_t *info;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
     
     DEBUG(0, "ibmtr_attach()\n");
 
     /* Create new token-ring device */
     info = kmalloc(sizeof(*info), GFP_KERNEL); 
-    if (!info) return NULL;
+    if (!info) return -ENOMEM;
     memset(info,0,sizeof(*info));
     dev = alloc_trdev(sizeof(struct tok_info));
-    if (!dev) { 
-	kfree(info); 
-	return NULL;
-    } 
+    if (!dev) {
+	kfree(info);
+	return -ENOMEM;
+    }
 
     link = &info->link;
     link->priv = info;
@@ -185,25 +175,13 @@
     
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-        cs_error(link->handle, RegisterClient, ret);
-	goto out_detach;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-out:
-    return link;
+    link->state |= DEV_PRESENT;
+    ibmtr_config(link);
 
-out_detach:
-    ibmtr_detach(link);
-    link = NULL;
-    goto out;
+    return 0;
 } /* ibmtr_attach */
 
 /*======================================================================
@@ -215,22 +193,14 @@
 
 ======================================================================*/
 
-static void ibmtr_detach(dev_link_t *link)
+static void ibmtr_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct ibmtr_dev_t *info = link->priv;
-    dev_link_t **linkp;
-    struct net_device *dev;
+    struct net_device *dev = info->dev;
 
     DEBUG(0, "ibmtr_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-        if (*linkp == link) break;
-    if (*linkp == NULL)
-        return;
-
-    dev = info->dev;
-
     if (link->dev)
 	unregister_netdev(dev);
 
@@ -241,13 +211,8 @@
     if (link->state & DEV_CONFIG)
         ibmtr_release(link);
 
-    if (link->handle)
-        pcmcia_deregister_client(link->handle);
-
-    /* Unlink device structure, free bits */
-    *linkp = link->next;
     free_netdev(dev);
-    kfree(info); 
+    kfree(info);
 } /* ibmtr_detach */
 
 /*======================================================================
@@ -401,63 +366,40 @@
     link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-======================================================================*/
-
-static int ibmtr_event(event_t event, int priority,
-                       event_callback_args_t *args)
+static int ibmtr_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    ibmtr_dev_t *info = link->priv;
-    struct net_device *dev = info->dev;
+	dev_link_t *link = dev_to_instance(p_dev);
+	ibmtr_dev_t *info = link->priv;
+	struct net_device *dev = info->dev;
 
-    DEBUG(1, "ibmtr_event(0x%06x)\n", event);
+	link->state |= DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
+        }
 
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
+	return 0;
+}
+
+static int ibmtr_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	ibmtr_dev_t *info = link->priv;
+	struct net_device *dev = info->dev;
+
+	link->state &= ~DEV_SUSPEND;
         if (link->state & DEV_CONFIG) {
-	    /* set flag to bypass normal interrupt code */
-	    struct tok_info *priv = netdev_priv(dev);
-	    priv->sram_phys |= 1;
-	    netif_device_detach(dev);
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			ibmtr_probe(dev);	/* really? */
+			netif_device_attach(dev);
+		}
         }
-        break;
-    case CS_EVENT_CARD_INSERTION:
-        link->state |= DEV_PRESENT;
-	ibmtr_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        if (link->state & DEV_CONFIG) {
-            if (link->open)
-		netif_device_detach(dev);
-            pcmcia_release_configuration(link->handle);
-        }
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-        if (link->state & DEV_CONFIG) {
-            pcmcia_request_configuration(link->handle, &link->conf);
-            if (link->open) {
-		ibmtr_probe(dev);	/* really? */
-		netif_device_attach(dev);
-            }
-        }
-        break;
-    }
-    return 0;
-} /* ibmtr_event */
+
+	return 0;
+}
+
 
 /*====================================================================*/
 
@@ -514,10 +456,11 @@
 	.drv		= {
 		.name	= "ibmtr_cs",
 	},
-	.attach		= ibmtr_attach,
-	.event		= ibmtr_event,
-	.detach		= ibmtr_detach,
+	.probe		= ibmtr_attach,
+	.remove		= ibmtr_detach,
 	.id_table       = ibmtr_ids,
+	.suspend	= ibmtr_suspend,
+	.resume		= ibmtr_resume,
 };
 
 static int __init init_ibmtr_cs(void)
@@ -528,7 +471,6 @@
 static void __exit exit_ibmtr_cs(void)
 {
 	pcmcia_unregister_driver(&ibmtr_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_ibmtr_cs);
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 980d7e5..4a23225 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -388,9 +388,6 @@
 DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
 #endif
 
-static dev_info_t dev_info="nmclan_cs";
-static dev_link_t *dev_list;
-
 static char *if_names[]={
     "Auto", "10baseT", "BNC",
 };
@@ -422,8 +419,6 @@
 
 static void nmclan_config(dev_link_t *link);
 static void nmclan_release(dev_link_t *link);
-static int nmclan_event(event_t event, int priority,
-			event_callback_args_t *args);
 
 static void nmclan_reset(struct net_device *dev);
 static int mace_config(struct net_device *dev, struct ifmap *map);
@@ -439,8 +434,7 @@
 static struct ethtool_ops netdev_ethtool_ops;
 
 
-static dev_link_t *nmclan_attach(void);
-static void nmclan_detach(dev_link_t *);
+static void nmclan_detach(struct pcmcia_device *p_dev);
 
 /* ----------------------------------------------------------------------------
 nmclan_attach
@@ -449,13 +443,11 @@
 	Services.
 ---------------------------------------------------------------------------- */
 
-static dev_link_t *nmclan_attach(void)
+static int nmclan_attach(struct pcmcia_device *p_dev)
 {
     mace_private *lp;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
 
     DEBUG(0, "nmclan_attach()\n");
     DEBUG(1, "%s\n", rcsid);
@@ -463,7 +455,7 @@
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(mace_private));
     if (!dev)
-	return NULL;
+	    return -ENOMEM;
     lp = netdev_priv(dev);
     link = &lp->link;
     link->priv = dev;
@@ -497,20 +489,13 @@
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	nmclan_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    nmclan_config(link);
+
+    return 0;
 } /* nmclan_attach */
 
 /* ----------------------------------------------------------------------------
@@ -521,30 +506,19 @@
 	when the device is released.
 ---------------------------------------------------------------------------- */
 
-static void nmclan_detach(dev_link_t *link)
+static void nmclan_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
-    dev_link_t **linkp;
 
     DEBUG(0, "nmclan_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
-
     if (link->dev)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
 	nmclan_release(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-
-    /* Unlink device structure, free bits */
-    *linkp = link->next;
     free_netdev(dev);
 } /* nmclan_detach */
 
@@ -801,59 +775,39 @@
   link->state &= ~DEV_CONFIG;
 }
 
-/* ----------------------------------------------------------------------------
-nmclan_event
-	The card status event handler.  Mostly, this schedules other
-	stuff to run after an event is received.  A CARD_REMOVAL event
-	also sets some flags to discourage the net drivers from trying
-	to talk to the card any more.
----------------------------------------------------------------------------- */
-static int nmclan_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int nmclan_suspend(struct pcmcia_device *p_dev)
 {
-  dev_link_t *link = args->client_data;
-  struct net_device *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-  DEBUG(1, "nmclan_event(0x%06x)\n", event);
-
-  switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-      link->state &= ~DEV_PRESENT;
-      if (link->state & DEV_CONFIG)
-	netif_device_detach(dev);
-      break;
-    case CS_EVENT_CARD_INSERTION:
-      link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-      nmclan_config(link);
-      break;
-    case CS_EVENT_PM_SUSPEND:
-      link->state |= DEV_SUSPEND;
-      /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-      if (link->state & DEV_CONFIG) {
-	if (link->open)
-	  netif_device_detach(dev);
-	pcmcia_release_configuration(link->handle);
-      }
-      break;
-    case CS_EVENT_PM_RESUME:
-      link->state &= ~DEV_SUSPEND;
-      /* Fall through... */
-    case CS_EVENT_CARD_RESET:
-      if (link->state & DEV_CONFIG) {
-	pcmcia_request_configuration(link->handle, &link->conf);
-	if (link->open) {
-	  nmclan_reset(dev);
-	  netif_device_attach(dev);
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-      }
-      break;
-    case CS_EVENT_RESET_REQUEST:
-      return 1;
-      break;
-  }
-  return 0;
-} /* nmclan_event */
+
+
+	return 0;
+}
+
+static int nmclan_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			nmclan_reset(dev);
+			netif_device_attach(dev);
+		}
+	}
+
+	return 0;
+}
+
 
 /* ----------------------------------------------------------------------------
 nmclan_reset
@@ -1681,10 +1635,11 @@
 	.drv		= {
 		.name	= "nmclan_cs",
 	},
-	.attach		= nmclan_attach,
-	.event		= nmclan_event,
-	.detach		= nmclan_detach,
+	.probe		= nmclan_attach,
+	.remove		= nmclan_detach,
 	.id_table       = nmclan_ids,
+	.suspend	= nmclan_suspend,
+	.resume		= nmclan_resume,
 };
 
 static int __init init_nmclan_cs(void)
@@ -1695,7 +1650,6 @@
 static void __exit exit_nmclan_cs(void)
 {
 	pcmcia_unregister_driver(&nmclan_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_nmclan_cs);
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 818c185..d85b758f3 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -105,8 +105,6 @@
 static void mii_phy_probe(struct net_device *dev);
 static void pcnet_config(dev_link_t *link);
 static void pcnet_release(dev_link_t *link);
-static int pcnet_event(event_t event, int priority,
-		       event_callback_args_t *args);
 static int pcnet_open(struct net_device *dev);
 static int pcnet_close(struct net_device *dev);
 static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -120,11 +118,9 @@
 static int setup_dma_config(dev_link_t *link, int start_pg,
 			    int stop_pg);
 
-static dev_link_t *pcnet_attach(void);
-static void pcnet_detach(dev_link_t *);
+static void pcnet_detach(struct pcmcia_device *p_dev);
 
 static dev_info_t dev_info = "pcnet_cs";
-static dev_link_t *dev_list;
 
 /*====================================================================*/
 
@@ -244,19 +240,17 @@
 
 ======================================================================*/
 
-static dev_link_t *pcnet_attach(void)
+static int pcnet_probe(struct pcmcia_device *p_dev)
 {
     pcnet_dev_t *info;
     dev_link_t *link;
     struct net_device *dev;
-    client_reg_t client_reg;
-    int ret;
 
     DEBUG(0, "pcnet_attach()\n");
 
     /* Create new ethernet device */
     dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
-    if (!dev) return NULL;
+    if (!dev) return -ENOMEM;
     info = PRIV(dev);
     link = &info->link;
     link->priv = dev;
@@ -271,20 +265,13 @@
     dev->stop = &pcnet_close;
     dev->set_config = &set_config;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	pcnet_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    pcnet_config(link);
+
+    return 0;
 } /* pcnet_attach */
 
 /*======================================================================
@@ -296,31 +283,20 @@
 
 ======================================================================*/
 
-static void pcnet_detach(dev_link_t *link)
+static void pcnet_detach(struct pcmcia_device *p_dev)
 {
-    struct net_device *dev = link->priv;
-    dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    DEBUG(0, "pcnet_detach(0x%p)\n", link);
+	DEBUG(0, "pcnet_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
+	if (link->dev)
+		unregister_netdev(dev);
 
-    if (link->dev)
-	unregister_netdev(dev);
+	if (link->state & DEV_CONFIG)
+		pcnet_release(link);
 
-    if (link->state & DEV_CONFIG)
-	pcnet_release(link);
-
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-
-    /* Unlink device structure, free bits */
-    *linkp = link->next;
-    free_netdev(dev);
+	free_netdev(dev);
 } /* pcnet_detach */
 
 /*======================================================================
@@ -780,50 +756,39 @@
 
 ======================================================================*/
 
-static int pcnet_event(event_t event, int priority,
-		       event_callback_args_t *args)
+static int pcnet_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    DEBUG(2, "pcnet_event(0x%06x)\n", event);
-
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	pcnet_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int pcnet_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		pcnet_reset_8390(dev);
-		NS8390_init(dev, 1);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			pcnet_reset_8390(dev);
+			NS8390_init(dev, 1);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* pcnet_event */
+
+	return 0;
+}
+
 
 /*======================================================================
 
@@ -1844,11 +1809,12 @@
 	.drv		= {
 		.name	= "pcnet_cs",
 	},
-	.attach		= pcnet_attach,
-	.event		= pcnet_event,
-	.detach		= pcnet_detach,
+	.probe		= pcnet_probe,
+	.remove		= pcnet_detach,
 	.owner		= THIS_MODULE,
 	.id_table	= pcnet_ids,
+	.suspend	= pcnet_suspend,
+	.resume		= pcnet_resume,
 };
 
 static int __init init_pcnet_cs(void)
@@ -1860,7 +1826,6 @@
 {
     DEBUG(0, "pcnet_cs: unloading\n");
     pcmcia_unregister_driver(&pcnet_driver);
-    BUG_ON(dev_list != NULL);
 }
 
 module_init(init_pcnet_cs);
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index c7cca84..0122415df 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -102,10 +102,6 @@
    currently have room for another Tx packet. */
 #define MEMORY_WAIT_TIME       	8
 
-static dev_info_t dev_info = "smc91c92_cs";
-
-static dev_link_t *dev_list;
-
 struct smc_private {
     dev_link_t			link;
     spinlock_t			lock;
@@ -281,12 +277,9 @@
 
 /*====================================================================*/
 
-static dev_link_t *smc91c92_attach(void);
-static void smc91c92_detach(dev_link_t *);
+static void smc91c92_detach(struct pcmcia_device *p_dev);
 static void smc91c92_config(dev_link_t *link);
 static void smc91c92_release(dev_link_t *link);
-static int smc91c92_event(event_t event, int priority,
-			  event_callback_args_t *args);
 
 static int smc_open(struct net_device *dev);
 static int smc_close(struct net_device *dev);
@@ -315,20 +308,18 @@
 
 ======================================================================*/
 
-static dev_link_t *smc91c92_attach(void)
+static int smc91c92_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     struct smc_private *smc;
     dev_link_t *link;
     struct net_device *dev;
-    int ret;
 
     DEBUG(0, "smc91c92_attach()\n");
 
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(struct smc_private));
     if (!dev)
-	return NULL;
+	return -ENOMEM;
     smc = netdev_priv(dev);
     link = &smc->link;
     link->priv = dev;
@@ -366,20 +357,13 @@
     smc->mii_if.phy_id_mask = 0x1f;
     smc->mii_if.reg_num_mask = 0x1f;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	smc91c92_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    smc91c92_config(link);
+
+    return 0;
 } /* smc91c92_attach */
 
 /*======================================================================
@@ -391,30 +375,19 @@
 
 ======================================================================*/
 
-static void smc91c92_detach(dev_link_t *link)
+static void smc91c92_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
-    dev_link_t **linkp;
 
     DEBUG(0, "smc91c92_detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
-
     if (link->dev)
 	unregister_netdev(dev);
 
     if (link->state & DEV_CONFIG)
 	smc91c92_release(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-
-    /* Unlink device structure, free bits */
-    *linkp = link->next;
     free_netdev(dev);
 } /* smc91c92_detach */
 
@@ -895,6 +868,62 @@
    return rc;
 }
 
+static int smc91c92_suspend(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
+	}
+
+	return 0;
+}
+
+static int smc91c92_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+	struct smc_private *smc = netdev_priv(dev);
+	int i;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		if ((smc->manfid == MANFID_MEGAHERTZ) &&
+		    (smc->cardid == PRODID_MEGAHERTZ_EM3288))
+			mhz_3288_power(link);
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (smc->manfid == MANFID_MOTOROLA)
+			mot_config(link);
+		if ((smc->manfid == MANFID_OSITECH) &&
+		    (smc->cardid != PRODID_OSITECH_SEVEN)) {
+			/* Power up the card and enable interrupts */
+			set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
+			set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
+		}
+		if (((smc->manfid == MANFID_OSITECH) &&
+		     (smc->cardid == PRODID_OSITECH_SEVEN)) ||
+		    ((smc->manfid == MANFID_PSION) &&
+		     (smc->cardid == PRODID_PSION_NET100))) {
+			/* Download the Seven of Diamonds firmware */
+			for (i = 0; i < sizeof(__Xilinx7OD); i++) {
+				outb(__Xilinx7OD[i], link->io.BasePort1+2);
+				udelay(50);
+			}
+		}
+		if (link->open) {
+			smc_reset(dev);
+			netif_device_attach(dev);
+		}
+	}
+
+	return 0;
+}
+
+
 /*======================================================================
 
     This verifies that the chip is some SMC91cXX variant, and returns
@@ -935,14 +964,12 @@
     }
 
     if (width) {
-	event_callback_args_t args;
 	printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
-	args.client_data = link;
-	smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
+	smc91c92_suspend(link->handle);
 	pcmcia_release_io(link->handle, &link->io);
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	pcmcia_request_io(link->handle, &link->io);
-	smc91c92_event(CS_EVENT_CARD_RESET, 0, &args);
+	smc91c92_resume(link->handle);
 	return check_sig(link);
     }
     return -ENODEV;
@@ -1172,82 +1199,6 @@
 
 /*======================================================================
 
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-======================================================================*/
-
-static int smc91c92_event(event_t event, int priority,
-			  event_callback_args_t *args)
-{
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
-    struct smc_private *smc = netdev_priv(dev);
-    int i;
-
-    DEBUG(1, "smc91c92_event(0x%06x)\n", event);
-
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	smc91c92_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
-	}
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (link->state & DEV_CONFIG) {
-	    if ((smc->manfid == MANFID_MEGAHERTZ) &&
-		(smc->cardid == PRODID_MEGAHERTZ_EM3288))
-		mhz_3288_power(link);
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (smc->manfid == MANFID_MOTOROLA)
-		mot_config(link);
-	    if ((smc->manfid == MANFID_OSITECH) &&
-		(smc->cardid != PRODID_OSITECH_SEVEN)) {
-		/* Power up the card and enable interrupts */
-		set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
-		set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
-	    }
-	    if (((smc->manfid == MANFID_OSITECH) &&
-	 	(smc->cardid == PRODID_OSITECH_SEVEN)) ||
-		((smc->manfid == MANFID_PSION) &&
-	 	(smc->cardid == PRODID_PSION_NET100))) {
-		/* Download the Seven of Diamonds firmware */
-		for (i = 0; i < sizeof(__Xilinx7OD); i++) {
-	    	    outb(__Xilinx7OD[i], link->io.BasePort1+2);
-	   	    udelay(50);
-		}
-	    }
-	    if (link->open) {
-		smc_reset(dev);
-		netif_device_attach(dev);
-	    }
-	}
-	break;
-    }
-    return 0;
-} /* smc91c92_event */
-
-/*======================================================================
-
     MII interface support for SMC91cXX based cards
 ======================================================================*/
 
@@ -2360,10 +2311,11 @@
 	.drv		= {
 		.name	= "smc91c92_cs",
 	},
-	.attach		= smc91c92_attach,
-	.event		= smc91c92_event,
-	.detach		= smc91c92_detach,
+	.probe		= smc91c92_attach,
+	.remove		= smc91c92_detach,
 	.id_table       = smc91c92_ids,
+	.suspend	= smc91c92_suspend,
+	.resume		= smc91c92_resume,
 };
 
 static int __init init_smc91c92_cs(void)
@@ -2374,7 +2326,6 @@
 static void __exit exit_smc91c92_cs(void)
 {
 	pcmcia_unregister_driver(&smc91c92_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_smc91c92_cs);
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index ce143f0..049c34b3 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -292,8 +292,6 @@
 static int has_ce2_string(dev_link_t * link);
 static void xirc2ps_config(dev_link_t * link);
 static void xirc2ps_release(dev_link_t * link);
-static int xirc2ps_event(event_t event, int priority,
-			 event_callback_args_t * args);
 
 /****************
  * The attach() and detach() entry points are used to create and destroy
@@ -301,8 +299,7 @@
  * needed to manage one actual PCMCIA card.
  */
 
-static dev_link_t *xirc2ps_attach(void);
-static void xirc2ps_detach(dev_link_t *);
+static void xirc2ps_detach(struct pcmcia_device *p_dev);
 
 /****************
  * You'll also need to prototype all the functions that will actually
@@ -313,14 +310,6 @@
 
 static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card configuration
- * database.
- */
-
-static dev_info_t dev_info = "xirc2ps_cs";
-
 /****************
  * A linked list of "instances" of the device.  Each actual
  * PCMCIA card corresponds to one device instance, and is described
@@ -331,15 +320,7 @@
  * device numbers are used to derive the corresponding array index.
  */
 
-static dev_link_t *dev_list;
-
 /****************
- * A dev_link_t structure has fields for most things that are needed
- * to keep track of a socket, but there will usually be some device
- * specific information that also needs to be kept track of.  The
- * 'priv' pointer in a dev_link_t structure can be used to point to
- * a device-specific private data structure, like this.
- *
  * A driver needs to provide a dev_node_t structure for each device
  * on a card.  In some cases, there is only one device per card (for
  * example, ethernet cards, modems).  In other cases, there may be
@@ -571,21 +552,19 @@
  * card insertion event.
  */
 
-static dev_link_t *
-xirc2ps_attach(void)
+static int
+xirc2ps_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     struct net_device *dev;
     local_info_t *local;
-    int err;
 
     DEBUG(0, "attach()\n");
 
     /* Allocate the device structure */
     dev = alloc_etherdev(sizeof(local_info_t));
     if (!dev)
-	    return NULL;
+	    return -ENOMEM;
     local = netdev_priv(dev);
     link = &local->link;
     link->priv = dev;
@@ -614,19 +593,13 @@
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    if ((err = pcmcia_register_client(&link->handle, &client_reg))) {
-	cs_error(link->handle, RegisterClient, err);
-	xirc2ps_detach(link);
-	return NULL;
-    }
+    link->handle = p_dev;
+    p_dev->instance = link;
 
-    return link;
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    xirc2ps_config(link);
+
+    return 0;
 } /* xirc2ps_attach */
 
 /****************
@@ -637,40 +610,19 @@
  */
 
 static void
-xirc2ps_detach(dev_link_t * link)
+xirc2ps_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     struct net_device *dev = link->priv;
-    dev_link_t **linkp;
 
     DEBUG(0, "detach(0x%p)\n", link);
 
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link)
-	    break;
-    if (!*linkp) {
-	DEBUG(0, "detach(0x%p): dev_link lost\n", link);
-	return;
-    }
-
     if (link->dev)
 	unregister_netdev(dev);
 
-    /*
-     * If the device is currently configured and active, we won't
-     * actually delete it yet.	Instead, it is marked so that when
-     * the release() function is called, that will trigger a proper
-     * detach().
-     */
     if (link->state & DEV_CONFIG)
 	xirc2ps_release(link);
 
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-
-    /* Unlink device structure, free it */
-    *linkp = link->next;
     free_netdev(dev);
 } /* xirc2ps_detach */
 
@@ -1157,67 +1109,41 @@
 
 /*====================================================================*/
 
-/****************
- * The card status event handler.  Mostly, this schedules other
- * stuff to run after an event is received.  A CARD_REMOVAL event
- * also sets some flags to discourage the net drivers from trying
- * to talk to the card any more.
- *
- * When a CARD_REMOVAL event is received, we immediately set a flag
- * to block future accesses to this device.  All the functions that
- * actually access the device should check this flag to make sure
- * the card is still present.
- */
 
-static int
-xirc2ps_event(event_t event, int priority,
-	      event_callback_args_t * args)
+static int xirc2ps_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    DEBUG(0, "event(%d)\n", (int)event);
-
-    switch (event) {
-    case CS_EVENT_REGISTRATION_COMPLETE:
-	DEBUG(0, "registration complete\n");
-	break;
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    netif_device_detach(dev);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	xirc2ps_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open) {
-		netif_device_detach(dev);
-		do_powerdown(dev);
-	    }
-	    pcmcia_release_configuration(link->handle);
+		if (link->open) {
+			netif_device_detach(dev);
+			do_powerdown(dev);
+		}
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int xirc2ps_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		do_reset(dev,1);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			do_reset(dev,1);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* xirc2ps_event */
+
+	return 0;
+}
+
 
 /*====================================================================*/
 
@@ -2009,10 +1935,11 @@
 	.drv		= {
 		.name	= "xirc2ps_cs",
 	},
-	.attach		= xirc2ps_attach,
-	.event		= xirc2ps_event,
-	.detach		= xirc2ps_detach,
+	.probe		= xirc2ps_attach,
+	.remove		= xirc2ps_detach,
 	.id_table       = xirc2ps_ids,
+	.suspend	= xirc2ps_suspend,
+	.resume		= xirc2ps_resume,
 };
 
 static int __init
@@ -2025,7 +1952,6 @@
 exit_xirc2ps_cs(void)
 {
 	pcmcia_unregister_driver(&xirc2ps_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_xirc2ps_cs);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index be31922..8f6cf8c 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -1251,12 +1251,7 @@
 
     if (memcmp(promaddr, dev->dev_addr, 6)
 	|| !is_valid_ether_addr(dev->dev_addr)) {
-#ifndef __powerpc__
 	if (is_valid_ether_addr(promaddr)) {
-#else
-	if (!is_valid_ether_addr(dev->dev_addr)
-	    && is_valid_ether_addr(promaddr)) {
-#endif
 	    if (pcnet32_debug & NETIF_MSG_PROBE) {
 		printk(" warning: CSR address invalid,\n");
 		printk(KERN_INFO "    using instead PROM address of");
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index c782a63..fa39b94 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -6,7 +6,7 @@
 
 config PHYLIB
 	tristate "PHY Device support and infrastructure"
-	depends on NET_ETHERNET && (BROKEN || !ARCH_S390)
+	depends on NET_ETHERNET && (BROKEN || !S390)
 	help
 	  Ethernet controllers are usually attached to PHY
 	  devices.  This option provides infrastructure for
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 16bebe7..7da0e3d 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -38,6 +38,10 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
+MODULE_DESCRIPTION("PHY library");
+MODULE_AUTHOR("Andy Fleming");
+MODULE_LICENSE("GPL");
+
 static struct phy_driver genphy_driver;
 extern int mdio_bus_init(void);
 extern void mdio_bus_exit(void);
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index 1bd22cd..87ee327 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -98,7 +98,6 @@
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
-#include <linux/lp.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -106,7 +105,6 @@
 #include <linux/skbuff.h>
 #include <linux/if_plip.h>
 #include <linux/workqueue.h>
-#include <linux/ioport.h>
 #include <linux/spinlock.h>
 #include <linux/parport.h>
 #include <linux/bitops.h>
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 50430f7..1c6d328 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -524,9 +524,6 @@
 	if (copy_from_user(&uprog, arg, sizeof(uprog)))
 		return -EFAULT;
 
-	if (uprog.len > BPF_MAXINSNS)
-		return -EINVAL;
-
 	if (!uprog.len) {
 		*p = NULL;
 		return 0;
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index a842ecc..9369f81 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -85,7 +85,7 @@
 static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb);
 static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
 
-static struct proto_ops pppoe_ops;
+static const struct proto_ops pppoe_ops;
 static DEFINE_RWLOCK(pppoe_hash_lock);
 
 static struct ppp_channel_ops pppoe_chan_ops;
@@ -383,8 +383,6 @@
 {
 	struct pppoe_hdr *ph;
 	struct pppox_sock *po;
-	struct sock *sk;
-	int ret;
 
 	if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
 		goto drop;
@@ -395,24 +393,8 @@
 	ph = (struct pppoe_hdr *) skb->nh.raw;
 
 	po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source);
-	if (!po) 
-		goto drop;
-
-	sk = sk_pppox(po);
-	bh_lock_sock(sk);
-
-	/* Socket state is unknown, must put skb into backlog. */
-	if (sock_owned_by_user(sk) != 0) {
-		sk_add_backlog(sk, skb);
-		ret = NET_RX_SUCCESS;
-	} else {
-		ret = pppoe_rcv_core(sk, skb);
-	}
-
-	bh_unlock_sock(sk);
-	sock_put(sk);
-
-	return ret;
+	if (po != NULL) 
+		return sk_receive_skb(sk_pppox(po), skb);
 drop:
 	kfree_skb(skb);
 out:
@@ -1081,9 +1063,7 @@
 static inline int pppoe_proc_init(void) { return 0; }
 #endif /* CONFIG_PROC_FS */
 
-/* ->ioctl are set at pppox_create */
-
-static struct proto_ops pppoe_ops = {
+static const struct proto_ops pppoe_ops = {
     .family		= AF_PPPOX,
     .owner		= THIS_MODULE,
     .release		= pppoe_release,
@@ -1099,7 +1079,8 @@
     .getsockopt		= sock_no_getsockopt,
     .sendmsg		= pppoe_sendmsg,
     .recvmsg		= pppoe_recvmsg,
-    .mmap		= sock_no_mmap
+    .mmap		= sock_no_mmap,
+    .ioctl		= pppox_ioctl,
 };
 
 static struct pppox_proto pppoe_proto = {
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index 0c1e114..9315046 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -68,8 +68,7 @@
 EXPORT_SYMBOL(unregister_pppox_proto);
 EXPORT_SYMBOL(pppox_unbind_sock);
 
-static int pppox_ioctl(struct socket* sock, unsigned int cmd, 
-		       unsigned long arg)
+int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	struct sock *sk = sock->sk;
 	struct pppox_sock *po = pppox_sk(sk);
@@ -105,6 +104,7 @@
 	return rc;
 }
 
+EXPORT_SYMBOL(pppox_ioctl);
 
 static int pppox_create(struct socket *sock, int protocol)
 {
@@ -119,11 +119,7 @@
 		goto out;
 
 	rc = pppox_protos[protocol]->create(sock);
-	if (!rc) {
-		/* We get to set the ioctl handler. */
-		/* For everything else, pppox is just a shell. */
-		sock->ops->ioctl = pppox_ioctl;
-	}
+
 	module_put(pppox_protos[protocol]->owner);
 out:
 	return rc;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index e57df8d..89c4678 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -66,7 +66,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "Version 2.0.9.3"
+#define DRV_VERSION "Version 2.0.9.4"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -412,7 +412,7 @@
 		    config->tx_cfg[i].fifo_len - 1;
 		mac_control->fifos[i].fifo_no = i;
 		mac_control->fifos[i].nic = nic;
-		mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 1;
+		mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 2;
 
 		for (j = 0; j < page_num; j++) {
 			int k = 0;
@@ -459,6 +459,10 @@
 		}
 	}
 
+	nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL);
+	if (!nic->ufo_in_band_v)
+		return -ENOMEM;
+
 	/* Allocation and initialization of RXDs in Rings */
 	size = 0;
 	for (i = 0; i < config->rx_ring_num; i++) {
@@ -731,6 +735,8 @@
 				    mac_control->stats_mem,
 				    mac_control->stats_mem_phy);
 	}
+	if (nic->ufo_in_band_v)
+		kfree(nic->ufo_in_band_v);
 }
 
 /**
@@ -2003,6 +2009,49 @@
 
 	return SUCCESS;
 }
+/**
+ * s2io_txdl_getskb - Get the skb from txdl, unmap and return skb
+ */
+static struct sk_buff *s2io_txdl_getskb(fifo_info_t *fifo_data, TxD_t *txdlp, int get_off)
+{
+	nic_t *nic = fifo_data->nic;
+	struct sk_buff *skb;
+	TxD_t *txds;
+	u16 j, frg_cnt;
+
+	txds = txdlp;
+	if (txds->Host_Control == (u64)(long)nic->ufo_in_band_v) {
+		pci_unmap_single(nic->pdev, (dma_addr_t)
+			txds->Buffer_Pointer, sizeof(u64),
+			PCI_DMA_TODEVICE);
+		txds++;
+	}
+
+	skb = (struct sk_buff *) ((unsigned long)
+			txds->Host_Control);
+	if (!skb) {
+		memset(txdlp, 0, (sizeof(TxD_t) * fifo_data->max_txds));
+		return NULL;
+	}
+	pci_unmap_single(nic->pdev, (dma_addr_t)
+			 txds->Buffer_Pointer,
+			 skb->len - skb->data_len,
+			 PCI_DMA_TODEVICE);
+	frg_cnt = skb_shinfo(skb)->nr_frags;
+	if (frg_cnt) {
+		txds++;
+		for (j = 0; j < frg_cnt; j++, txds++) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[j];
+			if (!txds->Buffer_Pointer)
+				break;
+			pci_unmap_page(nic->pdev, (dma_addr_t) 
+					txds->Buffer_Pointer,
+				       frag->size, PCI_DMA_TODEVICE);
+		}
+	}
+	txdlp->Host_Control = 0;
+	return(skb);
+}
 
 /**
  *  free_tx_buffers - Free all queued Tx buffers
@@ -2020,7 +2069,7 @@
 	int i, j;
 	mac_info_t *mac_control;
 	struct config_param *config;
-	int cnt = 0, frg_cnt;
+	int cnt = 0;
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
@@ -2029,38 +2078,11 @@
 		for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
 			txdp = (TxD_t *) mac_control->fifos[i].list_info[j].
 			    list_virt_addr;
-			skb =
-			    (struct sk_buff *) ((unsigned long) txdp->
-						Host_Control);
-			if (skb == NULL) {
-				memset(txdp, 0, sizeof(TxD_t) *
-				       config->max_txds);
-				continue;
+			skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
+			if (skb) {
+				dev_kfree_skb(skb);
+				cnt++;
 			}
-			frg_cnt = skb_shinfo(skb)->nr_frags;
-			pci_unmap_single(nic->pdev, (dma_addr_t)
-					 txdp->Buffer_Pointer,
-					 skb->len - skb->data_len,
-					 PCI_DMA_TODEVICE);
-			if (frg_cnt) {
-				TxD_t *temp;
-				temp = txdp;
-				txdp++;
-				for (j = 0; j < frg_cnt; j++, txdp++) {
-					skb_frag_t *frag =
-					    &skb_shinfo(skb)->frags[j];
-					pci_unmap_page(nic->pdev,
-						       (dma_addr_t)
-						       txdp->
-						       Buffer_Pointer,
-						       frag->size,
-						       PCI_DMA_TODEVICE);
-				}
-				txdp = temp;
-			}
-			dev_kfree_skb(skb);
-			memset(txdp, 0, sizeof(TxD_t) * config->max_txds);
-			cnt++;
 		}
 		DBG_PRINT(INTR_DBG,
 			  "%s:forcibly freeing %d skbs on FIFO%d\n",
@@ -2661,7 +2683,6 @@
 	tx_curr_get_info_t get_info, put_info;
 	struct sk_buff *skb;
 	TxD_t *txdlp;
-	u16 j, frg_cnt;
 
 	get_info = fifo_data->tx_curr_get_info;
 	put_info = fifo_data->tx_curr_put_info;
@@ -2684,8 +2705,7 @@
 			}
 		}
 
-		skb = (struct sk_buff *) ((unsigned long)
-				txdlp->Host_Control);
+		skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset);
 		if (skb == NULL) {
 			DBG_PRINT(ERR_DBG, "%s: Null skb ",
 			__FUNCTION__);
@@ -2693,34 +2713,6 @@
 			return;
 		}
 
-		frg_cnt = skb_shinfo(skb)->nr_frags;
-		nic->tx_pkt_count++;
-
-		pci_unmap_single(nic->pdev, (dma_addr_t)
-				 txdlp->Buffer_Pointer,
-				 skb->len - skb->data_len,
-				 PCI_DMA_TODEVICE);
-		if (frg_cnt) {
-			TxD_t *temp;
-			temp = txdlp;
-			txdlp++;
-			for (j = 0; j < frg_cnt; j++, txdlp++) {
-				skb_frag_t *frag =
-				    &skb_shinfo(skb)->frags[j];
-				if (!txdlp->Buffer_Pointer)
-					break;
-				pci_unmap_page(nic->pdev,
-					       (dma_addr_t)
-					       txdlp->
-					       Buffer_Pointer,
-					       frag->size,
-					       PCI_DMA_TODEVICE);
-			}
-			txdlp = temp;
-		}
-		memset(txdlp, 0,
-		       (sizeof(TxD_t) * fifo_data->max_txds));
-
 		/* Updating the statistics block */
 		nic->stats.tx_bytes += skb->len;
 		dev_kfree_skb_irq(skb);
@@ -3078,7 +3070,7 @@
 
 static int wait_for_msix_trans(nic_t *nic, int i)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u64 val64;
 	int ret = 0, cnt = 0;
 
@@ -3099,7 +3091,7 @@
 
 void restore_xmsi_data(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u64 val64;
 	int i;
 
@@ -3117,7 +3109,7 @@
 
 static void store_xmsi_data(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u64 val64, addr, data;
 	int i;
 
@@ -3140,7 +3132,7 @@
 
 int s2io_enable_msi(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u16 msi_ctrl, msg_val;
 	struct config_param *config = &nic->config;
 	struct net_device *dev = nic->dev;
@@ -3190,7 +3182,7 @@
 
 int s2io_enable_msi_x(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u64 tx_mat, rx_mat;
 	u16 msi_control; /* Temp variable */
 	int ret, i, j, msix_indx = 1;
@@ -3331,7 +3323,7 @@
 					  s2io_msix_fifo_handle, 0, sp->desc1,
 					  sp->s2io_entries[i].arg);
 				DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc1, 
-							sp->msix_info[i].addr);
+				    (unsigned long long)sp->msix_info[i].addr);
 			} else {
 				sprintf(sp->desc2, "%s:MSI-X-%d-RX",
 					dev->name, i);
@@ -3339,7 +3331,7 @@
 					  s2io_msix_ring_handle, 0, sp->desc2,
 					  sp->s2io_entries[i].arg);
 				DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc2, 
-							sp->msix_info[i].addr);
+				     (unsigned long long)sp->msix_info[i].addr);
 			}
 			if (err) {
 				DBG_PRINT(ERR_DBG, "%s: MSI-X-%d registration \
@@ -3527,6 +3519,8 @@
 		return 0;
 	}
 
+	txdp->Control_1 = 0;
+	txdp->Control_2 = 0;
 #ifdef NETIF_F_TSO
 	mss = skb_shinfo(skb)->tso_size;
 	if (mss) {
@@ -3534,19 +3528,13 @@
 		txdp->Control_1 |= TXD_TCP_LSO_MSS(mss);
 	}
 #endif
-
-	frg_cnt = skb_shinfo(skb)->nr_frags;
-	frg_len = skb->len - skb->data_len;
-
-	txdp->Buffer_Pointer = pci_map_single
-	    (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
-	txdp->Host_Control = (unsigned long) skb;
 	if (skb->ip_summed == CHECKSUM_HW) {
 		txdp->Control_2 |=
 		    (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN |
 		     TXD_TX_CKO_UDP_EN);
 	}
-
+	txdp->Control_1 |= TXD_GATHER_CODE_FIRST;
+	txdp->Control_1 |= TXD_LIST_OWN_XENA;
 	txdp->Control_2 |= config->tx_intr_type;
 
 	if (sp->vlgrp && vlan_tx_tag_present(skb)) {
@@ -3554,10 +3542,40 @@
 		txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag);
 	}
 
-	txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) |
-			    TXD_GATHER_CODE_FIRST);
-	txdp->Control_1 |= TXD_LIST_OWN_XENA;
+	frg_len = skb->len - skb->data_len;
+	if (skb_shinfo(skb)->ufo_size) {
+		int ufo_size;
 
+		ufo_size = skb_shinfo(skb)->ufo_size;
+		ufo_size &= ~7;
+		txdp->Control_1 |= TXD_UFO_EN;
+		txdp->Control_1 |= TXD_UFO_MSS(ufo_size);
+		txdp->Control_1 |= TXD_BUFFER0_SIZE(8);
+#ifdef __BIG_ENDIAN
+		sp->ufo_in_band_v[put_off] =
+				(u64)skb_shinfo(skb)->ip6_frag_id;
+#else
+		sp->ufo_in_band_v[put_off] =
+				(u64)skb_shinfo(skb)->ip6_frag_id << 32;
+#endif
+		txdp->Host_Control = (unsigned long)sp->ufo_in_band_v;
+		txdp->Buffer_Pointer = pci_map_single(sp->pdev,
+					sp->ufo_in_band_v,
+					sizeof(u64), PCI_DMA_TODEVICE);
+		txdp++;
+		txdp->Control_1 = 0;
+		txdp->Control_2 = 0;
+	}
+
+	txdp->Buffer_Pointer = pci_map_single
+	    (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE);
+	txdp->Host_Control = (unsigned long) skb;
+	txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
+
+	if (skb_shinfo(skb)->ufo_size)
+		txdp->Control_1 |= TXD_UFO_EN;
+
+	frg_cnt = skb_shinfo(skb)->nr_frags;
 	/* For fragmented SKB. */
 	for (i = 0; i < frg_cnt; i++) {
 		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -3569,9 +3587,14 @@
 		    (sp->pdev, frag->page, frag->page_offset,
 		     frag->size, PCI_DMA_TODEVICE);
 		txdp->Control_1 |= TXD_BUFFER0_SIZE(frag->size);
+		if (skb_shinfo(skb)->ufo_size)
+			txdp->Control_1 |= TXD_UFO_EN;
 	}
 	txdp->Control_1 |= TXD_GATHER_CODE_LAST;
 
+	if (skb_shinfo(skb)->ufo_size)
+		frg_cnt++; /* as Txd0 was used for inband header */
+
 	tx_fifo = mac_control->tx_FIFO_start[queue];
 	val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr;
 	writeq(val64, &tx_fifo->TxDL_Pointer);
@@ -3583,6 +3606,8 @@
 	if (mss)
 		val64 |= TX_FIFO_SPECIAL_FUNC;
 #endif
+	if (skb_shinfo(skb)->ufo_size)
+		val64 |= TX_FIFO_SPECIAL_FUNC;
 	writeq(val64, &tx_fifo->List_Control);
 
 	mmiowb();
@@ -4721,7 +4746,10 @@
 		fail = 1;
 
 	if (ret_data != 0x012345) {
-		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
+		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. "
+			"Data written %llx Data read %llx\n",
+			dev->name, (unsigned long long)0x12345,
+			(unsigned long long)ret_data);
 		fail = 1;
 	}
 
@@ -4740,7 +4768,10 @@
 		fail = 1;
 
 	if (ret_data != 0x012345) {
-		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
+		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. "
+			"Data written %llx Data read %llx\n",
+			dev->name, (unsigned long long)0x12345,
+			(unsigned long long)ret_data);
 		fail = 1;
 	}
 
@@ -5190,6 +5221,8 @@
 	.get_tso = ethtool_op_get_tso,
 	.set_tso = ethtool_op_set_tso,
 #endif
+	.get_ufo = ethtool_op_get_ufo,
+	.set_ufo = ethtool_op_set_ufo,
 	.self_test_count = s2io_ethtool_self_test_count,
 	.self_test = s2io_ethtool_test,
 	.get_strings = s2io_ethtool_get_strings,
@@ -5941,7 +5974,8 @@
 			break;
 		}
 	}
-	config->max_txds = MAX_SKB_FRAGS + 1;
+	/* + 2 because one Txd for skb->data and one Txd for UFO */
+	config->max_txds = MAX_SKB_FRAGS + 2;
 
 	/* Rx side parameters. */
 	if (rx_ring_sz[0] == 0)
@@ -6035,6 +6069,10 @@
 #ifdef NETIF_F_TSO
 	dev->features |= NETIF_F_TSO;
 #endif
+	if (sp->device_type & XFRAME_II_DEVICE) {
+		dev->features |= NETIF_F_UFO;
+		dev->features |= NETIF_F_HW_CSUM;
+	}
 
 	dev->tx_timeout = &s2io_tx_watchdog;
 	dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 419aad7..852a6a8 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -393,7 +393,9 @@
 #define TXD_GATHER_CODE_LAST    BIT(23)
 #define TXD_TCP_LSO_EN          BIT(30)
 #define TXD_UDP_COF_EN          BIT(31)
+#define TXD_UFO_EN		BIT(31) | BIT(30)
 #define TXD_TCP_LSO_MSS(val)    vBIT(val,34,14)
+#define TXD_UFO_MSS(val)	vBIT(val,34,14)
 #define TXD_BUFFER0_SIZE(val)   vBIT(val,48,16)
 
 	u64 Control_2;
@@ -789,6 +791,7 @@
 
 	spinlock_t	rx_lock;
 	atomic_t	isr_cnt;
+	u64 *ufo_in_band_v;
 };
 
 #define RESET_ERROR 1;
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 1d4d886..3d95fa2 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1,6 +1,6 @@
 /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
    Copyright 1999 Silicon Integrated System Corporation 
-   Revision:	1.08.08 Jan. 22 2005
+   Revision:	1.08.09 Sep. 19 2005
    
    Modified from the driver which is originally written by Donald Becker.
    
@@ -17,6 +17,7 @@
    SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
    preliminary Rev. 1.0 Jan. 18, 1998
 
+   Rev 1.08.09 Sep. 19 2005 Daniele Venzano add Wake on LAN support
    Rev 1.08.08 Jan. 22 2005 Daniele Venzano use netif_msg for debugging messages
    Rev 1.08.07 Nov.  2 2003 Daniele Venzano <webvenza@libero.it> add suspend/resume support
    Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support
@@ -76,7 +77,7 @@
 #include "sis900.h"
 
 #define SIS900_MODULE_NAME "sis900"
-#define SIS900_DRV_VERSION "v1.08.08 Jan. 22 2005"
+#define SIS900_DRV_VERSION "v1.08.09 Sep. 19 2005"
 
 static char version[] __devinitdata =
 KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
@@ -538,6 +539,11 @@
 		printk("%2.2x:", (u8)net_dev->dev_addr[i]);
 	printk("%2.2x.\n", net_dev->dev_addr[i]);
 
+	/* Detect Wake on Lan support */
+	ret = inl(CFGPMC & PMESP);
+	if (netif_msg_probe(sis_priv) && (ret & PME_D3C) == 0)
+		printk(KERN_INFO "%s: Wake on LAN only available from suspend to RAM.", net_dev->name);
+
 	return 0;
 
  err_unmap_rx:
@@ -2015,6 +2021,67 @@
 	return mii_nway_restart(&sis_priv->mii_info);
 }
 
+/**
+ *	sis900_set_wol - Set up Wake on Lan registers
+ *	@net_dev: the net device to probe
+ *	@wol: container for info passed to the driver
+ *
+ *	Process ethtool command "wol" to setup wake on lan features.
+ *	SiS900 supports sending WoL events if a correct packet is received,
+ *	but there is no simple way to filter them to only a subset (broadcast,
+ *	multicast, unicast or arp).
+ */
+ 
+static int sis900_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
+{
+	struct sis900_private *sis_priv = net_dev->priv;
+	long pmctrl_addr = net_dev->base_addr + pmctrl;
+	u32 cfgpmcsr = 0, pmctrl_bits = 0;
+
+	if (wol->wolopts == 0) {
+		pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr);
+		cfgpmcsr |= ~PME_EN;
+		pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr);
+		outl(pmctrl_bits, pmctrl_addr);
+		if (netif_msg_wol(sis_priv))
+			printk(KERN_DEBUG "%s: Wake on LAN disabled\n", net_dev->name);
+		return 0;
+	}
+
+	if (wol->wolopts & (WAKE_MAGICSECURE | WAKE_UCAST | WAKE_MCAST
+				| WAKE_BCAST | WAKE_ARP))
+		return -EINVAL;
+
+	if (wol->wolopts & WAKE_MAGIC)
+		pmctrl_bits |= MAGICPKT;
+	if (wol->wolopts & WAKE_PHY)
+		pmctrl_bits |= LINKON;
+	
+	outl(pmctrl_bits, pmctrl_addr);
+
+	pci_read_config_dword(sis_priv->pci_dev, CFGPMCSR, &cfgpmcsr);
+	cfgpmcsr |= PME_EN;
+	pci_write_config_dword(sis_priv->pci_dev, CFGPMCSR, cfgpmcsr);
+	if (netif_msg_wol(sis_priv))
+		printk(KERN_DEBUG "%s: Wake on LAN enabled\n", net_dev->name);
+
+	return 0;
+}
+
+static void sis900_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
+{
+	long pmctrl_addr = net_dev->base_addr + pmctrl;
+	u32 pmctrl_bits;
+
+	pmctrl_bits = inl(pmctrl_addr);
+	if (pmctrl_bits & MAGICPKT)
+		wol->wolopts |= WAKE_MAGIC;
+	if (pmctrl_bits & LINKON)
+		wol->wolopts |= WAKE_PHY;
+
+	wol->supported = (WAKE_PHY | WAKE_MAGIC);
+}
+
 static struct ethtool_ops sis900_ethtool_ops = {
 	.get_drvinfo 	= sis900_get_drvinfo,
 	.get_msglevel	= sis900_get_msglevel,
@@ -2023,6 +2090,8 @@
 	.get_settings	= sis900_get_settings,
 	.set_settings	= sis900_set_settings,
 	.nway_reset	= sis900_nway_reset,
+	.get_wol	= sis900_get_wol,
+	.set_wol	= sis900_set_wol
 };
 
 /**
diff --git a/drivers/net/sis900.h b/drivers/net/sis900.h
index de3c067..4233ea5 100644
--- a/drivers/net/sis900.h
+++ b/drivers/net/sis900.h
@@ -33,6 +33,7 @@
         rxcfg=0x34,             //Receive Configuration Register
         flctrl=0x38,            //Flow Control Register
         rxlen=0x3c,             //Receive Packet Length Register
+        cfgpmcsr=0x44,          //Configuration Power Management Control/Status Register
         rfcr=0x48,              //Receive Filter Control Register
         rfdr=0x4C,              //Receive Filter Data Register
         pmctrl=0xB0,            //Power Management Control Register
@@ -140,6 +141,50 @@
 	EEREQ = 0x00000400, EEDONE = 0x00000200, EEGNT = 0x00000100
 };
 
+/* PCI Registers */
+enum sis900_pci_registers {
+	CFGPMC 	 = 0x40,
+	CFGPMCSR = 0x44
+};
+
+/* Power management capabilities bits */
+enum sis900_cfgpmc_register_bits {
+	PMVER	= 0x00070000, 
+	DSI	= 0x00100000,
+	PMESP	= 0xf8000000
+};
+
+enum sis900_pmesp_bits {
+	PME_D0 = 0x1,
+	PME_D1 = 0x2,
+	PME_D2 = 0x4,
+	PME_D3H = 0x8,
+	PME_D3C = 0x10
+};
+
+/* Power management control/status bits */
+enum sis900_cfgpmcsr_register_bits {
+	PMESTS = 0x00004000,
+	PME_EN = 0x00000100, // Power management enable
+	PWR_STA = 0x00000003 // Current power state
+};
+
+/* Wake-on-LAN support. */
+enum sis900_power_management_control_register_bits {
+	LINKLOSS  = 0x00000001,
+	LINKON    = 0x00000002,
+	MAGICPKT  = 0x00000400,
+	ALGORITHM = 0x00000800,
+	FRM1EN    = 0x00100000,
+	FRM2EN    = 0x00200000,
+	FRM3EN    = 0x00400000,
+	FRM1ACS   = 0x01000000,
+	FRM2ACS   = 0x02000000,
+	FRM3ACS   = 0x04000000,
+	WAKEALL   = 0x40000000,
+	GATECLK   = 0x80000000
+};
+
 /* Management Data I/O (mdio) frame */
 #define MIIread         0x6000
 #define MIIwrite        0x5002
diff --git a/drivers/net/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
index 6783039..afd900d 100644
--- a/drivers/net/sk98lin/Makefile
+++ b/drivers/net/sk98lin/Makefile
@@ -26,9 +26,7 @@
 		skrlmt.o	\
 		sktimer.o	\
 		skvpd.o		\
-		skxmac2.o	\
-		skproc.o	\
-		skcsum.o
+		skxmac2.o
 
 # DBGDEF =  \
 # -DDEBUG
@@ -77,7 +75,7 @@
 # SK_DBGCAT_DRV_INT_SRC         0x04000000      interrupts sources
 # SK_DBGCAT_DRV_EVENT           0x08000000      driver events
 
-EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
+EXTRA_CFLAGS += -Idrivers/net/sk98lin -DSK_DIAG_SUPPORT -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM)
 
 clean:
 	rm -f core *.o *.a *.s
diff --git a/drivers/net/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
index 542cec5..778d9e6 100644
--- a/drivers/net/sk98lin/h/skdrv2nd.h
+++ b/drivers/net/sk98lin/h/skdrv2nd.h
@@ -60,7 +60,6 @@
 extern int		SkPciReadCfgDWord(SK_AC*, int, SK_U32*);
 extern int		SkPciReadCfgWord(SK_AC*, int, SK_U16*);
 extern int		SkPciReadCfgByte(SK_AC*, int, SK_U8*);
-extern int		SkPciWriteCfgDWord(SK_AC*, int, SK_U32);
 extern int		SkPciWriteCfgWord(SK_AC*, int, SK_U16);
 extern int		SkPciWriteCfgByte(SK_AC*, int, SK_U8);
 extern int		SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA);
@@ -268,8 +267,6 @@
 struct s_DevNet {
 	int             PortNr;
 	int             NetNr;
-	int             Mtu;
-	int             Up;
 	SK_AC   *pAC;
 };  
 
@@ -298,6 +295,7 @@
 	RXD		*pRxdRingTail;	/* Tail of Rx rings */
 	RXD		*pRxdRingPrev;	/* descriptor given to BMU previously */
 	int		RxdRingFree;	/* # of free entrys */
+	int		RxCsum;		/* use receive checksum hardware */
 	spinlock_t	RxDesRingLock;	/* serialize descriptor accesses */
 	int		RxFillLimit;	/* limit for buffers in ring */
 	SK_IOC		HwAddr;		/* bmu registers address */
@@ -390,12 +388,10 @@
 	
 	SK_IOC		IoBase;		/* register set of adapter */
 	int		BoardLevel;	/* level of active hw init (0-2) */
-	char		DeviceStr[80];	/* adapter string from vpd */
+
 	SK_U32		AllocFlag;	/* flag allocation of resources */
 	struct pci_dev	*PciDev;	/* for access to pci config space */
-	SK_U32		PciDevId;	/* pci device id */
 	struct SK_NET_DEVICE	*dev[2];	/* pointer to device struct */
-	char		Name[30];	/* driver name */
 
 	int		RxBufSize;	/* length of receive buffers */
         struct net_device_stats stats;	/* linux 'netstat -i' statistics */
@@ -425,16 +421,11 @@
 	TX_PORT		TxPort[SK_MAX_MACS][2];
 	RX_PORT		RxPort[SK_MAX_MACS];
 
-	unsigned int	CsOfs1;		/* for checksum calculation */
-	unsigned int	CsOfs2;		/* for checksum calculation */
-	SK_U32		CsOfs;		/* for checksum calculation */
-
 	SK_BOOL		CheckQueue;	/* check event queue soon */
 	SK_TIMER        DrvCleanupTimer;/* to check for pending descriptors */
 	DIM_INFO        DynIrqModInfo;  /* all data related to DIM */
 
 	/* Only for tests */
-	int		PortUp;
 	int		PortDown;
 	int		ChipsetType;	/*  Chipset family type 
 					 *  0 == Genesis family support
diff --git a/drivers/net/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
index bdc1a5e..daa9a8d 100644
--- a/drivers/net/sk98lin/h/skvpd.h
+++ b/drivers/net/sk98lin/h/skvpd.h
@@ -130,14 +130,12 @@
 #ifndef VPD_DO_IO
 #define VPD_OUT8(pAC,IoC,Addr,Val)	(void)SkPciWriteCfgByte(pAC,Addr,Val)
 #define VPD_OUT16(pAC,IoC,Addr,Val)	(void)SkPciWriteCfgWord(pAC,Addr,Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val)	(void)SkPciWriteCfgDWord(pAC,Addr,Val)
 #define VPD_IN8(pAC,IoC,Addr,pVal)	(void)SkPciReadCfgByte(pAC,Addr,pVal)
 #define VPD_IN16(pAC,IoC,Addr,pVal)	(void)SkPciReadCfgWord(pAC,Addr,pVal)
 #define VPD_IN32(pAC,IoC,Addr,pVal)	(void)SkPciReadCfgDWord(pAC,Addr,pVal)
 #else	/* VPD_DO_IO */
 #define VPD_OUT8(pAC,IoC,Addr,Val)	SK_OUT8(IoC,PCI_C(Addr),Val)
 #define VPD_OUT16(pAC,IoC,Addr,Val)	SK_OUT16(IoC,PCI_C(Addr),Val)
-#define VPD_OUT32(pAC,IoC,Addr,Val)	SK_OUT32(IoC,PCI_C(Addr),Val)
 #define VPD_IN8(pAC,IoC,Addr,pVal)	SK_IN8(IoC,PCI_C(Addr),pVal)
 #define VPD_IN16(pAC,IoC,Addr,pVal)	SK_IN16(IoC,PCI_C(Addr),pVal)
 #define VPD_IN32(pAC,IoC,Addr,pVal)	SK_IN32(IoC,PCI_C(Addr),pVal)
@@ -155,12 +153,6 @@
 		else						\
 			SK_OUT16(pAC,PCI_C(Addr),Val);		\
 		}
-#define VPD_OUT32(pAC,Ioc,Addr,Val) {			\
-		if ((pAC)->DgT.DgUseCfgCycle)			\
-			SkPciWriteCfgDWord(pAC,Addr,Val);	\
-		else						\
-			SK_OUT32(pAC,PCI_C(Addr),Val); 		\
-		}
 #define VPD_IN8(pAC,Ioc,Addr,pVal) {			\
 		if ((pAC)->DgT.DgUseCfgCycle) 			\
 			SkPciReadCfgByte(pAC,Addr,pVal);	\
diff --git a/drivers/net/sk98lin/skcsum.c b/drivers/net/sk98lin/skcsum.c
deleted file mode 100644
index 38a6e7a..0000000
--- a/drivers/net/sk98lin/skcsum.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/******************************************************************************
- *
- * Name:	skcsum.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.12 $
- * Date:	$Date: 2003/08/20 13:55:53 $
- * Purpose:	Store/verify Internet checksum in send/receive packets.
- *
- ******************************************************************************/
-
-/******************************************************************************
- *
- *	(C)Copyright 1998-2003 SysKonnect GmbH.
- *
- *	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.
- *
- *	The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-
-#ifdef SK_USE_CSUM	/* Check if CSUM is to be used. */
-
-#ifndef lint
-static const char SysKonnectFileId[] =
-	"@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect.";
-#endif	/* !lint */
-
-/******************************************************************************
- *
- * Description:
- *
- * This is the "GEnesis" common module "CSUM".
- *
- * This module contains the code necessary to calculate, store, and verify the
- * Internet Checksum of IP, TCP, and UDP frames.
- *
- * "GEnesis" is an abbreviation of "Gigabit Ethernet Network System in Silicon"
- * and is the code name of this SysKonnect project.
- *
- * Compilation Options:
- *
- *	SK_USE_CSUM - Define if CSUM is to be used. Otherwise, CSUM will be an
- *	empty module.
- *
- *	SKCS_OVERWRITE_PROTO - Define to overwrite the default protocol id
- *	definitions. In this case, all SKCS_PROTO_xxx definitions must be made
- *	external.
- *
- *	SKCS_OVERWRITE_STATUS - Define to overwrite the default return status
- *	definitions. In this case, all SKCS_STATUS_xxx definitions must be made
- *	external.
- *
- * Include File Hierarchy:
- *
- *	"h/skdrv1st.h"
- *	"h/skcsum.h"
- *	"h/sktypes.h"
- *	"h/skqueue.h"
- *	"h/skdrv2nd.h"
- *
- ******************************************************************************/
-
-#include "h/skdrv1st.h"
-#include "h/skcsum.h"
-#include "h/skdrv2nd.h"
-
-/* defines ********************************************************************/
-
-/* The size of an Ethernet MAC header. */
-#define SKCS_ETHERNET_MAC_HEADER_SIZE			(6+6+2)
-
-/* The size of the used topology's MAC header. */
-#define	SKCS_MAC_HEADER_SIZE	SKCS_ETHERNET_MAC_HEADER_SIZE
-
-/* The size of the IP header without any option fields. */
-#define SKCS_IP_HEADER_SIZE						20
-
-/*
- * Field offsets within the IP header.
- */
-
-/* "Internet Header Version" and "Length". */
-#define SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH	0
-
-/* "Total Length". */
-#define SKCS_OFS_IP_TOTAL_LENGTH				2
-
-/* "Flags" "Fragment Offset". */
-#define SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET	6
-
-/* "Next Level Protocol" identifier. */
-#define SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL			9
-
-/* Source IP address. */
-#define SKCS_OFS_IP_SOURCE_ADDRESS				12
-
-/* Destination IP address. */
-#define SKCS_OFS_IP_DESTINATION_ADDRESS			16
-
-
-/*
- * Field offsets within the UDP header.
- */
-
-/* UDP checksum. */
-#define SKCS_OFS_UDP_CHECKSUM					6
-
-/* IP "Next Level Protocol" identifiers (see RFC 790). */
-#define SKCS_PROTO_ID_TCP		6	/* Transport Control Protocol */
-#define SKCS_PROTO_ID_UDP		17	/* User Datagram Protocol */
-
-/* IP "Don't Fragment" bit. */
-#define SKCS_IP_DONT_FRAGMENT	SKCS_HTON16(0x4000)
-
-/* Add a byte offset to a pointer. */
-#define SKCS_IDX(pPtr, Ofs)	((void *) ((char *) (pPtr) + (Ofs)))
-
-/*
- * Macros that convert host to network representation and vice versa, i.e.
- * little/big endian conversion on little endian machines only.
- */
-#ifdef SK_LITTLE_ENDIAN
-#define SKCS_HTON16(Val16)	(((unsigned) (Val16) >> 8) | (((Val16) & 0xff) << 8))
-#endif	/* SK_LITTLE_ENDIAN */
-#ifdef SK_BIG_ENDIAN
-#define SKCS_HTON16(Val16)	(Val16)
-#endif	/* SK_BIG_ENDIAN */
-#define SKCS_NTOH16(Val16)	SKCS_HTON16(Val16)
-
-/* typedefs *******************************************************************/
-
-/* function prototypes ********************************************************/
-
-/******************************************************************************
- *
- *	SkCsGetSendInfo - get checksum information for a send packet
- *
- * Description:
- *	Get all checksum information necessary to send a TCP or UDP packet. The
- *	function checks the IP header passed to it. If the high-level protocol
- *	is either TCP or UDP the pseudo header checksum is calculated and
- *	returned.
- *
- *	The function returns the total length of the IP header (including any
- *	IP option fields), which is the same as the start offset of the IP data
- *	which in turn is the start offset of the TCP or UDP header.
- *
- *	The function also returns the TCP or UDP pseudo header checksum, which
- *	should be used as the start value for the hardware checksum calculation.
- *	(Note that any actual pseudo header checksum can never calculate to
- *	zero.)
- *
- * Note:
- *	There is a bug in the GENESIS ASIC which may lead to wrong checksums.
- *
- * Arguments:
- *	pAc - A pointer to the adapter context struct.
- *
- *	pIpHeader - Pointer to IP header. Must be at least the IP header *not*
- *	including any option fields, i.e. at least 20 bytes.
- *
- *	Note: This pointer will be used to address 8-, 16-, and 32-bit
- *	variables with the respective alignment offsets relative to the pointer.
- *	Thus, the pointer should point to a 32-bit aligned address. If the
- *	target system cannot address 32-bit variables on non 32-bit aligned
- *	addresses, then the pointer *must* point to a 32-bit aligned address.
- *
- *	pPacketInfo - A pointer to the packet information structure for this
- *	packet. Before calling this SkCsGetSendInfo(), the following field must
- *	be initialized:
- *
- *		ProtocolFlags - Initialize with any combination of
- *		SKCS_PROTO_XXX bit flags. SkCsGetSendInfo() will only work on
- *		the protocols specified here. Any protocol(s) not specified
- *		here will be ignored.
- *
- *		Note: Only one checksum can be calculated in hardware. Thus, if
- *		SKCS_PROTO_IP is specified in the 'ProtocolFlags',
- *		SkCsGetSendInfo() must calculate the IP header checksum in
- *		software. It might be a better idea to have the calling
- *		protocol stack calculate the IP header checksum.
- *
- * Returns: N/A
- *	On return, the following fields in 'pPacketInfo' may or may not have
- *	been filled with information, depending on the protocol(s) found in the
- *	packet:
- *
- *	ProtocolFlags - Returns the SKCS_PROTO_XXX bit flags of the protocol(s)
- *	that were both requested by the caller and actually found in the packet.
- *	Protocol(s) not specified by the caller and/or not found in the packet
- *	will have their respective SKCS_PROTO_XXX bit flags reset.
- *
- *	Note: For IP fragments, TCP and UDP packet information is ignored.
- *
- *	IpHeaderLength - The total length in bytes of the complete IP header
- *	including any option fields is returned here. This is the start offset
- *	of the IP data, i.e. the TCP or UDP header if present.
- *
- *	IpHeaderChecksum - If IP has been specified in the 'ProtocolFlags', the
- *	16-bit Internet Checksum of the IP header is returned here. This value
- *	is to be stored into the packet's 'IP Header Checksum' field.
- *
- *	PseudoHeaderChecksum - If this is a TCP or UDP packet and if TCP or UDP
- *	has been specified in the 'ProtocolFlags', the 16-bit Internet Checksum
- *	of the TCP or UDP pseudo header is returned here.
- */
-void SkCsGetSendInfo(
-SK_AC				*pAc,			/* Adapter context struct. */
-void				*pIpHeader,		/* IP header. */
-SKCS_PACKET_INFO	*pPacketInfo,	/* Packet information struct. */
-int					NetNumber)		/* Net number */
-{
-	/* Internet Header Version found in IP header. */
-	unsigned InternetHeaderVersion;
-
-	/* Length of the IP header as found in IP header. */
-	unsigned IpHeaderLength;
-
-	/* Bit field specifiying the desired/found protocols. */
-	unsigned ProtocolFlags;
-
-	/* Next level protocol identifier found in IP header. */
-	unsigned NextLevelProtocol;
-
-	/* Length of IP data portion. */
-	unsigned IpDataLength;
-
-	/* TCP/UDP pseudo header checksum. */
-	unsigned long PseudoHeaderChecksum;
-
-	/* Pointer to next level protocol statistics structure. */
-	SKCS_PROTO_STATS *NextLevelProtoStats;
-
-	/* Temporary variable. */
-	unsigned Tmp;
-
-	Tmp = *(SK_U8 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
-
-	/* Get the Internet Header Version (IHV). */
-	/* Note: The IHV is stored in the upper four bits. */
-
-	InternetHeaderVersion = Tmp >> 4;
-
-	/* Check the Internet Header Version. */
-	/* Note: We currently only support IP version 4. */
-
-	if (InternetHeaderVersion != 4) {	/* IPv4? */
-		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
-			("Tx: Unknown Internet Header Version %u.\n",
-			InternetHeaderVersion));
-		pPacketInfo->ProtocolFlags = 0;
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
-		return;
-	}
-
-	/* Get the IP header length (IHL). */
-	/*
-	 * Note: The IHL is stored in the lower four bits as the number of
-	 * 4-byte words.
-	 */
-
-	IpHeaderLength = (Tmp & 0xf) * 4;
-	pPacketInfo->IpHeaderLength = IpHeaderLength;
-
-	/* Check the IP header length. */
-
-	/* 04-Aug-1998 sw - Really check the IHL? Necessary? */
-
-	if (IpHeaderLength < 5*4) {
-		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_TX,
-			("Tx: Invalid IP Header Length %u.\n", IpHeaderLength));
-		pPacketInfo->ProtocolFlags = 0;
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxUnableCts++;
-		return;
-	}
-
-	/* This is an IPv4 frame with a header of valid length. */
-
-	pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].TxOkCts++;
-
-	/* Check if we should calculate the IP header checksum. */
-
-	ProtocolFlags = pPacketInfo->ProtocolFlags;
-
-	if (ProtocolFlags & SKCS_PROTO_IP) {
-		pPacketInfo->IpHeaderChecksum =
-			SkCsCalculateChecksum(pIpHeader, IpHeaderLength);
-	}
-
-	/* Get the next level protocol identifier. */
-
-	NextLevelProtocol =
-		*(SK_U8 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
-
-	/*
-	 * Check if this is a TCP or UDP frame and if we should calculate the
-	 * TCP/UDP pseudo header checksum.
-	 *
-	 * Also clear all protocol bit flags of protocols not present in the
-	 * frame.
-	 */
-
-	if ((ProtocolFlags & SKCS_PROTO_TCP) != 0 &&
-		NextLevelProtocol == SKCS_PROTO_ID_TCP) {
-		/* TCP/IP frame. */
-		ProtocolFlags &= SKCS_PROTO_TCP | SKCS_PROTO_IP;
-		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
-	}
-	else if ((ProtocolFlags & SKCS_PROTO_UDP) != 0 &&
-		NextLevelProtocol == SKCS_PROTO_ID_UDP) {
-		/* UDP/IP frame. */
-		ProtocolFlags &= SKCS_PROTO_UDP | SKCS_PROTO_IP;
-		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
-	}
-	else {
-		/*
-		 * Either not a TCP or UDP frame and/or TCP/UDP processing not
-		 * specified.
-		 */
-		pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
-		return;
-	}
-
-	/* Check if this is an IP fragment. */
-
-	/*
-	 * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
-	 * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
-	 * and the "More Fragments" are zero, it is *not* a fragment. We can
-	 * easily check both at the same time since they are in the same 16-bit
-	 * word.
-	 */
-
-	if ((*(SK_U16 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
-		~SKCS_IP_DONT_FRAGMENT) != 0) {
-		/* IP fragment; ignore all other protocols. */
-		pPacketInfo->ProtocolFlags = ProtocolFlags & SKCS_PROTO_IP;
-		NextLevelProtoStats->TxUnableCts++;
-		return;
-	}
-
-	/*
-	 * Calculate the TCP/UDP pseudo header checksum.
-	 */
-
-	/* Get total length of IP header and data. */
-
-	IpDataLength =
-		*(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
-
-	/* Get length of IP data portion. */
-
-	IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
-
-	/* Calculate the sum of all pseudo header fields (16-bit). */
-
-	PseudoHeaderChecksum =
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
-		(unsigned long) SKCS_HTON16(NextLevelProtocol) +
-		(unsigned long) SKCS_HTON16(IpDataLength);
-	
-	/* Add-in any carries. */
-
-	SKCS_OC_ADD(PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
-
-	/* Add-in any new carry. */
-
-	SKCS_OC_ADD(pPacketInfo->PseudoHeaderChecksum, PseudoHeaderChecksum, 0);
-
-	pPacketInfo->ProtocolFlags = ProtocolFlags;
-	NextLevelProtoStats->TxOkCts++;	/* Success. */
-}	/* SkCsGetSendInfo */
-
-
-/******************************************************************************
- *
- *	SkCsGetReceiveInfo - verify checksum information for a received packet
- *
- * Description:
- *	Verify a received frame's checksum. The function returns a status code
- *	reflecting the result of the verification.
- *
- * Note:
- *	Before calling this function you have to verify that the frame is
- *	not padded and Checksum1 and Checksum2 are bigger than 1.
- *
- * Arguments:
- *	pAc - Pointer to adapter context struct.
- *
- *	pIpHeader - Pointer to IP header. Must be at least the length in bytes
- *	of the received IP header including any option fields. For UDP packets,
- *	8 additional bytes are needed to access the UDP checksum.
- *
- *	Note: The actual length of the IP header is stored in the lower four
- *	bits of the first octet of the IP header as the number of 4-byte words,
- *	so it must be multiplied by four to get the length in bytes. Thus, the
- *	maximum IP header length is 15 * 4 = 60 bytes.
- *
- *	Checksum1 - The first 16-bit Internet Checksum calculated by the
- *	hardware starting at the offset returned by SkCsSetReceiveFlags().
- *
- *	Checksum2 - The second 16-bit Internet Checksum calculated by the
- *	hardware starting at the offset returned by SkCsSetReceiveFlags().
- *
- * Returns:
- *	SKCS_STATUS_UNKNOWN_IP_VERSION - Not an IP v4 frame.
- *	SKCS_STATUS_IP_CSUM_ERROR - IP checksum error.
- *	SKCS_STATUS_IP_CSUM_ERROR_TCP - IP checksum error in TCP frame.
- *	SKCS_STATUS_IP_CSUM_ERROR_UDP - IP checksum error in UDP frame
- *	SKCS_STATUS_IP_FRAGMENT - IP fragment (IP checksum ok).
- *	SKCS_STATUS_IP_CSUM_OK - IP checksum ok (not a TCP or UDP frame).
- *	SKCS_STATUS_TCP_CSUM_ERROR - TCP checksum error (IP checksum ok).
- *	SKCS_STATUS_UDP_CSUM_ERROR - UDP checksum error (IP checksum ok).
- *	SKCS_STATUS_TCP_CSUM_OK - IP and TCP checksum ok.
- *	SKCS_STATUS_UDP_CSUM_OK - IP and UDP checksum ok.
- *	SKCS_STATUS_IP_CSUM_OK_NO_UDP - IP checksum OK and no UDP checksum.
- *
- *	Note: If SKCS_OVERWRITE_STATUS is defined, the SKCS_STATUS_XXX values
- *	returned here can be defined in some header file by the module using CSUM.
- *	In this way, the calling module can assign return values for its own needs,
- *	e.g. by assigning bit flags to the individual protocols.
- */
-SKCS_STATUS SkCsGetReceiveInfo(
-SK_AC		*pAc,		/* Adapter context struct. */
-void		*pIpHeader,	/* IP header. */
-unsigned	Checksum1,	/* Hardware checksum 1. */
-unsigned	Checksum2,	/* Hardware checksum 2. */
-int			NetNumber)	/* Net number */
-{
-	/* Internet Header Version found in IP header. */
-	unsigned InternetHeaderVersion;
-
-	/* Length of the IP header as found in IP header. */
-	unsigned IpHeaderLength;
-
-	/* Length of IP data portion. */
-	unsigned IpDataLength;
-
-	/* IP header checksum. */
-	unsigned IpHeaderChecksum;
-
-	/* IP header options checksum, if any. */
-	unsigned IpOptionsChecksum;
-
-	/* IP data checksum, i.e. TCP/UDP checksum. */
-	unsigned IpDataChecksum;
-
-	/* Next level protocol identifier found in IP header. */
-	unsigned NextLevelProtocol;
-
-	/* The checksum of the "next level protocol", i.e. TCP or UDP. */
-	unsigned long NextLevelProtocolChecksum;
-
-	/* Pointer to next level protocol statistics structure. */
-	SKCS_PROTO_STATS *NextLevelProtoStats;
-
-	/* Temporary variable. */
-	unsigned Tmp;
-
-	Tmp = *(SK_U8 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_HEADER_VERSION_AND_LENGTH);
-
-	/* Get the Internet Header Version (IHV). */
-	/* Note: The IHV is stored in the upper four bits. */
-
-	InternetHeaderVersion = Tmp >> 4;
-
-	/* Check the Internet Header Version. */
-	/* Note: We currently only support IP version 4. */
-
-	if (InternetHeaderVersion != 4) {	/* IPv4? */
-		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
-			("Rx: Unknown Internet Header Version %u.\n",
-			InternetHeaderVersion));
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxUnableCts++;
-		return (SKCS_STATUS_UNKNOWN_IP_VERSION);
-	}
-
-	/* Get the IP header length (IHL). */
-	/*
-	 * Note: The IHL is stored in the lower four bits as the number of
-	 * 4-byte words.
-	 */
-
-	IpHeaderLength = (Tmp & 0xf) * 4;
-
-	/* Check the IP header length. */
-
-	/* 04-Aug-1998 sw - Really check the IHL? Necessary? */
-
-	if (IpHeaderLength < 5*4) {
-		SK_DBG_MSG(pAc, SK_DBGMOD_CSUM, SK_DBGCAT_ERR | SK_DBGCAT_RX,
-			("Rx: Invalid IP Header Length %u.\n", IpHeaderLength));
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
-		return (SKCS_STATUS_IP_CSUM_ERROR);
-	}
-
-	/* This is an IPv4 frame with a header of valid length. */
-
-	/* Get the IP header and data checksum. */
-
-	IpDataChecksum = Checksum2;
-
-	/*
-	 * The IP header checksum is calculated as follows:
-	 *
-	 *	IpHeaderChecksum = Checksum1 - Checksum2
-	 */
-
-	SKCS_OC_SUB(IpHeaderChecksum, Checksum1, Checksum2);
-
-	/* Check if any IP header options. */
-
-	if (IpHeaderLength > SKCS_IP_HEADER_SIZE) {
-
-		/* Get the IP options checksum. */
-
-		IpOptionsChecksum = SkCsCalculateChecksum(
-			SKCS_IDX(pIpHeader, SKCS_IP_HEADER_SIZE),
-			IpHeaderLength - SKCS_IP_HEADER_SIZE);
-
-		/* Adjust the IP header and IP data checksums. */
-
-		SKCS_OC_ADD(IpHeaderChecksum, IpHeaderChecksum, IpOptionsChecksum);
-
-		SKCS_OC_SUB(IpDataChecksum, IpDataChecksum, IpOptionsChecksum);
-	}
-
-	/*
-	 * Check if the IP header checksum is ok.
-	 *
-	 * NOTE: We must check the IP header checksum even if the caller just wants
-	 * us to check upper-layer checksums, because we cannot do any further
-	 * processing of the packet without a valid IP checksum.
-	 */
-	
-	/* Get the next level protocol identifier. */
-	
-	NextLevelProtocol = *(SK_U8 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_NEXT_LEVEL_PROTOCOL);
-
-	if (IpHeaderChecksum != 0xffff) {
-		pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_IP].RxErrCts++;
-		/* the NDIS tester wants to know the upper level protocol too */
-		if (NextLevelProtocol == SKCS_PROTO_ID_TCP) {
-			return(SKCS_STATUS_IP_CSUM_ERROR_TCP);
-		}
-		else if (NextLevelProtocol == SKCS_PROTO_ID_UDP) {
-			return(SKCS_STATUS_IP_CSUM_ERROR_UDP);
-		}
-		return (SKCS_STATUS_IP_CSUM_ERROR);
-	}
-
-	/*
-	 * Check if this is a TCP or UDP frame and if we should calculate the
-	 * TCP/UDP pseudo header checksum.
-	 *
-	 * Also clear all protocol bit flags of protocols not present in the
-	 * frame.
-	 */
-
-	if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_TCP) != 0 &&
-		NextLevelProtocol == SKCS_PROTO_ID_TCP) {
-		/* TCP/IP frame. */
-		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_TCP];
-	}
-	else if ((pAc->Csum.ReceiveFlags[NetNumber] & SKCS_PROTO_UDP) != 0 &&
-		NextLevelProtocol == SKCS_PROTO_ID_UDP) {
-		/* UDP/IP frame. */
-		NextLevelProtoStats =
-			&pAc->Csum.ProtoStats[NetNumber][SKCS_PROTO_STATS_UDP];
-	}
-	else {
-		/*
-		 * Either not a TCP or UDP frame and/or TCP/UDP processing not
-		 * specified.
-		 */
-		return (SKCS_STATUS_IP_CSUM_OK);
-	}
-
-	/* Check if this is an IP fragment. */
-
-	/*
-	 * Note: An IP fragment has a non-zero "Fragment Offset" field and/or
-	 * the "More Fragments" bit set. Thus, if both the "Fragment Offset"
-	 * and the "More Fragments" are zero, it is *not* a fragment. We can
-	 * easily check both at the same time since they are in the same 16-bit
-	 * word.
-	 */
-
-	if ((*(SK_U16 *)
-		SKCS_IDX(pIpHeader, SKCS_OFS_IP_FLAGS_AND_FRAGMENT_OFFSET) &
-		~SKCS_IP_DONT_FRAGMENT) != 0) {
-		/* IP fragment; ignore all other protocols. */
-		NextLevelProtoStats->RxUnableCts++;
-		return (SKCS_STATUS_IP_FRAGMENT);
-	}
-
-	/*
-	 * 08-May-2000 ra
-	 *
-	 * From RFC 768 (UDP)
-	 * If the computed checksum is zero, it is transmitted as all ones (the
-	 * equivalent in one's complement arithmetic).  An all zero transmitted
-	 * checksum value means that the transmitter generated no checksum (for
-	 * debugging or for higher level protocols that don't care).
-	 */
-
-	if (NextLevelProtocol == SKCS_PROTO_ID_UDP &&
-		*(SK_U16*)SKCS_IDX(pIpHeader, IpHeaderLength + 6) == 0x0000) {
-
-		NextLevelProtoStats->RxOkCts++;
-		
-		return (SKCS_STATUS_IP_CSUM_OK_NO_UDP);
-	}
-
-	/*
-	 * Calculate the TCP/UDP checksum.
-	 */
-
-	/* Get total length of IP header and data. */
-
-	IpDataLength =
-		*(SK_U16 *) SKCS_IDX(pIpHeader, SKCS_OFS_IP_TOTAL_LENGTH);
-
-	/* Get length of IP data portion. */
-
-	IpDataLength = SKCS_NTOH16(IpDataLength) - IpHeaderLength;
-
-	NextLevelProtocolChecksum =
-
-		/* Calculate the pseudo header checksum. */
-
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_SOURCE_ADDRESS + 0) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_SOURCE_ADDRESS + 2) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_DESTINATION_ADDRESS + 0) +
-		(unsigned long) *(SK_U16 *) SKCS_IDX(pIpHeader,
-			SKCS_OFS_IP_DESTINATION_ADDRESS + 2) +
-		(unsigned long) SKCS_HTON16(NextLevelProtocol) +
-		(unsigned long) SKCS_HTON16(IpDataLength) +
-
-		/* Add the TCP/UDP header checksum. */
-
-		(unsigned long) IpDataChecksum;
-
-	/* Add-in any carries. */
-
-	SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
-
-	/* Add-in any new carry. */
-
-	SKCS_OC_ADD(NextLevelProtocolChecksum, NextLevelProtocolChecksum, 0);
-
-	/* Check if the TCP/UDP checksum is ok. */
-
-	if ((unsigned) NextLevelProtocolChecksum == 0xffff) {
-
-		/* TCP/UDP checksum ok. */
-
-		NextLevelProtoStats->RxOkCts++;
-
-		return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
-			SKCS_STATUS_TCP_CSUM_OK : SKCS_STATUS_UDP_CSUM_OK);
-	}
-	
-	/* TCP/UDP checksum error. */
-
-	NextLevelProtoStats->RxErrCts++;
-
-	return (NextLevelProtocol == SKCS_PROTO_ID_TCP ?
-		SKCS_STATUS_TCP_CSUM_ERROR : SKCS_STATUS_UDP_CSUM_ERROR);
-}	/* SkCsGetReceiveInfo */
-
-
-/******************************************************************************
- *
- *	SkCsSetReceiveFlags - set checksum receive flags
- *
- * Description:
- *	Use this function to set the various receive flags. According to the
- *	protocol flags set by the caller, the start offsets within received
- *	packets of the two hardware checksums are returned. These offsets must
- *	be stored in all receive descriptors.
- *
- * Arguments:
- *	pAc - Pointer to adapter context struct.
- *
- *	ReceiveFlags - Any combination of SK_PROTO_XXX flags of the protocols
- *	for which the caller wants checksum information on received frames.
- *
- *	pChecksum1Offset - The start offset of the first receive descriptor
- *	hardware checksum to be calculated for received frames is returned
- *	here.
- *
- *	pChecksum2Offset - The start offset of the second receive descriptor
- *	hardware checksum to be calculated for received frames is returned
- *	here.
- *
- * Returns: N/A
- *	Returns the two hardware checksum start offsets.
- */
-void SkCsSetReceiveFlags(
-SK_AC		*pAc,				/* Adapter context struct. */
-unsigned	ReceiveFlags,		/* New receive flags. */
-unsigned	*pChecksum1Offset,	/* Offset for hardware checksum 1. */
-unsigned	*pChecksum2Offset,	/* Offset for hardware checksum 2. */
-int			NetNumber)
-{
-	/* Save the receive flags. */
-
-	pAc->Csum.ReceiveFlags[NetNumber] = ReceiveFlags;
-
-	/* First checksum start offset is the IP header. */
-	*pChecksum1Offset = SKCS_MAC_HEADER_SIZE;
-
-	/*
-	 * Second checksum start offset is the IP data. Note that this may vary
-	 * if there are any IP header options in the actual packet.
-	 */
-	*pChecksum2Offset = SKCS_MAC_HEADER_SIZE + SKCS_IP_HEADER_SIZE;
-}	/* SkCsSetReceiveFlags */
-
-#ifndef SK_CS_CALCULATE_CHECKSUM
-
-/******************************************************************************
- *
- *	SkCsCalculateChecksum - calculate checksum for specified data
- *
- * Description:
- *	Calculate and return the 16-bit Internet Checksum for the specified
- *	data.
- *
- * Arguments:
- *	pData - Pointer to data for which the checksum shall be calculated.
- *	Note: The pointer should be aligned on a 16-bit boundary.
- *
- *	Length - Length in bytes of data to checksum.
- *
- * Returns:
- *	The 16-bit Internet Checksum for the specified data.
- *
- *	Note: The checksum is calculated in the machine's natural byte order,
- *	i.e. little vs. big endian. Thus, the resulting checksum is different
- *	for the same input data on little and big endian machines.
- *
- *	However, when written back to the network packet, the byte order is
- *	always in correct network order.
- */
-unsigned SkCsCalculateChecksum(
-void		*pData,		/* Data to checksum. */
-unsigned	Length)		/* Length of data. */
-{
-	SK_U16 *pU16;		/* Pointer to the data as 16-bit words. */
-	unsigned long Checksum;	/* Checksum; must be at least 32 bits. */
-
-	/* Sum up all 16-bit words. */
-
-	pU16 = (SK_U16 *) pData;
-	for (Checksum = 0; Length > 1; Length -= 2) {
-		Checksum += *pU16++;
-	}
-
-	/* If this is an odd number of bytes, add-in the last byte. */
-
-	if (Length > 0) {
-#ifdef SK_BIG_ENDIAN
-		/* Add the last byte as the high byte. */
-		Checksum += ((unsigned) *(SK_U8 *) pU16) << 8;
-#else	/* !SK_BIG_ENDIAN */
-		/* Add the last byte as the low byte. */
-		Checksum += *(SK_U8 *) pU16;
-#endif	/* !SK_BIG_ENDIAN */
-	}
-
-	/* Add-in any carries. */
-
-	SKCS_OC_ADD(Checksum, Checksum, 0);
-
-	/* Add-in any new carry. */
-
-	SKCS_OC_ADD(Checksum, Checksum, 0);
-
-	/* Note: All bits beyond the 16-bit limit are now zero. */
-
-	return ((unsigned) Checksum);
-}	/* SkCsCalculateChecksum */
-
-#endif /* SK_CS_CALCULATE_CHECKSUM */
-
-/******************************************************************************
- *
- *	SkCsEvent - the CSUM event dispatcher
- *
- * Description:
- *	This is the event handler for the CSUM module.
- *
- * Arguments:
- *	pAc - Pointer to adapter context.
- *
- *	Ioc - I/O context.
- *
- *	Event -	 Event id.
- *
- *	Param - Event dependent parameter.
- *
- * Returns:
- *	The 16-bit Internet Checksum for the specified data.
- *
- *	Note: The checksum is calculated in the machine's natural byte order,
- *	i.e. little vs. big endian. Thus, the resulting checksum is different
- *	for the same input data on little and big endian machines.
- *
- *	However, when written back to the network packet, the byte order is
- *	always in correct network order.
- */
-int SkCsEvent(
-SK_AC		*pAc,	/* Pointer to adapter context. */
-SK_IOC		Ioc,	/* I/O context. */
-SK_U32		Event,	/* Event id. */
-SK_EVPARA	Param)	/* Event dependent parameter. */
-{
-	int ProtoIndex;
-	int	NetNumber;
-
-	switch (Event) {
-	/*
-	 * Clear protocol statistics.
-	 *
-	 * Param - Protocol index, or -1 for all protocols.
-	 *		 - Net number.
-	 */
-	case SK_CSUM_EVENT_CLEAR_PROTO_STATS:
-
-		ProtoIndex = (int)Param.Para32[1];
-		NetNumber = (int)Param.Para32[0];
-		if (ProtoIndex < 0) {	/* Clear for all protocols. */
-			if (NetNumber >= 0) {
-				SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][0], 0,
-					sizeof(pAc->Csum.ProtoStats[NetNumber]));
-			}
-		}
-		else {					/* Clear for individual protocol. */
-			SK_MEMSET(&pAc->Csum.ProtoStats[NetNumber][ProtoIndex], 0,
-				sizeof(pAc->Csum.ProtoStats[NetNumber][ProtoIndex]));
-		}
-		break;
-	default:
-		break;
-	}
-	return (0);	/* Success. */
-}	/* SkCsEvent */
-
-#endif	/* SK_USE_CSUM */
diff --git a/drivers/net/sk98lin/skethtool.c b/drivers/net/sk98lin/skethtool.c
index fb63995..4265ed9 100644
--- a/drivers/net/sk98lin/skethtool.c
+++ b/drivers/net/sk98lin/skethtool.c
@@ -539,6 +539,48 @@
         return ret ? -EIO : 0;
 }
 
+/* Only Yukon supports checksum offload. */
+static int setScatterGather(struct net_device *dev, u32 data)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+		return -EOPNOTSUPP;
+	return ethtool_op_set_sg(dev, data);
+}
+
+static int setTxCsum(struct net_device *dev, u32 data)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+		return -EOPNOTSUPP;
+
+	return ethtool_op_set_tx_csum(dev, data);
+}
+
+static u32 getRxCsum(struct net_device *dev)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	return pAC->RxPort[pNet->PortNr].RxCsum;
+}
+
+static int setRxCsum(struct net_device *dev, u32 data)
+{
+	DEV_NET *pNet = netdev_priv(dev);
+	SK_AC *pAC = pNet->pAC;
+
+	if (pAC->GIni.GIChipId == CHIP_ID_GENESIS)
+		return -EOPNOTSUPP;
+
+	pAC->RxPort[pNet->PortNr].RxCsum = data != 0;
+	return 0;
+}
+
 struct ethtool_ops SkGeEthtoolOps = {
 	.get_settings		= getSettings,
 	.set_settings		= setSettings,
@@ -549,4 +591,12 @@
 	.phys_id		= locateDevice,
 	.get_pauseparam		= getPauseParams,
 	.set_pauseparam		= setPauseParams,
+	.get_link		= ethtool_op_get_link,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
+	.get_sg			= ethtool_op_get_sg,
+	.set_sg			= setScatterGather,
+	.get_tx_csum		= ethtool_op_get_tx_csum,
+	.set_tx_csum		= setTxCsum,
+	.get_rx_csum		= getRxCsum,
+	.set_rx_csum		= setRxCsum,
 };
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index b18c92c..9a76ac1 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -101,18 +101,18 @@
  *		"h/skgeinit.h"
  *		"h/skaddr.h"
  *		"h/skgesirq.h"
- *		"h/skcsum.h"
  *		"h/skrlmt.h"
  *
  ******************************************************************************/
 
 #include	"h/skversion.h"
 
+#include	<linux/in.h>
 #include	<linux/module.h>
 #include	<linux/moduleparam.h>
 #include	<linux/init.h>
-#include 	<linux/proc_fs.h>
 #include	<linux/dma-mapping.h>
+#include	<linux/ip.h>
 
 #include	"h/skdrv1st.h"
 #include	"h/skdrv2nd.h"
@@ -206,7 +206,6 @@
 static struct	net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev);
 static int	SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd);
 static void	GetConfiguration(SK_AC*);
-static void	ProductStr(SK_AC*);
 static int	XmitFrame(SK_AC*, TX_PORT*, struct sk_buff*);
 static void	FreeTxDescriptors(SK_AC*pAC, TX_PORT*);
 static void	FillRxRing(SK_AC*, RX_PORT*);
@@ -235,28 +234,6 @@
  * Extern Function Prototypes
  *
  ******************************************************************************/
-static const char 	SKRootName[] = "net/sk98lin";
-static struct		proc_dir_entry *pSkRootDir;
-extern struct	file_operations sk_proc_fops;
-
-static inline void SkGeProcCreate(struct net_device *dev)
-{
-	struct proc_dir_entry *pe;
-
-	if (pSkRootDir && 
-	    (pe = create_proc_entry(dev->name, S_IRUGO, pSkRootDir))) {
-		pe->proc_fops = &sk_proc_fops;
-		pe->data = dev;
-		pe->owner = THIS_MODULE;
-	}
-}
- 
-static inline void SkGeProcRemove(struct net_device *dev)
-{
-	if (pSkRootDir)
-		remove_proc_entry(dev->name, pSkRootDir);
-}
-
 extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);	
 extern void SkDimDisplayModerationSettings(SK_AC *pAC);
 extern void SkDimStartModerationTimer(SK_AC *pAC);
@@ -279,6 +256,27 @@
 
 /*****************************************************************************
  *
+ *	SkPciWriteCfgDWord - write a 32 bit value to pci config space
+ *
+ * Description:
+ *	This routine writes a 32 bit value to the pci configuration
+ *	space.
+ *
+ * Returns:
+ *	0 - indicate everything worked ok.
+ *	!= 0 - error indication
+ */
+static inline int SkPciWriteCfgDWord(
+SK_AC *pAC,	/* Adapter Control structure pointer */
+int PciAddr,		/* PCI register address */
+SK_U32 Val)		/* pointer to store the read value */
+{
+	pci_write_config_dword(pAC->PciDev, PciAddr, Val);
+	return(0);
+} /* SkPciWriteCfgDWord */
+
+/*****************************************************************************
+ *
  * 	SkGeInitPCI - Init the PCI resources
  *
  * Description:
@@ -300,7 +298,7 @@
 	dev->mem_start = pci_resource_start (pdev, 0);
 	pci_set_master(pdev);
 
-	if (pci_request_regions(pdev, pAC->Name) != 0) {
+	if (pci_request_regions(pdev, "sk98lin") != 0) {
 		retval = 2;
 		goto out_disable;
 	}
@@ -578,10 +576,10 @@
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 
 	if (pAC->GIni.GIMacsFound == 2) {
-		 Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+		 Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev);
 	} else if (pAC->GIni.GIMacsFound == 1) {
 		Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ,
-			pAC->Name, dev);
+			"sk98lin", dev);
 	} else {
 		printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
 		       pAC->GIni.GIMacsFound);
@@ -601,11 +599,6 @@
        		return(-EAGAIN);
 	}
 
-	SkCsSetReceiveFlags(pAC,
-		SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP,
-		&pAC->CsOfs1, &pAC->CsOfs2, 0);
-	pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;
-
 	BoardInitMem(pAC);
 	/* tschilling: New common function with minimum size check. */
 	DualNet = SK_FALSE;
@@ -823,7 +816,7 @@
 		/* set the pointers right */
 		pDescr->VNextRxd = VNextDescr & 0xffffffffULL;
 		pDescr->pNextRxd = pNextDescr;
-		pDescr->TcpSumStarts = pAC->CsOfs;
+		if (!IsTx) pDescr->TcpSumStarts = ETH_HLEN << 16 | ETH_HLEN;
 
 		/* advance one step */
 		pPrevDescr = pDescr;
@@ -1270,7 +1263,6 @@
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
 
 	pAC->MaxPorts++;
-	pNet->Up = 1;
 
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY,
@@ -1400,7 +1392,6 @@
 			sizeof(SK_PNMI_STRUCT_DATA));
 
 	pAC->MaxPorts--;
-	pNet->Up = 0;
 
 	return (0);
 } /* SkGeClose */
@@ -1505,8 +1496,6 @@
 	TXD		*pOldTxd;
 	unsigned long	 Flags;
 	SK_U64		 PhysAddr;
-	int	 	 Protocol;
-	int		 IpHeaderLength;
 	int		 BytesSend = pMessage->len;
 
 	SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("X"));
@@ -1579,8 +1568,10 @@
 	pTxd->pMBuf     = pMessage;
 
 	if (pMessage->ip_summed == CHECKSUM_HW) {
-		Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
-		if ((Protocol == C_PROTO_ID_UDP) && 
+		u16 hdrlen = pMessage->h.raw - pMessage->data;
+		u16 offset = hdrlen + pMessage->csum;
+
+		if ((pMessage->h.ipiph->protocol == IPPROTO_UDP ) &&
 			(pAC->GIni.GIChipRev == 0) &&
 			(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
 			pTxd->TBControl = BMU_TCP_CHECK;
@@ -1588,14 +1579,9 @@
 			pTxd->TBControl = BMU_UDP_CHECK;
 		}
 
-		IpHeaderLength  = (SK_U8)pMessage->data[C_OFFSET_IPHEADER];
-		IpHeaderLength  = (IpHeaderLength & 0xf) * 4;
-		pTxd->TcpSumOfs = 0; /* PH-Checksum already calculated */
-		pTxd->TcpSumSt  = C_LEN_ETHERMAC_HEADER + IpHeaderLength + 
-							(Protocol == C_PROTO_ID_UDP ?
-							C_OFFSET_UDPHEADER_UDPCS : 
-							C_OFFSET_TCPHEADER_TCPCS);
-		pTxd->TcpSumWr  = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
+		pTxd->TcpSumOfs = 0;
+		pTxd->TcpSumSt  = hdrlen;
+		pTxd->TcpSumWr  = offset;
 
 		pTxd->TBControl |= BMU_OWN | BMU_STF | 
 				   BMU_SW  | BMU_EOF |
@@ -1658,11 +1644,10 @@
 	TXD		*pTxdLst;
 	int 	 	 CurrFrag;
 	int		 BytesSend;
-	int		 IpHeaderLength; 
-	int		 Protocol;
 	skb_frag_t	*sk_frag;
 	SK_U64		 PhysAddr;
 	unsigned long	 Flags;
+	SK_U32		 Control;
 
 	spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags);
 #ifndef USE_TX_COMPLETE
@@ -1685,7 +1670,6 @@
 	pTxdFst   = pTxd;
 	pTxdLst   = pTxd;
 	BytesSend = 0;
-	Protocol  = 0;
 
 	/* 
 	** Map the first fragment (header) into the DMA-space
@@ -1703,32 +1687,31 @@
 	** Does the HW need to evaluate checksum for TCP or UDP packets? 
 	*/
 	if (pMessage->ip_summed == CHECKSUM_HW) {
-		pTxd->TBControl = BMU_STF | BMU_STFWD | skb_headlen(pMessage);
+		u16 hdrlen = pMessage->h.raw - pMessage->data;
+		u16 offset = hdrlen + pMessage->csum;
+
+		Control = BMU_STFWD;
+
 		/* 
 		** We have to use the opcode for tcp here,  because the
 		** opcode for udp is not working in the hardware yet 
 		** (Revision 2.0)
 		*/
-		Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
-		if ((Protocol == C_PROTO_ID_UDP) && 
+		if ((pMessage->h.ipiph->protocol == IPPROTO_UDP ) &&
 			(pAC->GIni.GIChipRev == 0) &&
 			(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
-			pTxd->TBControl |= BMU_TCP_CHECK;
+			Control |= BMU_TCP_CHECK;
 		} else {
-			pTxd->TBControl |= BMU_UDP_CHECK;
+			Control |= BMU_UDP_CHECK;
 		}
 
-		IpHeaderLength  = ((SK_U8)pMessage->data[C_OFFSET_IPHEADER] & 0xf)*4;
-		pTxd->TcpSumOfs = 0; /* PH-Checksum already claculated */
-		pTxd->TcpSumSt  = C_LEN_ETHERMAC_HEADER + IpHeaderLength +
-						(Protocol == C_PROTO_ID_UDP ?
-						C_OFFSET_UDPHEADER_UDPCS :
-						C_OFFSET_TCPHEADER_TCPCS);
-		pTxd->TcpSumWr  = C_LEN_ETHERMAC_HEADER + IpHeaderLength;
-	} else {
-		pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_STF |
-					skb_headlen(pMessage);
-	}
+		pTxd->TcpSumOfs = 0;
+		pTxd->TcpSumSt  = hdrlen;
+		pTxd->TcpSumWr  = offset;
+	} else
+		Control = BMU_CHECK | BMU_SW;
+
+	pTxd->TBControl = BMU_STF | Control | skb_headlen(pMessage);
 
 	pTxd = pTxd->pNextTxd;
 	pTxPort->TxdRingFree--;
@@ -1752,40 +1735,18 @@
 		pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32);
 		pTxd->pMBuf     = pMessage;
 		
-		/* 
-		** Does the HW need to evaluate checksum for TCP or UDP packets? 
-		*/
-		if (pMessage->ip_summed == CHECKSUM_HW) {
-			pTxd->TBControl = BMU_OWN | BMU_SW | BMU_STFWD;
-			/* 
-			** We have to use the opcode for tcp here because the 
-			** opcode for udp is not working in the hardware yet 
-			** (revision 2.0)
-			*/
-			if ((Protocol == C_PROTO_ID_UDP) && 
-				(pAC->GIni.GIChipRev == 0) &&
-				(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
-				pTxd->TBControl |= BMU_TCP_CHECK;
-			} else {
-				pTxd->TBControl |= BMU_UDP_CHECK;
-			}
-		} else {
-			pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_OWN;
-		}
+		pTxd->TBControl = Control | BMU_OWN | sk_frag->size;;
 
 		/* 
 		** Do we have the last fragment? 
 		*/
 		if( (CurrFrag+1) == skb_shinfo(pMessage)->nr_frags )  {
 #ifdef USE_TX_COMPLETE
-			pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF | sk_frag->size;
+			pTxd->TBControl |= BMU_EOF | BMU_IRQ_EOF;
 #else
-			pTxd->TBControl |= BMU_EOF | sk_frag->size;
+			pTxd->TBControl |= BMU_EOF;
 #endif
 			pTxdFst->TBControl |= BMU_OWN | BMU_SW;
-
-		} else {
-			pTxd->TBControl |= sk_frag->size;
 		}
 		pTxdLst = pTxd;
 		pTxd    = pTxd->pNextTxd;
@@ -2032,7 +1993,6 @@
 struct sk_buff	*pMsg;			/* pointer to message holding frame */
 struct sk_buff	*pNewMsg;		/* pointer to a new message for copying frame */
 int				FrameLength;	/* total length of received frame */
-int				IpFrameLength;
 SK_MBUF			*pRlmtMbuf;		/* ptr to a buffer for giving a frame to rlmt */
 SK_EVPARA		EvPara;			/* an event parameter union */	
 unsigned long	Flags;			/* for spin lock */
@@ -2045,10 +2005,6 @@
 SK_BOOL  IsBadFrame; 			/* Bad frame */
 
 SK_U32			FrameStat;
-unsigned short	Csum1;
-unsigned short	Csum2;
-unsigned short	Type;
-int				Result;
 SK_U64			PhysAddr;
 
 rx_start:	
@@ -2177,8 +2133,8 @@
 						    (dma_addr_t) PhysAddr,
 						    FrameLength,
 						    PCI_DMA_FROMDEVICE);
-			eth_copy_and_sum(pNewMsg, pMsg->data,
-				FrameLength, 0);
+			memcpy(pNewMsg->data, pMsg, FrameLength);
+
 			pci_dma_sync_single_for_device(pAC->PciDev,
 						       (dma_addr_t) PhysAddr,
 						       FrameLength,
@@ -2206,69 +2162,15 @@
 
 			/* set length in message */
 			skb_put(pMsg, FrameLength);
-			/* hardware checksum */
-			Type = ntohs(*((short*)&pMsg->data[12]));
+		} /* frame > SK_COPY_TRESHOLD */
 
 #ifdef USE_SK_RX_CHECKSUM
-			if (Type == 0x800) {
-				Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff);
-				Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff);
-				IpFrameLength = (int) ntohs((unsigned short)
-								((unsigned short *) pMsg->data)[8]);
-
-				/*
-				 * Test: If frame is padded, a check is not possible!
-				 * Frame not padded? Length difference must be 14 (0xe)!
-				 */
-				if ((FrameLength - IpFrameLength) != 0xe) {
-				/* Frame padded => TCP offload not possible! */
-					pMsg->ip_summed = CHECKSUM_NONE;
-				} else {
-				/* Frame not padded => TCP offload! */
-					if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) &&
-						(pAC->GIni.GIChipId == CHIP_ID_GENESIS)) ||
-						(pAC->ChipsetType)) {
-						Result = SkCsGetReceiveInfo(pAC,
-							&pMsg->data[14],
-							Csum1, Csum2, pRxPort->PortIndex);
-						if (Result ==
-							SKCS_STATUS_IP_FRAGMENT ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_OK ||
-							Result ==
-							SKCS_STATUS_TCP_CSUM_OK ||
-							Result ==
-							SKCS_STATUS_UDP_CSUM_OK) {
-								pMsg->ip_summed =
-								CHECKSUM_UNNECESSARY;
-						}
-						else if (Result ==
-							SKCS_STATUS_TCP_CSUM_ERROR ||
-							Result ==
-							SKCS_STATUS_UDP_CSUM_ERROR ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_ERROR_UDP ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_ERROR_TCP ||
-							Result ==
-							SKCS_STATUS_IP_CSUM_ERROR ) {
-							/* HW Checksum error */
-							SK_DBG_MSG(NULL, SK_DBGMOD_DRV,
-							SK_DBGCAT_DRV_RX_PROGRESS,
-							("skge: CRC error. Frame dropped!\n"));
-							goto rx_failed;
-						} else {
-								pMsg->ip_summed =
-								CHECKSUM_NONE;
-						}
-					}/* checksumControl calculation valid */
-				} /* Frame length check */
-			} /* IP frame */
+		pMsg->csum = pRxd->TcpSums & 0xffff;
+		pMsg->ip_summed = CHECKSUM_HW;
 #else
-			pMsg->ip_summed = CHECKSUM_NONE;	
+		pMsg->ip_summed = CHECKSUM_NONE;
 #endif
-		} /* frame > SK_COPY_TRESHOLD */
-		
+
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV,	1,("V"));
 		ForRlmt = SK_RLMT_RX_PROTOCOL;
 #if 0
@@ -2643,7 +2545,7 @@
 static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu)
 {
 DEV_NET		*pNet;
-DEV_NET		*pOtherNet;
+struct net_device *pOtherDev;
 SK_AC		*pAC;
 unsigned long	Flags;
 int		i;
@@ -2673,11 +2575,11 @@
 	}
 #endif
 
-	pNet->Mtu = NewMtu;
-	pOtherNet = netdev_priv(pAC->dev[1 - pNet->NetNr]);
-	if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) {
-		return(0);
-	}
+	pOtherDev = pAC->dev[1 - pNet->NetNr];
+
+	if ( netif_running(pOtherDev) && (pOtherDev->mtu > 1500)
+	     && (NewMtu <= 1500))
+		return 0;
 
 	pAC->RxBufSize = NewMtu + 32;
 	dev->mtu = NewMtu;
@@ -2839,7 +2741,8 @@
 		EvPara.Para32[1] = -1;
 		SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
 			
-		if (pOtherNet->Up) {
+		if (netif_running(pOtherDev)) {
+			DEV_NET *pOtherNet = netdev_priv(pOtherDev);
 			EvPara.Para32[0] = pOtherNet->PortNr;
 			SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara);
 		}
@@ -2913,7 +2816,7 @@
 	pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts;
 	pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts;
 	
-        if (pNet->Mtu <= 1500) {
+        if (dev->mtu <= 1500) {
                 pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF;
         } else {
                 pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts -
@@ -3864,25 +3767,21 @@
  *
  * Returns: N/A
  */
-static void ProductStr(
-SK_AC	*pAC		/* pointer to adapter context */
+static inline int ProductStr(
+	SK_AC	*pAC,		/* pointer to adapter context */
+	char    *DeviceStr,	/* result string */
+	int      StrLen		/* length of the string */
 )
 {
-int	StrLen = 80;		/* length of the string, defined in SK_AC */
 char	Keyword[] = VPD_NAME;	/* vpd productname identifier */
 int	ReturnCode;		/* return code from vpd_read */
 unsigned long Flags;
 
 	spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-	ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr,
-		&StrLen);
+	ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, DeviceStr, &StrLen);
 	spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-	if (ReturnCode != 0) {
-		/* there was an error reading the vpd data */
-		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR,
-			("Error reading VPD data: %d\n", ReturnCode));
-		pAC->DeviceStr[0] = '\0';
-	}
+
+	return ReturnCode;
 } /* ProductStr */
 
 /*****************************************************************************
@@ -4085,28 +3984,6 @@
 
 /*****************************************************************************
  *
- *	SkPciWriteCfgDWord - write a 32 bit value to pci config space
- *
- * Description:
- *	This routine writes a 32 bit value to the pci configuration
- *	space.
- *
- * Returns:
- *	0 - indicate everything worked ok.
- *	!= 0 - error indication
- */
-int SkPciWriteCfgDWord(
-SK_AC *pAC,	/* Adapter Control structure pointer */
-int PciAddr,		/* PCI register address */
-SK_U32 Val)		/* pointer to store the read value */
-{
-	pci_write_config_dword(pAC->PciDev, PciAddr, Val);
-	return(0);
-} /* SkPciWriteCfgDWord */
-
-
-/*****************************************************************************
- *
  *	SkPciWriteCfgWord - write a 16 bit value to pci config space
  *
  * Description:
@@ -4243,6 +4120,7 @@
 			Flags);
 		break;
 	case SK_DRV_NET_UP:	 /* SK_U32 PortIdx */
+	{	struct net_device *dev = pAC->dev[Param.Para32[0]];
 		/* action list 5 */
 		FromPort = Param.Para32[0];
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4326,22 +4204,12 @@
 			printk("    irq moderation:  disabled\n");
 
 
-#ifdef SK_ZEROCOPY
-		if (pAC->ChipsetType)
-#ifdef USE_SK_TX_CHECKSUM
-			printk("    scatter-gather:  enabled\n");
-#else
-			printk("    tx-checksum:     disabled\n");
-#endif
-		else
-			printk("    scatter-gather:  disabled\n");
-#else
-			printk("    scatter-gather:  disabled\n");
-#endif
-
-#ifndef USE_SK_RX_CHECKSUM
-			printk("    rx-checksum:     disabled\n");
-#endif
+		printk("    scatter-gather:  %s\n",
+		       (dev->features & NETIF_F_SG) ? "enabled" : "disabled");
+		printk("    tx-checksum:     %s\n",
+		       (dev->features & NETIF_F_IP_CSUM) ? "enabled" : "disabled");
+		printk("    rx-checksum:     %s\n",
+		       pAC->RxPort[Param.Para32[0]].RxCsum ? "enabled" : "disabled");
 
 		} else {
                         DoPrintInterfaceChange = SK_TRUE;
@@ -4356,9 +4224,9 @@
 		}
 
 		/* Inform the world that link protocol is up. */
-		netif_carrier_on(pAC->dev[Param.Para32[0]]);
-
+		netif_carrier_on(dev);
 		break;
+	}
 	case SK_DRV_NET_DOWN:	 /* SK_U32 Reason */
 		/* action list 7 */
 		SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT,
@@ -4572,7 +4440,7 @@
 
 	pAC->DiagModeActive = DIAG_ACTIVE;
 	if (pAC->BoardLevel > SK_INIT_DATA) {
-		if (pNet->Up) {
+		if (netif_running(pAC->dev[0])) {
 			pAC->WasIfUp[0] = SK_TRUE;
 			pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose      */
 			DoPrintInterfaceChange = SK_FALSE;
@@ -4582,7 +4450,7 @@
 		}
 		if (pNet != netdev_priv(pAC->dev[1])) {
 			pNet = netdev_priv(pAC->dev[1]);
-			if (pNet->Up) {
+			if (netif_running(pAC->dev[1])) {
 				pAC->WasIfUp[1] = SK_TRUE;
 				pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */
 				DoPrintInterfaceChange = SK_FALSE;
@@ -4908,6 +4776,7 @@
 	struct net_device	*dev = NULL;
 	static int boards_found = 0;
 	int error = -ENODEV;
+	char DeviceStr[80];
 
 	if (pci_enable_device(pdev))
 		goto out;
@@ -4935,18 +4804,15 @@
 	memset(pNet->pAC, 0, sizeof(SK_AC));
 	pAC = pNet->pAC;
 	pAC->PciDev = pdev;
-	pAC->PciDevId = pdev->device;
+
 	pAC->dev[0] = dev;
 	pAC->dev[1] = dev;
-	sprintf(pAC->Name, "SysKonnect SK-98xx");
 	pAC->CheckQueue = SK_FALSE;
 
-	pNet->Mtu = 1500;
-	pNet->Up = 0;
 	dev->irq = pdev->irq;
 	error = SkGeInitPCI(pAC);
 	if (error) {
-		printk("SKGE: PCI setup failed: %i\n", error);
+		printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error);
 		goto out_free_netdev;
 	}
 
@@ -4965,30 +4831,38 @@
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
+	/* Use only if yukon hardware */
 	if (pAC->ChipsetType) {
-		/* Use only if yukon hardware */
-		/* SK and ZEROCOPY - fly baby... */
-		dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+#ifdef USE_SK_TX_CHECKSUM
+		dev->features |= NETIF_F_IP_CSUM;
+#endif
+#ifdef SK_ZEROCOPY
+		dev->features |= NETIF_F_SG;
+#endif
+#ifdef USE_SK_RX_CHECKSUM
+		pAC->RxPort[0].RxCsum = 1;
+#endif
 	}
-#endif
-#endif
 
 	pAC->Index = boards_found++;
 
 	if (SkGeBoardInit(dev, pAC))
 		goto out_free_netdev;
 
+	/* Read Adapter name from VPD */
+	if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
+		printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
+		goto out_free_resources;
+	}
+
 	/* Register net device */
 	if (register_netdev(dev)) {
-		printk(KERN_ERR "SKGE: Could not register device.\n");
+		printk(KERN_ERR "sk98lin: Could not register device.\n");
 		goto out_free_resources;
 	}
 
 	/* Print adapter specific string from vpd */
-	ProductStr(pAC);
-	printk("%s: %s\n", dev->name, pAC->DeviceStr);
+	printk("%s: %s\n", dev->name, DeviceStr);
 
 	/* Print configuration settings */
 	printk("      PrefPort:%c  RlmtMode:%s\n",
@@ -5001,10 +4875,8 @@
 
 	SkGeYellowLED(pAC, pAC->IoBase, 1);
 
-
 	memcpy(&dev->dev_addr, &pAC->Addr.Net[0].CurrentMacAddress, 6);
-
-	SkGeProcCreate(dev);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	pNet->PortNr = 0;
 	pNet->NetNr  = 0;
@@ -5024,8 +4896,6 @@
 		pNet->PortNr  = 1;
 		pNet->NetNr   = 1;
 		pNet->pAC     = pAC;
-		pNet->Mtu     = 1500;
-		pNet->Up      = 0;
 
 		dev->open               = &SkGeOpen;
 		dev->stop               = &SkGeClose;
@@ -5038,25 +4908,28 @@
 		SET_NETDEV_DEV(dev, &pdev->dev);
 		SET_ETHTOOL_OPS(dev, &SkGeEthtoolOps);
 
-#ifdef SK_ZEROCOPY
-#ifdef USE_SK_TX_CHECKSUM
 		if (pAC->ChipsetType) {
-			/* SG and ZEROCOPY - fly baby... */
-			dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+#ifdef USE_SK_TX_CHECKSUM
+			dev->features |= NETIF_F_IP_CSUM;
+#endif
+#ifdef SK_ZEROCOPY
+			dev->features |= NETIF_F_SG;
+#endif
+#ifdef USE_SK_RX_CHECKSUM
+			pAC->RxPort[1].RxCsum = 1;
+#endif
 		}
-#endif
-#endif
 
 		if (register_netdev(dev)) {
-			printk(KERN_ERR "SKGE: Could not register device.\n");
+			printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n");
 			free_netdev(dev);
 			pAC->dev[1] = pAC->dev[0];
 		} else {
-			SkGeProcCreate(dev);
 			memcpy(&dev->dev_addr,
 					&pAC->Addr.Net[1].CurrentMacAddress, 6);
+			memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	
-			printk("%s: %s\n", dev->name, pAC->DeviceStr);
+			printk("%s: %s\n", dev->name, DeviceStr);
 			printk("      PrefPort:B  RlmtMode:Dual Check Link State\n");
 		}
 	}
@@ -5092,10 +4965,7 @@
 	SK_AC *pAC = pNet->pAC;
 	struct net_device *otherdev = pAC->dev[1];
 
-	SkGeProcRemove(dev);
 	unregister_netdev(dev);
-	if (otherdev != dev)
-		SkGeProcRemove(otherdev);
 
 	SkGeYellowLED(pAC, pAC->IoBase, 0);
 
@@ -5180,9 +5050,9 @@
 	pci_enable_device(pdev);
 	pci_set_master(pdev);
 	if (pAC->GIni.GIMacsFound == 2)
-		ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, pAC->Name, dev);
+		ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, "sk98lin", dev);
 	else
-		ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, pAC->Name, dev);
+		ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, "sk98lin", dev);
 	if (ret) {
 		printk(KERN_WARNING "sk98lin: unable to acquire IRQ %d\n", dev->irq);
 		pAC->AllocFlag &= ~SK_ALLOC_IRQ;
@@ -5240,23 +5110,12 @@
 
 static int __init skge_init(void)
 {
-	int error;
-
-	pSkRootDir = proc_mkdir(SKRootName, NULL);
-	if (pSkRootDir) 
-		pSkRootDir->owner = THIS_MODULE;
-	
-	error = pci_register_driver(&skge_driver);
-	if (error)
-		remove_proc_entry(SKRootName, NULL);
-	return error;
+	return pci_module_init(&skge_driver);
 }
 
 static void __exit skge_exit(void)
 {
 	pci_unregister_driver(&skge_driver);
-	remove_proc_entry(SKRootName, NULL);
-
 }
 
 module_init(skge_init);
diff --git a/drivers/net/sk98lin/skproc.c b/drivers/net/sk98lin/skproc.c
deleted file mode 100644
index 5cece25..0000000
--- a/drivers/net/sk98lin/skproc.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/******************************************************************************
- *
- * Name:	skproc.c
- * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.11 $
- * Date:	$Date: 2003/12/11 16:03:57 $
- * Purpose:	Funktions to display statictic data
- *
- ******************************************************************************/
- 
-/******************************************************************************
- *
- *	(C)Copyright 1998-2002 SysKonnect GmbH.
- *	(C)Copyright 2002-2003 Marvell.
- *
- *	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.
- *
- *	Created 22-Nov-2000
- *	Author: Mirko Lindner (mlindner@syskonnect.de)
- *
- *	The information in this file is provided "AS IS" without warranty.
- *
- ******************************************************************************/
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include "h/skdrv1st.h"
-#include "h/skdrv2nd.h"
-#include "h/skversion.h"
-
-static int sk_seq_show(struct seq_file *seq, void *v);
-static int sk_proc_open(struct inode *inode, struct file *file);
-
-struct file_operations sk_proc_fops = {
-	.owner		= THIS_MODULE,
-	.open		= sk_proc_open,
-	.read		= seq_read,
-	.llseek		= seq_lseek,
-	.release	= single_release,
-};
-
-
-/*****************************************************************************
- *
- *      sk_seq_show - show proc information of a particular adapter
- *
- * Description:
- *  This function fills the proc entry with statistic data about 
- *  the ethernet device. It invokes the generic sk_gen_browse() to
- *  print out all items one per one.
- *  
- * Returns: 0
- *      
- */
-static int sk_seq_show(struct seq_file *seq, void *v)
-{
-	struct net_device *dev = seq->private;
-	DEV_NET			*pNet = netdev_priv(dev);
-	SK_AC			*pAC = pNet->pAC;
-	SK_PNMI_STRUCT_DATA 	*pPnmiStruct = &pAC->PnmiStruct;
-	unsigned long		Flags;	
-	unsigned int		Size;
-	char			sens_msg[50];
-	int 			t;
-	int 			i;
-
-	/* NetIndex in GetStruct is now required, zero is only dummy */
-	for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
-		if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
-			t--;
-
-		spin_lock_irqsave(&pAC->SlowPathLock, Flags);
-		Size = SK_PNMI_STRUCT_SIZE;
-#ifdef SK_DIAG_SUPPORT
-		if (pAC->BoardLevel == SK_INIT_DATA) {
-			SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
-			if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
-				pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
-			}
-		} else {
-			SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
-		}
-#else
-		SkPnmiGetStruct(pAC, pAC->IoBase, 
-				pPnmiStruct, &Size, t-1);
-#endif
-		spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
-	
-		if (pAC->dev[t-1] == dev) {
-			SK_PNMI_STAT	*pPnmiStat = &pPnmiStruct->Stat[0];
-
-			seq_printf(seq, "\nDetailed statistic for device %s\n",
-				      pAC->dev[t-1]->name);
-			seq_printf(seq, "=======================================\n");
-	
-			/* Board statistics */
-			seq_printf(seq, "\nBoard statistics\n\n");
-			seq_printf(seq, "Active Port                    %c\n",
-				      'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-								    Net[t-1].PrefPort]->PortNumber);
-			seq_printf(seq, "Preferred Port                 %c\n",
-				      'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
-								    Net[t-1].PrefPort]->PortNumber);
-
-			seq_printf(seq, "Bus speed (MHz)                %d\n",
-				      pPnmiStruct->BusSpeed);
-
-			seq_printf(seq, "Bus width (Bit)                %d\n",
-				      pPnmiStruct->BusWidth);
-			seq_printf(seq, "Driver version                 %s\n",
-				      VER_STRING);
-			seq_printf(seq, "Hardware revision              v%d.%d\n",
-				      (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
-				      pAC->GIni.GIPciHwRev & 0x0F);
-
-			/* Print sensor informations */
-			for (i=0; i < pAC->I2c.MaxSens; i ++) {
-				/* Check type */
-				switch (pAC->I2c.SenTable[i].SenType) {
-				case 1:
-					strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-					strcat(sens_msg, " (C)");
-					seq_printf(seq, "%-25s      %d.%02d\n",
-						      sens_msg,
-						      pAC->I2c.SenTable[i].SenValue / 10,
-						      pAC->I2c.SenTable[i].SenValue % 10);
-
-					strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-					strcat(sens_msg, " (F)");
-					seq_printf(seq, "%-25s      %d.%02d\n",
-						      sens_msg,
-						      ((((pAC->I2c.SenTable[i].SenValue)
-							 *10)*9)/5 + 3200)/100,
-						      ((((pAC->I2c.SenTable[i].SenValue)
-							 *10)*9)/5 + 3200) % 10);
-					break;
-				case 2:
-					strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-					strcat(sens_msg, " (V)");
-					seq_printf(seq, "%-25s      %d.%03d\n",
-						      sens_msg,
-						      pAC->I2c.SenTable[i].SenValue / 1000,
-						      pAC->I2c.SenTable[i].SenValue % 1000);
-					break;
-				case 3:
-					strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
-					strcat(sens_msg, " (rpm)");
-					seq_printf(seq, "%-25s      %d\n",
-						      sens_msg,
-						      pAC->I2c.SenTable[i].SenValue);
-					break;
-				default:
-					break;
-				}
-			}
-				
-			/*Receive statistics */
-			seq_printf(seq, "\nReceive statistics\n\n");
-
-			seq_printf(seq, "Received bytes                 %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
-			seq_printf(seq, "Received packets               %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxOkCts);
-#if 0
-			if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && 
-			    pAC->HWRevision < 12) {
-				pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - 
-					pPnmiStat->StatRxShortsCts;
-				pPnmiStat->StatRxShortsCts = 0;
-			}
-#endif
-			if (dev->mtu > 1500)
-				pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
-					pPnmiStat->StatRxTooLongCts;
-
-			seq_printf(seq, "Receive errors                 %Lu\n",
-				      (unsigned long long) pPnmiStruct->InErrorsCts);
-			seq_printf(seq, "Receive dropped                %Lu\n",
-				      (unsigned long long) pPnmiStruct->RxNoBufCts);
-			seq_printf(seq, "Received multicast             %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
-			seq_printf(seq, "Receive error types\n");
-			seq_printf(seq, "   length                      %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxRuntCts);
-			seq_printf(seq, "   buffer overflow             %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
-			seq_printf(seq, "   bad crc                     %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxFcsCts);
-			seq_printf(seq, "   framing                     %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxFramingCts);
-			seq_printf(seq, "   missed frames               %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxMissedCts);
-
-			if (dev->mtu > 1500)
-				pPnmiStat->StatRxTooLongCts = 0;
-
-			seq_printf(seq, "   too long                    %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxTooLongCts);					
-			seq_printf(seq, "   carrier extension           %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxCextCts);				
-			seq_printf(seq, "   too short                   %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxShortsCts);				
-			seq_printf(seq, "   symbol                      %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxSymbolCts);				
-			seq_printf(seq, "   LLC MAC size                %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxIRLengthCts);				
-			seq_printf(seq, "   carrier event               %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxCarrierCts);				
-			seq_printf(seq, "   jabber                      %Lu\n",
-				      (unsigned long long) pPnmiStat->StatRxJabberCts);				
-
-
-			/*Transmit statistics */
-			seq_printf(seq, "\nTransmit statistics\n\n");
-				
-			seq_printf(seq, "Transmited bytes               %Lu\n",
-				      (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
-			seq_printf(seq, "Transmited packets             %Lu\n",
-				      (unsigned long long) pPnmiStat->StatTxOkCts);
-			seq_printf(seq, "Transmit errors                %Lu\n",
-				      (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-			seq_printf(seq, "Transmit dropped               %Lu\n",
-				      (unsigned long long) pPnmiStruct->TxNoBufCts);
-			seq_printf(seq, "Transmit collisions            %Lu\n",
-				      (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
-			seq_printf(seq, "Transmit error types\n");
-			seq_printf(seq, "   excessive collision         %ld\n",
-				      pAC->stats.tx_aborted_errors);
-			seq_printf(seq, "   carrier                     %Lu\n",
-				      (unsigned long long) pPnmiStat->StatTxCarrierCts);
-			seq_printf(seq, "   fifo underrun               %Lu\n",
-				      (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
-			seq_printf(seq, "   heartbeat                   %Lu\n",
-				      (unsigned long long) pPnmiStat->StatTxCarrierCts);
-			seq_printf(seq, "   window                      %ld\n",
-				      pAC->stats.tx_window_errors);
-				
-		}
-	}
-	return 0;
-}
-
-/*****************************************************************************
- *
- *      sk_proc_open - register the show function when proc is open'ed
- *  
- * Description:
- *  This function is called whenever a sk98lin proc file is queried.
- *  
- * Returns: the return value of single_open()
- *      
- */
-static int sk_proc_open(struct inode *inode, struct file *file)
-{
-    return single_open(file, sk_seq_show, PDE(inode)->data);
-}
-
-/*******************************************************************************
- *
- * End of file
- *
- ******************************************************************************/
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 596c93b..b538e30 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -25,6 +25,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -43,7 +44,7 @@
 #include "skge.h"
 
 #define DRV_NAME		"skge"
-#define DRV_VERSION		"1.2"
+#define DRV_VERSION		"1.3"
 #define PFX			DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE	128
@@ -88,15 +89,14 @@
 
 static int skge_up(struct net_device *dev);
 static int skge_down(struct net_device *dev);
+static void skge_phy_reset(struct skge_port *skge);
 static void skge_tx_clean(struct skge_port *skge);
 static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static void genesis_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_init(struct skge_hw *hw, int port);
-static void yukon_reset(struct skge_hw *hw, int port);
 static void genesis_mac_init(struct skge_hw *hw, int port);
-static void genesis_reset(struct skge_hw *hw, int port);
 static void genesis_link_up(struct skge_port *skge);
 
 /* Avoid conditionals by using array */
@@ -276,10 +276,9 @@
 	skge->autoneg = ecmd->autoneg;
 	skge->advertising = ecmd->advertising;
 
-	if (netif_running(dev)) {
-		skge_down(dev);
-		skge_up(dev);
-	}
+	if (netif_running(dev))
+		skge_phy_reset(skge);
+
 	return (0);
 }
 
@@ -399,6 +398,7 @@
 			       struct ethtool_ringparam *p)
 {
 	struct skge_port *skge = netdev_priv(dev);
+	int err;
 
 	if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE ||
 	    p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE)
@@ -409,7 +409,9 @@
 
 	if (netif_running(dev)) {
 		skge_down(dev);
-		skge_up(dev);
+		err = skge_up(dev);
+		if (err)
+			dev_close(dev);
 	}
 
 	return 0;
@@ -430,21 +432,11 @@
 static int skge_nway_reset(struct net_device *dev)
 {
 	struct skge_port *skge = netdev_priv(dev);
-	struct skge_hw *hw = skge->hw;
-	int port = skge->port;
 
 	if (skge->autoneg != AUTONEG_ENABLE || !netif_running(dev))
 		return -EINVAL;
 
-	spin_lock_bh(&hw->phy_lock);
-	if (hw->chip_id == CHIP_ID_GENESIS) {
-		genesis_reset(hw, port);
-		genesis_mac_init(hw, port);
-	} else {
-		yukon_reset(hw, port);
-		yukon_init(hw, port);
-	}
-	spin_unlock_bh(&hw->phy_lock);
+	skge_phy_reset(skge);
 	return 0;
 }
 
@@ -516,10 +508,8 @@
 	else
 		skge->flow_control = FLOW_MODE_NONE;
 
-	if (netif_running(dev)) {
-		skge_down(dev);
-		skge_up(dev);
-	}
+	if (netif_running(dev))
+		skge_phy_reset(skge);
 	return 0;
 }
 
@@ -2019,6 +2009,25 @@
 	/* XXX restart autonegotiation? */
 }
 
+static void skge_phy_reset(struct skge_port *skge)
+{
+	struct skge_hw *hw = skge->hw;
+	int port = skge->port;
+
+	netif_stop_queue(skge->netdev);
+	netif_carrier_off(skge->netdev);
+
+	spin_lock_bh(&hw->phy_lock);
+	if (hw->chip_id == CHIP_ID_GENESIS) {
+		genesis_reset(hw, port);
+		genesis_mac_init(hw, port);
+	} else {
+		yukon_reset(hw, port);
+		yukon_init(hw, port);
+	}
+	spin_unlock_bh(&hw->phy_lock);
+}
+
 /* Basic MII support */
 static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -2187,6 +2196,7 @@
 	kfree(skge->rx_ring.start);
  free_pci_mem:
 	pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+	skge->mem = NULL;
 
 	return err;
 }
@@ -2197,6 +2207,9 @@
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
 
+	if (skge->mem == NULL)
+		return 0;
+
 	if (netif_msg_ifdown(skge))
 		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
 
@@ -2253,6 +2266,7 @@
 	kfree(skge->rx_ring.start);
 	kfree(skge->tx_ring.start);
 	pci_free_consistent(hw->pdev, skge->mem_size, skge->mem, skge->dma);
+	skge->mem = NULL;
 	return 0;
 }
 
@@ -2280,11 +2294,13 @@
  	}
 
 	if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) {
-		netif_stop_queue(dev);
-		spin_unlock_irqrestore(&skge->tx_lock, flags);
+		if (!netif_queue_stopped(dev)) {
+			netif_stop_queue(dev);
 
-		printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
-		       dev->name);
+			printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
+			       dev->name);
+		}
+		spin_unlock_irqrestore(&skge->tx_lock, flags);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -2300,14 +2316,12 @@
 	td->dma_hi = map >> 32;
 
 	if (skb->ip_summed == CHECKSUM_HW) {
-		const struct iphdr *ip
-			= (const struct iphdr *) (skb->data + ETH_HLEN);
 		int offset = skb->h.raw - skb->data;
 
 		/* This seems backwards, but it is what the sk98lin
 		 * does.  Looks like hardware is wrong?
 		 */
-		if (ip->protocol == IPPROTO_UDP
+		if (skb->h.ipiph->protocol == IPPROTO_UDP
 	            && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON)
 			control = BMU_TCP_CHECK;
 		else
@@ -2413,18 +2427,23 @@
 
 static int skge_change_mtu(struct net_device *dev, int new_mtu)
 {
-	int err = 0;
-	int running = netif_running(dev);
+	int err;
 
 	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
 		return -EINVAL;
 
+	if (!netif_running(dev)) {
+		dev->mtu = new_mtu;
+		return 0;
+	}
 
-	if (running)
-		skge_down(dev);
+	skge_down(dev);
+
 	dev->mtu = new_mtu;
-	if (running)
-		skge_up(dev);
+
+	err = skge_up(dev);
+	if (err)
+		dev_close(dev);
 
 	return err;
 }
@@ -3398,8 +3417,8 @@
 		struct net_device *dev = hw->dev[i];
 		if (dev) {
 			netif_device_attach(dev);
-			if (netif_running(dev))
-				skge_up(dev);
+			if (netif_running(dev) && skge_up(dev))
+				dev_close(dev);
 		}
 	}
 	return 0;
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index ee123c1..2efdacc 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -475,18 +475,6 @@
 	Q_T2	= 0x40,	/* 32 bit	Test Register 2	*/
 	Q_T3	= 0x44,	/* 32 bit	Test Register 3	*/
 
-/* Yukon-2 */
-	Q_DONE	= 0x24,	/* 16 bit	Done Index 		(Yukon-2 only) */
-	Q_WM	= 0x40,	/* 16 bit	FIFO Watermark */
-	Q_AL	= 0x42,	/*  8 bit	FIFO Alignment */
-	Q_RSP	= 0x44,	/* 16 bit	FIFO Read Shadow Pointer */
-	Q_RSL	= 0x46,	/*  8 bit	FIFO Read Shadow Level */
-	Q_RP	= 0x48,	/*  8 bit	FIFO Read Pointer */
-	Q_RL	= 0x4a,	/*  8 bit	FIFO Read Level */
-	Q_WP	= 0x4c,	/*  8 bit	FIFO Write Pointer */
-	Q_WSP	= 0x4d,	/*  8 bit	FIFO Write Shadow Pointer */
-	Q_WL	= 0x4e,	/*  8 bit	FIFO Write Level */
-	Q_WSL	= 0x4f,	/*  8 bit	FIFO Write Shadow Level */
 };
 #define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
 
@@ -675,22 +663,16 @@
 	LED_OFF	= 1<<0,	/* switch LED off */
 };
 
-/* Receive GMAC FIFO (YUKON and Yukon-2) */
+/* Receive GMAC FIFO (YUKON) */
 enum {
 	RX_GMF_EA	= 0x0c40,/* 32 bit	Rx GMAC FIFO End Address */
 	RX_GMF_AF_THR	= 0x0c44,/* 32 bit	Rx GMAC FIFO Almost Full Thresh. */
 	RX_GMF_CTRL_T	= 0x0c48,/* 32 bit	Rx GMAC FIFO Control/Test */
 	RX_GMF_FL_MSK	= 0x0c4c,/* 32 bit	Rx GMAC FIFO Flush Mask */
 	RX_GMF_FL_THR	= 0x0c50,/* 32 bit	Rx GMAC FIFO Flush Threshold */
-	RX_GMF_TR_THR	= 0x0c54,/* 32 bit	Rx Truncation Threshold (Yukon-2) */
-
-	RX_GMF_VLAN	= 0x0c5c,/* 32 bit	Rx VLAN Type Register (Yukon-2) */
 	RX_GMF_WP	= 0x0c60,/* 32 bit	Rx GMAC FIFO Write Pointer */
-
 	RX_GMF_WLEV	= 0x0c68,/* 32 bit	Rx GMAC FIFO Write Level */
-
 	RX_GMF_RP	= 0x0c70,/* 32 bit	Rx GMAC FIFO Read Pointer */
-
 	RX_GMF_RLEV	= 0x0c78,/* 32 bit	Rx GMAC FIFO Read Level */
 };
 
@@ -855,48 +837,6 @@
 	GMAC_TI_ST_TST	= 0x0e1a,/*  8 bit	Time Stamp Timer Test Reg */
 };
 
-/* Status BMU Registers (Yukon-2 only)*/
-enum {
-	STAT_CTRL	= 0x0e80,/* 32 bit	Status BMU Control Reg */
-	STAT_LAST_IDX	= 0x0e84,/* 16 bit	Status BMU Last Index */
-	/* 0x0e85 - 0x0e86:	reserved */
-	STAT_LIST_ADDR_LO	= 0x0e88,/* 32 bit	Status List Start Addr (low) */
-	STAT_LIST_ADDR_HI	= 0x0e8c,/* 32 bit	Status List Start Addr (high) */
-	STAT_TXA1_RIDX	= 0x0e90,/* 16 bit	Status TxA1 Report Index Reg */
-	STAT_TXS1_RIDX	= 0x0e92,/* 16 bit	Status TxS1 Report Index Reg */
-	STAT_TXA2_RIDX	= 0x0e94,/* 16 bit	Status TxA2 Report Index Reg */
-	STAT_TXS2_RIDX	= 0x0e96,/* 16 bit	Status TxS2 Report Index Reg */
-	STAT_TX_IDX_TH	= 0x0e98,/* 16 bit	Status Tx Index Threshold Reg */
-	STAT_PUT_IDX	= 0x0e9c,/* 16 bit	Status Put Index Reg */
-
-/* FIFO Control/Status Registers (Yukon-2 only)*/
-	STAT_FIFO_WP	= 0x0ea0,/*  8 bit	Status FIFO Write Pointer Reg */
-	STAT_FIFO_RP	= 0x0ea4,/*  8 bit	Status FIFO Read Pointer Reg */
-	STAT_FIFO_RSP	= 0x0ea6,/*  8 bit	Status FIFO Read Shadow Ptr */
-	STAT_FIFO_LEVEL	= 0x0ea8,/*  8 bit	Status FIFO Level Reg */
-	STAT_FIFO_SHLVL	= 0x0eaa,/*  8 bit	Status FIFO Shadow Level Reg */
-	STAT_FIFO_WM	= 0x0eac,/*  8 bit	Status FIFO Watermark Reg */
-	STAT_FIFO_ISR_WM	= 0x0ead,/*  8 bit	Status FIFO ISR Watermark Reg */
-
-/* Level and ISR Timer Registers (Yukon-2 only)*/
-	STAT_LEV_TIMER_INI	= 0x0eb0,/* 32 bit	Level Timer Init. Value Reg */
-	STAT_LEV_TIMER_CNT	= 0x0eb4,/* 32 bit	Level Timer Counter Reg */
-	STAT_LEV_TIMER_CTRL	= 0x0eb8,/*  8 bit	Level Timer Control Reg */
-	STAT_LEV_TIMER_TEST	= 0x0eb9,/*  8 bit	Level Timer Test Reg */
-	STAT_TX_TIMER_INI	= 0x0ec0,/* 32 bit	Tx Timer Init. Value Reg */
-	STAT_TX_TIMER_CNT	= 0x0ec4,/* 32 bit	Tx Timer Counter Reg */
-	STAT_TX_TIMER_CTRL	= 0x0ec8,/*  8 bit	Tx Timer Control Reg */
-	STAT_TX_TIMER_TEST	= 0x0ec9,/*  8 bit	Tx Timer Test Reg */
-	STAT_ISR_TIMER_INI	= 0x0ed0,/* 32 bit	ISR Timer Init. Value Reg */
-	STAT_ISR_TIMER_CNT	= 0x0ed4,/* 32 bit	ISR Timer Counter Reg */
-	STAT_ISR_TIMER_CTRL	= 0x0ed8,/*  8 bit	ISR Timer Control Reg */
-	STAT_ISR_TIMER_TEST	= 0x0ed9,/*  8 bit	ISR Timer Test Reg */
-
-	ST_LAST_IDX_MASK	= 0x007f,/* Last Index Mask */
-	ST_TXRP_IDX_MASK	= 0x0fff,/* Tx Report Index Mask */
-	ST_TXTH_IDX_MASK	= 0x0fff,/* Tx Threshold Index Mask */
-	ST_WM_IDX_MASK	= 0x3f,/* FIFO Watermark Index Mask */
-};
 
 enum {
 	LINKLED_OFF 	     = 0x01,
@@ -923,8 +863,6 @@
 	WOL_MATCH_CTL	= 0x0f22,/*  8 bit	WOL Match Control Reg */
 	WOL_MATCH_RES	= 0x0f23,/*  8 bit	WOL Match Result Reg */
 	WOL_MAC_ADDR	= 0x0f24,/* 32 bit	WOL MAC Address */
-	WOL_PATT_PME	= 0x0f2a,/*  8 bit	WOL PME Match Enable (Yukon-2) */
-	WOL_PATT_ASFM	= 0x0f2b,/*  8 bit	WOL ASF Match Enable (Yukon-2) */
 	WOL_PATT_RPTR	= 0x0f2c,/*  8 bit	WOL Pattern Read Pointer */
 
 /* WOL Pattern Length Registers (YUKON only) */
@@ -1641,15 +1579,6 @@
 	PHY_M_FESC_SEL_CL_A	= 1<<0, /* Select Class A driver (100B-TX) */
 };
 
-/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
-/*****  PHY_MARV_PHY_CTRL (page 2)		16 bit r/w	MAC Specific Ctrl *****/
-enum {
-	PHY_M_MAC_MD_MSK	= 7<<7, /* Bit  9.. 7: Mode Select Mask */
-	PHY_M_MAC_MD_AUTO	= 3,/* Auto Copper/1000Base-X */
-	PHY_M_MAC_MD_COPPER	= 5,/* Copper only */
-	PHY_M_MAC_MD_1000BX	= 7,/* 1000Base-X only */
-};
-#define PHY_M_MAC_MODE_SEL(x)	(((x)<<7) & PHY_M_MAC_MD_MSK)
 
 /*****  PHY_MARV_PHY_CTRL (page 3)		16 bit r/w	LED Control Reg. *****/
 enum {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
new file mode 100644
index 0000000..f5d697c
--- /dev/null
+++ b/drivers/net/sky2.c
@@ -0,0 +1,3262 @@
+/*
+ * New driver for Marvell Yukon 2 chipset.
+ * Based on earlier sk98lin, and skge driver.
+ *
+ * This driver intentionally does not support all the features
+ * of the original driver such as link fail-over and link management because
+ * those should be done at higher levels.
+ *
+ * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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.
+ */
+
+/*
+ * TOTEST
+ *	- speed setting
+ *	- suspend/resume
+ */
+
+#include <linux/config.h>
+#include <linux/crc32.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/if_vlan.h>
+#include <linux/prefetch.h>
+#include <linux/mii.h>
+
+#include <asm/irq.h>
+
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define SKY2_VLAN_TAG_USED 1
+#endif
+
+#include "sky2.h"
+
+#define DRV_NAME		"sky2"
+#define DRV_VERSION		"0.11"
+#define PFX			DRV_NAME " "
+
+/*
+ * The Yukon II chipset takes 64 bit command blocks (called list elements)
+ * that are organized into three (receive, transmit, status) different rings
+ * similar to Tigon3. A transmit can require several elements;
+ * a receive requires one (or two if using 64 bit dma).
+ */
+
+#define is_ec_a1(hw) \
+	unlikely((hw)->chip_id == CHIP_ID_YUKON_EC && \
+		 (hw)->chip_rev == CHIP_REV_YU_EC_A1)
+
+#define RX_LE_SIZE	    	512
+#define RX_LE_BYTES		(RX_LE_SIZE*sizeof(struct sky2_rx_le))
+#define RX_MAX_PENDING		(RX_LE_SIZE/2 - 2)
+#define RX_DEF_PENDING		RX_MAX_PENDING
+
+#define TX_RING_SIZE		512
+#define TX_DEF_PENDING		(TX_RING_SIZE - 1)
+#define TX_MIN_PENDING		64
+#define MAX_SKB_TX_LE		(4 + 2*MAX_SKB_FRAGS)
+
+#define STATUS_RING_SIZE	2048	/* 2 ports * (TX + 2*RX) */
+#define STATUS_LE_BYTES		(STATUS_RING_SIZE*sizeof(struct sky2_status_le))
+#define ETH_JUMBO_MTU		9000
+#define TX_WATCHDOG		(5 * HZ)
+#define NAPI_WEIGHT		64
+#define PHY_RETRIES		1000
+
+static const u32 default_msg =
+    NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
+    | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR
+    | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_INTR;
+
+static int debug = -1;		/* defaults above */
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+
+static int copybreak __read_mostly = 256;
+module_param(copybreak, int, 0);
+MODULE_PARM_DESC(copybreak, "Receive copy threshold");
+
+static const struct pci_device_id sky2_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4343) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4344) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4345) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4346) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4347) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, sky2_id_table);
+
+/* Avoid conditionals by using array */
+static const unsigned txqaddr[] = { Q_XA1, Q_XA2 };
+static const unsigned rxqaddr[] = { Q_R1, Q_R2 };
+
+/* This driver supports yukon2 chipset only */
+static const char *yukon2_name[] = {
+	"XL",		/* 0xb3 */
+	"EC Ultra", 	/* 0xb4 */
+	"UNKNOWN",	/* 0xb5 */
+	"EC",		/* 0xb6 */
+	"FE",		/* 0xb7 */
+};
+
+/* Access to external PHY */
+static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
+{
+	int i;
+
+	gma_write16(hw, port, GM_SMI_DATA, val);
+	gma_write16(hw, port, GM_SMI_CTRL,
+		    GM_SMI_CT_PHY_AD(PHY_ADDR_MARV) | GM_SMI_CT_REG_AD(reg));
+
+	for (i = 0; i < PHY_RETRIES; i++) {
+		if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+			return 0;
+		udelay(1);
+	}
+
+	printk(KERN_WARNING PFX "%s: phy write timeout\n", hw->dev[port]->name);
+	return -ETIMEDOUT;
+}
+
+static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
+{
+	int i;
+
+	gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(PHY_ADDR_MARV)
+		    | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
+
+	for (i = 0; i < PHY_RETRIES; i++) {
+		if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) {
+			*val = gma_read16(hw, port, GM_SMI_DATA);
+			return 0;
+		}
+
+		udelay(1);
+	}
+
+	return -ETIMEDOUT;
+}
+
+static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg)
+{
+	u16 v;
+
+	if (__gm_phy_read(hw, port, reg, &v) != 0)
+		printk(KERN_WARNING PFX "%s: phy read timeout\n", hw->dev[port]->name);
+	return v;
+}
+
+static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state)
+{
+	u16 power_control;
+	u32 reg1;
+	int vaux;
+	int ret = 0;
+
+	pr_debug("sky2_set_power_state %d\n", state);
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+
+	pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control);
+	vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) &&
+		(power_control & PCI_PM_CAP_PME_D3cold);
+
+	pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control);
+
+	power_control |= PCI_PM_CTRL_PME_STATUS;
+	power_control &= ~(PCI_PM_CTRL_STATE_MASK);
+
+	switch (state) {
+	case PCI_D0:
+		/* switch power to VCC (WA for VAUX problem) */
+		sky2_write8(hw, B0_POWER_CTRL,
+			    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
+
+		/* disable Core Clock Division, */
+		sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS);
+
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+			/* enable bits are inverted */
+			sky2_write8(hw, B2_Y2_CLK_GATE,
+				    Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
+				    Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
+				    Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
+		else
+			sky2_write8(hw, B2_Y2_CLK_GATE, 0);
+
+		/* Turn off phy power saving */
+		pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg1);
+		reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+
+		/* looks like this XL is back asswards .. */
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) {
+			reg1 |= PCI_Y2_PHY1_COMA;
+			if (hw->ports > 1)
+				reg1 |= PCI_Y2_PHY2_COMA;
+		}
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
+		break;
+
+	case PCI_D3hot:
+	case PCI_D3cold:
+		/* Turn on phy power saving */
+		pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg1);
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+			reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+		else
+			reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD);
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
+
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
+			sky2_write8(hw, B2_Y2_CLK_GATE, 0);
+		else
+			/* enable bits are inverted */
+			sky2_write8(hw, B2_Y2_CLK_GATE,
+				    Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS |
+				    Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS |
+				    Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS);
+
+		/* switch power to VAUX */
+		if (vaux && state != PCI_D3cold)
+			sky2_write8(hw, B0_POWER_CTRL,
+				    (PC_VAUX_ENA | PC_VCC_ENA |
+				     PC_VAUX_ON | PC_VCC_OFF));
+		break;
+	default:
+		printk(KERN_ERR PFX "Unknown power state %d\n", state);
+		ret = -1;
+	}
+
+	pci_write_config_byte(hw->pdev, hw->pm_cap + PCI_PM_CTRL, power_control);
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+	return ret;
+}
+
+static void sky2_phy_reset(struct sky2_hw *hw, unsigned port)
+{
+	u16 reg;
+
+	/* disable all GMAC IRQ's */
+	sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+	/* disable PHY IRQs */
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+
+	gma_write16(hw, port, GM_MC_ADDR_H1, 0);	/* clear MC hash */
+	gma_write16(hw, port, GM_MC_ADDR_H2, 0);
+	gma_write16(hw, port, GM_MC_ADDR_H3, 0);
+	gma_write16(hw, port, GM_MC_ADDR_H4, 0);
+
+	reg = gma_read16(hw, port, GM_RX_CTRL);
+	reg |= GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA;
+	gma_write16(hw, port, GM_RX_CTRL, reg);
+}
+
+static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
+{
+	struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
+	u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
+
+	if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) {
+		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
+
+		ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
+			   PHY_M_EC_MAC_S_MSK);
+		ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ);
+
+		if (hw->chip_id == CHIP_ID_YUKON_EC)
+			ectrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA;
+		else
+			ectrl |= PHY_M_EC_M_DSC(2) | PHY_M_EC_S_DSC(3);
+
+		gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl);
+	}
+
+	ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+	if (hw->copper) {
+		if (hw->chip_id == CHIP_ID_YUKON_FE) {
+			/* enable automatic crossover */
+			ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
+		} else {
+			/* disable energy detect */
+			ctrl &= ~PHY_M_PC_EN_DET_MSK;
+
+			/* enable automatic crossover */
+			ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO);
+
+			if (sky2->autoneg == AUTONEG_ENABLE &&
+			    hw->chip_id == CHIP_ID_YUKON_XL) {
+				ctrl &= ~PHY_M_PC_DSC_MSK;
+				ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
+			}
+		}
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+	} else {
+		/* workaround for deviation #4.88 (CRC errors) */
+		/* disable Automatic Crossover */
+
+		ctrl &= ~PHY_M_PC_MDIX_MSK;
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+		if (hw->chip_id == CHIP_ID_YUKON_XL) {
+			/* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
+			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
+			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+			ctrl &= ~PHY_M_MAC_MD_MSK;
+			ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
+			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+			/* select page 1 to access Fiber registers */
+			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
+		}
+	}
+
+	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+	if (sky2->autoneg == AUTONEG_DISABLE)
+		ctrl &= ~PHY_CT_ANE;
+	else
+		ctrl |= PHY_CT_ANE;
+
+	ctrl |= PHY_CT_RESET;
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+	ctrl = 0;
+	ct1000 = 0;
+	adv = PHY_AN_CSMA;
+
+	if (sky2->autoneg == AUTONEG_ENABLE) {
+		if (hw->copper) {
+			if (sky2->advertising & ADVERTISED_1000baseT_Full)
+				ct1000 |= PHY_M_1000C_AFD;
+			if (sky2->advertising & ADVERTISED_1000baseT_Half)
+				ct1000 |= PHY_M_1000C_AHD;
+			if (sky2->advertising & ADVERTISED_100baseT_Full)
+				adv |= PHY_M_AN_100_FD;
+			if (sky2->advertising & ADVERTISED_100baseT_Half)
+				adv |= PHY_M_AN_100_HD;
+			if (sky2->advertising & ADVERTISED_10baseT_Full)
+				adv |= PHY_M_AN_10_FD;
+			if (sky2->advertising & ADVERTISED_10baseT_Half)
+				adv |= PHY_M_AN_10_HD;
+		} else		/* special defines for FIBER (88E1011S only) */
+			adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD;
+
+		/* Set Flow-control capabilities */
+		if (sky2->tx_pause && sky2->rx_pause)
+			adv |= PHY_AN_PAUSE_CAP;	/* symmetric */
+		else if (sky2->rx_pause && !sky2->tx_pause)
+			adv |= PHY_AN_PAUSE_ASYM | PHY_AN_PAUSE_CAP;
+		else if (!sky2->rx_pause && sky2->tx_pause)
+			adv |= PHY_AN_PAUSE_ASYM;	/* local */
+
+		/* Restart Auto-negotiation */
+		ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+	} else {
+		/* forced speed/duplex settings */
+		ct1000 = PHY_M_1000C_MSE;
+
+		if (sky2->duplex == DUPLEX_FULL)
+			ctrl |= PHY_CT_DUP_MD;
+
+		switch (sky2->speed) {
+		case SPEED_1000:
+			ctrl |= PHY_CT_SP1000;
+			break;
+		case SPEED_100:
+			ctrl |= PHY_CT_SP100;
+			break;
+		}
+
+		ctrl |= PHY_CT_RESET;
+	}
+
+	if (hw->chip_id != CHIP_ID_YUKON_FE)
+		gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
+
+	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+	/* Setup Phy LED's */
+	ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
+	ledover = 0;
+
+	switch (hw->chip_id) {
+	case CHIP_ID_YUKON_FE:
+		/* on 88E3082 these bits are at 11..9 (shifted left) */
+		ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1;
+
+		ctrl = gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR);
+
+		/* delete ACT LED control bits */
+		ctrl &= ~PHY_M_FELP_LED1_MSK;
+		/* change ACT LED control to blink mode */
+		ctrl |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL);
+		gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
+		break;
+
+	case CHIP_ID_YUKON_XL:
+		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+
+		/* select page 3 to access LED control register */
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+
+		/* set LED Function Control register */
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) |	/* LINK/ACT */
+							   PHY_M_LEDC_INIT_CTRL(7) |	/* 10 Mbps */
+							   PHY_M_LEDC_STA1_CTRL(7) |	/* 100 Mbps */
+							   PHY_M_LEDC_STA0_CTRL(7)));	/* 1000 Mbps */
+
+		/* set Polarity Control register */
+		gm_phy_write(hw, port, PHY_MARV_PHY_STAT,
+			     (PHY_M_POLC_LS1_P_MIX(4) |
+			      PHY_M_POLC_IS0_P_MIX(4) |
+			      PHY_M_POLC_LOS_CTRL(2) |
+			      PHY_M_POLC_INIT_CTRL(2) |
+			      PHY_M_POLC_STA1_CTRL(2) |
+			      PHY_M_POLC_STA0_CTRL(2)));
+
+		/* restore page register */
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+		break;
+
+	default:
+		/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */
+		ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL;
+		/* turn off the Rx LED (LED_RX) */
+		ledover |= PHY_M_LED_MO_RX(MO_LED_OFF);
+	}
+
+	gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+
+	if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
+		/* turn on 100 Mbps LED (LED_LINK100) */
+		ledover |= PHY_M_LED_MO_100(MO_LED_ON);
+	}
+
+	if (ledover)
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+
+	/* Enable phy interrupt on auto-negotiation complete (or link up) */
+	if (sky2->autoneg == AUTONEG_ENABLE)
+		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL);
+	else
+		gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+}
+
+/* Force a renegotiation */
+static void sky2_phy_reinit(struct sky2_port *sky2)
+{
+	down(&sky2->phy_sema);
+	sky2_phy_init(sky2->hw, sky2->port);
+	up(&sky2->phy_sema);
+}
+
+static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
+{
+	struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
+	u16 reg;
+	int i;
+	const u8 *addr = hw->dev[port]->dev_addr;
+
+	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE);
+
+	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
+
+	if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 && port == 1) {
+		/* WA DEV_472 -- looks like crossed wires on port 2 */
+		/* clear GMAC 1 Control reset */
+		sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR);
+		do {
+			sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_SET);
+			sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_CLR);
+		} while (gm_phy_read(hw, 1, PHY_MARV_ID0) != PHY_MARV_ID0_VAL ||
+			 gm_phy_read(hw, 1, PHY_MARV_ID1) != PHY_MARV_ID1_Y2 ||
+			 gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0);
+	}
+
+	if (sky2->autoneg == AUTONEG_DISABLE) {
+		reg = gma_read16(hw, port, GM_GP_CTRL);
+		reg |= GM_GPCR_AU_ALL_DIS;
+		gma_write16(hw, port, GM_GP_CTRL, reg);
+		gma_read16(hw, port, GM_GP_CTRL);
+
+		switch (sky2->speed) {
+		case SPEED_1000:
+			reg |= GM_GPCR_SPEED_1000;
+			/* fallthru */
+		case SPEED_100:
+			reg |= GM_GPCR_SPEED_100;
+		}
+
+		if (sky2->duplex == DUPLEX_FULL)
+			reg |= GM_GPCR_DUP_FULL;
+	} else
+		reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL;
+
+	if (!sky2->tx_pause && !sky2->rx_pause) {
+		sky2_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+		reg |=
+		    GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+	} else if (sky2->tx_pause && !sky2->rx_pause) {
+		/* disable Rx flow-control */
+		reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS;
+	}
+
+	gma_write16(hw, port, GM_GP_CTRL, reg);
+
+	sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
+
+	down(&sky2->phy_sema);
+	sky2_phy_init(hw, port);
+	up(&sky2->phy_sema);
+
+	/* MIB clear */
+	reg = gma_read16(hw, port, GM_PHY_ADDR);
+	gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR);
+
+	for (i = 0; i < GM_MIB_CNT_SIZE; i++)
+		gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i);
+	gma_write16(hw, port, GM_PHY_ADDR, reg);
+
+	/* transmit control */
+	gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF));
+
+	/* receive control reg: unicast + multicast + no FCS  */
+	gma_write16(hw, port, GM_RX_CTRL,
+		    GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA);
+
+	/* transmit flow control */
+	gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff);
+
+	/* transmit parameter */
+	gma_write16(hw, port, GM_TX_PARAM,
+		    TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) |
+		    TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) |
+		    TX_IPG_JAM_DATA(TX_IPG_JAM_DEF) |
+		    TX_BACK_OFF_LIM(TX_BOF_LIM_DEF));
+
+	/* serial mode register */
+	reg = DATA_BLIND_VAL(DATA_BLIND_DEF) |
+		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
+
+	if (hw->dev[port]->mtu > ETH_DATA_LEN)
+		reg |= GM_SMOD_JUMBO_ENA;
+
+	gma_write16(hw, port, GM_SERIAL_MODE, reg);
+
+	/* virtual address for data */
+	gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr);
+
+	/* physical address: used for pause frames */
+	gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr);
+
+	/* ignore counter overflows */
+	gma_write16(hw, port, GM_TX_IRQ_MSK, 0);
+	gma_write16(hw, port, GM_RX_IRQ_MSK, 0);
+	gma_write16(hw, port, GM_TR_IRQ_MSK, 0);
+
+	/* Configure Rx MAC FIFO */
+	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
+	sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T),
+		     GMF_RX_CTRL_DEF);
+
+	/* Flush Rx MAC FIFO on any flow control or error */
+	sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
+
+	/* Set threshold to 0xa (64 bytes)
+	 *  ASF disabled so no need to do WA dev #4.30
+	 */
+	sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF);
+
+	/* Configure Tx MAC FIFO */
+	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
+	sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
+
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+		sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
+		sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
+		if (hw->dev[port]->mtu > ETH_DATA_LEN) {
+			/* set Tx GMAC FIFO Almost Empty Threshold */
+			sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), 0x180);
+			/* Disable Store & Forward mode for TX */
+			sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
+		}
+	}
+
+}
+
+static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, size_t len)
+{
+	u32 end;
+
+	start /= 8;
+	len /= 8;
+	end = start + len - 1;
+
+	sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
+	sky2_write32(hw, RB_ADDR(q, RB_START), start);
+	sky2_write32(hw, RB_ADDR(q, RB_END), end);
+	sky2_write32(hw, RB_ADDR(q, RB_WP), start);
+	sky2_write32(hw, RB_ADDR(q, RB_RP), start);
+
+	if (q == Q_R1 || q == Q_R2) {
+		u32 rxup, rxlo;
+
+		rxlo = len/2;
+		rxup = rxlo + len/4;
+
+		/* Set thresholds on receive queue's */
+		sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), rxup);
+		sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), rxlo);
+	} else {
+		/* Enable store & forward on Tx queue's because
+		 * Tx FIFO is only 1K on Yukon
+		 */
+		sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_STFWD);
+	}
+
+	sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_ENA_OP_MD);
+	sky2_read8(hw, RB_ADDR(q, RB_CTRL));
+}
+
+/* Setup Bus Memory Interface */
+static void sky2_qset(struct sky2_hw *hw, u16 q)
+{
+	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_RESET);
+	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_OPER_INIT);
+	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_FIFO_OP_ON);
+	sky2_write32(hw, Q_ADDR(q, Q_WM),  BMU_WM_DEFAULT);
+}
+
+/* Setup prefetch unit registers. This is the interface between
+ * hardware and driver list elements
+ */
+static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
+				      u64 addr, u32 last)
+{
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_CLR);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), addr >> 32);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), (u32) addr);
+	sky2_write16(hw, Y2_QADDR(qaddr, PREF_UNIT_LAST_IDX), last);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_OP_ON);
+
+	sky2_read32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL));
+}
+
+static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
+{
+	struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
+
+	sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE;
+	return le;
+}
+
+/*
+ * This is a workaround code taken from SysKonnect sk98lin driver
+ * to deal with chip bug on Yukon EC rev 0 in the wraparound case.
+ */
+static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q,
+				u16 idx, u16 *last, u16 size)
+{
+	if (is_ec_a1(hw) && idx < *last) {
+		u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
+
+		if (hwget == 0) {
+			/* Start prefetching again */
+			sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 0xe0);
+			goto setnew;
+		}
+
+		if (hwget == size - 1) {
+			/* set watermark to one list element */
+			sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 8);
+
+			/* set put index to first list element */
+			sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), 0);
+		} else		/* have hardware go to end of list */
+			sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX),
+				     size - 1);
+	} else {
+setnew:
+		sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
+	}
+	*last = idx;
+}
+
+
+static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
+{
+	struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
+	sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE;
+	return le;
+}
+
+/* Return high part of DMA address (could be 32 or 64 bit) */
+static inline u32 high32(dma_addr_t a)
+{
+	return (a >> 16) >> 16;
+}
+
+/* Build description to hardware about buffer */
+static inline void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
+{
+	struct sky2_rx_le *le;
+	u32 hi = high32(map);
+	u16 len = sky2->rx_bufsize;
+
+	if (sky2->rx_addr64 != hi) {
+		le = sky2_next_rx(sky2);
+		le->addr = cpu_to_le32(hi);
+		le->ctrl = 0;
+		le->opcode = OP_ADDR64 | HW_OWNER;
+		sky2->rx_addr64 = high32(map + len);
+	}
+
+	le = sky2_next_rx(sky2);
+	le->addr = cpu_to_le32((u32) map);
+	le->length = cpu_to_le16(len);
+	le->ctrl = 0;
+	le->opcode = OP_PACKET | HW_OWNER;
+}
+
+
+/* Tell chip where to start receive checksum.
+ * Actually has two checksums, but set both same to avoid possible byte
+ * order problems.
+ */
+static void rx_set_checksum(struct sky2_port *sky2)
+{
+	struct sky2_rx_le *le;
+
+	le = sky2_next_rx(sky2);
+	le->addr = (ETH_HLEN << 16) | ETH_HLEN;
+	le->ctrl = 0;
+	le->opcode = OP_TCPSTART | HW_OWNER;
+
+	sky2_write32(sky2->hw,
+		     Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+		     sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+
+}
+
+/*
+ * The RX Stop command will not work for Yukon-2 if the BMU does not
+ * reach the end of packet and since we can't make sure that we have
+ * incoming data, we must reset the BMU while it is not doing a DMA
+ * transfer. Since it is possible that the RX path is still active,
+ * the RX RAM buffer will be stopped first, so any possible incoming
+ * data will not trigger a DMA. After the RAM buffer is stopped, the
+ * BMU is polled until any DMA in progress is ended and only then it
+ * will be reset.
+ */
+static void sky2_rx_stop(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned rxq = rxqaddr[sky2->port];
+	int i;
+
+	/* disable the RAM Buffer receive queue */
+	sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_DIS_OP_MD);
+
+	for (i = 0; i < 0xffff; i++)
+		if (sky2_read8(hw, RB_ADDR(rxq, Q_RSL))
+		    == sky2_read8(hw, RB_ADDR(rxq, Q_RL)))
+			goto stopped;
+
+	printk(KERN_WARNING PFX "%s: receiver stop failed\n",
+	       sky2->netdev->name);
+stopped:
+	sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST);
+
+	/* reset the Rx prefetch unit */
+	sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+}
+
+/* Clean out receive buffer area, assumes receiver hardware stopped */
+static void sky2_rx_clean(struct sky2_port *sky2)
+{
+	unsigned i;
+
+	memset(sky2->rx_le, 0, RX_LE_BYTES);
+	for (i = 0; i < sky2->rx_pending; i++) {
+		struct ring_info *re = sky2->rx_ring + i;
+
+		if (re->skb) {
+			pci_unmap_single(sky2->hw->pdev,
+					 re->mapaddr, sky2->rx_bufsize,
+					 PCI_DMA_FROMDEVICE);
+			kfree_skb(re->skb);
+			re->skb = NULL;
+		}
+	}
+}
+
+/* Basic MII support */
+static int sky2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct mii_ioctl_data *data = if_mii(ifr);
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	int err = -EOPNOTSUPP;
+
+	if (!netif_running(dev))
+		return -ENODEV;	/* Phy still in reset */
+
+	switch(cmd) {
+	case SIOCGMIIPHY:
+		data->phy_id = PHY_ADDR_MARV;
+
+		/* fallthru */
+	case SIOCGMIIREG: {
+		u16 val = 0;
+
+		down(&sky2->phy_sema);
+		err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val);
+		up(&sky2->phy_sema);
+
+		data->val_out = val;
+		break;
+	}
+
+	case SIOCSMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		down(&sky2->phy_sema);
+		err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f,
+				   data->val_in);
+		up(&sky2->phy_sema);
+		break;
+	}
+	return err;
+}
+
+#ifdef SKY2_VLAN_TAG_USED
+static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	u16 port = sky2->port;
+
+	spin_lock(&sky2->tx_lock);
+
+	sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON);
+	sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON);
+	sky2->vlgrp = grp;
+
+	spin_unlock(&sky2->tx_lock);
+}
+
+static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	u16 port = sky2->port;
+
+	spin_lock(&sky2->tx_lock);
+
+	sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF);
+	sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF);
+	if (sky2->vlgrp)
+		sky2->vlgrp->vlan_devices[vid] = NULL;
+
+	spin_unlock(&sky2->tx_lock);
+}
+#endif
+
+/*
+ * Allocate and setup receiver buffer pool.
+ * In case of 64 bit dma, there are 2X as many list elements
+ * available as ring entries
+ * and need to reserve one list element so we don't wrap around.
+ *
+ * It appears the hardware has a bug in the FIFO logic that
+ * cause it to hang if the FIFO gets overrun and the receive buffer
+ * is not aligned.  This means we can't use skb_reserve to align
+ * the IP header.
+ */
+static int sky2_rx_start(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned rxq = rxqaddr[sky2->port];
+	int i;
+
+	sky2->rx_put = sky2->rx_next = 0;
+	sky2_qset(hw, rxq);
+	sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
+
+	rx_set_checksum(sky2);
+	for (i = 0; i < sky2->rx_pending; i++) {
+		struct ring_info *re = sky2->rx_ring + i;
+
+		re->skb = dev_alloc_skb(sky2->rx_bufsize);
+		if (!re->skb)
+			goto nomem;
+
+		re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
+					     sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+		sky2_rx_add(sky2, re->mapaddr);
+	}
+
+	/* Tell chip about available buffers */
+	sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
+	sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX));
+	return 0;
+nomem:
+	sky2_rx_clean(sky2);
+	return -ENOMEM;
+}
+
+/* Bring up network interface. */
+static int sky2_up(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u32 ramsize, rxspace;
+	int err = -ENOMEM;
+
+	if (netif_msg_ifup(sky2))
+		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
+
+	/* must be power of 2 */
+	sky2->tx_le = pci_alloc_consistent(hw->pdev,
+					   TX_RING_SIZE *
+					   sizeof(struct sky2_tx_le),
+					   &sky2->tx_le_map);
+	if (!sky2->tx_le)
+		goto err_out;
+
+	sky2->tx_ring = kcalloc(TX_RING_SIZE, sizeof(struct tx_ring_info),
+				GFP_KERNEL);
+	if (!sky2->tx_ring)
+		goto err_out;
+	sky2->tx_prod = sky2->tx_cons = 0;
+
+	sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
+					   &sky2->rx_le_map);
+	if (!sky2->rx_le)
+		goto err_out;
+	memset(sky2->rx_le, 0, RX_LE_BYTES);
+
+	sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct ring_info),
+				GFP_KERNEL);
+	if (!sky2->rx_ring)
+		goto err_out;
+
+	sky2_mac_init(hw, port);
+
+	/* Configure RAM buffers */
+	if (hw->chip_id == CHIP_ID_YUKON_FE ||
+	    (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == 2))
+		ramsize = 4096;
+	else {
+		u8 e0 = sky2_read8(hw, B2_E_0);
+		ramsize = (e0 == 0) ? (128 * 1024) : (e0 * 4096);
+	}
+
+	/* 2/3 for Rx */
+	rxspace = (2 * ramsize) / 3;
+	sky2_ramset(hw, rxqaddr[port], 0, rxspace);
+	sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);
+
+	/* Make sure SyncQ is disabled */
+	sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
+		    RB_RST_SET);
+
+	sky2_qset(hw, txqaddr[port]);
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U)
+		sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0);
+
+
+	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
+			   TX_RING_SIZE - 1);
+
+	err = sky2_rx_start(sky2);
+	if (err)
+		goto err_out;
+
+	/* Enable interrupts from phy/mac for port */
+	hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+	return 0;
+
+err_out:
+	if (sky2->rx_le) {
+		pci_free_consistent(hw->pdev, RX_LE_BYTES,
+				    sky2->rx_le, sky2->rx_le_map);
+		sky2->rx_le = NULL;
+	}
+	if (sky2->tx_le) {
+		pci_free_consistent(hw->pdev,
+				    TX_RING_SIZE * sizeof(struct sky2_tx_le),
+				    sky2->tx_le, sky2->tx_le_map);
+		sky2->tx_le = NULL;
+	}
+	kfree(sky2->tx_ring);
+	kfree(sky2->rx_ring);
+
+	sky2->tx_ring = NULL;
+	sky2->rx_ring = NULL;
+	return err;
+}
+
+/* Modular subtraction in ring */
+static inline int tx_dist(unsigned tail, unsigned head)
+{
+	return (head - tail) % TX_RING_SIZE;
+}
+
+/* Number of list elements available for next tx */
+static inline int tx_avail(const struct sky2_port *sky2)
+{
+	return sky2->tx_pending - tx_dist(sky2->tx_cons, sky2->tx_prod);
+}
+
+/* Estimate of number of transmit list elements required */
+static inline unsigned tx_le_req(const struct sk_buff *skb)
+{
+	unsigned count;
+
+	count = sizeof(dma_addr_t) / sizeof(u32);
+	count += skb_shinfo(skb)->nr_frags * count;
+
+	if (skb_shinfo(skb)->tso_size)
+		++count;
+
+	if (skb->ip_summed == CHECKSUM_HW)
+		++count;
+
+	return count;
+}
+
+/*
+ * Put one packet in ring for transmit.
+ * A single packet can generate multiple list elements, and
+ * the number of ring elements will probably be less than the number
+ * of list elements used.
+ *
+ * No BH disabling for tx_lock here (like tg3)
+ */
+static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	struct sky2_tx_le *le = NULL;
+	struct tx_ring_info *re;
+	unsigned i, len;
+	dma_addr_t mapping;
+	u32 addr64;
+	u16 mss;
+	u8 ctrl;
+
+	if (!spin_trylock(&sky2->tx_lock))
+		return NETDEV_TX_LOCKED;
+
+	if (unlikely(tx_avail(sky2) < tx_le_req(skb))) {
+		/* There is a known but harmless race with lockless tx
+		 * and netif_stop_queue.
+		 */
+		if (!netif_queue_stopped(dev)) {
+			netif_stop_queue(dev);
+			printk(KERN_WARNING PFX "%s: ring full when queue awake!\n",
+			       dev->name);
+		}
+		spin_unlock(&sky2->tx_lock);
+
+		return NETDEV_TX_BUSY;
+	}
+
+	if (unlikely(netif_msg_tx_queued(sky2)))
+		printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
+		       dev->name, sky2->tx_prod, skb->len);
+
+	len = skb_headlen(skb);
+	mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	addr64 = high32(mapping);
+
+	re = sky2->tx_ring + sky2->tx_prod;
+
+	/* Send high bits if changed or crosses boundary */
+	if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
+		le = get_tx_le(sky2);
+		le->tx.addr = cpu_to_le32(addr64);
+		le->ctrl = 0;
+		le->opcode = OP_ADDR64 | HW_OWNER;
+		sky2->tx_addr64 = high32(mapping + len);
+	}
+
+	/* Check for TCP Segmentation Offload */
+	mss = skb_shinfo(skb)->tso_size;
+	if (mss != 0) {
+		/* just drop the packet if non-linear expansion fails */
+		if (skb_header_cloned(skb) &&
+		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
+			dev_kfree_skb_any(skb);
+			goto out_unlock;
+		}
+
+		mss += ((skb->h.th->doff - 5) * 4);	/* TCP options */
+		mss += (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr);
+		mss += ETH_HLEN;
+	}
+
+	if (mss != sky2->tx_last_mss) {
+		le = get_tx_le(sky2);
+		le->tx.tso.size = cpu_to_le16(mss);
+		le->tx.tso.rsvd = 0;
+		le->opcode = OP_LRGLEN | HW_OWNER;
+		le->ctrl = 0;
+		sky2->tx_last_mss = mss;
+	}
+
+	ctrl = 0;
+#ifdef SKY2_VLAN_TAG_USED
+	/* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */
+	if (sky2->vlgrp && vlan_tx_tag_present(skb)) {
+		if (!le) {
+			le = get_tx_le(sky2);
+			le->tx.addr = 0;
+			le->opcode = OP_VLAN|HW_OWNER;
+			le->ctrl = 0;
+		} else
+			le->opcode |= OP_VLAN;
+		le->length = cpu_to_be16(vlan_tx_tag_get(skb));
+		ctrl |= INS_VLAN;
+	}
+#endif
+
+	/* Handle TCP checksum offload */
+	if (skb->ip_summed == CHECKSUM_HW) {
+		u16 hdr = skb->h.raw - skb->data;
+		u16 offset = hdr + skb->csum;
+
+		ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
+		if (skb->nh.iph->protocol == IPPROTO_UDP)
+			ctrl |= UDPTCP;
+
+		le = get_tx_le(sky2);
+		le->tx.csum.start = cpu_to_le16(hdr);
+		le->tx.csum.offset = cpu_to_le16(offset);
+		le->length = 0;	/* initial checksum value */
+		le->ctrl = 1;	/* one packet */
+		le->opcode = OP_TCPLISW | HW_OWNER;
+	}
+
+	le = get_tx_le(sky2);
+	le->tx.addr = cpu_to_le32((u32) mapping);
+	le->length = cpu_to_le16(len);
+	le->ctrl = ctrl;
+	le->opcode = mss ? (OP_LARGESEND | HW_OWNER) : (OP_PACKET | HW_OWNER);
+
+	/* Record the transmit mapping info */
+	re->skb = skb;
+	pci_unmap_addr_set(re, mapaddr, mapping);
+
+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		struct tx_ring_info *fre;
+
+		mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
+				       frag->size, PCI_DMA_TODEVICE);
+		addr64 = (mapping >> 16) >> 16;
+		if (addr64 != sky2->tx_addr64) {
+			le = get_tx_le(sky2);
+			le->tx.addr = cpu_to_le32(addr64);
+			le->ctrl = 0;
+			le->opcode = OP_ADDR64 | HW_OWNER;
+			sky2->tx_addr64 = addr64;
+		}
+
+		le = get_tx_le(sky2);
+		le->tx.addr = cpu_to_le32((u32) mapping);
+		le->length = cpu_to_le16(frag->size);
+		le->ctrl = ctrl;
+		le->opcode = OP_BUFFER | HW_OWNER;
+
+		fre = sky2->tx_ring
+		    + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE;
+		pci_unmap_addr_set(fre, mapaddr, mapping);
+	}
+
+	re->idx = sky2->tx_prod;
+	le->ctrl |= EOP;
+
+	sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod,
+		     &sky2->tx_last_put, TX_RING_SIZE);
+
+	if (tx_avail(sky2) <= MAX_SKB_TX_LE)
+		netif_stop_queue(dev);
+
+out_unlock:
+	mmiowb();
+	spin_unlock(&sky2->tx_lock);
+
+	dev->trans_start = jiffies;
+	return NETDEV_TX_OK;
+}
+
+/*
+ * Free ring elements from starting at tx_cons until "done"
+ *
+ * NB: the hardware will tell us about partial completion of multi-part
+ *     buffers; these are deferred until completion.
+ */
+static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
+{
+	struct net_device *dev = sky2->netdev;
+	struct pci_dev *pdev = sky2->hw->pdev;
+	u16 nxt, put;
+	unsigned i;
+
+	BUG_ON(done >= TX_RING_SIZE);
+
+	if (unlikely(netif_msg_tx_done(sky2)))
+		printk(KERN_DEBUG "%s: tx done, up to %u\n",
+		       dev->name, done);
+
+	for (put = sky2->tx_cons; put != done; put = nxt) {
+		struct tx_ring_info *re = sky2->tx_ring + put;
+		struct sk_buff *skb = re->skb;
+
+  		nxt = re->idx;
+		BUG_ON(nxt >= TX_RING_SIZE);
+		prefetch(sky2->tx_ring + nxt);
+
+		/* Check for partial status */
+		if (tx_dist(put, done) < tx_dist(put, nxt))
+			break;
+
+		skb = re->skb;
+		pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr),
+				 skb_headlen(skb), PCI_DMA_TODEVICE);
+
+		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+			struct tx_ring_info *fre;
+			fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE;
+			pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
+  				       skb_shinfo(skb)->frags[i].size,
+				       PCI_DMA_TODEVICE);
+		}
+
+		dev_kfree_skb_any(skb);
+	}
+
+	spin_lock(&sky2->tx_lock);
+	sky2->tx_cons = put;
+	if (netif_queue_stopped(dev) && tx_avail(sky2) > MAX_SKB_TX_LE)
+		netif_wake_queue(dev);
+	spin_unlock(&sky2->tx_lock);
+}
+
+/* Cleanup all untransmitted buffers, assume transmitter not running */
+static void sky2_tx_clean(struct sky2_port *sky2)
+{
+	sky2_tx_complete(sky2, sky2->tx_prod);
+}
+
+/* Network shutdown */
+static int sky2_down(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 ctrl;
+
+	/* Never really got started! */
+	if (!sky2->tx_le)
+		return 0;
+
+	if (netif_msg_ifdown(sky2))
+		printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
+
+	/* Stop more packets from being queued */
+	netif_stop_queue(dev);
+
+	/* Disable port IRQ */
+	local_irq_disable();
+	hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+	local_irq_enable();
+
+	flush_scheduled_work();
+
+	sky2_phy_reset(hw, port);
+
+	/* Stop transmitter */
+	sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP);
+	sky2_read32(hw, Q_ADDR(txqaddr[port], Q_CSR));
+
+	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
+		     RB_RST_SET | RB_DIS_OP_MD);
+
+	ctrl = gma_read16(hw, port, GM_GP_CTRL);
+	ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA);
+	gma_write16(hw, port, GM_GP_CTRL, ctrl);
+
+	sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+
+	/* Workaround shared GMAC reset */
+	if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0
+	      && port == 0 && hw->dev[1] && netif_running(hw->dev[1])))
+		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+
+	/* Disable Force Sync bit and Enable Alloc bit */
+	sky2_write8(hw, SK_REG(port, TXA_CTRL),
+		    TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC);
+
+	/* Stop Interval Timer and Limit Counter of Tx Arbiter */
+	sky2_write32(hw, SK_REG(port, TXA_ITI_INI), 0L);
+	sky2_write32(hw, SK_REG(port, TXA_LIM_INI), 0L);
+
+	/* Reset the PCI FIFO of the async Tx queue */
+	sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR),
+		     BMU_RST_SET | BMU_FIFO_RST);
+
+	/* Reset the Tx prefetch units */
+	sky2_write32(hw, Y2_QADDR(txqaddr[port], PREF_UNIT_CTRL),
+		     PREF_UNIT_RST_SET);
+
+	sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET);
+
+	sky2_rx_stop(sky2);
+
+	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
+	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
+
+	/* turn off LED's */
+	sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
+
+	synchronize_irq(hw->pdev->irq);
+
+	sky2_tx_clean(sky2);
+	sky2_rx_clean(sky2);
+
+	pci_free_consistent(hw->pdev, RX_LE_BYTES,
+			    sky2->rx_le, sky2->rx_le_map);
+	kfree(sky2->rx_ring);
+
+	pci_free_consistent(hw->pdev,
+			    TX_RING_SIZE * sizeof(struct sky2_tx_le),
+			    sky2->tx_le, sky2->tx_le_map);
+	kfree(sky2->tx_ring);
+
+	sky2->tx_le = NULL;
+	sky2->rx_le = NULL;
+
+	sky2->rx_ring = NULL;
+	sky2->tx_ring = NULL;
+
+	return 0;
+}
+
+static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
+{
+	if (!hw->copper)
+		return SPEED_1000;
+
+	if (hw->chip_id == CHIP_ID_YUKON_FE)
+		return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10;
+
+	switch (aux & PHY_M_PS_SPEED_MSK) {
+	case PHY_M_PS_SPEED_1000:
+		return SPEED_1000;
+	case PHY_M_PS_SPEED_100:
+		return SPEED_100;
+	default:
+		return SPEED_10;
+	}
+}
+
+static void sky2_link_up(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 reg;
+
+	/* Enable Transmit FIFO Underrun */
+	sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
+
+	reg = gma_read16(hw, port, GM_GP_CTRL);
+	if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE)
+		reg |= GM_GPCR_DUP_FULL;
+
+	/* enable Rx/Tx */
+	reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
+	gma_write16(hw, port, GM_GP_CTRL, reg);
+	gma_read16(hw, port, GM_GP_CTRL);
+
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
+
+	netif_carrier_on(sky2->netdev);
+	netif_wake_queue(sky2->netdev);
+
+	/* Turn on link LED */
+	sky2_write8(hw, SK_REG(port, LNK_LED_REG),
+		    LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
+
+	if (hw->chip_id == CHIP_ID_YUKON_XL) {
+		u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) |	/* LINK/ACT */
+			     PHY_M_LEDC_INIT_CTRL(sky2->speed ==
+						  SPEED_10 ? 7 : 0) |
+			     PHY_M_LEDC_STA1_CTRL(sky2->speed ==
+						  SPEED_100 ? 7 : 0) |
+			     PHY_M_LEDC_STA0_CTRL(sky2->speed ==
+						  SPEED_1000 ? 7 : 0));
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+	}
+
+	if (netif_msg_link(sky2))
+		printk(KERN_INFO PFX
+		       "%s: Link is up at %d Mbps, %s duplex, flow control %s\n",
+		       sky2->netdev->name, sky2->speed,
+		       sky2->duplex == DUPLEX_FULL ? "full" : "half",
+		       (sky2->tx_pause && sky2->rx_pause) ? "both" :
+		       sky2->tx_pause ? "tx" : sky2->rx_pause ? "rx" : "none");
+}
+
+static void sky2_link_down(struct sky2_port *sky2)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 reg;
+
+	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
+
+	reg = gma_read16(hw, port, GM_GP_CTRL);
+	reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
+	gma_write16(hw, port, GM_GP_CTRL, reg);
+	gma_read16(hw, port, GM_GP_CTRL);	/* PCI post */
+
+	if (sky2->rx_pause && !sky2->tx_pause) {
+		/* restore Asymmetric Pause bit */
+		gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
+			     gm_phy_read(hw, port, PHY_MARV_AUNE_ADV)
+			     | PHY_M_AN_ASP);
+	}
+
+	netif_carrier_off(sky2->netdev);
+	netif_stop_queue(sky2->netdev);
+
+	/* Turn on link LED */
+	sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
+
+	if (netif_msg_link(sky2))
+		printk(KERN_INFO PFX "%s: Link is down.\n", sky2->netdev->name);
+	sky2_phy_init(hw, port);
+}
+
+static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 lpa;
+
+	lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
+
+	if (lpa & PHY_M_AN_RF) {
+		printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name);
+		return -1;
+	}
+
+	if (hw->chip_id != CHIP_ID_YUKON_FE &&
+	    gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) {
+		printk(KERN_ERR PFX "%s: master/slave fault",
+		       sky2->netdev->name);
+		return -1;
+	}
+
+	if (!(aux & PHY_M_PS_SPDUP_RES)) {
+		printk(KERN_ERR PFX "%s: speed/duplex mismatch",
+		       sky2->netdev->name);
+		return -1;
+	}
+
+	sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
+
+	sky2->speed = sky2_phy_speed(hw, aux);
+
+	/* Pause bits are offset (9..8) */
+	if (hw->chip_id == CHIP_ID_YUKON_XL)
+		aux >>= 6;
+
+	sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0;
+	sky2->tx_pause = (aux & PHY_M_PS_TX_P_EN) != 0;
+
+	if ((sky2->tx_pause || sky2->rx_pause)
+	    && !(sky2->speed < SPEED_1000 && sky2->duplex == DUPLEX_HALF))
+		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
+	else
+		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
+
+	return 0;
+}
+
+/*
+ * Interrupt from PHY are handled outside of interrupt context
+ * because accessing phy registers requires spin wait which might
+ * cause excess interrupt latency.
+ */
+static void sky2_phy_task(void *arg)
+{
+	struct sky2_port *sky2 = arg;
+	struct sky2_hw *hw = sky2->hw;
+	u16 istatus, phystat;
+
+	down(&sky2->phy_sema);
+	istatus = gm_phy_read(hw, sky2->port, PHY_MARV_INT_STAT);
+	phystat = gm_phy_read(hw, sky2->port, PHY_MARV_PHY_STAT);
+
+	if (netif_msg_intr(sky2))
+		printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
+		       sky2->netdev->name, istatus, phystat);
+
+	if (istatus & PHY_M_IS_AN_COMPL) {
+		if (sky2_autoneg_done(sky2, phystat) == 0)
+			sky2_link_up(sky2);
+		goto out;
+	}
+
+	if (istatus & PHY_M_IS_LSP_CHANGE)
+		sky2->speed = sky2_phy_speed(hw, phystat);
+
+	if (istatus & PHY_M_IS_DUP_CHANGE)
+		sky2->duplex =
+		    (phystat & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
+
+	if (istatus & PHY_M_IS_LST_CHANGE) {
+		if (phystat & PHY_M_PS_LINK_UP)
+			sky2_link_up(sky2);
+		else
+			sky2_link_down(sky2);
+	}
+out:
+	up(&sky2->phy_sema);
+
+	local_irq_disable();
+	hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2;
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+	local_irq_enable();
+}
+
+static void sky2_tx_timeout(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned txq = txqaddr[sky2->port];
+
+	if (netif_msg_timer(sky2))
+		printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
+
+	netif_stop_queue(dev);
+
+	sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
+	sky2_read32(hw, Q_ADDR(txq, Q_CSR));
+
+	sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+
+	sky2_tx_clean(sky2);
+
+	sky2_qset(hw, txq);
+	sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
+
+	netif_wake_queue(dev);
+}
+
+
+#define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
+/* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */
+static inline unsigned sky2_buf_size(int mtu)
+{
+	return roundup(mtu + ETH_HLEN + 4, 8);
+}
+
+static int sky2_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	int err;
+	u16 ctl, mode;
+
+	if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
+		return -EINVAL;
+
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U && new_mtu > ETH_DATA_LEN)
+		return -EINVAL;
+
+	if (!netif_running(dev)) {
+		dev->mtu = new_mtu;
+		return 0;
+	}
+
+	sky2_write32(hw, B0_IMSK, 0);
+
+	dev->trans_start = jiffies;	/* prevent tx timeout */
+	netif_stop_queue(dev);
+	netif_poll_disable(hw->dev[0]);
+
+	ctl = gma_read16(hw, sky2->port, GM_GP_CTRL);
+	gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
+	sky2_rx_stop(sky2);
+	sky2_rx_clean(sky2);
+
+	dev->mtu = new_mtu;
+	sky2->rx_bufsize = sky2_buf_size(new_mtu);
+	mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
+		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
+
+	if (dev->mtu > ETH_DATA_LEN)
+		mode |= GM_SMOD_JUMBO_ENA;
+
+	gma_write16(hw, sky2->port, GM_SERIAL_MODE, mode);
+
+	sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD);
+
+	err = sky2_rx_start(sky2);
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+
+	if (err)
+		dev_close(dev);
+	else {
+		gma_write16(hw, sky2->port, GM_GP_CTRL, ctl);
+
+		netif_poll_enable(hw->dev[0]);
+		netif_wake_queue(dev);
+	}
+
+	return err;
+}
+
+/*
+ * Receive one packet.
+ * For small packets or errors, just reuse existing skb.
+ * For larger packets, get new buffer.
+ */
+static struct sk_buff *sky2_receive(struct sky2_port *sky2,
+				    u16 length, u32 status)
+{
+	struct ring_info *re = sky2->rx_ring + sky2->rx_next;
+	struct sk_buff *skb = NULL;
+
+	if (unlikely(netif_msg_rx_status(sky2)))
+		printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
+		       sky2->netdev->name, sky2->rx_next, status, length);
+
+	sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
+	prefetch(sky2->rx_ring + sky2->rx_next);
+
+	if (status & GMR_FS_ANY_ERR)
+		goto error;
+
+	if (!(status & GMR_FS_RX_OK))
+		goto resubmit;
+
+	if ((status >> 16) != length || length > sky2->rx_bufsize)
+		goto oversize;
+
+	if (length < copybreak) {
+		skb = alloc_skb(length + 2, GFP_ATOMIC);
+		if (!skb)
+			goto resubmit;
+
+		skb_reserve(skb, 2);
+		pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr,
+					    length, PCI_DMA_FROMDEVICE);
+		memcpy(skb->data, re->skb->data, length);
+		skb->ip_summed = re->skb->ip_summed;
+		skb->csum = re->skb->csum;
+		pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr,
+					       length, PCI_DMA_FROMDEVICE);
+	} else {
+		struct sk_buff *nskb;
+
+		nskb = dev_alloc_skb(sky2->rx_bufsize);
+		if (!nskb)
+			goto resubmit;
+
+		skb = re->skb;
+		re->skb = nskb;
+		pci_unmap_single(sky2->hw->pdev, re->mapaddr,
+				 sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+		prefetch(skb->data);
+
+		re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data,
+					     sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
+	}
+
+	skb_put(skb, length);
+resubmit:
+	re->skb->ip_summed = CHECKSUM_NONE;
+	sky2_rx_add(sky2, re->mapaddr);
+
+	/* Tell receiver about new buffers. */
+	sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put,
+		     &sky2->rx_last_put, RX_LE_SIZE);
+
+	return skb;
+
+oversize:
+	++sky2->net_stats.rx_over_errors;
+	goto resubmit;
+
+error:
+	++sky2->net_stats.rx_errors;
+
+	if (netif_msg_rx_err(sky2))
+		printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n",
+		       sky2->netdev->name, status, length);
+
+	if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE))
+		sky2->net_stats.rx_length_errors++;
+	if (status & GMR_FS_FRAGMENT)
+		sky2->net_stats.rx_frame_errors++;
+	if (status & GMR_FS_CRC_ERR)
+		sky2->net_stats.rx_crc_errors++;
+	if (status & GMR_FS_RX_FF_OV)
+		sky2->net_stats.rx_fifo_errors++;
+
+	goto resubmit;
+}
+
+/*
+ * Check for transmit complete
+ */
+#define TX_NO_STATUS	0xffff
+
+static inline void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
+{
+	if (last != TX_NO_STATUS) {
+		struct net_device *dev = hw->dev[port];
+		if (dev && netif_running(dev)) {
+			struct sky2_port *sky2 = netdev_priv(dev);
+			sky2_tx_complete(sky2, last);
+		}
+	}
+}
+
+/*
+ * Both ports share the same status interrupt, therefore there is only
+ * one poll routine.
+ */
+static int sky2_poll(struct net_device *dev0, int *budget)
+{
+	struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
+	unsigned int to_do = min(dev0->quota, *budget);
+	unsigned int work_done = 0;
+	u16 hwidx;
+	u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
+
+	hwidx = sky2_read16(hw, STAT_PUT_IDX);
+	BUG_ON(hwidx >= STATUS_RING_SIZE);
+	rmb();
+
+	while (hwidx != hw->st_idx) {
+		struct sky2_status_le *le  = hw->st_le + hw->st_idx;
+		struct net_device *dev;
+		struct sky2_port *sky2;
+		struct sk_buff *skb;
+		u32 status;
+		u16 length;
+		u8 op;
+
+		le = hw->st_le + hw->st_idx;
+		hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE;
+		prefetch(hw->st_le + hw->st_idx);
+
+		BUG_ON(le->link >= 2);
+		dev = hw->dev[le->link];
+		if (dev == NULL || !netif_running(dev))
+			continue;
+
+		sky2 = netdev_priv(dev);
+		status = le32_to_cpu(le->status);
+		length = le16_to_cpu(le->length);
+		op = le->opcode & ~HW_OWNER;
+		le->opcode = 0;
+
+		switch (op) {
+		case OP_RXSTAT:
+			skb = sky2_receive(sky2, length, status);
+			if (!skb)
+				break;
+
+			skb->dev = dev;
+			skb->protocol = eth_type_trans(skb, dev);
+			dev->last_rx = jiffies;
+
+#ifdef SKY2_VLAN_TAG_USED
+			if (sky2->vlgrp && (status & GMR_FS_VLAN)) {
+				vlan_hwaccel_receive_skb(skb,
+							 sky2->vlgrp,
+							 be16_to_cpu(sky2->rx_tag));
+			} else
+#endif
+				netif_receive_skb(skb);
+
+			if (++work_done >= to_do)
+				goto exit_loop;
+			break;
+
+#ifdef SKY2_VLAN_TAG_USED
+		case OP_RXVLAN:
+			sky2->rx_tag = length;
+			break;
+
+		case OP_RXCHKSVLAN:
+			sky2->rx_tag = length;
+			/* fall through */
+#endif
+		case OP_RXCHKS:
+			skb = sky2->rx_ring[sky2->rx_next].skb;
+			skb->ip_summed = CHECKSUM_HW;
+			skb->csum = le16_to_cpu(status);
+			break;
+
+		case OP_TXINDEXLE:
+			/* TX index reports status for both ports */
+			tx_done[0] = status & 0xffff;
+			tx_done[1] = ((status >> 24) & 0xff)
+				| (u16)(length & 0xf) << 8;
+			break;
+
+		default:
+			if (net_ratelimit())
+				printk(KERN_WARNING PFX
+				       "unknown status opcode 0x%x\n", op);
+			break;
+		}
+	}
+
+exit_loop:
+	sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+	mmiowb();
+
+	sky2_tx_check(hw, 0, tx_done[0]);
+	sky2_tx_check(hw, 1, tx_done[1]);
+
+	if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) {
+		/* need to restart TX timer */
+		if (is_ec_a1(hw)) {
+			sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+			sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+		}
+
+		netif_rx_complete(dev0);
+		hw->intr_mask |= Y2_IS_STAT_BMU;
+		sky2_write32(hw, B0_IMSK, hw->intr_mask);
+		mmiowb();
+		return 0;
+	} else {
+		*budget -= work_done;
+		dev0->quota -= work_done;
+		return 1;
+	}
+}
+
+static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
+{
+	struct net_device *dev = hw->dev[port];
+
+	printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n",
+	       dev->name, status);
+
+	if (status & Y2_IS_PAR_RD1) {
+		printk(KERN_ERR PFX "%s: ram data read parity error\n",
+		       dev->name);
+		/* Clear IRQ */
+		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR);
+	}
+
+	if (status & Y2_IS_PAR_WR1) {
+		printk(KERN_ERR PFX "%s: ram data write parity error\n",
+		       dev->name);
+
+		sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR);
+	}
+
+	if (status & Y2_IS_PAR_MAC1) {
+		printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name);
+		sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE);
+	}
+
+	if (status & Y2_IS_PAR_RX1) {
+		printk(KERN_ERR PFX "%s: RX parity error\n", dev->name);
+		sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR);
+	}
+
+	if (status & Y2_IS_TCP_TXA1) {
+		printk(KERN_ERR PFX "%s: TCP segmentation error\n", dev->name);
+		sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP);
+	}
+}
+
+static void sky2_hw_intr(struct sky2_hw *hw)
+{
+	u32 status = sky2_read32(hw, B0_HWE_ISRC);
+
+	if (status & Y2_IS_TIST_OV)
+		sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+
+	if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
+		u16 pci_err;
+
+		pci_read_config_word(hw->pdev, PCI_STATUS, &pci_err);
+		printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n",
+		       pci_name(hw->pdev), pci_err);
+
+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+		pci_write_config_word(hw->pdev, PCI_STATUS,
+				      pci_err | PCI_STATUS_ERROR_BITS);
+		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+	}
+
+	if (status & Y2_IS_PCI_EXP) {
+		/* PCI-Express uncorrectable Error occurred */
+		u32 pex_err;
+
+		pci_read_config_dword(hw->pdev, PEX_UNC_ERR_STAT, &pex_err);
+
+		printk(KERN_ERR PFX "%s: pci express error (0x%x)\n",
+		       pci_name(hw->pdev), pex_err);
+
+		/* clear the interrupt */
+		sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+		pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
+				       0xffffffffUL);
+		sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+		if (pex_err & PEX_FATAL_ERRORS) {
+			u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
+			hwmsk &= ~Y2_IS_PCI_EXP;
+			sky2_write32(hw, B0_HWE_IMSK, hwmsk);
+		}
+	}
+
+	if (status & Y2_HWE_L1_MASK)
+		sky2_hw_error(hw, 0, status);
+	status >>= 8;
+	if (status & Y2_HWE_L1_MASK)
+		sky2_hw_error(hw, 1, status);
+}
+
+static void sky2_mac_intr(struct sky2_hw *hw, unsigned port)
+{
+	struct net_device *dev = hw->dev[port];
+	struct sky2_port *sky2 = netdev_priv(dev);
+	u8 status = sky2_read8(hw, SK_REG(port, GMAC_IRQ_SRC));
+
+	if (netif_msg_intr(sky2))
+		printk(KERN_INFO PFX "%s: mac interrupt status 0x%x\n",
+		       dev->name, status);
+
+	if (status & GM_IS_RX_FF_OR) {
+		++sky2->net_stats.rx_fifo_errors;
+		sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
+	}
+
+	if (status & GM_IS_TX_FF_UR) {
+		++sky2->net_stats.tx_fifo_errors;
+		sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
+	}
+}
+
+static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
+{
+	struct net_device *dev = hw->dev[port];
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+	schedule_work(&sky2->phy_task);
+}
+
+static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct sky2_hw *hw = dev_id;
+	struct net_device *dev0 = hw->dev[0];
+	u32 status;
+
+	status = sky2_read32(hw, B0_Y2_SP_ISRC2);
+	if (status == 0 || status == ~0)
+		return IRQ_NONE;
+
+	if (status & Y2_IS_HW_ERR)
+		sky2_hw_intr(hw);
+
+	/* Do NAPI for Rx and Tx status */
+	if (status & Y2_IS_STAT_BMU) {
+		hw->intr_mask &= ~Y2_IS_STAT_BMU;
+		sky2_write32(hw, B0_IMSK, hw->intr_mask);
+
+		if (likely(__netif_rx_schedule_prep(dev0))) {
+			prefetch(&hw->st_le[hw->st_idx]);
+			__netif_rx_schedule(dev0);
+		}
+	}
+
+	if (status & Y2_IS_IRQ_PHY1)
+		sky2_phy_intr(hw, 0);
+
+	if (status & Y2_IS_IRQ_PHY2)
+		sky2_phy_intr(hw, 1);
+
+	if (status & Y2_IS_IRQ_MAC1)
+		sky2_mac_intr(hw, 0);
+
+	if (status & Y2_IS_IRQ_MAC2)
+		sky2_mac_intr(hw, 1);
+
+	sky2_write32(hw, B0_Y2_SP_ICR, 2);
+
+	sky2_read32(hw, B0_IMSK);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void sky2_netpoll(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	sky2_intr(sky2->hw->pdev->irq, sky2->hw, NULL);
+}
+#endif
+
+/* Chip internal frequency for clock calculations */
+static inline u32 sky2_mhz(const struct sky2_hw *hw)
+{
+	switch (hw->chip_id) {
+	case CHIP_ID_YUKON_EC:
+	case CHIP_ID_YUKON_EC_U:
+		return 125;	/* 125 Mhz */
+	case CHIP_ID_YUKON_FE:
+		return 100;	/* 100 Mhz */
+	default:		/* YUKON_XL */
+		return 156;	/* 156 Mhz */
+	}
+}
+
+static inline u32 sky2_us2clk(const struct sky2_hw *hw, u32 us)
+{
+	return sky2_mhz(hw) * us;
+}
+
+static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk)
+{
+	return clk / sky2_mhz(hw);
+}
+
+
+static int sky2_reset(struct sky2_hw *hw)
+{
+	u32 ctst;
+	u16 status;
+	u8 t8, pmd_type;
+	int i;
+
+	ctst = sky2_read32(hw, B0_CTST);
+
+	sky2_write8(hw, B0_CTST, CS_RST_CLR);
+	hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
+	if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) {
+		printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n",
+		       pci_name(hw->pdev), hw->chip_id);
+		return -EOPNOTSUPP;
+	}
+
+	/* ring for status responses */
+	hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
+					 &hw->st_dma);
+	if (!hw->st_le)
+		return -ENOMEM;
+
+	/* disable ASF */
+	if (hw->chip_id <= CHIP_ID_YUKON_EC) {
+		sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
+		sky2_write16(hw, B0_CTST, Y2_ASF_DISABLE);
+	}
+
+	/* do a SW reset */
+	sky2_write8(hw, B0_CTST, CS_RST_SET);
+	sky2_write8(hw, B0_CTST, CS_RST_CLR);
+
+	/* clear PCI errors, if any */
+	pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+	pci_write_config_word(hw->pdev, PCI_STATUS,
+			      status | PCI_STATUS_ERROR_BITS);
+
+	sky2_write8(hw, B0_CTST, CS_MRST_CLR);
+
+	/* clear any PEX errors */
+	if (is_pciex(hw)) {
+		u16 lstat;
+		pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT,
+				       0xffffffffUL);
+		pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat);
+	}
+
+	pmd_type = sky2_read8(hw, B2_PMD_TYP);
+	hw->copper = !(pmd_type == 'L' || pmd_type == 'S');
+
+	hw->ports = 1;
+	t8 = sky2_read8(hw, B2_Y2_HW_RES);
+	if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
+		if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
+			++hw->ports;
+	}
+	hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
+
+	sky2_set_power_state(hw, PCI_D0);
+
+	for (i = 0; i < hw->ports; i++) {
+		sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
+		sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
+	}
+
+	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+	/* Clear I2C IRQ noise */
+	sky2_write32(hw, B2_I2C_IRQ, 1);
+
+	/* turn off hardware timer (unused) */
+	sky2_write8(hw, B2_TI_CTRL, TIM_STOP);
+	sky2_write8(hw, B2_TI_CTRL, TIM_CLR_IRQ);
+
+	sky2_write8(hw, B0_Y2LED, LED_STAT_ON);
+
+	/* Turn off descriptor polling */
+	sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
+
+	/* Turn off receive timestamp */
+	sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_STOP);
+	sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+
+	/* enable the Tx Arbiters */
+	for (i = 0; i < hw->ports; i++)
+		sky2_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB);
+
+	/* Initialize ram interface */
+	for (i = 0; i < hw->ports; i++) {
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_CTRL), RI_RST_CLR);
+
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53);
+		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
+	}
+
+	sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
+
+	for (i = 0; i < hw->ports; i++)
+		sky2_phy_reset(hw, i);
+
+	memset(hw->st_le, 0, STATUS_LE_BYTES);
+	hw->st_idx = 0;
+
+	sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET);
+	sky2_write32(hw, STAT_CTRL, SC_STAT_RST_CLR);
+
+	sky2_write32(hw, STAT_LIST_ADDR_LO, hw->st_dma);
+	sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32);
+
+	/* Set the list last index */
+	sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);
+
+	/* These status setup values are copied from SysKonnect's driver */
+	if (is_ec_a1(hw)) {
+		/* WA for dev. #4.3 */
+		sky2_write16(hw, STAT_TX_IDX_TH, 0xfff);	/* Tx Threshold */
+
+		/* set Status-FIFO watermark */
+		sky2_write8(hw, STAT_FIFO_WM, 0x21);	/* WA for dev. #4.18 */
+
+		/* set Status-FIFO ISR watermark */
+		sky2_write8(hw, STAT_FIFO_ISR_WM, 0x07);	/* WA for dev. #4.18 */
+		sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 10000));
+	} else {
+		sky2_write16(hw, STAT_TX_IDX_TH, 10);
+		sky2_write8(hw, STAT_FIFO_WM, 16);
+
+		/* set Status-FIFO ISR watermark */
+		if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
+			sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
+		else
+			sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
+
+		sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
+		sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100));
+		sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20));
+	}
+
+	/* enable status unit */
+	sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);
+
+	sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+	sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
+	sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
+
+	return 0;
+}
+
+static inline u32 sky2_supported_modes(const struct sky2_hw *hw)
+{
+	u32 modes;
+	if (hw->copper) {
+		modes = SUPPORTED_10baseT_Half
+		    | SUPPORTED_10baseT_Full
+		    | SUPPORTED_100baseT_Half
+		    | SUPPORTED_100baseT_Full
+		    | SUPPORTED_Autoneg | SUPPORTED_TP;
+
+		if (hw->chip_id != CHIP_ID_YUKON_FE)
+			modes |= SUPPORTED_1000baseT_Half
+			    | SUPPORTED_1000baseT_Full;
+	} else
+		modes = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE
+		    | SUPPORTED_Autoneg;
+	return modes;
+}
+
+static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+
+	ecmd->transceiver = XCVR_INTERNAL;
+	ecmd->supported = sky2_supported_modes(hw);
+	ecmd->phy_address = PHY_ADDR_MARV;
+	if (hw->copper) {
+		ecmd->supported = SUPPORTED_10baseT_Half
+		    | SUPPORTED_10baseT_Full
+		    | SUPPORTED_100baseT_Half
+		    | SUPPORTED_100baseT_Full
+		    | SUPPORTED_1000baseT_Half
+		    | SUPPORTED_1000baseT_Full
+		    | SUPPORTED_Autoneg | SUPPORTED_TP;
+		ecmd->port = PORT_TP;
+	} else
+		ecmd->port = PORT_FIBRE;
+
+	ecmd->advertising = sky2->advertising;
+	ecmd->autoneg = sky2->autoneg;
+	ecmd->speed = sky2->speed;
+	ecmd->duplex = sky2->duplex;
+	return 0;
+}
+
+static int sky2_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	const struct sky2_hw *hw = sky2->hw;
+	u32 supported = sky2_supported_modes(hw);
+
+	if (ecmd->autoneg == AUTONEG_ENABLE) {
+		ecmd->advertising = supported;
+		sky2->duplex = -1;
+		sky2->speed = -1;
+	} else {
+		u32 setting;
+
+		switch (ecmd->speed) {
+		case SPEED_1000:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_1000baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_1000baseT_Half;
+			else
+				return -EINVAL;
+			break;
+		case SPEED_100:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_100baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_100baseT_Half;
+			else
+				return -EINVAL;
+			break;
+
+		case SPEED_10:
+			if (ecmd->duplex == DUPLEX_FULL)
+				setting = SUPPORTED_10baseT_Full;
+			else if (ecmd->duplex == DUPLEX_HALF)
+				setting = SUPPORTED_10baseT_Half;
+			else
+				return -EINVAL;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		if ((setting & supported) == 0)
+			return -EINVAL;
+
+		sky2->speed = ecmd->speed;
+		sky2->duplex = ecmd->duplex;
+	}
+
+	sky2->autoneg = ecmd->autoneg;
+	sky2->advertising = ecmd->advertising;
+
+	if (netif_running(dev))
+		sky2_phy_reinit(sky2);
+
+	return 0;
+}
+
+static void sky2_get_drvinfo(struct net_device *dev,
+			     struct ethtool_drvinfo *info)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->fw_version, "N/A");
+	strcpy(info->bus_info, pci_name(sky2->hw->pdev));
+}
+
+static const struct sky2_stat {
+	char name[ETH_GSTRING_LEN];
+	u16 offset;
+} sky2_stats[] = {
+	{ "tx_bytes",	   GM_TXO_OK_HI },
+	{ "rx_bytes",	   GM_RXO_OK_HI },
+	{ "tx_broadcast",  GM_TXF_BC_OK },
+	{ "rx_broadcast",  GM_RXF_BC_OK },
+	{ "tx_multicast",  GM_TXF_MC_OK },
+	{ "rx_multicast",  GM_RXF_MC_OK },
+	{ "tx_unicast",    GM_TXF_UC_OK },
+	{ "rx_unicast",    GM_RXF_UC_OK },
+	{ "tx_mac_pause",  GM_TXF_MPAUSE },
+	{ "rx_mac_pause",  GM_RXF_MPAUSE },
+	{ "collisions",    GM_TXF_SNG_COL },
+	{ "late_collision",GM_TXF_LAT_COL },
+	{ "aborted", 	   GM_TXF_ABO_COL },
+	{ "multi_collisions", GM_TXF_MUL_COL },
+	{ "fifo_underrun", GM_TXE_FIFO_UR },
+	{ "fifo_overflow", GM_RXE_FIFO_OV },
+	{ "rx_toolong",    GM_RXF_LNG_ERR },
+	{ "rx_jabber",     GM_RXF_JAB_PKT },
+	{ "rx_runt", 	   GM_RXE_FRAG },
+	{ "rx_too_long",   GM_RXF_LNG_ERR },
+	{ "rx_fcs_error",   GM_RXF_FCS_ERR },
+};
+
+static u32 sky2_get_rx_csum(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	return sky2->rx_csum;
+}
+
+static int sky2_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	sky2->rx_csum = data;
+
+	sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+		     data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+
+	return 0;
+}
+
+static u32 sky2_get_msglevel(struct net_device *netdev)
+{
+	struct sky2_port *sky2 = netdev_priv(netdev);
+	return sky2->msg_enable;
+}
+
+static int sky2_nway_reset(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	if (sky2->autoneg != AUTONEG_ENABLE)
+		return -EINVAL;
+
+	sky2_phy_reinit(sky2);
+
+	return 0;
+}
+
+static void sky2_phy_stats(struct sky2_port *sky2, u64 * data, unsigned count)
+{
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	int i;
+
+	data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32
+	    | (u64) gma_read32(hw, port, GM_TXO_OK_LO);
+	data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32
+	    | (u64) gma_read32(hw, port, GM_RXO_OK_LO);
+
+	for (i = 2; i < count; i++)
+		data[i] = (u64) gma_read32(hw, port, sky2_stats[i].offset);
+}
+
+static void sky2_set_msglevel(struct net_device *netdev, u32 value)
+{
+	struct sky2_port *sky2 = netdev_priv(netdev);
+	sky2->msg_enable = value;
+}
+
+static int sky2_get_stats_count(struct net_device *dev)
+{
+	return ARRAY_SIZE(sky2_stats);
+}
+
+static void sky2_get_ethtool_stats(struct net_device *dev,
+				   struct ethtool_stats *stats, u64 * data)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	sky2_phy_stats(sky2, data, ARRAY_SIZE(sky2_stats));
+}
+
+static void sky2_get_strings(struct net_device *dev, u32 stringset, u8 * data)
+{
+	int i;
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		for (i = 0; i < ARRAY_SIZE(sky2_stats); i++)
+			memcpy(data + i * ETH_GSTRING_LEN,
+			       sky2_stats[i].name, ETH_GSTRING_LEN);
+		break;
+	}
+}
+
+/* Use hardware MIB variables for critical path statistics and
+ * transmit feedback not reported at interrupt.
+ * Other errors are accounted for in interrupt handler.
+ */
+static struct net_device_stats *sky2_get_stats(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	u64 data[13];
+
+	sky2_phy_stats(sky2, data, ARRAY_SIZE(data));
+
+	sky2->net_stats.tx_bytes = data[0];
+	sky2->net_stats.rx_bytes = data[1];
+	sky2->net_stats.tx_packets = data[2] + data[4] + data[6];
+	sky2->net_stats.rx_packets = data[3] + data[5] + data[7];
+	sky2->net_stats.multicast = data[5] + data[7];
+	sky2->net_stats.collisions = data[10];
+	sky2->net_stats.tx_aborted_errors = data[12];
+
+	return &sky2->net_stats;
+}
+
+static int sky2_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sockaddr *addr = p;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+	memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8,
+		    dev->dev_addr, ETH_ALEN);
+	memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8,
+		    dev->dev_addr, ETH_ALEN);
+
+	if (netif_running(dev))
+		sky2_phy_reinit(sky2);
+
+	return 0;
+}
+
+static void sky2_set_multicast(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	struct dev_mc_list *list = dev->mc_list;
+	u16 reg;
+	u8 filter[8];
+
+	memset(filter, 0, sizeof(filter));
+
+	reg = gma_read16(hw, port, GM_RX_CTRL);
+	reg |= GM_RXCR_UCF_ENA;
+
+	if (dev->flags & IFF_PROMISC)	/* promiscuous */
+		reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
+	else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16)	/* all multicast */
+		memset(filter, 0xff, sizeof(filter));
+	else if (dev->mc_count == 0)	/* no multicast */
+		reg &= ~GM_RXCR_MCF_ENA;
+	else {
+		int i;
+		reg |= GM_RXCR_MCF_ENA;
+
+		for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
+			u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
+			filter[bit / 8] |= 1 << (bit % 8);
+		}
+	}
+
+	gma_write16(hw, port, GM_MC_ADDR_H1,
+		    (u16) filter[0] | ((u16) filter[1] << 8));
+	gma_write16(hw, port, GM_MC_ADDR_H2,
+		    (u16) filter[2] | ((u16) filter[3] << 8));
+	gma_write16(hw, port, GM_MC_ADDR_H3,
+		    (u16) filter[4] | ((u16) filter[5] << 8));
+	gma_write16(hw, port, GM_MC_ADDR_H4,
+		    (u16) filter[6] | ((u16) filter[7] << 8));
+
+	gma_write16(hw, port, GM_RX_CTRL, reg);
+}
+
+/* Can have one global because blinking is controlled by
+ * ethtool and that is always under RTNL mutex
+ */
+static void sky2_led(struct sky2_hw *hw, unsigned port, int on)
+{
+	u16 pg;
+
+	switch (hw->chip_id) {
+	case CHIP_ID_YUKON_XL:
+		pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL,
+			     on ? (PHY_M_LEDC_LOS_CTRL(1) |
+				   PHY_M_LEDC_INIT_CTRL(7) |
+				   PHY_M_LEDC_STA1_CTRL(7) |
+				   PHY_M_LEDC_STA0_CTRL(7))
+			     : 0);
+
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+		break;
+
+	default:
+		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER,
+			     on ? PHY_M_LED_MO_DUP(MO_LED_ON) |
+			     PHY_M_LED_MO_10(MO_LED_ON) |
+			     PHY_M_LED_MO_100(MO_LED_ON) |
+			     PHY_M_LED_MO_1000(MO_LED_ON) |
+			     PHY_M_LED_MO_RX(MO_LED_ON)
+			     : PHY_M_LED_MO_DUP(MO_LED_OFF) |
+			     PHY_M_LED_MO_10(MO_LED_OFF) |
+			     PHY_M_LED_MO_100(MO_LED_OFF) |
+			     PHY_M_LED_MO_1000(MO_LED_OFF) |
+			     PHY_M_LED_MO_RX(MO_LED_OFF));
+
+	}
+}
+
+/* blink LED's for finding board */
+static int sky2_phys_id(struct net_device *dev, u32 data)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	u16 ledctrl, ledover = 0;
+	long ms;
+	int interrupted;
+	int onoff = 1;
+
+	if (!data || data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ))
+		ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT);
+	else
+		ms = data * 1000;
+
+	/* save initial values */
+	down(&sky2->phy_sema);
+	if (hw->chip_id == CHIP_ID_YUKON_XL) {
+		u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+		ledctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+	} else {
+		ledctrl = gm_phy_read(hw, port, PHY_MARV_LED_CTRL);
+		ledover = gm_phy_read(hw, port, PHY_MARV_LED_OVER);
+	}
+
+	interrupted = 0;
+	while (!interrupted && ms > 0) {
+		sky2_led(hw, port, onoff);
+		onoff = !onoff;
+
+		up(&sky2->phy_sema);
+		interrupted = msleep_interruptible(250);
+		down(&sky2->phy_sema);
+
+		ms -= 250;
+	}
+
+	/* resume regularly scheduled programming */
+	if (hw->chip_id == CHIP_ID_YUKON_XL) {
+		u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
+		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ledctrl);
+		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
+	} else {
+		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
+	}
+	up(&sky2->phy_sema);
+
+	return 0;
+}
+
+static void sky2_get_pauseparam(struct net_device *dev,
+				struct ethtool_pauseparam *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	ecmd->tx_pause = sky2->tx_pause;
+	ecmd->rx_pause = sky2->rx_pause;
+	ecmd->autoneg = sky2->autoneg;
+}
+
+static int sky2_set_pauseparam(struct net_device *dev,
+			       struct ethtool_pauseparam *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	int err = 0;
+
+	sky2->autoneg = ecmd->autoneg;
+	sky2->tx_pause = ecmd->tx_pause != 0;
+	sky2->rx_pause = ecmd->rx_pause != 0;
+
+	sky2_phy_reinit(sky2);
+
+	return err;
+}
+
+#ifdef CONFIG_PM
+static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	wol->supported = WAKE_MAGIC;
+	wol->wolopts = sky2->wol ? WAKE_MAGIC : 0;
+}
+
+static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+
+	if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
+		return -EOPNOTSUPP;
+
+	sky2->wol = wol->wolopts == WAKE_MAGIC;
+
+	if (sky2->wol) {
+		memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN);
+
+		sky2_write16(hw, WOL_CTRL_STAT,
+			     WOL_CTL_ENA_PME_ON_MAGIC_PKT |
+			     WOL_CTL_ENA_MAGIC_PKT_UNIT);
+	} else
+		sky2_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT);
+
+	return 0;
+}
+#endif
+
+static int sky2_get_coalesce(struct net_device *dev,
+			     struct ethtool_coalesce *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+
+	if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_STOP)
+		ecmd->tx_coalesce_usecs = 0;
+	else {
+		u32 clks = sky2_read32(hw, STAT_TX_TIMER_INI);
+		ecmd->tx_coalesce_usecs = sky2_clk2us(hw, clks);
+	}
+	ecmd->tx_max_coalesced_frames = sky2_read16(hw, STAT_TX_IDX_TH);
+
+	if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_STOP)
+		ecmd->rx_coalesce_usecs = 0;
+	else {
+		u32 clks = sky2_read32(hw, STAT_LEV_TIMER_INI);
+		ecmd->rx_coalesce_usecs = sky2_clk2us(hw, clks);
+	}
+	ecmd->rx_max_coalesced_frames = sky2_read8(hw, STAT_FIFO_WM);
+
+	if (sky2_read8(hw, STAT_ISR_TIMER_CTRL) == TIM_STOP)
+		ecmd->rx_coalesce_usecs_irq = 0;
+	else {
+		u32 clks = sky2_read32(hw, STAT_ISR_TIMER_INI);
+		ecmd->rx_coalesce_usecs_irq = sky2_clk2us(hw, clks);
+	}
+
+	ecmd->rx_max_coalesced_frames_irq = sky2_read8(hw, STAT_FIFO_ISR_WM);
+
+	return 0;
+}
+
+/* Note: this affect both ports */
+static int sky2_set_coalesce(struct net_device *dev,
+			     struct ethtool_coalesce *ecmd)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_hw *hw = sky2->hw;
+	const u32 tmin = sky2_clk2us(hw, 1);
+	const u32 tmax = 5000;
+
+	if (ecmd->tx_coalesce_usecs != 0 &&
+	    (ecmd->tx_coalesce_usecs < tmin || ecmd->tx_coalesce_usecs > tmax))
+		return -EINVAL;
+
+	if (ecmd->rx_coalesce_usecs != 0 &&
+	    (ecmd->rx_coalesce_usecs < tmin || ecmd->rx_coalesce_usecs > tmax))
+		return -EINVAL;
+
+	if (ecmd->rx_coalesce_usecs_irq != 0 &&
+	    (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax))
+		return -EINVAL;
+
+	if (ecmd->tx_max_coalesced_frames > 0xffff)
+		return -EINVAL;
+	if (ecmd->rx_max_coalesced_frames > 0xff)
+		return -EINVAL;
+	if (ecmd->rx_max_coalesced_frames_irq > 0xff)
+		return -EINVAL;
+
+	if (ecmd->tx_coalesce_usecs == 0)
+		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+	else {
+		sky2_write32(hw, STAT_TX_TIMER_INI,
+			     sky2_us2clk(hw, ecmd->tx_coalesce_usecs));
+		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
+	}
+	sky2_write16(hw, STAT_TX_IDX_TH, ecmd->tx_max_coalesced_frames);
+
+	if (ecmd->rx_coalesce_usecs == 0)
+		sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
+	else {
+		sky2_write32(hw, STAT_LEV_TIMER_INI,
+			     sky2_us2clk(hw, ecmd->rx_coalesce_usecs));
+		sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
+	}
+	sky2_write8(hw, STAT_FIFO_WM, ecmd->rx_max_coalesced_frames);
+
+	if (ecmd->rx_coalesce_usecs_irq == 0)
+		sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP);
+	else {
+		sky2_write32(hw, STAT_TX_TIMER_INI,
+			     sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq));
+		sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
+	}
+	sky2_write8(hw, STAT_FIFO_ISR_WM, ecmd->rx_max_coalesced_frames_irq);
+	return 0;
+}
+
+static void sky2_get_ringparam(struct net_device *dev,
+			       struct ethtool_ringparam *ering)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+
+	ering->rx_max_pending = RX_MAX_PENDING;
+	ering->rx_mini_max_pending = 0;
+	ering->rx_jumbo_max_pending = 0;
+	ering->tx_max_pending = TX_RING_SIZE - 1;
+
+	ering->rx_pending = sky2->rx_pending;
+	ering->rx_mini_pending = 0;
+	ering->rx_jumbo_pending = 0;
+	ering->tx_pending = sky2->tx_pending;
+}
+
+static int sky2_set_ringparam(struct net_device *dev,
+			      struct ethtool_ringparam *ering)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	int err = 0;
+
+	if (ering->rx_pending > RX_MAX_PENDING ||
+	    ering->rx_pending < 8 ||
+	    ering->tx_pending < MAX_SKB_TX_LE ||
+	    ering->tx_pending > TX_RING_SIZE - 1)
+		return -EINVAL;
+
+	if (netif_running(dev))
+		sky2_down(dev);
+
+	sky2->rx_pending = ering->rx_pending;
+	sky2->tx_pending = ering->tx_pending;
+
+	if (netif_running(dev)) {
+		err = sky2_up(dev);
+		if (err)
+			dev_close(dev);
+		else
+			sky2_set_multicast(dev);
+	}
+
+	return err;
+}
+
+static int sky2_get_regs_len(struct net_device *dev)
+{
+	return 0x4000;
+}
+
+/*
+ * Returns copy of control register region
+ * Note: access to the RAM address register set will cause timeouts.
+ */
+static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+			  void *p)
+{
+	const struct sky2_port *sky2 = netdev_priv(dev);
+	const void __iomem *io = sky2->hw->regs;
+
+	BUG_ON(regs->len < B3_RI_WTO_R1);
+	regs->version = 1;
+	memset(p, 0, regs->len);
+
+	memcpy_fromio(p, io, B3_RAM_ADDR);
+
+	memcpy_fromio(p + B3_RI_WTO_R1,
+		      io + B3_RI_WTO_R1,
+		      regs->len - B3_RI_WTO_R1);
+}
+
+static struct ethtool_ops sky2_ethtool_ops = {
+	.get_settings = sky2_get_settings,
+	.set_settings = sky2_set_settings,
+	.get_drvinfo = sky2_get_drvinfo,
+	.get_msglevel = sky2_get_msglevel,
+	.set_msglevel = sky2_set_msglevel,
+	.nway_reset   = sky2_nway_reset,
+	.get_regs_len = sky2_get_regs_len,
+	.get_regs = sky2_get_regs,
+	.get_link = ethtool_op_get_link,
+	.get_sg = ethtool_op_get_sg,
+	.set_sg = ethtool_op_set_sg,
+	.get_tx_csum = ethtool_op_get_tx_csum,
+	.set_tx_csum = ethtool_op_set_tx_csum,
+	.get_tso = ethtool_op_get_tso,
+	.set_tso = ethtool_op_set_tso,
+	.get_rx_csum = sky2_get_rx_csum,
+	.set_rx_csum = sky2_set_rx_csum,
+	.get_strings = sky2_get_strings,
+	.get_coalesce = sky2_get_coalesce,
+	.set_coalesce = sky2_set_coalesce,
+	.get_ringparam = sky2_get_ringparam,
+	.set_ringparam = sky2_set_ringparam,
+	.get_pauseparam = sky2_get_pauseparam,
+	.set_pauseparam = sky2_set_pauseparam,
+#ifdef CONFIG_PM
+	.get_wol = sky2_get_wol,
+	.set_wol = sky2_set_wol,
+#endif
+	.phys_id = sky2_phys_id,
+	.get_stats_count = sky2_get_stats_count,
+	.get_ethtool_stats = sky2_get_ethtool_stats,
+	.get_perm_addr	= ethtool_op_get_perm_addr,
+};
+
+/* Initialize network device */
+static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
+						     unsigned port, int highmem)
+{
+	struct sky2_port *sky2;
+	struct net_device *dev = alloc_etherdev(sizeof(*sky2));
+
+	if (!dev) {
+		printk(KERN_ERR "sky2 etherdev alloc failed");
+		return NULL;
+	}
+
+	SET_MODULE_OWNER(dev);
+	SET_NETDEV_DEV(dev, &hw->pdev->dev);
+	dev->irq = hw->pdev->irq;
+	dev->open = sky2_up;
+	dev->stop = sky2_down;
+	dev->do_ioctl = sky2_ioctl;
+	dev->hard_start_xmit = sky2_xmit_frame;
+	dev->get_stats = sky2_get_stats;
+	dev->set_multicast_list = sky2_set_multicast;
+	dev->set_mac_address = sky2_set_mac_address;
+	dev->change_mtu = sky2_change_mtu;
+	SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops);
+	dev->tx_timeout = sky2_tx_timeout;
+	dev->watchdog_timeo = TX_WATCHDOG;
+	if (port == 0)
+		dev->poll = sky2_poll;
+	dev->weight = NAPI_WEIGHT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = sky2_netpoll;
+#endif
+
+	sky2 = netdev_priv(dev);
+	sky2->netdev = dev;
+	sky2->hw = hw;
+	sky2->msg_enable = netif_msg_init(debug, default_msg);
+
+	spin_lock_init(&sky2->tx_lock);
+	/* Auto speed and flow control */
+	sky2->autoneg = AUTONEG_ENABLE;
+	sky2->tx_pause = 1;
+	sky2->rx_pause = 1;
+	sky2->duplex = -1;
+	sky2->speed = -1;
+	sky2->advertising = sky2_supported_modes(hw);
+
+ 	/* Receive checksum disabled for Yukon XL
+	 * because of observed problems with incorrect
+	 * values when multiple packets are received in one interrupt
+	 */
+	sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
+
+	INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2);
+	init_MUTEX(&sky2->phy_sema);
+	sky2->tx_pending = TX_DEF_PENDING;
+	sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING;
+	sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
+
+	hw->dev[port] = dev;
+
+	sky2->port = port;
+
+	dev->features |= NETIF_F_LLTX;
+	if (hw->chip_id != CHIP_ID_YUKON_EC_U)
+		dev->features |= NETIF_F_TSO;
+	if (highmem)
+		dev->features |= NETIF_F_HIGHDMA;
+	dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+
+#ifdef SKY2_VLAN_TAG_USED
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	dev->vlan_rx_register = sky2_vlan_rx_register;
+	dev->vlan_rx_kill_vid = sky2_vlan_rx_kill_vid;
+#endif
+
+	/* read the mac address */
+	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+
+	/* device is off until link detection */
+	netif_carrier_off(dev);
+	netif_stop_queue(dev);
+
+	return dev;
+}
+
+static inline void sky2_show_addr(struct net_device *dev)
+{
+	const struct sky2_port *sky2 = netdev_priv(dev);
+
+	if (netif_msg_probe(sky2))
+		printk(KERN_INFO PFX "%s: addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+		       dev->name,
+		       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+}
+
+static int __devinit sky2_probe(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	struct net_device *dev, *dev1 = NULL;
+	struct sky2_hw *hw;
+	int err, pm_cap, using_dac = 0;
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR PFX "%s cannot enable PCI device\n",
+		       pci_name(pdev));
+		goto err_out;
+	}
+
+	err = pci_request_regions(pdev, DRV_NAME);
+	if (err) {
+		printk(KERN_ERR PFX "%s cannot obtain PCI resources\n",
+		       pci_name(pdev));
+		goto err_out;
+	}
+
+	pci_set_master(pdev);
+
+	/* Find power-management capability. */
+	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	if (pm_cap == 0) {
+		printk(KERN_ERR PFX "Cannot find PowerManagement capability, "
+		       "aborting.\n");
+		err = -EIO;
+		goto err_out_free_regions;
+	}
+
+	if (sizeof(dma_addr_t) > sizeof(u32)) {
+		err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+		if (!err)
+			using_dac = 1;
+	}
+
+	if (!using_dac) {
+		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+		if (err) {
+			printk(KERN_ERR PFX "%s no usable DMA configuration\n",
+			       pci_name(pdev));
+			goto err_out_free_regions;
+		}
+	}
+#ifdef __BIG_ENDIAN
+	/* byte swap descriptors in hardware */
+	{
+		u32 reg;
+
+		pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+		reg |= PCI_REV_DESC;
+		pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
+	}
+#endif
+
+	err = -ENOMEM;
+	hw = kmalloc(sizeof(*hw), GFP_KERNEL);
+	if (!hw) {
+		printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
+		       pci_name(pdev));
+		goto err_out_free_regions;
+	}
+
+	memset(hw, 0, sizeof(*hw));
+	hw->pdev = pdev;
+
+	hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
+	if (!hw->regs) {
+		printk(KERN_ERR PFX "%s: cannot map device registers\n",
+		       pci_name(pdev));
+		goto err_out_free_hw;
+	}
+	hw->pm_cap = pm_cap;
+
+	err = sky2_reset(hw);
+	if (err)
+		goto err_out_iounmap;
+
+	printk(KERN_INFO PFX "v%s addr 0x%lx irq %d Yukon-%s (0x%x) rev %d\n",
+	       DRV_VERSION, pci_resource_start(pdev, 0), pdev->irq,
+	       yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL],
+	       hw->chip_id, hw->chip_rev);
+
+	dev = sky2_init_netdev(hw, 0, using_dac);
+	if (!dev)
+		goto err_out_free_pci;
+
+	err = register_netdev(dev);
+	if (err) {
+		printk(KERN_ERR PFX "%s: cannot register net device\n",
+		       pci_name(pdev));
+		goto err_out_free_netdev;
+	}
+
+	sky2_show_addr(dev);
+
+	if (hw->ports > 1 && (dev1 = sky2_init_netdev(hw, 1, using_dac))) {
+		if (register_netdev(dev1) == 0)
+			sky2_show_addr(dev1);
+		else {
+			/* Failure to register second port need not be fatal */
+			printk(KERN_WARNING PFX
+			       "register of second port failed\n");
+			hw->dev[1] = NULL;
+			free_netdev(dev1);
+		}
+	}
+
+	err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
+	if (err) {
+		printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
+		       pci_name(pdev), pdev->irq);
+		goto err_out_unregister;
+	}
+
+	hw->intr_mask = Y2_IS_BASE;
+	sky2_write32(hw, B0_IMSK, hw->intr_mask);
+
+	pci_set_drvdata(pdev, hw);
+
+	return 0;
+
+err_out_unregister:
+	if (dev1) {
+		unregister_netdev(dev1);
+		free_netdev(dev1);
+	}
+	unregister_netdev(dev);
+err_out_free_netdev:
+	free_netdev(dev);
+err_out_free_pci:
+	sky2_write8(hw, B0_CTST, CS_RST_SET);
+	pci_free_consistent(hw->pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
+err_out_iounmap:
+	iounmap(hw->regs);
+err_out_free_hw:
+	kfree(hw);
+err_out_free_regions:
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+err_out:
+	return err;
+}
+
+static void __devexit sky2_remove(struct pci_dev *pdev)
+{
+	struct sky2_hw *hw = pci_get_drvdata(pdev);
+	struct net_device *dev0, *dev1;
+
+	if (!hw)
+		return;
+
+	dev0 = hw->dev[0];
+	dev1 = hw->dev[1];
+	if (dev1)
+		unregister_netdev(dev1);
+	unregister_netdev(dev0);
+
+	sky2_write32(hw, B0_IMSK, 0);
+	sky2_set_power_state(hw, PCI_D3hot);
+	sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
+	sky2_write8(hw, B0_CTST, CS_RST_SET);
+	sky2_read8(hw, B0_CTST);
+
+	free_irq(pdev->irq, hw);
+	pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+
+	if (dev1)
+		free_netdev(dev1);
+	free_netdev(dev0);
+	iounmap(hw->regs);
+	kfree(hw);
+
+	pci_set_drvdata(pdev, NULL);
+}
+
+#ifdef CONFIG_PM
+static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct sky2_hw *hw = pci_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		struct net_device *dev = hw->dev[i];
+
+		if (dev) {
+			if (!netif_running(dev))
+				continue;
+
+			sky2_down(dev);
+			netif_device_detach(dev);
+		}
+	}
+
+	return sky2_set_power_state(hw, pci_choose_state(pdev, state));
+}
+
+static int sky2_resume(struct pci_dev *pdev)
+{
+	struct sky2_hw *hw = pci_get_drvdata(pdev);
+	int i;
+
+	pci_restore_state(pdev);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	sky2_set_power_state(hw, PCI_D0);
+
+	sky2_reset(hw);
+
+	for (i = 0; i < 2; i++) {
+		struct net_device *dev = hw->dev[i];
+		if (dev) {
+			if (netif_running(dev)) {
+				netif_device_attach(dev);
+				if (sky2_up(dev))
+					dev_close(dev);
+			}
+		}
+	}
+	return 0;
+}
+#endif
+
+static struct pci_driver sky2_driver = {
+	.name = DRV_NAME,
+	.id_table = sky2_id_table,
+	.probe = sky2_probe,
+	.remove = __devexit_p(sky2_remove),
+#ifdef CONFIG_PM
+	.suspend = sky2_suspend,
+	.resume = sky2_resume,
+#endif
+};
+
+static int __init sky2_init_module(void)
+{
+	return pci_register_driver(&sky2_driver);
+}
+
+static void __exit sky2_cleanup_module(void)
+{
+	pci_unregister_driver(&sky2_driver);
+}
+
+module_init(sky2_init_module);
+module_exit(sky2_cleanup_module);
+
+MODULE_DESCRIPTION("Marvell Yukon 2 Gigabit Ethernet driver");
+MODULE_AUTHOR("Stephen Hemminger <shemminger@osdl.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
new file mode 100644
index 0000000..9551892
--- /dev/null
+++ b/drivers/net/sky2.h
@@ -0,0 +1,1922 @@
+/*
+ * Definitions for the new Marvell Yukon 2 driver.
+ */
+#ifndef _SKY2_H
+#define _SKY2_H
+
+/* PCI config registers */
+#define PCI_DEV_REG1	0x40
+#define PCI_DEV_REG2	0x44
+#define PCI_DEV_STATUS  0x7c
+#define PCI_OS_PCI_X    (1<<26)
+
+#define PEX_LNK_STAT	0xf2
+#define PEX_UNC_ERR_STAT 0x104
+#define PEX_DEV_CTRL	0xe8
+
+/* Yukon-2 */
+enum pci_dev_reg_1 {
+	PCI_Y2_PIG_ENA	 = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
+	PCI_Y2_DLL_DIS	 = 1<<30, /* Disable PCI DLL (YUKON-2) */
+	PCI_Y2_PHY2_COMA = 1<<29, /* Set PHY 2 to Coma Mode (YUKON-2) */
+	PCI_Y2_PHY1_COMA = 1<<28, /* Set PHY 1 to Coma Mode (YUKON-2) */
+	PCI_Y2_PHY2_POWD = 1<<27, /* Set PHY 2 to Power Down (YUKON-2) */
+	PCI_Y2_PHY1_POWD = 1<<26, /* Set PHY 1 to Power Down (YUKON-2) */
+};
+
+enum pci_dev_reg_2 {
+	PCI_VPD_WR_THR	= 0xffL<<24,	/* Bit 31..24:	VPD Write Threshold */
+	PCI_DEV_SEL	= 0x7fL<<17,	/* Bit 23..17:	EEPROM Device Select */
+	PCI_VPD_ROM_SZ	= 7L<<14,	/* Bit 16..14:	VPD ROM Size	*/
+
+	PCI_PATCH_DIR	= 0xfL<<8,	/* Bit 11.. 8:	Ext Patches dir 3..0 */
+	PCI_EXT_PATCHS	= 0xfL<<4,	/* Bit	7.. 4:	Extended Patches 3..0 */
+	PCI_EN_DUMMY_RD	= 1<<3,		/* Enable Dummy Read */
+	PCI_REV_DESC	= 1<<2,		/* Reverse Desc. Bytes */
+
+	PCI_USEDATA64	= 1<<0,		/* Use 64Bit Data bus ext */
+};
+
+
+#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
+			       PCI_STATUS_SIG_SYSTEM_ERROR | \
+			       PCI_STATUS_REC_MASTER_ABORT | \
+			       PCI_STATUS_REC_TARGET_ABORT | \
+			       PCI_STATUS_PARITY)
+
+enum pex_dev_ctrl {
+	PEX_DC_MAX_RRS_MSK	= 7<<12, /* Bit 14..12:	Max. Read Request Size */
+	PEX_DC_EN_NO_SNOOP	= 1<<11,/* Enable No Snoop */
+	PEX_DC_EN_AUX_POW	= 1<<10,/* Enable AUX Power */
+	PEX_DC_EN_PHANTOM	= 1<<9,	/* Enable Phantom Functions */
+	PEX_DC_EN_EXT_TAG	= 1<<8,	/* Enable Extended Tag Field */
+	PEX_DC_MAX_PLS_MSK	= 7<<5,	/* Bit  7.. 5:	Max. Payload Size Mask */
+	PEX_DC_EN_REL_ORD	= 1<<4,	/* Enable Relaxed Ordering */
+	PEX_DC_EN_UNS_RQ_RP	= 1<<3,	/* Enable Unsupported Request Reporting */
+	PEX_DC_EN_FAT_ER_RP	= 1<<2,	/* Enable Fatal Error Reporting */
+	PEX_DC_EN_NFA_ER_RP	= 1<<1,	/* Enable Non-Fatal Error Reporting */
+	PEX_DC_EN_COR_ER_RP	= 1<<0,	/* Enable Correctable Error Reporting */
+};
+#define  PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
+
+/* PEX_UNC_ERR_STAT	 PEX Uncorrectable Errors Status Register (Yukon-2) */
+enum pex_err {
+	PEX_UNSUP_REQ 	= 1<<20, /* Unsupported Request Error */
+
+	PEX_MALFOR_TLP	= 1<<18, /* Malformed TLP */
+
+	PEX_UNEXP_COMP	= 1<<16, /* Unexpected Completion */
+
+	PEX_COMP_TO	= 1<<14, /* Completion Timeout */
+	PEX_FLOW_CTRL_P	= 1<<13, /* Flow Control Protocol Error */
+	PEX_POIS_TLP	= 1<<12, /* Poisoned TLP */
+
+	PEX_DATA_LINK_P = 1<<4,	/* Data Link Protocol Error */
+	PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
+};
+
+
+enum csr_regs {
+	B0_RAP		= 0x0000,
+	B0_CTST		= 0x0004,
+	B0_Y2LED	= 0x0005,
+	B0_POWER_CTRL	= 0x0007,
+	B0_ISRC		= 0x0008,
+	B0_IMSK		= 0x000c,
+	B0_HWE_ISRC	= 0x0010,
+	B0_HWE_IMSK	= 0x0014,
+
+	/* Special ISR registers (Yukon-2 only) */
+	B0_Y2_SP_ISRC2	= 0x001c,
+	B0_Y2_SP_ISRC3	= 0x0020,
+	B0_Y2_SP_EISR	= 0x0024,
+	B0_Y2_SP_LISR	= 0x0028,
+	B0_Y2_SP_ICR	= 0x002c,
+
+	B2_MAC_1	= 0x0100,
+	B2_MAC_2	= 0x0108,
+	B2_MAC_3	= 0x0110,
+	B2_CONN_TYP	= 0x0118,
+	B2_PMD_TYP	= 0x0119,
+	B2_MAC_CFG	= 0x011a,
+	B2_CHIP_ID	= 0x011b,
+	B2_E_0		= 0x011c,
+
+	B2_Y2_CLK_GATE  = 0x011d,
+	B2_Y2_HW_RES	= 0x011e,
+	B2_E_3		= 0x011f,
+	B2_Y2_CLK_CTRL	= 0x0120,
+
+	B2_TI_INI	= 0x0130,
+	B2_TI_VAL	= 0x0134,
+	B2_TI_CTRL	= 0x0138,
+	B2_TI_TEST	= 0x0139,
+
+	B2_TST_CTRL1	= 0x0158,
+	B2_TST_CTRL2	= 0x0159,
+	B2_GP_IO	= 0x015c,
+
+	B2_I2C_CTRL	= 0x0160,
+	B2_I2C_DATA	= 0x0164,
+	B2_I2C_IRQ	= 0x0168,
+	B2_I2C_SW	= 0x016c,
+
+	B3_RAM_ADDR	= 0x0180,
+	B3_RAM_DATA_LO	= 0x0184,
+	B3_RAM_DATA_HI	= 0x0188,
+
+/* RAM Interface Registers */
+/* Yukon-2: use RAM_BUFFER() to access the RAM buffer */
+/*
+ * The HW-Spec. calls this registers Timeout Value 0..11. But this names are
+ * not usable in SW. Please notice these are NOT real timeouts, these are
+ * the number of qWords transferred continuously.
+ */
+#define RAM_BUFFER(port, reg)	(reg | (port <<6))
+
+	B3_RI_WTO_R1	= 0x0190,
+	B3_RI_WTO_XA1	= 0x0191,
+	B3_RI_WTO_XS1	= 0x0192,
+	B3_RI_RTO_R1	= 0x0193,
+	B3_RI_RTO_XA1	= 0x0194,
+	B3_RI_RTO_XS1	= 0x0195,
+	B3_RI_WTO_R2	= 0x0196,
+	B3_RI_WTO_XA2	= 0x0197,
+	B3_RI_WTO_XS2	= 0x0198,
+	B3_RI_RTO_R2	= 0x0199,
+	B3_RI_RTO_XA2	= 0x019a,
+	B3_RI_RTO_XS2	= 0x019b,
+	B3_RI_TO_VAL	= 0x019c,
+	B3_RI_CTRL	= 0x01a0,
+	B3_RI_TEST	= 0x01a2,
+	B3_MA_TOINI_RX1	= 0x01b0,
+	B3_MA_TOINI_RX2	= 0x01b1,
+	B3_MA_TOINI_TX1	= 0x01b2,
+	B3_MA_TOINI_TX2	= 0x01b3,
+	B3_MA_TOVAL_RX1	= 0x01b4,
+	B3_MA_TOVAL_RX2	= 0x01b5,
+	B3_MA_TOVAL_TX1	= 0x01b6,
+	B3_MA_TOVAL_TX2	= 0x01b7,
+	B3_MA_TO_CTRL	= 0x01b8,
+	B3_MA_TO_TEST	= 0x01ba,
+	B3_MA_RCINI_RX1	= 0x01c0,
+	B3_MA_RCINI_RX2	= 0x01c1,
+	B3_MA_RCINI_TX1	= 0x01c2,
+	B3_MA_RCINI_TX2	= 0x01c3,
+	B3_MA_RCVAL_RX1	= 0x01c4,
+	B3_MA_RCVAL_RX2	= 0x01c5,
+	B3_MA_RCVAL_TX1	= 0x01c6,
+	B3_MA_RCVAL_TX2	= 0x01c7,
+	B3_MA_RC_CTRL	= 0x01c8,
+	B3_MA_RC_TEST	= 0x01ca,
+	B3_PA_TOINI_RX1	= 0x01d0,
+	B3_PA_TOINI_RX2	= 0x01d4,
+	B3_PA_TOINI_TX1	= 0x01d8,
+	B3_PA_TOINI_TX2	= 0x01dc,
+	B3_PA_TOVAL_RX1	= 0x01e0,
+	B3_PA_TOVAL_RX2	= 0x01e4,
+	B3_PA_TOVAL_TX1	= 0x01e8,
+	B3_PA_TOVAL_TX2	= 0x01ec,
+	B3_PA_CTRL	= 0x01f0,
+	B3_PA_TEST	= 0x01f2,
+
+	Y2_CFG_SPC	= 0x1c00,
+};
+
+/*	B0_CTST			16 bit	Control/Status register */
+enum {
+	Y2_VMAIN_AVAIL	= 1<<17,/* VMAIN available (YUKON-2 only) */
+	Y2_VAUX_AVAIL	= 1<<16,/* VAUX available (YUKON-2 only) */
+	Y2_ASF_ENABLE	= 1<<13,/* ASF Unit Enable (YUKON-2 only) */
+	Y2_ASF_DISABLE	= 1<<12,/* ASF Unit Disable (YUKON-2 only) */
+	Y2_CLK_RUN_ENA	= 1<<11,/* CLK_RUN Enable  (YUKON-2 only) */
+	Y2_CLK_RUN_DIS	= 1<<10,/* CLK_RUN Disable (YUKON-2 only) */
+	Y2_LED_STAT_ON	= 1<<9, /* Status LED On  (YUKON-2 only) */
+	Y2_LED_STAT_OFF	= 1<<8, /* Status LED Off (YUKON-2 only) */
+
+	CS_ST_SW_IRQ	= 1<<7,	/* Set IRQ SW Request */
+	CS_CL_SW_IRQ	= 1<<6,	/* Clear IRQ SW Request */
+	CS_STOP_DONE	= 1<<5,	/* Stop Master is finished */
+	CS_STOP_MAST	= 1<<4,	/* Command Bit to stop the master */
+	CS_MRST_CLR	= 1<<3,	/* Clear Master reset	*/
+	CS_MRST_SET	= 1<<2,	/* Set Master reset	*/
+	CS_RST_CLR	= 1<<1,	/* Clear Software reset	*/
+	CS_RST_SET	= 1,	/* Set   Software reset	*/
+};
+
+/*	B0_LED			 8 Bit	LED register */
+enum {
+/* Bit  7.. 2:	reserved */
+	LED_STAT_ON	= 1<<1,	/* Status LED on	*/
+	LED_STAT_OFF	= 1,	/* Status LED off	*/
+};
+
+/*	B0_POWER_CTRL	 8 Bit	Power Control reg (YUKON only) */
+enum {
+	PC_VAUX_ENA	= 1<<7,	/* Switch VAUX Enable  */
+	PC_VAUX_DIS	= 1<<6,	/* Switch VAUX Disable */
+	PC_VCC_ENA	= 1<<5,	/* Switch VCC Enable  */
+	PC_VCC_DIS	= 1<<4,	/* Switch VCC Disable */
+	PC_VAUX_ON	= 1<<3,	/* Switch VAUX On  */
+	PC_VAUX_OFF	= 1<<2,	/* Switch VAUX Off */
+	PC_VCC_ON	= 1<<1,	/* Switch VCC On  */
+	PC_VCC_OFF	= 1<<0,	/* Switch VCC Off */
+};
+
+/*	B2_IRQM_MSK 	32 bit	IRQ Moderation Mask */
+
+/*	B0_Y2_SP_ISRC2	32 bit	Special Interrupt Source Reg 2 */
+/*	B0_Y2_SP_ISRC3	32 bit	Special Interrupt Source Reg 3 */
+/*	B0_Y2_SP_EISR	32 bit	Enter ISR Reg */
+/*	B0_Y2_SP_LISR	32 bit	Leave ISR Reg */
+enum {
+	Y2_IS_HW_ERR	= 1<<31,	/* Interrupt HW Error */
+	Y2_IS_STAT_BMU	= 1<<30,	/* Status BMU Interrupt */
+	Y2_IS_ASF	= 1<<29,	/* ASF subsystem Interrupt */
+
+	Y2_IS_POLL_CHK	= 1<<27,	/* Check IRQ from polling unit */
+	Y2_IS_TWSI_RDY	= 1<<26,	/* IRQ on end of TWSI Tx */
+	Y2_IS_IRQ_SW	= 1<<25,	/* SW forced IRQ	*/
+	Y2_IS_TIMINT	= 1<<24,	/* IRQ from Timer	*/
+
+	Y2_IS_IRQ_PHY2	= 1<<12,	/* Interrupt from PHY 2 */
+	Y2_IS_IRQ_MAC2	= 1<<11,	/* Interrupt from MAC 2 */
+	Y2_IS_CHK_RX2	= 1<<10,	/* Descriptor error Rx 2 */
+	Y2_IS_CHK_TXS2	= 1<<9,		/* Descriptor error TXS 2 */
+	Y2_IS_CHK_TXA2	= 1<<8,		/* Descriptor error TXA 2 */
+
+	Y2_IS_IRQ_PHY1	= 1<<4,		/* Interrupt from PHY 1 */
+	Y2_IS_IRQ_MAC1	= 1<<3,		/* Interrupt from MAC 1 */
+	Y2_IS_CHK_RX1	= 1<<2,		/* Descriptor error Rx 1 */
+	Y2_IS_CHK_TXS1	= 1<<1,		/* Descriptor error TXS 1 */
+	Y2_IS_CHK_TXA1	= 1<<0,		/* Descriptor error TXA 1 */
+
+	Y2_IS_BASE	= Y2_IS_HW_ERR | Y2_IS_STAT_BMU |
+			  Y2_IS_POLL_CHK | Y2_IS_TWSI_RDY |
+			  Y2_IS_IRQ_SW | Y2_IS_TIMINT,
+	Y2_IS_PORT_1	= Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 |
+			  Y2_IS_CHK_RX1 | Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXS1,
+	Y2_IS_PORT_2	= Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 |
+			  Y2_IS_CHK_RX2 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_TXS2,
+};
+
+/*	B2_IRQM_HWE_MSK	32 bit	IRQ Moderation HW Error Mask */
+enum {
+	IS_ERR_MSK	= 0x00003fff,/* 		All Error bits */
+
+	IS_IRQ_TIST_OV	= 1<<13, /* Time Stamp Timer Overflow (YUKON only) */
+	IS_IRQ_SENSOR	= 1<<12, /* IRQ from Sensor (YUKON only) */
+	IS_IRQ_MST_ERR	= 1<<11, /* IRQ master error detected */
+	IS_IRQ_STAT	= 1<<10, /* IRQ status exception */
+	IS_NO_STAT_M1	= 1<<9,	/* No Rx Status from MAC 1 */
+	IS_NO_STAT_M2	= 1<<8,	/* No Rx Status from MAC 2 */
+	IS_NO_TIST_M1	= 1<<7,	/* No Time Stamp from MAC 1 */
+	IS_NO_TIST_M2	= 1<<6,	/* No Time Stamp from MAC 2 */
+	IS_RAM_RD_PAR	= 1<<5,	/* RAM Read  Parity Error */
+	IS_RAM_WR_PAR	= 1<<4,	/* RAM Write Parity Error */
+	IS_M1_PAR_ERR	= 1<<3,	/* MAC 1 Parity Error */
+	IS_M2_PAR_ERR	= 1<<2,	/* MAC 2 Parity Error */
+	IS_R1_PAR_ERR	= 1<<1,	/* Queue R1 Parity Error */
+	IS_R2_PAR_ERR	= 1<<0,	/* Queue R2 Parity Error */
+};
+
+/* Hardware error interrupt mask for Yukon 2 */
+enum {
+	Y2_IS_TIST_OV	= 1<<29,/* Time Stamp Timer overflow interrupt */
+	Y2_IS_SENSOR	= 1<<28, /* Sensor interrupt */
+	Y2_IS_MST_ERR	= 1<<27, /* Master error interrupt */
+	Y2_IS_IRQ_STAT	= 1<<26, /* Status exception interrupt */
+	Y2_IS_PCI_EXP	= 1<<25, /* PCI-Express interrupt */
+	Y2_IS_PCI_NEXP	= 1<<24, /* PCI-Express error similar to PCI error */
+						/* Link 2 */
+	Y2_IS_PAR_RD2	= 1<<13, /* Read RAM parity error interrupt */
+	Y2_IS_PAR_WR2	= 1<<12, /* Write RAM parity error interrupt */
+	Y2_IS_PAR_MAC2	= 1<<11, /* MAC hardware fault interrupt */
+	Y2_IS_PAR_RX2	= 1<<10, /* Parity Error Rx Queue 2 */
+	Y2_IS_TCP_TXS2	= 1<<9, /* TCP length mismatch sync Tx queue IRQ */
+	Y2_IS_TCP_TXA2	= 1<<8, /* TCP length mismatch async Tx queue IRQ */
+						/* Link 1 */
+	Y2_IS_PAR_RD1	= 1<<5, /* Read RAM parity error interrupt */
+	Y2_IS_PAR_WR1	= 1<<4, /* Write RAM parity error interrupt */
+	Y2_IS_PAR_MAC1	= 1<<3, /* MAC hardware fault interrupt */
+	Y2_IS_PAR_RX1	= 1<<2, /* Parity Error Rx Queue 1 */
+	Y2_IS_TCP_TXS1	= 1<<1, /* TCP length mismatch sync Tx queue IRQ */
+	Y2_IS_TCP_TXA1	= 1<<0, /* TCP length mismatch async Tx queue IRQ */
+
+	Y2_HWE_L1_MASK	= Y2_IS_PAR_RD1 | Y2_IS_PAR_WR1 | Y2_IS_PAR_MAC1 |
+			  Y2_IS_PAR_RX1 | Y2_IS_TCP_TXS1| Y2_IS_TCP_TXA1,
+	Y2_HWE_L2_MASK	= Y2_IS_PAR_RD2 | Y2_IS_PAR_WR2 | Y2_IS_PAR_MAC2 |
+			  Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2,
+
+	Y2_HWE_ALL_MASK	= Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT |
+			  Y2_IS_PCI_EXP |
+			  Y2_HWE_L1_MASK | Y2_HWE_L2_MASK,
+};
+
+/*	B28_DPT_CTRL	 8 bit	Descriptor Poll Timer Ctrl Reg */
+enum {
+	DPT_START	= 1<<1,
+	DPT_STOP	= 1<<0,
+};
+
+/*	B2_TST_CTRL1	 8 bit	Test Control Register 1 */
+enum {
+	TST_FRC_DPERR_MR = 1<<7, /* force DATAPERR on MST RD */
+	TST_FRC_DPERR_MW = 1<<6, /* force DATAPERR on MST WR */
+	TST_FRC_DPERR_TR = 1<<5, /* force DATAPERR on TRG RD */
+	TST_FRC_DPERR_TW = 1<<4, /* force DATAPERR on TRG WR */
+	TST_FRC_APERR_M	 = 1<<3, /* force ADDRPERR on MST */
+	TST_FRC_APERR_T	 = 1<<2, /* force ADDRPERR on TRG */
+	TST_CFG_WRITE_ON = 1<<1, /* Enable  Config Reg WR */
+	TST_CFG_WRITE_OFF= 1<<0, /* Disable Config Reg WR */
+};
+
+/*	B2_MAC_CFG		 8 bit	MAC Configuration / Chip Revision */
+enum {
+	CFG_CHIP_R_MSK	  = 0xf<<4,	/* Bit 7.. 4: Chip Revision */
+					/* Bit 3.. 2:	reserved */
+	CFG_DIS_M2_CLK	  = 1<<1,	/* Disable Clock for 2nd MAC */
+	CFG_SNG_MAC	  = 1<<0,	/* MAC Config: 0=2 MACs / 1=1 MAC*/
+};
+
+/*	B2_CHIP_ID		 8 bit 	Chip Identification Number */
+enum {
+	CHIP_ID_GENESIS	   = 0x0a, /* Chip ID for GENESIS */
+	CHIP_ID_YUKON	   = 0xb0, /* Chip ID for YUKON */
+	CHIP_ID_YUKON_LITE = 0xb1, /* Chip ID for YUKON-Lite (Rev. A1-A3) */
+	CHIP_ID_YUKON_LP   = 0xb2, /* Chip ID for YUKON-LP */
+	CHIP_ID_YUKON_XL   = 0xb3, /* Chip ID for YUKON-2 XL */
+	CHIP_ID_YUKON_EC_U = 0xb4, /* Chip ID for YUKON-2 EC Ultra */
+	CHIP_ID_YUKON_EC   = 0xb6, /* Chip ID for YUKON-2 EC */
+ 	CHIP_ID_YUKON_FE   = 0xb7, /* Chip ID for YUKON-2 FE */
+
+	CHIP_REV_YU_EC_A1    = 0,  /* Chip Rev. for Yukon-EC A1/A0 */
+	CHIP_REV_YU_EC_A2    = 1,  /* Chip Rev. for Yukon-EC A2 */
+	CHIP_REV_YU_EC_A3    = 2,  /* Chip Rev. for Yukon-EC A3 */
+};
+
+/*	B2_Y2_CLK_GATE	 8 bit	Clock Gating (Yukon-2 only) */
+enum {
+	Y2_STATUS_LNK2_INAC	= 1<<7, /* Status Link 2 inactive (0 = active) */
+	Y2_CLK_GAT_LNK2_DIS	= 1<<6, /* Disable clock gating Link 2 */
+	Y2_COR_CLK_LNK2_DIS	= 1<<5, /* Disable Core clock Link 2 */
+	Y2_PCI_CLK_LNK2_DIS	= 1<<4, /* Disable PCI clock Link 2 */
+	Y2_STATUS_LNK1_INAC	= 1<<3, /* Status Link 1 inactive (0 = active) */
+	Y2_CLK_GAT_LNK1_DIS	= 1<<2, /* Disable clock gating Link 1 */
+	Y2_COR_CLK_LNK1_DIS	= 1<<1, /* Disable Core clock Link 1 */
+	Y2_PCI_CLK_LNK1_DIS	= 1<<0, /* Disable PCI clock Link 1 */
+};
+
+/*	B2_Y2_HW_RES	8 bit	HW Resources (Yukon-2 only) */
+enum {
+	CFG_LED_MODE_MSK	= 7<<2,	/* Bit  4.. 2:	LED Mode Mask */
+	CFG_LINK_2_AVAIL	= 1<<1,	/* Link 2 available */
+	CFG_LINK_1_AVAIL	= 1<<0,	/* Link 1 available */
+};
+#define CFG_LED_MODE(x)		(((x) & CFG_LED_MODE_MSK) >> 2)
+#define CFG_DUAL_MAC_MSK	(CFG_LINK_2_AVAIL | CFG_LINK_1_AVAIL)
+
+
+/* B2_Y2_CLK_CTRL	32 bit	Clock Frequency Control Register (Yukon-2/EC) */
+enum {
+	Y2_CLK_DIV_VAL_MSK	= 0xff<<16,/* Bit 23..16: Clock Divisor Value */
+#define	Y2_CLK_DIV_VAL(x)	(((x)<<16) & Y2_CLK_DIV_VAL_MSK)
+	Y2_CLK_DIV_VAL2_MSK	= 7<<21,   /* Bit 23..21: Clock Divisor Value */
+	Y2_CLK_SELECT2_MSK	= 0x1f<<16,/* Bit 20..16: Clock Select */
+#define Y2_CLK_DIV_VAL_2(x)	(((x)<<21) & Y2_CLK_DIV_VAL2_MSK)
+#define Y2_CLK_SEL_VAL_2(x)	(((x)<<16) & Y2_CLK_SELECT2_MSK)
+	Y2_CLK_DIV_ENA		= 1<<1, /* Enable  Core Clock Division */
+	Y2_CLK_DIV_DIS		= 1<<0,	/* Disable Core Clock Division */
+};
+
+/*	B2_TI_CTRL		 8 bit	Timer control */
+/*	B2_IRQM_CTRL	 8 bit	IRQ Moderation Timer Control */
+enum {
+	TIM_START	= 1<<2,	/* Start Timer */
+	TIM_STOP	= 1<<1,	/* Stop  Timer */
+	TIM_CLR_IRQ	= 1<<0,	/* Clear Timer IRQ (!IRQM) */
+};
+
+/*	B2_TI_TEST		 8 Bit	Timer Test */
+/*	B2_IRQM_TEST	 8 bit	IRQ Moderation Timer Test */
+/*	B28_DPT_TST		 8 bit	Descriptor Poll Timer Test Reg */
+enum {
+	TIM_T_ON	= 1<<2,	/* Test mode on */
+	TIM_T_OFF	= 1<<1,	/* Test mode off */
+	TIM_T_STEP	= 1<<0,	/* Test step */
+};
+
+/*	B3_RAM_ADDR		32 bit	RAM Address, to read or write */
+					/* Bit 31..19:	reserved */
+#define RAM_ADR_RAN	0x0007ffffL	/* Bit 18.. 0:	RAM Address Range */
+/* RAM Interface Registers */
+
+/*	B3_RI_CTRL		16 bit	RAM Interface Control Register */
+enum {
+	RI_CLR_RD_PERR	= 1<<9,	/* Clear IRQ RAM Read Parity Err */
+	RI_CLR_WR_PERR	= 1<<8,	/* Clear IRQ RAM Write Parity Err*/
+
+	RI_RST_CLR	= 1<<1,	/* Clear RAM Interface Reset */
+	RI_RST_SET	= 1<<0,	/* Set   RAM Interface Reset */
+};
+
+#define SK_RI_TO_53	36		/* RAM interface timeout */
+
+
+/* Port related registers FIFO, and Arbiter */
+#define SK_REG(port,reg)	(((port)<<7)+(reg))
+
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+/*	TXA_ITI_INI		32 bit	Tx Arb Interval Timer Init Val */
+/*	TXA_ITI_VAL		32 bit	Tx Arb Interval Timer Value */
+/*	TXA_LIM_INI		32 bit	Tx Arb Limit Counter Init Val */
+/*	TXA_LIM_VAL		32 bit	Tx Arb Limit Counter Value */
+
+#define TXA_MAX_VAL	0x00ffffffUL	/* Bit 23.. 0:	Max TXA Timer/Cnt Val */
+
+/*	TXA_CTRL		 8 bit	Tx Arbiter Control Register */
+enum {
+	TXA_ENA_FSYNC	= 1<<7,	/* Enable  force of sync Tx queue */
+	TXA_DIS_FSYNC	= 1<<6,	/* Disable force of sync Tx queue */
+	TXA_ENA_ALLOC	= 1<<5,	/* Enable  alloc of free bandwidth */
+	TXA_DIS_ALLOC	= 1<<4,	/* Disable alloc of free bandwidth */
+	TXA_START_RC	= 1<<3,	/* Start sync Rate Control */
+	TXA_STOP_RC	= 1<<2,	/* Stop  sync Rate Control */
+	TXA_ENA_ARB	= 1<<1,	/* Enable  Tx Arbiter */
+	TXA_DIS_ARB	= 1<<0,	/* Disable Tx Arbiter */
+};
+
+/*
+ *	Bank 4 - 5
+ */
+/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */
+enum {
+	TXA_ITI_INI	= 0x0200,/* 32 bit	Tx Arb Interval Timer Init Val*/
+	TXA_ITI_VAL	= 0x0204,/* 32 bit	Tx Arb Interval Timer Value */
+	TXA_LIM_INI	= 0x0208,/* 32 bit	Tx Arb Limit Counter Init Val */
+	TXA_LIM_VAL	= 0x020c,/* 32 bit	Tx Arb Limit Counter Value */
+	TXA_CTRL	= 0x0210,/*  8 bit	Tx Arbiter Control Register */
+	TXA_TEST	= 0x0211,/*  8 bit	Tx Arbiter Test Register */
+	TXA_STAT	= 0x0212,/*  8 bit	Tx Arbiter Status Register */
+};
+
+
+enum {
+	B6_EXT_REG	= 0x0300,/* External registers (GENESIS only) */
+	B7_CFG_SPC	= 0x0380,/* copy of the Configuration register */
+	B8_RQ1_REGS	= 0x0400,/* Receive Queue 1 */
+	B8_RQ2_REGS	= 0x0480,/* Receive Queue 2 */
+	B8_TS1_REGS	= 0x0600,/* Transmit sync queue 1 */
+	B8_TA1_REGS	= 0x0680,/* Transmit async queue 1 */
+	B8_TS2_REGS	= 0x0700,/* Transmit sync queue 2 */
+	B8_TA2_REGS	= 0x0780,/* Transmit sync queue 2 */
+	B16_RAM_REGS	= 0x0800,/* RAM Buffer Registers */
+};
+
+/* Queue Register Offsets, use Q_ADDR() to access */
+enum {
+	B8_Q_REGS = 0x0400, /* base of Queue registers */
+	Q_D	= 0x00,	/* 8*32	bit	Current Descriptor */
+	Q_DA_L	= 0x20,	/* 32 bit	Current Descriptor Address Low dWord */
+	Q_DA_H	= 0x24,	/* 32 bit	Current Descriptor Address High dWord */
+	Q_AC_L	= 0x28,	/* 32 bit	Current Address Counter Low dWord */
+	Q_AC_H	= 0x2c,	/* 32 bit	Current Address Counter High dWord */
+	Q_BC	= 0x30,	/* 32 bit	Current Byte Counter */
+	Q_CSR	= 0x34,	/* 32 bit	BMU Control/Status Register */
+	Q_F	= 0x38,	/* 32 bit	Flag Register */
+	Q_T1	= 0x3c,	/* 32 bit	Test Register 1 */
+	Q_T1_TR	= 0x3c,	/*  8 bit	Test Register 1 Transfer SM */
+	Q_T1_WR	= 0x3d,	/*  8 bit	Test Register 1 Write Descriptor SM */
+	Q_T1_RD	= 0x3e,	/*  8 bit	Test Register 1 Read Descriptor SM */
+	Q_T1_SV	= 0x3f,	/*  8 bit	Test Register 1 Supervisor SM */
+	Q_T2	= 0x40,	/* 32 bit	Test Register 2	*/
+	Q_T3	= 0x44,	/* 32 bit	Test Register 3	*/
+
+/* Yukon-2 */
+	Q_DONE	= 0x24,	/* 16 bit	Done Index 		(Yukon-2 only) */
+	Q_WM	= 0x40,	/* 16 bit	FIFO Watermark */
+	Q_AL	= 0x42,	/*  8 bit	FIFO Alignment */
+	Q_RSP	= 0x44,	/* 16 bit	FIFO Read Shadow Pointer */
+	Q_RSL	= 0x46,	/*  8 bit	FIFO Read Shadow Level */
+	Q_RP	= 0x48,	/*  8 bit	FIFO Read Pointer */
+	Q_RL	= 0x4a,	/*  8 bit	FIFO Read Level */
+	Q_WP	= 0x4c,	/*  8 bit	FIFO Write Pointer */
+	Q_WSP	= 0x4d,	/*  8 bit	FIFO Write Shadow Pointer */
+	Q_WL	= 0x4e,	/*  8 bit	FIFO Write Level */
+	Q_WSL	= 0x4f,	/*  8 bit	FIFO Write Shadow Level */
+};
+#define Q_ADDR(reg, offs) (B8_Q_REGS + (reg) + (offs))
+
+
+/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
+enum {
+	Y2_B8_PREF_REGS		= 0x0450,
+
+	PREF_UNIT_CTRL		= 0x00,	/* 32 bit	Control register */
+	PREF_UNIT_LAST_IDX	= 0x04,	/* 16 bit	Last Index */
+	PREF_UNIT_ADDR_LO	= 0x08,	/* 32 bit	List start addr, low part */
+	PREF_UNIT_ADDR_HI	= 0x0c,	/* 32 bit	List start addr, high part*/
+	PREF_UNIT_GET_IDX	= 0x10,	/* 16 bit	Get Index */
+	PREF_UNIT_PUT_IDX	= 0x14,	/* 16 bit	Put Index */
+	PREF_UNIT_FIFO_WP	= 0x20,	/*  8 bit	FIFO write pointer */
+	PREF_UNIT_FIFO_RP	= 0x24,	/*  8 bit	FIFO read pointer */
+	PREF_UNIT_FIFO_WM	= 0x28,	/*  8 bit	FIFO watermark */
+	PREF_UNIT_FIFO_LEV	= 0x2c,	/*  8 bit	FIFO level */
+
+	PREF_UNIT_MASK_IDX	= 0x0fff,
+};
+#define Y2_QADDR(q,reg)		(Y2_B8_PREF_REGS + (q) + (reg))
+
+/* RAM Buffer Register Offsets */
+enum {
+
+	RB_START	= 0x00,/* 32 bit	RAM Buffer Start Address */
+	RB_END	= 0x04,/* 32 bit	RAM Buffer End Address */
+	RB_WP	= 0x08,/* 32 bit	RAM Buffer Write Pointer */
+	RB_RP	= 0x0c,/* 32 bit	RAM Buffer Read Pointer */
+	RB_RX_UTPP	= 0x10,/* 32 bit	Rx Upper Threshold, Pause Packet */
+	RB_RX_LTPP	= 0x14,/* 32 bit	Rx Lower Threshold, Pause Packet */
+	RB_RX_UTHP	= 0x18,/* 32 bit	Rx Upper Threshold, High Prio */
+	RB_RX_LTHP	= 0x1c,/* 32 bit	Rx Lower Threshold, High Prio */
+	/* 0x10 - 0x1f:	reserved at Tx RAM Buffer Registers */
+	RB_PC	= 0x20,/* 32 bit	RAM Buffer Packet Counter */
+	RB_LEV	= 0x24,/* 32 bit	RAM Buffer Level Register */
+	RB_CTRL	= 0x28,/* 32 bit	RAM Buffer Control Register */
+	RB_TST1	= 0x29,/*  8 bit	RAM Buffer Test Register 1 */
+	RB_TST2	= 0x2a,/*  8 bit	RAM Buffer Test Register 2 */
+};
+
+/* Receive and Transmit Queues */
+enum {
+	Q_R1	= 0x0000,	/* Receive Queue 1 */
+	Q_R2	= 0x0080,	/* Receive Queue 2 */
+	Q_XS1	= 0x0200,	/* Synchronous Transmit Queue 1 */
+	Q_XA1	= 0x0280,	/* Asynchronous Transmit Queue 1 */
+	Q_XS2	= 0x0300,	/* Synchronous Transmit Queue 2 */
+	Q_XA2	= 0x0380,	/* Asynchronous Transmit Queue 2 */
+};
+
+/* Different PHY Types */
+enum {
+	PHY_ADDR_MARV	= 0,
+};
+
+#define RB_ADDR(offs, queue) (B16_RAM_REGS + (queue) + (offs))
+
+
+enum {
+	LNK_SYNC_INI	= 0x0c30,/* 32 bit	Link Sync Cnt Init Value */
+	LNK_SYNC_VAL	= 0x0c34,/* 32 bit	Link Sync Cnt Current Value */
+	LNK_SYNC_CTRL	= 0x0c38,/*  8 bit	Link Sync Cnt Control Register */
+	LNK_SYNC_TST	= 0x0c39,/*  8 bit	Link Sync Cnt Test Register */
+
+	LNK_LED_REG	= 0x0c3c,/*  8 bit	Link LED Register */
+
+/* Receive GMAC FIFO (YUKON and Yukon-2) */
+
+	RX_GMF_EA	= 0x0c40,/* 32 bit	Rx GMAC FIFO End Address */
+	RX_GMF_AF_THR	= 0x0c44,/* 32 bit	Rx GMAC FIFO Almost Full Thresh. */
+	RX_GMF_CTRL_T	= 0x0c48,/* 32 bit	Rx GMAC FIFO Control/Test */
+	RX_GMF_FL_MSK	= 0x0c4c,/* 32 bit	Rx GMAC FIFO Flush Mask */
+	RX_GMF_FL_THR	= 0x0c50,/* 32 bit	Rx GMAC FIFO Flush Threshold */
+	RX_GMF_TR_THR	= 0x0c54,/* 32 bit	Rx Truncation Threshold (Yukon-2) */
+	RX_GMF_UP_THR	= 0x0c58,/*  8 bit	Rx Upper Pause Thr (Yukon-EC_U) */
+	RX_GMF_LP_THR	= 0x0c5a,/*  8 bit	Rx Lower Pause Thr (Yukon-EC_U) */
+	RX_GMF_VLAN	= 0x0c5c,/* 32 bit	Rx VLAN Type Register (Yukon-2) */
+	RX_GMF_WP	= 0x0c60,/* 32 bit	Rx GMAC FIFO Write Pointer */
+
+	RX_GMF_WLEV	= 0x0c68,/* 32 bit	Rx GMAC FIFO Write Level */
+
+	RX_GMF_RP	= 0x0c70,/* 32 bit	Rx GMAC FIFO Read Pointer */
+
+	RX_GMF_RLEV	= 0x0c78,/* 32 bit	Rx GMAC FIFO Read Level */
+};
+
+
+/*	Q_BC			32 bit	Current Byte Counter */
+
+/* BMU Control Status Registers */
+/*	B0_R1_CSR		32 bit	BMU Ctrl/Stat Rx Queue 1 */
+/*	B0_R2_CSR		32 bit	BMU Ctrl/Stat Rx Queue 2 */
+/*	B0_XA1_CSR		32 bit	BMU Ctrl/Stat Sync Tx Queue 1 */
+/*	B0_XS1_CSR		32 bit	BMU Ctrl/Stat Async Tx Queue 1 */
+/*	B0_XA2_CSR		32 bit	BMU Ctrl/Stat Sync Tx Queue 2 */
+/*	B0_XS2_CSR		32 bit	BMU Ctrl/Stat Async Tx Queue 2 */
+/*	Q_CSR			32 bit	BMU Control/Status Register */
+
+/* Rx BMU Control / Status Registers (Yukon-2) */
+enum {
+	BMU_IDLE	= 1<<31, /* BMU Idle State */
+	BMU_RX_TCP_PKT	= 1<<30, /* Rx TCP Packet (when RSS Hash enabled) */
+	BMU_RX_IP_PKT	= 1<<29, /* Rx IP  Packet (when RSS Hash enabled) */
+
+	BMU_ENA_RX_RSS_HASH = 1<<15, /* Enable  Rx RSS Hash */
+	BMU_DIS_RX_RSS_HASH = 1<<14, /* Disable Rx RSS Hash */
+	BMU_ENA_RX_CHKSUM = 1<<13, /* Enable  Rx TCP/IP Checksum Check */
+	BMU_DIS_RX_CHKSUM = 1<<12, /* Disable Rx TCP/IP Checksum Check */
+	BMU_CLR_IRQ_PAR	= 1<<11, /* Clear IRQ on Parity errors (Rx) */
+	BMU_CLR_IRQ_TCP	= 1<<11, /* Clear IRQ on TCP segment. error (Tx) */
+	BMU_CLR_IRQ_CHK	= 1<<10, /* Clear IRQ Check */
+	BMU_STOP	= 1<<9, /* Stop  Rx/Tx Queue */
+	BMU_START	= 1<<8, /* Start Rx/Tx Queue */
+	BMU_FIFO_OP_ON	= 1<<7, /* FIFO Operational On */
+	BMU_FIFO_OP_OFF	= 1<<6, /* FIFO Operational Off */
+	BMU_FIFO_ENA	= 1<<5, /* Enable FIFO */
+	BMU_FIFO_RST	= 1<<4, /* Reset  FIFO */
+	BMU_OP_ON	= 1<<3, /* BMU Operational On */
+	BMU_OP_OFF	= 1<<2, /* BMU Operational Off */
+	BMU_RST_CLR	= 1<<1, /* Clear BMU Reset (Enable) */
+	BMU_RST_SET	= 1<<0, /* Set   BMU Reset */
+
+	BMU_CLR_RESET	= BMU_FIFO_RST | BMU_OP_OFF | BMU_RST_CLR,
+	BMU_OPER_INIT	= BMU_CLR_IRQ_PAR | BMU_CLR_IRQ_CHK | BMU_START |
+			  BMU_FIFO_ENA | BMU_OP_ON,
+
+	BMU_WM_DEFAULT = 0x600,
+};
+
+/* Tx BMU Control / Status Registers (Yukon-2) */
+								/* Bit 31: same as for Rx */
+enum {
+	BMU_TX_IPIDINCR_ON	= 1<<13, /* Enable  IP ID Increment */
+	BMU_TX_IPIDINCR_OFF	= 1<<12, /* Disable IP ID Increment */
+	BMU_TX_CLR_IRQ_TCP	= 1<<11, /* Clear IRQ on TCP segment length mismatch */
+};
+
+/* Queue Prefetch Unit Offsets, use Y2_QADDR() to address (Yukon-2 only)*/
+/* PREF_UNIT_CTRL	32 bit	Prefetch Control register */
+enum {
+	PREF_UNIT_OP_ON		= 1<<3,	/* prefetch unit operational */
+	PREF_UNIT_OP_OFF	= 1<<2,	/* prefetch unit not operational */
+	PREF_UNIT_RST_CLR	= 1<<1,	/* Clear Prefetch Unit Reset */
+	PREF_UNIT_RST_SET	= 1<<0,	/* Set   Prefetch Unit Reset */
+};
+
+/* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */
+/*	RB_START		32 bit	RAM Buffer Start Address */
+/*	RB_END			32 bit	RAM Buffer End Address */
+/*	RB_WP			32 bit	RAM Buffer Write Pointer */
+/*	RB_RP			32 bit	RAM Buffer Read Pointer */
+/*	RB_RX_UTPP		32 bit	Rx Upper Threshold, Pause Pack */
+/*	RB_RX_LTPP		32 bit	Rx Lower Threshold, Pause Pack */
+/*	RB_RX_UTHP		32 bit	Rx Upper Threshold, High Prio */
+/*	RB_RX_LTHP		32 bit	Rx Lower Threshold, High Prio */
+/*	RB_PC			32 bit	RAM Buffer Packet Counter */
+/*	RB_LEV			32 bit	RAM Buffer Level Register */
+
+#define RB_MSK	0x0007ffff	/* Bit 18.. 0:	RAM Buffer Pointer Bits */
+/*	RB_TST2			 8 bit	RAM Buffer Test Register 2 */
+/*	RB_TST1			 8 bit	RAM Buffer Test Register 1 */
+
+/*	RB_CTRL			 8 bit	RAM Buffer Control Register */
+enum {
+	RB_ENA_STFWD	= 1<<5,	/* Enable  Store & Forward */
+	RB_DIS_STFWD	= 1<<4,	/* Disable Store & Forward */
+	RB_ENA_OP_MD	= 1<<3,	/* Enable  Operation Mode */
+	RB_DIS_OP_MD	= 1<<2,	/* Disable Operation Mode */
+	RB_RST_CLR	= 1<<1,	/* Clear RAM Buf STM Reset */
+	RB_RST_SET	= 1<<0,	/* Set   RAM Buf STM Reset */
+};
+
+
+/* Transmit GMAC FIFO (YUKON only) */
+enum {
+	TX_GMF_EA	= 0x0d40,/* 32 bit	Tx GMAC FIFO End Address */
+	TX_GMF_AE_THR	= 0x0d44,/* 32 bit	Tx GMAC FIFO Almost Empty Thresh.*/
+	TX_GMF_CTRL_T	= 0x0d48,/* 32 bit	Tx GMAC FIFO Control/Test */
+
+	TX_GMF_WP	= 0x0d60,/* 32 bit 	Tx GMAC FIFO Write Pointer */
+	TX_GMF_WSP	= 0x0d64,/* 32 bit 	Tx GMAC FIFO Write Shadow Ptr. */
+	TX_GMF_WLEV	= 0x0d68,/* 32 bit 	Tx GMAC FIFO Write Level */
+
+	TX_GMF_RP	= 0x0d70,/* 32 bit 	Tx GMAC FIFO Read Pointer */
+	TX_GMF_RSTP	= 0x0d74,/* 32 bit 	Tx GMAC FIFO Restart Pointer */
+	TX_GMF_RLEV	= 0x0d78,/* 32 bit 	Tx GMAC FIFO Read Level */
+};
+
+/* Descriptor Poll Timer Registers */
+enum {
+	B28_DPT_INI	= 0x0e00,/* 24 bit	Descriptor Poll Timer Init Val */
+	B28_DPT_VAL	= 0x0e04,/* 24 bit	Descriptor Poll Timer Curr Val */
+	B28_DPT_CTRL	= 0x0e08,/*  8 bit	Descriptor Poll Timer Ctrl Reg */
+
+	B28_DPT_TST	= 0x0e0a,/*  8 bit	Descriptor Poll Timer Test Reg */
+};
+
+/* Time Stamp Timer Registers (YUKON only) */
+enum {
+	GMAC_TI_ST_VAL	= 0x0e14,/* 32 bit	Time Stamp Timer Curr Val */
+	GMAC_TI_ST_CTRL	= 0x0e18,/*  8 bit	Time Stamp Timer Ctrl Reg */
+	GMAC_TI_ST_TST	= 0x0e1a,/*  8 bit	Time Stamp Timer Test Reg */
+};
+
+/* Polling Unit Registers (Yukon-2 only) */
+enum {
+	POLL_CTRL	= 0x0e20, /* 32 bit	Polling Unit Control Reg */
+	POLL_LAST_IDX	= 0x0e24,/* 16 bit	Polling Unit List Last Index */
+
+	POLL_LIST_ADDR_LO= 0x0e28,/* 32 bit	Poll. List Start Addr (low) */
+	POLL_LIST_ADDR_HI= 0x0e2c,/* 32 bit	Poll. List Start Addr (high) */
+};
+
+/* ASF Subsystem Registers (Yukon-2 only) */
+enum {
+	B28_Y2_SMB_CONFIG  = 0x0e40,/* 32 bit	ASF SMBus Config Register */
+	B28_Y2_SMB_CSD_REG = 0x0e44,/* 32 bit	ASF SMB Control/Status/Data */
+	B28_Y2_ASF_IRQ_V_BASE=0x0e60,/* 32 bit	ASF IRQ Vector Base */
+
+	B28_Y2_ASF_STAT_CMD= 0x0e68,/* 32 bit	ASF Status and Command Reg */
+	B28_Y2_ASF_HOST_COM= 0x0e6c,/* 32 bit	ASF Host Communication Reg */
+	B28_Y2_DATA_REG_1  = 0x0e70,/* 32 bit	ASF/Host Data Register 1 */
+	B28_Y2_DATA_REG_2  = 0x0e74,/* 32 bit	ASF/Host Data Register 2 */
+	B28_Y2_DATA_REG_3  = 0x0e78,/* 32 bit	ASF/Host Data Register 3 */
+	B28_Y2_DATA_REG_4  = 0x0e7c,/* 32 bit	ASF/Host Data Register 4 */
+};
+
+/* Status BMU Registers (Yukon-2 only)*/
+enum {
+	STAT_CTRL	= 0x0e80,/* 32 bit	Status BMU Control Reg */
+	STAT_LAST_IDX	= 0x0e84,/* 16 bit	Status BMU Last Index */
+
+	STAT_LIST_ADDR_LO= 0x0e88,/* 32 bit	Status List Start Addr (low) */
+	STAT_LIST_ADDR_HI= 0x0e8c,/* 32 bit	Status List Start Addr (high) */
+	STAT_TXA1_RIDX	= 0x0e90,/* 16 bit	Status TxA1 Report Index Reg */
+	STAT_TXS1_RIDX	= 0x0e92,/* 16 bit	Status TxS1 Report Index Reg */
+	STAT_TXA2_RIDX	= 0x0e94,/* 16 bit	Status TxA2 Report Index Reg */
+	STAT_TXS2_RIDX	= 0x0e96,/* 16 bit	Status TxS2 Report Index Reg */
+	STAT_TX_IDX_TH	= 0x0e98,/* 16 bit	Status Tx Index Threshold Reg */
+	STAT_PUT_IDX	= 0x0e9c,/* 16 bit	Status Put Index Reg */
+
+/* FIFO Control/Status Registers (Yukon-2 only)*/
+	STAT_FIFO_WP	= 0x0ea0,/*  8 bit	Status FIFO Write Pointer Reg */
+	STAT_FIFO_RP	= 0x0ea4,/*  8 bit	Status FIFO Read Pointer Reg */
+	STAT_FIFO_RSP	= 0x0ea6,/*  8 bit	Status FIFO Read Shadow Ptr */
+	STAT_FIFO_LEVEL	= 0x0ea8,/*  8 bit	Status FIFO Level Reg */
+	STAT_FIFO_SHLVL	= 0x0eaa,/*  8 bit	Status FIFO Shadow Level Reg */
+	STAT_FIFO_WM	= 0x0eac,/*  8 bit	Status FIFO Watermark Reg */
+	STAT_FIFO_ISR_WM= 0x0ead,/*  8 bit	Status FIFO ISR Watermark Reg */
+
+/* Level and ISR Timer Registers (Yukon-2 only)*/
+	STAT_LEV_TIMER_INI= 0x0eb0,/* 32 bit	Level Timer Init. Value Reg */
+	STAT_LEV_TIMER_CNT= 0x0eb4,/* 32 bit	Level Timer Counter Reg */
+	STAT_LEV_TIMER_CTRL= 0x0eb8,/*  8 bit	Level Timer Control Reg */
+	STAT_LEV_TIMER_TEST= 0x0eb9,/*  8 bit	Level Timer Test Reg */
+	STAT_TX_TIMER_INI  = 0x0ec0,/* 32 bit	Tx Timer Init. Value Reg */
+	STAT_TX_TIMER_CNT  = 0x0ec4,/* 32 bit	Tx Timer Counter Reg */
+	STAT_TX_TIMER_CTRL = 0x0ec8,/*  8 bit	Tx Timer Control Reg */
+	STAT_TX_TIMER_TEST = 0x0ec9,/*  8 bit	Tx Timer Test Reg */
+	STAT_ISR_TIMER_INI = 0x0ed0,/* 32 bit	ISR Timer Init. Value Reg */
+	STAT_ISR_TIMER_CNT = 0x0ed4,/* 32 bit	ISR Timer Counter Reg */
+	STAT_ISR_TIMER_CTRL= 0x0ed8,/*  8 bit	ISR Timer Control Reg */
+	STAT_ISR_TIMER_TEST= 0x0ed9,/*  8 bit	ISR Timer Test Reg */
+};
+
+enum {
+	LINKLED_OFF 	     = 0x01,
+	LINKLED_ON  	     = 0x02,
+	LINKLED_LINKSYNC_OFF = 0x04,
+	LINKLED_LINKSYNC_ON  = 0x08,
+	LINKLED_BLINK_OFF    = 0x10,
+	LINKLED_BLINK_ON     = 0x20,
+};
+
+/* GMAC and GPHY Control Registers (YUKON only) */
+enum {
+	GMAC_CTRL	= 0x0f00,/* 32 bit	GMAC Control Reg */
+	GPHY_CTRL	= 0x0f04,/* 32 bit	GPHY Control Reg */
+	GMAC_IRQ_SRC	= 0x0f08,/*  8 bit	GMAC Interrupt Source Reg */
+	GMAC_IRQ_MSK	= 0x0f0c,/*  8 bit	GMAC Interrupt Mask Reg */
+	GMAC_LINK_CTRL	= 0x0f10,/* 16 bit	Link Control Reg */
+
+/* Wake-up Frame Pattern Match Control Registers (YUKON only) */
+
+	WOL_REG_OFFS	= 0x20,/* HW-Bug: Address is + 0x20 against spec. */
+
+	WOL_CTRL_STAT	= 0x0f20,/* 16 bit	WOL Control/Status Reg */
+	WOL_MATCH_CTL	= 0x0f22,/*  8 bit	WOL Match Control Reg */
+	WOL_MATCH_RES	= 0x0f23,/*  8 bit	WOL Match Result Reg */
+	WOL_MAC_ADDR	= 0x0f24,/* 32 bit	WOL MAC Address */
+	WOL_PATT_PME	= 0x0f2a,/*  8 bit	WOL PME Match Enable (Yukon-2) */
+	WOL_PATT_ASFM	= 0x0f2b,/*  8 bit	WOL ASF Match Enable (Yukon-2) */
+	WOL_PATT_RPTR	= 0x0f2c,/*  8 bit	WOL Pattern Read Pointer */
+
+/* WOL Pattern Length Registers (YUKON only) */
+
+	WOL_PATT_LEN_LO	= 0x0f30,/* 32 bit	WOL Pattern Length 3..0 */
+	WOL_PATT_LEN_HI	= 0x0f34,/* 24 bit	WOL Pattern Length 6..4 */
+
+/* WOL Pattern Counter Registers (YUKON only) */
+
+
+	WOL_PATT_CNT_0	= 0x0f38,/* 32 bit	WOL Pattern Counter 3..0 */
+	WOL_PATT_CNT_4	= 0x0f3c,/* 24 bit	WOL Pattern Counter 6..4 */
+};
+
+enum {
+	WOL_PATT_RAM_1	= 0x1000,/*  WOL Pattern RAM Link 1 */
+	WOL_PATT_RAM_2	= 0x1400,/*  WOL Pattern RAM Link 2 */
+};
+
+enum {
+	BASE_GMAC_1	= 0x2800,/* GMAC 1 registers */
+	BASE_GMAC_2	= 0x3800,/* GMAC 2 registers */
+};
+
+/*
+ * Marvel-PHY Registers, indirect addressed over GMAC
+ */
+enum {
+	PHY_MARV_CTRL		= 0x00,/* 16 bit r/w	PHY Control Register */
+	PHY_MARV_STAT		= 0x01,/* 16 bit r/o	PHY Status Register */
+	PHY_MARV_ID0		= 0x02,/* 16 bit r/o	PHY ID0 Register */
+	PHY_MARV_ID1		= 0x03,/* 16 bit r/o	PHY ID1 Register */
+	PHY_MARV_AUNE_ADV	= 0x04,/* 16 bit r/w	Auto-Neg. Advertisement */
+	PHY_MARV_AUNE_LP	= 0x05,/* 16 bit r/o	Link Part Ability Reg */
+	PHY_MARV_AUNE_EXP	= 0x06,/* 16 bit r/o	Auto-Neg. Expansion Reg */
+	PHY_MARV_NEPG		= 0x07,/* 16 bit r/w	Next Page Register */
+	PHY_MARV_NEPG_LP	= 0x08,/* 16 bit r/o	Next Page Link Partner */
+	/* Marvel-specific registers */
+	PHY_MARV_1000T_CTRL	= 0x09,/* 16 bit r/w	1000Base-T Control Reg */
+	PHY_MARV_1000T_STAT	= 0x0a,/* 16 bit r/o	1000Base-T Status Reg */
+	PHY_MARV_EXT_STAT	= 0x0f,/* 16 bit r/o	Extended Status Reg */
+	PHY_MARV_PHY_CTRL	= 0x10,/* 16 bit r/w	PHY Specific Ctrl Reg */
+	PHY_MARV_PHY_STAT	= 0x11,/* 16 bit r/o	PHY Specific Stat Reg */
+	PHY_MARV_INT_MASK	= 0x12,/* 16 bit r/w	Interrupt Mask Reg */
+	PHY_MARV_INT_STAT	= 0x13,/* 16 bit r/o	Interrupt Status Reg */
+	PHY_MARV_EXT_CTRL	= 0x14,/* 16 bit r/w	Ext. PHY Specific Ctrl */
+	PHY_MARV_RXE_CNT	= 0x15,/* 16 bit r/w	Receive Error Counter */
+	PHY_MARV_EXT_ADR	= 0x16,/* 16 bit r/w	Ext. Ad. for Cable Diag. */
+	PHY_MARV_PORT_IRQ	= 0x17,/* 16 bit r/o	Port 0 IRQ (88E1111 only) */
+	PHY_MARV_LED_CTRL	= 0x18,/* 16 bit r/w	LED Control Reg */
+	PHY_MARV_LED_OVER	= 0x19,/* 16 bit r/w	Manual LED Override Reg */
+	PHY_MARV_EXT_CTRL_2	= 0x1a,/* 16 bit r/w	Ext. PHY Specific Ctrl 2 */
+	PHY_MARV_EXT_P_STAT	= 0x1b,/* 16 bit r/w	Ext. PHY Spec. Stat Reg */
+	PHY_MARV_CABLE_DIAG	= 0x1c,/* 16 bit r/o	Cable Diagnostic Reg */
+	PHY_MARV_PAGE_ADDR	= 0x1d,/* 16 bit r/w	Extended Page Address Reg */
+	PHY_MARV_PAGE_DATA	= 0x1e,/* 16 bit r/w	Extended Page Data Reg */
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+	PHY_MARV_FE_LED_PAR	= 0x16,/* 16 bit r/w	LED Parallel Select Reg. */
+	PHY_MARV_FE_LED_SER	= 0x17,/* 16 bit r/w	LED Stream Select S. LED */
+	PHY_MARV_FE_VCT_TX	= 0x1a,/* 16 bit r/w	VCT Reg. for TXP/N Pins */
+	PHY_MARV_FE_VCT_RX	= 0x1b,/* 16 bit r/o	VCT Reg. for RXP/N Pins */
+	PHY_MARV_FE_SPEC_2	= 0x1c,/* 16 bit r/w	Specific Control Reg. 2 */
+};
+
+enum {
+	PHY_CT_RESET	= 1<<15, /* Bit 15: (sc)	clear all PHY related regs */
+	PHY_CT_LOOP	= 1<<14, /* Bit 14:	enable Loopback over PHY */
+	PHY_CT_SPS_LSB	= 1<<13, /* Bit 13:	Speed select, lower bit */
+	PHY_CT_ANE	= 1<<12, /* Bit 12:	Auto-Negotiation Enabled */
+	PHY_CT_PDOWN	= 1<<11, /* Bit 11:	Power Down Mode */
+	PHY_CT_ISOL	= 1<<10, /* Bit 10:	Isolate Mode */
+	PHY_CT_RE_CFG	= 1<<9, /* Bit  9:	(sc) Restart Auto-Negotiation */
+	PHY_CT_DUP_MD	= 1<<8, /* Bit  8:	Duplex Mode */
+	PHY_CT_COL_TST	= 1<<7, /* Bit  7:	Collision Test enabled */
+	PHY_CT_SPS_MSB	= 1<<6, /* Bit  6:	Speed select, upper bit */
+};
+
+enum {
+	PHY_CT_SP1000	= PHY_CT_SPS_MSB, /* enable speed of 1000 Mbps */
+	PHY_CT_SP100	= PHY_CT_SPS_LSB, /* enable speed of  100 Mbps */
+	PHY_CT_SP10	= 0,		  /* enable speed of   10 Mbps */
+};
+
+enum {
+	PHY_ST_EXT_ST	= 1<<8, /* Bit  8:	Extended Status Present */
+
+	PHY_ST_PRE_SUP	= 1<<6, /* Bit  6:	Preamble Suppression */
+	PHY_ST_AN_OVER	= 1<<5, /* Bit  5:	Auto-Negotiation Over */
+	PHY_ST_REM_FLT	= 1<<4, /* Bit  4:	Remote Fault Condition Occured */
+	PHY_ST_AN_CAP	= 1<<3, /* Bit  3:	Auto-Negotiation Capability */
+	PHY_ST_LSYNC	= 1<<2, /* Bit  2:	Link Synchronized */
+	PHY_ST_JAB_DET	= 1<<1, /* Bit  1:	Jabber Detected */
+	PHY_ST_EXT_REG	= 1<<0, /* Bit  0:	Extended Register available */
+};
+
+enum {
+	PHY_I1_OUI_MSK	= 0x3f<<10, /* Bit 15..10:	Organization Unique ID */
+	PHY_I1_MOD_NUM	= 0x3f<<4, /* Bit  9.. 4:	Model Number */
+	PHY_I1_REV_MSK	= 0xf, /* Bit  3.. 0:	Revision Number */
+};
+
+/* different Marvell PHY Ids */
+enum {
+	PHY_MARV_ID0_VAL= 0x0141, /* Marvell Unique Identifier */
+
+	PHY_BCOM_ID1_A1	= 0x6041,
+	PHY_BCOM_ID1_B2	= 0x6043,
+	PHY_BCOM_ID1_C0	= 0x6044,
+	PHY_BCOM_ID1_C5	= 0x6047,
+
+	PHY_MARV_ID1_B0	= 0x0C23, /* Yukon (PHY 88E1011) */
+	PHY_MARV_ID1_B2	= 0x0C25, /* Yukon-Plus (PHY 88E1011) */
+	PHY_MARV_ID1_C2	= 0x0CC2, /* Yukon-EC (PHY 88E1111) */
+	PHY_MARV_ID1_Y2	= 0x0C91, /* Yukon-2 (PHY 88E1112) */
+};
+
+/* Advertisement register bits */
+enum {
+	PHY_AN_NXT_PG	= 1<<15, /* Bit 15:	Request Next Page */
+	PHY_AN_ACK	= 1<<14, /* Bit 14:	(ro) Acknowledge Received */
+	PHY_AN_RF	= 1<<13, /* Bit 13:	Remote Fault Bits */
+
+	PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11:	Try for asymmetric */
+	PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10:	Try for pause */
+	PHY_AN_100BASE4	= 1<<9, /* Bit 9:	Try for 100mbps 4k packets */
+	PHY_AN_100FULL	= 1<<8, /* Bit 8:	Try for 100mbps full-duplex */
+	PHY_AN_100HALF	= 1<<7, /* Bit 7:	Try for 100mbps half-duplex */
+	PHY_AN_10FULL	= 1<<6, /* Bit 6:	Try for 10mbps full-duplex */
+	PHY_AN_10HALF	= 1<<5, /* Bit 5:	Try for 10mbps half-duplex */
+	PHY_AN_CSMA	= 1<<0, /* Bit 0:	Only selector supported */
+	PHY_AN_SEL	= 0x1f, /* Bit 4..0:	Selector Field, 00001=Ethernet*/
+	PHY_AN_FULL	= PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA,
+	PHY_AN_ALL	= PHY_AN_10HALF | PHY_AN_10FULL |
+		  	  PHY_AN_100HALF | PHY_AN_100FULL,
+};
+
+/*****  PHY_BCOM_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
+/*****  PHY_MARV_1000T_STAT	16 bit r/o	1000Base-T Status Reg *****/
+enum {
+	PHY_B_1000S_MSF	= 1<<15, /* Bit 15:	Master/Slave Fault */
+	PHY_B_1000S_MSR	= 1<<14, /* Bit 14:	Master/Slave Result */
+	PHY_B_1000S_LRS	= 1<<13, /* Bit 13:	Local Receiver Status */
+	PHY_B_1000S_RRS	= 1<<12, /* Bit 12:	Remote Receiver Status */
+	PHY_B_1000S_LP_FD	= 1<<11, /* Bit 11:	Link Partner can FD */
+	PHY_B_1000S_LP_HD	= 1<<10, /* Bit 10:	Link Partner can HD */
+									/* Bit  9..8:	reserved */
+	PHY_B_1000S_IEC	= 0xff, /* Bit  7..0:	Idle Error Count */
+};
+
+/** Marvell-Specific */
+enum {
+	PHY_M_AN_NXT_PG	= 1<<15, /* Request Next Page */
+	PHY_M_AN_ACK	= 1<<14, /* (ro)	Acknowledge Received */
+	PHY_M_AN_RF	= 1<<13, /* Remote Fault */
+
+	PHY_M_AN_ASP	= 1<<11, /* Asymmetric Pause */
+	PHY_M_AN_PC	= 1<<10, /* MAC Pause implemented */
+	PHY_M_AN_100_T4	= 1<<9, /* Not cap. 100Base-T4 (always 0) */
+	PHY_M_AN_100_FD	= 1<<8, /* Advertise 100Base-TX Full Duplex */
+	PHY_M_AN_100_HD	= 1<<7, /* Advertise 100Base-TX Half Duplex */
+	PHY_M_AN_10_FD	= 1<<6, /* Advertise 10Base-TX Full Duplex */
+	PHY_M_AN_10_HD	= 1<<5, /* Advertise 10Base-TX Half Duplex */
+	PHY_M_AN_SEL_MSK =0x1f<<4,	/* Bit  4.. 0: Selector Field Mask */
+};
+
+/* special defines for FIBER (88E1011S only) */
+enum {
+	PHY_M_AN_ASP_X	= 1<<8, /* Asymmetric Pause */
+	PHY_M_AN_PC_X	= 1<<7, /* MAC Pause implemented */
+	PHY_M_AN_1000X_AHD	= 1<<6, /* Advertise 10000Base-X Half Duplex */
+	PHY_M_AN_1000X_AFD	= 1<<5, /* Advertise 10000Base-X Full Duplex */
+};
+
+/* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */
+enum {
+	PHY_M_P_NO_PAUSE_X	= 0<<7,/* Bit  8.. 7:	no Pause Mode */
+	PHY_M_P_SYM_MD_X	= 1<<7, /* Bit  8.. 7:	symmetric Pause Mode */
+	PHY_M_P_ASYM_MD_X	= 2<<7,/* Bit  8.. 7:	asymmetric Pause Mode */
+	PHY_M_P_BOTH_MD_X	= 3<<7,/* Bit  8.. 7:	both Pause Mode */
+};
+
+/*****  PHY_MARV_1000T_CTRL	16 bit r/w	1000Base-T Control Reg *****/
+enum {
+	PHY_M_1000C_TEST	= 7<<13,/* Bit 15..13:	Test Modes */
+	PHY_M_1000C_MSE	= 1<<12, /* Manual Master/Slave Enable */
+	PHY_M_1000C_MSC	= 1<<11, /* M/S Configuration (1=Master) */
+	PHY_M_1000C_MPD	= 1<<10, /* Multi-Port Device */
+	PHY_M_1000C_AFD	= 1<<9, /* Advertise Full Duplex */
+	PHY_M_1000C_AHD	= 1<<8, /* Advertise Half Duplex */
+};
+
+/*****  PHY_MARV_PHY_CTRL	16 bit r/w	PHY Specific Ctrl Reg *****/
+enum {
+	PHY_M_PC_TX_FFD_MSK	= 3<<14,/* Bit 15..14: Tx FIFO Depth Mask */
+	PHY_M_PC_RX_FFD_MSK	= 3<<12,/* Bit 13..12: Rx FIFO Depth Mask */
+	PHY_M_PC_ASS_CRS_TX	= 1<<11, /* Assert CRS on Transmit */
+	PHY_M_PC_FL_GOOD	= 1<<10, /* Force Link Good */
+	PHY_M_PC_EN_DET_MSK	= 3<<8,/* Bit  9.. 8: Energy Detect Mask */
+	PHY_M_PC_ENA_EXT_D	= 1<<7, /* Enable Ext. Distance (10BT) */
+	PHY_M_PC_MDIX_MSK	= 3<<5,/* Bit  6.. 5: MDI/MDIX Config. Mask */
+	PHY_M_PC_DIS_125CLK	= 1<<4, /* Disable 125 CLK */
+	PHY_M_PC_MAC_POW_UP	= 1<<3, /* MAC Power up */
+	PHY_M_PC_SQE_T_ENA	= 1<<2, /* SQE Test Enabled */
+	PHY_M_PC_POL_R_DIS	= 1<<1, /* Polarity Reversal Disabled */
+	PHY_M_PC_DIS_JABBER	= 1<<0, /* Disable Jabber */
+};
+
+enum {
+	PHY_M_PC_EN_DET		= 2<<8,	/* Energy Detect (Mode 1) */
+	PHY_M_PC_EN_DET_PLUS	= 3<<8, /* Energy Detect Plus (Mode 2) */
+};
+
+#define PHY_M_PC_MDI_XMODE(x)	(((x)<<5) & PHY_M_PC_MDIX_MSK)
+
+enum {
+	PHY_M_PC_MAN_MDI	= 0, /* 00 = Manual MDI configuration */
+	PHY_M_PC_MAN_MDIX	= 1, /* 01 = Manual MDIX configuration */
+	PHY_M_PC_ENA_AUTO	= 3, /* 11 = Enable Automatic Crossover */
+};
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+enum {
+	PHY_M_PC_ENA_DTE_DT	= 1<<15, /* Enable Data Terminal Equ. (DTE) Detect */
+	PHY_M_PC_ENA_ENE_DT	= 1<<14, /* Enable Energy Detect (sense & pulse) */
+	PHY_M_PC_DIS_NLP_CK	= 1<<13, /* Disable Normal Link Puls (NLP) Check */
+	PHY_M_PC_ENA_LIP_NP	= 1<<12, /* Enable Link Partner Next Page Reg. */
+	PHY_M_PC_DIS_NLP_GN	= 1<<11, /* Disable Normal Link Puls Generation */
+
+	PHY_M_PC_DIS_SCRAMB	= 1<<9, /* Disable Scrambler */
+	PHY_M_PC_DIS_FEFI	= 1<<8, /* Disable Far End Fault Indic. (FEFI) */
+
+	PHY_M_PC_SH_TP_SEL	= 1<<6, /* Shielded Twisted Pair Select */
+	PHY_M_PC_RX_FD_MSK	= 3<<2,/* Bit  3.. 2: Rx FIFO Depth Mask */
+};
+
+/*****  PHY_MARV_PHY_STAT	16 bit r/o	PHY Specific Status Reg *****/
+enum {
+	PHY_M_PS_SPEED_MSK	= 3<<14, /* Bit 15..14: Speed Mask */
+	PHY_M_PS_SPEED_1000	= 1<<15, /*		10 = 1000 Mbps */
+	PHY_M_PS_SPEED_100	= 1<<14, /*		01 =  100 Mbps */
+	PHY_M_PS_SPEED_10	= 0,	 /*		00 =   10 Mbps */
+	PHY_M_PS_FULL_DUP	= 1<<13, /* Full Duplex */
+	PHY_M_PS_PAGE_REC	= 1<<12, /* Page Received */
+	PHY_M_PS_SPDUP_RES	= 1<<11, /* Speed & Duplex Resolved */
+	PHY_M_PS_LINK_UP	= 1<<10, /* Link Up */
+	PHY_M_PS_CABLE_MSK	= 7<<7,  /* Bit  9.. 7: Cable Length Mask */
+	PHY_M_PS_MDI_X_STAT	= 1<<6,  /* MDI Crossover Stat (1=MDIX) */
+	PHY_M_PS_DOWNS_STAT	= 1<<5,  /* Downshift Status (1=downsh.) */
+	PHY_M_PS_ENDET_STAT	= 1<<4,  /* Energy Detect Status (1=act) */
+	PHY_M_PS_TX_P_EN	= 1<<3,  /* Tx Pause Enabled */
+	PHY_M_PS_RX_P_EN	= 1<<2,  /* Rx Pause Enabled */
+	PHY_M_PS_POL_REV	= 1<<1,  /* Polarity Reversed */
+	PHY_M_PS_JABBER		= 1<<0,  /* Jabber */
+};
+
+#define PHY_M_PS_PAUSE_MSK	(PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN)
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+enum {
+	PHY_M_PS_DTE_DETECT	= 1<<15, /* Data Terminal Equipment (DTE) Detected */
+	PHY_M_PS_RES_SPEED	= 1<<14, /* Resolved Speed (1=100 Mbps, 0=10 Mbps */
+};
+
+enum {
+	PHY_M_IS_AN_ERROR	= 1<<15, /* Auto-Negotiation Error */
+	PHY_M_IS_LSP_CHANGE	= 1<<14, /* Link Speed Changed */
+	PHY_M_IS_DUP_CHANGE	= 1<<13, /* Duplex Mode Changed */
+	PHY_M_IS_AN_PR		= 1<<12, /* Page Received */
+	PHY_M_IS_AN_COMPL	= 1<<11, /* Auto-Negotiation Completed */
+	PHY_M_IS_LST_CHANGE	= 1<<10, /* Link Status Changed */
+	PHY_M_IS_SYMB_ERROR	= 1<<9, /* Symbol Error */
+	PHY_M_IS_FALSE_CARR	= 1<<8, /* False Carrier */
+	PHY_M_IS_FIFO_ERROR	= 1<<7, /* FIFO Overflow/Underrun Error */
+	PHY_M_IS_MDI_CHANGE	= 1<<6, /* MDI Crossover Changed */
+	PHY_M_IS_DOWNSH_DET	= 1<<5, /* Downshift Detected */
+	PHY_M_IS_END_CHANGE	= 1<<4, /* Energy Detect Changed */
+
+	PHY_M_IS_DTE_CHANGE	= 1<<2, /* DTE Power Det. Status Changed */
+	PHY_M_IS_POL_CHANGE	= 1<<1, /* Polarity Changed */
+	PHY_M_IS_JABBER		= 1<<0, /* Jabber */
+
+	PHY_M_DEF_MSK		= PHY_M_IS_LSP_CHANGE | PHY_M_IS_LST_CHANGE
+				 | PHY_M_IS_FIFO_ERROR,
+	PHY_M_AN_MSK	       = PHY_M_IS_AN_ERROR | PHY_M_IS_AN_COMPL,
+};
+
+
+/*****  PHY_MARV_EXT_CTRL	16 bit r/w	Ext. PHY Specific Ctrl *****/
+enum {
+	PHY_M_EC_ENA_BC_EXT = 1<<15, /* Enable Block Carr. Ext. (88E1111 only) */
+	PHY_M_EC_ENA_LIN_LB = 1<<14, /* Enable Line Loopback (88E1111 only) */
+
+	PHY_M_EC_DIS_LINK_P = 1<<12, /* Disable Link Pulses (88E1111 only) */
+	PHY_M_EC_M_DSC_MSK  = 3<<10, /* Bit 11..10:	Master Downshift Counter */
+					/* (88E1011 only) */
+	PHY_M_EC_S_DSC_MSK  = 3<<8,/* Bit  9.. 8:	Slave  Downshift Counter */
+				       /* (88E1011 only) */
+	PHY_M_EC_M_DSC_MSK2 = 7<<9,/* Bit 11.. 9:	Master Downshift Counter */
+					/* (88E1111 only) */
+	PHY_M_EC_DOWN_S_ENA = 1<<8, /* Downshift Enable (88E1111 only) */
+					/* !!! Errata in spec. (1 = disable) */
+	PHY_M_EC_RX_TIM_CT  = 1<<7, /* RGMII Rx Timing Control*/
+	PHY_M_EC_MAC_S_MSK  = 7<<4,/* Bit  6.. 4:	Def. MAC interface speed */
+	PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */
+	PHY_M_EC_DTE_D_ENA  = 1<<2, /* DTE Detect Enable (88E1111 only) */
+	PHY_M_EC_TX_TIM_CT  = 1<<1, /* RGMII Tx Timing Control */
+	PHY_M_EC_TRANS_DIS  = 1<<0, /* Transmitter Disable (88E1111 only) */};
+
+#define PHY_M_EC_M_DSC(x)	((x)<<10 & PHY_M_EC_M_DSC_MSK)
+					/* 00=1x; 01=2x; 10=3x; 11=4x */
+#define PHY_M_EC_S_DSC(x)	((x)<<8 & PHY_M_EC_S_DSC_MSK)
+					/* 00=dis; 01=1x; 10=2x; 11=3x */
+#define PHY_M_EC_DSC_2(x)	((x)<<9 & PHY_M_EC_M_DSC_MSK2)
+					/* 000=1x; 001=2x; 010=3x; 011=4x */
+#define PHY_M_EC_MAC_S(x)	((x)<<4 & PHY_M_EC_MAC_S_MSK)
+					/* 01X=0; 110=2.5; 111=25 (MHz) */
+
+/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
+enum {
+	PHY_M_PC_DIS_LINK_Pa	= 1<<15,/* Disable Link Pulses */
+	PHY_M_PC_DSC_MSK	= 7<<12,/* Bit 14..12:	Downshift Counter */
+	PHY_M_PC_DOWN_S_ENA	= 1<<11,/* Downshift Enable */
+};
+/* !!! Errata in spec. (1 = disable) */
+
+#define PHY_M_PC_DSC(x)			(((x)<<12) & PHY_M_PC_DSC_MSK)
+											/* 100=5x; 101=6x; 110=7x; 111=8x */
+enum {
+	MAC_TX_CLK_0_MHZ	= 2,
+	MAC_TX_CLK_2_5_MHZ	= 6,
+	MAC_TX_CLK_25_MHZ 	= 7,
+};
+
+/*****  PHY_MARV_LED_CTRL	16 bit r/w	LED Control Reg *****/
+enum {
+	PHY_M_LEDC_DIS_LED	= 1<<15, /* Disable LED */
+	PHY_M_LEDC_PULS_MSK	= 7<<12,/* Bit 14..12: Pulse Stretch Mask */
+	PHY_M_LEDC_F_INT	= 1<<11, /* Force Interrupt */
+	PHY_M_LEDC_BL_R_MSK	= 7<<8,/* Bit 10.. 8: Blink Rate Mask */
+	PHY_M_LEDC_DP_C_LSB	= 1<<7, /* Duplex Control (LSB, 88E1111 only) */
+	PHY_M_LEDC_TX_C_LSB	= 1<<6, /* Tx Control (LSB, 88E1111 only) */
+	PHY_M_LEDC_LK_C_MSK	= 7<<3,/* Bit  5.. 3: Link Control Mask */
+					/* (88E1111 only) */
+};
+
+enum {
+	PHY_M_LEDC_LINK_MSK	= 3<<3,/* Bit  4.. 3: Link Control Mask */
+									/* (88E1011 only) */
+	PHY_M_LEDC_DP_CTRL	= 1<<2, /* Duplex Control */
+	PHY_M_LEDC_DP_C_MSB	= 1<<2, /* Duplex Control (MSB, 88E1111 only) */
+	PHY_M_LEDC_RX_CTRL	= 1<<1, /* Rx Activity / Link */
+	PHY_M_LEDC_TX_CTRL	= 1<<0, /* Tx Activity / Link */
+	PHY_M_LEDC_TX_C_MSB	= 1<<0, /* Tx Control (MSB, 88E1111 only) */
+};
+
+#define PHY_M_LED_PULS_DUR(x)	(((x)<<12) & PHY_M_LEDC_PULS_MSK)
+
+/*****  PHY_MARV_PHY_STAT (page 3)16 bit r/w	Polarity Control Reg. *****/
+enum {
+	PHY_M_POLC_LS1M_MSK	= 0xf<<12, /* Bit 15..12: LOS,STAT1 Mix % Mask */
+	PHY_M_POLC_IS0M_MSK	= 0xf<<8,  /* Bit 11.. 8: INIT,STAT0 Mix % Mask */
+	PHY_M_POLC_LOS_MSK	= 0x3<<6,  /* Bit  7.. 6: LOS Pol. Ctrl. Mask */
+	PHY_M_POLC_INIT_MSK	= 0x3<<4,  /* Bit  5.. 4: INIT Pol. Ctrl. Mask */
+	PHY_M_POLC_STA1_MSK	= 0x3<<2,  /* Bit  3.. 2: STAT1 Pol. Ctrl. Mask */
+	PHY_M_POLC_STA0_MSK	= 0x3,     /* Bit  1.. 0: STAT0 Pol. Ctrl. Mask */
+};
+
+#define PHY_M_POLC_LS1_P_MIX(x)	(((x)<<12) & PHY_M_POLC_LS1M_MSK)
+#define PHY_M_POLC_IS0_P_MIX(x)	(((x)<<8) & PHY_M_POLC_IS0M_MSK)
+#define PHY_M_POLC_LOS_CTRL(x)	(((x)<<6) & PHY_M_POLC_LOS_MSK)
+#define PHY_M_POLC_INIT_CTRL(x)	(((x)<<4) & PHY_M_POLC_INIT_MSK)
+#define PHY_M_POLC_STA1_CTRL(x)	(((x)<<2) & PHY_M_POLC_STA1_MSK)
+#define PHY_M_POLC_STA0_CTRL(x)	(((x)<<0) & PHY_M_POLC_STA0_MSK)
+
+enum {
+	PULS_NO_STR	= 0,/* no pulse stretching */
+	PULS_21MS	= 1,/* 21 ms to 42 ms */
+	PULS_42MS	= 2,/* 42 ms to 84 ms */
+	PULS_84MS	= 3,/* 84 ms to 170 ms */
+	PULS_170MS	= 4,/* 170 ms to 340 ms */
+	PULS_340MS	= 5,/* 340 ms to 670 ms */
+	PULS_670MS	= 6,/* 670 ms to 1.3 s */
+	PULS_1300MS	= 7,/* 1.3 s to 2.7 s */
+};
+
+#define PHY_M_LED_BLINK_RT(x)	(((x)<<8) & PHY_M_LEDC_BL_R_MSK)
+
+enum {
+	BLINK_42MS	= 0,/* 42 ms */
+	BLINK_84MS	= 1,/* 84 ms */
+	BLINK_170MS	= 2,/* 170 ms */
+	BLINK_340MS	= 3,/* 340 ms */
+	BLINK_670MS	= 4,/* 670 ms */
+};
+
+/*****  PHY_MARV_LED_OVER	16 bit r/w	Manual LED Override Reg *****/
+#define PHY_M_LED_MO_SGMII(x)	((x)<<14) /* Bit 15..14:  SGMII AN Timer */
+										/* Bit 13..12:	reserved */
+#define PHY_M_LED_MO_DUP(x)	((x)<<10) /* Bit 11..10:  Duplex */
+#define PHY_M_LED_MO_10(x)	((x)<<8) /* Bit  9.. 8:  Link 10 */
+#define PHY_M_LED_MO_100(x)	((x)<<6) /* Bit  7.. 6:  Link 100 */
+#define PHY_M_LED_MO_1000(x)	((x)<<4) /* Bit  5.. 4:  Link 1000 */
+#define PHY_M_LED_MO_RX(x)	((x)<<2) /* Bit  3.. 2:  Rx */
+#define PHY_M_LED_MO_TX(x)	((x)<<0) /* Bit  1.. 0:  Tx */
+
+enum {
+	MO_LED_NORM	= 0,
+	MO_LED_BLINK	= 1,
+	MO_LED_OFF	= 2,
+	MO_LED_ON	= 3,
+};
+
+/*****  PHY_MARV_EXT_CTRL_2	16 bit r/w	Ext. PHY Specific Ctrl 2 *****/
+enum {
+	PHY_M_EC2_FI_IMPED	= 1<<6, /* Fiber Input  Impedance */
+	PHY_M_EC2_FO_IMPED	= 1<<5, /* Fiber Output Impedance */
+	PHY_M_EC2_FO_M_CLK	= 1<<4, /* Fiber Mode Clock Enable */
+	PHY_M_EC2_FO_BOOST	= 1<<3, /* Fiber Output Boost */
+	PHY_M_EC2_FO_AM_MSK	= 7,/* Bit  2.. 0:	Fiber Output Amplitude */
+};
+
+/*****  PHY_MARV_EXT_P_STAT 16 bit r/w	Ext. PHY Specific Status *****/
+enum {
+	PHY_M_FC_AUTO_SEL	= 1<<15, /* Fiber/Copper Auto Sel. Dis. */
+	PHY_M_FC_AN_REG_ACC	= 1<<14, /* Fiber/Copper AN Reg. Access */
+	PHY_M_FC_RESOLUTION	= 1<<13, /* Fiber/Copper Resolution */
+	PHY_M_SER_IF_AN_BP	= 1<<12, /* Ser. IF AN Bypass Enable */
+	PHY_M_SER_IF_BP_ST	= 1<<11, /* Ser. IF AN Bypass Status */
+	PHY_M_IRQ_POLARITY	= 1<<10, /* IRQ polarity */
+	PHY_M_DIS_AUT_MED	= 1<<9, /* Disable Aut. Medium Reg. Selection */
+	/* (88E1111 only) */
+
+	PHY_M_UNDOC1		= 1<<7, /* undocumented bit !! */
+	PHY_M_DTE_POW_STAT	= 1<<4, /* DTE Power Status (88E1111 only) */
+	PHY_M_MODE_MASK	= 0xf, /* Bit  3.. 0: copy of HWCFG MODE[3:0] */
+};
+
+/* for 10/100 Fast Ethernet PHY (88E3082 only) */
+/*****  PHY_MARV_FE_LED_PAR		16 bit r/w	LED Parallel Select Reg. *****/
+									/* Bit 15..12: reserved (used internally) */
+enum {
+	PHY_M_FELP_LED2_MSK = 0xf<<8,	/* Bit 11.. 8: LED2 Mask (LINK) */
+	PHY_M_FELP_LED1_MSK = 0xf<<4,	/* Bit  7.. 4: LED1 Mask (ACT) */
+	PHY_M_FELP_LED0_MSK = 0xf, /* Bit  3.. 0: LED0 Mask (SPEED) */
+};
+
+#define PHY_M_FELP_LED2_CTRL(x)	(((x)<<8) & PHY_M_FELP_LED2_MSK)
+#define PHY_M_FELP_LED1_CTRL(x)	(((x)<<4) & PHY_M_FELP_LED1_MSK)
+#define PHY_M_FELP_LED0_CTRL(x)	(((x)<<0) & PHY_M_FELP_LED0_MSK)
+
+enum {
+	LED_PAR_CTRL_COLX	= 0x00,
+	LED_PAR_CTRL_ERROR	= 0x01,
+	LED_PAR_CTRL_DUPLEX	= 0x02,
+	LED_PAR_CTRL_DP_COL	= 0x03,
+	LED_PAR_CTRL_SPEED	= 0x04,
+	LED_PAR_CTRL_LINK	= 0x05,
+	LED_PAR_CTRL_TX		= 0x06,
+	LED_PAR_CTRL_RX		= 0x07,
+	LED_PAR_CTRL_ACT	= 0x08,
+	LED_PAR_CTRL_LNK_RX	= 0x09,
+	LED_PAR_CTRL_LNK_AC	= 0x0a,
+	LED_PAR_CTRL_ACT_BL	= 0x0b,
+	LED_PAR_CTRL_TX_BL	= 0x0c,
+	LED_PAR_CTRL_RX_BL	= 0x0d,
+	LED_PAR_CTRL_COL_BL	= 0x0e,
+	LED_PAR_CTRL_INACT	= 0x0f
+};
+
+/*****,PHY_MARV_FE_SPEC_2		16 bit r/w	Specific Control Reg. 2 *****/
+enum {
+	PHY_M_FESC_DIS_WAIT	= 1<<2, /* Disable TDR Waiting Period */
+	PHY_M_FESC_ENA_MCLK	= 1<<1, /* Enable MAC Rx Clock in sleep mode */
+	PHY_M_FESC_SEL_CL_A	= 1<<0, /* Select Class A driver (100B-TX) */
+};
+
+/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */
+/*****  PHY_MARV_PHY_CTRL (page 2)		16 bit r/w	MAC Specific Ctrl *****/
+enum {
+	PHY_M_MAC_MD_MSK	= 7<<7, /* Bit  9.. 7: Mode Select Mask */
+	PHY_M_MAC_MD_AUTO	= 3,/* Auto Copper/1000Base-X */
+	PHY_M_MAC_MD_COPPER	= 5,/* Copper only */
+	PHY_M_MAC_MD_1000BX	= 7,/* 1000Base-X only */
+};
+#define PHY_M_MAC_MODE_SEL(x)	(((x)<<7) & PHY_M_MAC_MD_MSK)
+
+/*****  PHY_MARV_PHY_CTRL (page 3)		16 bit r/w	LED Control Reg. *****/
+enum {
+	PHY_M_LEDC_LOS_MSK	= 0xf<<12,/* Bit 15..12: LOS LED Ctrl. Mask */
+	PHY_M_LEDC_INIT_MSK	= 0xf<<8, /* Bit 11.. 8: INIT LED Ctrl. Mask */
+	PHY_M_LEDC_STA1_MSK	= 0xf<<4,/* Bit  7.. 4: STAT1 LED Ctrl. Mask */
+	PHY_M_LEDC_STA0_MSK	= 0xf, /* Bit  3.. 0: STAT0 LED Ctrl. Mask */
+};
+
+#define PHY_M_LEDC_LOS_CTRL(x)	(((x)<<12) & PHY_M_LEDC_LOS_MSK)
+#define PHY_M_LEDC_INIT_CTRL(x)	(((x)<<8) & PHY_M_LEDC_INIT_MSK)
+#define PHY_M_LEDC_STA1_CTRL(x)	(((x)<<4) & PHY_M_LEDC_STA1_MSK)
+#define PHY_M_LEDC_STA0_CTRL(x)	(((x)<<0) & PHY_M_LEDC_STA0_MSK)
+
+/* GMAC registers  */
+/* Port Registers */
+enum {
+	GM_GP_STAT	= 0x0000,	/* 16 bit r/o	General Purpose Status */
+	GM_GP_CTRL	= 0x0004,	/* 16 bit r/w	General Purpose Control */
+	GM_TX_CTRL	= 0x0008,	/* 16 bit r/w	Transmit Control Reg. */
+	GM_RX_CTRL	= 0x000c,	/* 16 bit r/w	Receive Control Reg. */
+	GM_TX_FLOW_CTRL	= 0x0010,	/* 16 bit r/w	Transmit Flow-Control */
+	GM_TX_PARAM	= 0x0014,	/* 16 bit r/w	Transmit Parameter Reg. */
+	GM_SERIAL_MODE	= 0x0018,	/* 16 bit r/w	Serial Mode Register */
+/* Source Address Registers */
+	GM_SRC_ADDR_1L	= 0x001c,	/* 16 bit r/w	Source Address 1 (low) */
+	GM_SRC_ADDR_1M	= 0x0020,	/* 16 bit r/w	Source Address 1 (middle) */
+	GM_SRC_ADDR_1H	= 0x0024,	/* 16 bit r/w	Source Address 1 (high) */
+	GM_SRC_ADDR_2L	= 0x0028,	/* 16 bit r/w	Source Address 2 (low) */
+	GM_SRC_ADDR_2M	= 0x002c,	/* 16 bit r/w	Source Address 2 (middle) */
+	GM_SRC_ADDR_2H	= 0x0030,	/* 16 bit r/w	Source Address 2 (high) */
+
+/* Multicast Address Hash Registers */
+	GM_MC_ADDR_H1	= 0x0034,	/* 16 bit r/w	Multicast Address Hash 1 */
+	GM_MC_ADDR_H2	= 0x0038,	/* 16 bit r/w	Multicast Address Hash 2 */
+	GM_MC_ADDR_H3	= 0x003c,	/* 16 bit r/w	Multicast Address Hash 3 */
+	GM_MC_ADDR_H4	= 0x0040,	/* 16 bit r/w	Multicast Address Hash 4 */
+
+/* Interrupt Source Registers */
+	GM_TX_IRQ_SRC	= 0x0044,	/* 16 bit r/o	Tx Overflow IRQ Source */
+	GM_RX_IRQ_SRC	= 0x0048,	/* 16 bit r/o	Rx Overflow IRQ Source */
+	GM_TR_IRQ_SRC	= 0x004c,	/* 16 bit r/o	Tx/Rx Over. IRQ Source */
+
+/* Interrupt Mask Registers */
+	GM_TX_IRQ_MSK	= 0x0050,	/* 16 bit r/w	Tx Overflow IRQ Mask */
+	GM_RX_IRQ_MSK	= 0x0054,	/* 16 bit r/w	Rx Overflow IRQ Mask */
+	GM_TR_IRQ_MSK	= 0x0058,	/* 16 bit r/w	Tx/Rx Over. IRQ Mask */
+
+/* Serial Management Interface (SMI) Registers */
+	GM_SMI_CTRL	= 0x0080,	/* 16 bit r/w	SMI Control Register */
+	GM_SMI_DATA	= 0x0084,	/* 16 bit r/w	SMI Data Register */
+	GM_PHY_ADDR	= 0x0088,	/* 16 bit r/w	GPHY Address Register */
+};
+
+/* MIB Counters */
+#define GM_MIB_CNT_BASE	0x0100		/* Base Address of MIB Counters */
+#define GM_MIB_CNT_SIZE	44		/* Number of MIB Counters */
+
+/*
+ * MIB Counters base address definitions (low word) -
+ * use offset 4 for access to high word	(32 bit r/o)
+ */
+enum {
+	GM_RXF_UC_OK  = GM_MIB_CNT_BASE + 0,	/* Unicast Frames Received OK */
+	GM_RXF_BC_OK	= GM_MIB_CNT_BASE + 8,	/* Broadcast Frames Received OK */
+	GM_RXF_MPAUSE	= GM_MIB_CNT_BASE + 16,	/* Pause MAC Ctrl Frames Received */
+	GM_RXF_MC_OK	= GM_MIB_CNT_BASE + 24,	/* Multicast Frames Received OK */
+	GM_RXF_FCS_ERR	= GM_MIB_CNT_BASE + 32,	/* Rx Frame Check Seq. Error */
+	/* GM_MIB_CNT_BASE + 40:	reserved */
+	GM_RXO_OK_LO	= GM_MIB_CNT_BASE + 48,	/* Octets Received OK Low */
+	GM_RXO_OK_HI	= GM_MIB_CNT_BASE + 56,	/* Octets Received OK High */
+	GM_RXO_ERR_LO	= GM_MIB_CNT_BASE + 64,	/* Octets Received Invalid Low */
+	GM_RXO_ERR_HI	= GM_MIB_CNT_BASE + 72,	/* Octets Received Invalid High */
+	GM_RXF_SHT	= GM_MIB_CNT_BASE + 80,	/* Frames <64 Byte Received OK */
+	GM_RXE_FRAG	= GM_MIB_CNT_BASE + 88,	/* Frames <64 Byte Received with FCS Err */
+	GM_RXF_64B	= GM_MIB_CNT_BASE + 96,	/* 64 Byte Rx Frame */
+	GM_RXF_127B	= GM_MIB_CNT_BASE + 104,	/* 65-127 Byte Rx Frame */
+	GM_RXF_255B	= GM_MIB_CNT_BASE + 112,	/* 128-255 Byte Rx Frame */
+	GM_RXF_511B	= GM_MIB_CNT_BASE + 120,	/* 256-511 Byte Rx Frame */
+	GM_RXF_1023B	= GM_MIB_CNT_BASE + 128,	/* 512-1023 Byte Rx Frame */
+	GM_RXF_1518B	= GM_MIB_CNT_BASE + 136,	/* 1024-1518 Byte Rx Frame */
+	GM_RXF_MAX_SZ	= GM_MIB_CNT_BASE + 144,	/* 1519-MaxSize Byte Rx Frame */
+	GM_RXF_LNG_ERR	= GM_MIB_CNT_BASE + 152,	/* Rx Frame too Long Error */
+	GM_RXF_JAB_PKT	= GM_MIB_CNT_BASE + 160,	/* Rx Jabber Packet Frame */
+	/* GM_MIB_CNT_BASE + 168:	reserved */
+	GM_RXE_FIFO_OV	= GM_MIB_CNT_BASE + 176,	/* Rx FIFO overflow Event */
+	/* GM_MIB_CNT_BASE + 184:	reserved */
+	GM_TXF_UC_OK	= GM_MIB_CNT_BASE + 192,	/* Unicast Frames Xmitted OK */
+	GM_TXF_BC_OK	= GM_MIB_CNT_BASE + 200,	/* Broadcast Frames Xmitted OK */
+	GM_TXF_MPAUSE	= GM_MIB_CNT_BASE + 208,	/* Pause MAC Ctrl Frames Xmitted */
+	GM_TXF_MC_OK	= GM_MIB_CNT_BASE + 216,	/* Multicast Frames Xmitted OK */
+	GM_TXO_OK_LO	= GM_MIB_CNT_BASE + 224,	/* Octets Transmitted OK Low */
+	GM_TXO_OK_HI	= GM_MIB_CNT_BASE + 232,	/* Octets Transmitted OK High */
+	GM_TXF_64B	= GM_MIB_CNT_BASE + 240,	/* 64 Byte Tx Frame */
+	GM_TXF_127B	= GM_MIB_CNT_BASE + 248,	/* 65-127 Byte Tx Frame */
+	GM_TXF_255B	= GM_MIB_CNT_BASE + 256,	/* 128-255 Byte Tx Frame */
+	GM_TXF_511B	= GM_MIB_CNT_BASE + 264,	/* 256-511 Byte Tx Frame */
+	GM_TXF_1023B	= GM_MIB_CNT_BASE + 272,	/* 512-1023 Byte Tx Frame */
+	GM_TXF_1518B	= GM_MIB_CNT_BASE + 280,	/* 1024-1518 Byte Tx Frame */
+	GM_TXF_MAX_SZ	= GM_MIB_CNT_BASE + 288,	/* 1519-MaxSize Byte Tx Frame */
+
+	GM_TXF_COL	= GM_MIB_CNT_BASE + 304,	/* Tx Collision */
+	GM_TXF_LAT_COL	= GM_MIB_CNT_BASE + 312,	/* Tx Late Collision */
+	GM_TXF_ABO_COL	= GM_MIB_CNT_BASE + 320,	/* Tx aborted due to Exces. Col. */
+	GM_TXF_MUL_COL	= GM_MIB_CNT_BASE + 328,	/* Tx Multiple Collision */
+	GM_TXF_SNG_COL	= GM_MIB_CNT_BASE + 336,	/* Tx Single Collision */
+	GM_TXE_FIFO_UR	= GM_MIB_CNT_BASE + 344,	/* Tx FIFO Underrun Event */
+};
+
+/* GMAC Bit Definitions */
+/*	GM_GP_STAT	16 bit r/o	General Purpose Status Register */
+enum {
+	GM_GPSR_SPEED		= 1<<15, /* Bit 15:	Port Speed (1 = 100 Mbps) */
+	GM_GPSR_DUPLEX		= 1<<14, /* Bit 14:	Duplex Mode (1 = Full) */
+	GM_GPSR_FC_TX_DIS	= 1<<13, /* Bit 13:	Tx Flow-Control Mode Disabled */
+	GM_GPSR_LINK_UP		= 1<<12, /* Bit 12:	Link Up Status */
+	GM_GPSR_PAUSE		= 1<<11, /* Bit 11:	Pause State */
+	GM_GPSR_TX_ACTIVE	= 1<<10, /* Bit 10:	Tx in Progress */
+	GM_GPSR_EXC_COL		= 1<<9,	/* Bit  9:	Excessive Collisions Occured */
+	GM_GPSR_LAT_COL		= 1<<8,	/* Bit  8:	Late Collisions Occured */
+
+	GM_GPSR_PHY_ST_CH	= 1<<5,	/* Bit  5:	PHY Status Change */
+	GM_GPSR_GIG_SPEED	= 1<<4,	/* Bit  4:	Gigabit Speed (1 = 1000 Mbps) */
+	GM_GPSR_PART_MODE	= 1<<3,	/* Bit  3:	Partition mode */
+	GM_GPSR_FC_RX_DIS	= 1<<2,	/* Bit  2:	Rx Flow-Control Mode Disabled */
+	GM_GPSR_PROM_EN		= 1<<1,	/* Bit  1:	Promiscuous Mode Enabled */
+};
+
+/*	GM_GP_CTRL	16 bit r/w	General Purpose Control Register */
+enum {
+	GM_GPCR_PROM_ENA	= 1<<14,	/* Bit 14:	Enable Promiscuous Mode */
+	GM_GPCR_FC_TX_DIS	= 1<<13, /* Bit 13:	Disable Tx Flow-Control Mode */
+	GM_GPCR_TX_ENA		= 1<<12, /* Bit 12:	Enable Transmit */
+	GM_GPCR_RX_ENA		= 1<<11, /* Bit 11:	Enable Receive */
+	GM_GPCR_BURST_ENA	= 1<<10, /* Bit 10:	Enable Burst Mode */
+	GM_GPCR_LOOP_ENA	= 1<<9,	/* Bit  9:	Enable MAC Loopback Mode */
+	GM_GPCR_PART_ENA	= 1<<8,	/* Bit  8:	Enable Partition Mode */
+	GM_GPCR_GIGS_ENA	= 1<<7,	/* Bit  7:	Gigabit Speed (1000 Mbps) */
+	GM_GPCR_FL_PASS		= 1<<6,	/* Bit  6:	Force Link Pass */
+	GM_GPCR_DUP_FULL	= 1<<5,	/* Bit  5:	Full Duplex Mode */
+	GM_GPCR_FC_RX_DIS	= 1<<4,	/* Bit  4:	Disable Rx Flow-Control Mode */
+	GM_GPCR_SPEED_100	= 1<<3,   /* Bit  3:	Port Speed 100 Mbps */
+	GM_GPCR_AU_DUP_DIS	= 1<<2,	/* Bit  2:	Disable Auto-Update Duplex */
+	GM_GPCR_AU_FCT_DIS	= 1<<1,	/* Bit  1:	Disable Auto-Update Flow-C. */
+	GM_GPCR_AU_SPD_DIS	= 1<<0,	/* Bit  0:	Disable Auto-Update Speed */
+};
+
+#define GM_GPCR_SPEED_1000	(GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100)
+#define GM_GPCR_AU_ALL_DIS	(GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS)
+
+/*	GM_TX_CTRL			16 bit r/w	Transmit Control Register */
+enum {
+	GM_TXCR_FORCE_JAM	= 1<<15, /* Bit 15:	Force Jam / Flow-Control */
+	GM_TXCR_CRC_DIS		= 1<<14, /* Bit 14:	Disable insertion of CRC */
+	GM_TXCR_PAD_DIS		= 1<<13, /* Bit 13:	Disable padding of packets */
+	GM_TXCR_COL_THR_MSK	= 1<<10, /* Bit 12..10:	Collision Threshold */
+};
+
+#define TX_COL_THR(x)		(((x)<<10) & GM_TXCR_COL_THR_MSK)
+#define TX_COL_DEF		0x04
+
+/*	GM_RX_CTRL			16 bit r/w	Receive Control Register */
+enum {
+	GM_RXCR_UCF_ENA	= 1<<15, /* Bit 15:	Enable Unicast filtering */
+	GM_RXCR_MCF_ENA	= 1<<14, /* Bit 14:	Enable Multicast filtering */
+	GM_RXCR_CRC_DIS	= 1<<13, /* Bit 13:	Remove 4-byte CRC */
+	GM_RXCR_PASS_FC	= 1<<12, /* Bit 12:	Pass FC packets to FIFO */
+};
+
+/*	GM_TX_PARAM		16 bit r/w	Transmit Parameter Register */
+enum {
+	GM_TXPA_JAMLEN_MSK	= 0x03<<14,	/* Bit 15..14:	Jam Length */
+	GM_TXPA_JAMIPG_MSK	= 0x1f<<9,	/* Bit 13..9:	Jam IPG */
+	GM_TXPA_JAMDAT_MSK	= 0x1f<<4,	/* Bit  8..4:	IPG Jam to Data */
+	GM_TXPA_BO_LIM_MSK	= 0x0f,		/* Bit  3.. 0: Backoff Limit Mask */
+
+	TX_JAM_LEN_DEF		= 0x03,
+	TX_JAM_IPG_DEF		= 0x0b,
+	TX_IPG_JAM_DEF		= 0x1c,
+	TX_BOF_LIM_DEF		= 0x04,
+};
+
+#define TX_JAM_LEN_VAL(x)	(((x)<<14) & GM_TXPA_JAMLEN_MSK)
+#define TX_JAM_IPG_VAL(x)	(((x)<<9)  & GM_TXPA_JAMIPG_MSK)
+#define TX_IPG_JAM_DATA(x)	(((x)<<4)  & GM_TXPA_JAMDAT_MSK)
+#define TX_BACK_OFF_LIM(x)	((x) & GM_TXPA_BO_LIM_MSK)
+
+
+/*	GM_SERIAL_MODE			16 bit r/w	Serial Mode Register */
+enum {
+	GM_SMOD_DATABL_MSK	= 0x1f<<11, /* Bit 15..11:	Data Blinder (r/o) */
+	GM_SMOD_LIMIT_4		= 1<<10, /* Bit 10:	4 consecutive Tx trials */
+	GM_SMOD_VLAN_ENA	= 1<<9,	/* Bit  9:	Enable VLAN  (Max. Frame Len) */
+	GM_SMOD_JUMBO_ENA	= 1<<8,	/* Bit  8:	Enable Jumbo (Max. Frame Len) */
+	 GM_SMOD_IPG_MSK	= 0x1f	/* Bit 4..0:	Inter-Packet Gap (IPG) */
+};
+
+#define DATA_BLIND_VAL(x)	(((x)<<11) & GM_SMOD_DATABL_MSK)
+#define DATA_BLIND_DEF		0x04
+
+#define IPG_DATA_VAL(x)		(x & GM_SMOD_IPG_MSK)
+#define IPG_DATA_DEF		0x1e
+
+/*	GM_SMI_CTRL			16 bit r/w	SMI Control Register */
+enum {
+	GM_SMI_CT_PHY_A_MSK	= 0x1f<<11,/* Bit 15..11:	PHY Device Address */
+	GM_SMI_CT_REG_A_MSK	= 0x1f<<6,/* Bit 10.. 6:	PHY Register Address */
+	GM_SMI_CT_OP_RD		= 1<<5,	/* Bit  5:	OpCode Read (0=Write)*/
+	GM_SMI_CT_RD_VAL	= 1<<4,	/* Bit  4:	Read Valid (Read completed) */
+	GM_SMI_CT_BUSY		= 1<<3,	/* Bit  3:	Busy (Operation in progress) */
+};
+
+#define GM_SMI_CT_PHY_AD(x)	(((x)<<11) & GM_SMI_CT_PHY_A_MSK)
+#define GM_SMI_CT_REG_AD(x)	(((x)<<6) & GM_SMI_CT_REG_A_MSK)
+
+/*	GM_PHY_ADDR				16 bit r/w	GPHY Address Register */
+enum {
+	GM_PAR_MIB_CLR	= 1<<5,	/* Bit  5:	Set MIB Clear Counter Mode */
+	GM_PAR_MIB_TST	= 1<<4,	/* Bit  4:	MIB Load Counter (Test Mode) */
+};
+
+/* Receive Frame Status Encoding */
+enum {
+	GMR_FS_LEN	= 0xffff<<16, /* Bit 31..16:	Rx Frame Length */
+	GMR_FS_VLAN	= 1<<13, /* VLAN Packet */
+	GMR_FS_JABBER	= 1<<12, /* Jabber Packet */
+	GMR_FS_UN_SIZE	= 1<<11, /* Undersize Packet */
+	GMR_FS_MC	= 1<<10, /* Multicast Packet */
+	GMR_FS_BC	= 1<<9,  /* Broadcast Packet */
+	GMR_FS_RX_OK	= 1<<8,  /* Receive OK (Good Packet) */
+	GMR_FS_GOOD_FC	= 1<<7,  /* Good Flow-Control Packet */
+	GMR_FS_BAD_FC	= 1<<6,  /* Bad  Flow-Control Packet */
+	GMR_FS_MII_ERR	= 1<<5,  /* MII Error */
+	GMR_FS_LONG_ERR	= 1<<4,  /* Too Long Packet */
+	GMR_FS_FRAGMENT	= 1<<3,  /* Fragment */
+
+	GMR_FS_CRC_ERR	= 1<<1,  /* CRC Error */
+	GMR_FS_RX_FF_OV	= 1<<0,  /* Rx FIFO Overflow */
+
+	GMR_FS_ANY_ERR	= GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
+			  GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
+		  	  GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
+			  GMR_FS_UN_SIZE | GMR_FS_JABBER,
+};
+
+/*	RX_GMF_CTRL_T	32 bit	Rx GMAC FIFO Control/Test */
+enum {
+	RX_TRUNC_ON	= 1<<27,  	/* enable  packet truncation */
+	RX_TRUNC_OFF	= 1<<26, 	/* disable packet truncation */
+	RX_VLAN_STRIP_ON = 1<<25,	/* enable  VLAN stripping */
+	RX_VLAN_STRIP_OFF = 1<<24,	/* disable VLAN stripping */
+
+	GMF_WP_TST_ON	= 1<<14,	/* Write Pointer Test On */
+	GMF_WP_TST_OFF	= 1<<13,	/* Write Pointer Test Off */
+	GMF_WP_STEP	= 1<<12,	/* Write Pointer Step/Increment */
+
+	GMF_RP_TST_ON	= 1<<10,	/* Read Pointer Test On */
+	GMF_RP_TST_OFF	= 1<<9,		/* Read Pointer Test Off */
+	GMF_RP_STEP	= 1<<8,		/* Read Pointer Step/Increment */
+	GMF_RX_F_FL_ON	= 1<<7,		/* Rx FIFO Flush Mode On */
+	GMF_RX_F_FL_OFF	= 1<<6,		/* Rx FIFO Flush Mode Off */
+	GMF_CLI_RX_FO	= 1<<5,		/* Clear IRQ Rx FIFO Overrun */
+	GMF_CLI_RX_C	= 1<<4,		/* Clear IRQ Rx Frame Complete */
+
+	GMF_OPER_ON	= 1<<3,		/* Operational Mode On */
+	GMF_OPER_OFF	= 1<<2,		/* Operational Mode Off */
+	GMF_RST_CLR	= 1<<1,		/* Clear GMAC FIFO Reset */
+	GMF_RST_SET	= 1<<0,		/* Set   GMAC FIFO Reset */
+
+	RX_GMF_FL_THR_DEF = 0xa,	/* flush threshold (default) */
+
+	GMF_RX_CTRL_DEF	= GMF_OPER_ON | GMF_RX_F_FL_ON,
+};
+
+
+/*	TX_GMF_CTRL_T	32 bit	Tx GMAC FIFO Control/Test */
+enum {
+	TX_STFW_DIS	= 1<<31,/* Disable Store & Forward (Yukon-EC Ultra) */
+	TX_STFW_ENA	= 1<<30,/* Enable  Store & Forward (Yukon-EC Ultra) */
+
+	TX_VLAN_TAG_ON	= 1<<25,/* enable  VLAN tagging */
+	TX_VLAN_TAG_OFF	= 1<<24,/* disable VLAN tagging */
+
+	GMF_WSP_TST_ON	= 1<<18,/* Write Shadow Pointer Test On */
+	GMF_WSP_TST_OFF	= 1<<17,/* Write Shadow Pointer Test Off */
+	GMF_WSP_STEP	= 1<<16,/* Write Shadow Pointer Step/Increment */
+
+	GMF_CLI_TX_FU	= 1<<6,	/* Clear IRQ Tx FIFO Underrun */
+	GMF_CLI_TX_FC	= 1<<5,	/* Clear IRQ Tx Frame Complete */
+	GMF_CLI_TX_PE	= 1<<4,	/* Clear IRQ Tx Parity Error */
+};
+
+/*	GMAC_TI_ST_CTRL	 8 bit	Time Stamp Timer Ctrl Reg (YUKON only) */
+enum {
+	GMT_ST_START	= 1<<2,	/* Start Time Stamp Timer */
+	GMT_ST_STOP	= 1<<1,	/* Stop  Time Stamp Timer */
+	GMT_ST_CLR_IRQ	= 1<<0,	/* Clear Time Stamp Timer IRQ */
+};
+
+/* B28_Y2_ASF_STAT_CMD		32 bit	ASF Status and Command Reg */
+enum {
+	Y2_ASF_OS_PRES	= 1<<4,	/* ASF operation system present */
+	Y2_ASF_RESET	= 1<<3,	/* ASF system in reset state */
+	Y2_ASF_RUNNING	= 1<<2,	/* ASF system operational */
+	Y2_ASF_CLR_HSTI = 1<<1,	/* Clear ASF IRQ */
+	Y2_ASF_IRQ	= 1<<0,	/* Issue an IRQ to ASF system */
+
+	Y2_ASF_UC_STATE = 3<<2,	/* ASF uC State */
+	Y2_ASF_CLK_HALT	= 0,	/* ASF system clock stopped */
+};
+
+/* B28_Y2_ASF_HOST_COM	32 bit	ASF Host Communication Reg */
+enum {
+	Y2_ASF_CLR_ASFI = 1<<1,	/* Clear host IRQ */
+	Y2_ASF_HOST_IRQ = 1<<0,	/* Issue an IRQ to HOST system */
+};
+
+/*	STAT_CTRL		32 bit	Status BMU control register (Yukon-2 only) */
+enum {
+	SC_STAT_CLR_IRQ	= 1<<4,	/* Status Burst IRQ clear */
+	SC_STAT_OP_ON	= 1<<3,	/* Operational Mode On */
+	SC_STAT_OP_OFF	= 1<<2,	/* Operational Mode Off */
+	SC_STAT_RST_CLR	= 1<<1,	/* Clear Status Unit Reset (Enable) */
+	SC_STAT_RST_SET	= 1<<0,	/* Set   Status Unit Reset */
+};
+
+/*	GMAC_CTRL		32 bit	GMAC Control Reg (YUKON only) */
+enum {
+	GMC_H_BURST_ON	= 1<<7,	/* Half Duplex Burst Mode On */
+	GMC_H_BURST_OFF	= 1<<6,	/* Half Duplex Burst Mode Off */
+	GMC_F_LOOPB_ON	= 1<<5,	/* FIFO Loopback On */
+	GMC_F_LOOPB_OFF	= 1<<4,	/* FIFO Loopback Off */
+	GMC_PAUSE_ON	= 1<<3,	/* Pause On */
+	GMC_PAUSE_OFF	= 1<<2,	/* Pause Off */
+	GMC_RST_CLR	= 1<<1,	/* Clear GMAC Reset */
+	GMC_RST_SET	= 1<<0,	/* Set   GMAC Reset */
+};
+
+/*	GPHY_CTRL		32 bit	GPHY Control Reg (YUKON only) */
+enum {
+	GPC_SEL_BDT	= 1<<28, /* Select Bi-Dir. Transfer for MDC/MDIO */
+	GPC_INT_POL_HI	= 1<<27, /* IRQ Polarity is Active HIGH */
+	GPC_75_OHM	= 1<<26, /* Use 75 Ohm Termination instead of 50 */
+	GPC_DIS_FC	= 1<<25, /* Disable Automatic Fiber/Copper Detection */
+	GPC_DIS_SLEEP	= 1<<24, /* Disable Energy Detect */
+	GPC_HWCFG_M_3	= 1<<23, /* HWCFG_MODE[3] */
+	GPC_HWCFG_M_2	= 1<<22, /* HWCFG_MODE[2] */
+	GPC_HWCFG_M_1	= 1<<21, /* HWCFG_MODE[1] */
+	GPC_HWCFG_M_0	= 1<<20, /* HWCFG_MODE[0] */
+	GPC_ANEG_0	= 1<<19, /* ANEG[0] */
+	GPC_ENA_XC	= 1<<18, /* Enable MDI crossover */
+	GPC_DIS_125	= 1<<17, /* Disable 125 MHz clock */
+	GPC_ANEG_3	= 1<<16, /* ANEG[3] */
+	GPC_ANEG_2	= 1<<15, /* ANEG[2] */
+	GPC_ANEG_1	= 1<<14, /* ANEG[1] */
+	GPC_ENA_PAUSE	= 1<<13, /* Enable Pause (SYM_OR_REM) */
+	GPC_PHYADDR_4	= 1<<12, /* Bit 4 of Phy Addr */
+	GPC_PHYADDR_3	= 1<<11, /* Bit 3 of Phy Addr */
+	GPC_PHYADDR_2	= 1<<10, /* Bit 2 of Phy Addr */
+	GPC_PHYADDR_1	= 1<<9,	 /* Bit 1 of Phy Addr */
+	GPC_PHYADDR_0	= 1<<8,	 /* Bit 0 of Phy Addr */
+						/* Bits  7..2:	reserved */
+	GPC_RST_CLR	= 1<<1,	/* Clear GPHY Reset */
+	GPC_RST_SET	= 1<<0,	/* Set   GPHY Reset */
+};
+
+/*	GMAC_IRQ_SRC	 8 bit	GMAC Interrupt Source Reg (YUKON only) */
+/*	GMAC_IRQ_MSK	 8 bit	GMAC Interrupt Mask   Reg (YUKON only) */
+enum {
+	GM_IS_TX_CO_OV	= 1<<5,	/* Transmit Counter Overflow IRQ */
+	GM_IS_RX_CO_OV	= 1<<4,	/* Receive Counter Overflow IRQ */
+	GM_IS_TX_FF_UR	= 1<<3,	/* Transmit FIFO Underrun */
+	GM_IS_TX_COMPL	= 1<<2,	/* Frame Transmission Complete */
+	GM_IS_RX_FF_OR	= 1<<1,	/* Receive FIFO Overrun */
+	GM_IS_RX_COMPL	= 1<<0,	/* Frame Reception Complete */
+
+#define GMAC_DEF_MSK     GM_IS_TX_FF_UR
+
+/*	GMAC_LINK_CTRL	16 bit	GMAC Link Control Reg (YUKON only) */
+						/* Bits 15.. 2:	reserved */
+	GMLC_RST_CLR	= 1<<1,	/* Clear GMAC Link Reset */
+	GMLC_RST_SET	= 1<<0,	/* Set   GMAC Link Reset */
+
+
+/*	WOL_CTRL_STAT	16 bit	WOL Control/Status Reg */
+	WOL_CTL_LINK_CHG_OCC		= 1<<15,
+	WOL_CTL_MAGIC_PKT_OCC		= 1<<14,
+	WOL_CTL_PATTERN_OCC		= 1<<13,
+	WOL_CTL_CLEAR_RESULT		= 1<<12,
+	WOL_CTL_ENA_PME_ON_LINK_CHG	= 1<<11,
+	WOL_CTL_DIS_PME_ON_LINK_CHG	= 1<<10,
+	WOL_CTL_ENA_PME_ON_MAGIC_PKT	= 1<<9,
+	WOL_CTL_DIS_PME_ON_MAGIC_PKT	= 1<<8,
+	WOL_CTL_ENA_PME_ON_PATTERN	= 1<<7,
+	WOL_CTL_DIS_PME_ON_PATTERN	= 1<<6,
+	WOL_CTL_ENA_LINK_CHG_UNIT	= 1<<5,
+	WOL_CTL_DIS_LINK_CHG_UNIT	= 1<<4,
+	WOL_CTL_ENA_MAGIC_PKT_UNIT	= 1<<3,
+	WOL_CTL_DIS_MAGIC_PKT_UNIT	= 1<<2,
+	WOL_CTL_ENA_PATTERN_UNIT	= 1<<1,
+	WOL_CTL_DIS_PATTERN_UNIT	= 1<<0,
+};
+
+#define WOL_CTL_DEFAULT				\
+	(WOL_CTL_DIS_PME_ON_LINK_CHG |	\
+	WOL_CTL_DIS_PME_ON_PATTERN |	\
+	WOL_CTL_DIS_PME_ON_MAGIC_PKT |	\
+	WOL_CTL_DIS_LINK_CHG_UNIT |		\
+	WOL_CTL_DIS_PATTERN_UNIT |		\
+	WOL_CTL_DIS_MAGIC_PKT_UNIT)
+
+/*	WOL_MATCH_CTL	 8 bit	WOL Match Control Reg */
+#define WOL_CTL_PATT_ENA(x)	(1 << (x))
+
+
+/* Control flags */
+enum {
+	UDPTCP	= 1<<0,
+	CALSUM	= 1<<1,
+	WR_SUM	= 1<<2,
+	INIT_SUM= 1<<3,
+	LOCK_SUM= 1<<4,
+	INS_VLAN= 1<<5,
+	FRC_STAT= 1<<6,
+	EOP	= 1<<7,
+};
+
+enum {
+	HW_OWNER 	= 1<<7,
+	OP_TCPWRITE	= 0x11,
+	OP_TCPSTART	= 0x12,
+	OP_TCPINIT	= 0x14,
+	OP_TCPLCK	= 0x18,
+	OP_TCPCHKSUM	= OP_TCPSTART,
+	OP_TCPIS	= OP_TCPINIT | OP_TCPSTART,
+	OP_TCPLW	= OP_TCPLCK | OP_TCPWRITE,
+	OP_TCPLSW	= OP_TCPLCK | OP_TCPSTART | OP_TCPWRITE,
+	OP_TCPLISW	= OP_TCPLCK | OP_TCPINIT | OP_TCPSTART | OP_TCPWRITE,
+
+	OP_ADDR64	= 0x21,
+	OP_VLAN		= 0x22,
+	OP_ADDR64VLAN	= OP_ADDR64 | OP_VLAN,
+	OP_LRGLEN	= 0x24,
+	OP_LRGLENVLAN	= OP_LRGLEN | OP_VLAN,
+	OP_BUFFER	= 0x40,
+	OP_PACKET	= 0x41,
+	OP_LARGESEND	= 0x43,
+
+/* YUKON-2 STATUS opcodes defines */
+	OP_RXSTAT	= 0x60,
+	OP_RXTIMESTAMP	= 0x61,
+	OP_RXVLAN	= 0x62,
+	OP_RXCHKS	= 0x64,
+	OP_RXCHKSVLAN	= OP_RXCHKS | OP_RXVLAN,
+	OP_RXTIMEVLAN	= OP_RXTIMESTAMP | OP_RXVLAN,
+	OP_RSS_HASH	= 0x65,
+	OP_TXINDEXLE	= 0x68,
+};
+
+/* Yukon 2 hardware interface
+ * Not tested on big endian
+ */
+struct sky2_tx_le {
+	union {
+		__le32	addr;
+		struct {
+			__le16	offset;
+			__le16	start;
+		} csum  __attribute((packed));
+		struct {
+			__le16	size;
+			__le16	rsvd;
+		} tso  __attribute((packed));
+	} tx;
+	__le16	length;	/* also vlan tag or checksum start */
+	u8	ctrl;
+	u8	opcode;
+} __attribute((packed));
+
+struct sky2_rx_le {
+	__le32	addr;
+	__le16	length;
+	u8	ctrl;
+	u8	opcode;
+} __attribute((packed));;
+
+struct sky2_status_le {
+	__le32	status;	/* also checksum */
+	__le16	length;	/* also vlan tag */
+	u8	link;
+	u8	opcode;
+} __attribute((packed));
+
+struct tx_ring_info {
+	struct sk_buff	*skb;
+	DECLARE_PCI_UNMAP_ADDR(mapaddr);
+	u16		idx;
+};
+
+struct ring_info {
+	struct sk_buff	*skb;
+	dma_addr_t	mapaddr;
+};
+
+struct sky2_port {
+	struct sky2_hw	     *hw;
+	struct net_device    *netdev;
+	unsigned	     port;
+	u32		     msg_enable;
+
+	spinlock_t	     tx_lock  ____cacheline_aligned_in_smp;
+	struct tx_ring_info  *tx_ring;
+	struct sky2_tx_le    *tx_le;
+	u16		     tx_cons;		/* next le to check */
+	u16		     tx_prod;		/* next le to use */
+	u32		     tx_addr64;
+	u16		     tx_pending;
+	u16		     tx_last_put;
+	u16		     tx_last_mss;
+
+	struct ring_info     *rx_ring ____cacheline_aligned_in_smp;
+	struct sky2_rx_le    *rx_le;
+	u32		     rx_addr64;
+	u16		     rx_next;		/* next re to check */
+	u16		     rx_put;		/* next le index to use */
+	u16		     rx_pending;
+	u16		     rx_last_put;
+	u16		     rx_bufsize;
+#ifdef SKY2_VLAN_TAG_USED
+	u16		     rx_tag;
+	struct vlan_group    *vlgrp;
+#endif
+
+	dma_addr_t	     rx_le_map;
+	dma_addr_t	     tx_le_map;
+	u32		     advertising;	/* ADVERTISED_ bits */
+	u16		     speed;	/* SPEED_1000, SPEED_100, ... */
+	u8		     autoneg;	/* AUTONEG_ENABLE, AUTONEG_DISABLE */
+	u8		     duplex;	/* DUPLEX_HALF, DUPLEX_FULL */
+	u8		     rx_pause;
+	u8		     tx_pause;
+	u8		     rx_csum;
+	u8		     wol;
+
+	struct net_device_stats net_stats;
+
+	struct work_struct   phy_task;
+	struct semaphore     phy_sema;
+};
+
+struct sky2_hw {
+	void __iomem  	     *regs;
+	struct pci_dev	     *pdev;
+	u32		     intr_mask;
+	struct net_device    *dev[2];
+
+	int		     pm_cap;
+	u8	     	     chip_id;
+	u8		     chip_rev;
+	u8		     copper;
+	u8		     ports;
+
+	struct sky2_status_le *st_le;
+	u32		     st_idx;
+	dma_addr_t   	     st_dma;
+};
+
+/* Register accessor for memory mapped device */
+static inline u32 sky2_read32(const struct sky2_hw *hw, unsigned reg)
+{
+	return readl(hw->regs + reg);
+}
+
+static inline u16 sky2_read16(const struct sky2_hw *hw, unsigned reg)
+{
+	return readw(hw->regs + reg);
+}
+
+static inline u8 sky2_read8(const struct sky2_hw *hw, unsigned reg)
+{
+	return readb(hw->regs + reg);
+}
+
+/* This should probably go away, bus based tweeks suck */
+static inline int is_pciex(const struct sky2_hw *hw)
+{
+	u32 status;
+	pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status);
+	return (status & PCI_OS_PCI_X) == 0;
+}
+
+static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val)
+{
+	writel(val, hw->regs + reg);
+}
+
+static inline void sky2_write16(const struct sky2_hw *hw, unsigned reg, u16 val)
+{
+	writew(val, hw->regs + reg);
+}
+
+static inline void sky2_write8(const struct sky2_hw *hw, unsigned reg, u8 val)
+{
+	writeb(val, hw->regs + reg);
+}
+
+/* Yukon PHY related registers */
+#define SK_GMAC_REG(port,reg) \
+	(BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg))
+#define GM_PHY_RETRIES	100
+
+static inline u16 gma_read16(const struct sky2_hw *hw, unsigned port, unsigned reg)
+{
+	return sky2_read16(hw, SK_GMAC_REG(port,reg));
+}
+
+static inline u32 gma_read32(struct sky2_hw *hw, unsigned port, unsigned reg)
+{
+	unsigned base = SK_GMAC_REG(port, reg);
+	return (u32) sky2_read16(hw, base)
+		| (u32) sky2_read16(hw, base+4) << 16;
+}
+
+static inline void gma_write16(const struct sky2_hw *hw, unsigned port, int r, u16 v)
+{
+	sky2_write16(hw, SK_GMAC_REG(port,r), v);
+}
+
+static inline void gma_set_addr(struct sky2_hw *hw, unsigned port, unsigned reg,
+				    const u8 *addr)
+{
+	gma_write16(hw, port, reg,  (u16) addr[0] | ((u16) addr[1] << 8));
+	gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
+	gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
+}
+#endif
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 28bf2e6..7ec0812 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -88,7 +88,6 @@
 #include <linux/skbuff.h>
 
 #include <asm/io.h>
-#include <asm/irq.h>
 
 #include "smc91x.h"
 
@@ -2007,12 +2006,10 @@
 	}
 
 	/* Grab the IRQ */
-      	retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
+      	retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev);
       	if (retval)
       		goto err_out;
 
-	set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE);
-
 #ifdef SMC_USE_PXA_DMA
 	{
 		int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW,
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 5c2824b..e0efd19 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -90,7 +90,7 @@
 			__l--;						\
 		}							\
 	} while (0)
-#define set_irq_type(irq, type)
+#define SMC_IRQ_FLAGS		(0)
 
 #elif defined(CONFIG_SA1100_PLEB)
 /* We can only do 16-bit reads and writes in the static memory space. */
@@ -109,7 +109,7 @@
 #define SMC_outw(v, a, r)	writew(v, (a) + (r))
 #define SMC_outsw(a, r, p, l)	writesw((a) + (r), p, l)
 
-#define set_irq_type(irq, type) do {} while (0)
+#define SMC_IRQ_FLAGS		(0)
 
 #elif defined(CONFIG_SA1100_ASSABET)
 
@@ -185,11 +185,11 @@
 #include <asm/mach-types.h>
 #include <asm/arch/cpu.h>
 
-#define	SMC_IRQ_TRIGGER_TYPE (( \
+#define	SMC_IRQ_FLAGS (( \
 		   machine_is_omap_h2() \
 		|| machine_is_omap_h3() \
 		|| (machine_is_omap_innovator() && !cpu_is_omap1510()) \
-	) ? IRQT_FALLING : IRQT_RISING)
+	) ? SA_TRIGGER_FALLING : SA_TRIGGER_RISING)
 
 
 #elif	defined(CONFIG_SH_SH4202_MICRODEV)
@@ -209,7 +209,7 @@
 #define SMC_insw(a, r, p, l)	insw((a) + (r) - 0xa0000000, p, l)
 #define SMC_outsw(a, r, p, l)	outsw((a) + (r) - 0xa0000000, p, l)
 
-#define set_irq_type(irq, type)	do {} while(0)
+#define SMC_IRQ_FLAGS		(0)
 
 #elif	defined(CONFIG_ISA)
 
@@ -237,7 +237,7 @@
 #define SMC_insw(a, r, p, l)	insw(((u32)a) + (r), p, l)
 #define SMC_outsw(a, r, p, l)	outsw(((u32)a) + (r), p, l)
 
-#define set_irq_type(irq, type)	do {} while(0)
+#define SMC_IRQ_FLAGS		(0)
 
 #define RPC_LSA_DEFAULT		RPC_LED_TX_RX
 #define RPC_LSB_DEFAULT		RPC_LED_100_10
@@ -319,7 +319,7 @@
 			au_writew(*_p++ , _a); \
 	} while(0)
 
-#define set_irq_type(irq, type) do {} while (0)
+#define SMC_IRQ_FLAGS		(0)
 
 #else
 
@@ -342,8 +342,8 @@
 
 #endif
 
-#ifndef	SMC_IRQ_TRIGGER_TYPE
-#define	SMC_IRQ_TRIGGER_TYPE	IRQT_RISING
+#ifndef	SMC_IRQ_FLAGS
+#define	SMC_IRQ_FLAGS		SA_TRIGGER_RISING
 #endif
 
 #ifdef SMC_USE_PXA_DMA
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 081717d..28ce47a 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2907,7 +2907,7 @@
 	return 0;
 }
 
-static void __devexit gem_remove_one(struct pci_dev *pdev)
+static void gem_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
@@ -3181,7 +3181,7 @@
 	.name		= GEM_MODULE_NAME,
 	.id_table	= gem_pci_tbl,
 	.probe		= gem_init_one,
-	.remove		= __devexit_p(gem_remove_one),
+	.remove		= gem_remove_one,
 #ifdef CONFIG_PM
 	.suspend	= gem_suspend,
 	.resume		= gem_resume,
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1828a6b..eb86b05 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -24,6 +24,7 @@
 #include <linux/compiler.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/in.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
@@ -68,8 +69,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.43"
-#define DRV_MODULE_RELDATE	"Oct 24, 2005"
+#define DRV_MODULE_VERSION	"3.47"
+#define DRV_MODULE_RELDATE	"Dec 28, 2005"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -341,6 +342,16 @@
 	{ "interrupt test (offline)" },
 };
 
+static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
+{
+	writel(val, tp->regs + off);
+}
+
+static u32 tg3_read32(struct tg3 *tp, u32 off)
+{
+	return (readl(tp->regs + off)); 
+}
+
 static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
 {
 	unsigned long flags;
@@ -411,13 +422,29 @@
 	return val;
 }
 
-static void _tw32_flush(struct tg3 *tp, u32 off, u32 val)
+/* usec_wait specifies the wait time in usec when writing to certain registers
+ * where it is unsafe to read back the register without some delay.
+ * GRC_LOCAL_CTRL is one example if the GPIOs are toggled to switch power.
+ * TG3PCI_CLOCK_CTRL is another example if the clock frequencies are changed.
+ */
+static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait)
 {
-	tp->write32(tp, off, val);
-	if (!(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) &&
-	    !(tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
-		tp->read32(tp, off);	/* flush */
+	if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) ||
+	    (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
+		/* Non-posted methods */
+		tp->write32(tp, off, val);
+	else {
+		/* Posted method */
+		tg3_write32(tp, off, val);
+		if (usec_wait)
+			udelay(usec_wait);
+		tp->read32(tp, off);
+	}
+	/* Wait again after the read for the posted method to guarantee that
+	 * the wait time is met.
+	 */
+	if (usec_wait)
+		udelay(usec_wait);
 }
 
 static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
@@ -438,16 +465,6 @@
 		readl(mbox);
 }
 
-static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
-{
-	writel(val, tp->regs + off);
-}
-
-static u32 tg3_read32(struct tg3 *tp, u32 off)
-{
-	return (readl(tp->regs + off)); 
-}
-
 #define tw32_mailbox(reg, val)	tp->write32_mbox(tp, reg, val)
 #define tw32_mailbox_f(reg, val)	tw32_mailbox_flush(tp, (reg), (val))
 #define tw32_rx_mbox(reg, val)	tp->write32_rx_mbox(tp, reg, val)
@@ -455,7 +472,8 @@
 #define tr32_mailbox(reg)	tp->read32_mbox(tp, reg)
 
 #define tw32(reg,val)		tp->write32(tp, reg, val)
-#define tw32_f(reg,val)		_tw32_flush(tp,(reg),(val))
+#define tw32_f(reg,val)		_tw32_flush(tp,(reg),(val), 0)
+#define tw32_wait_f(reg,val,us)	_tw32_flush(tp,(reg),(val), (us))
 #define tr32(reg)		tp->read32(tp, reg)
 
 static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
@@ -595,21 +613,19 @@
 
 	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
 		if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) {
-			tw32_f(TG3PCI_CLOCK_CTRL,
-			       clock_ctrl | CLOCK_CTRL_625_CORE);
-			udelay(40);
+			tw32_wait_f(TG3PCI_CLOCK_CTRL,
+				    clock_ctrl | CLOCK_CTRL_625_CORE, 40);
 		}
 	} else if ((orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE) != 0) {
-		tw32_f(TG3PCI_CLOCK_CTRL,
-		     clock_ctrl |
-		     (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK));
-		udelay(40);
-		tw32_f(TG3PCI_CLOCK_CTRL,
-		     clock_ctrl | (CLOCK_CTRL_ALTCLK));
-		udelay(40);
+		tw32_wait_f(TG3PCI_CLOCK_CTRL,
+			    clock_ctrl |
+			    (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK),
+			    40);
+		tw32_wait_f(TG3PCI_CLOCK_CTRL,
+			    clock_ctrl | (CLOCK_CTRL_ALTCLK),
+			    40);
 	}
-	tw32_f(TG3PCI_CLOCK_CTRL, clock_ctrl);
-	udelay(40);
+	tw32_wait_f(TG3PCI_CLOCK_CTRL, clock_ctrl, 40);
 }
 
 #define PHY_BUSY_LOOPS	5000
@@ -1017,37 +1033,50 @@
 	if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0)
 		return;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
-		tp_peer = pci_get_drvdata(tp->pdev_peer);
-		if (!tp_peer)
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
+	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
+		struct net_device *dev_peer;
+
+		dev_peer = pci_get_drvdata(tp->pdev_peer);
+		if (!dev_peer)
 			BUG();
+		tp_peer = netdev_priv(dev_peer);
 	}
 
-
 	if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
-	    (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0) {
+	    (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0 ||
+	    (tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) != 0 ||
+	    (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0) {
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
-			tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
-			     (GRC_LCLCTRL_GPIO_OE0 |
-			      GRC_LCLCTRL_GPIO_OE1 |
-			      GRC_LCLCTRL_GPIO_OE2 |
-			      GRC_LCLCTRL_GPIO_OUTPUT0 |
-			      GRC_LCLCTRL_GPIO_OUTPUT1));
-			udelay(100);
+			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+				    (GRC_LCLCTRL_GPIO_OE0 |
+				     GRC_LCLCTRL_GPIO_OE1 |
+				     GRC_LCLCTRL_GPIO_OE2 |
+				     GRC_LCLCTRL_GPIO_OUTPUT0 |
+				     GRC_LCLCTRL_GPIO_OUTPUT1),
+				    100);
 		} else {
 			u32 no_gpio2;
-			u32 grc_local_ctrl;
+			u32 grc_local_ctrl = 0;
 
 			if (tp_peer != tp &&
 			    (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0)
 				return;
 
+			/* Workaround to prevent overdrawing Amps. */
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+			    ASIC_REV_5714) {
+				grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE3;
+				tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+					    grc_local_ctrl, 100);
+			}
+
 			/* On 5753 and variants, GPIO2 cannot be used. */
 			no_gpio2 = tp->nic_sram_data_cfg &
 				    NIC_SRAM_DATA_CFG_NO_GPIO2;
 
-			grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
+			grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 |
 					 GRC_LCLCTRL_GPIO_OE1 |
 					 GRC_LCLCTRL_GPIO_OE2 |
 					 GRC_LCLCTRL_GPIO_OUTPUT1 |
@@ -1056,21 +1085,18 @@
 				grc_local_ctrl &= ~(GRC_LCLCTRL_GPIO_OE2 |
 						    GRC_LCLCTRL_GPIO_OUTPUT2);
 			}
-			tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
-						grc_local_ctrl);
-			udelay(100);
+			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+						    grc_local_ctrl, 100);
 
 			grc_local_ctrl |= GRC_LCLCTRL_GPIO_OUTPUT0;
 
-			tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
-						grc_local_ctrl);
-			udelay(100);
+			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+						    grc_local_ctrl, 100);
 
 			if (!no_gpio2) {
 				grc_local_ctrl &= ~GRC_LCLCTRL_GPIO_OUTPUT2;
-				tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
-				       grc_local_ctrl);
-				udelay(100);
+				tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+					    grc_local_ctrl, 100);
 			}
 		}
 	} else {
@@ -1080,19 +1106,16 @@
 			    (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE) != 0)
 				return;
 
-			tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
-			     (GRC_LCLCTRL_GPIO_OE1 |
-			      GRC_LCLCTRL_GPIO_OUTPUT1));
-			udelay(100);
+			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+				    (GRC_LCLCTRL_GPIO_OE1 |
+				     GRC_LCLCTRL_GPIO_OUTPUT1), 100);
 
-			tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
-			     (GRC_LCLCTRL_GPIO_OE1));
-			udelay(100);
+			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+				    GRC_LCLCTRL_GPIO_OE1, 100);
 
-			tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
-			     (GRC_LCLCTRL_GPIO_OE1 |
-			      GRC_LCLCTRL_GPIO_OUTPUT1));
-			udelay(100);
+			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl |
+				    (GRC_LCLCTRL_GPIO_OE1 |
+				     GRC_LCLCTRL_GPIO_OUTPUT1), 100);
 		}
 	}
 }
@@ -1105,6 +1128,8 @@
 
 static void tg3_write_sig_post_reset(struct tg3 *, int);
 static int tg3_halt_cpu(struct tg3 *, u32);
+static int tg3_nvram_lock(struct tg3 *);
+static void tg3_nvram_unlock(struct tg3 *);
 
 static int tg3_set_power_state(struct tg3 *tp, int state)
 {
@@ -1133,10 +1158,8 @@
 		udelay(100);	/* Delay after power state change */
 
 		/* Switch out of Vaux if it is not a LOM */
-		if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) {
-			tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
-			udelay(100);
-		}
+		if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT))
+			tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
 
 		return 0;
 
@@ -1179,6 +1202,21 @@
 		tg3_setup_phy(tp, 0);
 	}
 
+	if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+		int i;
+		u32 val;
+
+		for (i = 0; i < 200; i++) {
+			tg3_read_mem(tp, NIC_SRAM_FW_ASF_STATUS_MBOX, &val);
+			if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+				break;
+			msleep(1);
+		}
+	}
+	tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE |
+					     WOL_DRV_STATE_SHUTDOWN |
+					     WOL_DRV_WOL | WOL_SET_MAGIC_PKT);
+
 	pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps);
 
 	if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
@@ -1220,10 +1258,8 @@
 		base_val |= (CLOCK_CTRL_RXCLK_DISABLE |
 			     CLOCK_CTRL_TXCLK_DISABLE);
 
-		tw32_f(TG3PCI_CLOCK_CTRL, base_val |
-		     CLOCK_CTRL_ALTCLK |
-		     CLOCK_CTRL_PWRDOWN_PLL133);
-		udelay(40);
+		tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
+			    CLOCK_CTRL_PWRDOWN_PLL133, 40);
 	} else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
 		/* do nothing */
 	} else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
@@ -1244,11 +1280,11 @@
 			newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
 		}
 
-		tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1);
-		udelay(40);
+		tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1,
+			    40);
 
-		tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2);
-		udelay(40);
+		tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2,
+			    40);
 
 		if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
 			u32 newbits3;
@@ -1262,9 +1298,20 @@
 				newbits3 = CLOCK_CTRL_44MHZ_CORE;
 			}
 
-			tw32_f(TG3PCI_CLOCK_CTRL,
-					 tp->pci_clock_ctrl | newbits3);
-			udelay(40);
+			tw32_wait_f(TG3PCI_CLOCK_CTRL,
+				    tp->pci_clock_ctrl | newbits3, 40);
+		}
+	}
+
+	if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
+	    !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+		/* Turn off the PHY */
+		if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
+			tg3_writephy(tp, MII_TG3_EXT_CTRL,
+				     MII_TG3_EXT_CTRL_FORCE_LED_OFF);
+			tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
+				tg3_writephy(tp, MII_BMCR, BMCR_PDOWN);
 		}
 	}
 
@@ -1277,8 +1324,12 @@
 
 		val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
 		tw32(0x7d00, val);
-		if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+		if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+			tg3_nvram_lock(tp);
 			tg3_halt_cpu(tp, RX_CPU_BASE);
+			tw32_f(NVRAM_SWARB, SWARB_REQ_CLR0);
+			tg3_nvram_unlock(tp);
+		}
 	}
 
 	/* Finally, set the new power state. */
@@ -1812,7 +1863,7 @@
 		}
 	}
 relink:
-	if (current_link_up == 0) {
+	if (current_link_up == 0 || tp->link_config.phy_is_low_power) {
 		u32 tmp;
 
 		tg3_phy_copper_begin(tp);
@@ -3565,12 +3616,15 @@
 	if (!spin_trylock(&tp->tx_lock))
 		return NETDEV_TX_LOCKED; 
 
-	/* This is a hard error, log it. */
 	if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
-		netif_stop_queue(dev);
+		if (!netif_queue_stopped(dev)) {
+			netif_stop_queue(dev);
+
+			/* This is a hard error, log it. */
+			printk(KERN_ERR PFX "%s: BUG! Tx Ring full when "
+			       "queue awake!\n", dev->name);
+		}
 		spin_unlock(&tp->tx_lock);
-		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
-		       dev->name);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -3597,7 +3651,7 @@
 			       TXD_FLAG_CPU_POST_DMA);
 
 		skb->nh.iph->check = 0;
-		skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len);
+		skb->nh.iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
 		if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
 			skb->h.th->check = 0;
 			base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
@@ -7098,8 +7152,13 @@
 	GET_REG32_LOOP(BUFMGR_MODE, 0x58);
 	GET_REG32_LOOP(RDMAC_MODE, 0x08);
 	GET_REG32_LOOP(WDMAC_MODE, 0x08);
-	GET_REG32_LOOP(RX_CPU_BASE, 0x280);
-	GET_REG32_LOOP(TX_CPU_BASE, 0x280);
+	GET_REG32_1(RX_CPU_MODE);
+	GET_REG32_1(RX_CPU_STATE);
+	GET_REG32_1(RX_CPU_PGMCTR);
+	GET_REG32_1(RX_CPU_HWBKPT);
+	GET_REG32_1(TX_CPU_MODE);
+	GET_REG32_1(TX_CPU_STATE);
+	GET_REG32_1(TX_CPU_PGMCTR);
 	GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110);
 	GET_REG32_LOOP(FTQ_RESET, 0x120);
 	GET_REG32_LOOP(MSGINT_MODE, 0x0c);
@@ -7922,13 +7981,12 @@
 		u32 offset;
 		u32 len;
 	} mem_tbl_570x[] = {
-		{ 0x00000000, 0x01000},
+		{ 0x00000000, 0x00b50},
 		{ 0x00002000, 0x1c000},
 		{ 0xffffffff, 0x00000}
 	}, mem_tbl_5705[] = {
 		{ 0x00000100, 0x0000c},
 		{ 0x00000200, 0x00008},
-		{ 0x00000b50, 0x00400},
 		{ 0x00004000, 0x00800},
 		{ 0x00006000, 0x01000},
 		{ 0x00008000, 0x02000},
@@ -8530,6 +8588,7 @@
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
 		tp->tg3_flags |= TG3_FLAG_NVRAM;
 
+		tg3_nvram_lock(tp);
 		tg3_enable_nvram_access(tp);
 
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
@@ -8540,6 +8599,7 @@
 		tg3_get_nvram_size(tp);
 
 		tg3_disable_nvram_access(tp);
+		tg3_nvram_unlock(tp);
 
 	} else {
 		tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
@@ -8637,10 +8697,10 @@
 	if (ret == 0)
 		*val = swab32(tr32(NVRAM_RDDATA));
 
-	tg3_nvram_unlock(tp);
-
 	tg3_disable_nvram_access(tp);
 
+	tg3_nvram_unlock(tp);
+
 	return ret;
 }
 
@@ -8725,6 +8785,10 @@
 
 		offset = offset + (pagesize - page_off);
 
+		/* Nvram lock released by tg3_nvram_read() above,
+		 * so need to get it again.
+		 */
+		tg3_nvram_lock(tp);
 		tg3_enable_nvram_access(tp);
 
 		/*
@@ -10423,7 +10487,7 @@
 	return str;
 }
 
-static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp)
+static struct pci_dev * __devinit tg3_find_peer(struct tg3 *tp)
 {
 	struct pci_dev *peer;
 	unsigned int func, devnr = tp->pdev->devfn & ~7;
@@ -10434,8 +10498,13 @@
 			break;
 		pci_dev_put(peer);
 	}
-	if (!peer || peer == tp->pdev)
-		BUG();
+	/* 5704 can be configured in single-port mode, set peer to
+	 * tp->pdev in that case.
+	 */
+	if (!peer) {
+		peer = tp->pdev;
+		return peer;
+	}
 
 	/*
 	 * We don't need to keep the refcount elevated; there's no way
@@ -10671,8 +10740,9 @@
 		tp->rx_pending = 63;
 	}
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
-		tp->pdev_peer = tg3_find_5704_peer(tp);
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
+	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714))
+		tp->pdev_peer = tg3_find_peer(tp);
 
 	err = tg3_get_device_address(tp);
 	if (err) {
@@ -10817,12 +10887,14 @@
 
 	tg3_full_lock(tp, 0);
 	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
+	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
 	tg3_full_unlock(tp);
 
 	err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
 	if (err) {
 		tg3_full_lock(tp, 0);
 
+		tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
 		tg3_init_hw(tp);
 
 		tp->timer.expires = jiffies + tp->timer_offset;
@@ -10856,6 +10928,7 @@
 
 	tg3_full_lock(tp, 0);
 
+	tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
 	tg3_init_hw(tp);
 
 	tp->timer.expires = jiffies + tp->timer_offset;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index fb7e2a5..890e163 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1124,7 +1124,14 @@
 /* 0x280 --> 0x400 unused */
 
 #define RX_CPU_BASE			0x00005000
+#define RX_CPU_MODE			0x00005000
+#define RX_CPU_STATE			0x00005004
+#define RX_CPU_PGMCTR			0x0000501c
+#define RX_CPU_HWBKPT			0x00005034
 #define TX_CPU_BASE			0x00005400
+#define TX_CPU_MODE			0x00005400
+#define TX_CPU_STATE			0x00005404
+#define TX_CPU_PGMCTR			0x0000541c
 
 /* Mailboxes */
 #define GRCMBOX_INTERRUPT_0		0x00005800 /* 64-bit */
@@ -1529,6 +1536,12 @@
 #define NIC_SRAM_MAC_ADDR_HIGH_MBOX	0x00000c14
 #define NIC_SRAM_MAC_ADDR_LOW_MBOX	0x00000c18
 
+#define NIC_SRAM_WOL_MBOX		0x00000d30
+#define  WOL_SIGNATURE			 0x474c0000
+#define  WOL_DRV_STATE_SHUTDOWN		 0x00000001
+#define  WOL_DRV_WOL			 0x00000002
+#define  WOL_SET_MAGIC_PKT		 0x00000004
+
 #define NIC_SRAM_DATA_CFG_2		0x00000d38
 
 #define  SHASTA_EXT_LED_MODE_MASK	 0x00018000
@@ -1565,6 +1578,7 @@
 #define MII_TG3_EXT_CTRL		0x10 /* Extended control register */
 #define  MII_TG3_EXT_CTRL_FIFO_ELASTIC	0x0001
 #define  MII_TG3_EXT_CTRL_LNK3_LED_MODE	0x0002
+#define  MII_TG3_EXT_CTRL_FORCE_LED_OFF	0x0008
 #define  MII_TG3_EXT_CTRL_TBI		0x8000
 
 #define MII_TG3_EXT_STAT		0x11 /* Extended status register */
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 942fae0..c2506b5 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -2865,11 +2865,11 @@
 	 *				for this device.
 	 *		phy		The address of the PHY to be queried.
 	 *		reg		The register whose contents are to be
-	 *				retreived.
+	 *				retrieved.
 	 *		val		A pointer to a variable to store the
 	 *				retrieved value.
 	 *
-	 *	This function uses the TLAN's MII bus to retreive the contents
+	 *	This function uses the TLAN's MII bus to retrieve the contents
 	 *	of a given register on a PHY.  It sends the appropriate info
 	 *	and then reads the 16-bit register value from the MII bus via
 	 *	the TLAN SIO register.
diff --git a/drivers/net/wan/.gitignore b/drivers/net/wan/.gitignore
new file mode 100644
index 0000000..dae3ea6
--- /dev/null
+++ b/drivers/net/wan/.gitignore
@@ -0,0 +1 @@
+wanxlfw.inc
diff --git a/drivers/net/wan/lmc/lmc_prot.h b/drivers/net/wan/lmc/lmc_prot.h
deleted file mode 100644
index f3b1df9..0000000
--- a/drivers/net/wan/lmc/lmc_prot.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _LMC_PROTO_H_
-#define _LMC_PROTO_H_
-
-void lmc_proto_init(lmc_softc_t * const)
-void lmc_proto_attach(lmc_softc_t *sc const)
-void lmc_proto_detach(lmc_softc *sc const)
-void lmc_proto_reopen(lmc_softc_t *sc const)
-int lmc_proto_ioctl(lmc_softc_t *sc const, struct ifreq *ifr, int cmd)
-void lmc_proto_open(lmc_softc_t *sc const)
-void lmc_proto_close(lmc_softc_t *sc const)
-unsigned short lmc_proto_type(lmc_softc_t *sc const, struct skbuff *skb)
-
-
-#endif
-
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 036adc4..22e7940 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -329,9 +329,9 @@
 
 struct _dlci_stat 
 {
-	short dlci		__attribute__((packed));
-	char  flags		__attribute__((packed));
-};
+	short dlci;
+	char  flags;
+} __attribute__((packed));
 
 struct _frad_stat 
 {
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 00e5516..24f7967 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -173,7 +173,7 @@
 	  promiscuous mode via the Wireless Tool's Monitor mode.  While in this
 	  mode, no packets can be sent.
 
-config IPW_DEBUG
+config IPW2100_DEBUG
 	bool "Enable full debugging output in IPW2100 module."
 	depends on IPW2100
 	---help---
@@ -192,7 +192,7 @@
 
 config IPW2200
 	tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
-	depends on IEEE80211 && PCI
+	depends on NET_RADIO && IEEE80211 && PCI
 	select FW_LOADER
 	---help---
           A driver for the Intel PRO/Wireless 2200BG and 2915ABG Network
@@ -217,7 +217,7 @@
           say M here and read <file:Documentation/modules.txt>.  The module
           will be called ipw2200.ko.
 
-config IPW_DEBUG
+config IPW2200_DEBUG
 	bool "Enable full debugging output in IPW2200 module."
 	depends on IPW2200
 	---help---
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 340ab4e..ee866fd 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2755,8 +2755,8 @@
 	SET_NETDEV_DEV(dev, dmdev);
 
 
-	if (test_bit(FLAG_MPI,&ai->flags))
-		reset_card (dev, 1);
+	reset_card (dev, 1);
+	msleep(400);
 
 	rc = request_irq( dev->irq, airo_interrupt, SA_SHIRQ, dev->name, dev );
 	if (rc) {
@@ -4037,7 +4037,7 @@
 		Cmd cmd;
 		Resp rsp;
 
-		if (test_bit(FLAG_ENABLED, &ai->flags))
+		if (test_bit(FLAG_ENABLED, &ai->flags) && (RID_WEP_TEMP != rid))
 			printk(KERN_ERR
 				"%s: MAC should be disabled (rid=%04x)\n",
 				__FUNCTION__, rid);
@@ -5093,9 +5093,9 @@
 		printk(KERN_INFO "Setting key %d\n", index);
 	}
 
-	disable_MAC(ai, lock);
+	if (perm) disable_MAC(ai, lock);
 	writeWepKeyRid(ai, &wkr, perm, lock);
-	enable_MAC(ai, &rsp, lock);
+	if (perm) enable_MAC(ai, &rsp, lock);
 	return 0;
 }
 
@@ -6170,6 +6170,8 @@
 {
 	struct airo_info *local = dev->priv;
 	CapabilityRid cap_rid;		/* Card capability info */
+	int perm = ( dwrq->flags & IW_ENCODE_TEMP ? 0 : 1 );
+	u16 currentAuthType = local->config.authType;
 
 	/* Is WEP supported ? */
 	readCapabilityRid(local, &cap_rid, 1);
@@ -6212,7 +6214,7 @@
 			/* Copy the key in the driver */
 			memcpy(key.key, extra, dwrq->length);
 			/* Send the key to the card */
-			set_wep_key(local, index, key.key, key.len, 1, 1);
+			set_wep_key(local, index, key.key, key.len, perm, 1);
 		}
 		/* WE specify that if a valid key is set, encryption
 		 * should be enabled (user may turn it off later)
@@ -6220,13 +6222,12 @@
 		if((index == current_index) && (key.len > 0) &&
 		   (local->config.authType == AUTH_OPEN)) {
 			local->config.authType = AUTH_ENCRYPT;
-			set_bit (FLAG_COMMIT, &local->flags);
 		}
 	} else {
 		/* Do we want to just set the transmit key index ? */
 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 		if ((index >= 0) && (index < ((cap_rid.softCap & 0x80)?4:1))) {
-			set_wep_key(local, index, NULL, 0, 1, 1);
+			set_wep_key(local, index, NULL, 0, perm, 1);
 		} else
 			/* Don't complain if only change the mode */
 			if(!dwrq->flags & IW_ENCODE_MODE) {
@@ -6241,7 +6242,7 @@
 	if(dwrq->flags & IW_ENCODE_OPEN)
 		local->config.authType = AUTH_ENCRYPT;	// Only Wep
 	/* Commit the changes to flags if needed */
-	if(dwrq->flags & IW_ENCODE_MODE)
+	if (local->config.authType != currentAuthType)
 		set_bit (FLAG_COMMIT, &local->flags);
 	return -EINPROGRESS;		/* Call commit handler */
 }
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index e328547..a496460 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -82,8 +82,6 @@
 
 static void airo_config(dev_link_t *link);
 static void airo_release(dev_link_t *link);
-static int airo_event(event_t event, int priority,
-		       event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -91,8 +89,7 @@
    needed to manage one actual PCMCIA card.
 */
 
-static dev_link_t *airo_attach(void);
-static void airo_detach(dev_link_t *);
+static void airo_detach(struct pcmcia_device *p_dev);
 
 /*
    You'll also need to prototype all the functions that will actually
@@ -102,14 +99,6 @@
 */
 
 /*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "airo_cs";
-
-/*
    A linked list of "instances" of the  aironet device.  Each actual
    PCMCIA card corresponds to one device instance, and is described
    by one dev_link_t structure (defined in ds.h).
@@ -119,15 +108,7 @@
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -160,20 +141,18 @@
   
   ======================================================================*/
 
-static dev_link_t *airo_attach(void)
+static int airo_attach(struct pcmcia_device *p_dev)
 {
-	client_reg_t client_reg;
 	dev_link_t *link;
 	local_info_t *local;
-	int ret;
-	
+
 	DEBUG(0, "airo_attach()\n");
 
 	/* Initialize the dev_link_t structure */
 	link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
 	if (!link) {
 		printk(KERN_ERR "airo_cs: no memory for new device\n");
-		return NULL;
+		return -ENOMEM;
 	}
 	
 	/* Interrupt setup */
@@ -197,24 +176,17 @@
 	if (!local) {
 		printk(KERN_ERR "airo_cs: no memory for new device\n");
 		kfree (link);
-		return NULL;
+		return -ENOMEM;
 	}
 	link->priv = local;
-	
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		airo_detach(link);
-		return NULL;
-	}
-	
-	return link;
+
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	airo_config(link);
+
+	return 0;
 } /* airo_attach */
 
 /*======================================================================
@@ -226,37 +198,22 @@
   
   ======================================================================*/
 
-static void airo_detach(dev_link_t *link)
+static void airo_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
-	
+	dev_link_t *link = dev_to_instance(p_dev);
+
 	DEBUG(0, "airo_detach(0x%p)\n", link);
-	
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link) break;
-	if (*linkp == NULL)
-		return;
-	
+
 	if (link->state & DEV_CONFIG)
 		airo_release(link);
-	
+
 	if ( ((local_info_t*)link->priv)->eth_dev ) {
 		stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
 	}
-	((local_info_t*)link->priv)->eth_dev = NULL;   
-	
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-	
-	
-	
-	/* Unlink device structure, free pieces */
-	*linkp = link->next;
+	((local_info_t*)link->priv)->eth_dev = NULL;
+
 	kfree(link->priv);
 	kfree(link);
-	
 } /* airo_detach */
 
 /*======================================================================
@@ -492,60 +449,34 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
-  
-  The card status event handler.  Mostly, this schedules other
-  stuff to run after an event is received.
-
-  When a CARD_REMOVAL event is received, we immediately set a
-  private flag to block future accesses to this device.  All the
-  functions that actually access the device should check this flag
-  to make sure the card is still present.
-  
-  ======================================================================*/
-
-static int airo_event(event_t event, int priority,
-		      event_callback_args_t *args)
+static int airo_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	local_info_t *local = link->priv;
-	
-	DEBUG(1, "airo_event(0x%06x)\n", event);
-	
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			netif_device_detach(local->eth_dev);
-			airo_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		airo_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG) {
-			netif_device_detach(local->eth_dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			reset_airo_card(local->eth_dev);
-			netif_device_attach(local->eth_dev);
-		}
-		break;
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		netif_device_detach(local->eth_dev);
+		pcmcia_release_configuration(link->handle);
 	}
+
 	return 0;
-} /* airo_event */
+}
+
+static int airo_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	local_info_t *local = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		reset_airo_card(local->eth_dev);
+		netif_device_attach(local->eth_dev);
+	}
+
+	return 0;
+}
 
 static struct pcmcia_device_id airo_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a),
@@ -561,10 +492,11 @@
 	.drv		= {
 		.name	= "airo_cs",
 	},
-	.attach		= airo_attach,
-	.event		= airo_event,
-	.detach		= airo_detach,
+	.probe		= airo_attach,
+	.remove		= airo_detach,
 	.id_table       = airo_ids,
+	.suspend	= airo_suspend,
+	.resume		= airo_resume,
 };
 
 static int airo_cs_init(void)
@@ -575,7 +507,6 @@
 static void airo_cs_cleanup(void)
 {
 	pcmcia_unregister_driver(&airo_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 /*
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 5e53c52..e4729dd 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -5,9 +5,9 @@
         Copyright 2000-2001 ATMEL Corporation.
         Copyright 2003-2004 Simon Kelley.
 
-    This code was developed from version 2.1.1 of the Atmel drivers, 
-    released by Atmel corp. under the GPL in December 2002. It also 
-    includes code from the Linux aironet drivers (C) Benjamin Reed, 
+    This code was developed from version 2.1.1 of the Atmel drivers,
+    released by Atmel corp. under the GPL in December 2002. It also
+    includes code from the Linux aironet drivers (C) Benjamin Reed,
     and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
     extensions, (C) Jean Tourrilhes.
 
@@ -31,7 +31,7 @@
     along with Atmel wireless lan drivers; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-    For all queries about this code, please contact the current author, 
+    For all queries about this code, please contact the current author,
     Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
 
     Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
@@ -79,13 +79,13 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
 
-/* The name of the firmware file to be loaded 
+/* The name of the firmware file to be loaded
    over-rides any automatic selection */
 static char *firmware = NULL;
 module_param(firmware, charp, 0);
 
 /* table of firmware file names */
-static struct { 
+static struct {
 	AtmelFWType fw_type;
 	const char *fw_file;
 	const char *fw_file_ext;
@@ -104,17 +104,17 @@
 #define MAX_SSID_LENGTH 32
 #define MGMT_JIFFIES (256 * HZ / 100)
 
-#define MAX_BSS_ENTRIES	64	
+#define MAX_BSS_ENTRIES	64
 
 /* registers */
-#define GCR  0x00    //      (SIR0)  General Configuration Register        
-#define BSR  0x02    //      (SIR1)  Bank Switching Select Register 
+#define GCR  0x00    //      (SIR0)  General Configuration Register
+#define BSR  0x02    //      (SIR1)  Bank Switching Select Register
 #define AR   0x04
 #define DR   0x08
-#define MR1  0x12    //      Mirror Register 1                  
-#define MR2  0x14    //      Mirror Register 2  
-#define MR3  0x16    //      Mirror Register 3  
-#define MR4  0x18    //      Mirror Register 4   
+#define MR1  0x12    //      Mirror Register 1
+#define MR2  0x14    //      Mirror Register 2
+#define MR3  0x16    //      Mirror Register 3
+#define MR4  0x18    //      Mirror Register 4
 
 #define GPR1                            0x0c
 #define GPR2                            0x0e
@@ -123,9 +123,9 @@
 // Constants for the GCR register.
 //
 #define GCR_REMAP     0x0400          // Remap internal SRAM to 0
-#define GCR_SWRES     0x0080          // BIU reset (ARM and PAI are NOT reset) 
+#define GCR_SWRES     0x0080          // BIU reset (ARM and PAI are NOT reset)
 #define GCR_CORES     0x0060          // Core Reset (ARM and PAI are reset)
-#define GCR_ENINT     0x0002          // Enable Interrupts    
+#define GCR_ENINT     0x0002          // Enable Interrupts
 #define GCR_ACKINT    0x0008          // Acknowledge Interrupts
 
 #define BSS_SRAM      0x0200          // AMBA module selection --> SRAM
@@ -190,7 +190,7 @@
         u32          Next;
         u16          MsduPos;
         u16          MsduSize;
-	
+
         u8           State;
         u8           Status;
         u8           Rate;
@@ -199,7 +199,6 @@
         u8           PreambleType;
         u16          Duration;
         u32          RxTime;
-
 };
 
 #define RX_DESC_FLAG_VALID       0x80
@@ -218,16 +217,15 @@
 #define RX_DESC_DURATION_OFFSET      14
 #define RX_DESC_RX_TIME_OFFSET       16
 
-
 struct tx_desc {
 	u32       NextDescriptor;
 	u16       TxStartOfFrame;
 	u16       TxLength;
-	
+
 	u8        TxState;
 	u8        TxStatus;
 	u8        RetryCount;
-	
+
 	u8        TxRate;
 
 	u8        KeyIndex;
@@ -238,10 +236,8 @@
 	u8        Reserved;
 	u8        PacketType;
 	u16       HostTxLength;
-	
 };
 
-
 #define TX_DESC_NEXT_OFFSET          0
 #define TX_DESC_POS_OFFSET           4
 #define TX_DESC_SIZE_OFFSET          6
@@ -255,8 +251,6 @@
 #define TX_DESC_PACKET_TYPE_OFFSET   17
 #define TX_DESC_HOST_LENGTH_OFFSET   18
 
-
-
 ///////////////////////////////////////////////////////
 // Host-MAC interface
 ///////////////////////////////////////////////////////
@@ -266,7 +260,6 @@
 #define TX_FIRM_OWN             0x80
 #define TX_DONE                 0x40
 
-
 #define TX_ERROR                0x01
 
 #define TX_PACKET_TYPE_DATA     0x01
@@ -280,8 +273,7 @@
 #define ISR_COMMAND_COMPLETE    0x10        // command completed
 #define ISR_OUT_OF_RANGE        0x20        // command completed
 #define ISR_IBSS_MERGE          0x40        // (4.1.2.30): IBSS merge
-#define ISR_GENERIC_IRQ         0x80                
-
+#define ISR_GENERIC_IRQ         0x80
 
 #define Local_Mib_Type          0x01
 #define Mac_Address_Mib_Type    0x02
@@ -317,7 +309,6 @@
 #define LOCAL_MIB_PREAMBLE_TYPE               9
 #define MAC_ADDR_MIB_MAC_ADDR_POS             0
 
-
 #define         CMD_Set_MIB_Vars              0x01
 #define         CMD_Get_MIB_Vars              0x02
 #define         CMD_Scan                      0x03
@@ -338,7 +329,6 @@
 #define         CMD_STATUS_HOST_ERROR             0xFF
 #define         CMD_STATUS_BUSY                   0xFE
 
-
 #define CMD_BLOCK_COMMAND_OFFSET        0
 #define CMD_BLOCK_STATUS_OFFSET         1
 #define CMD_BLOCK_PARAMETERS_OFFSET     4
@@ -347,15 +337,15 @@
 
 #define MGMT_FRAME_BODY_OFFSET		24
 #define MAX_AUTHENTICATION_RETRIES	3
-#define MAX_ASSOCIATION_RETRIES 	3
+#define MAX_ASSOCIATION_RETRIES		3
 
 #define AUTHENTICATION_RESPONSE_TIME_OUT  1000
 
 #define MAX_WIRELESS_BODY  2316 /* mtu is 2312, CRC is 4 */
 #define LOOP_RETRY_LIMIT   500000
 
-#define ACTIVE_MODE 	1
-#define PS_MODE 	2
+#define ACTIVE_MODE	1
+#define PS_MODE		2
 
 #define MAX_ENCRYPTION_KEYS 4
 #define MAX_ENCRYPTION_KEY_SIZE 40
@@ -377,7 +367,7 @@
 #define REG_DOMAIN_MKK1		0x41	//Channel	1-14	Japan(MKK1)
 #define REG_DOMAIN_ISRAEL	0x50	//Channel	3-9	ISRAEL
 
-#define BSS_TYPE_AD_HOC 	1
+#define BSS_TYPE_AD_HOC		1
 #define BSS_TYPE_INFRASTRUCTURE 2
 
 #define SCAN_TYPE_ACTIVE	0
@@ -389,7 +379,7 @@
 
 #define DATA_FRAME_WS_HEADER_SIZE   30
 
-/* promiscuous mode control */ 
+/* promiscuous mode control */
 #define PROM_MODE_OFF			0x0
 #define PROM_MODE_UNKNOWN		0x1
 #define PROM_MODE_CRC_FAILED		0x2
@@ -398,8 +388,7 @@
 #define PROM_MODE_CTRL			0x10
 #define PROM_MODE_BAD_PROTOCOL		0x20
 
-
-#define IFACE_INT_STATUS_OFFSET 	0
+#define IFACE_INT_STATUS_OFFSET		0
 #define IFACE_INT_MASK_OFFSET		1
 #define IFACE_LOCKOUT_HOST_OFFSET	2
 #define IFACE_LOCKOUT_MAC_OFFSET	3
@@ -407,7 +396,7 @@
 #define IFACE_MAC_STAT_OFFSET		30
 #define IFACE_GENERIC_INT_TYPE_OFFSET	32
 
-#define CIPHER_SUITE_NONE     0 
+#define CIPHER_SUITE_NONE     0
 #define CIPHER_SUITE_WEP_64   1
 #define CIPHER_SUITE_TKIP     2
 #define CIPHER_SUITE_AES      3
@@ -419,11 +408,11 @@
 //
 //
 
-// FuncCtrl field: 
+// FuncCtrl field:
 //
 #define FUNC_CTRL_TxENABLE		0x10
 #define FUNC_CTRL_RxENABLE		0x20
-#define FUNC_CTRL_INIT_COMPLETE 	0x01
+#define FUNC_CTRL_INIT_COMPLETE		0x01
 
 /* A stub firmware image which reads the MAC address from NVRAM on the card.
    For copyright information and source see the end of this file. */
@@ -486,10 +475,10 @@
 	struct net_device_stats	stats;	// device stats
 	spinlock_t irqlock, timerlock;	// spinlocks
 	enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
-	enum { 
-		CARD_TYPE_PARALLEL_FLASH, 
+	enum {
+		CARD_TYPE_PARALLEL_FLASH,
 		CARD_TYPE_SPI_FLASH,
-		CARD_TYPE_EEPROM 
+		CARD_TYPE_EEPROM
 	} card_type;
 	int do_rx_crc; /* If we need to CRC incoming packets */
 	int probe_crc; /* set if we don't yet know */
@@ -497,18 +486,18 @@
 	u16 rx_desc_head;
 	u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
 	u16 tx_free_mem, tx_buff_head, tx_buff_tail;
-	
+
 	u16 frag_seq, frag_len, frag_no;
-	u8 frag_source[6]; 
-	
+	u8 frag_source[6];
+
 	u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
 	u8 group_cipher_suite, pairwise_cipher_suite;
 	u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
-	int wep_key_len[MAX_ENCRYPTION_KEYS]; 
+	int wep_key_len[MAX_ENCRYPTION_KEYS];
 	int use_wpa, radio_on_broken; /* firmware dependent stuff. */
 
 	u16 host_info_base;
-	struct host_info_struct { 
+	struct host_info_struct {
 		/* NB this is matched to the hardware, don't change. */
 		u8 volatile int_status;
 		u8 volatile int_mask;
@@ -524,20 +513,20 @@
 		u16 rx_buff_size;
 		u16 rx_desc_pos;
 		u16 rx_desc_count;
-		
+
 		u16 build_version;
-		u16 command_pos; 	
-		
+		u16 command_pos;
+
 		u16 major_version;
 		u16 minor_version;
-		
+
 		u16 func_ctrl;
 		u16 mac_status;
 		u16 generic_IRQ_type;
 		u8  reserved[2];
 	} host_info;
 
-	enum { 
+	enum {
 		STATION_STATE_SCANNING,
 		STATION_STATE_JOINNING,
 		STATION_STATE_AUTHENTICATING,
@@ -547,7 +536,7 @@
 		STATION_STATE_DOWN,
 		STATION_STATE_MGMT_ERROR
 	} station_state;
-	
+
 	int operating_mode, power_mode;
 	time_t last_qual;
 	int beacons_this_sec;
@@ -560,18 +549,18 @@
 	int long_retry, short_retry;
 	int preamble;
 	int default_beacon_period, beacon_period, listen_interval;
-	int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;	
+	int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
 	int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
 	enum {
 		SITE_SURVEY_IDLE,
 		SITE_SURVEY_IN_PROGRESS,
-		SITE_SURVEY_COMPLETED 
+		SITE_SURVEY_COMPLETED
 	} site_survey_state;
 	time_t last_survey;
 
 	int station_was_associated, station_is_associated;
 	int fast_scan;
-				
+
 	struct bss_info {
 		int channel;
 		int SSIDsize;
@@ -584,13 +573,12 @@
 		u8 SSID[MAX_SSID_LENGTH];
 	} BSSinfo[MAX_BSS_ENTRIES];
 	int BSS_list_entries, current_BSS;
-	int connect_to_any_BSS; 
+	int connect_to_any_BSS;
 	int SSID_size, new_SSID_size;
 	u8 CurrentBSSID[6], BSSID[6];
 	u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
 	u64 last_beacon_timestamp;
 	u8 rx_buf[MAX_WIRELESS_BODY];
-	
 };
 
 static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
@@ -598,39 +586,49 @@
 static const struct {
 	int reg_domain;
 	int min, max;
-	char *name; 
+	char *name;
 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
 		      { REG_DOMAIN_DOC, 1, 11, "Canada" },
 		      { REG_DOMAIN_ETSI, 1, 13, "Europe" },
 		      { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
-		      { REG_DOMAIN_FRANCE, 10, 13, "France" }, 
+		      { REG_DOMAIN_FRANCE, 10, 13, "France" },
 		      { REG_DOMAIN_MKK, 14, 14, "MKK" },
 		      { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
 		      { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
 
 static void build_wpa_mib(struct atmel_private *priv);
 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len);
-static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len);
+static void atmel_copy_to_card(struct net_device *dev, u16 dest,
+			       unsigned char *src, u16 len);
+static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
+			       u16 src, u16 len);
 static void atmel_set_gcr(struct net_device *dev, u16 mask);
 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
 static int atmel_lock_mac(struct atmel_private *priv);
 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
 static void atmel_command_irq(struct atmel_private *priv);
 static int atmel_validate_channel(struct atmel_private *priv, int channel);
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+static void atmel_management_frame(struct atmel_private *priv,
+				   struct ieee80211_hdr_4addr *header,
 				   u16 frame_len, u8 rssi);
 static void atmel_management_timer(u_long a);
-static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
+static void atmel_send_command(struct atmel_private *priv, int command,
+			       void *cmd, int cmd_size);
+static int atmel_send_command_wait(struct atmel_private *priv, int command,
+				   void *cmd, int cmd_size);
+static void atmel_transmit_management_frame(struct atmel_private *priv,
+					    struct ieee80211_hdr_4addr *header,
 					    u8 *body, int body_len);
 
 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
-static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data);
-static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data);
-static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
-static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
+static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index,
+			   u8 data);
+static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
+			    u16 data);
+static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
+			  u8 *data, int data_len);
+static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
+			  u8 *data, int data_len);
 static void atmel_scan(struct atmel_private *priv, int specific_ssid);
 static void atmel_join_bss(struct atmel_private *priv, int bss_index);
 static void atmel_smooth_qual(struct atmel_private *priv);
@@ -650,12 +648,12 @@
 	return priv->host_info.command_pos + offset;
 }
 
-static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16  desc)
+static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
 {
 	return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
 }
 
-static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16  desc)
+static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
 {
 	return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
 }
@@ -682,25 +680,25 @@
 
 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
 {
-	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	return atmel_read8(priv->dev, DR);
 }
 
 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
 {
-	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	atmel_write8(priv->dev, DR, data);
 }
 
 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
 {
-       	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	return atmel_read16(priv->dev, DR);
 }
 
 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
 {
-       	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	atmel_write16(priv->dev, DR, data);
 }
 
@@ -710,11 +708,10 @@
 {
 	int i;
 
-	for (i = 0; 
+	for (i = 0;
 	     atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
 		     i < priv->host_info.tx_desc_count;
 	     i++) {
-		
 		u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
 		u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
 		u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
@@ -728,16 +725,16 @@
 			priv->tx_buff_head = 0;
 		else
 			priv->tx_buff_head += msdu_size;
-			
+
 		if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
-			priv->tx_desc_head++ ;					
+			priv->tx_desc_head++ ;
 		else
 			priv->tx_desc_head = 0;
-		
+
 		if (type == TX_PACKET_TYPE_DATA) {
 			if (status == TX_STATUS_SUCCESS)
 				priv->stats.tx_packets++;
-			else 
+			else
 				priv->stats.tx_errors++;
 			netif_wake_queue(priv->dev);
 		}
@@ -748,21 +745,22 @@
 {
 	u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
 
-	if (priv->tx_desc_free == 3 || priv->tx_free_mem < len) 
+	if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
 		return 0;
-	
+
 	if (bottom_free >= len)
 		return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
-	
+
 	if (priv->tx_free_mem - bottom_free >= len) {
 		priv->tx_buff_tail = 0;
 		return priv->host_info.tx_buff_pos;
 	}
-	
+
 	return 0;
 }
 
-static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, u16 len, u16 buff, u8 type)
+static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
+				 u16 len, u16 buff, u8 type)
 {
 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
@@ -775,8 +773,8 @@
 		int cipher_type, cipher_length;
 		if (is_bcast) {
 			cipher_type = priv->group_cipher_suite;
-			if (cipher_type == CIPHER_SUITE_WEP_64 || 
-			    cipher_type == CIPHER_SUITE_WEP_128 )
+			if (cipher_type == CIPHER_SUITE_WEP_64 ||
+			    cipher_type == CIPHER_SUITE_WEP_128)
 				cipher_length = 8;
 			else if (cipher_type == CIPHER_SUITE_TKIP)
 				cipher_length = 12;
@@ -790,8 +788,8 @@
 			}
 		} else {
 			cipher_type = priv->pairwise_cipher_suite;
-			if (cipher_type == CIPHER_SUITE_WEP_64 || 
-			    cipher_type == CIPHER_SUITE_WEP_128 )
+			if (cipher_type == CIPHER_SUITE_WEP_64 ||
+			    cipher_type == CIPHER_SUITE_WEP_128)
 				cipher_length = 8;
 			else if (cipher_type == CIPHER_SUITE_TKIP)
 				cipher_length = 12;
@@ -804,9 +802,9 @@
 				cipher_length = 0;
 			}
 		}
-		
+
 		atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
-			    cipher_type);	
+			    cipher_type);
 		atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
 			    cipher_length);
 	}
@@ -815,46 +813,46 @@
 	if (priv->tx_desc_previous != priv->tx_desc_tail)
 		atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
 	priv->tx_desc_previous = priv->tx_desc_tail;
-	if (priv->tx_desc_tail < (priv->host_info.tx_desc_count -1 ))
+	if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1))
 		priv->tx_desc_tail++;
 	else
 		priv->tx_desc_tail = 0;
 	priv->tx_desc_free--;
 	priv->tx_free_mem -= len;
-
 }
 
-static int start_tx (struct sk_buff *skb, struct net_device *dev)
+static int start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	struct ieee80211_hdr_4addr header;
 	unsigned long flags;
 	u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
 	u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
- 
-	if (priv->card && priv->present_callback && 
+
+	if (priv->card && priv->present_callback &&
 	    !(*priv->present_callback)(priv->card)) {
 		priv->stats.tx_errors++;
 		dev_kfree_skb(skb);
 		return 0;
 	}
-	
+
 	if (priv->station_state != STATION_STATE_READY) {
 		priv->stats.tx_errors++;
 		dev_kfree_skb(skb);
 		return 0;
 	}
-	
+
 	/* first ensure the timer func cannot run */
-	spin_lock_bh(&priv->timerlock); 
+	spin_lock_bh(&priv->timerlock);
 	/* then stop the hardware ISR */
-	spin_lock_irqsave(&priv->irqlock, flags); 
+	spin_lock_irqsave(&priv->irqlock, flags);
 	/* nb doing the above in the opposite order will deadlock */
-	
+
 	/* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
-	   12 first bytes (containing DA/SA) and put them in the appropriate fields of
-	   the Wireless Header. Thus the packet length is then the initial + 18 (+30-12) */
-	
+	   12 first bytes (containing DA/SA) and put them in the appropriate
+	   fields of the Wireless Header. Thus the packet length is then the
+	   initial + 18 (+30-12) */
+
 	if (!(buff = find_tx_buff(priv, len + 18))) {
 		priv->stats.tx_dropped++;
 		spin_unlock_irqrestore(&priv->irqlock, flags);
@@ -862,7 +860,7 @@
 		netif_stop_queue(dev);
 		return 1;
 	}
-	
+
 	frame_ctl = IEEE80211_FTYPE_DATA;
 	header.duration_id = 0;
 	header.seq_ctl = 0;
@@ -878,7 +876,7 @@
 		memcpy(&header.addr2, dev->dev_addr, 6);
 		memcpy(&header.addr3, skb->data, 6);
 	}
-	
+
 	if (priv->use_wpa)
 		memcpy(&header.addr4, SNAP_RFC1024, 6);
 
@@ -888,27 +886,27 @@
 	/* Copy the packet sans its 802.3 header addresses which have been replaced */
 	atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
 	priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
-	
+
 	/* low bit of first byte of destination tells us if broadcast */
 	tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
 	dev->trans_start = jiffies;
 	priv->stats.tx_bytes += len;
-	
+
 	spin_unlock_irqrestore(&priv->irqlock, flags);
 	spin_unlock_bh(&priv->timerlock);
 	dev_kfree_skb(skb);
-	
-	return 0;	
+
+	return 0;
 }
 
-static void atmel_transmit_management_frame(struct atmel_private *priv, 
+static void atmel_transmit_management_frame(struct atmel_private *priv,
 					    struct ieee80211_hdr_4addr *header,
 					    u8 *body, int body_len)
 {
 	u16 buff;
-	int len =  MGMT_FRAME_BODY_OFFSET + body_len;
-	
-	if (!(buff = find_tx_buff(priv, len))) 
+	int len = MGMT_FRAME_BODY_OFFSET + body_len;
+
+	if (!(buff = find_tx_buff(priv, len)))
 		return;
 
 	atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
@@ -916,24 +914,25 @@
 	priv->tx_buff_tail += len;
 	tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
 }
-	
-static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
+
+static void fast_rx_path(struct atmel_private *priv,
+			 struct ieee80211_hdr_4addr *header,
 			 u16 msdu_size, u16 rx_packet_loc, u32 crc)
 {
 	/* fast path: unfragmented packet copy directly into skbuf */
-	u8 mac4[6]; 
-	struct sk_buff 	*skb;
+	u8 mac4[6];
+	struct sk_buff	*skb;
 	unsigned char *skbp;
-	
+
 	/* get the final, mac 4 header field, this tells us encapsulation */
 	atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
 	msdu_size -= 6;
-	
+
 	if (priv->do_rx_crc) {
 		crc = crc32_le(crc, mac4, 6);
 		msdu_size -= 4;
 	}
-	
+
 	if (!(skb = dev_alloc_skb(msdu_size + 14))) {
 		priv->stats.rx_dropped++;
 		return;
@@ -942,7 +941,7 @@
 	skb_reserve(skb, 2);
 	skbp = skb_put(skb, msdu_size + 12);
 	atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
-	
+
 	if (priv->do_rx_crc) {
 		u32 netcrc;
 		crc = crc32_le(crc, skbp + 12, msdu_size);
@@ -953,24 +952,25 @@
 			return;
 		}
 	}
-	
+
 	memcpy(skbp, header->addr1, 6); /* destination address */
-	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS) 
+	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
 		memcpy(&skbp[6], header->addr3, 6);
 	else
 		memcpy(&skbp[6], header->addr2, 6); /* source address */
-	
-	priv->dev->last_rx=jiffies;
+
+	priv->dev->last_rx = jiffies;
 	skb->dev = priv->dev;
 	skb->protocol = eth_type_trans(skb, priv->dev);
-	skb->ip_summed = CHECKSUM_NONE;	
+	skb->ip_summed = CHECKSUM_NONE;
 	netif_rx(skb);
 	priv->stats.rx_bytes += 12 + msdu_size;
 	priv->stats.rx_packets++;
 }
 
 /* Test to see if the packet in card memory at packet_loc has a valid CRC
-   It doesn't matter that this is slow: it is only used to proble the first few packets. */
+   It doesn't matter that this is slow: it is only used to proble the first few
+   packets. */
 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
 {
 	int i = msdu_size - 4;
@@ -980,7 +980,7 @@
 		return 0;
 
 	atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
-	
+
 	atmel_writeAR(priv->dev, packet_loc);
 	while (i--) {
 		u8 octet = atmel_read8(priv->dev, DR);
@@ -990,20 +990,22 @@
 	return (crc ^ 0xffffffff) == netcrc;
 }
 
-static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
-			 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
+static void frag_rx_path(struct atmel_private *priv,
+			 struct ieee80211_hdr_4addr *header,
+			 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
+			 u8 frag_no, int more_frags)
 {
-	u8 mac4[6]; 
+	u8 mac4[6];
 	u8 source[6];
 	struct sk_buff *skb;
 
-	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS) 
+	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
 		memcpy(source, header->addr3, 6);
 	else
-		memcpy(source, header->addr2, 6); 
-	
+		memcpy(source, header->addr2, 6);
+
 	rx_packet_loc += 24; /* skip header */
-	
+
 	if (priv->do_rx_crc)
 		msdu_size -= 4;
 
@@ -1012,16 +1014,16 @@
 		msdu_size -= 6;
 		rx_packet_loc += 6;
 
-		if (priv->do_rx_crc) 
+		if (priv->do_rx_crc)
 			crc = crc32_le(crc, mac4, 6);
-	       
+
 		priv->frag_seq = seq_no;
 		priv->frag_no = 1;
 		priv->frag_len = msdu_size;
-		memcpy(priv->frag_source, source, 6); 
+		memcpy(priv->frag_source, source, 6);
 		memcpy(&priv->rx_buf[6], source, 6);
 		memcpy(priv->rx_buf, header->addr1, 6);
-				
+
 		atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
 
 		if (priv->do_rx_crc) {
@@ -1033,17 +1035,17 @@
 				memset(priv->frag_source, 0xff, 6);
 			}
 		}
-		
+
 	} else if (priv->frag_no == frag_no &&
 		   priv->frag_seq == seq_no &&
 		   memcmp(priv->frag_source, source, 6) == 0) {
-		
-		atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len], 
+
+		atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
 				   rx_packet_loc, msdu_size);
 		if (priv->do_rx_crc) {
 			u32 netcrc;
-			crc = crc32_le(crc, 
-				       &priv->rx_buf[12 + priv->frag_len], 
+			crc = crc32_le(crc,
+				       &priv->rx_buf[12 + priv->frag_len],
 				       msdu_size);
 			atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
 			if ((crc ^ 0xffffffff) != netcrc) {
@@ -1052,7 +1054,7 @@
 				more_frags = 1; /* don't send broken assembly */
 			}
 		}
-		
+
 		priv->frag_len += msdu_size;
 		priv->frag_no++;
 
@@ -1062,60 +1064,60 @@
 				priv->stats.rx_dropped++;
 			} else {
 				skb_reserve(skb, 2);
-				memcpy(skb_put(skb, priv->frag_len + 12), 
+				memcpy(skb_put(skb, priv->frag_len + 12),
 				       priv->rx_buf,
 				       priv->frag_len + 12);
 				priv->dev->last_rx = jiffies;
 				skb->dev = priv->dev;
 				skb->protocol = eth_type_trans(skb, priv->dev);
-				skb->ip_summed = CHECKSUM_NONE;	
+				skb->ip_summed = CHECKSUM_NONE;
 				netif_rx(skb);
 				priv->stats.rx_bytes += priv->frag_len + 12;
 				priv->stats.rx_packets++;
 			}
 		}
-		
 	} else
 		priv->wstats.discard.fragment++;
 }
-		
+
 static void rx_done_irq(struct atmel_private *priv)
 {
 	int i;
 	struct ieee80211_hdr_4addr header;
-	
-	for (i = 0; 
+
+	for (i = 0;
 	     atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
 		     i < priv->host_info.rx_desc_count;
 	     i++) {
-				
+
 		u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
 		u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
 		u32 crc = 0xffffffff;
-		
+
 		if (status != RX_STATUS_SUCCESS) {
 			if (status == 0xc1) /* determined by experiment */
 				priv->wstats.discard.nwid++;
 			else
-				priv->stats.rx_errors++; 
+				priv->stats.rx_errors++;
 			goto next;
 		}
 
 		msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
 		rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
-		
+
 		if (msdu_size < 30) {
-			priv->stats.rx_errors++; 
+			priv->stats.rx_errors++;
 			goto next;
 		}
-		
+
 		/* Get header as far as end of seq_ctl */
 		atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
 		frame_ctl = le16_to_cpu(header.frame_ctl);
 		seq_control = le16_to_cpu(header.seq_ctl);
 
-		/* probe for CRC use here if needed  once five packets have arrived with
-		   the same crc status, we assume we know what's happening and stop probing */
+		/* probe for CRC use here if needed  once five packets have
+		   arrived with the same crc status, we assume we know what's
+		   happening and stop probing */
 		if (priv->probe_crc) {
 			if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
 				priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
@@ -1130,34 +1132,33 @@
 					priv->probe_crc = 0;
 			}
 		}
-		    
+
 		/* don't CRC header when WEP in use */
 		if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
 			crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
 		}
 		msdu_size -= 24; /* header */
 
-		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { 
-			
+		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
 			int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
 			u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
 			u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
-			
-			if (!more_fragments && packet_fragment_no == 0 ) {
+
+			if (!more_fragments && packet_fragment_no == 0) {
 				fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
 			} else {
 				frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
 					     packet_sequence_no, packet_fragment_no, more_fragments);
 			}
 		}
-		
+
 		if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
 			/* copy rest of packet into buffer */
 			atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
-			
+
 			/* we use the same buffer for frag reassembly and control packets */
 			memset(priv->frag_source, 0xff, 6);
-			
+
 			if (priv->do_rx_crc) {
 				/* last 4 octets is crc */
 				msdu_size -= 4;
@@ -1170,18 +1171,18 @@
 
 			atmel_management_frame(priv, &header, msdu_size,
 					       atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
-		} 
+		}
 
-	next:
+next:
 		/* release descriptor */
-		atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);  
-		
+		atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
+
 		if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
-			priv->rx_desc_head++;					
+			priv->rx_desc_head++;
 		else
 			priv->rx_desc_head = 0;
 	}
-}	
+}
 
 static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -1189,7 +1190,7 @@
 	struct atmel_private *priv = netdev_priv(dev);
 	u8 isr;
 	int i = -1;
-	static u8 irq_order[] = { 
+	static u8 irq_order[] = {
 		ISR_OUT_OF_RANGE,
 		ISR_RxCOMPLETE,
 		ISR_TxCOMPLETE,
@@ -1199,20 +1200,19 @@
 		ISR_IBSS_MERGE,
 		ISR_GENERIC_IRQ
 	};
-		
 
-	if (priv->card && priv->present_callback && 
+	if (priv->card && priv->present_callback &&
 	    !(*priv->present_callback)(priv->card))
 		return IRQ_HANDLED;
 
 	/* In this state upper-level code assumes it can mess with
 	   the card unhampered by interrupts which may change register state.
 	   Note that even though the card shouldn't generate interrupts
-	   the inturrupt line may be shared. This allows card setup 
+	   the inturrupt line may be shared. This allows card setup
 	   to go on without disabling interrupts for a long time. */
 	if (priv->station_state == STATION_STATE_DOWN)
 		return IRQ_NONE;
-     	
+
 	atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
 
 	while (1) {
@@ -1221,36 +1221,36 @@
 			printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
 			return IRQ_HANDLED;
 		}
-		
+
 		isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
-		
+
 		if (!isr) {
 			atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
 			return i == -1 ? IRQ_NONE : IRQ_HANDLED;
 		}
-		
+
 		atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
-		
+
 		for (i = 0; i < sizeof(irq_order)/sizeof(u8); i++)
 			if (isr & irq_order[i])
 				break;
-		
+
 		if (!atmel_lock_mac(priv)) {
 			/* failed to contact card */
 			printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
 			return IRQ_HANDLED;
 		}
-		
+
 		isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
 		isr ^= irq_order[i];
 		atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
-		
+
 		switch (irq_order[i]) {
-			
-		case ISR_OUT_OF_RANGE: 
-			if (priv->operating_mode == IW_MODE_INFRA && 
+
+		case ISR_OUT_OF_RANGE:
+			if (priv->operating_mode == IW_MODE_INFRA &&
 			    priv->station_state == STATION_STATE_READY) {
 				priv->station_is_associated = 0;
 				atmel_scan(priv, 1);
@@ -1261,24 +1261,24 @@
 			priv->wstats.discard.misc++;
 			/* fall through */
 		case ISR_RxCOMPLETE:
-			rx_done_irq(priv); 
+			rx_done_irq(priv);
 			break;
-			
+
 		case ISR_TxCOMPLETE:
-			tx_done_irq(priv); 
+			tx_done_irq(priv);
 			break;
-			
+
 		case ISR_FATAL_ERROR:
 			printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
 			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
 			break;
-			
-		case ISR_COMMAND_COMPLETE: 
+
+		case ISR_COMMAND_COMPLETE:
 			atmel_command_irq(priv);
 			break;
 
 		case ISR_IBSS_MERGE:
-			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS, 
+			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
 				      priv->CurrentBSSID, 6);
 			/* The WPA stuff cares about the current AP address */
 			if (priv->use_wpa)
@@ -1288,24 +1288,23 @@
 			printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
 			break;
 		}
-	}	
+	}
 }
 
-
-static struct net_device_stats *atmel_get_stats (struct net_device *dev)
+static struct net_device_stats *atmel_get_stats(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	return &priv->stats;
 }
 
-static struct iw_statistics *atmel_get_wireless_stats (struct net_device *dev)
+static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
 
-	/* update the link quality here in case we are seeing no beacons 
+	/* update the link quality here in case we are seeing no beacons
 	   at all to drive the process */
 	atmel_smooth_qual(priv);
-	
+
 	priv->wstats.status = priv->station_state;
 
 	if (priv->operating_mode == IW_MODE_INFRA) {
@@ -1328,8 +1327,8 @@
 					| IW_QUAL_NOISE_INVALID;
 		priv->wstats.miss.beacon = 0;
 	}
-	
-	return (&priv->wstats);
+
+	return &priv->wstats;
 }
 
 static int atmel_change_mtu(struct net_device *dev, int new_mtu)
@@ -1343,21 +1342,21 @@
 static int atmel_set_mac_address(struct net_device *dev, void *p)
 {
 	struct sockaddr *addr = p;
-        
+
         memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
 	return atmel_open(dev);
 }
 
 EXPORT_SYMBOL(atmel_open);
 
-int atmel_open (struct net_device *dev)
+int atmel_open(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	int i, channel;
 
 	/* any scheduled timer is no longer needed and might screw things up.. */
 	del_timer_sync(&priv->management_timer);
-	
+
 	/* Interrupts will not touch the card once in this state... */
 	priv->station_state = STATION_STATE_DOWN;
 
@@ -1377,7 +1376,7 @@
 	priv->site_survey_state = SITE_SURVEY_IDLE;
 	priv->station_is_associated = 0;
 
-	if (!reset_atmel_card(dev)) 
+	if (!reset_atmel_card(dev))
 		return -EAGAIN;
 
 	if (priv->config_reg_domain) {
@@ -1391,26 +1390,26 @@
 		if (i == sizeof(channel_table)/sizeof(channel_table[0])) {
 			priv->reg_domain = REG_DOMAIN_MKK1;
 			printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
-		} 
+		}
 	}
-	
+
 	if ((channel = atmel_validate_channel(priv, priv->channel)))
 		priv->channel = channel;
 
-	/* this moves station_state on.... */ 
-	atmel_scan(priv, 1);	
+	/* this moves station_state on.... */
+	atmel_scan(priv, 1);
 
 	atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
 	return 0;
 }
 
-static int atmel_close (struct net_device *dev)
+static int atmel_close(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-		
+
 	atmel_enter_state(priv, STATION_STATE_DOWN);
-	
-	if (priv->bus_type == BUS_TYPE_PCCARD) 
+
+	if (priv->bus_type == BUS_TYPE_PCCARD)
 		atmel_write16(dev, GCR, 0x0060);
 	atmel_write16(dev, GCR, 0x0040);
 	return 0;
@@ -1438,43 +1437,46 @@
 	int i;
 	char *p = buf;
 	char *s, *r, *c;
-	
-	p += sprintf(p, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
-	
+
+	p += sprintf(p, "Driver version:\t\t%d.%d\n",
+		     DRIVER_MAJOR, DRIVER_MINOR);
+
 	if (priv->station_state != STATION_STATE_DOWN) {
-		p += sprintf(p, "Firmware version:\t%d.%d build %d\nFirmware location:\t", 
+		p += sprintf(p, "Firmware version:\t%d.%d build %d\n"
+				"Firmware location:\t",
 			     priv->host_info.major_version,
 			     priv->host_info.minor_version,
 			     priv->host_info.build_version);
-		
-		if (priv->card_type != CARD_TYPE_EEPROM) 
+
+		if (priv->card_type != CARD_TYPE_EEPROM)
 			p += sprintf(p, "on card\n");
-		else if (priv->firmware) 
-			p += sprintf(p, "%s loaded by host\n", priv->firmware_id);
+		else if (priv->firmware)
+			p += sprintf(p, "%s loaded by host\n",
+				     priv->firmware_id);
 		else
-			p += sprintf(p, "%s loaded by hotplug\n", priv->firmware_id);
-		
-		switch(priv->card_type) {
+			p += sprintf(p, "%s loaded by hotplug\n",
+				     priv->firmware_id);
+
+		switch (priv->card_type) {
 		case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
 		case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
 		case CARD_TYPE_EEPROM: c = "EEPROM"; break;
 		default: c = "<unknown>";
 		}
 
-		
 		r = "<unknown>";
 		for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++)
 			if (priv->reg_domain == channel_table[i].reg_domain)
 				r = channel_table[i].name;
-		
+
 		p += sprintf(p, "MAC memory type:\t%s\n", c);
 		p += sprintf(p, "Regulatory domain:\t%s\n", r);
-		p += sprintf(p, "Host CRC checking:\t%s\n", 
+		p += sprintf(p, "Host CRC checking:\t%s\n",
 			     priv->do_rx_crc ? "On" : "Off");
 		p += sprintf(p, "WPA-capable firmware:\t%s\n",
 			     priv->use_wpa ? "Yes" : "No");
 	}
-	
+
 	switch(priv->station_state) {
 	case STATION_STATE_SCANNING: s = "Scanning"; break;
 	case STATION_STATE_JOINNING: s = "Joining"; break;
@@ -1486,9 +1488,9 @@
 	case STATION_STATE_DOWN: s = "Down"; break;
 	default: s = "<unknown>";
 	}
-      
+
 	p += sprintf(p, "Current state:\t\t%s\n", s);
-	return  p - buf;
+	return p - buf;
 }
 
 static int atmel_read_proc(char *page, char **start, off_t off,
@@ -1504,9 +1506,12 @@
         return len;
 }
 
-struct net_device *init_atmel_card( unsigned short irq, unsigned long port, const AtmelFWType fw_type,  
-				    struct device *sys_dev, int (*card_present)(void *), void *card)
+struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
+				   const AtmelFWType fw_type,
+				   struct device *sys_dev,
+				   int (*card_present)(void *), void *card)
 {
+	struct proc_dir_entry *ent;
 	struct net_device *dev;
 	struct atmel_private *priv;
 	int rc;
@@ -1514,11 +1519,11 @@
 	/* Create the network device object. */
         dev = alloc_etherdev(sizeof(*priv));
         if (!dev) {
-		printk(KERN_ERR "atmel:  Couldn't alloc_etherdev\n");
+		printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
 		return NULL;
         }
 	if (dev_alloc_name(dev, dev->name) < 0) {
-		printk(KERN_ERR "atmel:  Couldn't get name!\n");
+		printk(KERN_ERR "atmel: Couldn't get name!\n");
 		goto err_out_free;
 	}
 
@@ -1550,7 +1555,7 @@
 	memset(priv->BSSID, 0, 6);
 	priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
 	priv->station_was_associated = 0;
-	
+
 	priv->last_survey = jiffies;
 	priv->preamble = LONG_PREAMBLE;
 	priv->operating_mode = IW_MODE_INFRA;
@@ -1586,7 +1591,7 @@
 	spin_lock_init(&priv->timerlock);
 	priv->management_timer.function = atmel_management_timer;
 	priv->management_timer.data = (unsigned long) dev;
-	
+
 	dev->open = atmel_open;
 	dev->stop = atmel_close;
 	dev->change_mtu = atmel_change_mtu;
@@ -1597,44 +1602,46 @@
 	dev->do_ioctl = atmel_ioctl;
 	dev->irq = irq;
 	dev->base_addr = port;
-	
+
 	SET_NETDEV_DEV(dev, sys_dev);
-	
+
 	if ((rc = request_irq(dev->irq, service_interrupt, SA_SHIRQ, dev->name, dev))) {
-		printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc );
+		printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
 		goto err_out_free;
 	}
 
-	if (!request_region(dev->base_addr, 32, 
+	if (!request_region(dev->base_addr, 32,
 			    priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
 		goto err_out_irq;
 	}
-	
+
 	if (register_netdev(dev))
 		goto err_out_res;
-	
+
 	if (!probe_atmel_card(dev)){
 		unregister_netdev(dev);
 		goto err_out_res;
 	}
-	
+
 	netif_carrier_off(dev);
-	
-	create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);	
-	
+
+	ent = create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
+	if (!ent)
+		printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
+
 	printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
 	       dev->name, DRIVER_MAJOR, DRIVER_MINOR,
 	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
 	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
-	
+
 	SET_MODULE_OWNER(dev);
 	return dev;
-	
- err_out_res:
+
+err_out_res:
 	release_region( dev->base_addr, 32);
- err_out_irq:
+err_out_irq:
 	free_irq(dev->irq, dev);
- err_out_free:
+err_out_free:
 	free_netdev(dev);
 	return NULL;
 }
@@ -1644,12 +1651,12 @@
 void stop_atmel_card(struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-		
+
 	/* put a brick on it... */
-	if (priv->bus_type == BUS_TYPE_PCCARD) 
+	if (priv->bus_type == BUS_TYPE_PCCARD)
 		atmel_write16(dev, GCR, 0x0060);
 	atmel_write16(dev, GCR, 0x0040);
-	
+
 	del_timer_sync(&priv->management_timer);
 	unregister_netdev(dev);
 	remove_proc_entry("driver/atmel", NULL);
@@ -1675,13 +1682,13 @@
 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
 
 		priv->connect_to_any_BSS = 0;
-		
+
 		/* Check the size of the string */
 		if (dwrq->length > MAX_SSID_LENGTH + 1)
-			 return -E2BIG ;
+			 return -E2BIG;
 		if (index != 0)
 			return -EINVAL;
-		
+
 		memcpy(priv->new_SSID, extra, dwrq->length - 1);
 		priv->new_SSID_size = dwrq->length - 1;
 	}
@@ -1706,7 +1713,7 @@
 		extra[priv->SSID_size] = '\0';
 		dwrq->length = priv->SSID_size + 1;
 	}
-	
+
 	dwrq->flags = !priv->connect_to_any_BSS; /* active */
 
 	return 0;
@@ -1768,7 +1775,7 @@
 		/* WE specify that if a valid key is set, encryption
 		 * should be enabled (user may turn it off later)
 		 * This is also how "iwconfig ethX key on" works */
-		if (index == current_index && 
+		if (index == current_index &&
 		    priv->wep_key_len[index] > 0) {
 			priv->wep_is_on = 1;
 			priv->exclude_unencrypted = 1;
@@ -1783,18 +1790,18 @@
 	} else {
 		/* Do we want to just set the transmit key index ? */
 		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-		if ( index>=0 && index < 4 ) {
+		if (index >= 0 && index < 4) {
 			priv->default_key = index;
 		} else
 			/* Don't complain if only change the mode */
-			if(!dwrq->flags & IW_ENCODE_MODE) {
+			if (!dwrq->flags & IW_ENCODE_MODE) {
 				return -EINVAL;
 			}
 	}
 	/* Read the flags */
-	if(dwrq->flags & IW_ENCODE_DISABLED) {
+	if (dwrq->flags & IW_ENCODE_DISABLED) {
 		priv->wep_is_on = 0;
-		priv->encryption_level = 0; 	
+		priv->encryption_level = 0;
 		priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
 	} else {
 		priv->wep_is_on = 1;
@@ -1806,15 +1813,14 @@
 			priv->encryption_level = 1;
 		}
 	}
-	if(dwrq->flags & IW_ENCODE_RESTRICTED)
+	if (dwrq->flags & IW_ENCODE_RESTRICTED)
 		priv->exclude_unencrypted = 1;
-       	if(dwrq->flags & IW_ENCODE_OPEN) 
+	if(dwrq->flags & IW_ENCODE_OPEN)
 		priv->exclude_unencrypted = 0;
-       
+
 	return -EINPROGRESS;		/* Call commit handler */
 }
 
-
 static int atmel_get_encode(struct net_device *dev,
 			    struct iw_request_info *info,
 			    struct iw_point *dwrq,
@@ -1822,7 +1828,7 @@
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
-	
+
 	if (!priv->wep_is_on)
 		dwrq->flags = IW_ENCODE_DISABLED;
 	else {
@@ -1843,7 +1849,7 @@
 		memset(extra, 0, 16);
 		memcpy(extra, priv->wep_keys[index], dwrq->length);
 	}
-	
+
 	return 0;
 }
 
@@ -1862,17 +1868,17 @@
 			  char *extra)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-	
+
 	if (vwrq->fixed == 0) {
 		priv->tx_rate = 3;
 		priv->auto_tx_rate = 1;
 	} else {
 		priv->auto_tx_rate = 0;
-		
+
 		/* Which type of value ? */
-		if((vwrq->value < 4) && (vwrq->value >= 0)) {
+		if ((vwrq->value < 4) && (vwrq->value >= 0)) {
 			/* Setting by rate index */
-		priv->tx_rate = vwrq->value;
+			priv->tx_rate = vwrq->value;
 		} else {
 		/* Setting by frequency value */
 			switch (vwrq->value) {
@@ -1899,7 +1905,7 @@
 		return -EINVAL;
 
 	priv->operating_mode = *uwrq;
-	return -EINPROGRESS;  
+	return -EINPROGRESS;
 }
 
 static int atmel_get_mode(struct net_device *dev,
@@ -1908,7 +1914,7 @@
 			  char *extra)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-	
+
 	*uwrq = priv->operating_mode;
 	return 0;
 }
@@ -1962,9 +1968,9 @@
 			   char *extra)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-	
-	if(!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
-		if(vwrq->flags & IW_RETRY_MAX)
+
+	if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
+		if (vwrq->flags & IW_RETRY_MAX)
 			priv->long_retry = vwrq->value;
 		else if (vwrq->flags & IW_RETRY_MIN)
 			priv->short_retry = vwrq->value;
@@ -1973,9 +1979,9 @@
 			priv->long_retry = vwrq->value;
 			priv->short_retry = vwrq->value;
 		}
-		return -EINPROGRESS;		
+		return -EINPROGRESS;
 	}
-	   
+
 	return -EINVAL;
 }
 
@@ -1989,13 +1995,13 @@
 	vwrq->disabled = 0;      /* Can't be disabled */
 
 	/* Note : by default, display the min retry number */
-	if((vwrq->flags & IW_RETRY_MAX)) {
+	if (vwrq->flags & IW_RETRY_MAX) {
 		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
 		vwrq->value = priv->long_retry;
 	} else {
 		vwrq->flags = IW_RETRY_LIMIT;
 		vwrq->value = priv->short_retry;
-		if(priv->long_retry != priv->short_retry)
+		if (priv->long_retry != priv->short_retry)
 			vwrq->flags |= IW_RETRY_MIN;
 	}
 
@@ -2010,13 +2016,13 @@
 	struct atmel_private *priv = netdev_priv(dev);
 	int rthr = vwrq->value;
 
-	if(vwrq->disabled)
+	if (vwrq->disabled)
 		rthr = 2347;
-	if((rthr < 0) || (rthr > 2347)) {
+	if ((rthr < 0) || (rthr > 2347)) {
 		return -EINVAL;
 	}
 	priv->rts_threshold = rthr;
-	
+
 	return -EINPROGRESS;		/* Call commit handler */
 }
 
@@ -2026,7 +2032,7 @@
 			 char *extra)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-	
+
 	vwrq->value = priv->rts_threshold;
 	vwrq->disabled = (vwrq->value >= 2347);
 	vwrq->fixed = 1;
@@ -2042,14 +2048,14 @@
 	struct atmel_private *priv = netdev_priv(dev);
 	int fthr = vwrq->value;
 
-	if(vwrq->disabled)
+	if (vwrq->disabled)
 		fthr = 2346;
-	if((fthr < 256) || (fthr > 2346)) {
+	if ((fthr < 256) || (fthr > 2346)) {
 		return -EINVAL;
 	}
 	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
 	priv->frag_threshold = fthr;
-	
+
 	return -EINPROGRESS;		/* Call commit handler */
 }
 
@@ -2077,21 +2083,21 @@
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	int rc = -EINPROGRESS;		/* Call commit handler */
-	
+
 	/* If setting by frequency, convert to a channel */
-	if((fwrq->e == 1) &&
-	   (fwrq->m >= (int) 241200000) &&
-	   (fwrq->m <= (int) 248700000)) {
+	if ((fwrq->e == 1) &&
+	    (fwrq->m >= (int) 241200000) &&
+	    (fwrq->m <= (int) 248700000)) {
 		int f = fwrq->m / 100000;
 		int c = 0;
-		while((c < 14) && (f != frequency_list[c]))
+		while ((c < 14) && (f != frequency_list[c]))
 			c++;
 		/* Hack to fall through... */
 		fwrq->e = 0;
 		fwrq->m = c + 1;
 	}
 	/* Setting by channel number */
-	if((fwrq->m > 1000) || (fwrq->e > 0))
+	if ((fwrq->m > 1000) || (fwrq->e > 0))
 		rc = -EOPNOTSUPP;
 	else {
 		int channel = fwrq->m;
@@ -2099,7 +2105,7 @@
 			priv->channel = channel;
 		} else {
 			rc = -EINVAL;
-		} 
+		}
 	}
 	return rc;
 }
@@ -2130,7 +2136,7 @@
 	 * This is not an error, while the device perform scanning,
 	 * traffic doesn't flow, so it's a perfect DoS...
 	 * Jean II */
-	
+
 	if (priv->station_state == STATION_STATE_DOWN)
 		return -EAGAIN;
 
@@ -2142,15 +2148,15 @@
 	/* Initiate a scan command */
 	if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
 		return -EBUSY;
-		
+
 	del_timer_sync(&priv->management_timer);
 	spin_lock_irqsave(&priv->irqlock, flags);
-	
+
 	priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
 	priv->fast_scan = 0;
 	atmel_scan(priv, 0);
 	spin_unlock_irqrestore(&priv->irqlock, flags);
-	
+
 	return 0;
 }
 
@@ -2163,11 +2169,11 @@
 	int i;
 	char *current_ev = extra;
 	struct iw_event	iwe;
-	
+
 	if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
 		return -EAGAIN;
-	
-	for(i=0; i<priv->BSS_list_entries; i++) { 
+
+	for (i = 0; i < priv->BSS_list_entries; i++) {
 		iwe.cmd = SIOCGIWAP;
 		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 		memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
@@ -2179,16 +2185,16 @@
 		iwe.cmd = SIOCGIWESSID;
 		iwe.u.data.flags = 1;
 		current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
-		
+
 		iwe.cmd = SIOCGIWMODE;
 		iwe.u.mode = priv->BSSinfo[i].BSStype;
 		current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
-	
+
 		iwe.cmd = SIOCGIWFREQ;
 		iwe.u.freq.m = priv->BSSinfo[i].channel;
 		iwe.u.freq.e = 0;
 		current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
-		
+
 		iwe.cmd = SIOCGIWENCODE;
 		if (priv->BSSinfo[i].UsingWEP)
 			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
@@ -2196,13 +2202,12 @@
 			iwe.u.data.flags = IW_ENCODE_DISABLED;
 		iwe.u.data.length = 0;
 		current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
-		
 	}
 
 	/* Length of data */
 	dwrq->length = (current_ev - extra);
-	dwrq->flags = 0;   
-	
+	dwrq->flags = 0;
+
 	return 0;
 }
 
@@ -2213,7 +2218,7 @@
 {
 	struct atmel_private *priv = netdev_priv(dev);
 	struct iw_range *range = (struct iw_range *) extra;
-	int k,i,j;
+	int k, i, j;
 
 	dwrq->length = sizeof(struct iw_range);
 	memset(range, 0, sizeof(struct iw_range));
@@ -2226,14 +2231,14 @@
 			break;
 		}
 	if (range->num_channels != 0) {
-		for(k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
+		for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
 			range->freq[k].i = i; /* List index */
-			range->freq[k].m = frequency_list[i-1] * 100000;
+			range->freq[k].m = frequency_list[i - 1] * 100000;
 			range->freq[k++].e = 1;	/* Values in table in MHz -> * 10^5 * 10 */
 		}
 		range->num_frequency = k;
 	}
-	
+
 	range->max_qual.qual = 100;
 	range->max_qual.level = 100;
 	range->max_qual.noise = 0;
@@ -2261,11 +2266,11 @@
 	range->encoding_size[1] = 13;
 	range->num_encoding_sizes = 2;
 	range->max_encoding_tokens = 4;
-	
+
 	range->pmp_flags = IW_POWER_ON;
 	range->pmt_flags = IW_POWER_ON;
 	range->pm_capa = 0;
-	
+
 	range->we_version_source = WIRELESS_EXT;
 	range->we_version_compiled = WIRELESS_EXT;
 	range->retry_capa = IW_RETRY_LIMIT ;
@@ -2289,7 +2294,7 @@
 
 	if (awrq->sa_family != ARPHRD_ETHER)
 		return -EINVAL;
-	
+
 	if (memcmp(bcast, awrq->sa_data, 6) == 0) {
 		del_timer_sync(&priv->management_timer);
 		spin_lock_irqsave(&priv->irqlock, flags);
@@ -2297,8 +2302,8 @@
 		spin_unlock_irqrestore(&priv->irqlock, flags);
 		return 0;
 	}
-	
-	for(i=0; i<priv->BSS_list_entries; i++) {
+
+	for (i = 0; i < priv->BSS_list_entries; i++) {
 		if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
 			if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
 				return -EINVAL;
@@ -2313,10 +2318,10 @@
 			}
 		}
 	}
-		
+
 	return -EINVAL;
 }
-	
+
 static int atmel_config_commit(struct net_device *dev,
 			       struct iw_request_info *info,	/* NULL */
 			       void *zwrq,			/* NULL */
@@ -2325,18 +2330,18 @@
 	return atmel_open(dev);
 }
 
-static const iw_handler		atmel_handler[] =
+static const iw_handler atmel_handler[] =
 {
 	(iw_handler) atmel_config_commit,	/* SIOCSIWCOMMIT */
-	(iw_handler) atmel_get_name,    	/* SIOCGIWNAME */
+	(iw_handler) atmel_get_name,		/* SIOCGIWNAME */
 	(iw_handler) NULL,			/* SIOCSIWNWID */
 	(iw_handler) NULL,			/* SIOCGIWNWID */
 	(iw_handler) atmel_set_freq,		/* SIOCSIWFREQ */
 	(iw_handler) atmel_get_freq,		/* SIOCGIWFREQ */
 	(iw_handler) atmel_set_mode,		/* SIOCSIWMODE */
 	(iw_handler) atmel_get_mode,		/* SIOCGIWMODE */
-	(iw_handler) NULL,                  	/* SIOCSIWSENS */
-	(iw_handler) NULL,           		/* SIOCGIWSENS */
+	(iw_handler) NULL,			/* SIOCSIWSENS */
+	(iw_handler) NULL,			/* SIOCGIWSENS */
 	(iw_handler) NULL,			/* SIOCSIWRANGE */
 	(iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
 	(iw_handler) NULL,			/* SIOCSIWPRIV */
@@ -2350,13 +2355,13 @@
 	(iw_handler) atmel_set_wap,		/* SIOCSIWAP */
 	(iw_handler) atmel_get_wap,		/* SIOCGIWAP */
 	(iw_handler) NULL,			/* -- hole -- */
-	(iw_handler) NULL,       		/* SIOCGIWAPLIST */
+	(iw_handler) NULL,			/* SIOCGIWAPLIST */
 	(iw_handler) atmel_set_scan,		/* SIOCSIWSCAN */
 	(iw_handler) atmel_get_scan,		/* SIOCGIWSCAN */
 	(iw_handler) atmel_set_essid,		/* SIOCSIWESSID */
 	(iw_handler) atmel_get_essid,		/* SIOCGIWESSID */
-	(iw_handler) NULL,         		/* SIOCSIWNICKN */
-	(iw_handler) NULL,          		/* SIOCGIWNICKN */
+	(iw_handler) NULL,			/* SIOCSIWNICKN */
+	(iw_handler) NULL,			/* SIOCGIWNICKN */
 	(iw_handler) NULL,			/* -- hole -- */
 	(iw_handler) NULL,			/* -- hole -- */
 	(iw_handler) atmel_set_rate,		/* SIOCSIWRATE */
@@ -2365,8 +2370,8 @@
 	(iw_handler) atmel_get_rts,		/* SIOCGIWRTS */
 	(iw_handler) atmel_set_frag,		/* SIOCSIWFRAG */
 	(iw_handler) atmel_get_frag,		/* SIOCGIWFRAG */
-	(iw_handler) NULL,         		/* SIOCSIWTXPOW */
-	(iw_handler) NULL,          		/* SIOCGIWTXPOW */
+	(iw_handler) NULL,			/* SIOCSIWTXPOW */
+	(iw_handler) NULL,			/* SIOCGIWTXPOW */
 	(iw_handler) atmel_set_retry,		/* SIOCSIWRETRY */
 	(iw_handler) atmel_get_retry,		/* SIOCGIWRETRY */
 	(iw_handler) atmel_set_encode,		/* SIOCSIWENCODE */
@@ -2375,39 +2380,51 @@
 	(iw_handler) atmel_get_power,		/* SIOCGIWPOWER */
 };
 
-
-static const iw_handler		atmel_private_handler[] =
+static const iw_handler atmel_private_handler[] =
 {
 	NULL,				/* SIOCIWFIRSTPRIV */
 };
 
 typedef struct atmel_priv_ioctl {
 	char id[32];
-	unsigned char __user *data;		
-	unsigned short len;		
+	unsigned char __user *data;
+	unsigned short len;
 } atmel_priv_ioctl;
 
-	
-#define ATMELFWL SIOCIWFIRSTPRIV
-#define ATMELIDIFC ATMELFWL + 1
-#define ATMELRD ATMELFWL + 2
-#define ATMELMAGIC 0x51807 
+#define ATMELFWL	SIOCIWFIRSTPRIV
+#define ATMELIDIFC	ATMELFWL + 1
+#define ATMELRD		ATMELFWL + 2
+#define ATMELMAGIC 0x51807
 #define REGDOMAINSZ 20
 
 static const struct iw_priv_args atmel_private_args[] = {
-/*{ cmd,         set_args,                            get_args, name } */
-  { ATMELFWL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (atmel_priv_ioctl), IW_PRIV_TYPE_NONE, "atmelfwl" },
-  { ATMELIDIFC, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "atmelidifc" },
-  { ATMELRD, IW_PRIV_TYPE_CHAR | REGDOMAINSZ, IW_PRIV_TYPE_NONE, "regdomain" },
+	{
+		.cmd = ATMELFWL,
+		.set_args = IW_PRIV_TYPE_BYTE
+				| IW_PRIV_SIZE_FIXED
+				| sizeof (atmel_priv_ioctl),
+		.get_args = IW_PRIV_TYPE_NONE,
+		.name = "atmelfwl"
+	}, {
+		.cmd = ATMELIDIFC,
+		.set_args = IW_PRIV_TYPE_NONE,
+		.get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+		.name = "atmelidifc"
+	}, {
+		.cmd = ATMELRD,
+		.set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
+		.get_args = IW_PRIV_TYPE_NONE,
+		.name = "regdomain"
+	},
 };
 
-static const struct iw_handler_def	atmel_handler_def =
+static const struct iw_handler_def atmel_handler_def =
 {
 	.num_standard	= sizeof(atmel_handler)/sizeof(iw_handler),
-	.num_private	= sizeof(atmel_private_handler)/sizeof(iw_handler), 
-	.num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args), 
+	.num_private	= sizeof(atmel_private_handler)/sizeof(iw_handler),
+	.num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args),
 	.standard	= (iw_handler *) atmel_handler,
-	.private	= (iw_handler *) atmel_private_handler, 
+	.private	= (iw_handler *) atmel_private_handler,
 	.private_args	= (struct iw_priv_args *) atmel_private_args,
 	.get_wireless_stats = atmel_get_wireless_stats
 };
@@ -2419,13 +2436,13 @@
 	atmel_priv_ioctl com;
 	struct iwreq *wrq = (struct iwreq *) rq;
 	unsigned char *new_firmware;
-	char domain[REGDOMAINSZ+1];
+	char domain[REGDOMAINSZ + 1];
 
 	switch (cmd) {
 	case ATMELIDIFC:
-		wrq->u.param.value = ATMELMAGIC;		
+		wrq->u.param.value = ATMELMAGIC;
 		break;
-	
+
 	case ATMELFWL:
 		if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
 			rc = -EFAULT;
@@ -2449,7 +2466,7 @@
 		}
 
 		kfree(priv->firmware);
-		
+
 		priv->firmware = new_firmware;
 		priv->firmware_length = com.len;
 		strncpy(priv->firmware_id, com.id, 31);
@@ -2461,7 +2478,7 @@
 			rc = -EFAULT;
 			break;
 		}
-		
+
 		if (!capable(CAP_NET_ADMIN)) {
 			rc = -EPERM;
 			break;
@@ -2484,15 +2501,15 @@
 				rc = 0;
 			}
 		}
-		
+
 		if (rc == 0 &&  priv->station_state != STATION_STATE_DOWN)
 			rc = atmel_open(dev);
 		break;
-		
+
 	default:
 		rc = -EOPNOTSUPP;
 	}
-	
+
 	return rc;
 }
 
@@ -2503,17 +2520,17 @@
 	u8 el_id;
 	u8 chall_text_len;
 	u8 chall_text[253];
-}; 
+};
 
 static void atmel_enter_state(struct atmel_private *priv, int new_state)
 {
 	int old_state = priv->station_state;
-		
+
 	if (new_state == old_state)
 		return;
-	
+
 	priv->station_state = new_state;
-		
+
 	if (new_state == STATION_STATE_READY) {
 		netif_start_queue(priv->dev);
 		netif_carrier_on(priv->dev);
@@ -2540,7 +2557,7 @@
 		u8 options;
 		u8 SSID_size;
 	} cmd;
-	
+
 	memset(cmd.BSSID, 0xff, 6);
 
 	if (priv->fast_scan) {
@@ -2554,17 +2571,17 @@
 		cmd.min_channel_time = cpu_to_le16(10);
 		cmd.max_channel_time = cpu_to_le16(120);
 	}
-	
+
 	cmd.options = 0;
-	
+
 	if (!specific_ssid)
 		cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
-	
-	cmd.channel = (priv->channel & 0x7f); 
+
+	cmd.channel = (priv->channel & 0x7f);
 	cmd.scan_type = SCAN_TYPE_ACTIVE;
-	cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ? 
+	cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
 		BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
-	
+
 	atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
 
 	/* This must come after all hardware access to avoid being messed up
@@ -2591,16 +2608,15 @@
 	cmd.BSS_type = type;
 	cmd.timeout = cpu_to_le16(2000);
 
- 	atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
+	atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
 }
 
-
 static void start(struct atmel_private *priv, int type)
 {
 	struct {
 		u8 BSSID[6];
 		u8 SSID[MAX_SSID_LENGTH];
-		u8 BSS_type;                                
+		u8 BSS_type;
 		u8 channel;
 		u8 SSID_size;
 		u8 reserved[3];
@@ -2612,13 +2628,14 @@
 	cmd.BSS_type = type;
 	cmd.channel = (priv->channel & 0x7f);
 
-	atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd)); 
+	atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
 }
 
-static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 channel)
+static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
+				u8 channel)
 {
 	int rejoin = 0;
-	int new = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
+	int new = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ?
 		SHORT_PREAMBLE : LONG_PREAMBLE;
 
 	if (priv->preamble != new) {
@@ -2626,48 +2643,48 @@
 		rejoin = 1;
 		atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
 	}
-		
+
 	if (priv->channel != channel) {
 		priv->channel = channel;
 		rejoin = 1;
 		atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
 	}
-	
+
 	if (rejoin) {
 		priv->station_is_associated = 0;
 		atmel_enter_state(priv, STATION_STATE_JOINNING);
-		
+
 		if (priv->operating_mode == IW_MODE_INFRA)
 			join(priv, BSS_TYPE_INFRASTRUCTURE);
-		else 
+		else
 			join(priv, BSS_TYPE_AD_HOC);
-	} 
+	}
 }
 
-
-static void send_authentication_request(struct atmel_private *priv, u16 system, u8 *challenge, int challenge_len)
+static void send_authentication_request(struct atmel_private *priv, u16 system,
+					u8 *challenge, int challenge_len)
 {
 	struct ieee80211_hdr_4addr header;
 	struct auth_body auth;
-	
-	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); 
-	header.duration_id	= cpu_to_le16(0x8000);	
+
+	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
+	header.duration_id = cpu_to_le16(0x8000);
 	header.seq_ctl = 0;
 	memcpy(header.addr1, priv->CurrentBSSID, 6);
 	memcpy(header.addr2, priv->dev->dev_addr, 6);
 	memcpy(header.addr3, priv->CurrentBSSID, 6);
-	
-	if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1) 
+
+	if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
 		/* no WEP for authentication frames with TrSeqNo 1 */
                 header.frame_ctl |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
-	
-	auth.alg = cpu_to_le16(system); 
+
+	auth.alg = cpu_to_le16(system);
 
 	auth.status = 0;
 	auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
-	priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1; 
+	priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
 	priv->CurrentAuthentTransactionSeqNum += 2;
-	
+
 	if (challenge_len != 0)	{
 		auth.el_id = 16; /* challenge_text */
 		auth.chall_text_len = challenge_len;
@@ -2685,7 +2702,7 @@
 	struct ieee80211_hdr_4addr header;
 	struct ass_req_format {
 		u16 capability;
-		u16 listen_interval; 
+		u16 listen_interval;
 		u8 ap[6]; /* nothing after here directly accessible */
 		u8 ssid_el_id;
 		u8 ssid_len;
@@ -2694,15 +2711,15 @@
 		u8 sup_rates_len;
 		u8 rates[4];
 	} body;
-		
-	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | 
+
+	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
 		(is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
 	header.duration_id = cpu_to_le16(0x8000);
 	header.seq_ctl = 0;
 
-	memcpy(header.addr1, priv->CurrentBSSID, 6); 
+	memcpy(header.addr1, priv->CurrentBSSID, 6);
 	memcpy(header.addr2, priv->dev->dev_addr, 6);
-	memcpy(header.addr3, priv->CurrentBSSID, 6); 
+	memcpy(header.addr3, priv->CurrentBSSID, 6);
 
 	body.capability = cpu_to_le16(C80211_MGMT_CAPABILITY_ESS);
 	if (priv->wep_is_on)
@@ -2711,18 +2728,18 @@
 		body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_ShortPreamble);
 
 	body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
-	
+
 	/* current AP address - only in reassoc frame */
 	if (is_reassoc) {
-		memcpy(body.ap,  priv->CurrentBSSID, 6);
+		memcpy(body.ap, priv->CurrentBSSID, 6);
 		ssid_el_p = (u8 *)&body.ssid_el_id;
 		bodysize = 18 + priv->SSID_size;
 	} else {
 		ssid_el_p = (u8 *)&body.ap[0];
 		bodysize = 12 + priv->SSID_size;
 	}
-		
-	ssid_el_p[0]= C80211_MGMT_ElementID_SSID;
+
+	ssid_el_p[0] = C80211_MGMT_ElementID_SSID;
 	ssid_el_p[1] = priv->SSID_size;
 	memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
 	ssid_el_p[2 + priv->SSID_size] = C80211_MGMT_ElementID_SupportedRates;
@@ -2732,7 +2749,8 @@
 	atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
 }
 
-static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr_4addr *header)
+static int is_frame_from_current_bss(struct atmel_private *priv,
+				     struct ieee80211_hdr_4addr *header)
 {
 	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
 		return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
@@ -2745,29 +2763,29 @@
 	int i;
 	int max_rssi = -128;
 	int max_index = -1;
-	
+
 	if (priv->BSS_list_entries == 0)
 		return -1;
-			
+
 	if (priv->connect_to_any_BSS) {
-		/* Select a BSS with the max-RSSI but of the same type and of the same WEP mode
-		   and that it is not marked as 'bad' (i.e. we had previously failed to connect to
-		   this BSS with the settings that we currently use) */
+		/* Select a BSS with the max-RSSI but of the same type and of
+		   the same WEP mode and that it is not marked as 'bad' (i.e.
+		   we had previously failed to connect to this BSS with the
+		   settings that we currently use) */
 		priv->current_BSS = 0;
-		for(i=0; i<priv->BSS_list_entries; i++) { 
+		for (i = 0; i < priv->BSS_list_entries; i++) {
 			if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
-			    ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) || 
+			    ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
 			     (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
 			    !(priv->BSSinfo[i].channel & 0x80)) {
 				max_rssi = priv->BSSinfo[i].RSSI;
 				priv->current_BSS = max_index = i;
 			}
-			
 		}
 		return max_index;
 	}
-		
-	for(i=0; i<priv->BSS_list_entries; i++) {
+
+	for (i = 0; i < priv->BSS_list_entries; i++) {
 		if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
 		    memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
 		    priv->operating_mode == priv->BSSinfo[i].BSStype &&
@@ -2781,19 +2799,19 @@
 	return max_index;
 }
 
-
-static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
-			   u16 capability, u16 beacon_period, u8 channel, u8 rssi, 
-			   u8 ssid_len, u8 *ssid, int is_beacon)
+static void store_bss_info(struct atmel_private *priv,
+			   struct ieee80211_hdr_4addr *header, u16 capability,
+			   u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
+			   u8 *ssid, int is_beacon)
 {
 	u8 *bss = capability & C80211_MGMT_CAPABILITY_ESS ? header->addr2 : header->addr3;
 	int i, index;
-		
-	for (index = -1, i = 0; i < priv->BSS_list_entries; i++) 
-		if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0) 
+
+	for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
+		if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
 			index = i;
 
-        /* If we process a probe and an entry from this BSS exists 
+        /* If we process a probe and an entry from this BSS exists
 	   we will update the BSS entry with the info from this BSS.
 	   If we process a beacon we will only update RSSI */
 
@@ -2820,8 +2838,8 @@
 		priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
 	else if (capability & C80211_MGMT_CAPABILITY_ESS)
 		priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
-	
-	priv->BSSinfo[index].preamble = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
+
+	priv->BSSinfo[index].preamble = capability & C80211_MGMT_CAPABILITY_ShortPreamble ?
 		SHORT_PREAMBLE : LONG_PREAMBLE;
 }
 
@@ -2831,8 +2849,8 @@
 	u16 status = le16_to_cpu(auth->status);
 	u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
 	u16 system = le16_to_cpu(auth->alg);
-	
-	if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) { 
+
+	if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) {
 		/* no WEP */
 		if (priv->station_was_associated) {
 			atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
@@ -2842,20 +2860,20 @@
 			atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
 			send_association_request(priv, 0);
 			return;
-		} 
+		}
 	}
-		
-	if (status == C80211_MGMT_SC_Success && priv->wep_is_on) { 
+
+	if (status == C80211_MGMT_SC_Success && priv->wep_is_on) {
 		/* WEP */
 		if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
 			return;
-				
+
 		if (trans_seq_no == 0x0002 &&
 		    auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
 			send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
 			return;
 		}
-		
+
 		if (trans_seq_no == 0x0004) {
 			if(priv->station_was_associated) {
 				atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
@@ -2865,10 +2883,10 @@
 				atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
 				send_association_request(priv, 0);
 				return;
-			} 
+			}
 		}
-	}			
-	
+	}
+
 	if (status == C80211_MGMT_SC_AuthAlgNotSupported) {
 		/* Do opensystem first, then try sharedkey */
 		if (system ==  C80211_MGMT_AAN_OPENSYSTEM) {
@@ -2876,17 +2894,16 @@
 			send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
 		} else if (priv->connect_to_any_BSS) {
 			int bss_index;
-			
+
 			priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-			
+
 			if ((bss_index  = retrieve_bss(priv)) != -1) {
 				atmel_join_bss(priv, bss_index);
 				return;
 			}
 		}
 	}
-	
-	
+
 	priv->AuthenticationRequestRetryCnt = 0;
 	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
 	priv->station_is_associated = 0;
@@ -2902,38 +2919,44 @@
 		u8 length;
 		u8 rates[4];
 	} *ass_resp = (struct ass_resp_format *)priv->rx_buf;
-	
-       	u16 status = le16_to_cpu(ass_resp->status);
+
+	u16 status = le16_to_cpu(ass_resp->status);
 	u16 ass_id = le16_to_cpu(ass_resp->ass_id);
-   	u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
-	
+	u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
+
 	if (frame_len < 8 + rates_len)
 		return;
-	
+
 	if (status == C80211_MGMT_SC_Success) {
 		if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE)
 			priv->AssociationRequestRetryCnt = 0;
 		else
 			priv->ReAssociationRequestRetryCnt = 0;
-		
-		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
-		atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
+
+		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+				MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
+		atmel_set_mib(priv, Phy_Mib_Type,
+			      PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
 		if (priv->power_mode == 0) {
 			priv->listen_interval = 1;
-			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
-			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
+			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
+				       MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
+			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+					MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
 		} else {
 			priv->listen_interval = 2;
-			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
-			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
+			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
+				       MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
+			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+					MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
 		}
-		
+
 		priv->station_is_associated = 1;
 		priv->station_was_associated = 1;
 		atmel_enter_state(priv, STATION_STATE_READY);
 		return;
 	}
-	
+
 	if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE &&
 	    status != C80211_MGMT_SC_AssDeniedBSSRate &&
 	    status != C80211_MGMT_SC_SupportCapabilities &&
@@ -2943,7 +2966,7 @@
 		send_association_request(priv, 0);
 		return;
 	}
-		
+
 	if (subtype == C80211_SUBTYPE_MGMT_REASS_RESPONSE &&
 	    status != C80211_MGMT_SC_AssDeniedBSSRate &&
 	    status != C80211_MGMT_SC_SupportCapabilities &&
@@ -2953,17 +2976,16 @@
 		send_association_request(priv, 1);
 		return;
 	}
-	
+
 	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
 	priv->station_is_associated = 0;
-	
-	if(priv->connect_to_any_BSS) {
+
+	if (priv->connect_to_any_BSS) {
 		int bss_index;
 		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-		
-		if ((bss_index = retrieve_bss(priv)) != -1) 
+
+		if ((bss_index = retrieve_bss(priv)) != -1)
 			atmel_join_bss(priv, bss_index);
-		
 	}
 }
 
@@ -2977,7 +2999,7 @@
 	/* The WPA stuff cares about the current AP address */
 	if (priv->use_wpa)
 		build_wpa_mib(priv);
-	
+
 	/* When switching to AdHoc turn OFF Power Save if needed */
 
 	if (bss->BSStype == IW_MODE_ADHOC &&
@@ -2985,25 +3007,28 @@
 	    priv->power_mode) {
 		priv->power_mode = 0;
 		priv->listen_interval = 1;
-		atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
-		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
+		atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
+			       MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
+		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
+				MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
 	}
-		
+
 	priv->operating_mode = bss->BSStype;
-	priv->channel = bss->channel & 0x7f; 	
+	priv->channel = bss->channel & 0x7f;
 	priv->beacon_period = bss->beacon_period;
-	
+
 	if (priv->preamble != bss->preamble) {
 		priv->preamble = bss->preamble;
-		atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
+		atmel_set_mib8(priv, Local_Mib_Type,
+			       LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
 	}
-	
+
 	if (!priv->wep_is_on && bss->UsingWEP) {
 		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
 		priv->station_is_associated = 0;
 		return;
 	}
-		
+
 	if (priv->wep_is_on && !bss->UsingWEP) {
 		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
 		priv->station_is_associated = 0;
@@ -3011,30 +3036,28 @@
 	}
 
 	atmel_enter_state(priv, STATION_STATE_JOINNING);
-	
+
 	if (priv->operating_mode == IW_MODE_INFRA)
 		join(priv, BSS_TYPE_INFRASTRUCTURE);
-	else 
+	else
 		join(priv, BSS_TYPE_AD_HOC);
 }
 
-
 static void restart_search(struct atmel_private *priv)
 {
 	int bss_index;
-	
+
 	if (!priv->connect_to_any_BSS) {
 		atmel_scan(priv, 1);
 	} else {
 		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
-		
-		if ((bss_index = retrieve_bss(priv)) != -1) 
+
+		if ((bss_index = retrieve_bss(priv)) != -1)
 			atmel_join_bss(priv, bss_index);
 		else
 			atmel_scan(priv, 0);
-		
-	} 
-}	
+	}
+}
 
 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
 {
@@ -3050,21 +3073,21 @@
 	}
 
 	rssi = rssi * 100 / max_rssi;
-	if((rssi + old) % 2)
-		priv->wstats.qual.level =  ((rssi + old)/2) + 1;
+	if ((rssi + old) % 2)
+		priv->wstats.qual.level = (rssi + old) / 2 + 1;
 	else
-		priv->wstats.qual.level =  ((rssi + old)/2);		
+		priv->wstats.qual.level = (rssi + old) / 2;
 	priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
 	priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
 }
 
 static void atmel_smooth_qual(struct atmel_private *priv)
 {
-	unsigned long time_diff = (jiffies - priv->last_qual)/HZ;
+	unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
 	while (time_diff--) {
 		priv->last_qual += HZ;
-		priv->wstats.qual.qual = priv->wstats.qual.qual/2;
-		priv->wstats.qual.qual += 
+		priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
+		priv->wstats.qual.qual +=
 			priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
 		priv->beacons_this_sec = 0;
 	}
@@ -3073,15 +3096,17 @@
 }
 
 /* deals with incoming managment frames. */
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
-		      u16 frame_len, u8 rssi)
+static void atmel_management_frame(struct atmel_private *priv,
+				   struct ieee80211_hdr_4addr *header,
+				   u16 frame_len, u8 rssi)
 {
 	u16 subtype;
-	
-	switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE) {
-	case C80211_SUBTYPE_MGMT_BEACON :
+
+	subtype = le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_STYPE;
+	switch (subtype) {
+	case C80211_SUBTYPE_MGMT_BEACON:
 	case C80211_SUBTYPE_MGMT_ProbeResponse:
-		
+
 		/* beacon frame has multiple variable-length fields -
 		   never let an engineer loose with a data structure design. */
 		{
@@ -3099,7 +3124,7 @@
 				u8 ds_length;
 				/* ds here */
 			} *beacon = (struct beacon_format *)priv->rx_buf;
-			
+
 			u8 channel, rates_length, ssid_length;
 			u64 timestamp = le64_to_cpu(beacon->timestamp);
 			u16 beacon_interval = le16_to_cpu(beacon->interval);
@@ -3107,7 +3132,7 @@
 			u8 *beaconp = priv->rx_buf;
 			ssid_length = beacon->ssid_length;
 			/* this blows chunks. */
-			if (frame_len < 14 || frame_len < ssid_length + 15) 
+			if (frame_len < 14 || frame_len < ssid_length + 15)
 				return;
 			rates_length = beaconp[beacon->ssid_length + 15];
 			if (frame_len < ssid_length + rates_length + 18)
@@ -3115,10 +3140,10 @@
 			if (ssid_length >  MAX_SSID_LENGTH)
 				return;
 			channel = beaconp[ssid_length + rates_length + 18];
-		       
+
 			if (priv->station_state == STATION_STATE_READY) {
 				smooth_rssi(priv, rssi);
-				if (is_frame_from_current_bss(priv, header)) { 
+				if (is_frame_from_current_bss(priv, header)) {
 					priv->beacons_this_sec++;
 					atmel_smooth_qual(priv);
 					if (priv->last_beacon_timestamp) {
@@ -3132,41 +3157,43 @@
 					handle_beacon_probe(priv, capability, channel);
 				}
 			}
-			
-			if (priv->station_state == STATION_STATE_SCANNING ) 
-				store_bss_info(priv, header, capability, beacon_interval, channel,
-					       rssi, ssid_length, &beacon->rates_el_id,
-					       subtype == C80211_SUBTYPE_MGMT_BEACON) ;
+
+			if (priv->station_state == STATION_STATE_SCANNING)
+				store_bss_info(priv, header, capability,
+					       beacon_interval, channel, rssi,
+					       ssid_length,
+					       &beacon->rates_el_id,
+					       subtype == C80211_SUBTYPE_MGMT_BEACON);
 		}
 		break;
-		
+
 	case C80211_SUBTYPE_MGMT_Authentication:
 
 		if (priv->station_state == STATION_STATE_AUTHENTICATING)
 			authenticate(priv, frame_len);
-	
+
 		break;
-		
+
 	case C80211_SUBTYPE_MGMT_ASS_RESPONSE:
 	case C80211_SUBTYPE_MGMT_REASS_RESPONSE:
-		
-		if (priv->station_state == STATION_STATE_ASSOCIATING || 
+
+		if (priv->station_state == STATION_STATE_ASSOCIATING ||
 		    priv->station_state == STATION_STATE_REASSOCIATING)
 			associate(priv, frame_len, subtype);
-		
+
 		break;
 
 	case C80211_SUBTYPE_MGMT_DISASSOSIATION:
-		if (priv->station_is_associated && 
-		    priv->operating_mode == IW_MODE_INFRA && 
+		if (priv->station_is_associated &&
+		    priv->operating_mode == IW_MODE_INFRA &&
 		    is_frame_from_current_bss(priv, header)) {
 			priv->station_was_associated = 0;
 			priv->station_is_associated = 0;
-			
+
 			atmel_enter_state(priv, STATION_STATE_JOINNING);
 			join(priv, BSS_TYPE_INFRASTRUCTURE);
 		}
-		
+
 		break;
 
 	case C80211_SUBTYPE_MGMT_Deauthentication:
@@ -3177,7 +3204,7 @@
 			atmel_enter_state(priv, STATION_STATE_JOINNING);
 			join(priv, BSS_TYPE_INFRASTRUCTURE);
 		}
-		
+
 		break;
 	}
 }
@@ -3185,76 +3212,73 @@
 /* run when timer expires */
 static void atmel_management_timer(u_long a)
 {
-  struct net_device *dev = (struct net_device *) a;
-  struct atmel_private *priv = netdev_priv(dev);
-  unsigned long flags;
-  
-  /* Check if the card has been yanked. */
-  if (priv->card && priv->present_callback && 
-      !(*priv->present_callback)(priv->card))
-	  return;
-  
-  spin_lock_irqsave(&priv->irqlock, flags);
+	struct net_device *dev = (struct net_device *) a;
+	struct atmel_private *priv = netdev_priv(dev);
+	unsigned long flags;
 
-  switch (priv->station_state) {
-	  
-  case STATION_STATE_AUTHENTICATING:
-	  if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
-		  atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
-		  priv->station_is_associated = 0;
-		  priv->AuthenticationRequestRetryCnt = 0;
-		  restart_search(priv);
-	  } else {
-		  priv->AuthenticationRequestRetryCnt++;
-		  priv->CurrentAuthentTransactionSeqNum = 0x0001;
-		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-		  send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
+	/* Check if the card has been yanked. */
+	if (priv->card && priv->present_callback &&
+		!(*priv->present_callback)(priv->card))
+		return;
+
+	spin_lock_irqsave(&priv->irqlock, flags);
+
+	switch (priv->station_state) {
+
+	case STATION_STATE_AUTHENTICATING:
+		if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
+			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+			priv->station_is_associated = 0;
+			priv->AuthenticationRequestRetryCnt = 0;
+			restart_search(priv);
+		} else {
+			priv->AuthenticationRequestRetryCnt++;
+			priv->CurrentAuthentTransactionSeqNum = 0x0001;
+			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+			send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
 	  }
-	  
 	  break;
 
-  case STATION_STATE_ASSOCIATING:
-	  if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
-		  atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
-		  priv->station_is_associated = 0;
-		  priv->AssociationRequestRetryCnt = 0;
-		  restart_search(priv);
-	  } else {
-		  priv->AssociationRequestRetryCnt++;
-		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-		  send_association_request(priv, 0);
-	  }
+	case STATION_STATE_ASSOCIATING:
+		if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
+			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+			priv->station_is_associated = 0;
+			priv->AssociationRequestRetryCnt = 0;
+			restart_search(priv);
+		} else {
+			priv->AssociationRequestRetryCnt++;
+			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+			send_association_request(priv, 0);
+		}
+	  break;
 
-	  break;
-		  
-  case STATION_STATE_REASSOCIATING:	
-	  if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
-		  atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
-		  priv->station_is_associated = 0;
-		  priv->ReAssociationRequestRetryCnt = 0;
-		  restart_search(priv);
-	  } else {
-		  priv->ReAssociationRequestRetryCnt++;
-		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
-		  send_association_request(priv, 1);
-	  }
+	case STATION_STATE_REASSOCIATING:
+		if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
+			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+			priv->station_is_associated = 0;
+			priv->ReAssociationRequestRetryCnt = 0;
+			restart_search(priv);
+		} else {
+			priv->ReAssociationRequestRetryCnt++;
+			mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+			send_association_request(priv, 1);
+		}
+		break;
 
-	  break;
-  
-  default:
-	  break;
-  }
-  
-  spin_unlock_irqrestore(&priv->irqlock, flags);
+	default:
+		break;
+	}
+
+	spin_unlock_irqrestore(&priv->irqlock, flags);
 }
-  
+
 static void atmel_command_irq(struct atmel_private *priv)
 {
 	u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
 	u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
 	int fast_scan;
-	
-	if (status == CMD_STATUS_IDLE || 
+
+	if (status == CMD_STATUS_IDLE ||
 	    status == CMD_STATUS_IN_PROGRESS)
 		return;
 
@@ -3266,20 +3290,20 @@
 			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
 				      (u8 *)priv->CurrentBSSID, 6);
 			atmel_enter_state(priv, STATION_STATE_READY);
-		}			
+		}
 		break;
-		
+
 	case CMD_Scan:
 		fast_scan = priv->fast_scan;
 		priv->fast_scan = 0;
-		
+
 		if (status != CMD_STATUS_COMPLETE) {
 			atmel_scan(priv, 1);
 		} else {
 			int bss_index = retrieve_bss(priv);
 			if (bss_index != -1) {
 				atmel_join_bss(priv, bss_index);
-			} else if (priv->operating_mode == IW_MODE_ADHOC && 
+			} else if (priv->operating_mode == IW_MODE_ADHOC &&
 				   priv->SSID_size != 0) {
 				start(priv, BSS_TYPE_AD_HOC);
 			} else {
@@ -3289,16 +3313,16 @@
 			priv->site_survey_state = SITE_SURVEY_COMPLETED;
 		}
 		break;
-		
+
 	case CMD_SiteSurvey:
 		priv->fast_scan = 0;
-		
+
 		if (status != CMD_STATUS_COMPLETE)
 			return;
-		
+
 		priv->site_survey_state = SITE_SURVEY_COMPLETED;
 		if (priv->station_is_associated) {
-			atmel_enter_state(priv, STATION_STATE_READY);				
+			atmel_enter_state(priv, STATION_STATE_READY);
 		} else {
 			atmel_scan(priv, 1);
 		}
@@ -3312,16 +3336,15 @@
 			} else {
 				priv->AuthenticationRequestRetryCnt = 0;
 				atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
-				
+
 				mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
 				priv->CurrentAuthentTransactionSeqNum = 0x0001;
 				send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
 			}
 			return;
 		}
-		
+
 		atmel_scan(priv, 1);
-		
 	}
 }
 
@@ -3333,20 +3356,20 @@
 
 	if (priv->card_type == CARD_TYPE_SPI_FLASH)
 		atmel_set_gcr(priv->dev, GCR_REMAP);
-	
+
 	/* wake up on-board processor */
 	atmel_clear_gcr(priv->dev, 0x0040);
 	atmel_write16(priv->dev, BSR, BSS_SRAM);
-	
+
 	if (priv->card_type == CARD_TYPE_SPI_FLASH)
 		mdelay(100);
 
 	/* and wait for it */
-	for (i =  LOOP_RETRY_LIMIT; i; i--) {
+	for (i = LOOP_RETRY_LIMIT; i; i--) {
 		mr1 = atmel_read16(priv->dev, MR1);
 		mr3 = atmel_read16(priv->dev, MR3);
-		
-		if (mr3 & MAC_BOOT_COMPLETE) 
+
+		if (mr3 & MAC_BOOT_COMPLETE)
 			break;
 		if (mr1 & MAC_BOOT_COMPLETE &&
 		    priv->bus_type == BUS_TYPE_PCCARD)
@@ -3357,35 +3380,36 @@
 		printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
 		return 0;
 	}
-		
+
 	if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
 		printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
 		return 0;
 	}
-	
-	/* now check for completion of MAC initialization through  
-	   the FunCtrl field of the IFACE, poll MR1 to detect completion of	  
-	   MAC initialization, check completion status, set interrupt mask,  
-	   enables interrupts and calls Tx and Rx initialization functions */  
-	
+
+	/* now check for completion of MAC initialization through
+	   the FunCtrl field of the IFACE, poll MR1 to detect completion of
+	   MAC initialization, check completion status, set interrupt mask,
+	   enables interrupts and calls Tx and Rx initialization functions */
+
 	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
-	
-	for (i =  LOOP_RETRY_LIMIT; i; i--) {
+
+	for (i = LOOP_RETRY_LIMIT; i; i--) {
 		mr1 = atmel_read16(priv->dev, MR1);
 		mr3 = atmel_read16(priv->dev, MR3);
-		
-		if (mr3 & MAC_INIT_COMPLETE) 
+
+		if (mr3 & MAC_INIT_COMPLETE)
 			break;
 		if (mr1 & MAC_INIT_COMPLETE &&
 		    priv->bus_type == BUS_TYPE_PCCARD)
 			break;
 	}
-	
+
 	if (i == 0) {
-		printk(KERN_ALERT "%s: MAC failed to initialise.\n", priv->dev->name);
+		printk(KERN_ALERT "%s: MAC failed to initialise.\n",
+				priv->dev->name);
 		return 0;
 	}
-	
+
 	/* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
 	if ((mr3 & MAC_INIT_COMPLETE) &&
 	    !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
@@ -3398,9 +3422,9 @@
 		return 0;
 	}
 
-	atmel_copy_to_host(priv->dev, (unsigned char *)iface, 
+	atmel_copy_to_host(priv->dev, (unsigned char *)iface,
 			   priv->host_info_base, sizeof(*iface));
-        
+
 	iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
 	iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
 	iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
@@ -3424,16 +3448,16 @@
 {
 	int rc = 0;
 	struct atmel_private *priv = netdev_priv(dev);
-	 
+
 	/* reset pccard */
-	if (priv->bus_type == BUS_TYPE_PCCARD) 
+	if (priv->bus_type == BUS_TYPE_PCCARD)
 		atmel_write16(dev, GCR, 0x0060);
-	
+
 	atmel_write16(dev, GCR, 0x0040);
 	mdelay(500);
-	
+
 	if (atmel_read16(dev, MR2) == 0) {
-		/* No stored firmware so load a small stub which just 
+		/* No stored firmware so load a small stub which just
 		   tells us the MAC address */
 		int i;
 		priv->card_type = CARD_TYPE_EEPROM;
@@ -3442,7 +3466,7 @@
 		atmel_set_gcr(dev, GCR_REMAP);
 		atmel_clear_gcr(priv->dev, 0x0040);
 		atmel_write16(dev, BSR, BSS_SRAM);
-		for (i =  LOOP_RETRY_LIMIT; i; i--) 
+		for (i = LOOP_RETRY_LIMIT; i; i--)
 			if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
 				break;
 		if (i == 0) {
@@ -3451,7 +3475,7 @@
 			atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
 			/* got address, now squash it again until the network
 			   interface is opened */
-			if (priv->bus_type == BUS_TYPE_PCCARD) 
+			if (priv->bus_type == BUS_TYPE_PCCARD)
 				atmel_write16(dev, GCR, 0x0060);
 			atmel_write16(dev, GCR, 0x0040);
 			rc = 1;
@@ -3459,7 +3483,7 @@
 	} else if (atmel_read16(dev, MR4) == 0) {
 		/* Mac address easy in this case. */
 		priv->card_type = CARD_TYPE_PARALLEL_FLASH;
-		atmel_write16(dev,  BSR, 1);	
+		atmel_write16(dev,  BSR, 1);
 		atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
 		atmel_write16(dev,  BSR, 0x200);
 		rc = 1;
@@ -3469,16 +3493,16 @@
 		priv->card_type = CARD_TYPE_SPI_FLASH;
 		if (atmel_wakeup_firmware(priv)) {
 			atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
-			
+
 			/* got address, now squash it again until the network
 			   interface is opened */
-			if (priv->bus_type == BUS_TYPE_PCCARD) 
+			if (priv->bus_type == BUS_TYPE_PCCARD)
 				atmel_write16(dev, GCR, 0x0060);
 			atmel_write16(dev, GCR, 0x0040);
 			rc = 1;
 		}
 	}
-	
+
 	if (rc) {
 		if (dev->dev_addr[0] == 0xFF) {
 			u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
@@ -3486,27 +3510,27 @@
 			memcpy(dev->dev_addr, default_mac, 6);
 		}
 	}
-	
+
 	return rc;
 }
 
-static void build_wep_mib(struct atmel_private *priv)
 /* Move the encyption information on the MIB structure.
    This routine is for the pre-WPA firmware: later firmware has
    a different format MIB and a different routine. */
+static void build_wep_mib(struct atmel_private *priv)
 {
 	struct { /* NB this is matched to the hardware, don't change. */
-		u8 wep_is_on;                 
+		u8 wep_is_on;
 		u8 default_key; /* 0..3 */
 		u8 reserved;
 		u8 exclude_unencrypted;
-		
+
 		u32 WEPICV_error_count;
 		u32 WEP_excluded_count;
-		
+
 		u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
- 		u8 encryption_level; /* 0, 1, 2 */
-		u8 reserved2[3]; 
+		u8 encryption_level; /* 0, 1, 2 */
+		u8 reserved2[3];
 	} mib;
 	int i;
 
@@ -3515,54 +3539,55 @@
 		if (priv->wep_key_len[priv->default_key] > 5)
 			mib.encryption_level = 2;
 		else
-			mib.encryption_level = 1;	
+			mib.encryption_level = 1;
 	} else {
 		mib.encryption_level = 0;
 	}
 
 	mib.default_key = priv->default_key;
 	mib.exclude_unencrypted = priv->exclude_unencrypted;
-	
-	for(i = 0; i < MAX_ENCRYPTION_KEYS;  i++)
+
+	for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
 		memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
-		
+
 	atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
 }
 
 static void build_wpa_mib(struct atmel_private *priv)
 {
-	/* This is for the later (WPA enabled) firmware. */	   
+	/* This is for the later (WPA enabled) firmware. */
 
 	struct { /* NB this is matched to the hardware, don't change. */
 		u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
 		u8 receiver_address[6];
-		u8 wep_is_on;                 
+		u8 wep_is_on;
 		u8 default_key; /* 0..3 */
 		u8 group_key;
 		u8 exclude_unencrypted;
 		u8 encryption_type;
 		u8 reserved;
-		
+
 		u32 WEPICV_error_count;
 		u32 WEP_excluded_count;
-		
+
 		u8 key_RSC[4][8];
 	} mib;
-	
+
 	int i;
 
 	mib.wep_is_on = priv->wep_is_on;
 	mib.exclude_unencrypted = priv->exclude_unencrypted;
 	memcpy(mib.receiver_address, priv->CurrentBSSID, 6);
-	
+
 	/* zero all the keys before adding in valid ones. */
 	memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
-	
+
 	if (priv->wep_is_on) {
-		/* There's a comment in the Atmel code to the effect that this is only valid
-		   when still using WEP, it may need to be set to something to use WPA */
+		/* There's a comment in the Atmel code to the effect that this
+		   is only valid when still using WEP, it may need to be set to
+		   something to use WPA */
 		memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
-		
+
 		mib.default_key = mib.group_key = 255;
 		for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
 			if (priv->wep_key_len[i] > 0) {
@@ -3570,12 +3595,12 @@
 				if (i == priv->default_key) {
 					mib.default_key = i;
 					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
-					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite; 
+					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
 				} else {
 					mib.group_key = i;
 					priv->group_cipher_suite = priv->pairwise_cipher_suite;
 				        mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
-					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;	
+					mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
 				}
 			}
 		}
@@ -3583,47 +3608,47 @@
 			mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
 		if (mib.group_key == 255)
 			mib.group_key = mib.default_key;
-		
+
 	}
-	
+
 	atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
 }
-					
-static int reset_atmel_card(struct net_device *dev) 
+
+static int reset_atmel_card(struct net_device *dev)
 {
 	/* do everything necessary to wake up the hardware, including
 	   waiting for the lightning strike and throwing the knife switch....
 
-	   set all the Mib values which matter in the card to match 
+	   set all the Mib values which matter in the card to match
 	   their settings in the atmel_private structure. Some of these
 	   can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
 	   can only be changed by tearing down the world and coming back through
 	   here.
 
-	   This routine is also responsible for initialising some 
-	   hardware-specific fields in the atmel_private structure, 
+	   This routine is also responsible for initialising some
+	   hardware-specific fields in the atmel_private structure,
 	   including a copy of the firmware's hostinfo stucture
 	   which is the route into the rest of the firmare datastructures. */
 
 	struct atmel_private *priv = netdev_priv(dev);
 	u8 configuration;
-	
+
 	/* data to add to the firmware names, in priority order
 	   this implemenents firmware versioning */
-	
+
 	static char *firmware_modifier[] = {
 		"-wpa",
 		"",
 		NULL
 	};
-		
+
 	/* reset pccard */
-	if (priv->bus_type == BUS_TYPE_PCCARD) 
+	if (priv->bus_type == BUS_TYPE_PCCARD)
 		atmel_write16(priv->dev, GCR, 0x0060);
-		
+
 	/* stop card , disable interrupts */
 	atmel_write16(priv->dev, GCR, 0x0040);
-		
+
 	if (priv->card_type == CARD_TYPE_EEPROM) {
 		/* copy in firmware if needed */
 		const struct firmware *fw_entry = NULL;
@@ -3636,13 +3661,13 @@
 					       "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
 					       dev->name);
 					printk(KERN_INFO
-					       "%s: if not, use the firmware= module parameter.\n", 
+					       "%s: if not, use the firmware= module parameter.\n",
 					       dev->name);
 					strcpy(priv->firmware_id, "atmel_at76c502.bin");
 				}
 				if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) {
-					printk(KERN_ALERT 
-					       "%s: firmware %s is missing, cannot continue.\n", 
+					printk(KERN_ALERT
+					       "%s: firmware %s is missing, cannot continue.\n",
 					       dev->name, priv->firmware_id);
 					return 0;
 				}
@@ -3654,7 +3679,7 @@
 				while (fw_table[fw_index].fw_type != priv->firmware_type
 						&& fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
 					fw_index++;
-				
+
 				/* construct the actual firmware file name */
 				if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
 					int i;
@@ -3669,24 +3694,24 @@
 					}
 				}
 				if (!success) {
-					printk(KERN_ALERT 
-					       "%s: firmware %s is missing, cannot start.\n", 
+					printk(KERN_ALERT
+					       "%s: firmware %s is missing, cannot start.\n",
 					       dev->name, priv->firmware_id);
 					priv->firmware_id[0] = '\0';
-					return 0;	
+					return 0;
 				}
 			}
-			
+
 			fw = fw_entry->data;
 			len = fw_entry->size;
 		}
-		
+
 	        if (len <= 0x6000) {
 			atmel_write16(priv->dev, BSR, BSS_IRAM);
 			atmel_copy_to_card(priv->dev, 0, fw, len);
 			atmel_set_gcr(priv->dev, GCR_REMAP);
 		} else {
-			/* Remap */ 
+			/* Remap */
 			atmel_set_gcr(priv->dev, GCR_REMAP);
 			atmel_write16(priv->dev, BSR, BSS_IRAM);
 			atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
@@ -3708,45 +3733,45 @@
 	   the 3com broken-ness filter. */
 	priv->use_wpa = (priv->host_info.major_version == 4);
 	priv->radio_on_broken = (priv->host_info.major_version == 5);
-	
+
         /* unmask all irq sources */
 	atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
-	
+
 	/* int Tx system and enable Tx */
 	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
 	atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
 	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
 
-	priv->tx_desc_free = priv->host_info.tx_desc_count;		
-	priv->tx_desc_head = 0;									
-	priv->tx_desc_tail = 0;									
+	priv->tx_desc_free = priv->host_info.tx_desc_count;
+	priv->tx_desc_head = 0;
+	priv->tx_desc_tail = 0;
 	priv->tx_desc_previous = 0;
 	priv->tx_free_mem = priv->host_info.tx_buff_size;
-	priv->tx_buff_head = 0;	
-	priv->tx_buff_tail = 0;	
-		
-	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
-	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
+	priv->tx_buff_head = 0;
+	priv->tx_buff_tail = 0;
+
+	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
 				   configuration | FUNC_CTRL_TxENABLE);
 
 	/* init Rx system and enable */
 	priv->rx_desc_head = 0;
-	
-	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
-	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
+
+	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
 				   configuration | FUNC_CTRL_RxENABLE);
-			
+
 	if (!priv->radio_on_broken) {
-		if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == 
+		if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
 		    CMD_STATUS_REJECTED_RADIO_OFF) {
-			printk(KERN_INFO 
+			printk(KERN_INFO
 			       "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n",
 			       dev->name);
                         return 0;
 		}
 	}
-	
+
 	/* set up enough MIB values to run. */
 	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
 	atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
@@ -3755,7 +3780,7 @@
 	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
 	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
 	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
-	atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS, 
+	atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
 		      priv->dev->dev_addr, 6);
 	atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
 	atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
@@ -3766,42 +3791,44 @@
 		build_wpa_mib(priv);
 	else
 		build_wep_mib(priv);
-	
+
 	return 1;
 }
 
-static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size)
+static void atmel_send_command(struct atmel_private *priv, int command,
+			       void *cmd, int cmd_size)
 {
 	if (cmd)
-		atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET), 
+		atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
 				   cmd, cmd_size);
-	
+
 	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
 	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
 }
-	
-static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size)
+
+static int atmel_send_command_wait(struct atmel_private *priv, int command,
+				   void *cmd, int cmd_size)
 {
 	int i, status;
-	
+
 	atmel_send_command(priv, command, cmd, cmd_size);
-	
+
 	for (i = 5000; i; i--) {
 		status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
-		if (status != CMD_STATUS_IDLE && 
+		if (status != CMD_STATUS_IDLE &&
 		    status != CMD_STATUS_IN_PROGRESS)
 			break;
 		udelay(20);
 	}
-	
+
 	if (i == 0) {
 		printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
 		status =  CMD_STATUS_HOST_ERROR;
-	} else { 
+	} else {
 		if (command != CMD_EnableRadio)
 			status = CMD_STATUS_COMPLETE;
 	}
-	
+
 	return status;
 }
 
@@ -3827,7 +3854,8 @@
 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
 }
 
-static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data)
+static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
+			    u16 data)
 {
 	struct get_set_mib m;
 	m.type = type;
@@ -3839,7 +3867,8 @@
 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
 }
 
-static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
+static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
+			  u8 *data, int data_len)
 {
 	struct get_set_mib m;
 	m.type = type;
@@ -3848,23 +3877,24 @@
 
 	if (data_len > MIB_MAX_DATA_BYTES)
 		printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
-	
+
 	memcpy(m.data, data, data_len);
 	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
 }
 
-static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
+static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
+			  u8 *data, int data_len)
 {
 	struct get_set_mib m;
 	m.type = type;
 	m.size = data_len;
 	m.index = index;
-	
+
 	if (data_len > MIB_MAX_DATA_BYTES)
 		printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
-	
+
 	atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
-	atmel_copy_to_host(priv->dev, data, 
+	atmel_copy_to_host(priv->dev, data,
 			   atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
 }
 
@@ -3873,11 +3903,12 @@
 	int i;
 	outw(data, dev->base_addr + AR);
 	/* Address register appears to need some convincing..... */
-	for (i = 0; data != inw(dev->base_addr + AR) && i<10; i++)
+	for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
 		outw(data, dev->base_addr + AR);
 }
 
-static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len)
+static void atmel_copy_to_card(struct net_device *dev, u16 dest,
+			       unsigned char *src, u16 len)
 {
 	int i;
 	atmel_writeAR(dev, dest);
@@ -3894,7 +3925,8 @@
 		atmel_write8(dev, DR, *src);
 }
 
-static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len)
+static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
+			       u16 src, u16 len)
 {
 	int i;
 	atmel_writeAR(dev, src);
@@ -3930,22 +3962,24 @@
 			break;
 		udelay(20);
 	}
-	
-	if (!i) return 0; /* timed out */
-	
+
+	if (!i)
+		return 0; /* timed out */
+
 	atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
 	if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
 		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
-		if (!j--) return 0; /* timed out */
+		if (!j--)
+			return 0; /* timed out */
 		goto retry;
 	}
-	
+
 	return 1;
 }
 
 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
 {
-       	atmel_writeAR(priv->dev, pos);	
+	atmel_writeAR(priv->dev, pos);
 	atmel_write16(priv->dev, DR, data); /* card is little-endian */
 	atmel_write16(priv->dev, DR, data >> 16);
 }
@@ -4017,9 +4051,9 @@
 				  serial output, since SO is normally high.  But it
 				  does cause 8 clock cycles and thus 8 bits to be
 				  clocked in to the chip.  See Atmel's SPI
-				  controller (e.g. AT91M55800) timing and 4K 
+				  controller (e.g. AT91M55800) timing and 4K
 				  SPI EEPROM manuals */
-				 
+
 	.set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
 	.set NVRAM_IMAGE, 0x02000200
 	.set NVRAM_LENGTH, 0x0200
@@ -4032,24 +4066,24 @@
 	.set MR4, 0xC
 RESET_VECTOR:
         b RESET_HANDLER
-UNDEF_VECTOR:  
+UNDEF_VECTOR:
         b HALT1
-SWI_VECTOR:            
+SWI_VECTOR:
         b HALT1
-IABORT_VECTOR: 
+IABORT_VECTOR:
         b HALT1
-DABORT_VECTOR:         
-RESERVED_VECTOR:    
+DABORT_VECTOR:
+RESERVED_VECTOR:
         b HALT1
-IRQ_VECTOR:    
+IRQ_VECTOR:
         b HALT1
-FIQ_VECTOR:    
+FIQ_VECTOR:
 	b HALT1
 HALT1:	b HALT1
 RESET_HANDLER:
 	mov     r0, #CPSR_INITIAL
 	msr	CPSR_c, r0	/* This is probably unnecessary */
-			
+
 /* I'm guessing this is initializing clock generator electronics for SPI */
 	ldr	r0, =SPI_CGEN_BASE
 	mov	r1, #0
@@ -4061,7 +4095,7 @@
 	str	r1, [r0, #28]
 	mov	r1, #1
 	str	r1, [r0, #8]
-	
+
 	ldr	r0, =MRBASE
 	mov	r1, #0
 	strh	r1, [r0, #MR1]
@@ -4094,7 +4128,7 @@
 	ldmia	sp!, {lr}
 	bx	lr
 .endfunc
-	
+
 .func Get_MAC_Addr, GET_MAC_ADDR
 GET_MAC_ADDR:
 	stmdb	sp!, {lr}
@@ -4110,13 +4144,13 @@
 .func Delay9, DELAY9
 DELAY9:
 	adds	r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
-DELAYLOOP:	
+DELAYLOOP:
 	beq	DELAY9_done
 	subs	r0, r0, #1
 	b	DELAYLOOP
-DELAY9_done:	
+DELAY9_done:
 	bx	lr
-.endfunc	
+.endfunc
 
 .func SP_Init, SP_INIT
 SP_INIT:
@@ -4145,26 +4179,26 @@
 	ldr	r0, [r0, #SP_RDR]
 	bx	lr
 .endfunc
-.func NVRAM_Init, NVRAM_INIT	
+.func NVRAM_Init, NVRAM_INIT
 NVRAM_INIT:
 	ldr	r1, =SP_BASE
 	ldr	r0, [r1, #SP_RDR]
 	mov	r0, #NVRAM_CMD_RDSR
 	str	r0, [r1, #SP_TDR]
-SP_loop1:	
+SP_loop1:
 	ldr	r0, [r1, #SP_SR]
 	tst	r0, #SP_TDRE
 	beq	SP_loop1
 
 	mov	r0, #SPI_8CLOCKS
-	str	r0, [r1, #SP_TDR] 
-SP_loop2:	
+	str	r0, [r1, #SP_TDR]
+SP_loop2:
 	ldr	r0, [r1, #SP_SR]
 	tst	r0, #SP_TDRE
 	beq	SP_loop2
 
 	ldr	r0, [r1, #SP_RDR]
-SP_loop3:	
+SP_loop3:
 	ldr	r0, [r1, #SP_SR]
 	tst	r0, #SP_RDRF
 	beq	SP_loop3
@@ -4173,7 +4207,7 @@
 	and	r0, r0, #255
 	bx	lr
 .endfunc
-	
+
 .func NVRAM_Xfer, NVRAM_XFER
 	/* r0 = dest address */
 	/* r1 = not used */
@@ -4185,11 +4219,11 @@
 	mov	r4, r3		/* save r3 (length) */
 	mov	r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
 	and	r0, r0, #8
-	add	r0, r0, #NVRAM_CMD_READ 
+	add	r0, r0, #NVRAM_CMD_READ
 	ldr	r1, =NVRAM_SCRATCH
 	strb	r0, [r1, #0]	/* save command in NVRAM_SCRATCH[0] */
 	strb	r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
-_local1:	
+_local1:
 	bl	NVRAM_INIT
 	tst	r0, #NVRAM_SR_RDY
 	bne	_local1
@@ -4211,7 +4245,7 @@
 	cmp	r0, #0
 	bls	_local2
 	ldr	r5, =NVRAM_SCRATCH
-_local4:	
+_local4:
 	ldrb	r6, [r5, r3]
 	str	r6, [r4, #SP_TDR]
 _local3:
@@ -4225,7 +4259,7 @@
 	mov	r3, #SPI_8CLOCKS
 	str	r3, [r4, #SP_TDR]
 	ldr	r0, [r4, #SP_RDR]
-_local5:	
+_local5:
 	ldr	r0, [r4, #SP_SR]
 	tst	r0, #SP_RDRF
 	beq	_local5
@@ -4233,12 +4267,12 @@
 	mov	r0, #0
 	cmp	r2, #0  /* r2 is # of bytes to copy in */
 	bls	_local6
-_local7:	
+_local7:
 	ldr	r5, [r4, #SP_SR]
 	tst	r5, #SP_TDRE
 	beq	_local7
 	str	r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
-_local8:	
+_local8:
 	ldr	r5, [r4, #SP_SR]
 	tst	r5, #SP_RDRF
 	beq	_local8
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 17d1fd9..d6f4a5a 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -93,8 +93,6 @@
 
 static void atmel_config(dev_link_t *link);
 static void atmel_release(dev_link_t *link);
-static int atmel_event(event_t event, int priority,
-		       event_callback_args_t *args);
 
 /*
    The attach() and detach() entry points are used to create and destroy
@@ -102,8 +100,7 @@
    needed to manage one actual PCMCIA card.
 */
 
-static dev_link_t *atmel_attach(void);
-static void atmel_detach(dev_link_t *);
+static void atmel_detach(struct pcmcia_device *p_dev);
 
 /*
    You'll also need to prototype all the functions that will actually
@@ -113,14 +110,6 @@
 */
 
 /*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "atmel_cs";
-
-/*
    A linked list of "instances" of the  atmelnet device.  Each actual
    PCMCIA card corresponds to one device instance, and is described
    by one dev_link_t structure (defined in ds.h).
@@ -130,15 +119,7 @@
    device numbers are used to derive the corresponding array index.
 */
 
-static dev_link_t *dev_list = NULL;
-
 /*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
    A driver needs to provide a dev_node_t structure for each device
    on a card.  In some cases, there is only one device per card (for
    example, ethernet cards, modems).  In other cases, there may be
@@ -171,27 +152,25 @@
   
   ======================================================================*/
 
-static dev_link_t *atmel_attach(void)
+static int atmel_attach(struct pcmcia_device *p_dev)
 {
-	client_reg_t client_reg;
 	dev_link_t *link;
 	local_info_t *local;
-	int ret;
-	
+
 	DEBUG(0, "atmel_attach()\n");
 
 	/* Initialize the dev_link_t structure */
 	link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
 	if (!link) {
 		printk(KERN_ERR "atmel_cs: no memory for new device\n");
-		return NULL;
+		return -ENOMEM;
 	}
-	
+
 	/* Interrupt setup */
 	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
 	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 	link->irq.Handler = NULL;
-	
+
 	/*
 	  General socket configuration defaults can go here.  In this
 	  client, we assume very little, and rely on the CIS for almost
@@ -202,30 +181,23 @@
 	link->conf.Attributes = 0;
 	link->conf.Vcc = 50;
 	link->conf.IntType = INT_MEMORY_AND_IO;
-	
+
 	/* Allocate space for private device-specific data */
 	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
 	if (!local) {
 		printk(KERN_ERR "atmel_cs: no memory for new device\n");
 		kfree (link);
-		return NULL;
+		return -ENOMEM;
 	}
 	link->priv = local;
-	
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		atmel_detach(link);
-		return NULL;
-	}
-	
-	return link;
+
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	atmel_config(link);
+
+	return 0;
 } /* atmel_attach */
 
 /*======================================================================
@@ -237,27 +209,15 @@
   
   ======================================================================*/
 
-static void atmel_detach(dev_link_t *link)
+static void atmel_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
-	
+	dev_link_t *link = dev_to_instance(p_dev);
+
 	DEBUG(0, "atmel_detach(0x%p)\n", link);
-	
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link) break;
-	if (*linkp == NULL)
-		return;
 
 	if (link->state & DEV_CONFIG)
 		atmel_release(link);
-		
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
 
-	/* Unlink device structure, free pieces */
-	*linkp = link->next;
 	kfree(link->priv);
 	kfree(link);
 }
@@ -477,60 +437,34 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-/*======================================================================
-  
-  The card status event handler.  Mostly, this schedules other
-  stuff to run after an event is received.
-
-  When a CARD_REMOVAL event is received, we immediately set a
-  private flag to block future accesses to this device.  All the
-  functions that actually access the device should check this flag
-  to make sure the card is still present.
-  
-  ======================================================================*/
-
-static int atmel_event(event_t event, int priority,
-		      event_callback_args_t *args)
+static int atmel_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 	local_info_t *local = link->priv;
-	
-	DEBUG(1, "atmel_event(0x%06x)\n", event);
-	
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			netif_device_detach(local->eth_dev);
-			atmel_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		atmel_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG) {
-			netif_device_detach(local->eth_dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			atmel_open(local->eth_dev);
-			netif_device_attach(local->eth_dev);
-		}
-		break;
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		netif_device_detach(local->eth_dev);
+		pcmcia_release_configuration(link->handle);
 	}
+
 	return 0;
-} /* atmel_event */
+}
+
+static int atmel_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	local_info_t *local = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		atmel_open(local->eth_dev);
+		netif_device_attach(local->eth_dev);
+	}
+
+	return 0;
+}
 
 /*====================================================================*/
 /* We use the driver_info field to store the correct firmware type for a card. */
@@ -581,10 +515,11 @@
 	.drv		= {
 		.name	= "atmel_cs",
         },
-	.attach         = atmel_attach,
-	.event		= atmel_event,
-	.detach		= atmel_detach,
+	.probe          = atmel_attach,
+	.remove		= atmel_detach,
 	.id_table	= atmel_ids,
+	.suspend	= atmel_suspend,
+	.resume		= atmel_resume,
 };
 
 static int atmel_cs_init(void)
@@ -595,7 +530,6 @@
 static void atmel_cs_cleanup(void)
 {
         pcmcia_unregister_driver(&atmel_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 /*
diff --git a/drivers/net/wireless/hostap/Makefile b/drivers/net/wireless/hostap/Makefile
index fc62235..353ccb9 100644
--- a/drivers/net/wireless/hostap/Makefile
+++ b/drivers/net/wireless/hostap/Makefile
@@ -1,3 +1,4 @@
+hostap-y := hostap_main.o
 obj-$(CONFIG_HOSTAP) += hostap.o
 
 obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 2643976..8bc0b528 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -25,7 +25,6 @@
 
 static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
 static dev_info_t dev_info = "hostap_cs";
-static dev_link_t *dev_list = NULL;
 
 MODULE_AUTHOR("Jouni Malinen");
 MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
@@ -203,10 +202,9 @@
 
 
 
-static void prism2_detach(dev_link_t *link);
+static void prism2_detach(struct pcmcia_device *p_dev);
 static void prism2_release(u_long arg);
-static int prism2_event(event_t event, int priority,
-			event_callback_args_t *args);
+static int prism2_config(dev_link_t *link);
 
 
 static int prism2_pccard_card_present(local_info_t *local)
@@ -503,15 +501,13 @@
 
 /* allocate local data and register with CardServices
  * initialize dev_link structure, but do not configure the card yet */
-static dev_link_t *prism2_attach(void)
+static int prism2_attach(struct pcmcia_device *p_dev)
 {
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
 	if (link == NULL)
-		return NULL;
+		return -ENOMEM;
 
 	memset(link, 0, sizeof(dev_link_t));
 
@@ -519,50 +515,27 @@
 	link->conf.Vcc = 33;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* register with CardServices */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		prism2_detach(link);
-		return NULL;
-	}
-	return link;
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	if (prism2_config(link))
+		PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
+
+	return 0;
 }
 
 
-static void prism2_detach(dev_link_t *link)
+static void prism2_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	PDEBUG(DEBUG_FLOW, "prism2_detach\n");
 
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-	if (*linkp == NULL) {
-		printk(KERN_WARNING "%s: Attempt to detach non-existing "
-		       "PCMCIA client\n", dev_info);
-		return;
-	}
-
 	if (link->state & DEV_CONFIG) {
 		prism2_release((u_long)link);
 	}
 
-	if (link->handle) {
-		int res = pcmcia_deregister_client(link->handle);
-		if (res) {
-			printk("CardService(DeregisterClient) => %d\n", res);
-			cs_error(link->handle, DeregisterClient, res);
-		}
-	}
-
-	*linkp = link->next;
 	/* release net devices */
 	if (link->priv) {
 		struct hostap_cs_priv *hw_priv;
@@ -846,83 +819,57 @@
 	PDEBUG(DEBUG_FLOW, "release - done\n");
 }
 
-
-static int prism2_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int hostap_cs_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = (struct net_device *) link->priv;
 	int dev_open = 0;
 
+	PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
+
+	link->state |= DEV_SUSPEND;
+
 	if (link->state & DEV_CONFIG) {
 		struct hostap_interface *iface = netdev_priv(dev);
 		if (iface && iface->local)
 			dev_open = iface->local->num_dev_open > 0;
-	}
-
-	switch (event) {
-	case CS_EVENT_CARD_INSERTION:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		if (prism2_config(link)) {
-			PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
-		}
-		break;
-
-	case CS_EVENT_CARD_REMOVAL:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info);
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
+		if (dev_open) {
 			netif_stop_queue(dev);
 			netif_device_detach(dev);
-			prism2_release((u_long) link);
 		}
-		break;
-
-	case CS_EVENT_PM_SUSPEND:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
-		link->state |= DEV_SUSPEND;
-		/* fall through */
-
-	case CS_EVENT_RESET_PHYSICAL:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
-		if (link->state & DEV_CONFIG) {
-			if (dev_open) {
-				netif_stop_queue(dev);
-				netif_device_detach(dev);
-			}
-			prism2_suspend(dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-
-	case CS_EVENT_PM_RESUME:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
-		link->state &= ~DEV_SUSPEND;
-		/* fall through */
-
-	case CS_EVENT_CARD_RESET:
-		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle,
-						     &link->conf);
-			prism2_hw_shutdown(dev, 1);
-			prism2_hw_config(dev, dev_open ? 0 : 1);
-			if (dev_open) {
-				netif_device_attach(dev);
-				netif_start_queue(dev);
-			}
-		}
-		break;
-
-	default:
-		PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
-		       dev_info, event);
-		break;
+		prism2_suspend(dev);
+		pcmcia_release_configuration(link->handle);
 	}
+
 	return 0;
 }
 
+static int hostap_cs_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = (struct net_device *) link->priv;
+	int dev_open = 0;
+
+	PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		struct hostap_interface *iface = netdev_priv(dev);
+		if (iface && iface->local)
+			dev_open = iface->local->num_dev_open > 0;
+
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+		prism2_hw_shutdown(dev, 1);
+		prism2_hw_config(dev, dev_open ? 0 : 1);
+		if (dev_open) {
+			netif_device_attach(dev);
+			netif_start_queue(dev);
+		}
+	}
+
+	return 0;
+}
 
 static struct pcmcia_device_id hostap_cs_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100),
@@ -982,11 +929,12 @@
 	.drv		= {
 		.name	= "hostap_cs",
 	},
-	.attach		= prism2_attach,
-	.detach		= prism2_detach,
+	.probe		= prism2_attach,
+	.remove		= prism2_detach,
 	.owner		= THIS_MODULE,
-	.event		= prism2_event,
 	.id_table	= hostap_cs_ids,
+	.suspend	= hostap_cs_suspend,
+	.resume		= hostap_cs_resume,
 };
 
 static int __init init_prism2_pccard(void)
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap_main.c
similarity index 100%
rename from drivers/net/wireless/hostap/hostap.c
rename to drivers/net/wireless/hostap/hostap_main.c
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 77d2a21..44cd3fc 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -175,7 +175,7 @@
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2005 Intel Corporation"
 
 /* Debugging stuff */
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define CONFIG_IPW2100_RX_DEBUG	/* Reception debugging */
 #endif
 
@@ -208,7 +208,7 @@
 
 static u32 ipw2100_debug_level = IPW_DL_NONE;
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define IPW_DEBUG(level, message...) \
 do { \
 	if (ipw2100_debug_level & (level)) { \
@@ -219,9 +219,9 @@
 } while (0)
 #else
 #define IPW_DEBUG(level, message...) do {} while (0)
-#endif				/* CONFIG_IPW_DEBUG */
+#endif				/* CONFIG_IPW2100_DEBUG */
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static const char *command_types[] = {
 	"undefined",
 	"unused",		/* HOST_ATTENTION */
@@ -2081,7 +2081,7 @@
 	priv->status &= ~STATUS_SCANNING;
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 #define IPW2100_HANDLER(v, f) { v, f, # v }
 struct ipw2100_status_indicator {
 	int status;
@@ -2094,7 +2094,7 @@
 	int status;
 	void (*cb) (struct ipw2100_priv * priv, u32 status);
 };
-#endif				/* CONFIG_IPW_DEBUG */
+#endif				/* CONFIG_IPW2100_DEBUG */
 
 static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
 {
@@ -2149,7 +2149,7 @@
 static void isr_rx_complete_command(struct ipw2100_priv *priv,
 				    struct ipw2100_cmd_header *cmd)
 {
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
 		IPW_DEBUG_HC("Command completed '%s (%d)'\n",
 			     command_types[cmd->host_command_reg],
@@ -2167,7 +2167,7 @@
 	wake_up_interruptible(&priv->wait_command_queue);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static const char *frame_types[] = {
 	"COMMAND_STATUS_VAL",
 	"STATUS_CHANGE_VAL",
@@ -2290,7 +2290,7 @@
 
 static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
 {
-#ifdef CONFIG_IPW_DEBUG_C3
+#ifdef CONFIG_IPW2100_DEBUG_C3
 	struct ipw2100_status *status = &priv->status_queue.drv[i];
 	u32 match, reg;
 	int j;
@@ -2312,7 +2312,7 @@
 	}
 #endif
 
-#ifdef CONFIG_IPW_DEBUG_C3
+#ifdef CONFIG_IPW2100_DEBUG_C3
 	/* Halt the fimrware so we can get a good image */
 	write_register(priv->net_dev, IPW_REG_RESET_REG,
 		       IPW_AUX_HOST_RESET_REG_STOP_MASTER);
@@ -2716,7 +2716,7 @@
 	list_del(element);
 	DEC_STAT(&priv->fw_pend_stat);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	{
 		int i = txq->oldest;
 		IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
@@ -2782,7 +2782,7 @@
 			       "something else: ids %d=%d.\n",
 			       priv->net_dev->name, txq->oldest, packet->index);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 		if (packet->info.c_struct.cmd->host_command_reg <
 		    sizeof(command_types) / sizeof(*command_types))
 			IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
@@ -2975,7 +2975,7 @@
 
 		IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n",
 			     packet->index, tbd->host_addr, tbd->buf_length);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 		if (packet->info.d_struct.txb->nr_frags > 1)
 			IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
 				       packet->info.d_struct.txb->nr_frags);
@@ -3827,7 +3827,7 @@
 		       priv->rx_interrupts, priv->inta_other);
 	out += sprintf(out, "firmware resets: %d\n", priv->resets);
 	out += sprintf(out, "firmware hangs: %d\n", priv->hangs);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	out += sprintf(out, "packet mismatch image: %s\n",
 		       priv->snapshot[0] ? "YES" : "NO");
 #endif
@@ -3982,7 +3982,7 @@
 
 static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 static ssize_t show_debug_level(struct device_driver *d, char *buf)
 {
 	return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
@@ -4011,7 +4011,7 @@
 
 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
 		   store_debug_level);
-#endif				/* CONFIG_IPW_DEBUG */
+#endif				/* CONFIG_IPW2100_DEBUG */
 
 static ssize_t show_fatal_error(struct device *d,
 				struct device_attribute *attr, char *buf)
@@ -4937,7 +4937,7 @@
 	};
 	int err;
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	if (bssid != NULL)
 		IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
 			     bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
@@ -6858,7 +6858,7 @@
 
 	ret = pci_module_init(&ipw2100_pci_driver);
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	ipw2100_debug_level = debug;
 	driver_create_file(&ipw2100_pci_driver.driver,
 			   &driver_attr_debug_level);
@@ -6873,7 +6873,7 @@
 static void __exit ipw2100_exit(void)
 {
 	/* FIXME: IPG: check that we have no instances of the devices open */
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 	driver_remove_file(&ipw2100_pci_driver.driver,
 			   &driver_attr_debug_level);
 #endif
@@ -8558,7 +8558,7 @@
 
 		quality = min(beacon_qual, min(tx_qual, rssi_qual));
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2100_DEBUG
 		if (beacon_qual == quality)
 			IPW_DEBUG_WX("Quality clamped by Missed Beacons\n");
 		else if (tx_qual == quality)
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 7c65b10..f6c5144 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -73,7 +73,7 @@
  * you simply need to add your entry to the ipw2100_debug_levels array.
  *
  * If you do not see debug_level in /proc/net/ipw2100 then you do not have
- * CONFIG_IPW_DEBUG defined in your kernel configuration
+ * CONFIG_IPW2100_DEBUG defined in your kernel configuration
  *
  */
 
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 5e7c7e9..cdfe502 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -462,7 +462,7 @@
 	ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 static char *ipw_error_desc(u32 val)
 {
 	switch (val) {
@@ -1235,7 +1235,7 @@
 			      const char *buf, size_t count)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 	struct net_device *dev = priv->net_dev;
 #endif
 	char buffer[] = "00000000";
@@ -1754,7 +1754,7 @@
 		IPW_ERROR("Firmware error detected.  Restarting.\n");
 		if (priv->error) {
 			IPW_ERROR("Sysfs 'error' log already exists.\n");
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 			if (ipw_debug_level & IPW_DL_FW_ERRORS) {
 				struct ipw_fw_error *error =
 				    ipw_alloc_error_log(priv);
@@ -1770,7 +1770,7 @@
 			else
 				IPW_ERROR("Error allocating sysfs 'error' "
 					  "log.\n");
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 			if (ipw_debug_level & IPW_DL_FW_ERRORS)
 				ipw_dump_error_log(priv, priv->error);
 #endif
@@ -3778,7 +3778,7 @@
 	{0x2E, "Cipher suite is rejected per security policy"},
 };
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 static const char *ipw_get_status_code(u16 status)
 {
 	int i;
@@ -4250,7 +4250,7 @@
 					if (priv->
 					    status & (STATUS_ASSOCIATED |
 						      STATUS_AUTH)) {
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 						struct notif_authenticate *auth
 						    = &notif->u.auth;
 						IPW_DEBUG(IPW_DL_NOTIF |
@@ -4944,12 +4944,11 @@
 	struct ipw_rx_queue *rxq;
 	int i;
 
-	rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
+	rxq = kzalloc(sizeof(*rxq), GFP_KERNEL);
 	if (unlikely(!rxq)) {
 		IPW_ERROR("memory allocation failed\n");
 		return NULL;
 	}
-	memset(rxq, 0, sizeof(*rxq));
 	spin_lock_init(&rxq->lock);
 	INIT_LIST_HEAD(&rxq->rx_free);
 	INIT_LIST_HEAD(&rxq->rx_used);
@@ -5828,7 +5827,7 @@
 	up(&priv->sem);
 }
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 static void ipw_debug_config(struct ipw_priv *priv)
 {
 	IPW_DEBUG_INFO("Scan completed, no valid APs matched "
@@ -7456,8 +7455,7 @@
 	/* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
 	hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
 	if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
-	    ((is_multicast_ether_addr(hdr->addr1) ||
-	      is_broadcast_ether_addr(hdr->addr1)) ?
+	    (is_multicast_ether_addr(hdr->addr1) ?
 	     !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
 		ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
@@ -7648,8 +7646,7 @@
 			return 0;
 
 		/* {broad,multi}cast packets to our BSSID go through */
-		if (is_multicast_ether_addr(header->addr1) ||
-		    is_broadcast_ether_addr(header->addr1))
+		if (is_multicast_ether_addr(header->addr1))
 			return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
@@ -7662,8 +7659,7 @@
 			return 0;
 
 		/* {broad,multi}cast packets to our BSS go through */
-		if (is_multicast_ether_addr(header->addr1) ||
-		    is_broadcast_ether_addr(header->addr1))
+		if (is_multicast_ether_addr(header->addr1))
 			return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
@@ -7815,7 +7811,7 @@
 
 	while (i != r) {
 		rxb = priv->rxq->queue[i];
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 		if (unlikely(rxb == NULL)) {
 			printk(KERN_CRIT "Queue not allocated!\n");
 			break;
@@ -9657,8 +9653,7 @@
 	switch (priv->ieee->iw_mode) {
 	case IW_MODE_ADHOC:
 		hdr_len = IEEE80211_3ADDR_LEN;
-		unicast = !(is_multicast_ether_addr(hdr->addr1) ||
-			    is_broadcast_ether_addr(hdr->addr1));
+		unicast = !is_multicast_ether_addr(hdr->addr1);
 		id = ipw_find_station(priv, hdr->addr1);
 		if (id == IPW_INVALID_STATION) {
 			id = ipw_add_station(priv, hdr->addr1);
@@ -9673,8 +9668,7 @@
 
 	case IW_MODE_INFRA:
 	default:
-		unicast = !(is_multicast_ether_addr(hdr->addr3) ||
-			    is_broadcast_ether_addr(hdr->addr3));
+		unicast = !is_multicast_ether_addr(hdr->addr3);
 		hdr_len = IEEE80211_3ADDR_LEN;
 		id = 0;
 		break;
@@ -10956,7 +10950,7 @@
 
 	priv->net_dev = net_dev;
 	priv->pci_dev = pdev;
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 	ipw_debug_level = debug;
 #endif
 	spin_lock_init(&priv->lock);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 1c98db0..e65620a 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1301,14 +1301,14 @@
 
 /* debug macros */
 
-#ifdef CONFIG_IPW_DEBUG
+#ifdef CONFIG_IPW2200_DEBUG
 #define IPW_DEBUG(level, fmt, args...) \
 do { if (ipw_debug_level & (level)) \
   printk(KERN_DEBUG DRV_NAME": %c %s " fmt, \
          in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
 #else
 #define IPW_DEBUG(level, fmt, args...) do {} while (0)
-#endif				/* CONFIG_IPW_DEBUG */
+#endif				/* CONFIG_IPW2200_DEBUG */
 
 /*
  * To use the debug system;
@@ -1332,7 +1332,7 @@
  * you simply need to add your entry to the ipw_debug_levels array.
  *
  * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IPW_DEBUG defined in your kernel configuration
+ * CONFIG_IPW2200_DEBUG defined in your kernel configuration
  *
  */
 
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 92793b9..bf6271e 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -166,8 +166,6 @@
 #define DEBUG(n, args...)
 #endif
 
-static dev_info_t dev_info = "netwave_cs";
-
 /*====================================================================*/
 
 /* Parameters that can be set with 'insmod' */
@@ -195,12 +193,9 @@
 
 /* PCMCIA (Card Services) related functions */
 static void netwave_release(dev_link_t *link);     /* Card removal */
-static int  netwave_event(event_t event, int priority, 
-					      event_callback_args_t *args);
 static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card 
 													   insertion */
-static dev_link_t *netwave_attach(void);     /* Create instance */
-static void netwave_detach(dev_link_t *);    /* Destroy instance */
+static void netwave_detach(struct pcmcia_device *p_dev);    /* Destroy instance */
 
 /* Hardware configuration */
 static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase);
@@ -228,17 +223,6 @@
 static void set_multicast_list(struct net_device *dev);
 
 /*
-   A linked list of "instances" of the skeleton device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-
-   You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
-   device numbers are used to derive the corresponding array index.
-*/
-static dev_link_t *dev_list;
-
-/*
    A dev_link_t structure has fields for most things that are needed
    to keep track of a socket, but there will usually be some device
    specific information that also needs to be kept track of.  The
@@ -394,20 +378,18 @@
  *     configure the card at this point -- we wait until we receive a
  *     card insertion event.
  */
-static dev_link_t *netwave_attach(void)
+static int netwave_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     struct net_device *dev;
     netwave_private *priv;
-    int ret;
-    
+
     DEBUG(0, "netwave_attach()\n");
-    
+
     /* Initialize the dev_link_t structure */
     dev = alloc_etherdev(sizeof(netwave_private));
     if (!dev)
-	return NULL;
+	return -ENOMEM;
     priv = netdev_priv(dev);
     link = &priv->link;
     link->priv = dev;
@@ -449,21 +431,14 @@
     dev->open = &netwave_open;
     dev->stop = &netwave_close;
     link->irq.Instance = dev;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	netwave_detach(link);
-	return NULL;
-    }
 
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    netwave_pcmcia_config( link);
+
+    return 0;
 } /* netwave_attach */
 
 /*
@@ -474,42 +449,20 @@
  *    structures are freed.  Otherwise, the structures will be freed
  *    when the device is released.
  */
-static void netwave_detach(dev_link_t *link)
+static void netwave_detach(struct pcmcia_device *p_dev)
 {
-    struct net_device *dev = link->priv;
-    dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    DEBUG(0, "netwave_detach(0x%p)\n", link);
-  
-    /*
-	  If the device is currently configured and active, we won't
-	  actually delete it yet.  Instead, it is marked so that when
-	  the release() function is called, that will trigger a proper
-	  detach().
-	*/
-    if (link->state & DEV_CONFIG)
-	netwave_release(link);
-	
-    /* Break the link with Card Services */
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-      {
-	DEBUG(1, "netwave_cs: detach fail, '%s' not in list\n",
-	      link->dev->dev_name);
-	return;
-      }
+	DEBUG(0, "netwave_detach(0x%p)\n", link);
 
-    /* Unlink device structure, free pieces */
-    *linkp = link->next;
-    if (link->dev) 
-	unregister_netdev(dev);
-    free_netdev(dev);
-    
+	if (link->state & DEV_CONFIG)
+		netwave_release(link);
+
+	if (link->dev)
+		unregister_netdev(dev);
+
+	free_netdev(dev);
 } /* netwave_detach */
 
 /*
@@ -935,69 +888,38 @@
     link->state &= ~DEV_CONFIG;
 }
 
-/*
- * Function netwave_event (event, priority, args)
- *
- *    The card status event handler.  Mostly, this schedules other
- *    stuff to run after an event is received.  A CARD_REMOVAL event
- *    also sets some flags to discourage the net drivers from trying
- *    to talk to the card any more.
- *
- *    When a CARD_REMOVAL event is received, we immediately set a flag
- *    to block future accesses to this device.  All the functions that
- *    actually access the device should check this flag to make sure
- *    the card is still present.
- *
- */
-static int netwave_event(event_t event, int priority,
-			 event_callback_args_t *args)
+static int netwave_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
-	
-    DEBUG(1, "netwave_event(0x%06x)\n", event);
-  
-    switch (event) {
-    case CS_EVENT_REGISTRATION_COMPLETE:
-	DEBUG(0, "netwave_cs: registration complete\n");
-	break;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG) {
-	    netif_device_detach(dev);
-	    netwave_release(link);
-	}
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	netwave_pcmcia_config( link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG) {
-	    if (link->open)
-		netif_device_detach(dev);
-	    pcmcia_release_configuration(link->handle);
+		if (link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
 	}
-	break;
-    case CS_EVENT_PM_RESUME:
+
+	return 0;
+}
+
+static int netwave_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    if (link->open) {
-		netwave_reset(dev);
-		netif_device_attach(dev);
-	    }
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			netwave_reset(dev);
+			netif_device_attach(dev);
+		}
 	}
-	break;
-    }
-    return 0;
-} /* netwave_event */
+
+	return 0;
+}
+
 
 /*
  * Function netwave_doreset (ioBase, ramBase)
@@ -1491,10 +1413,11 @@
 	.drv		= {
 		.name	= "netwave_cs",
 	},
-	.attach		= netwave_attach,
-	.event		= netwave_event,
-	.detach		= netwave_detach,
+	.probe		= netwave_attach,
+	.remove		= netwave_detach,
 	.id_table       = netwave_ids,
+	.suspend	= netwave_suspend,
+	.resume		= netwave_resume,
 };
 
 static int __init init_netwave_cs(void)
@@ -1505,7 +1428,6 @@
 static void __exit exit_netwave_cs(void)
 {
 	pcmcia_unregister_driver(&netwave_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_netwave_cs);
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 488ab06..6fd0bf7 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -3512,9 +3512,8 @@
 			break;
 		default:
 			err = -EINVAL;
-		}
-		if (err)
 			goto out;
+		}
 		
 		if (prq->flags & IW_POWER_TIMEOUT) {
 			priv->pm_on = 1;
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index dc1128a..b664708 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -43,17 +43,6 @@
 MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
 
 /********************************************************************/
-/* Magic constants						    */
-/********************************************************************/
-
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card
- * configuration database.
- */
-static dev_info_t dev_info = DRIVER_NAME;
-
-/********************************************************************/
 /* Data structures						    */
 /********************************************************************/
 
@@ -69,19 +58,14 @@
 	unsigned long hard_reset_in_progress; 
 };
 
-/*
- * A linked list of "instances" of the device.  Each actual PCMCIA
- * card corresponds to one device instance, and is described by one
- * dev_link_t structure (defined in ds.h).
- */
-static dev_link_t *dev_list; /* = NULL */
 
 /********************************************************************/
 /* Function prototypes						    */
 /********************************************************************/
 
+static void orinoco_cs_config(dev_link_t *link);
 static void orinoco_cs_release(dev_link_t *link);
-static void orinoco_cs_detach(dev_link_t *link);
+static void orinoco_cs_detach(struct pcmcia_device *p_dev);
 
 /********************************************************************/
 /* Device methods     						    */
@@ -119,19 +103,17 @@
  * The dev_link structure is initialized, but we don't actually
  * configure the card at this point -- we wait until we receive a card
  * insertion event.  */
-static dev_link_t *
-orinoco_cs_attach(void)
+static int
+orinoco_cs_attach(struct pcmcia_device *p_dev)
 {
 	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
 	if (! dev)
-		return NULL;
+		return -ENOMEM;
 	priv = netdev_priv(dev);
 	card = priv->card;
 
@@ -154,22 +136,15 @@
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
 	/* Register with Card Services */
-	/* FIXME: need a lock? */
-	link->next = dev_list;
-	dev_list = link;
+	link->next = NULL;
 
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210; /* FIXME: what does this mean? */
-	client_reg.event_callback_args.client_data = link;
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		orinoco_cs_detach(link);
-		return NULL;
-	}
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	orinoco_cs_config(link);
 
-	return link;
+	return 0;
 }				/* orinoco_cs_attach */
 
 /*
@@ -178,27 +153,14 @@
  * are freed.  Otherwise, the structures will be freed when the device
  * is released.
  */
-static void orinoco_cs_detach(dev_link_t *link)
+static void orinoco_cs_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-
-	BUG_ON(*linkp == NULL);
-
 	if (link->state & DEV_CONFIG)
 		orinoco_cs_release(link);
 
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
-	/* Unlink device structure, and free it */
-	*linkp = link->next;
 	DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
 	if (link->dev) {
 		DEBUG(0, PFX "About to unregister net device %p\n",
@@ -465,106 +427,82 @@
 		ioport_unmap(priv->hw.iobase);
 }				/* orinoco_cs_release */
 
-/*
- * The card status event handler.  Mostly, this schedules other stuff
- * to run after an event is received.
- */
-static int
-orinoco_cs_event(event_t event, int priority,
-		       event_callback_args_t * args)
+static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct orinoco_pccard *card = priv->card;
 	int err = 0;
 	unsigned long flags;
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			unsigned long flags;
-
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		/* This is probably racy, but I can't think of
+		   a better way, short of rewriting the PCMCIA
+		   layer to not suck :-( */
+		if (! test_bit(0, &card->hard_reset_in_progress)) {
 			spin_lock_irqsave(&priv->lock, flags);
+
+			err = __orinoco_down(dev);
+			if (err)
+				printk(KERN_WARNING "%s: Error %d downing interface\n",
+				       dev->name, err);
+
 			netif_device_detach(dev);
 			priv->hw_unavailable++;
+
 			spin_unlock_irqrestore(&priv->lock, flags);
 		}
-		break;
 
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		orinoco_cs_config(link);
-		break;
-
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		/* Mark the device as stopped, to block IO until later */
-		if (link->state & DEV_CONFIG) {
-			/* This is probably racy, but I can't think of
-                           a better way, short of rewriting the PCMCIA
-                           layer to not suck :-( */
-			if (! test_bit(0, &card->hard_reset_in_progress)) {
-				spin_lock_irqsave(&priv->lock, flags);
-
-				err = __orinoco_down(dev);
-				if (err)
-					printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
-					       dev->name,
-					       event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
-					       err);
-				
-				netif_device_detach(dev);
-				priv->hw_unavailable++;
-
-				spin_unlock_irqrestore(&priv->lock, flags);
-			}
-
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			/* FIXME: should we double check that this is
-			 * the same card as we had before */
-			pcmcia_request_configuration(link->handle, &link->conf);
-
-			if (! test_bit(0, &card->hard_reset_in_progress)) {
-				err = orinoco_reinit_firmware(dev);
-				if (err) {
-					printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
-					       dev->name, err);
-					break;
-				}
-				
-				spin_lock_irqsave(&priv->lock, flags);
-				
-				netif_device_attach(dev);
-				priv->hw_unavailable--;
-				
-				if (priv->open && ! priv->hw_unavailable) {
-					err = __orinoco_up(dev);
-					if (err)
-						printk(KERN_ERR "%s: Error %d restarting card\n",
-						       dev->name, err);
-					
-				}
-
-				spin_unlock_irqrestore(&priv->lock, flags);
-			}
-		}
-		break;
+		pcmcia_release_configuration(link->handle);
 	}
 
-	return err;
-}				/* orinoco_cs_event */
+	return 0;
+}
+
+static int orinoco_cs_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_pccard *card = priv->card;
+	int err = 0;
+	unsigned long flags;
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		/* FIXME: should we double check that this is
+		 * the same card as we had before */
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+		if (! test_bit(0, &card->hard_reset_in_progress)) {
+			err = orinoco_reinit_firmware(dev);
+			if (err) {
+				printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
+				       dev->name, err);
+				return -EIO;
+			}
+
+			spin_lock_irqsave(&priv->lock, flags);
+
+			netif_device_attach(dev);
+			priv->hw_unavailable--;
+
+			if (priv->open && ! priv->hw_unavailable) {
+				err = __orinoco_up(dev);
+				if (err)
+					printk(KERN_ERR "%s: Error %d restarting card\n",
+					       dev->name, err);
+			}
+
+			spin_unlock_irqrestore(&priv->lock, flags);
+		}
+	}
+
+	return 0;
+}
+
 
 /********************************************************************/
 /* Module initialization					    */
@@ -665,10 +603,11 @@
 	.drv		= {
 		.name	= DRIVER_NAME,
 	},
-	.attach		= orinoco_cs_attach,
-	.detach		= orinoco_cs_detach,
-	.event		= orinoco_cs_event,
+	.probe		= orinoco_cs_attach,
+	.remove		= orinoco_cs_detach,
 	.id_table       = orinoco_cs_ids,
+	.suspend	= orinoco_cs_suspend,
+	.resume		= orinoco_cs_resume,
 };
 
 static int __init
@@ -683,7 +622,6 @@
 exit_orinoco_cs(void)
 {
 	pcmcia_unregister_driver(&orinoco_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_orinoco_cs);
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
index d8afd51..d1a670b 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -1,6 +1,8 @@
 /* orinoco_nortel.c
  * 
  * Driver for Prism II devices which would usually be driven by orinoco_cs,
+ * but are connected to the PCI bus by a PCI-to-PCMCIA adapter used in
+ * Nortel emobility, Symbol LA-4113 and Symbol LA-4123.
  * but are connected to the PCI bus by a Nortel PCI-PCMCIA-Adapter. 
  *
  * Copyright (C) 2002 Tobias Hoffmann
@@ -165,7 +167,7 @@
 		goto fail_resources;
 	}
 
-	iomem = pci_iomap(pdev, 3, 0);
+	iomem = pci_iomap(pdev, 2, 0);
 	if (!iomem) {
 		err = -ENOMEM;
 		goto fail_map_io;
@@ -265,6 +267,8 @@
 static struct pci_device_id nortel_pci_id_table[] = {
 	/* Nortel emobility PCI */
 	{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
+	/* Symbol LA-4123 PCI */
+	{0x1562, 0x0001, PCI_ANY_ID, PCI_ANY_ID,},
 	{0,},
 };
 
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 70fd6fd..319180c 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -92,9 +92,7 @@
 /** Prototypes based on PCMCIA skeleton driver *******************************/
 static void ray_config(dev_link_t *link);
 static void ray_release(dev_link_t *link);
-static int ray_event(event_t event, int priority, event_callback_args_t *args);
-static dev_link_t *ray_attach(void);
-static void ray_detach(dev_link_t *);
+static void ray_detach(struct pcmcia_device *p_dev);
 
 /***** Prototypes indicated by device structure ******************************/
 static int ray_dev_close(struct net_device *dev);
@@ -192,12 +190,6 @@
 static char *phy_addr = NULL;
 
 
-/* The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-static dev_info_t dev_info = "ray_cs";
-
 /* A linked list of "instances" of the ray device.  Each actual
    PCMCIA card corresponds to one device instance, and is described
    by one dev_link_t structure (defined in ds.h).
@@ -314,12 +306,10 @@
     configure the card at this point -- we wait until we receive a
     card insertion event.
 =============================================================================*/
-static dev_link_t *ray_attach(void)
+static int ray_attach(struct pcmcia_device *p_dev)
 {
-    client_reg_t client_reg;
     dev_link_t *link;
     ray_dev_t *local;
-    int ret;
     struct net_device *dev;
     
     DEBUG(1, "ray_attach()\n");
@@ -328,7 +318,7 @@
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
 
     if (!link)
-	    return NULL;
+	    return -ENOMEM;
 
     /* Allocate space for private device-specific data */
     dev = alloc_etherdev(sizeof(ray_dev_t));
@@ -387,30 +377,19 @@
     dev->stop = &ray_dev_close;
     netif_stop_queue(dev);
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-
-    DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n");
-
     init_timer(&local->timer);
 
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-        printk("ray_cs ray_attach RegisterClient unhappy - detaching\n");
-        cs_error(link->handle, RegisterClient, ret);
-        ray_detach(link);
-        return NULL;
-    }
-    DEBUG(2,"ray_cs ray_attach ending\n");
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    ray_config(link);
+
+    return 0;
 
 fail_alloc_dev:
     kfree(link);
-    return NULL;
+    return -ENOMEM;
 } /* ray_attach */
 /*=============================================================================
     This deletes a driver "instance".  The device is de-registered
@@ -418,9 +397,12 @@
     structures are freed.  Otherwise, the structures will be freed
     when the device is released.
 =============================================================================*/
-static void ray_detach(dev_link_t *link)
+static void ray_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
+    struct net_device *dev;
+    ray_dev_t *local;
 
     DEBUG(1, "ray_detach(0x%p)\n", link);
     
@@ -430,22 +412,18 @@
     if (*linkp == NULL)
         return;
 
-    /* If the device is currently configured and active, we won't
-      actually delete it yet.  Instead, it is marked so that when
-      the release() function is called, that will trigger a proper
-      detach().
-    */
-    if (link->state & DEV_CONFIG)
-        ray_release(link);
+    dev = link->priv;
 
-    /* Break the link with Card Services */
-    if (link->handle)
-        pcmcia_deregister_client(link->handle);
-    
+    if (link->state & DEV_CONFIG) {
+	    ray_release(link);
+
+	    local = (ray_dev_t *)dev->priv;
+            del_timer(&local->timer);
+    }
+
     /* Unlink device structure, free pieces */
     *linkp = link->next;
     if (link->priv) {
-        struct net_device *dev = link->priv;
 	if (link->dev) unregister_netdev(dev);
         free_netdev(dev);
     }
@@ -891,65 +869,40 @@
     DEBUG(2,"ray_release ending\n");
 }
 
-/*=============================================================================
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
-=============================================================================*/
-static int ray_event(event_t event, int priority,
-                     event_callback_args_t *args)
+static int ray_suspend(struct pcmcia_device *p_dev)
 {
-    dev_link_t *link = args->client_data;
-    struct net_device *dev = link->priv;
-    ray_dev_t *local = (ray_dev_t *)dev->priv;
-    DEBUG(1, "ray_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-        link->state &= ~DEV_PRESENT;
-        netif_device_detach(dev);
-        if (link->state & DEV_CONFIG) {
-	    ray_release(link);
-            del_timer(&local->timer);
-        }
-        break;
-    case CS_EVENT_CARD_INSERTION:
-        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-        ray_config(link);
-        break;
-    case CS_EVENT_PM_SUSPEND:
-        link->state |= DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-        if (link->state & DEV_CONFIG) {
-            if (link->open)
-            	netif_device_detach(dev);
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
 
-            pcmcia_release_configuration(link->handle);
-        }
-        break;
-    case CS_EVENT_PM_RESUME:
-        link->state &= ~DEV_SUSPEND;
-        /* Fall through... */
-    case CS_EVENT_CARD_RESET:
+	link->state |= DEV_SUSPEND;
         if (link->state & DEV_CONFIG) {
-            pcmcia_request_configuration(link->handle, &link->conf);
-            if (link->open) {
-                ray_reset(dev);
-		netif_device_attach(dev);
-            }
+		if (link->open)
+			netif_device_detach(dev);
+
+		pcmcia_release_configuration(link->handle);
         }
-        break;
-    }
-    return 0;
-    DEBUG(2,"ray_event ending\n");
-} /* ray_event */
+
+
+	return 0;
+}
+
+static int ray_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+        if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			ray_reset(dev);
+			netif_device_attach(dev);
+		}
+        }
+
+	return 0;
+}
+
 /*===========================================================================*/
 int ray_dev_init(struct net_device *dev)
 {
@@ -2945,10 +2898,11 @@
 	.drv		= {
 		.name	= "ray_cs",
 	},
-	.attach		= ray_attach,
-	.event		= ray_event,
-	.detach		= ray_detach,
+	.probe		= ray_attach,
+	.remove		= ray_detach,
 	.id_table       = ray_ids,
+	.suspend	= ray_suspend,
+	.resume		= ray_resume,
 };
 
 static int __init init_ray_cs(void)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b1bbc8e..fee4be1 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -57,17 +57,6 @@
 MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
 
 /********************************************************************/
-/* Magic constants						    */
-/********************************************************************/
-
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card
- * configuration database.
- */
-static dev_info_t dev_info = DRIVER_NAME;
-
-/********************************************************************/
 /* Data structures						    */
 /********************************************************************/
 
@@ -78,19 +67,12 @@
 	dev_node_t node;
 };
 
-/*
- * A linked list of "instances" of the device.  Each actual PCMCIA
- * card corresponds to one device instance, and is described by one
- * dev_link_t structure (defined in ds.h).
- */
-static dev_link_t *dev_list; /* = NULL */
-
 /********************************************************************/
 /* Function prototypes						    */
 /********************************************************************/
 
+static void spectrum_cs_config(dev_link_t *link);
 static void spectrum_cs_release(dev_link_t *link);
-static void spectrum_cs_detach(dev_link_t *link);
 
 /********************************************************************/
 /* Firmware downloader						    */
@@ -601,19 +583,17 @@
  * The dev_link structure is initialized, but we don't actually
  * configure the card at this point -- we wait until we receive a card
  * insertion event.  */
-static dev_link_t *
-spectrum_cs_attach(void)
+static int
+spectrum_cs_attach(struct pcmcia_device *p_dev)
 {
 	struct net_device *dev;
 	struct orinoco_private *priv;
 	struct orinoco_pccard *card;
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
 	if (! dev)
-		return NULL;
+		return -ENOMEM;
 	priv = netdev_priv(dev);
 	card = priv->card;
 
@@ -635,23 +615,13 @@
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	/* FIXME: need a lock? */
-	link->next = dev_list;
-	dev_list = link;
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210; /* FIXME: what does this mean? */
-	client_reg.event_callback_args.client_data = link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	spectrum_cs_config(link);
 
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		spectrum_cs_detach(link);
-		return NULL;
-	}
-
-	return link;
+	return 0;
 }				/* spectrum_cs_attach */
 
 /*
@@ -660,27 +630,14 @@
  * are freed.  Otherwise, the structures will be freed when the device
  * is released.
  */
-static void spectrum_cs_detach(dev_link_t *link)
+static void spectrum_cs_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-
-	BUG_ON(*linkp == NULL);
-
 	if (link->state & DEV_CONFIG)
 		spectrum_cs_release(link);
 
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
-	/* Unlink device structure, and free it */
-	*linkp = link->next;
 	DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
 	if (link->dev) {
 		DEBUG(0, PFX "About to unregister net device %p\n",
@@ -948,82 +905,56 @@
 		ioport_unmap(priv->hw.iobase);
 }				/* spectrum_cs_release */
 
-/*
- * The card status event handler.  Mostly, this schedules other stuff
- * to run after an event is received.
- */
+
 static int
-spectrum_cs_event(event_t event, int priority,
-		       event_callback_args_t * args)
+spectrum_cs_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 	struct orinoco_private *priv = netdev_priv(dev);
-	int err = 0;
 	unsigned long flags;
+	int err = 0;
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			unsigned long flags;
+	link->state |= DEV_SUSPEND;
+	/* Mark the device as stopped, to block IO until later */
+	if (link->state & DEV_CONFIG) {
+		spin_lock_irqsave(&priv->lock, flags);
 
-			spin_lock_irqsave(&priv->lock, flags);
-			netif_device_detach(dev);
-			priv->hw_unavailable++;
-			spin_unlock_irqrestore(&priv->lock, flags);
-		}
-		break;
+		err = __orinoco_down(dev);
+		if (err)
+			printk(KERN_WARNING "%s: Error %d downing interface\n",
+			       dev->name, err);
 
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		spectrum_cs_config(link);
-		break;
+		netif_device_detach(dev);
+		priv->hw_unavailable++;
 
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		/* Mark the device as stopped, to block IO until later */
-		if (link->state & DEV_CONFIG) {
-			/* This is probably racy, but I can't think of
-                           a better way, short of rewriting the PCMCIA
-                           layer to not suck :-( */
-			spin_lock_irqsave(&priv->lock, flags);
+		spin_unlock_irqrestore(&priv->lock, flags);
 
-			err = __orinoco_down(dev);
-			if (err)
-				printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
-				       dev->name,
-				       event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
-				       err);
-
-			netif_device_detach(dev);
-			priv->hw_unavailable++;
-
-			spin_unlock_irqrestore(&priv->lock, flags);
-
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			/* FIXME: should we double check that this is
-			 * the same card as we had before */
-			pcmcia_request_configuration(link->handle, &link->conf);
-			netif_device_attach(dev);
-			priv->hw_unavailable--;
-			schedule_work(&priv->reset_work);
-		}
-		break;
+		pcmcia_release_configuration(link->handle);
 	}
 
-	return err;
-}				/* spectrum_cs_event */
+	return 0;
+}
+
+static int
+spectrum_cs_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = netdev_priv(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		/* FIXME: should we double check that this is
+		 * the same card as we had before */
+		pcmcia_request_configuration(link->handle, &link->conf);
+		netif_device_attach(dev);
+		priv->hw_unavailable--;
+		schedule_work(&priv->reset_work);
+	}
+	return 0;
+}
+
 
 /********************************************************************/
 /* Module initialization					    */
@@ -1048,9 +979,10 @@
 	.drv		= {
 		.name	= DRIVER_NAME,
 	},
-	.attach		= spectrum_cs_attach,
-	.detach		= spectrum_cs_detach,
-	.event		= spectrum_cs_event,
+	.probe		= spectrum_cs_attach,
+	.remove		= spectrum_cs_detach,
+	.suspend	= spectrum_cs_suspend,
+	.resume		= spectrum_cs_resume,
 	.id_table       = spectrum_cs_ids,
 };
 
@@ -1066,7 +998,6 @@
 exit_spectrum_cs(void)
 {
 	pcmcia_unregister_driver(&orinoco_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_spectrum_cs);
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index c822cad..7e2039f 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4594,14 +4594,12 @@
  * configure the card at this point -- we wait until we receive a
  * card insertion event.
  */
-static dev_link_t *
-wavelan_attach(void)
+static int
+wavelan_attach(struct pcmcia_device *p_dev)
 {
-  client_reg_t	client_reg;	/* Register with cardmgr */
   dev_link_t *	link;		/* Info for cardmgr */
   struct net_device *	dev;		/* Interface generic data */
   net_local *	lp;		/* Interface specific data */
-  int		ret;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "-> wavelan_attach()\n");
@@ -4609,7 +4607,7 @@
 
   /* Initialize the dev_link_t structure */
   link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-  if (!link) return NULL;
+  if (!link) return -ENOMEM;
 
   /* The io structure describes IO port mapping */
   link->io.NumPorts1 = 8;
@@ -4627,14 +4625,13 @@
   link->conf.IntType = INT_MEMORY_AND_IO;
 
   /* Chain drivers */
-  link->next = dev_list;
-  dev_list = link;
+  link->next = NULL;
 
   /* Allocate the generic data structure */
   dev = alloc_etherdev(sizeof(net_local));
   if (!dev) {
       kfree(link);
-      return NULL;
+      return -ENOMEM;
   }
   link->priv = link->irq.Instance = dev;
 
@@ -4679,28 +4676,21 @@
   /* Other specific data */
   dev->mtu = WAVELAN_MTU;
 
-  /* Register with Card Services */
-  client_reg.dev_info = &dev_info;
-  client_reg.Version = 0x0210;
-  client_reg.event_callback_args.client_data = link;
+  link->handle = p_dev;
+  p_dev->instance = link;
 
-#ifdef DEBUG_CONFIG_INFO
-  printk(KERN_DEBUG "wavelan_attach(): almost done, calling pcmcia_register_client\n");
-#endif
-
-  ret = pcmcia_register_client(&link->handle, &client_reg);
-  if(ret != 0)
-    {
-      cs_error(link->handle, RegisterClient, ret);
-      wavelan_detach(link);
-      return NULL;
-    }
+  link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+  if(wv_pcmcia_config(link) &&
+     wv_hw_config(dev))
+	  wv_init_info(dev);
+  else
+	  dev->irq = 0;
 
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "<- wavelan_attach()\n");
 #endif
 
-  return link;
+  return 0;
 }
 
 /*------------------------------------------------------------------*/
@@ -4711,8 +4701,10 @@
  * is released.
  */
 static void
-wavelan_detach(dev_link_t *	link)
+wavelan_detach(struct pcmcia_device *p_dev)
 {
+   dev_link_t *link = dev_to_instance(p_dev);
+
 #ifdef DEBUG_CALLBACK_TRACE
   printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);
 #endif
@@ -4729,31 +4721,6 @@
       wv_pcmcia_release(link);
     }
 
-  /* Break the link with Card Services */
-  if(link->handle)
-    pcmcia_deregister_client(link->handle);
-    
-  /* Remove the interface data from the linked list */
-  if(dev_list == link)
-    dev_list = link->next;
-  else
-    {
-      dev_link_t *	prev = dev_list;
-
-      while((prev != (dev_link_t *) NULL) && (prev->next != link))
-	prev = prev->next;
-
-      if(prev == (dev_link_t *) NULL)
-	{
-#ifdef DEBUG_CONFIG_ERRORS
-	  printk(KERN_WARNING "wavelan_detach : Attempting to remove a nonexistent device.\n");
-#endif
-	  return;
-	}
-
-      prev->next = link->next;
-    }
-
   /* Free pieces */
   if(link->priv)
     {
@@ -4775,65 +4742,11 @@
 #endif
 }
 
-/*------------------------------------------------------------------*/
-/*
- * The card status event handler. Mostly, this schedules other stuff
- * to run after an event is received. A CARD_REMOVAL event also sets
- * some flags to discourage the net drivers from trying to talk to the
- * card any more.
- */
-static int
-wavelan_event(event_t		event,		/* The event received */
-	      int		priority,
-	      event_callback_args_t *	args)
+static int wavelan_suspend(struct pcmcia_device *p_dev)
 {
-  dev_link_t *	link = (dev_link_t *) args->client_data;
-  struct net_device *	dev = (struct net_device *) link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *	dev = (struct net_device *) link->priv;
 
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "->wavelan_event(): %s\n",
-	 ((event == CS_EVENT_REGISTRATION_COMPLETE)?"registration complete" :
-	  ((event == CS_EVENT_CARD_REMOVAL) ? "card removal" :
-	   ((event == CS_EVENT_CARD_INSERTION) ? "card insertion" :
-	    ((event == CS_EVENT_PM_SUSPEND) ? "pm suspend" :
-	     ((event == CS_EVENT_RESET_PHYSICAL) ? "physical reset" :
-	      ((event == CS_EVENT_PM_RESUME) ? "pm resume" :
-	       ((event == CS_EVENT_CARD_RESET) ? "card reset" :
-		"unknown"))))))));
-#endif
-
-    switch(event)
-      {
-      case CS_EVENT_REGISTRATION_COMPLETE:
-#ifdef DEBUG_CONFIG_INFO
-	printk(KERN_DEBUG "wavelan_cs: registration complete\n");
-#endif
-	break;
-
-      case CS_EVENT_CARD_REMOVAL:
-	/* Oups ! The card is no more there */
-	link->state &= ~DEV_PRESENT;
-	if(link->state & DEV_CONFIG)
-	  {
-	    /* Accept no more transmissions */
-	    netif_device_detach(dev);
-
-	    /* Release the card */
-	    wv_pcmcia_release(link);
-	  }
-	break;
-
-      case CS_EVENT_CARD_INSERTION:
-	/* Reset and configure the card */
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	if(wv_pcmcia_config(link) &&
-	   wv_hw_config(dev))
-	  wv_init_info(dev);
-	else
-	  dev->irq = 0;
-	break;
-
-      case CS_EVENT_PM_SUSPEND:
 	/* NB: wavelan_close will be called, but too late, so we are
 	 * obliged to close nicely the wavelan here. David, could you
 	 * close the device before suspending them ? And, by the way,
@@ -4848,38 +4761,37 @@
 
 	/* The card is now suspended */
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-      case CS_EVENT_RESET_PHYSICAL:
+
     	if(link->state & DEV_CONFIG)
-	  {
-      	    if(link->open)
-	      netif_device_detach(dev);
-      	    pcmcia_release_configuration(link->handle);
-	  }
-	break;
+	{
+		if(link->open)
+			netif_device_detach(dev);
+		pcmcia_release_configuration(link->handle);
+	}
 
-      case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-      case CS_EVENT_CARD_RESET:
-	if(link->state & DEV_CONFIG)
-	  {
-      	    pcmcia_request_configuration(link->handle, &link->conf);
-      	    if(link->open)	/* If RESET -> True, If RESUME -> False ? */
-	      {
-		wv_hw_reset(dev);
-		netif_device_attach(dev);
-	      }
-	  }
-	break;
-    }
-
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "<-wavelan_event()\n");
-#endif
-  return 0;
+	return 0;
 }
 
+static int wavelan_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *	dev = (struct net_device *) link->priv;
+
+	link->state &= ~DEV_SUSPEND;
+	if(link->state & DEV_CONFIG)
+	{
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if(link->open)	/* If RESET -> True, If RESUME -> False ? */
+		{
+			wv_hw_reset(dev);
+			netif_device_attach(dev);
+		}
+	}
+
+	return 0;
+}
+
+
 static struct pcmcia_device_id wavelan_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),
 	PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06),
@@ -4894,10 +4806,11 @@
 	.drv		= {
 		.name	= "wavelan_cs",
 	},
-	.attach		= wavelan_attach,
-	.event		= wavelan_event,
-	.detach		= wavelan_detach,
+	.probe		= wavelan_attach,
+	.remove		= wavelan_detach,
 	.id_table       = wavelan_ids,
+	.suspend	= wavelan_suspend,
+	.resume		= wavelan_resume,
 };
 
 static int __init
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 724a715..f2d5975 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -754,20 +754,11 @@
 static int
 	wavelan_open(struct net_device *),		/* Open the device */
 	wavelan_close(struct net_device *);	/* Close the device */
-static dev_link_t *
-	wavelan_attach(void);		/* Create a new device */
 static void
-	wavelan_detach(dev_link_t *);	/* Destroy a removed device */
-static int
-	wavelan_event(event_t,		/* Manage pcmcia events */
-		      int,
-		      event_callback_args_t *);
+	wavelan_detach(struct pcmcia_device *p_dev);	/* Destroy a removed device */
 
 /**************************** VARIABLES ****************************/
 
-static dev_info_t dev_info = "wavelan_cs";
-static dev_link_t *dev_list = NULL;	/* Linked list of devices */
-
 /*
  * Parameters that can be set with 'insmod'
  * The exact syntax is 'insmod wavelan_cs.o <var>=<value>'
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 978fdc6..48e10b0 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -105,7 +105,6 @@
  */
 static void wl3501_config(dev_link_t *link);
 static void wl3501_release(dev_link_t *link);
-static int wl3501_event(event_t event, int pri, event_callback_args_t *args);
 
 /*
  * The dev_info variable is the "key" that is used to match up this
@@ -1498,9 +1497,11 @@
  * Services. If it has been released, all local data structures are freed.
  * Otherwise, the structures will be freed when the device is released.
  */
-static void wl3501_detach(dev_link_t *link)
+static void wl3501_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	dev_link_t **linkp;
+	struct net_device *dev = link->priv;
 
 	/* Locate device structure */
 	for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next)
@@ -1514,16 +1515,12 @@
 	 * function is called, that will trigger a proper detach(). */
 
 	if (link->state & DEV_CONFIG) {
-#ifdef PCMCIA_DEBUG
-		printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' "
-		       "still locked\n", link->dev->dev_name);
-#endif
-		goto out;
-	}
+		while (link->open > 0)
+			wl3501_close(dev);
 
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
+		netif_device_detach(dev);
+		wl3501_release(link);
+	}
 
 	/* Unlink device structure, free pieces */
 	*linkp = link->next;
@@ -1956,18 +1953,16 @@
  * The dev_link structure is initialized, but we don't actually configure the
  * card at this point -- we wait until we receive a card insertion event.
  */
-static dev_link_t *wl3501_attach(void)
+static int wl3501_attach(struct pcmcia_device *p_dev)
 {
-	client_reg_t client_reg;
 	dev_link_t *link;
 	struct net_device *dev;
 	struct wl3501_card *this;
-	int ret;
 
 	/* Initialize the dev_link_t structure */
 	link = kzalloc(sizeof(*link), GFP_KERNEL);
 	if (!link)
-		goto out;
+		return -ENOMEM;
 
 	/* The io structure describes IO port mapping */
 	link->io.NumPorts1	= 16;
@@ -2003,24 +1998,17 @@
 	netif_stop_queue(dev);
 	link->priv = link->irq.Instance = dev;
 
-	/* Register with Card Services */
-	link->next		 = wl3501_dev_list;
-	wl3501_dev_list		 = link;
-	client_reg.dev_info	 = &wl3501_dev_info;
-	client_reg.Version	 = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret) {
-		cs_error(link->handle, RegisterClient, ret);
-		wl3501_detach(link);
-		link = NULL;
-	}
-out:
-	return link;
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	wl3501_config(link);
+
+	return 0;
 out_link:
 	kfree(link);
 	link = NULL;
-	goto out;
+	return -ENOMEM;
 }
 
 #define CS_CHECK(fn, ret) \
@@ -2173,67 +2161,41 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-/**
- * wl3501_event - The card status event handler
- * @event - event
- * @pri - priority
- * @args - arguments for this event
- *
- * The card status event handler. Mostly, this schedules other stuff to run
- * after an event is received. A CARD_REMOVAL event also sets some flags to
- * discourage the net drivers from trying to talk to the card any more.
- *
- * When a CARD_REMOVAL event is received, we immediately set a flag to block
- * future accesses to this device. All the functions that actually access the
- * device should check this flag to make sure the card is still present.
- */
-static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
+static int wl3501_suspend(struct pcmcia_device *p_dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct net_device *dev = link->priv;
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			while (link->open > 0)
-				wl3501_close(dev);
+	link->state |= DEV_SUSPEND;
+
+	wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
+	if (link->state & DEV_CONFIG) {
+		if (link->open)
 			netif_device_detach(dev);
-			wl3501_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		wl3501_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG) {
-			if (link->open)
-				netif_device_detach(dev);
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			if (link->open) {
-				wl3501_reset(dev);
-				netif_device_attach(dev);
-			}
-		}
-		break;
+		pcmcia_release_configuration(link->handle);
 	}
+
 	return 0;
 }
 
+static int wl3501_resume(struct pcmcia_device *p_dev)
+{
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct net_device *dev = link->priv;
+
+	wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (link->open) {
+			wl3501_reset(dev);
+			netif_device_attach(dev);
+		}
+	}
+
+	return 0;
+}
+
+
 static struct pcmcia_device_id wl3501_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),
 	PCMCIA_DEVICE_NULL
@@ -2245,10 +2207,11 @@
 	.drv		= {
 		.name	= "wl3501_cs",
 	},
-	.attach		= wl3501_attach,
-	.event		= wl3501_event,
-	.detach		= wl3501_detach,
+	.probe		= wl3501_attach,
+	.remove		= wl3501_detach,
 	.id_table	= wl3501_ids,
+	.suspend	= wl3501_suspend,
+	.resume		= wl3501_resume,
 };
 
 static int __init wl3501_init_module(void)
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 531b073..b2e8e49 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -43,13 +43,16 @@
  * list for processing. Only after two full buffer syncs
  * does the task eventually get freed, because by then
  * we are sure we will not reference it again.
+ * Can be invoked from softirq via RCU callback due to
+ * call_rcu() of the task struct, hence the _irqsave.
  */
 static int task_free_notify(struct notifier_block * self, unsigned long val, void * data)
 {
+	unsigned long flags;
 	struct task_struct * task = data;
-	spin_lock(&task_mortuary);
+	spin_lock_irqsave(&task_mortuary, flags);
 	list_add(&task->tasks, &dying_tasks);
-	spin_unlock(&task_mortuary);
+	spin_unlock_irqrestore(&task_mortuary, flags);
 	return NOTIFY_OK;
 }
 
@@ -431,25 +434,22 @@
  */
 static void process_task_mortuary(void)
 {
-	struct list_head * pos;
-	struct list_head * pos2;
+	unsigned long flags;
+	LIST_HEAD(local_dead_tasks);
 	struct task_struct * task;
+	struct task_struct * ttask;
 
-	spin_lock(&task_mortuary);
+	spin_lock_irqsave(&task_mortuary, flags);
 
-	list_for_each_safe(pos, pos2, &dead_tasks) {
-		task = list_entry(pos, struct task_struct, tasks);
+	list_splice_init(&dead_tasks, &local_dead_tasks);
+	list_splice_init(&dying_tasks, &dead_tasks);
+
+	spin_unlock_irqrestore(&task_mortuary, flags);
+
+	list_for_each_entry_safe(task, ttask, &local_dead_tasks, tasks) {
 		list_del(&task->tasks);
 		free_task(task);
 	}
-
-	list_for_each_safe(pos, pos2, &dying_tasks) {
-		task = list_entry(pos, struct task_struct, tasks);
-		list_del(&task->tasks);
-		list_add_tail(&task->tasks, &dead_tasks);
-	}
-
-	spin_unlock(&task_mortuary);
 }
 
 
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 026f671..78193e4 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -52,7 +52,8 @@
 	for_each_online_cpu(i) {
 		struct oprofile_cpu_buffer * b = &cpu_buffer[i];
  
-		b->buffer = vmalloc(sizeof(struct op_sample) * buffer_size);
+		b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size,
+			cpu_to_node(i));
 		if (!b->buffer)
 			goto fail;
  
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index 725a141..a665951 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -34,7 +34,7 @@
 
 config PARPORT_PC
 	tristate "PC-style hardware"
-	depends on PARPORT && (!SPARC64 || PCI) && !SPARC32 && !M32R
+	depends on PARPORT && (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV
 	---help---
 	  You should say Y here if you have a PC-style parallel port. All
 	  IBM PC compatible computers and some Alphas have PC-style
@@ -77,7 +77,7 @@
 
 config PARPORT_PC_PCMCIA
 	tristate "Support for PCMCIA management for PC-style ports"
-	depends on PARPORT!=n && (PCMCIA!=n && PARPORT_PC=m && PARPORT_PC || PARPORT_PC=y && PCMCIA)
+	depends on PCMCIA && PARPORT_PC
 	help
 	  Say Y here if you need PCMCIA support for your PC-style parallel
 	  ports. If unsure, say N.
diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c
index 075c7eb..9ee6732 100644
--- a/drivers/parport/daisy.c
+++ b/drivers/parport/daisy.c
@@ -144,9 +144,9 @@
 	add_dev (numdevs++, port, -1);
 
 	/* Find out the legacy device's IEEE 1284 device ID. */
-	deviceid = kmalloc (1000, GFP_KERNEL);
+	deviceid = kmalloc (1024, GFP_KERNEL);
 	if (deviceid) {
-		if (parport_device_id (numdevs - 1, deviceid, 1000) > 2)
+		if (parport_device_id (numdevs - 1, deviceid, 1024) > 2)
 			detected++;
 
 		kfree (deviceid);
@@ -252,7 +252,7 @@
 		selected = port->daisy;
 		parport_release (dev);
 
-		if (selected != port->daisy) {
+		if (selected != daisy) {
 			/* No corresponding device. */
 			parport_unregister_device (dev);
 			return NULL;
@@ -344,9 +344,9 @@
 			      PARPORT_CONTROL_STROBE,
 			      PARPORT_CONTROL_STROBE);
 	udelay (1);
+	s = parport_read_status (port);
 	parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
 	udelay (1);
-	s = parport_read_status (port);
 	parport_write_data (port, 0xff); udelay (2);
 
 	return s;
@@ -395,15 +395,15 @@
 		case IEEE1284_MODE_EPP:
 		case IEEE1284_MODE_EPPSL:
 		case IEEE1284_MODE_EPPSWE:
-			return (cpp_daisy (port, 0x20 + daisy) &
-				PARPORT_STATUS_ERROR);
+			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) &
-				PARPORT_STATUS_ERROR);
+			return !(cpp_daisy (port, 0xd0 + daisy) &
+				 PARPORT_STATUS_ERROR);
 
 		// Nothing was told for BECP in Daisy chain specification.
 		// May be it's wise to use ECP?
@@ -413,8 +413,8 @@
 		case IEEE1284_MODE_BYTE:
 		case IEEE1284_MODE_COMPAT:
 		default:
-			return (cpp_daisy (port, 0xe0 + daisy) &
-				PARPORT_STATUS_ERROR);
+			return !(cpp_daisy (port, 0xe0 + daisy) &
+				 PARPORT_STATUS_ERROR);
 	}
 }
 
@@ -436,7 +436,7 @@
 
 static int assign_addrs (struct parport *port)
 {
-	unsigned char s, last_dev;
+	unsigned char s;
 	unsigned char daisy;
 	int thisdev = numdevs;
 	int detected;
@@ -472,10 +472,13 @@
 	}
 
 	parport_write_data (port, 0x78); udelay (2);
-	last_dev = 0; /* We've just been speaking to a device, so we
-			 know there must be at least _one_ out there. */
+	s = parport_read_status (port);
 
-	for (daisy = 0; daisy < 4; daisy++) {
+	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,
@@ -485,14 +488,18 @@
 		parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
 		udelay (1);
 
-		if (last_dev)
-			/* No more devices. */
+		add_dev (numdevs++, port, daisy);
+
+		/* See if this device thought it was the last in the
+		 * chain. */
+		if (!(s & PARPORT_STATUS_BUSY))
 			break;
 
-		last_dev = !(parport_read_status (port)
-			     & PARPORT_STATUS_BUSY);
-
-		add_dev (numdevs++, port, daisy);
+		/* We are seeing pass through status now. We see
+		   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);
 	}
 
 	parport_write_data (port, 0xff); udelay (2);
@@ -501,11 +508,11 @@
 		 detected);
 
 	/* Ask the new devices to introduce themselves. */
-	deviceid = kmalloc (1000, GFP_KERNEL);
+	deviceid = kmalloc (1024, GFP_KERNEL);
 	if (!deviceid) return 0;
 
 	for (daisy = 0; thisdev < numdevs; thisdev++, daisy++)
-		parport_device_id (thisdev, deviceid, 1000);
+		parport_device_id (thisdev, deviceid, 1024);
 
 	kfree (deviceid);
 	return detected;
diff --git a/drivers/parport/ieee1284_ops.c b/drivers/parport/ieee1284_ops.c
index ce1e2aa..d6c7765 100644
--- a/drivers/parport/ieee1284_ops.c
+++ b/drivers/parport/ieee1284_ops.c
@@ -165,17 +165,7 @@
 		/* Does the error line indicate end of data? */
 		if (((i & 1) == 0) &&
 		    (parport_read_status(port) & PARPORT_STATUS_ERROR)) {
-			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
-			DPRINTK (KERN_DEBUG
-				"%s: No more nibble data (%d bytes)\n",
-				port->name, i/2);
-
-			/* Go to reverse idle phase. */
-			parport_frob_control (port,
-					      PARPORT_CONTROL_AUTOFD,
-					      PARPORT_CONTROL_AUTOFD);
-			port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
-			break;
+			goto end_of_data;
 		}
 
 		/* Event 7: Set nAutoFd low. */
@@ -225,18 +215,25 @@
 			byte = nibble;
 	}
 
-	i /= 2; /* i is now in bytes */
-
 	if (i == len) {
 		/* Read the last nibble without checking data avail. */
-		port = port->physport;
-		if (parport_read_status (port) & PARPORT_STATUS_ERROR)
-			port->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
+		if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
+		end_of_data:
+			DPRINTK (KERN_DEBUG
+				"%s: No more nibble data (%d bytes)\n",
+				port->name, i/2);
+
+			/* Go to reverse idle phase. */
+			parport_frob_control (port,
+					      PARPORT_CONTROL_AUTOFD,
+					      PARPORT_CONTROL_AUTOFD);
+			port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
+		}
 		else
-			port->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
+			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
 	}
 
-	return i;
+	return i/2;
 #endif /* IEEE1284 support */
 }
 
@@ -256,17 +253,7 @@
 
 		/* Data available? */
 		if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
-			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
-			DPRINTK (KERN_DEBUG
-				 "%s: No more byte data (%Zd bytes)\n",
-				 port->name, count);
-
-			/* Go to reverse idle phase. */
-			parport_frob_control (port,
-					      PARPORT_CONTROL_AUTOFD,
-					      PARPORT_CONTROL_AUTOFD);
-			port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
-			break;
+			goto end_of_data;
 		}
 
 		/* Event 14: Place data bus in high impedance state. */
@@ -318,11 +305,20 @@
 
 	if (count == len) {
 		/* Read the last byte without checking data avail. */
-		port = port->physport;
-		if (parport_read_status (port) & PARPORT_STATUS_ERROR)
-			port->ieee1284.phase = IEEE1284_PH_HBUSY_DNA;
+		if (parport_read_status (port) & PARPORT_STATUS_ERROR) {
+		end_of_data:
+			DPRINTK (KERN_DEBUG
+				 "%s: No more byte data (%Zd bytes)\n",
+				 port->name, count);
+
+			/* Go to reverse idle phase. */
+			parport_frob_control (port,
+					      PARPORT_CONTROL_AUTOFD,
+					      PARPORT_CONTROL_AUTOFD);
+			port->physport->ieee1284.phase = IEEE1284_PH_REV_IDLE;
+		}
 		else
-			port->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
+			port->physport->ieee1284.phase = IEEE1284_PH_HBUSY_DAVAIL;
 	}
 
 	return count;
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 24e6aac..158d925 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -87,15 +87,9 @@
     struct parport	*port;
 } parport_info_t;
 
-static dev_link_t *parport_attach(void);
-static void parport_detach(dev_link_t *);
+static void parport_detach(struct pcmcia_device *p_dev);
 static void parport_config(dev_link_t *link);
 static void parport_cs_release(dev_link_t *);
-static int parport_event(event_t event, int priority,
-			 event_callback_args_t *args);
-
-static dev_info_t dev_info = "parport_cs";
-static dev_link_t *dev_list = NULL;
 
 /*======================================================================
 
@@ -105,18 +99,16 @@
 
 ======================================================================*/
 
-static dev_link_t *parport_attach(void)
+static int parport_attach(struct pcmcia_device *p_dev)
 {
     parport_info_t *info;
     dev_link_t *link;
-    client_reg_t client_reg;
-    int ret;
-    
+
     DEBUG(0, "parport_attach()\n");
 
     /* Create new parport device */
     info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
+    if (!info) return -ENOMEM;
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
 
@@ -127,21 +119,14 @@
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.Vcc = 50;
     link->conf.IntType = INT_MEMORY_AND_IO;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != CS_SUCCESS) {
-	cs_error(link->handle, RegisterClient, ret);
-	parport_detach(link);
-	return NULL;
-    }
-    
-    return link;
+
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    parport_config(link);
+
+    return 0;
 } /* parport_attach */
 
 /*======================================================================
@@ -153,32 +138,16 @@
 
 ======================================================================*/
 
-static void parport_detach(dev_link_t *link)
+static void parport_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
-    int ret;
+    dev_link_t *link = dev_to_instance(p_dev);
 
     DEBUG(0, "parport_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
 
     if (link->state & DEV_CONFIG)
 	parport_cs_release(link);
-    
-    if (link->handle) {
-	ret = pcmcia_deregister_client(link->handle);
-	if (ret != CS_SUCCESS)
-	    cs_error(link->handle, DeregisterClient, ret);
-    }
-    
-    /* Unlink, free device structure */
-    *linkp = link->next;
+
     kfree(link->priv);
-    
 } /* parport_detach */
 
 /*======================================================================
@@ -325,47 +294,27 @@
 
 } /* parport_cs_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.
-    
-======================================================================*/
-
-int parport_event(event_t event, int priority,
-		  event_callback_args_t *args)
+static int parport_suspend(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 
-    DEBUG(1, "parport_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-		parport_cs_release(link);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	parport_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int parport_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (DEV_OK(link))
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	break;
-    }
-    return 0;
-} /* parport_event */
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
 
 static struct pcmcia_device_id parport_ids[] = {
 	PCMCIA_DEVICE_FUNC_ID(3),
@@ -379,11 +328,11 @@
 	.drv		= {
 		.name	= "parport_cs",
 	},
-	.attach		= parport_attach,
-	.event		= parport_event,
-	.detach		= parport_detach,
+	.probe		= parport_attach,
+	.remove		= parport_detach,
 	.id_table	= parport_ids,
-
+	.suspend	= parport_suspend,
+	.resume		= parport_resume,
 };
 
 static int __init init_parport_cs(void)
@@ -394,7 +343,6 @@
 static void __exit exit_parport_cs(void)
 {
 	pcmcia_unregister_driver(&parport_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_parport_cs);
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index c6493ad..9302b8f 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -1169,7 +1169,7 @@
 
 /* GCC is not inlining extern inline function later overwriten to non-inline,
    so we use outlined_ variants here.  */
-static struct parport_operations parport_pc_ops =
+static const struct parport_operations parport_pc_ops =
 {
 	.write_data	= parport_pc_write_data,
 	.read_data	= parport_pc_read_data,
@@ -1211,10 +1211,11 @@
 static void __devinit show_parconfig_smsc37c669(int io, int key)
 {
 	int cr1,cr4,cra,cr23,cr26,cr27,i=0;
-	static const char *modes[]={ "SPP and Bidirectional (PS/2)",	
-				     "EPP and SPP",
-				     "ECP",
-				     "ECP and EPP" };
+	static const char *const modes[]={
+		"SPP and Bidirectional (PS/2)",
+		"EPP and SPP",
+		"ECP",
+		"ECP and EPP" };
 
 	outb(key,io);
 	outb(key,io);
@@ -1288,7 +1289,7 @@
 static void __devinit show_parconfig_winbond(int io, int key)
 {
 	int cr30,cr60,cr61,cr70,cr74,crf0,i=0;
-	static const char *modes[] = {
+	static const char *const modes[] = {
 		"Standard (SPP) and Bidirectional(PS/2)", /* 0 */
 		"EPP-1.9 and SPP",
 		"ECP",
@@ -1297,7 +1298,9 @@
 		"EPP-1.7 and SPP",		/* 5 */
 		"undefined!",
 		"ECP and EPP-1.7" };
-	static char *irqtypes[] = { "pulsed low, high-Z", "follows nACK" };
+	static char *const irqtypes[] = {
+		"pulsed low, high-Z",
+		"follows nACK" };
 		
 	/* The registers are called compatible-PnP because the
            register layout is modelled after ISA-PnP, the access
@@ -2368,8 +2371,10 @@
 	spin_lock(&ports_lock);
 	list_del_init(&priv->list);
 	spin_unlock(&ports_lock);
+#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
 	if (p->dma != PARPORT_DMA_NONE)
 		free_dma(p->dma);
+#endif
 	if (p->irq != PARPORT_IRQ_NONE)
 		free_irq(p->irq, p);
 	release_region(p->base, 3);
@@ -2377,14 +2382,12 @@
 		release_region(p->base + 3, p->size - 3);
 	if (p->modes & PARPORT_MODE_ECP)
 		release_region(p->base_hi, 3);
-#ifdef CONFIG_PARPORT_PC_FIFO
-#ifdef HAS_DMA
+#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
 	if (priv->dma_buf)
 		pci_free_consistent(priv->dev, PAGE_SIZE,
 				    priv->dma_buf,
 				    priv->dma_handle);
 #endif
-#endif
 	kfree (p->private_data);
 	parport_put_port(p);
 	kfree (ops); /* hope no-one cached it */
@@ -2396,7 +2399,8 @@
 
 /* ITE support maintained by Rich Liu <richliu@poorman.org> */
 static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
-					 int autodma, struct parport_pc_via_data *via)
+					 int autodma,
+					 const struct parport_pc_via_data *via)
 {
 	short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 };
 	struct resource *base_res;
@@ -2524,7 +2528,8 @@
 };
 
 static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq,
-					 int autodma, struct parport_pc_via_data *via)
+				    int autodma,
+				    const struct parport_pc_via_data *via)
 {
 	u8 tmp, tmp2, siofunc;
 	u8 ppcontrol = 0;
@@ -2694,8 +2699,9 @@
 
 /* each element directly indexed from enum list, above */
 static struct parport_pc_superio {
-	int (*probe) (struct pci_dev *pdev, int autoirq, int autodma, struct parport_pc_via_data *via);
-	struct parport_pc_via_data *via;
+	int (*probe) (struct pci_dev *pdev, int autoirq, int autodma,
+		      const struct parport_pc_via_data *via);
+	const struct parport_pc_via_data *via;
 } parport_pc_superio_info[] __devinitdata = {
 	{ sio_via_probe, &via_686a_data, },
 	{ sio_via_probe, &via_8231_data, },
@@ -2828,7 +2834,7 @@
 	/* netmos_9815 */               { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */
 };
 
-static struct pci_device_id parport_pc_pci_tbl[] = {
+static const struct pci_device_id parport_pc_pci_tbl[] = {
 	/* Super-IO onboard chips */
 	{ 0x1106, 0x0686, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_via_686a },
 	{ 0x1106, 0x8231, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_via_8231 },
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
index 4b48b31..b62aee8 100644
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -11,9 +11,9 @@
 #include <linux/string.h>
 #include <asm/uaccess.h>
 
-static struct {
-	char *token;
-	char *descr;
+static const struct {
+	const char *token;
+	const char *descr;
 } classes[] = {
 	{ "",            "Legacy device" },
 	{ "PRINTER",     "Printer" },
@@ -128,8 +128,131 @@
 	kfree(txt);
 }
 
+/* Read up to count-1 bytes of device id. Terminate buffer with
+ * '\0'. Buffer begins with two Device ID length bytes as given by
+ * device. */
+static ssize_t parport_read_device_id (struct parport *port, char *buffer,
+				       size_t count)
+{
+	unsigned char length[2];
+	unsigned lelen, belen;
+	size_t idlens[4];
+	unsigned numidlens;
+	unsigned current_idlen;
+	ssize_t retval;
+	size_t len;
+
+	/* First two bytes are MSB,LSB of inclusive length. */
+	retval = parport_read (port, length, 2);
+
+	if (retval < 0)
+		return retval;
+	if (retval != 2)
+		return -EIO;
+
+	if (count < 2)
+		return 0;
+	memcpy(buffer, length, 2);
+	len = 2;
+
+	/* Some devices wrongly send LE length, and some send it two
+	 * bytes short. Construct a sorted array of lengths to try. */
+	belen = (length[0] << 8) + length[1];
+	lelen = (length[1] << 8) + length[0];
+	idlens[0] = min(belen, lelen);
+	idlens[1] = idlens[0]+2;
+	if (belen != lelen) {
+		int off = 2;
+		/* Don't try lenghts of 0x100 and 0x200 as 1 and 2 */
+		if (idlens[0] <= 2)
+			off = 0;
+		idlens[off] = max(belen, lelen);
+		idlens[off+1] = idlens[off]+2;
+		numidlens = off+2;
+	}
+	else {
+		/* Some devices don't truly implement Device ID, but
+		 * just return constant nibble forever. This catches
+		 * also those cases. */
+		if (idlens[0] == 0 || idlens[0] > 0xFFF) {
+			printk (KERN_DEBUG "%s: reported broken Device ID"
+				" length of %#zX bytes\n",
+				port->name, idlens[0]);
+			return -EIO;
+		}
+		numidlens = 2;
+	}
+
+	/* Try to respect the given ID length despite all the bugs in
+	 * the ID length. Read according to shortest possible ID
+	 * first. */
+	for (current_idlen = 0; current_idlen < numidlens; ++current_idlen) {
+		size_t idlen = idlens[current_idlen];
+		if (idlen+1 >= count)
+			break;
+
+		retval = parport_read (port, buffer+len, idlen-len);
+
+		if (retval < 0)
+			return retval;
+		len += retval;
+
+		if (port->physport->ieee1284.phase != IEEE1284_PH_HBUSY_DAVAIL) {
+			if (belen != len) {
+				printk (KERN_DEBUG "%s: Device ID was %d bytes"
+					" while device told it would be %d"
+					" bytes\n",
+					port->name, len, belen);
+			}
+			goto done;
+		}
+
+		/* This might end reading the Device ID too
+		 * soon. Hopefully the needed fields were already in
+		 * the first 256 bytes or so that we must have read so
+		 * far. */
+		if (buffer[len-1] == ';') {
+ 			printk (KERN_DEBUG "%s: Device ID reading stopped"
+				" before device told data not available. "
+				"Current idlen %d of %d, len bytes %02X %02X\n",
+				port->name, current_idlen, numidlens,
+				length[0], length[1]);
+			goto done;
+		}
+	}
+	if (current_idlen < numidlens) {
+		/* Buffer not large enough, read to end of buffer. */
+		size_t idlen, len2;
+		if (len+1 < count) {
+			retval = parport_read (port, buffer+len, count-len-1);
+			if (retval < 0)
+				return retval;
+			len += retval;
+		}
+		/* Read the whole ID since some devices would not
+		 * otherwise give back the Device ID from beginning
+		 * next time when asked. */
+		idlen = idlens[current_idlen];
+		len2 = len;
+		while(len2 < idlen && retval > 0) {
+			char tmp[4];
+			retval = parport_read (port, tmp,
+					       min(sizeof tmp, idlen-len2));
+			if (retval < 0)
+				return retval;
+			len2 += retval;
+		}
+	}
+	/* In addition, there are broken devices out there that don't
+	   even finish off with a semi-colon. We do not need to care
+	   about those at this time. */
+ done:
+	buffer[len] = '\0';
+	return len;
+}
+
 /* Get Std 1284 Device ID. */
-ssize_t parport_device_id (int devnum, char *buffer, size_t len)
+ssize_t parport_device_id (int devnum, char *buffer, size_t count)
 {
 	ssize_t retval = -ENXIO;
 	struct pardevice *dev = parport_open (devnum, "Device ID probe",
@@ -139,76 +262,20 @@
 
 	parport_claim_or_block (dev);
 
-	/* Negotiate to compatibility mode, and then to device ID mode.
-	 * (This is in case we are already in device ID mode.) */
+	/* Negotiate to compatibility mode, and then to device ID
+	 * mode. (This so that we start form beginning of device ID if
+	 * already in device ID mode.) */
 	parport_negotiate (dev->port, IEEE1284_MODE_COMPAT);
 	retval = parport_negotiate (dev->port,
 				    IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID);
 
 	if (!retval) {
-		int idlen;
-		unsigned char length[2];
-
-		/* First two bytes are MSB,LSB of inclusive length. */
-		retval = parport_read (dev->port, length, 2);
-
-		if (retval != 2) goto end_id;
-
-		idlen = (length[0] << 8) + length[1] - 2;
-		/*
-		 * Check if the caller-allocated buffer is large enough
-		 * otherwise bail out or there will be an at least off by one.
-		 */
-		if (idlen + 1 < len)
-			len = idlen;
-		else {
-			retval = -EINVAL;
-			goto out;
-		}
-		retval = parport_read (dev->port, buffer, len);
-
-		if (retval != len)
-			printk (KERN_DEBUG "%s: only read %Zd of %Zd ID bytes\n",
-				dev->port->name, retval,
-				len);
-
-		/* Some printer manufacturers mistakenly believe that
-                   the length field is supposed to be _exclusive_.
-		   In addition, there are broken devices out there
-                   that don't even finish off with a semi-colon. */
-		if (buffer[len - 1] != ';') {
-			ssize_t diff;
-			diff = parport_read (dev->port, buffer + len, 2);
-			retval += diff;
-
-			if (diff)
-				printk (KERN_DEBUG
-					"%s: device reported incorrect "
-					"length field (%d, should be %Zd)\n",
-					dev->port->name, idlen, retval);
-			else {
-				/* One semi-colon short of a device ID. */
-				buffer[len++] = ';';
-				printk (KERN_DEBUG "%s: faking semi-colon\n",
-					dev->port->name);
-
-				/* If we get here, I don't think we
-                                   need to worry about the possible
-                                   standard violation of having read
-                                   more than we were told to.  The
-                                   device is non-compliant anyhow. */
-			}
-		}
-
-	end_id:
-		buffer[len] = '\0';
+		retval = parport_read_device_id (dev->port, buffer, count);
 		parport_negotiate (dev->port, IEEE1284_MODE_COMPAT);
+		if (retval > 2)
+			parse_data (dev->port, dev->daisy, buffer+2);
 	}
 
-	if (retval > 2)
-		parse_data (dev->port, dev->daisy, buffer);
-
-out:
 	parport_release (dev);
 	parport_close (dev);
 	return retval;
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index 9cb3ab1..ea62bed 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -1002,6 +1002,7 @@
 EXPORT_SYMBOL(parport_unregister_driver);
 EXPORT_SYMBOL(parport_register_device);
 EXPORT_SYMBOL(parport_unregister_device);
+EXPORT_SYMBOL(parport_get_port);
 EXPORT_SYMBOL(parport_put_port);
 EXPORT_SYMBOL(parport_find_number);
 EXPORT_SYMBOL(parport_find_base);
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 716df015..6707df9 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -6,6 +6,9 @@
 			pci-driver.o search.o pci-sysfs.o rom.o setup-res.o
 obj-$(CONFIG_PROC_FS) += proc.o
 
+# Build PCI Express stuff if needed
+obj-$(CONFIG_PCIEPORTBUS) += pcie/
+
 obj-$(CONFIG_HOTPLUG) += hotplug.o
 
 # Build the PCI Hotplug drivers if we were asked to
@@ -40,7 +43,3 @@
 ifeq ($(CONFIG_PCI_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
 endif
-
-# Build PCI Express stuff if needed
-obj-$(CONFIG_PCIEPORTBUS) += pcie/
-
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index e1743be..1c97e7d 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -3,8 +3,8 @@
 #include <linux/module.h>
 #include "pci.h"
 
-int pci_hotplug (struct device *dev, char **envp, int num_envp,
-		 char *buffer, int buffer_size)
+int pci_uevent(struct device *dev, char **envp, int num_envp,
+	       char *buffer, int buffer_size)
 {
 	struct pci_dev *pdev;
 	int i = 0;
@@ -17,34 +17,34 @@
 	if (!pdev)
 		return -ENODEV;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"PCI_CLASS=%04X", pdev->class))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "PCI_CLASS=%04X", pdev->class))
 		return -ENOMEM;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
 		return -ENOMEM;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
-				pdev->subsystem_device))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
+			   pdev->subsystem_device))
 		return -ENOMEM;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"PCI_SLOT_NAME=%s", pci_name(pdev)))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "PCI_SLOT_NAME=%s", pci_name(pdev)))
 		return -ENOMEM;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
-				pdev->vendor, pdev->device,
-				pdev->subsystem_vendor, pdev->subsystem_device,
-				(u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
-				(u8)(pdev->class)))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
+			   pdev->vendor, pdev->device,
+			   pdev->subsystem_vendor, pdev->subsystem_device,
+			   (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
+			   (u8)(pdev->class)))
 		return -ENOMEM;
 
 	envp[i] = NULL;
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 6a61b9f..0aac6a6 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -32,6 +32,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/sched.h>		/* signal_pending() */
 #include <linux/pcieport_if.h>
 #include "pci_hotplug.h"
 
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 0b8b26b..ac1e495 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -30,6 +30,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/signal.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
 
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index a9046d4..7146b69 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -502,8 +502,8 @@
 }
 
 #ifndef CONFIG_HOTPLUG
-int pci_hotplug (struct device *dev, char **envp, int num_envp,
-		 char *buffer, int buffer_size)
+int pci_uevent(struct device *dev, char **envp, int num_envp,
+	       char *buffer, int buffer_size)
 {
 	return -ENODEV;
 }
@@ -512,7 +512,7 @@
 struct bus_type pci_bus_type = {
 	.name		= "pci",
 	.match		= pci_bus_match,
-	.hotplug	= pci_hotplug,
+	.uevent		= pci_uevent,
 	.suspend	= pci_device_suspend,
 	.resume		= pci_device_resume,
 	.dev_attrs	= pci_dev_attrs,
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 6527b36..294849d 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1,7 +1,7 @@
 /* Functions internal to the PCI core code */
 
-extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
-			 char *buffer, int buffer_size);
+extern int pci_uevent(struct device *dev, char **envp, int num_envp,
+		      char *buffer, int buffer_size);
 extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
 extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
 extern void pci_cleanup_rom(struct pci_dev *dev);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 3a4f49f..f28ebdd 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1098,6 +1098,23 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_EESSC,	quirk_alder_ioapic );
 #endif
 
+enum ide_combined_type { COMBINED = 0, IDE = 1, LIBATA = 2 };
+/* Defaults to combined */
+static enum ide_combined_type combined_mode;
+
+static int __init combined_setup(char *str)
+{
+	if (!strncmp(str, "ide", 3))
+		combined_mode = IDE;
+	else if (!strncmp(str, "libata", 6))
+		combined_mode = LIBATA;
+	else /* "combined" or anything else defaults to old behavior */
+		combined_mode = COMBINED;
+
+	return 1;
+}
+__setup("combined_mode=", combined_setup);
+
 #ifdef CONFIG_SCSI_SATA_INTEL_COMBINED
 static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
 {
@@ -1164,6 +1181,19 @@
 	if (prog & comb)
 		return;
 
+	/* Don't reserve any so the IDE driver can get them (but only if
+	 * combined_mode=ide).
+	 */
+	if (combined_mode == IDE)
+		return;
+
+	/* Grab them both for libata if combined_mode=libata. */
+	if (combined_mode == LIBATA) {
+		request_region(0x1f0, 8, "libata");	/* port 0 */
+		request_region(0x170, 8, "libata");	/* port 1 */
+		return;
+	}
+
 	/* SATA port is in legacy mode.  Reserve port so that
 	 * IDE driver does not attempt to use it.  If request_region
 	 * fails, it will be obvious at boot time, so we don't bother
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 309eb55..1f4ad0e 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -116,6 +116,31 @@
 
 	  If unsure, say Y.
 
+config YENTA_O2
+	default y
+	bool "Special initialization for O2Micro bridges" if EMBEDDED
+	depends on YENTA
+
+config YENTA_RICOH
+	default y
+	bool "Special initialization for Ricoh bridges" if EMBEDDED
+	depends on YENTA
+
+config YENTA_TI
+	default y
+	bool "Special initialization for TI and EnE bridges" if EMBEDDED
+	depends on YENTA
+
+config YENTA_ENE_TUNE
+	default y
+	bool "Auto-tune EnE bridges for CB cards" if EMBEDDED
+	depends on YENTA_TI && CARDBUS
+
+config YENTA_TOSHIBA
+	default y
+	bool "Special initialization for Toshiba ToPIC bridges" if EMBEDDED
+	depends on YENTA
+
 config PD6729
 	tristate "Cirrus PD6729 compatible bridge support"
 	depends on PCMCIA && PCI
@@ -157,7 +182,7 @@
 config PCMCIA_M8XX
         tristate "MPC8xx PCMCIA support"
         depends on PCMCIA && PPC && 8xx 
-        select PCCARD_NONSTATIC
+        select PCCARD_IODYN
         help
         Say Y here to include support for PowerPC 8xx series PCMCIA
         controller.
@@ -200,7 +225,7 @@
 
 config PCMCIA_PROBE
 	bool
-	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X
+	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
 
 config M32R_PCC
 	bool "M32R PCMCIA I/F"
@@ -241,6 +266,9 @@
 config PCCARD_NONSTATIC
 	tristate
 
+config PCCARD_IODYN
+	bool
+
 endif	# PCCARD
 
 endmenu
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 87302c5..971a352 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -241,23 +241,6 @@
 	return 0;
 }
 
-/* au1x00_pcmcia_get_socket()
- * Implements the get_socket() operation for the in-kernel PCMCIA
- * service (formerly SS_GetSocket in Card Services). Not a very
- * exciting routine.
- *
- * Returns: 0
- */
-static int
-au1x00_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-  struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
-
-  debug("for sock %u\n", skt->nr);
-  *state = skt->cs_state;
-  return 0;
-}
-
 /* au1x00_pcmcia_set_socket()
  * Implements the set_socket() operation for the in-kernel PCMCIA
  * service (formerly SS_SetSocket in Card Services). We more or
@@ -352,7 +335,6 @@
 	.init			= au1x00_pcmcia_sock_init,
 	.suspend		= au1x00_pcmcia_suspend,
 	.get_status		= au1x00_pcmcia_get_status,
-	.get_socket		= au1x00_pcmcia_get_socket,
 	.set_socket		= au1x00_pcmcia_set_socket,
 	.set_io_map		= au1x00_pcmcia_set_io_map,
 	.set_mem_map		= au1x00_pcmcia_set_mem_map,
@@ -372,13 +354,12 @@
 	struct skt_dev_info *sinfo;
 	int ret, i;
 
-	sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
+	sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
 	if (!sinfo) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	memset(sinfo, 0, sizeof(struct skt_dev_info));
 	sinfo->nskt = nr;
 
 	/*
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 2dc3e61..120fa8d 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -60,9 +60,9 @@
 
 /* Parameters that can be set with 'insmod' */
 
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
-
-INT_MODULE_PARM(cis_width,	0);		/* 16-bit CIS? */
+/* 16-bit CIS? */
+static int cis_width;
+module_param(cis_width, int, 0444);
 
 void release_cis_mem(struct pcmcia_socket *s)
 {
@@ -463,7 +463,7 @@
 	/* Get indirect link from the MFC tuple */
 	read_cis_cache(s, LINK_SPACE(tuple->Flags),
 		       tuple->LinkOffset, 5, link);
-	ofs = le32_to_cpu(*(u_int *)(link+1));
+	ofs = le32_to_cpu(*(__le32 *)(link+1));
 	SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
 	/* Move to the next indirect link */
 	tuple->LinkOffset += 5;
@@ -671,8 +671,8 @@
     if (tuple->TupleDataLen < 5)
 	return CS_BAD_TUPLE;
     p = (u_char *)tuple->TupleData;
-    csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(u_short *)p)-2;
-    csum->len = le16_to_cpu(*(u_short *)(p + 2));
+    csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2;
+    csum->len = le16_to_cpu(*(__le16 *)(p + 2));
     csum->sum = *(p+4);
     return CS_SUCCESS;
 }
@@ -683,7 +683,7 @@
 {
     if (tuple->TupleDataLen < 4)
 	return CS_BAD_TUPLE;
-    link->addr = le32_to_cpu(*(u_int *)tuple->TupleData);
+    link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData);
     return CS_SUCCESS;
 }
 
@@ -702,7 +702,7 @@
 	return CS_BAD_TUPLE;
     for (i = 0; i < link->nfn; i++) {
 	link->fn[i].space = *p; p++;
-	link->fn[i].addr = le32_to_cpu(*(u_int *)p); p += 4;
+	link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4;
     }
     return CS_SUCCESS;
 }
@@ -789,10 +789,10 @@
 
 static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
 {
-    u_short *p;
+    __le16 *p;
     if (tuple->TupleDataLen < 4)
 	return CS_BAD_TUPLE;
-    p = (u_short *)tuple->TupleData;
+    p = (__le16 *)tuple->TupleData;
     m->manf = le16_to_cpu(p[0]);
     m->card = le16_to_cpu(p[1]);
     return CS_SUCCESS;
@@ -1093,7 +1093,7 @@
 	break;
     case 0x20:
 	entry->mem.nwin = 1;
-	entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8;
+	entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
 	entry->mem.win[0].card_addr = 0;
 	entry->mem.win[0].host_addr = 0;
 	p += 2;
@@ -1101,9 +1101,9 @@
 	break;
     case 0x40:
 	entry->mem.nwin = 1;
-	entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8;
+	entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
 	entry->mem.win[0].card_addr =
-	    le16_to_cpu(*(u_short *)(p+2)) << 8;
+	    le16_to_cpu(*(__le16 *)(p+2)) << 8;
 	entry->mem.win[0].host_addr = 0;
 	p += 4;
 	if (p > q) return CS_BAD_TUPLE;
@@ -1140,7 +1140,7 @@
     p = (u_char *)tuple->TupleData;
     bar->attr = *p;
     p += 2;
-    bar->size = le32_to_cpu(*(u_int *)p);
+    bar->size = le32_to_cpu(*(__le32 *)p);
     return CS_SUCCESS;
 }
 
@@ -1153,7 +1153,7 @@
 	return CS_BAD_TUPLE;
     config->last_idx = *(++p);
     p++;
-    config->base = le32_to_cpu(*(u_int *)p);
+    config->base = le32_to_cpu(*(__le32 *)p);
     config->subtuples = tuple->TupleDataLen - 6;
     return CS_SUCCESS;
 }
@@ -1269,7 +1269,7 @@
 
     v2->vers = p[0];
     v2->comply = p[1];
-    v2->dindex = le16_to_cpu(*(u_short *)(p+2));
+    v2->dindex = le16_to_cpu(*(__le16 *)(p+2));
     v2->vspec8 = p[6];
     v2->vspec9 = p[7];
     v2->nhdr = p[8];
@@ -1310,8 +1310,8 @@
 
     fmt->type = p[0];
     fmt->edc = p[1];
-    fmt->offset = le32_to_cpu(*(u_int *)(p+2));
-    fmt->length = le32_to_cpu(*(u_int *)(p+6));
+    fmt->offset = le32_to_cpu(*(__le32 *)(p+2));
+    fmt->length = le32_to_cpu(*(__le32 *)(p+6));
 
     return CS_SUCCESS;
 }
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index a30aa74..613f2f1 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -309,41 +309,6 @@
 }
 EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
 
-
-/**
- * socket_setup() and shutdown_socket() are called by the main event
- * handler when card insertion and removal events are received.
- * socket_setup() turns on socket power and resets the socket, in two stages.
- * shutdown_socket() unconfigures a socket and turns off socket power.
- */
-static void shutdown_socket(struct pcmcia_socket *s)
-{
-	cs_dbg(s, 1, "shutdown_socket\n");
-
-	/* Blank out the socket state */
-	s->socket = dead_socket;
-	s->ops->init(s);
-	s->ops->set_socket(s, &s->socket);
-	s->irq.AssignedIRQ = s->irq.Config = 0;
-	s->lock_count = 0;
-	destroy_cis_cache(s);
-#ifdef CONFIG_CARDBUS
-	cb_free(s);
-#endif
-	s->functions = 0;
-	kfree(s->config);
-	s->config = NULL;
-
-	{
-		int status;
-		s->ops->get_status(s, &status);
-		if (status & SS_POWERON) {
-			printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
-		}
-	}
-} /* shutdown_socket */
-
-
 /**
  * The central event handler.  Send_event() sends an event to the
  * 16-bit subsystem, which then calls the relevant device drivers.
@@ -383,17 +348,6 @@
 	send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
 }
 
-static void socket_shutdown(struct pcmcia_socket *skt)
-{
-	cs_dbg(skt, 4, "shutdown\n");
-
-	socket_remove_drivers(skt);
-	skt->state &= SOCKET_INUSE|SOCKET_PRESENT;
-	msleep(shutdown_delay * 10);
-	skt->state &= SOCKET_INUSE;
-	shutdown_socket(skt);
-}
-
 static int socket_reset(struct pcmcia_socket *skt)
 {
 	int status, i;
@@ -424,6 +378,45 @@
 	return CS_GENERAL_FAILURE;
 }
 
+/**
+ * socket_setup() and socket_shutdown() are called by the main event handler
+ * when card insertion and removal events are received.
+ * socket_setup() turns on socket power and resets the socket, in two stages.
+ * socket_shutdown() unconfigures a socket and turns off socket power.
+ */
+static void socket_shutdown(struct pcmcia_socket *s)
+{
+	int status;
+
+	cs_dbg(s, 4, "shutdown\n");
+
+	socket_remove_drivers(s);
+	s->state &= SOCKET_INUSE | SOCKET_PRESENT;
+	msleep(shutdown_delay * 10);
+	s->state &= SOCKET_INUSE;
+
+	/* Blank out the socket state */
+	s->socket = dead_socket;
+	s->ops->init(s);
+	s->ops->set_socket(s, &s->socket);
+	s->irq.AssignedIRQ = s->irq.Config = 0;
+	s->lock_count = 0;
+	destroy_cis_cache(s);
+#ifdef CONFIG_CARDBUS
+	cb_free(s);
+#endif
+	s->functions = 0;
+	kfree(s->config);
+	s->config = NULL;
+
+	s->ops->get_status(s, &status);
+	if (status & SS_POWERON) {
+		printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
+	}
+
+	cs_socket_put(s);
+}
+
 static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
 {
 	int status, i;
@@ -529,7 +522,6 @@
 		send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
 	} else {
 		socket_shutdown(skt);
-		cs_socket_put(skt);
 	}
 
 	return ret;
@@ -593,7 +585,6 @@
 		}
 	} else {
 		socket_shutdown(skt);
-		cs_socket_put(skt);
 	}
 
 	skt->state &= ~SOCKET_SUSPEND;
@@ -605,7 +596,6 @@
 {
 	printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
 	socket_shutdown(skt);
-	cs_socket_put(skt);
 }
 
 /*
@@ -780,8 +770,13 @@
 		ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
 		if (ret == 0) {
 			send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
-			if (socket_reset(skt) == CS_SUCCESS)
+			if (skt->callback)
+				skt->callback->suspend(skt);
+			if (socket_reset(skt) == CS_SUCCESS) {
 				send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
+				if (skt->callback)
+					skt->callback->resume(skt);
+			}
 		}
 
 		ret = CS_SUCCESS;
@@ -812,6 +807,11 @@
 			ret = CS_UNSUPPORTED_FUNCTION;
 			break;
 		}
+		if (skt->callback) {
+			ret = skt->callback->suspend(skt);
+			if (ret)
+				break;
+		}
 		ret = socket_suspend(skt);
 	} while (0);
 	up(&skt->skt_sem);
@@ -838,6 +838,8 @@
 			break;
 		}
 		ret = socket_resume(skt);
+		if (!ret && skt->callback)
+			skt->callback->resume(skt);
 	} while (0);
 	up(&skt->skt_sem);
 
@@ -901,14 +903,14 @@
 EXPORT_SYMBOL(pcmcia_insert_card);
 
 
-static int pcmcia_socket_hotplug(struct class_device *dev, char **envp,
-				int num_envp, char *buffer, int buffer_size)
+static int pcmcia_socket_uevent(struct class_device *dev, char **envp,
+			        int num_envp, char *buffer, int buffer_size)
 {
 	struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
 	int i = 0, length = 0;
 
-	if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
-				&length, "SOCKET_NO=%u", s->sock))
+	if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+			   &length, "SOCKET_NO=%u", s->sock))
 		return -ENOMEM;
 
 	envp[i] = NULL;
@@ -927,7 +929,7 @@
 
 struct class pcmcia_socket_class = {
 	.name = "pcmcia_socket",
-        .hotplug = pcmcia_socket_hotplug,
+	.uevent = pcmcia_socket_uevent,
 	.release = pcmcia_release_socket,
 	.class_release = pcmcia_release_socket_class,
 };
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 55867bc..7b37eba 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -117,7 +117,7 @@
 int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);
 
 /* In rsrc_mgr */
-void pcmcia_validate_mem(struct pcmcia_socket *s);
+int pcmcia_validate_mem(struct pcmcia_socket *s);
 struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,
 		   struct pcmcia_socket *s);
 int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start,
@@ -143,6 +143,8 @@
 	struct module	*owner;
 	int		(*event) (struct pcmcia_socket *s, event_t event, int priority);
 	void		(*requery) (struct pcmcia_socket *s);
+	int		(*suspend) (struct pcmcia_socket *s);
+	int		(*resume) (struct pcmcia_socket *s);
 };
 
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 7f8219f..0252582 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -57,8 +57,6 @@
 
 spinlock_t pcmcia_dev_list_lock;
 
-static int unbind_request(struct pcmcia_socket *s);
-
 /*====================================================================*/
 
 /* code which was in cs.c before */
@@ -205,7 +203,7 @@
 	unsigned int i;
 	u32 hash;
 
-	if (!p_drv->attach || !p_drv->event || !p_drv->detach)
+	if (!p_drv->probe || !p_drv->remove)
 		printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback "
 		       "function\n", p_drv->drv.name);
 
@@ -266,12 +264,10 @@
 		if (fw->size >= CISTPL_MAX_CIS_SIZE)
 			goto release;
 
-		cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL);
+		cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
 		if (!cis)
 			goto release;
 
-		memset(cis, 0, sizeof(cisdump_t));
-
 		cis->Length = fw->size + 1;
 		memcpy(cis->Data, fw->data, fw->size);
 
@@ -363,6 +359,7 @@
 {
 	struct pcmcia_device *p_dev;
 	struct pcmcia_driver *p_drv;
+	struct pcmcia_socket *s;
 	int ret = 0;
 
 	dev = get_device(dev);
@@ -371,25 +368,38 @@
 
 	p_dev = to_pcmcia_dev(dev);
 	p_drv = to_pcmcia_drv(dev->driver);
+	s = p_dev->socket;
 
-	if (!try_module_get(p_drv->owner)) {
+	if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) {
 		ret = -EINVAL;
 		goto put_dev;
 	}
 
-	if (p_drv->attach) {
-		p_dev->instance = p_drv->attach();
-		if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) {
-			printk(KERN_NOTICE "ds: unable to create instance "
-			       "of '%s'!\n", p_drv->drv.name);
-			ret = -EINVAL;
+	p_dev->state &= ~CLIENT_UNBOUND;
+
+	/* set up the device configuration, if it hasn't been done before */
+	if (!s->functions) {
+		cistpl_longlink_mfc_t mfc;
+		if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC,
+				      &mfc) == CS_SUCCESS)
+			s->functions = mfc.nfn;
+		else
+			s->functions = 1;
+		s->config = kzalloc(sizeof(config_t) * s->functions,
+				    GFP_KERNEL);
+		if (!s->config) {
+			ret = -ENOMEM;
+			goto put_module;
 		}
 	}
 
+	ret = p_drv->probe(p_dev);
+
+ put_module:
 	if (ret)
 		module_put(p_drv->owner);
  put_dev:
-	if ((ret) || !(p_drv->attach))
+	if (ret)
 		put_device(dev);
 	return (ret);
 }
@@ -399,24 +409,66 @@
 {
 	struct pcmcia_device *p_dev;
 	struct pcmcia_driver *p_drv;
+	int i;
 
 	/* detach the "instance" */
 	p_dev = to_pcmcia_dev(dev);
 	p_drv = to_pcmcia_drv(dev->driver);
+	if (!p_drv)
+		return 0;
 
-	if (p_drv) {
-		if ((p_drv->detach) && (p_dev->instance)) {
-			p_drv->detach(p_dev->instance);
-			/* from pcmcia_probe_device */
-			put_device(&p_dev->dev);
-		}
-		module_put(p_drv->owner);
-	}
+	if (p_drv->remove)
+	       	p_drv->remove(p_dev);
+
+	/* check for proper unloading */
+	if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
+		printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
+		       p_drv->drv.name);
+
+	for (i = 0; i < MAX_WIN; i++)
+		if (p_dev->state & CLIENT_WIN_REQ(i))
+			printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
+			       p_drv->drv.name);
+
+	/* references from pcmcia_probe_device */
+	p_dev->state = CLIENT_UNBOUND;
+	pcmcia_put_dev(p_dev);
+	module_put(p_drv->owner);
 
 	return 0;
 }
 
 
+/*
+ * Removes a PCMCIA card from the device tree and socket list.
+ */
+static void pcmcia_card_remove(struct pcmcia_socket *s)
+{
+	struct pcmcia_device	*p_dev;
+	unsigned long		flags;
+
+	ds_dbg(2, "unbind_request(%d)\n", s->sock);
+
+	s->device_count = 0;
+
+	for (;;) {
+		/* unregister all pcmcia_devices registered with this socket*/
+		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
+		if (list_empty(&s->devices_list)) {
+			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+ 			return;
+		}
+		p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
+		list_del(&p_dev->socket_device_list);
+		p_dev->state |= CLIENT_STALE;
+		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
+
+		device_unregister(&p_dev->dev);
+	}
+
+	return;
+} /* unbind_request */
+
 
 /*
  * pcmcia_device_query -- determine information about a pcmcia device
@@ -517,10 +569,9 @@
 	if (s->device_count == 2)
 		goto err_put;
 
-	p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
+	p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
 	if (!p_dev)
 		goto err_put;
-	memset(p_dev, 0, sizeof(struct pcmcia_device));
 
 	p_dev->socket = s;
 	p_dev->device_no = (s->device_count++);
@@ -583,7 +634,9 @@
 	if (!(s->resource_setup_done))
 		return -EAGAIN; /* try again, but later... */
 
-	pcmcia_validate_mem(s);
+	if (pcmcia_validate_mem(s))
+		return -EAGAIN; /* try again, but later... */
+
 	ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo);
 	if (ret || !cisinfo.Chains) {
 		ds_dbg(0, "invalid CIS or invalid resources\n");
@@ -779,8 +832,8 @@
 
 #ifdef CONFIG_HOTPLUG
 
-static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
-			      char *buffer, int buffer_size)
+static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
+			     char *buffer, int buffer_size)
 {
 	struct pcmcia_device *p_dev;
 	int i, length = 0;
@@ -800,31 +853,31 @@
 
 	i = 0;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"SOCKET_NO=%u",
-				p_dev->socket->sock))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "SOCKET_NO=%u",
+			   p_dev->socket->sock))
 		return -ENOMEM;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"DEVICE_NO=%02X",
-				p_dev->device_no))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "DEVICE_NO=%02X",
+			   p_dev->device_no))
 		return -ENOMEM;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
-				"pa%08Xpb%08Xpc%08Xpd%08X",
-				p_dev->has_manf_id ? p_dev->manf_id : 0,
-				p_dev->has_card_id ? p_dev->card_id : 0,
-				p_dev->has_func_id ? p_dev->func_id : 0,
-				p_dev->func,
-				p_dev->device_no,
-				hash[0],
-				hash[1],
-				hash[2],
-				hash[3]))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
+			   "pa%08Xpb%08Xpc%08Xpd%08X",
+			   p_dev->has_manf_id ? p_dev->manf_id : 0,
+			   p_dev->has_card_id ? p_dev->card_id : 0,
+			   p_dev->has_func_id ? p_dev->func_id : 0,
+			   p_dev->func,
+			   p_dev->device_no,
+			   hash[0],
+			   hash[1],
+			   hash[2],
+			   hash[3]))
 		return -ENOMEM;
 
 	envp[i] = NULL;
@@ -834,7 +887,7 @@
 
 #else
 
-static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
+static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
 			      char *buffer, int buffer_size)
 {
 	return -ENODEV;
@@ -918,6 +971,78 @@
 	__ATTR_NULL,
 };
 
+/* PM support, also needed for reset */
+
+static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
+{
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+	struct pcmcia_driver *p_drv = NULL;
+
+	if (dev->driver)
+		p_drv = to_pcmcia_drv(dev->driver);
+
+	if (p_drv && p_drv->suspend)
+		return p_drv->suspend(p_dev);
+
+	return 0;
+}
+
+
+static int pcmcia_dev_resume(struct device * dev)
+{
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+        struct pcmcia_driver *p_drv = NULL;
+
+	if (dev->driver)
+		p_drv = to_pcmcia_drv(dev->driver);
+
+	if (p_drv && p_drv->resume)
+		return p_drv->resume(p_dev);
+
+	return 0;
+}
+
+
+static int pcmcia_bus_suspend_callback(struct device *dev, void * _data)
+{
+	struct pcmcia_socket *skt = _data;
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+
+	if (p_dev->socket != skt)
+		return 0;
+
+	return dpm_runtime_suspend(dev, PMSG_SUSPEND);
+}
+
+static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
+{
+	struct pcmcia_socket *skt = _data;
+	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
+
+	if (p_dev->socket != skt)
+		return 0;
+
+	dpm_runtime_resume(dev);
+
+	return 0;
+}
+
+static int pcmcia_bus_resume(struct pcmcia_socket *skt)
+{
+	bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
+	return 0;
+}
+
+static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
+{
+	if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
+			     pcmcia_bus_suspend_callback)) {
+		pcmcia_bus_resume(skt);
+		return -EIO;
+	}
+	return 0;
+}
+
 
 /*======================================================================
 
@@ -925,49 +1050,6 @@
     
 ======================================================================*/
 
-struct send_event_data {
-	struct pcmcia_socket *skt;
-	event_t event;
-	int priority;
-};
-
-static int send_event_callback(struct device *dev, void * _data)
-{
-	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
-	struct pcmcia_driver *p_drv;
-	struct send_event_data *data = _data;
-
-	/* we get called for all sockets, but may only pass the event
-	 * for drivers _on the affected socket_ */
-	if (p_dev->socket != data->skt)
-		return 0;
-
-	p_drv = to_pcmcia_drv(p_dev->dev.driver);
-	if (!p_drv)
-		return 0;
-
-	if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
-		return 0;
-
-	if (p_drv->event)
-		return p_drv->event(data->event, data->priority,
-				    &p_dev->event_callback_args);
-
-	return 0;
-}
-
-static int send_event(struct pcmcia_socket *s, event_t event, int priority)
-{
-	struct send_event_data private;
-
-	private.skt = s;
-	private.event = event;
-	private.priority = priority;
-
-	return bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback);
-} /* send_event */
-
-
 /* Normally, the event is passed to individual drivers after
  * informing userspace. Only for CS_EVENT_CARD_REMOVAL this
  * is inversed to maintain historic compatibility.
@@ -976,20 +1058,17 @@
 static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
 {
 	struct pcmcia_socket *s = pcmcia_get_socket(skt);
-	int ret = 0;
 
 	ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
 	       event, priority, skt);
-    
-	switch (event) {
 
+	switch (event) {
 	case CS_EVENT_CARD_REMOVAL:
 		s->pcmcia_state.present = 0;
-	    	send_event(skt, event, priority);
-		unbind_request(skt);
+		pcmcia_card_remove(skt);
 		handle_event(skt, event);
 		break;
-	
+
 	case CS_EVENT_CARD_INSERTION:
 		s->pcmcia_state.present = 1;
 		pcmcia_card_add(skt);
@@ -997,12 +1076,14 @@
 		break;
 
 	case CS_EVENT_EJECTION_REQUEST:
-		ret = send_event(skt, event, priority);
 		break;
 
+	case CS_EVENT_PM_SUSPEND:
+	case CS_EVENT_PM_RESUME:
+	case CS_EVENT_RESET_PHYSICAL:
+	case CS_EVENT_CARD_RESET:
 	default:
 		handle_event(skt, event);
-		send_event(skt, event, priority);
 		break;
     }
 
@@ -1012,152 +1093,12 @@
 } /* ds_event */
 
 
-
-int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req)
-{
-	struct pcmcia_socket *s = NULL;
-	struct pcmcia_device *p_dev = NULL;
-	struct pcmcia_driver *p_drv = NULL;
-
-	/* Look for unbound client with matching dev_info */
-	down_read(&pcmcia_socket_list_rwsem);
-	list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
-		unsigned long flags;
-
-		if (s->state & SOCKET_CARDBUS)
-			continue;
-
-		s = pcmcia_get_socket(s);
-		if (!s)
-			continue;
-		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-		list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
-			p_dev = pcmcia_get_dev(p_dev);
-			if (!p_dev)
-				continue;
-			if (!(p_dev->state & CLIENT_UNBOUND) ||
-			    (!p_dev->dev.driver)) {
-				pcmcia_put_dev(p_dev);
-				continue;
-			}
-			p_drv = to_pcmcia_drv(p_dev->dev.driver);
-			if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) {
-				spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-				goto found;
-			}
-			pcmcia_put_dev(p_dev);
-		}
-		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-		pcmcia_put_socket(s);
-	}
- found:
-	up_read(&pcmcia_socket_list_rwsem);
-	if (!p_dev)
-		return -ENODEV;
-
-	pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */
-
-	*handle = p_dev;
-	p_dev->state &= ~CLIENT_UNBOUND;
-	p_dev->event_callback_args = req->event_callback_args;
-	p_dev->event_callback_args.client_handle = p_dev;
-
-
-	if (!s->functions) {
-		cistpl_longlink_mfc_t mfc;
-		if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc)
-		    == CS_SUCCESS)
-			s->functions = mfc.nfn;
-		else
-			s->functions = 1;
-		s->config = kmalloc(sizeof(config_t) * s->functions,
-				    GFP_KERNEL);
-		if (!s->config)
-			goto out_no_resource;
-		memset(s->config, 0, sizeof(config_t) * s->functions);
-	}
-
-	ds_dbg(1, "register_client(): client 0x%p, dev %s\n",
-	       p_dev, p_dev->dev.bus_id);
-
-	if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
-		if (p_drv->event)
-			p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW,
-				     &p_dev->event_callback_args);
-
-	}
-
-	return CS_SUCCESS;
-
- out_no_resource:
-	pcmcia_put_dev(p_dev);
-	return CS_OUT_OF_RESOURCE;
-} /* register_client */
-EXPORT_SYMBOL(pcmcia_register_client);
-
-
-/* unbind _all_ devices attached to a given pcmcia_bus_socket. The
- * drivers have been called with EVENT_CARD_REMOVAL before.
- */
-static int unbind_request(struct pcmcia_socket *s)
-{
-	struct pcmcia_device	*p_dev;
-	unsigned long		flags;
-
-	ds_dbg(2, "unbind_request(%d)\n", s->sock);
-
-	s->device_count = 0;
-
-	for (;;) {
-		/* unregister all pcmcia_devices registered with this socket*/
-		spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
-		if (list_empty(&s->devices_list)) {
-			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
- 			return 0;
-		}
-		p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
-		list_del(&p_dev->socket_device_list);
-		p_dev->state |= CLIENT_STALE;
-		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
-
-		device_unregister(&p_dev->dev);
-	}
-
-	return 0;
-} /* unbind_request */
-
-int pcmcia_deregister_client(struct pcmcia_device *p_dev)
-{
-	struct pcmcia_socket *s;
-	int i;
-
-	s = p_dev->socket;
-	ds_dbg(1, "deregister_client(%p)\n", p_dev);
-
-	if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
-		goto warn_out;
-	for (i = 0; i < MAX_WIN; i++)
-		if (p_dev->state & CLIENT_WIN_REQ(i))
-			goto warn_out;
-
-	if (p_dev->state & CLIENT_STALE) {
-		p_dev->state &= ~CLIENT_STALE;
-		pcmcia_put_dev(p_dev);
-	} else {
-		p_dev->state = CLIENT_UNBOUND;
-	}
-
-	return CS_SUCCESS;
- warn_out:
-	printk(KERN_WARNING "ds: deregister_client was called too early.\n");
-	return CS_IN_USE;
-} /* deregister_client */
-EXPORT_SYMBOL(pcmcia_deregister_client);
-
 static struct pcmcia_callback pcmcia_bus_callback = {
 	.owner = THIS_MODULE,
 	.event = ds_event,
 	.requery = pcmcia_bus_rescan,
+	.suspend = pcmcia_bus_suspend,
+	.resume = pcmcia_bus_resume,
 };
 
 static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
@@ -1223,9 +1164,11 @@
 
 struct bus_type pcmcia_bus_type = {
 	.name = "pcmcia",
-	.hotplug = pcmcia_bus_hotplug,
+	.uevent = pcmcia_bus_uevent,
 	.match = pcmcia_bus_match,
 	.dev_attrs = pcmcia_dev_attrs,
+	.suspend = pcmcia_dev_suspend,
+	.resume = pcmcia_dev_resume,
 };
 
 
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 561706b..b39435b 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -417,18 +417,6 @@
 
 /*============================================================*/
 
-static int hs_get_socket(struct pcmcia_socket *s, socket_state_t *state)
-{
-    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
-
-    	DPRINTK("hs_get_socket(%d)\n", sock);
-	
-	*state = sp->state;
-	return 0;
-}
-
-/*============================================================*/
-
 static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
     	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket);
@@ -749,7 +737,6 @@
 static struct pccard_operations hs_operations = {
 	.init			= hs_init,
 	.get_status		= hs_get_status,
-	.get_socket		= hs_get_socket,
 	.set_socket		= hs_set_socket,
 	.set_io_map		= hs_set_io_map,
 	.set_mem_map		= hs_set_mem_map,
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index f3fdc74..7979c85 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -66,7 +66,6 @@
 static struct pccard_operations i82092aa_operations = {
 	.init 		 	= i82092aa_init,
 	.get_status		= i82092aa_get_status,
-	.get_socket		= i82092aa_get_socket,
 	.set_socket		= i82092aa_set_socket,
 	.set_io_map		= i82092aa_set_io_map,
 	.set_mem_map		= i82092aa_set_mem_map,
@@ -482,78 +481,6 @@
 }
 
 
-static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state) 
-{
-	unsigned int sock = container_of(socket, struct socket_info, socket)->number;
-	unsigned char reg,vcc,vpp;
-	
-	enter("i82092aa_get_socket");
-	state->flags    = 0;
-	state->Vcc      = 0;
-	state->Vpp      = 0;
-	state->io_irq   = 0;
-	state->csc_mask = 0;
-
-	/* First the power status of the socket */
-	reg = indirect_read(sock,I365_POWER); /* PCTRL - Power Control Register */
-
-	if (reg & I365_PWR_AUTO)
-		state->flags |= SS_PWR_AUTO;  /* Automatic Power Switch */
-		
-	if (reg & I365_PWR_OUT)
-		state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */
-		
-	vcc = reg & I365_VCC_MASK;    vpp = reg & I365_VPP1_MASK;
-	
-	if (reg & I365_VCC_5V) { /* Can still be 3.3V, in this case the Vcc value will be overwritten later */
-		state->Vcc = 50;
-		
-		if (vpp == I365_VPP1_5V)
-			state->Vpp = 50;
-		if (vpp == I365_VPP1_12V)
-			state->Vpp = 120;
-			
-	}
-	
-	if ((reg & I365_VCC_3V)==I365_VCC_3V)
-		state->Vcc = 33;
-	
-	
-	/* Now the IO card, RESET flags and IO interrupt */
-	
-	reg = indirect_read(sock, I365_INTCTL); /* IGENC, Interrupt and General Control */
-	
-	if ((reg & I365_PC_RESET)==0)
-		state->flags |= SS_RESET;
-	if (reg & I365_PC_IOCARD) 
-		state->flags |= SS_IOCARD; /* This is an IO card */
-	
-	/* Set the IRQ number */
-	if (sockets[sock].dev!=NULL)
-		state->io_irq = sockets[sock].dev->irq;
-	
-	/* Card status change */
-	reg = indirect_read(sock, I365_CSCINT); /* CSCICR, Card Status Change Interrupt Configuration */
-	
-	if (reg & I365_CSC_DETECT) 
-		state->csc_mask |= SS_DETECT; /* Card detect is enabled */
-	
-	if (state->flags & SS_IOCARD) {/* IO Cards behave different */
-		if (reg & I365_CSC_STSCHG)
-			state->csc_mask |= SS_STSCHG;
-	} else {
-		if (reg & I365_CSC_BVD1) 
-			state->csc_mask |= SS_BATDEAD;
-		if (reg & I365_CSC_BVD2) 
-			state->csc_mask |= SS_BATWARN;
-		if (reg & I365_CSC_READY) 
-			state->csc_mask |= SS_READY;
-	}
-		
-	leave("i82092aa_get_socket");
-	return 0;
-}
-
 static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state) 
 {
 	unsigned int sock = container_of(socket, struct socket_info, socket)->number;
diff --git a/drivers/pcmcia/i82092aa.h b/drivers/pcmcia/i82092aa.h
index b98cac7..9c14599d 100644
--- a/drivers/pcmcia/i82092aa.h
+++ b/drivers/pcmcia/i82092aa.h
@@ -29,7 +29,6 @@
 
 
 static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value);
-static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state);
 static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state);
 static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io);
 static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem);
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 4d56bc9..35a92d1 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -940,78 +940,6 @@
 
 /*====================================================================*/
 
-static int i365_get_socket(u_short sock, socket_state_t *state)
-{
-    struct i82365_socket *t = &socket[sock];
-    u_char reg, vcc, vpp;
-    
-    reg = i365_get(sock, I365_POWER);
-    state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
-    state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
-    vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK;
-    state->Vcc = state->Vpp = 0;
-    if (t->flags & IS_CIRRUS) {
-	if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {
-	    if (reg & I365_VCC_5V) state->Vcc = 33;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 33;
-	} else {
-	    if (reg & I365_VCC_5V) state->Vcc = 50;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 50;
-	}
-	if (vpp == I365_VPP1_12V) state->Vpp = 120;
-    } else if (t->flags & IS_VG_PWR) {
-	if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) {
-	    if (reg & I365_VCC_5V) state->Vcc = 33;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 33;
-	} else {
-	    if (reg & I365_VCC_5V) state->Vcc = 50;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 50;
-	}
-	if (vpp == I365_VPP1_12V) state->Vpp = 120;
-    } else if (t->flags & IS_DF_PWR) {
-	if (vcc == I365_VCC_3V) state->Vcc = 33;
-	if (vcc == I365_VCC_5V) state->Vcc = 50;
-	if (vpp == I365_VPP1_5V) state->Vpp = 50;
-	if (vpp == I365_VPP1_12V) state->Vpp = 120;
-    } else {
-	if (reg & I365_VCC_5V) {
-	    state->Vcc = 50;
-	    if (vpp == I365_VPP1_5V) state->Vpp = 50;
-	    if (vpp == I365_VPP1_12V) state->Vpp = 120;
-	}
-    }
-
-    /* IO card, RESET flags, IO interrupt */
-    reg = i365_get(sock, I365_INTCTL);
-    state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
-    if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;
-    state->io_irq = reg & I365_IRQ_MASK;
-    
-    /* speaker control */
-    if (t->flags & IS_CIRRUS) {
-	if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA)
-	    state->flags |= SS_SPKR_ENA;
-    }
-    
-    /* Card status change mask */
-    reg = i365_get(sock, I365_CSCINT);
-    state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
-    if (state->flags & SS_IOCARD)
-	state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
-    else {
-	state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-	state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
-	state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
-    }
-    
-    debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-	  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
-	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-    return 0;
-} /* i365_get_socket */
-
-/*====================================================================*/
-
 static int i365_set_socket(u_short sock, socket_state_t *state)
 {
     struct i82365_socket *t = &socket[sock];
@@ -1265,16 +1193,6 @@
 	LOCKED(i365_get_status(sock, value));
 }
 
-static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state)
-{
-	unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
-
-	if (socket[sock].flags & IS_ALIVE)
-		return -EINVAL;
-
-	LOCKED(i365_get_socket(sock, state));
-}
-
 static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
 	unsigned int sock = container_of(s, struct i82365_socket, socket)->number;
@@ -1324,7 +1242,6 @@
 static struct pccard_operations pcic_operations = {
 	.init			= pcic_init,
 	.get_status		= pcic_get_status,
-	.get_socket		= pcic_get_socket,
 	.set_socket		= pcic_set_socket,
 	.set_io_map		= pcic_set_io_map,
 	.set_mem_map		= pcic_set_mem_map,
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 2c22b4b..071cf48 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -355,9 +355,10 @@
 #ifndef CONFIG_PLAT_USRV
 	/* insert interrupt */
 	request_irq(irq, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
+#ifndef CONFIG_PLAT_MAPPI3
 	/* eject interrupt */
 	request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
-
+#endif
 	debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
 	pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
 #endif	/* CONFIG_PLAT_USRV */
@@ -479,25 +480,6 @@
 
 /*====================================================================*/
 
-static int _pcc_get_socket(u_short sock, socket_state_t *state)
-{
-//	pcc_socket_t *t = &socket[sock];
-
-	state->flags = 0;
-	state->csc_mask = SS_DETECT;
-	state->csc_mask |= SS_READY;
-	state->io_irq = 0;
-	state->Vcc = 33;	/* 3.3V fixed */
-	state->Vpp = 33;
-
-	debug(3, "m32r_cfc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-		  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
-		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-	return 0;
-} /* _get_socket */
-
-/*====================================================================*/
-
 static int _pcc_set_socket(u_short sock, socket_state_t *state)
 {
 	debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
@@ -666,18 +648,6 @@
 	LOCKED(_pcc_get_status(sock, value));
 }
 
-static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state)
-{
-	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
-
-	if (socket[sock].flags & IS_ALIVE) {
-		debug(3, "m32r_cfc: pcc_get_socket: sock(%d) -EINVAL\n", sock);
-		return -EINVAL;
-	}
-	debug(3, "m32r_cfc: pcc_get_socket: sock(%d)\n", sock);
-	LOCKED(_pcc_get_socket(sock, state));
-}
-
 static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
@@ -723,7 +693,6 @@
 static struct pccard_operations pcc_operations = {
 	.init			= pcc_init,
 	.get_status		= pcc_get_status,
-	.get_socket		= pcc_get_socket,
 	.set_socket		= pcc_set_socket,
 	.set_io_map		= pcc_set_io_map,
 	.set_mem_map		= pcc_set_mem_map,
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 356a6fb..70d5f07 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -429,16 +429,6 @@
 
 /*====================================================================*/
 
-static int _pcc_get_socket(u_short sock, socket_state_t *state)
-{
-	debug(3, "m32r-pcc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-		  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
-		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-	return 0;
-} /* _get_socket */
-
-/*====================================================================*/
-
 static int _pcc_set_socket(u_short sock, socket_state_t *state)
 {
 	u_long reg = 0;
@@ -641,15 +631,6 @@
 	LOCKED(_pcc_get_status(sock, value));
 }
 
-static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state)
-{
-	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
-
-	if (socket[sock].flags & IS_ALIVE)
-		return -EINVAL;
-	LOCKED(_pcc_get_socket(sock, state));
-}
-
 static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
 {
 	unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
@@ -687,7 +668,6 @@
 static struct pccard_operations pcc_operations = {
 	.init			= pcc_init,
 	.get_status		= pcc_get_status,
-	.get_socket		= pcc_get_socket,
 	.set_socket		= pcc_set_socket,
 	.set_io_map		= pcc_set_io_map,
 	.set_mem_map		= pcc_set_mem_map,
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index 6d9f71c..0e07d95 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -9,6 +9,9 @@
  *     <oliver.kurth@cyclades.de>
  * Further fixes, v2.6 kernel port
  *     <marcelo.tosatti@cyclades.com>
+ * 
+ * Some fixes, additions (C) 2005 Montavista Software, Inc. 
+ *     <vbordug@ru.mvista.com>
  *
  * "The ExCA standard specifies that socket controllers should provide
  * two IO and five memory windows per socket, which can be independently
@@ -97,6 +100,11 @@
 #endif
 #endif
 
+#if defined(CONFIG_MPC885ADS)
+#define CONFIG_PCMCIA_SLOT_A
+#define PCMCIA_GLITCHY_CD
+#endif
+
 /* Cyclades ACS uses both slots */
 #ifdef CONFIG_PRxK
 #define CONFIG_PCMCIA_SLOT_A
@@ -374,10 +382,10 @@
 	}
 
 	/* first, turn off all power */
-	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
+	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
 
 	/* enable new powersettings */
-	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg);
+	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | reg);
 
 	return 0;
 }
@@ -386,12 +394,89 @@
 
 static void hardware_enable(int slot)
 {
-	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN);
+	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~BCSR1_PCCEN);
 }
 
 static void hardware_disable(int slot)
 {
-	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) |  BCSR1_PCCEN);
+	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) |  BCSR1_PCCEN);
+}
+
+#endif
+
+/* MPC885ADS Boards */
+
+#if defined(CONFIG_MPC885ADS)
+
+#define PCMCIA_BOARD_MSG "MPC885ADS"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	u32 reg = 0;
+	unsigned *bcsr_io;
+
+	bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+	switch(vcc) {
+		case 0:
+			break;
+		case 33:
+			reg |= BCSR1_PCCVCC0;
+			break;
+		case 50:
+			reg |= BCSR1_PCCVCC1;
+			break;
+		default:
+			return 1;
+	}
+
+	switch(vpp) {
+		case 0:
+			break;
+		case 33:
+		case 50:
+			if(vcc == vpp)
+				reg |= BCSR1_PCCVPP1;
+			else
+				return 1;
+			break;
+		case 120:
+			if ((vcc == 33) || (vcc == 50))
+				reg |= BCSR1_PCCVPP0;
+			else
+				return 1;
+		default:
+			return 1;
+	}
+
+	/* first, turn off all power */
+	out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));
+
+	/* enable new powersettings */
+	out_be32(bcsr_io, in_be32(bcsr_io) | reg);
+
+	iounmap(bcsr_io);
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+
+static void hardware_enable(int slot)
+{
+	unsigned *bcsr_io;
+
+	bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+	out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN);
+	iounmap(bcsr_io);
+}
+
+static void hardware_disable(int slot)
+{
+	unsigned *bcsr_io;
+
+	bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+	out_be32(bcsr_io, in_be32(bcsr_io) |  BCSR1_PCCEN);
+	iounmap(bcsr_io);
 }
 
 #endif
@@ -440,10 +525,10 @@
 	}
 
 	/* first, turn off all power */
-	out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
+	out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));
 
 	/* enable new powersettings */
-	out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg);
+	out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) | reg);
 
 	return 0;
 }
@@ -823,17 +908,6 @@
 	return 0;
 }
 
-static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	int lsock = container_of(sock, struct socket_info, socket)->slot;
-	*state = socket[lsock].state; /* copy the whole structure */
-
-	dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-	      "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
-	      state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-	return 0;
-}
-
 static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
 	int lsock = container_of(sock, struct socket_info, socket)->slot;
@@ -1023,8 +1097,7 @@
 		if(io->flags & MAP_WRPROT)
 			reg |= M8XX_PCMCIA_POR_WRPROT;
 
-		/*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/
-		if(io->flags & MAP_16BIT)
+		if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
 			reg |= M8XX_PCMCIA_POR_16BIT;
 
 		if(io->flags & MAP_ACTIVE)
@@ -1169,7 +1242,6 @@
 	.init	= m8xx_sock_init,
 	.suspend = m8xx_suspend,
 	.get_status = m8xx_get_status,
-	.get_socket = m8xx_get_socket,
 	.set_socket = m8xx_set_socket,
 	.set_io_map = m8xx_set_io_map,
 	.set_mem_map = m8xx_set_mem_map,
@@ -1244,7 +1316,7 @@
 		socket[i].socket.io_offset = 0;
 		socket[i].socket.pci_irq = i  ? 7 : 9;
 		socket[i].socket.ops = &m8xx_services;
-		socket[i].socket.resource_ops = &pccard_nonstatic_ops;
+		socket[i].socket.resource_ops = &pccard_iodyn_ops;
 		socket[i].socket.cb_dev = NULL;
 		socket[i].socket.dev.dev = &m8xx_device.dev;
 	}
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index 20642f0..f2789af 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -304,75 +304,6 @@
 }
 
 
-static int pd6729_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct pd6729_socket *socket
-			= container_of(sock, struct pd6729_socket, socket);
-	unsigned char reg, vcc, vpp;
-
-	state->flags    = 0;
-	state->Vcc      = 0;
-	state->Vpp      = 0;
-	state->io_irq   = 0;
-	state->csc_mask = 0;
-
-	/* First the power status of the socket */
-	reg = indirect_read(socket, I365_POWER);
-
-	if (reg & I365_PWR_AUTO)
-		state->flags |= SS_PWR_AUTO;  /* Automatic Power Switch */
-
-	if (reg & I365_PWR_OUT)
-		state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */
-
-	vcc = reg & I365_VCC_MASK;    vpp = reg & I365_VPP1_MASK;
-
-	if (reg & I365_VCC_5V) {
-		state->Vcc = (indirect_read(socket, PD67_MISC_CTL_1) &
-			PD67_MC1_VCC_3V) ? 33 : 50;
-
-		if (vpp == I365_VPP1_5V) {
-			if (state->Vcc == 50)
-				state->Vpp = 50;
-			else
-				state->Vpp = 33;
-		}
-		if (vpp == I365_VPP1_12V)
-			state->Vpp = 120;
-	}
-
-	/* Now the IO card, RESET flags and IO interrupt */
-	reg = indirect_read(socket, I365_INTCTL);
-
-	if ((reg & I365_PC_RESET) == 0)
-		state->flags |= SS_RESET;
-	if (reg & I365_PC_IOCARD)
-		state->flags |= SS_IOCARD; /* This is an IO card */
-
-	/* Set the IRQ number */
-	state->io_irq = socket->card_irq;
-
-	/* Card status change */
-	reg = indirect_read(socket, I365_CSCINT);
-
-	if (reg & I365_CSC_DETECT)
-		state->csc_mask |= SS_DETECT; /* Card detect is enabled */
-
-	if (state->flags & SS_IOCARD) {/* IO Cards behave different */
-		if (reg & I365_CSC_STSCHG)
-			state->csc_mask |= SS_STSCHG;
-	} else {
-		if (reg & I365_CSC_BVD1)
-			state->csc_mask |= SS_BATDEAD;
-		if (reg & I365_CSC_BVD2)
-			state->csc_mask |= SS_BATWARN;
-		if (reg & I365_CSC_READY)
-			state->csc_mask |= SS_READY;
-	}
-
-	return 0;
-}
-
 static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
 {
 	struct pd6729_socket *socket
@@ -640,7 +571,6 @@
 static struct pccard_operations pd6729_operations = {
 	.init 			= pd6729_init,
 	.get_status		= pd6729_get_status,
-	.get_socket		= pd6729_get_socket,
 	.set_socket		= pd6729_set_socket,
 	.set_io_map		= pd6729_set_io_map,
 	.set_mem_map		= pd6729_set_mem_map,
@@ -704,13 +634,11 @@
 	char configbyte;
 	struct pd6729_socket *socket;
 
-	socket = kmalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,
+	socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,
 			 GFP_KERNEL);
 	if (!socket)
 		return -ENOMEM;
 
-	memset(socket, 0, sizeof(struct pd6729_socket) * MAX_SOCKETS);
-
 	if ((ret = pci_enable_device(dev)))
 		goto err_out_free_mem;
 
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 5209d8c..5d957df 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -171,10 +171,9 @@
 {
 	int ret;
 
-	mst_pcmcia_device = kmalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL);
+	mst_pcmcia_device = kzalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL);
 	if (!mst_pcmcia_device)
 		return -ENOMEM;
-	memset(mst_pcmcia_device, 0, sizeof(*mst_pcmcia_device));
 	mst_pcmcia_device->name = "pxa2xx-pcmcia";
 	mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops;
 
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index 56c5883..12a7244 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -36,9 +36,18 @@
 struct scoop_pcmcia_config *platform_scoop_config;
 #define SCOOP_DEV platform_scoop_config->devs
 
-static void sharpsl_pcmcia_init_reset(struct scoop_pcmcia_dev *scoopdev)
+static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt)
 {
+	struct scoop_pcmcia_dev *scoopdev = &SCOOP_DEV[skt->nr];
+
 	reset_scoop(scoopdev->dev);
+
+	/* Shared power controls need to be handled carefully */
+	if (platform_scoop_config->power_ctrl)
+		platform_scoop_config->power_ctrl(scoopdev->dev, 0x0000, skt->nr);
+	else
+		write_scoop_reg(scoopdev->dev, SCOOP_CPR, 0x0000);
+
 	scoopdev->keep_vs = NO_KEEP_VS;
 	scoopdev->keep_rd = 0;
 }
@@ -208,26 +217,17 @@
 
 static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
 {
-	sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
+	sharpsl_pcmcia_init_reset(skt);
 
 	/* Enable interrupt */
 	write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_IMR, 0x00C0);
 	write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_MCR, 0x0101);
 	SCOOP_DEV[skt->nr].keep_vs = NO_KEEP_VS;
-
-	if (machine_is_collie())
-		/* We need to disable SS_OUTPUT_ENA here. */
-		write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
 }
 
 static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
-	/* CF_BUS_OFF */
-	sharpsl_pcmcia_init_reset(&SCOOP_DEV[skt->nr]);
-
-	if (machine_is_collie())
-		/* We need to disable SS_OUTPUT_ENA here. */
-		write_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR, read_scoop_reg(SCOOP_DEV[skt->nr].dev, SCOOP_CPR) & ~0x0080);
+	sharpsl_pcmcia_init_reset(skt);
 }
 
 static struct pcmcia_low_level sharpsl_pcmcia_ops = {
@@ -264,11 +264,10 @@
 	int ret;
 
 	sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs;
-	sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
+	sharpsl_pcmcia_device = kzalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);
 	if (!sharpsl_pcmcia_device)
 		return -ENOMEM;
 
-	memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));
 	sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";
 	sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
 	sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev;
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index 0668384..5146093 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -98,10 +98,12 @@
 }
 EXPORT_SYMBOL(pcmcia_adjust_resource_info);
 
-void pcmcia_validate_mem(struct pcmcia_socket *s)
+int pcmcia_validate_mem(struct pcmcia_socket *s)
 {
 	if (s->resource_ops->validate_mem)
-		s->resource_ops->validate_mem(s);
+		return s->resource_ops->validate_mem(s);
+	/* if there is no callback, we can assume that everything is OK */
+	return 0;
 }
 EXPORT_SYMBOL(pcmcia_validate_mem);
 
@@ -164,3 +166,105 @@
 	.exit = NULL,
 };
 EXPORT_SYMBOL(pccard_static_ops);
+
+
+#ifdef CONFIG_PCCARD_IODYN
+
+static struct resource *
+make_resource(unsigned long b, unsigned long n, int flags, char *name)
+{
+	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
+
+	if (res) {
+		res->name = name;
+		res->start = b;
+		res->end = b + n - 1;
+		res->flags = flags;
+	}
+	return res;
+}
+
+struct pcmcia_align_data {
+	unsigned long	mask;
+	unsigned long	offset;
+};
+
+static void pcmcia_align(void *align_data, struct resource *res,
+			unsigned long size, unsigned long align)
+{
+	struct pcmcia_align_data *data = align_data;
+	unsigned long start;
+
+	start = (res->start & ~data->mask) + data->offset;
+	if (start < res->start)
+		start += data->mask + 1;
+	res->start = start;
+
+#ifdef CONFIG_X86
+        if (res->flags & IORESOURCE_IO) {
+                if (start & 0x300) {
+                        start = (start + 0x3ff) & ~0x3ff;
+                        res->start = start;
+                }
+        }
+#endif
+
+#ifdef CONFIG_M68K
+        if (res->flags & IORESOURCE_IO) {
+		if ((res->start + size - 1) >= 1024)
+			res->start = res->end;
+	}
+#endif
+}
+
+
+static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start,
+				      unsigned long r_end, struct pcmcia_socket *s)
+{
+	return adjust_resource(res, r_start, r_end - r_start + 1);
+}
+
+
+static struct resource *iodyn_find_io_region(unsigned long base, int num,
+		unsigned long align, struct pcmcia_socket *s)
+{
+	struct resource *res = make_resource(0, num, IORESOURCE_IO,
+					     s->dev.class_id);
+	struct pcmcia_align_data data;
+	unsigned long min = base;
+	int ret;
+
+	if (align == 0)
+		align = 0x10000;
+
+	data.mask = align - 1;
+	data.offset = base & data.mask;
+
+#ifdef CONFIG_PCI
+	if (s->cb_dev) {
+		ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
+					     min, 0, pcmcia_align, &data);
+	} else
+#endif
+		ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
+					1, pcmcia_align, &data);
+
+	if (ret != 0) {
+		kfree(res);
+		res = NULL;
+	}
+	return res;
+}
+
+struct pccard_resource_ops pccard_iodyn_ops = {
+	.validate_mem = NULL,
+	.adjust_io_region = iodyn_adjust_io_region,
+	.find_io = iodyn_find_io_region,
+	.find_mem = NULL,
+	.adjust_resource = NULL,
+	.init = static_init,
+	.exit = NULL,
+};
+EXPORT_SYMBOL(pccard_iodyn_ops);
+
+#endif /* CONFIG_PCCARD_IODYN */
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 00960a3..5301ac6 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -75,10 +75,9 @@
 static struct resource *
 make_resource(unsigned long b, unsigned long n, int flags, char *name)
 {
-	struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL);
+	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
 
 	if (res) {
-		memset(res, 0, sizeof(*res));
 		res->name = name;
 		res->start = b;
 		res->end = b + n - 1;
@@ -200,12 +199,11 @@
 	   base, base+num-1);
 
     /* First, what does a floating port look like? */
-    b = kmalloc(256, GFP_KERNEL);
+    b = kzalloc(256, GFP_KERNEL);
     if (!b) {
             printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
             return;
     }
-    memset(b, 0, 256);
     for (i = base, most = 0; i < base+num; i += 8) {
 	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");
 	if (!res)
@@ -407,69 +405,79 @@
 
 static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)
 {
-    struct socket_data *s_data = s->resource_data;
-    u_long ok;
-    if (m == &s_data->mem_db)
-	return 0;
-    ok = inv_probe(m->next, s);
-    if (ok) {
-	if (m->base >= 0x100000)
-	    sub_interval(&s_data->mem_db, m->base, m->num);
-	return ok;
-    }
-    if (m->base < 0x100000)
-	return 0;
-    return do_mem_probe(m->base, m->num, s);
+	struct socket_data *s_data = s->resource_data;
+	u_long ok;
+	if (m == &s_data->mem_db)
+		return 0;
+	ok = inv_probe(m->next, s);
+	if (ok) {
+		if (m->base >= 0x100000)
+			sub_interval(&s_data->mem_db, m->base, m->num);
+		return ok;
+	}
+	if (m->base < 0x100000)
+		return 0;
+	return do_mem_probe(m->base, m->num, s);
 }
 
-static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
+static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 {
-    struct resource_map *m, mm;
-    static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
-    u_long b, i, ok = 0;
-    struct socket_data *s_data = s->resource_data;
+	struct resource_map *m, mm;
+	static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
+	unsigned long b, i, ok = 0;
+	struct socket_data *s_data = s->resource_data;
 
-    /* We do up to four passes through the list */
-    if (probe_mask & MEM_PROBE_HIGH) {
-	if (inv_probe(s_data->mem_db.next, s) > 0)
-	    return;
-	printk(KERN_NOTICE "cs: warning: no high memory space "
-	       "available!\n");
-    }
-    if ((probe_mask & MEM_PROBE_LOW) == 0)
-	return;
-    for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
-	mm = *m;
-	/* Only probe < 1 MB */
-	if (mm.base >= 0x100000) continue;
-	if ((mm.base | mm.num) & 0xffff) {
-	    ok += do_mem_probe(mm.base, mm.num, s);
-	    continue;
+	/* We do up to four passes through the list */
+	if (probe_mask & MEM_PROBE_HIGH) {
+		if (inv_probe(s_data->mem_db.next, s) > 0)
+			return 0;
+		printk(KERN_NOTICE "cs: warning: no high memory space "
+		       "available!\n");
+		return -ENODEV;
 	}
-	/* Special probe for 64K-aligned block */
-	for (i = 0; i < 4; i++) {
-	    b = order[i] << 12;
-	    if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
-		if (ok >= mem_limit)
-		    sub_interval(&s_data->mem_db, b, 0x10000);
-		else
-		    ok += do_mem_probe(b, 0x10000, s);
-	    }
+
+	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
+		mm = *m;
+		/* Only probe < 1 MB */
+		if (mm.base >= 0x100000)
+			continue;
+		if ((mm.base | mm.num) & 0xffff) {
+			ok += do_mem_probe(mm.base, mm.num, s);
+			continue;
+		}
+		/* Special probe for 64K-aligned block */
+		for (i = 0; i < 4; i++) {
+			b = order[i] << 12;
+			if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) {
+				if (ok >= mem_limit)
+					sub_interval(&s_data->mem_db, b, 0x10000);
+				else
+					ok += do_mem_probe(b, 0x10000, s);
+			}
+		}
 	}
-    }
+
+	if (ok > 0)
+		return 0;
+
+	return -ENODEV;
 }
 
 #else /* CONFIG_PCMCIA_PROBE */
 
-static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
+static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
 {
 	struct resource_map *m, mm;
 	struct socket_data *s_data = s->resource_data;
+	unsigned long ok = 0;
 
 	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {
 		mm = *m;
-		do_mem_probe(mm.base, mm.num, s);
+		ok += do_mem_probe(mm.base, mm.num, s);
 	}
+	if (ok > 0)
+		return 0;
+	return -ENODEV;
 }
 
 #endif /* CONFIG_PCMCIA_PROBE */
@@ -478,27 +486,30 @@
 /*
  * Locking note: Must be called with skt_sem held!
  */
-static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
+static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
 {
 	struct socket_data *s_data = s->resource_data;
-	if (probe_mem) {
-		unsigned int probe_mask;
+	unsigned int probe_mask = MEM_PROBE_LOW;
+	int ret = 0;
 
-		down(&rsrc_sem);
+	if (!probe_mem)
+		return 0;
 
-		probe_mask = MEM_PROBE_LOW;
-		if (s->features & SS_CAP_PAGE_REGS)
-			probe_mask = MEM_PROBE_HIGH;
+	down(&rsrc_sem);
 
-		if (probe_mask & ~s_data->rsrc_mem_probe) {
+	if (s->features & SS_CAP_PAGE_REGS)
+		probe_mask = MEM_PROBE_HIGH;
+
+	if (probe_mask & ~s_data->rsrc_mem_probe) {
+		if (s->state & SOCKET_PRESENT)
+			ret = validate_mem(s, probe_mask);
+		if (!ret)
 			s_data->rsrc_mem_probe |= probe_mask;
-
-			if (s->state & SOCKET_PRESENT)
-				validate_mem(s, probe_mask);
-		}
-
-		up(&rsrc_sem);
 	}
+
+	up(&rsrc_sem);
+
+	return ret;
 }
 
 struct pcmcia_align_data {
@@ -837,10 +848,9 @@
 {
 	struct socket_data *data;
 
-	data = kmalloc(sizeof(struct socket_data), GFP_KERNEL);
+	data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);
 	if (!data)
 		return -ENOMEM;
-	memset(data, 0, sizeof(struct socket_data));
 
 	data->mem_db.next = &data->mem_db;
 	data->io_db.next = &data->io_db;
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 9e7ccd8..ea7d9ca 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -297,25 +297,6 @@
 
 
 /*
- * Implements the get_socket() operation for the in-kernel PCMCIA
- * service (formerly SS_GetSocket in Card Services). Not a very
- * exciting routine.
- *
- * Returns: 0
- */
-static int
-soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock);
-
-	debug(skt, 2, "\n");
-
-	*state = skt->cs_state;
-
-	return 0;
-}
-
-/*
  * Implements the set_socket() operation for the in-kernel PCMCIA
  * service (formerly SS_SetSocket in Card Services). We more or
  * less punt all of this work and let the kernel handle the details
@@ -528,7 +509,6 @@
 	.init			= soc_common_pcmcia_sock_init,
 	.suspend		= soc_common_pcmcia_suspend,
 	.get_status		= soc_common_pcmcia_get_status,
-	.get_socket		= soc_common_pcmcia_get_socket,
 	.set_socket		= soc_common_pcmcia_set_socket,
 	.set_io_map		= soc_common_pcmcia_set_io_map,
 	.set_mem_map		= soc_common_pcmcia_set_mem_map,
@@ -665,13 +645,12 @@
 
 	down(&soc_pcmcia_sockets_lock);
 
-	sinfo = kmalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
+	sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
 	if (!sinfo) {
 		ret = -ENOMEM;
 		goto out;
 	}
 
-	memset(sinfo, 0, SKT_DEV_INFO_SIZE(nr));
 	sinfo->nskt = nr;
 
 	/*
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 4a3150a..7a77446 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -42,35 +42,28 @@
 
 static ssize_t pccard_show_type(struct class_device *dev, char *buf)
 {
-	int val;
 	struct pcmcia_socket *s = to_socket(dev);
 
 	if (!(s->state & SOCKET_PRESENT))
 		return -ENODEV;
-	s->ops->get_status(s, &val);
-	if (val & SS_CARDBUS)
+	if (s->state & SOCKET_CARDBUS)
 		return sprintf(buf, "32-bit\n");
-	if (val & SS_DETECT)
-		return sprintf(buf, "16-bit\n");
-	return sprintf(buf, "invalid\n");
+	return sprintf(buf, "16-bit\n");
 }
-static CLASS_DEVICE_ATTR(card_type, 0400, pccard_show_type, NULL);
+static CLASS_DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);
 
 static ssize_t pccard_show_voltage(struct class_device *dev, char *buf)
 {
-	int val;
 	struct pcmcia_socket *s = to_socket(dev);
 
 	if (!(s->state & SOCKET_PRESENT))
 		return -ENODEV;
-	s->ops->get_status(s, &val);
-	if (val & SS_3VCARD)
-		return sprintf(buf, "3.3V\n");
-	if (val & SS_XVCARD)
-		return sprintf(buf, "X.XV\n");
-	return sprintf(buf, "5.0V\n");
+	if (s->socket.Vcc)
+		return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10,
+			       s->socket.Vcc % 10);
+	return sprintf(buf, "X.XV\n");
 }
-static CLASS_DEVICE_ATTR(card_voltage, 0400, pccard_show_voltage, NULL);
+static CLASS_DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);
 
 static ssize_t pccard_show_vpp(struct class_device *dev, char *buf)
 {
@@ -79,7 +72,7 @@
 		return -ENODEV;
 	return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10);
 }
-static CLASS_DEVICE_ATTR(card_vpp, 0400, pccard_show_vpp, NULL);
+static CLASS_DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);
 
 static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)
 {
@@ -88,7 +81,7 @@
 		return -ENODEV;
 	return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10);
 }
-static CLASS_DEVICE_ATTR(card_vcc, 0400, pccard_show_vcc, NULL);
+static CLASS_DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);
 
 
 static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count)
@@ -292,10 +285,9 @@
 	if (!(s->state & SOCKET_PRESENT))
 		return -ENODEV;
 
-	cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL);
+	cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);
 	if (!cis)
 		return -ENOMEM;
-	memset(cis, 0, sizeof(cisdump_t));
 
 	cis->Length = count + 1;
 	memcpy(cis->Data, buf, count);
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index e312638..73bad1d 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -181,13 +181,6 @@
     outw(data >> 16, tcic_base+reg+2);
 }
 
-static u_char tcic_aux_getb(u_short reg)
-{
-    u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
-    tcic_setb(TCIC_MODE, mode);
-    return tcic_getb(TCIC_AUX);
-}
-
 static void tcic_aux_setb(u_short reg, u_char data)
 {
     u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg;
@@ -641,59 +634,6 @@
     debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
     return 0;
 } /* tcic_get_status */
-  
-/*====================================================================*/
-
-static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-    u_short psock = container_of(sock, struct tcic_socket, socket)->psock;
-    u_char reg;
-    u_short scf1, scf2;
-    
-    tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT)
-	      | TCIC_ADDR_INDREG | TCIC_SCF1(psock));
-    scf1 = tcic_getw(TCIC_DATA);
-    state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0;
-    state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0;
-    state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0;
-    if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA)
-	state->flags |= SS_OUTPUT_ENA;
-    state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK;
-    if (state->io_irq == 1) state->io_irq = 11;
-
-    reg = tcic_getb(TCIC_PWR);
-    state->Vcc = state->Vpp = 0;
-    if (reg & TCIC_PWR_VCC(psock)) {
-	if (reg & TCIC_PWR_VPP(psock))
-	    state->Vcc = 50;
-	else
-	    state->Vcc = state->Vpp = 50;
-    } else {
-	if (reg & TCIC_PWR_VPP(psock)) {
-	    state->Vcc = 50;
-	    state->Vpp = 120;
-	}
-    }
-    reg = tcic_aux_getb(TCIC_AUX_ILOCK);
-    state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0;
-
-    /* Card status change interrupt mask */
-    tcic_setw(TCIC_ADDR, TCIC_SCF2(psock));
-    scf2 = tcic_getw(TCIC_DATA);
-    state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT;
-    if (state->flags & SS_IOCARD) {
-	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG;
-    } else {
-	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD;
-	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN;
-	state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY;
-    }
-
-    debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
-	  "io_irq %d, csc_mask %#2.2x\n", psock, state->flags,
-	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-    return 0;
-} /* tcic_get_socket */
 
 /*====================================================================*/
 
@@ -874,7 +814,6 @@
 static struct pccard_operations tcic_operations = {
 	.init		   = tcic_init,
 	.get_status	   = tcic_get_status,
-	.get_socket	   = tcic_get_socket,
 	.set_socket	   = tcic_set_socket,
 	.set_io_map	   = tcic_set_io_map,
 	.set_mem_map	   = tcic_set_mem_map,
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index 539b5cd..d5b4ff7 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -873,7 +873,7 @@
  * Some fixup code to make everybody happy (TM).
  */
 
-#ifdef CONFIG_CARDBUS
+#ifdef CONFIG_YENTA_ENE_TUNE
 /**
  * set/clear various test bits:
  * Defaults to clear the bit.
@@ -937,7 +937,7 @@
 }
 #else
 #  define ene_override ti1250_override
-#endif
+#endif /* !CONFIG_YENTA_ENE_TUNE */
 
 #endif /* _LINUX_TI113X_H */
 
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 38a028c..24c547e 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -301,75 +301,6 @@
 	return 0;
 }
 
-static inline u_char get_Vcc_value(uint8_t voltage)
-{
-	switch (voltage) {
-	case VCC_STATUS_3V:
-		return 33;
-	case VCC_STATUS_5V:
-		return 50;
-	default:
-		break;
-	}
-
-	return 0;
-}
-
-static inline u_char get_Vpp_value(uint8_t power, u_char Vcc)
-{
-	if ((power & 0x03) == 0x01 || (power & 0x03) == 0x02)
-		return Vcc;
-
-	return 0;
-}
-
-static int pccard_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	unsigned int slot;
-	uint8_t power, voltage, control, cscint;
-
-	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || state == NULL)
-		return -EINVAL;
-
-	slot = sock->sock;
-
-	power = exca_read_byte(slot, I365_POWER);
-	voltage = exca_read_byte(slot, CARD_VOLTAGE_SELECT);
-
-	state->Vcc = get_Vcc_value(voltage);
-	state->Vpp = get_Vpp_value(power, state->Vcc);
-
-	state->flags = 0;
-	if (power & POWER_ENABLE)
-		state->flags |= SS_PWR_AUTO;
-	if (power & I365_PWR_OUT)
-		state->flags |= SS_OUTPUT_ENA;
-
-	control = exca_read_byte(slot, I365_INTCTL);
-	if (control & I365_PC_IOCARD)
-		state->flags |= SS_IOCARD;
-	if (!(control & I365_PC_RESET))
-		state->flags |= SS_RESET;
-
-        cscint = exca_read_byte(slot, I365_CSCINT);
-	state->csc_mask = 0;
-	if (state->flags & SS_IOCARD) {
-		if (cscint & I365_CSC_STSCHG)
-			state->flags |= SS_STSCHG;
-	} else {
-		if (cscint & I365_CSC_BVD1)
-			state->csc_mask |= SS_BATDEAD;
-		if (cscint & I365_CSC_BVD2)
-			state->csc_mask |= SS_BATWARN;
-	}
-	if (cscint & I365_CSC_READY)
-		state->csc_mask |= SS_READY;
-	if (cscint & I365_CSC_DETECT)
-		state->csc_mask |= SS_DETECT;
-
-	return 0;
-}
-
 static inline uint8_t set_Vcc_value(u_char Vcc)
 {
 	switch (Vcc) {
@@ -551,7 +482,6 @@
 static struct pccard_operations vrc4171_pccard_operations = {
 	.init			= pccard_init,
 	.get_status		= pccard_get_status,
-	.get_socket		= pccard_get_socket,
 	.set_socket		= pccard_set_socket,
 	.set_io_map		= pccard_set_io_map,
 	.set_mem_map		= pccard_set_mem_map,
diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c
index db91259..1b277d2 100644
--- a/drivers/pcmcia/vrc4173_cardu.c
+++ b/drivers/pcmcia/vrc4173_cardu.c
@@ -198,48 +198,6 @@
 	return 0;
 }
 
-static inline u_char get_Vcc_value(uint8_t val)
-{
-	switch (val & VCC_MASK) {
-	case VCC_3V:
-		return 33;
-	case VCC_5V:
-		return 50;
-	}
-
-	return 0;
-}
-
-static inline u_char get_Vpp_value(uint8_t val)
-{
-	switch (val & VPP_MASK) {
-	case VPP_12V:
-		return 120;
-	case VPP_VCC:
-		return get_Vcc_value(val);
-	}
-
-	return 0;
-}
-
-static int cardu_get_socket(unsigned int sock, socket_state_t *state)
-{
-	vrc4173_socket_t *socket = &cardu_sockets[sock];
-	uint8_t val;
-
-	val = exca_readb(socket, PWR_CNT);
-	state->Vcc = get_Vcc_value(val);
-	state->Vpp = get_Vpp_value(val);
-	state->flags = 0;
-	if (val & CARD_OUT_EN) state->flags |= SS_OUTPUT_ENA;
-
-	val = exca_readb(socket, INT_GEN_CNT);
-	if (!(val & CARD_REST0)) state->flags |= SS_RESET;
-	if (val & CARD_TYPE_IO) state->flags |= SS_IOCARD;
-
-	return 0;
-}
-
 static inline uint8_t set_Vcc_value(u_char Vcc)
 {
 	switch (Vcc) {
@@ -431,7 +389,6 @@
 	.register_callback	= cardu_register_callback,
 	.inquire_socket		= cardu_inquire_socket,
 	.get_status		= cardu_get_status,
-	.get_socket		= cardu_get_socket,
 	.set_socket		= cardu_set_socket,
 	.get_io_map		= cardu_get_io_map,
 	.set_io_map		= cardu_set_io_map,
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index ec6ab65..4145eb8 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -49,7 +49,13 @@
 #define to_cycles(ns)	((ns)/120)
 #define to_ns(cycles)	((cycles)*120)
 
+/**
+ * yenta PCI irq probing.
+ * currently only used in the TI/EnE initialization code
+ */
+#ifdef CONFIG_YENTA_TI
 static int yenta_probe_cb_irq(struct yenta_socket *socket);
+#endif
 
 
 static unsigned int override_bios;
@@ -224,95 +230,6 @@
 	return 0;
 }
 
-static void yenta_get_power(struct yenta_socket *socket, socket_state_t *state)
-{
-	if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) &&
-	    (socket->flags & YENTA_16BIT_POWER_EXCA)) {
-		u8 reg, vcc, vpp;
-
-		reg = exca_readb(socket, I365_POWER);
-		vcc = reg & I365_VCC_MASK;
-		vpp = reg & I365_VPP1_MASK;
-		state->Vcc = state->Vpp = 0;
-
-		if (socket->flags & YENTA_16BIT_POWER_DF) {
-			if (vcc == I365_VCC_3V)
-				state->Vcc = 33;
-			if (vcc == I365_VCC_5V)
-				state->Vcc = 50;
-			if (vpp == I365_VPP1_5V)
-				state->Vpp = state->Vcc;
-			if (vpp == I365_VPP1_12V)
-				state->Vpp = 120;
-		} else {
-			if (reg & I365_VCC_5V) {
-				state->Vcc = 50;
-				if (vpp == I365_VPP1_5V)
-					state->Vpp = 50;
-				if (vpp == I365_VPP1_12V)
-					state->Vpp = 120;
-			}
-		}
-	} else {
-		u32 control;
-
-		control = cb_readl(socket, CB_SOCKET_CONTROL);
-
-		switch (control & CB_SC_VCC_MASK) {
-		case CB_SC_VCC_5V: state->Vcc = 50; break;
-		case CB_SC_VCC_3V: state->Vcc = 33; break;
-		default: state->Vcc = 0;
-		}
-
-		switch (control & CB_SC_VPP_MASK) {
-		case CB_SC_VPP_12V: state->Vpp = 120; break;
-		case CB_SC_VPP_5V: state->Vpp = 50; break;
-		case CB_SC_VPP_3V: state->Vpp = 33; break;
-		default: state->Vpp = 0;
-		}
-	}
-}
-
-static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	u8 reg;
-	u32 control;
-
-	control = cb_readl(socket, CB_SOCKET_CONTROL);
-
-	yenta_get_power(socket, state);
-	state->io_irq = socket->io_irq;
-
-	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
-		u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL);
-		if (bridge & CB_BRIDGE_CRST)
-			state->flags |= SS_RESET;
-		return 0;
-	}
-
-	/* 16-bit card state.. */
-	reg = exca_readb(socket, I365_POWER);
-	state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
-	state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
-
-	reg = exca_readb(socket, I365_INTCTL);
-	state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
-	state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0;
-
-	reg = exca_readb(socket, I365_CSCINT);
-	state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
-	if (state->flags & SS_IOCARD) {
-		state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
-	} else {
-		state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-		state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
-		state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
-	}
-
-	return 0;
-}
-
 static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)
 {
 	/* some birdges require to use the ExCA registers to power 16bit cards */
@@ -531,6 +448,9 @@
 
 	csc = exca_readb(socket, I365_CSC);
 
+	if (!(cb_event || csc))
+		return IRQ_NONE;
+
 	events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ;
 	events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
 	if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
@@ -544,10 +464,7 @@
 	if (events)
 		pcmcia_parse_events(&socket->socket, events);
 
-	if (cb_event || csc)
-		return IRQ_HANDLED;
-
-	return IRQ_NONE;
+	return IRQ_HANDLED;
 }
 
 static void yenta_interrupt_wrapper(unsigned long data)
@@ -828,17 +745,24 @@
 	.init			= yenta_sock_init,
 	.suspend		= yenta_sock_suspend,
 	.get_status		= yenta_get_status,
-	.get_socket		= yenta_get_socket,
 	.set_socket		= yenta_set_socket,
 	.set_io_map		= yenta_set_io_map,
 	.set_mem_map		= yenta_set_mem_map,
 };
 
 
+#ifdef CONFIG_YENTA_TI
 #include "ti113x.h"
+#endif
+#ifdef CONFIG_YENTA_RICOH
 #include "ricoh.h"
+#endif
+#ifdef CONFIG_YENTA_TOSHIBA
 #include "topic.h"
+#endif
+#ifdef CONFIG_YENTA_O2
 #include "o2micro.h"
+#endif
 
 enum {
 	CARDBUS_TYPE_DEFAULT = -1,
@@ -858,6 +782,7 @@
  * initialization sequences etc details. List them here..
  */
 static struct cardbus_type cardbus_type[] = {
+#ifdef CONFIG_YENTA_TI
 	[CARDBUS_TYPE_TI]	= {
 		.override	= ti_override,
 		.save_state	= ti_save_state,
@@ -882,27 +807,36 @@
 		.restore_state	= ti_restore_state,
 		.sock_init	= ti_init,
 	},
+#endif
+#ifdef CONFIG_YENTA_RICOH
 	[CARDBUS_TYPE_RICOH]	= {
 		.override	= ricoh_override,
 		.save_state	= ricoh_save_state,
 		.restore_state	= ricoh_restore_state,
 	},
+#endif
+#ifdef CONFIG_YENTA_TOSHIBA
 	[CARDBUS_TYPE_TOPIC95]	= {
 		.override	= topic95_override,
 	},
 	[CARDBUS_TYPE_TOPIC97]	= {
 		.override	= topic97_override,
 	},
+#endif
+#ifdef CONFIG_YENTA_O2
 	[CARDBUS_TYPE_O2MICRO]	= {
 		.override	= o2micro_override,
 		.restore_state	= o2micro_restore_state,
 	},
+#endif
+#ifdef CONFIG_YENTA_TI
 	[CARDBUS_TYPE_ENE]	= {
 		.override	= ene_override,
 		.save_state	= ti_save_state,
 		.restore_state	= ti_restore_state,
 		.sock_init	= ti_init,
 	},
+#endif
 };
 
 
@@ -948,6 +882,12 @@
 }
 
 
+/**
+ * yenta PCI irq probing.
+ * currently only used in the TI/EnE initialization code
+ */
+#ifdef CONFIG_YENTA_TI
+
 /* interrupt handler, only used during probing */
 static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -1000,6 +940,7 @@
 	return (int) socket->probe_status;
 }
 
+#endif /* CONFIG_YENTA_TI */
 
 
 /*
@@ -1078,10 +1019,9 @@
 		return -ENODEV;
 	}
 
-	socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
+	socket = kzalloc(sizeof(struct yenta_socket), GFP_KERNEL);
 	if (!socket)
 		return -ENOMEM;
-	memset(socket, 0, sizeof(*socket));
 
 	/* prepare pcmcia_socket */
 	socket->socket.ops = &yenta_socket_operations;
@@ -1263,6 +1203,7 @@
 	 * advanced overrides instead.  (I can't get the
 	 * data sheets for these devices. --rmk)
 	 */
+#ifdef CONFIG_YENTA_TI
 	CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI),
 
 	CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X),
@@ -1305,18 +1246,25 @@
 	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE),
 	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE),
 	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE),
+#endif /* CONFIG_YENTA_TI */
 
+#ifdef CONFIG_YENTA_RICOH
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH),
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH),
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH),
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH),
 	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH),
+#endif
 
+#ifdef CONFIG_YENTA_TOSHIBA
 	CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95),
 	CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97),
 	CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97),
+#endif
 
+#ifdef CONFIG_YENTA_O2
 	CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO),
+#endif
 
 	/* match any cardbus bridge */
 	CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c
index bd7c966..0ecbe4e 100644
--- a/drivers/pnp/card.c
+++ b/drivers/pnp/card.c
@@ -69,6 +69,7 @@
 			return 0;
 		clink->card = card;
 		clink->driver = drv;
+		clink->pm_state = PMSG_ON;
 		if (drv->probe) {
 			if (drv->probe(clink, id)>=0)
 				return 1;
@@ -333,6 +334,28 @@
 	up_write(&dev->dev.bus->subsys.rwsem);
 }
 
+/*
+ * suspend/resume callbacks
+ */
+static int card_suspend(struct pnp_dev *dev, pm_message_t state)
+{
+	struct pnp_card_link *link = dev->card_link;
+	if (link->pm_state.event == state.event)
+		return 0;
+	link->pm_state = state;
+	return link->driver->suspend(link, state);
+}
+
+static int card_resume(struct pnp_dev *dev)
+{
+	struct pnp_card_link *link = dev->card_link;
+	if (link->pm_state.event == PM_EVENT_ON)
+		return 0;
+	link->pm_state = PMSG_ON;
+	link->driver->resume(link);
+	return 0;
+}
+
 /**
  * pnp_register_card_driver - registers a PnP card driver with the PnP Layer
  * @drv: pointer to the driver to register
@@ -348,6 +371,8 @@
 	drv->link.flags = drv->flags;
 	drv->link.probe = NULL;
 	drv->link.remove = &card_remove_first;
+	drv->link.suspend = drv->suspend ? card_suspend : NULL;
+	drv->link.resume = drv->resume ? card_resume : NULL;
 
 	spin_lock(&pnp_lock);
 	list_add_tail(&drv->global_list, &pnp_card_drivers);
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index d3ccce7..15fb758 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -146,10 +146,57 @@
 	return 1;
 }
 
+static int pnp_bus_suspend(struct device *dev, pm_message_t state)
+{
+	struct pnp_dev * pnp_dev = to_pnp_dev(dev);
+	struct pnp_driver * pnp_drv = pnp_dev->driver;
+	int error;
+
+	if (!pnp_drv)
+		return 0;
+
+	if (pnp_drv->suspend) {
+		error = pnp_drv->suspend(pnp_dev, state);
+		if (error)
+			return error;
+	}
+
+	if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) &&
+	    pnp_can_disable(pnp_dev)) {
+	    	error = pnp_stop_dev(pnp_dev);
+	    	if (error)
+	    		return error;
+	}
+
+	return 0;
+}
+
+static int pnp_bus_resume(struct device *dev)
+{
+	struct pnp_dev * pnp_dev = to_pnp_dev(dev);
+	struct pnp_driver * pnp_drv = pnp_dev->driver;
+	int error;
+
+	if (!pnp_drv)
+		return 0;
+
+	if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) {
+		error = pnp_start_dev(pnp_dev);
+		if (error)
+			return error;
+	}
+
+	if (pnp_drv->resume)
+		return pnp_drv->resume(pnp_dev);
+
+	return 0;
+}
 
 struct bus_type pnp_bus_type = {
 	.name	= "pnp",
 	.match	= pnp_bus_match,
+	.suspend = pnp_bus_suspend,
+	.resume = pnp_bus_resume,
 };
 
 
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 2616686..c4256aa 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -470,23 +470,14 @@
 }
 
 /**
- * pnp_activate_dev - activates a PnP device for use
+ * pnp_start_dev - low-level start of the PnP device
  * @dev: pointer to the desired device
  *
- * does not validate or set resources so be careful.
+ * assumes that resources have alread been allocated
  */
-int pnp_activate_dev(struct pnp_dev *dev)
+
+int pnp_start_dev(struct pnp_dev *dev)
 {
-	if (!dev)
-		return -EINVAL;
-	if (dev->active) {
-		return 0; /* the device is already active */
-	}
-
-	/* ensure resources are allocated */
-	if (pnp_auto_config_dev(dev))
-		return -EBUSY;
-
 	if (!pnp_can_write(dev)) {
 		pnp_info("Device %s does not supported activation.", dev->dev.bus_id);
 		return -EINVAL;
@@ -497,9 +488,60 @@
 		return -EIO;
 	}
 
-	dev->active = 1;
 	pnp_info("Device %s activated.", dev->dev.bus_id);
 
+	return 0;
+}
+
+/**
+ * pnp_stop_dev - low-level disable of the PnP device
+ * @dev: pointer to the desired device
+ *
+ * does not free resources
+ */
+
+int pnp_stop_dev(struct pnp_dev *dev)
+{
+	if (!pnp_can_disable(dev)) {
+		pnp_info("Device %s does not supported disabling.", dev->dev.bus_id);
+		return -EINVAL;
+	}
+	if (dev->protocol->disable(dev)<0) {
+		pnp_err("Failed to disable device %s.", dev->dev.bus_id);
+		return -EIO;
+	}
+
+	pnp_info("Device %s disabled.", dev->dev.bus_id);
+
+	return 0;
+}
+
+/**
+ * pnp_activate_dev - activates a PnP device for use
+ * @dev: pointer to the desired device
+ *
+ * does not validate or set resources so be careful.
+ */
+int pnp_activate_dev(struct pnp_dev *dev)
+{
+	int error;
+
+	if (!dev)
+		return -EINVAL;
+	if (dev->active) {
+		return 0; /* the device is already active */
+	}
+
+	/* ensure resources are allocated */
+	if (pnp_auto_config_dev(dev))
+		return -EBUSY;
+
+	error = pnp_start_dev(dev);
+	if (error)
+		return error;
+
+	dev->active = 1;
+
 	return 1;
 }
 
@@ -511,23 +553,19 @@
  */
 int pnp_disable_dev(struct pnp_dev *dev)
 {
+	int error;
+
         if (!dev)
                 return -EINVAL;
 	if (!dev->active) {
 		return 0; /* the device is already disabled */
 	}
 
-	if (!pnp_can_disable(dev)) {
-		pnp_info("Device %s does not supported disabling.", dev->dev.bus_id);
-		return -EINVAL;
-	}
-	if (dev->protocol->disable(dev)<0) {
-		pnp_err("Failed to disable device %s.", dev->dev.bus_id);
-		return -EIO;
-	}
+	error = pnp_stop_dev(dev);
+	if (error)
+		return error;
 
 	dev->active = 0;
-	pnp_info("Device %s disabled.", dev->dev.bus_id);
 
 	/* release the resources so that other devices can use them */
 	down(&pnp_res_mutex);
@@ -558,6 +596,8 @@
 #if 0
 EXPORT_SYMBOL(pnp_auto_config_dev);
 #endif
+EXPORT_SYMBOL(pnp_start_dev);
+EXPORT_SYMBOL(pnp_stop_dev);
 EXPORT_SYMBOL(pnp_activate_dev);
 EXPORT_SYMBOL(pnp_disable_dev);
 EXPORT_SYMBOL(pnp_resource_change);
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
index 6b7583f..a1f0b0b 100644
--- a/drivers/pnp/pnpbios/bioscalls.c
+++ b/drivers/pnp/pnpbios/bioscalls.c
@@ -31,15 +31,6 @@
 } pnp_bios_callpoint;
 
 
-/* The PnP BIOS entries in the GDT */
-#define PNP_GDT    (GDT_ENTRY_PNPBIOS_BASE * 8)
-
-#define PNP_CS32   (PNP_GDT+0x00)	/* segment for calling fn */
-#define PNP_CS16   (PNP_GDT+0x08)	/* code segment for BIOS */
-#define PNP_DS     (PNP_GDT+0x10)	/* data segment for BIOS */
-#define PNP_TS1    (PNP_GDT+0x18)	/* transfer data segment */
-#define PNP_TS2    (PNP_GDT+0x20)	/* another data segment */
-
 /*
  * These are some opcodes for a "static asmlinkage"
  * As this code is *not* executed inside the linux kernel segment, but in a
@@ -67,16 +58,11 @@
 	".previous		\n"
 );
 
-#define Q_SET_SEL(cpu, selname, address, size) \
-do { \
-set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], __va((u32)(address))); \
-set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \
-} while(0)
-
 #define Q2_SET_SEL(cpu, selname, address, size) \
 do { \
-set_base(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], (u32)(address)); \
-set_limit(per_cpu(cpu_gdt_table,cpu)[(selname) >> 3], size); \
+struct desc_struct *gdt = get_cpu_gdt_table((cpu)); \
+set_base(gdt[(selname) >> 3], (u32)(address)); \
+set_limit(gdt[(selname) >> 3], size); \
 } while(0)
 
 static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
@@ -115,8 +101,8 @@
 		return PNP_FUNCTION_NOT_SUPPORTED;
 
 	cpu = get_cpu();
-	save_desc_40 = per_cpu(cpu_gdt_table,cpu)[0x40 / 8];
-	per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = bad_bios_desc;
+	save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
+	get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
 
 	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
 	spin_lock_irqsave(&pnp_bios_lock, flags);
@@ -158,7 +144,7 @@
 	);
 	spin_unlock_irqrestore(&pnp_bios_lock, flags);
 
-	per_cpu(cpu_gdt_table,cpu)[0x40 / 8] = save_desc_40;
+	get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
 	put_cpu();
 
 	/* If we get here and this is set then the PnP BIOS faulted on us. */
@@ -290,12 +276,15 @@
 static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
 {
 	u16 status;
+	u16 tmp_nodenum;
 	if (!pnp_bios_present())
 		return PNP_FUNCTION_NOT_SUPPORTED;
 	if ( !boot && pnpbios_dont_use_current_config )
 		return PNP_FUNCTION_NOT_SUPPORTED;
+	tmp_nodenum = *nodenum;
 	status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0,
-			       nodenum, sizeof(char), data, 65536);
+			       &tmp_nodenum, sizeof(tmp_nodenum), data, 65536);
+	*nodenum = tmp_nodenum;
 	return status;
 }
 
@@ -535,10 +524,12 @@
 
 	set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
 	_set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
-	for(i=0; i < NR_CPUS; i++)
-	{
-		Q2_SET_SEL(i, PNP_CS32, &pnp_bios_callfunc, 64 * 1024);
-		Q_SET_SEL(i, PNP_CS16, header->fields.pm16cseg, 64 * 1024);
-		Q_SET_SEL(i, PNP_DS, header->fields.pm16dseg, 64 * 1024);
-	}
+ 	for (i = 0; i < NR_CPUS; i++) {
+  		struct desc_struct *gdt = get_cpu_gdt_table(i);
+  		if (!gdt)
+  			continue;
+ 		set_base(gdt[GDT_ENTRY_PNPBIOS_CS32], &pnp_bios_callfunc);
+ 		set_base(gdt[GDT_ENTRY_PNPBIOS_CS16], __va(header->fields.pm16cseg));
+ 		set_base(gdt[GDT_ENTRY_PNPBIOS_DS], __va(header->fields.pm16dseg));
+  	}
 }
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index f49674f..b154b3f 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -56,7 +56,6 @@
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/slab.h>
-#include <linux/kobject_uevent.h>
 #include <linux/completion.h>
 #include <linux/spinlock.h>
 #include <linux/dmi.h>
@@ -106,8 +105,6 @@
 	char *argv [3], **envp, *buf, *scratch;
 	int i = 0, value;
 
-	if (!hotplug_path [0])
-		return -ENOENT;
 	if (!current->fs->root) {
 		return -EAGAIN;
 	}
@@ -119,8 +116,9 @@
 		return -ENOMEM;
 	}
 
-	/* only one standardized param to hotplug command: type */
-	argv [0] = hotplug_path;
+	/* FIXME: if there are actual users of this, it should be integrated into
+	 * the driver core and use the usual infrastructure like sysfs and uevents */
+	argv [0] = "/sbin/pnpbios";
 	argv [1] = "dock";
 	argv [2] = NULL;
 
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 4f7ed4b..94e30fe 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -24,6 +24,8 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
 
 #include "rio.h"
 
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
index 30a1143..bef9316 100644
--- a/drivers/rapidio/rio-sysfs.c
+++ b/drivers/rapidio/rio-sysfs.c
@@ -15,6 +15,7 @@
 #include <linux/rio.h>
 #include <linux/rio_drv.h>
 #include <linux/stat.h>
+#include <linux/sched.h>	/* for capable() */
 
 #include "rio.h"
 
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 3ca1011..5e38247 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -23,6 +23,7 @@
 #include <linux/rio_regs.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
+#include <linux/slab.h>
 
 #include "rio.h"
 
diff --git a/drivers/s390/Makefile b/drivers/s390/Makefile
index c99a2fe..9803c93 100644
--- a/drivers/s390/Makefile
+++ b/drivers/s390/Makefile
@@ -2,7 +2,7 @@
 # Makefile for the S/390 specific device drivers
 #
 
-obj-y += s390mach.o sysinfo.o
+obj-y += s390mach.o sysinfo.o s390_rdev.o
 obj-y += cio/ block/ char/ crypto/ net/ scsi/
 
 drivers-y += drivers/s390/built-in.o
diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig
index 6e7d7b0..6f50cc9 100644
--- a/drivers/s390/block/Kconfig
+++ b/drivers/s390/block/Kconfig
@@ -1,11 +1,11 @@
-if ARCH_S390
+if S390
 
 comment "S/390 block device drivers"
-	depends on ARCH_S390
+	depends on S390
 
 config BLK_DEV_XPRAM
 	tristate "XPRAM disk support"
-	depends on ARCH_S390
+	depends on S390
 	help
 	  Select this option if you want to use your expanded storage on S/390
 	  or zSeries as a disk.  This is useful as a _fast_ swap device if you
@@ -49,7 +49,7 @@
 
 config DASD_DIAG
 	tristate "Support for DIAG access to Disks"
-	depends on DASD && ( ARCH_S390X = 'n' || EXPERIMENTAL)
+	depends on DASD && ( 64BIT = 'n' || EXPERIMENTAL)
 	help
 	  Select this option if you want to use Diagnose250 command to access
 	  Disks under VM.  If you are not running under VM or unsure what it is,
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 7008d32..2472fa1 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.167 $
+ * $Revision: 1.172 $
  */
 
 #include <linux/config.h>
@@ -18,6 +18,7 @@
 #include <linux/major.h>
 #include <linux/slab.h>
 #include <linux/buffer_head.h>
+#include <linux/hdreg.h>
 
 #include <asm/ccwdev.h>
 #include <asm/ebcdic.h>
@@ -604,7 +605,7 @@
 void
 dasd_kfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device)
 {
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 	struct ccw1 *ccw;
 
 	/* Clear any idals used for the request. */
@@ -1035,7 +1036,7 @@
 	if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
 		BUG();
 	add_disk_randomness(req->rq_disk);
-	end_that_request_last(req);
+	end_that_request_last(req, uptodate);
 }
 
 /*
@@ -1224,6 +1225,12 @@
 	if (list_empty(&device->ccw_queue))
 		return;
 	cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
+        /* check FAILFAST */
+	if (device->stopped & ~DASD_STOPPED_PENDING &&
+	    test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) {
+		cqr->status = DASD_CQR_FAILED;
+		dasd_schedule_bh(device);
+	}
 	if ((cqr->status == DASD_CQR_QUEUED) &&
 	    (!device->stopped)) {
 		/* try to start the first I/O that can be started */
@@ -1323,7 +1330,7 @@
 dasd_schedule_bh(struct dasd_device * device)
 {
 	/* Protect against rescheduling. */
-	if (atomic_compare_and_swap (0, 1, &device->tasklet_scheduled))
+	if (atomic_cmpxchg (&device->tasklet_scheduled, 0, 1) != 0)
 		return;
 	dasd_get_device(device);
 	tasklet_hi_schedule(&device->tasklet);
@@ -1717,12 +1724,34 @@
 	return 0;
 }
 
+/*
+ * Return disk geometry.
+ */
+static int
+dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+	struct dasd_device *device;
+
+	device = bdev->bd_disk->private_data;
+	if (!device)
+		return -ENODEV;
+
+	if (!device->discipline ||
+	    !device->discipline->fill_geometry)
+		return -EINVAL;
+
+	device->discipline->fill_geometry(device, geo);
+	geo->start = get_start_sect(bdev) >> device->s2b_shift;
+	return 0;
+}
+
 struct block_device_operations
 dasd_device_operations = {
 	.owner		= THIS_MODULE,
 	.open		= dasd_open,
 	.release	= dasd_release,
 	.ioctl		= dasd_ioctl,
+	.getgeo		= dasd_getgeo,
 };
 
 
@@ -1750,8 +1779,10 @@
  * SECTION: common functions for ccw_driver use
  */
 
-/* initial attempt at a probe function. this can be simplified once
- * the other detection code is gone */
+/*
+ * Initial attempt at a probe function. this can be simplified once
+ * the other detection code is gone.
+ */
 int
 dasd_generic_probe (struct ccw_device *cdev,
 		    struct dasd_discipline *discipline)
@@ -1770,8 +1801,10 @@
 	return ret;
 }
 
-/* this will one day be called from a global not_oper handler.
- * It is also used by driver_unregister during module unload */
+/*
+ * This will one day be called from a global not_oper handler.
+ * It is also used by driver_unregister during module unload.
+ */
 void
 dasd_generic_remove (struct ccw_device *cdev)
 {
@@ -1798,9 +1831,11 @@
 	dasd_delete_device(device);
 }
 
-/* activate a device. This is called from dasd_{eckd,fba}_probe() when either
+/*
+ * Activate a device. This is called from dasd_{eckd,fba}_probe() when either
  * the device is detected for the first time and is supposed to be used
- * or the user has started activation through sysfs */
+ * or the user has started activation through sysfs.
+ */
 int
 dasd_generic_set_online (struct ccw_device *cdev,
 			 struct dasd_discipline *discipline)
@@ -1917,7 +1952,6 @@
 				if (cqr->status == DASD_CQR_IN_IO)
 					cqr->status = DASD_CQR_FAILED;
 			device->stopped |= DASD_STOPPED_DC_EIO;
-			dasd_schedule_bh(device);
 		} else {
 			list_for_each_entry(cqr, &device->ccw_queue, list)
 				if (cqr->status == DASD_CQR_IN_IO) {
@@ -1927,6 +1961,7 @@
 			device->stopped |= DASD_STOPPED_DC_WAIT;
 			dasd_set_timer(device, 0);
 		}
+		dasd_schedule_bh(device);
 		ret = 1;
 		break;
 	case CIO_OPER:
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index ab8754e..ba80fde 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.51 $
+ * $Revision: 1.53 $
  */
 
 #include <linux/config.h>
@@ -25,6 +25,7 @@
 #include <asm/io.h>
 #include <asm/s390_ext.h>
 #include <asm/todclk.h>
+#include <asm/vtoc.h>
 
 #include "dasd_int.h"
 #include "dasd_diag.h"
@@ -74,7 +75,7 @@
 	int rc;
 
 	__asm__ __volatile__(
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 		"	lghi	%0,3\n"
 		"	lgr	0,%3\n"
 		"	diag	0,%2,0x250\n"
@@ -329,7 +330,7 @@
 	struct dasd_diag_private *private;
 	struct dasd_diag_characteristics *rdc_data;
 	struct dasd_diag_bio bio;
-	struct dasd_diag_cms_label *label;
+	struct vtoc_cms_label *label;
 	blocknum_t end_block;
 	unsigned int sb, bsize;
 	int rc;
@@ -380,7 +381,7 @@
 	mdsk_term_io(device);
 
 	/* figure out blocksize of device */
-	label = (struct dasd_diag_cms_label *) get_zeroed_page(GFP_KERNEL);
+	label = (struct vtoc_cms_label *) get_zeroed_page(GFP_KERNEL);
 	if (label == NULL)  {
 		DEV_MESSAGE(KERN_WARNING, device, "%s",
 			    "No memory to allocate initialization request");
@@ -548,6 +549,8 @@
 	}
 	cqr->retries = DIAG_MAX_RETRIES;
 	cqr->buildclk = get_clock();
+	if (req->flags & REQ_FAILFAST)
+		set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
 	cqr->device = device;
 	cqr->expires = DIAG_TIMEOUT;
 	cqr->status = DASD_CQR_FILLED;
diff --git a/drivers/s390/block/dasd_diag.h b/drivers/s390/block/dasd_diag.h
index df31484..a4f80bd 100644
--- a/drivers/s390/block/dasd_diag.h
+++ b/drivers/s390/block/dasd_diag.h
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.8 $
+ * $Revision: 1.9 $
  */
 
 #define MDSK_WRITE_REQ 0x01
@@ -44,29 +44,8 @@
 	u8 rdev_features;
 } __attribute__ ((packed, aligned(4)));
 
-struct dasd_diag_cms_label {
-	u8 label_id[4];
-	u8 vol_id[6];
-	u16 version_id;
-	u32 block_size;
-	u32 origin_ptr;
-	u32 usable_count;
-	u32 formatted_count;
-	u32 block_count;
-	u32 used_count;
-	u32 fst_size;
-	u32 fst_count;
-	u8 format_date[6];
-	u8 reserved1[2];
-	u32 disk_offset;
-	u32 map_block;
-	u32 hblk_disp;
-	u32 user_disp;
-	u8 reserved2[4];
-	u8 segment_name[8];
-} __attribute__ ((packed));
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 #define DASD_DIAG_FLAGA_DEFAULT		DASD_DIAG_FLAGA_FORMAT_64BIT
 
 typedef u64 blocknum_t;
@@ -107,7 +86,7 @@
 	struct dasd_diag_bio *bio_list;
 	u8  spare4[8];
 } __attribute__ ((packed, aligned(8)));
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 #define DASD_DIAG_FLAGA_DEFAULT		0x0
 
 typedef u32 blocknum_t;
@@ -146,4 +125,4 @@
 	u32 interrupt_params;
 	u8 spare3[20];
 } __attribute__ ((packed, aligned(8)));
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 811060e..96eb482 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.71 $
+ * $Revision: 1.74 $
  */
 
 #include <linux/config.h>
@@ -1041,7 +1041,7 @@
 				/* Eckd can only do full blocks. */
 				return ERR_PTR(-EINVAL);
 			count += bv->bv_len >> (device->s2b_shift + 9);
-#if defined(CONFIG_ARCH_S390X)
+#if defined(CONFIG_64BIT)
 			if (idal_is_needed (page_address(bv->bv_page),
 					    bv->bv_len))
 				cidaw += bv->bv_len >> (device->s2b_shift + 9);
@@ -1136,6 +1136,8 @@
 			recid++;
 		}
 	}
+	if (req->flags & REQ_FAILFAST)
+		set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
 	cqr->device = device;
 	cqr->expires = 5 * 60 * HZ;	/* 5 minutes */
 	cqr->lpm = private->path_data.ppm;
@@ -1252,6 +1254,7 @@
 	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
 	cqr->device = device;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
+	set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
 	cqr->retries = 0;
 	cqr->expires = 2 * HZ;
 	cqr->buildclk = get_clock();
@@ -1296,6 +1299,7 @@
 	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
 	cqr->device = device;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
+	set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
 	cqr->retries = 0;
 	cqr->expires = 2 * HZ;
 	cqr->buildclk = get_clock();
@@ -1339,6 +1343,7 @@
 	cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
 	cqr->device = device;
 	clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
+	set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
 	cqr->retries = 0;
 	cqr->expires = 2 * HZ;
 	cqr->buildclk = get_clock();
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 28cb461..8ec75dc 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -4,7 +4,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.40 $
+ * $Revision: 1.41 $
  */
 
 #include <linux/config.h>
@@ -271,7 +271,7 @@
 				/* Fba can only do full blocks. */
 				return ERR_PTR(-EINVAL);
 			count += bv->bv_len >> (device->s2b_shift + 9);
-#if defined(CONFIG_ARCH_S390X)
+#if defined(CONFIG_64BIT)
 			if (idal_is_needed (page_address(bv->bv_page),
 					    bv->bv_len))
 				cidaw += bv->bv_len / blksize;
@@ -352,6 +352,8 @@
 			recid++;
 		}
 	}
+	if (req->flags & REQ_FAILFAST)
+		set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
 	cqr->device = device;
 	cqr->expires = 5 * 60 * HZ;	/* 5 minutes */
 	cqr->retries = 32;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 9fab04f..2fb05c4 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.65 $
+ * $Revision: 1.68 $
  */
 
 #ifndef DASD_INT_H
@@ -208,6 +208,7 @@
 
 /* per dasd_ccw_req flags */
 #define DASD_CQR_FLAGS_USE_ERP   0	/* use ERP for this request */
+#define DASD_CQR_FLAGS_FAILFAST  1	/* FAILFAST */
 
 /* Signature for error recovery functions. */
 typedef struct dasd_ccw_req *(*dasd_erp_fn_t) (struct dasd_ccw_req *);
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 789595b..8e4dcd5 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
  *
- * $Revision: 1.47 $
+ * $Revision: 1.50 $
  *
  * i/o controls for the dasd driver.
  */
@@ -352,6 +352,9 @@
 	if (device == NULL)
 		return -ENODEV;
 
+	if (dasd_profile_level == DASD_PROFILE_OFF)
+		return -EIO;
+
 	if (copy_to_user((long __user *) args, (long *) &device->profile,
 			 sizeof (struct dasd_profile_info_t)))
 		return -EFAULT;
@@ -483,33 +486,6 @@
 }
 
 /*
- * Return disk geometry.
- */
-static int
-dasd_ioctl_getgeo(struct block_device *bdev, int no, long args)
-{
-	struct hd_geometry geo = { 0, };
-	struct dasd_device *device;
-
-	device =  bdev->bd_disk->private_data;
-	if (device == NULL)
-		return -ENODEV;
-
-	if (device == NULL || device->discipline == NULL ||
-	    device->discipline->fill_geometry == NULL)
-		return -EINVAL;
-
-	geo = (struct hd_geometry) {};
-	device->discipline->fill_geometry(device, &geo);
-	geo.start = get_start_sect(bdev) >> device->s2b_shift;
-	if (copy_to_user((struct hd_geometry __user *) args, &geo,
-			 sizeof (struct hd_geometry)))
-		return -EFAULT;
-
-	return 0;
-}
-
-/*
  * List of static ioctls.
  */
 static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] =
@@ -525,7 +501,6 @@
 	{ BIODASDPRRST, dasd_ioctl_reset_profile },
 	{ BLKROSET, dasd_ioctl_set_ro },
 	{ DASDAPIVER, dasd_ioctl_api_version },
-	{ HDIO_GETGEO, dasd_ioctl_getgeo },
 	{ -1, NULL }
 };
 
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 4fde411..2e727f4 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -15,7 +15,7 @@
 #include <asm/io.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
-#include <asm/ccwdev.h> 	// for s390_root_dev_(un)register()
+#include <asm/s390_rdev.h>
 
 //#define DCSSBLK_DEBUG		/* Debug messages on/off */
 #define DCSSBLK_NAME "dcssblk"
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index d428c90..54ecd54 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -160,7 +160,7 @@
                 "0: ipm   %0\n"
 		"   srl   %0,28\n"
 		"1:\n"
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 		".section __ex_table,\"a\"\n"
 		"   .align 4\n"
 		"   .long  0b,1b\n"
@@ -208,7 +208,7 @@
                 "0: ipm   %0\n"
 		"   srl   %0,28\n"
 		"1:\n"
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 		".section __ex_table,\"a\"\n"
 		"   .align 4\n"
 		"   .long  0b,1b\n"
@@ -328,31 +328,27 @@
 	return 0;
 }
 
-static int xpram_ioctl (struct inode *inode, struct file *filp,
-		 unsigned int cmd, unsigned long arg)
+static int xpram_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
-	struct hd_geometry __user *geo;
 	unsigned long size;
-	if (cmd != HDIO_GETGEO)
-		return -EINVAL;
+
 	/*
 	 * get geometry: we have to fake one...  trim the size to a
 	 * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
 	 * whatever cylinders. Tell also that data starts at sector. 4.
 	 */
-	geo = (struct hd_geometry __user *) arg;
 	size = (xpram_pages * 8) & ~0x3f;
-	put_user(size >> 6, &geo->cylinders);
-	put_user(4, &geo->heads);
-	put_user(16, &geo->sectors);
-	put_user(4, &geo->start);
+	geo->cylinders = size >> 6;
+	geo->heads = 4;
+	geo->sectors = 16;
+	geo->start = 4;
 	return 0;
 }
 
 static struct block_device_operations xpram_devops =
 {
 	.owner	= THIS_MODULE,
-	.ioctl	= xpram_ioctl,
+	.getgeo	= xpram_getgeo,
 };
 
 /*
diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c
index 5a6cef2..80f7f31 100644
--- a/drivers/s390/char/sclp_cpi.c
+++ b/drivers/s390/char/sclp_cpi.c
@@ -204,7 +204,7 @@
 		printk(KERN_WARNING "cpi: no control program identification "
 		       "support\n");
 		sclp_unregister(&sclp_cpi_event);
-		return -ENOTSUPP;
+		return -EOPNOTSUPP;
 	}
 
 	req = cpi_prepare_req();
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c
index 83f7577..56fa691 100644
--- a/drivers/s390/char/sclp_quiesce.c
+++ b/drivers/s390/char/sclp_quiesce.c
@@ -32,7 +32,7 @@
 	psw_t quiesce_psw;
 	int cpu;
 
-	if (atomic_compare_and_swap(-1, smp_processor_id(), &cpuid))
+	if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1)
 		signal_processor(smp_processor_id(), sigp_stop);
 	/* Wait for all other cpus to enter stopped state */
 	for_each_online_cpu(cpu) {
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index 1efc9f2..5ced272 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -65,7 +65,7 @@
 tapeblock_trigger_requeue(struct tape_device *device)
 {
 	/* Protect against rescheduling. */
-	if (atomic_compare_and_swap(0, 1, &device->blk_data.requeue_scheduled))
+	if (atomic_cmpxchg(&device->blk_data.requeue_scheduled, 0, 1) != 0)
 		return;
 	schedule_work(&device->blk_data.requeue_task);
 }
@@ -78,7 +78,7 @@
 {
 	if (end_that_request_first(req, uptodate, req->hard_nr_sectors))
 		BUG();
-	end_that_request_last(req);
+	end_that_request_last(req, uptodate);
 }
 
 static void
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index 5473c23..5acc0ac 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -66,7 +66,7 @@
 	__cmdl = len;
 	err = 0;
 	asm volatile (
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 		       "diag %2,%4,0x288\n"
 		"1:	\n"
 		".section .fixup,\"ax\"\n"
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index a1c52a6..daf21e0 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/blacklist.c
  *   S/390 common I/O routines -- blacklisting of specific devices
- *   $Revision: 1.35 $
+ *   $Revision: 1.39 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -15,6 +15,7 @@
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/ctype.h>
 #include <linux/device.h>
 
@@ -34,10 +35,10 @@
  * These can be single devices or ranges of devices
  */
 
-/* 65536 bits to indicate if a devno is blacklisted or not */
-#define __BL_DEV_WORDS ((__MAX_SUBCHANNELS + (8*sizeof(long) - 1)) / \
+/* 65536 bits for each set to indicate if a devno is blacklisted or not */
+#define __BL_DEV_WORDS ((__MAX_SUBCHANNEL + (8*sizeof(long) - 1)) / \
 			 (8*sizeof(long)))
-static unsigned long bl_dev[__BL_DEV_WORDS];
+static unsigned long bl_dev[__MAX_SSID + 1][__BL_DEV_WORDS];
 typedef enum {add, free} range_action;
 
 /*
@@ -45,21 +46,23 @@
  * (Un-)blacklist the devices from-to
  */
 static inline void
-blacklist_range (range_action action, unsigned int from, unsigned int to)
+blacklist_range (range_action action, unsigned int from, unsigned int to,
+		 unsigned int ssid)
 {
 	if (!to)
 		to = from;
 
-	if (from > to || to > __MAX_SUBCHANNELS) {
+	if (from > to || to > __MAX_SUBCHANNEL || ssid > __MAX_SSID) {
 		printk (KERN_WARNING "Invalid blacklist range "
-			"0x%04x to 0x%04x, skipping\n", from, to);
+			"0.%x.%04x to 0.%x.%04x, skipping\n",
+			ssid, from, ssid, to);
 		return;
 	}
 	for (; from <= to; from++) {
 		if (action == add)
-			set_bit (from, bl_dev);
+			set_bit (from, bl_dev[ssid]);
 		else
-			clear_bit (from, bl_dev);
+			clear_bit (from, bl_dev[ssid]);
 	}
 }
 
@@ -69,7 +72,7 @@
  * Shamelessly grabbed from dasd_devmap.c.
  */
 static inline int
-blacklist_busid(char **str, int *id0, int *id1, int *devno)
+blacklist_busid(char **str, int *id0, int *ssid, int *devno)
 {
 	int val, old_style;
 	char *sav;
@@ -86,7 +89,7 @@
 		goto confused;
 	val = simple_strtoul(*str, str, 16);
 	if (old_style || (*str)[0] != '.') {
-		*id0 = *id1 = 0;
+		*id0 = *ssid = 0;
 		if (val < 0 || val > 0xffff)
 			goto confused;
 		*devno = val;
@@ -105,7 +108,7 @@
 	val = simple_strtoul(*str, str, 16);
 	if (val < 0 || val > 0xff || (*str)++[0] != '.')
 		goto confused;
-	*id1 = val;
+	*ssid = val;
 	if (!isxdigit((*str)[0]))	/* We require at least one hex digit */
 		goto confused;
 	val = simple_strtoul(*str, str, 16);
@@ -125,7 +128,7 @@
 static inline int
 blacklist_parse_parameters (char *str, range_action action)
 {
-	unsigned int from, to, from_id0, to_id0, from_id1, to_id1;
+	unsigned int from, to, from_id0, to_id0, from_ssid, to_ssid;
 
 	while (*str != 0 && *str != '\n') {
 		range_action ra = action;
@@ -142,23 +145,25 @@
 		 */
 		if (strncmp(str,"all,",4) == 0 || strcmp(str,"all") == 0 ||
 		    strncmp(str,"all\n",4) == 0 || strncmp(str,"all ",4) == 0) {
-			from = 0;
-			to = __MAX_SUBCHANNELS;
+			int j;
+
 			str += 3;
+			for (j=0; j <= __MAX_SSID; j++)
+				blacklist_range(ra, 0, __MAX_SUBCHANNEL, j);
 		} else {
 			int rc;
 
 			rc = blacklist_busid(&str, &from_id0,
-					     &from_id1, &from);
+					     &from_ssid, &from);
 			if (rc)
 				continue;
 			to = from;
 			to_id0 = from_id0;
-			to_id1 = from_id1;
+			to_ssid = from_ssid;
 			if (*str == '-') {
 				str++;
 				rc = blacklist_busid(&str, &to_id0,
-						     &to_id1, &to);
+						     &to_ssid, &to);
 				if (rc)
 					continue;
 			}
@@ -168,18 +173,19 @@
 					strsep(&str, ",\n"));
 				continue;
 			}
-			if ((from_id0 != to_id0) || (from_id1 != to_id1)) {
+			if ((from_id0 != to_id0) ||
+			    (from_ssid != to_ssid)) {
 				printk(KERN_WARNING "invalid cio_ignore range "
 					"%x.%x.%04x-%x.%x.%04x\n",
-					from_id0, from_id1, from,
-					to_id0, to_id1, to);
+					from_id0, from_ssid, from,
+					to_id0, to_ssid, to);
 				continue;
 			}
+			pr_debug("blacklist_setup: adding range "
+				 "from %x.%x.%04x to %x.%x.%04x\n",
+				 from_id0, from_ssid, from, to_id0, to_ssid, to);
+			blacklist_range (ra, from, to, to_ssid);
 		}
-		/* FIXME: ignoring id0 and id1 here. */
-		pr_debug("blacklist_setup: adding range "
-			 "from 0.0.%04x to 0.0.%04x\n", from, to);
-		blacklist_range (ra, from, to);
 	}
 	return 1;
 }
@@ -213,12 +219,33 @@
  * Used by validate_subchannel()
  */
 int
-is_blacklisted (int devno)
+is_blacklisted (int ssid, int devno)
 {
-	return test_bit (devno, bl_dev);
+	return test_bit (devno, bl_dev[ssid]);
 }
 
 #ifdef CONFIG_PROC_FS
+static int
+__s390_redo_validation(struct subchannel_id schid, void *data)
+{
+	int ret;
+	struct subchannel *sch;
+
+	sch = get_subchannel_by_schid(schid);
+	if (sch) {
+		/* Already known. */
+		put_device(&sch->dev);
+		return 0;
+	}
+	ret = css_probe_device(schid);
+	if (ret == -ENXIO)
+		return ret; /* We're through. */
+	if (ret == -ENOMEM)
+		/* Stop validation for now. Bad, but no need for a panic. */
+		return ret;
+	return 0;
+}
+
 /*
  * Function: s390_redo_validation
  * Look for no longer blacklisted devices
@@ -226,29 +253,9 @@
 static inline void
 s390_redo_validation (void)
 {
-	unsigned int irq;
-
 	CIO_TRACE_EVENT (0, "redoval");
-	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
-		int ret;
-		struct subchannel *sch;
 
-		sch = get_subchannel_by_schid(irq);
-		if (sch) {
-			/* Already known. */
-			put_device(&sch->dev);
-			continue;
-		}
-		ret = css_probe_device(irq);
-		if (ret == -ENXIO)
-			break; /* We're through. */
-		if (ret == -ENOMEM)
-			/*
-			 * Stop validation for now. Bad, but no need for a
-			 * panic.
-			 */
-			break;
-	}
+	for_each_subchannel(__s390_redo_validation, NULL);
 }
 
 /*
@@ -278,41 +285,90 @@
 	s390_redo_validation ();
 }
 
-/* FIXME: These should be real bus ids and not home-grown ones! */
-static int cio_ignore_read (char *page, char **start, off_t off,
-			    int count, int *eof, void *data)
+/* Iterator struct for all devices. */
+struct ccwdev_iter {
+	int devno;
+	int ssid;
+	int in_range;
+};
+
+static void *
+cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset)
 {
-	const unsigned int entry_size = 18; /* "0.0.ABCD-0.0.EFGH\n" */
-	long devno;
-	int len;
+	struct ccwdev_iter *iter;
 
-	len = 0;
-	for (devno = off; /* abuse the page variable
-			   * as counter, see fs/proc/generic.c */
-	     devno < __MAX_SUBCHANNELS && len + entry_size < count; devno++) {
-		if (!test_bit(devno, bl_dev))
-			continue;
-		len += sprintf(page + len, "0.0.%04lx", devno);
-		if (test_bit(devno + 1, bl_dev)) { /* print range */
-			while (++devno < __MAX_SUBCHANNELS)
-				if (!test_bit(devno, bl_dev))
-					break;
-			len += sprintf(page + len, "-0.0.%04lx", --devno);
-		}
-		len += sprintf(page + len, "\n");
-	}
-
-	if (devno < __MAX_SUBCHANNELS)
-		*eof = 1;
-	*start = (char *) (devno - off); /* number of checked entries */
-	return len;
+	if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1))
+		return NULL;
+	iter = kzalloc(sizeof(struct ccwdev_iter), GFP_KERNEL);
+	if (!iter)
+		return ERR_PTR(-ENOMEM);
+	iter->ssid = *offset / (__MAX_SUBCHANNEL + 1);
+	iter->devno = *offset % (__MAX_SUBCHANNEL + 1);
+	return iter;
 }
 
-static int cio_ignore_write(struct file *file, const char __user *user_buf,
-			     unsigned long user_len, void *data)
+static void
+cio_ignore_proc_seq_stop(struct seq_file *s, void *it)
+{
+	if (!IS_ERR(it))
+		kfree(it);
+}
+
+static void *
+cio_ignore_proc_seq_next(struct seq_file *s, void *it, loff_t *offset)
+{
+	struct ccwdev_iter *iter;
+
+	if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1))
+		return NULL;
+	iter = it;
+	if (iter->devno == __MAX_SUBCHANNEL) {
+		iter->devno = 0;
+		iter->ssid++;
+		if (iter->ssid > __MAX_SSID)
+			return NULL;
+	} else
+		iter->devno++;
+	(*offset)++;
+	return iter;
+}
+
+static int
+cio_ignore_proc_seq_show(struct seq_file *s, void *it)
+{
+	struct ccwdev_iter *iter;
+
+	iter = it;
+	if (!is_blacklisted(iter->ssid, iter->devno))
+		/* Not blacklisted, nothing to output. */
+		return 0;
+	if (!iter->in_range) {
+		/* First device in range. */
+		if ((iter->devno == __MAX_SUBCHANNEL) ||
+		    !is_blacklisted(iter->ssid, iter->devno + 1))
+			/* Singular device. */
+			return seq_printf(s, "0.%x.%04x\n",
+					  iter->ssid, iter->devno);
+		iter->in_range = 1;
+		return seq_printf(s, "0.%x.%04x-", iter->ssid, iter->devno);
+	}
+	if ((iter->devno == __MAX_SUBCHANNEL) ||
+	    !is_blacklisted(iter->ssid, iter->devno + 1)) {
+		/* Last device in range. */
+		iter->in_range = 0;
+		return seq_printf(s, "0.%x.%04x\n", iter->ssid, iter->devno);
+	}
+	return 0;
+}
+
+static ssize_t
+cio_ignore_write(struct file *file, const char __user *user_buf,
+		 size_t user_len, loff_t *offset)
 {
 	char *buf;
 
+	if (*offset)
+		return -EINVAL;
 	if (user_len > 65536)
 		user_len = 65536;
 	buf = vmalloc (user_len + 1); /* maybe better use the stack? */
@@ -330,6 +386,27 @@
 	return user_len;
 }
 
+static struct seq_operations cio_ignore_proc_seq_ops = {
+	.start = cio_ignore_proc_seq_start,
+	.stop  = cio_ignore_proc_seq_stop,
+	.next  = cio_ignore_proc_seq_next,
+	.show  = cio_ignore_proc_seq_show,
+};
+
+static int
+cio_ignore_proc_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &cio_ignore_proc_seq_ops);
+}
+
+static struct file_operations cio_ignore_proc_fops = {
+	.open    = cio_ignore_proc_open,
+	.read    = seq_read,
+	.llseek  = seq_lseek,
+	.release = seq_release,
+	.write   = cio_ignore_write,
+};
+
 static int
 cio_ignore_proc_init (void)
 {
@@ -340,8 +417,7 @@
 	if (!entry)
 		return 0;
 
-	entry->read_proc  = cio_ignore_read;
-	entry->write_proc = cio_ignore_write;
+	entry->proc_fops = &cio_ignore_proc_fops;
 
 	return 1;
 }
diff --git a/drivers/s390/cio/blacklist.h b/drivers/s390/cio/blacklist.h
index fb42caf..95e25c1 100644
--- a/drivers/s390/cio/blacklist.h
+++ b/drivers/s390/cio/blacklist.h
@@ -1,6 +1,6 @@
 #ifndef S390_BLACKLIST_H
 #define S390_BLACKLIST_H
 
-extern int is_blacklisted (int devno);
+extern int is_blacklisted (int ssid, int devno);
 
 #endif
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index e7bd7f3..e849289 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/ccwgroup.c
  *  bus driver for ccwgroup
- *   $Revision: 1.32 $
+ *   $Revision: 1.33 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *                       IBM Corporation
@@ -45,7 +45,7 @@
 	return 0;
 }
 static int
-ccwgroup_hotplug (struct device *dev, char **envp, int num_envp, char *buffer,
+ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer,
 		  int buffer_size)
 {
 	/* TODO */
@@ -55,7 +55,7 @@
 static struct bus_type ccwgroup_bus_type = {
 	.name    = "ccwgroup",
 	.match   = ccwgroup_bus_match,
-	.hotplug = ccwgroup_hotplug,
+	.uevent = ccwgroup_uevent,
 };
 
 static inline void
@@ -263,7 +263,7 @@
 	struct ccwgroup_driver *gdrv;
 	int ret;
 
-	if (atomic_compare_and_swap(0, 1, &gdev->onoff))
+	if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
 		return -EAGAIN;
 	if (gdev->state == CCWGROUP_ONLINE) {
 		ret = 0;
@@ -289,7 +289,7 @@
 	struct ccwgroup_driver *gdrv;
 	int ret;
 
-	if (atomic_compare_and_swap(0, 1, &gdev->onoff))
+	if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
 		return -EAGAIN;
 	if (gdev->state == CCWGROUP_OFFLINE) {
 		ret = 0;
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index fa3c23b..7270808 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/chsc.c
  *   S/390 common I/O routines -- channel subsystem call
- *   $Revision: 1.120 $
+ *   $Revision: 1.126 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -24,8 +24,6 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-static struct channel_path *chps[NR_CHPIDS];
-
 static void *sei_page;
 
 static int new_channel_path(int chpid);
@@ -33,13 +31,13 @@
 static inline void
 set_chp_logically_online(int chp, int onoff)
 {
-	chps[chp]->state = onoff;
+	css[0]->chps[chp]->state = onoff;
 }
 
 static int
 get_chp_status(int chp)
 {
-	return (chps[chp] ? chps[chp]->state : -ENODEV);
+	return (css[0]->chps[chp] ? css[0]->chps[chp]->state : -ENODEV);
 }
 
 void
@@ -77,7 +75,9 @@
 
 	struct {
 		struct chsc_header request;
-		u16 reserved1;
+		u16 reserved1a:10;
+		u16 ssid:2;
+		u16 reserved1b:4;
 		u16 f_sch;	  /* first subchannel */
 		u16 reserved2;
 		u16 l_sch;	  /* last subchannel */
@@ -104,8 +104,9 @@
 		.code   = 0x0004,
 	};
 
-	ssd_area->f_sch = sch->irq;
-	ssd_area->l_sch = sch->irq;
+	ssd_area->ssid = sch->schid.ssid;
+	ssd_area->f_sch = sch->schid.sch_no;
+	ssd_area->l_sch = sch->schid.sch_no;
 
 	ccode = chsc(ssd_area);
 	if (ccode > 0) {
@@ -147,7 +148,8 @@
 	 */
 	if (ssd_area->st > 3) { /* uhm, that looks strange... */
 		CIO_CRW_EVENT(0, "Strange subchannel type %d"
-			      " for sch %04x\n", ssd_area->st, sch->irq);
+			      " for sch 0.%x.%04x\n", ssd_area->st,
+			      sch->schid.ssid, sch->schid.sch_no);
 		/*
 		 * There may have been a new subchannel type defined in the
 		 * time since this code was written; since we don't know which
@@ -156,8 +158,9 @@
 		return 0;
 	} else {
 		const char *type[4] = {"I/O", "chsc", "message", "ADM"};
-		CIO_CRW_EVENT(6, "ssd: sch %04x is %s subchannel\n",
-			      sch->irq, type[ssd_area->st]);
+		CIO_CRW_EVENT(6, "ssd: sch 0.%x.%04x is %s subchannel\n",
+			      sch->schid.ssid, sch->schid.sch_no,
+			      type[ssd_area->st]);
 
 		sch->ssd_info.valid = 1;
 		sch->ssd_info.type = ssd_area->st;
@@ -218,13 +221,13 @@
 	int j;
 	int mask;
 	struct subchannel *sch;
-	__u8 *chpid;
+	struct channel_path *chpid;
 	struct schib schib;
 
 	sch = to_subchannel(dev);
 	chpid = data;
 	for (j = 0; j < 8; j++)
-		if (sch->schib.pmcw.chpid[j] == *chpid)
+		if (sch->schib.pmcw.chpid[j] == chpid->id)
 			break;
 	if (j >= 8)
 		return 0;
@@ -232,7 +235,7 @@
 	mask = 0x80 >> j;
 	spin_lock(&sch->lock);
 
-	stsch(sch->irq, &schib);
+	stsch(sch->schid, &schib);
 	if (!schib.pmcw.dnv)
 		goto out_unreg;
 	memcpy(&sch->schib, &schib, sizeof(struct schib));
@@ -284,7 +287,7 @@
 out_unreg:
 	spin_unlock(&sch->lock);
 	sch->lpm = 0;
-	if (css_enqueue_subchannel_slow(sch->irq)) {
+	if (css_enqueue_subchannel_slow(sch->schid)) {
 		css_clear_subchannel_slow_list();
 		need_rescan = 1;
 	}
@@ -295,23 +298,30 @@
 s390_set_chpid_offline( __u8 chpid)
 {
 	char dbf_txt[15];
+	struct device *dev;
 
 	sprintf(dbf_txt, "chpr%x", chpid);
 	CIO_TRACE_EVENT(2, dbf_txt);
 
 	if (get_chp_status(chpid) <= 0)
 		return;
-
-	bus_for_each_dev(&css_bus_type, NULL, &chpid,
+	dev = get_device(&css[0]->chps[chpid]->dev);
+	bus_for_each_dev(&css_bus_type, NULL, to_channelpath(dev),
 			 s390_subchannel_remove_chpid);
 
 	if (need_rescan || css_slow_subchannels_exist())
 		queue_work(slow_path_wq, &slow_path_work);
+	put_device(dev);
 }
 
+struct res_acc_data {
+	struct channel_path *chp;
+	u32 fla_mask;
+	u16 fla;
+};
+
 static int
-s390_process_res_acc_sch(u8 chpid, __u16 fla, u32 fla_mask,
-			 struct subchannel *sch)
+s390_process_res_acc_sch(struct res_acc_data *res_data, struct subchannel *sch)
 {
 	int found;
 	int chp;
@@ -323,8 +333,9 @@
 		 * check if chpid is in information updated by ssd
 		 */
 		if (sch->ssd_info.valid &&
-		    sch->ssd_info.chpid[chp] == chpid &&
-		    (sch->ssd_info.fla[chp] & fla_mask) == fla) {
+		    sch->ssd_info.chpid[chp] == res_data->chp->id &&
+		    (sch->ssd_info.fla[chp] & res_data->fla_mask)
+		    == res_data->fla) {
 			found = 1;
 			break;
 		}
@@ -337,24 +348,87 @@
 	 * new path information and eventually check for logically
 	 * offline chpids.
 	 */
-	ccode = stsch(sch->irq, &sch->schib);
+	ccode = stsch(sch->schid, &sch->schib);
 	if (ccode > 0)
 		return 0;
 
 	return 0x80 >> chp;
 }
 
-static int
-s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask)
+static inline int
+s390_process_res_acc_new_sch(struct subchannel_id schid)
 {
+	struct schib schib;
+	int ret;
+	/*
+	 * We don't know the device yet, but since a path
+	 * may be available now to the device we'll have
+	 * to do recognition again.
+	 * Since we don't have any idea about which chpid
+	 * that beast may be on we'll have to do a stsch
+	 * on all devices, grr...
+	 */
+	if (stsch_err(schid, &schib))
+		/* We're through */
+		return need_rescan ? -EAGAIN : -ENXIO;
+
+	/* Put it on the slow path. */
+	ret = css_enqueue_subchannel_slow(schid);
+	if (ret) {
+		css_clear_subchannel_slow_list();
+		need_rescan = 1;
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+static int
+__s390_process_res_acc(struct subchannel_id schid, void *data)
+{
+	int chp_mask, old_lpm;
+	struct res_acc_data *res_data;
 	struct subchannel *sch;
-	int irq, rc;
+
+	res_data = (struct res_acc_data *)data;
+	sch = get_subchannel_by_schid(schid);
+	if (!sch)
+		/* Check if a subchannel is newly available. */
+		return s390_process_res_acc_new_sch(schid);
+
+	spin_lock_irq(&sch->lock);
+
+	chp_mask = s390_process_res_acc_sch(res_data, sch);
+
+	if (chp_mask == 0) {
+		spin_unlock_irq(&sch->lock);
+		return 0;
+	}
+	old_lpm = sch->lpm;
+	sch->lpm = ((sch->schib.pmcw.pim &
+		     sch->schib.pmcw.pam &
+		     sch->schib.pmcw.pom)
+		    | chp_mask) & sch->opm;
+	if (!old_lpm && sch->lpm)
+		device_trigger_reprobe(sch);
+	else if (sch->driver && sch->driver->verify)
+		sch->driver->verify(&sch->dev);
+
+	spin_unlock_irq(&sch->lock);
+	put_device(&sch->dev);
+	return (res_data->fla_mask == 0xffff) ? -ENODEV : 0;
+}
+
+
+static int
+s390_process_res_acc (struct res_acc_data *res_data)
+{
+	int rc;
 	char dbf_txt[15];
 
-	sprintf(dbf_txt, "accpr%x", chpid);
+	sprintf(dbf_txt, "accpr%x", res_data->chp->id);
 	CIO_TRACE_EVENT( 2, dbf_txt);
-	if (fla != 0) {
-		sprintf(dbf_txt, "fla%x", fla);
+	if (res_data->fla != 0) {
+		sprintf(dbf_txt, "fla%x", res_data->fla);
 		CIO_TRACE_EVENT( 2, dbf_txt);
 	}
 
@@ -365,70 +439,11 @@
 	 * The more information we have (info), the less scanning
 	 * will we have to do.
 	 */
-
-	if (!get_chp_status(chpid))
-		return 0; /* no need to do the rest */
-
-	rc = 0;
-	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
-		int chp_mask, old_lpm;
-
-		sch = get_subchannel_by_schid(irq);
-		if (!sch) {
-			struct schib schib;
-			int ret;
-			/*
-			 * We don't know the device yet, but since a path
-			 * may be available now to the device we'll have
-			 * to do recognition again.
-			 * Since we don't have any idea about which chpid
-			 * that beast may be on we'll have to do a stsch
-			 * on all devices, grr...
-			 */
-			if (stsch(irq, &schib)) {
-				/* We're through */
-				if (need_rescan)
-					rc = -EAGAIN;
-				break;
-			}
-			if (need_rescan) {
-				rc = -EAGAIN;
-				continue;
-			}
-			/* Put it on the slow path. */
-			ret = css_enqueue_subchannel_slow(irq);
-			if (ret) {
-				css_clear_subchannel_slow_list();
-				need_rescan = 1;
-			}
-			rc = -EAGAIN;
-			continue;
-		}
-	
-		spin_lock_irq(&sch->lock);
-
-		chp_mask = s390_process_res_acc_sch(chpid, fla, fla_mask, sch);
-
-		if (chp_mask == 0) {
-
-			spin_unlock_irq(&sch->lock);
-			continue;
-		}
-		old_lpm = sch->lpm;
-		sch->lpm = ((sch->schib.pmcw.pim &
-			     sch->schib.pmcw.pam &
-			     sch->schib.pmcw.pom)
-			    | chp_mask) & sch->opm;
-		if (!old_lpm && sch->lpm)
-			device_trigger_reprobe(sch);
-		else if (sch->driver && sch->driver->verify)
-			sch->driver->verify(&sch->dev);
-
-		spin_unlock_irq(&sch->lock);
-		put_device(&sch->dev);
-		if (fla_mask == 0xffff)
-			break;
-	}
+	rc = for_each_subchannel(__s390_process_res_acc, res_data);
+	if (css_slow_subchannels_exist())
+		rc = -EAGAIN;
+	else if (rc != -EAGAIN)
+		rc = 0;
 	return rc;
 }
 
@@ -466,6 +481,7 @@
 chsc_process_crw(void)
 {
 	int chpid, ret;
+	struct res_acc_data res_data;
 	struct {
 		struct chsc_header request;
 		u32 reserved1;
@@ -499,8 +515,9 @@
 	ret = 0;
 	do {
 		int ccode, status;
+		struct device *dev;
 		memset(sei_area, 0, sizeof(*sei_area));
-
+		memset(&res_data, 0, sizeof(struct res_acc_data));
 		sei_area->request = (struct chsc_header) {
 			.length = 0x0010,
 			.code   = 0x000e,
@@ -573,26 +590,25 @@
 			if (status < 0)
 				new_channel_path(sei_area->rsid);
 			else if (!status)
-				return 0;
-			if ((sei_area->vf & 0x80) == 0) {
-				pr_debug("chpid: %x\n", sei_area->rsid);
-				ret = s390_process_res_acc(sei_area->rsid,
-							   0, 0);
-			} else if ((sei_area->vf & 0xc0) == 0x80) {
-				pr_debug("chpid: %x link addr: %x\n",
-					 sei_area->rsid, sei_area->fla);
-				ret = s390_process_res_acc(sei_area->rsid,
-							   sei_area->fla,
-							   0xff00);
-			} else if ((sei_area->vf & 0xc0) == 0xc0) {
-				pr_debug("chpid: %x full link addr: %x\n",
-					 sei_area->rsid, sei_area->fla);
-				ret = s390_process_res_acc(sei_area->rsid,
-							   sei_area->fla,
-							   0xffff);
+				break;
+			dev = get_device(&css[0]->chps[sei_area->rsid]->dev);
+			res_data.chp = to_channelpath(dev);
+			pr_debug("chpid: %x", sei_area->rsid);
+			if ((sei_area->vf & 0xc0) != 0) {
+				res_data.fla = sei_area->fla;
+				if ((sei_area->vf & 0xc0) == 0xc0) {
+					pr_debug(" full link addr: %x",
+						 sei_area->fla);
+					res_data.fla_mask = 0xffff;
+				} else {
+					pr_debug(" link addr: %x",
+						 sei_area->fla);
+					res_data.fla_mask = 0xff00;
+				}
 			}
-			pr_debug("\n");
-			
+			ret = s390_process_res_acc(&res_data);
+			pr_debug("\n\n");
+			put_device(dev);
 			break;
 			
 		default: /* other stuff */
@@ -604,12 +620,72 @@
 	return ret;
 }
 
+static inline int
+__chp_add_new_sch(struct subchannel_id schid)
+{
+	struct schib schib;
+	int ret;
+
+	if (stsch(schid, &schib))
+		/* We're through */
+		return need_rescan ? -EAGAIN : -ENXIO;
+
+	/* Put it on the slow path. */
+	ret = css_enqueue_subchannel_slow(schid);
+	if (ret) {
+		css_clear_subchannel_slow_list();
+		need_rescan = 1;
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+
+static int
+__chp_add(struct subchannel_id schid, void *data)
+{
+	int i;
+	struct channel_path *chp;
+	struct subchannel *sch;
+
+	chp = (struct channel_path *)data;
+	sch = get_subchannel_by_schid(schid);
+	if (!sch)
+		/* Check if the subchannel is now available. */
+		return __chp_add_new_sch(schid);
+	spin_lock(&sch->lock);
+	for (i=0; i<8; i++)
+		if (sch->schib.pmcw.chpid[i] == chp->id) {
+			if (stsch(sch->schid, &sch->schib) != 0) {
+				/* Endgame. */
+				spin_unlock(&sch->lock);
+				return -ENXIO;
+			}
+			break;
+		}
+	if (i==8) {
+		spin_unlock(&sch->lock);
+		return 0;
+	}
+	sch->lpm = ((sch->schib.pmcw.pim &
+		     sch->schib.pmcw.pam &
+		     sch->schib.pmcw.pom)
+		    | 0x80 >> i) & sch->opm;
+
+	if (sch->driver && sch->driver->verify)
+		sch->driver->verify(&sch->dev);
+
+	spin_unlock(&sch->lock);
+	put_device(&sch->dev);
+	return 0;
+}
+
 static int
 chp_add(int chpid)
 {
-	struct subchannel *sch;
-	int irq, ret, rc;
+	int rc;
 	char dbf_txt[15];
+	struct device *dev;
 
 	if (!get_chp_status(chpid))
 		return 0; /* no need to do the rest */
@@ -617,59 +693,13 @@
 	sprintf(dbf_txt, "cadd%x", chpid);
 	CIO_TRACE_EVENT(2, dbf_txt);
 
-	rc = 0;
-	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
-		int i;
-
-		sch = get_subchannel_by_schid(irq);
-		if (!sch) {
-			struct schib schib;
-
-			if (stsch(irq, &schib)) {
-				/* We're through */
-				if (need_rescan)
-					rc = -EAGAIN;
-				break;
-			}
-			if (need_rescan) {
-				rc = -EAGAIN;
-				continue;
-			}
-			/* Put it on the slow path. */
-			ret = css_enqueue_subchannel_slow(irq);
-			if (ret) {
-				css_clear_subchannel_slow_list();
-				need_rescan = 1;
-			}
-			rc = -EAGAIN;
-			continue;
-		}
-	
-		spin_lock(&sch->lock);
-		for (i=0; i<8; i++)
-			if (sch->schib.pmcw.chpid[i] == chpid) {
-				if (stsch(sch->irq, &sch->schib) != 0) {
-					/* Endgame. */
-					spin_unlock(&sch->lock);
-					return rc;
-				}
-				break;
-			}
-		if (i==8) {
-			spin_unlock(&sch->lock);
-			return rc;
-		}
-		sch->lpm = ((sch->schib.pmcw.pim &
-			     sch->schib.pmcw.pam &
-			     sch->schib.pmcw.pom)
-			    | 0x80 >> i) & sch->opm;
-
-		if (sch->driver && sch->driver->verify)
-			sch->driver->verify(&sch->dev);
-
-		spin_unlock(&sch->lock);
-		put_device(&sch->dev);
-	}
+	dev = get_device(&css[0]->chps[chpid]->dev);
+	rc = for_each_subchannel(__chp_add, to_channelpath(dev));
+	if (css_slow_subchannels_exist())
+		rc = -EAGAIN;
+	if (rc != -EAGAIN)
+		rc = 0;
+	put_device(dev);
 	return rc;
 }
 
@@ -702,7 +732,7 @@
 	if (!device_is_online(sch))
 		/* cio could be doing I/O. */
 		return 0;
-	cc = stsch(sch->irq, &sch->schib);
+	cc = stsch(sch->schid, &sch->schib);
 	if (cc)
 		return 0;
 	if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) {
@@ -743,7 +773,7 @@
 			 * just varied off path. Then kill it.
 			 */
 			if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) {
-				if (css_enqueue_subchannel_slow(sch->irq)) {
+				if (css_enqueue_subchannel_slow(sch->schid)) {
 					css_clear_subchannel_slow_list();
 					need_rescan = 1;
 				}
@@ -781,6 +811,29 @@
 	return 0;
 }
 
+static int
+__s390_vary_chpid_on(struct subchannel_id schid, void *data)
+{
+	struct schib schib;
+	struct subchannel *sch;
+
+	sch = get_subchannel_by_schid(schid);
+	if (sch) {
+		put_device(&sch->dev);
+		return 0;
+	}
+	if (stsch_err(schid, &schib))
+		/* We're through */
+		return -ENXIO;
+	/* Put it on the slow path. */
+	if (css_enqueue_subchannel_slow(schid)) {
+		css_clear_subchannel_slow_list();
+		need_rescan = 1;
+		return -EAGAIN;
+	}
+	return 0;
+}
+
 /*
  * Function: s390_vary_chpid
  * Varies the specified chpid online or offline
@@ -789,8 +842,7 @@
 s390_vary_chpid( __u8 chpid, int on)
 {
 	char dbf_text[15];
-	int status, irq, ret;
-	struct subchannel *sch;
+	int status;
 
 	sprintf(dbf_text, on?"varyon%x":"varyoff%x", chpid);
 	CIO_TRACE_EVENT( 2, dbf_text);
@@ -815,30 +867,9 @@
 	bus_for_each_dev(&css_bus_type, NULL, &chpid, on ?
 			 s390_subchannel_vary_chpid_on :
 			 s390_subchannel_vary_chpid_off);
-	if (!on)
-		goto out;
-	/* Scan for new devices on varied on path. */
-	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
-		struct schib schib;
-
-		if (need_rescan)
-			break;
-		sch = get_subchannel_by_schid(irq);
-		if (sch) {
-			put_device(&sch->dev);
-			continue;
-		}
-		if (stsch(irq, &schib))
-			/* We're through */
-			break;
-		/* Put it on the slow path. */
-		ret = css_enqueue_subchannel_slow(irq);
-		if (ret) {
-			css_clear_subchannel_slow_list();
-			need_rescan = 1;
-		}
-	}
-out:
+	if (on)
+		/* Scan for new devices on varied on path. */
+		for_each_subchannel(__s390_vary_chpid_on, NULL);
 	if (need_rescan || css_slow_subchannels_exist())
 		queue_work(slow_path_wq, &slow_path_work);
 	return 0;
@@ -995,7 +1026,7 @@
 	chp->id = chpid;
 	chp->state = 1;
 	chp->dev = (struct device) {
-		.parent  = &css_bus_device,
+		.parent  = &css[0]->device,
 		.release = chp_release,
 	};
 	snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp0.%x", chpid);
@@ -1017,7 +1048,7 @@
 		device_unregister(&chp->dev);
 		goto out_free;
 	} else
-		chps[chpid] = chp;
+		css[0]->chps[chpid] = chp;
 	return ret;
 out_free:
 	kfree(chp);
@@ -1030,7 +1061,7 @@
 	struct channel_path *chp;
 	struct channel_path_desc *desc;
 
-	chp = chps[sch->schib.pmcw.chpid[chp_no]];
+	chp = css[0]->chps[sch->schib.pmcw.chpid[chp_no]];
 	if (!chp)
 		return NULL;
 	desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL);
@@ -1051,6 +1082,54 @@
 	return (sei_page ? 0 : -ENOMEM);
 }
 
+int __init
+chsc_enable_facility(int operation_code)
+{
+	int ret;
+	struct {
+		struct chsc_header request;
+		u8 reserved1:4;
+		u8 format:4;
+		u8 reserved2;
+		u16 operation_code;
+		u32 reserved3;
+		u32 reserved4;
+		u32 operation_data_area[252];
+		struct chsc_header response;
+		u32 reserved5:4;
+		u32 format2:4;
+		u32 reserved6:24;
+	} *sda_area;
+
+	sda_area = (void *)get_zeroed_page(GFP_KERNEL|GFP_DMA);
+	if (!sda_area)
+		return -ENOMEM;
+	sda_area->request = (struct chsc_header) {
+		.length = 0x0400,
+		.code = 0x0031,
+	};
+	sda_area->operation_code = operation_code;
+
+	ret = chsc(sda_area);
+	if (ret > 0) {
+		ret = (ret == 3) ? -ENODEV : -EBUSY;
+		goto out;
+	}
+	switch (sda_area->response.code) {
+	case 0x0003: /* invalid request block */
+	case 0x0007:
+		ret = -EINVAL;
+		break;
+	case 0x0004: /* command not provided */
+	case 0x0101: /* facility not provided */
+		ret = -EOPNOTSUPP;
+		break;
+	}
+ out:
+	free_page((unsigned long)sda_area);
+	return ret;
+}
+
 subsys_initcall(chsc_alloc_sei_area);
 
 struct css_general_char css_general_characteristics;
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index be20da4..44e4b4b 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -1,12 +1,12 @@
 #ifndef S390_CHSC_H
 #define S390_CHSC_H
 
-#define NR_CHPIDS 256
-
 #define CHSC_SEI_ACC_CHPID        1
 #define CHSC_SEI_ACC_LINKADDR     2
 #define CHSC_SEI_ACC_FULLLINKADDR 3
 
+#define CHSC_SDA_OC_MSS   0x2
+
 struct chsc_header {
 	u16 length;
 	u16 code;
@@ -43,7 +43,9 @@
 	u32 ext_mb : 1;  /* bit 48 */
 	u32 : 7;
 	u32 aif_tdd : 1; /* bit 56 */
-	u32 : 10;
+	u32 : 1;
+	u32 qebsm : 1;   /* bit 58 */
+	u32 : 8;
 	u32 aif_osa : 1; /* bit 67 */
 	u32 : 28;
 }__attribute__((packed));
@@ -63,4 +65,9 @@
 extern int css_characteristics_avail;
 
 extern void *chsc_get_chp_desc(struct subchannel*, int);
+
+extern int chsc_enable_facility(int);
+
+#define to_channelpath(dev) container_of(dev, struct channel_path, dev)
+
 #endif
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 185bc73..7376bc8 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/cio.c
  *   S/390 common I/O routines -- low level i/o calls
- *   $Revision: 1.135 $
+ *   $Revision: 1.138 $
  *
  *    Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
  *			      IBM Corporation
@@ -135,7 +135,7 @@
 		return 0;
 	irb = (struct irb *) __LC_IRB;
 	/* Store interrupt response block to lowcore. */
-	if (tsch (tpi_info->irq, irb) != 0)
+	if (tsch (tpi_info->schid, irb) != 0)
 		/* Not status pending or not operational. */
 		return 1;
 	sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
@@ -163,10 +163,11 @@
 	else
 		sch->lpm = 0;
 
-	stsch (sch->irq, &sch->schib);
+	stsch (sch->schid, &sch->schib);
 
 	CIO_MSG_EVENT(0, "cio_start: 'not oper' status for "
-		      "subchannel %04x!\n", sch->irq);
+		      "subchannel 0.%x.%04x!\n", sch->schid.ssid,
+		      sch->schid.sch_no);
 	sprintf(dbf_text, "no%s", sch->dev.bus_id);
 	CIO_TRACE_EVENT(0, dbf_text);
 	CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib));
@@ -194,7 +195,7 @@
 	sch->orb.spnd = sch->options.suspend;
 	sch->orb.ssic = sch->options.suspend && sch->options.inter;
 	sch->orb.lpm = (lpm != 0) ? (lpm & sch->opm) : sch->lpm;
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 	/*
 	 * for 64 bit we always support 64 bit IDAWs with 4k page size only
 	 */
@@ -204,7 +205,7 @@
 	sch->orb.key = key >> 4;
 	/* issue "Start Subchannel" */
 	sch->orb.cpa = (__u32) __pa (cpa);
-	ccode = ssch (sch->irq, &sch->orb);
+	ccode = ssch (sch->schid, &sch->orb);
 
 	/* process condition code */
 	sprintf (dbf_txt, "ccode:%d", ccode);
@@ -243,7 +244,7 @@
 	CIO_TRACE_EVENT (4, "resIO");
 	CIO_TRACE_EVENT (4, sch->dev.bus_id);
 
-	ccode = rsch (sch->irq);
+	ccode = rsch (sch->schid);
 
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (4, dbf_txt);
@@ -283,7 +284,7 @@
 	/*
 	 * Issue "Halt subchannel" and process condition code
 	 */
-	ccode = hsch (sch->irq);
+	ccode = hsch (sch->schid);
 
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (2, dbf_txt);
@@ -318,7 +319,7 @@
 	/*
 	 * Issue "Clear subchannel" and process condition code
 	 */
-	ccode = csch (sch->irq);
+	ccode = csch (sch->schid);
 
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (2, dbf_txt);
@@ -351,7 +352,7 @@
 	CIO_TRACE_EVENT (2, "cancelIO");
 	CIO_TRACE_EVENT (2, sch->dev.bus_id);
 
-	ccode = xsch (sch->irq);
+	ccode = xsch (sch->schid);
 
 	sprintf (dbf_txt, "ccode:%d", ccode);
 	CIO_TRACE_EVENT (2, dbf_txt);
@@ -359,7 +360,7 @@
 	switch (ccode) {
 	case 0:		/* success */
 		/* Update information in scsw. */
-		stsch (sch->irq, &sch->schib);
+		stsch (sch->schid, &sch->schib);
 		return 0;
 	case 1:		/* status pending */
 		return -EBUSY;
@@ -381,7 +382,7 @@
 
 	ret = 0;
 	for (retry = 0; retry < 5; retry++) {
-		ccode = msch_err (sch->irq, &sch->schib);
+		ccode = msch_err (sch->schid, &sch->schib);
 		if (ccode < 0)	/* -EIO if msch gets a program check. */
 			return ccode;
 		switch (ccode) {
@@ -414,7 +415,7 @@
 	CIO_TRACE_EVENT (2, "ensch");
 	CIO_TRACE_EVENT (2, sch->dev.bus_id);
 
-	ccode = stsch (sch->irq, &sch->schib);
+	ccode = stsch (sch->schid, &sch->schib);
 	if (ccode)
 		return -ENODEV;
 
@@ -432,13 +433,13 @@
 			 */
 			sch->schib.pmcw.csense = 0;
 		if (ret == 0) {
-			stsch (sch->irq, &sch->schib);
+			stsch (sch->schid, &sch->schib);
 			if (sch->schib.pmcw.ena)
 				break;
 		}
 		if (ret == -EBUSY) {
 			struct irb irb;
-			if (tsch(sch->irq, &irb) != 0)
+			if (tsch(sch->schid, &irb) != 0)
 				break;
 		}
 	}
@@ -461,7 +462,7 @@
 	CIO_TRACE_EVENT (2, "dissch");
 	CIO_TRACE_EVENT (2, sch->dev.bus_id);
 
-	ccode = stsch (sch->irq, &sch->schib);
+	ccode = stsch (sch->schid, &sch->schib);
 	if (ccode == 3)		/* Not operational. */
 		return -ENODEV;
 
@@ -485,7 +486,7 @@
 			 */
 			break;
 		if (ret == 0) {
-			stsch (sch->irq, &sch->schib);
+			stsch (sch->schid, &sch->schib);
 			if (!sch->schib.pmcw.ena)
 				break;
 		}
@@ -508,12 +509,12 @@
  *   -ENODEV for subchannels with invalid device number or blacklisted devices
  */
 int
-cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
+cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
 {
 	char dbf_txt[15];
 	int ccode;
 
-	sprintf (dbf_txt, "valsch%x", irq);
+	sprintf (dbf_txt, "valsch%x", schid.sch_no);
 	CIO_TRACE_EVENT (4, dbf_txt);
 
 	/* Nuke all fields. */
@@ -522,17 +523,20 @@
 	spin_lock_init(&sch->lock);
 
 	/* Set a name for the subchannel */
-	snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.0.%04x", irq);
+	snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x", schid.ssid,
+		  schid.sch_no);
 
 	/*
 	 * The first subchannel that is not-operational (ccode==3)
 	 *  indicates that there aren't any more devices available.
+	 * If stsch gets an exception, it means the current subchannel set
+	 *  is not valid.
 	 */
-	sch->irq = irq;
-	ccode = stsch (irq, &sch->schib);
+	ccode = stsch_err (schid, &sch->schib);
 	if (ccode)
-		return -ENXIO;
+		return (ccode == 3) ? -ENXIO : ccode;
 
+	sch->schid = schid;
 	/* Copy subchannel type from path management control word. */
 	sch->st = sch->schib.pmcw.st;
 
@@ -541,9 +545,9 @@
 	 */
 	if (sch->st != 0) {
 		CIO_DEBUG(KERN_INFO, 0,
-			  "Subchannel %04X reports "
+			  "Subchannel 0.%x.%04x reports "
 			  "non-I/O subchannel type %04X\n",
-			  sch->irq, sch->st);
+			  sch->schid.ssid, sch->schid.sch_no, sch->st);
 		/* We stop here for non-io subchannels. */
 		return sch->st;
 	}
@@ -554,26 +558,29 @@
 		return -ENODEV;
 
 	/* Devno is valid. */
-	if (is_blacklisted (sch->schib.pmcw.dev)) {
+	if (is_blacklisted (sch->schid.ssid, sch->schib.pmcw.dev)) {
 		/*
 		 * This device must not be known to Linux. So we simply
 		 * say that there is no device and return ENODEV.
 		 */
 		CIO_MSG_EVENT(0, "Blacklisted device detected "
-			      "at devno %04X\n", sch->schib.pmcw.dev);
+			      "at devno %04X, subchannel set %x\n",
+			      sch->schib.pmcw.dev, sch->schid.ssid);
 		return -ENODEV;
 	}
 	sch->opm = 0xff;
-	chsc_validate_chpids(sch);
+	if (!cio_is_console(sch->schid))
+		chsc_validate_chpids(sch);
 	sch->lpm = sch->schib.pmcw.pim &
 		sch->schib.pmcw.pam &
 		sch->schib.pmcw.pom &
 		sch->opm;
 
 	CIO_DEBUG(KERN_INFO, 0,
-		  "Detected device %04X on subchannel %04X"
+		  "Detected device %04x on subchannel 0.%x.%04X"
 		  " - PIM = %02X, PAM = %02X, POM = %02X\n",
-		  sch->schib.pmcw.dev, sch->irq, sch->schib.pmcw.pim,
+		  sch->schib.pmcw.dev, sch->schid.ssid,
+		  sch->schid.sch_no, sch->schib.pmcw.pim,
 		  sch->schib.pmcw.pam, sch->schib.pmcw.pom);
 
 	/*
@@ -632,7 +639,7 @@
 		if (sch)
 			spin_lock(&sch->lock);
 		/* Store interrupt response block to lowcore. */
-		if (tsch (tpi_info->irq, irb) == 0 && sch) {
+		if (tsch (tpi_info->schid, irb) == 0 && sch) {
 			/* Keep subchannel information word up to date. */
 			memcpy (&sch->schib.scsw, &irb->scsw,
 				sizeof (irb->scsw));
@@ -691,28 +698,36 @@
 }
 
 static int
-cio_console_irq(void)
+cio_test_for_console(struct subchannel_id schid, void *data)
 {
-	int irq;
+	if (stsch_err(schid, &console_subchannel.schib) != 0)
+		return -ENXIO;
+	if (console_subchannel.schib.pmcw.dnv &&
+	    console_subchannel.schib.pmcw.dev ==
+	    console_devno) {
+		console_irq = schid.sch_no;
+		return 1; /* found */
+	}
+	return 0;
+}
+
+
+static int
+cio_get_console_sch_no(void)
+{
+	struct subchannel_id schid;
 	
+	init_subchannel_id(&schid);
 	if (console_irq != -1) {
 		/* VM provided us with the irq number of the console. */
-		if (stsch(console_irq, &console_subchannel.schib) != 0 ||
+		schid.sch_no = console_irq;
+		if (stsch(schid, &console_subchannel.schib) != 0 ||
 		    !console_subchannel.schib.pmcw.dnv)
 			return -1;
 		console_devno = console_subchannel.schib.pmcw.dev;
 	} else if (console_devno != -1) {
 		/* At least the console device number is known. */
-		for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
-			if (stsch(irq, &console_subchannel.schib) != 0)
-				break;
-			if (console_subchannel.schib.pmcw.dnv &&
-			    console_subchannel.schib.pmcw.dev ==
-			    console_devno) {
-				console_irq = irq;
-				break;
-			}
-		}
+		for_each_subchannel(cio_test_for_console, NULL);
 		if (console_irq == -1)
 			return -1;
 	} else {
@@ -728,17 +743,20 @@
 struct subchannel *
 cio_probe_console(void)
 {
-	int irq, ret;
+	int sch_no, ret;
+	struct subchannel_id schid;
 
 	if (xchg(&console_subchannel_in_use, 1) != 0)
 		return ERR_PTR(-EBUSY);
-	irq = cio_console_irq();
-	if (irq == -1) {
+	sch_no = cio_get_console_sch_no();
+	if (sch_no == -1) {
 		console_subchannel_in_use = 0;
 		return ERR_PTR(-ENODEV);
 	}
 	memset(&console_subchannel, 0, sizeof(struct subchannel));
-	ret = cio_validate_subchannel(&console_subchannel, irq);
+	init_subchannel_id(&schid);
+	schid.sch_no = sch_no;
+	ret = cio_validate_subchannel(&console_subchannel, schid);
 	if (ret) {
 		console_subchannel_in_use = 0;
 		return ERR_PTR(-ENODEV);
@@ -770,11 +788,11 @@
 
 /* Bah... hack to catch console special sausages. */
 int
-cio_is_console(int irq)
+cio_is_console(struct subchannel_id schid)
 {
 	if (!console_subchannel_in_use)
 		return 0;
-	return (irq == console_subchannel.irq);
+	return schid_equal(&schid, &console_subchannel.schid);
 }
 
 struct subchannel *
@@ -787,7 +805,7 @@
 
 #endif
 static inline int
-__disable_subchannel_easy(unsigned int schid, struct schib *schib)
+__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
 {
 	int retry, cc;
 
@@ -805,7 +823,7 @@
 }
 
 static inline int
-__clear_subchannel_easy(unsigned int schid)
+__clear_subchannel_easy(struct subchannel_id schid)
 {
 	int retry;
 
@@ -815,8 +833,8 @@
 		struct tpi_info ti;
 
 		if (tpi(&ti)) {
-			tsch(ti.irq, (struct irb *)__LC_IRB);
-			if (ti.irq == schid)
+			tsch(ti.schid, (struct irb *)__LC_IRB);
+			if (schid_equal(&ti.schid, &schid))
 				return 0;
 		}
 		udelay(100);
@@ -825,31 +843,33 @@
 }
 
 extern void do_reipl(unsigned long devno);
+static int
+__shutdown_subchannel_easy(struct subchannel_id schid, void *data)
+{
+	struct schib schib;
 
-/* Clear all subchannels. */
+	if (stsch_err(schid, &schib))
+		return -ENXIO;
+	if (!schib.pmcw.ena)
+		return 0;
+	switch(__disable_subchannel_easy(schid, &schib)) {
+	case 0:
+	case -ENODEV:
+		break;
+	default: /* -EBUSY */
+		if (__clear_subchannel_easy(schid))
+			break; /* give up... */
+		stsch(schid, &schib);
+		__disable_subchannel_easy(schid, &schib);
+	}
+	return 0;
+}
+
 void
 clear_all_subchannels(void)
 {
-	unsigned int schid;
-
 	local_irq_disable();
-	for (schid=0;schid<=highest_subchannel;schid++) {
-		struct schib schib;
-		if (stsch(schid, &schib))
-			break; /* break out of the loop */
-		if (!schib.pmcw.ena)
-			continue;
-		switch(__disable_subchannel_easy(schid, &schib)) {
-		case 0:
-		case -ENODEV:
-			break;
-		default: /* -EBUSY */
-			if (__clear_subchannel_easy(schid))
-				break; /* give up... jump out of switch */
-			stsch(schid, &schib);
-			__disable_subchannel_easy(schid, &schib);
-		}
-	}
+	for_each_subchannel(__shutdown_subchannel_easy, NULL);
 }
 
 /* Make sure all subchannels are quiet before we re-ipl an lpar. */
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index c50a9da..0ca9873 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -1,6 +1,8 @@
 #ifndef S390_CIO_H
 #define S390_CIO_H
 
+#include "schid.h"
+
 /*
  * where we put the ssd info
  */
@@ -83,7 +85,7 @@
 
 /* subchannel data structure used by I/O subroutines */
 struct subchannel {
-	unsigned int irq;	/* aka. subchannel number */
+	struct subchannel_id schid;
 	spinlock_t lock;	/* subchannel lock */
 
 	enum {
@@ -114,7 +116,7 @@
 
 #define to_subchannel(n) container_of(n, struct subchannel, dev)
 
-extern int cio_validate_subchannel (struct subchannel *, unsigned int);
+extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id);
 extern int cio_enable_subchannel (struct subchannel *, unsigned int);
 extern int cio_disable_subchannel (struct subchannel *);
 extern int cio_cancel (struct subchannel *);
@@ -127,14 +129,15 @@
 extern int cio_set_options (struct subchannel *, int);
 extern int cio_get_options (struct subchannel *);
 extern int cio_modify (struct subchannel *);
+
 /* Use with care. */
 #ifdef CONFIG_CCW_CONSOLE
 extern struct subchannel *cio_probe_console(void);
 extern void cio_release_console(void);
-extern int cio_is_console(int irq);
+extern int cio_is_console(struct subchannel_id);
 extern struct subchannel *cio_get_console_subchannel(void);
 #else
-#define cio_is_console(irq) 0
+#define cio_is_console(schid) 0
 #define cio_get_console_subchannel() NULL
 #endif
 
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index b978f7f..0b03714 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/s390/cio/cmf.c ($Revision: 1.16 $)
+ * linux/drivers/s390/cio/cmf.c ($Revision: 1.19 $)
  *
  * Linux on zSeries Channel Measurement Facility support
  *
@@ -178,7 +178,7 @@
 	/* msch can silently fail, so do it again if necessary */
 	for (retry = 0; retry < 3; retry++) {
 		/* prepare schib */
-		stsch(sch->irq, schib);
+		stsch(sch->schid, schib);
 		schib->pmcw.mme  = mme;
 		schib->pmcw.mbfc = mbfc;
 		/* address can be either a block address or a block index */
@@ -188,7 +188,7 @@
 			schib->pmcw.mbi = address;
 
 		/* try to submit it */
-		switch(ret = msch_err(sch->irq, schib)) {
+		switch(ret = msch_err(sch->schid, schib)) {
 			case 0:
 				break;
 			case 1:
@@ -202,7 +202,7 @@
 				ret = -EINVAL;
 				break;
 		}
-		stsch(sch->irq, schib); /* restore the schib */
+		stsch(sch->schid, schib); /* restore the schib */
 
 		if (ret)
 			break;
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 555119c..e565193 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/css.c
  *  driver for channel subsystem
- *   $Revision: 1.85 $
+ *   $Revision: 1.93 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -21,19 +21,35 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-unsigned int highest_subchannel;
 int need_rescan = 0;
 int css_init_done = 0;
+static int max_ssid = 0;
 
-struct pgid global_pgid;
+struct channel_subsystem *css[__MAX_CSSID + 1];
+
 int css_characteristics_avail = 0;
 
-struct device css_bus_device = {
-	.bus_id = "css0",
-};
+inline int
+for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data)
+{
+	struct subchannel_id schid;
+	int ret;
+
+	init_subchannel_id(&schid);
+	ret = -ENODEV;
+	do {
+		do {
+			ret = fn(schid, data);
+			if (ret)
+				break;
+		} while (schid.sch_no++ < __MAX_SUBCHANNEL);
+		schid.sch_no = 0;
+	} while (schid.ssid++ < max_ssid);
+	return ret;
+}
 
 static struct subchannel *
-css_alloc_subchannel(int irq)
+css_alloc_subchannel(struct subchannel_id schid)
 {
 	struct subchannel *sch;
 	int ret;
@@ -41,13 +57,11 @@
 	sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA);
 	if (sch == NULL)
 		return ERR_PTR(-ENOMEM);
-	ret = cio_validate_subchannel (sch, irq);
+	ret = cio_validate_subchannel (sch, schid);
 	if (ret < 0) {
 		kfree(sch);
 		return ERR_PTR(ret);
 	}
-	if (irq > highest_subchannel)
-		highest_subchannel = irq;
 
 	if (sch->st != SUBCHANNEL_TYPE_IO) {
 		/* For now we ignore all non-io subchannels. */
@@ -87,7 +101,7 @@
 	struct subchannel *sch;
 
 	sch = to_subchannel(dev);
-	if (!cio_is_console(sch->irq))
+	if (!cio_is_console(sch->schid))
 		kfree(sch);
 }
 
@@ -99,7 +113,7 @@
 	int ret;
 
 	/* Initialize the subchannel structure */
-	sch->dev.parent = &css_bus_device;
+	sch->dev.parent = &css[0]->device;
 	sch->dev.bus = &css_bus_type;
 	sch->dev.release = &css_subchannel_release;
 	
@@ -114,12 +128,12 @@
 }
 
 int
-css_probe_device(int irq)
+css_probe_device(struct subchannel_id schid)
 {
 	int ret;
 	struct subchannel *sch;
 
-	sch = css_alloc_subchannel(irq);
+	sch = css_alloc_subchannel(schid);
 	if (IS_ERR(sch))
 		return PTR_ERR(sch);
 	ret = css_register_subchannel(sch);
@@ -132,26 +146,26 @@
 check_subchannel(struct device * dev, void * data)
 {
 	struct subchannel *sch;
-	int irq = (unsigned long)data;
+	struct subchannel_id *schid = data;
 
 	sch = to_subchannel(dev);
-	return (sch->irq == irq);
+	return schid_equal(&sch->schid, schid);
 }
 
 struct subchannel *
-get_subchannel_by_schid(int irq)
+get_subchannel_by_schid(struct subchannel_id schid)
 {
 	struct device *dev;
 
 	dev = bus_find_device(&css_bus_type, NULL,
-			      (void *)(unsigned long)irq, check_subchannel);
+			      (void *)&schid, check_subchannel);
 
 	return dev ? to_subchannel(dev) : NULL;
 }
 
 
 static inline int
-css_get_subchannel_status(struct subchannel *sch, int schid)
+css_get_subchannel_status(struct subchannel *sch, struct subchannel_id schid)
 {
 	struct schib schib;
 	int cc;
@@ -170,13 +184,13 @@
 }
 	
 static int
-css_evaluate_subchannel(int irq, int slow)
+css_evaluate_subchannel(struct subchannel_id schid, int slow)
 {
 	int event, ret, disc;
 	struct subchannel *sch;
 	unsigned long flags;
 
-	sch = get_subchannel_by_schid(irq);
+	sch = get_subchannel_by_schid(schid);
 	disc = sch ? device_is_disconnected(sch) : 0;
 	if (disc && slow) {
 		if (sch)
@@ -194,9 +208,10 @@
 			put_device(&sch->dev);
 		return -EAGAIN; /* Will be done on the slow path. */
 	}
-	event = css_get_subchannel_status(sch, irq);
-	CIO_MSG_EVENT(4, "Evaluating schid %04x, event %d, %s, %s path.\n",
-		      irq, event, sch?(disc?"disconnected":"normal"):"unknown",
+	event = css_get_subchannel_status(sch, schid);
+	CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, %s, %s path.\n",
+		      schid.ssid, schid.sch_no, event,
+		      sch?(disc?"disconnected":"normal"):"unknown",
 		      slow?"slow":"fast");
 	switch (event) {
 	case CIO_NO_PATH:
@@ -253,7 +268,7 @@
 			sch->schib.pmcw.intparm = 0;
 			cio_modify(sch);
 			put_device(&sch->dev);
-			ret = css_probe_device(irq);
+			ret = css_probe_device(schid);
 		} else {
 			/*
 			 * We can't immediately deregister the disconnected
@@ -272,7 +287,7 @@
 			device_trigger_reprobe(sch);
 			spin_unlock_irqrestore(&sch->lock, flags);
 		}
-		ret = sch ? 0 : css_probe_device(irq);
+		ret = sch ? 0 : css_probe_device(schid);
 		break;
 	default:
 		BUG();
@@ -281,28 +296,15 @@
 	return ret;
 }
 
-static void
-css_rescan_devices(void)
+static int
+css_rescan_devices(struct subchannel_id schid, void *data)
 {
-	int irq, ret;
-
-	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
-		ret = css_evaluate_subchannel(irq, 1);
-		/* No more memory. It doesn't make sense to continue. No
-		 * panic because this can happen in midflight and just
-		 * because we can't use a new device is no reason to crash
-		 * the system. */
-		if (ret == -ENOMEM)
-			break;
-		/* -ENXIO indicates that there are no more subchannels. */
-		if (ret == -ENXIO)
-			break;
-	}
+	return css_evaluate_subchannel(schid, 1);
 }
 
 struct slow_subchannel {
 	struct list_head slow_list;
-	unsigned long schid;
+	struct subchannel_id schid;
 };
 
 static LIST_HEAD(slow_subchannels_head);
@@ -315,7 +317,7 @@
 
 	if (need_rescan) {
 		need_rescan = 0;
-		css_rescan_devices();
+		for_each_subchannel(css_rescan_devices, NULL);
 		return;
 	}
 
@@ -354,23 +356,31 @@
  * Called from the machine check handler for subchannel report words.
  */
 int
-css_process_crw(int irq)
+css_process_crw(int rsid1, int rsid2)
 {
 	int ret;
+	struct subchannel_id mchk_schid;
 
-	CIO_CRW_EVENT(2, "source is subchannel %04X\n", irq);
+	CIO_CRW_EVENT(2, "source is subchannel %04X, subsystem id %x\n",
+		      rsid1, rsid2);
 
 	if (need_rescan)
 		/* We need to iterate all subchannels anyway. */
 		return -EAGAIN;
+
+	init_subchannel_id(&mchk_schid);
+	mchk_schid.sch_no = rsid1;
+	if (rsid2 != 0)
+		mchk_schid.ssid = (rsid2 >> 8) & 3;
+
 	/* 
 	 * Since we are always presented with IPI in the CRW, we have to
 	 * use stsch() to find out if the subchannel in question has come
 	 * or gone.
 	 */
-	ret = css_evaluate_subchannel(irq, 0);
+	ret = css_evaluate_subchannel(mchk_schid, 0);
 	if (ret == -EAGAIN) {
-		if (css_enqueue_subchannel_slow(irq)) {
+		if (css_enqueue_subchannel_slow(mchk_schid)) {
 			css_clear_subchannel_slow_list();
 			need_rescan = 1;
 		}
@@ -378,22 +388,83 @@
 	return ret;
 }
 
-static void __init
-css_generate_pgid(void)
+static int __init
+__init_channel_subsystem(struct subchannel_id schid, void *data)
 {
-	/* Let's build our path group ID here. */
-	if (css_characteristics_avail && css_general_characteristics.mcss)
-		global_pgid.cpu_addr = 0x8000;
+	struct subchannel *sch;
+	int ret;
+
+	if (cio_is_console(schid))
+		sch = cio_get_console_subchannel();
 	else {
+		sch = css_alloc_subchannel(schid);
+		if (IS_ERR(sch))
+			ret = PTR_ERR(sch);
+		else
+			ret = 0;
+		switch (ret) {
+		case 0:
+			break;
+		case -ENOMEM:
+			panic("Out of memory in init_channel_subsystem\n");
+		/* -ENXIO: no more subchannels. */
+		case -ENXIO:
+			return ret;
+		default:
+			return 0;
+		}
+	}
+	/*
+	 * We register ALL valid subchannels in ioinfo, even those
+	 * that have been present before init_channel_subsystem.
+	 * These subchannels can't have been registered yet (kmalloc
+	 * not working) so we do it now. This is true e.g. for the
+	 * console subchannel.
+	 */
+	css_register_subchannel(sch);
+	return 0;
+}
+
+static void __init
+css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
+{
+	if (css_characteristics_avail && css_general_characteristics.mcss) {
+		css->global_pgid.pgid_high.ext_cssid.version = 0x80;
+		css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid;
+	} else {
 #ifdef CONFIG_SMP
-		global_pgid.cpu_addr = hard_smp_processor_id();
+		css->global_pgid.pgid_high.cpu_addr = hard_smp_processor_id();
 #else
-		global_pgid.cpu_addr = 0;
+		css->global_pgid.pgid_high.cpu_addr = 0;
 #endif
 	}
-	global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident;
-	global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine;
-	global_pgid.tod_high = (__u32) (get_clock() >> 32);
+	css->global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident;
+	css->global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine;
+	css->global_pgid.tod_high = tod_high;
+
+}
+
+static void
+channel_subsystem_release(struct device *dev)
+{
+	struct channel_subsystem *css;
+
+	css = to_css(dev);
+	kfree(css);
+}
+
+static inline void __init
+setup_css(int nr)
+{
+	u32 tod_high;
+
+	memset(css[nr], 0, sizeof(struct channel_subsystem));
+	css[nr]->valid = 1;
+	css[nr]->cssid = nr;
+	sprintf(css[nr]->device.bus_id, "css%x", nr);
+	css[nr]->device.release = channel_subsystem_release;
+	tod_high = (u32) (get_clock() >> 32);
+	css_generate_pgid(css[nr], tod_high);
 }
 
 /*
@@ -404,53 +475,50 @@
 static int __init
 init_channel_subsystem (void)
 {
-	int ret, irq;
+	int ret, i;
 
 	if (chsc_determine_css_characteristics() == 0)
 		css_characteristics_avail = 1;
 
-	css_generate_pgid();
-
 	if ((ret = bus_register(&css_bus_type)))
 		goto out;
-	if ((ret = device_register (&css_bus_device)))
-		goto out_bus;
 
+	/* Try to enable MSS. */
+	ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
+	switch (ret) {
+	case 0: /* Success. */
+		max_ssid = __MAX_SSID;
+		break;
+	case -ENOMEM:
+		goto out_bus;
+	default:
+		max_ssid = 0;
+	}
+	/* Setup css structure. */
+	for (i = 0; i <= __MAX_CSSID; i++) {
+		css[i] = kmalloc(sizeof(struct channel_subsystem), GFP_KERNEL);
+		if (!css[i]) {
+			ret = -ENOMEM;
+			goto out_unregister;
+		}
+		setup_css(i);
+		ret = device_register(&css[i]->device);
+		if (ret)
+			goto out_free;
+	}
 	css_init_done = 1;
 
 	ctl_set_bit(6, 28);
 
-	for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) {
-		struct subchannel *sch;
-
-		if (cio_is_console(irq))
-			sch = cio_get_console_subchannel();
-		else {
-			sch = css_alloc_subchannel(irq);
-			if (IS_ERR(sch))
-				ret = PTR_ERR(sch);
-			else
-				ret = 0;
-			if (ret == -ENOMEM)
-				panic("Out of memory in "
-				      "init_channel_subsystem\n");
-			/* -ENXIO: no more subchannels. */
-			if (ret == -ENXIO)
-				break;
-			if (ret)
-				continue;
-		}
-		/*
-		 * We register ALL valid subchannels in ioinfo, even those
-		 * that have been present before init_channel_subsystem.
-		 * These subchannels can't have been registered yet (kmalloc
-		 * not working) so we do it now. This is true e.g. for the
-		 * console subchannel.
-		 */
-		css_register_subchannel(sch);
-	}
+	for_each_subchannel(__init_channel_subsystem, NULL);
 	return 0;
-
+out_free:
+	kfree(css[i]);
+out_unregister:
+	while (i > 0) {
+		i--;
+		device_unregister(&css[i]->device);
+	}
 out_bus:
 	bus_unregister(&css_bus_type);
 out:
@@ -481,47 +549,8 @@
 
 subsys_initcall(init_channel_subsystem);
 
-/*
- * Register root devices for some drivers. The release function must not be
- * in the device drivers, so we do it here.
- */
-static void
-s390_root_dev_release(struct device *dev)
-{
-	kfree(dev);
-}
-
-struct device *
-s390_root_dev_register(const char *name)
-{
-	struct device *dev;
-	int ret;
-
-	if (!strlen(name))
-		return ERR_PTR(-EINVAL);
-	dev = kmalloc(sizeof(struct device), GFP_KERNEL);
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-	memset(dev, 0, sizeof(struct device));
-	strncpy(dev->bus_id, name, min(strlen(name), (size_t)BUS_ID_SIZE));
-	dev->release = s390_root_dev_release;
-	ret = device_register(dev);
-	if (ret) {
-		kfree(dev);
-		return ERR_PTR(ret);
-	}
-	return dev;
-}
-
-void
-s390_root_dev_unregister(struct device *dev)
-{
-	if (dev)
-		device_unregister(dev);
-}
-
 int
-css_enqueue_subchannel_slow(unsigned long schid)
+css_enqueue_subchannel_slow(struct subchannel_id schid)
 {
 	struct slow_subchannel *new_slow_sch;
 	unsigned long flags;
@@ -564,6 +593,4 @@
 
 MODULE_LICENSE("GPL");
 EXPORT_SYMBOL(css_bus_type);
-EXPORT_SYMBOL(s390_root_dev_register);
-EXPORT_SYMBOL(s390_root_dev_unregister);
 EXPORT_SYMBOL_GPL(css_characteristics_avail);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 2004a6c..251ebd7 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -6,6 +6,8 @@
 
 #include <asm/cio.h>
 
+#include "schid.h"
+
 /*
  * path grouping stuff
  */
@@ -33,19 +35,25 @@
 	__u8  resvd  : 3;	/* reserved */
 } __attribute__ ((packed));
 
+struct extended_cssid {
+	u8 version;
+	u8 cssid;
+} __attribute__ ((packed));
+
 struct pgid {
 	union {
 		__u8 fc;   	/* SPID function code */
 		struct path_state ps;	/* SNID path state */
 	} inf;
-	__u32 cpu_addr	: 16;	/* CPU address */
+	union {
+		__u32 cpu_addr	: 16;	/* CPU address */
+		struct extended_cssid ext_cssid;
+	} pgid_high;
 	__u32 cpu_id	: 24;	/* CPU identification */
 	__u32 cpu_model : 16;	/* CPU model */
 	__u32 tod_high;		/* high word TOD clock */
 } __attribute__ ((packed));
 
-extern struct pgid global_pgid;
-
 #define MAX_CIWS 8
 
 /*
@@ -68,7 +76,8 @@
 	atomic_t onoff;
 	unsigned long registered;
 	__u16 devno;		/* device number */
-	__u16 irq;		/* subchannel number */
+	__u16 sch_no;		/* subchannel number */
+	__u8 ssid;              /* subchannel set id */
 	__u8 imask;		/* lpm mask for SNID/SID/SPGID */
 	int iretry;		/* retry counter SNID/SID/SPGID */
 	struct {
@@ -121,15 +130,27 @@
 extern struct bus_type css_bus_type;
 extern struct css_driver io_subchannel_driver;
 
-int css_probe_device(int irq);
-extern struct subchannel * get_subchannel_by_schid(int irq);
-extern unsigned int highest_subchannel;
+extern int css_probe_device(struct subchannel_id);
+extern struct subchannel * get_subchannel_by_schid(struct subchannel_id);
 extern int css_init_done;
+extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
 
-#define __MAX_SUBCHANNELS 65536
+#define __MAX_SUBCHANNEL 65535
+#define __MAX_SSID 3
+#define __MAX_CHPID 255
+#define __MAX_CSSID 0
+
+struct channel_subsystem {
+	u8 cssid;
+	int valid;
+	struct channel_path *chps[__MAX_CHPID];
+	struct device device;
+	struct pgid global_pgid;
+};
+#define to_css(dev) container_of(dev, struct channel_subsystem, device)
 
 extern struct bus_type css_bus_type;
-extern struct device css_bus_device;
+extern struct channel_subsystem *css[];
 
 /* Some helper functions for disconnected state. */
 int device_is_disconnected(struct subchannel *);
@@ -144,7 +165,7 @@
 void device_kill_pending_timer(struct subchannel *);
 
 /* Helper functions to build lists for the slow path. */
-int css_enqueue_subchannel_slow(unsigned long schid);
+extern int css_enqueue_subchannel_slow(struct subchannel_id schid);
 void css_walk_subchannel_slow_list(void (*fn)(unsigned long));
 void css_clear_subchannel_slow_list(void);
 int css_slow_subchannels_exist(void);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 811c9d1..fa3e4c0 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/device.c
  *  bus driver for ccw devices
- *   $Revision: 1.131 $
+ *   $Revision: 1.137 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -59,7 +59,7 @@
  * Heavily modeled on pci and usb hotplug.
  */
 static int
-ccw_hotplug (struct device *dev, char **envp, int num_envp,
+ccw_uevent (struct device *dev, char **envp, int num_envp,
 	     char *buffer, int buffer_size)
 {
 	struct ccw_device *cdev = to_ccwdev(dev);
@@ -110,7 +110,7 @@
 struct bus_type ccw_bus_type = {
 	.name  = "ccw",
 	.match = &ccw_bus_match,
-	.hotplug = &ccw_hotplug,
+	.uevent = &ccw_uevent,
 };
 
 static int io_subchannel_probe (struct device *);
@@ -374,7 +374,7 @@
 	int i, force, ret;
 	char *tmp;
 
-	if (atomic_compare_and_swap(0, 1, &cdev->private->onoff))
+	if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
 		return -EAGAIN;
 
 	if (cdev->drv && !try_module_get(cdev->drv->owner)) {
@@ -535,7 +535,8 @@
 }
 
 struct match_data {
-	unsigned int  devno;
+	unsigned int devno;
+	unsigned int ssid;
 	struct ccw_device * sibling;
 };
 
@@ -548,6 +549,7 @@
 	cdev = to_ccwdev(dev);
 	if ((cdev->private->state == DEV_STATE_DISCONNECTED) &&
 	    (cdev->private->devno == d->devno) &&
+	    (cdev->private->ssid == d->ssid) &&
 	    (cdev != d->sibling)) {
 		cdev->private->state = DEV_STATE_NOT_OPER;
 		return 1;
@@ -556,11 +558,13 @@
 }
 
 static struct ccw_device *
-get_disc_ccwdev_by_devno(unsigned int devno, struct ccw_device *sibling)
+get_disc_ccwdev_by_devno(unsigned int devno, unsigned int ssid,
+			 struct ccw_device *sibling)
 {
 	struct device *dev;
 	struct match_data data = {
-		.devno  = devno,
+		.devno   = devno,
+		.ssid    = ssid,
 		.sibling = sibling,
 	};
 
@@ -616,13 +620,13 @@
 
 		need_rename = 1;
 		other_cdev = get_disc_ccwdev_by_devno(sch->schib.pmcw.dev,
-						      cdev);
+						      sch->schid.ssid, cdev);
 		if (other_cdev) {
 			struct subchannel *other_sch;
 
 			other_sch = to_subchannel(other_cdev->dev.parent);
 			if (get_device(&other_sch->dev)) {
-				stsch(other_sch->irq, &other_sch->schib);
+				stsch(other_sch->schid, &other_sch->schib);
 				if (other_sch->schib.pmcw.dnv) {
 					other_sch->schib.pmcw.intparm = 0;
 					cio_modify(other_sch);
@@ -639,8 +643,8 @@
 	if (test_and_clear_bit(1, &cdev->private->registered))
 		device_del(&cdev->dev);
 	if (need_rename)
-		snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.0.%04x",
-			  sch->schib.pmcw.dev);
+		snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
+			  sch->schid.ssid, sch->schib.pmcw.dev);
 	PREPARE_WORK(&cdev->private->kick_work,
 		     ccw_device_add_changed, (void *)cdev);
 	queue_work(ccw_device_work, &cdev->private->kick_work);
@@ -769,18 +773,20 @@
 	sch->dev.driver_data = cdev;
 	sch->driver = &io_subchannel_driver;
 	cdev->ccwlock = &sch->lock;
+
 	/* Init private data. */
 	priv = cdev->private;
 	priv->devno = sch->schib.pmcw.dev;
-	priv->irq = sch->irq;
+	priv->ssid = sch->schid.ssid;
+	priv->sch_no = sch->schid.sch_no;
 	priv->state = DEV_STATE_NOT_OPER;
 	INIT_LIST_HEAD(&priv->cmb_list);
 	init_waitqueue_head(&priv->wait_q);
 	init_timer(&priv->timer);
 
 	/* Set an initial name for the device. */
-	snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.0.%04x",
-		  sch->schib.pmcw.dev);
+	snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
+		  sch->schid.ssid, sch->schib.pmcw.dev);
 
 	/* Increase counter of devices currently in recognition. */
 	atomic_inc(&ccw_device_init_count);
@@ -951,7 +957,7 @@
 	sch = to_subchannel(dev);
 	cdev = dev->driver_data;
 
-	if (cio_is_console(sch->irq))
+	if (cio_is_console(sch->schid))
 		return;
 	if (!sch->schib.pmcw.ena)
 		/* Nothing to do. */
@@ -986,10 +992,6 @@
 	cdev->dev = (struct device) {
 		.parent = &sch->dev,
 	};
-	/* Initialize the subchannel structure */
-	sch->dev.parent = &css_bus_device;
-	sch->dev.bus = &css_bus_type;
-
 	rc = io_subchannel_recog(cdev, sch);
 	if (rc)
 		return rc;
@@ -1146,6 +1148,16 @@
 	driver_unregister(&cdriver->driver);
 }
 
+/* Helper func for qdio. */
+struct subchannel_id
+ccw_device_get_subchannel_id(struct ccw_device *cdev)
+{
+	struct subchannel *sch;
+
+	sch = to_subchannel(cdev->dev.parent);
+	return sch->schid;
+}
+
 MODULE_LICENSE("GPL");
 EXPORT_SYMBOL(ccw_device_set_online);
 EXPORT_SYMBOL(ccw_device_set_offline);
@@ -1155,3 +1167,4 @@
 EXPORT_SYMBOL(ccw_bus_type);
 EXPORT_SYMBOL(ccw_device_work);
 EXPORT_SYMBOL(ccw_device_notify_work);
+EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index a3aa056..11587eb 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -110,6 +110,7 @@
 
 /* qdio needs this. */
 void ccw_device_set_timeout(struct ccw_device *, int);
+extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *);
 
 void retry_set_schib(struct ccw_device *cdev);
 #endif
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index c1c89f4..23d12b6 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -133,7 +133,7 @@
 	int ret;
 
 	sch = to_subchannel(cdev->dev.parent);
-	ret = stsch(sch->irq, &sch->schib);
+	ret = stsch(sch->schid, &sch->schib);
 	if (ret || !sch->schib.pmcw.dnv)
 		return -ENODEV; 
 	if (!sch->schib.pmcw.ena || sch->schib.scsw.actl == 0)
@@ -231,7 +231,7 @@
 	 * through ssch() and the path information is up to date.
 	 */
 	old_lpm = sch->lpm;
-	stsch(sch->irq, &sch->schib);
+	stsch(sch->schid, &sch->schib);
 	sch->lpm = sch->schib.pmcw.pim &
 		sch->schib.pmcw.pam &
 		sch->schib.pmcw.pom &
@@ -257,8 +257,9 @@
 	switch (state) {
 	case DEV_STATE_NOT_OPER:
 		CIO_DEBUG(KERN_WARNING, 2,
-			  "SenseID : unknown device %04x on subchannel %04x\n",
-			  cdev->private->devno, sch->irq);
+			  "SenseID : unknown device %04x on subchannel "
+			  "0.%x.%04x\n", cdev->private->devno,
+			  sch->schid.ssid, sch->schid.sch_no);
 		break;
 	case DEV_STATE_OFFLINE:
 		if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
@@ -282,16 +283,18 @@
 			return;
 		}
 		/* Issue device info message. */
-		CIO_DEBUG(KERN_INFO, 2, "SenseID : device %04x reports: "
+		CIO_DEBUG(KERN_INFO, 2, "SenseID : device 0.%x.%04x reports: "
 			  "CU  Type/Mod = %04X/%02X, Dev Type/Mod = "
-			  "%04X/%02X\n", cdev->private->devno,
+			  "%04X/%02X\n",
+			  cdev->private->ssid, cdev->private->devno,
 			  cdev->id.cu_type, cdev->id.cu_model,
 			  cdev->id.dev_type, cdev->id.dev_model);
 		break;
 	case DEV_STATE_BOXED:
 		CIO_DEBUG(KERN_WARNING, 2,
-			  "SenseID : boxed device %04x on subchannel %04x\n",
-			  cdev->private->devno, sch->irq);
+			  "SenseID : boxed device %04x on subchannel "
+			  "0.%x.%04x\n", cdev->private->devno,
+			  sch->schid.ssid, sch->schid.sch_no);
 		break;
 	}
 	cdev->private->state = state;
@@ -359,7 +362,7 @@
 	if (state == DEV_STATE_BOXED)
 		CIO_DEBUG(KERN_WARNING, 2,
 			  "Boxed device %04x on subchannel %04x\n",
-			  cdev->private->devno, sch->irq);
+			  cdev->private->devno, sch->schid.sch_no);
 
 	if (cdev->private->flags.donotify) {
 		cdev->private->flags.donotify = 0;
@@ -592,7 +595,7 @@
 	struct subchannel *sch;
 
 	sch = to_subchannel(cdev->dev.parent);
-	if (stsch(sch->irq, &sch->schib) || !sch->schib.pmcw.dnv)
+	if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv)
 		return -ENODEV;
 	if (cdev->private->state != DEV_STATE_ONLINE) {
 		if (sch->schib.scsw.actl != 0)
@@ -711,7 +714,7 @@
 	 * Since we might not just be coming from an interrupt from the
 	 * subchannel we have to update the schib.
 	 */
-	stsch(sch->irq, &sch->schib);
+	stsch(sch->schid, &sch->schib);
 
 	if (sch->schib.scsw.actl != 0 ||
 	    (cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) {
@@ -923,7 +926,7 @@
 
 	/* Iff device is idle, reset timeout. */
 	sch = to_subchannel(cdev->dev.parent);
-	if (!stsch(sch->irq, &sch->schib))
+	if (!stsch(sch->schid, &sch->schib))
 		if (sch->schib.scsw.actl == 0)
 			ccw_device_set_timeout(cdev, 0);
 	/* Call the handler. */
@@ -1035,7 +1038,7 @@
 		return;
 
 	/* Update some values. */
-	if (stsch(sch->irq, &sch->schib))
+	if (stsch(sch->schid, &sch->schib))
 		return;
 
 	/*
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index 0e68fb5..04ceba3 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -27,7 +27,7 @@
 /*
  * diag210 is used under VM to get information about a virtual device
  */
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 int
 diag210(struct diag210 * addr)
 {
@@ -256,16 +256,17 @@
 		 *     sense id information. So, for intervention required,
 		 *     we use the "whack it until it talks" strategy...
 		 */
-		CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel %04x "
-			      "reports cmd reject\n",
-			      cdev->private->devno, sch->irq);
+		CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel "
+			      "0.%x.%04x reports cmd reject\n",
+			      cdev->private->devno, sch->schid.ssid,
+			      sch->schid.sch_no);
 		return -EOPNOTSUPP;
 	}
 	if (irb->esw.esw0.erw.cons) {
-		CIO_MSG_EVENT(2, "SenseID : UC on dev %04x, "
+		CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, "
 			      "lpum %02X, cnt %02d, sns :"
 			      " %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-			      cdev->private->devno,
+			      cdev->private->ssid, cdev->private->devno,
 			      irb->esw.esw0.sublog.lpum,
 			      irb->esw.esw0.erw.scnt,
 			      irb->ecw[0], irb->ecw[1],
@@ -277,16 +278,17 @@
 	if (irb->scsw.cc == 3) {
 		if ((sch->orb.lpm &
 		     sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0)
-			CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x on"
-				      " subchannel %04x is 'not operational'\n",
-				      sch->orb.lpm, cdev->private->devno,
-				      sch->irq);
+			CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x "
+				      "on subchannel 0.%x.%04x is "
+				      "'not operational'\n", sch->orb.lpm,
+				      cdev->private->devno, sch->schid.ssid,
+				      sch->schid.sch_no);
 		return -EACCES;
 	}
 	/* Hmm, whatever happened, try again. */
 	CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on "
-		      "subchannel %04x returns status %02X%02X\n",
-		      cdev->private->devno, sch->irq,
+		      "subchannel 0.%x.%04x returns status %02X%02X\n",
+		      cdev->private->devno, sch->schid.ssid, sch->schid.sch_no,
 		      irb->scsw.dstat, irb->scsw.cstat);
 	return -EAGAIN;
 }
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 85a3026..143b6c2 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/device_ops.c
  *
- *   $Revision: 1.57 $
+ *   $Revision: 1.58 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *			 IBM Corporation
@@ -570,7 +570,7 @@
 int
 _ccw_device_get_subchannel_number(struct ccw_device *cdev)
 {
-	return cdev->private->irq;
+	return cdev->private->sch_no;
 }
 
 int
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 0adac8a..052832d 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -22,6 +22,7 @@
 #include "cio_debug.h"
 #include "css.h"
 #include "device.h"
+#include "ioasm.h"
 
 /*
  * Start Sense Path Group ID helper function. Used in ccw_device_recog
@@ -56,10 +57,10 @@
 			if (ret != -EACCES)
 				return ret;
 			CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel "
-				      "%04x, lpm %02X, became 'not "
+				      "0.%x.%04x, lpm %02X, became 'not "
 				      "operational'\n",
-				      cdev->private->devno, sch->irq,
-				      cdev->private->imask);
+				      cdev->private->devno, sch->schid.ssid,
+				      sch->schid.sch_no, cdev->private->imask);
 
 		}
 		cdev->private->imask >>= 1;
@@ -105,10 +106,10 @@
 		return -EOPNOTSUPP;
 	}
 	if (irb->esw.esw0.erw.cons) {
-		CIO_MSG_EVENT(2, "SNID - device %04x, unit check, "
+		CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, "
 			      "lpum %02X, cnt %02d, sns : "
 			      "%02X%02X%02X%02X %02X%02X%02X%02X ...\n",
-			      cdev->private->devno,
+			      cdev->private->ssid, cdev->private->devno,
 			      irb->esw.esw0.sublog.lpum,
 			      irb->esw.esw0.erw.scnt,
 			      irb->ecw[0], irb->ecw[1],
@@ -118,15 +119,17 @@
 		return -EAGAIN;
 	}
 	if (irb->scsw.cc == 3) {
-		CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel "
-			      "%04x, lpm %02X, became 'not operational'\n",
-			      cdev->private->devno, sch->irq, sch->orb.lpm);
+		CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x,"
+			      " lpm %02X, became 'not operational'\n",
+			      cdev->private->devno, sch->schid.ssid,
+			      sch->schid.sch_no, sch->orb.lpm);
 		return -EACCES;
 	}
 	if (cdev->private->pgid.inf.ps.state2 == SNID_STATE2_RESVD_ELSE) {
-		CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel %04x "
+		CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x "
 			      "is reserved by someone else\n",
-			      cdev->private->devno, sch->irq);
+			      cdev->private->devno, sch->schid.ssid,
+			      sch->schid.sch_no);
 		return -EUSERS;
 	}
 	return 0;
@@ -162,7 +165,7 @@
 	/* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */
 	case 0:			/* Sense Path Group ID successful. */
 		if (cdev->private->pgid.inf.ps.state1 == SNID_STATE1_RESET)
-			memcpy(&cdev->private->pgid, &global_pgid,
+			memcpy(&cdev->private->pgid, &css[0]->global_pgid,
 			       sizeof(struct pgid));
 		ccw_device_sense_pgid_done(cdev, 0);
 		break;
@@ -235,8 +238,9 @@
 	sch->lpm &= ~cdev->private->imask;
 	sch->vpm &= ~cdev->private->imask;
 	CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
-		      "%04x, lpm %02X, became 'not operational'\n",
-		      cdev->private->devno, sch->irq, cdev->private->imask);
+		      "0.%x.%04x, lpm %02X, became 'not operational'\n",
+		      cdev->private->devno, sch->schid.ssid,
+		      sch->schid.sch_no, cdev->private->imask);
 	return ret;
 }
 
@@ -258,8 +262,10 @@
 		if (irb->ecw[0] & SNS0_CMD_REJECT)
 			return -EOPNOTSUPP;
 		/* Hmm, whatever happened, try again. */
-		CIO_MSG_EVENT(2, "SPID - device %04x, unit check, cnt %02d, "
+		CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, "
+			      "cnt %02d, "
 			      "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n",
+			      cdev->private->ssid,
 			      cdev->private->devno, irb->esw.esw0.erw.scnt,
 			      irb->ecw[0], irb->ecw[1],
 			      irb->ecw[2], irb->ecw[3],
@@ -268,10 +274,10 @@
 		return -EAGAIN;
 	}
 	if (irb->scsw.cc == 3) {
-		CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
-			      "%04x, lpm %02X, became 'not operational'\n",
-			      cdev->private->devno, sch->irq,
-			      cdev->private->imask);
+		CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel 0.%x.%04x,"
+			      " lpm %02X, became 'not operational'\n",
+			      cdev->private->devno, sch->schid.ssid,
+			      sch->schid.sch_no, cdev->private->imask);
 		return -EACCES;
 	}
 	return 0;
@@ -364,8 +370,22 @@
 void
 ccw_device_verify_start(struct ccw_device *cdev)
 {
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+
 	cdev->private->flags.pgid_single = 0;
 	cdev->private->iretry = 5;
+	/*
+	 * Update sch->lpm with current values to catch paths becoming
+	 * available again.
+	 */
+	if (stsch(sch->schid, &sch->schib)) {
+		ccw_device_verify_done(cdev, -ENODEV);
+		return;
+	}
+	sch->lpm = sch->schib.pmcw.pim &
+		sch->schib.pmcw.pam &
+		sch->schib.pmcw.pom &
+		sch->opm;
 	__ccw_device_verify_start(cdev);
 }
 
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 12a24d4..db09c20 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -36,15 +36,16 @@
 		
 	CIO_MSG_EVENT(0, "Channel-Check or Interface-Control-Check "
 		      "received"
-		      " ... device %04X on subchannel %04X, dev_stat "
+		      " ... device %04x on subchannel 0.%x.%04x, dev_stat "
 		      ": %02X sch_stat : %02X\n",
-		      cdev->private->devno, cdev->private->irq,
+		      cdev->private->devno, cdev->private->ssid,
+		      cdev->private->sch_no,
 		      irb->scsw.dstat, irb->scsw.cstat);
 
 	if (irb->scsw.cc != 3) {
 		char dbf_text[15];
 
-		sprintf(dbf_text, "chk%x", cdev->private->irq);
+		sprintf(dbf_text, "chk%x", cdev->private->sch_no);
 		CIO_TRACE_EVENT(0, dbf_text);
 		CIO_HEX_EVENT(0, irb, sizeof (struct irb));
 	}
@@ -59,10 +60,11 @@
 	struct subchannel *sch;
 
 	sch = to_subchannel(cdev->dev.parent);
-	stsch (sch->irq, &sch->schib);
+	stsch (sch->schid, &sch->schib);
 
-	CIO_MSG_EVENT(0, "%s(%04x) - path(s) %02x are "
-		      "not operational \n", __FUNCTION__, sch->irq,
+	CIO_MSG_EVENT(0, "%s(0.%x.%04x) - path(s) %02x are "
+		      "not operational \n", __FUNCTION__,
+		      sch->schid.ssid, sch->schid.sch_no,
 		      sch->schib.pmcw.pnom);
 
 	sch->lpm &= ~sch->schib.pmcw.pnom;
diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h
index 45480a2..95a9462 100644
--- a/drivers/s390/cio/ioasm.h
+++ b/drivers/s390/cio/ioasm.h
@@ -1,12 +1,13 @@
 #ifndef S390_CIO_IOASM_H
 #define S390_CIO_IOASM_H
 
+#include "schid.h"
+
 /*
  * TPI info structure
  */
 struct tpi_info {
-	__u32 reserved1	 : 16;	 /* reserved 0x00000001 */
-	__u32 irq	 : 16;	 /* aka. subchannel number */
+	struct subchannel_id schid;
 	__u32 intparm;		 /* interruption parameter */
 	__u32 adapter_IO : 1;
 	__u32 reserved2	 : 1;
@@ -21,7 +22,8 @@
  * Some S390 specific IO instructions as inline
  */
 
-static inline int stsch(int irq, volatile struct schib *addr)
+static inline int stsch(struct subchannel_id schid,
+			    volatile struct schib *addr)
 {
 	int ccode;
 
@@ -31,38 +33,24 @@
 		"   ipm	  %0\n"
 		"   srl	  %0,28"
 		: "=d" (ccode)
-		: "d" (irq | 0x10000), "a" (addr)
+		: "d" (schid), "a" (addr), "m" (*addr)
 		: "cc", "1" );
 	return ccode;
 }
 
-static inline int msch(int irq, volatile struct schib *addr)
-{
-	int ccode;
-
-	__asm__ __volatile__(
-		"   lr	  1,%1\n"
-		"   msch  0(%2)\n"
-		"   ipm	  %0\n"
-		"   srl	  %0,28"
-		: "=d" (ccode)
-		: "d" (irq | 0x10000L), "a" (addr)
-		: "cc", "1" );
-	return ccode;
-}
-
-static inline int msch_err(int irq, volatile struct schib *addr)
+static inline int stsch_err(struct subchannel_id schid,
+				volatile struct schib *addr)
 {
 	int ccode;
 
 	__asm__ __volatile__(
 		"    lhi  %0,%3\n"
 		"    lr	  1,%1\n"
-		"    msch 0(%2)\n"
+		"    stsch 0(%2)\n"
 		"0:  ipm  %0\n"
 		"    srl  %0,28\n"
 		"1:\n"
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 		".section __ex_table,\"a\"\n"
 		"   .align 8\n"
 		"   .quad 0b,1b\n"
@@ -74,12 +62,58 @@
 		".previous"
 #endif
 		: "=&d" (ccode)
-		: "d" (irq | 0x10000L), "a" (addr), "K" (-EIO)
+		: "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr)
 		: "cc", "1" );
 	return ccode;
 }
 
-static inline int tsch(int irq, volatile struct irb *addr)
+static inline int msch(struct subchannel_id schid,
+			   volatile struct schib *addr)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"   lr	  1,%1\n"
+		"   msch  0(%2)\n"
+		"   ipm	  %0\n"
+		"   srl	  %0,28"
+		: "=d" (ccode)
+		: "d" (schid), "a" (addr), "m" (*addr)
+		: "cc", "1" );
+	return ccode;
+}
+
+static inline int msch_err(struct subchannel_id schid,
+			       volatile struct schib *addr)
+{
+	int ccode;
+
+	__asm__ __volatile__(
+		"    lhi  %0,%3\n"
+		"    lr	  1,%1\n"
+		"    msch 0(%2)\n"
+		"0:  ipm  %0\n"
+		"    srl  %0,28\n"
+		"1:\n"
+#ifdef CONFIG_64BIT
+		".section __ex_table,\"a\"\n"
+		"   .align 8\n"
+		"   .quad 0b,1b\n"
+		".previous"
+#else
+		".section __ex_table,\"a\"\n"
+		"   .align 4\n"
+		"   .long 0b,1b\n"
+		".previous"
+#endif
+		: "=&d" (ccode)
+		: "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr)
+		: "cc", "1" );
+	return ccode;
+}
+
+static inline int tsch(struct subchannel_id schid,
+			   volatile struct irb *addr)
 {
 	int ccode;
 
@@ -89,7 +123,7 @@
 		"   ipm	  %0\n"
 		"   srl	  %0,28"
 		: "=d" (ccode)
-		: "d" (irq | 0x10000L), "a" (addr)
+		: "d" (schid), "a" (addr), "m" (*addr)
 		: "cc", "1" );
 	return ccode;
 }
@@ -103,12 +137,13 @@
 		"   ipm	  %0\n"
 		"   srl	  %0,28"
 		: "=d" (ccode)
-		: "a" (addr)
+		: "a" (addr), "m" (*addr)
 		: "cc", "1" );
 	return ccode;
 }
 
-static inline int ssch(int irq, volatile struct orb *addr)
+static inline int ssch(struct subchannel_id schid,
+			   volatile struct orb *addr)
 {
 	int ccode;
 
@@ -118,12 +153,12 @@
 		"   ipm	  %0\n"
 		"   srl	  %0,28"
 		: "=d" (ccode)
-		: "d" (irq | 0x10000L), "a" (addr)
+		: "d" (schid), "a" (addr), "m" (*addr)
 		: "cc", "1" );
 	return ccode;
 }
 
-static inline int rsch(int irq)
+static inline int rsch(struct subchannel_id schid)
 {
 	int ccode;
 
@@ -133,12 +168,12 @@
 		"   ipm	  %0\n"
 		"   srl	  %0,28"
 		: "=d" (ccode)
-		: "d" (irq | 0x10000L)
+		: "d" (schid)
 		: "cc", "1" );
 	return ccode;
 }
 
-static inline int csch(int irq)
+static inline int csch(struct subchannel_id schid)
 {
 	int ccode;
 
@@ -148,12 +183,12 @@
 		"   ipm	  %0\n"
 		"   srl	  %0,28"
 		: "=d" (ccode)
-		: "d" (irq | 0x10000L)
+		: "d" (schid)
 		: "cc", "1" );
 	return ccode;
 }
 
-static inline int hsch(int irq)
+static inline int hsch(struct subchannel_id schid)
 {
 	int ccode;
 
@@ -163,12 +198,12 @@
 		"   ipm	  %0\n"
 		"   srl	  %0,28"
 		: "=d" (ccode)
-		: "d" (irq | 0x10000L)
+		: "d" (schid)
 		: "cc", "1" );
 	return ccode;
 }
 
-static inline int xsch(int irq)
+static inline int xsch(struct subchannel_id schid)
 {
 	int ccode;
 
@@ -178,21 +213,22 @@
 		"   ipm	  %0\n"
 		"   srl	  %0,28"
 		: "=d" (ccode)
-		: "d" (irq | 0x10000L)
+		: "d" (schid)
 		: "cc", "1" );
 	return ccode;
 }
 
 static inline int chsc(void *chsc_area)
 {
+	typedef struct { char _[4096]; } addr_type;
 	int cc;
 
 	__asm__ __volatile__ (
-		".insn	rre,0xb25f0000,%1,0	\n\t"
+		".insn	rre,0xb25f0000,%2,0	\n\t"
 		"ipm	%0	\n\t"
 		"srl	%0,28	\n\t"
-		: "=d" (cc)
-		: "d" (chsc_area)
+		: "=d" (cc), "=m" (*(addr_type *) chsc_area)
+		: "d" (chsc_area), "m" (*(addr_type *) chsc_area)
 		: "cc" );
 
 	return cc;
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index eb39218..30a836f 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -56,7 +56,7 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-#define VERSION_QDIO_C "$Revision: 1.108 $"
+#define VERSION_QDIO_C "$Revision: 1.114 $"
 
 /****************** MODULE PARAMETER VARIABLES ********************/
 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -76,6 +76,7 @@
 #endif /* QDIO_PERFORMANCE_STATS */
 
 static int hydra_thinints;
+static int is_passthrough = 0;
 static int omit_svs;
 
 static int indicator_used[INDICATORS_PER_CACHELINE];
@@ -136,12 +137,126 @@
 	atomic_dec(&q->use_count);
 }
 
-static volatile inline void 
-qdio_set_slsb(volatile char *slsb, unsigned char value)
+/*check ccq  */
+static inline int
+qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
 {
-	xchg((char*)slsb,value);
+	char dbf_text[15];
+
+	if (ccq == 0 || ccq == 32 || ccq == 96)
+		return 0;
+	if (ccq == 97)
+		return 1;
+	/*notify devices immediately*/
+	sprintf(dbf_text,"%d", ccq);
+	QDIO_DBF_TEXT2(1,trace,dbf_text);
+	return -EIO;
+}
+/* EQBS: extract buffer states */
+static inline int
+qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
+	     unsigned int *start, unsigned int *cnt)
+{
+	struct qdio_irq *irq;
+	unsigned int tmp_cnt, q_no, ccq;
+	int rc ;
+	char dbf_text[15];
+
+	ccq = 0;
+	tmp_cnt = *cnt;
+	irq = (struct qdio_irq*)q->irq_ptr;
+	q_no = q->q_no;
+	if(!q->is_input_q)
+		q_no += irq->no_input_qs;
+	ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt);
+	rc = qdio_check_ccq(q, ccq);
+	if (rc < 0) {
+                QDIO_DBF_TEXT2(1,trace,"eqberr");
+                sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt, *cnt, ccq, q_no);
+                QDIO_DBF_TEXT2(1,trace,dbf_text);
+		q->handler(q->cdev,QDIO_STATUS_ACTIVATE_CHECK_CONDITION|
+				QDIO_STATUS_LOOK_FOR_ERROR,
+				0, 0, 0, -1, -1, q->int_parm);
+		return 0;
+	}
+	return (tmp_cnt - *cnt);
 }
 
+/* SQBS: set buffer states */
+static inline int
+qdio_do_sqbs(struct qdio_q *q, unsigned char state,
+	     unsigned int *start, unsigned int *cnt)
+{
+	struct qdio_irq *irq;
+	unsigned int tmp_cnt, q_no, ccq;
+	int rc;
+	char dbf_text[15];
+
+	ccq = 0;
+	tmp_cnt = *cnt;
+	irq = (struct qdio_irq*)q->irq_ptr;
+	q_no = q->q_no;
+	if(!q->is_input_q)
+		q_no += irq->no_input_qs;
+	ccq = do_sqbs(irq->sch_token, state, q_no, start, cnt);
+	rc = qdio_check_ccq(q, ccq);
+	if (rc < 0) {
+                QDIO_DBF_TEXT3(1,trace,"sqberr");
+                sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt,*cnt,ccq,q_no);
+                QDIO_DBF_TEXT3(1,trace,dbf_text);
+		q->handler(q->cdev,QDIO_STATUS_ACTIVATE_CHECK_CONDITION|
+				QDIO_STATUS_LOOK_FOR_ERROR,
+				0, 0, 0, -1, -1, q->int_parm);
+		return 0;
+	}
+	return (tmp_cnt - *cnt);
+}
+
+static inline int
+qdio_set_slsb(struct qdio_q *q, unsigned int *bufno,
+	      unsigned char state, unsigned int *count)
+{
+	volatile char *slsb;
+	struct qdio_irq *irq;
+
+	irq = (struct qdio_irq*)q->irq_ptr;
+	if (!irq->is_qebsm) {
+		slsb = (char *)&q->slsb.acc.val[(*bufno)];
+		xchg(slsb, state);
+		return 1;
+	}
+	return qdio_do_sqbs(q, state, bufno, count);
+}
+
+#ifdef CONFIG_QDIO_DEBUG
+static inline void
+qdio_trace_slsb(struct qdio_q *q)
+{
+	if (q->queue_type==QDIO_TRACE_QTYPE) {
+		if (q->is_input_q)
+			QDIO_DBF_HEX2(0,slsb_in,&q->slsb,
+				      QDIO_MAX_BUFFERS_PER_Q);
+		else
+			QDIO_DBF_HEX2(0,slsb_out,&q->slsb,
+				      QDIO_MAX_BUFFERS_PER_Q);
+	}
+}
+#endif
+
+static inline int
+set_slsb(struct qdio_q *q, unsigned int *bufno,
+	 unsigned char state, unsigned int *count)
+{
+	int rc;
+#ifdef CONFIG_QDIO_DEBUG
+	qdio_trace_slsb(q);
+#endif
+	rc = qdio_set_slsb(q, bufno, state, count);
+#ifdef CONFIG_QDIO_DEBUG
+	qdio_trace_slsb(q);
+#endif
+	return rc;
+}
 static inline int 
 qdio_siga_sync(struct qdio_q *q, unsigned int gpr2,
 	       unsigned int gpr3)
@@ -155,7 +270,7 @@
 	perf_stats.siga_syncs++;
 #endif /* QDIO_PERFORMANCE_STATS */
 
-	cc = do_siga_sync(q->irq, gpr2, gpr3);
+	cc = do_siga_sync(q->schid, gpr2, gpr3);
 	if (cc)
 		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
 
@@ -170,6 +285,23 @@
 	return qdio_siga_sync(q, q->mask, 0);
 }
 
+static int
+__do_siga_output(struct qdio_q *q, unsigned int *busy_bit)
+{
+       struct qdio_irq *irq;
+       unsigned int fc = 0;
+       unsigned long schid;
+
+       irq = (struct qdio_irq *) q->irq_ptr;
+       if (!irq->is_qebsm)
+	       schid = *((u32 *)&q->schid);
+       else {
+	       schid = irq->sch_token;
+	       fc |= 0x80;
+       }
+       return do_siga_output(schid, q->mask, busy_bit, fc);
+}
+
 /* 
  * returns QDIO_SIGA_ERROR_ACCESS_EXCEPTION as cc, when SIGA returns
  * an access exception 
@@ -189,7 +321,7 @@
 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
 
 	for (;;) {
-		cc = do_siga_output(q->irq, q->mask, &busy_bit);
+		cc = __do_siga_output(q, &busy_bit);
 //QDIO_PRINT_ERR("cc=%x, busy=%x\n",cc,busy_bit);
 		if ((cc==2) && (busy_bit) && (q->is_iqdio_q)) {
 			if (!start_time) 
@@ -221,7 +353,7 @@
 	perf_stats.siga_ins++;
 #endif /* QDIO_PERFORMANCE_STATS */
 
-	cc = do_siga_input(q->irq, q->mask);
+	cc = do_siga_input(q->schid, q->mask);
 	
 	if (cc)
 		QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
@@ -230,7 +362,7 @@
 }
 
 /* locked by the locks in qdio_activate and qdio_cleanup */
-static __u32 volatile *
+static __u32 *
 qdio_get_indicator(void)
 {
 	int i;
@@ -258,7 +390,7 @@
 		atomic_dec(&spare_indicator_usecount);
 }
 
-static inline volatile void 
+static inline void
 tiqdio_clear_summary_bit(__u32 *location)
 {
 	QDIO_DBF_TEXT5(0,trace,"clrsummb");
@@ -267,7 +399,7 @@
 	xchg(location,0);
 }
 
-static inline volatile void
+static inline  void
 tiqdio_set_summary_bit(__u32 *location)
 {
 	QDIO_DBF_TEXT5(0,trace,"setsummb");
@@ -336,7 +468,9 @@
 qdio_stop_polling(struct qdio_q *q)
 {
 #ifdef QDIO_USE_PROCESSING_STATE
-	int gsf;
+       unsigned int tmp, gsf, count = 1;
+       unsigned char state = 0;
+       struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
 
 	if (!atomic_swap(&q->polling,0)) 
 		return 1;
@@ -348,17 +482,22 @@
 	if (!q->is_input_q)
 		return 1;
 
-	gsf=GET_SAVED_FRONTIER(q);
-	set_slsb(&q->slsb.acc.val[(gsf+QDIO_MAX_BUFFERS_PER_Q-1)&
-				  (QDIO_MAX_BUFFERS_PER_Q-1)],
-		 SLSB_P_INPUT_NOT_INIT);
+       tmp = gsf = GET_SAVED_FRONTIER(q);
+       tmp = ((tmp + QDIO_MAX_BUFFERS_PER_Q-1) & (QDIO_MAX_BUFFERS_PER_Q-1) );
+       set_slsb(q, &tmp, SLSB_P_INPUT_NOT_INIT, &count);
+
 	/* 
 	 * we don't issue this SYNC_MEMORY, as we trust Rick T and
 	 * moreover will not use the PROCESSING state under VM, so
 	 * q->polling was 0 anyway
 	 */
 	/*SYNC_MEMORY;*/
-	if (q->slsb.acc.val[gsf]!=SLSB_P_INPUT_PRIMED)
+       if (irq->is_qebsm) {
+               count = 1;
+               qdio_do_eqbs(q, &state, &gsf, &count);
+       } else
+               state = q->slsb.acc.val[gsf];
+       if (state != SLSB_P_INPUT_PRIMED)
 		return 1;
 	/* 
 	 * set our summary bit again, as otherwise there is a
@@ -431,18 +570,136 @@
 
 
 /************************* OUTBOUND ROUTINES *******************************/
+static int
+qdio_qebsm_get_outbound_buffer_frontier(struct qdio_q *q)
+{
+        struct qdio_irq *irq;
+        unsigned char state;
+        unsigned int cnt, count, ftc;
+
+        irq = (struct qdio_irq *) q->irq_ptr;
+        if ((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis))
+                SYNC_MEMORY;
+
+        ftc = q->first_to_check;
+        count = qdio_min(atomic_read(&q->number_of_buffers_used),
+                        (QDIO_MAX_BUFFERS_PER_Q-1));
+        if (count == 0)
+                return q->first_to_check;
+        cnt = qdio_do_eqbs(q, &state, &ftc, &count);
+        if (cnt == 0)
+                return q->first_to_check;
+        switch (state) {
+        case SLSB_P_OUTPUT_ERROR:
+                QDIO_DBF_TEXT3(0,trace,"outperr");
+                atomic_sub(cnt , &q->number_of_buffers_used);
+                if (q->qdio_error)
+                        q->error_status_flags |=
+                                QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
+                q->qdio_error = SLSB_P_OUTPUT_ERROR;
+                q->error_status_flags |= QDIO_STATUS_LOOK_FOR_ERROR;
+                q->first_to_check = ftc;
+                break;
+        case SLSB_P_OUTPUT_EMPTY:
+                QDIO_DBF_TEXT5(0,trace,"outpempt");
+                atomic_sub(cnt, &q->number_of_buffers_used);
+                q->first_to_check = ftc;
+                break;
+        case SLSB_CU_OUTPUT_PRIMED:
+                /* all buffers primed */
+                QDIO_DBF_TEXT5(0,trace,"outpprim");
+                break;
+        default:
+                break;
+        }
+        QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
+        return q->first_to_check;
+}
+
+static int
+qdio_qebsm_get_inbound_buffer_frontier(struct qdio_q *q)
+{
+        struct qdio_irq *irq;
+        unsigned char state;
+        int tmp, ftc, count, cnt;
+        char dbf_text[15];
+
+
+        irq = (struct qdio_irq *) q->irq_ptr;
+        ftc = q->first_to_check;
+        count = qdio_min(atomic_read(&q->number_of_buffers_used),
+                        (QDIO_MAX_BUFFERS_PER_Q-1));
+        if (count == 0)
+                 return q->first_to_check;
+        cnt = qdio_do_eqbs(q, &state, &ftc, &count);
+        if (cnt == 0)
+                 return q->first_to_check;
+        switch (state) {
+        case SLSB_P_INPUT_ERROR :
+#ifdef CONFIG_QDIO_DEBUG
+                QDIO_DBF_TEXT3(1,trace,"inperr");
+                sprintf(dbf_text,"%2x,%2x",ftc,count);
+                QDIO_DBF_TEXT3(1,trace,dbf_text);
+#endif /* CONFIG_QDIO_DEBUG */
+                if (q->qdio_error)
+                        q->error_status_flags |=
+                                QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR;
+                q->qdio_error = SLSB_P_INPUT_ERROR;
+                q->error_status_flags |= QDIO_STATUS_LOOK_FOR_ERROR;
+                atomic_sub(cnt, &q->number_of_buffers_used);
+                q->first_to_check = ftc;
+                break;
+        case SLSB_P_INPUT_PRIMED :
+                QDIO_DBF_TEXT3(0,trace,"inptprim");
+                sprintf(dbf_text,"%2x,%2x",ftc,count);
+                QDIO_DBF_TEXT3(1,trace,dbf_text);
+                tmp = 0;
+                ftc = q->first_to_check;
+#ifdef QDIO_USE_PROCESSING_STATE
+		if (cnt > 1) {
+			cnt -= 1;
+			tmp = set_slsb(q, &ftc, SLSB_P_INPUT_NOT_INIT, &cnt);
+			if (!tmp)
+				break;
+		}
+		cnt = 1;
+		tmp += set_slsb(q, &ftc,
+			       SLSB_P_INPUT_PROCESSING, &cnt);
+		atomic_set(&q->polling, 1);
+#else
+                tmp = set_slsb(q, &ftc, SLSB_P_INPUT_NOT_INIT, &cnt);
+#endif
+                atomic_sub(tmp, &q->number_of_buffers_used);
+                q->first_to_check = ftc;
+                break;
+        case SLSB_CU_INPUT_EMPTY:
+        case SLSB_P_INPUT_NOT_INIT:
+        case SLSB_P_INPUT_PROCESSING:
+                QDIO_DBF_TEXT5(0,trace,"inpnipro");
+                break;
+        default:
+                break;
+        }
+        QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
+        return q->first_to_check;
+}
 
 static inline int
 qdio_get_outbound_buffer_frontier(struct qdio_q *q)
 {
-	int f,f_mod_no;
-	volatile char *slsb;
-	int first_not_to_check;
+	struct qdio_irq *irq;
+        volatile char *slsb;
+        unsigned int count = 1;
+        int first_not_to_check, f, f_mod_no;
 	char dbf_text[15];
 
 	QDIO_DBF_TEXT4(0,trace,"getobfro");
 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
 
+	irq = (struct qdio_irq *) q->irq_ptr;
+	if (irq->is_qebsm)
+		return qdio_qebsm_get_outbound_buffer_frontier(q);
+
 	slsb=&q->slsb.acc.val[0];
 	f_mod_no=f=q->first_to_check;
 	/* 
@@ -484,7 +741,7 @@
 		QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
 
 		/* kind of process the buffer */
-		set_slsb(&q->slsb.acc.val[f_mod_no], SLSB_P_OUTPUT_NOT_INIT);
+		set_slsb(q, &f_mod_no, SLSB_P_OUTPUT_NOT_INIT, &count);
 
 		/* 
 		 * we increment the frontier, as this buffer
@@ -597,48 +854,48 @@
 
 	result=qdio_siga_output(q);
 
-		switch (result) {
-		case 0:
-			/* went smooth this time, reset timestamp */
+	switch (result) {
+	case 0:
+		/* went smooth this time, reset timestamp */
 #ifdef CONFIG_QDIO_DEBUG
-			QDIO_DBF_TEXT3(0,trace,"cc2reslv");
-			sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no,
-				atomic_read(&q->busy_siga_counter));
-			QDIO_DBF_TEXT3(0,trace,dbf_text);
+		QDIO_DBF_TEXT3(0,trace,"cc2reslv");
+		sprintf(dbf_text,"%4x%2x%2x",q->schid.sch_no,q->q_no,
+			atomic_read(&q->busy_siga_counter));
+		QDIO_DBF_TEXT3(0,trace,dbf_text);
 #endif /* CONFIG_QDIO_DEBUG */
-			q->timing.busy_start=0;
+		q->timing.busy_start=0;
+		break;
+	case (2|QDIO_SIGA_ERROR_B_BIT_SET):
+		/* cc=2 and busy bit: */
+		atomic_inc(&q->busy_siga_counter);
+
+		/* if the last siga was successful, save
+		 * timestamp here */
+		if (!q->timing.busy_start)
+			q->timing.busy_start=NOW;
+
+		/* if we're in time, don't touch error_status_flags
+		 * and siga_error */
+		if (NOW-q->timing.busy_start<QDIO_BUSY_BIT_GIVE_UP) {
+			qdio_mark_q(q);
 			break;
-		case (2|QDIO_SIGA_ERROR_B_BIT_SET):
-			/* cc=2 and busy bit: */
-			atomic_inc(&q->busy_siga_counter);
-
-			/* if the last siga was successful, save
-			 * timestamp here */
-			if (!q->timing.busy_start)
-				q->timing.busy_start=NOW;
-
-			/* if we're in time, don't touch error_status_flags
-			 * and siga_error */
-			if (NOW-q->timing.busy_start<QDIO_BUSY_BIT_GIVE_UP) {
-				qdio_mark_q(q);
-				break;
-			}
-			QDIO_DBF_TEXT2(0,trace,"cc2REPRT");
-#ifdef CONFIG_QDIO_DEBUG
-			sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no,
-				atomic_read(&q->busy_siga_counter));
-			QDIO_DBF_TEXT3(0,trace,dbf_text);
-#endif /* CONFIG_QDIO_DEBUG */
-			/* else fallthrough and report error */
-		default:
-			/* for plain cc=1, 2 or 3: */
-			if (q->siga_error)
-				q->error_status_flags|=
-					QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
-			q->error_status_flags|=
-				QDIO_STATUS_LOOK_FOR_ERROR;
-			q->siga_error=result;
 		}
+		QDIO_DBF_TEXT2(0,trace,"cc2REPRT");
+#ifdef CONFIG_QDIO_DEBUG
+		sprintf(dbf_text,"%4x%2x%2x",q->schid.sch_no,q->q_no,
+			atomic_read(&q->busy_siga_counter));
+		QDIO_DBF_TEXT3(0,trace,dbf_text);
+#endif /* CONFIG_QDIO_DEBUG */
+		/* else fallthrough and report error */
+	default:
+		/* for plain cc=1, 2 or 3: */
+		if (q->siga_error)
+			q->error_status_flags|=
+				QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR;
+		q->error_status_flags|=
+			QDIO_STATUS_LOOK_FOR_ERROR;
+		q->siga_error=result;
+	}
 }
 
 static inline void
@@ -743,8 +1000,10 @@
 static inline int
 qdio_get_inbound_buffer_frontier(struct qdio_q *q)
 {
+	struct qdio_irq *irq;
 	int f,f_mod_no;
 	volatile char *slsb;
+	unsigned int count = 1;
 	int first_not_to_check;
 #ifdef CONFIG_QDIO_DEBUG
 	char dbf_text[15];
@@ -756,6 +1015,10 @@
 	QDIO_DBF_TEXT4(0,trace,"getibfro");
 	QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
 
+	irq = (struct qdio_irq *) q->irq_ptr;
+	if (irq->is_qebsm)
+		return qdio_qebsm_get_inbound_buffer_frontier(q);
+
 	slsb=&q->slsb.acc.val[0];
 	f_mod_no=f=q->first_to_check;
 	/* 
@@ -792,19 +1055,19 @@
 		 * kill VM in terms of CP overhead 
 		 */
 		if (q->siga_sync) {
-			set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
+			set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count);
 		} else {
 			/* set the previous buffer to NOT_INIT. The current
 			 * buffer will be set to PROCESSING at the end of
 			 * this function to avoid further interrupts. */
 			if (last_position>=0)
-				set_slsb(&slsb[last_position],
-					 SLSB_P_INPUT_NOT_INIT);
+				set_slsb(q, &last_position,
+					 SLSB_P_INPUT_NOT_INIT, &count);
 			atomic_set(&q->polling,1);
 			last_position=f_mod_no;
 		}
 #else /* QDIO_USE_PROCESSING_STATE */
-		set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
+		set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count);
 #endif /* QDIO_USE_PROCESSING_STATE */
 		/* 
 		 * not needed, as the inbound queue will be synced on the next
@@ -829,7 +1092,7 @@
 		QDIO_DBF_HEX2(1,sbal,q->sbal[f_mod_no],256);
 
 		/* kind of process the buffer */
-		set_slsb(&slsb[f_mod_no],SLSB_P_INPUT_NOT_INIT);
+		set_slsb(q, &f_mod_no, SLSB_P_INPUT_NOT_INIT, &count);
 
 		if (q->qdio_error)
 			q->error_status_flags|=
@@ -857,7 +1120,7 @@
 
 #ifdef QDIO_USE_PROCESSING_STATE
 	if (last_position>=0)
-		set_slsb(&slsb[last_position],SLSB_P_INPUT_PROCESSING);
+		set_slsb(q, &last_position, SLSB_P_INPUT_NOT_INIT, &count);
 #endif /* QDIO_USE_PROCESSING_STATE */
 
 	QDIO_DBF_HEX4(0,trace,&q->first_to_check,sizeof(int));
@@ -902,6 +1165,10 @@
 tiqdio_is_inbound_q_done(struct qdio_q *q)
 {
 	int no_used;
+	unsigned int start_buf, count;
+	unsigned char state = 0;
+	struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
+
 #ifdef CONFIG_QDIO_DEBUG
 	char dbf_text[15];
 #endif
@@ -927,8 +1194,13 @@
 	if (!q->siga_sync)
 		/* we'll check for more primed buffers in qeth_stop_polling */
 		return 0;
-
-	if (q->slsb.acc.val[q->first_to_check]!=SLSB_P_INPUT_PRIMED)
+	if (irq->is_qebsm) {
+		count = 1;
+		start_buf = q->first_to_check;
+		qdio_do_eqbs(q, &state, &start_buf, &count);
+	} else
+		state = q->slsb.acc.val[q->first_to_check];
+	if (state != SLSB_P_INPUT_PRIMED)
 		/* 
 		 * nothing more to do, if next buffer is not PRIMED.
 		 * note that we did a SYNC_MEMORY before, that there
@@ -955,6 +1227,10 @@
 qdio_is_inbound_q_done(struct qdio_q *q)
 {
 	int no_used;
+	unsigned int start_buf, count;
+	unsigned char state = 0;
+	struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
+
 #ifdef CONFIG_QDIO_DEBUG
 	char dbf_text[15];
 #endif
@@ -973,8 +1249,13 @@
 		QDIO_DBF_TEXT4(0,trace,dbf_text);
 		return 1;
 	}
-
-	if (q->slsb.acc.val[q->first_to_check]==SLSB_P_INPUT_PRIMED) {
+	if (irq->is_qebsm) {
+		count = 1;
+		start_buf = q->first_to_check;
+		qdio_do_eqbs(q, &state, &start_buf, &count);
+	} else
+		state = q->slsb.acc.val[q->first_to_check];
+	if (state == SLSB_P_INPUT_PRIMED) {
 		/* we got something to do */
 		QDIO_DBF_TEXT4(0,trace,"inqisntA");
 		QDIO_DBF_HEX4(0,trace,&q,sizeof(void*));
@@ -1456,7 +1737,7 @@
 	void *ptr;
 	int available;
 
-	sprintf(dbf_text,"qfqs%4x",cdev->private->irq);
+	sprintf(dbf_text,"qfqs%4x",cdev->private->sch_no);
 	QDIO_DBF_TEXT0(0,setup,dbf_text);
 	for (i=0;i<no_input_qs;i++) {
 		q=irq_ptr->input_qs[i];
@@ -1476,7 +1757,7 @@
 
                 q->queue_type=q_format;
 		q->int_parm=int_parm;
-		q->irq=irq_ptr->irq;
+		q->schid = irq_ptr->schid;
 		q->irq_ptr = irq_ptr;
 		q->cdev = cdev;
 		q->mask=1<<(31-i);
@@ -1523,11 +1804,11 @@
 		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
 
 		/* fill in slsb */
-		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-			set_slsb(&q->slsb.acc.val[j],
-		   		 SLSB_P_INPUT_NOT_INIT);
-/*			q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/
-		}
+		if (!irq_ptr->is_qebsm) {
+                        unsigned int count = 1;
+                        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++)
+                                set_slsb(q, &j, SLSB_P_INPUT_NOT_INIT, &count);
+                }
 	}
 
 	for (i=0;i<no_output_qs;i++) {
@@ -1549,7 +1830,7 @@
                 q->queue_type=q_format;
 		q->int_parm=int_parm;
 		q->is_input_q=0;
-		q->irq=irq_ptr->irq;
+		q->schid = irq_ptr->schid;
 		q->cdev = cdev;
 		q->irq_ptr = irq_ptr;
 		q->mask=1<<(31-i);
@@ -1584,11 +1865,11 @@
 		QDIO_DBF_HEX2(0,setup,&ptr,sizeof(void*));
 
 		/* fill in slsb */
-		for (j=0;j<QDIO_MAX_BUFFERS_PER_Q;j++) {
-			set_slsb(&q->slsb.acc.val[j],
-		   		 SLSB_P_OUTPUT_NOT_INIT);
-/*			q->sbal[j]->element[1].sbalf.i1.key=QDIO_STORAGE_KEY;*/
-		}
+                if (!irq_ptr->is_qebsm) {
+                        unsigned int count = 1;
+                        for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++)
+                                set_slsb(q, &j, SLSB_P_OUTPUT_NOT_INIT, &count);
+                }
 	}
 }
 
@@ -1656,7 +1937,7 @@
 	char dbf_text[15];
 
 	QDIO_DBF_TEXT5(0,trace,"newstate");
-	sprintf(dbf_text,"%4x%4x",irq_ptr->irq,state);
+	sprintf(dbf_text,"%4x%4x",irq_ptr->schid.sch_no,state);
 	QDIO_DBF_TEXT5(0,trace,dbf_text);
 #endif /* CONFIG_QDIO_DEBUG */
 
@@ -1669,12 +1950,12 @@
 }
 
 static inline void
-qdio_irq_check_sense(int irq, struct irb *irb)
+qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
 {
 	char dbf_text[15];
 
 	if (irb->esw.esw0.erw.cons) {
-		sprintf(dbf_text,"sens%4x",irq);
+		sprintf(dbf_text,"sens%4x",schid.sch_no);
 		QDIO_DBF_TEXT2(1,trace,dbf_text);
 		QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN);
 
@@ -1785,21 +2066,22 @@
 
 	switch (irq_ptr->state) {
 	case QDIO_IRQ_STATE_INACTIVE:
-		QDIO_PRINT_ERR("establish queues on irq %04x: timed out\n",
-			       irq_ptr->irq);
+		QDIO_PRINT_ERR("establish queues on irq 0.%x.%04x: timed out\n",
+			       irq_ptr->schid.ssid, irq_ptr->schid.sch_no);
 		QDIO_DBF_TEXT2(1,setup,"eq:timeo");
 		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
 		break;
 	case QDIO_IRQ_STATE_CLEANUP:
-		QDIO_PRINT_INFO("Did not get interrupt on cleanup, irq=0x%x.\n",
-				irq_ptr->irq);
+		QDIO_PRINT_INFO("Did not get interrupt on cleanup, "
+				"irq=0.%x.%x.\n",
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no);
 		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
 		break;
 	case QDIO_IRQ_STATE_ESTABLISHED:
 	case QDIO_IRQ_STATE_ACTIVE:
 		/* I/O has been terminated by common I/O layer. */
-		QDIO_PRINT_INFO("Queues on irq %04x killed by cio.\n",
-				irq_ptr->irq);
+		QDIO_PRINT_INFO("Queues on irq 0.%x.%04x killed by cio.\n",
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no);
 		QDIO_DBF_TEXT2(1, trace, "cio:term");
 		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
 		if (get_device(&cdev->dev)) {
@@ -1862,7 +2144,7 @@
 		}
 	}
 
-	qdio_irq_check_sense(irq_ptr->irq, irb);
+	qdio_irq_check_sense(irq_ptr->schid, irb);
 
 #ifdef CONFIG_QDIO_DEBUG
 	sprintf(dbf_text, "state:%d", irq_ptr->state);
@@ -1905,7 +2187,7 @@
 qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
 		 unsigned int queue_number)
 {
-	int cc;
+	int cc = 0;
 	struct qdio_q *q;
 	struct qdio_irq *irq_ptr;
 	void *ptr;
@@ -1918,7 +2200,7 @@
 		return -ENODEV;
 
 #ifdef CONFIG_QDIO_DEBUG
-	*((int*)(&dbf_text[4])) = irq_ptr->irq;
+	*((int*)(&dbf_text[4])) = irq_ptr->schid.sch_no;
 	QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
 	*((int*)(&dbf_text[0]))=flags;
 	*((int*)(&dbf_text[4]))=queue_number;
@@ -1929,12 +2211,14 @@
 		q=irq_ptr->input_qs[queue_number];
 		if (!q)
 			return -EINVAL;
-		cc = do_siga_sync(q->irq, 0, q->mask);
+		if (!(irq_ptr->is_qebsm))
+			cc = do_siga_sync(q->schid, 0, q->mask);
 	} else if (flags&QDIO_FLAG_SYNC_OUTPUT) {
 		q=irq_ptr->output_qs[queue_number];
 		if (!q)
 			return -EINVAL;
-		cc = do_siga_sync(q->irq, q->mask, 0);
+		if (!(irq_ptr->is_qebsm))
+			cc = do_siga_sync(q->schid, q->mask, 0);
 	} else 
 		return -EINVAL;
 
@@ -1945,15 +2229,54 @@
 	return cc;
 }
 
-static unsigned char
-qdio_check_siga_needs(int sch)
+static inline void
+qdio_check_subchannel_qebsm(struct qdio_irq *irq_ptr, unsigned char qdioac,
+			    unsigned long token)
+{
+	struct qdio_q *q;
+	int i;
+	unsigned int count, start_buf;
+	char dbf_text[15];
+
+	/*check if QEBSM is disabled */
+	if (!(irq_ptr->is_qebsm) || !(qdioac & 0x01)) {
+		irq_ptr->is_qebsm  = 0;
+		irq_ptr->sch_token = 0;
+		irq_ptr->qib.rflags &= ~QIB_RFLAGS_ENABLE_QEBSM;
+		QDIO_DBF_TEXT0(0,setup,"noV=V");
+		return;
+	}
+	irq_ptr->sch_token = token;
+	/*input queue*/
+	for (i = 0; i < irq_ptr->no_input_qs;i++) {
+		q = irq_ptr->input_qs[i];
+		count = QDIO_MAX_BUFFERS_PER_Q;
+		start_buf = 0;
+		set_slsb(q, &start_buf, SLSB_P_INPUT_NOT_INIT, &count);
+	}
+	sprintf(dbf_text,"V=V:%2x",irq_ptr->is_qebsm);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	sprintf(dbf_text,"%8lx",irq_ptr->sch_token);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+	/*output queue*/
+	for (i = 0; i < irq_ptr->no_output_qs; i++) {
+		q = irq_ptr->output_qs[i];
+		count = QDIO_MAX_BUFFERS_PER_Q;
+		start_buf = 0;
+		set_slsb(q, &start_buf, SLSB_P_OUTPUT_NOT_INIT, &count);
+	}
+}
+
+static void
+qdio_get_ssqd_information(struct qdio_irq *irq_ptr)
 {
 	int result;
 	unsigned char qdioac;
-
 	struct {
 		struct chsc_header request;
-		u16 reserved1;
+		u16 reserved1:10;
+		u16 ssid:2;
+		u16 fmt:4;
 		u16 first_sch;
 		u16 reserved2;
 		u16 last_sch;
@@ -1964,67 +2287,83 @@
 		u8  reserved5;
 		u16 sch;
 		u8  qfmt;
-		u8  reserved6;
-		u8  qdioac;
+		u8  parm;
+		u8  qdioac1;
 		u8  sch_class;
 		u8  reserved7;
 		u8  icnt;
 		u8  reserved8;
 		u8  ocnt;
+		u8 reserved9;
+		u8 mbccnt;
+		u16 qdioac2;
+		u64 sch_token;
 	} *ssqd_area;
 
+	QDIO_DBF_TEXT0(0,setup,"getssqd");
+	qdioac = 0;
 	ssqd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
 	if (!ssqd_area) {
 	        QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \
-				"SIGAs for sch x%x.\n", sch);
-		return CHSC_FLAG_SIGA_INPUT_NECESSARY ||
-			CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
-			CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
+				"SIGAs for sch x%x.\n", irq_ptr->schid.sch_no);
+		irq_ptr->qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY ||
+				  CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
+				  CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
+		irq_ptr->is_qebsm = 0;
+		irq_ptr->sch_token = 0;
+		irq_ptr->qib.rflags &= ~QIB_RFLAGS_ENABLE_QEBSM;
+		return;
 	}
+
 	ssqd_area->request = (struct chsc_header) {
 		.length = 0x0010,
 		.code   = 0x0024,
 	};
-
-	ssqd_area->first_sch = sch;
-	ssqd_area->last_sch = sch;
-
-	result=chsc(ssqd_area);
+	ssqd_area->first_sch = irq_ptr->schid.sch_no;
+	ssqd_area->last_sch = irq_ptr->schid.sch_no;
+	ssqd_area->ssid = irq_ptr->schid.ssid;
+	result = chsc(ssqd_area);
 
 	if (result) {
 		QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \
-				"SIGAs for sch x%x.\n",
-				result,sch);
+				"SIGAs for sch 0.%x.%x.\n", result,
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no);
 		qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY ||
 			CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
 			CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
+		irq_ptr->is_qebsm  = 0;
 		goto out;
 	}
 
 	if (ssqd_area->response.code != QDIO_CHSC_RESPONSE_CODE_OK) {
 		QDIO_PRINT_WARN("response upon checking SIGA needs " \
-				"is 0x%x. Using all SIGAs for sch x%x.\n",
-				ssqd_area->response.code, sch);
+				"is 0x%x. Using all SIGAs for sch 0.%x.%x.\n",
+				ssqd_area->response.code,
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no);
 		qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY ||
 			CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
 			CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
+		irq_ptr->is_qebsm  = 0;
 		goto out;
 	}
 	if (!(ssqd_area->flags & CHSC_FLAG_QDIO_CAPABILITY) ||
 	    !(ssqd_area->flags & CHSC_FLAG_VALIDITY) ||
-	    (ssqd_area->sch != sch)) {
-		QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \
-				"using all SIGAs.\n",sch);
+	    (ssqd_area->sch != irq_ptr->schid.sch_no)) {
+		QDIO_PRINT_WARN("huh? problems checking out sch 0.%x.%x... " \
+				"using all SIGAs.\n",
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no);
 		qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY |
 			CHSC_FLAG_SIGA_OUTPUT_NECESSARY |
 			CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */
+		irq_ptr->is_qebsm  = 0;
 		goto out;
 	}
-
-	qdioac = ssqd_area->qdioac;
+	qdioac = ssqd_area->qdioac1;
 out:
+	qdio_check_subchannel_qebsm(irq_ptr, qdioac,
+				    ssqd_area->sch_token);
 	free_page ((unsigned long) ssqd_area);
-	return qdioac;
+	irq_ptr->qdioac = qdioac;
 }
 
 static unsigned int
@@ -2055,6 +2394,13 @@
 	sprintf(dbf_text,"hydrati%1x", hydra_thinints);
 	QDIO_DBF_TEXT0(0,setup,dbf_text);
 
+#ifdef CONFIG_64BIT
+	/* Check for QEBSM support in general (bit 58). */
+	is_passthrough = css_general_characteristics.qebsm;
+#endif
+	sprintf(dbf_text,"cssQBS:%1x", is_passthrough);
+	QDIO_DBF_TEXT0(0,setup,dbf_text);
+
 	/* Check for aif time delay disablement fac (bit 56). If installed,
 	 * omit svs even under lpar (good point by rick again) */
 	omit_svs = css_general_characteristics.aif_tdd;
@@ -2091,7 +2437,7 @@
 		/* set to 0x10000000 to enable
 		 * time delay disablement facility */
 		u32 reserved5;
-		u32 subsystem_id;
+		struct subchannel_id schid;
 		u32 reserved6[1004];
 		struct chsc_header response;
 		u32 reserved7;
@@ -2113,7 +2459,8 @@
 	scssc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
 	if (!scssc_area) {
 		QDIO_PRINT_WARN("No memory for setting indicators on " \
-				"subchannel x%x.\n", irq_ptr->irq);
+				"subchannel 0.%x.%x.\n",
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no);
 		return -ENOMEM;
 	}
 	scssc_area->request = (struct chsc_header) {
@@ -2127,7 +2474,7 @@
 	scssc_area->ks = QDIO_STORAGE_KEY;
 	scssc_area->kc = QDIO_STORAGE_KEY;
 	scssc_area->isc = TIQDIO_THININT_ISC;
-	scssc_area->subsystem_id = (1<<16) + irq_ptr->irq;
+	scssc_area->schid = irq_ptr->schid;
 	/* enables the time delay disablement facility. Don't care
 	 * whether it is really there (i.e. we haven't checked for
 	 * it) */
@@ -2137,12 +2484,11 @@
 		QDIO_PRINT_WARN("Time delay disablement facility " \
 				"not available\n");
 
-
-
 	result = chsc(scssc_area);
 	if (result) {
-		QDIO_PRINT_WARN("could not set indicators on irq x%x, " \
-				"cc=%i.\n",irq_ptr->irq,result);
+		QDIO_PRINT_WARN("could not set indicators on irq 0.%x.%x, " \
+				"cc=%i.\n",
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no,result);
 		result = -EIO;
 		goto out;
 	}
@@ -2198,7 +2544,8 @@
 	scsscf_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
 	if (!scsscf_area) {
 		QDIO_PRINT_WARN("No memory for setting delay target on " \
-				"subchannel x%x.\n", irq_ptr->irq);
+				"subchannel 0.%x.%x.\n",
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no);
 		return -ENOMEM;
 	}
 	scsscf_area->request = (struct chsc_header) {
@@ -2210,8 +2557,10 @@
 
 	result=chsc(scsscf_area);
 	if (result) {
-		QDIO_PRINT_WARN("could not set delay target on irq x%x, " \
-				"cc=%i. Continuing.\n",irq_ptr->irq,result);
+		QDIO_PRINT_WARN("could not set delay target on irq 0.%x.%x, " \
+				"cc=%i. Continuing.\n",
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no,
+				result);
 		result = -EIO;
 		goto out;
 	}
@@ -2245,7 +2594,7 @@
 	if (!irq_ptr)
 		return -ENODEV;
 
-	sprintf(dbf_text,"qcln%4x",irq_ptr->irq);
+	sprintf(dbf_text,"qcln%4x",irq_ptr->schid.sch_no);
 	QDIO_DBF_TEXT1(0,trace,dbf_text);
 	QDIO_DBF_TEXT0(0,setup,dbf_text);
 
@@ -2272,7 +2621,7 @@
 
 	down(&irq_ptr->setting_up_sema);
 
-	sprintf(dbf_text,"qsqs%4x",irq_ptr->irq);
+	sprintf(dbf_text,"qsqs%4x",irq_ptr->schid.sch_no);
 	QDIO_DBF_TEXT1(0,trace,dbf_text);
 	QDIO_DBF_TEXT0(0,setup,dbf_text);
 
@@ -2378,7 +2727,7 @@
 
 	down(&irq_ptr->setting_up_sema);
 
-	sprintf(dbf_text,"qfqs%4x",irq_ptr->irq);
+	sprintf(dbf_text,"qfqs%4x",irq_ptr->schid.sch_no);
 	QDIO_DBF_TEXT1(0,trace,dbf_text);
 	QDIO_DBF_TEXT0(0,setup,dbf_text);
 
@@ -2526,13 +2875,14 @@
 	irq_ptr = cdev->private->qdio_data;
 
 	if (cstat || (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END))) {
-		sprintf(dbf_text,"ick1%4x",irq_ptr->irq);
+		sprintf(dbf_text,"ick1%4x",irq_ptr->schid.sch_no);
 		QDIO_DBF_TEXT2(1,trace,dbf_text);
 		QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int));
 		QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int));
 		QDIO_PRINT_ERR("received check condition on establish " \
-			       "queues on irq 0x%x (cs=x%x, ds=x%x).\n",
-			       irq_ptr->irq,cstat,dstat);
+			       "queues on irq 0.%x.%x (cs=x%x, ds=x%x).\n",
+			       irq_ptr->schid.ssid, irq_ptr->schid.sch_no,
+			       cstat,dstat);
 		qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ERR);
 	}
 	
@@ -2540,9 +2890,10 @@
 		QDIO_DBF_TEXT2(1,setup,"eq:no de");
 		QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat));
 		QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat));
-		QDIO_PRINT_ERR("establish queues on irq %04x: didn't get "
+		QDIO_PRINT_ERR("establish queues on irq 0.%x.%04x: didn't get "
 			       "device end: dstat=%02x, cstat=%02x\n",
-			       irq_ptr->irq, dstat, cstat);
+			       irq_ptr->schid.ssid, irq_ptr->schid.sch_no,
+			       dstat, cstat);
 		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
 		return 1;
 	}
@@ -2551,10 +2902,10 @@
 		QDIO_DBF_TEXT2(1,setup,"eq:badio");
 		QDIO_DBF_HEX2(0,setup,&dstat, sizeof(dstat));
 		QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat));
-		QDIO_PRINT_ERR("establish queues on irq %04x: got "
+		QDIO_PRINT_ERR("establish queues on irq 0.%x.%04x: got "
 			       "the following devstat: dstat=%02x, "
-			       "cstat=%02x\n",
-			       irq_ptr->irq, dstat, cstat);
+			       "cstat=%02x\n", irq_ptr->schid.ssid,
+			       irq_ptr->schid.sch_no, dstat, cstat);
 		qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
 		return 1;
 	}
@@ -2569,7 +2920,7 @@
 
 	irq_ptr = cdev->private->qdio_data;
 
-	sprintf(dbf_text,"qehi%4x",cdev->private->irq);
+	sprintf(dbf_text,"qehi%4x",cdev->private->sch_no);
 	QDIO_DBF_TEXT0(0,setup,dbf_text);
 	QDIO_DBF_TEXT0(0,trace,dbf_text);
 
@@ -2588,7 +2939,7 @@
 	int rc;
 	char dbf_text[15];
 
-	sprintf(dbf_text,"qini%4x",init_data->cdev->private->irq);
+	sprintf(dbf_text,"qini%4x",init_data->cdev->private->sch_no);
 	QDIO_DBF_TEXT0(0,setup,dbf_text);
 	QDIO_DBF_TEXT0(0,trace,dbf_text);
 
@@ -2609,7 +2960,7 @@
 	struct qdio_irq *irq_ptr;
 	char dbf_text[15];
 
-	sprintf(dbf_text,"qalc%4x",init_data->cdev->private->irq);
+	sprintf(dbf_text,"qalc%4x",init_data->cdev->private->sch_no);
 	QDIO_DBF_TEXT0(0,setup,dbf_text);
 	QDIO_DBF_TEXT0(0,trace,dbf_text);
 	if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) ||
@@ -2682,7 +3033,7 @@
 
 	irq_ptr->int_parm=init_data->int_parm;
 
-	irq_ptr->irq = init_data->cdev->private->irq;
+	irq_ptr->schid = ccw_device_get_subchannel_id(init_data->cdev);
 	irq_ptr->no_input_qs=init_data->no_input_qs;
 	irq_ptr->no_output_qs=init_data->no_output_qs;
 
@@ -2698,11 +3049,12 @@
 	QDIO_DBF_TEXT2(0,setup,dbf_text);
 
 	if (irq_ptr->is_thinint_irq) {
-		irq_ptr->dev_st_chg_ind=qdio_get_indicator();
+		irq_ptr->dev_st_chg_ind = qdio_get_indicator();
 		QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*));
 		if (!irq_ptr->dev_st_chg_ind) {
 			QDIO_PRINT_WARN("no indicator location available " \
-					"for irq 0x%x\n",irq_ptr->irq);
+					"for irq 0.%x.%x\n",
+					irq_ptr->schid.ssid, irq_ptr->schid.sch_no);
 			qdio_release_irq_memory(irq_ptr);
 			return -ENOBUFS;
 		}
@@ -2747,6 +3099,10 @@
 	irq_ptr->qdr->qkey=QDIO_STORAGE_KEY;
 
 	/* fill in qib */
+	irq_ptr->is_qebsm = is_passthrough;
+	if (irq_ptr->is_qebsm)
+		irq_ptr->qib.rflags |= QIB_RFLAGS_ENABLE_QEBSM;
+
 	irq_ptr->qib.qfmt=init_data->q_format;
 	if (init_data->no_input_qs)
 		irq_ptr->qib.isliba=(unsigned long)(irq_ptr->input_qs[0]->slib);
@@ -2829,7 +3185,7 @@
 		tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET);
 	}
 
-	sprintf(dbf_text,"qest%4x",cdev->private->irq);
+	sprintf(dbf_text,"qest%4x",cdev->private->sch_no);
 	QDIO_DBF_TEXT0(0,setup,dbf_text);
 	QDIO_DBF_TEXT0(0,trace,dbf_text);
 
@@ -2855,9 +3211,10 @@
 			sprintf(dbf_text,"eq:io%4x",result);
 			QDIO_DBF_TEXT2(1,setup,dbf_text);
 		}
-		QDIO_PRINT_WARN("establish queues on irq %04x: do_IO " \
-                           "returned %i, next try returned %i\n",
-                           irq_ptr->irq,result,result2);
+		QDIO_PRINT_WARN("establish queues on irq 0.%x.%04x: do_IO " \
+				"returned %i, next try returned %i\n",
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no,
+				result, result2);
 		result=result2;
 		if (result)
 			ccw_device_set_timeout(cdev, 0);
@@ -2884,7 +3241,7 @@
 		return -EIO;
 	}
 
-	irq_ptr->qdioac=qdio_check_siga_needs(irq_ptr->irq);
+	qdio_get_ssqd_information(irq_ptr);
 	/* if this gets set once, we're running under VM and can omit SVSes */
 	if (irq_ptr->qdioac&CHSC_FLAG_SIGA_SYNC_NECESSARY)
 		omit_svs=1;
@@ -2930,7 +3287,7 @@
 		goto out;
 	}
 
-	sprintf(dbf_text,"qact%4x", irq_ptr->irq);
+	sprintf(dbf_text,"qact%4x", irq_ptr->schid.sch_no);
 	QDIO_DBF_TEXT2(0,setup,dbf_text);
 	QDIO_DBF_TEXT2(0,trace,dbf_text);
 
@@ -2955,9 +3312,10 @@
 			sprintf(dbf_text,"aq:io%4x",result);
 			QDIO_DBF_TEXT2(1,setup,dbf_text);
 		}
-		QDIO_PRINT_WARN("activate queues on irq %04x: do_IO " \
-                           "returned %i, next try returned %i\n",
-                           irq_ptr->irq,result,result2);
+		QDIO_PRINT_WARN("activate queues on irq 0.%x.%04x: do_IO " \
+				"returned %i, next try returned %i\n",
+				irq_ptr->schid.ssid, irq_ptr->schid.sch_no,
+				result, result2);
 		result=result2;
 	}
 
@@ -3015,30 +3373,40 @@
 qdio_do_qdio_fill_input(struct qdio_q *q, unsigned int qidx,
 			unsigned int count, struct qdio_buffer *buffers)
 {
+	struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
+	qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1);
+	if (irq->is_qebsm) {
+		while (count)
+			set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count);
+		return;
+	}
 	for (;;) {
-		set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_INPUT_EMPTY);
+		set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count);
 		count--;
 		if (!count) break;
-		qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
+		qidx = (qidx + 1) & (QDIO_MAX_BUFFERS_PER_Q - 1);
 	}
-
-	/* not necessary, as the queues are synced during the SIGA read */
-	/*SYNC_MEMORY;*/
 }
 
 static inline void
 qdio_do_qdio_fill_output(struct qdio_q *q, unsigned int qidx,
 			 unsigned int count, struct qdio_buffer *buffers)
 {
-	for (;;) {
-		set_slsb(&q->slsb.acc.val[qidx],SLSB_CU_OUTPUT_PRIMED);
-		count--;
-		if (!count) break;
-		qidx=(qidx+1)&(QDIO_MAX_BUFFERS_PER_Q-1);
+	struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
+
+	qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1);
+	if (irq->is_qebsm) {
+		while (count)
+			set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count);
+		return;
 	}
 
-	/* SIGA write will sync the queues */
-	/*SYNC_MEMORY;*/
+	for (;;) {
+		set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count);
+		count--;
+		if (!count) break;
+		qidx = (qidx + 1) & (QDIO_MAX_BUFFERS_PER_Q - 1);
+	}
 }
 
 static inline void
@@ -3083,6 +3451,9 @@
 			struct qdio_buffer *buffers)
 {
 	int used_elements;
+	unsigned int cnt, start_buf;
+	unsigned char state = 0;
+	struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
 
 	/* This is the outbound handling of queues */
 #ifdef QDIO_PERFORMANCE_STATS
@@ -3115,9 +3486,15 @@
 			 * SYNC_MEMORY :-/ ), we try to
 			 * fast-requeue buffers 
 			 */
-			if (q->slsb.acc.val[(qidx+QDIO_MAX_BUFFERS_PER_Q-1)
-					    &(QDIO_MAX_BUFFERS_PER_Q-1)]!=
-			    SLSB_CU_OUTPUT_PRIMED) {
+			if (irq->is_qebsm) {
+				cnt = 1;
+				start_buf = ((qidx+QDIO_MAX_BUFFERS_PER_Q-1) &
+					     (QDIO_MAX_BUFFERS_PER_Q-1));
+				qdio_do_eqbs(q, &state, &start_buf, &cnt);
+			} else
+				state = q->slsb.acc.val[(qidx+QDIO_MAX_BUFFERS_PER_Q-1)
+					&(QDIO_MAX_BUFFERS_PER_Q-1) ];
+			 if (state != SLSB_CU_OUTPUT_PRIMED) {
 				qdio_kick_outbound_q(q);
 			} else {
 				QDIO_DBF_TEXT3(0,trace, "fast-req");
@@ -3150,7 +3527,7 @@
 #ifdef CONFIG_QDIO_DEBUG
 	char dbf_text[20];
 
-	sprintf(dbf_text,"doQD%04x",cdev->private->irq);
+	sprintf(dbf_text,"doQD%04x",cdev->private->sch_no);
  	QDIO_DBF_TEXT3(0,trace,dbf_text);
 #endif /* CONFIG_QDIO_DEBUG */
 
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 328e31c..fa385e7 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -3,14 +3,15 @@
 
 #include <asm/page.h>
 
-#define VERSION_CIO_QDIO_H "$Revision: 1.33 $"
+#include "schid.h"
+
+#define VERSION_CIO_QDIO_H "$Revision: 1.40 $"
 
 #ifdef CONFIG_QDIO_DEBUG
 #define QDIO_VERBOSE_LEVEL 9
 #else /* CONFIG_QDIO_DEBUG */
 #define QDIO_VERBOSE_LEVEL 5
 #endif /* CONFIG_QDIO_DEBUG */
-
 #define QDIO_USE_PROCESSING_STATE
 
 #ifdef CONFIG_QDIO_PERF_STATS
@@ -265,12 +266,64 @@
 /*
  * Some instructions as assembly
  */
+
 static inline int
-do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
+do_sqbs(unsigned long sch, unsigned char state, int queue,
+       unsigned int *start, unsigned int *count)
+{
+#ifdef CONFIG_64BIT
+       register unsigned long _ccq asm ("0") = *count;
+       register unsigned long _sch asm ("1") = sch;
+       unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
+
+       asm volatile (
+              " .insn rsy,0xeb000000008A,%1,0,0(%2)\n\t"
+              : "+d" (_ccq), "+d" (_queuestart)
+              : "d" ((unsigned long)state), "d" (_sch)
+              : "memory", "cc"
+       );
+       *count = _ccq & 0xff;
+       *start = _queuestart & 0xff;
+
+       return (_ccq >> 32) & 0xff;
+#else
+       return 0;
+#endif
+}
+
+static inline int
+do_eqbs(unsigned long sch, unsigned char *state, int queue,
+	unsigned int *start, unsigned int *count)
+{
+#ifdef CONFIG_64BIT
+	register unsigned long _ccq asm ("0") = *count;
+	register unsigned long _sch asm ("1") = sch;
+	unsigned long _queuestart = ((unsigned long)queue << 32) | *start;
+	unsigned long _state = 0;
+
+	asm volatile (
+	      " .insn rrf,0xB99c0000,%1,%2,0,0  \n\t"
+	      : "+d" (_ccq), "+d" (_queuestart), "+d" (_state)
+	      : "d" (_sch)
+	      : "memory", "cc"
+	);
+	*count = _ccq & 0xff;
+	*start = _queuestart & 0xff;
+	*state = _state & 0xff;
+
+	return (_ccq >> 32) & 0xff;
+#else
+	return 0;
+#endif
+}
+
+
+static inline int
+do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2)
 {
 	int cc;
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 	asm volatile (
 		"lhi	0,2	\n\t"
 		"lr	1,%1	\n\t"
@@ -280,10 +333,10 @@
 		"ipm	%0	\n\t"
 		"srl	%0,28	\n\t"
 		: "=d" (cc)
-		: "d" (0x10000|irq), "d" (mask1), "d" (mask2)
+		: "d" (schid), "d" (mask1), "d" (mask2)
 		: "cc", "0", "1", "2", "3"
 		);
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 	asm volatile (
 		"lghi	0,2	\n\t"
 		"llgfr	1,%1	\n\t"
@@ -293,19 +346,19 @@
 		"ipm	%0	\n\t"
 		"srl	%0,28	\n\t"
 		: "=d" (cc)
-		: "d" (0x10000|irq), "d" (mask1), "d" (mask2)
+		: "d" (schid), "d" (mask1), "d" (mask2)
 		: "cc", "0", "1", "2", "3"
 		);
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 	return cc;
 }
 
 static inline int
-do_siga_input(unsigned int irq, unsigned int mask)
+do_siga_input(struct subchannel_id schid, unsigned int mask)
 {
 	int cc;
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 	asm volatile (
 		"lhi	0,1	\n\t"
 		"lr	1,%1	\n\t"
@@ -314,10 +367,10 @@
 		"ipm	%0	\n\t"
 		"srl	%0,28	\n\t"
 		: "=d" (cc)
-		: "d" (0x10000|irq), "d" (mask)
+		: "d" (schid), "d" (mask)
 		: "cc", "0", "1", "2", "memory"
 		);
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 	asm volatile (
 		"lghi	0,1	\n\t"
 		"llgfr	1,%1	\n\t"
@@ -326,21 +379,22 @@
 		"ipm	%0	\n\t"
 		"srl	%0,28	\n\t"
 		: "=d" (cc)
-		: "d" (0x10000|irq), "d" (mask)
+		: "d" (schid), "d" (mask)
 		: "cc", "0", "1", "2", "memory"
 		);
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 	
 	return cc;
 }
 
 static inline int
-do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb)
+do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb,
+	       unsigned int fc)
 {
 	int cc;
 	__u32 busy_bit;
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 	asm volatile (
 		"lhi	0,0	\n\t"
 		"lr	1,%2	\n\t"
@@ -366,14 +420,14 @@
 		".long	0b,2b	\n\t"
 		".previous	\n\t"
 		: "=d" (cc), "=d" (busy_bit)
-		: "d" (0x10000|irq), "d" (mask),
+		: "d" (schid), "d" (mask),
 		"i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
 		: "cc", "0", "1", "2", "memory"
 		);
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 	asm volatile (
-		"lghi	0,0	\n\t"
-		"llgfr	1,%2	\n\t"
+        	"llgfr  0,%5    \n\t"
+                "lgr    1,%2    \n\t"
 		"llgfr	2,%3	\n\t"
 		"siga	0	\n\t"
 		"0:"
@@ -391,11 +445,11 @@
 		".quad	0b,1b	\n\t"
 		".previous	\n\t"
 		: "=d" (cc), "=d" (busy_bit)
-		: "d" (0x10000|irq), "d" (mask),
-		"i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
+		: "d" (schid), "d" (mask),
+		"i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc)
 		: "cc", "0", "1", "2", "memory"
 		);
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 	
 	(*bb) = busy_bit;
 	return cc;
@@ -407,21 +461,21 @@
 
 	unsigned long time;
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 	asm volatile (
 		"lhi	1,3	\n\t"
 		".insn	rre,0xb2650000,2,0	\n\t"
 		"lr	%0,3	\n\t"
 		: "=d" (time) : : "cc", "1", "2", "3"
 		);
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 	asm volatile (
 		"lghi	1,3	\n\t"
 		".insn	rre,0xb2650000,2,0	\n\t"
 		"lgr	%0,3	\n\t"
 		: "=d" (time) : : "cc", "1", "2", "3"
 		);
-#endif /* CONFIG_ARCH_S390X */
+#endif /* CONFIG_64BIT */
 	
 	return time;
 }
@@ -488,42 +542,21 @@
 
 #define MY_MODULE_STRING(x) #x
 
-#ifdef CONFIG_ARCH_S390X
+#ifdef CONFIG_64BIT
 #define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x)
-#else /* CONFIG_ARCH_S390X */
+#else /* CONFIG_64BIT */
 #define QDIO_GET_ADDR(x) ((__u32)(long)x)
-#endif /* CONFIG_ARCH_S390X */
-
-#ifdef CONFIG_QDIO_DEBUG
-#define set_slsb(x,y) \
-  if(q->queue_type==QDIO_TRACE_QTYPE) { \
-        if(q->is_input_q) { \
-            QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
-        } else { \
-            QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
-        } \
-  } \
-  qdio_set_slsb(x,y); \
-  if(q->queue_type==QDIO_TRACE_QTYPE) { \
-        if(q->is_input_q) { \
-            QDIO_DBF_HEX2(0,slsb_in,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
-        } else { \
-            QDIO_DBF_HEX2(0,slsb_out,&q->slsb,QDIO_MAX_BUFFERS_PER_Q); \
-        } \
-  }
-#else /* CONFIG_QDIO_DEBUG */
-#define set_slsb(x,y) qdio_set_slsb(x,y)
-#endif /* CONFIG_QDIO_DEBUG */
+#endif /* CONFIG_64BIT */
 
 struct qdio_q {
 	volatile struct slsb slsb;
 
 	char unused[QDIO_MAX_BUFFERS_PER_Q];
 
-	__u32 * volatile dev_st_chg_ind;
+	__u32 * dev_st_chg_ind;
 
 	int is_input_q;
-	int irq;
+	struct subchannel_id schid;
 	struct ccw_device *cdev;
 
 	unsigned int is_iqdio_q;
@@ -568,6 +601,7 @@
 	struct tasklet_struct tasklet;
 #endif /* QDIO_USE_TIMERS_FOR_POLLING */
 
+
 	enum qdio_irq_states state;
 
 	/* used to store the error condition during a data transfer */
@@ -617,13 +651,17 @@
 	__u32 * volatile dev_st_chg_ind;
 
 	unsigned long int_parm;
-	int irq;
+	struct subchannel_id schid;
 
 	unsigned int is_iqdio_irq;
 	unsigned int is_thinint_irq;
 	unsigned int hydra_gives_outbound_pcis;
 	unsigned int sync_done_on_outb_pcis;
 
+	/* QEBSM facility */
+	unsigned int is_qebsm;
+	unsigned long sch_token;
+
 	enum qdio_irq_states state;
 
 	unsigned int no_input_qs;
diff --git a/drivers/s390/cio/schid.h b/drivers/s390/cio/schid.h
new file mode 100644
index 0000000..54328fe
--- /dev/null
+++ b/drivers/s390/cio/schid.h
@@ -0,0 +1,26 @@
+#ifndef S390_SCHID_H
+#define S390_SCHID_H
+
+struct subchannel_id {
+	__u32 reserved:13;
+	__u32 ssid:2;
+	__u32 one:1;
+	__u32 sch_no:16;
+} __attribute__ ((packed,aligned(4)));
+
+
+/* Helper function for sane state of pre-allocated subchannel_id. */
+static inline void
+init_subchannel_id(struct subchannel_id *schid)
+{
+	memset(schid, 0, sizeof(struct subchannel_id));
+	schid->one = 1;
+}
+
+static inline int
+schid_equal(struct subchannel_id *schid1, struct subchannel_id *schid2)
+{
+	return !memcmp(schid1, schid2, sizeof(struct subchannel_id));
+}
+
+#endif /* S390_SCHID_H */
diff --git a/drivers/s390/crypto/z90common.h b/drivers/s390/crypto/z90common.h
index e319e78..f87c785 100644
--- a/drivers/s390/crypto/z90common.h
+++ b/drivers/s390/crypto/z90common.h
@@ -1,9 +1,9 @@
 /*
  *  linux/drivers/s390/crypto/z90common.h
  *
- *  z90crypt 1.3.2
+ *  z90crypt 1.3.3
  *
- *  Copyright (C)  2001, 2004 IBM Corporation
+ *  Copyright (C)  2001, 2005 IBM Corporation
  *  Author(s): Robert Burroughs (burrough@us.ibm.com)
  *             Eric Rossman (edrossma@us.ibm.com)
  *
@@ -91,12 +91,13 @@
 #define TSQ_FATAL_ERROR 34
 #define RSQ_FATAL_ERROR 35
 
-#define Z90CRYPT_NUM_TYPES	5
+#define Z90CRYPT_NUM_TYPES	6
 #define PCICA		0
 #define PCICC		1
 #define PCIXCC_MCL2	2
 #define PCIXCC_MCL3	3
 #define CEX2C		4
+#define CEX2A		5
 #define NILDEV		-1
 #define ANYDEV		-1
 #define PCIXCC_UNK	-2
@@ -105,7 +106,7 @@
 	PCICC_HW  = 3,
 	PCICA_HW  = 4,
 	PCIXCC_HW = 5,
-	OTHER_HW  = 6,
+	CEX2A_HW  = 6,
 	CEX2C_HW  = 7
 };
 
diff --git a/drivers/s390/crypto/z90crypt.h b/drivers/s390/crypto/z90crypt.h
index 0a3bb5a..3a18443 100644
--- a/drivers/s390/crypto/z90crypt.h
+++ b/drivers/s390/crypto/z90crypt.h
@@ -1,9 +1,9 @@
 /*
  *  linux/drivers/s390/crypto/z90crypt.h
  *
- *  z90crypt 1.3.2
+ *  z90crypt 1.3.3
  *
- *  Copyright (C)  2001, 2004 IBM Corporation
+ *  Copyright (C)  2001, 2005 IBM Corporation
  *  Author(s): Robert Burroughs (burrough@us.ibm.com)
  *             Eric Rossman (edrossma@us.ibm.com)
  *
@@ -29,11 +29,11 @@
 
 #include <linux/ioctl.h>
 
-#define VERSION_Z90CRYPT_H "$Revision: 1.11 $"
+#define VERSION_Z90CRYPT_H "$Revision: 1.2.2.4 $"
 
 #define z90crypt_VERSION 1
 #define z90crypt_RELEASE 3	// 2 = PCIXCC, 3 = rewrite for coding standards
-#define z90crypt_VARIANT 2	// 2 = added PCIXCC MCL3 and CEX2C support
+#define z90crypt_VARIANT 3	// 3 = CEX2A support
 
 /**
  * struct ica_rsa_modexpo
@@ -122,6 +122,9 @@
  *   Z90STAT_CEX2CCOUNT
  *     Return an integer count of all CEX2Cs.
  *
+ *   Z90STAT_CEX2ACOUNT
+ *     Return an integer count of all CEX2As.
+ *
  *   Z90STAT_REQUESTQ_COUNT
  *     Return an integer count of the number of entries waiting to be
  *     sent to a device.
@@ -144,6 +147,7 @@
  *       0x03: PCIXCC_MCL2
  *       0x04: PCIXCC_MCL3
  *       0x05: CEX2C
+ *       0x06: CEX2A
  *       0x0d: device is disabled via the proc filesystem
  *
  *   Z90STAT_QDEPTH_MASK
@@ -199,6 +203,7 @@
 #define Z90STAT_PCIXCCMCL2COUNT	_IOR(Z90_IOCTL_MAGIC, 0x4b, int)
 #define Z90STAT_PCIXCCMCL3COUNT	_IOR(Z90_IOCTL_MAGIC, 0x4c, int)
 #define Z90STAT_CEX2CCOUNT	_IOR(Z90_IOCTL_MAGIC, 0x4d, int)
+#define Z90STAT_CEX2ACOUNT	_IOR(Z90_IOCTL_MAGIC, 0x4e, int)
 #define Z90STAT_REQUESTQ_COUNT	_IOR(Z90_IOCTL_MAGIC, 0x44, int)
 #define Z90STAT_PENDINGQ_COUNT	_IOR(Z90_IOCTL_MAGIC, 0x45, int)
 #define Z90STAT_TOTALOPEN_COUNT _IOR(Z90_IOCTL_MAGIC, 0x46, int)
diff --git a/drivers/s390/crypto/z90hardware.c b/drivers/s390/crypto/z90hardware.c
index c215e08..d7f7494 100644
--- a/drivers/s390/crypto/z90hardware.c
+++ b/drivers/s390/crypto/z90hardware.c
@@ -1,9 +1,9 @@
 /*
  *  linux/drivers/s390/crypto/z90hardware.c
  *
- *  z90crypt 1.3.2
+ *  z90crypt 1.3.3
  *
- *  Copyright (C)  2001, 2004 IBM Corporation
+ *  Copyright (C)  2001, 2005 IBM Corporation
  *  Author(s): Robert Burroughs (burrough@us.ibm.com)
  *             Eric Rossman (edrossma@us.ibm.com)
  *
@@ -648,6 +648,87 @@
 #define RESPONSE_CPRB_SIZE  0x000006B8
 #define RESPONSE_CPRBX_SIZE 0x00000724
 
+struct type50_hdr {
+	u8    reserved1;
+	u8    msg_type_code;
+	u16   msg_len;
+	u8    reserved2;
+	u8    ignored;
+	u16   reserved3;
+};
+
+#define TYPE50_TYPE_CODE 0x50
+
+#define TYPE50_MEB1_LEN (sizeof(struct type50_meb1_msg))
+#define TYPE50_MEB2_LEN (sizeof(struct type50_meb2_msg))
+#define TYPE50_CRB1_LEN (sizeof(struct type50_crb1_msg))
+#define TYPE50_CRB2_LEN (sizeof(struct type50_crb2_msg))
+
+#define TYPE50_MEB1_FMT 0x0001
+#define TYPE50_MEB2_FMT 0x0002
+#define TYPE50_CRB1_FMT 0x0011
+#define TYPE50_CRB2_FMT 0x0012
+
+struct type50_meb1_msg {
+	struct type50_hdr	header;
+	u16			keyblock_type;
+	u8			reserved[6];
+	u8			exponent[128];
+	u8			modulus[128];
+	u8			message[128];
+};
+
+struct type50_meb2_msg {
+	struct type50_hdr	header;
+	u16			keyblock_type;
+	u8			reserved[6];
+	u8			exponent[256];
+	u8			modulus[256];
+	u8			message[256];
+};
+
+struct type50_crb1_msg {
+	struct type50_hdr	header;
+	u16			keyblock_type;
+	u8			reserved[6];
+	u8			p[64];
+	u8			q[64];
+	u8			dp[64];
+	u8			dq[64];
+	u8			u[64];
+	u8			message[128];
+};
+
+struct type50_crb2_msg {
+	struct type50_hdr	header;
+	u16			keyblock_type;
+	u8			reserved[6];
+	u8			p[128];
+	u8			q[128];
+	u8			dp[128];
+	u8			dq[128];
+	u8			u[128];
+	u8			message[256];
+};
+
+union type50_msg {
+	struct type50_meb1_msg meb1;
+	struct type50_meb2_msg meb2;
+	struct type50_crb1_msg crb1;
+	struct type50_crb2_msg crb2;
+};
+
+struct type80_hdr {
+	u8	reserved1;
+	u8	type;
+	u16	len;
+	u8	code;
+	u8	reserved2[3];
+	u8	reserved3[8];
+};
+
+#define TYPE80_RSP_CODE 0x80
+
 struct error_hdr {
 	unsigned char reserved1;
 	unsigned char type;
@@ -657,6 +738,7 @@
 };
 
 #define TYPE82_RSP_CODE 0x82
+#define TYPE88_RSP_CODE 0x88
 
 #define REP82_ERROR_MACHINE_FAILURE  0x10
 #define REP82_ERROR_PREEMPT_FAILURE  0x12
@@ -679,6 +761,22 @@
 #define REP82_ERROR_PACKET_TRUNCATED 0xA0
 #define REP82_ERROR_ZERO_BUFFER_LEN  0xB0
 
+#define REP88_ERROR_MODULE_FAILURE   0x10
+#define REP88_ERROR_MODULE_TIMEOUT   0x11
+#define REP88_ERROR_MODULE_NOTINIT   0x13
+#define REP88_ERROR_MODULE_NOTAVAIL  0x14
+#define REP88_ERROR_MODULE_DISABLED  0x15
+#define REP88_ERROR_MODULE_IN_DIAGN  0x17
+#define REP88_ERROR_FASTPATH_DISABLD 0x19
+#define REP88_ERROR_MESSAGE_TYPE     0x20
+#define REP88_ERROR_MESSAGE_MALFORMD 0x22
+#define REP88_ERROR_MESSAGE_LENGTH   0x23
+#define REP88_ERROR_RESERVED_FIELD   0x24
+#define REP88_ERROR_KEY_TYPE         0x34
+#define REP88_ERROR_INVALID_KEY      0x82
+#define REP88_ERROR_OPERAND          0x84
+#define REP88_ERROR_OPERAND_EVEN_MOD 0x85
+
 #define CALLER_HEADER 12
 
 static inline int
@@ -687,7 +785,7 @@
 	int ccode;
 
 	asm volatile
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 	("	llgfr	0,%4		\n"
 	 "	slgr	1,1		\n"
 	 "	lgr	2,1		\n"
@@ -757,7 +855,7 @@
 	int ccode;
 
 	asm volatile
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 	("	llgfr	0,%2		\n"
 	 "	lghi	1,1		\n"
 	 "	sll	1,24		\n"
@@ -823,7 +921,7 @@
 	int ccode;
 
 	asm volatile
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 	("	lgr	6,%3		\n"
 	 "	llgfr	7,%2		\n"
 	 "	llgt	0,0(6)		\n"
@@ -902,7 +1000,7 @@
 	int ccode;
 
 	asm volatile
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 	("	llgfr	0,%2		\n"
 	 "	lgr	3,%4		\n"
 	 "	lgr	6,%3		\n"
@@ -1029,10 +1127,6 @@
 			stat = HD_ONLINE;
 			*q_depth = t_depth + 1;
 			switch (t_dev_type) {
-			case OTHER_HW:
-				stat = HD_NOT_THERE;
-				*dev_type = NILDEV;
-				break;
 			case PCICA_HW:
 				*dev_type = PCICA;
 				break;
@@ -1045,6 +1139,9 @@
 			case CEX2C_HW:
 				*dev_type = CEX2C;
 				break;
+			case CEX2A_HW:
+				*dev_type = CEX2A;
+				break;
 			default:
 				*dev_type = NILDEV;
 				break;
@@ -2029,6 +2126,177 @@
 	return 0;
 }
 
+static int
+ICAMEX_msg_to_type50MEX_msg(struct ica_rsa_modexpo *icaMex_p, int *z90cMsg_l_p,
+			    union type50_msg *z90cMsg_p)
+{
+	int mod_len, msg_size, mod_tgt_len, exp_tgt_len, inp_tgt_len;
+	unsigned char *mod_tgt, *exp_tgt, *inp_tgt;
+	union type50_msg *tmp_type50_msg;
+
+	mod_len = icaMex_p->inputdatalength;
+
+	msg_size = ((mod_len <= 128) ? TYPE50_MEB1_LEN : TYPE50_MEB2_LEN) +
+		    CALLER_HEADER;
+
+	memset(z90cMsg_p, 0, msg_size);
+
+	tmp_type50_msg = (union type50_msg *)
+		((unsigned char *) z90cMsg_p + CALLER_HEADER);
+
+	tmp_type50_msg->meb1.header.msg_type_code = TYPE50_TYPE_CODE;
+
+	if (mod_len <= 128) {
+		tmp_type50_msg->meb1.header.msg_len = TYPE50_MEB1_LEN;
+		tmp_type50_msg->meb1.keyblock_type = TYPE50_MEB1_FMT;
+		mod_tgt = tmp_type50_msg->meb1.modulus;
+		mod_tgt_len = sizeof(tmp_type50_msg->meb1.modulus);
+		exp_tgt = tmp_type50_msg->meb1.exponent;
+		exp_tgt_len = sizeof(tmp_type50_msg->meb1.exponent);
+		inp_tgt = tmp_type50_msg->meb1.message;
+		inp_tgt_len = sizeof(tmp_type50_msg->meb1.message);
+	} else {
+		tmp_type50_msg->meb2.header.msg_len = TYPE50_MEB2_LEN;
+		tmp_type50_msg->meb2.keyblock_type = TYPE50_MEB2_FMT;
+		mod_tgt = tmp_type50_msg->meb2.modulus;
+		mod_tgt_len = sizeof(tmp_type50_msg->meb2.modulus);
+		exp_tgt = tmp_type50_msg->meb2.exponent;
+		exp_tgt_len = sizeof(tmp_type50_msg->meb2.exponent);
+		inp_tgt = tmp_type50_msg->meb2.message;
+		inp_tgt_len = sizeof(tmp_type50_msg->meb2.message);
+	}
+
+	mod_tgt += (mod_tgt_len - mod_len);
+	if (copy_from_user(mod_tgt, icaMex_p->n_modulus, mod_len))
+		return SEN_RELEASED;
+	if (is_empty(mod_tgt, mod_len))
+		return SEN_USER_ERROR;
+	exp_tgt += (exp_tgt_len - mod_len);
+	if (copy_from_user(exp_tgt, icaMex_p->b_key, mod_len))
+		return SEN_RELEASED;
+	if (is_empty(exp_tgt, mod_len))
+		return SEN_USER_ERROR;
+	inp_tgt += (inp_tgt_len - mod_len);
+	if (copy_from_user(inp_tgt, icaMex_p->inputdata, mod_len))
+		return SEN_RELEASED;
+	if (is_empty(inp_tgt, mod_len))
+		return SEN_USER_ERROR;
+
+	*z90cMsg_l_p = msg_size - CALLER_HEADER;
+
+	return 0;
+}
+
+static int
+ICACRT_msg_to_type50CRT_msg(struct ica_rsa_modexpo_crt *icaMsg_p,
+			    int *z90cMsg_l_p, union type50_msg *z90cMsg_p)
+{
+	int mod_len, short_len, long_len, tmp_size, p_tgt_len, q_tgt_len,
+	    dp_tgt_len, dq_tgt_len, u_tgt_len, inp_tgt_len, long_offset;
+	unsigned char *p_tgt, *q_tgt, *dp_tgt, *dq_tgt, *u_tgt, *inp_tgt,
+		      temp[8];
+	union type50_msg *tmp_type50_msg;
+
+	mod_len = icaMsg_p->inputdatalength;
+	short_len = mod_len / 2;
+	long_len = mod_len / 2 + 8;
+	long_offset = 0;
+
+	if (long_len > 128) {
+		memset(temp, 0x00, sizeof(temp));
+		if (copy_from_user(temp, icaMsg_p->np_prime, long_len-128))
+			return SEN_RELEASED;
+		if (!is_empty(temp, 8))
+			return SEN_NOT_AVAIL;
+		if (copy_from_user(temp, icaMsg_p->bp_key, long_len-128))
+			return SEN_RELEASED;
+		if (!is_empty(temp, 8))
+			return SEN_NOT_AVAIL;
+		if (copy_from_user(temp, icaMsg_p->u_mult_inv, long_len-128))
+			return SEN_RELEASED;
+		if (!is_empty(temp, 8))
+			return SEN_NOT_AVAIL;
+		long_offset = long_len - 128;
+		long_len = 128;
+	}
+
+	tmp_size = ((mod_len <= 128) ? TYPE50_CRB1_LEN : TYPE50_CRB2_LEN) +
+		    CALLER_HEADER;
+
+	memset(z90cMsg_p, 0, tmp_size);
+
+	tmp_type50_msg = (union type50_msg *)
+		((unsigned char *) z90cMsg_p + CALLER_HEADER);
+
+	tmp_type50_msg->crb1.header.msg_type_code = TYPE50_TYPE_CODE;
+	if (long_len <= 64) {
+		tmp_type50_msg->crb1.header.msg_len = TYPE50_CRB1_LEN;
+		tmp_type50_msg->crb1.keyblock_type = TYPE50_CRB1_FMT;
+		p_tgt = tmp_type50_msg->crb1.p;
+		p_tgt_len = sizeof(tmp_type50_msg->crb1.p);
+		q_tgt = tmp_type50_msg->crb1.q;
+		q_tgt_len = sizeof(tmp_type50_msg->crb1.q);
+		dp_tgt = tmp_type50_msg->crb1.dp;
+		dp_tgt_len = sizeof(tmp_type50_msg->crb1.dp);
+		dq_tgt = tmp_type50_msg->crb1.dq;
+		dq_tgt_len = sizeof(tmp_type50_msg->crb1.dq);
+		u_tgt = tmp_type50_msg->crb1.u;
+		u_tgt_len = sizeof(tmp_type50_msg->crb1.u);
+		inp_tgt = tmp_type50_msg->crb1.message;
+		inp_tgt_len = sizeof(tmp_type50_msg->crb1.message);
+	} else {
+		tmp_type50_msg->crb2.header.msg_len = TYPE50_CRB2_LEN;
+		tmp_type50_msg->crb2.keyblock_type = TYPE50_CRB2_FMT;
+		p_tgt = tmp_type50_msg->crb2.p;
+		p_tgt_len = sizeof(tmp_type50_msg->crb2.p);
+		q_tgt = tmp_type50_msg->crb2.q;
+		q_tgt_len = sizeof(tmp_type50_msg->crb2.q);
+		dp_tgt = tmp_type50_msg->crb2.dp;
+		dp_tgt_len = sizeof(tmp_type50_msg->crb2.dp);
+		dq_tgt = tmp_type50_msg->crb2.dq;
+		dq_tgt_len = sizeof(tmp_type50_msg->crb2.dq);
+		u_tgt = tmp_type50_msg->crb2.u;
+		u_tgt_len = sizeof(tmp_type50_msg->crb2.u);
+		inp_tgt = tmp_type50_msg->crb2.message;
+		inp_tgt_len = sizeof(tmp_type50_msg->crb2.message);
+	}
+
+	p_tgt += (p_tgt_len - long_len);
+	if (copy_from_user(p_tgt, icaMsg_p->np_prime + long_offset, long_len))
+		return SEN_RELEASED;
+	if (is_empty(p_tgt, long_len))
+		return SEN_USER_ERROR;
+	q_tgt += (q_tgt_len - short_len);
+	if (copy_from_user(q_tgt, icaMsg_p->nq_prime, short_len))
+		return SEN_RELEASED;
+	if (is_empty(q_tgt, short_len))
+		return SEN_USER_ERROR;
+	dp_tgt += (dp_tgt_len - long_len);
+	if (copy_from_user(dp_tgt, icaMsg_p->bp_key + long_offset, long_len))
+		return SEN_RELEASED;
+	if (is_empty(dp_tgt, long_len))
+		return SEN_USER_ERROR;
+	dq_tgt += (dq_tgt_len - short_len);
+	if (copy_from_user(dq_tgt, icaMsg_p->bq_key, short_len))
+		return SEN_RELEASED;
+	if (is_empty(dq_tgt, short_len))
+		return SEN_USER_ERROR;
+	u_tgt += (u_tgt_len - long_len);
+	if (copy_from_user(u_tgt, icaMsg_p->u_mult_inv + long_offset, long_len))
+		return SEN_RELEASED;
+	if (is_empty(u_tgt, long_len))
+		return SEN_USER_ERROR;
+	inp_tgt += (inp_tgt_len - mod_len);
+	if (copy_from_user(inp_tgt, icaMsg_p->inputdata, mod_len))
+		return SEN_RELEASED;
+	if (is_empty(inp_tgt, mod_len))
+		return SEN_USER_ERROR;
+
+	*z90cMsg_l_p = tmp_size - CALLER_HEADER;
+
+	return 0;
+}
+
 int
 convert_request(unsigned char *buffer, int func, unsigned short function,
 		int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p)
@@ -2071,6 +2339,16 @@
 				cdx, msg_l_p, (struct type6_msg *) msg_p,
 				dev_type);
 	}
+	if (dev_type == CEX2A) {
+		if (func == ICARSACRT)
+			return ICACRT_msg_to_type50CRT_msg(
+				(struct ica_rsa_modexpo_crt *) buffer,
+				msg_l_p, (union type50_msg *) msg_p);
+		else
+			return ICAMEX_msg_to_type50MEX_msg(
+				(struct ica_rsa_modexpo *) buffer,
+				msg_l_p, (union type50_msg *) msg_p);
+	}
 
 	return 0;
 }
@@ -2081,8 +2359,8 @@
 {
 	if (!ext_bitlens_msg_count) {
 		PRINTK("Unable to use coprocessors for extended bitlengths. "
-		       "Using PCICAs (if present) for extended bitlengths. "
-		       "This is not an error.\n");
+		       "Using PCICAs/CEX2As (if present) for extended "
+		       "bitlengths. This is not an error.\n");
 		ext_bitlens_msg_count++;
 	}
 	ext_bitlens = 0;
@@ -2094,6 +2372,7 @@
 {
 	struct ica_rsa_modexpo *icaMsg_p = (struct ica_rsa_modexpo *) buffer;
 	struct error_hdr *errh_p = (struct error_hdr *) response;
+	struct type80_hdr *t80h_p = (struct type80_hdr *) response;
 	struct type84_hdr *t84h_p = (struct type84_hdr *) response;
 	struct type86_fmt2_msg *t86m_p =  (struct type86_fmt2_msg *) response;
 	int reply_code, service_rc, service_rs, src_l;
@@ -2108,6 +2387,7 @@
 	src_l = 0;
 	switch (errh_p->type) {
 	case TYPE82_RSP_CODE:
+	case TYPE88_RSP_CODE:
 		reply_code = errh_p->reply_code;
 		src_p = (unsigned char *)errh_p;
 		PRINTK("Hardware error: Type %02X Message Header: "
@@ -2116,6 +2396,10 @@
 		       src_p[0], src_p[1], src_p[2], src_p[3],
 		       src_p[4], src_p[5], src_p[6], src_p[7]);
 		break;
+	case TYPE80_RSP_CODE:
+		src_l = icaMsg_p->outputdatalength;
+		src_p = response + (int)t80h_p->len - src_l;
+		break;
 	case TYPE84_RSP_CODE:
 		src_l = icaMsg_p->outputdatalength;
 		src_p = response + (int)t84h_p->len - src_l;
@@ -2202,6 +2486,7 @@
 	if (reply_code)
 		switch (reply_code) {
 		case REP82_ERROR_OPERAND_INVALID:
+		case REP88_ERROR_MESSAGE_MALFORMD:
 			return REC_OPERAND_INV;
 		case REP82_ERROR_OPERAND_SIZE:
 			return REC_OPERAND_SIZE;
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c
index 4010f2b..135ae04 100644
--- a/drivers/s390/crypto/z90main.c
+++ b/drivers/s390/crypto/z90main.c
@@ -34,7 +34,6 @@
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/kobject_uevent.h>
 #include <linux/proc_fs.h>
 #include <linux/syscalls.h>
 #include "z90crypt.h"
@@ -229,7 +228,7 @@
  */
 struct device {
 	int		 dev_type;	    // PCICA, PCICC, PCIXCC_MCL2,
-					    // PCIXCC_MCL3, CEX2C
+					    // PCIXCC_MCL3, CEX2C, CEX2A
 	enum devstat	 dev_stat;	    // current device status
 	int		 dev_self_x;	    // Index in array
 	int		 disabled;	    // Set when device is in error
@@ -296,26 +295,30 @@
 /**
  * Function prototypes from z90hardware.c
  */
-enum hdstat query_online(int, int, int, int *, int *);
-enum devstat reset_device(int, int, int);
-enum devstat send_to_AP(int, int, int, unsigned char *);
-enum devstat receive_from_AP(int, int, int, unsigned char *, unsigned char *);
-int convert_request(unsigned char *, int, short, int, int, int *,
-		    unsigned char *);
-int convert_response(unsigned char *, unsigned char *, int *, unsigned char *);
+enum hdstat query_online(int deviceNr, int cdx, int resetNr, int *q_depth,
+			 int *dev_type);
+enum devstat reset_device(int deviceNr, int cdx, int resetNr);
+enum devstat send_to_AP(int dev_nr, int cdx, int msg_len, unsigned char *msg_ext);
+enum devstat receive_from_AP(int dev_nr, int cdx, int resplen,
+			     unsigned char *resp, unsigned char *psmid);
+int convert_request(unsigned char *buffer, int func, unsigned short function,
+		    int cdx, int dev_type, int *msg_l_p, unsigned char *msg_p);
+int convert_response(unsigned char *response, unsigned char *buffer,
+		     int *respbufflen_p, unsigned char *resp_buff);
 
 /**
  * Low level function prototypes
  */
-static int create_z90crypt(int *);
-static int refresh_z90crypt(int *);
-static int find_crypto_devices(struct status *);
-static int create_crypto_device(int);
-static int destroy_crypto_device(int);
+static int create_z90crypt(int *cdx_p);
+static int refresh_z90crypt(int *cdx_p);
+static int find_crypto_devices(struct status *deviceMask);
+static int create_crypto_device(int index);
+static int destroy_crypto_device(int index);
 static void destroy_z90crypt(void);
-static int refresh_index_array(struct status *, struct device_x *);
-static int probe_device_type(struct device *);
-static int probe_PCIXCC_type(struct device *);
+static int refresh_index_array(struct status *status_str,
+			       struct device_x *index_array);
+static int probe_device_type(struct device *devPtr);
+static int probe_PCIXCC_type(struct device *devPtr);
 
 /**
  * proc fs definitions
@@ -426,7 +429,7 @@
 MODULE_AUTHOR("zSeries Linux Crypto Team: Robert H. Burroughs, Eric D. Rossman"
 	      "and Jochen Roehrig");
 MODULE_DESCRIPTION("zSeries Linux Cryptographic Coprocessor device driver, "
-		   "Copyright 2001, 2004 IBM Corporation");
+		   "Copyright 2001, 2005 IBM Corporation");
 MODULE_LICENSE("GPL");
 module_param(domain, int, 0);
 MODULE_PARM_DESC(domain, "domain index for device");
@@ -861,6 +864,12 @@
 }
 
 static inline int
+get_status_CEX2Acount(void)
+{
+	return z90crypt.hdware_info->type_mask[CEX2A].st_count;
+}
+
+static inline int
 get_status_requestq_count(void)
 {
 	return requestq_count;
@@ -1009,11 +1018,13 @@
 select_device_type(int *dev_type_p, int bytelength)
 {
 	static int count = 0;
-	int PCICA_avail, PCIXCC_MCL3_avail, CEX2C_avail, index_to_use;
+	int PCICA_avail, PCIXCC_MCL3_avail, CEX2C_avail, CEX2A_avail,
+	    index_to_use;
 	struct status *stat;
 	if ((*dev_type_p != PCICC) && (*dev_type_p != PCICA) &&
 	    (*dev_type_p != PCIXCC_MCL2) && (*dev_type_p != PCIXCC_MCL3) &&
-	    (*dev_type_p != CEX2C) && (*dev_type_p != ANYDEV))
+	    (*dev_type_p != CEX2C) && (*dev_type_p != CEX2A) &&
+	    (*dev_type_p != ANYDEV))
 		return -1;
 	if (*dev_type_p != ANYDEV) {
 		stat = &z90crypt.hdware_info->type_mask[*dev_type_p];
@@ -1023,7 +1034,13 @@
 		return -1;
 	}
 
-	/* Assumption: PCICA, PCIXCC_MCL3, and CEX2C are all similar in speed */
+	/**
+	 * Assumption: PCICA, PCIXCC_MCL3, CEX2C, and CEX2A are all similar in
+	 * speed.
+	 *
+	 * PCICA and CEX2A do NOT co-exist, so it would be either one or the
+	 * other present.
+	 */
 	stat = &z90crypt.hdware_info->type_mask[PCICA];
 	PCICA_avail = stat->st_count -
 			(stat->disabled_count + stat->user_disabled_count);
@@ -1033,29 +1050,38 @@
 	stat = &z90crypt.hdware_info->type_mask[CEX2C];
 	CEX2C_avail = stat->st_count -
 			(stat->disabled_count + stat->user_disabled_count);
-	if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail) {
+	stat = &z90crypt.hdware_info->type_mask[CEX2A];
+	CEX2A_avail = stat->st_count -
+			(stat->disabled_count + stat->user_disabled_count);
+	if (PCICA_avail || PCIXCC_MCL3_avail || CEX2C_avail || CEX2A_avail) {
 		/**
-		 * bitlength is a factor, PCICA is the most capable, even with
-		 * the new MCL for PCIXCC.
+		 * bitlength is a factor, PCICA or CEX2A are the most capable,
+		 * even with the new MCL for PCIXCC.
 		 */
 		if ((bytelength < PCIXCC_MIN_MOD_SIZE) ||
 		    (!ext_bitlens && (bytelength < OLD_PCIXCC_MIN_MOD_SIZE))) {
-			if (!PCICA_avail)
-				return -1;
-			else {
+			if (PCICA_avail) {
 				*dev_type_p = PCICA;
 				return 0;
 			}
+			if (CEX2A_avail) {
+				*dev_type_p = CEX2A;
+				return 0;
+			}
+			return -1;
 		}
 
 		index_to_use = count % (PCICA_avail + PCIXCC_MCL3_avail +
-					CEX2C_avail);
+					CEX2C_avail + CEX2A_avail);
 		if (index_to_use < PCICA_avail)
 			*dev_type_p = PCICA;
 		else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail))
 			*dev_type_p = PCIXCC_MCL3;
-		else
+		else if (index_to_use < (PCICA_avail + PCIXCC_MCL3_avail +
+					 CEX2C_avail))
 			*dev_type_p = CEX2C;
+		else
+			*dev_type_p = CEX2A;
 		count++;
 		return 0;
 	}
@@ -1360,7 +1386,7 @@
 
 	if ((we_p->devtype != PCICC) && (we_p->devtype != PCICA) &&
 	    (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) &&
-	    (we_p->devtype != CEX2C))
+	    (we_p->devtype != CEX2C) && (we_p->devtype != CEX2A))
 		return SEN_NOT_AVAIL;
 
 	memcpy(caller_p->caller_id, we_p->caller_id,
@@ -1429,7 +1455,8 @@
 
 	if ((we_p->devtype != PCICA) && (we_p->devtype != PCICC) &&
 	    (we_p->devtype != PCIXCC_MCL2) && (we_p->devtype != PCIXCC_MCL3) &&
-	    (we_p->devtype != CEX2C) && (we_p->devtype != ANYDEV)) {
+	    (we_p->devtype != CEX2C) && (we_p->devtype != CEX2A) &&
+	    (we_p->devtype != ANYDEV)) {
 		PRINTK("invalid device type\n");
 		return SEN_USER_ERROR;
 	}
@@ -1504,8 +1531,9 @@
 
 	function = PCI_FUNC_KEY_ENCRYPT;
 	switch (we_p->devtype) {
-	/* PCICA does everything with a simple RSA mod-expo operation */
+	/* PCICA and CEX2A do everything with a simple RSA mod-expo operation */
 	case PCICA:
+	case CEX2A:
 		function = PCI_FUNC_KEY_ENCRYPT;
 		break;
 	/**
@@ -1663,7 +1691,8 @@
 		 * trigger a fallback to software.
 		 */
 		case -EINVAL:
-			if (we_p->devtype != PCICA)
+			if ((we_p->devtype != PCICA) &&
+			    (we_p->devtype != CEX2A))
 				rv = -EGETBUFF;
 			break;
 		case -ETIMEOUT:
@@ -1780,6 +1809,12 @@
 			ret = -EFAULT;
 		break;
 
+	case Z90STAT_CEX2ACOUNT:
+		tempstat = get_status_CEX2Acount();
+		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
+			ret = -EFAULT;
+		break;
+
 	case Z90STAT_REQUESTQ_COUNT:
 		tempstat = get_status_requestq_count();
 		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)
@@ -2020,6 +2055,8 @@
 		get_status_PCIXCCMCL3count());
 	len += sprintf(resp_buff+len, "CEX2C count: %d\n",
 		get_status_CEX2Ccount());
+	len += sprintf(resp_buff+len, "CEX2A count: %d\n",
+		get_status_CEX2Acount());
 	len += sprintf(resp_buff+len, "requestq count: %d\n",
 		get_status_requestq_count());
 	len += sprintf(resp_buff+len, "pendingq count: %d\n",
@@ -2027,8 +2064,8 @@
 	len += sprintf(resp_buff+len, "Total open handles: %d\n\n",
 		get_status_totalopen_count());
 	len += sprinthx(
-		"Online devices: 1: PCICA, 2: PCICC, 3: PCIXCC (MCL2), "
-		"4: PCIXCC (MCL3), 5: CEX2C",
+		"Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) "
+		"4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A",
 		resp_buff+len,
 		get_status_status_mask(workarea),
 		Z90CRYPT_NUM_APS);
@@ -2141,6 +2178,7 @@
 		case '3':	// PCIXCC_MCL2
 		case '4':	// PCIXCC_MCL3
 		case '5':	// CEX2C
+		case '6':       // CEX2A
 			j++;
 			break;
 		case 'd':
@@ -3008,7 +3046,9 @@
 			z90crypt.hdware_info->device_type_array[index] = 4;
 		else if (deviceType == CEX2C)
 			z90crypt.hdware_info->device_type_array[index] = 5;
-		else
+		else if (deviceType == CEX2A)
+			z90crypt.hdware_info->device_type_array[index] = 6;
+		else // No idea how this would happen.
 			z90crypt.hdware_info->device_type_array[index] = -1;
 	}
 
diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig
index a7efc39..5488547 100644
--- a/drivers/s390/net/Kconfig
+++ b/drivers/s390/net/Kconfig
@@ -1,5 +1,5 @@
 menu "S/390 network device drivers"
-	depends on NETDEVICES && ARCH_S390
+	depends on NETDEVICES && S390
 
 config LCS
 	tristate "Lan Channel Station Interface"
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 6b63d21..e70af7f3 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -1603,7 +1603,7 @@
         __u32      ct, sw, rm, dup;
         char       *ptr, *rptr;
         char       tbuf[82], tdup[82];
-#if (CONFIG_ARCH_S390X)
+#if (CONFIG_64BIT)
         char       addr[22];
 #else
         char       addr[12];
@@ -1619,7 +1619,7 @@
         dup = 0;
         for ( ct=0; ct < len; ct++, ptr++, rptr++ )  {
                 if (sw == 0) {
-#if (CONFIG_ARCH_S390X)
+#if (CONFIG_64BIT)
                         sprintf(addr, "%16.16lX",(unsigned long)rptr);
 #else
                         sprintf(addr, "%8.8X",(__u32)rptr);
@@ -1634,7 +1634,7 @@
                 if (sw == 8) {
                         strcat(bhex, "  ");
                 }
-#if (CONFIG_ARCH_S390X)
+#if (CONFIG_64BIT)
                 sprintf(tbuf,"%2.2lX", (unsigned long)*ptr);
 #else
                 sprintf(tbuf,"%2.2X", (__u32)*ptr);
diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c
index 0075894..77dacb4 100644
--- a/drivers/s390/net/cu3088.c
+++ b/drivers/s390/net/cu3088.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cu3088.c,v 1.35 2005/03/30 19:28:52 richtera Exp $
+ * $Id: cu3088.c,v 1.36 2005/10/25 14:37:17 cohuck Exp $
  *
  * CTC / LCS ccw_device driver
  *
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/err.h>
 
+#include <asm/s390_rdev.h>
 #include <asm/ccwdev.h>
 #include <asm/ccwgroup.h>
 
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
index df7647c..ea81773 100644
--- a/drivers/s390/net/iucv.c
+++ b/drivers/s390/net/iucv.c
@@ -1,5 +1,5 @@
 /* 
- * $Id: iucv.c,v 1.45 2005/04/26 22:59:06 braunu Exp $
+ * $Id: iucv.c,v 1.47 2005/11/21 11:35:22 mschwide Exp $
  *
  * IUCV network driver
  *
@@ -29,7 +29,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.45 $
+ * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.47 $
  *
  */
 
@@ -54,7 +54,7 @@
 #include <asm/s390_ext.h>
 #include <asm/ebcdic.h>
 #include <asm/smp.h>
-#include <asm/ccwdev.h> //for root device stuff
+#include <asm/s390_rdev.h>
 
 /* FLAGS:
  * All flags are defined in the field IPFLAGS1 of each function
@@ -355,7 +355,7 @@
 static void
 iucv_banner(void)
 {
-	char vbuf[] = "$Revision: 1.45 $";
+	char vbuf[] = "$Revision: 1.47 $";
 	char *version = vbuf;
 
 	if ((version = strchr(version, ':'))) {
@@ -477,7 +477,7 @@
 		ptr++;
 		if (ptr >= iucv_param_pool + PARAM_POOL_SIZE)
 			ptr = iucv_param_pool;
-	} while (atomic_compare_and_swap(0, 1, &ptr->in_use));
+	} while (atomic_cmpxchg(&ptr->in_use, 0, 1) != 0);
 	hint = ptr - iucv_param_pool;
 
 	memset(&ptr->param, 0, sizeof(ptr->param));
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index 011915d..f94f1f25 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -62,7 +62,8 @@
 	for (i = 0; i < ctx->num_pages; ++i)
 		free_page((unsigned long)ctx->pages[i]);
 	kfree(ctx->pages);
-	kfree(ctx->elements);
+	if (ctx->elements != NULL)
+		kfree(ctx->elements);
 	kfree(ctx);
 }
 
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 99cceb2..97f927c 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.242 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.251 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  *
@@ -12,7 +12,7 @@
  *			  Frank Pavlic (fpavlic@de.ibm.com) and
  *		 	  Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.242 $	 $Date: 2005/05/04 20:19:18 $
+ *    $Revision: 1.251 $	 $Date: 2005/05/04 20:19:18 $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -65,6 +65,7 @@
 #include <asm/timex.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
+#include <asm/s390_rdev.h>
 
 #include "qeth.h"
 #include "qeth_mpc.h"
@@ -72,7 +73,7 @@
 #include "qeth_eddp.h"
 #include "qeth_tso.h"
 
-#define VERSION_QETH_C "$Revision: 1.242 $"
+#define VERSION_QETH_C "$Revision: 1.251 $"
 static const char *version = "qeth S/390 OSA-Express driver";
 
 /**
@@ -518,7 +519,8 @@
 
 	QETH_DBF_TEXT(setup, 3, "setoffl");
 	QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
-
+	
+	netif_carrier_off(card->dev);
 	recover_flag = card->state;
 	if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){
 		PRINT_WARN("Stopping card %s interrupted by user!\n",
@@ -1020,7 +1022,6 @@
 qeth_schedule_recovery(struct qeth_card *card)
 {
 	QETH_DBF_TEXT(trace,2,"startrec");
-
 	if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
 		schedule_work(&card->kernel_thread_starter);
 }
@@ -1396,7 +1397,7 @@
 	channel->ccw.cda = (__u32) __pa(iob->data);
 
 	wait_event(card->wait_q,
-		   atomic_compare_and_swap(0,1,&channel->irq_pending) == 0);
+		   atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
 	QETH_DBF_TEXT(setup, 6, "noirqpnd");
 	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
 	rc = ccw_device_start(channel->ccwdev,
@@ -1463,7 +1464,7 @@
 	memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(iob->data), &temp, 2);
 
 	wait_event(card->wait_q,
-		   atomic_compare_and_swap(0,1,&channel->irq_pending) == 0);
+		   atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
 	QETH_DBF_TEXT(setup, 6, "noirqpnd");
 	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
 	rc = ccw_device_start(channel->ccwdev,
@@ -1616,7 +1617,7 @@
 	}
 	qeth_setup_ccw(&card->read, iob->data, QETH_BUFSIZE);
 	wait_event(card->wait_q,
-		   atomic_compare_and_swap(0,1,&card->read.irq_pending) == 0);
+		   atomic_cmpxchg(&card->read.irq_pending, 0, 1) == 0);
 	QETH_DBF_TEXT(trace, 6, "noirqpnd");
 	rc = ccw_device_start(card->read.ccwdev, &card->read.ccw,
 			      (addr_t) iob, 0, 0);
@@ -1710,7 +1711,6 @@
 					   "IP address reset.\n",
 					   QETH_CARD_IFNAME(card),
 					   card->info.chpid);
-				netif_carrier_on(card->dev);
 				qeth_schedule_recovery(card);
 				return NULL;
 			case IPA_CMD_MODCCID:
@@ -1883,7 +1883,7 @@
 	spin_unlock_irqrestore(&card->lock, flags);
 	QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
 	wait_event(card->wait_q,
-		   atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
+		   atomic_cmpxchg(&card->write.irq_pending, 0, 1) == 0);
 	qeth_prepare_control_data(card, len, iob);
 	if (IS_IPA(iob->data))
 		timer.expires = jiffies + QETH_IPA_TIMEOUT;
@@ -1925,7 +1925,7 @@
 	QETH_DBF_TEXT(trace, 5, "osndctrd");
 
 	wait_event(card->wait_q,
-		   atomic_compare_and_swap(0,1,&card->write.irq_pending) == 0);
+		   atomic_cmpxchg(&card->write.irq_pending, 0, 1) == 0);
 	qeth_prepare_control_data(card, len, iob);
 	QETH_DBF_TEXT(trace, 6, "osnoirqp");
 	spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
@@ -1959,7 +1959,7 @@
 {
 	u16 s1, s2;
 
-QETH_DBF_TEXT(trace,4,"osndipa");
+	QETH_DBF_TEXT(trace,4,"osndipa");
 
 	qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
 	s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
@@ -2203,24 +2203,21 @@
 }
 
 static inline int
-qeth_check_for_inbound_error(struct qeth_qdio_buffer *buf,
-			     unsigned int qdio_error,
-			     unsigned int siga_error)
+qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
+		       unsigned int siga_error, const char *dbftext)
 {
-	int rc = 0;
-
 	if (qdio_error || siga_error) {
-		QETH_DBF_TEXT(trace, 2, "qdinerr");
-		QETH_DBF_TEXT(qerr, 2, "qdinerr");
+		QETH_DBF_TEXT(trace, 2, dbftext);
+		QETH_DBF_TEXT(qerr, 2, dbftext);
 		QETH_DBF_TEXT_(qerr, 2, " F15=%02X",
-			       buf->buffer->element[15].flags & 0xff);
+			       buf->element[15].flags & 0xff);
 		QETH_DBF_TEXT_(qerr, 2, " F14=%02X",
-			       buf->buffer->element[14].flags & 0xff);
+			       buf->element[14].flags & 0xff);
 		QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error);
 		QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error);
-		rc = 1;
+		return 1;
 	}
-	return rc;
+	return 0;
 }
 
 static inline struct sk_buff *
@@ -2769,8 +2766,9 @@
 	for (i = first_element; i < (first_element + count); ++i) {
 		index = i % QDIO_MAX_BUFFERS_PER_Q;
 		buffer = &card->qdio.in_q->bufs[index];
-		if (!((status == QDIO_STATUS_LOOK_FOR_ERROR) &&
-		      qeth_check_for_inbound_error(buffer, qdio_err, siga_err)))
+		if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) &&
+		      qeth_check_qdio_errors(buffer->buffer, 
+					     qdio_err, siga_err,"qinerr")))
 			qeth_process_inbound_buffer(card, buffer, index);
 		/* clear buffer and give back to hardware */
 		qeth_put_buffer_pool_entry(card, buffer->pool_entry);
@@ -2785,12 +2783,13 @@
 static inline int
 qeth_handle_send_error(struct qeth_card *card,
 		       struct qeth_qdio_out_buffer *buffer,
-		       int qdio_err, int siga_err)
+		       unsigned int qdio_err, unsigned int siga_err)
 {
 	int sbalf15 = buffer->buffer->element[15].flags & 0xff;
 	int cc = siga_err & 3;
 
 	QETH_DBF_TEXT(trace, 6, "hdsnderr");
+	qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err, "qouterr");
 	switch (cc) {
 	case 0:
 		if (qdio_err){
@@ -3047,7 +3046,8 @@
 	for(i = first_element; i < (first_element + count); ++i){
 		buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
 		/*we only handle the KICK_IT error by doing a recovery */
-		if (qeth_handle_send_error(card, buffer, qdio_error, siga_error)
+		if (qeth_handle_send_error(card, buffer,
+					   qdio_error, siga_error)
 				== QETH_SEND_ERROR_KICK_IT){
 			netif_stop_queue(card->dev);
 			qeth_schedule_recovery(card);
@@ -3289,7 +3289,6 @@
 	card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count;
 	INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
 	INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
-	/* outbound */
 }
 
 static int
@@ -3731,6 +3730,9 @@
 			break;
 		}
 	}
+	if (rc && !(VLAN_DEV_INFO(dev)->real_dev->priv == (void *)card))
+		return 0;
+
 #endif
 	return rc;
 }
@@ -3807,10 +3809,8 @@
 	card->data.state = CH_STATE_UP;
 	card->state = CARD_STATE_UP;
 
-	if (!card->lan_online){
-		if (netif_carrier_ok(dev))
-			netif_carrier_off(dev);
-	}
+	if (!card->lan_online && netif_carrier_ok(dev))
+		netif_carrier_off(dev);
 	return 0;
 }
 
@@ -4237,9 +4237,8 @@
 	QETH_DBF_TEXT(trace, 6, "dosndpfa");
 
 	/* spin until we get the queue ... */
-	while (atomic_compare_and_swap(QETH_OUT_Q_UNLOCKED,
-				       QETH_OUT_Q_LOCKED,
-				       &queue->state));
+	while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
+			      QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
 	/* ... now we've got the queue */
 	index = queue->next_buf_to_fill;
 	buffer = &queue->bufs[queue->next_buf_to_fill];
@@ -4293,9 +4292,8 @@
 	QETH_DBF_TEXT(trace, 6, "dosndpkt");
 
 	/* spin until we get the queue ... */
-	while (atomic_compare_and_swap(QETH_OUT_Q_UNLOCKED,
-				       QETH_OUT_Q_LOCKED,
-				       &queue->state));
+	while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
+			      QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
 	start_index = queue->next_buf_to_fill;
 	buffer = &queue->bufs[queue->next_buf_to_fill];
 	/*
@@ -5870,10 +5868,8 @@
 	struct inet6_dev *in6_dev;
 
 	QETH_DBF_TEXT(trace,4,"chkmcv6");
-	if ((card->options.layer2 == 0) &&
-	    (!qeth_is_supported(card, IPA_IPV6)) )
+	if (!qeth_is_supported(card, IPA_IPV6)) 
 		return ;
-
 	in6_dev = in6_dev_get(card->dev);
 	if (in6_dev == NULL)
 		return;
@@ -7936,8 +7932,8 @@
 		QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
 		goto out_remove;
 	}
-/*maybe it was set offline without ifconfig down
- * we can also use this state for recovery purposes*/
+	netif_carrier_on(card->dev);
+
 	qeth_set_allowed_threads(card, 0xffffffff, 0);
 	if (recover_flag == CARD_STATE_RECOVER)
 		qeth_start_again(card, recovery_mode);
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
index f0a080a..5f8754a 100644
--- a/drivers/s390/net/qeth_mpc.c
+++ b/drivers/s390/net/qeth_mpc.c
@@ -11,7 +11,7 @@
 #include <asm/cio.h>
 #include "qeth_mpc.h"
 
-const char *VERSION_QETH_MPC_C = "$Revision: 1.12 $";
+const char *VERSION_QETH_MPC_C = "$Revision: 1.13 $";
 
 unsigned char IDX_ACTIVATE_READ[]={
 	0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
index 5f71486..864cec5 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_mpc.h
@@ -14,14 +14,14 @@
 
 #include <asm/qeth.h>
 
-#define VERSION_QETH_MPC_H "$Revision: 1.44 $"
+#define VERSION_QETH_MPC_H "$Revision: 1.46 $"
 
 extern const char *VERSION_QETH_MPC_C;
 
 #define IPA_PDU_HEADER_SIZE	0x40
 #define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e)
 #define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26)
-#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x2a)
+#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x29)
 #define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer+0x3a)
 
 extern unsigned char IPA_PDU_HEADER[];
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index f2ccfea..7bf3509 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.13 $)
+ * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.16 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to procfs.
@@ -21,7 +21,7 @@
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_PROC_C = "$Revision: 1.13 $";
+const char *VERSION_QETH_PROC_C = "$Revision: 1.16 $";
 
 /***** /proc/qeth *****/
 #define QETH_PROCFILE_NAME "qeth"
@@ -30,30 +30,26 @@
 static int
 qeth_procfile_seq_match(struct device *dev, void *data)
 {
-	return 1;
+	return(dev ? 1 : 0);
 }
 
 static void *
 qeth_procfile_seq_start(struct seq_file *s, loff_t *offset)
 {
-	struct device *dev;
-	loff_t nr;
-
+	struct device *dev = NULL;
+	loff_t nr = 0;
+	
 	down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-
-	nr = *offset;
-	if (nr == 0)
+	if (*offset == 0)
 		return SEQ_START_TOKEN;
-
-	dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL,
-				 NULL, qeth_procfile_seq_match);
-
-	/* get card at pos *offset */
-	nr = *offset;
-	while (nr-- > 1 && dev)
+	while (1) {
 		dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
 					 NULL, qeth_procfile_seq_match);
-	return (void *) dev;
+		if (++nr == *offset)
+			break;
+		put_device(dev);
+	}
+	return dev;
 }
 
 static void
@@ -66,19 +62,14 @@
 qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
 {
 	struct device *prev, *next;
-
-	if (it == SEQ_START_TOKEN) {
-		next = driver_find_device(&qeth_ccwgroup_driver.driver,
-					  NULL, NULL, qeth_procfile_seq_match);
-		if (next)
-			(*offset)++;
-		return (void *) next;
-	}
-	prev = (struct device *) it;
+	
+	if (it == SEQ_START_TOKEN) 
+		prev = NULL;
+	else
+		prev = (struct device *) it;
 	next = driver_find_device(&qeth_ccwgroup_driver.driver,
 				  prev, NULL, qeth_procfile_seq_match);
-	if (next)
-		(*offset)++;
+	(*offset)++;
 	return (void *) next;
 }
 
@@ -87,7 +78,7 @@
 {
 	int routing_type = 0;
 
-	if (ipv == 4){
+	if (ipv == 4) {
 		routing_type = card->options.route4.type;
 	} else {
 #ifdef CONFIG_QETH_IPV6
@@ -154,6 +145,7 @@
 					card->qdio.in_buf_pool.buf_count);
 		else
 			seq_printf(s, "  +++ LAN OFFLINE +++\n");
+		put_device(device);
 	}
 	return 0;
 }
@@ -184,51 +176,16 @@
 static struct proc_dir_entry *qeth_perf_procfile;
 
 #ifdef CONFIG_QETH_PERF_STATS
-
-static void *
-qeth_perf_procfile_seq_start(struct seq_file *s, loff_t *offset)
-{
-	struct device *dev = NULL;
-	int nr;
-
-	down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-	/* get card at pos *offset */
-	dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
-				 qeth_procfile_seq_match);
-
-	/* get card at pos *offset */
-	nr = *offset;
-	while (nr-- > 1 && dev)
-		dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
-					 NULL, qeth_procfile_seq_match);
-	return (void *) dev;
-}
-
-static void
-qeth_perf_procfile_seq_stop(struct seq_file *s, void* it)
-{
-	up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-}
-
-static void *
-qeth_perf_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
-{
-	struct device *prev, *next;
-
-	prev = (struct device *) it;
-	next = driver_find_device(&qeth_ccwgroup_driver.driver, prev,
-				  NULL, qeth_procfile_seq_match);
-	if (next)
-		(*offset)++;
-	return (void *) next;
-}
-
 static int
 qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
 {
 	struct device *device;
 	struct qeth_card *card;
 
+	
+	if (it == SEQ_START_TOKEN)
+		return 0;
+
 	device = (struct device *) it;
 	card = device->driver_data;
 	seq_printf(s, "For card with devnos %s/%s/%s (%s):\n",
@@ -295,13 +252,14 @@
 		        card->perf_stats.outbound_do_qdio_time,
 			card->perf_stats.outbound_do_qdio_cnt
 		  );
+	put_device(device);
 	return 0;
 }
 
 static struct seq_operations qeth_perf_procfile_seq_ops = {
-	.start = qeth_perf_procfile_seq_start,
-	.stop  = qeth_perf_procfile_seq_stop,
-	.next  = qeth_perf_procfile_seq_next,
+	.start = qeth_procfile_seq_start,
+	.stop  = qeth_procfile_seq_stop,
+	.next  = qeth_procfile_seq_next,
 	.show  = qeth_perf_procfile_seq_show,
 };
 
@@ -324,93 +282,6 @@
 #define qeth_perf_procfile_created 1
 #endif /* CONFIG_QETH_PERF_STATS */
 
-/***** /proc/qeth_ipa_takeover *****/
-#define QETH_IPATO_PROCFILE_NAME "qeth_ipa_takeover"
-static struct proc_dir_entry *qeth_ipato_procfile;
-
-static void *
-qeth_ipato_procfile_seq_start(struct seq_file *s, loff_t *offset)
-{
-	struct device *dev;
-	loff_t nr;
-
-	down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-	/* TODO: finish this */
-	/*
-	 * maybe SEQ_SATRT_TOKEN can be returned for offset 0
-	 * output driver settings then;
-	 * else output setting for respective card
-	 */
-
-	dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
-				 qeth_procfile_seq_match);
-
-	/* get card at pos *offset */
-	nr = *offset;
-	while (nr-- > 1 && dev)
-		dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
-					 NULL, qeth_procfile_seq_match);
-	return (void *) dev;
-}
-
-static void
-qeth_ipato_procfile_seq_stop(struct seq_file *s, void* it)
-{
-	up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-}
-
-static void *
-qeth_ipato_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
-{
-	struct device *prev, *next;
-
-	prev = (struct device *) it;
-	next = driver_find_device(&qeth_ccwgroup_driver.driver, prev,
-				  NULL, qeth_procfile_seq_match);
-	if (next)
-		(*offset)++;
-	return (void *) next;
-}
-
-static int
-qeth_ipato_procfile_seq_show(struct seq_file *s, void *it)
-{
-	struct device *device;
-	struct qeth_card *card;
-
-	/* TODO: finish this */
-	/*
-	 * maybe SEQ_SATRT_TOKEN can be returned for offset 0
-	 * output driver settings then;
-	 * else output setting for respective card
-	 */
-	device = (struct device *) it;
-	card = device->driver_data;
-
-	return 0;
-}
-
-static struct seq_operations qeth_ipato_procfile_seq_ops = {
-	.start = qeth_ipato_procfile_seq_start,
-	.stop  = qeth_ipato_procfile_seq_stop,
-	.next  = qeth_ipato_procfile_seq_next,
-	.show  = qeth_ipato_procfile_seq_show,
-};
-
-static int
-qeth_ipato_procfile_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &qeth_ipato_procfile_seq_ops);
-}
-
-static struct file_operations qeth_ipato_procfile_fops = {
-	.owner   = THIS_MODULE,
-	.open    = qeth_ipato_procfile_open,
-	.read    = seq_read,
-	.llseek  = seq_lseek,
-	.release = seq_release,
-};
-
 int __init
 qeth_create_procfs_entries(void)
 {
@@ -426,13 +297,7 @@
 		qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops;
 #endif /* CONFIG_QETH_PERF_STATS */
 
-	qeth_ipato_procfile = create_proc_entry(QETH_IPATO_PROCFILE_NAME,
-					   S_IFREG | 0444, NULL);
-	if (qeth_ipato_procfile)
-		qeth_ipato_procfile->proc_fops = &qeth_ipato_procfile_fops;
-
 	if (qeth_procfile &&
-	    qeth_ipato_procfile &&
 	    qeth_perf_procfile_created)
 		return 0;
 	else
@@ -446,62 +311,5 @@
 		remove_proc_entry(QETH_PROCFILE_NAME, NULL);
 	if (qeth_perf_procfile)
 		remove_proc_entry(QETH_PERF_PROCFILE_NAME, NULL);
-	if (qeth_ipato_procfile)
-		remove_proc_entry(QETH_IPATO_PROCFILE_NAME, NULL);
 }
 
-
-/* ONLY FOR DEVELOPMENT! -> make it as module */
-/*
-static void
-qeth_create_sysfs_entries(void)
-{
-	struct device *dev;
-
-	down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-
-	list_for_each_entry(dev, &qeth_ccwgroup_driver.driver.devices,
-			driver_list)
-		qeth_create_device_attributes(dev);
-
-	up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-}
-
-static void
-qeth_remove_sysfs_entries(void)
-{
-	struct device *dev;
-
-	down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-
-	list_for_each_entry(dev, &qeth_ccwgroup_driver.driver.devices,
-			driver_list)
-		qeth_remove_device_attributes(dev);
-
-	up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-}
-
-static int __init
-qeth_fs_init(void)
-{
-	printk(KERN_INFO "qeth_fs_init\n");
-	qeth_create_procfs_entries();
-	qeth_create_sysfs_entries();
-
-	return 0;
-}
-
-static void __exit
-qeth_fs_exit(void)
-{
-	printk(KERN_INFO "qeth_fs_exit\n");
-	qeth_remove_procfs_entries();
-	qeth_remove_sysfs_entries();
-}
-
-
-module_init(qeth_fs_init);
-module_exit(qeth_fs_exit);
-
-MODULE_LICENSE("GPL");
-*/
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index ddd6019..0ea185f 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.58 $)
+ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.60 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to sysfs.
@@ -20,7 +20,7 @@
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_SYS_C = "$Revision: 1.58 $";
+const char *VERSION_QETH_SYS_C = "$Revision: 1.60 $";
 
 /*****************************************************************************/
 /*                                                                           */
@@ -160,7 +160,7 @@
 		return -EPERM;
 
 	tmp = strsep((char **) &buf, "\n");
-	if ((strlen(tmp) > 8) || (strlen(tmp) < 2))
+	if ((strlen(tmp) > 8) || (strlen(tmp) == 0))
 		return -EINVAL;
 
 	card->info.portname[0] = strlen(tmp);
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
index e245af3..3c50b6f 100644
--- a/drivers/s390/net/qeth_tso.h
+++ b/drivers/s390/net/qeth_tso.h
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.7 $)
+ * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.8 $)
  *
  * Header file for qeth TCP Segmentation Offload support.
  *
@@ -7,7 +7,7 @@
  *
  *    Author(s): Frank Pavlic <fpavlic@de.ibm.com>
  *
- *    $Revision: 1.7 $	 $Date: 2005/05/04 20:19:18 $
+ *    $Revision: 1.8 $	 $Date: 2005/05/04 20:19:18 $
  *
  */
 #ifndef __QETH_TSO_H__
diff --git a/drivers/s390/s390_rdev.c b/drivers/s390/s390_rdev.c
new file mode 100644
index 0000000..566cc3d
--- /dev/null
+++ b/drivers/s390/s390_rdev.c
@@ -0,0 +1,53 @@
+/*
+ *  drivers/s390/s390_rdev.c
+ *  s390 root device
+ *   $Revision: 1.2 $
+ *
+ *    Copyright (C) 2002, 2005 IBM Deutschland Entwicklung GmbH,
+ *			 IBM Corporation
+ *    Author(s): Cornelia Huck (cohuck@de.ibm.com)
+ *		  Carsten Otte  (cotte@de.ibm.com)
+ */
+
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <asm/s390_rdev.h>
+
+static void
+s390_root_dev_release(struct device *dev)
+{
+	kfree(dev);
+}
+
+struct device *
+s390_root_dev_register(const char *name)
+{
+	struct device *dev;
+	int ret;
+
+	if (!strlen(name))
+		return ERR_PTR(-EINVAL);
+	dev = kmalloc(sizeof(struct device), GFP_KERNEL);
+	if (!dev)
+		return ERR_PTR(-ENOMEM);
+	memset(dev, 0, sizeof(struct device));
+	strncpy(dev->bus_id, name, min(strlen(name), (size_t)BUS_ID_SIZE));
+	dev->release = s390_root_dev_release;
+	ret = device_register(dev);
+	if (ret) {
+		kfree(dev);
+		return ERR_PTR(ret);
+	}
+	return dev;
+}
+
+void
+s390_root_dev_unregister(struct device *dev)
+{
+	if (dev)
+		device_unregister(dev);
+}
+
+EXPORT_SYMBOL(s390_root_dev_register);
+EXPORT_SYMBOL(s390_root_dev_unregister);
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 4191fd9..3bf4666 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -23,7 +23,7 @@
 
 static struct semaphore m_sem;
 
-extern int css_process_crw(int);
+extern int css_process_crw(int, int);
 extern int chsc_process_crw(void);
 extern int chp_process_crw(int, int);
 extern void css_reiterate_subchannels(void);
@@ -49,9 +49,10 @@
 static int
 s390_collect_crw_info(void *param)
 {
-	struct crw crw;
+	struct crw crw[2];
 	int ccode, ret, slow;
 	struct semaphore *sem;
+	unsigned int chain;
 
 	sem = (struct semaphore *)param;
 	/* Set a nice name. */
@@ -59,25 +60,50 @@
 repeat:
 	down_interruptible(sem);
 	slow = 0;
+	chain = 0;
 	while (1) {
-		ccode = stcrw(&crw);
+		if (unlikely(chain > 1)) {
+			struct crw tmp_crw;
+
+			printk(KERN_WARNING"%s: Code does not support more "
+			       "than two chained crws; please report to "
+			       "linux390@de.ibm.com!\n", __FUNCTION__);
+			ccode = stcrw(&tmp_crw);
+			printk(KERN_WARNING"%s: crw reports slct=%d, oflw=%d, "
+			       "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
+			       __FUNCTION__, tmp_crw.slct, tmp_crw.oflw,
+			       tmp_crw.chn, tmp_crw.rsc, tmp_crw.anc,
+			       tmp_crw.erc, tmp_crw.rsid);
+			printk(KERN_WARNING"%s: This was crw number %x in the "
+			       "chain\n", __FUNCTION__, chain);
+			if (ccode != 0)
+				break;
+			chain = tmp_crw.chn ? chain + 1 : 0;
+			continue;
+		}
+		ccode = stcrw(&crw[chain]);
 		if (ccode != 0)
 			break;
 		DBG(KERN_DEBUG "crw_info : CRW reports slct=%d, oflw=%d, "
 		    "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
-		    crw.slct, crw.oflw, crw.chn, crw.rsc, crw.anc,
-		    crw.erc, crw.rsid);
+		    crw[chain].slct, crw[chain].oflw, crw[chain].chn,
+		    crw[chain].rsc, crw[chain].anc, crw[chain].erc,
+		    crw[chain].rsid);
 		/* Check for overflows. */
-		if (crw.oflw) {
+		if (crw[chain].oflw) {
 			pr_debug("%s: crw overflow detected!\n", __FUNCTION__);
 			css_reiterate_subchannels();
+			chain = 0;
 			slow = 1;
 			continue;
 		}
-		switch (crw.rsc) {
+		switch (crw[chain].rsc) {
 		case CRW_RSC_SCH:
-			pr_debug("source is subchannel %04X\n", crw.rsid);
-			ret = css_process_crw (crw.rsid);
+			if (crw[0].chn && !chain)
+				break;
+			pr_debug("source is subchannel %04X\n", crw[0].rsid);
+			ret = css_process_crw (crw[0].rsid,
+					       chain ? crw[1].rsid : 0);
 			if (ret == -EAGAIN)
 				slow = 1;
 			break;
@@ -85,18 +111,18 @@
 			pr_debug("source is monitoring facility\n");
 			break;
 		case CRW_RSC_CPATH:
-			pr_debug("source is channel path %02X\n", crw.rsid);
-			switch (crw.erc) {
+			pr_debug("source is channel path %02X\n", crw[0].rsid);
+			switch (crw[0].erc) {
 			case CRW_ERC_IPARM: /* Path has come. */
-				ret = chp_process_crw(crw.rsid, 1);
+				ret = chp_process_crw(crw[0].rsid, 1);
 				break;
 			case CRW_ERC_PERRI: /* Path has gone. */
 			case CRW_ERC_PERRN:
-				ret = chp_process_crw(crw.rsid, 0);
+				ret = chp_process_crw(crw[0].rsid, 0);
 				break;
 			default:
 				pr_debug("Don't know how to handle erc=%x\n",
-					 crw.erc);
+					 crw[0].erc);
 				ret = 0;
 			}
 			if (ret == -EAGAIN)
@@ -115,6 +141,8 @@
 			pr_debug("unknown source\n");
 			break;
 		}
+		/* chain is always 0 or 1 here. */
+		chain = crw[chain].chn ? chain + 1 : 0;
 	}
 	if (slow)
 		queue_work(slow_path_wq, &slow_path_work);
@@ -218,7 +246,7 @@
 		 */
 		kill_task = 1;
 
-#ifndef __s390x__
+#ifndef CONFIG_64BIT
 	asm volatile("ld 0,0(%0)\n"
 		     "ld 2,8(%0)\n"
 		     "ld 4,16(%0)\n"
@@ -227,7 +255,7 @@
 #endif
 
 	if (MACHINE_HAS_IEEE) {
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 		fpt_save_area = &S390_lowcore.floating_pt_save_area;
 		fpt_creg_save_area = &S390_lowcore.fpt_creg_save_area;
 #else
@@ -286,7 +314,7 @@
 		 */
 		s390_handle_damage("invalid control registers.");
 	else
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 		asm volatile("lctlg 0,15,0(%0)"
 			     : : "a" (&S390_lowcore.cregs_save_area));
 #else
@@ -299,7 +327,7 @@
 	 * can't write something sensible into that register.
 	 */
 
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 	/*
 	 * See if we can revalidate the TOD programmable register with its
 	 * old contents (should be zero) otherwise set it to zero.
@@ -356,7 +384,7 @@
 		if (mci->b) {
 			/* Processing backup -> verify if we can survive this */
 			u64 z_mcic, o_mcic, t_mcic;
-#ifdef __s390x__
+#ifdef CONFIG_64BIT
 			z_mcic = (1ULL<<63 | 1ULL<<59 | 1ULL<<29);
 			o_mcic = (1ULL<<43 | 1ULL<<42 | 1ULL<<41 | 1ULL<<40 |
 				  1ULL<<36 | 1ULL<<35 | 1ULL<<34 | 1ULL<<32 |
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index c218b5c..5e84c5a 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -996,6 +996,20 @@
 	spin_lock_init(&adapter->fsf_req_list_lock);
 	INIT_LIST_HEAD(&adapter->fsf_req_list_head);
 
+	/* initialize debug locks */
+
+	spin_lock_init(&adapter->erp_dbf_lock);
+	spin_lock_init(&adapter->hba_dbf_lock);
+	spin_lock_init(&adapter->san_dbf_lock);
+	spin_lock_init(&adapter->scsi_dbf_lock);
+
+	/* initialize error recovery stuff */
+
+	rwlock_init(&adapter->erp_lock);
+	sema_init(&adapter->erp_ready_sem, 0);
+	INIT_LIST_HEAD(&adapter->erp_ready_head);
+	INIT_LIST_HEAD(&adapter->erp_running_head);
+
 	/* initialize abort lock */
 	rwlock_init(&adapter->abort_lock);
 
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 826fb3b..9559971 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -926,7 +926,6 @@
 	char dbf_name[DEBUG_MAX_NAME_LEN];
 
 	/* debug feature area which records recovery activity */
-	spin_lock_init(&adapter->erp_dbf_lock);
 	sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter));
 	adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2,
 					  sizeof(struct zfcp_erp_dbf_record));
@@ -936,7 +935,6 @@
 	debug_set_level(adapter->erp_dbf, 3);
 
 	/* debug feature area which records HBA (FSF and QDIO) conditions */
-	spin_lock_init(&adapter->hba_dbf_lock);
 	sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
 	adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,
 					  sizeof(struct zfcp_hba_dbf_record));
@@ -947,7 +945,6 @@
 	debug_set_level(adapter->hba_dbf, 3);
 
 	/* debug feature area which records SAN command failures and recovery */
-	spin_lock_init(&adapter->san_dbf_lock);
 	sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter));
 	adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,
 					  sizeof(struct zfcp_san_dbf_record));
@@ -958,7 +955,6 @@
 	debug_set_level(adapter->san_dbf, 6);
 
 	/* debug feature area which records SCSI command failures and recovery */
-	spin_lock_init(&adapter->scsi_dbf_lock);
 	sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter));
 	adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,
 					   sizeof(struct zfcp_scsi_dbf_record));
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 023f4e5..ee7314d 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -1071,11 +1071,6 @@
 
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
 
-	rwlock_init(&adapter->erp_lock);
-	INIT_LIST_HEAD(&adapter->erp_ready_head);
-	INIT_LIST_HEAD(&adapter->erp_running_head);
-	sema_init(&adapter->erp_ready_sem, 0);
-
 	retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD);
 	if (retval < 0) {
 		ZFCP_LOG_NORMAL("error: creation of erp thread failed for "
@@ -2248,29 +2243,26 @@
 	return retval;
 }
 
-/*
- * function:    zfcp_fsf_init
- *
- * purpose:	initializes FSF operation for the specified adapter
- *
- * returns:	0 - succesful initialization of FSF operation
- *		!0 - failed to initialize FSF operation
- */
 static int
 zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
 {
-	int xconfig, xport;
+	int retval;
 
-	if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-			     &erp_action->adapter->status)) {
+	if ((atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+			      &erp_action->adapter->status)) &&
+	    (erp_action->adapter->adapter_features &
+	     FSF_FEATURE_HBAAPI_MANAGEMENT)) {
 		zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
 		atomic_set(&erp_action->adapter->erp_counter, 0);
 		return ZFCP_ERP_FAILED;
 	}
 
-	xconfig = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
-	xport   = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
-	if ((xconfig == ZFCP_ERP_FAILED) || (xport == ZFCP_ERP_FAILED))
+	retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
+	if (retval == ZFCP_ERP_FAILED)
+		return ZFCP_ERP_FAILED;
+
+	retval = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
+	if (retval == ZFCP_ERP_FAILED)
 		return ZFCP_ERP_FAILED;
 
 	return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
@@ -2359,41 +2351,29 @@
 static int
 zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
 {
-	int retval = ZFCP_ERP_SUCCEEDED;
+	int ret;
 	int retries;
 	int sleep;
 	struct zfcp_adapter *adapter = erp_action->adapter;
 
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
 
-	for (retries = 0; ; retries++) {
-		ZFCP_LOG_DEBUG("Doing exchange port data\n");
+	retries = 0;
+	do {
+		write_lock(&adapter->erp_lock);
 		zfcp_erp_action_to_running(erp_action);
+		write_unlock(&adapter->erp_lock);
 		zfcp_erp_timeout_init(erp_action);
-		if (zfcp_fsf_exchange_port_data(erp_action, adapter, NULL)) {
-			retval = ZFCP_ERP_FAILED;
-			debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf");
-			ZFCP_LOG_INFO("error: initiation of exchange of "
-				      "port data failed for adapter %s\n",
-				      zfcp_get_busid_by_adapter(adapter));
-			break;
+		ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
+		if (ret == -EOPNOTSUPP) {
+			debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
+			return ZFCP_ERP_SUCCEEDED;
+		} else if (ret) {
+			debug_text_event(adapter->erp_dbf, 3, "a_xport_failed");
+			return ZFCP_ERP_FAILED;
 		}
-		debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok");
-		ZFCP_LOG_DEBUG("Xchange underway\n");
+		debug_text_event(adapter->erp_dbf, 6, "a_xport_ok");
 
-		/*
-		 * Why this works:
-		 * Both the normal completion handler as well as the timeout
-		 * handler will do an 'up' when the 'exchange port data'
-		 * request completes or times out. Thus, the signal to go on
-		 * won't be lost utilizing this semaphore.
-		 * Furthermore, this 'adapter_reopen' action is
-		 * guaranteed to be the only action being there (highest action
-		 * which prevents other actions from being created).
-		 * Resulting from that, the wake signal recognized here
-		 * _must_ be the one belonging to the 'exchange port
-		 * data' request.
-		 */
 		down(&adapter->erp_ready_sem);
 		if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
 			ZFCP_LOG_INFO("error: exchange of port data "
@@ -2401,29 +2381,19 @@
 				      zfcp_get_busid_by_adapter(adapter));
 			break;
 		}
-
 		if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
 				      &adapter->status))
 			break;
 
-		ZFCP_LOG_DEBUG("host connection still initialising... "
-			       "waiting and retrying...\n");
-		/* sleep a little bit before retry */
-		sleep = retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES ?
-				ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP :
-				ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP;
-		msleep(jiffies_to_msecs(sleep));
-	}
+		if (retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES) {
+			sleep = ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP;
+			retries++;
+		} else
+			sleep = ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP;
+		schedule_timeout(sleep);
+	} while (1);
 
-	if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-			     &adapter->status)) {
-		ZFCP_LOG_INFO("error: exchange of port data for "
-			      "adapter %s failed\n",
-			      zfcp_get_busid_by_adapter(adapter));
-		retval = ZFCP_ERP_FAILED;
-	}
-
-	return retval;
+	return ZFCP_ERP_SUCCEEDED;
 }
 
 /*
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 3b0fc11..5958795 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -554,6 +554,17 @@
 zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
 			     struct fsf_link_down_info *link_down)
 {
+	if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+	                     &adapter->status))
+		return;
+
+	atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
+
+	if (link_down == NULL) {
+		zfcp_erp_adapter_reopen(adapter, 0);
+		return;
+	}
+
 	switch (link_down->error_code) {
 	case FSF_PSQ_LINK_NO_LIGHT:
 		ZFCP_LOG_NORMAL("The local link to adapter %s is down "
@@ -634,20 +645,15 @@
 				link_down->explanation_code,
 				link_down->vendor_specific_code);
 
-	if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-			      &adapter->status)) {
-		atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
-				&adapter->status);
-		switch (link_down->error_code) {
-		case FSF_PSQ_LINK_NO_LIGHT:
-		case FSF_PSQ_LINK_WRAP_PLUG:
-		case FSF_PSQ_LINK_NO_FCP:
-		case FSF_PSQ_LINK_FIRMWARE_UPDATE:
-			zfcp_erp_adapter_reopen(adapter, 0);
-			break;
-		default:
-			zfcp_erp_adapter_failed(adapter);
-		}
+	switch (link_down->error_code) {
+	case FSF_PSQ_LINK_NO_LIGHT:
+	case FSF_PSQ_LINK_WRAP_PLUG:
+	case FSF_PSQ_LINK_NO_FCP:
+	case FSF_PSQ_LINK_FIRMWARE_UPDATE:
+		zfcp_erp_adapter_reopen(adapter, 0);
+		break;
+	default:
+		zfcp_erp_adapter_failed(adapter);
 	}
 }
 
@@ -919,30 +925,36 @@
 		case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
 			ZFCP_LOG_INFO("Physical link to adapter %s is down\n",
 				      zfcp_get_busid_by_adapter(adapter));
+			zfcp_fsf_link_down_info_eval(adapter,
+				(struct fsf_link_down_info *)
+				&status_buffer->payload);
 			break;
 		case FSF_STATUS_READ_SUB_FDISC_FAILED:
 			ZFCP_LOG_INFO("Local link to adapter %s is down "
 				      "due to failed FDISC login\n",
-			      zfcp_get_busid_by_adapter(adapter));
+				      zfcp_get_busid_by_adapter(adapter));
+			zfcp_fsf_link_down_info_eval(adapter,
+				(struct fsf_link_down_info *)
+				&status_buffer->payload);
 			break;
 		case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
 			ZFCP_LOG_INFO("Local link to adapter %s is down "
 				      "due to firmware update on adapter\n",
 				      zfcp_get_busid_by_adapter(adapter));
+			zfcp_fsf_link_down_info_eval(adapter, NULL);
 			break;
 		default:
 			ZFCP_LOG_INFO("Local link to adapter %s is down "
 				      "due to unknown reason\n",
 				      zfcp_get_busid_by_adapter(adapter));
+			zfcp_fsf_link_down_info_eval(adapter, NULL);
 		};
-		zfcp_fsf_link_down_info_eval(adapter,
-			(struct fsf_link_down_info *) &status_buffer->payload);
 		break;
 
 	case FSF_STATUS_READ_LINK_UP:
 		ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. "
-			      "Restarting operations on this adapter\n",
-			      zfcp_get_busid_by_adapter(adapter));
+				"Restarting operations on this adapter\n",
+				zfcp_get_busid_by_adapter(adapter));
 		/* All ports should be marked as ready to run again */
 		zfcp_erp_modify_adapter_status(adapter,
 					       ZFCP_STATUS_COMMON_RUNNING,
@@ -2191,13 +2203,10 @@
                 return -EOPNOTSUPP;
         }
 
-	timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
-	if (!timer)
-		return -ENOMEM;
-
 	/* setup new FSF request */
 	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
-                                     0, 0, &lock_flags, &fsf_req);
+				     erp_action ? ZFCP_REQ_AUTO_CLEANUP : 0,
+				     0, &lock_flags, &fsf_req);
 	if (retval < 0) {
 		ZFCP_LOG_INFO("error: Out of resources. Could not create an "
                               "exchange port data request for"
@@ -2205,25 +2214,33 @@
 			      zfcp_get_busid_by_adapter(adapter));
 		write_unlock_irqrestore(&adapter->request_queue.queue_lock,
 					lock_flags);
-		goto out;
-	}
-
-	if (erp_action) {
-		erp_action->fsf_req = fsf_req;
-		fsf_req->erp_action = erp_action;
+		return retval;
 	}
 
 	if (data)
-	fsf_req->data = (unsigned long) data;
+		fsf_req->data = (unsigned long) data;
 
 	sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
         sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
         sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
 
-	init_timer(timer);
-	timer->function = zfcp_fsf_request_timeout_handler;
-	timer->data = (unsigned long) adapter;
-	timer->expires = ZFCP_FSF_REQUEST_TIMEOUT;
+	if (erp_action) {
+		erp_action->fsf_req = fsf_req;
+		fsf_req->erp_action = erp_action;
+		timer = &erp_action->timer;
+	} else {
+		timer = kmalloc(sizeof(struct timer_list), GFP_ATOMIC);
+		if (!timer) {
+			write_unlock_irqrestore(&adapter->request_queue.queue_lock,
+						lock_flags);
+			zfcp_fsf_req_free(fsf_req);
+			return -ENOMEM;
+		}
+		init_timer(timer);
+		timer->function = zfcp_fsf_request_timeout_handler;
+		timer->data = (unsigned long) adapter;
+		timer->expires = ZFCP_FSF_REQUEST_TIMEOUT;
+	}
 
 	retval = zfcp_fsf_req_send(fsf_req, timer);
 	if (retval) {
@@ -2233,23 +2250,22 @@
 		zfcp_fsf_req_free(fsf_req);
 		if (erp_action)
 			erp_action->fsf_req = NULL;
+		else
+			kfree(timer);
 		write_unlock_irqrestore(&adapter->request_queue.queue_lock,
 					lock_flags);
-		goto out;
+		return retval;
 	}
 
-	ZFCP_LOG_DEBUG("Exchange Port Data request initiated (adapter %s)\n",
-		       zfcp_get_busid_by_adapter(adapter));
+	write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
 
-	write_unlock_irqrestore(&adapter->request_queue.queue_lock,
-				lock_flags);
-
-	wait_event(fsf_req->completion_wq,
-		   fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
-	del_timer_sync(timer);
-	zfcp_fsf_req_free(fsf_req);
- out:
-	kfree(timer);
+	if (!erp_action) {
+		wait_event(fsf_req->completion_wq,
+			   fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+		del_timer_sync(timer);
+		zfcp_fsf_req_free(fsf_req);
+		kfree(timer);
+	}
 	return retval;
 }
 
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 3dcd1bf..66608d1 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -179,7 +179,7 @@
 	struct zfcp_adapter *adapter;
 	struct zfcp_unit *unit;
 	unsigned long flags;
-	int retval = -ENODEV;
+	int retval = -ENXIO;
 
 	adapter = (struct zfcp_adapter *) sdp->host->hostdata[0];
 	if (!adapter)
diff --git a/drivers/s390/sysinfo.c b/drivers/s390/sysinfo.c
index 87c2db1..66da840 100644
--- a/drivers/s390/sysinfo.c
+++ b/drivers/s390/sysinfo.c
@@ -106,7 +106,7 @@
 {
 	int cc, retv;
 
-#ifndef CONFIG_ARCH_S390X
+#ifndef CONFIG_64BIT
 	__asm__ __volatile__ (	"lr\t0,%2\n"
 				"\tlr\t1,%3\n"
 				"\tstsi\t0(%4)\n"
diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
index c12c504..14631ac 100644
--- a/drivers/sbus/char/jsflash.c
+++ b/drivers/sbus/char/jsflash.c
@@ -249,11 +249,11 @@
 /*
  * OS SIMM Cannot be read in other size but a 32bits word.
  */
-static ssize_t jsf_read(struct file * file, char * buf, 
+static ssize_t jsf_read(struct file * file, char __user * buf, 
     size_t togo, loff_t *ppos)
 {
 	unsigned long p = *ppos;
-	char *tmp = buf;
+	char __user *tmp = buf;
 
 	union byte4 {
 		char s[4];
@@ -305,7 +305,7 @@
 	return tmp-buf;
 }
 
-static ssize_t jsf_write(struct file * file, const char * buf,
+static ssize_t jsf_write(struct file * file, const char __user * buf,
     size_t count, loff_t *ppos)
 {
 	return -ENOSPC;
@@ -356,10 +356,10 @@
  * Program a block of flash.
  * Very simple because we can do it byte by byte anyway.
  */
-static int jsf_ioctl_program(unsigned long arg)
+static int jsf_ioctl_program(void __user *arg)
 {
 	struct jsflash_program_arg abuf;
-	char *uptr;
+	char __user *uptr;
 	unsigned long p;
 	unsigned int togo;
 	union {
@@ -367,13 +367,13 @@
 		char s[4];
 	} b;
 
-	if (copy_from_user(&abuf, (char *)arg, JSFPRGSZ))
+	if (copy_from_user(&abuf, arg, JSFPRGSZ))
 		return -EFAULT; 
 	p = abuf.off;
 	togo = abuf.size;
 	if ((togo & 3) || (p & 3)) return -EINVAL;
 
-	uptr = (char *) (unsigned long) abuf.data;
+	uptr = (char __user *) (unsigned long) abuf.data;
 	while (togo != 0) {
 		togo -= 4;
 		if (copy_from_user(&b.s[0], uptr, 4))
@@ -390,19 +390,20 @@
     unsigned long arg)
 {
 	int error = -ENOTTY;
+	void __user *argp = (void __user *)arg;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
 	switch (cmd) {
 	case JSFLASH_IDENT:
-		if (copy_to_user((void *)arg, &jsf0.id, JSFIDSZ))
+		if (copy_to_user(argp, &jsf0.id, JSFIDSZ))
 			return -EFAULT;
 		break;
 	case JSFLASH_ERASE:
 		error = jsf_ioctl_erase(arg);
 		break;
 	case JSFLASH_PROGRAM:
-		error = jsf_ioctl_program(arg);
+		error = jsf_ioctl_program(argp);
 		break;
 	}
 
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
index 858cc68..e2d9a7c 100644
--- a/drivers/sbus/char/uctrl.c
+++ b/drivers/sbus/char/uctrl.c
@@ -309,7 +309,7 @@
 	}
 }
 
-void uctrl_get_event_status()
+void uctrl_get_event_status(void)
 {
 	struct uctrl_driver *driver = &drv;
 	struct uctrl_txn txn;
@@ -318,7 +318,7 @@
 	txn.opcode = READ_EVENT_STATUS;
 	txn.inbits = 0;
 	txn.outbits = 2;
-	txn.inbuf = 0;
+	txn.inbuf = NULL;
 	txn.outbuf = outbits;
 
 	uctrl_do_txn(&txn);
@@ -329,7 +329,7 @@
 	dprintk(("ev is %x\n", driver->status.event_status));
 }
 
-void uctrl_get_external_status()
+void uctrl_get_external_status(void)
 {
 	struct uctrl_driver *driver = &drv;
 	struct uctrl_txn txn;
@@ -339,7 +339,7 @@
 	txn.opcode = READ_EXTERNAL_STATUS;
 	txn.inbits = 0;
 	txn.outbits = 2;
-	txn.inbuf = 0;
+	txn.inbuf = NULL;
 	txn.outbuf = outbits;
 
 	uctrl_do_txn(&txn);
@@ -414,7 +414,7 @@
 	if (driver->irq)
 		free_irq(driver->irq, driver);
 	if (driver->regs)
-		driver->regs = 0;
+		driver->regs = NULL;
 }
 
 module_init(ts102_uctrl_init);
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h
index a7782e7..8045cd5 100644
--- a/drivers/sbus/char/vfc.h
+++ b/drivers/sbus/char/vfc.h
@@ -125,7 +125,7 @@
 
 
 struct vfc_dev {
-	volatile struct vfc_regs *regs;
+	volatile struct vfc_regs __iomem *regs;
 	struct vfc_regs *phys_regs;
 	unsigned int control_reg;
 	struct semaphore device_lock_sem;
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 7a10369..dfdd6be 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -149,7 +149,7 @@
 	}
 	printk("Initializing vfc%d\n",instance);
 	dev->regs = NULL;
-	dev->regs = (volatile struct vfc_regs *)
+	dev->regs = (volatile struct vfc_regs __iomem *)
 		sbus_ioremap(&sdev->resource[0], 0,
 			     sizeof(struct vfc_regs), vfcstr);
 	dev->which_io = sdev->reg_addrs[0].which_io;
@@ -319,7 +319,7 @@
 	int timeout = 1000;
 
 	while (!timeout--) {
-		if (dev->regs->control & VFC_STATUS_CAPTURE)
+		if (sbus_readl(&dev->regs->control) & VFC_STATUS_CAPTURE)
 			break;
 		vfc_i2c_delay_no_busy(dev, 100);
 	}
@@ -718,7 +718,7 @@
 	if(dev == NULL)
 		return;
 	devfs_remove("vfc/%d", dev->instance);
-	sbus_iounmap((unsigned long)dev->regs, sizeof(struct vfc_regs));
+	sbus_iounmap(dev->regs, sizeof(struct vfc_regs));
 	kfree(dev);
 }
 
diff --git a/drivers/scsi/.gitignore b/drivers/scsi/.gitignore
new file mode 100644
index 0000000..b385af3
--- /dev/null
+++ b/drivers/scsi/.gitignore
@@ -0,0 +1,3 @@
+53c700_d.h
+53c7xx_d.h
+53c7xx_u.h
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index e7ad269..4ce7438 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -857,7 +857,7 @@
 		printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
 		       host->host_no, pun, lun,
 		       NCR_700_phase[(dsps & 0xf00) >> 8]);
-		scsi_print_msg(hostdata->msgin);
+		spi_print_msg(hostdata->msgin);
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
@@ -887,7 +887,7 @@
 #ifdef NCR_700_DEBUG
 	printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
 	       NCR_700_phase[(dsps & 0xf00) >> 8]);
-	scsi_print_msg(hostdata->msgin);
+	spi_print_msg(hostdata->msgin);
 	printk("\n");
 #endif
 
@@ -939,7 +939,7 @@
 		       host->host_no, pun, lun,
 		       NCR_700_phase[(dsps & 0xf00) >> 8]);
 
-		scsi_print_msg(hostdata->msgin);
+		spi_print_msg(hostdata->msgin);
 		printk("\n");
 		/* just reject it */
 		hostdata->msgout[0] = A_REJECT_MSG;
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
index 362d784..a8c83bb 100644
--- a/drivers/scsi/53c700.h
+++ b/drivers/scsi/53c700.h
@@ -238,21 +238,23 @@
 #ifdef CONFIG_53C700_LE_ON_BE
 #define bE	(hostdata->force_le_on_be ? 0 : 3)
 #define	bSWAP	(hostdata->force_le_on_be)
-/* This is terrible, but there's no raw version of ioread32.  That means
- * that on a be board we swap twice (once in ioread32 and once again to 
- * get the value correct) */
-#define bS_to_io(x)	((hostdata->force_le_on_be) ? (x) : cpu_to_le32(x))
+#define bEBus	(!hostdata->force_le_on_be)
 #elif defined(__BIG_ENDIAN)
 #define bE	3
 #define bSWAP	0
-#define bS_to_io(x)	(x)
 #elif defined(__LITTLE_ENDIAN)
 #define bE	0
 #define bSWAP	0
-#define bS_to_io(x)	(x)
 #else
 #error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined, did you include byteorder.h?"
 #endif
+#ifndef bEBus
+#ifdef CONFIG_53C700_BE_BUS
+#define bEBus	1
+#else
+#define bEBus	0
+#endif
+#endif
 #define bS_to_cpu(x)	(bSWAP ? le32_to_cpu(x) : (x))
 #define bS_to_host(x)	(bSWAP ? cpu_to_le32(x) : (x))
 
@@ -466,14 +468,15 @@
 {
 	const struct NCR_700_Host_Parameters *hostdata
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
-	__u32 value = ioread32(hostdata->base + reg);
+	__u32 value = bEBus ? ioread32be(hostdata->base + reg) :
+		ioread32(hostdata->base + reg);
 #if 1
 	/* sanity check the register */
 	if((reg & 0x3) != 0)
 		BUG();
 #endif
 
-	return bS_to_io(value);
+	return value;
 }
 
 static inline void
@@ -497,7 +500,8 @@
 		BUG();
 #endif
 
-	iowrite32(bS_to_io(value), hostdata->base + reg);
+	bEBus ? iowrite32be(value, hostdata->base + reg): 
+		iowrite32(value, hostdata->base + reg);
 }
 
 #endif
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c
index 9cb5dd4..7894b8e 100644
--- a/drivers/scsi/53c7xx.c
+++ b/drivers/scsi/53c7xx.c
@@ -282,6 +282,7 @@
 #include "scsi.h"
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
 #include "53c7xx.h"
 #include <linux/stat.h>
 #include <linux/stddef.h>
@@ -1724,7 +1725,7 @@
 		printk ("scsi%d : status ", host->host_no);
 		scsi_print_status (status);
 		printk ("\nscsi%d : message ", host->host_no);
-		scsi_print_msg (&msg);
+		spi_print_msg(&msg);
 		printk ("\n");
 	    } else if (hostdata->test_completed == 3) {
 		printk("scsi%d : test 2 no connection with target %d\n",
@@ -2313,7 +2314,7 @@
 	    printk ("scsi%d : received message", host->host_no);
 	    if (c) 
 	    	printk (" from target %d lun %d ", c->device->id, c->device->lun);
-	    scsi_print_msg ((unsigned char *) hostdata->msg_buf);
+	    spi_print_msg((unsigned char *) hostdata->msg_buf);
 	    printk("\n");
 	}
 	
@@ -5540,7 +5541,7 @@
 	    i > 0 && !check_address ((unsigned long) ptr, 1);
 	    ptr += len, i -= len) {
 	    printk("               ");
-	    len = scsi_print_msg (ptr);
+	    len = spi_print_msg(ptr);
 	    printk("\n");
 	    if (!len)
 		break;
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 20dd85a..3c606cf 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -336,6 +336,7 @@
 config SCSI_AHA152X
 	tristate "Adaptec AHA152X/2825 support"
 	depends on ISA && SCSI && !64BIT
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825
 	  SCSI host adapters. It also works for the AVA-1505, but the IRQ etc.
@@ -623,6 +624,7 @@
 config SCSI_DMX3191D
 	tristate "DMX3191D SCSI support"
 	depends on PCI && SCSI
+	select SCSI_SPI_ATTRS
 	help
 	  This is support for Domex DMX3191D SCSI Host Adapters.
 
@@ -632,6 +634,7 @@
 config SCSI_DTC3280
 	tristate "DTC3180/3280 SCSI support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	help
 	  This is support for DTC 3180/3280 SCSI Host Adapters.  Please read
 	  the SCSI-HOWTO, available from
@@ -752,6 +755,7 @@
 config SCSI_GENERIC_NCR5380
 	tristate "Generic NCR5380/53c400 SCSI PIO support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is a driver for the old NCR 53c80 series of SCSI controllers
 	  on boards using PIO. Most boards such as the Trantor T130 fit this
@@ -771,6 +775,7 @@
 config SCSI_GENERIC_NCR5380_MMIO
 	tristate "Generic NCR5380/53c400 SCSI MMIO support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is a driver for the old NCR 53c80 series of SCSI controllers
 	  on boards using memory mapped I/O. 
@@ -909,7 +914,7 @@
 
 config SCSI_PPA
 	tristate "IOMEGA parallel port (ppa - older drives)"
-	depends on SCSI && PARPORT
+	depends on SCSI && PARPORT_PC
 	---help---
 	  This driver supports older versions of IOMEGA's parallel port ZIP
 	  drive (a 100 MB removable media device).
@@ -936,7 +941,7 @@
 
 config SCSI_IMM
 	tristate "IOMEGA parallel port (imm - newer drives)"
-	depends on SCSI && PARPORT
+	depends on SCSI && PARPORT_PC
 	---help---
 	  This driver supports newer versions of IOMEGA's parallel port ZIP
 	  drive (a 100 MB removable media device).
@@ -963,7 +968,7 @@
 
 config SCSI_IZIP_EPP16
 	bool "ppa/imm option - Use slow (but safe) EPP-16"
-	depends on PARPORT && (SCSI_PPA || SCSI_IMM)
+	depends on SCSI_PPA || SCSI_IMM
 	---help---
 	  EPP (Enhanced Parallel Port) is a standard for parallel ports which
 	  allows them to act as expansion buses that can handle up to 64
@@ -978,7 +983,7 @@
 
 config SCSI_IZIP_SLOW_CTR
 	bool "ppa/imm option - Assume slow parport control register"
-	depends on PARPORT && (SCSI_PPA || SCSI_IMM)
+	depends on SCSI_PPA || SCSI_IMM
 	help
 	  Some parallel ports are known to have excessive delays between
 	  changing the parallel port control register and good data being
@@ -1254,6 +1259,7 @@
 config SCSI_PAS16
 	tristate "PAS16 SCSI support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is support for a SCSI host adapter.  It is explained in section
 	  3.10 of the SCSI-HOWTO, available from
@@ -1423,6 +1429,7 @@
 config SCSI_T128
 	tristate "Trantor T128/T128F/T228 SCSI support"
 	depends on ISA && SCSI
+	select SCSI_SPI_ATTRS
 	---help---
 	  This is support for a SCSI host adapter. It is explained in section
 	  3.11 of the SCSI-HOWTO, available from
@@ -1681,6 +1688,7 @@
 config ATARI_SCSI
 	tristate "Atari native SCSI support"
 	depends on ATARI && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	---help---
 	  If you have an Atari with built-in NCR5380 SCSI controller (TT,
 	  Falcon, ...) say Y to get it supported. Of course also, if you have
@@ -1722,6 +1730,7 @@
 config MAC_SCSI
 	bool "Macintosh NCR5380 SCSI"
 	depends on MAC && SCSI=y
+	select SCSI_SPI_ATTRS
 	help
 	  This is the NCR 5380 SCSI controller included on most of the 68030
 	  based Macintoshes.  If you have one of these say Y and read the
@@ -1743,6 +1752,7 @@
 config MVME147_SCSI
 	bool "WD33C93 SCSI driver for MVME147"
 	depends on MVME147 && SCSI=y
+	select SCSI_SPI_ATTRS
 	help
 	  Support for the on-board SCSI controller on the Motorola MVME147
 	  single-board computer.
@@ -1750,6 +1760,7 @@
 config MVME16x_SCSI
 	bool "NCR53C710 SCSI driver for MVME16x"
 	depends on MVME16x && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	help
 	  The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
 	  SCSI controller chip.  Almost everyone using one of these boards
@@ -1758,6 +1769,7 @@
 config BVME6000_SCSI
 	bool "NCR53C710 SCSI driver for BVME6000"
 	depends on BVME6000 && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	help
 	  The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
 	  SCSI controller chip.  Almost everyone using one of these boards
@@ -1774,6 +1786,7 @@
 config SUN3_SCSI
 	tristate "Sun3 NCR5380 SCSI"
 	depends on SUN3 && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	help
 	  This option will enable support for the OBIO (onboard io) NCR5380
 	  SCSI controller found in the Sun 3/50 and 3/60, as well as for
@@ -1802,7 +1815,7 @@
 
 config ZFCP
 	tristate "FCP host bus adapter driver for IBM eServer zSeries"
-	depends on ARCH_S390 && QDIO && SCSI
+	depends on S390 && QDIO && SCSI
 	select SCSI_FC_ATTRS
 	help
           If you want to access SCSI devices attached to your IBM eServer
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index cba9655..9f0ddbe 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -87,6 +87,7 @@
  *      the high level code.
  */
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_spi.h>
 
 #ifndef NDEBUG
 #define NDEBUG 0
@@ -2377,7 +2378,7 @@
  * 3..length+1  arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since scsi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.  
  */
 					extended_msg[0] = EXTENDED_MESSAGE;
 					/* Accept first byte by clearing ACK */
@@ -2424,7 +2425,7 @@
 				default:
 					if (!tmp) {
 						printk("scsi%d: rejecting message ", instance->host_no);
-						scsi_print_msg(extended_msg);
+						spi_print_msg(extended_msg);
 						printk("\n");
 					} else if (tmp != EXTENDED_MESSAGE)
 						scmd_printk(KERN_INFO, cmd,
@@ -2560,7 +2561,7 @@
 
 	if (!(msg[0] & 0x80)) {
 		printk(KERN_ERR "scsi%d : expecting IDENTIFY message, got ", instance->host_no);
-		scsi_print_msg(msg);
+		spi_print_msg(msg);
 		abort = 1;
 	} else {
 		/* Accept message by clearing ACK */
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index ab383d1..3cb68af 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -325,6 +325,8 @@
 	 *	translations ( 64/32, 128/32, 255/63 ).
 	 */
 	buf = scsi_bios_ptable(bdev);
+	if (!buf)
+		return 0;
 	if(*(__le16 *)(buf + 0x40) == cpu_to_le16(0xaa55)) {
 		struct partition *first = (struct partition * )buf;
 		struct partition *entry = first;
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 9df23b6..cb2ee25 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -259,6 +259,7 @@
 #include "scsi.h"
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
 #include "aha152x.h"
 
 
@@ -1845,7 +1846,7 @@
 #if defined(AHA152X_DEBUG)
 		if (HOSTDATA(shpnt)->debug & debug_msgi) {
 			printk(INFO_LEAD "inbound message %02x ", CMDINFO(CURRENT_SC), MSGI(0));
-			scsi_print_msg(&MSGI(0));
+			spi_print_msg(&MSGI(0));
 			printk("\n");
 		}
 #endif
@@ -1933,7 +1934,7 @@
 						break;
 
 					printk(INFO_LEAD, CMDINFO(CURRENT_SC));
-					scsi_print_msg(&MSGI(0));
+					spi_print_msg(&MSGI(0));
 					printk("\n");
 
 					ticks = (MSGI(3) * 4 + 49) / 50;
@@ -2031,7 +2032,7 @@
 		int i;
 
 		printk(DEBUG_LEAD "messages( ", CMDINFO(CURRENT_SC));
-		for (i=0; i<MSGOLEN; i+=scsi_print_msg(&MSGO(i)), printk(" "))
+		for (i=0; i<MSGOLEN; i+=spi_print_msg(&MSGO(i)), printk(" "))
 			;
 		printk(")\n");
 	}
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index 83467a0..d113290 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -214,7 +214,6 @@
 	.dma_boundary		= AHCI_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 static const struct ata_port_operations ahci_ops = {
@@ -243,7 +242,7 @@
 	.port_stop		= ahci_port_stop,
 };
 
-static struct ata_port_info ahci_port_info[] = {
+static const struct ata_port_info ahci_port_info[] = {
 	/* board_ahci */
 	{
 		.sht		= &ahci_sht,
@@ -643,7 +642,8 @@
 	 	 * not being called from the SCSI EH.
 	 	 */
 		qc->scsidone = scsi_finish_command;
-		ata_qc_complete(qc, AC_ERR_OTHER);
+		qc->err_mask |= AC_ERR_OTHER;
+		ata_qc_complete(qc);
 	}
 
 	spin_unlock_irqrestore(&host_set->lock, flags);
@@ -664,7 +664,8 @@
 	ci = readl(port_mmio + PORT_CMD_ISSUE);
 	if (likely((ci & 0x1) == 0)) {
 		if (qc) {
-			ata_qc_complete(qc, 0);
+			assert(qc->err_mask == 0);
+			ata_qc_complete(qc);
 			qc = NULL;
 		}
 	}
@@ -681,8 +682,10 @@
 		/* command processing has stopped due to error; restart */
 		ahci_restart_port(ap, status);
 
-		if (qc)
-			ata_qc_complete(qc, err_mask);
+		if (qc) {
+			qc->err_mask |= AC_ERR_OTHER;
+			ata_qc_complete(qc);
+		}
 	}
 
 	return 1;
diff --git a/drivers/scsi/aic7xxx/.gitignore b/drivers/scsi/aic7xxx/.gitignore
new file mode 100644
index 0000000..b8ee24d
--- /dev/null
+++ b/drivers/scsi/aic7xxx/.gitignore
@@ -0,0 +1,6 @@
+aic79xx_reg.h
+aic79xx_reg_print.c
+aic79xx_seq.h
+aic7xxx_reg.h
+aic7xxx_reg_print.c
+aic7xxx_seq.h
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 31e9f40..1c8f872 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -1064,6 +1064,7 @@
 	struct	Scsi_Host *host;
 	char	*new_name;
 	u_long	s;
+	int	retval;
 
 	template->name = ahd->description;
 	host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
@@ -1096,9 +1097,15 @@
 
 	host->transportt = ahd_linux_transport_template;
 
-	scsi_add_host(host, &ahd->dev_softc->dev); /* XXX handle failure */
+	retval = scsi_add_host(host, &ahd->dev_softc->dev);
+	if (retval) {
+		printk(KERN_WARNING "aic79xx: scsi_add_host failed\n");
+		scsi_host_put(host);
+		return retval;
+	}
+
 	scsi_scan_host(host);
-	return (0);
+	return 0;
 }
 
 uint64_t
@@ -2105,7 +2112,7 @@
 					  scmd_id(cmd),
 					  scmd_channel(cmd) + 'A',
 					  CAM_LUN_WILDCARD,
-					  SCB_LIST_NULL, ROLE_INITIATOR) == 0)
+					  SCB_LIST_NULL, ROLE_INITIATOR))
 				break;
 		}
 	}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 7fc6454..fd389e9 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -1061,10 +1061,11 @@
 int
 ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template)
 {
-	char	 buf[80];
-	struct	 Scsi_Host *host;
+	char	buf[80];
+	struct	Scsi_Host *host;
 	char	*new_name;
-	u_long	 s;
+	u_long	s;
+	int	retval;
 
 	template->name = ahc->description;
 	host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
@@ -1097,9 +1098,16 @@
 
 	host->transportt = ahc_linux_transport_template;
 
-	scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */
+	retval = scsi_add_host(host,
+			(ahc->dev_softc ? &ahc->dev_softc->dev : NULL));
+	if (retval) {
+		printk(KERN_WARNING "aic7xxx: scsi_add_host failed\n");
+		scsi_host_put(host);
+		return retval;
+	}
+
 	scsi_scan_host(host);
-	return (0);
+	return 0;
 }
 
 /*
@@ -2169,7 +2177,7 @@
 		  	if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd),
 					  scmd_channel(cmd) + 'A',
 					  CAM_LUN_WILDCARD,
-					  SCB_LIST_NULL, ROLE_INITIATOR) == 0)
+					  SCB_LIST_NULL, ROLE_INITIATOR))
 				break;
 		}
 	}
diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig
index 13f2304..06d7601 100644
--- a/drivers/scsi/arm/Kconfig
+++ b/drivers/scsi/arm/Kconfig
@@ -4,6 +4,7 @@
 config SCSI_ACORNSCSI_3
 	tristate "Acorn SCSI card (aka30) support"
 	depends on ARCH_ACORN && SCSI && BROKEN
+	select SCSI_SPI_ATTRS
 	help
 	  This enables support for the Acorn SCSI card (aka30). If you have an
 	  Acorn system with one of these, say Y. If unsure, say N.
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index b7b20c6..09ed057 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -152,6 +152,7 @@
 #include "../scsi.h"
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_transport_spi.h>
 #include "acornscsi.h"
 #include "msgqueue.h"
 #include "scsi.h"
@@ -1370,7 +1371,7 @@
 
 	host->scsi.last_message = msg->msg[0];
 #if (DEBUG & DEBUG_MESSAGES)
-	scsi_print_msg(msg->msg);
+	spi_print_msg(msg->msg);
 #endif
 	break;
 
@@ -1392,7 +1393,7 @@
 	while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) {
 	    unsigned int i;
 #if (DEBUG & DEBUG_MESSAGES)
-	    scsi_print_msg(msg);
+	    spi_print_msg(msg);
 #endif
 	    i = 0;
 	    if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000))
@@ -1488,7 +1489,7 @@
 #if (DEBUG & DEBUG_MESSAGES)
     printk("scsi%d.%c: message in: ",
 	    host->host->host_no, acornscsi_target(host));
-    scsi_print_msg(message);
+    spi_print_msg(message);
     printk("\n");
 #endif
 
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 333d69d..557788e 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -37,6 +37,49 @@
  *
  *  Hardware documentation available at http://developer.intel.com/
  *
+ * Documentation
+ *	Publically available from Intel web site. Errata documentation
+ * is also publically available. As an aide to anyone hacking on this
+ * driver the list of errata that are relevant is below.going back to
+ * PIIX4. Older device documentation is now a bit tricky to find.
+ *
+ * The chipsets all follow very much the same design. The orginal Triton
+ * series chipsets do _not_ support independant device timings, but this
+ * is fixed in Triton II. With the odd mobile exception the chips then
+ * change little except in gaining more modes until SATA arrives. This
+ * driver supports only the chips with independant timing (that is those
+ * with SITRE and the 0x44 timing register). See pata_oldpiix and pata_mpiix
+ * for the early chip drivers.
+ *
+ * Errata of note:
+ *
+ * Unfixable
+ *	PIIX4    errata #9	- Only on ultra obscure hw
+ *	ICH3	 errata #13     - Not observed to affect real hw
+ *				  by Intel
+ *
+ * Things we must deal with
+ *	PIIX4	errata #10	- BM IDE hang with non UDMA
+ *				  (must stop/start dma to recover)
+ *	440MX   errata #15	- As PIIX4 errata #10
+ *	PIIX4	errata #15	- Must not read control registers
+ * 				  during a PIO transfer
+ *	440MX   errata #13	- As PIIX4 errata #15
+ *	ICH2	errata #21	- DMA mode 0 doesn't work right
+ *	ICH0/1  errata #55	- As ICH2 errata #21
+ *	ICH2	spec c #9	- Extra operations needed to handle
+ *				  drive hotswap [NOT YET SUPPORTED]
+ *	ICH2    spec c #20	- IDE PRD must not cross a 64K boundary
+ *				  and must be dword aligned
+ *	ICH2    spec c #24	- UDMA mode 4,5 t85/86 should be 6ns not 3.3
+ *
+ * Should have been BIOS fixed:
+ *	450NX:	errata #19	- DMA hangs on old 450NX
+ *	450NX:  errata #20	- DMA hangs on old 450NX
+ *	450NX:  errata #25	- Corruption with DMA on old 450NX
+ *	ICH3    errata #15      - IDE deadlock under high load
+ *				  (BIOS must set dev 31 fn 0 bit 23)
+ *	ICH3	errata #18	- Don't use native mode
  */
 
 #include <linux/kernel.h>
@@ -78,9 +121,7 @@
 	ich5_sata		= 1,
 	piix4_pata		= 2,
 	ich6_sata		= 3,
-	ich6_sata_rm		= 4,
-	ich7_sata		= 5,
-	esb2_sata		= 6,
+	ich6_sata_ahci		= 4,
 
 	PIIX_AHCI_DEVICE	= 6,
 };
@@ -111,11 +152,11 @@
 	{ 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
 	{ 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
 	{ 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
-	{ 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
-	{ 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_rm },
-	{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
-	{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich7_sata },
-	{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb2_sata },
+	{ 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+	{ 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
 
 	{ }	/* terminate list */
 };
@@ -125,6 +166,8 @@
 	.id_table		= piix_pci_tbl,
 	.probe			= piix_init_one,
 	.remove			= ata_pci_remove_one,
+	.suspend		= ata_pci_device_suspend,
+	.resume			= ata_pci_device_resume,
 };
 
 static struct scsi_host_template piix_sht = {
@@ -144,7 +187,8 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
+	.resume			= ata_scsi_device_resume,
+	.suspend		= ata_scsi_device_suspend,
 };
 
 static const struct ata_port_operations piix_pata_ops = {
@@ -258,31 +302,7 @@
 		.port_ops	= &piix_sata_ops,
 	},
 
-	/* ich6_sata_rm */
-	{
-		.sht		= &piix_sht,
-		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
-				  PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
-				  ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
-		.udma_mask	= 0x7f,	/* udma0-6 */
-		.port_ops	= &piix_sata_ops,
-	},
-
-	/* ich7_sata */
-	{
-		.sht		= &piix_sht,
-		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
-				  PIIX_FLAG_COMBINED | PIIX_FLAG_CHECKINTR |
-				  ATA_FLAG_SLAVE_POSS | PIIX_FLAG_AHCI,
-		.pio_mask	= 0x1f,	/* pio0-4 */
-		.mwdma_mask	= 0x07, /* mwdma0-2 */
-		.udma_mask	= 0x7f,	/* udma0-6 */
-		.port_ops	= &piix_sata_ops,
-	},
-
-	/* esb2_sata */
+	/* ich6_sata_ahci */
 	{
 		.sht		= &piix_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_SRST |
@@ -603,6 +623,40 @@
 }
 
 /**
+ *	piix_check_450nx_errata	-	Check for problem 450NX setup
+ *	
+ *	Check for the present of 450NX errata #19 and errata #25. If
+ *	they are found return an error code so we can turn off DMA
+ */
+
+static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
+{
+	struct pci_dev *pdev = NULL;
+	u16 cfg;
+	u8 rev;
+	int no_piix_dma = 0;
+	
+	while((pdev = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, pdev)) != NULL)
+	{
+		/* Look for 450NX PXB. Check for problem configurations
+		   A PCI quirk checks bit 6 already */
+		pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
+		pci_read_config_word(pdev, 0x41, &cfg);
+		/* Only on the original revision: IDE DMA can hang */
+		if(rev == 0x00)
+			no_piix_dma = 1;
+		/* On all revisions below 5 PXB bus lock must be disabled for IDE */
+		else if(cfg & (1<<14) && rev < 5)
+			no_piix_dma = 2;
+	}
+	if(no_piix_dma)
+		dev_printk(KERN_WARNING, &ata_dev->dev, "450NX errata present, disabling IDE DMA.\n");
+	if(no_piix_dma == 2)
+		dev_printk(KERN_WARNING, &ata_dev->dev, "A BIOS update may resolve this.\n");
+	return no_piix_dma;
+}		
+
+/**
  *	piix_init_one - Register PIIX ATA PCI device with kernel services
  *	@pdev: PCI device to register
  *	@ent: Entry in piix_pci_tbl matching with @pdev
@@ -676,7 +730,15 @@
 			   "combined mode detected (p=%u, s=%u)\n",
 			   pata_chan, sata_chan);
 	}
-
+	if (piix_check_450nx_errata(pdev)) {
+		/* This writes into the master table but it does not
+		   really matter for this errata as we will apply it to
+		   all the PIIX devices on the board */
+		port_info[0]->mwdma_mask = 0;
+		port_info[0]->udma_mask = 0;
+		port_info[1]->mwdma_mask = 0;
+		port_info[1]->udma_mask = 0;
+	}
 	return ata_pci_init_one(pdev, port_info, 2);
 }
 
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 2ae31ce..57295bce 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -74,6 +74,7 @@
  *     the high level code.
  */
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_spi.h>
 
 #if (NDEBUG & NDEBUG_LISTS)
 #define LIST(x,y) \
@@ -2355,7 +2356,7 @@
  * 3..length+1	arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since scsi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.  
  */
 		    extended_msg[0] = EXTENDED_MESSAGE;
 		    /* Accept first byte by clearing ACK */
@@ -2408,7 +2409,7 @@
 		default:
 		    if (!tmp) {
 			printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
-			scsi_print_msg (extended_msg);
+			spi_print_msg(extended_msg);
 			printk("\n");
 		    } else if (tmp != EXTENDED_MESSAGE)
 			printk(KERN_DEBUG "scsi%d: rejecting unknown "
@@ -2541,7 +2542,7 @@
 
     if (!(msg[0] & 0x80)) {
 	printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
-	scsi_print_msg(msg);
+	spi_print_msg(msg);
 	do_abort(instance);
 	return;
     }
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index ccbbae2..0920220 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -75,7 +75,7 @@
 module_param_array(vendor_firsts, int, NULL, 0444);
 module_param_array(vendor_counts, int, NULL, 0444);
 
-static char *vendor_labels[CH_TYPES-4] = {
+static const char * vendor_labels[CH_TYPES-4] = {
 	"v0", "v1", "v2", "v3"
 };
 // module_param_string_array(vendor_labels, NULL, 0444);
@@ -140,7 +140,7 @@
 #endif
 };
 
-static struct {
+static const struct {
 	unsigned char  sense;
 	unsigned char  asc;
 	unsigned char  ascq;
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 09bc815..30a3353 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1065,7 +1065,7 @@
 	const char * fmt;
 };
 
-static struct error_info2 additional2[] =
+static const struct error_info2 additional2[] =
 {
 	{0x40,0x00,0x7f,"Ram failure (%x)"},
 	{0x40,0x80,0xff,"Diagnostic failure on component (%x)"},
@@ -1077,7 +1077,7 @@
 };
 
 /* description of the sense key values */
-static const char *snstext[] = {
+static const char * const snstext[] = {
 	"No Sense",	    /* 0: There is no sense information */
 	"Recovered Error",  /* 1: The last command completed successfully
 				  but used error correction */
@@ -1278,114 +1278,6 @@
 }
 EXPORT_SYMBOL(scsi_print_req_sense);
 
-#ifdef CONFIG_SCSI_CONSTANTS
-static const char *one_byte_msgs[] = {
-/* 0x00 */ "Command Complete", NULL, "Save Pointers",
-/* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", 
-/* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error",
-/* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag",
-/* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
-/* 0x0f */ "Initiate Recovery", "Release Recovery"
-};
-#define NO_ONE_BYTE_MSGS (sizeof(one_byte_msgs)  / sizeof (const char *))
-
-static const char *two_byte_msgs[] = {
-/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag"
-/* 0x23 */ "Ignore Wide Residue"
-};
-#define NO_TWO_BYTE_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
-
-static const char *extended_msgs[] = {
-/* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
-/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request"
-};
-#define NO_EXTENDED_MSGS (sizeof(two_byte_msgs)  / sizeof (const char *))
-
-
-int scsi_print_msg (const unsigned char *msg)
-{
-	int len = 0, i;
-	if (msg[0] == EXTENDED_MESSAGE) {
-		len = 3 + msg[1];
-		if (msg[2] < NO_EXTENDED_MSGS)
-			printk ("%s ", extended_msgs[msg[2]]); 
-		else 
-			printk ("Extended Message, reserved code (0x%02x) ",
-				(int) msg[2]);
-		switch (msg[2]) {
-		case EXTENDED_MODIFY_DATA_POINTER:
-			printk("pointer = %d", (int) (msg[3] << 24) |
-				(msg[4] << 16) | (msg[5] << 8) | msg[6]);
-			break;
-		case EXTENDED_SDTR:
-			printk("period = %d ns, offset = %d",
-				(int) msg[3] * 4, (int) msg[4]);
-			break;
-		case EXTENDED_WDTR:
-			printk("width = 2^%d bytes", msg[3]);
-			break;
-		default:
-		for (i = 2; i < len; ++i) 
-			printk("%02x ", msg[i]);
-		}
-	/* Identify */
-	} else if (msg[0] & 0x80) {
-		printk("Identify disconnect %sallowed %s %d ",
-			(msg[0] & 0x40) ? "" : "not ",
-			(msg[0] & 0x20) ? "target routine" : "lun",
-			msg[0] & 0x7);
-		len = 1;
-	/* Normal One byte */
-	} else if (msg[0] < 0x1f) {
-		if (msg[0] < NO_ONE_BYTE_MSGS)
-			printk(one_byte_msgs[msg[0]]);
-		else
-			printk("reserved (%02x) ", msg[0]);
-		len = 1;
-	/* Two byte */
-	} else if (msg[0] <= 0x2f) {
-		if ((msg[0] - 0x20) < NO_TWO_BYTE_MSGS)
-			printk("%s %02x ", two_byte_msgs[msg[0] - 0x20], 
-				msg[1]);
-		else 
-			printk("reserved two byte (%02x %02x) ", 
-				msg[0], msg[1]);
-		len = 2;
-	} else 
-		printk("reserved");
-	return len;
-}
-EXPORT_SYMBOL(scsi_print_msg);
-
-#else  /* ifndef CONFIG_SCSI_CONSTANTS */
-
-int scsi_print_msg (const unsigned char *msg)
-{
-	int len = 0, i;
-
-	if (msg[0] == EXTENDED_MESSAGE) {
-		len = 3 + msg[1];
-		for (i = 0; i < len; ++i)
-			printk("%02x ", msg[i]);
-	/* Identify */
-	} else if (msg[0] & 0x80) {
-		printk("%02x ", msg[0]);
-		len = 1;
-	/* Normal One byte */
-	} else if (msg[0] < 0x1f) {
-		printk("%02x ", msg[0]);
-		len = 1;
-	/* Two byte */
-	} else if (msg[0] <= 0x2f) {
-		printk("%02x %02x", msg[0], msg[1]);
-		len = 2;
-	} else 
-		printk("%02x ", msg[0]);
-	return len;
-}
-EXPORT_SYMBOL(scsi_print_msg);
-#endif /* ! CONFIG_SCSI_CONSTANTS */
-
 void scsi_print_command(struct scsi_cmnd *cmd)
 {
 	/* Assume appended output (i.e. not at start of line) */
@@ -1397,7 +1289,7 @@
 
 #ifdef CONFIG_SCSI_CONSTANTS
 
-static const char * hostbyte_table[]={
+static const char * const hostbyte_table[]={
 "DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", 
 "DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
 "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"};
@@ -1422,12 +1314,12 @@
 
 #ifdef CONFIG_SCSI_CONSTANTS
 
-static const char * driverbyte_table[]={
+static const char * const driverbyte_table[]={
 "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT",  "DRIVER_MEDIA", "DRIVER_ERROR", 
 "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
 #define NUM_DRIVERBYTE_STRS (sizeof(driverbyte_table) / sizeof(const char *))
 
-static const char * driversuggest_table[]={"SUGGEST_OK",
+static const char * const driversuggest_table[]={"SUGGEST_OK",
 "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
 "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
 #define NUM_SUGGEST_STRS (sizeof(driversuggest_table) / sizeof(const char *))
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 418fc7b..6252b9d 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -660,7 +660,12 @@
 	msg[2] = 0;
 	msg[3]= 0; 
 	msg[4] = (u32)cmd;
-	if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){
+	if (pHba->host)
+		spin_lock_irq(pHba->host->host_lock);
+	rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
+	if (pHba->host)
+		spin_unlock_irq(pHba->host->host_lock);
+	if (rcode != 0) {
 		if(rcode == -EOPNOTSUPP ){
 			printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
 			return FAILED;
@@ -697,10 +702,15 @@
 	msg[2] = 0;
 	msg[3] = 0;
 
+	if (pHba->host)
+		spin_lock_irq(pHba->host->host_lock);
 	old_state = d->state;
 	d->state |= DPTI_DEV_RESET;
-	if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){
-		d->state = old_state;
+	rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
+	d->state = old_state;
+	if (pHba->host)
+		spin_unlock_irq(pHba->host->host_lock);
+	if (rcode != 0) {
 		if(rcode == -EOPNOTSUPP ){
 			printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
 			return FAILED;
@@ -708,7 +718,6 @@
 		printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
 		return FAILED;
 	} else {
-		d->state = old_state;
 		printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
 		return SUCCESS;
 	}
@@ -721,6 +730,7 @@
 {
 	adpt_hba* pHba;
 	u32 msg[4];
+	u32 rcode;
 
 	pHba = (adpt_hba*)cmd->device->host->hostdata[0];
 	memset(msg, 0, sizeof(msg));
@@ -729,7 +739,12 @@
 	msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
 	msg[2] = 0;
 	msg[3] = 0;
-	if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){
+	if (pHba->host)
+		spin_lock_irq(pHba->host->host_lock);
+	rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
+	if (pHba->host)
+		spin_unlock_irq(pHba->host->host_lock);
+	if (rcode != 0) {
 		printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
 		return FAILED;
 	} else {
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 5b9c2c5..66783c8 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -347,17 +347,8 @@
 	shost->cmd_per_lun = sht->cmd_per_lun;
 	shost->unchecked_isa_dma = sht->unchecked_isa_dma;
 	shost->use_clustering = sht->use_clustering;
-	shost->ordered_flush = sht->ordered_flush;
 	shost->ordered_tag = sht->ordered_tag;
 
-	/*
-	 * hosts/devices that do queueing must support ordered tags
-	 */
-	if (shost->can_queue > 1 && shost->ordered_flush) {
-		printk(KERN_ERR "scsi: ordered flushes don't support queueing\n");
-		shost->ordered_flush = 0;
-	}
-
 	if (sht->max_host_blocked)
 		shost->max_host_blocked = sht->max_host_blocked;
 	else
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h
index 8bec043..5b0edd1 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.h
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.h
@@ -100,7 +100,7 @@
 void ibmvscsi_release_crq_queue(struct crq_queue *queue,
 				struct ibmvscsi_host_data *hostdata,
 				int max_requests);
-void ibmvscsi_reset_crq_queue(struct crq_queue *queue,
+int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
 			      struct ibmvscsi_host_data *hostdata);
 
 void ibmvscsi_handle_crq(struct viosrp_crq *crq,
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c
index 1045872..ce15d9e 100644
--- a/drivers/scsi/ibmvscsi/iseries_vscsi.c
+++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c
@@ -117,9 +117,10 @@
  *
  * no-op for iSeries
  */
-void ibmvscsi_reset_crq_queue(struct crq_queue *queue,
+int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
 			      struct ibmvscsi_host_data *hostdata)
 {
+	return 0;
 }
 
 /**
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c
index 8bf5652..75db2f5 100644
--- a/drivers/scsi/ibmvscsi/rpa_vscsi.c
+++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c
@@ -230,6 +230,11 @@
 	rc = plpar_hcall_norets(H_REG_CRQ,
 				vdev->unit_address,
 				queue->msg_token, PAGE_SIZE);
+	if (rc == H_Resource) 
+		/* maybe kexecing and resource is busy. try a reset */
+		rc = ibmvscsi_reset_crq_queue(queue,
+					      hostdata);
+
 	if (rc == 2) {
 		/* Adapter is good, but other end is not ready */
 		printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n");
@@ -281,7 +286,7 @@
  * @hostdata:	ibmvscsi_host_data of host
  *
  */
-void ibmvscsi_reset_crq_queue(struct crq_queue *queue,
+int ibmvscsi_reset_crq_queue(struct crq_queue *queue,
 			      struct ibmvscsi_host_data *hostdata)
 {
 	int rc;
@@ -309,4 +314,5 @@
 		printk(KERN_WARNING
 		       "ibmvscsi: couldn't register crq--rc 0x%x\n", rc);
 	}
+	return rc;
 }
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 4cb1f3e..3c688ef 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -1046,7 +1046,7 @@
 
 	/* kill current request */
 	blkdev_dequeue_request(req);
-	end_that_request_last(req);
+	end_that_request_last(req, 0);
 	if (req->flags & REQ_SENSE)
 		kfree(scsi->pc->buffer);
 	kfree(scsi->pc);
@@ -1056,7 +1056,7 @@
 	/* now nuke the drive queue */
 	while ((req = elv_next_request(drive->queue))) {
 		blkdev_dequeue_request(req);
-		end_that_request_last(req);
+		end_that_request_last(req, 0);
 	}
 
 	HWGROUP(drive)->rq = NULL;
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index fa2cb358..27acf78 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2132,7 +2132,7 @@
 	}
 
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-	kobject_uevent(&ioa_cfg->host->shost_classdev.kobj, KOBJ_CHANGE, NULL);
+	kobject_uevent(&ioa_cfg->host->shost_classdev.kobj, KOBJ_CHANGE);
 	LEAVE;
 }
 
@@ -5887,7 +5887,12 @@
 	ENTER;
 	spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags);
 	dev_dbg(&ioa_cfg->pdev->dev, "ioa_cfg adx: 0x%p\n", ioa_cfg);
-	_ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, IPR_SHUTDOWN_NONE);
+	if (ioa_cfg->needs_hard_reset) {
+		ioa_cfg->needs_hard_reset = 0;
+		ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+	} else
+		_ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa,
+					IPR_SHUTDOWN_NONE);
 
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
 	wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload);
@@ -6264,6 +6269,7 @@
 	unsigned long ipr_regs_pci;
 	void __iomem *ipr_regs;
 	u32 rc = PCIBIOS_SUCCESSFUL;
+	volatile u32 mask, uproc;
 
 	ENTER;
 
@@ -6356,6 +6362,15 @@
 		goto cleanup_nomem;
 	}
 
+	/*
+	 * If HRRQ updated interrupt is not masked, or reset alert is set,
+	 * the card is in an unknown state and needs a hard reset
+	 */
+	mask = readl(ioa_cfg->regs.sense_interrupt_mask_reg);
+	uproc = readl(ioa_cfg->regs.sense_uproc_interrupt_reg);
+	if ((mask & IPR_PCII_HRRQ_UPDATED) == 0 || (uproc & IPR_UPROCI_RESET_ALERT))
+		ioa_cfg->needs_hard_reset = 1;
+
 	ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER);
 	rc = request_irq(pdev->irq, ipr_isr, SA_SHIRQ, IPR_NAME, ioa_cfg);
 
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 6bec673..b639332 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -36,8 +36,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.1.0"
-#define IPR_DRIVER_DATE "(October 31, 2005)"
+#define IPR_DRIVER_VERSION "2.1.1"
+#define IPR_DRIVER_DATE "(November 15, 2005)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -922,6 +922,7 @@
 	u8 dump_taken:1;
 	u8 allow_cmds:1;
 	u8 allow_ml_add_del:1;
+	u8 needs_hard_reset:1;
 
 	enum ipr_cache_state cache_state;
 	u16 type; /* CCIN of the card */
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 4fea3e4..10bcf42 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -49,7 +49,7 @@
 	      "Alex Aizman <itn780@yahoo.com>");
 MODULE_DESCRIPTION("iSCSI/TCP data-path");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("0:4.409");
+MODULE_VERSION("0:4.445");
 /* #define DEBUG_TCP */
 /* #define DEBUG_SCSI */
 #define DEBUG_ASSERT
@@ -581,10 +581,16 @@
 		crypto_digest_digest(conn->rx_tfm, &sg, 1, (u8 *)&cdgst);
 		rdgst = *(uint32_t*)((char*)hdr + sizeof(struct iscsi_hdr) +
 				     conn->in.ahslen);
+		if (cdgst != rdgst) {
+			printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "
+			       "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,
+			       cdgst);
+			return ISCSI_ERR_HDR_DGST;
+		}
 	}
 
 	/* save opcode for later */
-	conn->in.opcode = hdr->opcode;
+	conn->in.opcode = hdr->opcode & ISCSI_OPCODE_MASK;
 
 	/* verify itt (itt encoding: age+cid+itt) */
 	if (hdr->itt != cpu_to_be32(ISCSI_RESERVED_TAG)) {
@@ -610,13 +616,6 @@
 		  conn->in.ahslen, conn->in.datalen);
 
 	if (conn->in.itt < session->cmds_max) {
-		if (conn->hdrdgst_en && cdgst != rdgst) {
-			printk(KERN_ERR "iscsi_tcp: itt %x: hdrdgst error "
-			       "recv 0x%x calc 0x%x\n", conn->in.itt, rdgst,
-			       cdgst);
-			return ISCSI_ERR_HDR_DGST;
-		}
-
 		ctask = (struct iscsi_cmd_task *)session->cmds[conn->in.itt];
 
 		if (!ctask->sc) {
@@ -642,9 +641,7 @@
 		switch(conn->in.opcode) {
 		case ISCSI_OP_SCSI_CMD_RSP:
 			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
-			if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE)
-				rc = iscsi_cmd_rsp(conn, ctask);
-			else if (!conn->in.datalen)
+			if (!conn->in.datalen)
 				rc = iscsi_cmd_rsp(conn, ctask);
 			else
 				/*
@@ -666,8 +663,7 @@
 			break;
 		case ISCSI_OP_R2T:
 			BUG_ON((void*)ctask != ctask->sc->SCp.ptr);
-			if (ctask->hdr.flags & ISCSI_FLAG_CMD_WRITE &&
-			    ctask->sc->sc_data_direction == DMA_TO_DEVICE)
+			if (ctask->sc->sc_data_direction == DMA_TO_DEVICE)
 				rc = iscsi_r2t_rsp(conn, ctask);
 			else
 				rc = ISCSI_ERR_PROTO;
@@ -906,11 +902,20 @@
 	crypto_digest_update(conn->data_rx_tfm, &temp, 1);
 }
 
+static void
+iscsi_recv_digest_update(struct iscsi_conn *conn, char* buf, int len)
+{
+	struct scatterlist tmp;
+
+	sg_init_one(&tmp, buf, len);
+	crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
+}
+
 static int iscsi_scsi_data_in(struct iscsi_conn *conn)
 {
 	struct iscsi_cmd_task *ctask = conn->in.ctask;
 	struct scsi_cmnd *sc = ctask->sc;
-	struct scatterlist tmp, *sg;
+	struct scatterlist *sg;
 	int i, offset, rc = 0;
 
 	BUG_ON((void*)ctask != sc->SCp.ptr);
@@ -924,10 +929,8 @@
 				      sc->request_bufflen, ctask->data_offset);
 		if (rc == -EAGAIN)
 			return rc;
-		if (conn->datadgst_en) {
-			sg_init_one(&tmp, sc->request_buffer, i);
-			crypto_digest_update(conn->data_rx_tfm, &tmp, 1);
-		}
+		if (conn->datadgst_en) 
+			iscsi_recv_digest_update(conn, sc->request_buffer, i);
 		rc = 0;
 		goto done;
 	}
@@ -1021,6 +1024,9 @@
 		conn->in.hdr = &conn->hdr;
 		conn->senselen = (conn->data[0] << 8) | conn->data[1];
 		rc = iscsi_cmd_rsp(conn, conn->in.ctask);
+		if (!rc && conn->datadgst_en) 
+			iscsi_recv_digest_update(conn, conn->data,
+						 conn->in.datalen);
 	}
 	break;
 	case ISCSI_OP_TEXT_RSP:
@@ -1045,6 +1051,11 @@
 		rc = iscsi_recv_pdu(iscsi_handle(conn), conn->in.hdr,
 				    conn->data, conn->in.datalen);
 
+		if (!rc && conn->datadgst_en && 
+			conn->in.opcode != ISCSI_OP_LOGIN_RSP)
+			iscsi_recv_digest_update(conn, conn->data,
+			  			conn->in.datalen);
+
 		if (mtask && conn->login_mtask != mtask) {
 			spin_lock(&session->lock);
 			__kfifo_put(session->mgmtpool.queue, (void*)&mtask,
@@ -1053,6 +1064,8 @@
 		}
 	}
 	break;
+	case ISCSI_OP_ASYNC_EVENT:
+	case ISCSI_OP_REJECT:
 	default:
 		BUG_ON(1);
 	}
@@ -1114,8 +1127,7 @@
 		 */
 		rc = iscsi_hdr_recv(conn);
 		if (!rc && conn->in.datalen) {
-			if (conn->datadgst_en &&
-			    conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+			if (conn->datadgst_en) {
 				BUG_ON(!conn->data_rx_tfm);
 				crypto_digest_init(conn->data_rx_tfm);
 			}
@@ -1127,26 +1139,24 @@
 	}
 
 	if (conn->in_progress == IN_PROGRESS_DDIGEST_RECV) {
+		uint32_t recv_digest;
 		debug_tcp("extra data_recv offset %d copy %d\n",
 			  conn->in.offset, conn->in.copy);
-		if (conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
-			uint32_t recv_digest;
-			skb_copy_bits(conn->in.skb, conn->in.offset,
-				      &recv_digest, 4);
-			conn->in.offset += 4;
-			conn->in.copy -= 4;
-			if (recv_digest != conn->in.datadgst) {
-				debug_tcp("iscsi_tcp: data digest error!"
-					  "0x%x != 0x%x\n", recv_digest,
-					  conn->in.datadgst);
-				iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
-				return 0;
-			} else {
-				debug_tcp("iscsi_tcp: data digest match!"
-					  "0x%x == 0x%x\n", recv_digest,
-					  conn->in.datadgst);
-				conn->in_progress = IN_PROGRESS_WAIT_HEADER;
-			}
+		skb_copy_bits(conn->in.skb, conn->in.offset,
+				&recv_digest, 4);
+		conn->in.offset += 4;
+		conn->in.copy -= 4;
+		if (recv_digest != conn->in.datadgst) {
+			debug_tcp("iscsi_tcp: data digest error!"
+				  "0x%x != 0x%x\n", recv_digest,
+				  conn->in.datadgst);
+			iscsi_conn_failure(conn, ISCSI_ERR_DATA_DGST);
+			return 0;
+		} else {
+			debug_tcp("iscsi_tcp: data digest match!"
+				  "0x%x == 0x%x\n", recv_digest,
+				  conn->in.datadgst);
+			conn->in_progress = IN_PROGRESS_WAIT_HEADER;
 		}
 	}
 
@@ -1167,8 +1177,7 @@
 		}
 		conn->in.copy -= conn->in.padding;
 		conn->in.offset += conn->in.padding;
-		if (conn->datadgst_en &&
-		    conn->in.opcode == ISCSI_OP_SCSI_DATA_IN) {
+		if (conn->datadgst_en) {
 			if (conn->in.padding) {
 				debug_tcp("padding -> %d\n", conn->in.padding);
 				memset(pad, 0, conn->in.padding);
@@ -1237,8 +1246,9 @@
 	conn = (struct iscsi_conn*)sk->sk_user_data;
 	session = conn->session;
 
-	if (sk->sk_state == TCP_CLOSE_WAIT ||
-	    sk->sk_state == TCP_CLOSE) {
+	if ((sk->sk_state == TCP_CLOSE_WAIT ||
+	     sk->sk_state == TCP_CLOSE) &&
+	    !atomic_read(&sk->sk_rmem_alloc)) {
 		debug_tcp("iscsi_tcp_state_change: TCP_CLOSE|TCP_CLOSE_WAIT\n");
 		iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
 	}
@@ -2389,6 +2399,15 @@
 }
 
 static int
+iscsi_change_queue_depth(struct scsi_device *sdev, int depth)
+{
+	if (depth > ISCSI_MAX_CMD_PER_LUN)
+		depth = ISCSI_MAX_CMD_PER_LUN;
+	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth);
+	return sdev->queue_depth;
+}
+
+static int
 iscsi_pool_init(struct iscsi_queue *q, int max, void ***items, int item_size)
 {
 	int i;
@@ -2853,8 +2872,11 @@
 		 * in hdr_extract() and will be re-negotiated at
 		 * set_param() time.
 		 */
-		if (flag == STOP_CONN_RECOVER)
+		if (flag == STOP_CONN_RECOVER) {
 			conn->hdr_size = sizeof(struct iscsi_hdr);
+			conn->hdrdgst_en = 0;
+			conn->datadgst_en = 0;
+		}
 	}
 	up(&conn->xmitsema);
 }
@@ -3247,13 +3269,14 @@
 static struct scsi_host_template iscsi_sht = {
 	.name			= "iSCSI Initiator over TCP/IP, v."
 				  ISCSI_VERSION_STR,
-        .queuecommand           = iscsi_queuecommand,
+	.queuecommand           = iscsi_queuecommand,
+	.change_queue_depth	= iscsi_change_queue_depth,
 	.can_queue		= ISCSI_XMIT_CMDS_MAX - 1,
 	.sg_tablesize		= ISCSI_SG_TABLESIZE,
-	.cmd_per_lun		= ISCSI_CMD_PER_LUN,
-        .eh_abort_handler       = iscsi_eh_abort,
-        .eh_host_reset_handler	= iscsi_eh_host_reset,
-        .use_clustering         = DISABLE_CLUSTERING,
+	.cmd_per_lun		= ISCSI_DEF_CMD_PER_LUN,
+	.eh_abort_handler       = iscsi_eh_abort,
+	.eh_host_reset_handler	= iscsi_eh_host_reset,
+	.use_clustering         = DISABLE_CLUSTERING,
 	.proc_name		= "iscsi_tcp",
 	.this_id		= -1,
 };
@@ -3368,7 +3391,7 @@
 	switch(param) {
 	case ISCSI_PARAM_MAX_RECV_DLENGTH: {
 		char *saveptr = conn->data;
-		int flags = GFP_KERNEL;
+		gfp_t flags = GFP_KERNEL;
 
 		if (conn->data_size >= value) {
 			conn->max_recv_dlength = value;
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index d23ae68..855f2df 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -71,7 +71,8 @@
 #define ISCSI_MGMT_CMDS_MAX		32	/* must be power of 2 */
 #define ISCSI_MGMT_ITT_OFFSET		0xa00
 #define ISCSI_SG_TABLESIZE		SG_ALL
-#define ISCSI_CMD_PER_LUN		128
+#define ISCSI_DEF_CMD_PER_LUN		32
+#define ISCSI_MAX_CMD_PER_LUN		128
 #define ISCSI_TCP_MAX_CMD_LEN		16
 
 #define ITT_MASK			(0xfff)
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 665ae79..f55b9b3 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -562,16 +562,28 @@
 	ATA_CMD_WRITE_MULTI,
 	ATA_CMD_READ_MULTI_EXT,
 	ATA_CMD_WRITE_MULTI_EXT,
+	0,
+	0,
+	0,
+	ATA_CMD_WRITE_MULTI_FUA_EXT,
 	/* pio */
 	ATA_CMD_PIO_READ,
 	ATA_CMD_PIO_WRITE,
 	ATA_CMD_PIO_READ_EXT,
 	ATA_CMD_PIO_WRITE_EXT,
+	0,
+	0,
+	0,
+	0,
 	/* dma */
 	ATA_CMD_READ,
 	ATA_CMD_WRITE,
 	ATA_CMD_READ_EXT,
-	ATA_CMD_WRITE_EXT
+	ATA_CMD_WRITE_EXT,
+	0,
+	0,
+	0,
+	ATA_CMD_WRITE_FUA_EXT
 };
 
 /**
@@ -584,28 +596,35 @@
  *	LOCKING:
  *	caller.
  */
-void ata_rwcmd_protocol(struct ata_queued_cmd *qc)
+int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
 {
 	struct ata_taskfile *tf = &qc->tf;
 	struct ata_device *dev = qc->dev;
+	u8 cmd;
 
-	int index, lba48, write;
+	int index, fua, lba48, write;
  
+	fua = (tf->flags & ATA_TFLAG_FUA) ? 4 : 0;
 	lba48 = (tf->flags & ATA_TFLAG_LBA48) ? 2 : 0;
 	write = (tf->flags & ATA_TFLAG_WRITE) ? 1 : 0;
 
 	if (dev->flags & ATA_DFLAG_PIO) {
 		tf->protocol = ATA_PROT_PIO;
-		index = dev->multi_count ? 0 : 4;
+		index = dev->multi_count ? 0 : 8;
 	} else {
 		tf->protocol = ATA_PROT_DMA;
-		index = 8;
+		index = 16;
 	}
 
-	tf->command = ata_rw_cmds[index + lba48 + write];
+	cmd = ata_rw_cmds[index + fua + lba48 + write];
+	if (cmd) {
+		tf->command = cmd;
+		return 0;
+	}
+	return -1;
 }
 
-static const char * xfer_mode_str[] = {
+static const char * const xfer_mode_str[] = {
 	"UDMA/16",
 	"UDMA/25",
 	"UDMA/33",
@@ -1046,28 +1065,103 @@
 	return modes;
 }
 
-static int ata_qc_wait_err(struct ata_queued_cmd *qc,
-			   struct completion *wait)
+struct ata_exec_internal_arg {
+	unsigned int err_mask;
+	struct ata_taskfile *tf;
+	struct completion *waiting;
+};
+
+int ata_qc_complete_internal(struct ata_queued_cmd *qc)
 {
-	int rc = 0;
+	struct ata_exec_internal_arg *arg = qc->private_data;
+	struct completion *waiting = arg->waiting;
 
-	if (wait_for_completion_timeout(wait, 30 * HZ) < 1) {
-		/* timeout handling */
-		unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap));
+	if (!(qc->err_mask & ~AC_ERR_DEV))
+		qc->ap->ops->tf_read(qc->ap, arg->tf);
+	arg->err_mask = qc->err_mask;
+	arg->waiting = NULL;
+	complete(waiting);
 
-		if (!err_mask) {
-			printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n",
-			       qc->ap->id, qc->tf.command);
-		} else {
-			printk(KERN_WARNING "ata%u: qc timeout (cmd %x)\n",
-			       qc->ap->id, qc->tf.command);
-			rc = -EIO;
-		}
+	return 0;
+}
 
-		ata_qc_complete(qc, err_mask);
+/**
+ *	ata_exec_internal - execute libata internal command
+ *	@ap: Port to which the command is sent
+ *	@dev: Device to which the command is sent
+ *	@tf: Taskfile registers for the command and the result
+ *	@dma_dir: Data tranfer direction of the command
+ *	@buf: Data buffer of the command
+ *	@buflen: Length of data buffer
+ *
+ *	Executes libata internal command with timeout.  @tf contains
+ *	command on entry and result on return.  Timeout and error
+ *	conditions are reported via return value.  No recovery action
+ *	is taken after a command times out.  It's caller's duty to
+ *	clean up after timeout.
+ *
+ *	LOCKING:
+ *	None.  Should be called with kernel context, might sleep.
+ */
+
+static unsigned
+ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
+		  struct ata_taskfile *tf,
+		  int dma_dir, void *buf, unsigned int buflen)
+{
+	u8 command = tf->command;
+	struct ata_queued_cmd *qc;
+	DECLARE_COMPLETION(wait);
+	unsigned long flags;
+	struct ata_exec_internal_arg arg;
+
+	spin_lock_irqsave(&ap->host_set->lock, flags);
+
+	qc = ata_qc_new_init(ap, dev);
+	BUG_ON(qc == NULL);
+
+	qc->tf = *tf;
+	qc->dma_dir = dma_dir;
+	if (dma_dir != DMA_NONE) {
+		ata_sg_init_one(qc, buf, buflen);
+		qc->nsect = buflen / ATA_SECT_SIZE;
 	}
 
-	return rc;
+	arg.waiting = &wait;
+	arg.tf = tf;
+	qc->private_data = &arg;
+	qc->complete_fn = ata_qc_complete_internal;
+
+	if (ata_qc_issue(qc))
+		goto issue_fail;
+
+	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+
+	if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) {
+		spin_lock_irqsave(&ap->host_set->lock, flags);
+
+		/* We're racing with irq here.  If we lose, the
+		 * following test prevents us from completing the qc
+		 * again.  If completion irq occurs after here but
+		 * before the caller cleans up, it will result in a
+		 * spurious interrupt.  We can live with that.
+		 */
+		if (arg.waiting) {
+			qc->err_mask = AC_ERR_OTHER;
+			ata_qc_complete(qc);
+			printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
+			       ap->id, command);
+		}
+
+		spin_unlock_irqrestore(&ap->host_set->lock, flags);
+	}
+
+	return arg.err_mask;
+
+ issue_fail:
+	ata_qc_free(qc);
+	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+	return AC_ERR_OTHER;
 }
 
 /**
@@ -1099,9 +1193,8 @@
 	u16 tmp;
 	unsigned long xfer_modes;
 	unsigned int using_edd;
-	DECLARE_COMPLETION(wait);
-	struct ata_queued_cmd *qc;
-	unsigned long flags;
+	struct ata_taskfile tf;
+	unsigned int err_mask;
 	int rc;
 
 	if (!ata_dev_present(dev)) {
@@ -1122,40 +1215,26 @@
 
 	ata_dev_select(ap, device, 1, 1); /* select device 0/1 */
 
-	qc = ata_qc_new_init(ap, dev);
-	BUG_ON(qc == NULL);
-
-	ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-	qc->dma_dir = DMA_FROM_DEVICE;
-	qc->tf.protocol = ATA_PROT_PIO;
-	qc->nsect = 1;
-
 retry:
+	ata_tf_init(ap, &tf, device);
+
 	if (dev->class == ATA_DEV_ATA) {
-		qc->tf.command = ATA_CMD_ID_ATA;
+		tf.command = ATA_CMD_ID_ATA;
 		DPRINTK("do ATA identify\n");
 	} else {
-		qc->tf.command = ATA_CMD_ID_ATAPI;
+		tf.command = ATA_CMD_ID_ATAPI;
 		DPRINTK("do ATAPI identify\n");
 	}
 
-	qc->waiting = &wait;
-	qc->complete_fn = ata_qc_complete_noop;
+	tf.protocol = ATA_PROT_PIO;
 
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	rc = ata_qc_issue(qc);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
+	err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+				     dev->id, sizeof(dev->id));
 
-	if (rc)
-		goto err_out;
-	else
-		ata_qc_wait_err(qc, &wait);
+	if (err_mask) {
+		if (err_mask & ~AC_ERR_DEV)
+			goto err_out;
 
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	ap->ops->tf_read(ap, &qc->tf);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-	if (qc->tf.command & ATA_ERR) {
 		/*
 		 * arg!  EDD works for all test cases, but seems to return
 		 * the ATA signature for some ATAPI devices.  Until the
@@ -1168,13 +1247,9 @@
 		 * to have this problem.
 		 */
 		if ((using_edd) && (dev->class == ATA_DEV_ATA)) {
-			u8 err = qc->tf.feature;
+			u8 err = tf.feature;
 			if (err & ATA_ABORTED) {
 				dev->class = ATA_DEV_ATAPI;
-				qc->cursg = 0;
-				qc->cursg_ofs = 0;
-				qc->cursect = 0;
-				qc->nsect = 1;
 				goto retry;
 			}
 		}
@@ -1444,11 +1519,23 @@
 	} while (time_before(jiffies, timeout));
 
 	/* TODO: phy layer with polling, timeouts, etc. */
-	if (sata_dev_present(ap))
+	sstatus = scr_read(ap, SCR_STATUS);
+	if (sata_dev_present(ap)) {
+		const char *speed;
+		u32 tmp;
+
+		tmp = (sstatus >> 4) & 0xf;
+		if (tmp & (1 << 0))
+			speed = "1.5";
+		else if (tmp & (1 << 1))
+			speed = "3.0";
+		else
+			speed = "<unknown>";
+		printk(KERN_INFO "ata%u: SATA link up %s Gbps (SStatus %X)\n",
+		       ap->id, speed, sstatus);
 		ata_port_probe(ap);
-	else {
-		sstatus = scr_read(ap, SCR_STATUS);
-		printk(KERN_INFO "ata%u: no device found (phy stat %08x)\n",
+	} else {
+		printk(KERN_INFO "ata%u: SATA link down (SStatus %X)\n",
 		       ap->id, sstatus);
 		ata_port_disable(ap);
 	}
@@ -2071,7 +2158,7 @@
 		ap->id, dev->devno);
 }
 
-static const char * ata_dma_blacklist [] = {
+static const char * const ata_dma_blacklist [] = {
 	"WDC AC11000H",
 	"WDC AC22100H",
 	"WDC AC32500H",
@@ -2266,34 +2353,23 @@
 
 static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
 {
-	DECLARE_COMPLETION(wait);
-	struct ata_queued_cmd *qc;
-	int rc;
-	unsigned long flags;
+	struct ata_taskfile tf;
 
 	/* set up set-features taskfile */
 	DPRINTK("set features - xfer mode\n");
 
-	qc = ata_qc_new_init(ap, dev);
-	BUG_ON(qc == NULL);
+	ata_tf_init(ap, &tf, dev->devno);
+	tf.command = ATA_CMD_SET_FEATURES;
+	tf.feature = SETFEATURES_XFER;
+	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_NODATA;
+	tf.nsect = dev->xfer_mode;
 
-	qc->tf.command = ATA_CMD_SET_FEATURES;
-	qc->tf.feature = SETFEATURES_XFER;
-	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-	qc->tf.protocol = ATA_PROT_NODATA;
-	qc->tf.nsect = dev->xfer_mode;
-
-	qc->waiting = &wait;
-	qc->complete_fn = ata_qc_complete_noop;
-
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	rc = ata_qc_issue(qc);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-	if (rc)
+	if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
+		printk(KERN_ERR "ata%u: failed to set xfermode, disabled\n",
+		       ap->id);
 		ata_port_disable(ap);
-	else
-		ata_qc_wait_err(qc, &wait);
+	}
 
 	DPRINTK("EXIT\n");
 }
@@ -2308,41 +2384,25 @@
 
 static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
 {
-	DECLARE_COMPLETION(wait);
-	struct ata_queued_cmd *qc;
-	unsigned long flags;
-	int rc;
+	struct ata_taskfile tf;
 
-	qc = ata_qc_new_init(ap, dev);
-	BUG_ON(qc == NULL);
-
-	ata_sg_init_one(qc, dev->id, sizeof(dev->id));
-	qc->dma_dir = DMA_FROM_DEVICE;
+	ata_tf_init(ap, &tf, dev->devno);
 
 	if (dev->class == ATA_DEV_ATA) {
-		qc->tf.command = ATA_CMD_ID_ATA;
+		tf.command = ATA_CMD_ID_ATA;
 		DPRINTK("do ATA identify\n");
 	} else {
-		qc->tf.command = ATA_CMD_ID_ATAPI;
+		tf.command = ATA_CMD_ID_ATAPI;
 		DPRINTK("do ATAPI identify\n");
 	}
 
-	qc->tf.flags |= ATA_TFLAG_DEVICE;
-	qc->tf.protocol = ATA_PROT_PIO;
-	qc->nsect = 1;
+	tf.flags |= ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_PIO;
 
-	qc->waiting = &wait;
-	qc->complete_fn = ata_qc_complete_noop;
-
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	rc = ata_qc_issue(qc);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-	if (rc)
+	if (ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
+			      dev->id, sizeof(dev->id)))
 		goto err_out;
 
-	ata_qc_wait_err(qc, &wait);
-
 	swap_buf_le16(dev->id, ATA_ID_WORDS);
 
 	ata_dump_id(dev);
@@ -2351,6 +2411,7 @@
 
 	return;
 err_out:
+	printk(KERN_ERR "ata%u: failed to reread ID, disabled\n", ap->id);
 	ata_port_disable(ap);
 }
 
@@ -2364,10 +2425,7 @@
 
 static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
 {
-	DECLARE_COMPLETION(wait);
-	struct ata_queued_cmd *qc;
-	int rc;
-	unsigned long flags;
+	struct ata_taskfile tf;
 	u16 sectors = dev->id[6];
 	u16 heads   = dev->id[3];
 
@@ -2378,26 +2436,18 @@
 	/* set up init dev params taskfile */
 	DPRINTK("init dev params \n");
 
-	qc = ata_qc_new_init(ap, dev);
-	BUG_ON(qc == NULL);
+	ata_tf_init(ap, &tf, dev->devno);
+	tf.command = ATA_CMD_INIT_DEV_PARAMS;
+	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_NODATA;
+	tf.nsect = sectors;
+	tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
 
-	qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
-	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-	qc->tf.protocol = ATA_PROT_NODATA;
-	qc->tf.nsect = sectors;
-	qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */
-
-	qc->waiting = &wait;
-	qc->complete_fn = ata_qc_complete_noop;
-
-	spin_lock_irqsave(&ap->host_set->lock, flags);
-	rc = ata_qc_issue(qc);
-	spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-	if (rc)
+	if (ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0)) {
+		printk(KERN_ERR "ata%u: failed to init parameters, disabled\n",
+		       ap->id);
 		ata_port_disable(ap);
-	else
-		ata_qc_wait_err(qc, &wait);
+	}
 
 	DPRINTK("EXIT\n");
 }
@@ -2443,7 +2493,7 @@
 			struct scatterlist *psg = &qc->pad_sgent;
 			void *addr = kmap_atomic(psg->page, KM_IRQ0);
 			memcpy(addr + psg->offset, pad_buf, qc->pad_len);
-			kunmap_atomic(psg->page, KM_IRQ0);
+			kunmap_atomic(addr, KM_IRQ0);
 		}
 	} else {
 		if (sg_dma_len(&sg[0]) > 0)
@@ -2717,7 +2767,7 @@
 		if (qc->tf.flags & ATA_TFLAG_WRITE) {
 			void *addr = kmap_atomic(psg->page, KM_IRQ0);
 			memcpy(pad_buf, addr + psg->offset, qc->pad_len);
-			kunmap_atomic(psg->page, KM_IRQ0);
+			kunmap_atomic(addr, KM_IRQ0);
 		}
 
 		sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ);
@@ -2765,7 +2815,7 @@
  *	None.  (grabs host lock)
  */
 
-void ata_poll_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+void ata_poll_qc_complete(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
 	unsigned long flags;
@@ -2773,7 +2823,7 @@
 	spin_lock_irqsave(&ap->host_set->lock, flags);
 	ap->flags &= ~ATA_FLAG_NOINTR;
 	ata_irq_on(ap);
-	ata_qc_complete(qc, err_mask);
+	ata_qc_complete(qc);
 	spin_unlock_irqrestore(&ap->host_set->lock, flags);
 }
 
@@ -2790,10 +2840,14 @@
 
 static unsigned long ata_pio_poll(struct ata_port *ap)
 {
+	struct ata_queued_cmd *qc;
 	u8 status;
 	unsigned int poll_state = HSM_ST_UNKNOWN;
 	unsigned int reg_state = HSM_ST_UNKNOWN;
 
+	qc = ata_qc_from_tag(ap, ap->active_tag);
+	assert(qc != NULL);
+
 	switch (ap->hsm_task_state) {
 	case HSM_ST:
 	case HSM_ST_POLL:
@@ -2813,6 +2867,7 @@
 	status = ata_chk_status(ap);
 	if (status & ATA_BUSY) {
 		if (time_after(jiffies, ap->pio_task_timeout)) {
+			qc->err_mask |= AC_ERR_ATA_BUS;
 			ap->hsm_task_state = HSM_ST_TMOUT;
 			return 0;
 		}
@@ -2847,29 +2902,31 @@
 	 * msecs, then chk-status again.  If still busy, fall back to
 	 * HSM_ST_POLL state.
 	 */
-	drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
-	if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+	drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
+	if (drv_stat & ATA_BUSY) {
 		msleep(2);
-		drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10);
-		if (drv_stat & (ATA_BUSY | ATA_DRQ)) {
+		drv_stat = ata_busy_wait(ap, ATA_BUSY, 10);
+		if (drv_stat & ATA_BUSY) {
 			ap->hsm_task_state = HSM_ST_LAST_POLL;
 			ap->pio_task_timeout = jiffies + ATA_TMOUT_PIO;
 			return 0;
 		}
 	}
 
+	qc = ata_qc_from_tag(ap, ap->active_tag);
+	assert(qc != NULL);
+
 	drv_stat = ata_wait_idle(ap);
 	if (!ata_ok(drv_stat)) {
+		qc->err_mask |= __ac_err_mask(drv_stat);
 		ap->hsm_task_state = HSM_ST_ERR;
 		return 0;
 	}
 
-	qc = ata_qc_from_tag(ap, ap->active_tag);
-	assert(qc != NULL);
-
 	ap->hsm_task_state = HSM_ST_IDLE;
 
-	ata_poll_qc_complete(qc, 0);
+	assert(qc->err_mask == 0);
+	ata_poll_qc_complete(qc);
 
 	/* another command may start at this point */
 
@@ -3177,6 +3234,7 @@
 err_out:
 	printk(KERN_INFO "ata%u: dev %u: ATAPI check failed\n",
 	      ap->id, dev->devno);
+	qc->err_mask |= AC_ERR_ATA_BUS;
 	ap->hsm_task_state = HSM_ST_ERR;
 }
 
@@ -3215,8 +3273,16 @@
 	qc = ata_qc_from_tag(ap, ap->active_tag);
 	assert(qc != NULL);
 
+	/* check error */
+	if (status & (ATA_ERR | ATA_DF)) {
+		qc->err_mask |= AC_ERR_DEV;
+		ap->hsm_task_state = HSM_ST_ERR;
+		return;
+	}
+
+	/* transfer data if any */
 	if (is_atapi_taskfile(&qc->tf)) {
-		/* no more data to transfer or unsupported ATAPI command */
+		/* DRQ=0 means no more data to transfer */
 		if ((status & ATA_DRQ) == 0) {
 			ap->hsm_task_state = HSM_ST_LAST;
 			return;
@@ -3226,6 +3292,7 @@
 	} else {
 		/* handle BSY=0, DRQ=0 as error */
 		if ((status & ATA_DRQ) == 0) {
+			qc->err_mask |= AC_ERR_ATA_BUS;
 			ap->hsm_task_state = HSM_ST_ERR;
 			return;
 		}
@@ -3243,9 +3310,14 @@
 	qc = ata_qc_from_tag(ap, ap->active_tag);
 	assert(qc != NULL);
 
+	/* make sure qc->err_mask is available to 
+	 * know what's wrong and recover
+	 */
+	assert(qc->err_mask);
+
 	ap->hsm_task_state = HSM_ST_IDLE;
 
-	ata_poll_qc_complete(qc, AC_ERR_ATA_BUS);
+	ata_poll_qc_complete(qc);
 }
 
 static void ata_pio_task(void *_data)
@@ -3347,7 +3419,8 @@
 		       ap->id, qc->tf.command, drv_stat, host_stat);
 
 		/* complete taskfile transaction */
-		ata_qc_complete(qc, ac_err_mask(drv_stat));
+		qc->err_mask |= ac_err_mask(drv_stat);
+		ata_qc_complete(qc);
 		break;
 	}
 
@@ -3446,15 +3519,10 @@
 	return qc;
 }
 
-int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask)
-{
-	return 0;
-}
-
 static void __ata_qc_complete(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
-	unsigned int tag, do_clear = 0;
+	unsigned int tag;
 
 	qc->flags = 0;
 	tag = qc->tag;
@@ -3462,17 +3530,8 @@
 		if (tag == ap->active_tag)
 			ap->active_tag = ATA_TAG_POISON;
 		qc->tag = ATA_TAG_POISON;
-		do_clear = 1;
-	}
-
-	if (qc->waiting) {
-		struct completion *waiting = qc->waiting;
-		qc->waiting = NULL;
-		complete(waiting);
-	}
-
-	if (likely(do_clear))
 		clear_bit(tag, &ap->qactive);
+	}
 }
 
 /**
@@ -3488,7 +3547,6 @@
 void ata_qc_free(struct ata_queued_cmd *qc)
 {
 	assert(qc != NULL);	/* ata_qc_from_tag _might_ return NULL */
-	assert(qc->waiting == NULL);	/* nothing should be waiting */
 
 	__ata_qc_complete(qc);
 }
@@ -3505,7 +3563,7 @@
  *	spin_lock_irqsave(host_set lock)
  */
 
-void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+void ata_qc_complete(struct ata_queued_cmd *qc)
 {
 	int rc;
 
@@ -3522,7 +3580,7 @@
 	qc->flags &= ~ATA_QCFLAG_ACTIVE;
 
 	/* call completion callback */
-	rc = qc->complete_fn(qc, err_mask);
+	rc = qc->complete_fn(qc);
 
 	/* if callback indicates not to complete command (non-zero),
 	 * return immediately
@@ -3960,7 +4018,8 @@
 		ap->ops->irq_clear(ap);
 
 		/* complete taskfile transaction */
-		ata_qc_complete(qc, ac_err_mask(status));
+		qc->err_mask |= ac_err_mask(status);
+		ata_qc_complete(qc);
 		break;
 
 	default:
@@ -4054,13 +4113,17 @@
 
 	/* sleep-wait for BSY to clear */
 	DPRINTK("busy wait\n");
-	if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB))
-		goto err_out_status;
+	if (ata_busy_sleep(ap, ATA_TMOUT_CDB_QUICK, ATA_TMOUT_CDB)) {
+		qc->err_mask |= AC_ERR_ATA_BUS;
+		goto err_out;
+	}
 
 	/* make sure DRQ is set */
 	status = ata_chk_status(ap);
-	if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)
+	if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) {
+		qc->err_mask |= AC_ERR_ATA_BUS;
 		goto err_out;
+	}
 
 	/* send SCSI cdb */
 	DPRINTK("send cdb\n");
@@ -4092,10 +4155,8 @@
 
 	return;
 
-err_out_status:
-	status = ata_chk_status(ap);
 err_out:
-	ata_poll_qc_complete(qc, __ac_err_mask(status));
+	ata_poll_qc_complete(qc);
 }
 
 
@@ -4112,6 +4173,96 @@
  *	Inherited from caller.
  */
 
+/*
+ * Execute a 'simple' command, that only consists of the opcode 'cmd' itself,
+ * without filling any other registers
+ */
+static int ata_do_simple_cmd(struct ata_port *ap, struct ata_device *dev,
+			     u8 cmd)
+{
+	struct ata_taskfile tf;
+	int err;
+
+	ata_tf_init(ap, &tf, dev->devno);
+
+	tf.command = cmd;
+	tf.flags |= ATA_TFLAG_DEVICE;
+	tf.protocol = ATA_PROT_NODATA;
+
+	err = ata_exec_internal(ap, dev, &tf, DMA_NONE, NULL, 0);
+	if (err)
+		printk(KERN_ERR "%s: ata command failed: %d\n",
+				__FUNCTION__, err);
+
+	return err;
+}
+
+static int ata_flush_cache(struct ata_port *ap, struct ata_device *dev)
+{
+	u8 cmd;
+
+	if (!ata_try_flush_cache(dev))
+		return 0;
+
+	if (ata_id_has_flush_ext(dev->id))
+		cmd = ATA_CMD_FLUSH_EXT;
+	else
+		cmd = ATA_CMD_FLUSH;
+
+	return ata_do_simple_cmd(ap, dev, cmd);
+}
+
+static int ata_standby_drive(struct ata_port *ap, struct ata_device *dev)
+{
+	return ata_do_simple_cmd(ap, dev, ATA_CMD_STANDBYNOW1);
+}
+
+static int ata_start_drive(struct ata_port *ap, struct ata_device *dev)
+{
+	return ata_do_simple_cmd(ap, dev, ATA_CMD_IDLEIMMEDIATE);
+}
+
+/**
+ *	ata_device_resume - wakeup a previously suspended devices
+ *
+ *	Kick the drive back into action, by sending it an idle immediate
+ *	command and making sure its transfer mode matches between drive
+ *	and host.
+ *
+ */
+int ata_device_resume(struct ata_port *ap, struct ata_device *dev)
+{
+	if (ap->flags & ATA_FLAG_SUSPENDED) {
+		ap->flags &= ~ATA_FLAG_SUSPENDED;
+		ata_set_mode(ap);
+	}
+	if (!ata_dev_present(dev))
+		return 0;
+	if (dev->class == ATA_DEV_ATA)
+		ata_start_drive(ap, dev);
+
+	return 0;
+}
+
+/**
+ *	ata_device_suspend - prepare a device for suspend
+ *
+ *	Flush the cache on the drive, if appropriate, then issue a
+ *	standbynow command.
+ *
+ */
+int ata_device_suspend(struct ata_port *ap, struct ata_device *dev)
+{
+	if (!ata_dev_present(dev))
+		return 0;
+	if (dev->class == ATA_DEV_ATA)
+		ata_flush_cache(ap, dev);
+
+	ata_standby_drive(ap, dev);
+	ap->flags |= ATA_FLAG_SUSPENDED;
+	return 0;
+}
+
 int ata_port_start (struct ata_port *ap)
 {
 	struct device *dev = ap->host_set->dev;
@@ -4860,6 +5011,23 @@
 
 	return (tmp == bits->val) ? 1 : 0;
 }
+
+int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+	pci_set_power_state(pdev, PCI_D3hot);
+	return 0;
+}
+
+int ata_pci_device_resume(struct pci_dev *pdev)
+{
+	pci_set_power_state(pdev, PCI_D0);
+	pci_restore_state(pdev);
+	pci_enable_device(pdev);
+	pci_set_master(pdev);
+	return 0;
+}
 #endif /* CONFIG_PCI */
 
 
@@ -4963,4 +5131,11 @@
 EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
+EXPORT_SYMBOL_GPL(ata_pci_device_resume);
 #endif /* CONFIG_PCI */
+
+EXPORT_SYMBOL_GPL(ata_device_suspend);
+EXPORT_SYMBOL_GPL(ata_device_resume);
+EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
+EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 3b4ca55a..cfbceb5 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -396,6 +396,22 @@
 	}
 }
 
+int ata_scsi_device_resume(struct scsi_device *sdev)
+{
+	struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+	struct ata_device *dev = &ap->device[sdev->id];
+
+	return ata_device_resume(ap, dev);
+}
+
+int ata_scsi_device_suspend(struct scsi_device *sdev)
+{
+	struct ata_port *ap = (struct ata_port *) &sdev->host->hostdata[0];
+	struct ata_device *dev = &ap->device[sdev->id];
+
+	return ata_device_suspend(ap, dev);
+}
+
 /**
  *	ata_to_sense_error - convert ATA error to SCSI error
  *	@id: ATA device number
@@ -418,7 +434,7 @@
 	int i;
 
 	/* Based on the 3ware driver translation table */
-	static unsigned char sense_table[][4] = {
+	static const unsigned char sense_table[][4] = {
 		/* BBD|ECC|ID|MAR */
 		{0xd1, 		ABORTED_COMMAND, 0x00, 0x00}, 	// Device busy                  Aborted command
 		/* BBD|ECC|ID */
@@ -449,7 +465,7 @@
 		{0x80, 		MEDIUM_ERROR, 0x11, 0x04}, 	// Block marked bad		  Medium error, unrecovered read error
 		{0xFF, 0xFF, 0xFF, 0xFF}, // END mark
 	};
-	static unsigned char stat_table[][4] = {
+	static const unsigned char stat_table[][4] = {
 		/* Must be first because BUSY means no other bits valid */
 		{0x80, 		ABORTED_COMMAND, 0x47, 0x00},	// Busy, fake parity for now
 		{0x20, 		HARDWARE_ERROR,  0x00, 0x00}, 	// Device fault
@@ -1080,11 +1096,13 @@
 	    scsicmd[0] == WRITE_16)
 		tf->flags |= ATA_TFLAG_WRITE;
 
-	/* Calculate the SCSI LBA and transfer length. */
+	/* Calculate the SCSI LBA, transfer length and FUA. */
 	switch (scsicmd[0]) {
 	case READ_10:
 	case WRITE_10:
 		scsi_10_lba_len(scsicmd, &block, &n_block);
+		if (unlikely(scsicmd[1] & (1 << 3)))
+			tf->flags |= ATA_TFLAG_FUA;
 		break;
 	case READ_6:
 	case WRITE_6:
@@ -1099,6 +1117,8 @@
 	case READ_16:
 	case WRITE_16:
 		scsi_16_lba_len(scsicmd, &block, &n_block);
+		if (unlikely(scsicmd[1] & (1 << 3)))
+			tf->flags |= ATA_TFLAG_FUA;
 		break;
 	default:
 		DPRINTK("no-byte command\n");
@@ -1142,7 +1162,8 @@
 			tf->device |= (block >> 24) & 0xf;
 		}
 
-		ata_rwcmd_protocol(qc);
+		if (unlikely(ata_rwcmd_protocol(qc) < 0))
+			goto invalid_fld;
 
 		qc->nsect = n_block;
 		tf->nsect = n_block & 0xff;
@@ -1160,7 +1181,8 @@
 		if ((block >> 28) || (n_block > 256))
 			goto out_of_range;
 
-		ata_rwcmd_protocol(qc);
+		if (unlikely(ata_rwcmd_protocol(qc) < 0))
+			goto invalid_fld;
 
 		/* Convert LBA to CHS */
 		track = (u32)block / dev->sectors;
@@ -1203,12 +1225,11 @@
 	return 1;
 }
 
-static int ata_scsi_qc_complete(struct ata_queued_cmd *qc,
-				unsigned int err_mask)
+static int ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 {
 	struct scsi_cmnd *cmd = qc->scsicmd;
 	u8 *cdb = cmd->cmnd;
- 	int need_sense = (err_mask != 0);
+ 	int need_sense = (qc->err_mask != 0);
 
 	/* For ATA pass thru (SAT) commands, generate a sense block if
 	 * user mandated it or if there's an error.  Note that if we
@@ -1532,7 +1553,7 @@
 	return 0;
 }
 
-static const char *inq_83_str = "Linux ATA-SCSI simulator";
+static const char * const inq_83_str = "Linux ATA-SCSI simulator";
 
 /**
  *	ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity
@@ -1696,6 +1717,7 @@
 unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf,
 				  unsigned int buflen)
 {
+	struct ata_device *dev = args->dev;
 	u8 *scsicmd = args->cmd->cmnd, *p, *last;
 	const u8 sat_blk_desc[] = {
 		0, 0, 0, 0,	/* number of blocks: sat unspecified */
@@ -1704,6 +1726,7 @@
 	};
 	u8 pg, spg;
 	unsigned int ebd, page_control, six_byte, output_len, alloc_len, minlen;
+	u8 dpofua;
 
 	VPRINTK("ENTER\n");
 
@@ -1772,9 +1795,17 @@
 
 	if (minlen < 1)
 		return 0;
+
+	dpofua = 0;
+	if (ata_id_has_fua(args->id) && dev->flags & ATA_DFLAG_LBA48 &&
+	    (!(dev->flags & ATA_DFLAG_PIO) || dev->multi_count))
+		dpofua = 1 << 4;
+
 	if (six_byte) {
 		output_len--;
 		rbuf[0] = output_len;
+		if (minlen > 2)
+			rbuf[2] |= dpofua;
 		if (ebd) {
 			if (minlen > 3)
 				rbuf[3] = sizeof(sat_blk_desc);
@@ -1787,6 +1818,8 @@
 		rbuf[0] = output_len >> 8;
 		if (minlen > 1)
 			rbuf[1] = output_len;
+		if (minlen > 3)
+			rbuf[3] |= dpofua;
 		if (ebd) {
 			if (minlen > 7)
 				rbuf[7] = sizeof(sat_blk_desc);
@@ -1955,9 +1988,9 @@
 	done(cmd);
 }
 
-static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask)
+static int atapi_sense_complete(struct ata_queued_cmd *qc)
 {
-	if (err_mask && ((err_mask & AC_ERR_DEV) == 0))
+	if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0))
 		/* FIXME: not quite right; we don't want the
 		 * translation of taskfile registers into
 		 * a sense descriptors, since that's only
@@ -2015,15 +2048,18 @@
 
 	qc->complete_fn = atapi_sense_complete;
 
-	if (ata_qc_issue(qc))
-		ata_qc_complete(qc, AC_ERR_OTHER);
+	if (ata_qc_issue(qc)) {
+		qc->err_mask |= AC_ERR_OTHER;
+		ata_qc_complete(qc);
+	}
 
 	DPRINTK("EXIT\n");
 }
 
-static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask)
+static int atapi_qc_complete(struct ata_queued_cmd *qc)
 {
 	struct scsi_cmnd *cmd = qc->scsicmd;
+	unsigned int err_mask = qc->err_mask;
 
 	VPRINTK("ENTER, err_mask 0x%X\n", err_mask);
 
@@ -2044,7 +2080,7 @@
 	else {
 		u8 *scsicmd = cmd->cmnd;
 
-		if (scsicmd[0] == INQUIRY) {
+		if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) {
 			u8 *buf = NULL;
 			unsigned int buflen;
 
@@ -2058,9 +2094,6 @@
 	 * device.  2) Ensure response data format / ATAPI information
 	 * are always correct.
 	 */
-	/* FIXME: do we ever override EVPD pages and the like, with
-	 * this code?
-	 */
 			if (buf[2] == 0) {
 				buf[2] = 0x5;
 				buf[3] = 0x32;
@@ -2173,9 +2206,12 @@
 	if (unlikely(!ata_dev_present(dev)))
 		return NULL;
 
-	if (!atapi_enabled) {
-		if (unlikely(dev->class == ATA_DEV_ATAPI))
+	if (!atapi_enabled || (ap->flags & ATA_FLAG_NO_ATAPI)) {
+		if (unlikely(dev->class == ATA_DEV_ATAPI)) {
+			printk(KERN_WARNING "ata%u(%u): WARNING: ATAPI is %s, device ignored.\n",
+			       ap->id, dev->devno, atapi_enabled ? "not supported with this driver" : "disabled");
 			return NULL;
+		}
 	}
 
 	return dev;
@@ -2239,7 +2275,7 @@
 	struct scsi_cmnd *cmd = qc->scsicmd;
 
 	if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN)
-		return 1;
+		goto invalid_fld;
 
 	/*
 	 * 12 and 16 byte CDBs use different offsets to
@@ -2301,7 +2337,7 @@
 	 */
 	if ((tf->command == ATA_CMD_SET_FEATURES)
 	 && (tf->feature == SETFEATURES_XFER))
-		return 1;
+		goto invalid_fld;
 
 	/*
 	 * Set flags so that all registers will be written,
@@ -2322,6 +2358,11 @@
 	qc->nsect = cmd->bufflen / ATA_SECT_SIZE;
 
 	return 0;
+
+ invalid_fld:
+	ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00);
+	/* "Invalid field in cdb" */
+	return 1;
 }
 
 /**
@@ -2439,7 +2480,7 @@
 		if (xlat_func)
 			ata_scsi_translate(ap, dev, cmd, done, xlat_func);
 		else
-			ata_scsi_simulate(dev->id, cmd, done);
+			ata_scsi_simulate(ap, dev, cmd, done);
 	} else
 		ata_scsi_translate(ap, dev, cmd, done, atapi_xlat);
 
@@ -2462,14 +2503,16 @@
  *	spin_lock_irqsave(host_set lock)
  */
 
-void ata_scsi_simulate(u16 *id,
+void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
 		      struct scsi_cmnd *cmd,
 		      void (*done)(struct scsi_cmnd *))
 {
 	struct ata_scsi_args args;
 	const u8 *scsicmd = cmd->cmnd;
 
-	args.id = id;
+	args.ap = ap;
+	args.dev = dev;
+	args.id = dev->id;
 	args.cmd = cmd;
 	args.done = done;
 
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 8ebaa69..e03ce48 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -32,6 +32,8 @@
 #define DRV_VERSION	"1.20"	/* must be exactly four chars */
 
 struct ata_scsi_args {
+	struct ata_port		*ap;
+	struct ata_device	*dev;
 	u16			*id;
 	struct scsi_cmnd	*cmd;
 	void			(*done)(struct scsi_cmnd *);
@@ -39,10 +41,9 @@
 
 /* libata-core.c */
 extern int atapi_enabled;
-extern int ata_qc_complete_noop(struct ata_queued_cmd *qc, unsigned int err_mask);
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
 				      struct ata_device *dev);
-extern void ata_rwcmd_protocol(struct ata_queued_cmd *qc);
+extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
 extern void ata_qc_free(struct ata_queued_cmd *qc);
 extern int ata_qc_issue(struct ata_queued_cmd *qc);
 extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 3062b39..38ffa8d 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -29,9 +29,10 @@
 #define LPFC_LC_HBA_Q_DEPTH	1024	/* max cmds per low cost hba */
 #define LPFC_LP101_HBA_Q_DEPTH	128	/* max cmds per low cost hba */
 
-#define LPFC_CMD_PER_LUN	30	/* max outstanding cmds per lun */
+#define LPFC_CMD_PER_LUN	3	/* max outstanding cmds per lun */
 #define LPFC_SG_SEG_CNT		64	/* sg element count per scsi cmnd */
 #define LPFC_IOCB_LIST_CNT	2250	/* list of IOCBs for fast-path usage. */
+#define LPFC_Q_RAMP_UP_INTERVAL 120     /* lun q_depth ramp up interval */
 
 /* Define macros for 64 bit support */
 #define putPaddrLow(addr)    ((uint32_t) (0xffffffff & (u64)(addr)))
@@ -45,6 +46,11 @@
 
 #define MAX_HBAEVT	32
 
+enum lpfc_polling_flags {
+	ENABLE_FCP_RING_POLLING = 0x1,
+	DISABLE_FCP_RING_INT    = 0x2
+};
+
 /* Provide DMA memory definitions the driver uses per port instance. */
 struct lpfc_dmabuf {
 	struct list_head list;
@@ -167,6 +173,7 @@
 	dma_addr_t slim2p_mapping;
 	uint16_t pci_cfg_value;
 
+	struct semaphore hba_can_block;
 	uint32_t hba_state;
 
 #define LPFC_INIT_START           1	/* Initial state after board reset */
@@ -286,6 +293,8 @@
 	uint32_t cfg_fcp_bind_method;
 	uint32_t cfg_discovery_threads;
 	uint32_t cfg_max_luns;
+	uint32_t cfg_poll;
+	uint32_t cfg_poll_tmo;
 	uint32_t cfg_sg_seg_cnt;
 	uint32_t cfg_sg_dma_buf_size;
 
@@ -337,7 +346,9 @@
 #define VPD_PORT            0x8         /* valid vpd port data */
 #define VPD_MASK            0xf         /* mask for any vpd data */
 
+	struct timer_list fcp_poll_timer;
 	struct timer_list els_tmofunc;
+
 	/*
 	 * stat  counters
 	 */
@@ -348,6 +359,7 @@
 	struct lpfc_sysfs_mbox sysfs_mbox;
 
 	/* fastpath list. */
+	spinlock_t scsi_buf_list_lock;
 	struct list_head lpfc_scsi_buf_list;
 	uint32_t total_scsi_bufs;
 	struct list_head lpfc_iocb_list;
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 89e8222..5625a8c 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -278,6 +278,71 @@
 		return -EIO;
 }
 
+static ssize_t
+lpfc_poll_show(struct class_device *cdev, char *buf)
+{
+	struct Scsi_Host *host = class_to_shost(cdev);
+	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+
+	return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
+}
+
+static ssize_t
+lpfc_poll_store(struct class_device *cdev, const char *buf,
+		size_t count)
+{
+	struct Scsi_Host *host = class_to_shost(cdev);
+	struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata[0];
+	uint32_t creg_val;
+	uint32_t old_val;
+	int val=0;
+
+	if (!isdigit(buf[0]))
+		return -EINVAL;
+
+	if (sscanf(buf, "%i", &val) != 1)
+		return -EINVAL;
+
+	if ((val & 0x3) != val)
+		return -EINVAL;
+
+	spin_lock_irq(phba->host->host_lock);
+
+	old_val = phba->cfg_poll;
+
+	if (val & ENABLE_FCP_RING_POLLING) {
+		if ((val & DISABLE_FCP_RING_INT) &&
+		    !(old_val & DISABLE_FCP_RING_INT)) {
+			creg_val = readl(phba->HCregaddr);
+			creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+			writel(creg_val, phba->HCregaddr);
+			readl(phba->HCregaddr); /* flush */
+
+			lpfc_poll_start_timer(phba);
+		}
+	} else if (val != 0x0) {
+		spin_unlock_irq(phba->host->host_lock);
+		return -EINVAL;
+	}
+
+	if (!(val & DISABLE_FCP_RING_INT) &&
+	    (old_val & DISABLE_FCP_RING_INT))
+	{
+		spin_unlock_irq(phba->host->host_lock);
+		del_timer(&phba->fcp_poll_timer);
+		spin_lock_irq(phba->host->host_lock);
+		creg_val = readl(phba->HCregaddr);
+		creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+		writel(creg_val, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
+	}
+
+	phba->cfg_poll = val;
+
+	spin_unlock_irq(phba->host->host_lock);
+
+	return strlen(buf);
+}
 
 #define lpfc_param_show(attr)	\
 static ssize_t \
@@ -416,6 +481,15 @@
 static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR,
 			 lpfc_board_online_show, lpfc_board_online_store);
 
+static int lpfc_poll = 0;
+module_param(lpfc_poll, int, 0);
+MODULE_PARM_DESC(lpfc_poll, "FCP ring polling mode control:"
+		 " 0 - none,"
+		 " 1 - poll with interrupts enabled"
+		 " 3 - poll and disable FCP ring interrupts");
+
+static CLASS_DEVICE_ATTR(lpfc_poll, S_IRUGO | S_IWUSR,
+			 lpfc_poll_show, lpfc_poll_store);
 
 /*
 # lpfc_log_verbose: Only turn this flag on if you are willing to risk being
@@ -523,10 +597,10 @@
 # is 0. Default value of cr_count is 1. The cr_count feature is disabled if
 # cr_delay is set to 0.
 */
-LPFC_ATTR(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
+LPFC_ATTR_RW(cr_delay, 0, 0, 63, "A count of milliseconds after which an"
 		"interrupt response is generated");
 
-LPFC_ATTR(cr_count, 1, 1, 255, "A count of I/O completions after which an"
+LPFC_ATTR_RW(cr_count, 1, 1, 255, "A count of I/O completions after which an"
 		"interrupt response is generated");
 
 /*
@@ -553,6 +627,13 @@
 LPFC_ATTR_R(max_luns, 256, 1, 32768,
 	     "Maximum number of LUNs per target driver will support");
 
+/*
+# lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring.
+# Value range is [1,255], default value is 10.
+*/
+LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
+	     "Milliseconds driver will wait between polling FCP ring");
+
 struct class_device_attribute *lpfc_host_attrs[] = {
 	&class_device_attr_info,
 	&class_device_attr_serialnum,
@@ -575,11 +656,15 @@
 	&class_device_attr_lpfc_topology,
 	&class_device_attr_lpfc_scan_down,
 	&class_device_attr_lpfc_link_speed,
+	&class_device_attr_lpfc_cr_delay,
+	&class_device_attr_lpfc_cr_count,
 	&class_device_attr_lpfc_fdmi_on,
 	&class_device_attr_lpfc_max_luns,
 	&class_device_attr_nport_evt_cnt,
 	&class_device_attr_management_version,
 	&class_device_attr_board_online,
+	&class_device_attr_lpfc_poll,
+	&class_device_attr_lpfc_poll_tmo,
 	NULL,
 };
 
@@ -1292,6 +1377,9 @@
 	lpfc_fdmi_on_init(phba, lpfc_fdmi_on);
 	lpfc_discovery_threads_init(phba, lpfc_discovery_threads);
 	lpfc_max_luns_init(phba, lpfc_max_luns);
+	lpfc_poll_tmo_init(phba, lpfc_poll_tmo);
+
+	phba->cfg_poll = lpfc_poll;
 
 	/*
 	 * The total number of segments is the configuration value plus 2
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index d527d05..f1e7089 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -143,6 +143,9 @@
 int lpfc_mem_alloc(struct lpfc_hba *);
 void lpfc_mem_free(struct lpfc_hba *);
 
+void lpfc_poll_timeout(unsigned long ptr);
+void lpfc_poll_start_timer(struct lpfc_hba * phba);
+void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba);
 struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
 void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
 uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 084e762..ed6c816 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -73,6 +73,8 @@
 	struct lpfc_hba      *nlp_phba;
 	struct lpfc_work_evt nodev_timeout_evt;
 	struct lpfc_work_evt els_retry_evt;
+	unsigned long last_ramp_up_time;        /* jiffy of last ramp up */
+	unsigned long last_q_full_time;		/* jiffy of last queue full */
 };
 
 /* Defines for nlp_flag (uint32) */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index bcc29ec..20f1a07 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -720,6 +720,7 @@
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 		   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+		   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
 		}
@@ -869,6 +870,7 @@
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 		   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+		   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			goto out;
 		}
@@ -1054,6 +1056,7 @@
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 		   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+		   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
 		}
@@ -1205,6 +1208,7 @@
 		/* Do not call DSM for lpfc_els_abort'ed ELS cmds */
 		if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
 		   ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) ||
+		   (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) ||
 		   (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) {
 			goto out;
 		}
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 259eeb1..a1f751e 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1017,12 +1017,7 @@
 	rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
 	rport_ids.port_id = ndlp->nlp_DID;
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
-	if (ndlp->nlp_type & NLP_FCP_TARGET)
-		rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
-	if (ndlp->nlp_type & NLP_FCP_INITIATOR)
-		rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
 
-	scsi_block_requests(phba->host);
 	ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids);
 	if (!rport) {
 		dev_printk(KERN_WARNING, &phba->pcidev->dev,
@@ -1039,7 +1034,16 @@
 	}
 	rdata = rport->dd_data;
 	rdata->pnode = ndlp;
-	scsi_unblock_requests(phba->host);
+
+	if (ndlp->nlp_type & NLP_FCP_TARGET)
+		rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
+	if (ndlp->nlp_type & NLP_FCP_INITIATOR)
+		rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
+
+
+	if (rport_ids.roles !=  FC_RPORT_ROLE_UNKNOWN)
+		fc_remote_port_rolechg(rport, rport_ids.roles);
+
 
 	return;
 }
@@ -1053,9 +1057,7 @@
 
 	ndlp->rport = NULL;
 	rdata->pnode = NULL;
-	scsi_block_requests(phba->host);
 	fc_remote_port_delete(rport);
-	scsi_unblock_requests(phba->host);
 
 	return;
 }
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 86c4198..1ea565e 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -266,9 +266,11 @@
 		struct {
 #ifdef __BIG_ENDIAN_BITFIELD
 			uint8_t nameType:4;	/* FC Word 0, bit 28:31 */
-			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit
+						   8:11 of IEEE ext */
 #else	/*  __LITTLE_ENDIAN_BITFIELD */
-			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit 8:11 of IEEE ext */
+			uint8_t IEEEextMsn:4;	/* FC Word 0, bit 24:27, bit
+						   8:11 of IEEE ext */
 			uint8_t nameType:4;	/* FC Word 0, bit 28:31 */
 #endif
 
@@ -278,7 +280,8 @@
 #define NAME_IP_TYPE        0x4	/* IP address */
 #define NAME_CCITT_TYPE     0xC
 #define NAME_CCITT_GR_TYPE  0xE
-			uint8_t IEEEextLsb;	/* FC Word 0, bit 16:23, IEEE extended Lsb */
+			uint8_t IEEEextLsb;	/* FC Word 0, bit 16:23, IEEE
+						   extended Lsb */
 			uint8_t IEEE[6];	/* FC IEEE address */
 		} s;
 		uint8_t wwn[8];
@@ -1024,23 +1027,38 @@
 /* Start FireFly Register definitions */
 #define PCI_VENDOR_ID_EMULEX        0x10df
 #define PCI_DEVICE_ID_FIREFLY       0x1ae5
-#define PCI_DEVICE_ID_SUPERFLY      0xf700
-#define PCI_DEVICE_ID_DRAGONFLY     0xf800
 #define PCI_DEVICE_ID_RFLY          0xf095
 #define PCI_DEVICE_ID_PFLY          0xf098
+#define PCI_DEVICE_ID_LP101         0xf0a1
 #define PCI_DEVICE_ID_TFLY          0xf0a5
+#define PCI_DEVICE_ID_BSMB          0xf0d1
+#define PCI_DEVICE_ID_BMID          0xf0d5
+#define PCI_DEVICE_ID_ZSMB          0xf0e1
+#define PCI_DEVICE_ID_ZMID          0xf0e5
+#define PCI_DEVICE_ID_NEPTUNE       0xf0f5
+#define PCI_DEVICE_ID_NEPTUNE_SCSP  0xf0f6
+#define PCI_DEVICE_ID_NEPTUNE_DCSP  0xf0f7
+#define PCI_DEVICE_ID_SUPERFLY      0xf700
+#define PCI_DEVICE_ID_DRAGONFLY     0xf800
 #define PCI_DEVICE_ID_CENTAUR       0xf900
 #define PCI_DEVICE_ID_PEGASUS       0xf980
 #define PCI_DEVICE_ID_THOR          0xfa00
 #define PCI_DEVICE_ID_VIPER         0xfb00
+#define PCI_DEVICE_ID_LP10000S      0xfc00
+#define PCI_DEVICE_ID_LP11000S      0xfc10
+#define PCI_DEVICE_ID_LPE11000S     0xfc20
 #define PCI_DEVICE_ID_HELIOS        0xfd00
-#define PCI_DEVICE_ID_BMID          0xf0d5
-#define PCI_DEVICE_ID_BSMB          0xf0d1
+#define PCI_DEVICE_ID_HELIOS_SCSP   0xfd11
+#define PCI_DEVICE_ID_HELIOS_DCSP   0xfd12
 #define PCI_DEVICE_ID_ZEPHYR        0xfe00
-#define PCI_DEVICE_ID_ZMID          0xf0e5
-#define PCI_DEVICE_ID_ZSMB          0xf0e1
-#define PCI_DEVICE_ID_LP101	    0xf0a1
-#define PCI_DEVICE_ID_LP10000S	    0xfc00
+#define PCI_DEVICE_ID_ZEPHYR_SCSP   0xfe11
+#define PCI_DEVICE_ID_ZEPHYR_DCSP   0xfe12
+
+#define PCI_SUBSYSTEM_ID_LP11000S      0xfc11
+#define PCI_SUBSYSTEM_ID_LP11002S      0xfc12
+#define PCI_SUBSYSTEM_ID_LPE11000S     0xfc21
+#define PCI_SUBSYSTEM_ID_LPE11002S     0xfc22
+#define PCI_SUBSYSTEM_ID_LPE11010S     0xfc2A
 
 #define JEDEC_ID_ADDRESS            0x0080001c
 #define FIREFLY_JEDEC_ID            0x1ACC
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 0749811..b7a603a 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -126,34 +126,26 @@
 		return -ERESTART;
 	}
 
-	/* The HBA's current state is provided by the ProgType and rr fields.
-	 * Read and check the value of these fields before continuing to config
-	 * this port.
+	/*
+	 * The value of rr must be 1 since the driver set the cv field to 1.
+	 * This setting requires the FW to set all revision fields.
 	 */
-	if (mb->un.varRdRev.rr == 0 || mb->un.varRdRev.un.b.ProgType != 2) {
-		/* Old firmware */
+	if (mb->un.varRdRev.rr == 0) {
 		vp->rev.rBit = 0;
-		lpfc_printf_log(phba,
-				KERN_ERR,
-				LOG_INIT,
-				"%d:0440 Adapter failed to init, mbxCmd x%x "
-				"READ_REV detected outdated firmware"
-				"Data: x%x\n",
-				phba->brd_no,
-				mb->mbxCommand, 0);
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"%d:0440 Adapter failed to init, READ_REV has "
+				"missing revision information.\n",
+				phba->brd_no);
 		mempool_free(pmb, phba->mbox_mem_pool);
 		return -ERESTART;
-	} else {
-		vp->rev.rBit = 1;
-		vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev;
-		memcpy(vp->rev.sli1FwName,
-			(char*)mb->un.varRdRev.sli1FwName, 16);
-		vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev;
-		memcpy(vp->rev.sli2FwName,
-					(char *)mb->un.varRdRev.sli2FwName, 16);
 	}
 
 	/* Save information as VPD data */
+	vp->rev.rBit = 1;
+	vp->rev.sli1FwRev = mb->un.varRdRev.sli1FwRev;
+	memcpy(vp->rev.sli1FwName, (char*) mb->un.varRdRev.sli1FwName, 16);
+	vp->rev.sli2FwRev = mb->un.varRdRev.sli2FwRev;
+	memcpy(vp->rev.sli2FwName, (char *) mb->un.varRdRev.sli2FwName, 16);
 	vp->rev.biuRev = mb->un.varRdRev.biuRev;
 	vp->rev.smRev = mb->un.varRdRev.smRev;
 	vp->rev.smFwRev = mb->un.varRdRev.un.smFwRev;
@@ -378,6 +370,10 @@
 	if (psli->num_rings > 3)
 		status |= HC_R3INT_ENA;
 
+	if ((phba->cfg_poll & ENABLE_FCP_RING_POLLING) &&
+	    (phba->cfg_poll & DISABLE_FCP_RING_INT))
+		status &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+
 	writel(status, phba->HCregaddr);
 	readl(phba->HCregaddr); /* flush */
 	spin_unlock_irq(phba->host->host_lock);
@@ -571,6 +567,8 @@
 
 	rc = -EIO;
 
+	/* Cleanup any outstanding ELS commands */
+	lpfc_els_flush_cmd(phba);
 
 	psli->slistat.link_event++;
 	lpfc_read_la(phba, pmb, mp);
@@ -765,96 +763,139 @@
 lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp)
 {
 	lpfc_vpd_t *vp;
-	uint32_t id;
-	uint8_t hdrtype;
-	char str[16];
+	uint16_t dev_id = phba->pcidev->device;
+	uint16_t dev_subid = phba->pcidev->subsystem_device;
+	uint8_t hdrtype = phba->pcidev->hdr_type;
+	char *model_str = "";
 
 	vp = &phba->vpd;
-	pci_read_config_dword(phba->pcidev, PCI_VENDOR_ID, &id);
-	pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype);
 
-	switch ((id >> 16) & 0xffff) {
+	switch (dev_id) {
 	case PCI_DEVICE_ID_FIREFLY:
-		strcpy(str, "LP6000 1");
+		model_str = "LP6000 1Gb PCI";
 		break;
 	case PCI_DEVICE_ID_SUPERFLY:
 		if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3)
-			strcpy(str, "LP7000 1");
+			model_str = "LP7000 1Gb PCI";
 		else
-			strcpy(str, "LP7000E 1");
+			model_str = "LP7000E 1Gb PCI";
 		break;
 	case PCI_DEVICE_ID_DRAGONFLY:
-		strcpy(str, "LP8000 1");
+		model_str = "LP8000 1Gb PCI";
 		break;
 	case PCI_DEVICE_ID_CENTAUR:
 		if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID)
-			strcpy(str, "LP9002 2");
+			model_str = "LP9002 2Gb PCI";
 		else
-			strcpy(str, "LP9000 1");
+			model_str = "LP9000 1Gb PCI";
 		break;
 	case PCI_DEVICE_ID_RFLY:
-		strcpy(str, "LP952 2");
+		model_str = "LP952 2Gb PCI";
 		break;
 	case PCI_DEVICE_ID_PEGASUS:
-		strcpy(str, "LP9802 2");
+		model_str = "LP9802 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_THOR:
 		if (hdrtype == 0x80)
-			strcpy(str, "LP10000DC 2");
+			model_str = "LP10000DC 2Gb 2-port PCI-X";
 		else
-			strcpy(str, "LP10000 2");
+			model_str = "LP10000 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_VIPER:
-		strcpy(str, "LPX1000 10");
+		model_str = "LPX1000 10Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_PFLY:
-		strcpy(str, "LP982 2");
+		model_str = "LP982 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_TFLY:
 		if (hdrtype == 0x80)
-			strcpy(str, "LP1050DC 2");
+			model_str = "LP1050DC 2Gb 2-port PCI-X";
 		else
-			strcpy(str, "LP1050 2");
+			model_str = "LP1050 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_HELIOS:
 		if (hdrtype == 0x80)
-			strcpy(str, "LP11002 4");
+			model_str = "LP11002 4Gb 2-port PCI-X2";
 		else
-			strcpy(str, "LP11000 4");
+			model_str = "LP11000 4Gb PCI-X2";
+		break;
+	case PCI_DEVICE_ID_HELIOS_SCSP:
+		model_str = "LP11000-SP 4Gb PCI-X2";
+		break;
+	case PCI_DEVICE_ID_HELIOS_DCSP:
+		model_str = "LP11002-SP 4Gb 2-port PCI-X2";
+		break;
+	case PCI_DEVICE_ID_NEPTUNE:
+		if (hdrtype == 0x80)
+			model_str = "LPe1002 4Gb 2-port";
+		else
+			model_str = "LPe1000 4Gb PCIe";
+		break;
+	case PCI_DEVICE_ID_NEPTUNE_SCSP:
+		model_str = "LPe1000-SP 4Gb PCIe";
+		break;
+	case PCI_DEVICE_ID_NEPTUNE_DCSP:
+		model_str = "LPe1002-SP 4Gb 2-port PCIe";
 		break;
 	case PCI_DEVICE_ID_BMID:
-		strcpy(str, "LP1150 4");
+		model_str = "LP1150 4Gb PCI-X2";
 		break;
 	case PCI_DEVICE_ID_BSMB:
-		strcpy(str, "LP111 4");
+		model_str = "LP111 4Gb PCI-X2";
 		break;
 	case PCI_DEVICE_ID_ZEPHYR:
 		if (hdrtype == 0x80)
-			strcpy(str, "LPe11002 4");
+			model_str = "LPe11002 4Gb 2-port PCIe";
 		else
-			strcpy(str, "LPe11000 4");
+			model_str = "LPe11000 4Gb PCIe";
+		break;
+	case PCI_DEVICE_ID_ZEPHYR_SCSP:
+		model_str = "LPe11000-SP 4Gb PCIe";
+		break;
+	case PCI_DEVICE_ID_ZEPHYR_DCSP:
+		model_str = "LPe11002-SP 4Gb 2-port PCIe";
 		break;
 	case PCI_DEVICE_ID_ZMID:
-		strcpy(str, "LPe1150 4");
+		model_str = "LPe1150 4Gb PCIe";
 		break;
 	case PCI_DEVICE_ID_ZSMB:
-		strcpy(str, "LPe111 4");
+		model_str = "LPe111 4Gb PCIe";
 		break;
 	case PCI_DEVICE_ID_LP101:
-		strcpy(str, "LP101 2");
+		model_str = "LP101 2Gb PCI-X";
 		break;
 	case PCI_DEVICE_ID_LP10000S:
-		strcpy(str, "LP10000-S 2");
+		model_str = "LP10000-S 2Gb PCI";
+		break;
+	case PCI_DEVICE_ID_LP11000S:
+	case PCI_DEVICE_ID_LPE11000S:
+		switch (dev_subid) {
+		case PCI_SUBSYSTEM_ID_LP11000S:
+			model_str = "LP11002-S 4Gb PCI-X2";
+			break;
+		case PCI_SUBSYSTEM_ID_LP11002S:
+			model_str = "LP11000-S 4Gb 2-port PCI-X2";
+			break;
+		case PCI_SUBSYSTEM_ID_LPE11000S:
+			model_str = "LPe11002-S 4Gb PCIe";
+			break;
+		case PCI_SUBSYSTEM_ID_LPE11002S:
+			model_str = "LPe11002-S 4Gb 2-port PCIe";
+			break;
+		case PCI_SUBSYSTEM_ID_LPE11010S:
+			model_str = "LPe11010-S 4Gb 10-port PCIe";
+			break;
+		default:
+			break;
+		}
 		break;
 	default:
-		memset(str, 0, 16);
 		break;
 	}
 	if (mdp)
-		sscanf(str, "%s", mdp);
+		sscanf(model_str, "%s", mdp);
 	if (descp)
-		sprintf(descp, "Emulex LightPulse %s Gigabit PCI Fibre "
-			"Channel Adapter", str);
+		sprintf(descp, "Emulex %s Fibre Channel Adapter", model_str);
 }
 
 /**************************************************/
@@ -1196,6 +1237,7 @@
 		}
 	}
 
+	del_timer_sync(&phba->fcp_poll_timer);
 	del_timer_sync(&phba->fc_estabtmo);
 	del_timer_sync(&phba->fc_disctmo);
 	del_timer_sync(&phba->fc_fdmitmo);
@@ -1351,7 +1393,7 @@
 		goto out_put_host;
 
 	host->unique_id = phba->brd_no;
-
+	init_MUTEX(&phba->hba_can_block);
 	INIT_LIST_HEAD(&phba->ctrspbuflist);
 	INIT_LIST_HEAD(&phba->rnidrspbuflist);
 	INIT_LIST_HEAD(&phba->freebufList);
@@ -1375,6 +1417,10 @@
 	psli->mbox_tmo.function = lpfc_mbox_timeout;
 	psli->mbox_tmo.data = (unsigned long)phba;
 
+	init_timer(&phba->fcp_poll_timer);
+	phba->fcp_poll_timer.function = lpfc_poll_timeout;
+	phba->fcp_poll_timer.data = (unsigned long)phba;
+
 	/*
 	 * Get all the module params for configuring this host and then
 	 * establish the host parameters.
@@ -1489,6 +1535,7 @@
 	host->max_cmd_len = 16;
 
 	/* Initialize the list of scsi buffers used by driver for scsi IO. */
+	spin_lock_init(&phba->scsi_buf_list_lock);
 	INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list);
 
 	host->transportt = lpfc_transport_template;
@@ -1520,6 +1567,12 @@
 	if (error)
 		goto out_free_irq;
 
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		spin_lock_irq(phba->host->host_lock);
+		lpfc_poll_start_timer(phba);
+		spin_unlock_irq(phba->host->host_lock);
+	}
+
 	/*
 	 * set fixed host attributes
 	 * Must done after lpfc_sli_hba_setup()
@@ -1679,14 +1732,28 @@
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PFLY,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE_SCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_NEPTUNE_DCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS_SCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HELIOS_DCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BMID,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_BSMB,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_SCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_DCSP,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZMID,
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZSMB,
@@ -1697,6 +1764,10 @@
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LP10000S,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LP11000S,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LPE11000S,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0 }
 };
 
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 507a6af..fbead78 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -55,55 +55,76 @@
 	return (1);
 }
 
-
 int
 lpfc_check_sparm(struct lpfc_hba * phba,
 		 struct lpfc_nodelist * ndlp, struct serv_parm * sp,
 		 uint32_t class)
 {
 	volatile struct serv_parm *hsp = &phba->fc_sparam;
-	/* First check for supported version */
+	uint16_t hsp_value, ssp_value = 0;
 
-	/* Next check for class validity */
+	/*
+	 * The receive data field size and buffer-to-buffer receive data field
+	 * size entries are 16 bits but are represented as two 8-bit fields in
+	 * the driver data structure to account for rsvd bits and other control
+	 * bits.  Reconstruct and compare the fields as a 16-bit values before
+	 * correcting the byte values.
+	 */
 	if (sp->cls1.classValid) {
-
-		if (sp->cls1.rcvDataSizeMsb > hsp->cls1.rcvDataSizeMsb)
-			sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
-		if (sp->cls1.rcvDataSizeLsb > hsp->cls1.rcvDataSizeLsb)
+		hsp_value = (hsp->cls1.rcvDataSizeMsb << 8) |
+				hsp->cls1.rcvDataSizeLsb;
+		ssp_value = (sp->cls1.rcvDataSizeMsb << 8) |
+				sp->cls1.rcvDataSizeLsb;
+		if (ssp_value > hsp_value) {
 			sp->cls1.rcvDataSizeLsb = hsp->cls1.rcvDataSizeLsb;
+			sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
+		}
 	} else if (class == CLASS1) {
-		return (0);
+		return 0;
 	}
 
 	if (sp->cls2.classValid) {
-
-		if (sp->cls2.rcvDataSizeMsb > hsp->cls2.rcvDataSizeMsb)
-			sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
-		if (sp->cls2.rcvDataSizeLsb > hsp->cls2.rcvDataSizeLsb)
+		hsp_value = (hsp->cls2.rcvDataSizeMsb << 8) |
+				hsp->cls2.rcvDataSizeLsb;
+		ssp_value = (sp->cls2.rcvDataSizeMsb << 8) |
+				sp->cls2.rcvDataSizeLsb;
+		if (ssp_value > hsp_value) {
 			sp->cls2.rcvDataSizeLsb = hsp->cls2.rcvDataSizeLsb;
+			sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
+		}
 	} else if (class == CLASS2) {
-		return (0);
+		return 0;
 	}
 
 	if (sp->cls3.classValid) {
-
-		if (sp->cls3.rcvDataSizeMsb > hsp->cls3.rcvDataSizeMsb)
-			sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
-		if (sp->cls3.rcvDataSizeLsb > hsp->cls3.rcvDataSizeLsb)
+		hsp_value = (hsp->cls3.rcvDataSizeMsb << 8) |
+				hsp->cls3.rcvDataSizeLsb;
+		ssp_value = (sp->cls3.rcvDataSizeMsb << 8) |
+				sp->cls3.rcvDataSizeLsb;
+		if (ssp_value > hsp_value) {
 			sp->cls3.rcvDataSizeLsb = hsp->cls3.rcvDataSizeLsb;
+			sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
+		}
 	} else if (class == CLASS3) {
-		return (0);
+		return 0;
 	}
 
-	if (sp->cmn.bbRcvSizeMsb > hsp->cmn.bbRcvSizeMsb)
-		sp->cmn.bbRcvSizeMsb = hsp->cmn.bbRcvSizeMsb;
-	if (sp->cmn.bbRcvSizeLsb > hsp->cmn.bbRcvSizeLsb)
+	/*
+	 * Preserve the upper four bits of the MSB from the PLOGI response.
+	 * These bits contain the Buffer-to-Buffer State Change Number
+	 * from the target and need to be passed to the FW.
+	 */
+	hsp_value = (hsp->cmn.bbRcvSizeMsb << 8) | hsp->cmn.bbRcvSizeLsb;
+	ssp_value = (sp->cmn.bbRcvSizeMsb << 8) | sp->cmn.bbRcvSizeLsb;
+	if (ssp_value > hsp_value) {
 		sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb;
+		sp->cmn.bbRcvSizeMsb = (sp->cmn.bbRcvSizeMsb & 0xF0) |
+				       (hsp->cmn.bbRcvSizeMsb & 0x0F);
+	}
 
-	/* If check is good, copy wwpn wwnn into ndlp */
 	memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
 	memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));
-	return (1);
+	return 1;
 }
 
 static void *
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index c63275e..9ee8218 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -41,6 +41,20 @@
 #define LPFC_ABORT_WAIT  2
 
 
+static inline void
+lpfc_block_requests(struct lpfc_hba * phba)
+{
+	down(&phba->hba_can_block);
+	scsi_block_requests(phba->host);
+}
+
+static inline void
+lpfc_unblock_requests(struct lpfc_hba * phba)
+{
+	scsi_unblock_requests(phba->host);
+	up(&phba->hba_can_block);
+}
+
 /*
  * This routine allocates a scsi buffer, which contains all the necessary
  * information needed to initiate a SCSI I/O.  The non-DMAable buffer region
@@ -137,18 +151,22 @@
 }
 
 struct  lpfc_scsi_buf*
-lpfc_sli_get_scsi_buf(struct lpfc_hba * phba)
+lpfc_get_scsi_buf(struct lpfc_hba * phba)
 {
 	struct  lpfc_scsi_buf * lpfc_cmd = NULL;
 	struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
+	unsigned long iflag = 0;
 
+	spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
 	list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list);
+	spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
 	return  lpfc_cmd;
 }
 
 static void
 lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
 {
+	unsigned long iflag = 0;
 	/*
 	 * There are only two special cases to consider.  (1) the scsi command
 	 * requested scatter-gather usage or (2) the scsi command allocated
@@ -166,8 +184,10 @@
 		 }
 	}
 
+	spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag);
 	psb->pCmd = NULL;
 	list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list);
+	spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag);
 }
 
 static int
@@ -389,7 +409,9 @@
 	struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
 	struct lpfc_nodelist *pnode = rdata->pnode;
 	struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
-	unsigned long iflag;
+	int result;
+	struct scsi_device *sdev, *tmp_sdev;
+	int depth = 0;
 
 	lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
 	lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
@@ -441,11 +463,64 @@
 				*lp, *(lp + 3), cmd->retries, cmd->resid);
 	}
 
+	result = cmd->result;
+	sdev = cmd->device;
 	cmd->scsi_done(cmd);
 
-	spin_lock_irqsave(phba->host->host_lock, iflag);
+	if (!result &&
+	   ((jiffies - pnode->last_ramp_up_time) >
+		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
+	   ((jiffies - pnode->last_q_full_time) >
+		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
+	   (phba->cfg_lun_queue_depth > sdev->queue_depth)) {
+		shost_for_each_device(tmp_sdev, sdev->host) {
+			if (phba->cfg_lun_queue_depth > tmp_sdev->queue_depth) {
+				if (tmp_sdev->id != sdev->id)
+					continue;
+				if (tmp_sdev->ordered_tags)
+					scsi_adjust_queue_depth(tmp_sdev,
+						MSG_ORDERED_TAG,
+						tmp_sdev->queue_depth+1);
+				else
+					scsi_adjust_queue_depth(tmp_sdev,
+						MSG_SIMPLE_TAG,
+						tmp_sdev->queue_depth+1);
+
+				pnode->last_ramp_up_time = jiffies;
+			}
+		}
+	}
+
+	/*
+	 * Check for queue full.  If the lun is reporting queue full, then
+	 * back off the lun queue depth to prevent target overloads.
+	 */
+	if (result == SAM_STAT_TASK_SET_FULL) {
+		pnode->last_q_full_time = jiffies;
+
+		shost_for_each_device(tmp_sdev, sdev->host) {
+			if (tmp_sdev->id != sdev->id)
+				continue;
+			depth = scsi_track_queue_full(tmp_sdev,
+					tmp_sdev->queue_depth - 1);
+		}
+		/*
+ 		 * The queue depth cannot be lowered any more.
+		 * Modify the returned error code to store
+		 * the final depth value set by
+		 * scsi_track_queue_full.
+		 */
+		if (depth == -1)
+			depth = sdev->host->cmd_per_lun;
+
+		if (depth) {
+			lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
+				"%d:0711 detected queue full - lun queue depth "
+				" adjusted to %d.\n", phba->brd_no, depth);
+		}
+	}
+
 	lpfc_release_scsi_buf(phba, lpfc_cmd);
-	spin_unlock_irqrestore(phba->host->host_lock, iflag);
 }
 
 static void
@@ -693,6 +768,37 @@
 	return lpfcinfobuf;
 }
 
+static __inline__ void lpfc_poll_rearm_timer(struct lpfc_hba * phba)
+{
+	unsigned long  poll_tmo_expires =
+		(jiffies + msecs_to_jiffies(phba->cfg_poll_tmo));
+
+	if (phba->sli.ring[LPFC_FCP_RING].txcmplq_cnt)
+		mod_timer(&phba->fcp_poll_timer,
+			  poll_tmo_expires);
+}
+
+void lpfc_poll_start_timer(struct lpfc_hba * phba)
+{
+	lpfc_poll_rearm_timer(phba);
+}
+
+void lpfc_poll_timeout(unsigned long ptr)
+{
+	struct lpfc_hba *phba = (struct lpfc_hba *)ptr;
+	unsigned long iflag;
+
+	spin_lock_irqsave(phba->host->host_lock, iflag);
+
+	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+		lpfc_sli_poll_fcp_ring (phba);
+		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+			lpfc_poll_rearm_timer(phba);
+	}
+
+	spin_unlock_irqrestore(phba->host->host_lock, iflag);
+}
+
 static int
 lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 {
@@ -719,10 +825,11 @@
 		cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
 		goto out_fail_command;
 	}
-	lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
+	lpfc_cmd = lpfc_get_scsi_buf (phba);
 	if (lpfc_cmd == NULL) {
-		printk(KERN_WARNING "%s: No buffer available - list empty, "
-		       "total count %d\n", __FUNCTION__, phba->total_scsi_bufs);
+		lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+				"%d:0707 driver's buffer pool is empty, "
+				"IO busied\n", phba->brd_no);
 		goto out_host_busy;
 	}
 
@@ -746,11 +853,17 @@
 				&lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB);
 	if (err)
 		goto out_host_busy_free_buf;
+
+	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+		lpfc_sli_poll_fcp_ring(phba);
+		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+			lpfc_poll_rearm_timer(phba);
+	}
+
 	return 0;
 
  out_host_busy_free_buf:
 	lpfc_release_scsi_buf(phba, lpfc_cmd);
-	cmnd->host_scribble = NULL;
  out_host_busy:
 	return SCSI_MLQUEUE_HOST_BUSY;
 
@@ -759,11 +872,12 @@
 	return 0;
 }
 
+
 static int
-__lpfc_abort_handler(struct scsi_cmnd *cmnd)
+lpfc_abort_handler(struct scsi_cmnd *cmnd)
 {
-	struct lpfc_hba *phba =
-			(struct lpfc_hba *)cmnd->device->host->hostdata[0];
+	struct Scsi_Host *shost = cmnd->device->host;
+	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
 	struct lpfc_sli_ring *pring = &phba->sli.ring[phba->sli.fcp_ring];
 	struct lpfc_iocbq *iocb;
 	struct lpfc_iocbq *abtsiocb;
@@ -772,6 +886,8 @@
 	unsigned int loop_count = 0;
 	int ret = SUCCESS;
 
+	lpfc_block_requests(phba);
+	spin_lock_irq(shost->host_lock);
 
 	lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
 	BUG_ON(!lpfc_cmd);
@@ -821,9 +937,15 @@
 		goto out;
 	}
 
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+		lpfc_sli_poll_fcp_ring (phba);
+
 	/* Wait for abort to complete */
 	while (lpfc_cmd->pCmd == cmnd)
 	{
+		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+			lpfc_sli_poll_fcp_ring (phba);
+
 		spin_unlock_irq(phba->host->host_lock);
 			schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ);
 		spin_lock_irq(phba->host->host_lock);
@@ -844,26 +966,19 @@
 
  out:
 	lpfc_printf_log(phba, KERN_WARNING, LOG_FCP,
-			"%d:0749 SCSI layer issued abort device: ret %#x, "
-			"ID %d, LUN %d, snum %#lx\n",
+			"%d:0749 SCSI Layer I/O Abort Request "
+			"Status x%x ID %d LUN %d snum %#lx\n",
 			phba->brd_no, ret, cmnd->device->id,
 			cmnd->device->lun, cmnd->serial_number);
 
+	spin_unlock_irq(shost->host_lock);
+	lpfc_unblock_requests(phba);
+
 	return ret;
 }
 
 static int
-lpfc_abort_handler(struct scsi_cmnd *cmnd)
-{
-	int rc;
-	spin_lock_irq(cmnd->device->host->host_lock);
-	rc = __lpfc_abort_handler(cmnd);
-	spin_unlock_irq(cmnd->device->host->host_lock);
-	return rc;
-}
-
-static int
-__lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
+lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
 {
 	struct Scsi_Host *shost = cmnd->device->host;
 	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -871,9 +986,12 @@
 	struct lpfc_iocbq *iocbq, *iocbqrsp;
 	struct lpfc_rport_data *rdata = cmnd->device->hostdata;
 	struct lpfc_nodelist *pnode = rdata->pnode;
+	uint32_t cmd_result = 0, cmd_status = 0;
 	int ret = FAILED;
 	int cnt, loopcnt;
 
+	lpfc_block_requests(phba);
+	spin_lock_irq(shost->host_lock);
 	/*
 	 * If target is not in a MAPPED state, delay the reset until
 	 * target is rediscovered or nodev timeout expires.
@@ -891,7 +1009,7 @@
 			break;
 	}
 
-	lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
+	lpfc_cmd = lpfc_get_scsi_buf (phba);
 	if (lpfc_cmd == NULL)
 		goto out;
 
@@ -916,26 +1034,28 @@
 	if (ret == IOCB_SUCCESS)
 		ret = SUCCESS;
 
-	lpfc_cmd->result = iocbqrsp->iocb.un.ulpWord[4];
-	lpfc_cmd->status = iocbqrsp->iocb.ulpStatus;
-	if (lpfc_cmd->status == IOSTAT_LOCAL_REJECT)
-		if (lpfc_cmd->result & IOERR_DRVR_MASK)
-			lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
+
+	cmd_result = iocbqrsp->iocb.un.ulpWord[4];
+	cmd_status = iocbqrsp->iocb.ulpStatus;
+
+	lpfc_sli_release_iocbq(phba, iocbqrsp);
+	lpfc_release_scsi_buf(phba, lpfc_cmd);
 
 	/*
-	 * All outstanding txcmplq I/Os should have been aborted by the target.
+	 * All outstanding txcmplq I/Os should have been aborted by the device.
 	 * Unfortunately, some targets do not abide by this forcing the driver
 	 * to double check.
 	 */
-	lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
-			    cmnd->device->id, cmnd->device->lun, 0,
-			    LPFC_CTX_LUN);
-
+	cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
+				cmnd->device->id, cmnd->device->lun,
+				LPFC_CTX_LUN);
+	if (cnt)
+		lpfc_sli_abort_iocb(phba,
+				    &phba->sli.ring[phba->sli.fcp_ring],
+				    cmnd->device->id, cmnd->device->lun,
+				    0, LPFC_CTX_LUN);
 	loopcnt = 0;
-	while((cnt = lpfc_sli_sum_iocb(phba,
-				       &phba->sli.ring[phba->sli.fcp_ring],
-				       cmnd->device->id, cmnd->device->lun,
-				       LPFC_CTX_LUN))) {
+	while(cnt) {
 		spin_unlock_irq(phba->host->host_lock);
 		schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
 		spin_lock_irq(phba->host->host_lock);
@@ -943,6 +1063,11 @@
 		if (++loopcnt
 		    > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT)
 			break;
+
+		cnt = lpfc_sli_sum_iocb(phba,
+					&phba->sli.ring[phba->sli.fcp_ring],
+					cmnd->device->id, cmnd->device->lun,
+					LPFC_CTX_LUN);
 	}
 
 	if (cnt) {
@@ -952,35 +1077,21 @@
 		ret = FAILED;
 	}
 
-	lpfc_sli_release_iocbq(phba, iocbqrsp);
-
 out_free_scsi_buf:
 	lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
 			"%d:0713 SCSI layer issued LUN reset (%d, %d) "
 			"Data: x%x x%x x%x\n",
-			phba->brd_no, lpfc_cmd->pCmd->device->id,
-			lpfc_cmd->pCmd->device->lun, ret, lpfc_cmd->status,
-			lpfc_cmd->result);
-	lpfc_release_scsi_buf(phba, lpfc_cmd);
+			phba->brd_no, cmnd->device->id,cmnd->device->lun,
+			ret, cmd_status, cmd_result);
+
 out:
+	spin_unlock_irq(shost->host_lock);
+	lpfc_unblock_requests(phba);
 	return ret;
 }
 
 static int
-lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
-{
-	int rc;
-	spin_lock_irq(cmnd->device->host->host_lock);
-	rc = __lpfc_reset_lun_handler(cmnd);
-	spin_unlock_irq(cmnd->device->host->host_lock);
-	return rc;
-}
-
-/*
- * Note: midlayer calls this function with the host_lock held
- */
-static int
-__lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
+lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
 {
 	struct Scsi_Host *shost = cmnd->device->host;
 	struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
@@ -991,7 +1102,10 @@
 	unsigned int midlayer_id = 0;
 	struct lpfc_scsi_buf * lpfc_cmd;
 
-	lpfc_cmd = lpfc_sli_get_scsi_buf (phba);
+	lpfc_block_requests(phba);
+	spin_lock_irq(shost->host_lock);
+
+	lpfc_cmd = lpfc_get_scsi_buf(phba);
 	if (lpfc_cmd == NULL)
 		goto out;
 
@@ -1022,18 +1136,31 @@
 		lpfc_cmd->pCmd->device->hostdata = ndlp->rport->dd_data;
 		ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba);
 		if (ret != SUCCESS) {
-			lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+			lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
 				"%d:0713 Bus Reset on target %d failed\n",
 				phba->brd_no, i);
 			err_count++;
 		}
 	}
 
+	if (err_count == 0)
+		ret = SUCCESS;
+
+	lpfc_release_scsi_buf(phba, lpfc_cmd);
+
+	/*
+	 * All outstanding txcmplq I/Os should have been aborted by
+	 * the targets.  Unfortunately, some targets do not abide by
+	 * this forcing the driver to double check.
+	 */
 	cmnd->device->id = midlayer_id;
+	cnt = lpfc_sli_sum_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
+				0, 0, LPFC_CTX_HOST);
+	if (cnt)
+		lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
+				    0, 0, 0, LPFC_CTX_HOST);
 	loopcnt = 0;
-	while((cnt = lpfc_sli_sum_iocb(phba,
-				&phba->sli.ring[phba->sli.fcp_ring],
-				0, 0, LPFC_CTX_HOST))) {
+	while(cnt) {
 		spin_unlock_irq(phba->host->host_lock);
 		schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
 		spin_lock_irq(phba->host->host_lock);
@@ -1041,45 +1168,31 @@
 		if (++loopcnt
 		    > (2 * phba->cfg_nodev_tmo)/LPFC_RESET_WAIT)
 			break;
+
+		cnt = lpfc_sli_sum_iocb(phba,
+					&phba->sli.ring[phba->sli.fcp_ring],
+					0, 0, LPFC_CTX_HOST);
 	}
 
 	if (cnt) {
-		/* flush all outstanding commands on the host */
-		i = lpfc_sli_abort_iocb(phba,
-				&phba->sli.ring[phba->sli.fcp_ring], 0, 0, 0,
-				LPFC_CTX_HOST);
-
-		lpfc_printf_log(phba, KERN_INFO, LOG_FCP,
+		lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
 		   "%d:0715 Bus Reset I/O flush failure: cnt x%x left x%x\n",
 		   phba->brd_no, cnt, i);
+		ret = FAILED;
 	}
 
-	if (cnt == 0)
-		ret = SUCCESS;
-	else
-		ret = FAILED;
-
-	lpfc_release_scsi_buf(phba, lpfc_cmd);
 	lpfc_printf_log(phba,
 			KERN_ERR,
 			LOG_FCP,
 			"%d:0714 SCSI layer issued Bus Reset Data: x%x\n",
 			phba->brd_no, ret);
 out:
+	spin_unlock_irq(shost->host_lock);
+	lpfc_unblock_requests(phba);
 	return ret;
 }
 
 static int
-lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
-{
-	int rc;
-	spin_lock_irq(cmnd->device->host->host_lock);
-	rc = __lpfc_reset_bus_handler(cmnd);
-	spin_unlock_irq(cmnd->device->host->host_lock);
-	return rc;
-}
-
-static int
 lpfc_slave_alloc(struct scsi_device *sdev)
 {
 	struct lpfc_hba *phba = (struct lpfc_hba *)sdev->host->hostdata[0];
@@ -1127,10 +1240,10 @@
 			break;
 		}
 
-		spin_lock_irqsave(phba->host->host_lock, flags);
+		spin_lock_irqsave(&phba->scsi_buf_list_lock, flags);
 		phba->total_scsi_bufs++;
 		list_add_tail(&scsi_buf->list, &phba->lpfc_scsi_buf_list);
-		spin_unlock_irqrestore(phba->host->host_lock, flags);
+		spin_unlock_irqrestore(&phba->scsi_buf_list_lock, flags);
 	}
 	return 0;
 }
@@ -1154,6 +1267,12 @@
 	 */
 	rport->dev_loss_tmo = phba->cfg_nodev_tmo + 5;
 
+	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
+		lpfc_sli_poll_fcp_ring(phba);
+		if (phba->cfg_poll & DISABLE_FCP_RING_INT)
+			lpfc_poll_rearm_timer(phba);
+	}
+
 	return 0;
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index e2c08c5..7b785ad 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -886,6 +886,182 @@
 	return rc;
 }
 
+static void lpfc_sli_rsp_pointers_error(struct lpfc_hba * phba,
+					struct lpfc_sli_ring * pring)
+{
+	struct lpfc_pgp *pgp = &phba->slim2p->mbx.us.s2.port[pring->ringno];
+	/*
+	 * Ring <ringno> handler: portRspPut <portRspPut> is bigger then
+	 * rsp ring <portRspMax>
+	 */
+	lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+			"%d:0312 Ring %d handler: portRspPut %d "
+			"is bigger then rsp ring %d\n",
+			phba->brd_no, pring->ringno,
+			le32_to_cpu(pgp->rspPutInx),
+			pring->numRiocb);
+
+	phba->hba_state = LPFC_HBA_ERROR;
+
+	/*
+	 * All error attention handlers are posted to
+	 * worker thread
+	 */
+	phba->work_ha |= HA_ERATT;
+	phba->work_hs = HS_FFER3;
+	if (phba->work_wait)
+		wake_up(phba->work_wait);
+
+	return;
+}
+
+void lpfc_sli_poll_fcp_ring(struct lpfc_hba * phba)
+{
+	struct lpfc_sli      * psli   = &phba->sli;
+	struct lpfc_sli_ring * pring = &psli->ring[LPFC_FCP_RING];
+	IOCB_t *irsp = NULL;
+	IOCB_t *entry = NULL;
+	struct lpfc_iocbq *cmdiocbq = NULL;
+	struct lpfc_iocbq rspiocbq;
+	struct lpfc_pgp *pgp;
+	uint32_t status;
+	uint32_t portRspPut, portRspMax;
+	int type;
+	uint32_t rsp_cmpl = 0;
+	void __iomem *to_slim;
+	uint32_t ha_copy;
+
+	pring->stats.iocb_event++;
+
+	/* The driver assumes SLI-2 mode */
+	pgp =  &phba->slim2p->mbx.us.s2.port[pring->ringno];
+
+	/*
+	 * The next available response entry should never exceed the maximum
+	 * entries.  If it does, treat it as an adapter hardware error.
+	 */
+	portRspMax = pring->numRiocb;
+	portRspPut = le32_to_cpu(pgp->rspPutInx);
+	if (unlikely(portRspPut >= portRspMax)) {
+		lpfc_sli_rsp_pointers_error(phba, pring);
+		return;
+	}
+
+	rmb();
+	while (pring->rspidx != portRspPut) {
+
+		entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+
+		if (++pring->rspidx >= portRspMax)
+			pring->rspidx = 0;
+
+		lpfc_sli_pcimem_bcopy((uint32_t *) entry,
+				      (uint32_t *) &rspiocbq.iocb,
+				      sizeof (IOCB_t));
+		irsp = &rspiocbq.iocb;
+		type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK);
+		pring->stats.iocb_rsp++;
+		rsp_cmpl++;
+
+		if (unlikely(irsp->ulpStatus)) {
+			/* Rsp ring <ringno> error: IOCB */
+			lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+					"%d:0326 Rsp Ring %d error: IOCB Data: "
+					"x%x x%x x%x x%x x%x x%x x%x x%x\n",
+					phba->brd_no, pring->ringno,
+					irsp->un.ulpWord[0],
+					irsp->un.ulpWord[1],
+					irsp->un.ulpWord[2],
+					irsp->un.ulpWord[3],
+					irsp->un.ulpWord[4],
+					irsp->un.ulpWord[5],
+					*(((uint32_t *) irsp) + 6),
+					*(((uint32_t *) irsp) + 7));
+		}
+
+		switch (type) {
+		case LPFC_ABORT_IOCB:
+		case LPFC_SOL_IOCB:
+			/*
+			 * Idle exchange closed via ABTS from port.  No iocb
+			 * resources need to be recovered.
+			 */
+			if (unlikely(irsp->ulpCommand == CMD_XRI_ABORTED_CX)) {
+				printk(KERN_INFO "%s: IOCB cmd 0x%x processed."
+				       " Skipping completion\n", __FUNCTION__,
+				       irsp->ulpCommand);
+				break;
+			}
+
+			cmdiocbq = lpfc_sli_iocbq_lookup(phba, pring,
+							 &rspiocbq);
+			if ((cmdiocbq) && (cmdiocbq->iocb_cmpl)) {
+				(cmdiocbq->iocb_cmpl)(phba, cmdiocbq,
+						      &rspiocbq);
+			}
+			break;
+		default:
+			if (irsp->ulpCommand == CMD_ADAPTER_MSG) {
+				char adaptermsg[LPFC_MAX_ADPTMSG];
+				memset(adaptermsg, 0, LPFC_MAX_ADPTMSG);
+				memcpy(&adaptermsg[0], (uint8_t *) irsp,
+				       MAX_MSG_DATA);
+				dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s",
+					 phba->brd_no, adaptermsg);
+			} else {
+				/* Unknown IOCB command */
+				lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+						"%d:0321 Unknown IOCB command "
+						"Data: x%x, x%x x%x x%x x%x\n",
+						phba->brd_no, type,
+						irsp->ulpCommand,
+						irsp->ulpStatus,
+						irsp->ulpIoTag,
+						irsp->ulpContext);
+			}
+			break;
+		}
+
+		/*
+		 * The response IOCB has been processed.  Update the ring
+		 * pointer in SLIM.  If the port response put pointer has not
+		 * been updated, sync the pgp->rspPutInx and fetch the new port
+		 * response put pointer.
+		 */
+		to_slim = phba->MBslimaddr +
+			(SLIMOFF + (pring->ringno * 2) + 1) * 4;
+		writeb(pring->rspidx, to_slim);
+
+		if (pring->rspidx == portRspPut)
+			portRspPut = le32_to_cpu(pgp->rspPutInx);
+	}
+
+	ha_copy = readl(phba->HAregaddr);
+	ha_copy >>= (LPFC_FCP_RING * 4);
+
+	if ((rsp_cmpl > 0) && (ha_copy & HA_R0RE_REQ)) {
+		pring->stats.iocb_rsp_full++;
+		status = ((CA_R0ATT | CA_R0RE_RSP) << (LPFC_FCP_RING * 4));
+		writel(status, phba->CAregaddr);
+		readl(phba->CAregaddr);
+	}
+	if ((ha_copy & HA_R0CE_RSP) &&
+	    (pring->flag & LPFC_CALL_RING_AVAILABLE)) {
+		pring->flag &= ~LPFC_CALL_RING_AVAILABLE;
+		pring->stats.iocb_cmd_empty++;
+
+		/* Force update of the local copy of cmdGetInx */
+		pring->local_getidx = le32_to_cpu(pgp->cmdGetInx);
+		lpfc_sli_resume_iocb(phba, pring);
+
+		if ((pring->lpfc_sli_cmd_available))
+			(pring->lpfc_sli_cmd_available) (phba, pring);
+
+	}
+
+	return;
+}
+
 /*
  * This routine presumes LPFC_FCP_RING handling and doesn't bother
  * to check it explicitly.
@@ -917,24 +1093,7 @@
 	portRspMax = pring->numRiocb;
 	portRspPut = le32_to_cpu(pgp->rspPutInx);
 	if (unlikely(portRspPut >= portRspMax)) {
-		/*
-		 * Ring <ringno> handler: portRspPut <portRspPut> is bigger then
-		 * rsp ring <portRspMax>
-		 */
-		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
-				"%d:0312 Ring %d handler: portRspPut %d "
-				"is bigger then rsp ring %d\n",
-				phba->brd_no, pring->ringno, portRspPut,
-				portRspMax);
-
-		phba->hba_state = LPFC_HBA_ERROR;
-
-		/* All error attention handlers are posted to worker thread */
-		phba->work_ha |= HA_ERATT;
-		phba->work_hs = HS_FFER3;
-		if (phba->work_wait)
-			wake_up(phba->work_wait);
-
+		lpfc_sli_rsp_pointers_error(phba, pring);
 		spin_unlock_irqrestore(phba->host->host_lock, iflag);
 		return 1;
 	}
@@ -947,6 +1106,10 @@
 		 * network byte order and pci byte orders are different.
 		 */
 		entry = IOCB_ENTRY(pring->rspringaddr, pring->rspidx);
+
+		if (++pring->rspidx >= portRspMax)
+			pring->rspidx = 0;
+
 		lpfc_sli_pcimem_bcopy((uint32_t *) entry,
 				      (uint32_t *) &rspiocbq.iocb,
 				      sizeof (IOCB_t));
@@ -1020,9 +1183,6 @@
 		 * been updated, sync the pgp->rspPutInx and fetch the new port
 		 * response put pointer.
 		 */
-		if (++pring->rspidx >= portRspMax)
-			pring->rspidx = 0;
-
 		to_slim = phba->MBslimaddr +
 			(SLIMOFF + (pring->ringno * 2) + 1) * 4;
 		writel(pring->rspidx, to_slim);
@@ -2615,6 +2775,7 @@
 	DECLARE_WAIT_QUEUE_HEAD(done_q);
 	long timeleft, timeout_req = 0;
 	int retval = IOCB_SUCCESS;
+	uint32_t creg_val;
 
 	/*
 	 * If the caller has provided a response iocbq buffer, then context2
@@ -2630,6 +2791,13 @@
 	piocb->context_un.wait_queue = &done_q;
 	piocb->iocb_flag &= ~LPFC_IO_WAKE;
 
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		creg_val = readl(phba->HCregaddr);
+		creg_val |= (HC_R0INT_ENA << LPFC_FCP_RING);
+		writel(creg_val, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
+	}
+
 	retval = lpfc_sli_issue_iocb(phba, pring, piocb, 0);
 	if (retval == IOCB_SUCCESS) {
 		timeout_req = timeout * HZ;
@@ -2663,6 +2831,13 @@
 		retval = IOCB_ERROR;
 	}
 
+	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
+		creg_val = readl(phba->HCregaddr);
+		creg_val &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+		writel(creg_val, phba->HCregaddr);
+		readl(phba->HCregaddr); /* flush */
+	}
+
 	if (prspiocbq)
 		piocb->context2 = NULL;
 
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index 4f0466f..fa681a9 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.1.0"
+#define LPFC_DRIVER_VERSION "8.1.1"
 
 #define LPFC_DRIVER_NAME "lpfc"
 
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index dfea346..4a6feb1 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -2,7 +2,7 @@
  *
  *			Linux MegaRAID device driver
  *
- * Copyright © 2002  LSI Logic Corporation.
+ * Copyright (c) 2002  LSI Logic Corporation.
  *
  *	   This program is free software; you can redistribute it and/or
  *	   modify it under the terms of the GNU General Public License
@@ -17,7 +17,8 @@
  * Copyright (c) 2003  Christoph Hellwig  <hch@lst.de>
  *	  - new-style, hotplug-aware pci probing and scsi registration
  *
- * Version : v2.00.3 (Feb 19, 2003) - Atul Mukker <Atul.Mukker@lsil.com>
+ * Version : v2.00.4 Mon Nov 14 14:02:43 EST 2005 - Seokmann Ju
+ * 						<Seokmann.Ju@lsil.com>
  *
  * Description: Linux device driver for LSI Logic MegaRAID controller
  *
@@ -51,10 +52,10 @@
 
 #include "megaraid.h"
 
-#define MEGARAID_MODULE_VERSION "2.00.3"
+#define MEGARAID_MODULE_VERSION "2.00.4"
 
-MODULE_AUTHOR ("LSI Logic Corporation");
-MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
+MODULE_AUTHOR ("sju@lsil.com");
+MODULE_DESCRIPTION ("LSI Logic MegaRAID legacy driver");
 MODULE_LICENSE ("GPL");
 MODULE_VERSION(MEGARAID_MODULE_VERSION);
 
@@ -380,23 +381,23 @@
 
 	spin_lock_irqsave(&adapter->lock, flags);
 	scb = mega_build_cmd(adapter, scmd, &busy);
+	if (!scb)
+		goto out;
 
-	if(scb) {
-		scb->state |= SCB_PENDQ;
-		list_add_tail(&scb->list, &adapter->pending_list);
+	scb->state |= SCB_PENDQ;
+	list_add_tail(&scb->list, &adapter->pending_list);
 
-		/*
-		 * Check if the HBA is in quiescent state, e.g., during a
-		 * delete logical drive opertion. If it is, don't run
-		 * the pending_list.
-		 */
-		if(atomic_read(&adapter->quiescent) == 0) {
-			mega_runpendq(adapter);
-		}
-		return 0;
-	}
+	/*
+	 * Check if the HBA is in quiescent state, e.g., during a
+	 * delete logical drive opertion. If it is, don't run
+	 * the pending_list.
+	 */
+	if (atomic_read(&adapter->quiescent) == 0)
+		mega_runpendq(adapter);
+
+	busy = 0;
+ out:
 	spin_unlock_irqrestore(&adapter->lock, flags);
-
 	return busy;
 }
 
@@ -664,7 +665,7 @@
 					sg->offset;
 			} else
 				buf = cmd->request_buffer;
-			memset(cmd->request_buffer, 0, cmd->cmnd[4]);
+			memset(buf, 0, cmd->cmnd[4]);
 			if (cmd->use_sg) {
 				struct scatterlist *sg;
 
@@ -4553,7 +4554,7 @@
 static struct scsi_host_template megaraid_template = {
 	.module				= THIS_MODULE,
 	.name				= "MegaRAID",
-	.proc_name			= "megaraid",
+	.proc_name			= "megaraid_legacy",
 	.info				= megaraid_info,
 	.queuecommand			= megaraid_queue,	
 	.bios_param			= megaraid_biosparam,
@@ -4677,7 +4678,6 @@
 
 	adapter->flag = flag;
 	spin_lock_init(&adapter->lock);
-	scsi_assign_lock(host, &adapter->lock);
 
 	host->cmd_per_lun = max_cmd_per_lun;
 	host->max_sectors = max_sectors_per_io;
@@ -5038,22 +5038,12 @@
 }
 
 static struct pci_device_id megaraid_pci_tbl[] = {
-	{PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DISCOVERY,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_PERC4_DI,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
-	{PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_PERC4_QC_VERDE,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, BOARD_64BIT},
 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID2,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_AMI_MEGARAID3,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, megaraid_pci_tbl);
@@ -5096,7 +5086,7 @@
 	 * First argument (major) to register_chrdev implies a dynamic
 	 * major number allocation.
 	 */
-	major = register_chrdev(0, "megadev", &megadev_fops);
+	major = register_chrdev(0, "megadev_legacy", &megadev_fops);
 	if (!major) {
 		printk(KERN_WARNING
 				"megaraid: failed to register char device\n");
@@ -5110,7 +5100,7 @@
 	/*
 	 * Unregister the character device interface to the driver.
 	 */
-	unregister_chrdev(major, "megadev");
+	unregister_chrdev(major, "megadev_legacy");
 
 	pci_unregister_driver(&megaraid_pci_driver);
 
diff --git a/drivers/scsi/megaraid/Kconfig.megaraid b/drivers/scsi/megaraid/Kconfig.megaraid
index 7363e12..17419e3 100644
--- a/drivers/scsi/megaraid/Kconfig.megaraid
+++ b/drivers/scsi/megaraid/Kconfig.megaraid
@@ -64,7 +64,6 @@
 	To compile this driver as a module, choose M here: the
 	module will be called megaraid_mbox
 
-if MEGARAID_NEWGEN=n
 config MEGARAID_LEGACY
 	tristate "LSI Logic Legacy MegaRAID Driver"
 	depends on PCI && SCSI
@@ -75,7 +74,6 @@
 
 	To compile this driver as a module, choose M here: the
 	module will be called megaraid
-endif
 
 config MEGARAID_SAS
 	tristate "LSI Logic MegaRAID SAS RAID Module"
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 4b5d420..d18a4bc 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -10,12 +10,13 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_mbox.c
- * Version	: v2.20.4.6 (Mar 07 2005)
+ * Version	: v2.20.4.7 (Nov 14 2005)
  *
  * Authors:
  * 	Atul Mukker		<Atul.Mukker@lsil.com>
  * 	Sreenivas Bagalkote	<Sreenivas.Bagalkote@lsil.com>
  * 	Manoj Jose		<Manoj.Jose@lsil.com>
+ * 	Seokmann Ju		<Seokmann.Ju@lsil.com>
  *
  * List of supported controllers
  *
@@ -136,7 +137,7 @@
 
 
 
-MODULE_AUTHOR("LSI Logic Corporation");
+MODULE_AUTHOR("sju@lsil.com");
 MODULE_DESCRIPTION("LSI Logic MegaRAID Mailbox Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(MEGARAID_VERSION);
@@ -278,68 +279,14 @@
 	{
 		PCI_VENDOR_ID_AMI,
 		PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_VENDOR_ID_DELL,
-		PCI_SUBSYS_ID_PERC3_QC,
+		PCI_ANY_ID,
+		PCI_ANY_ID,
 	},
 	{
-		PCI_VENDOR_ID_AMI,
+		PCI_VENDOR_ID_LSI_LOGIC,
 		PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_VENDOR_ID_DELL,
-		PCI_SUBSYS_ID_PERC3_DC,
-	},
-	{
-		PCI_VENDOR_ID_AMI,
-		PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_VENDOR_ID_DELL,
-		PCI_SUBSYS_ID_PERC3_SC,
-	},
-	{
-		PCI_VENDOR_ID_AMI,
-		PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_VENDOR_ID_AMI,
-		PCI_SUBSYS_ID_PERC3_SC,
-	},
-	{
-		PCI_VENDOR_ID_AMI,
-		PCI_DEVICE_ID_AMI_MEGARAID3,
-		PCI_VENDOR_ID_AMI,
-		PCI_SUBSYS_ID_PERC3_DC,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_0,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_0,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_1,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_1,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SCSI_320_2,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SCSI_320_2,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_I4_133_RAID,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_I4_133_RAID,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SATA_150_4,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SATA_150_4,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_MEGARAID_SATA_150_6,
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_SUBSYS_ID_MEGARAID_SATA_150_6,
+		PCI_ANY_ID,
+		PCI_ANY_ID,
 	},
 	{
 		PCI_VENDOR_ID_LSI_LOGIC,
@@ -347,18 +294,6 @@
 		PCI_ANY_ID,
 		PCI_ANY_ID,
 	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SRCS16,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SRCS16,
-	},
-	{
-		PCI_VENDOR_ID_LSI_LOGIC,
-		PCI_DEVICE_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
-		PCI_VENDOR_ID_INTEL,
-		PCI_SUBSYS_ID_INTEL_RAID_SRCU41L_LAKE_SHETEK,
-	},
 	{0}	/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, pci_id_table_g);
@@ -2985,6 +2920,7 @@
 
 	for (i = 0; i < 0xFFFFF; i++) {
 		if (mbox->numstatus != 0xFF) break;
+		rmb();
 	}
 
 	if (i == 0xFFFFF) {
diff --git a/drivers/scsi/megaraid/megaraid_mbox.h b/drivers/scsi/megaraid/megaraid_mbox.h
index 644b91b..882fb1a 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.h
+++ b/drivers/scsi/megaraid/megaraid_mbox.h
@@ -21,8 +21,8 @@
 #include "megaraid_ioctl.h"
 
 
-#define MEGARAID_VERSION	"2.20.4.6"
-#define MEGARAID_EXT_VERSION	"(Release Date: Mon Mar 07 12:27:22 EST 2005)"
+#define MEGARAID_VERSION	"2.20.4.7"
+#define MEGARAID_EXT_VERSION	"(Release Date: Mon Nov 14 12:27:22 EST 2005)"
 
 
 /*
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index 2434709..3235070 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -131,7 +131,739 @@
 #define NAME53C			"ncr53c"
 #define NAME53C8XX		"ncr53c8xx"
 
-#include "sym53c8xx_comm.h"
+
+/*==========================================================
+**
+**	Debugging tags
+**
+**==========================================================
+*/
+
+#define DEBUG_ALLOC    (0x0001)
+#define DEBUG_PHASE    (0x0002)
+#define DEBUG_QUEUE    (0x0008)
+#define DEBUG_RESULT   (0x0010)
+#define DEBUG_POINTER  (0x0020)
+#define DEBUG_SCRIPT   (0x0040)
+#define DEBUG_TINY     (0x0080)
+#define DEBUG_TIMING   (0x0100)
+#define DEBUG_NEGO     (0x0200)
+#define DEBUG_TAGS     (0x0400)
+#define DEBUG_SCATTER  (0x0800)
+#define DEBUG_IC        (0x1000)
+
+/*
+**    Enable/Disable debug messages.
+**    Can be changed at runtime too.
+*/
+
+#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
+static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
+	#define DEBUG_FLAGS ncr_debug
+#else
+	#define DEBUG_FLAGS	SCSI_NCR_DEBUG_FLAGS
+#endif
+
+static inline struct list_head *ncr_list_pop(struct list_head *head)
+{
+	if (!list_empty(head)) {
+		struct list_head *elem = head->next;
+
+		list_del(elem);
+		return elem;
+	}
+
+	return NULL;
+}
+
+/*==========================================================
+**
+**	Simple power of two buddy-like allocator.
+**
+**	This simple code is not intended to be fast, but to 
+**	provide power of 2 aligned memory allocations.
+**	Since the SCRIPTS processor only supplies 8 bit 
+**	arithmetic, this allocator allows simple and fast 
+**	address calculations  from the SCRIPTS code.
+**	In addition, cache line alignment is guaranteed for 
+**	power of 2 cache line size.
+**	Enhanced in linux-2.3.44 to provide a memory pool 
+**	per pcidev to support dynamic dma mapping. (I would 
+**	have preferred a real bus astraction, btw).
+**
+**==========================================================
+*/
+
+#define MEMO_SHIFT	4	/* 16 bytes minimum memory chunk */
+#if PAGE_SIZE >= 8192
+#define MEMO_PAGE_ORDER	0	/* 1 PAGE  maximum */
+#else
+#define MEMO_PAGE_ORDER	1	/* 2 PAGES maximum */
+#endif
+#define MEMO_FREE_UNUSED	/* Free unused pages immediately */
+#define MEMO_WARN	1
+#define MEMO_GFP_FLAGS	GFP_ATOMIC
+#define MEMO_CLUSTER_SHIFT	(PAGE_SHIFT+MEMO_PAGE_ORDER)
+#define MEMO_CLUSTER_SIZE	(1UL << MEMO_CLUSTER_SHIFT)
+#define MEMO_CLUSTER_MASK	(MEMO_CLUSTER_SIZE-1)
+
+typedef u_long m_addr_t;	/* Enough bits to bit-hack addresses */
+typedef struct device *m_bush_t;	/* Something that addresses DMAable */
+
+typedef struct m_link {		/* Link between free memory chunks */
+	struct m_link *next;
+} m_link_s;
+
+typedef struct m_vtob {		/* Virtual to Bus address translation */
+	struct m_vtob *next;
+	m_addr_t vaddr;
+	m_addr_t baddr;
+} m_vtob_s;
+#define VTOB_HASH_SHIFT		5
+#define VTOB_HASH_SIZE		(1UL << VTOB_HASH_SHIFT)
+#define VTOB_HASH_MASK		(VTOB_HASH_SIZE-1)
+#define VTOB_HASH_CODE(m)	\
+	((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
+
+typedef struct m_pool {		/* Memory pool of a given kind */
+	m_bush_t bush;
+	m_addr_t (*getp)(struct m_pool *);
+	void (*freep)(struct m_pool *, m_addr_t);
+	int nump;
+	m_vtob_s *(vtob[VTOB_HASH_SIZE]);
+	struct m_pool *next;
+	struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
+} m_pool_s;
+
+static void *___m_alloc(m_pool_s *mp, int size)
+{
+	int i = 0;
+	int s = (1 << MEMO_SHIFT);
+	int j;
+	m_addr_t a;
+	m_link_s *h = mp->h;
+
+	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
+		return NULL;
+
+	while (size > s) {
+		s <<= 1;
+		++i;
+	}
+
+	j = i;
+	while (!h[j].next) {
+		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
+			h[j].next = (m_link_s *)mp->getp(mp);
+			if (h[j].next)
+				h[j].next->next = NULL;
+			break;
+		}
+		++j;
+		s <<= 1;
+	}
+	a = (m_addr_t) h[j].next;
+	if (a) {
+		h[j].next = h[j].next->next;
+		while (j > i) {
+			j -= 1;
+			s >>= 1;
+			h[j].next = (m_link_s *) (a+s);
+			h[j].next->next = NULL;
+		}
+	}
+#ifdef DEBUG
+	printk("___m_alloc(%d) = %p\n", size, (void *) a);
+#endif
+	return (void *) a;
+}
+
+static void ___m_free(m_pool_s *mp, void *ptr, int size)
+{
+	int i = 0;
+	int s = (1 << MEMO_SHIFT);
+	m_link_s *q;
+	m_addr_t a, b;
+	m_link_s *h = mp->h;
+
+#ifdef DEBUG
+	printk("___m_free(%p, %d)\n", ptr, size);
+#endif
+
+	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
+		return;
+
+	while (size > s) {
+		s <<= 1;
+		++i;
+	}
+
+	a = (m_addr_t) ptr;
+
+	while (1) {
+#ifdef MEMO_FREE_UNUSED
+		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
+			mp->freep(mp, a);
+			break;
+		}
+#endif
+		b = a ^ s;
+		q = &h[i];
+		while (q->next && q->next != (m_link_s *) b) {
+			q = q->next;
+		}
+		if (!q->next) {
+			((m_link_s *) a)->next = h[i].next;
+			h[i].next = (m_link_s *) a;
+			break;
+		}
+		q->next = q->next->next;
+		a = a & b;
+		s <<= 1;
+		++i;
+	}
+}
+
+static DEFINE_SPINLOCK(ncr53c8xx_lock);
+
+static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
+{
+	void *p;
+
+	p = ___m_alloc(mp, size);
+
+	if (DEBUG_FLAGS & DEBUG_ALLOC)
+		printk ("new %-10s[%4d] @%p.\n", name, size, p);
+
+	if (p)
+		memset(p, 0, size);
+	else if (uflags & MEMO_WARN)
+		printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
+
+	return p;
+}
+
+#define __m_calloc(mp, s, n)	__m_calloc2(mp, s, n, MEMO_WARN)
+
+static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
+{
+	if (DEBUG_FLAGS & DEBUG_ALLOC)
+		printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
+
+	___m_free(mp, ptr, size);
+
+}
+
+/*
+ * With pci bus iommu support, we use a default pool of unmapped memory 
+ * for memory we donnot need to DMA from/to and one pool per pcidev for 
+ * memory accessed by the PCI chip. `mp0' is the default not DMAable pool.
+ */
+
+static m_addr_t ___mp0_getp(m_pool_s *mp)
+{
+	m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER);
+	if (m)
+		++mp->nump;
+	return m;
+}
+
+static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
+{
+	free_pages(m, MEMO_PAGE_ORDER);
+	--mp->nump;
+}
+
+static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep};
+
+/*
+ * DMAable pools.
+ */
+
+/*
+ * With pci bus iommu support, we maintain one pool per pcidev and a 
+ * hashed reverse table for virtual to bus physical address translations.
+ */
+static m_addr_t ___dma_getp(m_pool_s *mp)
+{
+	m_addr_t vp;
+	m_vtob_s *vbp;
+
+	vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
+	if (vbp) {
+		dma_addr_t daddr;
+		vp = (m_addr_t) dma_alloc_coherent(mp->bush,
+						PAGE_SIZE<<MEMO_PAGE_ORDER,
+						&daddr, GFP_ATOMIC);
+		if (vp) {
+			int hc = VTOB_HASH_CODE(vp);
+			vbp->vaddr = vp;
+			vbp->baddr = daddr;
+			vbp->next = mp->vtob[hc];
+			mp->vtob[hc] = vbp;
+			++mp->nump;
+			return vp;
+		}
+	}
+	if (vbp)
+		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+	return 0;
+}
+
+static void ___dma_freep(m_pool_s *mp, m_addr_t m)
+{
+	m_vtob_s **vbpp, *vbp;
+	int hc = VTOB_HASH_CODE(m);
+
+	vbpp = &mp->vtob[hc];
+	while (*vbpp && (*vbpp)->vaddr != m)
+		vbpp = &(*vbpp)->next;
+	if (*vbpp) {
+		vbp = *vbpp;
+		*vbpp = (*vbpp)->next;
+		dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
+				  (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
+		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
+		--mp->nump;
+	}
+}
+
+static inline m_pool_s *___get_dma_pool(m_bush_t bush)
+{
+	m_pool_s *mp;
+	for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
+	return mp;
+}
+
+static m_pool_s *___cre_dma_pool(m_bush_t bush)
+{
+	m_pool_s *mp;
+	mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
+	if (mp) {
+		memset(mp, 0, sizeof(*mp));
+		mp->bush = bush;
+		mp->getp = ___dma_getp;
+		mp->freep = ___dma_freep;
+		mp->next = mp0.next;
+		mp0.next = mp;
+	}
+	return mp;
+}
+
+static void ___del_dma_pool(m_pool_s *p)
+{
+	struct m_pool **pp = &mp0.next;
+
+	while (*pp && *pp != p)
+		pp = &(*pp)->next;
+	if (*pp) {
+		*pp = (*pp)->next;
+		__m_free(&mp0, p, sizeof(*p), "MPOOL");
+	}
+}
+
+static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
+{
+	u_long flags;
+	struct m_pool *mp;
+	void *m = NULL;
+
+	spin_lock_irqsave(&ncr53c8xx_lock, flags);
+	mp = ___get_dma_pool(bush);
+	if (!mp)
+		mp = ___cre_dma_pool(bush);
+	if (mp)
+		m = __m_calloc(mp, size, name);
+	if (mp && !mp->nump)
+		___del_dma_pool(mp);
+	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+
+	return m;
+}
+
+static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
+{
+	u_long flags;
+	struct m_pool *mp;
+
+	spin_lock_irqsave(&ncr53c8xx_lock, flags);
+	mp = ___get_dma_pool(bush);
+	if (mp)
+		__m_free(mp, m, size, name);
+	if (mp && !mp->nump)
+		___del_dma_pool(mp);
+	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+}
+
+static m_addr_t __vtobus(m_bush_t bush, void *m)
+{
+	u_long flags;
+	m_pool_s *mp;
+	int hc = VTOB_HASH_CODE(m);
+	m_vtob_s *vp = NULL;
+	m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
+
+	spin_lock_irqsave(&ncr53c8xx_lock, flags);
+	mp = ___get_dma_pool(bush);
+	if (mp) {
+		vp = mp->vtob[hc];
+		while (vp && (m_addr_t) vp->vaddr != a)
+			vp = vp->next;
+	}
+	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
+	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
+}
+
+#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->dev, s, n)
+#define _m_free_dma(np, p, s, n)	__m_free_dma(np->dev, p, s, n)
+#define m_calloc_dma(s, n)		_m_calloc_dma(np, s, n)
+#define m_free_dma(p, s, n)		_m_free_dma(np, p, s, n)
+#define _vtobus(np, p)			__vtobus(np->dev, p)
+#define vtobus(p)			_vtobus(np, p)
+
+/*
+ *  Deal with DMA mapping/unmapping.
+ */
+
+/* To keep track of the dma mapping (sg/single) that has been set */
+#define __data_mapped	SCp.phase
+#define __data_mapping	SCp.have_data_in
+
+static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
+{
+	switch(cmd->__data_mapped) {
+	case 2:
+		dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
+				cmd->sc_data_direction);
+		break;
+	case 1:
+		dma_unmap_single(dev, cmd->__data_mapping,
+				 cmd->request_bufflen,
+				 cmd->sc_data_direction);
+		break;
+	}
+	cmd->__data_mapped = 0;
+}
+
+static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd)
+{
+	dma_addr_t mapping;
+
+	if (cmd->request_bufflen == 0)
+		return 0;
+
+	mapping = dma_map_single(dev, cmd->request_buffer,
+				 cmd->request_bufflen,
+				 cmd->sc_data_direction);
+	cmd->__data_mapped = 1;
+	cmd->__data_mapping = mapping;
+
+	return mapping;
+}
+
+static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
+{
+	int use_sg;
+
+	if (cmd->use_sg == 0)
+		return 0;
+
+	use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
+			cmd->sc_data_direction);
+	cmd->__data_mapped = 2;
+	cmd->__data_mapping = use_sg;
+
+	return use_sg;
+}
+
+#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->dev, cmd)
+#define map_scsi_single_data(np, cmd)	__map_scsi_single_data(np->dev, cmd)
+#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->dev, cmd)
+
+/*==========================================================
+**
+**	Driver setup.
+**
+**	This structure is initialized from linux config 
+**	options. It can be overridden at boot-up by the boot 
+**	command line.
+**
+**==========================================================
+*/
+static struct ncr_driver_setup
+	driver_setup			= SCSI_NCR_DRIVER_SETUP;
+
+#ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+static struct ncr_driver_setup
+	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;
+#endif
+
+#define initverbose (driver_setup.verbose)
+#define bootverbose (np->verbose)
+
+
+/*===================================================================
+**
+**	Driver setup from the boot command line
+**
+**===================================================================
+*/
+
+#ifdef MODULE
+#define	ARG_SEP	' '
+#else
+#define	ARG_SEP	','
+#endif
+
+#define OPT_TAGS		1
+#define OPT_MASTER_PARITY	2
+#define OPT_SCSI_PARITY		3
+#define OPT_DISCONNECTION	4
+#define OPT_SPECIAL_FEATURES	5
+#define OPT_UNUSED_1		6
+#define OPT_FORCE_SYNC_NEGO	7
+#define OPT_REVERSE_PROBE	8
+#define OPT_DEFAULT_SYNC	9
+#define OPT_VERBOSE		10
+#define OPT_DEBUG		11
+#define OPT_BURST_MAX		12
+#define OPT_LED_PIN		13
+#define OPT_MAX_WIDE		14
+#define OPT_SETTLE_DELAY	15
+#define OPT_DIFF_SUPPORT	16
+#define OPT_IRQM		17
+#define OPT_PCI_FIX_UP		18
+#define OPT_BUS_CHECK		19
+#define OPT_OPTIMIZE		20
+#define OPT_RECOVERY		21
+#define OPT_SAFE_SETUP		22
+#define OPT_USE_NVRAM		23
+#define OPT_EXCLUDE		24
+#define OPT_HOST_ID		25
+
+#ifdef SCSI_NCR_IARB_SUPPORT
+#define OPT_IARB		26
+#endif
+
+static char setup_token[] __initdata = 
+	"tags:"   "mpar:"
+	"spar:"   "disc:"
+	"specf:"  "ultra:"
+	"fsn:"    "revprob:"
+	"sync:"   "verb:"
+	"debug:"  "burst:"
+	"led:"    "wide:"
+	"settle:" "diff:"
+	"irqm:"   "pcifix:"
+	"buschk:" "optim:"
+	"recovery:"
+	"safe:"   "nvram:"
+	"excl:"   "hostid:"
+#ifdef SCSI_NCR_IARB_SUPPORT
+	"iarb:"
+#endif
+	;	/* DONNOT REMOVE THIS ';' */
+
+#ifdef MODULE
+#define	ARG_SEP	' '
+#else
+#define	ARG_SEP	','
+#endif
+
+static int __init get_setup_token(char *p)
+{
+	char *cur = setup_token;
+	char *pc;
+	int i = 0;
+
+	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+		++pc;
+		++i;
+		if (!strncmp(p, cur, pc - cur))
+			return i;
+		cur = pc;
+	}
+	return 0;
+}
+
+
+static int __init sym53c8xx__setup(char *str)
+{
+#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+	char *cur = str;
+	char *pc, *pv;
+	int i, val, c;
+	int xi = 0;
+
+	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
+		char *pe;
+
+		val = 0;
+		pv = pc;
+		c = *++pv;
+
+		if	(c == 'n')
+			val = 0;
+		else if	(c == 'y')
+			val = 1;
+		else
+			val = (int) simple_strtoul(pv, &pe, 0);
+
+		switch (get_setup_token(cur)) {
+		case OPT_TAGS:
+			driver_setup.default_tags = val;
+			if (pe && *pe == '/') {
+				i = 0;
+				while (*pe && *pe != ARG_SEP && 
+					i < sizeof(driver_setup.tag_ctrl)-1) {
+					driver_setup.tag_ctrl[i++] = *pe++;
+				}
+				driver_setup.tag_ctrl[i] = '\0';
+			}
+			break;
+		case OPT_MASTER_PARITY:
+			driver_setup.master_parity = val;
+			break;
+		case OPT_SCSI_PARITY:
+			driver_setup.scsi_parity = val;
+			break;
+		case OPT_DISCONNECTION:
+			driver_setup.disconnection = val;
+			break;
+		case OPT_SPECIAL_FEATURES:
+			driver_setup.special_features = val;
+			break;
+		case OPT_FORCE_SYNC_NEGO:
+			driver_setup.force_sync_nego = val;
+			break;
+		case OPT_REVERSE_PROBE:
+			driver_setup.reverse_probe = val;
+			break;
+		case OPT_DEFAULT_SYNC:
+			driver_setup.default_sync = val;
+			break;
+		case OPT_VERBOSE:
+			driver_setup.verbose = val;
+			break;
+		case OPT_DEBUG:
+			driver_setup.debug = val;
+			break;
+		case OPT_BURST_MAX:
+			driver_setup.burst_max = val;
+			break;
+		case OPT_LED_PIN:
+			driver_setup.led_pin = val;
+			break;
+		case OPT_MAX_WIDE:
+			driver_setup.max_wide = val? 1:0;
+			break;
+		case OPT_SETTLE_DELAY:
+			driver_setup.settle_delay = val;
+			break;
+		case OPT_DIFF_SUPPORT:
+			driver_setup.diff_support = val;
+			break;
+		case OPT_IRQM:
+			driver_setup.irqm = val;
+			break;
+		case OPT_PCI_FIX_UP:
+			driver_setup.pci_fix_up	= val;
+			break;
+		case OPT_BUS_CHECK:
+			driver_setup.bus_check = val;
+			break;
+		case OPT_OPTIMIZE:
+			driver_setup.optimize = val;
+			break;
+		case OPT_RECOVERY:
+			driver_setup.recovery = val;
+			break;
+		case OPT_USE_NVRAM:
+			driver_setup.use_nvram = val;
+			break;
+		case OPT_SAFE_SETUP:
+			memcpy(&driver_setup, &driver_safe_setup,
+				sizeof(driver_setup));
+			break;
+		case OPT_EXCLUDE:
+			if (xi < SCSI_NCR_MAX_EXCLUDES)
+				driver_setup.excludes[xi++] = val;
+			break;
+		case OPT_HOST_ID:
+			driver_setup.host_id = val;
+			break;
+#ifdef SCSI_NCR_IARB_SUPPORT
+		case OPT_IARB:
+			driver_setup.iarb = val;
+			break;
+#endif
+		default:
+			printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
+			break;
+		}
+
+		if ((cur = strchr(cur, ARG_SEP)) != NULL)
+			++cur;
+	}
+#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
+	return 1;
+}
+
+/*===================================================================
+**
+**	Get device queue depth from boot command line.
+**
+**===================================================================
+*/
+#define DEF_DEPTH	(driver_setup.default_tags)
+#define ALL_TARGETS	-2
+#define NO_TARGET	-1
+#define ALL_LUNS	-2
+#define NO_LUN		-1
+
+static int device_queue_depth(int unit, int target, int lun)
+{
+	int c, h, t, u, v;
+	char *p = driver_setup.tag_ctrl;
+	char *ep;
+
+	h = -1;
+	t = NO_TARGET;
+	u = NO_LUN;
+	while ((c = *p++) != 0) {
+		v = simple_strtoul(p, &ep, 0);
+		switch(c) {
+		case '/':
+			++h;
+			t = ALL_TARGETS;
+			u = ALL_LUNS;
+			break;
+		case 't':
+			if (t != target)
+				t = (target == v) ? v : NO_TARGET;
+			u = ALL_LUNS;
+			break;
+		case 'u':
+			if (u != lun)
+				u = (lun == v) ? v : NO_LUN;
+			break;
+		case 'q':
+			if (h == unit &&
+				(t == ALL_TARGETS || t == target) &&
+				(u == ALL_LUNS    || u == lun))
+				return v;
+			break;
+		case '-':
+			t = ALL_TARGETS;
+			u = ALL_LUNS;
+			break;
+		default:
+			break;
+		}
+		p = ep;
+	}
+	return DEF_DEPTH;
+}
 
 
 /*==========================================================
@@ -2971,21 +3703,10 @@
 
 static void ncr_print_msg(struct ccb *cp, char *label, u_char *msg)
 {
-	int i;
 	PRINT_ADDR(cp->cmd, "%s: ", label);
 
-	printk ("%x",*msg);
-	if (*msg == M_EXTENDED) {
-		for (i = 1; i < 8; i++) {
-			if (i - 1 > msg[1])
-				break;
-			printk ("-%x",msg[i]);
-		}
-	} else if ((*msg & 0xf0) == 0x20) {
-		printk ("-%x",msg[1]);
-	}
-
-	printk(".\n");
+	spi_print_msg(msg);
+	printk("\n");
 }
 
 /*==========================================================
diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h
index 05c7b83..6a7bef2 100644
--- a/drivers/scsi/ncr53c8xx.h
+++ b/drivers/scsi/ncr53c8xx.h
@@ -2,6 +2,7 @@
 **  Device driver for the PCI-SCSI NCR538XX controller family.
 **
 **  Copyright (C) 1994  Wolfgang Stanglmeier
+**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
 **
 **  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
@@ -36,15 +37,1275 @@
 **  And has been ported to NetBSD by
 **          Charles M. Hannum           <mycroft@gnu.ai.mit.edu>
 **
+**  NVRAM detection and reading.
+**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
+**
+**  Added support for MIPS big endian systems.
+**    Carsten Langgaard, carstenl@mips.com
+**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+**
+**  Added support for HP PARISC big endian systems.
+**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+**
 *******************************************************************************
 */
 
 #ifndef NCR53C8XX_H
 #define NCR53C8XX_H
 
+#include <linux/config.h>
 #include <scsi/scsi_host.h>
 
-#include "sym53c8xx_defs.h"
+/*
+**	If you want a driver as small as possible, do not define the 
+**	following options.
+*/
+#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
+#define SCSI_NCR_DEBUG_INFO_SUPPORT
+
+/*
+**	To disable integrity checking, do not define the 
+**	following option.
+*/
+#ifdef	CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK
+#	define SCSI_NCR_ENABLE_INTEGRITY_CHECK
+#endif
+
+/* ---------------------------------------------------------------------
+** Take into account kernel configured parameters.
+** Most of these options can be overridden at startup by a command line.
+** ---------------------------------------------------------------------
+*/
+
+/*
+ * For Ultra2 and Ultra3 SCSI support option, use special features. 
+ *
+ * Value (default) means:
+ *	bit 0 : all features enabled, except:
+ *		bit 1 : PCI Write And Invalidate.
+ *		bit 2 : Data Phase Mismatch handling from SCRIPTS.
+ *
+ * Use boot options ncr53c8xx=specf:1 if you want all chip features to be 
+ * enabled by the driver.
+ */
+#define	SCSI_NCR_SETUP_SPECIAL_FEATURES		(3)
+
+#define SCSI_NCR_MAX_SYNC			(80)
+
+/*
+ * Allow tags from 2 to 256, default 8
+ */
+#ifdef	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
+#if	CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2
+#define SCSI_NCR_MAX_TAGS	(2)
+#elif	CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256
+#define SCSI_NCR_MAX_TAGS	(256)
+#else
+#define	SCSI_NCR_MAX_TAGS	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
+#endif
+#else
+#define SCSI_NCR_MAX_TAGS	(8)
+#endif
+
+/*
+ * Allow tagged command queuing support if configured with default number 
+ * of tags set to max (see above).
+ */
+#ifdef	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
+#define	SCSI_NCR_SETUP_DEFAULT_TAGS	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
+#elif	defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
+#define	SCSI_NCR_SETUP_DEFAULT_TAGS	SCSI_NCR_MAX_TAGS
+#else
+#define	SCSI_NCR_SETUP_DEFAULT_TAGS	(0)
+#endif
+
+/*
+ * Immediate arbitration
+ */
+#if defined(CONFIG_SCSI_NCR53C8XX_IARB)
+#define SCSI_NCR_IARB_SUPPORT
+#endif
+
+/*
+ * Sync transfer frequency at startup.
+ * Allow from 5Mhz to 80Mhz default 20 Mhz.
+ */
+#ifndef	CONFIG_SCSI_NCR53C8XX_SYNC
+#define	CONFIG_SCSI_NCR53C8XX_SYNC	(20)
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC
+#undef	CONFIG_SCSI_NCR53C8XX_SYNC
+#define	CONFIG_SCSI_NCR53C8XX_SYNC	SCSI_NCR_MAX_SYNC
+#endif
+
+#if	CONFIG_SCSI_NCR53C8XX_SYNC == 0
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(255)
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 5
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(50)
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 20
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(250/(CONFIG_SCSI_NCR53C8XX_SYNC))
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 33
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(11)
+#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 40
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(10)
+#else
+#define	SCSI_NCR_SETUP_DEFAULT_SYNC 	(9)
+#endif
+
+/*
+ * Disallow disconnections at boot-up
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
+#define SCSI_NCR_SETUP_DISCONNECTION	(0)
+#else
+#define SCSI_NCR_SETUP_DISCONNECTION	(1)
+#endif
+
+/*
+ * Force synchronous negotiation for all targets
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
+#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(1)
+#else
+#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(0)
+#endif
+
+/*
+ * Disable master parity checking (flawed hardwares need that)
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
+#define SCSI_NCR_SETUP_MASTER_PARITY	(0)
+#else
+#define SCSI_NCR_SETUP_MASTER_PARITY	(1)
+#endif
+
+/*
+ * Disable scsi parity checking (flawed devices may need that)
+ */
+#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
+#define SCSI_NCR_SETUP_SCSI_PARITY	(0)
+#else
+#define SCSI_NCR_SETUP_SCSI_PARITY	(1)
+#endif
+
+/*
+ * Settle time after reset at boot-up
+ */
+#define SCSI_NCR_SETUP_SETTLE_TIME	(2)
+
+/*
+**	Bridge quirks work-around option defaulted to 1.
+*/
+#ifndef	SCSI_NCR_PCIQ_WORK_AROUND_OPT
+#define	SCSI_NCR_PCIQ_WORK_AROUND_OPT	1
+#endif
+
+/*
+**	Work-around common bridge misbehaviour.
+**
+**	- Do not flush posted writes in the opposite 
+**	  direction on read.
+**	- May reorder DMA writes to memory.
+**
+**	This option should not affect performances 
+**	significantly, so it is the default.
+*/
+#if	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1
+#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
+#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
+#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
+
+/*
+**	Same as option 1, but also deal with 
+**	misconfigured interrupts.
+**
+**	- Edge triggerred instead of level sensitive.
+**	- No interrupt line connected.
+**	- IRQ number misconfigured.
+**	
+**	If no interrupt is delivered, the driver will 
+**	catch the interrupt conditions 10 times per 
+**	second. No need to say that this option is 
+**	not recommended.
+*/
+#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2
+#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
+#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
+#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
+#define	SCSI_NCR_PCIQ_BROKEN_INTR
+
+/*
+**	Some bridge designers decided to flush 
+**	everything prior to deliver the interrupt.
+**	This option tries to deal with such a 
+**	behaviour.
+*/
+#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3
+#define	SCSI_NCR_PCIQ_SYNC_ON_INTR
+#endif
+
+/*
+**	Other parameters not configurable with "make config"
+**	Avoid to change these constants, unless you know what you are doing.
+*/
+
+#define SCSI_NCR_ALWAYS_SIMPLE_TAG
+#define SCSI_NCR_MAX_SCATTER	(127)
+#define SCSI_NCR_MAX_TARGET	(16)
+
+/*
+**   Compute some desirable value for CAN_QUEUE 
+**   and CMD_PER_LUN.
+**   The driver will use lower values if these 
+**   ones appear to be too large.
+*/
+#define SCSI_NCR_CAN_QUEUE	(8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET)
+#define SCSI_NCR_CMD_PER_LUN	(SCSI_NCR_MAX_TAGS)
+
+#define SCSI_NCR_SG_TABLESIZE	(SCSI_NCR_MAX_SCATTER)
+#define SCSI_NCR_TIMER_INTERVAL	(HZ)
+
+#if 1 /* defined CONFIG_SCSI_MULTI_LUN */
+#define SCSI_NCR_MAX_LUN	(16)
+#else
+#define SCSI_NCR_MAX_LUN	(1)
+#endif
+
+/*
+ *  IO functions definition for big/little endian CPU support.
+ *  For now, the NCR is only supported in little endian addressing mode, 
+ */
+
+#ifdef	__BIG_ENDIAN
+
+#define	inw_l2b		inw
+#define	inl_l2b		inl
+#define	outw_b2l	outw
+#define	outl_b2l	outl
+
+#define	readb_raw	readb
+#define	writeb_raw	writeb
+
+#if defined(SCSI_NCR_BIG_ENDIAN)
+#define	readw_l2b	__raw_readw
+#define	readl_l2b	__raw_readl
+#define	writew_b2l	__raw_writew
+#define	writel_b2l	__raw_writel
+#define	readw_raw	__raw_readw
+#define	readl_raw	__raw_readl
+#define	writew_raw	__raw_writew
+#define	writel_raw	__raw_writel
+#else	/* Other big-endian */
+#define	readw_l2b	readw
+#define	readl_l2b	readl
+#define	writew_b2l	writew
+#define	writel_b2l	writel
+#define	readw_raw	readw
+#define	readl_raw	readl
+#define	writew_raw	writew
+#define	writel_raw	writel
+#endif
+
+#else	/* little endian */
+
+#define	inw_raw		inw
+#define	inl_raw		inl
+#define	outw_raw	outw
+#define	outl_raw	outl
+
+#define	readb_raw	readb
+#define	readw_raw	readw
+#define	readl_raw	readl
+#define	writeb_raw	writeb
+#define	writew_raw	writew
+#define	writel_raw	writel
+
+#endif
+
+#if !defined(__hppa__) && !defined(__mips__)
+#ifdef	SCSI_NCR_BIG_ENDIAN
+#error	"The NCR in BIG ENDIAN addressing mode is not (yet) supported"
+#endif
+#endif
+
+#define MEMORY_BARRIER()	mb()
+
+
+/*
+ *  If the NCR uses big endian addressing mode over the 
+ *  PCI, actual io register addresses for byte and word 
+ *  accesses must be changed according to lane routing.
+ *  Btw, ncr_offb() and ncr_offw() macros only apply to 
+ *  constants and so donnot generate bloated code.
+ */
+
+#if	defined(SCSI_NCR_BIG_ENDIAN)
+
+#define ncr_offb(o)	(((o)&~3)+((~((o)&3))&3))
+#define ncr_offw(o)	(((o)&~3)+((~((o)&3))&2))
+
+#else
+
+#define ncr_offb(o)	(o)
+#define ncr_offw(o)	(o)
+
+#endif
+
+/*
+ *  If the CPU and the NCR use same endian-ness addressing,
+ *  no byte reordering is needed for script patching.
+ *  Macro cpu_to_scr() is to be used for script patching.
+ *  Macro scr_to_cpu() is to be used for getting a DWORD 
+ *  from the script.
+ */
+
+#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+
+#define cpu_to_scr(dw)	cpu_to_le32(dw)
+#define scr_to_cpu(dw)	le32_to_cpu(dw)
+
+#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+
+#define cpu_to_scr(dw)	cpu_to_be32(dw)
+#define scr_to_cpu(dw)	be32_to_cpu(dw)
+
+#else
+
+#define cpu_to_scr(dw)	(dw)
+#define scr_to_cpu(dw)	(dw)
+
+#endif
+
+/*
+ *  Access to the controller chip.
+ *
+ *  If the CPU and the NCR use same endian-ness addressing,
+ *  no byte reordering is needed for accessing chip io 
+ *  registers. Functions suffixed by '_raw' are assumed 
+ *  to access the chip over the PCI without doing byte 
+ *  reordering. Functions suffixed by '_l2b' are 
+ *  assumed to perform little-endian to big-endian byte 
+ *  reordering, those suffixed by '_b2l' blah, blah,
+ *  blah, ...
+ */
+
+/*
+ *  MEMORY mapped IO input / output
+ */
+
+#define INB_OFF(o)		readb_raw((char __iomem *)np->reg + ncr_offb(o))
+#define OUTB_OFF(o, val)	writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o))
+
+#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o)		readw_l2b((char __iomem *)np->reg + ncr_offw(o))
+#define INL_OFF(o)		readl_l2b((char __iomem *)np->reg + (o))
+
+#define OUTW_OFF(o, val)	writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o))
+#define OUTL_OFF(o, val)	writel_b2l((val), (char __iomem *)np->reg + (o))
+
+#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
+
+#define INW_OFF(o)		readw_b2l((char __iomem *)np->reg + ncr_offw(o))
+#define INL_OFF(o)		readl_b2l((char __iomem *)np->reg + (o))
+
+#define OUTW_OFF(o, val)	writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o))
+#define OUTL_OFF(o, val)	writel_l2b((val), (char __iomem *)np->reg + (o))
+
+#else
+
+#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
+/* Only 8 or 32 bit transfers allowed */
+#define INW_OFF(o)		(readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1))
+#else
+#define INW_OFF(o)		readw_raw((char __iomem *)np->reg + ncr_offw(o))
+#endif
+#define INL_OFF(o)		readl_raw((char __iomem *)np->reg + (o))
+
+#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
+/* Only 8 or 32 bit transfers allowed */
+#define OUTW_OFF(o, val)	do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0)
+#else
+#define OUTW_OFF(o, val)	writew_raw((val), (char __iomem *)np->reg + ncr_offw(o))
+#endif
+#define OUTL_OFF(o, val)	writel_raw((val), (char __iomem *)np->reg + (o))
+
+#endif
+
+#define INB(r)		INB_OFF (offsetof(struct ncr_reg,r))
+#define INW(r)		INW_OFF (offsetof(struct ncr_reg,r))
+#define INL(r)		INL_OFF (offsetof(struct ncr_reg,r))
+
+#define OUTB(r, val)	OUTB_OFF (offsetof(struct ncr_reg,r), (val))
+#define OUTW(r, val)	OUTW_OFF (offsetof(struct ncr_reg,r), (val))
+#define OUTL(r, val)	OUTL_OFF (offsetof(struct ncr_reg,r), (val))
+
+/*
+ *  Set bit field ON, OFF 
+ */
+
+#define OUTONB(r, m)	OUTB(r, INB(r) | (m))
+#define OUTOFFB(r, m)	OUTB(r, INB(r) & ~(m))
+#define OUTONW(r, m)	OUTW(r, INW(r) | (m))
+#define OUTOFFW(r, m)	OUTW(r, INW(r) & ~(m))
+#define OUTONL(r, m)	OUTL(r, INL(r) | (m))
+#define OUTOFFL(r, m)	OUTL(r, INL(r) & ~(m))
+
+/*
+ *  We normally want the chip to have a consistent view
+ *  of driver internal data structures when we restart it.
+ *  Thus these macros.
+ */
+#define OUTL_DSP(v)				\
+	do {					\
+		MEMORY_BARRIER();		\
+		OUTL (nc_dsp, (v));		\
+	} while (0)
+
+#define OUTONB_STD()				\
+	do {					\
+		MEMORY_BARRIER();		\
+		OUTONB (nc_dcntl, (STD|NOCOM));	\
+	} while (0)
+
+
+/*
+**   NCR53C8XX devices features table.
+*/
+struct ncr_chip {
+	unsigned short	revision_id;
+	unsigned char	burst_max;	/* log-base-2 of max burst */
+	unsigned char	offset_max;
+	unsigned char	nr_divisor;
+	unsigned int	features;
+#define FE_LED0		(1<<0)
+#define FE_WIDE		(1<<1)    /* Wide data transfers */
+#define FE_ULTRA	(1<<2)	  /* Ultra speed 20Mtrans/sec */
+#define FE_DBLR		(1<<4)	  /* Clock doubler present */
+#define FE_QUAD		(1<<5)	  /* Clock quadrupler present */
+#define FE_ERL		(1<<6)    /* Enable read line */
+#define FE_CLSE		(1<<7)    /* Cache line size enable */
+#define FE_WRIE		(1<<8)    /* Write & Invalidate enable */
+#define FE_ERMP		(1<<9)    /* Enable read multiple */
+#define FE_BOF		(1<<10)   /* Burst opcode fetch */
+#define FE_DFS		(1<<11)   /* DMA fifo size */
+#define FE_PFEN		(1<<12)   /* Prefetch enable */
+#define FE_LDSTR	(1<<13)   /* Load/Store supported */
+#define FE_RAM		(1<<14)   /* On chip RAM present */
+#define FE_VARCLK	(1<<15)   /* SCSI clock may vary */
+#define FE_RAM8K	(1<<16)   /* On chip RAM sized 8Kb */
+#define FE_64BIT	(1<<17)   /* Have a 64-bit PCI interface */
+#define FE_IO256	(1<<18)   /* Requires full 256 bytes in PCI space */
+#define FE_NOPM		(1<<19)   /* Scripts handles phase mismatch */
+#define FE_LEDC		(1<<20)   /* Hardware control of LED */
+#define FE_DIFF		(1<<21)   /* Support Differential SCSI */
+#define FE_66MHZ 	(1<<23)   /* 66MHz PCI Support */
+#define FE_DAC	 	(1<<24)   /* Support DAC cycles (64 bit addressing) */
+#define FE_ISTAT1 	(1<<25)   /* Have ISTAT1, MBOX0, MBOX1 registers */
+#define FE_DAC_IN_USE	(1<<26)	  /* Platform does DAC cycles */
+#define FE_EHP		(1<<27)   /* 720: Even host parity */
+#define FE_MUX		(1<<28)   /* 720: Multiplexed bus */
+#define FE_EA		(1<<29)   /* 720: Enable Ack */
+
+#define FE_CACHE_SET	(FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
+#define FE_SCSI_SET	(FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80)
+#define FE_SPECIAL_SET	(FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM)
+};
+
+
+/*
+**	Driver setup structure.
+**
+**	This structure is initialized from linux config options.
+**	It can be overridden at boot-up by the boot command line.
+*/
+#define SCSI_NCR_MAX_EXCLUDES 8
+struct ncr_driver_setup {
+	u8	master_parity;
+	u8	scsi_parity;
+	u8	disconnection;
+	u8	special_features;
+	u8	force_sync_nego;
+	u8	reverse_probe;
+	u8	pci_fix_up;
+	u8	use_nvram;
+	u8	verbose;
+	u8	default_tags;
+	u16	default_sync;
+	u16	debug;
+	u8	burst_max;
+	u8	led_pin;
+	u8	max_wide;
+	u8	settle_delay;
+	u8	diff_support;
+	u8	irqm;
+	u8	bus_check;
+	u8	optimize;
+	u8	recovery;
+	u8	host_id;
+	u16	iarb;
+	u32	excludes[SCSI_NCR_MAX_EXCLUDES];
+	char	tag_ctrl[100];
+};
+
+/*
+**	Initial setup.
+**	Can be overriden at startup by a command line.
+*/
+#define SCSI_NCR_DRIVER_SETUP			\
+{						\
+	SCSI_NCR_SETUP_MASTER_PARITY,		\
+	SCSI_NCR_SETUP_SCSI_PARITY,		\
+	SCSI_NCR_SETUP_DISCONNECTION,		\
+	SCSI_NCR_SETUP_SPECIAL_FEATURES,	\
+	SCSI_NCR_SETUP_FORCE_SYNC_NEGO,		\
+	0,					\
+	0,					\
+	1,					\
+	0,					\
+	SCSI_NCR_SETUP_DEFAULT_TAGS,		\
+	SCSI_NCR_SETUP_DEFAULT_SYNC,		\
+	0x00,					\
+	7,					\
+	0,					\
+	1,					\
+	SCSI_NCR_SETUP_SETTLE_TIME,		\
+	0,					\
+	0,					\
+	1,					\
+	0,					\
+	0,					\
+	255,					\
+	0x00					\
+}
+
+/*
+**	Boot fail safe setup.
+**	Override initial setup from boot command line:
+**	ncr53c8xx=safe:y
+*/
+#define SCSI_NCR_DRIVER_SAFE_SETUP		\
+{						\
+	0,					\
+	1,					\
+	0,					\
+	0,					\
+	0,					\
+	0,					\
+	0,					\
+	1,					\
+	2,					\
+	0,					\
+	255,					\
+	0x00,					\
+	255,					\
+	0,					\
+	0,					\
+	10,					\
+	1,					\
+	1,					\
+	1,					\
+	0,					\
+	0,					\
+	255					\
+}
+
+/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/
+
+/*-----------------------------------------------------------------
+**
+**	The ncr 53c810 register structure.
+**
+**-----------------------------------------------------------------
+*/
+
+struct ncr_reg {
+/*00*/  u8	nc_scntl0;    /* full arb., ena parity, par->ATN  */
+
+/*01*/  u8	nc_scntl1;    /* no reset                         */
+        #define   ISCON   0x10  /* connected to scsi		    */
+        #define   CRST    0x08  /* force reset                      */
+        #define   IARB    0x02  /* immediate arbitration            */
+
+/*02*/  u8	nc_scntl2;    /* no disconnect expected           */
+	#define   SDU     0x80  /* cmd: disconnect will raise error */
+	#define   CHM     0x40  /* sta: chained mode                */
+	#define   WSS     0x08  /* sta: wide scsi send           [W]*/
+	#define   WSR     0x01  /* sta: wide scsi received       [W]*/
+
+/*03*/  u8	nc_scntl3;    /* cnf system clock dependent       */
+	#define   EWS     0x08  /* cmd: enable wide scsi         [W]*/
+	#define   ULTRA   0x80  /* cmd: ULTRA enable                */
+				/* bits 0-2, 7 rsvd for C1010       */
+
+/*04*/  u8	nc_scid;	/* cnf host adapter scsi address    */
+	#define   RRE     0x40  /* r/w:e enable response to resel.  */
+	#define   SRE     0x20  /* r/w:e enable response to select  */
+
+/*05*/  u8	nc_sxfer;	/* ### Sync speed and count         */
+				/* bits 6-7 rsvd for C1010          */
+
+/*06*/  u8	nc_sdid;	/* ### Destination-ID               */
+
+/*07*/  u8	nc_gpreg;	/* ??? IO-Pins                      */
+
+/*08*/  u8	nc_sfbr;	/* ### First byte in phase          */
+
+/*09*/  u8	nc_socl;
+	#define   CREQ	  0x80	/* r/w: SCSI-REQ                    */
+	#define   CACK	  0x40	/* r/w: SCSI-ACK                    */
+	#define   CBSY	  0x20	/* r/w: SCSI-BSY                    */
+	#define   CSEL	  0x10	/* r/w: SCSI-SEL                    */
+	#define   CATN	  0x08	/* r/w: SCSI-ATN                    */
+	#define   CMSG	  0x04	/* r/w: SCSI-MSG                    */
+	#define   CC_D	  0x02	/* r/w: SCSI-C_D                    */
+	#define   CI_O	  0x01	/* r/w: SCSI-I_O                    */
+
+/*0a*/  u8	nc_ssid;
+
+/*0b*/  u8	nc_sbcl;
+
+/*0c*/  u8	nc_dstat;
+        #define   DFE     0x80  /* sta: dma fifo empty              */
+        #define   MDPE    0x40  /* int: master data parity error    */
+        #define   BF      0x20  /* int: script: bus fault           */
+        #define   ABRT    0x10  /* int: script: command aborted     */
+        #define   SSI     0x08  /* int: script: single step         */
+        #define   SIR     0x04  /* int: script: interrupt instruct. */
+        #define   IID     0x01  /* int: script: illegal instruct.   */
+
+/*0d*/  u8	nc_sstat0;
+        #define   ILF     0x80  /* sta: data in SIDL register lsb   */
+        #define   ORF     0x40  /* sta: data in SODR register lsb   */
+        #define   OLF     0x20  /* sta: data in SODL register lsb   */
+        #define   AIP     0x10  /* sta: arbitration in progress     */
+        #define   LOA     0x08  /* sta: arbitration lost            */
+        #define   WOA     0x04  /* sta: arbitration won             */
+        #define   IRST    0x02  /* sta: scsi reset signal           */
+        #define   SDP     0x01  /* sta: scsi parity signal          */
+
+/*0e*/  u8	nc_sstat1;
+	#define   FF3210  0xf0	/* sta: bytes in the scsi fifo      */
+
+/*0f*/  u8	nc_sstat2;
+        #define   ILF1    0x80  /* sta: data in SIDL register msb[W]*/
+        #define   ORF1    0x40  /* sta: data in SODR register msb[W]*/
+        #define   OLF1    0x20  /* sta: data in SODL register msb[W]*/
+        #define   DM      0x04  /* sta: DIFFSENS mismatch (895/6 only) */
+        #define   LDSC    0x02  /* sta: disconnect & reconnect      */
+
+/*10*/  u8	nc_dsa;	/* --> Base page                    */
+/*11*/  u8	nc_dsa1;
+/*12*/  u8	nc_dsa2;
+/*13*/  u8	nc_dsa3;
+
+/*14*/  u8	nc_istat;	/* --> Main Command and status      */
+        #define   CABRT   0x80  /* cmd: abort current operation     */
+        #define   SRST    0x40  /* mod: reset chip                  */
+        #define   SIGP    0x20  /* r/w: message from host to ncr    */
+        #define   SEM     0x10  /* r/w: message between host + ncr  */
+        #define   CON     0x08  /* sta: connected to scsi           */
+        #define   INTF    0x04  /* sta: int on the fly (reset by wr)*/
+        #define   SIP     0x02  /* sta: scsi-interrupt              */
+        #define   DIP     0x01  /* sta: host/script interrupt       */
+
+/*15*/  u8	nc_istat1;	/* 896 and later cores only */
+        #define   FLSH    0x04  /* sta: chip is flushing            */
+        #define   SRUN    0x02  /* sta: scripts are running         */
+        #define   SIRQD   0x01  /* r/w: disable INT pin             */
+
+/*16*/  u8	nc_mbox0;	/* 896 and later cores only */
+/*17*/  u8	nc_mbox1;	/* 896 and later cores only */
+
+/*18*/	u8	nc_ctest0;
+	#define   EHP     0x04	/* 720 even host parity             */
+/*19*/  u8	nc_ctest1;
+
+/*1a*/  u8	nc_ctest2;
+	#define   CSIGP   0x40
+				/* bits 0-2,7 rsvd for C1010        */
+
+/*1b*/  u8	nc_ctest3;
+	#define   FLF     0x08  /* cmd: flush dma fifo              */
+	#define   CLF	  0x04	/* cmd: clear dma fifo		    */
+	#define   FM      0x02  /* mod: fetch pin mode              */
+	#define   WRIE    0x01  /* mod: write and invalidate enable */
+				/* bits 4-7 rsvd for C1010          */
+
+/*1c*/  u32    nc_temp;	/* ### Temporary stack              */
+
+/*20*/	u8	nc_dfifo;
+/*21*/  u8	nc_ctest4;
+	#define   MUX     0x80  /* 720 host bus multiplex mode      */
+	#define   BDIS    0x80  /* mod: burst disable               */
+	#define   MPEE    0x08  /* mod: master parity error enable  */
+
+/*22*/  u8	nc_ctest5;
+	#define   DFS     0x20  /* mod: dma fifo size               */
+				/* bits 0-1, 3-7 rsvd for C1010          */
+/*23*/  u8	nc_ctest6;
+
+/*24*/  u32    nc_dbc;	/* ### Byte count and command       */
+/*28*/  u32    nc_dnad;	/* ### Next command register        */
+/*2c*/  u32    nc_dsp;	/* --> Script Pointer               */
+/*30*/  u32    nc_dsps;	/* --> Script pointer save/opcode#2 */
+
+/*34*/  u8	nc_scratcha;  /* Temporary register a            */
+/*35*/  u8	nc_scratcha1;
+/*36*/  u8	nc_scratcha2;
+/*37*/  u8	nc_scratcha3;
+
+/*38*/  u8	nc_dmode;
+	#define   BL_2    0x80  /* mod: burst length shift value +2 */
+	#define   BL_1    0x40  /* mod: burst length shift value +1 */
+	#define   ERL     0x08  /* mod: enable read line            */
+	#define   ERMP    0x04  /* mod: enable read multiple        */
+	#define   BOF     0x02  /* mod: burst op code fetch         */
+
+/*39*/  u8	nc_dien;
+/*3a*/  u8	nc_sbr;
+
+/*3b*/  u8	nc_dcntl;	/* --> Script execution control     */
+	#define   CLSE    0x80  /* mod: cache line size enable      */
+	#define   PFF     0x40  /* cmd: pre-fetch flush             */
+	#define   PFEN    0x20  /* mod: pre-fetch enable            */
+	#define   EA      0x20  /* mod: 720 enable-ack              */
+	#define   SSM     0x10  /* mod: single step mode            */
+	#define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
+	#define   STD     0x04  /* cmd: start dma mode              */
+	#define   IRQD    0x02  /* mod: irq disable                 */
+ 	#define	  NOCOM   0x01	/* cmd: protect sfbr while reselect */
+				/* bits 0-1 rsvd for C1010          */
+
+/*3c*/  u32	nc_adder;
+
+/*40*/  u16	nc_sien;	/* -->: interrupt enable            */
+/*42*/  u16	nc_sist;	/* <--: interrupt status            */
+        #define   SBMC    0x1000/* sta: SCSI Bus Mode Change (895/6 only) */
+        #define   STO     0x0400/* sta: timeout (select)            */
+        #define   GEN     0x0200/* sta: timeout (general)           */
+        #define   HTH     0x0100/* sta: timeout (handshake)         */
+        #define   MA      0x80  /* sta: phase mismatch              */
+        #define   CMP     0x40  /* sta: arbitration complete        */
+        #define   SEL     0x20  /* sta: selected by another device  */
+        #define   RSL     0x10  /* sta: reselected by another device*/
+        #define   SGE     0x08  /* sta: gross error (over/underflow)*/
+        #define   UDC     0x04  /* sta: unexpected disconnect       */
+        #define   RST     0x02  /* sta: scsi bus reset detected     */
+        #define   PAR     0x01  /* sta: scsi parity error           */
+
+/*44*/  u8	nc_slpar;
+/*45*/  u8	nc_swide;
+/*46*/  u8	nc_macntl;
+/*47*/  u8	nc_gpcntl;
+/*48*/  u8	nc_stime0;    /* cmd: timeout for select&handshake*/
+/*49*/  u8	nc_stime1;    /* cmd: timeout user defined        */
+/*4a*/  u16   nc_respid;    /* sta: Reselect-IDs                */
+
+/*4c*/  u8	nc_stest0;
+
+/*4d*/  u8	nc_stest1;
+	#define   SCLK    0x80	/* Use the PCI clock as SCSI clock	*/
+	#define   DBLEN   0x08	/* clock doubler running		*/
+	#define   DBLSEL  0x04	/* clock doubler selected		*/
+  
+
+/*4e*/  u8	nc_stest2;
+	#define   ROF     0x40	/* reset scsi offset (after gross error!) */
+	#define   DIF     0x20  /* 720 SCSI differential mode             */
+	#define   EXT     0x02  /* extended filtering                     */
+
+/*4f*/  u8	nc_stest3;
+	#define   TE     0x80	/* c: tolerAnt enable */
+	#define   HSC    0x20	/* c: Halt SCSI Clock */
+	#define   CSF    0x02	/* c: clear scsi fifo */
+
+/*50*/  u16   nc_sidl;	/* Lowlevel: latched from scsi data */
+/*52*/  u8	nc_stest4;
+	#define   SMODE  0xc0	/* SCSI bus mode      (895/6 only) */
+	#define    SMODE_HVD 0x40	/* High Voltage Differential       */
+	#define    SMODE_SE  0x80	/* Single Ended                    */
+	#define    SMODE_LVD 0xc0	/* Low Voltage Differential        */
+	#define   LCKFRQ 0x20	/* Frequency Lock (895/6 only)     */
+				/* bits 0-5 rsvd for C1010          */
+
+/*53*/  u8	nc_53_;
+/*54*/  u16	nc_sodl;	/* Lowlevel: data out to scsi data  */
+/*56*/	u8	nc_ccntl0;	/* Chip Control 0 (896)             */
+	#define   ENPMJ  0x80	/* Enable Phase Mismatch Jump       */
+	#define   PMJCTL 0x40	/* Phase Mismatch Jump Control      */
+	#define   ENNDJ  0x20	/* Enable Non Data PM Jump          */
+	#define   DISFC  0x10	/* Disable Auto FIFO Clear          */
+	#define   DILS   0x02	/* Disable Internal Load/Store      */
+	#define   DPR    0x01	/* Disable Pipe Req                 */
+
+/*57*/	u8	nc_ccntl1;	/* Chip Control 1 (896)             */
+	#define   ZMOD   0x80	/* High Impedance Mode              */
+	#define	  DIC	 0x10	/* Disable Internal Cycles	    */
+	#define   DDAC   0x08	/* Disable Dual Address Cycle       */
+	#define   XTIMOD 0x04	/* 64-bit Table Ind. Indexing Mode  */
+	#define   EXTIBMV 0x02	/* Enable 64-bit Table Ind. BMOV    */
+	#define   EXDBMV 0x01	/* Enable 64-bit Direct BMOV        */
+
+/*58*/  u16	nc_sbdl;	/* Lowlevel: data from scsi data    */
+/*5a*/  u16	nc_5a_;
+
+/*5c*/  u8	nc_scr0;	/* Working register B               */
+/*5d*/  u8	nc_scr1;	/*                                  */
+/*5e*/  u8	nc_scr2;	/*                                  */
+/*5f*/  u8	nc_scr3;	/*                                  */
+
+/*60*/  u8	nc_scrx[64];	/* Working register C-R             */
+/*a0*/	u32	nc_mmrs;	/* Memory Move Read Selector        */
+/*a4*/	u32	nc_mmws;	/* Memory Move Write Selector       */
+/*a8*/	u32	nc_sfs;		/* Script Fetch Selector            */
+/*ac*/	u32	nc_drs;		/* DSA Relative Selector            */
+/*b0*/	u32	nc_sbms;	/* Static Block Move Selector       */
+/*b4*/	u32	nc_dbms;	/* Dynamic Block Move Selector      */
+/*b8*/	u32	nc_dnad64;	/* DMA Next Address 64              */
+/*bc*/	u16	nc_scntl4;	/* C1010 only                       */
+	#define   U3EN   0x80	/* Enable Ultra 3                   */
+	#define   AIPEN	 0x40   /* Allow check upper byte lanes     */
+	#define   XCLKH_DT 0x08 /* Extra clock of data hold on DT
+					transfer edge	            */
+	#define   XCLKH_ST 0x04 /* Extra clock of data hold on ST
+					transfer edge	            */
+
+/*be*/  u8	nc_aipcntl0;	/* Epat Control 1 C1010 only        */
+/*bf*/  u8	nc_aipcntl1;	/* AIP Control C1010_66 Only        */
+
+/*c0*/	u32	nc_pmjad1;	/* Phase Mismatch Jump Address 1    */
+/*c4*/	u32	nc_pmjad2;	/* Phase Mismatch Jump Address 2    */
+/*c8*/	u8	nc_rbc;		/* Remaining Byte Count             */
+/*c9*/	u8	nc_rbc1;	/*                                  */
+/*ca*/	u8	nc_rbc2;	/*                                  */
+/*cb*/	u8	nc_rbc3;	/*                                  */
+
+/*cc*/	u8	nc_ua;		/* Updated Address                  */
+/*cd*/	u8	nc_ua1;		/*                                  */
+/*ce*/	u8	nc_ua2;		/*                                  */
+/*cf*/	u8	nc_ua3;		/*                                  */
+/*d0*/	u32	nc_esa;		/* Entry Storage Address            */
+/*d4*/	u8	nc_ia;		/* Instruction Address              */
+/*d5*/	u8	nc_ia1;
+/*d6*/	u8	nc_ia2;
+/*d7*/	u8	nc_ia3;
+/*d8*/	u32	nc_sbc;		/* SCSI Byte Count (3 bytes only)   */
+/*dc*/	u32	nc_csbc;	/* Cumulative SCSI Byte Count       */
+
+				/* Following for C1010 only         */
+/*e0*/  u16	nc_crcpad;	/* CRC Value                        */
+/*e2*/  u8	nc_crccntl0;	/* CRC control register             */
+	#define   SNDCRC  0x10	/* Send CRC Request                 */
+/*e3*/  u8	nc_crccntl1;	/* CRC control register             */
+/*e4*/  u32	nc_crcdata;	/* CRC data register                */ 
+/*e8*/  u32	nc_e8_;		/* rsvd 			    */
+/*ec*/  u32	nc_ec_;		/* rsvd 			    */
+/*f0*/  u16	nc_dfbc;	/* DMA FIFO byte count              */ 
+
+};
+
+/*-----------------------------------------------------------
+**
+**	Utility macros for the script.
+**
+**-----------------------------------------------------------
+*/
+
+#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r))
+#define REG(r) REGJ (nc_, r)
+
+typedef u32 ncrcmd;
+
+/*-----------------------------------------------------------
+**
+**	SCSI phases
+**
+**	DT phases illegal for ncr driver.
+**
+**-----------------------------------------------------------
+*/
+
+#define	SCR_DATA_OUT	0x00000000
+#define	SCR_DATA_IN	0x01000000
+#define	SCR_COMMAND	0x02000000
+#define	SCR_STATUS	0x03000000
+#define SCR_DT_DATA_OUT	0x04000000
+#define SCR_DT_DATA_IN	0x05000000
+#define SCR_MSG_OUT	0x06000000
+#define SCR_MSG_IN      0x07000000
+
+#define SCR_ILG_OUT	0x04000000
+#define SCR_ILG_IN	0x05000000
+
+/*-----------------------------------------------------------
+**
+**	Data transfer via SCSI.
+**
+**-----------------------------------------------------------
+**
+**	MOVE_ABS (LEN)
+**	<<start address>>
+**
+**	MOVE_IND (LEN)
+**	<<dnad_offset>>
+**
+**	MOVE_TBL
+**	<<dnad_offset>>
+**
+**-----------------------------------------------------------
+*/
+
+#define OPC_MOVE          0x08000000
+
+#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l))
+#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l))
+#define SCR_MOVE_TBL     (0x10000000 | OPC_MOVE)
+
+#define SCR_CHMOV_ABS(l) ((0x00000000) | (l))
+#define SCR_CHMOV_IND(l) ((0x20000000) | (l))
+#define SCR_CHMOV_TBL     (0x10000000)
+
+struct scr_tblmove {
+        u32  size;
+        u32  addr;
+};
+
+/*-----------------------------------------------------------
+**
+**	Selection
+**
+**-----------------------------------------------------------
+**
+**	SEL_ABS | SCR_ID (0..15)    [ | REL_JMP]
+**	<<alternate_address>>
+**
+**	SEL_TBL | << dnad_offset>>  [ | REL_JMP]
+**	<<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define	SCR_SEL_ABS	0x40000000
+#define	SCR_SEL_ABS_ATN	0x41000000
+#define	SCR_SEL_TBL	0x42000000
+#define	SCR_SEL_TBL_ATN	0x43000000
+
+
+#ifdef SCSI_NCR_BIG_ENDIAN
+struct scr_tblsel {
+        u8	sel_scntl3;
+        u8	sel_id;
+        u8	sel_sxfer;
+        u8	sel_scntl4;	
+};
+#else
+struct scr_tblsel {
+        u8	sel_scntl4;	
+        u8	sel_sxfer;
+        u8	sel_id;
+        u8	sel_scntl3;
+};
+#endif
+
+#define SCR_JMP_REL     0x04000000
+#define SCR_ID(id)	(((u32)(id)) << 16)
+
+/*-----------------------------------------------------------
+**
+**	Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+**	WAIT_DISC
+**	dummy: <<alternate_address>>
+**
+**	WAIT_RESEL
+**	<<alternate_address>>
+**
+**-----------------------------------------------------------
+*/
+
+#define	SCR_WAIT_DISC	0x48000000
+#define SCR_WAIT_RESEL  0x50000000
+
+/*-----------------------------------------------------------
+**
+**	Bit Set / Reset
+**
+**-----------------------------------------------------------
+**
+**	SET (flags {|.. })
+**
+**	CLR (flags {|.. })
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_SET(f)     (0x58000000 | (f))
+#define SCR_CLR(f)     (0x60000000 | (f))
+
+#define	SCR_CARRY	0x00000400
+#define	SCR_TRG		0x00000200
+#define	SCR_ACK		0x00000040
+#define	SCR_ATN		0x00000008
+
+
+
+
+/*-----------------------------------------------------------
+**
+**	Memory to memory move
+**
+**-----------------------------------------------------------
+**
+**	COPY (bytecount)
+**	<< source_address >>
+**	<< destination_address >>
+**
+**	SCR_COPY   sets the NO FLUSH option by default.
+**	SCR_COPY_F does not set this option.
+**
+**	For chips which do not support this option,
+**	ncr_copy_and_bind() will remove this bit.
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_FLUSH 0x01000000
+
+#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
+#define SCR_COPY_F(n) (0xc0000000 | (n))
+
+/*-----------------------------------------------------------
+**
+**	Register move and binary operations
+**
+**-----------------------------------------------------------
+**
+**	SFBR_REG (reg, op, data)        reg  = SFBR op data
+**	<< 0 >>
+**
+**	REG_SFBR (reg, op, data)        SFBR = reg op data
+**	<< 0 >>
+**
+**	REG_REG  (reg, op, data)        reg  = reg op data
+**	<< 0 >>
+**
+**-----------------------------------------------------------
+**	On 810A, 860, 825A, 875, 895 and 896 chips the content 
+**	of SFBR register can be used as data (SCR_SFBR_DATA).
+**	The 896 has additionnal IO registers starting at 
+**	offset 0x80. Bit 7 of register offset is stored in 
+**	bit 7 of the SCRIPTS instruction first DWORD.
+**-----------------------------------------------------------
+*/
+
+#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) 
+
+#define SCR_SFBR_REG(reg,op,data) \
+        (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+#define SCR_REG_SFBR(reg,op,data) \
+        (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+#define SCR_REG_REG(reg,op,data) \
+        (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
+
+
+#define      SCR_LOAD   0x00000000
+#define      SCR_SHL    0x01000000
+#define      SCR_OR     0x02000000
+#define      SCR_XOR    0x03000000
+#define      SCR_AND    0x04000000
+#define      SCR_SHR    0x05000000
+#define      SCR_ADD    0x06000000
+#define      SCR_ADDC   0x07000000
+
+#define      SCR_SFBR_DATA   (0x00800000>>8ul)	/* Use SFBR as data */
+
+/*-----------------------------------------------------------
+**
+**	FROM_REG (reg)		  SFBR = reg
+**	<< 0 >>
+**
+**	TO_REG	 (reg)		  reg  = SFBR
+**	<< 0 >>
+**
+**	LOAD_REG (reg, data)	  reg  = <data>
+**	<< 0 >>
+**
+**	LOAD_SFBR(data) 	  SFBR = <data>
+**	<< 0 >>
+**
+**-----------------------------------------------------------
+*/
+
+#define	SCR_FROM_REG(reg) \
+	SCR_REG_SFBR(reg,SCR_OR,0)
+
+#define	SCR_TO_REG(reg) \
+	SCR_SFBR_REG(reg,SCR_OR,0)
+
+#define	SCR_LOAD_REG(reg,data) \
+	SCR_REG_REG(reg,SCR_LOAD,data)
+
+#define SCR_LOAD_SFBR(data) \
+        (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
+
+/*-----------------------------------------------------------
+**
+**	LOAD  from memory   to register.
+**	STORE from register to memory.
+**
+**	Only supported by 810A, 860, 825A, 875, 895 and 896.
+**
+**-----------------------------------------------------------
+**
+**	LOAD_ABS (LEN)
+**	<<start address>>
+**
+**	LOAD_REL (LEN)        (DSA relative)
+**	<<dsa_offset>>
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul)
+#define SCR_NO_FLUSH2	0x02000000
+#define SCR_DSA_REL2	0x10000000
+
+#define SCR_LOAD_R(reg, how, n) \
+        (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+
+#define SCR_STORE_R(reg, how, n) \
+        (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
+
+#define SCR_LOAD_ABS(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2, n)
+#define SCR_LOAD_REL(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n)
+#define SCR_LOAD_ABS_F(reg, n)	SCR_LOAD_R(reg, 0, n)
+#define SCR_LOAD_REL_F(reg, n)	SCR_LOAD_R(reg, SCR_DSA_REL2, n)
+
+#define SCR_STORE_ABS(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2, n)
+#define SCR_STORE_REL(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n)
+#define SCR_STORE_ABS_F(reg, n)	SCR_STORE_R(reg, 0, n)
+#define SCR_STORE_REL_F(reg, n)	SCR_STORE_R(reg, SCR_DSA_REL2, n)
+
+
+/*-----------------------------------------------------------
+**
+**	Waiting for Disconnect or Reselect
+**
+**-----------------------------------------------------------
+**
+**	JUMP            [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<address>>
+**
+**	JUMPR           [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<distance>>
+**
+**	CALL            [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<address>>
+**
+**	CALLR           [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<distance>>
+**
+**	RETURN          [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<dummy>>
+**
+**	INT             [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<ident>>
+**
+**	INT_FLY         [ | IFTRUE/IFFALSE ( ... ) ]
+**	<<ident>>
+**
+**	Conditions:
+**	     WHEN (phase)
+**	     IF   (phase)
+**	     CARRYSET
+**	     DATA (data, mask)
+**
+**-----------------------------------------------------------
+*/
+
+#define SCR_NO_OP       0x80000000
+#define SCR_JUMP        0x80080000
+#define SCR_JUMP64      0x80480000
+#define SCR_JUMPR       0x80880000
+#define SCR_CALL        0x88080000
+#define SCR_CALLR       0x88880000
+#define SCR_RETURN      0x90080000
+#define SCR_INT         0x98080000
+#define SCR_INT_FLY     0x98180000
+
+#define IFFALSE(arg)   (0x00080000 | (arg))
+#define IFTRUE(arg)    (0x00000000 | (arg))
+
+#define WHEN(phase)    (0x00030000 | (phase))
+#define IF(phase)      (0x00020000 | (phase))
+
+#define DATA(D)        (0x00040000 | ((D) & 0xff))
+#define MASK(D,M)      (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
+
+#define CARRYSET       (0x00200000)
+
+/*-----------------------------------------------------------
+**
+**	SCSI  constants.
+**
+**-----------------------------------------------------------
+*/
+
+/*
+**	Messages
+*/
+
+#define	M_COMPLETE	COMMAND_COMPLETE
+#define	M_EXTENDED	EXTENDED_MESSAGE
+#define	M_SAVE_DP	SAVE_POINTERS
+#define	M_RESTORE_DP	RESTORE_POINTERS
+#define	M_DISCONNECT	DISCONNECT
+#define	M_ID_ERROR	INITIATOR_ERROR
+#define	M_ABORT		ABORT_TASK_SET
+#define	M_REJECT	MESSAGE_REJECT
+#define	M_NOOP		NOP
+#define	M_PARITY	MSG_PARITY_ERROR
+#define	M_LCOMPLETE	LINKED_CMD_COMPLETE
+#define	M_FCOMPLETE	LINKED_FLG_CMD_COMPLETE
+#define	M_RESET		TARGET_RESET
+#define	M_ABORT_TAG	ABORT_TASK
+#define	M_CLEAR_QUEUE	CLEAR_TASK_SET
+#define	M_INIT_REC	INITIATE_RECOVERY
+#define	M_REL_REC	RELEASE_RECOVERY
+#define	M_TERMINATE	(0x11)
+#define	M_SIMPLE_TAG	SIMPLE_QUEUE_TAG
+#define	M_HEAD_TAG	HEAD_OF_QUEUE_TAG
+#define	M_ORDERED_TAG	ORDERED_QUEUE_TAG
+#define	M_IGN_RESIDUE	IGNORE_WIDE_RESIDUE
+#define	M_IDENTIFY   	(0x80)
+
+#define	M_X_MODIFY_DP	EXTENDED_MODIFY_DATA_POINTER
+#define	M_X_SYNC_REQ	EXTENDED_SDTR
+#define	M_X_WIDE_REQ	EXTENDED_WDTR
+#define	M_X_PPR_REQ	EXTENDED_PPR
+
+/*
+**	Status
+*/
+
+#define	S_GOOD		(0x00)
+#define	S_CHECK_COND	(0x02)
+#define	S_COND_MET	(0x04)
+#define	S_BUSY		(0x08)
+#define	S_INT		(0x10)
+#define	S_INT_COND_MET	(0x14)
+#define	S_CONFLICT	(0x18)
+#define	S_TERMINATED	(0x20)
+#define	S_QUEUE_FULL	(0x28)
+#define	S_ILLEGAL	(0xff)
+#define	S_SENSE		(0x80)
+
+/*
+ * End of ncrreg from FreeBSD
+ */
 
 /*
 	Build a scatter/gather entry.
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 7c53064..0c9edb7 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -95,27 +95,21 @@
 } scsi_info_t;
 
 static void aha152x_release_cs(dev_link_t *link);
-static int aha152x_event(event_t event, int priority,
-			 event_callback_args_t *args);
-
-static dev_link_t *aha152x_attach(void);
-static void aha152x_detach(dev_link_t *);
+static void aha152x_detach(struct pcmcia_device *p_dev);
+static void aha152x_config_cs(dev_link_t *link);
 
 static dev_link_t *dev_list;
-static dev_info_t dev_info = "aha152x_cs";
 
-static dev_link_t *aha152x_attach(void)
+static int aha152x_attach(struct pcmcia_device *p_dev)
 {
     scsi_info_t *info;
-    client_reg_t client_reg;
     dev_link_t *link;
-    int ret;
     
     DEBUG(0, "aha152x_attach()\n");
 
     /* Create new SCSI device */
     info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
+    if (!info) return -ENOMEM;
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
 
@@ -129,26 +123,20 @@
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	aha152x_detach(link);
-	return NULL;
-    }
-    
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    aha152x_config_cs(link);
+
+    return 0;
 } /* aha152x_attach */
 
 /*====================================================================*/
 
-static void aha152x_detach(dev_link_t *link)
+static void aha152x_detach(struct pcmcia_device *p_dev)
 {
+    dev_link_t *link = dev_to_instance(p_dev);
     dev_link_t **linkp;
 
     DEBUG(0, "aha152x_detach(0x%p)\n", link);
@@ -162,9 +150,6 @@
     if (link->state & DEV_CONFIG)
 	aha152x_release_cs(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
     /* Unlink device structure, free bits */
     *linkp = link->next;
     kfree(link->priv);
@@ -272,44 +257,31 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-static int aha152x_event(event_t event, int priority,
-			 event_callback_args_t *args)
+static int aha152x_suspend(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
-    scsi_info_t *info = link->priv;
-    
-    DEBUG(0, "aha152x_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    aha152x_release_cs(link);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	aha152x_config_cs(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
+	dev_link_t *link = dev_to_instance(dev);
+
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int aha152x_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	scsi_info_t *info = link->priv;
+
 	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
 	if (link->state & DEV_CONFIG) {
-	    Scsi_Cmnd tmp;
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    tmp.device->host = info->host;
-	    aha152x_host_reset(&tmp);
+		Scsi_Cmnd tmp;
+		pcmcia_request_configuration(link->handle, &link->conf);
+		tmp.device->host = info->host;
+		aha152x_host_reset(&tmp);
 	}
-	break;
-    }
-    return 0;
+
+	return 0;
 }
 
 static struct pcmcia_device_id aha152x_ids[] = {
@@ -327,10 +299,11 @@
 	.drv		= {
 		.name	= "aha152x_cs",
 	},
-	.attach		= aha152x_attach,
-	.event		= aha152x_event,
-	.detach		= aha152x_detach,
+	.probe		= aha152x_attach,
+	.remove		= aha152x_detach,
 	.id_table       = aha152x_ids,
+	.suspend	= aha152x_suspend,
+	.resume		= aha152x_resume,
 };
 
 static int __init init_aha152x_cs(void)
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index db8f5cd..788c58d 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -80,29 +80,19 @@
 
 
 static void fdomain_release(dev_link_t *link);
-static int fdomain_event(event_t event, int priority,
-			event_callback_args_t *args);
+static void fdomain_detach(struct pcmcia_device *p_dev);
+static void fdomain_config(dev_link_t *link);
 
-static dev_link_t *fdomain_attach(void);
-static void fdomain_detach(dev_link_t *);
-
-
-static dev_link_t *dev_list = NULL;
-
-static dev_info_t dev_info = "fdomain_cs";
-
-static dev_link_t *fdomain_attach(void)
+static int fdomain_attach(struct pcmcia_device *p_dev)
 {
     scsi_info_t *info;
-    client_reg_t client_reg;
     dev_link_t *link;
-    int ret;
-    
+
     DEBUG(0, "fdomain_attach()\n");
 
     /* Create new SCSI device */
     info = kmalloc(sizeof(*info), GFP_KERNEL);
-    if (!info) return NULL;
+    if (!info) return -ENOMEM;
     memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
     link->io.NumPorts1 = 0x10;
@@ -115,46 +105,27 @@
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = pcmcia_register_client(&link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	fdomain_detach(link);
-	return NULL;
-    }
-    
-    return link;
+    link->handle = p_dev;
+    p_dev->instance = link;
+
+    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+    fdomain_config(link);
+
+    return 0;
 } /* fdomain_attach */
 
 /*====================================================================*/
 
-static void fdomain_detach(dev_link_t *link)
+static void fdomain_detach(struct pcmcia_device *p_dev)
 {
-    dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
-    DEBUG(0, "fdomain_detach(0x%p)\n", link);
-    
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
+	DEBUG(0, "fdomain_detach(0x%p)\n", link);
 
-    if (link->state & DEV_CONFIG)
-	fdomain_release(link);
+	if (link->state & DEV_CONFIG)
+		fdomain_release(link);
 
-    if (link->handle)
-	pcmcia_deregister_client(link->handle);
-    
-    /* Unlink device structure, free bits */
-    *linkp = link->next;
-    kfree(link->priv);
-    
+	kfree(link->priv);
 } /* fdomain_detach */
 
 /*====================================================================*/
@@ -256,43 +227,29 @@
 
 /*====================================================================*/
 
-static int fdomain_event(event_t event, int priority,
-			event_callback_args_t *args)
+static int fdomain_suspend(struct pcmcia_device *dev)
 {
-    dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 
-    DEBUG(1, "fdomain_event(0x%06x)\n", event);
-    
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG)
-	    fdomain_release(link);
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	fdomain_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
 	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
 	if (link->state & DEV_CONFIG)
-	    pcmcia_release_configuration(link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (link->state & DEV_CONFIG) {
-	    pcmcia_request_configuration(link->handle, &link->conf);
-	    fdomain_16x0_bus_reset(NULL);
-	}
-	break;
-    }
-    return 0;
-} /* fdomain_event */
+		pcmcia_release_configuration(link->handle);
 
+	return 0;
+}
+
+static int fdomain_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
+		fdomain_16x0_bus_reset(NULL);
+	}
+
+	return 0;
+}
 
 static struct pcmcia_device_id fdomain_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20),
@@ -307,10 +264,11 @@
 	.drv		= {
 		.name	= "fdomain_cs",
 	},
-	.attach		= fdomain_attach,
-	.event		= fdomain_event,
-	.detach		= fdomain_detach,
+	.probe		= fdomain_attach,
+	.remove		= fdomain_detach,
 	.id_table       = fdomain_ids,
+	.suspend	= fdomain_suspend,
+	.resume		= fdomain_resume,
 };
 
 static int __init init_fdomain_cs(void)
@@ -321,7 +279,6 @@
 static void __exit exit_fdomain_cs(void)
 {
 	pcmcia_unregister_driver(&fdomain_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_fdomain_cs);
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 050ea13..9e3ab3f 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -104,9 +104,6 @@
 #endif
 };
 
-static dev_link_t *dev_list = NULL;
-static dev_info_t dev_info  = {"nsp_cs"};
-
 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
 
 
@@ -1596,19 +1593,17 @@
     configure the card at this point -- we wait until we receive a
     card insertion event.
 ======================================================================*/
-static dev_link_t *nsp_cs_attach(void)
+static int nsp_cs_attach(struct pcmcia_device *p_dev)
 {
 	scsi_info_t  *info;
-	client_reg_t  client_reg;
 	dev_link_t   *link;
-	int	      ret;
 	nsp_hw_data  *data = &nsp_data_base;
 
 	nsp_dbg(NSP_DEBUG_INIT, "in");
 
 	/* Create new SCSI device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
-	if (info == NULL) { return NULL; }
+	if (info == NULL) { return -ENOMEM; }
 	memset(info, 0, sizeof(*info));
 	link = &info->link;
 	link->priv = info;
@@ -1636,23 +1631,14 @@
 	link->conf.IntType	 = INT_MEMORY_AND_IO;
 	link->conf.Present	 = PRESENT_OPTION;
 
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	/* Register with Card Services */
-	link->next               = dev_list;
-	dev_list                 = link;
-	client_reg.dev_info	 = &dev_info;
-	client_reg.Version	 = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		nsp_cs_detach(link);
-		return NULL;
-	}
-
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	nsp_cs_config(link);
 
 	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
-	return link;
+	return 0;
 } /* nsp_cs_attach */
 
 
@@ -1662,35 +1648,19 @@
     structures are freed.  Otherwise, the structures will be freed
     when the device is released.
 ======================================================================*/
-static void nsp_cs_detach(dev_link_t *link)
+static void nsp_cs_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
-		if (*linkp == link) {
-			break;
-		}
-	}
-	if (*linkp == NULL) {
-		return;
-	}
-
-	if (link->state & DEV_CONFIG)
+	if (link->state & DEV_CONFIG) {
+		((scsi_info_t *)link->priv)->stop = 1;
 		nsp_cs_release(link);
-
-	/* Break the link with Card Services */
-	if (link->handle) {
-		pcmcia_deregister_client(link->handle);
 	}
 
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
 	kfree(link->priv);
 	link->priv = NULL;
-
 } /* nsp_cs_detach */
 
 
@@ -2021,99 +1991,58 @@
 #endif
 } /* nsp_cs_release */
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
-
-======================================================================*/
-static int nsp_cs_event(event_t		       event,
-			int		       priority,
-			event_callback_args_t *args)
+static int nsp_cs_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t  *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 	scsi_info_t *info = link->priv;
 	nsp_hw_data *data;
 
-	nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
+	link->state |= DEV_SUSPEND;
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		nsp_dbg(NSP_DEBUG_INIT, "event: remove");
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			((scsi_info_t *)link->priv)->stop = 1;
-			nsp_cs_release(link);
-		}
-		break;
+	nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
 
-	case CS_EVENT_CARD_INSERTION:
-		nsp_dbg(NSP_DEBUG_INIT, "event: insert");
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
-		info->bus    =  args->bus;
-#endif
-		nsp_cs_config(link);
-		break;
+	if (info->host != NULL) {
+		nsp_msg(KERN_INFO, "clear SDTR status");
 
-	case CS_EVENT_PM_SUSPEND:
-		nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		/* Mark the device as stopped, to block IO until later */
-		nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
+		data = (nsp_hw_data *)info->host->hostdata;
 
-		if (info->host != NULL) {
-			nsp_msg(KERN_INFO, "clear SDTR status");
-
-			data = (nsp_hw_data *)info->host->hostdata;
-
-			nsphw_init_sync(data);
-		}
-
-		info->stop = 1;
-		if (link->state & DEV_CONFIG) {
-			pcmcia_release_configuration(link->handle);
-		}
-		break;
-
-	case CS_EVENT_PM_RESUME:
-		nsp_dbg(NSP_DEBUG_INIT, "event: resume");
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		nsp_dbg(NSP_DEBUG_INIT, "event: reset");
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-		}
-		info->stop = 0;
-
-		if (info->host != NULL) {
-			nsp_msg(KERN_INFO, "reset host and bus");
-
-			data = (nsp_hw_data *)info->host->hostdata;
-
-			nsphw_init   (data);
-			nsp_bus_reset(data);
-		}
-
-		break;
-
-	default:
-		nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
-		break;
+		nsphw_init_sync(data);
 	}
-	nsp_dbg(NSP_DEBUG_INIT, "end");
+
+	info->stop = 1;
+
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
 	return 0;
-} /* nsp_cs_event */
+}
+
+static int nsp_cs_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	scsi_info_t *info = link->priv;
+	nsp_hw_data *data;
+
+	nsp_dbg(NSP_DEBUG_INIT, "event: resume");
+
+	link->state &= ~DEV_SUSPEND;
+
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	info->stop = 0;
+
+	if (info->host != NULL) {
+		nsp_msg(KERN_INFO, "reset host and bus");
+
+		data = (nsp_hw_data *)info->host->hostdata;
+
+		nsphw_init   (data);
+		nsp_bus_reset(data);
+	}
+
+	return 0;
+}
 
 /*======================================================================*
  *	module entry point
@@ -2136,10 +2065,11 @@
 	.drv		= {
 		.name	= "nsp_cs",
 	},
-	.attach		= nsp_cs_attach,
-	.event		= nsp_cs_event,
-	.detach		= nsp_cs_detach,
+	.probe		= nsp_cs_attach,
+	.remove		= nsp_cs_detach,
 	.id_table	= nsp_cs_ids,
+	.suspend	= nsp_cs_suspend,
+	.resume		= nsp_cs_resume,
 };
 #endif
 
@@ -2171,7 +2101,6 @@
 
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
 	pcmcia_unregister_driver(&nsp_driver);
-	BUG_ON(dev_list != NULL);
 #else
 	unregister_pcmcia_driver(&dev_info);
 	/* XXX: this really needs to move into generic code.. */
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index f8b9430..b66b140 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -296,11 +296,9 @@
  */
 
 /* Card service functions */
-static dev_link_t *nsp_cs_attach (void);
-static void        nsp_cs_detach (dev_link_t *link);
+static void        nsp_cs_detach (struct pcmcia_device *p_dev);
 static void        nsp_cs_release(dev_link_t *link);
 static void        nsp_cs_config (dev_link_t *link);
-static int         nsp_cs_event  (event_t event, int priority, event_callback_args_t *args);
 
 /* Linux SCSI subsystem specific functions */
 static struct Scsi_Host *nsp_detect     (struct scsi_host_template *sht);
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index bb091a4..dce7e68 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -98,15 +98,8 @@
 } scsi_info_t;
 
 static void qlogic_release(dev_link_t *link);
-static int qlogic_event(event_t event, int priority, event_callback_args_t * args);
-
-static dev_link_t *qlogic_attach(void);
-static void qlogic_detach(dev_link_t *);
-
-
-static dev_link_t *dev_list = NULL;
-
-static dev_info_t dev_info = "qlogic_cs";
+static void qlogic_detach(struct pcmcia_device *p_dev);
+static void qlogic_config(dev_link_t * link);
 
 static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host,
 				dev_link_t *link, int qbase, int qlirq)
@@ -163,19 +156,17 @@
 err:
 	return NULL;
 }
-static dev_link_t *qlogic_attach(void)
+static int qlogic_attach(struct pcmcia_device *p_dev)
 {
 	scsi_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	DEBUG(0, "qlogic_attach()\n");
 
 	/* Create new SCSI device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 	memset(info, 0, sizeof(*info));
 	link = &info->link;
 	link->priv = info;
@@ -189,45 +180,26 @@
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.Present = PRESENT_OPTION;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		qlogic_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	qlogic_config(link);
+
+	return 0;
 }				/* qlogic_attach */
 
 /*====================================================================*/
 
-static void qlogic_detach(dev_link_t * link)
+static void qlogic_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DEBUG(0, "qlogic_detach(0x%p)\n", link);
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-	if (*linkp == NULL)
-		return;
-
 	if (link->state & DEV_CONFIG)
 		qlogic_release(link);
 
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
 	kfree(link->priv);
 
 }				/* qlogic_detach */
@@ -349,48 +321,39 @@
 
 /*====================================================================*/
 
-static int qlogic_event(event_t event, int priority, event_callback_args_t * args)
+static int qlogic_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 
-	DEBUG(1, "qlogic_event(0x%06x)\n", event);
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			qlogic_release(link);
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		qlogic_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			scsi_info_t *info = link->priv;
-			pcmcia_request_configuration(link->handle, &link->conf);
-			if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
-				outb(0x80, link->io.BasePort1 + 0xd);
-				outb(0x24, link->io.BasePort1 + 0x9);
-				outb(0x04, link->io.BasePort1 + 0xd);
-			}
-			/* Ugggglllyyyy!!! */
-			qlogicfas408_bus_reset(NULL);
-		}
-		break;
-	}
 	return 0;
-}				/* qlogic_event */
+}
+
+static int qlogic_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		scsi_info_t *info = link->priv;
+
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if ((info->manf_id == MANFID_MACNICA) ||
+		    (info->manf_id == MANFID_PIONEER) ||
+		    (info->manf_id == 0x0098)) {
+			outb(0x80, link->io.BasePort1 + 0xd);
+			outb(0x24, link->io.BasePort1 + 0x9);
+			outb(0x04, link->io.BasePort1 + 0xd);
+		}
+		/* Ugggglllyyyy!!! */
+		qlogicfas408_bus_reset(NULL);
+	}
+
+	return 0;
+}
 
 static struct pcmcia_device_id qlogic_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6),
@@ -419,10 +382,11 @@
 	.drv		= {
 	.name		= "qlogic_cs",
 	},
-	.attach		= qlogic_attach,
-	.event		= qlogic_event,
-	.detach		= qlogic_detach,
+	.probe		= qlogic_attach,
+	.remove		= qlogic_detach,
 	.id_table       = qlogic_ids,
+	.suspend	= qlogic_suspend,
+	.resume		= qlogic_resume,
 };
 
 static int __init init_qlogic_cs(void)
@@ -433,7 +397,6 @@
 static void __exit exit_qlogic_cs(void)
 {
 	pcmcia_unregister_driver(&qlogic_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 98b64b2..3a4dd6f 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -228,15 +228,6 @@
 
 /* ================================================================== */
 
-/*
-*  Global (within this module) variables other than
-*  sym53c500_driver_template (the scsi_host_template).
-*/
-static dev_link_t *dev_list;
-static dev_info_t dev_info = "sym53c500_cs";
-
-/* ================================================================== */
-
 static void
 chip_init(int io_port)
 {
@@ -872,96 +863,70 @@
 	return;
 } /* SYM53C500_config */
 
-static int
-SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
+static int sym53c500_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int sym53c500_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
 	struct scsi_info_t *info = link->priv;
 
-	DEBUG(1, "SYM53C500_event(0x%06x)\n", event);
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG) {
+		pcmcia_request_configuration(link->handle, &link->conf);
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			SYM53C500_release(link);
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		SYM53C500_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG) {
-			pcmcia_request_configuration(link->handle, &link->conf);
-			/* See earlier comment about manufacturer IDs. */
-			if ((info->manf_id == MANFID_MACNICA) ||
-			    (info->manf_id == MANFID_PIONEER) ||
-			    (info->manf_id == 0x0098)) {
-				outb(0x80, link->io.BasePort1 + 0xd);
-				outb(0x24, link->io.BasePort1 + 0x9);
-				outb(0x04, link->io.BasePort1 + 0xd);
-			}
-			/*
-			*  If things don't work after a "resume",
-			*  this is a good place to start looking.
-			*/
-			SYM53C500_int_host_reset(link->io.BasePort1);
+		/* See earlier comment about manufacturer IDs. */
+		if ((info->manf_id == MANFID_MACNICA) ||
+		    (info->manf_id == MANFID_PIONEER) ||
+		    (info->manf_id == 0x0098)) {
+			outb(0x80, link->io.BasePort1 + 0xd);
+			outb(0x24, link->io.BasePort1 + 0x9);
+			outb(0x04, link->io.BasePort1 + 0xd);
 		}
-		break;
+		/*
+		 *  If things don't work after a "resume",
+		 *  this is a good place to start looking.
+		 */
+		SYM53C500_int_host_reset(link->io.BasePort1);
 	}
+
 	return 0;
-} /* SYM53C500_event */
+}
 
 static void
-SYM53C500_detach(dev_link_t *link)
+SYM53C500_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-	if (*linkp == NULL)
-		return;
-
 	if (link->state & DEV_CONFIG)
 		SYM53C500_release(link);
 
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
-	/* Unlink device structure, free bits. */
-	*linkp = link->next;
 	kfree(link->priv);
 	link->priv = NULL;
 } /* SYM53C500_detach */
 
-static dev_link_t *
-SYM53C500_attach(void)
+static int
+SYM53C500_attach(struct pcmcia_device *p_dev)
 {
 	struct scsi_info_t *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	DEBUG(0, "SYM53C500_attach()\n");
 
 	/* Create new SCSI device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 	memset(info, 0, sizeof(*info));
 	link = &info->link;
 	link->priv = info;
@@ -975,20 +940,13 @@
 	link->conf.IntType = INT_MEMORY_AND_IO;
 	link->conf.Present = PRESENT_OPTION;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != 0) {
-		cs_error(link->handle, RegisterClient, ret);
-		SYM53C500_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	SYM53C500_config(link);
+
+	return 0;
 } /* SYM53C500_attach */
 
 MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
@@ -1008,10 +966,11 @@
 	.drv		= {
 		.name	= "sym53c500_cs",
 	},
-	.attach		= SYM53C500_attach,
-	.event		= SYM53C500_event,
-	.detach		= SYM53C500_detach,
+	.probe		= SYM53C500_attach,
+	.remove		= SYM53C500_detach,
 	.id_table       = sym53c500_ids,
+	.suspend	= sym53c500_suspend,
+	.resume		= sym53c500_resume,
 };
 
 static int __init
diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c
index f557f17..e8df0c9 100644
--- a/drivers/scsi/pdc_adma.c
+++ b/drivers/scsi/pdc_adma.c
@@ -464,14 +464,12 @@
 			continue;
 		qc = ata_qc_from_tag(ap, ap->active_tag);
 		if (qc && (!(qc->tf.ctl & ATA_NIEN))) {
-			unsigned int err_mask = 0;
-
 			if ((status & (aPERR | aPSD | aUIRQ)))
-				err_mask = AC_ERR_OTHER;
+				qc->err_mask |= AC_ERR_OTHER;
 			else if (pp->pkt[0] != cDONE)
-				err_mask = AC_ERR_OTHER;
+				qc->err_mask |= AC_ERR_OTHER;
 
-			ata_qc_complete(qc, err_mask);
+			ata_qc_complete(qc);
 		}
 	}
 	return handled;
@@ -501,7 +499,8 @@
 		
 				/* complete taskfile transaction */
 				pp->state = adma_state_idle;
-				ata_qc_complete(qc, ac_err_mask(status));
+				qc->err_mask |= ac_err_mask(status);
+				ata_qc_complete(qc);
 				handled = 1;
 			}
 		}
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
index c1c1c68..5205c4e 100644
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -1,55 +1,70 @@
 config SCSI_QLA2XXX
-	tristate
-	default (SCSI && PCI)
-	depends on SCSI && PCI
+	tristate "QLogic QLA2XXX Fibre Channel Support"
+	depends on PCI && SCSI
+	select SCSI_FC_ATTRS
+	select FW_LOADER
+	---help---
+	This qla2xxx driver supports all QLogic Fibre Channel
+	PCI and PCIe host adapters.
+
+	By default, firmware for the ISP parts will be loaded
+	via the Firmware Loader interface.
+
+	ISP             Firmware Filename
+	----------      -----------------
+	21xx            ql2100_fw.bin
+	22xx            ql2200_fw.bin
+	2300, 2312      ql2300_fw.bin
+	2322            ql2322_fw.bin
+	6312, 6322      ql6312_fw.bin
+	24xx            ql2400_fw.bin
+
+	Upon request, the driver caches the firmware image until
+	the driver is unloaded.
+
+	NOTE: The original method of building firmware-loader
+	modules has been deprecated as the firmware-images will
+	be removed from the kernel sources.
+
+config SCSI_QLA2XXX_EMBEDDED_FIRMWARE
+	bool "  Use firmware-loader modules (DEPRECATED)"
+	depends on SCSI_QLA2XXX
 
 config SCSI_QLA21XX
-	tristate "QLogic ISP2100 host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP2100 firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 21xx (ISP2100) host adapter family.
 
 config SCSI_QLA22XX
-	tristate "QLogic ISP2200 host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP2200 firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 22xx (ISP2200) host adapter family.
 
 config SCSI_QLA2300
-	tristate "QLogic ISP2300 host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP2300 firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 2300 (ISP2300 and ISP2312) host
 	adapter family.
 
 config SCSI_QLA2322
-	tristate "QLogic ISP2322 host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP2322 firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 2322 (ISP2322) host adapter family.
 
 config SCSI_QLA6312
-	tristate "QLogic ISP63xx host adapter family support"
-	depends on SCSI_QLA2XXX
-        select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP63xx firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 63xx (ISP6312 and ISP6322) host
 	adapter family.
 
 config SCSI_QLA24XX
-	tristate "QLogic ISP24xx host adapter family support"
-	depends on SCSI_QLA2XXX
-	select SCSI_FC_ATTRS
-	select FW_LOADER
+	tristate "  Build QLogic ISP24xx firmware-module"
+	depends on SCSI_QLA2XXX_EMBEDDED_FIRMWARE
 	---help---
 	This driver supports the QLogic 24xx (ISP2422 and ISP2432) host
 	adapter family.
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
index b169687..40c0de1 100644
--- a/drivers/scsi/qla2xxx/Makefile
+++ b/drivers/scsi/qla2xxx/Makefile
@@ -3,15 +3,18 @@
 qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
 		qla_dbg.o qla_sup.o qla_rscn.o qla_attr.o
 
+obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx.o
+
 qla2100-y := ql2100.o ql2100_fw.o
 qla2200-y := ql2200.o ql2200_fw.o
 qla2300-y := ql2300.o ql2300_fw.o
 qla2322-y := ql2322.o ql2322_fw.o
 qla6312-y := ql6312.o ql6312_fw.o
+qla2400-y := ql2400.o ql2400_fw.o
 
 obj-$(CONFIG_SCSI_QLA21XX) += qla2xxx.o qla2100.o
 obj-$(CONFIG_SCSI_QLA22XX) += qla2xxx.o qla2200.o
 obj-$(CONFIG_SCSI_QLA2300) += qla2xxx.o qla2300.o
 obj-$(CONFIG_SCSI_QLA2322) += qla2xxx.o qla2322.o
 obj-$(CONFIG_SCSI_QLA6312) += qla2xxx.o qla6312.o
-obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o
+obj-$(CONFIG_SCSI_QLA24XX) += qla2xxx.o qla2400.o
diff --git a/drivers/scsi/qla2xxx/ql2400.c b/drivers/scsi/qla2xxx/ql2400.c
new file mode 100644
index 0000000..6c7165f
--- /dev/null
+++ b/drivers/scsi/qla2xxx/ql2400.c
@@ -0,0 +1,111 @@
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "qla_def.h"
+
+static char qla_driver_name[] = "qla2400";
+
+extern uint32_t fw2400_version_str[];
+extern uint32_t fw2400_addr01;
+extern uint32_t fw2400_code01[];
+extern uint32_t fw2400_length01;
+extern uint32_t fw2400_addr02;
+extern uint32_t fw2400_code02[];
+extern uint32_t fw2400_length02;
+
+static struct qla_fw_info qla_fw_tbl[] = {
+	{
+		.addressing	= FW_INFO_ADDR_EXTENDED,
+		.fwcode		= (unsigned short *)&fw2400_code01[0],
+		.fwlen		= (unsigned short *)&fw2400_length01,
+		.lfwstart	= (unsigned long *)&fw2400_addr01,
+	},
+	{
+		.addressing	= FW_INFO_ADDR_EXTENDED,
+		.fwcode		= (unsigned short *)&fw2400_code02[0],
+		.fwlen		= (unsigned short *)&fw2400_length02,
+		.lfwstart	= (unsigned long *)&fw2400_addr02,
+	},
+	{ FW_INFO_ADDR_NOMORE, },
+};
+
+static struct qla_board_info qla_board_tbl[] = {
+	{
+		.drv_name	= qla_driver_name,
+		.isp_name	= "ISP2422",
+		.fw_info	= qla_fw_tbl,
+		.fw_fname	= "ql2400_fw.bin",
+	},
+	{
+		.drv_name	= qla_driver_name,
+		.isp_name	= "ISP2432",
+		.fw_info	= qla_fw_tbl,
+		.fw_fname	= "ql2400_fw.bin",
+	},
+};
+
+static struct pci_device_id qla24xx_pci_tbl[] = {
+	{
+		.vendor		= PCI_VENDOR_ID_QLOGIC,
+		.device		= PCI_DEVICE_ID_QLOGIC_ISP2422,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (unsigned long)&qla_board_tbl[0],
+	},
+	{
+		.vendor		= PCI_VENDOR_ID_QLOGIC,
+		.device		= PCI_DEVICE_ID_QLOGIC_ISP2432,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.driver_data	= (unsigned long)&qla_board_tbl[1],
+	},
+	{0, 0},
+};
+MODULE_DEVICE_TABLE(pci, qla24xx_pci_tbl);
+
+static int __devinit
+qla24xx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	return qla2x00_probe_one(pdev,
+	    (struct qla_board_info *)id->driver_data);
+}
+
+static void __devexit
+qla24xx_remove_one(struct pci_dev *pdev)
+{
+	qla2x00_remove_one(pdev);
+}
+
+static struct pci_driver qla24xx_pci_driver = {
+	.name		= "qla2400",
+	.id_table	= qla24xx_pci_tbl,
+	.probe		= qla24xx_probe_one,
+	.remove		= __devexit_p(qla24xx_remove_one),
+};
+
+static int __init
+qla24xx_init(void)
+{
+	return pci_module_init(&qla24xx_pci_driver);
+}
+
+static void __exit
+qla24xx_exit(void)
+{
+	pci_unregister_driver(&qla24xx_pci_driver);
+}
+
+module_init(qla24xx_init);
+module_exit(qla24xx_exit);
+
+MODULE_AUTHOR("QLogic Corporation");
+MODULE_DESCRIPTION("QLogic ISP24xx FC-SCSI Host Bus Adapter driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(QLA2XXX_VERSION);
diff --git a/drivers/scsi/qla2xxx/ql2400_fw.c b/drivers/scsi/qla2xxx/ql2400_fw.c
new file mode 100644
index 0000000..5977795
--- /dev/null
+++ b/drivers/scsi/qla2xxx/ql2400_fw.c
@@ -0,0 +1,12376 @@
+/*
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2005 QLogic Corporation
+ *
+ * See LICENSE.qla2xxx for copyright and licensing details.
+ */
+#include <linux/types.h>
+
+/*
+ *	Firmware Version 4.00.16 (08:09 Oct 26, 2005)
+ */
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_version = 4*1024+0;
+#else
+uint32_t risc_code_version = 4*1024+0;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_version_str[] = {4, 0,16};
+#else
+uint32_t firmware_version[] = {4, 0,16};
+#endif
+
+#ifdef UNIQUE_FW_NAME
+#define fw2400_VERSION_STRING "4.00.16"
+#else
+#define FW_VERSION_STRING "4.00.16"
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_addr01 = 0x00100000 ;
+#else
+uint32_t risc_code_addr01 = 0x00100000 ;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_code01[] = {
+#else
+uint32_t risc_code01[] = {
+#endif
+	0x0401f17c, 0x0010e000, 0x00100000, 0x0000ab4a,
+	0x00000004, 0x00000000, 0x00000010, 0x00000002,
+	0x00000003, 0x00000000, 0x20434f50, 0x59524947,
+	0x48542032, 0x30303520, 0x514c4f47, 0x49432043,
+	0x4f52504f, 0x52415449, 0x4f4e2020, 0x20495350,
+	0x32347878, 0x20466972, 0x6d776172, 0x65202020,
+	0x56657273, 0x696f6e20, 0x342e302e, 0x31362020,
+	0x20202024, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x42001800, 0x0010014f, 0x42002000, 0x0010b8fe,
+	0x500c0800, 0x800c1800, 0x500c1000, 0x800c1800,
+	0x54042000, 0x80102000, 0x80040800, 0x80081040,
+	0x040207fc, 0x500c0800, 0x800409c0, 0x040207f6,
+	0x44002000, 0x80102000, 0x40100000, 0x44040000,
+	0x80000000, 0x44080000, 0x80000000, 0x440c0000,
+	0x80000000, 0x44100000, 0x80000000, 0x44140000,
+	0x80000000, 0x44180000, 0x80000000, 0x441c0000,
+	0x80000000, 0x44200000, 0x80000000, 0x44240000,
+	0x80000000, 0x44280000, 0x80000000, 0x442c0000,
+	0x80000000, 0x44300000, 0x80000000, 0x44340000,
+	0x80000000, 0x44380000, 0x80000000, 0x443c0000,
+	0x80000000, 0x44400000, 0x80000000, 0x44440000,
+	0x80000000, 0x44480000, 0x80000000, 0x444c0000,
+	0x80000000, 0x44500000, 0x80000000, 0x44540000,
+	0x80000000, 0x44580000, 0x80000000, 0x445c0000,
+	0x80000000, 0x44600000, 0x80000000, 0x44640000,
+	0x80000000, 0x44680000, 0x80000000, 0x446c0000,
+	0x80000000, 0x44700000, 0x80000000, 0x44740000,
+	0x80000000, 0x44780000, 0x80000000, 0x447c0000,
+	0x80000000, 0x44800000, 0x80000000, 0x44840000,
+	0x80000000, 0x44880000, 0x80000000, 0x448c0000,
+	0x80000000, 0x44900000, 0x80000000, 0x44940000,
+	0x80000000, 0x44980000, 0x80000000, 0x449c0000,
+	0x80000000, 0x44a00000, 0x80000000, 0x44a40000,
+	0x80000000, 0x44a80000, 0x80000000, 0x44ac0000,
+	0x80000000, 0x44b00000, 0x80000000, 0x44b40000,
+	0x80000000, 0x44b80000, 0x80000000, 0x44bc0000,
+	0x80000000, 0x44c00000, 0x80000000, 0x44c40000,
+	0x80000000, 0x44c80000, 0x80000000, 0x44cc0000,
+	0x80000000, 0x44d00000, 0x80000000, 0x44d80000,
+	0x80000000, 0x44d40000, 0x80000000, 0x44dc0000,
+	0x80000000, 0x44e00000, 0x80000000, 0x44e40000,
+	0x80000000, 0x44e80000, 0x80000000, 0x44ec0000,
+	0x80000000, 0x44f00000, 0x80000000, 0x44f40000,
+	0x80000000, 0x44f80000, 0x80000000, 0x44fc0000,
+	0x80000000, 0x45000000, 0x80000000, 0x45040000,
+	0x80000000, 0x45080000, 0x80000000, 0x450c0000,
+	0x80000000, 0x45100000, 0x80000000, 0x45140000,
+	0x80000000, 0x45180000, 0x80000000, 0x451c0000,
+	0x80000000, 0x45200000, 0x80000000, 0x45240000,
+	0x80000000, 0x45280000, 0x80000000, 0x452c0000,
+	0x80000000, 0x45300000, 0x80000000, 0x45340000,
+	0x80000000, 0x45380000, 0x80000000, 0x453c0000,
+	0x80000000, 0x45400000, 0x80000000, 0x45440000,
+	0x80000000, 0x45480000, 0x80000000, 0x454c0000,
+	0x80000000, 0x45500000, 0x80000000, 0x45540000,
+	0x80000000, 0x45580000, 0x80000000, 0x455c0000,
+	0x80000000, 0x45600000, 0x80000000, 0x45640000,
+	0x80000000, 0x45680000, 0x80000000, 0x456c0000,
+	0x80000000, 0x45700000, 0x80000000, 0x45740000,
+	0x80000000, 0x45780000, 0x80000000, 0x457c0000,
+	0x80000000, 0x45800000, 0x80000000, 0x45840000,
+	0x80000000, 0x45880000, 0x80000000, 0x458c0000,
+	0x80000000, 0x45900000, 0x80000000, 0x45940000,
+	0x80000000, 0x45980000, 0x80000000, 0x459c0000,
+	0x80000000, 0x45a00000, 0x80000000, 0x45a40000,
+	0x80000000, 0x45a80000, 0x80000000, 0x45ac0000,
+	0x80000000, 0x45b00000, 0x80000000, 0x45b40000,
+	0x80000000, 0x45b80000, 0x80000000, 0x45bc0000,
+	0x80000000, 0x45c00000, 0x80000000, 0x45c40000,
+	0x80000000, 0x45c80000, 0x80000000, 0x45cc0000,
+	0x80000000, 0x45d00000, 0x80000000, 0x45d40000,
+	0x80000000, 0x45d80000, 0x80000000, 0x45dc0000,
+	0x80000000, 0x45e00000, 0x80000000, 0x45e40000,
+	0x80000000, 0x45e80000, 0x80000000, 0x45ec0000,
+	0x80000000, 0x45f00000, 0x80000000, 0x45f40000,
+	0x80000000, 0x45f80000, 0x80000000, 0x45fc0000,
+	0x4a03c020, 0x00004000, 0x4a03c011, 0x40000010,
+	0x04006000, 0x4203e000, 0x40000000, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000000,
+	0x4203e000, 0x30000001, 0x0401f000, 0x0000bf00,
+	0x00000080, 0x0000bfe0, 0x00000020, 0x0000ff00,
+	0x00000080, 0x0000ffd0, 0x00000030, 0x00007100,
+	0x00000010, 0x00007200, 0x00000008, 0x00007209,
+	0x00000007, 0x00007300, 0x00000008, 0x00007309,
+	0x00000007, 0x00007400, 0x00000008, 0x00007409,
+	0x00000007, 0x00007600, 0x000000b0, 0x00007700,
+	0x00000040, 0x00003000, 0x00000070, 0x00004000,
+	0x000000c0, 0x00006000, 0x00000050, 0x00006100,
+	0x00000010, 0x00006130, 0x00000010, 0x00006150,
+	0x00000010, 0x00006170, 0x00000010, 0x00006190,
+	0x00000010, 0x000061b0, 0x00000010, 0x00000000,
+	0x42000000, 0x00000100, 0x4202f000, 0x00000000,
+	0x42000800, 0x00021f00, 0x45780800, 0x80040800,
+	0x80000040, 0x040207fd, 0x4203f000, 0x00021fff,
+	0x40000000, 0x4203e000, 0x90000100, 0x40000000,
+	0x0201f800, 0x001006fd, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24320002, 0x04020015,
+	0x42000800, 0x00000064, 0x80040840, 0x04000007,
+	0x4a030000, 0x00000001, 0x40000000, 0x59800000,
+	0x8c000500, 0x040007f9, 0x04000008, 0x42000800,
+	0x00007a17, 0x50040000, 0x8c00050e, 0x04020003,
+	0x8400054e, 0x44000800, 0x4a030000, 0x00000000,
+	0x4a03c020, 0x00000004, 0x4203e000, 0x6000000f,
+	0x59e00023, 0x8c000500, 0x04020039, 0x42000000,
+	0x00100001, 0x50000800, 0x82040c00, 0x00000004,
+	0x58042003, 0x42001000, 0xffffffff, 0x0201f800,
+	0x001006f4, 0x0402004e, 0x58042003, 0x42001000,
+	0xffffffff, 0x0201f800, 0x001006f4, 0x04020048,
+	0x58042003, 0x42001000, 0x00ffffff, 0x0201f800,
+	0x001006f4, 0x04020042, 0x58042003, 0x42001000,
+	0x00ffffff, 0x0201f800, 0x001006f4, 0x0402003c,
+	0x42000000, 0x00100001, 0x5000a000, 0x8250a400,
+	0x00000004, 0x4200a800, 0x00020000, 0x5850b003,
+	0x0201f800, 0x0010ab17, 0x8250a400, 0x00000005,
+	0x4a0370e8, 0x00000003, 0x4200a800, 0x0000c000,
+	0x5850b003, 0x0201f800, 0x0010ab17, 0x4a0378e8,
+	0x00000003, 0x4200a800, 0x00008000, 0x5850b003,
+	0x0201f800, 0x0010ab17, 0x0401f02b, 0x42000800,
+	0x00020000, 0x58042003, 0x42001000, 0xffffffff,
+	0x0201f800, 0x001006f4, 0x04020019, 0x4a0370e8,
+	0x00000003, 0x42000800, 0x0000c000, 0x58042003,
+	0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff,
+	0x0201f800, 0x001006f4, 0x0402000d, 0x4a0378e8,
+	0x00000003, 0x42000800, 0x00008000, 0x58042003,
+	0x82102500, 0x00ffffff, 0x42001000, 0x00ffffff,
+	0x0201f800, 0x001006f4, 0x0400000b, 0x4a03c020,
+	0x00004010, 0x4a03c011, 0x40100011, 0x04006000,
+	0x4203e000, 0x40000000, 0x4203e000, 0x30000001,
+	0x0401f000, 0x0201f800, 0x00100791, 0x42001000,
+	0x0010ab4a, 0x40080000, 0x80140480, 0x82001d00,
+	0xffffff00, 0x04020003, 0x40001800, 0x0401f003,
+	0x42001800, 0x000000ff, 0x480bc840, 0x480fc842,
+	0x04011000, 0x400c0000, 0x80081400, 0x40140000,
+	0x80080580, 0x040207f0, 0x4817500d, 0x45782800,
+	0x59c40000, 0x82000500, 0xffff0000, 0x80000120,
+	0x82000580, 0x00002422, 0x04020005, 0x59a80005,
+	0x8400054e, 0x48035005, 0x0401f008, 0x59e00003,
+	0x82000500, 0x00030000, 0x04000004, 0x59a80005,
+	0x84000554, 0x48035005, 0x42000800, 0x00000040,
+	0x59a80005, 0x8c000514, 0x0402000e, 0x42000800,
+	0x00001000, 0x82141480, 0x0017ffff, 0x04021009,
+	0x80040902, 0x82141480, 0x0013ffff, 0x04021005,
+	0x80040902, 0x82141480, 0x0011ffff, 0x04001b8d,
+	0x4807500e, 0x42001000, 0x00000024, 0x0201f800,
+	0x00106681, 0x82040c00, 0x0010d1c0, 0x4807500b,
+	0x4a03c810, 0x00100000, 0x4a03c811, 0x0010ab4a,
+	0x4a03c829, 0x00000004, 0x59e40001, 0x82000540,
+	0x0003001d, 0x4803c801, 0x4a03c014, 0x001c001c,
+	0x42001000, 0x0000001c, 0x0201f800, 0x001006e2,
+	0x4202c000, 0x0010d1c0, 0x59aab00b, 0x59aaa00b,
+	0x59aaa80b, 0x59aac80e, 0x49675069, 0x59a8000b,
+	0x4803500c, 0x0401fbf5, 0x0201f800, 0x00107903,
+	0x0201f800, 0x001007be, 0x0201f800, 0x00100807,
+	0x0201f800, 0x00101a05, 0x0201f800, 0x00101354,
+	0x0201f800, 0x00100969, 0x0201f800, 0x00101354,
+	0x0201f800, 0x00100f4c, 0x0201f800, 0x001066c1,
+	0x0401fb1a, 0x0201f800, 0x0010220e, 0x0201f800,
+	0x001053bb, 0x0201f800, 0x00104c90, 0x0201f800,
+	0x00106194, 0x0201f800, 0x00105f28, 0x0201f800,
+	0x001013ed, 0x0201f800, 0x0010126f, 0x4203e000,
+	0xf0000001, 0x42000000, 0x00001000, 0x50000000,
+	0x82000480, 0x24220001, 0x04000016, 0x59e00002,
+	0x8c00051e, 0x42000000, 0x7ffe00fe, 0x04020003,
+	0x42000000, 0x7ffe01fe, 0x50000800, 0x48075058,
+	0x80040920, 0x82040580, 0x0000013a, 0x04000004,
+	0x82040580, 0x0000013b, 0x04020006, 0x59a80005,
+	0x84000552, 0x48035005, 0x4a0378e4, 0x000c0000,
+	0x4a03c018, 0x0000000f, 0x4203e000, 0x20000511,
+	0x4203e000, 0x50010000, 0x4a03c020, 0x00000000,
+	0x04027013, 0x59e00020, 0x82000580, 0x00000002,
+	0x0402000f, 0x4a03c020, 0x00004000, 0x4a03c011,
+	0x40000010, 0x04006000, 0x4203e000, 0x40000000,
+	0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017,
+	0x00000000, 0x4203e000, 0x30000001, 0x4202d800,
+	0x00000000, 0x4203e000, 0xb0600000, 0x59a80005,
+	0x42000800, 0x00000002, 0x8c000512, 0x04020007,
+	0x42000800, 0x0000000f, 0x8c000514, 0x04020003,
+	0x42000800, 0x00000001, 0x4007f800, 0x59a80005,
+	0x8c000514, 0x02020000, 0x00020004, 0x59e00003,
+	0x82000500, 0x00030000, 0x82000580, 0x00000000,
+	0x04020af8, 0x0201f000, 0x00020004, 0x4df00000,
+	0x4203e000, 0x50000000, 0x416c0000, 0x82000c80,
+	0x00000008, 0x04021aef, 0x0c01f804, 0x5c03e000,
+	0x0201f000, 0x00020008, 0x001002f7, 0x0010030a,
+	0x001003d7, 0x001002f6, 0x00100452, 0x001002f6,
+	0x001002f6, 0x00100593, 0x0401fae2, 0x42000800,
+	0x0010b4a4, 0x5804001d, 0x4803c857, 0x8c000500,
+	0x0400000d, 0x84000500, 0x4800081d, 0x4202d800,
+	0x00000004, 0x0401fbd3, 0x49f3c857, 0x5c000800,
+	0x5c000000, 0x82000540, 0x00003e00, 0x4c000000,
+	0x4c040000, 0x1c01f000, 0x0401fbbd, 0x0201f800,
+	0x0010513b, 0x04000009, 0x0201f800, 0x00105151,
+	0x0402002e, 0x59c40006, 0x82000540, 0x000000c0,
+	0x48038806, 0x0401f029, 0x0201f800, 0x001050a2,
+	0x836c0580, 0x00000001, 0x040200bc, 0x59a80017,
+	0x82000580, 0x00000009, 0x040200b8, 0x497b5010,
+	0x4a038893, 0x00000001, 0x42001000, 0x000000f0,
+	0x0201f800, 0x0010193d, 0x0201f800, 0x00105149,
+	0x59c41006, 0x04020006, 0x82081540, 0x000000f1,
+	0x82081500, 0xbbffffff, 0x0401f003, 0x82081540,
+	0x440000f1, 0x480b8806, 0x0201f800, 0x0010609e,
+	0x4a0378e4, 0x00002000, 0x42000000, 0x0010b83a,
+	0x0201f800, 0x0010aa47, 0x42001000, 0x00008030,
+	0x497b5013, 0x0401f035, 0x0201f800, 0x00103b38,
+	0x59c400a4, 0x82000500, 0x0000000f, 0x82000480,
+	0x00000007, 0x04021091, 0x0201f800, 0x0010609e,
+	0x59c400a3, 0x82000500, 0xffefffff, 0x480388a3,
+	0x59a8004b, 0x800001c0, 0x04020004, 0x0201f800,
+	0x00104139, 0x0401f085, 0x59a80015, 0x84000546,
+	0x48035015, 0x0201f800, 0x00105141, 0x59c41006,
+	0x04020006, 0x82081540, 0x44000001, 0x82081500,
+	0xffffff0f, 0x0401f003, 0x82081540, 0x440000f1,
+	0x480b8806, 0x497b9005, 0x4a038802, 0x0000ffff,
+	0x4a0378e4, 0x00003000, 0x42000000, 0x0010b80c,
+	0x0201f800, 0x0010aa47, 0x59a81010, 0x42000800,
+	0x00000003, 0x0201f800, 0x00106c78, 0x42001000,
+	0x00008010, 0x59a8180a, 0x0201f800, 0x00103a3e,
+	0x0201f800, 0x00101815, 0x59a80805, 0x82040d00,
+	0xffffffdf, 0x48075005, 0x0201f800, 0x0010483d,
+	0x0201f800, 0x0010513b, 0x0400000a, 0x0201f800,
+	0x0010413e, 0x04000007, 0x4a035013, 0x00000001,
+	0x497b5021, 0x0201f800, 0x00103c80, 0x0401f04f,
+	0x0201f800, 0x001048ec, 0x04000005, 0x59c41002,
+	0x8408150c, 0x480b8802, 0x0401f012, 0x0201f800,
+	0x0010513b, 0x04020006, 0x59a8001d, 0x80000540,
+	0x02000800, 0x0010930f, 0x0401f00a, 0x0201f800,
+	0x0010930f, 0x59a80026, 0x8c000506, 0x04020005,
+	0x59a8001d, 0x80000540, 0x02020800, 0x00104245,
+	0x497b5028, 0x497b5027, 0x497b5018, 0x0201f800,
+	0x0010513b, 0x59a81026, 0x0402000a, 0x0201f800,
+	0x0010162a, 0x80001580, 0x59a8002a, 0x82000500,
+	0xffff0000, 0x80040d40, 0x4807502a, 0x0401f005,
+	0x59a8002a, 0x82000500, 0xffff0000, 0x4803502a,
+	0x599c0017, 0x8c00050a, 0x04000002, 0x84081544,
+	0x480b5026, 0x0201f800, 0x0010513b, 0x04000004,
+	0x0201f800, 0x0010162a, 0x48078880, 0x42001000,
+	0x00000005, 0x0201f800, 0x001070b0, 0x497b5028,
+	0x497b501b, 0x4a03501c, 0x0000ffff, 0x4a0378e4,
+	0x000000c0, 0x4202d800, 0x00000002, 0x0201f800,
+	0x0010513b, 0x04000007, 0x59a80026, 0x82000500,
+	0x0000000c, 0x82000580, 0x00000004, 0x04000003,
+	0x0201f800, 0x00101e45, 0x1c01f000, 0x59a8001c,
+	0x82000580, 0x0000ffff, 0x04000004, 0x0201f800,
+	0x00101e45, 0x0401f074, 0x59a80026, 0x8c00050a,
+	0x04020003, 0x8c000506, 0x0400001c, 0x8c000500,
+	0x0400001a, 0x4a038802, 0x0000ffbf, 0x8c000502,
+	0x04000016, 0x599c0018, 0x8c000516, 0x04020010,
+	0x59a80027, 0x82000580, 0x0000ffff, 0x0400000c,
+	0x0201f800, 0x00101f9a, 0x59a80026, 0x8c000504,
+	0x0402005d, 0x42001000, 0x00000003, 0x417a5800,
+	0x0201f800, 0x00101fbf, 0x0401f057, 0x59a80028,
+	0x80000540, 0x04020054, 0x59a80026, 0x8c000508,
+	0x04020005, 0x59a8001b, 0x80000540, 0x0402004e,
+	0x0401f003, 0x8c000516, 0x0400004b, 0x0201f800,
+	0x001048ec, 0x04020048, 0x599c0018, 0x8c000516,
+	0x04020004, 0x0201f800, 0x00104c51, 0x04020042,
+	0x599c0017, 0x8c00050a, 0x0400000d, 0x4200b000,
+	0x000007f0, 0x417a8800, 0x0201f800, 0x00020245,
+	0x04020004, 0x59340200, 0x8c00051a, 0x04020036,
+	0x81468800, 0x8058b040, 0x040207f8, 0x4a038802,
+	0x0000ffff, 0x42001800, 0x0010b4eb, 0x0401fb8c,
+	0x42001800, 0x0010b4f8, 0x0401fb89, 0x59a80005,
+	0x84000502, 0x48035005, 0x4a0378e4, 0x00000080,
+	0x4202d800, 0x00000003, 0x4a03501c, 0x0000ffff,
+	0x0401fa7f, 0x80000580, 0x0201f800, 0x00101590,
+	0x599c0018, 0x8c000516, 0x04000004, 0x0201f800,
+	0x00103b10, 0x0401f009, 0x42001800, 0x0000ffff,
+	0x42002000, 0x00000006, 0x42003000, 0x00000000,
+	0x0201f800, 0x00103aae, 0x0201f800, 0x00105151,
+	0x0400000b, 0x59c40006, 0x0201f800, 0x0010513b,
+	0x04000004, 0x82000500, 0xffffff0f, 0x0401f003,
+	0x82000500, 0xfbffffff, 0x48038806, 0x0201f800,
+	0x00106f36, 0x1c01f000, 0x4c040000, 0x4c080000,
+	0x4c100000, 0x59a8003e, 0x82000c80, 0x00000004,
+	0x04021980, 0x0c01f805, 0x5c002000, 0x5c001000,
+	0x5c000800, 0x1c01f000, 0x00100462, 0x001004ea,
+	0x00100516, 0x00100577, 0x42000000, 0x00000001,
+	0x0201f800, 0x00101590, 0x0201f800, 0x0010609e,
+	0x59c408a3, 0x82040d00, 0xfffffff7, 0x480788a3,
+	0x0201f800, 0x00105141, 0x0400000e, 0x0201f800,
+	0x00105151, 0x0400000b, 0x0201f800, 0x00105149,
+	0x04020964, 0x59c400a3, 0x84000532, 0x84000570,
+	0x480388a3, 0x4a038808, 0x00000008, 0x0401f010,
+	0x59c400a3, 0x84000530, 0x82000500, 0xbf7fffff,
+	0x480388a3, 0x42000800, 0x000000f8, 0x0201f800,
+	0x00104200, 0x59c400a3, 0x82000540, 0x00018000,
+	0x8400051c, 0x480388a3, 0x497b8808, 0x59c40006,
+	0x82000500, 0xfbffff0e, 0x48038806, 0x497b2822,
+	0x497b2823, 0x42000800, 0x000001f4, 0x42001000,
+	0x00100591, 0x0201f800, 0x00105f83, 0x59c40805,
+	0x42001000, 0x00000001, 0x0201f800, 0x0010193d,
+	0x0201f800, 0x0010163b, 0x0402000a, 0x42000000,
+	0x00000001, 0x0201f800, 0x0010188c, 0x42000000,
+	0x00000001, 0x0201f800, 0x00101821, 0x0401f022,
+	0x0201f800, 0x00101642, 0x04020008, 0x41780000,
+	0x0201f800, 0x0010188c, 0x41780000, 0x0201f800,
+	0x00101821, 0x0401f018, 0x0201f800, 0x00101649,
+	0x0402000a, 0x42000000, 0x00000002, 0x0201f800,
+	0x0010188c, 0x42000000, 0x00000002, 0x0201f800,
+	0x00101821, 0x0401f00c, 0x0201f800, 0x00101650,
+	0x04020918, 0x59a80049, 0x800001c0, 0x04000006,
+	0x0201f800, 0x00101656, 0x4a03503e, 0x00000001,
+	0x0401f021, 0x0201f800, 0x00101927, 0x4a03503e,
+	0x00000001, 0x0201f800, 0x00105141, 0x0400000c,
+	0x0201f800, 0x00105151, 0x04000009, 0x0201f800,
+	0x00105149, 0x04020903, 0x4a035033, 0x00000001,
+	0x0201f800, 0x001050a2, 0x0401f00f, 0x59c400a4,
+	0x82000500, 0x0000000f, 0x82000580, 0x00000008,
+	0x04000003, 0x4a038805, 0x04000000, 0x59c400a3,
+	0x82000540, 0x0001c000, 0x480388a3, 0x84000520,
+	0x480388a3, 0x1c01f000, 0x0401f8a3, 0x04020004,
+	0x4a03503e, 0x00000003, 0x0401f027, 0x0201f800,
+	0x00101650, 0x04020011, 0x59a80049, 0x800001c0,
+	0x0400000e, 0x0201f800, 0x00101656, 0x59a80048,
+	0x8c00051e, 0x0400001c, 0x0201f800, 0x00105149,
+	0x04020009, 0x4a035033, 0x00000001, 0x0201f800,
+	0x001050a2, 0x0401f004, 0x0201f800, 0x001018d3,
+	0x04020011, 0x0201f800, 0x00101815, 0x4a03503e,
+	0x00000002, 0x497b5049, 0x59c400a3, 0x84000520,
+	0x480388a3, 0x497b2822, 0x497b2823, 0x42000800,
+	0x0000002d, 0x42001000, 0x00100591, 0x0201f800,
+	0x00105f83, 0x1c01f000, 0x0401f877, 0x04020004,
+	0x4a03503e, 0x00000003, 0x0401f05b, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x001018d3, 0x04020050,
+	0x0201f800, 0x00105149, 0x04000044, 0x59c400a4,
+	0x82000500, 0x0000000f, 0x82000580, 0x00000008,
+	0x04000020, 0x59c40005, 0x8c000534, 0x0402001d,
+	0x59940022, 0x82000580, 0x00000001, 0x04020046,
+	0x0201f800, 0x00105151, 0x04020043, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x00105196, 0x4a035032,
+	0x0000aaaa, 0x4a035033, 0x00000000, 0x59c408a3,
+	0x82040d40, 0x00000008, 0x480788a3, 0x4202d800,
+	0x00000001, 0x4a03503e, 0x00000000, 0x4a038805,
+	0x00000001, 0x497b2822, 0x497b2823, 0x0401f01f,
+	0x0201f800, 0x00105151, 0x04020007, 0x59a80032,
+	0x82000580, 0x0000aaaa, 0x04020003, 0x4a035010,
+	0x00ffffff, 0x497b5032, 0x59c40006, 0x82000540,
+	0x04000001, 0x48038806, 0x59a80805, 0x8c040d06,
+	0x04020005, 0x59c408a3, 0x82040d40, 0x00000008,
+	0x480788a3, 0x4202d800, 0x00000001, 0x4a03503e,
+	0x00000000, 0x4a038805, 0x00000001, 0x497b2822,
+	0x497b2823, 0x0401f010, 0x59c40005, 0x82000500,
+	0x000000c0, 0x0400000c, 0x59c40006, 0x82000540,
+	0x000000f1, 0x48038806, 0x0401f7ef, 0x0201f800,
+	0x00101650, 0x04020004, 0x59a80049, 0x800001c0,
+	0x040207a4, 0x497b8885, 0x1c01f000, 0x4803c856,
+	0x42000000, 0x00000001, 0x0201f800, 0x00101590,
+	0x4a03503e, 0x00000000, 0x0201f800, 0x00101650,
+	0x0402000b, 0x59a80052, 0x800001c0, 0x04000004,
+	0x80000040, 0x48035052, 0x04020005, 0x4a035052,
+	0x0000000a, 0x4a035049, 0x00000001, 0x497b8885,
+	0x0401f0ed, 0x59940022, 0x59940823, 0x80040540,
+	0x1c01f000, 0x497b2823, 0x1c01f000, 0x4c080000,
+	0x42001000, 0x000000f0, 0x0201f800, 0x0010193d,
+	0x5c001000, 0x1c01f000, 0x4a03505c, 0x00000004,
+	0x4a03505d, 0x00000000, 0x4a03505e, 0x00000010,
+	0x4a03505f, 0x00000002, 0x4a035010, 0x00ffffff,
+	0x0201f800, 0x0010930f, 0x4a03502a, 0x20200000,
+	0x4a03502b, 0x88000200, 0x4a03502c, 0x00ff001f,
+	0x4a03502d, 0x000007d0, 0x4a03502e, 0x80000000,
+	0x4a03502f, 0x00000200, 0x4a035030, 0x00ff0000,
+	0x4a035031, 0x00010000, 0x4a03503a, 0x514c4f47,
+	0x4a03503b, 0x49432020, 0x1c01f000, 0x4d440000,
+	0x417a8800, 0x41780800, 0x0201f800, 0x00020245,
+	0x04020005, 0x0201f800, 0x001049e7, 0x04020002,
+	0x80040800, 0x81468800, 0x83440580, 0x000007f0,
+	0x040207f6, 0x5c028800, 0x1c01f000, 0x4803c857,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x0401f809,
+	0x485fc857, 0x4203e000, 0x50000000, 0x5c000000,
+	0x4d780000, 0x4200b800, 0x00008002, 0x0401f006,
+	0x485fc857, 0x4203e000, 0x50000000, 0x4200b800,
+	0x00008002, 0x04006000, 0x4c000000, 0x4c040000,
+	0x59bc00ea, 0x82000500, 0x00000007, 0x82000580,
+	0x00000001, 0x04020005, 0x42000800, 0x00000000,
+	0x0201f800, 0x00106c6c, 0x5c000800, 0x4807c025,
+	0x80040920, 0x4807c026, 0x5c000000, 0x4803c023,
+	0x80000120, 0x4803c024, 0x5c000000, 0x4803c857,
+	0x4803c021, 0x80000120, 0x4803c022, 0x41f80000,
+	0x4803c027, 0x80000120, 0x4803c028, 0x42000000,
+	0x00001000, 0x50000000, 0x82000480, 0x24320001,
+	0x4803c857, 0x0400104f, 0x42000800, 0x00000064,
+	0x80040840, 0x04000007, 0x4a030000, 0x00000001,
+	0x40000000, 0x59800000, 0x8c000500, 0x040007f9,
+	0x04000042, 0x42000800, 0x0010c1a3, 0x46000800,
+	0xfaceface, 0x80040800, 0x42001000, 0x00007a00,
+	0x58080013, 0x44000800, 0x80040800, 0x58080019,
+	0x44000800, 0x80040800, 0x5808001a, 0x44000800,
+	0x80040800, 0x5808001b, 0x44000800, 0x80040800,
+	0x5808001c, 0x44000800, 0x80040800, 0x5808001f,
+	0x44000800, 0x80040800, 0x42001000, 0x00007a40,
+	0x42001800, 0x0000000b, 0x50080000, 0x44000800,
+	0x80081000, 0x80040800, 0x800c1840, 0x040207fb,
+	0x42001800, 0x00000003, 0x42001000, 0x00007b00,
+	0x480c1003, 0x58080005, 0x44000800, 0x80040800,
+	0x800c1840, 0x040217fb, 0x42001000, 0x00007c00,
+	0x58080002, 0x44000800, 0x80040800, 0x58080003,
+	0x44000800, 0x80040800, 0x58080020, 0x44000800,
+	0x80040800, 0x58080021, 0x44000800, 0x80040800,
+	0x58080022, 0x44000800, 0x80040800, 0x58080023,
+	0x44000800, 0x80040800, 0x4a030000, 0x00000000,
+	0x485fc020, 0x905cb9c0, 0x825cbd40, 0x00000012,
+	0x485fc011, 0x4203e000, 0x40000000, 0x4202d800,
+	0x00000005, 0x59e00017, 0x8c000508, 0x04000003,
+	0x4a03c017, 0x00000002, 0x4203e000, 0x30000001,
+	0x0401f81a, 0x0401f7ff, 0x4a03c850, 0x0010c1bf,
+	0x4a03c851, 0x0010d1be, 0x4a03c853, 0x00000800,
+	0x4a03c855, 0x0001eb5a, 0x59e40001, 0x82000540,
+	0x00003f00, 0x4803c801, 0x4a03b104, 0x70000002,
+	0x4a03a804, 0x70000002, 0x4a03b004, 0x70000002,
+	0x42000000, 0x0010b8ec, 0x49780001, 0x49780002,
+	0x1c01f000, 0x1c01f000, 0x59a8006b, 0x8c000530,
+	0x040207fe, 0x4c080000, 0x42001000, 0x00000004,
+	0x0401f862, 0x5c001000, 0x4201d000, 0x00028b0a,
+	0x0201f800, 0x0010608e, 0x4c080000, 0x42001000,
+	0x00000008, 0x0401f859, 0x5c001000, 0x4201d000,
+	0x00028b0a, 0x0201f800, 0x0010608e, 0x4c080000,
+	0x42001000, 0x00000010, 0x0401f850, 0x5c001000,
+	0x4201d000, 0x00028b0a, 0x0201f800, 0x0010608e,
+	0x0401f7e2, 0x8c00050c, 0x59a8086b, 0x04020003,
+	0x84040d30, 0x0401f006, 0x84040d70, 0x4807506b,
+	0x42001000, 0x00000000, 0x0401f040, 0x4807506b,
+	0x836c0500, 0x00000007, 0x0c01f001, 0x001006e1,
+	0x001006c7, 0x001006c7, 0x001006af, 0x001006d4,
+	0x001006c7, 0x001006c7, 0x001006d4, 0x59a80005,
+	0x8c000514, 0x04020013, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00010000, 0x0400000a,
+	0x82040580, 0x00008000, 0x04000004, 0x42001000,
+	0x42004000, 0x0401f006, 0x42001000, 0x22002000,
+	0x0401f003, 0x42001000, 0x12001000, 0x0401f025,
+	0x42001000, 0x00001004, 0x0401f022, 0x59a80005,
+	0x8c000514, 0x04020008, 0x59a8006b, 0x8c000534,
+	0x04020004, 0x42001000, 0x74057005, 0x0401f819,
+	0x1c01f000, 0x42001000, 0x00002008, 0x0401f7fc,
+	0x59a8006b, 0x8c000534, 0x0402000a, 0x59a80005,
+	0x8c000514, 0x04000004, 0x42001000, 0x24052005,
+	0x0401f00c, 0x42001000, 0x74057005, 0x0401f009,
+	0x1c01f000, 0x1c01f000, 0x82081500, 0x0000001c,
+	0x82081540, 0x001c0000, 0x480bc013, 0x1c01f000,
+	0x59a8006b, 0x8c000530, 0x04000002, 0x84081570,
+	0x480b506b, 0x8c000530, 0x04020005, 0x82081500,
+	0x00007000, 0x80081114, 0x0401fff0, 0x1c01f000,
+	0x41780000, 0x50041800, 0x800c0400, 0x80040800,
+	0x80102040, 0x040207fc, 0x80080500, 0x80000540,
+	0x1c01f000, 0x4202f000, 0x00000000, 0x41780000,
+	0x41780800, 0x41781000, 0x41781800, 0x41782000,
+	0x41782800, 0x41783000, 0x41783800, 0x41784000,
+	0x41784800, 0x41785000, 0x41785800, 0x41786000,
+	0x41786800, 0x41787000, 0x41787800, 0x41788000,
+	0x41788800, 0x41789000, 0x41789800, 0x4178a000,
+	0x4178a800, 0x4178b000, 0x4178b800, 0x4178c000,
+	0x4178c800, 0x4178d000, 0x4178d800, 0x4178e000,
+	0x4178e800, 0x4178f000, 0x4178f800, 0x41790000,
+	0x41790800, 0x41791000, 0x41791800, 0x41792000,
+	0x41792800, 0x41793000, 0x41793800, 0x41794000,
+	0x41794800, 0x41795000, 0x41795800, 0x41796000,
+	0x41796800, 0x41797000, 0x41797800, 0x41798000,
+	0x41798800, 0x42019000, 0x0010b537, 0x42019800,
+	0x0010b50e, 0x4179a000, 0x4179b000, 0x4179a800,
+	0x4179b800, 0x4179c800, 0x4179c000, 0x4179d000,
+	0x4179d800, 0x4179e000, 0x4179e800, 0x4179f000,
+	0x4179f800, 0x417a0000, 0x417a0800, 0x417a1000,
+	0x417a1800, 0x417a2000, 0x42022800, 0x00006100,
+	0x417a3000, 0x417a3800, 0x417a4000, 0x417a4800,
+	0x417a5000, 0x417a5800, 0x417a6000, 0x417a6800,
+	0x417a7000, 0x417a7800, 0x417a8000, 0x417a8800,
+	0x417a9000, 0x417a9800, 0x417ae800, 0x417af800,
+	0x42030000, 0x00007c00, 0x42031000, 0x0010b806,
+	0x42031800, 0x0000bf1d, 0x42032000, 0x0000bf32,
+	0x42032800, 0x0010b7ce, 0x42033000, 0x0010b46e,
+	0x42034000, 0x0010b4a4, 0x42033800, 0x0010b4c3,
+	0x42034800, 0x0010b544, 0x42035000, 0x0010b400,
+	0x42035800, 0x0010ac00, 0x42030800, 0x0010b505,
+	0x417b6000, 0x42036800, 0x00006f00, 0x4203c800,
+	0x00003000, 0x42037000, 0x0000ff00, 0x42037800,
+	0x0000bf00, 0x42038000, 0x00007700, 0x42038800,
+	0x00004000, 0x42039000, 0x00006000, 0x42039800,
+	0x0010bedb, 0x4203a000, 0x00007600, 0x4203a800,
+	0x00007400, 0x4203b000, 0x00007200, 0x4203b800,
+	0x00007100, 0x4203c000, 0x00007000, 0x4203d000,
+	0x00000000, 0x4203e800, 0x00101b95, 0x417bd800,
+	0x1c01f000, 0x42000800, 0x00100000, 0x50040000,
+	0x4c000000, 0x42000000, 0x0000aaaa, 0x44000800,
+	0x42001800, 0x00005555, 0x41782000, 0x82102400,
+	0x00010000, 0x40100000, 0x80042c00, 0x440c2800,
+	0x42003000, 0x0000000a, 0x80183040, 0x040207ff,
+	0x50140000, 0x800c0580, 0x04020004, 0x50040000,
+	0x800c0580, 0x040207f2, 0x5c000000, 0x44000800,
+	0x80142840, 0x4817c861, 0x1c01f000, 0x59a8081f,
+	0x800409c0, 0x04020009, 0x49781c0c, 0x4a001a0c,
+	0x00000200, 0x4a001804, 0x07000000, 0x59a80010,
+	0x9c0001c0, 0x48001805, 0x0401fe01, 0x9c0409c0,
+	0x48041806, 0x1c01f000, 0x59a8080c, 0x4006d000,
+	0x4202b800, 0x00000001, 0x59a8180d, 0x480fc857,
+	0x82041400, 0x00000014, 0x82082400, 0x00000014,
+	0x40100000, 0x800c0480, 0x04001006, 0x44080800,
+	0x40080800, 0x40101000, 0x815eb800, 0x0401f7f7,
+	0x45780800, 0x495f5020, 0x1c01f000, 0x835c0480,
+	0x00000020, 0x04001009, 0x496bc857, 0x815eb840,
+	0x416a5800, 0x592ed000, 0x497a5800, 0x497a5801,
+	0x812e59c0, 0x1c01f000, 0x42000000, 0x0010b853,
+	0x0201f800, 0x0010aa47, 0x417a5800, 0x0401f7f9,
+	0x815eb840, 0x04001008, 0x416a5800, 0x492fc857,
+	0x592ed000, 0x497a5800, 0x497a5801, 0x812e59c0,
+	0x1c01f000, 0x42000000, 0x0010b853, 0x0201f800,
+	0x0010aa47, 0x417ab800, 0x417a5800, 0x0401f7f8,
+	0x492fc857, 0x496a5800, 0x412ed000, 0x815eb800,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x1c01f000, 0x492fc857, 0x812e59c0, 0x04000007,
+	0x592c0001, 0x497a5801, 0x4c000000, 0x0401fff1,
+	0x5c025800, 0x0401f7f9, 0x1c01f000, 0x4807c856,
+	0x42007000, 0x0010b7f8, 0x4a007001, 0x00000000,
+	0x59e00003, 0x82000540, 0x00008080, 0x4803c003,
+	0x4a03b805, 0x90000001, 0x59dc0006, 0x4a03b805,
+	0x70000000, 0x59dc0006, 0x4a03b805, 0x30000000,
+	0x4200b000, 0x00000020, 0x497bb807, 0x8058b040,
+	0x040207fe, 0x4a03b805, 0x30000000, 0x59dc0006,
+	0x4a03b805, 0x60000001, 0x59dc0006, 0x4a03b805,
+	0x70000001, 0x59dc0006, 0x4a03b805, 0x30000002,
+	0x4200b000, 0x00000020, 0x497bb807, 0x8058b040,
+	0x040207fe, 0x4a03b805, 0x30000000, 0x59dc0006,
+	0x4a03b805, 0x60000001, 0x0401ffa1, 0x04000da5,
+	0x42001000, 0x0010b7f6, 0x452c1000, 0x4a025801,
+	0x00000001, 0x4a025802, 0x00000100, 0x4a025809,
+	0x00107149, 0x497a580a, 0x497a580b, 0x497a580c,
+	0x0401ff93, 0x04000d97, 0x42001000, 0x0010b7f7,
+	0x452c1000, 0x4a025801, 0x00000000, 0x4a025802,
+	0x00000100, 0x4a025809, 0x001011bc, 0x497a5803,
+	0x497a5807, 0x497a5808, 0x497a580a, 0x59a80005,
+	0x8c00050e, 0x04000006, 0x4a03b805, 0xe0000001,
+	0x59dc0006, 0x8c000522, 0x040007fc, 0x1c01f000,
+	0x4df00000, 0x4203e000, 0x50000000, 0x4c380000,
+	0x40087000, 0x480bc857, 0x4a007002, 0x00000000,
+	0x42007000, 0x0010b7f8, 0x82080400, 0x00000000,
+	0x45780000, 0x58380005, 0x48087005, 0x80000540,
+	0x04000005, 0x82000400, 0x00000000, 0x44080000,
+	0x0401f003, 0x480bc857, 0x48087006, 0x58380001,
+	0x80000540, 0x0400080c, 0x5c007000, 0x5c03e000,
+	0x1c01f000, 0x4c380000, 0x42007000, 0x0010b7f8,
+	0x58380001, 0x80000540, 0x04000803, 0x5c007000,
+	0x1c01f000, 0x42007000, 0x0010b7f8, 0x58380001,
+	0x82000580, 0x00000000, 0x04020012, 0x58380000,
+	0x0c01f001, 0x0010088e, 0x0010088d, 0x0010088d,
+	0x0010088d, 0x0010088d, 0x0010088d, 0x0010088d,
+	0x0010088d, 0x0401fd4b, 0x58380808, 0x800409c0,
+	0x04020024, 0x58380006, 0x80000540, 0x04020002,
+	0x1c01f000, 0x4803c857, 0x48007002, 0x40006800,
+	0x58340000, 0x80000540, 0x04020002, 0x48007005,
+	0x48007006, 0x4a03b805, 0x20000000, 0x59dc0006,
+	0x4a03b805, 0x30000000, 0x58340007, 0x4803b800,
+	0x58340008, 0x4803b801, 0x58340004, 0x48007003,
+	0x58340003, 0x48007004, 0x4803b803, 0x58340001,
+	0x8c000500, 0x04000004, 0x4a007001, 0x00000001,
+	0x0401f028, 0x4a007001, 0x00000002, 0x0401f03d,
+	0x0201f800, 0x001093ea, 0x0201f800, 0x0010a69d,
+	0x04000017, 0x4a03b805, 0x20000000, 0x59dc0006,
+	0x4a03b805, 0x30000000, 0x4807b800, 0x480bb801,
+	0x4a007003, 0x00000010, 0x480c7009, 0x42001000,
+	0x00100875, 0x0201f800, 0x00105f9a, 0x58380008,
+	0x82000400, 0x00000004, 0x48007004, 0x4803b803,
+	0x4a007001, 0x00000007, 0x0401f022, 0x0201f800,
+	0x00109402, 0x42000800, 0x00000001, 0x42001000,
+	0x00100875, 0x0201f800, 0x00105f76, 0x0401f7ba,
+	0x4c040000, 0x4c080000, 0x58380803, 0x42001000,
+	0x00003fff, 0x82040480, 0x00003fff, 0x04021003,
+	0x40041000, 0x80000580, 0x48007003, 0x800800c4,
+	0x4803b802, 0x4a03b805, 0x30000002, 0x59dc0006,
+	0x4a03b805, 0x70000001, 0x59dc0006, 0x4a03b805,
+	0x10000000, 0x5c001000, 0x5c000800, 0x1c01f000,
+	0x483bc857, 0x4c040000, 0x4c080000, 0x58380803,
+	0x42001000, 0x00003fff, 0x82040480, 0x00003fff,
+	0x04021003, 0x40041000, 0x80000580, 0x48007003,
+	0x800800c4, 0x4803b802, 0x4a03b805, 0x10000002,
+	0x5c001000, 0x5c000800, 0x1c01f000, 0x4c040000,
+	0x4c380000, 0x42007000, 0x0010b7f8, 0x59dc0806,
+	0x4807c857, 0x4a03b805, 0x20000000, 0x8c040d3e,
+	0x04000007, 0x8c040d08, 0x04020cca, 0x58380001,
+	0x82000500, 0x00000007, 0x0c01f804, 0x5c007000,
+	0x5c000800, 0x1c01f000, 0x0010087d, 0x0010091e,
+	0x0010092e, 0x001005d8, 0x001005d8, 0x001005d8,
+	0x001005d8, 0x001011ea, 0x4807c856, 0x82040d00,
+	0x43000f80, 0x04020009, 0x58380003, 0x80000540,
+	0x0400001c, 0x59dc0000, 0x4803b800, 0x59dc0001,
+	0x4803b801, 0x0401f7af, 0x58380802, 0x4a000802,
+	0x00000200, 0x0401f01e, 0x4807c856, 0x82040d00,
+	0x43000f80, 0x04020009, 0x58380003, 0x80000540,
+	0x0400000c, 0x59dc0000, 0x4803b800, 0x59dc0001,
+	0x4803b801, 0x0401f7b7, 0x58380002, 0x82000400,
+	0x00000002, 0x46000000, 0x00000200, 0x0401f00c,
+	0x4c340000, 0x58386802, 0x59dc0000, 0x4803c857,
+	0x48006807, 0x59dc0001, 0x4803c857, 0x48006808,
+	0x4a006802, 0x00000100, 0x5c006800, 0x4a007001,
+	0x00000000, 0x4c300000, 0x58386002, 0x0401f80c,
+	0x04000009, 0x58300009, 0x82000c80, 0x0010ab4a,
+	0x04021c84, 0x82000c80, 0x00020000, 0x04001c81,
+	0x0801f800, 0x5c006000, 0x0401f723, 0x4833c857,
+	0x803061c0, 0x04000009, 0x59a8000c, 0x80300480,
+	0x04001007, 0x59a8000d, 0x80300480, 0x04021004,
+	0x82000540, 0x00000001, 0x1c01f000, 0x80000580,
+	0x1c01f000, 0x4803c856, 0x4dc00000, 0x42007000,
+	0x0010b803, 0x4a007400, 0x00000000, 0x49787001,
+	0x42038000, 0x00007720, 0x4a038006, 0x60000001,
+	0x4a038009, 0xf4f60000, 0x42038000, 0x00007700,
+	0x4a038006, 0x60000001, 0x4a038009, 0xf4f60000,
+	0x4a03c822, 0x00000010, 0x4a0370e8, 0x00000000,
+	0x0401f809, 0x4a0370e9, 0x00003a0f, 0x4a0370e8,
+	0x00000000, 0x4a0370e8, 0x00000001, 0x5c038000,
+	0x1c01f000, 0x4c5c0000, 0x4178b800, 0x0401f80a,
+	0x5c00b800, 0x1c01f000, 0x4803c856, 0x4c5c0000,
+	0x825cbd40, 0x00000001, 0x0401f803, 0x5c00b800,
+	0x1c01f000, 0x4803c856, 0x4dc00000, 0x4c500000,
+	0x4c580000, 0x4c540000, 0x4a0370e8, 0x00000000,
+	0x805cb9c0, 0x04000009, 0x4a038807, 0x00000004,
+	0x59b800ea, 0x8c000510, 0x04000004, 0x59b800e0,
+	0x0401f87b, 0x0401f7fb, 0x42038000, 0x00007720,
+	0x0201f800, 0x00100ec1, 0x59c00007, 0x4a038006,
+	0x20000000, 0x59c00007, 0x4a038006, 0x8000000a,
+	0x59c00007, 0x4a038006, 0x8000000b, 0x59c00007,
+	0x4a038006, 0x40000001, 0x83c00580, 0x00007700,
+	0x04000004, 0x42038000, 0x00007700, 0x0401f7ed,
+	0x42038000, 0x00007720, 0x42000800, 0x00000800,
+	0x59c00007, 0x8c00051e, 0x04000006, 0x4a038006,
+	0x90000001, 0x80040840, 0x040207fa, 0x0401fc11,
+	0x83c00580, 0x00007700, 0x04000004, 0x42038000,
+	0x00007700, 0x0401f7f1, 0x805cb9c0, 0x0402001d,
+	0x4200b000, 0x00000020, 0x83b8ac00, 0x00000020,
+	0x0201f800, 0x0010ab20, 0x4a0370fb, 0x00000001,
+	0x4a037020, 0x001010bd, 0x59a80039, 0x82000500,
+	0x0000ffff, 0x48037021, 0x4a037035, 0x0010bddb,
+	0x4a037030, 0x0010b410, 0x4a037031, 0x0010ac00,
+	0x4a037032, 0x0010b519, 0x4a037036, 0x0010b524,
+	0x59840002, 0x48037034, 0x4a037038, 0x001010b4,
+	0x4a0370fb, 0x00000001, 0x4178a000, 0x4200b000,
+	0x00000020, 0x83b8ac00, 0x00000000, 0x0201f800,
+	0x0010ab20, 0x4200b000, 0x00000040, 0x83b8ac00,
+	0x00000040, 0x0201f800, 0x0010ab20, 0x805cb9c0,
+	0x04020004, 0x4a0370e4, 0xaaaaaaaa, 0x0401f003,
+	0x4a0370e4, 0xa2aaaa82, 0x4a0370e5, 0xaaaaaaaa,
+	0x4a0370e6, 0xaaaaaaaa, 0x4a0370fb, 0x00000000,
+	0x4a0370e6, 0xaaaaaaaa, 0x42038000, 0x00007720,
+	0x4a038006, 0x90000000, 0x59c00007, 0x8c00051e,
+	0x02020800, 0x001005d8, 0x42038000, 0x00007700,
+	0x4a038006, 0x90000000, 0x59c00007, 0x8c00051e,
+	0x02020800, 0x001005d8, 0x5c00a800, 0x5c00b000,
+	0x5c00a000, 0x5c038000, 0x1c01f000, 0x4d300000,
+	0x4d380000, 0x40026000, 0x82000500, 0x7f000000,
+	0x82000580, 0x00000003, 0x0402000f, 0x83326500,
+	0x00ffffff, 0x59300203, 0x82000580, 0x00000004,
+	0x04020009, 0x59300c06, 0x82040580, 0x00000009,
+	0x04020005, 0x42027000, 0x00000047, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x5c026000, 0x1c01f000,
+	0x4d300000, 0x4d2c0000, 0x4d340000, 0x4d400000,
+	0x4cfc0000, 0x4d380000, 0x4d3c0000, 0x4d440000,
+	0x4d4c0000, 0x4d480000, 0x4c5c0000, 0x4c600000,
+	0x4c640000, 0x4cc80000, 0x4ccc0000, 0x4cf00000,
+	0x4cf40000, 0x4cf80000, 0x4cfc0000, 0x4d000000,
+	0x4d040000, 0x0201f800, 0x00020015, 0x5c020800,
+	0x5c020000, 0x5c01f800, 0x5c01f000, 0x5c01e800,
+	0x5c01e000, 0x5c019800, 0x5c019000, 0x5c00c800,
+	0x5c00c000, 0x5c00b800, 0x5c029000, 0x5c029800,
+	0x5c028800, 0x5c027800, 0x5c027000, 0x5c01f800,
+	0x5c028000, 0x5c026800, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x493bc857, 0x0201f000, 0x00020044,
+	0x83300500, 0x1f000000, 0x04000008, 0x81326580,
+	0x80000130, 0x82000c80, 0x00000014, 0x02021800,
+	0x001005d8, 0x0c01f013, 0x83300500, 0x000000ff,
+	0x82000c80, 0x00000007, 0x02021800, 0x001005d8,
+	0x0c01f025, 0x1c01f000, 0x82000d00, 0xc0000038,
+	0x02020800, 0x001005d0, 0x0201f800, 0x001005d8,
+	0x00000000, 0x00000048, 0x00000054, 0x00000053,
+	0x00100a9b, 0x00100abf, 0x00100aba, 0x00100adf,
+	0x00100aa6, 0x00100ab2, 0x00100a9b, 0x00100ada,
+	0x00100b1a, 0x00100a9b, 0x00100a9b, 0x00100a9b,
+	0x00100a9b, 0x00100b1d, 0x00100b23, 0x00100b34,
+	0x00100b45, 0x00100a9b, 0x00100b4e, 0x00100b5a,
+	0x00100a9b, 0x00100a9b, 0x00100a9b, 0x0201f800,
+	0x001005d8, 0x00100aa4, 0x00100bff, 0x00100aec,
+	0x00100b0f, 0x00100aa4, 0x00100aa4, 0x00100aa4,
+	0x0201f800, 0x001005d8, 0x4803c856, 0x59300004,
+	0x8c00053e, 0x04020005, 0x42027000, 0x00000055,
+	0x0201f000, 0x000207a1, 0x0201f800, 0x00106f60,
+	0x040007fa, 0x1c01f000, 0x4803c856, 0x0401f8a9,
+	0x40002800, 0x41782000, 0x42027000, 0x00000056,
+	0x0201f000, 0x000207a1, 0x4803c856, 0x42027000,
+	0x00000057, 0x0201f000, 0x000207a1, 0x4803c856,
+	0x59300007, 0x8c00051a, 0x04020010, 0x59325808,
+	0x812e59c0, 0x04000014, 0x592c0408, 0x8c00051c,
+	0x04020003, 0x4a026011, 0xffffffff, 0x59300004,
+	0x8c00053e, 0x04020009, 0x42027000, 0x00000048,
+	0x0201f000, 0x000207a1, 0x59325808, 0x4a025a06,
+	0x00000007, 0x0401f7f4, 0x0201f800, 0x00106f60,
+	0x040007f6, 0x1c01f000, 0x4803c856, 0x83300500,
+	0x00ffffff, 0x0201f000, 0x001064d7, 0x1c01f000,
+	0x4c040000, 0x59b808ea, 0x82040d00, 0x00000007,
+	0x82040580, 0x00000003, 0x04000004, 0x42000000,
+	0x60000000, 0x0401f8ab, 0x5c000800, 0x1c01f000,
+	0x0401f8f9, 0x59325808, 0x812e59c0, 0x04000018,
+	0x592c0204, 0x82000500, 0x000000ff, 0x82000d80,
+	0x00000029, 0x04020012, 0x59300203, 0x82000580,
+	0x00000003, 0x0400000b, 0x59300807, 0x84040d26,
+	0x48066007, 0x0201f800, 0x00020086, 0x4a03900d,
+	0x00000040, 0x4a0370e5, 0x00000008, 0x1c01f000,
+	0x0201f800, 0x00106f60, 0x040007f4, 0x59880052,
+	0x80000000, 0x48031052, 0x4a03900d, 0x00000040,
+	0x42000000, 0xc0000000, 0x0401f05a, 0x42007800,
+	0x0010bde2, 0x42002000, 0x00003000, 0x42003000,
+	0x00000105, 0x0201f800, 0x00105e04, 0x4a0370e4,
+	0x02000000, 0x1c01f000, 0x4933c857, 0x0201f000,
+	0x0002077d, 0x41300800, 0x800409c0, 0x02020800,
+	0x001005d8, 0x0201f800, 0x001005d0, 0x4933c857,
+	0x813261c0, 0x02000800, 0x001005d8, 0x0401f835,
+	0x40002800, 0x0201f800, 0x0010a99c, 0x0401f8ae,
+	0x04000007, 0x59326809, 0x59340200, 0x8c00050e,
+	0x59300414, 0x02020800, 0x001092ce, 0x1c01f000,
+	0x4933c857, 0x813261c0, 0x02000800, 0x001005d8,
+	0x0401f8a1, 0x0400000b, 0x59325808, 0x0201f800,
+	0x00109037, 0x04000007, 0x592c0208, 0x8400054e,
+	0x48025a08, 0x417a7800, 0x0201f800, 0x00108be3,
+	0x1c01f000, 0x485fc857, 0x5c000000, 0x4d780000,
+	0x4203e000, 0x50000000, 0x4200b800, 0x00008005,
+	0x0201f000, 0x001005dd, 0x4933c857, 0x83300480,
+	0x00000020, 0x02021800, 0x001005d8, 0x83300c00,
+	0x0010b8cc, 0x50040000, 0x80000000, 0x04001002,
+	0x44000800, 0x1c01f000, 0x4933c857, 0x0401f7f4,
+	0x4807c856, 0x59b800ea, 0x8c000510, 0x040007fd,
+	0x59b800e0, 0x4803c857, 0x1c01f000, 0x4803c856,
+	0x42000000, 0x10000000, 0x41300800, 0x0401f02d,
+	0x82000500, 0xf0000000, 0x82040d00, 0x0fffffff,
+	0x80040d40, 0x4807c857, 0x59b800ea, 0x8c000516,
+	0x04020003, 0x480770e1, 0x1c01f000, 0x8c000510,
+	0x040007fa, 0x4c040000, 0x0401f809, 0x5c000800,
+	0x82100480, 0x00000008, 0x040017f4, 0x4c040000,
+	0x0401febc, 0x5c000800, 0x0401f7f0, 0x59b800e2,
+	0x59b820e2, 0x80100580, 0x040207fd, 0x80102114,
+	0x0401f006, 0x59b800e2, 0x59b820e2, 0x80100580,
+	0x040207fd, 0x0401f001, 0x40101800, 0x800c190a,
+	0x82100500, 0x0000001f, 0x820c1d00, 0x0000001f,
+	0x800c2480, 0x82102500, 0x0000001f, 0x1c01f000,
+	0x82000500, 0xf0000000, 0x82040d00, 0x0fffffff,
+	0x80040d40, 0x4807c857, 0x42001000, 0x0010b804,
+	0x50080000, 0x80000540, 0x04020005, 0x4a0370e5,
+	0x00000003, 0x4a0370e4, 0x00000300, 0x80000000,
+	0x44001000, 0x42001000, 0x00000400, 0x59b800ea,
+	0x8c000510, 0x0400000c, 0x0401ffd5, 0x82100480,
+	0x00000008, 0x04001007, 0x4c040000, 0x4c080000,
+	0x0401fe88, 0x5c001000, 0x5c000800, 0x0401f020,
+	0x59b800ea, 0x8c000516, 0x0402001d, 0x4a0370e4,
+	0x00300000, 0x480770e1, 0x42001000, 0x0000ff00,
+	0x80081040, 0x04000012, 0x59b808e4, 0x8c040d28,
+	0x040207fc, 0x42001000, 0x0010b804, 0x50080000,
+	0x80000040, 0x04020005, 0x4a0370e5, 0x00000002,
+	0x4a0370e4, 0x00000200, 0x02001800, 0x001005d8,
+	0x44001000, 0x8c040d2c, 0x1c01f000, 0x41f80000,
+	0x50000000, 0x0201f800, 0x001005d8, 0x80081040,
+	0x040207d3, 0x41f80000, 0x50000000, 0x0201f800,
+	0x001005d8, 0x4d380000, 0x59300c06, 0x82040580,
+	0x00000009, 0x04020006, 0x42027000, 0x00000047,
+	0x0201f800, 0x000207a1, 0x80000580, 0x5c027000,
+	0x1c01f000, 0x4c500000, 0x4a03900d, 0x00000001,
+	0x59c8a020, 0x4a03900d, 0x00000002, 0x59c80820,
+	0x8c50a52e, 0x04000002, 0x900409c0, 0x82040d00,
+	0x0000ffff, 0x0201f800, 0x00105dd7, 0x02000800,
+	0x001005d8, 0x4933c857, 0x8250a500, 0xff000000,
+	0x82500580, 0x05000000, 0x04000003, 0x82000540,
+	0x00000001, 0x5c00a000, 0x1c01f000, 0x0401ffe6,
+	0x4933c857, 0x59300406, 0x82000580, 0x00000000,
+	0x04000040, 0x59c82021, 0x4a03900d, 0x00000001,
+	0x59c82821, 0x82142d00, 0x0000ffff, 0x59325808,
+	0x812e59c0, 0x04000037, 0x59326809, 0x0201f800,
+	0x001048d9, 0x02020800, 0x001092b6, 0x599c0019,
+	0x8c00050c, 0x04020018, 0x0201f800, 0x001048d9,
+	0x04020015, 0x59300811, 0x4807c857, 0x592c0408,
+	0x8c00051c, 0x0402000e, 0x8400055c, 0x48025c08,
+	0x592c0a04, 0x82040d00, 0x000000ff, 0x82040580,
+	0x00000048, 0x04000004, 0x82040580, 0x00000018,
+	0x04020003, 0x59300811, 0x48065803, 0x4a026011,
+	0x7fffffff, 0x48166013, 0x0201f800, 0x001010dd,
+	0x04020014, 0x0401f9fd, 0x40280000, 0x4802600d,
+	0x04000005, 0x4832600b, 0x50200000, 0x4802600a,
+	0x4822600c, 0x59300414, 0x8c00051c, 0x04020004,
+	0x599c0019, 0x8c00050c, 0x0402086e, 0x4a03900d,
+	0x00000040, 0x4a0370e5, 0x00000008, 0x1c01f000,
+	0x59880052, 0x80000000, 0x48031052, 0x4a03900d,
+	0x00000040, 0x42000000, 0xc0000000, 0x0401f71d,
+	0x4cf80000, 0x58f40000, 0x8001f540, 0x0401f820,
+	0x41781800, 0x0401f8e4, 0x04020014, 0x44140800,
+	0x0401f82a, 0x04000011, 0x40043800, 0x42001800,
+	0x00000001, 0x40142000, 0x0401f8db, 0x0402000b,
+	0x801c3800, 0x501c0000, 0x44000800, 0x0401f810,
+	0x801c0580, 0x04000004, 0x44103800, 0x801c3840,
+	0x44143800, 0x0401f819, 0x5c01f000, 0x1c01f000,
+	0x80f9f1c0, 0x04020003, 0x58f41202, 0x0401f003,
+	0x42001000, 0x00000007, 0x1c01f000, 0x80f9f1c0,
+	0x04020006, 0x58f40401, 0x82000480, 0x00000002,
+	0x80f40400, 0x0401f005, 0x58f80401, 0x82000480,
+	0x00000002, 0x80f80400, 0x50002800, 0x80000000,
+	0x50002000, 0x1c01f000, 0x80f9f1c0, 0x04020008,
+	0x58f40401, 0x82000480, 0x00000002, 0x02001800,
+	0x001005d8, 0x4801ec01, 0x0401f00b, 0x58f80401,
+	0x82000480, 0x00000002, 0x02001800, 0x001005d8,
+	0x4801f401, 0x82000580, 0x00000002, 0x04020002,
+	0x0401f809, 0x58f40202, 0x80000040, 0x4801ea02,
+	0x02000800, 0x001005d8, 0x82000580, 0x00000001,
+	0x1c01f000, 0x4d2c0000, 0x40fa5800, 0x0201f800,
+	0x001007f4, 0x4979e800, 0x4179f000, 0x5c025800,
+	0x1c01f000, 0x80f5e9c0, 0x04000009, 0x80f9f1c0,
+	0x04020ff5, 0x4d2c0000, 0x40f65800, 0x0201f800,
+	0x001007f4, 0x4179e800, 0x5c025800, 0x1c01f000,
+	0x4cf40000, 0x59300807, 0x82040500, 0x00003100,
+	0x04020032, 0x8c040d22, 0x04000032, 0x5930001f,
+	0x8001ed40, 0x02000800, 0x001005d8, 0x82000580,
+	0xffffffff, 0x04000029, 0x58f40201, 0x82000580,
+	0x0000dcb3, 0x02020800, 0x001005d8, 0x58f40a02,
+	0x82040500, 0x0000fffe, 0x04000003, 0x0401ff89,
+	0x58f40a02, 0x82040480, 0x0000000f, 0x04021059,
+	0x80040800, 0x4805ea02, 0x82040580, 0x00000008,
+	0x0400005d, 0x82040480, 0x00000008, 0x0400100a,
+	0x58f40000, 0x8001ed40, 0x02000800, 0x001005d8,
+	0x58f40201, 0x82000580, 0x0000ddb9, 0x02020800,
+	0x001005d8, 0x58f40401, 0x82000c00, 0x00000002,
+	0x4805ec01, 0x80f40400, 0x59300812, 0x44040000,
+	0x80000000, 0x45780000, 0x5c01e800, 0x1c01f000,
+	0x42001000, 0x00000400, 0x59b800e4, 0x8c000524,
+	0x04020023, 0x4a0370e4, 0x00030000, 0x40000000,
+	0x59b800e4, 0x8c000524, 0x0402001b, 0x59300807,
+	0x84040d62, 0x48066007, 0x4a0370e4, 0x00020000,
+	0x4d2c0000, 0x0201f800, 0x001007d3, 0x04000025,
+	0x492e601f, 0x4a025a01, 0x0000dcb3, 0x59300008,
+	0x80001d40, 0x02000800, 0x001005d8, 0x580c080f,
+	0x48065803, 0x59301811, 0x40040000, 0x800c0580,
+	0x0402000d, 0x497a5a02, 0x4a025c01, 0x00000004,
+	0x0401f011, 0x4a0370e4, 0x00020000, 0x40000000,
+	0x40000000, 0x80081040, 0x02000800, 0x001005d8,
+	0x0401f7d6, 0x4a025a02, 0x00000001, 0x4a025c01,
+	0x00000006, 0x497a5804, 0x400c0000, 0x80040480,
+	0x48025805, 0x412de800, 0x5c025800, 0x0401f7a9,
+	0x5c025800, 0x4a02601f, 0xffffffff, 0x0401f7c3,
+	0x4d2c0000, 0x58f65800, 0x0201f800, 0x001007f4,
+	0x40f65800, 0x0201f800, 0x001007f4, 0x5c025800,
+	0x0401f7f5, 0x4d2c0000, 0x0201f800, 0x001007d3,
+	0x040007f8, 0x4a025a01, 0x0000ddb9, 0x4a025c01,
+	0x00000002, 0x492de800, 0x412de800, 0x5c025800,
+	0x0401f7a5, 0x0401ff33, 0x82f40400, 0x00000004,
+	0x800c0400, 0x40000800, 0x50040000, 0x80100580,
+	0x04000016, 0x82040c00, 0x00000002, 0x80081040,
+	0x040207fa, 0x80f9f1c0, 0x04000011, 0x58f41202,
+	0x82081480, 0x00000007, 0x82f80400, 0x00000002,
+	0x800c0400, 0x40000800, 0x50040000, 0x80100580,
+	0x04000006, 0x82040c00, 0x00000002, 0x80081040,
+	0x040207fa, 0x0401f002, 0x1c01f000, 0x82000540,
+	0x00000001, 0x0401f7fd, 0x4cf40000, 0x4cf80000,
+	0x4001e800, 0x592c0a06, 0x800409c0, 0x0402001d,
+	0x82f40580, 0xffffffff, 0x04000017, 0x58f40201,
+	0x82000580, 0x0000dcb3, 0x02020800, 0x001005d8,
+	0x58f40000, 0x8001f540, 0x04000006, 0x58f80201,
+	0x82000580, 0x0000ddb9, 0x02020800, 0x001005d8,
+	0x41783800, 0x0401f839, 0x04020006, 0x0401ff32,
+	0x497a601f, 0x5c01f000, 0x5c01e800, 0x1c01f000,
+	0x0401ff2d, 0x4a025a06, 0x00000011, 0x0401f7f9,
+	0x82f40580, 0xffffffff, 0x04020f27, 0x0401f7f5,
+	0x4cf40000, 0x4cf80000, 0x4001e800, 0x82040580,
+	0x00000001, 0x0402001f, 0x82f40580, 0xffffffff,
+	0x04000019, 0x58f40201, 0x82000580, 0x0000dcb3,
+	0x02020800, 0x001005d8, 0x58f40000, 0x8001f540,
+	0x04000006, 0x58f80201, 0x82000580, 0x0000ddb9,
+	0x02020800, 0x001005d8, 0x41783800, 0x0401f813,
+	0x04020008, 0x0401ff0c, 0x42000800, 0x00000001,
+	0x497a601f, 0x5c01f000, 0x5c01e800, 0x1c01f000,
+	0x0401ff05, 0x42000800, 0x00000011, 0x0401f7f9,
+	0x4c040000, 0x82f40580, 0xffffffff, 0x04020efe,
+	0x5c000800, 0x0401f7f3, 0x4803c856, 0x401c2000,
+	0x41781800, 0x0401ff8c, 0x0402002c, 0x58f42003,
+	0x42001800, 0x00000001, 0x0401ff87, 0x04020027,
+	0x0401feb8, 0x40082800, 0x82f40400, 0x00000004,
+	0x40003000, 0x50182000, 0x40100000, 0x801c0580,
+	0x04000005, 0x42001800, 0x00000001, 0x0401ff7a,
+	0x0402001a, 0x82183400, 0x00000002, 0x80142840,
+	0x040207f5, 0x80f9f1c0, 0x04000013, 0x58f42a02,
+	0x82142c80, 0x00000007, 0x82f80400, 0x00000003,
+	0x40003000, 0x50182000, 0x40100000, 0x801c0580,
+	0x04000005, 0x42001800, 0x00000001, 0x0401ff66,
+	0x04020006, 0x82183400, 0x00000002, 0x80142840,
+	0x040207f5, 0x1c01f000, 0x82000540, 0x00000001,
+	0x0401f7fd, 0x0201f800, 0x001005d8, 0x58380207,
+	0x8c000502, 0x040007fc, 0x50200000, 0x80387c00,
+	0x583c2800, 0x583c2001, 0x58380404, 0x80001540,
+	0x04020002, 0x58381407, 0x58c83401, 0x58380c08,
+	0x59303807, 0x497a6012, 0x497a6013, 0x0201f000,
+	0x000200be, 0x592c0408, 0x8c000502, 0x040007ea,
+	0x592c0409, 0x80000540, 0x040007e7, 0x82000c80,
+	0x00000002, 0x04001011, 0x58380001, 0x80007540,
+	0x02000800, 0x001005d8, 0x58380204, 0x82000500,
+	0x0000000f, 0x82000400, 0x001010bd, 0x50004000,
+	0x40040000, 0x800409c0, 0x04000005, 0x82040c80,
+	0x00000005, 0x040217f1, 0x80204400, 0x50200000,
+	0x80387c00, 0x583c2800, 0x583c2001, 0x583c1002,
+	0x592c0a07, 0x592c4c08, 0x592c300d, 0x59303807,
+	0x497a6012, 0x497a6013, 0x4816600e, 0x4812600f,
+	0x480a6010, 0x481a6011, 0x80040840, 0x4806600d,
+	0x02000000, 0x000200c6, 0x80204000, 0x50201800,
+	0x800c19c0, 0x0402000c, 0x58380001, 0x80007540,
+	0x02000800, 0x001005d8, 0x58380204, 0x82000500,
+	0x0000000f, 0x82000400, 0x001010bd, 0x50004000,
+	0x50201800, 0x483a600b, 0x480e600a, 0x4822600c,
+	0x0201f000, 0x000200c6, 0x4803c856, 0x592c0208,
+	0x8c00051e, 0x04020017, 0x50200000, 0x80306c00,
+	0x40240000, 0x0c01f001, 0x00100e46, 0x00100e46,
+	0x00100e4f, 0x00100e46, 0x00100e46, 0x00100e46,
+	0x00100e46, 0x00100e46, 0x00100e4f, 0x00100e46,
+	0x00100e4f, 0x00100e46, 0x00100e46, 0x00100e4f,
+	0x00100e46, 0x00100e46, 0x0201f800, 0x001005d8,
+	0x8400051e, 0x48025a08, 0x50200000, 0x80306c00,
+	0x58343801, 0x481e600f, 0x0401f007, 0x58341802,
+	0x58342800, 0x58343801, 0x480e6010, 0x4816600e,
+	0x481e600f, 0x0401f246, 0x4933c857, 0x5931f808,
+	0x59300a06, 0x800409c0, 0x04000005, 0x80040906,
+	0x04020002, 0x80040800, 0x4805fc06, 0x4a026206,
+	0x00000002, 0x592c0409, 0x82000500, 0x00000008,
+	0x0400000b, 0x0401f834, 0x59300203, 0x82000580,
+	0x00000004, 0x04020005, 0x42027000, 0x00000048,
+	0x0201f800, 0x000207a1, 0x1c01f000, 0x4cfc0000,
+	0x58fc0204, 0x82000500, 0x000000ff, 0x82000580,
+	0x00000048, 0x0402000c, 0x58fc000b, 0x800001c0,
+	0x04000009, 0x58fc0407, 0x800001c0, 0x04000006,
+	0x58fc080b, 0x8c040d16, 0x04000017, 0x58fc0007,
+	0x0401f00a, 0x58fc0408, 0x8c000512, 0x04020014,
+	0x58fc0c09, 0x8c040d16, 0x04020003, 0x5c01f800,
+	0x1c01f000, 0x58fc000a, 0x59300811, 0x80040580,
+	0x04020009, 0x59300007, 0x84000500, 0x48026007,
+	0x42027000, 0x00000048, 0x5c01f800, 0x0201f000,
+	0x000207a1, 0x5c01f800, 0x1c01f000, 0x58fdf809,
+	0x0401f7ec, 0x4933c857, 0x59b808ea, 0x82040d00,
+	0x00000007, 0x82040580, 0x00000000, 0x0400001e,
+	0x82040580, 0x00000003, 0x0400001b, 0x59300406,
+	0x4c000000, 0x4a026406, 0x00000000, 0x42003000,
+	0x00000041, 0x42000000, 0x50000000, 0x41300800,
+	0x4c180000, 0x0401fce7, 0x5c003000, 0x0400000b,
+	0x42000000, 0x0000001e, 0x80000040, 0x040207ff,
+	0x80183040, 0x040207f4, 0x42000000, 0x40000000,
+	0x41300800, 0x0401fcdb, 0x5c000000, 0x48026406,
+	0x1c01f000, 0x59300007, 0x84000500, 0x48026007,
+	0x0401f7fc, 0x59c00007, 0x4a038006, 0x30000000,
+	0x40000000, 0x59c00007, 0x8c00050a, 0x040207fe,
+	0x1c01f000, 0x5c000000, 0x4c000000, 0x4803c857,
+	0x4dc00000, 0x4a0370e8, 0x00000000, 0x42038000,
+	0x00007720, 0x0401fff0, 0x42038000, 0x00007700,
+	0x0401ffed, 0x0201f800, 0x0010513b, 0x04020013,
+	0x4a038891, 0x0000ffff, 0x497b8880, 0x497b8892,
+	0x42001000, 0x00000190, 0x40000000, 0x40000000,
+	0x80081040, 0x040207fd, 0x42000000, 0x0010b8a6,
+	0x0201f800, 0x0010aa47, 0x0401f80e, 0x5c038000,
+	0x0201f000, 0x00105258, 0x0401f82d, 0x42000000,
+	0x0010b8a7, 0x0201f800, 0x0010aa47, 0x0401f805,
+	0x48178892, 0x480b8880, 0x5c038000, 0x1c01f000,
+	0x496fc857, 0x836c0580, 0x00000003, 0x0402000b,
+	0x4c080000, 0x4c0c0000, 0x42001000, 0x00008048,
+	0x42001800, 0x0000ffff, 0x0201f800, 0x00103a3e,
+	0x5c001800, 0x5c001000, 0x42000800, 0x0000003c,
+	0x0201f800, 0x00101345, 0x59a8006c, 0x80000540,
+	0x04000006, 0x59a8106d, 0x800811c0, 0x04000003,
+	0x0201f800, 0x00101aaf, 0x4a038891, 0x0000ffff,
+	0x4a03900d, 0x00000040, 0x0201f800, 0x0010098e,
+	0x4a0370e8, 0x00000001, 0x1c01f000, 0x5c000000,
+	0x4c000000, 0x4803c857, 0x59c41080, 0x497b8880,
+	0x59c42892, 0x497b8892, 0x0201f800, 0x0010513b,
+	0x04020002, 0x1c01f000, 0x42002000, 0x00000260,
+	0x59c418a4, 0x820c1d00, 0x0000000f, 0x820c0580,
+	0x00000000, 0x04000010, 0x59c41805, 0x820c1d00,
+	0x00000001, 0x0402000e, 0x59c418a4, 0x820c1d00,
+	0x0000000f, 0x820c0480, 0x00000007, 0x04001004,
+	0x820c0480, 0x0000000c, 0x04001003, 0x80102040,
+	0x040207ec, 0x497b8891, 0x1c01f000, 0x4c100000,
+	0x42002000, 0x00000019, 0x46000000, 0x00000001,
+	0x0201f800, 0x00101937, 0x50001800, 0x820c1d00,
+	0x00000001, 0x04000005, 0x80102040, 0x040207f7,
+	0x5c002000, 0x0401f7f0, 0x5c002000, 0x0401f7ec,
+	0x4803c856, 0x1c01f000, 0x4d2c0000, 0x59325808,
+	0x592c0a04, 0x4807c857, 0x82040d00, 0x000000ff,
+	0x82040500, 0x0000000f, 0x0c01f001, 0x00100f67,
+	0x00100f67, 0x00100f67, 0x00100f7f, 0x00100f67,
+	0x00100f67, 0x00100f67, 0x00100f67, 0x00100f67,
+	0x00100f7f, 0x00100f67, 0x00100f69, 0x00100f67,
+	0x00100f67, 0x00100f67, 0x00100f67, 0x0201f800,
+	0x001005d8, 0x82040580, 0x0000003b, 0x02020800,
+	0x001005d8, 0x592c020a, 0x8c000500, 0x0400005f,
+	0x592c1a07, 0x82040500, 0x0000000f, 0x82000400,
+	0x001010bd, 0x50001000, 0x50080000, 0x59302013,
+	0x4802600a, 0x492e600b, 0x480a600c, 0x480e600d,
+	0x48126012, 0x5c025800, 0x1c01f000, 0x82040500,
+	0x0000000f, 0x82000400, 0x001010bd, 0x50001000,
+	0x50080000, 0x592c1a07, 0x4802600a, 0x492e600b,
+	0x480a600c, 0x480e600d, 0x497a6012, 0x0401f7f2,
+	0x8c040d00, 0x04020041, 0x82040d00, 0x00000080,
+	0x0400003e, 0x0201f000, 0x000200cf, 0x59300013,
+	0x59301012, 0x80080580, 0x0402000c, 0x42007800,
+	0x80000005, 0x592c1208, 0x82080500, 0xffff7fff,
+	0x48025a08, 0x8c08151e, 0x0402002d, 0x823c7d40,
+	0x00000020, 0x0401f02a, 0x480bc857, 0x42000000,
+	0x0010b851, 0x0201f800, 0x0010aa47, 0x59300414,
+	0x4803c857, 0x8c000514, 0x04020007, 0x599c1819,
+	0x8c0c1d12, 0x04020004, 0x820c1d40, 0x00000001,
+	0x0401f01d, 0x59302013, 0x0401f92b, 0x0402001a,
+	0x42007800, 0x80000005, 0x5930500d, 0x592c0208,
+	0x4803c857, 0x8c00051e, 0x04020005, 0x823c7d40,
+	0x00000020, 0x5930400c, 0x0401f004, 0x8400051e,
+	0x48025a08, 0x0401f8da, 0x50201800, 0x480e600a,
+	0x4832600b, 0x4822600c, 0x482a600d, 0x480fc857,
+	0x4833c857, 0x4823c857, 0x482bc857, 0x80000580,
+	0x483e6004, 0x1c01f000, 0x0201f800, 0x001005d8,
+	0x4933c857, 0x4d2c0000, 0x59900004, 0x81300580,
+	0x02020800, 0x001005d8, 0x0201f800, 0x00109037,
+	0x02000800, 0x001005d8, 0x59325808, 0x4d3c0000,
+	0x4d400000, 0x59300004, 0x4803c857, 0x4c000000,
+	0x0201f800, 0x00106dc3, 0x0201f800, 0x00106b8a,
+	0x5c000000, 0x8c000516, 0x04000010, 0x592c000f,
+	0x4803c857, 0x48025807, 0x41780800, 0x42028000,
+	0x00000002, 0x0201f800, 0x00104e70, 0x4a025c06,
+	0x0000ffff, 0x0201f800, 0x000202da, 0x0201f800,
+	0x00107911, 0x0401f015, 0x4a026203, 0x00000002,
+	0x592c0208, 0x8400054e, 0x48025a08, 0x59300406,
+	0x82000580, 0x00000006, 0x04020009, 0x811800ca,
+	0x81c80c00, 0x58040939, 0x592c000d, 0x80040480,
+	0x592c080f, 0x80040480, 0x4802580b, 0x417a7800,
+	0x0201f800, 0x00108be3, 0x5c028000, 0x5c027800,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4d2c0000,
+	0x59900004, 0x81300580, 0x02020800, 0x001005d8,
+	0x0201f800, 0x00109037, 0x02000800, 0x001005d8,
+	0x59325808, 0x592c0208, 0x84000540, 0x48025a08,
+	0x0401f7bf, 0x491bc857, 0x49d3c857, 0x4dd00000,
+	0x41780800, 0x8007a0ca, 0x83d3a400, 0x00007600,
+	0x4a03a005, 0x80000002, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24220001, 0x04020029,
+	0x59d01006, 0x82080500, 0x00006000, 0x82000580,
+	0x00006000, 0x0400002f, 0x82080500, 0x40008000,
+	0x040007f8, 0x800409c0, 0x0402002a, 0x811a31c0,
+	0x04000028, 0x42000000, 0x00001002, 0x50001000,
+	0x46000000, 0x00000512, 0x42001800, 0x0000000a,
+	0x59e00000, 0x8c00051a, 0x040207fc, 0x800c1840,
+	0x040207fc, 0x42000000, 0x00001002, 0x46000000,
+	0x00000514, 0x42001800, 0x0000000a, 0x59e00000,
+	0x8c00053a, 0x040207fc, 0x800c1840, 0x040207fc,
+	0x42000000, 0x00001002, 0x44080000, 0x0401f00d,
+	0x59d01006, 0x82080500, 0x00006000, 0x82000580,
+	0x00006000, 0x04000007, 0x8c08151e, 0x040007f9,
+	0x59d01006, 0x82080500, 0x00006000, 0x040207f5,
+	0x83d3a400, 0x00000020, 0x80040800, 0x82040480,
+	0x00000005, 0x040017bf, 0x5c03a000, 0x1c01f000,
+	0x491bc857, 0x49d3c857, 0x4dd00000, 0x41780800,
+	0x8007a0ca, 0x83d3a400, 0x00007600, 0x4a03a005,
+	0x80000001, 0x59d00006, 0x83d3a400, 0x00000020,
+	0x80040800, 0x82040480, 0x00000005, 0x040017f8,
+	0x5c03a000, 0x1c01f000, 0x59d00006, 0x8c00053e,
+	0x0400001e, 0x59902804, 0x4817c857, 0x801429c0,
+	0x04000013, 0x5990000a, 0x5990080b, 0x5990100c,
+	0x5990180d, 0x4800280a, 0x4804280b, 0x4808280c,
+	0x480c280d, 0x59d00000, 0x59d00801, 0x59d01002,
+	0x59d01803, 0x59d02004, 0x4800280e, 0x4804280f,
+	0x48082810, 0x480c2811, 0x48102812, 0x59900006,
+	0x82000500, 0xffff0000, 0x48032006, 0x4a03a005,
+	0x30000000, 0x59d00006, 0x1c01f000, 0x4803c856,
+	0x80204000, 0x50200000, 0x80000540, 0x04000003,
+	0x80285040, 0x1c01f000, 0x58300001, 0x80000540,
+	0x0400000e, 0x4802600b, 0x40006000, 0x58300204,
+	0x82000500, 0x0000000f, 0x82000400, 0x001010bd,
+	0x50004000, 0x802041c0, 0x02000800, 0x001005d8,
+	0x80285040, 0x1c01f000, 0x40005000, 0x1c01f000,
+	0x00000005, 0x00000008, 0x0000000b, 0x0000000e,
+	0x00000011, 0x00000000, 0x00000000, 0x0000000b,
+	0x00000000, 0x00000000, 0x00000000, 0x001010b8,
+	0x001010b7, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x001010b8, 0x001010b7, 0x001010b4,
+	0x001010b8, 0x001010b7, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x001010b8,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x001010b8, 0x001010b8, 0x001010b8,
+	0x00000000, 0x001010b8, 0x00000000, 0x00000000,
+	0x00000000, 0x4813c857, 0x492fc857, 0x4933c857,
+	0x48126012, 0x592c5207, 0x802851c0, 0x0400004a,
+	0x412c6000, 0x0401f84b, 0x04000009, 0x82240580,
+	0x00000002, 0x04020003, 0x5830000d, 0x80102480,
+	0x50200000, 0x80004540, 0x0400003f, 0x50200000,
+	0x80000540, 0x0400000b, 0x80301400, 0x58080002,
+	0x80102480, 0x0400101e, 0x801021c0, 0x04000009,
+	0x80285040, 0x04000034, 0x80204000, 0x0401f7f4,
+	0x58300001, 0x80006540, 0x0400002f, 0x0401f7e6,
+	0x80285040, 0x0400002c, 0x80204000, 0x50200000,
+	0x80000540, 0x0402000a, 0x58300001, 0x80006540,
+	0x04000025, 0x58300204, 0x82004d00, 0x0000000f,
+	0x82244400, 0x001010bd, 0x50204000, 0x592c0208,
+	0x8400051e, 0x48025a08, 0x0401f013, 0x80102080,
+	0x80102000, 0x48126010, 0x4813c857, 0x58080802,
+	0x40100000, 0x80042480, 0x02001800, 0x001005d8,
+	0x58080000, 0x58081801, 0x80102400, 0x4812600e,
+	0x480e600f, 0x4813c857, 0x592c0208, 0x8400055e,
+	0x48025a08, 0x4833c857, 0x4823c857, 0x482bc857,
+	0x4832600b, 0x4822600c, 0x482a600d, 0x80000580,
+	0x0401f003, 0x82000540, 0x00000001, 0x1c01f000,
+	0x58300204, 0x82004d00, 0x0000000f, 0x82244400,
+	0x001010bd, 0x82000500, 0x000000ff, 0x82000580,
+	0x00000029, 0x0402001b, 0x50204000, 0x592c0409,
+	0x80000540, 0x02000800, 0x001005d8, 0x82000c80,
+	0x00000002, 0x04001011, 0x58300001, 0x80006540,
+	0x02000800, 0x001005d8, 0x58300204, 0x82000500,
+	0x0000000f, 0x82000400, 0x001010bd, 0x50004000,
+	0x40040000, 0x800409c0, 0x04000006, 0x82040c80,
+	0x00000005, 0x040217f1, 0x80204400, 0x80000580,
+	0x1c01f000, 0x59e00004, 0x8c00050e, 0x02020000,
+	0x00100903, 0x1c01f000, 0x4c5c0000, 0x59e4b800,
+	0x485fc857, 0x825c0500, 0x0000001f, 0x04000004,
+	0x59e40862, 0x0201f800, 0x001005d8, 0x825c0500,
+	0x000000e0, 0x02000800, 0x001005d8, 0x8c5cbd0e,
+	0x04020807, 0x8c5cbd0c, 0x04020809, 0x8c5cbd0a,
+	0x04020878, 0x5c00b800, 0x1c01f000, 0x4803c856,
+	0x4a03c800, 0x00000080, 0x1c01f000, 0x4d2c0000,
+	0x42007800, 0x0010b8ec, 0x583c0001, 0x583c0802,
+	0x80040540, 0x0400003f, 0x42000800, 0x0010b7f7,
+	0x50065800, 0x592c0002, 0x82000580, 0x00000000,
+	0x0400000e, 0x59e40850, 0x59e41853, 0x400c0000,
+	0x80040400, 0x59e40852, 0x4807c857, 0x80041480,
+	0x04021008, 0x40001000, 0x480bc857, 0x4a007800,
+	0x00000001, 0x0401f006, 0x4803c857, 0x0401f029,
+	0x59e41050, 0x480bc857, 0x49787800, 0x480bc857,
+	0x480fc857, 0x592c0003, 0x80000540, 0x04000006,
+	0x80080580, 0x04020004, 0x592c0003, 0x4803c857,
+	0x480bc857, 0x480a5803, 0x592c0007, 0x800001c0,
+	0x04000007, 0x592c1007, 0x480bc857, 0x583c0003,
+	0x4803c857, 0x80080480, 0x04001003, 0x583c1001,
+	0x480bc857, 0x583c0802, 0x480bc857, 0x4807c857,
+	0x4a025801, 0x00000000, 0x4a025809, 0x001011bc,
+	0x480a5807, 0x48065808, 0x59e40053, 0x48025804,
+	0x412c1000, 0x492fc857, 0x0201f800, 0x00100858,
+	0x5c025800, 0x4a03c800, 0x00000040, 0x1c01f000,
+	0x42007800, 0x0010b7f7, 0x503c7800, 0x4a007802,
+	0x00000100, 0x42007800, 0x0010b8ec, 0x583c0000,
+	0x4803c857, 0x82000d80, 0x00000001, 0x04000004,
+	0x80000000, 0x48007800, 0x0401f019, 0x49787800,
+	0x583c1806, 0x583c0005, 0x800c1800, 0x480c7806,
+	0x800c0580, 0x04020002, 0x49787806, 0x583c0807,
+	0x800409c0, 0x0400000e, 0x583c0008, 0x80000000,
+	0x48007808, 0x80040580, 0x04020009, 0x49787808,
+	0x583c2006, 0x42001800, 0x00000001, 0x42001000,
+	0x00008028, 0x0201f800, 0x00103a3e, 0x1c01f000,
+	0x4a03c800, 0x00000020, 0x0201f800, 0x0010aa40,
+	0x59e40000, 0x1c01f000, 0x4d2c0000, 0x4a007001,
+	0x00000000, 0x82040d00, 0x43000f80, 0x02020800,
+	0x001005d8, 0x58380009, 0x4803c00f, 0x0201f800,
+	0x00109402, 0x583a5808, 0x592c0000, 0x48007008,
+	0x800001c0, 0x04020002, 0x49787007, 0x0201f800,
+	0x001007f4, 0x5c025800, 0x0201f000, 0x0010087d,
+	0x4803c856, 0x4c3c0000, 0x4d2c0000, 0x4d300000,
+	0x5830000a, 0x80025d40, 0x02000800, 0x001005d8,
+	0x592e6008, 0x4c300000, 0x0201f800, 0x0010941a,
+	0x5c006000, 0x02000800, 0x001005d8, 0x58300002,
+	0x82000580, 0x00000100, 0x04020010, 0x5930780b,
+	0x583c0001, 0x80000540, 0x0400000e, 0x4802600b,
+	0x40007800, 0x82000400, 0x00000002, 0x48006003,
+	0x583c0000, 0x48006004, 0x40301000, 0x0201f800,
+	0x00100858, 0x0401f00c, 0x4a025a06, 0x00000002,
+	0x4c300000, 0x0201f800, 0x000202da, 0x5c006000,
+	0x40325800, 0x0201f800, 0x001007f4, 0x0201f800,
+	0x0002077d, 0x5c026000, 0x5c025800, 0x5c007800,
+	0x1c01f000, 0x4803c856, 0x4d2c0000, 0x4d300000,
+	0x42007000, 0x0010b7f8, 0x58380801, 0x82040580,
+	0x00000002, 0x04020011, 0x58386002, 0x5830000a,
+	0x812c0580, 0x0402000d, 0x59e00004, 0x8c00050e,
+	0x040007fe, 0x59dc0006, 0x4803c857, 0x4a03b805,
+	0x20000000, 0x8c00053e, 0x040007f8, 0x4a007001,
+	0x00000000, 0x0401f019, 0x58386006, 0x40305000,
+	0x803061c0, 0x02000800, 0x001005d8, 0x5830000a,
+	0x812c0580, 0x04000004, 0x40305000, 0x58306000,
+	0x0401f7f8, 0x40280000, 0x80300580, 0x58300000,
+	0x04000006, 0x48005000, 0x800001c0, 0x04020007,
+	0x48287005, 0x0401f005, 0x800001c0, 0x04020002,
+	0x48007005, 0x48007006, 0x40325800, 0x0201f800,
+	0x001007f4, 0x42007000, 0x0010b7f8, 0x58380001,
+	0x82000580, 0x00000000, 0x02000800, 0x0010087d,
+	0x5c026000, 0x5c025800, 0x1c01f000, 0x4803c856,
+	0x42000800, 0x0000003c, 0x48079000, 0x59c80000,
+	0x80040500, 0x040207fe, 0x497b9005, 0x4a039035,
+	0x00880200, 0x59a8000e, 0x800000e0, 0x4803900e,
+	0x4a039011, 0x00000024, 0x4a03900f, 0x0010d1c0,
+	0x4a039010, 0x0010d1c0, 0x4a039015, 0x0000007f,
+	0x4a03900d, 0x00000040, 0x4a039000, 0x00001600,
+	0x1c01f000, 0x59c80007, 0x8c000508, 0x040208b7,
+	0x59c80800, 0x8c040d16, 0x04020004, 0x82000500,
+	0x00000006, 0x0c01f005, 0x4807c857, 0x82000500,
+	0x0000000e, 0x0c01f001, 0x001012a8, 0x001012a6,
+	0x00105999, 0x001012a6, 0x001012aa, 0x001012a6,
+	0x001012aa, 0x001012aa, 0x001012a6, 0x001012a6,
+	0x001012a6, 0x001012a6, 0x001012aa, 0x001012a6,
+	0x001012aa, 0x001012a6, 0x0201f800, 0x001005d8,
+	0x4803c857, 0x1c01f000, 0x59c8080c, 0x4807c857,
+	0x82040500, 0x00006000, 0x04000004, 0x0201f800,
+	0x0010aa03, 0x0401f006, 0x82040500, 0x007f0000,
+	0x04000006, 0x0201f800, 0x0010a9d5, 0x0201f800,
+	0x00106eb3, 0x0401f02b, 0x82040500, 0x00000014,
+	0x04000014, 0x0201f800, 0x0010aa32, 0x836c0580,
+	0x00000003, 0x0400000d, 0x0201f800, 0x0010513b,
+	0x04000004, 0x0201f800, 0x0010411d, 0x0401f007,
+	0x4a035033, 0x00000001, 0x4202d800, 0x00000001,
+	0x0201f800, 0x001050a2, 0x0401f817, 0x0401f015,
+	0x82040500, 0x00001c00, 0x04000005, 0x0201f800,
+	0x0010aa11, 0x0401f810, 0x0401f00e, 0x82040500,
+	0x00000140, 0x04000005, 0x0201f800, 0x0010aa24,
+	0x0401f809, 0x0401f007, 0x82040500, 0x00008000,
+	0x04000004, 0x0201f800, 0x0010a9fc, 0x0401f802,
+	0x1c01f000, 0x4c0c0000, 0x4c100000, 0x4c140000,
+	0x0201f800, 0x00100ec9, 0x5c002800, 0x5c002000,
+	0x5c001800, 0x1c01f000, 0x4803c856, 0x59a80804,
+	0x59a8002b, 0x82000500, 0xfffff000, 0x80040540,
+	0x4803502b, 0x59a8002f, 0x82000500, 0xfffff000,
+	0x80040540, 0x4803502f, 0x48078882, 0x82041c00,
+	0x0000000f, 0x800c1908, 0x820c1c00, 0x00000004,
+	0x400c2000, 0x901029c0, 0x82040480, 0x000001e4,
+	0x04021005, 0x42001000, 0x00000008, 0x801020c6,
+	0x0401f031, 0x82040480, 0x00000230, 0x04021009,
+	0x42001000, 0x00000007, 0x801000c2, 0x800000c2,
+	0x80100400, 0x80100400, 0x80102400, 0x0401f026,
+	0x82040480, 0x00000298, 0x04021008, 0x42001000,
+	0x00000006, 0x801000c2, 0x800000c2, 0x80100400,
+	0x80102400, 0x0401f01c, 0x82040480, 0x00000328,
+	0x04021007, 0x42001000, 0x00000005, 0x801000c2,
+	0x800000c2, 0x80102400, 0x0401f013, 0x82040480,
+	0x00000404, 0x04021005, 0x42001000, 0x00000004,
+	0x801020c4, 0x0401f00c, 0x82040480, 0x0000056c,
+	0x04021006, 0x42001000, 0x00000003, 0x801000c2,
+	0x80102400, 0x0401f004, 0x42001000, 0x00000002,
+	0x801020c2, 0x82100480, 0x00000110, 0x80000080,
+	0x80002000, 0x800800d0, 0x80140540, 0x80100540,
+	0x48039035, 0x1c01f000, 0x59c80815, 0x0201f800,
+	0x001005d0, 0x82040d00, 0x0000007c, 0x48079000,
+	0x59c80000, 0x80040500, 0x040207fe, 0x8c040d04,
+	0x04000003, 0x59c80035, 0x48039035, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x1c01f000,
+	0x4803c856, 0x497b88a9, 0x4a038807, 0x00000001,
+	0x497b8807, 0x59c40005, 0x48038805, 0x0201f800,
+	0x00101815, 0x4201d000, 0x000001f4, 0x0201f800,
+	0x0010608e, 0x497b880e, 0x4200b000, 0x000001f4,
+	0x42000000, 0x00000001, 0x42000800, 0x00000014,
+	0x0201f800, 0x00101944, 0x42000800, 0x00000014,
+	0x0201f800, 0x0010193f, 0x8c040d00, 0x04000005,
+	0x8058b040, 0x040207f3, 0x0201f800, 0x001005d8,
+	0x4200b000, 0x00000032, 0x42000000, 0x00000001,
+	0x42000800, 0x000000b4, 0x0201f800, 0x00101944,
+	0x42000800, 0x000000b4, 0x0201f800, 0x0010193f,
+	0x8c040d00, 0x04000005, 0x8058b040, 0x040207f3,
+	0x0201f800, 0x001005d8, 0x59c40005, 0x48038805,
+	0x42000000, 0x00000089, 0x800008d0, 0x48075054,
+	0x48075055, 0x48075056, 0x42000800, 0x000000e0,
+	0x0201f800, 0x00101944, 0x42000800, 0x000000f4,
+	0x0201f800, 0x0010193f, 0x82040500, 0xffffffd1,
+	0x82000540, 0x00000002, 0x42000800, 0x000000f4,
+	0x0201f800, 0x00101944, 0x42000800, 0x000000a0,
+	0x0201f800, 0x0010193f, 0x82040540, 0x00000001,
+	0x42000800, 0x000000a0, 0x0201f800, 0x00101944,
+	0x42000800, 0x00000000, 0x0201f800, 0x0010193f,
+	0x82040540, 0x00000001, 0x42000800, 0x00000000,
+	0x0201f800, 0x00101944, 0x4201d000, 0x0001d4c0,
+	0x0201f800, 0x0010608e, 0x0401fa2b, 0x4a0388a7,
+	0x0000f7f7, 0x4a0388a3, 0x8000403c, 0x4a0388ae,
+	0x000061a8, 0x4a038801, 0x00032063, 0x4a038810,
+	0x00410108, 0x4a038811, 0x00520608, 0x4a038812,
+	0x00450320, 0x4a038813, 0x00440405, 0x4a03881c,
+	0x004132e1, 0x4a038850, 0x80000108, 0x4a038860,
+	0x00000008, 0x4a038870, 0x00000008, 0x4a038851,
+	0x80000508, 0x4a038861, 0x00800000, 0x4a038871,
+	0x00800000, 0x4a038852, 0x80000708, 0x4a038862,
+	0x00800000, 0x4a038872, 0x00800000, 0x4a038853,
+	0x80000608, 0x497b8863, 0x4a038873, 0x00800000,
+	0x4a038882, 0x00000840, 0x4a0388a5, 0x0000001e,
+	0x4a0388a6, 0x0000001e, 0x4a0388b0, 0x00007530,
+	0x4a038802, 0x0000ffff, 0x4a038806, 0xc0e00800,
+	0x1c01f000, 0x497b5022, 0x4a035021, 0x00000001,
+	0x42000800, 0x00000040, 0x0201f800, 0x0010193f,
+	0x82040500, 0xffffffaf, 0x82000540, 0x00000000,
+	0x42000800, 0x00000040, 0x0201f800, 0x00101944,
+	0x42000800, 0x000000f4, 0x0201f800, 0x0010193f,
+	0x4c040000, 0x40040000, 0x84000548, 0x42000800,
+	0x000000f4, 0x0201f800, 0x00101944, 0x42000800,
+	0x00000000, 0x0201f800, 0x0010193f, 0x82040500,
+	0xffffffc1, 0x82000540, 0x00000038, 0x42000800,
+	0x00000000, 0x0201f800, 0x00101944, 0x5c000000,
+	0x42000800, 0x000000f4, 0x0201f000, 0x00101944,
+	0x59c40805, 0x4807c857, 0x59c40006, 0x80040d00,
+	0x02000800, 0x001005d8, 0x82040500, 0x00e00800,
+	0x04020004, 0x8c040d3e, 0x040208c4, 0x0401f007,
+	0x82040500, 0x00800800, 0x02020800, 0x001005d0,
+	0x0201f800, 0x001005d8, 0x4c5c0000, 0x4c600000,
+	0x59c4b805, 0x485fc857, 0x59c40006, 0x8c000500,
+	0x04000003, 0x8c5cbd00, 0x04020079, 0x0201f800,
+	0x0010513b, 0x04000014, 0x59c40005, 0x82000500,
+	0x000000c0, 0x04000036, 0x0201f800, 0x00105151,
+	0x04020033, 0x4a038805, 0x04000000, 0x59c400a3,
+	0x82000500, 0xbf203fff, 0x480388a3, 0x497b5049,
+	0x4a038805, 0x000000c0, 0x0201f800, 0x00105065,
+	0x0401f063, 0x8c5cbd34, 0x04020025, 0x59c40005,
+	0x8c00050c, 0x04020012, 0x8c00050e, 0x04020013,
+	0x8c00050a, 0x04020014, 0x8c000508, 0x0400000b,
+	0x59a80017, 0x82000580, 0x00000009, 0x04020007,
+	0x42000000, 0x0010b844, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00105318, 0x0401f04b, 0x4a035033,
+	0x00000000, 0x0401f00b, 0x4a035033, 0x00000002,
+	0x0401f008, 0x42000000, 0x0010b846, 0x0201f800,
+	0x0010aa47, 0x0201f800, 0x001052c2, 0x0401f03e,
+	0x0201f800, 0x00105378, 0x0401f03b, 0x8c5cbd34,
+	0x04000037, 0x59c40005, 0x8c00053a, 0x04020005,
+	0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47,
+	0x4a038805, 0x02000000, 0x0201f800, 0x0010513b,
+	0x04020010, 0x4a038805, 0x04000000, 0x0201f800,
+	0x00105149, 0x04020008, 0x4a035033, 0x00000001,
+	0x4202d800, 0x00000001, 0x0201f800, 0x001050a2,
+	0x0401f05b, 0x41780000, 0x0201f800, 0x00105113,
+	0x0201f800, 0x001019fe, 0x4000c000, 0x0201f800,
+	0x00101963, 0x836c1580, 0x00000004, 0x0402000d,
+	0x8c5cbd00, 0x04020012, 0x59a81005, 0x8c081506,
+	0x04020005, 0x59c410a3, 0x82081540, 0x00000008,
+	0x480b88a3, 0x59c41006, 0x84081540, 0x480b8806,
+	0x4a038805, 0x04000000, 0x4202d800, 0x00000001,
+	0x497b5014, 0x0201f800, 0x00103b38, 0x8c5cbd3c,
+	0x04020858, 0x8c5cbd00, 0x04000036, 0x42000000,
+	0x0010b8ca, 0x0201f800, 0x0010aa47, 0x4a038805,
+	0x00000001, 0x4200b000, 0x000003e8, 0x4201d000,
+	0x00000064, 0x4c580000, 0x0201f800, 0x0010608e,
+	0x0201f800, 0x001018d3, 0x5c00b000, 0x04000004,
+	0x8058b040, 0x040207f6, 0x0401f004, 0x4a038805,
+	0x00000001, 0x0401f01f, 0x59c40006, 0x84000500,
+	0x48038806, 0x0201f800, 0x00106ede, 0x497b8880,
+	0x0201f800, 0x0010a9c0, 0x59c4000d, 0x8c000500,
+	0x02020800, 0x0010a9ce, 0x59c400a3, 0x82000500,
+	0xfcf8ffff, 0x480388a3, 0x4a03504c, 0x00000002,
+	0x4202d800, 0x00000004, 0x4a038805, 0x00000001,
+	0x0201f800, 0x001006d4, 0x0401fb3b, 0x497b5052,
+	0x4a035049, 0x00000001, 0x0201f800, 0x00100452,
+	0x825cbd00, 0xbbfffffe, 0x485f8805, 0x5c00c000,
+	0x5c00b800, 0x1c01f000, 0x59c41004, 0x480bc857,
+	0x8c081500, 0x04000006, 0x4803c856, 0x497b2807,
+	0x0201f800, 0x00106fa4, 0x0401f00a, 0x82080500,
+	0x000001f0, 0x04000007, 0x4803c856, 0x417a3000,
+	0x0201f800, 0x00106062, 0x0201f800, 0x00106fc6,
+	0x4a038805, 0x80000000, 0x1c01f000, 0x59c408a3,
+	0x4807c857, 0x84040d40, 0x480788a3, 0x1c01f000,
+	0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000,
+	0x4a038805, 0x40000000, 0x42000000, 0x0010b8c6,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x00106c55,
+	0x59c41004, 0x8c081500, 0x04000054, 0x598e600d,
+	0x497b2807, 0x813261c0, 0x04000032, 0x59300403,
+	0x82000580, 0x00000032, 0x0402002e, 0x5930001c,
+	0x48038833, 0x4a038807, 0x00018000, 0x4201d000,
+	0x00000002, 0x0201f800, 0x0010608e, 0x497b8807,
+	0x4201d000, 0x00000002, 0x0201f800, 0x0010608e,
+	0x0201f800, 0x00106e21, 0x4201d000, 0x00007530,
+	0x0201f800, 0x0010608e, 0x59c408a4, 0x82040d00,
+	0x0000000f, 0x82040d80, 0x00000000, 0x04000005,
+	0x42000000, 0x00200000, 0x0201f800, 0x00101949,
+	0x0201f800, 0x00106bbf, 0x59300008, 0x80000540,
+	0x02000800, 0x001005d8, 0x40025800, 0x4a025a04,
+	0x00000103, 0x5931d821, 0x58ef400b, 0x58ec0009,
+	0x0801f800, 0x0201f800, 0x0002077d, 0x0401f047,
+	0x598c000f, 0x82001c80, 0x000000c8, 0x0402100f,
+	0x80000000, 0x4803180f, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000580, 0x00000002, 0x04020004,
+	0x42000000, 0x00200000, 0x0401fbf7, 0x0201f800,
+	0x0010604d, 0x0401f035, 0x4933c857, 0x0201f800,
+	0x00106e21, 0x813261c0, 0x04000030, 0x4a026203,
+	0x00000001, 0x42027000, 0x00000027, 0x0201f800,
+	0x000207a1, 0x0401f029, 0x8c081508, 0x04000027,
+	0x417a3000, 0x0201f800, 0x001070d8, 0x42032000,
+	0x0000bf32, 0x0201f800, 0x00106062, 0x59926004,
+	0x813261c0, 0x04000012, 0x42001800, 0x000000c8,
+	0x0201f800, 0x001070a4, 0x0402000d, 0x59c400a4,
+	0x82000500, 0x0000000f, 0x82000580, 0x00000002,
+	0x04020004, 0x42000000, 0x00200000, 0x0401fbce,
+	0x0201f800, 0x00106052, 0x0401f00c, 0x4933c857,
+	0x0201f800, 0x00106dc3, 0x813261c0, 0x04000007,
+	0x42027000, 0x0000004f, 0x4a026203, 0x00000003,
+	0x0201f800, 0x000207a1, 0x5c022800, 0x5c034800,
+	0x5c03a000, 0x5c032000, 0x0201f000, 0x00106c4b,
+	0x4803c857, 0x59a80821, 0x48035021, 0x80041580,
+	0x04000045, 0x800409c0, 0x04000023, 0x497b504c,
+	0x42000000, 0x0010b80d, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x0010aaf9, 0x42001000, 0x00008011,
+	0x59c40001, 0x82000500, 0x00018000, 0x82001d80,
+	0x00000000, 0x04000009, 0x82001d80, 0x00008000,
+	0x04000009, 0x82001d80, 0x00010000, 0x04000009,
+	0x0201f800, 0x001005d8, 0x42001800, 0x00000000,
+	0x0401f006, 0x42001800, 0x00000001, 0x0401f003,
+	0x42001800, 0x00000003, 0x0201f800, 0x00103a3e,
+	0x0401f021, 0x59a8084c, 0x800409c0, 0x04020007,
+	0x59c4000d, 0x8c000520, 0x04000004, 0x42001800,
+	0x00000003, 0x0401f002, 0x40041800, 0x0201f800,
+	0x0010aadd, 0x42001000, 0x00008012, 0x0201f800,
+	0x00103a3e, 0x0201f800, 0x001006d4, 0x0201f800,
+	0x0010ab33, 0x0402000c, 0x0401f853, 0x4d400000,
+	0x4d3c0000, 0x42028000, 0x00000028, 0x42027800,
+	0x00000408, 0x0201f800, 0x00101fe5, 0x5c027800,
+	0x5c028000, 0x1c01f000, 0x4803c857, 0x82000400,
+	0x0010210e, 0x50000800, 0x82040d00, 0x000000ff,
+	0x1c01f000, 0x4803c856, 0x4c580000, 0x4200b000,
+	0x00000010, 0x497b88ac, 0x497b88ad, 0x8058b040,
+	0x040207fe, 0x5c00b000, 0x1c01f000, 0x4807c857,
+	0x48075010, 0x80041108, 0x4200b000, 0x00000010,
+	0x497b88ac, 0x80000580, 0x800811c0, 0x04020006,
+	0x82040500, 0x0000000f, 0x82000400, 0x0010ab38,
+	0x50000000, 0x480388ad, 0x80081040, 0x8058b040,
+	0x040207f5, 0x1c01f000, 0x59a80005, 0x04000003,
+	0x84000546, 0x0401f002, 0x84000506, 0x48035005,
+	0x4803c857, 0x1c01f000, 0x4803c857, 0x4c080000,
+	0x4c040000, 0x4c000000, 0x59c40892, 0x4807c857,
+	0x80041580, 0x04000010, 0x80041480, 0x04021007,
+	0x80081080, 0x80081000, 0x4008b000, 0x42000000,
+	0x00000201, 0x0401f004, 0x4008b000, 0x42000000,
+	0x00000210, 0x48038886, 0x8058b040, 0x040207fe,
+	0x497b8886, 0x5c000000, 0x5c000800, 0x5c001000,
+	0x1c01f000, 0x4803c856, 0x0201f800, 0x00103b25,
+	0x04000005, 0x42028000, 0x0000002e, 0x0201f000,
+	0x0010a449, 0x1c01f000, 0x42000800, 0x00000002,
+	0x59a80005, 0x8c000514, 0x0402000b, 0x59c80835,
+	0x82040d00, 0x00001f00, 0x80040910, 0x80040800,
+	0x59a8006c, 0x80000540, 0x04000003, 0x42000800,
+	0x0000025a, 0x4807c857, 0x1c01f000, 0x4c000000,
+	0x59a80053, 0x4803c857, 0x82000580, 0x00000000,
+	0x5c000000, 0x1c01f000, 0x4c000000, 0x59a80053,
+	0x4803c857, 0x82000580, 0x00000001, 0x5c000000,
+	0x1c01f000, 0x4c000000, 0x59a80053, 0x4803c857,
+	0x82000580, 0x00000003, 0x5c000000, 0x1c01f000,
+	0x4c000000, 0x59a80053, 0x82000580, 0x00000002,
+	0x5c000000, 0x1c01f000, 0x4c000000, 0x4c040000,
+	0x4c080000, 0x4c380000, 0x59a80040, 0x82000c80,
+	0x00000007, 0x02021800, 0x001005d8, 0x0c01f806,
+	0x5c007000, 0x5c001000, 0x5c000800, 0x5c000000,
+	0x1c01f000, 0x0010166c, 0x0010167f, 0x00101693,
+	0x00101695, 0x001016bc, 0x001016be, 0x001016c0,
+	0x4803c856, 0x4a035042, 0x00000000, 0x42000000,
+	0x00000002, 0x0401fa1b, 0x42000000, 0x00000002,
+	0x0401f9ad, 0x0401fab2, 0x4803c856, 0x4a035040,
+	0x00000006, 0x42000800, 0x0000001e, 0x42001000,
+	0x001016c1, 0x0201f000, 0x0010606e, 0x497b5045,
+	0x4a035050, 0x00000036, 0x4a03504f, 0x0000002a,
+	0x4803c856, 0x4a035042, 0x00000001, 0x42000000,
+	0x00000002, 0x0401f998, 0x4803c856, 0x4a035040,
+	0x00000006, 0x42000800, 0x0000001e, 0x42001000,
+	0x001016c1, 0x0201f000, 0x0010606e, 0x0201f800,
+	0x001005d8, 0x4a035050, 0x00000036, 0x4803c856,
+	0x4a035042, 0x00000003, 0x42000800, 0x00000000,
+	0x0401faa3, 0x82040d00, 0x00000090, 0x82040580,
+	0x00000090, 0x04000009, 0x82040580, 0x00000010,
+	0x04000009, 0x82040580, 0x00000000, 0x04000008,
+	0x0201f800, 0x001005d8, 0x42000000, 0x00000001,
+	0x0401f005, 0x41780000, 0x0401f003, 0x42000000,
+	0x00000002, 0x0401f970, 0x497b5046, 0x4803c856,
+	0x4a035040, 0x00000006, 0x42000800, 0x0000001e,
+	0x42001000, 0x001016c1, 0x0201f000, 0x0010606e,
+	0x0201f800, 0x001005d8, 0x0201f800, 0x001005d8,
+	0x1c01f000, 0x4c000000, 0x4c040000, 0x4c080000,
+	0x4c380000, 0x59a80042, 0x82000c80, 0x00000007,
+	0x02021800, 0x001005d8, 0x0c01f806, 0x5c007000,
+	0x5c001000, 0x5c000800, 0x5c000000, 0x1c01f000,
+	0x001016d7, 0x001016f6, 0x0010174a, 0x00101761,
+	0x00101778, 0x00101781, 0x00101783, 0x0401f9fc,
+	0x0402001b, 0x59a81048, 0x42000800, 0x00000000,
+	0x0401fa63, 0x82040d00, 0x00000090, 0x82040580,
+	0x00000090, 0x04000009, 0x82040580, 0x00000010,
+	0x04000008, 0x82040580, 0x00000000, 0x04000007,
+	0x0201f800, 0x001005d8, 0x84081540, 0x0401f004,
+	0x84081542, 0x0401f002, 0x84081544, 0x480b5048,
+	0x4a035040, 0x00000001, 0x0401f003, 0x0401f8cb,
+	0x0401ff82, 0x1c01f000, 0x0401f88f, 0x04000052,
+	0x0401f9db, 0x0402002a, 0x42000800, 0x00000000,
+	0x0401fa43, 0x82040d00, 0x00000090, 0x82040580,
+	0x00000000, 0x04000044, 0x82040580, 0x00000010,
+	0x04000006, 0x82040580, 0x00000090, 0x04000009,
+	0x0201f800, 0x001005d8, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00000000, 0x04000036,
+	0x42000800, 0x00000000, 0x0401fa2d, 0x82040d00,
+	0x00000090, 0x82040580, 0x00000010, 0x04000006,
+	0x82040580, 0x00000090, 0x04000006, 0x02020800,
+	0x001005d8, 0x59a80048, 0x84000542, 0x0401f003,
+	0x59a80048, 0x84000540, 0x48035048, 0x59a80045,
+	0x80000000, 0x48035045, 0x82000580, 0x00000005,
+	0x04000003, 0x0401f861, 0x0401f01e, 0x497b5045,
+	0x59c40801, 0x82040d00, 0x00018000, 0x82040580,
+	0x00000000, 0x04000009, 0x82040580, 0x00008000,
+	0x04000009, 0x82040580, 0x00010000, 0x04000008,
+	0x0201f800, 0x001005d8, 0x42000000, 0x00000001,
+	0x0401f005, 0x41780000, 0x0401f003, 0x42000000,
+	0x00000002, 0x0401f94b, 0x4a035042, 0x00000002,
+	0x0401f004, 0x4a035040, 0x00000003, 0x0401f002,
+	0x0401ff42, 0x1c01f000, 0x0401f83b, 0x04000015,
+	0x59a8004f, 0x80000040, 0x4803504f, 0x0401f984,
+	0x04020005, 0x4a035040, 0x00000003, 0x497b5041,
+	0x0401f00c, 0x59a8004f, 0x80000540, 0x04020003,
+	0x0401f89e, 0x0401f002, 0x0401f84b, 0x0401f82f,
+	0x497b5045, 0x4a035042, 0x00000001, 0x0401ff2b,
+	0x1c01f000, 0x0401f824, 0x04000015, 0x0401f970,
+	0x0402000f, 0x59a80046, 0x80000000, 0x48035046,
+	0x82000580, 0x00000007, 0x0402000c, 0x4a035052,
+	0x0000000a, 0x497b5049, 0x59a80048, 0x8400055e,
+	0x48035048, 0x4803c857, 0x0401f005, 0x0401f817,
+	0x4a035042, 0x00000004, 0x0401ff3d, 0x1c01f000,
+	0x0401f80d, 0x04000007, 0x0401f959, 0x04020003,
+	0x0401ff1b, 0x0401f003, 0x0401f80c, 0x0401ff34,
+	0x1c01f000, 0x0201f800, 0x001005d8, 0x0201f800,
+	0x001005d8, 0x59a80050, 0x80000040, 0x48035050,
+	0x0400088d, 0x1c01f000, 0x4c040000, 0x42000800,
+	0x00000000, 0x0401f9b2, 0x82040d00, 0x00000090,
+	0x82040580, 0x00000090, 0x04000009, 0x82040580,
+	0x00000010, 0x04000009, 0x82040580, 0x00000000,
+	0x04000009, 0x0201f800, 0x001005d8, 0x42000000,
+	0x00000002, 0x0401f005, 0x42000000, 0x00000001,
+	0x0401f002, 0x41780000, 0x0401f8ea, 0x5c000800,
+	0x1c01f000, 0x4c040000, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00000000, 0x04000009,
+	0x82040580, 0x00008000, 0x04000009, 0x82040580,
+	0x00010000, 0x04000009, 0x0201f800, 0x001005d8,
+	0x42000000, 0x00000002, 0x0401f005, 0x42000000,
+	0x00000001, 0x0401f002, 0x41780000, 0x0401f866,
+	0x5c000800, 0x1c01f000, 0x4c040000, 0x59a80045,
+	0x80000000, 0x48035045, 0x82000580, 0x00000005,
+	0x04020018, 0x497b5045, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00000000, 0x04000009,
+	0x82040580, 0x00008000, 0x04000009, 0x82040580,
+	0x00010000, 0x04000009, 0x0201f800, 0x001005d8,
+	0x42000000, 0x00000002, 0x0401f005, 0x42000000,
+	0x00000001, 0x0401f002, 0x41780000, 0x0401f846,
+	0x42000800, 0x00000000, 0x0401f961, 0x82040d00,
+	0x00000090, 0x82040580, 0x00000090, 0x04000009,
+	0x82040580, 0x00000010, 0x04000009, 0x82040580,
+	0x00000000, 0x04000009, 0x0201f800, 0x001005d8,
+	0x42000000, 0x00000002, 0x0401f005, 0x42000000,
+	0x00000001, 0x0401f002, 0x41780000, 0x0401f899,
+	0x5c000800, 0x1c01f000, 0x4c200000, 0x59a80048,
+	0x82000500, 0x00007fff, 0x02000800, 0x001005d8,
+	0x59a84047, 0x80204102, 0x02001800, 0x001005d8,
+	0x48235047, 0x80204500, 0x040007fa, 0x8c000504,
+	0x04020007, 0x8c000502, 0x04020008, 0x8c000500,
+	0x04020008, 0x0201f800, 0x001005d8, 0x42000000,
+	0x00000002, 0x0401f005, 0x41780000, 0x0401f003,
+	0x42000000, 0x00000001, 0x0401f80f, 0x5c004000,
+	0x1c01f000, 0x04011000, 0x4a03c840, 0x0010b440,
+	0x4a03c842, 0x00000009, 0x40000000, 0x040117ff,
+	0x4a035047, 0x00000004, 0x4a03503e, 0x00000000,
+	0x1c01f000, 0x59a80858, 0x82040d80, 0x01391077,
+	0x04020008, 0x59e00813, 0x8c040d00, 0x04000005,
+	0x82000d80, 0x00000002, 0x04020002, 0x41780000,
+	0x4c000000, 0x0401f9b1, 0x5c000000, 0x800001c0,
+	0x04000040, 0x82000d80, 0x00000001, 0x0402001d,
+	0x42000800, 0x000000a0, 0x0401f909, 0x82040540,
+	0x00000004, 0x42000800, 0x000000a0, 0x0401f909,
+	0x42000800, 0x000000c0, 0x0401f901, 0x82040540,
+	0x00000020, 0x42000800, 0x000000c0, 0x0401f901,
+	0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540,
+	0x00000000, 0x48038801, 0x59a80054, 0x80000110,
+	0x42000800, 0x000000e0, 0x0401f8f6, 0x0401f03c,
+	0x82000d80, 0x00000002, 0x02020800, 0x001005d8,
+	0x42000800, 0x000000a0, 0x0401f8e9, 0x82040500,
+	0xfffffffb, 0x42000800, 0x000000a0, 0x0401f8e9,
+	0x42000800, 0x000000c0, 0x0401f8e1, 0x82040500,
+	0xffffffdf, 0x42000800, 0x000000c0, 0x0401f8e1,
+	0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540,
+	0x00010000, 0x48038801, 0x59a80056, 0x80000110,
+	0x42000800, 0x000000e0, 0x0401f8d6, 0x0401f01c,
+	0x42000800, 0x000000a0, 0x0401f8cd, 0x82040540,
+	0x00000004, 0x42000800, 0x000000a0, 0x0401f8cd,
+	0x42000800, 0x000000c0, 0x0401f8c5, 0x82040500,
+	0xffffffdf, 0x42000800, 0x000000c0, 0x0401f8c5,
+	0x59c40001, 0x82000500, 0xfffe7fff, 0x82000540,
+	0x00008000, 0x48038801, 0x59a80055, 0x80000110,
+	0x42000800, 0x000000e0, 0x0401f8ba, 0x0401f163,
+	0x4803c857, 0x59a80858, 0x82040d80, 0x01391077,
+	0x04020008, 0x59e00813, 0x8c040d00, 0x04000005,
+	0x82000d80, 0x00000002, 0x04020002, 0x41780000,
+	0x4c000000, 0x0401f94d, 0x5c000000, 0x800001c0,
+	0x04000026, 0x82000d80, 0x00000001, 0x04020010,
+	0x59a8006c, 0x80000540, 0x04000004, 0x42001000,
+	0x00000000, 0x0401fa0a, 0x42000800, 0x00000000,
+	0x0401f897, 0x82040540, 0x00000090, 0x42000800,
+	0x00000000, 0x0401f897, 0x0401f024, 0x82000d80,
+	0x00000002, 0x02020800, 0x001005d8, 0x59a8006c,
+	0x80000540, 0x04000004, 0x42001000, 0x00010000,
+	0x0401f9f7, 0x42000800, 0x00000000, 0x0401f884,
+	0x82040500, 0xffffff6f, 0x42000800, 0x00000000,
+	0x0401f884, 0x0401f011, 0x59a8006c, 0x80000540,
+	0x04000004, 0x42001000, 0x00008000, 0x0401f9e8,
+	0x42000800, 0x00000000, 0x0401f875, 0x82040500,
+	0xffffff6f, 0x82000540, 0x00000010, 0x42000800,
+	0x00000000, 0x0401f873, 0x0401f124, 0x4c580000,
+	0x4200b000, 0x00000014, 0x8058b040, 0x04000043,
+	0x59c4000d, 0x8c000520, 0x040207fc, 0x0401f85c,
+	0x59c4000d, 0x8c000520, 0x040207f8, 0x59c40808,
+	0x84040d50, 0x48078808, 0x4200b000, 0x000000c8,
+	0x8058b040, 0x040207ff, 0x4200b000, 0x00000014,
+	0x8058b040, 0x04000031, 0x59c4000d, 0x8c000520,
+	0x0402002e, 0x42000800, 0x00001000, 0x50040800,
+	0x82040c80, 0x24220001, 0x04020003, 0x8c000504,
+	0x040007f4, 0x0401f842, 0x59c4000d, 0x8c000520,
+	0x04020022, 0x42000800, 0x00001000, 0x50040800,
+	0x82040c80, 0x24220001, 0x04020003, 0x8c000504,
+	0x040007e8, 0x4200b000, 0x0000000a, 0x8058b040,
+	0x04000003, 0x0401f832, 0x0401f7fd, 0x4200b000,
+	0x00000064, 0x59c4000d, 0x8c00051e, 0x0400000f,
+	0x8058b040, 0x040207fc, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24220001, 0x04020004,
+	0x59c40808, 0x84040d10, 0x48078808, 0x80000580,
+	0x4803c857, 0x0401f00c, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24220001, 0x04020004,
+	0x59c40808, 0x84040d10, 0x48078808, 0x82000540,
+	0x00000001, 0x5c00b000, 0x1c01f000, 0x42000800,
+	0x000000a0, 0x0401f816, 0x82040500, 0xfffffffe,
+	0x42000800, 0x000000a0, 0x0401f816, 0x42000800,
+	0x00000000, 0x0401f80e, 0x82040500, 0xfffffffe,
+	0x42000800, 0x00000000, 0x0401f00e, 0x40000000,
+	0x40000000, 0x40000000, 0x40000000, 0x40000000,
+	0x1c01f000, 0x480b8805, 0x1c01f000, 0x4807880e,
+	0x59c4080f, 0x82040d00, 0x000000ff, 0x1c01f000,
+	0x900001c0, 0x80040d40, 0x84040d40, 0x4807880e,
+	0x1c01f000, 0x82000d80, 0x00200000, 0x04000009,
+	0x82000d80, 0x02000000, 0x04000006, 0x82000d80,
+	0x01000000, 0x04000006, 0x59c408a3, 0x0401f006,
+	0x59c408a3, 0x84040d30, 0x0401f003, 0x59c408a3,
+	0x84040d32, 0x80040540, 0x480388a3, 0x480788a3,
+	0x1c01f000, 0x59c400a3, 0x84000556, 0x480388a3,
+	0x84000516, 0x480388a3, 0x1c01f000, 0x485fc857,
+	0x4863c857, 0x4c640000, 0x4d3c0000, 0x4d400000,
+	0x0201f800, 0x00106ede, 0x4863500a, 0x0201f800,
+	0x0010ab33, 0x0402006c, 0x82600d00, 0x0000ff00,
+	0x800409c0, 0x0400000c, 0x4200c800, 0x00000001,
+	0x59a80010, 0x82000500, 0x000000ff, 0x80041110,
+	0x80081580, 0x04000021, 0x82041580, 0x0000ff00,
+	0x0400000a, 0x59c410a3, 0x82081500, 0x00008000,
+	0x04000009, 0x59c410a7, 0x82081500, 0x0000ff00,
+	0x82081580, 0x0000ff00, 0x4200c800, 0x00000000,
+	0x04000012, 0x59a80005, 0x8c000502, 0x04020008,
+	0x8c000500, 0x0402000d, 0x599c1017, 0x8c08151a,
+	0x0400003e, 0x84000542, 0x48035005, 0x4200c800,
+	0x00000002, 0x42028000, 0x00000004, 0x42027800,
+	0x00000008, 0x0401f008, 0x59a80805, 0x84040d40,
+	0x48075005, 0x42028000, 0x00000004, 0x42027800,
+	0x00000400, 0x59a80006, 0x8c000502, 0x04020006,
+	0x59a80805, 0x8c040d0a, 0x04020033, 0x84040d4a,
+	0x48075005, 0x42000000, 0x0010b812, 0x0201f800,
+	0x0010aa47, 0x59a8180a, 0x42001000, 0x00008013,
+	0x0201f800, 0x00103a3e, 0x0201f800, 0x00103b25,
+	0x04000015, 0x4d400000, 0x82600500, 0x000000ff,
+	0x42028800, 0x0000ffff, 0x40643000, 0x42028000,
+	0x0000000e, 0x0201f800, 0x0010a446, 0x42000800,
+	0x00000001, 0x42001000, 0x00000100, 0x0201f800,
+	0x0010618b, 0x5c028000, 0x599c0817, 0x8c040d0a,
+	0x04020011, 0x493fc857, 0x4943c857, 0x0201f800,
+	0x00101fe5, 0x0401f00c, 0x0201f800, 0x00103b25,
+	0x04000009, 0x42028000, 0x0000000f, 0x42028800,
+	0x0000ffff, 0x42003000, 0x00000000, 0x0201f800,
+	0x0010a449, 0x497b8880, 0x5c028000, 0x5c027800,
+	0x5c00c800, 0x1c01f000, 0x42000800, 0x000000a0,
+	0x0401ff5f, 0x82040540, 0x00000002, 0x42000800,
+	0x000000a0, 0x0401f75f, 0x42000800, 0x00000000,
+	0x0401ff57, 0x82040540, 0x00000002, 0x42000800,
+	0x00000000, 0x0401f757, 0x42000800, 0x000000a0,
+	0x0401ff4f, 0x82040500, 0xfffffffd, 0x42000800,
+	0x000000a0, 0x0401f74f, 0x42000800, 0x00000000,
+	0x0401ff47, 0x82040500, 0xfffffffd, 0x42000800,
+	0x00000000, 0x0401f747, 0x59c408a8, 0x0401ff38,
+	0x0401ff37, 0x59c400a8, 0x80040d80, 0x040207fb,
+	0x1c01f000, 0x4803c856, 0x4a038807, 0x00000001,
+	0x497b8807, 0x59c40005, 0x48038805, 0x497b506c,
+	0x497b506d, 0x41785800, 0x42006000, 0x00000001,
+	0x42006800, 0x00000003, 0x0401f824, 0x0401f82f,
+	0x40400000, 0x4803c857, 0x82408580, 0x00000000,
+	0x0402001d, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000014, 0x0401f818, 0x0401f823,
+	0x40400000, 0x4803c857, 0x82408580, 0x00000800,
+	0x04020011, 0x42005800, 0x00000001, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000014, 0x0401f80b,
+	0x0401f816, 0x40400000, 0x4803c857, 0x82408580,
+	0x0000ffff, 0x04020004, 0x4a03506c, 0x00000001,
+	0x4803c856, 0x1c01f000, 0x41785000, 0x0401f812,
+	0x0401f838, 0x40347000, 0x40340800, 0x0401f03d,
+	0x42005000, 0x00000001, 0x0401f80b, 0x0401f831,
+	0x40340800, 0x0401f037, 0x42005000, 0x00000002,
+	0x0401f805, 0x0401f81d, 0x0401f835, 0x40048000,
+	0x1c01f000, 0x0401f808, 0x0401f814, 0x40280800,
+	0x0401f826, 0x402c0800, 0x0401f827, 0x40300800,
+	0x0401f025, 0x42000800, 0x0000ffff, 0x42001000,
+	0x00000001, 0x0401f829, 0x42001000, 0x00000010,
+	0x0401f826, 0x42000800, 0x0000ffff, 0x42001000,
+	0x00000010, 0x0401f021, 0x41780800, 0x42001000,
+	0x00000002, 0x0401f01d, 0x0401f92e, 0x4a03d000,
+	0x00050004, 0x0401f92b, 0x4a03d000, 0x00050005,
+	0x0401f928, 0x4a03d000, 0x00050004, 0x42000800,
+	0x00000001, 0x42001000, 0x00000001, 0x0401f00f,
+	0x42000800, 0x00000002, 0x42001000, 0x00000002,
+	0x0401f00a, 0x42001000, 0x00000005, 0x0401f007,
+	0x42001000, 0x00000010, 0x0401f004, 0x42001000,
+	0x00000010, 0x0401f01b, 0x0401f912, 0x82082c00,
+	0x0010ab38, 0x50142800, 0x82081500, 0xffffffff,
+	0x04000013, 0x0401f90b, 0x80081040, 0x80142902,
+	0x40040000, 0x80140500, 0x04000007, 0x4a03d000,
+	0x00070006, 0x0401f903, 0x4a03d000, 0x00070007,
+	0x0401f006, 0x4a03d000, 0x00070004, 0x0401f8fd,
+	0x4a03d000, 0x00070005, 0x0401f7ec, 0x1c01f000,
+	0x41780800, 0x82082c00, 0x0010ab38, 0x50142800,
+	0x82081500, 0xffffffff, 0x04000010, 0x0401f8f1,
+	0x4a03d000, 0x00050001, 0x0401f8ee, 0x59e81800,
+	0x80081040, 0x80142902, 0x8c0c1d06, 0x04000004,
+	0x40140000, 0x80040d40, 0x0401f8e6, 0x4a03d000,
+	0x00070000, 0x0401f7ef, 0x1c01f000, 0x480bc857,
+	0x480b506d, 0x59c40001, 0x82000500, 0xffffefff,
+	0x48038801, 0x41781800, 0x0401f8c4, 0x41785800,
+	0x42006000, 0x0000001e, 0x42006800, 0x00000004,
+	0x0401ff7a, 0x42006800, 0x0000003c, 0x0401ff7d,
+	0x41785800, 0x42006000, 0x0000001e, 0x42006800,
+	0x00000004, 0x0401ff71, 0x41786800, 0x0401ff75,
+	0x41785800, 0x42006000, 0x0000001e, 0x41786800,
+	0x0401ff6a, 0x42006800, 0x00000002, 0x0401ff6d,
+	0x42006800, 0x00000001, 0x0401ff64, 0x42006800,
+	0x000000f5, 0x0401ff67, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000004, 0x0401ff5b,
+	0x42006800, 0x00000020, 0x0401ff5e, 0x59a8106d,
+	0x0401f865, 0x42001800, 0x000200f5, 0x0401f897,
+	0x59a8106d, 0x0401f879, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000004, 0x0401ff4b,
+	0x41786800, 0x0401ff4f, 0x59c40001, 0x82000540,
+	0x00001000, 0x48038801, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000015, 0x0401ff3f,
+	0x0401ff4a, 0x40400000, 0x82000540, 0x00000002,
+	0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000015, 0x0401ff34, 0x5c000000,
+	0x40006800, 0x0401ff37, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000015, 0x0401ff2b,
+	0x0401ff36, 0x40400000, 0x82000500, 0x0000fffd,
+	0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000015, 0x0401ff20, 0x5c000000,
+	0x40006800, 0x0401ff23, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000014, 0x0401ff17,
+	0x0401ff22, 0x40400000, 0x82000540, 0x00000040,
+	0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000014, 0x0401ff0c, 0x5c000000,
+	0x40006800, 0x0401ff0f, 0x41785800, 0x42006000,
+	0x0000001e, 0x42006800, 0x00000014, 0x0401ff03,
+	0x0401ff0e, 0x40400000, 0x82000500, 0x0000ffbf,
+	0x4c000000, 0x41785800, 0x42006000, 0x0000001e,
+	0x42006800, 0x00000014, 0x0401fef8, 0x5c000000,
+	0x40006800, 0x0401fefb, 0x4a038886, 0x00002020,
+	0x0401f04c, 0x480bc857, 0x82080580, 0x00010000,
+	0x04020007, 0x82040d40, 0x00010000, 0x42001800,
+	0x00000001, 0x0401f82d, 0x0401f00f, 0x82080580,
+	0x00008000, 0x04000007, 0x82040d40, 0x00000000,
+	0x42001800, 0x00900001, 0x0401f824, 0x0401f006,
+	0x82040d40, 0x00008000, 0x42001800, 0x00100001,
+	0x0401f81e, 0x1c01f000, 0x480bc857, 0x82080580,
+	0x00010000, 0x04020008, 0x42001800, 0x000000a1,
+	0x0401f816, 0x42001800, 0x000000c1, 0x0401f813,
+	0x0401f011, 0x82080580, 0x00008000, 0x04000008,
+	0x42001800, 0x000400a1, 0x0401f80c, 0x42001800,
+	0x002000c1, 0x0401f809, 0x0401f007, 0x42001800,
+	0x000400a1, 0x0401f805, 0x42001800, 0x000000c1,
+	0x0401f802, 0x1c01f000, 0x480fc857, 0x41785800,
+	0x42006000, 0x0000001e, 0x41786800, 0x0401feb7,
+	0x400c6800, 0x80346960, 0x0401feba, 0x42006800,
+	0x00000001, 0x0401feb1, 0x400c6800, 0x0401feb5,
+	0x42006800, 0x00000003, 0x0401feac, 0x0401feb7,
+	0x40400000, 0x8c000504, 0x040207fc, 0x1c01f000,
+	0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+	0x1c01f000, 0x00020103, 0x00101bd5, 0x00101bdb,
+	0x00101be1, 0x00101be9, 0x00101bef, 0x00101bf7,
+	0x00101bff, 0x00101c09, 0x00101c0f, 0x00101c17,
+	0x00101c1f, 0x00101c29, 0x00101c31, 0x00101c3b,
+	0x00101c45, 0x000200f8, 0x00101c51, 0x00101c59,
+	0x00101c61, 0x00101c6b, 0x00101c73, 0x00101c7d,
+	0x00101c87, 0x00101c93, 0x00101c9b, 0x00101ca5,
+	0x00101caf, 0x00101cbb, 0x00101cc5, 0x00101cd1,
+	0x00101cdd, 0x000200fd, 0x00101ceb, 0x00101cf3,
+	0x00101cfb, 0x00101d05, 0x00101d0d, 0x00101d17,
+	0x00101d21, 0x00101d2d, 0x00101d35, 0x00101d3f,
+	0x00101d49, 0x00101d55, 0x00101d5f, 0x00101d6b,
+	0x00101d77, 0x00101d85, 0x00101d8d, 0x00101d97,
+	0x00101da1, 0x00101dad, 0x00101db7, 0x00101dc3,
+	0x00101dcf, 0x00101ddd, 0x00101de7, 0x00101df3,
+	0x00101dff, 0x00101e0d, 0x00101e19, 0x00101e27,
+	0x00101e35, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020729, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020015, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020015, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101155, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f800,
+	0x00020104, 0x0201f000, 0x00020101, 0x4c000000,
+	0x4df00000, 0x0201f800, 0x00101155, 0x0201f800,
+	0x00101418, 0x0201f800, 0x00020729, 0x0201f800,
+	0x00020015, 0x0201f800, 0x00101289, 0x0201f000,
+	0x00020101, 0x4c000000, 0x4df00000, 0x0201f800,
+	0x00101155, 0x0201f800, 0x00101418, 0x0201f800,
+	0x00020729, 0x0201f800, 0x00020015, 0x0201f800,
+	0x00101289, 0x0201f800, 0x00020104, 0x0201f000,
+	0x00020101, 0x4c5c0000, 0x4c600000, 0x4178b800,
+	0x0201f800, 0x001048ec, 0x040200fd, 0x59a8c026,
+	0x0201f800, 0x0010513b, 0x04000003, 0x8c60c506,
+	0x0400000e, 0x8c60c500, 0x04020004, 0x8c60c50e,
+	0x040008f6, 0x0401f0f2, 0x0401fab4, 0x040200f0,
+	0x0201f800, 0x0010513b, 0x04020004, 0x4a03501c,
+	0x0000ffff, 0x0401f0ea, 0x8c60c504, 0x04000004,
+	0x4a03501c, 0x0000ffff, 0x0401f0e5, 0x59a8c010,
+	0x8260c500, 0x000000ff, 0x59a81013, 0x8c081500,
+	0x0400005d, 0x8c081502, 0x0402005b, 0x59a8b81c,
+	0x825c0d80, 0x0000ffff, 0x04020003, 0x4200b800,
+	0x00000001, 0x805c1104, 0x82086400, 0x0010be21,
+	0x50300800, 0x825c0500, 0x00000003, 0x0c01f001,
+	0x00101e81, 0x00101e7c, 0x00101e80, 0x00101e7e,
+	0x80040910, 0x0401f004, 0x80040930, 0x0401f002,
+	0x80040920, 0x82040500, 0x000000ff, 0x82000d80,
+	0x000000ff, 0x0400000f, 0x4c000000, 0x82000400,
+	0x0010210e, 0x50000800, 0x80040910, 0x82040580,
+	0x00000080, 0x5c000000, 0x04000030, 0x80600d80,
+	0x0400002e, 0x80000540, 0x0400002c, 0x0401f00b,
+	0x59a81005, 0x82081500, 0x00000003, 0x0402002b,
+	0x59a81013, 0x84081542, 0x480b5013, 0x4a03501c,
+	0x0000ffff, 0x0401f028, 0x4c000000, 0x59a80005,
+	0x8c000514, 0x42001000, 0x00000010, 0x02020800,
+	0x00104c6d, 0x5c000000, 0x0402001c, 0x417a8800,
+	0x0201f800, 0x00105c9a, 0x04020016, 0x0201f800,
+	0x001045e5, 0x04000006, 0x0201f800, 0x00104c62,
+	0x0401f8b1, 0x0400000f, 0x0401f00c, 0x599c0019,
+	0x8c00050e, 0x04020009, 0x0201f800, 0x001045a6,
+	0x04020008, 0x0201f800, 0x00104c62, 0x0401f9e1,
+	0x0401f8be, 0x04000003, 0x805cb800, 0x0401f7b2,
+	0x485f501c, 0x0401f086, 0x4a03501c, 0x0000ffff,
+	0x0401f083, 0x42003000, 0x0000007e, 0x59a8001c,
+	0x82001580, 0x0000ffff, 0x04020005, 0x80000d80,
+	0x4018b000, 0x4803c856, 0x0401f009, 0x8018b480,
+	0x04001004, 0x40000800, 0x4803c856, 0x0401f004,
+	0x4a03501c, 0x0000ffff, 0x0401f071, 0x4c040000,
+	0x4c580000, 0x82040400, 0x0010210e, 0x50000000,
+	0x82000500, 0x000000ff, 0x80604580, 0x0400005c,
+	0x0201f800, 0x00105c9b, 0x04020061, 0x59a80005,
+	0x8c000514, 0x42001000, 0x00000010, 0x02020800,
+	0x00104c6d, 0x5c00b000, 0x5c000800, 0x040207d7,
+	0x4c040000, 0x4c580000, 0x845cbd00, 0x0201f800,
+	0x00020245, 0x04000008, 0x599c0019, 0x8c00050e,
+	0x04020047, 0x0201f800, 0x001045ab, 0x0402004c,
+	0x0401f002, 0x845cbd40, 0x0201f800, 0x00104c62,
+	0x0201f800, 0x001049e7, 0x04020007, 0x59a80005,
+	0x8c000502, 0x04000033, 0x59340200, 0x8c00050e,
+	0x04020030, 0x59a81013, 0x8c081502, 0x04000025,
+	0x0201f800, 0x00104a09, 0x04000031, 0x8c5cbd00,
+	0x04020004, 0x0201f800, 0x001045ff, 0x0401f02c,
+	0x0401f9cd, 0x0400002a, 0x42026000, 0x0010bde9,
+	0x49366009, 0x497a6008, 0x417a7800, 0x0401f925,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00103b25, 0x0400001d, 0x41782800,
+	0x42003000, 0x00000008, 0x4d400000, 0x4d440000,
+	0x59368c03, 0x42028000, 0x00000029, 0x0201f800,
+	0x0010a446, 0x5c028800, 0x5c028000, 0x0401f010,
+	0x4937c857, 0x599c0019, 0x8c00050e, 0x0402000c,
+	0x0401f96c, 0x0401f849, 0x04000011, 0x0401f008,
+	0x59a80013, 0x8c000500, 0x04000003, 0x0401f9a6,
+	0x04000003, 0x0401f828, 0x04000009, 0x5c00b000,
+	0x5c000800, 0x80040800, 0x8058b040, 0x04020798,
+	0x4a03501c, 0x0000ffff, 0x0401f005, 0x4937c857,
+	0x5c00b000, 0x5c000800, 0x4807501c, 0x5c00c000,
+	0x5c00b800, 0x1c01f000, 0x4803c856, 0x4a03501c,
+	0x00000001, 0x42028800, 0x000007fe, 0x42003000,
+	0x00fffffe, 0x0201f800, 0x001045a6, 0x0402000c,
+	0x0401f948, 0x0401f825, 0x04000009, 0x59a80026,
+	0x8400054e, 0x48035026, 0x0201f800, 0x0010930f,
+	0x82000540, 0x00000001, 0x1c01f000, 0x80000580,
+	0x0401f7fe, 0x4937c857, 0x0201f800, 0x00107942,
+	0x04000015, 0x49366009, 0x4a026406, 0x00000001,
+	0x417a7800, 0x0201f800, 0x00104567, 0x59a8001b,
+	0x80000000, 0x4803501b, 0x42027000, 0x00000004,
+	0x599c0019, 0x8c00050e, 0x04000003, 0x42027000,
+	0x00000000, 0x0201f800, 0x000207a1, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4937c857, 0x0201f800,
+	0x00107942, 0x0400001c, 0x49366009, 0x59340403,
+	0x82000580, 0x000007fe, 0x04000005, 0x4d3c0000,
+	0x417a7800, 0x0401f8b7, 0x5c027800, 0x4a026406,
+	0x00000001, 0x417a7800, 0x0201f800, 0x00104567,
+	0x42000800, 0x00000003, 0x0201f800, 0x00104571,
+	0x59a8001b, 0x80000000, 0x4803501b, 0x42027000,
+	0x00000002, 0x0201f800, 0x000207a1, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4803c856, 0x42028800,
+	0x000007fc, 0x42003000, 0x00fffffc, 0x0201f800,
+	0x001045a6, 0x04020005, 0x0401f805, 0x04000003,
+	0x4a035027, 0x0000ffff, 0x1c01f000, 0x4937c857,
+	0x0201f800, 0x00107942, 0x04000014, 0x49366009,
+	0x4a026406, 0x00000001, 0x417a7800, 0x0201f800,
+	0x00104567, 0x42000800, 0x00000003, 0x0201f800,
+	0x00104571, 0x59a80028, 0x80000000, 0x48035028,
+	0x42027000, 0x00000002, 0x0201f800, 0x000207a1,
+	0x82000540, 0x00000001, 0x1c01f000, 0x480bc857,
+	0x492fc857, 0x4c5c0000, 0x4008b800, 0x42028800,
+	0x000007fd, 0x42003000, 0x00fffffd, 0x0201f800,
+	0x001045a6, 0x0402001a, 0x0201f800, 0x0002075a,
+	0x04000017, 0x49366009, 0x5934000a, 0x84000544,
+	0x4802680a, 0x812e59c0, 0x04000005, 0x592c0404,
+	0x8c00051e, 0x04000002, 0x48ee6021, 0x492e6008,
+	0x4a026406, 0x00000001, 0x485e601c, 0x42027000,
+	0x00000022, 0x0201f800, 0x000207a1, 0x82000540,
+	0x00000001, 0x5c00b800, 0x1c01f000, 0x80000580,
+	0x0401f7fd, 0x5c000000, 0x4c000000, 0x4803c857,
+	0x4943c857, 0x493fc857, 0x4d340000, 0x4d440000,
+	0x4c580000, 0x4d2c0000, 0x4c5c0000, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x0201f800, 0x001069f1,
+	0x0201f800, 0x00106aac, 0x0201f800, 0x00106737,
+	0x0201f800, 0x0010848a, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x4200b000, 0x000007f0, 0x417a8800,
+	0x0201f800, 0x00020245, 0x0402001f, 0x8d3e7d14,
+	0x04000005, 0x59340212, 0x82000500, 0x0000ff00,
+	0x04000019, 0x8d3e7d06, 0x04000004, 0x59340200,
+	0x8c00050e, 0x04020014, 0x8d3e7d18, 0x0400000f,
+	0x5934b80f, 0x805cb9c0, 0x04000009, 0x49425a06,
+	0x592cb800, 0x0201f800, 0x000202ce, 0x805cb9c0,
+	0x040207fb, 0x497a680f, 0x497a6810, 0x4a026c00,
+	0x00000707, 0x0401f004, 0x4937c857, 0x0201f800,
+	0x001042b4, 0x81468800, 0x8058b040, 0x040207dd,
+	0x8d3e7d02, 0x04000011, 0x497b501d, 0x42028800,
+	0x000007f0, 0x4200b000, 0x00000010, 0x0201f800,
+	0x00020245, 0x04020006, 0x4937c857, 0x4a026c00,
+	0x00000707, 0x0201f800, 0x001042b4, 0x81468800,
+	0x8058b040, 0x040207f6, 0x5c00b800, 0x5c025800,
+	0x5c00b000, 0x5c028800, 0x5c026800, 0x1c01f000,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x4933c857,
+	0x493fc857, 0x4d340000, 0x4d400000, 0x4d440000,
+	0x4d2c0000, 0x4c5c0000, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x59326809, 0x813669c0, 0x04000020,
+	0x59368c03, 0x42028000, 0x00000029, 0x0201f800,
+	0x00106a50, 0x0201f800, 0x00106ab4, 0x0201f800,
+	0x001067fd, 0x0201f800, 0x0010a2ff, 0x4937c857,
+	0x8d3e7d18, 0x04000010, 0x5934b80f, 0x805cb9c0,
+	0x0400000a, 0x405e5800, 0x49425a06, 0x592cb800,
+	0x0201f800, 0x000202ce, 0x805cb9c0, 0x040207fa,
+	0x497a680f, 0x497a6810, 0x4a026c00, 0x00000707,
+	0x0401f003, 0x0201f800, 0x001042b4, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x5c00b800, 0x5c025800,
+	0x5c028800, 0x5c028000, 0x5c026800, 0x1c01f000,
+	0x4933c857, 0x59a80026, 0x8c000508, 0x04020012,
+	0x59305009, 0x482bc857, 0x836c0580, 0x00000002,
+	0x0402000d, 0x0401f813, 0x0402000b, 0x58280403,
+	0x82000580, 0x000007fc, 0x04000008, 0x59a8001b,
+	0x80000040, 0x4803c857, 0x02001800, 0x001005d8,
+	0x4803501b, 0x1c01f000, 0x59a80028, 0x80000040,
+	0x4803c857, 0x040017fc, 0x48035028, 0x1c01f000,
+	0x59300008, 0x800001c0, 0x04020009, 0x59300403,
+	0x82000580, 0x00000001, 0x04020004, 0x82000540,
+	0x00000001, 0x0401f002, 0x80000580, 0x1c01f000,
+	0x4937c857, 0x59340200, 0x84000502, 0x48026a00,
+	0x1c01f000, 0x4933c857, 0x493fc857, 0x4947c857,
+	0x4d3c0000, 0x4d400000, 0x4d340000, 0x4d440000,
+	0x4c580000, 0x0201f800, 0x00106c55, 0x4df00000,
+	0x813e79c0, 0x04020004, 0x4200b000, 0x00000001,
+	0x0401f004, 0x4200b000, 0x000007f0, 0x417a8800,
+	0x41440000, 0x81ac0400, 0x50000000, 0x80026d40,
+	0x04000019, 0x42027800, 0x00000001, 0x0201f800,
+	0x001048f6, 0x42028000, 0x00000029, 0x417a7800,
+	0x0201f800, 0x00106a50, 0x0201f800, 0x00106ab4,
+	0x0201f800, 0x001067fd, 0x0201f800, 0x001049e7,
+	0x04020005, 0x4937c857, 0x4a026c00, 0x00000404,
+	0x0401f003, 0x0201f800, 0x00104a14, 0x0201f800,
+	0x0010a2ff, 0x81468800, 0x8058b040, 0x040207e1,
+	0x5c03e000, 0x02000800, 0x00106c4b, 0x5c00b000,
+	0x5c028800, 0x5c026800, 0x5c028000, 0x5c027800,
+	0x1c01f000, 0x4937c857, 0x4947c857, 0x4c5c0000,
+	0x4c600000, 0x4c640000, 0x59a80013, 0x8c000500,
+	0x0400001f, 0x599c0017, 0x8c00050a, 0x0402001c,
+	0x5934ba02, 0x825cbd00, 0x000000ff, 0x485fc857,
+	0x4178c000, 0x4178c800, 0x82600400, 0x0010be21,
+	0x50002000, 0x8060c1c0, 0x04000008, 0x82100500,
+	0x000000ff, 0x82002d80, 0x000000ff, 0x0400000c,
+	0x805c0580, 0x0400000d, 0x80102110, 0x8064c800,
+	0x82640580, 0x00000004, 0x040207f5, 0x8060c000,
+	0x82600580, 0x00000020, 0x040207eb, 0x4813c857,
+	0x82000540, 0x00000001, 0x5c00c800, 0x5c00c000,
+	0x5c00b800, 0x1c01f000, 0x59a80026, 0x4803c857,
+	0x8c000512, 0x1c01f000, 0x00007eef, 0x00007de8,
+	0x00007ce4, 0x000080e2, 0x00007be1, 0x000080e0,
+	0x000080dc, 0x000080da, 0x00007ad9, 0x000080d6,
+	0x000080d5, 0x000080d4, 0x000080d3, 0x000080d2,
+	0x000080d1, 0x000079ce, 0x000078cd, 0x000080cc,
+	0x000080cb, 0x000080ca, 0x000080c9, 0x000080c7,
+	0x000080c6, 0x000077c5, 0x000076c3, 0x000080bc,
+	0x000080ba, 0x000075b9, 0x000080b6, 0x000074b5,
+	0x000073b4, 0x000072b3, 0x000080b2, 0x000080b1,
+	0x000080ae, 0x000071ad, 0x000080ac, 0x000070ab,
+	0x00006faa, 0x00006ea9, 0x000080a7, 0x00006da6,
+	0x00006ca5, 0x00006ba3, 0x00006a9f, 0x0000699e,
+	0x0000689d, 0x0000809b, 0x00008098, 0x00006797,
+	0x00006690, 0x0000658f, 0x00006488, 0x00006384,
+	0x00006282, 0x00008081, 0x00008080, 0x0000617c,
+	0x0000607a, 0x00008079, 0x00005f76, 0x00008075,
+	0x00008074, 0x00008073, 0x00008072, 0x00008071,
+	0x0000806e, 0x00005e6d, 0x0000806c, 0x00005d6b,
+	0x00005c6a, 0x00005b69, 0x00008067, 0x00005a66,
+	0x00005965, 0x00005863, 0x0000575c, 0x0000565a,
+	0x00005559, 0x00008056, 0x00008055, 0x00005454,
+	0x00005353, 0x00005252, 0x00005151, 0x0000504e,
+	0x00004f4d, 0x0000804c, 0x0000804b, 0x00004e4a,
+	0x00004d49, 0x00008047, 0x00004c46, 0x00008045,
+	0x00008043, 0x0000803c, 0x0000803a, 0x00008039,
+	0x00008036, 0x00004b35, 0x00008034, 0x00004a33,
+	0x00004932, 0x00004831, 0x0000802e, 0x0000472d,
+	0x0000462c, 0x0000452b, 0x0000442a, 0x00004329,
+	0x00004227, 0x00008026, 0x00008025, 0x00004123,
+	0x0000401f, 0x00003f1e, 0x00003e1d, 0x00003d1b,
+	0x00003c18, 0x00008017, 0x00008010, 0x00003b0f,
+	0x00003a08, 0x00008004, 0x00003902, 0x00008001,
+	0x00008000, 0x00008000, 0x00003800, 0x00003700,
+	0x00003600, 0x00008000, 0x00003500, 0x00008000,
+	0x00008000, 0x00008000, 0x00003400, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00003300, 0x00003200, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00003100, 0x00003000, 0x00008000,
+	0x00008000, 0x00002f00, 0x00008000, 0x00002e00,
+	0x00002d00, 0x00002c00, 0x00008000, 0x00008000,
+	0x00008000, 0x00002b00, 0x00008000, 0x00002a00,
+	0x00002900, 0x00002800, 0x00008000, 0x00002700,
+	0x00002600, 0x00002500, 0x00002400, 0x00002300,
+	0x00002200, 0x00008000, 0x00008000, 0x00002100,
+	0x00002000, 0x00001f00, 0x00001e00, 0x00001d00,
+	0x00001c00, 0x00008000, 0x00008000, 0x00001b00,
+	0x00001a00, 0x00008000, 0x00001900, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00001800, 0x00008000, 0x00001700,
+	0x00001600, 0x00001500, 0x00008000, 0x00001400,
+	0x00001300, 0x00001200, 0x00001100, 0x00001000,
+	0x00000f00, 0x00008000, 0x00008000, 0x00000e00,
+	0x00000d00, 0x00000c00, 0x00000b00, 0x00000a00,
+	0x00000900, 0x00008000, 0x00008000, 0x00000800,
+	0x00000700, 0x00008000, 0x00000600, 0x00008000,
+	0x00008000, 0x00008000, 0x00000500, 0x00000400,
+	0x00000300, 0x00008000, 0x00000200, 0x00008000,
+	0x00008000, 0x00008000, 0x00000100, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00000000, 0x00008000, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00008000, 0x00008000, 0x00008000,
+	0x00008000, 0x00008000, 0x0201f800, 0x001007d3,
+	0x02000800, 0x001005d8, 0x492f4016, 0x1c01f000,
+	0x83a0ac00, 0x00000006, 0x83a00580, 0x0010b4a4,
+	0x0400000c, 0x492fc857, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x832ca400, 0x00000006, 0x4200b000,
+	0x0000000d, 0x0201f800, 0x0010ab17, 0x0401f00f,
+	0x4200b000, 0x00000010, 0x83e0a400, 0x00000020,
+	0x50500000, 0x8050a000, 0x50500800, 0x900409c0,
+	0x80040540, 0x4400a800, 0x8050a000, 0x8054a800,
+	0x8058b040, 0x040207f7, 0x1c01f000, 0x59a00206,
+	0x4803c857, 0x82000c80, 0x0000007f, 0x040210c9,
+	0x59a80821, 0x0c01f001, 0x001022c0, 0x00102300,
+	0x00102300, 0x0010234b, 0x0010236d, 0x00102300,
+	0x001022c0, 0x0010238f, 0x001023a0, 0x00102300,
+	0x00102300, 0x001023ad, 0x001023c5, 0x001023dd,
+	0x00102300, 0x001023e7, 0x001023f4, 0x00102300,
+	0x0010241d, 0x00102300, 0x0010247a, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102491, 0x00102300,
+	0x001024e3, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x001024e8, 0x00102560, 0x00102300,
+	0x00102567, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102569, 0x001025ea,
+	0x00102727, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102736, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102753, 0x001027a6,
+	0x00102802, 0x00102816, 0x00102835, 0x00102a70,
+	0x00102dff, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00102300,
+	0x00102300, 0x00102fb4, 0x00103028, 0x00102300,
+	0x00102300, 0x00103094, 0x00102300, 0x00103126,
+	0x001031d8, 0x00102300, 0x00102300, 0x0010320f,
+	0x0010326b, 0x00102300, 0x001032bd, 0x00103419,
+	0x00102300, 0x0010342d, 0x001034b8, 0x00102300,
+	0x00102300, 0x00102300, 0x00102300, 0x00103522,
+	0x00103526, 0x00103545, 0x00102300, 0x001035e7,
+	0x00102300, 0x00102300, 0x00103615, 0x00102300,
+	0x00103643, 0x00102300, 0x00102300, 0x001036aa,
+	0x001037b7, 0x00103814, 0x00102300, 0x0010387a,
+	0x00102300, 0x00102300, 0x001038d3, 0x00103936,
+	0x00102300, 0x48efc857, 0x4031d800, 0x58ef400b,
+	0x58ec0002, 0x82000580, 0x00000200, 0x04000045,
+	0x48efc857, 0x4a034206, 0x00004000, 0x0201f800,
+	0x00103a15, 0x83a00580, 0x0010b4a4, 0x0400000d,
+	0x58ee580a, 0x4d2c0000, 0x0401f856, 0x41a25800,
+	0x0201f800, 0x001007f4, 0x40ee5800, 0x0201f800,
+	0x001007f4, 0x5c025800, 0x0201f000, 0x000202da,
+	0x04026007, 0x59a0001d, 0x84000542, 0x4803401d,
+	0x4a01d809, 0x001022d4, 0x1c01f000, 0x59a00206,
+	0x82000d80, 0x00004000, 0x04000006, 0x900001c0,
+	0x82000540, 0x00000011, 0x4803c011, 0x0401f005,
+	0x900001c0, 0x82000540, 0x00000010, 0x4803c011,
+	0x0401f845, 0x59e00017, 0x8c000508, 0x0402000c,
+	0x4203e000, 0x30000001, 0x4203e000, 0x40000000,
+	0x40ee5800, 0x0201f800, 0x001007f4, 0x59a0001d,
+	0x84000504, 0x4803401d, 0x1c01f000, 0x4a03c017,
+	0x00000000, 0x59a00206, 0x82000d80, 0x00004000,
+	0x040007f0, 0x4a03c017, 0x00000001, 0x0401f7ed,
+	0x4803c856, 0x4a034206, 0x00004001, 0x0401f7c0,
+	0x4803c856, 0x4a034206, 0x00004002, 0x0401f7bc,
+	0x4803c856, 0x4a034206, 0x00004003, 0x0401f7b8,
+	0x4803c856, 0x4a034206, 0x00004005, 0x0401f7b4,
+	0x4803c856, 0x4a034206, 0x00004006, 0x0401f7b0,
+	0x4803c856, 0x4a034206, 0x0000400b, 0x0401f7ac,
+	0x4803c856, 0x4a034206, 0x0000400c, 0x0401f7a8,
+	0x4803c856, 0x4a034206, 0x0000400c, 0x0401f7a4,
+	0x48efc857, 0x58eca80a, 0x8054a9c0, 0x02000800,
+	0x001005d8, 0x83a0a400, 0x00000006, 0x8254ac00,
+	0x00000006, 0x4200b000, 0x0000000d, 0x0201f000,
+	0x0010ab17, 0x59a00206, 0x4803c857, 0x59a00406,
+	0x4803c857, 0x59a00207, 0x4803c857, 0x59a00407,
+	0x4803c857, 0x59a00208, 0x4803c857, 0x59a00408,
+	0x4803c857, 0x59a00209, 0x4803c857, 0x83e0ac00,
+	0x00000020, 0x83a0a400, 0x00000006, 0x4200b000,
+	0x00000010, 0x50500000, 0x4400a800, 0x8054a800,
+	0x900001c0, 0x4400a800, 0x8054a800, 0x8050a000,
+	0x8058b040, 0x040207f8, 0x1c01f000, 0x59a00406,
+	0x800000c2, 0x59a00a07, 0x900409c0, 0x80040540,
+	0x84000540, 0x59a00c07, 0x8c040d00, 0x04000018,
+	0x59a80805, 0x8c040d0e, 0x040207ba, 0x42000800,
+	0x00000064, 0x80040840, 0x04000007, 0x4a030000,
+	0x00000001, 0x40000000, 0x59801000, 0x8c081500,
+	0x040007f9, 0x04000005, 0x48030004, 0x4a030000,
+	0x00000000, 0x0401f75b, 0x4a030000, 0x00000000,
+	0x4a034406, 0x00000004, 0x040007a2, 0x4803880e,
+	0x0401f754, 0x59a00406, 0x800000c2, 0x59a00c07,
+	0x8c040d00, 0x0400001a, 0x59a80805, 0x8c040d0e,
+	0x0402079c, 0x42000800, 0x00000064, 0x80040840,
+	0x04000007, 0x4a030000, 0x00000001, 0x40000000,
+	0x59801000, 0x8c081500, 0x040007f9, 0x04000007,
+	0x48030004, 0x59800805, 0x48074406, 0x4a030000,
+	0x00000000, 0x0401f73b, 0x4a030000, 0x00000000,
+	0x4a034406, 0x00000004, 0x04000782, 0x4803880e,
+	0x59c4080f, 0x48074406, 0x0401f732, 0x59a01c06,
+	0x59a00207, 0x900c19c0, 0x800c1d40, 0x580c0803,
+	0x80000580, 0x500c1000, 0x80080400, 0x800c1800,
+	0x80040840, 0x040207fc, 0x48034406, 0x900001c0,
+	0x48034207, 0x800001c0, 0x04000722, 0x0401f769,
+	0x4a034406, 0x00000004, 0x4a034207, 0x00000000,
+	0x4a034407, 0x00000010, 0x59a8000d, 0x48034208,
+	0x900001c0, 0x48034408, 0x4a034209, 0x00000002,
+	0x0401f714, 0x59a00407, 0x59a01207, 0x900811c0,
+	0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+	0x800c1d40, 0x59a00a08, 0x59a00408, 0x900409c0,
+	0x80040d40, 0x59a0020a, 0x82002480, 0x00000010,
+	0x04001754, 0x59a02406, 0x900001c0, 0x80100540,
+	0x59a8280d, 0x80142480, 0x0400174e, 0x0201f000,
+	0x00103a25, 0x59a00407, 0x59a01207, 0x900811c0,
+	0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+	0x800c1d40, 0x59a00a08, 0x59a00408, 0x900409c0,
+	0x80040d40, 0x59a0020a, 0x82002480, 0x00000010,
+	0x0400173c, 0x59a02406, 0x900001c0, 0x80100540,
+	0x59a8280d, 0x80142480, 0x04001736, 0x0201f000,
+	0x00103a28, 0x59a00a0a, 0x59a00406, 0x900409c0,
+	0x80040d40, 0x59a01407, 0x59a00207, 0x900811c0,
+	0x80081540, 0x44080800, 0x0401f6da, 0x59a00a0a,
+	0x59a00406, 0x900409c0, 0x80040d40, 0x50040000,
+	0x82000d00, 0x0000ffff, 0x48074207, 0x82000d00,
+	0xffff0000, 0x900409c0, 0x48074407, 0x0401f6cd,
+	0x59a00406, 0x8c000500, 0x04000020, 0x59a01207,
+	0x59a01c07, 0x59a02208, 0x480b5054, 0x480f5055,
+	0x48135056, 0x59c40801, 0x82040d00, 0x00018000,
+	0x82040580, 0x00000000, 0x04000009, 0x82040580,
+	0x00008000, 0x04000008, 0x82040580, 0x00010000,
+	0x04000007, 0x0201f800, 0x001005d8, 0x40080000,
+	0x0401f004, 0x400c0000, 0x0401f002, 0x40100000,
+	0x80000110, 0x42000800, 0x000000e0, 0x0201f800,
+	0x00101944, 0x0401f007, 0x59a81054, 0x59a81855,
+	0x59a82056, 0x480b4207, 0x480f4407, 0x48134208,
+	0x0401f6a4, 0x4d2c0000, 0x4d340000, 0x4d300000,
+	0x4d440000, 0x59a28c06, 0x0201f800, 0x00020245,
+	0x04000006, 0x5c028800, 0x5c026000, 0x5c026800,
+	0x5c025800, 0x0401f6e7, 0x59a04407, 0x59a00207,
+	0x900001c0, 0x80204540, 0x0401f81e, 0x04000009,
+	0x4a034208, 0x00000001, 0x4a034406, 0x0000ffff,
+	0x4a034207, 0x0000ffff, 0x497b4407, 0x0401f00b,
+	0x0401f822, 0x0400000e, 0x4a034208, 0x00000002,
+	0x59300402, 0x48034406, 0x59300202, 0x48034207,
+	0x59300206, 0x48034407, 0x5c028800, 0x5c026000,
+	0x5c026800, 0x5c025800, 0x0401f67a, 0x5c028800,
+	0x5c026000, 0x5c026800, 0x5c025800, 0x0401f6c1,
+	0x4937c856, 0x4823c856, 0x4d2c0000, 0x5934000f,
+	0x80025d40, 0x04000007, 0x592c0005, 0x80200580,
+	0x592c0000, 0x040207fb, 0x82000540, 0x00000001,
+	0x5c025800, 0x1c01f000, 0x4823c857, 0x4d2c0000,
+	0x4d300000, 0x42026000, 0x0010d1c0, 0x59300406,
+	0x82000d80, 0x00000003, 0x04000004, 0x82000d80,
+	0x00000006, 0x04020007, 0x59325808, 0x812e59c0,
+	0x04000004, 0x592c0005, 0x80200580, 0x0400000a,
+	0x83326400, 0x00000024, 0x41580000, 0x81300480,
+	0x040017ef, 0x80000580, 0x5c026000, 0x5c025800,
+	0x1c01f000, 0x82000540, 0x00000001, 0x5c026000,
+	0x5c025800, 0x1c01f000, 0x83a00580, 0x0010b4a4,
+	0x04020684, 0x59a80005, 0x8c00050e, 0x04020003,
+	0x4a030000, 0x00000000, 0x4a034206, 0x00004000,
+	0x4a03c011, 0x40000010, 0x0401fea7, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000000,
+	0x4203e000, 0x30000001, 0x4203e000, 0x40000000,
+	0x0401f000, 0x800409c0, 0x04000004, 0x4a034406,
+	0x00000001, 0x0401f677, 0x836c0580, 0x00000003,
+	0x04020010, 0x59a80010, 0x497b4406, 0x0201f800,
+	0x0010513b, 0x0400000f, 0x82000d00, 0x00ffff00,
+	0x0402000c, 0x82000c00, 0x0010210e, 0x50040800,
+	0x80040910, 0x82041580, 0x00000080, 0x04020004,
+	0x4a034406, 0x00000007, 0x0401f662, 0x48074406,
+	0x82000d00, 0x0000ffff, 0x48074207, 0x80000120,
+	0x48034407, 0x59a80026, 0x82001500, 0x00000100,
+	0x480b4409, 0x8c000502, 0x0400001f, 0x8c000506,
+	0x04000009, 0x82000d00, 0x0000000a, 0x82040d80,
+	0x0000000a, 0x04020004, 0x4a034209, 0x00000001,
+	0x0401f022, 0x8c00050a, 0x04000009, 0x82000d00,
+	0x00000022, 0x82040d80, 0x00000022, 0x04020004,
+	0x4a034209, 0x00000003, 0x0401f018, 0x8c000508,
+	0x04000009, 0x82000d00, 0x00000012, 0x82040d80,
+	0x00000012, 0x04020004, 0x4a034209, 0x00000002,
+	0x0401f00e, 0x0201f800, 0x0010513b, 0x04020004,
+	0x4a034209, 0x00000004, 0x0401f5e6, 0x8c000506,
+	0x04000004, 0x4a034406, 0x00000005, 0x0401f62d,
+	0x4a034209, 0x00000000, 0x0401f5de, 0x59a80037,
+	0x48034407, 0x59a80038, 0x48034209, 0x0401f5d9,
+	0x42007800, 0x0010b8ec, 0x59a00406, 0x4803c857,
+	0x82000c80, 0x00000006, 0x04021622, 0x0c01f001,
+	0x001024f6, 0x001024f7, 0x00102505, 0x00102518,
+	0x00102539, 0x001024f6, 0x0401f61a, 0x836c0580,
+	0x00000000, 0x04000613, 0x59a00a07, 0x59a00407,
+	0x900001c0, 0x80040d40, 0x4807c857, 0x59a00a08,
+	0x59a00408, 0x900001c0, 0x80040d40, 0x4807c857,
+	0x0401f056, 0x836c0580, 0x00000000, 0x04000605,
+	0x59a00407, 0x59a01207, 0x900001c0, 0x80081540,
+	0x59a00408, 0x59a01a08, 0x900001c0, 0x800c1d40,
+	0x42000000, 0x0010c1bf, 0x480fc857, 0x480bc857,
+	0x42000800, 0x00001000, 0x0201f000, 0x00103a28,
+	0x59a00a07, 0x59a00407, 0x900001c0, 0x80041d40,
+	0x820c0c80, 0x0010ab4a, 0x040215f2, 0x820c0c80,
+	0x00100000, 0x040015ef, 0x480fc857, 0x823c7c00,
+	0x00000009, 0x503c0800, 0x800409c0, 0x04000006,
+	0x823c0580, 0x0000000d, 0x040005e6, 0x803c7800,
+	0x0401f7f9, 0x59e41001, 0x82080d00, 0xfffeffcf,
+	0x4807c801, 0x440c7800, 0x46001800, 0x0201f800,
+	0x800c1800, 0x46001800, 0x001005cb, 0x480bc801,
+	0x0401f022, 0x59a01a07, 0x59a00407, 0x900001c0,
+	0x800c1d40, 0x480c7801, 0x59a02208, 0x59a00408,
+	0x900001c0, 0x80102540, 0x48107802, 0x59a00209,
+	0x80000040, 0x040015cb, 0x48007806, 0x80000000,
+	0x48007805, 0x42000800, 0x00004000, 0x40001000,
+	0x0201f800, 0x00106681, 0x80000540, 0x04000003,
+	0x49787801, 0x0401f5bf, 0x40040000, 0x800c1c00,
+	0x040015bc, 0x480c7803, 0x48107804, 0x49787808,
+	0x59a00409, 0x48007807, 0x59e40001, 0x4803c857,
+	0x82000540, 0x00040000, 0x4803c801, 0x0401f561,
+	0x59a80006, 0x48034406, 0x59a80007, 0x48034207,
+	0x59a80008, 0x48034407, 0x0401f55a, 0x0201f800,
+	0x001005d8, 0x4803c856, 0x4a03c013, 0x03800300,
+	0x4a03c014, 0x03800380, 0x59a00c06, 0x82040580,
+	0x000000a0, 0x04000004, 0x82040580, 0x000000a2,
+	0x0402002b, 0x59a0140a, 0x82080480, 0x00000100,
+	0x04021027, 0x59a0020b, 0x8c000500, 0x0402002e,
+	0x59a00a0a, 0x800409c0, 0x04000021, 0x82040480,
+	0x00000041, 0x0402101e, 0x82040c00, 0x00000003,
+	0x82040d00, 0x000000fc, 0x80040904, 0x59a00407,
+	0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+	0x59a01a09, 0x900c19c0, 0x800c1d40, 0x0201f800,
+	0x00103a00, 0x04020006, 0x4a034406, 0x00000002,
+	0x4a03c014, 0x03800000, 0x0401f576, 0x832e5c00,
+	0x00000004, 0x412c0000, 0x0201f800, 0x00103a25,
+	0x4a01d809, 0x001025a2, 0x1c01f000, 0x4a03c014,
+	0x03800000, 0x0401f56f, 0x4031d800, 0x58ef400b,
+	0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200,
+	0x0400055c, 0x59a00c06, 0x59a0140a, 0x59a0020b,
+	0x8c000500, 0x04020031, 0x832e5c00, 0x00000004,
+	0x41783800, 0x59a04a0a, 0x401c0000, 0x812c0400,
+	0x50004000, 0x82201d00, 0x000000ff, 0x4c040000,
+	0x0401f8ac, 0x5c000800, 0x0400002d, 0x80244840,
+	0x04000028, 0x80081000, 0x82201d00, 0x0000ff00,
+	0x800c1910, 0x4c040000, 0x0401f8a2, 0x5c000800,
+	0x04000023, 0x80244840, 0x0400001e, 0x80081000,
+	0x82201d00, 0x00ff0000, 0x800c1920, 0x4c040000,
+	0x0401f898, 0x5c000800, 0x04000019, 0x80244840,
+	0x04000014, 0x80081000, 0x82201d00, 0xff000000,
+	0x800c1930, 0x4c040000, 0x0401f88e, 0x5c000800,
+	0x0400000f, 0x80244840, 0x0400000a, 0x80081000,
+	0x801c3800, 0x0401f7d5, 0x59a0020a, 0x82000500,
+	0x000000ff, 0x40001800, 0x0401f882, 0x04000004,
+	0x4a03c014, 0x03800000, 0x0401f4da, 0x4a03c014,
+	0x03800000, 0x0401f523, 0x4803c856, 0x4a03c013,
+	0x03800300, 0x4a03c014, 0x03800380, 0x59a00c06,
+	0x82040580, 0x000000a0, 0x04000004, 0x82040580,
+	0x000000a2, 0x0402006c, 0x59a0140a, 0x82080480,
+	0x00000100, 0x04021068, 0x59a0020b, 0x8c000500,
+	0x0402005c, 0x59a01a0a, 0x800c19c0, 0x04000062,
+	0x820c0480, 0x00000041, 0x0402105f, 0x0201f800,
+	0x00103a00, 0x04020006, 0x4a034406, 0x00000002,
+	0x4a03c014, 0x03800000, 0x0401f502, 0x832e5c00,
+	0x00000004, 0x41783800, 0x59a04a0a, 0x401c0000,
+	0x812c0400, 0x40004000, 0x4c040000, 0x4c080000,
+	0x0401f874, 0x5c001000, 0x5c000800, 0x04000047,
+	0x44144000, 0x80244840, 0x0400002b, 0x80081000,
+	0x4c040000, 0x4c080000, 0x0401f86a, 0x5c001000,
+	0x5c000800, 0x0400003d, 0x50200000, 0x801428d0,
+	0x80140540, 0x44004000, 0x80244840, 0x0400001e,
+	0x80081000, 0x4c040000, 0x4c080000, 0x0401f85d,
+	0x5c001000, 0x5c000800, 0x04000030, 0x50200000,
+	0x801428e0, 0x80140540, 0x44004000, 0x80244840,
+	0x04000011, 0x80081000, 0x4c040000, 0x4c080000,
+	0x0401f850, 0x5c001000, 0x5c000800, 0x04000023,
+	0x50200000, 0x801428f0, 0x80140540, 0x44004000,
+	0x80244840, 0x04000004, 0x80081000, 0x801c3800,
+	0x0401f7cb, 0x59a00a0a, 0x82040c00, 0x00000003,
+	0x82040d00, 0x000000fc, 0x80040904, 0x59a00407,
+	0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+	0x59a01a09, 0x900c19c0, 0x800c1d40, 0x4a03c014,
+	0x03800000, 0x412c0000, 0x0201f000, 0x00103a28,
+	0x0401f830, 0x04000005, 0x48174406, 0x4a03c014,
+	0x03800000, 0x0401f463, 0x4a03c014, 0x03800000,
+	0x0401f4ac, 0x4a03c014, 0x03800000, 0x0401f4ad,
+	0x0401f836, 0x04000010, 0x0401f862, 0x0402000f,
+	0x40080800, 0x0401f85f, 0x0402000c, 0x400c0800,
+	0x0401f85c, 0x04020009, 0x0401f84b, 0x42000000,
+	0x00030d40, 0x80000040, 0x040207ff, 0x82000540,
+	0x00000001, 0x1c01f000, 0x0401f843, 0x80000580,
+	0x0401f7fd, 0x0401f821, 0x0400000a, 0x82040d40,
+	0x00000001, 0x0401f84b, 0x04020007, 0x0401f87e,
+	0x0401f898, 0x0401f838, 0x82000540, 0x00000001,
+	0x1c01f000, 0x0401f834, 0x80000580, 0x0401f7fd,
+	0x40041800, 0x0401f811, 0x0400000c, 0x0401f83d,
+	0x0402000b, 0x40080800, 0x0401f83a, 0x04020008,
+	0x400c0800, 0x0401ffe8, 0x04000004, 0x0401f826,
+	0x82000540, 0x00000001, 0x1c01f000, 0x0401f822,
+	0x80000580, 0x0401f7fd, 0x4c040000, 0x42000800,
+	0x00000064, 0x4a03c013, 0x03800300, 0x80040840,
+	0x04000016, 0x59e00013, 0x82000500, 0x00000300,
+	0x82000580, 0x00000300, 0x040207f7, 0x42000000,
+	0x00000064, 0x80000040, 0x040207ff, 0x4a03c013,
+	0x01000000, 0x42000000, 0x00000064, 0x80000040,
+	0x040207ff, 0x4a03c013, 0x02000000, 0x82000540,
+	0x00000001, 0x0401f002, 0x80000580, 0x5c000800,
+	0x1c01f000, 0x4a03c013, 0x01000000, 0x42000000,
+	0x00000064, 0x80000040, 0x040207ff, 0x4a03c013,
+	0x02000200, 0x42000000, 0x00000064, 0x80000040,
+	0x040207ff, 0x4a03c013, 0x01000100, 0x1c01f000,
+	0x42002000, 0x00000008, 0x82040500, 0x00000080,
+	0x800000c2, 0x82000540, 0x01000000, 0x4803c013,
+	0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+	0x4a03c013, 0x02000200, 0x42000000, 0x00000064,
+	0x80000040, 0x040207ff, 0x4a03c013, 0x02000000,
+	0x800408c2, 0x80102040, 0x040207ec, 0x4a03c013,
+	0x01000100, 0x42000000, 0x00000064, 0x80000040,
+	0x040207ff, 0x4a03c013, 0x02000200, 0x42000000,
+	0x00000064, 0x80000040, 0x040207ff, 0x59e00013,
+	0x82000500, 0x00000100, 0x4a03c013, 0x02000000,
+	0x4c040000, 0x42000800, 0x00000064, 0x59e00013,
+	0x82000500, 0x00000100, 0x80040840, 0x04000003,
+	0x80000540, 0x040207fa, 0x80000540, 0x5c000800,
+	0x1c01f000, 0x4a03c013, 0x01000100, 0x42001000,
+	0x00000008, 0x80000d80, 0x42000000, 0x00000064,
+	0x80000040, 0x040207ff, 0x4a03c013, 0x02000200,
+	0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+	0x59e00013, 0x82000500, 0x00000100, 0x80000110,
+	0x800408c2, 0x80040d40, 0x4a03c013, 0x02000000,
+	0x80081040, 0x040207ed, 0x40042800, 0x1c01f000,
+	0x4a03c013, 0x01000100, 0x42000000, 0x00000064,
+	0x80000040, 0x040207ff, 0x4a03c013, 0x02000200,
+	0x42000000, 0x00000064, 0x80000040, 0x040207ff,
+	0x4a03c013, 0x02000000, 0x1c01f000, 0x59a00407,
+	0x59a80837, 0x48035037, 0x48074407, 0x59a00a09,
+	0x82040480, 0x00000014, 0x04021003, 0x42000800,
+	0x000007d0, 0x59a80038, 0x48075038, 0x48034209,
+	0x0201f000, 0x001022c0, 0x836c0580, 0x00000000,
+	0x0400000e, 0x59a80006, 0x59a00c06, 0x80041580,
+	0x82081500, 0x00000040, 0x02000000, 0x001022c0,
+	0x80080580, 0x48035006, 0x0201f800, 0x00100699,
+	0x0201f000, 0x001022c0, 0x59a00406, 0x59a80806,
+	0x48035006, 0x80040d80, 0x8c040d0c, 0x02020800,
+	0x00100699, 0x59a00207, 0x48035007, 0x59a00407,
+	0x48035008, 0x0201f000, 0x001022c0, 0x800409c0,
+	0x04000005, 0x4a034406, 0x00000001, 0x0201f000,
+	0x0010230c, 0x0201f800, 0x0010513b, 0x04020005,
+	0x4a034406, 0x00000016, 0x0201f000, 0x0010230c,
+	0x836c0580, 0x00000003, 0x04000005, 0x4a034406,
+	0x00000007, 0x0201f000, 0x0010230c, 0x59a00c06,
+	0x82040500, 0xffffff00, 0x02020000, 0x00102310,
+	0x82041580, 0x000000ff, 0x04020007, 0x59a80010,
+	0x82000500, 0x000000ff, 0x82001540, 0x0000ff00,
+	0x0401f011, 0x82040400, 0x0010210e, 0x50000000,
+	0x80000110, 0x82000580, 0x00000080, 0x02000000,
+	0x00102310, 0x59a80010, 0x82000500, 0x000000ff,
+	0x80041580, 0x02000000, 0x00102310, 0x840409c0,
+	0x80041540, 0x0201f800, 0x0002075a, 0x04020005,
+	0x4a034406, 0x00000003, 0x0201f000, 0x0010230c,
+	0x48ee6021, 0x480a621c, 0x4a02641c, 0x0000bc09,
+	0x4a026406, 0x00000001, 0x0201f800, 0x00103a00,
+	0x04020007, 0x0201f800, 0x0002077d, 0x4a034406,
+	0x00000002, 0x0201f000, 0x0010230c, 0x497a5a04,
+	0x497a5805, 0x4a025c04, 0x00008000, 0x4a01d809,
+	0x001027f9, 0x492e6008, 0x42027000, 0x00000032,
+	0x0201f000, 0x000207a1, 0x800409c0, 0x04000005,
+	0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+	0x0201f800, 0x0010513b, 0x04020005, 0x4a034406,
+	0x00000016, 0x0201f000, 0x0010230c, 0x836c0580,
+	0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x59a00c06, 0x82040500,
+	0xffffff00, 0x02020000, 0x00102310, 0x82041580,
+	0x000000ff, 0x04020007, 0x59a80010, 0x82000500,
+	0x000000ff, 0x82001540, 0x0000ff00, 0x0401f011,
+	0x82040400, 0x0010210e, 0x50000000, 0x80000110,
+	0x82000580, 0x00000080, 0x02000000, 0x00102310,
+	0x59a80010, 0x82000500, 0x000000ff, 0x80041580,
+	0x02000000, 0x00102310, 0x840409c0, 0x80041540,
+	0x0201f800, 0x0002075a, 0x04020005, 0x4a034406,
+	0x00000003, 0x0201f000, 0x0010230c, 0x48ee6021,
+	0x480a621c, 0x4a02641c, 0x0000bc05, 0x4a026406,
+	0x00000001, 0x0201f800, 0x00103a00, 0x04020007,
+	0x0201f800, 0x0002077d, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x497a5a04, 0x497a5805,
+	0x4a025c04, 0x00008000, 0x4a01d809, 0x001027f9,
+	0x492e6008, 0x42027000, 0x00000032, 0x0201f000,
+	0x000207a1, 0x592c0005, 0x82000580, 0x01000000,
+	0x02020000, 0x001022c0, 0x4a034406, 0x00000004,
+	0x0201f000, 0x0010230c, 0x497b4406, 0x497b4207,
+	0x0201f800, 0x00103b25, 0x04000008, 0x59a80066,
+	0x59a8086a, 0x80040480, 0x59a80867, 0x48074406,
+	0x80041480, 0x480b4207, 0x49674407, 0x59a8000e,
+	0x48034209, 0x495f4409, 0x59a80020, 0x4803420b,
+	0x0201f000, 0x001022c0, 0x800409c0, 0x04000005,
+	0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+	0x59a00406, 0x8c000500, 0x0402000f, 0x59a80069,
+	0x81640480, 0x04001008, 0x59a8000b, 0x81500580,
+	0x04000009, 0x59a8006a, 0x59a81066, 0x80080580,
+	0x04000005, 0x4a034406, 0x00000018, 0x0201f000,
+	0x0010230c, 0x82000540, 0x00000001, 0x0201f800,
+	0x001015fe, 0x0201f800, 0x00103c80, 0x0201f000,
+	0x001022c0, 0x4803c856, 0x800409c0, 0x02020000,
+	0x00102314, 0x59a00406, 0x8c00051e, 0x04000008,
+	0x4803c856, 0x59a0020b, 0x82000480, 0x00000800,
+	0x04001015, 0x0201f000, 0x00102310, 0x4803c856,
+	0x59a0020b, 0x599c0a01, 0x80040480, 0x04021003,
+	0x0201f000, 0x00102310, 0x59a8000e, 0x81640580,
+	0x04000009, 0x4a034406, 0x00000018, 0x0201f000,
+	0x0010230c, 0x4a034406, 0x00000005, 0x0201f000,
+	0x0010230c, 0x59a80026, 0x8c00050a, 0x040007fa,
+	0x59a00406, 0x8c00051e, 0x04000036, 0x0201f800,
+	0x0002075a, 0x040007f4, 0x0201f800, 0x00103a00,
+	0x040007f1, 0x497a5a04, 0x59a00406, 0x4802620a,
+	0x59a00209, 0x4802640a, 0x59a00409, 0x4802620b,
+	0x59a0020d, 0x4802620c, 0x59a0040d, 0x4802640c,
+	0x59a0020e, 0x4802620d, 0x59a0040e, 0x4802640d,
+	0x59a00210, 0x4802620e, 0x59a00410, 0x4802640e,
+	0x59a0020b, 0x82000500, 0x0000fffc, 0x80000104,
+	0x4802640b, 0x0401f9d9, 0x040007d7, 0x48ee6021,
+	0x58ee580d, 0x5930020e, 0x59301c0e, 0x900c19c0,
+	0x800c1d40, 0x5930020c, 0x5930140c, 0x900811c0,
+	0x80081540, 0x592c0a05, 0x832c0400, 0x00000006,
+	0x0201f800, 0x00103a25, 0x4a01d809, 0x001029e5,
+	0x4a034000, 0x00000001, 0x49334001, 0x1c01f000,
+	0x0201f800, 0x00106c55, 0x0201f800, 0x00100ae0,
+	0x0401f86d, 0x497b5057, 0x4201d000, 0x00002710,
+	0x0201f800, 0x001060c6, 0x59c40880, 0x4c040000,
+	0x59c408a3, 0x4c040000, 0x497b4002, 0x0401f876,
+	0x0401f893, 0x4a03a005, 0x10000000, 0x0401f8b4,
+	0x0401f901, 0x04000048, 0x59c80001, 0x800001c0,
+	0x040007fc, 0x59c80018, 0x82000500, 0xf0000000,
+	0x59c00808, 0x82040d00, 0x0fffffff, 0x80040540,
+	0x48038008, 0x0201f800, 0x00100ec1, 0x59c00006,
+	0x4a038006, 0x10000000, 0x59c00009, 0x82000d00,
+	0x00e00000, 0x04020024, 0x4a03900d, 0x00000000,
+	0x59c80020, 0x82000500, 0xff000000, 0x82000580,
+	0x32000000, 0x0402001c, 0x4a03900d, 0x00000001,
+	0x59c80020, 0x82000500, 0xff000000, 0x82000580,
+	0xe1000000, 0x04020014, 0x4a03900d, 0x00000000,
+	0x59c80020, 0x82000500, 0x00ffffff, 0x4a03900d,
+	0x00000000, 0x59c80821, 0x82040d00, 0x00ffffff,
+	0x80040580, 0x04020008, 0x59a80010, 0x80040580,
+	0x04020005, 0x59c40005, 0x82000500, 0x000000f0,
+	0x04000006, 0x4803c856, 0x0401f8d7, 0x4a035057,
+	0x00000001, 0x0401f002, 0x0401f8e1, 0x42000000,
+	0x00000064, 0x80000040, 0x02000800, 0x001005d8,
+	0x59c00807, 0x82040d00, 0x0000000c, 0x040007fa,
+	0x0401f003, 0x4a035057, 0x00000001, 0x0401f8da,
+	0x0201f800, 0x00106f36, 0x0401f818, 0x4201d000,
+	0x000186a0, 0x0201f800, 0x001060c6, 0x5c000800,
+	0x480788a3, 0x5c000800, 0x48078880, 0x59a80057,
+	0x800001c0, 0x02000000, 0x001022c0, 0x0201f000,
+	0x00102318, 0x599c0201, 0x48035059, 0x41780800,
+	0x42001000, 0x00003b10, 0x0201f800, 0x001066a0,
+	0x480b505a, 0x1c01f000, 0x0201f800, 0x00106c4b,
+	0x59b800ea, 0x82000500, 0x00000007, 0x82000580,
+	0x00000003, 0x04020003, 0x4a0370e8, 0x00000001,
+	0x1c01f000, 0x42038000, 0x00007700, 0x4a038006,
+	0x30000000, 0x59c00007, 0x8c00050a, 0x040207fe,
+	0x59c00006, 0x59a00209, 0x59a00c09, 0x900409c0,
+	0x80040d40, 0x48078001, 0x59a0020e, 0x59a00c0e,
+	0x900409c0, 0x80040d40, 0x48078000, 0x59a0020b,
+	0x82000500, 0x0000fffc, 0x48038002, 0x48038003,
+	0x48038005, 0x497b9009, 0x59e00003, 0x82000540,
+	0x00008060, 0x4803c003, 0x1c01f000, 0x41780800,
+	0x8007a0ca, 0x83d3a400, 0x00007600, 0x42000800,
+	0x00000040, 0x0201f800, 0x00101345, 0x4a03a00a,
+	0x00000001, 0x4a03a005, 0x20000000, 0x59d00006,
+	0x4a03a005, 0x30000000, 0x59d00006, 0x8c00050a,
+	0x040207fe, 0x59d00005, 0x59a00210, 0x59a00c10,
+	0x900409c0, 0x80040d40, 0x4807a001, 0x59a0020d,
+	0x59a00c0d, 0x900409c0, 0x80040d40, 0x4807a000,
+	0x59a0020b, 0x82000500, 0x0000fffc, 0x4803a003,
+	0x4803a002, 0x4803a008, 0x1c01f000, 0x59a00002,
+	0x4803c857, 0x800001c0, 0x0402004a, 0x59a8005a,
+	0x48038880, 0x59c400a3, 0x82000540, 0x00002008,
+	0x8400053a, 0x480388a3, 0x59c40008, 0x8400054e,
+	0x82000500, 0xffffffe1, 0x48038808, 0x59c80040,
+	0x84000534, 0x48039040, 0x0401f902, 0x04020013,
+	0x59a80010, 0x800000d0, 0x82000540, 0x00000011,
+	0x48039120, 0x59a80010, 0x82000500, 0x00ffffff,
+	0x82000540, 0x32000000, 0x48039121, 0x4a039123,
+	0xe1290008, 0x59a80010, 0x82000500, 0x00ffffff,
+	0x48039122, 0x0401f016, 0x59a80010, 0x82000500,
+	0x000000ff, 0x900009c0, 0x840001c0, 0x80040540,
+	0x82000540, 0x00000000, 0x48039120, 0x59a80010,
+	0x82000500, 0x000000ff, 0x82000540, 0x01000000,
+	0x48039121, 0x4a039123, 0x08210008, 0x59a80010,
+	0x82000500, 0x000000ff, 0x48039122, 0x497b9124,
+	0x59a80c5b, 0x80040800, 0x4807545b, 0x900409c0,
+	0x82040540, 0x0000aaaa, 0x48039125, 0x497b9126,
+	0x497b9127, 0x0401f8cf, 0x04020004, 0x4a039100,
+	0x0000e980, 0x0401f003, 0x4a039100, 0x0000e9a0,
+	0x1c01f000, 0x82000540, 0x00000001, 0x0402500d,
+	0x4203e000, 0x80000000, 0x40e81000, 0x41780800,
+	0x42000000, 0x00000064, 0x0201f800, 0x001066a0,
+	0x59940024, 0x80080400, 0x48032824, 0x80000580,
+	0x1c01f000, 0x4d900000, 0x4dd00000, 0x4da40000,
+	0x4d140000, 0x417a3000, 0x0201f800, 0x001070d8,
+	0x0201f800, 0x00106dc3, 0x5c022800, 0x5c034800,
+	0x5c03a000, 0x5c032000, 0x1c01f000, 0x59c80007,
+	0x8c000500, 0x04000003, 0x4a03900d, 0x00000030,
+	0x1c01f000, 0x4a038805, 0x00020000, 0x42000800,
+	0x0000003c, 0x0201f800, 0x00101345, 0x4a038891,
+	0x0000ffff, 0x59c80035, 0x48039035, 0x4a03900d,
+	0x00000040, 0x42038000, 0x00007700, 0x0201f800,
+	0x00100ec1, 0x42038000, 0x00007720, 0x0201f800,
+	0x00100ec1, 0x4a03a005, 0x20000000, 0x4a03a005,
+	0x30000000, 0x59d00806, 0x8c040d0a, 0x040207fe,
+	0x1c01f000, 0x4d300000, 0x4031d800, 0x58ef400b,
+	0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200,
+	0x5c026000, 0x02000000, 0x00102304, 0x4d300000,
+	0x59a26001, 0x59a00000, 0x4000b000, 0x80000000,
+	0x48034000, 0x592c0001, 0x80000540, 0x0400001e,
+	0x40025800, 0x8058b040, 0x040207fb, 0x58ec1007,
+	0x58ec1808, 0x592c0a05, 0x4d2c0000, 0x58ec000d,
+	0x40025800, 0x592c0204, 0x5c025800, 0x82000580,
+	0x00000103, 0x04000008, 0x832c0400, 0x00000006,
+	0x0201f800, 0x00103a25, 0x4a01d809, 0x001029e5,
+	0x0401f007, 0x832c0400, 0x00000006, 0x0201f800,
+	0x00103a28, 0x4a01d809, 0x001029e5, 0x5c026000,
+	0x1c01f000, 0x58ec000d, 0x40025800, 0x592c0204,
+	0x82000580, 0x00000103, 0x04020006, 0x0201f800,
+	0x0002077d, 0x5c026000, 0x0201f000, 0x001022c0,
+	0x58ec000d, 0x40025800, 0x592c0404, 0x8400055e,
+	0x48025c04, 0x42028800, 0x000007fd, 0x42003000,
+	0x00fffffd, 0x0201f800, 0x001045a6, 0x04000003,
+	0x80000580, 0x0401f004, 0x59a26001, 0x0201f800,
+	0x0010937d, 0x5c026000, 0x02000000, 0x0010230c,
+	0x4d300000, 0x4a01d809, 0x00102a38, 0x0401f7dc,
+	0x592c0005, 0x82000580, 0x01000000, 0x02000000,
+	0x00102318, 0x4d300000, 0x59a26001, 0x5930020b,
+	0x59301c0a, 0x900001c0, 0x800c1d40, 0x5930040d,
+	0x5930120d, 0x900001c0, 0x80081540, 0x592c0a05,
+	0x832c0400, 0x00000006, 0x0201f800, 0x00103a28,
+	0x4a01d809, 0x001029e5, 0x4a034000, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x4933c857, 0x4c300000,
+	0x5930040b, 0x82000c80, 0x0000000e, 0x04001004,
+	0x4a025a05, 0x0000000e, 0x0401f003, 0x48025a05,
+	0x0401f00c, 0x800409c0, 0x0400000a, 0x4c040000,
+	0x0201f800, 0x00103a00, 0x5c000800, 0x04000003,
+	0x40040000, 0x0401f7f0, 0x80000580, 0x0401f003,
+	0x82000540, 0x00000001, 0x5c006000, 0x1c01f000,
+	0x59a00206, 0x82000580, 0x00000044, 0x1c01f000,
+	0x4807c857, 0x800409c0, 0x0400000c, 0x0201f800,
+	0x00101650, 0x04020009, 0x42000000, 0x00000002,
+	0x0201f800, 0x0010188c, 0x42000000, 0x00000002,
+	0x0201f800, 0x00101821, 0x59a00406, 0x82000500,
+	0x00000007, 0x0c01f001, 0x00102a8c, 0x00102aa1,
+	0x00102ab7, 0x00102a8a, 0x00102a8a, 0x00102a8a,
+	0x00102a8a, 0x00102a8a, 0x0201f000, 0x00102310,
+	0x42000800, 0x000000c0, 0x0201f800, 0x0010193f,
+	0x82040540, 0x00000002, 0x42000800, 0x000000c0,
+	0x0201f800, 0x00101944, 0x42000800, 0x00000000,
+	0x0201f800, 0x0010193f, 0x82040540, 0x00000008,
+	0x42000800, 0x00000000, 0x0201f800, 0x00101944,
+	0x0401f00b, 0x42000800, 0x000000c0, 0x0201f800,
+	0x0010193f, 0x82040540, 0x00000001, 0x42000800,
+	0x000000c0, 0x0201f800, 0x00101944, 0x59c80040,
+	0x4c000000, 0x59a80010, 0x4c000000, 0x59c400a3,
+	0x4c000000, 0x59c40008, 0x4c000000, 0x0401f911,
+	0x04000021, 0x0201f800, 0x001005d8, 0x59a80821,
+	0x800409c0, 0x02020000, 0x00102314, 0x0201f800,
+	0x0010513b, 0x04020005, 0x4a034406, 0x00000016,
+	0x0201f000, 0x0010230c, 0x836c0580, 0x00000003,
+	0x02020000, 0x00102314, 0x59c408a4, 0x82040d00,
+	0x0000000f, 0x82040580, 0x00000000, 0x02020000,
+	0x00102314, 0x59c80040, 0x4c000000, 0x59a80010,
+	0x4c000000, 0x59c400a3, 0x4c000000, 0x59c40008,
+	0x4c000000, 0x59c40080, 0x4c000000, 0x59a0020f,
+	0x59a0bc0f, 0x905cb9c0, 0x805cbd40, 0x41784800,
+	0x41785000, 0x41785800, 0x41789000, 0x41789800,
+	0x0401fe21, 0x0201f800, 0x00106c55, 0x0201f800,
+	0x00100ae0, 0x4178c000, 0x497b4002, 0x0401f95c,
+	0x0401f9aa, 0x59a0020c, 0x59a00c0c, 0x80040d40,
+	0x04000002, 0x0401f9fb, 0x0401f9fa, 0x0401fe68,
+	0x8060c1c0, 0x04020014, 0x0401fa98, 0x0401feb2,
+	0x0402000e, 0x0201f800, 0x001018d3, 0x04020008,
+	0x4a034406, 0x00000017, 0x0201f800, 0x0010230c,
+	0x4203e000, 0x50000000, 0x0401f000, 0x42005800,
+	0x0000aaaa, 0x0401f058, 0x59c80001, 0x800001c0,
+	0x040007ee, 0x59c80801, 0x800409c0, 0x04000006,
+	0x0401fa70, 0x40240000, 0x80280540, 0x802c0540,
+	0x0402004d, 0x59a00002, 0x82000580, 0xfeedbeef,
+	0x04000004, 0x42008800, 0x10000000, 0x0401f003,
+	0x42008800, 0x10000004, 0x0401fa19, 0x4a034002,
+	0xfeedbeef, 0x0401fa71, 0x0401fa97, 0x0401fea8,
+	0x59c40005, 0x8c000534, 0x04000004, 0x42005800,
+	0x0000bbbb, 0x0401f038, 0x0401fe83, 0x04020007,
+	0x42005800, 0x0000cccc, 0x485f420f, 0x905cb9c0,
+	0x485f440f, 0x0401f030, 0x59a0040c, 0x800001c0,
+	0x0400000e, 0x59a26000, 0x5930000d, 0x800001c0,
+	0x040207be, 0x59a26001, 0x5930080d, 0x800409c0,
+	0x040207ba, 0x804891c0, 0x040207b8, 0x804c99c0,
+	0x040207b6, 0x0401f87a, 0x805cb840, 0x04000005,
+	0x40240000, 0x80280540, 0x802c0540, 0x0402001a,
+	0x42000000, 0x00030d40, 0x80000040, 0x04020012,
+	0x59c00007, 0x82000500, 0x000501c0, 0x0402000b,
+	0x0201f800, 0x001018d3, 0x04020008, 0x4a034406,
+	0x00000017, 0x0201f800, 0x0010230c, 0x4203e000,
+	0x50000000, 0x0401f000, 0x42005800, 0x0000dddd,
+	0x0401f005, 0x59c00807, 0x82040d00, 0x0000000c,
+	0x040007ea, 0x0401fe5c, 0x59a0040c, 0x800001c0,
+	0x04000002, 0x0401f856, 0x0401fe6b, 0x40240000,
+	0x80280540, 0x802c0540, 0x04020003, 0x805cb9c0,
+	0x04020781, 0x0201f800, 0x00106f36, 0x0401fda3,
+	0x4201d000, 0x000186a0, 0x0201f800, 0x001060c6,
+	0x5c000800, 0x48078880, 0x5c000800, 0x48078808,
+	0x5c000800, 0x480788a3, 0x5c000800, 0x48075010,
+	0x5c000800, 0x48079040, 0x0201f800, 0x00100969,
+	0x59a00406, 0x82000500, 0x00000003, 0x82000580,
+	0x00000002, 0x0400002c, 0x42000800, 0x000000c0,
+	0x0201f800, 0x0010193f, 0x82040500, 0xfffffffc,
+	0x42000800, 0x000000c0, 0x0201f800, 0x00101944,
+	0x42000800, 0x00000000, 0x0201f800, 0x0010193f,
+	0x82040500, 0xfffffff7, 0x42000800, 0x00000000,
+	0x0201f800, 0x00101944, 0x42000800, 0x00000000,
+	0x0201f800, 0x0010193f, 0x82040500, 0xfffffffb,
+	0x42000800, 0x00000000, 0x0201f800, 0x00101944,
+	0x4a0388a7, 0x0000f7f7, 0x42006000, 0xbeffffff,
+	0x42006800, 0x80018000, 0x0201f800, 0x0010427d,
+	0x42006000, 0xfffeffff, 0x41786800, 0x0201f800,
+	0x0010427d, 0x402c0000, 0x80280540, 0x80240540,
+	0x02000000, 0x001022c0, 0x48274406, 0x482b4207,
+	0x482f4407, 0x0201f000, 0x0010231c, 0x59a26000,
+	0x813261c0, 0x0400000e, 0x59325808, 0x812e59c0,
+	0x0400000b, 0x0201f800, 0x0002077d, 0x0201f800,
+	0x001007fd, 0x59a26001, 0x59325808, 0x0201f800,
+	0x0002077d, 0x0201f800, 0x001007fd, 0x1c01f000,
+	0x42000800, 0x000000ef, 0x0201f800, 0x001015eb,
+	0x59c400a3, 0x8400055a, 0x8400053a, 0x480388a3,
+	0x0201f800, 0x0010163b, 0x0402000a, 0x42000000,
+	0x00000001, 0x0201f800, 0x0010188c, 0x42000000,
+	0x00000001, 0x0201f800, 0x00101821, 0x0401f013,
+	0x0201f800, 0x00101642, 0x04020008, 0x41780000,
+	0x0201f800, 0x0010188c, 0x41780000, 0x0201f800,
+	0x00101821, 0x0401f009, 0x42000000, 0x00000002,
+	0x0201f800, 0x0010188c, 0x42000000, 0x00000002,
+	0x0201f800, 0x00101821, 0x42000800, 0x00000000,
+	0x0201f800, 0x0010193f, 0x82040540, 0x00000004,
+	0x42000800, 0x00000000, 0x0201f800, 0x00101944,
+	0x4201d000, 0x00000014, 0x0201f800, 0x0010608e,
+	0x59c40008, 0x8400054e, 0x82000500, 0xffffffe1,
+	0x48038808, 0x4a0388a7, 0x0000f7f7, 0x42001000,
+	0x04000001, 0x0201f800, 0x0010193d, 0x42006000,
+	0xbe20bfff, 0x42006800, 0x80018000, 0x0201f800,
+	0x0010427d, 0x42006000, 0xfffeffff, 0x41786800,
+	0x0201f800, 0x0010427d, 0x4200b000, 0x00001388,
+	0x4201d000, 0x00000014, 0x4c580000, 0x0201f800,
+	0x0010608e, 0x0201f800, 0x001018d3, 0x5c00b000,
+	0x04000004, 0x8058b040, 0x040207f6, 0x0401f025,
+	0x59c40005, 0x8c000534, 0x04020007, 0x59c400a4,
+	0x82000500, 0x0000000f, 0x82000580, 0x00000008,
+	0x0402001c, 0x42006000, 0x00020000, 0x0201f800,
+	0x00104282, 0x4201d000, 0x00000064, 0x0201f800,
+	0x0010608e, 0x42006000, 0xfeffffff, 0x42006800,
+	0x02000000, 0x0201f800, 0x0010427d, 0x42006000,
+	0xfdffffff, 0x41786800, 0x0201f800, 0x0010427d,
+	0x4a038805, 0x04000001, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000580, 0x00000000, 0x04000003,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4803c856,
+	0x42038000, 0x00007700, 0x0201f800, 0x00100ec1,
+	0x59c00006, 0x59a0040c, 0x800001c0, 0x0400003f,
+	0x59a03c0c, 0x59a00209, 0x59a01c09, 0x900c19c0,
+	0x800c1d40, 0x59a0020e, 0x59a0240e, 0x901021c0,
+	0x80102540, 0x59a0020b, 0x82000500, 0x0000fffc,
+	0x59a0140b, 0x900811c0, 0x80081540, 0x480b8003,
+	0x0201f800, 0x0002075a, 0x02000800, 0x001005d8,
+	0x49334000, 0x0201f800, 0x001007e4, 0x4a025a04,
+	0x00000018, 0x4a025805, 0x00abcdef, 0x492e6008,
+	0x492e600b, 0x481e600d, 0x4a02600c, 0x00000004,
+	0x832c0400, 0x00000011, 0x4802600a, 0x42001000,
+	0x0000000c, 0x821c0d80, 0x00000001, 0x04000004,
+	0x801c3840, 0x0401f963, 0x0401f004, 0x41783800,
+	0x0401f960, 0x0401f011, 0x821c0c80, 0x00000005,
+	0x04001005, 0x40043800, 0x42001000, 0x0000003c,
+	0x0401f006, 0x80001580, 0x82081400, 0x0000000c,
+	0x801c3840, 0x040207fd, 0x832c0400, 0x00000005,
+	0x0401f950, 0x040207f1, 0x497b9009, 0x59e00003,
+	0x82000540, 0x00008060, 0x4803c003, 0x4a038009,
+	0x00e00000, 0x1c01f000, 0x4803c856, 0x41780800,
+	0x8007a0ca, 0x83d3a400, 0x00007600, 0x42000800,
+	0x00000040, 0x0201f800, 0x00101345, 0x4a03a00a,
+	0x00000001, 0x4a03a005, 0x20000000, 0x59d00006,
+	0x4a03a005, 0x30000000, 0x59d00006, 0x8c00050a,
+	0x040207fe, 0x59d00005, 0x59a0020c, 0x800001c0,
+	0x0400003f, 0x59a03a0c, 0x59a00210, 0x59a01c10,
+	0x900c19c0, 0x800c1d40, 0x59a0020d, 0x59a0240d,
+	0x901021c0, 0x80102540, 0x59a0120b, 0x82081500,
+	0x0000fffc, 0x59a0040b, 0x900001c0, 0x80081540,
+	0x480ba003, 0x0201f800, 0x0002075a, 0x02000800,
+	0x001005d8, 0x49334001, 0x0201f800, 0x001007e4,
+	0x4a025a04, 0x00000018, 0x4a025805, 0x00abcdef,
+	0x492e6008, 0x492e600b, 0x481e600d, 0x4a02600c,
+	0x00000004, 0x832c0400, 0x00000011, 0x4802600a,
+	0x42001000, 0x0000000c, 0x821c0d80, 0x00000001,
+	0x04000004, 0x801c3840, 0x0401f906, 0x0401f004,
+	0x41783800, 0x0401f903, 0x0401f011, 0x821c0c80,
+	0x00000005, 0x04001005, 0x40043800, 0x42001000,
+	0x0000003c, 0x0401f006, 0x80001580, 0x82081400,
+	0x0000000c, 0x801c3840, 0x040207fd, 0x832c0400,
+	0x00000005, 0x0401f8f3, 0x040207f1, 0x1c01f000,
+	0x4803c856, 0x59a0020c, 0x800001c0, 0x04000024,
+	0x824c0580, 0x00000002, 0x04000040, 0x59a26001,
+	0x5930380d, 0x801c39c0, 0x0400003c, 0x801c3840,
+	0x481e600d, 0x5932580b, 0x5930080a, 0x50042000,
+	0x58041801, 0x58041002, 0x82081500, 0xfffffffc,
+	0x5930000c, 0x80000000, 0x82000d80, 0x00000005,
+	0x04020009, 0x497a600c, 0x592e5801, 0x812e59c0,
+	0x0400001a, 0x492e600b, 0x832c0c00, 0x00000005,
+	0x0401f005, 0x4802600c, 0x5930080a, 0x82040c00,
+	0x00000003, 0x4806600a, 0x0401f010, 0x59a0120b,
+	0x82081500, 0x0000fffc, 0x59a0040b, 0x900001c0,
+	0x80081540, 0x480ba003, 0x59a0020d, 0x59a0240d,
+	0x901021c0, 0x80102540, 0x59a00210, 0x59a01c10,
+	0x900c19c0, 0x800c1d40, 0x4201d000, 0x00003a98,
+	0x0201f800, 0x001060c6, 0x480ba002, 0x59a80059,
+	0x4803a008, 0x4813a000, 0x480fa001, 0x4a03a005,
+	0x10000000, 0x02005800, 0x001005d8, 0x804c9800,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4847c857,
+	0x59a0040c, 0x800001c0, 0x04000024, 0x82480580,
+	0x00000002, 0x04000042, 0x59a26000, 0x5930380d,
+	0x801c39c0, 0x0400003e, 0x801c3840, 0x481e600d,
+	0x5932580b, 0x5930080a, 0x50042000, 0x58041801,
+	0x58041002, 0x82081500, 0xfffffffc, 0x5930000c,
+	0x80000000, 0x82000d80, 0x00000005, 0x04020009,
+	0x497a600c, 0x592e5801, 0x812e59c0, 0x0400001d,
+	0x492e600b, 0x832c0c00, 0x00000005, 0x0401f005,
+	0x4802600c, 0x5930080a, 0x82040c00, 0x00000003,
+	0x4806600a, 0x0401f013, 0x82440580, 0x10000000,
+	0x0402001f, 0x59a0020e, 0x59a0240e, 0x901021c0,
+	0x80102540, 0x59a00209, 0x59a01c09, 0x900c19c0,
+	0x800c1d40, 0x59a0020b, 0x82000500, 0x0000fffc,
+	0x59a0140b, 0x900811c0, 0x80081540, 0x480b8003,
+	0x48138000, 0x480f8001, 0x480b8002, 0x59c80018,
+	0x82000500, 0xf0000000, 0x59c02008, 0x82102500,
+	0x0fffffff, 0x80100540, 0x48038008, 0x48478006,
+	0x80489000, 0x8260c540, 0x00000001, 0x1c01f000,
+	0x59c00009, 0x4803c857, 0x82000d00, 0x00e00000,
+	0x0400000d, 0x485f420f, 0x905cb9c0, 0x485f440f,
+	0x8c00052e, 0x04000002, 0x80285000, 0x8c00052c,
+	0x04000002, 0x80244800, 0x8c00052a, 0x04000002,
+	0x802c5800, 0x1c01f000, 0x59a0020c, 0x800001c0,
+	0x04000024, 0x59d00806, 0x4807c857, 0x8c040d3e,
+	0x04000020, 0x4a03a005, 0x20000000, 0x4a03a005,
+	0x30000000, 0x59d00806, 0x8c040d0a, 0x040207fe,
+	0x824c0480, 0x00000003, 0x02021800, 0x001005d8,
+	0x404c0000, 0x0c01f001, 0x00102da1, 0x00102da3,
+	0x00102da9, 0x0201f800, 0x001005d8, 0x80000040,
+	0x40009800, 0x0401ff43, 0x0400000a, 0x0401ff41,
+	0x0401f008, 0x80000040, 0x40009800, 0x59d00806,
+	0x4807c857, 0x8c040d3e, 0x040207e3, 0x0401ff39,
+	0x1c01f000, 0x59a0040c, 0x800001c0, 0x04000024,
+	0x59c00807, 0x4807c857, 0x8c040d3e, 0x04000020,
+	0x59c00807, 0x4a038006, 0x20000000, 0x82480480,
+	0x00000003, 0x02021800, 0x001005d8, 0x40480000,
+	0x0c01f001, 0x00102dc4, 0x00102dc6, 0x00102dce,
+	0x0201f800, 0x001005d8, 0x80000040, 0x40009000,
+	0x42008800, 0x10000004, 0x0401ff65, 0x0400000c,
+	0x0401ff63, 0x0401f00a, 0x80000040, 0x40009000,
+	0x59c00807, 0x4807c857, 0x8c040d3e, 0x040207e5,
+	0x42008800, 0x10000004, 0x0401ff59, 0x1c01f000,
+	0x492fc857, 0x4000a800, 0x4a03b805, 0x20000000,
+	0x59dc0006, 0x4a03b805, 0x30000000, 0x4813b800,
+	0x480fb801, 0x480bb802, 0x4857b803, 0x4a03b805,
+	0x30000002, 0x59dc0006, 0x4a03b805, 0x70000001,
+	0x59dc0006, 0x4a03b805, 0x10000000, 0x59dc0006,
+	0x8c00053e, 0x040007fe, 0x4a03b805, 0x20000000,
+	0x59dc0006, 0x59dc2000, 0x59dc1801, 0x801c39c0,
+	0x0400000a, 0x4d2c0000, 0x0201f800, 0x001007e4,
+	0x5c000800, 0x02000800, 0x001005d8, 0x4a025a04,
+	0x0000000a, 0x492c0801, 0x1c01f000, 0x42006000,
+	0x00102fb2, 0x0201f800, 0x00101345, 0x4a03902c,
+	0x00200000, 0x4200b000, 0x000001f4, 0x59c8002c,
+	0x8c00052c, 0x04000007, 0x8058b040, 0x040207fc,
+	0x42000000, 0x00004003, 0x41781000, 0x0401f196,
+	0x50301000, 0x41784800, 0x4a03902d, 0x00008000,
+	0x4200b000, 0x000001f4, 0x59c8002c, 0x8c000534,
+	0x04000007, 0x8058b040, 0x040207fc, 0x42000000,
+	0x00004003, 0x41781000, 0x0401f187, 0x0401f8f8,
+	0x80244800, 0x40240000, 0x82000580, 0x000003b1,
+	0x040207fb, 0x0401f988, 0x41784800, 0x0401f920,
+	0x80244800, 0x40240000, 0x82000580, 0x000003b1,
+	0x040207fb, 0x80306000, 0x82300580, 0x00102fb4,
+	0x040207e0, 0x59a80863, 0x800409c0, 0x04000007,
+	0x42000000, 0x00004004, 0x42001000, 0x00000002,
+	0x59a81862, 0x0401f16c, 0x42006000, 0x00102fb2,
+	0x4a035064, 0x00000004, 0x50301000, 0x41784800,
+	0x4a03902d, 0x00004000, 0x4200b000, 0x000001f4,
+	0x59c8002c, 0x8c000532, 0x04000007, 0x8058b040,
+	0x040207fc, 0x42000000, 0x00004003, 0x41781000,
+	0x0401f159, 0x0401f8ca, 0x80244800, 0x40240000,
+	0x82000580, 0x00000154, 0x040207fb, 0x0401f95a,
+	0x41784800, 0x0401f8f2, 0x80244800, 0x40240000,
+	0x82000580, 0x00000154, 0x040207fb, 0x80306000,
+	0x82300580, 0x00102fb4, 0x040207e0, 0x59a80863,
+	0x800409c0, 0x04000007, 0x42000000, 0x00004004,
+	0x42001000, 0x00000004, 0x59a81862, 0x0401f13e,
+	0x42006000, 0x00102fb2, 0x497b5064, 0x50301000,
+	0x41784800, 0x4a03902d, 0x00001000, 0x4200b000,
+	0x000001f4, 0x59c8002c, 0x8c00052e, 0x04000007,
+	0x8058b040, 0x040207fc, 0x42000000, 0x00004003,
+	0x41781000, 0x0401f12c, 0x0401f89d, 0x80244800,
+	0x40240000, 0x82000580, 0x00000088, 0x040207fb,
+	0x0401f92d, 0x41784800, 0x0401f8c5, 0x80244800,
+	0x40240000, 0x82000580, 0x00000088, 0x040207fb,
+	0x80306000, 0x82300580, 0x00102fb4, 0x040207e0,
+	0x59a80863, 0x800409c0, 0x04000007, 0x42000000,
+	0x00004004, 0x42001000, 0x00000001, 0x59a81862,
+	0x0401f111, 0x42006000, 0x00102fb2, 0x50301000,
+	0x41784800, 0x4a03902d, 0x00000800, 0x0401f87c,
+	0x80244800, 0x40240000, 0x82000580, 0x00000018,
+	0x040207fb, 0x0401f90c, 0x41784800, 0x0401f8a4,
+	0x80244800, 0x40240000, 0x82000580, 0x00000018,
+	0x040207fb, 0x80306000, 0x82300580, 0x00102fb4,
+	0x040207eb, 0x59a80863, 0x800409c0, 0x04000007,
+	0x42000000, 0x00004004, 0x42001000, 0x00000010,
+	0x59a81862, 0x0401f0f0, 0x42006000, 0x00102fb2,
+	0x50301000, 0x41784800, 0x4a03902d, 0x00000400,
+	0x0401f85b, 0x80244800, 0x40240000, 0x82000580,
+	0x00000088, 0x040207fb, 0x0401f8eb, 0x41784800,
+	0x0401f883, 0x80244800, 0x40240000, 0x82000580,
+	0x00000088, 0x040207fb, 0x80306000, 0x82300580,
+	0x00102fb4, 0x040207eb, 0x59a80863, 0x800409c0,
+	0x04000007, 0x42000000, 0x00004004, 0x42001000,
+	0x00000008, 0x59a81862, 0x0401f0cf, 0x42006000,
+	0x00102fb2, 0x50301000, 0x41784800, 0x4a03902d,
+	0x00002000, 0x4200b000, 0x000001f4, 0x59c8002c,
+	0x8c000530, 0x04000007, 0x8058b040, 0x040207fc,
+	0x42000000, 0x00004003, 0x41781000, 0x0401f0be,
+	0x59c8002c, 0x82000500, 0xffe0ffff, 0x82080d00,
+	0x001f0000, 0x80040540, 0x4803902c, 0x0401f828,
+	0x80244800, 0x40240000, 0x82000580, 0x00000110,
+	0x040207fb, 0x0401f8b8, 0x41784800, 0x0401f850,
+	0x59c80034, 0x82080d00, 0x001f0000, 0x82000500,
+	0x001f0000, 0x80040580, 0x04000006, 0x59a80063,
+	0x80000000, 0x48035063, 0x40240000, 0x48035062,
+	0x80244800, 0x40240000, 0x82000580, 0x00000110,
+	0x040207ef, 0x80306000, 0x82300580, 0x00102fb4,
+	0x040207cd, 0x59a80863, 0x800409c0, 0x04000006,
+	0x42000000, 0x00004004, 0x42001000, 0x00000020,
+	0x59a81862, 0x0201f000, 0x001022c0, 0x59c8002c,
+	0x82000500, 0xffff0000, 0x82080d00, 0x0000ffff,
+	0x80040540, 0x4803902c, 0x40080000, 0x48039028,
+	0x48039029, 0x59a80064, 0x82000580, 0x00000004,
+	0x04000004, 0x40080000, 0x4803902a, 0x4803902b,
+	0x59c8082d, 0x82040d00, 0xfffffc00, 0x40240000,
+	0x80040d40, 0x4807902d, 0x4200b000, 0x000001f4,
+	0x59c8002c, 0x82000500, 0x18000000, 0x04000007,
+	0x8058b040, 0x040207fb, 0x42000000, 0x00004003,
+	0x41781000, 0x0401f06c, 0x4a03902e, 0x00000001,
+	0x4200b000, 0x000001f4, 0x59c8002e, 0x8c000500,
+	0x04000006, 0x8058b040, 0x040207fc, 0x42000000,
+	0x00004003, 0x0401f060, 0x1c01f000, 0x41783800,
+	0x59c8082d, 0x82040d00, 0xfffffc00, 0x40240000,
+	0x80040d40, 0x4807902d, 0x4200b000, 0x000001f4,
+	0x59c8002c, 0x82000500, 0x18000000, 0x04000007,
+	0x8058b040, 0x040207fb, 0x42000000, 0x00004003,
+	0x41781000, 0x0401f04c, 0x59c80030, 0x59c80830,
+	0x80040580, 0x040207fd, 0x40041800, 0x59c80031,
+	0x59c80831, 0x80040580, 0x040207fd, 0x40042000,
+	0x59c80032, 0x59c80832, 0x80040580, 0x040207fd,
+	0x40042800, 0x59c80033, 0x59c80833, 0x80040580,
+	0x040207fd, 0x40043000, 0x400c0000, 0x80080580,
+	0x04000002, 0x801c3800, 0x40100000, 0x80080580,
+	0x04000002, 0x801c3800, 0x59a80064, 0x82000580,
+	0x00000004, 0x04000009, 0x40140000, 0x80080580,
+	0x04000002, 0x801c3800, 0x40180000, 0x80080580,
+	0x04000002, 0x801c3800, 0x59a80064, 0x82000580,
+	0x00000004, 0x0400000d, 0x59c80034, 0x59c80834,
+	0x80040580, 0x040207fd, 0x82040500, 0x0000ffff,
+	0x82080d00, 0x0000ffff, 0x80040580, 0x0400000e,
+	0x801c3800, 0x0401f00c, 0x59c80034, 0x59c80834,
+	0x80040580, 0x040207fd, 0x82040500, 0x000000ff,
+	0x82080d00, 0x000000ff, 0x80040580, 0x04000002,
+	0x801c3800, 0x801c39c0, 0x04000006, 0x59a80063,
+	0x801c0400, 0x48035063, 0x40240000, 0x48035062,
+	0x1c01f000, 0x48034206, 0x48074406, 0x480b4207,
+	0x480f4407, 0x48134208, 0x48174408, 0x0201f000,
+	0x001022c3, 0x42000000, 0x00600000, 0x80000040,
+	0x040207ff, 0x1c01f000, 0x5a5a5a5a, 0xa5a5a5a5,
+	0x59a00c0a, 0x800409c0, 0x02000000, 0x00102310,
+	0x82040480, 0x00000021, 0x02021000, 0x00102310,
+	0x82040480, 0x00000011, 0x04001003, 0x42000800,
+	0x00000010, 0x59a00208, 0x59a01407, 0x900811c0,
+	0x80081540, 0x59a00207, 0x59a01c06, 0x900c19c0,
+	0x800c1d40, 0x0201f800, 0x00103a00, 0x04000006,
+	0x0201f800, 0x00103a25, 0x4a01d809, 0x00102fd5,
+	0x1c01f000, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x4031d800, 0x58ef400b, 0x58ec0002,
+	0x82000580, 0x00000200, 0x02000000, 0x00102304,
+	0x59a00c0a, 0x82040480, 0x00000011, 0x04001003,
+	0x42000800, 0x00000010, 0x59a0040b, 0x59a0120b,
+	0x900811c0, 0x80081540, 0x59a00209, 0x59a01c08,
+	0x900c19c0, 0x800c1d40, 0x58ec0003, 0x0201f800,
+	0x00103a28, 0x4a01d809, 0x00102ff0, 0x1c01f000,
+	0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x59a00c0a,
+	0x82040480, 0x00000011, 0x02001000, 0x001022c0,
+	0x82040c80, 0x00000010, 0x59a00208, 0x59a01407,
+	0x900811c0, 0x80081540, 0x59a00207, 0x59a01c06,
+	0x900c19c0, 0x800c1d40, 0x82081400, 0x00000040,
+	0x58ec0003, 0x0201f800, 0x00103a25, 0x4a01d809,
+	0x0010300e, 0x1c01f000, 0x4031d800, 0x58ef400b,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x59a0040a, 0x82000c80, 0x00000010,
+	0x59a0040b, 0x59a0120b, 0x900811c0, 0x80081540,
+	0x59a00209, 0x59a01c08, 0x900c19c0, 0x800c1d40,
+	0x82081400, 0x00000040, 0x58ec0003, 0x0201f800,
+	0x00103a28, 0x4a01d809, 0x001022b9, 0x1c01f000,
+	0x48efc857, 0x59a00207, 0x59a01407, 0x900001c0,
+	0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+	0x800c1d40, 0x59a00406, 0x48034000, 0x480b4001,
+	0x480f4002, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x42000800, 0x00000010, 0x0201f800, 0x00103a25,
+	0x4a01d809, 0x00103043, 0x1c01f000, 0x4031d800,
+	0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x48efc857,
+	0x49a3c857, 0x492fc857, 0x592c0a04, 0x80040910,
+	0x04020005, 0x4a034406, 0x00000019, 0x0201f000,
+	0x0010230c, 0x4805d80c, 0x0401f00a, 0x4031d800,
+	0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x48efc857, 0x49a3c857,
+	0x48efc857, 0x49a3c857, 0x58ec000c, 0x80000040,
+	0x04000012, 0x4801d80c, 0x0201f800, 0x00103a00,
+	0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x42000800, 0x00000010, 0x58ec1007,
+	0x58ec1808, 0x0201f800, 0x00103a25, 0x4a01d809,
+	0x00103057, 0x1c01f000, 0x58ee580d, 0x48efc857,
+	0x49a3c857, 0x492fc857, 0x492f3006, 0x592c0404,
+	0x8400055e, 0x48025c04, 0x4a01d809, 0x00103081,
+	0x1c01f000, 0x58ee580d, 0x48efc857, 0x49a3c857,
+	0x492fc857, 0x592c0404, 0x8400051e, 0x48025c04,
+	0x59a00000, 0x59a01001, 0x59a01802, 0x80081400,
+	0x820c1c40, 0x00000000, 0x832c0400, 0x00000004,
+	0x42000800, 0x00000010, 0x0201f000, 0x00103a28,
+	0x800409c0, 0x04000005, 0x4a034406, 0x00000001,
+	0x0201f000, 0x0010230c, 0x836c0580, 0x00000003,
+	0x04000005, 0x4a034406, 0x00000007, 0x0201f000,
+	0x0010230c, 0x59a0320b, 0x82183500, 0x000000ff,
+	0x59a28c06, 0x0201f800, 0x00020245, 0x02020000,
+	0x00102310, 0x83440580, 0x000007fd, 0x04000008,
+	0x0201f800, 0x001049e7, 0x04000005, 0x4a034406,
+	0x00000009, 0x0201f000, 0x0010230c, 0x0201f800,
+	0x00103a00, 0x04020005, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x801831c0, 0x0400000a,
+	0x412c0800, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x40065800, 0x4a025c04, 0x00008000, 0x497a5a04,
+	0x0201f800, 0x00109100, 0x04020005, 0x4a034406,
+	0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809,
+	0x001030d2, 0x1c01f000, 0x592c0005, 0x82000580,
+	0x01000000, 0x04020005, 0x4a034406, 0x00000004,
+	0x0201f000, 0x0010230c, 0x592c0406, 0x82002d00,
+	0x0000ff00, 0x82000500, 0x000000ff, 0x80000904,
+	0x80040800, 0x82040480, 0x00000006, 0x04001003,
+	0x42000800, 0x00000005, 0x832ca400, 0x00000006,
+	0x4050a800, 0x4004b000, 0x0201f800, 0x0010ab28,
+	0x59a00407, 0x59a01207, 0x900811c0, 0x80081540,
+	0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40,
+	0x832c0400, 0x00000006, 0x4c140000, 0x0201f800,
+	0x00103a28, 0x5c002800, 0x801429c0, 0x04000003,
+	0x4a01d809, 0x001030ff, 0x1c01f000, 0x4031d800,
+	0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x592c0006, 0x82000500,
+	0xff000000, 0x80000904, 0x800409c0, 0x02000000,
+	0x00102304, 0x82040480, 0x0000000e, 0x04001003,
+	0x42000800, 0x0000000d, 0x592e5801, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x832ca400, 0x00000005,
+	0x4050a800, 0x4004b000, 0x0201f800, 0x0010ab28,
+	0x58ec1007, 0x58ec1808, 0x832c0400, 0x00000005,
+	0x0201f000, 0x00103a28, 0x0201f800, 0x00103a00,
+	0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x59a00c06, 0x82040500, 0x0000ff00,
+	0x840001c0, 0x82001480, 0x00000007, 0x02021000,
+	0x00102310, 0x0c01f001, 0x0010313d, 0x00103144,
+	0x0010314b, 0x0010314b, 0x0010314b, 0x0010314d,
+	0x00103152, 0x42000800, 0x0000000d, 0x42003800,
+	0x00103166, 0x4a034000, 0x0010b4eb, 0x0401f013,
+	0x42000800, 0x0000000d, 0x42003800, 0x00103166,
+	0x4a034000, 0x0010b4f8, 0x0401f00c, 0x0201f000,
+	0x00102310, 0x42000800, 0x00000008, 0x42003800,
+	0x00103179, 0x0401f005, 0x42000800, 0x00000004,
+	0x42003800, 0x001031c3, 0x59a00207, 0x59a01407,
+	0x900001c0, 0x80081540, 0x59a00209, 0x59a01c09,
+	0x900001c0, 0x800c1d40, 0x832c0400, 0x00000005,
+	0x4c1c0000, 0x0201f800, 0x00103a25, 0x5c003800,
+	0x481dd809, 0x1c01f000, 0x4031d800, 0x58ef400b,
+	0x58ee580d, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x4a03501f, 0x00000001,
+	0x4200b000, 0x0000000d, 0x59a0a800, 0x832ca400,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x0201f000,
+	0x001022c0, 0x4031d800, 0x58ef400b, 0x58ee580d,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x832ca400, 0x00000005, 0x50500000,
+	0x82001500, 0x000c0016, 0x02020000, 0x00102310,
+	0x82500c00, 0x00000003, 0x50040000, 0x82001500,
+	0x00000001, 0x02020000, 0x00102310, 0x50500000,
+	0x82001500, 0x00000028, 0x0400001d, 0x82081580,
+	0x00000028, 0x02020000, 0x00102310, 0x80500800,
+	0x50040000, 0x82001500, 0x00000013, 0x82081580,
+	0x00000013, 0x02020000, 0x00102310, 0x80040800,
+	0x50040000, 0x82001500, 0x00010000, 0x82081580,
+	0x00010000, 0x02020000, 0x00102310, 0x836c0580,
+	0x00000000, 0x04000012, 0x599c0019, 0x8c00050e,
+	0x0402000f, 0x0201f000, 0x00102310, 0x80500800,
+	0x50040000, 0x82001500, 0x00000013, 0x02020000,
+	0x00102310, 0x80040800, 0x50040000, 0x82001500,
+	0x00010000, 0x02020000, 0x00102310, 0x4200b000,
+	0x00000008, 0x4200a800, 0x0010b4e3, 0x0201f800,
+	0x0010ab17, 0x0201f000, 0x001022c0, 0x4031d800,
+	0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x4200b000,
+	0x00000004, 0x4200a800, 0x0010b8fa, 0x832ca400,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x59a80005,
+	0x84000550, 0x48035005, 0x0201f000, 0x001022c0,
+	0x0201f800, 0x00103a00, 0x04020005, 0x4a034406,
+	0x00000002, 0x0201f000, 0x0010230c, 0x59a00c06,
+	0x82040500, 0x0000ff00, 0x840001c0, 0x82001480,
+	0x00000006, 0x02021000, 0x00102310, 0x0c01f001,
+	0x001031ee, 0x001031f3, 0x001031f8, 0x001031f8,
+	0x001031f8, 0x001031fa, 0x42000800, 0x0000000d,
+	0x4200a000, 0x0010b4eb, 0x0401f00c, 0x42000800,
+	0x0000000d, 0x4200a000, 0x0010b4f8, 0x0401f007,
+	0x0201f000, 0x00102310, 0x42000800, 0x00000008,
+	0x4200a000, 0x0010b4e3, 0x4004b000, 0x832cac00,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x59a00207,
+	0x59a01407, 0x900001c0, 0x80081540, 0x59a00209,
+	0x59a01c09, 0x900001c0, 0x800c1d40, 0x832c0400,
+	0x00000005, 0x0201f000, 0x00103a28, 0x836c0580,
+	0x00000000, 0x04020005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x59a00406, 0x800001c0,
+	0x0400001a, 0x59a80005, 0x8c000514, 0x04000005,
+	0x42000000, 0x00000001, 0x40000800, 0x0401f003,
+	0x59a00207, 0x59a80853, 0x48035053, 0x0201f800,
+	0x0010163b, 0x04000022, 0x0201f800, 0x00101642,
+	0x0400001f, 0x0201f800, 0x00101649, 0x0400001c,
+	0x0201f800, 0x00101650, 0x04000019, 0x48075053,
+	0x0201f000, 0x00102310, 0x59c40801, 0x82040d00,
+	0x00018000, 0x82040580, 0x00000000, 0x04020004,
+	0x4a034406, 0x00000000, 0x0401f00d, 0x82040580,
+	0x00008000, 0x04020004, 0x4a034406, 0x00000001,
+	0x0401f007, 0x82040580, 0x00010000, 0x02020800,
+	0x001005d8, 0x4a034406, 0x00000003, 0x59a00406,
+	0x82000580, 0x00000002, 0x0402001f, 0x59c40006,
+	0x84000500, 0x48038806, 0x0201f800, 0x00106ede,
+	0x497b8880, 0x0201f800, 0x0010a9c0, 0x0201f800,
+	0x0010a9ce, 0x42000000, 0x0010b8ca, 0x0201f800,
+	0x0010aa47, 0x82000540, 0x00000001, 0x0201f800,
+	0x0010518c, 0x4a038808, 0x00000000, 0x4202d800,
+	0x00000004, 0x42001000, 0x00000001, 0x0201f800,
+	0x0010193d, 0x4a035049, 0x00000001, 0x0201f800,
+	0x001006d4, 0x0201f000, 0x001022c0, 0x800409c0,
+	0x04000005, 0x4a034406, 0x00000001, 0x0201f000,
+	0x0010230c, 0x836c0580, 0x00000003, 0x04000005,
+	0x4a034406, 0x00000007, 0x0201f000, 0x0010230c,
+	0x59a28c06, 0x59a0320b, 0x82183500, 0x000000ff,
+	0x0201f800, 0x00020245, 0x02020000, 0x00102310,
+	0x83440580, 0x000007fd, 0x04000008, 0x0201f800,
+	0x001049e7, 0x04000005, 0x42000800, 0x00000009,
+	0x0201f000, 0x0010230c, 0x0201f800, 0x00103a00,
+	0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x497a5a04, 0x4a025c04, 0x00008000,
+	0x0201f800, 0x00109115, 0x04020005, 0x4a034406,
+	0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809,
+	0x0010329e, 0x1c01f000, 0x592c0005, 0x82000d00,
+	0x0000ffff, 0x82000500, 0xffff0000, 0x82000580,
+	0x01000000, 0x04020005, 0x4a034406, 0x00000004,
+	0x0201f000, 0x0010230c, 0x80040904, 0x832ca400,
+	0x00000005, 0x4050a800, 0x4004b000, 0x0201f800,
+	0x0010ab28, 0x59a00207, 0x59a01407, 0x900001c0,
+	0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+	0x800c1d40, 0x832c0400, 0x00000005, 0x0201f000,
+	0x00103a28, 0x496fc857, 0x836c0580, 0x00000000,
+	0x04000005, 0x4a034406, 0x0000001a, 0x0201f000,
+	0x0010230c, 0x0201f800, 0x0010513b, 0x02020800,
+	0x00104142, 0x42000800, 0x00000020, 0x59a00407,
+	0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+	0x59a01a09, 0x900c19c0, 0x800c1d40, 0x419c0000,
+	0x49a3c857, 0x0201f800, 0x00103a25, 0x4a01d809,
+	0x001032da, 0x1c01f000, 0x4833c857, 0x4031d800,
+	0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x599c0200, 0x800001c0,
+	0x02000000, 0x00102310, 0x59a80005, 0x8c000512,
+	0x04000004, 0x599c0019, 0x8400050c, 0x48033819,
+	0x0201f800, 0x001097d7, 0x59a80005, 0x8c000514,
+	0x04000004, 0x599c0017, 0x84000508, 0x48033817,
+	0x0201f800, 0x00103b25, 0x04020004, 0x8c00050a,
+	0x02020000, 0x00102310, 0x4803c857, 0x8c000504,
+	0x04020004, 0x59c408a3, 0x84040d7a, 0x480788a3,
+	0x8c000502, 0x04020004, 0x59c408a3, 0x84040d08,
+	0x480788a3, 0x599c0c02, 0x8c000500, 0x04020004,
+	0x8c000516, 0x04000012, 0x0401f001, 0x82041480,
+	0x0000007f, 0x02021000, 0x00102310, 0x82041400,
+	0x0010210e, 0x50081000, 0x82081500, 0x000000ff,
+	0x8c000500, 0x04020006, 0x480b5010, 0x42000800,
+	0x00000003, 0x0201f800, 0x00106c78, 0x599c0019,
+	0x8c00050e, 0x0402000b, 0x59a80806, 0x8c040d14,
+	0x04000008, 0x42000800, 0x0010b4e3, 0x50040800,
+	0x82040d00, 0x00000028, 0x02020000, 0x00102310,
+	0x82000500, 0x00000030, 0x04000003, 0x80000108,
+	0x0401f003, 0x42000000, 0x00000002, 0x48039040,
+	0x42000800, 0x00000002, 0x82000400, 0x00103415,
+	0x50001000, 0x0201f800, 0x00106c78, 0x599c0201,
+	0x82000c80, 0x00000100, 0x02001000, 0x00102310,
+	0x82000c80, 0x00000841, 0x02021000, 0x00102310,
+	0x82000500, 0x00000007, 0x02020000, 0x00102310,
+	0x599c0401, 0x80000540, 0x02000000, 0x00102310,
+	0x599c0409, 0x599c0c07, 0x80040c80, 0x02021000,
+	0x00102310, 0x80000040, 0x02000000, 0x00102310,
+	0x599c0209, 0x599c0a07, 0x80040c80, 0x02021000,
+	0x00102310, 0x80000040, 0x02000000, 0x00102310,
+	0x0201f800, 0x001053cd, 0x0201f800, 0x00104cb6,
+	0x599c0201, 0x48035004, 0x0201f800, 0x001012ee,
+	0x599c020a, 0x800001c0, 0x04000003, 0x4803504d,
+	0x0401f003, 0x4a03504d, 0x000000c8, 0x0201f800,
+	0x00103b25, 0x04000004, 0x0201f800, 0x001060df,
+	0x417a5000, 0x836c0580, 0x00000000, 0x04020098,
+	0x599c0003, 0x599c0804, 0x9c0001c0, 0x9c0409c0,
+	0x48035002, 0x48075003, 0x599c1017, 0x8c08151c,
+	0x04000006, 0x599c0005, 0x599c0806, 0x9c0001c0,
+	0x9c0409c0, 0x0401f003, 0x82000500, 0xf0ffffff,
+	0x48035000, 0x48075001, 0x42001000, 0x0010b4eb,
+	0x48001000, 0x48041001, 0x42001000, 0x0010b4f8,
+	0x48001000, 0x48041001, 0x59a80005, 0x8c000514,
+	0x04020015, 0x599c1019, 0x82081500, 0x0000e000,
+	0x82080580, 0x00000000, 0x0402000c, 0x4a035053,
+	0x00000000, 0x42000000, 0x00000001, 0x0201f800,
+	0x0010188c, 0x42000000, 0x00000001, 0x0201f800,
+	0x00101821, 0x0401f02b, 0x82080580, 0x00002000,
+	0x0402000a, 0x4a035053, 0x00000001, 0x41780000,
+	0x0201f800, 0x0010188c, 0x41780000, 0x0201f800,
+	0x00101821, 0x0401f01f, 0x82080580, 0x00004000,
+	0x04020006, 0x4a035053, 0x00000002, 0x4a035049,
+	0x00000001, 0x0401f017, 0x82080580, 0x00006000,
+	0x02020000, 0x00102310, 0x59a80858, 0x82040d80,
+	0x01391077, 0x04020005, 0x59e00813, 0x8c040d00,
+	0x02020000, 0x00102310, 0x4a035053, 0x00000003,
+	0x42000000, 0x00000002, 0x0201f800, 0x0010188c,
+	0x42000000, 0x00000002, 0x0201f800, 0x00101821,
+	0x599c0019, 0x8c000520, 0x0400000d, 0x42000000,
+	0x00000004, 0x42000800, 0x00000040, 0x0201f800,
+	0x00101944, 0x42000000, 0x00000010, 0x42000800,
+	0x000000c0, 0x0201f800, 0x00101944, 0x4a035032,
+	0x0000aaaa, 0x599c1018, 0x82081500, 0x00000030,
+	0x59a8006c, 0x80000540, 0x0400000c, 0x82080580,
+	0x00000000, 0x02000000, 0x00102310, 0x599c1018,
+	0x82081500, 0xffffffcf, 0x82081540, 0x00000010,
+	0x480b3818, 0x0401f010, 0x82080d80, 0x00000000,
+	0x04000007, 0x82080d80, 0x00000010, 0x0400000a,
+	0x82080d80, 0x00000020, 0x04020002, 0x48075032,
+	0x0201f800, 0x00103aba, 0x04000008, 0x0201f800,
+	0x001015fe, 0x0201f800, 0x0010162a, 0x59a8002a,
+	0x80040540, 0x4803502a, 0x49f3c857, 0x42001000,
+	0x00105065, 0x0201f800, 0x00105f90, 0x42001000,
+	0x00105058, 0x0201f800, 0x00106084, 0x4a038805,
+	0xffffffff, 0x4a03c014, 0x00400040, 0x4a03c013,
+	0x00400000, 0x0201f800, 0x001048c7, 0x59a0001d,
+	0x84000540, 0x4803401d, 0x49f3c857, 0x0201f000,
+	0x001022c0, 0x00000018, 0x0000000c, 0x00000018,
+	0x00000020, 0x836c0580, 0x00000000, 0x04020005,
+	0x42000800, 0x00000007, 0x0201f000, 0x0010230c,
+	0x42000800, 0x00000020, 0x59a00407, 0x59a01207,
+	0x900811c0, 0x80081540, 0x59a00409, 0x59a01a09,
+	0x900c19c0, 0x800c1d40, 0x419c0000, 0x0201f000,
+	0x00103a28, 0x800409c0, 0x04000005, 0x4a034406,
+	0x00000001, 0x0201f000, 0x0010230c, 0x0201f800,
+	0x0010513b, 0x04020005, 0x4a034406, 0x00000016,
+	0x0201f000, 0x0010230c, 0x59a80013, 0x8c000500,
+	0x04000011, 0x4a034406, 0x00000000, 0x42000800,
+	0x00000020, 0x59a00407, 0x59a01207, 0x900811c0,
+	0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+	0x800c1d40, 0x42000000, 0x0010be21, 0x0201f000,
+	0x00103a28, 0x4a034406, 0x00000001, 0x4200b000,
+	0x00000020, 0x4200a800, 0x0010be21, 0x4200a000,
+	0xffffffff, 0x4450a800, 0x8054a800, 0x8058b040,
+	0x040207fd, 0x4d440000, 0x4d340000, 0x42028800,
+	0xffffffff, 0x42002000, 0xffffffff, 0x42003000,
+	0x00000001, 0x42003800, 0x00000001, 0x42001800,
+	0x0010be21, 0x59a81010, 0x82081500, 0x000000ff,
+	0x40180000, 0x0c01f001, 0x0010346e, 0x00103471,
+	0x00103475, 0x00103479, 0x82102500, 0xffffff00,
+	0x0401f014, 0x82102500, 0xffff00ff, 0x840811c0,
+	0x0401f010, 0x82102500, 0xff00ffff, 0x900811c0,
+	0x0401f00c, 0x82102500, 0x00ffffff, 0x9c0801c0,
+	0x80102540, 0x44101800, 0x42003000, 0xffffffff,
+	0x42002000, 0xffffffff, 0x800c1800, 0x0401f003,
+	0x40080000, 0x80102540, 0x81468800, 0x83442c80,
+	0x0000007f, 0x04021014, 0x4c080000, 0x4c0c0000,
+	0x4c180000, 0x4c1c0000, 0x0201f800, 0x00020245,
+	0x5c003800, 0x5c003000, 0x5c001800, 0x5c001000,
+	0x040207f2, 0x0201f800, 0x001049f3, 0x040207ef,
+	0x80183000, 0x801c3800, 0x59341202, 0x40180000,
+	0x0c01f7ce, 0x82100580, 0xffffffff, 0x04000002,
+	0x44101800, 0x42001800, 0x0010be21, 0x500c0000,
+	0x82000500, 0xffffff00, 0x801c0540, 0x44001800,
+	0x5c026800, 0x5c028800, 0x42000800, 0x00000020,
+	0x59a00407, 0x59a01207, 0x900811c0, 0x80081540,
+	0x59a00409, 0x59a01a09, 0x900c19c0, 0x800c1d40,
+	0x42000000, 0x0010be21, 0x0201f000, 0x00103a28,
+	0x59a28c06, 0x59a0020b, 0x8c000500, 0x0400000e,
+	0x59a01208, 0x59a00408, 0x82000500, 0x000000ff,
+	0x900001c0, 0x80081540, 0x41784000, 0x0201f800,
+	0x00104919, 0x04000008, 0x48034406, 0x0201f000,
+	0x00102310, 0x0201f800, 0x00020245, 0x02020000,
+	0x00102310, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x59a0020b, 0x8c000500, 0x04000005, 0x0201f800,
+	0x001049f3, 0x02020000, 0x00103ac4, 0x59a0020b,
+	0x8c000502, 0x04000019, 0x83440480, 0x000007f0,
+	0x04021016, 0x0201f800, 0x001049fc, 0x04020013,
+	0x497a5a04, 0x4a025c04, 0x00008000, 0x0201f800,
+	0x001090e6, 0x04020005, 0x4a034406, 0x00000003,
+	0x0201f000, 0x0010230c, 0x4a01d809, 0x001034f1,
+	0x1c01f000, 0x59a28c06, 0x0201f800, 0x00020245,
+	0x02020000, 0x00102310, 0x4200b000, 0x0000000a,
+	0x4134a000, 0x832e5c00, 0x00000002, 0x412ca800,
+	0x0201f800, 0x0010ab17, 0x832cac00, 0x00000006,
+	0x4054a000, 0x4200b000, 0x00000004, 0x0201f800,
+	0x0010ab28, 0x592c0802, 0x82040500, 0x00ff00ff,
+	0x900001c0, 0x82041500, 0xff00ff00, 0x80080540,
+	0x48025802, 0x592c0801, 0x82040500, 0x00ff00ff,
+	0x900001c0, 0x82041500, 0xff00ff00, 0x80080540,
+	0x48025801, 0x42000800, 0x0000000a, 0x59a00407,
+	0x59a01207, 0x900811c0, 0x80081540, 0x59a00409,
+	0x59a01a09, 0x900c19c0, 0x800c1d40, 0x412c0000,
+	0x0201f000, 0x00103a28, 0x496fc857, 0x496f4406,
+	0x0201f000, 0x001022c0, 0x59a28c06, 0x0201f800,
+	0x00020245, 0x02020000, 0x00102310, 0x836c0580,
+	0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x83340c00, 0x00000006,
+	0x59a0020b, 0x8c000500, 0x04000003, 0x83340c00,
+	0x00000008, 0x58040001, 0x48034409, 0x900001c0,
+	0x48034209, 0x50040000, 0x48034407, 0x900001c0,
+	0x48034207, 0x59340200, 0x48034406, 0x0201f000,
+	0x001022c0, 0x800409c0, 0x04000005, 0x4a034406,
+	0x00000001, 0x0201f000, 0x0010230c, 0x59a0220b,
+	0x8c102500, 0x0402002e, 0x8c102506, 0x04020006,
+	0x59a03208, 0x82180480, 0x00000003, 0x02021000,
+	0x00102310, 0x59a28c06, 0x0201f800, 0x00020245,
+	0x02020000, 0x00102310, 0x0201f800, 0x001049e7,
+	0x04000005, 0x4a034406, 0x00000009, 0x0201f000,
+	0x0010230c, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x59a0220b, 0x8c102506, 0x04000004, 0x59343002,
+	0x82183500, 0x00ffffff, 0x497a5a04, 0x4a025c04,
+	0x00008000, 0x0201f800, 0x001090a8, 0x04020005,
+	0x4a034406, 0x00000003, 0x0201f000, 0x0010230c,
+	0x4a01d809, 0x001035d1, 0x1c01f000, 0x59a28c06,
+	0x0201f800, 0x00020245, 0x02020000, 0x00102310,
+	0x0201f800, 0x001049e7, 0x04000005, 0x4a034406,
+	0x00000009, 0x0201f000, 0x0010230c, 0x0201f800,
+	0x00103a00, 0x04020005, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x497a5a04, 0x4a025c04,
+	0x00008000, 0x0201f800, 0x00103a00, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x592e5800, 0x0201f800, 0x001090bd, 0x04020005,
+	0x4a034406, 0x00000003, 0x0201f000, 0x0010230c,
+	0x4a01d809, 0x001035a3, 0x1c01f000, 0x592c2805,
+	0x82140d80, 0x01000000, 0x04020005, 0x4a034406,
+	0x00000004, 0x0201f000, 0x0010230c, 0x42000800,
+	0x00000008, 0x59a00207, 0x59a01407, 0x900001c0,
+	0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+	0x800c1d40, 0x832c0400, 0x00000005, 0x0201f800,
+	0x00103a28, 0x8c142d00, 0x04000003, 0x4a01d809,
+	0x001035be, 0x1c01f000, 0x4031d800, 0x58ef400b,
+	0x58ee580e, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x42000800, 0x00000008, 0x832c0400,
+	0x00000005, 0x58ec1007, 0x58ec1808, 0x0201f000,
+	0x00103a28, 0x592c0005, 0x82000580, 0x01000000,
+	0x04020005, 0x4a034406, 0x00000004, 0x0201f000,
+	0x0010230c, 0x59a00207, 0x59a01407, 0x900001c0,
+	0x80081540, 0x59a00209, 0x59a01c09, 0x900001c0,
+	0x800c1d40, 0x42000800, 0x00000006, 0x832c0400,
+	0x00000006, 0x0201f000, 0x00103a28, 0x59a00a0a,
+	0x800409c0, 0x02000000, 0x00102310, 0x82040480,
+	0x000000e7, 0x04001003, 0x42000800, 0x000000e6,
+	0x59a00207, 0x59a01407, 0x900001c0, 0x80081540,
+	0x59a00209, 0x59a01c09, 0x900001c0, 0x800c1d40,
+	0x83880400, 0x00000000, 0x0201f800, 0x00103a28,
+	0x4a01d809, 0x001035ff, 0x1c01f000, 0x4031d800,
+	0x58ef400b, 0x58ec0002, 0x82000580, 0x00000200,
+	0x02000000, 0x00102304, 0x58ef400b, 0x59a0020b,
+	0x8c000500, 0x04000008, 0x83880400, 0x00000000,
+	0x4803c840, 0x4a03c842, 0x00000006, 0x04011000,
+	0x497b8885, 0x4a034207, 0x000000e6, 0x0201f000,
+	0x001022c0, 0x800409c0, 0x04000005, 0x4a034406,
+	0x00000001, 0x0201f000, 0x0010230c, 0x0401fbe5,
+	0x04020005, 0x4a034406, 0x00000002, 0x0201f000,
+	0x0010230c, 0x497a5a04, 0x4a025c04, 0x00008000,
+	0x59a00406, 0x800001c0, 0x02000000, 0x00102310,
+	0x82001580, 0x000000ff, 0x04000005, 0x82001480,
+	0x00000004, 0x02021000, 0x00102310, 0x40001000,
+	0x0201f800, 0x00101fbf, 0x04020005, 0x4a034406,
+	0x00000003, 0x0201f000, 0x0010230c, 0x4a01d809,
+	0x0010363a, 0x1c01f000, 0x592c0005, 0x82000580,
+	0x01000000, 0x02020000, 0x001022c0, 0x4a034406,
+	0x00000004, 0x0201f000, 0x0010230c, 0x59a01406,
+	0x8c081508, 0x04020007, 0x800409c0, 0x04000005,
+	0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+	0x59a01c07, 0x820c0480, 0x00001000, 0x02021000,
+	0x00102310, 0x497b2804, 0x497b2805, 0x497b281c,
+	0x497b281d, 0x497b281f, 0x497b2820, 0x497b2822,
+	0x497b2823, 0x80000580, 0x0201f800, 0x001015fe,
+	0x59a80805, 0x8c081500, 0x04000004, 0x82040d40,
+	0x00000011, 0x0401f004, 0x8c081506, 0x04000002,
+	0x84040d42, 0x84040d0a, 0x48075005, 0x4202d800,
+	0x00000001, 0x82081500, 0x000000e0, 0x8008010a,
+	0x0c020036, 0x0201f800, 0x0010513b, 0x04020009,
+	0x4a035033, 0x00000001, 0x0201f800, 0x001050a2,
+	0x0401f01f, 0x4a035033, 0x00000000, 0x0401f7fb,
+	0x497b5032, 0x0201f800, 0x00104142, 0x0201f800,
+	0x00106c55, 0x0201f800, 0x00106ede, 0x0201f800,
+	0x00106c4b, 0x59a00a07, 0x480788a7, 0x59c400a3,
+	0x82000500, 0xfeffffff, 0x82000540, 0x80018000,
+	0x40000800, 0x84040d20, 0x480388a3, 0x480788a3,
+	0x497b504e, 0x42000800, 0x0000002d, 0x42001000,
+	0x001041bc, 0x0201f800, 0x00105f69, 0x59a00407,
+	0x800000c2, 0x800008c4, 0x8005d400, 0x42000000,
+	0x0000ffff, 0x0201f800, 0x0010513b, 0x04000003,
+	0x59a00207, 0x80000110, 0x0201f800, 0x00103afc,
+	0x0201f000, 0x001022c0, 0x0010366d, 0x00103670,
+	0x00103678, 0x00102310, 0x00103675, 0x00102310,
+	0x00102310, 0x00102310, 0x836c0580, 0x00000003,
+	0x04000005, 0x4a034406, 0x00000007, 0x0201f000,
+	0x0010230c, 0x59a03c06, 0x59a00407, 0x59a04a07,
+	0x902449c0, 0x80244d40, 0x59a00409, 0x59a05209,
+	0x902851c0, 0x80285540, 0x0401fb46, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x417a8800, 0x41783000, 0x497b4001, 0x497b4004,
+	0x832c4400, 0x00000005, 0x48234002, 0x8c1c3d04,
+	0x04020078, 0x0201f800, 0x00020245, 0x0402002a,
+	0x0201f800, 0x001049e7, 0x04000004, 0x0201f800,
+	0x001048e3, 0x04020024, 0x8c1c3d00, 0x04000008,
+	0x59340009, 0x44004000, 0x59340008, 0x80204000,
+	0x44004000, 0x80204000, 0x0401f007, 0x59340007,
+	0x44004000, 0x59340006, 0x80204000, 0x44004000,
+	0x80204000, 0x83440580, 0x000007fe, 0x0400000d,
+	0x83440580, 0x000007fc, 0x0400000a, 0x0201f800,
+	0x001049f3, 0x04000003, 0x85468d5e, 0x0401f005,
+	0x0201f800, 0x00104838, 0x04020002, 0x85468d5e,
+	0x45444000, 0x85468d1e, 0x80204000, 0x82183400,
+	0x00000003, 0x81468800, 0x83440480, 0x000007f0,
+	0x0400100e, 0x8c1c3d06, 0x04000010, 0x83440580,
+	0x000007f0, 0x04020004, 0x42028800, 0x000007fe,
+	0x0401f006, 0x83440580, 0x000007ff, 0x04020007,
+	0x42028800, 0x000007fc, 0x82180580, 0x0000000f,
+	0x0400000b, 0x0401f7c0, 0x801831c0, 0x04020006,
+	0x59a00801, 0x800408c4, 0x48074406, 0x0201f000,
+	0x001022c0, 0x4a034004, 0x00000001, 0x49474000,
+	0x59a00001, 0x80180400, 0x48034001, 0x481f4003,
+	0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002,
+	0x4801d803, 0x4825d807, 0x4829d808, 0x4000a800,
+	0x4000a000, 0x4018b000, 0x0201f800, 0x0010ab17,
+	0x40ec1000, 0x0201f800, 0x00100858, 0x4a01d809,
+	0x0010372a, 0x1c01f000, 0x4031d800, 0x58ef400b,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x59a00004, 0x80000540, 0x04020008,
+	0x59a28800, 0x59a04002, 0x59a03803, 0x41783000,
+	0x58ec4807, 0x58ec5008, 0x0401f78f, 0x59a00801,
+	0x800408c4, 0x48074406, 0x0201f000, 0x001022c0,
+	0x0201f800, 0x00020245, 0x0402002f, 0x0201f800,
+	0x001049e7, 0x04000004, 0x0201f800, 0x001048e3,
+	0x04020029, 0x83440580, 0x000007fe, 0x04000011,
+	0x83440580, 0x000007fc, 0x0400000e, 0x0201f800,
+	0x001049f3, 0x04000005, 0x59340403, 0x8400055e,
+	0x48026c03, 0x0401f007, 0x0201f800, 0x00104838,
+	0x04020004, 0x59340403, 0x8400055e, 0x48026c03,
+	0x4134a000, 0x4020a800, 0x4200b000, 0x00000006,
+	0x0201f800, 0x0010ab17, 0x59340007, 0x4400a800,
+	0x59340006, 0x4800a801, 0x59340009, 0x4800a802,
+	0x59340008, 0x4800a803, 0x59340403, 0x8400051e,
+	0x48026c03, 0x82204400, 0x0000000a, 0x82183400,
+	0x0000000a, 0x81468800, 0x83440480, 0x000007f0,
+	0x0400100e, 0x8c1c3d06, 0x04000010, 0x83440580,
+	0x000007f0, 0x04020004, 0x42028800, 0x000007fe,
+	0x0401f006, 0x83440580, 0x000007ff, 0x04020007,
+	0x42028800, 0x000007fc, 0x82180580, 0x0000000a,
+	0x0400000b, 0x0401f7bb, 0x801831c0, 0x04020006,
+	0x59a00801, 0x800408c4, 0x48074406, 0x0201f000,
+	0x001022c0, 0x4a034004, 0x00000001, 0x49474000,
+	0x59a00001, 0x80180400, 0x48034001, 0x481f4003,
+	0x4a01d801, 0x00000000, 0x4819d804, 0x59a00002,
+	0x4801d803, 0x4825d807, 0x4829d808, 0x40ec1000,
+	0x0201f800, 0x00100858, 0x4a01d809, 0x001037a1,
+	0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ec0002,
+	0x82000580, 0x00000200, 0x02000000, 0x00102304,
+	0x59a00004, 0x80000540, 0x04020008, 0x59a28800,
+	0x59a04002, 0x59a03803, 0x41783000, 0x58ec4807,
+	0x58ec5008, 0x0401f78f, 0x59a00801, 0x800408c4,
+	0x48074406, 0x0201f000, 0x001022c0, 0x42002800,
+	0x0000007e, 0x59a00c06, 0x59a01207, 0x59a01c07,
+	0x59a02209, 0x82040500, 0x0000ff00, 0x840001c0,
+	0x82003480, 0x00000020, 0x02001000, 0x00102310,
+	0x80140480, 0x02001000, 0x00102310, 0x82040500,
+	0x000000ff, 0x82003480, 0x00000020, 0x02001000,
+	0x00102310, 0x80140480, 0x02001000, 0x00102310,
+	0x82080500, 0x0000ff00, 0x840001c0, 0x82003480,
+	0x00000020, 0x02001000, 0x00102310, 0x80140480,
+	0x02001000, 0x00102310, 0x82080500, 0x000000ff,
+	0x82003480, 0x00000020, 0x02001000, 0x00102310,
+	0x80140480, 0x02001000, 0x00102310, 0x820c0500,
+	0x0000ff00, 0x840001c0, 0x82003480, 0x00000020,
+	0x02001000, 0x00102310, 0x80140480, 0x02001000,
+	0x00102310, 0x820c0500, 0x000000ff, 0x82003480,
+	0x00000020, 0x02001000, 0x00102310, 0x80140480,
+	0x02001000, 0x00102310, 0x82100500, 0x0000ff00,
+	0x840001c0, 0x82003480, 0x00000020, 0x02001000,
+	0x00102310, 0x80140480, 0x02001000, 0x00102310,
+	0x82100500, 0x000000ff, 0x82003480, 0x00000020,
+	0x02001000, 0x00102310, 0x80140480, 0x02001000,
+	0x00102310, 0x900401c0, 0x80080d40, 0x900c01c0,
+	0x80101d40, 0x83a83400, 0x0000003a, 0x44043000,
+	0x80183000, 0x440c3000, 0x0201f000, 0x001022c0,
+	0x0401f9ec, 0x04020005, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x42000800, 0x0000000c,
+	0x0401f853, 0x4a01d809, 0x00103820, 0x1c01f000,
+	0x4031d800, 0x58ee580d, 0x58ef400b, 0x58ec0002,
+	0x82000580, 0x00000200, 0x02000000, 0x00102304,
+	0x832ca400, 0x00000004, 0x4200b000, 0x0000000c,
+	0x40c8a800, 0x0201f800, 0x0010ab17, 0x58c80200,
+	0x80000540, 0x04000034, 0x58c80400, 0x82000500,
+	0xfffffffb, 0x04020030, 0x58c80401, 0x80000540,
+	0x0400002d, 0x82000480, 0x0000ff01, 0x0402102a,
+	0x58c80202, 0x82000480, 0x0000005c, 0x04001026,
+	0x0201f800, 0x001063a3, 0x58c80c08, 0x58c80204,
+	0x80040480, 0x04001020, 0x58c80204, 0x82000480,
+	0x00000005, 0x0402101c, 0x58c80205, 0x58c80c08,
+	0x80040902, 0x80040480, 0x04001017, 0x58c80c08,
+	0x0201f800, 0x001062f1, 0x0400001b, 0x0201f800,
+	0x001061b9, 0x04020012, 0x4979940b, 0x59c408a3,
+	0x82040d40, 0x00000002, 0x480788a3, 0x4a038830,
+	0x00000001, 0x4a038832, 0x01ffffff, 0x58c80202,
+	0x48030804, 0x0201f800, 0x0010619b, 0x0201f000,
+	0x001022c0, 0x0201f000, 0x00102310, 0x0201f800,
+	0x001063f5, 0x0201f800, 0x00106402, 0x0201f800,
+	0x001062e4, 0x0201f000, 0x0010230c, 0x4c000000,
+	0x59a01207, 0x59a00407, 0x900811c0, 0x80081540,
+	0x59a01a09, 0x59a00409, 0x900c19c0, 0x800c1d40,
+	0x5c000000, 0x0401f1ac, 0x59840000, 0x82000580,
+	0x00000000, 0x04000054, 0x59840002, 0x8c000504,
+	0x04000051, 0x84000546, 0x48030802, 0x0201f800,
+	0x001062e4, 0x59c408a3, 0x82040d00, 0xfffffffd,
+	0x480788a3, 0x4c5c0000, 0x4200b800, 0x0010ac00,
+	0x505e6800, 0x813669c0, 0x04000008, 0x5936600e,
+	0x813261c0, 0x04000005, 0x0201f800, 0x001062d5,
+	0x02000800, 0x001064ad, 0x805cb800, 0x825c0580,
+	0x0010b3f0, 0x040207f3, 0x59866003, 0x813261c0,
+	0x0400000b, 0x59300406, 0x82000580, 0x00000009,
+	0x02020800, 0x001005d8, 0x5930b800, 0x0201f800,
+	0x001062c1, 0x405e6000, 0x0401f7f5, 0x497b0803,
+	0x4200b800, 0x0010b51b, 0x505e6000, 0x813261c0,
+	0x04000011, 0x59300406, 0x82000580, 0x00000009,
+	0x0402000d, 0x59300203, 0x82000580, 0x00000004,
+	0x04020009, 0x59326809, 0x813669c0, 0x02020800,
+	0x001005d8, 0x0201f800, 0x00100e99, 0x0201f800,
+	0x001062c1, 0x4578b800, 0x805cb800, 0x825c0580,
+	0x0010b523, 0x040207e9, 0x42000800, 0x0010b519,
+	0x49780801, 0x49780800, 0x59a80069, 0x82000400,
+	0x00000007, 0x48035069, 0x0201f800, 0x001063f5,
+	0x0201f800, 0x00106402, 0x5c00b800, 0x0201f800,
+	0x001061b4, 0x0201f000, 0x001022c0, 0x836c0580,
+	0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x59a00407, 0x59a02207,
+	0x901021c0, 0x80102540, 0x59a00409, 0x59a02a09,
+	0x901429c0, 0x80142d40, 0x0401f91e, 0x04020005,
+	0x4a034406, 0x00000002, 0x0201f000, 0x0010230c,
+	0x417a8800, 0x41781800, 0x497b4001, 0x497b4003,
+	0x832c3400, 0x00000004, 0x481b4002, 0x41440000,
+	0x81ac0400, 0x50026800, 0x813669c0, 0x0400000b,
+	0x0201f800, 0x001049e7, 0x04020008, 0x59340002,
+	0x48003000, 0x49443001, 0x82183400, 0x00000002,
+	0x820c1c00, 0x00000002, 0x81468800, 0x83440480,
+	0x00000800, 0x04000005, 0x820c0480, 0x00000010,
+	0x0402100b, 0x0401f7ea, 0x800c19c0, 0x04020006,
+	0x59a00801, 0x80040902, 0x48074406, 0x0201f000,
+	0x001022c0, 0x4a034003, 0x00000001, 0x49474000,
+	0x59a00001, 0x800c0400, 0x48034001, 0x40ec1000,
+	0x4a001001, 0x00000000, 0x480c1004, 0x59a00002,
+	0x48001003, 0x48101007, 0x48141008, 0x0201f800,
+	0x00100858, 0x4a01d809, 0x00103920, 0x1c01f000,
+	0x4031d800, 0x58ef400b, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x59a00003,
+	0x80000540, 0x04020008, 0x59a28800, 0x59a03002,
+	0x41781800, 0x40ec1000, 0x58082007, 0x58082808,
+	0x0401f7bf, 0x59a00801, 0x80040902, 0x48074406,
+	0x0201f000, 0x001022c0, 0x800409c0, 0x04000005,
+	0x4a034406, 0x00000001, 0x0201f000, 0x0010230c,
+	0x59a80026, 0x8c00050a, 0x04020007, 0x8c000506,
+	0x04020005, 0x4a034406, 0x00000016, 0x0201f000,
+	0x0010230c, 0x0401f8bb, 0x04020005, 0x4a034406,
+	0x00000002, 0x0201f000, 0x0010230c, 0x59a00c06,
+	0x80040902, 0x59a00407, 0x59a01207, 0x900811c0,
+	0x80081540, 0x59a00409, 0x59a01a09, 0x900c19c0,
+	0x800c1d40, 0x832c0400, 0x00000005, 0x0401f8ce,
+	0x4a01d809, 0x0010395b, 0x1c01f000, 0x4031d800,
+	0x58ef400b, 0x58ee580d, 0x58ec0002, 0x82000580,
+	0x00000200, 0x02000000, 0x00102304, 0x592c0009,
+	0x0201f800, 0x00105c9a, 0x02000800, 0x001045a6,
+	0x02020000, 0x00102310, 0x49474001, 0x481a6802,
+	0x592c000a, 0x82001d80, 0x70000000, 0x04020007,
+	0x0401f890, 0x04020011, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x82001d80, 0x72000000,
+	0x02020000, 0x00102310, 0x0401f886, 0x04020885,
+	0x04020884, 0x04020005, 0x4a034406, 0x00000002,
+	0x0201f000, 0x0010230c, 0x58ee580d, 0x4a025c04,
+	0x00008000, 0x497a5a04, 0x592c3208, 0x80183102,
+	0x592c1801, 0x4a001805, 0x01000000, 0x0201f800,
+	0x001090d1, 0x04020005, 0x4a034406, 0x00000003,
+	0x0201f000, 0x0010230c, 0x4a01d809, 0x00103995,
+	0x1c01f000, 0x592c4000, 0x592c0005, 0x82000580,
+	0x01000000, 0x04020005, 0x4a034406, 0x00000004,
+	0x0201f000, 0x0010230c, 0x832c3c00, 0x00000005,
+	0x401ca000, 0x401ca800, 0x5820280a, 0x4200b000,
+	0x00000002, 0x82143580, 0x70000000, 0x04000003,
+	0x4200b000, 0x0000000f, 0x0201f800, 0x0010ab28,
+	0x401c0000, 0x58201006, 0x58201807, 0x58202205,
+	0x80102102, 0x82143580, 0x70000000, 0x04020008,
+	0x82103480, 0x00000002, 0x02001000, 0x00102310,
+	0x42000800, 0x00000002, 0x0401f06e, 0x82143580,
+	0x72000000, 0x02020000, 0x00102310, 0x82103480,
+	0x0000002a, 0x02001000, 0x00102310, 0x42000800,
+	0x0000000f, 0x0401f863, 0x4a01d809, 0x001039c9,
+	0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580e,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x592e5800, 0x832c0c00, 0x00000005,
+	0x4004a000, 0x4004a800, 0x4200b000, 0x0000000f,
+	0x0201f800, 0x0010ab28, 0x40ec1000, 0x4a001001,
+	0x00000000, 0x4a001004, 0x0000000f, 0x48041003,
+	0x0201f800, 0x00100858, 0x4a01d809, 0x001039e5,
+	0x1c01f000, 0x4031d800, 0x58ef400b, 0x58ee580e,
+	0x58ec0002, 0x82000580, 0x00000200, 0x02000000,
+	0x00102304, 0x832c0c00, 0x00000005, 0x4004a000,
+	0x4004a800, 0x4200b000, 0x0000000c, 0x0201f800,
+	0x0010ab28, 0x40ec1000, 0x4a001001, 0x00000000,
+	0x4a001004, 0x0000000c, 0x48041003, 0x0201f800,
+	0x00100858, 0x4a01d809, 0x001022b9, 0x1c01f000,
+	0x0201f800, 0x001007e4, 0x04000010, 0x497a5800,
+	0x58ec000d, 0x80000540, 0x04020004, 0x492dd80d,
+	0x492dd80e, 0x0401f007, 0x58ec000e, 0x48025800,
+	0x82000400, 0x00000001, 0x452c0000, 0x492dd80e,
+	0x832c0400, 0x00000004, 0x492fc857, 0x4803c857,
+	0x1c01f000, 0x4d2c0000, 0x48efc857, 0x58ec400d,
+	0x4823c857, 0x802041c0, 0x04000007, 0x40225800,
+	0x592c4001, 0x497a5801, 0x0201f800, 0x001007f4,
+	0x0401f7f8, 0x4979d80d, 0x4979d80e, 0x5c025800,
+	0x1c01f000, 0x42003000, 0x00000001, 0x0401f003,
+	0x42003000, 0x00000000, 0x4803c857, 0x4807c857,
+	0x480bc857, 0x480fc857, 0x481bc857, 0x48efc857,
+	0x4819d801, 0x800409c0, 0x02000800, 0x001005d8,
+	0x4805d804, 0x4801d803, 0x4809d807, 0x480dd808,
+	0x40ec1000, 0x0201f800, 0x00100858, 0x4a01d809,
+	0x001022b9, 0x1c01f000, 0x80002d80, 0x480bc857,
+	0x480fc857, 0x4813c857, 0x4817c857, 0x4d2c0000,
+	0x4da00000, 0x42034000, 0x0010b4a4, 0x59a00017,
+	0x800001c0, 0x04020013, 0x04006012, 0x480bc020,
+	0x480fc021, 0x4813c022, 0x4817c023, 0x900811c0,
+	0x82081540, 0x00000012, 0x480bc011, 0x59e00017,
+	0x8c000508, 0x04020004, 0x4203e000, 0x30000001,
+	0x0401f053, 0x4a03c017, 0x00000002, 0x0401f7fb,
+	0x4c040000, 0x4c1c0000, 0x80000800, 0x48074017,
+	0x59a0381a, 0x481fc857, 0x801c39c0, 0x04020027,
+	0x82000480, 0x0000000a, 0x04021010, 0x59a00018,
+	0x80000000, 0x48034018, 0x59a00219, 0x82000400,
+	0x00000002, 0x82000c80, 0x00000013, 0x48034219,
+	0x04001003, 0x497b4219, 0x41780000, 0x59a03816,
+	0x801c3c00, 0x0401f030, 0x4803c856, 0x0201f800,
+	0x001007e4, 0x04000007, 0x492f401a, 0x492f401b,
+	0x412c3800, 0x497b421c, 0x497a5813, 0x0401f026,
+	0x59880051, 0x80000000, 0x48031051, 0x59a00017,
+	0x80000040, 0x48034017, 0x59a00219, 0x59a03816,
+	0x801c3c00, 0x0401f01c, 0x59a0021c, 0x82000400,
+	0x00000002, 0x82000c80, 0x00000012, 0x04021004,
+	0x4803421c, 0x801c3c00, 0x0401f013, 0x0201f800,
+	0x001007e4, 0x0402000b, 0x59880051, 0x80000000,
+	0x48031051, 0x59a00017, 0x80000040, 0x48034017,
+	0x4803c856, 0x59a0021c, 0x801c3c00, 0x0401f006,
+	0x492f401a, 0x492c3813, 0x412c3800, 0x497b421c,
+	0x497a5813, 0x48083c00, 0x480c3a00, 0x48103c01,
+	0x48143a01, 0x5c003800, 0x5c000800, 0x5c034000,
+	0x5c025800, 0x1c01f000, 0x480fc857, 0x4813c857,
+	0x481bc857, 0x42000000, 0x0010b813, 0x0201f800,
+	0x0010aa47, 0x801800d0, 0x40002800, 0x42001000,
+	0x00008014, 0x0401f786, 0x4c000000, 0x599c0017,
+	0x8c000512, 0x5c000000, 0x1c01f000, 0x4c000000,
+	0x599c0018, 0x8c00050e, 0x5c000000, 0x1c01f000,
+	0x59a80821, 0x800409c0, 0x04000005, 0x4a034406,
+	0x00000001, 0x0201f000, 0x0010230c, 0x836c0580,
+	0x00000003, 0x04000005, 0x4a034406, 0x00000007,
+	0x0201f000, 0x0010230c, 0x599c0017, 0x8c00050a,
+	0x04000005, 0x4a034406, 0x00000008, 0x0201f000,
+	0x0010230c, 0x59340405, 0x8c000508, 0x04020004,
+	0x8c00050a, 0x02020000, 0x001034db, 0x497a5a04,
+	0x497a5805, 0x4a025c04, 0x00008000, 0x0201f800,
+	0x00109176, 0x04020005, 0x4a034406, 0x00000003,
+	0x0201f000, 0x0010230c, 0x4a01d809, 0x00103aed,
+	0x1c01f000, 0x592c0005, 0x82000580, 0x01000000,
+	0x04020005, 0x4a034406, 0x00000004, 0x0201f000,
+	0x0010230c, 0x59a28c06, 0x0201f800, 0x00020245,
+	0x02020000, 0x00102310, 0x0201f000, 0x001034db,
+	0x82001580, 0x0000ffff, 0x04000009, 0x0201f800,
+	0x00105c9a, 0x02000800, 0x00020245, 0x0402000c,
+	0x0201f800, 0x00105fae, 0x0401f009, 0x42028800,
+	0x000007ef, 0x0201f800, 0x00020245, 0x02000800,
+	0x00105fae, 0x81468840, 0x040217fb, 0x1c01f000,
+	0x4803c856, 0x4c0c0000, 0x4d340000, 0x4d440000,
+	0x42028800, 0x000007fe, 0x0201f800, 0x00020245,
+	0x04020009, 0x5934180a, 0x820c1d00, 0x00000001,
+	0x820c1d80, 0x00000001, 0x42001000, 0x0000801b,
+	0x0401ff1e, 0x5c028800, 0x5c026800, 0x5c001800,
+	0x1c01f000, 0x599c0017, 0x8c000508, 0x1c01f000,
+	0x48efc857, 0x04011000, 0x48efc840, 0x4a03c842,
+	0x00000011, 0x40000000, 0x040117ff, 0x4a01d80f,
+	0xbeefbeef, 0x1c01f000, 0x497b4000, 0x497b4001,
+	0x497b4002, 0x497b4003, 0x497b4004, 0x1c01f000,
+	0x59c400a4, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x82000500, 0x0000000f, 0x82000480, 0x00000007,
+	0x0400100a, 0x82006c80, 0x00000006, 0x02021800,
+	0x001005d8, 0x0c01f807, 0x5c00a800, 0x5c00a000,
+	0x5c00b000, 0x1c01f000, 0x0401f906, 0x0401f7fb,
+	0x00103b51, 0x00103b57, 0x00103b7c, 0x00103b9e,
+	0x00103c59, 0x59c40806, 0x8c040d00, 0x04020003,
+	0x84040d40, 0x48078806, 0x1c01f000, 0x59c40005,
+	0x8c000534, 0x02020000, 0x0010429e, 0x4a038805,
+	0xffffffff, 0x42006000, 0x00020000, 0x0201f800,
+	0x00104282, 0x59a80015, 0x82000500, 0xfffffffa,
+	0x84000542, 0x48035015, 0x497b5026, 0x42000800,
+	0x0010be21, 0x45780800, 0x497b5013, 0x42006000,
+	0xffefffff, 0x42006800, 0x40000000, 0x0201f800,
+	0x0010427d, 0x59c40006, 0x82000500, 0xffffff0f,
+	0x48038806, 0x42000800, 0x00000010, 0x42001000,
+	0x001041f3, 0x0201f800, 0x00105f83, 0x0401f001,
+	0x42006000, 0xffffffff, 0x42006800, 0x00800000,
+	0x0201f800, 0x0010427d, 0x4200b000, 0x000000c8,
+	0x59c400a4, 0x82000500, 0x0000000f, 0x82000580,
+	0x0000000a, 0x0400000f, 0x8058b040, 0x040207f9,
+	0x497b5014, 0x42006000, 0xbf7fffff, 0x42006800,
+	0x00018000, 0x0201f800, 0x0010427d, 0x42006000,
+	0xfffeffff, 0x41786800, 0x0201f000, 0x0010427d,
+	0x497b5014, 0x4a035012, 0x00000000, 0x80000580,
+	0x0201f000, 0x00104289, 0x4a038805, 0xffffffff,
+	0x59a80012, 0x82000c80, 0x00000004, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x00103ba9, 0x00103bd6,
+	0x00103c4f, 0x4803c856, 0x59c400a3, 0x8400051e,
+	0x480388a3, 0x4a035012, 0x00000001, 0x59c40008,
+	0x8400054e, 0x48038808, 0x0201f800, 0x00104263,
+	0x42007800, 0x0010b54c, 0x4a007806, 0x11010000,
+	0x4200a000, 0x0010b402, 0x4200a800, 0x0010b553,
+	0x4200b000, 0x00000002, 0x0201f800, 0x0010ab17,
+	0x497b8802, 0x42000800, 0x00000003, 0x497b504a,
+	0x0201f800, 0x0010416e, 0x4a03504a, 0x00000001,
+	0x497b5016, 0x0201f800, 0x00104290, 0x42006000,
+	0xffffffff, 0x42006800, 0x00080000, 0x0201f800,
+	0x0010427d, 0x42006000, 0xfff7ffff, 0x41786800,
+	0x0201f000, 0x0010427d, 0x59a80016, 0x497b5016,
+	0x80002540, 0x04000066, 0x59c40004, 0x82000500,
+	0x00000003, 0x04020071, 0x59a80815, 0x8c040d02,
+	0x0400004b, 0x82100580, 0x0000000c, 0x0402004f,
+	0x82100400, 0x00000018, 0x8000b104, 0x41cc1000,
+	0x42001800, 0x0010b54c, 0x50080800, 0x500c0000,
+	0x80040580, 0x0402001a, 0x80081000, 0x800c1800,
+	0x8058b040, 0x040207f9, 0x0201f800, 0x00104290,
+	0x42006000, 0xffffffff, 0x42006800, 0x00500000,
+	0x0201f800, 0x0010427d, 0x4a035012, 0x00000002,
+	0x4a035014, 0x00000002, 0x42000800, 0x000007d0,
+	0x42001000, 0x00104148, 0x0201f800, 0x0010606e,
+	0x0201f800, 0x00104263, 0x0401f048, 0x59cc0806,
+	0x82040d80, 0x11010000, 0x04020028, 0x59cc0800,
+	0x82040500, 0x00ffffff, 0x0400001a, 0x82000580,
+	0x000000ef, 0x04020017, 0x59cc0801, 0x82040500,
+	0x00ffffff, 0x82000580, 0x000000ef, 0x04020011,
+	0x83cca400, 0x00000007, 0x4200a800, 0x0010b402,
+	0x4200b000, 0x00000002, 0x50500800, 0x50540000,
+	0x80040480, 0x04001007, 0x04020010, 0x8050a000,
+	0x8054a800, 0x8058b040, 0x040207f8, 0x0401f00b,
+	0x59a80015, 0x84000502, 0x48035015, 0x41cca000,
+	0x4200a800, 0x0010b54c, 0x4200b000, 0x00000009,
+	0x0201f800, 0x0010ab17, 0x0201f800, 0x00104290,
+	0x42006000, 0xffffffff, 0x42006800, 0x00080000,
+	0x0201f800, 0x0010427d, 0x42006000, 0xfff7ffff,
+	0x41786800, 0x0201f800, 0x0010427d, 0x42006000,
+	0xffffffff, 0x42006800, 0x00004000, 0x0201f800,
+	0x0010427d, 0x59c40004, 0x82000500, 0x00000003,
+	0x04020006, 0x497b5016, 0x42000800, 0x00000003,
+	0x0201f000, 0x0010416e, 0x1c01f000, 0x1c01f000,
+	0x59a80014, 0x82006d80, 0x0000000f, 0x04000005,
+	0x82000580, 0x0000001b, 0x02020800, 0x00104139,
+	0x1c01f000, 0x59a80015, 0x84000506, 0x48035015,
+	0x497b504a, 0x59a80014, 0x82000c80, 0x0000001e,
+	0x02021800, 0x001005d8, 0x0c01f001, 0x00103c97,
+	0x00103cac, 0x00103cd5, 0x00103cf0, 0x00103d14,
+	0x00103d45, 0x00103d68, 0x00103d9b, 0x00103dbe,
+	0x00103de4, 0x00103e21, 0x00103e48, 0x00103e5f,
+	0x00103e71, 0x00103e8a, 0x00103ea0, 0x00103ea5,
+	0x00103ecd, 0x00103ef0, 0x00103f16, 0x00103f39,
+	0x00103f6c, 0x00103fae, 0x00103fd8, 0x00103ff0,
+	0x00104030, 0x00104049, 0x0010405c, 0x0010405d,
+	0x4803c856, 0x4202d800, 0x00000007, 0x0201f800,
+	0x0010513b, 0x04000007, 0x42006000, 0xffffffd7,
+	0x41786800, 0x0201f800, 0x0010427d, 0x0401f00b,
+	0x59c40006, 0x82000500, 0xffffff0f, 0x48038806,
+	0x42001000, 0x000000f0, 0x0201f800, 0x0010193d,
+	0x0201f800, 0x00105098, 0x1c01f000, 0x4803c856,
+	0x42006000, 0xbf7fffff, 0x42006800, 0x00400000,
+	0x0201f800, 0x0010427d, 0x4a035014, 0x00000001,
+	0x42001000, 0x001041f3, 0x0201f800, 0x00105fa4,
+	0x0201f800, 0x001041f8, 0x42000800, 0x000007d0,
+	0x42001000, 0x00104148, 0x0201f000, 0x0010606e,
+	0x59a80016, 0x82000580, 0x00000014, 0x04020025,
+	0x4803c857, 0x42006000, 0xffbfffff, 0x41786800,
+	0x0201f800, 0x0010427d, 0x59c40004, 0x82000500,
+	0x00000003, 0x0402001b, 0x59cc1006, 0x82081580,
+	0x11020000, 0x04020016, 0x59cc1007, 0x8c08153e,
+	0x0400000b, 0x59a80015, 0x8c000504, 0x04020008,
+	0x42000000, 0x0010b83f, 0x0201f800, 0x0010aa47,
+	0x59a80015, 0x84000544, 0x48035015, 0x42001000,
+	0x00104148, 0x0201f800, 0x00105f90, 0x4a035014,
+	0x00000010, 0x0401f9d4, 0x0401f002, 0x497b5016,
+	0x1c01f000, 0x4803c856, 0x4a035014, 0x00000003,
+	0x42006000, 0xbf3fffff, 0x42006800, 0x00100000,
+	0x0201f800, 0x0010427d, 0x42001000, 0x001041f3,
+	0x0201f800, 0x00105fa4, 0x0201f800, 0x001041f8,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x42007800, 0x0010b552, 0x46007800, 0x11020000,
+	0x42000800, 0x00000005, 0x0201f000, 0x0010416e,
+	0x59a80016, 0x80000540, 0x04000021, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000014, 0x04020016,
+	0x59cc1006, 0x82081580, 0x11020000, 0x04020012,
+	0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015,
+	0x8c000504, 0x04020008, 0x42000000, 0x0010b83f,
+	0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544,
+	0x48035015, 0x4a035014, 0x00000004, 0x0401f805,
+	0x0401f003, 0x0201f800, 0x00104139, 0x1c01f000,
+	0x4803c856, 0x4a035014, 0x00000005, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x42007800,
+	0x0010b552, 0x46007800, 0x11030000, 0x0201f800,
+	0x0010413e, 0x04020014, 0x59a80015, 0x8c000500,
+	0x04020011, 0x59a80810, 0x82040580, 0x00ffffff,
+	0x0400000d, 0x82040d00, 0x000000ff, 0x82040400,
+	0x0010210e, 0x50000800, 0x80040910, 0x42001000,
+	0x00000004, 0x0401fb9b, 0x0400000b, 0x0201f800,
+	0x0010420d, 0x4200b000, 0x00000004, 0x83cca400,
+	0x00000007, 0x4200a800, 0x0010b553, 0x0201f800,
+	0x0010ab17, 0x42000800, 0x00000005, 0x0201f000,
+	0x0010416e, 0x59a80016, 0x80000540, 0x04000020,
+	0x4803c857, 0x42001000, 0x00104148, 0x0201f800,
+	0x00105f90, 0x59a80016, 0x82000580, 0x00000014,
+	0x04020016, 0x59cc1006, 0x82081580, 0x11030000,
+	0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b,
+	0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+	0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+	0x84000544, 0x48035015, 0x4a035014, 0x00000006,
+	0x0401f804, 0x0401f002, 0x0401fbd3, 0x1c01f000,
+	0x4803c856, 0x4a035014, 0x00000007, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x42007800,
+	0x0010b552, 0x46007800, 0x11040000, 0x0401fbc7,
+	0x04020020, 0x59a80015, 0x8c000500, 0x0402001d,
+	0x599c0017, 0x8c000500, 0x0400001a, 0x599c1402,
+	0x82080480, 0x0000007f, 0x02021800, 0x001005d8,
+	0x4c080000, 0x82081400, 0x0010210e, 0x50081000,
+	0x82081500, 0x000000ff, 0x480b5010, 0x42000800,
+	0x00000003, 0x0201f800, 0x00106c78, 0x5c000800,
+	0x42001000, 0x00000004, 0x0401fb3e, 0x04000005,
+	0x0401fd2b, 0x04000003, 0x0201f800, 0x001015fe,
+	0x42000800, 0x00000005, 0x0401f3d4, 0x59a80016,
+	0x80000540, 0x04000020, 0x4803c857, 0x42001000,
+	0x00104148, 0x0201f800, 0x00105f90, 0x59a80016,
+	0x82000580, 0x00000014, 0x04020016, 0x59cc1006,
+	0x82081580, 0x11040000, 0x04020012, 0x59cc1007,
+	0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504,
+	0x04020008, 0x42000000, 0x0010b83f, 0x0201f800,
+	0x0010aa47, 0x59a80015, 0x84000544, 0x48035015,
+	0x4a035014, 0x00000008, 0x0401f804, 0x0401f002,
+	0x0401fb7d, 0x1c01f000, 0x4803c856, 0x4a035014,
+	0x00000009, 0x83cca400, 0x00000006, 0x4200a800,
+	0x0010b552, 0x4200b000, 0x00000005, 0x0201f800,
+	0x0010ab17, 0x42007800, 0x0010b552, 0x46007800,
+	0x11050100, 0x0401fb71, 0x0402000a, 0x59a80015,
+	0x8c000500, 0x04020007, 0x0401fa8c, 0x04020005,
+	0x82000540, 0x00000001, 0x0201f800, 0x001015fe,
+	0x42000800, 0x00000005, 0x0401fb94, 0x0401fb63,
+	0x04020ea4, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00109874, 0x5c027800, 0x1c01f000,
+	0x59a80016, 0x80000540, 0x0400003a, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000014, 0x04020030,
+	0x59cc1006, 0x82080500, 0x11050000, 0x82000580,
+	0x11050000, 0x0402002a, 0x8c081510, 0x04000014,
+	0x59cc1007, 0x8c08153e, 0x0400000b, 0x59a80015,
+	0x8c000504, 0x04020008, 0x42000000, 0x0010b83f,
+	0x0201f800, 0x0010aa47, 0x59a80015, 0x84000544,
+	0x48035015, 0x4a035013, 0x00000001, 0x4a035014,
+	0x0000000a, 0x0401f818, 0x0401f016, 0x80000540,
+	0x04020013, 0x59cc1007, 0x8c08153e, 0x0400000b,
+	0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+	0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+	0x84000544, 0x48035015, 0x497b5013, 0x4a035014,
+	0x0000000e, 0x0401f86d, 0x0401f002, 0x0401fb1a,
+	0x1c01f000, 0x4803c856, 0x4a035014, 0x0000000b,
+	0x42001000, 0x0010b553, 0x4008a800, 0x4200b000,
+	0x00000020, 0x4600a800, 0xffffffff, 0x8054a800,
+	0x8058b040, 0x040207fc, 0x42007800, 0x0010b552,
+	0x46007800, 0x11060000, 0x42001000, 0x0010b553,
+	0x0401fb0a, 0x04000005, 0x50080000, 0x46001000,
+	0x00ffffff, 0x0401f00c, 0x50080800, 0x82040d00,
+	0x0000ffff, 0x59a80010, 0x82000500, 0x000000ff,
+	0x82000540, 0x00000100, 0x800000e0, 0x80040d40,
+	0x44041000, 0x42000800, 0x00000021, 0x0401f327,
+	0x59a80016, 0x80000540, 0x04000014, 0x4803c857,
+	0x59a80016, 0x42001000, 0x00104148, 0x0201f800,
+	0x00105f90, 0x59a80016, 0x82000580, 0x00000084,
+	0x04020009, 0x59cc1006, 0x82081580, 0x11060000,
+	0x04020005, 0x4a035014, 0x0000000c, 0x0401f804,
+	0x0401f002, 0x0401fadc, 0x1c01f000, 0x4803c856,
+	0x4a035014, 0x0000000d, 0x83cca400, 0x00000006,
+	0x4200a800, 0x0010b552, 0x4200b000, 0x00000021,
+	0x0201f800, 0x0010ab17, 0x42007800, 0x0010b552,
+	0x46007800, 0x11070000, 0x42000800, 0x00000021,
+	0x0401f2fe, 0x59a80016, 0x80000540, 0x04000016,
+	0x4803c857, 0x59a80016, 0x42001000, 0x00104148,
+	0x0201f800, 0x00105f90, 0x82000580, 0x00000084,
+	0x0402000c, 0x59cc1006, 0x82081580, 0x11070000,
+	0x04020008, 0x4a035013, 0x00000001, 0x0401fa91,
+	0x4a035014, 0x0000000e, 0x0401f804, 0x0401f002,
+	0x0401fab1, 0x1c01f000, 0x4803c856, 0x82040d40,
+	0x00000001, 0x0401fbfc, 0x4a035014, 0x0000000f,
+	0x497b5016, 0x42006000, 0xffffffff, 0x42006800,
+	0x00300000, 0x0401fbe8, 0x42006000, 0xffdfffff,
+	0x41786800, 0x0401fbe4, 0x42000800, 0x000007d0,
+	0x42001000, 0x00104148, 0x0201f000, 0x00105f69,
+	0x4803c856, 0x59a80016, 0x80000540, 0x04020296,
+	0x1c01f000, 0x4803c856, 0x4a035014, 0x00000011,
+	0x83cca400, 0x00000006, 0x4200a800, 0x0010b552,
+	0x4200b000, 0x00000005, 0x0201f800, 0x0010ab17,
+	0x4200a800, 0x0010b552, 0x4600a800, 0x11020000,
+	0x0401fa8a, 0x04020015, 0x59a80010, 0x82000d00,
+	0xffff0000, 0x04000011, 0x82000500, 0x000000ff,
+	0x0400000e, 0x82000c00, 0x0010210e, 0x50040800,
+	0x80040910, 0x82040580, 0x0000007e, 0x04000007,
+	0x82040580, 0x00000080, 0x04000004, 0x42001000,
+	0x00000004, 0x0401fa07, 0x42000800, 0x00000005,
+	0x0401f2a2, 0x59a80016, 0x80000540, 0x04000020,
+	0x4803c857, 0x42001000, 0x00104148, 0x0201f800,
+	0x00105f90, 0x59a80016, 0x82000580, 0x00000014,
+	0x04020016, 0x59cc1006, 0x82081580, 0x11030000,
+	0x04020012, 0x59cc1007, 0x8c08153e, 0x0400000b,
+	0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+	0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+	0x84000544, 0x48035015, 0x4a035014, 0x00000012,
+	0x0401f804, 0x0401f002, 0x0401fa4b, 0x1c01f000,
+	0x4803c856, 0x4a035014, 0x00000013, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x4200a800,
+	0x0010b552, 0x4600a800, 0x11030000, 0x0401fa3f,
+	0x04020013, 0x59a80015, 0x8c000500, 0x04020010,
+	0x59a80810, 0x82040580, 0x00ffffff, 0x0400000c,
+	0x82040d00, 0x000000ff, 0x82040400, 0x0010210e,
+	0x50000800, 0x80040910, 0x42001000, 0x00000004,
+	0x0401f9c0, 0x04000002, 0x0401fafb, 0x42000800,
+	0x00000005, 0x0401f259, 0x59a80016, 0x80000540,
+	0x04000020, 0x4803c857, 0x42001000, 0x00104148,
+	0x0201f800, 0x00105f90, 0x59a80016, 0x82000580,
+	0x00000014, 0x04020016, 0x59cc1006, 0x82081580,
+	0x11040000, 0x04020012, 0x59cc1007, 0x8c08153e,
+	0x0400000b, 0x59a80015, 0x8c000504, 0x04020008,
+	0x42000000, 0x0010b83f, 0x0201f800, 0x0010aa47,
+	0x59a80015, 0x84000544, 0x48035015, 0x4a035014,
+	0x00000014, 0x0401f804, 0x0401f002, 0x0401fa02,
+	0x1c01f000, 0x4803c856, 0x4a035014, 0x00000015,
+	0x83cca400, 0x00000006, 0x4200a800, 0x0010b552,
+	0x4200b000, 0x00000005, 0x0201f800, 0x0010ab17,
+	0x4200a800, 0x0010b552, 0x4600a800, 0x11040000,
+	0x0401f9f6, 0x04020020, 0x59a80015, 0x8c000500,
+	0x0402001d, 0x599c0017, 0x8c000500, 0x0400001a,
+	0x599c1402, 0x82080480, 0x0000007f, 0x02021800,
+	0x001005d8, 0x4c080000, 0x82081400, 0x0010210e,
+	0x50081000, 0x82081500, 0x000000ff, 0x480b5010,
+	0x42000800, 0x00000003, 0x0201f800, 0x00106c78,
+	0x5c000800, 0x42001000, 0x00000004, 0x0401f96d,
+	0x04000005, 0x0201f800, 0x00103abf, 0x02020800,
+	0x001015fe, 0x42000800, 0x00000005, 0x0401f203,
+	0x59a80016, 0x80000540, 0x0400003f, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000014, 0x04020035,
+	0x59cc1006, 0x82080500, 0x11050000, 0x82000580,
+	0x11050000, 0x0402002f, 0x8c081510, 0x04000010,
+	0x0401fb09, 0x59cc1007, 0x8c08153e, 0x0400000b,
+	0x59a80015, 0x8c000504, 0x04020008, 0x42000000,
+	0x0010b83f, 0x0201f800, 0x0010aa47, 0x59a80015,
+	0x84000544, 0x48035015, 0x0401f013, 0x59cc1007,
+	0x8c08153e, 0x0400000b, 0x59a80015, 0x8c000504,
+	0x04020008, 0x42000000, 0x0010b83f, 0x0201f800,
+	0x0010aa47, 0x59a80015, 0x84000544, 0x48035015,
+	0x82000540, 0x00000001, 0x0401faeb, 0x497b5013,
+	0x0401f003, 0x4a035013, 0x00000001, 0x59cc1007,
+	0x8c08153c, 0x04000003, 0x4a035026, 0x00000008,
+	0x4a035014, 0x00000016, 0x0401f804, 0x0401f002,
+	0x0401f98d, 0x1c01f000, 0x4803c856, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x4a035014,
+	0x00000017, 0x59a80013, 0x8c000500, 0x04000006,
+	0x42001000, 0x0010b552, 0x46001000, 0x11050100,
+	0x0401f003, 0x4a035014, 0x0000001b, 0x0401f97b,
+	0x0402000a, 0x59a80015, 0x8c000500, 0x04020007,
+	0x0401f896, 0x04020005, 0x82000540, 0x00000001,
+	0x0201f800, 0x001015fe, 0x42000800, 0x00000005,
+	0x0401f99e, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00109874, 0x5c027800, 0x1c01f000,
+	0x59a80016, 0x80000540, 0x04000015, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000084, 0x0402000b,
+	0x59cc1006, 0x82081580, 0x11060000, 0x04020007,
+	0x80000580, 0x0401faa0, 0x4a035014, 0x00000018,
+	0x0401f804, 0x0401f002, 0x0401f94b, 0x1c01f000,
+	0x4803c856, 0x4a035014, 0x00000019, 0x83cca400,
+	0x00000006, 0x4200a800, 0x0010b552, 0x4200b000,
+	0x00000021, 0x0201f800, 0x0010ab17, 0x42003800,
+	0x0010b553, 0x0401f941, 0x04020018, 0x401c2800,
+	0x50141000, 0x80080130, 0x80000000, 0x40001800,
+	0x82081500, 0x00ffffff, 0x800000f0, 0x80080540,
+	0x44002800, 0x59a80810, 0x82040d00, 0x000000ff,
+	0x400c1000, 0x80081104, 0x82082400, 0x0010b553,
+	0x50101000, 0x820c0500, 0x00000003, 0x0c01f806,
+	0x80081540, 0x44082000, 0x42000800, 0x00000021,
+	0x0401f156, 0x0010401d, 0x00104022, 0x00104027,
+	0x0010402c, 0x800408f0, 0x40040000, 0x82081500,
+	0x00ffffff, 0x1c01f000, 0x800408e0, 0x40040000,
+	0x82081500, 0xff00ffff, 0x1c01f000, 0x800408d0,
+	0x40040000, 0x82081500, 0xffff00ff, 0x1c01f000,
+	0x40040000, 0x82081500, 0xffffff00, 0x1c01f000,
+	0x59a80016, 0x80000540, 0x04000016, 0x4803c857,
+	0x42001000, 0x00104148, 0x0201f800, 0x00105f90,
+	0x59a80016, 0x82000580, 0x00000084, 0x0402000c,
+	0x59cc1006, 0x82081580, 0x11070000, 0x04020008,
+	0x4a035013, 0x00000001, 0x0401f8d2, 0x4a035014,
+	0x0000001a, 0x0401f804, 0x0401f002, 0x0401f8f2,
+	0x1c01f000, 0x82000540, 0x00000001, 0x0401fa3e,
+	0x4a035014, 0x0000001b, 0x83cca400, 0x00000006,
+	0x4200a800, 0x0010b552, 0x59a82016, 0x40100000,
+	0x8000b104, 0x40580800, 0x5450a800, 0x8050a000,
+	0x8054a800, 0x8058b040, 0x040207fc, 0x0401f113,
+	0x1c01f000, 0x1c01f000, 0x4803c856, 0x42003000,
+	0x00000004, 0x42004000, 0x0010b553, 0x599c2817,
+	0x8c142d14, 0x0402001f, 0x42001000, 0x00000003,
+	0x40200000, 0x80080400, 0x50000800, 0x82042580,
+	0xffffffff, 0x04020005, 0x80081040, 0x80183040,
+	0x040207f8, 0x0401f05e, 0x800811c0, 0x04020006,
+	0x82042580, 0x3fffffff, 0x04000058, 0x82040d40,
+	0xc0000000, 0x4200b000, 0x00000020, 0x42001800,
+	0x00000001, 0x40042000, 0x80102102, 0x04021021,
+	0x800c18c2, 0x8058b040, 0x040207fc, 0x0401f04b,
+	0x41781000, 0x40200000, 0x80080400, 0x50000800,
+	0x82042580, 0xffffffff, 0x04020005, 0x80081000,
+	0x80183040, 0x040207f8, 0x0401f040, 0x800811c0,
+	0x04020003, 0x82040d40, 0xc0000000, 0x4200b000,
+	0x00000001, 0x42001800, 0x80000000, 0x40042000,
+	0x801020c2, 0x04021007, 0x800c1902, 0x8058b000,
+	0x82580480, 0x00000021, 0x040017fa, 0x0401f02f,
+	0x40200000, 0x80082400, 0x50100000, 0x800c0540,
+	0x44002000, 0x59a80015, 0x84000540, 0x48035015,
+	0x40580000, 0x42002800, 0x00000020, 0x80142c80,
+	0x40080000, 0x42003800, 0x00000003, 0x801c0480,
+	0x800000ca, 0x80142d40, 0x82144c00, 0x0010210e,
+	0x50242800, 0x82142d00, 0x000000ff, 0x48175010,
+	0x4c040000, 0x40140800, 0x0201f800, 0x001015eb,
+	0x5c000800, 0x40001800, 0x500c0000, 0x80100540,
+	0x44001800, 0x59a80015, 0x84000540, 0x48035015,
+	0x4200a800, 0x0010b553, 0x4020a000, 0x4200b000,
+	0x00000004, 0x0201f800, 0x0010ab17, 0x82000540,
+	0x00000001, 0x0401f002, 0x80000580, 0x1c01f000,
+	0x4807c857, 0x480bc857, 0x4008b000, 0x83cca400,
+	0x00000007, 0x4200a800, 0x0010b553, 0x40541000,
+	0x0201f800, 0x0010ab17, 0x40041800, 0x41782000,
+	0x42000000, 0x00000003, 0x820c1c80, 0x00000020,
+	0x04001004, 0x80102000, 0x80000040, 0x0401f7fb,
+	0x40041800, 0x801021c0, 0x04000005, 0x820c1c80,
+	0x00000020, 0x80102040, 0x040207fd, 0x42002000,
+	0x00000001, 0x800c19c0, 0x04000004, 0x801020c2,
+	0x800c1840, 0x040207fe, 0x80083c00, 0x83cc2c00,
+	0x00000007, 0x80142c00, 0x50140000, 0x80102d00,
+	0x04020012, 0x80100540, 0x44003800, 0x82042400,
+	0x0010210e, 0x50102800, 0x82142d00, 0x000000ff,
+	0x48175010, 0x4c040000, 0x40140800, 0x0201f800,
+	0x001015eb, 0x5c000800, 0x59a80015, 0x84000540,
+	0x48035015, 0x80000580, 0x1c01f000, 0x4807c856,
+	0x42001000, 0x00008017, 0x59a8184e, 0x0201f800,
+	0x0010aa4f, 0x0201f800, 0x00103a3e, 0x1c01f000,
+	0x4807c856, 0x4200b000, 0x00000020, 0x83cca400,
+	0x00000007, 0x4200a800, 0x0010be21, 0x0201f000,
+	0x0010ab28, 0x4807c856, 0x0201f800, 0x00106ede,
+	0x42000800, 0x000000f7, 0x0401f8de, 0x497b2804,
+	0x497b2805, 0x497b281c, 0x497b281d, 0x4202d800,
+	0x00000001, 0x42006000, 0xbf7fffff, 0x42006800,
+	0x00018000, 0x0401f950, 0x42006000, 0xfffeffff,
+	0x41786800, 0x0401f94c, 0x497b504e, 0x42000800,
+	0x0000002d, 0x42001000, 0x001041bc, 0x0201f000,
+	0x00105f69, 0x4807c856, 0x0401ffe3, 0x497b5014,
+	0x497b5016, 0x1c01f000, 0x4807c856, 0x59a80005,
+	0x8c000506, 0x1c01f000, 0x4807c856, 0x42006000,
+	0xffffffff, 0x42006800, 0x00000028, 0x0401f136,
+	0x4807c856, 0x0401ffc2, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000580, 0x00000002, 0x0402000a,
+	0x42006000, 0xffffffff, 0x42006800, 0x00200000,
+	0x0401f921, 0x42006000, 0xffdfffff, 0x41786800,
+	0x0401f91d, 0x497b5014, 0x42000800, 0x000000f7,
+	0x0401f89c, 0x59c400a3, 0x82000500, 0xbf20bfff,
+	0x82000540, 0x0001c000, 0x480388a3, 0x84000520,
+	0x480388a3, 0x1c01f000, 0x497b5016, 0x59b400f5,
+	0x8c000500, 0x04020004, 0x82000540, 0x00000001,
+	0x480368f5, 0x800400c4, 0x82000400, 0x00002000,
+	0x4803910a, 0x59b400f6, 0x82000500, 0x00000018,
+	0x040207fd, 0x4a0368f0, 0x0010b54b, 0x42000000,
+	0x0010b552, 0x480368f1, 0x82040400, 0x0000dc00,
+	0x480368f3, 0x59c400a4, 0x82000500, 0x0000000f,
+	0x82000580, 0x00000008, 0x04020017, 0x4c5c0000,
+	0x4c600000, 0x59c4b805, 0x8c5cbd3a, 0x04020005,
+	0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47,
+	0x4a038805, 0x02000000, 0x0201f800, 0x001019fe,
+	0x4000c000, 0x0201f800, 0x00101963, 0x4202d800,
+	0x00000001, 0x497b5014, 0x5c00c000, 0x5c00b800,
+	0x1c01f000, 0x59c8010b, 0x8c000502, 0x040007e2,
+	0x59c408a4, 0x82040d00, 0x0000000f, 0x82040d80,
+	0x0000000b, 0x04020005, 0x59a80814, 0x82040d40,
+	0x00002000, 0x0401f004, 0x59a80812, 0x82040d40,
+	0x00001000, 0x4807504e, 0x59a8084a, 0x800409c0,
+	0x04020007, 0x42000800, 0x000007d0, 0x42001000,
+	0x00104148, 0x0201f800, 0x0010606e, 0x1c01f000,
+	0x4807c856, 0x0401ff4e, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000580, 0x00000002, 0x0402000a,
+	0x42006000, 0xffffffff, 0x42006800, 0x00200000,
+	0x0401f8ad, 0x42006000, 0xffdfffff, 0x41786800,
+	0x0401f8a9, 0x0201f800, 0x00105141, 0x04000014,
+	0x0201f800, 0x00105151, 0x04020011, 0x4a035032,
+	0x0000aaaa, 0x4c040000, 0x0201f800, 0x0010162a,
+	0x59a8002a, 0x82000500, 0xffff0000, 0x80040540,
+	0x4803502a, 0x5c000800, 0x4a035033, 0x00000000,
+	0x0201f800, 0x001050a2, 0x0401f008, 0x4a03504c,
+	0x00000005, 0x42000000, 0x00000001, 0x0201f800,
+	0x00101590, 0x0401ff2c, 0x1c01f000, 0x0401f805,
+	0x42006000, 0xbf7f7fff, 0x41786800, 0x0401f086,
+	0x0201f800, 0x00105151, 0x04020005, 0x59c40006,
+	0x82000540, 0x000000f0, 0x48038806, 0x1c01f000,
+	0x800408d0, 0x59a80015, 0x8c000506, 0x04000006,
+	0x59a80010, 0x82000500, 0x000000ff, 0x80040540,
+	0x0401f003, 0x82040540, 0x000000f7, 0x480388a7,
+	0x1c01f000, 0x4807c856, 0x42000000, 0x0010b83b,
+	0x0201f800, 0x0010aa47, 0x42003000, 0x00000005,
+	0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000d,
+	0x42027800, 0x00000002, 0x0401f038, 0x4807c856,
+	0x42000000, 0x0010b86b, 0x0201f800, 0x0010aa47,
+	0x42003000, 0x00000000, 0x4d3c0000, 0x4c180000,
+	0x42003000, 0x0000000f, 0x42027800, 0x00000002,
+	0x0401f02a, 0x4807c856, 0x42000000, 0x0010b86a,
+	0x0201f800, 0x0010aa47, 0x42003000, 0x00000003,
+	0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000e,
+	0x42027800, 0x00000202, 0x0401f01c, 0x4807c856,
+	0x42000000, 0x0010b869, 0x0201f800, 0x0010aa47,
+	0x42003000, 0x00000004, 0x4d3c0000, 0x4c180000,
+	0x42003000, 0x00000010, 0x42027800, 0x00000202,
+	0x0401f00e, 0x4807c856, 0x42000000, 0x0010b83e,
+	0x0201f800, 0x0010aa47, 0x42003000, 0x00000001,
+	0x4d3c0000, 0x4c180000, 0x42003000, 0x0000000c,
+	0x42027800, 0x00000202, 0x42001800, 0x0000ffff,
+	0x42002000, 0x00000007, 0x0201f800, 0x00103aae,
+	0x5c003000, 0x4d400000, 0x0201f800, 0x0010a95d,
+	0x42028000, 0x0000002a, 0x0201f800, 0x00101fe5,
+	0x5c028000, 0x5c027800, 0x1c01f000, 0x4807c856,
+	0x04011000, 0x4a03c840, 0x0010b54b, 0x4a03c842,
+	0x00000040, 0x40000000, 0x040117ff, 0x42007800,
+	0x0010b54b, 0x46007800, 0x00000011, 0x803c7800,
+	0x4a007800, 0x220000ef, 0x4a007801, 0x000000ef,
+	0x4a007802, 0x01380000, 0x4a007803, 0x00000000,
+	0x4a007804, 0xffffffff, 0x4a007805, 0x00000000,
+	0x1c01f000, 0x59c400a3, 0x80300500, 0x80340540,
+	0x480388a3, 0x1c01f000, 0x4833c857, 0x59c400a3,
+	0x80300540, 0x480388a3, 0x80300580, 0x480388a3,
+	0x1c01f000, 0x4803c856, 0x04000004, 0x4a03504b,
+	0x00000001, 0x0401f002, 0x497b504b, 0x1c01f000,
+	0x4803c856, 0x59c80002, 0x80000540, 0x0400000a,
+	0x80000040, 0x04000008, 0x4a039005, 0x00000140,
+	0x42000000, 0x00000006, 0x80000040, 0x040207ff,
+	0x0401f7f4, 0x1c01f000, 0x4c5c0000, 0x4c600000,
+	0x59c4b805, 0x485fc856, 0x8c5cbd3a, 0x04020005,
+	0x42000000, 0x0010b818, 0x0201f800, 0x0010aa47,
+	0x4a038805, 0x02000000, 0x0201f800, 0x001019fe,
+	0x4000c000, 0x0201f800, 0x00101963, 0x4a038805,
+	0x04000000, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+	0x497a6a00, 0x4937c857, 0x4a026c00, 0x00000707,
+	0x497a6801, 0x497a6808, 0x497a6809, 0x497a6806,
+	0x497a6807, 0x497a6c0b, 0x497a680c, 0x0201f800,
+	0x00103b25, 0x04020006, 0x5934080f, 0x59340010,
+	0x80040540, 0x02020800, 0x001005d8, 0x4a026a04,
+	0x00000100, 0x497a6a03, 0x59340402, 0x82000500,
+	0x000000ff, 0x48026c02, 0x497a6c04, 0x497a6a05,
+	0x497a6c05, 0x497a6811, 0x4d2c0000, 0x5934000d,
+	0x49466c03, 0x80025d40, 0x04000004, 0x0201f800,
+	0x001007fd, 0x497a680d, 0x5c025800, 0x599c0401,
+	0x48026a0b, 0x599c0208, 0x48026c12, 0x497a680a,
+	0x0201f000, 0x00104c62, 0x42000000, 0x00000005,
+	0x80000d80, 0x0401f02d, 0x0201f800, 0x00104a09,
+	0x04020017, 0x59a80026, 0x8c00050a, 0x04020010,
+	0x59340212, 0x82000500, 0x0000ff00, 0x4803c857,
+	0x0400000b, 0x59340a00, 0x8c040d1e, 0x02000000,
+	0x000201c4, 0x42000000, 0x00000029, 0x42000800,
+	0x00001000, 0x492fc857, 0x0401f018, 0x492fc857,
+	0x42000000, 0x00000028, 0x0401f012, 0x59a80805,
+	0x8c040d02, 0x04020003, 0x8c040d00, 0x04000004,
+	0x42000000, 0x00000004, 0x0401f00a, 0x42000000,
+	0x00000029, 0x59340a00, 0x8c040d1e, 0x04000005,
+	0x492fc857, 0x42000800, 0x00001000, 0x0401f003,
+	0x492fc857, 0x80000d80, 0x4803c857, 0x80028540,
+	0x1c01f000, 0x4803c857, 0x59a80005, 0x8c000500,
+	0x040207ec, 0x0201f800, 0x001049e7, 0x040207e4,
+	0x59340200, 0x8c00050e, 0x040007e1, 0x0201f000,
+	0x000201c4, 0x0201f800, 0x001047eb, 0x040007bf,
+	0x0201f000, 0x000201c8, 0x592c0206, 0x492fc857,
+	0x82000d80, 0x000007ff, 0x04020006, 0x4a025c0a,
+	0x00000030, 0x42026800, 0x0010b524, 0x0401f021,
+	0x82000c80, 0x000007f0, 0x04021046, 0x81ac0400,
+	0x50000000, 0x80026d40, 0x04000038, 0x0201f800,
+	0x001048e3, 0x04020038, 0x592c040a, 0x8c00050a,
+	0x04020014, 0x592e6009, 0x83300480, 0x0010d1c0,
+	0x0400103b, 0x41580000, 0x81300480, 0x04021038,
+	0x59300c06, 0x82040580, 0x00000009, 0x04020037,
+	0x4a025a06, 0x00000000, 0x497a5800, 0x59300008,
+	0x80000540, 0x04020018, 0x492e6008, 0x0401f010,
+	0x0201f800, 0x0002075a, 0x04000019, 0x592c0206,
+	0x49366009, 0x492e6008, 0x4a026406, 0x00000009,
+	0x497a6015, 0x49325809, 0x82000d80, 0x000007ff,
+	0x04020003, 0x4a026015, 0x00008000, 0x42027000,
+	0x00000043, 0x0201f800, 0x000207a1, 0x80000580,
+	0x0401f020, 0x40000800, 0x58040000, 0x80000d40,
+	0x040207fd, 0x492c0800, 0x0401f01a, 0x42000000,
+	0x0000002c, 0x0401f016, 0x42000000, 0x00000028,
+	0x0401f013, 0x59a80805, 0x82040500, 0x00000003,
+	0x04000004, 0x42000000, 0x00000004, 0x0401f00c,
+	0x42000000, 0x00000029, 0x0401f009, 0x42000000,
+	0x00000008, 0x0401f006, 0x82040580, 0x00000007,
+	0x040207fb, 0x42000000, 0x00000005, 0x80000540,
+	0x1c01f000, 0x492fc857, 0x592e8c06, 0x83440d80,
+	0x000007fc, 0x04000004, 0x83440480, 0x000007f0,
+	0x04021014, 0x0201f800, 0x00020245, 0x04020011,
+	0x0201f800, 0x001049f3, 0x04020011, 0x0201f800,
+	0x0002075a, 0x0400001c, 0x49366009, 0x492e6008,
+	0x4a026406, 0x0000000a, 0x42027000, 0x00000040,
+	0x0201f800, 0x000207a1, 0x80000580, 0x0401f011,
+	0x42000000, 0x00000028, 0x0401f00d, 0x0201f800,
+	0x00104a09, 0x040007fb, 0x59a80805, 0x82040d00,
+	0x00000003, 0x04000004, 0x42000000, 0x00000004,
+	0x0401f003, 0x42000000, 0x00000029, 0x80000540,
+	0x1c01f000, 0x42000000, 0x0000002c, 0x0401f7fc,
+	0x492fc857, 0x592e8c06, 0x4947c857, 0x83440c80,
+	0x00000800, 0x42000000, 0x0000000a, 0x04021176,
+	0x592c4207, 0x4823c857, 0x82200500, 0x0000000f,
+	0x0c01f001, 0x001043d5, 0x0010445d, 0x001044a9,
+	0x001044b4, 0x001044bf, 0x001043d1, 0x001043d1,
+	0x001043d1, 0x001044cf, 0x00104513, 0x00104530,
+	0x001043d1, 0x001043d1, 0x001043d1, 0x001043d1,
+	0x001043d1, 0x4803c857, 0x42000000, 0x0000000c,
+	0x0401f15d, 0x592c1008, 0x82081500, 0x00ffffff,
+	0x59a80010, 0x80084d80, 0x42000000, 0x00000010,
+	0x04000155, 0x0201f800, 0x00104919, 0x04000036,
+	0x4803c857, 0x82004d80, 0x0000001d, 0x0402001a,
+	0x0201f800, 0x00105755, 0x59340405, 0x4c000000,
+	0x0201f800, 0x001049e7, 0x5c000000, 0x04000004,
+	0x8c20450a, 0x04000028, 0x80000580, 0x44002800,
+	0x59340008, 0x48002802, 0x59340009, 0x48002801,
+	0x59340006, 0x48002804, 0x59340007, 0x48002803,
+	0x4200b000, 0x00000005, 0x0201f800, 0x0010955f,
+	0x0401f166, 0x4803c857, 0x82004d80, 0x0000001a,
+	0x04020003, 0x40101000, 0x0401f136, 0x4803c857,
+	0x82004d80, 0x0000001b, 0x04020003, 0x40181000,
+	0x0401f130, 0x4803c857, 0x82004d80, 0x0000001c,
+	0x04000131, 0x82004d80, 0x00000019, 0x42000000,
+	0x0000000a, 0x04000120, 0x42000000, 0x0000000a,
+	0x04020137, 0x59a80005, 0x8c000514, 0x0400001b,
+	0x0201f800, 0x001049e7, 0x04000018, 0x59340212,
+	0x82000500, 0x0000ff00, 0x42001000, 0x00000010,
+	0x0402000c, 0x42001000, 0x00000008, 0x59a80026,
+	0x8c000506, 0x04020009, 0x59340002, 0x82000500,
+	0x00ff0000, 0x82000580, 0x00ff0000, 0x04000007,
+	0x0201f800, 0x00104c6d, 0x42000000, 0x0000001c,
+	0x40181000, 0x04020107, 0x0201f800, 0x0002075a,
+	0x04000111, 0x49366009, 0x492e6008, 0x4a026406,
+	0x00000001, 0x8c20450a, 0x04000004, 0x592c0404,
+	0x8400055c, 0x48025c04, 0x4c200000, 0x4d3c0000,
+	0x42027800, 0x00001000, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x5c004000, 0x8c204512, 0x0400000b,
+	0x599c0018, 0x8c000518, 0x04000008, 0x592c0009,
+	0x82000500, 0x00000380, 0x5934080a, 0x80040d40,
+	0x84040d54, 0x4806680a, 0x417a7800, 0x0401f914,
+	0x42000800, 0x00000003, 0x0401f91b, 0x42027000,
+	0x00000002, 0x0201f800, 0x000207a1, 0x80000580,
+	0x0401f10a, 0x0201f800, 0x00020245, 0x040200ec,
+	0x0201f800, 0x001049ed, 0x04000008, 0x0201f800,
+	0x001049e7, 0x040200ec, 0x417a7800, 0x417a6000,
+	0x0201f800, 0x001020a1, 0x59a80005, 0x8c000514,
+	0x0400001b, 0x0201f800, 0x001049e7, 0x04000018,
+	0x59340212, 0x82000500, 0x0000ff00, 0x42001000,
+	0x00000010, 0x0402000c, 0x42001000, 0x00000008,
+	0x59a80026, 0x8c000506, 0x04020009, 0x59340002,
+	0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000,
+	0x04000007, 0x0201f800, 0x00104c6d, 0x42000000,
+	0x0000001c, 0x40181000, 0x040200b2, 0x0201f800,
+	0x0002075a, 0x040000bc, 0x5934080a, 0x8c204512,
+	0x0400000c, 0x599c0018, 0x8c000518, 0x04000009,
+	0x592c0009, 0x82000500, 0x00000380, 0x82041500,
+	0xfffffc7f, 0x80080d40, 0x84040d54, 0x0401f002,
+	0x84040d14, 0x4806680a, 0x49366009, 0x492e6008,
+	0x4a026406, 0x00000001, 0x417a7800, 0x0401f8c8,
+	0x42000800, 0x00000005, 0x0401f8cf, 0x42027000,
+	0x00000003, 0x0201f800, 0x000207a1, 0x80000580,
+	0x0401f0be, 0x0201f800, 0x00020245, 0x040200a0,
+	0x0201f800, 0x001049fc, 0x040200a3, 0x0201f800,
+	0x00109517, 0x04000094, 0x80000580, 0x0401f0b3,
+	0x0201f800, 0x00020245, 0x04020095, 0x0201f800,
+	0x001049fc, 0x04020098, 0x0201f800, 0x001090e6,
+	0x04000089, 0x80000580, 0x0401f0a8, 0x0201f800,
+	0x00020245, 0x0402008a, 0x83444d80, 0x000007fe,
+	0x42000000, 0x0000000a, 0x0402006b, 0x0201f800,
+	0x001049e7, 0x04020088, 0x0201f800, 0x0010952f,
+	0x04000079, 0x80000580, 0x0401f098, 0x82200500,
+	0x00000070, 0x04020005, 0x8c20450e, 0x42000000,
+	0x0000000c, 0x0402005c, 0x8c20450a, 0x0400000d,
+	0x4d3c0000, 0x42027800, 0x00001000, 0x8c20450e,
+	0x04020002, 0x853e7d56, 0x82200500, 0x000000a0,
+	0x0201f800, 0x001049d3, 0x5c027800, 0x0401f07f,
+	0x0201f800, 0x00020245, 0x04020065, 0x8c204508,
+	0x04000010, 0x4d3c0000, 0x42027800, 0x00001000,
+	0x8c20450e, 0x04020002, 0x853e7d56, 0x82200500,
+	0x00000090, 0x0201f800, 0x001049bb, 0x5c027800,
+	0x42000000, 0x0000000a, 0x0402003b, 0x0401f06b,
+	0x836c0580, 0x00000003, 0x42000800, 0x00000007,
+	0x0402000f, 0x0201f800, 0x001049f3, 0x04000007,
+	0x4c000000, 0x0201f800, 0x00104a1f, 0x5c000000,
+	0x0400004d, 0x0401f05d, 0x0201f800, 0x001094c5,
+	0x04000007, 0x80000580, 0x0401f05c, 0x0201f800,
+	0x00104a1f, 0x04000051, 0x0401f054, 0x0201f800,
+	0x00104a1f, 0x04000034, 0x0401f050, 0x0201f800,
+	0x00020245, 0x04020036, 0x836c0580, 0x00000003,
+	0x04020040, 0x8c204508, 0x04000006, 0x417a7800,
+	0x417a6000, 0x0201f800, 0x001020a1, 0x0401f043,
+	0x0201f800, 0x001049ed, 0x04000008, 0x0201f800,
+	0x001049e7, 0x0402002c, 0x417a7800, 0x417a6000,
+	0x0201f800, 0x001020a1, 0x480bc856, 0x0201f800,
+	0x00109332, 0x04000018, 0x80000580, 0x0401f037,
+	0x0401f7e3, 0x480bc857, 0x42000800, 0x00000019,
+	0x40001000, 0x4200b000, 0x00000002, 0x0401f00a,
+	0x480bc857, 0x40000800, 0x4200b000, 0x00000002,
+	0x0401f005, 0x480bc857, 0x40000800, 0x4200b000,
+	0x00000001, 0x480bc857, 0x42028000, 0x00000031,
+	0x0401f020, 0x480bc857, 0x42000800, 0x00000003,
+	0x4200b000, 0x00000001, 0x0401f7f7, 0x480bc857,
+	0x42000800, 0x0000000a, 0x4200b000, 0x00000001,
+	0x0401f7f1, 0x480bc857, 0x42000800, 0x00000009,
+	0x40001000, 0x4200b000, 0x00000002, 0x0401f7ea,
+	0x480bc857, 0x42000800, 0x00000007, 0x4200b000,
+	0x00000001, 0x0401f7e4, 0x480bc857, 0x4200b000,
+	0x00000001, 0x0401f7e0, 0x80028580, 0x4178b000,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4937c857,
+	0x59326809, 0x59341200, 0x813e79c0, 0x04000003,
+	0x84081540, 0x0401f002, 0x84081500, 0x480a6a00,
+	0x1c01f000, 0x59326809, 0x5c000000, 0x4c000000,
+	0x4803c857, 0x4937c857, 0x82040580, 0x00000006,
+	0x04020004, 0x42000000, 0x00000606, 0x0401f021,
+	0x82040580, 0x00000004, 0x04020004, 0x42000000,
+	0x00000404, 0x0401f01b, 0x82040580, 0x00000007,
+	0x42000000, 0x00000707, 0x04000016, 0x82040580,
+	0x00000003, 0x42000000, 0x00000703, 0x04000011,
+	0x82040580, 0x00000005, 0x42000000, 0x00000405,
+	0x0400000c, 0x82040580, 0x00000009, 0x42000000,
+	0x00000409, 0x04000007, 0x82040580, 0x0000000b,
+	0x42000000, 0x0000070b, 0x02020800, 0x001005d8,
+	0x4803c857, 0x48026c00, 0x82040d80, 0x00000006,
+	0x04020005, 0x59341404, 0x800811c0, 0x02000800,
+	0x001005d8, 0x1c01f000, 0x5c000000, 0x4c000000,
+	0x4803c857, 0x4947c857, 0x481bc857, 0x83440480,
+	0x00000800, 0x04021034, 0x83441400, 0x0010ac00,
+	0x50080000, 0x80026d40, 0x04020011, 0x4c180000,
+	0x4d2c0000, 0x0201f800, 0x001007d3, 0x412e6800,
+	0x5c025800, 0x5c003000, 0x04000027, 0x45341000,
+	0x497a680d, 0x497a6810, 0x497a680f, 0x497a680e,
+	0x4c180000, 0x0401fcf3, 0x5c003000, 0x59340a12,
+	0x4c040000, 0x0201f800, 0x0010513b, 0x5c000800,
+	0x04000009, 0x82180500, 0x00ffff00, 0x04000008,
+	0x59a81010, 0x82081500, 0x00ffff00, 0x80080580,
+	0x04000003, 0x80000580, 0x0401f004, 0x82180500,
+	0x000000ff, 0x800000d0, 0x80040d80, 0x04000003,
+	0x4803c857, 0x48026a12, 0x59340002, 0x80180580,
+	0x04000003, 0x481bc857, 0x481a6802, 0x80000580,
+	0x1c01f000, 0x4803c856, 0x82000540, 0x00000001,
+	0x0401f7fc, 0x4947c857, 0x83440480, 0x00000800,
+	0x04021011, 0x83441400, 0x0010ac00, 0x50080000,
+	0x80026d40, 0x0400000b, 0x0401fbf9, 0x0402000a,
+	0x59a80005, 0x8c000502, 0x04000004, 0x59340200,
+	0x8c00050e, 0x04000004, 0x82000540, 0x00000001,
+	0x1c01f000, 0x80000580, 0x0401f7fe, 0x5c000000,
+	0x4c000000, 0x4803c857, 0x4947c857, 0x4d2c0000,
+	0x4d300000, 0x83440480, 0x00000800, 0x04021024,
+	0x83441400, 0x0010ac00, 0x50080000, 0x80026d40,
+	0x0400001b, 0x45781000, 0x5934000d, 0x80025d40,
+	0x02020800, 0x001007fd, 0x59366011, 0x813261c0,
+	0x0400000e, 0x4c640000, 0x5930c800, 0x59325808,
+	0x0201f800, 0x00109037, 0x02020800, 0x001007fd,
+	0x0201f800, 0x0002077d, 0x82666540, 0x00000000,
+	0x040207f6, 0x5c00c800, 0x0201f800, 0x00104c62,
+	0x41365800, 0x0201f800, 0x001007f5, 0x80000580,
+	0x5c026000, 0x5c025800, 0x1c01f000, 0x82000540,
+	0x00000001, 0x0401f7fb, 0x4937c857, 0x4c580000,
+	0x59cc0001, 0x82000500, 0x00ffffff, 0x48026802,
+	0x497a6c01, 0x497a6a01, 0x59340200, 0x84000502,
+	0x48026a00, 0x0201f800, 0x0010513b, 0x04020017,
+	0x59340403, 0x82000580, 0x000007fe, 0x04000005,
+	0x59a80026, 0x8c00050a, 0x04020010, 0x0401f008,
+	0x59cc0408, 0x8c000518, 0x0400000c, 0x59cc0009,
+	0x48035035, 0x59cc000a, 0x48035036, 0x59cc0207,
+	0x80000540, 0x04020003, 0x42000000, 0x00000001,
+	0x48038893, 0x4803501e, 0x59cc0a09, 0x82040d00,
+	0x00000010, 0x59cc0408, 0x82000500, 0x00000020,
+	0x04000002, 0x84040d40, 0x5934000a, 0x82000500,
+	0xffffffee, 0x80040540, 0x4802680a, 0x83cca400,
+	0x0000000b, 0x8334ac00, 0x00000006, 0x4200b000,
+	0x00000002, 0x0201f800, 0x0010ab17, 0x83cca400,
+	0x0000000d, 0x8334ac00, 0x00000008, 0x4200b000,
+	0x00000002, 0x0201f800, 0x0010ab17, 0x59cc0a18,
+	0x82040480, 0x00000800, 0x0402100c, 0x82040480,
+	0x00000400, 0x04001004, 0x42000800, 0x00000400,
+	0x0401f006, 0x82040480, 0x00000200, 0x04001003,
+	0x42000800, 0x00000200, 0x48066a04, 0x59340403,
+	0x82000580, 0x000007fe, 0x04020003, 0x59cc0a08,
+	0x48066a04, 0x42000800, 0x00000004, 0x59cc1207,
+	0x800811c0, 0x04000005, 0x82080480, 0x00000004,
+	0x04021002, 0x40080800, 0x48066c04, 0x5c00b000,
+	0x1c01f000, 0x4937c857, 0x59a80026, 0x8c000508,
+	0x04000004, 0x84000556, 0x4803c857, 0x48035026,
+	0x59cc0207, 0x4803c857, 0x48026a05, 0x59cc020a,
+	0x4803c857, 0x48026c05, 0x59341200, 0x599c0818,
+	0x5934180a, 0x4807c857, 0x480bc857, 0x480fc857,
+	0x59cc2006, 0x82102500, 0xff000000, 0x82102580,
+	0x02000000, 0x04000007, 0x8c00050e, 0x04000009,
+	0x8c0c1d14, 0x04000003, 0x8c0c1d0e, 0x04000005,
+	0x8c040d18, 0x04000003, 0x8408154a, 0x0401f002,
+	0x8408150a, 0x8c000510, 0x04000009, 0x8c0c1d14,
+	0x04000003, 0x8c0c1d10, 0x04000005, 0x8c040d18,
+	0x04000003, 0x8408154e, 0x0401f002, 0x8408150e,
+	0x8c000512, 0x04000009, 0x8c0c1d14, 0x04000003,
+	0x8c0c1d12, 0x04000005, 0x8c040d18, 0x04000003,
+	0x8408155c, 0x0401f002, 0x8408151c, 0x480a6a00,
+	0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4d2c0000,
+	0x4c580000, 0x5934000d, 0x80025d40, 0x04000029,
+	0x592c0003, 0x82000480, 0x00000008, 0x0400100b,
+	0x412cb800, 0x592c0001, 0x80025d40, 0x040207f9,
+	0x0201f800, 0x001007e4, 0x04000037, 0x492fc857,
+	0x492cb801, 0x0401f020, 0x832c0c00, 0x00000004,
+	0x4200b000, 0x00000008, 0x50040000, 0x82000580,
+	0xffffffff, 0x04020006, 0x80041000, 0x50080000,
+	0x82000580, 0xffffffff, 0x04000007, 0x82040c00,
+	0x00000002, 0x8058b040, 0x040207f4, 0x0201f800,
+	0x001005d8, 0x45480800, 0x454c1000, 0x592c1803,
+	0x800c1800, 0x480e5803, 0x480fc857, 0x0401f014,
+	0x0201f800, 0x001007e4, 0x04000017, 0x492fc857,
+	0x492e680d, 0x497a5802, 0x4a025803, 0x00000001,
+	0x494a5804, 0x494e5805, 0x832c0c00, 0x00000006,
+	0x4200b000, 0x0000000e, 0x46000800, 0xffffffff,
+	0x80040800, 0x8058b040, 0x040207fc, 0x82000540,
+	0x00000001, 0x5c00b000, 0x5c025800, 0x5c00b800,
+	0x1c01f000, 0x80000580, 0x0401f7fb, 0x4803c856,
+	0x4d3c0000, 0x4d2c0000, 0x5934000d, 0x80025d40,
+	0x0400001f, 0x592c0002, 0x80000540, 0x0402001f,
+	0x412e7800, 0x0401f8ce, 0x0402001c, 0x46000800,
+	0xffffffff, 0x46001000, 0xffffffff, 0x4813c857,
+	0x480fc857, 0x580c0003, 0x82000c80, 0x00000002,
+	0x04021014, 0x480fc857, 0x400c0000, 0x812c0580,
+	0x04020004, 0x580c0001, 0x4802680d, 0x0401f003,
+	0x580c0001, 0x48002001, 0x400e5800, 0x0201f800,
+	0x001007f4, 0x82000540, 0x00000001, 0x5c025800,
+	0x5c027800, 0x1c01f000, 0x80000580, 0x0401f7fc,
+	0x80000040, 0x48001803, 0x4803c857, 0x0401f7f6,
+	0x0201f800, 0x00020086, 0x59300007, 0x8400054e,
+	0x48026007, 0x592c1a04, 0x820c1d00, 0x000000ff,
+	0x820c0580, 0x00000048, 0x04000013, 0x0201f000,
+	0x0002028e, 0x8c000500, 0x02020800, 0x000200e5,
+	0x4a026203, 0x00000002, 0x592c1a04, 0x820c1d00,
+	0x000000ff, 0x820c0580, 0x00000018, 0x02000000,
+	0x0002028e, 0x820c0580, 0x00000048, 0x02020000,
+	0x0002028e, 0x42000800, 0x80000804, 0x0201f800,
+	0x00106721, 0x0201f000, 0x00020297, 0x4a025a06,
+	0x00000008, 0x0201f000, 0x000202da, 0x4a025a06,
+	0x00000029, 0x0201f000, 0x000202da, 0x4a025a06,
+	0x0000002a, 0x0201f000, 0x000202da, 0x4a025a06,
+	0x00000028, 0x0201f000, 0x000202da, 0x4943c857,
+	0x4d440000, 0x4d340000, 0x4d2c0000, 0x4c580000,
+	0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800,
+	0x00020245, 0x0402000d, 0x8d3e7d14, 0x04000005,
+	0x59340212, 0x82000500, 0x0000ff00, 0x04000007,
+	0x8d3e7d06, 0x04000004, 0x59340200, 0x8c00050e,
+	0x04020002, 0x0401f813, 0x81468800, 0x8058b040,
+	0x040207ef, 0x83440480, 0x00000800, 0x04021008,
+	0x8d3e7d02, 0x04000006, 0x42028800, 0x000007f0,
+	0x4200b000, 0x00000010, 0x0401f7e5, 0x5c00b000,
+	0x5c025800, 0x5c026800, 0x5c028800, 0x1c01f000,
+	0x4d2c0000, 0x41783000, 0x5936580f, 0x812e59c0,
+	0x04000029, 0x592c0204, 0x82000500, 0x000000ff,
+	0x82000580, 0x00000012, 0x04000020, 0x8d3e7d00,
+	0x04000003, 0x0401f83c, 0x0402001c, 0x592c2000,
+	0x497a5800, 0x801831c0, 0x04020009, 0x59340010,
+	0x812c0580, 0x04020004, 0x497a680f, 0x497a6810,
+	0x0401f008, 0x4812680f, 0x0401f006, 0x48103000,
+	0x59340010, 0x812c0580, 0x04020002, 0x481a6810,
+	0x4a025a04, 0x00000103, 0x49425a06, 0x497a5c09,
+	0x0201f800, 0x001091c6, 0x0201f800, 0x000202da,
+	0x40125800, 0x0401f7da, 0x412c3000, 0x592e5800,
+	0x0401f7d7, 0x5c025800, 0x1c01f000, 0x4803c856,
+	0x41781800, 0x5934000f, 0x80025d40, 0x04000010,
+	0x592c0005, 0x80200580, 0x592c0000, 0x04000003,
+	0x412c1800, 0x0401f7f9, 0x497a5800, 0x800c19c0,
+	0x04000008, 0x48001800, 0x80000540, 0x04020004,
+	0x480e6810, 0x82000540, 0x00000001, 0x1c01f000,
+	0x4802680f, 0x80000540, 0x040207fd, 0x497a6810,
+	0x0401f7f9, 0x592c0008, 0x81480580, 0x04020003,
+	0x592c0009, 0x814c0580, 0x1c01f000, 0x4803c856,
+	0x4c580000, 0x413c1800, 0x400c2000, 0x593c0002,
+	0x80000540, 0x04020018, 0x4200b000, 0x00000008,
+	0x820c0c00, 0x00000004, 0x50040000, 0x81480580,
+	0x04020005, 0x80041000, 0x50080000, 0x814c0580,
+	0x0400000d, 0x82040c00, 0x00000002, 0x8058b040,
+	0x040207f6, 0x400c2000, 0x580c0001, 0x80001d40,
+	0x040207ee, 0x82000540, 0x00000001, 0x5c00b000,
+	0x1c01f000, 0x80000580, 0x0401f7fd, 0x4937c857,
+	0x4c580000, 0x4d2c0000, 0x5934000d, 0x80025d40,
+	0x04020016, 0x0201f800, 0x001007e4, 0x04000010,
+	0x492e680d, 0x4a025802, 0x00000001, 0x497a5803,
+	0x832c0c00, 0x00000004, 0x4200b000, 0x00000010,
+	0x46000800, 0xffffffff, 0x80040800, 0x8058b040,
+	0x040207fc, 0x82000540, 0x00000001, 0x5c025800,
+	0x5c00b000, 0x1c01f000, 0x4d2c0000, 0x592e5801,
+	0x0201f800, 0x001007fd, 0x5c025800, 0x0401f7ea,
+	0x4d2c0000, 0x5936580d, 0x812e59c0, 0x04000007,
+	0x4937c857, 0x497a680d, 0x0201f800, 0x001007fd,
+	0x82000540, 0x00000001, 0x5c025800, 0x1c01f000,
+	0x59340405, 0x4937c857, 0x4803c857, 0x8c000508,
+	0x1c01f000, 0x4803c856, 0x0201f800, 0x0010513b,
+	0x04000011, 0x59a80815, 0x8c040d04, 0x0402000e,
+	0x59a80826, 0x8c040d06, 0x0400000b, 0x83ac0400,
+	0x000007fe, 0x50000000, 0x80026d40, 0x04000006,
+	0x0401f9a7, 0x04020004, 0x59340200, 0x8400055a,
+	0x48026a00, 0x599c0017, 0x8c000508, 0x04000015,
+	0x4200b000, 0x000007f0, 0x417a8800, 0x0201f800,
+	0x00020245, 0x0402000c, 0x0401f999, 0x0402000a,
+	0x59a80010, 0x59340802, 0x80040580, 0x82000500,
+	0x00ffff00, 0x04020004, 0x59340200, 0x8400055a,
+	0x48026a00, 0x81468800, 0x8058b040, 0x040207f0,
+	0x0401f884, 0x04000003, 0x59a80836, 0x0401f006,
+	0x599c0017, 0x8c000508, 0x04000007, 0x42000800,
+	0x000007d0, 0x42001000, 0x00104876, 0x0201f800,
+	0x0010606e, 0x1c01f000, 0x4803c856, 0x4d340000,
+	0x4d440000, 0x4d3c0000, 0x4c580000, 0x42001000,
+	0x00104876, 0x0201f800, 0x00105f90, 0x59a80826,
+	0x8c040d06, 0x04000015, 0x0401f86a, 0x04000013,
+	0x83ae6c00, 0x000007fe, 0x51366800, 0x59340200,
+	0x8400051a, 0x48026a00, 0x599c0017, 0x8c000508,
+	0x04000007, 0x42000800, 0x000007d0, 0x42001000,
+	0x00104876, 0x0201f800, 0x0010606e, 0x0201f800,
+	0x00101e45, 0x0401f027, 0x4200b000, 0x000007f0,
+	0x80028d80, 0x0201f800, 0x00020245, 0x0402001e,
+	0x59340200, 0x8c00051a, 0x0400001b, 0x59368c03,
+	0x417a7800, 0x42028000, 0x00000029, 0x41783000,
+	0x0201f800, 0x0010a446, 0x59340200, 0x84000558,
+	0x8400051a, 0x48026a00, 0x4937c857, 0x4a026c00,
+	0x00000707, 0x42028000, 0x00000029, 0x0201f800,
+	0x00106ab4, 0x417a7800, 0x0201f800, 0x001067fd,
+	0x80000d80, 0x0201f800, 0x0010a2ff, 0x0201f800,
+	0x00106c4b, 0x81468800, 0x8058b040, 0x040207de,
+	0x5c00b000, 0x5c027800, 0x5c028800, 0x5c026800,
+	0x1c01f000, 0x4933c857, 0x59303809, 0x581c0200,
+	0x8400051a, 0x48003a00, 0x1c01f000, 0x4803c856,
+	0x42026800, 0x0010b524, 0x497a680e, 0x42028800,
+	0x000007ff, 0x0201f800, 0x001042b4, 0x4937c857,
+	0x4a026c00, 0x00000606, 0x4a026802, 0x00ffffff,
+	0x4a026a04, 0x00000200, 0x4a026c04, 0x00000002,
+	0x1c01f000, 0x59300009, 0x50000000, 0x4933c857,
+	0x4803c857, 0x8c00050e, 0x1c01f000, 0x59300009,
+	0x50000000, 0x8c00050a, 0x1c01f000, 0x4933c856,
+	0x0401f90f, 0x04000006, 0x59340400, 0x82000d00,
+	0x000000ff, 0x82041580, 0x00000005, 0x1c01f000,
+	0x4d340000, 0x83ac0400, 0x000007fe, 0x50000000,
+	0x80026d40, 0x04000003, 0x59340200, 0x8c00051a,
+	0x5c026800, 0x1c01f000, 0x4937c857, 0x493fc857,
+	0x59340403, 0x81ac0400, 0x50000000, 0x81340580,
+	0x02020800, 0x001005d8, 0x59341200, 0x813e79c0,
+	0x04000003, 0x8408155e, 0x0401f002, 0x8408151e,
+	0x480a6a00, 0x1c01f000, 0x4937c857, 0x0201f800,
+	0x0010210a, 0x04000006, 0x59a80835, 0x42001000,
+	0x00104910, 0x0201f800, 0x0010606e, 0x1c01f000,
+	0x4937c857, 0x42001000, 0x00104910, 0x0201f800,
+	0x00105f90, 0x59a81026, 0x84081512, 0x480b5026,
+	0x1c01f000, 0x4c380000, 0x4c340000, 0x4c240000,
+	0x4c600000, 0x4008c000, 0x83440480, 0x00000800,
+	0x04021045, 0x80002d80, 0x41442000, 0x83447400,
+	0x0010ac00, 0x4200b000, 0x000007f0, 0x83444c80,
+	0x000007f0, 0x04001003, 0x4200b000, 0x00000010,
+	0x50380000, 0x80000540, 0x0402001e, 0x41440000,
+	0x80100580, 0x04020043, 0x40102800, 0x82104c80,
+	0x000007f0, 0x04001015, 0x82104d80, 0x000007fc,
+	0x04020005, 0x82604d80, 0x00fffffc, 0x0402002a,
+	0x0401f00e, 0x82104d80, 0x000007fd, 0x04020005,
+	0x82604d80, 0x00fffffd, 0x04020023, 0x0401f007,
+	0x82104d80, 0x000007ff, 0x0402001f, 0x82604d80,
+	0x00ffffff, 0x0402001c, 0x84142d5e, 0x0401f029,
+	0x40006800, 0x58343002, 0x82183500, 0x00ffffff,
+	0x40180000, 0x80600580, 0x04020019, 0x40100000,
+	0x81440580, 0x0402000a, 0x40366800, 0x8c204508,
+	0x04000053, 0x0401ff8a, 0x04020051, 0x4947c857,
+	0x42000000, 0x0000001d, 0x0401f04e, 0x4947c857,
+	0x480bc857, 0x4823c857, 0x42000000, 0x0000001a,
+	0x0401f048, 0x4947c857, 0x4863c857, 0x4813c857,
+	0x42000000, 0x00000019, 0x0401f042, 0x40100000,
+	0x81440580, 0x04020007, 0x58343002, 0x4947c857,
+	0x481bc857, 0x42000000, 0x0000001b, 0x0401f039,
+	0x80102000, 0x80387000, 0x83444c80, 0x000007f0,
+	0x04001009, 0x82104d80, 0x00000800, 0x0402000c,
+	0x42002000, 0x000007f0, 0x42007000, 0x0010b3f0,
+	0x0401f007, 0x82104d80, 0x000007f0, 0x04020004,
+	0x41782000, 0x42007000, 0x0010ac00, 0x8058b040,
+	0x040207a4, 0x801429c0, 0x04020007, 0x0201f800,
+	0x001005d8, 0x4947c857, 0x42000000, 0x0000000a,
+	0x0401f01c, 0x4d2c0000, 0x4c180000, 0x40603000,
+	0x0401fc12, 0x4947c857, 0x4937c857, 0x5c003000,
+	0x5c025800, 0x040207f4, 0x497a6a12, 0x59a80026,
+	0x8c00050a, 0x0402000d, 0x82600500, 0x00ffff00,
+	0x04000006, 0x59a84810, 0x82244d00, 0x00ffff00,
+	0x80240580, 0x04020005, 0x82600500, 0x000000ff,
+	0x800000d0, 0x48026a12, 0x48626802, 0x80000580,
+	0x80000540, 0x5c00c000, 0x5c004800, 0x5c006800,
+	0x5c007000, 0x1c01f000, 0x5934000f, 0x5934140b,
+	0x80081040, 0x04001002, 0x480a6c0b, 0x80000540,
+	0x02020800, 0x00020253, 0x1c01f000, 0x4803c857,
+	0x4947c857, 0x4c300000, 0x82006500, 0x00000030,
+	0x04000006, 0x4c000000, 0x0201f800, 0x0010942a,
+	0x5c000000, 0x0402000b, 0x8c00050e, 0x04000006,
+	0x0201f800, 0x00020245, 0x04020006, 0x4937c857,
+	0x0401fc2f, 0x80000580, 0x5c006000, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fc, 0x4803c857,
+	0x4c580000, 0x4d440000, 0x40001000, 0x80000d80,
+	0x4200b000, 0x000007f0, 0x4c040000, 0x40068800,
+	0x4c080000, 0x40080000, 0x0401ffdd, 0x5c001000,
+	0x5c000800, 0x80040800, 0x8058b040, 0x040207f7,
+	0x5c028800, 0x5c00b000, 0x1c01f000, 0x4c5c0000,
+	0x59340400, 0x8200bd80, 0x00000606, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x59340400, 0x8200bd80,
+	0x00000404, 0x5c00b800, 0x1c01f000, 0x4c5c0000,
+	0x59340400, 0x8200bd80, 0x00000404, 0x04000003,
+	0x8200bd80, 0x00000606, 0x5c00b800, 0x1c01f000,
+	0x4c5c0000, 0x4c600000, 0x59340400, 0x8200bd00,
+	0x0000ff00, 0x825cc580, 0x00000400, 0x04000003,
+	0x825cc580, 0x00000600, 0x5c00c000, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x59340400, 0x82000500,
+	0x000000ff, 0x8200bd80, 0x00000003, 0x04000003,
+	0x8200bd80, 0x00000005, 0x5c00b800, 0x1c01f000,
+	0x4c5c0000, 0x59340400, 0x82000500, 0x0000ff00,
+	0x8400b9c0, 0x805c0580, 0x4937c857, 0x4803c857,
+	0x48026c00, 0x5c00b800, 0x1c01f000, 0x4c040000,
+	0x4c080000, 0x592c0207, 0x8c00050c, 0x0400000f,
+	0x592e8c06, 0x82000500, 0x00000080, 0x84000548,
+	0x4d3c0000, 0x42027800, 0x00001000, 0x0401ff90,
+	0x5c027800, 0x82000540, 0x00000001, 0x5c001000,
+	0x5c000800, 0x1c01f000, 0x80000580, 0x0401f7fc,
+	0x592c040b, 0x82000500, 0x0000e000, 0x82000580,
+	0x00006000, 0x04000019, 0x836c0580, 0x00000003,
+	0x04000016, 0x836c0580, 0x00000002, 0x040200ff,
+	0x59a80026, 0x82000d00, 0x00000038, 0x04020005,
+	0x59a80832, 0x800409c0, 0x0400000c, 0x0401f0f7,
+	0x82000d00, 0x00000003, 0x82040d80, 0x00000003,
+	0x040200f2, 0x82000d00, 0x00000028, 0x04020003,
+	0x8c00050c, 0x040000ed, 0x592c100a, 0x82080500,
+	0xff000000, 0x040200ce, 0x59a80010, 0x80080580,
+	0x040000c8, 0x592c0c0b, 0x82040d00, 0x0000e000,
+	0x82040480, 0x00008000, 0x040210c8, 0x592e8c06,
+	0x83440480, 0x00000800, 0x04001007, 0x83440580,
+	0x0000ffff, 0x040200af, 0x800409c0, 0x040200f7,
+	0x0401f0ac, 0x800409c0, 0x040200f4, 0x41784000,
+	0x0401fead, 0x040200db, 0x42027000, 0x00000053,
+	0x592c2409, 0x82100500, 0xffffff00, 0x040200aa,
+	0x4813c857, 0x592c000c, 0x800001c0, 0x04000083,
+	0x82100580, 0x00000004, 0x040000a0, 0x82100580,
+	0x00000051, 0x0400009d, 0x82100580, 0x00000003,
+	0x04000016, 0x82100580, 0x00000020, 0x0400004b,
+	0x82100580, 0x00000024, 0x04000042, 0x82100580,
+	0x00000021, 0x04000042, 0x82100580, 0x00000050,
+	0x04000037, 0x82100580, 0x00000052, 0x04000031,
+	0x82100580, 0x00000005, 0x0402006b, 0x42027000,
+	0x00000001, 0x0401f01b, 0x42027000, 0x00000002,
+	0x59a80005, 0x8c000514, 0x04000016, 0x0401ff4c,
+	0x04000014, 0x59340212, 0x82000500, 0x0000ff00,
+	0x42001000, 0x00000010, 0x0402000c, 0x59a80026,
+	0x8c000506, 0x0402006f, 0x42001000, 0x00000008,
+	0x59340002, 0x82000500, 0x00ff0000, 0x82000580,
+	0x00ff0000, 0x04000003, 0x0401f9bf, 0x04020065,
+	0x0201f800, 0x0002075a, 0x0400007e, 0x4a026406,
+	0x00000010, 0x49366009, 0x42000800, 0x00000003,
+	0x83380580, 0x00000002, 0x04000003, 0x42000800,
+	0x0000000b, 0x0201f800, 0x00104571, 0x0401f044,
+	0x42027000, 0x00000000, 0x0401f003, 0x42027000,
+	0x00000004, 0x0401ff37, 0x04020071, 0x0401f036,
+	0x42027000, 0x00000033, 0x0401f006, 0x42027000,
+	0x00000005, 0x0401f003, 0x42027000, 0x00000003,
+	0x0401ff23, 0x04020066, 0x59a80005, 0x8c000514,
+	0x04000016, 0x0401ff12, 0x04000014, 0x59340212,
+	0x82000500, 0x0000ff00, 0x42001000, 0x00000010,
+	0x0402000c, 0x59a80026, 0x8c000506, 0x04020035,
+	0x42001000, 0x00000008, 0x59340002, 0x82000500,
+	0x00ff0000, 0x82000580, 0x00ff0000, 0x04000003,
+	0x0401f985, 0x0402002b, 0x0201f800, 0x0002075a,
+	0x04000044, 0x4a026406, 0x00000010, 0x49366009,
+	0x42000800, 0x00000005, 0x83380580, 0x00000003,
+	0x04000003, 0x42000800, 0x00000009, 0x0201f800,
+	0x00104571, 0x0401f00a, 0x82102580, 0x00000011,
+	0x0402002d, 0x0201f800, 0x0002075a, 0x04000031,
+	0x4a026406, 0x00000010, 0x49366009, 0x492e6008,
+	0x49325808, 0x813669c0, 0x04000007, 0x592c0c0b,
+	0x8c040d18, 0x04000004, 0x59340200, 0x84000514,
+	0x48026a00, 0x0201f800, 0x000207a1, 0x80000580,
+	0x1c01f000, 0x82000540, 0x00000001, 0x0401f7fd,
+	0x42001000, 0x0000000a, 0x0401f015, 0x42001000,
+	0x00000010, 0x0401f012, 0x42001000, 0x00000016,
+	0x0401f00f, 0x42001000, 0x00000017, 0x0401f00c,
+	0x42001000, 0x00000018, 0x0401f009, 0x42001000,
+	0x0000001b, 0x0401f006, 0x42001000, 0x0000001e,
+	0x0401f003, 0x42001000, 0x00000020, 0x42000800,
+	0x00000019, 0x42028000, 0x00000031, 0x0401f7e2,
+	0x42000800, 0x00000003, 0x0401f003, 0x42000800,
+	0x0000000a, 0x41781000, 0x0401f7f7, 0x42000800,
+	0x00000009, 0x59341400, 0x0401f7f3, 0x42028000,
+	0x00000008, 0x0401f005, 0x42000800, 0x00000007,
+	0x416c1000, 0x0401f7ec, 0x41780800, 0x41781000,
+	0x0401f7cd, 0x42028000, 0x00000000, 0x0401f7fb,
+	0x82004d80, 0x0000001d, 0x02000800, 0x001005d8,
+	0x82004d80, 0x0000001a, 0x04020004, 0x40101000,
+	0x40000800, 0x0401f7dc, 0x82004d80, 0x0000001b,
+	0x04020003, 0x40181000, 0x0401f7fa, 0x82004d80,
+	0x0000001c, 0x040007f7, 0x82004d80, 0x00000019,
+	0x040007b8, 0x0401f7d6, 0x592e6008, 0x0201f800,
+	0x0010941a, 0x040007b6, 0x59300c06, 0x82040580,
+	0x00000011, 0x040207d6, 0x83440580, 0x0000ffff,
+	0x04020005, 0x59326809, 0x813669c0, 0x0400000e,
+	0x0401f7cf, 0x592c100a, 0x82081500, 0x00ffffff,
+	0x41784000, 0x0401fda8, 0x040207d6, 0x59300009,
+	0x800001c0, 0x04000003, 0x81340580, 0x040207c4,
+	0x49366009, 0x592c0c0b, 0x82041500, 0x0000e000,
+	0x82080580, 0x00006000, 0x04000009, 0x59300a03,
+	0x82040580, 0x00000007, 0x040207b9, 0x492e6008,
+	0x42027000, 0x00000054, 0x0401f77f, 0x0201f800,
+	0x0010a8d4, 0x040007bc, 0x0401f7b1, 0x492fc857,
+	0x59a80021, 0x800001c0, 0x04020073, 0x592e6008,
+	0x4933c857, 0x0201f800, 0x0010941a, 0x04000041,
+	0x59301406, 0x82080580, 0x00000005, 0x0402005b,
+	0x59301203, 0x82080580, 0x00000007, 0x04020057,
+	0x592e8c06, 0x83440480, 0x00000800, 0x04021032,
+	0x41784000, 0x592c1009, 0x82081500, 0x00ffffff,
+	0x0401fd75, 0x0402005f, 0x59300009, 0x800001c0,
+	0x04000003, 0x81340580, 0x04020048, 0x4d300000,
+	0x592e6013, 0x4933c857, 0x83300580, 0xffffffff,
+	0x0400000d, 0x0201f800, 0x0010941a, 0x5c026000,
+	0x04000029, 0x591c1406, 0x82080580, 0x00000006,
+	0x04000046, 0x82080580, 0x00000011, 0x04000043,
+	0x0401f002, 0x5c026000, 0x59a80010, 0x592c100a,
+	0x82081500, 0x00ffffff, 0x80081580, 0x04020017,
+	0x592c1009, 0x82081500, 0x00ffffff, 0x80081580,
+	0x0400000f, 0x49366009, 0x492e6008, 0x42027000,
+	0x00000092, 0x0201f800, 0x000207a1, 0x80000580,
+	0x1c01f000, 0x42001000, 0x0000000a, 0x0401f00c,
+	0x42001000, 0x00000010, 0x0401f009, 0x42001000,
+	0x00000014, 0x0401f006, 0x42001000, 0x00000018,
+	0x0401f003, 0x42001000, 0x0000003c, 0x492fc857,
+	0x480bc857, 0x42000800, 0x00000019, 0x42028000,
+	0x00000031, 0x82000540, 0x00000001, 0x0401f7e9,
+	0x492fc857, 0x4803c857, 0x480bc857, 0x40000800,
+	0x0401f7f7, 0x492fc857, 0x42000800, 0x0000000a,
+	0x41781000, 0x0401f7f2, 0x4933c857, 0x59300406,
+	0x4803c857, 0x59300203, 0x4803c857, 0x59300009,
+	0x4803c857, 0x42028000, 0x00000008, 0x41780800,
+	0x41781000, 0x0401f7e8, 0x42000800, 0x0000001e,
+	0x0401f7f0, 0x42000800, 0x00000001, 0x0401f7ed,
+	0x82004d80, 0x0000001d, 0x02000800, 0x001005d8,
+	0x82004d80, 0x0000001a, 0x04020003, 0x40101000,
+	0x0401f7dc, 0x82004d80, 0x0000001b, 0x04020003,
+	0x40181000, 0x0401f7d7, 0x82004d80, 0x0000001c,
+	0x040007d4, 0x82004d80, 0x00000019, 0x040007d1,
+	0x0401f7d5, 0x59302009, 0x801021c0, 0x04000035,
+	0x58101400, 0x82081d00, 0x000000ff, 0x59300c03,
+	0x82040580, 0x00000008, 0x04000022, 0x82040580,
+	0x0000000a, 0x04000017, 0x82040580, 0x0000000c,
+	0x04000010, 0x82040580, 0x00000002, 0x04000019,
+	0x82040580, 0x00000001, 0x04000012, 0x82040580,
+	0x00000003, 0x0400000b, 0x82040580, 0x00000005,
+	0x04000004, 0x82040580, 0x00000033, 0x04020019,
+	0x820c0580, 0x00000009, 0x0400000d, 0x0401f015,
+	0x820c0580, 0x00000005, 0x04000009, 0x0401f011,
+	0x820c0580, 0x0000000b, 0x04000005, 0x0401f00d,
+	0x820c0580, 0x00000003, 0x0402000a, 0x82081d00,
+	0xffffff00, 0x840c01c0, 0x800c0540, 0x4813c857,
+	0x480bc857, 0x4807c857, 0x4803c857, 0x48002400,
+	0x1c01f000, 0x599c0017, 0x8c00050a, 0x04000003,
+	0x80000580, 0x1c01f000, 0x59a80026, 0x82000500,
+	0x00000028, 0x04000008, 0x42028800, 0x000007fd,
+	0x0201f800, 0x00020245, 0x04020003, 0x5934000a,
+	0x8c000504, 0x1c01f000, 0x4d300000, 0x5934000e,
+	0x80026540, 0x04000006, 0x0201f800, 0x001062d5,
+	0x02000800, 0x001064ad, 0x497a680e, 0x5c026000,
+	0x1c01f000, 0x4d440000, 0x4d340000, 0x80000580,
+	0x40001800, 0x40028800, 0x82080580, 0x00000008,
+	0x04020003, 0x42001800, 0x00000001, 0x0201f800,
+	0x00020245, 0x0402000a, 0x0401fd6d, 0x04020008,
+	0x800c19c0, 0x04000004, 0x59340405, 0x8c000508,
+	0x04000003, 0x80081040, 0x04000009, 0x81468800,
+	0x83440480, 0x00000800, 0x040017f1, 0x80000580,
+	0x5c026800, 0x5c028800, 0x1c01f000, 0x82000540,
+	0x00000001, 0x5c026800, 0x5c028800, 0x1c01f000,
+	0x4a033020, 0x00000000, 0x497b3026, 0x497b3027,
+	0x497b3028, 0x497b3029, 0x497b302b, 0x497b3021,
+	0x4a03b104, 0x60000001, 0x1c01f000, 0x4803c856,
+	0x599c0018, 0x497b3024, 0x497b3025, 0x82000500,
+	0x0000000f, 0x82000d80, 0x00000005, 0x04000006,
+	0x82000580, 0x00000006, 0x0400000d, 0x497b3022,
+	0x1c01f000, 0x4a033022, 0x00000005, 0x599c0216,
+	0x82000500, 0x0000ffff, 0x04020003, 0x42000000,
+	0x00000002, 0x48033023, 0x1c01f000, 0x4a033022,
+	0x00000006, 0x0401f7f6, 0x0401ffe5, 0x4a03c826,
+	0x00000004, 0x599c0209, 0x80000540, 0x0400001f,
+	0x599c0207, 0x80000540, 0x04000007, 0x800000cc,
+	0x599c080d, 0x80040400, 0x4803b100, 0x497bb102,
+	0x59d80101, 0x599c000d, 0x4803b100, 0x599c000e,
+	0x4803b101, 0x599c0207, 0x80000540, 0x04020002,
+	0x497bb102, 0x599c0a09, 0x82040540, 0x00400000,
+	0x59980822, 0x4803b103, 0x4a03b109, 0x00000004,
+	0x4a03b104, 0x10000001, 0x800409c0, 0x04020004,
+	0x4a033020, 0x00000001, 0x1c01f000, 0x4a033020,
+	0x00000002, 0x0401f7fd, 0x59980022, 0x4803c856,
+	0x80000540, 0x02000000, 0x000202de, 0x0401f017,
+	0x42034000, 0x0010b4a4, 0x59a1d81e, 0x80edd9c0,
+	0x02000800, 0x001005d8, 0x58ec0009, 0x48efc857,
+	0x49a3c857, 0x492fc857, 0x4803c857, 0x800001c0,
+	0x08020000, 0x0201f800, 0x001005d8, 0x5931d821,
+	0x58ef400b, 0x58ec0009, 0x800001c0, 0x08020000,
+	0x0201f800, 0x001005d8, 0x497a5800, 0x59980026,
+	0x80000540, 0x0402008c, 0x59d80105, 0x82000d00,
+	0x00018780, 0x040201da, 0x80000106, 0x82000500,
+	0x00000003, 0x0c01f001, 0x00104d0a, 0x00104d89,
+	0x00104d22, 0x00104d50, 0x592c0001, 0x492fc857,
+	0x492fb107, 0x80000d40, 0x04020007, 0x59940019,
+	0x80000540, 0x04022003, 0x59980023, 0x48032819,
+	0x1c01f000, 0x497a5801, 0x40065800, 0x592c0001,
+	0x496a5800, 0x815eb800, 0x412ed000, 0x80000d40,
+	0x040207f9, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0401f7ee, 0x492fc857, 0x492fb107,
+	0x592c0001, 0x80000d40, 0x04020012, 0x59da5908,
+	0x835c0480, 0x00000020, 0x0400101c, 0x0402b01a,
+	0x492fb007, 0x0400e7fa, 0x59d80105, 0x82000500,
+	0x00018780, 0x040201aa, 0x59940019, 0x80000540,
+	0x04022003, 0x59980023, 0x48032819, 0x1c01f000,
+	0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+	0x815eb800, 0x412ed000, 0x80000d40, 0x040207f9,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x0401f7e3, 0x0400f009, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0401f7e0, 0x492fa807, 0x0401f7de,
+	0x492fc857, 0x59d81108, 0x45681000, 0x400ad000,
+	0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540,
+	0x00001200, 0x48039000, 0x0402d00c, 0x592c0001,
+	0x492fc857, 0x492fb107, 0x80000d40, 0x0402001d,
+	0x59940019, 0x80000540, 0x04022003, 0x59980023,
+	0x48032819, 0x1c01f000, 0x59d80105, 0x82000500,
+	0x00018780, 0x04020172, 0x42000000, 0x0010b855,
+	0x0201f800, 0x0010aa47, 0x59980026, 0x59980828,
+	0x80000000, 0x48033026, 0x492fc857, 0x800409c0,
+	0x492f3028, 0x04000003, 0x492c0800, 0x0401f002,
+	0x492f3029, 0x592c0001, 0x80000d40, 0x040007e5,
+	0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+	0x815eb800, 0x412ed000, 0x80000d40, 0x040207f9,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x0401f7d8, 0x59980026, 0x59980828, 0x80000000,
+	0x48033026, 0x492fc857, 0x800409c0, 0x492f3028,
+	0x04000003, 0x492c0800, 0x0401f002, 0x492f3029,
+	0x592c0001, 0x80000d40, 0x04020027, 0x0402d00e,
+	0x59980029, 0x80025d40, 0x0400000f, 0x59980026,
+	0x80000040, 0x48033026, 0x04020002, 0x48033028,
+	0x592c0000, 0x48033029, 0x492fc857, 0x492fb107,
+	0x0400d7f4, 0x42000000, 0x0010b855, 0x0201f800,
+	0x0010aa47, 0x0402e00a, 0x59da5908, 0x496a5800,
+	0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x59d80105,
+	0x82000500, 0x00018780, 0x04020125, 0x59940019,
+	0x80000540, 0x04022003, 0x59980023, 0x48032819,
+	0x1c01f000, 0x497a5801, 0x40065800, 0x592c0001,
+	0x496a5800, 0x815eb800, 0x412ed000, 0x80000d40,
+	0x040207f9, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0401f7ce, 0x592c0204, 0x4803c856,
+	0x04000008, 0x42034000, 0x0010b4a4, 0x59a1d81e,
+	0x80edd9c0, 0x02000800, 0x001005d8, 0x0401f003,
+	0x5931d821, 0x58ef400b, 0x58ec0009, 0x800001c0,
+	0x08020000, 0x0201f800, 0x001005d8, 0x497a5801,
+	0x40065800, 0x592c0001, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x80000d40, 0x040207f9, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x1c01f000,
+	0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+	0x412ed000, 0x815eb800, 0x80000d40, 0x040207f9,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x0200e000, 0x000202fb, 0x0201f000, 0x00020302,
+	0x5998002b, 0x84000540, 0x4803302b, 0x0201f000,
+	0x0002035e, 0x42000000, 0x0010b855, 0x0201f800,
+	0x0010aa47, 0x492fc857, 0x59980026, 0x59980828,
+	0x80000000, 0x48033026, 0x800409c0, 0x492f3028,
+	0x04000003, 0x492c0800, 0x0401f002, 0x492f3029,
+	0x592c0001, 0x80000d40, 0x04020002, 0x1c01f000,
+	0x497a5801, 0x40065800, 0x592c0001, 0x496a5800,
+	0x412ed000, 0x815eb800, 0x80000d40, 0x040207f9,
+	0x59c80000, 0x82000540, 0x00001200, 0x48039000,
+	0x1c01f000, 0x59980026, 0x59980828, 0x80000000,
+	0x48033026, 0x492fc857, 0x800409c0, 0x492f3028,
+	0x04000003, 0x492c0800, 0x0401f002, 0x492f3029,
+	0x592c0001, 0x80000d40, 0x04020039, 0x0402d00e,
+	0x59980029, 0x80025d40, 0x0400000f, 0x59980026,
+	0x80000040, 0x48033026, 0x04020002, 0x48033028,
+	0x592c0000, 0x48033029, 0x492fc857, 0x492fb107,
+	0x0400d7f4, 0x42000000, 0x0010b855, 0x0201f800,
+	0x0010aa47, 0x0402e01d, 0x59da5908, 0x496a5800,
+	0x412ed000, 0x815eb800, 0x0400e7fc, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x04006018,
+	0x59d8010a, 0x59d8090a, 0x80040d80, 0x040207fd,
+	0x900001c0, 0x82000540, 0x00000013, 0x4803c011,
+	0x5998002b, 0x84000500, 0x4803302b, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000003,
+	0x4203e000, 0x30000001, 0x59d80105, 0x82000500,
+	0x00018780, 0x0402007e, 0x1c01f000, 0x5998002b,
+	0x84000540, 0x4803302b, 0x0401f7f8, 0x497a5801,
+	0x40065800, 0x592c0001, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x80000d40, 0x040207f9, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x0401f7bc,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x492fc857,
+	0x4943c857, 0x4807c857, 0x4a025a04, 0x00000103,
+	0x49425a06, 0x48065a08, 0x4a025c06, 0x0000ffff,
+	0x813261c0, 0x04000003, 0x59300402, 0x48025c06,
+	0x832c0400, 0x00000009, 0x04011000, 0x4803c840,
+	0x4a03c842, 0x0000000b, 0x04011000, 0x1c01f000,
+	0x4df00000, 0x4203e000, 0x50000000, 0x599cb817,
+	0x59940019, 0x80000540, 0x04002023, 0x0400000e,
+	0x59980022, 0x82000580, 0x00000005, 0x0400001e,
+	0x59a80069, 0x81640580, 0x0402001b, 0x8c5cbd08,
+	0x04000005, 0x59a8006a, 0x59a80866, 0x80040580,
+	0x04020015, 0x8c5cbd08, 0x04020030, 0x59d8090b,
+	0x59d8010a, 0x80040580, 0x0400000d, 0x0400600e,
+	0x4a03c011, 0x80400012, 0x4a03c020, 0x00008040,
+	0x59e00017, 0x8c000508, 0x04000003, 0x4a03c017,
+	0x00000002, 0x4203e000, 0x30000001, 0x4a032819,
+	0xffff0000, 0x04026835, 0x04006003, 0x8c5cbd08,
+	0x04020860, 0x59980029, 0x80025d40, 0x04000010,
+	0x59d80105, 0x82000500, 0x00018780, 0x04020020,
+	0x0402d00d, 0x59980026, 0x492fc857, 0x80000040,
+	0x48033026, 0x592c0000, 0x492fb107, 0x48033029,
+	0x04020003, 0x4803c856, 0x48033028, 0x5c03e000,
+	0x1c01f000, 0x42000000, 0x0010b855, 0x0201f800,
+	0x0010aa47, 0x0401f7fa, 0x59e0000f, 0x59e0080f,
+	0x80040580, 0x040207fd, 0x59e00010, 0x59e01010,
+	0x80081580, 0x040207fd, 0x40065000, 0x80041580,
+	0x040007c7, 0x040067dc, 0x0401f7ca, 0x4803c857,
+	0x485fc857, 0x8c00050e, 0x02020800, 0x001005d0,
+	0x4203e000, 0x50000000, 0x4200b800, 0x00008004,
+	0x0201f000, 0x001005dd, 0x5998002b, 0x8c000500,
+	0x04000013, 0x84000500, 0x4803302b, 0x59d8010a,
+	0x59d8090a, 0x80040580, 0x040207fd, 0x800408e0,
+	0x82040d40, 0x00000013, 0x4807c011, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000003,
+	0x4203e000, 0x30000001, 0x1c01f000, 0x0402e014,
+	0x59da5908, 0x496a5800, 0x412ed000, 0x815eb800,
+	0x0400e7fc, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x59d8090b, 0x59980024, 0x48073024,
+	0x80040480, 0x04020004, 0x59940019, 0x80000540,
+	0x04022003, 0x59980823, 0x48072819, 0x59d80105,
+	0x82000500, 0x00018780, 0x040207c9, 0x1c01f000,
+	0x59981025, 0x59e00010, 0x59e00810, 0x80041d80,
+	0x040207fd, 0x80080580, 0x04000013, 0x48073025,
+	0x59e0000f, 0x59e0100f, 0x80081d80, 0x040207fd,
+	0x81280580, 0x04000008, 0x400a5000, 0x40080000,
+	0x80040580, 0x04000003, 0x59980823, 0x48072819,
+	0x1c01f000, 0x59940019, 0x80000540, 0x040227f8,
+	0x0401f7fc, 0x59e0000f, 0x59e0100f, 0x80081d80,
+	0x040207fd, 0x81280580, 0x040007f6, 0x400a5000,
+	0x59940019, 0x80000540, 0x040027ed, 0x0401f7f1,
+	0x59a80017, 0x82000c80, 0x0000000a, 0x02021800,
+	0x001005d8, 0x0c01f809, 0x4a038805, 0x000000f0,
+	0x59c400a3, 0x82000500, 0x02870000, 0x02020800,
+	0x001005d8, 0x1c01f000, 0x00104fc5, 0x00104f51,
+	0x00104f6c, 0x00104f95, 0x00104fb8, 0x00104ff2,
+	0x00105004, 0x00104f6c, 0x00104fd6, 0x00104f50,
+	0x1c01f000, 0x4a038808, 0x00000004, 0x0401f8f9,
+	0x0201f800, 0x001053ab, 0x59c40805, 0x8c040d0e,
+	0x04020013, 0x8c040d0a, 0x0402000b, 0x8c040d0c,
+	0x04020006, 0x8c040d08, 0x0400000d, 0x4a035017,
+	0x00000003, 0x0401f00a, 0x4a035017, 0x00000000,
+	0x0401f007, 0x42000000, 0x0010b844, 0x0201f800,
+	0x0010aa47, 0x4a035017, 0x00000002, 0x1c01f000,
+	0x4a038808, 0x00000002, 0x0401f8de, 0x59c40805,
+	0x8c040d08, 0x04020021, 0x8c040d0c, 0x0402001c,
+	0x8c040d0e, 0x04020017, 0x82040500, 0x000000f0,
+	0x0402001c, 0x0201f800, 0x001053ab, 0x4a038808,
+	0x00000080, 0x59c40002, 0x8400050c, 0x48038802,
+	0x0401f9d9, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00109874, 0x5c027800, 0x4a038808,
+	0x00000080, 0x4a035017, 0x00000009, 0x0401f009,
+	0x4a035017, 0x00000001, 0x0401f006, 0x4a035017,
+	0x00000000, 0x0401f003, 0x4a035017, 0x00000003,
+	0x1c01f000, 0x0401f8b7, 0x4a038808, 0x00000080,
+	0x59c40805, 0x8c040d0a, 0x0402001b, 0x8c040d0c,
+	0x04020016, 0x8c040d0e, 0x04020011, 0x82040500,
+	0x000000f0, 0x04020016, 0x59c40002, 0x8400050c,
+	0x48038802, 0x0401f9b4, 0x4d3c0000, 0x42027800,
+	0x00000001, 0x0201f800, 0x00109874, 0x5c027800,
+	0x4a035017, 0x00000009, 0x0401f009, 0x4a035017,
+	0x00000001, 0x0401f006, 0x4a035017, 0x00000000,
+	0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000,
+	0x4a038808, 0x00000008, 0x59c40805, 0x8c040d0c,
+	0x04020006, 0x8c040d0e, 0x04000006, 0x4a035017,
+	0x00000001, 0x0401f003, 0x4a035017, 0x00000000,
+	0x1c01f000, 0x0401f8d3, 0x59c40805, 0x8c040d0c,
+	0x0402000d, 0x4c040000, 0x0401f882, 0x5c000800,
+	0x8c040d0a, 0x04020006, 0x8c040d0e, 0x04000006,
+	0x4a035017, 0x00000001, 0x0401f003, 0x4a035017,
+	0x00000002, 0x1c01f000, 0x4a038808, 0x00000008,
+	0x42001000, 0x00105058, 0x0201f800, 0x00106084,
+	0x59c40805, 0x8c040d0a, 0x0402000d, 0x8c040d08,
+	0x0402000b, 0x8c040d0c, 0x04020006, 0x8c040d0e,
+	0x0400000d, 0x4a035017, 0x00000001, 0x0401f00a,
+	0x4a035017, 0x00000000, 0x0401f007, 0x42000000,
+	0x0010b844, 0x0201f800, 0x0010aa47, 0x4a035017,
+	0x00000004, 0x1c01f000, 0x0401f8a6, 0x0401f859,
+	0x59c40805, 0x8c040d0a, 0x0402000b, 0x8c040d0c,
+	0x04020006, 0x8c040d0e, 0x04000009, 0x4a035017,
+	0x00000001, 0x0401f006, 0x4a035017, 0x00000000,
+	0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000,
+	0x4a038808, 0x00000004, 0x0401f846, 0x59c40805,
+	0x8c040d0a, 0x04020010, 0x8c040d08, 0x0402000b,
+	0x8c040d0c, 0x04020006, 0x8c040d0e, 0x0400000c,
+	0x4a035017, 0x00000001, 0x0401f009, 0x4a035017,
+	0x00000000, 0x0401f006, 0x4a035017, 0x00000003,
+	0x0401f003, 0x4a035017, 0x00000002, 0x1c01f000,
+	0x0401f91f, 0x02020800, 0x001005d8, 0x59a80805,
+	0x8c040d0c, 0x04000015, 0x84040d0c, 0x48075005,
+	0x4a038805, 0x00000010, 0x0201f800, 0x00101937,
+	0x59c40005, 0x8c000508, 0x04000008, 0x4a038808,
+	0x00000008, 0x4a035033, 0x00000001, 0x4202d800,
+	0x00000001, 0x0401f01a, 0x59c40006, 0x84000548,
+	0x48038806, 0x0401f016, 0x59a80017, 0x82000580,
+	0x00000001, 0x0400000c, 0x59a80017, 0x82000580,
+	0x00000005, 0x0402000c, 0x42000000, 0x0010b844,
+	0x0201f800, 0x0010aa47, 0x4a035017, 0x00000008,
+	0x0401f007, 0x42000000, 0x0010b844, 0x0201f800,
+	0x0010aa47, 0x4a035017, 0x00000004, 0x1c01f000,
+	0x4803c856, 0x4c040000, 0x4c080000, 0x42000800,
+	0x00000064, 0x42001000, 0x00105058, 0x0201f800,
+	0x00106079, 0x5c001000, 0x5c000800, 0x1c01f000,
+	0x4803c856, 0x4c040000, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x0201f800, 0x00106e21, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x0401ffba, 0x5c000800,
+	0x1c01f000, 0x4803c856, 0x4c040000, 0x4c080000,
+	0x0201f800, 0x00106c55, 0x4df00000, 0x0201f800,
+	0x00106e21, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x59c40006, 0x84000500, 0x48038806, 0x0201f800,
+	0x00106ede, 0x497b8880, 0x0201f800, 0x0010a9c0,
+	0x0201f800, 0x0010a9ce, 0x0201f800, 0x00101815,
+	0x4a03504c, 0x00000004, 0x4202d800, 0x00000004,
+	0x4a038805, 0x00000001, 0x42001000, 0x00105058,
+	0x0201f800, 0x00106084, 0x0201f800, 0x001006d4,
+	0x0401f8c1, 0x04000006, 0x42006000, 0xfeffffff,
+	0x41786800, 0x0201f800, 0x0010427d, 0x0201f800,
+	0x00100452, 0x42000000, 0x00000001, 0x0201f800,
+	0x00101590, 0x5c001000, 0x5c000800, 0x1c01f000,
+	0x59c40008, 0x8c000508, 0x04020007, 0x4a038808,
+	0x00000010, 0x4201d000, 0x00001388, 0x0201f800,
+	0x0010608e, 0x1c01f000, 0x4c040000, 0x59a80833,
+	0x82040580, 0x00000000, 0x0400000b, 0x82040580,
+	0x00000001, 0x0400000b, 0x82040580, 0x00000002,
+	0x0400000b, 0x82040580, 0x00000003, 0x0400000b,
+	0x0401f057, 0x4a035017, 0x00000000, 0x0401f009,
+	0x4a035017, 0x00000004, 0x0401f006, 0x4a035017,
+	0x00000001, 0x0401f003, 0x4a035017, 0x00000007,
+	0x497b8880, 0x4a038893, 0x00000001, 0x41780000,
+	0x0201f800, 0x00101606, 0x0201f800, 0x00106ede,
+	0x836c0d80, 0x00000004, 0x04000008, 0x59c40006,
+	0x82000500, 0xffffff0f, 0x82000540, 0x04000001,
+	0x48038806, 0x0401f007, 0x59c40006, 0x82000500,
+	0xffffff0f, 0x82000540, 0x04000000, 0x48038806,
+	0x0401f875, 0x04020005, 0x59c40806, 0x82040d00,
+	0xfbffff0f, 0x48078806, 0x4200b000, 0x00000005,
+	0x59c40005, 0x8c000534, 0x04020033, 0x42006000,
+	0xfc18ffff, 0x42006800, 0x01000000, 0x0201f800,
+	0x0010427d, 0x0201f800, 0x00101937, 0x59c408a4,
+	0x82040d00, 0x0000000f, 0x82040d80, 0x0000000c,
+	0x0400000a, 0x42006000, 0xfeffffff, 0x42006800,
+	0x02000000, 0x0201f800, 0x0010427d, 0x8058b040,
+	0x040207e8, 0x0401f8a1, 0x0401f853, 0x04000006,
+	0x42006000, 0xfeffffff, 0x41786800, 0x0201f800,
+	0x0010427d, 0x836c0d80, 0x00000004, 0x04000006,
+	0x59a8084d, 0x42001000, 0x00105065, 0x0201f800,
+	0x0010606e, 0x4a035033, 0x00000004, 0x0401fe31,
+	0x0401f841, 0x04020008, 0x59c408a4, 0x82040d00,
+	0x0000000f, 0x82040580, 0x0000000c, 0x02020800,
+	0x001005d8, 0x5c000800, 0x1c01f000, 0x4803c856,
+	0x4c000000, 0x0201f800, 0x0010609e, 0x4a035010,
+	0x00ffffff, 0x497b5032, 0x59a8002a, 0x82000500,
+	0xffff0000, 0x4803502a, 0x497b8880, 0x497b8893,
+	0x41780000, 0x0201f800, 0x00101606, 0x59c40001,
+	0x82000500, 0xfffffcff, 0x48038801, 0x42006000,
+	0xfc18ffff, 0x41786800, 0x0201f800, 0x0010427d,
+	0x4a038808, 0x00000000, 0x5c000000, 0x800001c0,
+	0x02020800, 0x0010411d, 0x4a038805, 0x040000f0,
+	0x59c40006, 0x82000500, 0xffffffcf, 0x82000540,
+	0x440000c1, 0x48038806, 0x1c01f000, 0x4c5c0000,
+	0x59a8b832, 0x825cbd80, 0x0000aaaa, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00,
+	0x00000030, 0x825cbd80, 0x00000000, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00,
+	0x00000030, 0x825cbd80, 0x00000010, 0x5c00b800,
+	0x1c01f000, 0x4c5c0000, 0x599cb818, 0x825cbd00,
+	0x00000030, 0x825cbd80, 0x00000020, 0x5c00b800,
+	0x1c01f000, 0x59a80005, 0x4803c857, 0x82000d00,
+	0x00000013, 0x04000025, 0x599c1017, 0x4d3c0000,
+	0x82000500, 0x00000011, 0x04000007, 0x42027800,
+	0x00000400, 0x0201f800, 0x00103b25, 0x0402000a,
+	0x0401f012, 0x42027800, 0x00000408, 0x0201f800,
+	0x00103b25, 0x0400000d, 0x42003000, 0x00000003,
+	0x0401f003, 0x42003000, 0x00000004, 0x42028000,
+	0x0000000e, 0x0201f800, 0x0010a449, 0x599c1017,
+	0x8c08150a, 0x04020007, 0x42028000, 0x00000004,
+	0x0201f800, 0x00101fe5, 0x80000580, 0x0401f80d,
+	0x5c027800, 0x0401f00a, 0x0201f800, 0x00103b25,
+	0x04000007, 0x42028000, 0x0000000f, 0x42003000,
+	0x00000001, 0x0201f800, 0x0010a449, 0x1c01f000,
+	0x59a80005, 0x04000004, 0x82000540, 0x00000010,
+	0x0401f003, 0x82000500, 0xffffffef, 0x48035005,
+	0x4803c857, 0x1c01f000, 0x4803c856, 0x4c580000,
+	0x42000000, 0x0010b8cb, 0x0201f800, 0x0010aa47,
+	0x42000800, 0x0010c0f1, 0x59c40003, 0x44000800,
+	0x59c40004, 0x48000801, 0x59c4000b, 0x48000802,
+	0x59c4008e, 0x48000803, 0x59c4008f, 0x48000804,
+	0x59c40090, 0x48000805, 0x59c40091, 0x48000806,
+	0x59c40092, 0x48000807, 0x59c40093, 0x48000808,
+	0x59c40099, 0x48000809, 0x59c4009e, 0x4800080a,
+	0x59c400aa, 0x4800080b, 0x59c400af, 0x4800080c,
+	0x59c400b2, 0x4800080d, 0x59c400b1, 0x4800080e,
+	0x82040c00, 0x0000000f, 0x41c41800, 0x4200b000,
+	0x00000030, 0x580c0050, 0x44000800, 0x80040800,
+	0x800c1800, 0x8058b040, 0x040207fb, 0x41c41800,
+	0x4200b000, 0x00000020, 0x580c0010, 0x44000800,
+	0x80040800, 0x800c1800, 0x8058b040, 0x040207fb,
+	0x497b8830, 0x4200b000, 0x00000040, 0x59c40031,
+	0x44000800, 0x80040800, 0x8058b040, 0x040207fc,
+	0x497b88ac, 0x4200b000, 0x00000010, 0x59c400ad,
+	0x44000800, 0x80040800, 0x8058b040, 0x040207fc,
+	0x59c41001, 0x4c080000, 0x8408150c, 0x480b8801,
+	0x4a0370e4, 0x00000300, 0x4a0370e5, 0xb0000000,
+	0x42000800, 0x00000800, 0x80040840, 0x02000800,
+	0x001005d8, 0x59b800e5, 0x8c000538, 0x040207fb,
+	0x4a0370e4, 0x00000200, 0x42006000, 0xffffffff,
+	0x42006800, 0x80000000, 0x0201f800, 0x0010427d,
+	0x4a038807, 0x00000001, 0x497b8807, 0x4a038808,
+	0x00000010, 0x42006000, 0xfcf8ffff, 0x42006800,
+	0x01000000, 0x0201f800, 0x0010427d, 0x5c001000,
+	0x480b8801, 0x42000800, 0x0010c0f1, 0x50040000,
+	0x48038803, 0x58040001, 0x48038804, 0x58040002,
+	0x4803880b, 0x58040003, 0x4803888e, 0x58040004,
+	0x4803888f, 0x58040005, 0x48038890, 0x58040006,
+	0x48038891, 0x58040007, 0x48038892, 0x58040008,
+	0x48038893, 0x58040009, 0x48038899, 0x5804000a,
+	0x4803889e, 0x5804000b, 0x480388aa, 0x5804000c,
+	0x480388af, 0x5804000d, 0x480388b2, 0x5804000e,
+	0x480388b1, 0x82040c00, 0x0000000f, 0x41c41800,
+	0x4200b000, 0x00000030, 0x50040000, 0x48001850,
+	0x80040800, 0x800c1800, 0x8058b040, 0x040207fb,
+	0x41c41800, 0x4200b000, 0x00000020, 0x50040000,
+	0x48001810, 0x80040800, 0x800c1800, 0x8058b040,
+	0x040207fb, 0x497b8830, 0x4200b000, 0x00000040,
+	0x50040000, 0x48038831, 0x80040800, 0x8058b040,
+	0x040207fc, 0x497b88ac, 0x4200b000, 0x00000010,
+	0x50040000, 0x480388ad, 0x80040800, 0x8058b040,
+	0x040207fc, 0x497b8880, 0x41780000, 0x0201f800,
+	0x00101606, 0x59c408a4, 0x82040d00, 0x0000000f,
+	0x82040580, 0x0000000c, 0x02020800, 0x001005d8,
+	0x4a038805, 0x04000000, 0x5c00b000, 0x1c01f000,
+	0x4803c856, 0x4c580000, 0x4ce80000, 0x42000000,
+	0x0010b845, 0x0201f800, 0x0010aa47, 0x59c41008,
+	0x4c080000, 0x82080500, 0xffffff7f, 0x48038808,
+	0x59c40004, 0x82000500, 0x00003e02, 0x04000005,
+	0x4201d000, 0x00000014, 0x0201f800, 0x0010608e,
+	0x59c40006, 0x82000500, 0xffffff0f, 0x48038806,
+	0x4a038805, 0x00000010, 0x4a038808, 0x00000004,
+	0x4200b000, 0x00000065, 0x59c40005, 0x8c000508,
+	0x04020012, 0x4201d000, 0x000003e8, 0x0201f800,
+	0x0010608e, 0x8058b040, 0x040207f8, 0x0201f800,
+	0x00106ede, 0x4a038808, 0x00000008, 0x4a035033,
+	0x00000001, 0x4202d800, 0x00000001, 0x82000540,
+	0x00000001, 0x0401f030, 0x0201f800, 0x00100ae0,
+	0x42000000, 0x0010b8a8, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00100ef4, 0x497b8880, 0x59a8002a,
+	0x82000500, 0x0000ffff, 0x4c000000, 0x0201f800,
+	0x00101606, 0x5c000000, 0x48038880, 0x4a038808,
+	0x00000000, 0x4200b000, 0x00000065, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x00101937, 0x42000800,
+	0x000000f0, 0x59c40005, 0x80040d00, 0x04000008,
+	0x4201d000, 0x000003e8, 0x0201f800, 0x0010608e,
+	0x8058b040, 0x040207f2, 0x0401f7d1, 0x59c40006,
+	0x82000540, 0x000000f0, 0x48038806, 0x59a8001e,
+	0x80000540, 0x04020002, 0x80000000, 0x48038893,
+	0x80000580, 0x5c001000, 0x4df00000, 0x0201f800,
+	0x0010195d, 0x5c03e000, 0x480b8808, 0x5c01d000,
+	0x5c00b000, 0x1c01f000, 0x4803c856, 0x4c580000,
+	0x4ce80000, 0x59c41008, 0x82080500, 0xffffff7f,
+	0x48038808, 0x4c080000, 0x59c40004, 0x82000500,
+	0x00003e02, 0x04000005, 0x4201d000, 0x00000014,
+	0x0201f800, 0x0010608e, 0x0201f800, 0x00100ae0,
+	0x42000000, 0x0010b8a9, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00100ef4, 0x4a038808, 0x00000002,
+	0x80000580, 0x48038880, 0x48038893, 0x0201f800,
+	0x00101606, 0x4200b000, 0x00000384, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x00101937, 0x42000800,
+	0x000000f0, 0x59c40005, 0x80040d00, 0x04000015,
+	0x82000500, 0x000000d0, 0x04020012, 0x4201d000,
+	0x00000067, 0x0201f800, 0x0010608e, 0x8058b040,
+	0x040207ef, 0x0201f800, 0x00106ede, 0x4a038808,
+	0x00000008, 0x4a035033, 0x00000001, 0x4202d800,
+	0x00000001, 0x82000540, 0x00000001, 0x0401f010,
+	0x497b8880, 0x59a8001e, 0x80000540, 0x04020002,
+	0x80000000, 0x48038893, 0x59a8002a, 0x82000500,
+	0x0000ffff, 0x4c000000, 0x0201f800, 0x00101606,
+	0x5c000000, 0x48038880, 0x80000580, 0x5c001000,
+	0x4df00000, 0x0201f800, 0x0010195d, 0x5c03e000,
+	0x480b8808, 0x5c01d000, 0x5c00b000, 0x1c01f000,
+	0x4803c856, 0x59c40004, 0x82000500, 0x00003e02,
+	0x0400000a, 0x0201f800, 0x00106ede, 0x4a038808,
+	0x00000008, 0x4a035033, 0x00000001, 0x4202d800,
+	0x00000001, 0x0401f052, 0x0201f800, 0x00100ae0,
+	0x42000000, 0x0010b8aa, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00100ef4, 0x59c40006, 0x84000508,
+	0x48038806, 0x4a038805, 0x00000010, 0x59a80805,
+	0x84040d4c, 0x48075005, 0x42000800, 0x00000064,
+	0x42001000, 0x00105058, 0x0201f800, 0x0010606e,
+	0x4a038808, 0x00000000, 0x497b8880, 0x4a038805,
+	0x000000f0, 0x0201f800, 0x00101937, 0x42000800,
+	0x000000f0, 0x59c40005, 0x80040d00, 0x0400000e,
+	0x82000500, 0x000000e0, 0x0402000b, 0x4201d000,
+	0x000003e8, 0x0201f800, 0x0010608e, 0x0201f800,
+	0x00105f48, 0x59940004, 0x80000540, 0x040207ec,
+	0x0401f023, 0x4c080000, 0x42001000, 0x00105065,
+	0x0201f800, 0x00105f90, 0x42001000, 0x00105058,
+	0x0201f800, 0x00106084, 0x5c001000, 0x497b8880,
+	0x59a8001e, 0x80000540, 0x04020002, 0x80000000,
+	0x48038893, 0x59a8002a, 0x82000500, 0x0000ffff,
+	0x4c000000, 0x0201f800, 0x00101606, 0x5c000000,
+	0x48038880, 0x59a80805, 0x84040d0c, 0x48075005,
+	0x59c40006, 0x84000548, 0x48038806, 0x0201f800,
+	0x0010195d, 0x4a038808, 0x00000080, 0x1c01f000,
+	0x4803c856, 0x4d400000, 0x4d3c0000, 0x0201f800,
+	0x00106ede, 0x0201f800, 0x0010ab33, 0x04020025,
+	0x599c1017, 0x59a80805, 0x8c040d00, 0x0402000c,
+	0x8c08151a, 0x0400001f, 0x84040d42, 0x48075005,
+	0x42028000, 0x00000004, 0x42027800, 0x0000000c,
+	0x8c081508, 0x04020008, 0x0401f012, 0x42028000,
+	0x00000004, 0x42027800, 0x00000004, 0x8c081508,
+	0x0400000c, 0x4d400000, 0x42028000, 0x0000000e,
+	0x42028800, 0x0000ffff, 0x0201f800, 0x0010a446,
+	0x5c028000, 0x599c0817, 0x8c040d0a, 0x04020005,
+	0x4943c857, 0x493fc857, 0x0201f800, 0x00101fe5,
+	0x497b8880, 0x4202d800, 0x00000001, 0x0401fcfb,
+	0x5c027800, 0x5c028000, 0x1c01f000, 0x0201f800,
+	0x00100ae0, 0x42000000, 0x0010b8ab, 0x0201f800,
+	0x0010aa47, 0x0201f800, 0x00100ef4, 0x42000000,
+	0x00000001, 0x0201f800, 0x00101606, 0x4a038880,
+	0x00000001, 0x0201f000, 0x0010195d, 0x4202e000,
+	0x00000000, 0x4a033015, 0x00000001, 0x497b301d,
+	0x497b3006, 0x4a03b004, 0x60000001, 0x59d80005,
+	0x4a03b004, 0x90000001, 0x4a03a804, 0x60000001,
+	0x59d40005, 0x4a03a804, 0x90000001, 0x0201f000,
+	0x00105983, 0x4a03c825, 0x00000004, 0x4a03c827,
+	0x00000004, 0x599c0409, 0x80000d40, 0x04000020,
+	0x599c0407, 0x80000540, 0x04000007, 0x800000cc,
+	0x599c100b, 0x80080400, 0x4803b000, 0x497bb002,
+	0x59d80001, 0x599c000b, 0x4803b000, 0x599c000c,
+	0x4803b001, 0x599c0407, 0x80000540, 0x04020002,
+	0x497bb002, 0x599c0c09, 0x82040540, 0x00400000,
+	0x4803b003, 0x4a03b009, 0x00000004, 0x4a03b004,
+	0x10000001, 0x59e00803, 0x82040d00, 0xfffffeff,
+	0x82040d40, 0x00008000, 0x4807c003, 0x599c040a,
+	0x80000540, 0x04000020, 0x599c0408, 0x80000540,
+	0x04000007, 0x800000cc, 0x599c100f, 0x80080400,
+	0x4803a800, 0x497ba802, 0x59d40001, 0x599c000f,
+	0x4803a800, 0x599c0010, 0x4803a801, 0x599c0408,
+	0x80000540, 0x04020002, 0x497ba802, 0x599c0c0a,
+	0x82040540, 0x00400000, 0x4803a803, 0x4a03a809,
+	0x00000004, 0x4a03a804, 0x10000001, 0x59e00803,
+	0x82040d00, 0xfffffbff, 0x82040d40, 0x00008000,
+	0x4807c003, 0x800409c0, 0x04000007, 0x4202e000,
+	0x00000001, 0x0200b800, 0x00020551, 0x0200f000,
+	0x00020566, 0x1c01f000, 0x0201f800, 0x001005d8,
+	0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000,
+	0x59981005, 0x800811c0, 0x0400001e, 0x58080005,
+	0x82000d00, 0x43018780, 0x02020000, 0x00105846,
+	0x8c000508, 0x04000015, 0x580a5808, 0x592c0204,
+	0x497a5800, 0x497a5801, 0x82000500, 0x000000ff,
+	0x82000c80, 0x0000004b, 0x0402100b, 0x0c01f80f,
+	0x5c03e000, 0x83700580, 0x00000003, 0x040007e6,
+	0x0200f800, 0x00020566, 0x0200b000, 0x00020551,
+	0x1c01f000, 0x0401f850, 0x5c03e000, 0x0401f7f9,
+	0x0401f8de, 0x0401f7fd, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x001054a1, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105519, 0x00105491, 0x00105491, 0x001054a1,
+	0x001054a1, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x492fc857, 0x42000000, 0x0010b85e,
+	0x0201f800, 0x0010aa47, 0x42000000, 0x00000400,
+	0x0401f019, 0x492fc857, 0x42000000, 0x0010b85d,
+	0x0201f800, 0x0010aa47, 0x42000000, 0x00001000,
+	0x0401f011, 0x492fc857, 0x42000000, 0x0010b85c,
+	0x0201f800, 0x0010aa47, 0x42000000, 0x00002000,
+	0x0401f009, 0x492fc857, 0x42000000, 0x0010b85f,
+	0x0201f800, 0x0010aa47, 0x42000000, 0x00000800,
+	0x0401f001, 0x4803c857, 0x4202e000, 0x00000001,
+	0x592c0c04, 0x82040d00, 0xffff80ff, 0x80040540,
+	0x48025c04, 0x0201f000, 0x000202da, 0x592c0204,
+	0x492fc857, 0x80000110, 0x040007db, 0x80000040,
+	0x04000025, 0x48033002, 0x492f3003, 0x492f3004,
+	0x4a033008, 0x001054e5, 0x4202e000, 0x00000003,
+	0x1c01f000, 0x592c0204, 0x492fc857, 0x80000110,
+	0x040007cd, 0x80000040, 0x04000033, 0x48033002,
+	0x492f3003, 0x492f3004, 0x4a033008, 0x00105501,
+	0x4202e000, 0x00000003, 0x1c01f000, 0x0201f800,
+	0x0010ab33, 0x02020000, 0x000204d9, 0x42028000,
+	0x00000028, 0x41780800, 0x417a6000, 0x0201f800,
+	0x00104e70, 0x0201f800, 0x001091c6, 0x0201f000,
+	0x000202da, 0x592c0a0a, 0x8c040d02, 0x04020016,
+	0x59a80021, 0x492fc857, 0x80000540, 0x0402000f,
+	0x592c0207, 0x80000540, 0x04000005, 0x0201f800,
+	0x00104326, 0x04020004, 0x1c01f000, 0x42000000,
+	0x00000000, 0x592c0a06, 0x48065c06, 0x48025a06,
+	0x0201f000, 0x000202da, 0x42000000, 0x00000028,
+	0x0401f7f9, 0x42000800, 0x00000009, 0x0201f000,
+	0x0010665b, 0x592c0208, 0x492fc857, 0x82000c80,
+	0x0000199a, 0x040217a4, 0x592c0408, 0x80000540,
+	0x040207a1, 0x59a80821, 0x800409c0, 0x04020009,
+	0x592c0207, 0x80000540, 0x0400079b, 0x497a5a06,
+	0x0201f800, 0x00104385, 0x04020004, 0x1c01f000,
+	0x42000000, 0x00000028, 0x48025a06, 0x0201f000,
+	0x000202da, 0x59980804, 0x59980002, 0x48065800,
+	0x492c0801, 0x492f3004, 0x80000040, 0x48033002,
+	0x04000002, 0x1c01f000, 0x599a5803, 0x59980008,
+	0x4202e000, 0x00000001, 0x0801f000, 0x592e8a06,
+	0x592c0406, 0x4803c856, 0x82000500, 0x000000ff,
+	0x4200b800, 0x00000001, 0x82000d80, 0x00000001,
+	0x04000015, 0x417a8800, 0x4200b800, 0x000007f0,
+	0x82000d80, 0x00000002, 0x0400000f, 0x80000540,
+	0x02020000, 0x000202da, 0x592e8a06, 0x0201f800,
+	0x00020245, 0x02020000, 0x000202da, 0x592e9008,
+	0x592e9809, 0x0201f800, 0x00104713, 0x0201f000,
+	0x000202da, 0x59a80805, 0x84040d00, 0x48075005,
+	0x0201f800, 0x00020245, 0x02000800, 0x0010482c,
+	0x81468800, 0x805cb840, 0x040207fa, 0x0201f000,
+	0x000202da, 0x592c0a08, 0x4807c857, 0x82040580,
+	0x0000000e, 0x04000045, 0x82040580, 0x00000046,
+	0x04000046, 0x82040580, 0x00000045, 0x04000020,
+	0x82040580, 0x00000029, 0x04000010, 0x82040580,
+	0x0000002a, 0x04000009, 0x82040580, 0x0000000f,
+	0x040001fc, 0x82040580, 0x0000002e, 0x040001f9,
+	0x4807c856, 0x0401f1f2, 0x59a80805, 0x84040d04,
+	0x48075005, 0x0401f1f3, 0x592e8a06, 0x0201f800,
+	0x00020245, 0x040201ef, 0x59340200, 0x84000518,
+	0x48026a00, 0x592e6009, 0x4933c857, 0x83300580,
+	0xffffffff, 0x0402002a, 0x0401f1e6, 0x592c1407,
+	0x480bc857, 0x0201f800, 0x00109410, 0x411e6000,
+	0x04020003, 0x4803c856, 0x0401f1d9, 0x592e3809,
+	0x591c1414, 0x84081516, 0x84081554, 0x480a3c14,
+	0x4a026403, 0x0000003a, 0x592c040b, 0x80000540,
+	0x04000007, 0x4a026403, 0x0000003b, 0x592c020c,
+	0x4802641a, 0x592c040c, 0x4802621a, 0x4a026203,
+	0x00000001, 0x42000800, 0x80000040, 0x0201f800,
+	0x00020721, 0x0401f1c7, 0x59a80068, 0x84000510,
+	0x48035068, 0x0401f1c3, 0x592c1207, 0x8c081500,
+	0x040201c0, 0x592e8a06, 0x592e6009, 0x0201f800,
+	0x0010941a, 0x04020003, 0x4803c856, 0x0401f1b4,
+	0x59300c06, 0x82040580, 0x00000004, 0x04000003,
+	0x4803c856, 0x0401f1ae, 0x59300a03, 0x82040580,
+	0x00000007, 0x04000003, 0x4803c856, 0x0401f1a8,
+	0x59300c03, 0x82040580, 0x00000001, 0x04000021,
+	0x82040580, 0x00000003, 0x04000016, 0x82040580,
+	0x00000006, 0x04000020, 0x82040580, 0x00000008,
+	0x04000015, 0x82040580, 0x0000000a, 0x0400000a,
+	0x82040580, 0x0000000c, 0x04000004, 0x82040580,
+	0x0000002e, 0x04020018, 0x42000800, 0x00000009,
+	0x0401f013, 0x42000800, 0x00000005, 0x0401f010,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x4a026406,
+	0x00000001, 0x42000800, 0x00000003, 0x0401f008,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x4a026406,
+	0x00000001, 0x42000800, 0x0000000b, 0x0201f800,
+	0x00104571, 0x4a026203, 0x00000001, 0x0201f800,
+	0x0010672b, 0x0401f17b, 0x40000800, 0x58040000,
+	0x80000540, 0x040207fd, 0x492c0800, 0x1c01f000,
+	0x492fc857, 0x59300c06, 0x82040580, 0x00000006,
+	0x04020094, 0x0201f800, 0x001049e7, 0x04020005,
+	0x59340200, 0x8c00051a, 0x02000000, 0x00020533,
+	0x59340200, 0x8c00050e, 0x0400008a, 0x59300203,
+	0x42027800, 0x00000001, 0x82000580, 0x00000007,
+	0x02020000, 0x00020533, 0x4a026203, 0x00000002,
+	0x0201f000, 0x00020533, 0x42028000, 0x00000002,
+	0x4a026206, 0x00000014, 0x4d2c0000, 0x0201f800,
+	0x0010a1d1, 0x5c025800, 0x59300c06, 0x4807c857,
+	0x82040580, 0x00000007, 0x04020063, 0x492fc857,
+	0x4a025a06, 0x00000001, 0x0201f000, 0x000202da,
+	0x592c240a, 0x492fc857, 0x4813c857, 0x8c10251c,
+	0x04020016, 0x8c10251a, 0x04000003, 0x8c10250a,
+	0x04000069, 0x59340a00, 0x8c040d0e, 0x04000003,
+	0x8c10251e, 0x04000064, 0x0201f800, 0x0002075a,
+	0x0400006b, 0x592c240a, 0x49366009, 0x49325809,
+	0x4a026406, 0x00000006, 0x4a026203, 0x00000007,
+	0x0201f000, 0x0002052f, 0x592c0a0c, 0x5934000f,
+	0x41784000, 0x80001540, 0x0400006d, 0x58080204,
+	0x82000500, 0x000000ff, 0x82000580, 0x00000012,
+	0x04020004, 0x5808020c, 0x80040580, 0x04000004,
+	0x58080000, 0x40084000, 0x0401f7f3, 0x58080000,
+	0x49781000, 0x802041c0, 0x04000006, 0x48004000,
+	0x80000540, 0x04020007, 0x48226810, 0x0401f005,
+	0x4802680f, 0x80000540, 0x04020002, 0x497a6810,
+	0x4d2c0000, 0x400a5800, 0x4a025a06, 0x00000002,
+	0x0201f800, 0x000202da, 0x5c025800, 0x0401f7bc,
+	0x592c040a, 0x8c00051c, 0x04000016, 0x592c0206,
+	0x82000580, 0x0000ffff, 0x04020012, 0x592e6009,
+	0x83300580, 0xffffffff, 0x040007b1, 0x83300480,
+	0x0010d1c0, 0x04001010, 0x59a8000b, 0x81300480,
+	0x0402100d, 0x59300008, 0x800001c0, 0x04020005,
+	0x59300203, 0x82000580, 0x00000007, 0x04000797,
+	0x492fc857, 0x4a025a06, 0x00000029, 0x0201f000,
+	0x000202da, 0x492fc857, 0x4a025a06, 0x00000008,
+	0x0201f000, 0x000202da, 0x492fc857, 0x4a025a06,
+	0x00000045, 0x0201f000, 0x000202da, 0x492fc857,
+	0x4a025a06, 0x0000002a, 0x0201f000, 0x000202da,
+	0x492fc857, 0x4a025a06, 0x00000028, 0x0201f000,
+	0x000202da, 0x492fc857, 0x4a025a06, 0x00000006,
+	0x0201f000, 0x000202da, 0x492fc857, 0x4a025a06,
+	0x0000000e, 0x0201f000, 0x000202da, 0x59340010,
+	0x492e6810, 0x492fc857, 0x80000d40, 0x04000003,
+	0x492c0800, 0x1c01f000, 0x5934040b, 0x492e680f,
+	0x492fc857, 0x4803c857, 0x80000540, 0x04020003,
+	0x4a026a03, 0x00000001, 0x1c01f000, 0x59a8000e,
+	0x81640480, 0x0402176e, 0x42026000, 0x0010d1c0,
+	0x59300009, 0x81340580, 0x04020004, 0x59300202,
+	0x80040580, 0x04000759, 0x83326400, 0x00000024,
+	0x41580000, 0x81300480, 0x040017f6, 0x0401f760,
+	0x492fc857, 0x592c0407, 0x82000c80, 0x0000199a,
+	0x040215f1, 0x592c0204, 0x80000112, 0x040205de,
+	0x592e8a06, 0x0201f800, 0x00020245, 0x04020059,
+	0x0201f800, 0x001049e7, 0x04020059, 0x592e780a,
+	0x493fc857, 0x8d3e7d3e, 0x04020007, 0x59a80021,
+	0x80000540, 0x0402004f, 0x0201f800, 0x00104838,
+	0x040005dd, 0x833c1d00, 0x0000001f, 0x040005da,
+	0x592c0207, 0x82000c80, 0x00001000, 0x040215d6,
+	0x800000c2, 0x800008c4, 0x8005d400, 0x592e9008,
+	0x592e9809, 0x5934080d, 0x800409c0, 0x0402002e,
+	0x833c1d00, 0x0000001f, 0x81780040, 0x80000000,
+	0x800c1902, 0x040217fe, 0x040205c7, 0x0c01f001,
+	0x001056e9, 0x001056ec, 0x001056f9, 0x001056fc,
+	0x001056ff, 0x0201f800, 0x0010903e, 0x0401f01a,
+	0x0201f800, 0x0010480b, 0x04000027, 0x80e9d1c0,
+	0x02020800, 0x00105fae, 0x42028000, 0x00000005,
+	0x417a9000, 0x417a9800, 0x0201f800, 0x0010904e,
+	0x0401f00d, 0x42027000, 0x0000004d, 0x0401f006,
+	0x42027000, 0x0000004e, 0x0401f003, 0x42027000,
+	0x00000052, 0x0201f800, 0x001046c9, 0x02020800,
+	0x0010907e, 0x04000010, 0x8d3e7d3e, 0x04020017,
+	0x1c01f000, 0x58040002, 0x80000540, 0x04020007,
+	0x4d3c0000, 0x40067800, 0x0201f800, 0x001047eb,
+	0x5c027800, 0x040207cb, 0x4a025a06, 0x00000030,
+	0x0401f00d, 0x4a025a06, 0x0000002c, 0x0401f00a,
+	0x4a025a06, 0x00000028, 0x0401f007, 0x4a025a06,
+	0x00000029, 0x0401f004, 0x497a5c09, 0x4a025a06,
+	0x00000000, 0x4a025a04, 0x00000103, 0x0201f000,
+	0x000202da, 0x492fc857, 0x592c0204, 0x80000110,
+	0x80000040, 0x04000002, 0x0401f56f, 0x592c0207,
+	0x82000500, 0x000003ff, 0x48025a07, 0x8c000506,
+	0x04000004, 0x82000500, 0x00000070, 0x04020004,
+	0x59a80821, 0x800409c0, 0x04020018, 0x4a025a06,
+	0x0000dead, 0x592c0408, 0x82000500, 0x0000f0ff,
+	0x48025c08, 0x0201f800, 0x001043b4, 0x04020002,
+	0x1c01f000, 0x49425a06, 0x8058b1c0, 0x04000009,
+	0x0201f800, 0x0010955f, 0x0401f80f, 0x44042800,
+	0x82580580, 0x00000002, 0x04020002, 0x48082801,
+	0x0201f000, 0x000202da, 0x42028000, 0x00000031,
+	0x42000800, 0x00000001, 0x4200b000, 0x00000001,
+	0x0401f7ed, 0x592c0408, 0x80000118, 0x832c2c00,
+	0x00000009, 0x80142c00, 0x1c01f000, 0x492fc857,
+	0x4a025a08, 0x00000006, 0x0201f000, 0x000202da,
+	0x492fc857, 0x4a025a08, 0x00000001, 0x0201f000,
+	0x000202da, 0x492fc857, 0x592c040a, 0x82000500,
+	0x00000003, 0x04000020, 0x0201f800, 0x0002075a,
+	0x04000021, 0x592c0204, 0x492e6008, 0x82000500,
+	0x000000ff, 0x82000580, 0x00000045, 0x0400000e,
+	0x592c000b, 0x0201f800, 0x00105c9a, 0x02000800,
+	0x00020245, 0x04020018, 0x42027000, 0x00000041,
+	0x49366009, 0x4a026406, 0x00000001, 0x0201f000,
+	0x000207a1, 0x59300015, 0x8400055e, 0x48026015,
+	0x42026800, 0x0010b524, 0x42027000, 0x00000040,
+	0x0401f7f4, 0x4a025a06, 0x00000101, 0x0201f000,
+	0x000202da, 0x4a025a06, 0x0000002c, 0x0201f000,
+	0x000202da, 0x4a025a06, 0x00000028, 0x0201f800,
+	0x000202da, 0x0201f000, 0x0002077d, 0x492fc857,
+	0x0201f800, 0x001062e1, 0x0400000b, 0x592c0204,
+	0x80000110, 0x80000040, 0x040204fb, 0x592c0c06,
+	0x800409c0, 0x04000009, 0x42000000, 0x00000102,
+	0x0401f003, 0x42000000, 0x00000104, 0x48025a06,
+	0x0201f000, 0x000202da, 0x592c0c07, 0x800409c0,
+	0x04000024, 0x82040480, 0x00000005, 0x04021021,
+	0x4c040000, 0x80040800, 0x0201f800, 0x00106306,
+	0x5c001000, 0x04020018, 0x832c0400, 0x00000008,
+	0x4000a000, 0x0201f800, 0x0010632f, 0x04020012,
+	0x592c1207, 0x82cc0580, 0x0010b50e, 0x04020009,
+	0x58c80c0b, 0x84040d00, 0x84040d02, 0x8c081500,
+	0x04000002, 0x84040d5e, 0x4805940b, 0x0401f001,
+	0x42000000, 0x00000000, 0x48025a06, 0x0201f000,
+	0x000202da, 0x42000000, 0x00000103, 0x0401f7fb,
+	0x42000000, 0x00000102, 0x0401f7f8, 0x492fc857,
+	0x592e7c06, 0x833c0500, 0xfffffffe, 0x04020043,
+	0x592c4007, 0x42026000, 0x0010d1c0, 0x41581800,
+	0x400c0000, 0x81300480, 0x04021023, 0x59300203,
+	0x82000580, 0x00000000, 0x04000007, 0x59300008,
+	0x80000d40, 0x04000004, 0x58040005, 0x80200580,
+	0x04000004, 0x83326400, 0x00000024, 0x0401f7f1,
+	0x58040204, 0x82000500, 0x000000ff, 0x82000d80,
+	0x00000053, 0x04000007, 0x82000d80, 0x00000048,
+	0x04000004, 0x82000580, 0x00000018, 0x04020023,
+	0x4d2c0000, 0x0201f800, 0x00108be3, 0x5c025800,
+	0x0400001e, 0x4a025a06, 0x00000000, 0x0201f000,
+	0x000202da, 0x592e8a06, 0x83440480, 0x000007f0,
+	0x04021016, 0x83440400, 0x0010ac00, 0x50000000,
+	0x80026d40, 0x04000011, 0x4d2c0000, 0x0201f800,
+	0x001047cb, 0x0400000c, 0x42028000, 0x00000005,
+	0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800,
+	0x001091cc, 0x0201f800, 0x000202da, 0x5c025800,
+	0x0401f7e5, 0x5c025800, 0x4a025a06, 0x00000031,
+	0x0201f000, 0x000202da, 0x492fc857, 0x4d2c0000,
+	0x0201f800, 0x001007e4, 0x04000016, 0x492fc857,
+	0x412f4000, 0x0201f800, 0x001007e4, 0x0400000e,
+	0x492fc857, 0x412dd800, 0x0201f800, 0x00103b28,
+	0x0201f800, 0x00103b32, 0x49a1d80b, 0x5c025800,
+	0x492dd80a, 0x0201f800, 0x00102214, 0x0201f000,
+	0x00102233, 0x41a25800, 0x0201f800, 0x001007f4,
+	0x5c025800, 0x4a025a06, 0x00004005, 0x4a025c06,
+	0x00000002, 0x0201f000, 0x000202da, 0x4807c857,
+	0x485fc857, 0x4200b800, 0x00000001, 0x5c000800,
+	0x4c5c0000, 0x0401f005, 0x4807c857, 0x485fc857,
+	0x5c000800, 0x4d780000, 0x4803c857, 0x492fc857,
+	0x8c00050e, 0x02020800, 0x001005d0, 0x4203e000,
+	0x50000000, 0x4200b800, 0x00008003, 0x0201f000,
+	0x001005dd, 0x592c0204, 0x80000110, 0x80000040,
+	0x04020441, 0x0201f800, 0x00104a34, 0x04020002,
+	0x1c01f000, 0x49425a06, 0x4806580d, 0x480a580e,
+	0x4943c857, 0x4807c857, 0x480bc857, 0x0201f000,
+	0x000202da, 0x592c0204, 0x80000110, 0x80000040,
+	0x04020431, 0x0201f800, 0x00104b8b, 0x04020002,
+	0x1c01f000, 0x49425a06, 0x48065811, 0x480a5812,
+	0x0201f000, 0x000202da, 0x592c0204, 0x80000110,
+	0x04000425, 0x80000040, 0x0402000c, 0x4202e000,
+	0x00000001, 0x592c020a, 0x8c000504, 0x02000000,
+	0x000204d0, 0x592c0207, 0x82000c80, 0x00001001,
+	0x04021429, 0x0401f009, 0x4202e000, 0x00000003,
+	0x48033002, 0x492f3003, 0x492f3004, 0x4a033008,
+	0x000204d0, 0x1c01f000, 0x4202e000, 0x00000002,
+	0x42000000, 0x0010beda, 0x50007000, 0x492c700b,
+	0x4978700e, 0x4978700c, 0x592c0011, 0x592c0812,
+	0x48007007, 0x48047008, 0x592c1013, 0x82080500,
+	0xffff0000, 0x04000003, 0x0201f800, 0x001005d8,
+	0x4978700d, 0x82080480, 0x00000180, 0x4803c857,
+	0x04001007, 0x4800700f, 0x4a007005, 0x00000180,
+	0x4a007004, 0x00000060, 0x0401f005, 0x4978700f,
+	0x48087005, 0x80081104, 0x48087004, 0x5838000a,
+	0x48007003, 0x40381000, 0x0201f000, 0x00100858,
+	0x0201f800, 0x001007d3, 0x04000003, 0x59980007,
+	0x0801f000, 0x1c01f000, 0x40307000, 0x5838000b,
+	0x80025d40, 0x0400001b, 0x58380002, 0x82000580,
+	0x00000100, 0x0400001d, 0x4c380000, 0x592c0204,
+	0x82000500, 0x000000ff, 0x82000580, 0x00000012,
+	0x0400000b, 0x592c0208, 0x8400054e, 0x48025a08,
+	0x4a025a06, 0x00000002, 0x4a025a04, 0x00000103,
+	0x0201f800, 0x000202c1, 0x0401f005, 0x4a025a06,
+	0x00000010, 0x0201f800, 0x000202da, 0x5c007000,
+	0x4202e000, 0x00000001, 0x4a007002, 0x00000100,
+	0x49787010, 0x1c01f000, 0x58380004, 0x82000480,
+	0x00000003, 0x04000087, 0x58380010, 0x8c000500,
+	0x04020019, 0x4200b000, 0x00000003, 0x832cac00,
+	0x00000011, 0x5838000a, 0x5838100d, 0x8008a400,
+	0x4c380000, 0x0201f800, 0x0010ab17, 0x5c007000,
+	0x5838000d, 0x82000400, 0x00000003, 0x4800700d,
+	0x4a007010, 0x00000001, 0x58380004, 0x82000480,
+	0x00000003, 0x48007004, 0x82000580, 0x00000003,
+	0x0400006c, 0x5838000e, 0x80001d40, 0x04020020,
+	0x4c380000, 0x0201f800, 0x001007d3, 0x5c007000,
+	0x04000010, 0x4a025a04, 0x0000010a, 0x42001800,
+	0x00000005, 0x480c700e, 0x5838000c, 0x80000540,
+	0x04020002, 0x5838000b, 0x40000800, 0x492c0801,
+	0x492c700c, 0x42000800, 0x0000000f, 0x0401f011,
+	0x4202e000, 0x00000008, 0x4a033007, 0x00105915,
+	0x1c01f000, 0x4202e000, 0x00000002, 0x42000000,
+	0x0010beda, 0x50007000, 0x0401f7e7, 0x583a580c,
+	0x400c0000, 0x42000800, 0x00000014, 0x80040c80,
+	0x58381004, 0x5838000f, 0x41783000, 0x80000540,
+	0x04020005, 0x84183540, 0x82081480, 0x00000003,
+	0x0400003c, 0x40080000, 0x80040480, 0x04001002,
+	0x40080800, 0x4004b000, 0x412c0000, 0x800c0400,
+	0x4000a800, 0x5838000a, 0x5838100d, 0x8008a400,
+	0x4c080000, 0x4c040000, 0x4c0c0000, 0x4c380000,
+	0x0201f800, 0x0010ab17, 0x5c007000, 0x5c001800,
+	0x5c000800, 0x40040000, 0x58381004, 0x80080480,
+	0x48007004, 0x82000580, 0x00000003, 0x04000002,
+	0x84183500, 0x5c000000, 0x80041400, 0x82080480,
+	0x00000060, 0x04020003, 0x84183542, 0x41781000,
+	0x400c0000, 0x80041c00, 0x820c0480, 0x00000014,
+	0x04020003, 0x84183544, 0x40001800, 0x40080800,
+	0x4804700d, 0x480c700e, 0x40180000, 0x0c01f001,
+	0x00105960, 0x00105964, 0x00105962, 0x00105960,
+	0x001058fc, 0x00105964, 0x00105962, 0x00105960,
+	0x0201f800, 0x001005d8, 0x5838100f, 0x0401f739,
+	0x5838080d, 0x82040400, 0x00000002, 0x5838100a,
+	0x80080400, 0x50001000, 0x800811c0, 0x0402000f,
+	0x4202e000, 0x00000001, 0x583a580b, 0x4978700b,
+	0x49787010, 0x592c0204, 0x82000500, 0x000000ff,
+	0x82000580, 0x00000012, 0x02000000, 0x00020507,
+	0x0201f000, 0x000204d0, 0x5838000a, 0x80040c00,
+	0x82381c00, 0x00000007, 0x54041800, 0x80040800,
+	0x800c1800, 0x54041800, 0x0401f71a, 0x0201f800,
+	0x001007d3, 0x02000800, 0x001005d8, 0x4a02580a,
+	0x0010be79, 0x42000800, 0x0010beda, 0x452c0800,
+	0x497a580b, 0x497a580c, 0x497a580d, 0x497a580e,
+	0x497a580f, 0x4a025809, 0x001058b6, 0x497a5810,
+	0x4a025802, 0x00000100, 0x4a025801, 0x00000001,
+	0x1c01f000, 0x59c80007, 0x8c000502, 0x04000070,
+	0x835c2c80, 0x00000005, 0x02001000, 0x00105f23,
+	0x59c82817, 0x497b9005, 0x82140500, 0x00e00000,
+	0x0402004f, 0x82140500, 0x000003ff, 0x82001c00,
+	0x00000006, 0x41cc2000, 0x42003000, 0x00006080,
+	0x820c0480, 0x00000040, 0x04001006, 0x42001000,
+	0x00000040, 0x820c1c80, 0x00000040, 0x0401f003,
+	0x400c1000, 0x41781800, 0x54182000, 0x80102000,
+	0x80183000, 0x80081040, 0x040207fc, 0x800c19c0,
+	0x04000005, 0x59c80005, 0x80000000, 0x48039005,
+	0x0401f7ea, 0x82140500, 0x01f60000, 0x04020029,
+	0x82140500, 0x0000f000, 0x0400000b, 0x82000c80,
+	0x00002000, 0x0402100f, 0x82140500, 0x0e000000,
+	0x80000132, 0x0c01f840, 0x4a039005, 0x00000140,
+	0x1c01f000, 0x59cc0400, 0x82000500, 0x0000ff00,
+	0x82000580, 0x00008100, 0x040007f4, 0x0401f01c,
+	0x4817c857, 0x82140500, 0x000003ff, 0x04020007,
+	0x59cc0400, 0x82000500, 0x0000ff00, 0x82000580,
+	0x00008100, 0x04020012, 0x42000000, 0x0010b8bd,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x00105dfa,
+	0x4803c856, 0x4a039005, 0x00000140, 0x0401f020,
+	0x4817c857, 0x82140500, 0x00f60000, 0x04020004,
+	0x0201f800, 0x00105e35, 0x040207d2, 0x0201f800,
+	0x0010513b, 0x04000010, 0x59c400a4, 0x4803c857,
+	0x82000500, 0x0000000f, 0x82000580, 0x0000000a,
+	0x04020009, 0x497b5016, 0x59c400a3, 0x82000540,
+	0x00080000, 0x480388a3, 0x82000500, 0xfff7ffff,
+	0x480388a3, 0x4817c856, 0x0201f800, 0x0010a978,
+	0x4a039005, 0x00000140, 0x0401f842, 0x4803c856,
+	0x1c01f000, 0x00105a1d, 0x00105cf4, 0x00105a15,
+	0x00105a15, 0x00105a15, 0x00105a15, 0x00105a15,
+	0x00105a15, 0x4803c857, 0x42000000, 0x0010b85a,
+	0x0201f800, 0x0010aa47, 0x4a039005, 0x00000140,
+	0x1c01f000, 0x4817c857, 0x59cc0400, 0x4803c857,
+	0x82000d00, 0x0000ff00, 0x82041500, 0x0000f000,
+	0x840409c0, 0x82140500, 0x000003ff, 0x800018c4,
+	0x8c142d14, 0x04000005, 0x59cc0002, 0x82000500,
+	0x00000003, 0x800c1c80, 0x480f5016, 0x82080580,
+	0x00002000, 0x04020011, 0x836c0580, 0x00000001,
+	0x0402000c, 0x59cc0006, 0x82000500, 0xff000000,
+	0x82000580, 0x11000000, 0x04020011, 0x0201f800,
+	0x00103b38, 0x0201f800, 0x00105f48, 0x0401f00c,
+	0x0401f81f, 0x0401f00a, 0x82080580, 0x00003000,
+	0x04020003, 0x0401fa06, 0x0401f005, 0x82080580,
+	0x00008000, 0x04020002, 0x0401fafc, 0x1c01f000,
+	0x4817c857, 0x42000000, 0x0010b859, 0x0201f800,
+	0x0010aa47, 0x836c0580, 0x00000003, 0x0402000b,
+	0x4c080000, 0x4c0c0000, 0x42001000, 0x00008048,
+	0x40141800, 0x80142120, 0x0201f800, 0x00103a3e,
+	0x5c001800, 0x5c001000, 0x1c01f000, 0x4807c857,
+	0x59cc0002, 0x82000500, 0xff000000, 0x82001580,
+	0x01000000, 0x04000004, 0x82001580, 0x23000000,
+	0x04020192, 0x82040580, 0x00000023, 0x0402003f,
+	0x0401fb6a, 0x0400018d, 0x59300c06, 0x82040580,
+	0x00000010, 0x04000013, 0x82040580, 0x00000011,
+	0x04000010, 0x82040580, 0x00000001, 0x0400000d,
+	0x82040580, 0x00000004, 0x0400000a, 0x82040580,
+	0x00000008, 0x04000007, 0x82040580, 0x0000000a,
+	0x04000004, 0x4933c857, 0x4807c857, 0x0401f177,
+	0x59300004, 0x82000500, 0x80010000, 0x04000004,
+	0x0201f800, 0x00106f60, 0x04020170, 0x59cc0a04,
+	0x48066202, 0x59cc0006, 0x82000500, 0xffff0000,
+	0x82000d80, 0x02000000, 0x04020005, 0x42027000,
+	0x00000015, 0x0201f000, 0x000207a1, 0x82000d80,
+	0x02140000, 0x040007fa, 0x82000d80, 0x02100000,
+	0x040007f7, 0x82000d80, 0x02100000, 0x040007f4,
+	0x82000d80, 0x01000000, 0x04020158, 0x59cc0006,
+	0x82000500, 0x0000ffff, 0x04020154, 0x42027000,
+	0x00000016, 0x0401f7ec, 0x82040580, 0x00000022,
+	0x0402014e, 0x59a80806, 0x8c040d14, 0x04000011,
+	0x0401f967, 0x0402000f, 0x0401f97d, 0x0400000d,
+	0x42027000, 0x0000004c, 0x59cc0001, 0x82000500,
+	0x00ffffff, 0x0201f800, 0x00105eec, 0x0400012a,
+	0x42028800, 0x0000ffff, 0x417a6800, 0x0401f126,
+	0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80,
+	0x03000000, 0x04020021, 0x59a80026, 0x8c000508,
+	0x04000017, 0x8400054c, 0x48035026, 0x59cc0800,
+	0x82040d00, 0x00ffffff, 0x48075010, 0x497b8830,
+	0x84040d70, 0x48078832, 0x59c40802, 0x84040d4c,
+	0x48078802, 0x59cc0007, 0x82000500, 0x0000ffff,
+	0x48038893, 0x4803501e, 0x42000800, 0x00000003,
+	0x59a81010, 0x0201f800, 0x00106c78, 0x59cc0006,
+	0x82000500, 0x0000ffff, 0x04020118, 0x42027000,
+	0x00000017, 0x0401f0d9, 0x82000d80, 0x04000000,
+	0x04020011, 0x59cc0006, 0x82000500, 0x0000ffff,
+	0x0402010e, 0x0201f800, 0x0010513b, 0x04000004,
+	0x42027000, 0x0000001d, 0x0401f0cc, 0x59a80026,
+	0x84000548, 0x48035026, 0x42027000, 0x00000030,
+	0x0401f0c6, 0x82000d80, 0x05000000, 0x04020008,
+	0x59cc0006, 0x82000500, 0x0000ffff, 0x040200fb,
+	0x42027000, 0x00000018, 0x0401f0bc, 0x82000d80,
+	0x20100000, 0x04020004, 0x42027000, 0x00000019,
+	0x0401f0b6, 0x82000d80, 0x21100000, 0x04020004,
+	0x42027000, 0x0000001a, 0x0401f0b0, 0x82000d80,
+	0x52000000, 0x04020008, 0x59cc0006, 0x82000500,
+	0x0000ffff, 0x040200e5, 0x42027000, 0x0000001b,
+	0x0401f0a6, 0x82000d80, 0x50000000, 0x04020008,
+	0x59cc0006, 0x82000500, 0x0000ffff, 0x040200db,
+	0x42027000, 0x0000001c, 0x0401f09c, 0x82000d80,
+	0x13000000, 0x04020004, 0x42027000, 0x00000034,
+	0x0401f096, 0x82000d80, 0x12000000, 0x04020008,
+	0x59cc0006, 0x82000500, 0x0000ffff, 0x040200cb,
+	0x42027000, 0x00000024, 0x0401f08c, 0x82000d00,
+	0xff000000, 0x82040d80, 0x24000000, 0x04020004,
+	0x42027000, 0x0000002d, 0x0401f084, 0x82000d00,
+	0xff000000, 0x82040d80, 0x53000000, 0x04020004,
+	0x42027000, 0x0000002a, 0x0401f07c, 0x82000d80,
+	0x0f000000, 0x04020004, 0x42027000, 0x00000020,
+	0x0401f076, 0x82000d80, 0x61040000, 0x04020036,
+	0x83cc1400, 0x00000006, 0x80080800, 0x50080000,
+	0x82000500, 0x0000ffff, 0x82000480, 0x00000004,
+	0x4c580000, 0x8000b104, 0x8058b1c0, 0x04000026,
+	0x4c100000, 0x50041800, 0x820c1500, 0x03000000,
+	0x80081130, 0x42000000, 0x0010b817, 0x82082580,
+	0x00000000, 0x04020004, 0x42000000, 0x0010b814,
+	0x0401f00c, 0x82082580, 0x00000001, 0x04020004,
+	0x42000000, 0x0010b815, 0x0401f006, 0x82082580,
+	0x00000002, 0x04020003, 0x42000000, 0x0010b816,
+	0x0201f800, 0x0010aa47, 0x42001000, 0x00008015,
+	0x820c2500, 0x0000ffff, 0x800c1920, 0x0201f800,
+	0x00103a3e, 0x5c002000, 0x80040800, 0x8058b040,
+	0x040207da, 0x5c00b000, 0x42027000, 0x00000023,
+	0x0401f03e, 0x82000d80, 0x60000000, 0x04020004,
+	0x42027000, 0x0000003f, 0x0401f038, 0x82000d80,
+	0x54000000, 0x04020006, 0x0401fb12, 0x0402006f,
+	0x42027000, 0x00000046, 0x0401f030, 0x82000d80,
+	0x55000000, 0x04020009, 0x0401fb32, 0x04020004,
+	0x42027000, 0x00000041, 0x0401f028, 0x42027000,
+	0x00000042, 0x0401f025, 0x82000d80, 0x78000000,
+	0x04020004, 0x42027000, 0x00000045, 0x0401f01f,
+	0x82000d80, 0x10000000, 0x04020004, 0x42027000,
+	0x0000004e, 0x0401f019, 0x82000d80, 0x63000000,
+	0x04020004, 0x42027000, 0x0000004a, 0x0401f013,
+	0x82000d00, 0xff000000, 0x82040d80, 0x56000000,
+	0x04020004, 0x42027000, 0x0000004f, 0x0401f00b,
+	0x82000d00, 0xff000000, 0x82040d80, 0x57000000,
+	0x04020004, 0x42027000, 0x00000050, 0x0401f003,
+	0x42027000, 0x0000001d, 0x59cc3800, 0x821c3d00,
+	0x00ffffff, 0x821c0580, 0x00fffffe, 0x59cc0001,
+	0x04020005, 0x40003000, 0x42028800, 0x000007fe,
+	0x0401f003, 0x0401f8d1, 0x04020030, 0x0201f800,
+	0x001045a6, 0x0402002d, 0x83380580, 0x00000046,
+	0x04020004, 0x59a80010, 0x80180580, 0x04000027,
+	0x59340200, 0x8c000514, 0x0400000f, 0x83380580,
+	0x00000030, 0x0400000c, 0x83380580, 0x0000003f,
+	0x04000009, 0x83380580, 0x00000034, 0x04000006,
+	0x83380580, 0x00000024, 0x04000003, 0x42027000,
+	0x0000004c, 0x0201f800, 0x0002075a, 0x04000018,
+	0x49366009, 0x4a026406, 0x00000004, 0x59cc0c04,
+	0x48066202, 0x83380580, 0x0000004c, 0x04020009,
+	0x4a026406, 0x00000011, 0x813669c0, 0x04020005,
+	0x59cc0001, 0x82000500, 0x00ffffff, 0x4802601e,
+	0x0201f000, 0x000207a1, 0x59880052, 0x4803c857,
+	0x80000000, 0x48031052, 0x1c01f000, 0x42001000,
+	0x00008049, 0x59cc1806, 0x800c1930, 0x0201f800,
+	0x00103a3e, 0x0201f800, 0x00107942, 0x040007f3,
+	0x49366009, 0x4a026406, 0x00000004, 0x59cc0c04,
+	0x48066202, 0x4a026403, 0x00000009, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00002900, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x59a80026,
+	0x4803c857, 0x8c000508, 0x04000010, 0x59cc0006,
+	0x82000500, 0xff000000, 0x82000d80, 0x03000000,
+	0x0400000c, 0x82000d80, 0x20000000, 0x04000009,
+	0x82000d80, 0x05000000, 0x04000006, 0x82000d80,
+	0x21000000, 0x04000003, 0x80000580, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fd, 0x59cc2006,
+	0x82102500, 0xff000000, 0x9c1021c0, 0x0401f807,
+	0x820c1c00, 0x0010b4e3, 0x500c1800, 0x800c0500,
+	0x4803c857, 0x1c01f000, 0x40100800, 0x41781800,
+	0x82040480, 0x00000020, 0x04001004, 0x800c1800,
+	0x40000800, 0x0401f7fb, 0x82040500, 0x0000000f,
+	0x82000400, 0x0010ab38, 0x50000000, 0x8c040d08,
+	0x04000002, 0x900001c0, 0x1c01f000, 0x4803c856,
+	0x0401fac3, 0x0402000a, 0x0201f800, 0x0010210a,
+	0x04020007, 0x59cc0002, 0x82000500, 0xff000000,
+	0x82000d80, 0x08000000, 0x04000802, 0x1c01f000,
+	0x4803c856, 0x59cc0400, 0x82000d00, 0x0000ff00,
+	0x840409c0, 0x82040580, 0x00000033, 0x0402001f,
+	0x0401f976, 0x04000038, 0x59cc0a04, 0x48066202,
+	0x59cc0006, 0x4803c857, 0x82000500, 0xffff0000,
+	0x82000d80, 0x02000000, 0x04020009, 0x59cc0006,
+	0x82000500, 0x0000ffff, 0x0402002b, 0x42027000,
+	0x00000015, 0x0201f000, 0x000207a1, 0x82000d80,
+	0x01000000, 0x04020024, 0x59cc0006, 0x82000500,
+	0x0000ffff, 0x04020020, 0x42027000, 0x00000016,
+	0x0201f000, 0x000207a1, 0x82040580, 0x00000032,
+	0x04020019, 0x59cc0006, 0x82000500, 0xffff0000,
+	0x82000d80, 0x14000000, 0x04020013, 0x42027000,
+	0x00000038, 0x59cc0001, 0x0401f810, 0x0402000e,
+	0x0201f800, 0x001045a6, 0x0402000b, 0x0201f800,
+	0x0002075a, 0x04000008, 0x49366009, 0x4a026406,
+	0x00000004, 0x59cc0c04, 0x48066202, 0x0201f000,
+	0x000207a1, 0x1c01f000, 0x4803c857, 0x4c580000,
+	0x4c100000, 0x4c380000, 0x4c340000, 0x82003500,
+	0x00ffffff, 0x82181500, 0x00ff0000, 0x82081580,
+	0x00ff0000, 0x04020016, 0x82181480, 0x00fffffc,
+	0x04001013, 0x82181580, 0x00fffffd, 0x04020004,
+	0x42028800, 0x000007fd, 0x0401f040, 0x82181580,
+	0x00fffffe, 0x04020004, 0x42028800, 0x000007fe,
+	0x0401f03a, 0x82181580, 0x00fffffc, 0x04020004,
+	0x42028800, 0x000007fc, 0x0401f034, 0x41781000,
+	0x42002000, 0x00000000, 0x4200b000, 0x000007f0,
+	0x41ac7000, 0x50380000, 0x80006d40, 0x04020005,
+	0x800811c0, 0x0402001e, 0x8410155e, 0x0401f01c,
+	0x58340212, 0x82000500, 0x0000ff00, 0x04000011,
+	0x59a84010, 0x82204500, 0x00ffff00, 0x82180500,
+	0x00ffff00, 0x04000002, 0x80200580, 0x58340002,
+	0x0402000f, 0x82000500, 0x000000ff, 0x82184500,
+	0x000000ff, 0x80204580, 0x04020009, 0x0401f006,
+	0x58340002, 0x82000500, 0x00ffffff, 0x80184580,
+	0x04020003, 0x40128800, 0x0401f00c, 0x80102000,
+	0x80387000, 0x8058b040, 0x040207db, 0x800811c0,
+	0x04020005, 0x481bc857, 0x82000540, 0x00000001,
+	0x0401f003, 0x840a8d1e, 0x80000580, 0x5c006800,
+	0x5c007000, 0x5c002000, 0x5c00b000, 0x1c01f000,
+	0x59a80026, 0x8c00050e, 0x04000003, 0x8c000502,
+	0x04000006, 0x59cc0c00, 0x80040910, 0x82040500,
+	0x0000000f, 0x0c01f002, 0x1c01f000, 0x00105d0f,
+	0x00105d0f, 0x00105d0f, 0x00105de5, 0x00105d0f,
+	0x00105d11, 0x00105d29, 0x00105d2c, 0x00105d0f,
+	0x00105d0f, 0x00105d0f, 0x00105d0f, 0x00105d0f,
+	0x00105d0f, 0x00105d0f, 0x00105d0f, 0x4803c856,
+	0x1c01f000, 0x0401f8c5, 0x04000014, 0x82140500,
+	0x000003ff, 0x800000c4, 0x82000480, 0x00000008,
+	0x0400100e, 0x59cc0001, 0x59326809, 0x59340802,
+	0x80040580, 0x82000500, 0x00ffffff, 0x04020007,
+	0x59cc0a04, 0x48066202, 0x42027000, 0x00000046,
+	0x0201f000, 0x000207a1, 0x59cc0004, 0x4803c857,
+	0x1c01f000, 0x59cc0004, 0x4803c857, 0x1c01f000,
+	0x0401f8aa, 0x04000016, 0x82140500, 0x000003ff,
+	0x800000c4, 0x82000480, 0x0000000c, 0x04001010,
+	0x59cc0001, 0x82000500, 0x00ffffff, 0x59326809,
+	0x59340802, 0x82040d00, 0x00ffffff, 0x80040580,
+	0x04020007, 0x59cc0a04, 0x48066202, 0x42027000,
+	0x00000045, 0x0201f000, 0x000207a1, 0x59cc0004,
+	0x4803c857, 0x1c01f000, 0x4817c857, 0x0401f9c8,
+	0x04020011, 0x0201f800, 0x0010210a, 0x0402000e,
+	0x59cc0002, 0x82000500, 0xff000000, 0x82000580,
+	0x00000000, 0x04020008, 0x82040500, 0x0000000f,
+	0x82000c80, 0x00000006, 0x04021003, 0x4803c857,
+	0x0c01f002, 0x1c01f000, 0x00105d60, 0x00105d64,
+	0x00105d60, 0x00105d60, 0x00105db2, 0x00105dc3,
+	0x4803c857, 0x59cc0004, 0x4803c857, 0x1c01f000,
+	0x59cc0004, 0x4803c857, 0x59a80016, 0x800001c0,
+	0x040207f8, 0x59cc0802, 0x8c040d2e, 0x0402001d,
+	0x0201f800, 0x00107942, 0x02000800, 0x001005d8,
+	0x59cc0001, 0x4803c857, 0x0401ff28, 0x0402000d,
+	0x0201f800, 0x00020245, 0x0402000a, 0x4a026406,
+	0x00000005, 0x49366009, 0x59cc0c04, 0x48066202,
+	0x42027000, 0x00000088, 0x0201f000, 0x000207a1,
+	0x42028800, 0x0000ffff, 0x417a6800, 0x59cc0001,
+	0x82000500, 0x00ffffff, 0x4802601e, 0x0401f7f0,
+	0x59cc0001, 0x4803c857, 0x0401ff10, 0x040207d5,
+	0x0201f800, 0x001045a6, 0x040207d2, 0x59cc0005,
+	0x8c000500, 0x04020004, 0x59340200, 0x8c00050e,
+	0x040207cc, 0x0201f800, 0x001049f3, 0x0402000f,
+	0x0401f83e, 0x040007c7, 0x0201f800, 0x0002075a,
+	0x040007c4, 0x49366009, 0x4a026406, 0x00000002,
+	0x59cc0c04, 0x48066202, 0x42027000, 0x00000088,
+	0x0201f000, 0x000207a1, 0x0201f800, 0x0002075a,
+	0x040007b8, 0x49366009, 0x4a026406, 0x00000004,
+	0x59cc0c04, 0x48066202, 0x42027000, 0x00000001,
+	0x0201f000, 0x000207a1, 0x59cc0004, 0x4803c857,
+	0x59cc0802, 0x8c040d2e, 0x0400000b, 0x0401f81f,
+	0x04000009, 0x0401f960, 0x04020007, 0x59cc0a04,
+	0x48066202, 0x42027000, 0x00000089, 0x0201f000,
+	0x000207a1, 0x4933c857, 0x1c01f000, 0x59cc0004,
+	0x4803c857, 0x59cc0802, 0x8c040d2e, 0x0400000b,
+	0x0401f80e, 0x04000009, 0x0401f94f, 0x04020007,
+	0x59cc0a04, 0x48066202, 0x42027000, 0x0000008a,
+	0x0201f000, 0x000207a1, 0x4933c857, 0x1c01f000,
+	0x59cc0a04, 0x0401f002, 0x59cc0c04, 0x59a8000e,
+	0x59a81067, 0x80080400, 0x80040480, 0x04021008,
+	0x40040000, 0x800000c4, 0x800408ca, 0x80040c00,
+	0x82066400, 0x0010d1c0, 0x1c01f000, 0x80000580,
+	0x0401f7fe, 0x59cc0802, 0x8c040d2e, 0x04020010,
+	0x0401ffec, 0x0400000e, 0x59cc0001, 0x82000500,
+	0x00ffffff, 0x59326809, 0x59340802, 0x82040d00,
+	0x00ffffff, 0x80040580, 0x04020005, 0x42027000,
+	0x00000051, 0x0201f000, 0x000207a1, 0x59cc0004,
+	0x4803c857, 0x1c01f000, 0x4803c856, 0x42003000,
+	0x00000105, 0x0401f001, 0x4803c856, 0x4c3c0000,
+	0x41cc7800, 0x0401f803, 0x5c007800, 0x1c01f000,
+	0x4803c856, 0x4c580000, 0x583c0400, 0x82000500,
+	0x0000f000, 0x82000580, 0x0000c000, 0x04000024,
+	0x0201f800, 0x0002075a, 0x04000021, 0x4c180000,
+	0x583c0001, 0x0401fe89, 0x0402001f, 0x0201f800,
+	0x001045a6, 0x0402001c, 0x49366009, 0x0201f800,
+	0x001007e4, 0x04000018, 0x492e6017, 0x497a5800,
+	0x497a5a04, 0x48125c04, 0x832cac00, 0x00000005,
+	0x4200b000, 0x00000007, 0x403ca000, 0x0201f800,
+	0x0010ab17, 0x5c003000, 0x481a641a, 0x4a026403,
+	0x0000003e, 0x4a026406, 0x00000001, 0x4a026203,
+	0x00000001, 0x0201f800, 0x0010672b, 0x5c00b000,
+	0x1c01f000, 0x0201f800, 0x0002077d, 0x5c003000,
+	0x0401f7fb, 0x4803c856, 0x59cc0400, 0x82000d00,
+	0x0000ff00, 0x82040500, 0x0000f000, 0x840409c0,
+	0x82000580, 0x00002000, 0x04020049, 0x82040580,
+	0x00000022, 0x0402003a, 0x59c400a4, 0x82000500,
+	0x0000000f, 0x82000c80, 0x00000007, 0x04001004,
+	0x82000480, 0x0000000c, 0x0400103f, 0x59cc0006,
+	0x82000500, 0xffff0000, 0x82000d80, 0x04000000,
+	0x04000039, 0x82000d80, 0x60000000, 0x04000036,
+	0x82000d80, 0x54000000, 0x04000033, 0x82000d80,
+	0x03000000, 0x04020015, 0x59a80826, 0x8c040d02,
+	0x0402002d, 0x8c040d08, 0x0402002b, 0x0201f800,
+	0x001048ec, 0x0400002b, 0x59a8001d, 0x800000d0,
+	0x59a80810, 0x82040d00, 0x000000ff, 0x80040540,
+	0x59cc0800, 0x82040d00, 0x00ffffff, 0x80040580,
+	0x0402001b, 0x0401f01c, 0x59c40802, 0x8c040d0c,
+	0x04020017, 0x82000d80, 0x52000000, 0x040007ec,
+	0x82000d80, 0x05000000, 0x040007e9, 0x82000d80,
+	0x50000000, 0x040007e6, 0x0401f00d, 0x82040580,
+	0x00000023, 0x0402000a, 0x0401ff58, 0x04000008,
+	0x59300c03, 0x82040580, 0x00000002, 0x04000006,
+	0x82040580, 0x00000051, 0x04000003, 0x80000580,
+	0x0401f003, 0x82000540, 0x00000001, 0x1c01f000,
+	0x59cc0006, 0x82000500, 0xffff0000, 0x82000d80,
+	0x03000000, 0x04000004, 0x82000d80, 0x52000000,
+	0x040207f3, 0x59a80026, 0x82000500, 0x00000009,
+	0x82000580, 0x00000008, 0x040007ef, 0x0401f7ec,
+	0x4803c856, 0x4c5c0000, 0x4c580000, 0x59a80016,
+	0x82000580, 0x0000004c, 0x0402001f, 0x59ccb807,
+	0x9c5cb9c0, 0x825cbd00, 0x00000007, 0x8c5cbd00,
+	0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00,
+	0x00000002, 0x83cc1400, 0x0000000d, 0x0201f800,
+	0x0010855a, 0x04020010, 0x8c5cbd02, 0x0400000a,
+	0x4200b000, 0x00000002, 0x83a81c00, 0x00000000,
+	0x83cc1400, 0x0000000f, 0x0201f800, 0x0010855a,
+	0x04020005, 0x8c5cbd04, 0x04000003, 0x82000540,
+	0x00000001, 0x5c00b000, 0x5c00b800, 0x1c01f000,
+	0x4803c856, 0x4c5c0000, 0x4c580000, 0x59a80016,
+	0x82000580, 0x0000004c, 0x0402001f, 0x59ccb807,
+	0x9c5cb9c0, 0x825cbd00, 0x00000007, 0x8c5cbd00,
+	0x0400000a, 0x4200b000, 0x00000002, 0x83a81c00,
+	0x00000002, 0x83cc1400, 0x00000009, 0x0201f800,
+	0x0010855a, 0x04020010, 0x8c5cbd02, 0x0400000a,
+	0x4200b000, 0x00000002, 0x83a81c00, 0x00000000,
+	0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a,
+	0x04020005, 0x8c5cbd04, 0x04000003, 0x82000540,
+	0x00000001, 0x5c00b000, 0x5c00b800, 0x1c01f000,
+	0x4803c857, 0x4c580000, 0x40003000, 0x42002000,
+	0x000007f0, 0x4200b000, 0x00000010, 0x83ac7400,
+	0x000007f0, 0x50380000, 0x80026d40, 0x04000006,
+	0x59340002, 0x82000500, 0x00ffffff, 0x80180580,
+	0x04000010, 0x80102000, 0x80387000, 0x8058b040,
+	0x040207f5, 0x82100480, 0x00000800, 0x42002000,
+	0x00000000, 0x4200b000, 0x000007f0, 0x41ac7000,
+	0x040217ed, 0x82000540, 0x00000001, 0x0401f002,
+	0x40128800, 0x5c00b000, 0x1c01f000, 0x59a80026,
+	0x8c00050e, 0x04000004, 0x8c000502, 0x04000003,
+	0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+	0x0401f7fd, 0x59300c06, 0x82040580, 0x00000002,
+	0x04000006, 0x82040580, 0x00000005, 0x04000003,
+	0x82000540, 0x00000001, 0x1c01f000, 0x59c80000,
+	0x84000558, 0x84000512, 0x48039000, 0x1c01f000,
+	0x4a03281a, 0x000003e8, 0x4a032802, 0x0010d1c0,
+	0x4a032800, 0x00000000, 0x4a032808, 0x00107049,
+	0x42000000, 0x00000005, 0x83947c00, 0x00000009,
+	0x49787801, 0x4a007802, 0x00106fff, 0x823c7c00,
+	0x00000003, 0x80000040, 0x040207fa, 0x4a032819,
+	0xffff0000, 0x4201d000, 0x00000064, 0x0401f96e,
+	0x4201d000, 0x000186a0, 0x0401f184, 0x00000000,
+	0x00000003, 0x00000006, 0x00000009, 0x0000000c,
+	0x4d300000, 0x4d2c0000, 0x4d340000, 0x4d400000,
+	0x4cfc0000, 0x4d380000, 0x4d3c0000, 0x4d440000,
+	0x4d4c0000, 0x4d480000, 0x4c5c0000, 0x4c600000,
+	0x4c640000, 0x4cc80000, 0x4ccc0000, 0x0201f800,
+	0x0002057b, 0x5c019800, 0x5c019000, 0x5c00c800,
+	0x5c00c000, 0x5c00b800, 0x5c029000, 0x5c029800,
+	0x5c028800, 0x5c027800, 0x5c027000, 0x5c01f800,
+	0x5c028000, 0x5c026800, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x59940004, 0x80000540, 0x0402000a,
+	0x59940025, 0x80040400, 0x02001800, 0x001005d8,
+	0x48032804, 0x480b2805, 0x4a032803, 0x0000000a,
+	0x80000580, 0x1c01f000, 0x5994001f, 0x80000540,
+	0x0402000a, 0x59940025, 0x80040400, 0x02001800,
+	0x001005d8, 0x4803281f, 0x480b2820, 0x4a03281e,
+	0x00000001, 0x80000580, 0x1c01f000, 0x59940022,
+	0x80000540, 0x0402000a, 0x59940025, 0x80040400,
+	0x02001800, 0x001005d8, 0x48032822, 0x480b2823,
+	0x4a032821, 0x0000000a, 0x80000580, 0x1c01f000,
+	0x4c000000, 0x59940005, 0x4803c857, 0x480bc857,
+	0x80080580, 0x04020003, 0x497b2804, 0x497b2805,
+	0x5c000000, 0x1c01f000, 0x4c000000, 0x59940020,
+	0x4803c857, 0x480bc857, 0x80080580, 0x04020003,
+	0x497b281f, 0x497b2820, 0x5c000000, 0x1c01f000,
+	0x4c000000, 0x59940023, 0x4803c857, 0x480bc857,
+	0x80080580, 0x04020003, 0x497b2822, 0x497b2823,
+	0x5c000000, 0x1c01f000, 0x4937c857, 0x48ebc857,
+	0x59340203, 0x80e80480, 0x04001002, 0x48ea6a03,
+	0x1c01f000, 0x5c03e000, 0x1c01f000, 0x4d440000,
+	0x42007800, 0x00000010, 0x59968801, 0x0201f800,
+	0x00020245, 0x04020012, 0x59341a03, 0x800c1840,
+	0x0400100f, 0x59940027, 0x800c0480, 0x04000003,
+	0x48026a03, 0x0402100a, 0x5934000f, 0x497a6a03,
+	0x80000540, 0x04000006, 0x4c3c0000, 0x5934140b,
+	0x0201f800, 0x00020253, 0x5c007800, 0x81468800,
+	0x83440480, 0x00000800, 0x04021007, 0x803c7840,
+	0x040207e7, 0x49472801, 0x5c028800, 0x5c03e000,
+	0x1c01f000, 0x4a032800, 0x00000002, 0x497b2801,
+	0x0401f7fa, 0x42007800, 0x00000010, 0x59966002,
+	0x59300205, 0x80000d40, 0x04000006, 0x59940027,
+	0x80040480, 0x48026205, 0x0400102d, 0x0400002c,
+	0x59300206, 0x80000d40, 0x04000014, 0x59b800e4,
+	0x8c000524, 0x04020011, 0x4a0370e4, 0x00030000,
+	0x40000000, 0x59b800e4, 0x8c000524, 0x04000004,
+	0x4a0370e4, 0x00020000, 0x0401f008, 0x59940027,
+	0x80040480, 0x48026206, 0x4a0370e4, 0x00020000,
+	0x0400101c, 0x0400001b, 0x83326400, 0x00000024,
+	0x49332802, 0x41540000, 0x81300480, 0x04021005,
+	0x803c7840, 0x040207db, 0x5c03e000, 0x1c01f000,
+	0x59940026, 0x48032827, 0x4a032802, 0x0010d1c0,
+	0x497b2826, 0x80000540, 0x0400000f, 0x4a032800,
+	0x00000001, 0x5c03e000, 0x1c01f000, 0x4c3c0000,
+	0x0201f800, 0x001091db, 0x5c007800, 0x0401f7d1,
+	0x4c3c0000, 0x0201f800, 0x00108d5d, 0x5c007800,
+	0x0401f7e2, 0x4a032800, 0x00000000, 0x5c03e000,
+	0x1c01f000, 0x59a8086b, 0x8c040d30, 0x04020029,
+	0x8c040d32, 0x0400000f, 0x59a80069, 0x81640480,
+	0x04001019, 0x59a8000b, 0x81500580, 0x04000005,
+	0x59a8006a, 0x59a81066, 0x80080580, 0x04020012,
+	0x900411c0, 0x82081500, 0x00007000, 0x0401f012,
+	0x82040500, 0x0000001f, 0x04000016, 0x80040840,
+	0x82040500, 0x0000001f, 0x04000003, 0x4807506b,
+	0x0401f010, 0x900401c0, 0x82000500, 0x0000001f,
+	0x80040d40, 0x900401c0, 0x80040580, 0x82001500,
+	0x00007000, 0x82040500, 0xffff8fff, 0x80080540,
+	0x4803506b, 0x80081114, 0x0201f800, 0x001006e2,
+	0x1c01f000, 0x4a032807, 0x000007d0, 0x4a032806,
+	0x0000000a, 0x1c01f000, 0x42000800, 0x000007d0,
+	0x83180480, 0x00000005, 0x02021800, 0x001005d8,
+	0x83947c00, 0x00000009, 0x83180400, 0x00105f43,
+	0x50000000, 0x803c7c00, 0x48047801, 0x4a007800,
+	0x0000000a, 0x1c01f000, 0x83180480, 0x00000005,
+	0x02021800, 0x001005d8, 0x83947c00, 0x00000009,
+	0x83180400, 0x00105f43, 0x50000000, 0x803c7c00,
+	0x49787801, 0x1c01f000, 0x4807c857, 0x480bc857,
+	0x59940025, 0x80040400, 0x02001800, 0x001005d8,
+	0x48032804, 0x480b2805, 0x4a032803, 0x0000000a,
+	0x1c01f000, 0x4807c857, 0x480bc857, 0x59940025,
+	0x80040400, 0x02001800, 0x001005d8, 0x4803281c,
+	0x480b281d, 0x4a03281b, 0x0000000a, 0x1c01f000,
+	0x4c000000, 0x5994001d, 0x4803c857, 0x480bc857,
+	0x80080580, 0x04020003, 0x4803281c, 0x4803281d,
+	0x5c000000, 0x1c01f000, 0x80e9d1c0, 0x0400000e,
+	0x0401f836, 0x04025000, 0x4203e000, 0x80000000,
+	0x40e81000, 0x41780800, 0x42000000, 0x00000064,
+	0x0201f800, 0x001066a0, 0x59940024, 0x80080400,
+	0x48032824, 0x1c01f000, 0x42001000, 0x00105065,
+	0x0401fef0, 0x42001000, 0x00105058, 0x0401ffe1,
+	0x42001000, 0x00104148, 0x0401feea, 0x42001000,
+	0x001041bc, 0x0401fee7, 0x42001000, 0x001041f3,
+	0x0401f6f8, 0x4203e000, 0x70000000, 0x4203e000,
+	0xb0300000, 0x41fc0000, 0x40ebf800, 0x80e80480,
+	0x04001011, 0x04000004, 0x82000480, 0x00000003,
+	0x0402100d, 0x42000000, 0x0000000f, 0x04004004,
+	0x80000040, 0x040207fe, 0x0401f007, 0x4203e000,
+	0x70000000, 0x42000000, 0x0010b87e, 0x0201f800,
+	0x0010aa47, 0x1c01f000, 0x4203e000, 0x80000000,
+	0x4203e000, 0xb0400000, 0x41fc0000, 0x40ebf800,
+	0x80e80480, 0x04001011, 0x04000004, 0x82000480,
+	0x00000003, 0x0402100d, 0x42000000, 0x0000000f,
+	0x04005004, 0x80000040, 0x040207fe, 0x0401f007,
+	0x4203e000, 0x80000000, 0x42000000, 0x0010b87f,
+	0x0201f800, 0x0010aa47, 0x1c01f000, 0x59a8000e,
+	0x82000480, 0x00000100, 0x599c0a02, 0x800409c0,
+	0x04020002, 0x80040800, 0x80041480, 0x04001002,
+	0x40000800, 0x48075067, 0x59a8100e, 0x40040000,
+	0x800acc80, 0x4967500e, 0x49675069, 0x59aaa80b,
+	0x41640800, 0x42001000, 0x00000024, 0x0201f800,
+	0x00106681, 0x8206a400, 0x0010d1c0, 0x49535065,
+	0x4152b000, 0x42006000, 0x0010be65, 0x4a006004,
+	0x0000012c, 0x4a006005, 0xda10da10, 0x4a006008,
+	0x00000011, 0x4a006009, 0x0010be65, 0x4a00600a,
+	0x001010b8, 0x599c0014, 0x48006011, 0x599c0015,
+	0x48006012, 0x42006000, 0x0010be41, 0x4a006203,
+	0x00000008, 0x4a006406, 0x00000006, 0x4a006002,
+	0xffff0000, 0x4a006008, 0x0010be65, 0x4a006014,
+	0x0010be65, 0x599c0014, 0x48006015, 0x599c0015,
+	0x48006016, 0x599c0413, 0x48006017, 0x49506018,
+	0x49546019, 0x59a80067, 0x4800601a, 0x4a00601b,
+	0x0010b465, 0x4a00601c, 0x0010b466, 0x4a00601d,
+	0x0010b46a, 0x42000000, 0xb0000000, 0x42000800,
+	0x0010be41, 0x0201f800, 0x00100b68, 0x1c01f000,
+	0x82000d00, 0x000000c0, 0x04000004, 0x82040d80,
+	0x000000c0, 0x04020055, 0x82000d00, 0x00002020,
+	0x59300414, 0x84000512, 0x82040d80, 0x00002020,
+	0x0400000b, 0x8c000514, 0x0402000f, 0x48026414,
+	0x813e79c0, 0x02020000, 0x000206d0, 0x42027000,
+	0x00000043, 0x0201f000, 0x000207a1, 0x59326809,
+	0x59340a00, 0x8c040d0a, 0x040007f3, 0x84000552,
+	0x0401f7f1, 0x84000514, 0x592c080d, 0x48066015,
+	0x0401f7ef, 0x59326809, 0x59340a00, 0x8c040d0a,
+	0x02000000, 0x000206e3, 0x59300c14, 0x84040d52,
+	0x48066414, 0x0201f000, 0x000206e3, 0x0201f800,
+	0x00020086, 0x813e79c0, 0x02020000, 0x000206d0,
+	0x0201f000, 0x000206f1, 0x8c00051e, 0x02000000,
+	0x000206fd, 0x82000d00, 0x00002020, 0x82040d80,
+	0x00002020, 0x04000014, 0x82000500, 0x000000c0,
+	0x82000d80, 0x00000080, 0x04000008, 0x813e79c0,
+	0x02020000, 0x000206d0, 0x42027000, 0x00000041,
+	0x0201f000, 0x000207a1, 0x813e79c0, 0x02020000,
+	0x000206d0, 0x42027000, 0x00000043, 0x0201f000,
+	0x000207a1, 0x59326809, 0x59340a00, 0x8c040d0a,
+	0x040007ea, 0x59300c14, 0x84040d52, 0x48066414,
+	0x0401f7e6, 0x492fc857, 0x42000800, 0x00000006,
+	0x0201f000, 0x000206f8, 0x492fc857, 0x42000800,
+	0x00000004, 0x0201f000, 0x000206f8, 0x4807c856,
+	0x59a80068, 0x800409c0, 0x04000003, 0x80080540,
+	0x0401f002, 0x80080500, 0x48035068, 0x1c01f000,
+	0x4a030800, 0x00000000, 0x4a030802, 0x00000001,
+	0x497b0803, 0x497b0804, 0x1c01f000, 0x59840002,
+	0x8c000500, 0x04000004, 0x84000500, 0x4a030800,
+	0x00000001, 0x84000544, 0x84000506, 0x48030802,
+	0x82000d00, 0x0fffffff, 0x42000000, 0x90000000,
+	0x0201f800, 0x00100b94, 0x59a80069, 0x82000480,
+	0x00000007, 0x48035069, 0x80000580, 0x42000800,
+	0x0010b519, 0x48000800, 0x48000801, 0x1c01f000,
+	0x59a80069, 0x82000480, 0x00000007, 0x48035069,
+	0x1c01f000, 0x83640480, 0x00000008, 0x0400101b,
+	0x58c80a03, 0x80000580, 0x82000400, 0x00000008,
+	0x80040840, 0x040207fd, 0x815c0480, 0x04001013,
+	0x4200b000, 0x00000007, 0x0201f800, 0x0002075a,
+	0x4a026203, 0x00000004, 0x4a026406, 0x00000009,
+	0x4a026203, 0x00000004, 0x4a026007, 0x00000101,
+	0x0401f809, 0x0401f880, 0x8058b040, 0x040207f3,
+	0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+	0x0401f7fd, 0x0201f800, 0x001007e4, 0x492e6008,
+	0x58c80a03, 0x4a025a04, 0x0000002c, 0x497a5800,
+	0x497a5801, 0x497a5c04, 0x497a5c06, 0x497a5805,
+	0x4a025a08, 0x00000005, 0x4a025a07, 0x00000002,
+	0x58c80201, 0x48025c04, 0x58c80202, 0x48025c07,
+	0x58c80204, 0x48025c08, 0x4a02580d, 0x0000ffff,
+	0x80040840, 0x0400000c, 0x412c2000, 0x0201f800,
+	0x001007e4, 0x4a025a04, 0x0000000a, 0x497a5c04,
+	0x48125800, 0x492c2001, 0x412c2000, 0x80040840,
+	0x040207f7, 0x1c01f000, 0x4d7c0000, 0x4202f800,
+	0x00000010, 0x4df00000, 0x4203e000, 0x50000000,
+	0x59847803, 0x803c79c0, 0x0400001e, 0x4c5c0000,
+	0x583cb808, 0x585c3408, 0x801831c0, 0x0400000b,
+	0x0401f84a, 0x04000016, 0x42001000, 0x0010b519,
+	0x0401f87f, 0x04000012, 0x0201f800, 0x001007d3,
+	0x0400000f, 0x492cb805, 0x585c0005, 0x80000540,
+	0x02000800, 0x001005d8, 0x0401f830, 0x585c5408,
+	0x0401f80b, 0x5c00b800, 0x5c03e000, 0x817ef840,
+	0x040207e1, 0x5c02f800, 0x1c01f000, 0x5c00b800,
+	0x5c03e000, 0x5c02f800, 0x1c01f000, 0x4803c856,
+	0x405c6000, 0x802851c0, 0x04000018, 0x585c0204,
+	0x82000d00, 0x0000000f, 0x82040c00, 0x001010bd,
+	0x50044000, 0x4cf00000, 0x4d000000, 0x4d040000,
+	0x4021e000, 0x40320800, 0x59860004, 0x4c280000,
+	0x0401f934, 0x5c005000, 0x40f04000, 0x41046000,
+	0x0201f800, 0x0010109b, 0x040207f6, 0x5c020800,
+	0x5c020000, 0x5c01e000, 0x58c80204, 0x4800bc08,
+	0x0201f800, 0x00020086, 0x4a026007, 0x00000101,
+	0x497a6009, 0x0401f055, 0x4803c856, 0x59840003,
+	0x80026540, 0x04000003, 0x59300000, 0x48030803,
+	0x1c01f000, 0x4803c856, 0x59840003, 0x48026000,
+	0x49330803, 0x1c01f000, 0x58cc0805, 0x40180000,
+	0x80040480, 0x0400100d, 0x82cc0580, 0x0010b50e,
+	0x02020800, 0x001005d8, 0x58c80205, 0x80040480,
+	0x0400101d, 0x82000540, 0x00000001, 0x1c01f000,
+	0x80003580, 0x0401f7fe, 0x82cc0580, 0x0010b50e,
+	0x02020800, 0x001005d8, 0x58c80400, 0x8c000504,
+	0x040007f8, 0x58c8040b, 0x8c00051e, 0x040007f5,
+	0x8c000500, 0x040207f3, 0x84000540, 0x4801940b,
+	0x42000000, 0x0010b839, 0x0201f800, 0x0010aa47,
+	0x42001000, 0x00008026, 0x0201f800, 0x00103a3e,
+	0x0401f7e8, 0x58c8040b, 0x8c00051e, 0x040007e2,
+	0x8c000502, 0x040207e0, 0x84000542, 0x4801940b,
+	0x42000000, 0x0010b838, 0x0201f800, 0x0010aa47,
+	0x42001000, 0x00008025, 0x42001800, 0x00000000,
+	0x0201f800, 0x00103a3e, 0x0401f7d3, 0x4803c856,
+	0x58080000, 0x42001800, 0x00000007, 0x58080801,
+	0x80040480, 0x04020004, 0x400c0000, 0x80000540,
+	0x0401f005, 0x04001003, 0x800c0480, 0x0401f002,
+	0x80000080, 0x1c01f000, 0x4803c856, 0x59300008,
+	0x80000d40, 0x02000800, 0x001005d8, 0x58040005,
+	0x80000540, 0x02000800, 0x001005d8, 0x59300007,
+	0x82000500, 0x00000101, 0x82000580, 0x00000101,
+	0x02020800, 0x001005d8, 0x42001000, 0x0010b519,
+	0x58080801, 0x82040400, 0x0010b51b, 0x497a6414,
+	0x4a026015, 0x0000ffff, 0x45300000, 0x80040800,
+	0x82040480, 0x00000008, 0x04001002, 0x80000d80,
+	0x48041001, 0x82040400, 0x0010b51b, 0x45780000,
+	0x1c01f000, 0x4933c857, 0x59300808, 0x800409c0,
+	0x02000800, 0x001005d8, 0x4d2c0000, 0x58065805,
+	0x812e59c0, 0x02020800, 0x001007f4, 0x49780805,
+	0x40065800, 0x0201f800, 0x001007fd, 0x5c025800,
+	0x4d300000, 0x0201f800, 0x0002077d, 0x5c026000,
+	0x1c01f000, 0x59300406, 0x82000580, 0x00000009,
+	0x04020006, 0x59300007, 0x8c000510, 0x04000003,
+	0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+	0x1c01f000, 0x59840802, 0x8c040d04, 0x1c01f000,
+	0x4803c856, 0x59840802, 0x84040d04, 0x84040d40,
+	0x4a030800, 0x00000000, 0x48070802, 0x82040d00,
+	0x0fffffff, 0x42000000, 0x90000000, 0x0201f000,
+	0x00100b94, 0x4807c857, 0x4805980a, 0x49799801,
+	0x49799803, 0x49799806, 0x49799807, 0x49799808,
+	0x49799805, 0x49799809, 0x0401f8c9, 0x0400000a,
+	0x0401f8eb, 0x04000008, 0x48359800, 0x48359802,
+	0x48359806, 0x4a019804, 0x00000001, 0x4a019807,
+	0x00000005, 0x1c01f000, 0x4807c857, 0x58cc1007,
+	0x40040000, 0x80080480, 0x04021020, 0x4c040000,
+	0x4c080000, 0x0401f8da, 0x5c001000, 0x5c000800,
+	0x0400001c, 0x58cc0006, 0x80006540, 0x0402000b,
+	0x48359800, 0x48359802, 0x48359806, 0x49799801,
+	0x49799803, 0x49786801, 0x49786800, 0x49799804,
+	0x49799807, 0x0401f005, 0x48306801, 0x48346000,
+	0x48359806, 0x49786800, 0x58cc0004, 0x58cc1007,
+	0x80000000, 0x82081400, 0x00000005, 0x48019804,
+	0x48099807, 0x0401f7df, 0x80000580, 0x1c01f000,
+	0x82000540, 0x00000001, 0x1c01f000, 0x480bc857,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x40083000,
+	0x58cc0801, 0x82040480, 0x00000005, 0x02021800,
+	0x001005d8, 0x82040400, 0x00106418, 0x50000000,
+	0x58cca800, 0x8054ac00, 0x42001800, 0x00000005,
+	0x40040000, 0x800c0480, 0x80082480, 0x04021002,
+	0x40080000, 0x8000b0c2, 0x8058b400, 0x5450a800,
+	0x8050a000, 0x8054a800, 0x8058b040, 0x040207fc,
+	0x40001000, 0x58cc2805, 0x58cc0807, 0x58cc2001,
+	0x80142c00, 0x80040c80, 0x80102400, 0x48159805,
+	0x48059807, 0x48119801, 0x82100580, 0x00000005,
+	0x0400000c, 0x48119801, 0x40080000, 0x80181480,
+	0x40083000, 0x04000003, 0x040217d6, 0x80000580,
+	0x5c00b000, 0x5c00a800, 0x5c00a000, 0x1c01f000,
+	0x58cc0800, 0x800409c0, 0x02000800, 0x001005d8,
+	0x58040800, 0x48059800, 0x41782000, 0x0401f7ee,
+	0x0401f813, 0x50f00000, 0x81040400, 0x40001800,
+	0x585c0204, 0x4803c857, 0x82000580, 0x0000002c,
+	0x02020800, 0x001005d8, 0x58040202, 0x800000e0,
+	0x81000540, 0x48001802, 0x58040000, 0x48001800,
+	0x58040001, 0x48001801, 0x1c01f000, 0x4807c856,
+	0x58cc0005, 0x80000040, 0x02001800, 0x001005d8,
+	0x48019805, 0x58cc1003, 0x82080480, 0x00000005,
+	0x02021800, 0x001005d8, 0x82080400, 0x00106418,
+	0x50000000, 0x58cc0802, 0x80040c00, 0x80081000,
+	0x82080480, 0x00000005, 0x0402000f, 0x58cc2002,
+	0x58100000, 0x80006d40, 0x04000009, 0x4c340000,
+	0x0401f858, 0x5c006800, 0x49786801, 0x48359802,
+	0x58cc0004, 0x80000040, 0x48019804, 0x49799803,
+	0x0401f002, 0x48099803, 0x1c01f000, 0x4807c856,
+	0x41781800, 0x58c80201, 0x80000540, 0x04000002,
+	0x800c1800, 0x58c80c01, 0x80040c80, 0x0400100a,
+	0x04000009, 0x800c1800, 0x58c80202, 0x80041480,
+	0x04001005, 0x04000004, 0x800c1800, 0x40080800,
+	0x0401f7fb, 0x480d9204, 0x400c0000, 0x42002000,
+	0x00000001, 0x80000040, 0x04000007, 0x04001006,
+	0x80102000, 0x82000480, 0x00000005, 0x04000002,
+	0x040217fc, 0x48119203, 0x1c01f000, 0x4807c856,
+	0x4d2c0000, 0x58cc000a, 0x80000540, 0x02000800,
+	0x001005d8, 0x82002400, 0x00000005, 0x0201f800,
+	0x001007d3, 0x04000012, 0x492d9809, 0x497a5800,
+	0x497a5801, 0x0201f800, 0x001007d3, 0x0400000c,
+	0x58cc0009, 0x48025800, 0x497a5801, 0x492d9809,
+	0x82102480, 0x00000005, 0x040217f7, 0x82000540,
+	0x00000001, 0x5c025800, 0x1c01f000, 0x58cc0009,
+	0x80025d40, 0x040007fc, 0x592c2000, 0x0201f800,
+	0x001007f4, 0x40100000, 0x0401f7fa, 0x58cc0009,
+	0x48cfc857, 0x80006d40, 0x04000005, 0x50340000,
+	0x48019809, 0x49786800, 0x49786801, 0x1c01f000,
+	0x4813c857, 0x58cc0009, 0x48002000, 0x48119809,
+	0x1c01f000, 0x4807c856, 0x4d2c0000, 0x58cc0009,
+	0x80025d40, 0x04000007, 0x592c0000, 0x4c000000,
+	0x0201f800, 0x001007f4, 0x5c000000, 0x0401f7f9,
+	0x5c025800, 0x1c01f000, 0x4807c856, 0x4d2c0000,
+	0x58cc0002, 0x80025d40, 0x04000007, 0x592c0000,
+	0x4c000000, 0x0201f800, 0x001007f4, 0x5c000000,
+	0x0401f7f9, 0x49799800, 0x49799802, 0x49799801,
+	0x49799803, 0x49799806, 0x49799807, 0x49799808,
+	0x49799809, 0x4979980a, 0x5c025800, 0x1c01f000,
+	0x00000003, 0x00000006, 0x00000009, 0x0000000c,
+	0x0000000f, 0x00000012, 0x4803c856, 0x0401f857,
+	0x4a00c204, 0x0000003c, 0x59301009, 0x82080580,
+	0x0010b524, 0x04000013, 0x58080802, 0x82040d00,
+	0x00ffffff, 0x58080403, 0x4804c005, 0x4800c406,
+	0x4a00c207, 0x00000003, 0x59300811, 0x585c0404,
+	0x4978c206, 0x4804c407, 0x80000540, 0x0400000d,
+	0x58600206, 0x84000540, 0x4800c206, 0x0401f009,
+	0x585c080a, 0x82040d00, 0x00ffffff, 0x4804c005,
+	0x4a00c406, 0x000007ff, 0x4978c207, 0x0401f7ef,
+	0x82603c00, 0x00000008, 0x58605404, 0x40282000,
+	0x405c6000, 0x585c0a04, 0x82040d00, 0x0000000f,
+	0x82040c00, 0x001010bd, 0x50044000, 0x80004d80,
+	0x50200000, 0x80307400, 0x58380402, 0x8c244d00,
+	0x04020003, 0x48003a00, 0x0401f003, 0x48003c00,
+	0x801c3800, 0x80244800, 0x80102040, 0x04000006,
+	0x0201f800, 0x0010109b, 0x02000800, 0x001005d8,
+	0x0401f7f0, 0x1c01f000, 0x4803c856, 0x4d340000,
+	0x59300009, 0x80026d40, 0x02000800, 0x001005d8,
+	0x59340401, 0x80000540, 0x0400000e, 0x59840000,
+	0x80000540, 0x0400000b, 0x836c0580, 0x00000003,
+	0x04020008, 0x59341c03, 0x42002000, 0x00000004,
+	0x42003000, 0x00000004, 0x0201f800, 0x00103aae,
+	0x5c026800, 0x1c01f000, 0x4803c856, 0x80001580,
+	0x58c80c01, 0x59300011, 0x80040c80, 0x48066011,
+	0x58c80201, 0x80000540, 0x04000005, 0x80081000,
+	0x80040c80, 0x04001007, 0x04000006, 0x58c80202,
+	0x80081000, 0x80040c80, 0x04001002, 0x040207fd,
+	0x4808bc08, 0x4808c404, 0x1c01f000, 0x4803c856,
+	0x4a0370e5, 0x00020000, 0x59b800e5, 0x8c000524,
+	0x040207fc, 0x4a0370e5, 0x00030000, 0x40000000,
+	0x40000000, 0x59b800e5, 0x8c000524, 0x040207f5,
+	0x5934000e, 0x80006d40, 0x04000010, 0x81300580,
+	0x04020004, 0x58340000, 0x4802680e, 0x0401f00a,
+	0x40347800, 0x58340000, 0x80006d40, 0x02000800,
+	0x001005d8, 0x81300580, 0x040207fa, 0x58340000,
+	0x48007800, 0x497a6000, 0x4a0370e5, 0x00020000,
+	0x1c01f000, 0x4803c856, 0x4d300000, 0x4d2c0000,
+	0x42000800, 0x000003ff, 0x4a0370e5, 0x00020000,
+	0x59b800e5, 0x8c000524, 0x04000005, 0x80040840,
+	0x040207fa, 0x0201f800, 0x001005d8, 0x4a0370e5,
+	0x00030000, 0x40000000, 0x40000000, 0x59b800e5,
+	0x8c000524, 0x040207f1, 0x5934000e, 0x80026540,
+	0x0400000e, 0x4933c857, 0x59300000, 0x4802680e,
+	0x4a026203, 0x00000004, 0x497a6206, 0x497a6009,
+	0x4a026007, 0x00000101, 0x59325808, 0x497a5c08,
+	0x0401fd81, 0x0401f7f1, 0x4a0370e5, 0x00020000,
+	0x5c025800, 0x5c026000, 0x1c01f000, 0x4803c856,
+	0x4c000000, 0x0201f800, 0x00105c9a, 0x04020011,
+	0x0201f800, 0x001045a6, 0x02020800, 0x001005d8,
+	0x5c000000, 0x48026802, 0x0201f800, 0x0002075a,
+	0x04000009, 0x49366009, 0x4a026406, 0x00000001,
+	0x42027000, 0x00000001, 0x0201f000, 0x000207a1,
+	0x5c000000, 0x1c01f000, 0x59300203, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x4803c857,
+	0x0c01f001, 0x00106503, 0x00106503, 0x00106503,
+	0x00106505, 0x00106565, 0x00106503, 0x00106503,
+	0x001065b7, 0x001065b8, 0x00106503, 0x00106503,
+	0x00106503, 0x00106503, 0x00106503, 0x0201f800,
+	0x001005d8, 0x493bc857, 0x83380480, 0x00000050,
+	0x02021800, 0x001005d8, 0x83380480, 0x00000049,
+	0x02001800, 0x001005d8, 0x0c01f001, 0x00106518,
+	0x0010653a, 0x00106516, 0x00106516, 0x00106516,
+	0x00106516, 0x00106549, 0x0201f800, 0x001005d8,
+	0x4d2c0000, 0x59325808, 0x592c0206, 0x48025c06,
+	0x4a025a06, 0x00000000, 0x4c5c0000, 0x592cbc0a,
+	0x592c0000, 0x48026008, 0x0201f800, 0x00104cde,
+	0x59300008, 0x80000540, 0x04000008, 0x4a026203,
+	0x00000007, 0x42027000, 0x00000043, 0x5c00b800,
+	0x5c025800, 0x0401f08a, 0x8c5cbd08, 0x04020006,
+	0x4a026203, 0x00000007, 0x497a6206, 0x497a6008,
+	0x0401f003, 0x0201f800, 0x0002077d, 0x5c00b800,
+	0x5c025800, 0x1c01f000, 0x0201f800, 0x00106b8a,
+	0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+	0x04000006, 0x4d400000, 0x42028000, 0x00000001,
+	0x0401f8f8, 0x5c028000, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x0201f800, 0x00106b8a, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800,
+	0x42003000, 0x00000014, 0x0201f800, 0x0010a942,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+	0x04000006, 0x4d400000, 0x42028000, 0x00000029,
+	0x0401f8dc, 0x5c028000, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x493bc857, 0x497a6206, 0x83380480,
+	0x00000054, 0x02021800, 0x001005d8, 0x83380480,
+	0x00000047, 0x02001800, 0x001005d8, 0x0c01f001,
+	0x001065b6, 0x0010657f, 0x0010657d, 0x0010657d,
+	0x0010657d, 0x0010657d, 0x0010657d, 0x0010657d,
+	0x0010657d, 0x0010657d, 0x0010657d, 0x0010657d,
+	0x00106583, 0x0201f800, 0x001005d8, 0x59300011,
+	0x82000500, 0xffff0000, 0x04020034, 0x59840802,
+	0x8c040d04, 0x04000025, 0x59300009, 0x80026d40,
+	0x0400001f, 0x4c5c0000, 0x4c600000, 0x497a6206,
+	0x5930b808, 0x585c0005, 0x8000c540, 0x02000800,
+	0x001005d8, 0x0401fe8d, 0x40625800, 0x0201f800,
+	0x00104cde, 0x4978b805, 0x0401fef5, 0x497a6009,
+	0x585c3408, 0x0401fcbd, 0x0400000e, 0x42001000,
+	0x0010b519, 0x0401fcf2, 0x0400000a, 0x0201f800,
+	0x001007e4, 0x04000007, 0x492cb805, 0x585c5408,
+	0x0401fc83, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+	0x0401fca9, 0x0401f7fc, 0x8c040d06, 0x040207fc,
+	0x59300009, 0x80026d40, 0x04000006, 0x5934000e,
+	0x80000540, 0x02020800, 0x001005d8, 0x497a6009,
+	0x0401fd0d, 0x0401f7f2, 0x0401f06f, 0x4803c856,
+	0x4803c856, 0x83380580, 0x00000043, 0x02020800,
+	0x001005d8, 0x4a026203, 0x00000003, 0x493a6403,
+	0x59325808, 0x592c000f, 0x48026011, 0x497a6013,
+	0x592c0406, 0x800000c2, 0x800010c4, 0x80081400,
+	0x480a6206, 0x0201f800, 0x00100f4e, 0x42000800,
+	0x80000060, 0x0401f154, 0x42000000, 0x0010b875,
+	0x0201f800, 0x0010aa47, 0x59300203, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x4803c857,
+	0x82000d80, 0x00000003, 0x04000006, 0x82000d80,
+	0x00000004, 0x04000045, 0x0201f800, 0x001005d8,
+	0x0201f800, 0x00106c55, 0x59300004, 0x8c00053e,
+	0x04020007, 0x0201f800, 0x00106b6c, 0x02020800,
+	0x001005d8, 0x0201f000, 0x00106c4b, 0x0401f9c3,
+	0x0201f800, 0x00106c4b, 0x59325808, 0x42028000,
+	0x00000006, 0x0401f84b, 0x0201f000, 0x0002077d,
+	0x4803c856, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x82000d80, 0x00000003,
+	0x04000006, 0x82000d80, 0x00000004, 0x04000023,
+	0x0201f800, 0x001005d8, 0x4803c856, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x59300004, 0x8c00053e,
+	0x04020006, 0x0201f800, 0x00106f60, 0x02020800,
+	0x001005d8, 0x0401f010, 0x0201f800, 0x00108cd6,
+	0x04020004, 0x0201f800, 0x00106e62, 0x0402000a,
+	0x0401f99a, 0x02020800, 0x001005d8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x82000540, 0x00000001,
+	0x1c01f000, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x80000580, 0x1c01f000, 0x4933c857, 0x0201f800,
+	0x00100e99, 0x4933c857, 0x4c5c0000, 0x4d340000,
+	0x497a6206, 0x5930b808, 0x59300009, 0x80026d40,
+	0x04020e5f, 0x42001000, 0x0010b519, 0x0401fc60,
+	0x04000009, 0x58c80204, 0x4800bc08, 0x41785000,
+	0x0201f800, 0x00106227, 0x5c026800, 0x5c00b800,
+	0x1c01f000, 0x4978bc08, 0x0401fc17, 0x0401f7fb,
+	0x4803c856, 0x0201f800, 0x00109037, 0x0400000f,
+	0x592c0000, 0x80000d40, 0x04000009, 0x497a5800,
+	0x49425a06, 0x4c040000, 0x0201f800, 0x000202da,
+	0x5c000800, 0x40065800, 0x0401f7f6, 0x49425a06,
+	0x0201f800, 0x000202da, 0x1c01f000, 0x4933c857,
+	0x59300c06, 0x82040580, 0x0000000e, 0x04000004,
+	0x82040580, 0x00000009, 0x04020004, 0x0401ffe5,
+	0x497a6008, 0x80000580, 0x1c01f000, 0x592e6009,
+	0x83300480, 0x0010d1c0, 0x04001016, 0x41580000,
+	0x81300480, 0x04021013, 0x40040000, 0x59300c06,
+	0x80040580, 0x04020012, 0x59300a03, 0x82040580,
+	0x00000007, 0x02020800, 0x001005d8, 0x59300008,
+	0x80000540, 0x02020800, 0x001005d8, 0x0201f800,
+	0x0002077d, 0x42000000, 0x00000000, 0x0401f009,
+	0x42000000, 0x00000008, 0x0401f006, 0x82040580,
+	0x00000007, 0x040207fb, 0x42000000, 0x00000005,
+	0x592c0a06, 0x48065c06, 0x48025a06, 0x0201f000,
+	0x000202da, 0x4c0c0000, 0x4c100000, 0x4c140000,
+	0x4c180000, 0x80001d80, 0x80002580, 0x42003000,
+	0x00000020, 0x82040500, 0x00000001, 0x04000003,
+	0x40080000, 0x800c1c00, 0x400c2800, 0x800c1902,
+	0x80102102, 0x82140500, 0x00000001, 0x04000003,
+	0x82102540, 0x80000000, 0x80040902, 0x80183040,
+	0x040207f1, 0x40100800, 0x400c0000, 0x5c003000,
+	0x5c002800, 0x5c002000, 0x5c001800, 0x1c01f000,
+	0x4c580000, 0x4200b000, 0x00000020, 0x80000540,
+	0x04000018, 0x80041c80, 0x04021016, 0x800810c2,
+	0x80040982, 0x04001006, 0x80041c80, 0x04021005,
+	0x8058b040, 0x040207fa, 0x0401f006, 0x80041c80,
+	0x400c0800, 0x80081000, 0x8058b040, 0x040207f4,
+	0x4c000000, 0x41f00000, 0x82000500, 0xf7ffffff,
+	0x4003e000, 0x5c000000, 0x5c00b000, 0x1c01f000,
+	0x4c000000, 0x41f00000, 0x82000540, 0x08000000,
+	0x0401f7f8, 0x4a0378e8, 0x00000000, 0x4a03c821,
+	0x00000010, 0x4a03c823, 0x00000004, 0x0401f82c,
+	0x4a0378e9, 0x00003a0d, 0x4a0378e8, 0x00000001,
+	0x42000000, 0x00001000, 0x50000000, 0x82000480,
+	0x24220001, 0x04000004, 0x59e00002, 0x84000548,
+	0x4803c002, 0x42000800, 0x00000005, 0x4203a000,
+	0x00007600, 0x42000000, 0x00001000, 0x50000000,
+	0x82000480, 0x24320001, 0x04021003, 0x4a03a005,
+	0xd0000001, 0x59d00006, 0x4a03a005, 0x90000001,
+	0x83d3a400, 0x00000020, 0x80040840, 0x040207fa,
+	0x59e00003, 0x82000500, 0xffffffe0, 0x82000540,
+	0x00008000, 0x4803c003, 0x59c40006, 0x82000500,
+	0xfffcffff, 0x48038806, 0x1c01f000, 0x4d900000,
+	0x4d180000, 0x4a0378e7, 0xaaaaaaaa, 0x4a0378e6,
+	0xaaaaaaaa, 0x4a0378e5, 0xaaaaaaaa, 0x4a0378e4,
+	0xaaaaaaaa, 0x42000800, 0x0000bf00, 0x4a00081a,
+	0x0010b7d4, 0x4a00081b, 0x001010bd, 0x4a00081c,
+	0x001010cd, 0x4a031800, 0x00000000, 0x4a031801,
+	0x0010b544, 0x4a031802, 0x0010b54b, 0x42000800,
+	0x0010b7d7, 0x417a3000, 0x811b20c8, 0x83932400,
+	0x0000bf32, 0x48072000, 0x4a032001, 0x00000000,
+	0x83180400, 0x001070ea, 0x50000000, 0x48032002,
+	0x82040c00, 0x00000003, 0x811a3000, 0x83180480,
+	0x00000005, 0x040017f1, 0x5c023000, 0x5c032000,
+	0x1c01f000, 0x48066004, 0x497a6000, 0x497a6001,
+	0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400,
+	0xa0000000, 0x480378e1, 0x1c01f000, 0x4933c857,
+	0x42000800, 0x80000040, 0x48066004, 0x497a6000,
+	0x59bc00ea, 0x8c000516, 0x040207fe, 0x83300400,
+	0x60000000, 0x480378e1, 0x1c01f000, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x4d300000, 0x4d340000,
+	0x4d2c0000, 0x4d180000, 0x4c5c0000, 0x4c600000,
+	0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000,
+	0x42003000, 0x0000bf2e, 0x581a6001, 0x813261c0,
+	0x0400002c, 0x41302800, 0x4178c000, 0x59300000,
+	0x4c000000, 0x59326809, 0x5930b801, 0x59300406,
+	0x82000d80, 0x00000006, 0x04020003, 0x8d3e7d18,
+	0x04000010, 0x8d3e7d06, 0x04000007, 0x82000580,
+	0x00000003, 0x04020004, 0x59340200, 0x8c00050e,
+	0x04020008, 0x0401f92f, 0x4c0c0000, 0x4c140000,
+	0x0401fb5f, 0x5c002800, 0x5c001800, 0x0401f005,
+	0x41301800, 0x8060c1c0, 0x04020002, 0x400cc000,
+	0x805cb9c0, 0x04000003, 0x405e6000, 0x0401f7e3,
+	0x5c026000, 0x813261c0, 0x04000006, 0x8060c1c0,
+	0x04000002, 0x40602800, 0x4178c000, 0x0401f7d8,
+	0x417a3000, 0x0201f800, 0x001070d8, 0x59926004,
+	0x813261c0, 0x04000023, 0x59326809, 0x4130c000,
+	0x59300001, 0x8000bd40, 0x04000016, 0x40026000,
+	0x40602800, 0x5930b801, 0x59300406, 0x82000d80,
+	0x00000006, 0x0400000e, 0x8d3e7d06, 0x04000007,
+	0x82000580, 0x00000003, 0x04020004, 0x59340200,
+	0x8c00050e, 0x04020006, 0x0401f8dc, 0x4c140000,
+	0x0401fb2f, 0x5c002800, 0x0401f002, 0x41302800,
+	0x405e6000, 0x813261c0, 0x040207eb, 0x8060c1c0,
+	0x04000004, 0x40626000, 0x4178c000, 0x0401f7e7,
+	0x811a3000, 0x83180480, 0x00000005, 0x040017d6,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x5c00c000, 0x5c00b800, 0x5c023000, 0x5c025800,
+	0x5c026800, 0x5c026000, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x1c01f000, 0x4933c857, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x4d340000, 0x4d180000,
+	0x4d900000, 0x42003000, 0x0000bf2e, 0x59326809,
+	0x58182001, 0x40102800, 0x801021c0, 0x04000016,
+	0x41300000, 0x80100580, 0x04000011, 0x58100009,
+	0x81340580, 0x0402000b, 0x40101800, 0x58102001,
+	0x41300000, 0x801021c0, 0x0400000b, 0x80100d80,
+	0x04000007, 0x40101800, 0x58102001, 0x0401f7fa,
+	0x40102800, 0x58102000, 0x0401f7ec, 0x0401f8bd,
+	0x0401f01a, 0x42032000, 0x0000bf32, 0x417a3000,
+	0x59902004, 0x40102800, 0x801021c0, 0x0400000b,
+	0x58100009, 0x81340580, 0x04020008, 0x41300000,
+	0x80100580, 0x0400000c, 0x40102800, 0x58102001,
+	0x801021c0, 0x040207fa, 0x811a3000, 0x83180480,
+	0x00000005, 0x0402100d, 0x83932400, 0x00000010,
+	0x0401f7ec, 0x0401f881, 0x5c032000, 0x5c023000,
+	0x5c026800, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x80000580, 0x1c01f000, 0x0401fb6f, 0x040007f7,
+	0x5c032000, 0x5c023000, 0x5c026800, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x82000540, 0x00000001,
+	0x1c01f000, 0x0201f800, 0x00106c55, 0x4df00000,
+	0x4d300000, 0x4d340000, 0x4d180000, 0x4d2c0000,
+	0x4c5c0000, 0x4c600000, 0x4d900000, 0x4dd00000,
+	0x4da40000, 0x4d140000, 0x42003000, 0x0000bf2e,
+	0x581a6001, 0x813261c0, 0x04000023, 0x41302800,
+	0x5930b800, 0x59326809, 0x59340403, 0x81440580,
+	0x04000006, 0x805cb9c0, 0x0400001b, 0x41302800,
+	0x405e6000, 0x0401f7f7, 0x5930b801, 0x8d3e7d00,
+	0x04000003, 0x0401fb67, 0x0402000e, 0x59300406,
+	0x82000580, 0x00000006, 0x04020003, 0x8d3e7d18,
+	0x04000008, 0x0401f867, 0x4c0c0000, 0x4c140000,
+	0x0401fa97, 0x5c002800, 0x5c001800, 0x0401f002,
+	0x41301800, 0x405e6000, 0x813261c0, 0x040207eb,
+	0x0401f02d, 0x417a3000, 0x0201f800, 0x001070d8,
+	0x59926004, 0x813261c0, 0x04000005, 0x59326809,
+	0x59340403, 0x81440580, 0x04000006, 0x811a3000,
+	0x83180480, 0x00000005, 0x040017f4, 0x0401f01e,
+	0x4130c000, 0x59300001, 0x8000bd40, 0x04000012,
+	0x40026000, 0x40602800, 0x5930b801, 0x8d3e7d00,
+	0x04000003, 0x0401fb3b, 0x0402000a, 0x59300406,
+	0x82000580, 0x00000006, 0x04000006, 0x0401f81b,
+	0x4c140000, 0x0401fa6e, 0x5c002800, 0x0401f002,
+	0x41302800, 0x405e6000, 0x813261c0, 0x040207ef,
+	0x8060c1c0, 0x04000004, 0x40626000, 0x4178c000,
+	0x0401f7eb, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x5c00c000, 0x5c00b800, 0x5c025800,
+	0x5c023000, 0x5c026800, 0x5c026000, 0x5c03e000,
+	0x04000be3, 0x1c01f000, 0x0401fbc8, 0x59900004,
+	0x81300580, 0x04020018, 0x4c140000, 0x0201f800,
+	0x00106dc3, 0x0401fbb8, 0x5c002800, 0x59300001,
+	0x800001c0, 0x04020003, 0x497a680c, 0x1c01f000,
+	0x42003000, 0x0000bf2e, 0x497a6001, 0x58180801,
+	0x800409c0, 0x04020004, 0x48003000, 0x48003001,
+	0x1c01f000, 0x58180800, 0x48000800, 0x48003000,
+	0x1c01f000, 0x59300001, 0x48002801, 0x800001c0,
+	0x04020002, 0x4816680c, 0x497a6001, 0x1c01f000,
+	0x0401fba6, 0x42003000, 0x0000bf2e, 0x58180001,
+	0x81300580, 0x0402001c, 0x59300801, 0x800409c0,
+	0x0400000e, 0x59300000, 0x800001c0, 0x04020005,
+	0x48043001, 0x48043000, 0x497a6001, 0x1c01f000,
+	0x59300000, 0x48000800, 0x48043001, 0x497a6000,
+	0x497a6001, 0x1c01f000, 0x59300800, 0x800409c0,
+	0x04020005, 0x49783001, 0x49783000, 0x497a680c,
+	0x1c01f000, 0x48043001, 0x497a6000, 0x497a680c,
+	0x1c01f000, 0x58180000, 0x81300580, 0x0402000c,
+	0x59300001, 0x800001c0, 0x04020005, 0x48143000,
+	0x49782800, 0x497a680c, 0x1c01f000, 0x48003000,
+	0x48002800, 0x497a6001, 0x1c01f000, 0x59300000,
+	0x800001c0, 0x04020008, 0x59300001, 0x48001801,
+	0x800001c0, 0x04020002, 0x480e680c, 0x497a6001,
+	0x1c01f000, 0x59300801, 0x800409c0, 0x04020006,
+	0x59300800, 0x48042800, 0x497a6000, 0x497a680c,
+	0x1c01f000, 0x59300000, 0x48000800, 0x48042800,
+	0x497a6000, 0x497a6001, 0x1c01f000, 0x0401fb82,
+	0x4df00000, 0x0401f839, 0x040208c4, 0x04020945,
+	0x04020a89, 0x04020005, 0x5c03e000, 0x04000b70,
+	0x80000580, 0x1c01f000, 0x5c03e000, 0x04000b6c,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4d2c0000,
+	0x4d340000, 0x4d300000, 0x41783000, 0x598e6009,
+	0x813261c0, 0x04000021, 0x59300406, 0x82000580,
+	0x00000006, 0x04020004, 0x8d3e7d18, 0x0402000a,
+	0x0401f017, 0x82040580, 0x00000005, 0x04020006,
+	0x8d3e7d16, 0x04000004, 0x59300420, 0x8c000500,
+	0x0402000f, 0x0401fa4e, 0x59300000, 0x4c000000,
+	0x8d3e7d06, 0x04000004, 0x0201f800, 0x001092d7,
+	0x04000005, 0x0401f867, 0x4c180000, 0x0401f9bc,
+	0x5c003000, 0x5c026000, 0x0401f7e2, 0x41303000,
+	0x59326000, 0x0401f7df, 0x5c026000, 0x5c026800,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4c5c0000,
+	0x813261c0, 0x02000800, 0x001005d8, 0x41300000,
+	0x598cb809, 0x41783000, 0x805cb9c0, 0x04000013,
+	0x805c0d80, 0x04000004, 0x405c3000, 0x5818b800,
+	0x0401f7fa, 0x0401f84b, 0x598c000d, 0x81300580,
+	0x02000800, 0x001070b9, 0x59300403, 0x82000580,
+	0x00000042, 0x04020002, 0x497a6007, 0x80000580,
+	0x5c00b800, 0x1c01f000, 0x82000540, 0x00000001,
+	0x5c00b800, 0x1c01f000, 0x0401fb27, 0x4df00000,
+	0x4d2c0000, 0x4d340000, 0x4d300000, 0x41783000,
+	0x598e6009, 0x813261c0, 0x0400002c, 0x59300c06,
+	0x82040580, 0x00000006, 0x04020004, 0x8d3e7d18,
+	0x0402000a, 0x0401f022, 0x82040580, 0x00000005,
+	0x04020006, 0x8d3e7d18, 0x04000004, 0x59300420,
+	0x8c000500, 0x0402001a, 0x59326809, 0x59340403,
+	0x81440580, 0x04020016, 0x8d3e7d00, 0x04000006,
+	0x82040580, 0x00000003, 0x04020011, 0x0401fa35,
+	0x0402000f, 0x0401f9f6, 0x59300000, 0x4c000000,
+	0x8d3e7d06, 0x04000004, 0x0201f800, 0x001092d7,
+	0x04000005, 0x0401f80f, 0x4c180000, 0x0401f964,
+	0x5c003000, 0x5c026000, 0x0401f7d7, 0x41303000,
+	0x59326000, 0x0401f7d4, 0x5c026000, 0x5c026800,
+	0x5c025800, 0x5c03e000, 0x04000ae5, 0x1c01f000,
+	0x59300800, 0x497a6000, 0x0401fac8, 0x801831c0,
+	0x04020009, 0x598c0008, 0x81300580, 0x04020004,
+	0x48031808, 0x48031809, 0x0401f008, 0x48071809,
+	0x0401f006, 0x48043000, 0x598c0008, 0x81300580,
+	0x04020002, 0x481b1808, 0x0401f2ca, 0x4d2c0000,
+	0x4d300000, 0x4d340000, 0x41783000, 0x598e600b,
+	0x813261c0, 0x04000013, 0x8d3e7d06, 0x04000005,
+	0x59326809, 0x59340200, 0x8c00050e, 0x0402000a,
+	0x0401f9bf, 0x59300000, 0x4c000000, 0x0401f853,
+	0x4c180000, 0x0401f932, 0x5c003000, 0x5c026000,
+	0x0401f7f0, 0x41303000, 0x59326000, 0x0401f7ed,
+	0x0201f800, 0x00104773, 0x5c026800, 0x5c026000,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4c5c0000,
+	0x813261c0, 0x02000800, 0x001005d8, 0x41300000,
+	0x598cb80b, 0x41783000, 0x805cb9c0, 0x0400000f,
+	0x805c0d80, 0x04000004, 0x405c3000, 0x5818b800,
+	0x0401f7fa, 0x0401f835, 0x598c000d, 0x81300580,
+	0x02000800, 0x001070b9, 0x497a6007, 0x80000580,
+	0x5c00b800, 0x1c01f000, 0x82000540, 0x00000001,
+	0x5c00b800, 0x1c01f000, 0x0401fa9f, 0x4df00000,
+	0x4d340000, 0x4d300000, 0x4d2c0000, 0x0201f800,
+	0x00020245, 0x02020800, 0x001005d8, 0x41783000,
+	0x598e600b, 0x813261c0, 0x04000014, 0x59300009,
+	0x81340580, 0x0402000e, 0x8d3e7d00, 0x04000003,
+	0x0401f9bc, 0x0402000a, 0x0401f97d, 0x59300000,
+	0x4c000000, 0x0401f811, 0x4c180000, 0x0401f8f0,
+	0x5c003000, 0x5c026000, 0x0401f7ef, 0x41303000,
+	0x59326000, 0x0401f7ec, 0x0201f800, 0x0010479c,
+	0x5c025800, 0x5c026000, 0x5c026800, 0x5c03e000,
+	0x04000a6f, 0x1c01f000, 0x59300800, 0x497a6000,
+	0x0401fa52, 0x801831c0, 0x04020009, 0x598c000a,
+	0x81300580, 0x04020004, 0x4803180a, 0x4803180b,
+	0x0401f008, 0x4807180b, 0x0401f006, 0x48043000,
+	0x598c000a, 0x81300580, 0x04020002, 0x481b180a,
+	0x0401f254, 0x0401fa64, 0x4df00000, 0x4d300000,
+	0x598e6005, 0x813261c0, 0x04000020, 0x59300000,
+	0x4c000000, 0x59300c06, 0x82040580, 0x00000011,
+	0x04020007, 0x833c0500, 0x00001800, 0x04000015,
+	0x8d3e7d16, 0x04020013, 0x0401f009, 0x82040580,
+	0x00000004, 0x04020006, 0x8d3e7d16, 0x04000004,
+	0x59300420, 0x8c000500, 0x0402000a, 0x0201f800,
+	0x0010914e, 0x02000800, 0x0010801c, 0x0201f800,
+	0x00109326, 0x0201f800, 0x0002077d, 0x0401fa31,
+	0x5c026000, 0x0401f7e0, 0x497b1805, 0x497b1804,
+	0x5c026000, 0x5c03e000, 0x04000a31, 0x1c01f000,
+	0x4933c857, 0x4c5c0000, 0x4c600000, 0x813261c0,
+	0x02000800, 0x001005d8, 0x41300000, 0x598cb805,
+	0x405cc000, 0x805cb9c0, 0x04000025, 0x805c0d80,
+	0x04000004, 0x405cc000, 0x5860b800, 0x0401f7fa,
+	0x598c000d, 0x81300580, 0x02000800, 0x001070b9,
+	0x0401fa02, 0x598c0005, 0x805c0580, 0x04020009,
+	0x585c0000, 0x48031805, 0x4978b800, 0x598c0004,
+	0x805c0580, 0x0402000d, 0x497b1804, 0x0401f00b,
+	0x598c0004, 0x805c0580, 0x04020005, 0x48631804,
+	0x4978b800, 0x4978c000, 0x0401f004, 0x585c0000,
+	0x4800c000, 0x4978b800, 0x0401f9fe, 0x80000580,
+	0x5c00c000, 0x5c00b800, 0x1c01f000, 0x82000540,
+	0x00000001, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+	0x4933c857, 0x0401fa04, 0x4df00000, 0x4d2c0000,
+	0x4d340000, 0x4d300000, 0x4c5c0000, 0x4178b800,
+	0x8d3e7d18, 0x0400000d, 0x8d3e7d16, 0x0402000b,
+	0x0201f800, 0x00109037, 0x04000008, 0x0201f800,
+	0x00109597, 0x04020005, 0x592c0207, 0x492fc857,
+	0x8200bd00, 0x0000000f, 0x41783000, 0x598e6005,
+	0x813261c0, 0x04000029, 0x59326809, 0x813669c0,
+	0x04000023, 0x59340403, 0x81440580, 0x04020020,
+	0x59300c06, 0x82040580, 0x00000011, 0x0400001a,
+	0x82040580, 0x00000004, 0x04020004, 0x59300420,
+	0x8c000500, 0x04020016, 0x0201f800, 0x00109037,
+	0x04000008, 0x0201f800, 0x00109597, 0x04020005,
+	0x59300403, 0x82000580, 0x00000043, 0x0400000c,
+	0x0401f8c3, 0x59300000, 0x4c000000, 0x0401f812,
+	0x4c180000, 0x0401f836, 0x5c003000, 0x5c026000,
+	0x0401f7dc, 0x805cb9c0, 0x040207ec, 0x41303000,
+	0x59326000, 0x0401f7d7, 0x5c00b800, 0x5c026000,
+	0x5c026800, 0x5c025800, 0x5c03e000, 0x040009b4,
+	0x1c01f000, 0x59300800, 0x497a6000, 0x0401f997,
+	0x801831c0, 0x04020009, 0x598c0004, 0x81300580,
+	0x04020004, 0x48031804, 0x48031805, 0x0401f008,
+	0x48071805, 0x0401f006, 0x48043000, 0x598c0004,
+	0x81300580, 0x04020002, 0x481b1804, 0x0401f199,
+	0x4943c857, 0x0401f9a8, 0x4df00000, 0x0401fe34,
+	0x0401fecb, 0x5c03e000, 0x04000999, 0x1c01f000,
+	0x4947c857, 0x0401f9a0, 0x4df00000, 0x4d3c0000,
+	0x853e7d00, 0x0401fe75, 0x0401fefc, 0x5c027800,
+	0x5c03e000, 0x0400098e, 0x1c01f000, 0x5c000000,
+	0x4c000000, 0x4803c857, 0x4d340000, 0x4d2c0000,
+	0x59326809, 0x59325808, 0x59300406, 0x82000c80,
+	0x00000012, 0x02021800, 0x001005d8, 0x4933c857,
+	0x4943c857, 0x493fc857, 0x4803c857, 0x0c01f804,
+	0x5c025800, 0x5c026800, 0x1c01f000, 0x00106ae5,
+	0x00106ae7, 0x00106af1, 0x00106b0b, 0x00106ae7,
+	0x00106afb, 0x00106b23, 0x00106ae5, 0x00106ae5,
+	0x00106b36, 0x00106b2d, 0x00106ae5, 0x00106ae5,
+	0x00106ae5, 0x00106ae5, 0x00106ae5, 0x00106b3c,
+	0x00106b3c, 0x0201f800, 0x001005d8, 0x0201f800,
+	0x00109134, 0x02000800, 0x00102074, 0x0201f800,
+	0x00109326, 0x0201f800, 0x0010801c, 0x0201f000,
+	0x00107911, 0x812e59c0, 0x02020800, 0x001005d8,
+	0x5930021d, 0x82000580, 0x00000003, 0x02000800,
+	0x0010912a, 0x0201f000, 0x00107911, 0x0201f800,
+	0x00109037, 0x02000000, 0x00107911, 0x592c1204,
+	0x82081500, 0x000000ff, 0x82080580, 0x00000055,
+	0x02020800, 0x001005d8, 0x49425a06, 0x0201f800,
+	0x000202da, 0x0201f000, 0x00107911, 0x59300004,
+	0x8400055c, 0x48026004, 0x59300007, 0x8c000500,
+	0x02020800, 0x00100e99, 0x0201f800, 0x00109037,
+	0x0400000d, 0x4a025a04, 0x00000103, 0x49425a06,
+	0x497a5c09, 0x0201f800, 0x001091c6, 0x0201f800,
+	0x0010a693, 0x0201f800, 0x000202da, 0x0201f800,
+	0x0010912a, 0x0201f000, 0x00107911, 0x59300007,
+	0x8c000500, 0x02020800, 0x00100e99, 0x0201f800,
+	0x00109037, 0x02020800, 0x0010a3ef, 0x0201f000,
+	0x00107911, 0x0201f800, 0x00109037, 0x04000005,
+	0x49425a06, 0x497a5c09, 0x0201f800, 0x000202da,
+	0x0201f000, 0x00107911, 0x0201f800, 0x00109037,
+	0x02020800, 0x0010664f, 0x0201f000, 0x00107911,
+	0x0201f800, 0x00109037, 0x04000004, 0x49425a06,
+	0x0201f800, 0x000202da, 0x59325817, 0x0201f800,
+	0x001007fd, 0x0201f000, 0x00107911, 0x598c000d,
+	0x81300580, 0x04000003, 0x497a6007, 0x1c01f000,
+	0x59c40004, 0x82000500, 0x0000000c, 0x04000005,
+	0x4a038804, 0x0000000c, 0x497b2807, 0x0401f00a,
+	0x0401facd, 0x59300403, 0x82000d80, 0x00000040,
+	0x04000004, 0x82000580, 0x00000042, 0x04020002,
+	0x497a6007, 0x0201f800, 0x001070b9, 0x80000580,
+	0x1c01f000, 0x59300804, 0x8c040d3e, 0x04020004,
+	0x82000540, 0x00000001, 0x0401f005, 0x4933c857,
+	0x84040d3e, 0x48066004, 0x80000580, 0x1c01f000,
+	0x59300804, 0x8c040d20, 0x04020004, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4933c857, 0x4d380000,
+	0x59300804, 0x84040d20, 0x48066004, 0x42027000,
+	0x00000049, 0x59300203, 0x82000580, 0x00000003,
+	0x04000003, 0x42027000, 0x00000013, 0x0201f800,
+	0x000207a1, 0x80000580, 0x5c027000, 0x1c01f000,
+	0x59300017, 0x81480580, 0x04020003, 0x59300018,
+	0x814c0580, 0x1c01f000, 0x4d2c0000, 0x4d300000,
+	0x0401f8c9, 0x4df00000, 0x0201f800, 0x00106062,
+	0x59900001, 0x82000500, 0x00000003, 0x0c01f001,
+	0x00106bba, 0x00106b9a, 0x00106b98, 0x00106b98,
+	0x0201f800, 0x001005d8, 0x59926004, 0x0401f88e,
+	0x813261c0, 0x0400001d, 0x59300004, 0x8c000516,
+	0x04000004, 0x59325808, 0x497a5808, 0x497a5809,
+	0x0401f88e, 0x59300001, 0x800001c0, 0x0400000e,
+	0x497a6001, 0x42003000, 0x0000bf2e, 0x58180801,
+	0x800409c0, 0x04020004, 0x48003001, 0x48003000,
+	0x0401f00a, 0x58180800, 0x48000800, 0x48003000,
+	0x0401f006, 0x59300809, 0x800409c0, 0x02000800,
+	0x001005d8, 0x4978080c, 0x5c03e000, 0x04000890,
+	0x5c026000, 0x5c025800, 0x1c01f000, 0x4d300000,
+	0x497b2807, 0x0401f894, 0x4df00000, 0x598c0000,
+	0x82000500, 0x00000007, 0x4803c857, 0x0c01f001,
+	0x00106bef, 0x00106bd2, 0x00106bdb, 0x00106bdf,
+	0x00106bea, 0x00106bef, 0x00106bd0, 0x00106bd0,
+	0x0201f800, 0x001005d8, 0x598c000d, 0x80026540,
+	0x04000004, 0x0401f81e, 0x02020800, 0x001005d8,
+	0x0201f800, 0x001070b9, 0x0401f015, 0x0401f827,
+	0x0201f800, 0x001070b9, 0x0401f011, 0x598c000d,
+	0x80026540, 0x0400000e, 0x0401f838, 0x04000004,
+	0x0401f80f, 0x04000002, 0x0401f81c, 0x0201f800,
+	0x001070b9, 0x0401f006, 0x0401f830, 0x02020800,
+	0x001005d8, 0x0201f800, 0x001070b9, 0x5c03e000,
+	0x0400085b, 0x5c026000, 0x1c01f000, 0x598c0009,
+	0x81300580, 0x0402000c, 0x0401f84e, 0x0401f83b,
+	0x59300000, 0x800001c0, 0x04000004, 0x48031809,
+	0x497a6000, 0x0401f003, 0x497b1809, 0x497b1808,
+	0x80000580, 0x1c01f000, 0x4d2c0000, 0x59300406,
+	0x82000580, 0x00000003, 0x04020012, 0x598c000b,
+	0x81300580, 0x0402000f, 0x0401f83a, 0x59325808,
+	0x497a5808, 0x497a5809, 0x0401f824, 0x59300000,
+	0x800001c0, 0x04000004, 0x4803180b, 0x497a6000,
+	0x0401f003, 0x497b180a, 0x497b180b, 0x80000580,
+	0x5c025800, 0x1c01f000, 0x598c0005, 0x81300580,
+	0x0402000c, 0x0401f827, 0x0401f814, 0x59300000,
+	0x800001c0, 0x04000004, 0x48031805, 0x497a6000,
+	0x0401f003, 0x497b1805, 0x497b1804, 0x80000580,
+	0x1c01f000, 0x4a032001, 0x00000000, 0x497b2004,
+	0x497b2005, 0x59900006, 0x82000500, 0x0000ffff,
+	0x48032006, 0x1c01f000, 0x4c040000, 0x59300004,
+	0x82000500, 0x7ffeffff, 0x48026004, 0x59bc00e4,
+	0x8c000514, 0x04000009, 0x42000800, 0x0000bf00,
+	0x58040012, 0x81300580, 0x04020004, 0x49780812,
+	0x4a0378e4, 0x00000800, 0x5c000800, 0x1c01f000,
+	0x4803c856, 0x598c000c, 0x80000540, 0x04000003,
+	0x80000040, 0x4803180c, 0x1c01f000, 0x59bc00ea,
+	0x82000500, 0x00000007, 0x82000580, 0x00000003,
+	0x04020004, 0x4803c856, 0x4a0378e8, 0x00000001,
+	0x1c01f000, 0x59bc00ea, 0x82000500, 0x00000007,
+	0x82000580, 0x00000001, 0x04020011, 0x4803c856,
+	0x42000800, 0x00000000, 0x0401f80e, 0x42000800,
+	0x00001000, 0x59bc00ea, 0x82000500, 0x00000007,
+	0x82000580, 0x00000003, 0x04000005, 0x80040840,
+	0x040207f9, 0x0201f800, 0x001005d8, 0x1c01f000,
+	0x59bc00ea, 0x82000500, 0x00000007, 0x82000580,
+	0x00000001, 0x02020800, 0x001005d8, 0x59bc00ea,
+	0x8c000516, 0x040207fe, 0x480778e1, 0x1c01f000,
+	0x59bc00ea, 0x8c000516, 0x040207fe, 0x480778e1,
+	0x59bc00ea, 0x8c000516, 0x040207fe, 0x480b78e1,
+	0x1c01f000, 0x82000d00, 0x80000018, 0x02020800,
+	0x001005d0, 0x0201f800, 0x001005d8, 0x00106c97,
+	0x00106d3b, 0x00106d55, 0x00106c97, 0x00106c99,
+	0x00106cba, 0x00106cd9, 0x00106d0d, 0x00106c97,
+	0x00106d39, 0x00106c97, 0x00106c97, 0x00106c97,
+	0x00106c97, 0x00106c97, 0x00106c97, 0x0201f800,
+	0x001005d8, 0x4d300000, 0x4d900000, 0x4dd00000,
+	0x4da40000, 0x4d140000, 0x0201f800, 0x001070d8,
+	0x59bc00ea, 0x8c000510, 0x040007fe, 0x59be60e0,
+	0x59300004, 0x8c000520, 0x04000011, 0x82000500,
+	0xfffefeff, 0x48026004, 0x4a026203, 0x00000003,
+	0x0401ffa9, 0x0201f800, 0x00100fd0, 0x5c022800,
+	0x5c034800, 0x5c03a000, 0x5c032000, 0x5c026000,
+	0x4a0378e4, 0x00000008, 0x0401f795, 0x84000510,
+	0x48026004, 0x0401f7f6, 0x4d300000, 0x4d900000,
+	0x4dd00000, 0x4da40000, 0x4d140000, 0x0201f800,
+	0x001070d8, 0x59bc00ea, 0x8c000510, 0x040007fe,
+	0x59be60e0, 0x59300004, 0x8c000520, 0x0400000f,
+	0x82000500, 0xfffefeff, 0x48026004, 0x0401ff8a,
+	0x0201f800, 0x0010100e, 0x5c022800, 0x5c034800,
+	0x5c03a000, 0x5c032000, 0x5c026000, 0x4a0378e4,
+	0x00000008, 0x0401f776, 0x84000510, 0x48026004,
+	0x0401f7f6, 0x4d300000, 0x4d2c0000, 0x4d340000,
+	0x4da40000, 0x4cd00000, 0x59bc00ea, 0x8c000510,
+	0x040007fe, 0x59be60e0, 0x813261c0, 0x02000800,
+	0x001005d8, 0x59300004, 0x8c000520, 0x0400001d,
+	0x82000500, 0xfffefeff, 0x48026004, 0x59326809,
+	0x42034800, 0x0010b544, 0x04011000, 0x4a03c840,
+	0x0010b54b, 0x4a03c842, 0x00000012, 0x04011000,
+	0x4a03c840, 0x0010b55d, 0x4a03c842, 0x000000ff,
+	0x04011000, 0x4a03c840, 0x0010b65c, 0x4a03c842,
+	0x000000ff, 0x0401fbf2, 0x5c01a000, 0x5c034800,
+	0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000,
+	0x84000510, 0x48026004, 0x5c01a000, 0x5c034800,
+	0x5c026800, 0x5c025800, 0x5c026000, 0x1c01f000,
+	0x1c01f000, 0x4d300000, 0x4d2c0000, 0x4d340000,
+	0x4cd00000, 0x4d900000, 0x4dd00000, 0x4da40000,
+	0x4d140000, 0x0401fbc3, 0x59bc00ea, 0x8c000510,
+	0x040007fe, 0x59be60e0, 0x813261c0, 0x02000800,
+	0x001005d8, 0x59300004, 0x8c000520, 0x0400000f,
+	0x82000500, 0xfffefeff, 0x48026004, 0x0201f800,
+	0x0010783a, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x5c01a000, 0x5c026800, 0x5c025800,
+	0x5c026000, 0x1c01f000, 0x84000510, 0x48026004,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x5c01a000, 0x5c026800, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x0201f800, 0x001005d8, 0x4d300000,
+	0x4d380000, 0x42000000, 0x0010b8c4, 0x0201f800,
+	0x0010aa47, 0x0401ff14, 0x598e600d, 0x59c40004,
+	0x8c000506, 0x04000004, 0x0401f8db, 0x4a038804,
+	0x00000008, 0x813261c0, 0x04000006, 0x0401fb87,
+	0x42027000, 0x00000014, 0x0201f800, 0x000207a1,
+	0x4a0378e4, 0x00000002, 0x5c027000, 0x5c026000,
+	0x0401f6f7, 0x4d180000, 0x4d300000, 0x4d380000,
+	0x4d900000, 0x4dd00000, 0x4da40000, 0x4d140000,
+	0x0401fef9, 0x417a3000, 0x59c40804, 0x83180400,
+	0x0010709f, 0x50000000, 0x80040500, 0x0400001b,
+	0x42000000, 0x0010b8c5, 0x0201f800, 0x0010aa47,
+	0x0401fb70, 0x59926004, 0x0401f859, 0x83180400,
+	0x0010709f, 0x50000000, 0x48038804, 0x813261c0,
+	0x0400000a, 0x59300004, 0x8c00050c, 0x04020003,
+	0x4a026203, 0x00000003, 0x42027000, 0x0000004a,
+	0x0201f800, 0x000207a1, 0x59c40004, 0x82000500,
+	0x00f80000, 0x04000005, 0x811a3000, 0x83180480,
+	0x00000005, 0x040017dd, 0x4a0378e4, 0x00000008,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x5c027000, 0x5c026000, 0x5c023000, 0x0401f6c0,
+	0x4d2c0000, 0x4d340000, 0x59326809, 0x598c0800,
+	0x82040580, 0x00000004, 0x04020004, 0x838c1400,
+	0x00000005, 0x0401f00c, 0x82040580, 0x00000001,
+	0x04020004, 0x838c1400, 0x00000009, 0x0401f006,
+	0x82040580, 0x00000002, 0x04020022, 0x838c1400,
+	0x0000000b, 0x41306800, 0x58340000, 0x80007d40,
+	0x0400001c, 0x583c0009, 0x81340580, 0x04020006,
+	0x403c6800, 0x583c0000, 0x80007d40, 0x040207fa,
+	0x0401f014, 0x4933c857, 0x483fc857, 0x583c0000,
+	0x48006800, 0x49307800, 0x443c1000, 0x80000580,
+	0x4803180d, 0x4803180f, 0x598c0000, 0x82000580,
+	0x00000003, 0x04000003, 0x4a031800, 0x00000000,
+	0x80000580, 0x5c026800, 0x5c025800, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fb, 0x491bc857,
+	0x59c80840, 0x82040540, 0x00000010, 0x48039040,
+	0x59c41008, 0x82080500, 0xffffff7f, 0x48038808,
+	0x4c040000, 0x4c080000, 0x0401fabb, 0x04020007,
+	0x0401fabf, 0x04000022, 0x48038804, 0x0201f800,
+	0x0010107a, 0x0401f042, 0x4a038803, 0x00000008,
+	0x59c40003, 0x82000500, 0x00000003, 0x040007fd,
+	0x8c000502, 0x04020007, 0x0401fab1, 0x04000014,
+	0x48038804, 0x0201f800, 0x0010107a, 0x0401f034,
+	0x59c80040, 0x8400056a, 0x48039040, 0x59c80040,
+	0x8c00052a, 0x040207fe, 0x59c40005, 0x82000500,
+	0xc0000000, 0x04000006, 0x59c400a3, 0x84000540,
+	0x480388a3, 0x4a038805, 0xc0000000, 0x0201f800,
+	0x0010101d, 0x4a03a005, 0x30000000, 0x59d00006,
+	0x4a03a005, 0x30000000, 0x59900006, 0x82000500,
+	0xffff0000, 0x48032006, 0x59d00005, 0x8c000504,
+	0x040207fe, 0x42000800, 0x00007600, 0x83180540,
+	0x60000000, 0x480008a1, 0x811800dc, 0x59c80840,
+	0x80040540, 0x48039040, 0x82000540, 0x00003000,
+	0x48039040, 0x59c80040, 0x82000500, 0x00003000,
+	0x040207fd, 0x0201f800, 0x00101068, 0x83180400,
+	0x0010709f, 0x50000000, 0x48038804, 0x80000580,
+	0x4df00000, 0x0201f800, 0x00106062, 0x5c03e000,
+	0x5c001000, 0x5c000800, 0x480b8808, 0x48079040,
+	0x1c01f000, 0x4803c856, 0x59c80840, 0x82040540,
+	0x00000010, 0x48039040, 0x59c41008, 0x82080500,
+	0xffffff7f, 0x48038808, 0x4c040000, 0x4c080000,
+	0x59c40004, 0x82000500, 0x00000003, 0x04020010,
+	0x59c40004, 0x82000500, 0x0000000c, 0x04000005,
+	0x4a038804, 0x0000000c, 0x8c000504, 0x0401f025,
+	0x59c80040, 0x8400056e, 0x48039040, 0x59c80040,
+	0x8c00052e, 0x040207fe, 0x0401f01e, 0x4a038803,
+	0x00000008, 0x59c40003, 0x82000500, 0x00000003,
+	0x040007fd, 0x8c000502, 0x04020006, 0x59c40004,
+	0x4a038804, 0x0000000c, 0x8c000504, 0x0401f011,
+	0x59c80040, 0x8400056a, 0x48039040, 0x59c80040,
+	0x8c00052a, 0x040207fe, 0x59c40005, 0x82000500,
+	0xc0000000, 0x04000007, 0x59c400a3, 0x84000540,
+	0x480388a3, 0x4a038805, 0xc0000000, 0x80000580,
+	0x497b2807, 0x5c001000, 0x5c000800, 0x480b8808,
+	0x48079040, 0x1c01f000, 0x4933c857, 0x4d900000,
+	0x4dd00000, 0x4da40000, 0x4d140000, 0x0401fdee,
+	0x4df00000, 0x0401fa6f, 0x59900004, 0x800001c0,
+	0x04000011, 0x81300580, 0x0402000f, 0x59300004,
+	0x84000520, 0x48026004, 0x0401ff51, 0x04020009,
+	0x5c03e000, 0x04000dd6, 0x80000580, 0x5c022800,
+	0x5c034800, 0x5c03a000, 0x5c032000, 0x1c01f000,
+	0x0401fd0e, 0x42027000, 0x00000049, 0x59300004,
+	0x84000520, 0x48026004, 0x8c00050c, 0x02020800,
+	0x000207a1, 0x5c03e000, 0x04000dc5, 0x82000540,
+	0x00000001, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x1c01f000, 0x4933c857, 0x0401fdc6,
+	0x4df00000, 0x598c000d, 0x80026540, 0x04000012,
+	0x59300004, 0x84000520, 0x48026004, 0x0401ff8a,
+	0x04000017, 0x0401fd26, 0x42027000, 0x00000013,
+	0x59300004, 0x8c00050c, 0x02020800, 0x000207a1,
+	0x5c03e000, 0x04000daa, 0x82000540, 0x00000001,
+	0x1c01f000, 0x836c1580, 0x00000001, 0x040007f9,
+	0x836c1580, 0x00000004, 0x040007f6, 0x42001000,
+	0x00104148, 0x0201f800, 0x00105f90, 0x5c03e000,
+	0x04000d9b, 0x80000580, 0x1c01f000, 0x4d300000,
+	0x4d180000, 0x4d3c0000, 0x0401fd9f, 0x4df00000,
+	0x4a0378e4, 0x0000000f, 0x0401f9ff, 0x417a3000,
+	0x59926004, 0x813261c0, 0x04000010, 0x417a7800,
+	0x0201f800, 0x001048d9, 0x0400000a, 0x59300c06,
+	0x82040580, 0x00000003, 0x04000004, 0x82040580,
+	0x00000006, 0x04020003, 0x42027800, 0x00000002,
+	0x0201f800, 0x00108be3, 0x811a3000, 0x83180480,
+	0x00000005, 0x040017eb, 0x42000800, 0x00000040,
+	0x0201f800, 0x00101345, 0x4a0378e4, 0x0000000a,
+	0x5c03e000, 0x04000d72, 0x5c027800, 0x5c023000,
+	0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0401fd75, 0x4df00000, 0x59c80840, 0x82040540,
+	0x00000010, 0x48039040, 0x59c41008, 0x82080500,
+	0xffffff7f, 0x48038808, 0x4c040000, 0x4c080000,
+	0x42001000, 0x00000003, 0x0401f9c2, 0x598e600d,
+	0x813261c0, 0x04020f9d, 0x040009c7, 0x497b2807,
+	0x0401f80a, 0x5c001000, 0x5c000800, 0x480b8808,
+	0x84040d74, 0x48079040, 0x5c03e000, 0x04000d50,
+	0x5c026000, 0x1c01f000, 0x4d380000, 0x4d180000,
+	0x4d300000, 0x4d900000, 0x4dd00000, 0x4da40000,
+	0x4d140000, 0x59c41004, 0x480bc857, 0x82080500,
+	0x00003ff0, 0x04000025, 0x417a3000, 0x4c080000,
+	0x0201f800, 0x00106062, 0x5c001000, 0x82080500,
+	0x00000210, 0x04020004, 0x811a3000, 0x80081102,
+	0x0401f7f7, 0x0401f9c3, 0x59926004, 0x4933c857,
+	0x813261c0, 0x04020005, 0x59c400a3, 0x8c00051a,
+	0x02000800, 0x001005d8, 0x0401fea5, 0x04000009,
+	0x0401fc6a, 0x42027000, 0x00000049, 0x59300004,
+	0x8c00050c, 0x02020800, 0x000207a1, 0x0401f007,
+	0x42027000, 0x0000004a, 0x4a026203, 0x00000003,
+	0x0201f800, 0x000207a1, 0x5c022800, 0x5c034800,
+	0x5c03a000, 0x5c032000, 0x5c026000, 0x5c023000,
+	0x5c027000, 0x1c01f000, 0x4d300000, 0x4d180000,
+	0x4d900000, 0x0401fd1c, 0x42001000, 0x00000000,
+	0x598c0000, 0x82000580, 0x00000005, 0x04000971,
+	0x417a3000, 0x811b20c8, 0x83932400, 0x0000bf32,
+	0x59900001, 0x82000580, 0x00000001, 0x0402000d,
+	0x42000800, 0x000007d0, 0x59926004, 0x59300011,
+	0x82000500, 0xfff00000, 0x80000540, 0x04000003,
+	0x42000800, 0x00001b58, 0x0201f800, 0x00106054,
+	0x811a3000, 0x83180480, 0x00000005, 0x040017ea,
+	0x59c81040, 0x84081534, 0x480b9040, 0x0401fcf0,
+	0x5c032000, 0x5c023000, 0x5c026000, 0x1c01f000,
+	0x4933c857, 0x4d900000, 0x4dd00000, 0x4da40000,
+	0x4d140000, 0x4d380000, 0x0401fcef, 0x4df00000,
+	0x59300004, 0x8c00053e, 0x04020007, 0x8c000520,
+	0x04000025, 0x0201f800, 0x00106b6c, 0x04000022,
+	0x0401f02a, 0x598c000d, 0x81300580, 0x04000011,
+	0x0201f800, 0x00108cd6, 0x04020024, 0x0401f918,
+	0x04000022, 0x48038804, 0x0401f95e, 0x0201f800,
+	0x0010107a, 0x0401fc0d, 0x42027000, 0x00000049,
+	0x59300004, 0x8c00050c, 0x0402000d, 0x0401f00e,
+	0x59c40004, 0x8c000504, 0x04000014, 0x4a038804,
+	0x00000004, 0x0401fc36, 0x42027000, 0x00000013,
+	0x59300004, 0x8c00050c, 0x04000003, 0x0201f800,
+	0x000207a1, 0x5c03e000, 0x04000cb9, 0x5c027000,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x80000580, 0x1c01f000, 0x5c03e000, 0x04000cb0,
+	0x5c027000, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x82000540, 0x00000001, 0x1c01f000,
+	0x497b2807, 0x0401fcb0, 0x59c400af, 0x800001c0,
+	0x04020004, 0x0401fca2, 0x0201f000, 0x001014fb,
+	0x598c000f, 0x82001480, 0x00000002, 0x04021007,
+	0x80000000, 0x4803180f, 0x80000580, 0x0201f800,
+	0x0010604d, 0x0400000e, 0x0401fed8, 0x0402000c,
+	0x0401fdd4, 0x0400000a, 0x0201f800, 0x0010a9c7,
+	0x0401f916, 0x4d380000, 0x42027000, 0x00000014,
+	0x0201f800, 0x000207a1, 0x5c027000, 0x0401fc88,
+	0x0201f000, 0x001014fb, 0x4d900000, 0x4dd00000,
+	0x4da40000, 0x4d140000, 0x4d300000, 0x0201f800,
+	0x00106062, 0x0401fc88, 0x59c400af, 0x800001c0,
+	0x04000027, 0x0401f907, 0x59926004, 0x4933c857,
+	0x59300004, 0x8c000516, 0x0400000b, 0x0401fe8b,
+	0x0402001f, 0x0201f800, 0x00106b8a, 0x0401fc70,
+	0x42000800, 0x80000804, 0x0201f800, 0x00106721,
+	0x0401f017, 0x42001800, 0x00007530, 0x0401f8c1,
+	0x04020004, 0x0201f800, 0x00106052, 0x0401f010,
+	0x0401fe7a, 0x0402000e, 0x0201f800, 0x0010a9c7,
+	0x59300004, 0x8c00050c, 0x04020003, 0x4a026203,
+	0x00000003, 0x4d380000, 0x42027000, 0x0000004a,
+	0x0201f800, 0x000207a1, 0x5c027000, 0x0401fc54,
+	0x5c026000, 0x5c022800, 0x5c034800, 0x5c03a000,
+	0x5c032000, 0x0201f000, 0x001014fb, 0x4d900000,
+	0x4dd00000, 0x4da40000, 0x4d140000, 0x4d300000,
+	0x4d2c0000, 0x0401fc50, 0x0401f8d2, 0x59926004,
+	0x4933c857, 0x0401f880, 0x04000016, 0x0201f800,
+	0x00106062, 0x813261c0, 0x04000034, 0x59325808,
+	0x812e59c0, 0x02000800, 0x001005d8, 0x0201f800,
+	0x0010513b, 0x0402001d, 0x592c0208, 0x84000550,
+	0x48025a08, 0x0201f800, 0x00105258, 0x04020027,
+	0x592c0208, 0x84000510, 0x48025a08, 0x0401f023,
+	0x0201f800, 0x00106052, 0x0401f020, 0x0201f800,
+	0x0010a9c7, 0x0401fd9e, 0x592c0208, 0x84000550,
+	0x48025a08, 0x4d380000, 0x42027000, 0x0000004a,
+	0x4a026203, 0x00000003, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x0401f011, 0x59900006, 0x82000500,
+	0xffff0000, 0x040207ee, 0x59c408af, 0x82040480,
+	0x000003e8, 0x040217ea, 0x59900006, 0x82000400,
+	0x00010000, 0x48032006, 0x0201f800, 0x00106052,
+	0x0201f800, 0x0010411d, 0x5c025800, 0x5c026000,
+	0x5c022800, 0x5c034800, 0x5c03a000, 0x5c032000,
+	0x0401f403, 0x4d300000, 0x4d2c0000, 0x0401fc0a,
+	0x598e600d, 0x4933c857, 0x59c41004, 0x8c081500,
+	0x04000007, 0x0201f800, 0x0010513b, 0x04020007,
+	0x0201f800, 0x00105258, 0x0402002f, 0x0201f800,
+	0x0010604d, 0x0401f02c, 0x598c000f, 0x80000540,
+	0x04020011, 0x59c408af, 0x82040480, 0x000003e8,
+	0x0402100d, 0x598c080f, 0x80040800, 0x4807180f,
+	0x0201f800, 0x0010604d, 0x42000000, 0x0010b852,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x0010411d,
+	0x0401f019, 0x0401fdb4, 0x813261c0, 0x04020003,
+	0x0401f849, 0x0401f014, 0x0201f800, 0x0010a9c7,
+	0x59300406, 0x82000580, 0x00000003, 0x04020007,
+	0x59325808, 0x812e59c0, 0x04000004, 0x592c0208,
+	0x84000550, 0x48025a08, 0x0401f854, 0x4d380000,
+	0x42027000, 0x00000014, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x5c025800, 0x5c026000, 0x0201f000,
+	0x00106c4b, 0x59c40804, 0x83180400, 0x00107095,
+	0x50000000, 0x80040500, 0x1c01f000, 0x59c40804,
+	0x83180400, 0x0010709a, 0x50000000, 0x80040500,
+	0x1c01f000, 0x00000210, 0x00000420, 0x00000840,
+	0x00001080, 0x00002100, 0x00004000, 0x00008000,
+	0x00010000, 0x00020000, 0x00040000, 0x00080000,
+	0x00100000, 0x00200000, 0x00400000, 0x00800000,
+	0x59900806, 0x80040120, 0x800c0480, 0x04021004,
+	0x82000540, 0x00000001, 0x0401f005, 0x82040c00,
+	0x00010000, 0x48072006, 0x80000580, 0x1c01f000,
+	0x480bc857, 0x0201f800, 0x00106c55, 0x4df00000,
+	0x480b1800, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x1c01f000, 0x4803c856, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x497b180d, 0x497b1803, 0x497b180e,
+	0x497b180f, 0x497b1810, 0x598c0000, 0x82000580,
+	0x00000003, 0x04000009, 0x836c0580, 0x00000002,
+	0x04020004, 0x4a031800, 0x00000005, 0x0401f003,
+	0x4a031800, 0x00000000, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x1c01f000, 0x59300004, 0x8c00050c,
+	0x04020003, 0x4a026203, 0x00000001, 0x1c01f000,
+	0x83180480, 0x00000005, 0x02021800, 0x001005d8,
+	0x491bc857, 0x811b20c8, 0x83932400, 0x0000bf32,
+	0x811ba0ca, 0x83d3a400, 0x00007600, 0x83180400,
+	0x001070ea, 0x50034800, 0x811a28c2, 0x83162c00,
+	0x00006100, 0x1c01f000, 0x0010b75b, 0x0010b772,
+	0x0010b789, 0x0010b7a0, 0x0010b7b7, 0x4933c857,
+	0x59300406, 0x82000c80, 0x00000012, 0x04021016,
+	0x4803c857, 0x04011000, 0x0c01f001, 0x00107109,
+	0x00107198, 0x001074d1, 0x00107556, 0x00107198,
+	0x001074d1, 0x00107556, 0x00107109, 0x00107198,
+	0x00107109, 0x00107109, 0x00107109, 0x00107109,
+	0x00107109, 0x00107109, 0x00107109, 0x0010710f,
+	0x0010710f, 0x0201f800, 0x00106c55, 0x0201f800,
+	0x00106bbf, 0x0201f000, 0x00106c4b, 0x42001000,
+	0x0010b7f6, 0x50081000, 0x4930100c, 0x58080002,
+	0x82000580, 0x00000100, 0x04020032, 0x59325808,
+	0x812e59c0, 0x02000800, 0x001005d8, 0x59326809,
+	0x813669c0, 0x04000019, 0x592c040b, 0x82000500,
+	0x0000e000, 0x04000003, 0x0401fba8, 0x0401f002,
+	0x0401fb98, 0x42001000, 0x0010b7f6, 0x50081000,
+	0x4930100b, 0x492c100a, 0x82d00400, 0x00000006,
+	0x48001003, 0x592c000d, 0x80000104, 0x48001004,
+	0x592c000e, 0x48001007, 0x592c000f, 0x48001008,
+	0x0201f000, 0x00100858, 0x42026800, 0x0010be0d,
+	0x592c080a, 0x48066802, 0x82040500, 0x00ffff00,
+	0x04000007, 0x497a6a12, 0x59a81010, 0x82081500,
+	0x00ffff00, 0x80080580, 0x040207dc, 0x82040d00,
+	0x000000ff, 0x800408d0, 0x48066a12, 0x0401f7d7,
+	0x1c01f000, 0x4d2c0000, 0x4d300000, 0x4c580000,
+	0x4c540000, 0x4c500000, 0x5832580a, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x58300002, 0x4a006002,
+	0x00000100, 0x82000580, 0x00000100, 0x0402001c,
+	0x5830000b, 0x5832600c, 0x81300580, 0x04020010,
+	0x0401f828, 0x04020010, 0x592c080d, 0x80040904,
+	0x4004b000, 0x4200a000, 0x0010b54b, 0x4050a800,
+	0x0201f800, 0x0010ab28, 0x42001000, 0x0000dc00,
+	0x0201f800, 0x001078bc, 0x0401f003, 0x0401f819,
+	0x04000fa3, 0x5c00a000, 0x5c00a800, 0x5c00b000,
+	0x5c026000, 0x5c025800, 0x1c01f000, 0x5830000b,
+	0x5832600c, 0x81300580, 0x040207f5, 0x0401f80d,
+	0x040207f5, 0x0201f800, 0x001068d3, 0x02020800,
+	0x001005d8, 0x4a025a06, 0x00000002, 0x0201f800,
+	0x000202da, 0x0201f800, 0x00107911, 0x0401f7ea,
+	0x0201f800, 0x00106c55, 0x4df00000, 0x598c000d,
+	0x81300580, 0x04020009, 0x598c0005, 0x81300580,
+	0x04020006, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x80000580, 0x1c01f000, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x82000540, 0x00000001, 0x1c01f000,
+	0x59300403, 0x82000c80, 0x00000056, 0x02021800,
+	0x001005d8, 0x4803c857, 0x0c01f001, 0x00107302,
+	0x0010731d, 0x0010732e, 0x00107431, 0x001073f1,
+	0x001073f5, 0x00107406, 0x0010741a, 0x0010740f,
+	0x0010741a, 0x00107455, 0x0010741a, 0x00107497,
+	0x0010741a, 0x001074a5, 0x0010741a, 0x0010740f,
+	0x0010741a, 0x001074a9, 0x001071f5, 0x001071f5,
+	0x001071f5, 0x001071f5, 0x001071f5, 0x001071f5,
+	0x001071f5, 0x001071f5, 0x001071f5, 0x001071f5,
+	0x001071f5, 0x00107574, 0x00107593, 0x0010759d,
+	0x001071f5, 0x001075b3, 0x00107406, 0x001071f5,
+	0x00107406, 0x0010741a, 0x001071f5, 0x0010732e,
+	0x00107431, 0x001071f5, 0x00107603, 0x0010741a,
+	0x001071f5, 0x00107613, 0x0010741a, 0x001071f5,
+	0x0010740f, 0x001072f3, 0x001071f7, 0x001071f5,
+	0x0010762a, 0x0010765d, 0x001076d7, 0x001071f5,
+	0x001076e7, 0x00107404, 0x001076da, 0x001071f5,
+	0x001075bf, 0x00107700, 0x001071f5, 0x00107735,
+	0x00107788, 0x001071f5, 0x0010720c, 0x00107265,
+	0x00107272, 0x001071f5, 0x00107406, 0x001071f5,
+	0x001072b9, 0x001072c4, 0x001071f5, 0x001071f5,
+	0x00107220, 0x00107245, 0x001077c7, 0x00107808,
+	0x0010782e, 0x001071f5, 0x001071f5, 0x001071f5,
+	0x001077fc, 0x0201f800, 0x001005d8, 0x0401fac5,
+	0x59325808, 0x592c0009, 0x4801a006, 0x592c000a,
+	0x4801a007, 0x592c000b, 0x4801a008, 0x592c000c,
+	0x4801a009, 0x592c000d, 0x4801a00a, 0x4979a00b,
+	0x592c0809, 0x82040d00, 0x00000fff, 0x80040904,
+	0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+	0x4a026202, 0x0000ffff, 0x0401faae, 0x4d2c0000,
+	0x4a01a006, 0x05000000, 0x59325808, 0x592c0009,
+	0x4801a007, 0x592c000a, 0x4801a008, 0x592c000b,
+	0x4801a009, 0x42000800, 0x00000004, 0x42001000,
+	0x0000dc00, 0x5c025800, 0x0201f000, 0x001078bc,
+	0x4c580000, 0x4c500000, 0x4c540000, 0x4d2c0000,
+	0x0401fa98, 0x59325808, 0x5930040b, 0x800000c2,
+	0x4200a800, 0x0010b54b, 0x592cb205, 0x832ca400,
+	0x00000006, 0x0201f800, 0x0010ab17, 0x40580000,
+	0x8054ac00, 0x592c0001, 0x80000540, 0x04000003,
+	0x40025800, 0x0401f7f5, 0x4200a000, 0x0010b54b,
+	0x4050a800, 0x5930b40b, 0x0201f800, 0x0010ab28,
+	0x59300c0b, 0x42001000, 0x0000dc00, 0x5c025800,
+	0x5c00a800, 0x5c00b000, 0x5c00a000, 0x0201f000,
+	0x001078bc, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x4d2c0000, 0x42034800, 0x0010b544, 0x0401fa7f,
+	0x59325808, 0x4a025805, 0x02000000, 0x592c0802,
+	0x82d0ac00, 0x00000006, 0x592cb011, 0x832ca400,
+	0x00000005, 0x0201f800, 0x0010ab17, 0x40580000,
+	0x8054ac00, 0x592e5801, 0x41780000, 0x812e5d40,
+	0x040207f6, 0x42001000, 0x0000dc00, 0x5c025800,
+	0x5c00a800, 0x5c00b000, 0x5c00a000, 0x0201f000,
+	0x001078bc, 0x0401fa57, 0x4a01a006, 0x78000000,
+	0x5930001c, 0x840001c0, 0x4801a407, 0x4979a207,
+	0x42000800, 0x00000002, 0x42001000, 0x0000dc00,
+	0x0201f000, 0x001078bc, 0x4c580000, 0x4c540000,
+	0x4c500000, 0x0401fa55, 0x4a01a006, 0x02000000,
+	0x59a80002, 0x4801a008, 0x59a80003, 0x4801a009,
+	0x59a80000, 0x4801a00a, 0x59a80001, 0x4801a00b,
+	0x5930001c, 0x82000d80, 0x0000e000, 0x04000016,
+	0x82000d80, 0x0000df00, 0x04000006, 0x4a01a407,
+	0x00000010, 0x42000800, 0x00000006, 0x0401f027,
+	0x4a03c840, 0x0010b4eb, 0x4a03c842, 0x0000000d,
+	0x42001800, 0x0010b4eb, 0x0201f800, 0x001007af,
+	0x42000000, 0x0000df00, 0x4200a000, 0x0010b4eb,
+	0x0401f00d, 0x4a03c840, 0x0010b4f8, 0x4a03c842,
+	0x0000000d, 0x42001800, 0x0010b4f8, 0x0201f800,
+	0x001007af, 0x42000000, 0x0000e000, 0x4200a000,
+	0x0010b4f8, 0x82000540, 0x00000010, 0x4801a407,
+	0x4a01a207, 0x00000034, 0x4200b000, 0x0000000d,
+	0x82d0ac00, 0x0000000c, 0x0201f800, 0x0010ab17,
+	0x42000800, 0x00000013, 0x42001000, 0x0000dc00,
+	0x5c00a000, 0x5c00a800, 0x5c00b000, 0x0201f000,
+	0x001078bc, 0x0401fa03, 0x4a01a006, 0x63000028,
+	0x5930001c, 0x4801a007, 0x42000800, 0x00000002,
+	0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+	0x0401fa06, 0x41780000, 0x41780800, 0x42002000,
+	0x00080000, 0x0c01f81b, 0x80000000, 0x80040800,
+	0x42001000, 0x0000000c, 0x59841802, 0x8c0c1d00,
+	0x04020008, 0x42002000, 0x00050000, 0x0c01f811,
+	0x80000000, 0x80040800, 0x82081400, 0x00000004,
+	0x82080540, 0x02000000, 0x4801a006, 0x800408e0,
+	0x5930001c, 0x80040540, 0x4801a007, 0x80080904,
+	0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+	0x001072e9, 0x001072eb, 0x001072ed, 0x001072ef,
+	0x001072f1, 0x4811a008, 0x1c01f000, 0x4811a009,
+	0x1c01f000, 0x4811a00a, 0x1c01f000, 0x4811a00b,
+	0x1c01f000, 0x4811a00c, 0x1c01f000, 0x4a026009,
+	0x0010be0d, 0x59a80010, 0x82000500, 0x000000ff,
+	0x800000d0, 0x42026800, 0x0010be0d, 0x48026a12,
+	0x0401fa3b, 0x41780800, 0x42001000, 0x00005c00,
+	0x0201f000, 0x001078bc, 0x0401f9ba, 0x4a01a006,
+	0x52000000, 0x4979a007, 0x599c0017, 0x8c000500,
+	0x04000005, 0x599c0402, 0x0201f800, 0x001015da,
+	0x4805a007, 0x59a80002, 0x4801a008, 0x59a80003,
+	0x4801a009, 0x59a80000, 0x4801a00a, 0x59a80001,
+	0x4801a00b, 0x59a80010, 0x4801a00c, 0x42000800,
+	0x00000007, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x4a026202, 0x0000ffff, 0x0401f99d,
+	0x4a01a006, 0x05000000, 0x59a80010, 0x4801a007,
+	0x59a80002, 0x59a80803, 0x4801a008, 0x4805a009,
+	0x42000800, 0x00000004, 0x42001000, 0x0000dc00,
+	0x0201f000, 0x001078bc, 0x4a026202, 0x0000ffff,
+	0x0401f98c, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x001048f6, 0x5c027800, 0x4a01a006, 0x03000000,
+	0x59340403, 0x82000580, 0x000007fe, 0x0402006e,
+	0x4a01a006, 0x04000000, 0x81a40800, 0x4a000800,
+	0x22fffffe, 0x5934000a, 0x84000500, 0x4802680a,
+	0x59c41002, 0x8408150c, 0x480b8802, 0x59a80026,
+	0x8c000508, 0x04000010, 0x59a8002a, 0x4801a007,
+	0x59a8002b, 0x82000500, 0xffff2000, 0x599c0818,
+	0x8c040d16, 0x04000002, 0x8400056a, 0x4801a008,
+	0x4a01a009, 0x00002710, 0x59a8002d, 0x4801a00a,
+	0x0401f039, 0x59a8002a, 0x4801a007, 0x0201f800,
+	0x0010513b, 0x04020009, 0x497b8880, 0x82000500,
+	0x0000ffff, 0x4c000000, 0x0201f800, 0x00101606,
+	0x5c000000, 0x48038880, 0x59a8002b, 0x0201f800,
+	0x0010513b, 0x04020004, 0x82000500, 0x37ffffff,
+	0x0401f003, 0x82000500, 0x3fffffff, 0x599c0818,
+	0x8c040d16, 0x04000002, 0x8400056a, 0x59a80805,
+	0x8c040d10, 0x04000019, 0x59300c03, 0x82041580,
+	0x00000051, 0x04000015, 0x82041580, 0x00000031,
+	0x04000012, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x4200b000, 0x00000004, 0x4200a000, 0x0010b8fa,
+	0x82d0ac00, 0x0000001f, 0x4c000000, 0x0201f800,
+	0x0010ab17, 0x5c000000, 0x5c00a800, 0x5c00a000,
+	0x5c00b000, 0x8400057a, 0x4801a008, 0x4979a009,
+	0x4979a00a, 0x59a80002, 0x59a80803, 0x4801a00b,
+	0x4805a00c, 0x59a80000, 0x59a80801, 0x4801a00d,
+	0x4805a00e, 0x4979a00f, 0x4979a010, 0x4979a011,
+	0x4979a012, 0x4979a013, 0x4979a014, 0x4979a015,
+	0x4979a016, 0x59a8002e, 0x84000576, 0x4801a017,
+	0x59a8002f, 0x4801a018, 0x4979a019, 0x4979a01a,
+	0x0401f043, 0x59a80026, 0x8c000508, 0x0400000d,
+	0x59a8002a, 0x82000500, 0x0000ffff, 0x59c40880,
+	0x80040d80, 0x04000007, 0x497b8880, 0x4c000000,
+	0x0201f800, 0x00101606, 0x5c000000, 0x48038880,
+	0x59a8002a, 0x4801a007, 0x4c640000, 0x4d2c0000,
+	0x59a8c82b, 0x0201f800, 0x00109037, 0x0400000d,
+	0x0201f800, 0x00109597, 0x0402000a, 0x592c0207,
+	0x8c00050e, 0x04000007, 0x8264cd00, 0x0000ffff,
+	0x592c0009, 0x82000500, 0xffff0000, 0x8064cd40,
+	0x4865a008, 0x5c025800, 0x5c00c800, 0x59a8002c,
+	0x4801a009, 0x59a8002d, 0x4801a00a, 0x59a80002,
+	0x59a80803, 0x4801a00b, 0x4805a00c, 0x59a80000,
+	0x59a80801, 0x4801a00d, 0x4805a00e, 0x4979a00f,
+	0x4979a010, 0x4979a011, 0x4979a012, 0x4979a013,
+	0x4979a014, 0x4979a015, 0x4979a016, 0x59a8002e,
+	0x4801a017, 0x59a8002f, 0x4801a018, 0x59a80030,
+	0x4801a019, 0x59a80031, 0x4801a01a, 0x42000800,
+	0x0000001d, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x0401f8cb, 0x4a01a006, 0x50000000,
+	0x0401f7b5, 0x0401f8c7, 0x4a01a406, 0x21000010,
+	0x4a01a206, 0x00000014, 0x4979a007, 0x4979a008,
+	0x4979a009, 0x4979a00a, 0x42000800, 0x00000005,
+	0x42001000, 0x0000dc00, 0x0201f000, 0x001078bc,
+	0x0401f8bf, 0x0401f002, 0x0401f8c4, 0x4a01a006,
+	0x02000000, 0x42000800, 0x00000001, 0x42001000,
+	0x0000dc00, 0x0201f000, 0x001078bc, 0x0401f8bb,
+	0x4a01a006, 0x02000000, 0x59300403, 0x82000580,
+	0x00000031, 0x04020794, 0x81a40800, 0x4a000801,
+	0x00fffffe, 0x0401f72b, 0x0401f8b0, 0x4a01a006,
+	0x01000000, 0x5930041a, 0x80000540, 0x04000003,
+	0x4801a407, 0x0401f003, 0x4a01a407, 0x00000003,
+	0x5930021a, 0x80000540, 0x04000003, 0x4801a207,
+	0x0401f003, 0x4a01a207, 0x00002a00, 0x42000800,
+	0x00000002, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x4a026202, 0x0000ffff, 0x0401f889,
+	0x4a01a406, 0x00002010, 0x4a01a206, 0x00000014,
+	0x4a01a407, 0x00000800, 0x4a01a207, 0x00002000,
+	0x80000580, 0x599c0817, 0x8c040d0a, 0x04020003,
+	0x82000540, 0x00000020, 0x8c040d08, 0x04000003,
+	0x82000540, 0x00000010, 0x82000540, 0x00000002,
+	0x5934080a, 0x8c040d14, 0x04000005, 0x82040d00,
+	0x00000380, 0x80040540, 0x0401f006, 0x599c0818,
+	0x8c040d18, 0x04000003, 0x82000540, 0x00000380,
+	0x0401f03c, 0x0401f875, 0x4a01a406, 0x00000210,
+	0x4a01a206, 0x00000014, 0x4a01a407, 0x00000800,
+	0x5934000a, 0x8c000516, 0x04000014, 0x59340c05,
+	0x82040500, 0x00000030, 0x04000013, 0x59340a05,
+	0x82040500, 0x0000c000, 0x04020009, 0x8c040d1a,
+	0x04000004, 0x4a01a207, 0x00002100, 0x0401f00c,
+	0x4a01a207, 0x00000100, 0x0401f009, 0x4a01a207,
+	0x00000400, 0x0401f006, 0x4a01a207, 0x00000700,
+	0x0401f003, 0x4a01a207, 0x00000800, 0x80000580,
+	0x599c0817, 0x8c040d0a, 0x04020003, 0x82000540,
+	0x00000020, 0x8c040d08, 0x04000003, 0x82000540,
+	0x00000010, 0x82000540, 0x00000002, 0x59340a00,
+	0x8c040d0e, 0x0400000b, 0x84000550, 0x599c1017,
+	0x8c08150a, 0x04020004, 0x8c040d0a, 0x04000002,
+	0x8400054e, 0x8c040d1c, 0x04000002, 0x84000552,
+	0x4801a20a, 0x42000800, 0x00000005, 0x42001000,
+	0x0000dc00, 0x0201f000, 0x001078bc, 0x0401f833,
+	0x4a01a006, 0x02100014, 0x4a01a007, 0x01000000,
+	0x4979a008, 0x4979a009, 0x4979a00a, 0x42000800,
+	0x00000005, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x0401f825, 0x4a01a006, 0x02000000,
+	0x0401f65d, 0x4933c857, 0x0401f820, 0x4a01a006,
+	0x01000000, 0x4a01a407, 0x0000000b, 0x42000800,
+	0x00000002, 0x42001000, 0x0000dc00, 0x0201f000,
+	0x001078bc, 0x42005000, 0x32000000, 0x42006000,
+	0x08290000, 0x41786800, 0x41787800, 0x0401f3df,
+	0x42005000, 0x22000000, 0x42006000, 0x01290000,
+	0x41786800, 0x41787800, 0x0401f3d8, 0x42005000,
+	0x33000000, 0x42006000, 0x08980000, 0x41786800,
+	0x41787800, 0x0401f3d1, 0x42005000, 0x23000000,
+	0x42006000, 0x01980000, 0x41786800, 0x41787800,
+	0x0401f3ca, 0x59300403, 0x82000c80, 0x00000085,
+	0x02001800, 0x001005d8, 0x82000c80, 0x00000093,
+	0x02021800, 0x001005d8, 0x82000480, 0x00000085,
+	0x0c01f001, 0x001074eb, 0x001074ed, 0x001074fb,
+	0x001074eb, 0x001074eb, 0x001074eb, 0x001074eb,
+	0x001074eb, 0x001074eb, 0x001074eb, 0x001074eb,
+	0x001074eb, 0x001074eb, 0x00107506, 0x0201f800,
+	0x001005d8, 0x4933c857, 0x0401f850, 0x59300402,
+	0x4801a407, 0x5930001c, 0x4801a207, 0x4979a408,
+	0x4a01a208, 0x0000ffff, 0x42000800, 0x00000003,
+	0x42001000, 0x0000dc00, 0x0401f3c2, 0x4933c857,
+	0x0401f84e, 0x4a01a406, 0x00000003, 0x4a01a206,
+	0x00000300, 0x42000800, 0x00000001, 0x42001000,
+	0x0000dc00, 0x0401f3b7, 0x4d2c0000, 0x59325808,
+	0x4933c857, 0x492fc857, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x59340a12, 0x82040d00, 0x0000ff00,
+	0x592c000a, 0x82000500, 0x000000ff, 0x900001c0,
+	0x80040540, 0x82000540, 0x00000011, 0x44034800,
+	0x81a5a000, 0x42001000, 0x00000009, 0x42000800,
+	0x00000003, 0x592c0009, 0x82000500, 0xff000000,
+	0x82001d80, 0x84000000, 0x04000009, 0x82001d80,
+	0x85000000, 0x02020800, 0x001005d8, 0x42001000,
+	0x00000007, 0x42000800, 0x00000001, 0x832c1c00,
+	0x00000009, 0x500c0000, 0x4401a000, 0x800c1800,
+	0x80d1a000, 0x80081040, 0x040207fb, 0x42001000,
+	0x0000dc00, 0x5c025800, 0x0401f386, 0x42005000,
+	0x81000000, 0x42006000, 0x00090000, 0x41786800,
+	0x41787800, 0x0401f35d, 0x42005000, 0x84000000,
+	0x42006000, 0x00990000, 0x59300406, 0x82000580,
+	0x00000005, 0x04000002, 0x8430652e, 0x41786800,
+	0x41787800, 0x0401f351, 0x42005000, 0x85000000,
+	0x42006000, 0x00990000, 0x59300406, 0x82000580,
+	0x00000005, 0x04000002, 0x8430652e, 0x41786800,
+	0x41787800, 0x0401f345, 0x59300403, 0x82000c80,
+	0x00000053, 0x02021800, 0x001005d8, 0x82000480,
+	0x0000004b, 0x02001800, 0x001005d8, 0x59326809,
+	0x59368c03, 0x4803c857, 0x0c01f001, 0x001075da,
+	0x001075e2, 0x001075ea, 0x001075f2, 0x0010756b,
+	0x0010756b, 0x0010756b, 0x001075d2, 0x0201f800,
+	0x001005d8, 0x42005000, 0x06000000, 0x42006000,
+	0x08290000, 0x41786800, 0x41787800, 0x0401f327,
+	0x4933c857, 0x0401ff47, 0x4a01a006, 0x12000000,
+	0x59300406, 0x82000580, 0x00000004, 0x04020003,
+	0x59340002, 0x0401f002, 0x59a80010, 0x82000500,
+	0x00ffffff, 0x4801a007, 0x59300419, 0x4801a408,
+	0x59300219, 0x4801a208, 0x4979a009, 0x4979a00a,
+	0x4979a00b, 0x4979a00c, 0x4979a00d, 0x4979a00e,
+	0x4979a00f, 0x4979a010, 0x42000800, 0x0000000b,
+	0x42001000, 0x0000dc00, 0x0401f32a, 0x0401ff29,
+	0x4a01a006, 0x0f000000, 0x5930001c, 0x4801a007,
+	0x42000800, 0x00000002, 0x42001000, 0x0000dc00,
+	0x0401f320, 0x0401ff2d, 0x4a01a006, 0x02000000,
+	0x59c40085, 0x48031004, 0x59880000, 0x4801a007,
+	0x59880001, 0x4801a008, 0x59880002, 0x4801a009,
+	0x59880003, 0x4801a00a, 0x59880004, 0x4801a00b,
+	0x59880005, 0x4801a00c, 0x42000800, 0x00000007,
+	0x42001000, 0x0000dc00, 0x0401f30a, 0x4a026202,
+	0x0000ffff, 0x0401ff07, 0x4a01a006, 0x62000000,
+	0x5930001c, 0x4801a007, 0x42000800, 0x00000002,
+	0x42001000, 0x0000dc00, 0x0401f2fe, 0x0401fefd,
+	0x59300808, 0x4c500000, 0x4c540000, 0x4c580000,
+	0x8204a400, 0x0000000a, 0x5930b01c, 0x82d0ac00,
+	0x00000006, 0x0201f800, 0x0010ab17, 0x5930081c,
+	0x42001000, 0x0000dc00, 0x5c00b000, 0x5c00a800,
+	0x5c00a000, 0x0401f2eb, 0x0401ff9b, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00001000, 0x0401f020, 0x0401ff93, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00004000, 0x0401f018, 0x0401ff8b, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00002000, 0x0401f010, 0x0401ff83, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00000400, 0x0401f008, 0x0401ff7b, 0x59300017,
+	0x4801a006, 0x59300018, 0x4801a007, 0x4a01a008,
+	0x00000200, 0x4979a009, 0x4979a00a, 0x4979a00b,
+	0x4979a00c, 0x4979a00d, 0x42000800, 0x00000008,
+	0x42001000, 0x0000dc00, 0x0401f2ba, 0x0401fec7,
+	0x4a01a006, 0x02000014, 0x4979a407, 0x4979a207,
+	0x59a8003a, 0x4801a008, 0x59a8003b, 0x4801a009,
+	0x4a01a00a, 0x00047878, 0x42000800, 0x00000005,
+	0x42001000, 0x0000dc00, 0x0401f2aa, 0x0401feb7,
+	0x4a01a006, 0x02140018, 0x4a01a407, 0x00000800,
+	0x5930001c, 0x82000d00, 0xff000000, 0x900409c0,
+	0x4805a207, 0x82000500, 0x00ffffff, 0x4801a00a,
+	0x4979a408, 0x4979a208, 0x4979a409, 0x4979a209,
+	0x4979a00b, 0x42000800, 0x00000006, 0x42001000,
+	0x0000dc00, 0x0401f293, 0x4803c856, 0x4d380000,
+	0x4d1c0000, 0x42027000, 0x00000035, 0x0201f800,
+	0x001093ba, 0x0402001e, 0x0401fe8a, 0x4a01a006,
+	0x13000000, 0x5932381e, 0x591c0019, 0x4801a005,
+	0x591c0406, 0x82000580, 0x00000003, 0x04000007,
+	0x59300809, 0x58040002, 0x82000500, 0x00ffffff,
+	0x4801a007, 0x0401f003, 0x59a80010, 0x4801a007,
+	0x59300419, 0x4801a408, 0x59300219, 0x4801a208,
+	0x42000800, 0x00000003, 0x42001000, 0x0000dc00,
+	0x5c023800, 0x5c027000, 0x0401f26e, 0x0201f800,
+	0x00106c55, 0x598c000d, 0x81300580, 0x02020800,
+	0x001005d8, 0x0201f800, 0x00106bbf, 0x0201f800,
+	0x0002077d, 0x5c023800, 0x5c027000, 0x0201f000,
+	0x00106c4b, 0x4803c856, 0x4d2c0000, 0x4d1c0000,
+	0x5932381e, 0x811e39c0, 0x02000800, 0x001005d8,
+	0x591c0c06, 0x82040580, 0x00000006, 0x0400000d,
+	0x82040580, 0x00000003, 0x04000036, 0x4a026403,
+	0x00000037, 0x4a02641a, 0x00000003, 0x4a02621a,
+	0x00001700, 0x5c023800, 0x5c025800, 0x0401f064,
+	0x0401f84b, 0x42001000, 0x40000000, 0x591c0203,
+	0x591c0804, 0x8c040d3e, 0x04020023, 0x82000c80,
+	0x0000000e, 0x0c001003, 0x0201f800, 0x001005d8,
+	0x00107691, 0x0010769d, 0x00107693, 0x0010769d,
+	0x00107699, 0x00107691, 0x00107691, 0x0010769d,
+	0x0010769d, 0x00107691, 0x00107691, 0x00107691,
+	0x00107691, 0x00107691, 0x0010769d, 0x00107691,
+	0x0010769d, 0x0201f800, 0x001005d8, 0x591c0414,
+	0x4803c857, 0x8c000518, 0x04000003, 0x8c000512,
+	0x04000003, 0x80001580, 0x0401f003, 0x42001000,
+	0x20000000, 0x591c0015, 0x4801a00a, 0x0401f018,
+	0x0401f81f, 0x591e5808, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x592c100f, 0x591c0011, 0x80080480,
+	0x4801a00a, 0x591c0203, 0x591c0804, 0x8c040d3e,
+	0x04020007, 0x82000d80, 0x00000002, 0x04000007,
+	0x82000d80, 0x00000004, 0x04000004, 0x42001000,
+	0x40000000, 0x0401f002, 0x80001580, 0x4809a00b,
+	0x42000800, 0x00000006, 0x42001000, 0x0000dc00,
+	0x5c023800, 0x5c025800, 0x0401f1fe, 0x4803c856,
+	0x0401fe0a, 0x4a01a006, 0x02000000, 0x59300c19,
+	0x4805a407, 0x59300a19, 0x4805a207, 0x59a81010,
+	0x59300809, 0x58041802, 0x820c1d00, 0x00ffffff,
+	0x5930081e, 0x58040406, 0x82000580, 0x00000003,
+	0x04020004, 0x4809a008, 0x480da009, 0x0401f003,
+	0x480da008, 0x4809a009, 0x1c01f000, 0x4803c856,
+	0x0401fdf2, 0x0401f003, 0x4803c856, 0x0401fde8,
+	0x4a01a006, 0x01000000, 0x5930041a, 0x4801a407,
+	0x5930021a, 0x4801a207, 0x42000800, 0x00000002,
+	0x42001000, 0x0000dc00, 0x0401f1d6, 0x4803c856,
+	0x4d1c0000, 0x0401fdcc, 0x4a01a006, 0x14000000,
+	0x5932381e, 0x591c0019, 0x4801a005, 0x59300419,
+	0x4801a407, 0x59300219, 0x4801a207, 0x59300015,
+	0x4801a008, 0x59300216, 0x82000500, 0x000000ff,
+	0x840001c0, 0x4801a409, 0x42000800, 0x00000004,
+	0x42001000, 0x0000dc00, 0x5c023800, 0x0401f1bd,
+	0x4803c856, 0x0401f80b, 0x5930041a, 0x900001c0,
+	0x4801a005, 0x0401f9ec, 0x41780800, 0x42001000,
+	0x00005c00, 0x0401f9b3, 0x0201f000, 0x0010604d,
+	0x4803c856, 0x59300817, 0x82041c00, 0x00000005,
+	0x46034800, 0x00000021, 0x58040404, 0x82000500,
+	0x0000f000, 0x82000580, 0x00003000, 0x04000003,
+	0x46034800, 0x00000041, 0x81a5a000, 0x580c0001,
+	0x82000d00, 0x00ffffff, 0x82040d40, 0xc2000000,
+	0x4805a000, 0x580c0800, 0x82041500, 0x00ffffff,
+	0x82000500, 0xff000000, 0x80080540, 0x4801a001,
+	0x580c0002, 0x82000580, 0x00c00000, 0x82000500,
+	0x00fd0300, 0x4801a002, 0x580c0003, 0x4801a003,
+	0x580c0404, 0x4801a404, 0x580c0204, 0x4801a204,
+	0x1c01f000, 0x4803c856, 0x59a80026, 0x82000500,
+	0x00000028, 0x04020009, 0x59a80026, 0x82000500,
+	0x00000028, 0x04000003, 0x497a6a12, 0x0401f003,
+	0x4a026a12, 0x0000ff00, 0x42005000, 0x22000000,
+	0x42006000, 0x01380000, 0x41786800, 0x41787800,
+	0x0401f952, 0x59301008, 0x4a01a006, 0x54000000,
+	0x59a80010, 0x82000500, 0x00ffffff, 0x58080c0a,
+	0x800408f0, 0x80040540, 0x4801a007, 0x5808000a,
+	0x82000500, 0xff000000, 0x4801a008, 0x59a80002,
+	0x4801a009, 0x59a80003, 0x4801a00a, 0x59a80000,
+	0x4801a00b, 0x59a80001, 0x4801a00c, 0x5808000c,
+	0x9c0001c0, 0x4801a00d, 0x5808000d, 0x9c0001c0,
+	0x4801a00e, 0x5808000e, 0x9c0001c0, 0x4801a00f,
+	0x5808000f, 0x9c0001c0, 0x4801a010, 0x58080010,
+	0x9c0001c0, 0x4801a011, 0x58080011, 0x9c0001c0,
+	0x4801a012, 0x58080012, 0x9c0001c0, 0x4801a013,
+	0x58080013, 0x9c0001c0, 0x4801a014, 0x58080010,
+	0x9c0001c0, 0x4801a015, 0x58080011, 0x9c0001c0,
+	0x4801a016, 0x58080012, 0x9c0001c0, 0x4801a017,
+	0x58080013, 0x9c0001c0, 0x4801a018, 0x42000800,
+	0x00000013, 0x42001000, 0x0000dc00, 0x0401f135,
+	0x4803c856, 0x42005000, 0x22000000, 0x42006000,
+	0x01290000, 0x41786800, 0x41787800, 0x0401f90b,
+	0x59301008, 0x4a01a006, 0x55000000, 0x5808000b,
+	0x82000500, 0x00ffffff, 0x58080c0a, 0x800408f0,
+	0x80040540, 0x4801a007, 0x5808080a, 0x82040d00,
+	0xff000000, 0x59a80010, 0x82000500, 0x00ffffff,
+	0x80040540, 0x4801a008, 0x5808000c, 0x9c0001c0,
+	0x4801a009, 0x5808000d, 0x9c0001c0, 0x4801a00a,
+	0x5808000e, 0x9c0001c0, 0x4801a00b, 0x5808000f,
+	0x9c0001c0, 0x4801a00c, 0x59a80002, 0x4801a00d,
+	0x59a80003, 0x4801a00e, 0x59a80000, 0x4801a00f,
+	0x59a80001, 0x4801a010, 0x58080010, 0x4801a011,
+	0x58080011, 0x4801a012, 0x58080012, 0x4801a013,
+	0x58080013, 0x4801a014, 0x4979a015, 0x4979a016,
+	0x4979a017, 0x4979a018, 0x42000800, 0x00000013,
+	0x42001000, 0x0000dc00, 0x0401f0f6, 0x0401fd03,
+	0x5930001c, 0x800001c0, 0x04000008, 0x4a01a006,
+	0x01000000, 0x4a01a407, 0x00000003, 0x42000800,
+	0x00000002, 0x0401f028, 0x4a01a006, 0x02000000,
+	0x41780800, 0x836c0580, 0x00000004, 0x04020003,
+	0x84040d42, 0x0401f00d, 0x0201f800, 0x0010513b,
+	0x04020003, 0x84040d4a, 0x0401f002, 0x84040d48,
+	0x59a80026, 0x8c000506, 0x04020003, 0x8c00050a,
+	0x04000002, 0x84040d46, 0x4805a207, 0x59c40085,
+	0x48031004, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x4200b000, 0x00000006, 0x8388a400, 0x00000000,
+	0x82d0ac00, 0x00000008, 0x0201f800, 0x0010ab17,
+	0x5c00a800, 0x5c00a000, 0x5c00b000, 0x42000800,
+	0x00000008, 0x42001000, 0x0000dc00, 0x0401f0c1,
+	0x0401fcc0, 0x4a01a006, 0x56000000, 0x59340006,
+	0x4801a007, 0x59340007, 0x4801a008, 0x42000800,
+	0x00000003, 0x42001000, 0x0000dc00, 0x0401f0b5,
+	0x4803c856, 0x0401fcc1, 0x5930081c, 0x800409c0,
+	0x0400000e, 0x82040580, 0x0000ffff, 0x04000004,
+	0x82040480, 0x00000007, 0x04021008, 0x4a01a006,
+	0x01000000, 0x4a01a407, 0x00000003, 0x42000800,
+	0x00000002, 0x0401f012, 0x4a01a006, 0x0200001c,
+	0x4a01a007, 0x00000001, 0x42001000, 0x0010b4f0,
+	0x50080000, 0x9c0001c0, 0x4801a009, 0x59a80010,
+	0x4801a00a, 0x59a80002, 0x59a80803, 0x4801a00b,
+	0x4805a00c, 0x42000800, 0x00000007, 0x42001000,
+	0x0000dc00, 0x0401f08f, 0x4d2c0000, 0x0401fc8d,
+	0x59325808, 0x592c0008, 0x82000500, 0x00ffffff,
+	0x4801a001, 0x4a01a006, 0x51000000, 0x5c025800,
+	0x0201f000, 0x00107344, 0x4803c856, 0x59a80810,
+	0x82040d00, 0x000000ff, 0x59325808, 0x59326809,
+	0x59a83026, 0x8c18350a, 0x04020008, 0x8c00050e,
+	0x04020006, 0x80001d80, 0x59a82010, 0x82102500,
+	0x000000ff, 0x0401f001, 0x59300406, 0x4803c857,
+	0x82000d80, 0x00000009, 0x04000006, 0x82000d80,
+	0x0000000a, 0x0400002e, 0x0201f800, 0x001005d8,
+	0x59300015, 0x8c00051e, 0x04020020, 0x42005000,
+	0x04000000, 0x42006000, 0x05000000, 0x592c040a,
+	0x82000500, 0x00000030, 0x800000e0, 0x80306540,
+	0x5934000a, 0x8c000508, 0x04000002, 0x84306546,
+	0x41786800, 0x41787800, 0x0401f831, 0x59300c14,
+	0x80040000, 0x48026414, 0x40040000, 0x800000d0,
+	0x82000540, 0x00000020, 0x4801a403, 0x83180d40,
+	0x00000038, 0x42001000, 0x0000c920, 0x0401f860,
+	0x0201f000, 0x00106052, 0x59a80026, 0x82000500,
+	0x00000028, 0x04000003, 0x497a6a12, 0x0401f7dc,
+	0x4a026a12, 0x0000ff00, 0x0401f7d9, 0x42005000,
+	0x02000000, 0x42006000, 0x20290000, 0x41786800,
+	0x41787800, 0x0401f812, 0x83180d40, 0x00000038,
+	0x42001000, 0x0000c9a0, 0x0401f849, 0x42000800,
+	0x000007d0, 0x59300011, 0x82000500, 0xfff00000,
+	0x80000540, 0x04000003, 0x42000800, 0x00001b58,
+	0x41781000, 0x0201f000, 0x00106054, 0x4201a000,
+	0x00000000, 0x0401f003, 0x4201a000, 0x00000011,
+	0x59340a12, 0x82040d00, 0x0000ff00, 0x59a80010,
+	0x82000500, 0x000000ff, 0x900001c0, 0x80040540,
+	0x80d00540, 0x44034800, 0x81a5a000, 0x59340002,
+	0x82000500, 0x00ffffff, 0x80280540, 0x4801a000,
+	0x59a80010, 0x4801a001, 0x4831a002, 0x82340540,
+	0x00000000, 0x4801a003, 0x59300402, 0x4801a404,
+	0x59300a02, 0x4805a204, 0x8c30652e, 0x04000003,
+	0x4805a404, 0x4801a204, 0x483da005, 0x1c01f000,
+	0x4803c856, 0x4c040000, 0x0401f822, 0x5c000800,
+	0x40040000, 0x80081540, 0x800000c4, 0x82000540,
+	0x00002000, 0x4803910a, 0x59b400f6, 0x82000500,
+	0x00000018, 0x040207fd, 0x4a0368f0, 0x0010b544,
+	0x4a0368f1, 0x0010b54b, 0x480b68f3, 0x4a0378e4,
+	0x00008000, 0x0201f000, 0x0010604d, 0x4807c857,
+	0x480a2800, 0x4c040000, 0x0401f80a, 0x5c000800,
+	0x59b400f6, 0x8c00050a, 0x040207fe, 0x49a768f2,
+	0x480768f4, 0x4a0378e4, 0x00008000, 0x1c01f000,
+	0x4a0378e4, 0x0000c000, 0x59bc00e4, 0x8c000520,
+	0x0400000c, 0x4a0378e4, 0x00008000, 0x42007000,
+	0x000003e8, 0x59bc00e4, 0x8c000520, 0x040007f5,
+	0x80387040, 0x02000800, 0x001005d8, 0x0401f7fa,
+	0x1c01f000, 0x82000500, 0xffff0000, 0x82000580,
+	0x01050000, 0x0402000d, 0x599c0818, 0x8c040d10,
+	0x0400000a, 0x59a80807, 0x8c040d0a, 0x04000007,
+	0x42001000, 0x0000804f, 0x41781800, 0x41782000,
+	0x0201f800, 0x00103a3e, 0x1c01f000, 0x41781000,
+	0x42026000, 0x0010d1c0, 0x59a8180e, 0x480a6402,
+	0x4a026202, 0x0000ffff, 0x80081000, 0x800c1840,
+	0x04000004, 0x83326400, 0x00000024, 0x0401f7f8,
+	0x1c01f000, 0x4933c857, 0x59300203, 0x82000580,
+	0x00000000, 0x0400002c, 0x59300406, 0x4803c857,
+	0x82000d80, 0x00000004, 0x04000011, 0x82000d80,
+	0x00000001, 0x0400000e, 0x82000d80, 0x00000003,
+	0x04000006, 0x82000d80, 0x00000006, 0x04020011,
+	0x0201f800, 0x0010a5df, 0x5930001c, 0x800001c0,
+	0x02020800, 0x0010984e, 0x0401f00a, 0x5930081e,
+	0x4807c857, 0x800409c0, 0x04000006, 0x5804001c,
+	0x4803c857, 0x81300580, 0x04020002, 0x4978081c,
+	0x497a6008, 0x4a026004, 0x00004000, 0x59a80037,
+	0x82000c80, 0x00000051, 0x04001002, 0x80000102,
+	0x48026206, 0x497a6205, 0x497a6009, 0x4a026406,
+	0x00000007, 0x1c01f000, 0x8166c9c0, 0x0400001c,
+	0x41626000, 0x41580000, 0x59300a03, 0x82040d80,
+	0x00000000, 0x04000008, 0x83326400, 0x00000024,
+	0x81300c80, 0x040017f9, 0x42026000, 0x0010d1c0,
+	0x0401f7f6, 0x4933c857, 0x8166c840, 0x83300c00,
+	0x00000024, 0x80040480, 0x04021006, 0x4006c000,
+	0x4a026203, 0x00000008, 0x813261c0, 0x1c01f000,
+	0x4202c000, 0x0010d1c0, 0x0401f7fa, 0x42000000,
+	0x0010b854, 0x0201f800, 0x0010aa47, 0x4933c856,
+	0x417a6000, 0x0401f7f5, 0x4933c857, 0x83380580,
+	0x00000013, 0x0402000b, 0x59300004, 0x8c00053e,
+	0x04000007, 0x0201f800, 0x00106c55, 0x0201f800,
+	0x00106bbf, 0x0201f800, 0x00106c4b, 0x1c01f000,
+	0x4933c857, 0x59880052, 0x80000000, 0x48031052,
+	0x1c01f000, 0x4933c857, 0x59300203, 0x82003480,
+	0x0000000e, 0x02021800, 0x001005d8, 0x4d2c0000,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x00107991,
+	0x00107efd, 0x0010804a, 0x00107991, 0x001080b0,
+	0x00107af5, 0x00107991, 0x00107991, 0x00107e93,
+	0x00107991, 0x00107991, 0x00107991, 0x00107991,
+	0x00107991, 0x0201f800, 0x001005d8, 0x4933c857,
+	0x59300203, 0x82003480, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x001079a8, 0x00108a3d,
+	0x001079a8, 0x001079a8, 0x001079a8, 0x001079a8,
+	0x001079a8, 0x001079a8, 0x001089e5, 0x00108a58,
+	0x00108ac6, 0x00108a58, 0x00108ac6, 0x001079a8,
+	0x0201f800, 0x001005d8, 0x0201f800, 0x001005d8,
+	0x4933c857, 0x4d2c0000, 0x59325808, 0x59300203,
+	0x82003480, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x001079c5,
+	0x001079c5, 0x001079c5, 0x001079e1, 0x00107a2d,
+	0x001079c5, 0x001079c5, 0x001079c5, 0x001079c7,
+	0x001079c5, 0x001079c5, 0x001079c5, 0x001079c5,
+	0x001079c5, 0x0201f800, 0x001005d8, 0x4933c857,
+	0x83380580, 0x00000040, 0x02020800, 0x001005d8,
+	0x4a026007, 0x00082000, 0x4a026203, 0x00000003,
+	0x493a6403, 0x4a025c08, 0x00000001, 0x592c000d,
+	0x48026011, 0x497a6013, 0x592c0208, 0x800000c2,
+	0x800010c4, 0x80081400, 0x480a6206, 0x0201f800,
+	0x00100f4e, 0x42000800, 0x80000060, 0x0201f000,
+	0x00106721, 0x4933c857, 0x83380480, 0x00000050,
+	0x02021800, 0x001005d8, 0x83380480, 0x00000049,
+	0x02001800, 0x001005d8, 0x0c01f001, 0x001079f4,
+	0x001079ff, 0x001079f2, 0x001079f2, 0x001079f2,
+	0x001079f2, 0x00107a0a, 0x0201f800, 0x001005d8,
+	0x4a026203, 0x00000004, 0x4a025c08, 0x00000002,
+	0x592c0207, 0x48025c09, 0x592c0209, 0x48025a07,
+	0x592c000c, 0x4802580d, 0x1c01f000, 0x0201f800,
+	0x00106b8a, 0x0201f800, 0x00109037, 0x04000005,
+	0x4a025a06, 0x00000006, 0x0201f800, 0x000202da,
+	0x0201f000, 0x0002077d, 0x0201f800, 0x00106b8a,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x42003000, 0x00000014, 0x41782800,
+	0x42002000, 0x00000002, 0x4d400000, 0x4d440000,
+	0x59368c03, 0x42028000, 0x00000029, 0x0201f800,
+	0x0010985e, 0x5c028800, 0x5c028000, 0x42000000,
+	0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800,
+	0x00109037, 0x02000000, 0x0002077d, 0x4a025a06,
+	0x00000029, 0x0201f800, 0x000202da, 0x0201f000,
+	0x0002077d, 0x4933c857, 0x83380580, 0x00000048,
+	0x04000005, 0x83380580, 0x00000053, 0x02020800,
+	0x001005d8, 0x592c0206, 0x82000580, 0x00000007,
+	0x04000009, 0x59300011, 0x80000540, 0x04000006,
+	0x592c080c, 0x80040480, 0x4802580c, 0x4a025a06,
+	0x00000015, 0x592c0206, 0x80000540, 0x04020003,
+	0x4a025a06, 0x00000000, 0x0201f800, 0x000202da,
+	0x0201f000, 0x0002077d, 0x4933c857, 0x4d2c0000,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x0201f800,
+	0x001007e4, 0x02000800, 0x001005d8, 0x497a5a06,
+	0x59c80017, 0x82000500, 0x0000f000, 0x48025c07,
+	0x59a80816, 0x82040c00, 0x00000018, 0x48065a07,
+	0x412c7800, 0x4d2c0000, 0x41cca000, 0x42002800,
+	0x00000001, 0x42001000, 0x0000002c, 0x82040480,
+	0x0000002d, 0x04021006, 0x832cac00, 0x00000009,
+	0x0201f800, 0x00108b96, 0x0401f02e, 0x40043000,
+	0x42000800, 0x0000002c, 0x832cac00, 0x00000009,
+	0x0201f800, 0x00108b96, 0x82183480, 0x0000002c,
+	0x0201f800, 0x001007e4, 0x0400001a, 0x80142800,
+	0x4a025804, 0x00000110, 0x492c7801, 0x82180c80,
+	0x0000003d, 0x04021007, 0x40180800, 0x832cac00,
+	0x00000005, 0x0201f800, 0x00108b96, 0x0401f015,
+	0x82081400, 0x0000003c, 0x82183480, 0x0000003c,
+	0x42000800, 0x0000003c, 0x412c7800, 0x832cac00,
+	0x00000005, 0x0201f800, 0x00108b96, 0x0401f7e5,
+	0x5c025800, 0x592c0206, 0x8400055e, 0x48025a06,
+	0x592c0407, 0x80080540, 0x48025c07, 0x0401f002,
+	0x5c025800, 0x813669c0, 0x04000003, 0x59343403,
+	0x0401f003, 0x42003000, 0x0000ffff, 0x49325808,
+	0x481a5c06, 0x82100580, 0x00000054, 0x04020002,
+	0x491e5813, 0x841401c0, 0x80100540, 0x48025804,
+	0x592c0001, 0x497a5801, 0x4c000000, 0x0201f800,
+	0x000202da, 0x5c025800, 0x812e59c0, 0x040207f9,
+	0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800,
+	0x1c01f000, 0x4803c856, 0x4c5c0000, 0x4d2c0000,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x412cb800,
+	0x592c040b, 0x8c000516, 0x04000003, 0x41cca000,
+	0x0401f003, 0x83cca400, 0x00000006, 0x4008b000,
+	0x41781000, 0x82580480, 0x00000012, 0x04001004,
+	0x4200b000, 0x00000012, 0x40001000, 0x4c080000,
+	0x4d2c0000, 0x0201f800, 0x001007e4, 0x04000023,
+	0x5c001800, 0x492c1801, 0x485a5800, 0x832cac00,
+	0x00000002, 0x0201f800, 0x0010ab28, 0x585c040b,
+	0x8c000500, 0x0400000e, 0x832c1400, 0x00000002,
+	0x8c000516, 0x04000003, 0x82081400, 0x00000006,
+	0x46001000, 0x00000001, 0x80081000, 0x46001000,
+	0x00000900, 0x84000500, 0x4800bc0b, 0x5c001000,
+	0x800811c0, 0x040207da, 0x82000540, 0x00000001,
+	0x5c00b000, 0x5c00a800, 0x5c00a000, 0x5c025800,
+	0x5c00b800, 0x1c01f000, 0x5c025800, 0x5c001000,
+	0x0401f7f8, 0x4933c857, 0x83380d80, 0x00000015,
+	0x04020003, 0x0201f000, 0x0002077d, 0x83380d80,
+	0x00000016, 0x02020800, 0x001005d8, 0x0201f000,
+	0x0002077d, 0x4933c857, 0x4d2c0000, 0x4c500000,
+	0x4c540000, 0x4c580000, 0x59325808, 0x83cca400,
+	0x00000006, 0x59cc1806, 0x820c0580, 0x01000000,
+	0x04020004, 0x4200b000, 0x00000002, 0x0401f00f,
+	0x4200b000, 0x00000008, 0x832cac00, 0x00000005,
+	0x0201f800, 0x0010ab17, 0x8c0c1d00, 0x0400000b,
+	0x4200b000, 0x00000008, 0x592e5801, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x832cac00, 0x00000005,
+	0x0201f800, 0x0010ab17, 0x0401f816, 0x5c00b000,
+	0x5c00a800, 0x5c00a000, 0x5c025800, 0x1c01f000,
+	0x4933c857, 0x4c500000, 0x4c540000, 0x4c580000,
+	0x83cca400, 0x00000006, 0x5930a808, 0x8254ac00,
+	0x00000005, 0x4200b000, 0x00000007, 0x0201f800,
+	0x0010ab17, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+	0x4933c857, 0x0201f800, 0x00109037, 0x02000000,
+	0x0002077d, 0x4d2c0000, 0x0201f800, 0x00109597,
+	0x0402000b, 0x41780800, 0x4d400000, 0x42028000,
+	0x00000000, 0x0201f800, 0x0010943b, 0x5c028000,
+	0x5c025800, 0x0201f000, 0x0002077d, 0x5931d821,
+	0x58ef400b, 0x58ee580d, 0x4a025a04, 0x00000103,
+	0x58ec0009, 0x0801f800, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x4933c857, 0x59cc1806, 0x820c0580,
+	0x02000000, 0x04020014, 0x4a026802, 0x00fffffd,
+	0x5934000a, 0x84000504, 0x4802680a, 0x59300808,
+	0x800409c0, 0x02000000, 0x0002077d, 0x4a000a04,
+	0x00000103, 0x480c0805, 0x5931d821, 0x58ef400b,
+	0x58ee580d, 0x58ec0009, 0x0801f800, 0x0201f000,
+	0x0002077d, 0x42000000, 0x0010b86c, 0x0201f800,
+	0x0010aa47, 0x4c0c0000, 0x0401f804, 0x5c001800,
+	0x040207eb, 0x1c01f000, 0x4933c857, 0x4d2c0000,
+	0x59325808, 0x812e59c0, 0x04020009, 0x497a6206,
+	0x497a6205, 0x4d380000, 0x42027000, 0x00000022,
+	0x0401fb77, 0x5c027000, 0x80000580, 0x5c025800,
+	0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c500000,
+	0x4c540000, 0x4c580000, 0x59325808, 0x592e5801,
+	0x832cac00, 0x00000005, 0x83cca400, 0x00000006,
+	0x59c80817, 0x82040d00, 0x000003ff, 0x82041480,
+	0x0000000f, 0x0400101b, 0x4200b000, 0x0000000f,
+	0x0201f800, 0x0010ab17, 0x592e5801, 0x832cac00,
+	0x00000005, 0x82080c80, 0x0000000f, 0x0400100d,
+	0x4200b000, 0x0000000f, 0x0201f800, 0x0010ab17,
+	0x592e5801, 0x832cac00, 0x00000005, 0x82041480,
+	0x0000000f, 0x04001007, 0x42001000, 0x0000000f,
+	0x4008b000, 0x0201f800, 0x0010ab17, 0x0401f004,
+	0x4004b000, 0x0201f800, 0x0010ab17, 0x5931d821,
+	0x58ef400b, 0x58ee580d, 0x4a025a04, 0x00000103,
+	0x592e5801, 0x58ec0009, 0x0801f800, 0x0201f800,
+	0x0002077d, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4d2c0000,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x59cc0006,
+	0x82000d80, 0x01000000, 0x0400002c, 0x59cc0007,
+	0x9000b1c0, 0x8258b500, 0x000000ff, 0x8058b104,
+	0x8258b400, 0x00000002, 0x82580c80, 0x00000007,
+	0x04001003, 0x4200b000, 0x00000006, 0x83cca400,
+	0x00000006, 0x59301008, 0x800811c0, 0x02000800,
+	0x001005d8, 0x8208ac00, 0x00000005, 0x0201f800,
+	0x0010ab17, 0x82000d00, 0xff000000, 0x800409c0,
+	0x04000019, 0x8200b500, 0x000000ff, 0x8058b104,
+	0x82580c80, 0x0000000e, 0x04001003, 0x4200b000,
+	0x0000000d, 0x58081001, 0x800811c0, 0x02000800,
+	0x001005d8, 0x8208ac00, 0x00000005, 0x0201f800,
+	0x0010ab17, 0x0401f008, 0x59301008, 0x800811c0,
+	0x02000800, 0x001005d8, 0x48001005, 0x59cc0007,
+	0x48001006, 0x0401ff3b, 0x5c00b000, 0x5c00a800,
+	0x5c00a000, 0x5c025800, 0x1c01f000, 0x4933c857,
+	0x42000800, 0x00000000, 0x59cc0006, 0x82000580,
+	0x02000000, 0x04000003, 0x42000800, 0x00000001,
+	0x4d2c0000, 0x59325808, 0x812e59c0, 0x02000800,
+	0x001005d8, 0x48065a06, 0x0201f800, 0x000202da,
+	0x5c025800, 0x0201f000, 0x0002077d, 0x4933c857,
+	0x4d2c0000, 0x4c500000, 0x4c540000, 0x4c580000,
+	0x4200b000, 0x00000002, 0x59cc0806, 0x82040580,
+	0x01000000, 0x04000004, 0x8204b500, 0x0000ffff,
+	0x8058b104, 0x83cca400, 0x00000006, 0x59300008,
+	0x8200ac00, 0x00000005, 0x0201f800, 0x0010ab17,
+	0x0401ff0c, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x4803c857,
+	0x4807c857, 0x480bc857, 0x480fc857, 0x4813c857,
+	0x481bc857, 0x492fc857, 0x4d2c0000, 0x4c000000,
+	0x0201f800, 0x001007d3, 0x5c000000, 0x0400000f,
+	0x48025803, 0x5c000000, 0x4802580a, 0x4c000000,
+	0x481a5801, 0x48125809, 0x48065804, 0x480a5807,
+	0x480e5808, 0x412c1000, 0x0201f800, 0x00100858,
+	0x82000540, 0x00000001, 0x5c025800, 0x1c01f000,
+	0x4933c857, 0x4d1c0000, 0x59cc0001, 0x82000500,
+	0x00ffffff, 0x59341002, 0x82081500, 0x00ffffff,
+	0x80080580, 0x0402001f, 0x497a6205, 0x4d380000,
+	0x42027000, 0x00000035, 0x0201f800, 0x001093ba,
+	0x5c027000, 0x04020012, 0x591c001c, 0x800001c0,
+	0x0400000f, 0x497a381c, 0x591c0414, 0x8c000502,
+	0x02000800, 0x001005d8, 0x84000502, 0x48023c14,
+	0x591c1406, 0x82080580, 0x00000003, 0x04000006,
+	0x82080580, 0x00000006, 0x04000005, 0x0401fc9e,
+	0x0401f004, 0x0401f805, 0x0401f002, 0x0401f8c0,
+	0x5c023800, 0x1c01f000, 0x4d2c0000, 0x591e5808,
+	0x4933c857, 0x491fc857, 0x493bc857, 0x492fc857,
+	0x83380580, 0x00000015, 0x040000b3, 0x83380580,
+	0x00000016, 0x040200ae, 0x4d300000, 0x411e6000,
+	0x59cc0207, 0x4803c857, 0x82000d00, 0x0000ff00,
+	0x82040580, 0x00001700, 0x04000004, 0x82040580,
+	0x00000300, 0x0402005b, 0x591c0203, 0x4803c857,
+	0x82000580, 0x0000000d, 0x0400003f, 0x812e59c0,
+	0x0400009a, 0x591c0202, 0x4803c857, 0x82000580,
+	0x0000ffff, 0x0402007e, 0x592c020a, 0x4803c857,
+	0x82000500, 0x00000003, 0x82000580, 0x00000002,
+	0x04020007, 0x592c080f, 0x591c0011, 0x4803c857,
+	0x4807c857, 0x80040580, 0x04020071, 0x591c0414,
+	0x4803c857, 0x8c000500, 0x0402006d, 0x41780800,
+	0x591c1206, 0x42000000, 0x0000000a, 0x0201f800,
+	0x001066a0, 0x592c0406, 0x4803c857, 0x800001c0,
+	0x0400000c, 0x80080c80, 0x04001004, 0x02020800,
+	0x001005d8, 0x80001040, 0x480a5c06, 0x800811c0,
+	0x04020004, 0x0201f800, 0x00108d88, 0x0401f06b,
+	0x0201f800, 0x0010912a, 0x591c0817, 0x591c0018,
+	0x48065808, 0x48025809, 0x59300007, 0x8c000500,
+	0x02020800, 0x00100e99, 0x497a3808, 0x0201f800,
+	0x000201ba, 0x0402004a, 0x411e6000, 0x0401fc3e,
+	0x0401f05a, 0x0401fc6d, 0x04000013, 0x49366009,
+	0x4a026406, 0x00000003, 0x492e6008, 0x591c0817,
+	0x591c1018, 0x48066017, 0x480a6018, 0x4d380000,
+	0x591e7403, 0x4d300000, 0x411e6000, 0x0401fc2e,
+	0x5c026000, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x0401f046, 0x59a80039, 0x48023a05, 0x0401f043,
+	0x59cc0407, 0x82000580, 0x0000000b, 0x04020025,
+	0x59340a00, 0x84040d0e, 0x48066a00, 0x592c0a04,
+	0x82040d00, 0x000000ff, 0x82040d80, 0x00000014,
+	0x04000003, 0x4a02621d, 0x00000003, 0x59300007,
+	0x8c000500, 0x02020800, 0x00100e99, 0x4d400000,
+	0x42028000, 0x00000003, 0x592c0a08, 0x0201f800,
+	0x00104e70, 0x0201f800, 0x000202da, 0x5c028000,
+	0x497a6008, 0x4a026403, 0x00000085, 0x4a026203,
+	0x00000009, 0x4a026406, 0x00000002, 0x42000800,
+	0x8000404b, 0x0201f800, 0x00020721, 0x0401f01b,
+	0x59cc0207, 0x82000580, 0x00002a00, 0x04020004,
+	0x59a80039, 0x48023a05, 0x0401f014, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x4a025a04, 0x00000103,
+	0x591c0007, 0x8c000500, 0x02020800, 0x00100e99,
+	0x591c0402, 0x48025c06, 0x4a025a06, 0x00000003,
+	0x0201f800, 0x000202c1, 0x0201f800, 0x00107911,
+	0x0201f800, 0x001049b2, 0x5c026000, 0x0201f800,
+	0x0002077d, 0x0401f002, 0x5c026000, 0x5c025800,
+	0x1c01f000, 0x0401f819, 0x0401f7fd, 0x4933c857,
+	0x83380580, 0x00000015, 0x04020004, 0x59a80039,
+	0x48023a05, 0x0401f00d, 0x83380580, 0x00000016,
+	0x0402000d, 0x4d300000, 0x411e6000, 0x0201f800,
+	0x0010a5df, 0x0201f800, 0x000206fd, 0x0201f800,
+	0x0002077d, 0x5c026000, 0x497a381c, 0x0201f800,
+	0x0002077d, 0x1c01f000, 0x591c0414, 0x84000540,
+	0x48023c14, 0x59cc100b, 0x4933c857, 0x491fc857,
+	0x492fc857, 0x4803c857, 0x480bc857, 0x8c08153c,
+	0x04000006, 0x59a80039, 0x48023a05, 0x497a381c,
+	0x0201f000, 0x0002077d, 0x4d300000, 0x411e6000,
+	0x0201f800, 0x00108bd7, 0x5c026000, 0x591c0406,
+	0x82000580, 0x00000000, 0x02000000, 0x0002077d,
+	0x591c0403, 0x82000580, 0x00000050, 0x0402000d,
+	0x4d300000, 0x411e6000, 0x4a026203, 0x00000001,
+	0x42000800, 0x80000043, 0x0201f800, 0x00020721,
+	0x5c026000, 0x497a381c, 0x0201f000, 0x0002077d,
+	0x591c0203, 0x82000580, 0x0000000d, 0x04000014,
+	0x812e59c0, 0x02000800, 0x001005d8, 0x591c0203,
+	0x82000580, 0x00000004, 0x04020011, 0x592c020a,
+	0x8c000502, 0x0400000e, 0x4a023812, 0x0fffffff,
+	0x592c0208, 0x8400051e, 0x48025a08, 0x42000000,
+	0x00000001, 0x48023a14, 0x0401f021, 0x42000000,
+	0x00000007, 0x48023a14, 0x0401f01d, 0x592c020a,
+	0x4803c857, 0x8c000500, 0x0402000b, 0x8c000502,
+	0x040007f7, 0x591c0414, 0x8c00051c, 0x040207eb,
+	0x591c0011, 0x4803c857, 0x800001c0, 0x040007f0,
+	0x0401f7e6, 0x8c08153a, 0x040207ed, 0x59cc000a,
+	0x592c180f, 0x4803c857, 0x480fc857, 0x800c0580,
+	0x040007e7, 0x59cc000a, 0x4803c857, 0x48023816,
+	0x42000000, 0x00000005, 0x48023a14, 0x0201f000,
+	0x00109259, 0x4933c857, 0x4d1c0000, 0x59cc0001,
+	0x59341002, 0x80080580, 0x82000500, 0x00ffffff,
+	0x04020041, 0x59301419, 0x0201f800, 0x00109410,
+	0x02000800, 0x001005d8, 0x591c1406, 0x82080580,
+	0x00000007, 0x04000038, 0x82080580, 0x00000002,
+	0x04000035, 0x82080580, 0x00000000, 0x04000032,
+	0x591c0202, 0x82000d80, 0x0000ffff, 0x04000004,
+	0x59301a19, 0x800c0580, 0x0402002b, 0x83380580,
+	0x00000015, 0x04000026, 0x4d300000, 0x4d2c0000,
+	0x411e6000, 0x59325808, 0x0201f800, 0x00109037,
+	0x02000800, 0x001005d8, 0x592c0204, 0x82000500,
+	0x000000ff, 0x82000580, 0x00000014, 0x04000003,
+	0x4a02621d, 0x00000003, 0x42028000, 0x00000003,
+	0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800,
+	0x000202da, 0x5c025800, 0x497a6008, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x42000800, 0x8000404b, 0x0201f800,
+	0x00020721, 0x5c026000, 0x0401f003, 0x59a80039,
+	0x48023a05, 0x497a381c, 0x0201f800, 0x0002077d,
+	0x5c023800, 0x1c01f000, 0x4933c857, 0x4c580000,
+	0x4d2c0000, 0x59325808, 0x83383580, 0x00000015,
+	0x04000010, 0x59342200, 0x84102502, 0x48126a00,
+	0x0201f800, 0x00109037, 0x04000066, 0x0201f800,
+	0x00109597, 0x04020005, 0x4200b000, 0x00000002,
+	0x0201f800, 0x0010957d, 0x0401fa0a, 0x0401f079,
+	0x83cc1400, 0x00000008, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000006, 0x0201f800, 0x0010855a,
+	0x04020015, 0x83cc1400, 0x0000000a, 0x4200b000,
+	0x00000002, 0x83341c00, 0x00000008, 0x0201f800,
+	0x0010855a, 0x0402000c, 0x0201f800, 0x00102074,
+	0x59342200, 0x59cc1007, 0x800811c0, 0x04000003,
+	0x480a6801, 0x84102542, 0x8410251a, 0x48126a00,
+	0x0401f05f, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x59340200, 0x84000558,
+	0x48026a00, 0x4d300000, 0x0201f800, 0x0002075a,
+	0x02000800, 0x001005d8, 0x49366009, 0x497a6008,
+	0x4a026406, 0x00000001, 0x4a026403, 0x00000001,
+	0x42003000, 0x00000003, 0x0201f800, 0x0010a942,
+	0x0201f800, 0x00103b25, 0x04000011, 0x41782800,
+	0x42003000, 0x00000001, 0x4d400000, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010a43e, 0x5c028000,
+	0x4a026406, 0x00000004, 0x4a026203, 0x00000007,
+	0x4a026420, 0x00000001, 0x0401f009, 0x4a026203,
+	0x00000001, 0x42000800, 0x0000000b, 0x0201f800,
+	0x00104571, 0x0201f800, 0x0010672b, 0x5c026000,
+	0x0201f800, 0x00109037, 0x04000022, 0x0201f800,
+	0x00109597, 0x04020022, 0x0401f9ae, 0x0401f01d,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x59340200, 0x84000558, 0x48026a00, 0x42003000,
+	0x00000003, 0x41782800, 0x42002000, 0x00000005,
+	0x4d400000, 0x4d440000, 0x59368c03, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x5c028000, 0x5c027800, 0x0201f800, 0x00102074,
+	0x0201f800, 0x0002077d, 0x0401f002, 0x0401fca9,
+	0x5c025800, 0x5c00b000, 0x1c01f000, 0x4933c857,
+	0x41380000, 0x83383480, 0x00000056, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x00107ef7, 0x00107ef2,
+	0x00107ef7, 0x00107ef7, 0x00107ef7, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef7, 0x00107ef0, 0x00107ef7,
+	0x00107ef7, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef7, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef7, 0x00107ef7, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef7, 0x00107ef7,
+	0x00107ef0, 0x00107ef7, 0x00107ef7, 0x00107ef0,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x00107ef0, 0x00107ef0, 0x00107ef0, 0x00107ef7,
+	0x0201f800, 0x001005d8, 0x4a026203, 0x00000001,
+	0x493a6403, 0x0201f000, 0x0010672b, 0x4933c857,
+	0x4a026203, 0x00000001, 0x493a6403, 0x0201f000,
+	0x0010672b, 0x4933c857, 0x59300403, 0x82003480,
+	0x00000056, 0x02021800, 0x001005d8, 0x83383580,
+	0x00000013, 0x04000093, 0x83383580, 0x00000027,
+	0x0402004b, 0x0201f800, 0x00106bbf, 0x0201f800,
+	0x00109134, 0x0400000b, 0x0201f800, 0x0010914e,
+	0x04000041, 0x59300403, 0x82000d80, 0x00000022,
+	0x04020038, 0x0401fc61, 0x0400003a, 0x0401f03a,
+	0x0201f800, 0x00102074, 0x42000800, 0x00000007,
+	0x0201f800, 0x00104571, 0x0401f8fe, 0x4d440000,
+	0x59368c03, 0x83440580, 0x000007fe, 0x04020008,
+	0x59a81026, 0x84081540, 0x0201f800, 0x0010513b,
+	0x04020002, 0x8408154a, 0x480b5026, 0x42028000,
+	0x00000029, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x836c0580, 0x00000003,
+	0x0400000c, 0x59326809, 0x59340008, 0x800001c0,
+	0x04020008, 0x59368c03, 0x4933c857, 0x4937c857,
+	0x4947c857, 0x0201f800, 0x001045fb, 0x0401f00c,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x42003000, 0x00000015, 0x41782800, 0x42002000,
+	0x00000003, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x0201f800, 0x00109326, 0x0201f000, 0x0002077d,
+	0x1c01f000, 0x0401f8cb, 0x0401f7fa, 0x83380580,
+	0x00000014, 0x0400000b, 0x0201f800, 0x00106f60,
+	0x02020000, 0x00107974, 0x59300203, 0x82000580,
+	0x00000002, 0x040000ed, 0x0201f800, 0x001005d8,
+	0x0201f800, 0x00106bbf, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x0010203c, 0x5c027800, 0x42003000,
+	0x00000016, 0x41782800, 0x4d400000, 0x4d440000,
+	0x59368c03, 0x42002000, 0x00000009, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x5c028000, 0x42000000, 0x0010b864, 0x0201f800,
+	0x0010aa47, 0x0201f800, 0x00109134, 0x0402000c,
+	0x0201f800, 0x00102074, 0x0401f89e, 0x59340c03,
+	0x82040580, 0x000007fe, 0x040207ca, 0x59a80826,
+	0x84040d40, 0x48075026, 0x0401f7c6, 0x0201f800,
+	0x0010914e, 0x04020003, 0x0401f892, 0x0401f7c1,
+	0x59300403, 0x82000d80, 0x00000032, 0x04020004,
+	0x0201f800, 0x0010230c, 0x0401f7ba, 0x59300403,
+	0x82000d80, 0x00000022, 0x04000886, 0x0401f7b5,
+	0x4803c857, 0x0c01f001, 0x00108016, 0x00108016,
+	0x00108016, 0x00108016, 0x00108016, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff9, 0x00108016, 0x00107ff0, 0x00108016,
+	0x00108016, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00108016, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00107ff0,
+	0x00108007, 0x00108016, 0x00107ff0, 0x00108000,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108000,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x00108003, 0x00107ff0, 0x00107ff2, 0x00108016,
+	0x00107ff0, 0x00108016, 0x00108016, 0x00107ff0,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x00107ff0, 0x00107ff0, 0x00107ff0, 0x00108016,
+	0x0201f800, 0x001005d8, 0x4d2c0000, 0x59325808,
+	0x0201f800, 0x000202da, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x4a026203, 0x00000005, 0x59a80039,
+	0x48026205, 0x59a80037, 0x48026206, 0x1c01f000,
+	0x5930081e, 0x49780a05, 0x0401f014, 0x0201f800,
+	0x00109326, 0x0201f000, 0x0002077d, 0x0201f800,
+	0x0010230c, 0x0201f800, 0x00106c55, 0x04000005,
+	0x0201f800, 0x00106bbf, 0x0201f000, 0x0002077d,
+	0x0201f800, 0x00106bbf, 0x0201f800, 0x0002077d,
+	0x0201f000, 0x00106c4b, 0x4933c857, 0x4a026203,
+	0x00000002, 0x59a80037, 0x48026206, 0x1c01f000,
+	0x4933c857, 0x0201f800, 0x00109037, 0x0400002a,
+	0x4d2c0000, 0x0201f800, 0x00109597, 0x0402000a,
+	0x4d400000, 0x42028000, 0x00000031, 0x42000800,
+	0x00000004, 0x0201f800, 0x0010943b, 0x5c028000,
+	0x0401f01c, 0x59300c06, 0x82040580, 0x00000010,
+	0x04000004, 0x82040580, 0x00000011, 0x0402000a,
+	0x4a025a06, 0x00000031, 0x4a02580d, 0x00000004,
+	0x4a02580e, 0x000000ff, 0x0201f800, 0x000202da,
+	0x0401f00c, 0x592c0404, 0x8c00051e, 0x04000009,
+	0x4a025a04, 0x00000103, 0x4a025805, 0x01000000,
+	0x5931d821, 0x58ef400b, 0x58ec0009, 0x0801f800,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x59340400,
+	0x82000500, 0x000000ff, 0x82003480, 0x0000000c,
+	0x02021800, 0x001005d8, 0x59303403, 0x82180d80,
+	0x0000004d, 0x02000000, 0x0010938b, 0x82180d80,
+	0x00000033, 0x02000000, 0x00109349, 0x82180d80,
+	0x00000028, 0x02000000, 0x0010918f, 0x82180d80,
+	0x00000029, 0x02000000, 0x001091a3, 0x82180d80,
+	0x0000001f, 0x02000000, 0x00107b28, 0x82180d80,
+	0x00000055, 0x02000000, 0x00107b01, 0x82180d80,
+	0x00000000, 0x04000591, 0x82180d80, 0x00000022,
+	0x02000000, 0x00107b55, 0x82180d80, 0x00000035,
+	0x02000000, 0x00107c50, 0x82180d80, 0x00000039,
+	0x04000539, 0x82180d80, 0x0000003d, 0x02000000,
+	0x00107b85, 0x82180d80, 0x00000044, 0x02000000,
+	0x00107bc2, 0x82180d80, 0x00000049, 0x02000000,
+	0x00107c17, 0x82180d80, 0x00000041, 0x02000000,
+	0x00107c03, 0x82180d80, 0x00000043, 0x02000000,
+	0x001094dc, 0x82180d80, 0x00000051, 0x02000000,
+	0x00109542, 0x82180d80, 0x00000004, 0x04020003,
+	0x42000000, 0x00000001, 0x83380d80, 0x00000015,
+	0x04000006, 0x83380d80, 0x00000016, 0x02020000,
+	0x00107974, 0x0401f20f, 0x4d2c0000, 0x4d3c0000,
+	0x0c01f804, 0x5c027800, 0x5c025800, 0x1c01f000,
+	0x001080b8, 0x001080bc, 0x001080b8, 0x00108131,
+	0x001080b8, 0x00108226, 0x001082bf, 0x001080b8,
+	0x001080b8, 0x00108288, 0x001080b8, 0x0010829a,
+	0x4933c857, 0x497a6007, 0x59300808, 0x58040000,
+	0x4a000a04, 0x00000103, 0x0201f000, 0x0002077d,
+	0x4933c857, 0x40000000, 0x40000000, 0x1c01f000,
+	0x4933c857, 0x59a80016, 0x82000580, 0x00000074,
+	0x0402005c, 0x0201f800, 0x0010a2c8, 0x04020016,
+	0x0401f85c, 0x0201f800, 0x00109037, 0x0400000c,
+	0x0201f800, 0x00109597, 0x04020009, 0x41780800,
+	0x4d400000, 0x42028000, 0x00000000, 0x0201f800,
+	0x0010943b, 0x5c028000, 0x0401f003, 0x0201f800,
+	0x00102074, 0x0201f800, 0x001048c1, 0x0201f000,
+	0x0002077d, 0x0201f800, 0x00109037, 0x04000007,
+	0x0201f800, 0x00109597, 0x04020004, 0x0401ff3d,
+	0x0201f000, 0x0002077d, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x42000000, 0x0010b864, 0x0201f800,
+	0x0010aa47, 0x59340200, 0x84000558, 0x48026a00,
+	0x42003000, 0x00000003, 0x0201f800, 0x0010a942,
+	0x4d300000, 0x0201f800, 0x0002075a, 0x02000800,
+	0x001005d8, 0x49366009, 0x497a6008, 0x4a026406,
+	0x00000001, 0x4a026403, 0x00000001, 0x0201f800,
+	0x00103b25, 0x04000011, 0x4a026406, 0x00000004,
+	0x4a026203, 0x00000007, 0x4a026420, 0x00000001,
+	0x42003000, 0x00000001, 0x4d400000, 0x42028000,
+	0x00000029, 0x41782800, 0x0201f800, 0x0010a43e,
+	0x5c028000, 0x0401f009, 0x42000800, 0x0000000b,
+	0x0201f800, 0x00104571, 0x4a026203, 0x00000001,
+	0x0201f800, 0x0010672b, 0x5c026000, 0x0401ff05,
+	0x0201f800, 0x00102074, 0x0201f000, 0x0002077d,
+	0x0401ff00, 0x42000000, 0x00000001, 0x0401f0c7,
+	0x4933c857, 0x59340200, 0x8c000500, 0x0400000d,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x00104567,
+	0x5c027800, 0x0201f800, 0x00103b25, 0x04000005,
+	0x42000800, 0x00000006, 0x0201f800, 0x00104571,
+	0x1c01f000, 0x4933c857, 0x59a80816, 0x82040580,
+	0x00000074, 0x0400000e, 0x4807c857, 0x82040580,
+	0x00000100, 0x040200a0, 0x59cc0408, 0x4803c857,
+	0x8c000500, 0x0400009c, 0x59341403, 0x82080580,
+	0x000007fe, 0x04000006, 0x0401f097, 0x59341403,
+	0x82080580, 0x000007fe, 0x04020003, 0x0401fa9c,
+	0x0401f04c, 0x0201f800, 0x0010462a, 0x59341403,
+	0x82080580, 0x000007fc, 0x0402001f, 0x4a026802,
+	0x00fffffc, 0x0201f800, 0x00109037, 0x04000012,
+	0x0201f800, 0x00109597, 0x0402000f, 0x0401f8a9,
+	0x41780800, 0x4d400000, 0x42028000, 0x00000000,
+	0x0201f800, 0x0010943b, 0x5c028000, 0x42000800,
+	0x00000004, 0x0201f800, 0x00104571, 0x0201f000,
+	0x0002077d, 0x42000800, 0x00000004, 0x0201f800,
+	0x00104571, 0x0201f800, 0x00102074, 0x0201f000,
+	0x0002077d, 0x59a80005, 0x8c000514, 0x04000011,
+	0x0201f800, 0x0010513b, 0x42001000, 0x00000010,
+	0x04020009, 0x59340002, 0x82000500, 0x00ff0000,
+	0x82000580, 0x00ff0000, 0x04000006, 0x42001000,
+	0x00000008, 0x0201f800, 0x00104c6d, 0x0402005a,
+	0x0201f800, 0x00109037, 0x0400005b, 0x0201f800,
+	0x00109597, 0x04020005, 0x592c0404, 0x8c00051c,
+	0x040207c9, 0x0401f877, 0x42000800, 0x00000005,
+	0x0201f800, 0x00104571, 0x4a026203, 0x00000001,
+	0x4a026403, 0x00000003, 0x0201f000, 0x0010672b,
+	0x59cc0408, 0x8c000518, 0x04000010, 0x0201f800,
+	0x001092e5, 0x0201f800, 0x0010513b, 0x04000004,
+	0x59cc0408, 0x8c000516, 0x040207b3, 0x59a80026,
+	0x8400054a, 0x48035026, 0x59a80010, 0x84000570,
+	0x48038832, 0x0401f7ac, 0x42001000, 0x000000ef,
+	0x480b5010, 0x497b8830, 0x84081570, 0x480b8832,
+	0x59c40802, 0x84040d4c, 0x48078802, 0x0201f800,
+	0x0010930f, 0x59a80026, 0x84000548, 0x48035026,
+	0x0201f800, 0x0010a3da, 0x0402079b, 0x59a80026,
+	0x8400054c, 0x48035026, 0x42000800, 0x00000006,
+	0x0201f800, 0x00104571, 0x417a7800, 0x0201f800,
+	0x00104567, 0x42000000, 0x000000e8, 0x0201f800,
+	0x00105c9a, 0x02000800, 0x001045a6, 0x02020800,
+	0x001005d8, 0x49366009, 0x59340200, 0x8400051a,
+	0x48026a00, 0x42000800, 0x00000003, 0x0201f800,
+	0x00104571, 0x4a026406, 0x00000001, 0x4a026203,
+	0x00000001, 0x4a026403, 0x00000002, 0x0201f000,
+	0x0010672b, 0x0401fe43, 0x42000000, 0x00000001,
+	0x0401f00a, 0x599c0017, 0x8c00050a, 0x040007ab,
+	0x42000800, 0x00000004, 0x0201f800, 0x00104571,
+	0x0201f000, 0x0002077d, 0x4933c857, 0x80003540,
+	0x04000005, 0x42000800, 0x00000007, 0x0201f800,
+	0x00104571, 0x801831c0, 0x0402000e, 0x59302008,
+	0x801021c0, 0x04000004, 0x58100404, 0x8c00051e,
+	0x04020008, 0x59341c03, 0x42002000, 0x00000004,
+	0x42003000, 0x00000012, 0x0201f800, 0x00103aae,
+	0x0201f800, 0x00102074, 0x0201f000, 0x0002077d,
+	0x4c5c0000, 0x4d2c0000, 0x59325808, 0x0201f800,
+	0x00105755, 0x5c025800, 0x59cc0008, 0x48002805,
+	0x59cc0009, 0x48002806, 0x49782807, 0x49782808,
+	0x49782809, 0x4978280a, 0x59cc0013, 0x8c00053e,
+	0x04000009, 0x59cc0414, 0x900001c0, 0x59ccbc15,
+	0x805c0540, 0x48002807, 0x59cc0416, 0x900001c0,
+	0x48002808, 0x59cc0017, 0x8c00053e, 0x04000009,
+	0x59cc0418, 0x900001c0, 0x59ccbc19, 0x805c0540,
+	0x48002809, 0x59cc041a, 0x900001c0, 0x4800280a,
+	0x5c00b800, 0x1c01f000, 0x4933c857, 0x59a80016,
+	0x82000580, 0x00000014, 0x04020048, 0x59a80005,
+	0x8c000514, 0x04000015, 0x0201f800, 0x0010513b,
+	0x42001000, 0x00000010, 0x04020009, 0x59340002,
+	0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000,
+	0x0400000a, 0x42001000, 0x00000008, 0x0201f800,
+	0x00104c6d, 0x04000005, 0x59a80005, 0x84000556,
+	0x48035005, 0x0401f031, 0x836c0580, 0x00000003,
+	0x0402000b, 0x59300008, 0x80000540, 0x04020008,
+	0x59341c03, 0x42002000, 0x00000006, 0x42003000,
+	0x00000013, 0x0201f800, 0x00103aae, 0x0201f800,
+	0x0010468d, 0x0401fecf, 0x0401fa1d, 0x0402001f,
+	0x59340404, 0x80000540, 0x0400001c, 0x42000800,
+	0x00000006, 0x0201f800, 0x00104571, 0x0201f800,
+	0x00109037, 0x04000011, 0x0201f800, 0x00109597,
+	0x0402000a, 0x41780800, 0x4d400000, 0x42028000,
+	0x00000000, 0x0201f800, 0x0010943b, 0x5c028000,
+	0x0201f000, 0x0002077d, 0x4a025a04, 0x00000103,
+	0x4a025805, 0x02000000, 0x0201f800, 0x00102074,
+	0x0201f000, 0x0002077d, 0x0201f800, 0x00104c19,
+	0x0201f800, 0x00109037, 0x04000007, 0x0201f800,
+	0x00109597, 0x04020004, 0x0401fda2, 0x0201f000,
+	0x0002077d, 0x0401fd9f, 0x80000580, 0x59a80005,
+	0x8c000516, 0x04000005, 0x84000516, 0x48035005,
+	0x82000540, 0x00000001, 0x0401ff60, 0x1c01f000,
+	0x4933c857, 0x59a80016, 0x82000580, 0x00000014,
+	0x0402000b, 0x42000800, 0x0000000b, 0x0201f800,
+	0x00104571, 0x4a026203, 0x00000001, 0x4a026403,
+	0x00000001, 0x0201f000, 0x0010672b, 0x42000000,
+	0x00000001, 0x0401f74d, 0x4933c857, 0x40003000,
+	0x59a80016, 0x82000580, 0x00000004, 0x0402000a,
+	0x82183580, 0x0000000b, 0x04020005, 0x42000800,
+	0x00000007, 0x0201f800, 0x00104571, 0x0201f000,
+	0x0002077d, 0x42000000, 0x00000001, 0x0401f73b,
+	0x4803c857, 0x4d2c0000, 0x4d3c0000, 0x0c01f804,
+	0x5c027800, 0x5c025800, 0x1c01f000, 0x001080b8,
+	0x001082ce, 0x001080b8, 0x00108323, 0x001080b8,
+	0x00108391, 0x001082bf, 0x001080b8, 0x001080b8,
+	0x001083b1, 0x001080b8, 0x001083c1, 0x4933c857,
+	0x4d1c0000, 0x59301403, 0x82080580, 0x00000003,
+	0x04000008, 0x82081580, 0x0000001e, 0x04020003,
+	0x0201f800, 0x0002077d, 0x5c023800, 0x1c01f000,
+	0x0401ff5a, 0x0401f7fd, 0x4933c857, 0x0201f800,
+	0x00109037, 0x0400000b, 0x0201f800, 0x00109597,
+	0x04020008, 0x4200b000, 0x00000002, 0x0201f800,
+	0x0010957d, 0x0401fd43, 0x0201f000, 0x0002077d,
+	0x0401f8f5, 0x04020030, 0x417a7800, 0x0201f800,
+	0x00104567, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x59340200, 0x84000558, 0x48026a00, 0x4a026403,
+	0x00000002, 0x42003000, 0x00000003, 0x0201f800,
+	0x0010a942, 0x0201f800, 0x00103b25, 0x04000011,
+	0x4d400000, 0x41782800, 0x42003000, 0x00000005,
+	0x42028000, 0x00000029, 0x0201f800, 0x0010a43e,
+	0x5c028000, 0x4a026203, 0x00000007, 0x4a026406,
+	0x00000004, 0x4a026420, 0x00000001, 0x1c01f000,
+	0x42000800, 0x00000003, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x0201f800, 0x0010672b,
+	0x0401f7f7, 0x59cc0407, 0x82000580, 0x00000009,
+	0x0402000a, 0x59340412, 0x82000500, 0x000000ff,
+	0x0400000c, 0x80000040, 0x48026c12, 0x4a026206,
+	0x0000000a, 0x0401f7ea, 0x59cc0207, 0x82000500,
+	0x0000ff00, 0x82000580, 0x00001900, 0x040007c2,
+	0x0401fcfc, 0x80000580, 0x0401f6c4, 0x4933c857,
+	0x59a80032, 0x80000540, 0x04000015, 0x59340403,
+	0x82000580, 0x000007fe, 0x04020011, 0x59a80010,
+	0x80000000, 0x48035010, 0x417a7800, 0x0201f800,
+	0x00104567, 0x42000800, 0x00000003, 0x0201f800,
+	0x00104571, 0x4a026203, 0x00000001, 0x4a026403,
+	0x00000002, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x00109037, 0x04000011, 0x0201f800, 0x00109597,
+	0x0402000e, 0x4c580000, 0x4200b000, 0x00000002,
+	0x0201f800, 0x0010957d, 0x5c00b000, 0x0401fcd5,
+	0x42000800, 0x00000007, 0x0201f800, 0x00104571,
+	0x0201f000, 0x0002077d, 0x0401fcce, 0x59cc3407,
+	0x82183500, 0x000000ff, 0x82180580, 0x00000005,
+	0x0400001c, 0x82180580, 0x0000000b, 0x04000016,
+	0x59cc0207, 0x82000500, 0x0000ff00, 0x04020004,
+	0x82180580, 0x00000009, 0x04000012, 0x82000580,
+	0x00001900, 0x0402000c, 0x82180580, 0x00000009,
+	0x0400000c, 0x42000800, 0x00000004, 0x0201f800,
+	0x00104571, 0x0201f800, 0x00102074, 0x0201f000,
+	0x0002077d, 0x42000000, 0x00000001, 0x0401f677,
+	0x0201f800, 0x00109037, 0x59325808, 0x04000008,
+	0x592c0204, 0x82000580, 0x00000139, 0x040007f6,
+	0x592c0404, 0x8c00051e, 0x040207f3, 0x59340403,
+	0x82000580, 0x000007fe, 0x04020007, 0x59a80026,
+	0x84000540, 0x48035026, 0x0201f800, 0x00104229,
+	0x0401f7e9, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x42003000, 0x00000005, 0x0201f800, 0x0010a942,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x0401f7dd, 0x4933c857, 0x0401f84d, 0x0402000b,
+	0x42000800, 0x00000005, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000003,
+	0x0201f000, 0x0010672b, 0x42000800, 0x00000004,
+	0x0201f800, 0x00104571, 0x0201f800, 0x00109597,
+	0x0402000a, 0x4c580000, 0x4200b000, 0x00000002,
+	0x0201f800, 0x0010957d, 0x5c00b000, 0x0401fc71,
+	0x0201f000, 0x0002077d, 0x0401fc6e, 0x80000580,
+	0x0401f636, 0x4933c857, 0x0401f82d, 0x0402000b,
+	0x42000800, 0x00000009, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000005,
+	0x0201f000, 0x0010672b, 0x42000000, 0x00000001,
+	0x0401f626, 0x4933c857, 0x0401f81d, 0x0402000b,
+	0x42000800, 0x0000000b, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000001,
+	0x0201f000, 0x0010672b, 0x42000000, 0x00000001,
+	0x0401f616, 0x4933c857, 0x59cc0407, 0x82000580,
+	0x00000003, 0x04020009, 0x59cc0207, 0x82000500,
+	0x0000ff00, 0x82000d80, 0x00002a00, 0x04000003,
+	0x82000d80, 0x00001e00, 0x1c01f000, 0x4933c857,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4933c857,
+	0x4d400000, 0x4c580000, 0x59a80026, 0x82000540,
+	0x00000003, 0x48035026, 0x0401f85c, 0x04000038,
+	0x4d340000, 0x4d440000, 0x59a80026, 0x84000552,
+	0x48035026, 0x0201f800, 0x00103b25, 0x0400000c,
+	0x42028000, 0x0000002a, 0x42028800, 0x0000ffff,
+	0x42003000, 0x00000002, 0x0201f800, 0x0010a446,
+	0x59a80805, 0x84040d44, 0x48075005, 0x42028000,
+	0x0000002a, 0x4d3c0000, 0x42027800, 0x00000204,
+	0x0201f800, 0x00101fe5, 0x5c027800, 0x42000000,
+	0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800,
+	0x00101e45, 0x4200b000, 0x00000010, 0x42028800,
+	0x000007f0, 0x4d2c0000, 0x83440580, 0x000007fe,
+	0x04000003, 0x0201f800, 0x001045fb, 0x81468800,
+	0x8058b040, 0x040207f9, 0x5c025800, 0x59cc0408,
+	0x8c00051e, 0x04000004, 0x59a80026, 0x84000512,
+	0x48035026, 0x5c028800, 0x5c026800, 0x0201f800,
+	0x0010462a, 0x4a026802, 0x00fffffe, 0x59a80826,
+	0x84040d50, 0x59cc0013, 0x8c00053e, 0x04000003,
+	0x8c000536, 0x04000004, 0x59cc0017, 0x8c000536,
+	0x04020002, 0x84040d10, 0x48075026, 0x59cc0800,
+	0x82040d00, 0x00ffffff, 0x48075010, 0x80040110,
+	0x4803501d, 0x48038881, 0x0201f800, 0x0010513b,
+	0x04000007, 0x59cc0009, 0x48035035, 0x59cc000a,
+	0x48035036, 0x0201f800, 0x001092e5, 0x5c00b000,
+	0x5c028000, 0x1c01f000, 0x4933c857, 0x4c580000,
+	0x59a80010, 0x82000500, 0x00ffff00, 0x04000022,
+	0x59cc1000, 0x82081500, 0x00ffff00, 0x80080580,
+	0x04000004, 0x42000000, 0x0010b83b, 0x0401f016,
+	0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000006, 0x0401f900, 0x04000004,
+	0x42000000, 0x0010b83c, 0x0401f00b, 0x83cc1400,
+	0x0000000d, 0x4200b000, 0x00000002, 0x83341c00,
+	0x00000008, 0x0401f8f5, 0x04000007, 0x42000000,
+	0x0010b83d, 0x0201f800, 0x0010aa47, 0x82000540,
+	0x00000001, 0x5c00b000, 0x1c01f000, 0x4933c857,
+	0x59cc0206, 0x82000580, 0x00000014, 0x04020016,
+	0x59cc0407, 0x82000580, 0x00000800, 0x04020012,
+	0x59cc0207, 0x8c00051a, 0x0400000d, 0x82000500,
+	0x00000f00, 0x82000580, 0x00000100, 0x04020008,
+	0x59cc020a, 0x8c000508, 0x04020003, 0x8c00050a,
+	0x04000003, 0x80000580, 0x1c01f000, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4933c857, 0x4943c857,
+	0x493fc857, 0x4c5c0000, 0x4d300000, 0x4d340000,
+	0x4d2c0000, 0x4d380000, 0x4130b800, 0x42026000,
+	0x0010d1c0, 0x59a8000e, 0x81640480, 0x040210bd,
+	0x8d3e7d12, 0x04000004, 0x405c0000, 0x81300580,
+	0x040000b3, 0x59300406, 0x82000c80, 0x00000012,
+	0x04021015, 0x59326809, 0x0c01f001, 0x0010854f,
+	0x001084bc, 0x001084d3, 0x001084de, 0x001084b7,
+	0x001084ce, 0x00108507, 0x0010854f, 0x001084b5,
+	0x0010851b, 0x0010852a, 0x001084b5, 0x001084b5,
+	0x001084b5, 0x001084b5, 0x0010854f, 0x00108540,
+	0x00108538, 0x0201f800, 0x001005d8, 0x8d3e7d18,
+	0x04000004, 0x59300420, 0x8c000500, 0x04020094,
+	0x59300403, 0x82000580, 0x00000043, 0x04000090,
+	0x0201f800, 0x00109134, 0x02000800, 0x00102074,
+	0x0201f800, 0x0010914e, 0x02000800, 0x0010801c,
+	0x8d3e7d06, 0x04000084, 0x0201f800, 0x001092d7,
+	0x04000083, 0x0401f080, 0x8d3e7d16, 0x04000004,
+	0x59300420, 0x8c000500, 0x0402007d, 0x59325808,
+	0x0201f800, 0x00109037, 0x04000077, 0x49425a06,
+	0x497a5c09, 0x0201f800, 0x000202da, 0x0201f800,
+	0x0010912a, 0x0401f070, 0x813669c0, 0x02000800,
+	0x001005d8, 0x8d3e7d06, 0x04000004, 0x59340200,
+	0x8c00050e, 0x0402006a, 0x59300004, 0x8400055c,
+	0x48026004, 0x59300203, 0x82000580, 0x00000004,
+	0x02000800, 0x00100e99, 0x59325808, 0x0201f800,
+	0x00109037, 0x0400005c, 0x4a025a04, 0x00000103,
+	0x59300402, 0x48025c06, 0x592c0408, 0x8c000512,
+	0x04000006, 0x4d2c0000, 0x592e5809, 0x0201f800,
+	0x001007fd, 0x5c025800, 0x49425a06, 0x497a5c09,
+	0x0201f800, 0x0010959c, 0x0201f800, 0x000202da,
+	0x0201f800, 0x0010912a, 0x0401f047, 0x8c000518,
+	0x04000047, 0x59300203, 0x82000580, 0x00000004,
+	0x02000800, 0x00100e99, 0x59325808, 0x0201f800,
+	0x00109037, 0x0400003c, 0x49425a06, 0x497a5c09,
+	0x0201f800, 0x0010a693, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x000202da, 0x0401f033, 0x0201f800,
+	0x001062d5, 0x04000032, 0x59300203, 0x82000580,
+	0x00000004, 0x04020004, 0x0201f800, 0x00100e99,
+	0x0401f02b, 0x42027000, 0x00000047, 0x0201f800,
+	0x000207a1, 0x0401f026, 0x59300203, 0x82000580,
+	0x00000004, 0x02000800, 0x00100e99, 0x59325808,
+	0x0201f800, 0x00109037, 0x0400001b, 0x49425a06,
+	0x497a5c09, 0x0201f800, 0x000202da, 0x0401f016,
+	0x833c0500, 0x00001800, 0x04000015, 0x8d3e7d16,
+	0x04020013, 0x59325817, 0x0201f800, 0x001007fd,
+	0x59300203, 0x82000580, 0x00000004, 0x02000800,
+	0x00100e99, 0x59325808, 0x0201f800, 0x00109037,
+	0x04000005, 0x49425a06, 0x497a5c09, 0x0201f800,
+	0x000202da, 0x0201f800, 0x00107911, 0x83326400,
+	0x00000024, 0x41580000, 0x81300480, 0x04001742,
+	0x5c027000, 0x5c025800, 0x5c026800, 0x5c026000,
+	0x5c00b800, 0x1c01f000, 0x5c000000, 0x4c000000,
+	0x4803c857, 0x480bc857, 0x480fc857, 0x485bc857,
+	0x50080800, 0x500c0000, 0x80042580, 0x04020007,
+	0x80081000, 0x800c1800, 0x8058b040, 0x040207f9,
+	0x80000580, 0x1c01f000, 0x4803c857, 0x4807c857,
+	0x480bc857, 0x480fc857, 0x80040480, 0x04001006,
+	0x42000000, 0x00000001, 0x82040d40, 0x00000001,
+	0x1c01f000, 0x41780000, 0x0401f7fc, 0x83380480,
+	0x00000053, 0x02021800, 0x001005d8, 0x83380480,
+	0x0000004b, 0x02001800, 0x001005d8, 0x0c01f001,
+	0x0010858a, 0x0010858a, 0x0010858a, 0x0010858a,
+	0x00108588, 0x00108588, 0x00108588, 0x0010858a,
+	0x0201f800, 0x001005d8, 0x493bc857, 0x4a026203,
+	0x0000000d, 0x493a6403, 0x42000800, 0x80000000,
+	0x0201f000, 0x00020721, 0x83380580, 0x00000013,
+	0x04020008, 0x59300403, 0x82000580, 0x00000050,
+	0x02020800, 0x001005d8, 0x0201f000, 0x0002077d,
+	0x4933c857, 0x83380580, 0x00000027, 0x04020030,
+	0x4933c857, 0x0201f800, 0x00106bbf, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+	0x492fc857, 0x0400000d, 0x4a025a04, 0x00000103,
+	0x59300c02, 0x48065c06, 0x4a025a06, 0x00000029,
+	0x497a5c09, 0x592c0c08, 0x84040d50, 0x48065c08,
+	0x0201f800, 0x000202da, 0x5c025800, 0x42003000,
+	0x00000015, 0x41782800, 0x42002000, 0x00000003,
+	0x4d400000, 0x4d440000, 0x59368c03, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x5c028000, 0x0201f000, 0x0002077d, 0x83380580,
+	0x00000014, 0x0402000c, 0x59300403, 0x82000c80,
+	0x00000053, 0x02021800, 0x001005d8, 0x82000480,
+	0x00000040, 0x02001800, 0x001005d8, 0x4803c857,
+	0x0c01f00e, 0x83380580, 0x00000053, 0x0400000a,
+	0x83380580, 0x00000048, 0x02020800, 0x001005d8,
+	0x59300403, 0x82000580, 0x00000050, 0x02020800,
+	0x001005d8, 0x1c01f000, 0x001085ff, 0x001085fd,
+	0x001085fd, 0x001085fd, 0x001085fd, 0x001085fd,
+	0x001085fd, 0x001085fd, 0x001085fd, 0x001085fd,
+	0x001085fd, 0x00108616, 0x00108616, 0x00108616,
+	0x00108616, 0x001085fd, 0x00108616, 0x001085fd,
+	0x00108616, 0x0201f800, 0x001005d8, 0x4933c857,
+	0x0201f800, 0x00106bbf, 0x0201f800, 0x00109037,
+	0x02000000, 0x0002077d, 0x4d2c0000, 0x59325808,
+	0x4a025a04, 0x00000103, 0x59300402, 0x48025c06,
+	0x4a025a06, 0x00000006, 0x497a5c09, 0x0201f800,
+	0x000202da, 0x5c025800, 0x0201f800, 0x0010912a,
+	0x0201f000, 0x0002077d, 0x4933c857, 0x0201f800,
+	0x00106bbf, 0x0201f000, 0x0002077d, 0x0201f800,
+	0x001005d8, 0x5930001c, 0x800001c0, 0x02020800,
+	0x0010984e, 0x59300004, 0x8c00053e, 0x04020029,
+	0x59325808, 0x592c0c08, 0x59cc2a08, 0x82141d00,
+	0x00000c00, 0x04000002, 0x59cc1809, 0x84040d58,
+	0x48065c08, 0x82143500, 0x00000fff, 0x04020027,
+	0x59340200, 0x8c00050e, 0x04020080, 0x0201f800,
+	0x0002082b, 0x04020006, 0x4a025a06, 0x00000000,
+	0x59300811, 0x800409c0, 0x0402094b, 0x4a025a04,
+	0x00000103, 0x48065807, 0x480e580a, 0x48165c09,
+	0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1,
+	0x0201f800, 0x001049b2, 0x59cc0208, 0x8c000518,
+	0x02020000, 0x001091d1, 0x0201f000, 0x0002077d,
+	0x0201f800, 0x00106f60, 0x040007d6, 0x4d3c0000,
+	0x42027800, 0x00000002, 0x0201f800, 0x00108be3,
+	0x5c027800, 0x0401f7cf, 0x4817c857, 0x480fc857,
+	0x82180500, 0x000000ff, 0x0400000e, 0x592c0204,
+	0x82000500, 0x000000ff, 0x82000580, 0x00000048,
+	0x04020008, 0x592c0407, 0x800001c0, 0x04000005,
+	0x0201f800, 0x0010973f, 0x0201f000, 0x00109787,
+	0x82180d00, 0x00000c00, 0x04000004, 0x59340200,
+	0x8c00050e, 0x04020032, 0x4a025a06, 0x00000000,
+	0x41782000, 0x8c183510, 0x04000007, 0x59cc000c,
+	0x82000500, 0x000000ff, 0x04000002, 0x4803c857,
+	0x59cc200b, 0x4812580c, 0x41780000, 0x8c183512,
+	0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00,
+	0x040007b8, 0x82041480, 0x0000001d, 0x04001006,
+	0x592c0404, 0x8c00051e, 0x0400000e, 0x42000800,
+	0x0000001c, 0x4c500000, 0x4c540000, 0x83cca400,
+	0x0000000c, 0x832cac00, 0x0000000d, 0x0201f800,
+	0x00108b9f, 0x5c00a800, 0x5c00a000, 0x0401f7a5,
+	0x59300011, 0x59301402, 0x480a5c06, 0x48025807,
+	0x480e580a, 0x48165c09, 0x0201f800, 0x00108b48,
+	0x0201f800, 0x00108b84, 0x0401f7a6, 0x592c020a,
+	0x8c000502, 0x040007cd, 0x592c0208, 0x8c00050e,
+	0x040207ca, 0x59300011, 0x800c0d80, 0x040007c7,
+	0x4803c857, 0x480fc857, 0x8c183514, 0x02000000,
+	0x0010920f, 0x80000540, 0x040007c0, 0x4807c856,
+	0x0201f000, 0x0010920f, 0x592c020a, 0x8c000502,
+	0x04000782, 0x59300011, 0x800001c0, 0x0400077f,
+	0x592c0208, 0x8c00050e, 0x0402077c, 0x0201f000,
+	0x0010920f, 0x59cc2006, 0x59cc2807, 0x0401f035,
+	0x0401f034, 0x1c01f000, 0x4933c857, 0x5930001c,
+	0x800001c0, 0x02020800, 0x0010984e, 0x59325808,
+	0x592c0c08, 0x41782800, 0x41781800, 0x84040d58,
+	0x48065c08, 0x41783000, 0x59340200, 0x8c00050e,
+	0x04020018, 0x0201f800, 0x0002082b, 0x04020007,
+	0x4a025a06, 0x00000000, 0x59300811, 0x4807c857,
+	0x800409c0, 0x040208ac, 0x4a025a04, 0x00000103,
+	0x48065807, 0x480e580a, 0x48165c09, 0x4933c857,
+	0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1,
+	0x0201f800, 0x001049b2, 0x0201f000, 0x0002077d,
+	0x592c020a, 0x8c000502, 0x040007ea, 0x59300011,
+	0x4803c857, 0x800001c0, 0x040007e6, 0x592c0208,
+	0x8c00050e, 0x040207e3, 0x0201f000, 0x0010920f,
+	0x5930001c, 0x800001c0, 0x4c100000, 0x4c140000,
+	0x02020800, 0x0010984e, 0x5c002800, 0x5c002000,
+	0x4a026203, 0x00000002, 0x4a026403, 0x00000043,
+	0x59325808, 0x592c020a, 0x8c000502, 0x04020018,
+	0x40100000, 0x592c080f, 0x80040c80, 0x40140000,
+	0x80040480, 0x04001014, 0x48126013, 0x48166011,
+	0x59300004, 0x8c00053e, 0x04020008, 0x497a6205,
+	0x0201f800, 0x00100f93, 0x04020009, 0x59300804,
+	0x0201f000, 0x00106721, 0x0201f800, 0x00106f60,
+	0x040007f7, 0x0201f000, 0x00107974, 0x4933c857,
+	0x1c01f000, 0x4807c857, 0x40042800, 0x0401f7eb,
+	0x83380480, 0x00000058, 0x04021005, 0x83380480,
+	0x00000040, 0x04001002, 0x0c01f002, 0x1c01f000,
+	0x00108740, 0x00108740, 0x00108740, 0x00108740,
+	0x00108740, 0x00108740, 0x00108740, 0x00108740,
+	0x00108740, 0x00108740, 0x00108742, 0x00108740,
+	0x00108740, 0x00108740, 0x00108740, 0x0010874f,
+	0x00108740, 0x00108740, 0x00108740, 0x00108740,
+	0x0010877d, 0x00108740, 0x00108740, 0x00108740,
+	0x0201f800, 0x001005d8, 0x4933c857, 0x0201f800,
+	0x00106dc3, 0x4a026203, 0x00000002, 0x59a80039,
+	0x48026205, 0x59300011, 0x59300815, 0x80040c80,
+	0x48066015, 0x0201f000, 0x00106b8a, 0x4933c857,
+	0x0201f800, 0x00106b8a, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x0010203c, 0x5c027800, 0x42000000,
+	0x0010b864, 0x0201f800, 0x0010aa47, 0x0201f800,
+	0x00109037, 0x04000010, 0x4d2c0000, 0x59325808,
+	0x4a025a04, 0x00000103, 0x59300402, 0x48025c06,
+	0x4a025a06, 0x00000029, 0x497a5c09, 0x592c0c08,
+	0x84040d50, 0x48065c08, 0x0201f800, 0x000202da,
+	0x5c025800, 0x42003000, 0x00000014, 0x41782800,
+	0x4d400000, 0x4d440000, 0x59368c03, 0x42002000,
+	0x00000002, 0x42028000, 0x00000029, 0x0201f800,
+	0x0010985e, 0x5c028800, 0x5c028000, 0x0201f000,
+	0x0002077d, 0x4933c857, 0x59300808, 0x49780c09,
+	0x4978080a, 0x58041408, 0x84081558, 0x48080c08,
+	0x1c01f000, 0x4807c857, 0x8c040d3e, 0x04020023,
+	0x497a5a06, 0x5930001f, 0x80000540, 0x04000017,
+	0x497a5a06, 0x4c040000, 0x4c080000, 0x4c0c0000,
+	0x4c100000, 0x4c140000, 0x58f41003, 0x40040000,
+	0x80081480, 0x5930001f, 0x4809e803, 0x0201f800,
+	0x00100d56, 0x5c002800, 0x5c002000, 0x5c001800,
+	0x5c001000, 0x5c000800, 0x592c0206, 0x80000540,
+	0x04020009, 0x0401f005, 0x592c0408, 0x8c00051c,
+	0x04000002, 0x592c0803, 0x4807c857, 0x4a025a06,
+	0x00000015, 0x1c01f000, 0x5930001f, 0x80000540,
+	0x04000009, 0x4a025a06, 0x00000011, 0x5930001f,
+	0x4c040000, 0x0201f800, 0x00100d56, 0x5c000800,
+	0x0401f7f5, 0x4807c856, 0x4a025a06, 0x00000007,
+	0x1c01f000, 0x83380480, 0x00000058, 0x04021007,
+	0x83380480, 0x00000040, 0x04001004, 0x4d2c0000,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x001087db,
+	0x001087db, 0x001087db, 0x001087db, 0x001087db,
+	0x001087dd, 0x001087db, 0x001087db, 0x00108860,
+	0x001087db, 0x001087db, 0x001087db, 0x001087db,
+	0x001087db, 0x001087db, 0x001087db, 0x001087db,
+	0x001087db, 0x001087db, 0x00108910, 0x00108939,
+	0x00108918, 0x001087db, 0x00108945, 0x0201f800,
+	0x001005d8, 0x5930001c, 0x800001c0, 0x02020800,
+	0x0010984e, 0x59300007, 0x8c00050e, 0x0400007c,
+	0x8c000500, 0x0400006e, 0x8c00051c, 0x04000009,
+	0x84000500, 0x48026007, 0x59325808, 0x592c3c08,
+	0x841c3d58, 0x481e5c08, 0x0201f000, 0x000207dd,
+	0x59325808, 0x592c3c08, 0x841c3d58, 0x59300007,
+	0x8c00051c, 0x040207f3, 0x481e5c08, 0x42000000,
+	0x00000005, 0x40000000, 0x80000040, 0x040207fe,
+	0x59300007, 0x8c00051c, 0x040207ea, 0x59cc0a08,
+	0x592c0204, 0x82000500, 0x000000ff, 0x82000580,
+	0x00000048, 0x0402000c, 0x497a580b, 0x82040500,
+	0x000000ff, 0x04000008, 0x592c0407, 0x800001c0,
+	0x04000005, 0x0201f800, 0x0010973f, 0x0201f000,
+	0x00100e56, 0x48065c09, 0x41782000, 0x82040500,
+	0x00000c00, 0x04000002, 0x59cc2009, 0x82043500,
+	0x00000fff, 0x04020027, 0x481e5c08, 0x4a025a06,
+	0x00000000, 0x801831c0, 0x02000000, 0x00100e56,
+	0x41782000, 0x8c183510, 0x04000002, 0x59cc200b,
+	0x4812580c, 0x41780000, 0x8c183512, 0x04000002,
+	0x59cc000a, 0x4802580b, 0x80100c00, 0x02001800,
+	0x001005d8, 0x02000000, 0x00100e56, 0x82041480,
+	0x0000001d, 0x0402100c, 0x4c500000, 0x4c540000,
+	0x83cca400, 0x0000000c, 0x832cac00, 0x0000000d,
+	0x0401fb67, 0x5c00a800, 0x5c00a000, 0x0201f000,
+	0x00100e56, 0x0401fb0b, 0x0201f000, 0x00100e56,
+	0x412c7800, 0x0201f800, 0x001007e4, 0x02000800,
+	0x001005d8, 0x492c7809, 0x841c3d52, 0x481c7c08,
+	0x4a025a04, 0x00000103, 0x4812580a, 0x48065c09,
+	0x583c0404, 0x583c1005, 0x583c2208, 0x48025c04,
+	0x480a5805, 0x48125a08, 0x0401f7c8, 0x8c000524,
+	0x04000794, 0x59325808, 0x4c000000, 0x592c0408,
+	0x8c00051c, 0x5c000000, 0x04020003, 0x4a026011,
+	0xffffffff, 0x84000524, 0x0401f78a, 0x1c01f000,
+	0x59a80039, 0x48026205, 0x59325808, 0x4a026203,
+	0x00000002, 0x592c2408, 0x59300807, 0x4933c857,
+	0x4807c857, 0x592c0204, 0x82000500, 0x000000ff,
+	0x82000580, 0x00000048, 0x04020004, 0x8c102500,
+	0x02020000, 0x00109787, 0x4a025a06, 0x00000000,
+	0x8c040d1e, 0x04000027, 0x41780800, 0x497a5c09,
+	0x592c1c09, 0x59300011, 0x59341200, 0x497a6205,
+	0x8c08150e, 0x0402006e, 0x4807c857, 0x4806580a,
+	0x80000d40, 0x04020f04, 0x59300402, 0x48025c06,
+	0x48065807, 0x4a025a04, 0x00000103, 0x4c040000,
+	0x4c0c0000, 0x4c100000, 0x0201f800, 0x0010959c,
+	0x5c002000, 0x5c001800, 0x5c000800, 0x8c102512,
+	0x0402001a, 0x4c0c0000, 0x0201f800, 0x000202c1,
+	0x0201f800, 0x001049b2, 0x5c001800, 0x8c0c1d18,
+	0x02000000, 0x0002077d, 0x0201f000, 0x001091d1,
+	0x4813c857, 0x8c102518, 0x0400004b, 0x41780800,
+	0x592c1c09, 0x820c0580, 0x00001000, 0x040007d6,
+	0x8c102512, 0x040007d4, 0x592c7809, 0x583c080a,
+	0x583c1c09, 0x0401f7d0, 0x4807c857, 0x592c7809,
+	0x59300402, 0x592c1404, 0x8c08151e, 0x0402000d,
+	0x592c1206, 0x48007c06, 0x48047807, 0x48087a06,
+	0x84102512, 0x48107c08, 0x4c0c0000, 0x0201f800,
+	0x001007fd, 0x403e5800, 0x0401faca, 0x0401f7d9,
+	0x48025c06, 0x48065807, 0x583c080c, 0x583c000b,
+	0x80040c00, 0x82041480, 0x0000001d, 0x04001006,
+	0x583c1001, 0x480a5801, 0x49787801, 0x42000800,
+	0x0000001c, 0x82040c00, 0x00000014, 0x4c0c0000,
+	0x4c500000, 0x4c540000, 0x823ca400, 0x00000008,
+	0x832cac00, 0x00000008, 0x4c100000, 0x4c3c0000,
+	0x0401facb, 0x5c007800, 0x5c002000, 0x5c00a800,
+	0x5c00a000, 0x84102512, 0x48125c08, 0x403e5800,
+	0x0201f800, 0x001007fd, 0x42034000, 0x0010b4a4,
+	0x59a1d81e, 0x80edd9c0, 0x02000800, 0x001005d8,
+	0x48efc857, 0x58ec0009, 0x4803c857, 0x0801f800,
+	0x0401f7ac, 0x4933c857, 0x1c01f000, 0x59301414,
+	0x480bc857, 0x8c08151c, 0x0402000e, 0x80000540,
+	0x4803c857, 0x0400078d, 0x80042c80, 0x0402178b,
+	0x8c081514, 0x04020005, 0x592c080f, 0x4807c857,
+	0x80040480, 0x48026016, 0x8408155c, 0x480a6414,
+	0x59301007, 0x8408151e, 0x480a6007, 0x4a025c09,
+	0x00000001, 0x0201f800, 0x0010959c, 0x497a5c09,
+	0x8c102512, 0x04000006, 0x4d2c0000, 0x403e5800,
+	0x0201f800, 0x001007fd, 0x5c025800, 0x82102500,
+	0xffffedff, 0x48125c08, 0x0201f000, 0x0010920f,
+	0x59325808, 0x592c0408, 0x8c000518, 0x04000004,
+	0x412df800, 0x0201f000, 0x00100e6f, 0x1c01f000,
+	0x4933c857, 0x59325808, 0x497a5c09, 0x4a025a06,
+	0x00000000, 0x4a025a04, 0x00000103, 0x59300811,
+	0x4807c857, 0x800409c0, 0x0402000a, 0x48065807,
+	0x59300c02, 0x48065c06, 0x0201f800, 0x000202c1,
+	0x0201f800, 0x001049b2, 0x0201f000, 0x0002077d,
+	0x59340200, 0x8c00050e, 0x04020005, 0x59300811,
+	0x0401fe55, 0x48065807, 0x0401f7f2, 0x592c0208,
+	0x8c00050e, 0x040207fa, 0x4933c857, 0x0201f000,
+	0x0010920f, 0x4933c857, 0x59325808, 0x812e59c0,
+	0x02000800, 0x001005d8, 0x592c020a, 0x8c000502,
+	0x02000800, 0x001005d8, 0x4a026206, 0x00000002,
+	0x1c01f000, 0x5930001c, 0x800001c0, 0x02020800,
+	0x0010984e, 0x59300007, 0x4933c857, 0x4803c857,
+	0x8c00050e, 0x04000037, 0x8c000500, 0x04000029,
+	0x8c00051c, 0x0400000a, 0x84000500, 0x48026007,
+	0x59325808, 0x592c3c08, 0x481fc857, 0x841c3d58,
+	0x481e5c08, 0x0201f000, 0x000207dd, 0x59325808,
+	0x592c3c08, 0x841c3d58, 0x59300007, 0x8c00051c,
+	0x040207f2, 0x481e5c08, 0x42000000, 0x00000005,
+	0x40000000, 0x80000040, 0x040207fe, 0x59300007,
+	0x8c00051c, 0x040207e9, 0x592c0204, 0x82000500,
+	0x000000ff, 0x82000580, 0x00000048, 0x04020003,
+	0x497a580b, 0x0401f002, 0x497a5c09, 0x481e5c08,
+	0x4a025a06, 0x00000000, 0x0201f000, 0x00100e56,
+	0x8c000524, 0x040007d9, 0x59325808, 0x4c000000,
+	0x592c0408, 0x8c00051c, 0x5c000000, 0x04020003,
+	0x4a026011, 0xffffffff, 0x84000524, 0x0401f7cf,
+	0x1c01f000, 0x4933c857, 0x41780800, 0x83380480,
+	0x00000058, 0x0402100b, 0x83380480, 0x00000040,
+	0x04001008, 0x4d2c0000, 0x59325808, 0x812e59c0,
+	0x0c020806, 0x5c025800, 0x0201f000, 0x0002077d,
+	0x493bc857, 0x1c01f000, 0x001089ae, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x001089ae, 0x001089b0,
+	0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x001089ae, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x001089b5, 0x001089ae,
+	0x001089ae, 0x001089ae, 0x0201f800, 0x001005d8,
+	0x59cc0a08, 0x497a5807, 0x4807c857, 0x82040d00,
+	0x00000fff, 0x59300402, 0x48025c06, 0x4a025a04,
+	0x00000103, 0x48065c09, 0x4a025a06, 0x00000000,
+	0x800409c0, 0x02000000, 0x000202c1, 0x59cc0009,
+	0x4802580a, 0x82042500, 0x00000100, 0x04000002,
+	0x59cc200b, 0x4812580c, 0x82040500, 0x00000200,
+	0x04000002, 0x59cc000a, 0x4802580b, 0x80100c00,
+	0x02001800, 0x001005d8, 0x02000000, 0x000202da,
+	0x82041480, 0x0000001d, 0x04001006, 0x592c0404,
+	0x8c00051e, 0x0400000e, 0x42000800, 0x0000001c,
+	0x4c500000, 0x4c540000, 0x83cca400, 0x0000000c,
+	0x832cac00, 0x0000000d, 0x0401f9c1, 0x5c00a800,
+	0x5c00a000, 0x0201f000, 0x000202da, 0x0401f965,
+	0x0401f1a0, 0x83380480, 0x00000093, 0x02021800,
+	0x001005d8, 0x83380480, 0x00000085, 0x02001800,
+	0x001005d8, 0x0c01f001, 0x001089fd, 0x001089fb,
+	0x001089fb, 0x00108a04, 0x001089fb, 0x001089fb,
+	0x001089fb, 0x001089fb, 0x001089fb, 0x001089fb,
+	0x001089fb, 0x001089fb, 0x001089fb, 0x0201f800,
+	0x001005d8, 0x4a026203, 0x00000001, 0x493a6403,
+	0x42000800, 0x80000040, 0x0201f000, 0x00020721,
+	0x4933c857, 0x59cc1204, 0x480a601c, 0x59cc1404,
+	0x0201f800, 0x00109410, 0x0400001b, 0x591c0203,
+	0x82000580, 0x00000000, 0x04000017, 0x591c0009,
+	0x81340580, 0x04020014, 0x4d300000, 0x4d1c0000,
+	0x411e6000, 0x0401f9c2, 0x5c023800, 0x5c026000,
+	0x0400000b, 0x59cc0005, 0x8c000500, 0x04020003,
+	0x0401f98c, 0x0401f003, 0x4a023a03, 0x00000002,
+	0x4a026403, 0x00000086, 0x0401f005, 0x0401f9a6,
+	0x040007f5, 0x4a026403, 0x00000087, 0x4a026203,
+	0x00000001, 0x42000800, 0x80000040, 0x0201f800,
+	0x00020721, 0x59340200, 0x8c00050e, 0x0400000d,
+	0x59cc1404, 0x0201f800, 0x00109410, 0x04000009,
+	0x591c0414, 0x8c00051a, 0x04000006, 0x4d300000,
+	0x411e6000, 0x0201f800, 0x0010921e, 0x5c026000,
+	0x1c01f000, 0x83380580, 0x00000013, 0x0402000a,
+	0x59300403, 0x82000d80, 0x00000086, 0x04000012,
+	0x82000d80, 0x00000087, 0x02020800, 0x001005d8,
+	0x0401f00d, 0x83380580, 0x00000027, 0x04000005,
+	0x83380580, 0x00000014, 0x02020800, 0x001005d8,
+	0x493bc857, 0x0201f800, 0x00106bbf, 0x0201f000,
+	0x00107911, 0x4933c857, 0x0201f000, 0x00107911,
+	0x83380580, 0x00000013, 0x04020005, 0x59300403,
+	0x82000480, 0x00000085, 0x0c01f04d, 0x83380580,
+	0x00000027, 0x04020041, 0x4933c857, 0x0201f800,
+	0x00106bbf, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42003000, 0x00000015,
+	0x41782800, 0x42002000, 0x00000003, 0x42028000,
+	0x00000029, 0x4d400000, 0x4d440000, 0x59368c03,
+	0x0201f800, 0x0010985e, 0x5c028800, 0x5c028000,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00109037, 0x0400000c, 0x4d2c0000,
+	0x59325808, 0x4a025a04, 0x00000103, 0x59300402,
+	0x48025c06, 0x497a5c09, 0x49425a06, 0x0201f800,
+	0x000202da, 0x5c025800, 0x0201f800, 0x0010912a,
+	0x0201f000, 0x0002077d, 0x83380580, 0x00000089,
+	0x04000005, 0x83380580, 0x0000008a, 0x02020000,
+	0x00107974, 0x0201f800, 0x00106f60, 0x02020000,
+	0x00107974, 0x59300a03, 0x82040580, 0x0000000a,
+	0x0400002a, 0x82040580, 0x0000000c, 0x04000027,
+	0x0201f800, 0x001005d8, 0x83380580, 0x00000014,
+	0x040207ea, 0x4933c857, 0x0201f800, 0x00106bbf,
+	0x42028000, 0x00000006, 0x0401f7d2, 0x00108aba,
+	0x00108ab8, 0x00108ab8, 0x00108ab8, 0x00108ab8,
+	0x00108ab8, 0x00108ac0, 0x00108ab8, 0x00108ab8,
+	0x00108ab8, 0x00108ab8, 0x00108ab8, 0x00108ab8,
+	0x0201f800, 0x001005d8, 0x4933c857, 0x59a80037,
+	0x48026206, 0x4a026203, 0x0000000a, 0x1c01f000,
+	0x4933c857, 0x59a80037, 0x48026206, 0x4a026203,
+	0x0000000c, 0x1c01f000, 0x83380580, 0x00000089,
+	0x04000008, 0x83380580, 0x0000008a, 0x04000032,
+	0x4933c857, 0x493bc857, 0x0201f000, 0x00107974,
+	0x4933c857, 0x59325808, 0x59300a1d, 0x82040580,
+	0x00000003, 0x04020004, 0x0201f800, 0x001049b2,
+	0x0401f00c, 0x5930021d, 0x82000580, 0x00000001,
+	0x04020008, 0x59300c16, 0x82040580, 0x00000039,
+	0x0400002c, 0x82040580, 0x00000035, 0x04000029,
+	0x4c340000, 0x41306800, 0x0201f800, 0x0002075a,
+	0x04000010, 0x4a026203, 0x00000001, 0x4a026403,
+	0x0000001e, 0x59cc0c07, 0x48066419, 0x59cc0a07,
+	0x48066219, 0x49366009, 0x4a026406, 0x00000001,
+	0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+	0x40366000, 0x0201f800, 0x0002077d, 0x5c006800,
+	0x1c01f000, 0x4933c857, 0x5930021d, 0x82000580,
+	0x00000001, 0x04020040, 0x59300c16, 0x82040580,
+	0x00000035, 0x04000007, 0x82040580, 0x0000001e,
+	0x04000004, 0x82040580, 0x00000039, 0x04020036,
+	0x4933c857, 0x4c500000, 0x4d1c0000, 0x4130a000,
+	0x40067000, 0x0201f800, 0x001093ba, 0x04020029,
+	0x0201f800, 0x0002075a, 0x04000026, 0x491fc857,
+	0x4933c857, 0x83380580, 0x00000035, 0x04000004,
+	0x83380580, 0x00000039, 0x04020002, 0x4932381c,
+	0x493a6403, 0x4a026203, 0x00000001, 0x4a026406,
+	0x00000001, 0x58500809, 0x4807c857, 0x48066009,
+	0x58500c15, 0x4807c857, 0x48066415, 0x58500a15,
+	0x4807c857, 0x48066215, 0x58500a16, 0x4807c857,
+	0x48066216, 0x58500c19, 0x4807c857, 0x48066419,
+	0x58500a19, 0x4807c857, 0x48066219, 0x491e601e,
+	0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+	0x40526000, 0x5c023800, 0x5c00a000, 0x0201f000,
+	0x0002077d, 0x5930021d, 0x82000580, 0x00000003,
+	0x02000800, 0x001049b2, 0x0201f000, 0x0002077d,
+	0x4803c856, 0x4c500000, 0x4c540000, 0x412c7800,
+	0x4c3c0000, 0x42002800, 0x00000001, 0x82040480,
+	0x00000101, 0x04001003, 0x42000800, 0x00000100,
+	0x40043000, 0x42000800, 0x0000001c, 0x83cca400,
+	0x0000000c, 0x832cac00, 0x0000000d, 0x0401f844,
+	0x82183480, 0x0000001c, 0x592e5801, 0x812e59c0,
+	0x02020800, 0x001007fd, 0x0201f800, 0x001007e4,
+	0x04000017, 0x80142800, 0x4a025a04, 0x00000110,
+	0x497a5c04, 0x492c7801, 0x82180c80, 0x0000003d,
+	0x04021006, 0x40180800, 0x832cac00, 0x00000005,
+	0x0401f82f, 0x0401f00a, 0x82183480, 0x0000003c,
+	0x42000800, 0x0000003c, 0x412c7800, 0x832cac00,
+	0x00000005, 0x0401f826, 0x0401f7e8, 0x5c007800,
+	0x841429c0, 0x82142d40, 0x00000003, 0x48147a04,
+	0x403e5800, 0x5c00a800, 0x5c00a000, 0x1c01f000,
+	0x492fc857, 0x812e59c0, 0x0400000f, 0x4d2c0000,
+	0x4c3c0000, 0x592c7801, 0x803c79c0, 0x04000006,
+	0x497a5801, 0x0201f800, 0x000202da, 0x403e5800,
+	0x0401f7f9, 0x5c007800, 0x0201f800, 0x000202da,
+	0x5c025800, 0x1c01f000, 0x4803c856, 0x4c580000,
+	0x82040c00, 0x00000003, 0x8004b104, 0x0201f800,
+	0x0010ab17, 0x5c00b000, 0x1c01f000, 0x4803c856,
+	0x4c580000, 0x82040c00, 0x00000003, 0x8004b104,
+	0x0201f800, 0x0010ab17, 0x5c00b000, 0x1c01f000,
+	0x591c0c06, 0x82040580, 0x00000003, 0x04000004,
+	0x82040580, 0x00000002, 0x0402001a, 0x4d300000,
+	0x4d2c0000, 0x411e6000, 0x59325808, 0x0201f800,
+	0x00109037, 0x0400000f, 0x4d400000, 0x42028000,
+	0x00000013, 0x592c0a08, 0x84040d54, 0x0201f800,
+	0x00104e70, 0x5c028000, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x000202da, 0x0201f800, 0x0010912a,
+	0x0201f800, 0x00107911, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x59cc0005, 0x8c000500, 0x0402000b,
+	0x591c0406, 0x82000580, 0x00000002, 0x04020007,
+	0x591c0c03, 0x82040580, 0x00000085, 0x04000003,
+	0x82040580, 0x0000008b, 0x1c01f000, 0x4933c857,
+	0x4d3c0000, 0x42027800, 0x00000002, 0x59300406,
+	0x82000c80, 0x00000012, 0x02021800, 0x001005d8,
+	0x0c01f80a, 0x5c027800, 0x1c01f000, 0x4933c857,
+	0x59300406, 0x82000c80, 0x00000012, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x00108c01, 0x00108bfe,
+	0x00108bfe, 0x00108c29, 0x00108bfc, 0x00108bfe,
+	0x00108c1a, 0x00108bfe, 0x00108bfc, 0x001065f4,
+	0x00108bfe, 0x00108bfe, 0x00108bfe, 0x00108bfc,
+	0x00108bfc, 0x00108bfc, 0x00108cf9, 0x00108bfe,
+	0x0201f800, 0x001005d8, 0x4803c856, 0x80000580,
+	0x1c01f000, 0x4803c856, 0x8d3e7d02, 0x04020016,
+	0x0201f800, 0x00109037, 0x0400000f, 0x59325808,
+	0x41780800, 0x4d400000, 0x42028000, 0x00000005,
+	0x0201f800, 0x00104e70, 0x5c028000, 0x0201f800,
+	0x0010959c, 0x0201f800, 0x001091cc, 0x0201f800,
+	0x000202da, 0x0201f800, 0x00107911, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4933c857, 0x0201f800,
+	0x001048d9, 0x0402000c, 0x4d400000, 0x42028000,
+	0x00000010, 0x0201f800, 0x0010a1d1, 0x4a026406,
+	0x00000006, 0x4a026203, 0x00000007, 0x5c028000,
+	0x1c01f000, 0x4933c857, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x0401f8b8, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x0c01f001, 0x00108c43,
+	0x00108cb0, 0x00108c5a, 0x00108cc3, 0x00108cab,
+	0x00108c41, 0x00108c43, 0x00108c43, 0x00108c47,
+	0x00108c43, 0x00108c43, 0x00108c43, 0x00108c43,
+	0x00108c5a, 0x0201f800, 0x001005d8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x0401f7b8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x59300406, 0x82000580,
+	0x00000003, 0x040207b4, 0x59300203, 0x82000580,
+	0x0000000d, 0x040007b0, 0x8d3e7d02, 0x040207ae,
+	0x4d340000, 0x59326809, 0x0201f800, 0x001049b2,
+	0x5c026800, 0x0401f7a8, 0x59300004, 0x8400055c,
+	0x48026004, 0x0201f800, 0x00106c4b, 0x59300406,
+	0x82000580, 0x00000006, 0x04000043, 0x8d3e7d02,
+	0x04020041, 0x497a621d, 0x59300203, 0x82000580,
+	0x0000000d, 0x04000003, 0x4a02621d, 0x00000003,
+	0x0401fbcb, 0x04000024, 0x4d2c0000, 0x4d400000,
+	0x59325808, 0x0201f800, 0x001091cc, 0x592c0408,
+	0x8c000512, 0x04000009, 0x4d2c0000, 0x84000512,
+	0x48025c08, 0x592c0809, 0x40065800, 0x0201f800,
+	0x001007fd, 0x5c025800, 0x4d400000, 0x42028000,
+	0x00000005, 0x592c0a08, 0x8c040d0e, 0x04000004,
+	0x42028000, 0x00000002, 0x0401f001, 0x0201f800,
+	0x00104e70, 0x5c028000, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x000202da, 0x497a6008, 0x5c028000,
+	0x5c025800, 0x8d3e7d00, 0x04000009, 0x4d340000,
+	0x59326809, 0x0201f800, 0x001049b2, 0x5c026800,
+	0x0201f800, 0x00107911, 0x0401f00b, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x42000800, 0x8000404b, 0x0201f800,
+	0x00020721, 0x5c03e000, 0x02020800, 0x00106c55,
+	0x82000540, 0x00000001, 0x1c01f000, 0x0201f800,
+	0x00106c4b, 0x0201f800, 0x00100e99, 0x0401f7ab,
+	0x598c000d, 0x81300580, 0x04020004, 0x0201f800,
+	0x00106e8e, 0x0402001b, 0x0201f800, 0x001068d3,
+	0x04020006, 0x59300c03, 0x82040580, 0x00000040,
+	0x0400078b, 0x0401f79d, 0x0201f800, 0x00106b6c,
+	0x04000010, 0x0201f800, 0x001005d8, 0x0401f813,
+	0x04020004, 0x0201f800, 0x00106e62, 0x04020009,
+	0x0201f800, 0x001067ae, 0x040207f4, 0x59300c03,
+	0x82040580, 0x00000040, 0x04000779, 0x0401f78b,
+	0x59300203, 0x82000c80, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f75e, 0x417a3000, 0x42032000,
+	0x0000bf32, 0x59900004, 0x81300580, 0x04000009,
+	0x83932400, 0x00000010, 0x811a3000, 0x83180480,
+	0x00000005, 0x040017f8, 0x82000540, 0x00000001,
+	0x1c01f000, 0x59300004, 0x8c00053e, 0x04000010,
+	0x8c00050c, 0x0402000e, 0x8c000516, 0x04020006,
+	0x82000d00, 0x0000001f, 0x82040580, 0x00000005,
+	0x04020004, 0x42000000, 0x00000003, 0x0401f005,
+	0x42000000, 0x00000001, 0x0401f002, 0x59300203,
+	0x1c01f000, 0x4933c857, 0x0201f800, 0x00106c55,
+	0x4df00000, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x0c01f001, 0x00108d13,
+	0x00108d30, 0x00108d17, 0x00108d11, 0x00108d11,
+	0x00108d11, 0x00108d11, 0x00108d11, 0x00108d11,
+	0x00108d11, 0x00108d11, 0x00108d11, 0x00108d11,
+	0x00108d11, 0x0201f800, 0x001005d8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x0401f6e8, 0x5c03e000,
+	0x02000800, 0x00106c4b, 0x4d2c0000, 0x59325808,
+	0x59300403, 0x82000580, 0x00000052, 0x02000800,
+	0x00101231, 0x0401fb16, 0x02000800, 0x001005d8,
+	0x4a025a06, 0x00000005, 0x0201f800, 0x000202da,
+	0x0201f800, 0x00104c19, 0x0201f800, 0x00107911,
+	0x5c025800, 0x82000540, 0x00000001, 0x1c01f000,
+	0x598c000d, 0x81300580, 0x0402001a, 0x59300004,
+	0x8c000520, 0x04000004, 0x84000520, 0x48026004,
+	0x0401f01a, 0x42001000, 0x0010b7f6, 0x50081000,
+	0x58080002, 0x82000580, 0x00000100, 0x0400000a,
+	0x5808000c, 0x81300580, 0x02020800, 0x001005d8,
+	0x0201f800, 0x001068d3, 0x02020800, 0x001005d8,
+	0x0401f7cf, 0x0201f800, 0x00106e8e, 0x0402000c,
+	0x59300004, 0x8c000520, 0x04000004, 0x84000520,
+	0x48026004, 0x0401f7c6, 0x0201f800, 0x001068d3,
+	0x040007c3, 0x0201f800, 0x001005d8, 0x59300203,
+	0x82000c80, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f7a7, 0x59300406, 0x4933c857, 0x4803c857,
+	0x82000c80, 0x00000012, 0x02021800, 0x001005d8,
+	0x0c01f001, 0x00108d7c, 0x00108e41, 0x00108f79,
+	0x00108d88, 0x00107911, 0x00108d7c, 0x0010a1c0,
+	0x0002077d, 0x00108e41, 0x001065ce, 0x00108fda,
+	0x00108d77, 0x00108d77, 0x00108d77, 0x00108d77,
+	0x00108d77, 0x001096eb, 0x001096eb, 0x0201f800,
+	0x001005d8, 0x0401fbd5, 0x02000000, 0x0010801c,
+	0x1c01f000, 0x0201f800, 0x00106c55, 0x0201f800,
+	0x00106bbf, 0x0201f800, 0x00106c4b, 0x0201f000,
+	0x0002077d, 0x4a026206, 0x00000001, 0x1c01f000,
+	0x42000000, 0x0010b872, 0x0201f800, 0x0010aa47,
+	0x4d2c0000, 0x4d400000, 0x417a5800, 0x0401faa8,
+	0x04000007, 0x59325808, 0x592c0208, 0x8400054c,
+	0x48025a08, 0x42028000, 0x00000006, 0x0201f800,
+	0x00106c55, 0x0401ff4c, 0x4803c857, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f806,
+	0x0201f800, 0x00106c4b, 0x5c028000, 0x5c025800,
+	0x1c01f000, 0x00108e40, 0x00108db5, 0x00108dc3,
+	0x00108de5, 0x00108e11, 0x00108db3, 0x00108d7c,
+	0x00108d7c, 0x00108d7c, 0x00108db3, 0x00108db3,
+	0x00108db3, 0x00108db3, 0x00108dc3, 0x0201f800,
+	0x001005d8, 0x598c000d, 0x81300580, 0x04020004,
+	0x0201f800, 0x00106e8e, 0x04020038, 0x0201f800,
+	0x001068d3, 0x0400003b, 0x0201f800, 0x00106b6c,
+	0x04000032, 0x0201f800, 0x001005d8, 0x497a621d,
+	0x812e59c0, 0x02000800, 0x001005d8, 0x592c0204,
+	0x82000500, 0x000000ff, 0x82000580, 0x00000014,
+	0x04000003, 0x4a02621d, 0x00000003, 0x592c0a08,
+	0x0201f800, 0x00104e70, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x000202da, 0x497a6008, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x4a026004, 0x8000404b, 0x0201f800,
+	0x00106c4b, 0x42000800, 0x8000404b, 0x0201f000,
+	0x00020721, 0x0401fef1, 0x04020004, 0x0201f800,
+	0x00106e62, 0x04020009, 0x0201f800, 0x001067ae,
+	0x040207d2, 0x59300c03, 0x82040580, 0x00000040,
+	0x04000008, 0x0401f7d2, 0x59300203, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f7ae,
+	0x0201f800, 0x00106c4b, 0x812e59c0, 0x04000013,
+	0x592c0a08, 0x0201f800, 0x00104e70, 0x0201f800,
+	0x0010959c, 0x0201f800, 0x000202da, 0x59300203,
+	0x82000580, 0x0000000d, 0x04000008, 0x0201f800,
+	0x00106c4b, 0x4d340000, 0x59326809, 0x0201f800,
+	0x001049b2, 0x5c026800, 0x0201f800, 0x00107911,
+	0x0401f030, 0x812e59c0, 0x02000800, 0x001005d8,
+	0x0201f800, 0x0010940a, 0x04020004, 0x0201f800,
+	0x00100e99, 0x0401f7aa, 0x0201f800, 0x00106c4b,
+	0x592c0208, 0x8400050c, 0x48025a08, 0x592c0406,
+	0x800000c2, 0x800008c4, 0x80040c00, 0x48066206,
+	0x42000000, 0x10000000, 0x41300800, 0x0201f800,
+	0x00100b94, 0x0400000d, 0x592c0208, 0x8c00051c,
+	0x04020006, 0x8400055c, 0x48025a08, 0x4a026206,
+	0x00000002, 0x0401f00f, 0x4d300000, 0x0201f800,
+	0x001012e5, 0x5c026000, 0x59300203, 0x82000580,
+	0x00000004, 0x04020007, 0x4d380000, 0x42027000,
+	0x00000048, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x1c01f000, 0x42000000, 0x0010b86e, 0x0201f800,
+	0x0010aa47, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x4803c857, 0x0c01f001,
+	0x00108e5a, 0x00108d85, 0x00108e5c, 0x00108e5a,
+	0x00108e5c, 0x00108e5c, 0x00108d7d, 0x00108e5a,
+	0x00108d79, 0x00108e5a, 0x00108e5a, 0x00108e5a,
+	0x00108e5a, 0x00108e5a, 0x0201f800, 0x001005d8,
+	0x4d340000, 0x4d2c0000, 0x59326809, 0x59340400,
+	0x82000500, 0x000000ff, 0x82000c80, 0x0000000c,
+	0x02021800, 0x001005d8, 0x59303403, 0x82180d80,
+	0x00000004, 0x04020004, 0x42000000, 0x00000001,
+	0x0401f006, 0x82180d80, 0x00000000, 0x04020003,
+	0x42000000, 0x00000001, 0x4803c857, 0x0c01f804,
+	0x5c025800, 0x5c026800, 0x1c01f000, 0x00108e83,
+	0x00108f22, 0x00108e85, 0x00108eba, 0x00108e85,
+	0x00108f3f, 0x00108e85, 0x00108e8f, 0x00108e83,
+	0x00108f3f, 0x00108e83, 0x00108e9e, 0x0201f800,
+	0x001005d8, 0x59300403, 0x82000d80, 0x00000016,
+	0x0400002e, 0x82000d80, 0x00000004, 0x0400002b,
+	0x82000d80, 0x00000002, 0x04000028, 0x0401fabf,
+	0x04000079, 0x59300403, 0x82000d80, 0x00000022,
+	0x040000ae, 0x82000d80, 0x00000039, 0x040000b3,
+	0x82000d80, 0x00000035, 0x040000b0, 0x82000d80,
+	0x0000001e, 0x0400001b, 0x0401f999, 0x04000007,
+	0x0201f800, 0x00109597, 0x04020004, 0x0201f800,
+	0x00104a14, 0x0401f011, 0x59300403, 0x82000d80,
+	0x00000001, 0x04020004, 0x0201f800, 0x001049e7,
+	0x0400000a, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x0010801c,
+	0x0201f000, 0x00107911, 0x0401f97d, 0x04000004,
+	0x0201f800, 0x00109597, 0x040000a9, 0x59300c03,
+	0x82040580, 0x00000016, 0x04000056, 0x82040580,
+	0x00000002, 0x04020034, 0x59a80026, 0x8c000502,
+	0x04020013, 0x0201f800, 0x0010513b, 0x04020010,
+	0x0201f800, 0x00105151, 0x04020006, 0x42000000,
+	0x00000001, 0x0201f800, 0x00105113, 0x0401f094,
+	0x4a035033, 0x00000001, 0x4202d800, 0x00000001,
+	0x0201f800, 0x001050a2, 0x0401f08d, 0x59340403,
+	0x82000580, 0x000007fc, 0x04000008, 0x59a80026,
+	0x8c00050a, 0x04020084, 0x59340212, 0x82000500,
+	0x0000ff00, 0x04000082, 0x59340412, 0x82000500,
+	0x000000ff, 0x04000010, 0x80000040, 0x48026c12,
+	0x497a6008, 0x4a026406, 0x00000007, 0x4a026206,
+	0x00000398, 0x497a6205, 0x0201f800, 0x0002075a,
+	0x04000005, 0x49366009, 0x4a026406, 0x00000001,
+	0x0401f020, 0x59300403, 0x82000d80, 0x00000002,
+	0x0402000d, 0x59340403, 0x82000580, 0x000007fe,
+	0x04020009, 0x59a80026, 0x84000540, 0x48035026,
+	0x0201f800, 0x00104237, 0x0201f800, 0x0010801c,
+	0x0401f00c, 0x0201f800, 0x0010801c, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x0010203c, 0x5c027800,
+	0x42000000, 0x0010b864, 0x0201f800, 0x0010aa47,
+	0x0201f800, 0x00102074, 0x0201f000, 0x00107911,
+	0x42000800, 0x00000003, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000002,
+	0x0201f000, 0x0010672b, 0x0401f915, 0x04020793,
+	0x0201f800, 0x00102074, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x0010203c, 0x5c027800, 0x42000000,
+	0x0010b864, 0x0201f800, 0x0010aa47, 0x42003000,
+	0x00000018, 0x41782800, 0x42002000, 0x00000000,
+	0x4d400000, 0x4d440000, 0x59368c03, 0x42028000,
+	0x00000029, 0x0201f800, 0x0010985e, 0x5c028800,
+	0x5c028000, 0x0201f000, 0x00107911, 0x0201f800,
+	0x00104a14, 0x0401f7c8, 0x42000000, 0x0010b86d,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x00107b76,
+	0x040207c1, 0x1c01f000, 0x4d380000, 0x59327403,
+	0x0201f800, 0x001093ba, 0x5c027000, 0x02020000,
+	0x0002077d, 0x836c0580, 0x00000003, 0x04000004,
+	0x4a026206, 0x00000002, 0x1c01f000, 0x59300403,
+	0x48026416, 0x4a02621d, 0x00000001, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x42000800, 0x8000004b, 0x0201f000,
+	0x00020721, 0x0201f800, 0x00102074, 0x0201f800,
+	0x0010801c, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x497a6008, 0x4a026406,
+	0x00000007, 0x4a026206, 0x00000398, 0x497a6205,
+	0x1c01f000, 0x42000000, 0x0010b870, 0x0201f800,
+	0x0010aa47, 0x4d340000, 0x59326809, 0x59300203,
+	0x82000c80, 0x0000000e, 0x02021800, 0x001005d8,
+	0x4803c857, 0x0c01f803, 0x5c026800, 0x1c01f000,
+	0x00108f96, 0x00108d85, 0x00108f96, 0x00108f96,
+	0x00108f96, 0x00108f96, 0x00108f96, 0x00108f96,
+	0x00108f96, 0x00108d85, 0x00108f98, 0x00108d85,
+	0x00108fa0, 0x00108f96, 0x0201f800, 0x001005d8,
+	0x4a026403, 0x0000008b, 0x4a026203, 0x0000000b,
+	0x42000800, 0x8000404b, 0x0201f000, 0x00020721,
+	0x59300a1d, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42003000, 0x00000011,
+	0x0201f800, 0x0010a942, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x41306800, 0x0201f800,
+	0x0002075a, 0x04000008, 0x49366009, 0x4d300000,
+	0x40366000, 0x0201f800, 0x00107911, 0x5c026000,
+	0x0401f002, 0x40366000, 0x497a6008, 0x4a026406,
+	0x00000001, 0x4a026403, 0x00000001, 0x0201f800,
+	0x00103b25, 0x04000011, 0x4a026406, 0x00000004,
+	0x4a026203, 0x00000007, 0x4a026420, 0x00000001,
+	0x42003000, 0x00000004, 0x4d400000, 0x42028000,
+	0x00000029, 0x41782800, 0x0201f800, 0x0010a43e,
+	0x5c028000, 0x1c01f000, 0x42000800, 0x0000000b,
+	0x0201f800, 0x00104571, 0x4a026203, 0x00000001,
+	0x0201f000, 0x0010672b, 0x42000000, 0x0010b876,
+	0x0201f800, 0x0010aa47, 0x59300203, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x4803c857,
+	0x0c01f001, 0x0010900b, 0x00108ff3, 0x00108ff7,
+	0x0010900c, 0x00108ff5, 0x00108ff3, 0x00108ff3,
+	0x00108ff3, 0x00108ff3, 0x00108ff3, 0x00108ff3,
+	0x00108ff3, 0x00108ff3, 0x00108ff3, 0x0201f800,
+	0x001005d8, 0x0201f800, 0x00100e99, 0x4d2c0000,
+	0x59325808, 0x4a025a06, 0x00000006, 0x0201f800,
+	0x000202da, 0x5c025800, 0x497a6008, 0x4a02621d,
+	0x0000000a, 0x4a026403, 0x00000085, 0x4a026203,
+	0x00000009, 0x4a026406, 0x00000002, 0x42000800,
+	0x8000404b, 0x0201f000, 0x00020721, 0x1c01f000,
+	0x0201f800, 0x00106c55, 0x4df00000, 0x0401fcc7,
+	0x04020004, 0x0201f800, 0x00106e62, 0x0402000c,
+	0x0201f800, 0x001067ae, 0x04020005, 0x5c03e000,
+	0x0201f800, 0x00106c4b, 0x0401f7dd, 0x0201f800,
+	0x00106b6c, 0x02020800, 0x001005d8, 0x5c03e000,
+	0x0201f800, 0x00106c4b, 0x59300203, 0x82000d80,
+	0x00000003, 0x02000800, 0x001005d8, 0x82000c80,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f7ba,
+	0x4803c856, 0x59a8000e, 0x59a80867, 0x80040400,
+	0x80080480, 0x04021004, 0x82000540, 0x00000001,
+	0x1c01f000, 0x80000580, 0x1c01f000, 0x4803c856,
+	0x4c080000, 0x59301008, 0x82081500, 0xfff00000,
+	0x5c001000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0201f800, 0x0002075a, 0x0400000a, 0x0401f82f,
+	0x4d380000, 0x42027000, 0x0000004b, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0201f800, 0x00107942, 0x0400001b, 0x0401f81f,
+	0x4d300000, 0x0201f800, 0x00106c55, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x00106ab4, 0x0201f800,
+	0x001067fd, 0x5c027800, 0x0201f800, 0x0010a2ff,
+	0x0201f800, 0x00106c4b, 0x5c026000, 0x8d3e7d3e,
+	0x0402000b, 0x4d380000, 0x42027000, 0x0000004c,
+	0x0201f800, 0x000207a1, 0x5c027000, 0x82000540,
+	0x00000001, 0x5c026000, 0x1c01f000, 0x0201f800,
+	0x0002077d, 0x0401f7fa, 0x592c0407, 0x494a6017,
+	0x494e6018, 0x49366009, 0x492e6008, 0x4a026406,
+	0x00000003, 0x800000c2, 0x800008c4, 0x80040400,
+	0x48026206, 0x1c01f000, 0x493bc857, 0x4d300000,
+	0x0201f800, 0x0002075a, 0x0400000d, 0x0401ffef,
+	0x4d400000, 0x42028000, 0x00000005, 0x0401f80d,
+	0x5c028000, 0x8d3e7d3e, 0x04020007, 0x0201f800,
+	0x000207a1, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x0201f800, 0x0002077d, 0x0401f7fa,
+	0x4803c856, 0x0201f800, 0x00106c55, 0x4d3c0000,
+	0x4d440000, 0x59368c03, 0x42027800, 0x00000001,
+	0x0201f800, 0x001069b6, 0x0201f800, 0x0010692e,
+	0x0201f800, 0x001067fd, 0x0201f800, 0x0010a2ff,
+	0x5c028800, 0x5c027800, 0x0201f000, 0x00106c4b,
+	0x4803c856, 0x4d300000, 0x0201f800, 0x0002075a,
+	0x0400000f, 0x481a601c, 0x48ee6021, 0x49366009,
+	0x4a026406, 0x00000001, 0x492e6008, 0x4d380000,
+	0x42027000, 0x0000001f, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800,
+	0x0002075a, 0x0400000e, 0x48ee6021, 0x49366009,
+	0x4a026406, 0x00000001, 0x492e6008, 0x4d380000,
+	0x42027000, 0x00000055, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800,
+	0x0002075a, 0x0400000f, 0x481a601c, 0x48ee6021,
+	0x49366009, 0x4a026406, 0x00000001, 0x492e6008,
+	0x4d380000, 0x42027000, 0x0000003d, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0201f800, 0x00107942, 0x04000014, 0x49366009,
+	0x492fc857, 0x4933c857, 0x592c0404, 0x8c00051e,
+	0x04000003, 0x48efc857, 0x48ee6021, 0x4a026406,
+	0x00000001, 0x492e6008, 0x4d380000, 0x42027000,
+	0x00000000, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x82000540, 0x00000001, 0x5c026000, 0x1c01f000,
+	0x4803c856, 0x4d300000, 0x0201f800, 0x0002075a,
+	0x0400000f, 0x48ee6021, 0x481a601c, 0x49366009,
+	0x4a026406, 0x00000001, 0x492e6008, 0x4d380000,
+	0x42027000, 0x00000044, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x4803c856, 0x4d300000, 0x0201f800,
+	0x0002075a, 0x0400000f, 0x481a601c, 0x48ee6021,
+	0x49366009, 0x4a026406, 0x00000001, 0x492e6008,
+	0x4d380000, 0x42027000, 0x00000049, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x59300009, 0x80001540,
+	0x02000800, 0x001005d8, 0x5808040b, 0x4803c856,
+	0x80000040, 0x04001002, 0x4800140b, 0x1c01f000,
+	0x4803c856, 0x59300403, 0x82000d80, 0x00000002,
+	0x04000015, 0x82000d80, 0x00000003, 0x04000012,
+	0x82000d80, 0x00000004, 0x0400000f, 0x82000d80,
+	0x00000008, 0x0400000c, 0x82000d80, 0x0000000a,
+	0x04000009, 0x599c0819, 0x8c040d0e, 0x04000004,
+	0x82000d80, 0x00000000, 0x04000003, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4803c856, 0x4c000000,
+	0x4d2c0000, 0x59300406, 0x82000580, 0x00000004,
+	0x0400001d, 0x59300008, 0x80025d40, 0x800001c0,
+	0x04000019, 0x0201f800, 0x00109597, 0x04000014,
+	0x59300406, 0x82004580, 0x00000010, 0x04000010,
+	0x82004580, 0x00000011, 0x0400000d, 0x82004580,
+	0x00000003, 0x0400000c, 0x82004580, 0x00000002,
+	0x04000009, 0x82004580, 0x0000000a, 0x04000006,
+	0x592c0404, 0x8c00051e, 0x04000003, 0x80000580,
+	0x0401f003, 0x82000540, 0x00000001, 0x5c025800,
+	0x5c000000, 0x1c01f000, 0x4803c856, 0x4d300000,
+	0x0201f800, 0x00107942, 0x04000013, 0x49366009,
+	0x48ee6021, 0x4a026406, 0x00000001, 0x492e6008,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x4d380000, 0x42027000, 0x00000028,
+	0x0201f800, 0x000207a1, 0x5c027000, 0x82000540,
+	0x00000001, 0x5c026000, 0x1c01f000, 0x4803c856,
+	0x83380580, 0x00000015, 0x0402000d, 0x59a80016,
+	0x82000580, 0x00000074, 0x04020009, 0x0201f800,
+	0x0010462a, 0x4a026203, 0x00000001, 0x4a026403,
+	0x00000029, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x0010801c, 0x0201f000, 0x0002077d, 0x4803c856,
+	0x83380580, 0x00000016, 0x04020007, 0x42000800,
+	0x00000004, 0x0201f800, 0x00104571, 0x0201f000,
+	0x00107b38, 0x83380580, 0x00000015, 0x04020013,
+	0x59a80016, 0x82000580, 0x00000014, 0x0402000f,
+	0x0201f800, 0x0010468d, 0x0201f800, 0x0010846f,
+	0x0402000a, 0x59340404, 0x80000540, 0x04000007,
+	0x42000800, 0x00000006, 0x0201f800, 0x00104571,
+	0x0201f000, 0x00107b38, 0x0201f800, 0x0010801c,
+	0x0201f000, 0x0002077d, 0x4803c856, 0x592c0206,
+	0x82000580, 0x00000005, 0x04000002, 0x1c01f000,
+	0x4803c856, 0x592c0208, 0x8400054a, 0x48025a08,
+	0x1c01f000, 0x497a6205, 0x497a6008, 0x4a026203,
+	0x00000001, 0x4a026403, 0x00000050, 0x42000800,
+	0x80000043, 0x0201f000, 0x00020721, 0x4933c857,
+	0x4d340000, 0x59326809, 0x59340200, 0x8c00050e,
+	0x04000006, 0x59300406, 0x82000c80, 0x00000012,
+	0x04021004, 0x0c01f806, 0x5c026800, 0x1c01f000,
+	0x0201f800, 0x00108d7c, 0x0401f7fc, 0x00108d7c,
+	0x001091fd, 0x00109201, 0x00109204, 0x0010a49b,
+	0x0010a4b8, 0x0010a4bc, 0x00108d7c, 0x00108d7c,
+	0x00108d7c, 0x00108d7c, 0x00108d7c, 0x00108d7c,
+	0x00108d7c, 0x00108d7c, 0x00108d7c, 0x00108d7c,
+	0x00108d7c, 0x4803c856, 0x40000000, 0x40000000,
+	0x1c01f000, 0x40000000, 0x40000000, 0x1c01f000,
+	0x5930001c, 0x4803c857, 0x59300414, 0x4933c857,
+	0x4803c857, 0x8c000502, 0x04000005, 0x84000502,
+	0x84000540, 0x48026414, 0x1c01f000, 0x42000000,
+	0xd0000000, 0x41300800, 0x0201f800, 0x00100b94,
+	0x0401f80a, 0x04020008, 0x59a80037, 0x82000400,
+	0x0000000a, 0x48026205, 0x59300414, 0x84000542,
+	0x48026414, 0x1c01f000, 0x4933c857, 0x4d340000,
+	0x59326809, 0x59340200, 0x8c00050e, 0x02000800,
+	0x001005d8, 0x5930001c, 0x80000540, 0x0402002f,
+	0x59a80021, 0x80000540, 0x0402002a, 0x4d1c0000,
+	0x41323800, 0x0201f800, 0x0002075a, 0x04000023,
+	0x4932381c, 0x591c0414, 0x84000542, 0x48023c14,
+	0x49366009, 0x591c0406, 0x82000580, 0x00000003,
+	0x04000006, 0x591c0202, 0x48026419, 0x591c0402,
+	0x48026219, 0x0401f005, 0x591c0202, 0x48026219,
+	0x591c0402, 0x48026419, 0x491e601e, 0x4a026406,
+	0x00000001, 0x4a026403, 0x00000035, 0x4a026203,
+	0x00000001, 0x42000800, 0x80000040, 0x0201f800,
+	0x00020721, 0x411e6000, 0x5c023800, 0x80000580,
+	0x5c026800, 0x1c01f000, 0x411e6000, 0x5c023800,
+	0x59a80039, 0x48026205, 0x82000540, 0x00000001,
+	0x0401f7f8, 0x4933c857, 0x4d2c0000, 0x4932381c,
+	0x4a026202, 0x0000ffff, 0x591e5808, 0x591c0007,
+	0x8c00051e, 0x04000005, 0x8400051e, 0x48023807,
+	0x497a5c09, 0x0401f014, 0x592c0408, 0x8c000518,
+	0x04000011, 0x84000518, 0x48025c08, 0x4a025c09,
+	0x00000001, 0x0401fb2f, 0x497a5c09, 0x592c0408,
+	0x8c000512, 0x04000008, 0x4d2c0000, 0x84000512,
+	0x48025c08, 0x592e5809, 0x0201f800, 0x001007fd,
+	0x5c025800, 0x59a80039, 0x48026205, 0x591c0214,
+	0x48026216, 0x82000d80, 0x00000001, 0x04000008,
+	0x4a023a03, 0x00000002, 0x82000580, 0x00000005,
+	0x04000008, 0x497a6015, 0x0401f01e, 0x591c0007,
+	0x84000540, 0x48023807, 0x4a023a03, 0x00000004,
+	0x591c0414, 0x4803c857, 0x8400051c, 0x84000554,
+	0x48023c14, 0x592c000f, 0x40001000, 0x591c0816,
+	0x80040480, 0x040217f0, 0x591c0016, 0x82000500,
+	0xfffffffc, 0x48026015, 0x48023816, 0x591c0a14,
+	0x4807c857, 0x82040d80, 0x00000005, 0x04020005,
+	0x480bc857, 0x4803c857, 0x4a023812, 0xffffffff,
+	0x591c0402, 0x48026419, 0x591c0202, 0x48026219,
+	0x591e6809, 0x49366009, 0x4a026406, 0x00000001,
+	0x4a026403, 0x00000039, 0x4a026203, 0x00000001,
+	0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x59300414,
+	0x8c000514, 0x04000015, 0x8c00051c, 0x04020012,
+	0x59300016, 0x80100480, 0x04001006, 0x04000005,
+	0x59300414, 0x84000514, 0x8400055c, 0x0401f009,
+	0x48126016, 0x48126012, 0x40100000, 0x592c180f,
+	0x800c0480, 0x48026011, 0x59300414, 0x84000514,
+	0x48026414, 0x1c01f000, 0x4933c857, 0x8c00051c,
+	0x04020006, 0x59300012, 0x48026016, 0x59300414,
+	0x8400055c, 0x48026414, 0x1c01f000, 0x59300c03,
+	0x4933c857, 0x4807c857, 0x82040480, 0x00000034,
+	0x04001006, 0x82040480, 0x0000003c, 0x04021003,
+	0x80000580, 0x1c01f000, 0x82000540, 0x00000001,
+	0x0401f7fd, 0x41780800, 0x59a81035, 0x42000000,
+	0x00000032, 0x0201f800, 0x001066a0, 0x800811c0,
+	0x04020003, 0x42001000, 0x00000014, 0x480b5037,
+	0x59a81036, 0x480b502d, 0x41780800, 0x42000000,
+	0x00000064, 0x0201f800, 0x001066a0, 0x800811c0,
+	0x04020003, 0x42001000, 0x00000014, 0x480b5038,
+	0x82081400, 0x0000000a, 0x480b5039, 0x42000800,
+	0x00000001, 0x0201f800, 0x00106c78, 0x42000000,
+	0x30000000, 0x40080800, 0x0201f800, 0x00100b68,
+	0x42000800, 0x00000003, 0x59a81010, 0x0201f800,
+	0x00106c78, 0x0201f000, 0x00104906, 0x4a035037,
+	0x00000028, 0x4a035038, 0x00000014, 0x4a03502d,
+	0x000007d0, 0x42001000, 0x0000001e, 0x480b5039,
+	0x42000800, 0x00000001, 0x0201f800, 0x00106c78,
+	0x42000000, 0x30000000, 0x40080800, 0x0201f800,
+	0x00100b68, 0x42000800, 0x00000003, 0x59a81010,
+	0x0201f000, 0x00106c78, 0x4933c857, 0x4d2c0000,
+	0x59300403, 0x82000580, 0x0000003e, 0x04020005,
+	0x59325817, 0x812e59c0, 0x02020800, 0x001007f4,
+	0x5c025800, 0x1c01f000, 0x4937c857, 0x4d300000,
+	0x0201f800, 0x0002075a, 0x04000011, 0x49366009,
+	0x4a026406, 0x00000001, 0x492e6008, 0x42000800,
+	0x00000009, 0x0201f800, 0x00104571, 0x4d380000,
+	0x42027000, 0x00000033, 0x0201f800, 0x000207a1,
+	0x5c027000, 0x82000540, 0x00000001, 0x5c026000,
+	0x1c01f000, 0x4933c857, 0x4d2c0000, 0x4c580000,
+	0x4d3c0000, 0x59325808, 0x83380580, 0x00000015,
+	0x04020022, 0x59a8b016, 0x82580c80, 0x00000019,
+	0x04001003, 0x4200b000, 0x00000018, 0x8058b104,
+	0x0401fa07, 0x80000580, 0x0401fa17, 0x832cac00,
+	0x00000009, 0x83cca400, 0x00000006, 0x0201f800,
+	0x0010ab17, 0x42027800, 0x00000001, 0x592c100a,
+	0x8c081518, 0x04020006, 0x59a80010, 0x592c100d,
+	0x80080580, 0x04020006, 0x417a7800, 0x59301009,
+	0x58081403, 0x0201f800, 0x001020a1, 0x0201f800,
+	0x00107b38, 0x0401f008, 0x4200b000, 0x00000002,
+	0x0401fa09, 0x0201f800, 0x0010801c, 0x0201f800,
+	0x0002077d, 0x5c027800, 0x5c00b000, 0x5c025800,
+	0x1c01f000, 0x4933c856, 0x49366009, 0x4a026406,
+	0x00000001, 0x492e6008, 0x4d380000, 0x42027000,
+	0x0000004d, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x82000540, 0x00000001, 0x1c01f000, 0x4803c856,
+	0x4d2c0000, 0x83380580, 0x00000015, 0x04020027,
+	0x59a80816, 0x59325808, 0x5930040b, 0x800000c4,
+	0x80040580, 0x04020021, 0x4c500000, 0x4c540000,
+	0x4c580000, 0x83cca400, 0x00000006, 0x4050a800,
+	0x5930b40b, 0x0201f800, 0x0010ab28, 0x83cca400,
+	0x00000006, 0x592cb205, 0x832cac00, 0x00000006,
+	0x0201f800, 0x0010ab17, 0x592e5801, 0x812e59c0,
+	0x040207f9, 0x5931d821, 0x58ef400b, 0x58ee580d,
+	0x4a025a04, 0x00000103, 0x58ec0009, 0x0801f800,
+	0x59300402, 0x5c00b000, 0x5c00a800, 0x5c00a000,
+	0x5c025800, 0x1c01f000, 0x0201f800, 0x0010801c,
+	0x5c025800, 0x1c01f000, 0x4933c857, 0x83380580,
+	0x00000035, 0x04000005, 0x59301419, 0x0401f851,
+	0x04000027, 0x0401f006, 0x4d300000, 0x5932601e,
+	0x0401f856, 0x5c026000, 0x04000020, 0x591c0c06,
+	0x82040580, 0x00000003, 0x04000004, 0x82040580,
+	0x00000006, 0x0402001c, 0x591c0c02, 0x59300419,
+	0x80040580, 0x04000009, 0x59300219, 0x80040580,
+	0x04020015, 0x591c0a02, 0x59300419, 0x80040580,
+	0x04020011, 0x0401f009, 0x59300a19, 0x82040580,
+	0x0000ffff, 0x04000005, 0x591c0202, 0x59300a19,
+	0x80040580, 0x04020008, 0x591c0009, 0x59300809,
+	0x80040580, 0x1c01f000, 0x417a3800, 0x82000540,
+	0x00000001, 0x1c01f000, 0x4803c856, 0x59b800e4,
+	0x8c000538, 0x02020800, 0x001005d8, 0x42000800,
+	0x0000012c, 0x4a0370e4, 0x20000000, 0x59b800e4,
+	0x80040840, 0x02000800, 0x001005d8, 0x8c00053c,
+	0x040207f9, 0x4a0370e4, 0x30000000, 0x40000000,
+	0x40000000, 0x40000000, 0x59b800e4, 0x8c00053c,
+	0x040207f1, 0x1c01f000, 0x4803c856, 0x4a0370e4,
+	0x20000000, 0x40000000, 0x59b800e4, 0x8c000538,
+	0x040207fb, 0x1c01f000, 0x59300807, 0x8c040d1e,
+	0x592c0c08, 0x04020002, 0x8c040d18, 0x1c01f000,
+	0x0401fc1c, 0x04000008, 0x42000800, 0x00000024,
+	0x0201f800, 0x00106681, 0x82063c00, 0x0010d1c0,
+	0x491fc857, 0x1c01f000, 0x83300480, 0x0010d1c0,
+	0x0400100a, 0x59a8000b, 0x81300480, 0x04021007,
+	0x59301402, 0x0401ffef, 0x04000007, 0x411c0000,
+	0x81300580, 0x04000003, 0x81780500, 0x0401f002,
+	0x81300540, 0x1c01f000, 0x4947c857, 0x4d300000,
+	0x0201f800, 0x00020245, 0x0402000a, 0x42026000,
+	0x0010bde9, 0x49366009, 0x492e6008, 0x0201f800,
+	0x0010203c, 0x80000580, 0x5c026000, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fc, 0x4933c857,
+	0x0201f800, 0x00109037, 0x02000800, 0x001005d8,
+	0x4d2c0000, 0x4d340000, 0x4d440000, 0x4c580000,
+	0x59325808, 0x59326809, 0x49425a06, 0x0201f800,
+	0x00105755, 0x592e8c06, 0x592c4207, 0x82200500,
+	0x0000000f, 0x0c01f806, 0x5c00b000, 0x5c028800,
+	0x5c026800, 0x5c025800, 0x1c01f000, 0x00109466,
+	0x00109488, 0x0010948f, 0x00109493, 0x0010949c,
+	0x00109463, 0x00109463, 0x00109463, 0x001094a0,
+	0x001094ac, 0x001094ac, 0x00109463, 0x00109463,
+	0x00109463, 0x00109463, 0x00109463, 0x4803c857,
+	0x0201f800, 0x001005d8, 0x814281c0, 0x04020012,
+	0x41785800, 0x592c0404, 0x8c00051c, 0x04020002,
+	0x59345c05, 0x442c2800, 0x59340008, 0x48002802,
+	0x59340009, 0x48002801, 0x59340006, 0x48002804,
+	0x59340007, 0x48002803, 0x4200b000, 0x0000000b,
+	0x0401f037, 0x592c0207, 0x8c00051e, 0x4200b000,
+	0x00000002, 0x04020032, 0x8204b540, 0x00000000,
+	0x0400002f, 0x44042800, 0x59326809, 0x59340400,
+	0x48002801, 0x4200b000, 0x00000002, 0x0401f028,
+	0x814281c0, 0x04020030, 0x59345c05, 0x442c2800,
+	0x4200b000, 0x00000001, 0x0401f021, 0x8340b540,
+	0x00000000, 0x0400001e, 0x0401f027, 0x814281c0,
+	0x04020025, 0x59340200, 0x44002800, 0x59340001,
+	0x48002801, 0x4200b000, 0x00000002, 0x0401f014,
+	0x8340b540, 0x00000000, 0x0402001b, 0x0401f010,
+	0x8340b540, 0x00000000, 0x0400000d, 0x0201f800,
+	0x00104a1f, 0x04000014, 0x8c20450e, 0x04000002,
+	0x497a6009, 0x4178b000, 0x497a5a06, 0x0401f004,
+	0x8340b540, 0x00000000, 0x0402000b, 0x592c0404,
+	0x8400051c, 0x48025c04, 0x592c0207, 0x8400051e,
+	0x48025a07, 0x0401f8aa, 0x497a6008, 0x0201f000,
+	0x000202da, 0x592c0207, 0x8c00051e, 0x4200b000,
+	0x00000002, 0x040207f2, 0x8204b540, 0x00000000,
+	0x040007ef, 0x44042800, 0x4200b000, 0x00000001,
+	0x0401f7eb, 0x4937c857, 0x4d300000, 0x0201f800,
+	0x0002075a, 0x04000011, 0x49366009, 0x4a026406,
+	0x00000001, 0x492e6008, 0x42000800, 0x0000000b,
+	0x0201f800, 0x00104571, 0x4d380000, 0x42027000,
+	0x00000043, 0x0201f800, 0x000207a1, 0x5c027000,
+	0x82000540, 0x00000001, 0x5c026000, 0x1c01f000,
+	0x4937c857, 0x4d2c0000, 0x59325808, 0x83380580,
+	0x00000015, 0x04020025, 0x59a80016, 0x82000580,
+	0x00000004, 0x04020021, 0x59a80010, 0x592c1009,
+	0x80080580, 0x04020010, 0x4d440000, 0x592e8c06,
+	0x592c0207, 0x4803c856, 0x82000500, 0x00000080,
+	0x84000548, 0x4d3c0000, 0x42027800, 0x00001000,
+	0x0201f800, 0x001049bb, 0x5c027800, 0x5c028800,
+	0x0401f004, 0x4803c856, 0x0201f800, 0x00104a1f,
+	0x0201f800, 0x00109037, 0x04000017, 0x4d400000,
+	0x42028000, 0x00000000, 0x41780800, 0x0401ff38,
+	0x5c028000, 0x0401f00e, 0x0201f800, 0x00104a1f,
+	0x040207f4, 0x0201f800, 0x00109037, 0x0400000a,
+	0x4c580000, 0x4200b000, 0x00000002, 0x0401f86e,
+	0x5c00b000, 0x0201f800, 0x0010801c, 0x0201f800,
+	0x0002077d, 0x5c025800, 0x1c01f000, 0x4937c857,
+	0x4d300000, 0x0201f800, 0x0002075a, 0x04000012,
+	0x49366009, 0x4a026406, 0x00000001, 0x4d3c0000,
+	0x4d380000, 0x417a7800, 0x0201f800, 0x00104567,
+	0x492e6008, 0x42027000, 0x00000004, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x5c027800, 0x82000540,
+	0x00000001, 0x5c026000, 0x1c01f000, 0x4937c857,
+	0x4d300000, 0x0201f800, 0x00107942, 0x0400000d,
+	0x49366009, 0x4a026406, 0x00000001, 0x492e6008,
+	0x4d380000, 0x42027000, 0x00000051, 0x0201f800,
+	0x000207a1, 0x5c027000, 0x82000540, 0x00000001,
+	0x5c026000, 0x1c01f000, 0x4933c857, 0x4c580000,
+	0x59325808, 0x83383580, 0x00000015, 0x04020011,
+	0x592c0008, 0x82000500, 0x00ffffff, 0x0402000a,
+	0x0201f800, 0x00105755, 0x59cc0000, 0x82000500,
+	0x00ffffff, 0x44002800, 0x4200b000, 0x00000001,
+	0x0401f80b, 0x0201f800, 0x00107b38, 0x0401f006,
+	0x4200b000, 0x00000002, 0x0401f823, 0x0201f800,
+	0x0010801c, 0x5c00b000, 0x1c01f000, 0x492fc857,
+	0x4c580000, 0x4c000000, 0x8058b1c0, 0x0400000b,
+	0x82580500, 0xfffffff0, 0x02020800, 0x001005d8,
+	0x8058b0d0, 0x592c0408, 0x82000500, 0xfffff0ff,
+	0x80580540, 0x48025c08, 0x5c000000, 0x5c00b000,
+	0x1c01f000, 0x492fc857, 0x4c000000, 0x4c040000,
+	0x800000d8, 0x592c0c08, 0x82040d00, 0xffff0fff,
+	0x80040540, 0x48025c08, 0x5c000800, 0x5c000000,
+	0x1c01f000, 0x4933c857, 0x4d2c0000, 0x59325808,
+	0x592c0207, 0x8400055e, 0x48025a07, 0x4c500000,
+	0x4c540000, 0x4c580000, 0x0401ffd9, 0x0201f800,
+	0x00105755, 0x46002800, 0x00000018, 0x80142800,
+	0x8058b040, 0x83cca400, 0x00000007, 0x4014a800,
+	0x0201f800, 0x0010ab17, 0x5c00b000, 0x5c00a800,
+	0x5c00a000, 0x5c025800, 0x1c01f000, 0x59325808,
+	0x592c0204, 0x82000580, 0x00000152, 0x1c01f000,
+	0x5930001f, 0x80000540, 0x02020800, 0x00100d56,
+	0x1c01f000, 0x4d2c0000, 0x59325808, 0x59300203,
+	0x4933c857, 0x492fc857, 0x493bc857, 0x4803c857,
+	0x82003480, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x001095bd,
+	0x001095c8, 0x00109603, 0x001095bd, 0x001095bd,
+	0x001095bd, 0x001095bd, 0x001095bd, 0x001095bf,
+	0x001095bd, 0x001095bd, 0x001095bd, 0x001095bd,
+	0x001095bd, 0x0201f800, 0x001005d8, 0x83383480,
+	0x00000056, 0x02021800, 0x001005d8, 0x493a6403,
+	0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+	0x83380580, 0x00000013, 0x0402000f, 0x592c000c,
+	0x800001c0, 0x04000006, 0x4a026203, 0x00000002,
+	0x59a80037, 0x48026206, 0x1c01f000, 0x4a025a06,
+	0x00000000, 0x0201f800, 0x000202da, 0x0201f000,
+	0x0002077d, 0x83380580, 0x00000027, 0x0400001a,
+	0x83380580, 0x00000014, 0x04000012, 0x83380580,
+	0x00000015, 0x04000005, 0x83380580, 0x00000016,
+	0x02020800, 0x001005d8, 0x0201f800, 0x00106f60,
+	0x02020000, 0x00107974, 0x59300203, 0x82000580,
+	0x00000002, 0x02020800, 0x001005d8, 0x0401f014,
+	0x0201f800, 0x00106bbf, 0x4a02580e, 0x00000011,
+	0x0401f005, 0x0201f800, 0x00106bbf, 0x4a02580e,
+	0x00000010, 0x4a025a06, 0x00000031, 0x4a02580d,
+	0x00000004, 0x0201f800, 0x000202da, 0x0201f800,
+	0x00104c19, 0x0201f000, 0x00107911, 0x59341400,
+	0x82081d00, 0x000000ff, 0x59300c03, 0x480bc857,
+	0x4807c857, 0x82040580, 0x00000053, 0x0400002e,
+	0x82040580, 0x00000002, 0x04000016, 0x82040580,
+	0x00000001, 0x04000017, 0x82040580, 0x00000003,
+	0x0400001c, 0x82040580, 0x00000005, 0x0400001d,
+	0x82040580, 0x00000033, 0x0400001a, 0x82040580,
+	0x00000000, 0x0400001b, 0x82040580, 0x00000004,
+	0x02020800, 0x001005d8, 0x0401f8a1, 0x0401f016,
+	0x820c0580, 0x00000003, 0x0400084c, 0x0401f012,
+	0x820c0580, 0x0000000b, 0x0402000f, 0x42000800,
+	0x00000007, 0x0201f800, 0x00104571, 0x0401f00a,
+	0x820c0580, 0x00000005, 0x04000864, 0x0401f006,
+	0x820c0580, 0x00000009, 0x04000889, 0x0401f002,
+	0x0401f893, 0x4a026403, 0x00000052, 0x59a81016,
+	0x592c040b, 0x8c000500, 0x04000003, 0x42001000,
+	0x00000008, 0x592c040b, 0x8c000516, 0x04000003,
+	0x82081400, 0x00000018, 0x592c000c, 0x497a580d,
+	0x497a580e, 0x80080c80, 0x04000009, 0x04001005,
+	0x4a025a06, 0x00000007, 0x40001000, 0x0401f006,
+	0x4a025a06, 0x00000015, 0x0401f003, 0x4a025a06,
+	0x00000000, 0x480a580c, 0x82081400, 0x00000003,
+	0x80081104, 0x0201f800, 0x00107ab5, 0x04000010,
+	0x592c1001, 0x480a600b, 0x58080800, 0x82080400,
+	0x00000002, 0x592c1011, 0x592c1812, 0x42003000,
+	0x00000000, 0x42002000, 0x00101200, 0x0201f800,
+	0x00107c32, 0x04000002, 0x1c01f000, 0x4a025a06,
+	0x0000002c, 0x497a580c, 0x0201f800, 0x000202da,
+	0x0201f000, 0x0002077d, 0x83380580, 0x00000015,
+	0x0402000a, 0x59a80005, 0x8c000514, 0x0402000b,
+	0x0201f800, 0x0010462a, 0x42000800, 0x00000004,
+	0x0201f000, 0x00104571, 0x42000800, 0x00000007,
+	0x0201f000, 0x00104571, 0x0201f800, 0x0010513b,
+	0x42001000, 0x00000010, 0x04020009, 0x59340002,
+	0x82000500, 0x00ff0000, 0x82000580, 0x00ff0000,
+	0x040007ec, 0x42001000, 0x00000008, 0x0201f800,
+	0x00104c6d, 0x040007e7, 0x592c040b, 0x84000540,
+	0x48025c0b, 0x0401f7e9, 0x83380580, 0x00000015,
+	0x0402000f, 0x59a80005, 0x8c000514, 0x04020010,
+	0x0201f800, 0x0010468d, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x00104567, 0x5c027800, 0x42000800,
+	0x00000006, 0x0201f000, 0x00104571, 0x42000800,
+	0x00000004, 0x0201f000, 0x00104571, 0x0201f800,
+	0x0010513b, 0x42001000, 0x00000010, 0x04020009,
+	0x59340002, 0x82000500, 0x00ff0000, 0x82000580,
+	0x00ff0000, 0x040007e7, 0x42001000, 0x00000008,
+	0x0201f800, 0x00104c6d, 0x040007e2, 0x592c040b,
+	0x84000540, 0x48025c0b, 0x0401f7e9, 0x42000800,
+	0x00000004, 0x0201f000, 0x00104571, 0x83380580,
+	0x00000015, 0x04020005, 0x0201f800, 0x0010a2c8,
+	0x02000800, 0x001048c1, 0x1c01f000, 0x83380580,
+	0x00000015, 0x0402001d, 0x4c580000, 0x83cc1400,
+	0x00000008, 0x4200b000, 0x00000002, 0x83341c00,
+	0x00000006, 0x0201f800, 0x0010855a, 0x04020012,
+	0x83cc1400, 0x0000000a, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000008, 0x0201f800, 0x0010855a,
+	0x04020009, 0x59342200, 0x59cc1007, 0x800811c0,
+	0x04000003, 0x480a6801, 0x84102542, 0x8410251a,
+	0x48126a00, 0x5c00b000, 0x1c01f000, 0x42000000,
+	0x0010b87b, 0x0201f800, 0x0010aa47, 0x0201f800,
+	0x00106c55, 0x59300203, 0x4933c857, 0x4803c857,
+	0x82000c80, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f803, 0x0201f000, 0x00106c4b, 0x0010970b,
+	0x0010971a, 0x0010970c, 0x00109709, 0x00109709,
+	0x00109709, 0x00109709, 0x00109709, 0x00109709,
+	0x00109709, 0x00109709, 0x00109709, 0x00109709,
+	0x00109709, 0x0201f800, 0x001005d8, 0x1c01f000,
+	0x59300403, 0x82000580, 0x00000052, 0x02000000,
+	0x00108d85, 0x0201f800, 0x00104c19, 0x59325808,
+	0x4a025a06, 0x00000006, 0x0201f800, 0x000202da,
+	0x0201f000, 0x00107911, 0x59301804, 0x840c0520,
+	0x48026004, 0x598c000d, 0x81300580, 0x04020010,
+	0x8c0c1d20, 0x04020010, 0x42001000, 0x0010b7f6,
+	0x50081000, 0x58080002, 0x82000580, 0x00000100,
+	0x0400000e, 0x5808000c, 0x81300580, 0x02020800,
+	0x001005d8, 0x4978100c, 0x0401f003, 0x8c0c1d20,
+	0x040207dc, 0x0201f800, 0x001068d3, 0x040007d9,
+	0x0201f800, 0x001005d8, 0x0201f800, 0x00106e8e,
+	0x040007f9, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x0c01f7bd, 0x4933c857,
+	0x4c500000, 0x4c540000, 0x4c580000, 0x592c0c07,
+	0x4806580a, 0x59cc0809, 0x48065807, 0x59cc0a08,
+	0x4806580b, 0x59c80817, 0x82040500, 0x000003ff,
+	0x800010c4, 0x8c040d14, 0x04000005, 0x59cc0002,
+	0x82000500, 0x00000003, 0x80081480, 0x82080480,
+	0x000000f1, 0x02021800, 0x001005d8, 0x480a621a,
+	0x412c0800, 0x0201f800, 0x001007d3, 0x02000800,
+	0x001005d8, 0x492c0809, 0x58040408, 0x84000552,
+	0x84000540, 0x48000c08, 0x82081400, 0x00000003,
+	0x80081104, 0x83cca400, 0x00000006, 0x832cac00,
+	0x00000004, 0x42000800, 0x00000010, 0x82080480,
+	0x00000010, 0x04021003, 0x40080800, 0x80000580,
+	0x4004b000, 0x4c000000, 0x0201f800, 0x0010ab28,
+	0x5c000000, 0x800001c0, 0x0400000d, 0x412c1000,
+	0x4c000000, 0x0201f800, 0x001007d3, 0x02000800,
+	0x001005d8, 0x492c1001, 0x832cac00, 0x00000004,
+	0x5c000000, 0x40001000, 0x0401f7e9, 0x5c00b000,
+	0x5c00a800, 0x5c00a000, 0x1c01f000, 0x4933c857,
+	0x4d2c0000, 0x4c380000, 0x59325808, 0x5930021a,
+	0x48025a08, 0x59301011, 0x800811c0, 0x04020008,
+	0x4a025a06, 0x00000000, 0x592c000b, 0x82000500,
+	0x00000c00, 0x0400000b, 0x0401f00b, 0x8c08153e,
+	0x04000006, 0x4a025a06, 0x00000007, 0x80081080,
+	0x80081000, 0x0401f003, 0x4a025a06, 0x00000015,
+	0x480a5807, 0x42000000, 0x0010bed9, 0x50007000,
+	0x5838000b, 0x80000540, 0x04020008, 0x4930700c,
+	0x4930700b, 0x58380002, 0x82000580, 0x00000000,
+	0x04020809, 0x0401f005, 0x82001400, 0x00000000,
+	0x45301000, 0x4930700b, 0x5c007000, 0x5c025800,
+	0x1c01f000, 0x4933c857, 0x592c0009, 0x40001000,
+	0x4800700a, 0x82080400, 0x00000004, 0x48007003,
+	0x592c000d, 0x592c100e, 0x48007007, 0x48087008,
+	0x592c000a, 0x592c1208, 0x80080c80, 0x04001002,
+	0x40001000, 0x82081400, 0x00000003, 0x80081104,
+	0x82080480, 0x00000010, 0x04021003, 0x80000580,
+	0x0401f003, 0x42001000, 0x00000010, 0x4800700d,
+	0x48087004, 0x800810c4, 0x48087005, 0x40381000,
+	0x0201f800, 0x00100858, 0x1c01f000, 0x4d2c0000,
+	0x0201f800, 0x001007d3, 0x02000800, 0x001005d8,
+	0x42000800, 0x0010bed9, 0x452c0800, 0x497a580b,
+	0x497a580c, 0x497a580d, 0x4a025809, 0x001097ea,
+	0x4a025802, 0x00000100, 0x4a025801, 0x00000000,
+	0x5c025800, 0x1c01f000, 0x4833c857, 0x4d300000,
+	0x4d2c0000, 0x4c5c0000, 0x4030b800, 0x585c000a,
+	0x80025d40, 0x04020004, 0x585c000c, 0x4c000000,
+	0x0401f044, 0x585c0002, 0x82000580, 0x00000100,
+	0x04020022, 0x592c0801, 0x4c040000, 0x0201f800,
+	0x001007f4, 0x5c000800, 0x800409c0, 0x0400001c,
+	0x4804b80a, 0x585c100d, 0x800811c0, 0x04020005,
+	0x40065800, 0x0201f800, 0x001007fd, 0x0401f014,
+	0x82080480, 0x00000010, 0x04021003, 0x80000580,
+	0x0401f003, 0x42001000, 0x00000010, 0x4800b80d,
+	0x4808b804, 0x800810c4, 0x4808b805, 0x82040400,
+	0x00000004, 0x4800b803, 0x405c1000, 0x0201f800,
+	0x00100858, 0x0401f025, 0x0401f828, 0x585c000c,
+	0x80026540, 0x59300000, 0x80000d40, 0x04020002,
+	0x4800b80b, 0x4800b80c, 0x497a6000, 0x4c000000,
+	0x4978b80a, 0x59325808, 0x4a025a04, 0x00000103,
+	0x59300402, 0x48025c06, 0x592c100b, 0x4c080000,
+	0x0201f800, 0x000202c1, 0x0201f800, 0x0010912a,
+	0x5c001000, 0x8c081518, 0x04000004, 0x0201f800,
+	0x001091d1, 0x0401f003, 0x0201f800, 0x0002077d,
+	0x405c7000, 0x5c000000, 0x80026540, 0x04000003,
+	0x59325808, 0x0401ff78, 0x5c00b800, 0x5c025800,
+	0x5c026000, 0x1c01f000, 0x483bc857, 0x5838000a,
+	0x40025800, 0x0201f800, 0x001007fd, 0x5838000c,
+	0x80026540, 0x59300008, 0x80025d40, 0x4a025a06,
+	0x00000002, 0x1c01f000, 0x4803c857, 0x4d1c0000,
+	0x497a601c, 0x41323800, 0x40026000, 0x4d3c0000,
+	0x42027800, 0x00000005, 0x0401f83c, 0x5c027800,
+	0x411e6000, 0x59300414, 0x84000502, 0x48026414,
+	0x5c023800, 0x1c01f000, 0x481bc857, 0x4933c857,
+	0x4c5c0000, 0x4c600000, 0x4010b800, 0x4014c000,
+	0x0201f800, 0x0010a942, 0x0201f800, 0x00103b25,
+	0x04000008, 0x40602800, 0x405c3000, 0x0201f800,
+	0x0010a446, 0x82000540, 0x00000001, 0x0401f002,
+	0x80000580, 0x5c00c000, 0x5c00b800, 0x1c01f000,
+	0x4803c856, 0x4d300000, 0x42026000, 0x0010d1c0,
+	0x59a8000e, 0x81640580, 0x04000016, 0x59300c06,
+	0x82040580, 0x00000001, 0x04000009, 0x82040580,
+	0x00000004, 0x04000006, 0x82040580, 0x00000010,
+	0x02000800, 0x00108cf9, 0x0401f005, 0x4807c857,
+	0x0201f800, 0x001092d7, 0x04020808, 0x83326400,
+	0x00000024, 0x41580000, 0x81300480, 0x040017e9,
+	0x5c026000, 0x1c01f000, 0x4933c857, 0x59300403,
+	0x4803c857, 0x0201f800, 0x00106c55, 0x4df00000,
+	0x59300406, 0x4803c857, 0x82000d80, 0x00000002,
+	0x04000018, 0x82000d80, 0x00000001, 0x04000009,
+	0x82000d80, 0x00000004, 0x04000006, 0x4933c856,
+	0x5c03e000, 0x02000800, 0x00106c4b, 0x0401f03c,
+	0x59300203, 0x82000d80, 0x00000001, 0x04000018,
+	0x82000d80, 0x00000002, 0x04000026, 0x82000d80,
+	0x00000005, 0x04000023, 0x0201f800, 0x001005d8,
+	0x59300203, 0x82000d80, 0x00000009, 0x0400000c,
+	0x82000d80, 0x0000000b, 0x04000009, 0x82000d80,
+	0x0000000a, 0x04000017, 0x82000d80, 0x0000000c,
+	0x04000014, 0x0201f800, 0x001005d8, 0x598c000d,
+	0x81300580, 0x04020004, 0x0201f800, 0x00106e8e,
+	0x0402000c, 0x59300004, 0x4803c857, 0x8c000520,
+	0x04000004, 0x84000520, 0x48026004, 0x0401f005,
+	0x0201f800, 0x001068d3, 0x02020800, 0x001005d8,
+	0x5c03e000, 0x02000800, 0x00106c4b, 0x59300406,
+	0x82000d80, 0x00000002, 0x04000009, 0x0201f800,
+	0x00104c19, 0x0201f800, 0x0010914e, 0x02000800,
+	0x0010801c, 0x8d3e7d00, 0x04000003, 0x0201f000,
+	0x00107911, 0x4a02621d, 0x00000001, 0x4a026403,
+	0x00000085, 0x4a026203, 0x00000009, 0x4a026406,
+	0x00000002, 0x42000800, 0x8000004b, 0x0201f000,
+	0x00020721, 0x4933c857, 0x59368c03, 0x4c180000,
+	0x59300203, 0x82003480, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f803, 0x5c003000, 0x1c01f000,
+	0x0010990a, 0x00109dcf, 0x00109edb, 0x0010990a,
+	0x0010990a, 0x0010990a, 0x0010990a, 0x0010990a,
+	0x0010992d, 0x0010990a, 0x0010990a, 0x0010990a,
+	0x0010990a, 0x0010990a, 0x0201f800, 0x001005d8,
+	0x4933c857, 0x42028800, 0x0000ffff, 0x813669c0,
+	0x04000002, 0x59368c03, 0x4c180000, 0x59300203,
+	0x82003480, 0x0000000e, 0x02021800, 0x001005d8,
+	0x0c01f803, 0x5c003000, 0x1c01f000, 0x00109929,
+	0x0010a180, 0x00109929, 0x00109929, 0x00109929,
+	0x00109929, 0x00109929, 0x0010a952, 0x0010a0ed,
+	0x0010a52c, 0x0010a562, 0x0010a52c, 0x0010a562,
+	0x00109929, 0x0201f800, 0x001005d8, 0x0201f800,
+	0x001005d8, 0x83383480, 0x00000051, 0x02021800,
+	0x001005d8, 0x41380000, 0x493bc857, 0x4d1c0000,
+	0x4d400000, 0x0c01f804, 0x5c028000, 0x5c023800,
+	0x1c01f000, 0x0010998a, 0x00109b69, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x00109b74, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x001099ac, 0x001099f5, 0x00109a0c, 0x00109a62,
+	0x00109ac6, 0x00109b04, 0x00109b34, 0x0010998a,
+	0x0010998a, 0x00109b7c, 0x0010998a, 0x0010998a,
+	0x00109b8a, 0x00109b93, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x00109c15,
+	0x0010998a, 0x0010998a, 0x00109a9a, 0x0010998a,
+	0x0010998a, 0x00109bec, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x00109c23, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x00109c6c, 0x0010998a, 0x0010998a,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010998a,
+	0x00109cb9, 0x0010998a, 0x00109ce5, 0x00109cf0,
+	0x0010998a, 0x0010998a, 0x0010998c, 0x00109cfb,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x0010999b,
+	0x0010998a, 0x0010998a, 0x0010998a, 0x00109d02,
+	0x00109d0a, 0x00109d28, 0x0201f800, 0x001005d8,
+	0x4933c857, 0x0201f800, 0x0010a592, 0x040203a4,
+	0x0201f800, 0x0010210a, 0x040203a1, 0x59cc0407,
+	0x4802601c, 0x4a026403, 0x00000045, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x4933c857,
+	0x0201f800, 0x0010a592, 0x04020395, 0x0201f800,
+	0x0010210a, 0x04020392, 0x0401fbce, 0x040201a0,
+	0x59cc0007, 0x4802601c, 0x4a026403, 0x0000004a,
+	0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+	0x4933c857, 0x0201f800, 0x0010210a, 0x04020009,
+	0x0201f800, 0x001048ec, 0x04020006, 0x82000500,
+	0x00000009, 0x82000580, 0x00000008, 0x04020008,
+	0x4a026403, 0x00000009, 0x4a02641a, 0x00000009,
+	0x4a02621a, 0x00000000, 0x0401f1b2, 0x0201f800,
+	0x001048c1, 0x0201f800, 0x00104a09, 0x04000021,
+	0x0201f800, 0x001049ed, 0x0400001e, 0x0201f800,
+	0x0010a252, 0x04020025, 0x42028000, 0x00000029,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x0201f800, 0x0010462a, 0x836c0580,
+	0x00000002, 0x04020004, 0x59a8001b, 0x80000000,
+	0x4803501b, 0x4a026403, 0x00000008, 0x42003000,
+	0x00000003, 0x0201f800, 0x00103b25, 0x04000191,
+	0x4a026203, 0x00000007, 0x41782800, 0x0401f180,
+	0x0201f800, 0x0010a3da, 0x040207e1, 0x4a026403,
+	0x00000009, 0x4a02641a, 0x0000000e, 0x4a02621a,
+	0x00001900, 0x0401f183, 0x4a026403, 0x00000009,
+	0x4a02641a, 0x00000003, 0x4a02621a, 0x00000f00,
+	0x0401f17c, 0x4933c857, 0x0201f800, 0x0010210a,
+	0x0402033b, 0x0201f800, 0x001048ec, 0x04020338,
+	0x493a6403, 0x0201f800, 0x0010a22d, 0x04020006,
+	0x42003000, 0x00000005, 0x4a026403, 0x00000006,
+	0x0401f7d9, 0x4a026403, 0x00000007, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00000000, 0x0401f165,
+	0x4933c857, 0x0201f800, 0x001048ec, 0x04020324,
+	0x0201f800, 0x0010a592, 0x02000800, 0x0010210a,
+	0x0402031f, 0x0201f800, 0x00104a09, 0x04020005,
+	0x42027800, 0x00000001, 0x0201f800, 0x00104567,
+	0x0201f800, 0x001049fc, 0x0402002b, 0x59cc0206,
+	0x82003500, 0x00000003, 0x0402002e, 0x82003480,
+	0x00000014, 0x0400102b, 0x5934300a, 0x84183516,
+	0x82000580, 0x00000014, 0x04020002, 0x84183556,
+	0x481a680a, 0x59cc0406, 0x82000500, 0x00000003,
+	0x04020020, 0x0201f800, 0x0010a29f, 0x04020028,
+	0x0201f800, 0x001049e7, 0x0402000c, 0x417a7800,
+	0x0201f800, 0x001020a1, 0x42003000, 0x00000006,
+	0x0201f800, 0x0010a93a, 0x42000000, 0x0010b865,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x0010468d,
+	0x4a026403, 0x0000000a, 0x42003000, 0x00000020,
+	0x0401f795, 0x4a026403, 0x0000000b, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00001e00, 0x0401f121,
+	0x42000000, 0x0010b860, 0x0201f800, 0x0010aa47,
+	0x4a026403, 0x0000000b, 0x4a02641a, 0x00000007,
+	0x4a02621a, 0x00000000, 0x0401f116, 0x4a026403,
+	0x0000000b, 0x4a02641a, 0x00000003, 0x4a02621a,
+	0x00000000, 0x0401f10f, 0x4933c857, 0x0201f800,
+	0x001048ec, 0x040202ce, 0x0201f800, 0x0010a592,
+	0x040202cb, 0x0201f800, 0x0010210a, 0x040202c8,
+	0x59cc0206, 0x82003500, 0x00000003, 0x0402001d,
+	0x82003480, 0x00000014, 0x0400101a, 0x59cc0406,
+	0x82000500, 0x00000003, 0x04020016, 0x59340400,
+	0x82000580, 0x00000707, 0x04000019, 0x417a7800,
+	0x0201f800, 0x001020a1, 0x42003000, 0x0000000a,
+	0x0201f800, 0x0010a93a, 0x42000000, 0x0010b862,
+	0x0201f800, 0x0010aa47, 0x4a026403, 0x0000000c,
+	0x41782800, 0x42003000, 0x00000021, 0x0401f752,
+	0x4a026403, 0x0000000d, 0x4a02641a, 0x00000007,
+	0x4a02621a, 0x00000000, 0x0401f0de, 0x4a026403,
+	0x0000000d, 0x4a02641a, 0x00000009, 0x4a02621a,
+	0x00001e00, 0x0401f0d7, 0x4933c857, 0x0201f800,
+	0x001048ec, 0x04020296, 0x0201f800, 0x0010a592,
+	0x04020293, 0x0201f800, 0x0010210a, 0x04020290,
+	0x0401facc, 0x0402001a, 0x493a6403, 0x4c5c0000,
+	0x0401fad2, 0x0402000e, 0x4a026403, 0x0000002e,
+	0x405c2800, 0x42003000, 0x00000024, 0x0201f800,
+	0x00103b25, 0x0400000c, 0x4a026203, 0x00000007,
+	0x405c2800, 0x5c00b800, 0x0401f0ad, 0x4a026403,
+	0x0000000d, 0x4a02641a, 0x00000007, 0x4a02621a,
+	0x00000000, 0x5c00b800, 0x0401f0b2, 0x4a026403,
+	0x0000000d, 0x4a02641a, 0x00000009, 0x4a02621a,
+	0x00001e00, 0x0401f0ab, 0x4933c857, 0x0201f800,
+	0x001048ec, 0x040206ef, 0x59a80026, 0x82000500,
+	0x00000009, 0x82000580, 0x00000008, 0x040006e9,
+	0x0201f800, 0x001049fc, 0x0402002d, 0x0201f800,
+	0x0010a2a7, 0x04020007, 0x4a026403, 0x0000000e,
+	0x41782800, 0x42003000, 0x00000052, 0x0401f702,
+	0x4933c857, 0x42003000, 0x00000003, 0x0201f800,
+	0x0010a942, 0x4d3c0000, 0x417a7800, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x59340200, 0x84000558,
+	0x48026a00, 0x42000800, 0x0000000b, 0x0201f800,
+	0x00104571, 0x0201f800, 0x00103b25, 0x04000076,
+	0x42003000, 0x00000007, 0x0401f062, 0x4933c857,
+	0x4a026403, 0x0000000f, 0x4a02641a, 0x00000003,
+	0x4a02621a, 0x00001e00, 0x0401f072, 0x59340400,
+	0x82000580, 0x00000703, 0x040007f5, 0x0401f040,
+	0x4933c857, 0x0201f800, 0x001048ec, 0x0402022c,
+	0x59a80026, 0x82000500, 0x00000009, 0x82000580,
+	0x00000008, 0x04000226, 0x0201f800, 0x001049f3,
+	0x0402002f, 0x0201f800, 0x0010a2c8, 0x02000800,
+	0x0010a252, 0x04020007, 0x4a026403, 0x00000010,
+	0x41782800, 0x42003000, 0x00000050, 0x0401f6c2,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c027800, 0x42003000, 0x00000003, 0x0201f800,
+	0x0010a942, 0x42000000, 0x0010b864, 0x0201f800,
+	0x0010aa47, 0x59340200, 0x84000558, 0x48026a00,
+	0x0401f7c5, 0x4a026403, 0x00000011, 0x4a02641a,
+	0x00000003, 0x4a02621a, 0x00001e00, 0x0401f03d,
+	0x4933c857, 0x0201f800, 0x0010210a, 0x02000800,
+	0x0010a592, 0x040201fa, 0x0401fa36, 0x04020008,
+	0x4a026403, 0x00000012, 0x0401f032, 0x59340400,
+	0x82000580, 0x00000703, 0x040007eb, 0x4d3c0000,
+	0x417a7800, 0x42028000, 0x00000029, 0x0201f800,
+	0x0010203c, 0x5c027800, 0x42003000, 0x00000017,
+	0x0201f800, 0x0010a942, 0x42000000, 0x0010b864,
+	0x0201f800, 0x0010aa47, 0x0201f800, 0x00103b25,
+	0x04000015, 0x42003000, 0x00000006, 0x41782800,
+	0x42028000, 0x00000029, 0x4933c857, 0x4a026403,
+	0x00000001, 0x4a026203, 0x00000007, 0x0201f800,
+	0x0010a974, 0x0201f000, 0x0010a43e, 0x42028000,
+	0x00000046, 0x0201f800, 0x0010a974, 0x0201f000,
+	0x0010a43e, 0x4933c857, 0x4a026403, 0x00000001,
+	0x42000800, 0x0000000b, 0x0201f800, 0x00104571,
+	0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+	0x4933c857, 0x42000800, 0x00000009, 0x0201f800,
+	0x00104571, 0x4a026403, 0x00000005, 0x0401f7f5,
+	0x0201f800, 0x0010a592, 0x040201b5, 0x0201f800,
+	0x0010210a, 0x040201b2, 0x0401f9ee, 0x040207c0,
+	0x4a026403, 0x00000020, 0x4a026203, 0x00000001,
+	0x0201f000, 0x0010672b, 0x0201f800, 0x0010210a,
+	0x040201a7, 0x4a026403, 0x00000023, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x0010a592, 0x02000800, 0x0010210a, 0x0402019c,
+	0x0401f9d8, 0x040207aa, 0x40300800, 0x59a81010,
+	0x59cc0007, 0x82000500, 0x00ffffff, 0x80080580,
+	0x04000019, 0x59cc1408, 0x0201f800, 0x0010902c,
+	0x0400002d, 0x59cc0c08, 0x4d300000, 0x0201f800,
+	0x00105dd7, 0x41323800, 0x5c026000, 0x04000026,
+	0x591c0202, 0x82000580, 0x0000ffff, 0x04000005,
+	0x59cc1208, 0x591c0202, 0x80080580, 0x0402001e,
+	0x591c0406, 0x82000580, 0x00000007, 0x0402001a,
+	0x0401f02c, 0x59cc1208, 0x82080580, 0x0000ffff,
+	0x0400000c, 0x0201f800, 0x00109410, 0x04000012,
+	0x59cc1408, 0x591c0202, 0x80080580, 0x0402000e,
+	0x591c0009, 0x81340580, 0x04000016, 0x0401f00a,
+	0x59cc1408, 0x417a7800, 0x0201f800, 0x0010a405,
+	0x04020010, 0x59cc1208, 0x82080580, 0x0000ffff,
+	0x04000019, 0x4a026403, 0x00000026, 0x4a02621a,
+	0x00001700, 0x59cc1204, 0x82081580, 0x0000ffff,
+	0x04020798, 0x4a026403, 0x00000025, 0x0401f795,
+	0x591c0406, 0x82000580, 0x00000007, 0x040207f2,
+	0x591c0403, 0x82000580, 0x00000024, 0x04020006,
+	0x4d300000, 0x411e6000, 0x0201f800, 0x0002077d,
+	0x5c026000, 0x4a026403, 0x00000025, 0x0401f785,
+	0x4933c857, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00104567, 0x5c027800, 0x4c580000,
+	0x4200b000, 0x00000002, 0x83a81c00, 0x00000002,
+	0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a,
+	0x5c00b000, 0x04000004, 0x4a026403, 0x00000031,
+	0x0401f770, 0x0201f800, 0x00107911, 0x0201f800,
+	0x0010513b, 0x0402000f, 0x0201f800, 0x00105149,
+	0x04020008, 0x4a035033, 0x00000001, 0x4202d800,
+	0x00000001, 0x0201f800, 0x001050a2, 0x0401f005,
+	0x42000000, 0x00000001, 0x0201f800, 0x00105113,
+	0x1c01f000, 0x0201f800, 0x0010210a, 0x0402011c,
+	0x0401f958, 0x0402072a, 0x493a6403, 0x0401f996,
+	0x04020004, 0x4a026403, 0x0000002b, 0x0401f751,
+	0x4a026403, 0x0000002c, 0x0401f74e, 0x4933c857,
+	0x0201f800, 0x0010210a, 0x0402010d, 0x0201f800,
+	0x001049e7, 0x04020740, 0x0201f800, 0x001048d9,
+	0x0400003c, 0x59cc0408, 0x48026419, 0x59cc0208,
+	0x48026219, 0x59cc0807, 0x59340002, 0x82000500,
+	0x00ffffff, 0x80040580, 0x04000012, 0x59a80010,
+	0x80040580, 0x04020021, 0x59cc1408, 0x0201f800,
+	0x00109410, 0x04000023, 0x0201f800, 0x0010a4ca,
+	0x04000020, 0x0201f800, 0x0010a921, 0x0400001d,
+	0x491e601e, 0x4a026403, 0x00000036, 0x0401f0e6,
+	0x59cc1208, 0x82080580, 0x0000ffff, 0x04000009,
+	0x0201f800, 0x00109410, 0x04000012, 0x591c0202,
+	0x59cc0c08, 0x80040580, 0x0402000e, 0x0401f7eb,
+	0x59cc1408, 0x41327800, 0x0201f800, 0x0010a405,
+	0x04000008, 0x0401f7e5, 0x4803c856, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00001500, 0x0401f006,
+	0x4803c856, 0x4a02641a, 0x00000003, 0x4a02621a,
+	0x00001700, 0x4a026403, 0x00000037, 0x0401f0c6,
+	0x4803c856, 0x4a026403, 0x00000012, 0x0401f0c2,
+	0x4933c857, 0x0201f800, 0x0010210a, 0x040200c4,
+	0x0201f800, 0x001049e7, 0x040206f7, 0x0201f800,
+	0x001048d9, 0x0400003e, 0x59cc0407, 0x48026419,
+	0x59cc1207, 0x480a6219, 0x82080580, 0x0000ffff,
+	0x04000005, 0x0201f800, 0x00109410, 0x0400002c,
+	0x0401f006, 0x59cc1407, 0x41327800, 0x0201f800,
+	0x0010a405, 0x04000026, 0x59cc0c07, 0x591c0202,
+	0x80040580, 0x04020022, 0x4d300000, 0x411e6000,
+	0x0201f800, 0x00108bd7, 0x5c026000, 0x59cc0c09,
+	0x82040d00, 0x0000ff00, 0x840409c0, 0x0201f800,
+	0x0010a921, 0x04000016, 0x82040580, 0x00000001,
+	0x0400000a, 0x82040580, 0x00000005, 0x04000004,
+	0x82040580, 0x00000007, 0x04020007, 0x591c0008,
+	0x80000540, 0x04000004, 0x59cc2808, 0x0201f000,
+	0x0010a4de, 0x4803c856, 0x4a02641a, 0x00000009,
+	0x4a02621a, 0x00002a00, 0x0401f006, 0x4803c856,
+	0x4a02641a, 0x00000003, 0x4a02621a, 0x00000300,
+	0x4a026403, 0x0000003b, 0x0401f07b, 0x4803c856,
+	0x4a02641a, 0x0000000b, 0x4a02621a, 0x00000000,
+	0x0401f7f8, 0x4c080000, 0x0201f800, 0x001048ec,
+	0x04000026, 0x0201f800, 0x001048c1, 0x0201f800,
+	0x0010a601, 0x0402001e, 0x59a80026, 0x82000540,
+	0x00000003, 0x48035026, 0x59a8001d, 0x800000d0,
+	0x59a80810, 0x82040d00, 0x000000ff, 0x80041540,
+	0x480b5010, 0x42000800, 0x00000003, 0x0201f800,
+	0x00106c78, 0x497b5028, 0x0201f800, 0x00103b25,
+	0x04000003, 0x4a032804, 0x000007d0, 0x8c00050a,
+	0x0402000a, 0x0201f800, 0x0002077d, 0x0201f800,
+	0x00101e45, 0x5c001000, 0x1c01f000, 0x0201f800,
+	0x0010a623, 0x0401f7fc, 0x5c001000, 0x0201f000,
+	0x0002077d, 0x0201f800, 0x0010210a, 0x0402004c,
+	0x0201f800, 0x0010a628, 0x4a026403, 0x00000047,
+	0x4a026203, 0x00000001, 0x0201f000, 0x0010672b,
+	0x0201f800, 0x0010210a, 0x04020041, 0x0201f800,
+	0x0010a628, 0x4a026403, 0x00000047, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x0010210a, 0x04020036, 0x0201f800, 0x0010a628,
+	0x0201f000, 0x0002077d, 0x0401f834, 0x04000030,
+	0x4a026403, 0x0000004e, 0x4a026203, 0x00000001,
+	0x0201f000, 0x0010672b, 0x4a026403, 0x0000004f,
+	0x497a601c, 0x59cc0a06, 0x82040d00, 0x000000ff,
+	0x800409c0, 0x0400065f, 0x82040580, 0x00000001,
+	0x04020005, 0x59cc0808, 0x59a80005, 0x80040580,
+	0x04000658, 0x82040580, 0x00000002, 0x0402000a,
+	0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000006, 0x0201f800, 0x0010855a,
+	0x0400064c, 0x4a02601c, 0x00000001, 0x0401f649,
+	0x4a026403, 0x00000050, 0x59cc0207, 0x4802601c,
+	0x0401f644, 0x4a026203, 0x00000001, 0x42000800,
+	0x80000040, 0x0201f000, 0x00020721, 0x4803c857,
+	0x0201f000, 0x0002077d, 0x4d2c0000, 0x4c500000,
+	0x4c580000, 0x4c540000, 0x59a80016, 0x82000c80,
+	0x00000829, 0x04021029, 0x0201f800, 0x001007d3,
+	0x04000026, 0x492e6008, 0x59a80016, 0x80000104,
+	0x48025802, 0x83cca400, 0x00000006, 0x82000c80,
+	0x0000000b, 0x04001013, 0x4a025811, 0x0000000b,
+	0x4200b000, 0x0000000b, 0x832c0400, 0x00000005,
+	0x4000a800, 0x0201f800, 0x0010ab17, 0x412c7000,
+	0x0201f800, 0x001007d3, 0x04000010, 0x492c7001,
+	0x40040000, 0x800409c0, 0x04000009, 0x0401f7ec,
+	0x48025811, 0x4000b000, 0x832c0400, 0x00000005,
+	0x4000a800, 0x0201f800, 0x0010ab17, 0x82000540,
+	0x00000001, 0x0401f006, 0x497b5016, 0x59325808,
+	0x0201f800, 0x001007fd, 0x80000580, 0x5c00a800,
+	0x5c00b000, 0x5c00a000, 0x5c025800, 0x1c01f000,
+	0x4d340000, 0x59326809, 0x59343400, 0x4933c857,
+	0x4937c857, 0x481bc857, 0x0201f800, 0x001049f3,
+	0x5c026800, 0x1c01f000, 0x4933c857, 0x4c5c0000,
+	0x4d3c0000, 0x0401f840, 0x0402002c, 0x59cc0207,
+	0x82000d00, 0x0000ff00, 0x900411c0, 0x59cc000a,
+	0x82000500, 0x00ffffff, 0x80081540, 0x480a601c,
+	0x8c040d18, 0x0400000e, 0x42003000, 0x00000008,
+	0x0201f800, 0x0010a932, 0x42000000, 0x0010b863,
+	0x0201f800, 0x0010aa47, 0x4200b800, 0x00000002,
+	0x42027800, 0x00000001, 0x0401f011, 0x4178b800,
+	0x8c040d1a, 0x04000011, 0x59cc000a, 0x0201f800,
+	0x00105c9a, 0x0402000d, 0x42003000, 0x00000009,
+	0x0201f800, 0x0010a93a, 0x42000000, 0x0010b863,
+	0x0201f800, 0x0010aa47, 0x417a7800, 0x0201f800,
+	0x001020a1, 0x0401f004, 0x82000540, 0x00000001,
+	0x0401f002, 0x80000580, 0x5c027800, 0x5c00b800,
+	0x1c01f000, 0x4933c857, 0x59cc0206, 0x82000480,
+	0x00000010, 0x04021006, 0x4a02621a, 0x00000000,
+	0x82000540, 0x00000001, 0x0401f002, 0x80000580,
+	0x1c01f000, 0x4933c857, 0x4a02621a, 0x00000000,
+	0x59cc0407, 0x82000500, 0x0000ff00, 0x82000580,
+	0x00000800, 0x04020009, 0x59cc0006, 0x82000500,
+	0x00ff0000, 0x82000d80, 0x00140000, 0x04000003,
+	0x82000d80, 0x00100000, 0x1c01f000, 0x4933c857,
+	0x59300403, 0x82003480, 0x00000051, 0x02021800,
+	0x001005d8, 0x83383580, 0x00000013, 0x04020003,
+	0x4803c857, 0x0c01f012, 0x83383580, 0x00000027,
+	0x04000005, 0x83383580, 0x00000014, 0x02020800,
+	0x001005d8, 0x0201f800, 0x001048c1, 0x42000800,
+	0x00000007, 0x0201f800, 0x00104571, 0x0201f800,
+	0x00106bbf, 0x0201f000, 0x00107911, 0x00109e3c,
+	0x00109e45, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e45, 0x00109e50, 0x00109ecd, 0x00109e95,
+	0x00109ecd, 0x00109ead, 0x00109ecd, 0x00109ebe,
+	0x00109ecd, 0x00109ec6, 0x00109ecd, 0x00109ec6,
+	0x00109ecd, 0x00109ecd, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e45, 0x00109e3c, 0x00109ecd,
+	0x00109e3c, 0x00109e3c, 0x00109ecd, 0x00109e3c,
+	0x00109eca, 0x00109ecd, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109ecd, 0x00109ecd,
+	0x00109e3c, 0x00109ec3, 0x00109ecd, 0x00109e3c,
+	0x00109e4a, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109ec9, 0x00109ecd, 0x00109e3c,
+	0x00109e3c, 0x00109ecd, 0x00109ecd, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3c, 0x00109e3c, 0x00109e3c,
+	0x00109e3e, 0x00109e3c, 0x00109e3e, 0x00109e3c,
+	0x00109e3c, 0x00109e3e, 0x00109e3c, 0x00109e3c,
+	0x00109e3c, 0x00109e3e, 0x00109e3e, 0x00109e3e,
+	0x0201f800, 0x001005d8, 0x4d2c0000, 0x59325808,
+	0x0201f800, 0x001007fd, 0x5c025800, 0x0201f000,
+	0x0002077d, 0x59a80037, 0x48026206, 0x4a026203,
+	0x00000002, 0x1c01f000, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x00104567, 0x5c027800, 0x0401f07e,
+	0x42000800, 0x00000007, 0x0201f800, 0x00104571,
+	0x59a80026, 0x8c000508, 0x04000012, 0x59326809,
+	0x4c580000, 0x4200b000, 0x00000002, 0x83a81c00,
+	0x00000002, 0x83341400, 0x00000006, 0x0201f800,
+	0x0010855a, 0x80000540, 0x5c00b000, 0x0402006a,
+	0x59340200, 0x8400051a, 0x48026a00, 0x0401f01b,
+	0x599c0017, 0x8c00050a, 0x04020063, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x00104567, 0x5c027800,
+	0x42000800, 0x00000007, 0x0201f800, 0x00104571,
+	0x59340212, 0x82000500, 0x0000ff00, 0x04000056,
+	0x599c0019, 0x8c00050e, 0x04020053, 0x416c0000,
+	0x82000580, 0x00000002, 0x04020004, 0x59a8001b,
+	0x80000000, 0x4803501b, 0x42000800, 0x00000003,
+	0x0201f800, 0x00104571, 0x4a026406, 0x00000001,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000002,
+	0x0201f800, 0x0010672b, 0x4ce80000, 0x4201d000,
+	0x00000001, 0x0201f800, 0x00105fae, 0x5c01d000,
+	0x1c01f000, 0x0201f800, 0x001049f3, 0x04000036,
+	0x0201f800, 0x0010645e, 0x42000800, 0x00000004,
+	0x0201f800, 0x00104571, 0x0201f800, 0x0010a96a,
+	0x0402002d, 0x42000800, 0x00000005, 0x0201f800,
+	0x00104571, 0x4a026406, 0x00000001, 0x4a026203,
+	0x00000001, 0x4a026403, 0x00000003, 0x0201f000,
+	0x0010672b, 0x42000800, 0x00000006, 0x0401f820,
+	0x59303009, 0x599c0017, 0x8c00050a, 0x0402001a,
+	0x59a80026, 0x8c000508, 0x04000017, 0x0201f800,
+	0x001049e7, 0x04000014, 0x59a8001b, 0x80000000,
+	0x4803501b, 0x0401f7c5, 0x42000800, 0x00000004,
+	0x0201f800, 0x00104571, 0x0401f792, 0x42000800,
+	0x00000004, 0x0401f006, 0x0201f800, 0x001048c1,
+	0x0401f005, 0x0401f004, 0x0401f003, 0x0201f800,
+	0x00104571, 0x0201f000, 0x0002077d, 0x4933c857,
+	0x4807c857, 0x0201f800, 0x00104571, 0x4d3c0000,
+	0x417a7800, 0x0201f800, 0x00104567, 0x5c027800,
+	0x0201f800, 0x00102074, 0x1c01f000, 0x4933c857,
+	0x59340400, 0x80000110, 0x82003480, 0x0000000c,
+	0x02021800, 0x001005d8, 0x83383580, 0x00000015,
+	0x04020002, 0x0c01f006, 0x83383580, 0x00000016,
+	0x02020800, 0x001005d8, 0x0c01f00d, 0x001080b8,
+	0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8,
+	0x001080b8, 0x00109f30, 0x00109f03, 0x001080b8,
+	0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8,
+	0x001080b8, 0x001080b8, 0x001080b8, 0x001080b8,
+	0x001080b8, 0x00109f30, 0x00109f37, 0x001080b8,
+	0x001080b8, 0x001080b8, 0x001080b8, 0x4933c857,
+	0x599c0017, 0x8c00050a, 0x0402001b, 0x813669c0,
+	0x04000019, 0x59340212, 0x82000500, 0x0000ff00,
+	0x04000015, 0x599c0019, 0x8c00050e, 0x04020012,
+	0x4d3c0000, 0x417a7800, 0x0201f800, 0x00104567,
+	0x5c027800, 0x42000800, 0x00000003, 0x0201f800,
+	0x00104571, 0x4a026406, 0x00000001, 0x4a026203,
+	0x00000001, 0x4a026403, 0x00000002, 0x0201f000,
+	0x0010672b, 0x59cc0001, 0x0201f800, 0x00105c9a,
+	0x0402000b, 0x0201f800, 0x00020245, 0x02020000,
+	0x0002077d, 0x59345002, 0x0201f800, 0x001042b4,
+	0x482a6802, 0x0201f000, 0x0002077d, 0x1c01f000,
+	0x4933c857, 0x59303403, 0x82183580, 0x0000001e,
+	0x02000000, 0x0002077d, 0x1c01f000, 0x4933c857,
+	0x0201f800, 0x001083df, 0x02020000, 0x0002077d,
+	0x4a026203, 0x00000001, 0x4a026403, 0x00000001,
+	0x0201f000, 0x0010672b, 0x493bc857, 0x83380580,
+	0x00000051, 0x0402000b, 0x0201f800, 0x00106f60,
+	0x02020000, 0x00107974, 0x59300203, 0x82000580,
+	0x00000002, 0x0400006d, 0x0201f800, 0x001005d8,
+	0x83380580, 0x00000027, 0x04000014, 0x83380580,
+	0x00000048, 0x04000006, 0x83380580, 0x00000014,
+	0x0400000e, 0x02020800, 0x001005d8, 0x0201f800,
+	0x00106f60, 0x02020000, 0x00107974, 0x59300203,
+	0x82000580, 0x00000004, 0x02000000, 0x0002086e,
+	0x0201f800, 0x001005d8, 0x59300403, 0x82000c80,
+	0x00000044, 0x02021800, 0x001005d8, 0x82000480,
+	0x00000040, 0x02001800, 0x001005d8, 0x40027000,
+	0x4803c857, 0x0c01f001, 0x00109f76, 0x00109f78,
+	0x00109f78, 0x00109f93, 0x0201f800, 0x001005d8,
+	0x0201f800, 0x00106bbf, 0x59325808, 0x812e59c0,
+	0x04000016, 0x832c0500, 0x00ff0000, 0x04000013,
+	0x4a026203, 0x00000002, 0x59326809, 0x59340200,
+	0x8c00050e, 0x0402000d, 0x42028000, 0x00000004,
+	0x0201f800, 0x0010a3ef, 0x497a6008, 0x59300206,
+	0x80000540, 0x04020003, 0x59a80038, 0x48026206,
+	0x4a026203, 0x00000007, 0x1c01f000, 0x0201f800,
+	0x00106bbf, 0x0201f800, 0x00109037, 0x02000000,
+	0x00107911, 0x59325808, 0x0201f800, 0x001007f4,
+	0x0201f000, 0x00107911, 0x0201f800, 0x001005d8,
+	0x59325808, 0x592c040a, 0x8c000502, 0x04000007,
+	0x4a026203, 0x00000007, 0x42027000, 0x00000043,
+	0x0201f000, 0x000207a1, 0x4a026203, 0x00000004,
+	0x1c01f000, 0x0201f800, 0x0010a597, 0x02000000,
+	0x0002086c, 0x1c01f000, 0x4a026203, 0x00000001,
+	0x4a026403, 0x00000041, 0x42027800, 0x80002042,
+	0x0201f000, 0x00020721, 0x83380580, 0x00000051,
+	0x04000006, 0x83380580, 0x00000041, 0x02020800,
+	0x001005d8, 0x1c01f000, 0x0201f800, 0x000206fd,
+	0x0201f800, 0x0010a5df, 0x0201f000, 0x0002077d,
+	0x83380480, 0x00000050, 0x02021800, 0x001005d8,
+	0x83380480, 0x00000049, 0x02001800, 0x001005d8,
+	0x0c01f001, 0x00109fda, 0x00109ffb, 0x00109fd8,
+	0x00109fd8, 0x00109fd8, 0x00109fd8, 0x00109ffb,
+	0x0201f800, 0x001005d8, 0x59325808, 0x592c040a,
+	0x8c00051e, 0x0400000d, 0x82000d00, 0x000000c0,
+	0x82040d80, 0x00000080, 0x0400000d, 0x59300804,
+	0x8c040d18, 0x0402000a, 0x42027000, 0x00000041,
+	0x0201f000, 0x0002088d, 0x4a026203, 0x00000007,
+	0x497a6206, 0x0201f000, 0x000206fd, 0x59325808,
+	0x592c0c0a, 0x8c040d1a, 0x04020005, 0x0201f800,
+	0x000206fd, 0x0201f000, 0x0002077d, 0x0201f800,
+	0x0010a597, 0x040007fa, 0x1c01f000, 0x0201f800,
+	0x00106b8a, 0x59325808, 0x59326809, 0x59340200,
+	0x8c00050e, 0x0400000e, 0x592c040a, 0x82000500,
+	0x000000c0, 0x82000580, 0x00000080, 0x04000005,
+	0x592c000f, 0x59301815, 0x800c1c80, 0x480e6015,
+	0x4a026203, 0x00000002, 0x0401f00d, 0x42028000,
+	0x00000004, 0x0401fbde, 0x59300206, 0x80000540,
+	0x04020004, 0x59a80038, 0x800000c2, 0x48026206,
+	0x497a6008, 0x4a026203, 0x00000007, 0x1c01f000,
+	0x4a026203, 0x00000007, 0x497a6206, 0x0201f000,
+	0x000206fd, 0x4a026203, 0x00000007, 0x497a6206,
+	0x0201f000, 0x000206f8, 0x59300414, 0x8c00051c,
+	0x02020000, 0x0002087e, 0x59325808, 0x592c200f,
+	0x40080000, 0x80102480, 0x59300015, 0x80102400,
+	0x48126015, 0x0201f000, 0x0002087e, 0x8c040d0e,
+	0x0402000a, 0x4a026203, 0x00000006, 0x0401f823,
+	0x5930001f, 0x80000540, 0x02020800, 0x00100d7c,
+	0x0201f000, 0x000206f8, 0x4a026203, 0x00000002,
+	0x1c01f000, 0x42000800, 0x00000001, 0x0201f800,
+	0x00100d7c, 0x82040580, 0x00000001, 0x02000000,
+	0x00020885, 0x0401f7d8, 0x59300414, 0x8c00051c,
+	0x04000006, 0x0201f800, 0x00100b63, 0x02000000,
+	0x00020877, 0x1c01f000, 0x59300011, 0x80000540,
+	0x04020005, 0x0201f800, 0x00100b63, 0x02000000,
+	0x00020877, 0x1c01f000, 0x492fc857, 0x480bc857,
+	0x8c08153e, 0x04000006, 0x80081080, 0x80081000,
+	0x42000800, 0x00000009, 0x0401f003, 0x42000800,
+	0x00000015, 0x480a580b, 0x1c01f000, 0x83380580,
+	0x00000013, 0x04000005, 0x83380580, 0x00000014,
+	0x02020800, 0x001005d8, 0x59300414, 0x8c000516,
+	0x02000800, 0x001005d8, 0x1c01f000, 0x0201f800,
+	0x001005d8, 0x59300008, 0x80000540, 0x02020800,
+	0x001005d8, 0x1c01f000, 0x59300414, 0x8c000516,
+	0x02000800, 0x001005d8, 0x1c01f000, 0x4a026203,
+	0x00000004, 0x493a6403, 0x42000800, 0x80002001,
+	0x0201f000, 0x00020721, 0x4a026203, 0x00000003,
+	0x493a6403, 0x0201f800, 0x000200c9, 0x59325808,
+	0x592c040a, 0x8c00051e, 0x04000012, 0x82000500,
+	0x000000c0, 0x82000580, 0x00000080, 0x04000011,
+	0x59300414, 0x8c000512, 0x0402000a, 0x8c000510,
+	0x04020008, 0x592c040c, 0x80000540, 0x04020005,
+	0x82080d40, 0x80003065, 0x0201f000, 0x00106721,
+	0x82080d40, 0x80002065, 0x0201f000, 0x00106721,
+	0x82080d40, 0x80002042, 0x0201f000, 0x00106721,
+	0x4933c857, 0x493bc857, 0x83380480, 0x00000044,
+	0x02021800, 0x001005d8, 0x83380480, 0x00000041,
+	0x02001800, 0x001005d8, 0x0c01f001, 0x0010a0b6,
+	0x0010a0c6, 0x0010a0db, 0x59325808, 0x592c040a,
+	0x8c00051e, 0x0400001d, 0x82001d00, 0x000000c0,
+	0x820c1d80, 0x000000c0, 0x04000018, 0x4a026203,
+	0x00000001, 0x493a6403, 0x42000800, 0x80002042,
+	0x0201f000, 0x00020721, 0x59325808, 0x592c040a,
+	0x8c00051e, 0x0400000d, 0x82001d00, 0x000000c0,
+	0x820c1d80, 0x000000c0, 0x04000008, 0x4a026203,
+	0x00000001, 0x493a6403, 0x42000800, 0x80002001,
+	0x0201f000, 0x00020721, 0x497a6008, 0x497a6206,
+	0x42028000, 0x00000004, 0x0401f315, 0x59325808,
+	0x592c040a, 0x8c00051e, 0x040007f8, 0x82001d00,
+	0x000000c0, 0x820c1d80, 0x000000c0, 0x040007f3,
+	0x4a026203, 0x00000003, 0x493a6403, 0x0201f800,
+	0x000200c9, 0x82080d40, 0x80002065, 0x0201f000,
+	0x00106721, 0x4933c857, 0x493bc857, 0x83380580,
+	0x00000085, 0x04000006, 0x83380580, 0x00000088,
+	0x0400000a, 0x0201f800, 0x001005d8, 0x4a026203,
+	0x00000009, 0x493a6403, 0x42000800, 0x8000004b,
+	0x0201f000, 0x00020721, 0x4d1c0000, 0x813669c0,
+	0x04000004, 0x0201f800, 0x0010a592, 0x04020044,
+	0x59cc1404, 0x0401f846, 0x04000018, 0x591c0406,
+	0x82000500, 0x0000001f, 0x82002580, 0x00000006,
+	0x04000007, 0x82002580, 0x00000004, 0x0400002e,
+	0x82002580, 0x00000011, 0x0402000c, 0x497a3a05,
+	0x42002000, 0x00000054, 0x0201f800, 0x00107a4a,
+	0x4a026203, 0x00000007, 0x493a6403, 0x0201f800,
+	0x0010a974, 0x0401f02c, 0x0201f800, 0x00103b25,
+	0x04000004, 0x42023800, 0xffffffff, 0x0401f7f1,
+	0x813669c0, 0x04020009, 0x59cc0001, 0x0201f800,
+	0x00105c9a, 0x0402001e, 0x0201f800, 0x001045a6,
+	0x0402001b, 0x49366009, 0x4a026403, 0x00000087,
+	0x59cc1204, 0x82081580, 0x0000ffff, 0x04020003,
+	0x4a026403, 0x00000086, 0x4a026203, 0x00000001,
+	0x42000800, 0x80000040, 0x0201f800, 0x00020721,
+	0x0401f00d, 0x591c0203, 0x82000580, 0x00000007,
+	0x040207de, 0x4d300000, 0x411e6000, 0x0201f800,
+	0x00107911, 0x5c026000, 0x0401f7d8, 0x0201f800,
+	0x00107911, 0x5c023800, 0x1c01f000, 0x4933c857,
+	0x480bc857, 0x42002800, 0x0010d1c0, 0x41300000,
+	0x80140580, 0x04000017, 0x58140203, 0x82000580,
+	0x00000000, 0x04000013, 0x58140202, 0x80080580,
+	0x04020010, 0x58141c06, 0x820c0580, 0x00000005,
+	0x0400000c, 0x820c0580, 0x00000009, 0x0400001d,
+	0x59302009, 0x58140009, 0x800001c0, 0x0400000b,
+	0x801021c0, 0x04000003, 0x80100580, 0x04000010,
+	0x82142c00, 0x00000024, 0x41540000, 0x80140480,
+	0x0402100e, 0x0401f7e2, 0x5814001e, 0x801021c0,
+	0x04000005, 0x58102002, 0x82102500, 0x00ffffff,
+	0x0401f7f2, 0x5810201e, 0x0401f7f0, 0x40163800,
+	0x81300540, 0x0401f002, 0x80000580, 0x1c01f000,
+	0x58141807, 0x8c0c1d10, 0x040207ea, 0x0401f7e1,
+	0x4933c857, 0x493bc857, 0x83380580, 0x00000013,
+	0x0402000e, 0x59300403, 0x82000c80, 0x00000085,
+	0x02001800, 0x001005d8, 0x82000c80, 0x00000093,
+	0x02021800, 0x001005d8, 0x82000480, 0x00000085,
+	0x4803c857, 0x0c01f018, 0x83380580, 0x00000027,
+	0x04000005, 0x83380580, 0x00000014, 0x02020000,
+	0x00107974, 0x0201f800, 0x00106bbf, 0x59325808,
+	0x812e59c0, 0x02000000, 0x00107911, 0x4a025a06,
+	0x00000031, 0x4a025811, 0x00000004, 0x4a025812,
+	0x000000ff, 0x0201f800, 0x000202da, 0x0201f000,
+	0x00107911, 0x0010a1b7, 0x0010a1be, 0x0010a1be,
+	0x0010a1b7, 0x0010a1b7, 0x0010a1b7, 0x0010a1b7,
+	0x0010a1b7, 0x0010a1b7, 0x0010a1b7, 0x0010a1b7,
+	0x0010a1b7, 0x0010a1b7, 0x0010a1b9, 0x0201f800,
+	0x001005d8, 0x59325808, 0x4a025a06, 0x00000000,
+	0x0201f800, 0x000202da, 0x0201f000, 0x00107911,
+	0x4933c857, 0x42000000, 0x0010b873, 0x0201f800,
+	0x0010aa47, 0x0201f800, 0x0010a5df, 0x497a6205,
+	0x42028000, 0x0000000b, 0x0401f807, 0x4a026406,
+	0x00000006, 0x4a026203, 0x00000007, 0x497a6206,
+	0x1c01f000, 0x4933c857, 0x4943c857, 0x59300406,
+	0x82000580, 0x00000007, 0x04020002, 0x1c01f000,
+	0x0201f800, 0x00106c55, 0x4df00000, 0x0201f800,
+	0x00108ce5, 0x82000c80, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f001, 0x0010a205, 0x0010a209,
+	0x0010a1f0, 0x0010a217, 0x0010a22a, 0x0010a1f0,
+	0x0010a1f0, 0x0010a1f0, 0x0010a1f0, 0x0010a1f0,
+	0x0010a1f0, 0x0010a1f0, 0x0010a1f0, 0x0010a1f0,
+	0x4d400000, 0x5930001f, 0x80000540, 0x04000005,
+	0x41400800, 0x0201f800, 0x00100d7c, 0x40068000,
+	0x4d2c0000, 0x59325808, 0x0201f800, 0x00109037,
+	0x040209f3, 0x4c5c0000, 0x5930b809, 0x0201f800,
+	0x00107911, 0x485e6009, 0x5c00b800, 0x5c025800,
+	0x5c028000, 0x5c03e000, 0x02000000, 0x00106c4b,
+	0x1c01f000, 0x598c000d, 0x81300580, 0x04020004,
+	0x0201f800, 0x00106e8e, 0x04020016, 0x0201f800,
+	0x001068d3, 0x040007df, 0x0201f800, 0x00106b6c,
+	0x04000010, 0x0201f800, 0x001005d8, 0x0201f800,
+	0x00108cd6, 0x04020004, 0x0201f800, 0x00106e62,
+	0x04020008, 0x0201f800, 0x001067ae, 0x040007d1,
+	0x0201f800, 0x00106b6c, 0x02020800, 0x001005d8,
+	0x59300203, 0x82000c80, 0x0000000e, 0x02021800,
+	0x001005d8, 0x0c01f7b9, 0x0201f800, 0x00100e99,
+	0x0401f7c4, 0x4933c857, 0x4d440000, 0x4d340000,
+	0x59cc0007, 0x0201f800, 0x00105c9a, 0x02000800,
+	0x00020245, 0x0402001a, 0x59300009, 0x4c000000,
+	0x49366009, 0x42003000, 0x0000000b, 0x0201f800,
+	0x0010a942, 0x42000000, 0x0010b861, 0x0201f800,
+	0x0010aa47, 0x4d3c0000, 0x4d400000, 0x42028000,
+	0x00000029, 0x417a7800, 0x0201f800, 0x0010203c,
+	0x5c028000, 0x5c027800, 0x5c000000, 0x48026009,
+	0x59cc0007, 0x48026802, 0x80000580, 0x5c026800,
+	0x5c028800, 0x1c01f000, 0x4933c857, 0x4c040000,
+	0x59a80016, 0x82000580, 0x00000074, 0x04020040,
+	0x59cc0a08, 0x82040480, 0x00000100, 0x04001033,
+	0x59cc0c08, 0x82040500, 0x00008000, 0x04000035,
+	0x59a80032, 0x80000540, 0x04020009, 0x59301009,
+	0x58080212, 0x82000500, 0x0000ff00, 0x04000004,
+	0x82040500, 0x00000800, 0x0400002a, 0x59cc0c09,
+	0x80040840, 0x04001024, 0x59a80826, 0x8c040d06,
+	0x04000004, 0x59cc0c0f, 0x8c040d1e, 0x04020012,
+	0x59cc0a17, 0x800409c0, 0x04020012, 0x59cc0a18,
+	0x82040480, 0x00000100, 0x04001014, 0x59cc0c18,
+	0x800409c0, 0x0402000e, 0x59cc0c19, 0x80040840,
+	0x04001011, 0x59cc0c1a, 0x80040840, 0x04001011,
+	0x0401f018, 0x4a02621a, 0x00000100, 0x0401f012,
+	0x4a02621a, 0x00000300, 0x0401f00f, 0x4a02621a,
+	0x00000500, 0x0401f00c, 0x4a02621a, 0x00000700,
+	0x0401f009, 0x4a02621a, 0x00000900, 0x0401f006,
+	0x4a02621a, 0x00000f00, 0x0401f003, 0x4a02621a,
+	0x00002d00, 0x82000540, 0x00000001, 0x0401f002,
+	0x80000580, 0x5c000800, 0x1c01f000, 0x59cc0407,
+	0x4803c857, 0x82000580, 0x00000800, 0x04000003,
+	0x4a02621a, 0x00000000, 0x1c01f000, 0x4933c857,
+	0x4c040000, 0x4c080000, 0x4c0c0000, 0x4c580000,
+	0x59cc000c, 0x0201f800, 0x00105c9a, 0x02000800,
+	0x00020245, 0x04020012, 0x83cc1400, 0x00000008,
+	0x4200b000, 0x00000002, 0x83341c00, 0x00000006,
+	0x0201f800, 0x0010855a, 0x04020009, 0x83cc1400,
+	0x0000000a, 0x4200b000, 0x00000002, 0x83341c00,
+	0x00000008, 0x0201f800, 0x0010855a, 0x5c00b000,
+	0x5c001800, 0x5c001000, 0x5c000800, 0x1c01f000,
+	0x4933c857, 0x4c000000, 0x4c040000, 0x4c080000,
+	0x4c0c0000, 0x4c580000, 0x59cc0001, 0x0201f800,
+	0x00105c9a, 0x02000800, 0x00020245, 0x04020014,
+	0x83cc1400, 0x0000000b, 0x4200b000, 0x00000002,
+	0x83341c00, 0x00000006, 0x0201f800, 0x0010855a,
+	0x0402000c, 0x83cc1400, 0x0000000d, 0x4200b000,
+	0x00000002, 0x83341c00, 0x00000008, 0x0201f800,
+	0x0010855a, 0x04000014, 0x4933c856, 0x4933c856,
+	0x4933c857, 0x59340009, 0x4803c857, 0x5934000e,
+	0x4803c857, 0x59340008, 0x4803c857, 0x5934000d,
+	0x4803c857, 0x59340007, 0x4803c857, 0x5934000c,
+	0x4803c857, 0x59340006, 0x4803c857, 0x5934000b,
+	0x4803c857, 0x5c00b000, 0x5c001800, 0x5c001000,
+	0x5c000800, 0x5c000000, 0x1c01f000, 0x4933c857,
+	0x4947c857, 0x4943c857, 0x4c600000, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x4d2c0000, 0x4d300000,
+	0x4d340000, 0x4130c000, 0x42026000, 0x0010d1c0,
+	0x59a8000e, 0x8060c1c0, 0x04000005, 0x82601580,
+	0x0010bde9, 0x04000002, 0x80000040, 0x81640480,
+	0x040210be, 0x40600000, 0x81300580, 0x040000b6,
+	0x0401f97a, 0x040200b4, 0x59326809, 0x59300406,
+	0x82000c80, 0x00000012, 0x02021800, 0x001005d8,
+	0x0c01f001, 0x0010a3cd, 0x0010a338, 0x0010a351,
+	0x0010a35c, 0x0010a335, 0x0010a34c, 0x0010a387,
+	0x0010a3cd, 0x0010a333, 0x0010a39a, 0x0010a3ae,
+	0x0010a333, 0x0010a333, 0x0010a333, 0x0010a333,
+	0x0010a3cd, 0x0010a3c4, 0x0010a3bc, 0x0201f800,
+	0x001005d8, 0x59300420, 0x8c000500, 0x04020096,
+	0x59300403, 0x82000580, 0x00000043, 0x04000092,
+	0x0201f800, 0x00109134, 0x04000007, 0x0201f800,
+	0x0010914e, 0x0402008a, 0x0201f800, 0x0010801c,
+	0x0401f087, 0x0201f800, 0x00102074, 0x0201f800,
+	0x0010914e, 0x02000800, 0x0010801c, 0x0401f080,
+	0x8d3e7d18, 0x04000004, 0x59300420, 0x8c000500,
+	0x0402007d, 0x59325808, 0x0201f800, 0x00109037,
+	0x04000077, 0x49425a06, 0x497a5c09, 0x0201f800,
+	0x000202da, 0x0201f800, 0x0010912a, 0x0401f070,
+	0x8d3e7d00, 0x04000007, 0x59300017, 0x81480580,
+	0x0402006d, 0x59300018, 0x814c0580, 0x0402006a,
+	0x59300203, 0x82000580, 0x00000004, 0x02000800,
+	0x00100e99, 0x59325808, 0x0201f800, 0x00109037,
+	0x0400005f, 0x4a025a04, 0x00000103, 0x59300004,
+	0x8400055c, 0x48026004, 0x592c0408, 0x8c000512,
+	0x04000007, 0x4d2c0000, 0x592c0009, 0x40025800,
+	0x0201f800, 0x001007fd, 0x5c025800, 0x49425a06,
+	0x497a5c09, 0x0401fb16, 0x0201f800, 0x0010959c,
+	0x0201f800, 0x001091c6, 0x0201f800, 0x000202da,
+	0x0201f800, 0x0010912a, 0x0401f045, 0x8d3e7d18,
+	0x04000045, 0x59300203, 0x82000580, 0x00000004,
+	0x02000800, 0x00100e99, 0x59325808, 0x0201f800,
+	0x00109037, 0x0400003a, 0x49425a06, 0x497a5c09,
+	0x0401faff, 0x0201f800, 0x0010959c, 0x0201f800,
+	0x000202da, 0x0401f032, 0x0201f800, 0x001062d5,
+	0x04000031, 0x59300203, 0x82000580, 0x00000004,
+	0x0400002d, 0x59300203, 0x82000580, 0x00000003,
+	0x04020029, 0x0201f800, 0x00106b8a, 0x59325808,
+	0x0201f800, 0x00109037, 0x04000021, 0x0201f800,
+	0x000202da, 0x0401f01e, 0x59300203, 0x82000580,
+	0x00000004, 0x02000800, 0x00100e99, 0x59325808,
+	0x0201f800, 0x00109037, 0x04000015, 0x49425a06,
+	0x497a5c09, 0x0201f800, 0x000202da, 0x0401f010,
+	0x833c0500, 0x00001800, 0x0400000f, 0x8d3e7d16,
+	0x0402000d, 0x59325817, 0x0201f800, 0x001007fd,
+	0x59325808, 0x0201f800, 0x00109037, 0x04000004,
+	0x49425a06, 0x0201f800, 0x000202da, 0x0201f800,
+	0x00107911, 0x83326400, 0x00000024, 0x41580000,
+	0x81300480, 0x0400173b, 0x5c026800, 0x5c026000,
+	0x5c025800, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x5c00c000, 0x1c01f000, 0x5c000000, 0x4c000000,
+	0x4803c857, 0x4d3c0000, 0x42027800, 0x00000001,
+	0x0201f800, 0x00104567, 0x5c027800, 0x4c580000,
+	0x4200b000, 0x00000002, 0x83a81c00, 0x00000002,
+	0x83cc1400, 0x0000000b, 0x0201f800, 0x0010855a,
+	0x5c00b000, 0x80000540, 0x1c01f000, 0x492fc857,
+	0x4943c857, 0x59a8000c, 0x812c0480, 0x04001011,
+	0x59a8000d, 0x812c0480, 0x0402100e, 0x592c0000,
+	0x80005d40, 0x04000008, 0x497a5800, 0x49425a06,
+	0x4c2c0000, 0x0201f800, 0x000202da, 0x5c025800,
+	0x0401f7f7, 0x49425a06, 0x0201f000, 0x000202da,
+	0x1c01f000, 0x493fc857, 0x4933c857, 0x480bc857,
+	0x0201f800, 0x00103b25, 0x0400002e, 0x41502800,
+	0x813e79c0, 0x04020006, 0x59a80066, 0x80000000,
+	0x59a8086a, 0x80040580, 0x04000026, 0x41300000,
+	0x80140580, 0x0400001a, 0x58140203, 0x82000580,
+	0x00000000, 0x04000016, 0x58140202, 0x80080580,
+	0x04020013, 0x58141c06, 0x820c0580, 0x00000005,
+	0x0400000f, 0x820c0580, 0x00000009, 0x04000017,
+	0x59300009, 0x58142009, 0x801021c0, 0x04020006,
+	0x5814201e, 0x59301809, 0x580c0002, 0x82000500,
+	0x00ffffff, 0x80100580, 0x04000007, 0x82142c00,
+	0x00000024, 0x41540000, 0x80140480, 0x04021005,
+	0x0401f7df, 0x40163800, 0x81300540, 0x0401f002,
+	0x80000580, 0x1c01f000, 0x58141807, 0x8c0c1d10,
+	0x040207f3, 0x0401f7e7, 0x42002000, 0x0000ffff,
+	0x59301009, 0x800811c0, 0x04000002, 0x58082403,
+	0x41301000, 0x0401f007, 0x41781000, 0x41442000,
+	0x0401f004, 0x41781000, 0x42002000, 0x0000ffff,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x480bc857,
+	0x4813c857, 0x492fc857, 0x4943c857, 0x4d2c0000,
+	0x0201f800, 0x001007e4, 0x02000800, 0x001005d8,
+	0x4a025a04, 0x0000010d, 0x800811c0, 0x04000017,
+	0x83400580, 0x00000029, 0x04020010, 0x82180580,
+	0x00000002, 0x0400000a, 0x82180580, 0x00000003,
+	0x04000007, 0x82180580, 0x00000008, 0x04000004,
+	0x82180580, 0x00000009, 0x04020004, 0x4a025809,
+	0xffffffff, 0x0401f002, 0x480a5809, 0x58080202,
+	0x48025c13, 0x0401f005, 0x4a025809, 0xffffffff,
+	0x4a025c13, 0x0000ffff, 0x49425a08, 0x48125a06,
+	0x82100580, 0x0000ffff, 0x0400000e, 0x4d440000,
+	0x4d340000, 0x40128800, 0x0201f800, 0x00020245,
+	0x02020800, 0x001005d8, 0x59340002, 0x82000500,
+	0x00ffffff, 0x48025812, 0x5c026800, 0x5c028800,
+	0x497a5800, 0x497a5c04, 0x83400580, 0x00000046,
+	0x04020002, 0x48165a07, 0x481a5c08, 0x0401fbed,
+	0x5c025800, 0x1c01f000, 0x59300809, 0x800409c0,
+	0x04000004, 0x58040403, 0x81440580, 0x1c01f000,
+	0x82000540, 0x00000001, 0x0401f7fd, 0x4933c857,
+	0x4c040000, 0x59300403, 0x82000d80, 0x0000001e,
+	0x04020016, 0x800000d0, 0x59300a16, 0x82040d00,
+	0x000000ff, 0x80040540, 0x4803c857, 0x48026416,
+	0x4a026403, 0x00000085, 0x4a026203, 0x00000009,
+	0x4a026406, 0x00000005, 0x4a02621d, 0x00000004,
+	0x59a80038, 0x48026206, 0x42000800, 0x8000004b,
+	0x0201f800, 0x00020721, 0x5c000800, 0x1c01f000,
+	0x4933c857, 0x40000000, 0x40000000, 0x1c01f000,
+	0x59300414, 0x4933c857, 0x4803c857, 0x8c000518,
+	0x04000009, 0x8c000512, 0x02020000, 0x0010921e,
+	0x0401f91b, 0x0201f800, 0x000206fd, 0x0201f800,
+	0x0002077d, 0x1c01f000, 0x591c0406, 0x4803c857,
+	0x82000c80, 0x00000009, 0x0402100b, 0x0c01f001,
+	0x0010a4d9, 0x0010a4d9, 0x0010a4d9, 0x0010a4db,
+	0x0010a4d9, 0x0010a4db, 0x0010a4db, 0x0010a4d9,
+	0x0010a4db, 0x80000580, 0x1c01f000, 0x82000540,
+	0x00000001, 0x1c01f000, 0x591c0406, 0x82000500,
+	0x0000001f, 0x82000580, 0x00000006, 0x0400000e,
+	0x4803c857, 0x4a026403, 0x0000003b, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00002a00, 0x4a026203,
+	0x00000001, 0x42000800, 0x80000040, 0x0201f000,
+	0x00020721, 0x4803c856, 0x4c040000, 0x4c140000,
+	0x4d300000, 0x411e6000, 0x0401f8e9, 0x497a6205,
+	0x59300414, 0x4803c857, 0x82000500, 0xffffadff,
+	0x48026414, 0x497a6405, 0x5c026000, 0x0201f800,
+	0x001007e4, 0x02000800, 0x001005d8, 0x5c002800,
+	0x5c000800, 0x4a025a04, 0x0000010d, 0x497a5800,
+	0x497a5c04, 0x4a025a08, 0x00000045, 0x491e5809,
+	0x59300402, 0x48025c07, 0x59300419, 0x48025c0b,
+	0x591c0414, 0x84000556, 0x48023c14, 0x591c1809,
+	0x580c0403, 0x48025a06, 0x4816580a, 0x48065a0b,
+	0x0401f99d, 0x4d400000, 0x42028000, 0x00000045,
+	0x591c0202, 0x4c000000, 0x4d300000, 0x411e6000,
+	0x0401fcb1, 0x5c026000, 0x5c000000, 0x48023a02,
+	0x5c028000, 0x4a023c06, 0x00000006, 0x4a023a03,
+	0x00000007, 0x497a3a06, 0x497a3a05, 0x1c01f000,
+	0x4933c857, 0x83380580, 0x00000013, 0x0402000b,
+	0x59300403, 0x4803c857, 0x82000d80, 0x00000085,
+	0x0400002b, 0x82000d80, 0x0000008b, 0x04000028,
+	0x0201f800, 0x001005d8, 0x83380580, 0x00000027,
+	0x0402000c, 0x0201f800, 0x00106bbf, 0x4d2c0000,
+	0x4d400000, 0x59325808, 0x42028000, 0x00000004,
+	0x0401feab, 0x5c028000, 0x5c025800, 0x1c01f000,
+	0x83380580, 0x00000014, 0x040007f3, 0x83380580,
+	0x00000089, 0x04000005, 0x83380580, 0x0000008a,
+	0x02020000, 0x00107974, 0x0201f800, 0x00106f60,
+	0x02020000, 0x00107974, 0x59300a03, 0x82040580,
+	0x0000000a, 0x04000009, 0x82040580, 0x0000000c,
+	0x04000006, 0x0201f800, 0x001005d8, 0x4a026203,
+	0x0000000a, 0x1c01f000, 0x83380480, 0x00000093,
+	0x0402100c, 0x83380480, 0x00000085, 0x04001009,
+	0x83380580, 0x00000089, 0x0400000a, 0x83380580,
+	0x0000008a, 0x04000022, 0x0201f800, 0x001005d8,
+	0x493bc857, 0x4933c857, 0x0201f000, 0x00107974,
+	0x4933c857, 0x4c340000, 0x41306800, 0x0201f800,
+	0x0002075a, 0x04000011, 0x4a026203, 0x00000001,
+	0x4a026403, 0x0000001e, 0x59cc0c07, 0x48066419,
+	0x59cc0a07, 0x48066219, 0x58340809, 0x48066009,
+	0x4a026406, 0x00000004, 0x42000800, 0x80000040,
+	0x0201f800, 0x00020721, 0x40366000, 0x0201f800,
+	0x0002077d, 0x5c006800, 0x1c01f000, 0x4933c857,
+	0x0201f000, 0x0002077d, 0x4933c857, 0x59300809,
+	0x58040200, 0x8c00051a, 0x1c01f000, 0x0201f800,
+	0x001048df, 0x0400001e, 0x4a026203, 0x00000002,
+	0x59300414, 0x84000558, 0x48026414, 0x8c000512,
+	0x04000004, 0x59a80039, 0x48026205, 0x0401f007,
+	0x59a80839, 0x59a80037, 0x80040400, 0x82000400,
+	0x0000000a, 0x48026205, 0x59300009, 0x82000c00,
+	0x00000011, 0x50040000, 0x80000540, 0x04000004,
+	0x82000c00, 0x00000000, 0x0401f7fb, 0x45300800,
+	0x497a6000, 0x82000540, 0x00000001, 0x1c01f000,
+	0x82100500, 0xfffffeef, 0x04020020, 0x4d2c0000,
+	0x4937c857, 0x59340811, 0x83341400, 0x00000011,
+	0x800409c0, 0x0400000e, 0x40040000, 0x81300580,
+	0x04000005, 0x58040800, 0x82041400, 0x00000000,
+	0x0401f7f8, 0x59300800, 0x497a6000, 0x44041000,
+	0x0201f800, 0x000206fd, 0x0401f002, 0x4933c857,
+	0x592c0000, 0x80000540, 0x02020800, 0x001005d8,
+	0x5c025800, 0x492e6008, 0x0201f800, 0x000206fd,
+	0x0201f000, 0x0002077d, 0x492fc857, 0x4a025a06,
+	0x00000006, 0x0201f000, 0x000202da, 0x4c340000,
+	0x59300009, 0x800001c0, 0x04000010, 0x82006c00,
+	0x00000011, 0x50340000, 0x80000540, 0x04000009,
+	0x81300580, 0x04000005, 0x50340000, 0x82006c00,
+	0x00000000, 0x0401f7f8, 0x59300000, 0x44006800,
+	0x5c006800, 0x1c01f000, 0x59300c06, 0x82040580,
+	0x00000005, 0x040007fb, 0x82040580, 0x00000011,
+	0x040007f8, 0x82040580, 0x00000006, 0x040007f5,
+	0x82040580, 0x00000001, 0x040007f2, 0x0201f800,
+	0x001005d8, 0x4933c857, 0x4c080000, 0x4c0c0000,
+	0x4c580000, 0x59a8101d, 0x59cc1807, 0x820c1d00,
+	0x00ffffff, 0x800c0110, 0x80083580, 0x04020014,
+	0x83cc1400, 0x00000008, 0x4200b000, 0x00000002,
+	0x59300009, 0x82001c00, 0x00000006, 0x0201f800,
+	0x0010855a, 0x0402000a, 0x83cc1400, 0x0000000a,
+	0x4200b000, 0x00000002, 0x59300009, 0x82001c00,
+	0x00000008, 0x0201f800, 0x0010855a, 0x5c00b000,
+	0x5c001800, 0x5c001000, 0x1c01f000, 0x4933c856,
+	0x0201f800, 0x0010421b, 0x0201f000, 0x00101e45,
+	0x493bc857, 0x4d2c0000, 0x0201f800, 0x001007e4,
+	0x02000800, 0x001005d8, 0x832cac00, 0x00000005,
+	0x4c580000, 0x4c540000, 0x4200b000, 0x00000006,
+	0x4578a800, 0x8054a800, 0x8058b040, 0x040207fd,
+	0x83380580, 0x00000046, 0x04020004, 0x4a025a04,
+	0x00000144, 0x0401f008, 0x4a025a04, 0x00000146,
+	0x83380580, 0x00000041, 0x04000003, 0x4a025a06,
+	0x00000001, 0x59cc0007, 0x82000500, 0xff000000,
+	0x80000110, 0x59cc1008, 0x82081500, 0xff000000,
+	0x80081540, 0x480a580a, 0x83380580, 0x00000046,
+	0x04020006, 0x59cc0007, 0x82000500, 0x00ffffff,
+	0x4802580b, 0x0401f005, 0x59cc0008, 0x82000500,
+	0x00ffffff, 0x4802580b, 0x83380580, 0x00000046,
+	0x04020004, 0x83cc1400, 0x00000009, 0x0401f003,
+	0x83cc1400, 0x0000000d, 0x50080000, 0x9c0001c0,
+	0x4802580c, 0x80081000, 0x50080000, 0x9c0001c0,
+	0x4802580d, 0x83380580, 0x00000046, 0x04020008,
+	0x59cc000b, 0x9c0001c0, 0x4802580e, 0x59cc000c,
+	0x9c0001c0, 0x4802580f, 0x0401f007, 0x59cc000f,
+	0x9c0001c0, 0x4802580e, 0x59cc0010, 0x9c0001c0,
+	0x4802580f, 0x83380580, 0x00000046, 0x04020004,
+	0x83cc1400, 0x00000011, 0x0401f003, 0x83cc1400,
+	0x00000015, 0x412c3000, 0x82183400, 0x00000010,
+	0x4200b000, 0x00000004, 0x50080000, 0x9c0001c0,
+	0x44003000, 0x80081000, 0x80183000, 0x8058b040,
+	0x040207fa, 0x5c00a800, 0x5c00b000, 0x0201f800,
+	0x000202da, 0x5c025800, 0x1c01f000, 0x4933c857,
+	0x492fc857, 0x59300809, 0x58040200, 0x8c00051e,
+	0x04000004, 0x592c0208, 0x84000558, 0x48025a08,
+	0x1c01f000, 0x59e0180f, 0x599c0413, 0x800c1000,
+	0x80080580, 0x04020002, 0x41781000, 0x59e00010,
+	0x59e00810, 0x80040d80, 0x040207fd, 0x80080580,
+	0x0400000b, 0x4c080000, 0x599c0814, 0x599c1015,
+	0x800c00cc, 0x80040c00, 0x82081440, 0x00000000,
+	0x5c001800, 0x82000540, 0x00000001, 0x4803c857,
+	0x1c01f000, 0x492fc857, 0x42007000, 0x0010b7f8,
+	0x58380807, 0x800409c0, 0x04020005, 0x492c7008,
+	0x492c7007, 0x0201f000, 0x00100875, 0x492c0800,
+	0x492c7007, 0x1c01f000, 0x59300203, 0x4933c857,
+	0x4937c857, 0x493bc857, 0x4803c857, 0x82003480,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f001,
+	0x0010a6da, 0x0010a82c, 0x0010a6da, 0x0010a6da,
+	0x0010a6da, 0x0010a6da, 0x0010a6da, 0x0010a791,
+	0x0010a6dc, 0x0010a6da, 0x0010a6da, 0x0010a6da,
+	0x0010a6da, 0x0010a6da, 0x0201f800, 0x001005d8,
+	0x83380580, 0x0000004c, 0x02020800, 0x001005d8,
+	0x0201f800, 0x001048ec, 0x04020020, 0x59a80826,
+	0x82040500, 0x00000009, 0x82000580, 0x00000008,
+	0x0400001a, 0x8c040d12, 0x0400003d, 0x59cc0806,
+	0x82040d00, 0xff000000, 0x82040580, 0x03000000,
+	0x0400001f, 0x82040580, 0x50000000, 0x04000005,
+	0x82040580, 0x52000000, 0x02020000, 0x0002077d,
+	0x813669c0, 0x04000006, 0x4d3c0000, 0x417a7800,
+	0x0201f800, 0x0010203c, 0x5c027800, 0x4a026403,
+	0x00000001, 0x0401f014, 0x59cc0806, 0x82040d00,
+	0xff000000, 0x82040580, 0x03000000, 0x04000008,
+	0x82040580, 0x50000000, 0x04000005, 0x82040580,
+	0x52000000, 0x02020000, 0x0002077d, 0x4a026403,
+	0x00000009, 0x4a02641a, 0x00000009, 0x4a02621a,
+	0x00000000, 0x813669c0, 0x0402000b, 0x59cc0001,
+	0x0201f800, 0x00105c9a, 0x02020000, 0x0002077d,
+	0x0201f800, 0x001045a6, 0x02020000, 0x0002077d,
+	0x49366009, 0x4a026406, 0x00000004, 0x4a026203,
+	0x00000001, 0x0201f000, 0x0010672b, 0x0201f800,
+	0x00103b25, 0x04000023, 0x59cc0806, 0x4807c857,
+	0x82040d00, 0xff000000, 0x82040580, 0x03000000,
+	0x04000033, 0x82040580, 0x20000000, 0x04000041,
+	0x82040580, 0x21000000, 0x04000052, 0x82040580,
+	0x24000000, 0x0400004f, 0x82040580, 0x50000000,
+	0x0400004c, 0x82040580, 0x52000000, 0x04000049,
+	0x82040580, 0x05000000, 0x0402000d, 0x59cc0806,
+	0x82040d00, 0xff000000, 0x9c0431c0, 0x42028000,
+	0x00000046, 0x42002800, 0x00000001, 0x0401fcf3,
+	0x0401f93c, 0x02000800, 0x001005d8, 0x42002000,
+	0x00000051, 0x0201f800, 0x00107a4a, 0x59cc0000,
+	0x82000500, 0x00ffffff, 0x82000580, 0x00ffffff,
+	0x04000005, 0x4a026203, 0x00000007, 0x493a6403,
+	0x1c01f000, 0x59325817, 0x812e59c0, 0x02020800,
+	0x001007fd, 0x0201f000, 0x0002077d, 0x813669c0,
+	0x040007df, 0x59340400, 0x82000500, 0x000000ff,
+	0x82000580, 0x00000003, 0x040207d9, 0x0401fc6f,
+	0x040207d7, 0x4a026403, 0x00000009, 0x4a02641a,
+	0x0000000e, 0x4a02621a, 0x00001900, 0x0401f7a2,
+	0x813669c0, 0x0400000c, 0x59340c00, 0x82040500,
+	0x000000ff, 0x82000580, 0x00000009, 0x04000794,
+	0x82040500, 0x0000ff00, 0x82000580, 0x00000700,
+	0x040207c3, 0x4a026403, 0x00000009, 0x4a02641a,
+	0x00000009, 0x4a02621a, 0x00001e00, 0x0401f78e,
+	0x813669c0, 0x040007f8, 0x59340c00, 0x82040500,
+	0x0000ff00, 0x82000580, 0x00000700, 0x040007f2,
+	0x0401f7b3, 0x4d2c0000, 0x4c580000, 0x4c500000,
+	0x4c540000, 0x41385000, 0x83380580, 0x00000054,
+	0x02020800, 0x001005d8, 0x59325808, 0x592c0c0b,
+	0x82040d00, 0x0000e000, 0x82040580, 0x00002000,
+	0x04020076, 0x59300817, 0x800409c0, 0x04000014,
+	0x58041404, 0x41cca800, 0x8204a400, 0x00000005,
+	0x82080480, 0x00000010, 0x04021004, 0x4008b000,
+	0x0401fb6b, 0x0401f00a, 0x40001000, 0x4200b000,
+	0x0000000f, 0x0401fb66, 0x58040801, 0x800409c0,
+	0x040207f2, 0x0201f800, 0x001005d8, 0x813669c0,
+	0x0400005e, 0x59344c00, 0x592c0c09, 0x4807c857,
+	0x4827c857, 0x82040d00, 0x000000ff, 0x82040580,
+	0x00000003, 0x0400002a, 0x82040580, 0x00000005,
+	0x04000032, 0x82040580, 0x00000020, 0x04000036,
+	0x82040580, 0x00000052, 0x04000042, 0x82040580,
+	0x00000050, 0x04000042, 0x82040580, 0x00000021,
+	0x04000004, 0x82040580, 0x00000024, 0x04020043,
+	0x82240500, 0x0000ff00, 0x82000580, 0x00000007,
+	0x04000008, 0x42000800, 0x00000009, 0x0201f800,
+	0x00104571, 0x42005000, 0x0000000c, 0x0401f037,
+	0x4a025a06, 0x00000031, 0x4a02580d, 0x00000009,
+	0x59340400, 0x4802580e, 0x0201f800, 0x000202da,
+	0x0201f800, 0x00107911, 0x0401f03d, 0x0201f800,
+	0x001042b4, 0x0201f800, 0x0010462a, 0x42000800,
+	0x00000003, 0x0201f800, 0x00104571, 0x42005000,
+	0x00000008, 0x0401f021, 0x59cc0007, 0x0201f800,
+	0x00105eec, 0x0402001d, 0x0201f800, 0x001042b4,
+	0x0401f01a, 0x82240500, 0x0000ff00, 0x82000580,
+	0x00000007, 0x040007df, 0x82240500, 0x000000ff,
+	0x82000580, 0x00000009, 0x040007da, 0x0201f800,
+	0x0010468d, 0x42005000, 0x0000000a, 0x0401f00b,
+	0x42005000, 0x0000000e, 0x0401f003, 0x42005000,
+	0x00000010, 0x82240500, 0x0000ff00, 0x82000580,
+	0x00000007, 0x040007cb, 0x482a6403, 0x4a026203,
+	0x00000001, 0x592c000d, 0x48026011, 0x497a6013,
+	0x59a80038, 0x48026206, 0x417a7800, 0x0201f800,
+	0x0010672b, 0x59325817, 0x812e59c0, 0x04000004,
+	0x0201f800, 0x001007fd, 0x497a6017, 0x5c00a800,
+	0x5c00a000, 0x5c00b000, 0x5c025800, 0x1c01f000,
+	0x4d2c0000, 0x59325808, 0x83380580, 0x00000013,
+	0x04020029, 0x59300c03, 0x82040580, 0x00000054,
+	0x0400001e, 0x82040580, 0x00000010, 0x04000018,
+	0x82040580, 0x0000000e, 0x04000015, 0x82040580,
+	0x00000008, 0x0400000d, 0x82040580, 0x0000000c,
+	0x0400000a, 0x82040580, 0x0000000a, 0x02020800,
+	0x001005d8, 0x42000800, 0x00000006, 0x0201f800,
+	0x00104571, 0x0401f009, 0x42000800, 0x00000004,
+	0x0201f800, 0x00104571, 0x0401f004, 0x59340200,
+	0x8400051a, 0x48026a00, 0x4a025a06, 0x00000000,
+	0x0201f800, 0x000202da, 0x0201f800, 0x0002077d,
+	0x0401f022, 0x83380580, 0x00000027, 0x0400000e,
+	0x83380580, 0x00000014, 0x02020800, 0x001005d8,
+	0x0201f800, 0x00106bbf, 0x42028000, 0x00000031,
+	0x42000800, 0x00000004, 0x42001000, 0x000000ff,
+	0x0401f009, 0x0201f800, 0x00106bbf, 0x42028000,
+	0x00000031, 0x42000800, 0x00000004, 0x42001000,
+	0x00000010, 0x49425a06, 0x4806580d, 0x480a580e,
+	0x0201f800, 0x000202da, 0x0201f800, 0x00104c19,
+	0x0201f800, 0x00107911, 0x5c025800, 0x1c01f000,
+	0x42007000, 0x0010b7f8, 0x58380807, 0x800409c0,
+	0x04020005, 0x492c7008, 0x492c7007, 0x0201f000,
+	0x00100875, 0x492c0800, 0x492c7007, 0x1c01f000,
+	0x4d2c0000, 0x4c580000, 0x4c500000, 0x4c540000,
+	0x4933c857, 0x4937c857, 0x59cc0806, 0x4807c857,
+	0x82040d00, 0xff000000, 0x82040580, 0x03000000,
+	0x0400000d, 0x82040580, 0x05000000, 0x0400000a,
+	0x82040580, 0x21000000, 0x04000030, 0x82040580,
+	0x24000000, 0x0400002d, 0x82040580, 0x20000000,
+	0x0402002f, 0x0201f800, 0x001007e4, 0x0400002c,
+	0x492fc857, 0x492e6017, 0x59a8b016, 0x8258b400,
+	0x0000001b, 0x8258b500, 0xfffffffc, 0x8058b104,
+	0x485a5c04, 0x412c7800, 0x41cca000, 0x82580480,
+	0x00000010, 0x04021005, 0x832cac00, 0x00000005,
+	0x0401fa63, 0x0401f015, 0x40580800, 0x4200b000,
+	0x0000000f, 0x832cac00, 0x00000005, 0x0401fa5c,
+	0x8204b480, 0x0000000f, 0x0201f800, 0x001007e4,
+	0x04000004, 0x492c7801, 0x412c7800, 0x0401f7ec,
+	0x59325817, 0x0201f800, 0x001007fd, 0x497a6017,
+	0x80000580, 0x0401f006, 0x59340200, 0x84000554,
+	0x48026a00, 0x82000540, 0x00000001, 0x5c00a800,
+	0x5c00a000, 0x5c00b000, 0x5c025800, 0x1c01f000,
+	0x4933c857, 0x492fc857, 0x4d2c0000, 0x59300a03,
+	0x82040580, 0x00000007, 0x04000036, 0x82040580,
+	0x00000001, 0x02020800, 0x001005d8, 0x0201f800,
+	0x00106c55, 0x4df00000, 0x598c000d, 0x81300580,
+	0x04020016, 0x59300004, 0x8c000520, 0x04000004,
+	0x84000520, 0x48026004, 0x0401f016, 0x42001000,
+	0x0010b7f6, 0x50081000, 0x58080002, 0x82000580,
+	0x00000100, 0x04000006, 0x5808000c, 0x81300580,
+	0x02020800, 0x001005d8, 0x0401f00a, 0x0201f800,
+	0x00106e8e, 0x04020020, 0x59300004, 0x8c000520,
+	0x04000004, 0x84000520, 0x48026004, 0x0401f003,
+	0x0201f800, 0x001068d3, 0x5c03e000, 0x02000800,
+	0x00106c4b, 0x0201f800, 0x00109037, 0x02000800,
+	0x001005d8, 0x59325808, 0x4a025a06, 0x00000005,
+	0x0201f800, 0x000202da, 0x0201f800, 0x00104c19,
+	0x59325817, 0x812e59c0, 0x02020800, 0x001007fd,
+	0x0201f800, 0x00107911, 0x80000580, 0x5c025800,
+	0x1c01f000, 0x5c03e000, 0x02000800, 0x00106c4b,
+	0x59300406, 0x82000580, 0x00000011, 0x040007b8,
+	0x0401f7f7, 0x4c040000, 0x59340200, 0x4803c857,
+	0x8c00051c, 0x04000009, 0x59cc0805, 0x591c0019,
+	0x4803c857, 0x80040580, 0x04000004, 0x80000580,
+	0x4803c856, 0x0401f003, 0x82000540, 0x00000001,
+	0x5c000800, 0x1c01f000, 0x4c000000, 0x4c0c0000,
+	0x4c100000, 0x42001800, 0x0000ffff, 0x42002000,
+	0x00000004, 0x0401f010, 0x4c000000, 0x4c0c0000,
+	0x4c100000, 0x59302009, 0x58101c03, 0x42002000,
+	0x00000004, 0x0401f008, 0x4c000000, 0x4c0c0000,
+	0x4c100000, 0x59302009, 0x58101c03, 0x42002000,
+	0x00000007, 0x480fc857, 0x4813c857, 0x481bc857,
+	0x0201f800, 0x00103aae, 0x5c002000, 0x5c001800,
+	0x5c000000, 0x1c01f000, 0x83380580, 0x00000092,
+	0x02020800, 0x001005d8, 0x42000800, 0x80000040,
+	0x4a026203, 0x00000001, 0x493a6403, 0x0201f000,
+	0x00020721, 0x4d400000, 0x0201f800, 0x00103b25,
+	0x04000008, 0x59a80005, 0x84000544, 0x48035005,
+	0x42028000, 0x0000002a, 0x0201f800, 0x0010a449,
+	0x5c028000, 0x1c01f000, 0x59a80026, 0x8c000508,
+	0x04000005, 0x599c0017, 0x8c00050a, 0x04020002,
+	0x1c01f000, 0x82000540, 0x00000001, 0x1c01f000,
+	0x59300420, 0x84000540, 0x48026420, 0x1c01f000,
+	0x4817c857, 0x4c000000, 0x4c040000, 0x8c142d2a,
+	0x04000004, 0x598800b8, 0x80000000, 0x480310b8,
+	0x8c142d2e, 0x04000004, 0x598800b9, 0x80000000,
+	0x480310b9, 0x8c142d2c, 0x04000013, 0x40140000,
+	0x82000500, 0x00070000, 0x82000d80, 0x00030000,
+	0x0400000d, 0x82000d80, 0x00040000, 0x0400000a,
+	0x82000d80, 0x00050000, 0x04000007, 0x59880005,
+	0x80000000, 0x48031005, 0x598800ba, 0x80000000,
+	0x480310ba, 0x5c000800, 0x5c000000, 0x1c01f000,
+	0x4817c857, 0x4c000000, 0x4c040000, 0x8c142d2a,
+	0x04000004, 0x598800bb, 0x80000000, 0x480310bb,
+	0x8c142d2e, 0x04000004, 0x598800bc, 0x80000000,
+	0x480310bc, 0x8c142d2c, 0x04000013, 0x40140000,
+	0x82000500, 0x00070000, 0x82000d80, 0x00030000,
+	0x0400000d, 0x82000d80, 0x00040000, 0x0400000a,
+	0x82000d80, 0x00050000, 0x04000007, 0x59880005,
+	0x80000000, 0x48031005, 0x598800bd, 0x80000000,
+	0x480310bd, 0x5c000800, 0x5c000000, 0x1c01f000,
+	0x4c000000, 0x59880001, 0x80000000, 0x4803c857,
+	0x48031001, 0x5c000000, 0x1c01f000, 0x4c000000,
+	0x59880000, 0x80000000, 0x4803c857, 0x48031000,
+	0x5c000000, 0x1c01f000, 0x4c000000, 0x59880002,
+	0x80000000, 0x4803c857, 0x48031002, 0x5c000000,
+	0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d2c,
+	0x04000004, 0x598800a6, 0x80000000, 0x480310a6,
+	0x8c040d2a, 0x04000004, 0x598800a7, 0x80000000,
+	0x480310a7, 0x8c040d28, 0x04000004, 0x598800a8,
+	0x80000000, 0x480310a8, 0x8c040d26, 0x04000004,
+	0x598800a9, 0x80000000, 0x480310a9, 0x8c040d24,
+	0x04000004, 0x598800aa, 0x80000000, 0x480310aa,
+	0x8c040d22, 0x04000004, 0x598800ab, 0x80000000,
+	0x480310ab, 0x8c040d20, 0x04000004, 0x598800ac,
+	0x80000000, 0x480310ac, 0x5c000000, 0x1c01f000,
+	0x4807c857, 0x4c000000, 0x598800ad, 0x80000000,
+	0x480310ad, 0x5c000000, 0x1c01f000, 0x4807c857,
+	0x4c000000, 0x8c040d1c, 0x04000004, 0x598800ae,
+	0x80000000, 0x480310ae, 0x8c040d1a, 0x04000004,
+	0x598800af, 0x80000000, 0x480310af, 0x5c000000,
+	0x1c01f000, 0x4807c857, 0x4c000000, 0x8c040d18,
+	0x04000004, 0x598800b0, 0x80000000, 0x480310b0,
+	0x8c040d16, 0x04000004, 0x598800b1, 0x80000000,
+	0x480310b1, 0x8c040d14, 0x04000004, 0x598800b2,
+	0x80000000, 0x480310b2, 0x5c000000, 0x1c01f000,
+	0x4807c857, 0x4c000000, 0x8c040d10, 0x04000004,
+	0x598800b3, 0x80000000, 0x480310b3, 0x8c040d0c,
+	0x04000004, 0x598800b4, 0x80000000, 0x480310b4,
+	0x5c000000, 0x1c01f000, 0x4807c857, 0x4c000000,
+	0x8c040d08, 0x04000004, 0x598800b5, 0x80000000,
+	0x480310b5, 0x8c040d04, 0x04000004, 0x598800b6,
+	0x80000000, 0x480310b6, 0x5c000000, 0x1c01f000,
+	0x4807c856, 0x4c000000, 0x5988007f, 0x80000000,
+	0x4803107f, 0x5c000000, 0x1c01f000, 0x4803c857,
+	0x4c040000, 0x50000800, 0x80040800, 0x4807c857,
+	0x44040000, 0x5c000800, 0x1c01f000, 0x480fc857,
+	0x4c000000, 0x820c0580, 0x00000000, 0x04020004,
+	0x42000000, 0x0010b819, 0x0401f014, 0x820c0580,
+	0x00001001, 0x04020004, 0x42000000, 0x0010b81a,
+	0x0401f00e, 0x820c0580, 0x00001002, 0x04020004,
+	0x42000000, 0x0010b81b, 0x0401f008, 0x820c0c80,
+	0x0000201c, 0x02021800, 0x001005d8, 0x820c0500,
+	0x0000001f, 0x0c01f804, 0x0401ffdd, 0x5c000000,
+	0x1c01f000, 0x0010aa89, 0x0010aa8c, 0x0010aa8f,
+	0x0010aa92, 0x0010aa95, 0x0010aa98, 0x0010aa9b,
+	0x0010aa9e, 0x0010aaa1, 0x0010aaa4, 0x0010aaa7,
+	0x0010aaaa, 0x0010aaad, 0x0010aab0, 0x0010aab3,
+	0x0010aab6, 0x0010aab9, 0x0010aabc, 0x0010aabf,
+	0x0010aac2, 0x0010aac5, 0x0010aac8, 0x0010aacb,
+	0x0010aace, 0x0010aad1, 0x0010aad4, 0x0010aad7,
+	0x0010aada, 0x42000000, 0x0010b81c, 0x1c01f000,
+	0x42000000, 0x0010b81d, 0x1c01f000, 0x42000000,
+	0x0010b81e, 0x1c01f000, 0x42000000, 0x0010b81f,
+	0x1c01f000, 0x42000000, 0x0010b820, 0x1c01f000,
+	0x42000000, 0x0010b821, 0x1c01f000, 0x42000000,
+	0x0010b822, 0x1c01f000, 0x42000000, 0x0010b823,
+	0x1c01f000, 0x42000000, 0x0010b824, 0x1c01f000,
+	0x42000000, 0x0010b825, 0x1c01f000, 0x42000000,
+	0x0010b826, 0x1c01f000, 0x42000000, 0x0010b827,
+	0x1c01f000, 0x42000000, 0x0010b828, 0x1c01f000,
+	0x42000000, 0x0010b829, 0x1c01f000, 0x42000000,
+	0x0010b82a, 0x1c01f000, 0x42000000, 0x0010b82b,
+	0x1c01f000, 0x42000000, 0x0010b82c, 0x1c01f000,
+	0x42000000, 0x0010b82d, 0x1c01f000, 0x42000000,
+	0x0010b82e, 0x1c01f000, 0x42000000, 0x0010b82f,
+	0x1c01f000, 0x42000000, 0x0010b830, 0x1c01f000,
+	0x42000000, 0x0010b831, 0x1c01f000, 0x42000000,
+	0x0010b832, 0x1c01f000, 0x42000000, 0x0010b833,
+	0x1c01f000, 0x42000000, 0x0010b834, 0x1c01f000,
+	0x42000000, 0x0010b835, 0x1c01f000, 0x42000000,
+	0x0010b836, 0x1c01f000, 0x42000000, 0x0010b837,
+	0x1c01f000, 0x480fc857, 0x4c000000, 0x820c0580,
+	0x00000001, 0x04020004, 0x42000000, 0x0010b80e,
+	0x0401f012, 0x820c0580, 0x00000002, 0x04020004,
+	0x42000000, 0x0010b80f, 0x0401f00c, 0x820c0580,
+	0x00000003, 0x04020004, 0x42000000, 0x0010b810,
+	0x0401f006, 0x820c0580, 0x00000004, 0x04020004,
+	0x42000000, 0x0010b811, 0x0401ff51, 0x5c000000,
+	0x1c01f000, 0x4c000000, 0x59a80026, 0x4803c857,
+	0x8c000502, 0x04000010, 0x8c000506, 0x04000004,
+	0x42000000, 0x0010b841, 0x0401f012, 0x8c00050a,
+	0x04000004, 0x42000000, 0x0010b840, 0x0401f00d,
+	0x8c000508, 0x04000004, 0x42000000, 0x0010b843,
+	0x0401f008, 0x0201f800, 0x0010513b, 0x04000006,
+	0x8c000506, 0x04020004, 0x42000000, 0x0010b842,
+	0x0401ff33, 0x5c000000, 0x1c01f000, 0x8058b1c0,
+	0x02000800, 0x001005d8, 0x5450a800, 0x8050a000,
+	0x8054a800, 0x8058b040, 0x040207fc, 0x1c01f000,
+	0x8058b1c0, 0x02000800, 0x001005d8, 0x4450a800,
+	0x8054a800, 0x8058b040, 0x040207fd, 0x1c01f000,
+	0x8058b1c0, 0x02000800, 0x001005d8, 0x50500000,
+	0x9c0001c0, 0x4400a800, 0x8050a000, 0x8054a800,
+	0x8058b040, 0x040207fa, 0x1c01f000, 0x4c000000,
+	0x59a80008, 0x8c00051c, 0x5c000000, 0x1c01f000,
+	0x00000001, 0x00000002, 0x00000004, 0x00000008,
+	0x00000010, 0x00000020, 0x00000040, 0x00000080,
+	0x00000100, 0x00000200, 0x00000400, 0x00000800,
+	0x00001000, 0x00002000, 0x00004000, 0x00008000,
+	0x00010000, 0xa5f2b3ac
+};
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_length01 = 0x0000ab4a ;
+#else
+uint32_t risc_code_length01 = 0x0000ab4a ;
+#endif
+
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_addr02 = 0x0010e000  ;
+#else
+uint32_t risc_code_addr02 = 0x0010e000 ;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_code02[] = {
+#else
+uint32_t risc_code02[] = {
+#endif
+	0x00000000, 0x00000000, 0x0010e000, 0x000014ff,
+	0x00000000, 0x00000000, 0x00020000, 0x000008c0,
+	0x836c0580, 0x00000003, 0x02020000, 0x001002e3,
+	0x42000000, 0x0010b4bb, 0x50000000, 0x800001c0,
+	0x04020956, 0x0401f923, 0x0401fbe3, 0x0401fb5c,
+	0x0201f800, 0x00020718, 0x0201f800, 0x0002057b,
+	0x0401f7f0, 0x59b800ea, 0x82000d00, 0xf0000038,
+	0x02020000, 0x00100a7a, 0x8c000510, 0x02000000,
+	0x00100a79, 0x59ba60e0, 0x81300182, 0x0402104e,
+	0x04002030, 0x8532653e, 0x59300406, 0x82000580,
+	0x00000003, 0x04020028, 0x59300203, 0x82000580,
+	0x00000004, 0x04020024, 0x59325808, 0x59300402,
+	0x4a025a04, 0x00000103, 0x900001c0, 0x48025806,
+	0x497a5807, 0x497a5c09, 0x5930001f, 0x80000540,
+	0x02020800, 0x00100d56, 0x59300004, 0x8c00053e,
+	0x04020010, 0x0401fa88, 0x59326809, 0x0201f800,
+	0x0002077d, 0x5934000f, 0x5934140b, 0x80081040,
+	0x04001002, 0x480a6c0b, 0x80000540, 0x04020a10,
+	0x59b800ea, 0x8c000510, 0x040207d7, 0x1c01f000,
+	0x0201f800, 0x00106f60, 0x040007ef, 0x0201f000,
+	0x00100a65, 0x42027000, 0x00000055, 0x0401f027,
+	0x83326500, 0x3fffffff, 0x59300406, 0x82000580,
+	0x00000003, 0x04020015, 0x59325808, 0x59326809,
+	0x59301402, 0x4a025a04, 0x00000103, 0x900811c0,
+	0x480a5806, 0x497a5c09, 0x497a5807, 0x0401fa62,
+	0x0201f800, 0x0002077d, 0x5934000f, 0x5934140b,
+	0x80081040, 0x04001002, 0x480a6c0b, 0x80000540,
+	0x040209eb, 0x0401f7db, 0x42027000, 0x00000054,
+	0x0401f00a, 0x83300500, 0x60000000, 0x02000000,
+	0x00100a68, 0x81326580, 0x8000013a, 0x82000400,
+	0x00100a80, 0x50027000, 0x59300c06, 0x82040580,
+	0x00000002, 0x02000000, 0x00100a65, 0x59300004,
+	0x8c00053e, 0x04020004, 0x0201f800, 0x000207a1,
+	0x0401f7c4, 0x0201f800, 0x00106f60, 0x040007fb,
+	0x0201f000, 0x00100a65, 0x59325808, 0x412c7000,
+	0x58380a04, 0x82040500, 0x0000000f, 0x82000c00,
+	0x001010bd, 0x50044000, 0x0c01f001, 0x00100dd9,
+	0x00100dd9, 0x0002009f, 0x00100dd9, 0x00100dd9,
+	0x00100dd9, 0x00100dd9, 0x00100dd9, 0x000200af,
+	0x00100ded, 0x00100dd9, 0x00100dd9, 0x00100ddb,
+	0x00100dd9, 0x00100dd9, 0x00100dd9, 0x5838040a,
+	0x8c000500, 0x02000800, 0x001005d8, 0x50200000,
+	0x80387c00, 0x583c1002, 0x583c2800, 0x583c2001,
+	0x58380a07, 0x5838300f, 0x59303807, 0x58384c08,
+	0x5838000d, 0x48026012, 0x0401f010, 0x5838020a,
+	0x8c000502, 0x02000000, 0x00100dd9, 0x50200000,
+	0x80387c00, 0x583c2800, 0x583c2001, 0x583c1002,
+	0x592c0a07, 0x592c4c08, 0x592c300f, 0x59303807,
+	0x497a6012, 0x497a6013, 0x4816600e, 0x4812600f,
+	0x480a6010, 0x481a6011, 0x80040840, 0x4806600d,
+	0x02020000, 0x00100e1a, 0x841c3d40, 0x481e6007,
+	0x1c01f000, 0x41787800, 0x59325808, 0x592c0c0a,
+	0x8c040d02, 0x02000000, 0x00100f8c, 0x592c000d,
+	0x592c100f, 0x592c0a04, 0x480a6011, 0x48026012,
+	0x48026013, 0x412c3000, 0x82040500, 0x0000000f,
+	0x82000400, 0x001010bd, 0x50003800, 0x501c0000,
+	0x401c1000, 0x592c1a07, 0x4802600a, 0x481a600b,
+	0x480a600c, 0x480e600d, 0x843c7d4a, 0x403c1000,
+	0x1c01f000, 0x41787800, 0x497a6012, 0x592c0a04,
+	0x412c3000, 0x592c1a07, 0x82040500, 0x0000000f,
+	0x82000400, 0x001010bd, 0x50004000, 0x50200000,
+	0x40201000, 0x4802600a, 0x481a600b, 0x480a600c,
+	0x480e600d, 0x80000580, 0x483e6004, 0x1c01f000,
+	0x4c000000, 0x4df00000, 0x0201f800, 0x00020729,
+	0x0401f005, 0x4c000000, 0x4df00000, 0x0401ff16,
+	0x0401f001, 0x5c03e000, 0x5c000000, 0x1801f000,
+	0x4203e000, 0xb0100000, 0x41fc0000, 0x82000500,
+	0x00000011, 0x0c01f001, 0x0002012a, 0x00020697,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0010115a, 0x0002012c,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0002012a, 0x0002012a,
+	0x0002012a, 0x0002012a, 0x0201f800, 0x001005d8,
+	0x0201f800, 0x00020697, 0x0201f000, 0x0010115a,
+	0x42000000, 0x0010b4c1, 0x50000000, 0x8c000504,
+	0x04000014, 0x42000000, 0x0010b4c1, 0x50000000,
+	0x8c000502, 0x04020002, 0x1c01f000, 0x4df00000,
+	0x4203e000, 0x50000000, 0x42034000, 0x0010b4a4,
+	0x59a0001d, 0x59a1d81e, 0x84000502, 0x4803401d,
+	0x58ec0009, 0x0801f800, 0x5c03e000, 0x1c01f000,
+	0x04027002, 0x04026002, 0x1c01f000, 0x4df00000,
+	0x4203e000, 0x50000000, 0x0201f800, 0x001007e4,
+	0x04000010, 0x412dd800, 0x48efc857, 0x0201f800,
+	0x00103b28, 0x42034000, 0x0010b4a4, 0x49a1d80b,
+	0x48ef401e, 0x59a0001d, 0x84000544, 0x4803401d,
+	0x0201f800, 0x00102214, 0x0201f800, 0x00102233,
+	0x5c03e000, 0x1c01f000, 0x4da00000, 0x4df00000,
+	0x4203e000, 0x50000000, 0x04006051, 0x40001000,
+	0x42034000, 0x0010b4a4, 0x59a01818, 0x800c19c0,
+	0x04020008, 0x59a0381b, 0x801c39c0, 0x02000800,
+	0x001005d8, 0x59a0041c, 0x801c3c00, 0x0401f00c,
+	0x59a00419, 0x82000400, 0x00000002, 0x48034419,
+	0x82000c80, 0x00000013, 0x04001003, 0x497b4419,
+	0x41780000, 0x59a03816, 0x801c3c00, 0x80081040,
+	0x480b4017, 0x581c0200, 0x4803c021, 0x581c0401,
+	0x4803c022, 0x581c0201, 0x4803c023, 0x581c0400,
+	0x4803c020, 0x900001c0, 0x82000540, 0x00000012,
+	0x4803c011, 0x59e00017, 0x8c000508, 0x04000003,
+	0x4a03c017, 0x00000002, 0x4203e000, 0x30000001,
+	0x800c19c0, 0x04000007, 0x800c1840, 0x480f4018,
+	0x0402001f, 0x497b4419, 0x497b4219, 0x0401f01c,
+	0x800811c0, 0x0402000b, 0x4d2c0000, 0x59a2581b,
+	0x0201f800, 0x001007f4, 0x5c025800, 0x497b401b,
+	0x497b401a, 0x497b441c, 0x497b421c, 0x0401f010,
+	0x59a0041c, 0x82000400, 0x00000002, 0x82000c80,
+	0x00000012, 0x4803441c, 0x04001009, 0x4d2c0000,
+	0x59a2581b, 0x592c3813, 0x481f401b, 0x497b441c,
+	0x0201f800, 0x001007f4, 0x5c025800, 0x5c03e000,
+	0x5c034000, 0x1c01f000, 0x59a80005, 0x82000500,
+	0x00000003, 0x02020000, 0x00104315, 0x59340400,
+	0x82000580, 0x00000606, 0x02020000, 0x001042e6,
+	0x5934000d, 0x80027d40, 0x02020000, 0x00104321,
+	0x0401f803, 0x80000580, 0x1c01f000, 0x5934000f,
+	0x59341203, 0x80080540, 0x0402006f, 0x5934020b,
+	0x5934140b, 0x80080480, 0x0402106b, 0x0201f800,
+	0x0002075a, 0x04000064, 0x80081000, 0x592c0406,
+	0x480a6c0b, 0x49366009, 0x492e6008, 0x4a026406,
+	0x00000003, 0x4a026403, 0x00000040, 0x800000c2,
+	0x800018c4, 0x800c0400, 0x48026206, 0x592c0808,
+	0x592c1809, 0x592c020a, 0x48066017, 0x480e6018,
+	0x8c000502, 0x04000030, 0x4a026203, 0x00000004,
+	0x592c0207, 0x80000040, 0x04020020, 0x59a80005,
+	0x8c000514, 0x42000000, 0x00000055, 0x04020003,
+	0x42000000, 0x00000033, 0x80000040, 0x040207ff,
+	0x592c0204, 0x82000500, 0x000000ff, 0x82000580,
+	0x00000018, 0x04020011, 0x592c180f, 0x59300007,
+	0x82000540, 0x00000091, 0x480e6011, 0x48026007,
+	0x42000000, 0x80000004, 0x48026004, 0x59bc00ea,
+	0x8c000516, 0x040207fe, 0x83300400, 0x20000000,
+	0x480378e1, 0x1c01f000, 0x0401fe78, 0x59300007,
+	0x8400054e, 0x48026007, 0x592c1a04, 0x820c1d00,
+	0x000000ff, 0x820c0580, 0x00000048, 0x04000017,
+	0x0401f7ec, 0x8c000500, 0x04020ecb, 0x4a026203,
+	0x00000002, 0x59a80805, 0x82040500, 0x00000600,
+	0x04020012, 0x42000000, 0x00000030, 0x80000040,
+	0x040207ff, 0x592c1a04, 0x820c1d00, 0x000000ff,
+	0x820c0580, 0x00000018, 0x040007da, 0x820c0580,
+	0x00000048, 0x040207d7, 0x42000800, 0x80000804,
+	0x0201f000, 0x00106721, 0x8c040d12, 0x42000000,
+	0x00000010, 0x040207ee, 0x42000000, 0x00000051,
+	0x0401f7eb, 0x800811c0, 0x04020003, 0x4a026a03,
+	0x00000001, 0x59340010, 0x492e6810, 0x80000d40,
+	0x04020003, 0x492e680f, 0x1c01f000, 0x492c0800,
+	0x1c01f000, 0x83440c80, 0x00000800, 0x04021009,
+	0x83440400, 0x0010ac00, 0x50000000, 0x80000540,
+	0x04000004, 0x40026800, 0x80000580, 0x1c01f000,
+	0x82000540, 0x00000001, 0x1c01f000, 0x59340203,
+	0x80000540, 0x0402004b, 0x4d300000, 0x4d2c0000,
+	0x5934000f, 0x80025d40, 0x04000044, 0x0201f800,
+	0x0002075a, 0x0400003f, 0x592c0000, 0x4802680f,
+	0x80000540, 0x04020002, 0x48026810, 0x592c2a04,
+	0x80081000, 0x480a6c0b, 0x49366009, 0x492e6008,
+	0x82142d00, 0x000000ff, 0x82140580, 0x00000012,
+	0x04000035, 0x4a026406, 0x00000003, 0x4a026403,
+	0x00000040, 0x592c0406, 0x800000c2, 0x800018c4,
+	0x800c0400, 0x48026206, 0x592c0808, 0x592c1809,
+	0x592c020a, 0x48066017, 0x480e6018, 0x8c000502,
+	0x02000000, 0x0010474d, 0x4a026203, 0x00000004,
+	0x592c0207, 0x80000040, 0x02020000, 0x00104740,
+	0x82140580, 0x00000018, 0x02020000, 0x00104740,
+	0x592c180f, 0x59300007, 0x82000540, 0x00000091,
+	0x480e6011, 0x48026007, 0x42000000, 0x80000004,
+	0x48026004, 0x59bc00ea, 0x8c000516, 0x040207fe,
+	0x83300400, 0x20000000, 0x480378e1, 0x5934020b,
+	0x5934140b, 0x80080480, 0x040017be, 0x0401f003,
+	0x4a026a03, 0x00000001, 0x5c025800, 0x5c026000,
+	0x1c01f000, 0x497a5800, 0x49325809, 0x4a026406,
+	0x00000006, 0x4a026203, 0x00000007, 0x0401f802,
+	0x0401f7ef, 0x59a80021, 0x800001c0, 0x02020000,
+	0x0010476f, 0x59a80005, 0x8c000504, 0x02020000,
+	0x0010476b, 0x59340200, 0x8c000518, 0x02020000,
+	0x00104767, 0x592c0a0c, 0x48066202, 0x4a025a06,
+	0x00000000, 0x8c000508, 0x02020000, 0x00104763,
+	0x4d3c0000, 0x417a7800, 0x0401fbdf, 0x5c027800,
+	0x1c01f000, 0x592c0404, 0x8c00051e, 0x02020000,
+	0x00104ce4, 0x59980022, 0x80000540, 0x04000017,
+	0x592c0a06, 0x592c0409, 0x80040540, 0x04020013,
+	0x0201f000, 0x00104cfa, 0x592c0404, 0x8c00051e,
+	0x02020000, 0x00104cf3, 0x59980022, 0x80000540,
+	0x0400000a, 0x82040580, 0x00000001, 0x04020007,
+	0x0201f000, 0x00104cfa, 0x592c0404, 0x8c00051e,
+	0x02020000, 0x00104dca, 0x59980026, 0x497a5800,
+	0x80000540, 0x02020000, 0x00104e1d, 0x59d80105,
+	0x82000d00, 0x00018780, 0x02020000, 0x00104edb,
+	0x80000106, 0x82000500, 0x00000003, 0x0c01f001,
+	0x000202f0, 0x00104e1d, 0x000202f6, 0x00020341,
+	0x592c0001, 0x492fb107, 0x80000d40, 0x02020000,
+	0x00104ddb, 0x1c01f000, 0x592c0001, 0x492fb107,
+	0x80000d40, 0x02020000, 0x00104de8, 0x59da5908,
+	0x835c0480, 0x00000020, 0x0400102c, 0x0402b034,
+	0x492fb007, 0x0400e7fa, 0x59d80105, 0x82000500,
+	0x00018780, 0x02020000, 0x00104edb, 0x0400601f,
+	0x59d8010a, 0x59d8090a, 0x80040580, 0x040207fd,
+	0x800408e0, 0x599c1017, 0x8c081508, 0x04020028,
+	0x82040d40, 0x00000013, 0x5998002b, 0x4807c011,
+	0x84000500, 0x4803302b, 0x59e00017, 0x8c000508,
+	0x04020004, 0x4203e000, 0x30000001, 0x1c01f000,
+	0x4a03c017, 0x00000003, 0x82040500, 0x000000ff,
+	0x82000580, 0x0000001d, 0x040207f7, 0x4a03c017,
+	0x0000000d, 0x0401f7f4, 0x5998082b, 0x84040d40,
+	0x4807302b, 0x1c01f000, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0400e7ca, 0x0401f7d0, 0x0402f7f7,
+	0x492fa807, 0x0400e7c6, 0x0401f7cc, 0x59e0000f,
+	0x59e0100f, 0x80081580, 0x040207fd, 0x81281580,
+	0x040007d4, 0x40025000, 0x82040d40, 0x0000001d,
+	0x0401f7d2, 0x59d80908, 0x45680800, 0x4006d000,
+	0x815eb800, 0x0400e7fc, 0x59c80000, 0x82000540,
+	0x00001200, 0x48039000, 0x02006000, 0x00104df8,
+	0x59d8010a, 0x59d8090a, 0x80040d80, 0x040207fd,
+	0x900001c0, 0x82000540, 0x00000013, 0x4803c011,
+	0x5998002b, 0x84000500, 0x4803302b, 0x59e00017,
+	0x8c000508, 0x04000003, 0x4a03c017, 0x00000003,
+	0x4203e000, 0x30000001, 0x59d80105, 0x82000500,
+	0x00018780, 0x02020000, 0x00104edb, 0x0202d000,
+	0x00104dfd, 0x592c0001, 0x492fb107, 0x80000d40,
+	0x02020000, 0x00104e10, 0x1c01f000, 0x59980020,
+	0x0c01f001, 0x00020370, 0x00020371, 0x00104e88,
+	0x1c01f000, 0x4df00000, 0x4203e000, 0x50000000,
+	0x0402681e, 0x04006004, 0x599c0017, 0x8c000508,
+	0x04020865, 0x59980029, 0x80025d40, 0x0400000a,
+	0x0402d00b, 0x59980026, 0x80000040, 0x48033026,
+	0x592c0000, 0x492fb107, 0x48033029, 0x04020002,
+	0x48033028, 0x5c03e000, 0x1c01f000, 0x59d80105,
+	0x82000500, 0x00018780, 0x02020000, 0x00104edb,
+	0x42000000, 0x0010b855, 0x0201f800, 0x0010aa47,
+	0x5c03e000, 0x1c01f000, 0x5998002b, 0x8c000500,
+	0x0402003b, 0x0400e007, 0x59d80105, 0x82000500,
+	0x00018780, 0x02020000, 0x00104edb, 0x1c01f000,
+	0x59da5908, 0x835c0c80, 0x00000020, 0x04001003,
+	0x0400b029, 0x0400f02b, 0x496a5800, 0x412ed000,
+	0x815eb800, 0x59c80000, 0x82000540, 0x00001200,
+	0x48039000, 0x0400e7f3, 0x59d8010a, 0x59d8090a,
+	0x80040580, 0x040207fd, 0x800408e0, 0x599c1017,
+	0x8c081508, 0x04020022, 0x82040d40, 0x00000013,
+	0x4807c011, 0x59e00017, 0x8c000508, 0x0400000a,
+	0x4a03c017, 0x00000003, 0x82040500, 0x000000ff,
+	0x82000580, 0x0000001d, 0x04020003, 0x4a03c017,
+	0x0000000d, 0x4203e000, 0x30000001, 0x59d80105,
+	0x82000500, 0x00018780, 0x02020000, 0x00104edb,
+	0x1c01f000, 0x492fb007, 0x0400e7d2, 0x0401f7df,
+	0x492fa807, 0x0400e7cf, 0x0401f7dc, 0x84000500,
+	0x4803302b, 0x0400e7cb, 0x0401f7d8, 0x59e0000f,
+	0x59e0100f, 0x80081580, 0x040207fd, 0x81281580,
+	0x040007da, 0x40025000, 0x82040d40, 0x0000001d,
+	0x0401f7d8, 0x59e0000f, 0x59e0100f, 0x80080d80,
+	0x040207fd, 0x81280580, 0x04020002, 0x1c01f000,
+	0x400a5000, 0x900811c0, 0x82081540, 0x0000001c,
+	0x480bc011, 0x59e00017, 0x8c000508, 0x04000003,
+	0x4a03c017, 0x0000000c, 0x4203e000, 0x30000001,
+	0x1c01f000, 0x41700000, 0x0c01f001, 0x00105420,
+	0x000203fc, 0x00105420, 0x00105421, 0x0010541e,
+	0x0010541e, 0x0010541e, 0x0010541e, 0x001058b0,
+	0x04010037, 0x59980006, 0x80000540, 0x0402003c,
+	0x0402c01c, 0x4202f800, 0x00000010, 0x4df00000,
+	0x4203e000, 0x50000000, 0x49db3005, 0x59da5808,
+	0x592c0204, 0x497a5800, 0x497a5801, 0x82000500,
+	0x000000ff, 0x82000c80, 0x00000079, 0x04021036,
+	0x0c01f839, 0x5c03e000, 0x817ef840, 0x04000009,
+	0x836c0580, 0x00000003, 0x04020006, 0x83700580,
+	0x00000001, 0x04020010, 0x0401001b, 0x0400c7e8,
+	0x0400f94a, 0x0400b134, 0x59d40005, 0x82000500,
+	0x43018780, 0x02020000, 0x0010583f, 0x59d80005,
+	0x82000500, 0x43018780, 0x02020000, 0x00105846,
+	0x1c01f000, 0x83700580, 0x00000003, 0x02000800,
+	0x00105421, 0x83700580, 0x00000001, 0x040207ed,
+	0x04010005, 0x0400c7d2, 0x0401f7ea, 0x4202f800,
+	0x00000010, 0x4df00000, 0x4203e000, 0x50000000,
+	0x49d73005, 0x59d65808, 0x0401f7ce, 0x4df00000,
+	0x4203e000, 0x50000000, 0x40025800, 0x592c0204,
+	0x497b3005, 0x497b3006, 0x4202f800, 0x00000010,
+	0x0401f7c7, 0x0201f800, 0x00105491, 0x5c03e000,
+	0x0401f7d4, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105527, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x001054a1,
+	0x00105491, 0x00105491, 0x00105491, 0x00105551,
+	0x00105491, 0x00105491, 0x00105491, 0x000204ef,
+	0x00105491, 0x001056b4, 0x00105491, 0x00105491,
+	0x00105491, 0x000204c2, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x001054c9, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x001057d3, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x0010581e, 0x00105491,
+	0x001054bb, 0x00105491, 0x00105797, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105765, 0x00105491,
+	0x00105765, 0x00105872, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105725,
+	0x00105855, 0x00105491, 0x00105865, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x00105491, 0x00105491,
+	0x00105491, 0x00105491, 0x592c0204, 0x80000110,
+	0x02000000, 0x00105499, 0x80000040, 0x04000009,
+	0x48033002, 0x492f3003, 0x492f3004, 0x4a033008,
+	0x000204d0, 0x4202e000, 0x00000003, 0x1c01f000,
+	0x592c0406, 0x82000c80, 0x0000199a, 0x02021000,
+	0x001054a9, 0x59a80021, 0x80000540, 0x02020000,
+	0x001054d7, 0x592e8a06, 0x83440c80, 0x000007f0,
+	0x02021000, 0x001054a9, 0x83440400, 0x0010ac00,
+	0x50000000, 0x80026d40, 0x02000000, 0x001054db,
+	0x59340002, 0x592c0810, 0x80040580, 0x82000500,
+	0x00ffffff, 0x02020000, 0x001054a9, 0x0401fccf,
+	0x02020000, 0x001054de, 0x1c01f000, 0x592c0204,
+	0x80000110, 0x02000000, 0x00105499, 0x80000040,
+	0x0402000b, 0x592c040a, 0x8c000504, 0x04000010,
+	0x592c0207, 0x82000c80, 0x00001001, 0x02021000,
+	0x001054a9, 0x0201f000, 0x0010588a, 0x48033002,
+	0x492f3003, 0x492f3004, 0x4a033008, 0x00020507,
+	0x4202e000, 0x00000003, 0x1c01f000, 0x592c0406,
+	0x82000c80, 0x0000199a, 0x02021000, 0x001054a9,
+	0x592e8a06, 0x417a7800, 0x0401fd37, 0x02020000,
+	0x00105658, 0x59340002, 0x592c0808, 0x80040580,
+	0x82000500, 0x00ffffff, 0x02020000, 0x001054a9,
+	0x497a5808, 0x592e6009, 0x83300580, 0xffffffff,
+	0x02000000, 0x00105618, 0x83300480, 0x0010d1c0,
+	0x02001000, 0x00105675, 0x59a8000b, 0x81300480,
+	0x02021000, 0x00105675, 0x592c240a, 0x49366009,
+	0x8c10251c, 0x02020000, 0x00105606, 0x59a80068,
+	0x8c000510, 0x02020000, 0x0010568e, 0x59a80821,
+	0x800409c0, 0x02020000, 0x001055ec, 0x59a80805,
+	0x8c040d04, 0x02020000, 0x0010567f, 0x59340200,
+	0x8c000518, 0x02020000, 0x00105670, 0x59300c06,
+	0x82040580, 0x00000006, 0x02020000, 0x00105610,
+	0x59300414, 0x8c000516, 0x02020000, 0x0010567a,
+	0x8c102508, 0x02020000, 0x0010a5b8, 0x59300808,
+	0x4a025a06, 0x00000000, 0x800409c0, 0x02020000,
+	0x001055e7, 0x592c0a0c, 0x48066202, 0x492e6008,
+	0x0401f14d, 0x4df00000, 0x4203e000, 0x50000000,
+	0x0402b00b, 0x835c0480, 0x00000020, 0x0400100d,
+	0x815eb840, 0x416a5800, 0x592ed000, 0x492fb007,
+	0x497a5800, 0x497a5801, 0x0400b7f7, 0x59d80005,
+	0x82000500, 0x43018780, 0x02020000, 0x00105846,
+	0x5c03e000, 0x1c01f000, 0x4df00000, 0x4203e000,
+	0x50000000, 0x0402f00b, 0x835c0480, 0x00000020,
+	0x0400100d, 0x815eb840, 0x416a5800, 0x592ed000,
+	0x492fa807, 0x497a5800, 0x497a5801, 0x0400f7f7,
+	0x59d40005, 0x82000500, 0x43018780, 0x02020000,
+	0x0010583f, 0x5c03e000, 0x1c01f000, 0x4df00000,
+	0x4203e000, 0x50000000, 0x59940024, 0x80000540,
+	0x04000112, 0x4c000000, 0x42000000, 0x00001000,
+	0x50000000, 0x82000480, 0x24320001, 0x04020015,
+	0x42000800, 0x00000064, 0x80040840, 0x04000007,
+	0x4a030000, 0x00000001, 0x40000000, 0x59800000,
+	0x8c000500, 0x040007f9, 0x04000008, 0x42000800,
+	0x00007a01, 0x50040000, 0x8c000510, 0x04000003,
+	0x84000510, 0x44000800, 0x4a030000, 0x00000000,
+	0x59e00002, 0x8c00051e, 0x0402001b, 0x42000000,
+	0x00001000, 0x50000000, 0x82000480, 0x24320002,
+	0x04020015, 0x42000800, 0x00000064, 0x80040840,
+	0x04000007, 0x4a030000, 0x00000001, 0x40000000,
+	0x59800000, 0x8c000500, 0x040007f9, 0x04000008,
+	0x42000800, 0x00007a17, 0x50040000, 0x8c00050e,
+	0x04020003, 0x8400054e, 0x44000800, 0x4a030000,
+	0x00000000, 0x5c000000, 0x5994781a, 0x48032825,
+	0x803c0480, 0x04001004, 0x04000003, 0x4803281a,
+	0x0401f022, 0x41787800, 0x803c7800, 0x82000400,
+	0x000003e8, 0x040027fd, 0x4803281a, 0x59a80024,
+	0x803c1400, 0x480b5024, 0x803c0040, 0x04000002,
+	0x483fc857, 0x59e40852, 0x59a80025, 0x80040580,
+	0x04000004, 0x480bc857, 0x59e40052, 0x48035025,
+	0x59940026, 0x803c0400, 0x48032826, 0x0201f800,
+	0x00106021, 0x59940000, 0x82000580, 0x00000000,
+	0x04020006, 0x59940026, 0x48032827, 0x497b2826,
+	0x4a032800, 0x00000001, 0x4c0c0000, 0x59940007,
+	0x80000d40, 0x0400001d, 0x59941006, 0x59940025,
+	0x80081c80, 0x04001004, 0x04000003, 0x480f2806,
+	0x0401f016, 0x80040840, 0x48072807, 0x82040580,
+	0x000003e8, 0x04020007, 0x4c040000, 0x4c0c0000,
+	0x59940008, 0x0801f800, 0x5c001800, 0x5c000800,
+	0x800409c0, 0x04020004, 0x59940008, 0x0801f800,
+	0x0401f006, 0x400c0000, 0x820c1c00, 0x0000000a,
+	0x040027ed, 0x480f2806, 0x5c001800, 0x4d180000,
+	0x59c40008, 0x8c000534, 0x04020025, 0x417a3000,
+	0x83947c00, 0x00000009, 0x583c0001, 0x80000d40,
+	0x04020008, 0x823c7c00, 0x00000003, 0x811a3000,
+	0x83180580, 0x00000005, 0x040207f8, 0x0401f018,
+	0x583c1000, 0x59940025, 0x80080480, 0x04001005,
+	0x04000004, 0x48007800, 0x80000040, 0x04021010,
+	0x80040840, 0x48047801, 0x04000008, 0x82000400,
+	0x0000000a, 0x48007800, 0x040027fa, 0x82040500,
+	0x0000007f, 0x0401f7e8, 0x583c0002, 0x4c3c0000,
+	0x0801f800, 0x5c007800, 0x0401f7e3, 0x5c023000,
+	0x59940019, 0x80001540, 0x04000008, 0x04002007,
+	0x59940025, 0x80080480, 0x497b2819, 0x04001003,
+	0x04000002, 0x48032819, 0x59940004, 0x80000d40,
+	0x0400002a, 0x4c040000, 0x5994001c, 0x80000d40,
+	0x04000013, 0x5994101b, 0x59940025, 0x80080480,
+	0x04001005, 0x04000004, 0x4803281b, 0x80000040,
+	0x0402100b, 0x80040840, 0x4807281c, 0x04020004,
+	0x5994001d, 0x0801f800, 0x0401f005, 0x82000400,
+	0x0000000a, 0x4803281b, 0x040027f7, 0x5c000800,
+	0x59941003, 0x59940025, 0x80080480, 0x04001005,
+	0x04000004, 0x48032803, 0x80000040, 0x0402100b,
+	0x80040840, 0x48072804, 0x04020004, 0x59940005,
+	0x0801f800, 0x0401f005, 0x82000400, 0x0000000a,
+	0x48032803, 0x040027f7, 0x5994001f, 0x80000d40,
+	0x04000013, 0x5994101e, 0x59940025, 0x80080480,
+	0x04001005, 0x04000004, 0x4803281e, 0x80000040,
+	0x0402100b, 0x80040840, 0x4807281f, 0x04020004,
+	0x59940020, 0x0801f800, 0x0401f005, 0x82000400,
+	0x00000001, 0x4803281e, 0x040027f7, 0x59940022,
+	0x80000d40, 0x04000013, 0x59941021, 0x59940025,
+	0x80080480, 0x04001005, 0x04000004, 0x48032821,
+	0x80000040, 0x0402100b, 0x80040840, 0x48072822,
+	0x04020004, 0x59940023, 0x0801f800, 0x0401f005,
+	0x82000400, 0x0000000a, 0x48032821, 0x040027f7,
+	0x59940824, 0x59940025, 0x80040480, 0x02001800,
+	0x001005d8, 0x48032824, 0x59940000, 0x0c01f001,
+	0x00105fb5, 0x00105fb7, 0x00105fdd, 0x59940024,
+	0x80000000, 0x48032824, 0x4203e000, 0x70000000,
+	0x1c01f000, 0x592c0406, 0x800000c2, 0x800008c4,
+	0x80040c00, 0x592c040a, 0x48066206, 0x82000d00,
+	0x00000003, 0x02000000, 0x0010615e, 0x8c000500,
+	0x04020029, 0x8c00051e, 0x02000000, 0x00106139,
+	0x82000d00, 0x000000c0, 0x02020000, 0x0010612f,
+	0x82000d00, 0x00002020, 0x02020000, 0x0010612c,
+	0x813e79c0, 0x02020000, 0x0010612c, 0x592c0c0c,
+	0x800409c0, 0x02020000, 0x0010612c, 0x59300a03,
+	0x82040d80, 0x00000007, 0x02020000, 0x0010612c,
+	0x4a026203, 0x00000003, 0x4a026403, 0x00000043,
+	0x0201f800, 0x000200c9, 0x82080d40, 0x80003465,
+	0x48066004, 0x497a6000, 0x59bc00ea, 0x8c000516,
+	0x040207fe, 0x83300400, 0xa0000000, 0x480378e1,
+	0x1c01f000, 0x8c000502, 0x02020000, 0x00106181,
+	0x8c00051e, 0x0400000e, 0x82000d00, 0x000000c0,
+	0x04000005, 0x82040d80, 0x000000c0, 0x02020000,
+	0x00106186, 0x82000d00, 0x00002020, 0x82040d80,
+	0x00002020, 0x02000000, 0x0010614d, 0x592c0207,
+	0x80000040, 0x02020000, 0x00106157, 0x592c180d,
+	0x800c19c0, 0x02020000, 0x00106157, 0x592c180f,
+	0x59300007, 0x82000540, 0x00000011, 0x480e6011,
+	0x48026007, 0x4a026203, 0x00000004, 0x4a026403,
+	0x00000042, 0x42000800, 0x80002001, 0x0401f02a,
+	0x5c000000, 0x4c000000, 0x4803c857, 0x4807c857,
+	0x0401f003, 0x42000800, 0x00000001, 0x59325808,
+	0x832c0500, 0x00ff0000, 0x0400000d, 0x592c0000,
+	0x48065a06, 0x48026008, 0x592c040a, 0x8c000510,
+	0x04020008, 0x0201f800, 0x000202ce, 0x417a7800,
+	0x59300008, 0x80025d40, 0x0402078f, 0x1c01f000,
+	0x456a5800, 0x412ed000, 0x815eb800, 0x59c80000,
+	0x82000540, 0x00001200, 0x48039000, 0x0401f7f4,
+	0x59840000, 0x80000540, 0x04020002, 0x1c01f000,
+	0x59840003, 0x80000540, 0x02020000, 0x001061fe,
+	0x1c01f000, 0x48066004, 0x59bc00ea, 0x8c000516,
+	0x040207fe, 0x83300400, 0x40000000, 0x480378e1,
+	0x1c01f000, 0x59bc00ea, 0x82001500, 0xb0000018,
+	0x02020000, 0x00106c81, 0x8c000510, 0x0400002a,
+	0x59bc10e0, 0x82080500, 0xfffff000, 0x0402000a,
+	0x80080108, 0x820a3500, 0x0000000f, 0x4803c857,
+	0x1201f000, 0x00106c87, 0x84000510, 0x48026004,
+	0x0401f016, 0x840a653e, 0x59300004, 0x8c000520,
+	0x040007fa, 0x82000500, 0xfffefeff, 0x48026004,
+	0x8c08153e, 0x04020005, 0x42027000, 0x00000013,
+	0x0401f859, 0x0401f009, 0x59300004, 0x8c000514,
+	0x04000003, 0x0401ffb0, 0x0401f02f, 0x42027000,
+	0x00000049, 0x0401f850, 0x59bc00ea, 0x82001500,
+	0xb0000018, 0x02020000, 0x00106c81, 0x8c000510,
+	0x040207d8, 0x1c01f000, 0x83640480, 0x00000010,
+	0x0400101a, 0x41626000, 0x41580000, 0x59300a03,
+	0x82040d80, 0x00000000, 0x04000008, 0x83326400,
+	0x00000024, 0x81300c80, 0x040017f9, 0x42026000,
+	0x0010d1c0, 0x0401f7f6, 0x8166c840, 0x83300c00,
+	0x00000024, 0x80040480, 0x04021005, 0x4006c000,
+	0x4a026203, 0x00000008, 0x1c01f000, 0x837ac540,
+	0x0010d1c0, 0x0401f7fb, 0x42000000, 0x0010b854,
+	0x0201f800, 0x0010aa47, 0x4967c857, 0x80026580,
+	0x1c01f000, 0x83300480, 0x0010d1c0, 0x02001800,
+	0x001005d8, 0x41580000, 0x81300480, 0x0402100c,
+	0x04011000, 0x457a6000, 0x4a026202, 0x0000ffff,
+	0x83300400, 0x00000003, 0x4803c840, 0x4a03c842,
+	0x00000021, 0x8166c800, 0x1c01f000, 0x41540000,
+	0x81300480, 0x02021800, 0x001005d8, 0x04011000,
+	0x457a6000, 0x4a026202, 0x0000ffff, 0x83300400,
+	0x00000003, 0x4803c840, 0x4a03c842, 0x00000021,
+	0x59a80066, 0x49335065, 0x80000000, 0x48035066,
+	0x1c01f000, 0x4d340000, 0x59326809, 0x59300406,
+	0x82000500, 0x0000001f, 0x0c01f803, 0x5c026800,
+	0x1c01f000, 0x00107966, 0x00107979, 0x00107993,
+	0x000207c9, 0x001098f1, 0x0010990c, 0x0002083e,
+	0x00107966, 0x00107979, 0x001064ee, 0x001079ac,
+	0x00107966, 0x00107966, 0x00107966, 0x00107966,
+	0x00107966, 0x001095a1, 0x0010a6c2, 0x00107966,
+	0x00107966, 0x00107966, 0x00107966, 0x00107966,
+	0x00107966, 0x00107966, 0x00107966, 0x00107966,
+	0x00107966, 0x00107966, 0x00107966, 0x00107966,
+	0x00107966, 0x59300203, 0x82000c80, 0x0000000e,
+	0x02021800, 0x001005d8, 0x0c01f001, 0x001079aa,
+	0x00108592, 0x000207dd, 0x00108720, 0x001087b9,
+	0x001079aa, 0x001079aa, 0x001079aa, 0x00108577,
+	0x001079aa, 0x001079aa, 0x001079aa, 0x001079aa,
+	0x00108985, 0x83380480, 0x00000058, 0x04021007,
+	0x83380480, 0x00000040, 0x04001004, 0x4d2c0000,
+	0x0c01f803, 0x5c025800, 0x1c01f000, 0x0010861b,
+	0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b,
+	0x0010861d, 0x001086bd, 0x0010861b, 0x0010861b,
+	0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b,
+	0x0010861b, 0x0010861b, 0x0010861b, 0x0010861b,
+	0x0010861b, 0x0010861b, 0x001086c1, 0x000207ff,
+	0x0010861b, 0x001086c0, 0x001086c2, 0x59325808,
+	0x59300811, 0x59301402, 0x59340200, 0x8c00050e,
+	0x0402001c, 0x0401f826, 0x04000005, 0x4a025a04,
+	0x00000103, 0x497a5c09, 0x0401f009, 0x4a025a04,
+	0x00000103, 0x4a025a06, 0x00000000, 0x497a5c09,
+	0x800409c0, 0x02020800, 0x00108785, 0x48065807,
+	0x480a5c06, 0x0201f800, 0x000202c1, 0x5934000f,
+	0x5934140b, 0x80081040, 0x04001002, 0x480a6c0b,
+	0x80000540, 0x02020800, 0x00020253, 0x0401f75e,
+	0x592c020a, 0x8c000502, 0x040007e9, 0x800409c0,
+	0x040007e7, 0x592c0208, 0x8c00050e, 0x040207e4,
+	0x4933c857, 0x0201f000, 0x0010920f, 0x592c020a,
+	0x8c000500, 0x04000010, 0x59300015, 0x592c380f,
+	0x801c3c80, 0x0400000c, 0x4a025a06, 0x00000015,
+	0x8c1c3d3e, 0x04000005, 0x4a025a06, 0x00000007,
+	0x801c3880, 0x801c3800, 0x481fc857, 0x821c0d40,
+	0x00000000, 0x1c01f000, 0x59300203, 0x82003480,
+	0x0000000e, 0x02021800, 0x001005d8, 0x0c01f001,
+	0x0010992b, 0x00020852, 0x00109fba, 0x00109fc8,
+	0x0002086e, 0x0010992b, 0x0010a0a8, 0x0002088d,
+	0x0010992b, 0x0010992b, 0x0010992b, 0x0010992b,
+	0x0010992b, 0x0010992b, 0x83380580, 0x00000013,
+	0x02020000, 0x00109f42, 0x59300403, 0x82027480,
+	0x00000044, 0x02021800, 0x001005d8, 0x82000480,
+	0x00000040, 0x02001800, 0x001005d8, 0x0c01f001,
+	0x00109f9e, 0x00020864, 0x00109fa0, 0x00109fb2,
+	0x59325808, 0x832c0500, 0x00ff0000, 0x04000005,
+	0x592c0c0a, 0x8c040d1a, 0x02020000, 0x00109fad,
+	0x0401fe91, 0x0401f710, 0x83380580, 0x00000048,
+	0x04000007, 0x83380580, 0x00000053, 0x02000000,
+	0x0010a04a, 0x0201f800, 0x001005d8, 0x5930001f,
+	0x59301011, 0x59300809, 0x58040a00, 0x8c040d0e,
+	0x02020000, 0x0010a026, 0x800811c0, 0x02020000,
+	0x0010a033, 0x5930001f, 0x80000540, 0x02020000,
+	0x0010a041, 0x59325808, 0x592c040a, 0x8c00051e,
+	0x02000000, 0x0010a01c, 0x42027000, 0x00000041,
+	0x0401f001, 0x83380480, 0x00000054, 0x02021800,
+	0x001005d8, 0x83380480, 0x00000040, 0x02001000,
+	0x0010a067, 0x0c01f001, 0x0010a073, 0x000208aa,
+	0x0010a07f, 0x0010a086, 0x0010a073, 0x0010a073,
+	0x0010a073, 0x0010a073, 0x0010a075, 0x0010a07a,
+	0x0010a07a, 0x0010a073, 0x0010a073, 0x0010a073,
+	0x0010a073, 0x0010a07a, 0x0010a073, 0x0010a07a,
+	0x0010a073, 0x0010a075, 0x4a026203, 0x00000001,
+	0x493a6403, 0x42000800, 0x80002042, 0x0401f672,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x14aa62b1,
+	0x00000000, 0x00000000, 0x00000000, 0x00000005,
+	0xfffffffb, 0x02800004, 0x00000000, 0x0000c000,
+	0x0000071d, 0x073fca5a, 0x0705a5a5, 0x01928009,
+	0x070ff0e1, 0x03800006, 0x04958010, 0x05308000,
+	0x05008000, 0x0600902f, 0x04a004dc, 0x0202f051,
+	0x042e4020, 0x018f021b, 0x033e5000, 0x03020000,
+	0x078d0018, 0x0493041a, 0x0092041c, 0x038a0305,
+	0x078b0303, 0x048e8010, 0x0678aae5, 0x06000001,
+	0x07818174, 0x040010e6, 0x0448e0e6, 0x04818010,
+	0x002fb008, 0x0448e0e6, 0x04818010, 0x060ff0e6,
+	0x00580401, 0x054880ff, 0x04818010, 0x022a5001,
+	0x030430d4, 0x06780043, 0x030e0000, 0x030450ff,
+	0x06780043, 0x03019000, 0x058185c6, 0x027c0045,
+	0x03020000, 0x06810037, 0x027c0045, 0x03040000,
+	0x068100c7, 0x027c0045, 0x03080000, 0x0781061e,
+	0x04908037, 0x029105c4, 0x010410a6, 0x0379ff41,
+	0x037fffff, 0x072d6000, 0x07601241, 0x050f80ff,
+	0x032fa009, 0x05600400, 0x050f80ff, 0x056c04ff,
+	0x068105dc, 0x073fa009, 0x06000001, 0x0279ff02,
+	0x0700ffff, 0x070ff0d1, 0x0179feff, 0x0700ffff,
+	0x045c0402, 0x048185dc, 0x060ff0d0, 0x0179feff,
+	0x0700ffff, 0x057dfeff, 0x0700ffff, 0x078105be,
+	0x05600e41, 0x050f80ff, 0x032fa069, 0x07480000,
+	0x068105d0, 0x06780043, 0x070000f0, 0x0781005f,
+	0x037c00ff, 0x06000010, 0x0781005f, 0x038005cc,
+	0x0379ff00, 0x070fffff, 0x06780043, 0x07f00000,
+	0x075a0000, 0x020ef001, 0x028605ce, 0x05484000,
+	0x02a1819e, 0x062d6001, 0x002fb001, 0x070ff069,
+	0x01868072, 0x060ff079, 0x055c0441, 0x06810010,
+	0x012fb000, 0x060560fb, 0x03800078, 0x060ff079,
+	0x02868198, 0x070ff069, 0x055c0441, 0x06810010,
+	0x060560fb, 0x0400d0d0, 0x062d6002, 0x0648300d,
+	0x06810086, 0x070ff0d1, 0x062d6001, 0x045c040b,
+	0x06810089, 0x05488000, 0x04818086, 0x072e500c,
+	0x00208001, 0x05a004e1, 0x02800010, 0x062d6001,
+	0x07f00000, 0x07f00000, 0x070ff0d1, 0x0179feff,
+	0x070000ff, 0x055c040c, 0x058180bb, 0x0007b001,
+	0x03079041, 0x0307a000, 0x06600a79, 0x050f80ff,
+	0x053fa80a, 0x06000010, 0x072d5003, 0x078d0096,
+	0x0307c003, 0x0007d004, 0x0107e005, 0x0307f006,
+	0x02080007, 0x00081008, 0x01082009, 0x0308300a,
+	0x0008400b, 0x0308500c, 0x068d00a1, 0x0678007a,
+	0x07f00000, 0x010880ff, 0x03386000, 0x03010000,
+	0x072e6300, 0x020ef07f, 0x02860010, 0x070ff07d,
+	0x0450047c, 0x050f80ff, 0x002fa819, 0x068d00ae,
+	0x02080001, 0x00081002, 0x0448807a, 0x068100b5,
+	0x0379ff03, 0x070000ff, 0x01082003, 0x068d00b6,
+	0x02386004, 0x03010000, 0x072e6c00, 0x02800010,
+	0x06780043, 0x070000f0, 0x078105d7, 0x050020ff,
+	0x027c0002, 0x06000010, 0x078100c3, 0x038005d7,
+	0x0700c0d1, 0x0379ff0c, 0x070000ff, 0x0380008e,
+	0x0204a051, 0x06780043, 0x070000f0, 0x037c00ff,
+	0x06000010, 0x0781816a, 0x072d6000, 0x019485c0,
+	0x050fb056, 0x044880e6, 0x04818010, 0x060ff0d0,
+	0x0179feff, 0x0700ffff, 0x057dfeff, 0x0700ffff,
+	0x078105be, 0x05a00212, 0x0349c0e4, 0x0781811d,
+	0x070ff093, 0x050010ff, 0x070ff093, 0x045c0401,
+	0x058180db, 0x02046092, 0x04002046, 0x04600202,
+	0x00540401, 0x048280e6, 0x04500425, 0x070060ff,
+	0x0730ffff, 0x0700000f, 0x0742000f, 0x05810190,
+	0x07a005a6, 0x0648a002, 0x048180e9, 0x00047089,
+	0x070ff047, 0x045c0443, 0x077800ff, 0x07f00000,
+	0x0781818e, 0x07780047, 0x0500e000, 0x048185ad,
+	0x070ff006, 0x01860117, 0x0179fe47, 0x0700000f,
+	0x010480ff, 0x056c7048, 0x06818102, 0x007a0d4a,
+	0x04003801, 0x0220f001, 0x0180010f, 0x07608e48,
+	0x034a60ff, 0x0700f0ff, 0x074b88ff, 0x037000ff,
+	0x07000600, 0x05500448, 0x074d00ff, 0x045a044a,
+	0x0304a0ff, 0x070ff00f, 0x01540406, 0x05820117,
+	0x04950120, 0x05a001bd, 0x02868123, 0x0134bfff,
+	0x070fffff, 0x0104102e, 0x050fd041, 0x00800126,
+	0x0595011d, 0x05a001bd, 0x0186011d, 0x0202f00e,
+	0x052e4030, 0x040fd02f, 0x070fc0ff, 0x05a00218,
+	0x02800010, 0x0400e02f, 0x042e4020, 0x0202f051,
+	0x0004100e, 0x0004b00e, 0x050fd041, 0x024a6c46,
+	0x04500423, 0x050070ff, 0x03620024, 0x050080ff,
+	0x04004046, 0x0700500f, 0x03206000, 0x05601048,
+	0x0700a0ff, 0x0700900a, 0x070ff005, 0x04500446,
+	0x00540425, 0x04820157, 0x05601622, 0x050f80ff,
+	0x063fa032, 0x06000002, 0x03203000, 0x01204000,
+	0x03205000, 0x0120b000, 0x0320c000, 0x07601441,
+	0x050f80ff, 0x043fa852, 0x06000001, 0x070ff056,
+	0x056c02ff, 0x050fb0ff, 0x070560ff, 0x03079041,
+	0x05600e41, 0x050f80ff, 0x073fa011, 0x0600003d,
+	0x06780043, 0x07f00000, 0x065a007a, 0x010880ff,
+	0x04a001b6, 0x058d0150, 0x0208a04a, 0x0108b04b,
+	0x02386001, 0x03010000, 0x072e6300, 0x028000a8,
+	0x0500d00a, 0x05500405, 0x014a68ff, 0x070090ff,
+	0x0154040a, 0x0700c0ff, 0x0600a023, 0x0500b024,
+	0x02206001, 0x05601622, 0x050f80ff, 0x063fa04a,
+	0x06000002, 0x05601022, 0x050f80ff, 0x043fa819,
+	0x06000001, 0x0600a00d, 0x0180013c, 0x06780043,
+	0x070000f0, 0x050010ff, 0x027c0001, 0x07000030,
+	0x078105b4, 0x027c0001, 0x06000020, 0x078105b4,
+	0x038005cc, 0x054880ff, 0x06810010, 0x070ff056,
+	0x050fb0ff, 0x044880e5, 0x0581017d, 0x044880e6,
+	0x04818010, 0x00800183, 0x056c02ff, 0x050fb0ff,
+	0x070560ff, 0x072e5300, 0x044880e6, 0x04818010,
+	0x072d5003, 0x06780043, 0x07f00000, 0x010880ff,
+	0x058d0187, 0x03386005, 0x03010000, 0x033e6000,
+	0x0700000c, 0x052e5200, 0x02800010, 0x0120918e,
+	0x018004e4, 0x01209190, 0x018004e4, 0x00209192,
+	0x018004e4, 0x03209000, 0x018004e4, 0x01209196,
+	0x018004e4, 0x00209198, 0x018004e4, 0x02493075,
+	0x06810510, 0x0120919a, 0x018004e4, 0x06601e01,
+	0x050f80ff, 0x063fa029, 0x06000008, 0x02015010,
+	0x02016051, 0x00017051, 0x00011051, 0x05601a41,
+	0x050f80ff, 0x053fa83a, 0x06000008, 0x05600e41,
+	0x050f80ff, 0x01464000, 0x032fa00a, 0x07006011,
+	0x05007012, 0x04008013, 0x07009014, 0x0600a015,
+	0x0400b016, 0x0700c017, 0x07c00000, 0x072d5003,
+	0x06601479, 0x050f80ff, 0x048d01b9, 0x063fa051,
+	0x0600003e, 0x07c00000, 0x06005051, 0x0400e02c,
+	0x0660060e, 0x050f80ff, 0x032fa009, 0x0379ff00,
+	0x070000ff, 0x076c0000, 0x058101dd, 0x0660480e,
+	0x0500e0ff, 0x034000ff, 0x01540427, 0x0582020a,
+	0x03400005, 0x070ff005, 0x055c0428, 0x0481020e,
+	0x01680e05, 0x056c0405, 0x068181bf, 0x040f8029,
+	0x053fa809, 0x07000024, 0x06600649, 0x050f80ff,
+	0x032fa009, 0x0379ff00, 0x070000ff, 0x076c0000,
+	0x068181bf, 0x0400e049, 0x0340002d, 0x050f802b,
+	0x053fa80a, 0x06000016, 0x0660480e, 0x0302c0ff,
+	0x034000ff, 0x01540427, 0x0582020c, 0x072d6000,
+	0x0460040e, 0x050f80ff, 0x0104e0d1, 0x0379ff4e,
+	0x0700ffff, 0x062d6002, 0x032fa009, 0x0004d0d0,
+	0x074b004d, 0x07780000, 0x07ffff00, 0x055a044d,
+	0x070000ff, 0x00201008, 0x04002051, 0x06003051,
+	0x05304000, 0x07000060, 0x03205009, 0x07006022,
+	0x0460040e, 0x050f80ff, 0x032fa03a, 0x06603c0e,
+	0x050f80ff, 0x073fa00a, 0x07000027, 0x050010d1,
+	0x0460320e, 0x050f80ff, 0x012fa80a, 0x060ff00e,
+	0x055c042e, 0x04810210, 0x07c00000, 0x0400e026,
+	0x008001cb, 0x0202c026, 0x008001e6, 0x0500e02e,
+	0x008001e6, 0x0400e051, 0x01800209, 0x0349c0e4,
+	0x04810215, 0x07c00000, 0x013e4000, 0x070c0000,
+	0x07c00000, 0x013e4000, 0x03080000, 0x07c00000,
+	0x009702f4, 0x022a5002, 0x0790821d, 0x00910291,
+	0x030400a6, 0x0678aae5, 0x06000001, 0x00a1860e,
+	0x06600c40, 0x050f80ff, 0x032fa021, 0x074b0000,
+	0x076c0600, 0x07818293, 0x05600403, 0x050f80ff,
+	0x073fa009, 0x06000002, 0x0279ff04, 0x0700ffff,
+	0x010440d7, 0x0179fe44, 0x0700ffff, 0x045c0404,
+	0x07818295, 0x0349f044, 0x0681829e, 0x02495001,
+	0x06818297, 0x060ff079, 0x045c0440, 0x0781823c,
+	0x0644f07a, 0x002fb008, 0x060ff079, 0x045c0440,
+	0x07818241, 0x0644f07a, 0x002fb008, 0x0648f001,
+	0x07818288, 0x04600e40, 0x050f80ff, 0x06480001,
+	0x04810257, 0x0448e001, 0x04810273, 0x02460001,
+	0x0644f001, 0x012fa80a, 0x04008040, 0x05a004ee,
+	0x0286828c, 0x05a004d8, 0x062da001, 0x013e4000,
+	0x06000080, 0x06930013, 0x02920013, 0x02800010,
+	0x0644f001, 0x012fa80a, 0x020ef002, 0x00860275,
+	0x04600840, 0x050f80ff, 0x053fa809, 0x06000002,
+	0x05780105, 0x00800440, 0x017c0105, 0x05000400,
+	0x06818275, 0x06601e02, 0x050f80ff, 0x053fa809,
+	0x06000002, 0x04602a40, 0x050f80ff, 0x070ff005,
+	0x053fa809, 0x06000002, 0x055c0405, 0x06818275,
+	0x04008040, 0x0045e008, 0x05a004d8, 0x00800251,
+	0x0644f001, 0x012fa80a, 0x050020d8, 0x04600440,
+	0x050f80ff, 0x073fa00a, 0x06000001, 0x06480001,
+	0x07818281, 0x05308000, 0x03040000, 0x06009040,
+	0x04a004dc, 0x00800251, 0x06a0060e, 0x054b0800,
+	0x056a0700, 0x06600c40, 0x050f80ff, 0x032fa00a,
+	0x00800251, 0x013e4000, 0x06000080, 0x01209288,
+	0x018004e4, 0x06009008, 0x05308000, 0x05004000,
+	0x04a004dc, 0x00800251, 0x02209002, 0x008002e5,
+	0x03209000, 0x008002e5, 0x02209004, 0x008002e5,
+	0x04a002fd, 0x062da001, 0x05308000, 0x05002000,
+	0x06009040, 0x04a004dc, 0x02800013, 0x013e4000,
+	0x06000080, 0x02495001, 0x078182db, 0x04600840,
+	0x050f80ff, 0x053fa809, 0x06000001, 0x0721f000,
+	0x0349f003, 0x058102aa, 0x0245f01f, 0x06000002,
+	0x018602db, 0x07601400, 0x050f80ff, 0x012fa809,
+	0x06480001, 0x058102db, 0x06602440, 0x050f80ff,
+	0x012fa809, 0x020ef001, 0x038682db, 0x019b02db,
+	0x050020d8, 0x062da001, 0x06303002, 0x05000430,
+	0x04600440, 0x050f80ff, 0x073fa012, 0x06000001,
+	0x028f82bf, 0x050040d8, 0x062da001, 0x07601e00,
+	0x050f80ff, 0x073fa009, 0x06000001, 0x060ff004,
+	0x00540402, 0x048202d9, 0x06005051, 0x06006051,
+	0x06602240, 0x050f80ff, 0x063fa01a, 0x06000002,
+	0x06600a40, 0x050f80ff, 0x073fa00a, 0x07000003,
+	0x060ff040, 0x045a041f, 0x010eb0ff, 0x06930013,
+	0x02920013, 0x02800010, 0x04004002, 0x018002c9,
+	0x04a002fd, 0x062da001, 0x05308000, 0x07005000,
+	0x06009040, 0x04a004dc, 0x050080d8, 0x05a004e1,
+	0x062da001, 0x02800013, 0x050fd009, 0x050fd041,
+	0x013e4000, 0x06000080, 0x05308000, 0x03013000,
+	0x04a004dc, 0x010440d7, 0x0349f044, 0x048102f2,
+	0x062da001, 0x008f02f2, 0x03e00000, 0x062da001,
+	0x02800013, 0x0249c0e5, 0x06810013, 0x062da001,
+	0x07f00000, 0x07f00000, 0x033e5000, 0x070c0000,
+	0x018f02f6, 0x03800011, 0x050020d8, 0x04600440,
+	0x050f80ff, 0x073fa00a, 0x06000001, 0x07c00000,
+	0x002fb001, 0x03800306, 0x012fb000, 0x03075087,
+	0x068d0307, 0x03386000, 0x03020000, 0x04482075,
+	0x06810352, 0x0648a0e6, 0x07810347, 0x0642007f,
+	0x06810345, 0x0340007e, 0x060ff038, 0x0154047e,
+	0x02d00334, 0x0560027d, 0x050f80ff, 0x032fa009,
+	0x030ef000, 0x02860504, 0x0107d000, 0x05600800,
+	0x050f80ff, 0x032fa009, 0x03681e00, 0x04500420,
+	0x050f80ff, 0x073fa009, 0x0700003f, 0x03800311,
+	0x070ff07d, 0x0450047c, 0x050f80ff, 0x002fa819,
+	0x078d0327, 0x02080001, 0x00081002, 0x0448807a,
+	0x0781032e, 0x0379ff03, 0x070000ff, 0x01082003,
+	0x068d032f, 0x02386004, 0x03010000, 0x072e6c00,
+	0x02800352, 0x0380033a, 0x0380033c, 0x0280033e,
+	0x02800340, 0x03800342, 0x03800344, 0x0727c005,
+	0x02800323, 0x0627c008, 0x02800323, 0x0627c00b,
+	0x02800323, 0x0627c00e, 0x02800323, 0x0727c011,
+	0x02800323, 0x03800314, 0x052e6800, 0x02800352,
+	0x044880e6, 0x07810533, 0x052e6200, 0x070ff088,
+	0x0179feff, 0x070fffff, 0x04818501, 0x060ff083,
+	0x0086836d, 0x033e6000, 0x07000003, 0x068d0352,
+	0x07286000, 0x07f00000, 0x078d0355, 0x038c0306,
+	0x0648c0e6, 0x05818372, 0x0448e0e6, 0x0781036a,
+	0x004920e6, 0x07810365, 0x07a0056f, 0x05001088,
+	0x00700101, 0x03100000, 0x00088001, 0x033e6000,
+	0x07000088, 0x03800560, 0x02386001, 0x07030000,
+	0x033e6000, 0x06000008, 0x028003f1, 0x02799075,
+	0x0500040f, 0x06810010, 0x06601479, 0x050080ff,
+	0x06309052, 0x0600003e, 0x02800376, 0x06602279,
+	0x050080ff, 0x05309812, 0x07000041, 0x0648007a,
+	0x0781037e, 0x04488075, 0x0581837e, 0x040f8008,
+	0x070fa009, 0x0049107a, 0x01a183f3, 0x00798075,
+	0x06000507, 0x05818521, 0x0448b075, 0x06810385,
+	0x02493075, 0x0681050e, 0x0249c0e6, 0x048183e0,
+	0x0648c0e6, 0x0581839a, 0x068d0389, 0x02386001,
+	0x07030000, 0x0049107a, 0x07810390, 0x020ef083,
+	0x0386039a, 0x06483075, 0x068103ef, 0x0678007a,
+	0x07000035, 0x03a184cf, 0x05308000, 0x07060000,
+	0x06009079, 0x04a004dc, 0x028003ef, 0x0448807a,
+	0x0681039e, 0x06483075, 0x058104f9, 0x0448d07a,
+	0x068103a2, 0x06483075, 0x058104f9, 0x068d03a2,
+	0x02386001, 0x07030000, 0x0444e07a, 0x0648307a,
+	0x048183c7, 0x0448707a, 0x068103ea, 0x0648f07a,
+	0x078103b2, 0x05a004cf, 0x04008079, 0x05a004ee,
+	0x008683c2, 0x05a004d8, 0x028003ef, 0x0560107b,
+	0x050f80ff, 0x032fa009, 0x0349c000, 0x058183c0,
+	0x04600e79, 0x050f80ff, 0x073fa00a, 0x0600003d,
+	0x06600a79, 0x050f80ff, 0x053fa80a, 0x06000010,
+	0x028003ef, 0x0046e07a, 0x028003ea, 0x06009008,
+	0x05308000, 0x05004000, 0x04a004dc, 0x028003ef,
+	0x0560167b, 0x050f80ff, 0x032fa011, 0x070ff000,
+	0x04500401, 0x030460ff, 0x060ff025, 0x00540446,
+	0x078203d1, 0x030460ff, 0x04092046, 0x05a00218,
+	0x06600679, 0x050f80ff, 0x00201007, 0x012fa80a,
+	0x0046047a, 0x034630ff, 0x050020ff, 0x06003051,
+	0x04600e79, 0x050f80ff, 0x073fa012, 0x06000001,
+	0x028003ef, 0x033e6a00, 0x0202000e, 0x02079051,
+	0x07000088, 0x078d03e4, 0x0744c000, 0x01088000,
+	0x03386006, 0x03010000, 0x02800010, 0x05a004cf,
+	0x05308000, 0x03020000, 0x06009079, 0x04a004dc,
+	0x033e6a00, 0x0302000a, 0x02079051, 0x02800010,
+	0x04603e79, 0x050f80ff, 0x032fa009, 0x070ff000,
+	0x0186040c, 0x057dfeff, 0x07ffffff, 0x0581040c,
+	0x050f8000, 0x012fa811, 0x0079fe02, 0x070000ff,
+	0x077d66ff, 0x060000dc, 0x0781840c, 0x060ff001,
+	0x0286840d, 0x064b0002, 0x06420002, 0x060ff002,
+	0x05500400, 0x050f80ff, 0x05004084, 0x073fa00a,
+	0x06000002, 0x07c00000, 0x04600201, 0x050f80ff,
+	0x073fa009, 0x06000001, 0x0079fe02, 0x070000ff,
+	0x077d72ff, 0x070000dd, 0x0781840c, 0x064b0002,
+	0x06420002, 0x06000001, 0x01800406, 0x0605004c,
+	0x0180041e, 0x0493041a, 0x04a004d5, 0x054bc450,
+	0x05810421, 0x01d00422, 0x01800421, 0x00800432,
+	0x00800434, 0x00800432, 0x008004a7, 0x0180043f,
+	0x00800434, 0x01800471, 0x00800432, 0x00800432,
+	0x008004ab, 0x00800432, 0x018004af, 0x008004c4,
+	0x01800488, 0x00800432, 0x00800432, 0x00209432,
+	0x018004e4, 0x0379ff50, 0x070fffff, 0x060ff079,
+	0x055c0450, 0x048104a4, 0x002fb008, 0x060ff079,
+	0x055c0450, 0x058104a3, 0x04a004c7, 0x0180049c,
+	0x0179fe50, 0x070fffff, 0x070050ff, 0x060ff079,
+	0x055c0405, 0x04810449, 0x002fb008, 0x060ff079,
+	0x055c0405, 0x078184a0, 0x070ff087, 0x017980ff,
+	0x06000507, 0x06818451, 0x02203040, 0x05002087,
+	0x0049d002, 0x0481046b, 0x04930458, 0x01257000,
+	0x073c3fff, 0x0700000f, 0x052e4003, 0x072e5030,
+	0x0304c050, 0x02400057, 0x06740057, 0x06000002,
+	0x06820016, 0x04002083, 0x07003084, 0x04004085,
+	0x06602279, 0x050f80ff, 0x063fa01a, 0x06000001,
+	0x05a004cf, 0x07a00578, 0x033e6a00, 0x0302000a,
+	0x062e5020, 0x003e4002, 0x07000a00, 0x028003f1,
+	0x07420003, 0x0781844e, 0x00798002, 0x06000507,
+	0x06818451, 0x0180045c, 0x05930478, 0x01257000,
+	0x073c3fff, 0x0700000f, 0x052e4003, 0x072e5030,
+	0x0304c050, 0x067800e6, 0x07000041, 0x0581047d,
+	0x07a00581, 0x04818016, 0x002fb008, 0x067800e6,
+	0x07000041, 0x04810483, 0x07a00581, 0x04818016,
+	0x062e5020, 0x003e4002, 0x07000a00, 0x03e00000,
+	0x02800010, 0x0379ff50, 0x070fffff, 0x060ff079,
+	0x055c0450, 0x0781848e, 0x0245507a, 0x002fb008,
+	0x060ff079, 0x055c0450, 0x07818493, 0x0245507a,
+	0x002fb008, 0x05600e50, 0x050f80ff, 0x012fa809,
+	0x02455001, 0x05600e50, 0x050f80ff, 0x012fa80a,
+	0x0080049d, 0x002fb008, 0x003e4002, 0x07000a00,
+	0x02800016, 0x079384a3, 0x062e5020, 0x042e4002,
+	0x002fb008, 0x013e4000, 0x05000e00, 0x02800016,
+	0x0179fe50, 0x070fffff, 0x010210ff, 0x02800016,
+	0x0179fe50, 0x070fffff, 0x050340ff, 0x0080049d,
+	0x0179fe50, 0x070fffff, 0x0102e0ff, 0x0760282e,
+	0x050f80ff, 0x05222000, 0x07223000, 0x05224000,
+	0x07225000, 0x07226000, 0x05227000, 0x05228000,
+	0x07229000, 0x0722a000, 0x0522b000, 0x063fa051,
+	0x07000011, 0x0202c026, 0x0522d000, 0x052e400c,
+	0x02800016, 0x030430d4, 0x062e5008, 0x00800176,
+	0x05600e50, 0x050f80ff, 0x032fa009, 0x03460000,
+	0x018004d2, 0x0246007a, 0x0045207a, 0x008004d0,
+	0x0246007a, 0x0600007a, 0x04600e79, 0x050f80ff,
+	0x032fa00a, 0x07c00000, 0x029284d5, 0x070500e1,
+	0x07c00000, 0x0245f008, 0x048404d9, 0x020e0008,
+	0x07c00000, 0x070ff009, 0x065a0008, 0x058404de,
+	0x020e0008, 0x07c00000, 0x058404e1, 0x020e0008,
+	0x07c00000, 0x05308000, 0x0500d000, 0x04a004dc,
+	0x04a004e9, 0x02800010, 0x052e4300, 0x072e500c,
+	0x073c3fff, 0x0700000f, 0x07c00000, 0x06602208,
+	0x050f80ff, 0x032fa011, 0x076a0000, 0x068184f7,
+	0x066a0001, 0x048104f7, 0x04002051, 0x07c00000,
+	0x00202001, 0x07c00000, 0x0648307a, 0x00a18608,
+	0x05a004cc, 0x05308000, 0x05001000, 0x06009079,
+	0x04a004dc, 0x03800560, 0x0249c0e6, 0x058104f9,
+	0x0280036d, 0x0648307a, 0x07818196, 0x05a004cf,
+	0x05308000, 0x03013000, 0x03209006, 0x04a004dc,
+	0x033e6000, 0x07030000, 0x02800345, 0x02490075,
+	0x0781051e, 0x04002089, 0x04780102, 0x07f00000,
+	0x05001088, 0x07a0056f, 0x04740101, 0x03100000,
+	0x060ff002, 0x045c0401, 0x0481851f, 0x00088001,
+	0x033e6000, 0x070000c0, 0x0380055c, 0x07f00000,
+	0x0220951f, 0x018004e4, 0x0648307a, 0x07810527,
+	0x06780075, 0x06000007, 0x0581852e, 0x06a00608,
+	0x06486075, 0x06818194, 0x02490075, 0x0781819a,
+	0x04487075, 0x05818536, 0x0280053d, 0x05308000,
+	0x03010000, 0x06009079, 0x04a004dc, 0x02800010,
+	0x0448e0e6, 0x04818352, 0x00800192, 0x05308000,
+	0x0500e000, 0x06009079, 0x04a004dc, 0x04008089,
+	0x05a004e1, 0x0380055c, 0x05a004cc, 0x05308000,
+	0x0700f000, 0x06009079, 0x07000088, 0x06a00545,
+	0x04a004dc, 0x02800010, 0x03386000, 0x07030000,
+	0x07f00000, 0x078d0548, 0x033e6a00, 0x0202000e,
+	0x02079051, 0x0448b075, 0x07810553, 0x02493075,
+	0x07810553, 0x05301005, 0x03010000, 0x03800555,
+	0x05301006, 0x03010000, 0x05002087, 0x06485002,
+	0x05818555, 0x0744c000, 0x01088000, 0x02086001,
+	0x07c00000, 0x05001088, 0x07a0056f, 0x0644c001,
+	0x00088001, 0x033e6a00, 0x0202000e, 0x004920e6,
+	0x05818565, 0x02079051, 0x078d0565, 0x060ff089,
+	0x034990ff, 0x0781056c, 0x03386005, 0x03010000,
+	0x02800010, 0x03386006, 0x03010000, 0x02800010,
+	0x078d056f, 0x03386000, 0x07030000, 0x07f00000,
+	0x068d0573, 0x070ff087, 0x074850ff, 0x05818574,
+	0x07c00000, 0x078d0578, 0x02386001, 0x07030000,
+	0x07f00000, 0x068d057c, 0x070ff087, 0x074850ff,
+	0x0581857d, 0x07c00000, 0x05002087, 0x0049d002,
+	0x05818590, 0x002fb008, 0x067800e6, 0x07000041,
+	0x002fb008, 0x05818590, 0x07a005a6, 0x0448e002,
+	0x07810593, 0x0648a002, 0x0481859d, 0x06486002,
+	0x06810597, 0x02400057, 0x056a02ff, 0x07c00000,
+	0x07a005a6, 0x06788102, 0x06000004, 0x05818590,
+	0x04002089, 0x070ff0d4, 0x045c0402, 0x077800ff,
+	0x07f00000, 0x05818590, 0x00202010, 0x038c0590,
+	0x07f00000, 0x06420002, 0x0481859e, 0x07a00578,
+	0x033e6a00, 0x0302000a, 0x07c00000, 0x07f00000,
+	0x060ff0a2, 0x050020ff, 0x060ff0a2, 0x045c0402,
+	0x048185a7, 0x07c00000, 0x05a00218, 0x03495047,
+	0x078105b2, 0x0320901d, 0x02800604, 0x0220901f,
+	0x02800604, 0x014980e4, 0x04818010, 0x013e4000,
+	0x07003000, 0x05600e35, 0x050f80ff, 0x07a006fc,
+	0x01208003, 0x05a004e1, 0x038005cc, 0x03209009,
+	0x02800604, 0x03209011, 0x02800604, 0x02209007,
+	0x02800604, 0x03209003, 0x02800604, 0x00498043,
+	0x058185be, 0x00497043, 0x048185c2, 0x02209001,
+	0x02800604, 0x0220900d, 0x02800604, 0x0320900f,
+	0x02800604, 0x03493000, 0x068105d5, 0x027c0045,
+	0x070a0000, 0x078105de, 0x0220900b, 0x02800604,
+	0x02209013, 0x05308000, 0x01012000, 0x04a004dc,
+	0x00800183, 0x03209005, 0x02800604, 0x072e500c,
+	0x00208002, 0x05a004e1, 0x02800010, 0x02209015,
+	0x02800604, 0x072d6000, 0x05308000, 0x05007000,
+	0x07f00000, 0x070090d1, 0x0379ff09, 0x0700ffff,
+	0x04a004dc, 0x03209017, 0x02800604, 0x033e5000,
+	0x06000080, 0x02209019, 0x02800604, 0x072d6000,
+	0x033e5000, 0x06000080, 0x07f00000, 0x060ff0d0,
+	0x0179feff, 0x0700ffff, 0x057dfeff, 0x0700ffff,
+	0x04818010, 0x02400058, 0x00642058, 0x06820010,
+	0x033e5000, 0x06000080, 0x04058051, 0x0320901b,
+	0x02800604, 0x05308000, 0x01012000, 0x04a004dc,
+	0x00800176, 0x05a00218, 0x05308000, 0x05008000,
+	0x06009079, 0x04a004dc, 0x07c00000, 0x034900e4,
+	0x05818618, 0x013e4000, 0x070000c0, 0x07f00000,
+	0x034900e4, 0x04818616, 0x07c00000, 0x013e4000,
+	0x06000080, 0x07f00000, 0x07f00000, 0x07f00000,
+	0x034900e4, 0x06810610, 0x03800618, 0x072d6000,
+	0x00498043, 0x06810632, 0x060ff0d0, 0x0179feff,
+	0x0700ffff, 0x057dfeff, 0x0700ffff, 0x058185e2,
+	0x050f8030, 0x032fa009, 0x0379ff00, 0x0700ffff,
+	0x070ff0d1, 0x0179feff, 0x0700ffff, 0x055c0400,
+	0x078105e2, 0x04004051, 0x0280067a, 0x06a006dc,
+	0x062d6001, 0x020ef004, 0x038605e4, 0x06600004,
+	0x050f80ff, 0x032fa009, 0x074b0000, 0x05002000,
+	0x0769ff00, 0x01640800, 0x078205e4, 0x01640e00,
+	0x058285e4, 0x070ff036, 0x045c0404, 0x0581864d,
+	0x072d6000, 0x050f8030, 0x032fa009, 0x0379ff00,
+	0x0700ffff, 0x070ff0d1, 0x0179feff, 0x0700ffff,
+	0x055c0400, 0x078105e2, 0x04482034, 0x078105ff,
+	0x06483034, 0x058185ff, 0x070ff0d4, 0x077800ff,
+	0x070000f0, 0x037c00ff, 0x06000010, 0x0681067a,
+	0x06a006d6, 0x024900e5, 0x0681065d, 0x033e5000,
+	0x06000080, 0x02800010, 0x04601c04, 0x050f80ff,
+	0x053fa809, 0x06000020, 0x030ef041, 0x038605ee,
+	0x062d6002, 0x05602a41, 0x050f80ff, 0x012fa809,
+	0x060ff0d0, 0x074b00ff, 0x045c0401, 0x05818678,
+	0x062d6001, 0x07602841, 0x050f80ff, 0x053fa809,
+	0x06000001, 0x070ff0d1, 0x054b80ff, 0x074b0003,
+	0x055c0403, 0x05818678, 0x033e5000, 0x06000080,
+	0x0080070e, 0x07600041, 0x0280065e, 0x06a006d6,
+	0x024900e5, 0x06810680, 0x033e5000, 0x06000080,
+	0x02800010, 0x06a006c2, 0x030ef041, 0x028605f2,
+	0x04058051, 0x072d6000, 0x05601041, 0x050f80ff,
+	0x012fa809, 0x0600a0d0, 0x0500b0d1, 0x062d6001,
+	0x07f00000, 0x07f00000, 0x0600c0d0, 0x0500d0d1,
+	0x062d6002, 0x0279ff0d, 0x07ff0000, 0x044d800d,
+	0x060ff0d0, 0x074b00ff, 0x065a000d, 0x06601201,
+	0x050f80ff, 0x073fa022, 0x07000005, 0x0079fe0d,
+	0x070000ff, 0x050020ff, 0x05602a41, 0x050f80ff,
+	0x073fa00a, 0x06000001, 0x020ef004, 0x028606bf,
+	0x04601c04, 0x050f80ff, 0x053fa809, 0x06000001,
+	0x050f80ff, 0x053fa80a, 0x06000020, 0x07602841,
+	0x050f80ff, 0x073fa009, 0x06000001, 0x0279ff02,
+	0x070000ff, 0x0678000d, 0x0700ff00, 0x065a0002,
+	0x07602841, 0x050f80ff, 0x073fa00a, 0x06000001,
+	0x07600041, 0x050f80ff, 0x053fa80a, 0x06000001,
+	0x07601241, 0x050f80ff, 0x073fa00a, 0x06000002,
+	0x033e5000, 0x06000080, 0x0080070e, 0x040f8032,
+	0x073fa011, 0x06000001, 0x060ff002, 0x055c0403,
+	0x058186ca, 0x00041051, 0x07c00000, 0x04600402,
+	0x04500432, 0x050f80ff, 0x053fa809, 0x06000020,
+	0x00400402, 0x01680eff, 0x070030ff, 0x040f8032,
+	0x053fa80a, 0x06000001, 0x07c00000, 0x024900e5,
+	0x068106d9, 0x07c00000, 0x033e5000, 0x070000c0,
+	0x07c00000, 0x05004036, 0x060000d0, 0x0179fe00,
+	0x0700ffff, 0x057dfeff, 0x0700ffff, 0x068106fb,
+	0x070000d1, 0x0379ff00, 0x0700ffff, 0x06005051,
+	0x060ff031, 0x05500405, 0x050f80ff, 0x073fa009,
+	0x06000002, 0x020ef004, 0x038606f5, 0x04600404,
+	0x050f80ff, 0x012fa809, 0x0079fe01, 0x0700ffff,
+	0x055c0400, 0x068106fb, 0x01400405, 0x070050ff,
+	0x057de0ff, 0x06000007, 0x058186e7, 0x04004051,
+	0x07c00000, 0x072d6000, 0x07f00000, 0x07f00000,
+	0x000110d0, 0x010120d1, 0x062d6001, 0x07f00000,
+	0x07f00000, 0x020130d0, 0x010140d1, 0x062d6002,
+	0x010170d4, 0x07f00000, 0x020150d0, 0x030160d1,
+	0x053fa83a, 0x06000008, 0x07c00000, 0x07600c41,
+	0x050f80ff, 0x073fa009, 0x06000001, 0x04780102,
+	0x07ffff00, 0x046a0702, 0x050f80ff, 0x073fa00a,
+	0x06000001, 0x05600e41, 0x050f80ff, 0x032fa069,
+	0x03800053, 0xba6b4e34, 0x02800004, 0x00000000,
+	0x00008000, 0x00000518, 0x040f801f, 0x012fa8c9,
+	0x040f801f, 0x073fa081, 0x06000010, 0x03200005,
+	0x07420000, 0x050fb000, 0x040f801f, 0x073fa011,
+	0x06000038, 0x040f801f, 0x053fa859, 0x0700003a,
+	0x050fe000, 0x0581800a, 0x0684003d, 0x04958019,
+	0x030e0011, 0x072e4200, 0x03800014, 0x0291001f,
+	0x050010c0, 0x04482001, 0x058180e8, 0x06483001,
+	0x0781814b, 0x02920029, 0x068b0029, 0x018a0150,
+	0x050010c0, 0x06780001, 0x050007c0, 0x06818223,
+	0x06780001, 0x0500f800, 0x07818263, 0x03910030,
+	0x040fe029, 0x03860030, 0x076c001d, 0x04810294,
+	0x076c0a1d, 0x048102b9, 0x0292003d, 0x040fe02f,
+	0x0286003d, 0x06000013, 0x050fb000, 0x066c0073,
+	0x068103c2, 0x0297003d, 0x014920e4, 0x0481803d,
+	0x03400000, 0x076c0a00, 0x04818034, 0x0796003f,
+	0x03b900b8, 0x05908014, 0x010170e1, 0x07780017,
+	0x03e00000, 0x06810092, 0x050010ff, 0x0179fe17,
+	0x031fffff, 0x070000ff, 0x05600800, 0x050f80ff,
+	0x073fa009, 0x06000001, 0x06780002, 0x02800040,
+	0x037c00ff, 0x03800000, 0x0681005e, 0x0249f002,
+	0x068100ab, 0x0448e002, 0x0681005e, 0x07600c00,
+	0x050f80ff, 0x073fa009, 0x06000001, 0x06780002,
+	0x07ffff00, 0x037c00ff, 0x05000200, 0x048180ab,
+	0x064bd401, 0x03d00060, 0x038000a9, 0x02800068,
+	0x03800072, 0x0280007c, 0x02800086, 0x03800090,
+	0x038000a9, 0x038000a9, 0x050fe027, 0x0186806c,
+	0x01028000, 0x0380006f, 0x07600027, 0x050f80ff,
+	0x032fa00a, 0x01027000, 0x02400029, 0x028000ab,
+	0x040fe025, 0x00868076, 0x03026000, 0x02800079,
+	0x06600025, 0x050f80ff, 0x032fa00a, 0x03025000,
+	0x02400029, 0x028000ab, 0x050fe021, 0x00868080,
+	0x01022000, 0x02800083, 0x07600021, 0x050f80ff,
+	0x032fa00a, 0x01021000, 0x02400029, 0x028000ab,
+	0x040fe023, 0x0086808a, 0x01024000, 0x0380008d,
+	0x06600023, 0x050f80ff, 0x032fa00a, 0x03023000,
+	0x02400029, 0x028000ab, 0x06a000c8, 0x028000ab,
+	0x01640817, 0x058280a9, 0x070ff017, 0x03d00096,
+	0x0280009e, 0x038000a0, 0x038000a3, 0x038000a6,
+	0x038000a9, 0x038000a9, 0x038000a9, 0x038000a9,
+	0x03e00000, 0x03800014, 0x059080a0, 0x030160e1,
+	0x028000ab, 0x059080a3, 0x030150e1, 0x028000ab,
+	0x059080a6, 0x010140e1, 0x028000ab, 0x060fc013,
+	0x06a00510, 0x03800014, 0x072e4800, 0x07000012,
+	0x038000bb, 0x0747f000, 0x05600800, 0x050f80ff,
+	0x012fa809, 0x0249f001, 0x078100bb, 0x01012000,
+	0x052e4c00, 0x07c00000, 0x070000eb, 0x0349f000,
+	0x058180af, 0x05600800, 0x050f80ff, 0x012fa809,
+	0x0448e001, 0x068100c1, 0x07c00000, 0x0079c101,
+	0x07ffffff, 0x027a4b01, 0x03800000, 0x05600800,
+	0x050f80ff, 0x012fa80a, 0x07600c00, 0x050f80ff,
+	0x012fa821, 0x06780001, 0x07ffff00, 0x037c00ff,
+	0x05000700, 0x078100dd, 0x06601804, 0x070030ff,
+	0x050f80ff, 0x012fa809, 0x05002000, 0x050f8003,
+	0x073fa00a, 0x06000001, 0x040fe001, 0x038600de,
+	0x04600201, 0x050f80ff, 0x032fa00a, 0x07c00000,
+	0x050fe02e, 0x008680e3, 0x0102e000, 0x0302f000,
+	0x038000e7, 0x0760002e, 0x050f80ff, 0x032fa00a,
+	0x0102e000, 0x07c00000, 0x022c0004, 0x056c041d,
+	0x078100fc, 0x056c021d, 0x04810113, 0x056c081d,
+	0x04810125, 0x076c061d, 0x0581013f, 0x0521d000,
+	0x0202c013, 0x0202a013, 0x02020013, 0x0460021a,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x03b600ac,
+	0x0484801f, 0x0280003d, 0x040fe02a, 0x028600f2,
+	0x06000013, 0x04001013, 0x0560102b, 0x050f80ff,
+	0x032fa012, 0x06420029, 0x0660002a, 0x050f80ff,
+	0x053fa809, 0x06000001, 0x050fe003, 0x00860110,
+	0x01028003, 0x0660002a, 0x050f80ff, 0x053fa80a,
+	0x07000009, 0x00800140, 0x00028013, 0x00027013,
+	0x00800140, 0x040fe02a, 0x028600f1, 0x06420029,
+	0x0660002a, 0x050f80ff, 0x053fa809, 0x06000001,
+	0x050fe003, 0x01860122, 0x03026003, 0x0660002a,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x00800140,
+	0x02026013, 0x02025013, 0x00800140, 0x040fe02a,
+	0x028600f1, 0x06420029, 0x0660002a, 0x050f80ff,
+	0x053fa809, 0x06000001, 0x050fe003, 0x00860134,
+	0x01022003, 0x0660002a, 0x050f80ff, 0x053fa80a,
+	0x07000009, 0x01800136, 0x00022013, 0x00021013,
+	0x0647f020, 0x007a0120, 0x04000101, 0x04a00285,
+	0x0400802a, 0x05a004f5, 0x009480f1, 0x0521d005,
+	0x028000f2, 0x038000fa, 0x0647f020, 0x06486020,
+	0x06818145, 0x04a00285, 0x028000f1, 0x007a0120,
+	0x04000101, 0x04a00285, 0x0400802a, 0x05a004f5,
+	0x028000f1, 0x040fd02a, 0x052e4003, 0x00208010,
+	0x05a004f5, 0x038000fa, 0x00018098, 0x07480018,
+	0x06818161, 0x05481018, 0x0781815f, 0x05482018,
+	0x0681815d, 0x07483018, 0x0681815b, 0x002fb004,
+	0x00800162, 0x012fb003, 0x00800162, 0x002fb002,
+	0x00800162, 0x002fb001, 0x00800162, 0x012fb000,
+	0x0179fe78, 0x070000ff, 0x030190ff, 0x00017086,
+	0x058b0166, 0x03385000, 0x03020000, 0x07780017,
+	0x00430407, 0x078181ee, 0x046c0419, 0x048101a2,
+	0x046c0219, 0x05810172, 0x07219000, 0x00800186,
+	0x07219000, 0x07483017, 0x0481018c, 0x05482017,
+	0x05810193, 0x0448b075, 0x06818186, 0x06601476,
+	0x050f80ff, 0x073fa022, 0x0600003e, 0x06000080,
+	0x05001081, 0x05002082, 0x06003083, 0x05004084,
+	0x04601c76, 0x050f80ff, 0x022fa02a, 0x07219000,
+	0x07780078, 0x07ffff00, 0x045a0419, 0x010780ff,
+	0x0484801f, 0x0280003d, 0x040fe07f, 0x0086019b,
+	0x05a001bb, 0x00920186, 0x040fe07f, 0x07a681bb,
+	0x00800186, 0x0560107b, 0x050f80ff, 0x032fa009,
+	0x0744f000, 0x0560107b, 0x050f80ff, 0x032fa00a,
+	0x00800179, 0x052e400c, 0x040080fb, 0x046aa108,
+	0x06009076, 0x04002075, 0x05a004fc, 0x00800186,
+	0x06219001, 0x05482017, 0x058101af, 0x058b01a5,
+	0x060ff086, 0x0349f0ff, 0x07818165, 0x07483017,
+	0x058101ac, 0x050fd0ff, 0x040fe07f, 0x07a681bb,
+	0x00800186, 0x05004084, 0x05a00205, 0x00920186,
+	0x070ff07d, 0x0450047c, 0x056004ff, 0x050f80ff,
+	0x032fa009, 0x070ff000, 0x00540479, 0x030790ff,
+	0x01800193, 0x060ff079, 0x0054047a, 0x058201e7,
+	0x058101e7, 0x070ff07d, 0x0450047c, 0x050f80ff,
+	0x002fa819, 0x058b01c3, 0x02080001, 0x00081002,
+	0x01082003, 0x048b01c7, 0x03385000, 0x03010000,
+	0x02400019, 0x070ff003, 0x04500479, 0x030790ff,
+	0x0340007e, 0x0642007f, 0x058101e7, 0x070ff07e,
+	0x050f80ff, 0x032fa009, 0x050fe000, 0x028681e6,
+	0x070ff07d, 0x056002ff, 0x050f80ff, 0x032fa009,
+	0x0107d000, 0x018601e8, 0x0560087d, 0x050f80ff,
+	0x032fa009, 0x0569fe00, 0x0550041b, 0x050f80ff,
+	0x032fa009, 0x0107e000, 0x070ff07e, 0x018001d2,
+	0x0307c000, 0x07c00000, 0x052e400c, 0x040080fb,
+	0x046aa108, 0x06009076, 0x04002075, 0x018004fc,
+	0x040fd076, 0x050fd017, 0x060ff086, 0x077800ff,
+	0x07000060, 0x037c00ff, 0x07000060, 0x078181f0,
+	0x07780078, 0x07ffff00, 0x045a0419, 0x010780ff,
+	0x06601476, 0x050f80ff, 0x073fa022, 0x0600003e,
+	0x052e400c, 0x040080fb, 0x066a8108, 0x06009076,
+	0x04002075, 0x05a004fc, 0x02800029, 0x0240007f,
+	0x0742007e, 0x050f807e, 0x032fa009, 0x050fe000,
+	0x0286821f, 0x070ff07d, 0x055c047b, 0x05810214,
+	0x0760007d, 0x050f80ff, 0x032fa009, 0x050fe000,
+	0x03868214, 0x070ff07b, 0x0107d0ff, 0x0560087d,
+	0x050f80ff, 0x032fa009, 0x03681e00, 0x0450041c,
+	0x0107e0ff, 0x050f80ff, 0x032fa009, 0x050fe000,
+	0x01860221, 0x0307c000, 0x07c00000, 0x040fd076,
+	0x02800510, 0x010180c0, 0x0548e018, 0x0781823c,
+	0x0748f018, 0x06818238, 0x03490018, 0x06818234,
+	0x01491018, 0x07818230, 0x073c0000, 0x06000040,
+	0x02200004, 0x0180023f, 0x073c0000, 0x06000020,
+	0x03200003, 0x0180023f, 0x073c0000, 0x06000010,
+	0x02200002, 0x0180023f, 0x073c0000, 0x06000008,
+	0x02200001, 0x0180023f, 0x073c0000, 0x06000004,
+	0x06000013, 0x050fb000, 0x040fe076, 0x00860258,
+	0x046c0273, 0x04810268, 0x066c0073, 0x04810249,
+	0x040fd076, 0x06a00510, 0x03800014, 0x040fd076,
+	0x0080024c, 0x00452075, 0x00077013, 0x0647f075,
+	0x06486075, 0x06818252, 0x05a0028b, 0x00800258,
+	0x007a0175, 0x04000101, 0x05a0028b, 0x04008076,
+	0x0245f008, 0x05a004f5, 0x07273000, 0x05600272,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x0379ff78,
+	0x070000ff, 0x02076013, 0x02075013, 0x0484801f,
+	0x0280003d, 0x070fc0ff, 0x052e400c, 0x00208020,
+	0x05a004f5, 0x00800261, 0x04600276, 0x050010ff,
+	0x040f8001, 0x032fa009, 0x040f8001, 0x053fa80a,
+	0x07000009, 0x070ff000, 0x0286827a, 0x06601276,
+	0x050f80ff, 0x073fa009, 0x0700000c, 0x07601818,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x0180027b,
+	0x07a000de, 0x0448b075, 0x0581024b, 0x06000013,
+	0x04001013, 0x0560107b, 0x050f80ff, 0x032fa012,
+	0x0046b075, 0x03b600ac, 0x0080024c, 0x06000020,
+	0x04001016, 0x0460082a, 0x050f80ff, 0x032fa012,
+	0x07c00000, 0x06000075, 0x040010a2, 0x044b0801,
+	0x060ff016, 0x065a0001, 0x04600876, 0x050f80ff,
+	0x032fa012, 0x07c00000, 0x050fe022, 0x0186029a,
+	0x0421d004, 0x0302a022, 0x04a002c1, 0x018002b1,
+	0x040fe026, 0x008602b3, 0x0421d001, 0x0202a026,
+	0x04a002c1, 0x0202c013, 0x00683e20, 0x070060ff,
+	0x056c0206, 0x048102f4, 0x056c0406, 0x0781030a,
+	0x076c0606, 0x06810379, 0x056c1606, 0x078182b1,
+	0x04488020, 0x07810387, 0x040fd02a, 0x0521d000,
+	0x0202a013, 0x02020013, 0x008002b3, 0x04a004ec,
+	0x008002bf, 0x050fe028, 0x008602bf, 0x0302a028,
+	0x0421d002, 0x04a002c1, 0x008002c8, 0x050fe022,
+	0x008602bf, 0x0421d004, 0x0302a022, 0x04a002c1,
+	0x04a004ec, 0x05848030, 0x0280003d, 0x0460082a,
+	0x050f80ff, 0x022fa031, 0x03020000, 0x0002b004,
+	0x01018005, 0x07c00000, 0x0400702a, 0x06a003ba,
+	0x007a0101, 0x07060000, 0x07303000, 0x07008290,
+	0x07600018, 0x050f80ff, 0x053fa809, 0x07000003,
+	0x0448e007, 0x068182d6, 0x06006013, 0x018002dd,
+	0x02400010, 0x048102d6, 0x06006010, 0x0460322a,
+	0x050f80ff, 0x073fa00a, 0x07000003, 0x050f801e,
+	0x032fa03a, 0x063aa020, 0x06000002, 0x013e4000,
+	0x07000030, 0x009802e3, 0x070ff0f6, 0x036830ff,
+	0x078182e4, 0x070f001e, 0x0560102b, 0x050f10ff,
+	0x063f3c08, 0x0600000d, 0x013e4000, 0x06000020,
+	0x040f801a, 0x0320000a, 0x022017d0, 0x032fa012,
+	0x0202c013, 0x008002bf, 0x04007013, 0x06a003ba,
+	0x007a0101, 0x07050000, 0x07303000, 0x07008890,
+	0x074d0005, 0x06006013, 0x050f801e, 0x032fa03a,
+	0x05601a2b, 0x050f80ff, 0x022fa019, 0x04001002,
+	0x04002013, 0x040f801f, 0x022fa01a, 0x073aa00c,
+	0x06000002, 0x07300c03, 0x0600000d, 0x028003a7,
+	0x04007013, 0x06a003ba, 0x007a0101, 0x03070000,
+	0x0660282a, 0x050f80ff, 0x073fa009, 0x06000004,
+	0x02499008, 0x07810317, 0x07303000, 0x07008890,
+	0x02800319, 0x07303000, 0x04008980, 0x05007003,
+	0x074d0005, 0x06006013, 0x050f801e, 0x032fa03a,
+	0x0760142b, 0x050f80ff, 0x032fa021, 0x064b0002,
+	0x02499008, 0x06810325, 0x0644c002, 0x054b0400,
+	0x050040ff, 0x06698104, 0x0581833a, 0x06000013,
+	0x04001013, 0x04780102, 0x06000010, 0x06003013,
+	0x04004013, 0x06005013, 0x06006013, 0x04007013,
+	0x00644015, 0x07820336, 0x04448002, 0x02205008,
+	0x040f801f, 0x032fa042, 0x04008015, 0x03800371,
+	0x046c8004, 0x05818348, 0x01208018, 0x06780002,
+	0x07000003, 0x0581834b, 0x06003001, 0x06000013,
+	0x04001013, 0x04004013, 0x06005013, 0x040f801f,
+	0x022fa032, 0x03800371, 0x040fd02a, 0x06a00510,
+	0x03800014, 0x04488002, 0x07810350, 0x070ff003,
+	0x04500408, 0x050080ff, 0x06489002, 0x06810357,
+	0x0379ff00, 0x070000ff, 0x070ff000, 0x04500408,
+	0x050080ff, 0x07005003, 0x05004000, 0x06003001,
+	0x06000013, 0x04001013, 0x040f801f, 0x022fa032,
+	0x05601c2b, 0x050f80ff, 0x022fa031, 0x06600c1f,
+	0x050f80ff, 0x022fa032, 0x02680608, 0x07810371,
+	0x016408ff, 0x057dfeff, 0x07ffffff, 0x034000ff,
+	0x045a0407, 0x070000ff, 0x0760061e, 0x050f80ff,
+	0x032fa00a, 0x06600908, 0x0669f908, 0x027a0008,
+	0x06000020, 0x070aa0ff, 0x014a20ff, 0x037a00ff,
+	0x060000dc, 0x070000ff, 0x028003a7, 0x04007013,
+	0x06a003ba, 0x007a0101, 0x07030000, 0x07303000,
+	0x07008190, 0x06006013, 0x050f801e, 0x032fa03a,
+	0x073aa000, 0x06000002, 0x07300c00, 0x07000005,
+	0x028003a7, 0x04007013, 0x06a003ba, 0x007a0101,
+	0x07810000, 0x07303000, 0x07000090, 0x06006013,
+	0x06600c2a, 0x050f80ff, 0x053fa809, 0x07000003,
+	0x04780107, 0x07ffff00, 0x007c0107, 0x07000500,
+	0x0581839a, 0x07303000, 0x05000890, 0x074d0005,
+	0x0660282a, 0x050f80ff, 0x053fa809, 0x07000003,
+	0x0049d007, 0x068103a1, 0x02206001, 0x050f801e,
+	0x032fa03a, 0x073aa000, 0x06000002, 0x07300c00,
+	0x07000005, 0x013e4000, 0x07000030, 0x039803a9,
+	0x070ff0f6, 0x036830ff, 0x058183aa, 0x070f001e,
+	0x040f101f, 0x070f3000, 0x013e4000, 0x06000020,
+	0x040f801a, 0x0320000a, 0x022017d0, 0x032fa012,
+	0x008002bf, 0x03200000, 0x06006076, 0x028003bc,
+	0x03200011, 0x0600602a, 0x05a00441, 0x05600406,
+	0x050f80ff, 0x053fa809, 0x06000002, 0x07c00000,
+	0x0207602f, 0x04600876, 0x050f80ff, 0x022fa031,
+	0x03075000, 0x0007b004, 0x01018005, 0x06600076,
+	0x050020ff, 0x050f80ff, 0x012fa809, 0x0202f001,
+	0x008683d0, 0x0002e013, 0x040f8002, 0x053fa80a,
+	0x07000009, 0x06273001, 0x0448b075, 0x048183da,
+	0x04602076, 0x050f80ff, 0x053fa811, 0x0700003c,
+	0x0179fe78, 0x070000ff, 0x030190ff, 0x018683e2,
+	0x07a003f6, 0x00078019, 0x039203f5, 0x0180043a,
+	0x040fd076, 0x040fd019, 0x04600276, 0x050020ff,
+	0x050f80ff, 0x032fa009, 0x040f8002, 0x053fa80a,
+	0x07000009, 0x050fe000, 0x008683f2, 0x07601818,
+	0x050f80ff, 0x053fa80a, 0x07000009, 0x038003f3,
+	0x07a000de, 0x07273000, 0x02076013, 0x0280003d,
+	0x078b03f6, 0x03385000, 0x07030000, 0x05600818,
+	0x050f80ff, 0x032fa009, 0x054b0400, 0x0308a0ff,
+	0x0179fe00, 0x070000ff, 0x010880ff, 0x0448b075,
+	0x04810410, 0x0760147b, 0x050f80ff, 0x002fa819,
+	0x064b0001, 0x02080002, 0x01081003, 0x00082001,
+	0x02083001, 0x02079001, 0x0207a001, 0x00084013,
+	0x0207f013, 0x00800432, 0x06485075, 0x05810428,
+	0x02465075, 0x06601476, 0x050f80ff, 0x073fa021,
+	0x0600003e, 0x070ff07d, 0x0450047c, 0x050f80ff,
+	0x002fa819, 0x058b041b, 0x02080001, 0x00081002,
+	0x01082003, 0x03079003, 0x0208307a, 0x0340007e,
+	0x0642007f, 0x0581042d, 0x070ff07e, 0x05a001d2,
+	0x0392842d, 0x01800439, 0x058b0428, 0x06601476,
+	0x050f80ff, 0x073fa041, 0x0600003e, 0x06602476,
+	0x050f80ff, 0x073fa009, 0x06000007, 0x0008400e,
+	0x048b0432, 0x03385000, 0x03010000, 0x06219001,
+	0x040fe07f, 0x01860439, 0x018001bb, 0x07c00000,
+	0x00683e75, 0x0581043f, 0x0448d075, 0x05810465,
+	0x01800493, 0x05a004f0, 0x038003f5, 0x0297844c,
+	0x07602418, 0x050f80ff, 0x012fa809, 0x06780001,
+	0x070000ff, 0x075a0000, 0x070ff014, 0x0569feff,
+	0x054b08ff, 0x075a0000, 0x05600418, 0x050f80ff,
+	0x012fa809, 0x040fe007, 0x03868453, 0x01204000,
+	0x00800461, 0x00700101, 0x03010000, 0x06780001,
+	0x07ff0000, 0x076c00ff, 0x0681845b, 0x00700101,
+	0x03010000, 0x05600418, 0x050f80ff, 0x012fa80a,
+	0x06780001, 0x07ff0000, 0x050040ff, 0x0279ff01,
+	0x0700ffff, 0x05002014, 0x07c00000, 0x04007076,
+	0x0448b075, 0x0481047f, 0x03200011, 0x06006076,
+	0x06a003bc, 0x007a0101, 0x07060000, 0x07303000,
+	0x07008290, 0x07600018, 0x050f80ff, 0x053fa809,
+	0x07000003, 0x0448e007, 0x07818477, 0x06006013,
+	0x0180048e, 0x02400010, 0x05810477, 0x06006010,
+	0x04603276, 0x050f80ff, 0x073fa00a, 0x07000003,
+	0x0180048e, 0x04602a76, 0x050f80ff, 0x032fa009,
+	0x060ff07a, 0x05500400, 0x070000ff, 0x04602a76,
+	0x050f80ff, 0x032fa00a, 0x07a003b7, 0x007a0101,
+	0x03010000, 0x06303008, 0x05008000, 0x0600600e,
+	0x050f8074, 0x032fa03a, 0x053079a0, 0x0700000c,
+	0x008004d3, 0x00683e75, 0x076c0aff, 0x058104b2,
+	0x04007013, 0x03200011, 0x06006076, 0x06a003bc,
+	0x007a0101, 0x03070000, 0x06602876, 0x050f80ff,
+	0x053fa809, 0x06000001, 0x03499003, 0x048104a7,
+	0x07303000, 0x07008890, 0x053079a0, 0x0700000c,
+	0x008004ab, 0x07303000, 0x04008980, 0x04307920,
+	0x0700000c, 0x074d0005, 0x06006013, 0x050f8074,
+	0x032fa03a, 0x04307920, 0x0700000c, 0x008004d3,
+	0x04602a76, 0x050f80ff, 0x032fa009, 0x060ff07a,
+	0x05500400, 0x070000ff, 0x04602a76, 0x050f80ff,
+	0x032fa00a, 0x04007076, 0x07a003b7, 0x007a0101,
+	0x03010000, 0x06303008, 0x07008800, 0x074d0005,
+	0x06600a76, 0x050f80ff, 0x073fa009, 0x07000003,
+	0x054b0406, 0x045a0404, 0x050040ff, 0x0600600e,
+	0x050f8074, 0x032fa03a, 0x0648c075, 0x058104d1,
+	0x06307d20, 0x0700000c, 0x008004d3, 0x04307920,
+	0x0700000c, 0x013e4000, 0x07000030, 0x009804d5,
+	0x070ff0f6, 0x074850ff, 0x068184d6, 0x050f2074,
+	0x060a0007, 0x040070fb, 0x046a7007, 0x050f40ff,
+	0x013e4000, 0x06000020, 0x0678007a, 0x07fff000,
+	0x068184e6, 0x0320000a, 0x022017d0, 0x008004e9,
+	0x0320000a, 0x06301b58, 0x06000001, 0x050f8072,
+	0x032fa012, 0x038003f5, 0x01208060, 0x0600902a,
+	0x04002020, 0x018004fc, 0x040080fb, 0x066ae108,
+	0x06009076, 0x04002075, 0x018004fc, 0x03201100,
+	0x078484fa, 0x06420001, 0x078184f6, 0x02800513,
+	0x020e0008, 0x07c00000, 0x050fd009, 0x040fd008,
+	0x03201100, 0x05848503, 0x06420001, 0x078184ff,
+	0x02800513, 0x007a0102, 0x04000101, 0x05600809,
+	0x050f80ff, 0x073fa00a, 0x06000001, 0x020e0008,
+	0x0684050d, 0x030e0009, 0x07c00000, 0x01011009,
+	0x052e4300, 0x07c00000, 0x052e400f, 0x01208090,
+	0x018004f5, 0x070fc0ff, 0x040f8013, 0x032fa009,
+	0x02800516, 0x15416ea9, 0xffef0b01
+};
+
+#ifdef UNIQUE_FW_NAME
+uint32_t fw2400_length02 = 0x000014ff ;
+#else
+uint32_t risc_code_length02 = 0x000014ff ;
+#endif
+
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 48e460e..2efca52 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -232,7 +232,7 @@
 qla2x00_isp_name_show(struct class_device *cdev, char *buf)
 {
 	scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev));
-	return snprintf(buf, PAGE_SIZE, "%s\n", ha->brd_info->isp_name);
+	return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device);
 }
 
 static ssize_t
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 7096945..79d8a91 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -22,6 +22,7 @@
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/workqueue.h>
+#include <linux/firmware.h>
 #include <asm/semaphore.h>
 
 #include <scsi/scsi.h>
@@ -29,6 +30,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
 #if defined(CONFIG_SCSI_QLA21XX) || defined(CONFIG_SCSI_QLA21XX_MODULE)
 #define IS_QLA2100(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100)
 #else
@@ -79,9 +81,23 @@
 #define IS_QLA2522(ha)	0
 #endif
 
+#else	/* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
+
+#define IS_QLA2100(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2100)
+#define IS_QLA2200(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2200)
+#define IS_QLA2300(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2300)
+#define IS_QLA2312(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2312)
+#define IS_QLA2322(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2322)
+#define IS_QLA6312(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6312)
+#define IS_QLA6322(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP6322)
+#define IS_QLA2422(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422)
+#define IS_QLA2432(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
+#define IS_QLA2512(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2512)
+#define IS_QLA2522(ha)	((ha)->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2522)
+#endif
+
 #define IS_QLA23XX(ha)	(IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
     			 IS_QLA6312(ha) || IS_QLA6322(ha))
-
 #define IS_QLA24XX(ha)	(IS_QLA2422(ha) || IS_QLA2432(ha))
 #define IS_QLA25XX(ha)	(IS_QLA2512(ha) || IS_QLA2522(ha))
 
@@ -2124,6 +2140,12 @@
 	struct scsi_host_template *sht;
 };
 
+struct fw_blob {
+	char *name;
+	uint32_t segs[4];
+	const struct firmware *fw;
+};
+
 /* Return data from MBC_GET_ID_LIST call. */
 struct gid_list_info {
 	uint8_t	al_pa;
@@ -2476,17 +2498,9 @@
  */
 #define LOOP_TRANSITION(ha) \
 	(test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \
-	 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))
-
-#define LOOP_NOT_READY(ha) \
-	((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \
-	  test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || \
-	  test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \
-	  test_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags)) || \
+	 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \
 	 atomic_read(&ha->loop_state) == LOOP_DOWN)
 
-#define LOOP_RDY(ha)	(!LOOP_NOT_READY(ha))
-
 #define TGT_Q(ha, t) (ha->otgt[t])
 
 #define to_qla_host(x)		((scsi_qla_host_t *) (x)->hostdata)
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index fedcb0d..bec81ad 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -33,8 +33,8 @@
 extern void qla2x00_update_fw_options(struct scsi_qla_host *);
 extern void qla24xx_update_fw_options(scsi_qla_host_t *);
 extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *);
+extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *);
 extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *);
-extern int qla24xx_load_risc_hotplug(scsi_qla_host_t *, uint32_t *);
 
 extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t);
 
@@ -76,6 +76,8 @@
 
 extern int qla2x00_down_timeout(struct semaphore *, unsigned long);
 
+extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
+
 /*
  * Global Function Prototypes in qla_iocb.c source file.
  */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 2d72012..7d973bd 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -8,7 +8,6 @@
 
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
-#include <linux/firmware.h>
 #include <scsi/scsi_transport_fc.h>
 
 #include "qla_devtbl.h"
@@ -1259,7 +1258,7 @@
 	rval = qla2x00_get_adapter_id(ha,
 	    &loop_id, &al_pa, &area, &domain, &topo);
 	if (rval != QLA_SUCCESS) {
-		if (LOOP_NOT_READY(ha) || atomic_read(&ha->loop_down_timer) ||
+		if (LOOP_TRANSITION(ha) || atomic_read(&ha->loop_down_timer) ||
 		    (rval == QLA_COMMAND_ERROR && loop_id == 0x7)) {
 			DEBUG2(printk("%s(%ld) Loop is in a transition state\n",
 			    __func__, ha->host_no));
@@ -1796,7 +1795,7 @@
 	}
 
 	if (rval == QLA_SUCCESS && test_bit(RSCN_UPDATE, &flags)) {
-		if (LOOP_NOT_READY(ha)) {
+		if (LOOP_TRANSITION(ha)) {
 			rval = QLA_FUNCTION_FAILED;
 		} else {
 			rval = qla2x00_configure_fabric(ha);
@@ -2369,7 +2368,7 @@
 		if (qla2x00_is_reserved_id(ha, loop_id))
 			continue;
 
-		if (atomic_read(&ha->loop_down_timer) || LOOP_NOT_READY(ha))
+		if (atomic_read(&ha->loop_down_timer) || LOOP_TRANSITION(ha))
 			break;
 
 		if (swl != NULL) {
@@ -3484,17 +3483,16 @@
 	return (rval);
 }
 
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+
 int
 qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
 {
-	int		rval;
-	uint16_t	cnt;
-	uint16_t	*risc_code;
-	unsigned long	risc_address;
-	unsigned long	risc_code_size;
-	int		num;
-	int		i;
-	uint16_t	*req_ring;
+	int	rval, num, i;
+	uint32_t cnt;
+	uint16_t *risc_code;
+	uint32_t risc_addr, risc_size;
+	uint16_t *req_ring;
 	struct qla_fw_info *fw_iter;
 
 	rval = QLA_SUCCESS;
@@ -3504,37 +3502,29 @@
 	*srisc_addr = *ha->brd_info->fw_info->fwstart;
 	while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) {
 		risc_code = fw_iter->fwcode;
-		risc_code_size = *fw_iter->fwlen;
-
-		if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
-			risc_address = *fw_iter->fwstart;
-		} else {
-			/* Extended address */
-			risc_address = *fw_iter->lfwstart;
-		}
+		risc_size = *fw_iter->fwlen;
+		if (fw_iter->addressing == FW_INFO_ADDR_NORMAL)
+			risc_addr = *fw_iter->fwstart;
+		else
+			risc_addr = *fw_iter->lfwstart;
 
 		num = 0;
 		rval = 0;
-		while (risc_code_size > 0 && !rval) {
+		while (risc_size > 0 && !rval) {
 			cnt = (uint16_t)(ha->fw_transfer_size >> 1);
-			if (cnt > risc_code_size)
-				cnt = risc_code_size;
+			if (cnt > risc_size)
+				cnt = risc_size;
 
 			DEBUG7(printk("scsi(%ld): Loading risc segment@ "
 			    "addr %p, number of bytes 0x%x, offset 0x%lx.\n",
-			    ha->host_no, risc_code, cnt, risc_address));
+			    ha->host_no, risc_code, cnt, risc_addr));
 
 			req_ring = (uint16_t *)ha->request_ring;
 			for (i = 0; i < cnt; i++)
 				req_ring[i] = cpu_to_le16(risc_code[i]);
 
-			if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) {
-				rval = qla2x00_load_ram(ha, ha->request_dma,
-				    risc_address, cnt);
-			} else {
-				rval = qla2x00_load_ram_ext(ha,
-				    ha->request_dma, risc_address, cnt);
-			}
+			rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+			    cnt);
 			if (rval) {
 				DEBUG(printk("scsi(%ld): [ERROR] Failed to "
 				    "load segment %d of firmware\n",
@@ -3548,16 +3538,76 @@
 			}
 
 			risc_code += cnt;
-			risc_address += cnt;
-			risc_code_size -= cnt;
+			risc_addr += cnt;
+			risc_size -= cnt;
 			num++;
 		}
 
 		/* Next firmware sequence */
 		fw_iter++;
 	}
+	return rval;
+}
 
-	return (rval);
+int
+qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+	int	rval, num, i;
+	uint32_t cnt;
+	uint32_t *risc_code;
+	uint32_t risc_addr, risc_size;
+	uint32_t *req_ring;
+	struct qla_fw_info *fw_iter;
+
+	rval = QLA_SUCCESS;
+
+	/* Load firmware sequences */
+	fw_iter = ha->brd_info->fw_info;
+	*srisc_addr = *((uint32_t *)fw_iter->lfwstart);
+	while (fw_iter->addressing != FW_INFO_ADDR_NOMORE) {
+		risc_code = (uint32_t *)fw_iter->fwcode;
+		risc_size = *((uint32_t *)fw_iter->fwlen);
+		risc_addr = *((uint32_t *)fw_iter->lfwstart);
+
+		num = 0;
+		rval = 0;
+		while (risc_size > 0 && !rval) {
+			cnt = (uint32_t)(ha->fw_transfer_size >> 2);
+			if (cnt > risc_size)
+				cnt = risc_size;
+
+			DEBUG7(printk("scsi(%ld): Loading risc segment@ "
+			    "addr %p, number of bytes 0x%x, offset 0x%lx.\n",
+			    ha->host_no, risc_code, cnt, risc_addr));
+
+			req_ring = (uint32_t *)ha->request_ring;
+			for (i = 0; i < cnt; i++)
+				req_ring[i] = cpu_to_le32(risc_code[i]);
+
+			rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+			    cnt);
+			if (rval) {
+				DEBUG(printk("scsi(%ld): [ERROR] Failed to "
+				    "load segment %d of firmware\n",
+				    ha->host_no, num));
+				qla_printk(KERN_WARNING, ha,
+				    "[ERROR] Failed to load segment %d of "
+				    "firmware\n", num);
+
+				qla2x00_dump_regs(ha);
+				break;
+			}
+
+			risc_code += cnt;
+			risc_addr += cnt;
+			risc_size -= cnt;
+			num++;
+		}
+
+		/* Next firmware sequence */
+		fw_iter++;
+	}
+	return rval;
 }
 
 int
@@ -3642,8 +3692,108 @@
 	return rval;
 }
 
+#else	/* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
+
 int
-qla24xx_load_risc_hotplug(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+qla2x00_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
+{
+	int	rval;
+	int	i, fragment;
+	uint16_t *wcode, *fwcode;
+	uint32_t risc_addr, risc_size, fwclen, wlen, *seg;
+	struct fw_blob *blob;
+
+	/* Load firmware blob. */
+	blob = qla2x00_request_firmware(ha);
+	if (!blob) {
+		qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n");
+		return QLA_FUNCTION_FAILED;
+	}
+
+	rval = QLA_SUCCESS;
+
+	wcode = (uint16_t *)ha->request_ring;
+	*srisc_addr = 0;
+	fwcode = (uint16_t *)blob->fw->data;
+	fwclen = 0;
+
+	/* Validate firmware image by checking version. */
+	if (blob->fw->size < 8 * sizeof(uint16_t)) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to verify integrity of firmware image (%Zd)!\n",
+		    blob->fw->size);
+		goto fail_fw_integrity;
+	}
+	for (i = 0; i < 4; i++)
+		wcode[i] = be16_to_cpu(fwcode[i + 4]);
+	if ((wcode[0] == 0xffff && wcode[1] == 0xffff && wcode[2] == 0xffff &&
+	    wcode[3] == 0xffff) || (wcode[0] == 0 && wcode[1] == 0 &&
+		wcode[2] == 0 && wcode[3] == 0)) {
+		qla_printk(KERN_WARNING, ha,
+		    "Unable to verify integrity of firmware image!\n");
+		qla_printk(KERN_WARNING, ha,
+		    "Firmware data: %04x %04x %04x %04x!\n", wcode[0],
+		    wcode[1], wcode[2], wcode[3]);
+		goto fail_fw_integrity;
+	}
+
+	seg = blob->segs;
+	while (*seg && rval == QLA_SUCCESS) {
+		risc_addr = *seg;
+		*srisc_addr = *srisc_addr == 0 ? *seg : *srisc_addr;
+		risc_size = be16_to_cpu(fwcode[3]);
+
+		/* Validate firmware image size. */
+		fwclen += risc_size * sizeof(uint16_t);
+		if (blob->fw->size < fwclen) {
+			qla_printk(KERN_WARNING, ha,
+			    "Unable to verify integrity of firmware image "
+			    "(%Zd)!\n", blob->fw->size);
+			goto fail_fw_integrity;
+		}
+
+		fragment = 0;
+		while (risc_size > 0 && rval == QLA_SUCCESS) {
+			wlen = (uint16_t)(ha->fw_transfer_size >> 1);
+			if (wlen > risc_size)
+				wlen = risc_size;
+
+			DEBUG7(printk("scsi(%ld): Loading risc segment@ risc "
+			    "addr %x, number of words 0x%x.\n", ha->host_no,
+			    risc_addr, wlen));
+
+			for (i = 0; i < wlen; i++)
+				wcode[i] = swab16(fwcode[i]);
+
+			rval = qla2x00_load_ram(ha, ha->request_dma, risc_addr,
+			    wlen);
+			if (rval) {
+				DEBUG(printk("scsi(%ld):[ERROR] Failed to load "
+				    "segment %d of firmware\n", ha->host_no,
+				    fragment));
+				qla_printk(KERN_WARNING, ha,
+				    "[ERROR] Failed to load segment %d of "
+				    "firmware\n", fragment);
+				break;
+			}
+
+			fwcode += wlen;
+			risc_addr += wlen;
+			risc_size -= wlen;
+			fragment++;
+		}
+
+		/* Next segment. */
+		seg++;
+	}
+	return rval;
+
+fail_fw_integrity:
+	return QLA_FUNCTION_FAILED;
+}
+
+int
+qla24xx_load_risc(scsi_qla_host_t *ha, uint32_t *srisc_addr)
 {
 	int	rval;
 	int	segments, fragment;
@@ -3651,14 +3801,13 @@
 	uint32_t risc_addr;
 	uint32_t risc_size;
 	uint32_t i;
-	const struct firmware *fw_entry;
+	struct fw_blob *blob;
 	uint32_t *fwcode, fwclen;
 
-	if (request_firmware(&fw_entry, ha->brd_info->fw_fname,
-	    &ha->pdev->dev)) {
-		qla_printk(KERN_ERR, ha,
-		    "Firmware image file not available: '%s'\n",
-		    ha->brd_info->fw_fname);
+	/* Load firmware blob. */
+	blob = qla2x00_request_firmware(ha);
+	if (!blob) {
+		qla_printk(KERN_ERR, ha, "Firmware image unavailable.\n");
 		return QLA_FUNCTION_FAILED;
 	}
 
@@ -3667,14 +3816,14 @@
 	segments = FA_RISC_CODE_SEGMENTS;
 	dcode = (uint32_t *)ha->request_ring;
 	*srisc_addr = 0;
-	fwcode = (uint32_t *)fw_entry->data;
+	fwcode = (uint32_t *)blob->fw->data;
 	fwclen = 0;
 
 	/* Validate firmware image by checking version. */
-	if (fw_entry->size < 8 * sizeof(uint32_t)) {
+	if (blob->fw->size < 8 * sizeof(uint32_t)) {
 		qla_printk(KERN_WARNING, ha,
-		    "Unable to verify integrity of flash firmware image "
-		    "(%Zd)!\n", fw_entry->size);
+		    "Unable to verify integrity of firmware image (%Zd)!\n",
+		    blob->fw->size);
 		goto fail_fw_integrity;
 	}
 	for (i = 0; i < 4; i++)
@@ -3684,7 +3833,7 @@
 	    (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 &&
 		dcode[3] == 0)) {
 		qla_printk(KERN_WARNING, ha,
-		    "Unable to verify integrity of flash firmware image!\n");
+		    "Unable to verify integrity of firmware image!\n");
 		qla_printk(KERN_WARNING, ha,
 		    "Firmware data: %08x %08x %08x %08x!\n", dcode[0],
 		    dcode[1], dcode[2], dcode[3]);
@@ -3698,10 +3847,11 @@
 
 		/* Validate firmware image size. */
 		fwclen += risc_size * sizeof(uint32_t);
-		if (fw_entry->size < fwclen) {
+		if (blob->fw->size < fwclen) {
 			qla_printk(KERN_WARNING, ha,
-			    "Unable to verify integrity of flash firmware "
-			    "image (%Zd)!\n", fw_entry->size);
+			    "Unable to verify integrity of firmware image "
+			    "(%Zd)!\n", blob->fw->size);
+
 			goto fail_fw_integrity;
 		}
 
@@ -3739,13 +3889,9 @@
 		/* Next segment. */
 		segments--;
 	}
-
-	release_firmware(fw_entry);
 	return rval;
 
 fail_fw_integrity:
-
-	release_firmware(fw_entry);
 	return QLA_FUNCTION_FAILED;
-
 }
+#endif
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 09afc0f..5181d96 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -909,6 +909,21 @@
 			resid = resid_len;
 			cp->resid = resid;
 			CMD_RESID_LEN(cp) = resid;
+
+			if (!lscsi_status &&
+			    ((unsigned)(cp->request_bufflen - resid) <
+			     cp->underflow)) {
+				qla_printk(KERN_INFO, ha,
+				    "scsi(%ld:%d:%d:%d): Mid-layer underflow "
+				    "detected (%x of %x bytes)...returning "
+				    "error status.\n", ha->host_no,
+				    cp->device->channel, cp->device->id,
+				    cp->device->lun, resid,
+				    cp->request_bufflen);
+
+				cp->result = DID_ERROR << 16;
+				break;
+			}
 		}
 		cp->result = DID_OK << 16 | lscsi_status;
 
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index c58c9d9..2430430 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -54,10 +54,12 @@
 MODULE_PARM_DESC(ql2xloginretrycount,
 		"Specify an alternate value for the NVRAM login retry count.");
 
-int ql2xfwloadbin=1;
-module_param(ql2xfwloadbin, int, S_IRUGO|S_IRUSR);
-MODULE_PARM_DESC(ql2xfwloadbin,
-		"Load ISP2xxx firmware image via hotplug.");
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+int ql2xfwloadflash;
+module_param(ql2xfwloadflash, int, S_IRUGO|S_IRUSR);
+MODULE_PARM_DESC(ql2xfwloadflash,
+		"Load ISP24xx firmware image from FLASH (onboard memory).");
+#endif
 
 static void qla2x00_free_device(scsi_qla_host_t *);
 
@@ -1261,12 +1263,16 @@
 	char pci_info[20];
 	char fw_str[30];
 	fc_port_t *fcport;
+	struct scsi_host_template *sht;
 
 	if (pci_enable_device(pdev))
 		goto probe_out;
 
-	host = scsi_host_alloc(brd_info->sht ? brd_info->sht:
-	    &qla2x00_driver_template, sizeof(scsi_qla_host_t));
+	sht = &qla2x00_driver_template;
+	if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
+	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432)
+		sht = &qla24xx_driver_template;
+	host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
 	if (host == NULL) {
 		printk(KERN_WARNING
 		    "qla2xxx: Couldn't allocate host from scsi layer!\n");
@@ -1291,8 +1297,8 @@
 		goto probe_failed;
 
 	qla_printk(KERN_INFO, ha,
-	    "Found an %s, irq %d, iobase 0x%p\n", ha->brd_info->isp_name,
-	    pdev->irq, ha->iobase);
+	    "Found an ISP%04X, irq %d, iobase 0x%p\n", pdev->device, pdev->irq,
+	    ha->iobase);
 
 	spin_lock_init(&ha->hardware_lock);
 
@@ -1368,9 +1374,11 @@
 		ha->isp_ops.reset_adapter = qla24xx_reset_adapter;
 		ha->isp_ops.nvram_config = qla24xx_nvram_config;
 		ha->isp_ops.update_fw_options = qla24xx_update_fw_options;
-		ha->isp_ops.load_risc = qla24xx_load_risc_flash;
-		if (ql2xfwloadbin)
-			ha->isp_ops.load_risc = qla24xx_load_risc_hotplug;
+		ha->isp_ops.load_risc = qla24xx_load_risc;
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+		if (ql2xfwloadflash)
+			ha->isp_ops.load_risc = qla24xx_load_risc_flash;
+#endif
 		ha->isp_ops.pci_info_str = qla24xx_pci_info_str;
 		ha->isp_ops.fw_version_str = qla24xx_fw_version_str;
 		ha->isp_ops.intr_handler = qla24xx_intr_handler;
@@ -1531,11 +1539,12 @@
 	qla_printk(KERN_INFO, ha, "\n"
 	    " QLogic Fibre Channel HBA Driver: %s\n"
 	    "  QLogic %s - %s\n"
-	    "  %s: %s @ %s hdma%c, host#=%ld, fw=%s\n", qla2x00_version_str,
-	    ha->model_number, ha->model_desc ? ha->model_desc: "",
-	    ha->brd_info->isp_name, ha->isp_ops.pci_info_str(ha, pci_info),
-	    pci_name(pdev), ha->flags.enable_64bit_addressing ? '+': '-',
-	    ha->host_no, ha->isp_ops.fw_version_str(ha, fw_str));
+	    "  ISP%04X: %s @ %s hdma%c, host#=%ld, fw=%s\n",
+	    qla2x00_version_str, ha->model_number,
+	    ha->model_desc ? ha->model_desc: "", pdev->device,
+	    ha->isp_ops.pci_info_str(ha, pci_info), pci_name(pdev),
+	    ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
+	    ha->isp_ops.fw_version_str(ha, fw_str));
 
 	/* Go with fc_rport registration. */
 	list_for_each_entry(fcport, &ha->fcports, list)
@@ -2483,45 +2492,115 @@
 	return -ETIMEDOUT;
 }
 
-static struct qla_board_info qla_board_tbl[] = {
-	{
-		.drv_name	= "qla2400",
-		.isp_name	= "ISP2422",
-		.fw_fname	= "ql2400_fw.bin",
-		.sht		= &qla24xx_driver_template,
-	},
-	{
-		.drv_name	= "qla2400",
-		.isp_name	= "ISP2432",
-		.fw_fname	= "ql2400_fw.bin",
-		.sht		= &qla24xx_driver_template,
-	},
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+
+#define qla2x00_release_firmware()	do { } while (0)
+#define qla2x00_pci_module_init()	(0)
+#define qla2x00_pci_module_exit()	do { } while (0)
+
+#else	/* !defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE) */
+
+/* Firmware interface routines. */
+
+#define FW_BLOBS	6
+#define FW_ISP21XX	0
+#define FW_ISP22XX	1
+#define FW_ISP2300	2
+#define FW_ISP2322	3
+#define FW_ISP63XX	4
+#define FW_ISP24XX	5
+
+static DECLARE_MUTEX(qla_fw_lock);
+
+static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
+	{ .name = "ql2100_fw.bin", .segs = { 0x1000, 0 }, },
+	{ .name = "ql2200_fw.bin", .segs = { 0x1000, 0 }, },
+	{ .name = "ql2300_fw.bin", .segs = { 0x800, 0 }, },
+	{ .name = "ql2322_fw.bin", .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
+	{ .name = "ql6312_fw.bin", .segs = { 0x800, 0 }, },
+	{ .name = "ql2400_fw.bin", },
+};
+
+struct fw_blob *
+qla2x00_request_firmware(scsi_qla_host_t *ha)
+{
+	struct fw_blob *blob;
+
+	blob = NULL;
+	if (IS_QLA2100(ha)) {
+		blob = &qla_fw_blobs[FW_ISP21XX];
+	} else if (IS_QLA2200(ha)) {
+		blob = &qla_fw_blobs[FW_ISP22XX];
+	} else if (IS_QLA2300(ha) || IS_QLA2312(ha)) {
+		blob = &qla_fw_blobs[FW_ISP2300];
+	} else if (IS_QLA2322(ha)) {
+		blob = &qla_fw_blobs[FW_ISP2322];
+	} else if (IS_QLA6312(ha) || IS_QLA6322(ha)) {
+		blob = &qla_fw_blobs[FW_ISP63XX];
+	} else if (IS_QLA24XX(ha)) {
+		blob = &qla_fw_blobs[FW_ISP24XX];
+	}
+
+	down(&qla_fw_lock);
+	if (blob->fw)
+		goto out;
+
+	if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) {
+		DEBUG2(printk("scsi(%ld): Failed to load firmware image "
+		    "(%s).\n", ha->host_no, blob->name));
+		blob->fw = NULL;
+		blob = NULL;
+		goto out;
+	}
+
+out:
+	up(&qla_fw_lock);
+	return blob;
+}
+
+static void
+qla2x00_release_firmware(void)
+{
+	int idx;
+
+	down(&qla_fw_lock);
+	for (idx = 0; idx < FW_BLOBS; idx++)
+		if (qla_fw_blobs[idx].fw)
+			release_firmware(qla_fw_blobs[idx].fw);
+	up(&qla_fw_lock);
+}
+
+static struct qla_board_info qla_board_tbl = {
+	.drv_name       = "qla2xxx",
 };
 
 static struct pci_device_id qla2xxx_pci_tbl[] = {
-	{
-		.vendor		= PCI_VENDOR_ID_QLOGIC,
-		.device		= PCI_DEVICE_ID_QLOGIC_ISP2422,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= (unsigned long)&qla_board_tbl[0],
-	},
-	{
-		.vendor		= PCI_VENDOR_ID_QLOGIC,
-		.device		= PCI_DEVICE_ID_QLOGIC_ISP2432,
-		.subvendor	= PCI_ANY_ID,
-		.subdevice	= PCI_ANY_ID,
-		.driver_data	= (unsigned long)&qla_board_tbl[1],
-	},
-	{0, 0},
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0 },
 };
 MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
 
 static int __devinit
 qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
-	return qla2x00_probe_one(pdev,
-	    (struct qla_board_info *)id->driver_data);
+	return qla2x00_probe_one(pdev, &qla_board_tbl);
 }
 
 static void __devexit
@@ -2532,11 +2611,28 @@
 
 static struct pci_driver qla2xxx_pci_driver = {
 	.name		= "qla2xxx",
+	.driver		= {
+		.owner		= THIS_MODULE,
+	},
 	.id_table	= qla2xxx_pci_tbl,
 	.probe		= qla2xxx_probe_one,
 	.remove		= __devexit_p(qla2xxx_remove_one),
 };
 
+static inline int
+qla2x00_pci_module_init(void)
+{
+	return pci_module_init(&qla2xxx_pci_driver);
+}
+
+static inline void
+qla2x00_pci_module_exit(void)
+{
+	pci_unregister_driver(&qla2xxx_pci_driver);
+}
+
+#endif
+
 /**
  * qla2x00_module_init - Module initialization.
  **/
@@ -2556,6 +2652,9 @@
 
 	/* Derive version string. */
 	strcpy(qla2x00_version_str, QLA2XXX_VERSION);
+#if defined(CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE)
+	strcat(qla2x00_version_str, "-fw");
+#endif
 #if DEBUG_QLA2100
 	strcat(qla2x00_version_str, "-debug");
 #endif
@@ -2565,7 +2664,7 @@
 		return -ENODEV;
 
 	printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n");
-	ret = pci_module_init(&qla2xxx_pci_driver);
+	ret = qla2x00_pci_module_init();
 	if (ret) {
 		kmem_cache_destroy(srb_cachep);
 		fc_release_transport(qla2xxx_transport_template);
@@ -2579,7 +2678,8 @@
 static void __exit
 qla2x00_module_exit(void)
 {
-	pci_unregister_driver(&qla2xxx_pci_driver);
+	qla2x00_pci_module_exit();
+	qla2x00_release_firmware();
 	kmem_cache_destroy(srb_cachep);
 	fc_release_transport(qla2xxx_transport_template);
 }
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c
index 5b1c120..5ec5f44 100644
--- a/drivers/scsi/raid_class.c
+++ b/drivers/scsi/raid_class.c
@@ -115,7 +115,7 @@
 			       raid_remove,
 			       NULL);
 
-static struct {
+static const struct {
 	enum raid_state	value;
 	char		*name;
 } raid_states[] = {
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index ab7432a..cd54244 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -86,7 +86,8 @@
 	MV_FLAG_DUAL_HC		= (1 << 30),  /* two SATA Host Controllers */
 	MV_FLAG_IRQ_COALESCE	= (1 << 29),  /* IRQ coalescing capability */
 	MV_COMMON_FLAGS		= (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				   ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO),
+				   ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |
+				   ATA_FLAG_NO_ATAPI),
 	MV_6XXX_FLAGS		= MV_FLAG_IRQ_COALESCE,
 
 	CRQB_FLAG_READ		= (1 << 0),
@@ -373,7 +374,6 @@
 	.dma_boundary		= MV_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 static const struct ata_port_operations mv5_ops = {
@@ -430,7 +430,7 @@
 	.host_stop		= mv_host_stop,
 };
 
-static struct ata_port_info mv_port_info[] = {
+static const struct ata_port_info mv_port_info[] = {
 	{  /* chip_504x */
 		.sht		= &mv_sht,
 		.host_flags	= MV_COMMON_FLAGS,
@@ -1242,8 +1242,10 @@
 				VPRINTK("port %u IRQ found for qc, "
 					"ata_status 0x%x\n", port,ata_status);
 				/* mark qc status appropriately */
-				if (!(qc->tf.ctl & ATA_NIEN))
-					ata_qc_complete(qc, err_mask);
+				if (!(qc->tf.ctl & ATA_NIEN)) {
+					qc->err_mask |= err_mask;
+					ata_qc_complete(qc);
+				}
 			}
 		}
 	}
@@ -1864,7 +1866,8 @@
 	 	 */
 		spin_lock_irqsave(&ap->host_set->lock, flags);
 		qc->scsidone = scsi_finish_command;
-		ata_qc_complete(qc, AC_ERR_OTHER);
+		qc->err_mask |= AC_ERR_OTHER;
+		ata_qc_complete(qc);
 		spin_unlock_irqrestore(&ap->host_set->lock, flags);
 	}
 }
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index 4954896..c0cf52c 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -235,7 +235,6 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 static const struct ata_port_operations nv_ops = {
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 8a8e3e3..3d1ea09 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -70,6 +70,9 @@
 	PDC_HAS_PATA		= (1 << 1), /* PDC20375 has PATA */
 
 	PDC_RESET		= (1 << 11), /* HDMA reset */
+
+	PDC_COMMON_FLAGS	= ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST |
+				  ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI,
 };
 
 
@@ -111,7 +114,6 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 static const struct ata_port_operations pdc_sata_ops = {
@@ -158,12 +160,11 @@
 	.host_stop		= ata_pci_host_stop,
 };
 
-static struct ata_port_info pdc_port_info[] = {
+static const struct ata_port_info pdc_port_info[] = {
 	/* board_2037x */
 	{
 		.sht		= &pdc_ata_sht,
-		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+		.host_flags	= PDC_COMMON_FLAGS | ATA_FLAG_SATA,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
@@ -173,8 +174,7 @@
 	/* board_20319 */
 	{
 		.sht		= &pdc_ata_sht,
-		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+		.host_flags	= PDC_COMMON_FLAGS | ATA_FLAG_SATA,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
@@ -184,8 +184,7 @@
 	/* board_20619 */
 	{
 		.sht		= &pdc_ata_sht,
-		.host_flags	= ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST |
-				  ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS,
+		.host_flags	= PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
@@ -401,7 +400,8 @@
 	case ATA_PROT_NODATA:
 		printk(KERN_ERR "ata%u: command timeout\n", ap->id);
 		drv_stat = ata_wait_idle(ap);
-		ata_qc_complete(qc, __ac_err_mask(drv_stat));
+		qc->err_mask |= __ac_err_mask(drv_stat);
+		ata_qc_complete(qc);
 		break;
 
 	default:
@@ -410,7 +410,8 @@
 		printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
 		       ap->id, qc->tf.command, drv_stat);
 
-		ata_qc_complete(qc, ac_err_mask(drv_stat));
+		qc->err_mask |= ac_err_mask(drv_stat);
+		ata_qc_complete(qc);
 		break;
 	}
 
@@ -422,21 +423,21 @@
 static inline unsigned int pdc_host_intr( struct ata_port *ap,
                                           struct ata_queued_cmd *qc)
 {
-	unsigned int handled = 0, err_mask = 0;
+	unsigned int handled = 0;
 	u32 tmp;
 	void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
 
 	tmp = readl(mmio);
 	if (tmp & PDC_ERR_MASK) {
-		err_mask = AC_ERR_DEV;
+		qc->err_mask |= AC_ERR_DEV;
 		pdc_reset_port(ap);
 	}
 
 	switch (qc->tf.protocol) {
 	case ATA_PROT_DMA:
 	case ATA_PROT_NODATA:
-		err_mask |= ac_err_mask(ata_wait_idle(ap));
-		ata_qc_complete(qc, err_mask);
+		qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
+		ata_qc_complete(qc);
 		handled = 1;
 		break;
 
@@ -703,7 +704,7 @@
 		probe_ent->port[3].scr_addr = base + 0x700;
 		break;
 	case board_2037x:
-       		probe_ent->n_ports = 2;
+		probe_ent->n_ports = 2;
 		break;
 	case board_20619:
 		probe_ent->n_ports = 4;
@@ -713,7 +714,7 @@
 
 		probe_ent->port[2].scr_addr = base + 0x600;
 		probe_ent->port[3].scr_addr = base + 0x700;
-                break;
+		break;
 	default:
 		BUG();
 		break;
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c
index a8987f5..de05e28 100644
--- a/drivers/scsi/sata_qstor.c
+++ b/drivers/scsi/sata_qstor.c
@@ -170,7 +170,7 @@
 	.bmdma_status		= qs_bmdma_status,
 };
 
-static struct ata_port_info qs_port_info[] = {
+static const struct ata_port_info qs_port_info[] = {
 	/* board_2068_idx */
 	{
 		.sht		= &qs_ata_sht,
@@ -409,8 +409,8 @@
 					case 3: /* device error */
 						pp->state = qs_state_idle;
 						qs_enter_reg_mode(qc->ap);
-						ata_qc_complete(qc,
-							ac_err_mask(sDST));
+						qc->err_mask |= ac_err_mask(sDST);
+						ata_qc_complete(qc);
 						break;
 					default:
 						break;
@@ -447,7 +447,8 @@
 
 				/* complete taskfile transaction */
 				pp->state = qs_state_idle;
-				ata_qc_complete(qc, ac_err_mask(status));
+				qc->err_mask |= ac_err_mask(status);
+				ata_qc_complete(qc);
 				handled = 1;
 			}
 		}
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 3609186..b017f85 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -147,7 +147,6 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 static const struct ata_port_operations sil_ops = {
@@ -176,7 +175,7 @@
 	.host_stop		= ata_pci_host_stop,
 };
 
-static struct ata_port_info sil_port_info[] = {
+static const struct ata_port_info sil_port_info[] = {
 	/* sil_3112 */
 	{
 		.sht		= &sil_sht,
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index e0d6f19..9231301 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -292,7 +292,6 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1, /* NCQ not supported yet */
 };
 
 static const struct ata_port_operations sil24_ops = {
@@ -654,7 +653,8 @@
 	 */
 	printk(KERN_ERR "ata%u: command timeout\n", ap->id);
 	qc->scsidone = scsi_finish_command;
-	ata_qc_complete(qc, AC_ERR_OTHER);
+	qc->err_mask |= AC_ERR_OTHER;
+	ata_qc_complete(qc);
 
 	sil24_reset_controller(ap);
 }
@@ -711,8 +711,10 @@
 		sil24_reset_controller(ap);
 	}
 
-	if (qc)
-		ata_qc_complete(qc, err_mask);
+	if (qc) {
+		qc->err_mask |= err_mask;
+		ata_qc_complete(qc);
+	}
 }
 
 static inline void sil24_host_intr(struct ata_port *ap)
@@ -734,8 +736,10 @@
 		 */
 		sil24_update_tf(ap);
 
-		if (qc)
-			ata_qc_complete(qc, ac_err_mask(pp->tf.command));
+		if (qc) {
+			qc->err_mask |= ac_err_mask(pp->tf.command);
+			ata_qc_complete(qc);
+		}
 	} else
 		sil24_error_intr(ap, slot_stat);
 }
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 32e1262..2df8c56 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -99,7 +99,6 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 static const struct ata_port_operations sis_ops = {
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 6e7f7c8..6683735 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -303,7 +303,6 @@
 	.proc_info		= k2_sata_proc_info,
 #endif
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index dcc3ad9..bc87c16 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -194,7 +194,6 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 static const struct ata_port_operations pdc_20621_ops = {
@@ -215,12 +214,13 @@
 	.host_stop		= pdc20621_host_stop,
 };
 
-static struct ata_port_info pdc_port_info[] = {
+static const struct ata_port_info pdc_port_info[] = {
 	/* board_20621 */
 	{
 		.sht		= &pdc_sata_sht,
 		.host_flags	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-				  ATA_FLAG_SRST | ATA_FLAG_MMIO,
+				  ATA_FLAG_SRST | ATA_FLAG_MMIO |
+				  ATA_FLAG_NO_ATAPI,
 		.pio_mask	= 0x1f, /* pio0-4 */
 		.mwdma_mask	= 0x07, /* mwdma0-2 */
 		.udma_mask	= 0x7f, /* udma0-6 ; FIXME */
@@ -718,7 +718,8 @@
 			VPRINTK("ata%u: read hdma, 0x%x 0x%x\n", ap->id,
 				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
 			/* get drive status; clear intr; complete txn */
-			ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
+			qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
+			ata_qc_complete(qc);
 			pdc20621_pop_hdma(qc);
 		}
 
@@ -756,7 +757,8 @@
 			VPRINTK("ata%u: write ata, 0x%x 0x%x\n", ap->id,
 				readl(mmio + 0x104), readl(mmio + PDC_HDMA_CTLSTAT));
 			/* get drive status; clear intr; complete txn */
-			ata_qc_complete(qc, ac_err_mask(ata_wait_idle(ap)));
+			qc->err_mask |= ac_err_mask(ata_wait_idle(ap));
+			ata_qc_complete(qc);
 			pdc20621_pop_hdma(qc);
 		}
 		handled = 1;
@@ -766,7 +768,8 @@
 
 		status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
 		DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
-		ata_qc_complete(qc, ac_err_mask(status));
+		qc->err_mask |= ac_err_mask(status);
+		ata_qc_complete(qc);
 		handled = 1;
 
 	} else {
@@ -881,7 +884,8 @@
 	case ATA_PROT_DMA:
 	case ATA_PROT_NODATA:
 		printk(KERN_ERR "ata%u: command timeout\n", ap->id);
-		ata_qc_complete(qc, __ac_err_mask(ata_wait_idle(ap)));
+		qc->err_mask |= __ac_err_mask(ata_wait_idle(ap));
+		ata_qc_complete(qc);
 		break;
 
 	default:
@@ -890,7 +894,8 @@
 		printk(KERN_ERR "ata%u: unknown timeout, cmd 0x%x stat 0x%x\n",
 		       ap->id, qc->tf.command, drv_stat);
 
-		ata_qc_complete(qc, ac_err_mask(drv_stat));
+		qc->err_mask |= ac_err_mask(drv_stat);
+		ata_qc_complete(qc);
 		break;
 	}
 
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c
index b2422a0..9635ca7 100644
--- a/drivers/scsi/sata_uli.c
+++ b/drivers/scsi/sata_uli.c
@@ -87,7 +87,6 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 static const struct ata_port_operations uli_ops = {
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index c762156..6d5b0a7 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -106,7 +106,6 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 static const struct ata_port_operations svia_sata_ops = {
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index fcfa486..2e2c3b7 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -235,7 +235,6 @@
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-	.ordered_flush		= 1,
 };
 
 
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index e69477d..f01ec0a 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -354,8 +354,9 @@
  *     @model, if found, return the matching flags value, else return
  *     the host or global default settings.
  **/
-int scsi_get_device_flags(struct scsi_device *sdev, unsigned char *vendor,
-			  unsigned char *model)
+int scsi_get_device_flags(struct scsi_device *sdev,
+			  const unsigned char *vendor,
+			  const unsigned char *model)
 {
 	struct scsi_dev_info_list *devinfo;
 	unsigned int bflags;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 18c5d25..a2333d2 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -422,10 +422,15 @@
  **/
 static void scsi_eh_done(struct scsi_cmnd *scmd)
 {
+	struct completion     *eh_action;
+
 	SCSI_LOG_ERROR_RECOVERY(3,
 		printk("%s scmd: %p result: %x\n",
 			__FUNCTION__, scmd, scmd->result));
-	complete(scmd->device->host->eh_action);
+
+	eh_action = scmd->device->host->eh_action;
+	if (eh_action)
+		complete(eh_action);
 }
 
 /**
@@ -1315,23 +1320,6 @@
 }
 
 /**
- * scsi_eh_lock_done - done function for eh door lock request
- * @scmd:	SCSI command block for the door lock request
- *
- * Notes:
- * 	We completed the asynchronous door lock request, and it has either
- * 	locked the door or failed.  We must free the command structures
- * 	associated with this request.
- **/
-static void scsi_eh_lock_done(struct scsi_cmnd *scmd)
-{
-	struct scsi_request *sreq = scmd->sc_request;
-
-	scsi_release_request(sreq);
-}
-
-
-/**
  * scsi_eh_lock_door - Prevent medium removal for the specified device
  * @sdev:	SCSI device to prevent medium removal
  *
@@ -1353,29 +1341,17 @@
  **/
 static void scsi_eh_lock_door(struct scsi_device *sdev)
 {
-	struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL);
+	unsigned char cmnd[MAX_COMMAND_SIZE];
 
-	if (unlikely(!sreq)) {
-		printk(KERN_ERR "%s: request allocate failed,"
-		       "prevent media removal cmd not sent\n", __FUNCTION__);
-		return;
-	}
+	cmnd[0] = ALLOW_MEDIUM_REMOVAL;
+	cmnd[1] = 0;
+	cmnd[2] = 0;
+	cmnd[3] = 0;
+	cmnd[4] = SCSI_REMOVAL_PREVENT;
+	cmnd[5] = 0;
 
-	sreq->sr_cmnd[0] = ALLOW_MEDIUM_REMOVAL;
-	sreq->sr_cmnd[1] = 0;
-	sreq->sr_cmnd[2] = 0;
-	sreq->sr_cmnd[3] = 0;
-	sreq->sr_cmnd[4] = SCSI_REMOVAL_PREVENT;
-	sreq->sr_cmnd[5] = 0;
-	sreq->sr_data_direction = DMA_NONE;
-	sreq->sr_bufflen = 0;
-	sreq->sr_buffer = NULL;
-	sreq->sr_allowed = 5;
-	sreq->sr_done = scsi_eh_lock_done;
-	sreq->sr_timeout_per_command = 10 * HZ;
-	sreq->sr_cmd_len = COMMAND_SIZE(sreq->sr_cmnd[0]);
-
-	scsi_insert_special_req(sreq, 1);
+	scsi_execute_async(sdev, cmnd, DMA_NONE, NULL, 0, 0, 10 * HZ,
+			   5, NULL, NULL, GFP_KERNEL);
 }
 
 
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ce9d73a..ba93d6e 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -63,39 +63,6 @@
 }; 	
 #undef SP
 
-
-/*
- * Function:    scsi_insert_special_req()
- *
- * Purpose:     Insert pre-formed request into request queue.
- *
- * Arguments:   sreq	- request that is ready to be queued.
- *              at_head	- boolean.  True if we should insert at head
- *                        of queue, false if we should insert at tail.
- *
- * Lock status: Assumed that lock is not held upon entry.
- *
- * Returns:     Nothing
- *
- * Notes:       This function is called from character device and from
- *              ioctl types of functions where the caller knows exactly
- *              what SCSI command needs to be issued.   The idea is that
- *              we merely inject the command into the queue (at the head
- *              for now), and then call the queue request function to actually
- *              process it.
- */
-int scsi_insert_special_req(struct scsi_request *sreq, int at_head)
-{
-	/*
-	 * Because users of this function are apt to reuse requests with no
-	 * modification, we have to sanitise the request flags here
-	 */
-	sreq->sr_request->flags &= ~REQ_DONTPREP;
-	blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
-		       	   at_head, sreq);
-	return 0;
-}
-
 static void scsi_run_queue(struct request_queue *q);
 
 /*
@@ -249,8 +216,13 @@
 
 	/*
 	 * head injection *required* here otherwise quiesce won't work
+	 *
+	 * Because users of this function are apt to reuse requests with no
+	 * modification, we have to sanitise the request flags here
 	 */
-	scsi_insert_special_req(sreq, 1);
+	sreq->sr_request->flags &= ~REQ_DONTPREP;
+	blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
+		       	   1, sreq);
 }
 EXPORT_SYMBOL(scsi_do_req);
 
@@ -287,6 +259,7 @@
 	memcpy(req->cmd, cmd, req->cmd_len);
 	req->sense = sense;
 	req->sense_len = 0;
+	req->retries = retries;
 	req->timeout = timeout;
 	req->flags |= flags | REQ_BLOCK_PC | REQ_SPECIAL | REQ_QUIET;
 
@@ -327,6 +300,200 @@
 }
 EXPORT_SYMBOL(scsi_execute_req);
 
+struct scsi_io_context {
+	void *data;
+	void (*done)(void *data, char *sense, int result, int resid);
+	char sense[SCSI_SENSE_BUFFERSIZE];
+};
+
+static kmem_cache_t *scsi_io_context_cache;
+
+static void scsi_end_async(struct request *req, int uptodate)
+{
+	struct scsi_io_context *sioc = req->end_io_data;
+
+	if (sioc->done)
+		sioc->done(sioc->data, sioc->sense, req->errors, req->data_len);
+
+	kmem_cache_free(scsi_io_context_cache, sioc);
+	__blk_put_request(req->q, req);
+}
+
+static int scsi_merge_bio(struct request *rq, struct bio *bio)
+{
+	struct request_queue *q = rq->q;
+
+	bio->bi_flags &= ~(1 << BIO_SEG_VALID);
+	if (rq_data_dir(rq) == WRITE)
+		bio->bi_rw |= (1 << BIO_RW);
+	blk_queue_bounce(q, &bio);
+
+	if (!rq->bio)
+		blk_rq_bio_prep(q, rq, bio);
+	else if (!q->back_merge_fn(q, rq, bio))
+		return -EINVAL;
+	else {
+		rq->biotail->bi_next = bio;
+		rq->biotail = bio;
+		rq->hard_nr_sectors += bio_sectors(bio);
+		rq->nr_sectors = rq->hard_nr_sectors;
+	}
+
+	return 0;
+}
+
+static int scsi_bi_endio(struct bio *bio, unsigned int bytes_done, int error)
+{
+	if (bio->bi_size)
+		return 1;
+
+	bio_put(bio);
+	return 0;
+}
+
+/**
+ * scsi_req_map_sg - map a scatterlist into a request
+ * @rq:		request to fill
+ * @sg:		scatterlist
+ * @nsegs:	number of elements
+ * @bufflen:	len of buffer
+ * @gfp:	memory allocation flags
+ *
+ * scsi_req_map_sg maps a scatterlist into a request so that the
+ * request can be sent to the block layer. We do not trust the scatterlist
+ * sent to use, as some ULDs use that struct to only organize the pages.
+ */
+static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
+			   int nsegs, unsigned bufflen, gfp_t gfp)
+{
+	struct request_queue *q = rq->q;
+	int nr_pages = (bufflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	unsigned int data_len = 0, len, bytes, off;
+	struct page *page;
+	struct bio *bio = NULL;
+	int i, err, nr_vecs = 0;
+
+	for (i = 0; i < nsegs; i++) {
+		page = sgl[i].page;
+		off = sgl[i].offset;
+		len = sgl[i].length;
+		data_len += len;
+
+		while (len > 0) {
+			bytes = min_t(unsigned int, len, PAGE_SIZE - off);
+
+			if (!bio) {
+				nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages);
+				nr_pages -= nr_vecs;
+
+				bio = bio_alloc(gfp, nr_vecs);
+				if (!bio) {
+					err = -ENOMEM;
+					goto free_bios;
+				}
+				bio->bi_end_io = scsi_bi_endio;
+			}
+
+			if (bio_add_pc_page(q, bio, page, bytes, off) !=
+			    bytes) {
+				bio_put(bio);
+				err = -EINVAL;
+				goto free_bios;
+			}
+
+			if (bio->bi_vcnt >= nr_vecs) {
+				err = scsi_merge_bio(rq, bio);
+				if (err) {
+					bio_endio(bio, bio->bi_size, 0);
+					goto free_bios;
+				}
+				bio = NULL;
+			}
+
+			page++;
+			len -= bytes;
+			off = 0;
+		}
+	}
+
+	rq->buffer = rq->data = NULL;
+	rq->data_len = data_len;
+	return 0;
+
+free_bios:
+	while ((bio = rq->bio) != NULL) {
+		rq->bio = bio->bi_next;
+		/*
+		 * call endio instead of bio_put incase it was bounced
+		 */
+		bio_endio(bio, bio->bi_size, 0);
+	}
+
+	return err;
+}
+
+/**
+ * scsi_execute_async - insert request
+ * @sdev:	scsi device
+ * @cmd:	scsi command
+ * @data_direction: data direction
+ * @buffer:	data buffer (this can be a kernel buffer or scatterlist)
+ * @bufflen:	len of buffer
+ * @use_sg:	if buffer is a scatterlist this is the number of elements
+ * @timeout:	request timeout in seconds
+ * @retries:	number of times to retry request
+ * @flags:	or into request flags
+ **/
+int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd,
+		       int data_direction, void *buffer, unsigned bufflen,
+		       int use_sg, int timeout, int retries, void *privdata,
+		       void (*done)(void *, char *, int, int), gfp_t gfp)
+{
+	struct request *req;
+	struct scsi_io_context *sioc;
+	int err = 0;
+	int write = (data_direction == DMA_TO_DEVICE);
+
+	sioc = kmem_cache_alloc(scsi_io_context_cache, gfp);
+	if (!sioc)
+		return DRIVER_ERROR << 24;
+	memset(sioc, 0, sizeof(*sioc));
+
+	req = blk_get_request(sdev->request_queue, write, gfp);
+	if (!req)
+		goto free_sense;
+	req->flags |= REQ_BLOCK_PC | REQ_QUIET;
+
+	if (use_sg)
+		err = scsi_req_map_sg(req, buffer, use_sg, bufflen, gfp);
+	else if (bufflen)
+		err = blk_rq_map_kern(req->q, req, buffer, bufflen, gfp);
+
+	if (err)
+		goto free_req;
+
+	req->cmd_len = COMMAND_SIZE(cmd[0]);
+	memcpy(req->cmd, cmd, req->cmd_len);
+	req->sense = sioc->sense;
+	req->sense_len = 0;
+	req->timeout = timeout;
+	req->retries = retries;
+	req->end_io_data = sioc;
+
+	sioc->data = privdata;
+	sioc->done = done;
+
+	blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async);
+	return 0;
+
+free_req:
+	blk_put_request(req);
+free_sense:
+	kfree(sioc);
+	return DRIVER_ERROR << 24;
+}
+EXPORT_SYMBOL_GPL(scsi_execute_async);
+
 /*
  * Function:    scsi_init_cmd_errh()
  *
@@ -624,7 +791,7 @@
 	spin_lock_irqsave(q->queue_lock, flags);
 	if (blk_rq_tagged(req))
 		blk_queue_end_tag(q, req);
-	end_that_request_last(req);
+	end_that_request_last(req, uptodate);
 	spin_unlock_irqrestore(q->queue_lock, flags);
 
 	/*
@@ -765,9 +932,6 @@
 	int sense_valid = 0;
 	int sense_deferred = 0;
 
-	if (blk_complete_barrier_rq(q, req, good_bytes >> 9))
-		return;
-
 	/*
 	 * Free up any indirection buffers we allocated for DMA purposes. 
 	 * For the case of a READ, we need to copy the data out of the
@@ -884,7 +1048,8 @@
 			* system where READ CAPACITY failed, we may have read
 			* past the end of the disk.
 		 	*/
-			if (cmd->device->use_10_for_rw &&
+			if ((cmd->device->use_10_for_rw &&
+			    sshdr.asc == 0x20 && sshdr.ascq == 0x00) &&
 			    (cmd->cmnd[0] == READ_10 ||
 			     cmd->cmnd[0] == WRITE_10)) {
 				cmd->device->use_10_for_rw = 0;
@@ -1031,38 +1196,6 @@
 	return BLKPREP_KILL;
 }
 
-static int scsi_prepare_flush_fn(request_queue_t *q, struct request *rq)
-{
-	struct scsi_device *sdev = q->queuedata;
-	struct scsi_driver *drv;
-
-	if (sdev->sdev_state == SDEV_RUNNING) {
-		drv = *(struct scsi_driver **) rq->rq_disk->private_data;
-
-		if (drv->prepare_flush)
-			return drv->prepare_flush(q, rq);
-	}
-
-	return 0;
-}
-
-static void scsi_end_flush_fn(request_queue_t *q, struct request *rq)
-{
-	struct scsi_device *sdev = q->queuedata;
-	struct request *flush_rq = rq->end_io_data;
-	struct scsi_driver *drv;
-
-	if (flush_rq->errors) {
-		printk("scsi: barrier error, disabling flush support\n");
-		blk_queue_ordered(q, QUEUE_ORDERED_NONE);
-	}
-
-	if (sdev->sdev_state == SDEV_RUNNING) {
-		drv = *(struct scsi_driver **) rq->rq_disk->private_data;
-		drv->end_flush(q, rq);
-	}
-}
-
 static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
 			       sector_t *error_sector)
 {
@@ -1082,9 +1215,35 @@
 static void scsi_generic_done(struct scsi_cmnd *cmd)
 {
 	BUG_ON(!blk_pc_request(cmd->request));
-	scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0);
+	/*
+	 * This will complete the whole command with uptodate=1 so
+	 * as far as the block layer is concerned the command completed
+	 * successfully. Since this is a REQ_BLOCK_PC command the
+	 * caller should check the request's errors value
+	 */
+	scsi_io_completion(cmd, cmd->bufflen, 0);
 }
 
+void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd)
+{
+	struct request *req = cmd->request;
+
+	BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
+	memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
+	cmd->cmd_len = req->cmd_len;
+	if (!req->data_len)
+		cmd->sc_data_direction = DMA_NONE;
+	else if (rq_data_dir(req) == WRITE)
+		cmd->sc_data_direction = DMA_TO_DEVICE;
+	else
+		cmd->sc_data_direction = DMA_FROM_DEVICE;
+	
+	cmd->transfersize = req->data_len;
+	cmd->allowed = req->retries;
+	cmd->timeout_per_command = req->timeout;
+}
+EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd);
+
 static int scsi_prep_fn(struct request_queue *q, struct request *req)
 {
 	struct scsi_device *sdev = q->queuedata;
@@ -1220,18 +1379,7 @@
 				goto kill;
 			}
 		} else {
-			memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
-			cmd->cmd_len = req->cmd_len;
-			if (rq_data_dir(req) == WRITE)
-				cmd->sc_data_direction = DMA_TO_DEVICE;
-			else if (req->data_len)
-				cmd->sc_data_direction = DMA_FROM_DEVICE;
-			else
-				cmd->sc_data_direction = DMA_NONE;
-			
-			cmd->transfersize = req->data_len;
-			cmd->allowed = 3;
-			cmd->timeout_per_command = req->timeout;
+			scsi_setup_blk_pc_cmnd(cmd);
 			cmd->done = scsi_generic_done;
 		}
 	}
@@ -1520,17 +1668,6 @@
 	blk_queue_segment_boundary(q, shost->dma_boundary);
 	blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);
 
-	/*
-	 * ordered tags are superior to flush ordering
-	 */
-	if (shost->ordered_tag)
-		blk_queue_ordered(q, QUEUE_ORDERED_TAG);
-	else if (shost->ordered_flush) {
-		blk_queue_ordered(q, QUEUE_ORDERED_FLUSH);
-		q->prepare_flush_fn = scsi_prepare_flush_fn;
-		q->end_flush_fn = scsi_end_flush_fn;
-	}
-
 	if (!shost->use_clustering)
 		clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
 	return q;
@@ -1594,6 +1731,14 @@
 {
 	int i;
 
+	scsi_io_context_cache = kmem_cache_create("scsi_io_context",
+					sizeof(struct scsi_io_context),
+					0, 0, NULL, NULL);
+	if (!scsi_io_context_cache) {
+		printk(KERN_ERR "SCSI: can't init scsi io context cache\n");
+		return -ENOMEM;
+	}
+
 	for (i = 0; i < SG_MEMPOOL_NR; i++) {
 		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
 		int size = sgp->size * sizeof(struct scatterlist);
@@ -1621,6 +1766,8 @@
 {
 	int i;
 
+	kmem_cache_destroy(scsi_io_context_cache);
+
 	for (i = 0; i < SG_MEMPOOL_NR; i++) {
 		struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
 		mempool_destroy(sgp->pool);
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index d632d9e..f04e7e1 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -40,7 +40,6 @@
 extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
 extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
 extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
-extern int scsi_insert_special_req(struct scsi_request *sreq, int);
 extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
 		struct scsi_request *sreq);
 extern void __scsi_release_request(struct scsi_request *sreq);
@@ -57,7 +56,8 @@
 
 /* scsi_devinfo.c */
 extern int scsi_get_device_flags(struct scsi_device *sdev,
-				 unsigned char *vendor, unsigned char *model);
+				 const unsigned char *vendor,
+				 const unsigned char *model);
 extern int __init scsi_init_devinfo(void);
 extern void scsi_exit_devinfo(void);
 
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 374853d..05ebb9c 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -74,7 +74,7 @@
 #define SCSI_SCAN_TARGET_PRESENT	1
 #define SCSI_SCAN_LUN_PRESENT		2
 
-static char *scsi_null_device_strs = "nullnullnullnull";
+static const char *scsi_null_device_strs = "nullnullnullnull";
 
 #define MAX_SCSI_LUNS	512
 
@@ -266,8 +266,6 @@
 			/*
 			 * if LLDD reports slave not present, don't clutter
 			 * console with alloc failure messages
-
-
 			 */
 			if (ret == -ENXIO)
 				display_failure_msg = 0;
@@ -279,7 +277,6 @@
 
 out_device_destroy:
 	transport_destroy_device(&sdev->sdev_gendev);
-	scsi_free_queue(sdev->request_queue);
 	put_device(&sdev->sdev_gendev);
 out:
 	if (display_failure_msg)
@@ -403,6 +400,36 @@
 	return found_target;
 }
 
+struct work_queue_wrapper {
+	struct work_struct	work;
+	struct scsi_target	*starget;
+};
+
+static void scsi_target_reap_work(void *data) {
+	struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data;
+	struct scsi_target *starget = wqw->starget;
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	unsigned long flags;
+
+	kfree(wqw);
+
+	spin_lock_irqsave(shost->host_lock, flags);
+
+	if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
+		list_del_init(&starget->siblings);
+		spin_unlock_irqrestore(shost->host_lock, flags);
+		transport_remove_device(&starget->dev);
+		device_del(&starget->dev);
+		transport_destroy_device(&starget->dev);
+		put_device(&starget->dev);
+		return;
+
+	}
+	spin_unlock_irqrestore(shost->host_lock, flags);
+
+	return;
+}
+
 /**
  * scsi_target_reap - check to see if target is in use and destroy if not
  *
@@ -414,19 +441,18 @@
  */
 void scsi_target_reap(struct scsi_target *starget)
 {
-	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
-	unsigned long flags;
-	spin_lock_irqsave(shost->host_lock, flags);
+	struct work_queue_wrapper *wqw = 
+		kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC);
 
-	if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
-		list_del_init(&starget->siblings);
-		spin_unlock_irqrestore(shost->host_lock, flags);
-		device_del(&starget->dev);
-		transport_unregister_device(&starget->dev);
-		put_device(&starget->dev);
+	if (!wqw) {
+		starget_printk(KERN_ERR, starget,
+			       "Failed to allocate memory in scsi_reap_target()\n");
 		return;
 	}
-	spin_unlock_irqrestore(shost->host_lock, flags);
+
+	INIT_WORK(&wqw->work, scsi_target_reap_work, wqw);
+	wqw->starget = starget;
+	schedule_work(&wqw->work);
 }
 
 /**
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 4634929..ea7f3a4 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -21,7 +21,7 @@
 #include "scsi_priv.h"
 #include "scsi_logging.h"
 
-static struct {
+static const struct {
 	enum scsi_device_state	value;
 	char			*name;
 } sdev_states[] = {
@@ -48,7 +48,7 @@
 	return name;
 }
 
-static struct {
+static const struct {
 	enum scsi_host_state	value;
 	char			*name;
 } shost_states[] = {
@@ -263,9 +263,40 @@
 	return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
 }
 
+static int scsi_bus_suspend(struct device * dev, pm_message_t state)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct scsi_host_template *sht = sdev->host->hostt;
+	int err;
+
+	err = scsi_device_quiesce(sdev);
+	if (err)
+		return err;
+
+	if (sht->suspend)
+		err = sht->suspend(sdev);
+
+	return err;
+}
+
+static int scsi_bus_resume(struct device * dev)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct scsi_host_template *sht = sdev->host->hostt;
+	int err = 0;
+
+	if (sht->resume)
+		err = sht->resume(sdev);
+
+	scsi_device_resume(sdev);
+	return err;
+}
+
 struct bus_type scsi_bus_type = {
         .name		= "scsi",
         .match		= scsi_bus_match,
+	.suspend	= scsi_bus_suspend,
+	.resume		= scsi_bus_resume,
 };
 
 int scsi_sysfs_register(void)
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 6cd5931..685b997 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -105,13 +105,14 @@
 	{ FC_PORTSTATE_LINKDOWN,	"Linkdown" },
 	{ FC_PORTSTATE_ERROR,		"Error" },
 	{ FC_PORTSTATE_LOOPBACK,	"Loopback" },
+	{ FC_PORTSTATE_DELETED,		"Deleted" },
 };
 fc_enum_name_search(port_state, fc_port_state, fc_port_state_names)
 #define FC_PORTSTATE_MAX_NAMELEN	20
 
 
 /* Convert fc_tgtid_binding_type values to ascii string name */
-static struct {
+static const struct {
 	enum fc_tgtid_binding_type	value;
 	char				*name;
 	int				matchlen;
@@ -149,7 +150,7 @@
 
 
 /* Convert FC_COS bit values to ascii string name */
-static struct {
+static const struct {
 	u32 			value;
 	char			*name;
 } fc_cos_names[] = {
@@ -163,7 +164,7 @@
 
 
 /* Convert FC_PORTSPEED bit values to ascii string name */
-static struct {
+static const struct {
 	u32 			value;
 	char			*name;
 } fc_port_speed_names[] = {
@@ -189,7 +190,7 @@
 
 
 /* Convert FC_RPORT_ROLE bit values to ascii string name */
-static struct {
+static const struct {
 	u32 			value;
 	char			*name;
 } fc_remote_port_role_names[] = {
@@ -211,6 +212,7 @@
 #define FC_MGMTSRVR_PORTID		0x00000a
 
 
+static void fc_shost_remove_rports(void  *data);
 static void fc_timeout_deleted_rport(void *data);
 static void fc_scsi_scan_rport(void *data);
 static void fc_rport_terminate(struct fc_rport  *rport);
@@ -318,6 +320,8 @@
 	fc_host_next_rport_number(shost) = 0;
 	fc_host_next_target_id(shost) = 0;
 
+	fc_host_flags(shost) = 0;
+	INIT_WORK(&fc_host_rport_del_work(shost), fc_shost_remove_rports, shost);
 	return 0;
 }
 
@@ -387,6 +391,7 @@
 	struct fc_internal *i = to_fc_internal(shost->transportt);	\
 	if ((i->f->get_rport_##field) &&				\
 	    !((rport->port_state == FC_PORTSTATE_BLOCKED) ||		\
+	      (rport->port_state == FC_PORTSTATE_DELETED) ||		\
 	      (rport->port_state == FC_PORTSTATE_NOTPRESENT)))		\
 		i->f->get_rport_##field(rport);				\
 	return snprintf(buf, sz, format_string, cast rport->field); 	\
@@ -402,6 +407,7 @@
 	struct Scsi_Host *shost = rport_to_shost(rport);		\
 	struct fc_internal *i = to_fc_internal(shost->transportt);	\
 	if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||		\
+	    (rport->port_state == FC_PORTSTATE_DELETED) ||		\
 	    (rport->port_state == FC_PORTSTATE_NOTPRESENT))		\
 		return -EBUSY;						\
 	val = simple_strtoul(buf, NULL, 0);				\
@@ -519,6 +525,7 @@
 	struct Scsi_Host *shost = rport_to_shost(rport);
 	struct fc_internal *i = to_fc_internal(shost->transportt);
 	if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
+	    (rport->port_state == FC_PORTSTATE_DELETED) ||
 	    (rport->port_state == FC_PORTSTATE_NOTPRESENT))
 		return -EBUSY;
 	val = simple_strtoul(buf, NULL, 0);
@@ -1769,7 +1776,7 @@
 	rport->maxframe_size = -1;
 	rport->supported_classes = FC_COS_UNSPECIFIED;
 	rport->roles = FC_RPORT_ROLE_UNKNOWN;
-	rport->port_state = FC_PORTSTATE_NOTPRESENT;
+	rport->port_state = FC_PORTSTATE_DELETED;
 
 	/* remove the identifiers that aren't used in the consisting binding */
 	switch (fc_host_tgtid_bind_type(shost)) {
@@ -1789,14 +1796,23 @@
 		break;
 	}
 
-	spin_unlock_irqrestore(shost->host_lock, flags);
-
 	/*
 	 * As this only occurs if the remote port (scsi target)
 	 * went away and didn't come back - we'll remove
 	 * all attached scsi devices.
+	 *
+	 * We'll schedule the shost work item to perform the actual removal
+	 * to avoid recursion in the different flush calls if we perform
+	 * the removal in each target - and there are lots of targets
+	 * whose timeouts fire at the same time.
 	 */
-	fc_rport_tgt_remove(rport);
+
+	if ( !(fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED)) {
+		fc_host_flags(shost) |= FC_SHOST_RPORT_DEL_SCHEDULED;
+		scsi_queue_work(shost, &fc_host_rport_del_work(shost));
+	}
+
+	spin_unlock_irqrestore(shost->host_lock, flags);
 }
 
 /**
@@ -1818,6 +1834,41 @@
 }
 
 
+/**
+ * fc_shost_remove_rports - called to remove all rports that are marked
+ *                       as in a deleted (not connected) state.
+ * 
+ * @data:	shost whose rports are to be looked at
+ **/
+static void
+fc_shost_remove_rports(void  *data)
+{
+	struct Scsi_Host *shost = (struct Scsi_Host *)data;
+	struct fc_rport *rport, *next_rport;
+	unsigned long flags;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	while (fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED) {
+
+		fc_host_flags(shost) &= ~FC_SHOST_RPORT_DEL_SCHEDULED;
+
+restart_search:
+		list_for_each_entry_safe(rport, next_rport,
+				&fc_host_rport_bindings(shost), peers) {
+			if (rport->port_state == FC_PORTSTATE_DELETED) {
+				rport->port_state = FC_PORTSTATE_NOTPRESENT;
+				spin_unlock_irqrestore(shost->host_lock, flags);
+				fc_rport_tgt_remove(rport);
+				spin_lock_irqsave(shost->host_lock, flags);
+				goto restart_search;
+			}
+		}
+
+	}
+	spin_unlock_irqrestore(shost->host_lock, flags);
+}
+
+
 MODULE_AUTHOR("Martin Hicks");
 MODULE_DESCRIPTION("FC Transport Attributes");
 MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 49fd18c..e08462d 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -249,7 +249,7 @@
 }
 
 static void*
-mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data)
+mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data)
 {
 	struct mempool_zone *zone = pool_data;
 
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 718a2bc..46da6fe 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -18,6 +18,7 @@
  *  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/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -378,9 +379,7 @@
 
 /* Translate the period into ns according to the current spec
  * for SDTR/PPR messages */
-static ssize_t
-show_spi_transport_period_helper(struct class_device *cdev, char *buf,
-				 int period)
+static int period_to_str(char *buf, int period)
 {
 	int len, picosec;
 
@@ -398,6 +397,14 @@
 		len = sprint_frac(buf, picosec, 1000);
 	}
 
+	return len;
+}
+
+static ssize_t
+show_spi_transport_period_helper(struct class_device *cdev, char *buf,
+				 int period)
+{
+	int len = period_to_str(buf, period);
 	buf[len++] = '\n';
 	buf[len] = '\0';
 	return len;
@@ -812,12 +819,10 @@
 	if (!scsi_device_sync(sdev) && !scsi_device_dt(sdev))
 		return;
 
-	/* see if the device has an echo buffer.  If it does we can
-	 * do the SPI pattern write tests */
-
-	len = 0;
-	if (scsi_device_dt(sdev))
-		len = spi_dv_device_get_echo_buffer(sdev, buffer);
+	/* len == -1 is the signal that we need to ascertain the
+	 * presence of an echo buffer before trying to use it.  len ==
+	 * 0 means we don't have an echo buffer */
+	len = -1;
 
  retry:
 
@@ -840,11 +845,23 @@
 		if (spi_min_period(starget) == 8)
 			DV_SET(pcomp_en, 1);
 	}
+	/* Do the read only INQUIRY tests */
+	spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len,
+		       spi_dv_device_compare_inquiry);
+	/* See if we actually managed to negotiate and sustain DT */
+	if (i->f->get_dt)
+		i->f->get_dt(starget);
 
-	if (len == 0) {
+	/* see if the device has an echo buffer.  If it does we can do
+	 * the SPI pattern write tests.  Because of some broken
+	 * devices, we *only* try this on a device that has actually
+	 * negotiated DT */
+
+	if (len == -1 && spi_dt(starget))
+		len = spi_dv_device_get_echo_buffer(sdev, buffer);
+
+	if (len <= 0) {
 		starget_printk(KERN_INFO, starget, "Domain Validation skipping write tests\n");
-		spi_dv_retrain(sdev, buffer, buffer + len,
-			       spi_dv_device_compare_inquiry);
 		return;
 	}
 
@@ -1031,12 +1048,133 @@
 			 tp->hold_mcs ? " HMCS" : "",
 			 tmp, tp->offset);
 	} else {
-		dev_info(&starget->dev, "%sasynchronous.\n",
+		dev_info(&starget->dev, "%sasynchronous\n",
 				tp->width ? "wide " : "");
 	}
 }
 EXPORT_SYMBOL(spi_display_xfer_agreement);
 
+#ifdef CONFIG_SCSI_CONSTANTS
+static const char * const one_byte_msgs[] = {
+/* 0x00 */ "Command Complete", NULL, "Save Pointers",
+/* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error", 
+/* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error",
+/* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag",
+/* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue", 
+/* 0x0f */ "Initiate Recovery", "Release Recovery"
+};
+
+static const char * const two_byte_msgs[] = {
+/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag",
+/* 0x23 */ "Ignore Wide Residue"
+};
+
+static const char * const extended_msgs[] = {
+/* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
+/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request",
+/* 0x04 */ "Parallel Protocol Request"
+};
+
+void print_nego(const unsigned char *msg, int per, int off, int width)
+{
+	if (per) {
+		char buf[20];
+		period_to_str(buf, msg[per]);
+		printk("period = %s ns ", buf);
+	}
+
+	if (off)
+		printk("offset = %d ", msg[off]);
+	if (width)
+		printk("width = %d ", 8 << msg[width]);
+}
+
+int spi_print_msg(const unsigned char *msg)
+{
+	int len = 0, i;
+	if (msg[0] == EXTENDED_MESSAGE) {
+		len = 3 + msg[1];
+		if (msg[2] < ARRAY_SIZE(extended_msgs))
+			printk ("%s ", extended_msgs[msg[2]]); 
+		else 
+			printk ("Extended Message, reserved code (0x%02x) ",
+				(int) msg[2]);
+		switch (msg[2]) {
+		case EXTENDED_MODIFY_DATA_POINTER:
+			printk("pointer = %d", (int) (msg[3] << 24) |
+				(msg[4] << 16) | (msg[5] << 8) | msg[6]);
+			break;
+		case EXTENDED_SDTR:
+			print_nego(msg, 3, 4, 0);
+			break;
+		case EXTENDED_WDTR:
+			print_nego(msg, 0, 0, 3);
+			break;
+		case EXTENDED_PPR:
+			print_nego(msg, 3, 5, 6);
+			break;
+		default:
+		for (i = 2; i < len; ++i) 
+			printk("%02x ", msg[i]);
+		}
+	/* Identify */
+	} else if (msg[0] & 0x80) {
+		printk("Identify disconnect %sallowed %s %d ",
+			(msg[0] & 0x40) ? "" : "not ",
+			(msg[0] & 0x20) ? "target routine" : "lun",
+			msg[0] & 0x7);
+		len = 1;
+	/* Normal One byte */
+	} else if (msg[0] < 0x1f) {
+		if (msg[0] < ARRAY_SIZE(one_byte_msgs))
+			printk(one_byte_msgs[msg[0]]);
+		else
+			printk("reserved (%02x) ", msg[0]);
+		len = 1;
+	/* Two byte */
+	} else if (msg[0] <= 0x2f) {
+		if ((msg[0] - 0x20) < ARRAY_SIZE(two_byte_msgs))
+			printk("%s %02x ", two_byte_msgs[msg[0] - 0x20], 
+				msg[1]);
+		else 
+			printk("reserved two byte (%02x %02x) ", 
+				msg[0], msg[1]);
+		len = 2;
+	} else 
+		printk("reserved");
+	return len;
+}
+EXPORT_SYMBOL(spi_print_msg);
+
+#else  /* ifndef CONFIG_SCSI_CONSTANTS */
+
+int spi_print_msg(const unsigned char *msg)
+{
+	int len = 0, i;
+
+	if (msg[0] == EXTENDED_MESSAGE) {
+		len = 3 + msg[1];
+		for (i = 0; i < len; ++i)
+			printk("%02x ", msg[i]);
+	/* Identify */
+	} else if (msg[0] & 0x80) {
+		printk("%02x ", msg[0]);
+		len = 1;
+	/* Normal One byte */
+	} else if (msg[0] < 0x1f) {
+		printk("%02x ", msg[0]);
+		len = 1;
+	/* Two byte */
+	} else if (msg[0] <= 0x2f) {
+		printk("%02x %02x", msg[0], msg[1]);
+		len = 2;
+	} else 
+		printk("%02x ", msg[0]);
+	return len;
+}
+EXPORT_SYMBOL(spi_print_msg);
+#endif /* ! CONFIG_SCSI_CONSTANTS */
+
 #define SETUP_ATTRIBUTE(field)						\
 	i->private_attrs[count] = class_device_attr_##field;		\
 	if (!i->f->set_##field) {					\
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 8613a13..4c5127e 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -102,6 +102,7 @@
 	u8		write_prot;
 	unsigned	WCE : 1;	/* state of disk WCE bit */
 	unsigned	RCD : 1;	/* state of disk RCD bit, unused */
+	unsigned	DPOFUA : 1;	/* state of disk DPOFUA bit */
 };
 
 static DEFINE_IDR(sd_index_idr);
@@ -121,8 +122,7 @@
 static void sd_rescan(struct device *);
 static int sd_init_command(struct scsi_cmnd *);
 static int sd_issue_flush(struct device *, sector_t *);
-static void sd_end_flush(request_queue_t *, struct request *);
-static int sd_prepare_flush(request_queue_t *, struct request *);
+static void sd_prepare_flush(request_queue_t *, struct request *);
 static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
 			     unsigned char *buffer);
 
@@ -137,8 +137,6 @@
 	.rescan			= sd_rescan,
 	.init_command		= sd_init_command,
 	.issue_flush		= sd_issue_flush,
-	.prepare_flush		= sd_prepare_flush,
-	.end_flush		= sd_end_flush,
 };
 
 /*
@@ -245,24 +243,10 @@
 	 * SG_IO from block layer already setup, just copy cdb basically
 	 */
 	if (blk_pc_request(rq)) {
-		if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
-			return 0;
-
-		memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
-		SCpnt->cmd_len = rq->cmd_len;
-		if (rq_data_dir(rq) == WRITE)
-			SCpnt->sc_data_direction = DMA_TO_DEVICE;
-		else if (rq->data_len)
-			SCpnt->sc_data_direction = DMA_FROM_DEVICE;
-		else
-			SCpnt->sc_data_direction = DMA_NONE;
-
-		this_count = rq->data_len;
+		scsi_setup_blk_pc_cmnd(SCpnt);
 		if (rq->timeout)
 			timeout = rq->timeout;
 
-		SCpnt->transfersize = rq->data_len;
-		SCpnt->allowed = SD_PASSTHROUGH_RETRIES;
 		goto queue;
 	}
 
@@ -360,6 +344,7 @@
 	
 	if (block > 0xffffffff) {
 		SCpnt->cmnd[0] += READ_16 - READ_6;
+		SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0;
 		SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0;
 		SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0;
 		SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0;
@@ -379,6 +364,7 @@
 			this_count = 0xffff;
 
 		SCpnt->cmnd[0] += READ_10 - READ_6;
+		SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0;
 		SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
 		SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff;
 		SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff;
@@ -387,6 +373,17 @@
 		SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff;
 		SCpnt->cmnd[8] = (unsigned char) this_count & 0xff;
 	} else {
+		if (unlikely(blk_fua_rq(rq))) {
+			/*
+			 * This happens only if this drive failed
+			 * 10byte rw command with ILLEGAL_REQUEST
+			 * during operation and thus turned off
+			 * use_10_for_rw.
+			 */
+			printk(KERN_ERR "sd: FUA write on READ/WRITE(6) drive\n");
+			return 0;
+		}
+
 		SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f);
 		SCpnt->cmnd[2] = (unsigned char) ((block >> 8) & 0xff);
 		SCpnt->cmnd[3] = (unsigned char) block & 0xff;
@@ -530,7 +527,7 @@
 	return 0;
 }
 
-static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *loc)
+static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 {
 	struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk);
 	struct scsi_device *sdp = sdkp->device;
@@ -548,15 +545,9 @@
 	else
 		scsicam_bios_param(bdev, sdkp->capacity, diskinfo);
 
-	if (put_user(diskinfo[0], &loc->heads))
-		return -EFAULT;
-	if (put_user(diskinfo[1], &loc->sectors))
-		return -EFAULT;
-	if (put_user(diskinfo[2], &loc->cylinders))
-		return -EFAULT;
-	if (put_user((unsigned)get_start_sect(bdev),
-	             (unsigned long __user *)&loc->start))
-		return -EFAULT;
+	geo->heads = diskinfo[0];
+	geo->sectors = diskinfo[1];
+	geo->cylinders = diskinfo[2];
 	return 0;
 }
 
@@ -596,12 +587,6 @@
 	if (!scsi_block_when_processing_errors(sdp) || !error)
 		return error;
 
-	if (cmd == HDIO_GETGEO) {
-		if (!arg)
-			return -EINVAL;
-		return sd_hdio_getgeo(bdev, p);
-	}
-
 	/*
 	 * Send SCSI addressing ioctls directly to mid level, send other
 	 * ioctls to block level and then onto mid level if they can't be
@@ -743,42 +728,13 @@
 	return ret;
 }
 
-static void sd_end_flush(request_queue_t *q, struct request *flush_rq)
+static void sd_prepare_flush(request_queue_t *q, struct request *rq)
 {
-	struct request *rq = flush_rq->end_io_data;
-	struct scsi_cmnd *cmd = rq->special;
-	unsigned int bytes = rq->hard_nr_sectors << 9;
-
-	if (!flush_rq->errors) {
-		spin_unlock(q->queue_lock);
-		scsi_io_completion(cmd, bytes, 0);
-		spin_lock(q->queue_lock);
-	} else if (blk_barrier_postflush(rq)) {
-		spin_unlock(q->queue_lock);
-		scsi_io_completion(cmd, 0, bytes);
-		spin_lock(q->queue_lock);
-	} else {
-		/*
-		 * force journal abort of barriers
-		 */
-		end_that_request_first(rq, -EOPNOTSUPP, rq->hard_nr_sectors);
-		end_that_request_last(rq);
-	}
-}
-
-static int sd_prepare_flush(request_queue_t *q, struct request *rq)
-{
-	struct scsi_device *sdev = q->queuedata;
-	struct scsi_disk *sdkp = dev_get_drvdata(&sdev->sdev_gendev);
-
-	if (!sdkp || !sdkp->WCE)
-		return 0;
-
 	memset(rq->cmd, 0, sizeof(rq->cmd));
-	rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
+	rq->flags |= REQ_BLOCK_PC;
 	rq->timeout = SD_TIMEOUT;
 	rq->cmd[0] = SYNCHRONIZE_CACHE;
-	return 1;
+	rq->cmd_len = 10;
 }
 
 static void sd_rescan(struct device *dev)
@@ -832,6 +788,7 @@
 	.open			= sd_open,
 	.release		= sd_release,
 	.ioctl			= sd_ioctl,
+	.getgeo			= sd_getgeo,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl		= sd_compat_ioctl,
 #endif
@@ -1441,10 +1398,18 @@
 			sdkp->RCD = 0;
 		}
 
+		sdkp->DPOFUA = (data.device_specific & 0x10) != 0;
+		if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) {
+			printk(KERN_NOTICE "SCSI device %s: uses "
+			       "READ/WRITE(6), disabling FUA\n", diskname);
+			sdkp->DPOFUA = 0;
+		}
+
 		ct =  sdkp->RCD + 2*sdkp->WCE;
 
-		printk(KERN_NOTICE "SCSI device %s: drive cache: %s\n",
-		       diskname, types[ct]);
+		printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n",
+		       diskname, types[ct],
+		       sdkp->DPOFUA ? " w/ FUA" : "");
 
 		return;
 	}
@@ -1476,6 +1441,7 @@
 	struct scsi_disk *sdkp = scsi_disk(disk);
 	struct scsi_device *sdp = sdkp->device;
 	unsigned char *buffer;
+	unsigned ordered;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name));
 
@@ -1509,12 +1475,24 @@
 	 */
 	if (sdkp->media_present) {
 		sd_read_capacity(sdkp, disk->disk_name, buffer);
-		if (sdp->removable)
-			sd_read_write_protect_flag(sdkp, disk->disk_name,
-						   buffer);
+		sd_read_write_protect_flag(sdkp, disk->disk_name, buffer);
 		sd_read_cache_type(sdkp, disk->disk_name, buffer);
 	}
-		
+
+	/*
+	 * We now have all cache related info, determine how we deal
+	 * with ordered requests.  Note that as the current SCSI
+	 * dispatch function can alter request order, we cannot use
+	 * QUEUE_ORDERED_TAG_* even when ordered tag is supported.
+	 */
+	if (sdkp->WCE)
+		ordered = sdkp->DPOFUA
+			? QUEUE_ORDERED_DRAIN_FUA : QUEUE_ORDERED_DRAIN_FLUSH;
+	else
+		ordered = QUEUE_ORDERED_DRAIN;
+
+	blk_queue_ordered(sdkp->disk->queue, ordered, sd_prepare_flush);
+
 	set_capacity(disk, sdkp->capacity);
 	kfree(buffer);
 
@@ -1614,6 +1592,7 @@
 	strcpy(gd->devfs_name, sdp->devfs_name);
 
 	gd->private_data = &sdkp->driver;
+	gd->queue = sdkp->device->request_queue;
 
 	sd_revalidate_disk(gd);
 
@@ -1621,7 +1600,6 @@
 	gd->flags = GENHD_FL_DRIVERFS;
 	if (sdp->removable)
 		gd->flags |= GENHD_FL_REMOVABLE;
-	gd->queue = sdkp->device->request_queue;
 
 	dev_set_drvdata(dev, sdkp);
 	add_disk(gd);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 72ec594..221e96e 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -104,8 +104,6 @@
 static int sg_add(struct class_device *, struct class_interface *);
 static void sg_remove(struct class_device *, struct class_interface *);
 
-static Scsi_Request *dummy_cmdp;	/* only used for sizeof */
-
 static DEFINE_RWLOCK(sg_dev_arr_lock);	/* Also used to lock
 							   file descriptor list for device */
 
@@ -119,7 +117,7 @@
 	unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */
 	unsigned bufflen;	/* Size of (aggregate) data buffer */
 	unsigned b_malloc_len;	/* actual len malloc'ed in buffer */
-	void *buffer;		/* Data buffer or scatter list (k_use_sg>0) */
+	struct scatterlist *buffer;/* scatter list */
 	char dio_in_use;	/* 0->indirect IO (or mmap), 1->dio */
 	unsigned char cmd_opcode; /* first byte of command */
 } Sg_scatter_hold;
@@ -128,12 +126,11 @@
 struct sg_fd;
 
 typedef struct sg_request {	/* SG_MAX_QUEUE requests outstanding per file */
-	Scsi_Request *my_cmdp;	/* != 0  when request with lower levels */
 	struct sg_request *nextrp;	/* NULL -> tail request (slist) */
 	struct sg_fd *parentfp;	/* NULL -> not in use */
 	Sg_scatter_hold data;	/* hold buffer, perhaps scatter list */
 	sg_io_hdr_t header;	/* scsi command+info, see <scsi/sg.h> */
-	unsigned char sense_b[sizeof (dummy_cmdp->sr_sense_buffer)];
+	unsigned char sense_b[SCSI_SENSE_BUFFERSIZE];
 	char res_used;		/* 1 -> using reserve buffer, 0 -> not ... */
 	char orphan;		/* 1 -> drop on sight, 0 -> normal */
 	char sg_io_owned;	/* 1 -> packet belongs to SG_IO */
@@ -174,7 +171,8 @@
 } Sg_device;
 
 static int sg_fasync(int fd, struct file *filp, int mode);
-static void sg_cmd_done(Scsi_Cmnd * SCpnt);	/* tasklet or soft irq callback */
+/* tasklet or soft irq callback */
+static void sg_cmd_done(void *data, char *sense, int result, int resid);
 static int sg_start_req(Sg_request * srp);
 static void sg_finish_rem_req(Sg_request * srp);
 static int sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size);
@@ -195,8 +193,8 @@
 static void sg_build_reserve(Sg_fd * sfp, int req_size);
 static void sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size);
 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp);
-static char *sg_page_malloc(int rqSz, int lowDma, int *retSzp);
-static void sg_page_free(char *buff, int size);
+static struct page *sg_page_malloc(int rqSz, int lowDma, int *retSzp);
+static void sg_page_free(struct page *page, int size);
 static Sg_fd *sg_add_sfp(Sg_device * sdp, int dev);
 static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
 static void __sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp);
@@ -207,7 +205,6 @@
 static int sg_allow_access(unsigned char opcode, char dev_type);
 static int sg_build_direct(Sg_request * srp, Sg_fd * sfp, int dxfer_len);
 static Sg_device *sg_get_dev(int dev);
-static inline unsigned char *sg_scatg2virt(const struct scatterlist *sclp);
 #ifdef CONFIG_SCSI_PROC_FS
 static int sg_last_dev(void);
 #endif
@@ -226,6 +223,7 @@
 {
 	int dev = iminor(inode);
 	int flags = filp->f_flags;
+	struct request_queue *q;
 	Sg_device *sdp;
 	Sg_fd *sfp;
 	int res;
@@ -287,7 +285,9 @@
 	}
 	if (!sdp->headfp) {	/* no existing opens on this device */
 		sdp->sgdebug = 0;
-		sdp->sg_tablesize = sdp->device->host->sg_tablesize;
+		q = sdp->device->request_queue;
+		sdp->sg_tablesize = min(q->max_hw_segments,
+					q->max_phys_segments);
 	}
 	if ((sfp = sg_add_sfp(sdp, dev)))
 		filp->private_data = sfp;
@@ -340,6 +340,7 @@
 		return -ENXIO;
 	SCSI_LOG_TIMEOUT(3, printk("sg_read: %s, count=%d\n",
 				   sdp->disk->disk_name, (int) count));
+
 	if (!access_ok(VERIFY_WRITE, buf, count))
 		return -EFAULT;
 	if (sfp->force_packid && (count >= SZ_SG_HEADER)) {
@@ -491,7 +492,7 @@
 	if ((hp->mx_sb_len > 0) && hp->sbp) {
 		if ((CHECK_CONDITION & hp->masked_status) ||
 		    (DRIVER_SENSE & hp->driver_status)) {
-			int sb_len = sizeof (dummy_cmdp->sr_sense_buffer);
+			int sb_len = SCSI_SENSE_BUFFERSIZE;
 			sb_len = (hp->mx_sb_len > sb_len) ? sb_len : hp->mx_sb_len;
 			len = 8 + (int) srp->sense_b[7];	/* Additional sense length field */
 			len = (len > sb_len) ? sb_len : len;
@@ -525,7 +526,7 @@
 	Sg_request *srp;
 	struct sg_header old_hdr;
 	sg_io_hdr_t *hp;
-	unsigned char cmnd[sizeof (dummy_cmdp->sr_cmnd)];
+	unsigned char cmnd[MAX_COMMAND_SIZE];
 
 	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
 		return -ENXIO;
@@ -624,7 +625,7 @@
 	int k;
 	Sg_request *srp;
 	sg_io_hdr_t *hp;
-	unsigned char cmnd[sizeof (dummy_cmdp->sr_cmnd)];
+	unsigned char cmnd[MAX_COMMAND_SIZE];
 	int timeout;
 	unsigned long ul_timeout;
 
@@ -692,11 +693,9 @@
 sg_common_write(Sg_fd * sfp, Sg_request * srp,
 		unsigned char *cmnd, int timeout, int blocking)
 {
-	int k;
-	Scsi_Request *SRpnt;
+	int k, data_dir;
 	Sg_device *sdp = sfp->parentdp;
 	sg_io_hdr_t *hp = &srp->header;
-	request_queue_t *q;
 
 	srp->data.cmd_opcode = cmnd[0];	/* hold opcode of command */
 	hp->status = 0;
@@ -723,51 +722,36 @@
 		sg_finish_rem_req(srp);
 		return -ENODEV;
 	}
-	SRpnt = scsi_allocate_request(sdp->device, GFP_ATOMIC);
-	if (SRpnt == NULL) {
-		SCSI_LOG_TIMEOUT(1, printk("sg_write: no mem\n"));
-		sg_finish_rem_req(srp);
-		return -ENOMEM;
-	}
 
-	srp->my_cmdp = SRpnt;
-	q = SRpnt->sr_device->request_queue;
-	SRpnt->sr_request->rq_disk = sdp->disk;
-	SRpnt->sr_sense_buffer[0] = 0;
-	SRpnt->sr_cmd_len = hp->cmd_len;
-	SRpnt->sr_use_sg = srp->data.k_use_sg;
-	SRpnt->sr_sglist_len = srp->data.sglist_len;
-	SRpnt->sr_bufflen = srp->data.bufflen;
-	SRpnt->sr_underflow = 0;
-	SRpnt->sr_buffer = srp->data.buffer;
 	switch (hp->dxfer_direction) {
 	case SG_DXFER_TO_FROM_DEV:
 	case SG_DXFER_FROM_DEV:
-		SRpnt->sr_data_direction = DMA_FROM_DEVICE;
+		data_dir = DMA_FROM_DEVICE;
 		break;
 	case SG_DXFER_TO_DEV:
-		SRpnt->sr_data_direction = DMA_TO_DEVICE;
+		data_dir = DMA_TO_DEVICE;
 		break;
 	case SG_DXFER_UNKNOWN:
-		SRpnt->sr_data_direction = DMA_BIDIRECTIONAL;
+		data_dir = DMA_BIDIRECTIONAL;
 		break;
 	default:
-		SRpnt->sr_data_direction = DMA_NONE;
+		data_dir = DMA_NONE;
 		break;
 	}
-	SRpnt->upper_private_data = srp;
-	srp->data.k_use_sg = 0;
-	srp->data.sglist_len = 0;
-	srp->data.bufflen = 0;
-	srp->data.buffer = NULL;
 	hp->duration = jiffies_to_msecs(jiffies);
 /* Now send everything of to mid-level. The next time we hear about this
    packet is when sg_cmd_done() is called (i.e. a callback). */
-	scsi_do_req(SRpnt, (void *) cmnd,
-		    (void *) SRpnt->sr_buffer, hp->dxfer_len,
-		    sg_cmd_done, timeout, SG_DEFAULT_RETRIES);
-	/* dxfer_len overwrites SRpnt->sr_bufflen, hence need for b_malloc_len */
-	return 0;
+	if (scsi_execute_async(sdp->device, cmnd, data_dir, srp->data.buffer,
+				hp->dxfer_len, srp->data.k_use_sg, timeout,
+				SG_DEFAULT_RETRIES, srp, sg_cmd_done,
+				GFP_ATOMIC)) {
+		SCSI_LOG_TIMEOUT(1, printk("sg_write: scsi_execute_async failed\n"));
+		/*
+		 * most likely out of mem, but could also be a bad map
+		 */
+		return -ENOMEM;
+	} else
+		return 0;
 }
 
 static int
@@ -1156,45 +1140,22 @@
 	return (retval < 0) ? retval : 0;
 }
 
-static inline unsigned char *
-sg_scatg2virt(const struct scatterlist *sclp)
-{
-	return (sclp && sclp->page) ?
-	    (unsigned char *) page_address(sclp->page) + sclp->offset : NULL;
-}
-
 /* When startFinish==1 increments page counts for pages other than the 
-   first of scatter gather elements obtained from __get_free_pages().
+   first of scatter gather elements obtained from alloc_pages().
    When startFinish==0 decrements ... */
 static void
 sg_rb_correct4mmap(Sg_scatter_hold * rsv_schp, int startFinish)
 {
-	void *page_ptr;
+	struct scatterlist *sg = rsv_schp->buffer;
 	struct page *page;
 	int k, m;
 
 	SCSI_LOG_TIMEOUT(3, printk("sg_rb_correct4mmap: startFinish=%d, scatg=%d\n", 
 				   startFinish, rsv_schp->k_use_sg));
 	/* N.B. correction _not_ applied to base page of each allocation */
-	if (rsv_schp->k_use_sg) {	/* reserve buffer is a scatter gather list */
-		struct scatterlist *sclp = rsv_schp->buffer;
-
-		for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
-			for (m = PAGE_SIZE; m < sclp->length; m += PAGE_SIZE) {
-				page_ptr = sg_scatg2virt(sclp) + m;
-				page = virt_to_page(page_ptr);
-				if (startFinish)
-					get_page(page);
-				else {
-					if (page_count(page) > 0)
-						__put_page(page);
-				}
-			}
-		}
-	} else {		/* reserve buffer is just a single allocation */
-		for (m = PAGE_SIZE; m < rsv_schp->bufflen; m += PAGE_SIZE) {
-			page_ptr = (unsigned char *) rsv_schp->buffer + m;
-			page = virt_to_page(page_ptr);
+	for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) {
+		for (m = PAGE_SIZE; m < sg->length; m += PAGE_SIZE) {
+			page = sg->page;
 			if (startFinish)
 				get_page(page);
 			else {
@@ -1210,9 +1171,10 @@
 {
 	Sg_fd *sfp;
 	struct page *page = NOPAGE_SIGBUS;
-	void *page_ptr = NULL;
-	unsigned long offset;
+	unsigned long offset, len, sa;
 	Sg_scatter_hold *rsv_schp;
+	struct scatterlist *sg;
+	int k;
 
 	if ((NULL == vma) || (!(sfp = (Sg_fd *) vma->vm_private_data)))
 		return page;
@@ -1222,30 +1184,21 @@
 		return page;
 	SCSI_LOG_TIMEOUT(3, printk("sg_vma_nopage: offset=%lu, scatg=%d\n",
 				   offset, rsv_schp->k_use_sg));
-	if (rsv_schp->k_use_sg) {	/* reserve buffer is a scatter gather list */
-		int k;
-		unsigned long sa = vma->vm_start;
-		unsigned long len;
-		struct scatterlist *sclp = rsv_schp->buffer;
-
-		for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-		     ++k, ++sclp) {
-			len = vma->vm_end - sa;
-			len = (len < sclp->length) ? len : sclp->length;
-			if (offset < len) {
-				page_ptr = sg_scatg2virt(sclp) + offset;
-				page = virt_to_page(page_ptr);
-				get_page(page);	/* increment page count */
-				break;
-			}
-			sa += len;
-			offset -= len;
+	sg = rsv_schp->buffer;
+	sa = vma->vm_start;
+	for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
+	     ++k, ++sg) {
+		len = vma->vm_end - sa;
+		len = (len < sg->length) ? len : sg->length;
+		if (offset < len) {
+			page = sg->page;
+			get_page(page);	/* increment page count */
+			break;
 		}
-	} else {		/* reserve buffer is just a single allocation */
-		page_ptr = (unsigned char *) rsv_schp->buffer + offset;
-		page = virt_to_page(page_ptr);
-		get_page(page);	/* increment page count */
+		sa += len;
+		offset -= len;
 	}
+
 	if (type)
 		*type = VM_FAULT_MINOR;
 	return page;
@@ -1259,8 +1212,10 @@
 sg_mmap(struct file *filp, struct vm_area_struct *vma)
 {
 	Sg_fd *sfp;
-	unsigned long req_sz;
+	unsigned long req_sz, len, sa;
 	Sg_scatter_hold *rsv_schp;
+	int k;
+	struct scatterlist *sg;
 
 	if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
 		return -ENXIO;
@@ -1273,24 +1228,15 @@
 	if (req_sz > rsv_schp->bufflen)
 		return -ENOMEM;	/* cannot map more than reserved buffer */
 
-	if (rsv_schp->k_use_sg) { /* reserve buffer is a scatter gather list */
-		int k;
-		unsigned long sa = vma->vm_start;
-		unsigned long len;
-		struct scatterlist *sclp = rsv_schp->buffer;
-
-		for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
-		     ++k, ++sclp) {
-			if (0 != sclp->offset)
-				return -EFAULT;	/* non page aligned memory ?? */
-			len = vma->vm_end - sa;
-			len = (len < sclp->length) ? len : sclp->length;
-			sa += len;
-		}
-	} else {	/* reserve buffer is just a single allocation */
-		if ((unsigned long) rsv_schp->buffer & (PAGE_SIZE - 1))
-			return -EFAULT;	/* non page aligned memory ?? */
+	sa = vma->vm_start;
+	sg = rsv_schp->buffer;
+	for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
+	     ++k, ++sg) {
+		len = vma->vm_end - sa;
+		len = (len < sg->length) ? len : sg->length;
+		sa += len;
 	}
+
 	if (0 == sfp->mmap_called) {
 		sg_rb_correct4mmap(rsv_schp, 1);	/* do only once per fd lifetime */
 		sfp->mmap_called = 1;
@@ -1304,21 +1250,16 @@
 /* This function is a "bottom half" handler that is called by the
  * mid level when a command is completed (or has failed). */
 static void
-sg_cmd_done(Scsi_Cmnd * SCpnt)
+sg_cmd_done(void *data, char *sense, int result, int resid)
 {
-	Scsi_Request *SRpnt = NULL;
+	Sg_request *srp = data;
 	Sg_device *sdp = NULL;
 	Sg_fd *sfp;
-	Sg_request *srp = NULL;
 	unsigned long iflags;
 	unsigned int ms;
 
-	if (SCpnt && (SRpnt = SCpnt->sc_request))
-		srp = (Sg_request *) SRpnt->upper_private_data;
 	if (NULL == srp) {
 		printk(KERN_ERR "sg_cmd_done: NULL request\n");
-		if (SRpnt)
-			scsi_release_request(SRpnt);
 		return;
 	}
 	sfp = srp->parentfp;
@@ -1326,49 +1267,34 @@
 		sdp = sfp->parentdp;
 	if ((NULL == sdp) || sdp->detached) {
 		printk(KERN_INFO "sg_cmd_done: device detached\n");
-		scsi_release_request(SRpnt);
 		return;
 	}
 
-	/* First transfer ownership of data buffers to sg_device object. */
-	srp->data.k_use_sg = SRpnt->sr_use_sg;
-	srp->data.sglist_len = SRpnt->sr_sglist_len;
-	srp->data.bufflen = SRpnt->sr_bufflen;
-	srp->data.buffer = SRpnt->sr_buffer;
-	/* now clear out request structure */
-	SRpnt->sr_use_sg = 0;
-	SRpnt->sr_sglist_len = 0;
-	SRpnt->sr_bufflen = 0;
-	SRpnt->sr_buffer = NULL;
-	SRpnt->sr_underflow = 0;
-	SRpnt->sr_request->rq_disk = NULL; /* "sg" _disowns_ request blk */
-
-	srp->my_cmdp = NULL;
 
 	SCSI_LOG_TIMEOUT(4, printk("sg_cmd_done: %s, pack_id=%d, res=0x%x\n",
-		sdp->disk->disk_name, srp->header.pack_id, (int) SRpnt->sr_result));
-	srp->header.resid = SCpnt->resid;
+		sdp->disk->disk_name, srp->header.pack_id, result));
+	srp->header.resid = resid;
 	ms = jiffies_to_msecs(jiffies);
 	srp->header.duration = (ms > srp->header.duration) ?
 				(ms - srp->header.duration) : 0;
-	if (0 != SRpnt->sr_result) {
+	if (0 != result) {
 		struct scsi_sense_hdr sshdr;
 
-		memcpy(srp->sense_b, SRpnt->sr_sense_buffer,
-		       sizeof (srp->sense_b));
-		srp->header.status = 0xff & SRpnt->sr_result;
-		srp->header.masked_status = status_byte(SRpnt->sr_result);
-		srp->header.msg_status = msg_byte(SRpnt->sr_result);
-		srp->header.host_status = host_byte(SRpnt->sr_result);
-		srp->header.driver_status = driver_byte(SRpnt->sr_result);
+		memcpy(srp->sense_b, sense, sizeof (srp->sense_b));
+		srp->header.status = 0xff & result;
+		srp->header.masked_status = status_byte(result);
+		srp->header.msg_status = msg_byte(result);
+		srp->header.host_status = host_byte(result);
+		srp->header.driver_status = driver_byte(result);
 		if ((sdp->sgdebug > 0) &&
 		    ((CHECK_CONDITION == srp->header.masked_status) ||
 		     (COMMAND_TERMINATED == srp->header.masked_status)))
-			scsi_print_req_sense("sg_cmd_done", SRpnt);
+			__scsi_print_sense("sg_cmd_done", sense,
+					   SCSI_SENSE_BUFFERSIZE);
 
 		/* Following if statement is a patch supplied by Eric Youngdale */
-		if (driver_byte(SRpnt->sr_result) != 0
-		    && scsi_command_normalize_sense(SCpnt, &sshdr)
+		if (driver_byte(result) != 0
+		    && scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)
 		    && !scsi_sense_is_deferred(&sshdr)
 		    && sshdr.sense_key == UNIT_ATTENTION
 		    && sdp->device->removable) {
@@ -1379,8 +1305,6 @@
 	}
 	/* Rely on write phase to clean out srp status values, so no "else" */
 
-	scsi_release_request(SRpnt);
-	SRpnt = NULL;
 	if (sfp->closed) {	/* whoops this fd already released, cleanup */
 		SCSI_LOG_TIMEOUT(1, printk("sg_cmd_done: already closed, freeing ...\n"));
 		sg_finish_rem_req(srp);
@@ -1431,6 +1355,7 @@
 
 static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp)
 {
+	struct request_queue *q = scsidp->request_queue;
 	Sg_device *sdp;
 	unsigned long iflags;
 	void *old_sg_dev_arr = NULL;
@@ -1473,7 +1398,7 @@
 	sdp->disk = disk;
 	sdp->device = scsidp;
 	init_waitqueue_head(&sdp->o_excl_wait);
-	sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;
+	sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments);
 
 	sg_nr_dev++;
 	sg_dev_arr[k] = sdp;
@@ -1753,36 +1678,35 @@
 static int
 sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
 {
-	int ret_sz;
-	int elem_sz = sizeof (struct scatterlist);
-	int sg_bufflen = tablesize * elem_sz;
-	int mx_sc_elems = tablesize;
+	int sg_bufflen = tablesize * sizeof(struct scatterlist);
+	unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN;
 
-	schp->buffer = sg_page_malloc(sg_bufflen, sfp->low_dma, &ret_sz);
+	/*
+	 * TODO: test without low_dma, we should not need it since
+	 * the block layer will bounce the buffer for us
+	 *
+	 * XXX(hch): we shouldn't need GFP_DMA for the actual S/G list.
+	 */
+	if (sfp->low_dma)
+		 gfp_flags |= GFP_DMA;
+	schp->buffer = kzalloc(sg_bufflen, gfp_flags);
 	if (!schp->buffer)
 		return -ENOMEM;
-	else if (ret_sz != sg_bufflen) {
-		sg_bufflen = ret_sz;
-		mx_sc_elems = sg_bufflen / elem_sz;
-	}
 	schp->sglist_len = sg_bufflen;
-	memset(schp->buffer, 0, sg_bufflen);
-	return mx_sc_elems;	/* number of scat_gath elements allocated */
+	return tablesize;	/* number of scat_gath elements allocated */
 }
 
 #ifdef SG_ALLOW_DIO_CODE
 /* vvvvvvvv  following code borrowed from st driver's direct IO vvvvvvvvv */
-	/* hopefully this generic code will moved to a library */
+	/* TODO: hopefully we can use the generic block layer code */
 
 /* Pin down user pages and put them into a scatter gather list. Returns <= 0 if
    - mapping of all pages not successful
-   - any page is above max_pfn
    (i.e., either completely successful or fails)
 */
 static int 
 st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
-	          unsigned long uaddr, size_t count, int rw,
-	          unsigned long max_pfn)
+	          unsigned long uaddr, size_t count, int rw)
 {
 	unsigned long end = (uaddr + count + PAGE_SIZE - 1) >> PAGE_SHIFT;
 	unsigned long start = uaddr >> PAGE_SHIFT;
@@ -1828,21 +1752,17 @@
                  * probably wrong function for rw==WRITE
                  */
 		flush_dcache_page(pages[i]);
-		if (page_to_pfn(pages[i]) > max_pfn)
-			goto out_unlock;
 		/* ?? Is locking needed? I don't think so */
 		/* if (TestSetPageLocked(pages[i]))
 		   goto out_unlock; */
         }
 
-	/* Populate the scatter/gather list */
-	sgl[0].page = pages[0]; 
+	sgl[0].page = pages[0];
 	sgl[0].offset = uaddr & ~PAGE_MASK;
 	if (nr_pages > 1) {
 		sgl[0].length = PAGE_SIZE - sgl[0].offset;
 		count -= sgl[0].length;
 		for (i=1; i < nr_pages ; i++) {
-			sgl[i].offset = 0;
 			sgl[i].page = pages[i]; 
 			sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
 			count -= PAGE_SIZE;
@@ -1855,14 +1775,12 @@
 	kfree(pages);
 	return nr_pages;
 
- out_unlock:
-	/* for (j=0; j < i; j++)
-	   unlock_page(pages[j]); */
-	res = 0;
  out_unmap:
-	if (res > 0)
+	if (res > 0) {
 		for (j=0; j < res; j++)
 			page_cache_release(pages[j]);
+		res = 0;
+	}
 	kfree(pages);
 	return res;
 }
@@ -1878,8 +1796,6 @@
 	for (i=0; i < nr_pages; i++) {
 		struct page *page = sgl[i].page;
 
-		/* XXX: just for debug. Remove when PageReserved is removed */
-		BUG_ON(PageReserved(page));
 		if (dirtied)
 			SetPageDirty(page);
 		/* unlock_page(page); */
@@ -1904,20 +1820,20 @@
 	sg_io_hdr_t *hp = &srp->header;
 	Sg_scatter_hold *schp = &srp->data;
 	int sg_tablesize = sfp->parentdp->sg_tablesize;
-	struct scatterlist *sgl;
 	int mx_sc_elems, res;
 	struct scsi_device *sdev = sfp->parentdp->device;
 
 	if (((unsigned long)hp->dxferp &
 			queue_dma_alignment(sdev->request_queue)) != 0)
 		return 1;
+
 	mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
         if (mx_sc_elems <= 0) {
                 return 1;
         }
-	sgl = (struct scatterlist *)schp->buffer;
-	res = st_map_user_pages(sgl, mx_sc_elems, (unsigned long)hp->dxferp, dxfer_len, 
-				(SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0, ULONG_MAX);
+	res = st_map_user_pages(schp->buffer, mx_sc_elems,
+				(unsigned long)hp->dxferp, dxfer_len, 
+				(SG_DXFER_TO_DEV == hp->dxfer_direction) ? 1 : 0);
 	if (res <= 0)
 		return 1;
 	schp->k_use_sg = res;
@@ -1932,9 +1848,11 @@
 static int
 sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
 {
-	int ret_sz;
+	struct scatterlist *sg;
+	int ret_sz = 0, k, rem_sz, num, mx_sc_elems;
+	int sg_tablesize = sfp->parentdp->sg_tablesize;
 	int blk_size = buff_size;
-	unsigned char *p = NULL;
+	struct page *p = NULL;
 
 	if ((blk_size < 0) || (!sfp))
 		return -EFAULT;
@@ -1944,59 +1862,35 @@
 	blk_size = (blk_size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK);
 	SCSI_LOG_TIMEOUT(4, printk("sg_build_indirect: buff_size=%d, blk_size=%d\n",
 				   buff_size, blk_size));
-	if (blk_size <= SG_SCATTER_SZ) {
-		p = sg_page_malloc(blk_size, sfp->low_dma, &ret_sz);
+
+	/* N.B. ret_sz carried into this block ... */
+	mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
+	if (mx_sc_elems < 0)
+		return mx_sc_elems;	/* most likely -ENOMEM */
+
+	for (k = 0, sg = schp->buffer, rem_sz = blk_size;
+	     (rem_sz > 0) && (k < mx_sc_elems);
+	     ++k, rem_sz -= ret_sz, ++sg) {
+		
+		num = (rem_sz > SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz;
+		p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
 		if (!p)
 			return -ENOMEM;
-		if (blk_size == ret_sz) {	/* got it on the first attempt */
-			schp->k_use_sg = 0;
-			schp->buffer = p;
-			schp->bufflen = blk_size;
-			schp->b_malloc_len = blk_size;
-			return 0;
-		}
-	} else {
-		p = sg_page_malloc(SG_SCATTER_SZ, sfp->low_dma, &ret_sz);
-		if (!p)
-			return -ENOMEM;
-	}
-/* Want some local declarations, so start new block ... */
-	{			/* lets try and build a scatter gather list */
-		struct scatterlist *sclp;
-		int k, rem_sz, num;
-		int mx_sc_elems;
-		int sg_tablesize = sfp->parentdp->sg_tablesize;
-		int first = 1;
 
-		/* N.B. ret_sz carried into this block ... */
-		mx_sc_elems = sg_build_sgat(schp, sfp, sg_tablesize);
-		if (mx_sc_elems < 0)
-			return mx_sc_elems;	/* most likely -ENOMEM */
+		sg->page = p;
+		sg->length = ret_sz;
 
-		for (k = 0, sclp = schp->buffer, rem_sz = blk_size;
-		     (rem_sz > 0) && (k < mx_sc_elems);
-		     ++k, rem_sz -= ret_sz, ++sclp) {
-			if (first)
-				first = 0;
-			else {
-				num =
-				    (rem_sz >
-				     SG_SCATTER_SZ) ? SG_SCATTER_SZ : rem_sz;
-				p = sg_page_malloc(num, sfp->low_dma, &ret_sz);
-				if (!p)
-					break;
-			}
-			sg_set_buf(sclp, p, ret_sz);
+		SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
+				  k, p, ret_sz));
+	}		/* end of for loop */
 
-			SCSI_LOG_TIMEOUT(5, printk("sg_build_build: k=%d, a=0x%p, len=%d\n",
-					  k, sg_scatg2virt(sclp), ret_sz));
-		}		/* end of for loop */
-		schp->k_use_sg = k;
-		SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz));
-		schp->bufflen = blk_size;
-		if (rem_sz > 0)	/* must have failed */
-			return -ENOMEM;
-	}
+	schp->k_use_sg = k;
+	SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k_use_sg=%d, rem_sz=%d\n", k, rem_sz));
+
+	schp->bufflen = blk_size;
+	if (rem_sz > 0)	/* must have failed */
+		return -ENOMEM;
+
 	return 0;
 }
 
@@ -2005,6 +1899,7 @@
 {
 	sg_io_hdr_t *hp = &srp->header;
 	Sg_scatter_hold *schp = &srp->data;
+	struct scatterlist *sg = schp->buffer;
 	int num_xfer = 0;
 	int j, k, onum, usglen, ksglen, res;
 	int iovec_count = (int) hp->iovec_count;
@@ -2033,63 +1928,45 @@
 	} else
 		onum = 1;
 
-	if (0 == schp->k_use_sg) {	/* kernel has single buffer */
-		for (j = 0, p = schp->buffer; j < onum; ++j) {
-			res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
-			if (res)
-				return res;
-			usglen = (num_xfer > usglen) ? usglen : num_xfer;
-			if (__copy_from_user(p, up, usglen))
-				return -EFAULT;
-			p += usglen;
-			num_xfer -= usglen;
-			if (num_xfer <= 0)
+	ksglen = sg->length;
+	p = page_address(sg->page);
+	for (j = 0, k = 0; j < onum; ++j) {
+		res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
+		if (res)
+			return res;
+
+		for (; p; ++sg, ksglen = sg->length,
+		     p = page_address(sg->page)) {
+			if (usglen <= 0)
+				break;
+			if (ksglen > usglen) {
+				if (usglen >= num_xfer) {
+					if (__copy_from_user(p, up, num_xfer))
+						return -EFAULT;
+					return 0;
+				}
+				if (__copy_from_user(p, up, usglen))
+					return -EFAULT;
+				p += usglen;
+				ksglen -= usglen;
+				break;
+			} else {
+				if (ksglen >= num_xfer) {
+					if (__copy_from_user(p, up, num_xfer))
+						return -EFAULT;
+					return 0;
+				}
+				if (__copy_from_user(p, up, ksglen))
+					return -EFAULT;
+				up += ksglen;
+				usglen -= ksglen;
+			}
+			++k;
+			if (k >= schp->k_use_sg)
 				return 0;
 		}
-	} else {		/* kernel using scatter gather list */
-		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
-
-		ksglen = (int) sclp->length;
-		p = sg_scatg2virt(sclp);
-		for (j = 0, k = 0; j < onum; ++j) {
-			res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
-			if (res)
-				return res;
-
-			for (; p; ++sclp, ksglen = (int) sclp->length,
-				  p = sg_scatg2virt(sclp)) {
-				if (usglen <= 0)
-					break;
-				if (ksglen > usglen) {
-					if (usglen >= num_xfer) {
-						if (__copy_from_user
-						    (p, up, num_xfer))
-							return -EFAULT;
-						return 0;
-					}
-					if (__copy_from_user(p, up, usglen))
-						return -EFAULT;
-					p += usglen;
-					ksglen -= usglen;
-					break;
-				} else {
-					if (ksglen >= num_xfer) {
-						if (__copy_from_user
-						    (p, up, num_xfer))
-							return -EFAULT;
-						return 0;
-					}
-					if (__copy_from_user(p, up, ksglen))
-						return -EFAULT;
-					up += ksglen;
-					usglen -= ksglen;
-				}
-				++k;
-				if (k >= schp->k_use_sg)
-					return 0;
-			}
-		}
 	}
+
 	return 0;
 }
 
@@ -2127,29 +2004,25 @@
 {
 	SCSI_LOG_TIMEOUT(4, printk("sg_remove_scat: k_use_sg=%d\n", schp->k_use_sg));
 	if (schp->buffer && (schp->sglist_len > 0)) {
-		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
+		struct scatterlist *sg = schp->buffer;
 
 		if (schp->dio_in_use) {
 #ifdef SG_ALLOW_DIO_CODE
-			st_unmap_user_pages(sclp, schp->k_use_sg, TRUE);
+			st_unmap_user_pages(sg, schp->k_use_sg, TRUE);
 #endif
 		} else {
 			int k;
 
-			for (k = 0; (k < schp->k_use_sg) && sg_scatg2virt(sclp);
-			     ++k, ++sclp) {
+			for (k = 0; (k < schp->k_use_sg) && sg->page;
+			     ++k, ++sg) {
 				SCSI_LOG_TIMEOUT(5, printk(
 				    "sg_remove_scat: k=%d, a=0x%p, len=%d\n",
-				    k, sg_scatg2virt(sclp), sclp->length));
-				sg_page_free(sg_scatg2virt(sclp), sclp->length);
-				sclp->page = NULL;
-				sclp->offset = 0;
-				sclp->length = 0;
+				    k, sg->page, sg->length));
+				sg_page_free(sg->page, sg->length);
 			}
 		}
-		sg_page_free(schp->buffer, schp->sglist_len);
-	} else if (schp->buffer)
-		sg_page_free(schp->buffer, schp->b_malloc_len);
+		kfree(schp->buffer);
+	}
 	memset(schp, 0, sizeof (*schp));
 }
 
@@ -2158,6 +2031,7 @@
 {
 	sg_io_hdr_t *hp = &srp->header;
 	Sg_scatter_hold *schp = &srp->data;
+	struct scatterlist *sg = schp->buffer;
 	int num_xfer = 0;
 	int j, k, onum, usglen, ksglen, res;
 	int iovec_count = (int) hp->iovec_count;
@@ -2186,63 +2060,45 @@
 	} else
 		onum = 1;
 
-	if (0 == schp->k_use_sg) {	/* kernel has single buffer */
-		for (j = 0, p = schp->buffer; j < onum; ++j) {
-			res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
-			if (res)
-				return res;
-			usglen = (num_xfer > usglen) ? usglen : num_xfer;
-			if (__copy_to_user(up, p, usglen))
-				return -EFAULT;
-			p += usglen;
-			num_xfer -= usglen;
-			if (num_xfer <= 0)
+	p = page_address(sg->page);
+	ksglen = sg->length;
+	for (j = 0, k = 0; j < onum; ++j) {
+		res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
+		if (res)
+			return res;
+
+		for (; p; ++sg, ksglen = sg->length,
+		     p = page_address(sg->page)) {
+			if (usglen <= 0)
+				break;
+			if (ksglen > usglen) {
+				if (usglen >= num_xfer) {
+					if (__copy_to_user(up, p, num_xfer))
+						return -EFAULT;
+					return 0;
+				}
+				if (__copy_to_user(up, p, usglen))
+					return -EFAULT;
+				p += usglen;
+				ksglen -= usglen;
+				break;
+			} else {
+				if (ksglen >= num_xfer) {
+					if (__copy_to_user(up, p, num_xfer))
+						return -EFAULT;
+					return 0;
+				}
+				if (__copy_to_user(up, p, ksglen))
+					return -EFAULT;
+				up += ksglen;
+				usglen -= ksglen;
+			}
+			++k;
+			if (k >= schp->k_use_sg)
 				return 0;
 		}
-	} else {		/* kernel using scatter gather list */
-		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
-
-		ksglen = (int) sclp->length;
-		p = sg_scatg2virt(sclp);
-		for (j = 0, k = 0; j < onum; ++j) {
-			res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
-			if (res)
-				return res;
-
-			for (; p; ++sclp, ksglen = (int) sclp->length,
-				  p = sg_scatg2virt(sclp)) {
-				if (usglen <= 0)
-					break;
-				if (ksglen > usglen) {
-					if (usglen >= num_xfer) {
-						if (__copy_to_user
-						    (up, p, num_xfer))
-							return -EFAULT;
-						return 0;
-					}
-					if (__copy_to_user(up, p, usglen))
-						return -EFAULT;
-					p += usglen;
-					ksglen -= usglen;
-					break;
-				} else {
-					if (ksglen >= num_xfer) {
-						if (__copy_to_user
-						    (up, p, num_xfer))
-							return -EFAULT;
-						return 0;
-					}
-					if (__copy_to_user(up, p, ksglen))
-						return -EFAULT;
-					up += ksglen;
-					usglen -= ksglen;
-				}
-				++k;
-				if (k >= schp->k_use_sg)
-					return 0;
-			}
-		}
 	}
+
 	return 0;
 }
 
@@ -2250,37 +2106,32 @@
 sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
 {
 	Sg_scatter_hold *schp = &srp->data;
+	struct scatterlist *sg = schp->buffer;
+	int k, num;
 
 	SCSI_LOG_TIMEOUT(4, printk("sg_read_oxfer: num_read_xfer=%d\n",
 				   num_read_xfer));
 	if ((!outp) || (num_read_xfer <= 0))
 		return 0;
-	if (schp->k_use_sg > 0) {
-		int k, num;
-		struct scatterlist *sclp = (struct scatterlist *) schp->buffer;
 
-		for (k = 0; (k < schp->k_use_sg) && sg_scatg2virt(sclp);
-		     ++k, ++sclp) {
-			num = (int) sclp->length;
-			if (num > num_read_xfer) {
-				if (__copy_to_user
-				    (outp, sg_scatg2virt(sclp), num_read_xfer))
-					return -EFAULT;
+	for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, ++sg) {
+		num = sg->length;
+		if (num > num_read_xfer) {
+			if (__copy_to_user(outp, page_address(sg->page),
+					   num_read_xfer))
+				return -EFAULT;
+			break;
+		} else {
+			if (__copy_to_user(outp, page_address(sg->page),
+					   num))
+				return -EFAULT;
+			num_read_xfer -= num;
+			if (num_read_xfer <= 0)
 				break;
-			} else {
-				if (__copy_to_user
-				    (outp, sg_scatg2virt(sclp), num))
-					return -EFAULT;
-				num_read_xfer -= num;
-				if (num_read_xfer <= 0)
-					break;
-				outp += num;
-			}
+			outp += num;
 		}
-	} else {
-		if (__copy_to_user(outp, schp->buffer, num_read_xfer))
-			return -EFAULT;
 	}
+
 	return 0;
 }
 
@@ -2306,44 +2157,31 @@
 {
 	Sg_scatter_hold *req_schp = &srp->data;
 	Sg_scatter_hold *rsv_schp = &sfp->reserve;
+	struct scatterlist *sg = rsv_schp->buffer;
+	int k, num, rem;
 
 	srp->res_used = 1;
 	SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
-	size = (size + 1) & (~1);	/* round to even for aha1542 */
-	if (rsv_schp->k_use_sg > 0) {
-		int k, num;
-		int rem = size;
-		struct scatterlist *sclp =
-		    (struct scatterlist *) rsv_schp->buffer;
+	rem = size = (size + 1) & (~1);	/* round to even for aha1542 */
 
-		for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sclp) {
-			num = (int) sclp->length;
-			if (rem <= num) {
-				if (0 == k) {
-					req_schp->k_use_sg = 0;
-					req_schp->buffer = sg_scatg2virt(sclp);
-				} else {
-					sfp->save_scat_len = num;
-					sclp->length = (unsigned) rem;
-					req_schp->k_use_sg = k + 1;
-					req_schp->sglist_len =
-					    rsv_schp->sglist_len;
-					req_schp->buffer = rsv_schp->buffer;
-				}
-				req_schp->bufflen = size;
-				req_schp->b_malloc_len = rsv_schp->b_malloc_len;
-				break;
-			} else
-				rem -= num;
-		}
-		if (k >= rsv_schp->k_use_sg)
-			SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
-	} else {
-		req_schp->k_use_sg = 0;
-		req_schp->bufflen = size;
-		req_schp->buffer = rsv_schp->buffer;
-		req_schp->b_malloc_len = rsv_schp->b_malloc_len;
+	for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) {
+		num = sg->length;
+		if (rem <= num) {
+			sfp->save_scat_len = num;
+			sg->length = rem;
+			req_schp->k_use_sg = k + 1;
+			req_schp->sglist_len = rsv_schp->sglist_len;
+			req_schp->buffer = rsv_schp->buffer;
+
+			req_schp->bufflen = size;
+			req_schp->b_malloc_len = rsv_schp->b_malloc_len;
+			break;
+		} else
+			rem -= num;
 	}
+
+	if (k >= rsv_schp->k_use_sg)
+		SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n"));
 }
 
 static void
@@ -2355,11 +2193,10 @@
 	SCSI_LOG_TIMEOUT(4, printk("sg_unlink_reserve: req->k_use_sg=%d\n",
 				   (int) req_schp->k_use_sg));
 	if ((rsv_schp->k_use_sg > 0) && (req_schp->k_use_sg > 0)) {
-		struct scatterlist *sclp =
-		    (struct scatterlist *) rsv_schp->buffer;
+		struct scatterlist *sg = rsv_schp->buffer;
 
 		if (sfp->save_scat_len > 0)
-			(sclp + (req_schp->k_use_sg - 1))->length =
+			(sg + (req_schp->k_use_sg - 1))->length =
 			    (unsigned) sfp->save_scat_len;
 		else
 			SCSI_LOG_TIMEOUT(1, printk ("sg_unlink_reserve: BAD save_scat_len\n"));
@@ -2445,7 +2282,6 @@
 	if (resp) {
 		resp->nextrp = NULL;
 		resp->header.duration = jiffies_to_msecs(jiffies);
-		resp->my_cmdp = NULL;
 	}
 	write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
 	return resp;
@@ -2463,8 +2299,6 @@
 	if ((!sfp) || (!srp) || (!sfp->headrp))
 		return res;
 	write_lock_irqsave(&sfp->rq_list_lock, iflags);
-	if (srp->my_cmdp)
-		srp->my_cmdp->upper_private_data = NULL;
 	prev_rp = sfp->headrp;
 	if (srp == prev_rp) {
 		sfp->headrp = prev_rp->nextrp;
@@ -2507,10 +2341,10 @@
 	Sg_fd *sfp;
 	unsigned long iflags;
 
-	sfp = (Sg_fd *) sg_page_malloc(sizeof (Sg_fd), 0, NULL);
+	sfp = kzalloc(sizeof(*sfp), GFP_ATOMIC | __GFP_NOWARN);
 	if (!sfp)
 		return NULL;
-	memset(sfp, 0, sizeof (Sg_fd));
+
 	init_waitqueue_head(&sfp->read_wait);
 	rwlock_init(&sfp->rq_list_lock);
 
@@ -2567,7 +2401,7 @@
 	}
 	sfp->parentdp = NULL;
 	SCSI_LOG_TIMEOUT(6, printk("__sg_remove_sfp:    sfp=0x%p\n", sfp));
-	sg_page_free((char *) sfp, sizeof (Sg_fd));
+	kfree(sfp);
 }
 
 /* Returns 0 in normal case, 1 when detached and sdp object removed */
@@ -2632,10 +2466,10 @@
 }
 
 /* If retSzp==NULL want exact size or fail */
-static char *
+static struct page *
 sg_page_malloc(int rqSz, int lowDma, int *retSzp)
 {
-	char *resp = NULL;
+	struct page *resp = NULL;
 	gfp_t page_mask;
 	int order, a_size;
 	int resSz = rqSz;
@@ -2650,11 +2484,11 @@
 
 	for (order = 0, a_size = PAGE_SIZE; a_size < rqSz;
 	     order++, a_size <<= 1) ;
-	resp = (char *) __get_free_pages(page_mask, order);
+	resp = alloc_pages(page_mask, order);
 	while ((!resp) && order && retSzp) {
 		--order;
 		a_size >>= 1;	/* divide by 2, until PAGE_SIZE */
-		resp = (char *) __get_free_pages(page_mask, order);	/* try half */
+		resp =  alloc_pages(page_mask, order);	/* try half */
 		resSz = a_size;
 	}
 	if (resp) {
@@ -2667,15 +2501,15 @@
 }
 
 static void
-sg_page_free(char *buff, int size)
+sg_page_free(struct page *page, int size)
 {
 	int order, a_size;
 
-	if (!buff)
+	if (!page)
 		return;
 	for (order = 0, a_size = PAGE_SIZE; a_size < size;
 	     order++, a_size <<= 1) ;
-	free_pages((unsigned long) buff, order);
+	__free_pages(page, order);
 }
 
 #ifndef MAINTENANCE_IN_CMD
@@ -3067,13 +2901,11 @@
 					cp = "     ";
 			}
 			seq_printf(s, cp);
-			blen = srp->my_cmdp ? 
-				srp->my_cmdp->sr_bufflen : srp->data.bufflen;
-			usg = srp->my_cmdp ? 
-				srp->my_cmdp->sr_use_sg : srp->data.k_use_sg;
+			blen = srp->data.bufflen;
+			usg = srp->data.k_use_sg;
 			seq_printf(s, srp->done ? 
 				   ((1 == srp->done) ?  "rcv:" : "fin:")
-				   : (srp->my_cmdp ? "act:" : "prior:"));
+				   : "act:");
 			seq_printf(s, " id=%d blen=%d",
 				   srp->header.pack_id, blen);
 			if (srp->done)
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index d68cea7..a4d9be7 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -320,25 +320,11 @@
 	 * these are already setup, just copy cdb basically
 	 */
 	if (SCpnt->request->flags & REQ_BLOCK_PC) {
-		struct request *rq = SCpnt->request;
+		scsi_setup_blk_pc_cmnd(SCpnt);
 
-		if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
-			return 0;
+		if (SCpnt->timeout_per_command)
+			timeout = SCpnt->timeout_per_command;
 
-		memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
-		SCpnt->cmd_len = rq->cmd_len;
-		if (!rq->data_len)
-			SCpnt->sc_data_direction = DMA_NONE;
-		else if (rq_data_dir(rq) == WRITE)
-			SCpnt->sc_data_direction = DMA_TO_DEVICE;
-		else
-			SCpnt->sc_data_direction = DMA_FROM_DEVICE;
-
-		this_count = rq->data_len;
-		if (rq->timeout)
-			timeout = rq->timeout;
-
-		SCpnt->transfersize = rq->data_len;
 		goto queue;
 	}
 
@@ -730,7 +716,7 @@
 	unsigned int the_result;
 	int retries, rc, n;
 
-	static char *loadmech[] =
+	static const char *loadmech[] =
 	{
 		"caddy",
 		"tray",
diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c
index 78274dc..9dde8df 100644
--- a/drivers/scsi/sr_vendor.c
+++ b/drivers/scsi/sr_vendor.c
@@ -68,8 +68,8 @@
 #ifndef CONFIG_BLK_DEV_SR_VENDOR
 	cd->vendor = VENDOR_SCSI3;
 #else
-	char *vendor = cd->device->vendor;
-	char *model = cd->device->model;
+	const char *vendor = cd->device->vendor;
+	const char *model = cd->device->model;
 	
 	/* default */
 	cd->vendor = VENDOR_SCSI3;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 770c432..c4aade8 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -17,7 +17,7 @@
    Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
  */
 
-static char *verstr = "20050830";
+static const char *verstr = "20050830";
 
 #include <linux/module.h>
 
@@ -50,7 +50,6 @@
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
-#include <scsi/scsi_request.h>
 #include <scsi/sg.h>
 
 
@@ -134,7 +133,7 @@
 #endif
 /* Bit reversed order to get same names for same minors with all
    mode counts */
-static char *st_formats[] = {
+static const char *st_formats[] = {
 	"",  "r", "k", "s", "l", "t", "o", "u",
 	"m", "v", "p", "x", "a", "y", "q", "z"}; 
 
@@ -188,8 +187,6 @@
 static void move_buffer_data(struct st_buffer *, int);
 static void buf_to_sg(struct st_buffer *, unsigned int);
 
-static int st_map_user_pages(struct scatterlist *, const unsigned int, 
-			     unsigned long, size_t, int, unsigned long);
 static int sgl_map_user_pages(struct scatterlist *, const unsigned int, 
 			      unsigned long, size_t, int);
 static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
@@ -313,12 +310,13 @@
 }
 
 
-static void st_analyze_sense(struct scsi_request *SRpnt, struct st_cmdstatus *s)
+static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s)
 {
 	const u8 *ucp;
-	const u8 *sense = SRpnt->sr_sense_buffer;
+	const u8 *sense = SRpnt->sense;
 
-	s->have_sense = scsi_request_normalize_sense(SRpnt, &s->sense_hdr);
+	s->have_sense = scsi_normalize_sense(SRpnt->sense,
+				SCSI_SENSE_BUFFERSIZE, &s->sense_hdr);
 	s->flags = 0;
 
 	if (s->have_sense) {
@@ -345,9 +343,9 @@
 
 
 /* Convert the result to success code */
-static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt)
+static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
 {
-	int result = SRpnt->sr_result;
+	int result = SRpnt->result;
 	u8 scode;
 	DEB(const char *stp;)
 	char *name = tape_name(STp);
@@ -366,13 +364,12 @@
 
         DEB(
         if (debugging) {
-                printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n",
+                printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n",
 		       name, result,
-		       SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2],
-		       SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5],
-		       SRpnt->sr_bufflen);
+		       SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
+		       SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
 		if (cmdstatp->have_sense)
-			scsi_print_req_sense("st", SRpnt);
+			 __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
 	} ) /* end DEB */
 	if (!debugging) { /* Abnormal conditions for tape */
 		if (!cmdstatp->have_sense)
@@ -386,20 +383,21 @@
 			 /* scode != UNIT_ATTENTION && */
 			 scode != BLANK_CHECK &&
 			 scode != VOLUME_OVERFLOW &&
-			 SRpnt->sr_cmnd[0] != MODE_SENSE &&
-			 SRpnt->sr_cmnd[0] != TEST_UNIT_READY) {
+			 SRpnt->cmd[0] != MODE_SENSE &&
+			 SRpnt->cmd[0] != TEST_UNIT_READY) {
 				printk(KERN_WARNING "%s: Error with sense data: ", name);
-				scsi_print_req_sense("st", SRpnt);
+				__scsi_print_sense("st", SRpnt->sense,
+						   SCSI_SENSE_BUFFERSIZE);
 		}
 	}
 
 	if (cmdstatp->fixed_format &&
 	    STp->cln_mode >= EXTENDED_SENSE_START) {  /* Only fixed format sense */
 		if (STp->cln_sense_value)
-			STp->cleaning_req |= ((SRpnt->sr_sense_buffer[STp->cln_mode] &
+			STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
 					       STp->cln_sense_mask) == STp->cln_sense_value);
 		else
-			STp->cleaning_req |= ((SRpnt->sr_sense_buffer[STp->cln_mode] &
+			STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] &
 					       STp->cln_sense_mask) != 0);
 	}
 	if (cmdstatp->have_sense &&
@@ -411,8 +409,8 @@
 	if (cmdstatp->have_sense &&
 	    scode == RECOVERED_ERROR
 #if ST_RECOVERED_WRITE_FATAL
-	    && SRpnt->sr_cmnd[0] != WRITE_6
-	    && SRpnt->sr_cmnd[0] != WRITE_FILEMARKS
+	    && SRpnt->cmd[0] != WRITE_6
+	    && SRpnt->cmd[0] != WRITE_FILEMARKS
 #endif
 	    ) {
 		STp->recover_count++;
@@ -420,9 +418,9 @@
 
                 DEB(
 		if (debugging) {
-			if (SRpnt->sr_cmnd[0] == READ_6)
+			if (SRpnt->cmd[0] == READ_6)
 				stp = "read";
-			else if (SRpnt->sr_cmnd[0] == WRITE_6)
+			else if (SRpnt->cmd[0] == WRITE_6)
 				stp = "write";
 			else
 				stp = "ioctl";
@@ -438,28 +436,37 @@
 
 
 /* Wakeup from interrupt */
-static void st_sleep_done(struct scsi_cmnd * SCpnt)
+static void st_sleep_done(void *data, char *sense, int result, int resid)
 {
-	struct scsi_tape *STp = container_of(SCpnt->request->rq_disk->private_data,
-					     struct scsi_tape, driver);
+	struct st_request *SRpnt = data;
+	struct scsi_tape *STp = SRpnt->stp;
 
-	(STp->buffer)->cmdstat.midlevel_result = SCpnt->result;
-	SCpnt->request->rq_status = RQ_SCSI_DONE;
+	memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE);
+	(STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result;
 	DEB( STp->write_pending = 0; )
 
-	if (SCpnt->request->waiting)
-		complete(SCpnt->request->waiting);
+	if (SRpnt->waiting)
+		complete(SRpnt->waiting);
+}
+
+static struct st_request *st_allocate_request(void)
+{
+	return kzalloc(sizeof(struct st_request), GFP_KERNEL);
+}
+
+static void st_release_request(struct st_request *streq)
+{
+	kfree(streq);
 }
 
 /* Do the scsi command. Waits until command performed if do_wait is true.
    Otherwise write_behind_check() is used to check that the command
    has finished. */
-static struct scsi_request *
-st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
+static struct st_request *
+st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd,
 	   int bytes, int direction, int timeout, int retries, int do_wait)
 {
 	struct completion *waiting;
-	unsigned char *bp;
 
 	/* if async, make sure there's no command outstanding */
 	if (!do_wait && ((STp->buffer)->last_SRpnt)) {
@@ -473,7 +480,7 @@
 	}
 
 	if (SRpnt == NULL) {
-		SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC);
+		SRpnt = st_allocate_request();
 		if (SRpnt == NULL) {
 			DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n",
 				     tape_name(STp)); );
@@ -483,6 +490,7 @@
 				(STp->buffer)->syscall_result = (-EBUSY);
 			return NULL;
 		}
+		SRpnt->stp = STp;
 	}
 
 	/* If async IO, set last_SRpnt. This ptr tells write_behind_check
@@ -492,32 +500,28 @@
 
 	waiting = &STp->wait;
 	init_completion(waiting);
-	SRpnt->sr_use_sg = STp->buffer->do_dio || (bytes > (STp->buffer)->frp[0].length);
-	if (SRpnt->sr_use_sg) {
-		if (!STp->buffer->do_dio)
-			buf_to_sg(STp->buffer, bytes);
-		SRpnt->sr_use_sg = (STp->buffer)->sg_segs;
-		bp = (char *) &((STp->buffer)->sg[0]);
-	} else
-		bp = (STp->buffer)->b_data;
-	SRpnt->sr_data_direction = direction;
-	SRpnt->sr_cmd_len = 0;
-	SRpnt->sr_request->waiting = waiting;
-	SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
-	SRpnt->sr_request->rq_disk = STp->disk;
-	SRpnt->sr_request->end_io = blk_end_sync_rq;
+	SRpnt->waiting = waiting;
+
+	if (!STp->buffer->do_dio)
+		buf_to_sg(STp->buffer, bytes);
+
+	memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd));
 	STp->buffer->cmdstat.have_sense = 0;
+	STp->buffer->syscall_result = 0;
 
-	scsi_do_req(SRpnt, (void *) cmd, bp, bytes,
-		    st_sleep_done, timeout, retries);
-
-	if (do_wait) {
+	if (scsi_execute_async(STp->device, cmd, direction,
+			&((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
+			       timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
+		/* could not allocate the buffer or request was too large */
+		(STp->buffer)->syscall_result = (-EBUSY);
+		(STp->buffer)->last_SRpnt = NULL;
+	}
+	else if (do_wait) {
 		wait_for_completion(waiting);
-		SRpnt->sr_request->waiting = NULL;
-		if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE)
-			SRpnt->sr_result |= (DRIVER_ERROR << 24);
+		SRpnt->waiting = NULL;
 		(STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
 	}
+
 	return SRpnt;
 }
 
@@ -532,7 +536,7 @@
 	struct st_buffer *STbuffer;
 	struct st_partstat *STps;
 	struct st_cmdstatus *cmdstatp;
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 
 	STbuffer = STp->buffer;
 	if (!STbuffer->writing)
@@ -548,12 +552,10 @@
 	wait_for_completion(&(STp->wait));
 	SRpnt = STbuffer->last_SRpnt;
 	STbuffer->last_SRpnt = NULL;
-	SRpnt->sr_request->waiting = NULL;
-	if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE)
-		SRpnt->sr_result |= (DRIVER_ERROR << 24);
+	SRpnt->waiting = NULL;
 
 	(STp->buffer)->syscall_result = st_chk_result(STp, SRpnt);
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 
 	STbuffer->buffer_bytes -= STbuffer->writing;
 	STps = &(STp->ps[STp->partition]);
@@ -593,7 +595,7 @@
    it messes up the block number). */
 static int cross_eof(struct scsi_tape * STp, int forward)
 {
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	unsigned char cmd[MAX_COMMAND_SIZE];
 
 	cmd[0] = SPACE;
@@ -613,7 +615,7 @@
 	if (!SRpnt)
 		return (STp->buffer)->syscall_result;
 
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 	SRpnt = NULL;
 
 	if ((STp->buffer)->cmdstat.midlevel_result != 0)
@@ -630,7 +632,7 @@
 	int offset, transfer, blks;
 	int result;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	struct st_partstat *STps;
 
 	result = write_behind_check(STp);
@@ -688,7 +690,7 @@
 			STp->dirty = 0;
 			(STp->buffer)->buffer_bytes = 0;
 		}
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 		SRpnt = NULL;
 	}
 	return result;
@@ -785,7 +787,7 @@
 }
 
 
-/* Lock or unlock the drive door. Don't use when scsi_request allocated. */
+/* Lock or unlock the drive door. Don't use when st_request allocated. */
 static int do_door_lock(struct scsi_tape * STp, int do_lock)
 {
 	int retval, cmd;
@@ -844,7 +846,7 @@
 	int attentions, waits, max_wait, scode;
 	int retval = CHKRES_READY, new_session = 0;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 	struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat;
 
 	max_wait = do_wait ? ST_BLOCK_SECONDS : 0;
@@ -903,7 +905,7 @@
 	}
 
 	if (SRpnt != NULL)
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 	return retval;
 }
 
@@ -918,7 +920,7 @@
 	int i, retval, new_session = 0, do_wait;
 	unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning;
 	unsigned short st_flags = filp->f_flags;
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 	struct st_modedef *STm;
 	struct st_partstat *STps;
 	char *name = tape_name(STp);
@@ -993,7 +995,7 @@
 			goto err_out;
 		}
 
-		if (!SRpnt->sr_result && !STp->buffer->cmdstat.have_sense) {
+		if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) {
 			STp->max_block = ((STp->buffer)->b_data[1] << 16) |
 			    ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3];
 			STp->min_block = ((STp->buffer)->b_data[4] << 8) |
@@ -1045,7 +1047,7 @@
 		}
 		STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0;
 	}
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 	SRpnt = NULL;
         STp->inited = 1;
 
@@ -1196,7 +1198,7 @@
 {
 	int result = 0, result2;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	struct scsi_tape *STp = filp->private_data;
 	struct st_modedef *STm = &(STp->modes[STp->current_mode]);
 	struct st_partstat *STps = &(STp->ps[STp->partition]);
@@ -1249,7 +1251,7 @@
 		      cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
 		     (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) {
 			/* Write successful at EOM */
-			scsi_release_request(SRpnt);
+			st_release_request(SRpnt);
 			SRpnt = NULL;
 			if (STps->drv_file >= 0)
 				STps->drv_file++;
@@ -1259,7 +1261,7 @@
 			STps->eof = ST_FM;
 		}
 		else { /* Write error */
-			scsi_release_request(SRpnt);
+			st_release_request(SRpnt);
 			SRpnt = NULL;
 			printk(KERN_ERR "%s: Error on write filemark.\n", name);
 			if (result == 0)
@@ -1400,11 +1402,11 @@
 		i = STp->try_dio && try_rdio;
 	else
 		i = STp->try_dio && try_wdio;
+
 	if (i && ((unsigned long)buf & queue_dma_alignment(
 					STp->device->request_queue)) == 0) {
-		i = st_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
-				      (unsigned long)buf, count, (is_read ? READ : WRITE),
-				      STp->max_pfn);
+		i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg,
+				      (unsigned long)buf, count, (is_read ? READ : WRITE));
 		if (i > 0) {
 			STbp->do_dio = i;
 			STbp->buffer_bytes = 0;   /* can be used as transfer counter */
@@ -1449,14 +1451,15 @@
 
 
 /* Can be called more than once after each setup_buffer() */
-static void release_buffering(struct scsi_tape *STp)
+static void release_buffering(struct scsi_tape *STp, int is_read)
 {
 	struct st_buffer *STbp;
 
 	STbp = STp->buffer;
 	if (STbp->do_dio) {
-		sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, 0);
+		sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, is_read);
 		STbp->do_dio = 0;
+		STbp->sg_segs = 0;
 	}
 }
 
@@ -1472,7 +1475,7 @@
 	int async_write;
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	const char __user *b_point;
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 	struct scsi_tape *STp = filp->private_data;
 	struct st_modedef *STm;
 	struct st_partstat *STps;
@@ -1624,7 +1627,7 @@
 			retval = STbp->syscall_result;
 			goto out;
 		}
-		if (async_write) {
+		if (async_write && !STbp->syscall_result) {
 			STbp->writing = transfer;
 			STp->dirty = !(STbp->writing ==
 				       STbp->buffer_bytes);
@@ -1698,7 +1701,7 @@
 			} else {
 				count += do_count;
 				STps->drv_block = (-1);		/* Too cautious? */
-				retval = (-EIO);
+				retval = STbp->syscall_result;
 			}
 
 		}
@@ -1728,8 +1731,8 @@
 
  out:
 	if (SRpnt != NULL)
-		scsi_release_request(SRpnt);
-	release_buffering(STp);
+		st_release_request(SRpnt);
+	release_buffering(STp, 0);
 	up(&STp->lock);
 
 	return retval;
@@ -1742,11 +1745,11 @@
    Does release user buffer mapping if it is set.
 */
 static long read_tape(struct scsi_tape *STp, long count,
-		      struct scsi_request ** aSRpnt)
+		      struct st_request ** aSRpnt)
 {
 	int transfer, blks, bytes;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	struct st_modedef *STm;
 	struct st_partstat *STps;
 	struct st_buffer *STbp;
@@ -1787,7 +1790,7 @@
 	SRpnt = *aSRpnt;
 	SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE,
 			   STp->device->timeout, MAX_RETRIES, 1);
-	release_buffering(STp);
+	release_buffering(STp, 1);
 	*aSRpnt = SRpnt;
 	if (!SRpnt)
 		return STbp->syscall_result;
@@ -1802,10 +1805,10 @@
 		retval = 1;
 		DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n",
                             name,
-                            SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1],
-                            SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3],
-                            SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5],
-                            SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7]));
+                            SRpnt->sense[0], SRpnt->sense[1],
+                            SRpnt->sense[2], SRpnt->sense[3],
+                            SRpnt->sense[4], SRpnt->sense[5],
+                            SRpnt->sense[6], SRpnt->sense[7]));
 		if (cmdstatp->have_sense) {
 
 			if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
@@ -1835,7 +1838,7 @@
 						}
 						STbp->buffer_bytes = bytes - transfer;
 					} else {
-						scsi_release_request(SRpnt);
+						st_release_request(SRpnt);
 						SRpnt = *aSRpnt = NULL;
 						if (transfer == blks) {	/* We did not get anything, error */
 							printk(KERN_NOTICE "%s: Incorrect block size.\n", name);
@@ -1929,7 +1932,7 @@
 	ssize_t retval = 0;
 	ssize_t i, transfer;
 	int special, do_dio = 0;
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 	struct scsi_tape *STp = filp->private_data;
 	struct st_modedef *STm;
 	struct st_partstat *STps;
@@ -2054,11 +2057,11 @@
 
  out:
 	if (SRpnt != NULL) {
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 		SRpnt = NULL;
 	}
 	if (do_dio) {
-		release_buffering(STp);
+		release_buffering(STp, 1);
 		STbp->buffer_bytes = 0;
 	}
 	up(&STp->lock);
@@ -2284,7 +2287,7 @@
 static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs)
 {
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SENSE;
@@ -2298,7 +2301,7 @@
 	if (SRpnt == NULL)
 		return (STp->buffer)->syscall_result;
 
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 
 	return (STp->buffer)->syscall_result;
 }
@@ -2310,7 +2313,7 @@
 {
 	int pgo;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt = NULL;
+	struct st_request *SRpnt = NULL;
 
 	memset(cmd, 0, MAX_COMMAND_SIZE);
 	cmd[0] = MODE_SELECT;
@@ -2329,7 +2332,7 @@
 	if (SRpnt == NULL)
 		return (STp->buffer)->syscall_result;
 
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 
 	return (STp->buffer)->syscall_result;
 }
@@ -2412,7 +2415,7 @@
 	DEB( char *name = tape_name(STp); )
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	struct st_partstat *STps;
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 
 	if (STp->ready != ST_READY && !load_code) {
 		if (STp->ready == ST_NO_TAPE)
@@ -2455,7 +2458,7 @@
 		return (STp->buffer)->syscall_result;
 
 	retval = (STp->buffer)->syscall_result;
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 
 	if (!retval) {	/* SCSI command successful */
 
@@ -2503,7 +2506,7 @@
 	int ioctl_result;
 	int chg_eof = 1;
 	unsigned char cmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	struct st_partstat *STps;
 	int fileno, blkno, at_sm, undone;
 	int datalen = 0, direction = DMA_NONE;
@@ -2757,7 +2760,7 @@
 	ioctl_result = (STp->buffer)->syscall_result;
 
 	if (!ioctl_result) {	/* SCSI command successful */
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 		SRpnt = NULL;
 		STps->drv_block = blkno;
 		STps->drv_file = fileno;
@@ -2872,7 +2875,7 @@
 				/* Try the other possible state of Page Format if not
 				   already tried */
 				STp->use_pf = !STp->use_pf | PF_TESTED;
-				scsi_release_request(SRpnt);
+				st_release_request(SRpnt);
 				SRpnt = NULL;
 				return st_int_ioctl(STp, cmd_in, arg);
 			}
@@ -2882,7 +2885,7 @@
 		if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK)
 			STps->eof = ST_EOD;
 
-		scsi_release_request(SRpnt);
+		st_release_request(SRpnt);
 		SRpnt = NULL;
 	}
 
@@ -2898,7 +2901,7 @@
 {
 	int result;
 	unsigned char scmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	DEB( char *name = tape_name(STp); )
 
 	if (STp->ready != ST_READY)
@@ -2944,7 +2947,7 @@
                 DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name,
                             *block, *partition));
 	}
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 	SRpnt = NULL;
 
 	return result;
@@ -2961,7 +2964,7 @@
 	unsigned int blk;
 	int timeout;
 	unsigned char scmd[MAX_COMMAND_SIZE];
-	struct scsi_request *SRpnt;
+	struct st_request *SRpnt;
 	DEB( char *name = tape_name(STp); )
 
 	if (STp->ready != ST_READY)
@@ -3047,7 +3050,7 @@
 		result = 0;
 	}
 
-	scsi_release_request(SRpnt);
+	st_release_request(SRpnt);
 	SRpnt = NULL;
 
 	return result;
@@ -3577,7 +3580,7 @@
 static struct st_buffer *
  new_tape_buffer(int from_initialization, int need_dma, int max_sg)
 {
-	int i, got = 0, segs = 0;
+	int i, got = 0;
 	gfp_t priority;
 	struct st_buffer *tb;
 
@@ -3594,10 +3597,8 @@
 		return NULL;
 	}
 	memset(tb, 0, i);
-	tb->frp_segs = tb->orig_frp_segs = segs;
+	tb->frp_segs = tb->orig_frp_segs = 0;
 	tb->use_sg = max_sg;
-	if (segs > 0)
-		tb->b_data = page_address(tb->sg[0].page);
 	tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
 
 	tb->in_use = 1;
@@ -3628,7 +3629,7 @@
 	priority = GFP_KERNEL | __GFP_NOWARN;
 	if (need_dma)
 		priority |= GFP_DMA;
-	for (b_size = PAGE_SIZE, order=0;
+	for (b_size = PAGE_SIZE, order=0; order <= 6 &&
 	     b_size < new_size - STbuffer->buffer_size;
 	     order++, b_size *= 2)
 		;  /* empty */
@@ -3670,6 +3671,7 @@
 	}
 	STbuffer->frp_segs = STbuffer->orig_frp_segs;
 	STbuffer->frp_sg_current = 0;
+	STbuffer->sg_segs = 0;
 }
 
 
@@ -3882,7 +3884,6 @@
 	struct st_buffer *buffer;
 	int i, j, mode, dev_num, error;
 	char *stp;
-	u64 bounce_limit;
 
 	if (SDp->type != TYPE_TAPE)
 		return -ENODEV;
@@ -3892,7 +3893,8 @@
 		return -ENODEV;
 	}
 
-	i = SDp->host->sg_tablesize;
+	i = min(SDp->request_queue->max_hw_segments,
+		SDp->request_queue->max_phys_segments);
 	if (st_max_sg_segs < i)
 		i = st_max_sg_segs;
 	buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i);
@@ -3994,11 +3996,6 @@
 	tpnt->long_timeout = ST_LONG_TIMEOUT;
 	tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
 
-	bounce_limit = scsi_calculate_bounce_limit(SDp->host) >> PAGE_SHIFT;
-	if (bounce_limit > ULONG_MAX)
-		bounce_limit = ULONG_MAX;
-	tpnt->max_pfn = bounce_limit;
-
 	for (i = 0; i < ST_NBR_MODES; i++) {
 		STm = &(tpnt->modes[i]);
 		STm->defined = 0;
@@ -4077,9 +4074,9 @@
 
 	sdev_printk(KERN_WARNING, SDp,
 		    "Attached scsi tape %s", tape_name(tpnt));
-	printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B), max page reachable by HBA %lu\n",
+	printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n",
 	       tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
-	       queue_dma_alignment(SDp->request_queue) + 1, tpnt->max_pfn);
+	       queue_dma_alignment(SDp->request_queue) + 1);
 
 	return 0;
 
@@ -4185,7 +4182,11 @@
 
 static void st_intr(struct scsi_cmnd *SCpnt)
 {
-	scsi_io_completion(SCpnt, (SCpnt->result ? 0: SCpnt->bufflen), 1);
+	/*
+	 * The caller should be checking the request's errors
+	 * value.
+	 */
+	scsi_io_completion(SCpnt, SCpnt->bufflen, 0);
 }
 
 /*
@@ -4194,27 +4195,10 @@
  */
 static int st_init_command(struct scsi_cmnd *SCpnt)
 {
-	struct request *rq;
-
 	if (!(SCpnt->request->flags & REQ_BLOCK_PC))
 		return 0;
 
-	rq = SCpnt->request;
-	if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
-		return 0;
-
-	memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
-	SCpnt->cmd_len = rq->cmd_len;
-
-	if (rq_data_dir(rq) == WRITE)
-		SCpnt->sc_data_direction = DMA_TO_DEVICE;
-	else if (rq->data_len)
-		SCpnt->sc_data_direction = DMA_FROM_DEVICE;
-	else
-		SCpnt->sc_data_direction = DMA_NONE;
-
-	SCpnt->timeout_per_command = rq->timeout;
-	SCpnt->transfersize = rq->data_len;
+	scsi_setup_blk_pc_cmnd(SCpnt);
 	SCpnt->done = st_intr;
 	return 1;
 }
@@ -4407,34 +4391,6 @@
 	return;
 }
 
-
-/* Pin down user pages and put them into a scatter gather list. Returns <= 0 if
-   - mapping of all pages not successful
-   - any page is above max_pfn
-   (i.e., either completely successful or fails)
-*/
-static int st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
-			     unsigned long uaddr, size_t count, int rw,
-			     unsigned long max_pfn)
-{
-	int i, nr_pages;
-
-	nr_pages = sgl_map_user_pages(sgl, max_pages, uaddr, count, rw);
-	if (nr_pages <= 0)
-		return nr_pages;
-
-	for (i=0; i < nr_pages; i++) {
-		if (page_to_pfn(sgl[i].page) > max_pfn)
-			goto out_unmap;
-	}
-	return nr_pages;
-
- out_unmap:
-	sgl_unmap_user_pages(sgl, nr_pages, 0);
-	return 0;
-}
-
-
 /* The following functions may be useful for a larger audience. */
 static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, 
 			      unsigned long uaddr, size_t count, int rw)
@@ -4509,6 +4465,7 @@
 	if (res > 0) {
 		for (j=0; j < res; j++)
 			page_cache_release(pages[j]);
+		res = 0;
 	}
 	kfree(pages);
 	return res;
@@ -4524,8 +4481,6 @@
 	for (i=0; i < nr_pages; i++) {
 		struct page *page = sgl[i].page;
 
-		/* XXX: just for debug. Remove when PageReserved is removed */
-		BUG_ON(PageReserved(page));
 		if (dirtied)
 			SetPageDirty(page);
 		/* FIXME: cache flush missing for rw==READ
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index 790acac..4112090 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -4,6 +4,7 @@
 
 #include <linux/completion.h>
 #include <linux/kref.h>
+#include <scsi/scsi_cmnd.h>
 
 /* Descriptor for analyzed sense data */
 struct st_cmdstatus {
@@ -17,6 +18,17 @@
 	u8 deferred;
 };
 
+struct scsi_tape;
+
+/* scsi tape command */
+struct st_request {
+	unsigned char cmd[MAX_COMMAND_SIZE];
+	unsigned char sense[SCSI_SENSE_BUFFERSIZE];
+	int result;
+	struct scsi_tape *stp;
+	struct completion *waiting;
+};
+
 /* The tape buffer descriptor. */
 struct st_buffer {
 	unsigned char in_use;
@@ -28,7 +40,7 @@
 	int read_pointer;
 	int writing;
 	int syscall_result;
-	struct scsi_request *last_SRpnt;
+	struct st_request *last_SRpnt;
 	struct st_cmdstatus cmdstat;
 	unsigned char *b_data;
 	unsigned short use_sg;	/* zero or max number of s/g segments for this adapter */
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index c041bfd..25cced9 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -70,6 +70,7 @@
  *
  */
 #include <scsi/scsi_dbg.h>
+#include <scsi/scsi_transport_spi.h>
 
 /*
  * Further development / testing that should be done : 
@@ -2378,7 +2379,7 @@
  * 3..length+1	arguments
  *
  * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since scsi_print_msg() wants the whole thing.  
+ * byte, since spi_print_msg() wants the whole thing.  
  */
 		    extended_msg[0] = EXTENDED_MESSAGE;
 		    /* Accept first byte by clearing ACK */
@@ -2431,7 +2432,7 @@
 		default:
 		    if (!tmp) {
 			printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
-			scsi_print_msg (extended_msg);
+			spi_print_msg(extended_msg);
 			printk("\n");
 		    } else if (tmp != EXTENDED_MESSAGE)
 			printk(KERN_DEBUG "scsi%d: rejecting unknown "
@@ -2566,7 +2567,7 @@
 
     if (!(msg[0] & 0x80)) {
 	printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
-	scsi_print_msg(msg);
+	spi_print_msg(msg);
 	do_abort(instance);
 	return;
     }
diff --git a/drivers/scsi/sym53c8xx_2/sym_defs.h b/drivers/scsi/sym53c8xx_2/sym_defs.h
index 2d9437d..3659dd7b 100644
--- a/drivers/scsi/sym53c8xx_2/sym_defs.h
+++ b/drivers/scsi/sym53c8xx_2/sym_defs.h
@@ -40,7 +40,7 @@
 #ifndef SYM_DEFS_H
 #define SYM_DEFS_H
 
-#define SYM_VERSION "2.2.1"
+#define SYM_VERSION "2.2.2"
 #define SYM_DRIVER_NAME	"sym-" SYM_VERSION
 
 /*
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.c b/drivers/scsi/sym53c8xx_2/sym_fw.c
index fd36cf9..9916a2a 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw.c
+++ b/drivers/scsi/sym53c8xx_2/sym_fw.c
@@ -37,11 +37,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifdef __FreeBSD__
-#include <dev/sym/sym_glue.h>
-#else
 #include "sym_glue.h"
-#endif
 
 /*
  *  Macros used for all firmwares.
@@ -60,19 +56,12 @@
 #define	SYM_FWA_SCR		sym_fw1a_scr
 #define	SYM_FWB_SCR		sym_fw1b_scr
 #define	SYM_FWZ_SCR		sym_fw1z_scr
-#ifdef __FreeBSD__
-#include <dev/sym/sym_fw1.h>
-#else
 #include "sym_fw1.h"
-#endif
 static struct sym_fwa_ofs sym_fw1a_ofs = {
 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
 };
 static struct sym_fwb_ofs sym_fw1b_ofs = {
 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	SYM_GEN_B(struct SYM_FWB_SCR, data_io)
-#endif
 };
 static struct sym_fwz_ofs sym_fw1z_ofs = {
 	SYM_GEN_FW_Z(struct SYM_FWZ_SCR)
@@ -88,19 +77,12 @@
 #define	SYM_FWA_SCR		sym_fw2a_scr
 #define	SYM_FWB_SCR		sym_fw2b_scr
 #define	SYM_FWZ_SCR		sym_fw2z_scr
-#ifdef __FreeBSD__
-#include <dev/sym/sym_fw2.h>
-#else
 #include "sym_fw2.h"
-#endif
 static struct sym_fwa_ofs sym_fw2a_ofs = {
 	SYM_GEN_FW_A(struct SYM_FWA_SCR)
 };
 static struct sym_fwb_ofs sym_fw2b_ofs = {
 	SYM_GEN_FW_B(struct SYM_FWB_SCR)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	SYM_GEN_B(struct SYM_FWB_SCR, data_io)
-#endif
 	SYM_GEN_B(struct SYM_FWB_SCR, start64)
 	SYM_GEN_B(struct SYM_FWB_SCR, pm_handle)
 };
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw.h b/drivers/scsi/sym53c8xx_2/sym_fw.h
index 43f6810..66ec35b 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw.h
@@ -92,9 +92,6 @@
 };
 struct sym_fwb_ofs {
 	SYM_GEN_FW_B(u_short)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	SYM_GEN_B(u_short, data_io)
-#endif
 	SYM_GEN_B(u_short, start64)
 	SYM_GEN_B(u_short, pm_handle)
 };
@@ -111,9 +108,6 @@
 };
 struct sym_fwb_ba {
 	SYM_GEN_FW_B(u32)
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	SYM_GEN_B(u32, data_io)
-#endif
 	SYM_GEN_B(u32, start64);
 	SYM_GEN_B(u32, pm_handle);
 };
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw1.h b/drivers/scsi/sym53c8xx_2/sym_fw1.h
index cdd92d8..7b39f4a 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw1.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw1.h
@@ -197,12 +197,6 @@
 	u32 bad_status		[  7];
 	u32 wsr_ma_helper	[  4];
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	/* Unknown direction handling */
-	u32 data_io		[  2];
-	u32 data_io_com		[  8];
-	u32 data_io_out		[  7];
-#endif
 	/* Data area */
 	u32 zero		[  1];
 	u32 scratch		[  1];
@@ -1747,48 +1741,6 @@
 	SCR_JUMP,
 		PADDR_A (dispatch),
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-}/*-------------------------< DATA_IO >--------------------------*/,{
-	/*
-	 *  We jump here if the data direction was unknown at the 
-	 *  time we had to queue the command to the scripts processor.
-	 *  Pointers had been set as follow in this situation:
-	 *    savep   -->   DATA_IO
-	 *    lastp   -->   start pointer when DATA_IN
-	 *    wlastp  -->   start pointer when DATA_OUT
-	 *  This script sets savep and lastp according to the 
-	 *  direction chosen by the target.
-	 */
-	SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
-		PADDR_B (data_io_out),
-}/*-------------------------< DATA_IO_COM >----------------------*/,{
-	/*
-	 *  Direction is DATA IN.
-	 */
-	SCR_COPY  (4),
-		HADDR_1 (ccb_head.lastp),
-		HADDR_1 (ccb_head.savep),
-	/*
-	 *  Jump to the SCRIPTS according to actual direction.
-	 */
-	SCR_COPY  (4),
-		HADDR_1 (ccb_head.savep),
-		RADDR_1 (temp),
-	SCR_RETURN,
-		0,
-}/*-------------------------< DATA_IO_OUT >----------------------*/,{
-	/*
-	 *  Direction is DATA OUT.
-	 */
-	SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
-		0,
-	SCR_COPY  (4),
-		HADDR_1 (ccb_head.wlastp),
-		HADDR_1 (ccb_head.lastp),
-	SCR_JUMP,
-		PADDR_B(data_io_com),
-#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */
-
 }/*-------------------------< ZERO >-----------------------------*/,{
 	SCR_DATA_ZERO,
 }/*-------------------------< SCRATCH >--------------------------*/,{
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw2.h b/drivers/scsi/sym53c8xx_2/sym_fw2.h
index 7ea7151..851f270 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw2.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw2.h
@@ -191,13 +191,6 @@
 	u32 pm_wsr_handle	[ 38];
 	u32 wsr_ma_helper	[  4];
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-	/* Unknown direction handling */
-	u32 data_io		[  2];
-	u32 data_io_in		[  2];
-	u32 data_io_com		[  6];
-	u32 data_io_out		[  8];
-#endif
 	/* Data area */
 	u32 zero		[  1];
 	u32 scratch		[  1];
@@ -1838,51 +1831,6 @@
 	SCR_JUMP,
 		PADDR_A (dispatch),
 
-#ifdef SYM_OPT_HANDLE_DIR_UNKNOWN
-}/*-------------------------< DATA_IO >--------------------------*/,{
-	/*
-	 *  We jump here if the data direction was unknown at the 
-	 *  time we had to queue the command to the scripts processor.
-	 *  Pointers had been set as follow in this situation:
-	 *    savep   -->   DATA_IO
-	 *    lastp   -->   start pointer when DATA_IN
-	 *    wlastp  -->   start pointer when DATA_OUT
-	 *  This script sets savep and lastp according to the 
-	 *  direction chosen by the target.
-	 */
-	SCR_JUMP ^ IFTRUE (WHEN (SCR_DATA_OUT)),
-		PADDR_B (data_io_out),
-}/*-------------------------< DATA_IO_IN >-----------------------*/,{
-	/*
-	 *  Direction is DATA IN.
-	 */
-	SCR_LOAD_REL  (scratcha, 4),
-		offsetof (struct sym_ccb, phys.head.lastp),
-}/*-------------------------< DATA_IO_COM >----------------------*/,{
-	SCR_STORE_REL (scratcha, 4),
-		offsetof (struct sym_ccb, phys.head.savep),
-
-	/*
-	 *  Jump to the SCRIPTS according to actual direction.
-	 */
-	SCR_LOAD_REL  (temp, 4),
-		offsetof (struct sym_ccb, phys.head.savep),
-	SCR_RETURN,
-		0,
-}/*-------------------------< DATA_IO_OUT >----------------------*/,{
-	/*
-	 *  Direction is DATA OUT.
-	 */
-	SCR_REG_REG (HF_REG, SCR_AND, (~HF_DATA_IN)),
-		0,
-	SCR_LOAD_REL  (scratcha, 4),
-		offsetof (struct sym_ccb, phys.head.wlastp),
-	SCR_STORE_REL (scratcha, 4),
-		offsetof (struct sym_ccb, phys.head.lastp),
-	SCR_JUMP,
-		PADDR_B(data_io_com),
-#endif /* SYM_OPT_HANDLE_DIR_UNKNOWN */
-
 }/*-------------------------< ZERO >-----------------------------*/,{
 	SCR_DATA_ZERO,
 }/*-------------------------< SCRATCH >--------------------------*/,{
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index d76766c..1fffd2b 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -514,9 +514,10 @@
  */
 int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)
 {
-	int dir;
 	struct sym_tcb *tp = &np->target[cp->target];
 	struct sym_lcb *lp = sym_lp(tp, cp->lun);
+	u32 lastp, goalp;
+	int dir;
 
 	/*
 	 *  Build the CDB.
@@ -534,15 +535,47 @@
 			sym_set_cam_status(cmd, DID_ERROR);
 			goto out_abort;
 		}
+
+		/*
+		 *  No segments means no data.
+		 */
+		if (!cp->segments)
+			dir = DMA_NONE;
 	} else {
 		cp->data_len = 0;
 		cp->segments = 0;
 	}
 
 	/*
-	 *  Set data pointers.
+	 *  Set the data pointer.
 	 */
-	sym_setup_data_pointers(np, cp, dir);
+	switch (dir) {
+	case DMA_BIDIRECTIONAL:
+		printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np));
+		sym_set_cam_status(cmd, DID_ERROR);
+		goto out_abort;
+	case DMA_TO_DEVICE:
+		goalp = SCRIPTA_BA(np, data_out2) + 8;
+		lastp = goalp - 8 - (cp->segments * (2*4));
+		break;
+	case DMA_FROM_DEVICE:
+		cp->host_flags |= HF_DATA_IN;
+		goalp = SCRIPTA_BA(np, data_in2) + 8;
+		lastp = goalp - 8 - (cp->segments * (2*4));
+		break;
+	case DMA_NONE:
+	default:
+		lastp = goalp = SCRIPTB_BA(np, no_data);
+		break;
+	}
+
+	/*
+	 *  Set all pointers values needed by SCRIPTS.
+	 */
+	cp->phys.head.lastp = cpu_to_scr(lastp);
+	cp->phys.head.savep = cpu_to_scr(lastp);
+	cp->startp	    = cp->phys.head.savep;
+	cp->goalp	    = cpu_to_scr(goalp);
 
 	/*
 	 *  When `#ifed 1', the code below makes the driver 
@@ -563,10 +596,7 @@
 	/*
 	 *	activate this job.
 	 */
-	if (lp)
-		sym_start_next_ccbs(np, lp, 2);
-	else
-		sym_put_start_queue(np, cp);
+	sym_start_next_ccbs(np, lp, 2);
 	return 0;
 
 out_abort:
@@ -981,15 +1011,14 @@
 
 static int sym53c8xx_slave_alloc(struct scsi_device *sdev)
 {
-	struct sym_hcb *np;
-	struct sym_tcb *tp;
+	struct sym_hcb *np = sym_get_hcb(sdev->host);
+	struct sym_tcb *tp = &np->target[sdev->id];
+	struct sym_lcb *lp;
 
 	if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)
 		return -ENXIO;
 
-	np = sym_get_hcb(sdev->host);
-	tp = &np->target[sdev->id];
-
+	tp->starget = sdev->sdev_target;
 	/*
 	 * Fail the device init if the device is flagged NOSCAN at BOOT in
 	 * the NVRAM.  This may speed up boot and maintain coherency with
@@ -999,35 +1028,41 @@
 	 * lun devices behave badly when asked for a non zero LUN.
 	 */
 
-	if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) ||
-	    ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) {
+	if (tp->usrflags & SYM_SCAN_BOOT_DISABLED) {
 		tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;
+		starget_printk(KERN_INFO, tp->starget,
+				"Scan at boot disabled in NVRAM\n");
 		return -ENXIO;
 	}
 
-	tp->starget = sdev->sdev_target;
+	if (tp->usrflags & SYM_SCAN_LUNS_DISABLED) {
+		if (sdev->lun != 0)
+			return -ENXIO;
+		starget_printk(KERN_INFO, tp->starget,
+				"Multiple LUNs disabled in NVRAM\n");
+	}
+
+	lp = sym_alloc_lcb(np, sdev->id, sdev->lun);
+	if (!lp)
+		return -ENOMEM;
+
+	spi_min_period(tp->starget) = tp->usr_period;
+	spi_max_width(tp->starget) = tp->usr_width;
+
 	return 0;
 }
 
 /*
  * Linux entry point for device queue sizing.
  */
-static int sym53c8xx_slave_configure(struct scsi_device *device)
+static int sym53c8xx_slave_configure(struct scsi_device *sdev)
 {
-	struct sym_hcb *np = sym_get_hcb(device->host);
-	struct sym_tcb *tp = &np->target[device->id];
-	struct sym_lcb *lp;
+	struct sym_hcb *np = sym_get_hcb(sdev->host);
+	struct sym_tcb *tp = &np->target[sdev->id];
+	struct sym_lcb *lp = sym_lp(tp, sdev->lun);
 	int reqtags, depth_to_use;
 
 	/*
-	 *  Allocate the LCB if not yet.
-	 *  If it fail, we may well be in the sh*t. :)
-	 */
-	lp = sym_alloc_lcb(np, device->id, device->lun);
-	if (!lp)
-		return -ENOMEM;
-
-	/*
 	 *  Get user flags.
 	 */
 	lp->curr_flags = lp->user_flags;
@@ -1038,10 +1073,10 @@
 	 *  Use at least 2.
 	 *  Donnot use more than our maximum.
 	 */
-	reqtags = device_queue_depth(np, device->id, device->lun);
+	reqtags = device_queue_depth(np, sdev->id, sdev->lun);
 	if (reqtags > tp->usrtags)
 		reqtags = tp->usrtags;
-	if (!device->tagged_supported)
+	if (!sdev->tagged_supported)
 		reqtags = 0;
 #if 1 /* Avoid to locally queue commands for no good reasons */
 	if (reqtags > SYM_CONF_MAX_TAG)
@@ -1050,19 +1085,30 @@
 #else
 	depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2);
 #endif
-	scsi_adjust_queue_depth(device,
-				(device->tagged_supported ?
+	scsi_adjust_queue_depth(sdev,
+				(sdev->tagged_supported ?
 				 MSG_SIMPLE_TAG : 0),
 				depth_to_use);
 	lp->s.scdev_depth = depth_to_use;
-	sym_tune_dev_queuing(tp, device->lun, reqtags);
+	sym_tune_dev_queuing(tp, sdev->lun, reqtags);
 
-	if (!spi_initial_dv(device->sdev_target))
-		spi_dv_device(device);
+	if (!spi_initial_dv(sdev->sdev_target))
+		spi_dv_device(sdev);
 
 	return 0;
 }
 
+static void sym53c8xx_slave_destroy(struct scsi_device *sdev)
+{
+	struct sym_hcb *np = sym_get_hcb(sdev->host);
+	struct sym_lcb *lp = sym_lp(&np->target[sdev->id], sdev->lun);
+
+	if (lp->itlq_tbl)
+		sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK * 4, "ITLQ_TBL");
+	kfree(lp->cb_tags);
+	sym_mfree_dma(lp, sizeof(*lp), "LCB");
+}
+
 /*
  *  Linux entry point for info() function
  */
@@ -1497,7 +1543,7 @@
 {
 #if SYM_CONF_DMA_ADDRESSING_MODE > 0
 #if   SYM_CONF_DMA_ADDRESSING_MODE == 1
-#define	DMA_DAC_MASK	0x000000ffffffffffULL /* 40-bit */
+#define	DMA_DAC_MASK	DMA_40BIT_MASK
 #elif SYM_CONF_DMA_ADDRESSING_MODE == 2
 #define	DMA_DAC_MASK	DMA_64BIT_MASK
 #endif
@@ -1926,6 +1972,7 @@
 	.queuecommand		= sym53c8xx_queue_command,
 	.slave_alloc		= sym53c8xx_slave_alloc,
 	.slave_configure	= sym53c8xx_slave_configure,
+	.slave_destroy		= sym53c8xx_slave_destroy,
 	.eh_abort_handler	= sym53c8xx_eh_abort_handler,
 	.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
 	.eh_bus_reset_handler	= sym53c8xx_eh_bus_reset_handler,
@@ -2086,6 +2133,7 @@
 	tp->tgoal.check_nego = 1;
 }
 
+#if 0
 static void sym2_set_iu(struct scsi_target *starget, int iu)
 {
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -2111,7 +2159,7 @@
 		tp->tgoal.qas = 0;
 	tp->tgoal.check_nego = 1;
 }
-
+#endif
 
 static struct spi_function_template sym2_transport_functions = {
 	.set_offset	= sym2_set_offset,
@@ -2122,10 +2170,12 @@
 	.show_width	= 1,
 	.set_dt		= sym2_set_dt,
 	.show_dt	= 1,
+#if 0
 	.set_iu		= sym2_set_iu,
 	.show_iu	= 1,
 	.set_qas	= sym2_set_qas,
 	.show_qas	= 1,
+#endif
 	.get_signalling	= sym2_get_signalling,
 };
 
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
index d3d52f1..cc92d0c 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h
@@ -68,7 +68,6 @@
  */
 #define	SYM_CONF_TIMER_INTERVAL		((HZ+1)/2)
 
-#define SYM_OPT_HANDLE_DIR_UNKNOWN
 #define SYM_OPT_HANDLE_DEVICE_QUEUEING
 #define SYM_OPT_LIMIT_COMMAND_REORDERING
 
@@ -268,6 +267,5 @@
 void sym_xpt_async_sent_bdr(struct sym_hcb *np, int target);
 int  sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp);
 void sym_log_bus_error(struct sym_hcb *np);
-void sym_sniff_inquiry(struct sym_hcb *np, struct scsi_cmnd *cmd, int resid);
 
 #endif /* SYM_GLUE_H */
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index a7420ca..8260f04 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -40,6 +40,7 @@
 
 #include <linux/slab.h>
 #include <asm/param.h>		/* for timeouts in units of HZ */
+#include <scsi/scsi_dbg.h>
 
 #include "sym_glue.h"
 #include "sym_nvram.h"
@@ -70,32 +71,12 @@
 	printf (".\n");
 }
 
-/*
- *  Print out the content of a SCSI message.
- */
-static int sym_show_msg (u_char * msg)
-{
-	u_char i;
-	printf ("%x",*msg);
-	if (*msg==M_EXTENDED) {
-		for (i=1;i<8;i++) {
-			if (i-1>msg[1]) break;
-			printf ("-%x",msg[i]);
-		}
-		return (i+1);
-	} else if ((*msg & 0xf0) == 0x20) {
-		printf ("-%x",msg[1]);
-		return (2);
-	}
-	return (1);
-}
-
 static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg)
 {
 	sym_print_addr(cp->cmd, "%s: ", label);
 
-	sym_show_msg(msg);
-	printf(".\n");
+	spi_print_msg(msg);
+	printf("\n");
 }
 
 static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg)
@@ -103,8 +84,8 @@
 	struct sym_tcb *tp = &np->target[target];
 	dev_info(&tp->starget->dev, "%s: ", label);
 
-	sym_show_msg(msg);
-	printf(".\n");
+	spi_print_msg(msg);
+	printf("\n");
 }
 
 /*
@@ -635,29 +616,6 @@
 	}
 }
 
-
-/*
- * Print out the list of targets that have some flag disabled by user.
- */
-static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg)
-{
-	int cnt;
-	int i;
-
-	for (cnt = 0, i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
-		if (i == np->myaddr)
-			continue;
-		if (np->target[i].usrflags & mask) {
-			if (!cnt++)
-				printf("%s: %s disabled for targets",
-					sym_name(np), msg);
-			printf(" %d", i);
-		}
-	}
-	if (cnt)
-		printf(".\n");
-}
-
 /*
  *  Save initial settings of some IO registers.
  *  Assumed to have been set by BIOS.
@@ -962,7 +920,7 @@
 		tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED);
 		tp->usrtags = SYM_SETUP_MAX_TAG;
 
-		sym_nvram_setup_target(np, i, nvram);
+		sym_nvram_setup_target(tp, i, nvram);
 
 		if (!tp->usrtags)
 			tp->usrflags &= ~SYM_TAGS_ENABLED;
@@ -1005,13 +963,6 @@
 			sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl,
 			np->rv_ctest3, np->rv_ctest4, np->rv_ctest5);
 	}
-	/*
-	 *  Let user be aware of targets that have some disable flags set.
-	 */
-	sym_print_targets_flag(np, SYM_SCAN_BOOT_DISABLED, "SCAN AT BOOT");
-	if (sym_verbose)
-		sym_print_targets_flag(np, SYM_SCAN_LUNS_DISABLED,
-				       "SCAN FOR LUNS");
 
 	return 0;
 }
@@ -1405,7 +1356,6 @@
 		goal->iu = 0;
 		goal->dt = 0;
 		goal->qas = 0;
-		goal->period = 0;
 		goal->offset = 0;
 		return;
 	}
@@ -1465,7 +1415,8 @@
 	 * Many devices implement PPR in a buggy way, so only use it if we
 	 * really want to.
 	 */
-	if (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)) {
+	if (goal->offset &&
+	    (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) {
 		nego = NS_PPR;
 	} else if (spi_width(starget) != goal->width) {
 		nego = NS_WIDE;
@@ -1523,7 +1474,7 @@
 /*
  *  Insert a job into the start queue.
  */
-void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
+static void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp)
 {
 	u_short	qidx;
 
@@ -3654,7 +3605,7 @@
 	 *  If result is dp_sg = SYM_CONF_MAX_SG, then we are at the 
 	 *  end of the data.
 	 */
-	tmp = scr_to_cpu(sym_goalp(cp));
+	tmp = scr_to_cpu(cp->goalp);
 	dp_sg = SYM_CONF_MAX_SG;
 	if (dp_scr != tmp)
 		dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4);
@@ -3761,7 +3712,7 @@
 	 *  And our alchemy:) allows to easily calculate the data 
 	 *  script address we want to return for the next data phase.
 	 */
-	dp_ret = cpu_to_scr(sym_goalp(cp));
+	dp_ret = cpu_to_scr(cp->goalp);
 	dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4);
 
 	/*
@@ -3857,7 +3808,7 @@
 	 *  If all data has been transferred,
 	 *  there is no residual.
 	 */
-	if (cp->phys.head.lastp == sym_goalp(cp))
+	if (cp->phys.head.lastp == cp->goalp)
 		return resid;
 
 	/*
@@ -4664,30 +4615,7 @@
 		goto out;
 	cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);
 
-#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING
-	/*
-	 *  If the LCB is not yet available and the LUN
-	 *  has been probed ok, try to allocate the LCB.
-	 */
-	if (!lp && sym_is_bit(tp->lun_map, ln)) {
-		lp = sym_alloc_lcb(np, tn, ln);
-		if (!lp)
-			goto out_free;
-	}
-#endif
-
-	/*
-	 *  If the LCB is not available here, then the 
-	 *  logical unit is not yet discovered. For those 
-	 *  ones only accept 1 SCSI IO per logical unit, 
-	 *  since we cannot allow disconnections.
-	 */
-	if (!lp) {
-		if (!sym_is_bit(tp->busy0_map, ln))
-			sym_set_bit(tp->busy0_map, ln);
-		else
-			goto out_free;
-	} else {
+	{
 		/*
 		 *  If we have been asked for a tagged command.
 		 */
@@ -4840,12 +4768,6 @@
 			lp->head.resel_sa =
 				cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun));
 	}
-	/*
-	 *  Otherwise, we only accept 1 IO per LUN.
-	 *  Clear the bit that keeps track of this IO.
-	 */
-	else
-		sym_clr_bit(tp->busy0_map, cp->lun);
 
 	/*
 	 *  We donnot queue more than 1 ccb per target 
@@ -4997,20 +4919,7 @@
 struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln)
 {
 	struct sym_tcb *tp = &np->target[tn];
-	struct sym_lcb *lp = sym_lp(tp, ln);
-
-	/*
-	 *  Already done, just return.
-	 */
-	if (lp)
-		return lp;
-
-	/*
-	 *  Donnot allow LUN control block 
-	 *  allocation for not probed LUNs.
-	 */
-	if (!sym_is_bit(tp->lun_map, ln))
-		return NULL;
+	struct sym_lcb *lp = NULL;
 
 	/*
 	 *  Initialize the target control block if not yet.
@@ -5082,13 +4991,7 @@
 	lp->started_max   = SYM_CONF_MAX_TASK;
 	lp->started_limit = SYM_CONF_MAX_TASK;
 #endif
-	/*
-	 *  If we are busy, count the IO.
-	 */
-	if (sym_is_bit(tp->busy0_map, ln)) {
-		lp->busy_itl = 1;
-		sym_clr_bit(tp->busy0_map, ln);
-	}
+
 fail:
 	return lp;
 }
@@ -5103,12 +5006,6 @@
 	int i;
 
 	/*
-	 *  If LCB not available, try to allocate it.
-	 */
-	if (!lp && !(lp = sym_alloc_lcb(np, tn, ln)))
-		goto fail;
-
-	/*
 	 *  Allocate the task table and and the tag allocation 
 	 *  circular buffer. We want both or none.
 	 */
@@ -5481,8 +5378,7 @@
 	/*
 	 *  Donnot start more than 1 command after an error.
 	 */
-	if (lp)
-		sym_start_next_ccbs(np, lp, 1);
+	sym_start_next_ccbs(np, lp, 1);
 #endif
 }
 
@@ -5521,17 +5417,11 @@
 	lp = sym_lp(tp, cp->lun);
 
 	/*
-	 *  Assume device discovered on first success.
-	 */
-	if (!lp)
-		sym_set_bit(tp->lun_map, cp->lun);
-
-	/*
 	 *  If all data have been transferred, given than no
 	 *  extended error did occur, there is no residual.
 	 */
 	resid = 0;
-	if (cp->phys.head.lastp != sym_goalp(cp))
+	if (cp->phys.head.lastp != cp->goalp)
 		resid = sym_compute_residual(np, cp);
 
 	/*
@@ -5551,15 +5441,6 @@
 	 */
 	sym_set_cam_result_ok(cp, cmd, resid);
 
-#ifdef	SYM_OPT_SNIFF_INQUIRY
-	/*
-	 *  On standard INQUIRY response (EVPD and CmDt 
-	 *  not set), sniff out device capabilities.
-	 */
-	if (cp->cdb_buf[0] == INQUIRY && !(cp->cdb_buf[1] & 0x3))
-		sym_sniff_inquiry(np, cmd, resid);
-#endif
-
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 	/*
 	 *  If max number of started ccbs had been reduced,
@@ -5587,7 +5468,7 @@
 	/*
 	 *  Requeue a couple of awaiting scsi commands.
 	 */
-	if (lp && !sym_que_empty(&lp->waiting_ccbq))
+	if (!sym_que_empty(&lp->waiting_ccbq))
 		sym_start_next_ccbs(np, lp, 2);
 #endif
 	/*
@@ -5830,8 +5711,7 @@
 	SYM_QUEHEAD *qp;
 	struct sym_ccb *cp;
 	struct sym_tcb *tp;
-	struct sym_lcb *lp;
-	int target, lun;
+	int target;
 
 	if (np->scriptz0)
 		sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0");
@@ -5857,16 +5737,6 @@
 
 	for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) {
 		tp = &np->target[target];
-		for (lun = 0 ; lun < SYM_CONF_MAX_LUN ; lun++) {
-			lp = sym_lp(tp, lun);
-			if (!lp)
-				continue;
-			if (lp->itlq_tbl)
-				sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4,
-				       "ITLQ_TBL");
-			kfree(lp->cb_tags);
-			sym_mfree_dma(lp, sizeof(*lp), "LCB");
-		}
 #if SYM_CONF_MAX_LUN > 1
 		kfree(tp->lunmp);
 #endif 
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index 3a264a4..2456090 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -48,12 +48,6 @@
  *  They may be defined in platform specific headers, if they 
  *  are useful.
  *
- *    SYM_OPT_HANDLE_DIR_UNKNOWN
- *        When this option is set, the SCRIPTS used by the driver 
- *        are able to handle SCSI transfers with direction not 
- *        supplied by user.
- *        (set for Linux-2.0.X)
- *
  *    SYM_OPT_HANDLE_DEVICE_QUEUEING
  *        When this option is set, the driver will use a queue per 
  *        device and handle QUEUE FULL status requeuing internally.
@@ -64,7 +58,6 @@
  *        (set for Linux)
  */
 #if 0
-#define SYM_OPT_HANDLE_DIR_UNKNOWN
 #define SYM_OPT_HANDLE_DEVICE_QUEUEING
 #define SYM_OPT_LIMIT_COMMAND_REORDERING
 #endif
@@ -416,19 +409,6 @@
 	struct sym_lcb **lunmp;		/* Other LCBs [1..MAX_LUN]	*/
 #endif
 
-	/*
-	 *  Bitmap that tells about LUNs that succeeded at least 
-	 *  1 IO and therefore assumed to be a real device.
-	 *  Avoid useless allocation of the LCB structure.
-	 */
-	u32	lun_map[(SYM_CONF_MAX_LUN+31)/32];
-
-	/*
-	 *  Bitmap that tells about LUNs that haven't yet an LCB 
-	 *  allocated (not discovered or LCB allocation failed).
-	 */
-	u32	busy0_map[(SYM_CONF_MAX_LUN+31)/32];
-
 #ifdef	SYM_HAVE_STCB
 	/*
 	 *  O/S specific data structure.
@@ -454,8 +434,10 @@
 	 *  Other user settable limits and options.
 	 *  These limits are read from the NVRAM if present.
 	 */
-	u_char	usrflags;
-	u_short	usrtags;
+	unsigned char	usrflags;
+	unsigned char	usr_period;
+	unsigned char	usr_width;
+	unsigned short	usrtags;
 	struct scsi_target *starget;
 };
 
@@ -672,9 +654,6 @@
 	 */
 	u32	savep;		/* Jump address to saved data pointer	*/
 	u32	lastp;		/* SCRIPTS address at end of data	*/
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-	u32	wlastp;
-#endif
 
 	/*
 	 *  Status fields.
@@ -804,9 +783,6 @@
 	SYM_QUEHEAD link_ccbq;	/* Link to free/busy CCB queue	*/
 	u32	startp;		/* Initial data pointer		*/
 	u32	goalp;		/* Expected last data pointer	*/
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-	u32	wgoalp;
-#endif
 	int	ext_sg;		/* Extreme data pointer, used	*/
 	int	ext_ofs;	/*  to calculate the residual.	*/
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
@@ -821,12 +797,6 @@
 
 #define CCB_BA(cp,lbl)	cpu_to_scr(cp->ccb_ba + offsetof(struct sym_ccb, lbl))
 
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-#define	sym_goalp(cp) ((cp->host_flags & HF_DATA_IN) ? cp->goalp : cp->wgoalp)
-#else
-#define	sym_goalp(cp) (cp->goalp)
-#endif
-
 typedef struct device *m_pool_ident_t;
 
 /*
@@ -1077,7 +1047,6 @@
 void sym_print_xerr(struct scsi_cmnd *cmd, int x_status);
 int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int);
 struct sym_chip *sym_lookup_chip_table(u_short device_id, u_char revision);
-void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp);
 #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING
 void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn);
 #endif
@@ -1136,71 +1105,6 @@
 #endif
 
 /*
- *  Set up data pointers used by SCRIPTS.
- *  Called from O/S specific code.
- */
-static inline void sym_setup_data_pointers(struct sym_hcb *np,
-		struct sym_ccb *cp, int dir)
-{
-	u32 lastp, goalp;
-
-	/*
-	 *  No segments means no data.
-	 */
-	if (!cp->segments)
-		dir = DMA_NONE;
-
-	/*
-	 *  Set the data pointer.
-	 */
-	switch(dir) {
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-	case DMA_BIDIRECTIONAL:
-#endif
-	case DMA_TO_DEVICE:
-		goalp = SCRIPTA_BA(np, data_out2) + 8;
-		lastp = goalp - 8 - (cp->segments * (2*4));
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-		cp->wgoalp = cpu_to_scr(goalp);
-		if (dir != DMA_BIDIRECTIONAL)
-			break;
-		cp->phys.head.wlastp = cpu_to_scr(lastp);
-		/* fall through */
-#else
-		break;
-#endif
-	case DMA_FROM_DEVICE:
-		cp->host_flags |= HF_DATA_IN;
-		goalp = SCRIPTA_BA(np, data_in2) + 8;
-		lastp = goalp - 8 - (cp->segments * (2*4));
-		break;
-	case DMA_NONE:
-	default:
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-		cp->host_flags |= HF_DATA_IN;
-#endif
-		lastp = goalp = SCRIPTB_BA(np, no_data);
-		break;
-	}
-
-	/*
-	 *  Set all pointers values needed by SCRIPTS.
-	 */
-	cp->phys.head.lastp = cpu_to_scr(lastp);
-	cp->phys.head.savep = cpu_to_scr(lastp);
-	cp->startp	    = cp->phys.head.savep;
-	cp->goalp	    = cpu_to_scr(goalp);
-
-#ifdef	SYM_OPT_HANDLE_DIR_UNKNOWN
-	/*
-	 *  If direction is unknown, start at data_io.
-	 */
-	if (dir == DMA_BIDIRECTIONAL)
-		cp->phys.head.savep = cpu_to_scr(SCRIPTB_BA(np, data_io));
-#endif
-}
-
-/*
  *  MEMORY ALLOCATOR.
  */
 
diff --git a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c
index a34d403..92bf9b1 100644
--- a/drivers/scsi/sym53c8xx_2/sym_malloc.c
+++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c
@@ -37,11 +37,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifdef __FreeBSD__
-#include <dev/sym/sym_glue.h>
-#else
 #include "sym_glue.h"
-#endif
 
 /*
  *  Simple power of two buddy-like generic allocator.
diff --git a/drivers/scsi/sym53c8xx_2/sym_nvram.c b/drivers/scsi/sym53c8xx_2/sym_nvram.c
index 994b756..15d6929 100644
--- a/drivers/scsi/sym53c8xx_2/sym_nvram.c
+++ b/drivers/scsi/sym53c8xx_2/sym_nvram.c
@@ -92,29 +92,32 @@
  *  Get target set-up from Symbios format NVRAM.
  */
 static void
-sym_Symbios_setup_target(struct sym_hcb *np, int target, Symbios_nvram *nvram)
+sym_Symbios_setup_target(struct sym_tcb *tp, int target, Symbios_nvram *nvram)
 {
-	struct sym_tcb *tp = &np->target[target];
 	Symbios_target *tn = &nvram->target[target];
 
-	tp->usrtags =
-		(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED)? SYM_SETUP_MAX_TAG : 0;
-
+	if (!(tn->flags & SYMBIOS_QUEUE_TAGS_ENABLED))
+		tp->usrtags = 0;
 	if (!(tn->flags & SYMBIOS_DISCONNECT_ENABLE))
 		tp->usrflags &= ~SYM_DISC_ENABLED;
 	if (!(tn->flags & SYMBIOS_SCAN_AT_BOOT_TIME))
 		tp->usrflags |= SYM_SCAN_BOOT_DISABLED;
 	if (!(tn->flags & SYMBIOS_SCAN_LUNS))
 		tp->usrflags |= SYM_SCAN_LUNS_DISABLED;
+	tp->usr_period = (tn->sync_period + 3) / 4;
+	tp->usr_width = (tn->bus_width == 0x8) ? 0 : 1;
 }
 
+static const unsigned char Tekram_sync[16] = {
+	25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21, 6, 7, 9, 10
+};
+
 /*
  *  Get target set-up from Tekram format NVRAM.
  */
 static void
-sym_Tekram_setup_target(struct sym_hcb *np, int target, Tekram_nvram *nvram)
+sym_Tekram_setup_target(struct sym_tcb *tp, int target, Tekram_nvram *nvram)
 {
-	struct sym_tcb *tp = &np->target[target];
 	struct Tekram_target *tn = &nvram->target[target];
 
 	if (tn->flags & TEKRAM_TAGGED_COMMANDS) {
@@ -124,22 +127,22 @@
 	if (tn->flags & TEKRAM_DISCONNECT_ENABLE)
 		tp->usrflags |= SYM_DISC_ENABLED;
  
-	/* If any device does not support parity, we will not use this option */
-	if (!(tn->flags & TEKRAM_PARITY_CHECK))
-		np->rv_scntl0  &= ~0x0a; /* SCSI parity checking disabled */
+	if (tn->flags & TEKRAM_SYNC_NEGO)
+		tp->usr_period = Tekram_sync[tn->sync_index & 0xf];
+	tp->usr_width = (tn->flags & TEKRAM_WIDE_NEGO) ? 1 : 0;
 }
 
 /*
  *  Get target setup from NVRAM.
  */
-void sym_nvram_setup_target(struct sym_hcb *np, int target, struct sym_nvram *nvp)
+void sym_nvram_setup_target(struct sym_tcb *tp, int target, struct sym_nvram *nvp)
 {
 	switch (nvp->type) {
 	case SYM_SYMBIOS_NVRAM:
-		sym_Symbios_setup_target(np, target, &nvp->data.Symbios);
+		sym_Symbios_setup_target(tp, target, &nvp->data.Symbios);
 		break;
 	case SYM_TEKRAM_NVRAM:
-		sym_Tekram_setup_target(np, target, &nvp->data.Tekram);
+		sym_Tekram_setup_target(tp, target, &nvp->data.Tekram);
 		break;
 	default:
 		break;
diff --git a/drivers/scsi/sym53c8xx_2/sym_nvram.h b/drivers/scsi/sym53c8xx_2/sym_nvram.h
index 1538bed..bdfbbb0 100644
--- a/drivers/scsi/sym53c8xx_2/sym_nvram.h
+++ b/drivers/scsi/sym53c8xx_2/sym_nvram.h
@@ -194,12 +194,12 @@
 
 #if SYM_CONF_NVRAM_SUPPORT
 void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram);
-void sym_nvram_setup_target (struct sym_hcb *np, int target, struct sym_nvram *nvp);
+void sym_nvram_setup_target (struct sym_tcb *tp, int target, struct sym_nvram *nvp);
 int sym_read_nvram (struct sym_device *np, struct sym_nvram *nvp);
 char *sym_nvram_type(struct sym_nvram *nvp);
 #else
 static inline void sym_nvram_setup_host(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) { }
-static inline void sym_nvram_setup_target(struct sym_hcb *np, struct sym_nvram *nvram) { }
+static inline void sym_nvram_setup_target(struct sym_tcb *tp, struct sym_nvram *nvram) { }
 static inline int sym_read_nvram(struct sym_device *np, struct sym_nvram *nvp)
 {
 	nvp->type = 0;
diff --git a/drivers/scsi/sym53c8xx_comm.h b/drivers/scsi/sym53c8xx_comm.h
deleted file mode 100644
index 20ae2b1..0000000
--- a/drivers/scsi/sym53c8xx_comm.h
+++ /dev/null
@@ -1,792 +0,0 @@
-/******************************************************************************
-**  High Performance device driver for the Symbios 53C896 controller.
-**
-**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
-**
-**  This driver also supports all the Symbios 53C8XX controller family, 
-**  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
-**  revisions of 53C815 controllers.
-**
-**  This driver is based on the Linux port of the FreeBSD ncr driver.
-** 
-**  Copyright (C) 1994  Wolfgang Stanglmeier
-**  
-**-----------------------------------------------------------------------------
-**  
-**  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.
-**
-**-----------------------------------------------------------------------------
-**
-**  The Linux port of the FreeBSD ncr driver has been achieved in 
-**  november 1995 by:
-**
-**          Gerard Roudier              <groudier@free.fr>
-**
-**  Being given that this driver originates from the FreeBSD version, and
-**  in order to keep synergy on both, any suggested enhancements and corrections
-**  received on Linux are automatically a potential candidate for the FreeBSD 
-**  version.
-**
-**  The original driver has been written for 386bsd and FreeBSD by
-**          Wolfgang Stanglmeier        <wolf@cologne.de>
-**          Stefan Esser                <se@mi.Uni-Koeln.de>
-**
-**-----------------------------------------------------------------------------
-**
-**  Major contributions:
-**  --------------------
-**
-**  NVRAM detection and reading.
-**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
-**
-*******************************************************************************
-*/
-
-/*==========================================================
-**
-**	Debugging tags
-**
-**==========================================================
-*/
-
-#define DEBUG_ALLOC    (0x0001)
-#define DEBUG_PHASE    (0x0002)
-#define DEBUG_QUEUE    (0x0008)
-#define DEBUG_RESULT   (0x0010)
-#define DEBUG_POINTER  (0x0020)
-#define DEBUG_SCRIPT   (0x0040)
-#define DEBUG_TINY     (0x0080)
-#define DEBUG_TIMING   (0x0100)
-#define DEBUG_NEGO     (0x0200)
-#define DEBUG_TAGS     (0x0400)
-#define DEBUG_SCATTER  (0x0800)
-#define DEBUG_IC        (0x1000)
-
-/*
-**    Enable/Disable debug messages.
-**    Can be changed at runtime too.
-*/
-
-#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT
-static int ncr_debug = SCSI_NCR_DEBUG_FLAGS;
-	#define DEBUG_FLAGS ncr_debug
-#else
-	#define DEBUG_FLAGS	SCSI_NCR_DEBUG_FLAGS
-#endif
-
-static inline struct list_head *ncr_list_pop(struct list_head *head)
-{
-	if (!list_empty(head)) {
-		struct list_head *elem = head->next;
-
-		list_del(elem);
-		return elem;
-	}
-
-	return NULL;
-}
-
-#ifdef __sparc__
-#include <asm/irq.h>
-#endif
-
-/*==========================================================
-**
-**	Simple power of two buddy-like allocator.
-**
-**	This simple code is not intended to be fast, but to 
-**	provide power of 2 aligned memory allocations.
-**	Since the SCRIPTS processor only supplies 8 bit 
-**	arithmetic, this allocator allows simple and fast 
-**	address calculations  from the SCRIPTS code.
-**	In addition, cache line alignment is guaranteed for 
-**	power of 2 cache line size.
-**	Enhanced in linux-2.3.44 to provide a memory pool 
-**	per pcidev to support dynamic dma mapping. (I would 
-**	have preferred a real bus astraction, btw).
-**
-**==========================================================
-*/
-
-#define MEMO_SHIFT	4	/* 16 bytes minimum memory chunk */
-#if PAGE_SIZE >= 8192
-#define MEMO_PAGE_ORDER	0	/* 1 PAGE  maximum */
-#else
-#define MEMO_PAGE_ORDER	1	/* 2 PAGES maximum */
-#endif
-#define MEMO_FREE_UNUSED	/* Free unused pages immediately */
-#define MEMO_WARN	1
-#define MEMO_GFP_FLAGS	GFP_ATOMIC
-#define MEMO_CLUSTER_SHIFT	(PAGE_SHIFT+MEMO_PAGE_ORDER)
-#define MEMO_CLUSTER_SIZE	(1UL << MEMO_CLUSTER_SHIFT)
-#define MEMO_CLUSTER_MASK	(MEMO_CLUSTER_SIZE-1)
-
-typedef u_long m_addr_t;	/* Enough bits to bit-hack addresses */
-typedef struct device *m_bush_t;	/* Something that addresses DMAable */
-
-typedef struct m_link {		/* Link between free memory chunks */
-	struct m_link *next;
-} m_link_s;
-
-typedef struct m_vtob {		/* Virtual to Bus address translation */
-	struct m_vtob *next;
-	m_addr_t vaddr;
-	m_addr_t baddr;
-} m_vtob_s;
-#define VTOB_HASH_SHIFT		5
-#define VTOB_HASH_SIZE		(1UL << VTOB_HASH_SHIFT)
-#define VTOB_HASH_MASK		(VTOB_HASH_SIZE-1)
-#define VTOB_HASH_CODE(m)	\
-	((((m_addr_t) (m)) >> MEMO_CLUSTER_SHIFT) & VTOB_HASH_MASK)
-
-typedef struct m_pool {		/* Memory pool of a given kind */
-	m_bush_t bush;
-	m_addr_t (*getp)(struct m_pool *);
-	void (*freep)(struct m_pool *, m_addr_t);
-	int nump;
-	m_vtob_s *(vtob[VTOB_HASH_SIZE]);
-	struct m_pool *next;
-	struct m_link h[PAGE_SHIFT-MEMO_SHIFT+MEMO_PAGE_ORDER+1];
-} m_pool_s;
-
-static void *___m_alloc(m_pool_s *mp, int size)
-{
-	int i = 0;
-	int s = (1 << MEMO_SHIFT);
-	int j;
-	m_addr_t a;
-	m_link_s *h = mp->h;
-
-	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
-		return NULL;
-
-	while (size > s) {
-		s <<= 1;
-		++i;
-	}
-
-	j = i;
-	while (!h[j].next) {
-		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
-			h[j].next = (m_link_s *)mp->getp(mp);
-			if (h[j].next)
-				h[j].next->next = NULL;
-			break;
-		}
-		++j;
-		s <<= 1;
-	}
-	a = (m_addr_t) h[j].next;
-	if (a) {
-		h[j].next = h[j].next->next;
-		while (j > i) {
-			j -= 1;
-			s >>= 1;
-			h[j].next = (m_link_s *) (a+s);
-			h[j].next->next = NULL;
-		}
-	}
-#ifdef DEBUG
-	printk("___m_alloc(%d) = %p\n", size, (void *) a);
-#endif
-	return (void *) a;
-}
-
-static void ___m_free(m_pool_s *mp, void *ptr, int size)
-{
-	int i = 0;
-	int s = (1 << MEMO_SHIFT);
-	m_link_s *q;
-	m_addr_t a, b;
-	m_link_s *h = mp->h;
-
-#ifdef DEBUG
-	printk("___m_free(%p, %d)\n", ptr, size);
-#endif
-
-	if (size > (PAGE_SIZE << MEMO_PAGE_ORDER))
-		return;
-
-	while (size > s) {
-		s <<= 1;
-		++i;
-	}
-
-	a = (m_addr_t) ptr;
-
-	while (1) {
-#ifdef MEMO_FREE_UNUSED
-		if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) {
-			mp->freep(mp, a);
-			break;
-		}
-#endif
-		b = a ^ s;
-		q = &h[i];
-		while (q->next && q->next != (m_link_s *) b) {
-			q = q->next;
-		}
-		if (!q->next) {
-			((m_link_s *) a)->next = h[i].next;
-			h[i].next = (m_link_s *) a;
-			break;
-		}
-		q->next = q->next->next;
-		a = a & b;
-		s <<= 1;
-		++i;
-	}
-}
-
-static DEFINE_SPINLOCK(ncr53c8xx_lock);
-
-static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags)
-{
-	void *p;
-
-	p = ___m_alloc(mp, size);
-
-	if (DEBUG_FLAGS & DEBUG_ALLOC)
-		printk ("new %-10s[%4d] @%p.\n", name, size, p);
-
-	if (p)
-		memset(p, 0, size);
-	else if (uflags & MEMO_WARN)
-		printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size);
-
-	return p;
-}
-
-#define __m_calloc(mp, s, n)	__m_calloc2(mp, s, n, MEMO_WARN)
-
-static void __m_free(m_pool_s *mp, void *ptr, int size, char *name)
-{
-	if (DEBUG_FLAGS & DEBUG_ALLOC)
-		printk ("freeing %-10s[%4d] @%p.\n", name, size, ptr);
-
-	___m_free(mp, ptr, size);
-
-}
-
-/*
- * With pci bus iommu support, we use a default pool of unmapped memory 
- * for memory we donnot need to DMA from/to and one pool per pcidev for 
- * memory accessed by the PCI chip. `mp0' is the default not DMAable pool.
- */
-
-static m_addr_t ___mp0_getp(m_pool_s *mp)
-{
-	m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER);
-	if (m)
-		++mp->nump;
-	return m;
-}
-
-static void ___mp0_freep(m_pool_s *mp, m_addr_t m)
-{
-	free_pages(m, MEMO_PAGE_ORDER);
-	--mp->nump;
-}
-
-static m_pool_s mp0 = {NULL, ___mp0_getp, ___mp0_freep};
-
-/*
- * DMAable pools.
- */
-
-/*
- * With pci bus iommu support, we maintain one pool per pcidev and a 
- * hashed reverse table for virtual to bus physical address translations.
- */
-static m_addr_t ___dma_getp(m_pool_s *mp)
-{
-	m_addr_t vp;
-	m_vtob_s *vbp;
-
-	vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");
-	if (vbp) {
-		dma_addr_t daddr;
-		vp = (m_addr_t) dma_alloc_coherent(mp->bush,
-						PAGE_SIZE<<MEMO_PAGE_ORDER,
-						&daddr, GFP_ATOMIC);
-		if (vp) {
-			int hc = VTOB_HASH_CODE(vp);
-			vbp->vaddr = vp;
-			vbp->baddr = daddr;
-			vbp->next = mp->vtob[hc];
-			mp->vtob[hc] = vbp;
-			++mp->nump;
-			return vp;
-		}
-	}
-	if (vbp)
-		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
-	return 0;
-}
-
-static void ___dma_freep(m_pool_s *mp, m_addr_t m)
-{
-	m_vtob_s **vbpp, *vbp;
-	int hc = VTOB_HASH_CODE(m);
-
-	vbpp = &mp->vtob[hc];
-	while (*vbpp && (*vbpp)->vaddr != m)
-		vbpp = &(*vbpp)->next;
-	if (*vbpp) {
-		vbp = *vbpp;
-		*vbpp = (*vbpp)->next;
-		dma_free_coherent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,
-				  (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);
-		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");
-		--mp->nump;
-	}
-}
-
-static inline m_pool_s *___get_dma_pool(m_bush_t bush)
-{
-	m_pool_s *mp;
-	for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);
-	return mp;
-}
-
-static m_pool_s *___cre_dma_pool(m_bush_t bush)
-{
-	m_pool_s *mp;
-	mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");
-	if (mp) {
-		memset(mp, 0, sizeof(*mp));
-		mp->bush = bush;
-		mp->getp = ___dma_getp;
-		mp->freep = ___dma_freep;
-		mp->next = mp0.next;
-		mp0.next = mp;
-	}
-	return mp;
-}
-
-static void ___del_dma_pool(m_pool_s *p)
-{
-	struct m_pool **pp = &mp0.next;
-
-	while (*pp && *pp != p)
-		pp = &(*pp)->next;
-	if (*pp) {
-		*pp = (*pp)->next;
-		__m_free(&mp0, p, sizeof(*p), "MPOOL");
-	}
-}
-
-static void *__m_calloc_dma(m_bush_t bush, int size, char *name)
-{
-	u_long flags;
-	struct m_pool *mp;
-	void *m = NULL;
-
-	spin_lock_irqsave(&ncr53c8xx_lock, flags);
-	mp = ___get_dma_pool(bush);
-	if (!mp)
-		mp = ___cre_dma_pool(bush);
-	if (mp)
-		m = __m_calloc(mp, size, name);
-	if (mp && !mp->nump)
-		___del_dma_pool(mp);
-	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
-
-	return m;
-}
-
-static void __m_free_dma(m_bush_t bush, void *m, int size, char *name)
-{
-	u_long flags;
-	struct m_pool *mp;
-
-	spin_lock_irqsave(&ncr53c8xx_lock, flags);
-	mp = ___get_dma_pool(bush);
-	if (mp)
-		__m_free(mp, m, size, name);
-	if (mp && !mp->nump)
-		___del_dma_pool(mp);
-	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
-}
-
-static m_addr_t __vtobus(m_bush_t bush, void *m)
-{
-	u_long flags;
-	m_pool_s *mp;
-	int hc = VTOB_HASH_CODE(m);
-	m_vtob_s *vp = NULL;
-	m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;
-
-	spin_lock_irqsave(&ncr53c8xx_lock, flags);
-	mp = ___get_dma_pool(bush);
-	if (mp) {
-		vp = mp->vtob[hc];
-		while (vp && (m_addr_t) vp->vaddr != a)
-			vp = vp->next;
-	}
-	spin_unlock_irqrestore(&ncr53c8xx_lock, flags);
-	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;
-}
-
-#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->dev, s, n)
-#define _m_free_dma(np, p, s, n)	__m_free_dma(np->dev, p, s, n)
-#define m_calloc_dma(s, n)		_m_calloc_dma(np, s, n)
-#define m_free_dma(p, s, n)		_m_free_dma(np, p, s, n)
-#define _vtobus(np, p)			__vtobus(np->dev, p)
-#define vtobus(p)			_vtobus(np, p)
-
-/*
- *  Deal with DMA mapping/unmapping.
- */
-
-/* To keep track of the dma mapping (sg/single) that has been set */
-#define __data_mapped	SCp.phase
-#define __data_mapping	SCp.have_data_in
-
-static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd)
-{
-	switch(cmd->__data_mapped) {
-	case 2:
-		dma_unmap_sg(dev, cmd->buffer, cmd->use_sg,
-				cmd->sc_data_direction);
-		break;
-	case 1:
-		dma_unmap_single(dev, cmd->__data_mapping,
-				 cmd->request_bufflen,
-				 cmd->sc_data_direction);
-		break;
-	}
-	cmd->__data_mapped = 0;
-}
-
-static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd)
-{
-	dma_addr_t mapping;
-
-	if (cmd->request_bufflen == 0)
-		return 0;
-
-	mapping = dma_map_single(dev, cmd->request_buffer,
-				 cmd->request_bufflen,
-				 cmd->sc_data_direction);
-	cmd->__data_mapped = 1;
-	cmd->__data_mapping = mapping;
-
-	return mapping;
-}
-
-static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd)
-{
-	int use_sg;
-
-	if (cmd->use_sg == 0)
-		return 0;
-
-	use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg,
-			cmd->sc_data_direction);
-	cmd->__data_mapped = 2;
-	cmd->__data_mapping = use_sg;
-
-	return use_sg;
-}
-
-#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->dev, cmd)
-#define map_scsi_single_data(np, cmd)	__map_scsi_single_data(np->dev, cmd)
-#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->dev, cmd)
-
-/*==========================================================
-**
-**	Driver setup.
-**
-**	This structure is initialized from linux config 
-**	options. It can be overridden at boot-up by the boot 
-**	command line.
-**
-**==========================================================
-*/
-static struct ncr_driver_setup
-	driver_setup			= SCSI_NCR_DRIVER_SETUP;
-
-#ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
-static struct ncr_driver_setup
-	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;
-#endif
-
-#define initverbose (driver_setup.verbose)
-#define bootverbose (np->verbose)
-
-
-/*===================================================================
-**
-**	Driver setup from the boot command line
-**
-**===================================================================
-*/
-
-#ifdef MODULE
-#define	ARG_SEP	' '
-#else
-#define	ARG_SEP	','
-#endif
-
-#define OPT_TAGS		1
-#define OPT_MASTER_PARITY	2
-#define OPT_SCSI_PARITY		3
-#define OPT_DISCONNECTION	4
-#define OPT_SPECIAL_FEATURES	5
-#define OPT_UNUSED_1		6
-#define OPT_FORCE_SYNC_NEGO	7
-#define OPT_REVERSE_PROBE	8
-#define OPT_DEFAULT_SYNC	9
-#define OPT_VERBOSE		10
-#define OPT_DEBUG		11
-#define OPT_BURST_MAX		12
-#define OPT_LED_PIN		13
-#define OPT_MAX_WIDE		14
-#define OPT_SETTLE_DELAY	15
-#define OPT_DIFF_SUPPORT	16
-#define OPT_IRQM		17
-#define OPT_PCI_FIX_UP		18
-#define OPT_BUS_CHECK		19
-#define OPT_OPTIMIZE		20
-#define OPT_RECOVERY		21
-#define OPT_SAFE_SETUP		22
-#define OPT_USE_NVRAM		23
-#define OPT_EXCLUDE		24
-#define OPT_HOST_ID		25
-
-#ifdef SCSI_NCR_IARB_SUPPORT
-#define OPT_IARB		26
-#endif
-
-static char setup_token[] __initdata = 
-	"tags:"   "mpar:"
-	"spar:"   "disc:"
-	"specf:"  "ultra:"
-	"fsn:"    "revprob:"
-	"sync:"   "verb:"
-	"debug:"  "burst:"
-	"led:"    "wide:"
-	"settle:" "diff:"
-	"irqm:"   "pcifix:"
-	"buschk:" "optim:"
-	"recovery:"
-	"safe:"   "nvram:"
-	"excl:"   "hostid:"
-#ifdef SCSI_NCR_IARB_SUPPORT
-	"iarb:"
-#endif
-	;	/* DONNOT REMOVE THIS ';' */
-
-#ifdef MODULE
-#define	ARG_SEP	' '
-#else
-#define	ARG_SEP	','
-#endif
-
-static int __init get_setup_token(char *p)
-{
-	char *cur = setup_token;
-	char *pc;
-	int i = 0;
-
-	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
-		++pc;
-		++i;
-		if (!strncmp(p, cur, pc - cur))
-			return i;
-		cur = pc;
-	}
-	return 0;
-}
-
-
-static int __init sym53c8xx__setup(char *str)
-{
-#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
-	char *cur = str;
-	char *pc, *pv;
-	int i, val, c;
-	int xi = 0;
-
-	while (cur != NULL && (pc = strchr(cur, ':')) != NULL) {
-		char *pe;
-
-		val = 0;
-		pv = pc;
-		c = *++pv;
-
-		if	(c == 'n')
-			val = 0;
-		else if	(c == 'y')
-			val = 1;
-		else
-			val = (int) simple_strtoul(pv, &pe, 0);
-
-		switch (get_setup_token(cur)) {
-		case OPT_TAGS:
-			driver_setup.default_tags = val;
-			if (pe && *pe == '/') {
-				i = 0;
-				while (*pe && *pe != ARG_SEP && 
-					i < sizeof(driver_setup.tag_ctrl)-1) {
-					driver_setup.tag_ctrl[i++] = *pe++;
-				}
-				driver_setup.tag_ctrl[i] = '\0';
-			}
-			break;
-		case OPT_MASTER_PARITY:
-			driver_setup.master_parity = val;
-			break;
-		case OPT_SCSI_PARITY:
-			driver_setup.scsi_parity = val;
-			break;
-		case OPT_DISCONNECTION:
-			driver_setup.disconnection = val;
-			break;
-		case OPT_SPECIAL_FEATURES:
-			driver_setup.special_features = val;
-			break;
-		case OPT_FORCE_SYNC_NEGO:
-			driver_setup.force_sync_nego = val;
-			break;
-		case OPT_REVERSE_PROBE:
-			driver_setup.reverse_probe = val;
-			break;
-		case OPT_DEFAULT_SYNC:
-			driver_setup.default_sync = val;
-			break;
-		case OPT_VERBOSE:
-			driver_setup.verbose = val;
-			break;
-		case OPT_DEBUG:
-			driver_setup.debug = val;
-			break;
-		case OPT_BURST_MAX:
-			driver_setup.burst_max = val;
-			break;
-		case OPT_LED_PIN:
-			driver_setup.led_pin = val;
-			break;
-		case OPT_MAX_WIDE:
-			driver_setup.max_wide = val? 1:0;
-			break;
-		case OPT_SETTLE_DELAY:
-			driver_setup.settle_delay = val;
-			break;
-		case OPT_DIFF_SUPPORT:
-			driver_setup.diff_support = val;
-			break;
-		case OPT_IRQM:
-			driver_setup.irqm = val;
-			break;
-		case OPT_PCI_FIX_UP:
-			driver_setup.pci_fix_up	= val;
-			break;
-		case OPT_BUS_CHECK:
-			driver_setup.bus_check = val;
-			break;
-		case OPT_OPTIMIZE:
-			driver_setup.optimize = val;
-			break;
-		case OPT_RECOVERY:
-			driver_setup.recovery = val;
-			break;
-		case OPT_USE_NVRAM:
-			driver_setup.use_nvram = val;
-			break;
-		case OPT_SAFE_SETUP:
-			memcpy(&driver_setup, &driver_safe_setup,
-				sizeof(driver_setup));
-			break;
-		case OPT_EXCLUDE:
-			if (xi < SCSI_NCR_MAX_EXCLUDES)
-				driver_setup.excludes[xi++] = val;
-			break;
-		case OPT_HOST_ID:
-			driver_setup.host_id = val;
-			break;
-#ifdef SCSI_NCR_IARB_SUPPORT
-		case OPT_IARB:
-			driver_setup.iarb = val;
-			break;
-#endif
-		default:
-			printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur);
-			break;
-		}
-
-		if ((cur = strchr(cur, ARG_SEP)) != NULL)
-			++cur;
-	}
-#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */
-	return 1;
-}
-
-/*===================================================================
-**
-**	Get device queue depth from boot command line.
-**
-**===================================================================
-*/
-#define DEF_DEPTH	(driver_setup.default_tags)
-#define ALL_TARGETS	-2
-#define NO_TARGET	-1
-#define ALL_LUNS	-2
-#define NO_LUN		-1
-
-static int device_queue_depth(int unit, int target, int lun)
-{
-	int c, h, t, u, v;
-	char *p = driver_setup.tag_ctrl;
-	char *ep;
-
-	h = -1;
-	t = NO_TARGET;
-	u = NO_LUN;
-	while ((c = *p++) != 0) {
-		v = simple_strtoul(p, &ep, 0);
-		switch(c) {
-		case '/':
-			++h;
-			t = ALL_TARGETS;
-			u = ALL_LUNS;
-			break;
-		case 't':
-			if (t != target)
-				t = (target == v) ? v : NO_TARGET;
-			u = ALL_LUNS;
-			break;
-		case 'u':
-			if (u != lun)
-				u = (lun == v) ? v : NO_LUN;
-			break;
-		case 'q':
-			if (h == unit &&
-				(t == ALL_TARGETS || t == target) &&
-				(u == ALL_LUNS    || u == lun))
-				return v;
-			break;
-		case '-':
-			t = ALL_TARGETS;
-			u = ALL_LUNS;
-			break;
-		default:
-			break;
-		}
-		p = ep;
-	}
-	return DEF_DEPTH;
-}
diff --git a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h
deleted file mode 100644
index 139cd0e..0000000
--- a/drivers/scsi/sym53c8xx_defs.h
+++ /dev/null
@@ -1,1320 +0,0 @@
-/******************************************************************************
-**  High Performance device driver for the Symbios 53C896 controller.
-**
-**  Copyright (C) 1998-2001  Gerard Roudier <groudier@free.fr>
-**
-**  This driver also supports all the Symbios 53C8XX controller family, 
-**  except 53C810 revisions < 16, 53C825 revisions < 16 and all 
-**  revisions of 53C815 controllers.
-**
-**  This driver is based on the Linux port of the FreeBSD ncr driver.
-** 
-**  Copyright (C) 1994  Wolfgang Stanglmeier
-**  
-**-----------------------------------------------------------------------------
-**  
-**  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.
-**
-**-----------------------------------------------------------------------------
-**
-**  The Linux port of the FreeBSD ncr driver has been achieved in 
-**  november 1995 by:
-**
-**          Gerard Roudier              <groudier@free.fr>
-**
-**  Being given that this driver originates from the FreeBSD version, and
-**  in order to keep synergy on both, any suggested enhancements and corrections
-**  received on Linux are automatically a potential candidate for the FreeBSD 
-**  version.
-**
-**  The original driver has been written for 386bsd and FreeBSD by
-**          Wolfgang Stanglmeier        <wolf@cologne.de>
-**          Stefan Esser                <se@mi.Uni-Koeln.de>
-**
-**-----------------------------------------------------------------------------
-**
-**  Major contributions:
-**  --------------------
-**
-**  NVRAM detection and reading.
-**    Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>
-**
-**  Added support for MIPS big endian systems.
-**    Carsten Langgaard, carstenl@mips.com
-**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-**
-**  Added support for HP PARISC big endian systems.
-**    Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
-**
-*******************************************************************************
-*/
-
-#ifndef SYM53C8XX_DEFS_H
-#define SYM53C8XX_DEFS_H
-
-#include <linux/config.h>
-
-/*
-**	If you want a driver as small as possible, donnot define the 
-**	following options.
-*/
-#define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT
-#define SCSI_NCR_DEBUG_INFO_SUPPORT
-
-/*
-**	To disable integrity checking, do not define the 
-**	following option.
-*/
-#ifdef	CONFIG_SCSI_NCR53C8XX_INTEGRITY_CHECK
-#	define SCSI_NCR_ENABLE_INTEGRITY_CHECK
-#endif
-
-/* ---------------------------------------------------------------------
-** Take into account kernel configured parameters.
-** Most of these options can be overridden at startup by a command line.
-** ---------------------------------------------------------------------
-*/
-
-/*
- * For Ultra2 and Ultra3 SCSI support option, use special features. 
- *
- * Value (default) means:
- *	bit 0 : all features enabled, except:
- *		bit 1 : PCI Write And Invalidate.
- *		bit 2 : Data Phase Mismatch handling from SCRIPTS.
- *
- * Use boot options ncr53c8xx=specf:1 if you want all chip features to be 
- * enabled by the driver.
- */
-#define	SCSI_NCR_SETUP_SPECIAL_FEATURES		(3)
-
-#define SCSI_NCR_MAX_SYNC			(80)
-
-/*
- * Allow tags from 2 to 256, default 8
- */
-#ifdef	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
-#if	CONFIG_SCSI_NCR53C8XX_MAX_TAGS < 2
-#define SCSI_NCR_MAX_TAGS	(2)
-#elif	CONFIG_SCSI_NCR53C8XX_MAX_TAGS > 256
-#define SCSI_NCR_MAX_TAGS	(256)
-#else
-#define	SCSI_NCR_MAX_TAGS	CONFIG_SCSI_NCR53C8XX_MAX_TAGS
-#endif
-#else
-#define SCSI_NCR_MAX_TAGS	(8)
-#endif
-
-/*
- * Allow tagged command queuing support if configured with default number 
- * of tags set to max (see above).
- */
-#ifdef	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
-#define	SCSI_NCR_SETUP_DEFAULT_TAGS	CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS
-#elif	defined CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE
-#define	SCSI_NCR_SETUP_DEFAULT_TAGS	SCSI_NCR_MAX_TAGS
-#else
-#define	SCSI_NCR_SETUP_DEFAULT_TAGS	(0)
-#endif
-
-/*
- * Immediate arbitration
- */
-#if defined(CONFIG_SCSI_NCR53C8XX_IARB)
-#define SCSI_NCR_IARB_SUPPORT
-#endif
-
-/*
- * Sync transfer frequency at startup.
- * Allow from 5Mhz to 80Mhz default 20 Mhz.
- */
-#ifndef	CONFIG_SCSI_NCR53C8XX_SYNC
-#define	CONFIG_SCSI_NCR53C8XX_SYNC	(20)
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC > SCSI_NCR_MAX_SYNC
-#undef	CONFIG_SCSI_NCR53C8XX_SYNC
-#define	CONFIG_SCSI_NCR53C8XX_SYNC	SCSI_NCR_MAX_SYNC
-#endif
-
-#if	CONFIG_SCSI_NCR53C8XX_SYNC == 0
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(255)
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 5
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(50)
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 20
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(250/(CONFIG_SCSI_NCR53C8XX_SYNC))
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 33
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(11)
-#elif	CONFIG_SCSI_NCR53C8XX_SYNC <= 40
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC	(10)
-#else
-#define	SCSI_NCR_SETUP_DEFAULT_SYNC 	(9)
-#endif
-
-/*
- * Disallow disconnections at boot-up
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
-#define SCSI_NCR_SETUP_DISCONNECTION	(0)
-#else
-#define SCSI_NCR_SETUP_DISCONNECTION	(1)
-#endif
-
-/*
- * Force synchronous negotiation for all targets
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO
-#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(1)
-#else
-#define SCSI_NCR_SETUP_FORCE_SYNC_NEGO	(0)
-#endif
-
-/*
- * Disable master parity checking (flawed hardwares need that)
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK
-#define SCSI_NCR_SETUP_MASTER_PARITY	(0)
-#else
-#define SCSI_NCR_SETUP_MASTER_PARITY	(1)
-#endif
-
-/*
- * Disable scsi parity checking (flawed devices may need that)
- */
-#ifdef CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK
-#define SCSI_NCR_SETUP_SCSI_PARITY	(0)
-#else
-#define SCSI_NCR_SETUP_SCSI_PARITY	(1)
-#endif
-
-/*
- * Settle time after reset at boot-up
- */
-#define SCSI_NCR_SETUP_SETTLE_TIME	(2)
-
-/*
-**	Bridge quirks work-around option defaulted to 1.
-*/
-#ifndef	SCSI_NCR_PCIQ_WORK_AROUND_OPT
-#define	SCSI_NCR_PCIQ_WORK_AROUND_OPT	1
-#endif
-
-/*
-**	Work-around common bridge misbehaviour.
-**
-**	- Do not flush posted writes in the opposite 
-**	  direction on read.
-**	- May reorder DMA writes to memory.
-**
-**	This option should not affect performances 
-**	significantly, so it is the default.
-*/
-#if	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 1
-#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
-#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
-#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
-
-/*
-**	Same as option 1, but also deal with 
-**	misconfigured interrupts.
-**
-**	- Edge triggerred instead of level sensitive.
-**	- No interrupt line connected.
-**	- IRQ number misconfigured.
-**	
-**	If no interrupt is delivered, the driver will 
-**	catch the interrupt conditions 10 times per 
-**	second. No need to say that this option is 
-**	not recommended.
-*/
-#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 2
-#define	SCSI_NCR_PCIQ_MAY_NOT_FLUSH_PW_UPSTREAM
-#define	SCSI_NCR_PCIQ_MAY_REORDER_WRITES
-#define	SCSI_NCR_PCIQ_MAY_MISS_COMPLETIONS
-#define	SCSI_NCR_PCIQ_BROKEN_INTR
-
-/*
-**	Some bridge designers decided to flush 
-**	everything prior to deliver the interrupt.
-**	This option tries to deal with such a 
-**	behaviour.
-*/
-#elif	SCSI_NCR_PCIQ_WORK_AROUND_OPT == 3
-#define	SCSI_NCR_PCIQ_SYNC_ON_INTR
-#endif
-
-/*
-**	Other parameters not configurable with "make config"
-**	Avoid to change these constants, unless you know what you are doing.
-*/
-
-#define SCSI_NCR_ALWAYS_SIMPLE_TAG
-#define SCSI_NCR_MAX_SCATTER	(127)
-#define SCSI_NCR_MAX_TARGET	(16)
-
-/*
-**   Compute some desirable value for CAN_QUEUE 
-**   and CMD_PER_LUN.
-**   The driver will use lower values if these 
-**   ones appear to be too large.
-*/
-#define SCSI_NCR_CAN_QUEUE	(8*SCSI_NCR_MAX_TAGS + 2*SCSI_NCR_MAX_TARGET)
-#define SCSI_NCR_CMD_PER_LUN	(SCSI_NCR_MAX_TAGS)
-
-#define SCSI_NCR_SG_TABLESIZE	(SCSI_NCR_MAX_SCATTER)
-#define SCSI_NCR_TIMER_INTERVAL	(HZ)
-
-#if 1 /* defined CONFIG_SCSI_MULTI_LUN */
-#define SCSI_NCR_MAX_LUN	(16)
-#else
-#define SCSI_NCR_MAX_LUN	(1)
-#endif
-
-/*
- *  IO functions definition for big/little endian CPU support.
- *  For now, the NCR is only supported in little endian addressing mode, 
- */
-
-#ifdef	__BIG_ENDIAN
-
-#define	inw_l2b		inw
-#define	inl_l2b		inl
-#define	outw_b2l	outw
-#define	outl_b2l	outl
-
-#define	readb_raw	readb
-#define	writeb_raw	writeb
-
-#if defined(SCSI_NCR_BIG_ENDIAN)
-#define	readw_l2b	__raw_readw
-#define	readl_l2b	__raw_readl
-#define	writew_b2l	__raw_writew
-#define	writel_b2l	__raw_writel
-#define	readw_raw	__raw_readw
-#define	readl_raw	__raw_readl
-#define	writew_raw	__raw_writew
-#define	writel_raw	__raw_writel
-#else	/* Other big-endian */
-#define	readw_l2b	readw
-#define	readl_l2b	readl
-#define	writew_b2l	writew
-#define	writel_b2l	writel
-#define	readw_raw	readw
-#define	readl_raw	readl
-#define	writew_raw	writew
-#define	writel_raw	writel
-#endif
-
-#else	/* little endian */
-
-#define	inw_raw		inw
-#define	inl_raw		inl
-#define	outw_raw	outw
-#define	outl_raw	outl
-
-#define	readb_raw	readb
-#define	readw_raw	readw
-#define	readl_raw	readl
-#define	writeb_raw	writeb
-#define	writew_raw	writew
-#define	writel_raw	writel
-
-#endif
-
-#if !defined(__hppa__) && !defined(__mips__)
-#ifdef	SCSI_NCR_BIG_ENDIAN
-#error	"The NCR in BIG ENDIAN addressing mode is not (yet) supported"
-#endif
-#endif
-
-#define MEMORY_BARRIER()	mb()
-
-
-/*
- *  If the NCR uses big endian addressing mode over the 
- *  PCI, actual io register addresses for byte and word 
- *  accesses must be changed according to lane routing.
- *  Btw, ncr_offb() and ncr_offw() macros only apply to 
- *  constants and so donnot generate bloated code.
- */
-
-#if	defined(SCSI_NCR_BIG_ENDIAN)
-
-#define ncr_offb(o)	(((o)&~3)+((~((o)&3))&3))
-#define ncr_offw(o)	(((o)&~3)+((~((o)&3))&2))
-
-#else
-
-#define ncr_offb(o)	(o)
-#define ncr_offw(o)	(o)
-
-#endif
-
-/*
- *  If the CPU and the NCR use same endian-ness addressing,
- *  no byte reordering is needed for script patching.
- *  Macro cpu_to_scr() is to be used for script patching.
- *  Macro scr_to_cpu() is to be used for getting a DWORD 
- *  from the script.
- */
-
-#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
-
-#define cpu_to_scr(dw)	cpu_to_le32(dw)
-#define scr_to_cpu(dw)	le32_to_cpu(dw)
-
-#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
-
-#define cpu_to_scr(dw)	cpu_to_be32(dw)
-#define scr_to_cpu(dw)	be32_to_cpu(dw)
-
-#else
-
-#define cpu_to_scr(dw)	(dw)
-#define scr_to_cpu(dw)	(dw)
-
-#endif
-
-/*
- *  Access to the controller chip.
- *
- *  If the CPU and the NCR use same endian-ness addressing,
- *  no byte reordering is needed for accessing chip io 
- *  registers. Functions suffixed by '_raw' are assumed 
- *  to access the chip over the PCI without doing byte 
- *  reordering. Functions suffixed by '_l2b' are 
- *  assumed to perform little-endian to big-endian byte 
- *  reordering, those suffixed by '_b2l' blah, blah,
- *  blah, ...
- */
-
-/*
- *  MEMORY mapped IO input / output
- */
-
-#define INB_OFF(o)		readb_raw((char __iomem *)np->reg + ncr_offb(o))
-#define OUTB_OFF(o, val)	writeb_raw((val), (char __iomem *)np->reg + ncr_offb(o))
-
-#if	defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)
-
-#define INW_OFF(o)		readw_l2b((char __iomem *)np->reg + ncr_offw(o))
-#define INL_OFF(o)		readl_l2b((char __iomem *)np->reg + (o))
-
-#define OUTW_OFF(o, val)	writew_b2l((val), (char __iomem *)np->reg + ncr_offw(o))
-#define OUTL_OFF(o, val)	writel_b2l((val), (char __iomem *)np->reg + (o))
-
-#elif	defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)
-
-#define INW_OFF(o)		readw_b2l((char __iomem *)np->reg + ncr_offw(o))
-#define INL_OFF(o)		readl_b2l((char __iomem *)np->reg + (o))
-
-#define OUTW_OFF(o, val)	writew_l2b((val), (char __iomem *)np->reg + ncr_offw(o))
-#define OUTL_OFF(o, val)	writel_l2b((val), (char __iomem *)np->reg + (o))
-
-#else
-
-#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
-/* Only 8 or 32 bit transfers allowed */
-#define INW_OFF(o)		(readb((char __iomem *)np->reg + ncr_offw(o)) << 8 | readb((char __iomem *)np->reg + ncr_offw(o) + 1))
-#else
-#define INW_OFF(o)		readw_raw((char __iomem *)np->reg + ncr_offw(o))
-#endif
-#define INL_OFF(o)		readl_raw((char __iomem *)np->reg + (o))
-
-#ifdef CONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS
-/* Only 8 or 32 bit transfers allowed */
-#define OUTW_OFF(o, val)	do { writeb((char)((val) >> 8), (char __iomem *)np->reg + ncr_offw(o)); writeb((char)(val), (char __iomem *)np->reg + ncr_offw(o) + 1); } while (0)
-#else
-#define OUTW_OFF(o, val)	writew_raw((val), (char __iomem *)np->reg + ncr_offw(o))
-#endif
-#define OUTL_OFF(o, val)	writel_raw((val), (char __iomem *)np->reg + (o))
-
-#endif
-
-#define INB(r)		INB_OFF (offsetof(struct ncr_reg,r))
-#define INW(r)		INW_OFF (offsetof(struct ncr_reg,r))
-#define INL(r)		INL_OFF (offsetof(struct ncr_reg,r))
-
-#define OUTB(r, val)	OUTB_OFF (offsetof(struct ncr_reg,r), (val))
-#define OUTW(r, val)	OUTW_OFF (offsetof(struct ncr_reg,r), (val))
-#define OUTL(r, val)	OUTL_OFF (offsetof(struct ncr_reg,r), (val))
-
-/*
- *  Set bit field ON, OFF 
- */
-
-#define OUTONB(r, m)	OUTB(r, INB(r) | (m))
-#define OUTOFFB(r, m)	OUTB(r, INB(r) & ~(m))
-#define OUTONW(r, m)	OUTW(r, INW(r) | (m))
-#define OUTOFFW(r, m)	OUTW(r, INW(r) & ~(m))
-#define OUTONL(r, m)	OUTL(r, INL(r) | (m))
-#define OUTOFFL(r, m)	OUTL(r, INL(r) & ~(m))
-
-/*
- *  We normally want the chip to have a consistent view
- *  of driver internal data structures when we restart it.
- *  Thus these macros.
- */
-#define OUTL_DSP(v)				\
-	do {					\
-		MEMORY_BARRIER();		\
-		OUTL (nc_dsp, (v));		\
-	} while (0)
-
-#define OUTONB_STD()				\
-	do {					\
-		MEMORY_BARRIER();		\
-		OUTONB (nc_dcntl, (STD|NOCOM));	\
-	} while (0)
-
-
-/*
-**   NCR53C8XX devices features table.
-*/
-struct ncr_chip {
-	unsigned short	revision_id;
-	unsigned char	burst_max;	/* log-base-2 of max burst */
-	unsigned char	offset_max;
-	unsigned char	nr_divisor;
-	unsigned int	features;
-#define FE_LED0		(1<<0)
-#define FE_WIDE		(1<<1)    /* Wide data transfers */
-#define FE_ULTRA	(1<<2)	  /* Ultra speed 20Mtrans/sec */
-#define FE_DBLR		(1<<4)	  /* Clock doubler present */
-#define FE_QUAD		(1<<5)	  /* Clock quadrupler present */
-#define FE_ERL		(1<<6)    /* Enable read line */
-#define FE_CLSE		(1<<7)    /* Cache line size enable */
-#define FE_WRIE		(1<<8)    /* Write & Invalidate enable */
-#define FE_ERMP		(1<<9)    /* Enable read multiple */
-#define FE_BOF		(1<<10)   /* Burst opcode fetch */
-#define FE_DFS		(1<<11)   /* DMA fifo size */
-#define FE_PFEN		(1<<12)   /* Prefetch enable */
-#define FE_LDSTR	(1<<13)   /* Load/Store supported */
-#define FE_RAM		(1<<14)   /* On chip RAM present */
-#define FE_VARCLK	(1<<15)   /* SCSI clock may vary */
-#define FE_RAM8K	(1<<16)   /* On chip RAM sized 8Kb */
-#define FE_64BIT	(1<<17)   /* Have a 64-bit PCI interface */
-#define FE_IO256	(1<<18)   /* Requires full 256 bytes in PCI space */
-#define FE_NOPM		(1<<19)   /* Scripts handles phase mismatch */
-#define FE_LEDC		(1<<20)   /* Hardware control of LED */
-#define FE_DIFF		(1<<21)   /* Support Differential SCSI */
-#define FE_66MHZ 	(1<<23)   /* 66MHz PCI Support */
-#define FE_DAC	 	(1<<24)   /* Support DAC cycles (64 bit addressing) */
-#define FE_ISTAT1 	(1<<25)   /* Have ISTAT1, MBOX0, MBOX1 registers */
-#define FE_DAC_IN_USE	(1<<26)	  /* Platform does DAC cycles */
-#define FE_EHP		(1<<27)   /* 720: Even host parity */
-#define FE_MUX		(1<<28)   /* 720: Multiplexed bus */
-#define FE_EA		(1<<29)   /* 720: Enable Ack */
-
-#define FE_CACHE_SET	(FE_ERL|FE_CLSE|FE_WRIE|FE_ERMP)
-#define FE_SCSI_SET	(FE_WIDE|FE_ULTRA|FE_DBLR|FE_QUAD|F_CLK80)
-#define FE_SPECIAL_SET	(FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM)
-};
-
-
-/*
-**	Driver setup structure.
-**
-**	This structure is initialized from linux config options.
-**	It can be overridden at boot-up by the boot command line.
-*/
-#define SCSI_NCR_MAX_EXCLUDES 8
-struct ncr_driver_setup {
-	u8	master_parity;
-	u8	scsi_parity;
-	u8	disconnection;
-	u8	special_features;
-	u8	force_sync_nego;
-	u8	reverse_probe;
-	u8	pci_fix_up;
-	u8	use_nvram;
-	u8	verbose;
-	u8	default_tags;
-	u16	default_sync;
-	u16	debug;
-	u8	burst_max;
-	u8	led_pin;
-	u8	max_wide;
-	u8	settle_delay;
-	u8	diff_support;
-	u8	irqm;
-	u8	bus_check;
-	u8	optimize;
-	u8	recovery;
-	u8	host_id;
-	u16	iarb;
-	u32	excludes[SCSI_NCR_MAX_EXCLUDES];
-	char	tag_ctrl[100];
-};
-
-/*
-**	Initial setup.
-**	Can be overriden at startup by a command line.
-*/
-#define SCSI_NCR_DRIVER_SETUP			\
-{						\
-	SCSI_NCR_SETUP_MASTER_PARITY,		\
-	SCSI_NCR_SETUP_SCSI_PARITY,		\
-	SCSI_NCR_SETUP_DISCONNECTION,		\
-	SCSI_NCR_SETUP_SPECIAL_FEATURES,	\
-	SCSI_NCR_SETUP_FORCE_SYNC_NEGO,		\
-	0,					\
-	0,					\
-	1,					\
-	0,					\
-	SCSI_NCR_SETUP_DEFAULT_TAGS,		\
-	SCSI_NCR_SETUP_DEFAULT_SYNC,		\
-	0x00,					\
-	7,					\
-	0,					\
-	1,					\
-	SCSI_NCR_SETUP_SETTLE_TIME,		\
-	0,					\
-	0,					\
-	1,					\
-	0,					\
-	0,					\
-	255,					\
-	0x00					\
-}
-
-/*
-**	Boot fail safe setup.
-**	Override initial setup from boot command line:
-**	ncr53c8xx=safe:y
-*/
-#define SCSI_NCR_DRIVER_SAFE_SETUP		\
-{						\
-	0,					\
-	1,					\
-	0,					\
-	0,					\
-	0,					\
-	0,					\
-	0,					\
-	1,					\
-	2,					\
-	0,					\
-	255,					\
-	0x00,					\
-	255,					\
-	0,					\
-	0,					\
-	10,					\
-	1,					\
-	1,					\
-	1,					\
-	0,					\
-	0,					\
-	255					\
-}
-
-/**************** ORIGINAL CONTENT of ncrreg.h from FreeBSD ******************/
-
-/*-----------------------------------------------------------------
-**
-**	The ncr 53c810 register structure.
-**
-**-----------------------------------------------------------------
-*/
-
-struct ncr_reg {
-/*00*/  u8	nc_scntl0;    /* full arb., ena parity, par->ATN  */
-
-/*01*/  u8	nc_scntl1;    /* no reset                         */
-        #define   ISCON   0x10  /* connected to scsi		    */
-        #define   CRST    0x08  /* force reset                      */
-        #define   IARB    0x02  /* immediate arbitration            */
-
-/*02*/  u8	nc_scntl2;    /* no disconnect expected           */
-	#define   SDU     0x80  /* cmd: disconnect will raise error */
-	#define   CHM     0x40  /* sta: chained mode                */
-	#define   WSS     0x08  /* sta: wide scsi send           [W]*/
-	#define   WSR     0x01  /* sta: wide scsi received       [W]*/
-
-/*03*/  u8	nc_scntl3;    /* cnf system clock dependent       */
-	#define   EWS     0x08  /* cmd: enable wide scsi         [W]*/
-	#define   ULTRA   0x80  /* cmd: ULTRA enable                */
-				/* bits 0-2, 7 rsvd for C1010       */
-
-/*04*/  u8	nc_scid;	/* cnf host adapter scsi address    */
-	#define   RRE     0x40  /* r/w:e enable response to resel.  */
-	#define   SRE     0x20  /* r/w:e enable response to select  */
-
-/*05*/  u8	nc_sxfer;	/* ### Sync speed and count         */
-				/* bits 6-7 rsvd for C1010          */
-
-/*06*/  u8	nc_sdid;	/* ### Destination-ID               */
-
-/*07*/  u8	nc_gpreg;	/* ??? IO-Pins                      */
-
-/*08*/  u8	nc_sfbr;	/* ### First byte in phase          */
-
-/*09*/  u8	nc_socl;
-	#define   CREQ	  0x80	/* r/w: SCSI-REQ                    */
-	#define   CACK	  0x40	/* r/w: SCSI-ACK                    */
-	#define   CBSY	  0x20	/* r/w: SCSI-BSY                    */
-	#define   CSEL	  0x10	/* r/w: SCSI-SEL                    */
-	#define   CATN	  0x08	/* r/w: SCSI-ATN                    */
-	#define   CMSG	  0x04	/* r/w: SCSI-MSG                    */
-	#define   CC_D	  0x02	/* r/w: SCSI-C_D                    */
-	#define   CI_O	  0x01	/* r/w: SCSI-I_O                    */
-
-/*0a*/  u8	nc_ssid;
-
-/*0b*/  u8	nc_sbcl;
-
-/*0c*/  u8	nc_dstat;
-        #define   DFE     0x80  /* sta: dma fifo empty              */
-        #define   MDPE    0x40  /* int: master data parity error    */
-        #define   BF      0x20  /* int: script: bus fault           */
-        #define   ABRT    0x10  /* int: script: command aborted     */
-        #define   SSI     0x08  /* int: script: single step         */
-        #define   SIR     0x04  /* int: script: interrupt instruct. */
-        #define   IID     0x01  /* int: script: illegal instruct.   */
-
-/*0d*/  u8	nc_sstat0;
-        #define   ILF     0x80  /* sta: data in SIDL register lsb   */
-        #define   ORF     0x40  /* sta: data in SODR register lsb   */
-        #define   OLF     0x20  /* sta: data in SODL register lsb   */
-        #define   AIP     0x10  /* sta: arbitration in progress     */
-        #define   LOA     0x08  /* sta: arbitration lost            */
-        #define   WOA     0x04  /* sta: arbitration won             */
-        #define   IRST    0x02  /* sta: scsi reset signal           */
-        #define   SDP     0x01  /* sta: scsi parity signal          */
-
-/*0e*/  u8	nc_sstat1;
-	#define   FF3210  0xf0	/* sta: bytes in the scsi fifo      */
-
-/*0f*/  u8	nc_sstat2;
-        #define   ILF1    0x80  /* sta: data in SIDL register msb[W]*/
-        #define   ORF1    0x40  /* sta: data in SODR register msb[W]*/
-        #define   OLF1    0x20  /* sta: data in SODL register msb[W]*/
-        #define   DM      0x04  /* sta: DIFFSENS mismatch (895/6 only) */
-        #define   LDSC    0x02  /* sta: disconnect & reconnect      */
-
-/*10*/  u8	nc_dsa;	/* --> Base page                    */
-/*11*/  u8	nc_dsa1;
-/*12*/  u8	nc_dsa2;
-/*13*/  u8	nc_dsa3;
-
-/*14*/  u8	nc_istat;	/* --> Main Command and status      */
-        #define   CABRT   0x80  /* cmd: abort current operation     */
-        #define   SRST    0x40  /* mod: reset chip                  */
-        #define   SIGP    0x20  /* r/w: message from host to ncr    */
-        #define   SEM     0x10  /* r/w: message between host + ncr  */
-        #define   CON     0x08  /* sta: connected to scsi           */
-        #define   INTF    0x04  /* sta: int on the fly (reset by wr)*/
-        #define   SIP     0x02  /* sta: scsi-interrupt              */
-        #define   DIP     0x01  /* sta: host/script interrupt       */
-
-/*15*/  u8	nc_istat1;	/* 896 and later cores only */
-        #define   FLSH    0x04  /* sta: chip is flushing            */
-        #define   SRUN    0x02  /* sta: scripts are running         */
-        #define   SIRQD   0x01  /* r/w: disable INT pin             */
-
-/*16*/  u8	nc_mbox0;	/* 896 and later cores only */
-/*17*/  u8	nc_mbox1;	/* 896 and later cores only */
-
-/*18*/	u8	nc_ctest0;
-	#define   EHP     0x04	/* 720 even host parity             */
-/*19*/  u8	nc_ctest1;
-
-/*1a*/  u8	nc_ctest2;
-	#define   CSIGP   0x40
-				/* bits 0-2,7 rsvd for C1010        */
-
-/*1b*/  u8	nc_ctest3;
-	#define   FLF     0x08  /* cmd: flush dma fifo              */
-	#define   CLF	  0x04	/* cmd: clear dma fifo		    */
-	#define   FM      0x02  /* mod: fetch pin mode              */
-	#define   WRIE    0x01  /* mod: write and invalidate enable */
-				/* bits 4-7 rsvd for C1010          */
-
-/*1c*/  u32    nc_temp;	/* ### Temporary stack              */
-
-/*20*/	u8	nc_dfifo;
-/*21*/  u8	nc_ctest4;
-	#define   MUX     0x80  /* 720 host bus multiplex mode      */
-	#define   BDIS    0x80  /* mod: burst disable               */
-	#define   MPEE    0x08  /* mod: master parity error enable  */
-
-/*22*/  u8	nc_ctest5;
-	#define   DFS     0x20  /* mod: dma fifo size               */
-				/* bits 0-1, 3-7 rsvd for C1010          */
-/*23*/  u8	nc_ctest6;
-
-/*24*/  u32    nc_dbc;	/* ### Byte count and command       */
-/*28*/  u32    nc_dnad;	/* ### Next command register        */
-/*2c*/  u32    nc_dsp;	/* --> Script Pointer               */
-/*30*/  u32    nc_dsps;	/* --> Script pointer save/opcode#2 */
-
-/*34*/  u8	nc_scratcha;  /* Temporary register a            */
-/*35*/  u8	nc_scratcha1;
-/*36*/  u8	nc_scratcha2;
-/*37*/  u8	nc_scratcha3;
-
-/*38*/  u8	nc_dmode;
-	#define   BL_2    0x80  /* mod: burst length shift value +2 */
-	#define   BL_1    0x40  /* mod: burst length shift value +1 */
-	#define   ERL     0x08  /* mod: enable read line            */
-	#define   ERMP    0x04  /* mod: enable read multiple        */
-	#define   BOF     0x02  /* mod: burst op code fetch         */
-
-/*39*/  u8	nc_dien;
-/*3a*/  u8	nc_sbr;
-
-/*3b*/  u8	nc_dcntl;	/* --> Script execution control     */
-	#define   CLSE    0x80  /* mod: cache line size enable      */
-	#define   PFF     0x40  /* cmd: pre-fetch flush             */
-	#define   PFEN    0x20  /* mod: pre-fetch enable            */
-	#define   EA      0x20  /* mod: 720 enable-ack              */
-	#define   SSM     0x10  /* mod: single step mode            */
-	#define   IRQM    0x08  /* mod: irq mode (1 = totem pole !) */
-	#define   STD     0x04  /* cmd: start dma mode              */
-	#define   IRQD    0x02  /* mod: irq disable                 */
- 	#define	  NOCOM   0x01	/* cmd: protect sfbr while reselect */
-				/* bits 0-1 rsvd for C1010          */
-
-/*3c*/  u32	nc_adder;
-
-/*40*/  u16	nc_sien;	/* -->: interrupt enable            */
-/*42*/  u16	nc_sist;	/* <--: interrupt status            */
-        #define   SBMC    0x1000/* sta: SCSI Bus Mode Change (895/6 only) */
-        #define   STO     0x0400/* sta: timeout (select)            */
-        #define   GEN     0x0200/* sta: timeout (general)           */
-        #define   HTH     0x0100/* sta: timeout (handshake)         */
-        #define   MA      0x80  /* sta: phase mismatch              */
-        #define   CMP     0x40  /* sta: arbitration complete        */
-        #define   SEL     0x20  /* sta: selected by another device  */
-        #define   RSL     0x10  /* sta: reselected by another device*/
-        #define   SGE     0x08  /* sta: gross error (over/underflow)*/
-        #define   UDC     0x04  /* sta: unexpected disconnect       */
-        #define   RST     0x02  /* sta: scsi bus reset detected     */
-        #define   PAR     0x01  /* sta: scsi parity error           */
-
-/*44*/  u8	nc_slpar;
-/*45*/  u8	nc_swide;
-/*46*/  u8	nc_macntl;
-/*47*/  u8	nc_gpcntl;
-/*48*/  u8	nc_stime0;    /* cmd: timeout for select&handshake*/
-/*49*/  u8	nc_stime1;    /* cmd: timeout user defined        */
-/*4a*/  u16   nc_respid;    /* sta: Reselect-IDs                */
-
-/*4c*/  u8	nc_stest0;
-
-/*4d*/  u8	nc_stest1;
-	#define   SCLK    0x80	/* Use the PCI clock as SCSI clock	*/
-	#define   DBLEN   0x08	/* clock doubler running		*/
-	#define   DBLSEL  0x04	/* clock doubler selected		*/
-  
-
-/*4e*/  u8	nc_stest2;
-	#define   ROF     0x40	/* reset scsi offset (after gross error!) */
-	#define   DIF     0x20  /* 720 SCSI differential mode             */
-	#define   EXT     0x02  /* extended filtering                     */
-
-/*4f*/  u8	nc_stest3;
-	#define   TE     0x80	/* c: tolerAnt enable */
-	#define   HSC    0x20	/* c: Halt SCSI Clock */
-	#define   CSF    0x02	/* c: clear scsi fifo */
-
-/*50*/  u16   nc_sidl;	/* Lowlevel: latched from scsi data */
-/*52*/  u8	nc_stest4;
-	#define   SMODE  0xc0	/* SCSI bus mode      (895/6 only) */
-	#define    SMODE_HVD 0x40	/* High Voltage Differential       */
-	#define    SMODE_SE  0x80	/* Single Ended                    */
-	#define    SMODE_LVD 0xc0	/* Low Voltage Differential        */
-	#define   LCKFRQ 0x20	/* Frequency Lock (895/6 only)     */
-				/* bits 0-5 rsvd for C1010          */
-
-/*53*/  u8	nc_53_;
-/*54*/  u16	nc_sodl;	/* Lowlevel: data out to scsi data  */
-/*56*/	u8	nc_ccntl0;	/* Chip Control 0 (896)             */
-	#define   ENPMJ  0x80	/* Enable Phase Mismatch Jump       */
-	#define   PMJCTL 0x40	/* Phase Mismatch Jump Control      */
-	#define   ENNDJ  0x20	/* Enable Non Data PM Jump          */
-	#define   DISFC  0x10	/* Disable Auto FIFO Clear          */
-	#define   DILS   0x02	/* Disable Internal Load/Store      */
-	#define   DPR    0x01	/* Disable Pipe Req                 */
-
-/*57*/	u8	nc_ccntl1;	/* Chip Control 1 (896)             */
-	#define   ZMOD   0x80	/* High Impedance Mode              */
-	#define	  DIC	 0x10	/* Disable Internal Cycles	    */
-	#define   DDAC   0x08	/* Disable Dual Address Cycle       */
-	#define   XTIMOD 0x04	/* 64-bit Table Ind. Indexing Mode  */
-	#define   EXTIBMV 0x02	/* Enable 64-bit Table Ind. BMOV    */
-	#define   EXDBMV 0x01	/* Enable 64-bit Direct BMOV        */
-
-/*58*/  u16	nc_sbdl;	/* Lowlevel: data from scsi data    */
-/*5a*/  u16	nc_5a_;
-
-/*5c*/  u8	nc_scr0;	/* Working register B               */
-/*5d*/  u8	nc_scr1;	/*                                  */
-/*5e*/  u8	nc_scr2;	/*                                  */
-/*5f*/  u8	nc_scr3;	/*                                  */
-
-/*60*/  u8	nc_scrx[64];	/* Working register C-R             */
-/*a0*/	u32	nc_mmrs;	/* Memory Move Read Selector        */
-/*a4*/	u32	nc_mmws;	/* Memory Move Write Selector       */
-/*a8*/	u32	nc_sfs;		/* Script Fetch Selector            */
-/*ac*/	u32	nc_drs;		/* DSA Relative Selector            */
-/*b0*/	u32	nc_sbms;	/* Static Block Move Selector       */
-/*b4*/	u32	nc_dbms;	/* Dynamic Block Move Selector      */
-/*b8*/	u32	nc_dnad64;	/* DMA Next Address 64              */
-/*bc*/	u16	nc_scntl4;	/* C1010 only                       */
-	#define   U3EN   0x80	/* Enable Ultra 3                   */
-	#define   AIPEN	 0x40   /* Allow check upper byte lanes     */
-	#define   XCLKH_DT 0x08 /* Extra clock of data hold on DT
-					transfer edge	            */
-	#define   XCLKH_ST 0x04 /* Extra clock of data hold on ST
-					transfer edge	            */
-
-/*be*/  u8	nc_aipcntl0;	/* Epat Control 1 C1010 only        */
-/*bf*/  u8	nc_aipcntl1;	/* AIP Control C1010_66 Only        */
-
-/*c0*/	u32	nc_pmjad1;	/* Phase Mismatch Jump Address 1    */
-/*c4*/	u32	nc_pmjad2;	/* Phase Mismatch Jump Address 2    */
-/*c8*/	u8	nc_rbc;		/* Remaining Byte Count             */
-/*c9*/	u8	nc_rbc1;	/*                                  */
-/*ca*/	u8	nc_rbc2;	/*                                  */
-/*cb*/	u8	nc_rbc3;	/*                                  */
-
-/*cc*/	u8	nc_ua;		/* Updated Address                  */
-/*cd*/	u8	nc_ua1;		/*                                  */
-/*ce*/	u8	nc_ua2;		/*                                  */
-/*cf*/	u8	nc_ua3;		/*                                  */
-/*d0*/	u32	nc_esa;		/* Entry Storage Address            */
-/*d4*/	u8	nc_ia;		/* Instruction Address              */
-/*d5*/	u8	nc_ia1;
-/*d6*/	u8	nc_ia2;
-/*d7*/	u8	nc_ia3;
-/*d8*/	u32	nc_sbc;		/* SCSI Byte Count (3 bytes only)   */
-/*dc*/	u32	nc_csbc;	/* Cumulative SCSI Byte Count       */
-
-				/* Following for C1010 only         */
-/*e0*/  u16	nc_crcpad;	/* CRC Value                        */
-/*e2*/  u8	nc_crccntl0;	/* CRC control register             */
-	#define   SNDCRC  0x10	/* Send CRC Request                 */
-/*e3*/  u8	nc_crccntl1;	/* CRC control register             */
-/*e4*/  u32	nc_crcdata;	/* CRC data register                */ 
-/*e8*/  u32	nc_e8_;		/* rsvd 			    */
-/*ec*/  u32	nc_ec_;		/* rsvd 			    */
-/*f0*/  u16	nc_dfbc;	/* DMA FIFO byte count              */ 
-
-};
-
-/*-----------------------------------------------------------
-**
-**	Utility macros for the script.
-**
-**-----------------------------------------------------------
-*/
-
-#define REGJ(p,r) (offsetof(struct ncr_reg, p ## r))
-#define REG(r) REGJ (nc_, r)
-
-typedef u32 ncrcmd;
-
-/*-----------------------------------------------------------
-**
-**	SCSI phases
-**
-**	DT phases illegal for ncr driver.
-**
-**-----------------------------------------------------------
-*/
-
-#define	SCR_DATA_OUT	0x00000000
-#define	SCR_DATA_IN	0x01000000
-#define	SCR_COMMAND	0x02000000
-#define	SCR_STATUS	0x03000000
-#define SCR_DT_DATA_OUT	0x04000000
-#define SCR_DT_DATA_IN	0x05000000
-#define SCR_MSG_OUT	0x06000000
-#define SCR_MSG_IN      0x07000000
-
-#define SCR_ILG_OUT	0x04000000
-#define SCR_ILG_IN	0x05000000
-
-/*-----------------------------------------------------------
-**
-**	Data transfer via SCSI.
-**
-**-----------------------------------------------------------
-**
-**	MOVE_ABS (LEN)
-**	<<start address>>
-**
-**	MOVE_IND (LEN)
-**	<<dnad_offset>>
-**
-**	MOVE_TBL
-**	<<dnad_offset>>
-**
-**-----------------------------------------------------------
-*/
-
-#define OPC_MOVE          0x08000000
-
-#define SCR_MOVE_ABS(l) ((0x00000000 | OPC_MOVE) | (l))
-#define SCR_MOVE_IND(l) ((0x20000000 | OPC_MOVE) | (l))
-#define SCR_MOVE_TBL     (0x10000000 | OPC_MOVE)
-
-#define SCR_CHMOV_ABS(l) ((0x00000000) | (l))
-#define SCR_CHMOV_IND(l) ((0x20000000) | (l))
-#define SCR_CHMOV_TBL     (0x10000000)
-
-struct scr_tblmove {
-        u32  size;
-        u32  addr;
-};
-
-/*-----------------------------------------------------------
-**
-**	Selection
-**
-**-----------------------------------------------------------
-**
-**	SEL_ABS | SCR_ID (0..15)    [ | REL_JMP]
-**	<<alternate_address>>
-**
-**	SEL_TBL | << dnad_offset>>  [ | REL_JMP]
-**	<<alternate_address>>
-**
-**-----------------------------------------------------------
-*/
-
-#define	SCR_SEL_ABS	0x40000000
-#define	SCR_SEL_ABS_ATN	0x41000000
-#define	SCR_SEL_TBL	0x42000000
-#define	SCR_SEL_TBL_ATN	0x43000000
-
-
-#ifdef SCSI_NCR_BIG_ENDIAN
-struct scr_tblsel {
-        u8	sel_scntl3;
-        u8	sel_id;
-        u8	sel_sxfer;
-        u8	sel_scntl4;	
-};
-#else
-struct scr_tblsel {
-        u8	sel_scntl4;	
-        u8	sel_sxfer;
-        u8	sel_id;
-        u8	sel_scntl3;
-};
-#endif
-
-#define SCR_JMP_REL     0x04000000
-#define SCR_ID(id)	(((u32)(id)) << 16)
-
-/*-----------------------------------------------------------
-**
-**	Waiting for Disconnect or Reselect
-**
-**-----------------------------------------------------------
-**
-**	WAIT_DISC
-**	dummy: <<alternate_address>>
-**
-**	WAIT_RESEL
-**	<<alternate_address>>
-**
-**-----------------------------------------------------------
-*/
-
-#define	SCR_WAIT_DISC	0x48000000
-#define SCR_WAIT_RESEL  0x50000000
-
-/*-----------------------------------------------------------
-**
-**	Bit Set / Reset
-**
-**-----------------------------------------------------------
-**
-**	SET (flags {|.. })
-**
-**	CLR (flags {|.. })
-**
-**-----------------------------------------------------------
-*/
-
-#define SCR_SET(f)     (0x58000000 | (f))
-#define SCR_CLR(f)     (0x60000000 | (f))
-
-#define	SCR_CARRY	0x00000400
-#define	SCR_TRG		0x00000200
-#define	SCR_ACK		0x00000040
-#define	SCR_ATN		0x00000008
-
-
-
-
-/*-----------------------------------------------------------
-**
-**	Memory to memory move
-**
-**-----------------------------------------------------------
-**
-**	COPY (bytecount)
-**	<< source_address >>
-**	<< destination_address >>
-**
-**	SCR_COPY   sets the NO FLUSH option by default.
-**	SCR_COPY_F does not set this option.
-**
-**	For chips which do not support this option,
-**	ncr_copy_and_bind() will remove this bit.
-**-----------------------------------------------------------
-*/
-
-#define SCR_NO_FLUSH 0x01000000
-
-#define SCR_COPY(n) (0xc0000000 | SCR_NO_FLUSH | (n))
-#define SCR_COPY_F(n) (0xc0000000 | (n))
-
-/*-----------------------------------------------------------
-**
-**	Register move and binary operations
-**
-**-----------------------------------------------------------
-**
-**	SFBR_REG (reg, op, data)        reg  = SFBR op data
-**	<< 0 >>
-**
-**	REG_SFBR (reg, op, data)        SFBR = reg op data
-**	<< 0 >>
-**
-**	REG_REG  (reg, op, data)        reg  = reg op data
-**	<< 0 >>
-**
-**-----------------------------------------------------------
-**	On 810A, 860, 825A, 875, 895 and 896 chips the content 
-**	of SFBR register can be used as data (SCR_SFBR_DATA).
-**	The 896 has additionnal IO registers starting at 
-**	offset 0x80. Bit 7 of register offset is stored in 
-**	bit 7 of the SCRIPTS instruction first DWORD.
-**-----------------------------------------------------------
-*/
-
-#define SCR_REG_OFS(ofs) ((((ofs) & 0x7f) << 16ul) + ((ofs) & 0x80)) 
-
-#define SCR_SFBR_REG(reg,op,data) \
-        (0x68000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
-
-#define SCR_REG_SFBR(reg,op,data) \
-        (0x70000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
-
-#define SCR_REG_REG(reg,op,data) \
-        (0x78000000 | (SCR_REG_OFS(REG(reg))) | (op) | (((data)&0xff)<<8ul))
-
-
-#define      SCR_LOAD   0x00000000
-#define      SCR_SHL    0x01000000
-#define      SCR_OR     0x02000000
-#define      SCR_XOR    0x03000000
-#define      SCR_AND    0x04000000
-#define      SCR_SHR    0x05000000
-#define      SCR_ADD    0x06000000
-#define      SCR_ADDC   0x07000000
-
-#define      SCR_SFBR_DATA   (0x00800000>>8ul)	/* Use SFBR as data */
-
-/*-----------------------------------------------------------
-**
-**	FROM_REG (reg)		  SFBR = reg
-**	<< 0 >>
-**
-**	TO_REG	 (reg)		  reg  = SFBR
-**	<< 0 >>
-**
-**	LOAD_REG (reg, data)	  reg  = <data>
-**	<< 0 >>
-**
-**	LOAD_SFBR(data) 	  SFBR = <data>
-**	<< 0 >>
-**
-**-----------------------------------------------------------
-*/
-
-#define	SCR_FROM_REG(reg) \
-	SCR_REG_SFBR(reg,SCR_OR,0)
-
-#define	SCR_TO_REG(reg) \
-	SCR_SFBR_REG(reg,SCR_OR,0)
-
-#define	SCR_LOAD_REG(reg,data) \
-	SCR_REG_REG(reg,SCR_LOAD,data)
-
-#define SCR_LOAD_SFBR(data) \
-        (SCR_REG_SFBR (gpreg, SCR_LOAD, data))
-
-/*-----------------------------------------------------------
-**
-**	LOAD  from memory   to register.
-**	STORE from register to memory.
-**
-**	Only supported by 810A, 860, 825A, 875, 895 and 896.
-**
-**-----------------------------------------------------------
-**
-**	LOAD_ABS (LEN)
-**	<<start address>>
-**
-**	LOAD_REL (LEN)        (DSA relative)
-**	<<dsa_offset>>
-**
-**-----------------------------------------------------------
-*/
-
-#define SCR_REG_OFS2(ofs) (((ofs) & 0xff) << 16ul)
-#define SCR_NO_FLUSH2	0x02000000
-#define SCR_DSA_REL2	0x10000000
-
-#define SCR_LOAD_R(reg, how, n) \
-        (0xe1000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
-
-#define SCR_STORE_R(reg, how, n) \
-        (0xe0000000 | how | (SCR_REG_OFS2(REG(reg))) | (n))
-
-#define SCR_LOAD_ABS(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2, n)
-#define SCR_LOAD_REL(reg, n)	SCR_LOAD_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2, n)
-#define SCR_LOAD_ABS_F(reg, n)	SCR_LOAD_R(reg, 0, n)
-#define SCR_LOAD_REL_F(reg, n)	SCR_LOAD_R(reg, SCR_DSA_REL2, n)
-
-#define SCR_STORE_ABS(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2, n)
-#define SCR_STORE_REL(reg, n)	SCR_STORE_R(reg, SCR_NO_FLUSH2|SCR_DSA_REL2,n)
-#define SCR_STORE_ABS_F(reg, n)	SCR_STORE_R(reg, 0, n)
-#define SCR_STORE_REL_F(reg, n)	SCR_STORE_R(reg, SCR_DSA_REL2, n)
-
-
-/*-----------------------------------------------------------
-**
-**	Waiting for Disconnect or Reselect
-**
-**-----------------------------------------------------------
-**
-**	JUMP            [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<address>>
-**
-**	JUMPR           [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<distance>>
-**
-**	CALL            [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<address>>
-**
-**	CALLR           [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<distance>>
-**
-**	RETURN          [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<dummy>>
-**
-**	INT             [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<ident>>
-**
-**	INT_FLY         [ | IFTRUE/IFFALSE ( ... ) ]
-**	<<ident>>
-**
-**	Conditions:
-**	     WHEN (phase)
-**	     IF   (phase)
-**	     CARRYSET
-**	     DATA (data, mask)
-**
-**-----------------------------------------------------------
-*/
-
-#define SCR_NO_OP       0x80000000
-#define SCR_JUMP        0x80080000
-#define SCR_JUMP64      0x80480000
-#define SCR_JUMPR       0x80880000
-#define SCR_CALL        0x88080000
-#define SCR_CALLR       0x88880000
-#define SCR_RETURN      0x90080000
-#define SCR_INT         0x98080000
-#define SCR_INT_FLY     0x98180000
-
-#define IFFALSE(arg)   (0x00080000 | (arg))
-#define IFTRUE(arg)    (0x00000000 | (arg))
-
-#define WHEN(phase)    (0x00030000 | (phase))
-#define IF(phase)      (0x00020000 | (phase))
-
-#define DATA(D)        (0x00040000 | ((D) & 0xff))
-#define MASK(D,M)      (0x00040000 | (((M ^ 0xff) & 0xff) << 8ul)|((D) & 0xff))
-
-#define CARRYSET       (0x00200000)
-
-/*-----------------------------------------------------------
-**
-**	SCSI  constants.
-**
-**-----------------------------------------------------------
-*/
-
-/*
-**	Messages
-*/
-
-#define	M_COMPLETE	COMMAND_COMPLETE
-#define	M_EXTENDED	EXTENDED_MESSAGE
-#define	M_SAVE_DP	SAVE_POINTERS
-#define	M_RESTORE_DP	RESTORE_POINTERS
-#define	M_DISCONNECT	DISCONNECT
-#define	M_ID_ERROR	INITIATOR_ERROR
-#define	M_ABORT		ABORT_TASK_SET
-#define	M_REJECT	MESSAGE_REJECT
-#define	M_NOOP		NOP
-#define	M_PARITY	MSG_PARITY_ERROR
-#define	M_LCOMPLETE	LINKED_CMD_COMPLETE
-#define	M_FCOMPLETE	LINKED_FLG_CMD_COMPLETE
-#define	M_RESET		TARGET_RESET
-#define	M_ABORT_TAG	ABORT_TASK
-#define	M_CLEAR_QUEUE	CLEAR_TASK_SET
-#define	M_INIT_REC	INITIATE_RECOVERY
-#define	M_REL_REC	RELEASE_RECOVERY
-#define	M_TERMINATE	(0x11)
-#define	M_SIMPLE_TAG	SIMPLE_QUEUE_TAG
-#define	M_HEAD_TAG	HEAD_OF_QUEUE_TAG
-#define	M_ORDERED_TAG	ORDERED_QUEUE_TAG
-#define	M_IGN_RESIDUE	IGNORE_WIDE_RESIDUE
-#define	M_IDENTIFY   	(0x80)
-
-#define	M_X_MODIFY_DP	EXTENDED_MODIFY_DATA_POINTER
-#define	M_X_SYNC_REQ	EXTENDED_SDTR
-#define	M_X_WIDE_REQ	EXTENDED_WDTR
-#define	M_X_PPR_REQ	EXTENDED_PPR
-
-/*
-**	Status
-*/
-
-#define	S_GOOD		(0x00)
-#define	S_CHECK_COND	(0x02)
-#define	S_COND_MET	(0x04)
-#define	S_BUSY		(0x08)
-#define	S_INT		(0x10)
-#define	S_INT_COND_MET	(0x14)
-#define	S_CONFLICT	(0x18)
-#define	S_TERMINATED	(0x20)
-#define	S_QUEUE_FULL	(0x28)
-#define	S_ILLEGAL	(0xff)
-#define	S_SENSE		(0x80)
-
-/*
- * End of ncrreg from FreeBSD
- */
-
-#endif /* defined SYM53C8XX_DEFS_H */
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index e08510d..1891cf5 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -102,7 +102,7 @@
 #define SERIAL_PORT_DFNS
 #endif
 
-static struct old_serial_port old_serial_port[] = {
+static const struct old_serial_port old_serial_port[] = {
 	SERIAL_PORT_DFNS /* defined in asm/serial.h */
 };
 
@@ -296,7 +296,7 @@
 
 #endif
 
-static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
+static unsigned int serial_in(struct uart_8250_port *up, int offset)
 {
 	offset = map_8250_in_reg(up, offset) << up->port.regshift;
 
@@ -321,7 +321,7 @@
 	}
 }
 
-static _INLINE_ void
+static void
 serial_out(struct uart_8250_port *up, int offset, int value)
 {
 	offset = map_8250_out_reg(up, offset) << up->port.regshift;
@@ -1131,7 +1131,7 @@
 	serial_out(up, UART_IER, up->ier);
 }
 
-static _INLINE_ void
+static void
 receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
 {
 	struct tty_struct *tty = up->port.info->tty;
@@ -1217,7 +1217,7 @@
 	*status = lsr;
 }
 
-static _INLINE_ void transmit_chars(struct uart_8250_port *up)
+static void transmit_chars(struct uart_8250_port *up)
 {
 	struct circ_buf *xmit = &up->port.info->xmit;
 	int count;
@@ -1255,25 +1255,24 @@
 		__stop_tx(up);
 }
 
-static _INLINE_ void check_modem_status(struct uart_8250_port *up)
+static unsigned int check_modem_status(struct uart_8250_port *up)
 {
-	int status;
+	unsigned int status = serial_in(up, UART_MSR);
 
-	status = serial_in(up, UART_MSR);
+	if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI) {
+		if (status & UART_MSR_TERI)
+			up->port.icount.rng++;
+		if (status & UART_MSR_DDSR)
+			up->port.icount.dsr++;
+		if (status & UART_MSR_DDCD)
+			uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
+		if (status & UART_MSR_DCTS)
+			uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
 
-	if ((status & UART_MSR_ANY_DELTA) == 0)
-		return;
+		wake_up_interruptible(&up->port.info->delta_msr_wait);
+	}
 
-	if (status & UART_MSR_TERI)
-		up->port.icount.rng++;
-	if (status & UART_MSR_DDSR)
-		up->port.icount.dsr++;
-	if (status & UART_MSR_DDCD)
-		uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
-	if (status & UART_MSR_DCTS)
-		uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
-
-	wake_up_interruptible(&up->port.info->delta_msr_wait);
+	return status;
 }
 
 /*
@@ -1282,7 +1281,11 @@
 static inline void
 serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
 {
-	unsigned int status = serial_inp(up, UART_LSR);
+	unsigned int status;
+
+	spin_lock(&up->port.lock);
+
+	status = serial_inp(up, UART_LSR);
 
 	DEBUG_INTR("status = %x...", status);
 
@@ -1291,6 +1294,8 @@
 	check_modem_status(up);
 	if (status & UART_LSR_THRE)
 		transmit_chars(up);
+
+	spin_unlock(&up->port.lock);
 }
 
 /*
@@ -1326,9 +1331,7 @@
 
 		iir = serial_in(up, UART_IIR);
 		if (!(iir & UART_IIR_NO_INT)) {
-			spin_lock(&up->port.lock);
 			serial8250_handle_port(up, regs);
-			spin_unlock(&up->port.lock);
 
 			handled = 1;
 
@@ -1427,11 +1430,8 @@
 	unsigned int iir;
 
 	iir = serial_in(up, UART_IIR);
-	if (!(iir & UART_IIR_NO_INT)) {
-		spin_lock(&up->port.lock);
+	if (!(iir & UART_IIR_NO_INT))
 		serial8250_handle_port(up, NULL);
-		spin_unlock(&up->port.lock);
-	}
 
 	timeout = up->port.timeout;
 	timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
@@ -1454,10 +1454,10 @@
 static unsigned int serial8250_get_mctrl(struct uart_port *port)
 {
 	struct uart_8250_port *up = (struct uart_8250_port *)port;
-	unsigned char status;
+	unsigned int status;
 	unsigned int ret;
 
-	status = serial_in(up, UART_MSR);
+	status = check_modem_status(up);
 
 	ret = 0;
 	if (status & UART_MSR_DCD)
@@ -2300,9 +2300,7 @@
 
 	for (line = 0; line < UART_NR; line++) {
 		port = &serial8250_ports[line].port;
-		if (p->iotype == port->iotype &&
-		    p->iobase == port->iobase &&
-		    p->membase == port->membase)
+		if (uart_match_port(p, port))
 			return line;
 	}
 	return -ENODEV;
diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
index a607b98..490606b 100644
--- a/drivers/serial/8250.h
+++ b/drivers/serial/8250.h
@@ -51,12 +51,6 @@
 #define UART_BUG_TXEN	(1 << 1)	/* UART has buggy TX IIR status */
 #define UART_BUG_NOMSR	(1 << 2)	/* UART has buggy MSR status bits (Au1x00) */
 
-#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
-#define _INLINE_ inline
-#else
-#define _INLINE_
-#endif
-
 #define PROBE_RSA	(1 << 0)
 #define PROBE_ANY	(~0)
 
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 5c3c039..589fb07 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -468,7 +468,7 @@
 	0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
 };
 
-static struct timedia_struct {
+static const struct timedia_struct {
 	int num;
 	unsigned short *ids;
 } timedia_data[] = {
@@ -516,7 +516,7 @@
 		break;
 	case 3:
 		offset = board->uart_offset;
-		bar = 1;
+		/* FALLTHROUGH */
 	case 4: /* BAR 2 */
 	case 5: /* BAR 3 */
 	case 6: /* BAR 4 */
@@ -837,8 +837,8 @@
 	return quirk;
 }
 
-static _INLINE_ int
-get_pci_irq(struct pci_dev *dev, struct pciserial_board *board)
+static inline int get_pci_irq(struct pci_dev *dev,
+				struct pciserial_board *board)
 {
 	if (board->flags & FL_NOIRQ)
 		return 0;
@@ -853,14 +853,15 @@
  * driver_data member.
  *
  * The makeup of these names are:
- *  pbn_bn{_bt}_n_baud
+ *  pbn_bn{_bt}_n_baud{_offsetinhex}
  *
- *  bn   = PCI BAR number
- *  bt   = Index using PCI BARs
- *  n    = number of serial ports
- *  baud = baud rate
+ *  bn		= PCI BAR number
+ *  bt		= Index using PCI BARs
+ *  n		= number of serial ports
+ *  baud	= baud rate
+ *  offsetinhex	= offset for each sequential port (in hex)
  *
- * This table is sorted by (in order): baud, bt, bn, n.
+ * This table is sorted by (in order): bn, bt, baud, offsetindex, n.
  *
  * Please note: in theory if n = 1, _bt infix should make no difference.
  * ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200
@@ -881,6 +882,13 @@
 
 	pbn_b0_4_1152000,
 
+	pbn_b0_2_1843200,
+	pbn_b0_4_1843200,
+
+	pbn_b0_2_1843200_200,
+	pbn_b0_4_1843200_200,
+	pbn_b0_8_1843200_200,
+
 	pbn_b0_bt_1_115200,
 	pbn_b0_bt_2_115200,
 	pbn_b0_bt_8_115200,
@@ -904,6 +912,8 @@
 	pbn_b1_4_921600,
 	pbn_b1_8_921600,
 
+	pbn_b1_2_1250000,
+
 	pbn_b1_bt_2_921600,
 
 	pbn_b1_1_1382400,
@@ -1029,6 +1039,38 @@
 		.uart_offset	= 8,
 	},
 
+	[pbn_b0_2_1843200] = {
+		.flags		= FL_BASE0,
+		.num_ports	= 2,
+		.base_baud	= 1843200,
+		.uart_offset	= 8,
+	},
+	[pbn_b0_4_1843200] = {
+		.flags		= FL_BASE0,
+		.num_ports	= 4,
+		.base_baud	= 1843200,
+		.uart_offset	= 8,
+	},
+
+	[pbn_b0_2_1843200_200] = {
+		.flags		= FL_BASE0,
+		.num_ports	= 2,
+		.base_baud	= 1843200,
+		.uart_offset	= 0x200,
+	},
+	[pbn_b0_4_1843200_200] = {
+		.flags		= FL_BASE0,
+		.num_ports	= 4,
+		.base_baud	= 1843200,
+		.uart_offset	= 0x200,
+	},
+	[pbn_b0_8_1843200_200] = {
+		.flags		= FL_BASE0,
+		.num_ports	= 8,
+		.base_baud	= 1843200,
+		.uart_offset	= 0x200,
+	},
+
 	[pbn_b0_bt_1_115200] = {
 		.flags		= FL_BASE0|FL_BASE_BARS,
 		.num_ports	= 1,
@@ -1141,6 +1183,12 @@
 		.base_baud	= 921600,
 		.uart_offset	= 8,
 	},
+	[pbn_b1_2_1250000] = {
+		.flags		= FL_BASE1,
+		.num_ports	= 2,
+		.base_baud	= 1250000,
+		.uart_offset	= 8,
+	},
 
 	[pbn_b1_bt_2_921600] = {
 		.flags		= FL_BASE1|FL_BASE_BARS,
@@ -1801,6 +1849,66 @@
 		PCI_SUBVENDOR_ID_CONNECT_TECH,
 		PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0,
 		pbn_b1_4_921600 },
+	{	PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ, 0, 0,
+		pbn_b1_2_1250000 },
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2, 0, 0,
+		pbn_b0_2_1843200 },
+	{	PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0,
+		pbn_b0_4_1843200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0,
+		pbn_b0_2_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232, 0, 0,
+		pbn_b0_4_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232, 0, 0,
+		pbn_b0_8_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1, 0, 0,
+		pbn_b0_2_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2, 0, 0,
+		pbn_b0_4_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4, 0, 0,
+		pbn_b0_8_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2, 0, 0,
+		pbn_b0_2_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4, 0, 0,
+		pbn_b0_4_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8, 0, 0,
+		pbn_b0_8_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485, 0, 0,
+		pbn_b0_2_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C154,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485, 0, 0,
+		pbn_b0_4_1843200_200 },
+	{	PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C158,
+		PCI_SUBVENDOR_ID_CONNECT_TECH,
+		PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485, 0, 0,
+		pbn_b0_8_1843200_200 },
 
 	{	PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index ad47c1b..812bae6 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -10,7 +10,7 @@
 # The new 8250/16550 serial drivers
 config SERIAL_8250
 	tristate "8250/16550 and compatible serial support"
-	depends on (BROKEN || !(SPARC64 || SPARC32))
+	depends on (BROKEN || !SPARC)
 	select SERIAL_CORE
 	---help---
 	  This selects whether you want to include the driver for the standard
@@ -469,14 +469,14 @@
 
 config SERIAL_SUNCORE
 	bool
-	depends on SPARC32 || SPARC64
+	depends on SPARC
 	select SERIAL_CORE
 	select SERIAL_CORE_CONSOLE
 	default y
 
 config SERIAL_SUNZILOG
 	tristate "Sun Zilog8530 serial support"
-	depends on SPARC32 || SPARC64
+	depends on SPARC
 	help
 	  This driver supports the Zilog8530 serial ports found on many Sparc
 	  systems.  Say Y or M if you want to be able to these serial ports.
@@ -491,7 +491,7 @@
 
 config SERIAL_SUNSU
 	tristate "Sun SU serial support"
-	depends on (SPARC32 || SPARC64) && PCI
+	depends on SPARC && PCI
 	help
 	  This driver supports the 8250 serial ports that run the keyboard and
 	  mouse on (PCI) UltraSPARC systems.  Say Y or M if you want to be able
@@ -547,7 +547,7 @@
 
 config SERIAL_SUNSAB
 	tristate "Sun Siemens SAB82532 serial support"
-	depends on (SPARC32 || SPARC64) && PCI
+	depends on SPARC && PCI
 	help
 	  This driver supports the Siemens SAB82532 DUSCC serial ports on newer
 	  (PCI) UltraSPARC systems.  Say Y or M if you want to be able to these
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index ddd0307..48f6e87 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -47,12 +47,12 @@
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/hardware.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/amba_serial.h>
 
 #define UART_NR		2
 
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 89d7bd3..1296705 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -47,12 +47,12 @@
 #include <linux/tty_flip.h>
 #include <linux/serial_core.h>
 #include <linux/serial.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/serial.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
 #include <asm/sizes.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/clock.h>
-#include <asm/hardware/amba_serial.h>
 
 #define UART_NR			14
 
@@ -160,7 +160,7 @@
 				flag = TTY_FRAME;
 		}
 
-		if (uart_handle_sysrq_char(&uap->port, ch, regs))
+		if (uart_handle_sysrq_char(&uap->port, ch & 255, regs))
 			goto ignore_char;
 
 		uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
@@ -761,10 +761,6 @@
 		goto unmap;
 	}
 
-	ret = clk_use(uap->clk);
-	if (ret)
-		goto putclk;
-
 	uap->port.dev = &dev->dev;
 	uap->port.mapbase = dev->res.start;
 	uap->port.membase = base;
@@ -782,8 +778,6 @@
 	if (ret) {
 		amba_set_drvdata(dev, NULL);
 		amba_ports[i] = NULL;
-		clk_unuse(uap->clk);
- putclk:
 		clk_put(uap->clk);
  unmap:
 		iounmap(base);
@@ -808,7 +802,6 @@
 			amba_ports[i] = NULL;
 
 	iounmap(uap->port.membase);
-	clk_unuse(uap->clk);
 	clk_put(uap->clk);
 	kfree(uap);
 	return 0;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index b8727d9..1288d62 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -37,11 +37,11 @@
  * by the bootloader or in the platform init code.
  *
  * The idx field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2,
- * and so on). So the PSC1 is mapped to /dev/ttyS0, PSC2 to /dev/ttyS1 and so
- * on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly for
- * the console code : without this 1:1 mapping, at early boot time, when we are
- * parsing the kernel args console=ttyS?, we wouldn't know wich PSC it will be
- * mapped to.
+ * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and
+ * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly
+ * fpr the console code : without this 1:1 mapping, at early boot time, when we
+ * are parsing the kernel args console=ttyPSC?, we wouldn't know wich PSC it
+ * will be mapped to.
  */
 
 #include <linux/config.h>
@@ -65,6 +65,10 @@
 #include <linux/serial_core.h>
 
 
+/* We've been assigned a range on the "Low-density serial ports" major */
+#define SERIAL_PSC_MAJOR	204
+#define SERIAL_PSC_MINOR	148
+
 
 #define ISR_PASS_LIMIT 256	/* Max number of iteration in the interrupt */
 
@@ -668,15 +672,15 @@
 }
 
 
-extern struct uart_driver mpc52xx_uart_driver;
+static struct uart_driver mpc52xx_uart_driver;
 
 static struct console mpc52xx_console = {
-	.name	= "ttyS",
+	.name	= "ttyPSC",
 	.write	= mpc52xx_console_write,
 	.device	= uart_console_device,
 	.setup	= mpc52xx_console_setup,
 	.flags	= CON_PRINTBUFFER,
-	.index	= -1,	/* Specified on the cmdline (e.g. console=ttyS0 ) */
+	.index	= -1,	/* Specified on the cmdline (e.g. console=ttyPSC0 ) */
 	.data	= &mpc52xx_uart_driver,
 };
 
@@ -703,10 +707,10 @@
 static struct uart_driver mpc52xx_uart_driver = {
 	.owner		= THIS_MODULE,
 	.driver_name	= "mpc52xx_psc_uart",
-	.dev_name	= "ttyS",
-	.devfs_name	= "ttyS",
-	.major		= TTY_MAJOR,
-	.minor		= 64,
+	.dev_name	= "ttyPSC",
+	.devfs_name	= "ttyPSC",
+	.major		= SERIAL_PSC_MAJOR,
+	.minor		= SERIAL_PSC_MINOR,
 	.nr		= MPC52xx_PSC_MAXNUM,
 	.cons		= MPC52xx_PSC_CONSOLE,
 };
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index ff5e630..cc998b9 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -361,7 +361,7 @@
 	if (port->line == 3) /* HWUART */
 		up->mcr |= UART_MCR_AFE;
 	else
-	up->mcr = 0;
+		up->mcr = 0;
 
 	/*
 	 * Allocate the IRQ
@@ -641,7 +641,7 @@
 	int i;
 
 	/*
-	 *	First save the UER then disable the interrupts
+	 *	First save the IER then disable the interrupts
 	 */
 	ier = serial_in(up, UART_IER);
 	serial_out(up, UART_IER, UART_IER_UUE);
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 47681c4..fe83ce6 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -72,12 +72,12 @@
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 #include <linux/delay.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/clock.h>
 
 #include <asm/arch/regs-serial.h>
 #include <asm/arch/regs-gpio.h>
@@ -782,11 +782,9 @@
 
 		if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
 			clk_disable(ourport->baudclk);
-			clk_unuse(ourport->baudclk);
 			ourport->baudclk  = NULL;
 		}
 
-		clk_use(clk);
 		clk_enable(clk);
 
 		ourport->clksrc = clksrc;
@@ -1077,9 +1075,6 @@
 
 	ourport->clk	= clk_get(&platdev->dev, "uart");
 
-	if (ourport->clk != NULL && !IS_ERR(ourport->clk))
-		clk_use(ourport->clk);
-
 	dbg("port: map=%08x, mem=%08x, irq=%d, clock=%ld\n",
 	    port->mapbase, port->membase, port->irq, port->uartclk);
 
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 2331296..34c576d 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1779,7 +1779,7 @@
 	unsigned int cflag;
 };
 
-static struct baud_rates baud_rates[] = {
+static const struct baud_rates baud_rates[] = {
 	{ 921600, B921600 },
 	{ 460800, B460800 },
 	{ 230400, B230400 },
@@ -2307,7 +2307,7 @@
 		return (port1->iobase == port2->iobase) &&
 		       (port1->hub6   == port2->hub6);
 	case UPIO_MEM:
-		return (port1->membase == port2->membase);
+		return (port1->mapbase == port2->mapbase);
 	}
 	return 0;
 }
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 2c7d3ef..96969cb 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -85,7 +85,7 @@
 	int multi;		/* 1 = multifunction, > 1 = # ports */
 };
 
-static struct multi_id multi_id[] = {
+static const struct multi_id multi_id[] = {
 	{ MANFID_OMEGA,   PRODID_OMEGA_QSP_100,         4 },
 	{ MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232,    2 },
 	{ MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
@@ -114,15 +114,7 @@
 
 
 static void serial_config(dev_link_t * link);
-static int serial_event(event_t event, int priority,
-			event_callback_args_t * args);
 
-static dev_info_t dev_info = "serial_cs";
-
-static dev_link_t *serial_attach(void);
-static void serial_detach(dev_link_t *);
-
-static dev_link_t *dev_list = NULL;
 
 /*======================================================================
 
@@ -159,8 +151,9 @@
 	}
 }
 
-static void serial_suspend(dev_link_t *link)
+static int serial_suspend(struct pcmcia_device *dev)
 {
+	dev_link_t *link = dev_to_instance(dev);
 	link->state |= DEV_SUSPEND;
 
 	if (link->state & DEV_CONFIG) {
@@ -173,10 +166,13 @@
 		if (!info->slave)
 			pcmcia_release_configuration(link->handle);
 	}
+
+	return 0;
 }
 
-static void serial_resume(dev_link_t *link)
+static int serial_resume(struct pcmcia_device *dev)
 {
+	dev_link_t *link = dev_to_instance(dev);
 	link->state &= ~DEV_SUSPEND;
 
 	if (DEV_OK(link)) {
@@ -189,6 +185,8 @@
 		for (i = 0; i < info->ndev; i++)
 			serial8250_resume_port(info->line[i]);
 	}
+
+	return 0;
 }
 
 /*======================================================================
@@ -199,19 +197,17 @@
 
 ======================================================================*/
 
-static dev_link_t *serial_attach(void)
+static int serial_probe(struct pcmcia_device *p_dev)
 {
 	struct serial_info *info;
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
 
 	DEBUG(0, "serial_attach()\n");
 
 	/* Create new serial device */
 	info = kmalloc(sizeof (*info), GFP_KERNEL);
 	if (!info)
-		return NULL;
+		return -ENOMEM;
 	memset(info, 0, sizeof (*info));
 	link = &info->link;
 	link->priv = info;
@@ -227,20 +223,12 @@
 	}
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		serial_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	serial_config(link);
 
-	return link;
+	return 0;
 }
 
 /*======================================================================
@@ -252,21 +240,13 @@
 
 ======================================================================*/
 
-static void serial_detach(dev_link_t * link)
+static void serial_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct serial_info *info = link->priv;
-	dev_link_t **linkp;
-	int ret;
 
 	DEBUG(0, "serial_detach(0x%p)\n", link);
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-	if (*linkp == NULL)
-		return;
-
 	/*
 	 * Ensure any outstanding scheduled tasks are completed.
 	 */
@@ -277,14 +257,7 @@
 	 */
 	serial_remove(link);
 
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
+	/* free bits */
 	kfree(info);
 }
 
@@ -354,8 +327,8 @@
 
 static int simple_config(dev_link_t *link)
 {
-	static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-	static int size_table[2] = { 8, 16 };
+	static const kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
+	static const int size_table[2] = { 8, 16 };
 	client_handle_t handle = link->handle;
 	struct serial_info *info = link->priv;
 	struct serial_cfg_mem *cfg_mem;
@@ -718,54 +691,6 @@
 	kfree(cfg_mem);
 }
 
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the serial drivers from
-    talking to the ports.
-    
-======================================================================*/
-
-static int
-serial_event(event_t event, int priority, event_callback_args_t * args)
-{
-	dev_link_t *link = args->client_data;
-	struct serial_info *info = link->priv;
-
-	DEBUG(1, "serial_event(0x%06x)\n", event);
-
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		serial_remove(link);
-		break;
-
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		serial_config(link);
-		break;
-
-	case CS_EVENT_PM_SUSPEND:
-		serial_suspend(link);
-		break;
-
-	case CS_EVENT_RESET_PHYSICAL:
-		if ((link->state & DEV_CONFIG) && !info->slave)
-			pcmcia_release_configuration(link->handle);
-		break;
-
-	case CS_EVENT_PM_RESUME:
-		serial_resume(link);
-		break;
-
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link) && !info->slave)
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
-	return 0;
-}
-
 static struct pcmcia_device_id serial_ids[] = {
 	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
 	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
@@ -877,10 +802,11 @@
 	.drv		= {
 		.name	= "serial_cs",
 	},
-	.attach		= serial_attach,
-	.event		= serial_event,
-	.detach		= serial_detach,
+	.probe		= serial_probe,
+	.remove		= serial_detach,
 	.id_table	= serial_ids,
+	.suspend	= serial_suspend,
+	.resume		= serial_resume,
 };
 
 static int __init init_serial_cs(void)
@@ -891,7 +817,6 @@
 static void __exit exit_serial_cs(void)
 {
 	pcmcia_unregister_driver(&serial_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_serial_cs);
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
index 57c0c6e..d3a7b0c 100644
--- a/drivers/telephony/ixj_pcmcia.c
+++ b/drivers/telephony/ixj_pcmcia.c
@@ -34,24 +34,19 @@
 	struct ixj *port;
 } ixj_info_t;
 
-static dev_link_t *ixj_attach(void);
-static void ixj_detach(dev_link_t *);
+static void ixj_detach(struct pcmcia_device *p_dev);
 static void ixj_config(dev_link_t * link);
 static void ixj_cs_release(dev_link_t * link);
-static int ixj_event(event_t event, int priority, event_callback_args_t * args);
-static dev_info_t dev_info = "ixj_cs";
-static dev_link_t *dev_list = NULL;
 
-static dev_link_t *ixj_attach(void)
+static int ixj_attach(struct pcmcia_device *p_dev)
 {
-	client_reg_t client_reg;
 	dev_link_t *link;
-	int ret;
+
 	DEBUG(0, "ixj_attach()\n");
 	/* Create new ixj device */
 	link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
 	if (!link)
-		return NULL;
+		return -ENOMEM;
 	memset(link, 0, sizeof(struct dev_link_t));
 	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
 	link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
@@ -61,44 +56,29 @@
 	link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
 	if (!link->priv) {
 		kfree(link);
-		return NULL;
+		return -ENOMEM;
 	}
 	memset(link->priv, 0, sizeof(struct ixj_info_t));
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		ixj_detach(link);
-		return NULL;
-	}
-	return link;
+
+	link->handle = p_dev;
+	p_dev->instance = link;
+
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	ixj_config(link);
+
+	return 0;
 }
 
-static void ixj_detach(dev_link_t * link)
+static void ixj_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
-	int ret;
+	dev_link_t *link = dev_to_instance(p_dev);
+
 	DEBUG(0, "ixj_detach(0x%p)\n", link);
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link)
-			break;
-	if (*linkp == NULL)
-		return;
+
 	link->state &= ~DEV_RELEASE_PENDING;
 	if (link->state & DEV_CONFIG)
 		ixj_cs_release(link);
-	if (link->handle) {
-		ret = pcmcia_deregister_client(link->handle);
-		if (ret != CS_SUCCESS)
-			cs_error(link->handle, DeregisterClient, ret);
-	}
-	/* Unlink device structure, free bits */
-	*linkp = link->next;
+
         kfree(link->priv);
         kfree(link);
 }
@@ -255,37 +235,25 @@
 	link->state &= ~DEV_CONFIG;
 }
 
-static int ixj_event(event_t event, int priority, event_callback_args_t * args)
+static int ixj_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
-	DEBUG(1, "ixj_event(0x%06x)\n", event);
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			link->state |= DEV_RELEASE_PENDING;
-			ixj_cs_release(link);
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		ixj_config(link);
-		break;
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (DEV_OK(link))
-			pcmcia_request_configuration(link->handle, &link->conf);
-		break;
-	}
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
+	return 0;
+}
+
+static int ixj_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (DEV_OK(link))
+		pcmcia_request_configuration(link->handle, &link->conf);
+
 	return 0;
 }
 
@@ -300,10 +268,11 @@
 	.drv		= {
 		.name	= "ixj_cs",
 	},
-	.attach		= ixj_attach,
-	.event		= ixj_event,
-	.detach		= ixj_detach,
+	.probe		= ixj_attach,
+	.remove		= ixj_detach,
 	.id_table	= ixj_ids,
+	.suspend	= ixj_suspend,
+	.resume		= ixj_resume,
 };
 
 static int __init ixj_pcmcia_init(void)
@@ -314,7 +283,6 @@
 static void ixj_pcmcia_exit(void)
 {
 	pcmcia_unregister_driver(&ixj_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(ixj_pcmcia_init);
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index a50c2bc..3639c3f 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -22,6 +22,7 @@
 obj-$(CONFIG_USB_PRINTER)	+= class/
 
 obj-$(CONFIG_USB_STORAGE)	+= storage/
+obj-$(CONFIG_USB)		+= storage/
 
 obj-$(CONFIG_USB_AIPTEK)	+= input/
 obj-$(CONFIG_USB_ATI_REMOTE)	+= input/
diff --git a/drivers/usb/atm/Kconfig b/drivers/usb/atm/Kconfig
index f429862..550ddfa 100644
--- a/drivers/usb/atm/Kconfig
+++ b/drivers/usb/atm/Kconfig
@@ -44,6 +44,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called cxacru.
 
+config USB_UEAGLEATM
+	tristate "ADI 930 and eagle USB DSL modem"
+	depends on USB_ATM
+	select FW_LOADER
+	help
+	  Say Y here if you have an ADSL USB modem based on the ADI 930
+	  or eagle chipset. In order to use your modem you will need to
+	  install firmwares and CMV (Command Management Variables); see
+	  <https://gna.org/projects/ueagleatm/> for details.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ueagle-atm.
+
 config USB_XUSBATM
 	tristate "Other USB DSL modem support"
 	depends on USB_ATM
diff --git a/drivers/usb/atm/Makefile b/drivers/usb/atm/Makefile
index 8509971..4c4a776 100644
--- a/drivers/usb/atm/Makefile
+++ b/drivers/usb/atm/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_USB_CXACRU)	+= cxacru.o
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= speedtch.o
+obj-$(CONFIG_USB_UEAGLEATM)	+= ueagle-atm.o
 obj-$(CONFIG_USB_ATM)		+= usbatm.o
 obj-$(CONFIG_USB_XUSBATM)	+= xusbatm.o
 
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 79861ee..af0a41e 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -787,6 +787,9 @@
 	{ /* V = Conexant			P = ADSL modem (Hasbani project)	*/
 		USB_DEVICE(0x0572, 0xcb00),	.driver_info = (unsigned long) &cxacru_cb00
 	},
+	{ /* V = Conexant             P = ADSL modem (Well PTI-800 */
+		USB_DEVICE(0x0572, 0xcb02),	.driver_info = (unsigned long) &cxacru_cb00
+	},
 	{ /* V = Conexant			P = ADSL modem				*/
 		USB_DEVICE(0x0572, 0xcb01),	.driver_info = (unsigned long) &cxacru_cb00
 	},
@@ -850,7 +853,6 @@
 }
 
 static struct usb_driver cxacru_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= cxacru_driver_name,
 	.probe		= cxacru_usb_probe,
 	.disconnect	= usbatm_usb_disconnect,
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index d0cbbb7..b283361 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -659,7 +659,6 @@
 static int speedtch_usb_probe(struct usb_interface *, const struct usb_device_id *);
 
 static struct usb_driver speedtch_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= speedtch_driver_name,
 	.probe		= speedtch_usb_probe,
 	.disconnect	= usbatm_usb_disconnect,
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
new file mode 100644
index 0000000..7d2a679
--- /dev/null
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -0,0 +1,1820 @@
+/*-
+ * Copyright (c) 2003, 2004
+ *	Damien Bergamini <damien.bergamini@free.fr>. All rights reserved.
+ *
+ * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr>
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ *
+ * GPL license :
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *
+ * HISTORY : some part of the code was base on ueagle 1.3 BSD driver,
+ * Damien Bergamini agree to put his code under a DUAL GPL/BSD license.
+ *
+ * The rest of the code was was rewritten from scratch.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/ctype.h>
+#include <linux/kthread.h>
+#include <linux/version.h>
+#include <asm/unaligned.h>
+
+#include "usbatm.h"
+
+#define EAGLEUSBVERSION "ueagle 1.1"
+
+
+/*
+ * Debug macros
+ */
+#define uea_dbg(usb_dev, format, args...)	\
+	do { \
+		if (debug >= 1) \
+			dev_dbg(&(usb_dev)->dev, \
+				"[ueagle-atm dbg] %s: " format, \
+					__FUNCTION__, ##args); \
+       } while (0)
+
+#define uea_vdbg(usb_dev, format, args...)	\
+	do { \
+		if (debug >= 2) \
+			dev_dbg(&(usb_dev)->dev, \
+				"[ueagle-atm vdbg]  " format, ##args); \
+       } while (0)
+
+#define uea_enters(usb_dev) \
+	uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__)
+
+#define uea_leaves(usb_dev) \
+	uea_vdbg(usb_dev, "leaving  %s\n", __FUNCTION__)
+
+#define uea_err(usb_dev, format,args...) \
+	dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args)
+
+#define uea_warn(usb_dev, format,args...) \
+	dev_warn(&(usb_dev)->dev ,"[Ueagle-atm] " format, ##args)
+
+#define uea_info(usb_dev, format,args...) \
+	dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args)
+
+struct uea_cmvs {
+	u32 address;
+	u16 offset;
+	u32 data;
+} __attribute__ ((packed));
+
+struct uea_softc {
+	struct usb_device *usb_dev;
+	struct usbatm_data *usbatm;
+
+	int modem_index;
+	unsigned int driver_info;
+
+	int booting;
+	int reset;
+
+	wait_queue_head_t sync_q;
+
+	struct task_struct *kthread;
+	u32 data;
+	wait_queue_head_t cmv_ack_wait;
+	int cmv_ack;
+
+	struct work_struct task;
+	u16 pageno;
+	u16 ovl;
+
+	const struct firmware *dsp_firm;
+	struct urb *urb_int;
+
+	u8 cmv_function;
+	u16 cmv_idx;
+	u32 cmv_address;
+	u16 cmv_offset;
+
+	/* keep in sync with eaglectl */
+	struct uea_stats {
+		struct {
+			u32 state;
+			u32 flags;
+			u32 mflags;
+			u32 vidcpe;
+			u32 vidco;
+			u32 dsrate;
+			u32 usrate;
+			u32 dsunc;
+			u32 usunc;
+			u32 dscorr;
+			u32 uscorr;
+			u32 txflow;
+			u32 rxflow;
+			u32 usattenuation;
+			u32 dsattenuation;
+			u32 dsmargin;
+			u32 usmargin;
+			u32 firmid;
+		} phy;
+	} stats;
+};
+
+/*
+ * Elsa IDs
+ */
+#define ELSA_VID		0x05CC
+#define ELSA_PID_PSTFIRM	0x3350
+#define ELSA_PID_PREFIRM	0x3351
+
+/*
+ * Sagem USB IDs
+ */
+#define EAGLE_VID		0x1110
+#define EAGLE_I_PID_PREFIRM	0x9010	/* Eagle I */
+#define EAGLE_I_PID_PSTFIRM	0x900F	/* Eagle I */
+
+#define EAGLE_IIC_PID_PREFIRM	0x9024	/* Eagle IIC */
+#define EAGLE_IIC_PID_PSTFIRM	0x9023	/* Eagle IIC */
+
+#define EAGLE_II_PID_PREFIRM	0x9022	/* Eagle II */
+#define EAGLE_II_PID_PSTFIRM	0x9021	/* Eagle II */
+
+/*
+ *  Eagle III Pid
+ */
+#define EAGLE_III_PID_PREFIRM	0x9032	/* Eagle III */
+#define EAGLE_III_PID_PSTFIRM	0x9031	/* Eagle III */
+
+/*
+ * USR USB IDs
+ */
+#define USR_VID			0x0BAF
+#define MILLER_A_PID_PREFIRM	0x00F2
+#define MILLER_A_PID_PSTFIRM	0x00F1
+#define MILLER_B_PID_PREFIRM	0x00FA
+#define MILLER_B_PID_PSTFIRM	0x00F9
+#define HEINEKEN_A_PID_PREFIRM	0x00F6
+#define HEINEKEN_A_PID_PSTFIRM	0x00F5
+#define HEINEKEN_B_PID_PREFIRM	0x00F8
+#define HEINEKEN_B_PID_PSTFIRM	0x00F7
+
+#define PREFIRM 0
+#define PSTFIRM (1<<7)
+enum {
+	ADI930 = 0,
+	EAGLE_I,
+	EAGLE_II,
+	EAGLE_III
+};
+
+/* macros for both struct usb_device_id and struct uea_softc */
+#define UEA_IS_PREFIRM(x) \
+	(!((x)->driver_info & PSTFIRM))
+#define UEA_CHIP_VERSION(x) \
+	((x)->driver_info & 0xf)
+
+#define IS_ISDN(sc) \
+	(le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)
+
+#define INS_TO_USBDEV(ins) ins->usb_dev
+
+#define GET_STATUS(data) \
+	((data >> 8) & 0xf)
+#define IS_OPERATIONAL(sc) \
+	(GET_STATUS(sc->stats.phy.state) == 2)
+
+/*
+ * Set of macros to handle unaligned data in the firmware blob.
+ * The FW_GET_BYTE() macro is provided only for consistency.
+ */
+
+#define FW_GET_BYTE(p)	*((__u8 *) (p))
+#define FW_GET_WORD(p)	le16_to_cpu(get_unaligned((__le16 *) (p)))
+#define FW_GET_LONG(p)	le32_to_cpu(get_unaligned((__le32 *) (p)))
+
+#define FW_DIR "ueagle-atm/"
+#define NB_MODEM 4
+
+#define BULK_TIMEOUT 300
+#define CTRL_TIMEOUT 1000
+
+#define ACK_TIMEOUT msecs_to_jiffies(1500)
+
+#define UEA_INTR_IFACE_NO 	0
+#define UEA_US_IFACE_NO		1
+#define UEA_DS_IFACE_NO		2
+
+#define FASTEST_ISO_INTF	8
+
+#define UEA_BULK_DATA_PIPE	0x02
+#define UEA_IDMA_PIPE		0x04
+#define UEA_INTR_PIPE		0x04
+#define UEA_ISO_DATA_PIPE	0x08
+
+#define UEA_SET_BLOCK    	0x0001
+#define UEA_SET_MODE     	0x0003
+#define UEA_SET_2183_DATA	0x0004
+#define UEA_SET_TIMEOUT		0x0011
+
+#define UEA_LOOPBACK_OFF	0x0002
+#define UEA_LOOPBACK_ON		0x0003
+#define UEA_BOOT_IDMA		0x0006
+#define UEA_START_RESET		0x0007
+#define UEA_END_RESET		0x0008
+
+#define UEA_SWAP_MAILBOX	(0x3fcd | 0x4000)
+#define UEA_MPTX_START		(0x3fce | 0x4000)
+#define UEA_MPTX_MAILBOX	(0x3fd6 | 0x4000)
+#define UEA_MPRX_MAILBOX	(0x3fdf | 0x4000)
+
+/* structure describing a block within a DSP page */
+struct block_info {
+	__le16 wHdr;
+#define UEA_BIHDR 0xabcd
+	__le16 wAddress;
+	__le16 wSize;
+	__le16 wOvlOffset;
+	__le16 wOvl;		/* overlay */
+	__le16 wLast;
+} __attribute__ ((packed));
+#define BLOCK_INFO_SIZE 12
+
+/* structure representing a CMV (Configuration and Management Variable) */
+struct cmv {
+	__le16 wPreamble;
+#define PREAMBLE 0x535c
+	__u8 bDirection;
+#define MODEMTOHOST 0x01
+#define HOSTTOMODEM 0x10
+	__u8 bFunction;
+#define FUNCTION_TYPE(f)    ((f) >> 4)
+#define MEMACCESS	0x1
+#define ADSLDIRECTIVE	0x7
+
+#define FUNCTION_SUBTYPE(f) ((f) & 0x0f)
+/* for MEMACCESS */
+#define REQUESTREAD	0x0
+#define REQUESTWRITE	0x1
+#define REPLYREAD	0x2
+#define REPLYWRITE	0x3
+/* for ADSLDIRECTIVE */
+#define KERNELREADY	0x0
+#define MODEMREADY	0x1
+
+#define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf))
+	__le16 wIndex;
+	__le32 dwSymbolicAddress;
+#define MAKESA(a, b, c, d)						\
+	(((c) & 0xff) << 24 |						\
+	 ((d) & 0xff) << 16 |						\
+	 ((a) & 0xff) << 8  |						\
+	 ((b) & 0xff))
+
+#define SA_CNTL MAKESA('C', 'N', 'T', 'L')
+#define SA_DIAG MAKESA('D', 'I', 'A', 'G')
+#define SA_INFO MAKESA('I', 'N', 'F', 'O')
+#define SA_OPTN MAKESA('O', 'P', 'T', 'N')
+#define SA_RATE MAKESA('R', 'A', 'T', 'E')
+#define SA_STAT MAKESA('S', 'T', 'A', 'T')
+	__le16 wOffsetAddress;
+	__le32 dwData;
+} __attribute__ ((packed));
+#define CMV_SIZE 16
+
+/* structure representing swap information */
+struct swap_info {
+	__u8 bSwapPageNo;
+	__u8 bOvl;		/* overlay */
+} __attribute__ ((packed));
+
+/* structure representing interrupt data */
+struct intr_pkt {
+	__u8 bType;
+	__u8 bNotification;
+	__le16 wValue;
+	__le16 wIndex;
+	__le16 wLength;
+	__le16 wInterrupt;
+#define INT_LOADSWAPPAGE 0x0001
+#define INT_INCOMINGCMV  0x0002
+	union {
+		struct {
+			struct swap_info swapinfo;
+			__le16 wDataSize;
+		} __attribute__ ((packed)) s1;
+
+		struct {
+			struct cmv cmv;
+			__le16 wDataSize;
+		} __attribute__ ((packed)) s2;
+	} __attribute__ ((packed)) u;
+#define bSwapPageNo	u.s1.swapinfo.bSwapPageNo
+#define bOvl		u.s1.swapinfo.bOvl
+} __attribute__ ((packed));
+#define INTR_PKT_SIZE 28
+
+static struct usb_driver uea_driver;
+static DECLARE_MUTEX(uea_semaphore);
+static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"};
+
+static int modem_index;
+static unsigned int debug;
+static int sync_wait[NB_MODEM];
+static char *cmv_file[NB_MODEM];
+
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)");
+module_param_array(sync_wait, bool, NULL, 0644);
+MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM");
+module_param_array(cmv_file, charp, NULL, 0644);
+MODULE_PARM_DESC(cmv_file,
+		"file name with configuration and management variables");
+
+#define UPDATE_ATM_STAT(type, val) \
+	do { \
+		if (sc->usbatm->atm_dev) \
+			sc->usbatm->atm_dev->type = val; \
+	} while (0)
+
+/* Firmware loading */
+#define LOAD_INTERNAL     0xA0
+#define F8051_USBCS       0x7f92
+
+/**
+ * uea_send_modem_cmd - Send a command for pre-firmware devices.
+ */
+static int uea_send_modem_cmd(struct usb_device *usb,
+		u16 addr, u16 size, u8 * buff)
+{
+	int ret = -ENOMEM;
+	u8 *xfer_buff;
+
+	xfer_buff = kmalloc(size, GFP_KERNEL);
+	if (xfer_buff) {
+		memcpy(xfer_buff, buff, size);
+		ret = usb_control_msg(usb,
+				      usb_sndctrlpipe(usb, 0),
+				      LOAD_INTERNAL,
+				      USB_DIR_OUT | USB_TYPE_VENDOR |
+				      USB_RECIP_DEVICE, addr, 0, xfer_buff,
+				      size, CTRL_TIMEOUT);
+		kfree(xfer_buff);
+	}
+
+	if (ret < 0)
+		return ret;
+
+	return (ret == size) ? 0 : -EIO;
+}
+
+static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context)
+{
+	struct usb_device *usb = context;
+	u8 *pfw, value;
+	u32 crc = 0;
+	int ret, size;
+
+	uea_enters(usb);
+	if (!fw_entry) {
+		uea_err(usb, "firmware is not available\n");
+		goto err;
+	}
+
+	pfw = fw_entry->data;
+	size = fw_entry->size;
+	if (size < 4)
+		goto err_fw_corrupted;
+
+	crc = FW_GET_LONG(pfw);
+	pfw += 4;
+	size -= 4;
+	if (crc32_be(0, pfw, size) != crc)
+		goto err_fw_corrupted;
+
+	/*
+	 * Start to upload formware : send reset
+	 */
+	value = 1;
+	ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value);
+
+	if (ret < 0) {
+		uea_err(usb, "modem reset failed with error %d\n", ret);
+		goto err;
+	}
+
+	while (size > 3) {
+		u8 len = FW_GET_BYTE(pfw);
+		u16 add = FW_GET_WORD(pfw + 1);
+
+		size -= len + 3;
+		if (size < 0)
+			goto err_fw_corrupted;
+
+		ret = uea_send_modem_cmd(usb, add, len, pfw + 3);
+		if (ret < 0) {
+			uea_err(usb, "uploading firmware data failed "
+					"with error %d\n", ret);
+			goto err;
+		}
+		pfw += len + 3;
+	}
+
+	if (size != 0)
+		goto err_fw_corrupted;
+
+	/*
+	 * Tell the modem we finish : de-assert reset
+	 */
+	value = 0;
+	ret = uea_send_modem_cmd(usb, F8051_USBCS, 1, &value);
+	if (ret < 0)
+		uea_err(usb, "modem de-assert failed with error %d\n", ret);
+	else
+		uea_info(usb, "firmware uploaded\n");
+
+	uea_leaves(usb);
+	return;
+
+err_fw_corrupted:
+	uea_err(usb, "firmware is corrupted\n");
+err:
+	uea_leaves(usb);
+}
+
+/**
+ * uea_load_firmware - Load usb firmware for pre-firmware devices.
+ */
+static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
+{
+	int ret;
+	char *fw_name = FW_DIR "eagle.fw";
+
+	uea_enters(usb);
+	uea_info(usb, "pre-firmware device, uploading firmware\n");
+
+	switch (ver) {
+	case ADI930:
+		fw_name = FW_DIR "adi930.fw";
+		break;
+	case EAGLE_I:
+		fw_name = FW_DIR "eagleI.fw";
+		break;
+	case EAGLE_II:
+		fw_name = FW_DIR "eagleII.fw";
+		break;
+	case EAGLE_III:
+		fw_name = FW_DIR "eagleIII.fw";
+		break;
+	}
+
+	ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware);
+	if (ret)
+		uea_err(usb, "firmware %s is not available\n", fw_name);
+	else
+		uea_info(usb, "loading firmware %s\n", fw_name);
+
+	uea_leaves(usb);
+	return ret;
+}
+
+/* modem management : dsp firmware, send/read CMV, monitoring statistic
+ */
+
+/*
+ * Make sure that the DSP code provided is safe to use.
+ */
+static int check_dsp(u8 *dsp, unsigned int len)
+{
+	u8 pagecount, blockcount;
+	u16 blocksize;
+	u32 pageoffset;
+	unsigned int i, j, p, pp;
+
+	pagecount = FW_GET_BYTE(dsp);
+	p = 1;
+
+	/* enough space for page offsets? */
+	if (p + 4 * pagecount > len)
+		return 1;
+
+	for (i = 0; i < pagecount; i++) {
+
+		pageoffset = FW_GET_LONG(dsp + p);
+		p += 4;
+
+		if (pageoffset == 0)
+			continue;
+
+		/* enough space for blockcount? */
+		if (pageoffset >= len)
+			return 1;
+
+		pp = pageoffset;
+		blockcount = FW_GET_BYTE(dsp + pp);
+		pp += 1;
+
+		for (j = 0; j < blockcount; j++) {
+
+			/* enough space for block header? */
+			if (pp + 4 > len)
+				return 1;
+
+			pp += 2;	/* skip blockaddr */
+			blocksize = FW_GET_WORD(dsp + pp);
+			pp += 2;
+
+			/* enough space for block data? */
+			if (pp + blocksize > len)
+				return 1;
+
+			pp += blocksize;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * send data to the idma pipe
+ * */
+static int uea_idma_write(struct uea_softc *sc, void *data, u32 size)
+{
+	int ret = -ENOMEM;
+	u8 *xfer_buff;
+	int bytes_read;
+
+	xfer_buff = kmalloc(size, GFP_KERNEL);
+	if (!xfer_buff) {
+		uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
+		return ret;
+	}
+
+	memcpy(xfer_buff, data, size);
+
+	ret = usb_bulk_msg(sc->usb_dev,
+			 usb_sndbulkpipe(sc->usb_dev, UEA_IDMA_PIPE),
+			 xfer_buff, size, &bytes_read, BULK_TIMEOUT);
+
+	kfree(xfer_buff);
+	if (ret < 0)
+		return ret;
+	if (size != bytes_read) {
+		uea_err(INS_TO_USBDEV(sc), "size != bytes_read %d %d\n", size,
+		       bytes_read);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int request_dsp(struct uea_softc *sc)
+{
+	int ret;
+	char *dsp_name;
+
+	if (UEA_CHIP_VERSION(sc) == ADI930) {
+		if (IS_ISDN(sc))
+			dsp_name = FW_DIR "DSP9i.bin";
+		else
+			dsp_name = FW_DIR "DSP9p.bin";
+	} else {
+		if (IS_ISDN(sc))
+			dsp_name = FW_DIR "DSPei.bin";
+		else
+			dsp_name = FW_DIR "DSPep.bin";
+	}
+
+	ret = request_firmware(&sc->dsp_firm,
+				dsp_name, &sc->usb_dev->dev);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "requesting firmware %s failed with error %d\n",
+		       dsp_name, ret);
+		return ret;
+	}
+
+	if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) {
+		uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
+		       dsp_name);
+		release_firmware(sc->dsp_firm);
+		sc->dsp_firm = NULL;
+		return -EILSEQ;
+	}
+
+	return 0;
+}
+
+/*
+ * The uea_load_page() function must be called within a process context
+ */
+static void uea_load_page(void *xsc)
+{
+	struct uea_softc *sc = xsc;
+	u16 pageno = sc->pageno;
+	u16 ovl = sc->ovl;
+	struct block_info bi;
+
+	u8 *p;
+	u8 pagecount, blockcount;
+	u16 blockaddr, blocksize;
+	u32 pageoffset;
+	int i;
+
+	/* reload firmware when reboot start and it's loaded already */
+	if (ovl == 0 && pageno == 0 && sc->dsp_firm) {
+		release_firmware(sc->dsp_firm);
+		sc->dsp_firm = NULL;
+	}
+
+	if (sc->dsp_firm == NULL && request_dsp(sc) < 0)
+		return;
+
+	p = sc->dsp_firm->data;
+	pagecount = FW_GET_BYTE(p);
+	p += 1;
+
+	if (pageno >= pagecount)
+		goto bad1;
+
+	p += 4 * pageno;
+	pageoffset = FW_GET_LONG(p);
+
+	if (pageoffset == 0)
+		goto bad1;
+
+	p = sc->dsp_firm->data + pageoffset;
+	blockcount = FW_GET_BYTE(p);
+	p += 1;
+
+	uea_dbg(INS_TO_USBDEV(sc),
+	       "sending %u blocks for DSP page %u\n", blockcount, pageno);
+
+	bi.wHdr = cpu_to_le16(UEA_BIHDR);
+	bi.wOvl = cpu_to_le16(ovl);
+	bi.wOvlOffset = cpu_to_le16(ovl | 0x8000);
+
+	for (i = 0; i < blockcount; i++) {
+		blockaddr = FW_GET_WORD(p);
+		p += 2;
+
+		blocksize = FW_GET_WORD(p);
+		p += 2;
+
+		bi.wSize = cpu_to_le16(blocksize);
+		bi.wAddress = cpu_to_le16(blockaddr);
+		bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0);
+
+		/* send block info through the IDMA pipe */
+		if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE))
+			goto bad2;
+
+		/* send block data through the IDMA pipe */
+		if (uea_idma_write(sc, p, blocksize))
+			goto bad2;
+
+		p += blocksize;
+	}
+
+	return;
+
+bad2:
+	uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", i);
+	return;
+bad1:
+	uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n",pageno);
+}
+
+static inline void wake_up_cmv_ack(struct uea_softc *sc)
+{
+	sc->cmv_ack = 1;
+	wake_up(&sc->cmv_ack_wait);
+}
+
+static inline int wait_cmv_ack(struct uea_softc *sc)
+{
+	int ret = wait_event_timeout(sc->cmv_ack_wait,
+						   sc->cmv_ack, ACK_TIMEOUT);
+	sc->cmv_ack = 0;
+
+	if (ret < 0)
+		return ret;
+
+	return (ret == 0) ? -ETIMEDOUT : 0;
+
+}
+
+#define UCDC_SEND_ENCAPSULATED_COMMAND 0x00
+
+static int uea_request(struct uea_softc *sc,
+		u16 value, u16 index, u16 size, void *data)
+{
+	u8 *xfer_buff;
+	int ret = -ENOMEM;
+
+	xfer_buff = kmalloc(size, GFP_KERNEL);
+	if (!xfer_buff) {
+		uea_err(INS_TO_USBDEV(sc), "can't allocate xfer_buff\n");
+		return ret;
+	}
+	memcpy(xfer_buff, data, size);
+
+	ret = usb_control_msg(sc->usb_dev, usb_sndctrlpipe(sc->usb_dev, 0),
+			      UCDC_SEND_ENCAPSULATED_COMMAND,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      value, index, xfer_buff, size, CTRL_TIMEOUT);
+
+	kfree(xfer_buff);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc), "usb_control_msg error %d\n", ret);
+		return ret;
+	}
+
+	if (ret != size) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "usb_control_msg send only %d bytes (instead of %d)\n",
+		       ret, size);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int uea_cmv(struct uea_softc *sc,
+		u8 function, u32 address, u16 offset, u32 data)
+{
+	struct cmv cmv;
+	int ret;
+
+	/* we send a request, but we expect a reply */
+	sc->cmv_function = function | 0x2;
+	sc->cmv_idx++;
+	sc->cmv_address = address;
+	sc->cmv_offset = offset;
+
+	cmv.wPreamble = cpu_to_le16(PREAMBLE);
+	cmv.bDirection = HOSTTOMODEM;
+	cmv.bFunction = function;
+	cmv.wIndex = cpu_to_le16(sc->cmv_idx);
+	put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress);
+	cmv.wOffsetAddress = cpu_to_le16(offset);
+	put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData);
+
+	ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv);
+	if (ret < 0)
+		return ret;
+	return wait_cmv_ack(sc);
+}
+
+static inline int uea_read_cmv(struct uea_softc *sc,
+		u32 address, u16 offset, u32 *data)
+{
+	int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD),
+			  address, offset, 0);
+	if (ret < 0)
+		uea_err(INS_TO_USBDEV(sc),
+			"reading cmv failed with error %d\n", ret);
+	else
+	 	*data = sc->data;
+
+	return ret;
+}
+
+static inline int uea_write_cmv(struct uea_softc *sc,
+		u32 address, u16 offset, u32 data)
+{
+	int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE),
+			  address, offset, data);
+	if (ret < 0)
+		uea_err(INS_TO_USBDEV(sc),
+			"writing cmv failed with error %d\n", ret);
+
+	return ret;
+}
+
+/*
+ * Monitor the modem and update the stat
+ * return 0 if everything is ok
+ * return < 0 if an error occurs (-EAGAIN reboot needed)
+ */
+static int uea_stat(struct uea_softc *sc)
+{
+	u32 data;
+	int ret;
+
+	uea_enters(INS_TO_USBDEV(sc));
+	data = sc->stats.phy.state;
+
+	ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state);
+	if (ret < 0)
+		return ret;
+
+	switch (GET_STATUS(sc->stats.phy.state)) {
+	case 0:		/* not yet synchronized */
+		uea_dbg(INS_TO_USBDEV(sc),
+		       "modem not yet synchronized\n");
+		return 0;
+
+	case 1:		/* initialization */
+		uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n");
+		return 0;
+
+	case 2:		/* operational */
+		uea_vdbg(INS_TO_USBDEV(sc), "modem operational\n");
+		break;
+
+	case 3:		/* fail ... */
+		uea_info(INS_TO_USBDEV(sc), "modem synchronization failed\n");
+		return -EAGAIN;
+
+	case 4 ... 6:	/* test state */
+		uea_warn(INS_TO_USBDEV(sc),
+				"modem in test mode - not supported\n");
+		return -EAGAIN;
+
+	case 7:		/* fast-retain ... */
+		uea_info(INS_TO_USBDEV(sc), "modem in fast-retain mode\n");
+		return 0;
+	default:
+		uea_err(INS_TO_USBDEV(sc), "modem invalid SW mode %d\n",
+			GET_STATUS(sc->stats.phy.state));
+		return -EAGAIN;
+	}
+
+	if (GET_STATUS(data) != 2) {
+		uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL);
+		uea_info(INS_TO_USBDEV(sc), "modem operational\n");
+
+		/* release the dsp firmware as it is not needed until
+		 * the next failure
+		 */
+		if (sc->dsp_firm) {
+			release_firmware(sc->dsp_firm);
+			sc->dsp_firm = NULL;
+		}
+
+		ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid);
+		if (ret < 0)
+			return ret;
+		uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n",
+				sc->stats.phy.firmid);
+	}
+
+	/* always update it as atm layer could not be init when we switch to
+	 * operational state
+	 */
+	UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND);
+
+	/* wake up processes waiting for synchronization */
+	wake_up(&sc->sync_q);
+
+	ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags);
+	if (ret < 0)
+		return ret;
+	sc->stats.phy.mflags |= sc->stats.phy.flags;
+
+	/* in case of a flags ( for example delineation LOSS (& 0x10)),
+	 * we check the status again in order to detect the failure earlier
+	 */
+	if (sc->stats.phy.flags) {
+		uea_dbg(INS_TO_USBDEV(sc), "Stat flag = %d\n",
+		       sc->stats.phy.flags);
+		return 0;
+	}
+
+	ret = uea_read_cmv(sc, SA_RATE, 0, &data);
+	if (ret < 0)
+		return ret;
+
+	/* in bulk mode the modem have problem with high rate
+	 * changing internal timing could improve things, but the
+	 * value is misterious.
+	 * ADI930 don't support it (-EPIPE error).
+	 */
+	if (UEA_CHIP_VERSION(sc) != ADI930
+		    && sc->stats.phy.dsrate != (data >> 16) * 32) {
+		/* Original timming from ADI(used in windows driver)
+		 * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits
+		 */
+		u16 timeout = (data <= 0x20ffff) ? 0 : 1;
+		ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL);
+		uea_info(INS_TO_USBDEV(sc),
+				"setting new timeout %d%s\n", timeout,
+				ret < 0?" failed":"");
+	}
+	sc->stats.phy.dsrate = (data >> 16) * 32;
+	sc->stats.phy.usrate = (data & 0xffff) * 32;
+	UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424);
+
+	ret = uea_read_cmv(sc, SA_DIAG, 23, &data);
+	if (ret < 0)
+		return ret;
+	sc->stats.phy.dsattenuation = (data & 0xff) / 2;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 47, &data);
+	if (ret < 0)
+		return ret;
+	sc->stats.phy.usattenuation = (data & 0xff) / 2;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc);
+	if (ret < 0)
+		return ret;
+
+	/* only for atu-c */
+	ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr);
+	if (ret < 0)
+		return ret;
+
+	/* only for atu-c */
+	ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco);
+	if (ret < 0)
+		return ret;
+
+	ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int request_cmvs(struct uea_softc *sc,
+		 struct uea_cmvs **cmvs, const struct firmware **fw)
+{
+	int ret, size;
+	u8 *data;
+	char *file;
+	static char cmv_name[256] = FW_DIR;
+
+	if (cmv_file[sc->modem_index] == NULL) {
+		if (UEA_CHIP_VERSION(sc) == ADI930)
+			file = (IS_ISDN(sc)) ? "CMV9i.bin" : "CMV9p.bin";
+		else
+			file = (IS_ISDN(sc)) ? "CMVei.bin" : "CMVep.bin";
+	} else
+		file = cmv_file[sc->modem_index];
+
+	strcpy(cmv_name, FW_DIR);
+	strlcat(cmv_name, file, sizeof(cmv_name));
+
+	ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "requesting firmware %s failed with error %d\n",
+		       cmv_name, ret);
+		return ret;
+	}
+
+	data = (u8 *) (*fw)->data;
+	size = *data * sizeof(struct uea_cmvs) + 1;
+	if (size != (*fw)->size) {
+		uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
+		       cmv_name);
+		release_firmware(*fw);
+		return -EILSEQ;
+	}
+
+	*cmvs = (struct uea_cmvs *)(data + 1);
+	return *data;
+}
+
+/* Start boot post firmware modem:
+ * - send reset commands through usb control pipe
+ * - start workqueue for DSP loading
+ * - send CMV options to modem
+ */
+
+static int uea_start_reset(struct uea_softc *sc)
+{
+	u16 zero = 0;	/* ;-) */
+	int i, len, ret;
+	struct uea_cmvs *cmvs;
+	const struct firmware *cmvs_fw;
+
+	uea_enters(INS_TO_USBDEV(sc));
+	uea_info(INS_TO_USBDEV(sc), "(re)booting started\n");
+
+	sc->booting = 1;
+	UPDATE_ATM_STAT(signal, ATM_PHY_SIG_LOST);
+
+	/* reset statistics */
+	memset(&sc->stats, 0, sizeof(struct uea_stats));
+
+	/* tell the modem that we want to boot in IDMA mode */
+	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
+	uea_request(sc, UEA_SET_MODE, UEA_BOOT_IDMA, 0, NULL);
+
+ 	/* enter reset mode */
+	uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL);
+
+	/* original driver use 200ms, but windows driver use 100ms */
+	msleep(100);
+
+	/* leave reset mode */
+	uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL);
+
+ 	/* clear tx and rx mailboxes */
+	uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero);
+	uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero);
+	uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero);
+
+	msleep(1000);
+	sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY);
+	sc->booting = 0;
+
+	/* start loading DSP */
+	sc->pageno = 0;
+	sc->ovl = 0;
+	schedule_work(&sc->task);
+
+	/* wait for modem ready CMV */
+	ret = wait_cmv_ack(sc);
+	if (ret < 0)
+		return ret;
+
+	/* Enter in R-IDLE (cmv) until instructed otherwise */
+	ret = uea_write_cmv(sc, SA_CNTL, 0, 1);
+	if (ret < 0)
+		return ret;
+
+	/* get options */
+ 	ret = len = request_cmvs(sc, &cmvs, &cmvs_fw);
+	if (ret < 0)
+		return ret;
+
+	/* send options */
+	for (i = 0; i < len; i++) {
+		ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address),
+					FW_GET_WORD(&cmvs[i].offset),
+					FW_GET_LONG(&cmvs[i].data));
+		if (ret < 0)
+			goto out;
+	}
+	/* Enter in R-ACT-REQ */
+	ret = uea_write_cmv(sc, SA_CNTL, 0, 2);
+out:
+	release_firmware(cmvs_fw);
+	sc->reset = 0;
+	uea_leaves(INS_TO_USBDEV(sc));
+	return ret;
+}
+
+/*
+ * In case of an error wait 1s before rebooting the modem
+ * if the modem don't request reboot (-EAGAIN).
+ * Monitor the modem every 1s.
+ */
+
+static int uea_kthread(void *data)
+{
+	struct uea_softc *sc = data;
+	int ret = -EAGAIN;
+
+	uea_enters(INS_TO_USBDEV(sc));
+	while (!kthread_should_stop()) {
+		if (ret < 0 || sc->reset)
+			ret = uea_start_reset(sc);
+		if (!ret)
+			ret = uea_stat(sc);
+		if (ret != -EAGAIN)
+			msleep(1000);
+	}
+	uea_leaves(INS_TO_USBDEV(sc));
+	return ret;
+}
+
+/* Load second usb firmware for ADI930 chip */
+static int load_XILINX_firmware(struct uea_softc *sc)
+{
+	const struct firmware *fw_entry;
+	int ret, size, u, ln;
+	u8 *pfw, value;
+	char *fw_name = FW_DIR "930-fpga.bin";
+
+	uea_enters(INS_TO_USBDEV(sc));
+
+	ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev);
+	if (ret) {
+		uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n",
+		       fw_name);
+		goto err0;
+	}
+
+	pfw = fw_entry->data;
+	size = fw_entry->size;
+	if (size != 0x577B) {
+		uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n",
+		       fw_name);
+		ret = -EILSEQ;
+		goto err1;
+	}
+	for (u = 0; u < size; u += ln) {
+		ln = min(size - u, 64);
+		ret = uea_request(sc, 0xe, 0, ln, pfw + u);
+		if (ret < 0) {
+			uea_err(INS_TO_USBDEV(sc),
+			       "elsa download data failed (%d)\n", ret);
+			goto err1;
+		}
+	}
+
+	/* finish to send the fpga
+	 */
+	ret = uea_request(sc, 0xe, 1, 0, NULL);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc),
+				"elsa download data failed (%d)\n", ret);
+		goto err1;
+	}
+
+	/*
+	 * Tell the modem we finish : de-assert reset
+	 */
+	value = 0;
+	ret = uea_send_modem_cmd(sc->usb_dev, 0xe, 1, &value);
+	if (ret < 0)
+		uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret);
+
+
+err1:
+	release_firmware(fw_entry);
+err0:
+	uea_leaves(INS_TO_USBDEV(sc));
+	return ret;
+}
+
+static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv)
+{
+	uea_enters(INS_TO_USBDEV(sc));
+	if (le16_to_cpu(cmv->wPreamble) != PREAMBLE)
+		goto bad1;
+
+	if (cmv->bDirection != MODEMTOHOST)
+		goto bad1;
+
+	/* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to
+	 * the first MEMACESS cmv. Ignore it...
+	 */
+	if (cmv->bFunction != sc->cmv_function) {
+		if (UEA_CHIP_VERSION(sc) == ADI930
+				&& cmv->bFunction ==  MAKEFUNCTION(2, 2)) {
+			cmv->wIndex = cpu_to_le16(sc->cmv_idx);
+			put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress);
+			cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset);
+		}
+		else
+			goto bad2;
+	}
+
+	if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) {
+		wake_up_cmv_ack(sc);
+		return;
+	}
+
+	/* in case of MEMACCESS */
+	if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx ||
+	    le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) !=
+	    sc->cmv_address
+	    || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset)
+		goto bad2;
+
+	sc->data = le32_to_cpu(get_unaligned(&cmv->dwData));
+	sc->data = sc->data << 16 | sc->data >> 16;
+
+	wake_up_cmv_ack(sc);
+	return;
+
+bad2:
+	uea_err(INS_TO_USBDEV(sc), "unexpected cmv received,"
+			"Function : %d, Subfunction : %d\n",
+			FUNCTION_TYPE(cmv->bFunction),
+			FUNCTION_SUBTYPE(cmv->bFunction));
+	return;
+
+bad1:
+	uea_err(INS_TO_USBDEV(sc), "invalid cmv received, "
+			"wPreamble %d, bDirection %d\n",
+			le16_to_cpu(cmv->wPreamble), cmv->bDirection);
+}
+
+/*
+ * interrupt handler
+ */
+static void uea_intr(struct urb *urb, struct pt_regs *regs)
+{
+	struct uea_softc *sc = (struct uea_softc *)urb->context;
+	struct intr_pkt *intr;
+	uea_enters(INS_TO_USBDEV(sc));
+
+	if (urb->status < 0) {
+		uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n",
+		       urb->status);
+		return;
+	}
+
+	intr = (struct intr_pkt *) urb->transfer_buffer;
+
+	/* device-to-host interrupt */
+	if (intr->bType != 0x08 || sc->booting) {
+		uea_err(INS_TO_USBDEV(sc), "wrong intr\n");
+		// rebooting ?
+		// sc->reset = 1;
+		goto resubmit;
+	}
+
+	switch (le16_to_cpu(intr->wInterrupt)) {
+	case INT_LOADSWAPPAGE:
+		sc->pageno = intr->bSwapPageNo;
+		sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4;
+		schedule_work(&sc->task);
+		break;
+
+	case INT_INCOMINGCMV:
+		uea_dispatch_cmv(sc, &intr->u.s2.cmv);
+		break;
+
+	default:
+		uea_err(INS_TO_USBDEV(sc), "unknown intr %u\n",
+		       le16_to_cpu(intr->wInterrupt));
+	}
+
+resubmit:
+	usb_submit_urb(sc->urb_int, GFP_ATOMIC);
+}
+
+/*
+ * Start the modem : init the data and start kernel thread
+ */
+static int uea_boot(struct uea_softc *sc)
+{
+	int ret;
+	struct intr_pkt *intr;
+
+	uea_enters(INS_TO_USBDEV(sc));
+
+	INIT_WORK(&sc->task, uea_load_page, sc);
+	init_waitqueue_head(&sc->sync_q);
+	init_waitqueue_head(&sc->cmv_ack_wait);
+
+	if (UEA_CHIP_VERSION(sc) == ADI930)
+		load_XILINX_firmware(sc);
+
+	intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL);
+	if (!intr) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "cannot allocate interrupt package\n");
+		uea_leaves(INS_TO_USBDEV(sc));
+		return -ENOMEM;
+	}
+
+	sc->urb_int = usb_alloc_urb(0, GFP_KERNEL);
+	if (!sc->urb_int) {
+		uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n");
+		goto err;
+	}
+
+	usb_fill_int_urb(sc->urb_int, sc->usb_dev,
+			 usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE),
+			 intr, INTR_PKT_SIZE, uea_intr, sc,
+			 sc->usb_dev->actconfig->interface[0]->altsetting[0].
+			 endpoint[0].desc.bInterval);
+
+	ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);
+	if (ret < 0) {
+		uea_err(INS_TO_USBDEV(sc),
+		       "urb submition failed with error %d\n", ret);
+		goto err1;
+	}
+
+	sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");
+	if (sc->kthread == ERR_PTR(-ENOMEM)) {
+		uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
+		goto err2;
+	}
+
+	uea_leaves(INS_TO_USBDEV(sc));
+	return 0;
+
+err2:
+	usb_kill_urb(sc->urb_int);
+err1:
+	kfree(intr);
+err:
+	usb_free_urb(sc->urb_int);
+	uea_leaves(INS_TO_USBDEV(sc));
+	return -ENOMEM;
+}
+
+/*
+ * Stop the modem : kill kernel thread and free data
+ */
+static void uea_stop(struct uea_softc *sc)
+{
+	int ret;
+	uea_enters(INS_TO_USBDEV(sc));
+	ret = kthread_stop(sc->kthread);
+	uea_info(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);
+
+	/* stop any pending boot process */
+	flush_scheduled_work();
+
+	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);
+
+	usb_kill_urb(sc->urb_int);
+	kfree(sc->urb_int->transfer_buffer);
+	usb_free_urb(sc->urb_int);
+
+	if (sc->dsp_firm)
+		release_firmware(sc->dsp_firm);
+	uea_leaves(INS_TO_USBDEV(sc));
+}
+
+/* syfs interface */
+static struct uea_softc *dev_to_uea(struct device *dev)
+{
+	struct usb_interface *intf;
+	struct usbatm_data *usbatm;
+
+	intf = to_usb_interface(dev);
+	if (!intf)
+		return NULL;
+
+	usbatm = usb_get_intfdata(intf);
+	if (!usbatm)
+		return NULL;
+
+	return usbatm->driver_data;
+}
+
+static ssize_t read_status(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	int ret = -ENODEV;
+	struct uea_softc *sc;
+
+	down(&uea_semaphore);
+	sc = dev_to_uea(dev);
+	if (!sc)
+		goto out;
+	ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state);
+out:
+	up(&uea_semaphore);
+	return ret;
+}
+
+static ssize_t reboot(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int ret = -ENODEV;
+	struct uea_softc *sc;
+
+	down(&uea_semaphore);
+	sc = dev_to_uea(dev);
+	if (!sc)
+		goto out;
+	sc->reset = 1;
+	ret = count;
+out:
+	up(&uea_semaphore);
+	return ret;
+}
+
+static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot);
+
+static ssize_t read_human_status(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	int ret = -ENODEV;
+	struct uea_softc *sc;
+
+	down(&uea_semaphore);
+	sc = dev_to_uea(dev);
+	if (!sc)
+		goto out;
+
+	switch (GET_STATUS(sc->stats.phy.state)) {
+	case 0:
+		ret = sprintf(buf, "Modem is booting\n");
+		break;
+	case 1:
+		ret = sprintf(buf, "Modem is initializing\n");
+		break;
+	case 2:
+		ret = sprintf(buf, "Modem is operational\n");
+		break;
+	default:
+		ret = sprintf(buf, "Modem synchronization failed\n");
+		break;
+	}
+out:
+	up(&uea_semaphore);
+	return ret;
+}
+
+static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL);
+
+static ssize_t read_delin(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	int ret = -ENODEV;
+	struct uea_softc *sc;
+
+	down(&uea_semaphore);
+	sc = dev_to_uea(dev);
+	if (!sc)
+		goto out;
+
+	if (sc->stats.phy.flags & 0x0C00)
+		ret = sprintf(buf, "ERROR\n");
+	else if (sc->stats.phy.flags & 0x0030)
+		ret = sprintf(buf, "LOSS\n");
+	else
+		ret = sprintf(buf, "GOOD\n");
+out:
+	up(&uea_semaphore);
+	return ret;
+}
+
+static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL);
+
+#define UEA_ATTR(name, reset) 					\
+								\
+static ssize_t read_##name(struct device *dev, 			\
+		struct device_attribute *attr, char *buf)	\
+{ 								\
+	int ret = -ENODEV; 					\
+	struct uea_softc *sc; 					\
+ 								\
+	down(&uea_semaphore); 					\
+	sc = dev_to_uea(dev);					\
+	if (!sc) 						\
+		goto out; 					\
+	ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.name);	\
+	if (reset)						\
+		sc->stats.phy.name = 0;				\
+out: 								\
+	up(&uea_semaphore); 					\
+	return ret; 						\
+} 								\
+								\
+static DEVICE_ATTR(stat_##name, S_IRUGO, read_##name, NULL)
+
+UEA_ATTR(mflags, 1);
+UEA_ATTR(vidcpe, 0);
+UEA_ATTR(usrate, 0);
+UEA_ATTR(dsrate, 0);
+UEA_ATTR(usattenuation, 0);
+UEA_ATTR(dsattenuation, 0);
+UEA_ATTR(usmargin, 0);
+UEA_ATTR(dsmargin, 0);
+UEA_ATTR(txflow, 0);
+UEA_ATTR(rxflow, 0);
+UEA_ATTR(uscorr, 0);
+UEA_ATTR(dscorr, 0);
+UEA_ATTR(usunc, 0);
+UEA_ATTR(dsunc, 0);
+
+/* Retrieve the device End System Identifier (MAC) */
+
+#define htoi(x) (isdigit(x) ? x-'0' : toupper(x)-'A'+10)
+static int uea_getesi(struct uea_softc *sc, u_char * esi)
+{
+	unsigned char mac_str[2 * ETH_ALEN + 1];
+	int i;
+	if (usb_string
+	    (sc->usb_dev, sc->usb_dev->descriptor.iSerialNumber, mac_str,
+	     sizeof(mac_str)) != 2 * ETH_ALEN)
+		return 1;
+
+	for (i = 0; i < ETH_ALEN; i++)
+		esi[i] = htoi(mac_str[2 * i]) * 16 + htoi(mac_str[2 * i + 1]);
+
+	return 0;
+}
+
+/* ATM stuff */
+static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev)
+{
+	struct uea_softc *sc = usbatm->driver_data;
+
+	return uea_getesi(sc, atm_dev->esi);
+}
+
+static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf)
+{
+	struct uea_softc *sc = usbatm->driver_data;
+
+	wait_event(sc->sync_q, IS_OPERATIONAL(sc));
+
+	return 0;
+
+}
+
+static int claim_interface(struct usb_device *usb_dev,
+			   struct usbatm_data *usbatm, int ifnum)
+{
+	int ret;
+	struct usb_interface *intf = usb_ifnum_to_if(usb_dev, ifnum);
+
+	if (!intf) {
+		uea_err(usb_dev, "interface %d not found\n", ifnum);
+		return -ENODEV;
+	}
+
+	ret = usb_driver_claim_interface(&uea_driver, intf, usbatm);
+	if (ret != 0)
+		uea_err(usb_dev, "can't claim interface %d, error %d\n", ifnum,
+		       ret);
+	return ret;
+}
+
+static void create_fs_entries(struct uea_softc *sc, struct usb_interface *intf)
+{
+	/* sysfs interface */
+	device_create_file(&intf->dev, &dev_attr_stat_status);
+	device_create_file(&intf->dev, &dev_attr_stat_mflags);
+	device_create_file(&intf->dev, &dev_attr_stat_human_status);
+	device_create_file(&intf->dev, &dev_attr_stat_delin);
+	device_create_file(&intf->dev, &dev_attr_stat_vidcpe);
+	device_create_file(&intf->dev, &dev_attr_stat_usrate);
+	device_create_file(&intf->dev, &dev_attr_stat_dsrate);
+	device_create_file(&intf->dev, &dev_attr_stat_usattenuation);
+	device_create_file(&intf->dev, &dev_attr_stat_dsattenuation);
+	device_create_file(&intf->dev, &dev_attr_stat_usmargin);
+	device_create_file(&intf->dev, &dev_attr_stat_dsmargin);
+	device_create_file(&intf->dev, &dev_attr_stat_txflow);
+	device_create_file(&intf->dev, &dev_attr_stat_rxflow);
+	device_create_file(&intf->dev, &dev_attr_stat_uscorr);
+	device_create_file(&intf->dev, &dev_attr_stat_dscorr);
+	device_create_file(&intf->dev, &dev_attr_stat_usunc);
+	device_create_file(&intf->dev, &dev_attr_stat_dsunc);
+}
+
+static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
+		   const struct usb_device_id *id, int *heavy)
+{
+	struct usb_device *usb = interface_to_usbdev(intf);
+	struct uea_softc *sc;
+	int ret, ifnum = intf->altsetting->desc.bInterfaceNumber;
+
+	uea_enters(usb);
+
+	/* interface 0 is for firmware/monitoring */
+	if (ifnum != UEA_INTR_IFACE_NO)
+		return -ENODEV;
+
+	*heavy = sync_wait[modem_index];
+
+	/* interface 1 is for outbound traffic */
+	ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO);
+	if (ret < 0)
+		return ret;
+
+	/* ADI930 has only 2 interfaces and inbound traffic
+	 * is on interface 1
+	 */
+	if (UEA_CHIP_VERSION(id) != ADI930) {
+		/* interface 2 is for inbound traffic */
+		ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO);
+		if (ret < 0)
+			return ret;
+	}
+
+	sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL);
+	if (!sc) {
+		uea_err(INS_TO_USBDEV(sc), "uea_init: not enough memory !\n");
+		return -ENOMEM;
+	}
+
+	sc->usb_dev = usb;
+	usbatm->driver_data = sc;
+	sc->usbatm = usbatm;
+	sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0;
+	sc->driver_info = id->driver_info;
+
+	ret = uea_boot(sc);
+	if (ret < 0) {
+		kfree(sc);
+		return ret;
+	}
+
+	create_fs_entries(sc, intf);
+	return 0;
+}
+
+static void destroy_fs_entries(struct uea_softc *sc, struct usb_interface *intf)
+{
+	/* sysfs interface */
+	device_remove_file(&intf->dev, &dev_attr_stat_status);
+	device_remove_file(&intf->dev, &dev_attr_stat_mflags);
+	device_remove_file(&intf->dev, &dev_attr_stat_human_status);
+	device_remove_file(&intf->dev, &dev_attr_stat_delin);
+	device_remove_file(&intf->dev, &dev_attr_stat_vidcpe);
+	device_remove_file(&intf->dev, &dev_attr_stat_usrate);
+	device_remove_file(&intf->dev, &dev_attr_stat_dsrate);
+	device_remove_file(&intf->dev, &dev_attr_stat_usattenuation);
+	device_remove_file(&intf->dev, &dev_attr_stat_dsattenuation);
+	device_remove_file(&intf->dev, &dev_attr_stat_usmargin);
+	device_remove_file(&intf->dev, &dev_attr_stat_dsmargin);
+	device_remove_file(&intf->dev, &dev_attr_stat_txflow);
+	device_remove_file(&intf->dev, &dev_attr_stat_rxflow);
+	device_remove_file(&intf->dev, &dev_attr_stat_uscorr);
+	device_remove_file(&intf->dev, &dev_attr_stat_dscorr);
+	device_remove_file(&intf->dev, &dev_attr_stat_usunc);
+	device_remove_file(&intf->dev, &dev_attr_stat_dsunc);
+}
+
+static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf)
+{
+	struct uea_softc *sc = usbatm->driver_data;
+
+	destroy_fs_entries(sc, intf);
+	uea_stop(sc);
+	kfree(sc);
+}
+
+static struct usbatm_driver uea_usbatm_driver = {
+	.driver_name = "ueagle-atm",
+	.owner = THIS_MODULE,
+	.bind = uea_bind,
+	.atm_start = uea_atm_open,
+	.unbind = uea_unbind,
+	.heavy_init = uea_heavy,
+	.in = UEA_BULK_DATA_PIPE,
+	.out = UEA_BULK_DATA_PIPE,
+};
+
+static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_device *usb = interface_to_usbdev(intf);
+
+	uea_enters(usb);
+	uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s\n",
+	       le16_to_cpu(usb->descriptor.idVendor),
+	       le16_to_cpu(usb->descriptor.idProduct),
+	       chip_name[UEA_CHIP_VERSION(id)]);
+
+	usb_reset_device(usb);
+
+	if (UEA_IS_PREFIRM(id))
+		return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
+
+	return usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+}
+
+static void uea_disconnect(struct usb_interface *intf)
+{
+	struct usb_device *usb = interface_to_usbdev(intf);
+	int ifnum = intf->altsetting->desc.bInterfaceNumber;
+	uea_enters(usb);
+
+	/* ADI930 has 2 interfaces and eagle 3 interfaces.
+	 * Pre-firmware device has one interface
+	 */
+	if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) {
+		down(&uea_semaphore);
+		usbatm_usb_disconnect(intf);
+		up(&uea_semaphore);
+		uea_info(usb, "ADSL device removed\n");
+	}
+
+	uea_leaves(usb);
+}
+
+/*
+ * List of supported VID/PID
+ */
+static const struct usb_device_id uea_ids[] = {
+	{USB_DEVICE(ELSA_VID,	ELSA_PID_PREFIRM),	.driver_info = ADI930 | PREFIRM},
+	{USB_DEVICE(ELSA_VID,	ELSA_PID_PSTFIRM),	.driver_info = ADI930 | PSTFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_I_PID_PREFIRM),	.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_I_PID_PSTFIRM),	.driver_info = EAGLE_I | PSTFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_II_PID_PREFIRM),	.driver_info = EAGLE_II | PREFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_II_PID_PSTFIRM),	.driver_info = EAGLE_II | PSTFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_IIC_PID_PREFIRM),	.driver_info = EAGLE_II | PREFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_IIC_PID_PSTFIRM),	.driver_info = EAGLE_II | PSTFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_III_PID_PREFIRM),	.driver_info = EAGLE_III | PREFIRM},
+	{USB_DEVICE(EAGLE_VID,	EAGLE_III_PID_PSTFIRM),	.driver_info = EAGLE_III | PSTFIRM},
+	{USB_DEVICE(USR_VID,	MILLER_A_PID_PREFIRM),	.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(USR_VID,	MILLER_A_PID_PSTFIRM),	.driver_info = EAGLE_I | PSTFIRM},
+	{USB_DEVICE(USR_VID,	MILLER_B_PID_PREFIRM),	.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(USR_VID,	MILLER_B_PID_PSTFIRM),	.driver_info = EAGLE_I | PSTFIRM},
+	{USB_DEVICE(USR_VID,	HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(USR_VID,	HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM},
+	{USB_DEVICE(USR_VID,	HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM},
+	{USB_DEVICE(USR_VID,	HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM},
+	{}
+};
+
+/*
+ * USB driver descriptor
+ */
+static struct usb_driver uea_driver = {
+	.name = "ueagle-atm",
+	.id_table = uea_ids,
+	.probe = uea_probe,
+	.disconnect = uea_disconnect,
+};
+
+MODULE_DEVICE_TABLE(usb, uea_ids);
+
+/**
+ * uea_init - Initialize the module.
+ *      Register to USB subsystem
+ */
+static int __init uea_init(void)
+{
+	printk(KERN_INFO "[ueagle-atm] driver " EAGLEUSBVERSION " loaded\n");
+
+	usb_register(&uea_driver);
+
+	return 0;
+}
+
+module_init(uea_init);
+
+/**
+ * uea_exit  -  Destroy module
+ *    Deregister with USB subsystem
+ */
+static void __exit uea_exit(void)
+{
+	/*
+	 * This calls automatically the uea_disconnect method if necessary:
+	 */
+	usb_deregister(&uea_driver);
+
+	printk(KERN_INFO "[ueagle-atm] driver unloaded\n");
+}
+
+module_exit(uea_exit);
+
+MODULE_AUTHOR("Damien Bergamini/Matthieu Castet/Stanislaw W. Gruszka");
+MODULE_DESCRIPTION("ADI 930/Eagle USB ADSL Modem driver");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index c466739..9baa629 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -646,14 +646,14 @@
 	kfree(instance);
 }
 
-void usbatm_get_instance(struct usbatm_data *instance)
+static void usbatm_get_instance(struct usbatm_data *instance)
 {
 	dbg("%s", __func__);
 
 	kref_get(&instance->refcount);
 }
 
-void usbatm_put_instance(struct usbatm_data *instance)
+static void usbatm_put_instance(struct usbatm_data *instance)
 {
 	dbg("%s", __func__);
 
@@ -879,7 +879,7 @@
 
  fail:
 	instance->atm_dev = NULL;
-	shutdown_atm_dev(atm_dev); /* usbatm_atm_dev_close will eventually be called */
+	atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */
 	return ret;
 }
 
@@ -1164,7 +1164,7 @@
 
 	/* ATM finalize */
 	if (instance->atm_dev)
-		shutdown_atm_dev(instance->atm_dev);
+		atm_dev_deregister(instance->atm_dev);
 
 	usbatm_put_instance(instance);	/* taken in usbatm_usb_probe */
 }
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 7fe7fb4..5c76e3a 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -140,7 +140,6 @@
 }
 
 static struct usb_driver xusbatm_usb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= xusbatm_driver_name,
 	.probe		= xusbatm_usb_probe,
 	.disconnect	= usbatm_usb_disconnect,
diff --git a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
index 5085827..3ad9ee8 100644
--- a/drivers/usb/class/audio.c
+++ b/drivers/usb/class/audio.c
@@ -2732,7 +2732,6 @@
 MODULE_DEVICE_TABLE (usb, usb_audio_ids);
 
 static struct usb_driver usb_audio_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"audio",
 	.probe =	usb_audio_probe,
 	.disconnect =	usb_audio_disconnect,
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 1b47514..248279e 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -6,6 +6,7 @@
  * Copyright (c) 1999 Johannes Erdfelt	<johannes@erdfelt.com>
  * Copyright (c) 2000 Vojtech Pavlik	<vojtech@suse.cz>
  * Copyright (c) 2004 Oliver Neukum	<oliver@neukum.name>
+ * Copyright (c) 2005 David Kubicek	<dave@awk.cz>
  *
  * USB Abstract Control Model driver for USB modems and ISDN adapters
  *
@@ -29,6 +30,7 @@
  *		config we want, sysadmin changes bConfigurationValue in sysfs.
  *	v0.23 - use softirq for rx processing, as needed by tty layer
  *	v0.24 - change probe method to evaluate CDC union descriptor
+ *	v0.25 - downstream tasks paralelized to maximize throughput
  */
 
 /*
@@ -63,14 +65,15 @@
 #include <linux/usb_cdc.h>
 #include <asm/byteorder.h>
 #include <asm/unaligned.h>
+#include <linux/list.h>
 
 #include "cdc-acm.h"
 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.23"
-#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik"
+#define DRIVER_VERSION "v0.25"
+#define DRIVER_AUTHOR "Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik, David Kubicek"
 #define DRIVER_DESC "USB Abstract Control Model driver for USB modems and ISDN adapters"
 
 static struct usb_driver acm_driver;
@@ -284,7 +287,9 @@
 /* data interface returns incoming bytes, or we got unthrottled */
 static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
 {
-	struct acm *acm = urb->context;
+	struct acm_rb *buf;
+	struct acm_ru *rcv = urb->context;
+	struct acm *acm = rcv->instance;
 	dbg("Entering acm_read_bulk with status %d\n", urb->status);
 
 	if (!ACM_READY(acm))
@@ -293,49 +298,109 @@
 	if (urb->status)
 		dev_dbg(&acm->data->dev, "bulk rx status %d\n", urb->status);
 
-	/* calling tty_flip_buffer_push() in_irq() isn't allowed */
-	tasklet_schedule(&acm->bh);
+	buf = rcv->buffer;
+	buf->size = urb->actual_length;
+
+	spin_lock(&acm->read_lock);
+	list_add_tail(&rcv->list, &acm->spare_read_urbs);
+	list_add_tail(&buf->list, &acm->filled_read_bufs);
+	spin_unlock(&acm->read_lock);
+
+	tasklet_schedule(&acm->urb_task);
 }
 
 static void acm_rx_tasklet(unsigned long _acm)
 {
 	struct acm *acm = (void *)_acm;
-	struct urb *urb = acm->readurb;
+	struct acm_rb *buf;
 	struct tty_struct *tty = acm->tty;
-	unsigned char *data = urb->transfer_buffer;
+	struct acm_ru *rcv;
+	//unsigned long flags;
 	int i = 0;
 	dbg("Entering acm_rx_tasklet");
 
-	if (urb->actual_length > 0 && !acm->throttle)  {
-		for (i = 0; i < urb->actual_length && !acm->throttle; i++) {
-			/* if we insert more than TTY_FLIPBUF_SIZE characters,
-			 * we drop them. */
-			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-				tty_flip_buffer_push(tty);
-			}
-			tty_insert_flip_char(tty, data[i], 0);
-		}
-		dbg("Handed %d bytes to tty layer", i+1);
-		tty_flip_buffer_push(tty);
+	if (!ACM_READY(acm) || acm->throttle)
+		return;
+
+next_buffer:
+	spin_lock(&acm->read_lock);
+	if (list_empty(&acm->filled_read_bufs)) {
+		spin_unlock(&acm->read_lock);
+		goto urbs;
 	}
+	buf = list_entry(acm->filled_read_bufs.next,
+			 struct acm_rb, list);
+	list_del(&buf->list);
+	spin_unlock(&acm->read_lock);
+
+	dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size);
+
+	for (i = 0; i < buf->size && !acm->throttle; i++) {
+		/* if we insert more than TTY_FLIPBUF_SIZE characters,
+		   we drop them. */
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty_flip_buffer_push(tty);
+ 		}
+		tty_insert_flip_char(tty, buf->base[i], 0);
+ 	}
+	tty_flip_buffer_push(tty);
 
 	spin_lock(&acm->throttle_lock);
 	if (acm->throttle) {
 		dbg("Throtteling noticed");
-		memmove(data, data + i, urb->actual_length - i);
-		urb->actual_length -= i;
-		acm->resubmit_to_unthrottle = 1;
+		memmove(buf->base, buf->base + i, buf->size - i);
+		buf->size -= i;
 		spin_unlock(&acm->throttle_lock);
+		spin_lock(&acm->read_lock);
+		list_add(&buf->list, &acm->filled_read_bufs);
+		spin_unlock(&acm->read_lock);
 		return;
 	}
 	spin_unlock(&acm->throttle_lock);
 
-	urb->actual_length = 0;
-	urb->dev = acm->dev;
+	spin_lock(&acm->read_lock);
+	list_add(&buf->list, &acm->spare_read_bufs);
+	spin_unlock(&acm->read_lock);
+	goto next_buffer;
 
-	i = usb_submit_urb(urb, GFP_ATOMIC);
-	if (i)
-		dev_dbg(&acm->data->dev, "bulk rx resubmit %d\n", i);
+urbs:
+	while (!list_empty(&acm->spare_read_bufs)) {
+		spin_lock(&acm->read_lock);
+		if (list_empty(&acm->spare_read_urbs)) {
+			spin_unlock(&acm->read_lock);
+			return;
+		}
+		rcv = list_entry(acm->spare_read_urbs.next,
+				 struct acm_ru, list);
+		list_del(&rcv->list);
+		spin_unlock(&acm->read_lock);
+
+		buf = list_entry(acm->spare_read_bufs.next,
+				 struct acm_rb, list);
+		list_del(&buf->list);
+
+		rcv->buffer = buf;
+
+		usb_fill_bulk_urb(rcv->urb, acm->dev,
+				  acm->rx_endpoint,
+				  buf->base,
+				  acm->readsize,
+				  acm_read_bulk, rcv);
+		rcv->urb->transfer_dma = buf->dma;
+		rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+		dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf);
+
+		/* This shouldn't kill the driver as unsuccessful URBs are returned to the
+		   free-urbs-pool and resubmited ASAP */
+		if (usb_submit_urb(rcv->urb, GFP_ATOMIC) < 0) {
+			list_add(&buf->list, &acm->spare_read_bufs);
+			spin_lock(&acm->read_lock);
+			list_add(&rcv->list, &acm->spare_read_urbs);
+			spin_unlock(&acm->read_lock);
+			return;
+		}
+	}
 }
 
 /* data interface wrote those outgoing bytes */
@@ -369,6 +434,7 @@
 {
 	struct acm *acm;
 	int rv = -EINVAL;
+	int i;
 	dbg("Entering acm_tty_open.\n");
 	
 	down(&open_sem);
@@ -382,7 +448,9 @@
 	tty->driver_data = acm;
 	acm->tty = tty;
 
-
+	/* force low_latency on so that our tty_push actually forces the data through,
+	   otherwise it is scheduled, and with high data rates data can get lost. */
+	tty->low_latency = 1;
 
 	if (acm->used++) {
 		goto done;
@@ -394,18 +462,20 @@
 		goto bail_out;
 	}
 
-	acm->readurb->dev = acm->dev;
-	if (usb_submit_urb(acm->readurb, GFP_KERNEL)) {
-		dbg("usb_submit_urb(read bulk) failed");
-		goto bail_out_and_unlink;
-	}
-
 	if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS))
 		goto full_bailout;
 
-	/* force low_latency on so that our tty_push actually forces the data through, 
-	   otherwise it is scheduled, and with high data rates data can get lost. */
-	tty->low_latency = 1;
+	INIT_LIST_HEAD(&acm->spare_read_urbs);
+	INIT_LIST_HEAD(&acm->spare_read_bufs);
+	INIT_LIST_HEAD(&acm->filled_read_bufs);
+	for (i = 0; i < ACM_NRU; i++) {
+		list_add(&(acm->ru[i].list), &acm->spare_read_urbs);
+	}
+	for (i = 0; i < ACM_NRB; i++) {
+		list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
+	}
+
+	tasklet_schedule(&acm->urb_task);
 
 done:
 err_out:
@@ -413,8 +483,6 @@
 	return rv;
 
 full_bailout:
-	usb_kill_urb(acm->readurb);
-bail_out_and_unlink:
 	usb_kill_urb(acm->ctrlurb);
 bail_out:
 	acm->used--;
@@ -424,18 +492,22 @@
 
 static void acm_tty_unregister(struct acm *acm)
 {
+	int i;
+
 	tty_unregister_device(acm_tty_driver, acm->minor);
 	usb_put_intf(acm->control);
 	acm_table[acm->minor] = NULL;
 	usb_free_urb(acm->ctrlurb);
-	usb_free_urb(acm->readurb);
 	usb_free_urb(acm->writeurb);
+	for (i = 0; i < ACM_NRU; i++)
+		usb_free_urb(acm->ru[i].urb);
 	kfree(acm);
 }
 
 static void acm_tty_close(struct tty_struct *tty, struct file *filp)
 {
 	struct acm *acm = tty->driver_data;
+	int i;
 
 	if (!acm || !acm->used)
 		return;
@@ -446,7 +518,8 @@
 			acm_set_control(acm, acm->ctrlout = 0);
 			usb_kill_urb(acm->ctrlurb);
 			usb_kill_urb(acm->writeurb);
-			usb_kill_urb(acm->readurb);
+			for (i = 0; i < ACM_NRU; i++)
+				usb_kill_urb(acm->ru[i].urb);
 		} else
 			acm_tty_unregister(acm);
 	}
@@ -528,10 +601,7 @@
 	spin_lock_bh(&acm->throttle_lock);
 	acm->throttle = 0;
 	spin_unlock_bh(&acm->throttle_lock);
-	if (acm->resubmit_to_unthrottle) {
-		acm->resubmit_to_unthrottle = 0;
-		acm_read_bulk(acm->readurb, NULL);
-	}
+	tasklet_schedule(&acm->urb_task);
 }
 
 static void acm_tty_break_ctl(struct tty_struct *tty, int state)
@@ -588,7 +658,7 @@
 	return -ENOIOCTLCMD;
 }
 
-static __u32 acm_tty_speed[] = {
+static const __u32 acm_tty_speed[] = {
 	0, 50, 75, 110, 134, 150, 200, 300, 600,
 	1200, 1800, 2400, 4800, 9600, 19200, 38400,
 	57600, 115200, 230400, 460800, 500000, 576000,
@@ -596,7 +666,7 @@
 	2500000, 3000000, 3500000, 4000000
 };
 
-static __u8 acm_tty_size[] = {
+static const __u8 acm_tty_size[] = {
 	5, 6, 7, 8
 };
 
@@ -694,6 +764,7 @@
 	int call_interface_num = -1;
 	int data_interface_num;
 	unsigned long quirks;
+	int i;
 
 	/* handle quirks deadly to normal probing*/
 	quirks = (unsigned long)id->driver_info;
@@ -833,7 +904,7 @@
 	}
 
 	ctrlsize = le16_to_cpu(epctrl->wMaxPacketSize);
-	readsize = le16_to_cpu(epread->wMaxPacketSize);
+	readsize = le16_to_cpu(epread->wMaxPacketSize)*2;
 	acm->writesize = le16_to_cpu(epwrite->wMaxPacketSize);
 	acm->control = control_interface;
 	acm->data = data_interface;
@@ -842,12 +913,14 @@
 	acm->ctrl_caps = ac_management_function;
 	acm->ctrlsize = ctrlsize;
 	acm->readsize = readsize;
-	acm->bh.func = acm_rx_tasklet;
-	acm->bh.data = (unsigned long) acm;
+	acm->urb_task.func = acm_rx_tasklet;
+	acm->urb_task.data = (unsigned long) acm;
 	INIT_WORK(&acm->work, acm_softint, acm);
 	spin_lock_init(&acm->throttle_lock);
 	spin_lock_init(&acm->write_lock);
+	spin_lock_init(&acm->read_lock);
 	acm->write_ready = 1;
+	acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress);
 
 	buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
 	if (!buf) {
@@ -856,13 +929,6 @@
 	}
 	acm->ctrl_buffer = buf;
 
-	buf = usb_buffer_alloc(usb_dev, readsize, GFP_KERNEL, &acm->read_dma);
-	if (!buf) {
-		dev_dbg(&intf->dev, "out of memory (read buffer alloc)\n");
-		goto alloc_fail3;
-	}
-	acm->read_buffer = buf;
-
 	if (acm_write_buffers_alloc(acm) < 0) {
 		dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
 		goto alloc_fail4;
@@ -873,10 +939,25 @@
 		dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
 		goto alloc_fail5;
 	}
-	acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!acm->readurb) {
-		dev_dbg(&intf->dev, "out of memory (readurb kmalloc)\n");
-		goto alloc_fail6;
+	for (i = 0; i < ACM_NRU; i++) {
+		struct acm_ru *rcv = &(acm->ru[i]);
+
+		if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
+			dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
+			goto alloc_fail7;
+		}
+
+		rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+		rcv->instance = acm;
+	}
+	for (i = 0; i < ACM_NRB; i++) {
+		struct acm_rb *buf = &(acm->rb[i]);
+
+		// Using usb_buffer_alloc instead of kmalloc as Oliver suggested
+		if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
+			dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
+			goto alloc_fail7;
+		}
 	}
 	acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!acm->writeurb) {
@@ -889,15 +970,9 @@
 	acm->ctrlurb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	acm->ctrlurb->transfer_dma = acm->ctrl_dma;
 
-	usb_fill_bulk_urb(acm->readurb, usb_dev, usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress),
-			  acm->read_buffer, readsize, acm_read_bulk, acm);
-	acm->readurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
-	acm->readurb->transfer_dma = acm->read_dma;
-
 	usb_fill_bulk_urb(acm->writeurb, usb_dev, usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
 			  NULL, acm->writesize, acm_write_bulk, acm);
 	acm->writeurb->transfer_flags |= URB_NO_FSBR | URB_NO_TRANSFER_DMA_MAP;
-	/* acm->writeurb->transfer_dma = 0; */
 
 	dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
 
@@ -917,14 +992,14 @@
 	return 0;
 
 alloc_fail7:
-	usb_free_urb(acm->readurb);
-alloc_fail6:
+	for (i = 0; i < ACM_NRB; i++)
+		usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
+	for (i = 0; i < ACM_NRU; i++)
+		usb_free_urb(acm->ru[i].urb);
 	usb_free_urb(acm->ctrlurb);
 alloc_fail5:
 	acm_write_buffers_free(acm);
 alloc_fail4:
-	usb_buffer_free(usb_dev, readsize, acm->read_buffer, acm->read_dma);
-alloc_fail3:
 	usb_buffer_free(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
 alloc_fail2:
 	kfree(acm);
@@ -936,6 +1011,7 @@
 {
 	struct acm *acm = usb_get_intfdata (intf);
 	struct usb_device *usb_dev = interface_to_usbdev(intf);
+	int i;
 
 	if (!acm || !acm->dev) {
 		dbg("disconnect on nonexisting interface");
@@ -946,15 +1022,24 @@
 	acm->dev = NULL;
 	usb_set_intfdata (intf, NULL);
 
+	tasklet_disable(&acm->urb_task);
+
 	usb_kill_urb(acm->ctrlurb);
-	usb_kill_urb(acm->readurb);
 	usb_kill_urb(acm->writeurb);
+	for (i = 0; i < ACM_NRU; i++)
+		usb_kill_urb(acm->ru[i].urb);
+
+	INIT_LIST_HEAD(&acm->filled_read_bufs);
+	INIT_LIST_HEAD(&acm->spare_read_bufs);
+
+	tasklet_enable(&acm->urb_task);
 
 	flush_scheduled_work(); /* wait for acm_softint */
 
 	acm_write_buffers_free(acm);
-	usb_buffer_free(usb_dev, acm->readsize, acm->read_buffer, acm->read_dma);
 	usb_buffer_free(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);
+	for (i = 0; i < ACM_NRB; i++)
+		usb_buffer_free(usb_dev, acm->readsize, acm->rb[i].base, acm->rb[i].dma);
 
 	usb_driver_release_interface(&acm_driver, acm->data);
 
@@ -1003,7 +1088,6 @@
 MODULE_DEVICE_TABLE (usb, acm_ids);
 
 static struct usb_driver acm_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cdc_acm",
 	.probe =	acm_probe,
 	.disconnect =	acm_disconnect,
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index 963a5df..fd2aaccd 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -59,6 +59,9 @@
  * when processing onlcr, so we only need 2 buffers.
  */
 #define ACM_NWB  2
+#define ACM_NRU  16
+#define ACM_NRB  16
+
 struct acm_wb {
 	unsigned char *buf;
 	dma_addr_t dmah;
@@ -66,22 +69,43 @@
 	int use;
 };
 
+struct acm_rb {
+	struct list_head	list;
+	int			size;
+	unsigned char		*base;
+	dma_addr_t		dma;
+};
+
+struct acm_ru {
+	struct list_head	list;
+	struct acm_rb		*buffer;
+	struct urb		*urb;
+	struct acm		*instance;
+};
+
 struct acm {
 	struct usb_device *dev;				/* the corresponding usb device */
 	struct usb_interface *control;			/* control interface */
 	struct usb_interface *data;			/* data interface */
 	struct tty_struct *tty;				/* the corresponding tty */
-	struct urb *ctrlurb, *readurb, *writeurb;	/* urbs */
-	u8 *ctrl_buffer, *read_buffer;			/* buffers of urbs */
-	dma_addr_t ctrl_dma, read_dma;			/* dma handles of buffers */
+	struct urb *ctrlurb, *writeurb;			/* urbs */
+	u8 *ctrl_buffer;				/* buffers of urbs */
+	dma_addr_t ctrl_dma;				/* dma handles of buffers */
 	struct acm_wb wb[ACM_NWB];
+	struct acm_ru ru[ACM_NRU];
+	struct acm_rb rb[ACM_NRB];
+	int rx_endpoint;
+	spinlock_t read_lock;
+	struct list_head spare_read_urbs;
+	struct list_head spare_read_bufs;
+	struct list_head filled_read_bufs;
 	int write_current;				/* current write buffer */
 	int write_used;					/* number of non-empty write buffers */
 	int write_ready;				/* write urb is not running */
 	spinlock_t write_lock;
 	struct usb_cdc_line_coding line;		/* bits, stop, parity */
 	struct work_struct work;			/* work queue entry for line discipline waking up */
-	struct tasklet_struct bh;			/* rx processing */
+	struct tasklet_struct urb_task;                 /* rx processing */
 	spinlock_t throttle_lock;			/* synchronize throtteling and read callback */
 	unsigned int ctrlin;				/* input control lines (DCD, DSR, RI, break, overruns) */
 	unsigned int ctrlout;				/* output control lines (DTR, RTS) */
@@ -91,7 +115,6 @@
 	unsigned int minor;				/* acm minor number */
 	unsigned char throttle;				/* throttled by tty layer */
 	unsigned char clocal;				/* termios CLOCAL */
-	unsigned char resubmit_to_unthrottle;		/* throtteling has disabled the read urb */
 	unsigned int ctrl_caps;				/* control capabilities from the class specific header */
 };
 
diff --git a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
index 5f8af35..f13f004 100644
--- a/drivers/usb/class/usb-midi.c
+++ b/drivers/usb/class/usb-midi.c
@@ -2027,7 +2027,6 @@
 };
 
 static struct usb_driver usb_midi_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"midi",
 	.probe =	usb_midi_probe,
 	.disconnect =	usb_midi_disconnect,
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 357e753..dba4cc0 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 1999 Michael Gee	<michael@linuxspecific.com>
  * Copyright (c) 1999 Pavel Machek	<pavel@suse.cz>
- * Copyright (c) 2000 Randy Dunlap	<rddunlap@osdl.org>
+ * Copyright (c) 2000 Randy Dunlap	<rdunlap@xenotime.net>
  * Copyright (c) 2000 Vojtech Pavlik	<vojtech@suse.cz>
  # Copyright (c) 2001 Pete Zaitcev	<zaitcev@redhat.com>
  # Copyright (c) 2001 David Paschal	<paschal@rcsis.com>
@@ -199,7 +199,7 @@
 #define USBLP_QUIRK_BIDIR	0x1	/* reports bidir but requires unidirectional mode (no INs/reads) */
 #define USBLP_QUIRK_USB_INIT	0x2	/* needs vendor USB init string */
 
-static struct quirk_printer_struct quirk_printers[] = {
+static const struct quirk_printer_struct quirk_printers[] = {
 	{ 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */
 	{ 0x03f0, 0x0104, USBLP_QUIRK_BIDIR }, /* HP DeskJet 880C */
 	{ 0x03f0, 0x0204, USBLP_QUIRK_BIDIR }, /* HP DeskJet 815C */
@@ -301,7 +301,7 @@
  * Get and print printer errors.
  */
 
-static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
+static const char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
 
 static int usblp_check_status(struct usblp *usblp, int err)
 {
@@ -438,7 +438,7 @@
  			       | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM);
 }
 
-static int usblp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct usblp *usblp = file->private_data;
 	int length, err, i;
@@ -838,7 +838,8 @@
 	.read =		usblp_read,
 	.write =	usblp_write,
 	.poll =		usblp_poll,
-	.ioctl =	usblp_ioctl,
+	.unlocked_ioctl =	usblp_ioctl,
+	.compat_ioctl =		usblp_ioctl,
 	.open =		usblp_open,
 	.release =	usblp_release,
 };
@@ -849,6 +850,20 @@
 	.minor_base =	USBLP_MINOR_BASE,
 };
 
+static ssize_t usblp_show_ieee1284_id(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct usblp *usblp = usb_get_intfdata (intf);
+
+	if (usblp->device_id_string[0] == 0 &&
+	    usblp->device_id_string[1] == 0)
+		return 0;
+
+	return sprintf(buf, "%s", usblp->device_id_string+2);
+}
+
+static DEVICE_ATTR(ieee1284_id, S_IRUGO, usblp_show_ieee1284_id, NULL);
+
 static int usblp_probe(struct usb_interface *intf,
 		       const struct usb_device_id *id)
 {
@@ -933,20 +948,12 @@
 
 	/* Retrieve and store the device ID string. */
 	usblp_cache_device_id_string(usblp);
+	device_create_file(&intf->dev, &dev_attr_ieee1284_id);
 
 #ifdef DEBUG
 	usblp_check_status(usblp, 0);
 #endif
 
-	info("usblp%d: USB %sdirectional printer dev %d "
-		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
-		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
-		usblp->ifnum,
-		usblp->protocol[usblp->current_protocol].alt_setting,
-		usblp->current_protocol,
-		le16_to_cpu(usblp->dev->descriptor.idVendor),
-		le16_to_cpu(usblp->dev->descriptor.idProduct));
-
 	usb_set_intfdata (intf, usblp);
 
 	usblp->present = 1;
@@ -957,11 +964,20 @@
 		goto abort_intfdata;
 	}
 	usblp->minor = intf->minor;
+	info("usblp%d: USB %sdirectional printer dev %d "
+		"if %d alt %d proto %d vid 0x%4.4X pid 0x%4.4X",
+		usblp->minor, usblp->bidir ? "Bi" : "Uni", dev->devnum,
+		usblp->ifnum,
+		usblp->protocol[usblp->current_protocol].alt_setting,
+		usblp->current_protocol,
+		le16_to_cpu(usblp->dev->descriptor.idVendor),
+		le16_to_cpu(usblp->dev->descriptor.idProduct));
 
 	return 0;
 
 abort_intfdata:
 	usb_set_intfdata (intf, NULL);
+	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
 abort:
 	if (usblp) {
 		if (usblp->writebuf)
@@ -1156,6 +1172,8 @@
 		BUG ();
 	}
 
+	device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
+
 	down (&usblp_sem);
 	down (&usblp->sem);
 	usblp->present = 0;
@@ -1186,7 +1204,6 @@
 MODULE_DEVICE_TABLE (usb, usblp_ids);
 
 static struct usb_driver usblp_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usblp",
 	.probe =	usblp_probe,
 	.disconnect =	usblp_disconnect,
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
index 86d5c38..28329dd 100644
--- a/drivers/usb/core/Makefile
+++ b/drivers/usb/core/Makefile
@@ -2,7 +2,7 @@
 # Makefile for USB Core files and filesystem
 #
 
-usbcore-objs	:= usb.o hub.o hcd.o urb.o message.o \
+usbcore-objs	:= usb.o hub.o hcd.o urb.o message.o driver.o \
 			config.o file.o buffer.o sysfs.o devio.o notify.o
 
 ifeq ($(CONFIG_PCI),y)
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 419c994..ad742ce 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -55,6 +55,9 @@
 	char		name [16];
 	int 		i, size;
 
+	if (!hcd->self.controller->dma_mask)
+		return 0;
+
 	for (i = 0; i < HCD_BUFFER_POOLS; i++) { 
 		if (!(size = pool_max [i]))
 			continue;
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index 83e815d..2684e15 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -67,45 +67,45 @@
 /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
 #define ALLOW_SERIAL_NUMBER
 
-static char *format_topo =
+static const char *format_topo =
 /* T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */
 "\nT:  Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n";
 
-static char *format_string_manufacturer =
+static const char *format_string_manufacturer =
 /* S:  Manufacturer=xxxx */
   "S:  Manufacturer=%.100s\n";
 
-static char *format_string_product =
+static const char *format_string_product =
 /* S:  Product=xxxx */
   "S:  Product=%.100s\n";
 
 #ifdef ALLOW_SERIAL_NUMBER
-static char *format_string_serialnumber =
+static const char *format_string_serialnumber =
 /* S:  SerialNumber=xxxx */
   "S:  SerialNumber=%.100s\n";
 #endif
 
-static char *format_bandwidth =
+static const char *format_bandwidth =
 /* B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */
   "B:  Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n";
   
-static char *format_device1 =
+static const char *format_device1 =
 /* D:  Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */
   "D:  Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n";
 
-static char *format_device2 =
+static const char *format_device2 =
 /* P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx */
   "P:  Vendor=%04x ProdID=%04x Rev=%2x.%02x\n";
 
-static char *format_config =
+static const char *format_config =
 /* C:  #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
   "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
   
-static char *format_iface =
+static const char *format_iface =
 /* I:  If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/
   "I:  If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
 
-static char *format_endpt =
+static const char *format_endpt =
 /* E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */
   "E:  Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n";
 
@@ -545,10 +545,10 @@
 		struct usb_device *childdev = usbdev->children[chix];
 
 		if (childdev) {
-			down(&childdev->serialize);
+			usb_lock_device(childdev);
 			ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, childdev,
 					bus, level + 1, chix, ++cnt);
-			up(&childdev->serialize);
+			usb_unlock_device(childdev);
 			if (ret == -EFAULT)
 				return total_written;
 			total_written += ret;
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index b1d6e9a..2b68998 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -402,7 +402,6 @@
 }
 
 struct usb_driver usbfs_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbfs",
 	.probe =	driver_probe,
 	.disconnect =	driver_disconnect,
@@ -1350,9 +1349,7 @@
 	/* let kernel drivers try to (re)bind to the interface */
 	case USBDEVFS_CONNECT:
 		usb_unlock_device(ps->dev);
-		usb_lock_all_devices();
 		bus_rescan_devices(intf->dev.bus);
-		usb_unlock_all_devices();
 		usb_lock_device(ps->dev);
 		break;
 
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
new file mode 100644
index 0000000..076462c
--- /dev/null
+++ b/drivers/usb/core/driver.c
@@ -0,0 +1,472 @@
+/*
+ * drivers/usb/driver.c - most of the driver model stuff for usb
+ *
+ * (C) Copyright 2005 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * based on drivers/usb/usb.c which had the following copyrights:
+ *	(C) Copyright Linus Torvalds 1999
+ *	(C) Copyright Johannes Erdfelt 1999-2001
+ *	(C) Copyright Andreas Gal 1999
+ *	(C) Copyright Gregory P. Smith 1999
+ *	(C) Copyright Deti Fliegl 1999 (new USB architecture)
+ *	(C) Copyright Randy Dunlap 2000
+ *	(C) Copyright David Brownell 2000-2004
+ *	(C) Copyright Yggdrasil Computing, Inc. 2000
+ *		(usb_device_id matching changes by Adam J. Richter)
+ *	(C) Copyright Greg Kroah-Hartman 2002-2003
+ *
+ * NOTE! This is not actually a driver at all, rather this is
+ * just a collection of helper routines that implement the
+ * generic USB things that the real drivers can use..
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/device.h>
+#include <linux/usb.h>
+#include "hcd.h"
+#include "usb.h"
+
+static int usb_match_one_id(struct usb_interface *interface,
+			    const struct usb_device_id *id);
+
+struct usb_dynid {
+	struct list_head node;
+	struct usb_device_id id;
+};
+
+
+static int generic_probe(struct device *dev)
+{
+	return 0;
+}
+static int generic_remove(struct device *dev)
+{
+	struct usb_device *udev = to_usb_device(dev);
+
+	/* if this is only an unbind, not a physical disconnect, then
+	 * unconfigure the device */
+	if (udev->state == USB_STATE_CONFIGURED)
+		usb_set_configuration(udev, 0);
+
+	/* in case the call failed or the device was suspended */
+	if (udev->state >= USB_STATE_CONFIGURED)
+		usb_disable_device(udev, 0);
+	return 0;
+}
+
+struct device_driver usb_generic_driver = {
+	.owner = THIS_MODULE,
+	.name =	"usb",
+	.bus = &usb_bus_type,
+	.probe = generic_probe,
+	.remove = generic_remove,
+};
+
+/* Fun hack to determine if the struct device is a
+ * usb device or a usb interface. */
+int usb_generic_driver_data;
+
+#ifdef CONFIG_HOTPLUG
+
+/*
+ * Adds a new dynamic USBdevice ID to this driver,
+ * and cause the driver to probe for all devices again.
+ */
+static ssize_t store_new_id(struct device_driver *driver,
+			    const char *buf, size_t count)
+{
+	struct usb_driver *usb_drv = to_usb_driver(driver);
+	struct usb_dynid *dynid;
+	u32 idVendor = 0;
+	u32 idProduct = 0;
+	int fields = 0;
+
+	fields = sscanf(buf, "%x %x", &idVendor, &idProduct);
+	if (fields < 2)
+		return -EINVAL;
+
+	dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
+	if (!dynid)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&dynid->node);
+	dynid->id.idVendor = idVendor;
+	dynid->id.idProduct = idProduct;
+	dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+
+	spin_lock(&usb_drv->dynids.lock);
+	list_add_tail(&usb_drv->dynids.list, &dynid->node);
+	spin_unlock(&usb_drv->dynids.lock);
+
+	if (get_driver(driver)) {
+		driver_attach(driver);
+		put_driver(driver);
+	}
+
+	return count;
+}
+static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
+
+static int usb_create_newid_file(struct usb_driver *usb_drv)
+{
+	int error = 0;
+
+	if (usb_drv->no_dynamic_id)
+		goto exit;
+
+	if (usb_drv->probe != NULL)
+		error = sysfs_create_file(&usb_drv->driver.kobj,
+					  &driver_attr_new_id.attr);
+exit:
+	return error;
+}
+
+static void usb_remove_newid_file(struct usb_driver *usb_drv)
+{
+	if (usb_drv->no_dynamic_id)
+		return;
+
+	if (usb_drv->probe != NULL)
+		sysfs_remove_file(&usb_drv->driver.kobj,
+				  &driver_attr_new_id.attr);
+}
+
+static void usb_free_dynids(struct usb_driver *usb_drv)
+{
+	struct usb_dynid *dynid, *n;
+
+	spin_lock(&usb_drv->dynids.lock);
+	list_for_each_entry_safe(dynid, n, &usb_drv->dynids.list, node) {
+		list_del(&dynid->node);
+		kfree(dynid);
+	}
+	spin_unlock(&usb_drv->dynids.lock);
+}
+#else
+static inline int usb_create_newid_file(struct usb_driver *usb_drv)
+{
+	return 0;
+}
+
+static void usb_remove_newid_file(struct usb_driver *usb_drv)
+{
+}
+
+static inline void usb_free_dynids(struct usb_driver *usb_drv)
+{
+}
+#endif
+
+static const struct usb_device_id *usb_match_dynamic_id(struct usb_interface *intf,
+							struct usb_driver *drv)
+{
+	struct usb_dynid *dynid;
+
+	spin_lock(&drv->dynids.lock);
+	list_for_each_entry(dynid, &drv->dynids.list, node) {
+		if (usb_match_one_id(intf, &dynid->id)) {
+			spin_unlock(&drv->dynids.lock);
+			return &dynid->id;
+		}
+	}
+	spin_unlock(&drv->dynids.lock);
+	return NULL;
+}
+
+
+/* called from driver core with usb_bus_type.subsys writelock */
+static int usb_probe_interface(struct device *dev)
+{
+	struct usb_interface * intf = to_usb_interface(dev);
+	struct usb_driver * driver = to_usb_driver(dev->driver);
+	const struct usb_device_id *id;
+	int error = -ENODEV;
+
+	dev_dbg(dev, "%s\n", __FUNCTION__);
+
+	if (!driver->probe)
+		return error;
+	/* FIXME we'd much prefer to just resume it ... */
+	if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED)
+		return -EHOSTUNREACH;
+
+	id = usb_match_id(intf, driver->id_table);
+	if (!id)
+		id = usb_match_dynamic_id(intf, driver);
+	if (id) {
+		dev_dbg(dev, "%s - got id\n", __FUNCTION__);
+
+		/* Interface "power state" doesn't correspond to any hardware
+		 * state whatsoever.  We use it to record when it's bound to
+		 * a driver that may start I/0:  it's not frozen/quiesced.
+		 */
+		mark_active(intf);
+		intf->condition = USB_INTERFACE_BINDING;
+		error = driver->probe(intf, id);
+		if (error) {
+			mark_quiesced(intf);
+			intf->condition = USB_INTERFACE_UNBOUND;
+		} else
+			intf->condition = USB_INTERFACE_BOUND;
+	}
+
+	return error;
+}
+
+/* called from driver core with usb_bus_type.subsys writelock */
+static int usb_unbind_interface(struct device *dev)
+{
+	struct usb_interface *intf = to_usb_interface(dev);
+	struct usb_driver *driver = to_usb_driver(intf->dev.driver);
+
+	intf->condition = USB_INTERFACE_UNBINDING;
+
+	/* release all urbs for this interface */
+	usb_disable_interface(interface_to_usbdev(intf), intf);
+
+	if (driver && driver->disconnect)
+		driver->disconnect(intf);
+
+	/* reset other interface state */
+	usb_set_interface(interface_to_usbdev(intf),
+			intf->altsetting[0].desc.bInterfaceNumber,
+			0);
+	usb_set_intfdata(intf, NULL);
+	intf->condition = USB_INTERFACE_UNBOUND;
+	mark_quiesced(intf);
+
+	return 0;
+}
+
+/* returns 0 if no match, 1 if match */
+static int usb_match_one_id(struct usb_interface *interface,
+			    const struct usb_device_id *id)
+{
+	struct usb_host_interface *intf;
+	struct usb_device *dev;
+
+	/* proc_connectinfo in devio.c may call us with id == NULL. */
+	if (id == NULL)
+		return 0;
+
+	intf = interface->cur_altsetting;
+	dev = interface_to_usbdev(interface);
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+	    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
+	    id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
+		return 0;
+
+	/* No need to test id->bcdDevice_lo != 0, since 0 is never
+	   greater than any unsigned number. */
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
+	    (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
+	    (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
+	    (id->bDeviceClass != dev->descriptor.bDeviceClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
+	    (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
+	    (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+	    (id->bInterfaceClass != intf->desc.bInterfaceClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
+	    (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))
+		return 0;
+
+	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
+	    (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
+		return 0;
+
+	return 1;
+}
+/**
+ * usb_match_id - find first usb_device_id matching device or interface
+ * @interface: the interface of interest
+ * @id: array of usb_device_id structures, terminated by zero entry
+ *
+ * usb_match_id searches an array of usb_device_id's and returns
+ * the first one matching the device or interface, or null.
+ * This is used when binding (or rebinding) a driver to an interface.
+ * Most USB device drivers will use this indirectly, through the usb core,
+ * but some layered driver frameworks use it directly.
+ * These device tables are exported with MODULE_DEVICE_TABLE, through
+ * modutils, to support the driver loading functionality of USB hotplugging.
+ *
+ * What Matches:
+ *
+ * The "match_flags" element in a usb_device_id controls which
+ * members are used.  If the corresponding bit is set, the
+ * value in the device_id must match its corresponding member
+ * in the device or interface descriptor, or else the device_id
+ * does not match.
+ *
+ * "driver_info" is normally used only by device drivers,
+ * but you can create a wildcard "matches anything" usb_device_id
+ * as a driver's "modules.usbmap" entry if you provide an id with
+ * only a nonzero "driver_info" field.  If you do this, the USB device
+ * driver's probe() routine should use additional intelligence to
+ * decide whether to bind to the specified interface.
+ *
+ * What Makes Good usb_device_id Tables:
+ *
+ * The match algorithm is very simple, so that intelligence in
+ * driver selection must come from smart driver id records.
+ * Unless you have good reasons to use another selection policy,
+ * provide match elements only in related groups, and order match
+ * specifiers from specific to general.  Use the macros provided
+ * for that purpose if you can.
+ *
+ * The most specific match specifiers use device descriptor
+ * data.  These are commonly used with product-specific matches;
+ * the USB_DEVICE macro lets you provide vendor and product IDs,
+ * and you can also match against ranges of product revisions.
+ * These are widely used for devices with application or vendor
+ * specific bDeviceClass values.
+ *
+ * Matches based on device class/subclass/protocol specifications
+ * are slightly more general; use the USB_DEVICE_INFO macro, or
+ * its siblings.  These are used with single-function devices
+ * where bDeviceClass doesn't specify that each interface has
+ * its own class.
+ *
+ * Matches based on interface class/subclass/protocol are the
+ * most general; they let drivers bind to any interface on a
+ * multiple-function device.  Use the USB_INTERFACE_INFO
+ * macro, or its siblings, to match class-per-interface style
+ * devices (as recorded in bDeviceClass).
+ *
+ * Within those groups, remember that not all combinations are
+ * meaningful.  For example, don't give a product version range
+ * without vendor and product IDs; or specify a protocol without
+ * its associated class and subclass.
+ */
+const struct usb_device_id *usb_match_id(struct usb_interface *interface,
+					 const struct usb_device_id *id)
+{
+	/* proc_connectinfo in devio.c may call us with id == NULL. */
+	if (id == NULL)
+		return NULL;
+
+	/* It is important to check that id->driver_info is nonzero,
+	   since an entry that is all zeroes except for a nonzero
+	   id->driver_info is the way to create an entry that
+	   indicates that the driver want to examine every
+	   device and interface. */
+	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
+	       id->driver_info; id++) {
+		if (usb_match_one_id(interface, id))
+			return id;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(usb_match_id);
+
+int usb_device_match(struct device *dev, struct device_driver *drv)
+{
+	struct usb_interface *intf;
+	struct usb_driver *usb_drv;
+	const struct usb_device_id *id;
+
+	/* check for generic driver, which we don't match any device with */
+	if (drv == &usb_generic_driver)
+		return 0;
+
+	intf = to_usb_interface(dev);
+	usb_drv = to_usb_driver(drv);
+
+	id = usb_match_id(intf, usb_drv->id_table);
+	if (id)
+		return 1;
+
+	id = usb_match_dynamic_id(intf, usb_drv);
+	if (id)
+		return 1;
+	return 0;
+}
+
+/**
+ * usb_register_driver - register a USB driver
+ * @new_driver: USB operations for the driver
+ * @owner: module owner of this driver.
+ *
+ * Registers a USB driver with the USB core.  The list of unattached
+ * interfaces will be rescanned whenever a new driver is added, allowing
+ * the new driver to attach to any recognized devices.
+ * Returns a negative error code on failure and 0 on success.
+ *
+ * NOTE: if you want your driver to use the USB major number, you must call
+ * usb_register_dev() to enable that functionality.  This function no longer
+ * takes care of that.
+ */
+int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
+{
+	int retval = 0;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	new_driver->driver.name = (char *)new_driver->name;
+	new_driver->driver.bus = &usb_bus_type;
+	new_driver->driver.probe = usb_probe_interface;
+	new_driver->driver.remove = usb_unbind_interface;
+	new_driver->driver.owner = owner;
+	spin_lock_init(&new_driver->dynids.lock);
+	INIT_LIST_HEAD(&new_driver->dynids.list);
+
+	retval = driver_register(&new_driver->driver);
+
+	if (!retval) {
+		pr_info("%s: registered new driver %s\n",
+			usbcore_name, new_driver->name);
+		usbfs_update_special();
+		usb_create_newid_file(new_driver);
+	} else {
+		printk(KERN_ERR "%s: error %d registering driver %s\n",
+			usbcore_name, retval, new_driver->name);
+	}
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(usb_register_driver);
+
+/**
+ * usb_deregister - unregister a USB driver
+ * @driver: USB operations of the driver to unregister
+ * Context: must be able to sleep
+ *
+ * Unlinks the specified driver from the internal USB driver list.
+ *
+ * NOTE: If you called usb_register_dev(), you still need to call
+ * usb_deregister_dev() to clean up your driver's allocated minor numbers,
+ * this * call will no longer do it for you.
+ */
+void usb_deregister(struct usb_driver *driver)
+{
+	pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name);
+
+	usb_remove_newid_file(driver);
+	usb_free_dynids(driver);
+	driver_unregister(&driver->driver);
+
+	usbfs_update_special();
+}
+EXPORT_SYMBOL_GPL(usb_deregister);
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 5131d88e..29b5b2a 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -219,6 +219,7 @@
 			goto done;
 		}
 	}
+	synchronize_irq(dev->irq);
 
 	/* FIXME until the generic PM interfaces change a lot more, this
 	 * can't use PCI D1 and D2 states.  For example, the confusion
@@ -392,7 +393,7 @@
 
 	dev->dev.power.power_state = PMSG_ON;
 
-	hcd->saw_irq = 0;
+	clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
 
 	if (hcd->driver->resume) {
 		retval = hcd->driver->resume(hcd);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5e5f65a..0018bbc 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -857,9 +857,7 @@
 		return (retval < 0) ? retval : -EMSGSIZE;
 	}
 
-	usb_lock_device (usb_dev);
 	retval = usb_new_device (usb_dev);
-	usb_unlock_device (usb_dev);
 	if (retval) {
 		usb_dev->bus->root_hub = NULL;
 		dev_err (parent_dev, "can't register root hub for %s, %d\n",
@@ -1315,11 +1313,12 @@
 	 * finish unlinking the initial failed usb_set_address()
 	 * or device descriptor fetch.
 	 */
-	if (!hcd->saw_irq && hcd->self.root_hub != urb->dev) {
+	if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags)
+	    && hcd->self.root_hub != urb->dev) {
 		dev_warn (hcd->self.controller, "Unlink after no-IRQ?  "
 			"Controller is probably using the wrong IRQ."
 			"\n");
-		hcd->saw_irq = 1;
+		set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
 	}
 
 	urb->status = status;
@@ -1649,13 +1648,15 @@
 	struct usb_hcd		*hcd = __hcd;
 	int			start = hcd->state;
 
-	if (start == HC_STATE_HALT)
+	if (unlikely(start == HC_STATE_HALT ||
+	    !test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
 		return IRQ_NONE;
 	if (hcd->driver->irq (hcd, r) == IRQ_NONE)
 		return IRQ_NONE;
 
-	hcd->saw_irq = 1;
-	if (hcd->state == HC_STATE_HALT)
+	set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);
+
+	if (unlikely(hcd->state == HC_STATE_HALT))
 		usb_hc_died (hcd);
 	return IRQ_HANDLED;
 }
@@ -1768,6 +1769,8 @@
 
 	dev_info(hcd->self.controller, "%s\n", hcd->product_desc);
 
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
 	/* till now HC has been in an indeterminate state ... */
 	if (hcd->driver->reset && (retval = hcd->driver->reset(hcd)) < 0) {
 		dev_err(hcd->self.controller, "can't reset\n");
@@ -1822,8 +1825,6 @@
 		retval = -ENOMEM;
 		goto err_allocate_root_hub;
 	}
-	rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
-			USB_SPEED_FULL;
 
 	/* Although in principle hcd->driver->start() might need to use rhdev,
 	 * none of the current drivers do.
@@ -1841,6 +1842,9 @@
 		dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
 	hcd->remote_wakeup = hcd->can_wakeup;
 
+	rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :
+			USB_SPEED_FULL;
+	rhdev->bus_mA = min(500u, hcd->power_budget);
 	if ((retval = register_root_hub(rhdev, hcd)) != 0)
 		goto err_register_root_hub;
 
@@ -1886,7 +1890,10 @@
 	spin_lock_irq (&hcd_root_hub_lock);
 	hcd->rh_registered = 0;
 	spin_unlock_irq (&hcd_root_hub_lock);
+
+	down(&usb_bus_list_lock);
 	usb_disconnect(&hcd->self.root_hub);
+	up(&usb_bus_list_lock);
 
 	hcd->poll_rh = 0;
 	del_timer_sync(&hcd->rh_timer);
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 24a62a2..591b5aa 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -72,7 +72,12 @@
 	 * hardware info/state
 	 */
 	const struct hc_driver	*driver;	/* hw-specific hooks */
-	unsigned		saw_irq : 1;
+
+	/* Flags that need to be manipulated atomically */
+	unsigned long		flags;
+#define HCD_FLAG_HW_ACCESSIBLE	0x00000001
+#define HCD_FLAG_SAW_IRQ	0x00000002
+
 	unsigned		can_wakeup:1;	/* hw supports wakeup? */
 	unsigned		remote_wakeup:1;/* sw should use wakeup? */
 	unsigned		rh_registered:1;/* is root hub registered? */
@@ -375,6 +380,7 @@
 #ifdef CONFIG_PM
 extern void usb_hcd_suspend_root_hub (struct usb_hcd *hcd);
 extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
+extern void usb_root_hub_lost_power (struct usb_device *rhdev);
 extern int hcd_bus_suspend (struct usb_bus *bus);
 extern int hcd_bus_resume (struct usb_bus *bus);
 #else
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index f78bd12..650d5ee 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -32,7 +32,7 @@
 #include "hub.h"
 
 /* Protect struct usb_device->state and ->children members
- * Note: Both are also protected by ->serialize, except that ->state can
+ * Note: Both are also protected by ->dev.sem, except that ->state can
  * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
 static DEFINE_SPINLOCK(device_state_lock);
 
@@ -515,6 +515,31 @@
 	return ret;
 }
 
+
+/* caller has locked the hub device */
+static void hub_pre_reset(struct usb_hub *hub, int disable_ports)
+{
+	struct usb_device *hdev = hub->hdev;
+	int port1;
+
+	for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+		if (hdev->children[port1 - 1]) {
+			usb_disconnect(&hdev->children[port1 - 1]);
+			if (disable_ports)
+				hub_port_disable(hub, port1, 0);
+		}
+	}
+	hub_quiesce(hub);
+}
+
+/* caller has locked the hub device */
+static void hub_post_reset(struct usb_hub *hub)
+{
+	hub_activate(hub);
+	hub_power_on(hub);
+}
+
+
 static int hub_configure(struct usb_hub *hub,
 	struct usb_endpoint_descriptor *endpoint)
 {
@@ -677,26 +702,40 @@
 	 * and battery-powered root hubs (may provide just 8 mA).
 	 */
 	ret = usb_get_status(hdev, USB_RECIP_DEVICE, 0, &hubstatus);
-	if (ret < 0) {
+	if (ret < 2) {
 		message = "can't get hub status";
 		goto fail;
 	}
 	le16_to_cpus(&hubstatus);
 	if (hdev == hdev->bus->root_hub) {
-		struct usb_hcd *hcd =
-				container_of(hdev->bus, struct usb_hcd, self);
-
-		hub->power_budget = min(500u, hcd->power_budget) / 2;
+		if (hdev->bus_mA == 0 || hdev->bus_mA >= 500)
+			hub->mA_per_port = 500;
+		else {
+			hub->mA_per_port = hdev->bus_mA;
+			hub->limited_power = 1;
+		}
 	} else if ((hubstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
 		dev_dbg(hub_dev, "hub controller current requirement: %dmA\n",
 			hub->descriptor->bHubContrCurrent);
-		hub->power_budget = (501 - hub->descriptor->bHubContrCurrent)
-					/ 2;
-	}
-	if (hub->power_budget)
-		dev_dbg(hub_dev, "%dmA bus power budget for children\n",
-			hub->power_budget * 2);
+		hub->limited_power = 1;
+		if (hdev->maxchild > 0) {
+			int remaining = hdev->bus_mA -
+					hub->descriptor->bHubContrCurrent;
 
+			if (remaining < hdev->maxchild * 100)
+				dev_warn(hub_dev,
+					"insufficient power available "
+					"to use all downstream ports\n");
+			hub->mA_per_port = 100;		/* 7.2.1.1 */
+		}
+	} else {	/* Self-powered external hub */
+		/* FIXME: What about battery-powered external hubs that
+		 * provide less current per port? */
+		hub->mA_per_port = 500;
+	}
+	if (hub->mA_per_port < 500)
+		dev_dbg(hub_dev, "%umA bus power budget for each child\n",
+				hub->mA_per_port);
 
 	ret = hub_hub_status(hub, &hubstatus, &hubchange);
 	if (ret < 0) {
@@ -750,29 +789,10 @@
 
 static unsigned highspeed_hubs;
 
-/* Called after the hub driver is unbound from a hub with children */
-static void hub_remove_children_work(void *__hub)
-{
-	struct usb_hub		*hub = __hub;
-	struct usb_device	*hdev = hub->hdev;
-	int			i;
-
-	kfree(hub);
-
-	usb_lock_device(hdev);
-	for (i = 0; i < hdev->maxchild; ++i) {
-		if (hdev->children[i])
-			usb_disconnect(&hdev->children[i]);
-	}
-	usb_unlock_device(hdev);
-	usb_put_dev(hdev);
-}
-
 static void hub_disconnect(struct usb_interface *intf)
 {
 	struct usb_hub *hub = usb_get_intfdata (intf);
 	struct usb_device *hdev;
-	int n, port1;
 
 	usb_set_intfdata (intf, NULL);
 	hdev = hub->hdev;
@@ -780,7 +800,9 @@
 	if (hdev->speed == USB_SPEED_HIGH)
 		highspeed_hubs--;
 
-	hub_quiesce(hub);
+	/* Disconnect all children and quiesce the hub */
+	hub_pre_reset(hub, 1);
+
 	usb_free_urb(hub->urb);
 	hub->urb = NULL;
 
@@ -800,27 +822,7 @@
 		hub->buffer = NULL;
 	}
 
-	/* If there are any children then this is an unbind only, not a
-	 * physical disconnection.  The active ports must be disabled
-	 * and later on we must call usb_disconnect().  We can't call
-	 * it now because we may not hold the hub's device lock.
-	 */
-	n = 0;
-	for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
-		if (hdev->children[port1 - 1]) {
-			++n;
-			hub_port_disable(hub, port1, 1);
-		}
-	}
-
-	if (n == 0)
-		kfree(hub);
-	else {
-		/* Reuse the hub->leds work_struct for our own purposes */
-		INIT_WORK(&hub->leds, hub_remove_children_work, hub);
-		schedule_work(&hub->leds);
-		usb_get_dev(hdev);
-	}
+	kfree(hub);
 }
 
 static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -917,26 +919,6 @@
 	}
 }
 
-/* caller has locked the hub device */
-static void hub_pre_reset(struct usb_hub *hub)
-{
-	struct usb_device *hdev = hub->hdev;
-	int i;
-
-	for (i = 0; i < hdev->maxchild; ++i) {
-		if (hdev->children[i])
-			usb_disconnect(&hdev->children[i]);
-	}
-	hub_quiesce(hub);
-}
-
-/* caller has locked the hub device */
-static void hub_post_reset(struct usb_hub *hub)
-{
-	hub_activate(hub);
-	hub_power_on(hub);
-}
-
 
 /* grab device/port lock, returning index of that port (zero based).
  * protects the upstream link used by this device from concurrent
@@ -964,24 +946,21 @@
 	t = locktree(hdev);
 	if (t < 0)
 		return t;
-	for (t = 0; t < hdev->maxchild; t++) {
-		if (hdev->children[t] == udev) {
-			/* everything is fail-fast once disconnect
-			 * processing starts
-			 */
-			if (udev->state == USB_STATE_NOTATTACHED)
-				break;
 
-			/* when everyone grabs locks top->bottom,
-			 * non-overlapping work may be concurrent
-			 */
-			down(&udev->serialize);
-			up(&hdev->serialize);
-			return t + 1;
-		}
+	/* everything is fail-fast once disconnect
+	 * processing starts
+	 */
+	if (udev->state == USB_STATE_NOTATTACHED) {
+		usb_unlock_device(hdev);
+		return -ENODEV;
 	}
+
+	/* when everyone grabs locks top->bottom,
+	 * non-overlapping work may be concurrent
+	 */
+	usb_lock_device(udev);
 	usb_unlock_device(hdev);
-	return -ENODEV;
+	return udev->portnum;
 }
 
 static void recursively_mark_NOTATTACHED(struct usb_device *udev)
@@ -1039,6 +1018,39 @@
 EXPORT_SYMBOL(usb_set_device_state);
 
 
+#ifdef CONFIG_PM
+
+/**
+ * usb_root_hub_lost_power - called by HCD if the root hub lost Vbus power
+ * @rhdev: struct usb_device for the root hub
+ *
+ * The USB host controller driver calls this function when its root hub
+ * is resumed and Vbus power has been interrupted or the controller
+ * has been reset.  The routine marks all the children of the root hub
+ * as NOTATTACHED and marks logical connect-change events on their ports.
+ */
+void usb_root_hub_lost_power(struct usb_device *rhdev)
+{
+	struct usb_hub *hub;
+	int port1;
+	unsigned long flags;
+
+	dev_warn(&rhdev->dev, "root hub lost power or was reset\n");
+	spin_lock_irqsave(&device_state_lock, flags);
+	hub = hdev_to_hub(rhdev);
+	for (port1 = 1; port1 <= rhdev->maxchild; ++port1) {
+		if (rhdev->children[port1 - 1]) {
+			recursively_mark_NOTATTACHED(
+					rhdev->children[port1 - 1]);
+			set_bit(port1, hub->change_bits);
+		}
+	}
+	spin_unlock_irqrestore(&device_state_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_root_hub_lost_power);
+
+#endif
+
 static void choose_address(struct usb_device *udev)
 {
 	int		devnum;
@@ -1099,16 +1111,10 @@
 	 * this quiesces everyting except pending urbs.
 	 */
 	usb_set_device_state(udev, USB_STATE_NOTATTACHED);
-
-	/* lock the bus list on behalf of HCDs unregistering their root hubs */
-	if (!udev->parent) {
-		down(&usb_bus_list_lock);
-		usb_lock_device(udev);
-	} else
-		down(&udev->serialize);
-
 	dev_info (&udev->dev, "USB disconnect, address %d\n", udev->devnum);
 
+	usb_lock_device(udev);
+
 	/* Free up all the children before we remove this device */
 	for (i = 0; i < USB_MAXCHILDREN; i++) {
 		if (udev->children[i])
@@ -1136,54 +1142,112 @@
 	*pdev = NULL;
 	spin_unlock_irq(&device_state_lock);
 
-	if (!udev->parent) {
-		usb_unlock_device(udev);
-		up(&usb_bus_list_lock);
-	} else
-		up(&udev->serialize);
+	usb_unlock_device(udev);
 
 	device_unregister(&udev->dev);
 }
 
+static inline const char *plural(int n)
+{
+	return (n == 1 ? "" : "s");
+}
+
 static int choose_configuration(struct usb_device *udev)
 {
-	int c, i;
+	int i;
+	u16 devstatus;
+	int bus_powered;
+	int num_configs;
+	struct usb_host_config *c, *best;
 
-	/* NOTE: this should interact with hub power budgeting */
+	/* If this fails, assume the device is bus-powered */
+	devstatus = 0;
+	usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
+	le16_to_cpus(&devstatus);
+	bus_powered = ((devstatus & (1 << USB_DEVICE_SELF_POWERED)) == 0);
+	dev_dbg(&udev->dev, "device is %s-powered\n",
+			bus_powered ? "bus" : "self");
 
-	c = udev->config[0].desc.bConfigurationValue;
-	if (udev->descriptor.bNumConfigurations != 1) {
-		for (i = 0; i < udev->descriptor.bNumConfigurations; i++) {
-			struct usb_interface_descriptor	*desc;
+	best = NULL;
+	c = udev->config;
+	num_configs = udev->descriptor.bNumConfigurations;
+	for (i = 0; i < num_configs; (i++, c++)) {
+		struct usb_interface_descriptor	*desc =
+				&c->intf_cache[0]->altsetting->desc;
 
-			/* heuristic:  Linux is more likely to have class
-			 * drivers, so avoid vendor-specific interfaces.
-			 */
-			desc = &udev->config[i].intf_cache[0]
-					->altsetting->desc;
-			if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC)
-				continue;
-			/* COMM/2/all is CDC ACM, except 0xff is MSFT RNDIS.
-			 * MSFT needs this to be the first config; never use
-			 * it as the default unless Linux has host-side RNDIS.
-			 * A second config would ideally be CDC-Ethernet, but
-			 * may instead be the "vendor specific" CDC subset
-			 * long used by ARM Linux for sa1100 or pxa255.
-			 */
-			if (desc->bInterfaceClass == USB_CLASS_COMM
-					&& desc->bInterfaceSubClass == 2
-					&& desc->bInterfaceProtocol == 0xff) {
-				c = udev->config[1].desc.bConfigurationValue;
-				continue;
-			}
-			c = udev->config[i].desc.bConfigurationValue;
+		/*
+		 * HP's USB bus-powered keyboard has only one configuration
+		 * and it claims to be self-powered; other devices may have
+		 * similar errors in their descriptors.  If the next test
+		 * were allowed to execute, such configurations would always
+		 * be rejected and the devices would not work as expected.
+		 */
+#if 0
+		/* Rule out self-powered configs for a bus-powered device */
+		if (bus_powered && (c->desc.bmAttributes &
+					USB_CONFIG_ATT_SELFPOWER))
+			continue;
+#endif
+
+		/*
+		 * The next test may not be as effective as it should be.
+		 * Some hubs have errors in their descriptor, claiming
+		 * to be self-powered when they are really bus-powered.
+		 * We will overestimate the amount of current such hubs
+		 * make available for each port.
+		 *
+		 * This is a fairly benign sort of failure.  It won't
+		 * cause us to reject configurations that we should have
+		 * accepted.
+		 */
+
+		/* Rule out configs that draw too much bus current */
+		if (c->desc.bMaxPower * 2 > udev->bus_mA)
+			continue;
+
+		/* If the first config's first interface is COMM/2/0xff
+		 * (MSFT RNDIS), rule it out unless Linux has host-side
+		 * RNDIS support. */
+		if (i == 0 && desc->bInterfaceClass == USB_CLASS_COMM
+				&& desc->bInterfaceSubClass == 2
+				&& desc->bInterfaceProtocol == 0xff) {
+#ifndef CONFIG_USB_NET_RNDIS
+			continue;
+#else
+			best = c;
+#endif
+		}
+
+		/* From the remaining configs, choose the first one whose
+		 * first interface is for a non-vendor-specific class.
+		 * Reason: Linux is more likely to have a class driver
+		 * than a vendor-specific driver. */
+		else if (udev->descriptor.bDeviceClass !=
+						USB_CLASS_VENDOR_SPEC &&
+				desc->bInterfaceClass !=
+						USB_CLASS_VENDOR_SPEC) {
+			best = c;
 			break;
 		}
-		dev_info(&udev->dev,
-			"configuration #%d chosen from %d choices\n",
-			c, udev->descriptor.bNumConfigurations);
+
+		/* If all the remaining configs are vendor-specific,
+		 * choose the first one. */
+		else if (!best)
+			best = c;
 	}
-	return c;
+
+	if (best) {
+		i = best->desc.bConfigurationValue;
+		dev_info(&udev->dev,
+			"configuration #%d chosen from %d choice%s\n",
+			i, num_configs, plural(num_configs));
+	} else {
+		i = -1;
+		dev_warn(&udev->dev,
+			"no configuration chosen from %d choice%s\n",
+			num_configs, plural(num_configs));
+	}
+	return i;
 }
 
 #ifdef DEBUG
@@ -1210,8 +1274,8 @@
  *
  * This is called with devices which have been enumerated, but not yet
  * configured.  The device descriptor is available, but not descriptors
- * for any device configuration.  The caller must have locked udev and
- * either the parent hub (if udev is a normal device) or else the
+ * for any device configuration.  The caller must have locked either
+ * the parent hub (if udev is a normal device) or else the
  * usb_bus_list_lock (if udev is a root hub).  The parent's pointer to
  * udev has already been installed, but udev is not yet visible through
  * sysfs or other filesystem code.
@@ -1221,8 +1285,7 @@
  *
  * This call is synchronous, and may not be used in an interrupt context.
  *
- * Only the hub driver should ever call this; root hub registration
- * uses it indirectly.
+ * Only the hub driver or root-hub registrar should ever call this.
  */
 int usb_new_device(struct usb_device *udev)
 {
@@ -1269,15 +1332,9 @@
 					le16_to_cpu(udev->config[0].desc.wTotalLength),
 					USB_DT_OTG, (void **) &desc) == 0) {
 			if (desc->bmAttributes & USB_OTG_HNP) {
-				unsigned		port1;
+				unsigned		port1 = udev->portnum;
 				struct usb_device	*root = udev->parent;
 				
-				for (port1 = 1; port1 <= root->maxchild;
-						port1++) {
-					if (root->children[port1-1] == udev)
-						break;
-				}
-
 				dev_info(&udev->dev,
 					"Dual-Role OTG device on %sHNP port\n",
 					(port1 == bus->otg_port)
@@ -1331,27 +1388,27 @@
 	}
 	usb_create_sysfs_dev_files (udev);
 
+	usb_lock_device(udev);
+
 	/* choose and set the configuration. that registers the interfaces
 	 * with the driver core, and lets usb device drivers bind to them.
 	 */
 	c = choose_configuration(udev);
-	if (c < 0)
-		dev_warn(&udev->dev,
-				"can't choose an initial configuration\n");
-	else {
+	if (c >= 0) {
 		err = usb_set_configuration(udev, c);
 		if (err) {
 			dev_err(&udev->dev, "can't set config #%d, error %d\n",
 					c, err);
-			usb_remove_sysfs_dev_files(udev);
-			device_del(&udev->dev);
-			goto fail;
+			/* This need not be fatal.  The user can try to
+			 * set other configurations. */
 		}
 	}
 
 	/* USB device state == configured ... usable */
 	usb_notify_add_device(udev);
 
+	usb_unlock_device(udev);
+
 	return 0;
 
 fail:
@@ -1654,15 +1711,9 @@
 int usb_suspend_device(struct usb_device *udev)
 {
 #ifdef	CONFIG_USB_SUSPEND
-	int	port1, status;
-
-	port1 = locktree(udev);
-	if (port1 < 0)
-		return port1;
-
-	status = __usb_suspend_device(udev, port1);
-	usb_unlock_device(udev);
-	return status;
+	if (udev->state == USB_STATE_NOTATTACHED)
+		return -ENODEV;
+	return __usb_suspend_device(udev, udev->portnum);
 #else
 	/* NOTE:  udev->state unchanged, it's not lying ... */
 	udev->dev.power.power_state = PMSG_SUSPEND;
@@ -1694,13 +1745,14 @@
 	usb_set_device_state(udev, udev->actconfig
 			? USB_STATE_CONFIGURED
 			: USB_STATE_ADDRESS);
+	udev->dev.power.power_state = PMSG_ON;
 
  	/* 10.5.4.5 says be sure devices in the tree are still there.
  	 * For now let's assume the device didn't go crazy on resume,
 	 * and device drivers will know about any resume quirks.
 	 */
 	status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
-	if (status < 0)
+	if (status < 2)
 		dev_dbg(&udev->dev,
 			"gone after usb resume? status %d\n",
 			status);
@@ -1709,7 +1761,7 @@
 		int		(*resume)(struct device *);
 
 		le16_to_cpus(&devstatus);
-		if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)
+		if ((devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP))
 				&& udev->parent) {
 			status = usb_control_msg(udev,
 					usb_sndctrlpipe(udev, 0),
@@ -1729,8 +1781,14 @@
 		 * may have a child resume event to deal with soon
 		 */
 		resume = udev->dev.bus->resume;
-		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++)
-			(void) resume(&udev->actconfig->interface[i]->dev);
+		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
+			struct device *dev =
+					&udev->actconfig->interface[i]->dev;
+
+			down(&dev->sem);
+			(void) resume(dev);
+			up(&dev->sem);
+		}
 		status = 0;
 
 	} else if (udev->devnum <= 0) {
@@ -1813,11 +1871,10 @@
  */
 int usb_resume_device(struct usb_device *udev)
 {
-	int	port1, status;
+	int	status;
 
-	port1 = locktree(udev);
-	if (port1 < 0)
-		return port1;
+	if (udev->state == USB_STATE_NOTATTACHED)
+		return -ENODEV;
 
 #ifdef	CONFIG_USB_SUSPEND
 	/* selective resume of one downstream hub-to-device port */
@@ -1826,7 +1883,7 @@
 			// NOTE swsusp may bork us, device state being wrong...
 			// NOTE this fails if parent is also suspended...
 			status = hub_port_resume(hdev_to_hub(udev->parent),
-					port1, udev);
+					udev->portnum, udev);
 		} else
 			status = 0;
 	} else
@@ -1836,13 +1893,11 @@
 		dev_dbg(&udev->dev, "can't resume, status %d\n",
 			status);
 
-	usb_unlock_device(udev);
-
 	/* rebind drivers that had no suspend() */
 	if (status == 0) {
-		usb_lock_all_devices();
+		usb_unlock_device(udev);
 		bus_rescan_devices(&usb_bus_type);
-		usb_unlock_all_devices();
+		usb_lock_device(udev);
 	}
 	return status;
 }
@@ -1856,14 +1911,14 @@
 	/* don't repeat RESUME sequence if this device
 	 * was already woken up by some other task
 	 */
-	down(&udev->serialize);
+	usb_lock_device(udev);
 	if (udev->state == USB_STATE_SUSPENDED) {
 		dev_dbg(&udev->dev, "RESUME (wakeup)\n");
 		/* TRSMRCY = 10 msec */
 		msleep(10);
 		status = finish_device_resume(udev);
 	}
-	up(&udev->serialize);
+	usb_unlock_device(udev);
 #endif
 	return status;
 }
@@ -1964,7 +2019,7 @@
 
 		if (!udev || status < 0)
 			continue;
-		down (&udev->serialize);
+		usb_lock_device(udev);
 		if (portstat & USB_PORT_STAT_SUSPEND)
 			status = hub_port_resume(hub, port1, udev);
 		else {
@@ -1975,7 +2030,7 @@
 				hub_port_logical_disconnect(hub, port1);
 			}
 		}
-		up(&udev->serialize);
+		usb_unlock_device(udev);
 	}
 	}
 #endif
@@ -2359,39 +2414,36 @@
 {
 	struct usb_device *hdev = hub->hdev;
 	int remaining;
-	unsigned i;
+	int port1;
 
-	remaining = hub->power_budget;
-	if (!remaining)		/* self-powered */
+	if (!hub->limited_power)
 		return 0;
 
-	for (i = 0; i < hdev->maxchild; i++) {
-		struct usb_device	*udev = hdev->children[i];
-		int			delta, ceiling;
+	remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;
+	for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
+		struct usb_device	*udev = hdev->children[port1 - 1];
+		int			delta;
 
 		if (!udev)
 			continue;
 
-		/* 100mA per-port ceiling, or 8mA for OTG ports */
-		if (i != (udev->bus->otg_port - 1) || hdev->parent)
-			ceiling = 50;
-		else
-			ceiling = 4;
-
+		/* Unconfigured devices may not use more than 100mA,
+		 * or 8mA for OTG ports */
 		if (udev->actconfig)
-			delta = udev->actconfig->desc.bMaxPower;
+			delta = udev->actconfig->desc.bMaxPower * 2;
+		else if (port1 != udev->bus->otg_port || hdev->parent)
+			delta = 100;
 		else
-			delta = ceiling;
-		// dev_dbg(&udev->dev, "budgeted %dmA\n", 2 * delta);
-		if (delta > ceiling)
-			dev_warn(&udev->dev, "%dmA over %dmA budget!\n",
-				2 * (delta - ceiling), 2 * ceiling);
+			delta = 8;
+		if (delta > hub->mA_per_port)
+			dev_warn(&udev->dev, "%dmA is over %umA budget "
+					"for port %d!\n",
+					delta, hub->mA_per_port, port1);
 		remaining -= delta;
 	}
 	if (remaining < 0) {
-		dev_warn(hub->intfdev,
-			"%dmA over power budget!\n",
-			-2 * remaining);
+		dev_warn(hub->intfdev, "%dmA over power budget!\n",
+			- remaining);
 		remaining = 0;
 	}
 	return remaining;
@@ -2486,7 +2538,8 @@
 
 		usb_set_device_state(udev, USB_STATE_POWERED);
 		udev->speed = USB_SPEED_UNKNOWN;
- 
+ 		udev->bus_mA = hub->mA_per_port;
+
 		/* set the address */
 		choose_address(udev);
 		if (udev->devnum <= 0) {
@@ -2506,16 +2559,16 @@
 		 * on the parent.
 		 */
 		if (udev->descriptor.bDeviceClass == USB_CLASS_HUB
-				&& hub->power_budget) {
+				&& udev->bus_mA <= 100) {
 			u16	devstat;
 
 			status = usb_get_status(udev, USB_RECIP_DEVICE, 0,
 					&devstat);
-			if (status < 0) {
+			if (status < 2) {
 				dev_dbg(&udev->dev, "get status %d ?\n", status);
 				goto loop_disable;
 			}
-			cpu_to_le16s(&devstat);
+			le16_to_cpus(&devstat);
 			if ((devstat & (1 << USB_DEVICE_SELF_POWERED)) == 0) {
 				dev_err(&udev->dev,
 					"can't connect bus-powered hub "
@@ -2540,7 +2593,6 @@
 		 * udev becomes globally accessible, although presumably
 		 * no one will look at it until hdev is unlocked.
 		 */
-		down (&udev->serialize);
 		status = 0;
 
 		/* We mustn't add new devices if the parent hub has
@@ -2564,15 +2616,12 @@
 			}
 		}
 
-		up (&udev->serialize);
 		if (status)
 			goto loop_disable;
 
 		status = hub_power_remaining(hub);
 		if (status)
-			dev_dbg(hub_dev,
-				"%dmA power budget left\n",
-				2 * status);
+			dev_dbg(hub_dev, "%dmA power budget left\n", status);
 
 		return;
 
@@ -2648,6 +2697,8 @@
 		if (i) {
 			dpm_runtime_resume(&hdev->dev);
 			dpm_runtime_resume(&intf->dev);
+			usb_put_intf(intf);
+			continue;
 		}
 
 		/* Lock the device, then check to see if we were
@@ -2661,7 +2712,7 @@
 
 		/* If the hub has died, clean up after it */
 		if (hdev->state == USB_STATE_NOTATTACHED) {
-			hub_pre_reset(hub);
+			hub_pre_reset(hub, 0);
 			goto loop;
 		}
 
@@ -2784,6 +2835,11 @@
 			if (hubchange & HUB_CHANGE_LOCAL_POWER) {
 				dev_dbg (hub_dev, "power change\n");
 				clear_hub_feature(hdev, C_HUB_LOCAL_POWER);
+				if (hubstatus & HUB_STATUS_LOCAL_POWER)
+					/* FIXME: Is this always true? */
+					hub->limited_power = 0;
+				else
+					hub->limited_power = 1;
 			}
 			if (hubchange & HUB_CHANGE_OVERCURRENT) {
 				dev_dbg (hub_dev, "overcurrent change\n");
@@ -2832,7 +2888,6 @@
 MODULE_DEVICE_TABLE (usb, hub_id_table);
 
 static struct usb_driver hub_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"hub",
 	.probe =	hub_probe,
 	.disconnect =	hub_disconnect,
@@ -2944,7 +2999,8 @@
 	struct usb_hub			*parent_hub;
 	struct usb_device_descriptor	descriptor = udev->descriptor;
 	struct usb_hub			*hub = NULL;
-	int 				i, ret = 0, port1 = -1;
+	int 				i, ret = 0;
+	int				port1 = udev->portnum;
 
 	if (udev->state == USB_STATE_NOTATTACHED ||
 			udev->state == USB_STATE_SUSPENDED) {
@@ -2958,18 +3014,6 @@
 		dev_dbg(&udev->dev, "%s for root hub!\n", __FUNCTION__);
 		return -EISDIR;
 	}
-
-	for (i = 0; i < parent_hdev->maxchild; i++)
-		if (parent_hdev->children[i] == udev) {
-			port1 = i + 1;
-			break;
-		}
-
-	if (port1 < 0) {
-		/* If this ever happens, it's very bad */
-		dev_err(&udev->dev, "Can't locate device's port!\n");
-		return -ENOENT;
-	}
 	parent_hub = hdev_to_hub(parent_hdev);
 
 	/* If we're resetting an active hub, take some special actions */
@@ -2977,7 +3021,7 @@
 			udev->actconfig->interface[0]->dev.driver ==
 				&hub_driver.driver &&
 			(hub = hdev_to_hub(udev)) != NULL) {
-		hub_pre_reset(hub);
+		hub_pre_reset(hub, 0);
 	}
 
 	set_bit(port1, parent_hub->busy_bits);
diff --git a/drivers/usb/core/hub.h b/drivers/usb/core/hub.h
index bf23f89..29d5f45 100644
--- a/drivers/usb/core/hub.h
+++ b/drivers/usb/core/hub.h
@@ -220,8 +220,9 @@
 	struct usb_hub_descriptor *descriptor;	/* class descriptor */
 	struct usb_tt		tt;		/* Transaction Translator */
 
-	u8			power_budget;	/* in 2mA units; or zero */
+	unsigned		mA_per_port;	/* current for each child */
 
+	unsigned		limited_power:1;
 	unsigned		quiescing:1;
 	unsigned		activating:1;
 	unsigned		resume_root_hub:1;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index c44bbed..4ddc453 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -186,7 +186,7 @@
 
 	down(&bus->d_inode->i_sem);
 
-	list_for_each_entry(dev, &bus->d_subdirs, d_child)
+	list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child)
 		if (dev->d_inode)
 			update_dev(dev);
 
@@ -203,7 +203,7 @@
 
 	down(&root->d_inode->i_sem);
 
-	list_for_each_entry(bus, &root->d_subdirs, d_child) {
+	list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
 		if (bus->d_inode) {
 			switch (S_IFMT & bus->d_inode->i_mode) {
 			case S_IFDIR:
@@ -319,7 +319,7 @@
 	spin_lock(&dcache_lock);
 
 	list_for_each(list, &dentry->d_subdirs) {
-		struct dentry *de = list_entry(list, struct dentry, d_child);
+		struct dentry *de = list_entry(list, struct dentry, d_u.d_child);
 		if (usbfs_positive(de)) {
 			spin_unlock(&dcache_lock);
 			return 0;
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index fe74f99..319de03 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1387,6 +1387,12 @@
 	if (dev->state != USB_STATE_ADDRESS)
 		usb_disable_device (dev, 1);	// Skip ep0
 
+	i = dev->bus_mA - cp->desc.bMaxPower * 2;
+	if (i < 0)
+		dev_warn(&dev->dev, "new config #%d exceeds power "
+				"limit by %dmA\n",
+				configuration, -i);
+
 	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 			USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
 			NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index e197ce9..13d1d36 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -32,7 +32,6 @@
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/smp_lock.h>
-#include <linux/rwsem.h>
 #include <linux/usb.h>
 
 #include <asm/io.h>
@@ -47,165 +46,7 @@
 const char *usbcore_name = "usbcore";
 
 static int nousb;	/* Disable USB when built into kernel image */
-			/* Not honored on modular build */
 
-static DECLARE_RWSEM(usb_all_devices_rwsem);
-
-
-static int generic_probe (struct device *dev)
-{
-	return 0;
-}
-static int generic_remove (struct device *dev)
-{
-	struct usb_device *udev = to_usb_device(dev);
-
-	/* if this is only an unbind, not a physical disconnect, then
-	 * unconfigure the device */
-	if (udev->state == USB_STATE_CONFIGURED)
-		usb_set_configuration(udev, 0);
-
-	/* in case the call failed or the device was suspended */
-	if (udev->state >= USB_STATE_CONFIGURED)
-		usb_disable_device(udev, 0);
-	return 0;
-}
-
-static struct device_driver usb_generic_driver = {
-	.owner = THIS_MODULE,
-	.name =	"usb",
-	.bus = &usb_bus_type,
-	.probe = generic_probe,
-	.remove = generic_remove,
-};
-
-static int usb_generic_driver_data;
-
-/* called from driver core with usb_bus_type.subsys writelock */
-static int usb_probe_interface(struct device *dev)
-{
-	struct usb_interface * intf = to_usb_interface(dev);
-	struct usb_driver * driver = to_usb_driver(dev->driver);
-	const struct usb_device_id *id;
-	int error = -ENODEV;
-
-	dev_dbg(dev, "%s\n", __FUNCTION__);
-
-	if (!driver->probe)
-		return error;
-	/* FIXME we'd much prefer to just resume it ... */
-	if (interface_to_usbdev(intf)->state == USB_STATE_SUSPENDED)
-		return -EHOSTUNREACH;
-
-	id = usb_match_id (intf, driver->id_table);
-	if (id) {
-		dev_dbg (dev, "%s - got id\n", __FUNCTION__);
-
-		/* Interface "power state" doesn't correspond to any hardware
-		 * state whatsoever.  We use it to record when it's bound to
-		 * a driver that may start I/0:  it's not frozen/quiesced.
-		 */
-		mark_active(intf);
-		intf->condition = USB_INTERFACE_BINDING;
-		error = driver->probe (intf, id);
-		if (error) {
-			mark_quiesced(intf);
-			intf->condition = USB_INTERFACE_UNBOUND;
-		} else
-			intf->condition = USB_INTERFACE_BOUND;
-	}
-
-	return error;
-}
-
-/* called from driver core with usb_bus_type.subsys writelock */
-static int usb_unbind_interface(struct device *dev)
-{
-	struct usb_interface *intf = to_usb_interface(dev);
-	struct usb_driver *driver = to_usb_driver(intf->dev.driver);
-
-	intf->condition = USB_INTERFACE_UNBINDING;
-
-	/* release all urbs for this interface */
-	usb_disable_interface(interface_to_usbdev(intf), intf);
-
-	if (driver && driver->disconnect)
-		driver->disconnect(intf);
-
-	/* reset other interface state */
-	usb_set_interface(interface_to_usbdev(intf),
-			intf->altsetting[0].desc.bInterfaceNumber,
-			0);
-	usb_set_intfdata(intf, NULL);
-	intf->condition = USB_INTERFACE_UNBOUND;
-	mark_quiesced(intf);
-
-	return 0;
-}
-
-/**
- * usb_register - register a USB driver
- * @new_driver: USB operations for the driver
- *
- * Registers a USB driver with the USB core.  The list of unattached
- * interfaces will be rescanned whenever a new driver is added, allowing
- * the new driver to attach to any recognized devices.
- * Returns a negative error code on failure and 0 on success.
- * 
- * NOTE: if you want your driver to use the USB major number, you must call
- * usb_register_dev() to enable that functionality.  This function no longer
- * takes care of that.
- */
-int usb_register(struct usb_driver *new_driver)
-{
-	int retval = 0;
-
-	if (nousb)
-		return -ENODEV;
-
-	new_driver->driver.name = (char *)new_driver->name;
-	new_driver->driver.bus = &usb_bus_type;
-	new_driver->driver.probe = usb_probe_interface;
-	new_driver->driver.remove = usb_unbind_interface;
-	new_driver->driver.owner = new_driver->owner;
-
-	usb_lock_all_devices();
-	retval = driver_register(&new_driver->driver);
-	usb_unlock_all_devices();
-
-	if (!retval) {
-		pr_info("%s: registered new driver %s\n",
-			usbcore_name, new_driver->name);
-		usbfs_update_special();
-	} else {
-		printk(KERN_ERR "%s: error %d registering driver %s\n",
-			usbcore_name, retval, new_driver->name);
-	}
-
-	return retval;
-}
-
-/**
- * usb_deregister - unregister a USB driver
- * @driver: USB operations of the driver to unregister
- * Context: must be able to sleep
- *
- * Unlinks the specified driver from the internal USB driver list.
- * 
- * NOTE: If you called usb_register_dev(), you still need to call
- * usb_deregister_dev() to clean up your driver's allocated minor numbers,
- * this * call will no longer do it for you.
- */
-void usb_deregister(struct usb_driver *driver)
-{
-	pr_info("%s: deregistering driver %s\n", usbcore_name, driver->name);
-
-	usb_lock_all_devices();
-	driver_unregister (&driver->driver);
-	usb_unlock_all_devices();
-
-	usbfs_update_special();
-}
 
 /**
  * usb_ifnum_to_if - get the interface object with a given interface number
@@ -352,151 +193,23 @@
 	mark_quiesced(iface);
 }
 
-/**
- * usb_match_id - find first usb_device_id matching device or interface
- * @interface: the interface of interest
- * @id: array of usb_device_id structures, terminated by zero entry
- *
- * usb_match_id searches an array of usb_device_id's and returns
- * the first one matching the device or interface, or null.
- * This is used when binding (or rebinding) a driver to an interface.
- * Most USB device drivers will use this indirectly, through the usb core,
- * but some layered driver frameworks use it directly.
- * These device tables are exported with MODULE_DEVICE_TABLE, through
- * modutils and "modules.usbmap", to support the driver loading
- * functionality of USB hotplugging.
- *
- * What Matches:
- *
- * The "match_flags" element in a usb_device_id controls which
- * members are used.  If the corresponding bit is set, the
- * value in the device_id must match its corresponding member
- * in the device or interface descriptor, or else the device_id
- * does not match.
- *
- * "driver_info" is normally used only by device drivers,
- * but you can create a wildcard "matches anything" usb_device_id
- * as a driver's "modules.usbmap" entry if you provide an id with
- * only a nonzero "driver_info" field.  If you do this, the USB device
- * driver's probe() routine should use additional intelligence to
- * decide whether to bind to the specified interface.
- * 
- * What Makes Good usb_device_id Tables:
- *
- * The match algorithm is very simple, so that intelligence in
- * driver selection must come from smart driver id records.
- * Unless you have good reasons to use another selection policy,
- * provide match elements only in related groups, and order match
- * specifiers from specific to general.  Use the macros provided
- * for that purpose if you can.
- *
- * The most specific match specifiers use device descriptor
- * data.  These are commonly used with product-specific matches;
- * the USB_DEVICE macro lets you provide vendor and product IDs,
- * and you can also match against ranges of product revisions.
- * These are widely used for devices with application or vendor
- * specific bDeviceClass values.
- *
- * Matches based on device class/subclass/protocol specifications
- * are slightly more general; use the USB_DEVICE_INFO macro, or
- * its siblings.  These are used with single-function devices
- * where bDeviceClass doesn't specify that each interface has
- * its own class. 
- *
- * Matches based on interface class/subclass/protocol are the
- * most general; they let drivers bind to any interface on a
- * multiple-function device.  Use the USB_INTERFACE_INFO
- * macro, or its siblings, to match class-per-interface style 
- * devices (as recorded in bDeviceClass).
- *  
- * Within those groups, remember that not all combinations are
- * meaningful.  For example, don't give a product version range
- * without vendor and product IDs; or specify a protocol without
- * its associated class and subclass.
- */   
-const struct usb_device_id *
-usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
-{
-	struct usb_host_interface *intf;
-	struct usb_device *dev;
-
-	/* proc_connectinfo in devio.c may call us with id == NULL. */
-	if (id == NULL)
-		return NULL;
-
-	intf = interface->cur_altsetting;
-	dev = interface_to_usbdev(interface);
-
-	/* It is important to check that id->driver_info is nonzero,
-	   since an entry that is all zeroes except for a nonzero
-	   id->driver_info is the way to create an entry that
-	   indicates that the driver want to examine every
-	   device and interface. */
-	for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass ||
-	       id->driver_info; id++) {
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
-		    id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
-		    id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
-			continue;
-
-		/* No need to test id->bcdDevice_lo != 0, since 0 is never
-		   greater than any unsigned number. */
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
-		    (id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
-		    (id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
-		    (id->bDeviceClass != dev->descriptor.bDeviceClass))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
-		    (id->bDeviceSubClass!= dev->descriptor.bDeviceSubClass))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
-		    (id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
-		    (id->bInterfaceClass != intf->desc.bInterfaceClass))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
-		    (id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))
-			continue;
-
-		if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
-		    (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
-			continue;
-
-		return id;
-	}
-
-	return NULL;
-}
-
+struct find_interface_arg {
+	int minor;
+	struct usb_interface *interface;
+};
 
 static int __find_interface(struct device * dev, void * data)
 {
-	struct usb_interface ** ret = (struct usb_interface **)data;
-	struct usb_interface * intf = *ret;
-	int *minor = (int *)data;
+	struct find_interface_arg *arg = data;
+	struct usb_interface *intf;
 
 	/* can't look at usb devices, only interfaces */
 	if (dev->driver == &usb_generic_driver)
 		return 0;
 
 	intf = to_usb_interface(dev);
-	if (intf->minor != -1 && intf->minor == *minor) {
-		*ret = intf;
+	if (intf->minor != -1 && intf->minor == arg->minor) {
+		arg->interface = intf;
 		return 1;
 	}
 	return 0;
@@ -513,42 +226,18 @@
  */
 struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
 {
-	struct usb_interface *intf = (struct usb_interface *)(long)minor;
-	int ret;
+	struct find_interface_arg argb;
 
-	ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface);
-
-	return ret ? intf : NULL;
+	argb.minor = minor;
+	argb.interface = NULL;
+	driver_for_each_device(&drv->driver, NULL, &argb, __find_interface);
+	return argb.interface;
 }
 
-static int usb_device_match (struct device *dev, struct device_driver *drv)
-{
-	struct usb_interface *intf;
-	struct usb_driver *usb_drv;
-	const struct usb_device_id *id;
-
-	/* check for generic driver, which we don't match any device with */
-	if (drv == &usb_generic_driver)
-		return 0;
-
-	intf = to_usb_interface(dev);
-	usb_drv = to_usb_driver(drv);
-	
-	id = usb_match_id (intf, usb_drv->id_table);
-	if (id)
-		return 1;
-
-	return 0;
-}
-
-
 #ifdef	CONFIG_HOTPLUG
 
 /*
- * USB hotplugging invokes what /proc/sys/kernel/hotplug says
- * (normally /sbin/hotplug) when USB devices get added or removed.
- *
- * This invokes a user mode policy agent, typically helping to load driver
+ * This sends an uevent to userspace, typically helping to load driver
  * or other modules, configure the device, and more.  Drivers can provide
  * a MODULE_DEVICE_TABLE to help with module loading subtasks.
  *
@@ -557,8 +246,8 @@
  * delays in event delivery.  Use sysfs (and DEVPATH) to make sure the
  * device (and this configuration!) are still present.
  */
-static int usb_hotplug (struct device *dev, char **envp, int num_envp,
-			char *buffer, int buffer_size)
+static int usb_uevent(struct device *dev, char **envp, int num_envp,
+		      char *buffer, int buffer_size)
 {
 	struct usb_interface *intf;
 	struct usb_device *usb_dev;
@@ -570,7 +259,7 @@
 		return -ENODEV;
 
 	/* driver is often null here; dev_dbg() would oops */
-	pr_debug ("usb %s: hotplug\n", dev->bus_id);
+	pr_debug ("usb %s: uevent\n", dev->bus_id);
 
 	/* Must check driver_data here, as on remove driver is always NULL */
 	if ((dev->driver == &usb_generic_driver) || 
@@ -597,51 +286,51 @@
 	 *
 	 * FIXME reduce hardwired intelligence here
 	 */
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"DEVICE=/proc/bus/usb/%03d/%03d",
-				usb_dev->bus->busnum, usb_dev->devnum))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "DEVICE=/proc/bus/usb/%03d/%03d",
+			   usb_dev->bus->busnum, usb_dev->devnum))
 		return -ENOMEM;
 #endif
 
 	/* per-device configurations are common */
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"PRODUCT=%x/%x/%x",
-				le16_to_cpu(usb_dev->descriptor.idVendor),
-				le16_to_cpu(usb_dev->descriptor.idProduct),
-				le16_to_cpu(usb_dev->descriptor.bcdDevice)))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "PRODUCT=%x/%x/%x",
+			   le16_to_cpu(usb_dev->descriptor.idVendor),
+			   le16_to_cpu(usb_dev->descriptor.idProduct),
+			   le16_to_cpu(usb_dev->descriptor.bcdDevice)))
 		return -ENOMEM;
 
 	/* class-based driver binding models */
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"TYPE=%d/%d/%d",
-				usb_dev->descriptor.bDeviceClass,
-				usb_dev->descriptor.bDeviceSubClass,
-				usb_dev->descriptor.bDeviceProtocol))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "TYPE=%d/%d/%d",
+			   usb_dev->descriptor.bDeviceClass,
+			   usb_dev->descriptor.bDeviceSubClass,
+			   usb_dev->descriptor.bDeviceProtocol))
 		return -ENOMEM;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"INTERFACE=%d/%d/%d",
-				alt->desc.bInterfaceClass,
-				alt->desc.bInterfaceSubClass,
-				alt->desc.bInterfaceProtocol))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "INTERFACE=%d/%d/%d",
+			   alt->desc.bInterfaceClass,
+			   alt->desc.bInterfaceSubClass,
+			   alt->desc.bInterfaceProtocol))
 		return -ENOMEM;
 
-	if (add_hotplug_env_var(envp, num_envp, &i,
-				buffer, buffer_size, &length,
-				"MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
-				le16_to_cpu(usb_dev->descriptor.idVendor),
-				le16_to_cpu(usb_dev->descriptor.idProduct),
-				le16_to_cpu(usb_dev->descriptor.bcdDevice),
-				usb_dev->descriptor.bDeviceClass,
-				usb_dev->descriptor.bDeviceSubClass,
-				usb_dev->descriptor.bDeviceProtocol,
-				alt->desc.bInterfaceClass,
-				alt->desc.bInterfaceSubClass,
-				alt->desc.bInterfaceProtocol))
+	if (add_uevent_var(envp, num_envp, &i,
+			   buffer, buffer_size, &length,
+			   "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
+			   le16_to_cpu(usb_dev->descriptor.idVendor),
+			   le16_to_cpu(usb_dev->descriptor.idProduct),
+			   le16_to_cpu(usb_dev->descriptor.bcdDevice),
+			   usb_dev->descriptor.bDeviceClass,
+			   usb_dev->descriptor.bDeviceSubClass,
+			   usb_dev->descriptor.bDeviceProtocol,
+			   alt->desc.bInterfaceClass,
+			   alt->desc.bInterfaceSubClass,
+			   alt->desc.bInterfaceProtocol))
 		return -ENOMEM;
 
 	envp[i] = NULL;
@@ -651,7 +340,7 @@
 
 #else
 
-static int usb_hotplug (struct device *dev, char **envp,
+static int usb_uevent(struct device *dev, char **envp,
 			int num_envp, char *buffer, int buffer_size)
 {
 	return -ENODEV;
@@ -750,12 +439,11 @@
 		/* hub driver sets up TT records */
 	}
 
+	dev->portnum = port1;
 	dev->bus = bus;
 	dev->parent = parent;
 	INIT_LIST_HEAD(&dev->filelist);
 
-	init_MUTEX(&dev->serialize);
-
 	return dev;
 }
 
@@ -828,76 +516,21 @@
 
 /*			USB device locking
  *
- * Although locking USB devices should be straightforward, it is
- * complicated by the way the driver-model core works.  When a new USB
- * driver is registered or unregistered, the core will automatically
- * probe or disconnect all matching interfaces on all USB devices while
- * holding the USB subsystem writelock.  There's no good way for us to
- * tell which devices will be used or to lock them beforehand; our only
- * option is to effectively lock all the USB devices.
- *
- * We do that by using a private rw-semaphore, usb_all_devices_rwsem.
- * When locking an individual device you must first acquire the rwsem's
- * readlock.  When a driver is registered or unregistered the writelock
- * must be held.  These actions are encapsulated in the subroutines
- * below, so all a driver needs to do is call usb_lock_device() and
- * usb_unlock_device().
+ * USB devices and interfaces are locked using the semaphore in their
+ * embedded struct device.  The hub driver guarantees that whenever a
+ * device is connected or disconnected, drivers are called with the
+ * USB device locked as well as their particular interface.
  *
  * Complications arise when several devices are to be locked at the same
  * time.  Only hub-aware drivers that are part of usbcore ever have to
- * do this; nobody else needs to worry about it.  The problem is that
- * usb_lock_device() must not be called to lock a second device since it
- * would acquire the rwsem's readlock reentrantly, leading to deadlock if
- * another thread was waiting for the writelock.  The solution is simple:
- *
- *	When locking more than one device, call usb_lock_device()
- *	to lock the first one.  Lock the others by calling
- *	down(&udev->serialize) directly.
- *
- *	When unlocking multiple devices, use up(&udev->serialize)
- *	to unlock all but the last one.  Unlock the last one by
- *	calling usb_unlock_device().
+ * do this; nobody else needs to worry about it.  The rule for locking
+ * is simple:
  *
  *	When locking both a device and its parent, always lock the
  *	the parent first.
  */
 
 /**
- * usb_lock_device - acquire the lock for a usb device structure
- * @udev: device that's being locked
- *
- * Use this routine when you don't hold any other device locks;
- * to acquire nested inner locks call down(&udev->serialize) directly.
- * This is necessary for proper interaction with usb_lock_all_devices().
- */
-void usb_lock_device(struct usb_device *udev)
-{
-	down_read(&usb_all_devices_rwsem);
-	down(&udev->serialize);
-}
-
-/**
- * usb_trylock_device - attempt to acquire the lock for a usb device structure
- * @udev: device that's being locked
- *
- * Don't use this routine if you already hold a device lock;
- * use down_trylock(&udev->serialize) instead.
- * This is necessary for proper interaction with usb_lock_all_devices().
- *
- * Returns 1 if successful, 0 if contention.
- */
-int usb_trylock_device(struct usb_device *udev)
-{
-	if (!down_read_trylock(&usb_all_devices_rwsem))
-		return 0;
-	if (down_trylock(&udev->serialize)) {
-		up_read(&usb_all_devices_rwsem);
-		return 0;
-	}
-	return 1;
-}
-
-/**
  * usb_lock_device_for_reset - cautiously acquire the lock for a
  *	usb device structure
  * @udev: device that's being locked
@@ -935,7 +568,7 @@
 		}
 	}
 
-	while (!usb_trylock_device(udev)) {
+	while (usb_trylock_device(udev) != 0) {
 
 		/* If we can't acquire the lock after waiting one second,
 		 * we're probably deadlocked */
@@ -953,39 +586,6 @@
 	return 1;
 }
 
-/**
- * usb_unlock_device - release the lock for a usb device structure
- * @udev: device that's being unlocked
- *
- * Use this routine when releasing the only device lock you hold;
- * to release inner nested locks call up(&udev->serialize) directly.
- * This is necessary for proper interaction with usb_lock_all_devices().
- */
-void usb_unlock_device(struct usb_device *udev)
-{
-	up(&udev->serialize);
-	up_read(&usb_all_devices_rwsem);
-}
-
-/**
- * usb_lock_all_devices - acquire the lock for all usb device structures
- *
- * This is necessary when registering a new driver or probing a bus,
- * since the driver-model core may try to use any usb_device.
- */
-void usb_lock_all_devices(void)
-{
-	down_write(&usb_all_devices_rwsem);
-}
-
-/**
- * usb_unlock_all_devices - release the lock for all usb device structures
- */
-void usb_unlock_all_devices(void)
-{
-	up_write(&usb_all_devices_rwsem);
-}
-
 
 static struct usb_device *match_device(struct usb_device *dev,
 				       u16 vendor_id, u16 product_id)
@@ -1008,10 +608,10 @@
 	/* look through all of the children of this device */
 	for (child = 0; child < dev->maxchild; ++child) {
 		if (dev->children[child]) {
-			down(&dev->children[child]->serialize);
+			usb_lock_device(dev->children[child]);
 			ret_dev = match_device(dev->children[child],
 					       vendor_id, product_id);
-			up(&dev->children[child]->serialize);
+			usb_unlock_device(dev->children[child]);
 			if (ret_dev)
 				goto exit;
 		}
@@ -1432,7 +1032,8 @@
 			mark_quiesced(intf);
 	} else {
 		// FIXME else if there's no suspend method, disconnect...
-		dev_warn(dev, "no %s?\n", "suspend");
+		dev_warn(dev, "no suspend for driver %s?\n", driver->name);
+		mark_quiesced(intf);
 		status = 0;
 	}
 	return status;
@@ -1460,8 +1061,10 @@
 	}
 
 	if ((dev->driver == NULL) ||
-	    (dev->driver_data == &usb_generic_driver_data))
+	    (dev->driver_data == &usb_generic_driver_data)) {
+		dev->power.power_state.event = PM_EVENT_FREEZE;
 		return 0;
+	}
 
 	intf = to_usb_interface(dev);
 	driver = to_usb_driver(dev->driver);
@@ -1481,30 +1084,20 @@
 			mark_quiesced(intf);
 		}
 	} else
-		dev_warn(dev, "no %s?\n", "resume");
+		dev_warn(dev, "no resume for driver %s?\n", driver->name);
 	return 0;
 }
 
 struct bus_type usb_bus_type = {
 	.name =		"usb",
 	.match =	usb_device_match,
-	.hotplug =	usb_hotplug,
+	.uevent =	usb_uevent,
 	.suspend =	usb_generic_suspend,
 	.resume =	usb_generic_resume,
 };
 
-#ifndef MODULE
-
-static int __init usb_setup_disable(char *str)
-{
-	nousb = 1;
-	return 1;
-}
-
 /* format to disable USB on kernel command line is: nousb */
-__setup("nousb", usb_setup_disable);
-
-#endif
+__module_param_call("", nousb, param_set_bool, param_get_bool, &nousb, 0444);
 
 /*
  * for external read access to <nousb>
@@ -1595,8 +1188,6 @@
  * driver modules to use.
  */
 
-EXPORT_SYMBOL(usb_register);
-EXPORT_SYMBOL(usb_deregister);
 EXPORT_SYMBOL(usb_disabled);
 
 EXPORT_SYMBOL_GPL(usb_get_intf);
@@ -1607,14 +1198,10 @@
 EXPORT_SYMBOL(usb_get_dev);
 EXPORT_SYMBOL(usb_hub_tt_clear_buffer);
 
-EXPORT_SYMBOL(usb_lock_device);
-EXPORT_SYMBOL(usb_trylock_device);
 EXPORT_SYMBOL(usb_lock_device_for_reset);
-EXPORT_SYMBOL(usb_unlock_device);
 
 EXPORT_SYMBOL(usb_driver_claim_interface);
 EXPORT_SYMBOL(usb_driver_release_interface);
-EXPORT_SYMBOL(usb_match_id);
 EXPORT_SYMBOL(usb_find_interface);
 EXPORT_SYMBOL(usb_ifnum_to_if);
 EXPORT_SYMBOL(usb_altnum_to_altsetting);
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index 1c4a684..4647e1e 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -16,9 +16,6 @@
 extern char *usb_cache_string(struct usb_device *udev, int index);
 extern int usb_set_configuration(struct usb_device *dev, int configuration);
 
-extern void usb_lock_all_devices(void);
-extern void usb_unlock_all_devices(void);
-
 extern void usb_kick_khubd(struct usb_device *dev);
 extern void usb_suspend_root_hub(struct usb_device *hdev);
 extern void usb_resume_root_hub(struct usb_device *dev);
@@ -33,6 +30,9 @@
 extern int usb_suspend_device(struct usb_device *dev);
 extern int usb_resume_device(struct usb_device *dev);
 
+extern struct device_driver usb_generic_driver;
+extern int usb_generic_driver_data;
+extern int usb_device_match(struct device *dev, struct device_driver *drv);
 
 /* Interfaces and their "power state" are owned by usbcore */
 
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index c655d46..9734cb7 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -138,7 +138,7 @@
 	/* or like sa1100: two fixed function endpoints */
 	"ep1out-bulk", "ep2in-bulk",
 };
-#define DUMMY_ENDPOINTS	(sizeof(ep_name)/sizeof(char *))
+#define DUMMY_ENDPOINTS	ARRAY_SIZE(ep_name)
 
 /*-------------------------------------------------------------------------*/
 
@@ -896,7 +896,7 @@
 #endif
 }
 
-static int dummy_udc_probe (struct platform_device *dev)
+static int dummy_udc_probe (struct platform_device *pdev)
 {
 	struct dummy	*dum = the_controller;
 	int		rc;
@@ -909,7 +909,7 @@
 	dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0);
 
 	strcpy (dum->gadget.dev.bus_id, "gadget");
-	dum->gadget.dev.parent = &dev->dev;
+	dum->gadget.dev.parent = &pdev->dev;
 	dum->gadget.dev.release = dummy_gadget_release;
 	rc = device_register (&dum->gadget.dev);
 	if (rc < 0)
@@ -919,47 +919,47 @@
 	usb_bus_get (&dummy_to_hcd (dum)->self);
 #endif
 
-	platform_set_drvdata (dev, dum);
+	platform_set_drvdata (pdev, dum);
 	device_create_file (&dum->gadget.dev, &dev_attr_function);
 	return rc;
 }
 
-static int dummy_udc_remove (struct platform_device *dev)
+static int dummy_udc_remove (struct platform_device *pdev)
 {
-	struct dummy	*dum = platform_get_drvdata (dev);
+	struct dummy	*dum = platform_get_drvdata (pdev);
 
-	platform_set_drvdata (dev, NULL);
+	platform_set_drvdata (pdev, NULL);
 	device_remove_file (&dum->gadget.dev, &dev_attr_function);
 	device_unregister (&dum->gadget.dev);
 	return 0;
 }
 
-static int dummy_udc_suspend (struct platform_device *dev, pm_message_t state)
+static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state)
 {
-	struct dummy	*dum = platform_get_drvdata(dev);
+	struct dummy	*dum = platform_get_drvdata(pdev);
 
-	dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
+	dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 	spin_lock_irq (&dum->lock);
 	dum->udc_suspended = 1;
 	set_link_state (dum);
 	spin_unlock_irq (&dum->lock);
 
-	dev->dev.power.power_state = state;
+	pdev->dev.power.power_state = state;
 	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
 	return 0;
 }
 
-static int dummy_udc_resume (struct platform_device *dev)
+static int dummy_udc_resume (struct platform_device *pdev)
 {
-	struct dummy	*dum = platform_get_drvdata(dev);
+	struct dummy	*dum = platform_get_drvdata(pdev);
 
-	dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
+	dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 	spin_lock_irq (&dum->lock);
 	dum->udc_suspended = 0;
 	set_link_state (dum);
 	spin_unlock_irq (&dum->lock);
 
-	dev->dev.power.power_state = PMSG_ON;
+	pdev->dev.power.power_state = PMSG_ON;
 	usb_hcd_poll_rh_status (dummy_to_hcd (dum));
 	return 0;
 }
@@ -1576,7 +1576,7 @@
 	dum = hcd_to_dummy (hcd);
 
 	spin_lock_irqsave (&dum->lock, flags);
-	if (hcd->state != HC_STATE_RUNNING)
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
 		goto done;
 
 	if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) {
@@ -1623,7 +1623,7 @@
 	int		retval = 0;
 	unsigned long	flags;
 
-	if (hcd->state != HC_STATE_RUNNING)
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
 		return -ETIMEDOUT;
 
 	dum = hcd_to_dummy (hcd);
@@ -1756,9 +1756,12 @@
 {
 	struct dummy *dum = hcd_to_dummy (hcd);
 
+	dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__);
+
 	spin_lock_irq (&dum->lock);
 	dum->rh_state = DUMMY_RH_SUSPENDED;
 	set_link_state (dum);
+	hcd->state = HC_STATE_SUSPENDED;
 	spin_unlock_irq (&dum->lock);
 	return 0;
 }
@@ -1766,14 +1769,23 @@
 static int dummy_bus_resume (struct usb_hcd *hcd)
 {
 	struct dummy *dum = hcd_to_dummy (hcd);
+	int rc = 0;
+
+	dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__);
 
 	spin_lock_irq (&dum->lock);
-	dum->rh_state = DUMMY_RH_RUNNING;
-	set_link_state (dum);
-	if (!list_empty(&dum->urbp_list))
-		mod_timer (&dum->timer, jiffies);
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+		dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n");
+		rc = -ENODEV;
+	} else {
+		dum->rh_state = DUMMY_RH_RUNNING;
+		set_link_state (dum);
+		if (!list_empty(&dum->urbp_list))
+			mod_timer (&dum->timer, jiffies);
+		hcd->state = HC_STATE_RUNNING;
+	}
 	spin_unlock_irq (&dum->lock);
-	return 0;
+	return rc;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -1899,14 +1911,14 @@
 	.bus_resume =		dummy_bus_resume,
 };
 
-static int dummy_hcd_probe (struct platform_device *dev)
+static int dummy_hcd_probe(struct platform_device *pdev)
 {
 	struct usb_hcd		*hcd;
 	int			retval;
 
-	dev_info(&dev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
+	dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc);
 
-	hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id);
+	hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, pdev->dev.bus_id);
 	if (!hcd)
 		return -ENOMEM;
 	the_controller = hcd_to_dummy (hcd);
@@ -1919,36 +1931,43 @@
 	return retval;
 }
 
-static int dummy_hcd_remove (struct platform_device *dev)
+static int dummy_hcd_remove (struct platform_device *pdev)
 {
 	struct usb_hcd		*hcd;
 
-	hcd = platform_get_drvdata (dev);
+	hcd = platform_get_drvdata (pdev);
 	usb_remove_hcd (hcd);
 	usb_put_hcd (hcd);
 	the_controller = NULL;
 	return 0;
 }
 
-static int dummy_hcd_suspend (struct platform_device *dev, pm_message_t state)
+static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state)
 {
 	struct usb_hcd		*hcd;
+	struct dummy		*dum;
+	int			rc = 0;
 
-	dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
-	hcd = platform_get_drvdata (dev);
+	dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 
-	hcd->state = HC_STATE_SUSPENDED;
-	return 0;
+	hcd = platform_get_drvdata (pdev);
+	dum = hcd_to_dummy (hcd);
+	if (dum->rh_state == DUMMY_RH_RUNNING) {
+		dev_warn(&pdev->dev, "Root hub isn't suspended!\n");
+		rc = -EBUSY;
+	} else
+		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+	return rc;
 }
 
-static int dummy_hcd_resume (struct platform_device *dev)
+static int dummy_hcd_resume (struct platform_device *pdev)
 {
 	struct usb_hcd		*hcd;
 
-	dev_dbg (&dev->dev, "%s\n", __FUNCTION__);
-	hcd = platform_get_drvdata (dev);
-	hcd->state = HC_STATE_RUNNING;
+	dev_dbg (&pdev->dev, "%s\n", __FUNCTION__);
 
+	hcd = platform_get_drvdata (pdev);
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	usb_hcd_poll_rh_status (hcd);
 	return 0;
 }
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ea09aaa..0cea978 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -224,6 +224,7 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/kref.h>
 #include <linux/kthread.h>
 #include <linux/limits.h>
 #include <linux/list.h>
@@ -238,7 +239,6 @@
 #include <linux/string.h>
 #include <linux/suspend.h>
 #include <linux/utsname.h>
-#include <linux/wait.h>
 
 #include <linux/usb_ch9.h>
 #include <linux/usb_gadget.h>
@@ -250,7 +250,7 @@
 
 #define DRIVER_DESC		"File-backed Storage Gadget"
 #define DRIVER_NAME		"g_file_storage"
-#define DRIVER_VERSION		"20 October 2004"
+#define DRIVER_VERSION		"28 November 2005"
 
 static const char longname[] = DRIVER_DESC;
 static const char shortname[] = DRIVER_NAME;
@@ -335,8 +335,8 @@
 #define MAX_LUNS	8
 
 	/* Arggh!  There should be a module_param_array_named macro! */
-static char		*file[MAX_LUNS] = {NULL, };
-static int		ro[MAX_LUNS] = {0, };
+static char		*file[MAX_LUNS];
+static int		ro[MAX_LUNS];
 
 static struct {
 	int		num_filenames;
@@ -587,7 +587,7 @@
 struct fsg_buffhd {
 	void				*buf;
 	dma_addr_t			dma;
-	volatile enum fsg_buffer_state	state;
+	enum fsg_buffer_state		state;
 	struct fsg_buffhd		*next;
 
 	/* The NetChip 2280 is faster, and handles some protocol faults
@@ -596,9 +596,9 @@
 	unsigned int			bulk_out_intended_length;
 
 	struct usb_request		*inreq;
-	volatile int			inreq_busy;
+	int				inreq_busy;
 	struct usb_request		*outreq;
-	volatile int			outreq_busy;
+	int				outreq_busy;
 };
 
 enum fsg_state {
@@ -631,13 +631,16 @@
 	/* filesem protects: backing files in use */
 	struct rw_semaphore	filesem;
 
+	/* reference counting: wait until all LUNs are released */
+	struct kref		ref;
+
 	struct usb_ep		*ep0;		// Handy copy of gadget->ep0
 	struct usb_request	*ep0req;	// For control responses
-	volatile unsigned int	ep0_req_tag;
+	unsigned int		ep0_req_tag;
 	const char		*ep0req_name;
 
 	struct usb_request	*intreq;	// For interrupt responses
-	volatile int		intreq_busy;
+	int			intreq_busy;
 	struct fsg_buffhd	*intr_buffhd;
 
  	unsigned int		bulk_out_maxpacket;
@@ -667,7 +670,6 @@
 	struct fsg_buffhd	*next_buffhd_to_drain;
 	struct fsg_buffhd	buffhds[NUM_BUFFERS];
 
-	wait_queue_head_t	thread_wqh;
 	int			thread_wakeup_needed;
 	struct completion	thread_notifier;
 	struct task_struct	*thread_task;
@@ -694,7 +696,6 @@
 	unsigned int		nluns;
 	struct lun		*luns;
 	struct lun		*curlun;
-	struct completion	lun_released;
 };
 
 typedef void (*fsg_routine_t)(struct fsg_dev *);
@@ -1073,11 +1074,13 @@
 
 /* These routines may be called in process context or in_irq */
 
+/* Caller must hold fsg->lock */
 static void wakeup_thread(struct fsg_dev *fsg)
 {
 	/* Tell the main thread that something has happened */
 	fsg->thread_wakeup_needed = 1;
-	wake_up_all(&fsg->thread_wqh);
+	if (fsg->thread_task)
+		wake_up_process(fsg->thread_task);
 }
 
 
@@ -1164,11 +1167,12 @@
 		usb_ep_fifo_flush(ep);
 
 	/* Hold the lock while we update the request and buffer states */
+	smp_wmb();
 	spin_lock(&fsg->lock);
 	bh->inreq_busy = 0;
 	bh->state = BUF_STATE_EMPTY;
-	spin_unlock(&fsg->lock);
 	wakeup_thread(fsg);
+	spin_unlock(&fsg->lock);
 }
 
 static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
@@ -1185,11 +1189,12 @@
 		usb_ep_fifo_flush(ep);
 
 	/* Hold the lock while we update the request and buffer states */
+	smp_wmb();
 	spin_lock(&fsg->lock);
 	bh->outreq_busy = 0;
 	bh->state = BUF_STATE_FULL;
-	spin_unlock(&fsg->lock);
 	wakeup_thread(fsg);
+	spin_unlock(&fsg->lock);
 }
 
 
@@ -1206,11 +1211,12 @@
 		usb_ep_fifo_flush(ep);
 
 	/* Hold the lock while we update the request and buffer states */
+	smp_wmb();
 	spin_lock(&fsg->lock);
 	fsg->intreq_busy = 0;
 	bh->state = BUF_STATE_EMPTY;
-	spin_unlock(&fsg->lock);
 	wakeup_thread(fsg);
+	spin_unlock(&fsg->lock);
 }
 
 #else
@@ -1261,8 +1267,8 @@
 	fsg->cbbuf_cmnd_size = req->actual;
 	memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size);
 
-	spin_unlock(&fsg->lock);
 	wakeup_thread(fsg);
+	spin_unlock(&fsg->lock);
 }
 
 #else
@@ -1514,8 +1520,8 @@
 
 /* Use this for bulk or interrupt transfers, not ep0 */
 static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
-		struct usb_request *req, volatile int *pbusy,
-		volatile enum fsg_buffer_state *state)
+		struct usb_request *req, int *pbusy,
+		enum fsg_buffer_state *state)
 {
 	int	rc;
 
@@ -1523,8 +1529,11 @@
 		dump_msg(fsg, "bulk-in", req->buf, req->length);
 	else if (ep == fsg->intr_in)
 		dump_msg(fsg, "intr-in", req->buf, req->length);
+
+	spin_lock_irq(&fsg->lock);
 	*pbusy = 1;
 	*state = BUF_STATE_BUSY;
+	spin_unlock_irq(&fsg->lock);
 	rc = usb_ep_queue(ep, req, GFP_KERNEL);
 	if (rc != 0) {
 		*pbusy = 0;
@@ -1544,14 +1553,23 @@
 
 static int sleep_thread(struct fsg_dev *fsg)
 {
-	int	rc;
+	int	rc = 0;
 
 	/* Wait until a signal arrives or we are woken up */
-	rc = wait_event_interruptible(fsg->thread_wqh,
-			fsg->thread_wakeup_needed);
+	for (;;) {
+		try_to_freeze();
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (signal_pending(current)) {
+			rc = -EINTR;
+			break;
+		}
+		if (fsg->thread_wakeup_needed)
+			break;
+		schedule();
+	}
+	__set_current_state(TASK_RUNNING);
 	fsg->thread_wakeup_needed = 0;
-	try_to_freeze();
-	return (rc ? -EINTR : 0);
+	return rc;
 }
 
 
@@ -1788,6 +1806,7 @@
 		if (bh->state == BUF_STATE_EMPTY && !get_some_more)
 			break;			// We stopped early
 		if (bh->state == BUF_STATE_FULL) {
+			smp_rmb();
 			fsg->next_buffhd_to_drain = bh->next;
 			bh->state = BUF_STATE_EMPTY;
 
@@ -2356,6 +2375,7 @@
 
 		/* Throw away the data in a filled buffer */
 		if (bh->state == BUF_STATE_FULL) {
+			smp_rmb();
 			bh->state = BUF_STATE_EMPTY;
 			fsg->next_buffhd_to_drain = bh->next;
 
@@ -3021,6 +3041,7 @@
 			if ((rc = sleep_thread(fsg)) != 0)
 				return rc;
 			}
+		smp_rmb();
 		rc = received_cbw(fsg, bh);
 		bh->state = BUF_STATE_EMPTY;
 
@@ -3642,11 +3663,19 @@
 
 /*-------------------------------------------------------------------------*/
 
+static void fsg_release(struct kref *ref)
+{
+	struct fsg_dev	*fsg = container_of(ref, struct fsg_dev, ref);
+
+	kfree(fsg->luns);
+	kfree(fsg);
+}
+
 static void lun_release(struct device *dev)
 {
 	struct fsg_dev	*fsg = (struct fsg_dev *) dev_get_drvdata(dev);
 
-	complete(&fsg->lun_released);
+	kref_put(&fsg->ref, fsg_release);
 }
 
 static void fsg_unbind(struct usb_gadget *gadget)
@@ -3660,14 +3689,12 @@
 	clear_bit(REGISTERED, &fsg->atomic_bitflags);
 
 	/* Unregister the sysfs attribute files and the LUNs */
-	init_completion(&fsg->lun_released);
 	for (i = 0; i < fsg->nluns; ++i) {
 		curlun = &fsg->luns[i];
 		if (curlun->registered) {
 			device_remove_file(&curlun->dev, &dev_attr_ro);
 			device_remove_file(&curlun->dev, &dev_attr_file);
 			device_unregister(&curlun->dev);
-			wait_for_completion(&fsg->lun_released);
 			curlun->registered = 0;
 		}
 	}
@@ -3846,6 +3873,7 @@
 			curlun->dev.release = lun_release;
 			device_create_file(&curlun->dev, &dev_attr_ro);
 			device_create_file(&curlun->dev, &dev_attr_file);
+			kref_get(&fsg->ref);
 		}
 
 		if (file[i] && *file[i]) {
@@ -4061,7 +4089,7 @@
 		return -ENOMEM;
 	spin_lock_init(&fsg->lock);
 	init_rwsem(&fsg->filesem);
-	init_waitqueue_head(&fsg->thread_wqh);
+	kref_init(&fsg->ref);
 	init_completion(&fsg->thread_notifier);
 
 	the_fsg = fsg;
@@ -4069,13 +4097,6 @@
 }
 
 
-static void fsg_free(struct fsg_dev *fsg)
-{
-	kfree(fsg->luns);
-	kfree(fsg);
-}
-
-
 static int __init fsg_init(void)
 {
 	int		rc;
@@ -4085,7 +4106,7 @@
 		return rc;
 	fsg = the_fsg;
 	if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0)
-		fsg_free(fsg);
+		kref_put(&fsg->ref, fsg_release);
 	return rc;
 }
 module_init(fsg_init);
@@ -4103,6 +4124,6 @@
 	wait_for_completion(&fsg->thread_notifier);
 
 	close_all_backing_files(fsg);
-	fsg_free(fsg);
+	kref_put(&fsg->ref, fsg_release);
 }
 module_exit(fsg_cleanup);
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b35ac6d..65e084a 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -890,10 +890,12 @@
 	/* wait for write buffer to drain, or */
 	/* at most GS_CLOSE_TIMEOUT seconds */
 	if (gs_buf_data_avail(port->port_write_buf) > 0) {
+		spin_unlock_irqrestore(&port->port_lock, flags);
 		wait_cond_interruptible_timeout(port->port_write_wait,
 		port->port_dev == NULL
 		|| gs_buf_data_avail(port->port_write_buf) == 0,
 		&port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ);
+		spin_lock_irqsave(&port->port_lock, flags);
 	}
 
 	/* free disconnected port on final close */
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 58321d3..e3020f4b 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -2,6 +2,10 @@
 # Makefile for USB Host Controller Drivers
 #
 
+ifeq ($(CONFIG_USB_DEBUG),y)
+	EXTRA_CFLAGS		+= -DDEBUG
+endif
+
 obj-$(CONFIG_PCI)		+= pci-quirks.o
 
 obj-$(CONFIG_USB_EHCI_HCD)	+= ehci-hcd.o
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 29f52a4..9dd3d14 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -17,13 +17,6 @@
  */
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-	#define DEBUG
-#else
-	#undef DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/dmapool.h>
@@ -624,7 +617,7 @@
 	}
 
 	/* remote wakeup [4.3.1] */
-	if ((status & STS_PCD) && hcd->remote_wakeup) {
+	if (status & STS_PCD) {
 		unsigned	i = HCS_N_PORTS (ehci->hcs_params);
 
 		/* resume root hub? */
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 82caf33..69b0b9b 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -59,7 +59,7 @@
 
 		if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
 			t2 |= PORT_SUSPEND;
-		if (hcd->remote_wakeup)
+		if (device_may_wakeup(&hcd->self.root_hub->dev))
 			t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
 		else
 			t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
@@ -517,7 +517,7 @@
 			if ((temp & PORT_PE) == 0
 					|| (temp & PORT_RESET) != 0)
 				goto error;
-			if (hcd->remote_wakeup)
+			if (device_may_wakeup(&hcd->self.root_hub->dev))
 				temp |= PORT_WAKE_BITS;
 			writel (temp | PORT_SUSPEND,
 				&ehci->regs->port_status [wIndex]);
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 441c260..08ca0f8 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -121,8 +121,8 @@
 	return 0;
 }
 
-/* called by khubd or root hub (re)init threads; leaves HC in halt state */
-static int ehci_pci_reset(struct usb_hcd *hcd)
+/* called during probe() after chip reset completes */
+static int ehci_pci_setup(struct usb_hcd *hcd)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
 	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
@@ -141,6 +141,11 @@
 	if (retval)
 		return retval;
 
+	/* data structure init */
+	retval = ehci_init(hcd);
+	if (retval)
+		return retval;
+
 	/* NOTE:  only the parts below this line are PCI-specific */
 
 	switch (pdev->vendor) {
@@ -154,7 +159,8 @@
 		/* AMD8111 EHCI doesn't work, according to AMD errata */
 		if (pdev->device == 0x7463) {
 			ehci_info(ehci, "ignoring AMD8111 (errata)\n");
-			return -EIO;
+			retval = -EIO;
+			goto done;
 		}
 		break;
 	case PCI_VENDOR_ID_NVIDIA:
@@ -204,12 +210,20 @@
 	/* Serial Bus Release Number is at PCI 0x60 offset */
 	pci_read_config_byte(pdev, 0x60, &ehci->sbrn);
 
-	/* REVISIT:  per-port wake capability (PCI 0x62) currently unused */
+	/* Workaround current PCI init glitch:  wakeup bits aren't
+	 * being set from PCI PM capability.
+	 */
+	if (!device_can_wakeup(&pdev->dev)) {
+		u16	port_wake;
+
+		pci_read_config_word(pdev, 0x62, &port_wake);
+		if (port_wake & 0x0001)
+			device_init_wakeup(&pdev->dev, 1);
+	}
 
 	retval = ehci_pci_reinit(ehci, pdev);
-
-	/* finish init */
-	return ehci_init(hcd);
+done:
+	return retval;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -228,21 +242,42 @@
 static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
+	unsigned long		flags;
+	int			rc = 0;
 
 	if (time_before(jiffies, ehci->next_statechange))
 		msleep(10);
 
+	/* Root hub was already suspended. Disable irq emission and
+	 * mark HW unaccessible, bail out if RH has been resumed. Use
+	 * the spinlock to properly synchronize with possible pending
+	 * RH suspend or resume activity.
+	 *
+	 * This is still racy as hcd->state is manipulated outside of
+	 * any locks =P But that will be a different fix.
+	 */
+	spin_lock_irqsave (&ehci->lock, flags);
+	if (hcd->state != HC_STATE_SUSPENDED) {
+		rc = -EINVAL;
+		goto bail;
+	}
+	writel (0, &ehci->regs->intr_enable);
+	(void)readl(&ehci->regs->intr_enable);
+
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ bail:
+	spin_unlock_irqrestore (&ehci->lock, flags);
+
 	// could save FLADJ in case of Vaux power loss
 	// ... we'd only use it to handle clock skew
 
-	return 0;
+	return rc;
 }
 
 static int ehci_pci_resume(struct usb_hcd *hcd)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
 	unsigned		port;
-	struct usb_device	*root = hcd->self.root_hub;
 	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
 	int			retval = -EINVAL;
 
@@ -251,6 +286,9 @@
 	if (time_before(jiffies, ehci->next_statechange))
 		msleep(100);
 
+	/* Mark hardware accessible again as we are out of D3 state by now */
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
 	/* If CF is clear, we lost PCI Vaux power and need to restart.  */
 	if (readl(&ehci->regs->configured_flag) != FLAG_CF)
 		goto restart;
@@ -273,13 +311,7 @@
 
 restart:
 	ehci_dbg(ehci, "lost power, restarting\n");
-	for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) {
-		port--;
-		if (!root->children [port])
-			continue;
-		usb_set_device_state(root->children[port],
-					USB_STATE_NOTATTACHED);
-	}
+	usb_root_hub_lost_power(hcd->self.root_hub);
 
 	/* Else reset, to cope with power loss or flush-to-storage
 	 * style "resume" having let BIOS kick in during reboot.
@@ -319,7 +351,7 @@
 	/*
 	 * basic lifecycle operations
 	 */
-	.reset =		ehci_pci_reset,
+	.reset =		ehci_pci_setup,
 	.start =		ehci_run,
 #ifdef	CONFIG_PM
 	.suspend =		ehci_pci_suspend,
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 5bb872c..9b13bf2 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -514,18 +514,18 @@
 		qtd->urb = urb;
 		qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
 		list_add_tail (&qtd->qtd_list, head);
+
+		/* for zero length DATA stages, STATUS is always IN */
+		if (len == 0)
+			token |= (1 /* "in" */ << 8);
 	} 
 
 	/*
 	 * data transfer stage:  buffer setup
 	 */
-	if (likely (len > 0))
-		buf = urb->transfer_dma;
-	else
-		buf = 0;
+	buf = urb->transfer_dma;
 
-	/* for zero length DATA stages, STATUS is always IN */
-	if (!buf || is_input)
+	if (is_input)
 		token |= (1 /* "in" */ << 8);
 	/* else it's already initted to "out" pid (0 << 8) */
 
@@ -572,7 +572,7 @@
 	 * control requests may need a terminating data "status" ack;
 	 * bulk ones may need a terminating short packet (zero length).
 	 */
-	if (likely (buf != 0)) {
+	if (likely (urb->transfer_buffer_length != 0)) {
 		int	one_more = 0;
 
 		if (usb_pipecontrol (urb->pipe)) {
@@ -912,6 +912,7 @@
 	int			epnum;
 	unsigned long		flags;
 	struct ehci_qh		*qh = NULL;
+	int			rc = 0;
 
 	qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list);
 	epnum = ep->desc.bEndpointAddress;
@@ -926,21 +927,28 @@
 #endif
 
 	spin_lock_irqsave (&ehci->lock, flags);
+	if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
+			       &ehci_to_hcd(ehci)->flags))) {
+		rc = -ESHUTDOWN;
+		goto done;
+	}
+
 	qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv);
+	if (unlikely(qh == NULL)) {
+		rc = -ENOMEM;
+		goto done;
+	}
 
 	/* Control/bulk operations through TTs don't need scheduling,
 	 * the HC and TT handle it when the TT has a buffer ready.
 	 */
-	if (likely (qh != NULL)) {
-		if (likely (qh->qh_state == QH_STATE_IDLE))
-			qh_link_async (ehci, qh_get (qh));
-	}
+	if (likely (qh->qh_state == QH_STATE_IDLE))
+		qh_link_async (ehci, qh_get (qh));
+ done:
 	spin_unlock_irqrestore (&ehci->lock, flags);
-	if (unlikely (qh == NULL)) {
+	if (unlikely (qh == NULL))
 		qtd_list_free (ehci, urb, qtd_list);
-		return -ENOMEM;
-	}
-	return 0;
+	return rc;
 }
 
 /*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index f0c8aa1..57e7737 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -602,6 +602,12 @@
 
 	spin_lock_irqsave (&ehci->lock, flags);
 
+	if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
+			       &ehci_to_hcd(ehci)->flags))) {
+		status = -ESHUTDOWN;
+		goto done;
+	}
+
 	/* get qh and force any scheduling errors */
 	INIT_LIST_HEAD (&empty);
 	qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv);
@@ -1456,7 +1462,11 @@
 
 	/* schedule ... need to lock */
 	spin_lock_irqsave (&ehci->lock, flags);
-	status = iso_stream_schedule (ehci, urb, stream);
+	if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
+			       &ehci_to_hcd(ehci)->flags)))
+		status = -ESHUTDOWN;
+	else
+		status = iso_stream_schedule (ehci, urb, stream);
  	if (likely (status == 0))
 		itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
 	spin_unlock_irqrestore (&ehci->lock, flags);
@@ -1815,7 +1825,11 @@
 
 	/* schedule ... need to lock */
 	spin_lock_irqsave (&ehci->lock, flags);
-	status = iso_stream_schedule (ehci, urb, stream);
+	if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
+			       &ehci_to_hcd(ehci)->flags)))
+		status = -ESHUTDOWN;
+	else
+		status = iso_stream_schedule (ehci, urb, stream);
  	if (status == 0)
 		sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
 	spin_unlock_irqrestore (&ehci->lock, flags);
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c
index 0eaabeb..641268d 100644
--- a/drivers/usb/host/hc_crisv10.c
+++ b/drivers/usb/host/hc_crisv10.c
@@ -4397,7 +4397,7 @@
         device_initialize(&fake_device);
         kobject_set_name(&fake_device.kobj, "etrax_usb");
         kobject_add(&fake_device.kobj);
-        kobject_hotplug(&fake_device.kobj, KOBJ_ADD);
+	kobject_uevent(&fake_device.kobj, KOBJ_ADD);
         hc->bus->controller = &fake_device;
 	usb_register_bus(hc->bus);
 
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 82f6498..584b8dc 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -55,19 +55,13 @@
 /* enqueuing/finishing log of urbs */
 //#define URB_TRACE
 
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
 #include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/list.h>
-#include <linux/interrupt.h>
 #include <linux/usb.h>
 #include <linux/usb_isp116x.h>
 #include <linux/platform_device.h>
@@ -77,14 +71,10 @@
 #include <asm/system.h>
 #include <asm/byteorder.h>
 
-#ifndef DEBUG
-#	define	STUB_DEBUG_FILE
-#endif
-
 #include "../core/hcd.h"
 #include "isp116x.h"
 
-#define DRIVER_VERSION	"05 Aug 2005"
+#define DRIVER_VERSION	"03 Nov 2005"
 #define DRIVER_DESC	"ISP116x USB Host Controller Driver"
 
 MODULE_DESCRIPTION(DRIVER_DESC);
@@ -164,13 +154,11 @@
 	struct ptd *ptd;
 	int buflen = isp116x->atl_last_dir == PTD_DIR_IN
 	    ? isp116x->atl_bufshrt : isp116x->atl_buflen;
-	int ptd_count = 0;
 
 	isp116x_write_reg16(isp116x, HCuPINT, HCuPINT_AIIEOT);
 	isp116x_write_reg16(isp116x, HCXFERCTR, buflen);
 	isp116x_write_addr(isp116x, HCATLPORT | ISP116x_WRITE_OFFSET);
 	for (ep = isp116x->atl_active; ep; ep = ep->active) {
-		++ptd_count;
 		ptd = &ep->ptd;
 		dump_ptd(ptd);
 		dump_ptd_out_data(ptd, ep->data);
@@ -305,9 +293,8 @@
 		udev = urb->dev;
 		ptd = &ep->ptd;
 		cc = PTD_GET_CC(ptd);
-
-		spin_lock(&urb->lock);
 		short_not_ok = 1;
+		spin_lock(&urb->lock);
 
 		/* Data underrun is special. For allowed underrun
 		   we clear the error and continue as normal. For
@@ -420,7 +407,7 @@
 			ep->nextpid = 0;
 			break;
 		default:
-			BUG_ON(1);
+			BUG();
 		}
 		spin_unlock(&urb->lock);
 	}
@@ -628,8 +615,12 @@
 		u32 intstat = isp116x_read_reg32(isp116x, HCINTSTAT);
 		isp116x_write_reg32(isp116x, HCINTSTAT, intstat);
 		if (intstat & HCINT_UE) {
-			ERR("Unrecoverable error\n");
-			/* What should we do here? Reset?  */
+			ERR("Unrecoverable error, HC is dead!\n");
+			/* IRQ's are off, we do no DMA,
+			   perfectly ready to die ... */
+			hcd->state = HC_STATE_HALT;
+			ret = IRQ_HANDLED;
+			goto done;
 		}
 		if (intstat & HCINT_RHSC)
 			/* When root hub or any of its ports is going
@@ -640,7 +631,6 @@
 		if (intstat & HCINT_RD) {
 			DBG("---- remote wakeup\n");
 			usb_hcd_resume_root_hub(hcd);
-			ret = IRQ_HANDLED;
 		}
 		irqstat &= ~HCuPINT_OPR;
 		ret = IRQ_HANDLED;
@@ -651,6 +641,7 @@
 	}
 
 	isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb);
+      done:
 	spin_unlock(&isp116x->lock);
 	return ret;
 }
@@ -724,6 +715,7 @@
 
 	spin_lock_irqsave(&isp116x->lock, flags);
 	if (!HC_IS_RUNNING(hcd->state)) {
+		kfree(ep);
 		ret = -ENODEV;
 		goto fail;
 	}
@@ -888,7 +880,7 @@
 				     struct usb_host_endpoint *hep)
 {
 	int i;
-	struct isp116x_ep *ep = hep->hcpriv;;
+	struct isp116x_ep *ep = hep->hcpriv;
 
 	if (!ep)
 		return;
@@ -916,8 +908,6 @@
 	return (int)fmnum;
 }
 
-/*----------------------------------------------------------------*/
-
 /*
   Adapted from ohci-hub.c. Currently we don't support autosuspend.
 */
@@ -968,11 +958,10 @@
 	desc->bHubContrCurrent = 0;
 	desc->bNbrPorts = (u8) (reg & 0x3);
 	/* Power switching, device type, overcurrent. */
-	desc->wHubCharacteristics =
-	    (__force __u16) cpu_to_le16((u16) ((reg >> 8) & 0x1f));
+	desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f));
 	desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff);
 	/* two bitmaps:  ports removable, and legacy PortPwrCtrlMask */
-	desc->bitmap[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1;
+	desc->bitmap[0] = 0;
 	desc->bitmap[1] = ~0;
 }
 
@@ -1159,135 +1148,9 @@
 	return ret;
 }
 
-#ifdef	CONFIG_PM
-
-static int isp116x_bus_suspend(struct usb_hcd *hcd)
-{
-	struct isp116x *isp116x = hcd_to_isp116x(hcd);
-	unsigned long flags;
-	u32 val;
-	int ret = 0;
-
-	spin_lock_irqsave(&isp116x->lock, flags);
-
-	val = isp116x_read_reg32(isp116x, HCCONTROL);
-	switch (val & HCCONTROL_HCFS) {
-	case HCCONTROL_USB_OPER:
-		hcd->state = HC_STATE_QUIESCING;
-		val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
-		val |= HCCONTROL_USB_SUSPEND;
-		if (hcd->remote_wakeup)
-			val |= HCCONTROL_RWE;
-		/* Wait for usb transfers to finish */
-		mdelay(2);
-		isp116x_write_reg32(isp116x, HCCONTROL, val);
-		hcd->state = HC_STATE_SUSPENDED;
-		/* Wait for devices to suspend */
-		mdelay(5);
-	case HCCONTROL_USB_SUSPEND:
-		break;
-	case HCCONTROL_USB_RESUME:
-		isp116x_write_reg32(isp116x, HCCONTROL,
-				    (val & ~HCCONTROL_HCFS) |
-				    HCCONTROL_USB_RESET);
-	case HCCONTROL_USB_RESET:
-		ret = -EBUSY;
-		break;
-	default:
-		ret = -EINVAL;
-	}
-
-	spin_unlock_irqrestore(&isp116x->lock, flags);
-	return ret;
-}
-
-static int isp116x_bus_resume(struct usb_hcd *hcd)
-{
-	struct isp116x *isp116x = hcd_to_isp116x(hcd);
-	u32 val;
-	int ret = -EINPROGRESS;
-
-	msleep(5);
-	spin_lock_irq(&isp116x->lock);
-
-	val = isp116x_read_reg32(isp116x, HCCONTROL);
-	switch (val & HCCONTROL_HCFS) {
-	case HCCONTROL_USB_SUSPEND:
-		val &= ~HCCONTROL_HCFS;
-		val |= HCCONTROL_USB_RESUME;
-		isp116x_write_reg32(isp116x, HCCONTROL, val);
-	case HCCONTROL_USB_RESUME:
-		break;
-	case HCCONTROL_USB_OPER:
-		/* Without setting power_state here the
-		   SUSPENDED state won't be removed from
-		   sysfs/usbN/power.state as a response to remote
-		   wakeup. Maybe in the future. */
-		hcd->self.root_hub->dev.power.power_state = PMSG_ON;
-		ret = 0;
-		break;
-	default:
-		ret = -EBUSY;
-	}
-
-	if (ret != -EINPROGRESS) {
-		spin_unlock_irq(&isp116x->lock);
-		return ret;
-	}
-
-	val = isp116x->rhdesca & RH_A_NDP;
-	while (val--) {
-		u32 stat =
-		    isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1);
-		/* force global, not selective, resume */
-		if (!(stat & RH_PS_PSS))
-			continue;
-		DBG("%s: Resuming port %d\n", __func__, val);
-		isp116x_write_reg32(isp116x, RH_PS_POCI, val
-				    ? HCRHPORT2 : HCRHPORT1);
-	}
-	spin_unlock_irq(&isp116x->lock);
-
-	hcd->state = HC_STATE_RESUMING;
-	mdelay(20);
-
-	/* Go operational */
-	spin_lock_irq(&isp116x->lock);
-	val = isp116x_read_reg32(isp116x, HCCONTROL);
-	isp116x_write_reg32(isp116x, HCCONTROL,
-			    (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
-	spin_unlock_irq(&isp116x->lock);
-	/* see analogous comment above */
-	hcd->self.root_hub->dev.power.power_state = PMSG_ON;
-	hcd->state = HC_STATE_RUNNING;
-
-	return 0;
-}
-
-
-#else
-
-#define	isp116x_bus_suspend	NULL
-#define	isp116x_bus_resume	NULL
-
-#endif
-
 /*-----------------------------------------------------------------*/
 
-#ifdef STUB_DEBUG_FILE
-
-static inline void create_debug_file(struct isp116x *isp116x)
-{
-}
-
-static inline void remove_debug_file(struct isp116x *isp116x)
-{
-}
-
-#else
-
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
+#ifdef CONFIG_DEBUG_FS
 
 static void dump_irq(struct seq_file *s, char *label, u16 mask)
 {
@@ -1311,13 +1174,9 @@
 		   mask & HCINT_SF ? " sof" : "", mask & HCINT_SO ? " so" : "");
 }
 
-static int proc_isp116x_show(struct seq_file *s, void *unused)
+static int isp116x_show_dbg(struct seq_file *s, void *unused)
 {
 	struct isp116x *isp116x = s->private;
-	struct isp116x_ep *ep;
-	struct urb *urb;
-	unsigned i;
-	char *str;
 
 	seq_printf(s, "%s\n%s version %s\n",
 		   isp116x_to_hcd(isp116x)->product_desc, hcd_name,
@@ -1333,105 +1192,50 @@
 	}
 
 	spin_lock_irq(&isp116x->lock);
-
 	dump_irq(s, "hc_irq_enable", isp116x_read_reg16(isp116x, HCuPINTENB));
 	dump_irq(s, "hc_irq_status", isp116x_read_reg16(isp116x, HCuPINT));
 	dump_int(s, "hc_int_enable", isp116x_read_reg32(isp116x, HCINTENB));
 	dump_int(s, "hc_int_status", isp116x_read_reg32(isp116x, HCINTSTAT));
-
-	list_for_each_entry(ep, &isp116x->async, schedule) {
-
-		switch (ep->nextpid) {
-		case USB_PID_IN:
-			str = "in";
-			break;
-		case USB_PID_OUT:
-			str = "out";
-			break;
-		case USB_PID_SETUP:
-			str = "setup";
-			break;
-		case USB_PID_ACK:
-			str = "status";
-			break;
-		default:
-			str = "?";
-			break;
-		};
-		seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep,
-			   ep->epnum, str, ep->maxpacket);
-		list_for_each_entry(urb, &ep->hep->urb_list, urb_list) {
-			seq_printf(s, "  urb%p, %d/%d\n", urb,
-				   urb->actual_length,
-				   urb->transfer_buffer_length);
-		}
-	}
-	if (!list_empty(&isp116x->async))
-		seq_printf(s, "\n");
-
-	seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE);
-
-	for (i = 0; i < PERIODIC_SIZE; i++) {
-		ep = isp116x->periodic[i];
-		if (!ep)
-			continue;
-		seq_printf(s, "%2d [%3d]:\n", i, isp116x->load[i]);
-
-		/* DUMB: prints shared entries multiple times */
-		do {
-			seq_printf(s, "   %d/%p (%sdev%d ep%d%s max %d)\n",
-				   ep->period, ep,
-				   (ep->udev->speed ==
-				    USB_SPEED_FULL) ? "" : "ls ",
-				   ep->udev->devnum, ep->epnum,
-				   (ep->epnum ==
-				    0) ? "" : ((ep->nextpid ==
-						USB_PID_IN) ? "in" : "out"),
-				   ep->maxpacket);
-			ep = ep->next;
-		} while (ep);
-	}
+	isp116x_show_regs_seq(isp116x, s);
 	spin_unlock_irq(&isp116x->lock);
 	seq_printf(s, "\n");
 
 	return 0;
 }
 
-static int proc_isp116x_open(struct inode *inode, struct file *file)
+static int isp116x_open_seq(struct inode *inode, struct file *file)
 {
-	return single_open(file, proc_isp116x_show, PDE(inode)->data);
+	return single_open(file, isp116x_show_dbg, inode->u.generic_ip);
 }
 
-static struct file_operations proc_ops = {
-	.open = proc_isp116x_open,
+static struct file_operations isp116x_debug_fops = {
+	.open = isp116x_open_seq,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
 };
 
-/* expect just one isp116x per system */
-static const char proc_filename[] = "driver/isp116x";
-
-static void create_debug_file(struct isp116x *isp116x)
+static int create_debug_file(struct isp116x *isp116x)
 {
-	struct proc_dir_entry *pde;
-
-	pde = create_proc_entry(proc_filename, 0, NULL);
-	if (pde == NULL)
-		return;
-
-	pde->proc_fops = &proc_ops;
-	pde->data = isp116x;
-	isp116x->pde = pde;
+	isp116x->dentry = debugfs_create_file(hcd_name,
+					      S_IRUGO, NULL, isp116x,
+					      &isp116x_debug_fops);
+	if (!isp116x->dentry)
+		return -ENOMEM;
+	return 0;
 }
 
 static void remove_debug_file(struct isp116x *isp116x)
 {
-	if (isp116x->pde)
-		remove_proc_entry(proc_filename, NULL);
+	debugfs_remove(isp116x->dentry);
 }
 
-#endif
+#else
+
+#define	create_debug_file(d)	0
+#define	remove_debug_file(d)	do{}while(0)
+
+#endif				/* CONFIG_DEBUG_FS */
 
 /*-----------------------------------------------------------------*/
 
@@ -1466,7 +1270,7 @@
 	struct isp116x *isp116x = hcd_to_isp116x(hcd);
 	unsigned long t;
 	u16 clkrdy = 0;
-	int ret = 0, timeout = 15 /* ms */ ;
+	int ret, timeout = 15 /* ms */ ;
 
 	ret = isp116x_sw_reset(isp116x);
 	if (ret)
@@ -1482,7 +1286,7 @@
 			break;
 	}
 	if (!clkrdy) {
-		ERR("Clock not ready after 20ms\n");
+		ERR("Clock not ready after %dms\n", timeout);
 		/* After sw_reset the clock won't report to be ready, if
 		   H_WAKEUP pin is high. */
 		ERR("Please make sure that the H_WAKEUP pin is pulled low!\n");
@@ -1572,7 +1376,8 @@
 
 	val = 0;
 	if (board->remote_wakeup_enable) {
-		hcd->can_wakeup = 1;
+		if (!device_can_wakeup(hcd->self.controller))
+			device_init_wakeup(hcd->self.controller, 1);
 		val |= RH_HS_DRWE;
 	}
 	isp116x_write_reg32(isp116x, HCRHSTATUS, val);
@@ -1600,12 +1405,126 @@
 	isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
 	isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
 
-	isp116x_show_regs(isp116x);
+	isp116x_show_regs_log(isp116x);
 	spin_unlock_irqrestore(&isp116x->lock, flags);
 	return 0;
 }
 
-/*-----------------------------------------------------------------*/
+#ifdef	CONFIG_PM
+
+static int isp116x_bus_suspend(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	unsigned long flags;
+	u32 val;
+	int ret = 0;
+
+	spin_lock_irqsave(&isp116x->lock, flags);
+
+	val = isp116x_read_reg32(isp116x, HCCONTROL);
+	switch (val & HCCONTROL_HCFS) {
+	case HCCONTROL_USB_OPER:
+		val &= (~HCCONTROL_HCFS & ~HCCONTROL_RWE);
+		val |= HCCONTROL_USB_SUSPEND;
+		if (device_may_wakeup(&hcd->self.root_hub->dev))
+			val |= HCCONTROL_RWE;
+		/* Wait for usb transfers to finish */
+		mdelay(2);
+		isp116x_write_reg32(isp116x, HCCONTROL, val);
+		/* Wait for devices to suspend */
+		mdelay(5);
+	case HCCONTROL_USB_SUSPEND:
+		break;
+	case HCCONTROL_USB_RESUME:
+		isp116x_write_reg32(isp116x, HCCONTROL,
+				    (val & ~HCCONTROL_HCFS) |
+				    HCCONTROL_USB_RESET);
+	case HCCONTROL_USB_RESET:
+		ret = -EBUSY;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	spin_unlock_irqrestore(&isp116x->lock, flags);
+	return ret;
+}
+
+static int isp116x_bus_resume(struct usb_hcd *hcd)
+{
+	struct isp116x *isp116x = hcd_to_isp116x(hcd);
+	u32 val;
+
+	msleep(5);
+	spin_lock_irq(&isp116x->lock);
+
+	val = isp116x_read_reg32(isp116x, HCCONTROL);
+	switch (val & HCCONTROL_HCFS) {
+	case HCCONTROL_USB_SUSPEND:
+		val &= ~HCCONTROL_HCFS;
+		val |= HCCONTROL_USB_RESUME;
+		isp116x_write_reg32(isp116x, HCCONTROL, val);
+	case HCCONTROL_USB_RESUME:
+		break;
+	case HCCONTROL_USB_OPER:
+		spin_unlock_irq(&isp116x->lock);
+		/* Without setting power_state here the
+		   SUSPENDED state won't be removed from
+		   sysfs/usbN/power.state as a response to remote
+		   wakeup. Maybe in the future. */
+		hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+		return 0;
+	default:
+		/* HCCONTROL_USB_RESET: this may happen, when during
+		   suspension the HC lost power. Reinitialize completely */
+		spin_unlock_irq(&isp116x->lock);
+		DBG("Chip has been reset while suspended. Reinit from scratch.\n");
+		isp116x_reset(hcd);
+		isp116x_start(hcd);
+		isp116x_hub_control(hcd, SetPortFeature,
+				    USB_PORT_FEAT_POWER, 1, NULL, 0);
+		if ((isp116x->rhdesca & RH_A_NDP) == 2)
+			isp116x_hub_control(hcd, SetPortFeature,
+					    USB_PORT_FEAT_POWER, 2, NULL, 0);
+		hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+		return 0;
+	}
+
+	val = isp116x->rhdesca & RH_A_NDP;
+	while (val--) {
+		u32 stat =
+		    isp116x_read_reg32(isp116x, val ? HCRHPORT2 : HCRHPORT1);
+		/* force global, not selective, resume */
+		if (!(stat & RH_PS_PSS))
+			continue;
+		DBG("%s: Resuming port %d\n", __func__, val);
+		isp116x_write_reg32(isp116x, RH_PS_POCI, val
+				    ? HCRHPORT2 : HCRHPORT1);
+	}
+	spin_unlock_irq(&isp116x->lock);
+
+	hcd->state = HC_STATE_RESUMING;
+	msleep(20);
+
+	/* Go operational */
+	spin_lock_irq(&isp116x->lock);
+	val = isp116x_read_reg32(isp116x, HCCONTROL);
+	isp116x_write_reg32(isp116x, HCCONTROL,
+			    (val & ~HCCONTROL_HCFS) | HCCONTROL_USB_OPER);
+	spin_unlock_irq(&isp116x->lock);
+	/* see analogous comment above */
+	hcd->self.root_hub->dev.power.power_state = PMSG_ON;
+	hcd->state = HC_STATE_RUNNING;
+
+	return 0;
+}
+
+#else
+
+#define	isp116x_bus_suspend	NULL
+#define	isp116x_bus_resume	NULL
+
+#endif
 
 static struct hc_driver isp116x_hc_driver = {
 	.description = hcd_name,
@@ -1735,12 +1654,19 @@
 	}
 
 	ret = usb_add_hcd(hcd, irq, SA_INTERRUPT);
-	if (ret != 0)
+	if (ret)
 		goto err6;
 
-	create_debug_file(isp116x);
+	ret = create_debug_file(isp116x);
+	if (ret) {
+		ERR("Couldn't create debugfs entry\n");
+		goto err7;
+	}
+
 	return 0;
 
+      err7:
+	usb_remove_hcd(hcd);
       err6:
 	usb_put_hcd(hcd);
       err5:
@@ -1762,13 +1688,9 @@
 */
 static int isp116x_suspend(struct platform_device *dev, pm_message_t state)
 {
-	int ret = 0;
-
-	VDBG("%s: state %x\n", __func__, state);
-
+	VDBG("%s: state %x\n", __func__, state.event);
 	dev->dev.power.power_state = state;
-
-	return ret;
+	return 0;
 }
 
 /*
@@ -1776,13 +1698,9 @@
 */
 static int isp116x_resume(struct platform_device *dev)
 {
-	int ret = 0;
-
-	VDBG("%s:  state %x\n", __func__, dev->dev.power.power_state);
-
+	VDBG("%s:  state %x\n", __func__, dev->power.power_state.event);
 	dev->dev.power.power_state = PMSG_ON;
-
-	return ret;
+	return 0;
 }
 
 #else
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
index c6fec96..a1b7c38 100644
--- a/drivers/usb/host/isp116x.h
+++ b/drivers/usb/host/isp116x.h
@@ -259,7 +259,7 @@
 
 	struct isp116x_platform_data *board;
 
-	struct proc_dir_entry *pde;
+	struct dentry *dentry;
 	unsigned long stat1, stat2, stat4, stat8, stat16;
 
 	/* HC registers */
@@ -450,7 +450,7 @@
 	isp116x_write_data32(isp116x, (u32) val);
 }
 
-#define isp116x_show_reg(d,r) {					\
+#define isp116x_show_reg_log(d,r,s) {				\
 	if ((r) < 0x20) {			                \
 		DBG("%-12s[%02x]: %08x\n", #r,			\
 			r, isp116x_read_reg32(d, r));		\
@@ -459,35 +459,60 @@
 			r, isp116x_read_reg16(d, r));	    	\
 	}							\
 }
+#define isp116x_show_reg_seq(d,r,s) {				\
+	if ((r) < 0x20) {					\
+		seq_printf(s, "%-12s[%02x]: %08x\n", #r,	\
+			r, isp116x_read_reg32(d, r));		\
+	} else {						\
+		seq_printf(s, "%-12s[%02x]:     %04x\n", #r,	\
+			r, isp116x_read_reg16(d, r));		\
+	}							\
+}
 
-static inline void isp116x_show_regs(struct isp116x *isp116x)
+#define isp116x_show_regs(d,type,s) {			\
+	isp116x_show_reg_##type(d, HCREVISION, s);	\
+	isp116x_show_reg_##type(d, HCCONTROL, s);	\
+	isp116x_show_reg_##type(d, HCCMDSTAT, s);	\
+	isp116x_show_reg_##type(d, HCINTSTAT, s);	\
+	isp116x_show_reg_##type(d, HCINTENB, s);	\
+	isp116x_show_reg_##type(d, HCFMINTVL, s);	\
+	isp116x_show_reg_##type(d, HCFMREM, s);		\
+	isp116x_show_reg_##type(d, HCFMNUM, s);		\
+	isp116x_show_reg_##type(d, HCLSTHRESH, s);	\
+	isp116x_show_reg_##type(d, HCRHDESCA, s);	\
+	isp116x_show_reg_##type(d, HCRHDESCB, s);	\
+	isp116x_show_reg_##type(d, HCRHSTATUS, s);	\
+	isp116x_show_reg_##type(d, HCRHPORT1, s);	\
+	isp116x_show_reg_##type(d, HCRHPORT2, s);	\
+	isp116x_show_reg_##type(d, HCHWCFG, s);		\
+	isp116x_show_reg_##type(d, HCDMACFG, s);	\
+	isp116x_show_reg_##type(d, HCXFERCTR, s);	\
+	isp116x_show_reg_##type(d, HCuPINT, s);		\
+	isp116x_show_reg_##type(d, HCuPINTENB, s);	\
+	isp116x_show_reg_##type(d, HCCHIPID, s);	\
+	isp116x_show_reg_##type(d, HCSCRATCH, s);	\
+	isp116x_show_reg_##type(d, HCITLBUFLEN, s);	\
+	isp116x_show_reg_##type(d, HCATLBUFLEN, s);	\
+	isp116x_show_reg_##type(d, HCBUFSTAT, s);	\
+	isp116x_show_reg_##type(d, HCRDITL0LEN, s);	\
+	isp116x_show_reg_##type(d, HCRDITL1LEN, s);	\
+}
+
+/*
+   Dump registers for debugfs.
+*/
+static inline void isp116x_show_regs_seq(struct isp116x *isp116x,
+					  struct seq_file *s)
 {
-	isp116x_show_reg(isp116x, HCREVISION);
-	isp116x_show_reg(isp116x, HCCONTROL);
-	isp116x_show_reg(isp116x, HCCMDSTAT);
-	isp116x_show_reg(isp116x, HCINTSTAT);
-	isp116x_show_reg(isp116x, HCINTENB);
-	isp116x_show_reg(isp116x, HCFMINTVL);
-	isp116x_show_reg(isp116x, HCFMREM);
-	isp116x_show_reg(isp116x, HCFMNUM);
-	isp116x_show_reg(isp116x, HCLSTHRESH);
-	isp116x_show_reg(isp116x, HCRHDESCA);
-	isp116x_show_reg(isp116x, HCRHDESCB);
-	isp116x_show_reg(isp116x, HCRHSTATUS);
-	isp116x_show_reg(isp116x, HCRHPORT1);
-	isp116x_show_reg(isp116x, HCRHPORT2);
-	isp116x_show_reg(isp116x, HCHWCFG);
-	isp116x_show_reg(isp116x, HCDMACFG);
-	isp116x_show_reg(isp116x, HCXFERCTR);
-	isp116x_show_reg(isp116x, HCuPINT);
-	isp116x_show_reg(isp116x, HCuPINTENB);
-	isp116x_show_reg(isp116x, HCCHIPID);
-	isp116x_show_reg(isp116x, HCSCRATCH);
-	isp116x_show_reg(isp116x, HCITLBUFLEN);
-	isp116x_show_reg(isp116x, HCATLBUFLEN);
-	isp116x_show_reg(isp116x, HCBUFSTAT);
-	isp116x_show_reg(isp116x, HCRDITL0LEN);
-	isp116x_show_reg(isp116x, HCRDITL1LEN);
+	isp116x_show_regs(isp116x, seq, s);
+}
+
+/*
+   Dump registers to syslog.
+*/
+static inline void isp116x_show_regs_log(struct isp116x *isp116x)
+{
+	isp116x_show_regs(isp116x, log, NULL);
 }
 
 #if defined(URB_TRACE)
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index d9cf3b3..77cd6ac 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -19,6 +19,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/signal.h>
 
 #include <asm/mach-au1x00/au1000.h>
 
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5c0c6c8..a4b1240 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -75,13 +75,6 @@
  */
  
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-#	define DEBUG
-#else
-#	undef DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/pci.h>
@@ -115,7 +108,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-// #define OHCI_VERBOSE_DEBUG	/* not always helpful */
+#undef OHCI_VERBOSE_DEBUG	/* not always helpful */
 
 /* For initializing controller (mask in an HCFS mode too) */
 #define	OHCI_CONTROL_INIT 	OHCI_CTRL_CBSR
@@ -253,6 +246,10 @@
 	spin_lock_irqsave (&ohci->lock, flags);
 
 	/* don't submit to a dead HC */
+	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+		retval = -ENODEV;
+		goto fail;
+	}
 	if (!HC_IS_RUNNING(hcd->state)) {
 		retval = -ENODEV;
 		goto fail;
@@ -798,7 +795,6 @@
 	int temp;
 	int i;
 	struct urb_priv *priv;
-	struct usb_device *root = ohci_to_hcd(ohci)->self.root_hub;
 
 	/* mark any devices gone, so they do nothing till khubd disconnects.
 	 * recycle any "live" eds/tds (and urbs) right away.
@@ -807,11 +803,7 @@
 	 */ 
 	spin_lock_irq(&ohci->lock);
 	disable (ohci);
-	for (i = 0; i < root->maxchild; i++) {
-		if (root->children [i])
-			usb_set_device_state (root->children[i],
-				USB_STATE_NOTATTACHED);
-	}
+	usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub);
 	if (!list_empty (&ohci->pending))
 		ohci_dbg(ohci, "abort schedule...\n");
 	list_for_each_entry (priv, &ohci->pending, pending) {
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index e01e77b..4b2226d 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -53,6 +53,11 @@
 
 	spin_lock_irqsave (&ohci->lock, flags);
 
+	if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
+		spin_unlock_irqrestore (&ohci->lock, flags);
+		return -ESHUTDOWN;
+	}
+
 	ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
 	switch (ohci->hc_control & OHCI_CTRL_HCFS) {
 	case OHCI_USB_RESUME:
@@ -140,11 +145,19 @@
 	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
 	u32			temp, enables;
 	int			status = -EINPROGRESS;
+	unsigned long		flags;
 
 	if (time_before (jiffies, ohci->next_statechange))
 		msleep(5);
 
-	spin_lock_irq (&ohci->lock);
+	spin_lock_irqsave (&ohci->lock, flags);
+
+	if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
+		spin_unlock_irqrestore (&ohci->lock, flags);
+		return -ESHUTDOWN;
+	}
+
+
 	ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
 
 	if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
@@ -179,7 +192,7 @@
 		ohci_dbg (ohci, "lost power\n");
 		status = -EBUSY;
 	}
-	spin_unlock_irq (&ohci->lock);
+	spin_unlock_irqrestore (&ohci->lock, flags);
 	if (status == -EBUSY) {
 		(void) ohci_init (ohci);
 		return ohci_restart (ohci);
@@ -297,8 +310,8 @@
 	/* handle autosuspended root:  finish resuming before
 	 * letting khubd or root hub timer see state changes.
 	 */
-	if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER
-			|| !HC_IS_RUNNING(hcd->state)) {
+	if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER
+		     || !HC_IS_RUNNING(hcd->state))) {
 		can_suspend = 0;
 		goto done;
 	}
@@ -359,7 +372,7 @@
 					& ohci->hc_control)
 				== OHCI_USB_OPER
 			&& time_after (jiffies, ohci->next_statechange)
-			&& usb_trylock_device (hcd->self.root_hub)
+			&& usb_trylock_device (hcd->self.root_hub) == 0
 			) {
 		ohci_vdbg (ohci, "autosuspend\n");
 		(void) ohci_bus_suspend (hcd);
@@ -508,6 +521,9 @@
 	u32		temp;
 	int		retval = 0;
 
+	if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)))
+		return -ESHUTDOWN;
+
 	switch (typeReq) {
 	case ClearHubFeature:
 		switch (wValue) {
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
index 3959ccc..0020ed7 100644
--- a/drivers/usb/host/ohci-lh7a404.c
+++ b/drivers/usb/host/ohci-lh7a404.c
@@ -17,6 +17,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/signal.h>
 
 #include <asm/hardware.h>
 
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index c9e29d8..3785b3f 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -17,6 +17,7 @@
 #include <linux/signal.h>	/* SA_INTERRUPT */
 #include <linux/jiffies.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
 #include <asm/io.h>
@@ -27,7 +28,6 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/fpga.h>
 #include <asm/arch/usb.h>
-#include <asm/hardware/clock.h>
 
 
 /* OMAP-1510 OHCI has its own MMU for DMA */
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 5f22e65..1b09dde 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -105,13 +105,36 @@
 
 static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
 {
-	/* root hub was already suspended */
-	return 0;
+	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+	unsigned long	flags;
+	int		rc = 0;
+
+	/* Root hub was already suspended. Disable irq emission and
+	 * mark HW unaccessible, bail out if RH has been resumed. Use
+	 * the spinlock to properly synchronize with possible pending
+	 * RH suspend or resume activity.
+	 *
+	 * This is still racy as hcd->state is manipulated outside of
+	 * any locks =P But that will be a different fix.
+	 */
+	spin_lock_irqsave (&ohci->lock, flags);
+	if (hcd->state != HC_STATE_SUSPENDED) {
+		rc = -EINVAL;
+		goto bail;
+	}
+	ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
+	(void)ohci_readl(ohci, &ohci->regs->intrdisable);
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ bail:
+	spin_unlock_irqrestore (&ohci->lock, flags);
+
+	return rc;
 }
 
 
 static int ohci_pci_resume (struct usb_hcd *hcd)
 {
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	usb_hcd_resume_root_hub(hcd);
 	return 0;
 }
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 2ec6a78..b2a8dfa 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -15,6 +15,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/signal.h>
 
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 9d65ec3..acde886 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -26,18 +26,12 @@
 #include <asm/mach-types.h>
 #include <asm/hardware.h>
 #include <asm/arch/pxa-regs.h>
-
-
-#define PMM_NPS_MODE           1
-#define PMM_GLOBAL_MODE        2
-#define PMM_PERPORT_MODE       3
+#include <asm/arch/ohci.h>
 
 #define PXA_UHC_MAX_PORTNUM    3
 
 #define UHCRHPS(x)              __REG2( 0x4C000050, (x)<<2 )
 
-static int pxa27x_ohci_pmm_state;
-
 /*
   PMM_NPS_MODE -- PMM Non-power switching mode
       Ports are powered continuously.
@@ -50,8 +44,6 @@
  */
 static int pxa27x_ohci_select_pmm( int mode )
 {
-	pxa27x_ohci_pmm_state = mode;
-
 	switch ( mode ) {
 	case PMM_NPS_MODE:
 		UHCRHDA |= RH_A_NPS;
@@ -71,7 +63,6 @@
 			"Invalid mode %d, set to non-power switch mode.\n", 
 			mode );
 
-		pxa27x_ohci_pmm_state = PMM_NPS_MODE;
 		UHCRHDA |= RH_A_NPS;
 	}
 
@@ -82,8 +73,13 @@
 
 /*-------------------------------------------------------------------------*/
 
-static void pxa27x_start_hc(struct platform_device *dev)
+static int pxa27x_start_hc(struct device *dev)
 {
+	int retval = 0;
+	struct pxaohci_platform_data *inf;
+
+	inf = dev->platform_data;
+
 	pxa_set_cken(CKEN10_USBHOST, 1);
 
 	UHCHR |= UHCHR_FHR;
@@ -94,21 +90,11 @@
 	while (UHCHR & UHCHR_FSBIR)
 		cpu_relax();
 
-	/* This could be properly abstracted away through the
-	   device data the day more machines are supported and
-	   their differences can be figured out correctly. */
-	if (machine_is_mainstone()) {
-		/* setup Port1 GPIO pin. */
-		pxa_gpio_mode( 88 | GPIO_ALT_FN_1_IN);	/* USBHPWR1 */
-		pxa_gpio_mode( 89 | GPIO_ALT_FN_2_OUT);	/* USBHPEN1 */
+	if (inf->init)
+		retval = inf->init(dev);
 
-		/* Set the Power Control Polarity Low and Power Sense
-		   Polarity Low to active low. Supply power to USB ports. */
-		UHCHR = (UHCHR | UHCHR_PCPL | UHCHR_PSPL) &
-			~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE);
-
-		pxa27x_ohci_pmm_state = PMM_PERPORT_MODE;
-	}
+	if (retval < 0)
+		return retval;
 
 	UHCHR &= ~UHCHR_SSE;
 
@@ -117,10 +103,19 @@
 	/* Clear any OTG Pin Hold */
 	if (PSSR & PSSR_OTGPH)
 		PSSR |= PSSR_OTGPH;
+
+	return 0;
 }
 
-static void pxa27x_stop_hc(struct platform_device *dev)
+static void pxa27x_stop_hc(struct device *dev)
 {
+	struct pxaohci_platform_data *inf;
+
+	inf = dev->platform_data;
+
+	if (inf->exit)
+		inf->exit(dev);
+
 	UHCHR |= UHCHR_FHR;
 	udelay(11);
 	UHCHR &= ~UHCHR_FHR;
@@ -147,22 +142,27 @@
  * through the hotplug entry's driver_data.
  *
  */
-int usb_hcd_pxa27x_probe (const struct hc_driver *driver,
-			  struct platform_device *dev)
+int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev)
 {
 	int retval;
 	struct usb_hcd *hcd;
+	struct pxaohci_platform_data *inf;
 
-	if (dev->resource[1].flags != IORESOURCE_IRQ) {
+	inf = pdev->dev.platform_data;
+
+	if (!inf)
+		return -ENODEV;
+
+	if (pdev->resource[1].flags != IORESOURCE_IRQ) {
 		pr_debug ("resource[1] is not IORESOURCE_IRQ");
 		return -ENOMEM;
 	}
 
-	hcd = usb_create_hcd (driver, &dev->dev, "pxa27x");
+	hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
 	if (!hcd)
 		return -ENOMEM;
-	hcd->rsrc_start = dev->resource[0].start;
-	hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
+	hcd->rsrc_start = pdev->resource[0].start;
+	hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
 
 	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
 		pr_debug("request_mem_region failed");
@@ -177,18 +177,22 @@
 		goto err2;
 	}
 
-	pxa27x_start_hc(dev);
+	if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) {
+		pr_debug("pxa27x_start_hc failed");
+		goto err3;
+	}
 
 	/* Select Power Management Mode */
-	pxa27x_ohci_select_pmm(pxa27x_ohci_pmm_state);
+	pxa27x_ohci_select_pmm(inf->port_mode);
 
 	ohci_hcd_init(hcd_to_ohci(hcd));
 
-	retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
+	retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
 	if (retval == 0)
 		return retval;
 
-	pxa27x_stop_hc(dev);
+	pxa27x_stop_hc(&pdev->dev);
+ err3:
 	iounmap(hcd->regs);
  err2:
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@@ -211,10 +215,10 @@
  * context, normally "rmmod", "apmd", or something similar.
  *
  */
-void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *dev)
+void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
 {
 	usb_remove_hcd(hcd);
-	pxa27x_stop_hc(dev);
+	pxa27x_stop_hc(&pdev->dev);
 	iounmap(hcd->regs);
 	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
@@ -292,15 +296,12 @@
 
 static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)
 {
-	int ret;
-
 	pr_debug ("In ohci_hcd_pxa27x_drv_probe");
 
 	if (usb_disabled())
 		return -ENODEV;
 
-	ret = usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev);
-	return ret;
+	return usb_hcd_pxa27x_probe(&ohci_pxa27x_hc_driver, pdev);
 }
 
 static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
@@ -308,31 +309,55 @@
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 
 	usb_hcd_pxa27x_remove(hcd, pdev);
+	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
-static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *dev, pm_message_t state)
+#ifdef	CONFIG_PM
+static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_t state)
 {
-//	struct usb_hcd *hcd = platform_get_drvdata(dev);
-	printk("%s: not implemented yet\n", __FUNCTION__);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	pxa27x_stop_hc(&pdev->dev);
+	hcd->state = HC_STATE_SUSPENDED;
+	pdev->dev.power.power_state = PMSG_SUSPEND;
 
 	return 0;
 }
 
-static int ohci_hcd_pxa27x_drv_resume(struct platform_device *dev)
+static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev)
 {
-//	struct usb_hcd *hcd = platform_get_drvdata(dev);
-	printk("%s: not implemented yet\n", __FUNCTION__);
+	struct usb_hcd *hcd = platform_get_drvdata(pdev);
+	struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+	int status;
+
+	if (time_before(jiffies, ohci->next_statechange))
+		msleep(5);
+	ohci->next_statechange = jiffies;
+
+	if ((status = pxa27x_start_hc(&pdev->dev)) < 0)
+		return status;
+
+	pdev->dev.power.power_state = PMSG_ON;
+	usb_hcd_resume_root_hub(hcd);
 
 	return 0;
 }
+#endif
 
 
 static struct platform_driver ohci_hcd_pxa27x_driver = {
 	.probe		= ohci_hcd_pxa27x_drv_probe,
 	.remove		= ohci_hcd_pxa27x_drv_remove,
+#ifdef CONFIG_PM
 	.suspend	= ohci_hcd_pxa27x_drv_suspend, 
 	.resume		= ohci_hcd_pxa27x_drv_resume,
+#endif
 	.driver		= {
 		.name	= "pxa27x-ohci",
 	},
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 35cc940..372527a 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -20,9 +20,9 @@
 */
 
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 
 #include <asm/hardware.h>
-#include <asm/hardware/clock.h>
 #include <asm/arch/usb-control.h>
 
 #define valid_port(idx) ((idx) == 1 || (idx) == 2)
@@ -363,7 +363,6 @@
 		goto err1;
 	}
 
-	clk_use(clk);
 	s3c2410_start_hc(dev, hcd);
 
 	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
@@ -384,7 +383,6 @@
  err2:
 	s3c2410_stop_hc(dev);
 	iounmap(hcd->regs);
-	clk_unuse(clk);
 	clk_put(clk);
 
  err1:
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index e46528c..3ef2c0c 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -9,12 +9,6 @@
  */
 
 #include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG
-#else
-#undef DEBUG
-#endif
-
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index a7722a6..517360b 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -32,13 +32,6 @@
 #undef	PACKET_TRACE
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_DEBUG
-#	define DEBUG
-#else
-#	undef DEBUG
-#endif
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -1581,7 +1574,9 @@
 	hcd->state = HC_STATE_RUNNING;
 
 	if (sl811->board) {
-		hcd->can_wakeup = sl811->board->can_wakeup;
+		if (!device_can_wakeup(hcd->self.controller))
+			device_init_wakeup(hcd->self.controller,
+				sl811->board->can_wakeup);
 		hcd->power_budget = sl811->board->power * 2;
 	}
 
@@ -1805,9 +1800,10 @@
 	 * let's assume it'd only be powered to enable remote wakeup.
 	 */
 	if (dev->dev.power.power_state.event == PM_EVENT_SUSPEND
-			|| !hcd->can_wakeup) {
+			|| !device_can_wakeup(&hcd->self.root_hub->dev)) {
 		sl811->port1 = 0;
 		port_power(sl811, 1);
+		usb_root_hub_lost_power(hcd->self.root_hub);
 		return 0;
 	}
 
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index e73faf8..466384d 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -38,7 +38,7 @@
 /* MACROS                                                             */
 /*====================================================================*/
 
-#if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG)
+#if defined(DEBUG) || defined(PCMCIA_DEBUG)
 
 static int pc_debug = 0;
 module_param(pc_debug, int, 0644);
@@ -66,13 +66,13 @@
 
 static const char driver_name[DEV_NAME_LEN]  = "sl811_cs";
 
-static dev_link_t *dev_list = NULL;
-
 typedef struct local_info_t {
 	dev_link_t		link;
 	dev_node_t		node;
 } local_info_t;
 
+static void sl811_cs_release(dev_link_t * link);
+
 /*====================================================================*/
 
 static void release_platform_dev(struct device * dev)
@@ -129,7 +129,8 @@
 	resources[2].end   = base_addr + 1;
 
 	/* The driver core will probe for us.  We know sl811-hcd has been
-	 * initialized already because of the link order dependency.
+	 * initialized already because of the link order dependency created
+	 * by referencing "sl811h_driver".
 	 */
 	platform_dev.name = sl811h_driver.name;
 	return platform_device_register(&platform_dev);
@@ -137,26 +138,16 @@
 
 /*====================================================================*/
 
-static void sl811_cs_detach(dev_link_t *link)
+static void sl811_cs_detach(struct pcmcia_device *p_dev)
 {
-	dev_link_t **linkp;
+	dev_link_t *link = dev_to_instance(p_dev);
 
 	DBG(0, "sl811_cs_detach(0x%p)\n", link);
 
-	/* Locate device structure */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
-		if (*linkp == link)
-			break;
-	}
-	if (*linkp == NULL)
-		return;
+	link->state &= ~DEV_PRESENT;
+	if (link->state & DEV_CONFIG)
+		sl811_cs_release(link);
 
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
-	/* Unlink device structure, and free it */
-	*linkp = link->next;
 	/* This points to the parent local_info_t struct */
 	kfree(link->priv);
 }
@@ -166,13 +157,6 @@
 
 	DBG(0, "sl811_cs_release(0x%p)\n", link);
 
-	if (link->open) {
-		DBG(1, "sl811_cs: release postponed, '%s' still open\n",
-		    link->dev->dev_name);
-		link->state |= DEV_STALE_CONFIG;
-		return;
-	}
-
 	/* Unlink the device chain */
 	link->dev = NULL;
 
@@ -183,9 +167,6 @@
 	if (link->irq.AssignedIRQ)
 		pcmcia_release_irq(link->handle, &link->irq);
 	link->state &= ~DEV_CONFIG;
-
-	if (link->state & DEV_STALE_LINK)
-		sl811_cs_detach(link);
 }
 
 static void sl811_cs_config(dev_link_t *link)
@@ -322,55 +303,36 @@
 	}
 }
 
-static int
-sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
+static int sl811_suspend(struct pcmcia_device *dev)
 {
-	dev_link_t *link = args->client_data;
+	dev_link_t *link = dev_to_instance(dev);
 
-	DBG(1, "sl811_cs_event(0x%06x)\n", event);
+	link->state |= DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
 
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			sl811_cs_release(link);
-		break;
-
-	case CS_EVENT_CARD_INSERTION:
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		sl811_cs_config(link);
-		break;
-
-	case CS_EVENT_PM_SUSPEND:
-		link->state |= DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-
-	case CS_EVENT_PM_RESUME:
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		if (link->state & DEV_CONFIG)
-			pcmcia_request_configuration(link->handle, &link->conf);
-		DBG(0, "reset sl811-hcd here?\n");
-		break;
-	}
 	return 0;
 }
 
-static dev_link_t *sl811_cs_attach(void)
+static int sl811_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+
+	link->state &= ~DEV_SUSPEND;
+	if (link->state & DEV_CONFIG)
+		pcmcia_request_configuration(link->handle, &link->conf);
+
+	return 0;
+}
+
+static int sl811_cs_attach(struct pcmcia_device *p_dev)
 {
 	local_info_t *local;
 	dev_link_t *link;
-	client_reg_t client_reg;
-	int ret;
 
 	local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
 	if (!local)
-		return NULL;
+		return -ENOMEM;
 	memset(local, 0, sizeof(local_info_t));
 	link = &local->link;
 	link->priv = local;
@@ -384,21 +346,13 @@
 	link->conf.Vcc = 33;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Register with Card Services */
-	link->next = dev_list;
-	dev_list = link;
-	client_reg.dev_info = (dev_info_t *) &driver_name;
-	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		sl811_cs_detach(link);
-		return NULL;
-	}
+	link->handle = p_dev;
+	p_dev->instance = link;
 
-	return link;
+	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	sl811_cs_config(link);
+
+	return 0;
 }
 
 static struct pcmcia_device_id sl811_ids[] = {
@@ -412,10 +366,11 @@
 	.drv		= {
 		.name	= (char *)driver_name,
 	},
-	.attach		= sl811_cs_attach,
-	.event		= sl811_cs_event,
-	.detach		= sl811_cs_detach,
+	.probe		= sl811_cs_attach,
+	.remove		= sl811_cs_detach,
 	.id_table	= sl811_ids,
+	.suspend	= sl811_suspend,
+	.resume		= sl811_resume,
 };
 
 /*====================================================================*/
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
index 151154d..5832953 100644
--- a/drivers/usb/host/uhci-debug.c
+++ b/drivers/usb/host/uhci-debug.c
@@ -2,8 +2,8 @@
  * UHCI-specific debugging code. Invaluable when something
  * goes wrong, but don't get in my face.
  *
- * Kernel visible pointers are surrounded in []'s and bus
- * visible pointers are surrounded in ()'s
+ * Kernel visible pointers are surrounded in []s and bus
+ * visible pointers are surrounded in ()s
  *
  * (C) Copyright 1999 Linus Torvalds
  * (C) Copyright 1999-2001 Johannes Erdfelt
@@ -19,7 +19,7 @@
 
 static struct dentry *uhci_debugfs_root = NULL;
 
-/* Handle REALLY large printk's so we don't overflow buffers */
+/* Handle REALLY large printks so we don't overflow buffers */
 static inline void lprintk(char *buf)
 {
 	char *p;
@@ -160,7 +160,7 @@
 			}
 
 			if (active && ni > i) {
-				out += sprintf(out, "%*s[skipped %d active TD's]\n", space, "", ni - i);
+				out += sprintf(out, "%*s[skipped %d active TDs]\n", space, "", ni - i);
 				tmp = ntmp;
 				td = ntd;
 				i = ni;
@@ -173,7 +173,7 @@
 	if (list_empty(&urbp->queue_list) || urbp->queued)
 		goto out;
 
-	out += sprintf(out, "%*sQueued QH's:\n", -space, "--");
+	out += sprintf(out, "%*sQueued QHs:\n", -space, "--");
 
 	head = &urbp->queue_list;
 	tmp = head->next;
@@ -197,7 +197,7 @@
 	}
 
 #ifdef CONFIG_PROC_FS
-static const char *qh_names[] = {
+static const char * const qh_names[] = {
   "skel_int128_qh", "skel_int64_qh",
   "skel_int32_qh", "skel_int16_qh",
   "skel_int8_qh", "skel_int4_qh",
@@ -464,7 +464,7 @@
 		} while (tmp != head);
 	}
 
-	out += sprintf(out, "Skeleton QH's\n");
+	out += sprintf(out, "Skeleton QHs\n");
 
 	for (i = 0; i < UHCI_NUM_SKELQH; ++i) {
 		int shown = 0;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index d33ce39..dfe121d 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -23,11 +23,6 @@
  */
 
 #include <linux/config.h>
-#ifdef CONFIG_USB_DEBUG
-#define DEBUG
-#else
-#undef DEBUG
-#endif
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
@@ -67,10 +62,10 @@
 
 /*
  * debug = 0, no debugging messages
- * debug = 1, dump failed URB's except for stalls
- * debug = 2, dump all failed URB's (including stalls)
+ * debug = 1, dump failed URBs except for stalls
+ * debug = 2, dump all failed URBs (including stalls)
  *            show all queues in /debug/uhci/[pci_addr]
- * debug = 3, show all TD's in URB's when dumping
+ * debug = 3, show all TDs in URBs when dumping
  */
 #ifdef DEBUG
 static int debug = 1;
@@ -93,7 +88,7 @@
 #define FSBR_DELAY	msecs_to_jiffies(50)
 
 /* When we timeout an idle transfer for FSBR, we'll switch it over to */
-/* depth first traversal. We'll do it in groups of this number of TD's */
+/* depth first traversal. We'll do it in groups of this number of TDs */
 /* to make sure it doesn't hog all of the bandwidth */
 #define DEPTH_INTERVAL 5
 
@@ -478,8 +473,6 @@
 	struct dentry *dentry;
 
 	hcd->uses_new_polling = 1;
-	if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM))
-		hcd->can_wakeup = 1;		/* Assume it supports PME# */
 
 	dentry = debugfs_create_file(hcd->self.bus_name,
 			S_IFREG|S_IRUGO|S_IWUSR, uhci_debugfs_root, uhci,
@@ -573,7 +566,7 @@
 	uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH;
 
 	/* This dummy TD is to work around a bug in Intel PIIX controllers */
-	uhci_fill_td(uhci->term_td, 0, (UHCI_NULL_DATA_SIZE << 21) |
+	uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
 		(0x7f << TD_TOKEN_DEVADDR_SHIFT) | USB_PID_IN, 0);
 	uhci->term_td->link = cpu_to_le32(uhci->term_td->dma_handle);
 
@@ -717,6 +710,8 @@
 	 * at the source, so we must turn off PIRQ.
 	 */
 	pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
+	mb();
+	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	uhci->hc_inaccessible = 1;
 	hcd->poll_rh = 0;
 
@@ -733,6 +728,13 @@
 
 	dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
 
+	/* Since we aren't in D3 any more, it's safe to set this flag
+	 * even if the controller was dead.  It might not even be dead
+	 * any more, if the firmware or quirks code has reset it.
+	 */
+	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+	mb();
+
 	if (uhci->rh_state == UHCI_RH_RESET)	/* Dead */
 		return 0;
 	spin_lock_irq(&uhci->lock);
@@ -747,8 +749,12 @@
 	check_and_reset_hc(uhci);
 	configure_hc(uhci);
 
-	if (uhci->rh_state == UHCI_RH_RESET)
+	if (uhci->rh_state == UHCI_RH_RESET) {
+
+		/* The controller had to be reset */
+		usb_root_hub_lost_power(hcd->self.root_hub);
 		suspend_rh(uhci, UHCI_RH_SUSPENDED);
+	}
 
 	spin_unlock_irq(&uhci->lock);
 
@@ -874,7 +880,7 @@
 
 init_failed:
 	if (kmem_cache_destroy(uhci_up_cachep))
-		warn("not all urb_priv's were freed!");
+		warn("not all urb_privs were freed!");
 
 up_failed:
 	debugfs_remove(uhci_debugfs_root);
@@ -892,7 +898,7 @@
 	pci_unregister_driver(&uhci_pci_driver);
 	
 	if (kmem_cache_destroy(uhci_up_cachep))
-		warn("not all urb_priv's were freed!");
+		warn("not all urb_privs were freed!");
 
 	debugfs_remove(uhci_debugfs_root);
 	kfree(errbuf);
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index e576db5..8b4b887 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -71,8 +71,6 @@
 #define   USBLEGSUP_RWC		0x8f00	/* the R/WC bits */
 #define   USBLEGSUP_RO		0x5040	/* R/O and reserved bits */
 
-#define UHCI_NULL_DATA_SIZE	0x7FF	/* for UHCI controller TD */
-
 #define UHCI_PTR_BITS		cpu_to_le32(0x000F)
 #define UHCI_PTR_TERM		cpu_to_le32(0x0001)
 #define UHCI_PTR_QH		cpu_to_le32(0x0002)
@@ -168,9 +166,11 @@
 #define TD_TOKEN_EXPLEN_MASK	0x7FF		/* expected length, encoded as n - 1 */
 #define TD_TOKEN_PID_MASK	0xFF
 
-#define uhci_explen(len)	((len) << TD_TOKEN_EXPLEN_SHIFT)
+#define uhci_explen(len)	((((len) - 1) & TD_TOKEN_EXPLEN_MASK) << \
+					TD_TOKEN_EXPLEN_SHIFT)
 
-#define uhci_expected_length(token) ((((token) >> 21) + 1) & TD_TOKEN_EXPLEN_MASK)
+#define uhci_expected_length(token) ((((token) >> TD_TOKEN_EXPLEN_SHIFT) + \
+					1) & TD_TOKEN_EXPLEN_MASK)
 #define uhci_toggle(token)	(((token) >> TD_TOKEN_TOGGLE_SHIFT) & 1)
 #define uhci_endpoint(token)	(((token) >> 15) & 0xf)
 #define uhci_devaddr(token)	(((token) >> TD_TOKEN_DEVADDR_SHIFT) & 0x7f)
@@ -223,10 +223,10 @@
  */
 
 /*
- * The UHCI driver places Interrupt, Control and Bulk into QH's both
- * to group together TD's for one transfer, and also to faciliate queuing
- * of URB's. To make it easy to insert entries into the schedule, we have
- * a skeleton of QH's for each predefined Interrupt latency, low-speed
+ * The UHCI driver places Interrupt, Control and Bulk into QHs both
+ * to group together TDs for one transfer, and also to facilitate queuing
+ * of URBs. To make it easy to insert entries into the schedule, we have
+ * a skeleton of QHs for each predefined Interrupt latency, low-speed
  * control, full-speed control and terminating QH (see explanation for
  * the terminating QH below).
  *
@@ -257,8 +257,8 @@
  *   reclamation.
  *
  * Isochronous transfers are stored before the start of the skeleton
- * schedule and don't use QH's. While the UHCI spec doesn't forbid the
- * use of QH's for Isochronous, it doesn't use them either. And the spec
+ * schedule and don't use QHs. While the UHCI spec doesn't forbid the
+ * use of QHs for Isochronous, it doesn't use them either. And the spec
  * says that queues never advance on an error completion status, which
  * makes them totally unsuitable for Isochronous transfers.
  */
@@ -359,7 +359,7 @@
 	struct dma_pool *td_pool;
 
 	struct uhci_td *term_td;	/* Terminating TD, see UHCI bug */
-	struct uhci_qh *skelqh[UHCI_NUM_SKELQH];	/* Skeleton QH's */
+	struct uhci_qh *skelqh[UHCI_NUM_SKELQH];	/* Skeleton QHs */
 
 	spinlock_t lock;
 
@@ -389,22 +389,22 @@
 	unsigned long resuming_ports;
 	unsigned long ports_timeout;		/* Time to stop signalling */
 
-	/* Main list of URB's currently controlled by this HC */
+	/* Main list of URBs currently controlled by this HC */
 	struct list_head urb_list;
 
-	/* List of QH's that are done, but waiting to be unlinked (race) */
+	/* List of QHs that are done, but waiting to be unlinked (race) */
 	struct list_head qh_remove_list;
 	unsigned int qh_remove_age;		/* Age in frames */
 
-	/* List of TD's that are done, but waiting to be freed (race) */
+	/* List of TDs that are done, but waiting to be freed (race) */
 	struct list_head td_remove_list;
 	unsigned int td_remove_age;		/* Age in frames */
 
-	/* List of asynchronously unlinked URB's */
+	/* List of asynchronously unlinked URBs */
 	struct list_head urb_remove_list;
 	unsigned int urb_remove_age;		/* Age in frames */
 
-	/* List of URB's awaiting completion callback */
+	/* List of URBs awaiting completion callback */
 	struct list_head complete_list;
 
 	int rh_numports;			/* Number of root-hub ports */
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 7e46887..b607600 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -80,7 +80,7 @@
 }
 
 /*
- * We insert Isochronous URB's directly into the frame list at the beginning
+ * We insert Isochronous URBs directly into the frame list at the beginning
  */
 static void uhci_insert_td_frame_list(struct uhci_hcd *uhci, struct uhci_td *td, unsigned framenum)
 {
@@ -369,7 +369,7 @@
 				uhci_fixup_toggle(urb,
 					uhci_toggle(td_token(lltd)) ^ 1));
 
-	/* All qh's in the queue need to link to the next queue */
+	/* All qhs in the queue need to link to the next queue */
 	urbp->qh->link = eurbp->qh->link;
 
 	wmb();			/* Make sure we flush everything */
@@ -502,7 +502,7 @@
 	}
 
 	/* Check to see if the remove list is empty. Set the IOC bit */
-	/* to force an interrupt so we can remove the TD's*/
+	/* to force an interrupt so we can remove the TDs*/
 	if (list_empty(&uhci->td_remove_list))
 		uhci_set_next_interrupt(uhci);
 
@@ -596,7 +596,7 @@
 		return -ENOMEM;
 
 	uhci_add_td_to_urb(urb, td);
-	uhci_fill_td(td, status, destination | uhci_explen(7),
+	uhci_fill_td(td, status, destination | uhci_explen(8),
 		urb->setup_dma);
 
 	/*
@@ -612,7 +612,7 @@
 	}
 
 	/*
-	 * Build the DATA TD's
+	 * Build the DATA TDs
 	 */
 	while (len > 0) {
 		int pktsze = len;
@@ -628,7 +628,7 @@
 		destination ^= TD_TOKEN_TOGGLE;
 	
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1),
+		uhci_fill_td(td, status, destination | uhci_explen(pktsze),
 			data);
 
 		data += pktsze;
@@ -658,7 +658,7 @@
 
 	uhci_add_td_to_urb(urb, td);
 	uhci_fill_td(td, status | TD_CTRL_IOC,
-		destination | uhci_explen(UHCI_NULL_DATA_SIZE), 0);
+		destination | uhci_explen(0), 0);
 
 	qh = uhci_alloc_qh(uhci);
 	if (!qh)
@@ -744,7 +744,7 @@
 
 	urb->actual_length = 0;
 
-	/* The rest of the TD's (but the last) are data */
+	/* The rest of the TDs (but the last) are data */
 	tmp = tmp->next;
 	while (tmp != head && tmp->next != head) {
 		unsigned int ctrlstat;
@@ -848,7 +848,7 @@
 		status |= TD_CTRL_SPD;
 
 	/*
-	 * Build the DATA TD's
+	 * Build the DATA TDs
 	 */
 	do {	/* Allow zero length packets */
 		int pktsze = maxsze;
@@ -864,7 +864,7 @@
 			return -ENOMEM;
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(pktsze - 1) |
+		uhci_fill_td(td, status, destination | uhci_explen(pktsze) |
 			(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
 			 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
 			data);
@@ -890,7 +890,7 @@
 			return -ENOMEM;
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(UHCI_NULL_DATA_SIZE) |
+		uhci_fill_td(td, status, destination | uhci_explen(0) |
 			(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
 			 usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE_SHIFT),
 			data);
@@ -1025,7 +1025,7 @@
 	list_for_each_entry(up, &uhci->urb_list, urb_list) {
 		struct urb *u = up->urb;
 
-		/* look for pending URB's with identical pipe handle */
+		/* look for pending URBs with identical pipe handle */
 		if ((urb->pipe == u->pipe) && (urb->dev == u->dev) &&
 		    (u->status == -EINPROGRESS) && (u != urb)) {
 			if (!last_urb)
@@ -1092,7 +1092,7 @@
 			return -ENOMEM;
 
 		uhci_add_td_to_urb(urb, td);
-		uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length - 1),
+		uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length),
 			urb->transfer_dma + urb->iso_frame_desc[i].offset);
 
 		if (i + 1 >= urb->number_of_packets)
@@ -1355,7 +1355,7 @@
 
 	uhci_delete_queued_urb(uhci, urb);
 
-	/* The interrupt loop will reclaim the QH's */
+	/* The interrupt loop will reclaim the QHs */
 	uhci_remove_qh(uhci, urbp->qh);
 	urbp->qh = NULL;
 }
@@ -1413,7 +1413,7 @@
 	list_for_each_entry(td, head, list) {
 		/*
 		 * Make sure we don't do the last one (since it'll have the
-		 * TERM bit set) as well as we skip every so many TD's to
+		 * TERM bit set) as well as we skip every so many TDs to
 		 * make sure it doesn't hog the bandwidth
 		 */
 		if (td->list.next != head && (count % DEPTH_INTERVAL) ==
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index 1d973bc..0498711 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -962,7 +962,6 @@
  */
 static struct usb_driver mdc800_usb_driver =
 {
-	.owner =	THIS_MODULE,
 	.name =		"mdc800",
 	.probe =	mdc800_usb_probe,
 	.disconnect =	mdc800_usb_disconnect,
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 950543a..458f2ac 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -160,7 +160,6 @@
 static struct usb_device_id mts_usb_ids [];
 
 static struct usb_driver mts_usb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"microtekX6",
 	.probe =	mts_usb_probe,
 	.disconnect =	mts_usb_disconnect,
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
index 1e53934..509dd0a 100644
--- a/drivers/usb/input/Kconfig
+++ b/drivers/usb/input/Kconfig
@@ -273,6 +273,20 @@
 	  To compile this driver as a module, choose M here: the module will be
 	  called ati_remote.
 
+config USB_ATI_REMOTE2
+	tristate "ATI / Philips USB RF remote control"
+	depends on USB && INPUT
+	---help---
+	  Say Y here if you want to use an ATI or Philips USB RF remote control.
+	  These are RF remotes with USB receivers.
+	  ATI Remote Wonder II comes with some ATI's All-In-Wonder video cards
+	  and is also available as a separate product.
+	  This driver provides mouse pointer, left and right mouse buttons,
+	  and maps all the other remote buttons to keypress events.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called ati_remote2.
+
 config USB_KEYSPAN_REMOTE
 	tristate "Keyspan DMR USB remote control (EXPERIMENTAL)"
 	depends on USB && INPUT && EXPERIMENTAL
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
index 07cb17d..d512d9f 100644
--- a/drivers/usb/input/Makefile
+++ b/drivers/usb/input/Makefile
@@ -28,6 +28,7 @@
 
 obj-$(CONFIG_USB_AIPTEK)	+= aiptek.o
 obj-$(CONFIG_USB_ATI_REMOTE)	+= ati_remote.o
+obj-$(CONFIG_USB_ATI_REMOTE2)	+= ati_remote2.o
 obj-$(CONFIG_USB_HID)		+= usbhid.o
 obj-$(CONFIG_USB_KBD)		+= usbkbd.o
 obj-$(CONFIG_USB_KBTAB)		+= kbtab.o
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
index a32558b..df29b80 100644
--- a/drivers/usb/input/acecad.c
+++ b/drivers/usb/input/acecad.c
@@ -261,7 +261,6 @@
 MODULE_DEVICE_TABLE(usb, usb_acecad_id_table);
 
 static struct usb_driver usb_acecad_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usb_acecad",
 	.probe =	usb_acecad_probe,
 	.disconnect =	usb_acecad_disconnect,
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index 1c3b472..a6693b0 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -338,7 +338,7 @@
  * the bitmap which comes from the tablet. This hides the
  * issue that the F_keys are not sequentially numbered.
  */
-static int macroKeyEvents[] = {
+static const int macroKeyEvents[] = {
 	KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
 	KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11,
 	KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16, KEY_F17,
@@ -2093,7 +2093,7 @@
 	/* Programming the tablet macro keys needs to be done with a for loop
 	 * as the keycodes are discontiguous.
 	 */
-	for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i)
+	for (i = 0; i < ARRAY_SIZE(macroKeyEvents); ++i)
 		set_bit(macroKeyEvents[i], inputdev->keybit);
 
 	/*
@@ -2103,7 +2103,7 @@
 	 * values.
 	 */
 	input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0);
-	input_set_abs_params(inputdev, ABS_X, 0, 2249, 0, 0);
+	input_set_abs_params(inputdev, ABS_Y, 0, 2249, 0, 0);
 	input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0);
 	input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
 	input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
@@ -2135,7 +2135,7 @@
 	 * not an error :-)
 	 */
 
-	for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) {
+	for (i = 0; i < ARRAY_SIZE(speeds); ++i) {
 		aiptek->curSetting.programmableDelay = speeds[i];
 		(void)aiptek_program_tablet(aiptek);
 		if (aiptek->inputdev->absmax[ABS_X] > 0) {
@@ -2190,7 +2190,6 @@
 static void aiptek_disconnect(struct usb_interface *intf);
 
 static struct usb_driver aiptek_driver = {
-	.owner = THIS_MODULE,
 	.name = "aiptek",
 	.probe = aiptek_probe,
 	.disconnect = aiptek_disconnect,
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
index 15840db..c222ed1 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2005      Stelian Pop (stelian@popies.net)
  * Copyright (C) 2005      Frank Arnold (frank@scirocco-5v-turbo.de)
  * Copyright (C) 2005      Peter Osterlund (petero2@telia.com)
+ * Copyright (C) 2005      Michael Hanselmann (linux-kernel@hansmi.ch)
  *
  * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
  *
@@ -38,6 +39,11 @@
 /* Apple has powerbooks which have the keyboard with different Product IDs */
 #define APPLE_VENDOR_ID		0x05AC
 
+/* These names come from Info.plist in AppleUSBTrackpad.kext */
+#define GEYSER_ANSI_PRODUCT_ID	0x0214
+#define GEYSER_ISO_PRODUCT_ID	0x0215
+#define GEYSER_JIS_PRODUCT_ID	0x0216
+
 #define ATP_DEVICE(prod)					\
 	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |		\
 		       USB_DEVICE_ID_MATCH_INT_CLASS |		\
@@ -53,13 +59,17 @@
 	{ ATP_DEVICE(0x020F) },
 	{ ATP_DEVICE(0x030A) },
 	{ ATP_DEVICE(0x030B) },
-	{ }					/* Terminating entry */
+
+	/* PowerBooks Oct 2005 */
+	{ ATP_DEVICE(GEYSER_ANSI_PRODUCT_ID) },
+	{ ATP_DEVICE(GEYSER_ISO_PRODUCT_ID) },
+	{ ATP_DEVICE(GEYSER_JIS_PRODUCT_ID) },
+
+	/* Terminating entry */
+	{ }
 };
 MODULE_DEVICE_TABLE (usb, atp_table);
 
-/* size of a USB urb transfer */
-#define ATP_DATASIZE	81
-
 /*
  * number of sensors. Note that only 16 instead of 26 X (horizontal)
  * sensors exist on 12" and 15" PowerBooks. All models have 16 Y
@@ -108,6 +118,8 @@
 	signed char		xy_old[ATP_XSENSORS + ATP_YSENSORS];
 						/* accumulated sensors */
 	int			xy_acc[ATP_XSENSORS + ATP_YSENSORS];
+	int			overflowwarn;	/* overflow warning printed? */
+	int			datalen;	/* size of an USB urb transfer */
 };
 
 #define dbg_dump(msg, tab) \
@@ -124,7 +136,7 @@
 		if (debug) printk(format, ##a);				\
 	} while (0)
 
-MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold");
+MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Michael Hanselmann");
 MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
 MODULE_LICENSE("GPL");
 
@@ -132,6 +144,16 @@
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Activate debugging output");
 
+/* Checks if the device a Geyser 2 (ANSI, ISO, JIS) */
+static inline int atp_is_geyser_2(struct atp *dev)
+{
+	int16_t productId = le16_to_cpu(dev->udev->descriptor.idProduct);
+
+	return (productId == GEYSER_ANSI_PRODUCT_ID) ||
+		(productId == GEYSER_ISO_PRODUCT_ID) ||
+		(productId == GEYSER_JIS_PRODUCT_ID);
+}
+
 static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
 			     int *z, int *fingers)
 {
@@ -168,13 +190,20 @@
 static void atp_complete(struct urb* urb, struct pt_regs* regs)
 {
 	int x, y, x_z, y_z, x_f, y_f;
-	int retval, i;
+	int retval, i, j;
 	struct atp *dev = urb->context;
 
 	switch (urb->status) {
 	case 0:
 		/* success */
 		break;
+	case -EOVERFLOW:
+		if(!dev->overflowwarn) {
+			printk("appletouch: OVERFLOW with data "
+				"length %d, actual length is %d\n",
+				dev->datalen, dev->urb->actual_length);
+			dev->overflowwarn = 1;
+		}
 	case -ECONNRESET:
 	case -ENOENT:
 	case -ESHUTDOWN:
@@ -189,23 +218,45 @@
 	}
 
 	/* drop incomplete datasets */
-	if (dev->urb->actual_length != ATP_DATASIZE) {
+	if (dev->urb->actual_length != dev->datalen) {
 		dprintk("appletouch: incomplete data package.\n");
 		goto exit;
 	}
 
 	/* reorder the sensors values */
-	for (i = 0; i < 8; i++) {
-		/* X values */
-		dev->xy_cur[i     ] = dev->data[5 * i +  2];
-		dev->xy_cur[i +  8] = dev->data[5 * i +  4];
-		dev->xy_cur[i + 16] = dev->data[5 * i + 42];
-		if (i < 2)
-			dev->xy_cur[i + 24] = dev->data[5 * i + 44];
+	if (atp_is_geyser_2(dev)) {
+		memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
 
-		/* Y values */
-		dev->xy_cur[i + 26] = dev->data[5 * i +  1];
-		dev->xy_cur[i + 34] = dev->data[5 * i +  3];
+		/*
+		 * The values are laid out like this:
+		 * Y1, Y2, -, Y3, Y4, -, ..., X1, X2, -, X3, X4, -, ...
+		 * '-' is an unused value.
+		 */
+
+		/* read X values */
+		for (i = 0, j = 19; i < 20; i += 2, j += 3) {
+			dev->xy_cur[i] = dev->data[j];
+			dev->xy_cur[i + 1] = dev->data[j + 1];
+		}
+
+		/* read Y values */
+		for (i = 0, j = 1; i < 9; i += 2, j += 3) {
+			dev->xy_cur[ATP_XSENSORS + i] = dev->data[j];
+			dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 1];
+		}
+	} else {
+		for (i = 0; i < 8; i++) {
+			/* X values */
+			dev->xy_cur[i     ] = dev->data[5 * i +  2];
+			dev->xy_cur[i +  8] = dev->data[5 * i +  4];
+			dev->xy_cur[i + 16] = dev->data[5 * i + 42];
+			if (i < 2)
+				dev->xy_cur[i + 24] = dev->data[5 * i + 44];
+
+			/* Y values */
+			dev->xy_cur[i + 26] = dev->data[5 * i +  1];
+			dev->xy_cur[i + 34] = dev->data[5 * i +  3];
+		}
 	}
 
 	dbg_dump("sample", dev->xy_cur);
@@ -216,16 +267,24 @@
 		dev->x_old = dev->y_old = -1;
 		memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
 
-		/* 17" Powerbooks have 10 extra X sensors */
-		for (i = 16; i < ATP_XSENSORS; i++)
-			if (dev->xy_cur[i]) {
-				printk("appletouch: 17\" model detected.\n");
+		/* 17" Powerbooks have extra X sensors */
+		for (i = (atp_is_geyser_2(dev)?15:16); i < ATP_XSENSORS; i++) {
+			if (!dev->xy_cur[i]) continue;
+
+			printk("appletouch: 17\" model detected.\n");
+			if(atp_is_geyser_2(dev))
+				input_set_abs_params(dev->input, ABS_X, 0,
+						     (20 - 1) *
+						     ATP_XFACT - 1,
+						     ATP_FUZZ, 0);
+			else
 				input_set_abs_params(dev->input, ABS_X, 0,
 						     (ATP_XSENSORS - 1) *
 						     ATP_XFACT - 1,
 						     ATP_FUZZ, 0);
-				break;
-			}
+
+			break;
+		}
 
 		goto exit;
 	}
@@ -282,7 +341,8 @@
 		memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
 	}
 
-	input_report_key(dev->input, BTN_LEFT, !!dev->data[80]);
+	input_report_key(dev->input, BTN_LEFT,
+			 !!dev->data[dev->datalen - 1]);
 
 	input_sync(dev->input);
 
@@ -353,6 +413,8 @@
 
 	dev->udev = udev;
 	dev->input = input_dev;
+	dev->overflowwarn = 0;
+	dev->datalen = (atp_is_geyser_2(dev)?64:81);
 
 	dev->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->urb) {
@@ -360,7 +422,7 @@
 		goto err_free_devs;
 	}
 
-	dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
+	dev->data = usb_buffer_alloc(dev->udev, dev->datalen, GFP_KERNEL,
 				     &dev->urb->transfer_dma);
 	if (!dev->data) {
 		retval = -ENOMEM;
@@ -369,7 +431,7 @@
 
 	usb_fill_int_urb(dev->urb, udev,
 			 usb_rcvintpipe(udev, int_in_endpointAddr),
-			 dev->data, ATP_DATASIZE, atp_complete, dev, 1);
+			 dev->data, dev->datalen, atp_complete, dev, 1);
 
 	usb_make_path(udev, dev->phys, sizeof(dev->phys));
 	strlcat(dev->phys, "/input0", sizeof(dev->phys));
@@ -385,14 +447,25 @@
 
 	set_bit(EV_ABS, input_dev->evbit);
 
-	/*
-	 * 12" and 15" Powerbooks only have 16 x sensors,
-	 * 17" models are detected later.
-	 */
-	input_set_abs_params(input_dev, ABS_X, 0,
-			     (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
-	input_set_abs_params(input_dev, ABS_Y, 0,
-			     (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
+	if (atp_is_geyser_2(dev)) {
+		/*
+		 * Oct 2005 15" PowerBooks have 15 X sensors, 17" are detected
+		 * later.
+		 */
+		input_set_abs_params(input_dev, ABS_X, 0,
+				     ((15 - 1) * ATP_XFACT) - 1, ATP_FUZZ, 0);
+		input_set_abs_params(input_dev, ABS_Y, 0,
+				     ((9 - 1) * ATP_YFACT) - 1, ATP_FUZZ, 0);
+	} else {
+		/*
+		 * 12" and 15" Powerbooks only have 16 x sensors,
+		 * 17" models are detected later.
+		 */
+		input_set_abs_params(input_dev, ABS_X, 0,
+				     (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
+		input_set_abs_params(input_dev, ABS_Y, 0,
+				     (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
+	}
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
 
 	set_bit(EV_KEY, input_dev->evbit);
@@ -427,7 +500,7 @@
 		usb_kill_urb(dev->urb);
 		input_unregister_device(dev->input);
 		usb_free_urb(dev->urb);
-		usb_buffer_free(dev->udev, ATP_DATASIZE,
+		usb_buffer_free(dev->udev, dev->datalen,
 				dev->data, dev->urb->transfer_dma);
 		kfree(dev);
 	}
@@ -452,7 +525,6 @@
 }
 
 static struct usb_driver atp_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "appletouch",
 	.probe		= atp_probe,
 	.disconnect	= atp_disconnect,
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index 9a2a47d..f7bdc50 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -96,6 +96,7 @@
 #include <linux/usb.h>
 #include <linux/usb_input.h>
 #include <linux/wait.h>
+#include <linux/jiffies.h>
 
 /*
  * Module and Version Information, Module Parameters
@@ -146,7 +147,7 @@
 static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 };
 
 /* Acceleration curve for directional control pad */
-static char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
+static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
 
 /* Duplicate event filtering time.
  * Sequential, identical KIND_FILTERED inputs with less than
@@ -197,7 +198,7 @@
 #define KIND_ACCEL      7   /* Directional keypad - left, right, up, down.*/
 
 /* Translation table from hardware messages to input events. */
-static struct {
+static const struct {
 	short kind;
 	unsigned char data1, data2;
 	int type;
@@ -295,7 +296,6 @@
 
 /* usb specific object to register with the usb subsystem */
 static struct usb_driver ati_remote_driver = {
-	.owner        = THIS_MODULE,
 	.name         = "ati_remote",
 	.probe        = ati_remote_probe,
 	.disconnect   = ati_remote_disconnect,
@@ -472,7 +472,7 @@
 		/* Filter duplicate events which happen "too close" together. */
 		if ((ati_remote->old_data[0] == data[1]) &&
 			(ati_remote->old_data[1] == data[2]) &&
-			((ati_remote->old_jiffies + FILTER_TIME) > jiffies)) {
+			time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) {
 			ati_remote->repeat_count++;
 		} else {
 			ati_remote->repeat_count = 0;
@@ -507,16 +507,16 @@
 	 * pad down, so we increase acceleration, ramping up over two seconds to
 	 * a maximum speed.  The acceleration curve is #defined above.
 	 */
-	if ((jiffies - ati_remote->old_jiffies) > (HZ >> 2)) {
+	if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) {
 		acc = 1;
 		ati_remote->acc_jiffies = jiffies;
 	}
-	else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 3))  acc = accel[0];
-	else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 2))  acc = accel[1];
-	else if ((jiffies - ati_remote->acc_jiffies) < (HZ >> 1))  acc = accel[2];
-	else if ((jiffies - ati_remote->acc_jiffies) < HZ )        acc = accel[3];
-	else if ((jiffies - ati_remote->acc_jiffies) < HZ+(HZ>>1)) acc = accel[4];
-	else if ((jiffies - ati_remote->acc_jiffies) < (HZ << 1))  acc = accel[5];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3)))  acc = accel[0];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2)))  acc = accel[1];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1)))  acc = accel[2];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + HZ))         acc = accel[3];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4];
+	else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1)))  acc = accel[5];
 	else acc = accel[6];
 
 	input_regs(dev, regs);
diff --git a/drivers/usb/input/ati_remote2.c b/drivers/usb/input/ati_remote2.c
new file mode 100644
index 0000000..ab1a1ae
--- /dev/null
+++ b/drivers/usb/input/ati_remote2.c
@@ -0,0 +1,477 @@
+/*
+ * ati_remote2 - ATI/Philips USB RF remote driver
+ *
+ * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi>
+ *
+ * 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/usb_input.h>
+
+#define DRIVER_DESC    "ATI/Philips USB RF remote driver"
+#define DRIVER_VERSION "0.1"
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
+MODULE_LICENSE("GPL");
+
+static unsigned int mode_mask = 0x1F;
+module_param(mode_mask, uint, 0644);
+MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
+
+static struct usb_device_id ati_remote2_id_table[] = {
+	{ USB_DEVICE(0x0471, 0x0602) },	/* ATI Remote Wonder II */
+	{ }
+};
+MODULE_DEVICE_TABLE(usb, ati_remote2_id_table);
+
+static struct {
+	int hw_code;
+	int key_code;
+} ati_remote2_key_table[] = {
+	{ 0x00, KEY_0 },
+	{ 0x01, KEY_1 },
+	{ 0x02, KEY_2 },
+	{ 0x03, KEY_3 },
+	{ 0x04, KEY_4 },
+	{ 0x05, KEY_5 },
+	{ 0x06, KEY_6 },
+	{ 0x07, KEY_7 },
+	{ 0x08, KEY_8 },
+	{ 0x09, KEY_9 },
+	{ 0x0c, KEY_POWER },
+	{ 0x0d, KEY_MUTE },
+	{ 0x10, KEY_VOLUMEUP },
+	{ 0x11, KEY_VOLUMEDOWN },
+	{ 0x20, KEY_CHANNELUP },
+	{ 0x21, KEY_CHANNELDOWN },
+	{ 0x28, KEY_FORWARD },
+	{ 0x29, KEY_REWIND },
+	{ 0x2c, KEY_PLAY },
+	{ 0x30, KEY_PAUSE },
+	{ 0x31, KEY_STOP },
+	{ 0x37, KEY_RECORD },
+	{ 0x38, KEY_DVD },
+	{ 0x39, KEY_TV },
+	{ 0x54, KEY_MENU },
+	{ 0x58, KEY_UP },
+	{ 0x59, KEY_DOWN },
+	{ 0x5a, KEY_LEFT },
+	{ 0x5b, KEY_RIGHT },
+	{ 0x5c, KEY_OK },
+	{ 0x78, KEY_A },
+	{ 0x79, KEY_B },
+	{ 0x7a, KEY_C },
+	{ 0x7b, KEY_D },
+	{ 0x7c, KEY_E },
+	{ 0x7d, KEY_F },
+	{ 0x82, KEY_ENTER },
+	{ 0x8e, KEY_VENDOR },
+	{ 0x96, KEY_COFFEE },
+	{ 0xa9, BTN_LEFT },
+	{ 0xaa, BTN_RIGHT },
+	{ 0xbe, KEY_QUESTION },
+	{ 0xd5, KEY_FRONT },
+	{ 0xd0, KEY_EDIT },
+	{ 0xf9, KEY_INFO },
+	{ (0x00 << 8) | 0x3f, KEY_PROG1 },
+	{ (0x01 << 8) | 0x3f, KEY_PROG2 },
+	{ (0x02 << 8) | 0x3f, KEY_PROG3 },
+	{ (0x03 << 8) | 0x3f, KEY_PROG4 },
+	{ (0x04 << 8) | 0x3f, KEY_PC },
+	{ 0, KEY_RESERVED }
+};
+
+struct ati_remote2 {
+	struct input_dev *idev;
+	struct usb_device *udev;
+
+	struct usb_interface *intf[2];
+	struct usb_endpoint_descriptor *ep[2];
+	struct urb *urb[2];
+	void *buf[2];
+	dma_addr_t buf_dma[2];
+
+	unsigned long jiffies;
+	int mode;
+
+	char name[64];
+	char phys[64];
+};
+
+static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
+static void ati_remote2_disconnect(struct usb_interface *interface);
+
+static struct usb_driver ati_remote2_driver = {
+	.name       = "ati_remote2",
+	.probe      = ati_remote2_probe,
+	.disconnect = ati_remote2_disconnect,
+	.id_table   = ati_remote2_id_table,
+};
+
+static int ati_remote2_open(struct input_dev *idev)
+{
+	struct ati_remote2 *ar2 = idev->private;
+	int r;
+
+	r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
+	if (r) {
+		dev_err(&ar2->intf[0]->dev,
+			"%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+		return r;
+	}
+	r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
+	if (r) {
+		usb_kill_urb(ar2->urb[0]);
+		dev_err(&ar2->intf[1]->dev,
+			"%s: usb_submit_urb() = %d\n", __FUNCTION__, r);
+		return r;
+	}
+
+	return 0;
+}
+
+static void ati_remote2_close(struct input_dev *idev)
+{
+	struct ati_remote2 *ar2 = idev->private;
+
+	usb_kill_urb(ar2->urb[0]);
+	usb_kill_urb(ar2->urb[1]);
+}
+
+static void ati_remote2_input_mouse(struct ati_remote2 *ar2, struct pt_regs *regs)
+{
+	struct input_dev *idev = ar2->idev;
+	u8 *data = ar2->buf[0];
+
+	if (data[0] > 4) {
+		dev_err(&ar2->intf[0]->dev,
+			"Unknown mode byte (%02x %02x %02x %02x)\n",
+			data[3], data[2], data[1], data[0]);
+		return;
+	}
+
+	if (!((1 << data[0]) & mode_mask))
+		return;
+
+	input_regs(idev, regs);
+	input_event(idev, EV_REL, REL_X, (s8) data[1]);
+	input_event(idev, EV_REL, REL_Y, (s8) data[2]);
+	input_sync(idev);
+}
+
+static int ati_remote2_lookup(unsigned int hw_code)
+{
+	int i;
+
+	for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
+		if (ati_remote2_key_table[i].hw_code == hw_code)
+			return i;
+
+	return -1;
+}
+
+static void ati_remote2_input_key(struct ati_remote2 *ar2, struct pt_regs *regs)
+{
+	struct input_dev *idev = ar2->idev;
+	u8 *data = ar2->buf[1];
+	int hw_code, index;
+
+	if (data[0] > 4) {
+		dev_err(&ar2->intf[1]->dev,
+			"Unknown mode byte (%02x %02x %02x %02x)\n",
+			data[3], data[2], data[1], data[0]);
+		return;
+	}
+
+	hw_code = data[2];
+	/*
+	 * Mode keys (AUX1-AUX4, PC) all generate the same code byte.
+	 * Use the mode byte to figure out which one was pressed.
+	 */
+	if (hw_code == 0x3f) {
+		/*
+		 * For some incomprehensible reason the mouse pad generates
+		 * events which look identical to the events from the last
+		 * pressed mode key. Naturally we don't want to generate key
+		 * events for the mouse pad so we filter out any subsequent
+		 * events from the same mode key.
+		 */
+		if (ar2->mode == data[0])
+			return;
+
+		if (data[1] == 0)
+			ar2->mode = data[0];
+
+		hw_code |= data[0] << 8;
+	}
+
+	if (!((1 << data[0]) & mode_mask))
+		return;
+
+	index = ati_remote2_lookup(hw_code);
+	if (index < 0) {
+		dev_err(&ar2->intf[1]->dev,
+			"Unknown code byte (%02x %02x %02x %02x)\n",
+			data[3], data[2], data[1], data[0]);
+		return;
+	}
+
+	switch (data[1]) {
+	case 0:	/* release */
+		break;
+	case 1:	/* press */
+		ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_DELAY]);
+		break;
+	case 2:	/* repeat */
+
+		/* No repeat for mouse buttons. */
+		if (ati_remote2_key_table[index].key_code == BTN_LEFT ||
+		    ati_remote2_key_table[index].key_code == BTN_RIGHT)
+			return;
+
+		if (!time_after_eq(jiffies, ar2->jiffies))
+			return;
+
+		ar2->jiffies = jiffies + msecs_to_jiffies(idev->rep[REP_PERIOD]);
+		break;
+	default:
+		dev_err(&ar2->intf[1]->dev,
+			"Unknown state byte (%02x %02x %02x %02x)\n",
+			data[3], data[2], data[1], data[0]);
+		return;
+	}
+
+	input_regs(idev, regs);
+	input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]);
+	input_sync(idev);
+}
+
+static void ati_remote2_complete_mouse(struct urb *urb, struct pt_regs *regs)
+{
+	struct ati_remote2 *ar2 = urb->context;
+	int r;
+
+	switch (urb->status) {
+	case 0:
+		ati_remote2_input_mouse(ar2, regs);
+		break;
+	case -ENOENT:
+	case -EILSEQ:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		dev_dbg(&ar2->intf[0]->dev,
+			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+		return;
+	default:
+		dev_err(&ar2->intf[0]->dev,
+			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+	}
+
+	r = usb_submit_urb(urb, GFP_ATOMIC);
+	if (r)
+		dev_err(&ar2->intf[0]->dev,
+			"%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+}
+
+static void ati_remote2_complete_key(struct urb *urb, struct pt_regs *regs)
+{
+	struct ati_remote2 *ar2 = urb->context;
+	int r;
+
+	switch (urb->status) {
+	case 0:
+		ati_remote2_input_key(ar2, regs);
+		break;
+	case -ENOENT:
+	case -EILSEQ:
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		dev_dbg(&ar2->intf[1]->dev,
+			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+		return;
+	default:
+		dev_err(&ar2->intf[1]->dev,
+			"%s(): urb status = %d\n", __FUNCTION__, urb->status);
+	}
+
+	r = usb_submit_urb(urb, GFP_ATOMIC);
+	if (r)
+		dev_err(&ar2->intf[1]->dev,
+			"%s(): usb_submit_urb() = %d\n", __FUNCTION__, r);
+}
+
+static int ati_remote2_input_init(struct ati_remote2 *ar2)
+{
+	struct input_dev *idev;
+	int i;
+
+	idev = input_allocate_device();
+	if (!idev)
+		return -ENOMEM;
+
+	ar2->idev = idev;
+	idev->private = ar2;
+
+	idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
+	idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+	idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
+		set_bit(ati_remote2_key_table[i].key_code, idev->keybit);
+
+	idev->rep[REP_DELAY]  = 250;
+	idev->rep[REP_PERIOD] = 33;
+
+	idev->open = ati_remote2_open;
+	idev->close = ati_remote2_close;
+
+	idev->name = ar2->name;
+	idev->phys = ar2->phys;
+
+	usb_to_input_id(ar2->udev, &idev->id);
+	idev->cdev.dev = &ar2->udev->dev;
+
+	i = input_register_device(idev);
+	if (i)
+		input_free_device(idev);
+
+	return i;
+}
+
+static int ati_remote2_urb_init(struct ati_remote2 *ar2)
+{
+	struct usb_device *udev = ar2->udev;
+	int i, pipe, maxp;
+
+	for (i = 0; i < 2; i++) {
+		ar2->buf[i] = usb_buffer_alloc(udev, 4, GFP_KERNEL, &ar2->buf_dma[i]);
+		if (!ar2->buf[i])
+			return -ENOMEM;
+
+		ar2->urb[i] = usb_alloc_urb(0, GFP_KERNEL);
+		if (!ar2->urb[i])
+			return -ENOMEM;
+
+		pipe = usb_rcvintpipe(udev, ar2->ep[i]->bEndpointAddress);
+		maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+		maxp = maxp > 4 ? 4 : maxp;
+
+		usb_fill_int_urb(ar2->urb[i], udev, pipe, ar2->buf[i], maxp,
+				 i ? ati_remote2_complete_key : ati_remote2_complete_mouse,
+				 ar2, ar2->ep[i]->bInterval);
+		ar2->urb[i]->transfer_dma = ar2->buf_dma[i];
+		ar2->urb[i]->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+	}
+
+	return 0;
+}
+
+static void ati_remote2_urb_cleanup(struct ati_remote2 *ar2)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (ar2->urb[i])
+			usb_free_urb(ar2->urb[i]);
+
+		if (ar2->buf[i])
+			usb_buffer_free(ar2->udev, 4, ar2->buf[i], ar2->buf_dma[i]);
+	}
+}
+
+static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(interface);
+	struct usb_host_interface *alt = interface->cur_altsetting;
+	struct ati_remote2 *ar2;
+	int r;
+
+	if (alt->desc.bInterfaceNumber)
+		return -ENODEV;
+
+	ar2 = kzalloc(sizeof (struct ati_remote2), GFP_KERNEL);
+	if (!ar2)
+		return -ENOMEM;
+
+	ar2->udev = udev;
+
+	ar2->intf[0] = interface;
+	ar2->ep[0] = &alt->endpoint[0].desc;
+
+	ar2->intf[1] = usb_ifnum_to_if(udev, 1);
+	r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2);
+	if (r)
+		goto fail1;
+	alt = ar2->intf[1]->cur_altsetting;
+	ar2->ep[1] = &alt->endpoint[0].desc;
+
+	r = ati_remote2_urb_init(ar2);
+	if (r)
+		goto fail2;
+
+	usb_make_path(udev, ar2->phys, sizeof(ar2->phys));
+	strlcat(ar2->phys, "/input0", sizeof(ar2->phys));
+
+	strlcat(ar2->name, "ATI Remote Wonder II", sizeof(ar2->name));
+
+	r = ati_remote2_input_init(ar2);
+	if (r)
+		goto fail2;
+
+	usb_set_intfdata(interface, ar2);
+
+	return 0;
+
+ fail2:
+	ati_remote2_urb_cleanup(ar2);
+
+	usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
+ fail1:
+	kfree(ar2);
+
+	return r;
+}
+
+static void ati_remote2_disconnect(struct usb_interface *interface)
+{
+	struct ati_remote2 *ar2;
+	struct usb_host_interface *alt = interface->cur_altsetting;
+
+	if (alt->desc.bInterfaceNumber)
+		return;
+
+	ar2 = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	input_unregister_device(ar2->idev);
+
+	ati_remote2_urb_cleanup(ar2);
+
+	usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]);
+
+	kfree(ar2);
+}
+
+static int __init ati_remote2_init(void)
+{
+	int r;
+
+	r = usb_register(&ati_remote2_driver);
+	if (r)
+		printk(KERN_ERR "ati_remote2: usb_register() = %d\n", r);
+	else
+		printk(KERN_INFO "ati_remote2: " DRIVER_DESC " " DRIVER_VERSION "\n");
+
+	return r;
+}
+
+static void __exit ati_remote2_exit(void)
+{
+	usb_deregister(&ati_remote2_driver);
+}
+
+module_init(ati_remote2_init);
+module_exit(ati_remote2_exit);
diff --git a/drivers/usb/input/fixp-arith.h b/drivers/usb/input/fixp-arith.h
index 26ca5b8..b44d398 100644
--- a/drivers/usb/input/fixp-arith.h
+++ b/drivers/usb/input/fixp-arith.h
@@ -38,7 +38,7 @@
 #define FRAC_MASK ((1<<FRAC_N)-1)
 
 // Not to be used directly. Use fixp_{cos,sin}
-static fixp_t cos_table[45] = {
+static const fixp_t cos_table[45] = {
 	0x0100,	0x00FF,	0x00FF,	0x00FE,	0x00FD,	0x00FC,	0x00FA,	0x00F8,
 	0x00F6,	0x00F3,	0x00F0,	0x00ED,	0x00E9,	0x00E6,	0x00E2,	0x00DD,
 	0x00D9,	0x00D4,	0x00CF,	0x00C9,	0x00C4,	0x00BE,	0x00B8,	0x00B1,
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 45f3130..5f52979 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -893,8 +893,10 @@
 
 	size = ((report->size - 1) >> 3) + 1;
 
-	if (len < size)
+	if (len < size) {
 		dbg("report %d is too short, (%d < %d)", report->id, len, size);
+		memset(data + len, 0, size - len);
+	}
 
 	if (hid->claimed & HID_CLAIMED_HIDDEV)
 		hiddev_report_event(hid, report);
@@ -1452,7 +1454,7 @@
  * Alphabetically sorted blacklist by quirk type.
  */
 
-static struct hid_blacklist {
+static const struct hid_blacklist {
 	__u16 idVendor;
 	__u16 idProduct;
 	unsigned quirks;
@@ -1928,7 +1930,6 @@
 MODULE_DEVICE_TABLE (usb, hid_usb_ids);
 
 static struct usb_driver hid_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbhid",
 	.probe =	hid_probe,
 	.disconnect =	hid_disconnect,
diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h
index ceebab9..702c48c 100644
--- a/drivers/usb/input/hid-debug.h
+++ b/drivers/usb/input/hid-debug.h
@@ -681,6 +681,21 @@
 	[KEY_SEND] = "Send",			[KEY_REPLY] = "Reply",
 	[KEY_FORWARDMAIL] = "ForwardMail",	[KEY_SAVE] = "Save",
 	[KEY_DOCUMENTS] = "Documents",
+	[KEY_FN] = "Fn",			[KEY_FN_ESC] = "Fn+ESC",
+	[KEY_FN_1] = "Fn+1",			[KEY_FN_2] = "Fn+2",
+	[KEY_FN_B] = "Fn+B",			[KEY_FN_D] = "Fn+D",
+	[KEY_FN_E] = "Fn+E",			[KEY_FN_F] = "Fn+F",
+	[KEY_FN_S] = "Fn+S",
+	[KEY_FN_F1] = "Fn+F1",			[KEY_FN_F2] = "Fn+F2",
+	[KEY_FN_F3] = "Fn+F3",			[KEY_FN_F4] = "Fn+F4",
+	[KEY_FN_F5] = "Fn+F5",			[KEY_FN_F6] = "Fn+F6",
+	[KEY_FN_F7] = "Fn+F7",			[KEY_FN_F8] = "Fn+F8",
+	[KEY_FN_F9] = "Fn+F9",			[KEY_FN_F10] = "Fn+F10",
+	[KEY_FN_F11] = "Fn+F11",		[KEY_FN_F12] = "Fn+F12",
+	[KEY_KBDILLUMTOGGLE] = "KbdIlluminationToggle",
+	[KEY_KBDILLUMDOWN] = "KbdIlluminationDown",
+	[KEY_KBDILLUMUP] = "KbdIlluminationUp",
+	[KEY_SWITCHVIDEOMODE] = "SwitchVideoMode",
 };
 
 static char *relatives[REL_MAX + 1] = {
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 9ff25eb..192a03b 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -39,7 +39,7 @@
 
 #define unk	KEY_UNKNOWN
 
-static unsigned char hid_keyboard[256] = {
+static const unsigned char hid_keyboard[256] = {
 	  0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
 	 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
 	  4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
@@ -58,7 +58,7 @@
 	150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
 };
 
-static struct {
+static const struct {
 	__s32 x;
 	__s32 y;
 }  hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};
@@ -137,6 +137,7 @@
 			switch (usage->hid & 0xffff) {
 				case 0xba: map_abs(ABS_RUDDER); break;
 				case 0xbb: map_abs(ABS_THROTTLE); break;
+				default:   goto ignore;
 			}
 			break;
 
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c
index 440377c..4dff847 100644
--- a/drivers/usb/input/hiddev.c
+++ b/drivers/usb/input/hiddev.c
@@ -826,7 +826,6 @@
 
 
 static /* const */ struct usb_driver hiddev_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"hiddev",
 	.probe =	hiddev_usbd_probe,
 };
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
index 4a50acb..7618ae5 100644
--- a/drivers/usb/input/itmtouch.c
+++ b/drivers/usb/input/itmtouch.c
@@ -250,7 +250,6 @@
 MODULE_DEVICE_TABLE(usb, itmtouch_ids);
 
 static struct usb_driver itmtouch_driver = {
-	.owner =        THIS_MODULE,
 	.name =         "itmtouch",
 	.probe =        itmtouch_probe,
 	.disconnect =   itmtouch_disconnect,
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
index a248664..f6d5cea 100644
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/usb/input/kbtab.c
@@ -159,7 +159,7 @@
 	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
 	input_dev->mscbit[0] |= BIT(MSC_SERIAL);
 	input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
-	input_set_abs_params(input_dev, ABS_X, 0, 0x1750, 4, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0);
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
 
 	endpoint = &intf->cur_altsetting->endpoint[0].desc;
@@ -197,7 +197,6 @@
 }
 
 static struct usb_driver kbtab_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"kbtab",
 	.probe =	kbtab_probe,
 	.disconnect =	kbtab_disconnect,
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index a32cfe5..b4a051b 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -95,7 +95,7 @@
  * Currently there are 15 and 17 button models so RESERVED codes
  * are blank areas in the mapping.
  */
-static int keyspan_key_table[] = {
+static const int keyspan_key_table[] = {
 	KEY_RESERVED,		/* 0 is just a place holder. */
 	KEY_RESERVED,
 	KEY_STOP,
@@ -559,7 +559,6 @@
  */
 static struct usb_driver keyspan_driver =
 {
-	.owner =	THIS_MODULE,
 	.name =		"keyspan_remote",
 	.probe =	keyspan_probe,
 	.disconnect =	keyspan_disconnect,
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index 52cc18c..f018953 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -310,7 +310,6 @@
 MODULE_DEVICE_TABLE(usb, mtouchusb_devices);
 
 static struct usb_driver mtouchusb_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "mtouchusb",
 	.probe		= mtouchusb_probe,
 	.disconnect	= mtouchusb_disconnect,
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
index b747623..fdf0f78 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -441,7 +441,6 @@
 MODULE_DEVICE_TABLE (usb, powermate_devices);
 
 static struct usb_driver powermate_driver = {
-	.owner =	THIS_MODULE,
         .name =         "powermate",
         .probe =        powermate_probe,
         .disconnect =   powermate_disconnect,
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index 7420c6b..3b3c7b4 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -1,7 +1,7 @@
 /******************************************************************************
  * touchkitusb.c  --  Driver for eGalax TouchKit USB Touchscreens
  *
- * Copyright (C) 2004 by Daniel Ritz
+ * Copyright (C) 2004-2005 by Daniel Ritz <daniel.ritz@gmx.ch>
  * Copyright (C) by Todd E. Johnson (mtouchusb.c)
  *
  * This program is free software; you can redistribute it and/or
@@ -41,15 +41,13 @@
 #define TOUCHKIT_MAX_YC			0x07ff
 #define TOUCHKIT_YC_FUZZ		0x0
 #define TOUCHKIT_YC_FLAT		0x0
-#define TOUCHKIT_REPORT_DATA_SIZE	8
+#define TOUCHKIT_REPORT_DATA_SIZE	16
 
 #define TOUCHKIT_DOWN			0x01
-#define TOUCHKIT_POINT_TOUCH		0x81
-#define TOUCHKIT_POINT_NOTOUCH		0x80
 
-#define TOUCHKIT_GET_TOUCHED(dat)	((((dat)[0]) & TOUCHKIT_DOWN) ? 1 : 0)
-#define TOUCHKIT_GET_X(dat)		(((dat)[3] << 7) | (dat)[4])
-#define TOUCHKIT_GET_Y(dat)		(((dat)[1] << 7) | (dat)[2])
+#define TOUCHKIT_PKT_TYPE_MASK		0xFE
+#define TOUCHKIT_PKT_TYPE_REPT		0x80
+#define TOUCHKIT_PKT_TYPE_DIAG		0x0A
 
 #define DRIVER_VERSION			"v0.1"
 #define DRIVER_AUTHOR			"Daniel Ritz <daniel.ritz@gmx.ch>"
@@ -62,6 +60,8 @@
 struct touchkit_usb {
 	unsigned char *data;
 	dma_addr_t data_dma;
+	char buffer[TOUCHKIT_REPORT_DATA_SIZE];
+	int buf_len;
 	struct urb *irq;
 	struct usb_device *udev;
 	struct input_dev *input;
@@ -77,11 +77,128 @@
 	{}
 };
 
+/* helpers to read the data */
+static inline int touchkit_get_touched(char *data)
+{
+	return (data[0] & TOUCHKIT_DOWN) ? 1 : 0;
+}
+
+static inline int touchkit_get_x(char *data)
+{
+	return ((data[3] & 0x0F) << 7) | (data[4] & 0x7F);
+}
+
+static inline int touchkit_get_y(char *data)
+{
+	return ((data[1] & 0x0F) << 7) | (data[2] & 0x7F);
+}
+
+
+/* processes one input packet. */
+static void touchkit_process_pkt(struct touchkit_usb *touchkit,
+                                 struct pt_regs *regs, char *pkt)
+{
+	int x, y;
+
+	/* only process report packets */
+	if ((pkt[0] & TOUCHKIT_PKT_TYPE_MASK) != TOUCHKIT_PKT_TYPE_REPT)
+		return;
+
+	if (swap_xy) {
+		y = touchkit_get_x(pkt);
+		x = touchkit_get_y(pkt);
+	} else {
+		x = touchkit_get_x(pkt);
+		y = touchkit_get_y(pkt);
+	}
+
+	input_regs(touchkit->input, regs);
+	input_report_key(touchkit->input, BTN_TOUCH, touchkit_get_touched(pkt));
+	input_report_abs(touchkit->input, ABS_X, x);
+	input_report_abs(touchkit->input, ABS_Y, y);
+	input_sync(touchkit->input);
+}
+
+
+static int touchkit_get_pkt_len(char *buf)
+{
+	switch (buf[0] & TOUCHKIT_PKT_TYPE_MASK) {
+	case TOUCHKIT_PKT_TYPE_REPT:
+		return 5;
+
+	case TOUCHKIT_PKT_TYPE_DIAG:
+		return buf[1] + 2;
+	}
+
+	return 0;
+}
+
+static void touchkit_process(struct touchkit_usb *touchkit, int len,
+                             struct pt_regs *regs)
+{
+	char *buffer;
+	int pkt_len, buf_len, pos;
+
+	/* if the buffer contains data, append */
+	if (unlikely(touchkit->buf_len)) {
+		int tmp;
+
+		/* if only 1 byte in buffer, add another one to get length */
+		if (touchkit->buf_len == 1)
+			touchkit->buffer[1] = touchkit->data[0];
+
+		pkt_len = touchkit_get_pkt_len(touchkit->buffer);
+
+		/* unknown packet: drop everything */
+		if (!pkt_len)
+			return;
+
+		/* append, process */
+		tmp = pkt_len - touchkit->buf_len;
+		memcpy(touchkit->buffer + touchkit->buf_len, touchkit->data, tmp);
+		touchkit_process_pkt(touchkit, regs, touchkit->buffer);
+
+		buffer = touchkit->data + tmp;
+		buf_len = len - tmp;
+	} else {
+		buffer = touchkit->data;
+		buf_len = len;
+	}
+
+	/* only one byte left in buffer */
+	if (unlikely(buf_len == 1)) {
+		touchkit->buffer[0] = buffer[0];
+		touchkit->buf_len = 1;
+		return;
+	}
+
+	/* loop over the buffer */
+	pos = 0;
+	while (pos < buf_len) {
+		/* get packet len */
+		pkt_len = touchkit_get_pkt_len(buffer + pos);
+
+		/* unknown packet: drop everything */
+		if (unlikely(!pkt_len))
+			return;
+
+		/* full packet: process */
+		if (likely(pkt_len <= buf_len)) {
+			touchkit_process_pkt(touchkit, regs, buffer + pos);
+		} else {
+			/* incomplete packet: save in buffer */
+			memcpy(touchkit->buffer, buffer + pos, buf_len - pos);
+			touchkit->buf_len = buf_len - pos;
+		}
+		pos += pkt_len;
+	}
+}
+
+
 static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
 {
 	struct touchkit_usb *touchkit = urb->context;
 	int retval;
-	int x, y;
 
 	switch (urb->status) {
 	case 0:
@@ -105,20 +222,7 @@
 		goto exit;
 	}
 
-	if (swap_xy) {
-		y = TOUCHKIT_GET_X(touchkit->data);
-		x = TOUCHKIT_GET_Y(touchkit->data);
-	} else {
-		x = TOUCHKIT_GET_X(touchkit->data);
-		y = TOUCHKIT_GET_Y(touchkit->data);
-	}
-
-	input_regs(touchkit->input, regs);
-	input_report_key(touchkit->input, BTN_TOUCH,
-	                 TOUCHKIT_GET_TOUCHED(touchkit->data));
-	input_report_abs(touchkit->input, ABS_X, x);
-	input_report_abs(touchkit->input, ABS_Y, y);
-	input_sync(touchkit->input);
+	touchkit_process(touchkit, urb->actual_length, regs);
 
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -267,7 +371,6 @@
 MODULE_DEVICE_TABLE(usb, touchkit_devices);
 
 static struct usb_driver touchkit_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "touchkitusb",
 	.probe		= touchkit_probe,
 	.disconnect	= touchkit_disconnect,
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index 226b6f9..2f3edc2 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -345,7 +345,6 @@
 MODULE_DEVICE_TABLE (usb, usb_kbd_id_table);
 
 static struct usb_driver usb_kbd_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbkbd",
 	.probe =	usb_kbd_probe,
 	.disconnect =	usb_kbd_disconnect,
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index 230f6b1..af52613 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -226,7 +226,6 @@
 MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
 
 static struct usb_driver usb_mouse_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "usbmouse",
 	.probe		= usb_mouse_probe,
 	.disconnect	= usb_mouse_disconnect,
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index aea1cfa..48df4cf 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -854,7 +854,7 @@
 
 	input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
 	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
-	input_set_abs_params(input_dev, ABS_X, 0, wacom->features->y_max, 4, 0);
+	input_set_abs_params(input_dev, ABS_X, 0, wacom->features->x_max, 4, 0);
 	input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0);
 	input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0);
 
@@ -945,7 +945,6 @@
 }
 
 static struct usb_driver wacom_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"wacom",
 	.probe =	wacom_probe,
 	.disconnect =	wacom_disconnect,
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index 43112f0..e278489 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -70,7 +70,7 @@
 
 #define XPAD_PKT_LEN 32
 
-static struct xpad_device {
+static const struct xpad_device {
 	u16 idVendor;
 	u16 idProduct;
 	char *name;
@@ -81,13 +81,13 @@
 	{ 0x0000, 0x0000, "X-Box pad" }
 };
 
-static signed short xpad_btn[] = {
+static const signed short xpad_btn[] = {
 	BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z,	/* "analog" buttons */
 	BTN_START, BTN_BACK, BTN_THUMBL, BTN_THUMBR,	/* start/back/sticks */
 	-1						/* terminating entry */
 };
 
-static signed short xpad_abs[] = {
+static const signed short xpad_abs[] = {
 	ABS_X, ABS_Y,		/* left stick */
 	ABS_RX, ABS_RY,		/* right stick */
 	ABS_Z, ABS_RZ,		/* triggers left/right */
@@ -316,7 +316,6 @@
 }
 
 static struct usb_driver xpad_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "xpad",
 	.probe		= xpad_probe,
 	.disconnect	= xpad_disconnect,
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
index f526aeb..1bfc105 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -987,7 +987,6 @@
 }
 
 static struct usb_driver yealink_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "yealink",
 	.probe		= usb_probe,
 	.disconnect	= usb_disconnect,
diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
index 27b23c5..18d8eaf 100644
--- a/drivers/usb/media/dabusb.c
+++ b/drivers/usb/media/dabusb.c
@@ -812,7 +812,6 @@
 MODULE_DEVICE_TABLE (usb, dabusb_ids);
 
 static struct usb_driver dabusb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"dabusb",
 	.probe =	dabusb_probe,
 	.disconnect =	dabusb_disconnect,
diff --git a/drivers/usb/media/dsbr100.c b/drivers/usb/media/dsbr100.c
index 7503f5b..6a5700e 100644
--- a/drivers/usb/media/dsbr100.c
+++ b/drivers/usb/media/dsbr100.c
@@ -150,7 +150,6 @@
 
 /* USB subsystem interface */
 static struct usb_driver usb_dsbr100_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"dsbr100",
 	.probe =	usb_dsbr100_probe,
 	.disconnect =	usb_dsbr100_disconnect,
diff --git a/drivers/usb/media/ibmcam.c b/drivers/usb/media/ibmcam.c
index ba41fc7..a42c222 100644
--- a/drivers/usb/media/ibmcam.c
+++ b/drivers/usb/media/ibmcam.c
@@ -3457,7 +3457,7 @@
 	if(init_model3_input) {
 		if (debug > 0)
 			info("Setting input to RCA.");
-		for (i=0; i < (sizeof(initData)/sizeof(initData[0])); i++) {
+		for (i=0; i < ARRAY_SIZE(initData); i++) {
 			ibmcam_veio(uvd, initData[i].req, initData[i].value, initData[i].index);
 		}
 	}
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
index 9fe2c27..e2ede58 100644
--- a/drivers/usb/media/konicawc.c
+++ b/drivers/usb/media/konicawc.c
@@ -77,14 +77,14 @@
 static int sharpness =	MAX_SHARPNESS/2;
 static int whitebal =	3*(MAX_WHITEBAL/4);
 
-static int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
+static const int spd_to_iface[] = { 1, 0, 3, 2, 4, 5, 6 };
 
 /* These FPS speeds are from the windows config box. They are
  * indexed on size (0-2) and speed (0-6). Divide by 3 to get the
  * real fps.
  */
 
-static int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
+static const int spd_to_fps[][7] = { { 24, 40, 48, 60, 72, 80, 100 },
 			       { 24, 40, 48, 60, 72, 80, 100 },
 			       { 18, 30, 36, 45, 54, 60, 75  },
 			       { 6,  10, 12, 15, 18, 21, 25  } };
@@ -95,7 +95,7 @@
 	u8	cmd;
 };
 
-static struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
+static const struct cam_size camera_sizes[] = { { 160, 120, 0x7 },
 					  { 160, 136, 0xa },
 					  { 176, 144, 0x4 },
 					  { 320, 240, 0x5 } };
diff --git a/drivers/usb/media/ov511.c b/drivers/usb/media/ov511.c
index 036c485..3a0e8ce 100644
--- a/drivers/usb/media/ov511.c
+++ b/drivers/usb/media/ov511.c
@@ -211,7 +211,7 @@
 
 /* Number of times to retry a failed I2C transaction. Increase this if you
  * are getting "Failed to read sensor ID..." */
-static int i2c_detect_tries = 5;
+static const int i2c_detect_tries = 5;
 
 /* MMX support is present in kernel and CPU. Checked upon decomp module load. */
 #if defined(__i386__) || defined(__x86_64__)
@@ -6008,7 +6008,6 @@
 }
 
 static struct usb_driver ov511_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ov511",
 	.id_table =	device_table,
 	.probe =	ov51x_probe,
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c
index 5309919..359c4b2 100644
--- a/drivers/usb/media/pwc/pwc-ctrl.c
+++ b/drivers/usb/media/pwc/pwc-ctrl.c
@@ -109,7 +109,7 @@
 #define PT_RESET_CONTROL_FORMATTER		0x02
 #define PT_STATUS_FORMATTER			0x03
 
-static char *size2name[PSZ_MAX] =
+static const char *size2name[PSZ_MAX] =
 {
 	"subQCIF",
 	"QSIF",
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c
index 5524fd7..09ca612 100644
--- a/drivers/usb/media/pwc/pwc-if.c
+++ b/drivers/usb/media/pwc/pwc-if.c
@@ -111,7 +111,6 @@
 static void usb_pwc_disconnect(struct usb_interface *intf);
 
 static struct usb_driver pwc_driver = {
-	.owner =		THIS_MODULE,
 	.name =			"Philips webcam",	/* name */
 	.id_table =		pwc_device_table,
 	.probe =		usb_pwc_probe,		/* probe() */
diff --git a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
index f69e443..b2ae29a 100644
--- a/drivers/usb/media/se401.c
+++ b/drivers/usb/media/se401.c
@@ -1401,7 +1401,6 @@
 }
 
 static struct usb_driver se401_driver = {
-	.owner		= THIS_MODULE,
         .name		= "se401",
         .id_table	= device_table,
 	.probe		= se401_probe,
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c
index b2e66e3..8d1a1c3 100644
--- a/drivers/usb/media/sn9c102_core.c
+++ b/drivers/usb/media/sn9c102_core.c
@@ -1316,7 +1316,7 @@
 	struct v4l2_control ctrl;
 	struct v4l2_queryctrl *qctrl;
 	struct v4l2_rect* rect;
-	u8 i = 0, n = 0;
+	u8 i = 0;
 	int err = 0;
 
 	if (!(cam->state & DEV_INITIALIZED)) {
@@ -1352,7 +1352,7 @@
 		return err;
 
 	if (s->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
-		DBG(3, "Compressed video format is active, quality %d", 
+		DBG(3, "Compressed video format is active, quality %d",
 		    cam->compression.quality)
 	else
 		DBG(3, "Uncompressed video format is active")
@@ -1364,9 +1364,8 @@
 		}
 
 	if (s->set_ctrl) {
-		n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
-		for (i = 0; i < n; i++)
-			if (s->qctrl[i].id != 0 && 
+		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
+			if (s->qctrl[i].id != 0 &&
 			    !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
 				ctrl.id = s->qctrl[i].id;
 				ctrl.value = qctrl[i].default_value;
@@ -1388,7 +1387,7 @@
 		init_waitqueue_head(&cam->wait_stream);
 		cam->nreadbuffers = 2;
 		memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
-		memcpy(&(s->_rect), &(s->cropcap.defrect), 
+		memcpy(&(s->_rect), &(s->cropcap.defrect),
 		       sizeof(struct v4l2_rect));
 		cam->state |= DEV_INITIALIZED;
 	}
@@ -1810,13 +1809,12 @@
 	{
 		struct sn9c102_sensor* s = cam->sensor;
 		struct v4l2_queryctrl qc;
-		u8 i, n;
+		u8 i;
 
 		if (copy_from_user(&qc, arg, sizeof(qc)))
 			return -EFAULT;
 
-		n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
-		for (i = 0; i < n; i++)
+		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
 			if (qc.id && qc.id == s->qctrl[i].id) {
 				memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
 				if (copy_to_user(arg, &qc, sizeof(qc)))
@@ -1852,7 +1850,7 @@
 	{
 		struct sn9c102_sensor* s = cam->sensor;
 		struct v4l2_control ctrl;
-		u8 i, n;
+		u8 i;
 		int err = 0;
 
 		if (!s->set_ctrl)
@@ -1861,8 +1859,7 @@
 		if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
 			return -EFAULT;
 
-		n = sizeof(s->qctrl) / sizeof(s->qctrl[0]);
-		for (i = 0; i < n; i++)
+		for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
 			if (ctrl.id == s->qctrl[i].id) {
 				if (ctrl.value < s->qctrl[i].minimum ||
 				    ctrl.value > s->qctrl[i].maximum)
@@ -2544,7 +2541,7 @@
 	unsigned int i, n;
 	int err = 0, r;
 
-	n = sizeof(sn9c102_id_table)/sizeof(sn9c102_id_table[0]);
+	n = ARRAY_SIZE(sn9c102_id_table);
 	for (i = 0; i < n-1; i++)
 		if (le16_to_cpu(udev->descriptor.idVendor) == 
 		    sn9c102_id_table[i].idVendor &&
@@ -2711,7 +2708,6 @@
 
 
 static struct usb_driver sn9c102_usb_driver = {
-	.owner =      THIS_MODULE,
 	.name =       "sn9c102",
 	.id_table =   sn9c102_id_table,
 	.probe =      sn9c102_usb_probe,
diff --git a/drivers/usb/media/stv680.c b/drivers/usb/media/stv680.c
index 0fd0fa9..774038b 100644
--- a/drivers/usb/media/stv680.c
+++ b/drivers/usb/media/stv680.c
@@ -1477,7 +1477,6 @@
 }
 
 static struct usb_driver stv680_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"stv680",
 	.probe =	stv680_probe,
 	.disconnect =	stv680_disconnect,
diff --git a/drivers/usb/media/stv680.h b/drivers/usb/media/stv680.h
index 4459406..b0551cd 100644
--- a/drivers/usb/media/stv680.h
+++ b/drivers/usb/media/stv680.h
@@ -151,7 +151,7 @@
 };
 
 
-static unsigned char red[256] = { 
+static const unsigned char red[256] = {
 	0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 
 	18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, 
 	44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, 
@@ -176,7 +176,7 @@
 	220, 220, 221, 221 
 }; 
 
-static unsigned char green[256] = {
+static const unsigned char green[256] = {
 	0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 
 	21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, 
 	50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, 
@@ -201,7 +201,7 @@
 	245, 245, 246, 246 
 }; 
 
-static unsigned char blue[256] = {
+static const unsigned char blue[256] = {
 	0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
 	23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, 
 	55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, 
diff --git a/drivers/usb/media/usbvideo.c b/drivers/usb/media/usbvideo.c
index 24efb21..4bd1133 100644
--- a/drivers/usb/media/usbvideo.c
+++ b/drivers/usb/media/usbvideo.c
@@ -725,7 +725,7 @@
 		/* Allocate user_data separately because of kmalloc's limits */
 		if (num_extra > 0) {
 			up->user_size = num_cams * num_extra;
-			up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL);
+			up->user_data = kmalloc(up->user_size, GFP_KERNEL);
 			if (up->user_data == NULL) {
 				err("%s: Failed to allocate user_data (%d. bytes)",
 				    __FUNCTION__, up->user_size);
@@ -955,7 +955,7 @@
 	.ioctl =  usbvideo_v4l_ioctl,
 	.llseek = no_llseek,
 };
-static struct video_device usbvideo_template = {
+static const struct video_device usbvideo_template = {
 	.owner =      THIS_MODULE,
 	.type =       VID_TYPE_CAPTURE,
 	.hardware =   VID_HARDWARE_CPIA,
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
index 0bc0b12..1c73155 100644
--- a/drivers/usb/media/vicam.c
+++ b/drivers/usb/media/vicam.c
@@ -1257,7 +1257,6 @@
 MODULE_DEVICE_TABLE(usb, vicam_table);
 
 static struct usb_driver vicam_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "vicam",
 	.probe		= vicam_probe,
 	.disconnect	= vicam_disconnect,
diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c
index 67612c8..3605a6f 100644
--- a/drivers/usb/media/w9968cf.c
+++ b/drivers/usb/media/w9968cf.c
@@ -1533,12 +1533,12 @@
 		}
 	} else {
 		DBG(4, "Rejected client [%s] with driver [%s]", 
-		    client->name, client->driver->name)
+		    client->name, client->driver->driver.name)
 		return -EINVAL;
 	}
 
 	DBG(5, "I2C attach client [%s] with driver [%s]",
-	    client->name, client->driver->name)
+	    client->name, client->driver->driver.name)
 
 	return 0;
 }
@@ -2958,7 +2958,7 @@
 	};
 
 	#define V4L1_IOCTL(cmd) \
-	        ((_IOC_NR((cmd)) < sizeof(v4l1_ioctls)/sizeof(char*)) ? \
+	        ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \
 	        v4l1_ioctls[_IOC_NR((cmd))] : "?")
 
 	cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
@@ -3554,7 +3554,7 @@
 
 
 	/* Allocate 2 bytes of memory for camera control USB transfers */
-	if (!(cam->control_buffer = (u16*)kmalloc(2, GFP_KERNEL))) {
+	if (!(cam->control_buffer = kmalloc(2, GFP_KERNEL))) {
 		DBG(1,"Couldn't allocate memory for camera control transfers")
 		err = -ENOMEM;
 		goto fail;
@@ -3562,7 +3562,7 @@
 	memset(cam->control_buffer, 0, 2);
 
 	/* Allocate 8 bytes of memory for USB data transfers to the FSB */
-	if (!(cam->data_buffer = (u16*)kmalloc(8, GFP_KERNEL))) {
+	if (!(cam->data_buffer = kmalloc(8, GFP_KERNEL))) {
 		DBG(1, "Couldn't allocate memory for data "
 		       "transfers to the FSB")
 		err = -ENOMEM;
@@ -3668,7 +3668,6 @@
 
 
 static struct usb_driver w9968cf_usb_driver = {
-	.owner =      THIS_MODULE,
 	.name =       "w9968cf",
 	.id_table =   winbond_id_table,
 	.probe =      w9968cf_usb_probe,
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
index 2a28cee..449b250 100644
--- a/drivers/usb/misc/auerswald.c
+++ b/drivers/usb/misc/auerswald.c
@@ -767,7 +767,7 @@
 	        memset (bep, 0, sizeof (auerbuf_t));
                 bep->list = bcp;
                 INIT_LIST_HEAD (&bep->buff_list);
-                bep->bufp = (char *) kmalloc (bufsize, GFP_KERNEL);
+                bep->bufp = kmalloc (bufsize, GFP_KERNEL);
                 if (!bep->bufp)
 			goto bl_fail;
                 bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL);
@@ -1123,7 +1123,7 @@
                 }
         }
         if (!cp->intbufp) {
-                cp->intbufp = (char *) kmalloc (irqsize, GFP_KERNEL);
+                cp->intbufp = kmalloc (irqsize, GFP_KERNEL);
                 if (!cp->intbufp) {
                         ret = -ENOMEM;
                         goto intoend;
@@ -1696,7 +1696,7 @@
 	int ret;
 	wait_queue_t wait;
 
-        dbg ("auerchar_write %d bytes", len);
+        dbg ("auerchar_write %zd bytes", len);
 
 	/* Error checking */
 	if (!ccp)
@@ -2103,7 +2103,6 @@
 
 /* Standard usb driver struct */
 static struct usb_driver auerswald_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"auerswald",
 	.probe =	auerswald_probe,
 	.disconnect =	auerswald_disconnect,
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
index b33044d..6671317 100644
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -50,7 +50,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver cytherm_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cytherm",
 	.probe =	cytherm_probe,
 	.disconnect =	cytherm_disconnect,
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
index c815520..3824df3 100644
--- a/drivers/usb/misc/emi26.c
+++ b/drivers/usb/misc/emi26.c
@@ -227,7 +227,6 @@
 }
 
 static struct usb_driver emi26_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "emi26 - firmware loader",
 	.probe		= emi26_probe,
 	.disconnect	= emi26_disconnect,
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
index 189986a..52fea2e 100644
--- a/drivers/usb/misc/emi62.c
+++ b/drivers/usb/misc/emi62.c
@@ -266,7 +266,6 @@
 }
 
 static struct usb_driver emi62_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "emi62 - firmware loader",
 	.probe		= emi62_probe,
 	.disconnect	= emi62_disconnect,
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 1dc3e0f..d8cde10 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -114,7 +114,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver idmouse_driver = {
-	.owner = THIS_MODULE,
 	.name = DRIVER_SHORT,
 	.probe = idmouse_probe,
 	.disconnect = idmouse_disconnect,
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 7e93ac9..981d8a5 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -763,7 +763,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver ld_usb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ldusb",
 	.probe =	ld_usb_probe,
 	.disconnect =	ld_usb_disconnect,
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 2703e20..1336745 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -282,7 +282,6 @@
 
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver tower_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"legousbtower",
 	.probe =	tower_probe,
 	.disconnect =	tower_disconnect,
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index 067a814..605a3c8 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -555,7 +555,6 @@
 }
 
 static struct usb_driver interfacekit_driver = {
-	.owner = THIS_MODULE,
 	.name = "phidgetkit",
 	.probe = interfacekit_probe,
 	.disconnect = interfacekit_disconnect,
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
index a30d4a6..b3418d2 100644
--- a/drivers/usb/misc/phidgetservo.c
+++ b/drivers/usb/misc/phidgetservo.c
@@ -306,7 +306,6 @@
 }
 
 static struct usb_driver servo_driver = {
-	.owner = THIS_MODULE,
 	.name = "phidgetservo",
 	.probe = servo_probe,
 	.disconnect = servo_disconnect,
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 9590dba..384fa37 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -465,14 +465,14 @@
 
 	rio->rio_dev = dev;
 
-	if (!(rio->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) {
+	if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
 		err("probe_rio: Not enough memory for the output buffer");
 		usb_deregister_dev(intf, &usb_rio_class);
 		return -ENOMEM;
 	}
 	dbg("probe_rio: obuf address:%p", rio->obuf);
 
-	if (!(rio->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) {
+	if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) {
 		err("probe_rio: Not enough memory for the input buffer");
 		usb_deregister_dev(intf, &usb_rio_class);
 		kfree(rio->obuf);
@@ -522,7 +522,6 @@
 MODULE_DEVICE_TABLE (usb, rio_table);
 
 static struct usb_driver rio_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"rio500",
 	.probe =	probe_rio,
 	.disconnect =	disconnect_rio,
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 41ef2b6..3260d59 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -863,9 +863,6 @@
 
 	    switch (length) {
 
-		case 0:
-			return ret;
-
 		case 1:
 			if (userbuffer) {
 				if (get_user(swap8, (u8 __user *)userbuffer))
@@ -1221,9 +1218,6 @@
 
 	    switch (length) {
 
-		case 0:
-			return ret;
-
 		case 1:
 
 			ret |= sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM,
@@ -2443,8 +2437,8 @@
 	u8 *tempbuf;
 	u16 *tempbufb;
 	size_t written;
-	static char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
-	static char bootlogo[] = "(o_ //\\ V_/_";
+	static const char bootstring[] = "SiSUSB VGA text console, (C) 2005 Thomas Winischhofer.";
+	static const char bootlogo[] = "(o_ //\\ V_/_";
 
 	/* sisusb->lock is down */
 
@@ -3489,7 +3483,6 @@
 MODULE_DEVICE_TABLE (usb, sisusb_table);
 
 static struct usb_driver sisusb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"sisusb",
 	.probe =	sisusb_probe,
 	.disconnect =	sisusb_disconnect,
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index 85f3725..cc3dae3 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -371,7 +371,6 @@
 }
 
 static struct usb_driver lcd_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usblcd",
 	.probe =	lcd_probe,
 	.disconnect =	lcd_disconnect,
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c
index 3c93921..877b081 100644
--- a/drivers/usb/misc/usbled.c
+++ b/drivers/usb/misc/usbled.c
@@ -148,7 +148,6 @@
 }
 
 static struct usb_driver led_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbled",
 	.probe =	led_probe,
 	.disconnect =	led_disconnect,
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 605a2af..84fa172 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -2134,7 +2134,6 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver usbtest_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbtest",
 	.id_table =	id_table,
 	.probe =	usbtest_probe,
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index 1cabe7e..4081990 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -780,7 +780,6 @@
 
 
 static struct usb_driver uss720_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"uss720",
 	.probe =	uss720_probe,
 	.disconnect =	uss720_disconnect,
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index 17d0190..6116121 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -97,19 +97,12 @@
 	if (len >= DATA_MAX)
 		len = DATA_MAX;
 
-	/*
-	 * Bulk is easy to shortcut reliably. 
-	 * XXX Other pipe types need consideration. Currently, we overdo it
-	 * and collect garbage for them: better more than less.
-	 */
-	if (usb_pipebulk(pipe) || usb_pipecontrol(pipe)) {
-		if (usb_pipein(pipe)) {
-			if (ev_type == 'S')
-				return '<';
-		} else {
-			if (ev_type == 'C')
-				return '>';
-		}
+	if (usb_pipein(pipe)) {
+		if (ev_type == 'S')
+			return '<';
+	} else {
+		if (ev_type == 'C')
+			return '>';
 	}
 
 	/*
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index 542120e..5411816 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -912,13 +912,16 @@
 	// ASIX AX88772 10/100
         USB_DEVICE (0x0b95, 0x7720),
         .driver_info = (unsigned long) &ax88772_info,
+}, {
+	// Linksys USB200M Rev 2
+	USB_DEVICE (0x13b1, 0x0018),
+	.driver_info = (unsigned long) &ax88772_info,
 },
 	{ },		// END
 };
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver asix_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"asix",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
index 37ef365..be5f5e1 100644
--- a/drivers/usb/net/catc.c
+++ b/drivers/usb/net/catc.c
@@ -934,7 +934,6 @@
 MODULE_DEVICE_TABLE(usb, catc_id_table);
 
 static struct usb_driver catc_driver = {
-	.owner =	THIS_MODULE,
 	.name =		driver_name,
 	.probe =	catc_probe,
 	.disconnect =	catc_disconnect,
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c
index c008c98..63f1f3b 100644
--- a/drivers/usb/net/cdc_ether.c
+++ b/drivers/usb/net/cdc_ether.c
@@ -476,7 +476,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver cdc_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cdc_ether",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c
index f05cfb8..ec801e8 100644
--- a/drivers/usb/net/cdc_subset.c
+++ b/drivers/usb/net/cdc_subset.c
@@ -306,7 +306,6 @@
 /*-------------------------------------------------------------------------*/
 
 static struct usb_driver cdc_subset_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cdc_subset",
 	.probe =	usbnet_probe,
 	.suspend =	usbnet_suspend,
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c
index 2455e9a..faf1e86 100644
--- a/drivers/usb/net/gl620a.c
+++ b/drivers/usb/net/gl620a.c
@@ -377,7 +377,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver gl620a_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"gl620a",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
index b577651..def3bb8 100644
--- a/drivers/usb/net/kaweth.c
+++ b/drivers/usb/net/kaweth.c
@@ -175,7 +175,6 @@
  *     kaweth_driver
  ****************************************************************/
 static struct usb_driver kaweth_driver = {
-	.owner =	THIS_MODULE,
 	.name =		driver_name,
 	.probe =	kaweth_probe,
 	.disconnect =	kaweth_disconnect,
diff --git a/drivers/usb/net/net1080.c b/drivers/usb/net/net1080.c
index b3799b1..78e6a43 100644
--- a/drivers/usb/net/net1080.c
+++ b/drivers/usb/net/net1080.c
@@ -593,7 +593,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver net1080_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"net1080",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
index 683e3df..156a2f1 100644
--- a/drivers/usb/net/pegasus.c
+++ b/drivers/usb/net/pegasus.c
@@ -45,7 +45,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.6.12 (2005/01/13)"
+#define DRIVER_VERSION "v0.6.13 (2005/11/13)"
 #define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
 #define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
 
@@ -57,12 +57,14 @@
 
 static int loopback = 0;
 static int mii_mode = 0;
+static char *devid=NULL;
 
 static struct usb_eth_dev usb_dev_id[] = {
 #define	PEGASUS_DEV(pn, vid, pid, flags)	\
 	{.name = pn, .vendor = vid, .device = pid, .private = flags},
 #include "pegasus.h"
 #undef	PEGASUS_DEV
+	{NULL, 0, 0, 0},
 	{NULL, 0, 0, 0}
 };
 
@@ -71,6 +73,7 @@
 	{.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
 #include "pegasus.h"
 #undef	PEGASUS_DEV
+	{},
 	{}
 };
 
@@ -79,8 +82,10 @@
 MODULE_LICENSE("GPL");
 module_param(loopback, bool, 0);
 module_param(mii_mode, bool, 0);
+module_param(devid, charp, 0);
 MODULE_PARM_DESC(loopback, "Enable MAC loopback mode (bit 0)");
 MODULE_PARM_DESC(mii_mode, "Enable HomePNA mode (bit 0),default=MII mode = 0");
+MODULE_PARM_DESC(devid, "The format is: 'DEV_name:VendorID:DeviceID:Flags'");
 
 /* use ethtool to change the level for any given device */
 static int msg_level = -1;
@@ -113,7 +118,7 @@
 		break;
 	default:
 		if (netif_msg_drv(pegasus))
-			dev_err(&pegasus->intf->dev, "%s, status %d\n",
+			dev_dbg(&pegasus->intf->dev, "%s, status %d\n",
 				__FUNCTION__, urb->status);
 	}
 	pegasus->flags &= ~ETH_REGS_CHANGED;
@@ -308,9 +313,9 @@
 	__le16 regdi;
 	int ret;
 
-	ret = set_register(pegasus, PhyCtrl, 0);
-	ret = set_registers(pegasus, PhyAddr, sizeof (data), data);
-	ret = set_register(pegasus, PhyCtrl, (indx | PHY_READ));
+	set_register(pegasus, PhyCtrl, 0);
+	set_registers(pegasus, PhyAddr, sizeof (data), data);
+	set_register(pegasus, PhyCtrl, (indx | PHY_READ));
 	for (i = 0; i < REG_TIMEOUT; i++) {
 		ret = get_registers(pegasus, PhyCtrl, 1, data);
 		if (data[0] & PHY_DONE)
@@ -319,12 +324,12 @@
 	if (i < REG_TIMEOUT) {
 		ret = get_registers(pegasus, PhyData, 2, &regdi);
 		*regd = le16_to_cpu(regdi);
-		return 1;
+		return ret;
 	}
 	if (netif_msg_drv(pegasus))
 		dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
 
-	return 0;
+	return ret;
 }
 
 static int mdio_read(struct net_device *dev, int phy_id, int loc)
@@ -344,20 +349,20 @@
 
 	data[1] = (u8) regd;
 	data[2] = (u8) (regd >> 8);
-	ret = set_register(pegasus, PhyCtrl, 0);
-	ret = set_registers(pegasus, PhyAddr, sizeof(data), data);
-	ret = set_register(pegasus, PhyCtrl, (indx | PHY_WRITE));
+	set_register(pegasus, PhyCtrl, 0);
+	set_registers(pegasus, PhyAddr, sizeof(data), data);
+	set_register(pegasus, PhyCtrl, (indx | PHY_WRITE));
 	for (i = 0; i < REG_TIMEOUT; i++) {
 		ret = get_registers(pegasus, PhyCtrl, 1, data);
 		if (data[0] & PHY_DONE)
 			break;
 	}
 	if (i < REG_TIMEOUT)
-		return 0;
+		return ret;
 
 	if (netif_msg_drv(pegasus))
 		dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
-	return 1;
+	return -ETIMEDOUT;
 }
 
 static void mdio_write(struct net_device *dev, int phy_id, int loc, int val)
@@ -374,9 +379,9 @@
 	__le16 retdatai;
 	int ret;
 
-	ret = set_register(pegasus, EpromCtrl, 0);
-	ret = set_register(pegasus, EpromOffset, index);
-	ret = set_register(pegasus, EpromCtrl, EPROM_READ);
+	set_register(pegasus, EpromCtrl, 0);
+	set_register(pegasus, EpromOffset, index);
+	set_register(pegasus, EpromCtrl, EPROM_READ);
 
 	for (i = 0; i < REG_TIMEOUT; i++) {
 		ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
@@ -386,12 +391,12 @@
 	if (i < REG_TIMEOUT) {
 		ret = get_registers(pegasus, EpromData, 2, &retdatai);
 		*retdata = le16_to_cpu(retdatai);
-		return 0;
+		return ret;
 	}
 
 	if (netif_msg_drv(pegasus))
 		dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
-	return -1;
+	return -ETIMEDOUT;
 }
 
 #ifdef	PEGASUS_WRITE_EEPROM
@@ -400,8 +405,8 @@
 	__u8 tmp;
 	int ret;
 
-	ret = get_registers(pegasus, EthCtrl2, 1, &tmp);
-	ret = set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
+	get_registers(pegasus, EthCtrl2, 1, &tmp);
+	set_register(pegasus, EthCtrl2, tmp | EPROM_WR_ENABLE);
 }
 
 static inline void disable_eprom_write(pegasus_t * pegasus)
@@ -409,9 +414,9 @@
 	__u8 tmp;
 	int ret;
 
-	ret = get_registers(pegasus, EthCtrl2, 1, &tmp);
-	ret = set_register(pegasus, EpromCtrl, 0);
-	ret = set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
+	get_registers(pegasus, EthCtrl2, 1, &tmp);
+	set_register(pegasus, EpromCtrl, 0);
+	set_register(pegasus, EthCtrl2, tmp & ~EPROM_WR_ENABLE);
 }
 
 static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
@@ -420,11 +425,11 @@
 	__u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE };
 	int ret;
 
-	ret = set_registers(pegasus, EpromOffset, 4, d);
+	set_registers(pegasus, EpromOffset, 4, d);
 	enable_eprom_write(pegasus);
-	ret = set_register(pegasus, EpromOffset, index);
-	ret = set_registers(pegasus, EpromData, 2, &data);
-	ret = set_register(pegasus, EpromCtrl, EPROM_WRITE);
+	set_register(pegasus, EpromOffset, index);
+	set_registers(pegasus, EpromData, 2, &data);
+	set_register(pegasus, EpromCtrl, EPROM_WRITE);
 
 	for (i = 0; i < REG_TIMEOUT; i++) {
 		ret = get_registers(pegasus, EpromCtrl, 1, &tmp);
@@ -433,10 +438,10 @@
 	}
 	disable_eprom_write(pegasus);
 	if (i < REG_TIMEOUT)
-		return 0;
+		return ret;
 	if (netif_msg_drv(pegasus))
 		dev_warn(&pegasus->intf->dev, "fail %s\n", __FUNCTION__);
-	return -1;
+	return -ETIMEDOUT;
 }
 #endif				/* PEGASUS_WRITE_EEPROM */
 
@@ -454,10 +459,9 @@
 static void set_ethernet_addr(pegasus_t * pegasus)
 {
 	__u8 node_id[6];
-	int ret;
 
 	get_node_id(pegasus, node_id);
-	ret = set_registers(pegasus, EthID, sizeof (node_id), node_id);
+	set_registers(pegasus, EthID, sizeof (node_id), node_id);
 	memcpy(pegasus->net->dev_addr, node_id, sizeof (node_id));
 }
 
@@ -465,30 +469,29 @@
 {
 	__u8 data = 0x8;
 	int i;
-	int ret;
 
-	ret = set_register(pegasus, EthCtrl1, data);
+	set_register(pegasus, EthCtrl1, data);
 	for (i = 0; i < REG_TIMEOUT; i++) {
-		ret = get_registers(pegasus, EthCtrl1, 1, &data);
+		get_registers(pegasus, EthCtrl1, 1, &data);
 		if (~data & 0x08) {
 			if (loopback & 1)
 				break;
 			if (mii_mode && (pegasus->features & HAS_HOME_PNA))
-				ret = set_register(pegasus, Gpio1, 0x34);
+				set_register(pegasus, Gpio1, 0x34);
 			else
-				ret = set_register(pegasus, Gpio1, 0x26);
-			ret = set_register(pegasus, Gpio0, pegasus->features);
-			ret = set_register(pegasus, Gpio0, DEFAULT_GPIO_SET);
+				set_register(pegasus, Gpio1, 0x26);
+			set_register(pegasus, Gpio0, pegasus->features);
+			set_register(pegasus, Gpio0, DEFAULT_GPIO_SET);
 			break;
 		}
 	}
 	if (i == REG_TIMEOUT)
-		return 1;
+		return -ETIMEDOUT;
 
 	if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
 	    usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
-		ret = set_register(pegasus, Gpio0, 0x24);
-		ret = set_register(pegasus, Gpio0, 0x26);
+		set_register(pegasus, Gpio0, 0x24);
+		set_register(pegasus, Gpio0, 0x26);
 	}
 	if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
 		__u16 auxmode;
@@ -527,7 +530,7 @@
 		write_mii_word(pegasus, 0, 0x1b, auxmode | 4);
 	}
 
-	return 0;
+	return ret;
 }
 
 static void fill_skb_pool(pegasus_t * pegasus)
@@ -881,9 +884,8 @@
 static inline void disable_net_traffic(pegasus_t * pegasus)
 {
 	int tmp = 0;
-	int ret;
 
-	ret = set_registers(pegasus, EthCtrl0, 2, &tmp);
+	set_registers(pegasus, EthCtrl0, 2, &tmp);
 }
 
 static inline void get_interrupt_interval(pegasus_t * pegasus)
@@ -1206,18 +1208,17 @@
 static inline void setup_pegasus_II(pegasus_t * pegasus)
 {
 	__u8 data = 0xa5;
-	int ret;
 	
-	ret = set_register(pegasus, Reg1d, 0);
-	ret = set_register(pegasus, Reg7b, 1);
+	set_register(pegasus, Reg1d, 0);
+	set_register(pegasus, Reg7b, 1);
 	mdelay(100);
 	if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
-		ret = set_register(pegasus, Reg7b, 0);
+		set_register(pegasus, Reg7b, 0);
 	else
-		ret = set_register(pegasus, Reg7b, 2);
+		set_register(pegasus, Reg7b, 2);
 
-	ret = set_register(pegasus, 0x83, data);
-	ret = get_registers(pegasus, 0x83, 1, &data);
+	set_register(pegasus, 0x83, data);
+	get_registers(pegasus, 0x83, 1, &data);
 
 	if (data == 0xa5) {
 		pegasus->chip = 0x8513;
@@ -1225,14 +1226,14 @@
 		pegasus->chip = 0;
 	}
 
-	ret = set_register(pegasus, 0x80, 0xc0);
-	ret = set_register(pegasus, 0x83, 0xff);
-	ret = set_register(pegasus, 0x84, 0x01);
+	set_register(pegasus, 0x80, 0xc0);
+	set_register(pegasus, 0x83, 0xff);
+	set_register(pegasus, 0x84, 0x01);
 	
 	if (pegasus->features & HAS_HOME_PNA && mii_mode)
-		ret = set_register(pegasus, Reg81, 6);
+		set_register(pegasus, Reg81, 6);
 	else
-		ret = set_register(pegasus, Reg81, 2);
+		set_register(pegasus, Reg81, 2);
 }
 
 
@@ -1414,9 +1415,42 @@
 	.resume = pegasus_resume,
 };
 
+static void parse_id(char *id)
+{
+	unsigned int vendor_id=0, device_id=0, flags=0, i=0;
+	char *token, *name=NULL;
+
+	if ((token = strsep(&id, ":")) != NULL)
+		name = token;
+	/* name now points to a null terminated string*/
+	if ((token = strsep(&id, ":")) != NULL)
+		vendor_id = simple_strtoul(token, NULL, 16);
+	if ((token = strsep(&id, ":")) != NULL)
+		device_id = simple_strtoul(token, NULL, 16);
+	flags = simple_strtoul(id, NULL, 16);
+	pr_info("%s: new device %s, vendor ID 0x%04x, device ID 0x%04x, flags: 0x%x\n",
+	        driver_name, name, vendor_id, device_id, flags);
+
+	if (vendor_id > 0x10000 || vendor_id == 0)
+		return;
+	if (device_id > 0x10000 || device_id == 0)
+		return;
+
+	for (i=0; usb_dev_id[i].name; i++);
+	usb_dev_id[i].name = name;
+	usb_dev_id[i].vendor = vendor_id;
+	usb_dev_id[i].device = device_id;
+	usb_dev_id[i].private = flags;
+	pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+	pegasus_ids[i].idVendor = vendor_id;
+	pegasus_ids[i].idProduct = device_id;
+}
+
 static int __init pegasus_init(void)
 {
 	pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION);
+	if (devid)
+		parse_id(devid);
 	pegasus_workqueue = create_singlethread_workqueue("pegasus");
 	if (!pegasus_workqueue)
 		return -ENOMEM;
diff --git a/drivers/usb/net/plusb.c b/drivers/usb/net/plusb.c
index 89856aa..4fe8633 100644
--- a/drivers/usb/net/plusb.c
+++ b/drivers/usb/net/plusb.c
@@ -127,7 +127,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver plusb_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"plusb",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c
index c0ecbab..49991ac 100644
--- a/drivers/usb/net/rndis_host.c
+++ b/drivers/usb/net/rndis_host.c
@@ -586,7 +586,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver rndis_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"rndis_host",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index 787dd35..8ca52be 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -177,7 +177,6 @@
 static const char driver_name [] = "rtl8150";
 
 static struct usb_driver rtl8150_driver = {
-	.owner =	THIS_MODULE,
 	.name =		driver_name,
 	.probe =	rtl8150_probe,
 	.disconnect =	rtl8150_disconnect,
diff --git a/drivers/usb/net/zaurus.c b/drivers/usb/net/zaurus.c
index 680d139..9c5ab25 100644
--- a/drivers/usb/net/zaurus.c
+++ b/drivers/usb/net/zaurus.c
@@ -357,7 +357,6 @@
 MODULE_DEVICE_TABLE(usb, products);
 
 static struct usb_driver zaurus_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"zaurus",
 	.id_table =	products,
 	.probe =	usbnet_probe,
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c
index 2f52261..f3a8e28 100644
--- a/drivers/usb/net/zd1201.c
+++ b/drivers/usb/net/zd1201.c
@@ -1722,7 +1722,7 @@
 	    IW_PRIV_TYPE_NONE, "sethostauth" },
 	{ ZD1201GIWHOSTAUTH, IW_PRIV_TYPE_NONE,
 	    IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "gethostauth" },
-	{ ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1, 
+	{ ZD1201SIWAUTHSTA, IW_PRIV_TYPE_ADDR | IW_PRIV_SIZE_FIXED | 1,
 	    IW_PRIV_TYPE_NONE, "authstation" },
 	{ ZD1201SIWMAXASSOC, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 	    IW_PRIV_TYPE_NONE, "setmaxassoc" },
@@ -1731,9 +1731,9 @@
 };
 
 static const struct iw_handler_def zd1201_iw_handlers = {
-	.num_standard 		= sizeof(zd1201_iw_handler)/sizeof(iw_handler),
-	.num_private 		= sizeof(zd1201_private_handler)/sizeof(iw_handler),
-	.num_private_args 	= sizeof(zd1201_private_args)/sizeof(struct iw_priv_args),
+	.num_standard 		= ARRAY_SIZE(zd1201_iw_handler),
+	.num_private 		= ARRAY_SIZE(zd1201_private_handler),
+	.num_private_args 	= ARRAY_SIZE(zd1201_private_args),
 	.standard 		= (iw_handler *)zd1201_iw_handler,
 	.private 		= (iw_handler *)zd1201_private_handler,
 	.private_args 		= (struct iw_priv_args *) zd1201_private_args,
@@ -1829,6 +1829,8 @@
 	if (err)
 		goto err_net;
 
+	SET_NETDEV_DEV(zd->dev, &usb->dev);
+
 	err = register_netdev(zd->dev);
 	if (err)
 		goto err_net;
@@ -1923,7 +1925,6 @@
 #endif
 
 static struct usb_driver zd1201_usb = {
-	.owner = THIS_MODULE,
 	.name = "zd1201",
 	.probe = zd1201_probe,
 	.disconnect = zd1201_disconnect,
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 1f29d88..dbf1f063 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -23,11 +23,11 @@
 MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver airprime_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"airprime",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver airprime_device = {
diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c
index 18022a7..343f6f2 100644
--- a/drivers/usb/serial/anydata.c
+++ b/drivers/usb/serial/anydata.c
@@ -27,11 +27,11 @@
 static int debug;
 
 static struct usb_driver anydata_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"anydata",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static int anydata_open(struct usb_serial_port *port, struct file *filp)
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 84bc0ee..4144777 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -113,11 +113,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver belkin_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"belkin",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* All of the device info needed for the serial converters */
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index c978700..da46b35 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -67,11 +67,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver cp2101_driver = {
-	.owner		= THIS_MODULE,
 	.name		= "cp2101",
 	.probe		= usb_serial_probe,
 	.disconnect	= usb_serial_disconnect,
 	.id_table	= id_table,
+	.no_dynamic_id	= 	1,
 };
 
 static struct usb_serial_driver cp2101_device = {
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index e581e4a..6d18d4e 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -76,11 +76,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver cyberjack_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"cyberjack",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver cyberjack_device = {
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index af9290e..af18355 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -112,6 +112,7 @@
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 struct cypress_private {
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index dc74644..8fc414b 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -493,11 +493,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver digi_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"digi_acceleport",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 0b0546d..79a766e 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -105,11 +105,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver empeg_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"empeg",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver empeg_device = {
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 06e04b4..eb863b3 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -471,12 +471,15 @@
 	{ USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) },
 	{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16HR_PID) },
 	{ USB_DEVICE(KOBIL_VID, KOBIL_CONV_B1_PID) },
 	{ USB_DEVICE(KOBIL_VID, KOBIL_CONV_KAAN_PID) },
+	{ USB_DEVICE(POSIFLEX_VID, POSIFLEX_PP7000_PID) },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
@@ -488,9 +491,10 @@
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
-static char *ftdi_chip_name[] = {
+static const char *ftdi_chip_name[] = {
 	[SIO] = "SIO",	/* the serial part of FT8U100AX */
 	[FT8U232AM] = "FT8U232AM",
 	[FT232BM] = "FT232BM",
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 773ea3e..00d45f8 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -343,6 +343,13 @@
 #define XSENS_CONVERTER_7_PID	0xD38F
 
 /*
+ * Teratronik product ids.
+ * Submitted by O. Wölfelschneider.
+ */
+#define FTDI_TERATRONIK_VCP_PID	 0xEC88	/* Teratronik device (preferring VCP driver on windows) */
+#define FTDI_TERATRONIK_D2XX_PID 0xEC89	/* Teratronik device (preferring D2XX driver on windows) */
+
+/*
  * Evolution Robotics products (http://www.evolution.com/).
  * Submitted by Shawn M. Lavelle.
  */
@@ -352,6 +359,12 @@
 /* Pyramid Computer GmbH */
 #define FTDI_PYRAMID_PID	0xE6C8	/* Pyramid Appliance Display */
 
+/*
+ * Posiflex inc retail equipment (http://www.posiflex.com.tw)
+ */
+#define POSIFLEX_VID		0x0d3a  /* Vendor ID */
+#define POSIFLEX_PP7000_PID	0x0300  /* PP-7000II thermal printer */
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
@@ -714,7 +727,7 @@
  */
 
 /* FTDI_SIO_GET_MODEM_STATUS */
-/* Retreive the current value of the modem status register */
+/* Retrieve the current value of the modem status register */
 
 #define FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE 0xc0
 #define FTDI_SIO_GET_MODEM_STATUS_REQUEST FTDI_SIO_GET_MODEM_STATUS
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 35820bd..452efce 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -222,11 +222,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver garmin_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"garmin_gps",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 53a47c3..4ddac62 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -68,11 +68,11 @@
 }
 
 static struct usb_driver generic_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbserial_generic",
 	.probe =	generic_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	generic_serial_ids,
+	.no_dynamic_id = 	1,
 };
 #endif
 
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c
index 8eadfb7..e9719da 100644
--- a/drivers/usb/serial/hp4x.c
+++ b/drivers/usb/serial/hp4x.c
@@ -37,11 +37,11 @@
 MODULE_DEVICE_TABLE(usb, id_table);
 
 static struct usb_driver hp49gp_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"hp4X",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver hp49gp_device = {
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index dc4c498..faedbeb 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -184,7 +184,7 @@
 // These assume a 3.6864MHz crystal, the standard /16, and
 // MCR.7 = 0.
 //
-static struct divisor_table_entry divisor_table[] = {
+static const struct divisor_table_entry divisor_table[] = {
 	{   50,		4608},  
 	{   75,		3072},  
 	{   110,	2095},		/* 2094.545455 => 230450   => .0217 % over */
@@ -242,11 +242,11 @@
 #include "io_tables.h"	/* all of the devices that this driver supports */
 
 static struct usb_driver io_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"io_edgeport",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* function prototypes for all of our local functions */
@@ -2353,7 +2353,7 @@
 
 	dbg("%s - %d", __FUNCTION__, baudrate);
 
-	for (i = 0; i < NUM_ENTRIES(divisor_table); i++) {
+	for (i = 0; i < ARRAY_SIZE(divisor_table); i++) {
 		if ( divisor_table[i].BaudRate == baudrate ) {
 			*divisor = divisor_table[i].Divisor;
 			return 0;
diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h
index 5112d7a..123fa8a 100644
--- a/drivers/usb/serial/io_edgeport.h
+++ b/drivers/usb/serial/io_edgeport.h
@@ -31,9 +31,6 @@
 #ifndef HIGH8
 	#define HIGH8(a)	((unsigned char)((a & 0xff00) >> 8))
 #endif
-#ifndef NUM_ENTRIES
-	#define NUM_ENTRIES(x)	(sizeof(x)/sizeof((x)[0]))
-#endif
 
 #ifndef __KERNEL__
 #define __KERNEL__
diff --git a/drivers/usb/serial/io_fw_boot2.h b/drivers/usb/serial/io_fw_boot2.h
index c7c3a3c..e3463de 100644
--- a/drivers/usb/serial/io_fw_boot2.h
+++ b/drivers/usb/serial/io_fw_boot2.h
@@ -537,7 +537,7 @@
 
 };
 
-static struct edge_firmware_version_info IMAGE_VERSION_NAME = {
+static const struct edge_firmware_version_info IMAGE_VERSION_NAME = {
 	2, 0, 3 };		// Major, Minor, Build
 
 #undef IMAGE_VERSION_NAME
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 832b6d6..2edf9cab 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -216,11 +216,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver io_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"io_ti",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 
@@ -2843,7 +2843,7 @@
  * Free the buffer and all associated memory.
  */
 
-void edge_buf_free(struct edge_buf *eb)
+static void edge_buf_free(struct edge_buf *eb)
 {
 	if (eb) {
 		kfree(eb->buf_buf);
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index d5d0664..06d07ce 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -542,11 +542,11 @@
 MODULE_DEVICE_TABLE (usb, ipaq_id_table);
 
 static struct usb_driver ipaq_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ipaq",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	ipaq_id_table,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 7744b81..2dd191f 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -152,11 +152,11 @@
 MODULE_DEVICE_TABLE(usb, usb_ipw_ids);
 
 static struct usb_driver usb_ipw_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ipwtty",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	usb_ipw_ids,
+	.no_dynamic_id = 	1,
 };
 
 static int debug;
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 19f329e..a590104 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -125,11 +125,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver ir_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"ir-usb",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 5cfc13b..7472ed6 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -520,11 +520,11 @@
 MODULE_DEVICE_TABLE(usb, keyspan_ids_combined);
 
 static struct usb_driver keyspan_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"keyspan",                
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	keyspan_ids_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* usb_device_id table for the pre-firmware download keyspan devices */
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index cd4f48b..b0441c3 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -150,11 +150,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver keyspan_pda_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"keyspan_pda",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_device_id id_table_std [] = {
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index a8951c0..4e2f7df 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -116,11 +116,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver kl5kusb105d_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"kl5kusb105d",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver kl5kusb105d_device = {
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 9456dd9..d9c21e2 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -97,11 +97,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver kobil_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"kobil",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index ca5dbad..b6d6cab 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -125,11 +125,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver mct_u232_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"mct_u232",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver mct_u232_device = {
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 3caf970..762d8ff 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -80,11 +80,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver omninet_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"omninet",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 7716000..3fd2405 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -95,11 +95,11 @@
 MODULE_DEVICE_TABLE(usb, option_ids);
 
 static struct usb_driver option_driver = {
-	.owner      = THIS_MODULE,
 	.name       = "option",
 	.probe      = usb_serial_probe,
 	.disconnect = usb_serial_disconnect,
 	.id_table   = option_ids,
+	.no_dynamic_id = 	1,
 };
 
 /* The card has three separate interfaces, wich the serial driver
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 41a45a5..f037210 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -82,11 +82,11 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver pl2303_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"pl2303",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
 #define SET_LINE_REQUEST_TYPE		0x21
@@ -810,7 +810,7 @@
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 	u8 status_idx = UART_STATE;
-	u8 length = UART_STATE;
+	u8 length = UART_STATE + 1;
 
 	if ((le16_to_cpu(port->serial->dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
 	    (le16_to_cpu(port->serial->dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_X65 ||
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index c22bdc0..f0215f8 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -160,14 +160,14 @@
 MODULE_DEVICE_TABLE (usb, id_table);
 
 static struct usb_driver safe_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"safe_serial",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table,
+	.no_dynamic_id = 	1,
 };
 
-static __u16 crc10_table[256] = {
+static const __u16 crc10_table[256] = {
 	0x000, 0x233, 0x255, 0x066, 0x299, 0x0aa, 0x0cc, 0x2ff, 0x301, 0x132, 0x154, 0x367, 0x198, 0x3ab, 0x3cd, 0x1fe,
 	0x031, 0x202, 0x264, 0x057, 0x2a8, 0x09b, 0x0fd, 0x2ce, 0x330, 0x103, 0x165, 0x356, 0x1a9, 0x39a, 0x3fc, 0x1cf,
 	0x062, 0x251, 0x237, 0x004, 0x2fb, 0x0c8, 0x0ae, 0x29d, 0x363, 0x150, 0x136, 0x305, 0x1fa, 0x3c9, 0x3af, 0x19c,
@@ -425,7 +425,7 @@
 	if (vendor || product) {
 		info ("vendor: %x product: %x\n", vendor, product);
 
-		for (i = 0; i < (sizeof (id_table) / sizeof (struct usb_device_id)); i++) {
+		for (i = 0; i < ARRAY_SIZE(id_table); i++) {
 			if (!id_table[i].idVendor && !id_table[i].idProduct) {
 				id_table[i].idVendor = vendor;
 				id_table[i].idProduct = product;
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 205dbf7..abb830c 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -248,11 +248,11 @@
 };
 
 static struct usb_driver ti_usb_driver = {
-	.owner			= THIS_MODULE,
 	.name			= "ti_usb_3410_5052",
 	.probe			= usb_serial_probe,
 	.disconnect		= usb_serial_disconnect,
 	.id_table		= ti_id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 static struct usb_serial_driver ti_1port_device = {
@@ -351,17 +351,14 @@
 	int i,j;
 	int ret;
 
-
 	/* insert extra vendor and product ids */
-	j = sizeof(ti_id_table_3410)/sizeof(struct usb_device_id)
-		- TI_EXTRA_VID_PID_COUNT - 1;
+	j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1;
 	for (i=0; i<min(vendor_3410_count,product_3410_count); i++,j++) {
 		ti_id_table_3410[j].idVendor = vendor_3410[i];
 		ti_id_table_3410[j].idProduct = product_3410[i];
 		ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
 	}
-	j = sizeof(ti_id_table_5052)/sizeof(struct usb_device_id)
-		- TI_EXTRA_VID_PID_COUNT - 1;
+	j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1;
 	for (i=0; i<min(vendor_5052_count,product_5052_count); i++,j++) {
 		ti_id_table_5052[j].idVendor = vendor_5052[i];
 		ti_id_table_5052[j].idProduct = product_5052[i];
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 0c4881d..8bc8337 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -30,6 +30,7 @@
 #include <linux/list.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
+#include <asm/semaphore.h>
 #include <linux/usb.h>
 #include "usb-serial.h"
 #include "pl2303.h"
@@ -42,10 +43,10 @@
 
 /* Driver structure we register with the USB core */
 static struct usb_driver usb_serial_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usbserial",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
+	.no_dynamic_id = 	1,
 };
 
 /* There is no MODULE_DEVICE_TABLE for usbserial.c.  Instead
@@ -188,6 +189,11 @@
 
 	portNumber = tty->index - serial->minor;
 	port = serial->port[portNumber];
+	if (!port)
+		return -ENODEV;
+
+	if (down_interruptible(&port->sem))
+		return -ERESTARTSYS;
 	 
 	++port->open_count;
 
@@ -213,6 +219,7 @@
 			goto bailout_module_put;
 	}
 
+	up(&port->sem);
 	return 0;
 
 bailout_module_put:
@@ -220,6 +227,7 @@
 bailout_kref_put:
 	kref_put(&serial->kref, destroy_serial);
 	port->open_count = 0;
+	up(&port->sem);
 	return retval;
 }
 
@@ -232,8 +240,10 @@
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
+	down(&port->sem);
+
 	if (port->open_count == 0)
-		return;
+		goto out;
 
 	--port->open_count;
 	if (port->open_count == 0) {
@@ -251,6 +261,9 @@
 	}
 
 	kref_put(&port->serial->kref, destroy_serial);
+
+out:
+	up(&port->sem);
 }
 
 static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count)
@@ -258,6 +271,9 @@
 	struct usb_serial_port *port = tty->driver_data;
 	int retval = -EINVAL;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count);
 
 	if (!port->open_count) {
@@ -277,6 +293,9 @@
 	struct usb_serial_port *port = tty->driver_data;
 	int retval = -EINVAL;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -296,6 +315,9 @@
 	struct usb_serial_port *port = tty->driver_data;
 	int retval = -EINVAL;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s = port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -314,6 +336,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		return;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -330,6 +355,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		return;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -347,6 +375,9 @@
 	struct usb_serial_port *port = tty->driver_data;
 	int retval = -ENODEV;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d, cmd 0x%.4x", __FUNCTION__, port->number, cmd);
 
 	if (!port->open_count) {
@@ -368,6 +399,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		return;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -384,6 +418,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		return;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -445,6 +482,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -464,6 +504,9 @@
 {
 	struct usb_serial_port *port = tty->driver_data;
 
+	if (!port)
+		goto exit;
+
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (!port->open_count) {
@@ -742,6 +785,7 @@
 		port->number = i + serial->minor;
 		port->serial = serial;
 		spin_lock_init(&port->lock);
+		sema_init(&port->sem, 1);
 		INIT_WORK(&port->work, usb_serial_port_softint, port);
 		serial->port[i] = port;
 	}
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
index 238a5a8..d7d27c3 100644
--- a/drivers/usb/serial/usb-serial.h
+++ b/drivers/usb/serial/usb-serial.h
@@ -16,6 +16,7 @@
 
 #include <linux/config.h>
 #include <linux/kref.h>
+#include <asm/semaphore.h>
 
 #define SERIAL_TTY_MAJOR	188	/* Nice legal number now */
 #define SERIAL_TTY_MINORS	255	/* loads of devices :) */
@@ -30,6 +31,8 @@
  * @serial: pointer back to the struct usb_serial owner of this port.
  * @tty: pointer to the corresponding tty for this port.
  * @lock: spinlock to grab when updating portions of this structure.
+ * @sem: semaphore used to synchronize serial_open() and serial_close()
+ *	access for this port.
  * @number: the number of the port (the minor number).
  * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
  * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
@@ -60,6 +63,7 @@
 	struct usb_serial *	serial;
 	struct tty_struct *	tty;
 	spinlock_t		lock;
+	struct semaphore        sem;
 	unsigned char		number;
 
 	unsigned char *		interrupt_in_buffer;
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index a473c1c..49b1fbe 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -173,11 +173,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver visor_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"visor",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 18c3183..a7c3c47 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -127,11 +127,11 @@
 MODULE_DEVICE_TABLE (usb, id_table_combined);
 
 static struct usb_driver whiteheat_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"whiteheat",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
 	.id_table =	id_table_combined,
+	.no_dynamic_id = 	1,
 };
 
 /* function prototypes for the Connect Tech WhiteHEAT prerenumeration device */
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index c41d64d..92be101 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -112,6 +112,15 @@
 	  Say Y here to include additional code to support the Lexar Jumpshot
 	  USB CompactFlash reader.
 
+config USB_STORAGE_ALAUDA
+	bool "Olympus MAUSB-10/Fuji DPC-R1 support (EXPERIMENTAL)"
+	depends on USB_STORAGE && EXPERIMENTAL
+	help
+	  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
+	  XD and SmartMedia cards.
 
 config USB_STORAGE_ONETOUCH
 	bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)"
@@ -124,3 +133,17 @@
 	  hard drive's as an input device. An action can be associated with
 	  this input in any keybinding software. (e.g. gnome's keyboard short-
 	  cuts)
+
+config USB_LIBUSUAL
+	bool "The shared table of common (or usual) storage devices"
+	depends on USB
+	help
+	  This module contains a table of common (or usual) devices
+	  for usb-storage and ub drivers, and allows to switch binding
+	  of these devices without rebuilding modules.
+
+	  Typical syntax of /etc/modprobe.conf is:
+
+		options libusual bias="ub"
+
+	  If unsure, say N.
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index 44ab8f9..8cbba22 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -18,7 +18,12 @@
 usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200)	+= isd200.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB)	+= datafab.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT)	+= jumpshot.o
+usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA)	+= alauda.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH)	+= onetouch.o
 
 usb-storage-objs :=	scsiglue.o protocol.o transport.o usb.o \
 			initializers.o $(usb-storage-obj-y)
+
+ifneq ($(CONFIG_USB_LIBUSUAL),)
+	obj-$(CONFIG_USB)	+= libusual.o
+endif
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
new file mode 100644
index 0000000..4d3cbb1
--- /dev/null
+++ b/drivers/usb/storage/alauda.c
@@ -0,0 +1,1119 @@
+/*
+ * Driver for Alauda-based card readers
+ *
+ * Current development and maintenance by:
+ *   (c) 2005 Daniel Drake <dsd@gentoo.org>
+ *
+ * The 'Alauda' is a chip manufacturered by RATOC for OEM use.
+ *
+ * Alauda implements a vendor-specific command set to access two media reader
+ * ports (XD, SmartMedia). This driver converts SCSI commands to the commands
+ * which are accepted by these devices.
+ *
+ * The driver was developed through reverse-engineering, with the help of the
+ * sddr09 driver which has many similarities, and with some help from the
+ * (very old) vendor-supplied GPL sma03 driver.
+ *
+ * For protocol info, see http://alauda.sourceforge.net
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, 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 <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+
+#include "usb.h"
+#include "transport.h"
+#include "protocol.h"
+#include "debug.h"
+#include "alauda.h"
+
+#define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) )
+#define LSB_of(s) ((s)&0xFF)
+#define MSB_of(s) ((s)>>8)
+
+#define MEDIA_PORT(us) us->srb->device->lun
+#define MEDIA_INFO(us) ((struct alauda_info *)us->extra)->port[MEDIA_PORT(us)]
+
+#define PBA_LO(pba) ((pba & 0xF) << 5)
+#define PBA_HI(pba) (pba >> 3)
+#define PBA_ZONE(pba) (pba >> 11)
+
+/*
+ * Media handling
+ */
+
+struct alauda_card_info {
+	unsigned char id;		/* id byte */
+	unsigned char chipshift;	/* 1<<cs bytes total capacity */
+	unsigned char pageshift;	/* 1<<ps bytes in a page */
+	unsigned char blockshift;	/* 1<<bs pages per block */
+	unsigned char zoneshift;	/* 1<<zs blocks per zone */
+};
+
+static struct alauda_card_info alauda_card_ids[] = {
+	/* NAND flash */
+	{ 0x6e, 20, 8, 4, 8},	/* 1 MB */
+	{ 0xe8, 20, 8, 4, 8},	/* 1 MB */
+	{ 0xec, 20, 8, 4, 8},	/* 1 MB */
+	{ 0x64, 21, 8, 4, 9}, 	/* 2 MB */
+	{ 0xea, 21, 8, 4, 9},	/* 2 MB */
+	{ 0x6b, 22, 9, 4, 9},	/* 4 MB */
+	{ 0xe3, 22, 9, 4, 9},	/* 4 MB */
+	{ 0xe5, 22, 9, 4, 9},	/* 4 MB */
+	{ 0xe6, 23, 9, 4, 10},	/* 8 MB */
+	{ 0x73, 24, 9, 5, 10},	/* 16 MB */
+	{ 0x75, 25, 9, 5, 10},	/* 32 MB */
+	{ 0x76, 26, 9, 5, 10},	/* 64 MB */
+	{ 0x79, 27, 9, 5, 10},	/* 128 MB */
+	{ 0x71, 28, 9, 5, 10},	/* 256 MB */
+
+	/* MASK ROM */
+	{ 0x5d, 21, 9, 4, 8},	/* 2 MB */
+	{ 0xd5, 22, 9, 4, 9},	/* 4 MB */
+	{ 0xd6, 23, 9, 4, 10},	/* 8 MB */
+	{ 0x57, 24, 9, 4, 11},	/* 16 MB */
+	{ 0x58, 25, 9, 4, 12},	/* 32 MB */
+	{ 0,}
+};
+
+static struct alauda_card_info *alauda_card_find_id(unsigned char id) {
+	int i;
+
+	for (i = 0; alauda_card_ids[i].id != 0; i++)
+		if (alauda_card_ids[i].id == id)
+			return &(alauda_card_ids[i]);
+	return NULL;
+}
+
+/*
+ * ECC computation.
+ */
+
+static unsigned char parity[256];
+static unsigned char ecc2[256];
+
+static void nand_init_ecc(void) {
+	int i, j, a;
+
+	parity[0] = 0;
+	for (i = 1; i < 256; i++)
+		parity[i] = (parity[i&(i-1)] ^ 1);
+
+	for (i = 0; i < 256; i++) {
+		a = 0;
+		for (j = 0; j < 8; j++) {
+			if (i & (1<<j)) {
+				if ((j & 1) == 0)
+					a ^= 0x04;
+				if ((j & 2) == 0)
+					a ^= 0x10;
+				if ((j & 4) == 0)
+					a ^= 0x40;
+			}
+		}
+		ecc2[i] = ~(a ^ (a<<1) ^ (parity[i] ? 0xa8 : 0));
+	}
+}
+
+/* compute 3-byte ecc on 256 bytes */
+static void nand_compute_ecc(unsigned char *data, unsigned char *ecc) {
+	int i, j, a;
+	unsigned char par, bit, bits[8];
+
+	par = 0;
+	for (j = 0; j < 8; j++)
+		bits[j] = 0;
+
+	/* collect 16 checksum bits */
+	for (i = 0; i < 256; i++) {
+		par ^= data[i];
+		bit = parity[data[i]];
+		for (j = 0; j < 8; j++)
+			if ((i & (1<<j)) == 0)
+				bits[j] ^= bit;
+	}
+
+	/* put 4+4+4 = 12 bits in the ecc */
+	a = (bits[3] << 6) + (bits[2] << 4) + (bits[1] << 2) + bits[0];
+	ecc[0] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0));
+
+	a = (bits[7] << 6) + (bits[6] << 4) + (bits[5] << 2) + bits[4];
+	ecc[1] = ~(a ^ (a<<1) ^ (parity[par] ? 0xaa : 0));
+
+	ecc[2] = ecc2[par];
+}
+
+static int nand_compare_ecc(unsigned char *data, unsigned char *ecc) {
+	return (data[0] == ecc[0] && data[1] == ecc[1] && data[2] == ecc[2]);
+}
+
+static void nand_store_ecc(unsigned char *data, unsigned char *ecc) {
+	memcpy(data, ecc, 3);
+}
+
+/*
+ * Alauda driver
+ */
+
+/*
+ * Forget our PBA <---> LBA mappings for a particular port
+ */
+static void alauda_free_maps (struct alauda_media_info *media_info)
+{
+	unsigned int shift = media_info->zoneshift
+		+ media_info->blockshift + media_info->pageshift;
+	unsigned int num_zones = media_info->capacity >> shift;
+	unsigned int i;
+
+	if (media_info->lba_to_pba != NULL)
+		for (i = 0; i < num_zones; i++) {
+			kfree(media_info->lba_to_pba[i]);
+			media_info->lba_to_pba[i] = NULL;
+		}
+
+	if (media_info->pba_to_lba != NULL)
+		for (i = 0; i < num_zones; i++) {
+			kfree(media_info->pba_to_lba[i]);
+			media_info->pba_to_lba[i] = NULL;
+		}
+}
+
+/*
+ * Returns 2 bytes of status data
+ * The first byte describes media status, and second byte describes door status
+ */
+static int alauda_get_media_status(struct us_data *us, unsigned char *data)
+{
+	int rc;
+	unsigned char command;
+
+	if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
+		command = ALAUDA_GET_XD_MEDIA_STATUS;
+	else
+		command = ALAUDA_GET_SM_MEDIA_STATUS;
+
+	rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
+		command, 0xc0, 0, 1, data, 2);
+
+	US_DEBUGP("alauda_get_media_status: Media status %02X %02X\n",
+		data[0], data[1]);
+
+	return rc;
+}
+
+/*
+ * Clears the "media was changed" bit so that we know when it changes again
+ * in the future.
+ */
+static int alauda_ack_media(struct us_data *us)
+{
+	unsigned char command;
+
+	if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
+		command = ALAUDA_ACK_XD_MEDIA_CHANGE;
+	else
+		command = ALAUDA_ACK_SM_MEDIA_CHANGE;
+
+	return usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
+		command, 0x40, 0, 1, NULL, 0);
+}
+
+/*
+ * Retrieves a 4-byte media signature, which indicates manufacturer, capacity,
+ * and some other details.
+ */
+static int alauda_get_media_signature(struct us_data *us, unsigned char *data)
+{
+	unsigned char command;
+
+	if (MEDIA_PORT(us) == ALAUDA_PORT_XD)
+		command = ALAUDA_GET_XD_MEDIA_SIG;
+	else
+		command = ALAUDA_GET_SM_MEDIA_SIG;
+
+	return usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe,
+		command, 0xc0, 0, 0, data, 4);
+}
+
+/*
+ * Resets the media status (but not the whole device?)
+ */
+static int alauda_reset_media(struct us_data *us)
+{
+	unsigned char *command = us->iobuf;
+
+	memset(command, 0, 9);
+	command[0] = ALAUDA_BULK_CMD;
+	command[1] = ALAUDA_BULK_RESET_MEDIA;
+	command[8] = MEDIA_PORT(us);
+
+	return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+}
+
+/*
+ * Examines the media and deduces capacity, etc.
+ */
+static int alauda_init_media(struct us_data *us)
+{
+	unsigned char *data = us->iobuf;
+	int ready = 0;
+	struct alauda_card_info *media_info;
+	unsigned int num_zones;
+
+	while (ready == 0) {
+		msleep(20);
+
+		if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD)
+			return USB_STOR_TRANSPORT_ERROR;
+
+		if (data[0] & 0x10)
+			ready = 1;
+	}
+
+	US_DEBUGP("alauda_init_media: We are ready for action!\n");
+
+	if (alauda_ack_media(us) != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
+
+	msleep(10);
+
+	if (alauda_get_media_status(us, data) != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
+
+	if (data[0] != 0x14) {
+		US_DEBUGP("alauda_init_media: Media not ready after ack\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	if (alauda_get_media_signature(us, data) != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
+
+	US_DEBUGP("alauda_init_media: Media signature: %02X %02X %02X %02X\n",
+		data[0], data[1], data[2], data[3]);
+	media_info = alauda_card_find_id(data[1]);
+	if (media_info == NULL) {
+		printk("alauda_init_media: Unrecognised media signature: "
+			"%02X %02X %02X %02X\n",
+			data[0], data[1], data[2], data[3]);
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	MEDIA_INFO(us).capacity = 1 << media_info->chipshift;
+	US_DEBUGP("Found media with capacity: %ldMB\n",
+		MEDIA_INFO(us).capacity >> 20);
+
+	MEDIA_INFO(us).pageshift = media_info->pageshift;
+	MEDIA_INFO(us).blockshift = media_info->blockshift;
+	MEDIA_INFO(us).zoneshift = media_info->zoneshift;
+
+	MEDIA_INFO(us).pagesize = 1 << media_info->pageshift;
+	MEDIA_INFO(us).blocksize = 1 << media_info->blockshift;
+	MEDIA_INFO(us).zonesize = 1 << media_info->zoneshift;
+
+	MEDIA_INFO(us).uzonesize = ((1 << media_info->zoneshift) / 128) * 125;
+	MEDIA_INFO(us).blockmask = MEDIA_INFO(us).blocksize - 1;
+
+	num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift
+		+ MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
+	MEDIA_INFO(us).pba_to_lba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
+	MEDIA_INFO(us).lba_to_pba = kcalloc(num_zones, sizeof(u16*), GFP_NOIO);
+
+	if (alauda_reset_media(us) != USB_STOR_XFER_GOOD)
+		return USB_STOR_TRANSPORT_ERROR;
+
+	return USB_STOR_TRANSPORT_GOOD;
+}
+
+/*
+ * Examines the media status and does the right thing when the media has gone,
+ * appeared, or changed.
+ */
+static int alauda_check_media(struct us_data *us)
+{
+	struct alauda_info *info = (struct alauda_info *) us->extra;
+	unsigned char status[2];
+	int rc;
+
+	rc = alauda_get_media_status(us, status);
+
+	/* Check for no media or door open */
+	if ((status[0] & 0x80) || ((status[0] & 0x1F) == 0x10)
+		|| ((status[1] & 0x01) == 0)) {
+		US_DEBUGP("alauda_check_media: No media, or door open\n");
+		alauda_free_maps(&MEDIA_INFO(us));
+		info->sense_key = 0x02;
+		info->sense_asc = 0x3A;
+		info->sense_ascq = 0x00;
+		return USB_STOR_TRANSPORT_FAILED;
+	}
+
+	/* Check for media change */
+	if (status[0] & 0x08) {
+		US_DEBUGP("alauda_check_media: Media change detected\n");
+		alauda_free_maps(&MEDIA_INFO(us));
+		alauda_init_media(us);
+
+		info->sense_key = UNIT_ATTENTION;
+		info->sense_asc = 0x28;
+		info->sense_ascq = 0x00;
+		return USB_STOR_TRANSPORT_FAILED;
+	}
+
+	return USB_STOR_TRANSPORT_GOOD;
+}
+
+/*
+ * Checks the status from the 2nd status register
+ * Returns 3 bytes of status data, only the first is known
+ */
+static int alauda_check_status2(struct us_data *us)
+{
+	int rc;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_GET_STATUS2,
+		0, 0, 0, 0, 3, 0, MEDIA_PORT(us)
+	};
+	unsigned char data[3];
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+		data, 3, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	US_DEBUGP("alauda_check_status2: %02X %02X %02X\n", data[0], data[1], data[2]);
+	if (data[0] & ALAUDA_STATUS_ERROR)
+		return USB_STOR_XFER_ERROR;
+
+	return USB_STOR_XFER_GOOD;
+}
+
+/*
+ * Gets the redundancy data for the first page of a PBA
+ * Returns 16 bytes.
+ */
+static int alauda_get_redu_data(struct us_data *us, u16 pba, unsigned char *data)
+{
+	int rc;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_GET_REDU_DATA,
+		PBA_HI(pba), PBA_ZONE(pba), 0, PBA_LO(pba), 0, 0, MEDIA_PORT(us)
+	};
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+		data, 16, NULL);
+}
+
+/*
+ * Finds the first unused PBA in a zone
+ * Returns the absolute PBA of an unused PBA, or 0 if none found.
+ */
+static u16 alauda_find_unused_pba(struct alauda_media_info *info,
+	unsigned int zone)
+{
+	u16 *pba_to_lba = info->pba_to_lba[zone];
+	unsigned int i;
+
+	for (i = 0; i < info->zonesize; i++)
+		if (pba_to_lba[i] == UNDEF)
+			return (zone << info->zoneshift) + i;
+
+	return 0;
+}
+
+/*
+ * Reads the redundancy data for all PBA's in a zone
+ * Produces lba <--> pba mappings
+ */
+static int alauda_read_map(struct us_data *us, unsigned int zone)
+{
+	unsigned char *data = us->iobuf;
+	int result;
+	int i, j;
+	unsigned int zonesize = MEDIA_INFO(us).zonesize;
+	unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+	unsigned int lba_offset, lba_real, blocknum;
+	unsigned int zone_base_lba = zone * uzonesize;
+	unsigned int zone_base_pba = zone * zonesize;
+	u16 *lba_to_pba = kcalloc(zonesize, sizeof(u16), GFP_NOIO);
+	u16 *pba_to_lba = kcalloc(zonesize, sizeof(u16), GFP_NOIO);
+	if (lba_to_pba == NULL || pba_to_lba == NULL) {
+		result = USB_STOR_TRANSPORT_ERROR;
+		goto error;
+	}
+
+	US_DEBUGP("alauda_read_map: Mapping blocks for zone %d\n", zone);
+
+	/* 1024 PBA's per zone */
+	for (i = 0; i < zonesize; i++)
+		lba_to_pba[i] = pba_to_lba[i] = UNDEF;
+
+	for (i = 0; i < zonesize; i++) {
+		blocknum = zone_base_pba + i;
+
+		result = alauda_get_redu_data(us, blocknum, data);
+		if (result != USB_STOR_XFER_GOOD) {
+			result = USB_STOR_TRANSPORT_ERROR;
+			goto error;
+		}
+
+		/* special PBAs have control field 0^16 */
+		for (j = 0; j < 16; j++)
+			if (data[j] != 0)
+				goto nonz;
+		pba_to_lba[i] = UNUSABLE;
+		US_DEBUGP("alauda_read_map: PBA %d has no logical mapping\n", blocknum);
+		continue;
+
+	nonz:
+		/* unwritten PBAs have control field FF^16 */
+		for (j = 0; j < 16; j++)
+			if (data[j] != 0xff)
+				goto nonff;
+		continue;
+
+	nonff:
+		/* normal PBAs start with six FFs */
+		if (j < 6) {
+			US_DEBUGP("alauda_read_map: PBA %d has no logical mapping: "
+			       "reserved area = %02X%02X%02X%02X "
+			       "data status %02X block status %02X\n",
+			       blocknum, data[0], data[1], data[2], data[3],
+			       data[4], data[5]);
+			pba_to_lba[i] = UNUSABLE;
+			continue;
+		}
+
+		if ((data[6] >> 4) != 0x01) {
+			US_DEBUGP("alauda_read_map: PBA %d has invalid address "
+			       "field %02X%02X/%02X%02X\n",
+			       blocknum, data[6], data[7], data[11], data[12]);
+			pba_to_lba[i] = UNUSABLE;
+			continue;
+		}
+
+		/* check even parity */
+		if (parity[data[6] ^ data[7]]) {
+			printk("alauda_read_map: Bad parity in LBA for block %d"
+			       " (%02X %02X)\n", i, data[6], data[7]);
+			pba_to_lba[i] = UNUSABLE;
+			continue;
+		}
+
+		lba_offset = short_pack(data[7], data[6]);
+		lba_offset = (lba_offset & 0x07FF) >> 1;
+		lba_real = lba_offset + zone_base_lba;
+
+		/*
+		 * Every 1024 physical blocks ("zone"), the LBA numbers
+		 * go back to zero, but are within a higher block of LBA's.
+		 * Also, there is a maximum of 1000 LBA's per zone.
+		 * In other words, in PBA 1024-2047 you will find LBA 0-999
+		 * which are really LBA 1000-1999. This allows for 24 bad
+		 * or special physical blocks per zone.
+		 */
+
+		if (lba_offset >= uzonesize) {
+			printk("alauda_read_map: Bad low LBA %d for block %d\n",
+			       lba_real, blocknum);
+			continue;
+		}
+
+		if (lba_to_pba[lba_offset] != UNDEF) {
+			printk("alauda_read_map: LBA %d seen for PBA %d and %d\n",
+			       lba_real, lba_to_pba[lba_offset], blocknum);
+			continue;
+		}
+
+		pba_to_lba[i] = lba_real;
+		lba_to_pba[lba_offset] = blocknum;
+		continue;
+	}
+
+	MEDIA_INFO(us).lba_to_pba[zone] = lba_to_pba;
+	MEDIA_INFO(us).pba_to_lba[zone] = pba_to_lba;
+	result = 0;
+	goto out;
+
+error:
+	kfree(lba_to_pba);
+	kfree(pba_to_lba);
+out:
+	return result;
+}
+
+/*
+ * Checks to see whether we have already mapped a certain zone
+ * If we haven't, the map is generated
+ */
+static void alauda_ensure_map_for_zone(struct us_data *us, unsigned int zone)
+{
+	if (MEDIA_INFO(us).lba_to_pba[zone] == NULL
+		|| MEDIA_INFO(us).pba_to_lba[zone] == NULL)
+		alauda_read_map(us, zone);
+}
+
+/*
+ * Erases an entire block
+ */
+static int alauda_erase_block(struct us_data *us, u16 pba)
+{
+	int rc;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_ERASE_BLOCK, PBA_HI(pba),
+		PBA_ZONE(pba), 0, PBA_LO(pba), 0x02, 0, MEDIA_PORT(us)
+	};
+	unsigned char buf[2];
+
+	US_DEBUGP("alauda_erase_block: Erasing PBA %d\n", pba);
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	rc = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+		buf, 2, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	US_DEBUGP("alauda_erase_block: Erase result: %02X %02X\n",
+		buf[0], buf[1]);
+	return rc;
+}
+
+/*
+ * Reads data from a certain offset page inside a PBA, including interleaved
+ * redundancy data. Returns (pagesize+64)*pages bytes in data.
+ */
+static int alauda_read_block_raw(struct us_data *us, u16 pba,
+		unsigned int page, unsigned int pages, unsigned char *data)
+{
+	int rc;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_READ_BLOCK, PBA_HI(pba),
+		PBA_ZONE(pba), 0, PBA_LO(pba) + page, pages, 0, MEDIA_PORT(us)
+	};
+
+	US_DEBUGP("alauda_read_block: pba %d page %d count %d\n",
+		pba, page, pages);
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+		data, (MEDIA_INFO(us).pagesize + 64) * pages, NULL);
+}
+
+/*
+ * Reads data from a certain offset page inside a PBA, excluding redundancy
+ * data. Returns pagesize*pages bytes in data. Note that data must be big enough
+ * to hold (pagesize+64)*pages bytes of data, but you can ignore those 'extra'
+ * trailing bytes outside this function.
+ */
+static int alauda_read_block(struct us_data *us, u16 pba,
+		unsigned int page, unsigned int pages, unsigned char *data)
+{
+	int i, rc;
+	unsigned int pagesize = MEDIA_INFO(us).pagesize;
+
+	rc = alauda_read_block_raw(us, pba, page, pages, data);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	/* Cut out the redundancy data */
+	for (i = 0; i < pages; i++) {
+		int dest_offset = i * pagesize;
+		int src_offset = i * (pagesize + 64);
+		memmove(data + dest_offset, data + src_offset, pagesize);
+	}
+
+	return rc;
+}
+
+/*
+ * Writes an entire block of data and checks status after write.
+ * Redundancy data must be already included in data. Data should be
+ * (pagesize+64)*blocksize bytes in length.
+ */
+static int alauda_write_block(struct us_data *us, u16 pba, unsigned char *data)
+{
+	int rc;
+	struct alauda_info *info = (struct alauda_info *) us->extra;
+	unsigned char command[] = {
+		ALAUDA_BULK_CMD, ALAUDA_BULK_WRITE_BLOCK, PBA_HI(pba),
+		PBA_ZONE(pba), 0, PBA_LO(pba), 32, 0, MEDIA_PORT(us)
+	};
+
+	US_DEBUGP("alauda_write_block: pba %d\n", pba);
+
+	rc = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+		command, 9, NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	rc = usb_stor_bulk_transfer_buf(us, info->wr_ep, data,
+		(MEDIA_INFO(us).pagesize + 64) * MEDIA_INFO(us).blocksize,
+		NULL);
+	if (rc != USB_STOR_XFER_GOOD)
+		return rc;
+
+	return alauda_check_status2(us);
+}
+
+/*
+ * Write some data to a specific LBA.
+ */
+static int alauda_write_lba(struct us_data *us, u16 lba,
+		 unsigned int page, unsigned int pages,
+		 unsigned char *ptr, unsigned char *blockbuffer)
+{
+	u16 pba, lbap, new_pba;
+	unsigned char *bptr, *cptr, *xptr;
+	unsigned char ecc[3];
+	int i, result;
+	unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+	unsigned int zonesize = MEDIA_INFO(us).zonesize;
+	unsigned int pagesize = MEDIA_INFO(us).pagesize;
+	unsigned int blocksize = MEDIA_INFO(us).blocksize;
+	unsigned int lba_offset = lba % uzonesize;
+	unsigned int new_pba_offset;
+	unsigned int zone = lba / uzonesize;
+
+	alauda_ensure_map_for_zone(us, zone);
+
+	pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];
+	if (pba == 1) {
+		/* Maybe it is impossible to write to PBA 1.
+		   Fake success, but don't do anything. */
+		printk("alauda_write_lba: avoid writing to pba 1\n");
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone);
+	if (!new_pba) {
+		printk("alauda_write_lba: Out of unused blocks\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	/* read old contents */
+	if (pba != UNDEF) {
+		result = alauda_read_block_raw(us, pba, 0,
+			blocksize, blockbuffer);
+		if (result != USB_STOR_XFER_GOOD)
+			return result;
+	} else {
+		memset(blockbuffer, 0, blocksize * (pagesize + 64));
+	}
+
+	lbap = (lba_offset << 1) | 0x1000;
+	if (parity[MSB_of(lbap) ^ LSB_of(lbap)])
+		lbap ^= 1;
+
+	/* check old contents and fill lba */
+	for (i = 0; i < blocksize; i++) {
+		bptr = blockbuffer + (i * (pagesize + 64));
+		cptr = bptr + pagesize;
+		nand_compute_ecc(bptr, ecc);
+		if (!nand_compare_ecc(cptr+13, ecc)) {
+			US_DEBUGP("Warning: bad ecc in page %d- of pba %d\n",
+				  i, pba);
+			nand_store_ecc(cptr+13, ecc);
+		}
+		nand_compute_ecc(bptr + (pagesize / 2), ecc);
+		if (!nand_compare_ecc(cptr+8, ecc)) {
+			US_DEBUGP("Warning: bad ecc in page %d+ of pba %d\n",
+				  i, pba);
+			nand_store_ecc(cptr+8, ecc);
+		}
+		cptr[6] = cptr[11] = MSB_of(lbap);
+		cptr[7] = cptr[12] = LSB_of(lbap);
+	}
+
+	/* copy in new stuff and compute ECC */
+	xptr = ptr;
+	for (i = page; i < page+pages; i++) {
+		bptr = blockbuffer + (i * (pagesize + 64));
+		cptr = bptr + pagesize;
+		memcpy(bptr, xptr, pagesize);
+		xptr += pagesize;
+		nand_compute_ecc(bptr, ecc);
+		nand_store_ecc(cptr+13, ecc);
+		nand_compute_ecc(bptr + (pagesize / 2), ecc);
+		nand_store_ecc(cptr+8, ecc);
+	}
+
+	result = alauda_write_block(us, new_pba, blockbuffer);
+	if (result != USB_STOR_XFER_GOOD)
+		return result;
+
+	new_pba_offset = new_pba - (zone * zonesize);
+	MEDIA_INFO(us).pba_to_lba[zone][new_pba_offset] = lba;
+	MEDIA_INFO(us).lba_to_pba[zone][lba_offset] = new_pba;
+	US_DEBUGP("alauda_write_lba: Remapped LBA %d to PBA %d\n",
+		lba, new_pba);
+
+	if (pba != UNDEF) {
+		unsigned int pba_offset = pba - (zone * zonesize);
+		result = alauda_erase_block(us, pba);
+		if (result != USB_STOR_XFER_GOOD)
+			return result;
+		MEDIA_INFO(us).pba_to_lba[zone][pba_offset] = UNDEF;
+	}
+
+	return USB_STOR_TRANSPORT_GOOD;
+}
+
+/*
+ * Read data from a specific sector address
+ */
+static int alauda_read_data(struct us_data *us, unsigned long address,
+		unsigned int sectors)
+{
+	unsigned char *buffer;
+	u16 lba, max_lba;
+	unsigned int page, len, index, offset;
+	unsigned int blockshift = MEDIA_INFO(us).blockshift;
+	unsigned int pageshift = MEDIA_INFO(us).pageshift;
+	unsigned int blocksize = MEDIA_INFO(us).blocksize;
+	unsigned int pagesize = MEDIA_INFO(us).pagesize;
+	unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
+	int result;
+
+	/*
+	 * Since we only read in one block at a time, we have to create
+	 * a bounce buffer and move the data a piece at a time between the
+	 * bounce buffer and the actual transfer buffer.
+	 * We make this buffer big enough to hold temporary redundancy data,
+	 * which we use when reading the data blocks.
+	 */
+
+	len = min(sectors, blocksize) * (pagesize + 64);
+	buffer = kmalloc(len, GFP_NOIO);
+	if (buffer == NULL) {
+		printk("alauda_read_data: Out of memory\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	/* Figure out the initial LBA and page */
+	lba = address >> blockshift;
+	page = (address & MEDIA_INFO(us).blockmask);
+	max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift);
+
+	result = USB_STOR_TRANSPORT_GOOD;
+	index = offset = 0;
+
+	while (sectors > 0) {
+		unsigned int zone = lba / uzonesize; /* integer division */
+		unsigned int lba_offset = lba - (zone * uzonesize);
+		unsigned int pages;
+		u16 pba;
+		alauda_ensure_map_for_zone(us, zone);
+
+		/* Not overflowing capacity? */
+		if (lba >= max_lba) {
+			US_DEBUGP("Error: Requested lba %u exceeds "
+				  "maximum %u\n", lba, max_lba);
+			result = USB_STOR_TRANSPORT_ERROR;
+			break;
+		}
+
+		/* Find number of pages we can read in this block */
+		pages = min(sectors, blocksize - page);
+		len = pages << pageshift;
+
+		/* Find where this lba lives on disk */
+		pba = MEDIA_INFO(us).lba_to_pba[zone][lba_offset];
+
+		if (pba == UNDEF) {	/* this lba was never written */
+			US_DEBUGP("Read %d zero pages (LBA %d) page %d\n",
+				  pages, lba, page);
+
+			/* This is not really an error. It just means
+			   that the block has never been written.
+			   Instead of returning USB_STOR_TRANSPORT_ERROR
+			   it is better to return all zero data. */
+
+			memset(buffer, 0, len);
+		} else {
+			US_DEBUGP("Read %d pages, from PBA %d"
+				  " (LBA %d) page %d\n",
+				  pages, pba, lba, page);
+
+			result = alauda_read_block(us, pba, page, pages, buffer);
+			if (result != USB_STOR_TRANSPORT_GOOD)
+				break;
+		}
+
+		/* Store the data in the transfer buffer */
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				&index, &offset, TO_XFER_BUF);
+
+		page = 0;
+		lba++;
+		sectors -= pages;
+	}
+
+	kfree(buffer);
+	return result;
+}
+
+/*
+ * Write data to a specific sector address
+ */
+static int alauda_write_data(struct us_data *us, unsigned long address,
+		unsigned int sectors)
+{
+	unsigned char *buffer, *blockbuffer;
+	unsigned int page, len, index, offset;
+	unsigned int blockshift = MEDIA_INFO(us).blockshift;
+	unsigned int pageshift = MEDIA_INFO(us).pageshift;
+	unsigned int blocksize = MEDIA_INFO(us).blocksize;
+	unsigned int pagesize = MEDIA_INFO(us).pagesize;
+	u16 lba, max_lba;
+	int result;
+
+	/*
+	 * Since we don't write the user data directly to the device,
+	 * we have to create a bounce buffer and move the data a piece
+	 * at a time between the bounce buffer and the actual transfer buffer.
+	 */
+
+	len = min(sectors, blocksize) * pagesize;
+	buffer = kmalloc(len, GFP_NOIO);
+	if (buffer == NULL) {
+		printk("alauda_write_data: Out of memory\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	/*
+	 * We also need a temporary block buffer, where we read in the old data,
+	 * overwrite parts with the new data, and manipulate the redundancy data
+	 */
+	blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO);
+	if (blockbuffer == NULL) {
+		printk("alauda_write_data: Out of memory\n");
+		kfree(buffer);
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+
+	/* Figure out the initial LBA and page */
+	lba = address >> blockshift;
+	page = (address & MEDIA_INFO(us).blockmask);
+	max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift);
+
+	result = USB_STOR_TRANSPORT_GOOD;
+	index = offset = 0;
+
+	while (sectors > 0) {
+		/* Write as many sectors as possible in this block */
+		unsigned int pages = min(sectors, blocksize - page);
+		len = pages << pageshift;
+
+		/* Not overflowing capacity? */
+		if (lba >= max_lba) {
+			US_DEBUGP("alauda_write_data: Requested lba %u exceeds "
+				  "maximum %u\n", lba, max_lba);
+			result = USB_STOR_TRANSPORT_ERROR;
+			break;
+		}
+
+		/* Get the data from the transfer buffer */
+		usb_stor_access_xfer_buf(buffer, len, us->srb,
+				&index, &offset, FROM_XFER_BUF);
+
+		result = alauda_write_lba(us, lba, page, pages, buffer,
+			blockbuffer);
+		if (result != USB_STOR_TRANSPORT_GOOD)
+			break;
+
+		page = 0;
+		lba++;
+		sectors -= pages;
+	}
+
+	kfree(buffer);
+	kfree(blockbuffer);
+	return result;
+}
+
+/*
+ * Our interface with the rest of the world
+ */
+
+static void alauda_info_destructor(void *extra)
+{
+	struct alauda_info *info = (struct alauda_info *) extra;
+	int port;
+
+	if (!info)
+		return;
+
+	for (port = 0; port < 2; port++) {
+		struct alauda_media_info *media_info = &info->port[port];
+
+		alauda_free_maps(media_info);
+		kfree(media_info->lba_to_pba);
+		kfree(media_info->pba_to_lba);
+	}
+}
+
+/*
+ * Initialize alauda_info struct and find the data-write endpoint
+ */
+int init_alauda(struct us_data *us)
+{
+	struct alauda_info *info;
+	struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting;
+	nand_init_ecc();
+
+	us->extra = kzalloc(sizeof(struct alauda_info), GFP_NOIO);
+	if (!us->extra) {
+		US_DEBUGP("init_alauda: Gah! Can't allocate storage for"
+			"alauda info struct!\n");
+		return USB_STOR_TRANSPORT_ERROR;
+	}
+	info = (struct alauda_info *) us->extra;
+	us->extra_destructor = alauda_info_destructor;
+
+	info->wr_ep = usb_sndbulkpipe(us->pusb_dev,
+		altsetting->endpoint[0].desc.bEndpointAddress
+		& USB_ENDPOINT_NUMBER_MASK);
+
+	return USB_STOR_TRANSPORT_GOOD;
+}
+
+int alauda_transport(struct scsi_cmnd *srb, struct us_data *us)
+{
+	int rc;
+	struct alauda_info *info = (struct alauda_info *) us->extra;
+	unsigned char *ptr = us->iobuf;
+	static unsigned char inquiry_response[36] = {
+		0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
+	};
+
+	if (srb->cmnd[0] == INQUIRY) {
+		US_DEBUGP("alauda_transport: INQUIRY. "
+			"Returning bogus response.\n");
+		memcpy(ptr, inquiry_response, sizeof(inquiry_response));
+		fill_inquiry_response(us, ptr, 36);
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	if (srb->cmnd[0] == TEST_UNIT_READY) {
+		US_DEBUGP("alauda_transport: TEST_UNIT_READY.\n");
+		return alauda_check_media(us);
+	}
+
+	if (srb->cmnd[0] == READ_CAPACITY) {
+		unsigned int num_zones;
+		unsigned long capacity;
+
+		rc = alauda_check_media(us);
+		if (rc != USB_STOR_TRANSPORT_GOOD)
+			return rc;
+
+		num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift
+			+ MEDIA_INFO(us).blockshift + MEDIA_INFO(us).pageshift);
+
+		capacity = num_zones * MEDIA_INFO(us).uzonesize
+			* MEDIA_INFO(us).blocksize;
+
+		/* Report capacity and page size */
+		((__be32 *) ptr)[0] = cpu_to_be32(capacity - 1);
+		((__be32 *) ptr)[1] = cpu_to_be32(512);
+
+		usb_stor_set_xfer_buf(ptr, 8, srb);
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	if (srb->cmnd[0] == READ_10) {
+		unsigned int page, pages;
+
+		rc = alauda_check_media(us);
+		if (rc != USB_STOR_TRANSPORT_GOOD)
+			return rc;
+
+		page = short_pack(srb->cmnd[3], srb->cmnd[2]);
+		page <<= 16;
+		page |= short_pack(srb->cmnd[5], srb->cmnd[4]);
+		pages = short_pack(srb->cmnd[8], srb->cmnd[7]);
+
+		US_DEBUGP("alauda_transport: READ_10: page %d pagect %d\n",
+			  page, pages);
+
+		return alauda_read_data(us, page, pages);
+	}
+
+	if (srb->cmnd[0] == WRITE_10) {
+		unsigned int page, pages;
+
+		rc = alauda_check_media(us);
+		if (rc != USB_STOR_TRANSPORT_GOOD)
+			return rc;
+
+		page = short_pack(srb->cmnd[3], srb->cmnd[2]);
+		page <<= 16;
+		page |= short_pack(srb->cmnd[5], srb->cmnd[4]);
+		pages = short_pack(srb->cmnd[8], srb->cmnd[7]);
+
+		US_DEBUGP("alauda_transport: WRITE_10: page %d pagect %d\n",
+			  page, pages);
+
+		return alauda_write_data(us, page, pages);
+	}
+
+	if (srb->cmnd[0] == REQUEST_SENSE) {
+		US_DEBUGP("alauda_transport: REQUEST_SENSE.\n");
+
+		memset(ptr, 0, 18);
+		ptr[0] = 0xF0;
+		ptr[2] = info->sense_key;
+		ptr[7] = 11;
+		ptr[12] = info->sense_asc;
+		ptr[13] = info->sense_ascq;
+		usb_stor_set_xfer_buf(ptr, 18, srb);
+
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) {
+		/* sure.  whatever.  not like we can stop the user from popping
+		   the media out of the device (no locking doors, etc) */
+		return USB_STOR_TRANSPORT_GOOD;
+	}
+
+	US_DEBUGP("alauda_transport: Gah! Unknown command: %d (0x%x)\n",
+		srb->cmnd[0], srb->cmnd[0]);
+	info->sense_key = 0x05;
+	info->sense_asc = 0x20;
+	info->sense_ascq = 0x00;
+	return USB_STOR_TRANSPORT_FAILED;
+}
+
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h
new file mode 100644
index 0000000..a700f87
--- /dev/null
+++ b/drivers/usb/storage/alauda.h
@@ -0,0 +1,100 @@
+/*
+ * Driver for Alauda-based card readers
+ *
+ * Current development and maintenance by:
+ *    (c) 2005 Daniel Drake <dsd@gentoo.org>
+ *
+ * See alauda.c for more explanation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _USB_ALAUDA_H
+#define _USB_ALAUDA_H
+
+/*
+ * Status bytes
+ */
+#define ALAUDA_STATUS_ERROR		0x01
+#define ALAUDA_STATUS_READY		0x40
+
+/*
+ * Control opcodes (for request field)
+ */
+#define ALAUDA_GET_XD_MEDIA_STATUS	0x08
+#define ALAUDA_GET_SM_MEDIA_STATUS	0x98
+#define ALAUDA_ACK_XD_MEDIA_CHANGE	0x0a
+#define ALAUDA_ACK_SM_MEDIA_CHANGE	0x9a
+#define ALAUDA_GET_XD_MEDIA_SIG		0x86
+#define ALAUDA_GET_SM_MEDIA_SIG		0x96
+
+/*
+ * Bulk command identity (byte 0)
+ */
+#define ALAUDA_BULK_CMD			0x40
+
+/*
+ * Bulk opcodes (byte 1)
+ */
+#define ALAUDA_BULK_GET_REDU_DATA	0x85
+#define ALAUDA_BULK_READ_BLOCK		0x94
+#define ALAUDA_BULK_ERASE_BLOCK		0xa3
+#define ALAUDA_BULK_WRITE_BLOCK		0xb4
+#define ALAUDA_BULK_GET_STATUS2		0xb7
+#define ALAUDA_BULK_RESET_MEDIA		0xe0
+
+/*
+ * Port to operate on (byte 8)
+ */
+#define ALAUDA_PORT_XD			0x00
+#define ALAUDA_PORT_SM			0x01
+
+/*
+ * LBA and PBA are unsigned ints. Special values.
+ */
+#define UNDEF    0xffff
+#define SPARE    0xfffe
+#define UNUSABLE 0xfffd
+
+int init_alauda(struct us_data *us);
+int alauda_transport(struct scsi_cmnd *srb, struct us_data *us);
+
+struct alauda_media_info {
+	unsigned long capacity;		/* total media size in bytes */
+	unsigned int pagesize;		/* page size in bytes */
+	unsigned int blocksize;		/* number of pages per block */
+	unsigned int uzonesize;		/* number of usable blocks per zone */
+	unsigned int zonesize;		/* number of blocks per zone */
+	unsigned int blockmask;		/* mask to get page from address */
+
+	unsigned char pageshift;
+	unsigned char blockshift;
+	unsigned char zoneshift;
+
+	u16 **lba_to_pba;		/* logical to physical block map */
+	u16 **pba_to_lba;		/* physical to logical block map */
+};
+
+struct alauda_info {
+	struct alauda_media_info port[2];
+	int wr_ep;			/* endpoint to write data out of */
+
+	unsigned char sense_key;
+	unsigned long sense_asc;	/* additional sense code */
+	unsigned long sense_ascq;	/* additional sense code qualifier */
+};
+
+#endif
+
diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c
index 5a93217..01e4306 100644
--- a/drivers/usb/storage/debug.c
+++ b/drivers/usb/storage/debug.c
@@ -132,6 +132,7 @@
 	case 0x5C: what = "READ BUFFER CAPACITY"; break;
 	case 0x5D: what = "SEND CUE SHEET"; break;
 	case GPCMD_BLANK: what = "BLANK"; break;
+	case REPORT_LUNS: what = "REPORT LUNS"; break;
 	case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break;
 	case READ_12: what = "READ_12"; break;
 	case WRITE_12: what = "WRITE_12"; break;
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h
index 7372386..4c1b2bd 100644
--- a/drivers/usb/storage/initializers.h
+++ b/drivers/usb/storage/initializers.h
@@ -45,10 +45,6 @@
  * mode */
 int usb_stor_euscsi_init(struct us_data *us);
 
-#ifdef CONFIG_USB_STORAGE_SDDR09
-int sddr09_init(struct us_data *us);
-#endif
-
 /* This function is required to activate all four slots on the UCR-61S2B
  * flash reader */
 int usb_stor_ucr61s2b_init(struct us_data *us);
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c
new file mode 100644
index 0000000..b28151d
--- /dev/null
+++ b/drivers/usb/storage/libusual.c
@@ -0,0 +1,266 @@
+/*
+ * libusual
+ *
+ * The libusual contains the table of devices common for ub and usb-storage.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb_usual.h>
+#include <linux/vmalloc.h>
+
+/*
+ */
+#define USU_MOD_FL_THREAD   1	/* Thread is running */
+#define USU_MOD_FL_PRESENT  2	/* The module is loaded */
+
+struct mod_status {
+	unsigned long fls;
+};
+
+static struct mod_status stat[3];
+static DEFINE_SPINLOCK(usu_lock);
+
+/*
+ */
+#define USB_US_DEFAULT_BIAS	USB_US_TYPE_STOR
+static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS);
+
+#define BIAS_NAME_SIZE  (sizeof("usb-storage"))
+static const char *bias_names[3] = { "none", "usb-storage", "ub" };
+
+static DECLARE_MUTEX_LOCKED(usu_init_notify);
+static DECLARE_COMPLETION(usu_end_notify);
+static atomic_t total_threads = ATOMIC_INIT(0);
+
+static int usu_probe_thread(void *arg);
+
+/*
+ * The table.
+ */
+#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
+		    vendorName, productName,useProtocol, useTransport, \
+		    initFunction, flags) \
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+  .driver_info = ((useType)<<24) }
+
+struct usb_device_id storage_usb_ids [] = {
+#	include "unusual_devs.h"
+	{ } /* Terminating entry */
+};
+
+#undef USUAL_DEV
+#undef UNUSUAL_DEV
+
+MODULE_DEVICE_TABLE(usb, storage_usb_ids);
+EXPORT_SYMBOL_GPL(storage_usb_ids);
+
+/*
+ * @type: the module type as an integer
+ */
+void usb_usual_set_present(int type)
+{
+	struct mod_status *st;
+	unsigned long flags;
+
+	if (type <= 0 || type >= 3)
+		return;
+	st = &stat[type];
+	spin_lock_irqsave(&usu_lock, flags);
+	st->fls |= USU_MOD_FL_PRESENT;
+	spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_usual_set_present);
+
+void usb_usual_clear_present(int type)
+{
+	struct mod_status *st;
+	unsigned long flags;
+
+	if (type <= 0 || type >= 3)
+		return;
+	st = &stat[type];
+	spin_lock_irqsave(&usu_lock, flags);
+	st->fls &= ~USU_MOD_FL_PRESENT;
+	spin_unlock_irqrestore(&usu_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_usual_clear_present);
+
+/*
+ * Match the calling driver type against the table.
+ * Returns: 0 if the device matches.
+ */
+int usb_usual_check_type(const struct usb_device_id *id, int caller_type)
+{
+	int id_type = USB_US_TYPE(id->driver_info);
+
+	if (caller_type <= 0 || caller_type >= 3)
+		return -EINVAL;
+
+	/* Drivers grab fixed assignment devices */
+	if (id_type == caller_type)
+		return 0;
+	/* Drivers grab devices biased to them */
+	if (id_type == USB_US_TYPE_NONE && caller_type == atomic_read(&usu_bias))
+		return 0;
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(usb_usual_check_type);
+
+/*
+ */
+static int usu_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
+{
+	int type;
+	int rc;
+	unsigned long flags;
+
+	type = USB_US_TYPE(id->driver_info);
+	if (type == 0)
+		type = atomic_read(&usu_bias);
+
+	spin_lock_irqsave(&usu_lock, flags);
+	if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) {
+		spin_unlock_irqrestore(&usu_lock, flags);
+		return -ENXIO;
+	}
+	stat[type].fls |= USU_MOD_FL_THREAD;
+	spin_unlock_irqrestore(&usu_lock, flags);
+
+	rc = kernel_thread(usu_probe_thread, (void*)type, CLONE_VM);
+	if (rc < 0) {
+		printk(KERN_WARNING "libusual: "
+		    "Unable to start the thread for %s: %d\n",
+		    bias_names[type], rc);
+		spin_lock_irqsave(&usu_lock, flags);
+		stat[type].fls &= ~USU_MOD_FL_THREAD;
+		spin_unlock_irqrestore(&usu_lock, flags);
+		return rc;	/* Not being -ENXIO causes a message printed */
+	}
+	atomic_inc(&total_threads);
+
+	return -ENXIO;
+}
+
+static void usu_disconnect(struct usb_interface *intf)
+{
+	;	/* We should not be here. */
+}
+
+static struct usb_driver usu_driver = {
+	.name =		"libusual",
+	.probe =	usu_probe,
+	.disconnect =	usu_disconnect,
+	.id_table =	storage_usb_ids,
+};
+
+/*
+ * A whole new thread for a purpose of request_module seems quite stupid.
+ * The request_module forks once inside again. However, if we attempt
+ * to load a storage module from our own modprobe thread, that module
+ * references our symbols, which cannot be resolved until our module is
+ * initialized. I wish there was a way to wait for the end of initialization.
+ * The module notifier reports MODULE_STATE_COMING only.
+ * So, we wait until module->init ends as the next best thing.
+ */
+static int usu_probe_thread(void *arg)
+{
+	int type = (unsigned long) arg;
+	struct mod_status *st = &stat[type];
+	int rc;
+	unsigned long flags;
+
+	daemonize("libusual_%d", type);	/* "usb-storage" is kinda too long */
+
+	/* A completion does not work here because it's counted. */
+	down(&usu_init_notify);
+	up(&usu_init_notify);
+
+	rc = request_module(bias_names[type]);
+	spin_lock_irqsave(&usu_lock, flags);
+	if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) {
+		/*
+		 * This should not happen, but let us keep tabs on it.
+		 */
+		printk(KERN_NOTICE "libusual: "
+		    "modprobe for %s succeeded, but module is not present\n",
+		    bias_names[type]);
+	}
+	st->fls &= ~USU_MOD_FL_THREAD;
+	spin_unlock_irqrestore(&usu_lock, flags);
+
+	complete_and_exit(&usu_end_notify, 0);
+}
+
+/*
+ */
+static int __init usb_usual_init(void)
+{
+	int rc;
+
+	rc = usb_register(&usu_driver);
+	up(&usu_init_notify);
+	return rc;
+}
+
+static void __exit usb_usual_exit(void)
+{
+	/*
+	 * We do not check for any drivers present, because
+	 * they keep us pinned with symbol references.
+	 */
+
+	usb_deregister(&usu_driver);
+
+	while (atomic_read(&total_threads) > 0) {
+		wait_for_completion(&usu_end_notify);
+		atomic_dec(&total_threads);
+	}
+}
+
+/*
+ * Validate and accept the bias parameter.
+ */
+static int usu_set_bias(const char *bias_s, struct kernel_param *kp)
+{
+	int i;
+	int len;
+	int bias_n = 0;
+
+	len = strlen(bias_s);
+	if (len == 0)
+		return -EDOM;
+	if (bias_s[len-1] == '\n')
+		--len;
+
+	for (i = 1; i < 3; i++) {
+		if (strncmp(bias_s, bias_names[i], len) == 0) {
+			bias_n = i;
+			break;
+		}
+	}
+	if (bias_n == 0)
+		return -EINVAL;
+
+	atomic_set(&usu_bias, bias_n);
+	return 0;
+}
+
+static int usu_get_bias(char *buffer, struct kernel_param *kp)
+{
+	return strlen(strcpy(buffer, bias_names[atomic_read(&usu_bias)]));
+}
+
+module_init(usb_usual_init);
+module_exit(usb_usual_exit);
+
+module_param_call(bias, usu_set_bias, usu_get_bias, NULL, S_IRUGO|S_IWUSR);
+__MODULE_PARM_TYPE(bias, "string");
+MODULE_PARM_DESC(bias, "Bias to usb-storage or ub");
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 89401a5..55ee2d3 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -52,6 +52,7 @@
 	struct urb *irq;	/* urb for interrupt in report */
 	unsigned char *data;	/* input data */
 	dma_addr_t data_dma;
+	unsigned int is_open:1;
 };
 
 static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
@@ -89,6 +90,7 @@
 {
 	struct usb_onetouch *onetouch = dev->private;
 
+	onetouch->is_open = 1;
 	onetouch->irq->dev = onetouch->udev;
 	if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
 		err("usb_submit_urb failed");
@@ -103,8 +105,30 @@
 	struct usb_onetouch *onetouch = dev->private;
 
 	usb_kill_urb(onetouch->irq);
+	onetouch->is_open = 0;
 }
 
+#ifdef CONFIG_PM
+static void usb_onetouch_pm_hook(struct us_data *us, int action)
+{
+	struct usb_onetouch *onetouch = (struct usb_onetouch *) us->extra;
+
+	if (onetouch->is_open) {
+		switch (action) {
+		case US_SUSPEND:
+			usb_kill_urb(onetouch->irq);
+			break;
+		case US_RESUME:
+			if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0)
+				err("usb_submit_urb failed");
+			break;
+		default:
+			break;
+		}
+	}
+}
+#endif /* CONFIG_PM */
+
 int onetouch_connect_input(struct us_data *ss)
 {
 	struct usb_device *udev = ss->pusb_dev;
@@ -185,6 +209,9 @@
 
 	ss->extra_destructor = onetouch_release_input;
 	ss->extra = onetouch;
+#ifdef CONFIG_PM
+	ss->suspend_resume_hook = usb_onetouch_pm_hook;
+#endif
 
 	input_register_device(onetouch->dev);
 
diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h
index 02bff01..845bed4 100644
--- a/drivers/usb/storage/protocol.h
+++ b/drivers/usb/storage/protocol.h
@@ -41,20 +41,6 @@
 #ifndef _PROTOCOL_H_
 #define _PROTOCOL_H_
 
-/* Sub Classes */
-
-#define US_SC_RBC	0x01		/* Typically, flash devices */
-#define US_SC_8020	0x02		/* CD-ROM */
-#define US_SC_QIC	0x03		/* QIC-157 Tapes */
-#define US_SC_UFI	0x04		/* Floppy */
-#define US_SC_8070	0x05		/* Removable media */
-#define US_SC_SCSI	0x06		/* Transparent */
-#define US_SC_ISD200    0x07		/* ISD200 ATA */
-#define US_SC_MIN	US_SC_RBC
-#define US_SC_MAX	US_SC_ISD200
-
-#define US_SC_DEVICE	0xff		/* Use device's value */
-
 /* Protocol handling routines */
 extern void usb_stor_ATAPI_command(struct scsi_cmnd*, struct us_data*);
 extern void usb_stor_qic157_command(struct scsi_cmnd*, struct us_data*);
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 4837524..4ef5527 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -109,7 +109,7 @@
 	 * data comes from.
 	 */
 	if (sdev->scsi_level < SCSI_2)
-		sdev->scsi_level = SCSI_2;
+		sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2;
 
 	/* According to the technical support people at Genesys Logic,
 	 * devices using their chips have problems transferring more than
@@ -162,7 +162,7 @@
 		 * a Get-Max-LUN request, we won't lose much by setting the
 		 * revision level down to 2.  The only devices that would be
 		 * affected are those with sparse LUNs. */
-		sdev->scsi_level = SCSI_2;
+		sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2;
 
 		/* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable
 		 * Hardware Error) when any low-level error occurs,
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index 0ea2f5a..fb8baca 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -133,13 +133,11 @@
 	{ 0,}
 };
 
-#define SIZE(a)	(sizeof(a)/sizeof((a)[0]))
-
 static struct nand_flash_dev *
 nand_find_id(unsigned char id) {
 	int i;
 
-	for (i = 0; i < SIZE(nand_flash_ids); i++)
+	for (i = 0; i < ARRAY_SIZE(nand_flash_ids); i++)
 		if (nand_flash_ids[i].model_id == id)
 			return &(nand_flash_ids[i]);
 	return NULL;
@@ -214,6 +212,20 @@
  * The actual driver starts here.
  */
 
+struct sddr09_card_info {
+	unsigned long	capacity;	/* Size of card in bytes */
+	int		pagesize;	/* Size of page in bytes */
+	int		pageshift;	/* log2 of pagesize */
+	int		blocksize;	/* Size of block in pages */
+	int		blockshift;	/* log2 of blocksize */
+	int		blockmask;	/* 2^blockshift - 1 */
+	int		*lba_to_pba;	/* logical to physical map */
+	int		*pba_to_lba;	/* physical to logical map */
+	int		lbact;		/* number of available pages */
+	int		flags;
+#define	SDDR09_WP	1		/* write protected */
+};
+
 /*
  * On my 16MB card, control blocks have size 64 (16 real control bytes,
  * and 48 junk bytes). In reality of course the card uses 16 control bytes,
@@ -237,7 +249,7 @@
 #define SPARE    0xfffffffe
 #define UNUSABLE 0xfffffffd
 
-static int erase_bad_lba_entries = 0;
+static const int erase_bad_lba_entries = 0;
 
 /* send vendor interface command (0x41) */
 /* called for requests 0, 1, 8 */
@@ -260,8 +272,11 @@
 
 	rc = usb_stor_ctrl_transfer(us, pipe, request, requesttype,
 				   0, 0, xfer_data, xfer_len);
-	return (rc == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD :
-			USB_STOR_TRANSPORT_ERROR);
+	switch (rc) {
+		case USB_STOR_XFER_GOOD:	return 0;
+		case USB_STOR_XFER_STALLED:	return -EPIPE;
+		default:			return -EIO;
+	}
 }
 
 static int
@@ -308,20 +323,12 @@
 	command[4] = buflen;
 
 	result = sddr09_send_scsi_command(us, command, 12);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
-		US_DEBUGP("request sense failed\n");
+	if (result)
 		return result;
-	}
 
 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 			sensebuf, buflen, NULL);
-	if (result != USB_STOR_XFER_GOOD) {
-		US_DEBUGP("request sense bulk in failed\n");
-		return USB_STOR_TRANSPORT_ERROR;
-	} else {
-		US_DEBUGP("request sense worked\n");
-		return USB_STOR_TRANSPORT_GOOD;
-	}
+	return (result == USB_STOR_XFER_GOOD ? 0 : -EIO);
 }
 
 /*
@@ -369,7 +376,7 @@
 
 	result = sddr09_send_scsi_command(us, command, 12);
 
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("Result for send_control in sddr09_read2%d %d\n",
 			  x, result);
 		return result;
@@ -381,9 +388,9 @@
 	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transfer in sddr09_read2%d %d\n",
 			  x, result);
-		return USB_STOR_TRANSPORT_ERROR;
+		return -EIO;
 	}
-	return USB_STOR_TRANSPORT_GOOD;
+	return 0;
 }
 
 /*
@@ -497,7 +504,7 @@
 
 	result = sddr09_send_scsi_command(us, command, 12);
 
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result)
 		US_DEBUGP("Result for send_control in sddr09_erase %d\n",
 			  result);
 
@@ -555,7 +562,7 @@
 
 	result = sddr09_send_scsi_command(us, command, 12);
 
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("Result for send_control in sddr09_writeX %d\n",
 			  result);
 		return result;
@@ -567,9 +574,9 @@
 	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transfer in sddr09_writeX %d\n",
 			  result);
-		return USB_STOR_TRANSPORT_ERROR;
+		return -EIO;
 	}
-	return USB_STOR_TRANSPORT_GOOD;
+	return 0;
 }
 
 /* erase address, write same address */
@@ -633,7 +640,7 @@
 
 	result = sddr09_send_scsi_command(us, command, 4*nsg+3);
 
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("Result for send_control in sddr09_read_sg %d\n",
 			  result);
 		return result;
@@ -641,7 +648,7 @@
 
 	buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO);
 	if (!buf)
-		return USB_STOR_TRANSPORT_ERROR;
+		return -ENOMEM;
 
 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 				       buf, bulklen, NULL);
@@ -649,10 +656,10 @@
 	if (result != USB_STOR_XFER_GOOD) {
 		US_DEBUGP("Result for bulk_transfer in sddr09_read_sg %d\n",
 			  result);
-		return USB_STOR_TRANSPORT_ERROR;
+		return -EIO;
 	}
 
-	return USB_STOR_TRANSPORT_GOOD;
+	return 0;
 }
 #endif
 
@@ -681,14 +688,13 @@
 	command[1] = LUNBITS;
 
 	result = sddr09_send_scsi_command(us, command, 12);
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result)
 		return result;
 
 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
 				       data, 64, NULL);
 	*status = data[0];
-	return (result == USB_STOR_XFER_GOOD ?
-			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
+	return (result == USB_STOR_XFER_GOOD ? 0 : -EIO);
 }
 
 static int
@@ -703,6 +709,13 @@
 	unsigned int len, index, offset;
 	int result;
 
+	// Figure out the initial LBA and page
+	lba = address >> info->blockshift;
+	page = (address & info->blockmask);
+	maxlba = info->capacity >> (info->pageshift + info->blockshift);
+	if (lba >= maxlba)
+		return -EIO;
+
 	// Since we only read in one block at a time, we have to create
 	// a bounce buffer and move the data a piece at a time between the
 	// bounce buffer and the actual transfer buffer.
@@ -711,18 +724,13 @@
 	buffer = kmalloc(len, GFP_NOIO);
 	if (buffer == NULL) {
 		printk("sddr09_read_data: Out of memory\n");
-		return USB_STOR_TRANSPORT_ERROR;
+		return -ENOMEM;
 	}
 
-	// Figure out the initial LBA and page
-	lba = address >> info->blockshift;
-	page = (address & info->blockmask);
-	maxlba = info->capacity >> (info->pageshift + info->blockshift);
-
 	// This could be made much more efficient by checking for
 	// contiguous LBA's. Another exercise left to the student.
 
-	result = USB_STOR_TRANSPORT_GOOD;
+	result = 0;
 	index = offset = 0;
 
 	while (sectors > 0) {
@@ -735,7 +743,7 @@
 		if (lba >= maxlba) {
 			US_DEBUGP("Error: Requested lba %u exceeds "
 				  "maximum %u\n", lba, maxlba);
-			result = USB_STOR_TRANSPORT_ERROR;
+			result = -EIO;
 			break;
 		}
 
@@ -749,7 +757,7 @@
 
 			/* This is not really an error. It just means
 			   that the block has never been written.
-			   Instead of returning USB_STOR_TRANSPORT_ERROR
+			   Instead of returning an error
 			   it is better to return all zero data. */
 
 			memset(buffer, 0, len);
@@ -764,7 +772,7 @@
 
 			result = sddr09_read20(us, address>>1,
 					pages, info->pageshift, buffer, 0);
-			if (result != USB_STOR_TRANSPORT_GOOD)
+			if (result)
 				break;
 		}
 
@@ -830,7 +838,7 @@
 		pba = sddr09_find_unused_pba(info, lba);
 		if (!pba) {
 			printk("sddr09_write_lba: Out of unused blocks\n");
-			return USB_STOR_TRANSPORT_ERROR;
+			return -ENOSPC;
 		}
 		info->pba_to_lba[pba] = lba;
 		info->lba_to_pba[lba] = pba;
@@ -841,7 +849,7 @@
 		/* Maybe it is impossible to write to PBA 1.
 		   Fake success, but don't do anything. */
 		printk("sddr09: avoid writing to pba 1\n");
-		return USB_STOR_TRANSPORT_GOOD;
+		return 0;
 	}
 
 	pagelen = (1 << info->pageshift) + (1 << CONTROL_SHIFT);
@@ -850,7 +858,7 @@
 	address = (pba << (info->pageshift + info->blockshift));
 	result = sddr09_read22(us, address>>1, info->blocksize,
 			       info->pageshift, blockbuffer, 0);
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result)
 		return result;
 
 	/* check old contents and fill lba */
@@ -897,7 +905,7 @@
 	{
 		unsigned char status = 0;
 		int result2 = sddr09_read_status(us, &status);
-		if (result2 != USB_STOR_TRANSPORT_GOOD)
+		if (result2)
 			US_DEBUGP("sddr09_write_inplace: cannot read status\n");
 		else if (status != 0xc0)
 			US_DEBUGP("sddr09_write_inplace: status after write: 0x%x\n",
@@ -920,13 +928,20 @@
 		  unsigned int sectors) {
 
 	struct sddr09_card_info *info = (struct sddr09_card_info *) us->extra;
-	unsigned int lba, page, pages;
+	unsigned int lba, maxlba, page, pages;
 	unsigned int pagelen, blocklen;
 	unsigned char *blockbuffer;
 	unsigned char *buffer;
 	unsigned int len, index, offset;
 	int result;
 
+	// Figure out the initial LBA and page
+	lba = address >> info->blockshift;
+	page = (address & info->blockmask);
+	maxlba = info->capacity >> (info->pageshift + info->blockshift);
+	if (lba >= maxlba)
+		return -EIO;
+
 	// blockbuffer is used for reading in the old data, overwriting
 	// with the new data, and performing ECC calculations
 
@@ -938,7 +953,7 @@
 	blockbuffer = kmalloc(blocklen, GFP_NOIO);
 	if (!blockbuffer) {
 		printk("sddr09_write_data: Out of memory\n");
-		return USB_STOR_TRANSPORT_ERROR;
+		return -ENOMEM;
 	}
 
 	// Since we don't write the user data directly to the device,
@@ -950,14 +965,10 @@
 	if (buffer == NULL) {
 		printk("sddr09_write_data: Out of memory\n");
 		kfree(blockbuffer);
-		return USB_STOR_TRANSPORT_ERROR;
+		return -ENOMEM;
 	}
 
-	// Figure out the initial LBA and page
-	lba = address >> info->blockshift;
-	page = (address & info->blockmask);
-
-	result = USB_STOR_TRANSPORT_GOOD;
+	result = 0;
 	index = offset = 0;
 
 	while (sectors > 0) {
@@ -967,13 +978,21 @@
 		pages = min(sectors, info->blocksize - page);
 		len = (pages << info->pageshift);
 
+		/* Not overflowing capacity? */
+		if (lba >= maxlba) {
+			US_DEBUGP("Error: Requested lba %u exceeds "
+				  "maximum %u\n", lba, maxlba);
+			result = -EIO;
+			break;
+		}
+
 		// Get the data from the transfer buffer
 		usb_stor_access_xfer_buf(buffer, len, us->srb,
 				&index, &offset, FROM_XFER_BUF);
 
 		result = sddr09_write_lba(us, lba, page, pages,
 				buffer, blockbuffer);
-		if (result != USB_STOR_TRANSPORT_GOOD)
+		if (result)
 			break;
 
 		page = 0;
@@ -1022,7 +1041,7 @@
 	command[1] = LUNBITS;
 
 	result = sddr09_send_scsi_command(us, command, 12);
-	if (result != USB_STOR_TRANSPORT_GOOD)
+	if (result)
 		return result;
 
 	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
@@ -1031,8 +1050,7 @@
 	for (i = 0; i < 4; i++)
 		deviceID[i] = content[i];
 
-	return (result == USB_STOR_XFER_GOOD ?
-			USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR);
+	return (result == USB_STOR_XFER_GOOD ? 0 : -EIO);
 }
 
 static int
@@ -1041,7 +1059,7 @@
 	unsigned char status;
 
 	result = sddr09_read_status(us, &status);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("sddr09_get_wp: read_status fails\n");
 		return result;
 	}
@@ -1057,7 +1075,7 @@
 	if (status & 0x1)
 		US_DEBUGP(" Error");
 	US_DEBUGP("\n");
-	return USB_STOR_TRANSPORT_GOOD;
+	return 0;
 }
 
 #if 0
@@ -1089,7 +1107,7 @@
 
 	result = sddr09_read_deviceID(us, deviceID);
 
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("Result of read_deviceID is %d\n", result);
 		printk("sddr09: could not read card info\n");
 		return NULL;
@@ -1200,7 +1218,7 @@
 				us, address>>1,
 				min(alloc_blocks, numblocks - i),
 				buffer, 0);
-			if (result != USB_STOR_TRANSPORT_GOOD) {
+			if (result) {
 				result = -1;
 				goto done;
 			}
@@ -1342,29 +1360,53 @@
 	kfree(info->pba_to_lba);
 }
 
-static void
-sddr09_init_card_info(struct us_data *us) {
-	if (!us->extra) {
-		us->extra = kmalloc(sizeof(struct sddr09_card_info), GFP_NOIO);
-		if (us->extra) {
-			memset(us->extra, 0, sizeof(struct sddr09_card_info));
-			us->extra_destructor = sddr09_card_info_destructor;
-		}
+static int
+sddr09_common_init(struct us_data *us) {
+	int result;
+
+	/* set the configuration -- STALL is an acceptable response here */
+	if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) {
+		US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev
+				->actconfig->desc.bConfigurationValue);
+		return -EINVAL;
 	}
+
+	result = usb_reset_configuration(us->pusb_dev);
+	US_DEBUGP("Result of usb_reset_configuration is %d\n", result);
+	if (result == -EPIPE) {
+		US_DEBUGP("-- stall on control interface\n");
+	} else if (result != 0) {
+		/* it's not a stall, but another error -- time to bail */
+		US_DEBUGP("-- Unknown error.  Rejecting device\n");
+		return -EINVAL;
+	}
+
+	us->extra = kzalloc(sizeof(struct sddr09_card_info), GFP_NOIO);
+	if (!us->extra)
+		return -ENOMEM;
+	us->extra_destructor = sddr09_card_info_destructor;
+
+	nand_init_ecc();
+	return 0;
 }
 
+
 /*
  * This is needed at a very early stage. If this is not listed in the
  * unusual devices list but called from here then LUN 0 of the combo reader
  * is not recognized. But I do not know what precisely these calls do.
  */
 int
-sddr09_init(struct us_data *us) {
+usb_stor_sddr09_dpcm_init(struct us_data *us) {
 	int result;
 	unsigned char *data = us->iobuf;
 
+	result = sddr09_common_init(us);
+	if (result)
+		return result;
+
 	result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("sddr09_init: send_command fails\n");
 		return result;
 	}
@@ -1373,7 +1415,7 @@
 	// get 07 02
 
 	result = sddr09_send_command(us, 0x08, USB_DIR_IN, data, 2);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("sddr09_init: 2nd send_command fails\n");
 		return result;
 	}
@@ -1382,7 +1424,7 @@
 	// get 07 00
 
 	result = sddr09_request_sense(us, data, 18);
-	if (result == USB_STOR_TRANSPORT_GOOD && data[2] != 0) {
+	if (result == 0 && data[2] != 0) {
 		int j;
 		for (j=0; j<18; j++)
 			printk(" %02X", data[j]);
@@ -1398,7 +1440,7 @@
 
 	// test unit ready
 
-	return USB_STOR_TRANSPORT_GOOD;		/* not result */
+	return 0;		/* not result */
 }
 
 /*
@@ -1427,13 +1469,6 @@
 	};
 
 	info = (struct sddr09_card_info *)us->extra;
-	if (!info) {
-		nand_init_ecc();
-		sddr09_init_card_info(us);
-		info = (struct sddr09_card_info *)us->extra;
-		if (!info)
-			return USB_STOR_TRANSPORT_ERROR;
-	}
 
 	if (srb->cmnd[0] == REQUEST_SENSE && havefakesense) {
 		/* for a faked command, we have to follow with a faked sense */
@@ -1536,7 +1571,9 @@
 		US_DEBUGP("READ_10: read page %d pagect %d\n",
 			  page, pages);
 
-		return sddr09_read_data(us, page, pages);
+		result = sddr09_read_data(us, page, pages);
+		return (result == 0 ? USB_STOR_TRANSPORT_GOOD :
+				USB_STOR_TRANSPORT_ERROR);
 	}
 
 	if (srb->cmnd[0] == WRITE_10) {
@@ -1549,7 +1586,9 @@
 		US_DEBUGP("WRITE_10: write page %d pagect %d\n",
 			  page, pages);
 
-		return sddr09_write_data(us, page, pages);
+		result = sddr09_write_data(us, page, pages);
+		return (result == 0 ? USB_STOR_TRANSPORT_GOOD :
+				USB_STOR_TRANSPORT_ERROR);
 	}
 
 	/* catch-all for all other commands, except
@@ -1575,10 +1614,10 @@
 	US_DEBUGP("SDDR09: Send control for command %s\n", ptr);
 
 	result = sddr09_send_scsi_command(us, srb->cmnd, 12);
-	if (result != USB_STOR_TRANSPORT_GOOD) {
+	if (result) {
 		US_DEBUGP("sddr09_transport: sddr09_send_scsi_command "
 			  "returns %d\n", result);
-		return result;
+		return USB_STOR_TRANSPORT_ERROR;
 	}
 
 	if (srb->request_bufflen == 0)
@@ -1606,3 +1645,10 @@
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
+/*
+ * Initialization routine for the sddr09 subdriver
+ */
+int
+usb_stor_sddr09_init(struct us_data *us) {
+	return sddr09_common_init(us);
+}
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h
index c9d78d6..c03089a 100644
--- a/drivers/usb/storage/sddr09.h
+++ b/drivers/usb/storage/sddr09.h
@@ -31,18 +31,7 @@
 
 extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us);
 
-struct sddr09_card_info {
-	unsigned long	capacity;	/* Size of card in bytes */
-	int		pagesize;	/* Size of page in bytes */
-	int		pageshift;	/* log2 of pagesize */
-	int		blocksize;	/* Size of block in pages */
-	int		blockshift;	/* log2 of blocksize */
-	int		blockmask;	/* 2^blockshift - 1 */
-	int		*lba_to_pba;	/* logical to physical map */
-	int		*pba_to_lba;	/* physical to logical map */
-	int		lbact;		/* number of available pages */
-	int		flags;
-#define	SDDR09_WP	1		/* write protected */
-};
+extern int usb_stor_sddr09_dpcm_init(struct us_data *us);
+extern int usb_stor_sddr09_init(struct us_data *us);
 
 #endif
diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
index 0a362cc..633a7158 100644
--- a/drivers/usb/storage/transport.h
+++ b/drivers/usb/storage/transport.h
@@ -41,39 +41,8 @@
 #ifndef _TRANSPORT_H_
 #define _TRANSPORT_H_
 
-#include <linux/config.h>
 #include <linux/blkdev.h>
 
-/* Protocols */
-
-#define US_PR_CBI	0x00		/* Control/Bulk/Interrupt */
-#define US_PR_CB	0x01		/* Control/Bulk w/o interrupt */
-#define US_PR_BULK	0x50		/* bulk only */
-#ifdef CONFIG_USB_STORAGE_USBAT
-#define US_PR_USBAT	0x80		/* SCM-ATAPI bridge */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR09
-#define US_PR_EUSB_SDDR09	0x81	/* SCM-SCSI bridge for SDDR-09 */
-#endif
-#ifdef CONFIG_USB_STORAGE_SDDR55
-#define US_PR_SDDR55	0x82		/* SDDR-55 (made up) */
-#endif
-#define US_PR_DPCM_USB  0xf0		/* Combination CB/SDDR09 */
-
-#ifdef CONFIG_USB_STORAGE_FREECOM
-#define US_PR_FREECOM   0xf1		/* Freecom */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_DATAFAB
-#define US_PR_DATAFAB   0xf2		/* Datafab chipsets */
-#endif
-
-#ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#define US_PR_JUMPSHOT  0xf3		/* Lexar Jumpshot */
-#endif
-
-#define US_PR_DEVICE	0xff		/* Use device's value */
-
 /*
  * Bulk only data structures
  */
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index f5f47a3..dc301e5 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -79,13 +79,6 @@
 		US_SC_8070, US_PR_USBAT, init_usbat, 0),
 #endif
 
-/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
-UNUSUAL_DEV(  0x040d, 0x6205, 0x0003, 0x0003,
-		"VIA Technologies Inc.",
-		"USB 2.0 Card Reader",
-		US_SC_DEVICE, US_PR_DEVICE, NULL,
-		US_FL_IGNORE_RESIDUE ),
-
 /* Reported by Sebastian Kapfer <sebastian_kapfer@gmx.net>
  * and Olaf Hering <olh@suse.de> (different bcd's, same vendor/product)
  * for USB floppies that need the SINGLE_LUN enforcement.
@@ -96,6 +89,13 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_SINGLE_LUN ),
 
+/* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */
+UNUSUAL_DEV(  0x040d, 0x6205, 0x0003, 0x0003,
+		"VIA Technologies Inc.",
+		"USB 2.0 Card Reader",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
  * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
  * always fails and confuses drive.
@@ -187,6 +187,14 @@
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY),
 
+/* Patch for Nikon coolpix 2000
+ * Submitted by Fabien Cosse <fabien.cosse@wanadoo.fr>*/
+UNUSUAL_DEV(  0x04b0, 0x0301, 0x0010, 0x0010,
+		"NIKON",
+		"NIKON DSC E2000",
+		US_SC_DEVICE, US_PR_DEVICE,NULL,
+		US_FL_NOT_LOCKABLE ),
+
 /* BENQ DC5330
  * Reported by Manuel Fombuena <mfombuena@ya.com> and
  * Frank Copeland <fjc@thingy.apana.org.au> */
@@ -276,14 +284,14 @@
 UNUSUAL_DEV(  0x04e6, 0x0003, 0x0000, 0x9999, 
 		"Sandisk",
 		"ImageMate SDDR09",
-		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-		US_FL_SINGLE_LUN ),
+		US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+		0),
 
 /* This entry is from Andries.Brouwer@cwi.nl */
 UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
 		"SCM Microsystems",
 		"eUSB SmartMedia / CompactFlash Adapter",
-		US_SC_SCSI, US_PR_DPCM_USB, sddr09_init, 
+		US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init,
 		0), 
 #endif
 
@@ -527,6 +535,13 @@
 		"Silicon Media R/W",
 		US_SC_DEVICE, US_PR_DEVICE, NULL, 0),
 
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+UNUSUAL_DEV(  0x0584, 0x0008, 0x0102, 0x0102,
+		"Fujifilm",
+		"DPC-R1 (Alauda)",
+ 		US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
+#endif
+
 /* Fabrizio Fellini <fello@libero.it> */
 UNUSUAL_DEV(  0x0595, 0x4343, 0x0000, 0x2210,
 		"Fujifilm",
@@ -673,8 +688,8 @@
 UNUSUAL_DEV(  0x066b, 0x0105, 0x0100, 0x0100, 
 		"Olympus",
 		"Camedia MAUSB-2",
-		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-		US_FL_SINGLE_LUN ),
+		US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+		0),
 #endif
 
 /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */
@@ -739,8 +754,8 @@
 UNUSUAL_DEV(  0x0781, 0x0200, 0x0000, 0x9999, 
 		"Sandisk",
 		"ImageMate SDDR-09",
-		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-		US_FL_SINGLE_LUN ),
+		US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init,
+		0),
 #endif
 
 #ifdef CONFIG_USB_STORAGE_FREECOM
@@ -776,6 +791,13 @@
  		US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
 #endif
 
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+UNUSUAL_DEV(  0x07b4, 0x010a, 0x0102, 0x0102,
+		"Olympus",
+		"MAUSB-10 (Alauda)",
+ 		US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ),
+#endif
+
 #ifdef CONFIG_USB_STORAGE_DATAFAB
 UNUSUAL_DEV(  0x07c4, 0xa000, 0x0000, 0x0015,
 		"Datafab",
@@ -1134,3 +1156,27 @@
 		US_SC_SCSI, US_PR_SDDR55, NULL,
 		US_FL_SINGLE_LUN),
 #endif
+
+/* Control/Bulk transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CB, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CB, USB_US_TYPE_STOR),
+
+/* Control/Bulk/Interrupt transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_CBI, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_CBI, USB_US_TYPE_STOR),
+
+/* Bulk-only transport for all SubClass values */
+USUAL_DEV(US_SC_RBC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8020, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_QIC, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_UFI, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_8070, US_PR_BULK, USB_US_TYPE_STOR),
+USUAL_DEV(US_SC_SCSI, US_PR_BULK, 0),
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 3847ebe..dbcf239 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -94,6 +94,9 @@
 #ifdef CONFIG_USB_STORAGE_ONETOUCH
 #include "onetouch.h"
 #endif
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+#include "alauda.h"
+#endif
 
 /* Some informational data */
 MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
@@ -112,49 +115,33 @@
 static DECLARE_COMPLETION(threads_gone);
 
 
-/* The entries in this table, except for final ones here
- * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
- * line for line with the entries of us_unsuaul_dev_list[].
+/*
+ * The entries in this table correspond, line for line,
+ * with the entries of us_unusual_dev_list[].
  */
+#ifndef CONFIG_USB_LIBUSUAL
 
 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
 		    vendorName, productName,useProtocol, useTransport, \
 		    initFunction, flags) \
-{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax) }
+{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
+  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }
+
+#define USUAL_DEV(useProto, useTrans, useType) \
+{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
+  .driver_info = (USB_US_TYPE_STOR<<24) }
 
 static struct usb_device_id storage_usb_ids [] = {
 
 #	include "unusual_devs.h"
 #undef UNUSUAL_DEV
-	/* Control/Bulk transport for all SubClass values */
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CB) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CB) },
-
-	/* Control/Bulk/Interrupt transport for all SubClass values */
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_CBI) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_CBI) },
-
-	/* Bulk-only transport for all SubClass values */
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_RBC, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8020, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_QIC, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_UFI, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_8070, US_PR_BULK) },
-	{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, US_SC_SCSI, US_PR_BULK) },
-
+#undef USUAL_DEV
 	/* Terminating entry */
 	{ }
 };
 
 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
+#endif /* CONFIG_USB_LIBUSUAL */
 
 /* This is the list of devices we recognize, along with their flag data */
 
@@ -167,7 +154,6 @@
  * are free to use as many characters as you like.
  */
 
-#undef UNUSUAL_DEV
 #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \
 		    vendor_name, product_name, use_protocol, use_transport, \
 		    init_function, Flags) \
@@ -177,53 +163,18 @@
 	.useProtocol = use_protocol,	\
 	.useTransport = use_transport,	\
 	.initFunction = init_function,	\
-	.flags = Flags, \
+}
+
+#define USUAL_DEV(use_protocol, use_transport, use_type) \
+{ \
+	.useProtocol = use_protocol,	\
+	.useTransport = use_transport,	\
 }
 
 static struct us_unusual_dev us_unusual_dev_list[] = {
 #	include "unusual_devs.h" 
 #	undef UNUSUAL_DEV
-	/* Control/Bulk transport for all SubClass values */
-	{ .useProtocol = US_SC_RBC,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_8020,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_QIC,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_UFI,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_8070,
-	  .useTransport = US_PR_CB},
-	{ .useProtocol = US_SC_SCSI,
-	  .useTransport = US_PR_CB},
-
-	/* Control/Bulk/Interrupt transport for all SubClass values */
-	{ .useProtocol = US_SC_RBC,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_8020,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_QIC,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_UFI,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_8070,
-	  .useTransport = US_PR_CBI},
-	{ .useProtocol = US_SC_SCSI,
-	  .useTransport = US_PR_CBI},
-
-	/* Bulk-only transport for all SubClass values */
-	{ .useProtocol = US_SC_RBC,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_8020,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_QIC,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_UFI,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_8070,
-	  .useTransport = US_PR_BULK},
-	{ .useProtocol = US_SC_SCSI,
-	  .useTransport = US_PR_BULK},
+#	undef USUAL_DEV
 
 	/* Terminating entry */
 	{ NULL }
@@ -240,6 +191,8 @@
 	down(&us->dev_semaphore);
 
 	US_DEBUGP("%s\n", __FUNCTION__);
+	if (us->suspend_resume_hook)
+		(us->suspend_resume_hook)(us, US_SUSPEND);
 	iface->dev.power.power_state.event = message.event;
 
 	/* When runtime PM is working, we'll set a flag to indicate
@@ -256,6 +209,8 @@
 	down(&us->dev_semaphore);
 
 	US_DEBUGP("%s\n", __FUNCTION__);
+	if (us->suspend_resume_hook)
+		(us->suspend_resume_hook)(us, US_RESUME);
 	iface->dev.power.power_state.event = PM_EVENT_ON;
 
 	up(&us->dev_semaphore);
@@ -484,14 +439,20 @@
 	return 0;
 }
 
+/* Find an unusual_dev descriptor (always succeeds in the current code) */
+static struct us_unusual_dev *find_unusual(const struct usb_device_id *id)
+{
+	const int id_index = id - storage_usb_ids;
+	return &us_unusual_dev_list[id_index];
+}
+
 /* Get the unusual_devs entries and the string descriptors */
-static void get_device_info(struct us_data *us, int id_index)
+static void get_device_info(struct us_data *us, const struct usb_device_id *id)
 {
 	struct usb_device *dev = us->pusb_dev;
 	struct usb_interface_descriptor *idesc =
 		&us->pusb_intf->cur_altsetting->desc;
-	struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index];
-	struct usb_device_id *id = &storage_usb_ids[id_index];
+	struct us_unusual_dev *unusual_dev = find_unusual(id);
 
 	/* Store the entries */
 	us->unusual_dev = unusual_dev;
@@ -501,7 +462,7 @@
 	us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
 			idesc->bInterfaceProtocol :
 			unusual_dev->useTransport;
-	us->flags = unusual_dev->flags;
+	us->flags = USB_US_ORIG_FLAGS(id->driver_info);
 
 	/*
 	 * This flag is only needed when we're in high-speed, so let's
@@ -516,7 +477,7 @@
 	 * from the unusual_devs.h table.
 	 */
 	if (id->idVendor || id->idProduct) {
-		static char *msgs[3] = {
+		static const char *msgs[3] = {
 			"an unneeded SubClass entry",
 			"an unneeded Protocol entry",
 			"unneeded SubClass and Protocol entries"};
@@ -529,7 +490,7 @@
 		if (unusual_dev->useTransport != US_PR_DEVICE &&
 			us->protocol == idesc->bInterfaceProtocol)
 			msg += 2;
-		if (msg >= 0 && !(unusual_dev->flags & US_FL_NEED_OVERRIDE))
+		if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
 			printk(KERN_NOTICE USB_STORAGE "This device "
 				"(%04x,%04x,%04x S %02x P %02x)"
 				" has %s in unusual_devs.h\n"
@@ -686,6 +647,15 @@
 		break;
 #endif
 
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+	case US_PR_ALAUDA:
+		us->transport_name  = "Alauda Control/Bulk";
+		us->transport = alauda_transport;
+		us->transport_reset = usb_stor_Bulk_reset;
+		us->max_lun = 1;
+		break;
+#endif
+
 	default:
 		return -EIO;
 	}
@@ -921,10 +891,12 @@
 {
 	struct Scsi_Host *host;
 	struct us_data *us;
-	const int id_index = id - storage_usb_ids; 
 	int result;
 	struct task_struct *th;
 
+	if (usb_usual_check_type(id, USB_US_TYPE_STOR))
+		return -ENXIO;
+
 	US_DEBUGP("USB Mass Storage device detected\n");
 
 	/*
@@ -957,29 +929,7 @@
 	 * of the match from the usb_device_id table, so we can find the
 	 * corresponding entry in the private table.
 	 */
-	get_device_info(us, id_index);
-
-#ifdef CONFIG_USB_STORAGE_SDDR09
-	if (us->protocol == US_PR_EUSB_SDDR09 ||
-			us->protocol == US_PR_DPCM_USB) {
-		/* set the configuration -- STALL is an acceptable response here */
-		if (us->pusb_dev->actconfig->desc.bConfigurationValue != 1) {
-			US_DEBUGP("active config #%d != 1 ??\n", us->pusb_dev
-				->actconfig->desc.bConfigurationValue);
-			goto BadDevice;
-		}
-		result = usb_reset_configuration(us->pusb_dev);
-
-		US_DEBUGP("Result of usb_reset_configuration is %d\n", result);
-		if (result == -EPIPE) {
-			US_DEBUGP("-- stall on control interface\n");
-		} else if (result != 0) {
-			/* it's not a stall, but another error -- time to bail */
-			US_DEBUGP("-- Unknown error.  Rejecting device\n");
-			goto BadDevice;
-		}
-	}
-#endif
+	get_device_info(us, id);
 
 	/* Get the transport, protocol, and pipe settings */
 	result = get_transport(us);
@@ -1044,7 +994,6 @@
  ***********************************************************************/
 
 static struct usb_driver usb_storage_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"usb-storage",
 	.probe =	storage_probe,
 	.disconnect =	storage_disconnect,
@@ -1062,9 +1011,10 @@
 
 	/* register the driver, return usb_register return code if error */
 	retval = usb_register(&usb_storage_driver);
-	if (retval == 0)
+	if (retval == 0) {
 		printk(KERN_INFO "USB Mass Storage support registered.\n");
-
+		usb_usual_set_present(USB_US_TYPE_STOR);
+	}
 	return retval;
 }
 
@@ -1088,6 +1038,8 @@
 		wait_for_completion(&threads_gone);
 		atomic_dec(&total_threads);
 	}
+
+	usb_usual_clear_present(USB_US_TYPE_STOR);
 }
 
 module_init(usb_stor_init);
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 98b0971..7259fd1 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -45,6 +45,7 @@
 #define _USB_H_
 
 #include <linux/usb.h>
+#include <linux/usb_usual.h>
 #include <linux/blkdev.h>
 #include <linux/smp_lock.h>
 #include <linux/completion.h>
@@ -63,38 +64,8 @@
 	__u8  useProtocol;
 	__u8  useTransport;
 	int (*initFunction)(struct us_data *);
-	unsigned int flags;
 };
 
-/*
- * Static flag definitions.  We use this roundabout technique so that the
- * proc_info() routine can automatically display a message for each flag.
- */
-#define US_DO_ALL_FLAGS						\
-	US_FLAG(SINGLE_LUN,	0x00000001)			\
-		/* allow access to only LUN 0 */		\
-	US_FLAG(NEED_OVERRIDE,	0x00000002)			\
-		/* unusual_devs entry is necessary */		\
-	US_FLAG(SCM_MULT_TARG,	0x00000004)			\
-		/* supports multiple targets */			\
-	US_FLAG(FIX_INQUIRY,	0x00000008)			\
-		/* INQUIRY response needs faking */		\
-	US_FLAG(FIX_CAPACITY,	0x00000010)			\
-		/* READ CAPACITY response too big */		\
-	US_FLAG(IGNORE_RESIDUE,	0x00000020)			\
-		/* reported residue is wrong */			\
-	US_FLAG(BULK32,		0x00000040)			\
-		/* Uses 32-byte CBW length */			\
-	US_FLAG(NOT_LOCKABLE,	0x00000080)			\
-		/* PREVENT/ALLOW not supported */		\
-	US_FLAG(GO_SLOW,	0x00000100)			\
-		/* Need delay after Command phase */		\
-	US_FLAG(NO_WP_DETECT,	0x00000200)			\
-		/* Don't check for write-protect */		\
-
-#define US_FLAG(name, value)	US_FL_##name = value ,
-enum { US_DO_ALL_FLAGS };
-#undef US_FLAG
 
 /* Dynamic flag definitions: used in set_bit() etc. */
 #define US_FLIDX_URB_ACTIVE	18  /* 0x00040000  current_urb is in use  */
@@ -122,7 +93,11 @@
 typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*);
 typedef int (*trans_reset)(struct us_data*);
 typedef void (*proto_cmnd)(struct scsi_cmnd*, struct us_data*);
-typedef void (*extra_data_destructor)(void *);	 /* extra data destructor   */
+typedef void (*extra_data_destructor)(void *);	/* extra data destructor */
+typedef void (*pm_hook)(struct us_data *, int);	/* power management hook */
+
+#define US_SUSPEND	0
+#define US_RESUME	1
 
 /* we allocate one of these for every device that we remember */
 struct us_data {
@@ -178,6 +153,9 @@
 	/* subdriver information */
 	void			*extra;		 /* Any extra data          */
 	extra_data_destructor	extra_destructor;/* extra data destructor   */
+#ifdef CONFIG_PM
+	pm_hook			suspend_resume_hook;
+#endif
 };
 
 /* Convert between us_data and the corresponding Scsi_Host */
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 6c3a53f..5d02f16 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -39,10 +39,15 @@
 /* Get a minor range for your devices from the usb maintainer */
 #define USB_SKEL_MINOR_BASE	192
 
+/* our private defines. if this grows any larger, use your own .h file */
+#define MAX_TRANSFER		( PAGE_SIZE - 512 )
+#define WRITES_IN_FLIGHT	8
+
 /* Structure to hold all of our device specific stuff */
 struct usb_skel {
 	struct usb_device *	udev;			/* the usb device for this device */
 	struct usb_interface *	interface;		/* the interface for this device */
+	struct semaphore	limit_sem;		/* limiting the number of writes in progress */
 	unsigned char *		bulk_in_buffer;		/* the buffer to receive data */
 	size_t			bulk_in_size;		/* the size of the receive buffer */
 	__u8			bulk_in_endpointAddr;	/* the address of the bulk in endpoint */
@@ -152,6 +157,7 @@
 	/* free up our allocated buffer */
 	usb_buffer_free(urb->dev, urb->transfer_buffer_length, 
 			urb->transfer_buffer, urb->transfer_dma);
+	up(&dev->limit_sem);
 }
 
 static ssize_t skel_write(struct file *file, const char *user_buffer, size_t count, loff_t *ppos)
@@ -160,6 +166,7 @@
 	int retval = 0;
 	struct urb *urb = NULL;
 	char *buf = NULL;
+	size_t writesize = min(count, (size_t)MAX_TRANSFER);
 
 	dev = (struct usb_skel *)file->private_data;
 
@@ -167,6 +174,12 @@
 	if (count == 0)
 		goto exit;
 
+	/* limit the number of URBs in flight to stop a user from using up all RAM */
+	if (down_interruptible(&dev->limit_sem)) {
+		retval = -ERESTARTSYS;
+		goto exit;
+	}
+
 	/* create a urb, and a buffer for it, and copy the data to the urb */
 	urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!urb) {
@@ -174,13 +187,13 @@
 		goto error;
 	}
 
-	buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
+	buf = usb_buffer_alloc(dev->udev, writesize, GFP_KERNEL, &urb->transfer_dma);
 	if (!buf) {
 		retval = -ENOMEM;
 		goto error;
 	}
 
-	if (copy_from_user(buf, user_buffer, count)) {
+	if (copy_from_user(buf, user_buffer, writesize)) {
 		retval = -EFAULT;
 		goto error;
 	}
@@ -188,7 +201,7 @@
 	/* initialize the urb properly */
 	usb_fill_bulk_urb(urb, dev->udev,
 			  usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
-			  buf, count, skel_write_bulk_callback, dev);
+			  buf, writesize, skel_write_bulk_callback, dev);
 	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	/* send the data out the bulk port */
@@ -202,11 +215,12 @@
 	usb_free_urb(urb);
 
 exit:
-	return count;
+	return writesize;
 
 error:
-	usb_buffer_free(dev->udev, count, buf, urb->transfer_dma);
+	usb_buffer_free(dev->udev, writesize, buf, urb->transfer_dma);
 	usb_free_urb(urb);
+	up(&dev->limit_sem);
 	return retval;
 }
 
@@ -238,13 +252,13 @@
 	int retval = -ENOMEM;
 
 	/* allocate memory for our device state and initialize it */
-	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (dev == NULL) {
 		err("Out of memory");
 		goto error;
 	}
-	memset(dev, 0x00, sizeof(*dev));
 	kref_init(&dev->kref);
+	sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
 
 	dev->udev = usb_get_dev(interface_to_usbdev(interface));
 	dev->interface = interface;
@@ -330,7 +344,6 @@
 }
 
 static struct usb_driver skel_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"skeleton",
 	.probe =	skel_probe,
 	.disconnect =	skel_disconnect,
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 25b6ca6..cc8e3bf 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -534,9 +534,15 @@
 	bool "Sun3 framebuffer support"
 	depends on (FB = y) && (SUN3 || SUN3X) && BROKEN
 
+config FB_SBUS
+	bool "SBUS and UPA framebuffers"
+	depends on (FB = y) && SPARC
+	help
+	  Say Y if you want support for SBUS or UPA based frame buffer device.
+
 config FB_BW2
 	bool "BWtwo support"
-	depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+	depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
@@ -545,7 +551,8 @@
 
 config FB_CG3
 	bool "CGthree support"
-	depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+	depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
 	help
@@ -553,7 +560,7 @@
 
 config FB_CG6
 	bool "CGsix (GX,TurboGX) support"
-	depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
+	depends on (FB = y) && (SPARC && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
 	help
@@ -1210,12 +1217,6 @@
 
 source "drivers/video/geode/Kconfig"
 
-config FB_SBUS
-	bool "SBUS and UPA framebuffers"
-	depends on (FB = y) && (SPARC32 || SPARC64)
-	help
-	  Say Y if you want support for SBUS or UPA based frame buffer device.
-
 config FB_FFB
 	bool "Creator/Creator3D/Elite3D support"
 	depends on FB_SBUS && SPARC64
@@ -1267,7 +1268,7 @@
 
 config FB_PCI
 	bool "PCI framebuffers"
-	depends on (FB = y) && PCI && (SPARC64 || SPARC32)
+	depends on (FB = y) && PCI && SPARC
 
 config FB_IGA
 	bool "IGA 168x display support"
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index a3c2c45..0da4083 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -21,12 +21,11 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/list.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
+#include <linux/clk.h>
 
 #include <asm/sizes.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/clock.h>
-
-#include <asm/hardware/amba_clcd.h>
 
 #define to_clcd(info)	container_of(info, struct clcd_fb, fb)
 
@@ -346,10 +345,6 @@
 		goto out;
 	}
 
-	ret = clk_use(fb->clk);
-	if (ret)
-		goto free_clk;
-
 	fb->fb.fix.mmio_start	= fb->dev->res.start;
 	fb->fb.fix.mmio_len	= SZ_4K;
 
@@ -357,7 +352,7 @@
 	if (!fb->regs) {
 		printk(KERN_ERR "CLCD: unable to remap registers\n");
 		ret = -ENOMEM;
-		goto unuse_clk;
+		goto free_clk;
 	}
 
 	fb->fb.fbops		= &clcdfb_ops;
@@ -427,8 +422,6 @@
 	printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret);
 
 	iounmap(fb->regs);
- unuse_clk:
-	clk_unuse(fb->clk);
  free_clk:
 	clk_put(fb->clk);
  out:
@@ -489,7 +482,6 @@
 	clcdfb_disable(fb);
 	unregister_framebuffer(&fb->fb);
 	iounmap(fb->regs);
-	clk_unuse(fb->clk);
 	clk_put(fb->clk);
 
 	fb->board->remove(fb);
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 080db81..2784f0a 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -441,7 +441,7 @@
  * the fb. it's inefficient for them to do anything less than 64*8
  * writes since we update the lcd in each write() anyway.
  */
-static ssize_t arcfb_write(struct file *file, const char *buf, size_t count,
+static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t count,
 				loff_t *ppos)
 {
 	/* modded from epson 1355 */
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 08edbfc..3fefdb0c 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -403,7 +403,7 @@
 	{ PCI_CHIP_MACH64GM, "3D RAGE XL (Mach64 GM, AGP)", 230, 83, 63, ATI_CHIP_264XL },
 	{ PCI_CHIP_MACH64GN, "3D RAGE XL (Mach64 GN, AGP)", 230, 83, 63, ATI_CHIP_264XL },
 	{ PCI_CHIP_MACH64GO, "3D RAGE XL (Mach64 GO, PCI-66/BGA)", 230, 83, 63, ATI_CHIP_264XL },
-	{ PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 230, 83, 63, ATI_CHIP_264XL },
+	{ PCI_CHIP_MACH64GR, "3D RAGE XL (Mach64 GR, PCI-33MHz)", 235, 83, 63, ATI_CHIP_264XL | M64F_SDRAM_MAGIC_PLL },
 	{ PCI_CHIP_MACH64GL, "3D RAGE XL (Mach64 GL, PCI)", 230, 83, 63, ATI_CHIP_264XL },
 	{ PCI_CHIP_MACH64GS, "3D RAGE XL (Mach64 GS, PCI)", 230, 83, 63, ATI_CHIP_264XL },
 
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 4f01ccc..156db84 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -594,7 +594,7 @@
 }
 
 /*
- * Retreive PLL infos by different means (BIOS, Open Firmware, register probing...)
+ * Retrieve PLL infos by different means (BIOS, Open Firmware, register probing...)
  */
 static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo)
 {
@@ -660,17 +660,17 @@
 
 #ifdef CONFIG_PPC_OF
 	/*
-	 * Retreive PLL infos from Open Firmware first
+	 * Retrieve PLL infos from Open Firmware first
 	 */
        	if (!force_measure_pll && radeon_read_xtal_OF(rinfo) == 0) {
-       		printk(KERN_INFO "radeonfb: Retreived PLL infos from Open Firmware\n");
+       		printk(KERN_INFO "radeonfb: Retrieved PLL infos from Open Firmware\n");
 		goto found;
 	}
 #endif /* CONFIG_PPC_OF */
 
 	/*
 	 * Check out if we have an X86 which gave us some PLL informations
-	 * and if yes, retreive them
+	 * and if yes, retrieve them
 	 */
 	if (!force_measure_pll && rinfo->bios_seg) {
 		u16 pll_info_block = BIOS_IN16(rinfo->fp_bios_start + 0x30);
@@ -682,7 +682,7 @@
 		rinfo->pll.ppll_min	= BIOS_IN32(pll_info_block + 0x12);
 		rinfo->pll.ppll_max	= BIOS_IN32(pll_info_block + 0x16);
 
-		printk(KERN_INFO "radeonfb: Retreived PLL infos from BIOS\n");
+		printk(KERN_INFO "radeonfb: Retrieved PLL infos from BIOS\n");
 		goto found;
 	}
 
@@ -691,7 +691,7 @@
 	 * probe them
 	 */
 	if (radeon_probe_pll_params(rinfo) == 0) {
-		printk(KERN_INFO "radeonfb: Retreived PLL infos from registers\n");
+		printk(KERN_INFO "radeonfb: Retrieved PLL infos from registers\n");
 		goto found;
 	}
 
@@ -702,7 +702,7 @@
 
 found:
 	/*
-	 * Some methods fail to retreive SCLK and MCLK values, we apply default
+	 * Some methods fail to retrieve SCLK and MCLK values, we apply default
 	 * settings in this case (200Mhz). If that really happne often, we could
 	 * fetch from registers instead...
 	 */
@@ -2393,7 +2393,7 @@
 	       rinfo->mapped_vram/1024);
 
 	/*
-	 * Map the BIOS ROM if any and retreive PLL parameters from
+	 * Map the BIOS ROM if any and retrieve PLL parameters from
 	 * the BIOS. We skip that on mobility chips as the real panel
 	 * values we need aren't in the ROM but in the BIOS image in
 	 * memory. This is definitely not the best meacnism though,
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index 6a219b2..d0aaf45 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -20,6 +20,7 @@
 #include <linux/backlight.h>
 
 #include <asm/arch/sharpsl.h>
+#include <asm/hardware/sharpsl_pm.h>
 
 #define CORGI_DEFAULT_INTENSITY		0x1f
 #define CORGI_LIMIT_MASK		0x0b
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index d3728f6..9248fe1 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -121,7 +121,6 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
-	struct list_head	list;
 };
 
 /**
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index cdc7157..7441532 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -64,8 +64,8 @@
 	int const shift = dst_idx-src_idx;
 	int left, right;
 
-	first = ~0UL >> dst_idx;
-	last = ~(~0UL >> ((dst_idx+n) % bits));
+	first = FB_SHIFT_HIGH(~0UL, dst_idx);
+	last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
 
 	if (!shift) {
 		// Same alignment for source and dest
@@ -216,8 +216,8 @@
 
 	shift = dst_idx-src_idx;
 
-	first = ~0UL << (bits - 1 - dst_idx);
-	last = ~(~0UL << (bits - 1 - ((dst_idx-n) % bits)));
+	first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx);
+	last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits)));
 
 	if (!shift) {
 		// Same alignment for source and dest
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index 167d931..e5ff62e 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -110,8 +110,8 @@
 	if (!n)
 		return;
 
-	first = ~0UL >> dst_idx;
-	last = ~(~0UL >> ((dst_idx+n) % bits));
+	first = FB_SHIFT_HIGH(~0UL, dst_idx);
+	last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
 
 	if (dst_idx+n <= bits) {
 		// Single word
@@ -167,8 +167,8 @@
 	if (!n)
 		return;
 
-	first = ~0UL >> dst_idx;
-	last = ~(~0UL >> ((dst_idx+n) % bits));
+	first = FB_SHIFT_HIGH(~0UL, dst_idx);
+	last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
 
 	if (dst_idx+n <= bits) {
 		// Single word
@@ -221,8 +221,8 @@
 	if (!n)
 		return;
 
-	first = ~0UL >> dst_idx;
-	last = ~(~0UL >> ((dst_idx+n) % bits));
+	first = FB_SHIFT_HIGH(~0UL, dst_idx);
+	last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
 
 	if (dst_idx+n <= bits) {
 		// Single word
@@ -290,8 +290,8 @@
 	if (!n)
 		return;
 
-	first = ~0UL >> dst_idx;
-	last = ~(~0UL >> ((dst_idx+n) % bits));
+	first = FB_SHIFT_HIGH(~0UL, dst_idx);
+	last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
 
 	if (dst_idx+n <= bits) {
 		// Single word
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index a7770c4..910e233 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -76,18 +76,6 @@
 #define FB_WRITEL fb_writel
 #define FB_READL  fb_readl
 
-#if defined (__BIG_ENDIAN)
-#define LEFT_POS(bpp)          (32 - bpp)
-#define SHIFT_HIGH(val, bits)  ((val) >> (bits))
-#define SHIFT_LOW(val, bits)   ((val) << (bits))
-#define BIT_NR(b)              (7 - (b))
-#else
-#define LEFT_POS(bpp)          (0)
-#define SHIFT_HIGH(val, bits)  ((val) << (bits))
-#define SHIFT_LOW(val, bits)   ((val) >> (bits))
-#define BIT_NR(b)              (b)
-#endif
-
 static inline void color_imageblit(const struct fb_image *image, 
 				   struct fb_info *p, u8 __iomem *dst1, 
 				   u32 start_index,
@@ -109,7 +97,7 @@
 		val = 0;
 		
 		if (start_index) {
-			u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
+			u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0, start_index));
 			val = FB_READL(dst) & start_mask;
 			shift = start_index;
 		}
@@ -119,20 +107,20 @@
 				color = palette[*src];
 			else
 				color = *src;
-			color <<= LEFT_POS(bpp);
-			val |= SHIFT_HIGH(color, shift);
+			color <<= FB_LEFT_POS(bpp);
+			val |= FB_SHIFT_HIGH(color, shift);
 			if (shift >= null_bits) {
 				FB_WRITEL(val, dst++);
 	
 				val = (shift == null_bits) ? 0 : 
-					SHIFT_LOW(color, 32 - shift);
+					FB_SHIFT_LOW(color, 32 - shift);
 			}
 			shift += bpp;
 			shift &= (32 - 1);
 			src++;
 		}
 		if (shift) {
-			u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
+			u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
 
 			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
 		}
@@ -162,6 +150,8 @@
 	u32 i, j, l;
 	
 	dst2 = (u32 __iomem *) dst1;
+	fgcolor <<= FB_LEFT_POS(bpp);
+	bgcolor <<= FB_LEFT_POS(bpp);
 
 	for (i = image->height; i--; ) {
 		shift = val = 0;
@@ -172,22 +162,21 @@
 
 		/* write leading bits */
 		if (start_index) {
-			u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index));
+			u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index));
 			val = FB_READL(dst) & start_mask;
 			shift = start_index;
 		}
 
 		while (j--) {
 			l--;
-			color = (*s & 1 << (BIT_NR(l))) ? fgcolor : bgcolor;
-			color <<= LEFT_POS(bpp);
-			val |= SHIFT_HIGH(color, shift);
+			color = (*s & 1 << (FB_BIT_NR(l))) ? fgcolor : bgcolor;
+			val |= FB_SHIFT_HIGH(color, shift);
 			
 			/* Did the bitshift spill bits to the next long? */
 			if (shift >= null_bits) {
 				FB_WRITEL(val, dst++);
 				val = (shift == null_bits) ? 0 :
-					 SHIFT_LOW(color,32 - shift);
+					FB_SHIFT_LOW(color,32 - shift);
 			}
 			shift += bpp;
 			shift &= (32 - 1);
@@ -196,7 +185,7 @@
 
 		/* write trailing bits */
  		if (shift) {
-			u32 end_mask = SHIFT_HIGH(~(u32)0, shift);
+			u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
 
 			FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
 		}
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index 1bed50f..a561471 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -206,7 +206,6 @@
 	int			mode;
 	int			ramsize;
 	struct sbus_dev		*sdev;
-	struct list_head	list;
 };
 
 static void __cg14_reset(struct cg14_par *par)
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index a1354e7..9fcd896 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -124,7 +124,6 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
-	struct list_head	list;
 };
 
 /**
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 9debe64..050835e3 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -265,7 +265,6 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
-	struct list_head	list;
 };
 
 static int cg6_sync(struct fb_info *info)
@@ -612,7 +611,7 @@
 	struct cg6_par *par = (struct cg6_par *) info->par;
 	struct cg6_tec __iomem *tec = par->tec;
 	struct cg6_fbc __iomem *fbc = par->fbc;
-	u32 rev, conf, mode, tmp;
+	u32 rev, conf, mode;
 	int i;
 	
 	/* Turn off stuff in the Transform Engine. */
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 2858c5c..e0dbdfc 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -404,7 +404,7 @@
 	struct cirrusfb_regs currentmode;
 	int blank_mode;
 
-	u32	pseudo_palette[17];
+	u32	pseudo_palette[16];
 	struct { u8 red, green, blue, pad; } palette[256];
 
 #ifdef CONFIG_ZORRO
@@ -1603,14 +1603,14 @@
 
 		switch (info->var.bits_per_pixel) {
 			case 8:
-				((u8*)(info->pseudo_palette))[regno] = v;
+				cinfo->pseudo_palette[regno] = v;
 				break;
 			case 16:
-				((u16*)(info->pseudo_palette))[regno] = v;
+				cinfo->pseudo_palette[regno] = v;
 				break;
 			case 24:
 			case 32:
-				((u32*)(info->pseudo_palette))[regno] = v;
+				cinfo->pseudo_palette[regno] = v;
 				break;
 		}
 		return 0;
@@ -2020,18 +2020,21 @@
 				   const struct fb_fillrect *region)
 {
 	int m; /* bytes per pixel */
+	u32 color = (cinfo->info->fix.visual == FB_VISUAL_TRUECOLOR) ?
+		cinfo->pseudo_palette[region->color] : region->color;
+
 	if(cinfo->info->var.bits_per_pixel == 1) {
 		cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
 				  region->dx / 8, region->dy,
 				  region->width / 8, region->height,
-				  region->color,
+				  color,
 				  cinfo->currentmode.line_length);
 	} else {
 		m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
 		cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
 				  region->dx * m, region->dy,
 				  region->width * m, region->height,
-				  region->color,
+				  color,
 				  cinfo->currentmode.line_length);
 	}
 	return;
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 5f74df9..6ee4498 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@
 
 config VGA_CONSOLE
 	bool "VGA text console" if EMBEDDED || !X86
-	depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC && !ARCH_VERSATILE
+	depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE
 	default y
 	help
 	  Saying Y here will allow you to use Linux in text mode through a
@@ -68,7 +68,7 @@
 
 config PROM_CONSOLE
 	bool "PROM console"
-	depends on SPARC32 || SPARC64
+	depends on SPARC
 	help
 	  Say Y to build a console driver for Sun machines that uses the
 	  terminal emulation built into their console PROMS.
@@ -136,7 +136,7 @@
 config FONT_8x8
 	bool "VGA 8x8 font" if FONTS
 	depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
-	default y if !SPARC32 && !SPARC64 && !FONTS
+	default y if !SPARC && !FONTS
 	help
 	  This is the "high resolution" font for the VGA frame buffer (the one
 	  provided by the text console 80x50 (and higher) modes).
@@ -150,7 +150,7 @@
 config FONT_8x16
 	bool "VGA 8x16 font" if FONTS
 	depends on FRAMEBUFFER_CONSOLE || SGI_NEWPORT_CONSOLE=y || STI_CONSOLE || USB_SISUSBVGA_CON 
-	default y if !SPARC32 && !SPARC64 && !FONTS
+	default y if !SPARC && !FONTS
 	help
 	  This is the "high resolution" font for the VGA frame buffer (the one
 	  provided by the VGA text console 80x25 mode.
@@ -160,7 +160,7 @@
 config FONT_6x11
 	bool "Mac console 6x11 font (not supported by all drivers)" if FONTS
 	depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
-	default y if !SPARC32 && !SPARC64 && !FONTS && MAC
+	default y if !SPARC && !FONTS && MAC
 	help
 	  Small console font with Macintosh-style high-half glyphs.  Some Mac
 	  framebuffer drivers don't support this one at all.
@@ -176,7 +176,7 @@
 config FONT_PEARL_8x8
 	bool "Pearl (old m68k) console 8x8 font" if FONTS
 	depends on FRAMEBUFFER_CONSOLE
-	default y if !SPARC32 && !SPARC64 && !FONTS && AMIGA
+	default y if !SPARC && !FONTS && AMIGA
 	help
 	  Small console font with PC-style control-character and high-half
 	  glyphs.
@@ -184,24 +184,24 @@
 config FONT_ACORN_8x8
 	bool "Acorn console 8x8 font" if FONTS
 	depends on FRAMEBUFFER_CONSOLE
-	default y if !SPARC32 && !SPARC64 && !FONTS && ARM && ARCH_ACORN
+	default y if !SPARC && !FONTS && ARM && ARCH_ACORN
 	help
 	  Small console font with PC-style control characters and high-half
 	  glyphs.
 
 config FONT_MINI_4x6
 	bool "Mini 4x6 font"
-	depends on !SPARC32 && !SPARC64 && FONTS
+	depends on !SPARC && FONTS
 
 config FONT_SUN8x16
 	bool "Sparc console 8x16 font"
-	depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
+	depends on FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC)
 	help
 	  This is the high resolution console font for Sun machines. Say Y.
 
 config FONT_SUN12x22
 	bool "Sparc console 12x22 font (not supported by all drivers)"
-	depends on FRAMEBUFFER_CONSOLE && (!SPARC32 && !SPARC64 && FONTS || SPARC32 || SPARC64)
+	depends on FRAMEBUFFER_CONSOLE && (!SPARC && FONTS || SPARC)
 	help
 	  This is the high resolution console font for Sun machines with very
 	  big letters (like the letters used in the SPARC PROM). If the
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index bcea87c..50e4c4e 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -1110,7 +1110,7 @@
 	 *
 	 * We need to do it in fbcon_init() to prevent screen corruption.
 	 */
-	if (CON_IS_VISIBLE(vc)) {
+	if (CON_IS_VISIBLE(vc) && vc->vc_mode == KD_TEXT) {
 		if (info->fbops->fb_set_par &&
 		    !(ops->flags & FBCON_FLAGS_INIT))
 			info->fbops->fb_set_par(info);
@@ -2048,7 +2048,7 @@
 	struct fbcon_ops *ops;
 	struct display *p = &fb_display[vc->vc_num];
 	struct fb_var_screeninfo var;
-	int i, prev_console;
+	int i, prev_console, charcnt = 256;
 
 	info = registered_fb[con2fb_map[vc->vc_num]];
 	ops = info->fbcon_par;
@@ -2103,7 +2103,8 @@
 	fb_set_var(info, &var);
 	ops->var = info->var;
 
-	if (old_info != NULL && old_info != info) {
+	if (old_info != NULL && (old_info != info ||
+				 info->flags & FBINFO_MISC_ALWAYS_SETPAR)) {
 		if (info->fbops->fb_set_par)
 			info->fbops->fb_set_par(info);
 		fbcon_del_cursor_timer(old_info);
@@ -2120,6 +2121,13 @@
 
 	vc->vc_can_do_color = (fb_get_color_depth(&info->var, &info->fix)!=1);
 	vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+
+	if (p->userfont)
+		charcnt = FNTCHARCNT(vc->vc_font.data);
+
+	if (charcnt > 256)
+		vc->vc_complement_mask <<= 1;
+
 	updatescrollmode(p, info, vc);
 
 	switch (p->scrollmode) {
@@ -2139,8 +2147,12 @@
 
 	scrollback_max = 0;
 	scrollback_current = 0;
-	ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
-	ops->update_start(info);
+
+	if (!fbcon_is_inactive(vc, info)) {
+	    ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
+	    ops->update_start(info);
+	}
+
 	fbcon_set_palette(vc, color_table); 	
 	fbcon_clear_margins(vc, 0);
 
@@ -2184,11 +2196,14 @@
 		ops->graphics = 1;
 
 		if (!blank) {
+			if (info->fbops->fb_save_state)
+				info->fbops->fb_save_state(info);
 			var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
 			fb_set_var(info, &var);
 			ops->graphics = 0;
 			ops->var = info->var;
-		}
+		} else if (info->fbops->fb_restore_state)
+			info->fbops->fb_restore_state(info);
 	}
 
  	if (!fbcon_is_inactive(vc, info)) {
@@ -2736,8 +2751,12 @@
 		updatescrollmode(p, info, vc);
 		scrollback_max = 0;
 		scrollback_current = 0;
-		ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
-		ops->update_start(info);
+
+		if (!fbcon_is_inactive(vc, info)) {
+		    ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
+		    ops->update_start(info);
+		}
+
 		fbcon_set_palette(vc, color_table);
 		update_screen(vc);
 		if (softback_buf)
@@ -2774,8 +2793,13 @@
 			updatescrollmode(p, info, vc);
 			scrollback_max = 0;
 			scrollback_current = 0;
-			ops->var.xoffset = ops->var.yoffset = p->yscroll = 0;
-			ops->update_start(info);
+
+			if (!fbcon_is_inactive(vc, info)) {
+			    ops->var.xoffset = ops->var.yoffset =
+				p->yscroll = 0;
+			    ops->update_start(info);
+			}
+
 			fbcon_set_palette(vc, color_table);
 			update_screen(vc);
 			if (softback_buf)
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c
index 3afd1ee..4952b66 100644
--- a/drivers/video/console/fbcon_ccw.c
+++ b/drivers/video/console/fbcon_ccw.c
@@ -34,7 +34,7 @@
 		msk <<= (8 - mod);
 
 	if (offset > mod)
-		set_bit(FBCON_BIT(7), (void *)&msk1);
+		msk1 |= 0x01;
 
 	for (i = 0; i < vc->vc_font.width; i++) {
 		for (j = 0; j < width; j++) {
diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h
index e504fbf..1b8f92f 100644
--- a/drivers/video/console/fbcon_rotate.h
+++ b/drivers/video/console/fbcon_rotate.h
@@ -21,21 +21,13 @@
         (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
         (i)->var.xres : (i)->var.xres_virtual; })
 
-/*
- * The bitmap is always big endian
- */
-#if defined(__LITTLE_ENDIAN)
-#define FBCON_BIT(b) (7 - (b))
-#else
-#define FBCON_BIT(b) (b)
-#endif
 
 static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
 {
 	u32 tmp = (y * pitch) + x, index = tmp / 8,  bit = tmp % 8;
 
 	pat +=index;
-	return (test_bit(FBCON_BIT(bit), (void *)pat));
+	return (*pat) & (0x80 >> bit);
 }
 
 static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
@@ -43,7 +35,8 @@
 	u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
 
 	pat += index;
-	set_bit(FBCON_BIT(bit), (void *)pat);
+
+	(*pat) |= 0x80 >> bit;
 }
 
 static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c
index c4d7c89..9dd059e 100644
--- a/drivers/video/console/fbcon_ud.c
+++ b/drivers/video/console/fbcon_ud.c
@@ -420,13 +420,15 @@
 int ud_update_start(struct fb_info *info)
 {
 	struct fbcon_ops *ops = info->fbcon_par;
-	u32 xoffset, yoffset;
+	int xoffset, yoffset;
 	u32 vyres = GETVYRES(ops->p->scrollmode, info);
 	u32 vxres = GETVXRES(ops->p->scrollmode, info);
 	int err;
 
-	xoffset = (vxres - info->var.xres) - ops->var.xoffset;
-	yoffset = (vyres - info->var.yres) - ops->var.yoffset;
+	xoffset = vxres - info->var.xres - ops->var.xoffset;
+	yoffset = vyres - info->var.yres - ops->var.yoffset;
+	if (yoffset < 0)
+		yoffset += vyres;
 	ops->var.xoffset = xoffset;
 	ops->var.yoffset = yoffset;
 	err = fb_pan_display(info, &ops->var);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 167de39..12d9329 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -56,6 +56,8 @@
 static DEFINE_SPINLOCK(vga_lock);
 static int cursor_size_lastfrom;
 static int cursor_size_lastto;
+static u32 vgacon_xres;
+static u32 vgacon_yres;
 static struct vgastate state;
 
 #define BLANK 0x0020
@@ -69,7 +71,7 @@
  * appear.
  */
 #undef TRIDENT_GLITCH
-
+#define VGA_FONTWIDTH       8   /* VGA does not support fontwidths != 8 */
 /*
  *  Interface used by the world
  */
@@ -325,6 +327,10 @@
 		vga_scan_lines =
 		    vga_video_font_height * vga_video_num_lines;
 	}
+
+	vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH;
+	vgacon_yres = vga_scan_lines;
+
 	return display_desc;
 }
 
@@ -503,10 +509,18 @@
 {
 	unsigned long flags;
 	unsigned int scanlines = height * c->vc_font.height;
-	u8 scanlines_lo, r7, vsync_end, mode;
+	u8 scanlines_lo, r7, vsync_end, mode, max_scan;
 
 	spin_lock_irqsave(&vga_lock, flags);
 
+	outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
+	max_scan = inb_p(vga_video_port_val);
+
+	if (max_scan & 0x80)
+		scanlines <<= 1;
+
+	vgacon_xres = width * VGA_FONTWIDTH;
+	vgacon_yres = height * c->vc_font.height;
 	outb_p(VGA_CRTC_MODE, vga_video_port_reg);
 	mode = inb_p(vga_video_port_val);
 
@@ -551,6 +565,10 @@
 
 static int vgacon_switch(struct vc_data *c)
 {
+	int x = c->vc_cols * VGA_FONTWIDTH;
+	int y = c->vc_rows * c->vc_font.height;
+	int rows = ORIG_VIDEO_LINES * vga_default_font_height/
+		c->vc_font.height;
 	/*
 	 * We need to save screen size here as it's the only way
 	 * we can spot the screen has been resized and we need to
@@ -566,10 +584,11 @@
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 				vga_vram_size : c->vc_screenbuf_size);
-		if (!(vga_video_num_columns % 2) &&
-		    vga_video_num_columns <= ORIG_VIDEO_COLS &&
-		    vga_video_num_lines <= (ORIG_VIDEO_LINES *
-			vga_default_font_height) / c->vc_font.height)
+
+		if ((vgacon_xres != x || vgacon_yres != y) &&
+		    (!(vga_video_num_columns % 2) &&
+		     vga_video_num_columns <= ORIG_VIDEO_COLS &&
+		     vga_video_num_lines <= rows))
 			vgacon_doresize(c, c->vc_cols, c->vc_rows);
 	}
 
@@ -993,7 +1012,8 @@
 	if (vga_video_type < VIDEO_TYPE_EGAM)
 		return -EINVAL;
 
-	if (font->width != 8 || (charcount != 256 && charcount != 512))
+	if (font->width != VGA_FONTWIDTH ||
+	    (charcount != 256 && charcount != 512))
 		return -EINVAL;
 
 	rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512);
@@ -1010,7 +1030,7 @@
 	if (vga_video_type < VIDEO_TYPE_EGAM)
 		return -EINVAL;
 
-	font->width = 8;
+	font->width = VGA_FONTWIDTH;
 	font->height = c->vc_font.height;
 	font->charcount = vga_512_chars ? 512 : 256;
 	if (!font->data)
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index c589d23..a9300f9 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1512,7 +1512,7 @@
 	 * I/O cycles storing into a reserved memory space at
 	 * physical address 0x3000000
 	 */
-	unsigned char *iop;
+	unsigned char __iomem *iop;
 
 	iop = ioremap(0x3000000, 0x5000);
 	if (iop == NULL) {
@@ -1526,7 +1526,7 @@
 	writeb(EXT_BIU_MISC, iop + 0x3ce);
 	writeb(EXT_BIU_MISC_LIN_ENABLE, iop + 0x3cf);
 
-	iounmap((void *)iop);
+	iounmap(iop);
 #else
 	/*
 	 * Most other machine types are "normal", so
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 6240aed..10dfdf0 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -722,14 +722,30 @@
 int
 fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
 {
+	struct fb_fix_screeninfo *fix = &info->fix;
         int xoffset = var->xoffset;
         int yoffset = var->yoffset;
-        int err;
+        int err = 0, yres = info->var.yres;
 
-        if (xoffset < 0 || yoffset < 0 || !info->fbops->fb_pan_display ||
-            xoffset + info->var.xres > info->var.xres_virtual ||
-            yoffset + info->var.yres > info->var.yres_virtual)
-                return -EINVAL;
+	if (var->yoffset > 0) {
+		if (var->vmode & FB_VMODE_YWRAP) {
+			if (!fix->ywrapstep || (var->yoffset % fix->ywrapstep))
+				err = -EINVAL;
+			else
+				yres = 0;
+		} else if (!fix->ypanstep || (var->yoffset % fix->ypanstep))
+			err = -EINVAL;
+	}
+
+	if (var->xoffset > 0 && (!fix->xpanstep ||
+				 (var->xoffset % fix->xpanstep)))
+		err = -EINVAL;
+
+        if (err || !info->fbops->fb_pan_display || xoffset < 0 ||
+	    yoffset < 0 || var->yoffset + yres > info->var.yres_virtual ||
+	    var->xoffset + info->var.xres > info->var.xres_virtual)
+		return -EINVAL;
+
 	if ((err = info->fbops->fb_pan_display(var, info)))
 		return err;
         info->var.xoffset = var->xoffset;
diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c
index 2584dae..c4870d5 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/ffb.c
@@ -359,7 +359,6 @@
 	int			prom_parent_node;
 	int			dac_rev;
 	int			board_type;
-	struct list_head	list;
 };
 
 static void FFBFifo(struct ffb_par *par, int n)
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 5924cc2..1718baa 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -554,7 +554,7 @@
 
 	inf = pdev->dev.platform_data;
 	if(!inf) {
-		dev_err(dev,"No platform_data available\n");
+		dev_err(&pdev->dev,"No platform_data available\n");
 		return -ENOMEM;
 	}
 
@@ -579,7 +579,7 @@
 	if (!inf->fixed_screen_cpu) {
 		ret = imxfb_map_video_memory(info);
 		if (ret) {
-			dev_err(dev, "Failed to allocate video RAM: %d\n", ret);
+			dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
 			ret = -ENOMEM;
 			goto failed_map;
 		}
@@ -608,7 +608,7 @@
 	imxfb_set_par(info);
 	ret = register_framebuffer(info);
 	if (ret < 0) {
-		dev_err(dev, "failed to register framebuffer\n");
+		dev_err(&pdev->dev, "failed to register framebuffer\n");
 		goto failed_register;
 	}
 
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index f077ca3..da29d00 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -41,6 +41,10 @@
 
 /*** hw-related values ***/
 
+/* Resource Allocation */
+#define INTELFB_FB_ACQUIRED                 1
+#define INTELFB_MMIO_ACQUIRED               2
+
 /* PCI ids for supported devices */
 #define PCI_DEVICE_ID_INTEL_830M	0x3577
 #define PCI_DEVICE_ID_INTEL_845G	0x2562
@@ -257,6 +261,7 @@
 	int hwcursor;
 	int fixed_mode;
 	int ring_active;
+	int flag;
 
 	/* hw cursor */
 	int cursor_on;
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 427689e..0090544 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -135,9 +135,6 @@
 static void __devinit get_initial_mode(struct intelfb_info *dinfo);
 static void update_dinfo(struct intelfb_info *dinfo,
 			 struct fb_var_screeninfo *var);
-static int intelfb_get_fix(struct fb_fix_screeninfo *fix,
-			   struct fb_info *info);
-
 static int intelfb_check_var(struct fb_var_screeninfo *var,
 			     struct fb_info *info);
 static int intelfb_set_par(struct fb_info *info);
@@ -473,9 +470,9 @@
 	if (dinfo->aperture.virtual)
 		iounmap((void __iomem *)dinfo->aperture.virtual);
 
-	if (dinfo->mmio_base_phys)
+	if (dinfo->flag & INTELFB_MMIO_ACQUIRED)
 		release_mem_region(dinfo->mmio_base_phys, INTEL_REG_SIZE);
-	if (dinfo->aperture.physical)
+	if (dinfo->flag & INTELFB_FB_ACQUIRED)
 		release_mem_region(dinfo->aperture.physical,
 				   dinfo->aperture.size);
 	framebuffer_release(dinfo->info);
@@ -572,6 +569,9 @@
 		cleanup(dinfo);
 		return -ENODEV;
 	}
+
+	dinfo->flag |= INTELFB_FB_ACQUIRED;
+
 	if (!request_mem_region(dinfo->mmio_base_phys,
 				INTEL_REG_SIZE,
 				INTELFB_MODULE_NAME)) {
@@ -580,6 +580,8 @@
 		return -ENODEV;
 	}
 
+	dinfo->flag |= INTELFB_MMIO_ACQUIRED;
+
 	/* Get the chipset info. */
 	dinfo->pci_chipset = pdev->device;
 
@@ -1091,7 +1093,17 @@
 		return 1;
 
 	info->pixmap.scan_align = 1;
-
+	strcpy(info->fix.id, dinfo->name);
+	info->fix.smem_start = dinfo->fb.physical;
+	info->fix.smem_len = dinfo->fb.size;
+	info->fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fix.type_aux = 0;
+	info->fix.xpanstep = 8;
+	info->fix.ypanstep = 1;
+	info->fix.ywrapstep = 0;
+	info->fix.mmio_start = dinfo->mmio_base_phys;
+	info->fix.mmio_len = INTEL_REG_SIZE;
+	info->fix.accel = FB_ACCEL_I830;
 	update_dinfo(dinfo, &info->var);
 
 	return 0;
@@ -1109,7 +1121,8 @@
 	dinfo->yres = var->xres;
 	dinfo->pixclock = var->pixclock;
 
-	intelfb_get_fix(&dinfo->info->fix, dinfo->info);
+	dinfo->info->fix.visual = dinfo->visual;
+	dinfo->info->fix.line_length = dinfo->pitch;
 
 	switch (dinfo->bpp) {
 	case 8:
@@ -1139,30 +1152,6 @@
 
 /* fbops functions */
 
-static int
-intelfb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
-{
-	struct intelfb_info *dinfo = GET_DINFO(info);
-
-	DBG_MSG("intelfb_get_fix\n");
-
-	memset(fix, 0, sizeof(*fix));
-	strcpy(fix->id, dinfo->name);
-	fix->smem_start = dinfo->fb.physical;
-	fix->smem_len = dinfo->fb.size;
-	fix->type = FB_TYPE_PACKED_PIXELS;
-	fix->type_aux = 0;
-	fix->visual = dinfo->visual;
-	fix->xpanstep = 8;
-	fix->ypanstep = 1;
-	fix->ywrapstep = 0;
-	fix->line_length = dinfo->pitch;
-	fix->mmio_start = dinfo->mmio_base_phys;
-	fix->mmio_len = INTEL_REG_SIZE;
-	fix->accel = FB_ACCEL_I830;
-	return 0;
-}
-
 /***************************************************************
  *                       fbdev interface                       *
  ***************************************************************/
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 376d4a1..494287f 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -197,7 +197,6 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
-	struct list_head	list;
 };
 
 static void leo_wait(struct leo_lx_krn __iomem *lx_krn)
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index 8cb7fb4..f0e6512 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -47,7 +47,7 @@
 
 config LOGO_SUN_CLUT224
 	bool "224-color Sun Linux logo"
-	depends on LOGO && (SPARC32 || SPARC64)
+	depends on LOGO && SPARC
 	default y
 
 config LOGO_SUPERH_MONO
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index ad60bbb..a1f2c5e 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -1288,18 +1288,13 @@
 	return 0;
 }
 
-static int maven_command(struct i2c_client* client, unsigned int cmd, void* arg) {
-	return -ENOIOCTLCMD;	/* or -EINVAL, depends on who will call this */
-}
-
 static struct i2c_driver maven_driver={
-	.owner		= THIS_MODULE,
-	.name		= "maven",
+	.driver = {
+		.name	= "maven",
+	},
 	.id		= I2C_DRIVERID_MGATVO,
-	.flags		= I2C_DF_NOTIFY,
 	.attach_adapter	= maven_attach_adapter,
 	.detach_client	= maven_detach_client,
-	.command	= maven_command,
 };
 
 /* ************************** */
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 18bcda2..b251e75 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -140,7 +140,6 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
-	struct list_head	list;
 };
 
 /**
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 7b4cd25..9fc10b9 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1396,7 +1396,8 @@
 int __devinit pxafb_setup(char *options)
 {
 # ifdef CONFIG_FB_PXA_PARAMETERS
-	strlcpy(g_options, options, sizeof(g_options));
+	if (options)
+		strlcpy(g_options, options, sizeof(g_options));
 # endif
 	return 0;
 }
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index ce6e749..fe99d17 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -87,6 +87,7 @@
 #include <linux/workqueue.h>
 #include <linux/wait.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -96,7 +97,6 @@
 #include <asm/arch/regs-lcd.h>
 #include <asm/arch/regs-gpio.h>
 #include <asm/arch/fb.h>
-#include <asm/hardware/clock.h>
 
 #ifdef CONFIG_PM
 #include <linux/pm.h>
@@ -746,7 +746,6 @@
 		goto release_irq;
 	}
 
-	clk_use(info->clk);
 	clk_enable(info->clk);
 	dprintk("got and enabled clock\n");
 
@@ -783,7 +782,6 @@
 	s3c2410fb_unmap_video_memory(info);
 release_clock:
 	clk_disable(info->clk);
-	clk_unuse(info->clk);
 	clk_put(info->clk);
 release_irq:
 	free_irq(irq,info);
@@ -828,7 +826,6 @@
 
  	if (info->clk) {
  		clk_disable(info->clk);
- 		clk_unuse(info->clk);
  		clk_put(info->clk);
  		info->clk = NULL;
 	}
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 646c43f..3a74a63d 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -46,6 +46,9 @@
 	unsigned long off;
 	int i;
                                         
+	if (!(vma->vm_flags & (VM_SHARED | VM_MAYSHARE)))
+		return -EINVAL;
+
 	size = vma->vm_end - vma->vm_start;
 	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
 		return -EINVAL;
diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c
index fe4f63f..2b27b44 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/tcx.c
@@ -125,7 +125,6 @@
 	int			lowdepth;
 
 	struct sbus_dev		*sdev;
-	struct list_head	list;
 };
 
 /* Reset control plane so that WID is 8-bit plane. */
@@ -444,7 +443,7 @@
 
 	tcx_reset(&all->info);
 
-	tcx_blank(0, &all->info);
+	tcx_blank(FB_BLANK_UNBLANK, &all->info);
 
 	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
 		printk(KERN_ERR "tcx: Could not allocate color map.\n");
diff --git a/drivers/w1/dscore.c b/drivers/w1/dscore.c
index 15fb250..b914630 100644
--- a/drivers/w1/dscore.c
+++ b/drivers/w1/dscore.c
@@ -52,7 +52,6 @@
 
 
 static struct usb_driver ds_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"DS9490R",
 	.probe =	ds_probe,
 	.disconnect =	ds_disconnect,
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 14016b1..024206c 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -142,12 +142,12 @@
 /* Default family */
 static struct w1_family w1_default_family;
 
-static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
+static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
 
 static struct bus_type w1_bus_type = {
 	.name = "w1",
 	.match = w1_master_match,
-	.hotplug = w1_hotplug,
+	.uevent = w1_uevent,
 };
 
 struct device_driver w1_master_driver = {
@@ -361,7 +361,7 @@
 }
 
 #ifdef CONFIG_HOTPLUG
-static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
 {
 	struct w1_master *md = NULL;
 	struct w1_slave *sl = NULL;
@@ -377,7 +377,7 @@
 		event_owner = "slave";
 		name = sl->name;
 	} else {
-		dev_dbg(dev, "Unknown hotplug event.\n");
+		dev_dbg(dev, "Unknown event.\n");
 		return -EINVAL;
 	}
 
@@ -386,18 +386,18 @@
 	if (dev->driver != &w1_slave_driver || !sl)
 		return 0;
 
-	err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family);
+	err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family);
 	if (err)
 		return err;
 
-	err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id);
+	err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id);
 	if (err)
 		return err;
 
 	return 0;
 };
 #else
-static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
+static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
 {
 	return 0;
 }
diff --git a/fs/9p/9p.c b/fs/9p/9p.c
index e847f50..1a6d087 100644
--- a/fs/9p/9p.c
+++ b/fs/9p/9p.c
@@ -1,8 +1,9 @@
 /*
  *  linux/fs/9p/9p.c
  *
- *  This file contains functions 9P2000 functions
+ *  This file contains functions to perform synchronous 9P calls
  *
+ *  Copyright (C) 2004 by Latchesar Ionkov <lucho@ionkov.net>
  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
  *
@@ -33,6 +34,7 @@
 #include "debug.h"
 #include "v9fs.h"
 #include "9p.h"
+#include "conv.h"
 #include "mux.h"
 
 /**
@@ -46,16 +48,21 @@
 
 int
 v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
-	       char *version, struct v9fs_fcall **fcall)
+	       char *version, struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
+	int ret;
+	struct v9fs_fcall *tc;
 
 	dprintk(DEBUG_9P, "msize: %d version: %s\n", msize, version);
-	msg.id = TVERSION;
-	msg.params.tversion.msize = msize;
-	msg.params.tversion.version = version;
+	tc = v9fs_create_tversion(msize, version);
 
-	return v9fs_mux_rpc(v9ses, &msg, fcall);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
+
+	return ret;
 }
 
 /**
@@ -71,19 +78,45 @@
 
 int
 v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
-	      u32 fid, u32 afid, struct v9fs_fcall **fcall)
+	      u32 fid, u32 afid, struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
+	int ret;
+	struct v9fs_fcall* tc;
 
 	dprintk(DEBUG_9P, "uname '%s' aname '%s' fid %d afid %d\n", uname,
 		aname, fid, afid);
-	msg.id = TATTACH;
-	msg.params.tattach.fid = fid;
-	msg.params.tattach.afid = afid;
-	msg.params.tattach.uname = uname;
-	msg.params.tattach.aname = aname;
 
-	return v9fs_mux_rpc(v9ses, &msg, fcall);
+	tc = v9fs_create_tattach(fid, afid, uname, aname);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
+
+	return ret;
+}
+
+static void v9fs_t_clunk_cb(void *a, struct v9fs_fcall *tc,
+	struct v9fs_fcall *rc, int err)
+{
+	int fid;
+	struct v9fs_session_info *v9ses;
+
+	if (err)
+		return;
+
+	fid = tc->params.tclunk.fid;
+	kfree(tc);
+
+	if (!rc)
+		return;
+
+	dprintk(DEBUG_9P, "tcall id %d rcall id %d\n", tc->id, rc->id);
+	v9ses = a;
+	if (rc->id == RCLUNK)
+		v9fs_put_idpool(fid, &v9ses->fidpool);
+
+	kfree(rc);
 }
 
 /**
@@ -95,16 +128,25 @@
  */
 
 int
-v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid,
-	     struct v9fs_fcall **fcall)
+v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid)
 {
-	struct v9fs_fcall msg;
+	int ret;
+	struct v9fs_fcall *tc, *rc;
 
 	dprintk(DEBUG_9P, "fid %d\n", fid);
-	msg.id = TCLUNK;
-	msg.params.tclunk.fid = fid;
 
-	return v9fs_mux_rpc(v9ses, &msg, fcall);
+	rc = NULL;
+	tc = v9fs_create_tclunk(fid);
+	if (!IS_ERR(tc))
+		ret = v9fs_mux_rpc(v9ses->mux, tc, &rc);
+	else
+		ret = PTR_ERR(tc);
+
+	if (ret)
+		dprintk(DEBUG_ERROR, "failed fid %d err %d\n", fid, ret);
+
+	v9fs_t_clunk_cb(v9ses, tc, rc, ret);
+	return ret;
 }
 
 /**
@@ -114,14 +156,21 @@
  *
  */
 
-int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 tag)
+int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag)
 {
-	struct v9fs_fcall msg;
+	int ret;
+	struct v9fs_fcall *tc;
 
-	dprintk(DEBUG_9P, "oldtag %d\n", tag);
-	msg.id = TFLUSH;
-	msg.params.tflush.oldtag = tag;
-	return v9fs_mux_rpc(v9ses, &msg, NULL);
+	dprintk(DEBUG_9P, "oldtag %d\n", oldtag);
+
+	tc = v9fs_create_tflush(oldtag);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, NULL);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
+
+	return ret;
 }
 
 /**
@@ -133,17 +182,22 @@
  */
 
 int
-v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **fcall)
+v9fs_t_stat(struct v9fs_session_info *v9ses, u32 fid, struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
+	int ret;
+	struct v9fs_fcall *tc;
 
 	dprintk(DEBUG_9P, "fid %d\n", fid);
-	if (fcall)
-		*fcall = NULL;
 
-	msg.id = TSTAT;
-	msg.params.tstat.fid = fid;
-	return v9fs_mux_rpc(v9ses, &msg, fcall);
+	ret = -ENOMEM;
+	tc = v9fs_create_tstat(fid);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
+
+	return ret;
 }
 
 /**
@@ -157,16 +211,21 @@
 
 int
 v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
-	     struct v9fs_stat *stat, struct v9fs_fcall **fcall)
+	     struct v9fs_wstat *wstat, struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
+	int ret;
+	struct v9fs_fcall *tc;
 
-	dprintk(DEBUG_9P, "fid %d length %d\n", fid, (int)stat->length);
-	msg.id = TWSTAT;
-	msg.params.twstat.fid = fid;
-	msg.params.twstat.stat = stat;
+	dprintk(DEBUG_9P, "fid %d\n", fid);
 
-	return v9fs_mux_rpc(v9ses, &msg, fcall);
+	tc = v9fs_create_twstat(fid, wstat, v9ses->extended);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
+
+	return ret;
 }
 
 /**
@@ -183,23 +242,27 @@
 
 int
 v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
-	    char *name, struct v9fs_fcall **fcall)
+	    char *name, struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
+	int ret;
+	struct v9fs_fcall *tc;
+	int nwname;
 
 	dprintk(DEBUG_9P, "fid %d newfid %d wname '%s'\n", fid, newfid, name);
-	msg.id = TWALK;
-	msg.params.twalk.fid = fid;
-	msg.params.twalk.newfid = newfid;
 
-	if (name) {
-		msg.params.twalk.nwname = 1;
-		msg.params.twalk.wnames = &name;
-	} else {
-		msg.params.twalk.nwname = 0;
-	}
+	if (name)
+		nwname = 1;
+	else
+		nwname = 0;
 
-	return v9fs_mux_rpc(v9ses, &msg, fcall);
+	tc = v9fs_create_twalk(fid, newfid, nwname, &name);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
+
+	return ret;
 }
 
 /**
@@ -214,19 +277,21 @@
 
 int
 v9fs_t_open(struct v9fs_session_info *v9ses, u32 fid, u8 mode,
-	    struct v9fs_fcall **fcall)
+	    struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
-	long errorno = -1;
+	int ret;
+	struct v9fs_fcall *tc;
 
 	dprintk(DEBUG_9P, "fid %d mode %d\n", fid, mode);
-	msg.id = TOPEN;
-	msg.params.topen.fid = fid;
-	msg.params.topen.mode = mode;
 
-	errorno = v9fs_mux_rpc(v9ses, &msg, fcall);
+	tc = v9fs_create_topen(fid, mode);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
 
-	return errorno;
+	return ret;
 }
 
 /**
@@ -239,14 +304,21 @@
 
 int
 v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
-	      struct v9fs_fcall **fcall)
+	      struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
+	int ret;
+	struct v9fs_fcall *tc;
 
 	dprintk(DEBUG_9P, "fid %d\n", fid);
-	msg.id = TREMOVE;
-	msg.params.tremove.fid = fid;
-	return v9fs_mux_rpc(v9ses, &msg, fcall);
+
+	tc = v9fs_create_tremove(fid);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
+
+	return ret;
 }
 
 /**
@@ -262,20 +334,22 @@
 
 int
 v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
-	      u32 perm, u8 mode, struct v9fs_fcall **fcall)
+	      u32 perm, u8 mode, struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
+	int ret;
+	struct v9fs_fcall *tc;
 
 	dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n",
 		fid, name, perm, mode);
 
-	msg.id = TCREATE;
-	msg.params.tcreate.fid = fid;
-	msg.params.tcreate.name = name;
-	msg.params.tcreate.perm = perm;
-	msg.params.tcreate.mode = mode;
+	tc = v9fs_create_tcreate(fid, name, perm, mode);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
 
-	return v9fs_mux_rpc(v9ses, &msg, fcall);
+	return ret;
 }
 
 /**
@@ -290,31 +364,29 @@
 
 int
 v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
-	    u32 count, struct v9fs_fcall **fcall)
+	    u32 count, struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
-	struct v9fs_fcall *rc = NULL;
-	long errorno = -1;
+	int ret;
+	struct v9fs_fcall *tc, *rc;
 
-	dprintk(DEBUG_9P, "fid %d offset 0x%lx count 0x%x\n", fid,
-		(long unsigned int)offset, count);
-	msg.id = TREAD;
-	msg.params.tread.fid = fid;
-	msg.params.tread.offset = offset;
-	msg.params.tread.count = count;
-	errorno = v9fs_mux_rpc(v9ses, &msg, &rc);
+	dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid,
+		(long long unsigned) offset, count);
 
-	if (!errorno) {
-		errorno = rc->params.rread.count;
-		dump_data(rc->params.rread.data, rc->params.rread.count);
-	}
+	tc = v9fs_create_tread(fid, offset, count);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, &rc);
+		if (!ret)
+			ret = rc->params.rread.count;
+		if (rcp)
+			*rcp = rc;
+		else
+			kfree(rc);
 
-	if (fcall)
-		*fcall = rc;
-	else
-		kfree(rc);
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
 
-	return errorno;
+	return ret;
 }
 
 /**
@@ -328,32 +400,30 @@
  */
 
 int
-v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid,
-	     u64 offset, u32 count, void *data, struct v9fs_fcall **fcall)
+v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, u32 count,
+	const char __user *data, struct v9fs_fcall **rcp)
 {
-	struct v9fs_fcall msg;
-	struct v9fs_fcall *rc = NULL;
-	long errorno = -1;
+	int ret;
+	struct v9fs_fcall *tc, *rc;
 
-	dprintk(DEBUG_9P, "fid %d offset 0x%llx count 0x%x\n", fid,
-		(unsigned long long)offset, count);
-	dump_data(data, count);
+	dprintk(DEBUG_9P, "fid %d offset 0x%llux count 0x%x\n", fid,
+		(long long unsigned) offset, count);
 
-	msg.id = TWRITE;
-	msg.params.twrite.fid = fid;
-	msg.params.twrite.offset = offset;
-	msg.params.twrite.count = count;
-	msg.params.twrite.data = data;
+	tc = v9fs_create_twrite(fid, offset, count, data);
+	if (!IS_ERR(tc)) {
+		ret = v9fs_mux_rpc(v9ses->mux, tc, &rc);
 
-	errorno = v9fs_mux_rpc(v9ses, &msg, &rc);
+		if (!ret)
+			ret = rc->params.rwrite.count;
+		if (rcp)
+			*rcp = rc;
+		else
+			kfree(rc);
 
-	if (!errorno)
-		errorno = rc->params.rwrite.count;
+		kfree(tc);
+	} else
+		ret = PTR_ERR(tc);
 
-	if (fcall)
-		*fcall = rc;
-	else
-		kfree(rc);
-
-	return errorno;
+	return ret;
 }
+
diff --git a/fs/9p/9p.h b/fs/9p/9p.h
index f554242..0cd374d 100644
--- a/fs/9p/9p.h
+++ b/fs/9p/9p.h
@@ -3,6 +3,7 @@
  *
  * 9P protocol definitions.
  *
+ *  Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
  *
@@ -100,9 +101,18 @@
 	V9FS_QTFILE = 0x00,
 };
 
+#define V9FS_NOTAG	(u16)(~0)
+#define V9FS_NOFID	(u32)(~0)
+#define V9FS_MAXWELEM	16
+
 /* ample room for Twrite/Rread header (iounit) */
 #define V9FS_IOHDRSZ	24
 
+struct v9fs_str {
+	u16 len;
+	char *str;
+};
+
 /* qids are the unique ID for a file (like an inode */
 struct v9fs_qid {
 	u8 type;
@@ -120,6 +130,29 @@
 	u32 atime;
 	u32 mtime;
 	u64 length;
+	struct v9fs_str name;
+	struct v9fs_str uid;
+	struct v9fs_str gid;
+	struct v9fs_str muid;
+	struct v9fs_str extension;	/* 9p2000.u extensions */
+	u32 n_uid;		/* 9p2000.u extensions */
+	u32 n_gid;		/* 9p2000.u extensions */
+	u32 n_muid;		/* 9p2000.u extensions */
+};
+
+/* file metadata (stat) structure used to create Twstat message
+   The is similar to v9fs_stat, but the strings don't point to
+   the same memory block and should be freed separately
+*/
+struct v9fs_wstat {
+	u16 size;
+	u16 type;
+	u32 dev;
+	struct v9fs_qid qid;
+	u32 mode;
+	u32 atime;
+	u32 mtime;
+	u64 length;
 	char *name;
 	char *uid;
 	char *gid;
@@ -128,25 +161,24 @@
 	u32 n_uid;		/* 9p2000.u extensions */
 	u32 n_gid;		/* 9p2000.u extensions */
 	u32 n_muid;		/* 9p2000.u extensions */
-	char data[0];
 };
 
 /* Structures for Protocol Operations */
 
 struct Tversion {
 	u32 msize;
-	char *version;
+	struct v9fs_str version;
 };
 
 struct Rversion {
 	u32 msize;
-	char *version;
+	struct v9fs_str version;
 };
 
 struct Tauth {
 	u32 afid;
-	char *uname;
-	char *aname;
+	struct v9fs_str uname;
+	struct v9fs_str aname;
 };
 
 struct Rauth {
@@ -154,12 +186,12 @@
 };
 
 struct Rerror {
-	char *error;
+	struct v9fs_str error;
 	u32 errno;		/* 9p2000.u extension */
 };
 
 struct Tflush {
-	u32 oldtag;
+	u16 oldtag;
 };
 
 struct Rflush {
@@ -168,8 +200,8 @@
 struct Tattach {
 	u32 fid;
 	u32 afid;
-	char *uname;
-	char *aname;
+	struct v9fs_str uname;
+	struct v9fs_str aname;
 };
 
 struct Rattach {
@@ -179,13 +211,13 @@
 struct Twalk {
 	u32 fid;
 	u32 newfid;
-	u32 nwname;
-	char **wnames;
+	u16 nwname;
+	struct v9fs_str wnames[16];
 };
 
 struct Rwalk {
-	u32 nwqid;
-	struct v9fs_qid *wqids;
+	u16 nwqid;
+	struct v9fs_qid wqids[16];
 };
 
 struct Topen {
@@ -200,7 +232,7 @@
 
 struct Tcreate {
 	u32 fid;
-	char *name;
+	struct v9fs_str name;
 	u32 perm;
 	u8 mode;
 };
@@ -251,12 +283,12 @@
 };
 
 struct Rstat {
-	struct v9fs_stat *stat;
+	struct v9fs_stat stat;
 };
 
 struct Twstat {
 	u32 fid;
-	struct v9fs_stat *stat;
+	struct v9fs_stat stat;
 };
 
 struct Rwstat {
@@ -271,6 +303,7 @@
 	u32 size;
 	u8 id;
 	u16 tag;
+	void *sdata;
 
 	union {
 		struct Tversion tversion;
@@ -303,7 +336,9 @@
 	} params;
 };
 
-#define FCALL_ERROR(fcall) (fcall ? fcall->params.rerror.error : "")
+#define PRINT_FCALL_ERROR(s, fcall) dprintk(DEBUG_ERROR, "%s: %.*s\n", s, \
+	fcall?fcall->params.rerror.error.len:0, \
+	fcall?fcall->params.rerror.error.str:"");
 
 int v9fs_t_version(struct v9fs_session_info *v9ses, u32 msize,
 		   char *version, struct v9fs_fcall **rcall);
@@ -311,8 +346,7 @@
 int v9fs_t_attach(struct v9fs_session_info *v9ses, char *uname, char *aname,
 		  u32 fid, u32 afid, struct v9fs_fcall **rcall);
 
-int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid,
-		 struct v9fs_fcall **rcall);
+int v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid);
 
 int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag);
 
@@ -320,7 +354,7 @@
 		struct v9fs_fcall **rcall);
 
 int v9fs_t_wstat(struct v9fs_session_info *v9ses, u32 fid,
-		 struct v9fs_stat *stat, struct v9fs_fcall **rcall);
+		 struct v9fs_wstat *wstat, struct v9fs_fcall **rcall);
 
 int v9fs_t_walk(struct v9fs_session_info *v9ses, u32 fid, u32 newfid,
 		char *name, struct v9fs_fcall **rcall);
@@ -338,4 +372,5 @@
 		u64 offset, u32 count, struct v9fs_fcall **rcall);
 
 int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
-		 u32 count, void *data, struct v9fs_fcall **rcall);
+		 u32 count, const char __user * data,
+		 struct v9fs_fcall **rcall);
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
index e4e4ffe..3d02308 100644
--- a/fs/9p/Makefile
+++ b/fs/9p/Makefile
@@ -1,17 +1,17 @@
 obj-$(CONFIG_9P_FS) := 9p2000.o
 
 9p2000-objs := \
+	trans_fd.o \
+	trans_sock.o \
+	mux.o \
+	9p.o \
+	conv.o \
 	vfs_super.o \
 	vfs_inode.o \
 	vfs_file.o \
 	vfs_dir.o \
 	vfs_dentry.o \
 	error.o \
-	mux.o \
-	trans_fd.o \
-	trans_sock.o \
-	9p.o \
-	conv.o \
 	v9fs.o \
 	fid.o
 
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index 18121af..55ccfa1 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -30,7 +30,7 @@
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/idr.h>
-
+#include <asm/uaccess.h>
 #include "debug.h"
 #include "v9fs.h"
 #include "9p.h"
@@ -58,12 +58,15 @@
 
 static inline int buf_check_size(struct cbuf *buf, int len)
 {
-	if (buf->p+len > buf->ep) {
+	if (buf->p + len > buf->ep) {
 		if (buf->p < buf->ep) {
-			eprintk(KERN_ERR, "buffer overflow\n");
+			eprintk(KERN_ERR, "buffer overflow: want %d has %d\n",
+				len, (int)(buf->ep - buf->p));
+			dump_stack();
 			buf->p = buf->ep + 1;
-			return 0;
 		}
+
+		return 0;
 	}
 
 	return 1;
@@ -127,14 +130,6 @@
 	buf_put_stringn(buf, s, strlen(s));
 }
 
-static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen)
-{
-	if (buf_check_size(buf, datalen)) {
-		memcpy(buf->p, data, datalen);
-		buf->p += datalen;
-	}
-}
-
 static inline u8 buf_get_int8(struct cbuf *buf)
 {
 	u8 ret = 0;
@@ -183,86 +178,37 @@
 	return ret;
 }
 
-static inline int
-buf_get_string(struct cbuf *buf, char *data, unsigned int datalen)
+static inline void buf_get_str(struct cbuf *buf, struct v9fs_str *vstr)
 {
-	u16 len = 0;
-
-	len = buf_get_int16(buf);
-	if (!buf_check_overflow(buf) && buf_check_size(buf, len) && len+1>datalen) {
-		memcpy(data, buf->p, len);
-		data[len] = 0;
-		buf->p += len;
-		len++;
+	vstr->len = buf_get_int16(buf);
+	if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) {
+		vstr->str = buf->p;
+		buf->p += vstr->len;
+	} else {
+		vstr->len = 0;
+		vstr->str = NULL;
 	}
-
-	return len;
 }
 
-static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
+static inline void buf_get_qid(struct cbuf *bufp, struct v9fs_qid *qid)
 {
-	char *ret;
-	u16 len;
-
-	ret = NULL;
-	len = buf_get_int16(buf);
-
-	if (!buf_check_overflow(buf) && buf_check_size(buf, len) &&
-		buf_check_size(sbuf, len+1)) {
-
-		memcpy(sbuf->p, buf->p, len);
-		sbuf->p[len] = 0;
-		ret = sbuf->p;
-		buf->p += len;
-		sbuf->p += len + 1;
-	}
-
-	return ret;
-}
-
-static inline int buf_get_data(struct cbuf *buf, void *data, int datalen)
-{
-	int ret = 0;
-
-	if (buf_check_size(buf, datalen)) {
-		memcpy(data, buf->p, datalen);
-		buf->p += datalen;
-		ret = datalen;
-	}
-
-	return ret;
-}
-
-static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf,
-				  int datalen)
-{
-	char *ret = NULL;
-	int n = 0;
-
-	if (buf_check_size(dbuf, datalen)) {
-		n = buf_get_data(buf, dbuf->p, datalen);
-		if (n > 0) {
-			ret = dbuf->p;
-			dbuf->p += n;
-		}
-	}
-
-	return ret;
+	qid->type = buf_get_int8(bufp);
+	qid->version = buf_get_int32(bufp);
+	qid->path = buf_get_int64(bufp);
 }
 
 /**
- * v9fs_size_stat - calculate the size of a variable length stat struct
- * @v9ses: session information
+ * v9fs_size_wstat - calculate the size of a variable length stat struct
  * @stat: metadata (stat) structure
+ * @extended: non-zero if 9P2000.u
  *
  */
 
-static int v9fs_size_stat(struct v9fs_session_info *v9ses,
-			  struct v9fs_stat *stat)
+static int v9fs_size_wstat(struct v9fs_wstat *wstat, int extended)
 {
 	int size = 0;
 
-	if (stat == NULL) {
+	if (wstat == NULL) {
 		eprintk(KERN_ERR, "v9fs_size_stat: got a NULL stat pointer\n");
 		return 0;
 	}
@@ -279,82 +225,38 @@
 	    8 +			/* length[8] */
 	    8;			/* minimum sum of string lengths */
 
-	if (stat->name)
-		size += strlen(stat->name);
-	if (stat->uid)
-		size += strlen(stat->uid);
-	if (stat->gid)
-		size += strlen(stat->gid);
-	if (stat->muid)
-		size += strlen(stat->muid);
+	if (wstat->name)
+		size += strlen(wstat->name);
+	if (wstat->uid)
+		size += strlen(wstat->uid);
+	if (wstat->gid)
+		size += strlen(wstat->gid);
+	if (wstat->muid)
+		size += strlen(wstat->muid);
 
-	if (v9ses->extended) {
+	if (extended) {
 		size += 4 +	/* n_uid[4] */
 		    4 +		/* n_gid[4] */
 		    4 +		/* n_muid[4] */
 		    2;		/* string length of extension[4] */
-		if (stat->extension)
-			size += strlen(stat->extension);
+		if (wstat->extension)
+			size += strlen(wstat->extension);
 	}
 
 	return size;
 }
 
 /**
- * serialize_stat - safely format a stat structure for transmission
- * @v9ses: session info
- * @stat: metadata (stat) structure
- * @bufp: buffer to serialize structure into
- *
- */
-
-static int
-serialize_stat(struct v9fs_session_info *v9ses, struct v9fs_stat *stat,
-	       struct cbuf *bufp)
-{
-	buf_put_int16(bufp, stat->size);
-	buf_put_int16(bufp, stat->type);
-	buf_put_int32(bufp, stat->dev);
-	buf_put_int8(bufp, stat->qid.type);
-	buf_put_int32(bufp, stat->qid.version);
-	buf_put_int64(bufp, stat->qid.path);
-	buf_put_int32(bufp, stat->mode);
-	buf_put_int32(bufp, stat->atime);
-	buf_put_int32(bufp, stat->mtime);
-	buf_put_int64(bufp, stat->length);
-
-	buf_put_string(bufp, stat->name);
-	buf_put_string(bufp, stat->uid);
-	buf_put_string(bufp, stat->gid);
-	buf_put_string(bufp, stat->muid);
-
-	if (v9ses->extended) {
-		buf_put_string(bufp, stat->extension);
-		buf_put_int32(bufp, stat->n_uid);
-		buf_put_int32(bufp, stat->n_gid);
-		buf_put_int32(bufp, stat->n_muid);
-	}
-
-	if (buf_check_overflow(bufp))
-		return 0;
-
-	return stat->size;
-}
-
-/**
- * deserialize_stat - safely decode a recieved metadata (stat) structure
- * @v9ses: session info
+ * buf_get_stat - safely decode a recieved metadata (stat) structure
  * @bufp: buffer to deserialize
  * @stat: metadata (stat) structure
- * @dbufp: buffer to deserialize variable strings into
+ * @extended: non-zero if 9P2000.u
  *
  */
 
-static inline int
-deserialize_stat(struct v9fs_session_info *v9ses, struct cbuf *bufp,
-		 struct v9fs_stat *stat, struct cbuf *dbufp)
+static inline void
+buf_get_stat(struct cbuf *bufp, struct v9fs_stat *stat, int extended)
 {
-
 	stat->size = buf_get_int16(bufp);
 	stat->type = buf_get_int16(bufp);
 	stat->dev = buf_get_int32(bufp);
@@ -365,282 +267,82 @@
 	stat->atime = buf_get_int32(bufp);
 	stat->mtime = buf_get_int32(bufp);
 	stat->length = buf_get_int64(bufp);
-	stat->name = buf_get_stringb(bufp, dbufp);
-	stat->uid = buf_get_stringb(bufp, dbufp);
-	stat->gid = buf_get_stringb(bufp, dbufp);
-	stat->muid = buf_get_stringb(bufp, dbufp);
+	buf_get_str(bufp, &stat->name);
+	buf_get_str(bufp, &stat->uid);
+	buf_get_str(bufp, &stat->gid);
+	buf_get_str(bufp, &stat->muid);
 
-	if (v9ses->extended) {
-		stat->extension = buf_get_stringb(bufp, dbufp);
+	if (extended) {
+		buf_get_str(bufp, &stat->extension);
 		stat->n_uid = buf_get_int32(bufp);
 		stat->n_gid = buf_get_int32(bufp);
 		stat->n_muid = buf_get_int32(bufp);
 	}
-
-	if (buf_check_overflow(bufp) || buf_check_overflow(dbufp))
-		return 0;
-
-	return stat->size + 2;
-}
-
-/**
- * deserialize_statb - wrapper for decoding a received metadata structure
- * @v9ses: session info
- * @bufp: buffer to deserialize
- * @dbufp: buffer to deserialize variable strings into
- *
- */
-
-static inline struct v9fs_stat *deserialize_statb(struct v9fs_session_info
-						  *v9ses, struct cbuf *bufp,
-						  struct cbuf *dbufp)
-{
-	struct v9fs_stat *ret = buf_alloc(dbufp, sizeof(struct v9fs_stat));
-
-	if (ret) {
-		int n = deserialize_stat(v9ses, bufp, ret, dbufp);
-		if (n <= 0)
-			return NULL;
-	}
-
-	return ret;
 }
 
 /**
  * v9fs_deserialize_stat - decode a received metadata structure
- * @v9ses: session info
  * @buf: buffer to deserialize
  * @buflen: length of received buffer
  * @stat: metadata structure to decode into
- * @statlen: length of destination metadata structure
+ * @extended: non-zero if 9P2000.u
  *
+ * Note: stat will point to the buf region.
  */
 
 int
-v9fs_deserialize_stat(struct v9fs_session_info *v9ses, void *buf,
-		      u32 buflen, struct v9fs_stat *stat, u32 statlen)
+v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat,
+		int extended)
 {
 	struct cbuf buffer;
 	struct cbuf *bufp = &buffer;
-	struct cbuf dbuffer;
-	struct cbuf *dbufp = &dbuffer;
+	unsigned char *p;
 
 	buf_init(bufp, buf, buflen);
-	buf_init(dbufp, (char *)stat + sizeof(struct v9fs_stat),
-		 statlen - sizeof(struct v9fs_stat));
-
-	return deserialize_stat(v9ses, bufp, stat, dbufp);
-}
-
-static inline int
-v9fs_size_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall)
-{
-	int size = 4 + 1 + 2;	/* size[4] msg[1] tag[2] */
-	int i = 0;
-
-	switch (fcall->id) {
-	default:
-		eprintk(KERN_ERR, "bad msg type %d\n", fcall->id);
-		return 0;
-	case TVERSION:		/* msize[4] version[s] */
-		size += 4 + 2 + strlen(fcall->params.tversion.version);
-		break;
-	case TAUTH:		/* afid[4] uname[s] aname[s] */
-		size += 4 + 2 + strlen(fcall->params.tauth.uname) +
-		    2 + strlen(fcall->params.tauth.aname);
-		break;
-	case TFLUSH:		/* oldtag[2] */
-		size += 2;
-		break;
-	case TATTACH:		/* fid[4] afid[4] uname[s] aname[s] */
-		size += 4 + 4 + 2 + strlen(fcall->params.tattach.uname) +
-		    2 + strlen(fcall->params.tattach.aname);
-		break;
-	case TWALK:		/* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
-		size += 4 + 4 + 2;
-		/* now compute total for the array of names */
-		for (i = 0; i < fcall->params.twalk.nwname; i++)
-			size += 2 + strlen(fcall->params.twalk.wnames[i]);
-		break;
-	case TOPEN:		/* fid[4] mode[1] */
-		size += 4 + 1;
-		break;
-	case TCREATE:		/* fid[4] name[s] perm[4] mode[1] */
-		size += 4 + 2 + strlen(fcall->params.tcreate.name) + 4 + 1;
-		break;
-	case TREAD:		/* fid[4] offset[8] count[4] */
-		size += 4 + 8 + 4;
-		break;
-	case TWRITE:		/* fid[4] offset[8] count[4] data[count] */
-		size += 4 + 8 + 4 + fcall->params.twrite.count;
-		break;
-	case TCLUNK:		/* fid[4] */
-		size += 4;
-		break;
-	case TREMOVE:		/* fid[4] */
-		size += 4;
-		break;
-	case TSTAT:		/* fid[4] */
-		size += 4;
-		break;
-	case TWSTAT:		/* fid[4] stat[n] */
-		fcall->params.twstat.stat->size =
-		    v9fs_size_stat(v9ses, fcall->params.twstat.stat);
-		size += 4 + 2 + 2 + fcall->params.twstat.stat->size;
-	}
-	return size;
-}
-
-/*
- * v9fs_serialize_fcall - marshall fcall struct into a packet
- * @v9ses: session information
- * @fcall: structure to convert
- * @data: buffer to serialize fcall into
- * @datalen: length of buffer to serialize fcall into
- *
- */
-
-int
-v9fs_serialize_fcall(struct v9fs_session_info *v9ses, struct v9fs_fcall *fcall,
-		     void *data, u32 datalen)
-{
-	int i = 0;
-	struct v9fs_stat *stat = NULL;
-	struct cbuf buffer;
-	struct cbuf *bufp = &buffer;
-
-	buf_init(bufp, data, datalen);
-
-	if (!fcall) {
-		eprintk(KERN_ERR, "no fcall\n");
-		return -EINVAL;
-	}
-
-	fcall->size = v9fs_size_fcall(v9ses, fcall);
-
-	buf_put_int32(bufp, fcall->size);
-	buf_put_int8(bufp, fcall->id);
-	buf_put_int16(bufp, fcall->tag);
-
-	dprintk(DEBUG_CONV, "size %d id %d tag %d\n", fcall->size, fcall->id,
-		fcall->tag);
-
-	/* now encode it */
-	switch (fcall->id) {
-	default:
-		eprintk(KERN_ERR, "bad msg type: %d\n", fcall->id);
-		return -EPROTO;
-	case TVERSION:
-		buf_put_int32(bufp, fcall->params.tversion.msize);
-		buf_put_string(bufp, fcall->params.tversion.version);
-		break;
-	case TAUTH:
-		buf_put_int32(bufp, fcall->params.tauth.afid);
-		buf_put_string(bufp, fcall->params.tauth.uname);
-		buf_put_string(bufp, fcall->params.tauth.aname);
-		break;
-	case TFLUSH:
-		buf_put_int16(bufp, fcall->params.tflush.oldtag);
-		break;
-	case TATTACH:
-		buf_put_int32(bufp, fcall->params.tattach.fid);
-		buf_put_int32(bufp, fcall->params.tattach.afid);
-		buf_put_string(bufp, fcall->params.tattach.uname);
-		buf_put_string(bufp, fcall->params.tattach.aname);
-		break;
-	case TWALK:
-		buf_put_int32(bufp, fcall->params.twalk.fid);
-		buf_put_int32(bufp, fcall->params.twalk.newfid);
-		buf_put_int16(bufp, fcall->params.twalk.nwname);
-		for (i = 0; i < fcall->params.twalk.nwname; i++)
-			buf_put_string(bufp, fcall->params.twalk.wnames[i]);
-		break;
-	case TOPEN:
-		buf_put_int32(bufp, fcall->params.topen.fid);
-		buf_put_int8(bufp, fcall->params.topen.mode);
-		break;
-	case TCREATE:
-		buf_put_int32(bufp, fcall->params.tcreate.fid);
-		buf_put_string(bufp, fcall->params.tcreate.name);
-		buf_put_int32(bufp, fcall->params.tcreate.perm);
-		buf_put_int8(bufp, fcall->params.tcreate.mode);
-		break;
-	case TREAD:
-		buf_put_int32(bufp, fcall->params.tread.fid);
-		buf_put_int64(bufp, fcall->params.tread.offset);
-		buf_put_int32(bufp, fcall->params.tread.count);
-		break;
-	case TWRITE:
-		buf_put_int32(bufp, fcall->params.twrite.fid);
-		buf_put_int64(bufp, fcall->params.twrite.offset);
-		buf_put_int32(bufp, fcall->params.twrite.count);
-		buf_put_data(bufp, fcall->params.twrite.data,
-			     fcall->params.twrite.count);
-		break;
-	case TCLUNK:
-		buf_put_int32(bufp, fcall->params.tclunk.fid);
-		break;
-	case TREMOVE:
-		buf_put_int32(bufp, fcall->params.tremove.fid);
-		break;
-	case TSTAT:
-		buf_put_int32(bufp, fcall->params.tstat.fid);
-		break;
-	case TWSTAT:
-		buf_put_int32(bufp, fcall->params.twstat.fid);
-		stat = fcall->params.twstat.stat;
-
-		buf_put_int16(bufp, stat->size + 2);
-		serialize_stat(v9ses, stat, bufp);
-		break;
-	}
+	p = bufp->p;
+	buf_get_stat(bufp, stat, extended);
 
 	if (buf_check_overflow(bufp))
-		return -EIO;
-
-	return fcall->size;
+		return 0;
+	else
+		return bufp->p - p;
 }
 
 /**
  * deserialize_fcall - unmarshal a response
- * @v9ses: session information
- * @msgsize: size of rcall message
  * @buf: recieved buffer
  * @buflen: length of received buffer
  * @rcall: fcall structure to populate
  * @rcalllen: length of fcall structure to populate
+ * @extended: non-zero if 9P2000.u
  *
  */
 
 int
-v9fs_deserialize_fcall(struct v9fs_session_info *v9ses, u32 msgsize,
-		       void *buf, u32 buflen, struct v9fs_fcall *rcall,
-		       int rcalllen)
+v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall,
+		       int extended)
 {
 
 	struct cbuf buffer;
 	struct cbuf *bufp = &buffer;
-	struct cbuf dbuffer;
-	struct cbuf *dbufp = &dbuffer;
 	int i = 0;
 
 	buf_init(bufp, buf, buflen);
-	buf_init(dbufp, (char *)rcall + sizeof(struct v9fs_fcall),
-		 rcalllen - sizeof(struct v9fs_fcall));
 
-	rcall->size = msgsize;
+	rcall->size = buf_get_int32(bufp);
 	rcall->id = buf_get_int8(bufp);
 	rcall->tag = buf_get_int16(bufp);
 
 	dprintk(DEBUG_CONV, "size %d id %d tag %d\n", rcall->size, rcall->id,
 		rcall->tag);
+
 	switch (rcall->id) {
 	default:
 		eprintk(KERN_ERR, "unknown message type: %d\n", rcall->id);
 		return -EPROTO;
 	case RVERSION:
 		rcall->params.rversion.msize = buf_get_int32(bufp);
-		rcall->params.rversion.version = buf_get_stringb(bufp, dbufp);
+		buf_get_str(bufp, &rcall->params.rversion.version);
 		break;
 	case RFLUSH:
 		break;
@@ -651,34 +353,27 @@
 		break;
 	case RWALK:
 		rcall->params.rwalk.nwqid = buf_get_int16(bufp);
-		rcall->params.rwalk.wqids = buf_alloc(dbufp,
-		      rcall->params.rwalk.nwqid * sizeof(struct v9fs_qid));
-		if (rcall->params.rwalk.wqids)
-			for (i = 0; i < rcall->params.rwalk.nwqid; i++) {
-				rcall->params.rwalk.wqids[i].type =
-				    buf_get_int8(bufp);
-				rcall->params.rwalk.wqids[i].version =
-				    buf_get_int16(bufp);
-				rcall->params.rwalk.wqids[i].path =
-				    buf_get_int64(bufp);
-			}
+		if (rcall->params.rwalk.nwqid > V9FS_MAXWELEM) {
+			eprintk(KERN_ERR, "Rwalk with more than %d qids: %d\n",
+				V9FS_MAXWELEM, rcall->params.rwalk.nwqid);
+			return -EPROTO;
+		}
+
+		for (i = 0; i < rcall->params.rwalk.nwqid; i++)
+			buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]);
 		break;
 	case ROPEN:
-		rcall->params.ropen.qid.type = buf_get_int8(bufp);
-		rcall->params.ropen.qid.version = buf_get_int32(bufp);
-		rcall->params.ropen.qid.path = buf_get_int64(bufp);
+		buf_get_qid(bufp, &rcall->params.ropen.qid);
 		rcall->params.ropen.iounit = buf_get_int32(bufp);
 		break;
 	case RCREATE:
-		rcall->params.rcreate.qid.type = buf_get_int8(bufp);
-		rcall->params.rcreate.qid.version = buf_get_int32(bufp);
-		rcall->params.rcreate.qid.path = buf_get_int64(bufp);
+		buf_get_qid(bufp, &rcall->params.rcreate.qid);
 		rcall->params.rcreate.iounit = buf_get_int32(bufp);
 		break;
 	case RREAD:
 		rcall->params.rread.count = buf_get_int32(bufp);
-		rcall->params.rread.data = buf_get_datab(bufp, dbufp,
-			rcall->params.rread.count);
+		rcall->params.rread.data = bufp->p;
+		buf_check_size(bufp, rcall->params.rread.count);
 		break;
 	case RWRITE:
 		rcall->params.rwrite.count = buf_get_int32(bufp);
@@ -689,20 +384,443 @@
 		break;
 	case RSTAT:
 		buf_get_int16(bufp);
-		rcall->params.rstat.stat =
-		    deserialize_statb(v9ses, bufp, dbufp);
+		buf_get_stat(bufp, &rcall->params.rstat.stat, extended);
 		break;
 	case RWSTAT:
 		break;
 	case RERROR:
-		rcall->params.rerror.error = buf_get_stringb(bufp, dbufp);
-		if (v9ses->extended)
+		buf_get_str(bufp, &rcall->params.rerror.error);
+		if (extended)
 			rcall->params.rerror.errno = buf_get_int16(bufp);
 		break;
 	}
 
-	if (buf_check_overflow(bufp) || buf_check_overflow(dbufp))
+	if (buf_check_overflow(bufp)) {
+		dprintk(DEBUG_ERROR, "buffer overflow\n");
 		return -EIO;
+	}
 
-	return rcall->size;
+	return bufp->p - bufp->sp;
+}
+
+static inline void v9fs_put_int8(struct cbuf *bufp, u8 val, u8 * p)
+{
+	*p = val;
+	buf_put_int8(bufp, val);
+}
+
+static inline void v9fs_put_int16(struct cbuf *bufp, u16 val, u16 * p)
+{
+	*p = val;
+	buf_put_int16(bufp, val);
+}
+
+static inline void v9fs_put_int32(struct cbuf *bufp, u32 val, u32 * p)
+{
+	*p = val;
+	buf_put_int32(bufp, val);
+}
+
+static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p)
+{
+	*p = val;
+	buf_put_int64(bufp, val);
+}
+
+static inline void
+v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str)
+{
+	if (data) {
+		str->len = strlen(data);
+		str->str = bufp->p;
+	} else {
+		str->len = 0;
+		str->str = NULL;
+	}
+
+	buf_put_stringn(bufp, data, str->len);
+}
+
+static inline int
+v9fs_put_user_data(struct cbuf *bufp, const char __user * data, int count,
+		   unsigned char **pdata)
+{
+	*pdata = buf_alloc(bufp, count);
+	return copy_from_user(*pdata, data, count);
+}
+
+static void
+v9fs_put_wstat(struct cbuf *bufp, struct v9fs_wstat *wstat,
+	       struct v9fs_stat *stat, int statsz, int extended)
+{
+	v9fs_put_int16(bufp, statsz, &stat->size);
+	v9fs_put_int16(bufp, wstat->type, &stat->type);
+	v9fs_put_int32(bufp, wstat->dev, &stat->dev);
+	v9fs_put_int8(bufp, wstat->qid.type, &stat->qid.type);
+	v9fs_put_int32(bufp, wstat->qid.version, &stat->qid.version);
+	v9fs_put_int64(bufp, wstat->qid.path, &stat->qid.path);
+	v9fs_put_int32(bufp, wstat->mode, &stat->mode);
+	v9fs_put_int32(bufp, wstat->atime, &stat->atime);
+	v9fs_put_int32(bufp, wstat->mtime, &stat->mtime);
+	v9fs_put_int64(bufp, wstat->length, &stat->length);
+
+	v9fs_put_str(bufp, wstat->name, &stat->name);
+	v9fs_put_str(bufp, wstat->uid, &stat->uid);
+	v9fs_put_str(bufp, wstat->gid, &stat->gid);
+	v9fs_put_str(bufp, wstat->muid, &stat->muid);
+
+	if (extended) {
+		v9fs_put_str(bufp, wstat->extension, &stat->extension);
+		v9fs_put_int32(bufp, wstat->n_uid, &stat->n_uid);
+		v9fs_put_int32(bufp, wstat->n_gid, &stat->n_gid);
+		v9fs_put_int32(bufp, wstat->n_muid, &stat->n_muid);
+	}
+}
+
+static struct v9fs_fcall *
+v9fs_create_common(struct cbuf *bufp, u32 size, u8 id)
+{
+	struct v9fs_fcall *fc;
+
+	size += 4 + 1 + 2;	/* size[4] id[1] tag[2] */
+	fc = kmalloc(sizeof(struct v9fs_fcall) + size, GFP_KERNEL);
+	if (!fc)
+		return ERR_PTR(-ENOMEM);
+
+	fc->sdata = (char *)fc + sizeof(*fc);
+
+	buf_init(bufp, (char *)fc->sdata, size);
+	v9fs_put_int32(bufp, size, &fc->size);
+	v9fs_put_int8(bufp, id, &fc->id);
+	v9fs_put_int16(bufp, V9FS_NOTAG, &fc->tag);
+
+	return fc;
+}
+
+void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag)
+{
+	fc->tag = tag;
+	*(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag);
+}
+
+struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4 + 2 + strlen(version);	/* msize[4] version[s] */
+	fc = v9fs_create_common(bufp, size, TVERSION);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, msize, &fc->params.tversion.msize);
+	v9fs_put_str(bufp, version, &fc->params.tversion.version);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4 + 2 + strlen(uname) + 2 + strlen(aname);	/* afid[4] uname[s] aname[s] */
+	fc = v9fs_create_common(bufp, size, TAUTH);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, afid, &fc->params.tauth.afid);
+	v9fs_put_str(bufp, uname, &fc->params.tauth.uname);
+	v9fs_put_str(bufp, aname, &fc->params.tauth.aname);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *
+v9fs_create_tattach(u32 fid, u32 afid, char *uname, char *aname)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4 + 4 + 2 + strlen(uname) + 2 + strlen(aname);	/* fid[4] afid[4] uname[s] aname[s] */
+	fc = v9fs_create_common(bufp, size, TATTACH);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.tattach.fid);
+	v9fs_put_int32(bufp, afid, &fc->params.tattach.afid);
+	v9fs_put_str(bufp, uname, &fc->params.tattach.uname);
+	v9fs_put_str(bufp, aname, &fc->params.tattach.aname);
+
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_tflush(u16 oldtag)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 2;		/* oldtag[2] */
+	fc = v9fs_create_common(bufp, size, TFLUSH);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int16(bufp, oldtag, &fc->params.tflush.oldtag);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname,
+				     char **wnames)
+{
+	int i, size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	if (nwname > V9FS_MAXWELEM) {
+		dprintk(DEBUG_ERROR, "nwname > %d\n", V9FS_MAXWELEM);
+		return NULL;
+	}
+
+	size = 4 + 4 + 2;	/* fid[4] newfid[4] nwname[2] ... */
+	for (i = 0; i < nwname; i++) {
+		size += 2 + strlen(wnames[i]);	/* wname[s] */
+	}
+
+	fc = v9fs_create_common(bufp, size, TWALK);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.twalk.fid);
+	v9fs_put_int32(bufp, newfid, &fc->params.twalk.newfid);
+	v9fs_put_int16(bufp, nwname, &fc->params.twalk.nwname);
+	for (i = 0; i < nwname; i++) {
+		v9fs_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]);
+	}
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4 + 1;		/* fid[4] mode[1] */
+	fc = v9fs_create_common(bufp, size, TOPEN);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.topen.fid);
+	v9fs_put_int8(bufp, mode, &fc->params.topen.mode);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4 + 2 + strlen(name) + 4 + 1;	/* fid[4] name[s] perm[4] mode[1] */
+	fc = v9fs_create_common(bufp, size, TCREATE);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.tcreate.fid);
+	v9fs_put_str(bufp, name, &fc->params.tcreate.name);
+	v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm);
+	v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4 + 8 + 4;	/* fid[4] offset[8] count[4] */
+	fc = v9fs_create_common(bufp, size, TREAD);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.tread.fid);
+	v9fs_put_int64(bufp, offset, &fc->params.tread.offset);
+	v9fs_put_int32(bufp, count, &fc->params.tread.count);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count,
+				      const char __user * data)
+{
+	int size, err;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4 + 8 + 4 + count;	/* fid[4] offset[8] count[4] data[count] */
+	fc = v9fs_create_common(bufp, size, TWRITE);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.twrite.fid);
+	v9fs_put_int64(bufp, offset, &fc->params.twrite.offset);
+	v9fs_put_int32(bufp, count, &fc->params.twrite.count);
+	err = v9fs_put_user_data(bufp, data, count, &fc->params.twrite.data);
+	if (err) {
+		kfree(fc);
+		fc = ERR_PTR(err);
+	}
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_tclunk(u32 fid)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4;		/* fid[4] */
+	fc = v9fs_create_common(bufp, size, TCLUNK);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.tclunk.fid);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_tremove(u32 fid)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4;		/* fid[4] */
+	fc = v9fs_create_common(bufp, size, TREMOVE);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.tremove.fid);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_tstat(u32 fid)
+{
+	int size;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	size = 4;		/* fid[4] */
+	fc = v9fs_create_common(bufp, size, TSTAT);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.tstat.fid);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
+}
+
+struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat,
+				      int extended)
+{
+	int size, statsz;
+	struct v9fs_fcall *fc;
+	struct cbuf buffer;
+	struct cbuf *bufp = &buffer;
+
+	statsz = v9fs_size_wstat(wstat, extended);
+	size = 4 + 2 + 2 + statsz;	/* fid[4] stat[n] */
+	fc = v9fs_create_common(bufp, size, TWSTAT);
+	if (IS_ERR(fc))
+		goto error;
+
+	v9fs_put_int32(bufp, fid, &fc->params.twstat.fid);
+	buf_put_int16(bufp, statsz + 2);
+	v9fs_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, extended);
+
+	if (buf_check_overflow(bufp)) {
+		kfree(fc);
+		fc = ERR_PTR(-ENOMEM);
+	}
+      error:
+	return fc;
 }
diff --git a/fs/9p/conv.h b/fs/9p/conv.h
index ee84961..26a736e 100644
--- a/fs/9p/conv.h
+++ b/fs/9p/conv.h
@@ -1,8 +1,9 @@
 /*
  * linux/fs/9p/conv.h
  *
- * 9P protocol conversion definitions
+ * 9P protocol conversion definitions.
  *
+ *  Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
  *
@@ -24,13 +25,27 @@
  *
  */
 
-int v9fs_deserialize_stat(struct v9fs_session_info *, void *buf,
-			  u32 buflen, struct v9fs_stat *stat, u32 statlen);
-int v9fs_serialize_fcall(struct v9fs_session_info *, struct v9fs_fcall *tcall,
-			 void *buf, u32 buflen);
-int v9fs_deserialize_fcall(struct v9fs_session_info *, u32 msglen,
-			   void *buf, u32 buflen, struct v9fs_fcall *rcall,
-			   int rcalllen);
+int v9fs_deserialize_stat(void *buf, u32 buflen, struct v9fs_stat *stat,
+	int extended);
+int v9fs_deserialize_fcall(void *buf, u32 buflen, struct v9fs_fcall *rcall,
+	int extended);
 
-/* this one is actually in error.c right now */
-int v9fs_errstr2errno(char *errstr);
+void v9fs_set_tag(struct v9fs_fcall *fc, u16 tag);
+
+struct v9fs_fcall *v9fs_create_tversion(u32 msize, char *version);
+struct v9fs_fcall *v9fs_create_tauth(u32 afid, char *uname, char *aname);
+struct v9fs_fcall *v9fs_create_tattach(u32 fid, u32 afid, char *uname,
+	char *aname);
+struct v9fs_fcall *v9fs_create_tflush(u16 oldtag);
+struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname,
+	char **wnames);
+struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode);
+struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode);
+struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count);
+struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count,
+	const char __user *data);
+struct v9fs_fcall *v9fs_create_tclunk(u32 fid);
+struct v9fs_fcall *v9fs_create_tremove(u32 fid);
+struct v9fs_fcall *v9fs_create_tstat(u32 fid);
+struct v9fs_fcall *v9fs_create_twstat(u32 fid, struct v9fs_wstat *wstat,
+	int extended);
diff --git a/fs/9p/debug.h b/fs/9p/debug.h
index 4445f06..fe55103 100644
--- a/fs/9p/debug.h
+++ b/fs/9p/debug.h
@@ -51,16 +51,23 @@
 #if DEBUG_DUMP_PKT
 static inline void dump_data(const unsigned char *data, unsigned int datalen)
 {
-	int i, j;
-	int len = datalen;
+	int i, n;
+	char buf[5*8];
 
-	printk(KERN_DEBUG "data ");
-	for (i = 0; i < len; i += 4) {
-		for (j = 0; (j < 4) && (i + j < len); j++)
-			printk(KERN_DEBUG "%02x", data[i + j]);
-		printk(KERN_DEBUG " ");
+	n = 0;
+	i = 0;
+	while (i < datalen) {
+		n += snprintf(buf+n, sizeof(buf)-n, "%02x", data[i++]);
+		if (i%4 == 0)
+			n += snprintf(buf+n, sizeof(buf)-n, " ");
+
+		if (i%16 == 0) {
+			dprintk(DEBUG_ERROR, "%s\n", buf);
+			n = 0;
+		}
 	}
-	printk(KERN_DEBUG "\n");
+
+	dprintk(DEBUG_ERROR, "%s\n", buf);
 }
 #else				/* DEBUG_DUMP_PKT */
 static inline void dump_data(const unsigned char *data, unsigned int datalen)
diff --git a/fs/9p/error.c b/fs/9p/error.c
index 834cb17..e4b6f8f 100644
--- a/fs/9p/error.c
+++ b/fs/9p/error.c
@@ -33,7 +33,6 @@
 
 #include <linux/list.h>
 #include <linux/jhash.h>
-#include <linux/string.h>
 
 #include "debug.h"
 #include "error.h"
@@ -55,7 +54,8 @@
 
 	/* load initial error map into hash table */
 	for (c = errmap; c->name != NULL; c++) {
-		bucket = jhash(c->name, strlen(c->name), 0) % ERRHASHSZ;
+		c->namelen = strlen(c->name);
+		bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ;
 		INIT_HLIST_NODE(&c->list);
 		hlist_add_head(&c->list, &hash_errmap[bucket]);
 	}
@@ -69,15 +69,15 @@
  *
  */
 
-int v9fs_errstr2errno(char *errstr)
+int v9fs_errstr2errno(char *errstr, int len)
 {
 	int errno = 0;
 	struct hlist_node *p = NULL;
 	struct errormap *c = NULL;
-	int bucket = jhash(errstr, strlen(errstr), 0) % ERRHASHSZ;
+	int bucket = jhash(errstr, len, 0) % ERRHASHSZ;
 
 	hlist_for_each_entry(c, p, &hash_errmap[bucket], list) {
-		if (!strcmp(c->name, errstr)) {
+		if (c->namelen==len && !memcmp(c->name, errstr, len)) {
 			errno = c->val;
 			break;
 		}
diff --git a/fs/9p/error.h b/fs/9p/error.h
index 78f89ac..a9794e8 100644
--- a/fs/9p/error.h
+++ b/fs/9p/error.h
@@ -36,6 +36,7 @@
 	char *name;
 	int val;
 
+	int namelen;
 	struct hlist_node list;
 };
 
@@ -175,4 +176,3 @@
 };
 
 extern int v9fs_error_init(void);
-extern int v9fs_errstr2errno(char *errstr);
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index d95f862..eda4497 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -31,9 +31,6 @@
 #include "v9fs.h"
 #include "9p.h"
 #include "v9fs_vfs.h"
-#include "transport.h"
-#include "mux.h"
-#include "conv.h"
 #include "fid.h"
 
 /**
@@ -164,7 +161,7 @@
 	return v9fs_fid_create(dentry, v9ses, fidnum, 0);
 
 clunk_fid:
-	v9fs_t_clunk(v9ses, fidnum, NULL);
+	v9fs_t_clunk(v9ses, fidnum);
 	return ERR_PTR(err);
 }
 
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
index 8835b57..945cb36 100644
--- a/fs/9p/mux.c
+++ b/fs/9p/mux.c
@@ -4,7 +4,7 @@
  * Protocol Multiplexer
  *
  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
- *  Copyright (C) 2004 by Latchesar Ionkov <lucho@ionkov.net>
+ *  Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -28,448 +28,943 @@
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
+#include <linux/poll.h>
 #include <linux/kthread.h>
 #include <linux/idr.h>
 
 #include "debug.h"
 #include "v9fs.h"
 #include "9p.h"
-#include "transport.h"
 #include "conv.h"
+#include "transport.h"
 #include "mux.h"
 
-/**
- * dprintcond - print condition of session info
- * @v9ses: session info structure
- * @req: RPC request structure
- *
- */
+#define ERREQFLUSH	1
+#define SCHED_TIMEOUT	10
+#define MAXPOLLWADDR	2
 
-static inline int
-dprintcond(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
+enum {
+	Rworksched = 1,		/* read work scheduled or running */
+	Rpending = 2,		/* can read */
+	Wworksched = 4,		/* write work scheduled or running */
+	Wpending = 8,		/* can write */
+};
+
+struct v9fs_mux_poll_task;
+
+struct v9fs_req {
+	int tag;
+	struct v9fs_fcall *tcall;
+	struct v9fs_fcall *rcall;
+	int err;
+	v9fs_mux_req_callback cb;
+	void *cba;
+	struct list_head req_list;
+};
+
+struct v9fs_mux_data {
+	spinlock_t lock;
+	struct list_head mux_list;
+	struct v9fs_mux_poll_task *poll_task;
+	int msize;
+	unsigned char *extended;
+	struct v9fs_transport *trans;
+	struct v9fs_idpool tidpool;
+	int err;
+	wait_queue_head_t equeue;
+	struct list_head req_list;
+	struct list_head unsent_req_list;
+	struct v9fs_fcall *rcall;
+	int rpos;
+	char *rbuf;
+	int wpos;
+	int wsize;
+	char *wbuf;
+	wait_queue_t poll_wait[MAXPOLLWADDR];
+	wait_queue_head_t *poll_waddr[MAXPOLLWADDR];
+	poll_table pt;
+	struct work_struct rq;
+	struct work_struct wq;
+	unsigned long wsched;
+};
+
+struct v9fs_mux_poll_task {
+	struct task_struct *task;
+	struct list_head mux_list;
+	int muxnum;
+};
+
+struct v9fs_mux_rpc {
+	struct v9fs_mux_data *m;
+	struct v9fs_req *req;
+	int err;
+	struct v9fs_fcall *rcall;
+	wait_queue_head_t wqueue;
+};
+
+static int v9fs_poll_proc(void *);
+static void v9fs_read_work(void *);
+static void v9fs_write_work(void *);
+static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address,
+			  poll_table * p);
+static u16 v9fs_mux_get_tag(struct v9fs_mux_data *);
+static void v9fs_mux_put_tag(struct v9fs_mux_data *, u16);
+
+static DECLARE_MUTEX(v9fs_mux_task_lock);
+static struct workqueue_struct *v9fs_mux_wq;
+
+static int v9fs_mux_num;
+static int v9fs_mux_poll_task_num;
+static struct v9fs_mux_poll_task v9fs_mux_poll_tasks[100];
+
+int v9fs_mux_global_init(void)
 {
-	dprintk(DEBUG_MUX, "condition: %d, %p\n", v9ses->transport->status,
-		req->rcall);
-	return 0;
-}
+	int i;
 
-/**
- * xread - force read of a certain number of bytes
- * @v9ses: session info structure
- * @ptr: pointer to buffer
- * @sz: number of bytes to read
- *
- * Chuck Cranor CS-533 project1
- */
+	for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++)
+		v9fs_mux_poll_tasks[i].task = NULL;
 
-static int xread(struct v9fs_session_info *v9ses, void *ptr, unsigned long sz)
-{
-	int rd = 0;
-	int ret = 0;
-	while (rd < sz) {
-		ret = v9ses->transport->read(v9ses->transport, ptr, sz - rd);
-		if (ret <= 0) {
-			dprintk(DEBUG_ERROR, "xread errno %d\n", ret);
-			return ret;
-		}
-		rd += ret;
-		ptr += ret;
-	}
-	return (rd);
-}
-
-/**
- * read_message - read a full 9P2000 fcall packet
- * @v9ses: session info structure
- * @rcall: fcall structure to read into
- * @rcalllen: size of fcall buffer
- *
- */
-
-static int
-read_message(struct v9fs_session_info *v9ses,
-	     struct v9fs_fcall *rcall, int rcalllen)
-{
-	unsigned char buf[4];
-	void *data;
-	int size = 0;
-	int res = 0;
-
-	res = xread(v9ses, buf, sizeof(buf));
-	if (res < 0) {
-		dprintk(DEBUG_ERROR,
-			"Reading of count field failed returned: %d\n", res);
-		return res;
-	}
-
-	if (res < 4) {
-		dprintk(DEBUG_ERROR,
-			"Reading of count field failed returned: %d\n", res);
-		return -EIO;
-	}
-
-	size = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
-	dprintk(DEBUG_MUX, "got a packet count: %d\n", size);
-
-	/* adjust for the four bytes of size */
-	size -= 4;
-
-	if (size > v9ses->maxdata) {
-		dprintk(DEBUG_ERROR, "packet too big: %d\n", size);
-		return -E2BIG;
-	}
-
-	data = kmalloc(size, GFP_KERNEL);
-	if (!data) {
-		eprintk(KERN_WARNING, "out of memory\n");
+	v9fs_mux_wq = create_workqueue("v9fs");
+	if (!v9fs_mux_wq)
 		return -ENOMEM;
-	}
-
-	res = xread(v9ses, data, size);
-	if (res < size) {
-		dprintk(DEBUG_ERROR, "Reading of fcall failed returned: %d\n",
-			res);
-		kfree(data);
-		return res;
-	}
-
-	/* we now have an in-memory string that is the reply.
-	 * deserialize it. There is very little to go wrong at this point
-	 * save for v9fs_alloc errors.
-	 */
-	res = v9fs_deserialize_fcall(v9ses, size, data, v9ses->maxdata,
-				     rcall, rcalllen);
-
-	kfree(data);
-
-	if (res < 0)
-		return res;
 
 	return 0;
 }
 
-/**
- * v9fs_recv - receive an RPC response for a particular tag
- * @v9ses: session info structure
- * @req: RPC request structure
- *
- */
-
-static int v9fs_recv(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
+void v9fs_mux_global_exit(void)
 {
-	int ret = 0;
-
-	dprintk(DEBUG_MUX, "waiting for response: %d\n", req->tcall->tag);
-	ret = wait_event_interruptible(v9ses->read_wait,
-		       ((v9ses->transport->status != Connected) ||
-			(req->rcall != 0) || (req->err < 0) ||
-			dprintcond(v9ses, req)));
-
-	dprintk(DEBUG_MUX, "got it: rcall %p\n", req->rcall);
-
-	spin_lock(&v9ses->muxlock);
-	list_del(&req->next);
-	spin_unlock(&v9ses->muxlock);
-
-	if (req->err < 0)
-		return req->err;
-
-	if (v9ses->transport->status == Disconnected)
-		return -ECONNRESET;
-
-	return ret;
+	destroy_workqueue(v9fs_mux_wq);
 }
 
 /**
- * v9fs_send - send a 9P request
- * @v9ses: session info structure
- * @req: RPC request to send
+ * v9fs_mux_calc_poll_procs - calculates the number of polling procs
+ * based on the number of mounted v9fs filesystems.
  *
+ * The current implementation returns sqrt of the number of mounts.
  */
-
-static int v9fs_send(struct v9fs_session_info *v9ses, struct v9fs_rpcreq *req)
+inline int v9fs_mux_calc_poll_procs(int muxnum)
 {
-	int ret = -1;
-	void *data = NULL;
-	struct v9fs_fcall *tcall = req->tcall;
+	int n;
 
-	data = kmalloc(v9ses->maxdata + V9FS_IOHDRSZ, GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	tcall->size = 0;	/* enforce size recalculation */
-	ret =
-	    v9fs_serialize_fcall(v9ses, tcall, data,
-				 v9ses->maxdata + V9FS_IOHDRSZ);
-	if (ret < 0)
-		goto free_data;
-
-	spin_lock(&v9ses->muxlock);
-	list_add(&req->next, &v9ses->mux_fcalls);
-	spin_unlock(&v9ses->muxlock);
-
-	dprintk(DEBUG_MUX, "sending message: tag %d size %d\n", tcall->tag,
-		tcall->size);
-	ret = v9ses->transport->write(v9ses->transport, data, tcall->size);
-
-	if (ret != tcall->size) {
-		spin_lock(&v9ses->muxlock);
-		list_del(&req->next);
-		kfree(req->rcall);
-
-		spin_unlock(&v9ses->muxlock);
-		if (ret >= 0)
-			ret = -EREMOTEIO;
-	} else
-		ret = 0;
-
-      free_data:
-	kfree(data);
-	return ret;
-}
-
-/**
- * v9fs_mux_rpc - send a request, receive a response
- * @v9ses: session info structure
- * @tcall: fcall to send
- * @rcall: buffer to place response into
- *
- */
-
-long
-v9fs_mux_rpc(struct v9fs_session_info *v9ses, struct v9fs_fcall *tcall,
-	     struct v9fs_fcall **rcall)
-{
-	int tid = -1;
-	struct v9fs_fcall *fcall = NULL;
-	struct v9fs_rpcreq req;
-	int ret = -1;
-
-	if (!v9ses)
-		return -EINVAL;
-
-	if (!v9ses->transport || v9ses->transport->status != Connected)
-		return -EIO;
-
-	if (rcall)
-		*rcall = NULL;
-
-	if (tcall->id != TVERSION) {
-		tid = v9fs_get_idpool(&v9ses->tidpool);
-		if (tid < 0)
-			return -ENOMEM;
-	}
-
-	tcall->tag = tid;
-
-	req.tcall = tcall;
-	req.err = 0;
-	req.rcall = NULL;
-
-	ret = v9fs_send(v9ses, &req);
-
-	if (ret < 0) {
-		if (tcall->id != TVERSION)
-			v9fs_put_idpool(tid, &v9ses->tidpool);
-		dprintk(DEBUG_MUX, "error %d\n", ret);
-		return ret;
-	}
-
-	ret = v9fs_recv(v9ses, &req);
-
-	fcall = req.rcall;
-
-	dprintk(DEBUG_MUX, "received: tag=%x, ret=%d\n", tcall->tag, ret);
-	if (ret == -ERESTARTSYS) {
-		if (v9ses->transport->status != Disconnected
-		    && tcall->id != TFLUSH) {
-			unsigned long flags;
-
-			dprintk(DEBUG_MUX, "flushing the tag: %d\n",
-				tcall->tag);
-			clear_thread_flag(TIF_SIGPENDING);
-			v9fs_t_flush(v9ses, tcall->tag);
-			spin_lock_irqsave(&current->sighand->siglock, flags);
-			recalc_sigpending();
-			spin_unlock_irqrestore(&current->sighand->siglock,
-					       flags);
-			dprintk(DEBUG_MUX, "flushing done\n");
-		}
-
-		goto release_req;
-	} else if (ret < 0)
-		goto release_req;
-
-	if (!fcall)
-		ret = -EIO;
-	else {
-		if (fcall->id == RERROR) {
-			ret = v9fs_errstr2errno(fcall->params.rerror.error);
-			if (ret == 0) {	/* string match failed */
-				if (fcall->params.rerror.errno)
-					ret = -(fcall->params.rerror.errno);
-				else
-					ret = -ESERVERFAULT;
-			}
-		} else if (fcall->id != tcall->id + 1) {
-			dprintk(DEBUG_ERROR,
-				"fcall mismatch: expected %d, got %d\n",
-				tcall->id + 1, fcall->id);
-			ret = -EIO;
-		}
-	}
-
-      release_req:
-	if (tcall->id != TVERSION)
-		v9fs_put_idpool(tid, &v9ses->tidpool);
-	if (rcall)
-		*rcall = fcall;
+	if (v9fs_mux_poll_task_num)
+		n = muxnum / v9fs_mux_poll_task_num +
+		    (muxnum % v9fs_mux_poll_task_num ? 1 : 0);
 	else
-		kfree(fcall);
+		n = 1;
 
-	return ret;
+	if (n > ARRAY_SIZE(v9fs_mux_poll_tasks))
+		n = ARRAY_SIZE(v9fs_mux_poll_tasks);
+
+	return n;
 }
 
-/**
- * v9fs_mux_cancel_requests - cancels all pending requests
- *
- * @v9ses: session info structure
- * @err: error code to return to the requests
- */
-void v9fs_mux_cancel_requests(struct v9fs_session_info *v9ses, int err)
+static int v9fs_mux_poll_start(struct v9fs_mux_data *m)
 {
-	struct v9fs_rpcreq *rptr;
-	struct v9fs_rpcreq *rreq;
+	int i, n;
+	struct v9fs_mux_poll_task *vpt, *vptlast;
+	struct task_struct *pproc;
 
-	dprintk(DEBUG_MUX, " %d\n", err);
-	spin_lock(&v9ses->muxlock);
-	list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
-		rreq->err = err;
+	dprintk(DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, v9fs_mux_num,
+		v9fs_mux_poll_task_num);
+	up(&v9fs_mux_task_lock);
+
+	n = v9fs_mux_calc_poll_procs(v9fs_mux_num + 1);
+	if (n > v9fs_mux_poll_task_num) {
+		for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) {
+			if (v9fs_mux_poll_tasks[i].task == NULL) {
+				vpt = &v9fs_mux_poll_tasks[i];
+				dprintk(DEBUG_MUX, "create proc %p\n", vpt);
+				pproc = kthread_create(v9fs_poll_proc, vpt,
+						   "v9fs-poll");
+
+				if (!IS_ERR(pproc)) {
+					vpt->task = pproc;
+					INIT_LIST_HEAD(&vpt->mux_list);
+					vpt->muxnum = 0;
+					v9fs_mux_poll_task_num++;
+					wake_up_process(vpt->task);
+				}
+				break;
+			}
+		}
+
+		if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks))
+			dprintk(DEBUG_ERROR, "warning: no free poll slots\n");
 	}
-	spin_unlock(&v9ses->muxlock);
-	wake_up_all(&v9ses->read_wait);
+
+	n = (v9fs_mux_num + 1) / v9fs_mux_poll_task_num +
+	    ((v9fs_mux_num + 1) % v9fs_mux_poll_task_num ? 1 : 0);
+
+	vptlast = NULL;
+	for (i = 0; i < ARRAY_SIZE(v9fs_mux_poll_tasks); i++) {
+		vpt = &v9fs_mux_poll_tasks[i];
+		if (vpt->task != NULL) {
+			vptlast = vpt;
+			if (vpt->muxnum < n) {
+				dprintk(DEBUG_MUX, "put in proc %d\n", i);
+				list_add(&m->mux_list, &vpt->mux_list);
+				vpt->muxnum++;
+				m->poll_task = vpt;
+				memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
+				init_poll_funcptr(&m->pt, v9fs_pollwait);
+				break;
+			}
+		}
+	}
+
+	if (i >= ARRAY_SIZE(v9fs_mux_poll_tasks)) {
+		if (vptlast == NULL)
+			return -ENOMEM;
+
+		dprintk(DEBUG_MUX, "put in proc %d\n", i);
+		list_add(&m->mux_list, &vptlast->mux_list);
+		vptlast->muxnum++;
+		m->poll_task = vptlast;
+		memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
+		init_poll_funcptr(&m->pt, v9fs_pollwait);
+	}
+
+	v9fs_mux_num++;
+	down(&v9fs_mux_task_lock);
+
+	return 0;
+}
+
+static void v9fs_mux_poll_stop(struct v9fs_mux_data *m)
+{
+	int i;
+	struct v9fs_mux_poll_task *vpt;
+
+	up(&v9fs_mux_task_lock);
+	vpt = m->poll_task;
+	list_del(&m->mux_list);
+	for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
+		if (m->poll_waddr[i] != NULL) {
+			remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]);
+			m->poll_waddr[i] = NULL;
+		}
+	}
+	vpt->muxnum--;
+	if (!vpt->muxnum) {
+		dprintk(DEBUG_MUX, "destroy proc %p\n", vpt);
+		send_sig(SIGKILL, vpt->task, 1);
+		vpt->task = NULL;
+		v9fs_mux_poll_task_num--;
+	}
+	v9fs_mux_num--;
+	down(&v9fs_mux_task_lock);
 }
 
 /**
- * v9fs_recvproc - kproc to handle demultiplexing responses
- * @data: session info structure
+ * v9fs_mux_init - allocate and initialize the per-session mux data
+ * Creates the polling task if this is the first session.
  *
+ * @trans - transport structure
+ * @msize - maximum message size
+ * @extended - pointer to the extended flag
  */
-
-static int v9fs_recvproc(void *data)
+struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize,
+				    unsigned char *extended)
 {
-	struct v9fs_session_info *v9ses = (struct v9fs_session_info *)data;
-	struct v9fs_fcall *rcall = NULL;
-	struct v9fs_rpcreq *rptr;
-	struct v9fs_rpcreq *req;
-	struct v9fs_rpcreq *rreq;
-	int err = 0;
+	int i, n;
+	struct v9fs_mux_data *m, *mtmp;
 
-	allow_signal(SIGKILL);
-	set_current_state(TASK_INTERRUPTIBLE);
-	complete(&v9ses->proccmpl);
-	while (!kthread_should_stop() && err >= 0) {
-		req = rptr = rreq = NULL;
+	dprintk(DEBUG_MUX, "transport %p msize %d\n", trans, msize);
+	m = kmalloc(sizeof(struct v9fs_mux_data), GFP_KERNEL);
+	if (!m)
+		return ERR_PTR(-ENOMEM);
 
-		rcall = kmalloc(v9ses->maxdata + V9FS_IOHDRSZ, GFP_KERNEL);
-		if (!rcall) {
-			eprintk(KERN_ERR, "no memory for buffers\n");
+	spin_lock_init(&m->lock);
+	INIT_LIST_HEAD(&m->mux_list);
+	m->msize = msize;
+	m->extended = extended;
+	m->trans = trans;
+	idr_init(&m->tidpool.pool);
+	init_MUTEX(&m->tidpool.lock);
+	m->err = 0;
+	init_waitqueue_head(&m->equeue);
+	INIT_LIST_HEAD(&m->req_list);
+	INIT_LIST_HEAD(&m->unsent_req_list);
+	m->rcall = NULL;
+	m->rpos = 0;
+	m->rbuf = NULL;
+	m->wpos = m->wsize = 0;
+	m->wbuf = NULL;
+	INIT_WORK(&m->rq, v9fs_read_work, m);
+	INIT_WORK(&m->wq, v9fs_write_work, m);
+	m->wsched = 0;
+	memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
+	m->poll_task = NULL;
+	n = v9fs_mux_poll_start(m);
+	if (n)
+		return ERR_PTR(n);
+
+	n = trans->poll(trans, &m->pt);
+	if (n & POLLIN) {
+		dprintk(DEBUG_MUX, "mux %p can read\n", m);
+		set_bit(Rpending, &m->wsched);
+	}
+
+	if (n & POLLOUT) {
+		dprintk(DEBUG_MUX, "mux %p can write\n", m);
+		set_bit(Wpending, &m->wsched);
+	}
+
+	for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
+		if (IS_ERR(m->poll_waddr[i])) {
+			v9fs_mux_poll_stop(m);
+			mtmp = (void *)m->poll_waddr;	/* the error code */
+			kfree(m);
+			m = mtmp;
 			break;
 		}
-
-		err = read_message(v9ses, rcall, v9ses->maxdata + V9FS_IOHDRSZ);
-		spin_lock(&v9ses->muxlock);
-		if (err < 0) {
-			list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
-				rreq->err = err;
-			}
-			if(err != -ERESTARTSYS)
-				eprintk(KERN_ERR,
-					"Transport error while reading message %d\n", err);
-		} else {
-			list_for_each_entry_safe(rreq, rptr, &v9ses->mux_fcalls, next) {
-				if (rreq->tcall->tag == rcall->tag) {
-					req = rreq;
-					req->rcall = rcall;
-					break;
-				}
-			}
-		}
-
-		if (req && (req->tcall->id == TFLUSH)) {
-			struct v9fs_rpcreq *treq = NULL;
-			list_for_each_entry_safe(treq, rptr, &v9ses->mux_fcalls, next) {
-				if (treq->tcall->tag ==
-				    req->tcall->params.tflush.oldtag) {
-					list_del(&rptr->next);
-					kfree(treq->rcall);
-					break;
-				}
-			}
-		}
-
-		spin_unlock(&v9ses->muxlock);
-
-		if (!req) {
-			if (err >= 0)
-				dprintk(DEBUG_ERROR,
-					"unexpected response: id %d tag %d\n",
-					rcall->id, rcall->tag);
-
-			kfree(rcall);
-		}
-
-		wake_up_all(&v9ses->read_wait);
-		set_current_state(TASK_INTERRUPTIBLE);
 	}
 
-	v9ses->transport->close(v9ses->transport);
-
-	/* Inform all pending processes about the failure */
-	wake_up_all(&v9ses->read_wait);
-
-	if (signal_pending(current))
-		complete(&v9ses->proccmpl);
-
-	dprintk(DEBUG_MUX, "recvproc: end\n");
-	v9ses->recvproc = NULL;
-
-	return err >= 0;
+	return m;
 }
 
 /**
- * v9fs_mux_init - initialize multiplexer (spawn kproc)
- * @v9ses: session info structure
- * @dev_name: mount device information (to create unique kproc)
- *
+ * v9fs_mux_destroy - cancels all pending requests and frees mux resources
  */
-
-int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name)
+void v9fs_mux_destroy(struct v9fs_mux_data *m)
 {
-	char procname[60];
+	dprintk(DEBUG_MUX, "mux %p prev %p next %p\n", m,
+		m->mux_list.prev, m->mux_list.next);
+	v9fs_mux_cancel(m, -ECONNRESET);
 
-	strncpy(procname, dev_name, sizeof(procname));
-	procname[sizeof(procname) - 1] = 0;
-
-	init_waitqueue_head(&v9ses->read_wait);
-	init_completion(&v9ses->fcread);
-	init_completion(&v9ses->proccmpl);
-	spin_lock_init(&v9ses->muxlock);
-	INIT_LIST_HEAD(&v9ses->mux_fcalls);
-	v9ses->recvproc = NULL;
-	v9ses->curfcall = NULL;
-
-	v9ses->recvproc = kthread_create(v9fs_recvproc, v9ses,
-					 "v9fs_recvproc %s", procname);
-
-	if (IS_ERR(v9ses->recvproc)) {
-		eprintk(KERN_ERR, "cannot create receiving thread\n");
-		v9fs_session_close(v9ses);
-		return -ECONNABORTED;
+	if (!list_empty(&m->req_list)) {
+		/* wait until all processes waiting on this session exit */
+		dprintk(DEBUG_MUX, "mux %p waiting for empty request queue\n",
+			m);
+		wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000);
+		dprintk(DEBUG_MUX, "mux %p request queue empty: %d\n", m,
+			list_empty(&m->req_list));
 	}
 
-	wake_up_process(v9ses->recvproc);
-	wait_for_completion(&v9ses->proccmpl);
+	v9fs_mux_poll_stop(m);
+	m->trans = NULL;
 
+	kfree(m);
+}
+
+/**
+ * v9fs_pollwait - called by files poll operation to add v9fs-poll task
+ * 	to files wait queue
+ */
+static void
+v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address,
+	      poll_table * p)
+{
+	int i;
+	struct v9fs_mux_data *m;
+
+	m = container_of(p, struct v9fs_mux_data, pt);
+	for(i = 0; i < ARRAY_SIZE(m->poll_waddr); i++)
+		if (m->poll_waddr[i] == NULL)
+			break;
+
+	if (i >= ARRAY_SIZE(m->poll_waddr)) {
+		dprintk(DEBUG_ERROR, "not enough wait_address slots\n");
+		return;
+	}
+
+	m->poll_waddr[i] = wait_address;
+
+	if (!wait_address) {
+		dprintk(DEBUG_ERROR, "no wait_address\n");
+		m->poll_waddr[i] = ERR_PTR(-EIO);
+		return;
+	}
+
+	init_waitqueue_entry(&m->poll_wait[i], m->poll_task->task);
+	add_wait_queue(wait_address, &m->poll_wait[i]);
+}
+
+/**
+ * v9fs_poll_mux - polls a mux and schedules read or write works if necessary
+ */
+static inline void v9fs_poll_mux(struct v9fs_mux_data *m)
+{
+	int n;
+
+	if (m->err < 0)
+		return;
+
+	n = m->trans->poll(m->trans, NULL);
+	if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
+		dprintk(DEBUG_MUX, "error mux %p err %d\n", m, n);
+		if (n >= 0)
+			n = -ECONNRESET;
+		v9fs_mux_cancel(m, n);
+	}
+
+	if (n & POLLIN) {
+		set_bit(Rpending, &m->wsched);
+		dprintk(DEBUG_MUX, "mux %p can read\n", m);
+		if (!test_and_set_bit(Rworksched, &m->wsched)) {
+			dprintk(DEBUG_MUX, "schedule read work mux %p\n", m);
+			queue_work(v9fs_mux_wq, &m->rq);
+		}
+	}
+
+	if (n & POLLOUT) {
+		set_bit(Wpending, &m->wsched);
+		dprintk(DEBUG_MUX, "mux %p can write\n", m);
+		if ((m->wsize || !list_empty(&m->unsent_req_list))
+		    && !test_and_set_bit(Wworksched, &m->wsched)) {
+			dprintk(DEBUG_MUX, "schedule write work mux %p\n", m);
+			queue_work(v9fs_mux_wq, &m->wq);
+		}
+	}
+}
+
+/**
+ * v9fs_poll_proc - polls all v9fs transports for new events and queues
+ * 	the appropriate work to the work queue
+ */
+static int v9fs_poll_proc(void *a)
+{
+	struct v9fs_mux_data *m, *mtmp;
+	struct v9fs_mux_poll_task *vpt;
+
+	vpt = a;
+	dprintk(DEBUG_MUX, "start %p %p\n", current, vpt);
+	allow_signal(SIGKILL);
+	while (!kthread_should_stop()) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (signal_pending(current))
+			break;
+
+		list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) {
+			v9fs_poll_mux(m);
+		}
+
+		dprintk(DEBUG_MUX, "sleeping...\n");
+		schedule_timeout(SCHED_TIMEOUT * HZ);
+	}
+
+	__set_current_state(TASK_RUNNING);
+	dprintk(DEBUG_MUX, "finish\n");
 	return 0;
 }
+
+/**
+ * v9fs_write_work - called when a transport can send some data
+ */
+static void v9fs_write_work(void *a)
+{
+	int n, err;
+	struct v9fs_mux_data *m;
+	struct v9fs_req *req;
+
+	m = a;
+
+	if (m->err < 0) {
+		clear_bit(Wworksched, &m->wsched);
+		return;
+	}
+
+	if (!m->wsize) {
+		if (list_empty(&m->unsent_req_list)) {
+			clear_bit(Wworksched, &m->wsched);
+			return;
+		}
+
+		spin_lock(&m->lock);
+		req =
+		    list_entry(m->unsent_req_list.next, struct v9fs_req,
+			       req_list);
+		list_move_tail(&req->req_list, &m->req_list);
+		m->wbuf = req->tcall->sdata;
+		m->wsize = req->tcall->size;
+		m->wpos = 0;
+		dump_data(m->wbuf, m->wsize);
+		spin_unlock(&m->lock);
+	}
+
+	dprintk(DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos, m->wsize);
+	clear_bit(Wpending, &m->wsched);
+	err = m->trans->write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos);
+	dprintk(DEBUG_MUX, "mux %p sent %d bytes\n", m, err);
+	if (err == -EAGAIN) {
+		clear_bit(Wworksched, &m->wsched);
+		return;
+	}
+
+	if (err <= 0)
+		goto error;
+
+	m->wpos += err;
+	if (m->wpos == m->wsize)
+		m->wpos = m->wsize = 0;
+
+	if (m->wsize == 0 && !list_empty(&m->unsent_req_list)) {
+		if (test_and_clear_bit(Wpending, &m->wsched))
+			n = POLLOUT;
+		else
+			n = m->trans->poll(m->trans, NULL);
+
+		if (n & POLLOUT) {
+			dprintk(DEBUG_MUX, "schedule write work mux %p\n", m);
+			queue_work(v9fs_mux_wq, &m->wq);
+		} else
+			clear_bit(Wworksched, &m->wsched);
+	} else
+		clear_bit(Wworksched, &m->wsched);
+
+	return;
+
+      error:
+	v9fs_mux_cancel(m, err);
+	clear_bit(Wworksched, &m->wsched);
+}
+
+static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req)
+{
+	int ecode, tag;
+	struct v9fs_str *ename;
+
+	tag = req->tag;
+	if (req->rcall->id == RERROR && !req->err) {
+		ecode = req->rcall->params.rerror.errno;
+		ename = &req->rcall->params.rerror.error;
+
+		dprintk(DEBUG_MUX, "Rerror %.*s\n", ename->len, ename->str);
+
+		if (*m->extended)
+			req->err = -ecode;
+
+		if (!req->err) {
+			req->err = v9fs_errstr2errno(ename->str, ename->len);
+
+			if (!req->err) {	/* string match failed */
+				PRINT_FCALL_ERROR("unknown error", req->rcall);
+			}
+
+			if (!req->err)
+				req->err = -ESERVERFAULT;
+		}
+	} else if (req->tcall && req->rcall->id != req->tcall->id + 1) {
+		dprintk(DEBUG_ERROR, "fcall mismatch: expected %d, got %d\n",
+			req->tcall->id + 1, req->rcall->id);
+		if (!req->err)
+			req->err = -EIO;
+	}
+
+	if (req->cb && req->err != ERREQFLUSH) {
+		dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n",
+			req->tcall, req->rcall);
+
+		(*req->cb) (req->cba, req->tcall, req->rcall, req->err);
+		req->cb = NULL;
+	} else
+		kfree(req->rcall);
+
+	v9fs_mux_put_tag(m, tag);
+
+	wake_up(&m->equeue);
+	kfree(req);
+}
+
+/**
+ * v9fs_read_work - called when there is some data to be read from a transport
+ */
+static void v9fs_read_work(void *a)
+{
+	int n, err;
+	struct v9fs_mux_data *m;
+	struct v9fs_req *req, *rptr, *rreq;
+	struct v9fs_fcall *rcall;
+	char *rbuf;
+
+	m = a;
+
+	if (m->err < 0)
+		return;
+
+	rcall = NULL;
+	dprintk(DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos);
+
+	if (!m->rcall) {
+		m->rcall =
+		    kmalloc(sizeof(struct v9fs_fcall) + m->msize, GFP_KERNEL);
+		if (!m->rcall) {
+			err = -ENOMEM;
+			goto error;
+		}
+
+		m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall);
+		m->rpos = 0;
+	}
+
+	clear_bit(Rpending, &m->wsched);
+	err = m->trans->read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos);
+	dprintk(DEBUG_MUX, "mux %p got %d bytes\n", m, err);
+	if (err == -EAGAIN) {
+		clear_bit(Rworksched, &m->wsched);
+		return;
+	}
+
+	if (err <= 0)
+		goto error;
+
+	m->rpos += err;
+	while (m->rpos > 4) {
+		n = le32_to_cpu(*(__le32 *) m->rbuf);
+		if (n >= m->msize) {
+			dprintk(DEBUG_ERROR,
+				"requested packet size too big: %d\n", n);
+			err = -EIO;
+			goto error;
+		}
+
+		if (m->rpos < n)
+			break;
+
+		dump_data(m->rbuf, n);
+		err =
+		    v9fs_deserialize_fcall(m->rbuf, n, m->rcall, *m->extended);
+		if (err < 0) {
+			goto error;
+		}
+
+		rcall = m->rcall;
+		rbuf = m->rbuf;
+		if (m->rpos > n) {
+			m->rcall = kmalloc(sizeof(struct v9fs_fcall) + m->msize,
+					   GFP_KERNEL);
+			if (!m->rcall) {
+				err = -ENOMEM;
+				goto error;
+			}
+
+			m->rbuf = (char *)m->rcall + sizeof(struct v9fs_fcall);
+			memmove(m->rbuf, rbuf + n, m->rpos - n);
+			m->rpos -= n;
+		} else {
+			m->rcall = NULL;
+			m->rbuf = NULL;
+			m->rpos = 0;
+		}
+
+		dprintk(DEBUG_MUX, "mux %p fcall id %d tag %d\n", m, rcall->id,
+			rcall->tag);
+
+		req = NULL;
+		spin_lock(&m->lock);
+		list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
+			if (rreq->tag == rcall->tag) {
+				req = rreq;
+				req->rcall = rcall;
+				list_del(&req->req_list);
+				spin_unlock(&m->lock);
+				process_request(m, req);
+				break;
+			}
+
+		}
+
+		if (!req) {
+			spin_unlock(&m->lock);
+			if (err >= 0 && rcall->id != RFLUSH)
+				dprintk(DEBUG_ERROR,
+					"unexpected response mux %p id %d tag %d\n",
+					m, rcall->id, rcall->tag);
+			kfree(rcall);
+		}
+	}
+
+	if (!list_empty(&m->req_list)) {
+		if (test_and_clear_bit(Rpending, &m->wsched))
+			n = POLLIN;
+		else
+			n = m->trans->poll(m->trans, NULL);
+
+		if (n & POLLIN) {
+			dprintk(DEBUG_MUX, "schedule read work mux %p\n", m);
+			queue_work(v9fs_mux_wq, &m->rq);
+		} else
+			clear_bit(Rworksched, &m->wsched);
+	} else
+		clear_bit(Rworksched, &m->wsched);
+
+	return;
+
+      error:
+	v9fs_mux_cancel(m, err);
+	clear_bit(Rworksched, &m->wsched);
+}
+
+/**
+ * v9fs_send_request - send 9P request
+ * The function can sleep until the request is scheduled for sending.
+ * The function can be interrupted. Return from the function is not
+ * a guarantee that the request is sent succesfully. Can return errors
+ * that can be retrieved by PTR_ERR macros.
+ *
+ * @m: mux data
+ * @tc: request to be sent
+ * @cb: callback function to call when response is received
+ * @cba: parameter to pass to the callback function
+ */
+static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m,
+					  struct v9fs_fcall *tc,
+					  v9fs_mux_req_callback cb, void *cba)
+{
+	int n;
+	struct v9fs_req *req;
+
+	dprintk(DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current,
+		tc, tc->id);
+	if (m->err < 0)
+		return ERR_PTR(m->err);
+
+	req = kmalloc(sizeof(struct v9fs_req), GFP_KERNEL);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	if (tc->id == TVERSION)
+		n = V9FS_NOTAG;
+	else
+		n = v9fs_mux_get_tag(m);
+
+	if (n < 0)
+		return ERR_PTR(-ENOMEM);
+
+	v9fs_set_tag(tc, n);
+
+	req->tag = n;
+	req->tcall = tc;
+	req->rcall = NULL;
+	req->err = 0;
+	req->cb = cb;
+	req->cba = cba;
+
+	spin_lock(&m->lock);
+	list_add_tail(&req->req_list, &m->unsent_req_list);
+	spin_unlock(&m->lock);
+
+	if (test_and_clear_bit(Wpending, &m->wsched))
+		n = POLLOUT;
+	else
+		n = m->trans->poll(m->trans, NULL);
+
+	if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
+		queue_work(v9fs_mux_wq, &m->wq);
+
+	return req;
+}
+
+static inline void
+v9fs_mux_flush_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc,
+		  int err)
+{
+	v9fs_mux_req_callback cb;
+	int tag;
+	struct v9fs_mux_data *m;
+	struct v9fs_req *req, *rptr;
+
+	m = a;
+	dprintk(DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m, tc,
+		rc, err, tc->params.tflush.oldtag);
+
+	spin_lock(&m->lock);
+	cb = NULL;
+	tag = tc->params.tflush.oldtag;
+	list_for_each_entry_safe(req, rptr, &m->req_list, req_list) {
+		if (req->tag == tag) {
+			list_del(&req->req_list);
+			if (req->cb) {
+				cb = req->cb;
+				req->cb = NULL;
+				spin_unlock(&m->lock);
+				(*cb) (req->cba, req->tcall, req->rcall,
+				       req->err);
+			}
+			kfree(req);
+			wake_up(&m->equeue);
+			break;
+		}
+	}
+
+	if (!cb)
+		spin_unlock(&m->lock);
+
+	v9fs_mux_put_tag(m, tag);
+	kfree(tc);
+	kfree(rc);
+}
+
+static void
+v9fs_mux_flush_request(struct v9fs_mux_data *m, struct v9fs_req *req)
+{
+	struct v9fs_fcall *fc;
+
+	dprintk(DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag);
+
+	fc = v9fs_create_tflush(req->tag);
+	v9fs_send_request(m, fc, v9fs_mux_flush_cb, m);
+}
+
+static void
+v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err)
+{
+	struct v9fs_mux_rpc *r;
+
+	if (err == ERREQFLUSH) {
+		dprintk(DEBUG_MUX, "err req flush\n");
+		return;
+	}
+
+	r = a;
+	dprintk(DEBUG_MUX, "mux %p req %p tc %p rc %p err %d\n", r->m, r->req,
+		tc, rc, err);
+	r->rcall = rc;
+	r->err = err;
+	wake_up(&r->wqueue);
+}
+
+/**
+ * v9fs_mux_rpc - sends 9P request and waits until a response is available.
+ *	The function can be interrupted.
+ * @m: mux data
+ * @tc: request to be sent
+ * @rc: pointer where a pointer to the response is stored
+ */
+int
+v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
+	     struct v9fs_fcall **rc)
+{
+	int err;
+	unsigned long flags;
+	struct v9fs_req *req;
+	struct v9fs_mux_rpc r;
+
+	r.err = 0;
+	r.rcall = NULL;
+	r.m = m;
+	init_waitqueue_head(&r.wqueue);
+
+	if (rc)
+		*rc = NULL;
+
+	req = v9fs_send_request(m, tc, v9fs_mux_rpc_cb, &r);
+	if (IS_ERR(req)) {
+		err = PTR_ERR(req);
+		dprintk(DEBUG_MUX, "error %d\n", err);
+		return PTR_ERR(req);
+	}
+
+	r.req = req;
+	dprintk(DEBUG_MUX, "mux %p tc %p tag %d rpc %p req %p\n", m, tc,
+		req->tag, &r, req);
+	err = wait_event_interruptible(r.wqueue, r.rcall != NULL || r.err < 0);
+	if (r.err < 0)
+		err = r.err;
+
+	if (err == -ERESTARTSYS && m->trans->status == Connected && m->err == 0) {
+		spin_lock(&m->lock);
+		req->tcall = NULL;
+		req->err = ERREQFLUSH;
+		spin_unlock(&m->lock);
+
+		clear_thread_flag(TIF_SIGPENDING);
+		v9fs_mux_flush_request(m, req);
+		spin_lock_irqsave(&current->sighand->siglock, flags);
+		recalc_sigpending();
+		spin_unlock_irqrestore(&current->sighand->siglock, flags);
+	}
+
+	if (!err) {
+		if (r.rcall)
+			dprintk(DEBUG_MUX, "got response id %d tag %d\n",
+				r.rcall->id, r.rcall->tag);
+
+		if (rc)
+			*rc = r.rcall;
+		else
+			kfree(r.rcall);
+	} else {
+		kfree(r.rcall);
+		dprintk(DEBUG_MUX, "got error %d\n", err);
+		if (err > 0)
+			err = -EIO;
+	}
+
+	return err;
+}
+
+/**
+ * v9fs_mux_rpcnb - sends 9P request without waiting for response.
+ * @m: mux data
+ * @tc: request to be sent
+ * @cb: callback function to be called when response arrives
+ * @cba: value to pass to the callback function
+ */
+int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
+		   v9fs_mux_req_callback cb, void *a)
+{
+	int err;
+	struct v9fs_req *req;
+
+	req = v9fs_send_request(m, tc, cb, a);
+	if (IS_ERR(req)) {
+		err = PTR_ERR(req);
+		dprintk(DEBUG_MUX, "error %d\n", err);
+		return PTR_ERR(req);
+	}
+
+	dprintk(DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag);
+	return 0;
+}
+
+/**
+ * v9fs_mux_cancel - cancel all pending requests with error
+ * @m: mux data
+ * @err: error code
+ */
+void v9fs_mux_cancel(struct v9fs_mux_data *m, int err)
+{
+	struct v9fs_req *req, *rtmp;
+	LIST_HEAD(cancel_list);
+
+	dprintk(DEBUG_MUX, "mux %p err %d\n", m, err);
+	m->err = err;
+	spin_lock(&m->lock);
+	list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
+		list_move(&req->req_list, &cancel_list);
+	}
+	spin_unlock(&m->lock);
+
+	list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
+		list_del(&req->req_list);
+		if (!req->err)
+			req->err = err;
+
+		if (req->cb)
+			(*req->cb) (req->cba, req->tcall, req->rcall, req->err);
+		else
+			kfree(req->rcall);
+
+		kfree(req);
+	}
+
+	wake_up(&m->equeue);
+}
+
+static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m)
+{
+	int tag;
+
+	tag = v9fs_get_idpool(&m->tidpool);
+	if (tag < 0)
+		return V9FS_NOTAG;
+	else
+		return (u16) tag;
+}
+
+static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag)
+{
+	if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tidpool))
+		v9fs_put_idpool(tag, &m->tidpool);
+}
diff --git a/fs/9p/mux.h b/fs/9p/mux.h
index 4994cb1..9473b84 100644
--- a/fs/9p/mux.h
+++ b/fs/9p/mux.h
@@ -3,6 +3,7 @@
  *
  * Multiplexer Definitions
  *
+ *  Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -23,19 +24,35 @@
  *
  */
 
-/* structure to manage each RPC transaction */
+struct v9fs_mux_data;
 
-struct v9fs_rpcreq {
-	struct v9fs_fcall *tcall;
-	struct v9fs_fcall *rcall;
-	int err;	/* error code if response failed */
+/**
+ * v9fs_mux_req_callback - callback function that is called when the
+ * response of a request is received. The callback is called from
+ * a workqueue and shouldn't block.
+ *
+ * @a - the pointer that was specified when the request was send to be
+ *      passed to the callback
+ * @tc - request call
+ * @rc - response call
+ * @err - error code (non-zero if error occured)
+ */
+typedef void (*v9fs_mux_req_callback)(void *a, struct v9fs_fcall *tc,
+	struct v9fs_fcall *rc, int err);
 
-	/* XXX - could we put scatter/gather buffers here? */
+int v9fs_mux_global_init(void);
+void v9fs_mux_global_exit(void);
 
-	struct list_head next;
-};
+struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize,
+	unsigned char *extended);
+void v9fs_mux_destroy(struct v9fs_mux_data *);
 
-int v9fs_mux_init(struct v9fs_session_info *v9ses, const char *dev_name);
-long v9fs_mux_rpc(struct v9fs_session_info *v9ses,
-		  struct v9fs_fcall *tcall, struct v9fs_fcall **rcall);
-void v9fs_mux_cancel_requests(struct v9fs_session_info *v9ses, int err);
+int v9fs_mux_send(struct v9fs_mux_data *m, struct v9fs_fcall *tc);
+struct v9fs_fcall *v9fs_mux_recv(struct v9fs_mux_data *m);
+int v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc, struct v9fs_fcall **rc);
+int v9fs_mux_rpcnb(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
+	v9fs_mux_req_callback cb, void *a);
+
+void v9fs_mux_flush(struct v9fs_mux_data *m, int sendflush);
+void v9fs_mux_cancel(struct v9fs_mux_data *m, int err);
+int v9fs_errstr2errno(char *errstr, int len);
diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c
index 63b58ce..1a28ef9 100644
--- a/fs/9p/trans_fd.c
+++ b/fs/9p/trans_fd.c
@@ -3,6 +3,7 @@
  *
  * File Descriptor Transport Layer
  *
+ *  Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
  *  Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -106,9 +107,6 @@
 		return -ENOPROTOOPT;
 	}
 
-	sema_init(&trans->writelock, 1);
-	sema_init(&trans->readlock, 1);
-
 	ts = kmalloc(sizeof(struct v9fs_trans_fd), GFP_KERNEL);
 
 	if (!ts)
@@ -148,12 +146,12 @@
 	if (!trans)
 		return;
 
-	trans->status = Disconnected;
-	ts = trans->priv;
+	ts = xchg(&trans->priv, NULL);
 
 	if (!ts)
 		return;
 
+	trans->status = Disconnected;
 	if (ts->in_file)
 		fput(ts->in_file);
 
@@ -163,10 +161,55 @@
 	kfree(ts);
 }
 
+static unsigned int
+v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt)
+{
+	int ret, n;
+	struct v9fs_trans_fd *ts;
+	mm_segment_t oldfs;
+
+	if (!trans)
+		return -EIO;
+
+	ts = trans->priv;
+	if (trans->status != Connected || !ts)
+		return -EIO;
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+
+	if (!ts->in_file->f_op || !ts->in_file->f_op->poll) {
+		ret = -EIO;
+		goto end;
+	}
+
+	ret = ts->in_file->f_op->poll(ts->in_file, pt);
+
+	if (ts->out_file != ts->in_file) {
+		if (!ts->out_file->f_op || !ts->out_file->f_op->poll) {
+			ret = -EIO;
+			goto end;
+		}
+
+		n = ts->out_file->f_op->poll(ts->out_file, pt);
+
+		ret &= ~POLLOUT;
+		n &= ~POLLIN;
+
+		ret |= n;
+	}
+
+end:
+	set_fs(oldfs);
+	return ret;
+}
+
+
 struct v9fs_transport v9fs_trans_fd = {
 	.init = v9fs_fd_init,
 	.write = v9fs_fd_send,
 	.read = v9fs_fd_recv,
 	.close = v9fs_fd_close,
+	.poll = v9fs_fd_poll,
 };
 
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
index a93c2bf..44e8306 100644
--- a/fs/9p/trans_sock.c
+++ b/fs/9p/trans_sock.c
@@ -3,6 +3,7 @@
  *
  * Socket Transport Layer
  *
+ *  Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
  *  Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
  *  Copyright (C) 1995, 1996 by Olaf Kirch <okir@monad.swb.de>
@@ -26,6 +27,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/module.h>
 #include <linux/net.h>
 #include <linux/ipv6.h>
@@ -35,6 +37,7 @@
 #include <asm/uaccess.h>
 #include <linux/inet.h>
 #include <linux/idr.h>
+#include <linux/file.h>
 
 #include "debug.h"
 #include "v9fs.h"
@@ -44,6 +47,7 @@
 
 struct v9fs_trans_sock {
 	struct socket *s;
+	struct file *filp;
 };
 
 /**
@@ -56,41 +60,26 @@
 
 static int v9fs_sock_recv(struct v9fs_transport *trans, void *v, int len)
 {
-	struct msghdr msg;
-	struct kvec iov;
-	int result;
-	mm_segment_t oldfs;
-	struct v9fs_trans_sock *ts = trans ? trans->priv : NULL;
+	int ret;
+	struct v9fs_trans_sock *ts;
 
-	if (trans->status == Disconnected)
+	if (!trans || trans->status == Disconnected) {
+		dprintk(DEBUG_ERROR, "disconnected ...\n");
 		return -EREMOTEIO;
+	}
 
-	result = -EINVAL;
+	ts = trans->priv;
 
-	oldfs = get_fs();
-	set_fs(get_ds());
+	if (!(ts->filp->f_flags & O_NONBLOCK))
+		dprintk(DEBUG_ERROR, "blocking read ...\n");
 
-	iov.iov_base = v;
-	iov.iov_len = len;
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_iovlen = 1;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-	msg.msg_namelen = 0;
-	msg.msg_flags = MSG_NOSIGNAL;
-
-	result = kernel_recvmsg(ts->s, &msg, &iov, 1, len, 0);
-
-	dprintk(DEBUG_TRANS, "socket state %d\n", ts->s->state);
-	set_fs(oldfs);
-
-	if (result <= 0) {
-		if (result != -ERESTARTSYS)
+	ret = kernel_read(ts->filp, ts->filp->f_pos, v, len);
+	if (ret <= 0) {
+		if (ret != -ERESTARTSYS && ret != -EAGAIN)
 			trans->status = Disconnected;
 	}
 
-	return result;
+	return ret;
 }
 
 /**
@@ -103,40 +92,72 @@
 
 static int v9fs_sock_send(struct v9fs_transport *trans, void *v, int len)
 {
-	struct kvec iov;
-	struct msghdr msg;
-	int result = -1;
+	int ret;
 	mm_segment_t oldfs;
-	struct v9fs_trans_sock *ts = trans ? trans->priv : NULL;
+	struct v9fs_trans_sock *ts;
 
-	dprintk(DEBUG_TRANS, "Sending packet size %d (%x)\n", len, len);
-	dump_data(v, len);
+	if (!trans || trans->status == Disconnected) {
+		dprintk(DEBUG_ERROR, "disconnected ...\n");
+		return -EREMOTEIO;
+	}
 
-	down(&trans->writelock);
+	ts = trans->priv;
+	if (!ts) {
+		dprintk(DEBUG_ERROR, "no transport ...\n");
+		return -EREMOTEIO;
+	}
+
+	if (!(ts->filp->f_flags & O_NONBLOCK))
+		dprintk(DEBUG_ERROR, "blocking write ...\n");
 
 	oldfs = get_fs();
 	set_fs(get_ds());
-	iov.iov_base = v;
-	iov.iov_len = len;
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_iovlen = 1;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-	msg.msg_namelen = 0;
-	msg.msg_flags = MSG_NOSIGNAL;
-	result = kernel_sendmsg(ts->s, &msg, &iov, 1, len);
+	ret = vfs_write(ts->filp, (void __user *)v, len, &ts->filp->f_pos);
 	set_fs(oldfs);
 
-	if (result < 0) {
-		if (result != -ERESTARTSYS)
+	if (ret < 0) {
+		if (ret != -ERESTARTSYS)
 			trans->status = Disconnected;
 	}
 
-	up(&trans->writelock);
-	return result;
+	return ret;
 }
 
+static unsigned int v9fs_sock_poll(struct v9fs_transport *trans,
+	struct poll_table_struct *pt) {
+
+	int ret;
+	struct v9fs_trans_sock *ts;
+	mm_segment_t oldfs;
+
+	if (!trans) {
+		dprintk(DEBUG_ERROR, "no transport\n");
+		return -EIO;
+	}
+
+	ts = trans->priv;
+	if (trans->status != Connected || !ts) {
+		dprintk(DEBUG_ERROR, "transport disconnected: %d\n", trans->status);
+		return -EIO;
+	}
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+
+	if (!ts->filp->f_op || !ts->filp->f_op->poll) {
+		dprintk(DEBUG_ERROR, "no poll operation\n");
+		ret = -EIO;
+		goto end;
+	}
+
+	ret = ts->filp->f_op->poll(ts->filp, pt);
+
+end:
+	set_fs(oldfs);
+	return ret;
+}
+
+
 /**
  * v9fs_tcp_init - initialize TCP socket
  * @v9ses: session information
@@ -153,9 +174,9 @@
 	int rc = 0;
 	struct v9fs_trans_sock *ts = NULL;
 	struct v9fs_transport *trans = v9ses->transport;
+	int fd;
 
-	sema_init(&trans->writelock, 1);
-	sema_init(&trans->readlock, 1);
+	trans->status = Disconnected;
 
 	ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);
 
@@ -164,6 +185,7 @@
 
 	trans->priv = ts;
 	ts->s = NULL;
+	ts->filp = NULL;
 
 	if (!addr)
 		return -EINVAL;
@@ -184,7 +206,18 @@
 		return rc;
 	}
 	csocket->sk->sk_allocation = GFP_NOIO;
+
+	fd = sock_map_fd(csocket);
+	if (fd < 0) {
+		sock_release(csocket);
+		kfree(ts);
+		trans->priv = NULL;
+		return fd;
+	}
+
 	ts->s = csocket;
+	ts->filp = fget(fd);
+	ts->filp->f_flags |= O_NONBLOCK;
 	trans->status = Connected;
 
 	return 0;
@@ -202,7 +235,7 @@
 v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name,
 	       char *data)
 {
-	int rc;
+	int rc, fd;
 	struct socket *csocket;
 	struct sockaddr_un sun_server;
 	struct v9fs_transport *trans;
@@ -212,6 +245,8 @@
 	csocket = NULL;
 	trans = v9ses->transport;
 
+	trans->status = Disconnected;
+
 	if (strlen(dev_name) > UNIX_PATH_MAX) {
 		eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n",
 			dev_name);
@@ -224,9 +259,7 @@
 
 	trans->priv = ts;
 	ts->s = NULL;
-
-	sema_init(&trans->writelock, 1);
-	sema_init(&trans->readlock, 1);
+	ts->filp = NULL;
 
 	sun_server.sun_family = PF_UNIX;
 	strcpy(sun_server.sun_path, dev_name);
@@ -240,7 +273,18 @@
 		return rc;
 	}
 	csocket->sk->sk_allocation = GFP_NOIO;
+
+	fd = sock_map_fd(csocket);
+	if (fd < 0) {
+		sock_release(csocket);
+		kfree(ts);
+		trans->priv = NULL;
+		return fd;
+	}
+
 	ts->s = csocket;
+	ts->filp = fget(fd);
+	ts->filp->f_flags |= O_NONBLOCK;
 	trans->status = Connected;
 
 	return 0;
@@ -261,12 +305,11 @@
 
 	ts = trans->priv;
 
-	if ((ts) && (ts->s)) {
-		dprintk(DEBUG_TRANS, "closing the socket %p\n", ts->s);
-		sock_release(ts->s);
+	if ((ts) && (ts->filp)) {
+		fput(ts->filp);
+		ts->filp = NULL;
 		ts->s = NULL;
 		trans->status = Disconnected;
-		dprintk(DEBUG_TRANS, "socket closed\n");
 	}
 
 	kfree(ts);
@@ -279,6 +322,7 @@
 	.write = v9fs_sock_send,
 	.read = v9fs_sock_recv,
 	.close = v9fs_sock_close,
+	.poll = v9fs_sock_poll,
 };
 
 struct v9fs_transport v9fs_trans_unix = {
@@ -286,4 +330,5 @@
 	.write = v9fs_sock_send,
 	.read = v9fs_sock_recv,
 	.close = v9fs_sock_close,
+	.poll = v9fs_sock_poll,
 };
diff --git a/fs/9p/transport.h b/fs/9p/transport.h
index 9e9cd41..91fcdb9 100644
--- a/fs/9p/transport.h
+++ b/fs/9p/transport.h
@@ -3,6 +3,7 @@
  *
  * Transport Definition
  *
+ *  Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -31,14 +32,13 @@
 
 struct v9fs_transport {
 	enum v9fs_transport_status status;
-	struct semaphore writelock;
-	struct semaphore readlock;
 	void *priv;
 
 	int (*init) (struct v9fs_session_info *, const char *, char *);
 	int (*write) (struct v9fs_transport *, void *, int);
 	int (*read) (struct v9fs_transport *, void *, int);
 	void (*close) (struct v9fs_transport *);
+	unsigned int (*poll)(struct v9fs_transport *, struct poll_table_struct *);
 };
 
 extern struct v9fs_transport v9fs_trans_tcp;
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 418c374..5250c42 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -37,7 +37,6 @@
 #include "v9fs_vfs.h"
 #include "transport.h"
 #include "mux.h"
-#include "conv.h"
 
 /* TODO: sysfs or debugfs interface */
 int v9fs_debug_level = 0;	/* feature-rific global debug level  */
@@ -213,7 +212,8 @@
 		return -1;
 	}
 
-	error = idr_get_new(&p->pool, NULL, &i);
+	/* no need to store exactly p, we just need something non-null */
+	error = idr_get_new(&p->pool, p, &i);
 	up(&p->lock);
 
 	if (error == -EAGAIN)
@@ -243,6 +243,16 @@
 }
 
 /**
+ * v9fs_check_idpool - check if the specified id is available
+ * @id - id to check
+ * @p - pool
+ */
+int v9fs_check_idpool(int id, struct v9fs_idpool *p)
+{
+	return idr_find(&p->pool, id) != NULL;
+}
+
+/**
  * v9fs_session_init - initialize session
  * @v9ses: session information structure
  * @dev_name: device being mounted
@@ -259,6 +269,7 @@
 	int n = 0;
 	int newfid = -1;
 	int retval = -EINVAL;
+	struct v9fs_str *version;
 
 	v9ses->name = __getname();
 	if (!v9ses->name)
@@ -281,9 +292,6 @@
 	/* id pools that are session-dependent: FIDs and TIDs */
 	idr_init(&v9ses->fidpool.pool);
 	init_MUTEX(&v9ses->fidpool.lock);
-	idr_init(&v9ses->tidpool.pool);
-	init_MUTEX(&v9ses->tidpool.lock);
-
 
 	switch (v9ses->proto) {
 	case PROTO_TCP:
@@ -320,7 +328,12 @@
 	v9ses->shutdown = 0;
 	v9ses->session_hung = 0;
 
-	if ((retval = v9fs_mux_init(v9ses, dev_name)) < 0) {
+	v9ses->mux = v9fs_mux_init(v9ses->transport, v9ses->maxdata + V9FS_IOHDRSZ,
+		&v9ses->extended);
+
+	if (IS_ERR(v9ses->mux)) {
+		retval = PTR_ERR(v9ses->mux);
+		v9ses->mux = NULL;
 		dprintk(DEBUG_ERROR, "problem initializing mux\n");
 		goto SessCleanUp;
 	}
@@ -339,13 +352,16 @@
 			goto FreeFcall;
 		}
 
-		/* Really should check for 9P1 and report error */
-		if (!strcmp(fcall->params.rversion.version, "9P2000.u")) {
+		version = &fcall->params.rversion.version;
+		if (version->len==8 && !memcmp(version->str, "9P2000.u", 8)) {
 			dprintk(DEBUG_9P, "9P2000 UNIX extensions enabled\n");
 			v9ses->extended = 1;
-		} else {
+		} else if (version->len==6 && !memcmp(version->str, "9P2000", 6)) {
 			dprintk(DEBUG_9P, "9P2000 legacy mode enabled\n");
 			v9ses->extended = 0;
+		} else {
+			retval = -EREMOTEIO;
+			goto FreeFcall;
 		}
 
 		n = fcall->params.rversion.msize;
@@ -381,7 +397,7 @@
 	}
 
 	if (v9ses->afid != ~0) {
-		if (v9fs_t_clunk(v9ses, v9ses->afid, NULL))
+		if (v9fs_t_clunk(v9ses, v9ses->afid))
 			dprintk(DEBUG_ERROR, "clunk failed\n");
 	}
 
@@ -403,13 +419,16 @@
 
 void v9fs_session_close(struct v9fs_session_info *v9ses)
 {
-	if (v9ses->recvproc) {
-		send_sig(SIGKILL, v9ses->recvproc, 1);
-		wait_for_completion(&v9ses->proccmpl);
+	if (v9ses->mux) {
+		v9fs_mux_destroy(v9ses->mux);
+		v9ses->mux = NULL;
 	}
 
-	if (v9ses->transport)
+	if (v9ses->transport) {
 		v9ses->transport->close(v9ses->transport);
+		kfree(v9ses->transport);
+		v9ses->transport = NULL;
+	}
 
 	__putname(v9ses->name);
 	__putname(v9ses->remotename);
@@ -420,8 +439,9 @@
  * 	and cancel all pending requests.
  */
 void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
+	dprintk(DEBUG_ERROR, "cancel session %p\n", v9ses);
 	v9ses->transport->status = Disconnected;
-	v9fs_mux_cancel_requests(v9ses, -EIO);
+	v9fs_mux_cancel(v9ses->mux, -EIO);
 }
 
 extern int v9fs_error_init(void);
@@ -433,11 +453,17 @@
 
 static int __init init_v9fs(void)
 {
+	int ret;
+
 	v9fs_error_init();
 
 	printk(KERN_INFO "Installing v9fs 9P2000 file system support\n");
 
-	return register_filesystem(&v9fs_fs_type);
+	ret = v9fs_mux_global_init();
+	if (!ret)
+		ret = register_filesystem(&v9fs_fs_type);
+
+	return ret;
 }
 
 /**
@@ -447,6 +473,7 @@
 
 static void __exit exit_v9fs(void)
 {
+	v9fs_mux_global_exit();
 	unregister_filesystem(&v9fs_fs_type);
 }
 
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 45dcef4..f337da7 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -57,24 +57,14 @@
 
 	/* book keeping */
 	struct v9fs_idpool fidpool;	/* The FID pool for file descriptors */
-	struct v9fs_idpool tidpool;	/* The TID pool for transactions ids */
 
-	/* transport information */
 	struct v9fs_transport *transport;
+	struct v9fs_mux_data *mux;
 
 	int inprogress;		/* session in progress => true */
 	int shutdown;		/* session shutting down. no more attaches. */
 	unsigned char session_hung;
-
-	/* mux private data */
-	struct v9fs_fcall *curfcall;
-	wait_queue_head_t read_wait;
-	struct completion fcread;
-	struct completion proccmpl;
-	struct task_struct *recvproc;
-
-	spinlock_t muxlock;
-	struct list_head mux_fcalls;
+	struct dentry *debugfs_dir;
 };
 
 /* possible values of ->proto */
@@ -84,11 +74,14 @@
 	PROTO_FD,
 };
 
+extern struct dentry *v9fs_debugfs_root;
+
 int v9fs_session_init(struct v9fs_session_info *, const char *, char *);
 struct v9fs_session_info *v9fs_inode2v9ses(struct inode *);
 void v9fs_session_close(struct v9fs_session_info *v9ses);
 int v9fs_get_idpool(struct v9fs_idpool *p);
 void v9fs_put_idpool(int id, struct v9fs_idpool *p);
+int v9fs_check_idpool(int id, struct v9fs_idpool *p);
 void v9fs_session_cancel(struct v9fs_session_info *v9ses);
 
 #define V9FS_MAGIC 0x01021997
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 2f2cea7..c78502a 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -45,9 +45,8 @@
 
 struct inode *v9fs_get_inode(struct super_block *sb, int mode);
 ino_t v9fs_qid2ino(struct v9fs_qid *qid);
-void v9fs_mistat2inode(struct v9fs_stat *, struct inode *,
-		       struct super_block *);
+void v9fs_stat2inode(struct v9fs_stat *, struct inode *, struct super_block *);
 int v9fs_dir_release(struct inode *inode, struct file *filp);
 int v9fs_file_open(struct inode *inode, struct file *file);
-void v9fs_inode2mistat(struct inode *inode, struct v9fs_stat *mistat);
+void v9fs_inode2stat(struct inode *inode, struct v9fs_stat *stat);
 void v9fs_dentry_release(struct dentry *);
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index a6aa947..2dd806d 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -40,7 +40,6 @@
 #include "v9fs.h"
 #include "9p.h"
 #include "v9fs_vfs.h"
-#include "conv.h"
 #include "fid.h"
 
 /**
@@ -95,24 +94,22 @@
 
 void v9fs_dentry_release(struct dentry *dentry)
 {
+	int err;
+
 	dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
 
 	if (dentry->d_fsdata != NULL) {
 		struct list_head *fid_list = dentry->d_fsdata;
 		struct v9fs_fid *temp = NULL;
 		struct v9fs_fid *current_fid = NULL;
-		struct v9fs_fcall *fcall = NULL;
 
 		list_for_each_entry_safe(current_fid, temp, fid_list, list) {
-			if (v9fs_t_clunk
-			    (current_fid->v9ses, current_fid->fid, &fcall))
-				dprintk(DEBUG_ERROR, "clunk failed: %s\n",
-					FCALL_ERROR(fcall));
+			err = v9fs_t_clunk(current_fid->v9ses, current_fid->fid);
 
-			v9fs_put_idpool(current_fid->fid,
-					&current_fid->v9ses->fidpool);
+			if (err < 0)
+				dprintk(DEBUG_ERROR, "clunk failed: %d name %s\n",
+					err, dentry->d_iname);
 
-			kfree(fcall);
 			v9fs_fid_destroy(current_fid);
 		}
 
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index 57a43b8..ae6d032 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -37,8 +37,8 @@
 #include "debug.h"
 #include "v9fs.h"
 #include "9p.h"
-#include "v9fs_vfs.h"
 #include "conv.h"
+#include "v9fs_vfs.h"
 #include "fid.h"
 
 /**
@@ -74,20 +74,16 @@
 	struct inode *inode = filp->f_dentry->d_inode;
 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
 	struct v9fs_fid *file = filp->private_data;
-	unsigned int i, n;
+	unsigned int i, n, s;
 	int fid = -1;
 	int ret = 0;
-	struct v9fs_stat *mi = NULL;
+	struct v9fs_stat stat;
 	int over = 0;
 
 	dprintk(DEBUG_VFS, "name %s\n", filp->f_dentry->d_name.name);
 
 	fid = file->fid;
 
-	mi = kmalloc(v9ses->maxdata, GFP_KERNEL);
-	if (!mi)
-		return -ENOMEM;
-
 	if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) {
 		kfree(file->rdir_fcall);
 		file->rdir_fcall = NULL;
@@ -97,20 +93,20 @@
 		n = file->rdir_fcall->params.rread.count;
 		i = file->rdir_fpos;
 		while (i < n) {
-			int s = v9fs_deserialize_stat(v9ses,
-				  file->rdir_fcall->params.rread.data + i,
-			          n - i, mi, v9ses->maxdata);
+			s = v9fs_deserialize_stat(
+				file->rdir_fcall->params.rread.data + i,
+				n - i, &stat, v9ses->extended);
 
 			if (s == 0) {
 				dprintk(DEBUG_ERROR,
-					"error while deserializing mistat\n");
+					"error while deserializing stat\n");
 				ret = -EIO;
 				goto FreeStructs;
 			}
 
-			over = filldir(dirent, mi->name, strlen(mi->name),
-				    filp->f_pos, v9fs_qid2ino(&mi->qid),
-				    dt_type(mi));
+			over = filldir(dirent, stat.name.str, stat.name.len,
+				    filp->f_pos, v9fs_qid2ino(&stat.qid),
+				    dt_type(&stat));
 
 			if (over) {
 				file->rdir_fpos = i;
@@ -130,7 +126,7 @@
 
 	while (!over) {
 		ret = v9fs_t_read(v9ses, fid, filp->f_pos,
-					    v9ses->maxdata-V9FS_IOHDRSZ, &fcall);
+			v9ses->maxdata-V9FS_IOHDRSZ, &fcall);
 		if (ret < 0) {
 			dprintk(DEBUG_ERROR, "error while reading: %d: %p\n",
 				ret, fcall);
@@ -141,19 +137,18 @@
 		n = ret;
 		i = 0;
 		while (i < n) {
-			int s = v9fs_deserialize_stat(v9ses,
-			          fcall->params.rread.data + i, n - i, mi,
-			          v9ses->maxdata);
+			s = v9fs_deserialize_stat(fcall->params.rread.data + i,
+				n - i, &stat, v9ses->extended);
 
 			if (s == 0) {
 				dprintk(DEBUG_ERROR,
-					"error while deserializing mistat\n");
+					"error while deserializing stat\n");
 				return -EIO;
 			}
 
-			over = filldir(dirent, mi->name, strlen(mi->name),
-				    filp->f_pos, v9fs_qid2ino(&mi->qid),
-				    dt_type(mi));
+			over = filldir(dirent, stat.name.str, stat.name.len,
+				    filp->f_pos, v9fs_qid2ino(&stat.qid),
+				    dt_type(&stat));
 
 			if (over) {
 				file->rdir_fcall = fcall;
@@ -172,7 +167,6 @@
 
       FreeStructs:
 	kfree(fcall);
-	kfree(mi);
 	return ret;
 }
 
@@ -193,18 +187,15 @@
 		fid->fid);
 	fidnum = fid->fid;
 
-	filemap_fdatawrite(inode->i_mapping);
-	filemap_fdatawait(inode->i_mapping);
+	filemap_write_and_wait(inode->i_mapping);
 
 	if (fidnum >= 0) {
 		dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen,
 			fid->fid);
 
-		if (v9fs_t_clunk(v9ses, fidnum, NULL))
+		if (v9fs_t_clunk(v9ses, fidnum))
 			dprintk(DEBUG_ERROR, "clunk failed\n");
 
-		v9fs_put_idpool(fid->fid, &v9ses->fidpool);
-
 		kfree(fid->rdir_fcall);
 		kfree(fid);
 
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 89c849d..6852f0e 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -32,6 +32,7 @@
 #include <linux/string.h>
 #include <linux/smp_lock.h>
 #include <linux/inet.h>
+#include <linux/version.h>
 #include <linux/list.h>
 #include <asm/uaccess.h>
 #include <linux/idr.h>
@@ -117,9 +118,7 @@
 
 		result = v9fs_t_open(v9ses, newfid, open_mode, &fcall);
 		if (result < 0) {
-			dprintk(DEBUG_ERROR,
-				"open failed, open_mode 0x%x: %s\n", open_mode,
-				FCALL_ERROR(fcall));
+			PRINT_FCALL_ERROR("open failed", fcall);
 			kfree(fcall);
 			return result;
 		}
@@ -165,8 +164,7 @@
 		return -ENOLCK;
 
 	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
-		filemap_fdatawrite(inode->i_mapping);
-		filemap_fdatawait(inode->i_mapping);
+		filemap_write_and_wait(inode->i_mapping);
 		invalidate_inode_pages(&inode->i_data);
 	}
 
@@ -257,7 +255,6 @@
 	int result = -EIO;
 	int rsize = 0;
 	int total = 0;
-	char *buf;
 
 	dprintk(DEBUG_VFS, "data %p count %d offset %x\n", data, (int)count,
 		(int)*offset);
@@ -265,28 +262,14 @@
 	if (v9fid->iounit != 0 && rsize > v9fid->iounit)
 		rsize = v9fid->iounit;
 
-	buf = kmalloc(v9ses->maxdata - V9FS_IOHDRSZ, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
 	do {
 		if (count < rsize)
 			rsize = count;
 
-		result = copy_from_user(buf, data, rsize);
-		if (result) {
-			dprintk(DEBUG_ERROR, "Problem copying from user\n");
-			kfree(buf);
-			return -EFAULT;
-		}
-
-		dump_data(buf, rsize);
-		result = v9fs_t_write(v9ses, fid, *offset, rsize, buf, &fcall);
+		result = v9fs_t_write(v9ses, fid, *offset, rsize, data, &fcall);
 		if (result < 0) {
-			eprintk(KERN_ERR, "error while writing: %s(%d)\n",
-				FCALL_ERROR(fcall), result);
+			PRINT_FCALL_ERROR("error while writing", fcall);
 			kfree(fcall);
-			kfree(buf);
 			return result;
 		} else
 			*offset += result;
@@ -306,7 +289,6 @@
 		total += result;
 	} while (count);
 
-	kfree(buf);
 	return total;
 }
 
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index be72881..d933ef1 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -40,7 +40,6 @@
 #include "v9fs.h"
 #include "9p.h"
 #include "v9fs_vfs.h"
-#include "conv.h"
 #include "fid.h"
 
 static struct inode_operations v9fs_dir_inode_operations;
@@ -127,100 +126,32 @@
 }
 
 /**
- * v9fs_blank_mistat - helper function to setup a 9P stat structure
+ * v9fs_blank_wstat - helper function to setup a 9P stat structure
  * @v9ses: 9P session info (for determining extended mode)
- * @mistat: structure to initialize
+ * @wstat: structure to initialize
  *
  */
 
 static void
-v9fs_blank_mistat(struct v9fs_session_info *v9ses, struct v9fs_stat *mistat)
+v9fs_blank_wstat(struct v9fs_wstat *wstat)
 {
-	mistat->type = ~0;
-	mistat->dev = ~0;
-	mistat->qid.type = ~0;
-	mistat->qid.version = ~0;
-	*((long long *)&mistat->qid.path) = ~0;
-	mistat->mode = ~0;
-	mistat->atime = ~0;
-	mistat->mtime = ~0;
-	mistat->length = ~0;
-	mistat->name = mistat->data;
-	mistat->uid = mistat->data;
-	mistat->gid = mistat->data;
-	mistat->muid = mistat->data;
-	if (v9ses->extended) {
-		mistat->n_uid = ~0;
-		mistat->n_gid = ~0;
-		mistat->n_muid = ~0;
-		mistat->extension = mistat->data;
-	}
-	*mistat->data = 0;
-}
-
-/**
- * v9fs_mistat2unix - convert mistat to unix stat
- * @mistat: Plan 9 metadata (mistat) structure
- * @buf: unix metadata (stat) structure to populate
- * @sb: superblock
- *
- */
-
-static void
-v9fs_mistat2unix(struct v9fs_stat *mistat, struct stat *buf,
-		 struct super_block *sb)
-{
-	struct v9fs_session_info *v9ses = sb ? sb->s_fs_info : NULL;
-
-	buf->st_nlink = 1;
-
-	buf->st_atime = mistat->atime;
-	buf->st_mtime = mistat->mtime;
-	buf->st_ctime = mistat->mtime;
-
-	buf->st_uid = (unsigned short)-1;
-	buf->st_gid = (unsigned short)-1;
-
-	if (v9ses && v9ses->extended) {
-		/* TODO: string to uid mapping via user-space daemon */
-		if (mistat->n_uid != -1)
-			sscanf(mistat->uid, "%x", (unsigned int *)&buf->st_uid);
-
-		if (mistat->n_gid != -1)
-			sscanf(mistat->gid, "%x", (unsigned int *)&buf->st_gid);
-	}
-
-	if (buf->st_uid == (unsigned short)-1)
-		buf->st_uid = v9ses->uid;
-	if (buf->st_gid == (unsigned short)-1)
-		buf->st_gid = v9ses->gid;
-
-	buf->st_mode = p9mode2unixmode(v9ses, mistat->mode);
-	if ((S_ISBLK(buf->st_mode)) || (S_ISCHR(buf->st_mode))) {
-		char type = 0;
-		int major = -1;
-		int minor = -1;
-		sscanf(mistat->extension, "%c %u %u", &type, &major, &minor);
-		switch (type) {
-		case 'c':
-			buf->st_mode &= ~S_IFBLK;
-			buf->st_mode |= S_IFCHR;
-			break;
-		case 'b':
-			break;
-		default:
-			dprintk(DEBUG_ERROR, "Unknown special type %c (%s)\n",
-				type, mistat->extension);
-		};
-		buf->st_rdev = MKDEV(major, minor);
-	} else
-		buf->st_rdev = 0;
-
-	buf->st_size = mistat->length;
-
-	buf->st_blksize = sb->s_blocksize;
-	buf->st_blocks =
-	    (buf->st_size + buf->st_blksize - 1) >> sb->s_blocksize_bits;
+	wstat->type = ~0;
+	wstat->dev = ~0;
+	wstat->qid.type = ~0;
+	wstat->qid.version = ~0;
+	*((long long *)&wstat->qid.path) = ~0;
+	wstat->mode = ~0;
+	wstat->atime = ~0;
+	wstat->mtime = ~0;
+	wstat->length = ~0;
+	wstat->name = NULL;
+	wstat->uid = NULL;
+	wstat->gid = NULL;
+	wstat->muid = NULL;
+	wstat->n_uid = ~0;
+	wstat->n_gid = ~0;
+	wstat->n_muid = ~0;
+	wstat->extension = NULL;
 }
 
 /**
@@ -312,12 +243,12 @@
 	struct inode *file_inode = NULL;
 	struct v9fs_fcall *fcall = NULL;
 	struct v9fs_qid qid;
-	struct stat newstat;
 	int dirfidnum = -1;
 	long newfid = -1;
 	int result = 0;
 	unsigned int iounit = 0;
 	int wfidno = -1;
+	int err;
 
 	perm = unixmode2p9mode(v9ses, perm);
 
@@ -349,57 +280,64 @@
 
 	result = v9fs_t_walk(v9ses, dirfidnum, newfid, NULL, &fcall);
 	if (result < 0) {
-		dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
+		PRINT_FCALL_ERROR("clone error", fcall);
 		v9fs_put_idpool(newfid, &v9ses->fidpool);
 		newfid = -1;
 		goto CleanUpFid;
 	}
 
 	kfree(fcall);
+	fcall = NULL;
 
 	result = v9fs_t_create(v9ses, newfid, (char *)file_dentry->d_name.name,
 			       perm, open_mode, &fcall);
 	if (result < 0) {
-		dprintk(DEBUG_ERROR, "create fails: %s(%d)\n",
-			FCALL_ERROR(fcall), result);
-
+		PRINT_FCALL_ERROR("create fails", fcall);
 		goto CleanUpFid;
 	}
 
 	iounit = fcall->params.rcreate.iounit;
 	qid = fcall->params.rcreate.qid;
 	kfree(fcall);
+	fcall = NULL;
 
-	fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1);
-	dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate);
-	if (!fid) {
-		result = -ENOMEM;
-		goto CleanUpFid;
+	if (!(perm&V9FS_DMDIR)) {
+		fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1);
+		dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate);
+		if (!fid) {
+			result = -ENOMEM;
+			goto CleanUpFid;
+		}
+
+		fid->qid = qid;
+		fid->iounit = iounit;
+	} else {
+		err = v9fs_t_clunk(v9ses, newfid);
+		newfid = -1;
+		if (err < 0)
+			dprintk(DEBUG_ERROR, "clunk for mkdir failed: %d\n", err);
 	}
 
-	fid->qid = qid;
-	fid->iounit = iounit;
-
 	/* walk to the newly created file and put the fid in the dentry */
 	wfidno = v9fs_get_idpool(&v9ses->fidpool);
-	if (newfid < 0) {
+	if (wfidno < 0) {
 		eprintk(KERN_WARNING, "no free fids available\n");
 		return -ENOSPC;
 	}
 
 	result = v9fs_t_walk(v9ses, dirfidnum, wfidno,
-		(char *) file_dentry->d_name.name, NULL);
+		(char *) file_dentry->d_name.name, &fcall);
 	if (result < 0) {
-		dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
+		PRINT_FCALL_ERROR("clone error", fcall);
 		v9fs_put_idpool(wfidno, &v9ses->fidpool);
 		wfidno = -1;
 		goto CleanUpFid;
 	}
+	kfree(fcall);
+	fcall = NULL;
 
 	if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) {
-		if (!v9fs_t_clunk(v9ses, newfid, &fcall)) {
-			v9fs_put_idpool(wfidno, &v9ses->fidpool);
-		}
+		v9fs_put_idpool(wfidno, &v9ses->fidpool);
 
 		goto CleanUpFid;
 	}
@@ -409,60 +347,43 @@
 	    (perm & V9FS_DMDEVICE))
 		return 0;
 
-	result = v9fs_t_stat(v9ses, newfid, &fcall);
+	result = v9fs_t_stat(v9ses, wfidno, &fcall);
 	if (result < 0) {
-		dprintk(DEBUG_ERROR, "stat error: %s(%d)\n", FCALL_ERROR(fcall),
-			result);
+		PRINT_FCALL_ERROR("stat error", fcall);
 		goto CleanUpFid;
 	}
 
-	v9fs_mistat2unix(fcall->params.rstat.stat, &newstat, sb);
 
-	file_inode = v9fs_get_inode(sb, newstat.st_mode);
+	file_inode = v9fs_get_inode(sb,
+		p9mode2unixmode(v9ses, fcall->params.rstat.stat.mode));
+
 	if ((!file_inode) || IS_ERR(file_inode)) {
 		dprintk(DEBUG_ERROR, "create inode failed\n");
 		result = -EBADF;
 		goto CleanUpFid;
 	}
 
-	v9fs_mistat2inode(fcall->params.rstat.stat, file_inode, sb);
+	v9fs_stat2inode(&fcall->params.rstat.stat, file_inode, sb);
 	kfree(fcall);
+	fcall = NULL;
+	file_dentry->d_op = &v9fs_dentry_operations;
 	d_instantiate(file_dentry, file_inode);
 
-	if (perm & V9FS_DMDIR) {
-		if (!v9fs_t_clunk(v9ses, newfid, &fcall))
-			v9fs_put_idpool(newfid, &v9ses->fidpool);
-		else
-			dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n",
-				FCALL_ERROR(fcall));
-		kfree(fcall);
-		fid->fidopen = 0;
-		fid->fidcreate = 0;
-		d_drop(file_dentry);
-	}
-
 	return 0;
 
       CleanUpFid:
 	kfree(fcall);
+	fcall = NULL;
 
 	if (newfid >= 0) {
-		if (!v9fs_t_clunk(v9ses, newfid, &fcall))
-			v9fs_put_idpool(newfid, &v9ses->fidpool);
-		else
-			dprintk(DEBUG_ERROR, "clunk failed: %s\n",
-				FCALL_ERROR(fcall));
-
-		kfree(fcall);
+ 		err = v9fs_t_clunk(v9ses, newfid);
+ 		if (err < 0)
+ 			dprintk(DEBUG_ERROR, "clunk failed: %d\n", err);
 	}
 	if (wfidno >= 0) {
-		if (!v9fs_t_clunk(v9ses, wfidno, &fcall))
-			v9fs_put_idpool(wfidno, &v9ses->fidpool);
-		else
-			dprintk(DEBUG_ERROR, "clunk failed: %s\n",
-				FCALL_ERROR(fcall));
-
-		kfree(fcall);
+ 		err = v9fs_t_clunk(v9ses, wfidno);
+ 		if (err < 0)
+ 			dprintk(DEBUG_ERROR, "clunk failed: %d\n", err);
 	}
 	return result;
 }
@@ -507,10 +428,9 @@
 	}
 
 	result = v9fs_t_remove(v9ses, fid, &fcall);
-	if (result < 0)
-		dprintk(DEBUG_ERROR, "remove of file fails: %s(%d)\n",
-			FCALL_ERROR(fcall), result);
-	else {
+	if (result < 0) {
+		PRINT_FCALL_ERROR("remove fails", fcall);
+	} else {
 		v9fs_put_idpool(fid, &v9ses->fidpool);
 		v9fs_fid_destroy(v9fid);
 	}
@@ -565,7 +485,6 @@
 	struct v9fs_fid *fid;
 	struct inode *inode;
 	struct v9fs_fcall *fcall = NULL;
-	struct stat newstat;
 	int dirfidnum = -1;
 	int newfid = -1;
 	int result = 0;
@@ -618,8 +537,8 @@
 		goto FreeFcall;
 	}
 
-	v9fs_mistat2unix(fcall->params.rstat.stat, &newstat, sb);
-	inode = v9fs_get_inode(sb, newstat.st_mode);
+	inode = v9fs_get_inode(sb, p9mode2unixmode(v9ses,
+		fcall->params.rstat.stat.mode));
 
 	if (IS_ERR(inode) && (PTR_ERR(inode) == -ENOSPC)) {
 		eprintk(KERN_WARNING, "inode alloc failes, returns %ld\n",
@@ -629,7 +548,7 @@
 		goto FreeFcall;
 	}
 
-	inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid);
+	inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat.qid);
 
 	fid = v9fs_fid_create(dentry, v9ses, newfid, 0);
 	if (fid == NULL) {
@@ -638,10 +557,10 @@
 		goto FreeFcall;
 	}
 
-	fid->qid = fcall->params.rstat.stat->qid;
+	fid->qid = fcall->params.rstat.stat.qid;
 
 	dentry->d_op = &v9fs_dentry_operations;
-	v9fs_mistat2inode(fcall->params.rstat.stat, inode, inode->i_sb);
+	v9fs_stat2inode(&fcall->params.rstat.stat, inode, inode->i_sb);
 
 	d_add(dentry, inode);
 	kfree(fcall);
@@ -697,7 +616,7 @@
 	    v9fs_fid_lookup(old_dentry->d_parent);
 	struct v9fs_fid *newdirfid =
 	    v9fs_fid_lookup(new_dentry->d_parent);
-	struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
+	struct v9fs_wstat wstat;
 	struct v9fs_fcall *fcall = NULL;
 	int fid = -1;
 	int olddirfidnum = -1;
@@ -706,9 +625,6 @@
 
 	dprintk(DEBUG_VFS, "\n");
 
-	if (!mistat)
-		return -ENOMEM;
-
 	if ((!oldfid) || (!olddirfid) || (!newdirfid)) {
 		dprintk(DEBUG_ERROR, "problem with arguments\n");
 		return -EBADF;
@@ -732,26 +648,15 @@
 		goto FreeFcallnBail;
 	}
 
-	v9fs_blank_mistat(v9ses, mistat);
+	v9fs_blank_wstat(&wstat);
+	wstat.muid = v9ses->name;
+	wstat.name = (char *) new_dentry->d_name.name;
 
-	strcpy(mistat->data + 1, v9ses->name);
-	mistat->name = mistat->data + 1 + strlen(v9ses->name);
-
-	if (new_dentry->d_name.len >
-	    (v9ses->maxdata - strlen(v9ses->name) - sizeof(struct v9fs_stat))) {
-		dprintk(DEBUG_ERROR, "new name too long\n");
-		goto FreeFcallnBail;
-	}
-
-	strcpy(mistat->name, new_dentry->d_name.name);
-	retval = v9fs_t_wstat(v9ses, fid, mistat, &fcall);
+	retval = v9fs_t_wstat(v9ses, fid, &wstat, &fcall);
 
       FreeFcallnBail:
-	kfree(mistat);
-
 	if (retval < 0)
-		dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
-			FCALL_ERROR(fcall));
+		PRINT_FCALL_ERROR("wstat error", fcall);
 
 	kfree(fcall);
 	return retval;
@@ -786,7 +691,7 @@
 	if (err < 0)
 		dprintk(DEBUG_ERROR, "stat error\n");
 	else {
-		v9fs_mistat2inode(fcall->params.rstat.stat, dentry->d_inode,
+		v9fs_stat2inode(&fcall->params.rstat.stat, dentry->d_inode,
 				  dentry->d_inode->i_sb);
 		generic_fillattr(dentry->d_inode, stat);
 	}
@@ -807,57 +712,44 @@
 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
 	struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
 	struct v9fs_fcall *fcall = NULL;
-	struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
+	struct v9fs_wstat wstat;
 	int res = -EPERM;
 
 	dprintk(DEBUG_VFS, "\n");
 
-	if (!mistat)
-		return -ENOMEM;
-
 	if (!fid) {
 		dprintk(DEBUG_ERROR,
 			"Couldn't find fid associated with dentry\n");
 		return -EBADF;
 	}
 
-	v9fs_blank_mistat(v9ses, mistat);
+	v9fs_blank_wstat(&wstat);
 	if (iattr->ia_valid & ATTR_MODE)
-		mistat->mode = unixmode2p9mode(v9ses, iattr->ia_mode);
+		wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode);
 
 	if (iattr->ia_valid & ATTR_MTIME)
-		mistat->mtime = iattr->ia_mtime.tv_sec;
+		wstat.mtime = iattr->ia_mtime.tv_sec;
 
 	if (iattr->ia_valid & ATTR_ATIME)
-		mistat->atime = iattr->ia_atime.tv_sec;
+		wstat.atime = iattr->ia_atime.tv_sec;
 
 	if (iattr->ia_valid & ATTR_SIZE)
-		mistat->length = iattr->ia_size;
+		wstat.length = iattr->ia_size;
 
 	if (v9ses->extended) {
-		char *ptr = mistat->data+1;
+		if (iattr->ia_valid & ATTR_UID)
+			wstat.n_uid = iattr->ia_uid;
 
-		if (iattr->ia_valid & ATTR_UID) {
-			mistat->uid = ptr;
-			ptr += 1+sprintf(ptr, "%08x", iattr->ia_uid);
-			mistat->n_uid = iattr->ia_uid;
-		}
-
-		if (iattr->ia_valid & ATTR_GID) {
-			mistat->gid = ptr;
-			ptr += 1+sprintf(ptr, "%08x", iattr->ia_gid);
-			mistat->n_gid = iattr->ia_gid;
-		}
+		if (iattr->ia_valid & ATTR_GID)
+			wstat.n_gid = iattr->ia_gid;
 	}
 
-	res = v9fs_t_wstat(v9ses, fid->fid, mistat, &fcall);
+	res = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall);
 
 	if (res < 0)
-		dprintk(DEBUG_ERROR, "wstat error: %s\n", FCALL_ERROR(fcall));
+		PRINT_FCALL_ERROR("wstat error", fcall);
 
-	kfree(mistat);
 	kfree(fcall);
-
 	if (res >= 0)
 		res = inode_setattr(dentry->d_inode, iattr);
 
@@ -865,51 +757,47 @@
 }
 
 /**
- * v9fs_mistat2inode - populate an inode structure with mistat info
- * @mistat: Plan 9 metadata (mistat) structure
+ * v9fs_stat2inode - populate an inode structure with mistat info
+ * @stat: Plan 9 metadata (mistat) structure
  * @inode: inode to populate
  * @sb: superblock of filesystem
  *
  */
 
 void
-v9fs_mistat2inode(struct v9fs_stat *mistat, struct inode *inode,
-		  struct super_block *sb)
+v9fs_stat2inode(struct v9fs_stat *stat, struct inode *inode,
+	struct super_block *sb)
 {
+	int n;
+	char ext[32];
 	struct v9fs_session_info *v9ses = sb->s_fs_info;
 
 	inode->i_nlink = 1;
 
-	inode->i_atime.tv_sec = mistat->atime;
-	inode->i_mtime.tv_sec = mistat->mtime;
-	inode->i_ctime.tv_sec = mistat->mtime;
+	inode->i_atime.tv_sec = stat->atime;
+	inode->i_mtime.tv_sec = stat->mtime;
+	inode->i_ctime.tv_sec = stat->mtime;
 
-	inode->i_uid = -1;
-	inode->i_gid = -1;
+	inode->i_uid = v9ses->uid;
+	inode->i_gid = v9ses->gid;
 
 	if (v9ses->extended) {
-		/* TODO: string to uid mapping via user-space daemon */
-		inode->i_uid = mistat->n_uid;
-		inode->i_gid = mistat->n_gid;
-
-		if (mistat->n_uid == -1)
-			sscanf(mistat->uid, "%x", &inode->i_uid);
-
-		if (mistat->n_gid == -1)
-			sscanf(mistat->gid, "%x", &inode->i_gid);
+		inode->i_uid = stat->n_uid;
+		inode->i_gid = stat->n_gid;
 	}
 
-	if (inode->i_uid == -1)
-		inode->i_uid = v9ses->uid;
-	if (inode->i_gid == -1)
-		inode->i_gid = v9ses->gid;
-
-	inode->i_mode = p9mode2unixmode(v9ses, mistat->mode);
+	inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
 	if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
 		char type = 0;
 		int major = -1;
 		int minor = -1;
-		sscanf(mistat->extension, "%c %u %u", &type, &major, &minor);
+
+		n = stat->extension.len;
+		if (n > sizeof(ext)-1)
+			n = sizeof(ext)-1;
+		memmove(ext, stat->extension.str, n);
+		ext[n] = 0;
+		sscanf(ext, "%c %u %u", &type, &major, &minor);
 		switch (type) {
 		case 'c':
 			inode->i_mode &= ~S_IFBLK;
@@ -918,14 +806,14 @@
 		case 'b':
 			break;
 		default:
-			dprintk(DEBUG_ERROR, "Unknown special type %c (%s)\n",
-				type, mistat->extension);
+			dprintk(DEBUG_ERROR, "Unknown special type %c (%.*s)\n",
+				type, stat->extension.len, stat->extension.str);
 		};
 		inode->i_rdev = MKDEV(major, minor);
 	} else
 		inode->i_rdev = 0;
 
-	inode->i_size = mistat->length;
+	inode->i_size = stat->length;
 
 	inode->i_blksize = sb->s_blocksize;
 	inode->i_blocks =
@@ -953,71 +841,6 @@
 }
 
 /**
- * v9fs_vfs_symlink - helper function to create symlinks
- * @dir: directory inode containing symlink
- * @dentry: dentry for symlink
- * @symname: symlink data
- *
- * See 9P2000.u RFC for more information
- *
- */
-
-static int
-v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
-{
-	int retval = -EPERM;
-	struct v9fs_fid *newfid;
-	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
-	struct v9fs_fcall *fcall = NULL;
-	struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
-
-	dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
-		symname);
-
-	if (!mistat)
-		return -ENOMEM;
-
-	if (!v9ses->extended) {
-		dprintk(DEBUG_ERROR, "not extended\n");
-		goto FreeFcall;
-	}
-
-	/* issue a create */
-	retval = v9fs_create(dir, dentry, S_IFLNK, 0);
-	if (retval != 0)
-		goto FreeFcall;
-
-	newfid = v9fs_fid_lookup(dentry);
-
-	/* issue a twstat */
-	v9fs_blank_mistat(v9ses, mistat);
-	strcpy(mistat->data + 1, symname);
-	mistat->extension = mistat->data + 1;
-	retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
-	if (retval < 0) {
-		dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
-			FCALL_ERROR(fcall));
-		goto FreeFcall;
-	}
-
-	kfree(fcall);
-
-	if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
-		dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
-			FCALL_ERROR(fcall));
-		goto FreeFcall;
-	}
-
-	d_drop(dentry);		/* FID - will this also clunk? */
-
-      FreeFcall:
-	kfree(mistat);
-	kfree(fcall);
-
-	return retval;
-}
-
-/**
  * v9fs_readlink - read a symlink's location (internal version)
  * @dentry: dentry for symlink
  * @buffer: buffer to load symlink location into
@@ -1056,16 +879,17 @@
 	if (!fcall)
 		return -EIO;
 
-	if (!(fcall->params.rstat.stat->mode & V9FS_DMSYMLINK)) {
+	if (!(fcall->params.rstat.stat.mode & V9FS_DMSYMLINK)) {
 		retval = -EINVAL;
 		goto FreeFcall;
 	}
 
 	/* copy extension buffer into buffer */
-	if (strlen(fcall->params.rstat.stat->extension) < buflen)
-		buflen = strlen(fcall->params.rstat.stat->extension);
+	if (fcall->params.rstat.stat.extension.len < buflen)
+		buflen = fcall->params.rstat.stat.extension.len;
 
-	memcpy(buffer, fcall->params.rstat.stat->extension, buflen + 1);
+	memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1);
+	buffer[buflen-1] = 0;
 
 	retval = buflen;
 
@@ -1155,6 +979,77 @@
 		__putname(s);
 }
 
+static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
+	int mode, const char *extension)
+{
+	int err, retval;
+	struct v9fs_session_info *v9ses;
+	struct v9fs_fcall *fcall;
+	struct v9fs_fid *fid;
+	struct v9fs_wstat wstat;
+
+	v9ses = v9fs_inode2v9ses(dir);
+	retval = -EPERM;
+	fcall = NULL;
+
+	if (!v9ses->extended) {
+		dprintk(DEBUG_ERROR, "not extended\n");
+		goto free_mem;
+	}
+
+	/* issue a create */
+	retval = v9fs_create(dir, dentry, mode, 0);
+	if (retval != 0)
+		goto free_mem;
+
+	fid = v9fs_fid_get_created(dentry);
+	if (!fid) {
+		dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n");
+		goto free_mem;
+	}
+
+	/* issue a Twstat */
+	v9fs_blank_wstat(&wstat);
+	wstat.muid = v9ses->name;
+	wstat.extension = (char *) extension;
+	retval = v9fs_t_wstat(v9ses, fid->fid, &wstat, &fcall);
+	if (retval < 0) {
+		PRINT_FCALL_ERROR("wstat error", fcall);
+		goto free_mem;
+	}
+
+	err = v9fs_t_clunk(v9ses, fid->fid);
+	if (err < 0) {
+		dprintk(DEBUG_ERROR, "clunk failed: %d\n", err);
+		goto free_mem;
+	}
+
+	d_drop(dentry);		/* FID - will this also clunk? */
+
+free_mem:
+	kfree(fcall);
+	return retval;
+}
+
+/**
+ * v9fs_vfs_symlink - helper function to create symlinks
+ * @dir: directory inode containing symlink
+ * @dentry: dentry for symlink
+ * @symname: symlink data
+ *
+ * See 9P2000.u RFC for more information
+ *
+ */
+
+static int
+v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+	dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
+		symname);
+
+	return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname);
+}
+
 /**
  * v9fs_vfs_link - create a hardlink
  * @old_dentry: dentry for file to link to
@@ -1171,64 +1066,24 @@
 v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
 	      struct dentry *dentry)
 {
-	int retval = -EPERM;
-	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
-	struct v9fs_fcall *fcall = NULL;
-	struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
-	struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry);
-	struct v9fs_fid *newfid = NULL;
-	char *symname = __getname();
+	int retval;
+	struct v9fs_fid *oldfid;
+	char *name;
 
 	dprintk(DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
 		old_dentry->d_name.name);
 
-	if (!v9ses->extended) {
-		dprintk(DEBUG_ERROR, "not extended\n");
-		goto FreeMem;
+	oldfid = v9fs_fid_lookup(old_dentry);
+	if (!oldfid) {
+		dprintk(DEBUG_ERROR, "can't find oldfid\n");
+		return -EPERM;
 	}
 
-	/* get fid of old_dentry */
-	sprintf(symname, "hardlink(%d)\n", oldfid->fid);
+	name = __getname();
+	sprintf(name, "hardlink(%d)\n", oldfid->fid);
+	retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name);
+	__putname(name);
 
-	/* issue a create */
-	retval = v9fs_create(dir, dentry, V9FS_DMLINK, 0);
-	if (retval != 0)
-		goto FreeMem;
-
-	newfid = v9fs_fid_lookup(dentry);
-	if (!newfid) {
-		dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n");
-		goto FreeMem;
-	}
-
-	/* issue a twstat */
-	v9fs_blank_mistat(v9ses, mistat);
-	strcpy(mistat->data + 1, symname);
-	mistat->extension = mistat->data + 1;
-	retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
-	if (retval < 0) {
-		dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
-			FCALL_ERROR(fcall));
-		goto FreeMem;
-	}
-
-	kfree(fcall);
-
-	if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
-		dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
-			FCALL_ERROR(fcall));
-		goto FreeMem;
-	}
-
-	d_drop(dentry);		/* FID - will this also clunk? */
-
-	kfree(fcall);
-	fcall = NULL;
-
-      FreeMem:
-	kfree(mistat);
-	kfree(fcall);
-	__putname(symname);
 	return retval;
 }
 
@@ -1244,82 +1099,30 @@
 static int
 v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
 {
-	int retval = -EPERM;
-	struct v9fs_fid *newfid;
-	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
-	struct v9fs_fcall *fcall = NULL;
-	struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
-	char *symname = __getname();
+	int retval;
+	char *name;
 
 	dprintk(DEBUG_VFS, " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
 		dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
 
-	if (!mistat)
-		return -ENOMEM;
+	if (!new_valid_dev(rdev))
+		return -EINVAL;
 
-	if (!new_valid_dev(rdev)) {
-		retval = -EINVAL;
-		goto FreeMem;
-	}
-
-	if (!v9ses->extended) {
-		dprintk(DEBUG_ERROR, "not extended\n");
-		goto FreeMem;
-	}
-
-	/* issue a create */
-	retval = v9fs_create(dir, dentry, mode, 0);
-
-	if (retval != 0)
-		goto FreeMem;
-
-	newfid = v9fs_fid_lookup(dentry);
-	if (!newfid) {
-		dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n");
-		retval = -EINVAL;
-		goto FreeMem;
-	}
-
+	name = __getname();
 	/* build extension */
 	if (S_ISBLK(mode))
-		sprintf(symname, "b %u %u", MAJOR(rdev), MINOR(rdev));
+		sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev));
 	else if (S_ISCHR(mode))
-		sprintf(symname, "c %u %u", MAJOR(rdev), MINOR(rdev));
+		sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev));
 	else if (S_ISFIFO(mode))
-		;	/* DO NOTHING */
+		*name = 0;
 	else {
-		retval = -EINVAL;
-		goto FreeMem;
+		__putname(name);
+		return -EINVAL;
 	}
 
-	if (!S_ISFIFO(mode)) {
-		/* issue a twstat */
-		v9fs_blank_mistat(v9ses, mistat);
-		strcpy(mistat->data + 1, symname);
-		mistat->extension = mistat->data + 1;
-		retval = v9fs_t_wstat(v9ses, newfid->fid, mistat, &fcall);
-		if (retval < 0) {
-			dprintk(DEBUG_ERROR, "v9fs_t_wstat error: %s\n",
-				FCALL_ERROR(fcall));
-			goto FreeMem;
-		}
-	}
-
-	/* need to update dcache so we show up */
-	kfree(fcall);
-
-	if (v9fs_t_clunk(v9ses, newfid->fid, &fcall)) {
-		dprintk(DEBUG_ERROR, "clunk for symlink failed: %s\n",
-			FCALL_ERROR(fcall));
-		goto FreeMem;
-	}
-
-	d_drop(dentry);		/* FID - will this also clunk? */
-
-      FreeMem:
-	kfree(mistat);
-	kfree(fcall);
-	__putname(symname);
+	retval = v9fs_vfs_mkspecial(dir, dentry, mode, name);
+	__putname(name);
 
 	return retval;
 }
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 82c5b00..ae0f06b 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -44,7 +44,6 @@
 #include "v9fs.h"
 #include "9p.h"
 #include "v9fs_vfs.h"
-#include "conv.h"
 #include "fid.h"
 
 static void v9fs_clear_inode(struct inode *);
@@ -123,12 +122,13 @@
 
 	dprintk(DEBUG_VFS, " \n");
 
-	v9ses = kcalloc(1, sizeof(struct v9fs_session_info), GFP_KERNEL);
+	v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
 	if (!v9ses)
 		return ERR_PTR(-ENOMEM);
 
 	if ((newfid = v9fs_session_init(v9ses, dev_name, data)) < 0) {
 		dprintk(DEBUG_ERROR, "problem initiating session\n");
+		kfree(v9ses);
 		return ERR_PTR(newfid);
 	}
 
@@ -157,7 +157,7 @@
 	stat_result = v9fs_t_stat(v9ses, newfid, &fcall);
 	if (stat_result < 0) {
 		dprintk(DEBUG_ERROR, "stat error\n");
-		v9fs_t_clunk(v9ses, newfid, NULL);
+		v9fs_t_clunk(v9ses, newfid);
 		v9fs_put_idpool(newfid, &v9ses->fidpool);
 	} else {
 		/* Setup the Root Inode */
@@ -167,10 +167,10 @@
 			goto put_back_sb;
 		}
 
-		root_fid->qid = fcall->params.rstat.stat->qid;
+		root_fid->qid = fcall->params.rstat.stat.qid;
 		root->d_inode->i_ino =
-		    v9fs_qid2ino(&fcall->params.rstat.stat->qid);
-		v9fs_mistat2inode(fcall->params.rstat.stat, root->d_inode, sb);
+		    v9fs_qid2ino(&fcall->params.rstat.stat.qid);
+		v9fs_stat2inode(&fcall->params.rstat.stat, root->d_inode, sb);
 	}
 
 	kfree(fcall);
diff --git a/fs/Kconfig b/fs/Kconfig
index d5255e6..382e3b2 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -70,6 +70,7 @@
 
 config EXT3_FS
 	tristate "Ext3 journalling file system support"
+	select JBD
 	help
 	  This is the journaling version of the Second extended file system
 	  (often called ext3), the de facto standard Linux file system
@@ -138,23 +139,20 @@
 	  extended attributes for file security labels, say N.
 
 config JBD
-# CONFIG_JBD could be its own option (even modular), but until there are
-# other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS
-# dep_tristate '  Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS
 	tristate
-	default EXT3_FS
 	help
 	  This is a generic journaling layer for block devices.  It is
-	  currently used by the ext3 file system, but it could also be used to
-	  add journal support to other file systems or block devices such as
-	  RAID or LVM.
+	  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.
 
-	  If you are using the ext3 file system, you need to say Y here. If
-	  you are not using ext3 then you will probably want to say N.
+	  If you are using the ext3 or OCFS2 file systems, you need to
+	  say Y here. If you are not using ext3 OCFS2 then you will probably
+	  want to say N.
 
 	  To compile this device as a module, choose M here: the module will be
-	  called jbd.  If you are compiling ext3 into the kernel, you cannot
-	  compile this code as a module.
+	  called jbd.  If you are compiling ext3 or OCFS2 into the kernel,
+	  you cannot compile this code as a module.
 
 config JBD_DEBUG
 	bool "JBD (ext3) debugging support"
@@ -326,6 +324,38 @@
 
 source "fs/xfs/Kconfig"
 
+config OCFS2_FS
+	tristate "OCFS2 file system support (EXPERIMENTAL)"
+	depends on NET && EXPERIMENTAL
+	select CONFIGFS_FS
+	select JBD
+	select CRC32
+	select INET
+	help
+	  OCFS2 is a general purpose extent based shared disk cluster file
+	  system with many similarities to ext3. It supports 64 bit inode
+	  numbers, and has automatically extending metadata groups which may
+	  also make it attractive for non-clustered use.
+
+	  You'll want to install the ocfs2-tools package in order to at least
+	  get "mount.ocfs2".
+
+	  Project web page:    http://oss.oracle.com/projects/ocfs2
+	  Tools web page:      http://oss.oracle.com/projects/ocfs2-tools
+	  OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
+
+	  Note: Features which OCFS2 does not support yet:
+	          - extended attributes
+		  - shared writeable mmap
+	          - loopback is supported, but data written will not
+	            be cluster coherent.
+	          - quotas
+	          - cluster aware flock
+	          - Directory change notification (F_NOTIFY)
+	          - Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
+	          - POSIX ACLs
+	          - readpages / writepages (not user visible)
+
 config MINIX_FS
 	tristate "Minix fs support"
 	help
@@ -841,6 +871,20 @@
 
 	  If unsure, say N.
 
+config CONFIGFS_FS
+	tristate "Userspace-driven configuration filesystem (EXPERIMENTAL)"
+	depends on EXPERIMENTAL
+	help
+	  configfs is a ram-based filesystem that provides the converse
+	  of sysfs's functionality. Where sysfs is a filesystem-based
+	  view of kernel objects, configfs is a filesystem-based manager
+	  of kernel objects, or config_items.
+
+	  Both sysfs and configfs can and should exist together on the
+	  same system. One is not a replacement for the other.
+
+	  If unsure, say N.
+
 endmenu
 
 menu "Miscellaneous filesystems"
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 175b2e8..f3d3d81 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -1,6 +1,6 @@
 config BINFMT_ELF
 	bool "Kernel support for ELF binaries"
-	depends on MMU
+	depends on MMU && (BROKEN || !FRV)
 	default y
 	---help---
 	  ELF (Executable and Linkable Format) is a format for libraries and
diff --git a/fs/Makefile b/fs/Makefile
index 4c26557..35e9aec 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,7 +10,7 @@
 		ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \
 		attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
 		seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \
-		ioprio.o pnode.o
+		ioprio.o pnode.o drop_caches.o
 
 obj-$(CONFIG_INOTIFY)		+= inotify.o
 obj-$(CONFIG_EPOLL)		+= eventpoll.o
@@ -101,3 +101,5 @@
 obj-$(CONFIG_HOSTFS)		+= hostfs/
 obj-$(CONFIG_HPPFS)		+= hppfs/
 obj-$(CONFIG_DEBUG_FS)		+= debugfs/
+obj-$(CONFIG_CONFIGFS_FS)	+= configfs/
+obj-$(CONFIG_OCFS2_FS)		+= ocfs2/
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 6682d6d..5c61c24 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -137,7 +137,7 @@
 #endif
 
 	/* determine how many magic numbers there should be in this page */
-	latter = dir->i_size - (page->index << PAGE_CACHE_SHIFT);
+	latter = dir->i_size - page_offset(page);
 	if (latter >= PAGE_SIZE)
 		qty = PAGE_SIZE;
 	else
diff --git a/fs/afs/volume.h b/fs/afs/volume.h
index 1e69188..bfdcf19 100644
--- a/fs/afs/volume.h
+++ b/fs/afs/volume.h
@@ -18,8 +18,6 @@
 #include "kafsasyncd.h"
 #include "cache.h"
 
-#define __packed __attribute__((packed))
-
 typedef enum {
 	AFS_VLUPD_SLEEP,		/* sleeping waiting for update timer to fire */
 	AFS_VLUPD_PENDING,		/* on pending queue */
@@ -115,7 +113,7 @@
 	struct cachefs_cookie	*cache;		/* caching cookie */
 #endif
 	afs_volid_t		vid;		/* volume ID */
-	afs_voltype_t __packed	type;		/* type of volume */
+	afs_voltype_t		type;		/* type of volume */
 	char			type_force;	/* force volume type (suppress R/O -> R/W) */
 	unsigned short		nservers;	/* number of server slots filled */
 	unsigned short		rjservers;	/* number of servers discarded due to -ENOMEDIUM */
diff --git a/fs/aio.c b/fs/aio.c
index 5a28b69..aec2b19 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -29,7 +29,6 @@
 #include <linux/highmem.h>
 #include <linux/workqueue.h>
 #include <linux/security.h>
-#include <linux/rcuref.h>
 
 #include <asm/kmap_types.h>
 #include <asm/uaccess.h>
@@ -514,7 +513,7 @@
 	/* Must be done under the lock to serialise against cancellation.
 	 * Call this aio_fput as it duplicates fput via the fput_work.
 	 */
-	if (unlikely(rcuref_dec_and_test(&req->ki_filp->f_count))) {
+	if (unlikely(atomic_dec_and_test(&req->ki_filp->f_count))) {
 		get_ioctx(ctx);
 		spin_lock(&fput_lock);
 		list_add(&req->ki_list, &fput_head);
diff --git a/fs/attr.c b/fs/attr.c
index 67bcd9b..b347325 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -67,20 +67,12 @@
 int inode_setattr(struct inode * inode, struct iattr * attr)
 {
 	unsigned int ia_valid = attr->ia_valid;
-	int error = 0;
 
-	if (ia_valid & ATTR_SIZE) {
-		if (attr->ia_size != i_size_read(inode)) {
-			error = vmtruncate(inode, attr->ia_size);
-			if (error || (ia_valid == ATTR_SIZE))
-				goto out;
-		} else {
-			/*
-			 * We skipped the truncate but must still update
-			 * timestamps
-			 */
-			ia_valid |= ATTR_MTIME|ATTR_CTIME;
-		}
+	if (ia_valid & ATTR_SIZE &&
+	    attr->ia_size != i_size_read(inode)) {
+		int error = vmtruncate(inode, attr->ia_size);
+		if (error)
+			return error;
 	}
 
 	if (ia_valid & ATTR_UID)
@@ -104,8 +96,8 @@
 		inode->i_mode = mode;
 	}
 	mark_inode_dirty(inode);
-out:
-	return error;
+
+	return 0;
 }
 EXPORT_SYMBOL(inode_setattr);
 
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index fca83e2..385bed0 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -209,7 +209,7 @@
 	struct dentry *child;
 	int ret = 0;
 
-	list_for_each_entry(child, &dentry->d_subdirs, d_child)
+	list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
 		if (simple_positive(child))
 			goto out;
 	ret = 1;
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index feb6ac4..dc39589 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -105,7 +105,7 @@
 	next = this_parent->d_subdirs.next;
 resume:
 	while (next != &this_parent->d_subdirs) {
-		struct dentry *dentry = list_entry(next, struct dentry, d_child);
+		struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
 
 		/* Negative dentry - give up */
 		if (!simple_positive(dentry)) {
@@ -138,7 +138,7 @@
 	}
 
 	if (this_parent != top) {
-		next = this_parent->d_child.next;
+		next = this_parent->d_u.d_child.next;
 		this_parent = this_parent->d_parent;
 		goto resume;
 	}
@@ -163,7 +163,7 @@
 	next = this_parent->d_subdirs.next;
 resume:
 	while (next != &this_parent->d_subdirs) {
-		struct dentry *dentry = list_entry(next, struct dentry, d_child);
+		struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
 
 		/* Negative dentry - give up */
 		if (!simple_positive(dentry)) {
@@ -199,7 +199,7 @@
 	}
 
 	if (this_parent != parent) {
-		next = this_parent->d_child.next;
+		next = this_parent->d_u.d_child.next;
 		this_parent = this_parent->d_parent;
 		goto resume;
 	}
@@ -238,7 +238,7 @@
 	/* On exit from the loop expire is set to a dgot dentry
 	 * to expire or it's NULL */
 	while ( next != &root->d_subdirs ) {
-		struct dentry *dentry = list_entry(next, struct dentry, d_child);
+		struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
 
 		/* Negative dentry - give up */
 		if ( !simple_positive(dentry) ) {
@@ -302,7 +302,7 @@
 			expired, (int)expired->d_name.len, expired->d_name.name);
 		spin_lock(&dcache_lock);
 		list_del(&expired->d_parent->d_subdirs);
-		list_add(&expired->d_parent->d_subdirs, &expired->d_child);
+		list_add(&expired->d_parent->d_subdirs, &expired->d_u.d_child);
 		spin_unlock(&dcache_lock);
 		return expired;
 	}
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 818b37b..2d30828 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -91,7 +91,7 @@
 	next = this_parent->d_subdirs.next;
 resume:
 	while (next != &this_parent->d_subdirs) {
-		struct dentry *dentry = list_entry(next, struct dentry, d_child);
+		struct dentry *dentry = list_entry(next, struct dentry, d_u.d_child);
 
 		/* Negative dentry - don`t care */
 		if (!simple_positive(dentry)) {
@@ -117,7 +117,7 @@
 	if (this_parent != sbi->root) {
 		struct dentry *dentry = this_parent;
 
-		next = this_parent->d_child.next;
+		next = this_parent->d_u.d_child.next;
 		this_parent = this_parent->d_parent;
 		spin_unlock(&dcache_lock);
 		DPRINTK("parent dentry %p %.*s",
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 2a771ec..2241405 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -143,7 +143,8 @@
 			}
 
 			while(1) {
-				struct dentry *de = list_entry(list, struct dentry, d_child);
+				struct dentry *de = list_entry(list,
+						struct dentry, d_u.d_child);
 
 				if (!d_unhashed(de) && de->d_inode) {
 					spin_unlock(&dcache_lock);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index f36f221..80ca932 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -58,7 +58,7 @@
  * If we don't support core dumping, then supply a NULL so we
  * don't even try.
  */
-#ifdef USE_ELF_CORE_DUMP
+#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
 static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file);
 #else
 #define elf_core_dump	NULL
@@ -288,11 +288,17 @@
 			struct elf_phdr *eppnt, int prot, int type)
 {
 	unsigned long map_addr;
+	unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr);
 
 	down_write(&current->mm->mmap_sem);
-	map_addr = do_mmap(filep, ELF_PAGESTART(addr),
-			   eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr), prot, type,
-			   eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr));
+	/* mmap() will return -EINVAL if given a zero size, but a
+	 * segment with zero filesize is perfectly valid */
+	if (eppnt->p_filesz + pageoffset)
+		map_addr = do_mmap(filep, ELF_PAGESTART(addr),
+				   eppnt->p_filesz + pageoffset, prot, type,
+				   eppnt->p_offset - pageoffset);
+	else
+		map_addr = ELF_PAGESTART(addr);
 	up_write(&current->mm->mmap_sem);
 	return(map_addr);
 }
@@ -1107,7 +1113,7 @@
  * Note that some platforms still use traditional core dumps and not
  * the ELF core dump.  Each platform can select it as appropriate.
  */
-#ifdef USE_ELF_CORE_DUMP
+#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
 
 /*
  * ELF core dumper
diff --git a/fs/bio.c b/fs/bio.c
index 460554b..dfe242a2 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -313,7 +313,8 @@
 }
 
 static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page
-			  *page, unsigned int len, unsigned int offset)
+			  *page, unsigned int len, unsigned int offset,
+			  unsigned short max_sectors)
 {
 	int retried_segments = 0;
 	struct bio_vec *bvec;
@@ -324,10 +325,31 @@
 	if (unlikely(bio_flagged(bio, BIO_CLONED)))
 		return 0;
 
-	if (bio->bi_vcnt >= bio->bi_max_vecs)
+	if (((bio->bi_size + len) >> 9) > max_sectors)
 		return 0;
 
-	if (((bio->bi_size + len) >> 9) > q->max_sectors)
+	/*
+	 * For filesystems with a blocksize smaller than the pagesize
+	 * we will often be called with the same page as last time and
+	 * a consecutive offset.  Optimize this special case.
+	 */
+	if (bio->bi_vcnt > 0) {
+		struct bio_vec *prev = &bio->bi_io_vec[bio->bi_vcnt - 1];
+
+		if (page == prev->bv_page &&
+		    offset == prev->bv_offset + prev->bv_len) {
+			prev->bv_len += len;
+			if (q->merge_bvec_fn &&
+			    q->merge_bvec_fn(q, bio, prev) < len) {
+				prev->bv_len -= len;
+				return 0;
+			}
+
+			goto done;
+		}
+	}
+
+	if (bio->bi_vcnt >= bio->bi_max_vecs)
 		return 0;
 
 	/*
@@ -381,11 +403,31 @@
 	bio->bi_vcnt++;
 	bio->bi_phys_segments++;
 	bio->bi_hw_segments++;
+ done:
 	bio->bi_size += len;
 	return len;
 }
 
 /**
+ *	bio_add_pc_page	-	attempt to add page to bio
+ *	@bio: destination bio
+ *	@page: page to add
+ *	@len: vec entry length
+ *	@offset: vec entry offset
+ *
+ *	Attempt to add a page to the bio_vec maplist. This can fail for a
+ *	number of reasons, such as the bio being full or target block
+ *	device limitations. The target block device must allow bio's
+ *      smaller than PAGE_SIZE, so it is always possible to add a single
+ *      page to an empty bio. This should only be used by REQ_PC bios.
+ */
+int bio_add_pc_page(request_queue_t *q, struct bio *bio, struct page *page,
+		    unsigned int len, unsigned int offset)
+{
+	return __bio_add_page(q, bio, page, len, offset, q->max_hw_sectors);
+}
+
+/**
  *	bio_add_page	-	attempt to add page to bio
  *	@bio: destination bio
  *	@page: page to add
@@ -401,8 +443,8 @@
 int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
 		 unsigned int offset)
 {
-	return __bio_add_page(bdev_get_queue(bio->bi_bdev), bio, page,
-			      len, offset);
+	struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+	return __bio_add_page(q, bio, page, len, offset, q->max_sectors);
 }
 
 struct bio_map_data {
@@ -514,7 +556,7 @@
 			break;
 		}
 
-		if (__bio_add_page(q, bio, page, bytes, 0) < bytes) {
+		if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) {
 			ret = -EINVAL;
 			break;
 		}
@@ -628,7 +670,8 @@
 			/*
 			 * sorry...
 			 */
-			if (__bio_add_page(q, bio, pages[j], bytes, offset) < bytes)
+			if (bio_add_pc_page(q, bio, pages[j], bytes, offset) <
+					    bytes)
 				break;
 
 			len -= bytes;
@@ -801,8 +844,8 @@
 		if (bytes > len)
 			bytes = len;
 
-		if (__bio_add_page(q, bio, virt_to_page(data), bytes,
-				   offset) < bytes)
+		if (bio_add_pc_page(q, bio, virt_to_page(data), bytes,
+				    offset) < bytes)
 			break;
 
 		data += bytes;
@@ -1228,6 +1271,7 @@
 EXPORT_SYMBOL(bio_phys_segments);
 EXPORT_SYMBOL(bio_hw_segments);
 EXPORT_SYMBOL(bio_add_page);
+EXPORT_SYMBOL(bio_add_pc_page);
 EXPORT_SYMBOL(bio_get_nr_vecs);
 EXPORT_SYMBOL(bio_map_user);
 EXPORT_SYMBOL(bio_unmap_user);
diff --git a/fs/buffer.c b/fs/buffer.c
index 5287be1..55f0975a 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -153,14 +153,8 @@
 {
 	int ret = 0;
 
-	if (bdev) {
-		int err;
-
-		ret = filemap_fdatawrite(bdev->bd_inode->i_mapping);
-		err = filemap_fdatawait(bdev->bd_inode->i_mapping);
-		if (!ret)
-			ret = err;
-	}
+	if (bdev)
+		ret = filemap_write_and_wait(bdev->bd_inode->i_mapping);
 	return ret;
 }
 EXPORT_SYMBOL(sync_blockdev);
@@ -1768,7 +1762,7 @@
 	 * handle that here by just cleaning them.
 	 */
 
-	block = page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+	block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
 	head = page_buffers(page);
 	bh = head;
 
@@ -2160,11 +2154,12 @@
  * truncates.  Uses prepare/commit_write to allow the filesystem to
  * deal with the hole.  
  */
-int generic_cont_expand(struct inode *inode, loff_t size)
+static int __generic_cont_expand(struct inode *inode, loff_t size,
+				 pgoff_t index, unsigned int offset)
 {
 	struct address_space *mapping = inode->i_mapping;
 	struct page *page;
-	unsigned long index, offset, limit;
+	unsigned long limit;
 	int err;
 
 	err = -EFBIG;
@@ -2176,24 +2171,24 @@
 	if (size > inode->i_sb->s_maxbytes)
 		goto out;
 
-	offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */
-
-	/* ugh.  in prepare/commit_write, if from==to==start of block, we 
-	** skip the prepare.  make sure we never send an offset for the start
-	** of a block
-	*/
-	if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
-		offset++;
-	}
-	index = size >> PAGE_CACHE_SHIFT;
 	err = -ENOMEM;
 	page = grab_cache_page(mapping, index);
 	if (!page)
 		goto out;
 	err = mapping->a_ops->prepare_write(NULL, page, offset, offset);
-	if (!err) {
-		err = mapping->a_ops->commit_write(NULL, page, offset, offset);
+	if (err) {
+		/*
+		 * ->prepare_write() may have instantiated a few blocks
+		 * outside i_size.  Trim these off again.
+		 */
+		unlock_page(page);
+		page_cache_release(page);
+		vmtruncate(inode, inode->i_size);
+		goto out;
 	}
+
+	err = mapping->a_ops->commit_write(NULL, page, offset, offset);
+
 	unlock_page(page);
 	page_cache_release(page);
 	if (err > 0)
@@ -2202,6 +2197,36 @@
 	return err;
 }
 
+int generic_cont_expand(struct inode *inode, loff_t size)
+{
+	pgoff_t index;
+	unsigned int offset;
+
+	offset = (size & (PAGE_CACHE_SIZE - 1)); /* Within page */
+
+	/* ugh.  in prepare/commit_write, if from==to==start of block, we
+	** skip the prepare.  make sure we never send an offset for the start
+	** of a block
+	*/
+	if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
+		/* caller must handle this extra byte. */
+		offset++;
+	}
+	index = size >> PAGE_CACHE_SHIFT;
+
+	return __generic_cont_expand(inode, size, index, offset);
+}
+
+int generic_cont_expand_simple(struct inode *inode, loff_t size)
+{
+	loff_t pos = size - 1;
+	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+	unsigned int offset = (pos & (PAGE_CACHE_SIZE - 1)) + 1;
+
+	/* prepare/commit_write can handle even if from==to==start of block. */
+	return __generic_cont_expand(inode, size, index, offset);
+}
+
 /*
  * For moronic filesystems that do not allow holes in file.
  * We may have to extend the file.
@@ -2610,7 +2635,7 @@
 	pgoff_t index = from >> PAGE_CACHE_SHIFT;
 	unsigned offset = from & (PAGE_CACHE_SIZE-1);
 	unsigned blocksize;
-	pgoff_t iblock;
+	sector_t iblock;
 	unsigned length, pos;
 	struct inode *inode = mapping->host;
 	struct page *page;
@@ -2626,7 +2651,7 @@
 		return 0;
 
 	length = blocksize - length;
-	iblock = index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+	iblock = (sector_t)index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
 	
 	page = grab_cache_page(mapping, index);
 	err = -ENOMEM;
@@ -3145,6 +3170,7 @@
 EXPORT_SYMBOL(generic_block_bmap);
 EXPORT_SYMBOL(generic_commit_write);
 EXPORT_SYMBOL(generic_cont_expand);
+EXPORT_SYMBOL(generic_cont_expand_simple);
 EXPORT_SYMBOL(init_buffer);
 EXPORT_SYMBOL(invalidate_bdev);
 EXPORT_SYMBOL(ll_rw_block);
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 6bded10..943ef9b 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,10 +1,12 @@
 Version 1.39
 ------------
-Defer close of a file handle slightly if pending writes depend on that file handle
+Defer close of a file handle slightly if pending writes depend on that handle
 (this reduces the EBADF bad file handle errors that can be logged under heavy
 stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 
-Fix SFU style symlinks and mknod needed for servers which do not support the CIFS
-Unix Extensions.  Fix setfacl/getfacl on bigendian. 
+Fix SFU style symlinks and mknod needed for servers which do not support the
+CIFS Unix Extensions.  Fix setfacl/getfacl on bigendian. Timeout negative
+dentries so files that the client sees as deleted but that later get created
+on the server will be recognized.  Add client side permission check on setattr.
 
 Version 1.38
 ------------
diff --git a/fs/cifs/README b/fs/cifs/README
index bb90941..e5d09a2 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -278,7 +278,9 @@
 		(such as Windows), permissions can also be checked at the
 		client, and a crude form of client side permission checking 
 		can be enabled by specifying file_mode and dir_mode on 
-		the client
+		the client.  Note that the mount.cifs helper must be
+		at version 1.10 or higher to support specifying the uid
+		(or gid) in non-numberic form.
   gid		If CIFS Unix extensions are not supported by the server
 		this overrides the default gid for inodes.
   file_mode     If CIFS Unix extensions are not supported by the server
@@ -345,7 +347,10 @@
 		client system. It is typically only needed when the server
 		supports the CIFS Unix Extensions but the UIDs/GIDs on the
 		client and server system do not match closely enough to allow
-		access by the user doing the mount.
+		access by the user doing the mount, but it may be useful with
+		non CIFS Unix Extension mounts for cases in which the default
+		mode is specified on the mount but is not to be enforced on the
+		client (e.g. perhaps when MultiUserMount is enabled)
 		Note that this does not affect the normal ACL check on the
 		target machine done by the server software (of the server
 		ACL against the user name provided at mount time).
@@ -368,15 +373,21 @@
   setuids       If the CIFS Unix extensions are negotiated with the server
 		the client will attempt to set the effective uid and gid of
 		the local process on newly created files, directories, and
-		devices (create, mkdir, mknod).
+		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
+		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).
   nosetuids     The client will not attempt to set the uid and gid on
 		on newly created files, directories, and devices (create, 
 		mkdir, mknod) which will result in the server setting the
 		uid and gid to the default (usually the server uid of the
 		user who mounted the share).  Letting the server (rather than
-		the client) set the uid and gid is the default. This
-		parameter has no effect if the CIFS Unix Extensions are not
-		negotiated.
+		the client) set the uid and gid is the default. If the CIFS
+		Unix Extensions are not negotiated then the uid and gid for
+		new files will appear to be the uid (gid) of the mounter or the
+		uid (gid) parameter specified on the mount.
   netbiosname   When mounting to servers via port 139, specifies the RFC1001
 		source name to use to represent the client netbios machine 
 		name when doing the RFC1001 netbios session initialize.
@@ -418,6 +429,13 @@
 		byte range locks).
  remount        remount the share (often used to change from ro to rw mounts
 	        or vice versa)
+ sfu            When the CIFS Unix Extensions are not negotiated, attempt to
+		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
+		mode also will be emulated using queries of the security
+		descriptor (ACL).
 		
 The mount.cifs mount helper also accepts a few mount options before -o
 including:
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index c909298..fc34c74 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -1,4 +1,4 @@
-version 1.37 October 9, 2005
+Version 1.39 November 30, 2005
 
 A Partial List of Missing Features
 ==================================
@@ -58,7 +58,7 @@
 at a time when 8 pages or more are requested. In conjuntion
 add support for async_cifs_readpages.
 
-p) Add support for storing symlink and fifo info to Windows servers 
+p) Add support for storing symlink info to Windows servers 
 in the Extended Attribute format their SFU clients would recognize.
 
 q) Finish fcntl D_NOTIFY support so kde and gnome file list windows
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 51548ed..2a13a2b 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -32,6 +32,7 @@
 #include <linux/seq_file.h>
 #include <linux/vfs.h>
 #include <linux/mempool.h>
+#include <linux/delay.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
 #define DECLARE_GLOBALS_HERE
@@ -429,6 +430,11 @@
 	{
 		cFYI(1,("wake up tasks now - umount begin not complete"));
 		wake_up_all(&tcon->ses->server->request_q);
+		wake_up_all(&tcon->ses->server->response_q);
+		msleep(1); /* yield */
+		/* we have to kick the requests once more */
+		wake_up_all(&tcon->ses->server->response_q);
+		msleep(1);
 	}
 /* BB FIXME - finish add checks for tidStatus BB */
 
@@ -895,6 +901,9 @@
 
 static int cifs_dnotify_thread(void * dummyarg)
 {
+	struct list_head *tmp;
+	struct cifsSesInfo *ses;
+
 	daemonize("cifsdnotifyd");
 	allow_signal(SIGTERM);
 
@@ -903,7 +912,19 @@
 		if(try_to_freeze())
 			continue;
 		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(39*HZ);
+		schedule_timeout(15*HZ);
+		read_lock(&GlobalSMBSeslock);
+		/* check if any stuck requests that need
+		   to be woken up and wakeq so the
+		   thread can wake up and error out */
+		list_for_each(tmp, &GlobalSMBSessionList) {
+			ses = list_entry(tmp, struct cifsSesInfo, 
+				cifsSessionList);
+			if(ses && ses->server && 
+			     atomic_read(&ses->server->inFlight))
+				wake_up_all(&ses->server->response_q);
+		}
+		read_unlock(&GlobalSMBSeslock);
 	} while(!signal_pending(current));
 	complete_and_exit (&cifs_dnotify_exited, 0);
 }
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index d179b0c..6867e55 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -90,6 +90,18 @@
 	   check for tcp and smb session status done differently
 	   for those three - in the calling routine */
 	if(tcon) {
+		if(tcon->tidStatus == CifsExiting) {
+			/* only tree disconnect, open, and write,
+			(and ulogoff which does not have tcon)
+			are allowed as we start force umount */
+			if((smb_command != SMB_COM_WRITE_ANDX) && 
+			   (smb_command != SMB_COM_OPEN_ANDX) && 
+			   (smb_command != SMB_COM_TREE_DISCONNECT)) {
+				cFYI(1,("can not send cmd %d while umounting",
+					smb_command));
+				return -ENODEV;
+			}
+		}
 		if((tcon->ses) && (tcon->ses->status != CifsExiting) &&
 				  (tcon->ses->server)){
 			struct nls_table *nls_codepage;
@@ -187,6 +199,19 @@
 	   check for tcp and smb session status done differently
 	   for those three - in the calling routine */
 	if(tcon) {
+		if(tcon->tidStatus == CifsExiting) {
+			/* only tree disconnect, open, and write,
+			  (and ulogoff which does not have tcon)
+			  are allowed as we start force umount */
+			if((smb_command != SMB_COM_WRITE_ANDX) &&
+			   (smb_command != SMB_COM_OPEN_ANDX) &&
+			   (smb_command != SMB_COM_TREE_DISCONNECT)) {
+				cFYI(1,("can not send cmd %d while umounting",
+					smb_command));
+				return -ENODEV;
+			}
+		}
+
 		if((tcon->ses) && (tcon->ses->status != CifsExiting) && 
 				  (tcon->ses->server)){
 			struct nls_table *nls_codepage;
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 16b2152..32cc96c 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -228,8 +228,15 @@
 		else {
 			rc = cifs_get_inode_info(&newinode, full_path,
 						 buf, inode->i_sb,xid);
-			if(newinode)
+			if(newinode) {
 				newinode->i_mode = mode;
+				if((oplock & CIFS_CREATE_ACTION) &&
+				  (cifs_sb->mnt_cifs_flags & 
+				     CIFS_MOUNT_SET_UID)) {
+					newinode->i_uid = current->fsuid;
+					newinode->i_gid = current->fsgid;
+				}
+			}
 		}
 
 		if (rc != 0) {
@@ -465,12 +472,20 @@
 			direntry->d_op = &cifs_dentry_ops;
 		d_add(direntry, newInode);
 
-		/* since paths are not looked up by component - the parent directories are presumed to be good here */
+		/* since paths are not looked up by component - the parent 
+		   directories are presumed to be good here */
 		renew_parental_timestamps(direntry);
 
 	} else if (rc == -ENOENT) {
 		rc = 0;
+		direntry->d_time = jiffies;
+		if (pTcon->nocase)
+			direntry->d_op = &cifs_ci_dentry_ops;
+		else
+			direntry->d_op = &cifs_dentry_ops;
 		d_add(direntry, NULL);
+	/*	if it was once a directory (but how can we tell?) we could do  
+			shrink_dcache_parent(direntry); */
 	} else {
 		cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s",
 			   rc,full_path));
@@ -489,21 +504,20 @@
 {
 	int isValid = 1;
 
-/*	lock_kernel(); *//* surely we do not want to lock the kernel for a whole network round trip which could take seconds */
-
 	if (direntry->d_inode) {
 		if (cifs_revalidate(direntry)) {
-			/* unlock_kernel(); */
 			return 0;
 		}
 	} else {
-		cFYI(1,
-		     ("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p",
-		      direntry->d_name.name, direntry));
+		cFYI(1, ("neg dentry 0x%p name = %s",
+			 direntry, direntry->d_name.name));
+		if(time_after(jiffies, direntry->d_time + HZ) || 
+			!lookupCacheEnabled) {
+			d_drop(direntry);
+			isValid = 0;
+		} 
 	}
 
-/*    unlock_kernel(); */
-
 	return isValid;
 }
 
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 14a1c72..5ade53d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -127,8 +127,7 @@
 		if (file->f_dentry->d_inode->i_mapping) {
 		/* BB no need to lock inode until after invalidate
 		   since namei code should already have it locked? */
-			filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
-			filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
+			filemap_write_and_wait(file->f_dentry->d_inode->i_mapping);
 		}
 		cFYI(1, ("invalidating remote inode since open detected it "
 			 "changed"));
@@ -419,8 +418,7 @@
 		pCifsInode = CIFS_I(inode);
 		if (pCifsInode) {
 			if (can_flush) {
-				filemap_fdatawrite(inode->i_mapping);
-				filemap_fdatawait(inode->i_mapping);
+				filemap_write_and_wait(inode->i_mapping);
 			/* temporarily disable caching while we
 			   go to server to get inode info */
 				pCifsInode->clientCanCacheAll = FALSE;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 05b5258..9558f51 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -710,7 +710,7 @@
 	char *full_path = NULL;
 	struct inode *newinode = NULL;
 
-	cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p ", mode, inode));
+	cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
 
 	xid = GetXid();
 
@@ -768,6 +768,17 @@
 			/* BB to be implemented via Windows secrty descriptors
 			   eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
 						 -1, -1, local_nls); */
+			if(direntry->d_inode) {
+				direntry->d_inode->i_mode = mode;
+				direntry->d_inode->i_mode |= S_IFDIR;
+				if(cifs_sb->mnt_cifs_flags & 
+				     CIFS_MOUNT_SET_UID) {
+					direntry->d_inode->i_uid = 
+						current->fsuid;
+					direntry->d_inode->i_gid = 
+						current->fsgid;
+				}
+			}
 		}
 	}
 	kfree(full_path);
@@ -1039,14 +1050,20 @@
 		filemap_fdatawrite(direntry->d_inode->i_mapping);
 	}
 	if (invalidate_inode) {
-		if (direntry->d_inode->i_mapping)
-			filemap_fdatawait(direntry->d_inode->i_mapping);
-		/* may eventually have to do this for open files too */
-		if (list_empty(&(cifsInode->openFileList))) {
-			/* Has changed on server - flush read ahead pages */
-			cFYI(1, ("Invalidating read ahead data on "
-				 "closed file"));
-			invalidate_remote_inode(direntry->d_inode);
+	/* shrink_dcache not necessary now that cifs dentry ops
+	are exported for negative dentries */
+/*		if(S_ISDIR(direntry->d_inode->i_mode)) 
+			shrink_dcache_parent(direntry); */
+		if (S_ISREG(direntry->d_inode->i_mode)) {
+			if (direntry->d_inode->i_mapping)
+				filemap_fdatawait(direntry->d_inode->i_mapping);
+			/* may eventually have to do this for open files too */
+			if (list_empty(&(cifsInode->openFileList))) {
+				/* changed on server - flush read ahead pages */
+				cFYI(1, ("Invalidating read ahead data on "
+					 "closed file"));
+				invalidate_remote_inode(direntry->d_inode);
+			}
 		}
 	}
 /*	up(&direntry->d_inode->i_sem); */
@@ -1105,9 +1122,20 @@
 
 	cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
 		 direntry->d_name.name, attrs->ia_valid));
+
 	cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
 	pTcon = cifs_sb->tcon;
 
+	if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
+		/* check if we have permission to change attrs */
+		rc = inode_change_ok(direntry->d_inode, attrs);
+		if(rc < 0) {
+			FreeXid(xid);
+			return rc;
+		} else
+			rc = 0;
+	}
+		
 	down(&direntry->d_sb->s_vfs_rename_sem);
 	full_path = build_path_from_dentry(direntry);
 	up(&direntry->d_sb->s_vfs_rename_sem);
@@ -1120,8 +1148,7 @@
 	/* BB check if we need to refresh inode from server now ? BB */
 
 	/* need to flush data before changing file size on server */
-	filemap_fdatawrite(direntry->d_inode->i_mapping);
-	filemap_fdatawait(direntry->d_inode->i_mapping);
+	filemap_write_and_wait(direntry->d_inode->i_mapping);
 
 	if (attrs->ia_valid & ATTR_SIZE) {
 		/* To avoid spurious oplock breaks from server, in the case of
@@ -1147,7 +1174,9 @@
 						  1 /* 45 seconds */);
 				cFYI(1,("Wrt seteof rc %d", rc));
 			}
-		}
+		} else 
+			rc = -EINVAL;
+
 		if (rc != 0) {
 			/* Set file size by pathname rather than by handle
 			   either because no valid, writeable file handle for
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index ca27a82..94baf6c 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -397,12 +397,12 @@
 			if(smb->Command == SMB_COM_LOCKING_ANDX)
 				return 0;
 			else
-				cERROR(1, ("Rcvd Request not response "));         
+				cERROR(1, ("Rcvd Request not response"));         
 		}
 	} else { /* bad signature or mid */
 		if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
 			cERROR(1,
-			       ("Bad protocol string signature header %x ",
+			       ("Bad protocol string signature header %x",
 				*(unsigned int *) smb->Protocol));
 		if (mid != smb->Mid)
 			cERROR(1, ("Mids do not match"));
@@ -417,7 +417,7 @@
 	__u32 len = smb->smb_buf_length;
 	__u32 clc_len;  /* calculated length */
 	cFYI(0,
-	     ("Entering checkSMB with Length: %x, smb_buf_length: %x ",
+	     ("Entering checkSMB with Length: %x, smb_buf_length: %x",
 	      length, len));
 	if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
 	    (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
@@ -451,9 +451,16 @@
 		cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid));
 		/* Windows XP can return a few bytes too much, presumably
 		an illegal pad, at the end of byte range lock responses 
-		so we allow for up to eight byte pad, as long as actual
+		so we allow for that three byte pad, as long as actual
 		received length is as long or longer than calculated length */
-		if((4+len > clc_len) && (len <= clc_len + 3))
+		/* We have now had to extend this more, since there is a 
+		case in which it needs to be bigger still to handle a
+		malformed response to transact2 findfirst from WinXP when
+		access denied is returned and thus bcc and wct are zero
+		but server says length is 0x21 bytes too long as if the server
+		forget to reset the smb rfc1001 length when it reset the
+		wct and bcc to minimum size and drop the t2 parms and data */
+		if((4+len > clc_len) && (len <= clc_len + 512))
 			return 0;
 		else
 			return 1;
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index f781468..5de74d2 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -330,7 +330,7 @@
 	ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {
 	ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, {
 	ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, {
-	ERRSRV, 2242, NT_STATUS_PASSWORD_EXPIRED}, {
+	ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, {
 	ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, {
 	ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, {
 	ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {
@@ -676,7 +676,7 @@
 	ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, {
 	ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, {
 	ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, {
-	ERRSRV, 2242, NT_STATUS_PASSWORD_MUST_CHANGE}, {
+	ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_MUST_CHANGE}, {
 	ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, {
 	ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, {
 	ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, {
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 41a9659..f887119 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -515,6 +515,7 @@
 			*pbytes_returned = in_buf->smb_buf_length;
 
 			/* BB special case reconnect tid and uid here? */
+			/* BB special case Errbadpassword and pwdexpired here */
 			rc = map_smb_to_linux_error(in_buf);
 
 			/* convert ByteCount if necessary */
diff --git a/fs/coda/cache.c b/fs/coda/cache.c
index 80072fd..c607d92 100644
--- a/fs/coda/cache.c
+++ b/fs/coda/cache.c
@@ -93,7 +93,7 @@
 	spin_lock(&dcache_lock);
 	list_for_each(child, &parent->d_subdirs)
 	{
-		de = list_entry(child, struct dentry, d_child);
+		de = list_entry(child, struct dentry, d_u.d_child);
 		/* don't know what to do with negative dentries */
 		if ( ! de->d_inode ) 
 			continue;
diff --git a/fs/compat.c b/fs/compat.c
index 8186341..271b75d 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -494,9 +494,21 @@
 		ret = sys_fcntl(fd, cmd, (unsigned long)&f);
 		set_fs(old_fs);
 		if (cmd == F_GETLK && ret == 0) {
-			if ((f.l_start >= COMPAT_OFF_T_MAX) ||
-			    ((f.l_start + f.l_len) > COMPAT_OFF_T_MAX))
+			/* GETLK was successfule and we need to return the data...
+			 * but it needs to fit in the compat structure.
+			 * l_start shouldn't be too big, unless the original
+			 * start + end is greater than COMPAT_OFF_T_MAX, in which
+			 * case the app was asking for trouble, so we return
+			 * -EOVERFLOW in that case.
+			 * l_len could be too big, in which case we just truncate it,
+			 * and only allow the app to see that part of the conflicting
+			 * lock that might make sense to it anyway
+			 */
+
+			if (f.l_start > COMPAT_OFF_T_MAX)
 				ret = -EOVERFLOW;
+			if (f.l_len > COMPAT_OFF_T_MAX)
+				f.l_len = COMPAT_OFF_T_MAX;
 			if (ret == 0)
 				ret = put_compat_flock(&f, compat_ptr(arg));
 		}
@@ -515,9 +527,11 @@
 				(unsigned long)&f);
 		set_fs(old_fs);
 		if (cmd == F_GETLK64 && ret == 0) {
-			if ((f.l_start >= COMPAT_LOFF_T_MAX) ||
-			    ((f.l_start + f.l_len) > COMPAT_LOFF_T_MAX))
+			/* need to return lock information - see above for commentary */
+			if (f.l_start > COMPAT_LOFF_T_MAX)
 				ret = -EOVERFLOW;
+			if (f.l_len > COMPAT_LOFF_T_MAX)
+				f.l_len = COMPAT_LOFF_T_MAX;
 			if (ret == 0)
 				ret = put_compat_flock64(&f, compat_ptr(arg));
 		}
@@ -1170,7 +1184,7 @@
 	}
 
 	ret = rw_verify_area(type, file, pos, tot_len);
-	if (ret)
+	if (ret < 0)
 		goto out;
 
 	fnv = NULL;
diff --git a/fs/configfs/Makefile b/fs/configfs/Makefile
new file mode 100644
index 0000000..00ffb27
--- /dev/null
+++ b/fs/configfs/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the configfs virtual filesystem
+#
+
+obj-$(CONFIG_CONFIGFS_FS)	+= configfs.o
+
+configfs-objs	:= inode.o file.o dir.o symlink.o mount.o item.o
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h
new file mode 100644
index 0000000..8899d9c
--- /dev/null
+++ b/fs/configfs/configfs_internal.h
@@ -0,0 +1,142 @@
+/* -*- mode: c; c-basic-offset:8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * configfs_internal.h - Internal stuff for configfs
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ */
+
+#include <linux/slab.h>
+#include <linux/list.h>
+
+struct configfs_dirent {
+	atomic_t		s_count;
+	struct list_head	s_sibling;
+	struct list_head	s_children;
+	struct list_head	s_links;
+	void 			* s_element;
+	int			s_type;
+	umode_t			s_mode;
+	struct dentry		* s_dentry;
+};
+
+#define CONFIGFS_ROOT		0x0001
+#define CONFIGFS_DIR		0x0002
+#define CONFIGFS_ITEM_ATTR 	0x0004
+#define CONFIGFS_ITEM_LINK 	0x0020
+#define CONFIGFS_USET_DIR	0x0040
+#define CONFIGFS_USET_DEFAULT	0x0080
+#define CONFIGFS_USET_DROPPING	0x0100
+#define CONFIGFS_NOT_PINNED	(CONFIGFS_ITEM_ATTR)
+
+extern struct vfsmount * configfs_mount;
+
+extern int configfs_is_root(struct config_item *item);
+
+extern struct inode * configfs_new_inode(mode_t mode);
+extern int configfs_create(struct dentry *, int mode, int (*init)(struct inode *));
+
+extern int configfs_create_file(struct config_item *, const struct configfs_attribute *);
+extern int configfs_make_dirent(struct configfs_dirent *,
+				struct dentry *, void *, umode_t, int);
+
+extern int configfs_add_file(struct dentry *, const struct configfs_attribute *, int);
+extern void configfs_hash_and_remove(struct dentry * dir, const char * name);
+
+extern const unsigned char * configfs_get_name(struct configfs_dirent *sd);
+extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent);
+
+extern int configfs_pin_fs(void);
+extern void configfs_release_fs(void);
+
+extern struct rw_semaphore configfs_rename_sem;
+extern struct super_block * configfs_sb;
+extern struct file_operations configfs_dir_operations;
+extern struct file_operations configfs_file_operations;
+extern struct file_operations bin_fops;
+extern struct inode_operations configfs_dir_inode_operations;
+extern struct inode_operations configfs_symlink_inode_operations;
+
+extern int configfs_symlink(struct inode *dir, struct dentry *dentry,
+			    const char *symname);
+extern int configfs_unlink(struct inode *dir, struct dentry *dentry);
+
+struct configfs_symlink {
+	struct list_head sl_list;
+	struct config_item *sl_target;
+};
+
+extern int configfs_create_link(struct configfs_symlink *sl,
+				struct dentry *parent,
+				struct dentry *dentry);
+
+static inline struct config_item * to_item(struct dentry * dentry)
+{
+	struct configfs_dirent * sd = dentry->d_fsdata;
+	return ((struct config_item *) sd->s_element);
+}
+
+static inline struct configfs_attribute * to_attr(struct dentry * dentry)
+{
+	struct configfs_dirent * sd = dentry->d_fsdata;
+	return ((struct configfs_attribute *) sd->s_element);
+}
+
+static inline struct config_item *configfs_get_config_item(struct dentry *dentry)
+{
+	struct config_item * item = NULL;
+
+	spin_lock(&dcache_lock);
+	if (!d_unhashed(dentry)) {
+		struct configfs_dirent * sd = dentry->d_fsdata;
+		if (sd->s_type & CONFIGFS_ITEM_LINK) {
+			struct configfs_symlink * sl = sd->s_element;
+			item = config_item_get(sl->sl_target);
+		} else
+			item = config_item_get(sd->s_element);
+	}
+	spin_unlock(&dcache_lock);
+
+	return item;
+}
+
+static inline void release_configfs_dirent(struct configfs_dirent * sd)
+{
+	if (!(sd->s_type & CONFIGFS_ROOT))
+		kfree(sd);
+}
+
+static inline struct configfs_dirent * configfs_get(struct configfs_dirent * sd)
+{
+	if (sd) {
+		WARN_ON(!atomic_read(&sd->s_count));
+		atomic_inc(&sd->s_count);
+	}
+	return sd;
+}
+
+static inline void configfs_put(struct configfs_dirent * sd)
+{
+	WARN_ON(!atomic_read(&sd->s_count));
+	if (atomic_dec_and_test(&sd->s_count))
+		release_configfs_dirent(sd);
+}
+
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
new file mode 100644
index 0000000..e48b539
--- /dev/null
+++ b/fs/configfs/dir.c
@@ -0,0 +1,1102 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dir.c - Operations for configfs directories.
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ */
+
+#undef DEBUG
+
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <linux/configfs.h>
+#include "configfs_internal.h"
+
+DECLARE_RWSEM(configfs_rename_sem);
+
+static void configfs_d_iput(struct dentry * dentry,
+			    struct inode * inode)
+{
+	struct configfs_dirent * sd = dentry->d_fsdata;
+
+	if (sd) {
+		BUG_ON(sd->s_dentry != dentry);
+		sd->s_dentry = NULL;
+		configfs_put(sd);
+	}
+	iput(inode);
+}
+
+/*
+ * We _must_ delete our dentries on last dput, as the chain-to-parent
+ * behavior is required to clear the parents of default_groups.
+ */
+static int configfs_d_delete(struct dentry *dentry)
+{
+	return 1;
+}
+
+static struct dentry_operations configfs_dentry_ops = {
+	.d_iput		= configfs_d_iput,
+	/* simple_delete_dentry() isn't exported */
+	.d_delete	= configfs_d_delete,
+};
+
+/*
+ * Allocates a new configfs_dirent and links it to the parent configfs_dirent
+ */
+static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * parent_sd,
+						void * element)
+{
+	struct configfs_dirent * sd;
+
+	sd = kmalloc(sizeof(*sd), GFP_KERNEL);
+	if (!sd)
+		return NULL;
+
+	memset(sd, 0, sizeof(*sd));
+	atomic_set(&sd->s_count, 1);
+	INIT_LIST_HEAD(&sd->s_links);
+	INIT_LIST_HEAD(&sd->s_children);
+	list_add(&sd->s_sibling, &parent_sd->s_children);
+	sd->s_element = element;
+
+	return sd;
+}
+
+int configfs_make_dirent(struct configfs_dirent * parent_sd,
+			 struct dentry * dentry, void * element,
+			 umode_t mode, int type)
+{
+	struct configfs_dirent * sd;
+
+	sd = configfs_new_dirent(parent_sd, element);
+	if (!sd)
+		return -ENOMEM;
+
+	sd->s_mode = mode;
+	sd->s_type = type;
+	sd->s_dentry = dentry;
+	if (dentry) {
+		dentry->d_fsdata = configfs_get(sd);
+		dentry->d_op = &configfs_dentry_ops;
+	}
+
+	return 0;
+}
+
+static int init_dir(struct inode * inode)
+{
+	inode->i_op = &configfs_dir_inode_operations;
+	inode->i_fop = &configfs_dir_operations;
+
+	/* directory inodes start off with i_nlink == 2 (for "." entry) */
+	inode->i_nlink++;
+	return 0;
+}
+
+static int init_file(struct inode * inode)
+{
+	inode->i_size = PAGE_SIZE;
+	inode->i_fop = &configfs_file_operations;
+	return 0;
+}
+
+static int init_symlink(struct inode * inode)
+{
+	inode->i_op = &configfs_symlink_inode_operations;
+	return 0;
+}
+
+static int create_dir(struct config_item * k, struct dentry * p,
+		      struct dentry * d)
+{
+	int error;
+	umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
+
+	error = configfs_create(d, mode, init_dir);
+	if (!error) {
+		error = configfs_make_dirent(p->d_fsdata, d, k, mode,
+					   CONFIGFS_DIR);
+		if (!error) {
+			p->d_inode->i_nlink++;
+			(d)->d_op = &configfs_dentry_ops;
+		}
+	}
+	return error;
+}
+
+
+/**
+ *	configfs_create_dir - create a directory for an config_item.
+ *	@item:		config_itemwe're creating directory for.
+ *	@dentry:	config_item's dentry.
+ */
+
+static int configfs_create_dir(struct config_item * item, struct dentry *dentry)
+{
+	struct dentry * parent;
+	int error = 0;
+
+	BUG_ON(!item);
+
+	if (item->ci_parent)
+		parent = item->ci_parent->ci_dentry;
+	else if (configfs_mount && configfs_mount->mnt_sb)
+		parent = configfs_mount->mnt_sb->s_root;
+	else
+		return -EFAULT;
+
+	error = create_dir(item,parent,dentry);
+	if (!error)
+		item->ci_dentry = dentry;
+	return error;
+}
+
+int configfs_create_link(struct configfs_symlink *sl,
+			 struct dentry *parent,
+			 struct dentry *dentry)
+{
+	int err = 0;
+	umode_t mode = S_IFLNK | S_IRWXUGO;
+
+	err = configfs_create(dentry, mode, init_symlink);
+	if (!err) {
+		err = configfs_make_dirent(parent->d_fsdata, dentry, sl,
+					 mode, CONFIGFS_ITEM_LINK);
+		if (!err)
+			dentry->d_op = &configfs_dentry_ops;
+	}
+	return err;
+}
+
+static void remove_dir(struct dentry * d)
+{
+	struct dentry * parent = dget(d->d_parent);
+	struct configfs_dirent * sd;
+
+	sd = d->d_fsdata;
+ 	list_del_init(&sd->s_sibling);
+	configfs_put(sd);
+	if (d->d_inode)
+		simple_rmdir(parent->d_inode,d);
+
+	pr_debug(" o %s removing done (%d)\n",d->d_name.name,
+		 atomic_read(&d->d_count));
+
+	dput(parent);
+}
+
+/**
+ * configfs_remove_dir - remove an config_item's directory.
+ * @item:	config_item we're removing.
+ *
+ * The only thing special about this is that we remove any files in
+ * the directory before we remove the directory, and we've inlined
+ * what used to be configfs_rmdir() below, instead of calling separately.
+ */
+
+static void configfs_remove_dir(struct config_item * item)
+{
+	struct dentry * dentry = dget(item->ci_dentry);
+
+	if (!dentry)
+		return;
+
+	remove_dir(dentry);
+	/**
+	 * Drop reference from dget() on entrance.
+	 */
+	dput(dentry);
+}
+
+
+/* attaches attribute's configfs_dirent to the dentry corresponding to the
+ * attribute file
+ */
+static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * dentry)
+{
+	struct configfs_attribute * attr = sd->s_element;
+	int error;
+
+	error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, init_file);
+	if (error)
+		return error;
+
+	dentry->d_op = &configfs_dentry_ops;
+	dentry->d_fsdata = configfs_get(sd);
+	sd->s_dentry = dentry;
+	d_rehash(dentry);
+
+	return 0;
+}
+
+static struct dentry * configfs_lookup(struct inode *dir,
+				       struct dentry *dentry,
+				       struct nameidata *nd)
+{
+	struct configfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
+	struct configfs_dirent * sd;
+	int found = 0;
+	int err = 0;
+
+	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+		if (sd->s_type & CONFIGFS_NOT_PINNED) {
+			const unsigned char * name = configfs_get_name(sd);
+
+			if (strcmp(name, dentry->d_name.name))
+				continue;
+
+			found = 1;
+			err = configfs_attach_attr(sd, dentry);
+			break;
+		}
+	}
+
+	if (!found) {
+		/*
+		 * If it doesn't exist and it isn't a NOT_PINNED item,
+		 * it must be negative.
+		 */
+		return simple_lookup(dir, dentry, nd);
+	}
+
+	return ERR_PTR(err);
+}
+
+/*
+ * Only subdirectories count here.  Files (CONFIGFS_NOT_PINNED) are
+ * attributes and are removed by rmdir().  We recurse, taking i_sem
+ * on all children that are candidates for default detach.  If the
+ * result is clean, then configfs_detach_group() will handle dropping
+ * i_sem.  If there is an error, the caller will clean up the i_sem
+ * holders via configfs_detach_rollback().
+ */
+static int configfs_detach_prep(struct dentry *dentry)
+{
+	struct configfs_dirent *parent_sd = dentry->d_fsdata;
+	struct configfs_dirent *sd;
+	int ret;
+
+	ret = -EBUSY;
+	if (!list_empty(&parent_sd->s_links))
+		goto out;
+
+	ret = 0;
+	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+		if (sd->s_type & CONFIGFS_NOT_PINNED)
+			continue;
+		if (sd->s_type & CONFIGFS_USET_DEFAULT) {
+			down(&sd->s_dentry->d_inode->i_sem);
+			/* Mark that we've taken i_sem */
+			sd->s_type |= CONFIGFS_USET_DROPPING;
+
+			ret = configfs_detach_prep(sd->s_dentry);
+			if (!ret)
+			       	continue;
+		} else
+			ret = -ENOTEMPTY;
+
+		break;
+	}
+
+out:
+	return ret;
+}
+
+/*
+ * Walk the tree, dropping i_sem wherever CONFIGFS_USET_DROPPING is
+ * set.
+ */
+static void configfs_detach_rollback(struct dentry *dentry)
+{
+	struct configfs_dirent *parent_sd = dentry->d_fsdata;
+	struct configfs_dirent *sd;
+
+	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+		if (sd->s_type & CONFIGFS_USET_DEFAULT) {
+			configfs_detach_rollback(sd->s_dentry);
+
+			if (sd->s_type & CONFIGFS_USET_DROPPING) {
+				sd->s_type &= ~CONFIGFS_USET_DROPPING;
+				up(&sd->s_dentry->d_inode->i_sem);
+			}
+		}
+	}
+}
+
+static void detach_attrs(struct config_item * item)
+{
+	struct dentry * dentry = dget(item->ci_dentry);
+	struct configfs_dirent * parent_sd;
+	struct configfs_dirent * sd, * tmp;
+
+	if (!dentry)
+		return;
+
+	pr_debug("configfs %s: dropping attrs for  dir\n",
+		 dentry->d_name.name);
+
+	parent_sd = dentry->d_fsdata;
+	list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
+		if (!sd->s_element || !(sd->s_type & CONFIGFS_NOT_PINNED))
+			continue;
+		list_del_init(&sd->s_sibling);
+		configfs_drop_dentry(sd, dentry);
+		configfs_put(sd);
+	}
+
+	/**
+	 * Drop reference from dget() on entrance.
+	 */
+	dput(dentry);
+}
+
+static int populate_attrs(struct config_item *item)
+{
+	struct config_item_type *t = item->ci_type;
+	struct configfs_attribute *attr;
+	int error = 0;
+	int i;
+
+	if (!t)
+		return -EINVAL;
+	if (t->ct_attrs) {
+		for (i = 0; (attr = t->ct_attrs[i]) != NULL; i++) {
+			if ((error = configfs_create_file(item, attr)))
+				break;
+		}
+	}
+
+	if (error)
+		detach_attrs(item);
+
+	return error;
+}
+
+static int configfs_attach_group(struct config_item *parent_item,
+				 struct config_item *item,
+				 struct dentry *dentry);
+static void configfs_detach_group(struct config_item *item);
+
+static void detach_groups(struct config_group *group)
+{
+	struct dentry * dentry = dget(group->cg_item.ci_dentry);
+	struct dentry *child;
+	struct configfs_dirent *parent_sd;
+	struct configfs_dirent *sd, *tmp;
+
+	if (!dentry)
+		return;
+
+	parent_sd = dentry->d_fsdata;
+	list_for_each_entry_safe(sd, tmp, &parent_sd->s_children, s_sibling) {
+		if (!sd->s_element ||
+		    !(sd->s_type & CONFIGFS_USET_DEFAULT))
+			continue;
+
+		child = sd->s_dentry;
+
+		configfs_detach_group(sd->s_element);
+		child->d_inode->i_flags |= S_DEAD;
+
+		/*
+		 * From rmdir/unregister, a configfs_detach_prep() pass
+		 * has taken our i_sem for us.  Drop it.
+		 * From mkdir/register cleanup, there is no sem held.
+		 */
+		if (sd->s_type & CONFIGFS_USET_DROPPING)
+			up(&child->d_inode->i_sem);
+
+		d_delete(child);
+		dput(child);
+	}
+
+	/**
+	 * Drop reference from dget() on entrance.
+	 */
+	dput(dentry);
+}
+
+/*
+ * This fakes mkdir(2) on a default_groups[] entry.  It
+ * creates a dentry, attachs it, and then does fixup
+ * on the sd->s_type.
+ *
+ * We could, perhaps, tweak our parent's ->mkdir for a minute and
+ * try using vfs_mkdir.  Just a thought.
+ */
+static int create_default_group(struct config_group *parent_group,
+				struct config_group *group)
+{
+	int ret;
+	struct qstr name;
+	struct configfs_dirent *sd;
+	/* We trust the caller holds a reference to parent */
+	struct dentry *child, *parent = parent_group->cg_item.ci_dentry;
+
+	if (!group->cg_item.ci_name)
+		group->cg_item.ci_name = group->cg_item.ci_namebuf;
+	name.name = group->cg_item.ci_name;
+	name.len = strlen(name.name);
+	name.hash = full_name_hash(name.name, name.len);
+
+	ret = -ENOMEM;
+	child = d_alloc(parent, &name);
+	if (child) {
+		d_add(child, NULL);
+
+		ret = configfs_attach_group(&parent_group->cg_item,
+					    &group->cg_item, child);
+		if (!ret) {
+			sd = child->d_fsdata;
+			sd->s_type |= CONFIGFS_USET_DEFAULT;
+		} else {
+			d_delete(child);
+			dput(child);
+		}
+	}
+
+	return ret;
+}
+
+static int populate_groups(struct config_group *group)
+{
+	struct config_group *new_group;
+	struct dentry *dentry = group->cg_item.ci_dentry;
+	int ret = 0;
+	int i;
+
+	if (group && group->default_groups) {
+		/* FYI, we're faking mkdir here
+		 * I'm not sure we need this semaphore, as we're called
+		 * from our parent's mkdir.  That holds our parent's
+		 * i_sem, so afaik lookup cannot continue through our
+		 * parent to find us, let alone mess with our tree.
+		 * That said, taking our i_sem is closer to mkdir
+		 * emulation, and shouldn't hurt. */
+		down(&dentry->d_inode->i_sem);
+
+		for (i = 0; group->default_groups[i]; i++) {
+			new_group = group->default_groups[i];
+
+			ret = create_default_group(group, new_group);
+			if (ret)
+				break;
+		}
+
+		up(&dentry->d_inode->i_sem);
+	}
+
+	if (ret)
+		detach_groups(group);
+
+	return ret;
+}
+
+/*
+ * All of link_obj/unlink_obj/link_group/unlink_group require that
+ * subsys->su_sem is held.
+ */
+
+static void unlink_obj(struct config_item *item)
+{
+	struct config_group *group;
+
+	group = item->ci_group;
+	if (group) {
+		list_del_init(&item->ci_entry);
+
+		item->ci_group = NULL;
+		item->ci_parent = NULL;
+		config_item_put(item);
+
+		config_group_put(group);
+	}
+}
+
+static void link_obj(struct config_item *parent_item, struct config_item *item)
+{
+	/* Parent seems redundant with group, but it makes certain
+	 * traversals much nicer. */
+	item->ci_parent = parent_item;
+	item->ci_group = config_group_get(to_config_group(parent_item));
+	list_add_tail(&item->ci_entry, &item->ci_group->cg_children);
+
+	config_item_get(item);
+}
+
+static void unlink_group(struct config_group *group)
+{
+	int i;
+	struct config_group *new_group;
+
+	if (group->default_groups) {
+		for (i = 0; group->default_groups[i]; i++) {
+			new_group = group->default_groups[i];
+			unlink_group(new_group);
+		}
+	}
+
+	group->cg_subsys = NULL;
+	unlink_obj(&group->cg_item);
+}
+
+static void link_group(struct config_group *parent_group, struct config_group *group)
+{
+	int i;
+	struct config_group *new_group;
+	struct configfs_subsystem *subsys = NULL; /* gcc is a turd */
+
+	link_obj(&parent_group->cg_item, &group->cg_item);
+
+	if (parent_group->cg_subsys)
+		subsys = parent_group->cg_subsys;
+	else if (configfs_is_root(&parent_group->cg_item))
+		subsys = to_configfs_subsystem(group);
+	else
+		BUG();
+	group->cg_subsys = subsys;
+
+	if (group->default_groups) {
+		for (i = 0; group->default_groups[i]; i++) {
+			new_group = group->default_groups[i];
+			link_group(group, new_group);
+		}
+	}
+}
+
+/*
+ * The goal is that configfs_attach_item() (and
+ * configfs_attach_group()) can be called from either the VFS or this
+ * module.  That is, they assume that the items have been created,
+ * the dentry allocated, and the dcache is all ready to go.
+ *
+ * If they fail, they must clean up after themselves as if they
+ * had never been called.  The caller (VFS or local function) will
+ * handle cleaning up the dcache bits.
+ *
+ * configfs_detach_group() and configfs_detach_item() behave similarly on
+ * the way out.  They assume that the proper semaphores are held, they
+ * clean up the configfs items, and they expect their callers will
+ * handle the dcache bits.
+ */
+static int configfs_attach_item(struct config_item *parent_item,
+				struct config_item *item,
+				struct dentry *dentry)
+{
+	int ret;
+
+	ret = configfs_create_dir(item, dentry);
+	if (!ret) {
+		ret = populate_attrs(item);
+		if (ret) {
+			configfs_remove_dir(item);
+			d_delete(dentry);
+		}
+	}
+
+	return ret;
+}
+
+static void configfs_detach_item(struct config_item *item)
+{
+	detach_attrs(item);
+	configfs_remove_dir(item);
+}
+
+static int configfs_attach_group(struct config_item *parent_item,
+				 struct config_item *item,
+				 struct dentry *dentry)
+{
+	int ret;
+	struct configfs_dirent *sd;
+
+	ret = configfs_attach_item(parent_item, item, dentry);
+	if (!ret) {
+		sd = dentry->d_fsdata;
+		sd->s_type |= CONFIGFS_USET_DIR;
+
+		ret = populate_groups(to_config_group(item));
+		if (ret) {
+			configfs_detach_item(item);
+			d_delete(dentry);
+		}
+	}
+
+	return ret;
+}
+
+static void configfs_detach_group(struct config_item *item)
+{
+	detach_groups(to_config_group(item));
+	configfs_detach_item(item);
+}
+
+/*
+ * Drop the initial reference from make_item()/make_group()
+ * This function assumes that reference is held on item
+ * and that item holds a valid reference to the parent.  Also, it
+ * assumes the caller has validated ci_type.
+ */
+static void client_drop_item(struct config_item *parent_item,
+			     struct config_item *item)
+{
+	struct config_item_type *type;
+
+	type = parent_item->ci_type;
+	BUG_ON(!type);
+
+	if (type->ct_group_ops && type->ct_group_ops->drop_item)
+		type->ct_group_ops->drop_item(to_config_group(parent_item),
+						item);
+	else
+		config_item_put(item);
+}
+
+
+static int configfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	int ret;
+	struct config_group *group;
+	struct config_item *item;
+	struct config_item *parent_item;
+	struct configfs_subsystem *subsys;
+	struct configfs_dirent *sd;
+	struct config_item_type *type;
+	struct module *owner;
+	char *name;
+
+	if (dentry->d_parent == configfs_sb->s_root)
+		return -EPERM;
+
+	sd = dentry->d_parent->d_fsdata;
+	if (!(sd->s_type & CONFIGFS_USET_DIR))
+		return -EPERM;
+
+	parent_item = configfs_get_config_item(dentry->d_parent);
+	type = parent_item->ci_type;
+	subsys = to_config_group(parent_item)->cg_subsys;
+	BUG_ON(!subsys);
+
+	if (!type || !type->ct_group_ops ||
+	    (!type->ct_group_ops->make_group &&
+	     !type->ct_group_ops->make_item)) {
+		config_item_put(parent_item);
+		return -EPERM;  /* What lack-of-mkdir returns */
+	}
+
+	name = kmalloc(dentry->d_name.len + 1, GFP_KERNEL);
+	if (!name) {
+		config_item_put(parent_item);
+		return -ENOMEM;
+	}
+	snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name);
+
+	down(&subsys->su_sem);
+	group = NULL;
+	item = NULL;
+	if (type->ct_group_ops->make_group) {
+		group = type->ct_group_ops->make_group(to_config_group(parent_item), name);
+		if (group) {
+			link_group(to_config_group(parent_item), group);
+			item = &group->cg_item;
+		}
+	} else {
+		item = type->ct_group_ops->make_item(to_config_group(parent_item), name);
+		if (item)
+			link_obj(parent_item, item);
+	}
+	up(&subsys->su_sem);
+
+	kfree(name);
+	if (!item) {
+		config_item_put(parent_item);
+		return -ENOMEM;
+	}
+
+	ret = -EINVAL;
+	type = item->ci_type;
+	if (type) {
+		owner = type->ct_owner;
+		if (try_module_get(owner)) {
+			if (group) {
+				ret = configfs_attach_group(parent_item,
+							    item,
+							    dentry);
+			} else {
+				ret = configfs_attach_item(parent_item,
+							   item,
+							   dentry);
+			}
+
+			if (ret) {
+				down(&subsys->su_sem);
+				if (group)
+					unlink_group(group);
+				else
+					unlink_obj(item);
+				client_drop_item(parent_item, item);
+				up(&subsys->su_sem);
+
+				config_item_put(parent_item);
+				module_put(owner);
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	struct config_item *parent_item;
+	struct config_item *item;
+	struct configfs_subsystem *subsys;
+	struct configfs_dirent *sd;
+	struct module *owner = NULL;
+	int ret;
+
+	if (dentry->d_parent == configfs_sb->s_root)
+		return -EPERM;
+
+	sd = dentry->d_fsdata;
+	if (sd->s_type & CONFIGFS_USET_DEFAULT)
+		return -EPERM;
+
+	parent_item = configfs_get_config_item(dentry->d_parent);
+	subsys = to_config_group(parent_item)->cg_subsys;
+	BUG_ON(!subsys);
+
+	if (!parent_item->ci_type) {
+		config_item_put(parent_item);
+		return -EINVAL;
+	}
+
+	ret = configfs_detach_prep(dentry);
+	if (ret) {
+		configfs_detach_rollback(dentry);
+		config_item_put(parent_item);
+		return ret;
+	}
+
+	item = configfs_get_config_item(dentry);
+
+	/* Drop reference from above, item already holds one. */
+	config_item_put(parent_item);
+
+	if (item->ci_type)
+		owner = item->ci_type->ct_owner;
+
+	if (sd->s_type & CONFIGFS_USET_DIR) {
+		configfs_detach_group(item);
+
+		down(&subsys->su_sem);
+		unlink_group(to_config_group(item));
+	} else {
+		configfs_detach_item(item);
+
+		down(&subsys->su_sem);
+		unlink_obj(item);
+	}
+
+	client_drop_item(parent_item, item);
+	up(&subsys->su_sem);
+
+	/* Drop our reference from above */
+	config_item_put(item);
+
+	module_put(owner);
+
+	return 0;
+}
+
+struct inode_operations configfs_dir_inode_operations = {
+	.mkdir		= configfs_mkdir,
+	.rmdir		= configfs_rmdir,
+	.symlink	= configfs_symlink,
+	.unlink		= configfs_unlink,
+	.lookup		= configfs_lookup,
+};
+
+#if 0
+int configfs_rename_dir(struct config_item * item, const char *new_name)
+{
+	int error = 0;
+	struct dentry * new_dentry, * parent;
+
+	if (!strcmp(config_item_name(item), new_name))
+		return -EINVAL;
+
+	if (!item->parent)
+		return -EINVAL;
+
+	down_write(&configfs_rename_sem);
+	parent = item->parent->dentry;
+
+	down(&parent->d_inode->i_sem);
+
+	new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
+	if (!IS_ERR(new_dentry)) {
+  		if (!new_dentry->d_inode) {
+			error = config_item_set_name(item, "%s", new_name);
+			if (!error) {
+				d_add(new_dentry, NULL);
+				d_move(item->dentry, new_dentry);
+			}
+			else
+				d_delete(new_dentry);
+		} else
+			error = -EEXIST;
+		dput(new_dentry);
+	}
+	up(&parent->d_inode->i_sem);
+	up_write(&configfs_rename_sem);
+
+	return error;
+}
+#endif
+
+static int configfs_dir_open(struct inode *inode, struct file *file)
+{
+	struct dentry * dentry = file->f_dentry;
+	struct configfs_dirent * parent_sd = dentry->d_fsdata;
+
+	down(&dentry->d_inode->i_sem);
+	file->private_data = configfs_new_dirent(parent_sd, NULL);
+	up(&dentry->d_inode->i_sem);
+
+	return file->private_data ? 0 : -ENOMEM;
+
+}
+
+static int configfs_dir_close(struct inode *inode, struct file *file)
+{
+	struct dentry * dentry = file->f_dentry;
+	struct configfs_dirent * cursor = file->private_data;
+
+	down(&dentry->d_inode->i_sem);
+	list_del_init(&cursor->s_sibling);
+	up(&dentry->d_inode->i_sem);
+
+	release_configfs_dirent(cursor);
+
+	return 0;
+}
+
+/* Relationship between s_mode and the DT_xxx types */
+static inline unsigned char dt_type(struct configfs_dirent *sd)
+{
+	return (sd->s_mode >> 12) & 15;
+}
+
+static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
+{
+	struct dentry *dentry = filp->f_dentry;
+	struct configfs_dirent * parent_sd = dentry->d_fsdata;
+	struct configfs_dirent *cursor = filp->private_data;
+	struct list_head *p, *q = &cursor->s_sibling;
+	ino_t ino;
+	int i = filp->f_pos;
+
+	switch (i) {
+		case 0:
+			ino = dentry->d_inode->i_ino;
+			if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
+				break;
+			filp->f_pos++;
+			i++;
+			/* fallthrough */
+		case 1:
+			ino = parent_ino(dentry);
+			if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
+				break;
+			filp->f_pos++;
+			i++;
+			/* fallthrough */
+		default:
+			if (filp->f_pos == 2) {
+				list_del(q);
+				list_add(q, &parent_sd->s_children);
+			}
+			for (p=q->next; p!= &parent_sd->s_children; p=p->next) {
+				struct configfs_dirent *next;
+				const char * name;
+				int len;
+
+				next = list_entry(p, struct configfs_dirent,
+						   s_sibling);
+				if (!next->s_element)
+					continue;
+
+				name = configfs_get_name(next);
+				len = strlen(name);
+				if (next->s_dentry)
+					ino = next->s_dentry->d_inode->i_ino;
+				else
+					ino = iunique(configfs_sb, 2);
+
+				if (filldir(dirent, name, len, filp->f_pos, ino,
+						 dt_type(next)) < 0)
+					return 0;
+
+				list_del(q);
+				list_add(q, p);
+				p = q;
+				filp->f_pos++;
+			}
+	}
+	return 0;
+}
+
+static loff_t configfs_dir_lseek(struct file * file, loff_t offset, int origin)
+{
+	struct dentry * dentry = file->f_dentry;
+
+	down(&dentry->d_inode->i_sem);
+	switch (origin) {
+		case 1:
+			offset += file->f_pos;
+		case 0:
+			if (offset >= 0)
+				break;
+		default:
+			up(&file->f_dentry->d_inode->i_sem);
+			return -EINVAL;
+	}
+	if (offset != file->f_pos) {
+		file->f_pos = offset;
+		if (file->f_pos >= 2) {
+			struct configfs_dirent *sd = dentry->d_fsdata;
+			struct configfs_dirent *cursor = file->private_data;
+			struct list_head *p;
+			loff_t n = file->f_pos - 2;
+
+			list_del(&cursor->s_sibling);
+			p = sd->s_children.next;
+			while (n && p != &sd->s_children) {
+				struct configfs_dirent *next;
+				next = list_entry(p, struct configfs_dirent,
+						   s_sibling);
+				if (next->s_element)
+					n--;
+				p = p->next;
+			}
+			list_add_tail(&cursor->s_sibling, p);
+		}
+	}
+	up(&dentry->d_inode->i_sem);
+	return offset;
+}
+
+struct file_operations configfs_dir_operations = {
+	.open		= configfs_dir_open,
+	.release	= configfs_dir_close,
+	.llseek		= configfs_dir_lseek,
+	.read		= generic_read_dir,
+	.readdir	= configfs_readdir,
+};
+
+int configfs_register_subsystem(struct configfs_subsystem *subsys)
+{
+	int err;
+	struct config_group *group = &subsys->su_group;
+	struct qstr name;
+	struct dentry *dentry;
+	struct configfs_dirent *sd;
+
+	err = configfs_pin_fs();
+	if (err)
+		return err;
+
+	if (!group->cg_item.ci_name)
+		group->cg_item.ci_name = group->cg_item.ci_namebuf;
+
+	sd = configfs_sb->s_root->d_fsdata;
+	link_group(to_config_group(sd->s_element), group);
+
+	down(&configfs_sb->s_root->d_inode->i_sem);
+
+	name.name = group->cg_item.ci_name;
+	name.len = strlen(name.name);
+	name.hash = full_name_hash(name.name, name.len);
+
+	err = -ENOMEM;
+	dentry = d_alloc(configfs_sb->s_root, &name);
+	if (!dentry)
+		goto out_release;
+
+	d_add(dentry, NULL);
+
+	err = configfs_attach_group(sd->s_element, &group->cg_item,
+				    dentry);
+	if (!err)
+		dentry = NULL;
+	else
+		d_delete(dentry);
+
+	up(&configfs_sb->s_root->d_inode->i_sem);
+
+	if (dentry) {
+	    dput(dentry);
+out_release:
+	    unlink_group(group);
+	    configfs_release_fs();
+	}
+
+	return err;
+}
+
+void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
+{
+	struct config_group *group = &subsys->su_group;
+	struct dentry *dentry = group->cg_item.ci_dentry;
+
+	if (dentry->d_parent != configfs_sb->s_root) {
+		printk(KERN_ERR "configfs: Tried to unregister non-subsystem!\n");
+		return;
+	}
+
+	down(&configfs_sb->s_root->d_inode->i_sem);
+	down(&dentry->d_inode->i_sem);
+	if (configfs_detach_prep(dentry)) {
+		printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n");
+	}
+	configfs_detach_group(&group->cg_item);
+	dentry->d_inode->i_flags |= S_DEAD;
+	up(&dentry->d_inode->i_sem);
+
+	d_delete(dentry);
+
+	up(&configfs_sb->s_root->d_inode->i_sem);
+
+	dput(dentry);
+
+	unlink_group(group);
+	configfs_release_fs();
+}
+
+EXPORT_SYMBOL(configfs_register_subsystem);
+EXPORT_SYMBOL(configfs_unregister_subsystem);
diff --git a/fs/configfs/file.c b/fs/configfs/file.c
new file mode 100644
index 0000000..af1ffc9
--- /dev/null
+++ b/fs/configfs/file.c
@@ -0,0 +1,360 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * file.c - operations for regular (text) files.
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ */
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/dnotify.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <asm/semaphore.h>
+
+#include <linux/configfs.h>
+#include "configfs_internal.h"
+
+
+struct configfs_buffer {
+	size_t			count;
+	loff_t			pos;
+	char			* page;
+	struct configfs_item_operations	* ops;
+	struct semaphore	sem;
+	int			needs_read_fill;
+};
+
+
+/**
+ *	fill_read_buffer - allocate and fill buffer from item.
+ *	@dentry:	dentry pointer.
+ *	@buffer:	data buffer for file.
+ *
+ *	Allocate @buffer->page, if it hasn't been already, then call the
+ *	config_item's show() method to fill the buffer with this attribute's
+ *	data.
+ *	This is called only once, on the file's first read.
+ */
+static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buffer)
+{
+	struct configfs_attribute * attr = to_attr(dentry);
+	struct config_item * item = to_item(dentry->d_parent);
+	struct configfs_item_operations * ops = buffer->ops;
+	int ret = 0;
+	ssize_t count;
+
+	if (!buffer->page)
+		buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
+	if (!buffer->page)
+		return -ENOMEM;
+
+	count = ops->show_attribute(item,attr,buffer->page);
+	buffer->needs_read_fill = 0;
+	BUG_ON(count > (ssize_t)PAGE_SIZE);
+	if (count >= 0)
+		buffer->count = count;
+	else
+		ret = count;
+	return ret;
+}
+
+
+/**
+ *	flush_read_buffer - push buffer to userspace.
+ *	@buffer:	data buffer for file.
+ *	@userbuf:	user-passed buffer.
+ *	@count:		number of bytes requested.
+ *	@ppos:		file position.
+ *
+ *	Copy the buffer we filled in fill_read_buffer() to userspace.
+ *	This is done at the reader's leisure, copying and advancing
+ *	the amount they specify each time.
+ *	This may be called continuously until the buffer is empty.
+ */
+static int flush_read_buffer(struct configfs_buffer * buffer, char __user * buf,
+			     size_t count, loff_t * ppos)
+{
+	int error;
+
+	if (*ppos > buffer->count)
+		return 0;
+
+	if (count > (buffer->count - *ppos))
+		count = buffer->count - *ppos;
+
+	error = copy_to_user(buf,buffer->page + *ppos,count);
+	if (!error)
+		*ppos += count;
+	return error ? -EFAULT : count;
+}
+
+/**
+ *	configfs_read_file - read an attribute.
+ *	@file:	file pointer.
+ *	@buf:	buffer to fill.
+ *	@count:	number of bytes to read.
+ *	@ppos:	starting offset in file.
+ *
+ *	Userspace wants to read an attribute file. The attribute descriptor
+ *	is in the file's ->d_fsdata. The target item is in the directory's
+ *	->d_fsdata.
+ *
+ *	We call fill_read_buffer() to allocate and fill the buffer from the
+ *	item's show() method exactly once (if the read is happening from
+ *	the beginning of the file). That should fill the entire buffer with
+ *	all the data the item has to offer for that attribute.
+ *	We then call flush_read_buffer() to copy the buffer to userspace
+ *	in the increments specified.
+ */
+
+static ssize_t
+configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
+{
+	struct configfs_buffer * buffer = file->private_data;
+	ssize_t retval = 0;
+
+	down(&buffer->sem);
+	if (buffer->needs_read_fill) {
+		if ((retval = fill_read_buffer(file->f_dentry,buffer)))
+			goto out;
+	}
+	pr_debug("%s: count = %d, ppos = %lld, buf = %s\n",
+		 __FUNCTION__,count,*ppos,buffer->page);
+	retval = flush_read_buffer(buffer,buf,count,ppos);
+out:
+	up(&buffer->sem);
+	return retval;
+}
+
+
+/**
+ *	fill_write_buffer - copy buffer from userspace.
+ *	@buffer:	data buffer for file.
+ *	@userbuf:	data from user.
+ *	@count:		number of bytes in @userbuf.
+ *
+ *	Allocate @buffer->page if it hasn't been already, then
+ *	copy the user-supplied buffer into it.
+ */
+
+static int
+fill_write_buffer(struct configfs_buffer * buffer, const char __user * buf, size_t count)
+{
+	int error;
+
+	if (!buffer->page)
+		buffer->page = (char *)get_zeroed_page(GFP_KERNEL);
+	if (!buffer->page)
+		return -ENOMEM;
+
+	if (count > PAGE_SIZE)
+		count = PAGE_SIZE;
+	error = copy_from_user(buffer->page,buf,count);
+	buffer->needs_read_fill = 1;
+	return error ? -EFAULT : count;
+}
+
+
+/**
+ *	flush_write_buffer - push buffer to config_item.
+ *	@file:		file pointer.
+ *	@buffer:	data buffer for file.
+ *
+ *	Get the correct pointers for the config_item and the attribute we're
+ *	dealing with, then call the store() method for the attribute,
+ *	passing the buffer that we acquired in fill_write_buffer().
+ */
+
+static int
+flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size_t count)
+{
+	struct configfs_attribute * attr = to_attr(dentry);
+	struct config_item * item = to_item(dentry->d_parent);
+	struct configfs_item_operations * ops = buffer->ops;
+
+	return ops->store_attribute(item,attr,buffer->page,count);
+}
+
+
+/**
+ *	configfs_write_file - write an attribute.
+ *	@file:	file pointer
+ *	@buf:	data to write
+ *	@count:	number of bytes
+ *	@ppos:	starting offset
+ *
+ *	Similar to configfs_read_file(), though working in the opposite direction.
+ *	We allocate and fill the data from the user in fill_write_buffer(),
+ *	then push it to the config_item in flush_write_buffer().
+ *	There is no easy way for us to know if userspace is only doing a partial
+ *	write, so we don't support them. We expect the entire buffer to come
+ *	on the first write.
+ *	Hint: if you're writing a value, first read the file, modify only the
+ *	the value you're changing, then write entire buffer back.
+ */
+
+static ssize_t
+configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{
+	struct configfs_buffer * buffer = file->private_data;
+
+	down(&buffer->sem);
+	count = fill_write_buffer(buffer,buf,count);
+	if (count > 0)
+		count = flush_write_buffer(file->f_dentry,buffer,count);
+	if (count > 0)
+		*ppos += count;
+	up(&buffer->sem);
+	return count;
+}
+
+static int check_perm(struct inode * inode, struct file * file)
+{
+	struct config_item *item = configfs_get_config_item(file->f_dentry->d_parent);
+	struct configfs_attribute * attr = to_attr(file->f_dentry);
+	struct configfs_buffer * buffer;
+	struct configfs_item_operations * ops = NULL;
+	int error = 0;
+
+	if (!item || !attr)
+		goto Einval;
+
+	/* Grab the module reference for this attribute if we have one */
+	if (!try_module_get(attr->ca_owner)) {
+		error = -ENODEV;
+		goto Done;
+	}
+
+	if (item->ci_type)
+		ops = item->ci_type->ct_item_ops;
+	else
+		goto Eaccess;
+
+	/* File needs write support.
+	 * The inode's perms must say it's ok,
+	 * and we must have a store method.
+	 */
+	if (file->f_mode & FMODE_WRITE) {
+
+		if (!(inode->i_mode & S_IWUGO) || !ops->store_attribute)
+			goto Eaccess;
+
+	}
+
+	/* File needs read support.
+	 * The inode's perms must say it's ok, and we there
+	 * must be a show method for it.
+	 */
+	if (file->f_mode & FMODE_READ) {
+		if (!(inode->i_mode & S_IRUGO) || !ops->show_attribute)
+			goto Eaccess;
+	}
+
+	/* No error? Great, allocate a buffer for the file, and store it
+	 * it in file->private_data for easy access.
+	 */
+	buffer = kmalloc(sizeof(struct configfs_buffer),GFP_KERNEL);
+	if (buffer) {
+		memset(buffer,0,sizeof(struct configfs_buffer));
+		init_MUTEX(&buffer->sem);
+		buffer->needs_read_fill = 1;
+		buffer->ops = ops;
+		file->private_data = buffer;
+	} else
+		error = -ENOMEM;
+	goto Done;
+
+ Einval:
+	error = -EINVAL;
+	goto Done;
+ Eaccess:
+	error = -EACCES;
+	module_put(attr->ca_owner);
+ Done:
+	if (error && item)
+		config_item_put(item);
+	return error;
+}
+
+static int configfs_open_file(struct inode * inode, struct file * filp)
+{
+	return check_perm(inode,filp);
+}
+
+static int configfs_release(struct inode * inode, struct file * filp)
+{
+	struct config_item * item = to_item(filp->f_dentry->d_parent);
+	struct configfs_attribute * attr = to_attr(filp->f_dentry);
+	struct module * owner = attr->ca_owner;
+	struct configfs_buffer * buffer = filp->private_data;
+
+	if (item)
+		config_item_put(item);
+	/* After this point, attr should not be accessed. */
+	module_put(owner);
+
+	if (buffer) {
+		if (buffer->page)
+			free_page((unsigned long)buffer->page);
+		kfree(buffer);
+	}
+	return 0;
+}
+
+struct file_operations configfs_file_operations = {
+	.read		= configfs_read_file,
+	.write		= configfs_write_file,
+	.llseek		= generic_file_llseek,
+	.open		= configfs_open_file,
+	.release	= configfs_release,
+};
+
+
+int configfs_add_file(struct dentry * dir, const struct configfs_attribute * attr, int type)
+{
+	struct configfs_dirent * parent_sd = dir->d_fsdata;
+	umode_t mode = (attr->ca_mode & S_IALLUGO) | S_IFREG;
+	int error = 0;
+
+	down(&dir->d_inode->i_sem);
+	error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type);
+	up(&dir->d_inode->i_sem);
+
+	return error;
+}
+
+
+/**
+ *	configfs_create_file - create an attribute file for an item.
+ *	@item:	item we're creating for.
+ *	@attr:	atrribute descriptor.
+ */
+
+int configfs_create_file(struct config_item * item, const struct configfs_attribute * attr)
+{
+	BUG_ON(!item || !item->ci_dentry || !attr);
+
+	return configfs_add_file(item->ci_dentry, attr,
+				 CONFIGFS_ITEM_ATTR);
+}
+
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
new file mode 100644
index 0000000..6b274c6
--- /dev/null
+++ b/fs/configfs/inode.c
@@ -0,0 +1,162 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * inode.c - basic inode and dentry operations.
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * Please see Documentation/filesystems/configfs.txt for more information.
+ */
+
+#undef DEBUG
+
+#include <linux/pagemap.h>
+#include <linux/namei.h>
+#include <linux/backing-dev.h>
+
+#include <linux/configfs.h>
+#include "configfs_internal.h"
+
+extern struct super_block * configfs_sb;
+
+static struct address_space_operations configfs_aops = {
+	.readpage	= simple_readpage,
+	.prepare_write	= simple_prepare_write,
+	.commit_write	= simple_commit_write
+};
+
+static struct backing_dev_info configfs_backing_dev_info = {
+	.ra_pages	= 0,	/* No readahead */
+	.capabilities	= BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
+};
+
+struct inode * configfs_new_inode(mode_t mode)
+{
+	struct inode * inode = new_inode(configfs_sb);
+	if (inode) {
+		inode->i_mode = mode;
+		inode->i_uid = 0;
+		inode->i_gid = 0;
+		inode->i_blksize = PAGE_CACHE_SIZE;
+		inode->i_blocks = 0;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		inode->i_mapping->a_ops = &configfs_aops;
+		inode->i_mapping->backing_dev_info = &configfs_backing_dev_info;
+	}
+	return inode;
+}
+
+int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
+{
+	int error = 0;
+	struct inode * inode = NULL;
+	if (dentry) {
+		if (!dentry->d_inode) {
+			if ((inode = configfs_new_inode(mode))) {
+				if (dentry->d_parent && dentry->d_parent->d_inode) {
+					struct inode *p_inode = dentry->d_parent->d_inode;
+					p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
+				}
+				goto Proceed;
+			}
+			else
+				error = -ENOMEM;
+		} else
+			error = -EEXIST;
+	} else
+		error = -ENOENT;
+	goto Done;
+
+ Proceed:
+	if (init)
+		error = init(inode);
+	if (!error) {
+		d_instantiate(dentry, inode);
+		if (S_ISDIR(mode) || S_ISLNK(mode))
+			dget(dentry);  /* pin link and directory dentries in core */
+	} else
+		iput(inode);
+ Done:
+	return error;
+}
+
+/*
+ * Get the name for corresponding element represented by the given configfs_dirent
+ */
+const unsigned char * configfs_get_name(struct configfs_dirent *sd)
+{
+	struct attribute * attr;
+
+	if (!sd || !sd->s_element)
+		BUG();
+
+	/* These always have a dentry, so use that */
+	if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK))
+		return sd->s_dentry->d_name.name;
+
+	if (sd->s_type & CONFIGFS_ITEM_ATTR) {
+		attr = sd->s_element;
+		return attr->name;
+	}
+	return NULL;
+}
+
+
+/*
+ * Unhashes the dentry corresponding to given configfs_dirent
+ * Called with parent inode's i_sem held.
+ */
+void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
+{
+	struct dentry * dentry = sd->s_dentry;
+
+	if (dentry) {
+		spin_lock(&dcache_lock);
+		if (!(d_unhashed(dentry) && dentry->d_inode)) {
+			dget_locked(dentry);
+			__d_drop(dentry);
+			spin_unlock(&dcache_lock);
+			simple_unlink(parent->d_inode, dentry);
+		} else
+			spin_unlock(&dcache_lock);
+	}
+}
+
+void configfs_hash_and_remove(struct dentry * dir, const char * name)
+{
+	struct configfs_dirent * sd;
+	struct configfs_dirent * parent_sd = dir->d_fsdata;
+
+	down(&dir->d_inode->i_sem);
+	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+		if (!sd->s_element)
+			continue;
+		if (!strcmp(configfs_get_name(sd), name)) {
+			list_del_init(&sd->s_sibling);
+			configfs_drop_dentry(sd, dir);
+			configfs_put(sd);
+			break;
+		}
+	}
+	up(&dir->d_inode->i_sem);
+}
+
+
diff --git a/fs/configfs/item.c b/fs/configfs/item.c
new file mode 100644
index 0000000..e07485a
--- /dev/null
+++ b/fs/configfs/item.c
@@ -0,0 +1,227 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * item.c - library routines for handling generic config items
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on kobject:
+ * 	kobject is Copyright (c) 2002-2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * Please see the file Documentation/filesystems/configfs.txt for
+ * critical information about using the config_item interface.
+ */
+
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+
+#include <linux/configfs.h>
+
+
+static inline struct config_item * to_item(struct list_head * entry)
+{
+	return container_of(entry,struct config_item,ci_entry);
+}
+
+/* Evil kernel */
+static void config_item_release(struct kref *kref);
+
+/**
+ *	config_item_init - initialize item.
+ *	@item:	item in question.
+ */
+void config_item_init(struct config_item * item)
+{
+	kref_init(&item->ci_kref);
+	INIT_LIST_HEAD(&item->ci_entry);
+}
+
+/**
+ *	config_item_set_name - Set the name of an item
+ *	@item:	item.
+ *	@name:	name.
+ *
+ *	If strlen(name) >= CONFIGFS_ITEM_NAME_LEN, then use a
+ *	dynamically allocated string that @item->ci_name points to.
+ *	Otherwise, use the static @item->ci_namebuf array.
+ */
+
+int config_item_set_name(struct config_item * item, const char * fmt, ...)
+{
+	int error = 0;
+	int limit = CONFIGFS_ITEM_NAME_LEN;
+	int need;
+	va_list args;
+	char * name;
+
+	/*
+	 * First, try the static array
+	 */
+	va_start(args,fmt);
+	need = vsnprintf(item->ci_namebuf,limit,fmt,args);
+	va_end(args);
+	if (need < limit)
+		name = item->ci_namebuf;
+	else {
+		/*
+		 * Need more space? Allocate it and try again
+		 */
+		limit = need + 1;
+		name = kmalloc(limit,GFP_KERNEL);
+		if (!name) {
+			error = -ENOMEM;
+			goto Done;
+		}
+		va_start(args,fmt);
+		need = vsnprintf(name,limit,fmt,args);
+		va_end(args);
+
+		/* Still? Give up. */
+		if (need >= limit) {
+			kfree(name);
+			error = -EFAULT;
+			goto Done;
+		}
+	}
+
+	/* Free the old name, if necessary. */
+	if (item->ci_name && item->ci_name != item->ci_namebuf)
+		kfree(item->ci_name);
+
+	/* Now, set the new name */
+	item->ci_name = name;
+ Done:
+	return error;
+}
+
+EXPORT_SYMBOL(config_item_set_name);
+
+void config_item_init_type_name(struct config_item *item,
+				const char *name,
+				struct config_item_type *type)
+{
+	config_item_set_name(item, name);
+	item->ci_type = type;
+	config_item_init(item);
+}
+EXPORT_SYMBOL(config_item_init_type_name);
+
+void config_group_init_type_name(struct config_group *group, const char *name,
+			 struct config_item_type *type)
+{
+	config_item_set_name(&group->cg_item, name);
+	group->cg_item.ci_type = type;
+	config_group_init(group);
+}
+EXPORT_SYMBOL(config_group_init_type_name);
+
+struct config_item * config_item_get(struct config_item * item)
+{
+	if (item)
+		kref_get(&item->ci_kref);
+	return item;
+}
+
+/**
+ *	config_item_cleanup - free config_item resources.
+ *	@item:	item.
+ */
+
+void config_item_cleanup(struct config_item * item)
+{
+	struct config_item_type * t = item->ci_type;
+	struct config_group * s = item->ci_group;
+	struct config_item * parent = item->ci_parent;
+
+	pr_debug("config_item %s: cleaning up\n",config_item_name(item));
+	if (item->ci_name != item->ci_namebuf)
+		kfree(item->ci_name);
+	item->ci_name = NULL;
+	if (t && t->ct_item_ops && t->ct_item_ops->release)
+		t->ct_item_ops->release(item);
+	if (s)
+		config_group_put(s);
+	if (parent)
+		config_item_put(parent);
+}
+
+static void config_item_release(struct kref *kref)
+{
+	config_item_cleanup(container_of(kref, struct config_item, ci_kref));
+}
+
+/**
+ *	config_item_put - decrement refcount for item.
+ *	@item:	item.
+ *
+ *	Decrement the refcount, and if 0, call config_item_cleanup().
+ */
+void config_item_put(struct config_item * item)
+{
+	if (item)
+		kref_put(&item->ci_kref, config_item_release);
+}
+
+
+/**
+ *	config_group_init - initialize a group for use
+ *	@k:	group
+ */
+
+void config_group_init(struct config_group *group)
+{
+	config_item_init(&group->cg_item);
+	INIT_LIST_HEAD(&group->cg_children);
+}
+
+
+/**
+ *	config_group_find_obj - search for item in group.
+ *	@group:	group we're looking in.
+ *	@name:	item's name.
+ *
+ *	Lock group via @group->cg_subsys, and iterate over @group->cg_list,
+ *	looking for a matching config_item. If matching item is found
+ *	take a reference and return the item.
+ */
+
+struct config_item * config_group_find_obj(struct config_group * group, const char * name)
+{
+	struct list_head * entry;
+	struct config_item * ret = NULL;
+
+        /* XXX LOCKING! */
+	list_for_each(entry,&group->cg_children) {
+		struct config_item * item = to_item(entry);
+		if (config_item_name(item) &&
+                    !strcmp(config_item_name(item), name)) {
+			ret = config_item_get(item);
+			break;
+		}
+	}
+	return ret;
+}
+
+
+EXPORT_SYMBOL(config_item_init);
+EXPORT_SYMBOL(config_group_init);
+EXPORT_SYMBOL(config_item_get);
+EXPORT_SYMBOL(config_item_put);
+
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
new file mode 100644
index 0000000..1a2f6f6
--- /dev/null
+++ b/fs/configfs/mount.c
@@ -0,0 +1,159 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * mount.c - operations for initializing and mounting configfs.
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ */
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+
+#include <linux/configfs.h>
+#include "configfs_internal.h"
+
+/* Random magic number */
+#define CONFIGFS_MAGIC 0x62656570
+
+struct vfsmount * configfs_mount = NULL;
+struct super_block * configfs_sb = NULL;
+static int configfs_mnt_count = 0;
+
+static struct super_operations configfs_ops = {
+	.statfs		= simple_statfs,
+	.drop_inode	= generic_delete_inode,
+};
+
+static struct config_group configfs_root_group = {
+	.cg_item = {
+		.ci_namebuf	= "root",
+		.ci_name	= configfs_root_group.cg_item.ci_namebuf,
+	},
+};
+
+int configfs_is_root(struct config_item *item)
+{
+	return item == &configfs_root_group.cg_item;
+}
+
+static struct configfs_dirent configfs_root = {
+	.s_sibling	= LIST_HEAD_INIT(configfs_root.s_sibling),
+	.s_children	= LIST_HEAD_INIT(configfs_root.s_children),
+	.s_element	= &configfs_root_group.cg_item,
+	.s_type		= CONFIGFS_ROOT,
+};
+
+static int configfs_fill_super(struct super_block *sb, void *data, int silent)
+{
+	struct inode *inode;
+	struct dentry *root;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = CONFIGFS_MAGIC;
+	sb->s_op = &configfs_ops;
+	configfs_sb = sb;
+
+	inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
+	if (inode) {
+		inode->i_op = &configfs_dir_inode_operations;
+		inode->i_fop = &configfs_dir_operations;
+		/* directory inodes start off with i_nlink == 2 (for "." entry) */
+		inode->i_nlink++;
+	} else {
+		pr_debug("configfs: could not get root inode\n");
+		return -ENOMEM;
+	}
+
+	root = d_alloc_root(inode);
+	if (!root) {
+		pr_debug("%s: could not get root dentry!\n",__FUNCTION__);
+		iput(inode);
+		return -ENOMEM;
+	}
+	config_group_init(&configfs_root_group);
+	configfs_root_group.cg_item.ci_dentry = root;
+	root->d_fsdata = &configfs_root;
+	sb->s_root = root;
+	return 0;
+}
+
+static struct super_block *configfs_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, configfs_fill_super);
+}
+
+static struct file_system_type configfs_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "configfs",
+	.get_sb		= configfs_get_sb,
+	.kill_sb	= kill_litter_super,
+};
+
+int configfs_pin_fs(void)
+{
+	return simple_pin_fs("configfs", &configfs_mount,
+			     &configfs_mnt_count);
+}
+
+void configfs_release_fs(void)
+{
+	simple_release_fs(&configfs_mount, &configfs_mnt_count);
+}
+
+
+static decl_subsys(config, NULL, NULL);
+
+static int __init configfs_init(void)
+{
+	int err;
+
+	kset_set_kset_s(&config_subsys, kernel_subsys);
+	err = subsystem_register(&config_subsys);
+	if (err)
+		return err;
+
+	err = register_filesystem(&configfs_fs_type);
+	if (err) {
+		printk(KERN_ERR "configfs: Unable to register filesystem!\n");
+		subsystem_unregister(&config_subsys);
+	}
+
+	return err;
+}
+
+static void __exit configfs_exit(void)
+{
+	unregister_filesystem(&configfs_fs_type);
+	subsystem_unregister(&config_subsys);
+}
+
+MODULE_AUTHOR("Oracle");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.0.1");
+MODULE_DESCRIPTION("Simple RAM filesystem for user driven kernel subsystem configuration.");
+
+module_init(configfs_init);
+module_exit(configfs_exit);
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
new file mode 100644
index 0000000..50f5840
--- /dev/null
+++ b/fs/configfs/symlink.c
@@ -0,0 +1,281 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * symlink.c - operations for configfs symlinks.
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ */
+
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/namei.h>
+
+#include <linux/configfs.h>
+#include "configfs_internal.h"
+
+static int item_depth(struct config_item * item)
+{
+	struct config_item * p = item;
+	int depth = 0;
+	do { depth++; } while ((p = p->ci_parent) && !configfs_is_root(p));
+	return depth;
+}
+
+static int item_path_length(struct config_item * item)
+{
+	struct config_item * p = item;
+	int length = 1;
+	do {
+		length += strlen(config_item_name(p)) + 1;
+		p = p->ci_parent;
+	} while (p && !configfs_is_root(p));
+	return length;
+}
+
+static void fill_item_path(struct config_item * item, char * buffer, int length)
+{
+	struct config_item * p;
+
+	--length;
+	for (p = item; p && !configfs_is_root(p); p = p->ci_parent) {
+		int cur = strlen(config_item_name(p));
+
+		/* back up enough to print this bus id with '/' */
+		length -= cur;
+		strncpy(buffer + length,config_item_name(p),cur);
+		*(buffer + --length) = '/';
+	}
+}
+
+static int create_link(struct config_item *parent_item,
+ 		       struct config_item *item,
+		       struct dentry *dentry)
+{
+	struct configfs_dirent *target_sd = item->ci_dentry->d_fsdata;
+	struct configfs_symlink *sl;
+	int ret;
+
+	ret = -ENOMEM;
+	sl = kmalloc(sizeof(struct configfs_symlink), GFP_KERNEL);
+	if (sl) {
+		sl->sl_target = config_item_get(item);
+		/* FIXME: needs a lock, I'd bet */
+		list_add(&sl->sl_list, &target_sd->s_links);
+		ret = configfs_create_link(sl, parent_item->ci_dentry,
+					   dentry);
+		if (ret) {
+			list_del_init(&sl->sl_list);
+			config_item_put(item);
+			kfree(sl);
+		}
+	}
+
+	return ret;
+}
+
+
+static int get_target(const char *symname, struct nameidata *nd,
+		      struct config_item **target)
+{
+	int ret;
+
+	ret = path_lookup(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, nd);
+	if (!ret) {
+		if (nd->dentry->d_sb == configfs_sb) {
+			*target = configfs_get_config_item(nd->dentry);
+			if (!*target) {
+				ret = -ENOENT;
+				path_release(nd);
+			}
+		} else
+			ret = -EPERM;
+	}
+
+	return ret;
+}
+
+
+int configfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+	int ret;
+	struct nameidata nd;
+	struct config_item *parent_item;
+	struct config_item *target_item;
+	struct config_item_type *type;
+
+	ret = -EPERM;  /* What lack-of-symlink returns */
+	if (dentry->d_parent == configfs_sb->s_root)
+		goto out;
+
+	parent_item = configfs_get_config_item(dentry->d_parent);
+	type = parent_item->ci_type;
+
+	if (!type || !type->ct_item_ops ||
+	    !type->ct_item_ops->allow_link)
+		goto out_put;
+
+	ret = get_target(symname, &nd, &target_item);
+	if (ret)
+		goto out_put;
+
+	ret = type->ct_item_ops->allow_link(parent_item, target_item);
+	if (!ret)
+		ret = create_link(parent_item, target_item, dentry);
+
+	config_item_put(target_item);
+	path_release(&nd);
+
+out_put:
+	config_item_put(parent_item);
+
+out:
+	return ret;
+}
+
+int configfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+	struct configfs_dirent *sd = dentry->d_fsdata;
+	struct configfs_symlink *sl;
+	struct config_item *parent_item;
+	struct config_item_type *type;
+	int ret;
+
+	ret = -EPERM;  /* What lack-of-symlink returns */
+	if (!(sd->s_type & CONFIGFS_ITEM_LINK))
+		goto out;
+
+	if (dentry->d_parent == configfs_sb->s_root)
+		BUG();
+
+	sl = sd->s_element;
+
+	parent_item = configfs_get_config_item(dentry->d_parent);
+	type = parent_item->ci_type;
+
+	list_del_init(&sd->s_sibling);
+	configfs_drop_dentry(sd, dentry->d_parent);
+	dput(dentry);
+	configfs_put(sd);
+
+	/*
+	 * drop_link() must be called before
+	 * list_del_init(&sl->sl_list), so that the order of
+	 * drop_link(this, target) and drop_item(target) is preserved.
+	 */
+	if (type && type->ct_item_ops &&
+	    type->ct_item_ops->drop_link)
+		type->ct_item_ops->drop_link(parent_item,
+					       sl->sl_target);
+
+	/* FIXME: Needs lock */
+	list_del_init(&sl->sl_list);
+
+	/* Put reference from create_link() */
+	config_item_put(sl->sl_target);
+	kfree(sl);
+
+	config_item_put(parent_item);
+
+	ret = 0;
+
+out:
+	return ret;
+}
+
+static int configfs_get_target_path(struct config_item * item, struct config_item * target,
+				   char *path)
+{
+	char * s;
+	int depth, size;
+
+	depth = item_depth(item);
+	size = item_path_length(target) + depth * 3 - 1;
+	if (size > PATH_MAX)
+		return -ENAMETOOLONG;
+
+	pr_debug("%s: depth = %d, size = %d\n", __FUNCTION__, depth, size);
+
+	for (s = path; depth--; s += 3)
+		strcpy(s,"../");
+
+	fill_item_path(target, path, size);
+	pr_debug("%s: path = '%s'\n", __FUNCTION__, path);
+
+	return 0;
+}
+
+static int configfs_getlink(struct dentry *dentry, char * path)
+{
+	struct config_item *item, *target_item;
+	int error = 0;
+
+	item = configfs_get_config_item(dentry->d_parent);
+	if (!item)
+		return -EINVAL;
+
+	target_item = configfs_get_config_item(dentry);
+	if (!target_item) {
+		config_item_put(item);
+		return -EINVAL;
+	}
+
+	down_read(&configfs_rename_sem);
+	error = configfs_get_target_path(item, target_item, path);
+	up_read(&configfs_rename_sem);
+
+	config_item_put(item);
+	config_item_put(target_item);
+	return error;
+
+}
+
+static void *configfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	int error = -ENOMEM;
+	unsigned long page = get_zeroed_page(GFP_KERNEL);
+
+	if (page) {
+		error = configfs_getlink(dentry, (char *)page);
+		if (!error) {
+			nd_set_link(nd, (char *)page);
+			return (void *)page;
+		}
+	}
+
+	nd_set_link(nd, ERR_PTR(error));
+	return NULL;
+}
+
+static void configfs_put_link(struct dentry *dentry, struct nameidata *nd,
+			      void *cookie)
+{
+	if (cookie) {
+		unsigned long page = (unsigned long)cookie;
+		free_page(page);
+	}
+}
+
+struct inode_operations configfs_symlink_inode_operations = {
+	.follow_link = configfs_follow_link,
+	.readlink = generic_readlink,
+	.put_link = configfs_put_link,
+};
+
diff --git a/fs/dcache.c b/fs/dcache.c
index 17e43913..1536f15 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -71,7 +71,7 @@
 
 static void d_callback(struct rcu_head *head)
 {
-	struct dentry * dentry = container_of(head, struct dentry, d_rcu);
+	struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu);
 
 	if (dname_external(dentry))
 		kfree(dentry->d_name.name);
@@ -86,7 +86,7 @@
 {
 	if (dentry->d_op && dentry->d_op->d_release)
 		dentry->d_op->d_release(dentry);
- 	call_rcu(&dentry->d_rcu, d_callback);
+ 	call_rcu(&dentry->d_u.d_rcu, d_callback);
 }
 
 /*
@@ -193,7 +193,7 @@
   			list_del(&dentry->d_lru);
   			dentry_stat.nr_unused--;
   		}
-  		list_del(&dentry->d_child);
+  		list_del(&dentry->d_u.d_child);
 		dentry_stat.nr_dentry--;	/* For d_free, below */
 		/*drops the locks, at that point nobody can reach this dentry */
 		dentry_iput(dentry);
@@ -367,7 +367,7 @@
 	struct dentry * parent;
 
 	__d_drop(dentry);
-	list_del(&dentry->d_child);
+	list_del(&dentry->d_u.d_child);
 	dentry_stat.nr_dentry--;	/* For d_free, below */
 	dentry_iput(dentry);
 	parent = dentry->d_parent;
@@ -518,7 +518,7 @@
 resume:
 	while (next != &this_parent->d_subdirs) {
 		struct list_head *tmp = next;
-		struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+		struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
 		next = tmp->next;
 		/* Have we found a mount point ? */
 		if (d_mountpoint(dentry))
@@ -532,7 +532,7 @@
 	 * All done at this level ... ascend and resume the search.
 	 */
 	if (this_parent != parent) {
-		next = this_parent->d_child.next; 
+		next = this_parent->d_u.d_child.next;
 		this_parent = this_parent->d_parent;
 		goto resume;
 	}
@@ -569,7 +569,7 @@
 resume:
 	while (next != &this_parent->d_subdirs) {
 		struct list_head *tmp = next;
-		struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+		struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
 		next = tmp->next;
 
 		if (!list_empty(&dentry->d_lru)) {
@@ -610,7 +610,7 @@
 	 * All done at this level ... ascend and resume the search.
 	 */
 	if (this_parent != parent) {
-		next = this_parent->d_child.next; 
+		next = this_parent->d_u.d_child.next;
 		this_parent = this_parent->d_parent;
 #ifdef DCACHE_DEBUG
 printk(KERN_DEBUG "select_parent: ascending to %s/%s, found=%d\n",
@@ -753,12 +753,12 @@
 		dentry->d_parent = dget(parent);
 		dentry->d_sb = parent->d_sb;
 	} else {
-		INIT_LIST_HEAD(&dentry->d_child);
+		INIT_LIST_HEAD(&dentry->d_u.d_child);
 	}
 
 	spin_lock(&dcache_lock);
 	if (parent)
-		list_add(&dentry->d_child, &parent->d_subdirs);
+		list_add(&dentry->d_u.d_child, &parent->d_subdirs);
 	dentry_stat.nr_dentry++;
 	spin_unlock(&dcache_lock);
 
@@ -1310,8 +1310,8 @@
 	/* Unhash the target: dput() will then get rid of it */
 	__d_drop(target);
 
-	list_del(&dentry->d_child);
-	list_del(&target->d_child);
+	list_del(&dentry->d_u.d_child);
+	list_del(&target->d_u.d_child);
 
 	/* Switch the names.. */
 	switch_names(dentry, target);
@@ -1322,15 +1322,15 @@
 	if (IS_ROOT(dentry)) {
 		dentry->d_parent = target->d_parent;
 		target->d_parent = target;
-		INIT_LIST_HEAD(&target->d_child);
+		INIT_LIST_HEAD(&target->d_u.d_child);
 	} else {
 		do_switch(dentry->d_parent, target->d_parent);
 
 		/* And add them back to the (new) parent lists */
-		list_add(&target->d_child, &target->d_parent->d_subdirs);
+		list_add(&target->d_u.d_child, &target->d_parent->d_subdirs);
 	}
 
-	list_add(&dentry->d_child, &dentry->d_parent->d_subdirs);
+	list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
 	spin_unlock(&target->d_lock);
 	spin_unlock(&dentry->d_lock);
 	write_sequnlock(&rename_lock);
@@ -1568,7 +1568,7 @@
 resume:
 	while (next != &this_parent->d_subdirs) {
 		struct list_head *tmp = next;
-		struct dentry *dentry = list_entry(tmp, struct dentry, d_child);
+		struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child);
 		next = tmp->next;
 		if (d_unhashed(dentry)||!dentry->d_inode)
 			continue;
@@ -1579,7 +1579,7 @@
 		atomic_dec(&dentry->d_count);
 	}
 	if (this_parent != root) {
-		next = this_parent->d_child.next; 
+		next = this_parent->d_u.d_child.next;
 		atomic_dec(&this_parent->d_count);
 		this_parent = this_parent->d_parent;
 		goto resume;
diff --git a/fs/dquot.c b/fs/dquot.c
index 05b6028..2a62b3d 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1513,10 +1513,16 @@
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
+	if (!dentry->d_inode) {
+		error = -ENOENT;
+		goto out;
+	}
+
 	error = security_quota_on(dentry);
 	if (!error)
 		error = vfs_quota_on_inode(dentry->d_inode, type, format_id);
 
+out:
 	dput(dentry);
 	return error;
 }
diff --git a/fs/drop_caches.c b/fs/drop_caches.c
new file mode 100644
index 0000000..4e47623
--- /dev/null
+++ b/fs/drop_caches.c
@@ -0,0 +1,68 @@
+/*
+ * Implement the manual drop-all-pagecache function
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/writeback.h>
+#include <linux/sysctl.h>
+#include <linux/gfp.h>
+
+/* A global variable is a bit ugly, but it keeps the code simple */
+int sysctl_drop_caches;
+
+static void drop_pagecache_sb(struct super_block *sb)
+{
+	struct inode *inode;
+
+	spin_lock(&inode_lock);
+	list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
+		if (inode->i_state & (I_FREEING|I_WILL_FREE))
+			continue;
+		invalidate_inode_pages(inode->i_mapping);
+	}
+	spin_unlock(&inode_lock);
+}
+
+void drop_pagecache(void)
+{
+	struct super_block *sb;
+
+	spin_lock(&sb_lock);
+restart:
+	list_for_each_entry(sb, &super_blocks, s_list) {
+		sb->s_count++;
+		spin_unlock(&sb_lock);
+		down_read(&sb->s_umount);
+		if (sb->s_root)
+			drop_pagecache_sb(sb);
+		up_read(&sb->s_umount);
+		spin_lock(&sb_lock);
+		if (__put_super_and_need_restart(sb))
+			goto restart;
+	}
+	spin_unlock(&sb_lock);
+}
+
+void drop_slab(void)
+{
+	int nr_objects;
+
+	do {
+		nr_objects = shrink_slab(1000, GFP_KERNEL, 1000);
+	} while (nr_objects > 10);
+}
+
+int drop_caches_sysctl_handler(ctl_table *table, int write,
+	struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
+{
+	proc_dointvec_minmax(table, write, file, buffer, length, ppos);
+	if (write) {
+		if (sysctl_drop_caches & 1)
+			drop_pagecache();
+		if (sysctl_drop_caches & 2)
+			drop_slab();
+	}
+	return 0;
+}
diff --git a/fs/exec.c b/fs/exec.c
index 1f8a9fd..fd02ea4a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -306,9 +306,6 @@
 			struct page *page, unsigned long address)
 {
 	struct mm_struct *mm = vma->vm_mm;
-	pgd_t * pgd;
-	pud_t * pud;
-	pmd_t * pmd;
 	pte_t * pte;
 	spinlock_t *ptl;
 
@@ -316,14 +313,7 @@
 		goto out;
 
 	flush_dcache_page(page);
-	pgd = pgd_offset(mm, address);
-	pud = pud_alloc(mm, pgd, address);
-	if (!pud)
-		goto out;
-	pmd = pmd_alloc(mm, pud, address);
-	if (!pmd)
-		goto out;
-	pte = pte_alloc_map_lock(mm, pmd, address, &ptl);
+	pte = get_locked_pte(mm, address, &ptl);
 	if (!pte)
 		goto out;
 	if (!pte_none(*pte)) {
@@ -334,7 +324,7 @@
 	lru_cache_add_active(page);
 	set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
 					page, vma->vm_page_prot))));
-	page_add_anon_rmap(page, vma, address);
+	page_add_new_anon_rmap(page, vma, address);
 	pte_unmap_unlock(pte, ptl);
 
 	/* no need for flush_tlb */
@@ -770,7 +760,7 @@
 		spin_lock(&oldsighand->siglock);
 		spin_lock(&newsighand->siglock);
 
-		current->sighand = newsighand;
+		rcu_assign_pointer(current->sighand, newsighand);
 		recalc_sigpending();
 
 		spin_unlock(&newsighand->siglock);
@@ -778,7 +768,7 @@
 		write_unlock_irq(&tasklist_lock);
 
 		if (atomic_dec_and_test(&oldsighand->count))
-			kmem_cache_free(sighand_cachep, oldsighand);
+			sighand_free(oldsighand);
 	}
 
 	BUG_ON(!thread_group_leader(current));
@@ -1472,6 +1462,7 @@
 	if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
 		current->signal->flags = SIGNAL_GROUP_EXIT;
 		current->signal->group_exit_code = exit_code;
+		current->signal->group_stop_count = 0;
 		retval = 0;
 	}
 	spin_unlock_irq(&current->sighand->siglock);
@@ -1487,7 +1478,6 @@
 	 * Clear any false indication of pending signals that might
 	 * be seen by the filesystem code called to write the core file.
 	 */
-	current->signal->group_stop_count = 0;
 	clear_thread_flag(TIF_SIGPENDING);
 
 	if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
@@ -1515,7 +1505,7 @@
 		goto close_fail;
 	if (!file->f_op->write)
 		goto close_fail;
-	if (do_truncate(file->f_dentry, 0, file) != 0)
+	if (do_truncate(file->f_dentry, 0, 0, file) != 0)
 		goto close_fail;
 
 	retval = binfmt->core_dump(signr, regs, file);
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 9e4a243..6907807 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -651,7 +651,7 @@
 	/* Error cases - e2fsck has already cleaned up for us */
 	if (ino > max_ino) {
 		ext3_warning(sb, __FUNCTION__,
-			     "bad orphan ino %lu!  e2fsck was run?\n", ino);
+			     "bad orphan ino %lu!  e2fsck was run?", ino);
 		goto out;
 	}
 
@@ -660,7 +660,7 @@
 	bitmap_bh = read_inode_bitmap(sb, block_group);
 	if (!bitmap_bh) {
 		ext3_warning(sb, __FUNCTION__,
-			     "inode bitmap error for orphan %lu\n", ino);
+			     "inode bitmap error for orphan %lu", ino);
 		goto out;
 	}
 
@@ -672,7 +672,7 @@
 			!(inode = iget(sb, ino)) || is_bad_inode(inode) ||
 			NEXT_ORPHAN(inode) > max_ino) {
 		ext3_warning(sb, __FUNCTION__,
-			     "bad orphan inode %lu!  e2fsck was run?\n", ino);
+			     "bad orphan inode %lu!  e2fsck was run?", ino);
 		printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
 		       bit, (unsigned long long)bitmap_bh->b_blocknr,
 		       ext3_test_bit(bit, bitmap_bh->b_data));
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index b3c690a..af193a3 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1476,7 +1476,7 @@
 		if (levels && (dx_get_count(frames->entries) ==
 			       dx_get_limit(frames->entries))) {
 			ext3_warning(sb, __FUNCTION__,
-				     "Directory index full!\n");
+				     "Directory index full!");
 			err = -ENOSPC;
 			goto cleanup;
 		}
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 1be78b4b..1041dab 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -31,7 +31,7 @@
 	unsigned start = le32_to_cpu(es->s_blocks_count);
 	unsigned end = start + input->blocks_count;
 	unsigned group = input->group;
-	unsigned itend = input->inode_table + EXT3_SB(sb)->s_itb_per_group;
+	unsigned itend = input->inode_table + sbi->s_itb_per_group;
 	unsigned overhead = ext3_bg_has_super(sb, group) ?
 		(1 + ext3_bg_num_gdb(sb, group) +
 		 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
@@ -340,7 +340,7 @@
 	while ((grp = ext3_list_backups(sb, &three, &five, &seven)) < end) {
 		if (le32_to_cpu(*p++) != grp * EXT3_BLOCKS_PER_GROUP(sb) + blk){
 			ext3_warning(sb, __FUNCTION__,
-				     "reserved GDT %ld missing grp %d (%ld)\n",
+				     "reserved GDT %ld missing grp %d (%ld)",
 				     blk, grp,
 				     grp * EXT3_BLOCKS_PER_GROUP(sb) + blk);
 			return -EINVAL;
@@ -393,7 +393,7 @@
 	if (EXT3_SB(sb)->s_sbh->b_blocknr !=
 	    le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block)) {
 		ext3_warning(sb, __FUNCTION__,
-			"won't resize using backup superblock at %llu\n",
+			"won't resize using backup superblock at %llu",
 			(unsigned long long)EXT3_SB(sb)->s_sbh->b_blocknr);
 		return -EPERM;
 	}
@@ -417,7 +417,7 @@
 	data = (__u32 *)dind->b_data;
 	if (le32_to_cpu(data[gdb_num % EXT3_ADDR_PER_BLOCK(sb)]) != gdblock) {
 		ext3_warning(sb, __FUNCTION__,
-			     "new group %u GDT block %lu not reserved\n",
+			     "new group %u GDT block %lu not reserved",
 			     input->group, gdblock);
 		err = -EINVAL;
 		goto exit_dind;
@@ -540,7 +540,7 @@
 	for (res = 0; res < reserved_gdb; res++, blk++) {
 		if (le32_to_cpu(*data) != blk) {
 			ext3_warning(sb, __FUNCTION__,
-				     "reserved block %lu not at offset %ld\n",
+				     "reserved block %lu not at offset %ld",
 				     blk, (long)(data - (__u32 *)dind->b_data));
 			err = -EINVAL;
 			goto exit_bh;
@@ -683,7 +683,7 @@
 	if (err) {
 		ext3_warning(sb, __FUNCTION__,
 			     "can't update backup for group %d (err %d), "
-			     "forcing fsck on next reboot\n", group, err);
+			     "forcing fsck on next reboot", group, err);
 		sbi->s_mount_state &= ~EXT3_VALID_FS;
 		sbi->s_es->s_state &= ~cpu_to_le16(EXT3_VALID_FS);
 		mark_buffer_dirty(sbi->s_sbh);
@@ -722,7 +722,7 @@
 	if (gdb_off == 0 && !EXT3_HAS_RO_COMPAT_FEATURE(sb,
 					EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
 		ext3_warning(sb, __FUNCTION__,
-			     "Can't resize non-sparse filesystem further\n");
+			     "Can't resize non-sparse filesystem further");
 		return -EPERM;
 	}
 
@@ -730,13 +730,13 @@
 		if (!EXT3_HAS_COMPAT_FEATURE(sb,
 					     EXT3_FEATURE_COMPAT_RESIZE_INODE)){
 			ext3_warning(sb, __FUNCTION__,
-				     "No reserved GDT blocks, can't resize\n");
+				     "No reserved GDT blocks, can't resize");
 			return -EPERM;
 		}
 		inode = iget(sb, EXT3_RESIZE_INO);
 		if (!inode || is_bad_inode(inode)) {
 			ext3_warning(sb, __FUNCTION__,
-				     "Error opening resize inode\n");
+				     "Error opening resize inode");
 			iput(inode);
 			return -ENOENT;
 		}
@@ -764,9 +764,10 @@
 	}
 
 	lock_super(sb);
-	if (input->group != EXT3_SB(sb)->s_groups_count) {
+	if (input->group != sbi->s_groups_count) {
 		ext3_warning(sb, __FUNCTION__,
-			     "multiple resizers run on filesystem!\n");
+			     "multiple resizers run on filesystem!");
+		err = -EBUSY;
 		goto exit_journal;
 	}
 
@@ -798,7 +799,7 @@
 	 * data.  So we need to be careful to set all of the relevant
 	 * group descriptor data etc. *before* we enable the group.
 	 *
-	 * The key field here is EXT3_SB(sb)->s_groups_count: as long as
+	 * The key field here is sbi->s_groups_count: as long as
 	 * that retains its old value, nobody is going to access the new
 	 * group.
 	 *
@@ -858,7 +859,7 @@
 	smp_wmb();
 
 	/* Update the global fs size fields */
-	EXT3_SB(sb)->s_groups_count++;
+	sbi->s_groups_count++;
 
 	ext3_journal_dirty_metadata(handle, primary);
 
@@ -873,7 +874,7 @@
 	percpu_counter_mod(&sbi->s_freeinodes_counter,
 			   EXT3_INODES_PER_GROUP(sb));
 
-	ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
+	ext3_journal_dirty_metadata(handle, sbi->s_sbh);
 	sb->s_dirt = 1;
 
 exit_journal:
@@ -936,7 +937,7 @@
 
 	if (last == 0) {
 		ext3_warning(sb, __FUNCTION__,
-			     "need to use ext2online to resize further\n");
+			     "need to use ext2online to resize further");
 		return -EPERM;
 	}
 
@@ -972,7 +973,7 @@
 	lock_super(sb);
 	if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) {
 		ext3_warning(sb, __FUNCTION__,
-			     "multiple resizers run on filesystem!\n");
+			     "multiple resizers run on filesystem!");
 		err = -EBUSY;
 		goto exit_put;
 	}
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 4e67306..7c45acf 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -43,7 +43,8 @@
 #include "acl.h"
 #include "namei.h"
 
-static int ext3_load_journal(struct super_block *, struct ext3_super_block *);
+static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
+			     unsigned long journal_devnum);
 static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
 			       int);
 static void ext3_commit_super (struct super_block * sb,
@@ -628,7 +629,7 @@
 	Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
 	Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
 	Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh,
-	Opt_commit, Opt_journal_update, Opt_journal_inum,
+	Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
 	Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
 	Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
 	Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
@@ -666,6 +667,7 @@
 	{Opt_commit, "commit=%u"},
 	{Opt_journal_update, "journal=update"},
 	{Opt_journal_inum, "journal=%u"},
+	{Opt_journal_dev, "journal_dev=%u"},
 	{Opt_abort, "abort"},
 	{Opt_data_journal, "data=journal"},
 	{Opt_data_ordered, "data=ordered"},
@@ -705,8 +707,9 @@
 	return sb_block;
 }
 
-static int parse_options (char * options, struct super_block *sb,
-			  unsigned long * inum, unsigned long *n_blocks_count, int is_remount)
+static int parse_options (char *options, struct super_block *sb,
+			  unsigned long *inum, unsigned long *journal_devnum,
+			  unsigned long *n_blocks_count, int is_remount)
 {
 	struct ext3_sb_info *sbi = EXT3_SB(sb);
 	char * p;
@@ -839,6 +842,16 @@
 				return 0;
 			*inum = option;
 			break;
+		case Opt_journal_dev:
+			if (is_remount) {
+				printk(KERN_ERR "EXT3-fs: cannot specify "
+				       "journal on remount\n");
+				return 0;
+			}
+			if (match_int(&args[0], &option))
+				return 0;
+			*journal_devnum = option;
+			break;
 		case Opt_noload:
 			set_opt (sbi->s_mount_opt, NOLOAD);
 			break;
@@ -1331,6 +1344,7 @@
 	unsigned long logic_sb_block;
 	unsigned long offset = 0;
 	unsigned long journal_inum = 0;
+	unsigned long journal_devnum = 0;
 	unsigned long def_mount_opts;
 	struct inode *root;
 	int blocksize;
@@ -1411,7 +1425,8 @@
 
 	set_opt(sbi->s_mount_opt, RESERVATION);
 
-	if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0))
+	if (!parse_options ((char *) data, sb, &journal_inum, &journal_devnum,
+			    NULL, 0))
 		goto failed_mount;
 
 	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
@@ -1622,7 +1637,7 @@
 	 */
 	if (!test_opt(sb, NOLOAD) &&
 	    EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
-		if (ext3_load_journal(sb, es))
+		if (ext3_load_journal(sb, es, journal_devnum))
 			goto failed_mount2;
 	} else if (journal_inum) {
 		if (ext3_create_journal(sb, es, journal_inum))
@@ -1902,15 +1917,24 @@
 	return NULL;
 }
 
-static int ext3_load_journal(struct super_block * sb,
-			     struct ext3_super_block * es)
+static int ext3_load_journal(struct super_block *sb,
+			     struct ext3_super_block *es,
+			     unsigned long journal_devnum)
 {
 	journal_t *journal;
 	int journal_inum = le32_to_cpu(es->s_journal_inum);
-	dev_t journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+	dev_t journal_dev;
 	int err = 0;
 	int really_read_only;
 
+	if (journal_devnum &&
+	    journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+		printk(KERN_INFO "EXT3-fs: external journal device major/minor "
+			"numbers have changed\n");
+		journal_dev = new_decode_dev(journal_devnum);
+	} else
+		journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+
 	really_read_only = bdev_read_only(sb->s_bdev);
 
 	/*
@@ -1969,6 +1993,16 @@
 
 	EXT3_SB(sb)->s_journal = journal;
 	ext3_clear_journal_err(sb, es);
+
+	if (journal_devnum &&
+	    journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+		es->s_journal_dev = cpu_to_le32(journal_devnum);
+		sb->s_dirt = 1;
+
+		/* Make sure we flush the recovery flag to disk. */
+		ext3_commit_super(sb, es, 1);
+	}
+
 	return 0;
 }
 
@@ -2197,7 +2231,7 @@
 	/*
 	 * Allow the "check" option to be passed as a remount option.
 	 */
-	if (!parse_options(data, sb, NULL, &n_blocks_count, 1)) {
+	if (!parse_options(data, sb, NULL, NULL, &n_blocks_count, 1)) {
 		err = -EINVAL;
 		goto restore_opts;
 	}
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 77c24fc..1acc941 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -295,7 +295,8 @@
 	return dclus;
 }
 
-int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
+int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
+	     unsigned long *mapped_blocks)
 {
 	struct super_block *sb = inode->i_sb;
 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -303,9 +304,12 @@
 	int cluster, offset;
 
 	*phys = 0;
+	*mapped_blocks = 0;
 	if ((sbi->fat_bits != 32) && (inode->i_ino == MSDOS_ROOT_INO)) {
-		if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits))
+		if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits)) {
 			*phys = sector + sbi->dir_start;
+			*mapped_blocks = 1;
+		}
 		return 0;
 	}
 	last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1))
@@ -318,7 +322,11 @@
 	cluster = fat_bmap_cluster(inode, cluster);
 	if (cluster < 0)
 		return cluster;
-	else if (cluster)
+	else if (cluster) {
 		*phys = fat_clus_to_blknr(sbi, cluster) + offset;
+		*mapped_blocks = sbi->sec_per_clus - offset;
+		if (*mapped_blocks > last_block - sector)
+			*mapped_blocks = last_block - sector;
+	}
 	return 0;
 }
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index ba82496..eef1b81 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -45,8 +45,8 @@
 	if ((sbi->fat_bits != 32) && (dir->i_ino == MSDOS_ROOT_INO))
 		return;
 
-	bh = sb_getblk(sb, phys);
-	if (bh && !buffer_uptodate(bh)) {
+	bh = sb_find_get_block(sb, phys);
+	if (bh == NULL || !buffer_uptodate(bh)) {
 		for (sec = 0; sec < sbi->sec_per_clus; sec++)
 			sb_breadahead(sb, phys + sec);
 	}
@@ -68,8 +68,8 @@
 {
 	struct super_block *sb = dir->i_sb;
 	sector_t phys, iblock;
-	int offset;
-	int err;
+	unsigned long mapped_blocks;
+	int err, offset;
 
 next:
 	if (*bh)
@@ -77,7 +77,7 @@
 
 	*bh = NULL;
 	iblock = *pos >> sb->s_blocksize_bits;
-	err = fat_bmap(dir, iblock, &phys);
+	err = fat_bmap(dir, iblock, &phys, &mapped_blocks);
 	if (err || !phys)
 		return -1;	/* beyond EOF or error */
 
@@ -418,7 +418,7 @@
 	return err;
 }
 
-EXPORT_SYMBOL(fat_search_long);
+EXPORT_SYMBOL_GPL(fat_search_long);
 
 struct fat_ioctl_filldir_callback {
 	struct dirent __user *dirent;
@@ -780,7 +780,7 @@
 	return -ENOENT;
 }
 
-EXPORT_SYMBOL(fat_get_dotdot_entry);
+EXPORT_SYMBOL_GPL(fat_get_dotdot_entry);
 
 /* See if directory is empty */
 int fat_dir_empty(struct inode *dir)
@@ -803,7 +803,7 @@
 	return result;
 }
 
-EXPORT_SYMBOL(fat_dir_empty);
+EXPORT_SYMBOL_GPL(fat_dir_empty);
 
 /*
  * fat_subdirs counts the number of sub-directories of dir. It can be run
@@ -849,7 +849,7 @@
 	return -ENOENT;
 }
 
-EXPORT_SYMBOL(fat_scan);
+EXPORT_SYMBOL_GPL(fat_scan);
 
 static int __fat_remove_entries(struct inode *dir, loff_t pos, int nr_slots)
 {
@@ -936,7 +936,7 @@
 	return 0;
 }
 
-EXPORT_SYMBOL(fat_remove_entries);
+EXPORT_SYMBOL_GPL(fat_remove_entries);
 
 static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
 			      struct buffer_head **bhs, int nr_bhs)
@@ -1048,7 +1048,7 @@
 	return err;
 }
 
-EXPORT_SYMBOL(fat_alloc_new_dir);
+EXPORT_SYMBOL_GPL(fat_alloc_new_dir);
 
 static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
 			       int *nr_cluster, struct msdos_dir_entry **de,
@@ -1264,4 +1264,4 @@
 	return err;
 }
 
-EXPORT_SYMBOL(fat_add_entries);
+EXPORT_SYMBOL_GPL(fat_add_entries);
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
index 4164cd5..a1a9e04 100644
--- a/fs/fat/fatent.c
+++ b/fs/fat/fatent.c
@@ -476,6 +476,7 @@
 				sbi->prev_free = entry;
 				if (sbi->free_clusters != -1)
 					sbi->free_clusters--;
+				sb->s_dirt = 1;
 
 				cluster[idx_clus] = entry;
 				idx_clus++;
@@ -496,6 +497,7 @@
 
 	/* Couldn't allocate the free entries */
 	sbi->free_clusters = 0;
+	sb->s_dirt = 1;
 	err = -ENOSPC;
 
 out:
@@ -509,7 +511,6 @@
 	}
 	for (i = 0; i < nr_bhs; i++)
 		brelse(bhs[i]);
-	fat_clusters_flush(sb);
 
 	if (err && idx_clus)
 		fat_free_clusters(inode, cluster[0]);
@@ -542,8 +543,10 @@
 		}
 
 		ops->ent_put(&fatent, FAT_ENT_FREE);
-		if (sbi->free_clusters != -1)
+		if (sbi->free_clusters != -1) {
 			sbi->free_clusters++;
+			sb->s_dirt = 1;
+		}
 
 		if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) {
 			if (sb->s_flags & MS_SYNCHRONOUS) {
@@ -578,7 +581,7 @@
 	return err;
 }
 
-EXPORT_SYMBOL(fat_free_clusters);
+EXPORT_SYMBOL_GPL(fat_free_clusters);
 
 int fat_count_free_clusters(struct super_block *sb)
 {
@@ -605,6 +608,7 @@
 		} while (fat_ent_next(sbi, &fatent));
 	}
 	sbi->free_clusters = free;
+	sb->s_dirt = 1;
 	fatent_brelse(&fatent);
 out:
 	unlock_fat(sbi);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 7134403..9b07c32 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -11,6 +11,7 @@
 #include <linux/msdos_fs.h>
 #include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
+#include <linux/writeback.h>
 
 int fat_generic_ioctl(struct inode *inode, struct file *filp,
 		      unsigned int cmd, unsigned long arg)
@@ -124,6 +125,24 @@
 	.sendfile	= generic_file_sendfile,
 };
 
+static int fat_cont_expand(struct inode *inode, loff_t size)
+{
+	struct address_space *mapping = inode->i_mapping;
+	loff_t start = inode->i_size, count = size - inode->i_size;
+	int err;
+
+	err = generic_cont_expand_simple(inode, size);
+	if (err)
+		goto out;
+
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
+	mark_inode_dirty(inode);
+	if (IS_SYNC(inode))
+		err = sync_page_range_nolock(inode, mapping, start, count);
+out:
+	return err;
+}
+
 int fat_notify_change(struct dentry *dentry, struct iattr *attr)
 {
 	struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
@@ -132,11 +151,17 @@
 
 	lock_kernel();
 
-	/* FAT cannot truncate to a longer file */
+	/*
+	 * Expand the file. Since inode_setattr() updates ->i_size
+	 * before calling the ->truncate(), but FAT needs to fill the
+	 * hole before it.
+	 */
 	if (attr->ia_valid & ATTR_SIZE) {
 		if (attr->ia_size > inode->i_size) {
-			error = -EPERM;
-			goto out;
+			error = fat_cont_expand(inode, attr->ia_size);
+			if (error || attr->ia_valid == ATTR_SIZE)
+				goto out;
+			attr->ia_valid &= ~ATTR_SIZE;
 		}
 	}
 
@@ -173,7 +198,7 @@
 	return error;
 }
 
-EXPORT_SYMBOL(fat_notify_change);
+EXPORT_SYMBOL_GPL(fat_notify_change);
 
 /* Free all clusters after the skip'th cluster. */
 static int fat_free(struct inode *inode, int skip)
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index a0f9b9f..e7f4aa7 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -18,10 +18,12 @@
 #include <linux/seq_file.h>
 #include <linux/msdos_fs.h>
 #include <linux/pagemap.h>
+#include <linux/mpage.h>
 #include <linux/buffer_head.h>
 #include <linux/mount.h>
 #include <linux/vfs.h>
 #include <linux/parser.h>
+#include <linux/uio.h>
 #include <asm/unaligned.h>
 
 #ifndef CONFIG_FAT_DEFAULT_IOCHARSET
@@ -48,51 +50,97 @@
 	return err;
 }
 
-static int fat_get_block(struct inode *inode, sector_t iblock,
-			 struct buffer_head *bh_result, int create)
+static int __fat_get_blocks(struct inode *inode, sector_t iblock,
+			    unsigned long *max_blocks,
+			    struct buffer_head *bh_result, int create)
 {
 	struct super_block *sb = inode->i_sb;
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	sector_t phys;
-	int err;
+	unsigned long mapped_blocks;
+	int err, offset;
 
-	err = fat_bmap(inode, iblock, &phys);
+	err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
 	if (err)
 		return err;
 	if (phys) {
 		map_bh(bh_result, sb, phys);
+		*max_blocks = min(mapped_blocks, *max_blocks);
 		return 0;
 	}
 	if (!create)
 		return 0;
+
 	if (iblock != MSDOS_I(inode)->mmu_private >> sb->s_blocksize_bits) {
 		fat_fs_panic(sb, "corrupted file size (i_pos %lld, %lld)",
 			     MSDOS_I(inode)->i_pos, MSDOS_I(inode)->mmu_private);
 		return -EIO;
 	}
-	if (!((unsigned long)iblock & (MSDOS_SB(sb)->sec_per_clus - 1))) {
+
+	offset = (unsigned long)iblock & (sbi->sec_per_clus - 1);
+	if (!offset) {
+		/* TODO: multiple cluster allocation would be desirable. */
 		err = fat_add_cluster(inode);
 		if (err)
 			return err;
 	}
-	MSDOS_I(inode)->mmu_private += sb->s_blocksize;
-	err = fat_bmap(inode, iblock, &phys);
+	/* available blocks on this cluster */
+	mapped_blocks = sbi->sec_per_clus - offset;
+
+	*max_blocks = min(mapped_blocks, *max_blocks);
+	MSDOS_I(inode)->mmu_private += *max_blocks << sb->s_blocksize_bits;
+
+	err = fat_bmap(inode, iblock, &phys, &mapped_blocks);
 	if (err)
 		return err;
-	if (!phys)
-		BUG();
+	BUG_ON(!phys);
+	BUG_ON(*max_blocks != mapped_blocks);
 	set_buffer_new(bh_result);
 	map_bh(bh_result, sb, phys);
 	return 0;
 }
 
+static int fat_get_blocks(struct inode *inode, sector_t iblock,
+			  unsigned long max_blocks,
+			  struct buffer_head *bh_result, int create)
+{
+	struct super_block *sb = inode->i_sb;
+	int err;
+
+	err = __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create);
+	if (err)
+		return err;
+	bh_result->b_size = max_blocks << sb->s_blocksize_bits;
+	return 0;
+}
+
+static int fat_get_block(struct inode *inode, sector_t iblock,
+			 struct buffer_head *bh_result, int create)
+{
+	unsigned long max_blocks = 1;
+	return __fat_get_blocks(inode, iblock, &max_blocks, bh_result, create);
+}
+
 static int fat_writepage(struct page *page, struct writeback_control *wbc)
 {
 	return block_write_full_page(page, fat_get_block, wbc);
 }
 
+static int fat_writepages(struct address_space *mapping,
+			  struct writeback_control *wbc)
+{
+	return mpage_writepages(mapping, wbc, fat_get_block);
+}
+
 static int fat_readpage(struct file *file, struct page *page)
 {
-	return block_read_full_page(page, fat_get_block);
+	return mpage_readpage(page, fat_get_block);
+}
+
+static int fat_readpages(struct file *file, struct address_space *mapping,
+			 struct list_head *pages, unsigned nr_pages)
+{
+	return mpage_readpages(mapping, pages, nr_pages, fat_get_block);
 }
 
 static int fat_prepare_write(struct file *file, struct page *page,
@@ -115,6 +163,34 @@
 	return err;
 }
 
+static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
+			     const struct iovec *iov,
+			     loff_t offset, unsigned long nr_segs)
+{
+	struct file *file = iocb->ki_filp;
+	struct inode *inode = file->f_mapping->host;
+
+	if (rw == WRITE) {
+		/*
+		 * FIXME: blockdev_direct_IO() doesn't use ->prepare_write(),
+		 * so we need to update the ->mmu_private to block boundary.
+		 *
+		 * But we must fill the remaining area or hole by nul for
+		 * updating ->mmu_private.
+		 */
+		loff_t size = offset + iov_length(iov, nr_segs);
+		if (MSDOS_I(inode)->mmu_private < size)
+			return -EINVAL;
+	}
+
+	/*
+	 * FAT need to use the DIO_LOCKING for avoiding the race
+	 * condition of fat_get_block() and ->truncate().
+	 */
+	return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+				  offset, nr_segs, fat_get_blocks, NULL);
+}
+
 static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
 {
 	return generic_block_bmap(mapping, block, fat_get_block);
@@ -122,10 +198,13 @@
 
 static struct address_space_operations fat_aops = {
 	.readpage	= fat_readpage,
+	.readpages	= fat_readpages,
 	.writepage	= fat_writepage,
+	.writepages	= fat_writepages,
 	.sync_page	= block_sync_page,
 	.prepare_write	= fat_prepare_write,
 	.commit_write	= fat_commit_write,
+	.direct_IO	= fat_direct_IO,
 	.bmap		= _fat_bmap
 };
 
@@ -182,7 +261,7 @@
 	spin_unlock(&sbi->inode_hash_lock);
 }
 
-EXPORT_SYMBOL(fat_attach);
+EXPORT_SYMBOL_GPL(fat_attach);
 
 void fat_detach(struct inode *inode)
 {
@@ -193,7 +272,7 @@
 	spin_unlock(&sbi->inode_hash_lock);
 }
 
-EXPORT_SYMBOL(fat_detach);
+EXPORT_SYMBOL_GPL(fat_detach);
 
 struct inode *fat_iget(struct super_block *sb, loff_t i_pos)
 {
@@ -347,7 +426,7 @@
 	return inode;
 }
 
-EXPORT_SYMBOL(fat_build_inode);
+EXPORT_SYMBOL_GPL(fat_build_inode);
 
 static void fat_delete_inode(struct inode *inode)
 {
@@ -374,12 +453,17 @@
 	unlock_kernel();
 }
 
-static void fat_put_super(struct super_block *sb)
+static void fat_write_super(struct super_block *sb)
 {
-	struct msdos_sb_info *sbi = MSDOS_SB(sb);
+	sb->s_dirt = 0;
 
 	if (!(sb->s_flags & MS_RDONLY))
 		fat_clusters_flush(sb);
+}
+
+static void fat_put_super(struct super_block *sb)
+{
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 
 	if (sbi->nls_disk) {
 		unload_nls(sbi->nls_disk);
@@ -537,7 +621,7 @@
 	return fat_write_inode(inode, 1);
 }
 
-EXPORT_SYMBOL(fat_sync_inode);
+EXPORT_SYMBOL_GPL(fat_sync_inode);
 
 static int fat_show_options(struct seq_file *m, struct vfsmount *mnt);
 static struct super_operations fat_sops = {
@@ -546,6 +630,7 @@
 	.write_inode	= fat_write_inode,
 	.delete_inode	= fat_delete_inode,
 	.put_super	= fat_put_super,
+	.write_super	= fat_write_super,
 	.statfs		= fat_statfs,
 	.clear_inode	= fat_clear_inode,
 	.remount_fs	= fat_remount,
@@ -1347,7 +1432,7 @@
 	return error;
 }
 
-EXPORT_SYMBOL(fat_fill_super);
+EXPORT_SYMBOL_GPL(fat_fill_super);
 
 int __init fat_cache_init(void);
 void fat_cache_destroy(void);
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 2a0df21..32fb0a3 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -33,7 +33,7 @@
 	}
 }
 
-EXPORT_SYMBOL(fat_fs_panic);
+EXPORT_SYMBOL_GPL(fat_fs_panic);
 
 /* Flushes the number of free clusters on FAT32 */
 /* XXX: Need to write one per FSINFO block.  Currently only writes 1 */
@@ -67,8 +67,6 @@
 		if (sbi->prev_free != -1)
 			fsinfo->next_cluster = cpu_to_le32(sbi->prev_free);
 		mark_buffer_dirty(bh);
-		if (sb->s_flags & MS_SYNCHRONOUS)
-			sync_dirty_buffer(bh);
 	}
 	brelse(bh);
 }
@@ -194,7 +192,7 @@
 	*date = cpu_to_le16(nl_day-day_n[month-1]+1+(month << 5)+(year << 9));
 }
 
-EXPORT_SYMBOL(fat_date_unix2dos);
+EXPORT_SYMBOL_GPL(fat_date_unix2dos);
 
 int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs)
 {
@@ -222,4 +220,4 @@
 	return err;
 }
 
-EXPORT_SYMBOL(fat_sync_bhs);
+EXPORT_SYMBOL_GPL(fat_sync_bhs);
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 863b46e..9903bde 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -457,11 +457,11 @@
 			else
 				si.si_band = band_table[reason - POLL_IN];
 			si.si_fd    = fd;
-			if (!send_group_sig_info(fown->signum, &si, p))
+			if (!group_send_sig_info(fown->signum, &si, p))
 				break;
 		/* fall-through: fall back on the old plain SIGIO signal */
 		case 0:
-			send_group_sig_info(SIGIO, SEND_SIG_PRIV, p);
+			group_send_sig_info(SIGIO, SEND_SIG_PRIV, p);
 	}
 }
 
@@ -495,7 +495,7 @@
                                 struct fown_struct *fown)
 {
 	if (sigio_perm(p, fown, SIGURG))
-		send_group_sig_info(SIGURG, SEND_SIG_PRIV, p);
+		group_send_sig_info(SIGURG, SEND_SIG_PRIV, p);
 }
 
 int send_sigurg(struct fown_struct *fown)
diff --git a/fs/file_table.c b/fs/file_table.c
index c3a5e2f..6142250 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -117,7 +117,7 @@
 
 void fastcall fput(struct file *file)
 {
-	if (rcuref_dec_and_test(&file->f_count))
+	if (atomic_dec_and_test(&file->f_count))
 		__fput(file);
 }
 
@@ -166,7 +166,7 @@
 	rcu_read_lock();
 	file = fcheck_files(files, fd);
 	if (file) {
-		if (!rcuref_inc_lf(&file->f_count)) {
+		if (!atomic_inc_not_zero(&file->f_count)) {
 			/* File object ref couldn't be taken */
 			rcu_read_unlock();
 			return NULL;
@@ -198,7 +198,7 @@
 		rcu_read_lock();
 		file = fcheck_files(files, fd);
 		if (file) {
-			if (rcuref_inc_lf(&file->f_count))
+			if (atomic_inc_not_zero(&file->f_count))
 				*fput_needed = 1;
 			else
 				/* Didn't get the reference, someone's freed */
@@ -213,7 +213,7 @@
 
 void put_filp(struct file *file)
 {
-	if (rcuref_dec_and_test(&file->f_count)) {
+	if (atomic_dec_and_test(&file->f_count)) {
 		security_file_free(file);
 		file_kill(file);
 		file_free(file);
diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c
index d0401dc6..6f5df17 100644
--- a/fs/freevxfs/vxfs_immed.c
+++ b/fs/freevxfs/vxfs_immed.c
@@ -99,8 +99,8 @@
 vxfs_immed_readpage(struct file *fp, struct page *pp)
 {
 	struct vxfs_inode_info	*vip = VXFS_INO(pp->mapping->host);
-	u_int64_t		offset = pp->index << PAGE_CACHE_SHIFT;
-	caddr_t			kaddr;
+	u_int64_t	offset = (u_int64_t)pp->index << PAGE_CACHE_SHIFT;
+	caddr_t		kaddr;
 
 	kaddr = kmap(pp);
 	memcpy(kaddr, vip->vii_immed.vi_immed + offset, PAGE_CACHE_SIZE);
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 8f873e62..e08ab47 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -148,6 +148,26 @@
 	spin_unlock(&fuse_lock);
 }
 
+static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
+{
+	int i;
+	struct fuse_init_out *arg = &req->misc.init_out;
+
+	if (arg->major != FUSE_KERNEL_VERSION)
+		fc->conn_error = 1;
+	else {
+		fc->minor = arg->minor;
+		fc->max_write = arg->minor < 5 ? 4096 : arg->max_write;
+	}
+
+	/* After INIT reply is received other requests can go
+	   out.  So do (FUSE_MAX_OUTSTANDING - 1) number of
+	   up()s on outstanding_sem.  The last up() is done in
+	   fuse_putback_request() */
+	for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
+		up(&fc->outstanding_sem);
+}
+
 /*
  * This function is called when a request is finished.  Either a reply
  * has arrived or it was interrupted (and not yet sent) or some error
@@ -172,19 +192,9 @@
 		up_read(&fc->sbput_sem);
 	}
 	wake_up(&req->waitq);
-	if (req->in.h.opcode == FUSE_INIT) {
-		int i;
-
-		if (req->misc.init_in_out.major != FUSE_KERNEL_VERSION)
-			fc->conn_error = 1;
-
-		/* After INIT reply is received other requests can go
-		   out.  So do (FUSE_MAX_OUTSTANDING - 1) number of
-		   up()s on outstanding_sem.  The last up() is done in
-		   fuse_putback_request() */
-		for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
-			up(&fc->outstanding_sem);
-	} else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
+	if (req->in.h.opcode == FUSE_INIT)
+		process_init_reply(fc, req);
+	else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
 		/* Special case for failed iget in CREATE */
 		u64 nodeid = req->in.h.nodeid;
 		__fuse_get_request(req);
@@ -357,7 +367,7 @@
 	/* This is called from fuse_read_super() so there's guaranteed
 	   to be a request available */
 	struct fuse_req *req = do_get_request(fc);
-	struct fuse_init_in_out *arg = &req->misc.init_in_out;
+	struct fuse_init_in *arg = &req->misc.init_in;
 	arg->major = FUSE_KERNEL_VERSION;
 	arg->minor = FUSE_KERNEL_MINOR_VERSION;
 	req->in.h.opcode = FUSE_INIT;
@@ -365,8 +375,12 @@
 	req->in.args[0].size = sizeof(*arg);
 	req->in.args[0].value = arg;
 	req->out.numargs = 1;
-	req->out.args[0].size = sizeof(*arg);
-	req->out.args[0].value = arg;
+	/* Variable length arguement used for backward compatibility
+	   with interface version < 7.5.  Rest of init_out is zeroed
+	   by do_get_request(), so a short reply is not a problem */
+	req->out.argvar = 1;
+	req->out.args[0].size = sizeof(struct fuse_init_out);
+	req->out.args[0].value = &req->misc.init_out;
 	request_send_background(fc, req);
 }
 
@@ -615,6 +629,7 @@
 	struct fuse_copy_state cs;
 	unsigned reqsize;
 
+ restart:
 	spin_lock(&fuse_lock);
 	fc = file->private_data;
 	err = -EPERM;
@@ -630,20 +645,25 @@
 
 	req = list_entry(fc->pending.next, struct fuse_req, list);
 	list_del_init(&req->list);
-	spin_unlock(&fuse_lock);
 
 	in = &req->in;
-	reqsize = req->in.h.len;
-	fuse_copy_init(&cs, 1, req, iov, nr_segs);
-	err = -EINVAL;
-	if (iov_length(iov, nr_segs) >= reqsize) {
-		err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
-		if (!err)
-			err = fuse_copy_args(&cs, in->numargs, in->argpages,
-					     (struct fuse_arg *) in->args, 0);
+	reqsize = in->h.len;
+	/* If request is too large, reply with an error and restart the read */
+	if (iov_length(iov, nr_segs) < reqsize) {
+		req->out.h.error = -EIO;
+		/* SETXATTR is special, since it may contain too large data */
+		if (in->h.opcode == FUSE_SETXATTR)
+			req->out.h.error = -E2BIG;
+		request_end(fc, req);
+		goto restart;
 	}
+	spin_unlock(&fuse_lock);
+	fuse_copy_init(&cs, 1, req, iov, nr_segs);
+	err = fuse_copy_one(&cs, &in->h, sizeof(in->h));
+	if (!err)
+		err = fuse_copy_args(&cs, in->numargs, in->argpages,
+				     (struct fuse_arg *) in->args, 0);
 	fuse_copy_finish(&cs);
-
 	spin_lock(&fuse_lock);
 	req->locked = 0;
 	if (!err && req->interrupted)
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index c045cc7..417bcee 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -13,8 +13,16 @@
 #include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/namei.h>
-#include <linux/mount.h>
 
+/*
+ * FUSE caches dentries and attributes with separate timeout.  The
+ * time in jiffies until the dentry/attributes are valid is stored in
+ * dentry->d_time and fuse_inode->i_time respectively.
+ */
+
+/*
+ * Calculate the time in jiffies until a dentry/attributes are valid
+ */
 static inline unsigned long time_to_jiffies(unsigned long sec,
 					    unsigned long nsec)
 {
@@ -22,6 +30,50 @@
 	return jiffies + timespec_to_jiffies(&ts);
 }
 
+/*
+ * Set dentry and possibly attribute timeouts from the lookup/mk*
+ * replies
+ */
+static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
+{
+	entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec);
+	if (entry->d_inode)
+		get_fuse_inode(entry->d_inode)->i_time =
+			time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+}
+
+/*
+ * Mark the attributes as stale, so that at the next call to
+ * ->getattr() they will be fetched from userspace
+ */
+void fuse_invalidate_attr(struct inode *inode)
+{
+	get_fuse_inode(inode)->i_time = jiffies - 1;
+}
+
+/*
+ * Just mark the entry as stale, so that a next attempt to look it up
+ * will result in a new lookup call to userspace
+ *
+ * This is called when a dentry is about to become negative and the
+ * timeout is unknown (unlink, rmdir, rename and in some cases
+ * lookup)
+ */
+static void fuse_invalidate_entry_cache(struct dentry *entry)
+{
+	entry->d_time = jiffies - 1;
+}
+
+/*
+ * Same as fuse_invalidate_entry_cache(), but also try to remove the
+ * dentry from the hash
+ */
+static void fuse_invalidate_entry(struct dentry *entry)
+{
+	d_invalidate(entry);
+	fuse_invalidate_entry_cache(entry);
+}
+
 static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
 			     struct dentry *entry,
 			     struct fuse_entry_out *outarg)
@@ -37,17 +89,34 @@
 	req->out.args[0].value = outarg;
 }
 
+/*
+ * Check whether the dentry is still valid
+ *
+ * If the entry validity timeout has expired and the dentry is
+ * positive, try to redo the lookup.  If the lookup results in a
+ * different inode, then let the VFS invalidate the dentry and redo
+ * the lookup once more.  If the lookup results in the same inode,
+ * then refresh the attributes, timeouts and mark the dentry valid.
+ */
 static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
 {
-	if (!entry->d_inode || is_bad_inode(entry->d_inode))
+	struct inode *inode = entry->d_inode;
+
+	if (inode && is_bad_inode(inode))
 		return 0;
 	else if (time_after(jiffies, entry->d_time)) {
 		int err;
 		struct fuse_entry_out outarg;
-		struct inode *inode = entry->d_inode;
-		struct fuse_inode *fi = get_fuse_inode(inode);
-		struct fuse_conn *fc = get_fuse_conn(inode);
-		struct fuse_req *req = fuse_get_request(fc);
+		struct fuse_conn *fc;
+		struct fuse_req *req;
+
+		/* Doesn't hurt to "reset" the validity timeout */
+		fuse_invalidate_entry_cache(entry);
+		if (!inode)
+			return 0;
+
+		fc = get_fuse_conn(inode);
+		req = fuse_get_request(fc);
 		if (!req)
 			return 0;
 
@@ -55,6 +124,7 @@
 		request_send(fc, req);
 		err = req->out.h.error;
 		if (!err) {
+			struct fuse_inode *fi = get_fuse_inode(inode);
 			if (outarg.nodeid != get_node_id(inode)) {
 				fuse_send_forget(fc, req, outarg.nodeid, 1);
 				return 0;
@@ -66,20 +136,44 @@
 			return 0;
 
 		fuse_change_attributes(inode, &outarg.attr);
-		entry->d_time = time_to_jiffies(outarg.entry_valid,
-						outarg.entry_valid_nsec);
-		fi->i_time = time_to_jiffies(outarg.attr_valid,
-					     outarg.attr_valid_nsec);
+		fuse_change_timeout(entry, &outarg);
 	}
 	return 1;
 }
 
+/*
+ * Check if there's already a hashed alias of this directory inode.
+ * If yes, then lookup and mkdir must not create a new alias.
+ */
+static int dir_alias(struct inode *inode)
+{
+	if (S_ISDIR(inode->i_mode)) {
+		struct dentry *alias = d_find_alias(inode);
+		if (alias) {
+			dput(alias);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static inline int invalid_nodeid(u64 nodeid)
+{
+	return !nodeid || nodeid == FUSE_ROOT_ID;
+}
+
 static struct dentry_operations fuse_dentry_operations = {
 	.d_revalidate	= fuse_dentry_revalidate,
 };
 
-static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
-			    struct inode **inodep)
+static inline int valid_mode(int m)
+{
+	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
+		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
+}
+
+static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
+				  struct nameidata *nd)
 {
 	int err;
 	struct fuse_entry_out outarg;
@@ -88,53 +182,49 @@
 	struct fuse_req *req;
 
 	if (entry->d_name.len > FUSE_NAME_MAX)
-		return -ENAMETOOLONG;
+		return ERR_PTR(-ENAMETOOLONG);
 
 	req = fuse_get_request(fc);
 	if (!req)
-		return -EINTR;
+		return ERR_PTR(-EINTR);
 
 	fuse_lookup_init(req, dir, entry, &outarg);
 	request_send(fc, req);
 	err = req->out.h.error;
-	if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID))
+	if (!err && ((outarg.nodeid && invalid_nodeid(outarg.nodeid)) ||
+		     !valid_mode(outarg.attr.mode)))
 		err = -EIO;
-	if (!err) {
+	if (!err && outarg.nodeid) {
 		inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
 				  &outarg.attr);
 		if (!inode) {
 			fuse_send_forget(fc, req, outarg.nodeid, 1);
-			return -ENOMEM;
+			return ERR_PTR(-ENOMEM);
 		}
 	}
 	fuse_put_request(fc, req);
 	if (err && err != -ENOENT)
-		return err;
+		return ERR_PTR(err);
 
-	if (inode) {
-		struct fuse_inode *fi = get_fuse_inode(inode);
-		entry->d_time =	time_to_jiffies(outarg.entry_valid,
-						outarg.entry_valid_nsec);
-		fi->i_time = time_to_jiffies(outarg.attr_valid,
-					     outarg.attr_valid_nsec);
+	if (inode && dir_alias(inode)) {
+		iput(inode);
+		return ERR_PTR(-EIO);
 	}
-
+	d_add(entry, inode);
 	entry->d_op = &fuse_dentry_operations;
-	*inodep = inode;
-	return 0;
+	if (!err)
+		fuse_change_timeout(entry, &outarg);
+	else
+		fuse_invalidate_entry_cache(entry);
+	return NULL;
 }
 
-void fuse_invalidate_attr(struct inode *inode)
-{
-	get_fuse_inode(inode)->i_time = jiffies - 1;
-}
-
-static void fuse_invalidate_entry(struct dentry *entry)
-{
-	d_invalidate(entry);
-	entry->d_time = jiffies - 1;
-}
-
+/*
+ * Atomic create+open operation
+ *
+ * If the filesystem doesn't support this, then fall back to separate
+ * 'mknod' + 'open' requests.
+ */
 static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
 			    struct nameidata *nd)
 {
@@ -145,7 +235,6 @@
 	struct fuse_open_in inarg;
 	struct fuse_open_out outopen;
 	struct fuse_entry_out outentry;
-	struct fuse_inode *fi;
 	struct fuse_file *ff;
 	struct file *file;
 	int flags = nd->intent.open.flags - 1;
@@ -154,10 +243,6 @@
 	if (fc->no_create)
 		goto out;
 
-	err = -ENAMETOOLONG;
-	if (entry->d_name.len > FUSE_NAME_MAX)
-		goto out;
-
 	err = -EINTR;
 	req = fuse_get_request(fc);
 	if (!req)
@@ -193,7 +278,7 @@
 	}
 
 	err = -EIO;
-	if (!S_ISREG(outentry.attr.mode))
+	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
 		goto out_free_ff;
 
 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
@@ -202,17 +287,15 @@
 	if (!inode) {
 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
 		ff->fh = outopen.fh;
+		/* Special release, with inode = NULL, this will
+		   trigger a 'forget' request when the release is
+		   complete */
 		fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
 		goto out_put_request;
 	}
 	fuse_put_request(fc, req);
-	entry->d_time =	time_to_jiffies(outentry.entry_valid,
-					outentry.entry_valid_nsec);
-	fi = get_fuse_inode(inode);
-	fi->i_time = time_to_jiffies(outentry.attr_valid,
-				     outentry.attr_valid_nsec);
-
 	d_instantiate(entry, inode);
+	fuse_change_timeout(entry, &outentry);
 	file = lookup_instantiate_filp(nd, entry, generic_file_open);
 	if (IS_ERR(file)) {
 		ff->fh = outopen.fh;
@@ -230,13 +313,15 @@
 	return err;
 }
 
+/*
+ * Code shared between mknod, mkdir, symlink and link
+ */
 static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
 			    struct inode *dir, struct dentry *entry,
 			    int mode)
 {
 	struct fuse_entry_out outarg;
 	struct inode *inode;
-	struct fuse_inode *fi;
 	int err;
 
 	req->in.h.nodeid = get_node_id(dir);
@@ -250,10 +335,13 @@
 		fuse_put_request(fc, req);
 		return err;
 	}
-	if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) {
-		fuse_put_request(fc, req);
-		return -EIO;
-	}
+	err = -EIO;
+	if (invalid_nodeid(outarg.nodeid))
+		goto out_put_request;
+
+	if ((outarg.attr.mode ^ mode) & S_IFMT)
+		goto out_put_request;
+
 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
 			  &outarg.attr);
 	if (!inode) {
@@ -262,22 +350,19 @@
 	}
 	fuse_put_request(fc, req);
 
-	/* Don't allow userspace to do really stupid things... */
-	if ((inode->i_mode ^ mode) & S_IFMT) {
+	if (dir_alias(inode)) {
 		iput(inode);
 		return -EIO;
 	}
 
-	entry->d_time = time_to_jiffies(outarg.entry_valid,
-					outarg.entry_valid_nsec);
-
-	fi = get_fuse_inode(inode);
-	fi->i_time = time_to_jiffies(outarg.attr_valid,
-				     outarg.attr_valid_nsec);
-
 	d_instantiate(entry, inode);
+	fuse_change_timeout(entry, &outarg);
 	fuse_invalidate_attr(dir);
 	return 0;
+
+ out_put_request:
+	fuse_put_request(fc, req);
+	return err;
 }
 
 static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
@@ -337,12 +422,7 @@
 {
 	struct fuse_conn *fc = get_fuse_conn(dir);
 	unsigned len = strlen(link) + 1;
-	struct fuse_req *req;
-
-	if (len > FUSE_SYMLINK_MAX)
-		return -ENAMETOOLONG;
-
-	req = fuse_get_request(fc);
+	struct fuse_req *req = fuse_get_request(fc);
 	if (!req)
 		return -EINTR;
 
@@ -381,6 +461,7 @@
 		inode->i_nlink = 0;
 		fuse_invalidate_attr(inode);
 		fuse_invalidate_attr(dir);
+		fuse_invalidate_entry_cache(entry);
 	} else if (err == -EINTR)
 		fuse_invalidate_entry(entry);
 	return err;
@@ -406,6 +487,7 @@
 	if (!err) {
 		entry->d_inode->i_nlink = 0;
 		fuse_invalidate_attr(dir);
+		fuse_invalidate_entry_cache(entry);
 	} else if (err == -EINTR)
 		fuse_invalidate_entry(entry);
 	return err;
@@ -441,6 +523,10 @@
 		fuse_invalidate_attr(olddir);
 		if (olddir != newdir)
 			fuse_invalidate_attr(newdir);
+
+		/* newent will end up negative */
+		if (newent->d_inode)
+			fuse_invalidate_entry_cache(newent);
 	} else if (err == -EINTR) {
 		/* If request was interrupted, DEITY only knows if the
 		   rename actually took place.  If the invalidation
@@ -548,6 +634,15 @@
 	return 0;
 }
 
+/*
+ * Check whether the inode attributes are still valid
+ *
+ * If the attribute validity timeout has expired, then fetch the fresh
+ * attributes with a 'getattr' request
+ *
+ * I'm not sure why cached attributes are never returned for the root
+ * inode, this is probably being too cautious.
+ */
 static int fuse_revalidate(struct dentry *entry)
 {
 	struct inode *inode = entry->d_inode;
@@ -595,6 +690,19 @@
 	return err;
 }
 
+/*
+ * Check permission.  The two basic access models of FUSE are:
+ *
+ * 1) Local access checking ('default_permissions' mount option) based
+ * on file mode.  This is the plain old disk filesystem permission
+ * modell.
+ *
+ * 2) "Remote" access checking, where server is responsible for
+ * checking permission in each inode operation.  An exception to this
+ * is if ->permission() was invoked from sys_access() in which case an
+ * access request is sent.  Execute permission is still checked
+ * locally based on file mode.
+ */
 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
 	struct fuse_conn *fc = get_fuse_conn(inode);
@@ -613,14 +721,10 @@
 				err = generic_permission(inode, mask, NULL);
 		}
 
-		/* FIXME: Need some mechanism to revoke permissions:
-		   currently if the filesystem suddenly changes the
-		   file mode, we will not be informed about it, and
-		   continue to allow access to the file/directory.
-
-		   This is actually not so grave, since the user can
-		   simply keep access to the file/directory anyway by
-		   keeping it open... */
+		/* Note: the opposite of the above test does not
+		   exist.  So if permissions are revoked this won't be
+		   noticed immediately, only after the attribute
+		   timeout has expired */
 
 		return err;
 	} else {
@@ -673,7 +777,12 @@
 	struct page *page;
 	struct inode *inode = file->f_dentry->d_inode;
 	struct fuse_conn *fc = get_fuse_conn(inode);
-	struct fuse_req *req = fuse_get_request(fc);
+	struct fuse_req *req;
+
+	if (is_bad_inode(inode))
+		return -EIO;
+
+	req = fuse_get_request(fc);
 	if (!req)
 		return -EINTR;
 
@@ -788,6 +897,15 @@
 	}
 }
 
+/*
+ * Set attributes, and at the same time refresh them.
+ *
+ * Truncation is slightly complicated, because the 'truncate' request
+ * may fail, in which case we don't want to touch the mapping.
+ * vmtruncate() doesn't allow for this case.  So do the rlimit
+ * checking by hand and call vmtruncate() only after the file has
+ * actually been truncated.
+ */
 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
 {
 	struct inode *inode = entry->d_inode;
@@ -865,28 +983,6 @@
 	return err;
 }
 
-static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
-				  struct nameidata *nd)
-{
-	struct inode *inode;
-	int err;
-
-	err = fuse_lookup_iget(dir, entry, &inode);
-	if (err)
-		return ERR_PTR(err);
-	if (inode && S_ISDIR(inode->i_mode)) {
-		/* Don't allow creating an alias to a directory  */
-		struct dentry *alias = d_find_alias(inode);
-		if (alias) {
-			dput(alias);
-			iput(inode);
-			return ERR_PTR(-EIO);
-		}
-	}
-	d_add(entry, inode);
-	return NULL;
-}
-
 static int fuse_setxattr(struct dentry *entry, const char *name,
 			 const void *value, size_t size, int flags)
 {
@@ -896,9 +992,6 @@
 	struct fuse_setxattr_in inarg;
 	int err;
 
-	if (size > FUSE_XATTR_SIZE_MAX)
-		return -E2BIG;
-
 	if (fc->no_setxattr)
 		return -EOPNOTSUPP;
 
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 2ca8614..05deddd 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -163,6 +163,9 @@
 	struct fuse_flush_in inarg;
 	int err;
 
+	if (is_bad_inode(inode))
+		return -EIO;
+
 	if (fc->no_flush)
 		return 0;
 
@@ -199,6 +202,9 @@
 	struct fuse_fsync_in inarg;
 	int err;
 
+	if (is_bad_inode(inode))
+		return -EIO;
+
 	if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
 		return 0;
 
@@ -272,16 +278,22 @@
 {
 	struct inode *inode = page->mapping->host;
 	struct fuse_conn *fc = get_fuse_conn(inode);
-	loff_t pos = (loff_t) page->index << PAGE_CACHE_SHIFT;
-	struct fuse_req *req = fuse_get_request(fc);
-	int err = -EINTR;
+	struct fuse_req *req;
+	int err;
+
+	err = -EIO;
+	if (is_bad_inode(inode))
+		goto out;
+
+	err = -EINTR;
+	req = fuse_get_request(fc);
 	if (!req)
 		goto out;
 
 	req->out.page_zeroing = 1;
 	req->num_pages = 1;
 	req->pages[0] = page;
-	fuse_send_read(req, file, inode, pos, PAGE_CACHE_SIZE);
+	fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE);
 	err = req->out.h.error;
 	fuse_put_request(fc, req);
 	if (!err)
@@ -295,7 +307,7 @@
 static int fuse_send_readpages(struct fuse_req *req, struct file *file,
 			       struct inode *inode)
 {
-	loff_t pos = (loff_t) req->pages[0]->index << PAGE_CACHE_SHIFT;
+	loff_t pos = page_offset(req->pages[0]);
 	size_t count = req->num_pages << PAGE_CACHE_SHIFT;
 	unsigned i;
 	req->out.page_zeroing = 1;
@@ -345,6 +357,10 @@
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	struct fuse_readpages_data data;
 	int err;
+
+	if (is_bad_inode(inode))
+		return -EIO;
+
 	data.file = file;
 	data.inode = inode;
 	data.req = fuse_get_request(fc);
@@ -402,8 +418,13 @@
 	unsigned count = to - offset;
 	struct inode *inode = page->mapping->host;
 	struct fuse_conn *fc = get_fuse_conn(inode);
-	loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + offset;
-	struct fuse_req *req = fuse_get_request(fc);
+	loff_t pos = page_offset(page) + offset;
+	struct fuse_req *req;
+
+	if (is_bad_inode(inode))
+		return -EIO;
+
+	req = fuse_get_request(fc);
 	if (!req)
 		return -EINTR;
 
@@ -454,7 +475,7 @@
 
 	nbytes = min(nbytes, (unsigned) FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT);
 	npages = (nbytes + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	npages = min(npages, FUSE_MAX_PAGES_PER_REQ);
+	npages = min(max(npages, 1), FUSE_MAX_PAGES_PER_REQ);
 	down_read(&current->mm->mmap_sem);
 	npages = get_user_pages(current, current->mm, user_addr, npages, write,
 				0, req->pages, NULL);
@@ -475,12 +496,16 @@
 	size_t nmax = write ? fc->max_write : fc->max_read;
 	loff_t pos = *ppos;
 	ssize_t res = 0;
-	struct fuse_req *req = fuse_get_request(fc);
+	struct fuse_req *req;
+
+	if (is_bad_inode(inode))
+		return -EIO;
+
+	req = fuse_get_request(fc);
 	if (!req)
 		return -EINTR;
 
 	while (count) {
-		size_t tmp;
 		size_t nres;
 		size_t nbytes = min(count, nmax);
 		int err = fuse_get_user_pages(req, buf, nbytes, !write);
@@ -488,8 +513,8 @@
 			res = err;
 			break;
 		}
-		tmp = (req->num_pages << PAGE_SHIFT) - req->page_offset;
-		nbytes = min(nbytes, tmp);
+		nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset;
+		nbytes = min(count, nbytes);
 		if (write)
 			nres = fuse_send_write(req, file, inode, pos, nbytes);
 		else
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 0ea5301..74c8d09 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -21,6 +21,9 @@
 /** If more requests are outstanding, then the operation will block */
 #define FUSE_MAX_OUTSTANDING 10
 
+/** It could be as large as PATH_MAX, but would that have any uses? */
+#define FUSE_NAME_MAX 1024
+
 /** If the FUSE_DEFAULT_PERMISSIONS flag is given, the filesystem
     module will check permissions based on the file mode.  Otherwise no
     permission checking is done in the kernel */
@@ -108,9 +111,6 @@
 	struct fuse_arg args[3];
 };
 
-struct fuse_req;
-struct fuse_conn;
-
 /**
  * A request to the client
  */
@@ -159,7 +159,8 @@
 	union {
 		struct fuse_forget_in forget_in;
 		struct fuse_release_in release_in;
-		struct fuse_init_in_out init_in_out;
+		struct fuse_init_in init_in;
+		struct fuse_init_out init_out;
 	} misc;
 
 	/** page vector */
@@ -272,6 +273,9 @@
 	/** Is create not implemented by fs? */
 	unsigned no_create : 1;
 
+	/** Negotiated minor version */
+	unsigned minor;
+
 	/** Backing dev info */
 	struct backing_dev_info bdi;
 };
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index e69a546..04c80cc 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -135,12 +135,8 @@
 		fuse_init_common(inode);
 		init_special_inode(inode, inode->i_mode,
 				   new_decode_dev(attr->rdev));
-	} else {
-		/* Don't let user create weird files */
-		inode->i_mode = S_IFREG;
-		fuse_init_common(inode);
-		fuse_init_file_inode(inode);
-	}
+	} else
+		BUG();
 }
 
 static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
@@ -218,6 +214,7 @@
 {
 	stbuf->f_type    = FUSE_SUPER_MAGIC;
 	stbuf->f_bsize   = attr->bsize;
+	stbuf->f_frsize  = attr->frsize;
 	stbuf->f_blocks  = attr->blocks;
 	stbuf->f_bfree   = attr->bfree;
 	stbuf->f_bavail  = attr->bavail;
@@ -238,10 +235,12 @@
 	if (!req)
 		return -EINTR;
 
+	memset(&outarg, 0, sizeof(outarg));
 	req->in.numargs = 0;
 	req->in.h.opcode = FUSE_STATFS;
 	req->out.numargs = 1;
-	req->out.args[0].size = sizeof(outarg);
+	req->out.args[0].size =
+		fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg);
 	req->out.args[0].value = &outarg;
 	request_send(fc, req);
 	err = req->out.h.error;
@@ -482,7 +481,6 @@
 	fc->max_read = d.max_read;
 	if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages)
 		fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE;
-	fc->max_write = FUSE_MAX_IN / 2;
 
 	err = -ENOMEM;
 	root = get_root_inode(sb, d.rootmode);
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index c60e563..df16fcb 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -151,6 +151,7 @@
 
 #define HFSPLUS_SB_WRITEBACKUP	0x0001
 #define HFSPLUS_SB_NODECOMPOSE	0x0002
+#define HFSPLUS_SB_FORCE	0x0004
 
 
 struct hfsplus_inode_info {
diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h
index 5bad37c..b4fbed6 100644
--- a/fs/hfsplus/hfsplus_raw.h
+++ b/fs/hfsplus/hfsplus_raw.h
@@ -123,11 +123,13 @@
 } __packed;
 
 /* HFS+ volume attributes */
-#define HFSPLUS_VOL_UNMNT     (1 << 8)
-#define HFSPLUS_VOL_SPARE_BLK (1 << 9)
-#define HFSPLUS_VOL_NOCACHE   (1 << 10)
-#define HFSPLUS_VOL_INCNSTNT  (1 << 11)
-#define HFSPLUS_VOL_SOFTLOCK  (1 << 15)
+#define HFSPLUS_VOL_UNMNT		(1 << 8)
+#define HFSPLUS_VOL_SPARE_BLK		(1 << 9)
+#define HFSPLUS_VOL_NOCACHE		(1 << 10)
+#define HFSPLUS_VOL_INCNSTNT		(1 << 11)
+#define HFSPLUS_VOL_NODEID_REUSED	(1 << 12)
+#define HFSPLUS_VOL_JOURNALED		(1 << 13)
+#define HFSPLUS_VOL_SOFTLOCK		(1 << 15)
 
 /* HFS+ BTree node descriptor */
 struct hfs_bnode_desc {
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c
index cca0818..935dafb 100644
--- a/fs/hfsplus/options.c
+++ b/fs/hfsplus/options.c
@@ -22,7 +22,7 @@
 	opt_umask, opt_uid, opt_gid,
 	opt_part, opt_session, opt_nls,
 	opt_nodecompose, opt_decompose,
-	opt_err
+	opt_force, opt_err
 };
 
 static match_table_t tokens = {
@@ -36,6 +36,7 @@
 	{ opt_nls, "nls=%s" },
 	{ opt_decompose, "decompose" },
 	{ opt_nodecompose, "nodecompose" },
+	{ opt_force, "force" },
 	{ opt_err, NULL }
 };
 
@@ -145,6 +146,9 @@
 		case opt_nodecompose:
 			sbi->flags |= HFSPLUS_SB_NODECOMPOSE;
 			break;
+		case opt_force:
+			sbi->flags |= HFSPLUS_SB_FORCE;
+			break;
 		default:
 			return 0;
 		}
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 0ce1c45..6daaf7c 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -251,16 +251,28 @@
 		return 0;
 	if (!(*flags & MS_RDONLY)) {
 		struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
+		struct hfsplus_sb_info sbi;
+
+		memset(&sbi, 0, sizeof(struct hfsplus_sb_info));
+		sbi.nls = HFSPLUS_SB(sb).nls;
+		if (!hfsplus_parse_options(data, &sbi))
+			return -EINVAL;
 
 		if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) {
 			printk("HFS+-fs warning: Filesystem was not cleanly unmounted, "
 			       "running fsck.hfsplus is recommended.  leaving read-only.\n");
 			sb->s_flags |= MS_RDONLY;
 			*flags |= MS_RDONLY;
+		} else if (sbi.flags & HFSPLUS_SB_FORCE) {
+			/* nothing */
 		} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
 			printk("HFS+-fs: Filesystem is marked locked, leaving read-only.\n");
 			sb->s_flags |= MS_RDONLY;
 			*flags |= MS_RDONLY;
+		} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
+			printk("HFS+-fs: Filesystem is marked journaled, leaving read-only.\n");
+			sb->s_flags |= MS_RDONLY;
+			*flags |= MS_RDONLY;
 		}
 	}
 	return 0;
@@ -308,7 +320,7 @@
 	/* temporarily use utf8 to correctly find the hidden dir below */
 	nls = sbi->nls;
 	sbi->nls = load_nls("utf8");
-	if (!nls) {
+	if (!sbi->nls) {
 		printk("HFS+: unable to load nls for utf8\n");
 		err = -EINVAL;
 		goto cleanup;
@@ -352,11 +364,19 @@
 			printk("HFS+-fs warning: Filesystem was not cleanly unmounted, "
 			       "running fsck.hfsplus is recommended.  mounting read-only.\n");
 		sb->s_flags |= MS_RDONLY;
+	} else if (sbi->flags & HFSPLUS_SB_FORCE) {
+		/* nothing */
 	} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
 		if (!silent)
 			printk("HFS+-fs: Filesystem is marked locked, mounting read-only.\n");
 		sb->s_flags |= MS_RDONLY;
+	} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
+		if (!silent)
+			printk("HFS+-fs: write access to a jounaled filesystem is not supported, "
+			       "use the force option at your own risk, mounting read-only.\n");
+		sb->s_flags |= MS_RDONLY;
 	}
+	sbi->flags &= ~HFSPLUS_SB_FORCE;
 
 	/* Load metadata objects (B*Trees) */
 	HFSPLUS_SB(sb).ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 4684eb7..b3ad0bd 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -501,11 +501,16 @@
 	long long start;
 	int err = 0;
 
-	start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
+	start = (((long long) page->index) << PAGE_CACHE_SHIFT) + from;
 	buffer = kmap(page);
 	err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from,
 			 to - from);
 	if(err > 0) err = 0;
+
+	/* Actually, if !err, write_file has added to-from to start, so, despite
+	 * the appearance, we are comparing i_size against the _last_ written
+	 * location, as we should. */
+
 	if(!err && (start > inode->i_size))
 		inode->i_size = start;
 
@@ -910,10 +915,8 @@
 int hostfs_link_readpage(struct file *file, struct page *page)
 {
 	char *buffer, *name;
-	long long start;
 	int err;
 
-	start = page->index << PAGE_CACHE_SHIFT;
 	buffer = kmap(page);
 	name = inode_name(page->mapping->host, 0);
 	if(name == NULL) return(-ENOMEM);
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 8c1cef3..8c41315 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -100,9 +100,6 @@
 	loff_t len, vma_len;
 	int ret;
 
-	if ((vma->vm_flags & (VM_MAYSHARE | VM_WRITE)) == VM_WRITE)
-		return -EINVAL;
-
 	if (vma->vm_pgoff & (HPAGE_SIZE / PAGE_SIZE - 1))
 		return -EINVAL;
 
diff --git a/fs/inode.c b/fs/inode.c
index d8d04bd..fd568ca 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -770,7 +770,7 @@
  *
  * Note, @test is called with the inode_lock held, so can't sleep.
  */
-static inline struct inode *ifind(struct super_block *sb,
+static struct inode *ifind(struct super_block *sb,
 		struct hlist_head *head, int (*test)(struct inode *, void *),
 		void *data, const int wait)
 {
@@ -804,7 +804,7 @@
  *
  * Otherwise NULL is returned.
  */
-static inline struct inode *ifind_fast(struct super_block *sb,
+static struct inode *ifind_fast(struct super_block *sb,
 		struct hlist_head *head, unsigned long ino)
 {
 	struct inode *inode;
diff --git a/fs/inotify.c b/fs/inotify.c
index bf7ce1d..2fecb7a 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -364,11 +364,12 @@
 /*
  * find_inode - resolve a user-given path to a specific inode and return a nd
  */
-static int find_inode(const char __user *dirname, struct nameidata *nd)
+static int find_inode(const char __user *dirname, struct nameidata *nd,
+		      unsigned flags)
 {
 	int error;
 
-	error = __user_walk(dirname, LOOKUP_FOLLOW, nd);
+	error = __user_walk(dirname, flags, nd);
 	if (error)
 		return error;
 	/* you can only watch an inode if you have read permissions on it */
@@ -933,6 +934,7 @@
 	struct file *filp;
 	int ret, fput_needed;
 	int mask_add = 0;
+	unsigned flags = 0;
 
 	filp = fget_light(fd, &fput_needed);
 	if (unlikely(!filp))
@@ -944,7 +946,12 @@
 		goto fput_and_out;
 	}
 
-	ret = find_inode(path, &nd);
+	if (!(mask & IN_DONT_FOLLOW))
+		flags |= LOOKUP_FOLLOW;
+	if (mask & IN_ONLYDIR)
+		flags |= LOOKUP_DIRECTORY;
+
+	ret = find_inode(path, &nd, flags);
 	if (unlikely(ret))
 		goto fput_and_out;
 
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
index 014a51f..cb3cef5 100644
--- a/fs/jbd/checkpoint.c
+++ b/fs/jbd/checkpoint.c
@@ -24,7 +24,28 @@
 #include <linux/slab.h>
 
 /*
- * Unlink a buffer from a transaction. 
+ * Unlink a buffer from a transaction checkpoint list.
+ *
+ * Called with j_list_lock held.
+ */
+
+static void __buffer_unlink_first(struct journal_head *jh)
+{
+	transaction_t *transaction;
+
+	transaction = jh->b_cp_transaction;
+
+	jh->b_cpnext->b_cpprev = jh->b_cpprev;
+	jh->b_cpprev->b_cpnext = jh->b_cpnext;
+	if (transaction->t_checkpoint_list == jh) {
+		transaction->t_checkpoint_list = jh->b_cpnext;
+		if (transaction->t_checkpoint_list == jh)
+			transaction->t_checkpoint_list = NULL;
+	}
+}
+
+/*
+ * Unlink a buffer from a transaction checkpoint(io) list.
  *
  * Called with j_list_lock held.
  */
@@ -34,19 +55,44 @@
 	transaction_t *transaction;
 
 	transaction = jh->b_cp_transaction;
-	jh->b_cp_transaction = NULL;
 
-	jh->b_cpnext->b_cpprev = jh->b_cpprev;
-	jh->b_cpprev->b_cpnext = jh->b_cpnext;
-	if (transaction->t_checkpoint_list == jh)
-		transaction->t_checkpoint_list = jh->b_cpnext;
-	if (transaction->t_checkpoint_list == jh)
-		transaction->t_checkpoint_list = NULL;
+	__buffer_unlink_first(jh);
+	if (transaction->t_checkpoint_io_list == jh) {
+		transaction->t_checkpoint_io_list = jh->b_cpnext;
+		if (transaction->t_checkpoint_io_list == jh)
+			transaction->t_checkpoint_io_list = NULL;
+	}
+}
+
+/*
+ * Move a buffer from the checkpoint list to the checkpoint io list
+ *
+ * Called with j_list_lock held
+ */
+
+static inline void __buffer_relink_io(struct journal_head *jh)
+{
+	transaction_t *transaction;
+
+	transaction = jh->b_cp_transaction;
+	__buffer_unlink_first(jh);
+
+	if (!transaction->t_checkpoint_io_list) {
+		jh->b_cpnext = jh->b_cpprev = jh;
+	} else {
+		jh->b_cpnext = transaction->t_checkpoint_io_list;
+		jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev;
+		jh->b_cpprev->b_cpnext = jh;
+		jh->b_cpnext->b_cpprev = jh;
+	}
+	transaction->t_checkpoint_io_list = jh;
 }
 
 /*
  * Try to release a checkpointed buffer from its transaction.
- * Returns 1 if we released it.
+ * Returns 1 if we released it and 2 if we also released the
+ * whole transaction.
+ *
  * Requires j_list_lock
  * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
  */
@@ -57,12 +103,11 @@
 
 	if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh)) {
 		JBUFFER_TRACE(jh, "remove from checkpoint list");
-		__journal_remove_checkpoint(jh);
+		ret = __journal_remove_checkpoint(jh) + 1;
 		jbd_unlock_bh_state(bh);
 		journal_remove_journal_head(bh);
 		BUFFER_TRACE(bh, "release");
 		__brelse(bh);
-		ret = 1;
 	} else {
 		jbd_unlock_bh_state(bh);
 	}
@@ -117,83 +162,53 @@
 }
 
 /*
- * Clean up a transaction's checkpoint list.  
- *
- * We wait for any pending IO to complete and make sure any clean
- * buffers are removed from the transaction. 
- *
- * Return 1 if we performed any actions which might have destroyed the
- * checkpoint.  (journal_remove_checkpoint() deletes the transaction when
- * the last checkpoint buffer is cleansed)
+ * Clean up transaction's list of buffers submitted for io.
+ * We wait for any pending IO to complete and remove any clean
+ * buffers. Note that we take the buffers in the opposite ordering
+ * from the one in which they were submitted for IO.
  *
  * Called with j_list_lock held.
  */
-static int __cleanup_transaction(journal_t *journal, transaction_t *transaction)
+
+static void __wait_cp_io(journal_t *journal, transaction_t *transaction)
 {
-	struct journal_head *jh, *next_jh, *last_jh;
+	struct journal_head *jh;
 	struct buffer_head *bh;
-	int ret = 0;
+	tid_t this_tid;
+	int released = 0;
 
-	assert_spin_locked(&journal->j_list_lock);
-	jh = transaction->t_checkpoint_list;
-	if (!jh)
-		return 0;
-
-	last_jh = jh->b_cpprev;
-	next_jh = jh;
-	do {
-		jh = next_jh;
+	this_tid = transaction->t_tid;
+restart:
+	/* Didn't somebody clean up the transaction in the meanwhile */
+	if (journal->j_checkpoint_transactions != transaction ||
+		transaction->t_tid != this_tid)
+		return;
+	while (!released && transaction->t_checkpoint_io_list) {
+		jh = transaction->t_checkpoint_io_list;
 		bh = jh2bh(jh);
+		if (!jbd_trylock_bh_state(bh)) {
+			jbd_sync_bh(journal, bh);
+			spin_lock(&journal->j_list_lock);
+			goto restart;
+		}
 		if (buffer_locked(bh)) {
 			atomic_inc(&bh->b_count);
 			spin_unlock(&journal->j_list_lock);
+			jbd_unlock_bh_state(bh);
 			wait_on_buffer(bh);
 			/* the journal_head may have gone by now */
 			BUFFER_TRACE(bh, "brelse");
 			__brelse(bh);
-			goto out_return_1;
+			spin_lock(&journal->j_list_lock);
+			goto restart;
 		}
-
 		/*
-		 * This is foul
+		 * Now in whatever state the buffer currently is, we know that
+		 * it has been written out and so we can drop it from the list
 		 */
-		if (!jbd_trylock_bh_state(bh)) {
-			jbd_sync_bh(journal, bh);
-			goto out_return_1;
-		}
-
-		if (jh->b_transaction != NULL) {
-			transaction_t *t = jh->b_transaction;
-			tid_t tid = t->t_tid;
-
-			spin_unlock(&journal->j_list_lock);
-			jbd_unlock_bh_state(bh);
-			log_start_commit(journal, tid);
-			log_wait_commit(journal, tid);
-			goto out_return_1;
-		}
-
-		/*
-		 * AKPM: I think the buffer_jbddirty test is redundant - it
-		 * shouldn't have NULL b_transaction?
-		 */
-		next_jh = jh->b_cpnext;
-		if (!buffer_dirty(bh) && !buffer_jbddirty(bh)) {
-			BUFFER_TRACE(bh, "remove from checkpoint");
-			__journal_remove_checkpoint(jh);
-			jbd_unlock_bh_state(bh);
-			journal_remove_journal_head(bh);
-			__brelse(bh);
-			ret = 1;
-		} else {
-			jbd_unlock_bh_state(bh);
-		}
-	} while (jh != last_jh);
-
-	return ret;
-out_return_1:
-	spin_lock(&journal->j_list_lock);
-	return 1;
+		released = __journal_remove_checkpoint(jh);
+		jbd_unlock_bh_state(bh);
+	}
 }
 
 #define NR_BATCH	64
@@ -203,9 +218,7 @@
 {
 	int i;
 
-	spin_unlock(&journal->j_list_lock);
 	ll_rw_block(SWRITE, *batch_count, bhs);
-	spin_lock(&journal->j_list_lock);
 	for (i = 0; i < *batch_count; i++) {
 		struct buffer_head *bh = bhs[i];
 		clear_buffer_jwrite(bh);
@@ -221,19 +234,46 @@
  * Return 1 if something happened which requires us to abort the current
  * scan of the checkpoint list.  
  *
- * Called with j_list_lock held.
+ * Called with j_list_lock held and drops it if 1 is returned
  * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
  */
-static int __flush_buffer(journal_t *journal, struct journal_head *jh,
-			struct buffer_head **bhs, int *batch_count,
-			int *drop_count)
+static int __process_buffer(journal_t *journal, struct journal_head *jh,
+			struct buffer_head **bhs, int *batch_count)
 {
 	struct buffer_head *bh = jh2bh(jh);
 	int ret = 0;
 
-	if (buffer_dirty(bh) && !buffer_locked(bh) && jh->b_jlist == BJ_None) {
-		J_ASSERT_JH(jh, jh->b_transaction == NULL);
+	if (buffer_locked(bh)) {
+		get_bh(bh);
+		spin_unlock(&journal->j_list_lock);
+		jbd_unlock_bh_state(bh);
+		wait_on_buffer(bh);
+		/* the journal_head may have gone by now */
+		BUFFER_TRACE(bh, "brelse");
+		put_bh(bh);
+		ret = 1;
+	}
+	else if (jh->b_transaction != NULL) {
+		transaction_t *t = jh->b_transaction;
+		tid_t tid = t->t_tid;
 
+		spin_unlock(&journal->j_list_lock);
+		jbd_unlock_bh_state(bh);
+		log_start_commit(journal, tid);
+		log_wait_commit(journal, tid);
+		ret = 1;
+	}
+	else if (!buffer_dirty(bh)) {
+		J_ASSERT_JH(jh, !buffer_jbddirty(bh));
+		BUFFER_TRACE(bh, "remove from checkpoint");
+		__journal_remove_checkpoint(jh);
+		spin_unlock(&journal->j_list_lock);
+		jbd_unlock_bh_state(bh);
+		journal_remove_journal_head(bh);
+		put_bh(bh);
+		ret = 1;
+	}
+	else {
 		/*
 		 * Important: we are about to write the buffer, and
 		 * possibly block, while still holding the journal lock.
@@ -246,45 +286,30 @@
 		J_ASSERT_BH(bh, !buffer_jwrite(bh));
 		set_buffer_jwrite(bh);
 		bhs[*batch_count] = bh;
+		__buffer_relink_io(jh);
 		jbd_unlock_bh_state(bh);
 		(*batch_count)++;
 		if (*batch_count == NR_BATCH) {
+			spin_unlock(&journal->j_list_lock);
 			__flush_batch(journal, bhs, batch_count);
 			ret = 1;
 		}
-	} else {
-		int last_buffer = 0;
-		if (jh->b_cpnext == jh) {
-			/* We may be about to drop the transaction.  Tell the
-			 * caller that the lists have changed.
-			 */
-			last_buffer = 1;
-		}
-		if (__try_to_free_cp_buf(jh)) {
-			(*drop_count)++;
-			ret = last_buffer;
-		}
 	}
 	return ret;
 }
 
 /*
- * Perform an actual checkpoint.  We don't write out only enough to
- * satisfy the current blocked requests: rather we submit a reasonably
- * sized chunk of the outstanding data to disk at once for
- * efficiency.  __log_wait_for_space() will retry if we didn't free enough.
+ * Perform an actual checkpoint. We take the first transaction on the
+ * list of transactions to be checkpointed and send all its buffers
+ * to disk. We submit larger chunks of data at once.
  * 
- * However, we _do_ take into account the amount requested so that once
- * the IO has been queued, we can return as soon as enough of it has
- * completed to disk.  
- *
  * The journal should be locked before calling this function.
  */
 int log_do_checkpoint(journal_t *journal)
 {
+	transaction_t *transaction;
+	tid_t this_tid;
 	int result;
-	int batch_count = 0;
-	struct buffer_head *bhs[NR_BATCH];
 
 	jbd_debug(1, "Start checkpoint\n");
 
@@ -299,79 +324,70 @@
 		return result;
 
 	/*
-	 * OK, we need to start writing disk blocks.  Try to free up a
-	 * quarter of the log in a single checkpoint if we can.
-	 */
-	/*
-	 * AKPM: check this code.  I had a feeling a while back that it
-	 * degenerates into a busy loop at unmount time.
+	 * OK, we need to start writing disk blocks.  Take one transaction
+	 * and write it.
 	 */
 	spin_lock(&journal->j_list_lock);
-	while (journal->j_checkpoint_transactions) {
-		transaction_t *transaction;
-		struct journal_head *jh, *last_jh, *next_jh;
-		int drop_count = 0;
-		int cleanup_ret, retry = 0;
-		tid_t this_tid;
+	if (!journal->j_checkpoint_transactions)
+		goto out;
+	transaction = journal->j_checkpoint_transactions;
+	this_tid = transaction->t_tid;
+restart:
+	/*
+	 * If someone cleaned up this transaction while we slept, we're
+	 * done (maybe it's a new transaction, but it fell at the same
+	 * address).
+	 */
+ 	if (journal->j_checkpoint_transactions == transaction ||
+			transaction->t_tid == this_tid) {
+		int batch_count = 0;
+		struct buffer_head *bhs[NR_BATCH];
+		struct journal_head *jh;
+		int retry = 0;
 
-		transaction = journal->j_checkpoint_transactions;
-		this_tid = transaction->t_tid;
-		jh = transaction->t_checkpoint_list;
-		last_jh = jh->b_cpprev;
-		next_jh = jh;
-		do {
+		while (!retry && transaction->t_checkpoint_list) {
 			struct buffer_head *bh;
 
-			jh = next_jh;
-			next_jh = jh->b_cpnext;
+			jh = transaction->t_checkpoint_list;
 			bh = jh2bh(jh);
 			if (!jbd_trylock_bh_state(bh)) {
 				jbd_sync_bh(journal, bh);
-				spin_lock(&journal->j_list_lock);
 				retry = 1;
 				break;
 			}
-			retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count);
-			if (cond_resched_lock(&journal->j_list_lock)) {
+			retry = __process_buffer(journal, jh, bhs,
+						&batch_count);
+			if (!retry &&
+			    lock_need_resched(&journal->j_list_lock)) {
+				spin_unlock(&journal->j_list_lock);
 				retry = 1;
 				break;
 			}
-		} while (jh != last_jh && !retry);
-
-		if (batch_count) {
-			__flush_batch(journal, bhs, &batch_count);
-			retry = 1;
 		}
 
+		if (batch_count) {
+			if (!retry) {
+				spin_unlock(&journal->j_list_lock);
+				retry = 1;
+			}
+			__flush_batch(journal, bhs, &batch_count);
+		}
+
+		if (retry) {
+			spin_lock(&journal->j_list_lock);
+			goto restart;
+		}
 		/*
-		 * If someone cleaned up this transaction while we slept, we're
-		 * done
+		 * Now we have cleaned up the first transaction's checkpoint
+		 * list.  Let's clean up the second one.
 		 */
-		if (journal->j_checkpoint_transactions != transaction)
-			break;
-		if (retry)
-			continue;
-		/*
-		 * Maybe it's a new transaction, but it fell at the same
-		 * address
-		 */
-		if (transaction->t_tid != this_tid)
-			continue;
-		/*
-		 * We have walked the whole transaction list without
-		 * finding anything to write to disk.  We had better be
-		 * able to make some progress or we are in trouble. 
-		 */
-		cleanup_ret = __cleanup_transaction(journal, transaction);
-		J_ASSERT(drop_count != 0 || cleanup_ret != 0);
-		if (journal->j_checkpoint_transactions != transaction)
-			break;
+		__wait_cp_io(journal, transaction);
 	}
+out:
 	spin_unlock(&journal->j_list_lock);
 	result = cleanup_journal_tail(journal);
 	if (result < 0)
 		return result;
-
 	return 0;
 }
 
@@ -456,52 +472,91 @@
 /* Checkpoint list management */
 
 /*
- * journal_clean_checkpoint_list
+ * journal_clean_one_cp_list
  *
- * Find all the written-back checkpoint buffers in the journal and release them.
+ * Find all the written-back checkpoint buffers in the given list and release them.
  *
  * Called with the journal locked.
  * Called with j_list_lock held.
  * Returns number of bufers reaped (for debug)
  */
 
+static int journal_clean_one_cp_list(struct journal_head *jh, int *released)
+{
+	struct journal_head *last_jh;
+	struct journal_head *next_jh = jh;
+	int ret, freed = 0;
+
+	*released = 0;
+	if (!jh)
+		return 0;
+
+ 	last_jh = jh->b_cpprev;
+	do {
+		jh = next_jh;
+		next_jh = jh->b_cpnext;
+		/* Use trylock because of the ranking */
+		if (jbd_trylock_bh_state(jh2bh(jh))) {
+			ret = __try_to_free_cp_buf(jh);
+			if (ret) {
+				freed++;
+				if (ret == 2) {
+					*released = 1;
+					return freed;
+				}
+			}
+		}
+		/*
+		 * This function only frees up some memory if possible so we
+		 * dont have an obligation to finish processing. Bail out if
+		 * preemption requested:
+		 */
+		if (need_resched())
+			return freed;
+	} while (jh != last_jh);
+
+	return freed;
+}
+
+/*
+ * journal_clean_checkpoint_list
+ *
+ * Find all the written-back checkpoint buffers in the journal and release them.
+ *
+ * Called with the journal locked.
+ * Called with j_list_lock held.
+ * Returns number of buffers reaped (for debug)
+ */
+
 int __journal_clean_checkpoint_list(journal_t *journal)
 {
 	transaction_t *transaction, *last_transaction, *next_transaction;
-	int ret = 0;
+	int ret = 0, released;
 
 	transaction = journal->j_checkpoint_transactions;
-	if (transaction == 0)
+	if (!transaction)
 		goto out;
 
 	last_transaction = transaction->t_cpprev;
 	next_transaction = transaction;
 	do {
-		struct journal_head *jh;
-
 		transaction = next_transaction;
 		next_transaction = transaction->t_cpnext;
-		jh = transaction->t_checkpoint_list;
-		if (jh) {
-			struct journal_head *last_jh = jh->b_cpprev;
-			struct journal_head *next_jh = jh;
-
-			do {
-				jh = next_jh;
-				next_jh = jh->b_cpnext;
-				/* Use trylock because of the ranknig */
-				if (jbd_trylock_bh_state(jh2bh(jh)))
-					ret += __try_to_free_cp_buf(jh);
-				/*
-				 * This function only frees up some memory
-				 * if possible so we dont have an obligation
-				 * to finish processing. Bail out if preemption
-				 * requested:
-				 */
-				if (need_resched())
-					goto out;
-			} while (jh != last_jh);
-		}
+		ret += journal_clean_one_cp_list(transaction->
+				t_checkpoint_list, &released);
+		if (need_resched())
+			goto out;
+		if (released)
+			continue;
+		/*
+		 * It is essential that we are as careful as in the case of
+		 * t_checkpoint_list with removing the buffer from the list as
+		 * we can possibly see not yet submitted buffers on io_list
+		 */
+		ret += journal_clean_one_cp_list(transaction->
+				t_checkpoint_io_list, &released);
+		if (need_resched())
+			goto out;
 	} while (transaction != last_transaction);
 out:
 	return ret;
@@ -516,18 +571,22 @@
  * buffer updates committed in that transaction have safely been stored
  * elsewhere on disk.  To achieve this, all of the buffers in a
  * transaction need to be maintained on the transaction's checkpoint
- * list until they have been rewritten, at which point this function is
+ * lists until they have been rewritten, at which point this function is
  * called to remove the buffer from the existing transaction's
- * checkpoint list.  
+ * checkpoint lists.
+ *
+ * The function returns 1 if it frees the transaction, 0 otherwise.
  *
  * This function is called with the journal locked.
  * This function is called with j_list_lock held.
+ * This function is called with jbd_lock_bh_state(jh2bh(jh))
  */
 
-void __journal_remove_checkpoint(struct journal_head *jh)
+int __journal_remove_checkpoint(struct journal_head *jh)
 {
 	transaction_t *transaction;
 	journal_t *journal;
+	int ret = 0;
 
 	JBUFFER_TRACE(jh, "entry");
 
@@ -538,8 +597,10 @@
 	journal = transaction->t_journal;
 
 	__buffer_unlink(jh);
+	jh->b_cp_transaction = NULL;
 
-	if (transaction->t_checkpoint_list != NULL)
+	if (transaction->t_checkpoint_list != NULL ||
+	    transaction->t_checkpoint_io_list != NULL)
 		goto out;
 	JBUFFER_TRACE(jh, "transaction has no more buffers");
 
@@ -565,8 +626,10 @@
 	/* Just in case anybody was waiting for more transactions to be
            checkpointed... */
 	wake_up(&journal->j_wait_logspace);
+	ret = 1;
 out:
 	JBUFFER_TRACE(jh, "exit");
+	return ret;
 }
 
 /*
@@ -628,6 +691,7 @@
 	J_ASSERT(transaction->t_shadow_list == NULL);
 	J_ASSERT(transaction->t_log_list == NULL);
 	J_ASSERT(transaction->t_checkpoint_list == NULL);
+	J_ASSERT(transaction->t_checkpoint_io_list == NULL);
 	J_ASSERT(transaction->t_updates == 0);
 	J_ASSERT(journal->j_committing_transaction != transaction);
 	J_ASSERT(journal->j_running_transaction != transaction);
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 3dcc6d2..2559ee1 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -757,7 +757,7 @@
 
 	read_len = 0;
 	result = 0;
-	offset = page->index << PAGE_CACHE_SHIFT;
+	offset = page_offset(page);
 
 	kmap(page);
 	buf = page_address(page);
@@ -1545,7 +1545,7 @@
 {
        void *addr = page_address(page) + from;
        /* XXX: PAGE_CACHE_SHIFT or PAGE_SHIFT */
-       loff_t pos = (page->index<<PAGE_CACHE_SHIFT) + from;
+       loff_t pos = page_offset(page) + from;
 
        return jffs_file_write(filp, addr, to-from, &pos);
 } /* jffs_commit_write() */
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 5434206..d0fcc5f 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -234,6 +234,7 @@
 	c = JFFS2_SB_INFO(inode->i_sb);
 
 	jffs2_init_inode_info(f);
+	down(&f->sem);
 
 	ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
 
@@ -400,6 +401,7 @@
 
 	f = JFFS2_INODE_INFO(inode);
 	jffs2_init_inode_info(f);
+	down(&f->sem);
 
 	memset(ri, 0, sizeof(*ri));
 	/* Set OS-specific defaults for new inodes */
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 9e0b545..9388381 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -51,7 +51,7 @@
 
 	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 	    SLAB_CTOR_CONSTRUCTOR) {
-		init_MUTEX_LOCKED(&ei->sem);
+		init_MUTEX(&ei->sem);
 		inode_init_once(&ei->vfs_inode);
 	}
 }
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index 68000a5..2967b73 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -302,8 +302,7 @@
 	/*
 	 * write out dirty pages of bmap
 	 */
-	filemap_fdatawrite(ipbmap->i_mapping);
-	filemap_fdatawait(ipbmap->i_mapping);
+	filemap_write_and_wait(ipbmap->i_mapping);
 
 	diWriteSpecial(ipbmap, 0);
 
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 28201b1..31b4aa1 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -265,8 +265,7 @@
 	/*
 	 * write out dirty pages of imap
 	 */
-	filemap_fdatawrite(ipimap->i_mapping);
-	filemap_fdatawait(ipimap->i_mapping);
+	filemap_write_and_wait(ipimap->i_mapping);
 
 	diWriteSpecial(ipimap, 0);
 
@@ -565,8 +564,7 @@
 		jfs_err("diFreeSpecial called with NULL ip!");
 		return;
 	}
-	filemap_fdatawrite(ip->i_mapping);
-	filemap_fdatawait(ip->i_mapping);
+	filemap_write_and_wait(ip->i_mapping);
 	truncate_inode_pages(ip->i_mapping, 0);
 	iput(ip);
 }
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index b660c93..2ddb6b8 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -1231,10 +1231,8 @@
 		 * when we don't need to worry about it at all.
 		 *
 		 * if ((!S_ISDIR(ip->i_mode))
-		 *    && (tblk->flag & COMMIT_DELETE) == 0) {
-		 *	filemap_fdatawrite(ip->i_mapping);
-		 *	filemap_fdatawait(ip->i_mapping);
-		 * }
+		 *    && (tblk->flag & COMMIT_DELETE) == 0)
+		 *	filemap_write_and_wait(ip->i_mapping);
 		 */
 
 		/*
diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c
index 5cf9178..21eaf7a 100644
--- a/fs/jfs/jfs_umount.c
+++ b/fs/jfs/jfs_umount.c
@@ -108,8 +108,7 @@
 	 * Make sure all metadata makes it to disk before we mark
 	 * the superblock as clean
 	 */
-	filemap_fdatawrite(sbi->direct_inode->i_mapping);
-	filemap_fdatawait(sbi->direct_inode->i_mapping);
+	filemap_write_and_wait(sbi->direct_inode->i_mapping);
 
 	/*
 	 * ensure all file system file pages are propagated to their
@@ -161,8 +160,7 @@
 	 * mark the superblock clean before everything is flushed to
 	 * disk.
 	 */
-	filemap_fdatawrite(sbi->direct_inode->i_mapping);
-	filemap_fdatawait(sbi->direct_inode->i_mapping);
+	filemap_write_and_wait(sbi->direct_inode->i_mapping);
 
 	updateSuper(sb, FM_CLEAN);
 
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c
index c6dc254..4518036 100644
--- a/fs/jfs/resize.c
+++ b/fs/jfs/resize.c
@@ -376,8 +376,7 @@
 	 * by txCommit();
 	 */
 	filemap_fdatawait(ipbmap->i_mapping);
-	filemap_fdatawrite(ipbmap->i_mapping);
-	filemap_fdatawait(ipbmap->i_mapping);
+	filemap_write_and_wait(ipbmap->i_mapping);
 	diWriteSpecial(ipbmap, 0);
 
 	newPage = nPages;	/* first new page number */
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 4226af3..8d31f13 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -502,8 +502,7 @@
 		jfs_err("jfs_umount failed with return code %d", rc);
 	}
 out_mount_failed:
-	filemap_fdatawrite(sbi->direct_inode->i_mapping);
-	filemap_fdatawait(sbi->direct_inode->i_mapping);
+	filemap_write_and_wait(sbi->direct_inode->i_mapping);
 	truncate_inode_pages(sbi->direct_inode->i_mapping, 0);
 	make_bad_inode(sbi->direct_inode);
 	iput(sbi->direct_inode);
diff --git a/fs/libfs.c b/fs/libfs.c
index 58101df..9c50523 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -93,16 +93,16 @@
 			loff_t n = file->f_pos - 2;
 
 			spin_lock(&dcache_lock);
-			list_del(&cursor->d_child);
+			list_del(&cursor->d_u.d_child);
 			p = file->f_dentry->d_subdirs.next;
 			while (n && p != &file->f_dentry->d_subdirs) {
 				struct dentry *next;
-				next = list_entry(p, struct dentry, d_child);
+				next = list_entry(p, struct dentry, d_u.d_child);
 				if (!d_unhashed(next) && next->d_inode)
 					n--;
 				p = p->next;
 			}
-			list_add_tail(&cursor->d_child, p);
+			list_add_tail(&cursor->d_u.d_child, p);
 			spin_unlock(&dcache_lock);
 		}
 	}
@@ -126,7 +126,7 @@
 {
 	struct dentry *dentry = filp->f_dentry;
 	struct dentry *cursor = filp->private_data;
-	struct list_head *p, *q = &cursor->d_child;
+	struct list_head *p, *q = &cursor->d_u.d_child;
 	ino_t ino;
 	int i = filp->f_pos;
 
@@ -153,7 +153,7 @@
 			}
 			for (p=q->next; p != &dentry->d_subdirs; p=p->next) {
 				struct dentry *next;
-				next = list_entry(p, struct dentry, d_child);
+				next = list_entry(p, struct dentry, d_u.d_child);
 				if (d_unhashed(next) || !next->d_inode)
 					continue;
 
@@ -261,7 +261,7 @@
 	int ret = 0;
 
 	spin_lock(&dcache_lock);
-	list_for_each_entry(child, &dentry->d_subdirs, d_child)
+	list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child)
 		if (simple_positive(child))
 			goto out;
 	ret = 1;
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index 006bb9e..3eaf6e7 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -157,6 +157,8 @@
 		inode = fl->fl_file->f_dentry->d_inode;
 		if (inode->i_sb->s_magic != NFS_SUPER_MAGIC)
 			continue;
+		if (fl->fl_u.nfs_fl.owner == NULL)
+			continue;
 		if (fl->fl_u.nfs_fl.owner->host != host)
 			continue;
 		if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_GRANTED))
@@ -226,6 +228,8 @@
 		inode = fl->fl_file->f_dentry->d_inode;
 		if (inode->i_sb->s_magic != NFS_SUPER_MAGIC)
 			continue;
+		if (fl->fl_u.nfs_fl.owner == NULL)
+			continue;
 		if (fl->fl_u.nfs_fl.owner->host != host)
 			continue;
 		if (!(fl->fl_u.nfs_fl.flags & NFS_LCK_RECLAIM))
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index c5a3364..1455240 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -26,11 +26,12 @@
 static int	nlmclnt_test(struct nlm_rqst *, struct file_lock *);
 static int	nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
 static int	nlmclnt_unlock(struct nlm_rqst *, struct file_lock *);
-static void	nlmclnt_unlock_callback(struct rpc_task *);
-static void	nlmclnt_cancel_callback(struct rpc_task *);
 static int	nlm_stat_to_errno(u32 stat);
 static void	nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host);
 
+static const struct rpc_call_ops nlmclnt_unlock_ops;
+static const struct rpc_call_ops nlmclnt_cancel_ops;
+
 /*
  * Cookie counter for NLM requests
  */
@@ -221,8 +222,7 @@
 			goto done;
 		}
 		clnt->cl_softrtry = nfssrv->client->cl_softrtry;
-		clnt->cl_intr     = nfssrv->client->cl_intr;
-		clnt->cl_chatty   = nfssrv->client->cl_chatty;
+		clnt->cl_intr = nfssrv->client->cl_intr;
 	}
 
 	/* Keep the old signal mask */
@@ -399,8 +399,7 @@
 /*
  * Generic NLM call, async version.
  */
-int
-nlmsvc_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
+int nlmsvc_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
 {
 	struct nlm_host	*host = req->a_host;
 	struct rpc_clnt	*clnt;
@@ -419,13 +418,12 @@
 	msg.rpc_proc = &clnt->cl_procinfo[proc];
 
         /* bootstrap and kick off the async RPC call */
-        status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, callback, req);
+        status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, tk_ops, req);
 
 	return status;
 }
 
-static int
-nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
+static int nlmclnt_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
 {
 	struct nlm_host	*host = req->a_host;
 	struct rpc_clnt	*clnt;
@@ -448,7 +446,7 @@
 	/* Increment host refcount */
 	nlm_get_host(host);
         /* bootstrap and kick off the async RPC call */
-        status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, callback, req);
+        status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, tk_ops, req);
 	if (status < 0)
 		nlm_release_host(host);
 	return status;
@@ -664,7 +662,7 @@
 
 	if (req->a_flags & RPC_TASK_ASYNC) {
 		status = nlmclnt_async_call(req, NLMPROC_UNLOCK,
-					nlmclnt_unlock_callback);
+					&nlmclnt_unlock_ops);
 		/* Hrmf... Do the unlock early since locks_remove_posix()
 		 * really expects us to free the lock synchronously */
 		do_vfs_lock(fl);
@@ -692,10 +690,9 @@
 	return -ENOLCK;
 }
 
-static void
-nlmclnt_unlock_callback(struct rpc_task *task)
+static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
 {
-	struct nlm_rqst	*req = (struct nlm_rqst *) task->tk_calldata;
+	struct nlm_rqst	*req = data;
 	int		status = req->a_res.status;
 
 	if (RPC_ASSASSINATED(task))
@@ -722,6 +719,10 @@
 	rpc_restart_call(task);
 }
 
+static const struct rpc_call_ops nlmclnt_unlock_ops = {
+	.rpc_call_done = nlmclnt_unlock_callback,
+};
+
 /*
  * Cancel a blocked lock request.
  * We always use an async RPC call for this in order not to hang a
@@ -750,8 +751,7 @@
 
 	nlmclnt_setlockargs(req, fl);
 
-	status = nlmclnt_async_call(req, NLMPROC_CANCEL,
-					nlmclnt_cancel_callback);
+	status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops);
 	if (status < 0) {
 		nlmclnt_release_lockargs(req);
 		kfree(req);
@@ -765,10 +765,9 @@
 	return status;
 }
 
-static void
-nlmclnt_cancel_callback(struct rpc_task *task)
+static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
 {
-	struct nlm_rqst	*req = (struct nlm_rqst *) task->tk_calldata;
+	struct nlm_rqst	*req = data;
 
 	if (RPC_ASSASSINATED(task))
 		goto die;
@@ -807,6 +806,10 @@
 	rpc_delay(task, 30 * HZ);
 }
 
+static const struct rpc_call_ops nlmclnt_cancel_ops = {
+	.rpc_call_done = nlmclnt_cancel_callback,
+};
+
 /*
  * Convert an NLM status code to a generic kernel errno
  */
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index c4c8601..82f7a0b 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -177,7 +177,7 @@
 	if ((clnt = host->h_rpcclnt) != NULL) {
 		xprt = clnt->cl_xprt;
 		if (time_after_eq(jiffies, host->h_nextrebind)) {
-			clnt->cl_port = 0;
+			rpc_force_rebind(clnt);
 			host->h_nextrebind = jiffies + NLM_HOST_REBIND;
 			dprintk("lockd: next rebind in %ld jiffies\n",
 					host->h_nextrebind - jiffies);
@@ -217,7 +217,7 @@
 {
 	dprintk("lockd: rebind host %s\n", host->h_name);
 	if (host->h_rpcclnt && time_after_eq(jiffies, host->h_nextrebind)) {
-		host->h_rpcclnt->cl_port = 0;
+		rpc_force_rebind(host->h_rpcclnt);
 		host->h_nextrebind = jiffies + NLM_HOST_REBIND;
 	}
 }
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 2d144ab..0edc03e 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -123,7 +123,6 @@
 	if (IS_ERR(clnt))
 		goto out_err;
 	clnt->cl_softrtry = 1;
-	clnt->cl_chatty   = 1;
 	clnt->cl_oneshot  = 1;
 	return clnt;
 
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 12a857c..71a30b4 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -178,6 +178,8 @@
 
 	}
 
+	flush_signals(current);
+
 	/*
 	 * Check whether there's a new lockd process before
 	 * shutting down the hosts and clearing the slot.
@@ -192,8 +194,6 @@
 			"lockd: new process, skipping host shutdown\n");
 	wake_up(&lockd_exit);
 
-	flush_signals(current);
-
 	/* Exit the RPC thread */
 	svc_exit_thread(rqstp);
 
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 489670e..4063095 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -22,7 +22,8 @@
 #define NLMDBG_FACILITY		NLMDBG_CLIENT
 
 static u32	nlm4svc_callback(struct svc_rqst *, u32, struct nlm_res *);
-static void	nlm4svc_callback_exit(struct rpc_task *);
+
+static const struct rpc_call_ops nlm4svc_callback_ops;
 
 /*
  * Obtain client and file from arguments
@@ -470,7 +471,6 @@
 }
 
 
-
 /*
  * This is the generic lockd callback for async RPC calls
  */
@@ -494,7 +494,7 @@
 	call->a_host  = host;
 	memcpy(&call->a_args, resp, sizeof(*resp));
 
-	if (nlmsvc_async_call(call, proc, nlm4svc_callback_exit) < 0)
+	if (nlmsvc_async_call(call, proc, &nlm4svc_callback_ops) < 0)
 		goto error;
 
 	return rpc_success;
@@ -504,10 +504,9 @@
 	return rpc_system_err;
 }
 
-static void
-nlm4svc_callback_exit(struct rpc_task *task)
+static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
 {
-	struct nlm_rqst	*call = (struct nlm_rqst *) task->tk_calldata;
+	struct nlm_rqst	*call = data;
 
 	if (task->tk_status < 0) {
 		dprintk("lockd: %4d callback failed (errno = %d)\n",
@@ -517,6 +516,10 @@
 	kfree(call);
 }
 
+static const struct rpc_call_ops nlm4svc_callback_ops = {
+	.rpc_call_done = nlm4svc_callback_exit,
+};
+
 /*
  * NLM Server procedures.
  */
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 49f9597..9cfced6 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -41,7 +41,8 @@
 
 static void	nlmsvc_insert_block(struct nlm_block *block, unsigned long);
 static int	nlmsvc_remove_block(struct nlm_block *block);
-static void	nlmsvc_grant_callback(struct rpc_task *task);
+
+static const struct rpc_call_ops nlmsvc_grant_ops;
 
 /*
  * The list of blocked locks to retry
@@ -226,31 +227,27 @@
  * It is the caller's responsibility to check whether the file
  * can be closed hereafter.
  */
-static void
+static int
 nlmsvc_delete_block(struct nlm_block *block, int unlock)
 {
 	struct file_lock	*fl = &block->b_call.a_args.lock.fl;
 	struct nlm_file		*file = block->b_file;
 	struct nlm_block	**bp;
+	int status = 0;
 
 	dprintk("lockd: deleting block %p...\n", block);
 
 	/* Remove block from list */
 	nlmsvc_remove_block(block);
-	if (fl->fl_next)
-		posix_unblock_lock(file->f_file, fl);
-	if (unlock) {
-		fl->fl_type = F_UNLCK;
-		posix_lock_file(file->f_file, fl);
-		block->b_granted = 0;
-	}
+	if (unlock)
+		status = posix_unblock_lock(file->f_file, fl);
 
 	/* If the block is in the middle of a GRANT callback,
 	 * don't kill it yet. */
 	if (block->b_incall) {
 		nlmsvc_insert_block(block, NLM_NEVER);
 		block->b_done = 1;
-		return;
+		return status;
 	}
 
 	/* Remove block from file's list of blocks */
@@ -265,6 +262,7 @@
 		nlm_release_host(block->b_host);
 	nlmclnt_freegrantargs(&block->b_call);
 	kfree(block);
+	return status;
 }
 
 /*
@@ -275,6 +273,7 @@
 nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action)
 {
 	struct nlm_block	*block, *next;
+	/* XXX: Will everything get cleaned up if we don't unlock here? */
 
 	down(&file->f_sema);
 	for (block = file->f_blocks; block; block = next) {
@@ -444,6 +443,7 @@
 nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
 {
 	struct nlm_block	*block;
+	int status = 0;
 
 	dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
 				file->f_file->f_dentry->d_inode->i_sb->s_id,
@@ -454,9 +454,9 @@
 
 	down(&file->f_sema);
 	if ((block = nlmsvc_lookup_block(file, lock, 1)) != NULL)
-		nlmsvc_delete_block(block, 1);
+		status = nlmsvc_delete_block(block, 1);
 	up(&file->f_sema);
-	return nlm_granted;
+	return status ? nlm_lck_denied : nlm_granted;
 }
 
 /*
@@ -562,7 +562,7 @@
 	/* Call the client */
 	nlm_get_host(block->b_call.a_host);
 	if (nlmsvc_async_call(&block->b_call, NLMPROC_GRANTED_MSG,
-						nlmsvc_grant_callback) < 0)
+						&nlmsvc_grant_ops) < 0)
 		nlm_release_host(block->b_call.a_host);
 	up(&file->f_sema);
 }
@@ -575,10 +575,9 @@
  * chain once more in order to have it removed by lockd itself (which can
  * then sleep on the file semaphore without disrupting e.g. the nfs client).
  */
-static void
-nlmsvc_grant_callback(struct rpc_task *task)
+static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
 {
-	struct nlm_rqst		*call = (struct nlm_rqst *) task->tk_calldata;
+	struct nlm_rqst		*call = data;
 	struct nlm_block	*block;
 	unsigned long		timeout;
 	struct sockaddr_in	*peer_addr = RPC_PEERADDR(task->tk_client);
@@ -614,6 +613,10 @@
 	nlm_release_host(call->a_host);
 }
 
+static const struct rpc_call_ops nlmsvc_grant_ops = {
+	.rpc_call_done = nlmsvc_grant_callback,
+};
+
 /*
  * We received a GRANT_RES callback. Try to find the corresponding
  * block.
@@ -633,11 +636,12 @@
 
 	file->f_count++;
 	down(&file->f_sema);
-	if ((block = nlmsvc_find_block(cookie,&rqstp->rq_addr)) != NULL) {
+	block = nlmsvc_find_block(cookie, &rqstp->rq_addr);
+	if (block) {
 		if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
 			/* Try again in a couple of seconds */
 			nlmsvc_insert_block(block, 10 * HZ);
-			block = NULL;
+			up(&file->f_sema);
 		} else {
 			/* Lock is now held by client, or has been rejected.
 			 * In both cases, the block should be removed. */
@@ -648,8 +652,6 @@
 				nlmsvc_delete_block(block, 1);
 		}
 	}
-	if (!block)
-		up(&file->f_sema);
 	nlm_release_file(file);
 }
 
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 757e344..3bc437e 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -23,7 +23,8 @@
 #define NLMDBG_FACILITY		NLMDBG_CLIENT
 
 static u32	nlmsvc_callback(struct svc_rqst *, u32, struct nlm_res *);
-static void	nlmsvc_callback_exit(struct rpc_task *);
+
+static const struct rpc_call_ops nlmsvc_callback_ops;
 
 #ifdef CONFIG_LOCKD_V4
 static u32
@@ -518,7 +519,7 @@
 	call->a_host  = host;
 	memcpy(&call->a_args, resp, sizeof(*resp));
 
-	if (nlmsvc_async_call(call, proc, nlmsvc_callback_exit) < 0)
+	if (nlmsvc_async_call(call, proc, &nlmsvc_callback_ops) < 0)
 		goto error;
 
 	return rpc_success;
@@ -528,10 +529,9 @@
 	return rpc_system_err;
 }
 
-static void
-nlmsvc_callback_exit(struct rpc_task *task)
+static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
 {
-	struct nlm_rqst	*call = (struct nlm_rqst *) task->tk_calldata;
+	struct nlm_rqst	*call = data;
 
 	if (task->tk_status < 0) {
 		dprintk("lockd: %4d callback failed (errno = %d)\n",
@@ -541,6 +541,10 @@
 	kfree(call);
 }
 
+static const struct rpc_call_ops nlmsvc_callback_ops = {
+	.rpc_call_done = nlmsvc_callback_exit,
+};
+
 /*
  * NLM Server procedures.
  */
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index ae4d6b4..fdcf105a 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -354,7 +354,9 @@
 		return 0;
 	argp->state = ntohl(*p++);
 	/* Preserve the address in network byte order */
-	argp->addr = *p++;
+	argp->addr  = *p++;
+	argp->vers  = *p++;
+	argp->proto = *p++;
 	return xdr_argsize_check(rqstp, p);
 }
 
diff --git a/fs/locks.c b/fs/locks.c
index 250ef53..909eab8 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -154,7 +154,7 @@
 }
 
 /* Free a lock which is not in use. */
-static inline void locks_free_lock(struct file_lock *fl)
+static void locks_free_lock(struct file_lock *fl)
 {
 	if (fl == NULL) {
 		BUG();
@@ -475,8 +475,7 @@
 /*
  * Check whether two locks have the same owner.
  */
-static inline int
-posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
+static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
 {
 	if (fl1->fl_lmops && fl1->fl_lmops->fl_compare_owner)
 		return fl2->fl_lmops == fl1->fl_lmops &&
@@ -487,7 +486,7 @@
 /* Remove waiter from blocker's block list.
  * When blocker ends up pointing to itself then the list is empty.
  */
-static inline void __locks_delete_block(struct file_lock *waiter)
+static void __locks_delete_block(struct file_lock *waiter)
 {
 	list_del_init(&waiter->fl_block);
 	list_del_init(&waiter->fl_link);
@@ -1958,22 +1957,18 @@
  *
  *	lockd needs to block waiting for locks.
  */
-void
+int
 posix_unblock_lock(struct file *filp, struct file_lock *waiter)
 {
-	/* 
-	 * A remote machine may cancel the lock request after it's been
-	 * granted locally.  If that happens, we need to delete the lock.
-	 */
+	int status = 0;
+
 	lock_kernel();
-	if (waiter->fl_next) {
+	if (waiter->fl_next)
 		__locks_delete_block(waiter);
-		unlock_kernel();
-	} else {
-		unlock_kernel();
-		waiter->fl_type = F_UNLCK;
-		posix_lock_file(filp, waiter);
-	}
+	else
+		status = -ENOENT;
+	unlock_kernel();
+	return status;
 }
 
 EXPORT_SYMBOL(posix_unblock_lock);
diff --git a/fs/mpage.c b/fs/mpage.c
index c5adcdd..e431cb3 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -184,7 +184,7 @@
 	if (page_has_buffers(page))
 		goto confused;
 
-	block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits);
+	block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
 	last_block = (i_size_read(inode) + blocksize - 1) >> blkbits;
 
 	bh.b_page = page;
@@ -466,7 +466,7 @@
 	 * The page has no buffers: map it to disk
 	 */
 	BUG_ON(!PageUptodate(page));
-	block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits);
+	block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
 	last_block = (i_size - 1) >> blkbits;
 	map_bh.b_page = page;
 	for (page_block = 0; page_block < blocks_per_page; ) {
@@ -721,7 +721,7 @@
 						&last_block_in_bio, &ret, wbc,
 						page->mapping->a_ops->writepage);
 			}
-			if (unlikely(ret == WRITEPAGE_ACTIVATE))
+			if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
 				unlock_page(page);
 			if (ret || (--(wbc->nr_to_write) <= 0))
 				done = 1;
diff --git a/fs/namei.c b/fs/namei.c
index 6dbbd42..300eae0 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1491,7 +1491,7 @@
 		if (!error) {
 			DQUOT_INIT(inode);
 			
-			error = do_truncate(dentry, 0, NULL);
+			error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
 		}
 		put_write_access(inode);
 		if (error)
diff --git a/fs/namespace.c b/fs/namespace.c
index 2019899f..3e8fb61 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -451,7 +451,7 @@
 void release_mounts(struct list_head *head)
 {
 	struct vfsmount *mnt;
-	while(!list_empty(head)) {
+	while (!list_empty(head)) {
 		mnt = list_entry(head->next, struct vfsmount, mnt_hash);
 		list_del_init(&mnt->mnt_hash);
 		if (mnt->mnt_parent != mnt) {
@@ -1526,6 +1526,10 @@
  * pointed to by put_old must yield the same directory as new_root. No other
  * file system may be mounted on put_old. After all, new_root is a mountpoint.
  *
+ * Also, the current root cannot be on the 'rootfs' (initial ramfs) filesystem.
+ * See Documentation/filesystems/ramfs-rootfs-initramfs.txt for alternatives
+ * in this situation.
+ *
  * Notes:
  *  - we don't move root/cwd if they are not at the root (reason: if something
  *    cared enough to change them, it's probably wrong to force them elsewhere)
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index a9f7a8a..cfd76f4 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -365,7 +365,7 @@
 	spin_lock(&dcache_lock);
 	next = parent->d_subdirs.next;
 	while (next != &parent->d_subdirs) {
-		dent = list_entry(next, struct dentry, d_child);
+		dent = list_entry(next, struct dentry, d_u.d_child);
 		if ((unsigned long)dent->d_fsdata == fpos) {
 			if (dent->d_inode)
 				dget_locked(dent);
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
index 9e4dc30..799e5c2 100644
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -196,7 +196,7 @@
 	spin_lock(&dcache_lock);
 	next = parent->d_subdirs.next;
 	while (next != &parent->d_subdirs) {
-		dentry = list_entry(next, struct dentry, d_child);
+		dentry = list_entry(next, struct dentry, d_u.d_child);
 
 		if (dentry->d_fsdata == NULL)
 			ncp_age_dentry(server, dentry);
@@ -218,7 +218,7 @@
 	spin_lock(&dcache_lock);
 	next = parent->d_subdirs.next;
 	while (next != &parent->d_subdirs) {
-		dentry = list_entry(next, struct dentry, d_child);
+		dentry = list_entry(next, struct dentry, d_u.d_child);
 		dentry->d_fsdata = NULL;
 		ncp_age_dentry(server, dentry);
 		next = next->next;
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 8b3bb71..ec61fd5 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -13,4 +13,5 @@
 			   delegation.o idmap.o \
 			   callback.o callback_xdr.o callback_proc.o
 nfs-$(CONFIG_NFS_DIRECTIO) += direct.o
+nfs-$(CONFIG_SYSCTL) += sysctl.o
 nfs-objs		:= $(nfs-y)
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index f2ca782..fcd97406 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -14,6 +14,9 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfs_fs.h>
+
+#include <net/inet_sock.h>
+
 #include "nfs4_fs.h"
 #include "callback.h"
 
@@ -31,6 +34,7 @@
 static DECLARE_MUTEX(nfs_callback_sema);
 static struct svc_program nfs4_callback_program;
 
+unsigned int nfs_callback_set_tcpport;
 unsigned short nfs_callback_tcpport;
 
 /*
@@ -95,7 +99,7 @@
 	if (!serv)
 		goto out_err;
 	/* FIXME: We don't want to register this socket with the portmapper */
-	ret = svc_makesock(serv, IPPROTO_TCP, 0);
+	ret = svc_makesock(serv, IPPROTO_TCP, nfs_callback_set_tcpport);
 	if (ret < 0)
 		goto out_destroy;
 	if (!list_empty(&serv->sv_permsocks)) {
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index a0db2d4f9..b252e7f 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -65,6 +65,7 @@
 extern int nfs_callback_up(void);
 extern int nfs_callback_down(void);
 
+extern unsigned int nfs_callback_set_tcpport;
 extern unsigned short nfs_callback_tcpport;
 
 #endif /* __LINUX_FS_NFS_CALLBACK_H */
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 65f1e19..462cfce 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -35,7 +35,9 @@
 	if (delegation == NULL || (delegation->type & FMODE_WRITE) == 0)
 		goto out_iput;
 	res->size = i_size_read(inode);
-	res->change_attr = NFS_CHANGE_ATTR(inode);
+	res->change_attr = delegation->change_attr;
+	if (nfsi->npages != 0)
+		res->change_attr++;
 	res->ctime = inode->i_ctime;
 	res->mtime = inode->i_mtime;
 	res->bitmap[0] = (FATTR4_WORD0_CHANGE|FATTR4_WORD0_SIZE) &
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 618a327..c6f07c1 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -8,6 +8,7 @@
  */
 #include <linux/config.h>
 #include <linux/completion.h>
+#include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
@@ -130,6 +131,7 @@
 			sizeof(delegation->stateid.data));
 	delegation->type = res->delegation_type;
 	delegation->maxsize = res->maxsize;
+	delegation->change_attr = nfsi->change_attr;
 	delegation->cred = get_rpccred(cred);
 	delegation->inode = inode;
 
@@ -157,8 +159,6 @@
 {
 	int res = 0;
 
-	__nfs_revalidate_inode(NFS_SERVER(inode), inode);
-
 	res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid);
 	nfs_free_delegation(delegation);
 	return res;
@@ -231,6 +231,49 @@
 	spin_unlock(&clp->cl_lock);
 }
 
+int nfs_do_expire_all_delegations(void *ptr)
+{
+	struct nfs4_client *clp = ptr;
+	struct nfs_delegation *delegation;
+	struct inode *inode;
+
+	allow_signal(SIGKILL);
+restart:
+	spin_lock(&clp->cl_lock);
+	if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0)
+		goto out;
+	if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0)
+		goto out;
+	list_for_each_entry(delegation, &clp->cl_delegations, super_list) {
+		inode = igrab(delegation->inode);
+		if (inode == NULL)
+			continue;
+		spin_unlock(&clp->cl_lock);
+		nfs_inode_return_delegation(inode);
+		iput(inode);
+		goto restart;
+	}
+out:
+	spin_unlock(&clp->cl_lock);
+	nfs4_put_client(clp);
+	module_put_and_exit(0);
+}
+
+void nfs_expire_all_delegations(struct nfs4_client *clp)
+{
+	struct task_struct *task;
+
+	__module_get(THIS_MODULE);
+	atomic_inc(&clp->cl_count);
+	task = kthread_run(nfs_do_expire_all_delegations, clp,
+			"%u.%u.%u.%u-delegreturn",
+			NIPQUAD(clp->cl_addr));
+	if (!IS_ERR(task))
+		return;
+	nfs4_put_client(clp);
+	module_put(THIS_MODULE);
+}
+
 /*
  * Return all delegations following an NFS4ERR_CB_PATH_DOWN error.
  */
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 2fcc30d..7a0b2bf 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -21,6 +21,7 @@
 #define NFS_DELEGATION_NEED_RECLAIM 1
 	long flags;
 	loff_t maxsize;
+	__u64 change_attr;
 };
 
 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
@@ -30,6 +31,7 @@
 
 struct inode *nfs_delegation_find_inode(struct nfs4_client *clp, const struct nfs_fh *fhandle);
 void nfs_return_all_delegations(struct super_block *sb);
+void nfs_expire_all_delegations(struct nfs4_client *clp);
 void nfs_handle_cb_pathdown(struct nfs4_client *clp);
 
 void nfs_delegation_mark_reclaim(struct nfs4_client *clp);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7370583..e925519 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1287,6 +1287,7 @@
 		nfs_begin_data_update(dentry->d_inode);
 		error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
 				dir, &qsilly);
+		nfs_mark_for_revalidate(dentry->d_inode);
 		nfs_end_data_update(dentry->d_inode);
 	} else
 		error = NFS_PROTO(dir)->rename(dir, &dentry->d_name,
@@ -1334,6 +1335,7 @@
 		/* The VFS may want to delete this inode */
 		if (error == 0)
 			inode->i_nlink--;
+		nfs_mark_for_revalidate(inode);
 		nfs_end_data_update(inode);
 	} else
 		error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
@@ -1548,14 +1550,17 @@
 	}
 	nfs_inode_return_delegation(old_inode);
 
-	if (new_inode)
+	if (new_inode != NULL) {
+		nfs_inode_return_delegation(new_inode);
 		d_delete(new_dentry);
+	}
 
 	nfs_begin_data_update(old_dir);
 	nfs_begin_data_update(new_dir);
 	nfs_begin_data_update(old_inode);
 	error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name,
 					   new_dir, &new_dentry->d_name);
+	nfs_mark_for_revalidate(old_inode);
 	nfs_end_data_update(old_inode);
 	nfs_end_data_update(new_dir);
 	nfs_end_data_update(old_dir);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index b497c71..10ae377 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -122,9 +122,10 @@
 {
 	int i;
 	for (i = 0; i < npages; i++) {
-		if (do_dirty)
-			set_page_dirty_lock(pages[i]);
-		page_cache_release(pages[i]);
+		struct page *page = pages[i];
+		if (do_dirty && !PageCompound(page))
+			set_page_dirty_lock(page);
+		page_cache_release(page);
 	}
 	kfree(pages);
 }
@@ -154,6 +155,7 @@
 	struct list_head *list;
 	struct nfs_direct_req *dreq;
 	unsigned int reads = 0;
+	unsigned int rpages = (rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
 	dreq = kmem_cache_alloc(nfs_direct_cachep, SLAB_KERNEL);
 	if (!dreq)
@@ -167,7 +169,7 @@
 
 	list = &dreq->list;
 	for(;;) {
-		struct nfs_read_data *data = nfs_readdata_alloc();
+		struct nfs_read_data *data = nfs_readdata_alloc(rpages);
 
 		if (unlikely(!data)) {
 			while (!list_empty(list)) {
@@ -268,8 +270,6 @@
 		NFS_PROTO(inode)->read_setup(data);
 
 		data->task.tk_cookie = (unsigned long) inode;
-		data->task.tk_calldata = data;
-		data->task.tk_release = nfs_readdata_release;
 		data->complete = nfs_direct_read_result;
 
 		lock_kernel();
@@ -433,7 +433,7 @@
 	struct nfs_writeverf first_verf;
 	struct nfs_write_data *wdata;
 
-	wdata = nfs_writedata_alloc();
+	wdata = nfs_writedata_alloc(NFS_SERVER(inode)->wpages);
 	if (!wdata)
 		return -ENOMEM;
 
@@ -662,10 +662,10 @@
 		.iov_len = count,
 	};
 
-	dprintk("nfs: direct read(%s/%s, %lu@%lu)\n",
+	dprintk("nfs: direct read(%s/%s, %lu@%Ld)\n",
 		file->f_dentry->d_parent->d_name.name,
 		file->f_dentry->d_name.name,
-		(unsigned long) count, (unsigned long) pos);
+		(unsigned long) count, (long long) pos);
 
 	if (!is_sync_kiocb(iocb))
 		goto out;
@@ -678,15 +678,9 @@
 	if (!count)
 		goto out;
 
-	if (mapping->nrpages) {
-		retval = filemap_fdatawrite(mapping);
-		if (retval == 0)
-			retval = nfs_wb_all(inode);
-		if (retval == 0)
-			retval = filemap_fdatawait(mapping);
-		if (retval)
-			goto out;
-	}
+	retval = nfs_sync_mapping(mapping);
+	if (retval)
+		goto out;
 
 	retval = nfs_direct_read(inode, ctx, &iov, pos, 1);
 	if (retval > 0)
@@ -724,9 +718,7 @@
 ssize_t
 nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
 {
-	ssize_t retval = -EINVAL;
-	loff_t *ppos = &iocb->ki_pos;
-	unsigned long limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+	ssize_t retval;
 	struct file *file = iocb->ki_filp;
 	struct nfs_open_context *ctx =
 			(struct nfs_open_context *) file->private_data;
@@ -734,51 +726,42 @@
 	struct inode *inode = mapping->host;
 	struct iovec iov = {
 		.iov_base = (char __user *)buf,
-		.iov_len = count,
 	};
 
-	dfprintk(VFS, "nfs: direct write(%s/%s(%ld), %lu@%lu)\n",
+	dfprintk(VFS, "nfs: direct write(%s/%s, %lu@%Ld)\n",
 		file->f_dentry->d_parent->d_name.name,
-		file->f_dentry->d_name.name, inode->i_ino,
-		(unsigned long) count, (unsigned long) pos);
+		file->f_dentry->d_name.name,
+		(unsigned long) count, (long long) pos);
 
+	retval = -EINVAL;
 	if (!is_sync_kiocb(iocb))
 		goto out;
-	if (count < 0)
+
+	retval = generic_write_checks(file, &pos, &count, 0);
+	if (retval)
 		goto out;
-        if (pos < 0)
+
+	retval = -EINVAL;
+	if ((ssize_t) count < 0)
 		goto out;
-	retval = -EFAULT;
-	if (!access_ok(VERIFY_READ, iov.iov_base, iov.iov_len))
-		goto out;
-	retval = -EFBIG;
-	if (limit != RLIM_INFINITY) {
-		if (pos >= limit) {
-			send_sig(SIGXFSZ, current, 0);
-			goto out;
-		}
-		if (count > limit - (unsigned long) pos)
-			count = limit - (unsigned long) pos;
-	}
 	retval = 0;
 	if (!count)
 		goto out;
+	iov.iov_len = count,
 
-	if (mapping->nrpages) {
-		retval = filemap_fdatawrite(mapping);
-		if (retval == 0)
-			retval = nfs_wb_all(inode);
-		if (retval == 0)
-			retval = filemap_fdatawait(mapping);
-		if (retval)
-			goto out;
-	}
+	retval = -EFAULT;
+	if (!access_ok(VERIFY_READ, iov.iov_base, iov.iov_len))
+		goto out;
+
+	retval = nfs_sync_mapping(mapping);
+	if (retval)
+		goto out;
 
 	retval = nfs_direct_write(inode, ctx, &iov, pos, 1);
 	if (mapping->nrpages)
 		invalidate_inode_pages2(mapping);
 	if (retval > 0)
-		*ppos = pos + retval;
+		iocb->ki_pos = pos + retval;
 
 out:
 	return retval;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 57d3e77..7a79fbe 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -433,11 +433,7 @@
 	 * Flush all pending writes before doing anything
 	 * with locks..
 	 */
-	filemap_fdatawrite(filp->f_mapping);
-	down(&inode->i_sem);
-	nfs_wb_all(inode);
-	up(&inode->i_sem);
-	filemap_fdatawait(filp->f_mapping);
+	nfs_sync_mapping(filp->f_mapping);
 
 	/* NOTE: special case
 	 * 	If we're signalled while cleaning up locks on process exit, we
@@ -465,15 +461,8 @@
 	 * Flush all pending writes before doing anything
 	 * with locks..
 	 */
-	status = filemap_fdatawrite(filp->f_mapping);
-	if (status == 0) {
-		down(&inode->i_sem);
-		status = nfs_wb_all(inode);
-		up(&inode->i_sem);
-		if (status == 0)
-			status = filemap_fdatawait(filp->f_mapping);
-	}
-	if (status < 0)
+	status = nfs_sync_mapping(filp->f_mapping);
+	if (status != 0)
 		goto out;
 
 	lock_kernel();
@@ -497,11 +486,7 @@
 	 * Make sure we clear the cache whenever we try to get the lock.
 	 * This makes locking act as a cache coherency point.
 	 */
-	filemap_fdatawrite(filp->f_mapping);
-	down(&inode->i_sem);
-	nfs_wb_all(inode);	/* we may have slept */
-	up(&inode->i_sem);
-	filemap_fdatawait(filp->f_mapping);
+	nfs_sync_mapping(filp->f_mapping);
 	nfs_zap_caches(inode);
 out:
 	rpc_clnt_sigunmask(NFS_CLIENT(inode), &oldset);
@@ -524,7 +509,8 @@
 		return -EINVAL;
 
 	/* No mandatory locks over NFS */
-	if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
+	if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
+	    fl->fl_type != F_UNLCK)
 		return -ENOLCK;
 
 	if (IS_GETLK(cmd))
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index ffb8df9..821edd3 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -54,7 +54,11 @@
 
 #define IDMAP_HASH_SZ          128
 
+/* Default cache timeout is 10 minutes */
+unsigned int nfs_idmap_cache_timeout = 600 * HZ;
+
 struct idmap_hashent {
+	unsigned long ih_expires;
 	__u32 ih_id;
 	int ih_namelen;
 	char ih_name[IDMAP_NAMESZ];
@@ -149,6 +153,8 @@
 
 	if (he->ih_namelen != len || memcmp(he->ih_name, name, len) != 0)
 		return NULL;
+	if (time_after(jiffies, he->ih_expires))
+		return NULL;
 	return he;
 }
 
@@ -164,6 +170,8 @@
 	struct idmap_hashent *he = idmap_id_hash(h, id);
 	if (he->ih_id != id || he->ih_namelen == 0)
 		return NULL;
+	if (time_after(jiffies, he->ih_expires))
+		return NULL;
 	return he;
 }
 
@@ -192,6 +200,7 @@
 	memcpy(he->ih_name, name, namelen);
 	he->ih_name[namelen] = '\0';
 	he->ih_namelen = namelen;
+	he->ih_expires = jiffies + nfs_idmap_cache_timeout;
 }
 
 /*
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index aaab1a5..3e4ba9c 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -40,6 +40,7 @@
 #include <asm/uaccess.h>
 
 #include "nfs4_fs.h"
+#include "callback.h"
 #include "delegation.h"
 
 #define NFSDBG_FACILITY		NFSDBG_VFS
@@ -54,7 +55,7 @@
 #define NFS_MAX_READAHEAD	(RPC_DEF_SLOT_TABLE - 1)
 
 static void nfs_invalidate_inode(struct inode *);
-static int nfs_update_inode(struct inode *, struct nfs_fattr *, unsigned long);
+static int nfs_update_inode(struct inode *, struct nfs_fattr *);
 
 static struct inode *nfs_alloc_inode(struct super_block *sb);
 static void nfs_destroy_inode(struct inode *);
@@ -221,10 +222,10 @@
 static inline unsigned long
 nfs_block_size(unsigned long bsize, unsigned char *nrbitsp)
 {
-	if (bsize < 1024)
-		bsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
-	else if (bsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
-		bsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
+	if (bsize < NFS_MIN_FILE_IO_SIZE)
+		bsize = NFS_DEF_FILE_IO_SIZE;
+	else if (bsize >= NFS_MAX_FILE_IO_SIZE)
+		bsize = NFS_MAX_FILE_IO_SIZE;
 
 	return nfs_block_bits(bsize, nrbitsp);
 }
@@ -307,20 +308,15 @@
 	max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
 	if (server->rsize > max_rpc_payload)
 		server->rsize = max_rpc_payload;
+	if (server->rsize > NFS_MAX_FILE_IO_SIZE)
+		server->rsize = NFS_MAX_FILE_IO_SIZE;
+	server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+
 	if (server->wsize > max_rpc_payload)
 		server->wsize = max_rpc_payload;
-
-	server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	if (server->rpages > NFS_READ_MAXIOV) {
-		server->rpages = NFS_READ_MAXIOV;
-		server->rsize = server->rpages << PAGE_CACHE_SHIFT;
-	}
-
+	if (server->wsize > NFS_MAX_FILE_IO_SIZE)
+		server->wsize = NFS_MAX_FILE_IO_SIZE;
 	server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-        if (server->wpages > NFS_WRITE_MAXIOV) {
-		server->wpages = NFS_WRITE_MAXIOV;
-                server->wsize = server->wpages << PAGE_CACHE_SHIFT;
-	}
 
 	if (sb->s_blocksize == 0)
 		sb->s_blocksize = nfs_block_bits(server->wsize,
@@ -417,7 +413,6 @@
 
 	clnt->cl_intr     = 1;
 	clnt->cl_softrtry = 1;
-	clnt->cl_chatty   = 1;
 
 	return clnt;
 
@@ -575,11 +570,10 @@
 	buf->f_namelen = server->namelen;
  out:
 	unlock_kernel();
-
 	return 0;
 
  out_err:
-	printk(KERN_WARNING "nfs_statfs: statfs error = %d\n", -error);
+	dprintk("%s: statfs error = %d\n", __FUNCTION__, -error);
 	buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1;
 	goto out;
 
@@ -640,6 +634,24 @@
 	return 0;
 }
 
+/**
+ * nfs_sync_mapping - helper to flush all mmapped dirty data to disk
+ */
+int nfs_sync_mapping(struct address_space *mapping)
+{
+	int ret;
+
+	if (mapping->nrpages == 0)
+		return 0;
+	unmap_mapping_range(mapping, 0, 0, 0);
+	ret = filemap_write_and_wait(mapping);
+	if (ret != 0)
+		goto out;
+	ret = nfs_wb_all(mapping->host);
+out:
+	return ret;
+}
+
 /*
  * Invalidate the local caches
  */
@@ -849,8 +861,7 @@
 	nfs_begin_data_update(inode);
 	/* Write all dirty data if we're changing file permissions or size */
 	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE)) != 0) {
-		if (filemap_fdatawrite(inode->i_mapping) == 0)
-			filemap_fdatawait(inode->i_mapping);
+		filemap_write_and_wait(inode->i_mapping);
 		nfs_wb_all(inode);
 	}
 	/*
@@ -937,6 +948,8 @@
 	int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
 	int err;
 
+	/* Flush out writes to the server in order to update c/mtime */
+	nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT);
 	if (__IS_FLG(inode, MS_NOATIME))
 		need_atime = 0;
 	else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode))
@@ -1080,8 +1093,6 @@
 	int		 status = -ESTALE;
 	struct nfs_fattr fattr;
 	struct nfs_inode *nfsi = NFS_I(inode);
-	unsigned long verifier;
-	unsigned long cache_validity;
 
 	dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n",
 		inode->i_sb->s_id, (long long)NFS_FILEID(inode));
@@ -1106,8 +1117,6 @@
 		}
 	}
 
-	/* Protect against RPC races by saving the change attribute */
-	verifier = nfs_save_change_attribute(inode);
 	status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
 	if (status != 0) {
 		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
@@ -1122,7 +1131,7 @@
 	}
 
 	spin_lock(&inode->i_lock);
-	status = nfs_update_inode(inode, &fattr, verifier);
+	status = nfs_update_inode(inode, &fattr);
 	if (status) {
 		spin_unlock(&inode->i_lock);
 		dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
@@ -1130,20 +1139,11 @@
 			 (long long)NFS_FILEID(inode), status);
 		goto out;
 	}
-	cache_validity = nfsi->cache_validity;
-	nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
-
-	/*
-	 * We may need to keep the attributes marked as invalid if
-	 * we raced with nfs_end_attr_update().
-	 */
-	if (time_after_eq(verifier, nfsi->cache_change_attribute))
-		nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
 	spin_unlock(&inode->i_lock);
 
 	nfs_revalidate_mapping(inode, inode->i_mapping);
 
-	if (cache_validity & NFS_INO_INVALID_ACL)
+	if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
 		nfs_zap_acl_cache(inode);
 
 	dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
@@ -1192,11 +1192,8 @@
 	struct nfs_inode *nfsi = NFS_I(inode);
 
 	if (nfsi->cache_validity & NFS_INO_INVALID_DATA) {
-		if (S_ISREG(inode->i_mode)) {
-			if (filemap_fdatawrite(mapping) == 0)
-				filemap_fdatawait(mapping);
-			nfs_wb_all(inode);
-		}
+		if (S_ISREG(inode->i_mode))
+			nfs_sync_mapping(mapping);
 		invalidate_inode_pages2(mapping);
 
 		spin_lock(&inode->i_lock);
@@ -1247,6 +1244,33 @@
 	atomic_dec(&nfsi->data_updates);
 }
 
+static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+	struct nfs_inode *nfsi = NFS_I(inode);
+
+	if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0
+			&& nfsi->change_attr == fattr->pre_change_attr) {
+		nfsi->change_attr = fattr->change_attr;
+		nfsi->cache_change_attribute = jiffies;
+	}
+
+	/* If we have atomic WCC data, we may update some attributes */
+	if ((fattr->valid & NFS_ATTR_WCC) != 0) {
+		if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) {
+			memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
+			nfsi->cache_change_attribute = jiffies;
+		}
+		if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {
+			memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
+			nfsi->cache_change_attribute = jiffies;
+		}
+		if (inode->i_size == fattr->pre_size && nfsi->npages == 0) {
+			inode->i_size = fattr->size;
+			nfsi->cache_change_attribute = jiffies;
+		}
+	}
+}
+
 /**
  * nfs_check_inode_attributes - verify consistency of the inode attribute cache
  * @inode - pointer to inode
@@ -1263,22 +1287,20 @@
 	int data_unstable;
 
 
+	if ((fattr->valid & NFS_ATTR_FATTR) == 0)
+		return 0;
+
 	/* Are we in the process of updating data on the server? */
 	data_unstable = nfs_caches_unstable(inode);
 
-	if (fattr->valid & NFS_ATTR_FATTR_V4) {
-		if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0
-				&& nfsi->change_attr == fattr->pre_change_attr)
-			nfsi->change_attr = fattr->change_attr;
-		if (nfsi->change_attr != fattr->change_attr) {
-			nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
-			if (!data_unstable)
-				nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
-		}
-	}
+	/* Do atomic weak cache consistency updates */
+	nfs_wcc_update_inode(inode, fattr);
 
-	if ((fattr->valid & NFS_ATTR_FATTR) == 0) {
-		return 0;
+	if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
+			nfsi->change_attr != fattr->change_attr) {
+		nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
+		if (!data_unstable)
+			nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
 	}
 
 	/* Has the inode gone and changed behind our back? */
@@ -1290,14 +1312,6 @@
 	cur_size = i_size_read(inode);
  	new_isize = nfs_size_to_loff_t(fattr->size);
 
-	/* If we have atomic WCC data, we may update some attributes */
-	if ((fattr->valid & NFS_ATTR_WCC) != 0) {
-		if (timespec_equal(&inode->i_ctime, &fattr->pre_ctime))
-			memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
-		if (timespec_equal(&inode->i_mtime, &fattr->pre_mtime))
-			memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
-	}
-
 	/* Verify a few of the more important attributes */
 	if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
 		nfsi->cache_validity |= NFS_INO_INVALID_ATTR;
@@ -1346,10 +1360,8 @@
 		return 0;
 	spin_lock(&inode->i_lock);
 	nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
-	if (nfs_verify_change_attribute(inode, fattr->time_start))
-		nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
 	if (time_after(fattr->time_start, nfsi->last_updated))
-		status = nfs_update_inode(inode, fattr, fattr->time_start);
+		status = nfs_update_inode(inode, fattr);
 	else
 		status = nfs_check_inode_attributes(inode, fattr);
 
@@ -1375,10 +1387,7 @@
 		nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS;
 		goto out;
 	}
-	status = nfs_update_inode(inode, fattr, fattr->time_start);
-	if (time_after_eq(fattr->time_start, nfsi->cache_change_attribute))
-		nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
-	nfsi->cache_change_attribute = jiffies;
+	status = nfs_update_inode(inode, fattr);
 out:
 	spin_unlock(&inode->i_lock);
 	return status;
@@ -1396,12 +1405,12 @@
  *
  * A very similar scenario holds for the dir cache.
  */
-static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsigned long verifier)
+static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
 	loff_t cur_isize, new_isize;
 	unsigned int	invalid = 0;
-	int data_unstable;
+	int data_stable;
 
 	dfprintk(VFS, "NFS: %s(%s/%ld ct=%d info=0x%x)\n",
 			__FUNCTION__, inode->i_sb->s_id, inode->i_ino,
@@ -1410,14 +1419,8 @@
 	if ((fattr->valid & NFS_ATTR_FATTR) == 0)
 		return 0;
 
-	if (nfsi->fileid != fattr->fileid) {
-		printk(KERN_ERR "%s: inode number mismatch\n"
-		       "expected (%s/0x%Lx), got (%s/0x%Lx)\n",
-		       __FUNCTION__,
-		       inode->i_sb->s_id, (long long)nfsi->fileid,
-		       inode->i_sb->s_id, (long long)fattr->fileid);
-		goto out_err;
-	}
+	if (nfsi->fileid != fattr->fileid)
+		goto out_fileid;
 
 	/*
 	 * Make sure the inode's type hasn't changed.
@@ -1432,8 +1435,12 @@
 	nfsi->last_updated = jiffies;
 
 	/* Are we racing with known updates of the metadata on the server? */
-	data_unstable = ! (nfs_verify_change_attribute(inode, verifier) ||
-		(nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE));
+	data_stable = nfs_verify_change_attribute(inode, fattr->time_start);
+	if (data_stable)
+		nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
+
+	/* Do atomic weak cache consistency updates */
+	nfs_wcc_update_inode(inode, fattr);
 
 	/* Check if our cached file size is stale */
  	new_isize = nfs_size_to_loff_t(fattr->size);
@@ -1442,7 +1449,7 @@
 		/* Do we perhaps have any outstanding writes? */
 		if (nfsi->npages == 0) {
 			/* No, but did we race with nfs_end_data_update()? */
-			if (time_after_eq(verifier,  nfsi->cache_change_attribute)) {
+			if (data_stable) {
 				inode->i_size = new_isize;
 				invalid |= NFS_INO_INVALID_DATA;
 			}
@@ -1451,6 +1458,7 @@
 			inode->i_size = new_isize;
 			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
 		}
+		nfsi->cache_change_attribute = jiffies;
 		dprintk("NFS: isize change on server for file %s/%ld\n",
 				inode->i_sb->s_id, inode->i_ino);
 	}
@@ -1460,8 +1468,8 @@
 		memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
 		dprintk("NFS: mtime change on server for file %s/%ld\n",
 				inode->i_sb->s_id, inode->i_ino);
-		if (!data_unstable)
-			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
+		invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
+		nfsi->cache_change_attribute = jiffies;
 	}
 
 	if ((fattr->valid & NFS_ATTR_FATTR_V4)
@@ -1469,15 +1477,15 @@
 		dprintk("NFS: change_attr change on server for file %s/%ld\n",
 		       inode->i_sb->s_id, inode->i_ino);
 		nfsi->change_attr = fattr->change_attr;
-		if (!data_unstable)
-			invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+		invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+		nfsi->cache_change_attribute = jiffies;
 	}
 
 	/* If ctime has changed we should definitely clear access+acl caches */
 	if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) {
-		if (!data_unstable)
-			invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+		invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
 		memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
+		nfsi->cache_change_attribute = jiffies;
 	}
 	memcpy(&inode->i_atime, &fattr->atime, sizeof(inode->i_atime));
 
@@ -1515,6 +1523,8 @@
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
 				|| S_ISLNK(inode->i_mode)))
 		invalid &= ~NFS_INO_INVALID_DATA;
+	if (data_stable)
+		invalid &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME|NFS_INO_REVAL_PAGECACHE);
 	if (!nfs_have_delegation(inode, FMODE_READ))
 		nfsi->cache_validity |= invalid;
 
@@ -1535,6 +1545,13 @@
 	 */
 	nfs_invalidate_inode(inode);
 	return -ESTALE;
+
+ out_fileid:
+	printk(KERN_ERR "NFS: server %s error: fileid changed\n"
+		"fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
+		NFS_SERVER(inode)->hostname, inode->i_sb->s_id,
+		(long long)nfsi->fileid, (long long)fattr->fileid);
+	goto out_err;
 }
 
 /*
@@ -1816,25 +1833,10 @@
 		}
 		clnt->cl_intr     = 1;
 		clnt->cl_softrtry = 1;
-		clnt->cl_chatty   = 1;
 		clp->cl_rpcclient = clnt;
-		clp->cl_cred = rpcauth_lookupcred(clnt->cl_auth, 0);
-		if (IS_ERR(clp->cl_cred)) {
-			up_write(&clp->cl_sem);
-			err = PTR_ERR(clp->cl_cred);
-			clp->cl_cred = NULL;
-			goto out_fail;
-		}
 		memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
 		nfs_idmap_new(clp);
 	}
-	if (list_empty(&clp->cl_superblocks)) {
-		err = nfs4_init_client(clp);
-		if (err != 0) {
-			up_write(&clp->cl_sem);
-			goto out_fail;
-		}
-	}
 	list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
 	clnt = rpc_clone_client(clp->cl_rpcclient);
 	if (!IS_ERR(clnt))
@@ -2029,6 +2031,35 @@
 	.fs_flags	= FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
 };
 
+static const int nfs_set_port_min = 0;
+static const int nfs_set_port_max = 65535;
+static int param_set_port(const char *val, struct kernel_param *kp)
+{
+	char *endp;
+	int num = simple_strtol(val, &endp, 0);
+	if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max)
+		return -EINVAL;
+	*((int *)kp->arg) = num;
+	return 0;
+}
+
+module_param_call(callback_tcpport, param_set_port, param_get_int,
+		 &nfs_callback_set_tcpport, 0644);
+
+static int param_set_idmap_timeout(const char *val, struct kernel_param *kp)
+{
+	char *endp;
+	int num = simple_strtol(val, &endp, 0);
+	int jif = num * HZ;
+	if (endp == val || *endp || num < 0 || jif < num)
+		return -EINVAL;
+	*((int *)kp->arg) = jif;
+	return 0;
+}
+
+module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int,
+		 &nfs_idmap_cache_timeout, 0644);
+
 #define nfs4_init_once(nfsi) \
 	do { \
 		INIT_LIST_HEAD(&(nfsi)->open_states); \
@@ -2036,8 +2067,25 @@
 		nfsi->delegation_state = 0; \
 		init_rwsem(&nfsi->rwsem); \
 	} while(0)
-#define register_nfs4fs() register_filesystem(&nfs4_fs_type)
-#define unregister_nfs4fs() unregister_filesystem(&nfs4_fs_type)
+
+static inline int register_nfs4fs(void)
+{
+	int ret;
+
+	ret = nfs_register_sysctl();
+	if (ret != 0)
+		return ret;
+	ret = register_filesystem(&nfs4_fs_type);
+	if (ret != 0)
+		nfs_unregister_sysctl();
+	return ret;
+}
+
+static inline void unregister_nfs4fs(void)
+{
+	unregister_filesystem(&nfs4_fs_type);
+	nfs_unregister_sysctl();
+}
 #else
 #define nfs4_init_once(nfsi) \
 	do { } while (0)
@@ -2066,6 +2114,7 @@
 		return NULL;
 	nfsi->flags = 0UL;
 	nfsi->cache_validity = 0UL;
+	nfsi->cache_change_attribute = jiffies;
 #ifdef CONFIG_NFS_V3_ACL
 	nfsi->acl_access = ERR_PTR(-EAGAIN);
 	nfsi->acl_default = ERR_PTR(-EAGAIN);
@@ -2161,11 +2210,11 @@
 #ifdef CONFIG_PROC_FS
 	rpc_proc_unregister("nfs");
 #endif
-	nfs_destroy_writepagecache();
 #ifdef CONFIG_NFS_DIRECTIO
-out0:
 	nfs_destroy_directcache();
+out0:
 #endif
+	nfs_destroy_writepagecache();
 out1:
 	nfs_destroy_readpagecache();
 out2:
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 0e82617..db99b8f 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -82,7 +82,6 @@
 				RPC_AUTH_UNIX);
 	if (!IS_ERR(clnt)) {
 		clnt->cl_softrtry = 1;
-		clnt->cl_chatty   = 1;
 		clnt->cl_oneshot  = 1;
 		clnt->cl_intr = 1;
 	}
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 59049e8..7fc0560 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -146,23 +146,23 @@
 	return p;
 }
 
-#define SATTR(p, attr, flag, field) \
-        *p++ = (attr->ia_valid & flag) ? htonl(attr->field) : ~(u32) 0
 static inline u32 *
 xdr_encode_sattr(u32 *p, struct iattr *attr)
 {
-	SATTR(p, attr, ATTR_MODE, ia_mode);
-	SATTR(p, attr, ATTR_UID, ia_uid);
-	SATTR(p, attr, ATTR_GID, ia_gid);
-	SATTR(p, attr, ATTR_SIZE, ia_size);
+	const u32 not_set = __constant_htonl(0xFFFFFFFF);
+
+	*p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set;
+	*p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set;
+	*p++ = (attr->ia_valid & ATTR_GID) ? htonl(attr->ia_gid) : not_set;
+	*p++ = (attr->ia_valid & ATTR_SIZE) ? htonl(attr->ia_size) : not_set;
 
 	if (attr->ia_valid & ATTR_ATIME_SET) {
 		p = xdr_encode_time(p, &attr->ia_atime);
 	} else if (attr->ia_valid & ATTR_ATIME) {
 		p = xdr_encode_current_server_time(p, &attr->ia_atime);
 	} else {
-		*p++ = ~(u32) 0;
-		*p++ = ~(u32) 0;
+		*p++ = not_set;
+		*p++ = not_set;
 	}
 
 	if (attr->ia_valid & ATTR_MTIME_SET) {
@@ -170,12 +170,11 @@
 	} else if (attr->ia_valid & ATTR_MTIME) {
 		p = xdr_encode_current_server_time(p, &attr->ia_mtime);
 	} else {
-		*p++ = ~(u32) 0;	
-		*p++ = ~(u32) 0;
+		*p++ = not_set;	
+		*p++ = not_set;
 	}
   	return p;
 }
-#undef SATTR
 
 /*
  * NFS encode functions
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 92c870d..ed67567 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -68,6 +68,23 @@
 	return 1;
 }
 
+static int
+do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
+		 struct nfs_fsinfo *info)
+{
+	int	status;
+
+	dprintk("%s: call  fsinfo\n", __FUNCTION__);
+	nfs_fattr_init(info->fattr);
+	status = rpc_call(client, NFS3PROC_FSINFO, fhandle, info, 0);
+	dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status);
+	if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
+		status = rpc_call(client, NFS3PROC_GETATTR, fhandle, info->fattr, 0);
+		dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
+	}
+	return status;
+}
+
 /*
  * Bare-bones access to getattr: this is for nfs_read_super.
  */
@@ -77,14 +94,9 @@
 {
 	int	status;
 
-	dprintk("%s: call  fsinfo\n", __FUNCTION__);
-	nfs_fattr_init(info->fattr);
-	status = rpc_call(server->client_sys, NFS3PROC_FSINFO, fhandle, info, 0);
-	dprintk("%s: reply fsinfo: %d\n", __FUNCTION__, status);
-	if (!(info->fattr->valid & NFS_ATTR_FATTR)) {
-		status = rpc_call(server->client_sys, NFS3PROC_GETATTR, fhandle, info->fattr, 0);
-		dprintk("%s: reply getattr: %d\n", __FUNCTION__, status);
-	}
+	status = do_proc_get_root(server->client, fhandle, info);
+	if (status && server->client_sys != server->client)
+		status = do_proc_get_root(server->client_sys, fhandle, info);
 	return status;
 }
 
@@ -732,19 +744,23 @@
 
 extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
 
-static void
-nfs3_read_done(struct rpc_task *task)
+static void nfs3_read_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
+	struct nfs_read_data *data = calldata;
 
 	if (nfs3_async_handle_jukebox(task))
 		return;
 	/* Call back common NFS readpage processing */
 	if (task->tk_status >= 0)
 		nfs_refresh_inode(data->inode, &data->fattr);
-	nfs_readpage_result(task);
+	nfs_readpage_result(task, calldata);
 }
 
+static const struct rpc_call_ops nfs3_read_ops = {
+	.rpc_call_done = nfs3_read_done,
+	.rpc_release = nfs_readdata_release,
+};
+
 static void
 nfs3_proc_read_setup(struct nfs_read_data *data)
 {
@@ -762,23 +778,26 @@
 	flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs3_read_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs3_read_ops, data);
 	rpc_call_setup(task, &msg, 0);
 }
 
-static void
-nfs3_write_done(struct rpc_task *task)
+static void nfs3_write_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_write_data *data;
+	struct nfs_write_data *data = calldata;
 
 	if (nfs3_async_handle_jukebox(task))
 		return;
-	data = (struct nfs_write_data *)task->tk_calldata;
 	if (task->tk_status >= 0)
 		nfs_post_op_update_inode(data->inode, data->res.fattr);
-	nfs_writeback_done(task);
+	nfs_writeback_done(task, calldata);
 }
 
+static const struct rpc_call_ops nfs3_write_ops = {
+	.rpc_call_done = nfs3_write_done,
+	.rpc_release = nfs_writedata_release,
+};
+
 static void
 nfs3_proc_write_setup(struct nfs_write_data *data, int how)
 {
@@ -806,23 +825,26 @@
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs3_write_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs3_write_ops, data);
 	rpc_call_setup(task, &msg, 0);
 }
 
-static void
-nfs3_commit_done(struct rpc_task *task)
+static void nfs3_commit_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_write_data *data;
+	struct nfs_write_data *data = calldata;
 
 	if (nfs3_async_handle_jukebox(task))
 		return;
-	data = (struct nfs_write_data *)task->tk_calldata;
 	if (task->tk_status >= 0)
 		nfs_post_op_update_inode(data->inode, data->res.fattr);
-	nfs_commit_done(task);
+	nfs_commit_done(task, calldata);
 }
 
+static const struct rpc_call_ops nfs3_commit_ops = {
+	.rpc_call_done = nfs3_commit_done,
+	.rpc_release = nfs_commit_release,
+};
+
 static void
 nfs3_proc_commit_setup(struct nfs_write_data *data, int how)
 {
@@ -840,7 +862,7 @@
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs3_commit_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs3_commit_ops, data);
 	rpc_call_setup(task, &msg, 0);
 }
 
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 0498bd3..b6c0b50 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -182,7 +182,7 @@
 {
 	if (attr->ia_valid & ATTR_MODE) {
 		*p++ = xdr_one;
-		*p++ = htonl(attr->ia_mode);
+		*p++ = htonl(attr->ia_mode & S_IALLUGO);
 	} else {
 		*p++ = xdr_zero;
 	}
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index b7f262d..0f5e4e7 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -38,7 +38,8 @@
  ((err) != NFSERR_NOFILEHANDLE))
 
 enum nfs4_client_state {
-	NFS4CLNT_OK  = 0,
+	NFS4CLNT_STATE_RECOVER  = 0,
+	NFS4CLNT_LEASE_EXPIRED,
 };
 
 /*
@@ -67,7 +68,6 @@
 	atomic_t		cl_count;
 
 	struct rpc_clnt *	cl_rpcclient;
-	struct rpc_cred *	cl_cred;
 
 	struct list_head	cl_superblocks;	/* List of nfs_server structs */
 
@@ -76,7 +76,6 @@
 	struct work_struct	cl_renewd;
 	struct work_struct	cl_recoverd;
 
-	wait_queue_head_t	cl_waitq;
 	struct rpc_wait_queue	cl_rpcwaitq;
 
 	/* used for the setclientid verifier */
@@ -182,8 +181,9 @@
 
 	nfs4_stateid stateid;
 
-	unsigned int nreaders;
-	unsigned int nwriters;
+	unsigned int n_rdonly;
+	unsigned int n_wronly;
+	unsigned int n_rdwr;
 	int state;			/* State on the server (R,W, or RW) */
 	atomic_t count;
 };
@@ -210,10 +210,10 @@
 
 /* nfs4proc.c */
 extern int nfs4_map_errors(int err);
-extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short);
-extern int nfs4_proc_setclientid_confirm(struct nfs4_client *);
-extern int nfs4_proc_async_renew(struct nfs4_client *);
-extern int nfs4_proc_renew(struct nfs4_client *);
+extern int nfs4_proc_setclientid(struct nfs4_client *, u32, unsigned short, struct rpc_cred *);
+extern int nfs4_proc_setclientid_confirm(struct nfs4_client *, struct rpc_cred *);
+extern int nfs4_proc_async_renew(struct nfs4_client *, struct rpc_cred *);
+extern int nfs4_proc_renew(struct nfs4_client *, struct rpc_cred *);
 extern int nfs4_do_close(struct inode *inode, struct nfs4_state *state);
 extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
 extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
@@ -237,8 +237,8 @@
 extern void destroy_nfsv4_state(struct nfs_server *);
 extern struct nfs4_client *nfs4_get_client(struct in_addr *);
 extern void nfs4_put_client(struct nfs4_client *clp);
-extern int nfs4_init_client(struct nfs4_client *clp);
 extern struct nfs4_client *nfs4_find_client(struct in_addr *);
+struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp);
 extern u32 nfs4_alloc_lockowner_id(struct nfs4_client *);
 
 extern struct nfs4_state_owner * nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 60e0dd8..984ca34 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -57,11 +57,13 @@
 #define NFS4_POLL_RETRY_MIN	(1*HZ)
 #define NFS4_POLL_RETRY_MAX	(15*HZ)
 
-static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid);
+struct nfs4_opendata;
+static int _nfs4_proc_open(struct nfs4_opendata *data);
 static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
 static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *);
 static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
 static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
+static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp);
 extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
 extern struct rpc_procinfo nfs4_procedures[];
 
@@ -173,8 +175,7 @@
 	kunmap_atomic(start, KM_USER0);
 }
 
-static void
-renew_lease(struct nfs_server *server, unsigned long timestamp)
+static void renew_lease(const struct nfs_server *server, unsigned long timestamp)
 {
 	struct nfs4_client *clp = server->nfs4_state;
 	spin_lock(&clp->cl_lock);
@@ -194,21 +195,123 @@
 	spin_unlock(&inode->i_lock);
 }
 
+struct nfs4_opendata {
+	atomic_t count;
+	struct nfs_openargs o_arg;
+	struct nfs_openres o_res;
+	struct nfs_open_confirmargs c_arg;
+	struct nfs_open_confirmres c_res;
+	struct nfs_fattr f_attr;
+	struct nfs_fattr dir_attr;
+	struct dentry *dentry;
+	struct dentry *dir;
+	struct nfs4_state_owner *owner;
+	struct iattr attrs;
+	unsigned long timestamp;
+	int rpc_status;
+	int cancelled;
+};
+
+static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
+		struct nfs4_state_owner *sp, int flags,
+		const struct iattr *attrs)
+{
+	struct dentry *parent = dget_parent(dentry);
+	struct inode *dir = parent->d_inode;
+	struct nfs_server *server = NFS_SERVER(dir);
+	struct nfs4_opendata *p;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (p == NULL)
+		goto err;
+	p->o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
+	if (p->o_arg.seqid == NULL)
+		goto err_free;
+	atomic_set(&p->count, 1);
+	p->dentry = dget(dentry);
+	p->dir = parent;
+	p->owner = sp;
+	atomic_inc(&sp->so_count);
+	p->o_arg.fh = NFS_FH(dir);
+	p->o_arg.open_flags = flags,
+	p->o_arg.clientid = server->nfs4_state->cl_clientid;
+	p->o_arg.id = sp->so_id;
+	p->o_arg.name = &dentry->d_name;
+	p->o_arg.server = server;
+	p->o_arg.bitmask = server->attr_bitmask;
+	p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
+	p->o_res.f_attr = &p->f_attr;
+	p->o_res.dir_attr = &p->dir_attr;
+	p->o_res.server = server;
+	nfs_fattr_init(&p->f_attr);
+	nfs_fattr_init(&p->dir_attr);
+	if (flags & O_EXCL) {
+		u32 *s = (u32 *) p->o_arg.u.verifier.data;
+		s[0] = jiffies;
+		s[1] = current->pid;
+	} else if (flags & O_CREAT) {
+		p->o_arg.u.attrs = &p->attrs;
+		memcpy(&p->attrs, attrs, sizeof(p->attrs));
+	}
+	p->c_arg.fh = &p->o_res.fh;
+	p->c_arg.stateid = &p->o_res.stateid;
+	p->c_arg.seqid = p->o_arg.seqid;
+	return p;
+err_free:
+	kfree(p);
+err:
+	dput(parent);
+	return NULL;
+}
+
+static void nfs4_opendata_free(struct nfs4_opendata *p)
+{
+	if (p != NULL && atomic_dec_and_test(&p->count)) {
+		nfs_free_seqid(p->o_arg.seqid);
+		nfs4_put_state_owner(p->owner);
+		dput(p->dir);
+		dput(p->dentry);
+		kfree(p);
+	}
+}
+
 /* Helper for asynchronous RPC calls */
-static int nfs4_call_async(struct rpc_clnt *clnt, rpc_action tk_begin,
-		rpc_action tk_exit, void *calldata)
+static int nfs4_call_async(struct rpc_clnt *clnt,
+		const struct rpc_call_ops *tk_ops, void *calldata)
 {
 	struct rpc_task *task;
 
-	if (!(task = rpc_new_task(clnt, tk_exit, RPC_TASK_ASYNC)))
+	if (!(task = rpc_new_task(clnt, RPC_TASK_ASYNC, tk_ops, calldata)))
 		return -ENOMEM;
-
-	task->tk_calldata = calldata;
-	task->tk_action = tk_begin;
 	rpc_execute(task);
 	return 0;
 }
 
+static int nfs4_wait_for_completion_rpc_task(struct rpc_task *task)
+{
+	sigset_t oldset;
+	int ret;
+
+	rpc_clnt_sigmask(task->tk_client, &oldset);
+	ret = rpc_wait_for_completion_task(task);
+	rpc_clnt_sigunmask(task->tk_client, &oldset);
+	return ret;
+}
+
+static inline void update_open_stateflags(struct nfs4_state *state, mode_t open_flags)
+{
+	switch (open_flags) {
+		case FMODE_WRITE:
+			state->n_wronly++;
+			break;
+		case FMODE_READ:
+			state->n_rdonly++;
+			break;
+		case FMODE_READ|FMODE_WRITE:
+			state->n_rdwr++;
+	}
+}
+
 static void update_open_stateid(struct nfs4_state *state, nfs4_stateid *stateid, int open_flags)
 {
 	struct inode *inode = state->inode;
@@ -218,41 +321,134 @@
 	spin_lock(&state->owner->so_lock);
 	spin_lock(&inode->i_lock);
 	memcpy(&state->stateid, stateid, sizeof(state->stateid));
-	if ((open_flags & FMODE_WRITE))
-		state->nwriters++;
-	if (open_flags & FMODE_READ)
-		state->nreaders++;
+	update_open_stateflags(state, open_flags);
 	nfs4_state_set_mode_locked(state, state->state | open_flags);
 	spin_unlock(&inode->i_lock);
 	spin_unlock(&state->owner->so_lock);
 }
 
+static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
+{
+	struct inode *inode;
+	struct nfs4_state *state = NULL;
+
+	if (!(data->f_attr.valid & NFS_ATTR_FATTR))
+		goto out;
+	inode = nfs_fhget(data->dir->d_sb, &data->o_res.fh, &data->f_attr);
+	if (inode == NULL)
+		goto out;
+	state = nfs4_get_open_state(inode, data->owner);
+	if (state == NULL)
+		goto put_inode;
+	update_open_stateid(state, &data->o_res.stateid, data->o_arg.open_flags);
+put_inode:
+	iput(inode);
+out:
+	return state;
+}
+
+static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state)
+{
+	struct nfs_inode *nfsi = NFS_I(state->inode);
+	struct nfs_open_context *ctx;
+
+	spin_lock(&state->inode->i_lock);
+	list_for_each_entry(ctx, &nfsi->open_files, list) {
+		if (ctx->state != state)
+			continue;
+		get_nfs_open_context(ctx);
+		spin_unlock(&state->inode->i_lock);
+		return ctx;
+	}
+	spin_unlock(&state->inode->i_lock);
+	return ERR_PTR(-ENOENT);
+}
+
+static int nfs4_open_recover_helper(struct nfs4_opendata *opendata, mode_t openflags, nfs4_stateid *stateid)
+{
+	int ret;
+
+	opendata->o_arg.open_flags = openflags;
+	ret = _nfs4_proc_open(opendata);
+	if (ret != 0)
+		return ret; 
+	memcpy(stateid->data, opendata->o_res.stateid.data,
+			sizeof(stateid->data));
+	return 0;
+}
+
+static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *state)
+{
+	nfs4_stateid stateid;
+	struct nfs4_state *newstate;
+	int mode = 0;
+	int delegation = 0;
+	int ret;
+
+	/* memory barrier prior to reading state->n_* */
+	smp_rmb();
+	if (state->n_rdwr != 0) {
+		ret = nfs4_open_recover_helper(opendata, FMODE_READ|FMODE_WRITE, &stateid);
+		if (ret != 0)
+			return ret;
+		mode |= FMODE_READ|FMODE_WRITE;
+		if (opendata->o_res.delegation_type != 0)
+			delegation = opendata->o_res.delegation_type;
+		smp_rmb();
+	}
+	if (state->n_wronly != 0) {
+		ret = nfs4_open_recover_helper(opendata, FMODE_WRITE, &stateid);
+		if (ret != 0)
+			return ret;
+		mode |= FMODE_WRITE;
+		if (opendata->o_res.delegation_type != 0)
+			delegation = opendata->o_res.delegation_type;
+		smp_rmb();
+	}
+	if (state->n_rdonly != 0) {
+		ret = nfs4_open_recover_helper(opendata, FMODE_READ, &stateid);
+		if (ret != 0)
+			return ret;
+		mode |= FMODE_READ;
+	}
+	clear_bit(NFS_DELEGATED_STATE, &state->flags);
+	if (mode == 0)
+		return 0;
+	if (opendata->o_res.delegation_type == 0)
+		opendata->o_res.delegation_type = delegation;
+	opendata->o_arg.open_flags |= mode;
+	newstate = nfs4_opendata_to_nfs4_state(opendata);
+	if (newstate != NULL) {
+		if (opendata->o_res.delegation_type != 0) {
+			struct nfs_inode *nfsi = NFS_I(newstate->inode);
+			int delegation_flags = 0;
+			if (nfsi->delegation)
+				delegation_flags = nfsi->delegation->flags;
+			if (!(delegation_flags & NFS_DELEGATION_NEED_RECLAIM))
+				nfs_inode_set_delegation(newstate->inode,
+						opendata->owner->so_cred,
+						&opendata->o_res);
+			else
+				nfs_inode_reclaim_delegation(newstate->inode,
+						opendata->owner->so_cred,
+						&opendata->o_res);
+		}
+		nfs4_close_state(newstate, opendata->o_arg.open_flags);
+	}
+	if (newstate != state)
+		return -ESTALE;
+	return 0;
+}
+
 /*
  * OPEN_RECLAIM:
  * 	reclaim state on the server after a reboot.
  */
-static int _nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
+static int _nfs4_do_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
 {
-	struct inode *inode = state->inode;
-	struct nfs_server *server = NFS_SERVER(inode);
-	struct nfs_delegation *delegation = NFS_I(inode)->delegation;
-	struct nfs_openargs o_arg = {
-		.fh = NFS_FH(inode),
-		.id = sp->so_id,
-		.open_flags = state->state,
-		.clientid = server->nfs4_state->cl_clientid,
-		.claim = NFS4_OPEN_CLAIM_PREVIOUS,
-		.bitmask = server->attr_bitmask,
-	};
-	struct nfs_openres o_res = {
-		.server = server,	/* Grrr */
-	};
-	struct rpc_message msg = {
-		.rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR],
-		.rpc_argp       = &o_arg,
-		.rpc_resp	= &o_res,
-		.rpc_cred	= sp->so_cred,
-	};
+	struct nfs_delegation *delegation = NFS_I(state->inode)->delegation;
+	struct nfs4_opendata *opendata;
+	int delegation_type = 0;
 	int status;
 
 	if (delegation != NULL) {
@@ -262,38 +458,27 @@
 			set_bit(NFS_DELEGATED_STATE, &state->flags);
 			return 0;
 		}
-		o_arg.u.delegation_type = delegation->type;
+		delegation_type = delegation->type;
 	}
-	o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
-	if (o_arg.seqid == NULL)
+	opendata = nfs4_opendata_alloc(dentry, sp, 0, NULL);
+	if (opendata == NULL)
 		return -ENOMEM;
-	status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
-	/* Confirm the sequence as being established */
-	nfs_confirm_seqid(&sp->so_seqid, status);
-	nfs_increment_open_seqid(status, o_arg.seqid);
-	if (status == 0) {
-		memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid));
-		if (o_res.delegation_type != 0) {
-			nfs_inode_reclaim_delegation(inode, sp->so_cred, &o_res);
-			/* Did the server issue an immediate delegation recall? */
-			if (o_res.do_recall)
-				nfs_async_inode_return_delegation(inode, &o_res.stateid);
-		}
-	}
-	nfs_free_seqid(o_arg.seqid);
-	clear_bit(NFS_DELEGATED_STATE, &state->flags);
-	/* Ensure we update the inode attributes */
-	NFS_CACHEINV(inode);
+	opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS;
+	opendata->o_arg.fh = NFS_FH(state->inode);
+	nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh);
+	opendata->o_arg.u.delegation_type = delegation_type;
+	status = nfs4_open_recover(opendata, state);
+	nfs4_opendata_free(opendata);
 	return status;
 }
 
-static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
+static int nfs4_do_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
 	struct nfs4_exception exception = { };
 	int err;
 	do {
-		err = _nfs4_open_reclaim(sp, state);
+		err = _nfs4_do_open_reclaim(sp, state, dentry);
 		if (err != -NFS4ERR_DELAY)
 			break;
 		nfs4_handle_exception(server, err, &exception);
@@ -301,63 +486,36 @@
 	return err;
 }
 
+static int nfs4_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state)
+{
+	struct nfs_open_context *ctx;
+	int ret;
+
+	ctx = nfs4_state_find_open_context(state);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+	ret = nfs4_do_open_reclaim(sp, state, ctx->dentry);
+	put_nfs_open_context(ctx);
+	return ret;
+}
+
 static int _nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
 {
 	struct nfs4_state_owner  *sp  = state->owner;
-	struct inode *inode = dentry->d_inode;
-	struct nfs_server *server = NFS_SERVER(inode);
-	struct dentry *parent = dget_parent(dentry);
-	struct nfs_openargs arg = {
-		.fh = NFS_FH(parent->d_inode),
-		.clientid = server->nfs4_state->cl_clientid,
-		.name = &dentry->d_name,
-		.id = sp->so_id,
-		.server = server,
-		.bitmask = server->attr_bitmask,
-		.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR,
-	};
-	struct nfs_openres res = {
-		.server = server,
-	};
-	struct 	rpc_message msg = {
-		.rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR],
-		.rpc_argp       = &arg,
-		.rpc_resp       = &res,
-		.rpc_cred	= sp->so_cred,
-	};
-	int status = 0;
+	struct nfs4_opendata *opendata;
+	int ret;
 
 	if (!test_bit(NFS_DELEGATED_STATE, &state->flags))
-		goto out;
-	if (state->state == 0)
-		goto out;
-	arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
-	status = -ENOMEM;
-	if (arg.seqid == NULL)
-		goto out;
-	arg.open_flags = state->state;
-	memcpy(arg.u.delegation.data, state->stateid.data, sizeof(arg.u.delegation.data));
-	status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
-	nfs_increment_open_seqid(status, arg.seqid);
-	if (status != 0)
-		goto out_free;
-	if(res.rflags & NFS4_OPEN_RESULT_CONFIRM) {
-		status = _nfs4_proc_open_confirm(server->client, NFS_FH(inode),
-				sp, &res.stateid, arg.seqid);
-		if (status != 0)
-			goto out_free;
-	}
-	nfs_confirm_seqid(&sp->so_seqid, 0);
-	if (status >= 0) {
-		memcpy(state->stateid.data, res.stateid.data,
-				sizeof(state->stateid.data));
-		clear_bit(NFS_DELEGATED_STATE, &state->flags);
-	}
-out_free:
-	nfs_free_seqid(arg.seqid);
-out:
-	dput(parent);
-	return status;
+		return 0;
+	opendata = nfs4_opendata_alloc(dentry, sp, 0, NULL);
+	if (opendata == NULL)
+		return -ENOMEM;
+	opendata->o_arg.claim = NFS4_OPEN_CLAIM_DELEGATE_CUR;
+	memcpy(opendata->o_arg.u.delegation.data, state->stateid.data,
+			sizeof(opendata->o_arg.u.delegation.data));
+	ret = nfs4_open_recover(opendata, state);
+	nfs4_opendata_free(opendata);
+	return ret;
 }
 
 int nfs4_open_delegation_recall(struct dentry *dentry, struct nfs4_state *state)
@@ -382,82 +540,202 @@
 	return err;
 }
 
-static int _nfs4_proc_open_confirm(struct rpc_clnt *clnt, const struct nfs_fh *fh, struct nfs4_state_owner *sp, nfs4_stateid *stateid, struct nfs_seqid *seqid)
+static void nfs4_open_confirm_prepare(struct rpc_task *task, void *calldata)
 {
-	struct nfs_open_confirmargs arg = {
-		.fh             = fh,
-		.seqid          = seqid,
-		.stateid	= *stateid,
+	struct nfs4_opendata *data = calldata;
+	struct  rpc_message msg = {
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM],
+		.rpc_argp = &data->c_arg,
+		.rpc_resp = &data->c_res,
+		.rpc_cred = data->owner->so_cred,
 	};
-	struct nfs_open_confirmres res;
-	struct 	rpc_message msg = {
-		.rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_OPEN_CONFIRM],
-		.rpc_argp       = &arg,
-		.rpc_resp       = &res,
-		.rpc_cred	= sp->so_cred,
-	};
+	data->timestamp = jiffies;
+	rpc_call_setup(task, &msg, 0);
+}
+
+static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata)
+{
+	struct nfs4_opendata *data = calldata;
+
+	data->rpc_status = task->tk_status;
+	if (RPC_ASSASSINATED(task))
+		return;
+	if (data->rpc_status == 0) {
+		memcpy(data->o_res.stateid.data, data->c_res.stateid.data,
+				sizeof(data->o_res.stateid.data));
+		renew_lease(data->o_res.server, data->timestamp);
+	}
+	nfs_increment_open_seqid(data->rpc_status, data->c_arg.seqid);
+	nfs_confirm_seqid(&data->owner->so_seqid, data->rpc_status);
+}
+
+static void nfs4_open_confirm_release(void *calldata)
+{
+	struct nfs4_opendata *data = calldata;
+	struct nfs4_state *state = NULL;
+
+	/* If this request hasn't been cancelled, do nothing */
+	if (data->cancelled == 0)
+		goto out_free;
+	/* In case of error, no cleanup! */
+	if (data->rpc_status != 0)
+		goto out_free;
+	nfs_confirm_seqid(&data->owner->so_seqid, 0);
+	state = nfs4_opendata_to_nfs4_state(data);
+	if (state != NULL)
+		nfs4_close_state(state, data->o_arg.open_flags);
+out_free:
+	nfs4_opendata_free(data);
+}
+
+static const struct rpc_call_ops nfs4_open_confirm_ops = {
+	.rpc_call_prepare = nfs4_open_confirm_prepare,
+	.rpc_call_done = nfs4_open_confirm_done,
+	.rpc_release = nfs4_open_confirm_release,
+};
+
+/*
+ * Note: On error, nfs4_proc_open_confirm will free the struct nfs4_opendata
+ */
+static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
+{
+	struct nfs_server *server = NFS_SERVER(data->dir->d_inode);
+	struct rpc_task *task;
 	int status;
 
-	status = rpc_call_sync(clnt, &msg, RPC_TASK_NOINTR);
-	/* Confirm the sequence as being established */
-	nfs_confirm_seqid(&sp->so_seqid, status);
-	nfs_increment_open_seqid(status, seqid);
-	if (status >= 0)
-		memcpy(stateid, &res.stateid, sizeof(*stateid));
+	atomic_inc(&data->count);
+	task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_confirm_ops, data);
+	if (IS_ERR(task)) {
+		nfs4_opendata_free(data);
+		return PTR_ERR(task);
+	}
+	status = nfs4_wait_for_completion_rpc_task(task);
+	if (status != 0) {
+		data->cancelled = 1;
+		smp_wmb();
+	} else
+		status = data->rpc_status;
+	rpc_release_task(task);
 	return status;
 }
 
-static int _nfs4_proc_open(struct inode *dir, struct nfs4_state_owner  *sp, struct nfs_openargs *o_arg, struct nfs_openres *o_res)
+static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
 {
-	struct nfs_server *server = NFS_SERVER(dir);
+	struct nfs4_opendata *data = calldata;
+	struct nfs4_state_owner *sp = data->owner;
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN],
-		.rpc_argp = o_arg,
-		.rpc_resp = o_res,
+		.rpc_argp = &data->o_arg,
+		.rpc_resp = &data->o_res,
 		.rpc_cred = sp->so_cred,
 	};
-	int status;
+	
+	if (nfs_wait_on_sequence(data->o_arg.seqid, task) != 0)
+		return;
+	/* Update sequence id. */
+	data->o_arg.id = sp->so_id;
+	data->o_arg.clientid = sp->so_client->cl_clientid;
+	if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS)
+		msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
+	data->timestamp = jiffies;
+	rpc_call_setup(task, &msg, 0);
+}
 
-	/* Update sequence id. The caller must serialize! */
-	o_arg->id = sp->so_id;
-	o_arg->clientid = sp->so_client->cl_clientid;
+static void nfs4_open_done(struct rpc_task *task, void *calldata)
+{
+	struct nfs4_opendata *data = calldata;
 
-	status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
-	if (status == 0) {
-		/* OPEN on anything except a regular file is disallowed in NFSv4 */
-		switch (o_res->f_attr->mode & S_IFMT) {
+	data->rpc_status = task->tk_status;
+	if (RPC_ASSASSINATED(task))
+		return;
+	if (task->tk_status == 0) {
+		switch (data->o_res.f_attr->mode & S_IFMT) {
 			case S_IFREG:
 				break;
 			case S_IFLNK:
-				status = -ELOOP;
+				data->rpc_status = -ELOOP;
 				break;
 			case S_IFDIR:
-				status = -EISDIR;
+				data->rpc_status = -EISDIR;
 				break;
 			default:
-				status = -ENOTDIR;
+				data->rpc_status = -ENOTDIR;
 		}
+		renew_lease(data->o_res.server, data->timestamp);
 	}
+	nfs_increment_open_seqid(data->rpc_status, data->o_arg.seqid);
+}
 
-	nfs_increment_open_seqid(status, o_arg->seqid);
+static void nfs4_open_release(void *calldata)
+{
+	struct nfs4_opendata *data = calldata;
+	struct nfs4_state *state = NULL;
+
+	/* If this request hasn't been cancelled, do nothing */
+	if (data->cancelled == 0)
+		goto out_free;
+	/* In case of error, no cleanup! */
+	if (data->rpc_status != 0)
+		goto out_free;
+	/* In case we need an open_confirm, no cleanup! */
+	if (data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM)
+		goto out_free;
+	nfs_confirm_seqid(&data->owner->so_seqid, 0);
+	state = nfs4_opendata_to_nfs4_state(data);
+	if (state != NULL)
+		nfs4_close_state(state, data->o_arg.open_flags);
+out_free:
+	nfs4_opendata_free(data);
+}
+
+static const struct rpc_call_ops nfs4_open_ops = {
+	.rpc_call_prepare = nfs4_open_prepare,
+	.rpc_call_done = nfs4_open_done,
+	.rpc_release = nfs4_open_release,
+};
+
+/*
+ * Note: On error, nfs4_proc_open will free the struct nfs4_opendata
+ */
+static int _nfs4_proc_open(struct nfs4_opendata *data)
+{
+	struct inode *dir = data->dir->d_inode;
+	struct nfs_server *server = NFS_SERVER(dir);
+	struct nfs_openargs *o_arg = &data->o_arg;
+	struct nfs_openres *o_res = &data->o_res;
+	struct rpc_task *task;
+	int status;
+
+	atomic_inc(&data->count);
+	task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_open_ops, data);
+	if (IS_ERR(task)) {
+		nfs4_opendata_free(data);
+		return PTR_ERR(task);
+	}
+	status = nfs4_wait_for_completion_rpc_task(task);
+	if (status != 0) {
+		data->cancelled = 1;
+		smp_wmb();
+	} else
+		status = data->rpc_status;
+	rpc_release_task(task);
 	if (status != 0)
-		goto out;
+		return status;
+
 	if (o_arg->open_flags & O_CREAT) {
 		update_changeattr(dir, &o_res->cinfo);
 		nfs_post_op_update_inode(dir, o_res->dir_attr);
 	} else
 		nfs_refresh_inode(dir, o_res->dir_attr);
 	if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
-		status = _nfs4_proc_open_confirm(server->client, &o_res->fh,
-				sp, &o_res->stateid, o_arg->seqid);
+		status = _nfs4_proc_open_confirm(data);
 		if (status != 0)
-			goto out;
+			return status;
 	}
-	nfs_confirm_seqid(&sp->so_seqid, 0);
+	nfs_confirm_seqid(&data->owner->so_seqid, 0);
 	if (!(o_res->f_attr->valid & NFS_ATTR_FATTR))
-		status = server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
-out:
-	return status;
+		return server->rpc_ops->getattr(server, &o_res->fh, o_res->f_attr);
+	return 0;
 }
 
 static int _nfs4_do_access(struct inode *inode, struct rpc_cred *cred, int openflags)
@@ -488,6 +766,15 @@
 	return -EACCES;
 }
 
+int nfs4_recover_expired_lease(struct nfs_server *server)
+{
+	struct nfs4_client *clp = server->nfs4_state;
+
+	if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
+		nfs4_schedule_state_recovery(clp);
+	return nfs4_wait_clnt_recover(server->client, clp);
+}
+
 /*
  * OPEN_EXPIRED:
  * 	reclaim state on the server after a network partition.
@@ -495,77 +782,31 @@
  */
 static int _nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
 {
-	struct dentry *parent = dget_parent(dentry);
-	struct inode *dir = parent->d_inode;
 	struct inode *inode = state->inode;
-	struct nfs_server *server = NFS_SERVER(dir);
 	struct nfs_delegation *delegation = NFS_I(inode)->delegation;
-	struct nfs_fattr f_attr, dir_attr;
-	struct nfs_openargs o_arg = {
-		.fh = NFS_FH(dir),
-		.open_flags = state->state,
-		.name = &dentry->d_name,
-		.bitmask = server->attr_bitmask,
-		.claim = NFS4_OPEN_CLAIM_NULL,
-	};
-	struct nfs_openres o_res = {
-		.f_attr = &f_attr,
-		.dir_attr = &dir_attr,
-		.server = server,
-	};
-	int status = 0;
+	struct nfs4_opendata *opendata;
+	int openflags = state->state & (FMODE_READ|FMODE_WRITE);
+	int ret;
 
 	if (delegation != NULL && !(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) {
-		status = _nfs4_do_access(inode, sp->so_cred, state->state);
-		if (status < 0)
-			goto out;
+		ret = _nfs4_do_access(inode, sp->so_cred, openflags);
+		if (ret < 0)
+			return ret;
 		memcpy(&state->stateid, &delegation->stateid, sizeof(state->stateid));
 		set_bit(NFS_DELEGATED_STATE, &state->flags);
-		goto out;
+		return 0;
 	}
-	o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
-	status = -ENOMEM;
-	if (o_arg.seqid == NULL)
-		goto out;
-	nfs_fattr_init(&f_attr);
-	nfs_fattr_init(&dir_attr);
-	status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
-	if (status != 0)
-		goto out_nodeleg;
-	/* Check if files differ */
-	if ((f_attr.mode & S_IFMT) != (inode->i_mode & S_IFMT))
-		goto out_stale;
-	/* Has the file handle changed? */
-	if (nfs_compare_fh(&o_res.fh, NFS_FH(inode)) != 0) {
-		/* Verify if the change attributes are the same */
-		if (f_attr.change_attr != NFS_I(inode)->change_attr)
-			goto out_stale;
-		if (nfs_size_to_loff_t(f_attr.size) != inode->i_size)
-			goto out_stale;
-		/* Lets just pretend that this is the same file */
-		nfs_copy_fh(NFS_FH(inode), &o_res.fh);
-		NFS_I(inode)->fileid = f_attr.fileid;
+	opendata = nfs4_opendata_alloc(dentry, sp, openflags, NULL);
+	if (opendata == NULL)
+		return -ENOMEM;
+	ret = nfs4_open_recover(opendata, state);
+	if (ret == -ESTALE) {
+		/* Invalidate the state owner so we don't ever use it again */
+		nfs4_drop_state_owner(sp);
+		d_drop(dentry);
 	}
-	memcpy(&state->stateid, &o_res.stateid, sizeof(state->stateid));
-	if (o_res.delegation_type != 0) {
-		if (!(delegation->flags & NFS_DELEGATION_NEED_RECLAIM))
-			nfs_inode_set_delegation(inode, sp->so_cred, &o_res);
-		else
-			nfs_inode_reclaim_delegation(inode, sp->so_cred, &o_res);
-	}
-out_nodeleg:
-	nfs_free_seqid(o_arg.seqid);
-	clear_bit(NFS_DELEGATED_STATE, &state->flags);
-out:
-	dput(parent);
-	return status;
-out_stale:
-	status = -ESTALE;
-	/* Invalidate the state owner so we don't ever use it again */
-	nfs4_drop_state_owner(sp);
-	d_drop(dentry);
-	/* Should we be trying to close that stateid? */
-	goto out_nodeleg;
+	nfs4_opendata_free(opendata);
+	return ret;
 }
 
 static inline int nfs4_do_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
@@ -584,26 +825,19 @@
 
 static int nfs4_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state)
 {
-	struct nfs_inode *nfsi = NFS_I(state->inode);
 	struct nfs_open_context *ctx;
-	int status;
+	int ret;
 
-	spin_lock(&state->inode->i_lock);
-	list_for_each_entry(ctx, &nfsi->open_files, list) {
-		if (ctx->state != state)
-			continue;
-		get_nfs_open_context(ctx);
-		spin_unlock(&state->inode->i_lock);
-		status = nfs4_do_open_expired(sp, state, ctx->dentry);
-		put_nfs_open_context(ctx);
-		return status;
-	}
-	spin_unlock(&state->inode->i_lock);
-	return -ENOENT;
+	ctx = nfs4_state_find_open_context(state);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+	ret = nfs4_do_open_expired(sp, state, ctx->dentry);
+	put_nfs_open_context(ctx);
+	return ret;
 }
 
 /*
- * Returns an nfs4_state + an extra reference to the inode
+ * Returns a referenced nfs4_state if there is an open delegation on the file
  */
 static int _nfs4_open_delegated(struct inode *inode, int flags, struct rpc_cred *cred, struct nfs4_state **res)
 {
@@ -616,6 +850,14 @@
 	int open_flags = flags & (FMODE_READ|FMODE_WRITE);
 	int err;
 
+	err = -ENOMEM;
+	if (!(sp = nfs4_get_state_owner(server, cred))) {
+		dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
+		return err;
+	}
+	err = nfs4_recover_expired_lease(server);
+	if (err != 0)
+		goto out_put_state_owner;
 	/* Protect against reboot recovery - NOTE ORDER! */
 	down_read(&clp->cl_sem);
 	/* Protect against delegation recall */
@@ -625,10 +867,6 @@
 	if (delegation == NULL || (delegation->type & open_flags) != open_flags)
 		goto out_err;
 	err = -ENOMEM;
-	if (!(sp = nfs4_get_state_owner(server, cred))) {
-		dprintk("%s: nfs4_get_state_owner failed!\n", __FUNCTION__);
-		goto out_err;
-	}
 	state = nfs4_get_open_state(inode, sp);
 	if (state == NULL)
 		goto out_err;
@@ -636,39 +874,34 @@
 	err = -ENOENT;
 	if ((state->state & open_flags) == open_flags) {
 		spin_lock(&inode->i_lock);
-		if (open_flags & FMODE_READ)
-			state->nreaders++;
-		if (open_flags & FMODE_WRITE)
-			state->nwriters++;
+		update_open_stateflags(state, open_flags);
 		spin_unlock(&inode->i_lock);
 		goto out_ok;
 	} else if (state->state != 0)
-		goto out_err;
+		goto out_put_open_state;
 
 	lock_kernel();
 	err = _nfs4_do_access(inode, cred, open_flags);
 	unlock_kernel();
 	if (err != 0)
-		goto out_err;
+		goto out_put_open_state;
 	set_bit(NFS_DELEGATED_STATE, &state->flags);
 	update_open_stateid(state, &delegation->stateid, open_flags);
 out_ok:
 	nfs4_put_state_owner(sp);
 	up_read(&nfsi->rwsem);
 	up_read(&clp->cl_sem);
-	igrab(inode);
 	*res = state;
-	return 0; 
+	return 0;
+out_put_open_state:
+	nfs4_put_open_state(state);
 out_err:
-	if (sp != NULL) {
-		if (state != NULL)
-			nfs4_put_open_state(state);
-		nfs4_put_state_owner(sp);
-	}
 	up_read(&nfsi->rwsem);
 	up_read(&clp->cl_sem);
 	if (err != -EACCES)
 		nfs_inode_return_delegation(inode);
+out_put_state_owner:
+	nfs4_put_state_owner(sp);
 	return err;
 }
 
@@ -689,7 +922,7 @@
 }
 
 /*
- * Returns an nfs4_state + an referenced inode
+ * Returns a referenced nfs4_state
  */
 static int _nfs4_do_open(struct inode *dir, struct dentry *dentry, int flags, struct iattr *sattr, struct rpc_cred *cred, struct nfs4_state **res)
 {
@@ -697,73 +930,46 @@
 	struct nfs4_state     *state = NULL;
 	struct nfs_server       *server = NFS_SERVER(dir);
 	struct nfs4_client *clp = server->nfs4_state;
-	struct inode *inode = NULL;
+	struct nfs4_opendata *opendata;
 	int                     status;
-	struct nfs_fattr f_attr, dir_attr;
-	struct nfs_openargs o_arg = {
-		.fh             = NFS_FH(dir),
-		.open_flags	= flags,
-		.name           = &dentry->d_name,
-		.server         = server,
-		.bitmask = server->attr_bitmask,
-		.claim = NFS4_OPEN_CLAIM_NULL,
-	};
-	struct nfs_openres o_res = {
-		.f_attr         = &f_attr,
-		.dir_attr	= &dir_attr,
-		.server         = server,
-	};
 
 	/* Protect against reboot recovery conflicts */
-	down_read(&clp->cl_sem);
 	status = -ENOMEM;
 	if (!(sp = nfs4_get_state_owner(server, cred))) {
 		dprintk("nfs4_do_open: nfs4_get_state_owner failed!\n");
 		goto out_err;
 	}
-	if (flags & O_EXCL) {
-		u32 *p = (u32 *) o_arg.u.verifier.data;
-		p[0] = jiffies;
-		p[1] = current->pid;
-	} else
-		o_arg.u.attrs = sattr;
-	/* Serialization for the sequence id */
-
-	o_arg.seqid = nfs_alloc_seqid(&sp->so_seqid);
-	if (o_arg.seqid == NULL)
-		return -ENOMEM;
-	nfs_fattr_init(&f_attr);
-	nfs_fattr_init(&dir_attr);
-	status = _nfs4_proc_open(dir, sp, &o_arg, &o_res);
+	status = nfs4_recover_expired_lease(server);
 	if (status != 0)
-		goto out_err;
+		goto err_put_state_owner;
+	down_read(&clp->cl_sem);
+	status = -ENOMEM;
+	opendata = nfs4_opendata_alloc(dentry, sp, flags, sattr);
+	if (opendata == NULL)
+		goto err_put_state_owner;
+
+	status = _nfs4_proc_open(opendata);
+	if (status != 0)
+		goto err_opendata_free;
 
 	status = -ENOMEM;
-	inode = nfs_fhget(dir->i_sb, &o_res.fh, &f_attr);
-	if (!inode)
-		goto out_err;
-	state = nfs4_get_open_state(inode, sp);
-	if (!state)
-		goto out_err;
-	update_open_stateid(state, &o_res.stateid, flags);
-	if (o_res.delegation_type != 0)
-		nfs_inode_set_delegation(inode, cred, &o_res);
-	nfs_free_seqid(o_arg.seqid);
+	state = nfs4_opendata_to_nfs4_state(opendata);
+	if (state == NULL)
+		goto err_opendata_free;
+	if (opendata->o_res.delegation_type != 0)
+		nfs_inode_set_delegation(state->inode, cred, &opendata->o_res);
+	nfs4_opendata_free(opendata);
 	nfs4_put_state_owner(sp);
 	up_read(&clp->cl_sem);
 	*res = state;
 	return 0;
+err_opendata_free:
+	nfs4_opendata_free(opendata);
+err_put_state_owner:
+	nfs4_put_state_owner(sp);
 out_err:
-	if (sp != NULL) {
-		if (state != NULL)
-			nfs4_put_open_state(state);
-		nfs_free_seqid(o_arg.seqid);
-		nfs4_put_state_owner(sp);
-	}
 	/* Note: clp->cl_sem must be released before nfs4_put_open_state()! */
 	up_read(&clp->cl_sem);
-	if (inode != NULL)
-		iput(inode);
 	*res = NULL;
 	return status;
 }
@@ -830,6 +1036,7 @@
                 .rpc_argp       = &arg,
                 .rpc_resp       = &res,
         };
+	unsigned long timestamp = jiffies;
 	int status;
 
 	nfs_fattr_init(fattr);
@@ -841,6 +1048,8 @@
 		memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
 
 	status = rpc_call_sync(server->client, &msg, 0);
+	if (status == 0 && state != NULL)
+		renew_lease(server, timestamp);
 	return status;
 }
 
@@ -865,12 +1074,13 @@
 	struct nfs_closeargs arg;
 	struct nfs_closeres res;
 	struct nfs_fattr fattr;
+	unsigned long timestamp;
 };
 
-static void nfs4_free_closedata(struct nfs4_closedata *calldata)
+static void nfs4_free_closedata(void *data)
 {
-	struct nfs4_state *state = calldata->state;
-	struct nfs4_state_owner *sp = state->owner;
+	struct nfs4_closedata *calldata = data;
+	struct nfs4_state_owner *sp = calldata->state->owner;
 
 	nfs4_put_open_state(calldata->state);
 	nfs_free_seqid(calldata->arg.seqid);
@@ -878,12 +1088,14 @@
 	kfree(calldata);
 }
 
-static void nfs4_close_done(struct rpc_task *task)
+static void nfs4_close_done(struct rpc_task *task, void *data)
 {
-	struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata;
+	struct nfs4_closedata *calldata = data;
 	struct nfs4_state *state = calldata->state;
 	struct nfs_server *server = NFS_SERVER(calldata->inode);
 
+	if (RPC_ASSASSINATED(task))
+		return;
         /* hmm. we are done with the inode, and in the process of freeing
 	 * the state_owner. we keep this around to process errors
 	 */
@@ -892,6 +1104,7 @@
 		case 0:
 			memcpy(&state->stateid, &calldata->res.stateid,
 					sizeof(state->stateid));
+			renew_lease(server, calldata->timestamp);
 			break;
 		case -NFS4ERR_STALE_STATEID:
 		case -NFS4ERR_EXPIRED:
@@ -904,12 +1117,11 @@
 			}
 	}
 	nfs_refresh_inode(calldata->inode, calldata->res.fattr);
-	nfs4_free_closedata(calldata);
 }
 
-static void nfs4_close_begin(struct rpc_task *task)
+static void nfs4_close_prepare(struct rpc_task *task, void *data)
 {
-	struct nfs4_closedata *calldata = (struct nfs4_closedata *)task->tk_calldata;
+	struct nfs4_closedata *calldata = data;
 	struct nfs4_state *state = calldata->state;
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE],
@@ -918,10 +1130,8 @@
 		.rpc_cred = state->owner->so_cred,
 	};
 	int mode = 0, old_mode;
-	int status;
 
-	status = nfs_wait_on_sequence(calldata->arg.seqid, task);
-	if (status != 0)
+	if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
 		return;
 	/* Recalculate the new open mode in case someone reopened the file
 	 * while we were waiting in line to be scheduled.
@@ -929,26 +1139,34 @@
 	spin_lock(&state->owner->so_lock);
 	spin_lock(&calldata->inode->i_lock);
 	mode = old_mode = state->state;
-	if (state->nreaders == 0)
-		mode &= ~FMODE_READ;
-	if (state->nwriters == 0)
-		mode &= ~FMODE_WRITE;
+	if (state->n_rdwr == 0) {
+		if (state->n_rdonly == 0)
+			mode &= ~FMODE_READ;
+		if (state->n_wronly == 0)
+			mode &= ~FMODE_WRITE;
+	}
 	nfs4_state_set_mode_locked(state, mode);
 	spin_unlock(&calldata->inode->i_lock);
 	spin_unlock(&state->owner->so_lock);
 	if (mode == old_mode || test_bit(NFS_DELEGATED_STATE, &state->flags)) {
-		nfs4_free_closedata(calldata);
-		task->tk_exit = NULL;
-		rpc_exit(task, 0);
+		/* Note: exit _without_ calling nfs4_close_done */
+		task->tk_action = NULL;
 		return;
 	}
 	nfs_fattr_init(calldata->res.fattr);
 	if (mode != 0)
 		msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE];
 	calldata->arg.open_flags = mode;
+	calldata->timestamp = jiffies;
 	rpc_call_setup(task, &msg, 0);
 }
 
+static const struct rpc_call_ops nfs4_close_ops = {
+	.rpc_call_prepare = nfs4_close_prepare,
+	.rpc_call_done = nfs4_close_done,
+	.rpc_release = nfs4_free_closedata,
+};
+
 /* 
  * It is possible for data to be read/written from a mem-mapped file 
  * after the sys_close call (which hits the vfs layer as a flush).
@@ -981,8 +1199,7 @@
 	calldata->res.fattr = &calldata->fattr;
 	calldata->res.server = server;
 
-	status = nfs4_call_async(server->client, nfs4_close_begin,
-			nfs4_close_done, calldata);
+	status = nfs4_call_async(server->client, &nfs4_close_ops, calldata);
 	if (status == 0)
 		goto out;
 
@@ -1034,7 +1251,7 @@
 			d_add(dentry, NULL);
 		return (struct dentry *)state;
 	}
-	res = d_add_unique(dentry, state->inode);
+	res = d_add_unique(dentry, igrab(state->inode));
 	if (res != NULL)
 		dentry = res;
 	nfs4_intent_set_file(nd, dentry, state);
@@ -1046,7 +1263,6 @@
 {
 	struct rpc_cred *cred;
 	struct nfs4_state *state;
-	struct inode *inode;
 
 	cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
 	if (IS_ERR(cred))
@@ -1070,9 +1286,7 @@
 		}
 		goto out_drop;
 	}
-	inode = state->inode;
-	iput(inode);
-	if (inode == dentry->d_inode) {
+	if (state->inode == dentry->d_inode) {
 		nfs4_intent_set_file(nd, dentry, state);
 		return 1;
 	}
@@ -1506,10 +1720,17 @@
 	dprintk("NFS call  write %d @ %Ld\n", wdata->args.count,
 			(long long) wdata->args.offset);
 
+	wdata->args.bitmask = server->attr_bitmask;
+	wdata->res.server = server;
+	wdata->timestamp = jiffies;
 	nfs_fattr_init(fattr);
 	status = rpc_call_sync(server->client, &msg, rpcflags);
 	dprintk("NFS reply write: %d\n", status);
-	return status;
+	if (status < 0)
+		return status;
+	renew_lease(server, wdata->timestamp);
+	nfs_post_op_update_inode(inode, fattr);
+	return wdata->res.count;
 }
 
 static int nfs4_proc_write(struct nfs_write_data *wdata)
@@ -1540,9 +1761,16 @@
 	dprintk("NFS call  commit %d @ %Ld\n", cdata->args.count,
 			(long long) cdata->args.offset);
 
+	cdata->args.bitmask = server->attr_bitmask;
+	cdata->res.server = server;
+	cdata->timestamp = jiffies;
 	nfs_fattr_init(fattr);
 	status = rpc_call_sync(server->client, &msg, 0);
+	if (status >= 0)
+		renew_lease(server, cdata->timestamp);
 	dprintk("NFS reply commit: %d\n", status);
+	if (status >= 0)
+		nfs_post_op_update_inode(inode, fattr);
 	return status;
 }
 
@@ -1592,7 +1820,7 @@
 		status = PTR_ERR(state);
 		goto out;
 	}
-	d_instantiate(dentry, state->inode);
+	d_instantiate(dentry, igrab(state->inode));
 	if (flags & O_EXCL) {
 		struct nfs_fattr fattr;
 		status = nfs4_do_setattr(NFS_SERVER(dir), &fattr,
@@ -2116,10 +2344,9 @@
 	return err;
 }
 
-static void
-nfs4_read_done(struct rpc_task *task)
+static void nfs4_read_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
+	struct nfs_read_data *data = calldata;
 	struct inode *inode = data->inode;
 
 	if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
@@ -2129,9 +2356,14 @@
 	if (task->tk_status > 0)
 		renew_lease(NFS_SERVER(inode), data->timestamp);
 	/* Call back common NFS readpage processing */
-	nfs_readpage_result(task);
+	nfs_readpage_result(task, calldata);
 }
 
+static const struct rpc_call_ops nfs4_read_ops = {
+	.rpc_call_done = nfs4_read_done,
+	.rpc_release = nfs_readdata_release,
+};
+
 static void
 nfs4_proc_read_setup(struct nfs_read_data *data)
 {
@@ -2151,14 +2383,13 @@
 	flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs4_read_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_read_ops, data);
 	rpc_call_setup(task, &msg, 0);
 }
 
-static void
-nfs4_write_done(struct rpc_task *task)
+static void nfs4_write_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+	struct nfs_write_data *data = calldata;
 	struct inode *inode = data->inode;
 	
 	if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
@@ -2170,9 +2401,14 @@
 		nfs_post_op_update_inode(inode, data->res.fattr);
 	}
 	/* Call back common NFS writeback processing */
-	nfs_writeback_done(task);
+	nfs_writeback_done(task, calldata);
 }
 
+static const struct rpc_call_ops nfs4_write_ops = {
+	.rpc_call_done = nfs4_write_done,
+	.rpc_release = nfs_writedata_release,
+};
+
 static void
 nfs4_proc_write_setup(struct nfs_write_data *data, int how)
 {
@@ -2205,14 +2441,13 @@
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs4_write_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_write_ops, data);
 	rpc_call_setup(task, &msg, 0);
 }
 
-static void
-nfs4_commit_done(struct rpc_task *task)
+static void nfs4_commit_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+	struct nfs_write_data *data = calldata;
 	struct inode *inode = data->inode;
 	
 	if (nfs4_async_handle_error(task, NFS_SERVER(inode)) == -EAGAIN) {
@@ -2222,9 +2457,14 @@
 	if (task->tk_status >= 0)
 		nfs_post_op_update_inode(inode, data->res.fattr);
 	/* Call back common NFS writeback processing */
-	nfs_commit_done(task);
+	nfs_commit_done(task, calldata);
 }
 
+static const struct rpc_call_ops nfs4_commit_ops = {
+	.rpc_call_done = nfs4_commit_done,
+	.rpc_release = nfs_commit_release,
+};
+
 static void
 nfs4_proc_commit_setup(struct nfs_write_data *data, int how)
 {
@@ -2246,7 +2486,7 @@
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs4_commit_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs4_commit_ops, data);
 	rpc_call_setup(task, &msg, 0);	
 }
 
@@ -2254,11 +2494,10 @@
  * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special
  * standalone procedure for queueing an asynchronous RENEW.
  */
-static void
-renew_done(struct rpc_task *task)
+static void nfs4_renew_done(struct rpc_task *task, void *data)
 {
 	struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp;
-	unsigned long timestamp = (unsigned long)task->tk_calldata;
+	unsigned long timestamp = (unsigned long)data;
 
 	if (task->tk_status < 0) {
 		switch (task->tk_status) {
@@ -2275,26 +2514,28 @@
 	spin_unlock(&clp->cl_lock);
 }
 
-int
-nfs4_proc_async_renew(struct nfs4_client *clp)
+static const struct rpc_call_ops nfs4_renew_ops = {
+	.rpc_call_done = nfs4_renew_done,
+};
+
+int nfs4_proc_async_renew(struct nfs4_client *clp, struct rpc_cred *cred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_RENEW],
 		.rpc_argp	= clp,
-		.rpc_cred	= clp->cl_cred,
+		.rpc_cred	= cred,
 	};
 
 	return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
-			renew_done, (void *)jiffies);
+			&nfs4_renew_ops, (void *)jiffies);
 }
 
-int
-nfs4_proc_renew(struct nfs4_client *clp)
+int nfs4_proc_renew(struct nfs4_client *clp, struct rpc_cred *cred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_RENEW],
 		.rpc_argp	= clp,
-		.rpc_cred	= clp->cl_cred,
+		.rpc_cred	= cred,
 	};
 	unsigned long now = jiffies;
 	int status;
@@ -2510,7 +2751,7 @@
 		case -NFS4ERR_EXPIRED:
 			rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL, NULL);
 			nfs4_schedule_state_recovery(clp);
-			if (test_bit(NFS4CLNT_OK, &clp->cl_state))
+			if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
 				rpc_wake_up_task(task);
 			task->tk_status = 0;
 			return -EAGAIN;
@@ -2527,25 +2768,25 @@
 	return 0;
 }
 
+static int nfs4_wait_bit_interruptible(void *word)
+{
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	schedule();
+	return 0;
+}
+
 static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp)
 {
-	DEFINE_WAIT(wait);
 	sigset_t oldset;
-	int interruptible, res = 0;
+	int res;
 
 	might_sleep();
 
 	rpc_clnt_sigmask(clnt, &oldset);
-	interruptible = TASK_UNINTERRUPTIBLE;
-	if (clnt->cl_intr)
-		interruptible = TASK_INTERRUPTIBLE;
-	prepare_to_wait(&clp->cl_waitq, &wait, interruptible);
-	nfs4_schedule_state_recovery(clp);
-	if (clnt->cl_intr && signalled())
-		res = -ERESTARTSYS;
-	else if (!test_bit(NFS4CLNT_OK, &clp->cl_state))
-		schedule();
-	finish_wait(&clp->cl_waitq, &wait);
+	res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER,
+			nfs4_wait_bit_interruptible,
+			TASK_INTERRUPTIBLE);
 	rpc_clnt_sigunmask(clnt, &oldset);
 	return res;
 }
@@ -2588,6 +2829,7 @@
 		case -NFS4ERR_STALE_CLIENTID:
 		case -NFS4ERR_STALE_STATEID:
 		case -NFS4ERR_EXPIRED:
+			nfs4_schedule_state_recovery(clp);
 			ret = nfs4_wait_clnt_recover(server->client, clp);
 			if (ret == 0)
 				exception->retry = 1;
@@ -2604,7 +2846,7 @@
 	return nfs4_map_errors(ret);
 }
 
-int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port)
+int nfs4_proc_setclientid(struct nfs4_client *clp, u32 program, unsigned short port, struct rpc_cred *cred)
 {
 	nfs4_verifier sc_verifier;
 	struct nfs4_setclientid setclientid = {
@@ -2615,7 +2857,7 @@
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
 		.rpc_argp = &setclientid,
 		.rpc_resp = clp,
-		.rpc_cred = clp->cl_cred,
+		.rpc_cred = cred,
 	};
 	u32 *p;
 	int loop = 0;
@@ -2629,7 +2871,7 @@
 		setclientid.sc_name_len = scnprintf(setclientid.sc_name,
 				sizeof(setclientid.sc_name), "%s/%u.%u.%u.%u %s %u",
 				clp->cl_ipaddr, NIPQUAD(clp->cl_addr.s_addr),
-				clp->cl_cred->cr_ops->cr_name,
+				cred->cr_ops->cr_name,
 				clp->cl_id_uniquifier);
 		setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
 				sizeof(setclientid.sc_netid), "tcp");
@@ -2652,14 +2894,14 @@
 }
 
 int
-nfs4_proc_setclientid_confirm(struct nfs4_client *clp)
+nfs4_proc_setclientid_confirm(struct nfs4_client *clp, struct rpc_cred *cred)
 {
 	struct nfs_fsinfo fsinfo;
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
 		.rpc_argp = clp,
 		.rpc_resp = &fsinfo,
-		.rpc_cred = clp->cl_cred,
+		.rpc_cred = cred,
 	};
 	unsigned long now;
 	int status;
@@ -2670,24 +2912,92 @@
 		spin_lock(&clp->cl_lock);
 		clp->cl_lease_time = fsinfo.lease_time * HZ;
 		clp->cl_last_renewal = now;
+		clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
 		spin_unlock(&clp->cl_lock);
 	}
 	return status;
 }
 
-static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
+struct nfs4_delegreturndata {
+	struct nfs4_delegreturnargs args;
+	struct nfs4_delegreturnres res;
+	struct nfs_fh fh;
+	nfs4_stateid stateid;
+	struct rpc_cred *cred;
+	unsigned long timestamp;
+	struct nfs_fattr fattr;
+	int rpc_status;
+};
+
+static void nfs4_delegreturn_prepare(struct rpc_task *task, void *calldata)
 {
-	struct nfs4_delegreturnargs args = {
-		.fhandle = NFS_FH(inode),
-		.stateid = stateid,
-	};
+	struct nfs4_delegreturndata *data = calldata;
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DELEGRETURN],
-		.rpc_argp = &args,
-		.rpc_cred = cred,
+		.rpc_argp = &data->args,
+		.rpc_resp = &data->res,
+		.rpc_cred = data->cred,
 	};
+	nfs_fattr_init(data->res.fattr);
+	rpc_call_setup(task, &msg, 0);
+}
 
-	return rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
+static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata)
+{
+	struct nfs4_delegreturndata *data = calldata;
+	data->rpc_status = task->tk_status;
+	if (data->rpc_status == 0)
+		renew_lease(data->res.server, data->timestamp);
+}
+
+static void nfs4_delegreturn_release(void *calldata)
+{
+	struct nfs4_delegreturndata *data = calldata;
+
+	put_rpccred(data->cred);
+	kfree(calldata);
+}
+
+const static struct rpc_call_ops nfs4_delegreturn_ops = {
+	.rpc_call_prepare = nfs4_delegreturn_prepare,
+	.rpc_call_done = nfs4_delegreturn_done,
+	.rpc_release = nfs4_delegreturn_release,
+};
+
+static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
+{
+	struct nfs4_delegreturndata *data;
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct rpc_task *task;
+	int status;
+
+	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+	data->args.fhandle = &data->fh;
+	data->args.stateid = &data->stateid;
+	data->args.bitmask = server->attr_bitmask;
+	nfs_copy_fh(&data->fh, NFS_FH(inode));
+	memcpy(&data->stateid, stateid, sizeof(data->stateid));
+	data->res.fattr = &data->fattr;
+	data->res.server = server;
+	data->cred = get_rpccred(cred);
+	data->timestamp = jiffies;
+	data->rpc_status = 0;
+
+	task = rpc_run_task(NFS_CLIENT(inode), RPC_TASK_ASYNC, &nfs4_delegreturn_ops, data);
+	if (IS_ERR(task)) {
+		nfs4_delegreturn_release(data);
+		return PTR_ERR(task);
+	}
+	status = nfs4_wait_for_completion_rpc_task(task);
+	if (status == 0) {
+		status = data->rpc_status;
+		if (status == 0)
+			nfs_post_op_update_inode(inode, &data->fattr);
+	}
+	rpc_release_task(task);
+	return status;
 }
 
 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
@@ -2725,43 +3035,17 @@
 	return timeout;
 }
 
-static inline int
-nfs4_lck_type(int cmd, struct file_lock *request)
-{
-	/* set lock type */
-	switch (request->fl_type) {
-		case F_RDLCK:
-			return IS_SETLKW(cmd) ? NFS4_READW_LT : NFS4_READ_LT;
-		case F_WRLCK:
-			return IS_SETLKW(cmd) ? NFS4_WRITEW_LT : NFS4_WRITE_LT;
-		case F_UNLCK:
-			return NFS4_WRITE_LT; 
-	}
-	BUG();
-	return 0;
-}
-
-static inline uint64_t
-nfs4_lck_length(struct file_lock *request)
-{
-	if (request->fl_end == OFFSET_MAX)
-		return ~(uint64_t)0;
-	return request->fl_end - request->fl_start + 1;
-}
-
 static int _nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
 {
 	struct inode *inode = state->inode;
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs4_client *clp = server->nfs4_state;
-	struct nfs_lockargs arg = {
+	struct nfs_lockt_args arg = {
 		.fh = NFS_FH(inode),
-		.type = nfs4_lck_type(cmd, request),
-		.offset = request->fl_start,
-		.length = nfs4_lck_length(request),
+		.fl = request,
 	};
-	struct nfs_lockres res = {
-		.server = server,
+	struct nfs_lockt_res res = {
+		.denied = request,
 	};
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_LOCKT],
@@ -2769,36 +3053,23 @@
 		.rpc_resp       = &res,
 		.rpc_cred	= state->owner->so_cred,
 	};
-	struct nfs_lowner nlo;
 	struct nfs4_lock_state *lsp;
 	int status;
 
 	down_read(&clp->cl_sem);
-	nlo.clientid = clp->cl_clientid;
+	arg.lock_owner.clientid = clp->cl_clientid;
 	status = nfs4_set_lock_state(state, request);
 	if (status != 0)
 		goto out;
 	lsp = request->fl_u.nfs4_fl.owner;
-	nlo.id = lsp->ls_id; 
-	arg.u.lockt = &nlo;
+	arg.lock_owner.id = lsp->ls_id; 
 	status = rpc_call_sync(server->client, &msg, 0);
-	if (!status) {
-		request->fl_type = F_UNLCK;
-	} else if (status == -NFS4ERR_DENIED) {
-		int64_t len, start, end;
-		start = res.u.denied.offset;
-		len = res.u.denied.length;
-		end = start + len - 1;
-		if (end < 0 || len == 0)
-			request->fl_end = OFFSET_MAX;
-		else
-			request->fl_end = (loff_t)end;
-		request->fl_start = (loff_t)start;
-		request->fl_type = F_WRLCK;
-		if (res.u.denied.type & 1)
-			request->fl_type = F_RDLCK;
-		request->fl_pid = 0;
-		status = 0;
+	switch (status) {
+		case 0:
+			request->fl_type = F_UNLCK;
+			break;
+		case -NFS4ERR_DENIED:
+			status = 0;
 	}
 out:
 	up_read(&clp->cl_sem);
@@ -2838,196 +3109,314 @@
 }
 
 struct nfs4_unlockdata {
-	struct nfs_lockargs arg;
-	struct nfs_locku_opargs luargs;
-	struct nfs_lockres res;
+	struct nfs_locku_args arg;
+	struct nfs_locku_res res;
 	struct nfs4_lock_state *lsp;
 	struct nfs_open_context *ctx;
-	atomic_t refcount;
-	struct completion completion;
+	struct file_lock fl;
+	const struct nfs_server *server;
+	unsigned long timestamp;
 };
 
-static void nfs4_locku_release_calldata(struct nfs4_unlockdata *calldata)
+static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl,
+		struct nfs_open_context *ctx,
+		struct nfs4_lock_state *lsp,
+		struct nfs_seqid *seqid)
 {
-	if (atomic_dec_and_test(&calldata->refcount)) {
-		nfs_free_seqid(calldata->luargs.seqid);
-		nfs4_put_lock_state(calldata->lsp);
-		put_nfs_open_context(calldata->ctx);
-		kfree(calldata);
-	}
+	struct nfs4_unlockdata *p;
+	struct inode *inode = lsp->ls_state->inode;
+
+	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	if (p == NULL)
+		return NULL;
+	p->arg.fh = NFS_FH(inode);
+	p->arg.fl = &p->fl;
+	p->arg.seqid = seqid;
+	p->arg.stateid = &lsp->ls_stateid;
+	p->lsp = lsp;
+	atomic_inc(&lsp->ls_count);
+	/* Ensure we don't close file until we're done freeing locks! */
+	p->ctx = get_nfs_open_context(ctx);
+	memcpy(&p->fl, fl, sizeof(p->fl));
+	p->server = NFS_SERVER(inode);
+	return p;
 }
 
-static void nfs4_locku_complete(struct nfs4_unlockdata *calldata)
+static void nfs4_locku_release_calldata(void *data)
 {
-	complete(&calldata->completion);
-	nfs4_locku_release_calldata(calldata);
+	struct nfs4_unlockdata *calldata = data;
+	nfs_free_seqid(calldata->arg.seqid);
+	nfs4_put_lock_state(calldata->lsp);
+	put_nfs_open_context(calldata->ctx);
+	kfree(calldata);
 }
 
-static void nfs4_locku_done(struct rpc_task *task)
+static void nfs4_locku_done(struct rpc_task *task, void *data)
 {
-	struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata;
+	struct nfs4_unlockdata *calldata = data;
 
-	nfs_increment_lock_seqid(task->tk_status, calldata->luargs.seqid);
+	if (RPC_ASSASSINATED(task))
+		return;
+	nfs_increment_lock_seqid(task->tk_status, calldata->arg.seqid);
 	switch (task->tk_status) {
 		case 0:
 			memcpy(calldata->lsp->ls_stateid.data,
-					calldata->res.u.stateid.data,
+					calldata->res.stateid.data,
 					sizeof(calldata->lsp->ls_stateid.data));
+			renew_lease(calldata->server, calldata->timestamp);
 			break;
 		case -NFS4ERR_STALE_STATEID:
 		case -NFS4ERR_EXPIRED:
-			nfs4_schedule_state_recovery(calldata->res.server->nfs4_state);
+			nfs4_schedule_state_recovery(calldata->server->nfs4_state);
 			break;
 		default:
-			if (nfs4_async_handle_error(task, calldata->res.server) == -EAGAIN) {
+			if (nfs4_async_handle_error(task, calldata->server) == -EAGAIN) {
 				rpc_restart_call(task);
-				return;
 			}
 	}
-	nfs4_locku_complete(calldata);
 }
 
-static void nfs4_locku_begin(struct rpc_task *task)
+static void nfs4_locku_prepare(struct rpc_task *task, void *data)
 {
-	struct nfs4_unlockdata *calldata = (struct nfs4_unlockdata *)task->tk_calldata;
+	struct nfs4_unlockdata *calldata = data;
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_LOCKU],
 		.rpc_argp       = &calldata->arg,
 		.rpc_resp       = &calldata->res,
 		.rpc_cred	= calldata->lsp->ls_state->owner->so_cred,
 	};
-	int status;
 
-	status = nfs_wait_on_sequence(calldata->luargs.seqid, task);
-	if (status != 0)
+	if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
 		return;
 	if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) {
-		nfs4_locku_complete(calldata);
-		task->tk_exit = NULL;
-		rpc_exit(task, 0);
+		/* Note: exit _without_ running nfs4_locku_done */
+		task->tk_action = NULL;
 		return;
 	}
+	calldata->timestamp = jiffies;
 	rpc_call_setup(task, &msg, 0);
 }
 
+static const struct rpc_call_ops nfs4_locku_ops = {
+	.rpc_call_prepare = nfs4_locku_prepare,
+	.rpc_call_done = nfs4_locku_done,
+	.rpc_release = nfs4_locku_release_calldata,
+};
+
+static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
+		struct nfs_open_context *ctx,
+		struct nfs4_lock_state *lsp,
+		struct nfs_seqid *seqid)
+{
+	struct nfs4_unlockdata *data;
+	struct rpc_task *task;
+
+	data = nfs4_alloc_unlockdata(fl, ctx, lsp, seqid);
+	if (data == NULL) {
+		nfs_free_seqid(seqid);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* Unlock _before_ we do the RPC call */
+	do_vfs_lock(fl->fl_file, fl);
+	task = rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data);
+	if (IS_ERR(task))
+		nfs4_locku_release_calldata(data);
+	return task;
+}
+
 static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *request)
 {
-	struct nfs4_unlockdata *calldata;
-	struct inode *inode = state->inode;
-	struct nfs_server *server = NFS_SERVER(inode);
+	struct nfs_seqid *seqid;
 	struct nfs4_lock_state *lsp;
-	int status;
+	struct rpc_task *task;
+	int status = 0;
 
 	/* Is this a delegated lock? */
 	if (test_bit(NFS_DELEGATED_STATE, &state->flags))
-		return do_vfs_lock(request->fl_file, request);
+		goto out_unlock;
+	/* Is this open_owner holding any locks on the server? */
+	if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
+		goto out_unlock;
 
 	status = nfs4_set_lock_state(state, request);
 	if (status != 0)
-		return status;
+		goto out_unlock;
 	lsp = request->fl_u.nfs4_fl.owner;
-	/* We might have lost the locks! */
-	if ((lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0)
-		return 0;
-	calldata = kmalloc(sizeof(*calldata), GFP_KERNEL);
-	if (calldata == NULL)
-		return -ENOMEM;
-	calldata->luargs.seqid = nfs_alloc_seqid(&lsp->ls_seqid);
-	if (calldata->luargs.seqid == NULL) {
-		kfree(calldata);
-		return -ENOMEM;
-	}
-	calldata->luargs.stateid = &lsp->ls_stateid;
-	calldata->arg.fh = NFS_FH(inode);
-	calldata->arg.type = nfs4_lck_type(cmd, request);
-	calldata->arg.offset = request->fl_start;
-	calldata->arg.length = nfs4_lck_length(request);
-	calldata->arg.u.locku = &calldata->luargs;
-	calldata->res.server = server;
-	calldata->lsp = lsp;
-	atomic_inc(&lsp->ls_count);
-
-	/* Ensure we don't close file until we're done freeing locks! */
-	calldata->ctx = get_nfs_open_context((struct nfs_open_context*)request->fl_file->private_data);
-
-	atomic_set(&calldata->refcount, 2);
-	init_completion(&calldata->completion);
-
-	status = nfs4_call_async(NFS_SERVER(inode)->client, nfs4_locku_begin,
-			nfs4_locku_done, calldata);
-	if (status == 0)
-		wait_for_completion_interruptible(&calldata->completion);
+	status = -ENOMEM;
+	seqid = nfs_alloc_seqid(&lsp->ls_seqid);
+	if (seqid == NULL)
+		goto out_unlock;
+	task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid);
+	status = PTR_ERR(task);
+	if (IS_ERR(task))
+		goto out_unlock;
+	status = nfs4_wait_for_completion_rpc_task(task);
+	rpc_release_task(task);
+	return status;
+out_unlock:
 	do_vfs_lock(request->fl_file, request);
-	nfs4_locku_release_calldata(calldata);
 	return status;
 }
 
-static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *request, int reclaim)
+struct nfs4_lockdata {
+	struct nfs_lock_args arg;
+	struct nfs_lock_res res;
+	struct nfs4_lock_state *lsp;
+	struct nfs_open_context *ctx;
+	struct file_lock fl;
+	unsigned long timestamp;
+	int rpc_status;
+	int cancelled;
+};
+
+static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl,
+		struct nfs_open_context *ctx, struct nfs4_lock_state *lsp)
 {
-	struct inode *inode = state->inode;
+	struct nfs4_lockdata *p;
+	struct inode *inode = lsp->ls_state->inode;
 	struct nfs_server *server = NFS_SERVER(inode);
-	struct nfs4_lock_state *lsp = request->fl_u.nfs4_fl.owner;
-	struct nfs_lock_opargs largs = {
-		.lock_stateid = &lsp->ls_stateid,
-		.open_stateid = &state->stateid,
-		.lock_owner = {
-			.clientid = server->nfs4_state->cl_clientid,
-			.id = lsp->ls_id,
-		},
-		.reclaim = reclaim,
-	};
-	struct nfs_lockargs arg = {
-		.fh = NFS_FH(inode),
-		.type = nfs4_lck_type(cmd, request),
-		.offset = request->fl_start,
-		.length = nfs4_lck_length(request),
-		.u = {
-			.lock = &largs,
-		},
-	};
-	struct nfs_lockres res = {
-		.server = server,
-	};
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (p == NULL)
+		return NULL;
+
+	p->arg.fh = NFS_FH(inode);
+	p->arg.fl = &p->fl;
+	p->arg.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
+	if (p->arg.lock_seqid == NULL)
+		goto out_free;
+	p->arg.lock_stateid = &lsp->ls_stateid;
+	p->arg.lock_owner.clientid = server->nfs4_state->cl_clientid;
+	p->arg.lock_owner.id = lsp->ls_id;
+	p->lsp = lsp;
+	atomic_inc(&lsp->ls_count);
+	p->ctx = get_nfs_open_context(ctx);
+	memcpy(&p->fl, fl, sizeof(p->fl));
+	return p;
+out_free:
+	kfree(p);
+	return NULL;
+}
+
+static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
+{
+	struct nfs4_lockdata *data = calldata;
+	struct nfs4_state *state = data->lsp->ls_state;
+	struct nfs4_state_owner *sp = state->owner;
 	struct rpc_message msg = {
-		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_LOCK],
-		.rpc_argp       = &arg,
-		.rpc_resp       = &res,
-		.rpc_cred	= state->owner->so_cred,
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCK],
+		.rpc_argp = &data->arg,
+		.rpc_resp = &data->res,
+		.rpc_cred = sp->so_cred,
 	};
-	int status = -ENOMEM;
 
-	largs.lock_seqid = nfs_alloc_seqid(&lsp->ls_seqid);
-	if (largs.lock_seqid == NULL)
-		return -ENOMEM;
-	if (!(lsp->ls_seqid.flags & NFS_SEQID_CONFIRMED)) {
-		struct nfs4_state_owner *owner = state->owner;
-
-		largs.open_seqid = nfs_alloc_seqid(&owner->so_seqid);
-		if (largs.open_seqid == NULL)
+	if (nfs_wait_on_sequence(data->arg.lock_seqid, task) != 0)
+		return;
+	dprintk("%s: begin!\n", __FUNCTION__);
+	/* Do we need to do an open_to_lock_owner? */
+	if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
+		data->arg.open_seqid = nfs_alloc_seqid(&sp->so_seqid);
+		if (data->arg.open_seqid == NULL) {
+			data->rpc_status = -ENOMEM;
+			task->tk_action = NULL;
 			goto out;
-		largs.new_lock_owner = 1;
-		status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
-		/* increment open seqid on success, and seqid mutating errors */
-		if (largs.new_lock_owner != 0) {
-			nfs_increment_open_seqid(status, largs.open_seqid);
-			if (status == 0)
-				nfs_confirm_seqid(&lsp->ls_seqid, 0);
 		}
-		nfs_free_seqid(largs.open_seqid);
-	} else
-		status = rpc_call_sync(server->client, &msg, RPC_TASK_NOINTR);
-	/* increment lock seqid on success, and seqid mutating errors*/
-	nfs_increment_lock_seqid(status, largs.lock_seqid);
-	/* save the returned stateid. */
-	if (status == 0) {
-		memcpy(lsp->ls_stateid.data, res.u.stateid.data,
-				sizeof(lsp->ls_stateid.data));
-		lsp->ls_flags |= NFS_LOCK_INITIALIZED;
-	} else if (status == -NFS4ERR_DENIED)
-		status = -EAGAIN;
+		data->arg.open_stateid = &state->stateid;
+		data->arg.new_lock_owner = 1;
+	}
+	data->timestamp = jiffies;
+	rpc_call_setup(task, &msg, 0);
 out:
-	nfs_free_seqid(largs.lock_seqid);
-	return status;
+	dprintk("%s: done!, ret = %d\n", __FUNCTION__, data->rpc_status);
+}
+
+static void nfs4_lock_done(struct rpc_task *task, void *calldata)
+{
+	struct nfs4_lockdata *data = calldata;
+
+	dprintk("%s: begin!\n", __FUNCTION__);
+
+	data->rpc_status = task->tk_status;
+	if (RPC_ASSASSINATED(task))
+		goto out;
+	if (data->arg.new_lock_owner != 0) {
+		nfs_increment_open_seqid(data->rpc_status, data->arg.open_seqid);
+		if (data->rpc_status == 0)
+			nfs_confirm_seqid(&data->lsp->ls_seqid, 0);
+		else
+			goto out;
+	}
+	if (data->rpc_status == 0) {
+		memcpy(data->lsp->ls_stateid.data, data->res.stateid.data,
+					sizeof(data->lsp->ls_stateid.data));
+		data->lsp->ls_flags |= NFS_LOCK_INITIALIZED;
+		renew_lease(NFS_SERVER(data->ctx->dentry->d_inode), data->timestamp);
+	}
+	nfs_increment_lock_seqid(data->rpc_status, data->arg.lock_seqid);
+out:
+	dprintk("%s: done, ret = %d!\n", __FUNCTION__, data->rpc_status);
+}
+
+static void nfs4_lock_release(void *calldata)
+{
+	struct nfs4_lockdata *data = calldata;
+
+	dprintk("%s: begin!\n", __FUNCTION__);
+	if (data->arg.open_seqid != NULL)
+		nfs_free_seqid(data->arg.open_seqid);
+	if (data->cancelled != 0) {
+		struct rpc_task *task;
+		task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp,
+				data->arg.lock_seqid);
+		if (!IS_ERR(task))
+			rpc_release_task(task);
+		dprintk("%s: cancelling lock!\n", __FUNCTION__);
+	} else
+		nfs_free_seqid(data->arg.lock_seqid);
+	nfs4_put_lock_state(data->lsp);
+	put_nfs_open_context(data->ctx);
+	kfree(data);
+	dprintk("%s: done!\n", __FUNCTION__);
+}
+
+static const struct rpc_call_ops nfs4_lock_ops = {
+	.rpc_call_prepare = nfs4_lock_prepare,
+	.rpc_call_done = nfs4_lock_done,
+	.rpc_release = nfs4_lock_release,
+};
+
+static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int reclaim)
+{
+	struct nfs4_lockdata *data;
+	struct rpc_task *task;
+	int ret;
+
+	dprintk("%s: begin!\n", __FUNCTION__);
+	data = nfs4_alloc_lockdata(fl, fl->fl_file->private_data,
+			fl->fl_u.nfs4_fl.owner);
+	if (data == NULL)
+		return -ENOMEM;
+	if (IS_SETLKW(cmd))
+		data->arg.block = 1;
+	if (reclaim != 0)
+		data->arg.reclaim = 1;
+	task = rpc_run_task(NFS_CLIENT(state->inode), RPC_TASK_ASYNC,
+			&nfs4_lock_ops, data);
+	if (IS_ERR(task)) {
+		nfs4_lock_release(data);
+		return PTR_ERR(task);
+	}
+	ret = nfs4_wait_for_completion_rpc_task(task);
+	if (ret == 0) {
+		ret = data->rpc_status;
+		if (ret == -NFS4ERR_DENIED)
+			ret = -EAGAIN;
+	} else
+		data->cancelled = 1;
+	rpc_release_task(task);
+	dprintk("%s: done, ret = %d!\n", __FUNCTION__, ret);
+	return ret;
 }
 
 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index a300162..5d764d8 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -54,6 +54,7 @@
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
 #include "nfs4_fs.h"
+#include "delegation.h"
 
 #define NFSDBG_FACILITY	NFSDBG_PROC
 
@@ -61,6 +62,7 @@
 nfs4_renew_state(void *data)
 {
 	struct nfs4_client *clp = (struct nfs4_client *)data;
+	struct rpc_cred *cred;
 	long lease, timeout;
 	unsigned long last, now;
 
@@ -68,7 +70,7 @@
 	dprintk("%s: start\n", __FUNCTION__);
 	/* Are there any active superblocks? */
 	if (list_empty(&clp->cl_superblocks))
-		goto out; 
+		goto out;
 	spin_lock(&clp->cl_lock);
 	lease = clp->cl_lease_time;
 	last = clp->cl_last_renewal;
@@ -76,9 +78,17 @@
 	timeout = (2 * lease) / 3 + (long)last - (long)now;
 	/* Are we close to a lease timeout? */
 	if (time_after(now, last + lease/3)) {
+		cred = nfs4_get_renew_cred(clp);
+		if (cred == NULL) {
+			set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
+			spin_unlock(&clp->cl_lock);
+			nfs_expire_all_delegations(clp);
+			goto out;
+		}
 		spin_unlock(&clp->cl_lock);
 		/* Queue an asynchronous RENEW. */
-		nfs4_proc_async_renew(clp);
+		nfs4_proc_async_renew(clp, cred);
+		put_rpccred(cred);
 		timeout = (2 * lease) / 3;
 		spin_lock(&clp->cl_lock);
 	} else
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 5ef4c57..afad025 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -43,6 +43,8 @@
 #include <linux/smp_lock.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_idmap.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
 #include <linux/workqueue.h>
 #include <linux/bitops.h>
 
@@ -57,8 +59,6 @@
 static DEFINE_SPINLOCK(state_spinlock);
 static LIST_HEAD(nfs4_clientid_list);
 
-static void nfs4_recover_state(void *);
-
 void
 init_nfsv4_state(struct nfs_server *server)
 {
@@ -91,11 +91,10 @@
 
 	if (nfs_callback_up() < 0)
 		return NULL;
-	if ((clp = kmalloc(sizeof(*clp), GFP_KERNEL)) == NULL) {
+	if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) {
 		nfs_callback_down();
 		return NULL;
 	}
-	memset(clp, 0, sizeof(*clp));
 	memcpy(&clp->cl_addr, addr, sizeof(clp->cl_addr));
 	init_rwsem(&clp->cl_sem);
 	INIT_LIST_HEAD(&clp->cl_delegations);
@@ -103,14 +102,12 @@
 	INIT_LIST_HEAD(&clp->cl_unused);
 	spin_lock_init(&clp->cl_lock);
 	atomic_set(&clp->cl_count, 1);
-	INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp);
 	INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
 	INIT_LIST_HEAD(&clp->cl_superblocks);
-	init_waitqueue_head(&clp->cl_waitq);
 	rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
 	clp->cl_rpcclient = ERR_PTR(-EINVAL);
 	clp->cl_boot_time = CURRENT_TIME;
-	clp->cl_state = 1 << NFS4CLNT_OK;
+	clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
 	return clp;
 }
 
@@ -127,8 +124,6 @@
 		kfree(sp);
 	}
 	BUG_ON(!list_empty(&clp->cl_state_owners));
-	if (clp->cl_cred)
-		put_rpccred(clp->cl_cred);
 	nfs_idmap_delete(clp);
 	if (!IS_ERR(clp->cl_rpcclient))
 		rpc_shutdown_client(clp->cl_rpcclient);
@@ -193,27 +188,22 @@
 	list_del(&clp->cl_servers);
 	spin_unlock(&state_spinlock);
 	BUG_ON(!list_empty(&clp->cl_superblocks));
-	wake_up_all(&clp->cl_waitq);
 	rpc_wake_up(&clp->cl_rpcwaitq);
 	nfs4_kill_renewd(clp);
 	nfs4_free_client(clp);
 }
 
-static int __nfs4_init_client(struct nfs4_client *clp)
+static int nfs4_init_client(struct nfs4_client *clp, struct rpc_cred *cred)
 {
-	int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, nfs_callback_tcpport);
+	int status = nfs4_proc_setclientid(clp, NFS4_CALLBACK,
+			nfs_callback_tcpport, cred);
 	if (status == 0)
-		status = nfs4_proc_setclientid_confirm(clp);
+		status = nfs4_proc_setclientid_confirm(clp, cred);
 	if (status == 0)
 		nfs4_schedule_state_renewal(clp);
 	return status;
 }
 
-int nfs4_init_client(struct nfs4_client *clp)
-{
-	return nfs4_map_errors(__nfs4_init_client(clp));
-}
-
 u32
 nfs4_alloc_lockowner_id(struct nfs4_client *clp)
 {
@@ -235,6 +225,32 @@
 	return sp;
 }
 
+struct rpc_cred *nfs4_get_renew_cred(struct nfs4_client *clp)
+{
+	struct nfs4_state_owner *sp;
+	struct rpc_cred *cred = NULL;
+
+	list_for_each_entry(sp, &clp->cl_state_owners, so_list) {
+		if (list_empty(&sp->so_states))
+			continue;
+		cred = get_rpccred(sp->so_cred);
+		break;
+	}
+	return cred;
+}
+
+struct rpc_cred *nfs4_get_setclientid_cred(struct nfs4_client *clp)
+{
+	struct nfs4_state_owner *sp;
+
+	if (!list_empty(&clp->cl_state_owners)) {
+		sp = list_entry(clp->cl_state_owners.next,
+				struct nfs4_state_owner, so_list);
+		return get_rpccred(sp->so_cred);
+	}
+	return NULL;
+}
+
 static struct nfs4_state_owner *
 nfs4_find_state_owner(struct nfs4_client *clp, struct rpc_cred *cred)
 {
@@ -349,14 +365,9 @@
 {
 	struct nfs4_state *state;
 
-	state = kmalloc(sizeof(*state), GFP_KERNEL);
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
-	state->state = 0;
-	state->nreaders = 0;
-	state->nwriters = 0;
-	state->flags = 0;
-	memset(state->stateid.data, 0, sizeof(state->stateid.data));
 	atomic_set(&state->count, 1);
 	INIT_LIST_HEAD(&state->lock_states);
 	spin_lock_init(&state->state_lock);
@@ -475,15 +486,23 @@
 	/* Protect against nfs4_find_state() */
 	spin_lock(&owner->so_lock);
 	spin_lock(&inode->i_lock);
-	if (mode & FMODE_READ)
-		state->nreaders--;
-	if (mode & FMODE_WRITE)
-		state->nwriters--;
+	switch (mode & (FMODE_READ | FMODE_WRITE)) {
+		case FMODE_READ:
+			state->n_rdonly--;
+			break;
+		case FMODE_WRITE:
+			state->n_wronly--;
+			break;
+		case FMODE_READ|FMODE_WRITE:
+			state->n_rdwr--;
+	}
 	oldstate = newstate = state->state;
-	if (state->nreaders == 0)
-		newstate &= ~FMODE_READ;
-	if (state->nwriters == 0)
-		newstate &= ~FMODE_WRITE;
+	if (state->n_rdwr == 0) {
+		if (state->n_rdonly == 0)
+			newstate &= ~FMODE_READ;
+		if (state->n_wronly == 0)
+			newstate &= ~FMODE_WRITE;
+	}
 	if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
 		nfs4_state_set_mode_locked(state, newstate);
 		oldstate = newstate;
@@ -733,45 +752,43 @@
 }
 
 static int reclaimer(void *);
-struct reclaimer_args {
-	struct nfs4_client *clp;
-	struct completion complete;
-};
+
+static inline void nfs4_clear_recover_bit(struct nfs4_client *clp)
+{
+	smp_mb__before_clear_bit();
+	clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state);
+	smp_mb__after_clear_bit();
+	wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER);
+	rpc_wake_up(&clp->cl_rpcwaitq);
+}
 
 /*
  * State recovery routine
  */
-void
-nfs4_recover_state(void *data)
+static void nfs4_recover_state(struct nfs4_client *clp)
 {
-	struct nfs4_client *clp = (struct nfs4_client *)data;
-	struct reclaimer_args args = {
-		.clp = clp,
-	};
-	might_sleep();
+	struct task_struct *task;
 
-	init_completion(&args.complete);
-
-	if (kernel_thread(reclaimer, &args, CLONE_KERNEL) < 0)
-		goto out_failed_clear;
-	wait_for_completion(&args.complete);
-	return;
-out_failed_clear:
-	set_bit(NFS4CLNT_OK, &clp->cl_state);
-	wake_up_all(&clp->cl_waitq);
-	rpc_wake_up(&clp->cl_rpcwaitq);
+	__module_get(THIS_MODULE);
+	atomic_inc(&clp->cl_count);
+	task = kthread_run(reclaimer, clp, "%u.%u.%u.%u-reclaim",
+			NIPQUAD(clp->cl_addr));
+	if (!IS_ERR(task))
+		return;
+	nfs4_clear_recover_bit(clp);
+	nfs4_put_client(clp);
+	module_put(THIS_MODULE);
 }
 
 /*
  * Schedule a state recovery attempt
  */
-void
-nfs4_schedule_state_recovery(struct nfs4_client *clp)
+void nfs4_schedule_state_recovery(struct nfs4_client *clp)
 {
 	if (!clp)
 		return;
-	if (test_and_clear_bit(NFS4CLNT_OK, &clp->cl_state))
-		schedule_work(&clp->cl_recoverd);
+	if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
+		nfs4_recover_state(clp);
 }
 
 static int nfs4_reclaim_locks(struct nfs4_state_recovery_ops *ops, struct nfs4_state *state)
@@ -887,18 +904,14 @@
 
 static int reclaimer(void *ptr)
 {
-	struct reclaimer_args *args = (struct reclaimer_args *)ptr;
-	struct nfs4_client *clp = args->clp;
+	struct nfs4_client *clp = ptr;
 	struct nfs4_state_owner *sp;
 	struct nfs4_state_recovery_ops *ops;
+	struct rpc_cred *cred;
 	int status = 0;
 
-	daemonize("%u.%u.%u.%u-reclaim", NIPQUAD(clp->cl_addr));
 	allow_signal(SIGKILL);
 
-	atomic_inc(&clp->cl_count);
-	complete(&args->complete);
-
 	/* Ensure exclusive access to NFSv4 state */
 	lock_kernel();
 	down_write(&clp->cl_sem);
@@ -906,20 +919,33 @@
 	if (list_empty(&clp->cl_superblocks))
 		goto out;
 restart_loop:
-	status = nfs4_proc_renew(clp);
-	switch (status) {
-		case 0:
-		case -NFS4ERR_CB_PATH_DOWN:
-			goto out;
-		case -NFS4ERR_STALE_CLIENTID:
-		case -NFS4ERR_LEASE_MOVED:
-			ops = &nfs4_reboot_recovery_ops;
-			break;
-		default:
-			ops = &nfs4_network_partition_recovery_ops;
-	};
+	ops = &nfs4_network_partition_recovery_ops;
+	/* Are there any open files on this volume? */
+	cred = nfs4_get_renew_cred(clp);
+	if (cred != NULL) {
+		/* Yes there are: try to renew the old lease */
+		status = nfs4_proc_renew(clp, cred);
+		switch (status) {
+			case 0:
+			case -NFS4ERR_CB_PATH_DOWN:
+				put_rpccred(cred);
+				goto out;
+			case -NFS4ERR_STALE_CLIENTID:
+			case -NFS4ERR_LEASE_MOVED:
+				ops = &nfs4_reboot_recovery_ops;
+		}
+	} else {
+		/* "reboot" to ensure we clear all state on the server */
+		clp->cl_boot_time = CURRENT_TIME;
+		cred = nfs4_get_setclientid_cred(clp);
+	}
+	/* We're going to have to re-establish a clientid */
 	nfs4_state_mark_reclaim(clp);
-	status = __nfs4_init_client(clp);
+	status = -ENOENT;
+	if (cred != NULL) {
+		status = nfs4_init_client(clp, cred);
+		put_rpccred(cred);
+	}
 	if (status)
 		goto out_error;
 	/* Mark all delegations for reclaim */
@@ -940,14 +966,13 @@
 	}
 	nfs_delegation_reap_unclaimed(clp);
 out:
-	set_bit(NFS4CLNT_OK, &clp->cl_state);
 	up_write(&clp->cl_sem);
 	unlock_kernel();
-	wake_up_all(&clp->cl_waitq);
-	rpc_wake_up(&clp->cl_rpcwaitq);
 	if (status == -NFS4ERR_CB_PATH_DOWN)
 		nfs_handle_cb_pathdown(clp);
+	nfs4_clear_recover_bit(clp);
 	nfs4_put_client(clp);
+	module_put_and_exit(0);
 	return 0;
 out_error:
 	printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %u.%u.%u.%u with error %d\n",
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index fbbace8..4bbf5ef 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -392,9 +392,11 @@
 				decode_getattr_maxsz)
 #define NFS4_enc_delegreturn_sz	(compound_encode_hdr_maxsz + \
 				encode_putfh_maxsz + \
-				encode_delegreturn_maxsz)
+				encode_delegreturn_maxsz + \
+				encode_getattr_maxsz)
 #define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
-				decode_delegreturn_maxsz)
+				decode_delegreturn_maxsz + \
+				decode_getattr_maxsz)
 #define NFS4_enc_getacl_sz	(compound_encode_hdr_maxsz + \
 				encode_putfh_maxsz + \
 				encode_getattr_maxsz)
@@ -564,7 +566,7 @@
 	}
 	if (iap->ia_valid & ATTR_MODE) {
 		bmval1 |= FATTR4_WORD1_MODE;
-		WRITE32(iap->ia_mode);
+		WRITE32(iap->ia_mode & S_IALLUGO);
 	}
 	if (iap->ia_valid & ATTR_UID) {
 		bmval1 |= FATTR4_WORD1_OWNER;
@@ -742,69 +744,80 @@
 	return 0;
 }
 
+static inline int nfs4_lock_type(struct file_lock *fl, int block)
+{
+	if ((fl->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) == F_RDLCK)
+		return block ? NFS4_READW_LT : NFS4_READ_LT;
+	return block ? NFS4_WRITEW_LT : NFS4_WRITE_LT;
+}
+
+static inline uint64_t nfs4_lock_length(struct file_lock *fl)
+{
+	if (fl->fl_end == OFFSET_MAX)
+		return ~(uint64_t)0;
+	return fl->fl_end - fl->fl_start + 1;
+}
+
 /*
  * opcode,type,reclaim,offset,length,new_lock_owner = 32
  * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
  */
-static int encode_lock(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
+static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)
 {
 	uint32_t *p;
-	struct nfs_lock_opargs *opargs = arg->u.lock;
 
 	RESERVE_SPACE(32);
 	WRITE32(OP_LOCK);
-	WRITE32(arg->type); 
-	WRITE32(opargs->reclaim);
-	WRITE64(arg->offset);
-	WRITE64(arg->length);
-	WRITE32(opargs->new_lock_owner);
-	if (opargs->new_lock_owner){
+	WRITE32(nfs4_lock_type(args->fl, args->block));
+	WRITE32(args->reclaim);
+	WRITE64(args->fl->fl_start);
+	WRITE64(nfs4_lock_length(args->fl));
+	WRITE32(args->new_lock_owner);
+	if (args->new_lock_owner){
 		RESERVE_SPACE(40);
-		WRITE32(opargs->open_seqid->sequence->counter);
-		WRITEMEM(opargs->open_stateid->data, sizeof(opargs->open_stateid->data));
-		WRITE32(opargs->lock_seqid->sequence->counter);
-		WRITE64(opargs->lock_owner.clientid);
+		WRITE32(args->open_seqid->sequence->counter);
+		WRITEMEM(args->open_stateid->data, sizeof(args->open_stateid->data));
+		WRITE32(args->lock_seqid->sequence->counter);
+		WRITE64(args->lock_owner.clientid);
 		WRITE32(4);
-		WRITE32(opargs->lock_owner.id);
+		WRITE32(args->lock_owner.id);
 	}
 	else {
 		RESERVE_SPACE(20);
-		WRITEMEM(opargs->lock_stateid->data, sizeof(opargs->lock_stateid->data));
-		WRITE32(opargs->lock_seqid->sequence->counter);
+		WRITEMEM(args->lock_stateid->data, sizeof(args->lock_stateid->data));
+		WRITE32(args->lock_seqid->sequence->counter);
 	}
 
 	return 0;
 }
 
-static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
+static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args)
 {
 	uint32_t *p;
-	struct nfs_lowner *opargs = arg->u.lockt;
 
 	RESERVE_SPACE(40);
 	WRITE32(OP_LOCKT);
-	WRITE32(arg->type);
-	WRITE64(arg->offset);
-	WRITE64(arg->length);
-	WRITE64(opargs->clientid);
+	WRITE32(nfs4_lock_type(args->fl, 0));
+	WRITE64(args->fl->fl_start);
+	WRITE64(nfs4_lock_length(args->fl));
+	WRITE64(args->lock_owner.clientid);
 	WRITE32(4);
-	WRITE32(opargs->id);
+	WRITE32(args->lock_owner.id);
 
 	return 0;
 }
 
-static int encode_locku(struct xdr_stream *xdr, const struct nfs_lockargs *arg)
+static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args)
 {
 	uint32_t *p;
-	struct nfs_locku_opargs *opargs = arg->u.locku;
 
 	RESERVE_SPACE(44);
 	WRITE32(OP_LOCKU);
-	WRITE32(arg->type);
-	WRITE32(opargs->seqid->sequence->counter);
-	WRITEMEM(opargs->stateid->data, sizeof(opargs->stateid->data));
-	WRITE64(arg->offset);
-	WRITE64(arg->length);
+	WRITE32(nfs4_lock_type(args->fl, 0));
+	WRITE32(args->seqid->sequence->counter);
+	WRITEMEM(args->stateid->data, sizeof(args->stateid->data));
+	WRITE64(args->fl->fl_start);
+	WRITE64(nfs4_lock_length(args->fl));
 
 	return 0;
 }
@@ -964,9 +977,9 @@
 {
 	uint32_t *p;
 
-	RESERVE_SPACE(8+sizeof(arg->stateid.data));
+	RESERVE_SPACE(8+sizeof(arg->stateid->data));
 	WRITE32(OP_OPEN_CONFIRM);
-	WRITEMEM(arg->stateid.data, sizeof(arg->stateid.data));
+	WRITEMEM(arg->stateid->data, sizeof(arg->stateid->data));
 	WRITE32(arg->seqid->sequence->counter);
 
 	return 0;
@@ -1499,9 +1512,6 @@
 	};
 	int status;
 
-	status = nfs_wait_on_sequence(args->seqid, req->rq_task);
-	if (status != 0)
-		goto out;
 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
 	encode_compound_hdr(&xdr, &hdr);
 	status = encode_putfh(&xdr, args->fh);
@@ -1538,9 +1548,6 @@
 	};
 	int status;
 
-	status = nfs_wait_on_sequence(args->seqid, req->rq_task);
-	if (status != 0)
-		goto out;
 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
 	encode_compound_hdr(&xdr, &hdr);
 	status = encode_putfh(&xdr, args->fh);
@@ -1558,19 +1565,19 @@
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
-		.nops   = 2,
+		.nops   = 3,
 	};
 	int status;
 
-	status = nfs_wait_on_sequence(args->seqid, req->rq_task);
-	if (status != 0)
-		goto out;
 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
 	encode_compound_hdr(&xdr, &hdr);
 	status = encode_putfh(&xdr, args->fh);
 	if (status)
 		goto out;
 	status = encode_open(&xdr, args);
+	if (status)
+		goto out;
+	status = encode_getfattr(&xdr, args->bitmask);
 out:
 	return status;
 }
@@ -1602,21 +1609,14 @@
 /*
  * Encode a LOCK request
  */
-static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args)
+static int nfs4_xdr_enc_lock(struct rpc_rqst *req, uint32_t *p, struct nfs_lock_args *args)
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
 		.nops   = 2,
 	};
-	struct nfs_lock_opargs *opargs = args->u.lock;
 	int status;
 
-	status = nfs_wait_on_sequence(opargs->lock_seqid, req->rq_task);
-	if (status != 0)
-		goto out;
-	/* Do we need to do an open_to_lock_owner? */
-	if (opargs->lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)
-		opargs->new_lock_owner = 0;
 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
 	encode_compound_hdr(&xdr, &hdr);
 	status = encode_putfh(&xdr, args->fh);
@@ -1630,7 +1630,7 @@
 /*
  * Encode a LOCKT request
  */
-static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args)
+static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, uint32_t *p, struct nfs_lockt_args *args)
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
@@ -1651,7 +1651,7 @@
 /*
  * Encode a LOCKU request
  */
-static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_lockargs *args)
+static int nfs4_xdr_enc_locku(struct rpc_rqst *req, uint32_t *p, struct nfs_locku_args *args)
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
@@ -1985,14 +1985,20 @@
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr = {
-		.nops = 2,
+		.nops = 3,
 	};
 	int status;
 
 	xdr_init_encode(&xdr, &req->rq_snd_buf, p);
 	encode_compound_hdr(&xdr, &hdr);
-	if ((status = encode_putfh(&xdr, args->fhandle)) == 0)
-		status = encode_delegreturn(&xdr, args->stateid);
+	status = encode_putfh(&xdr, args->fhandle);
+	if (status != 0)
+		goto out;
+	status = encode_delegreturn(&xdr, args->stateid);
+	if (status != 0)
+		goto out;
+	status = encode_getfattr(&xdr, args->bitmask);
+out:
 	return status;
 }
 
@@ -2955,55 +2961,64 @@
 /*
  * We create the owner, so we know a proper owner.id length is 4.
  */
-static int decode_lock_denied (struct xdr_stream *xdr, struct nfs_lock_denied *denied)
+static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
 {
+	uint64_t offset, length, clientid;
 	uint32_t *p;
-	uint32_t namelen;
+	uint32_t namelen, type;
 
 	READ_BUF(32);
-	READ64(denied->offset);
-	READ64(denied->length);
-	READ32(denied->type);
-	READ64(denied->owner.clientid);
+	READ64(offset);
+	READ64(length);
+	READ32(type);
+	if (fl != NULL) {
+		fl->fl_start = (loff_t)offset;
+		fl->fl_end = fl->fl_start + (loff_t)length - 1;
+		if (length == ~(uint64_t)0)
+			fl->fl_end = OFFSET_MAX;
+		fl->fl_type = F_WRLCK;
+		if (type & 1)
+			fl->fl_type = F_RDLCK;
+		fl->fl_pid = 0;
+	}
+	READ64(clientid);
 	READ32(namelen);
 	READ_BUF(namelen);
-	if (namelen == 4)
-		READ32(denied->owner.id);
 	return -NFS4ERR_DENIED;
 }
 
-static int decode_lock(struct xdr_stream *xdr, struct nfs_lockres *res)
+static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
 {
 	uint32_t *p;
 	int status;
 
 	status = decode_op_hdr(xdr, OP_LOCK);
 	if (status == 0) {
-		READ_BUF(sizeof(res->u.stateid.data));
-		COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
+		READ_BUF(sizeof(res->stateid.data));
+		COPYMEM(res->stateid.data, sizeof(res->stateid.data));
 	} else if (status == -NFS4ERR_DENIED)
-		return decode_lock_denied(xdr, &res->u.denied);
+		return decode_lock_denied(xdr, NULL);
 	return status;
 }
 
-static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockres *res)
+static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res)
 {
 	int status;
 	status = decode_op_hdr(xdr, OP_LOCKT);
 	if (status == -NFS4ERR_DENIED)
-		return decode_lock_denied(xdr, &res->u.denied);
+		return decode_lock_denied(xdr, res->denied);
 	return status;
 }
 
-static int decode_locku(struct xdr_stream *xdr, struct nfs_lockres *res)
+static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
 {
 	uint32_t *p;
 	int status;
 
 	status = decode_op_hdr(xdr, OP_LOCKU);
 	if (status == 0) {
-		READ_BUF(sizeof(res->u.stateid.data));
-		COPYMEM(res->u.stateid.data, sizeof(res->u.stateid.data));
+		READ_BUF(sizeof(res->stateid.data));
+		COPYMEM(res->stateid.data, sizeof(res->stateid.data));
 	}
 	return status;
 }
@@ -3831,6 +3846,9 @@
         if (status)
                 goto out;
         status = decode_open(&xdr, res);
+        if (status)
+                goto out;
+	decode_getfattr(&xdr, res->f_attr, res->server);
 out:
         return status;
 }
@@ -3864,7 +3882,7 @@
 /*
  * Decode LOCK response
  */
-static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res)
+static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lock_res *res)
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr;
@@ -3885,7 +3903,7 @@
 /*
  * Decode LOCKT response
  */
-static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res)
+static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockt_res *res)
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr;
@@ -3906,7 +3924,7 @@
 /*
  * Decode LOCKU response
  */
-static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_lockres *res)
+static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, uint32_t *p, struct nfs_locku_res *res)
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr;
@@ -4174,7 +4192,7 @@
 /*
  * DELEGRETURN request
  */
-static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, void *dummy)
+static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, uint32_t *p, struct nfs4_delegreturnres *res)
 {
 	struct xdr_stream xdr;
 	struct compound_hdr hdr;
@@ -4182,11 +4200,14 @@
 
 	xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
 	status = decode_compound_hdr(&xdr, &hdr);
-	if (status == 0) {
-		status = decode_putfh(&xdr);
-		if (status == 0)
-			status = decode_delegreturn(&xdr);
-	}
+	if (status != 0)
+		goto out;
+	status = decode_putfh(&xdr);
+	if (status != 0)
+		goto out;
+	status = decode_delegreturn(&xdr);
+	decode_getfattr(&xdr, res->fattr, res->server);
+out:
 	return status;
 }
 
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index 1b272a1..e897e00 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -275,7 +275,9 @@
 			case Opt_noacl:
 				nfs_data.flags |= NFS_MOUNT_NOACL;
 				break;
-			default : 
+			default:
+				printk(KERN_WARNING "Root-NFS: unknown "
+					"option: %s\n", p);
 				return 0;
 		}
 	}
@@ -296,8 +298,8 @@
 	nfs_port          = -1;
 	nfs_data.version  = NFS_MOUNT_VERSION;
 	nfs_data.flags    = NFS_MOUNT_NONLM;	/* No lockd in nfs root yet */
-	nfs_data.rsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
-	nfs_data.wsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
+	nfs_data.rsize    = NFS_DEF_FILE_IO_SIZE;
+	nfs_data.wsize    = NFS_DEF_FILE_IO_SIZE;
 	nfs_data.acregmin = 3;
 	nfs_data.acregmax = 60;
 	nfs_data.acdirmin = 30;
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index a48a003..f5150d7 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -111,6 +111,9 @@
 	};
 	int	status;
 
+	/* Mask out the non-modebit related stuff from attr->ia_mode */
+	sattr->ia_mode &= S_IALLUGO;
+
 	dprintk("NFS call  setattr\n");
 	nfs_fattr_init(fattr);
 	status = rpc_call(NFS_CLIENT(inode), NFSPROC_SETATTR, &arg, fattr, 0);
@@ -375,6 +378,7 @@
 
 	dprintk("NFS call  link %s\n", name->name);
 	status = rpc_call(NFS_CLIENT(inode), NFSPROC_LINK, &arg, NULL, 0);
+	nfs_mark_for_revalidate(inode);
 	nfs_mark_for_revalidate(dir);
 	dprintk("NFS reply link: %d\n", status);
 	return status;
@@ -546,10 +550,9 @@
 
 extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
 
-static void
-nfs_read_done(struct rpc_task *task)
+static void nfs_read_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
+	struct nfs_read_data *data = calldata;
 
 	if (task->tk_status >= 0) {
 		nfs_refresh_inode(data->inode, data->res.fattr);
@@ -559,9 +562,14 @@
 		if (data->args.offset + data->args.count >= data->res.fattr->size)
 			data->res.eof = 1;
 	}
-	nfs_readpage_result(task);
+	nfs_readpage_result(task, calldata);
 }
 
+static const struct rpc_call_ops nfs_read_ops = {
+	.rpc_call_done = nfs_read_done,
+	.rpc_release = nfs_readdata_release,
+};
+
 static void
 nfs_proc_read_setup(struct nfs_read_data *data)
 {
@@ -579,20 +587,24 @@
 	flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs_read_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs_read_ops, data);
 	rpc_call_setup(task, &msg, 0);
 }
 
-static void
-nfs_write_done(struct rpc_task *task)
+static void nfs_write_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_write_data *data = (struct nfs_write_data *) task->tk_calldata;
+	struct nfs_write_data *data = calldata;
 
 	if (task->tk_status >= 0)
 		nfs_post_op_update_inode(data->inode, data->res.fattr);
-	nfs_writeback_done(task);
+	nfs_writeback_done(task, calldata);
 }
 
+static const struct rpc_call_ops nfs_write_ops = {
+	.rpc_call_done = nfs_write_done,
+	.rpc_release = nfs_writedata_release,
+};
+
 static void
 nfs_proc_write_setup(struct nfs_write_data *data, int how)
 {
@@ -613,7 +625,7 @@
 	flags = (how & FLUSH_SYNC) ? 0 : RPC_TASK_ASYNC;
 
 	/* Finalize the task. */
-	rpc_init_task(task, NFS_CLIENT(inode), nfs_write_done, flags);
+	rpc_init_task(task, NFS_CLIENT(inode), flags, &nfs_write_ops, data);
 	rpc_call_setup(task, &msg, 0);
 }
 
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 5f20eaf..05eb43f 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -42,9 +42,8 @@
 
 #define MIN_POOL_READ	(32)
 
-void nfs_readdata_release(struct rpc_task *task)
+void nfs_readdata_release(void *data)
 {
-        struct nfs_read_data   *data = (struct nfs_read_data *)task->tk_calldata;
         nfs_readdata_free(data);
 }
 
@@ -84,7 +83,7 @@
 	int		result;
 	struct nfs_read_data *rdata;
 
-	rdata = nfs_readdata_alloc();
+	rdata = nfs_readdata_alloc(1);
 	if (!rdata)
 		return -ENOMEM;
 
@@ -220,9 +219,6 @@
 	NFS_PROTO(inode)->read_setup(data);
 
 	data->task.tk_cookie = (unsigned long)inode;
-	data->task.tk_calldata = data;
-	/* Release requests */
-	data->task.tk_release = nfs_readdata_release;
 
 	dprintk("NFS: %4d initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n",
 			data->task.tk_pid,
@@ -287,7 +283,7 @@
 
 	nbytes = req->wb_bytes;
 	for(;;) {
-		data = nfs_readdata_alloc();
+		data = nfs_readdata_alloc(1);
 		if (!data)
 			goto out_bad;
 		INIT_LIST_HEAD(&data->pages);
@@ -343,7 +339,7 @@
 	if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE)
 		return nfs_pagein_multi(head, inode);
 
-	data = nfs_readdata_alloc();
+	data = nfs_readdata_alloc(NFS_SERVER(inode)->rpages);
 	if (!data)
 		goto out_bad;
 
@@ -452,9 +448,9 @@
  * This is the callback from RPC telling us whether a reply was
  * received or some error occurred (timeout or socket shutdown).
  */
-void nfs_readpage_result(struct rpc_task *task)
+void nfs_readpage_result(struct rpc_task *task, void *calldata)
 {
-	struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata;
+	struct nfs_read_data *data = calldata;
 	struct nfs_readargs *argp = &data->args;
 	struct nfs_readres *resp = &data->res;
 	int status = task->tk_status;
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
new file mode 100644
index 0000000..4c486eb
--- /dev/null
+++ b/fs/nfs/sysctl.c
@@ -0,0 +1,84 @@
+/*
+ * linux/fs/nfs/sysctl.c
+ *
+ * Sysctl interface to NFS parameters
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/linkage.h>
+#include <linux/ctype.h>
+#include <linux/fs.h>
+#include <linux/sysctl.h>
+#include <linux/module.h>
+#include <linux/nfs4.h>
+#include <linux/nfs_idmap.h>
+
+#include "callback.h"
+
+static const int nfs_set_port_min = 0;
+static const int nfs_set_port_max = 65535;
+static struct ctl_table_header *nfs_callback_sysctl_table;
+/*
+ * Something that isn't CTL_ANY, CTL_NONE or a value that may clash.
+ * Use the same values as fs/lockd/svc.c
+ */
+#define CTL_UNNUMBERED -2
+
+static ctl_table nfs_cb_sysctls[] = {
+#ifdef CONFIG_NFS_V4
+	{
+		.ctl_name = CTL_UNNUMBERED,
+		.procname = "nfs_callback_tcpport",
+		.data = &nfs_callback_set_tcpport,
+		.maxlen = sizeof(int),
+		.mode = 0644,
+		.proc_handler = &proc_dointvec_minmax,
+		.extra1 = (int *)&nfs_set_port_min,
+		.extra2 = (int *)&nfs_set_port_max,
+	},
+	{
+		.ctl_name = CTL_UNNUMBERED,
+		.procname = "idmap_cache_timeout",
+		.data = &nfs_idmap_cache_timeout,
+		.maxlen = sizeof(int),
+		.mode = 0644,
+		.proc_handler = &proc_dointvec_jiffies,
+		.strategy = &sysctl_jiffies,
+	},
+#endif
+	{ .ctl_name = 0 }
+};
+
+static ctl_table nfs_cb_sysctl_dir[] = {
+	{
+		.ctl_name = CTL_UNNUMBERED,
+		.procname = "nfs",
+		.mode = 0555,
+		.child = nfs_cb_sysctls,
+	},
+	{ .ctl_name = 0 }
+};
+
+static ctl_table nfs_cb_sysctl_root[] = {
+	{
+		.ctl_name = CTL_FS,
+		.procname = "fs",
+		.mode = 0555,
+		.child = nfs_cb_sysctl_dir,
+	},
+	{ .ctl_name = 0 }
+};
+
+int nfs_register_sysctl(void)
+{
+	nfs_callback_sysctl_table = register_sysctl_table(nfs_cb_sysctl_root, 0);
+	if (nfs_callback_sysctl_table == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+void nfs_unregister_sysctl(void)
+{
+	unregister_sysctl_table(nfs_callback_sysctl_table);
+	nfs_callback_sysctl_table = NULL;
+}
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index d639d17..a65c7b5 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -87,10 +87,9 @@
  * We delay initializing RPC info until after the call to dentry_iput()
  * in order to minimize races against rename().
  */
-static void
-nfs_async_unlink_init(struct rpc_task *task)
+static void nfs_async_unlink_init(struct rpc_task *task, void *calldata)
 {
-	struct nfs_unlinkdata	*data = (struct nfs_unlinkdata *)task->tk_calldata;
+	struct nfs_unlinkdata	*data = calldata;
 	struct dentry		*dir = data->dir;
 	struct rpc_message	msg = {
 		.rpc_cred	= data->cred,
@@ -116,10 +115,9 @@
  *
  * Do the directory attribute update.
  */
-static void
-nfs_async_unlink_done(struct rpc_task *task)
+static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_unlinkdata	*data = (struct nfs_unlinkdata *)task->tk_calldata;
+	struct nfs_unlinkdata	*data = calldata;
 	struct dentry		*dir = data->dir;
 	struct inode		*dir_i;
 
@@ -141,13 +139,18 @@
  * We need to call nfs_put_unlinkdata as a 'tk_release' task since the
  * rpc_task would be freed too.
  */
-static void
-nfs_async_unlink_release(struct rpc_task *task)
+static void nfs_async_unlink_release(void *calldata)
 {
-	struct nfs_unlinkdata	*data = (struct nfs_unlinkdata *)task->tk_calldata;
+	struct nfs_unlinkdata	*data = calldata;
 	nfs_put_unlinkdata(data);
 }
 
+static const struct rpc_call_ops nfs_unlink_ops = {
+	.rpc_call_prepare = nfs_async_unlink_init,
+	.rpc_call_done = nfs_async_unlink_done,
+	.rpc_release = nfs_async_unlink_release,
+};
+
 /**
  * nfs_async_unlink - asynchronous unlinking of a file
  * @dentry: dentry to unlink
@@ -157,7 +160,6 @@
 {
 	struct dentry	*dir = dentry->d_parent;
 	struct nfs_unlinkdata	*data;
-	struct rpc_task	*task;
 	struct rpc_clnt	*clnt = NFS_CLIENT(dir->d_inode);
 	int		status = -ENOMEM;
 
@@ -178,17 +180,13 @@
 	nfs_deletes = data;
 	data->count = 1;
 
-	task = &data->task;
-	rpc_init_task(task, clnt, nfs_async_unlink_done , RPC_TASK_ASYNC);
-	task->tk_calldata = data;
-	task->tk_action = nfs_async_unlink_init;
-	task->tk_release = nfs_async_unlink_release;
+	rpc_init_task(&data->task, clnt, RPC_TASK_ASYNC, &nfs_unlink_ops, data);
 
 	spin_lock(&dentry->d_lock);
 	dentry->d_flags |= DCACHE_NFSFS_RENAMED;
 	spin_unlock(&dentry->d_lock);
 
-	rpc_sleep_on(&nfs_delete_queue, task, NULL, NULL);
+	rpc_sleep_on(&nfs_delete_queue, &data->task, NULL, NULL);
 	status = 0;
  out:
 	return status;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 8f71e76..9449b68 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -89,24 +89,38 @@
 
 static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion);
 
-static inline struct nfs_write_data *nfs_commit_alloc(void)
+static inline struct nfs_write_data *nfs_commit_alloc(unsigned int pagecount)
 {
 	struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, SLAB_NOFS);
+
 	if (p) {
 		memset(p, 0, sizeof(*p));
 		INIT_LIST_HEAD(&p->pages);
+		if (pagecount < NFS_PAGEVEC_SIZE)
+			p->pagevec = &p->page_array[0];
+		else {
+			size_t size = ++pagecount * sizeof(struct page *);
+			p->pagevec = kmalloc(size, GFP_NOFS);
+			if (p->pagevec) {
+				memset(p->pagevec, 0, size);
+			} else {
+				mempool_free(p, nfs_commit_mempool);
+				p = NULL;
+			}
+		}
 	}
 	return p;
 }
 
 static inline void nfs_commit_free(struct nfs_write_data *p)
 {
+	if (p && (p->pagevec != &p->page_array[0]))
+		kfree(p->pagevec);
 	mempool_free(p, nfs_commit_mempool);
 }
 
-static void nfs_writedata_release(struct rpc_task *task)
+void nfs_writedata_release(void *wdata)
 {
-	struct nfs_write_data	*wdata = (struct nfs_write_data *)task->tk_calldata;
 	nfs_writedata_free(wdata);
 }
 
@@ -168,7 +182,7 @@
 	int		result, written = 0;
 	struct nfs_write_data *wdata;
 
-	wdata = nfs_writedata_alloc();
+	wdata = nfs_writedata_alloc(1);
 	if (!wdata)
 		return -ENOMEM;
 
@@ -189,6 +203,7 @@
 		(long long)NFS_FILEID(inode),
 		count, (long long)(page_offset(page) + offset));
 
+	set_page_writeback(page);
 	nfs_begin_data_update(inode);
 	do {
 		if (count < wsize)
@@ -221,6 +236,7 @@
 
 io_error:
 	nfs_end_data_update(inode);
+	end_page_writeback(page);
 	nfs_writedata_free(wdata);
 	return written ? written : result;
 }
@@ -230,19 +246,16 @@
 		unsigned int offset, unsigned int count)
 {
 	struct nfs_page	*req;
-	int		status;
 
 	req = nfs_update_request(ctx, inode, page, offset, count);
-	status = (IS_ERR(req)) ? PTR_ERR(req) : 0;
-	if (status < 0)
-		goto out;
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 	/* Update file length */
 	nfs_grow_file(page, offset, count);
 	/* Set the PG_uptodate flag? */
 	nfs_mark_uptodate(page, offset, count);
 	nfs_unlock_request(req);
- out:
-	return status;
+	return 0;
 }
 
 static int wb_priority(struct writeback_control *wbc)
@@ -302,11 +315,8 @@
 	lock_kernel();
 	if (!IS_SYNC(inode) && inode_referenced) {
 		err = nfs_writepage_async(ctx, inode, page, 0, offset);
-		if (err >= 0) {
-			err = 0;
-			if (wbc->for_reclaim)
-				nfs_flush_inode(inode, 0, 0, FLUSH_STABLE);
-		}
+		if (!wbc->for_writepages)
+			nfs_flush_inode(inode, 0, 0, wb_priority(wbc));
 	} else {
 		err = nfs_writepage_sync(ctx, inode, page, 0,
 						offset, priority);
@@ -875,9 +885,6 @@
 
 	data->task.tk_priority = flush_task_priority(how);
 	data->task.tk_cookie = (unsigned long)inode;
-	data->task.tk_calldata = data;
-	/* Release requests */
-	data->task.tk_release = nfs_writedata_release;
 
 	dprintk("NFS: %4d initiated write call (req %s/%Ld, %u bytes @ offset %Lu)\n",
 		data->task.tk_pid,
@@ -917,7 +924,7 @@
 
 	nbytes = req->wb_bytes;
 	for (;;) {
-		data = nfs_writedata_alloc();
+		data = nfs_writedata_alloc(1);
 		if (!data)
 			goto out_bad;
 		list_add(&data->pages, &list);
@@ -929,7 +936,7 @@
 	atomic_set(&req->wb_complete, requests);
 
 	ClearPageError(page);
-	SetPageWriteback(page);
+	set_page_writeback(page);
 	offset = 0;
 	nbytes = req->wb_bytes;
 	do {
@@ -981,7 +988,7 @@
 	if (NFS_SERVER(inode)->wsize < PAGE_CACHE_SIZE)
 		return nfs_flush_multi(head, inode, how);
 
-	data = nfs_writedata_alloc();
+	data = nfs_writedata_alloc(NFS_SERVER(inode)->wpages);
 	if (!data)
 		goto out_bad;
 
@@ -992,7 +999,7 @@
 		nfs_list_remove_request(req);
 		nfs_list_add_request(req, &data->pages);
 		ClearPageError(req->wb_page);
-		SetPageWriteback(req->wb_page);
+		set_page_writeback(req->wb_page);
 		*pages++ = req->wb_page;
 		count += req->wb_bytes;
 	}
@@ -1135,9 +1142,9 @@
 /*
  * This function is called when the WRITE call is complete.
  */
-void nfs_writeback_done(struct rpc_task *task)
+void nfs_writeback_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_write_data	*data = (struct nfs_write_data *) task->tk_calldata;
+	struct nfs_write_data	*data = calldata;
 	struct nfs_writeargs	*argp = &data->args;
 	struct nfs_writeres	*resp = &data->res;
 
@@ -1204,9 +1211,8 @@
 
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-static void nfs_commit_release(struct rpc_task *task)
+void nfs_commit_release(void *wdata)
 {
-	struct nfs_write_data	*wdata = (struct nfs_write_data *)task->tk_calldata;
 	nfs_commit_free(wdata);
 }
 
@@ -1242,9 +1248,6 @@
 
 	data->task.tk_priority = flush_task_priority(how);
 	data->task.tk_cookie = (unsigned long)inode;
-	data->task.tk_calldata = data;
-	/* Release requests */
-	data->task.tk_release = nfs_commit_release;
 	
 	dprintk("NFS: %4d initiated commit call\n", data->task.tk_pid);
 }
@@ -1253,12 +1256,12 @@
  * Commit dirty pages
  */
 static int
-nfs_commit_list(struct list_head *head, int how)
+nfs_commit_list(struct inode *inode, struct list_head *head, int how)
 {
 	struct nfs_write_data	*data;
 	struct nfs_page         *req;
 
-	data = nfs_commit_alloc();
+	data = nfs_commit_alloc(NFS_SERVER(inode)->wpages);
 
 	if (!data)
 		goto out_bad;
@@ -1281,10 +1284,9 @@
 /*
  * COMMIT call returned
  */
-void
-nfs_commit_done(struct rpc_task *task)
+void nfs_commit_done(struct rpc_task *task, void *calldata)
 {
-	struct nfs_write_data	*data = (struct nfs_write_data *)task->tk_calldata;
+	struct nfs_write_data	*data = calldata;
 	struct nfs_page		*req;
 	int res = 0;
 
@@ -1364,7 +1366,7 @@
 	res = nfs_scan_commit(inode, &head, 0, 0);
 	spin_unlock(&nfsi->req_lock);
 	if (res) {
-		error = nfs_commit_list(&head, how);
+		error = nfs_commit_list(inode, &head, how);
 		if (error < 0)
 			return error;
 	}
@@ -1375,22 +1377,23 @@
 int nfs_sync_inode(struct inode *inode, unsigned long idx_start,
 		  unsigned int npages, int how)
 {
-	int	error,
-		wait;
+	int nocommit = how & FLUSH_NOCOMMIT;
+	int wait = how & FLUSH_WAIT;
+	int error;
 
-	wait = how & FLUSH_WAIT;
-	how &= ~FLUSH_WAIT;
+	how &= ~(FLUSH_WAIT|FLUSH_NOCOMMIT);
 
 	do {
-		error = 0;
-		if (wait)
+		if (wait) {
 			error = nfs_wait_on_requests(inode, idx_start, npages);
-		if (error == 0)
-			error = nfs_flush_inode(inode, idx_start, npages, how);
-#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-		if (error == 0)
+			if (error != 0)
+				continue;
+		}
+		error = nfs_flush_inode(inode, idx_start, npages, how);
+		if (error != 0)
+			continue;
+		if (!nocommit)
 			error = nfs_commit_inode(inode, how);
-#endif
 	} while (error > 0);
 	return error;
 }
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 7cbf068..fc95c4d 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -107,7 +107,7 @@
 	dprintk("nfsd: SETACL(2acl)   %s\n", SVCFH_fmt(&argp->fh));
 
 	fh = fh_copy(&resp->fh, &argp->fh);
-	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
+	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_SATTR);
 
 	if (!nfserr) {
 		nfserr = nfserrno( nfsd_set_posix_acl(
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index 64ba405..16e10c1 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -101,7 +101,7 @@
 	int nfserr = 0;
 
 	fh = fh_copy(&resp->fh, &argp->fh);
-	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
+	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_SATTR);
 
 	if (!nfserr) {
 		nfserr = nfserrno( nfsd_set_posix_acl(
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 041380f..6d2dfed 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -56,13 +56,20 @@
 nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
 					   struct nfsd3_attrstat *resp)
 {
-	int	nfserr;
+	int	err, nfserr;
 
 	dprintk("nfsd: GETATTR(3)  %s\n",
-				SVCFH_fmt(&argp->fh));
+		SVCFH_fmt(&argp->fh));
 
 	fh_copy(&resp->fh, &argp->fh);
 	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
+	if (nfserr)
+		RETURN_STATUS(nfserr);
+
+	err = vfs_getattr(resp->fh.fh_export->ex_mnt,
+			  resp->fh.fh_dentry, &resp->stat);
+	nfserr = nfserrno(err);
+
 	RETURN_STATUS(nfserr);
 }
 
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 9147b85..243d94b 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -154,37 +154,34 @@
 }
 
 static inline u32 *
-encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
+encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp,
+	      struct kstat *stat)
 {
-	struct vfsmount *mnt = fhp->fh_export->ex_mnt;
 	struct dentry	*dentry = fhp->fh_dentry;
-	struct kstat stat;
 	struct timespec time;
 
-	vfs_getattr(mnt, dentry, &stat);
-
-	*p++ = htonl(nfs3_ftypes[(stat.mode & S_IFMT) >> 12]);
-	*p++ = htonl((u32) stat.mode);
-	*p++ = htonl((u32) stat.nlink);
-	*p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid));
-	*p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid));
-	if (S_ISLNK(stat.mode) && stat.size > NFS3_MAXPATHLEN) {
+	*p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
+	*p++ = htonl((u32) stat->mode);
+	*p++ = htonl((u32) stat->nlink);
+	*p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
+	*p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
+	if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
 		p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
 	} else {
-		p = xdr_encode_hyper(p, (u64) stat.size);
+		p = xdr_encode_hyper(p, (u64) stat->size);
 	}
-	p = xdr_encode_hyper(p, ((u64)stat.blocks) << 9);
-	*p++ = htonl((u32) MAJOR(stat.rdev));
-	*p++ = htonl((u32) MINOR(stat.rdev));
+	p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
+	*p++ = htonl((u32) MAJOR(stat->rdev));
+	*p++ = htonl((u32) MINOR(stat->rdev));
 	if (is_fsid(fhp, rqstp->rq_reffh))
 		p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
 	else
-		p = xdr_encode_hyper(p, (u64) huge_encode_dev(stat.dev));
-	p = xdr_encode_hyper(p, (u64) stat.ino);
-	p = encode_time3(p, &stat.atime);
+		p = xdr_encode_hyper(p, (u64) huge_encode_dev(stat->dev));
+	p = xdr_encode_hyper(p, (u64) stat->ino);
+	p = encode_time3(p, &stat->atime);
 	lease_get_mtime(dentry->d_inode, &time); 
 	p = encode_time3(p, &time);
-	p = encode_time3(p, &stat.ctime);
+	p = encode_time3(p, &stat->ctime);
 
 	return p;
 }
@@ -232,8 +229,14 @@
 {
 	struct dentry *dentry = fhp->fh_dentry;
 	if (dentry && dentry->d_inode != NULL) {
-		*p++ = xdr_one;		/* attributes follow */
-		return encode_fattr3(rqstp, p, fhp);
+	        int err;
+		struct kstat stat;
+
+		err = vfs_getattr(fhp->fh_export->ex_mnt, dentry, &stat);
+		if (!err) {
+			*p++ = xdr_one;		/* attributes follow */
+			return encode_fattr3(rqstp, p, fhp, &stat);
+		}
 	}
 	*p++ = xdr_zero;
 	return p;
@@ -616,7 +619,7 @@
 					struct nfsd3_attrstat *resp)
 {
 	if (resp->status == 0)
-		p = encode_fattr3(rqstp, p, &resp->fh);
+		p = encode_fattr3(rqstp, p, &resp->fh, &resp->stat);
 	return xdr_ressize_check(rqstp, p);
 }
 
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 583c071..d828662 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -53,7 +53,7 @@
 #define NFSPROC4_CB_COMPOUND 1
 
 /* declarations */
-static void nfs4_cb_null(struct rpc_task *task);
+static const struct rpc_call_ops nfs4_cb_null_ops;
 
 /* Index of predefined Linux callback client operations */
 
@@ -431,7 +431,6 @@
 	}
 	clnt->cl_intr = 0;
 	clnt->cl_softrtry = 1;
-	clnt->cl_chatty = 1;
 
 	/* Kick rpciod, put the call on the wire. */
 
@@ -447,7 +446,7 @@
 	msg.rpc_cred = nfsd4_lookupcred(clp,0);
 	if (IS_ERR(msg.rpc_cred))
 		goto out_rpciod;
-	status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, nfs4_cb_null, NULL);
+	status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, &nfs4_cb_null_ops, NULL);
 	put_rpccred(msg.rpc_cred);
 
 	if (status != 0) {
@@ -469,7 +468,7 @@
 }
 
 static void
-nfs4_cb_null(struct rpc_task *task)
+nfs4_cb_null(struct rpc_task *task, void *dummy)
 {
 	struct nfs4_client *clp = (struct nfs4_client *)task->tk_msg.rpc_argp;
 	struct nfs4_callback *cb = &clp->cl_callback;
@@ -488,6 +487,10 @@
 	put_nfs4_client(clp);
 }
 
+static const struct rpc_call_ops nfs4_cb_null_ops = {
+	.rpc_call_done = nfs4_cb_null,
+};
+
 /*
  * called with dp->dl_count inc'ed.
  * nfs4_lock_state() may or may not have been called.
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index b45999f..aa7bb41 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -152,46 +152,44 @@
 }
 
 static inline u32 *
-encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
+encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp,
+	     struct kstat *stat)
 {
-	struct vfsmount *mnt = fhp->fh_export->ex_mnt;
 	struct dentry	*dentry = fhp->fh_dentry;
-	struct kstat stat;
 	int type;
 	struct timespec time;
 
-	vfs_getattr(mnt, dentry, &stat);
-	type = (stat.mode & S_IFMT);
+	type = (stat->mode & S_IFMT);
 
 	*p++ = htonl(nfs_ftypes[type >> 12]);
-	*p++ = htonl((u32) stat.mode);
-	*p++ = htonl((u32) stat.nlink);
-	*p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid));
-	*p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid));
+	*p++ = htonl((u32) stat->mode);
+	*p++ = htonl((u32) stat->nlink);
+	*p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid));
+	*p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid));
 
-	if (S_ISLNK(type) && stat.size > NFS_MAXPATHLEN) {
+	if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
 		*p++ = htonl(NFS_MAXPATHLEN);
 	} else {
-		*p++ = htonl((u32) stat.size);
+		*p++ = htonl((u32) stat->size);
 	}
-	*p++ = htonl((u32) stat.blksize);
+	*p++ = htonl((u32) stat->blksize);
 	if (S_ISCHR(type) || S_ISBLK(type))
-		*p++ = htonl(new_encode_dev(stat.rdev));
+		*p++ = htonl(new_encode_dev(stat->rdev));
 	else
 		*p++ = htonl(0xffffffff);
-	*p++ = htonl((u32) stat.blocks);
+	*p++ = htonl((u32) stat->blocks);
 	if (is_fsid(fhp, rqstp->rq_reffh))
 		*p++ = htonl((u32) fhp->fh_export->ex_fsid);
 	else
-		*p++ = htonl(new_encode_dev(stat.dev));
-	*p++ = htonl((u32) stat.ino);
-	*p++ = htonl((u32) stat.atime.tv_sec);
-	*p++ = htonl(stat.atime.tv_nsec ? stat.atime.tv_nsec / 1000 : 0);
+		*p++ = htonl(new_encode_dev(stat->dev));
+	*p++ = htonl((u32) stat->ino);
+	*p++ = htonl((u32) stat->atime.tv_sec);
+	*p++ = htonl(stat->atime.tv_nsec ? stat->atime.tv_nsec / 1000 : 0);
 	lease_get_mtime(dentry->d_inode, &time); 
 	*p++ = htonl((u32) time.tv_sec);
 	*p++ = htonl(time.tv_nsec ? time.tv_nsec / 1000 : 0); 
-	*p++ = htonl((u32) stat.ctime.tv_sec);
-	*p++ = htonl(stat.ctime.tv_nsec ? stat.ctime.tv_nsec / 1000 : 0);
+	*p++ = htonl((u32) stat->ctime.tv_sec);
+	*p++ = htonl(stat->ctime.tv_nsec ? stat->ctime.tv_nsec / 1000 : 0);
 
 	return p;
 }
@@ -199,7 +197,9 @@
 /* Helper function for NFSv2 ACL code */
 u32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 {
-	return encode_fattr(rqstp, p, fhp);
+	struct kstat stat;
+	vfs_getattr(fhp->fh_export->ex_mnt, fhp->fh_dentry, &stat);
+	return encode_fattr(rqstp, p, fhp, &stat);
 }
 
 /*
@@ -394,7 +394,7 @@
 nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd_attrstat *resp)
 {
-	p = encode_fattr(rqstp, p, &resp->fh);
+	p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
 	return xdr_ressize_check(rqstp, p);
 }
 
@@ -403,7 +403,7 @@
 					struct nfsd_diropres *resp)
 {
 	p = encode_fh(p, &resp->fh);
-	p = encode_fattr(rqstp, p, &resp->fh);
+	p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
 	return xdr_ressize_check(rqstp, p);
 }
 
@@ -428,7 +428,7 @@
 nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd_readres *resp)
 {
-	p = encode_fattr(rqstp, p, &resp->fh);
+	p = encode_fattr(rqstp, p, &resp->fh, &resp->stat);
 	*p++ = htonl(resp->count);
 	xdr_ressize_check(rqstp, p);
 
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index af7c3c3..df4019f 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -717,27 +717,33 @@
  * As this calls fsync (not fdatasync) there is no need for a write_inode
  * after it.
  */
-static inline void nfsd_dosync(struct file *filp, struct dentry *dp,
-			       struct file_operations *fop)
+static inline int nfsd_dosync(struct file *filp, struct dentry *dp,
+			      struct file_operations *fop)
 {
 	struct inode *inode = dp->d_inode;
 	int (*fsync) (struct file *, struct dentry *, int);
+	int err = nfs_ok;
 
 	filemap_fdatawrite(inode->i_mapping);
 	if (fop && (fsync = fop->fsync))
-		fsync(filp, dp, 0);
+		err=fsync(filp, dp, 0);
 	filemap_fdatawait(inode->i_mapping);
+
+	return nfserrno(err);
 }
 	
 
-static void
+static int
 nfsd_sync(struct file *filp)
 {
+        int err;
 	struct inode *inode = filp->f_dentry->d_inode;
 	dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
 	down(&inode->i_sem);
-	nfsd_dosync(filp, filp->f_dentry, filp->f_op);
+	err=nfsd_dosync(filp, filp->f_dentry, filp->f_op);
 	up(&inode->i_sem);
+
+	return err;
 }
 
 void
@@ -874,6 +880,16 @@
 	return err;
 }
 
+static void kill_suid(struct dentry *dentry)
+{
+	struct iattr	ia;
+	ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
+
+	down(&dentry->d_inode->i_sem);
+	notify_change(dentry, &ia);
+	up(&dentry->d_inode->i_sem);
+}
+
 static inline int
 nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 				loff_t offset, struct kvec *vec, int vlen,
@@ -927,14 +943,8 @@
 	}
 
 	/* clear setuid/setgid flag after write */
-	if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID))) {
-		struct iattr	ia;
-		ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
-
-		down(&inode->i_sem);
-		notify_change(dentry, &ia);
-		up(&inode->i_sem);
-	}
+	if (err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
+		kill_suid(dentry);
 
 	if (err >= 0 && stable) {
 		static ino_t	last_ino;
@@ -962,7 +972,7 @@
 
 			if (inode->i_state & I_DIRTY) {
 				dprintk("nfsd: write sync %d\n", current->pid);
-				nfsd_sync(file);
+				err=nfsd_sync(file);
 			}
 #if 0
 			wake_up(&inode->i_wait);
@@ -1066,7 +1076,7 @@
 		return err;
 	if (EX_ISSYNC(fhp->fh_export)) {
 		if (file->f_op && file->f_op->fsync) {
-			nfsd_sync(file);
+			err = nfsd_sync(file);
 		} else {
 			err = nfserr_notsupp;
 		}
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 50a7749..02f4409 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -884,7 +884,7 @@
 
 	- Add handling for initialized_size != data_size in compressed files.
 	- Reduce function local stack usage from 0x3d4 bytes to just noise in
-	  fs/ntfs/upcase.c. (Randy Dunlap <rddunlap@osdl.ord>)
+	  fs/ntfs/upcase.c. (Randy Dunlap <rdunlap@xenotime.net>)
 	- Remove compiler warnings for newer gcc.
 	- Pages are no longer kmapped by mm/filemap.c::generic_file_write()
 	  around calls to ->{prepare,commit}_write.  Adapt NTFS appropriately
diff --git a/fs/ocfs2/Makefile b/fs/ocfs2/Makefile
new file mode 100644
index 0000000..7d3be84
--- /dev/null
+++ b/fs/ocfs2/Makefile
@@ -0,0 +1,33 @@
+EXTRA_CFLAGS += -Ifs/ocfs2
+
+EXTRA_CFLAGS += -DCATCH_BH_JBD_RACES
+
+obj-$(CONFIG_OCFS2_FS) += ocfs2.o
+
+ocfs2-objs := \
+	alloc.o 		\
+	aops.o 			\
+	buffer_head_io.o	\
+	dcache.o 		\
+	dir.o 			\
+	dlmglue.o 		\
+	export.o 		\
+	extent_map.o 		\
+	file.o 			\
+	heartbeat.o 		\
+	inode.o 		\
+	journal.o 		\
+	localalloc.o 		\
+	mmap.o 			\
+	namei.o 		\
+	slot_map.o 		\
+	suballoc.o 		\
+	super.o 		\
+	symlink.o 		\
+	sysfile.o 		\
+	uptodate.o		\
+	ver.o 			\
+	vote.o
+
+obj-$(CONFIG_OCFS2_FS) += cluster/
+obj-$(CONFIG_OCFS2_FS) += dlm/
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
new file mode 100644
index 0000000..465f797
--- /dev/null
+++ b/fs/ocfs2/alloc.c
@@ -0,0 +1,2040 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * alloc.c
+ *
+ * Extent allocs and frees
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+
+#define MLOG_MASK_PREFIX ML_DISK_ALLOC
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "inode.h"
+#include "journal.h"
+#include "localalloc.h"
+#include "suballoc.h"
+#include "sysfile.h"
+#include "file.h"
+#include "super.h"
+#include "uptodate.h"
+
+#include "buffer_head_io.h"
+
+static int ocfs2_extent_contig(struct inode *inode,
+			       struct ocfs2_extent_rec *ext,
+			       u64 blkno);
+
+static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb,
+				     struct ocfs2_journal_handle *handle,
+				     struct inode *inode,
+				     int wanted,
+				     struct ocfs2_alloc_context *meta_ac,
+				     struct buffer_head *bhs[]);
+
+static int ocfs2_add_branch(struct ocfs2_super *osb,
+			    struct ocfs2_journal_handle *handle,
+			    struct inode *inode,
+			    struct buffer_head *fe_bh,
+			    struct buffer_head *eb_bh,
+			    struct buffer_head *last_eb_bh,
+			    struct ocfs2_alloc_context *meta_ac);
+
+static int ocfs2_shift_tree_depth(struct ocfs2_super *osb,
+				  struct ocfs2_journal_handle *handle,
+				  struct inode *inode,
+				  struct buffer_head *fe_bh,
+				  struct ocfs2_alloc_context *meta_ac,
+				  struct buffer_head **ret_new_eb_bh);
+
+static int ocfs2_do_insert_extent(struct ocfs2_super *osb,
+				  struct ocfs2_journal_handle *handle,
+				  struct inode *inode,
+				  struct buffer_head *fe_bh,
+				  u64 blkno,
+				  u32 new_clusters);
+
+static int ocfs2_find_branch_target(struct ocfs2_super *osb,
+				    struct inode *inode,
+				    struct buffer_head *fe_bh,
+				    struct buffer_head **target_bh);
+
+static int ocfs2_find_new_last_ext_blk(struct ocfs2_super *osb,
+				       struct inode *inode,
+				       struct ocfs2_dinode *fe,
+				       unsigned int new_i_clusters,
+				       struct buffer_head *old_last_eb,
+				       struct buffer_head **new_last_eb);
+
+static void ocfs2_free_truncate_context(struct ocfs2_truncate_context *tc);
+
+static int ocfs2_extent_contig(struct inode *inode,
+			       struct ocfs2_extent_rec *ext,
+			       u64 blkno)
+{
+	return blkno == (le64_to_cpu(ext->e_blkno) +
+			 ocfs2_clusters_to_blocks(inode->i_sb,
+						  le32_to_cpu(ext->e_clusters)));
+}
+
+/*
+ * How many free extents have we got before we need more meta data?
+ */
+int ocfs2_num_free_extents(struct ocfs2_super *osb,
+			   struct inode *inode,
+			   struct ocfs2_dinode *fe)
+{
+	int retval;
+	struct ocfs2_extent_list *el;
+	struct ocfs2_extent_block *eb;
+	struct buffer_head *eb_bh = NULL;
+
+	mlog_entry_void();
+
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe);
+		retval = -EIO;
+		goto bail;
+	}
+
+	if (fe->i_last_eb_blk) {
+		retval = ocfs2_read_block(osb, le64_to_cpu(fe->i_last_eb_blk),
+					  &eb_bh, OCFS2_BH_CACHED, inode);
+		if (retval < 0) {
+			mlog_errno(retval);
+			goto bail;
+		}
+		eb = (struct ocfs2_extent_block *) eb_bh->b_data;
+		el = &eb->h_list;
+	} else
+		el = &fe->id2.i_list;
+
+	BUG_ON(el->l_tree_depth != 0);
+
+	retval = le16_to_cpu(el->l_count) - le16_to_cpu(el->l_next_free_rec);
+bail:
+	if (eb_bh)
+		brelse(eb_bh);
+
+	mlog_exit(retval);
+	return retval;
+}
+
+/* expects array to already be allocated
+ *
+ * sets h_signature, h_blkno, h_suballoc_bit, h_suballoc_slot, and
+ * l_count for you
+ */
+static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb,
+				     struct ocfs2_journal_handle *handle,
+				     struct inode *inode,
+				     int wanted,
+				     struct ocfs2_alloc_context *meta_ac,
+				     struct buffer_head *bhs[])
+{
+	int count, status, i;
+	u16 suballoc_bit_start;
+	u32 num_got;
+	u64 first_blkno;
+	struct ocfs2_extent_block *eb;
+
+	mlog_entry_void();
+
+	count = 0;
+	while (count < wanted) {
+		status = ocfs2_claim_metadata(osb,
+					      handle,
+					      meta_ac,
+					      wanted - count,
+					      &suballoc_bit_start,
+					      &num_got,
+					      &first_blkno);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		for(i = count;  i < (num_got + count); i++) {
+			bhs[i] = sb_getblk(osb->sb, first_blkno);
+			if (bhs[i] == NULL) {
+				status = -EIO;
+				mlog_errno(status);
+				goto bail;
+			}
+			ocfs2_set_new_buffer_uptodate(inode, bhs[i]);
+
+			status = ocfs2_journal_access(handle, inode, bhs[i],
+						      OCFS2_JOURNAL_ACCESS_CREATE);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+
+			memset(bhs[i]->b_data, 0, osb->sb->s_blocksize);
+			eb = (struct ocfs2_extent_block *) bhs[i]->b_data;
+			/* Ok, setup the minimal stuff here. */
+			strcpy(eb->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE);
+			eb->h_blkno = cpu_to_le64(first_blkno);
+			eb->h_fs_generation = cpu_to_le32(osb->fs_generation);
+
+#ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS
+			/* we always use slot zero's suballocator */
+			eb->h_suballoc_slot = 0;
+#else
+			eb->h_suballoc_slot = cpu_to_le16(osb->slot_num);
+#endif
+			eb->h_suballoc_bit = cpu_to_le16(suballoc_bit_start);
+			eb->h_list.l_count =
+				cpu_to_le16(ocfs2_extent_recs_per_eb(osb->sb));
+
+			suballoc_bit_start++;
+			first_blkno++;
+
+			/* We'll also be dirtied by the caller, so
+			 * this isn't absolutely necessary. */
+			status = ocfs2_journal_dirty(handle, bhs[i]);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+		}
+
+		count += num_got;
+	}
+
+	status = 0;
+bail:
+	if (status < 0) {
+		for(i = 0; i < wanted; i++) {
+			if (bhs[i])
+				brelse(bhs[i]);
+			bhs[i] = NULL;
+		}
+	}
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * Add an entire tree branch to our inode. eb_bh is the extent block
+ * to start at, if we don't want to start the branch at the dinode
+ * structure.
+ *
+ * last_eb_bh is required as we have to update it's next_leaf pointer
+ * for the new last extent block.
+ *
+ * the new branch will be 'empty' in the sense that every block will
+ * contain a single record with e_clusters == 0.
+ */
+static int ocfs2_add_branch(struct ocfs2_super *osb,
+			    struct ocfs2_journal_handle *handle,
+			    struct inode *inode,
+			    struct buffer_head *fe_bh,
+			    struct buffer_head *eb_bh,
+			    struct buffer_head *last_eb_bh,
+			    struct ocfs2_alloc_context *meta_ac)
+{
+	int status, new_blocks, i;
+	u64 next_blkno, new_last_eb_blk;
+	struct buffer_head *bh;
+	struct buffer_head **new_eb_bhs = NULL;
+	struct ocfs2_dinode *fe;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_list  *eb_el;
+	struct ocfs2_extent_list  *el;
+
+	mlog_entry_void();
+
+	BUG_ON(!last_eb_bh);
+
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+
+	if (eb_bh) {
+		eb = (struct ocfs2_extent_block *) eb_bh->b_data;
+		el = &eb->h_list;
+	} else
+		el = &fe->id2.i_list;
+
+	/* we never add a branch to a leaf. */
+	BUG_ON(!el->l_tree_depth);
+
+	new_blocks = le16_to_cpu(el->l_tree_depth);
+
+	/* allocate the number of new eb blocks we need */
+	new_eb_bhs = kcalloc(new_blocks, sizeof(struct buffer_head *),
+			     GFP_KERNEL);
+	if (!new_eb_bhs) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_create_new_meta_bhs(osb, handle, inode, new_blocks,
+					   meta_ac, new_eb_bhs);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* Note: new_eb_bhs[new_blocks - 1] is the guy which will be
+	 * linked with the rest of the tree.
+	 * conversly, new_eb_bhs[0] is the new bottommost leaf.
+	 *
+	 * when we leave the loop, new_last_eb_blk will point to the
+	 * newest leaf, and next_blkno will point to the topmost extent
+	 * block. */
+	next_blkno = new_last_eb_blk = 0;
+	for(i = 0; i < new_blocks; i++) {
+		bh = new_eb_bhs[i];
+		eb = (struct ocfs2_extent_block *) bh->b_data;
+		if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+			OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, eb);
+			status = -EIO;
+			goto bail;
+		}
+		eb_el = &eb->h_list;
+
+		status = ocfs2_journal_access(handle, inode, bh,
+					      OCFS2_JOURNAL_ACCESS_CREATE);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		eb->h_next_leaf_blk = 0;
+		eb_el->l_tree_depth = cpu_to_le16(i);
+		eb_el->l_next_free_rec = cpu_to_le16(1);
+		eb_el->l_recs[0].e_cpos = fe->i_clusters;
+		eb_el->l_recs[0].e_blkno = cpu_to_le64(next_blkno);
+		eb_el->l_recs[0].e_clusters = cpu_to_le32(0);
+		if (!eb_el->l_tree_depth)
+			new_last_eb_blk = le64_to_cpu(eb->h_blkno);
+
+		status = ocfs2_journal_dirty(handle, bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		next_blkno = le64_to_cpu(eb->h_blkno);
+	}
+
+	/* This is a bit hairy. We want to update up to three blocks
+	 * here without leaving any of them in an inconsistent state
+	 * in case of error. We don't have to worry about
+	 * journal_dirty erroring as it won't unless we've aborted the
+	 * handle (in which case we would never be here) so reserving
+	 * the write with journal_access is all we need to do. */
+	status = ocfs2_journal_access(handle, inode, last_eb_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	status = ocfs2_journal_access(handle, inode, fe_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	if (eb_bh) {
+		status = ocfs2_journal_access(handle, inode, eb_bh,
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	/* Link the new branch into the rest of the tree (el will
+	 * either be on the fe, or the extent block passed in. */
+	i = le16_to_cpu(el->l_next_free_rec);
+	el->l_recs[i].e_blkno = cpu_to_le64(next_blkno);
+	el->l_recs[i].e_cpos = fe->i_clusters;
+	el->l_recs[i].e_clusters = 0;
+	le16_add_cpu(&el->l_next_free_rec, 1);
+
+	/* fe needs a new last extent block pointer, as does the
+	 * next_leaf on the previously last-extent-block. */
+	fe->i_last_eb_blk = cpu_to_le64(new_last_eb_blk);
+
+	eb = (struct ocfs2_extent_block *) last_eb_bh->b_data;
+	eb->h_next_leaf_blk = cpu_to_le64(new_last_eb_blk);
+
+	status = ocfs2_journal_dirty(handle, last_eb_bh);
+	if (status < 0)
+		mlog_errno(status);
+	status = ocfs2_journal_dirty(handle, fe_bh);
+	if (status < 0)
+		mlog_errno(status);
+	if (eb_bh) {
+		status = ocfs2_journal_dirty(handle, eb_bh);
+		if (status < 0)
+			mlog_errno(status);
+	}
+
+	status = 0;
+bail:
+	if (new_eb_bhs) {
+		for (i = 0; i < new_blocks; i++)
+			if (new_eb_bhs[i])
+				brelse(new_eb_bhs[i]);
+		kfree(new_eb_bhs);
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * adds another level to the allocation tree.
+ * returns back the new extent block so you can add a branch to it
+ * after this call.
+ */
+static int ocfs2_shift_tree_depth(struct ocfs2_super *osb,
+				  struct ocfs2_journal_handle *handle,
+				  struct inode *inode,
+				  struct buffer_head *fe_bh,
+				  struct ocfs2_alloc_context *meta_ac,
+				  struct buffer_head **ret_new_eb_bh)
+{
+	int status, i;
+	struct buffer_head *new_eb_bh = NULL;
+	struct ocfs2_dinode *fe;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_list  *fe_el;
+	struct ocfs2_extent_list  *eb_el;
+
+	mlog_entry_void();
+
+	status = ocfs2_create_new_meta_bhs(osb, handle, inode, 1, meta_ac,
+					   &new_eb_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	eb = (struct ocfs2_extent_block *) new_eb_bh->b_data;
+	if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+		OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, eb);
+		status = -EIO;
+		goto bail;
+	}
+
+	eb_el = &eb->h_list;
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+	fe_el = &fe->id2.i_list;
+
+	status = ocfs2_journal_access(handle, inode, new_eb_bh,
+				      OCFS2_JOURNAL_ACCESS_CREATE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* copy the fe data into the new extent block */
+	eb_el->l_tree_depth = fe_el->l_tree_depth;
+	eb_el->l_next_free_rec = fe_el->l_next_free_rec;
+	for(i = 0; i < le16_to_cpu(fe_el->l_next_free_rec); i++) {
+		eb_el->l_recs[i].e_cpos = fe_el->l_recs[i].e_cpos;
+		eb_el->l_recs[i].e_clusters = fe_el->l_recs[i].e_clusters;
+		eb_el->l_recs[i].e_blkno = fe_el->l_recs[i].e_blkno;
+	}
+
+	status = ocfs2_journal_dirty(handle, new_eb_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_journal_access(handle, inode, fe_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* update fe now */
+	le16_add_cpu(&fe_el->l_tree_depth, 1);
+	fe_el->l_recs[0].e_cpos = 0;
+	fe_el->l_recs[0].e_blkno = eb->h_blkno;
+	fe_el->l_recs[0].e_clusters = fe->i_clusters;
+	for(i = 1; i < le16_to_cpu(fe_el->l_next_free_rec); i++) {
+		fe_el->l_recs[i].e_cpos = 0;
+		fe_el->l_recs[i].e_clusters = 0;
+		fe_el->l_recs[i].e_blkno = 0;
+	}
+	fe_el->l_next_free_rec = cpu_to_le16(1);
+
+	/* If this is our 1st tree depth shift, then last_eb_blk
+	 * becomes the allocated extent block */
+	if (fe_el->l_tree_depth == cpu_to_le16(1))
+		fe->i_last_eb_blk = eb->h_blkno;
+
+	status = ocfs2_journal_dirty(handle, fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	*ret_new_eb_bh = new_eb_bh;
+	new_eb_bh = NULL;
+	status = 0;
+bail:
+	if (new_eb_bh)
+		brelse(new_eb_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * Expects the tree to already have room in the rightmost leaf for the
+ * extent.  Updates all the extent blocks (and the dinode) on the way
+ * down.
+ */
+static int ocfs2_do_insert_extent(struct ocfs2_super *osb,
+				  struct ocfs2_journal_handle *handle,
+				  struct inode *inode,
+				  struct buffer_head *fe_bh,
+				  u64 start_blk,
+				  u32 new_clusters)
+{
+	int status, i, num_bhs = 0;
+	u64 next_blkno;
+	u16 next_free;
+	struct buffer_head **eb_bhs = NULL;
+	struct ocfs2_dinode *fe;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_list  *el;
+
+	mlog_entry_void();
+
+	status = ocfs2_journal_access(handle, inode, fe_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+	el = &fe->id2.i_list;
+	if (el->l_tree_depth) {
+		/* This is another operation where we want to be
+		 * careful about our tree updates. An error here means
+		 * none of the previous changes we made should roll
+		 * forward. As a result, we have to record the buffers
+		 * for this part of the tree in an array and reserve a
+		 * journal write to them before making any changes. */
+		num_bhs = le16_to_cpu(fe->id2.i_list.l_tree_depth);
+		eb_bhs = kcalloc(num_bhs, sizeof(struct buffer_head *),
+				 GFP_KERNEL);
+		if (!eb_bhs) {
+			status = -ENOMEM;
+			mlog_errno(status);
+			goto bail;
+		}
+
+		i = 0;
+		while(el->l_tree_depth) {
+			next_free = le16_to_cpu(el->l_next_free_rec);
+			if (next_free == 0) {
+				ocfs2_error(inode->i_sb,
+					    "Dinode %"MLFu64" has a bad "
+					    "extent list",
+					    OCFS2_I(inode)->ip_blkno);
+				status = -EIO;
+				goto bail;
+			}
+			next_blkno = le64_to_cpu(el->l_recs[next_free - 1].e_blkno);
+
+			BUG_ON(i >= num_bhs);
+			status = ocfs2_read_block(osb, next_blkno, &eb_bhs[i],
+						  OCFS2_BH_CACHED, inode);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+			eb = (struct ocfs2_extent_block *) eb_bhs[i]->b_data;
+			if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+				OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb,
+								 eb);
+				status = -EIO;
+				goto bail;
+			}
+
+			status = ocfs2_journal_access(handle, inode, eb_bhs[i],
+						      OCFS2_JOURNAL_ACCESS_WRITE);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+
+			el = &eb->h_list;
+			i++;
+			/* When we leave this loop, eb_bhs[num_bhs - 1] will
+			 * hold the bottom-most leaf extent block. */
+		}
+		BUG_ON(el->l_tree_depth);
+
+		el = &fe->id2.i_list;
+		/* If we have tree depth, then the fe update is
+		 * trivial, and we want to switch el out for the
+		 * bottom-most leaf in order to update it with the
+		 * actual extent data below. */
+		next_free = le16_to_cpu(el->l_next_free_rec);
+		if (next_free == 0) {
+			ocfs2_error(inode->i_sb,
+				    "Dinode %"MLFu64" has a bad "
+				    "extent list",
+				    OCFS2_I(inode)->ip_blkno);
+			status = -EIO;
+			goto bail;
+		}
+		le32_add_cpu(&el->l_recs[next_free - 1].e_clusters,
+			     new_clusters);
+		/* (num_bhs - 1) to avoid the leaf */
+		for(i = 0; i < (num_bhs - 1); i++) {
+			eb = (struct ocfs2_extent_block *) eb_bhs[i]->b_data;
+			el = &eb->h_list;
+
+			/* finally, make our actual change to the
+			 * intermediate extent blocks. */
+			next_free = le16_to_cpu(el->l_next_free_rec);
+			le32_add_cpu(&el->l_recs[next_free - 1].e_clusters,
+				     new_clusters);
+
+			status = ocfs2_journal_dirty(handle, eb_bhs[i]);
+			if (status < 0)
+				mlog_errno(status);
+		}
+		BUG_ON(i != (num_bhs - 1));
+		/* note that the leaf block wasn't touched in
+		 * the loop above */
+		eb = (struct ocfs2_extent_block *) eb_bhs[num_bhs - 1]->b_data;
+		el = &eb->h_list;
+		BUG_ON(el->l_tree_depth);
+	}
+
+	/* yay, we can finally add the actual extent now! */
+	i = le16_to_cpu(el->l_next_free_rec) - 1;
+	if (le16_to_cpu(el->l_next_free_rec) &&
+	    ocfs2_extent_contig(inode, &el->l_recs[i], start_blk)) {
+		le32_add_cpu(&el->l_recs[i].e_clusters, new_clusters);
+	} else if (le16_to_cpu(el->l_next_free_rec) &&
+		   (le32_to_cpu(el->l_recs[i].e_clusters) == 0)) {
+		/* having an empty extent at eof is legal. */
+		if (el->l_recs[i].e_cpos != fe->i_clusters) {
+			ocfs2_error(inode->i_sb,
+				    "Dinode %"MLFu64" trailing extent is bad: "
+				    "cpos (%u) != number of clusters (%u)",
+				    le32_to_cpu(el->l_recs[i].e_cpos),
+				    le32_to_cpu(fe->i_clusters));
+			status = -EIO;
+			goto bail;
+		}
+		el->l_recs[i].e_blkno = cpu_to_le64(start_blk);
+		el->l_recs[i].e_clusters = cpu_to_le32(new_clusters);
+	} else {
+		/* No contiguous record, or no empty record at eof, so
+		 * we add a new one. */
+
+		BUG_ON(le16_to_cpu(el->l_next_free_rec) >=
+		       le16_to_cpu(el->l_count));
+		i = le16_to_cpu(el->l_next_free_rec);
+
+		el->l_recs[i].e_blkno = cpu_to_le64(start_blk);
+		el->l_recs[i].e_clusters = cpu_to_le32(new_clusters);
+		el->l_recs[i].e_cpos = fe->i_clusters;
+		le16_add_cpu(&el->l_next_free_rec, 1);
+	}
+
+	/*
+	 * extent_map errors are not fatal, so they are ignored outside
+	 * of flushing the thing.
+	 */
+	status = ocfs2_extent_map_append(inode, &el->l_recs[i],
+					 new_clusters);
+	if (status) {
+		mlog_errno(status);
+		ocfs2_extent_map_drop(inode, le32_to_cpu(fe->i_clusters));
+	}
+
+	status = ocfs2_journal_dirty(handle, fe_bh);
+	if (status < 0)
+		mlog_errno(status);
+	if (fe->id2.i_list.l_tree_depth) {
+		status = ocfs2_journal_dirty(handle, eb_bhs[num_bhs - 1]);
+		if (status < 0)
+			mlog_errno(status);
+	}
+
+	status = 0;
+bail:
+	if (eb_bhs) {
+		for (i = 0; i < num_bhs; i++)
+			if (eb_bhs[i])
+				brelse(eb_bhs[i]);
+		kfree(eb_bhs);
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * Should only be called when there is no space left in any of the
+ * leaf nodes. What we want to do is find the lowest tree depth
+ * non-leaf extent block with room for new records. There are three
+ * valid results of this search:
+ *
+ * 1) a lowest extent block is found, then we pass it back in
+ *    *lowest_eb_bh and return '0'
+ *
+ * 2) the search fails to find anything, but the dinode has room. We
+ *    pass NULL back in *lowest_eb_bh, but still return '0'
+ *
+ * 3) the search fails to find anything AND the dinode is full, in
+ *    which case we return > 0
+ *
+ * return status < 0 indicates an error.
+ */
+static int ocfs2_find_branch_target(struct ocfs2_super *osb,
+				    struct inode *inode,
+				    struct buffer_head *fe_bh,
+				    struct buffer_head **target_bh)
+{
+	int status = 0, i;
+	u64 blkno;
+	struct ocfs2_dinode *fe;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_list  *el;
+	struct buffer_head *bh = NULL;
+	struct buffer_head *lowest_bh = NULL;
+
+	mlog_entry_void();
+
+	*target_bh = NULL;
+
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+	el = &fe->id2.i_list;
+
+	while(le16_to_cpu(el->l_tree_depth) > 1) {
+		if (le16_to_cpu(el->l_next_free_rec) == 0) {
+			ocfs2_error(inode->i_sb, "Dinode %"MLFu64" has empty "
+				    "extent list (next_free_rec == 0)",
+				    OCFS2_I(inode)->ip_blkno);
+			status = -EIO;
+			goto bail;
+		}
+		i = le16_to_cpu(el->l_next_free_rec) - 1;
+		blkno = le64_to_cpu(el->l_recs[i].e_blkno);
+		if (!blkno) {
+			ocfs2_error(inode->i_sb, "Dinode %"MLFu64" has extent "
+				    "list where extent # %d has no physical "
+				    "block start",
+				    OCFS2_I(inode)->ip_blkno, i);
+			status = -EIO;
+			goto bail;
+		}
+
+		if (bh) {
+			brelse(bh);
+			bh = NULL;
+		}
+
+		status = ocfs2_read_block(osb, blkno, &bh, OCFS2_BH_CACHED,
+					  inode);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		eb = (struct ocfs2_extent_block *) bh->b_data;
+		if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+			OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, eb);
+			status = -EIO;
+			goto bail;
+		}
+		el = &eb->h_list;
+
+		if (le16_to_cpu(el->l_next_free_rec) <
+		    le16_to_cpu(el->l_count)) {
+			if (lowest_bh)
+				brelse(lowest_bh);
+			lowest_bh = bh;
+			get_bh(lowest_bh);
+		}
+	}
+
+	/* If we didn't find one and the fe doesn't have any room,
+	 * then return '1' */
+	if (!lowest_bh
+	    && (fe->id2.i_list.l_next_free_rec == fe->id2.i_list.l_count))
+		status = 1;
+
+	*target_bh = lowest_bh;
+bail:
+	if (bh)
+		brelse(bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+/* the caller needs to update fe->i_clusters */
+int ocfs2_insert_extent(struct ocfs2_super *osb,
+			struct ocfs2_journal_handle *handle,
+			struct inode *inode,
+			struct buffer_head *fe_bh,
+			u64 start_blk,
+			u32 new_clusters,
+			struct ocfs2_alloc_context *meta_ac)
+{
+	int status, i, shift;
+	struct buffer_head *last_eb_bh = NULL;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_dinode *fe;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_list  *el;
+
+	mlog_entry_void();
+
+	mlog(0, "add %u clusters starting at block %"MLFu64" to "
+		"inode %"MLFu64"\n",
+	     new_clusters, start_blk, OCFS2_I(inode)->ip_blkno);
+
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+	el = &fe->id2.i_list;
+
+	if (el->l_tree_depth) {
+		/* jump to end of tree */
+		status = ocfs2_read_block(osb, le64_to_cpu(fe->i_last_eb_blk),
+					  &last_eb_bh, OCFS2_BH_CACHED, inode);
+		if (status < 0) {
+			mlog_exit(status);
+			goto bail;
+		}
+		eb = (struct ocfs2_extent_block *) last_eb_bh->b_data;
+		el = &eb->h_list;
+	}
+
+	/* Can we allocate without adding/shifting tree bits? */
+	i = le16_to_cpu(el->l_next_free_rec) - 1;
+	if (le16_to_cpu(el->l_next_free_rec) == 0
+	    || (le16_to_cpu(el->l_next_free_rec) < le16_to_cpu(el->l_count))
+	    || le32_to_cpu(el->l_recs[i].e_clusters) == 0
+	    || ocfs2_extent_contig(inode, &el->l_recs[i], start_blk))
+		goto out_add;
+
+	mlog(0, "ocfs2_allocate_extent: couldn't do a simple add, traversing "
+	     "tree now.\n");
+
+	shift = ocfs2_find_branch_target(osb, inode, fe_bh, &bh);
+	if (shift < 0) {
+		status = shift;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* We traveled all the way to the bottom of the allocation tree
+	 * and didn't find room for any more extents - we need to add
+	 * another tree level */
+	if (shift) {
+		/* if we hit a leaf, we'd better be empty :) */
+		BUG_ON(le16_to_cpu(el->l_next_free_rec) !=
+		       le16_to_cpu(el->l_count));
+		BUG_ON(bh);
+		mlog(0, "ocfs2_allocate_extent: need to shift tree depth "
+		     "(current = %u)\n",
+		     le16_to_cpu(fe->id2.i_list.l_tree_depth));
+
+		/* ocfs2_shift_tree_depth will return us a buffer with
+		 * the new extent block (so we can pass that to
+		 * ocfs2_add_branch). */
+		status = ocfs2_shift_tree_depth(osb, handle, inode, fe_bh,
+						meta_ac, &bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		/* Special case: we have room now if we shifted from
+		 * tree_depth 0 */
+		if (fe->id2.i_list.l_tree_depth == cpu_to_le16(1))
+			goto out_add;
+	}
+
+	/* call ocfs2_add_branch to add the final part of the tree with
+	 * the new data. */
+	mlog(0, "ocfs2_allocate_extent: add branch. bh = %p\n", bh);
+	status = ocfs2_add_branch(osb, handle, inode, fe_bh, bh, last_eb_bh,
+				  meta_ac);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+out_add:
+	/* Finally, we can add clusters. */
+	status = ocfs2_do_insert_extent(osb, handle, inode, fe_bh,
+					start_blk, new_clusters);
+	if (status < 0)
+		mlog_errno(status);
+
+bail:
+	if (bh)
+		brelse(bh);
+
+	if (last_eb_bh)
+		brelse(last_eb_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+static inline int ocfs2_truncate_log_needs_flush(struct ocfs2_super *osb)
+{
+	struct buffer_head *tl_bh = osb->osb_tl_bh;
+	struct ocfs2_dinode *di;
+	struct ocfs2_truncate_log *tl;
+
+	di = (struct ocfs2_dinode *) tl_bh->b_data;
+	tl = &di->id2.i_dealloc;
+
+	mlog_bug_on_msg(le16_to_cpu(tl->tl_used) > le16_to_cpu(tl->tl_count),
+			"slot %d, invalid truncate log parameters: used = "
+			"%u, count = %u\n", osb->slot_num,
+			le16_to_cpu(tl->tl_used), le16_to_cpu(tl->tl_count));
+	return le16_to_cpu(tl->tl_used) == le16_to_cpu(tl->tl_count);
+}
+
+static int ocfs2_truncate_log_can_coalesce(struct ocfs2_truncate_log *tl,
+					   unsigned int new_start)
+{
+	unsigned int tail_index;
+	unsigned int current_tail;
+
+	/* No records, nothing to coalesce */
+	if (!le16_to_cpu(tl->tl_used))
+		return 0;
+
+	tail_index = le16_to_cpu(tl->tl_used) - 1;
+	current_tail = le32_to_cpu(tl->tl_recs[tail_index].t_start);
+	current_tail += le32_to_cpu(tl->tl_recs[tail_index].t_clusters);
+
+	return current_tail == new_start;
+}
+
+static int ocfs2_truncate_log_append(struct ocfs2_super *osb,
+				     struct ocfs2_journal_handle *handle,
+				     u64 start_blk,
+				     unsigned int num_clusters)
+{
+	int status, index;
+	unsigned int start_cluster, tl_count;
+	struct inode *tl_inode = osb->osb_tl_inode;
+	struct buffer_head *tl_bh = osb->osb_tl_bh;
+	struct ocfs2_dinode *di;
+	struct ocfs2_truncate_log *tl;
+
+	mlog_entry("start_blk = %"MLFu64", num_clusters = %u\n", start_blk,
+		   num_clusters);
+
+	BUG_ON(!down_trylock(&tl_inode->i_sem));
+
+	start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk);
+
+	di = (struct ocfs2_dinode *) tl_bh->b_data;
+	tl = &di->id2.i_dealloc;
+	if (!OCFS2_IS_VALID_DINODE(di)) {
+		OCFS2_RO_ON_INVALID_DINODE(osb->sb, di);
+		status = -EIO;
+		goto bail;
+	}
+
+	tl_count = le16_to_cpu(tl->tl_count);
+	mlog_bug_on_msg(tl_count > ocfs2_truncate_recs_per_inode(osb->sb) ||
+			tl_count == 0,
+			"Truncate record count on #%"MLFu64" invalid ("
+			"wanted %u, actual %u\n", OCFS2_I(tl_inode)->ip_blkno,
+			ocfs2_truncate_recs_per_inode(osb->sb),
+			le16_to_cpu(tl->tl_count));
+
+	/* Caller should have known to flush before calling us. */
+	index = le16_to_cpu(tl->tl_used);
+	if (index >= tl_count) {
+		status = -ENOSPC;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_journal_access(handle, tl_inode, tl_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	mlog(0, "Log truncate of %u clusters starting at cluster %u to "
+	     "%"MLFu64" (index = %d)\n", num_clusters, start_cluster,
+	     OCFS2_I(tl_inode)->ip_blkno, index);
+
+	if (ocfs2_truncate_log_can_coalesce(tl, start_cluster)) {
+		/*
+		 * Move index back to the record we are coalescing with.
+		 * ocfs2_truncate_log_can_coalesce() guarantees nonzero
+		 */
+		index--;
+
+		num_clusters += le32_to_cpu(tl->tl_recs[index].t_clusters);
+		mlog(0, "Coalesce with index %u (start = %u, clusters = %u)\n",
+		     index, le32_to_cpu(tl->tl_recs[index].t_start),
+		     num_clusters);
+	} else {
+		tl->tl_recs[index].t_start = cpu_to_le32(start_cluster);
+		tl->tl_used = cpu_to_le16(index + 1);
+	}
+	tl->tl_recs[index].t_clusters = cpu_to_le32(num_clusters);
+
+	status = ocfs2_journal_dirty(handle, tl_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
+					 struct ocfs2_journal_handle *handle,
+					 struct inode *data_alloc_inode,
+					 struct buffer_head *data_alloc_bh)
+{
+	int status = 0;
+	int i;
+	unsigned int num_clusters;
+	u64 start_blk;
+	struct ocfs2_truncate_rec rec;
+	struct ocfs2_dinode *di;
+	struct ocfs2_truncate_log *tl;
+	struct inode *tl_inode = osb->osb_tl_inode;
+	struct buffer_head *tl_bh = osb->osb_tl_bh;
+
+	mlog_entry_void();
+
+	di = (struct ocfs2_dinode *) tl_bh->b_data;
+	tl = &di->id2.i_dealloc;
+	i = le16_to_cpu(tl->tl_used) - 1;
+	while (i >= 0) {
+		/* Caller has given us at least enough credits to
+		 * update the truncate log dinode */
+		status = ocfs2_journal_access(handle, tl_inode, tl_bh,
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		tl->tl_used = cpu_to_le16(i);
+
+		status = ocfs2_journal_dirty(handle, tl_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		/* TODO: Perhaps we can calculate the bulk of the
+		 * credits up front rather than extending like
+		 * this. */
+		status = ocfs2_extend_trans(handle,
+					    OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		rec = tl->tl_recs[i];
+		start_blk = ocfs2_clusters_to_blocks(data_alloc_inode->i_sb,
+						    le32_to_cpu(rec.t_start));
+		num_clusters = le32_to_cpu(rec.t_clusters);
+
+		/* if start_blk is not set, we ignore the record as
+		 * invalid. */
+		if (start_blk) {
+			mlog(0, "free record %d, start = %u, clusters = %u\n",
+			     i, le32_to_cpu(rec.t_start), num_clusters);
+
+			status = ocfs2_free_clusters(handle, data_alloc_inode,
+						     data_alloc_bh, start_blk,
+						     num_clusters);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+		}
+		i--;
+	}
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/* Expects you to already be holding tl_inode->i_sem */
+static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
+{
+	int status;
+	unsigned int num_to_flush;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct inode *tl_inode = osb->osb_tl_inode;
+	struct inode *data_alloc_inode = NULL;
+	struct buffer_head *tl_bh = osb->osb_tl_bh;
+	struct buffer_head *data_alloc_bh = NULL;
+	struct ocfs2_dinode *di;
+	struct ocfs2_truncate_log *tl;
+
+	mlog_entry_void();
+
+	BUG_ON(!down_trylock(&tl_inode->i_sem));
+
+	di = (struct ocfs2_dinode *) tl_bh->b_data;
+	tl = &di->id2.i_dealloc;
+	if (!OCFS2_IS_VALID_DINODE(di)) {
+		OCFS2_RO_ON_INVALID_DINODE(osb->sb, di);
+		status = -EIO;
+		goto bail;
+	}
+
+	num_to_flush = le16_to_cpu(tl->tl_used);
+	mlog(0, "Flush %u records from truncate log #%"MLFu64"\n",
+	     num_to_flush, OCFS2_I(tl_inode)->ip_blkno);
+	if (!num_to_flush) {
+		status = 0;
+		goto bail;
+	}
+
+	handle = ocfs2_alloc_handle(osb);
+	if (!handle) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	data_alloc_inode = ocfs2_get_system_file_inode(osb,
+						       GLOBAL_BITMAP_SYSTEM_INODE,
+						       OCFS2_INVALID_SLOT);
+	if (!data_alloc_inode) {
+		status = -EINVAL;
+		mlog(ML_ERROR, "Could not get bitmap inode!\n");
+		goto bail;
+	}
+
+	ocfs2_handle_add_inode(handle, data_alloc_inode);
+	status = ocfs2_meta_lock(data_alloc_inode, handle, &data_alloc_bh, 1);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	handle = ocfs2_start_trans(osb, handle, OCFS2_TRUNCATE_LOG_UPDATE);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode,
+					       data_alloc_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+bail:
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (data_alloc_inode)
+		iput(data_alloc_inode);
+
+	if (data_alloc_bh)
+		brelse(data_alloc_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_flush_truncate_log(struct ocfs2_super *osb)
+{
+	int status;
+	struct inode *tl_inode = osb->osb_tl_inode;
+
+	down(&tl_inode->i_sem);
+	status = __ocfs2_flush_truncate_log(osb);
+	up(&tl_inode->i_sem);
+
+	return status;
+}
+
+static void ocfs2_truncate_log_worker(void *data)
+{
+	int status;
+	struct ocfs2_super *osb = data;
+
+	mlog_entry_void();
+
+	status = ocfs2_flush_truncate_log(osb);
+	if (status < 0)
+		mlog_errno(status);
+
+	mlog_exit(status);
+}
+
+#define OCFS2_TRUNCATE_LOG_FLUSH_INTERVAL (2 * HZ)
+void ocfs2_schedule_truncate_log_flush(struct ocfs2_super *osb,
+				       int cancel)
+{
+	if (osb->osb_tl_inode) {
+		/* We want to push off log flushes while truncates are
+		 * still running. */
+		if (cancel)
+			cancel_delayed_work(&osb->osb_truncate_log_wq);
+
+		queue_delayed_work(ocfs2_wq, &osb->osb_truncate_log_wq,
+				   OCFS2_TRUNCATE_LOG_FLUSH_INTERVAL);
+	}
+}
+
+static int ocfs2_get_truncate_log_info(struct ocfs2_super *osb,
+				       int slot_num,
+				       struct inode **tl_inode,
+				       struct buffer_head **tl_bh)
+{
+	int status;
+	struct inode *inode = NULL;
+	struct buffer_head *bh = NULL;
+
+	inode = ocfs2_get_system_file_inode(osb,
+					   TRUNCATE_LOG_SYSTEM_INODE,
+					   slot_num);
+	if (!inode) {
+		status = -EINVAL;
+		mlog(ML_ERROR, "Could not get load truncate log inode!\n");
+		goto bail;
+	}
+
+	status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &bh,
+				  OCFS2_BH_CACHED, inode);
+	if (status < 0) {
+		iput(inode);
+		mlog_errno(status);
+		goto bail;
+	}
+
+	*tl_inode = inode;
+	*tl_bh    = bh;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/* called during the 1st stage of node recovery. we stamp a clean
+ * truncate log and pass back a copy for processing later. if the
+ * truncate log does not require processing, a *tl_copy is set to
+ * NULL. */
+int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb,
+				      int slot_num,
+				      struct ocfs2_dinode **tl_copy)
+{
+	int status;
+	struct inode *tl_inode = NULL;
+	struct buffer_head *tl_bh = NULL;
+	struct ocfs2_dinode *di;
+	struct ocfs2_truncate_log *tl;
+
+	*tl_copy = NULL;
+
+	mlog(0, "recover truncate log from slot %d\n", slot_num);
+
+	status = ocfs2_get_truncate_log_info(osb, slot_num, &tl_inode, &tl_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	di = (struct ocfs2_dinode *) tl_bh->b_data;
+	tl = &di->id2.i_dealloc;
+	if (!OCFS2_IS_VALID_DINODE(di)) {
+		OCFS2_RO_ON_INVALID_DINODE(tl_inode->i_sb, di);
+		status = -EIO;
+		goto bail;
+	}
+
+	if (le16_to_cpu(tl->tl_used)) {
+		mlog(0, "We'll have %u logs to recover\n",
+		     le16_to_cpu(tl->tl_used));
+
+		*tl_copy = kmalloc(tl_bh->b_size, GFP_KERNEL);
+		if (!(*tl_copy)) {
+			status = -ENOMEM;
+			mlog_errno(status);
+			goto bail;
+		}
+
+		/* Assuming the write-out below goes well, this copy
+		 * will be passed back to recovery for processing. */
+		memcpy(*tl_copy, tl_bh->b_data, tl_bh->b_size);
+
+		/* All we need to do to clear the truncate log is set
+		 * tl_used. */
+		tl->tl_used = 0;
+
+		status = ocfs2_write_block(osb, tl_bh, tl_inode);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+bail:
+	if (tl_inode)
+		iput(tl_inode);
+	if (tl_bh)
+		brelse(tl_bh);
+
+	if (status < 0 && (*tl_copy)) {
+		kfree(*tl_copy);
+		*tl_copy = NULL;
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
+					 struct ocfs2_dinode *tl_copy)
+{
+	int status = 0;
+	int i;
+	unsigned int clusters, num_recs, start_cluster;
+	u64 start_blk;
+	struct ocfs2_journal_handle *handle;
+	struct inode *tl_inode = osb->osb_tl_inode;
+	struct ocfs2_truncate_log *tl;
+
+	mlog_entry_void();
+
+	if (OCFS2_I(tl_inode)->ip_blkno == le64_to_cpu(tl_copy->i_blkno)) {
+		mlog(ML_ERROR, "Asked to recover my own truncate log!\n");
+		return -EINVAL;
+	}
+
+	tl = &tl_copy->id2.i_dealloc;
+	num_recs = le16_to_cpu(tl->tl_used);
+	mlog(0, "cleanup %u records from %"MLFu64"\n", num_recs,
+	     tl_copy->i_blkno);
+
+	down(&tl_inode->i_sem);
+	for(i = 0; i < num_recs; i++) {
+		if (ocfs2_truncate_log_needs_flush(osb)) {
+			status = __ocfs2_flush_truncate_log(osb);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail_up;
+			}
+		}
+
+		handle = ocfs2_start_trans(osb, NULL,
+					   OCFS2_TRUNCATE_LOG_UPDATE);
+		if (IS_ERR(handle)) {
+			status = PTR_ERR(handle);
+			mlog_errno(status);
+			goto bail_up;
+		}
+
+		clusters = le32_to_cpu(tl->tl_recs[i].t_clusters);
+		start_cluster = le32_to_cpu(tl->tl_recs[i].t_start);
+		start_blk = ocfs2_clusters_to_blocks(osb->sb, start_cluster);
+
+		status = ocfs2_truncate_log_append(osb, handle,
+						   start_blk, clusters);
+		ocfs2_commit_trans(handle);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail_up;
+		}
+	}
+
+bail_up:
+	up(&tl_inode->i_sem);
+
+	mlog_exit(status);
+	return status;
+}
+
+void ocfs2_truncate_log_shutdown(struct ocfs2_super *osb)
+{
+	int status;
+	struct inode *tl_inode = osb->osb_tl_inode;
+
+	mlog_entry_void();
+
+	if (tl_inode) {
+		cancel_delayed_work(&osb->osb_truncate_log_wq);
+		flush_workqueue(ocfs2_wq);
+
+		status = ocfs2_flush_truncate_log(osb);
+		if (status < 0)
+			mlog_errno(status);
+
+		brelse(osb->osb_tl_bh);
+		iput(osb->osb_tl_inode);
+	}
+
+	mlog_exit_void();
+}
+
+int ocfs2_truncate_log_init(struct ocfs2_super *osb)
+{
+	int status;
+	struct inode *tl_inode = NULL;
+	struct buffer_head *tl_bh = NULL;
+
+	mlog_entry_void();
+
+	status = ocfs2_get_truncate_log_info(osb,
+					     osb->slot_num,
+					     &tl_inode,
+					     &tl_bh);
+	if (status < 0)
+		mlog_errno(status);
+
+	/* ocfs2_truncate_log_shutdown keys on the existence of
+	 * osb->osb_tl_inode so we don't set any of the osb variables
+	 * until we're sure all is well. */
+	INIT_WORK(&osb->osb_truncate_log_wq, ocfs2_truncate_log_worker, osb);
+	osb->osb_tl_bh    = tl_bh;
+	osb->osb_tl_inode = tl_inode;
+
+	mlog_exit(status);
+	return status;
+}
+
+/* This function will figure out whether the currently last extent
+ * block will be deleted, and if it will, what the new last extent
+ * block will be so we can update his h_next_leaf_blk field, as well
+ * as the dinodes i_last_eb_blk */
+static int ocfs2_find_new_last_ext_blk(struct ocfs2_super *osb,
+				       struct inode *inode,
+				       struct ocfs2_dinode *fe,
+				       u32 new_i_clusters,
+				       struct buffer_head *old_last_eb,
+				       struct buffer_head **new_last_eb)
+{
+	int i, status = 0;
+	u64 block = 0;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_list *el;
+	struct buffer_head *bh = NULL;
+
+	*new_last_eb = NULL;
+
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe);
+		status = -EIO;
+		goto bail;
+	}
+
+	/* we have no tree, so of course, no last_eb. */
+	if (!fe->id2.i_list.l_tree_depth)
+		goto bail;
+
+	/* trunc to zero special case - this makes tree_depth = 0
+	 * regardless of what it is.  */
+	if (!new_i_clusters)
+		goto bail;
+
+	eb = (struct ocfs2_extent_block *) old_last_eb->b_data;
+	el = &(eb->h_list);
+	BUG_ON(!el->l_next_free_rec);
+
+	/* Make sure that this guy will actually be empty after we
+	 * clear away the data. */
+	if (le32_to_cpu(el->l_recs[0].e_cpos) < new_i_clusters)
+		goto bail;
+
+	/* Ok, at this point, we know that last_eb will definitely
+	 * change, so lets traverse the tree and find the second to
+	 * last extent block. */
+	el = &(fe->id2.i_list);
+	/* go down the tree, */
+	do {
+		for(i = (le16_to_cpu(el->l_next_free_rec) - 1); i >= 0; i--) {
+			if (le32_to_cpu(el->l_recs[i].e_cpos) <
+			    new_i_clusters) {
+				block = le64_to_cpu(el->l_recs[i].e_blkno);
+				break;
+			}
+		}
+		BUG_ON(i < 0);
+
+		if (bh) {
+			brelse(bh);
+			bh = NULL;
+		}
+
+		status = ocfs2_read_block(osb, block, &bh, OCFS2_BH_CACHED,
+					 inode);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		eb = (struct ocfs2_extent_block *) bh->b_data;
+		el = &eb->h_list;
+		if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+			OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, eb);
+			status = -EIO;
+			goto bail;
+		}
+	} while (el->l_tree_depth);
+
+	*new_last_eb = bh;
+	get_bh(*new_last_eb);
+	mlog(0, "returning block %"MLFu64"\n", le64_to_cpu(eb->h_blkno));
+bail:
+	if (bh)
+		brelse(bh);
+
+	return status;
+}
+
+static int ocfs2_do_truncate(struct ocfs2_super *osb,
+			     unsigned int clusters_to_del,
+			     struct inode *inode,
+			     struct buffer_head *fe_bh,
+			     struct buffer_head *old_last_eb_bh,
+			     struct ocfs2_journal_handle *handle,
+			     struct ocfs2_truncate_context *tc)
+{
+	int status, i, depth;
+	struct ocfs2_dinode *fe;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_block *last_eb = NULL;
+	struct ocfs2_extent_list *el;
+	struct buffer_head *eb_bh = NULL;
+	struct buffer_head *last_eb_bh = NULL;
+	u64 next_eb = 0;
+	u64 delete_blk = 0;
+
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+
+	status = ocfs2_find_new_last_ext_blk(osb,
+					     inode,
+					     fe,
+					     le32_to_cpu(fe->i_clusters) -
+					     		clusters_to_del,
+					     old_last_eb_bh,
+					     &last_eb_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	if (last_eb_bh)
+		last_eb = (struct ocfs2_extent_block *) last_eb_bh->b_data;
+
+	status = ocfs2_journal_access(handle, inode, fe_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	el = &(fe->id2.i_list);
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters) -
+				      clusters_to_del;
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+	le32_add_cpu(&fe->i_clusters, -clusters_to_del);
+	fe->i_mtime = cpu_to_le64(CURRENT_TIME.tv_sec);
+	fe->i_mtime_nsec = cpu_to_le32(CURRENT_TIME.tv_nsec);
+
+	i = le16_to_cpu(el->l_next_free_rec) - 1;
+
+	BUG_ON(le32_to_cpu(el->l_recs[i].e_clusters) < clusters_to_del);
+	le32_add_cpu(&el->l_recs[i].e_clusters, -clusters_to_del);
+	/* tree depth zero, we can just delete the clusters, otherwise
+	 * we need to record the offset of the next level extent block
+	 * as we may overwrite it. */
+	if (!el->l_tree_depth)
+		delete_blk = le64_to_cpu(el->l_recs[i].e_blkno)
+			+ ocfs2_clusters_to_blocks(osb->sb,
+					le32_to_cpu(el->l_recs[i].e_clusters));
+	else
+		next_eb = le64_to_cpu(el->l_recs[i].e_blkno);
+
+	if (!el->l_recs[i].e_clusters) {
+		/* if we deleted the whole extent record, then clear
+		 * out the other fields and update the extent
+		 * list. For depth > 0 trees, we've already recorded
+		 * the extent block in 'next_eb' */
+		el->l_recs[i].e_cpos = 0;
+		el->l_recs[i].e_blkno = 0;
+		BUG_ON(!el->l_next_free_rec);
+		le16_add_cpu(&el->l_next_free_rec, -1);
+	}
+
+	depth = le16_to_cpu(el->l_tree_depth);
+	if (!fe->i_clusters) {
+		/* trunc to zero is a special case. */
+		el->l_tree_depth = 0;
+		fe->i_last_eb_blk = 0;
+	} else if (last_eb)
+		fe->i_last_eb_blk = last_eb->h_blkno;
+
+	status = ocfs2_journal_dirty(handle, fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	if (last_eb) {
+		/* If there will be a new last extent block, then by
+		 * definition, there cannot be any leaves to the right of
+		 * him. */
+		status = ocfs2_journal_access(handle, inode, last_eb_bh,
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		last_eb->h_next_leaf_blk = 0;
+		status = ocfs2_journal_dirty(handle, last_eb_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	/* if our tree depth > 0, update all the tree blocks below us. */
+	while (depth) {
+		mlog(0, "traveling tree (depth = %d, next_eb = %"MLFu64")\n",
+		     depth,  next_eb);
+		status = ocfs2_read_block(osb, next_eb, &eb_bh,
+					  OCFS2_BH_CACHED, inode);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		eb = (struct ocfs2_extent_block *)eb_bh->b_data;
+		if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+			OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, eb);
+			status = -EIO;
+			goto bail;
+		}
+		el = &(eb->h_list);
+
+		status = ocfs2_journal_access(handle, inode, eb_bh,
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		BUG_ON(le16_to_cpu(el->l_next_free_rec) == 0);
+		BUG_ON(depth != (le16_to_cpu(el->l_tree_depth) + 1));
+
+		i = le16_to_cpu(el->l_next_free_rec) - 1;
+
+		mlog(0, "extent block %"MLFu64", before: record %d: "
+		     "(%u, %u, %"MLFu64"), next = %u\n",
+		     le64_to_cpu(eb->h_blkno), i,
+		     le32_to_cpu(el->l_recs[i].e_cpos),
+		     le32_to_cpu(el->l_recs[i].e_clusters),
+		     le64_to_cpu(el->l_recs[i].e_blkno),
+		     le16_to_cpu(el->l_next_free_rec));
+
+		BUG_ON(le32_to_cpu(el->l_recs[i].e_clusters) < clusters_to_del);
+		le32_add_cpu(&el->l_recs[i].e_clusters, -clusters_to_del);
+
+		next_eb = le64_to_cpu(el->l_recs[i].e_blkno);
+		/* bottom-most block requires us to delete data.*/
+		if (!el->l_tree_depth)
+			delete_blk = le64_to_cpu(el->l_recs[i].e_blkno)
+				+ ocfs2_clusters_to_blocks(osb->sb,
+					le32_to_cpu(el->l_recs[i].e_clusters));
+		if (!el->l_recs[i].e_clusters) {
+			el->l_recs[i].e_cpos = 0;
+			el->l_recs[i].e_blkno = 0;
+			BUG_ON(!el->l_next_free_rec);
+			le16_add_cpu(&el->l_next_free_rec, -1);
+		}
+		mlog(0, "extent block %"MLFu64", after: record %d: "
+		     "(%u, %u, %"MLFu64"), next = %u\n",
+		     le64_to_cpu(eb->h_blkno), i,
+		     le32_to_cpu(el->l_recs[i].e_cpos),
+		     le32_to_cpu(el->l_recs[i].e_clusters),
+		     le64_to_cpu(el->l_recs[i].e_blkno),
+		     le16_to_cpu(el->l_next_free_rec));
+
+		status = ocfs2_journal_dirty(handle, eb_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		if (!el->l_next_free_rec) {
+			mlog(0, "deleting this extent block.\n");
+
+			ocfs2_remove_from_cache(inode, eb_bh);
+
+			BUG_ON(eb->h_suballoc_slot);
+			BUG_ON(el->l_recs[0].e_clusters);
+			BUG_ON(el->l_recs[0].e_cpos);
+			BUG_ON(el->l_recs[0].e_blkno);
+			status = ocfs2_free_extent_block(handle,
+							 tc->tc_ext_alloc_inode,
+							 tc->tc_ext_alloc_bh,
+							 eb);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+		}
+		brelse(eb_bh);
+		eb_bh = NULL;
+		depth--;
+	}
+
+	BUG_ON(!delete_blk);
+	status = ocfs2_truncate_log_append(osb, handle, delete_blk,
+					   clusters_to_del);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	status = 0;
+bail:
+	if (!status)
+		ocfs2_extent_map_trunc(inode, le32_to_cpu(fe->i_clusters));
+	else
+		ocfs2_extent_map_drop(inode, 0);
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * It is expected, that by the time you call this function,
+ * inode->i_size and fe->i_size have been adjusted.
+ *
+ * WARNING: This will kfree the truncate context
+ */
+int ocfs2_commit_truncate(struct ocfs2_super *osb,
+			  struct inode *inode,
+			  struct buffer_head *fe_bh,
+			  struct ocfs2_truncate_context *tc)
+{
+	int status, i, credits, tl_sem = 0;
+	u32 clusters_to_del, target_i_clusters;
+	u64 last_eb = 0;
+	struct ocfs2_dinode *fe;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_list *el;
+	struct buffer_head *last_eb_bh;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct inode *tl_inode = osb->osb_tl_inode;
+
+	mlog_entry_void();
+
+	down_write(&OCFS2_I(inode)->ip_alloc_sem);
+
+	target_i_clusters = ocfs2_clusters_for_bytes(osb->sb,
+						     i_size_read(inode));
+
+	last_eb_bh = tc->tc_last_eb_bh;
+	tc->tc_last_eb_bh = NULL;
+
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+
+	if (fe->id2.i_list.l_tree_depth) {
+		eb = (struct ocfs2_extent_block *) last_eb_bh->b_data;
+		el = &eb->h_list;
+	} else
+		el = &fe->id2.i_list;
+	last_eb = le64_to_cpu(fe->i_last_eb_blk);
+start:
+	mlog(0, "ocfs2_commit_truncate: fe->i_clusters = %u, "
+	     "last_eb = %"MLFu64", fe->i_last_eb_blk = %"MLFu64", "
+	     "fe->id2.i_list.l_tree_depth = %u last_eb_bh = %p\n",
+	     le32_to_cpu(fe->i_clusters), last_eb,
+	     le64_to_cpu(fe->i_last_eb_blk),
+	     le16_to_cpu(fe->id2.i_list.l_tree_depth), last_eb_bh);
+
+	if (last_eb != le64_to_cpu(fe->i_last_eb_blk)) {
+		mlog(0, "last_eb changed!\n");
+		BUG_ON(!fe->id2.i_list.l_tree_depth);
+		last_eb = le64_to_cpu(fe->i_last_eb_blk);
+		/* i_last_eb_blk may have changed, read it if
+		 * necessary. We don't have to worry about the
+		 * truncate to zero case here (where there becomes no
+		 * last_eb) because we never loop back after our work
+		 * is done. */
+		if (last_eb_bh) {
+			brelse(last_eb_bh);
+			last_eb_bh = NULL;
+		}
+
+		status = ocfs2_read_block(osb, last_eb,
+					  &last_eb_bh, OCFS2_BH_CACHED,
+					  inode);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		eb = (struct ocfs2_extent_block *) last_eb_bh->b_data;
+		if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+			OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, eb);
+			status = -EIO;
+			goto bail;
+		}
+		el = &(eb->h_list);
+	}
+
+	/* by now, el will point to the extent list on the bottom most
+	 * portion of this tree. */
+	i = le16_to_cpu(el->l_next_free_rec) - 1;
+	if (le32_to_cpu(el->l_recs[i].e_cpos) >= target_i_clusters)
+		clusters_to_del = le32_to_cpu(el->l_recs[i].e_clusters);
+	else
+		clusters_to_del = (le32_to_cpu(el->l_recs[i].e_clusters) +
+				   le32_to_cpu(el->l_recs[i].e_cpos)) -
+				  target_i_clusters;
+
+	mlog(0, "clusters_to_del = %u in this pass\n", clusters_to_del);
+
+	down(&tl_inode->i_sem);
+	tl_sem = 1;
+	/* ocfs2_truncate_log_needs_flush guarantees us at least one
+	 * record is free for use. If there isn't any, we flush to get
+	 * an empty truncate log.  */
+	if (ocfs2_truncate_log_needs_flush(osb)) {
+		status = __ocfs2_flush_truncate_log(osb);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	credits = ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del,
+						fe, el);
+	handle = ocfs2_start_trans(osb, NULL, credits);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	status = ocfs2_mark_inode_dirty(handle, inode, fe_bh);
+	if (status < 0)
+		mlog_errno(status);
+
+	status = ocfs2_do_truncate(osb, clusters_to_del, inode, fe_bh,
+				   last_eb_bh, handle, tc);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	up(&tl_inode->i_sem);
+	tl_sem = 0;
+
+	ocfs2_commit_trans(handle);
+	handle = NULL;
+
+	BUG_ON(le32_to_cpu(fe->i_clusters) < target_i_clusters);
+	if (le32_to_cpu(fe->i_clusters) > target_i_clusters)
+		goto start;
+bail:
+	up_write(&OCFS2_I(inode)->ip_alloc_sem);
+
+	ocfs2_schedule_truncate_log_flush(osb, 1);
+
+	if (tl_sem)
+		up(&tl_inode->i_sem);
+
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (last_eb_bh)
+		brelse(last_eb_bh);
+
+	/* This will drop the ext_alloc cluster lock for us */
+	ocfs2_free_truncate_context(tc);
+
+	mlog_exit(status);
+	return status;
+}
+
+
+/*
+ * Expects the inode to already be locked. This will figure out which
+ * inodes need to be locked and will put them on the returned truncate
+ * context.
+ */
+int ocfs2_prepare_truncate(struct ocfs2_super *osb,
+			   struct inode *inode,
+			   struct buffer_head *fe_bh,
+			   struct ocfs2_truncate_context **tc)
+{
+	int status, metadata_delete;
+	unsigned int new_i_clusters;
+	struct ocfs2_dinode *fe;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_list *el;
+	struct buffer_head *last_eb_bh = NULL;
+	struct inode *ext_alloc_inode = NULL;
+	struct buffer_head *ext_alloc_bh = NULL;
+
+	mlog_entry_void();
+
+	*tc = NULL;
+
+	new_i_clusters = ocfs2_clusters_for_bytes(osb->sb,
+						  i_size_read(inode));
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+
+	mlog(0, "fe->i_clusters = %u, new_i_clusters = %u, fe->i_size ="
+	     "%"MLFu64"\n", fe->i_clusters, new_i_clusters, fe->i_size);
+
+	if (le32_to_cpu(fe->i_clusters) <= new_i_clusters) {
+		ocfs2_error(inode->i_sb, "Dinode %"MLFu64" has cluster count "
+			    "%u and size %"MLFu64" whereas struct inode has "
+			    "cluster count %u and size %llu which caused an "
+			    "invalid truncate to %u clusters.",
+			    le64_to_cpu(fe->i_blkno),
+			    le32_to_cpu(fe->i_clusters),
+			    le64_to_cpu(fe->i_size),
+			    OCFS2_I(inode)->ip_clusters, i_size_read(inode),
+			    new_i_clusters);
+		mlog_meta_lvb(ML_ERROR, &OCFS2_I(inode)->ip_meta_lockres);
+		status = -EIO;
+		goto bail;
+	}
+
+	*tc = kcalloc(1, sizeof(struct ocfs2_truncate_context), GFP_KERNEL);
+	if (!(*tc)) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	metadata_delete = 0;
+	if (fe->id2.i_list.l_tree_depth) {
+		/* If we have a tree, then the truncate may result in
+		 * metadata deletes. Figure this out from the
+		 * rightmost leaf block.*/
+		status = ocfs2_read_block(osb, le64_to_cpu(fe->i_last_eb_blk),
+					  &last_eb_bh, OCFS2_BH_CACHED, inode);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		eb = (struct ocfs2_extent_block *) last_eb_bh->b_data;
+		if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+			OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, eb);
+
+			brelse(last_eb_bh);
+			status = -EIO;
+			goto bail;
+		}
+		el = &(eb->h_list);
+		if (le32_to_cpu(el->l_recs[0].e_cpos) >= new_i_clusters)
+			metadata_delete = 1;
+	}
+
+	(*tc)->tc_last_eb_bh = last_eb_bh;
+
+	if (metadata_delete) {
+		mlog(0, "Will have to delete metadata for this trunc. "
+		     "locking allocator.\n");
+		ext_alloc_inode = ocfs2_get_system_file_inode(osb, EXTENT_ALLOC_SYSTEM_INODE, 0);
+		if (!ext_alloc_inode) {
+			status = -ENOMEM;
+			mlog_errno(status);
+			goto bail;
+		}
+
+		down(&ext_alloc_inode->i_sem);
+		(*tc)->tc_ext_alloc_inode = ext_alloc_inode;
+
+		status = ocfs2_meta_lock(ext_alloc_inode,
+					 NULL,
+					 &ext_alloc_bh,
+					 1);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		(*tc)->tc_ext_alloc_bh = ext_alloc_bh;
+		(*tc)->tc_ext_alloc_locked = 1;
+	}
+
+	status = 0;
+bail:
+	if (status < 0) {
+		if (*tc)
+			ocfs2_free_truncate_context(*tc);
+		*tc = NULL;
+	}
+	mlog_exit_void();
+	return status;
+}
+
+static void ocfs2_free_truncate_context(struct ocfs2_truncate_context *tc)
+{
+	if (tc->tc_ext_alloc_inode) {
+		if (tc->tc_ext_alloc_locked)
+			ocfs2_meta_unlock(tc->tc_ext_alloc_inode, 1);
+
+		up(&tc->tc_ext_alloc_inode->i_sem);
+		iput(tc->tc_ext_alloc_inode);
+	}
+
+	if (tc->tc_ext_alloc_bh)
+		brelse(tc->tc_ext_alloc_bh);
+
+	if (tc->tc_last_eb_bh)
+		brelse(tc->tc_last_eb_bh);
+
+	kfree(tc);
+}
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
new file mode 100644
index 0000000..12ba897
--- /dev/null
+++ b/fs/ocfs2/alloc.h
@@ -0,0 +1,82 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * alloc.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_ALLOC_H
+#define OCFS2_ALLOC_H
+
+struct ocfs2_alloc_context;
+int ocfs2_insert_extent(struct ocfs2_super *osb,
+			struct ocfs2_journal_handle *handle,
+			struct inode *inode,
+			struct buffer_head *fe_bh,
+			u64 blkno,
+			u32 new_clusters,
+			struct ocfs2_alloc_context *meta_ac);
+int ocfs2_num_free_extents(struct ocfs2_super *osb,
+			   struct inode *inode,
+			   struct ocfs2_dinode *fe);
+/* how many new metadata chunks would an allocation need at maximum? */
+static inline int ocfs2_extend_meta_needed(struct ocfs2_dinode *fe)
+{
+	/*
+	 * Rather than do all the work of determining how much we need
+	 * (involves a ton of reads and locks), just ask for the
+	 * maximal limit.  That's a tree depth shift.  So, one block for
+	 * level of the tree (current l_tree_depth), one block for the
+	 * new tree_depth==0 extent_block, and one block at the new
+	 * top-of-the tree.
+	 */
+	return le16_to_cpu(fe->id2.i_list.l_tree_depth) + 2;
+}
+
+int ocfs2_truncate_log_init(struct ocfs2_super *osb);
+void ocfs2_truncate_log_shutdown(struct ocfs2_super *osb);
+void ocfs2_schedule_truncate_log_flush(struct ocfs2_super *osb,
+				       int cancel);
+int ocfs2_flush_truncate_log(struct ocfs2_super *osb);
+int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb,
+				      int slot_num,
+				      struct ocfs2_dinode **tl_copy);
+int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
+					 struct ocfs2_dinode *tl_copy);
+
+struct ocfs2_truncate_context {
+	struct inode *tc_ext_alloc_inode;
+	struct buffer_head *tc_ext_alloc_bh;
+	int tc_ext_alloc_locked; /* is it cluster locked? */
+	/* these get destroyed once it's passed to ocfs2_commit_truncate. */
+	struct buffer_head *tc_last_eb_bh;
+};
+
+int ocfs2_prepare_truncate(struct ocfs2_super *osb,
+			   struct inode *inode,
+			   struct buffer_head *fe_bh,
+			   struct ocfs2_truncate_context **tc);
+int ocfs2_commit_truncate(struct ocfs2_super *osb,
+			  struct inode *inode,
+			  struct buffer_head *fe_bh,
+			  struct ocfs2_truncate_context *tc);
+
+#endif /* OCFS2_ALLOC_H */
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
new file mode 100644
index 0000000..8f4467a
--- /dev/null
+++ b/fs/ocfs2/aops.c
@@ -0,0 +1,643 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <asm/byteorder.h>
+
+#define MLOG_MASK_PREFIX ML_FILE_IO
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "aops.h"
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "file.h"
+#include "inode.h"
+#include "journal.h"
+#include "super.h"
+#include "symlink.h"
+
+#include "buffer_head_io.h"
+
+static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
+				   struct buffer_head *bh_result, int create)
+{
+	int err = -EIO;
+	int status;
+	struct ocfs2_dinode *fe = NULL;
+	struct buffer_head *bh = NULL;
+	struct buffer_head *buffer_cache_bh = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	void *kaddr;
+
+	mlog_entry("(0x%p, %llu, 0x%p, %d)\n", inode,
+		   (unsigned long long)iblock, bh_result, create);
+
+	BUG_ON(ocfs2_inode_is_fast_symlink(inode));
+
+	if ((iblock << inode->i_sb->s_blocksize_bits) > PATH_MAX + 1) {
+		mlog(ML_ERROR, "block offset > PATH_MAX: %llu",
+		     (unsigned long long)iblock);
+		goto bail;
+	}
+
+	status = ocfs2_read_block(OCFS2_SB(inode->i_sb),
+				  OCFS2_I(inode)->ip_blkno,
+				  &bh, OCFS2_BH_CACHED, inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	fe = (struct ocfs2_dinode *) bh->b_data;
+
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		mlog(ML_ERROR, "Invalid dinode #%"MLFu64": signature = %.*s\n",
+		     fe->i_blkno, 7, fe->i_signature);
+		goto bail;
+	}
+
+	if ((u64)iblock >= ocfs2_clusters_to_blocks(inode->i_sb,
+						    le32_to_cpu(fe->i_clusters))) {
+		mlog(ML_ERROR, "block offset is outside the allocated size: "
+		     "%llu\n", (unsigned long long)iblock);
+		goto bail;
+	}
+
+	/* We don't use the page cache to create symlink data, so if
+	 * need be, copy it over from the buffer cache. */
+	if (!buffer_uptodate(bh_result) && ocfs2_inode_is_new(inode)) {
+		u64 blkno = le64_to_cpu(fe->id2.i_list.l_recs[0].e_blkno) +
+			    iblock;
+		buffer_cache_bh = sb_getblk(osb->sb, blkno);
+		if (!buffer_cache_bh) {
+			mlog(ML_ERROR, "couldn't getblock for symlink!\n");
+			goto bail;
+		}
+
+		/* we haven't locked out transactions, so a commit
+		 * could've happened. Since we've got a reference on
+		 * the bh, even if it commits while we're doing the
+		 * copy, the data is still good. */
+		if (buffer_jbd(buffer_cache_bh)
+		    && ocfs2_inode_is_new(inode)) {
+			kaddr = kmap_atomic(bh_result->b_page, KM_USER0);
+			if (!kaddr) {
+				mlog(ML_ERROR, "couldn't kmap!\n");
+				goto bail;
+			}
+			memcpy(kaddr + (bh_result->b_size * iblock),
+			       buffer_cache_bh->b_data,
+			       bh_result->b_size);
+			kunmap_atomic(kaddr, KM_USER0);
+			set_buffer_uptodate(bh_result);
+		}
+		brelse(buffer_cache_bh);
+	}
+
+	map_bh(bh_result, inode->i_sb,
+	       le64_to_cpu(fe->id2.i_list.l_recs[0].e_blkno) + iblock);
+
+	err = 0;
+
+bail:
+	if (bh)
+		brelse(bh);
+
+	mlog_exit(err);
+	return err;
+}
+
+static int ocfs2_get_block(struct inode *inode, sector_t iblock,
+			   struct buffer_head *bh_result, int create)
+{
+	int err = 0;
+	u64 p_blkno, past_eof;
+
+	mlog_entry("(0x%p, %llu, 0x%p, %d)\n", inode,
+		   (unsigned long long)iblock, bh_result, create);
+
+	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE)
+		mlog(ML_NOTICE, "get_block on system inode 0x%p (%lu)\n",
+		     inode, inode->i_ino);
+
+	if (S_ISLNK(inode->i_mode)) {
+		/* this always does I/O for some reason. */
+		err = ocfs2_symlink_get_block(inode, iblock, bh_result, create);
+		goto bail;
+	}
+
+	/* this can happen if another node truncs after our extend! */
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	if (iblock >= ocfs2_clusters_to_blocks(inode->i_sb,
+					       OCFS2_I(inode)->ip_clusters))
+		err = -EIO;
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+	if (err)
+		goto bail;
+
+	err = ocfs2_extent_map_get_blocks(inode, iblock, 1, &p_blkno,
+					  NULL);
+	if (err) {
+		mlog(ML_ERROR, "Error %d from get_blocks(0x%p, %llu, 1, "
+		     "%"MLFu64", NULL)\n", err, inode,
+		     (unsigned long long)iblock, p_blkno);
+		goto bail;
+	}
+
+	map_bh(bh_result, inode->i_sb, p_blkno);
+
+	if (bh_result->b_blocknr == 0) {
+		err = -EIO;
+		mlog(ML_ERROR, "iblock = %llu p_blkno = %"MLFu64" "
+		     "blkno=(%"MLFu64")\n", (unsigned long long)iblock,
+		     p_blkno, OCFS2_I(inode)->ip_blkno);
+	}
+
+	past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
+	mlog(0, "Inode %lu, past_eof = %"MLFu64"\n", inode->i_ino, past_eof);
+
+	if (create && (iblock >= past_eof))
+		set_buffer_new(bh_result);
+
+bail:
+	if (err < 0)
+		err = -EIO;
+
+	mlog_exit(err);
+	return err;
+}
+
+static int ocfs2_readpage(struct file *file, struct page *page)
+{
+	struct inode *inode = page->mapping->host;
+	loff_t start = (loff_t)page->index << PAGE_CACHE_SHIFT;
+	int ret, unlock = 1;
+
+	mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0));
+
+	ret = ocfs2_meta_lock_with_page(inode, NULL, NULL, 0, page);
+	if (ret != 0) {
+		if (ret == AOP_TRUNCATED_PAGE)
+			unlock = 0;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	down_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+	/*
+	 * i_size might have just been updated as we grabed the meta lock.  We
+	 * might now be discovering a truncate that hit on another node.
+	 * block_read_full_page->get_block freaks out if it is asked to read
+	 * beyond the end of a file, so we check here.  Callers
+	 * (generic_file_read, fault->nopage) are clever enough to check i_size
+	 * and notice that the page they just read isn't needed.
+	 *
+	 * XXX sys_readahead() seems to get that wrong?
+	 */
+	if (start >= i_size_read(inode)) {
+		char *addr = kmap(page);
+		memset(addr, 0, PAGE_SIZE);
+		flush_dcache_page(page);
+		kunmap(page);
+		SetPageUptodate(page);
+		ret = 0;
+		goto out_alloc;
+	}
+
+	ret = ocfs2_data_lock_with_page(inode, 0, page);
+	if (ret != 0) {
+		if (ret == AOP_TRUNCATED_PAGE)
+			unlock = 0;
+		mlog_errno(ret);
+		goto out_alloc;
+	}
+
+	ret = block_read_full_page(page, ocfs2_get_block);
+	unlock = 0;
+
+	ocfs2_data_unlock(inode, 0);
+out_alloc:
+	up_read(&OCFS2_I(inode)->ip_alloc_sem);
+	ocfs2_meta_unlock(inode, 0);
+out:
+	if (unlock)
+		unlock_page(page);
+	mlog_exit(ret);
+	return ret;
+}
+
+/* Note: Because we don't support holes, our allocation has
+ * already happened (allocation writes zeros to the file data)
+ * so we don't have to worry about ordered writes in
+ * ocfs2_writepage.
+ *
+ * ->writepage is called during the process of invalidating the page cache
+ * during blocked lock processing.  It can't block on any cluster locks
+ * to during block mapping.  It's relying on the fact that the block
+ * mapping can't have disappeared under the dirty pages that it is
+ * being asked to write back.
+ */
+static int ocfs2_writepage(struct page *page, struct writeback_control *wbc)
+{
+	int ret;
+
+	mlog_entry("(0x%p)\n", page);
+
+	ret = block_write_full_page(page, ocfs2_get_block, wbc);
+
+	mlog_exit(ret);
+
+	return ret;
+}
+
+/*
+ * ocfs2_prepare_write() can be an outer-most ocfs2 call when it is called
+ * from loopback.  It must be able to perform its own locking around
+ * ocfs2_get_block().
+ */
+int ocfs2_prepare_write(struct file *file, struct page *page,
+			unsigned from, unsigned to)
+{
+	struct inode *inode = page->mapping->host;
+	int ret;
+
+	mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to);
+
+	ret = ocfs2_meta_lock_with_page(inode, NULL, NULL, 0, page);
+	if (ret != 0) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	down_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+	ret = block_prepare_write(page, from, to, ocfs2_get_block);
+
+	up_read(&OCFS2_I(inode)->ip_alloc_sem);
+
+	ocfs2_meta_unlock(inode, 0);
+out:
+	mlog_exit(ret);
+	return ret;
+}
+
+/* Taken from ext3. We don't necessarily need the full blown
+ * functionality yet, but IMHO it's better to cut and paste the whole
+ * thing so we can avoid introducing our own bugs (and easily pick up
+ * their fixes when they happen) --Mark */
+static int walk_page_buffers(	handle_t *handle,
+				struct buffer_head *head,
+				unsigned from,
+				unsigned to,
+				int *partial,
+				int (*fn)(	handle_t *handle,
+						struct buffer_head *bh))
+{
+	struct buffer_head *bh;
+	unsigned block_start, block_end;
+	unsigned blocksize = head->b_size;
+	int err, ret = 0;
+	struct buffer_head *next;
+
+	for (	bh = head, block_start = 0;
+		ret == 0 && (bh != head || !block_start);
+	    	block_start = block_end, bh = next)
+	{
+		next = bh->b_this_page;
+		block_end = block_start + blocksize;
+		if (block_end <= from || block_start >= to) {
+			if (partial && !buffer_uptodate(bh))
+				*partial = 1;
+			continue;
+		}
+		err = (*fn)(handle, bh);
+		if (!ret)
+			ret = err;
+	}
+	return ret;
+}
+
+struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode,
+							 struct page *page,
+							 unsigned from,
+							 unsigned to)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct ocfs2_journal_handle *handle = NULL;
+	int ret = 0;
+
+	handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS);
+	if (!handle) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	if (ocfs2_should_order_data(inode)) {
+		ret = walk_page_buffers(handle->k_handle,
+					page_buffers(page),
+					from, to, NULL,
+					ocfs2_journal_dirty_data);
+		if (ret < 0) 
+			mlog_errno(ret);
+	}
+out:
+	if (ret) {
+		if (handle)
+			ocfs2_commit_trans(handle);
+		handle = ERR_PTR(ret);
+	}
+	return handle;
+}
+
+static int ocfs2_commit_write(struct file *file, struct page *page,
+			      unsigned from, unsigned to)
+{
+	int ret, extending = 0, locklevel = 0;
+	loff_t new_i_size;
+	struct buffer_head *di_bh = NULL;
+	struct inode *inode = page->mapping->host;
+	struct ocfs2_journal_handle *handle = NULL;
+
+	mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to);
+
+	/* NOTE: ocfs2_file_aio_write has ensured that it's safe for
+	 * us to sample inode->i_size here without the metadata lock:
+	 *
+	 * 1) We're currently holding the inode alloc lock, so no
+	 *    nodes can change it underneath us.
+	 *
+	 * 2) We've had to take the metadata lock at least once
+	 *    already to check for extending writes, hence insuring
+	 *    that our current copy is also up to date.
+	 */
+	new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+	if (new_i_size > i_size_read(inode)) {
+		extending = 1;
+		locklevel = 1;
+	}
+
+	ret = ocfs2_meta_lock_with_page(inode, NULL, &di_bh, locklevel, page);
+	if (ret != 0) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = ocfs2_data_lock_with_page(inode, 1, page);
+	if (ret != 0) {
+		mlog_errno(ret);
+		goto out_unlock_meta;
+	}
+
+	if (extending) {
+		handle = ocfs2_start_walk_page_trans(inode, page, from, to);
+		if (IS_ERR(handle)) {
+			ret = PTR_ERR(handle);
+			handle = NULL;
+			goto out_unlock_data;
+		}
+
+		/* Mark our buffer early. We'd rather catch this error up here
+		 * as opposed to after a successful commit_write which would
+		 * require us to set back inode->i_size. */
+		ret = ocfs2_journal_access(handle, inode, di_bh,
+					   OCFS2_JOURNAL_ACCESS_WRITE);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto out_commit;
+		}
+	}
+
+	/* might update i_size */
+	ret = generic_commit_write(file, page, from, to);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out_commit;
+	}
+
+	if (extending) {
+		loff_t size = (u64) i_size_read(inode);
+		struct ocfs2_dinode *di =
+			(struct ocfs2_dinode *)di_bh->b_data;
+
+		/* ocfs2_mark_inode_dirty is too heavy to use here. */
+		inode->i_blocks = ocfs2_align_bytes_to_sectors(size);
+		inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+
+		di->i_size = cpu_to_le64(size);
+		di->i_ctime = di->i_mtime = 
+				cpu_to_le64(inode->i_mtime.tv_sec);
+		di->i_ctime_nsec = di->i_mtime_nsec = 
+				cpu_to_le32(inode->i_mtime.tv_nsec);
+
+		ret = ocfs2_journal_dirty(handle, di_bh);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto out_commit;
+		}
+	}
+
+	BUG_ON(extending && (i_size_read(inode) != new_i_size));
+
+out_commit:
+	if (handle)
+		ocfs2_commit_trans(handle);
+out_unlock_data:
+	ocfs2_data_unlock(inode, 1);
+out_unlock_meta:
+	ocfs2_meta_unlock(inode, locklevel);
+out:
+	if (di_bh)
+		brelse(di_bh);
+
+	mlog_exit(ret);
+	return ret;
+}
+
+static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
+{
+	sector_t status;
+	u64 p_blkno = 0;
+	int err = 0;
+	struct inode *inode = mapping->host;
+
+	mlog_entry("(block = %llu)\n", (unsigned long long)block);
+
+	/* We don't need to lock journal system files, since they aren't
+	 * accessed concurrently from multiple nodes.
+	 */
+	if (!INODE_JOURNAL(inode)) {
+		err = ocfs2_meta_lock(inode, NULL, NULL, 0);
+		if (err) {
+			if (err != -ENOENT)
+				mlog_errno(err);
+			goto bail;
+		}
+		down_read(&OCFS2_I(inode)->ip_alloc_sem);
+	}
+
+	err = ocfs2_extent_map_get_blocks(inode, block, 1, &p_blkno,
+					  NULL);
+
+	if (!INODE_JOURNAL(inode)) {
+		up_read(&OCFS2_I(inode)->ip_alloc_sem);
+		ocfs2_meta_unlock(inode, 0);
+	}
+
+	if (err) {
+		mlog(ML_ERROR, "get_blocks() failed, block = %llu\n",
+		     (unsigned long long)block);
+		mlog_errno(err);
+		goto bail;
+	}
+
+
+bail:
+	status = err ? 0 : p_blkno;
+
+	mlog_exit((int)status);
+
+	return status;
+}
+
+/*
+ * TODO: Make this into a generic get_blocks function.
+ *
+ * From do_direct_io in direct-io.c:
+ *  "So what we do is to permit the ->get_blocks function to populate
+ *   bh.b_size with the size of IO which is permitted at this offset and
+ *   this i_blkbits."
+ *
+ * This function is called directly from get_more_blocks in direct-io.c.
+ *
+ * called like this: dio->get_blocks(dio->inode, fs_startblk,
+ * 					fs_count, map_bh, dio->rw == WRITE);
+ */
+static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
+				     unsigned long max_blocks,
+				     struct buffer_head *bh_result, int create)
+{
+	int ret;
+	u64 vbo_max; /* file offset, max_blocks from iblock */
+	u64 p_blkno;
+	int contig_blocks;
+	unsigned char blocksize_bits;
+
+	if (!inode || !bh_result) {
+		mlog(ML_ERROR, "inode or bh_result is null\n");
+		return -EIO;
+	}
+
+	blocksize_bits = inode->i_sb->s_blocksize_bits;
+
+	/* This function won't even be called if the request isn't all
+	 * nicely aligned and of the right size, so there's no need
+	 * for us to check any of that. */
+
+	vbo_max = ((u64)iblock + max_blocks) << blocksize_bits;
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	if ((iblock + max_blocks) >
+	    ocfs2_clusters_to_blocks(inode->i_sb,
+				     OCFS2_I(inode)->ip_clusters)) {
+		spin_unlock(&OCFS2_I(inode)->ip_lock);
+		ret = -EIO;
+		goto bail;
+	}
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	/* This figures out the size of the next contiguous block, and
+	 * our logical offset */
+	ret = ocfs2_extent_map_get_blocks(inode, iblock, 1, &p_blkno,
+					  &contig_blocks);
+	if (ret) {
+		mlog(ML_ERROR, "get_blocks() failed iblock=%llu\n",
+		     (unsigned long long)iblock);
+		ret = -EIO;
+		goto bail;
+	}
+
+	map_bh(bh_result, inode->i_sb, p_blkno);
+
+	/* make sure we don't map more than max_blocks blocks here as
+	   that's all the kernel will handle at this point. */
+	if (max_blocks < contig_blocks)
+		contig_blocks = max_blocks;
+	bh_result->b_size = contig_blocks << blocksize_bits;
+bail:
+	return ret;
+}
+
+/* 
+ * ocfs2_dio_end_io is called by the dio core when a dio is finished.  We're
+ * particularly interested in the aio/dio case.  Like the core uses
+ * i_alloc_sem, we use the rw_lock DLM lock to protect io on one node from
+ * truncation on another.
+ */
+static void ocfs2_dio_end_io(struct kiocb *iocb,
+			     loff_t offset,
+			     ssize_t bytes,
+			     void *private)
+{
+	struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
+
+	/* this io's submitter should not have unlocked this before we could */
+	BUG_ON(!ocfs2_iocb_is_rw_locked(iocb));
+	ocfs2_iocb_clear_rw_locked(iocb);
+	up_read(&inode->i_alloc_sem);
+	ocfs2_rw_unlock(inode, 0);
+}
+
+static ssize_t ocfs2_direct_IO(int rw,
+			       struct kiocb *iocb,
+			       const struct iovec *iov,
+			       loff_t offset,
+			       unsigned long nr_segs)
+{
+	struct file *file = iocb->ki_filp;
+	struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
+	int ret;
+
+	mlog_entry_void();
+	ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
+					    inode->i_sb->s_bdev, iov, offset,
+					    nr_segs, 
+					    ocfs2_direct_IO_get_blocks,
+					    ocfs2_dio_end_io);
+	mlog_exit(ret);
+	return ret;
+}
+
+struct address_space_operations ocfs2_aops = {
+	.readpage	= ocfs2_readpage,
+	.writepage	= ocfs2_writepage,
+	.prepare_write	= ocfs2_prepare_write,
+	.commit_write	= ocfs2_commit_write,
+	.bmap		= ocfs2_bmap,
+	.sync_page	= block_sync_page,
+	.direct_IO	= ocfs2_direct_IO
+};
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
new file mode 100644
index 0000000..d40456d
--- /dev/null
+++ b/fs/ocfs2/aops.h
@@ -0,0 +1,41 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2002, 2004, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_AOPS_H
+#define OCFS2_AOPS_H
+
+int ocfs2_prepare_write(struct file *file, struct page *page,
+			unsigned from, unsigned to);
+
+struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode,
+							 struct page *page,
+							 unsigned from,
+							 unsigned to);
+
+/* all ocfs2_dio_end_io()'s fault */
+#define ocfs2_iocb_is_rw_locked(iocb) \
+	test_bit(0, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_set_rw_locked(iocb) \
+	set_bit(0, (unsigned long *)&iocb->private)
+#define ocfs2_iocb_clear_rw_locked(iocb) \
+	clear_bit(0, (unsigned long *)&iocb->private)
+
+#endif /* OCFS2_FILE_H */
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c
new file mode 100644
index 0000000..d424041
--- /dev/null
+++ b/fs/ocfs2/buffer_head_io.c
@@ -0,0 +1,232 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * io.c
+ *
+ * Buffer cache handling
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "inode.h"
+#include "journal.h"
+#include "uptodate.h"
+
+#include "buffer_head_io.h"
+
+int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
+		      struct inode *inode)
+{
+	int ret = 0;
+
+	mlog_entry("(bh->b_blocknr = %llu, inode=%p)\n",
+		   (unsigned long long)bh->b_blocknr, inode);
+
+	BUG_ON(bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO);
+	BUG_ON(buffer_jbd(bh));
+
+	/* No need to check for a soft readonly file system here. non
+	 * journalled writes are only ever done on system files which
+	 * can get modified during recovery even if read-only. */
+	if (ocfs2_is_hard_readonly(osb)) {
+		ret = -EROFS;
+		goto out;
+	}
+
+	down(&OCFS2_I(inode)->ip_io_sem);
+
+	lock_buffer(bh);
+	set_buffer_uptodate(bh);
+
+	/* remove from dirty list before I/O. */
+	clear_buffer_dirty(bh);
+
+	get_bh(bh); /* for end_buffer_write_sync() */                   
+	bh->b_end_io = end_buffer_write_sync;
+	submit_bh(WRITE, bh);
+
+	wait_on_buffer(bh);
+
+	if (buffer_uptodate(bh)) {
+		ocfs2_set_buffer_uptodate(inode, bh);
+	} else {
+		/* We don't need to remove the clustered uptodate
+		 * information for this bh as it's not marked locally
+		 * uptodate. */
+		ret = -EIO;
+		brelse(bh);
+	}
+
+	up(&OCFS2_I(inode)->ip_io_sem);
+out:
+	mlog_exit(ret);
+	return ret;
+}
+
+int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr,
+		      struct buffer_head *bhs[], int flags,
+		      struct inode *inode)
+{
+	int status = 0;
+	struct super_block *sb;
+	int i, ignore_cache = 0;
+	struct buffer_head *bh;
+
+	mlog_entry("(block=(%"MLFu64"), nr=(%d), flags=%d, inode=%p)\n",
+		   block, nr, flags, inode);
+
+	if (osb == NULL || osb->sb == NULL || bhs == NULL) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	if (nr < 0) {
+		mlog(ML_ERROR, "asked to read %d blocks!\n", nr);
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	if (nr == 0) {
+		mlog(ML_BH_IO, "No buffers will be read!\n");
+		status = 0;
+		goto bail;
+	}
+
+	sb = osb->sb;
+
+	if (flags & OCFS2_BH_CACHED && !inode)
+		flags &= ~OCFS2_BH_CACHED;
+
+	if (inode)
+		down(&OCFS2_I(inode)->ip_io_sem);
+	for (i = 0 ; i < nr ; i++) {
+		if (bhs[i] == NULL) {
+			bhs[i] = sb_getblk(sb, block++);
+			if (bhs[i] == NULL) {
+				if (inode)
+					up(&OCFS2_I(inode)->ip_io_sem);
+				status = -EIO;
+				mlog_errno(status);
+				goto bail;
+			}
+		}
+		bh = bhs[i];
+		ignore_cache = 0;
+
+		if (flags & OCFS2_BH_CACHED &&
+		    !ocfs2_buffer_uptodate(inode, bh)) {
+			mlog(ML_UPTODATE,
+			     "bh (%llu), inode %"MLFu64" not uptodate\n",
+			     (unsigned long long)bh->b_blocknr,
+			     OCFS2_I(inode)->ip_blkno);
+			ignore_cache = 1;
+		}
+
+		/* XXX: Can we ever get this and *not* have the cached
+		 * flag set? */
+		if (buffer_jbd(bh)) {
+			if (!(flags & OCFS2_BH_CACHED) || ignore_cache)
+				mlog(ML_BH_IO, "trying to sync read a jbd "
+					       "managed bh (blocknr = %llu)\n",
+				     (unsigned long long)bh->b_blocknr);
+			continue;
+		}
+
+		if (!(flags & OCFS2_BH_CACHED) || ignore_cache) {
+			if (buffer_dirty(bh)) {
+				/* This should probably be a BUG, or
+				 * at least return an error. */
+				mlog(ML_BH_IO, "asking me to sync read a dirty "
+					       "buffer! (blocknr = %llu)\n",
+				     (unsigned long long)bh->b_blocknr);
+				continue;
+			}
+
+			lock_buffer(bh);
+			if (buffer_jbd(bh)) {
+#ifdef CATCH_BH_JBD_RACES
+				mlog(ML_ERROR, "block %llu had the JBD bit set "
+					       "while I was in lock_buffer!",
+				     (unsigned long long)bh->b_blocknr);
+				BUG();
+#else
+				unlock_buffer(bh);
+				continue;
+#endif
+			}
+			clear_buffer_uptodate(bh);
+			get_bh(bh); /* for end_buffer_read_sync() */
+			bh->b_end_io = end_buffer_read_sync;
+			if (flags & OCFS2_BH_READAHEAD)
+				submit_bh(READA, bh);
+			else
+				submit_bh(READ, bh);
+			continue;
+		}
+	}
+
+	status = 0;
+
+	for (i = (nr - 1); i >= 0; i--) {
+		bh = bhs[i];
+
+		/* We know this can't have changed as we hold the
+		 * inode sem. Avoid doing any work on the bh if the
+		 * journal has it. */
+		if (!buffer_jbd(bh))
+			wait_on_buffer(bh);
+
+		if (!buffer_uptodate(bh)) {
+			/* Status won't be cleared from here on out,
+			 * so we can safely record this and loop back
+			 * to cleanup the other buffers. Don't need to
+			 * remove the clustered uptodate information
+			 * for this bh as it's not marked locally
+			 * uptodate. */
+			status = -EIO;
+			brelse(bh);
+			bhs[i] = NULL;
+			continue;
+		}
+
+		if (inode)
+			ocfs2_set_buffer_uptodate(inode, bh);
+	}
+	if (inode)
+		up(&OCFS2_I(inode)->ip_io_sem);
+
+	mlog(ML_BH_IO, "block=(%"MLFu64"), nr=(%d), cached=%s\n", block, nr,
+	     (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes");
+
+bail:
+
+	mlog_exit(status);
+	return status;
+}
diff --git a/fs/ocfs2/buffer_head_io.h b/fs/ocfs2/buffer_head_io.h
new file mode 100644
index 0000000..6ecb909
--- /dev/null
+++ b/fs/ocfs2/buffer_head_io.h
@@ -0,0 +1,73 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ocfs2_buffer_head.h
+ *
+ * Buffer cache handling functions defined
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_BUFFER_HEAD_IO_H
+#define OCFS2_BUFFER_HEAD_IO_H
+
+#include <linux/buffer_head.h>
+
+void ocfs2_end_buffer_io_sync(struct buffer_head *bh,
+			     int uptodate);
+
+static inline int ocfs2_read_block(struct ocfs2_super          *osb,
+				   u64                  off,
+				   struct buffer_head **bh,
+				   int                  flags,
+				   struct inode        *inode);
+
+int ocfs2_write_block(struct ocfs2_super          *osb,
+		      struct buffer_head  *bh,
+		      struct inode        *inode);
+int ocfs2_read_blocks(struct ocfs2_super          *osb,
+		      u64                  block,
+		      int                  nr,
+		      struct buffer_head  *bhs[],
+		      int                  flags,
+		      struct inode        *inode);
+
+
+#define OCFS2_BH_CACHED            1
+#define OCFS2_BH_READAHEAD         8	/* use this to pass READA down to submit_bh */
+
+static inline int ocfs2_read_block(struct ocfs2_super * osb, u64 off,
+				   struct buffer_head **bh, int flags,
+				   struct inode *inode)
+{
+	int status = 0;
+
+	if (bh == NULL) {
+		printk("ocfs2: bh == NULL\n");
+		status = -EINVAL;
+		goto bail;
+	}
+
+	status = ocfs2_read_blocks(osb, off, 1, bh,
+				   flags, inode);
+
+bail:
+	return status;
+}
+
+#endif /* OCFS2_BUFFER_HEAD_IO_H */
diff --git a/fs/ocfs2/cluster/Makefile b/fs/ocfs2/cluster/Makefile
new file mode 100644
index 0000000..cdd162f
--- /dev/null
+++ b/fs/ocfs2/cluster/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_OCFS2_FS) += ocfs2_nodemanager.o
+
+ocfs2_nodemanager-objs := heartbeat.o masklog.o sys.o nodemanager.o \
+	quorum.o tcp.o ver.o
diff --git a/fs/ocfs2/cluster/endian.h b/fs/ocfs2/cluster/endian.h
new file mode 100644
index 0000000..2df9082
--- /dev/null
+++ b/fs/ocfs2/cluster/endian.h
@@ -0,0 +1,30 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_CLUSTER_ENDIAN_H
+#define OCFS2_CLUSTER_ENDIAN_H
+
+static inline void be32_add_cpu(__be32 *var, u32 val)
+{
+	*var = cpu_to_be32(be32_to_cpu(*var) + val);
+}
+
+#endif /* OCFS2_CLUSTER_ENDIAN_H */
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
new file mode 100644
index 0000000..7307ba5
--- /dev/null
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -0,0 +1,1797 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2004, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/bio.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/file.h>
+#include <linux/kthread.h>
+#include <linux/configfs.h>
+#include <linux/random.h>
+#include <linux/crc32.h>
+#include <linux/time.h>
+
+#include "heartbeat.h"
+#include "tcp.h"
+#include "nodemanager.h"
+#include "quorum.h"
+
+#include "masklog.h"
+
+
+/*
+ * The first heartbeat pass had one global thread that would serialize all hb
+ * callback calls.  This global serializing sem should only be removed once
+ * we've made sure that all callees can deal with being called concurrently
+ * from multiple hb region threads.
+ */
+static DECLARE_RWSEM(o2hb_callback_sem);
+
+/*
+ * multiple hb threads are watching multiple regions.  A node is live
+ * whenever any of the threads sees activity from the node in its region.
+ */
+static spinlock_t o2hb_live_lock = SPIN_LOCK_UNLOCKED;
+static struct list_head o2hb_live_slots[O2NM_MAX_NODES];
+static unsigned long o2hb_live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+static LIST_HEAD(o2hb_node_events);
+static DECLARE_WAIT_QUEUE_HEAD(o2hb_steady_queue);
+
+static LIST_HEAD(o2hb_all_regions);
+
+static struct o2hb_callback {
+	struct list_head list;
+} o2hb_callbacks[O2HB_NUM_CB];
+
+static struct o2hb_callback *hbcall_from_type(enum o2hb_callback_type type);
+
+#define O2HB_DEFAULT_BLOCK_BITS       9
+
+unsigned int o2hb_dead_threshold = O2HB_DEFAULT_DEAD_THRESHOLD;
+
+/* Only sets a new threshold if there are no active regions. 
+ *
+ * No locking or otherwise interesting code is required for reading
+ * o2hb_dead_threshold as it can't change once regions are active and
+ * it's not interesting to anyone until then anyway. */
+static void o2hb_dead_threshold_set(unsigned int threshold)
+{
+	if (threshold > O2HB_MIN_DEAD_THRESHOLD) {
+		spin_lock(&o2hb_live_lock);
+		if (list_empty(&o2hb_all_regions))
+			o2hb_dead_threshold = threshold;
+		spin_unlock(&o2hb_live_lock);
+	}
+}
+
+struct o2hb_node_event {
+	struct list_head        hn_item;
+	enum o2hb_callback_type hn_event_type;
+	struct o2nm_node        *hn_node;
+	int                     hn_node_num;
+};
+
+struct o2hb_disk_slot {
+	struct o2hb_disk_heartbeat_block *ds_raw_block;
+	u8			ds_node_num;
+	u64			ds_last_time;
+	u64			ds_last_generation;
+	u16			ds_equal_samples;
+	u16			ds_changed_samples;
+	struct list_head	ds_live_item;
+};
+
+/* each thread owns a region.. when we're asked to tear down the region
+ * we ask the thread to stop, who cleans up the region */
+struct o2hb_region {
+	struct config_item	hr_item;
+
+	struct list_head	hr_all_item;
+	unsigned		hr_unclean_stop:1;
+
+	/* protected by the hr_callback_sem */
+	struct task_struct 	*hr_task;
+
+	unsigned int		hr_blocks;
+	unsigned long long	hr_start_block;
+
+	unsigned int		hr_block_bits;
+	unsigned int		hr_block_bytes;
+
+	unsigned int		hr_slots_per_page;
+	unsigned int		hr_num_pages;
+
+	struct page             **hr_slot_data;
+	struct block_device	*hr_bdev;
+	struct o2hb_disk_slot	*hr_slots;
+
+	/* let the person setting up hb wait for it to return until it
+	 * has reached a 'steady' state.  This will be fixed when we have
+	 * a more complete api that doesn't lead to this sort of fragility. */
+	atomic_t		hr_steady_iterations;
+
+	char			hr_dev_name[BDEVNAME_SIZE];
+
+	unsigned int		hr_timeout_ms;
+
+	/* randomized as the region goes up and down so that a node
+	 * recognizes a node going up and down in one iteration */
+	u64			hr_generation;
+
+	struct work_struct	hr_write_timeout_work;
+	unsigned long		hr_last_timeout_start;
+
+	/* Used during o2hb_check_slot to hold a copy of the block
+	 * being checked because we temporarily have to zero out the
+	 * crc field. */
+	struct o2hb_disk_heartbeat_block *hr_tmp_block;
+};
+
+struct o2hb_bio_wait_ctxt {
+	atomic_t          wc_num_reqs;
+	struct completion wc_io_complete;
+};
+
+static void o2hb_write_timeout(void *arg)
+{
+	struct o2hb_region *reg = arg;
+
+	mlog(ML_ERROR, "Heartbeat write timeout to device %s after %u "
+	     "milliseconds\n", reg->hr_dev_name,
+	     jiffies_to_msecs(jiffies - reg->hr_last_timeout_start)); 
+	o2quo_disk_timeout();
+}
+
+static void o2hb_arm_write_timeout(struct o2hb_region *reg)
+{
+	mlog(0, "Queue write timeout for %u ms\n", O2HB_MAX_WRITE_TIMEOUT_MS);
+
+	cancel_delayed_work(&reg->hr_write_timeout_work);
+	reg->hr_last_timeout_start = jiffies;
+	schedule_delayed_work(&reg->hr_write_timeout_work,
+			      msecs_to_jiffies(O2HB_MAX_WRITE_TIMEOUT_MS));
+}
+
+static void o2hb_disarm_write_timeout(struct o2hb_region *reg)
+{
+	cancel_delayed_work(&reg->hr_write_timeout_work);
+	flush_scheduled_work();
+}
+
+static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc,
+				      unsigned int num_ios)
+{
+	atomic_set(&wc->wc_num_reqs, num_ios);
+	init_completion(&wc->wc_io_complete);
+}
+
+/* Used in error paths too */
+static inline void o2hb_bio_wait_dec(struct o2hb_bio_wait_ctxt *wc,
+				     unsigned int num)
+{
+	/* sadly atomic_sub_and_test() isn't available on all platforms.  The
+	 * good news is that the fast path only completes one at a time */
+	while(num--) {
+		if (atomic_dec_and_test(&wc->wc_num_reqs)) {
+			BUG_ON(num > 0);
+			complete(&wc->wc_io_complete);
+		}
+	}
+}
+
+static void o2hb_wait_on_io(struct o2hb_region *reg,
+			    struct o2hb_bio_wait_ctxt *wc)
+{
+	struct address_space *mapping = reg->hr_bdev->bd_inode->i_mapping;
+
+	blk_run_address_space(mapping);
+
+	wait_for_completion(&wc->wc_io_complete);
+}
+
+static int o2hb_bio_end_io(struct bio *bio,
+			   unsigned int bytes_done,
+			   int error)
+{
+	struct o2hb_bio_wait_ctxt *wc = bio->bi_private;
+
+	if (error)
+		mlog(ML_ERROR, "IO Error %d\n", error);
+
+	if (bio->bi_size)
+		return 1;
+
+	o2hb_bio_wait_dec(wc, 1);
+	return 0;
+}
+
+/* Setup a Bio to cover I/O against num_slots slots starting at
+ * start_slot. */
+static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,
+				      struct o2hb_bio_wait_ctxt *wc,
+				      unsigned int start_slot,
+				      unsigned int num_slots)
+{
+	int i, nr_vecs, len, first_page, last_page;
+	unsigned int vec_len, vec_start;
+	unsigned int bits = reg->hr_block_bits;
+	unsigned int spp = reg->hr_slots_per_page;
+	struct bio *bio;
+	struct page *page;
+
+	nr_vecs = (num_slots + spp - 1) / spp;
+
+	/* Testing has shown this allocation to take long enough under
+	 * GFP_KERNEL that the local node can get fenced. It would be
+	 * nicest if we could pre-allocate these bios and avoid this
+	 * all together. */
+	bio = bio_alloc(GFP_ATOMIC, nr_vecs);
+	if (!bio) {
+		mlog(ML_ERROR, "Could not alloc slots BIO!\n");
+		bio = ERR_PTR(-ENOMEM);
+		goto bail;
+	}
+
+	/* Must put everything in 512 byte sectors for the bio... */
+	bio->bi_sector = (reg->hr_start_block + start_slot) << (bits - 9);
+	bio->bi_bdev = reg->hr_bdev;
+	bio->bi_private = wc;
+	bio->bi_end_io = o2hb_bio_end_io;
+
+	first_page = start_slot / spp;
+	last_page = first_page + nr_vecs;
+	vec_start = (start_slot << bits) % PAGE_CACHE_SIZE;
+	for(i = first_page; i < last_page; i++) {
+		page = reg->hr_slot_data[i];
+
+		vec_len = PAGE_CACHE_SIZE;
+		/* last page might be short */
+		if (((i + 1) * spp) > (start_slot + num_slots))
+			vec_len = ((num_slots + start_slot) % spp) << bits;
+		vec_len -=  vec_start;
+
+		mlog(ML_HB_BIO, "page %d, vec_len = %u, vec_start = %u\n",
+		     i, vec_len, vec_start);
+
+		len = bio_add_page(bio, page, vec_len, vec_start);
+		if (len != vec_len) {
+			bio_put(bio);
+			bio = ERR_PTR(-EIO);
+
+			mlog(ML_ERROR, "Error adding page to bio i = %d, "
+			     "vec_len = %u, len = %d\n, start = %u\n",
+			     i, vec_len, len, vec_start);
+			goto bail;
+		}
+
+		vec_start = 0;
+	}
+
+bail:
+	return bio;
+}
+
+/*
+ * Compute the maximum number of sectors the bdev can handle in one bio,
+ * as a power of two.
+ *
+ * Stolen from oracleasm, thanks Joel!
+ */
+static int compute_max_sectors(struct block_device *bdev)
+{
+	int max_pages, max_sectors, pow_two_sectors;
+
+	struct request_queue *q;
+
+	q = bdev_get_queue(bdev);
+	max_pages = q->max_sectors >> (PAGE_SHIFT - 9);
+	if (max_pages > BIO_MAX_PAGES)
+		max_pages = BIO_MAX_PAGES;
+	if (max_pages > q->max_phys_segments)
+		max_pages = q->max_phys_segments;
+	if (max_pages > q->max_hw_segments)
+		max_pages = q->max_hw_segments;
+	max_pages--; /* Handle I/Os that straddle a page */
+
+	max_sectors = max_pages << (PAGE_SHIFT - 9);
+
+	/* Why is fls() 1-based???? */
+	pow_two_sectors = 1 << (fls(max_sectors) - 1);
+
+	return pow_two_sectors;
+}
+
+static inline void o2hb_compute_request_limits(struct o2hb_region *reg,
+					       unsigned int num_slots,
+					       unsigned int *num_bios,
+					       unsigned int *slots_per_bio)
+{
+	unsigned int max_sectors, io_sectors;
+
+	max_sectors = compute_max_sectors(reg->hr_bdev);
+
+	io_sectors = num_slots << (reg->hr_block_bits - 9);
+
+	*num_bios = (io_sectors + max_sectors - 1) / max_sectors;
+	*slots_per_bio = max_sectors >> (reg->hr_block_bits - 9);
+
+	mlog(ML_HB_BIO, "My io size is %u sectors for %u slots. This "
+	     "device can handle %u sectors of I/O\n", io_sectors, num_slots,
+	     max_sectors);
+	mlog(ML_HB_BIO, "Will need %u bios holding %u slots each\n",
+	     *num_bios, *slots_per_bio);
+}
+
+static int o2hb_read_slots(struct o2hb_region *reg,
+			   unsigned int max_slots)
+{
+	unsigned int num_bios, slots_per_bio, start_slot, num_slots;
+	int i, status;
+	struct o2hb_bio_wait_ctxt wc;
+	struct bio **bios;
+	struct bio *bio;
+
+	o2hb_compute_request_limits(reg, max_slots, &num_bios, &slots_per_bio);
+
+	bios = kcalloc(num_bios, sizeof(struct bio *), GFP_KERNEL);
+	if (!bios) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		return status;
+	}
+
+	o2hb_bio_wait_init(&wc, num_bios);
+
+	num_slots = slots_per_bio;
+	for(i = 0; i < num_bios; i++) {
+		start_slot = i * slots_per_bio;
+
+		/* adjust num_slots at last bio */
+		if (max_slots < (start_slot + num_slots))
+			num_slots = max_slots - start_slot;
+
+		bio = o2hb_setup_one_bio(reg, &wc, start_slot, num_slots);
+		if (IS_ERR(bio)) {
+			o2hb_bio_wait_dec(&wc, num_bios - i);
+
+			status = PTR_ERR(bio);
+			mlog_errno(status);
+			goto bail_and_wait;
+		}
+		bios[i] = bio;
+
+		submit_bio(READ, bio);
+	}
+
+	status = 0;
+
+bail_and_wait:
+	o2hb_wait_on_io(reg, &wc);
+
+	if (bios) {
+		for(i = 0; i < num_bios; i++)
+			if (bios[i])
+				bio_put(bios[i]);
+		kfree(bios);
+	}
+
+	return status;
+}
+
+static int o2hb_issue_node_write(struct o2hb_region *reg,
+				 struct bio **write_bio,
+				 struct o2hb_bio_wait_ctxt *write_wc)
+{
+	int status;
+	unsigned int slot;
+	struct bio *bio;
+
+	o2hb_bio_wait_init(write_wc, 1);
+
+	slot = o2nm_this_node();
+
+	bio = o2hb_setup_one_bio(reg, write_wc, slot, 1);
+	if (IS_ERR(bio)) {
+		status = PTR_ERR(bio);
+		mlog_errno(status);
+		goto bail;
+	}
+
+	submit_bio(WRITE, bio);
+
+	*write_bio = bio;
+	status = 0;
+bail:
+	return status;
+}
+
+static u32 o2hb_compute_block_crc_le(struct o2hb_region *reg,
+				     struct o2hb_disk_heartbeat_block *hb_block)
+{
+	__le32 old_cksum;
+	u32 ret;
+
+	/* We want to compute the block crc with a 0 value in the
+	 * hb_cksum field. Save it off here and replace after the
+	 * crc. */
+	old_cksum = hb_block->hb_cksum;
+	hb_block->hb_cksum = 0;
+
+	ret = crc32_le(0, (unsigned char *) hb_block, reg->hr_block_bytes);
+
+	hb_block->hb_cksum = old_cksum;
+
+	return ret;
+}
+
+static void o2hb_dump_slot(struct o2hb_disk_heartbeat_block *hb_block)
+{
+	mlog(ML_ERROR, "Dump slot information: seq = 0x%"MLFx64", node = %u, "
+	     "cksum = 0x%x, generation 0x%"MLFx64"\n",
+	     le64_to_cpu(hb_block->hb_seq), hb_block->hb_node,
+	     le32_to_cpu(hb_block->hb_cksum),
+	     le64_to_cpu(hb_block->hb_generation));
+}
+
+static int o2hb_verify_crc(struct o2hb_region *reg,
+			   struct o2hb_disk_heartbeat_block *hb_block)
+{
+	u32 read, computed;
+
+	read = le32_to_cpu(hb_block->hb_cksum);
+	computed = o2hb_compute_block_crc_le(reg, hb_block);
+
+	return read == computed;
+}
+
+/* We want to make sure that nobody is heartbeating on top of us --
+ * this will help detect an invalid configuration. */
+static int o2hb_check_last_timestamp(struct o2hb_region *reg)
+{
+	int node_num, ret;
+	struct o2hb_disk_slot *slot;
+	struct o2hb_disk_heartbeat_block *hb_block;
+
+	node_num = o2nm_this_node();
+
+	ret = 1;
+	slot = &reg->hr_slots[node_num];
+	/* Don't check on our 1st timestamp */
+	if (slot->ds_last_time) {
+		hb_block = slot->ds_raw_block;
+
+		if (le64_to_cpu(hb_block->hb_seq) != slot->ds_last_time)
+			ret = 0;
+	}
+
+	return ret;
+}
+
+static inline void o2hb_prepare_block(struct o2hb_region *reg,
+				      u64 generation)
+{
+	int node_num;
+	u64 cputime;
+	struct o2hb_disk_slot *slot;
+	struct o2hb_disk_heartbeat_block *hb_block;
+
+	node_num = o2nm_this_node();
+	slot = &reg->hr_slots[node_num];
+
+	hb_block = (struct o2hb_disk_heartbeat_block *)slot->ds_raw_block;
+	memset(hb_block, 0, reg->hr_block_bytes);
+	/* TODO: time stuff */
+	cputime = CURRENT_TIME.tv_sec;
+	if (!cputime)
+		cputime = 1;
+
+	hb_block->hb_seq = cpu_to_le64(cputime);
+	hb_block->hb_node = node_num;
+	hb_block->hb_generation = cpu_to_le64(generation);
+
+	/* This step must always happen last! */
+	hb_block->hb_cksum = cpu_to_le32(o2hb_compute_block_crc_le(reg,
+								   hb_block));
+
+	mlog(ML_HB_BIO, "our node generation = 0x%"MLFx64", cksum = 0x%x\n",
+	     cpu_to_le64(generation), le32_to_cpu(hb_block->hb_cksum));
+}
+
+static void o2hb_fire_callbacks(struct o2hb_callback *hbcall,
+				struct o2nm_node *node,
+				int idx)
+{
+	struct list_head *iter;
+	struct o2hb_callback_func *f;
+
+	list_for_each(iter, &hbcall->list) {
+		f = list_entry(iter, struct o2hb_callback_func, hc_item);
+		mlog(ML_HEARTBEAT, "calling funcs %p\n", f);
+		(f->hc_func)(node, idx, f->hc_data);
+	}
+}
+
+/* Will run the list in order until we process the passed event */
+static void o2hb_run_event_list(struct o2hb_node_event *queued_event)
+{
+	int empty;
+	struct o2hb_callback *hbcall;
+	struct o2hb_node_event *event;
+
+	spin_lock(&o2hb_live_lock);
+	empty = list_empty(&queued_event->hn_item);
+	spin_unlock(&o2hb_live_lock);
+	if (empty)
+		return;
+
+	/* Holding callback sem assures we don't alter the callback
+	 * lists when doing this, and serializes ourselves with other
+	 * processes wanting callbacks. */
+	down_write(&o2hb_callback_sem);
+
+	spin_lock(&o2hb_live_lock);
+	while (!list_empty(&o2hb_node_events)
+	       && !list_empty(&queued_event->hn_item)) {
+		event = list_entry(o2hb_node_events.next,
+				   struct o2hb_node_event,
+				   hn_item);
+		list_del_init(&event->hn_item);
+		spin_unlock(&o2hb_live_lock);
+
+		mlog(ML_HEARTBEAT, "Node %s event for %d\n",
+		     event->hn_event_type == O2HB_NODE_UP_CB ? "UP" : "DOWN",
+		     event->hn_node_num);
+
+		hbcall = hbcall_from_type(event->hn_event_type);
+
+		/* We should *never* have gotten on to the list with a
+		 * bad type... This isn't something that we should try
+		 * to recover from. */
+		BUG_ON(IS_ERR(hbcall));
+
+		o2hb_fire_callbacks(hbcall, event->hn_node, event->hn_node_num);
+
+		spin_lock(&o2hb_live_lock);
+	}
+	spin_unlock(&o2hb_live_lock);
+
+	up_write(&o2hb_callback_sem);
+}
+
+static void o2hb_queue_node_event(struct o2hb_node_event *event,
+				  enum o2hb_callback_type type,
+				  struct o2nm_node *node,
+				  int node_num)
+{
+	assert_spin_locked(&o2hb_live_lock);
+
+	event->hn_event_type = type;
+	event->hn_node = node;
+	event->hn_node_num = node_num;
+
+	mlog(ML_HEARTBEAT, "Queue node %s event for node %d\n",
+	     type == O2HB_NODE_UP_CB ? "UP" : "DOWN", node_num);
+
+	list_add_tail(&event->hn_item, &o2hb_node_events);
+}
+
+static void o2hb_shutdown_slot(struct o2hb_disk_slot *slot)
+{
+	struct o2hb_node_event event =
+		{ .hn_item = LIST_HEAD_INIT(event.hn_item), };
+	struct o2nm_node *node;
+
+	node = o2nm_get_node_by_num(slot->ds_node_num);
+	if (!node)
+		return;
+
+	spin_lock(&o2hb_live_lock);
+	if (!list_empty(&slot->ds_live_item)) {
+		mlog(ML_HEARTBEAT, "Shutdown, node %d leaves region\n",
+		     slot->ds_node_num);
+
+		list_del_init(&slot->ds_live_item);
+
+		if (list_empty(&o2hb_live_slots[slot->ds_node_num])) {
+			clear_bit(slot->ds_node_num, o2hb_live_node_bitmap);
+
+			o2hb_queue_node_event(&event, O2HB_NODE_DOWN_CB, node,
+					      slot->ds_node_num);
+		}
+	}
+	spin_unlock(&o2hb_live_lock);
+
+	o2hb_run_event_list(&event);
+
+	o2nm_node_put(node);
+}
+
+static int o2hb_check_slot(struct o2hb_region *reg,
+			   struct o2hb_disk_slot *slot)
+{
+	int changed = 0, gen_changed = 0;
+	struct o2hb_node_event event =
+		{ .hn_item = LIST_HEAD_INIT(event.hn_item), };
+	struct o2nm_node *node;
+	struct o2hb_disk_heartbeat_block *hb_block = reg->hr_tmp_block;
+	u64 cputime;
+
+	memcpy(hb_block, slot->ds_raw_block, reg->hr_block_bytes);
+
+	/* Is this correct? Do we assume that the node doesn't exist
+	 * if we're not configured for him? */
+	node = o2nm_get_node_by_num(slot->ds_node_num);
+	if (!node)
+		return 0;
+
+	if (!o2hb_verify_crc(reg, hb_block)) {
+		/* all paths from here will drop o2hb_live_lock for
+		 * us. */
+		spin_lock(&o2hb_live_lock);
+
+		/* Don't print an error on the console in this case -
+		 * a freshly formatted heartbeat area will not have a
+		 * crc set on it. */
+		if (list_empty(&slot->ds_live_item))
+			goto out;
+
+		/* The node is live but pushed out a bad crc. We
+		 * consider it a transient miss but don't populate any
+		 * other values as they may be junk. */
+		mlog(ML_ERROR, "Node %d has written a bad crc to %s\n",
+		     slot->ds_node_num, reg->hr_dev_name);
+		o2hb_dump_slot(hb_block);
+
+		slot->ds_equal_samples++;
+		goto fire_callbacks;
+	}
+
+	/* we don't care if these wrap.. the state transitions below
+	 * clear at the right places */
+	cputime = le64_to_cpu(hb_block->hb_seq);
+	if (slot->ds_last_time != cputime)
+		slot->ds_changed_samples++;
+	else
+		slot->ds_equal_samples++;
+	slot->ds_last_time = cputime;
+
+	/* The node changed heartbeat generations. We assume this to
+	 * mean it dropped off but came back before we timed out. We
+	 * want to consider it down for the time being but don't want
+	 * to lose any changed_samples state we might build up to
+	 * considering it live again. */
+	if (slot->ds_last_generation != le64_to_cpu(hb_block->hb_generation)) {
+		gen_changed = 1;
+		slot->ds_equal_samples = 0;
+		mlog(ML_HEARTBEAT, "Node %d changed generation (0x%"MLFx64" "
+		     "to 0x%"MLFx64")\n", slot->ds_node_num,
+		     slot->ds_last_generation,
+		     le64_to_cpu(hb_block->hb_generation));
+	}
+
+	slot->ds_last_generation = le64_to_cpu(hb_block->hb_generation);
+
+	mlog(ML_HEARTBEAT, "Slot %d gen 0x%"MLFx64" cksum 0x%x "
+	     "seq %"MLFu64" last %"MLFu64" changed %u equal %u\n",
+	     slot->ds_node_num, slot->ds_last_generation,
+	     le32_to_cpu(hb_block->hb_cksum), le64_to_cpu(hb_block->hb_seq), 
+	     slot->ds_last_time, slot->ds_changed_samples,
+	     slot->ds_equal_samples);
+
+	spin_lock(&o2hb_live_lock);
+
+fire_callbacks:
+	/* dead nodes only come to life after some number of
+	 * changes at any time during their dead time */
+	if (list_empty(&slot->ds_live_item) &&
+	    slot->ds_changed_samples >= O2HB_LIVE_THRESHOLD) {
+		mlog(ML_HEARTBEAT, "Node %d (id 0x%"MLFx64") joined my "
+		     "region\n", slot->ds_node_num, slot->ds_last_generation);
+
+		/* first on the list generates a callback */
+		if (list_empty(&o2hb_live_slots[slot->ds_node_num])) {
+			set_bit(slot->ds_node_num, o2hb_live_node_bitmap);
+
+			o2hb_queue_node_event(&event, O2HB_NODE_UP_CB, node,
+					      slot->ds_node_num);
+
+			changed = 1;
+		}
+
+		list_add_tail(&slot->ds_live_item,
+			      &o2hb_live_slots[slot->ds_node_num]);
+
+		slot->ds_equal_samples = 0;
+		goto out;
+	}
+
+	/* if the list is dead, we're done.. */
+	if (list_empty(&slot->ds_live_item))
+		goto out;
+
+	/* live nodes only go dead after enough consequtive missed
+	 * samples..  reset the missed counter whenever we see
+	 * activity */
+	if (slot->ds_equal_samples >= o2hb_dead_threshold || gen_changed) {
+		mlog(ML_HEARTBEAT, "Node %d left my region\n",
+		     slot->ds_node_num);
+
+		/* last off the live_slot generates a callback */
+		list_del_init(&slot->ds_live_item);
+		if (list_empty(&o2hb_live_slots[slot->ds_node_num])) {
+			clear_bit(slot->ds_node_num, o2hb_live_node_bitmap);
+
+			o2hb_queue_node_event(&event, O2HB_NODE_DOWN_CB, node,
+					      slot->ds_node_num);
+
+			changed = 1;
+		}
+
+		/* We don't clear this because the node is still
+		 * actually writing new blocks. */
+		if (!gen_changed)
+			slot->ds_changed_samples = 0;
+		goto out;
+	}
+	if (slot->ds_changed_samples) {
+		slot->ds_changed_samples = 0;
+		slot->ds_equal_samples = 0;
+	}
+out:
+	spin_unlock(&o2hb_live_lock);
+
+	o2hb_run_event_list(&event);
+
+	o2nm_node_put(node);
+	return changed;
+}
+
+/* This could be faster if we just implmented a find_last_bit, but I
+ * don't think the circumstances warrant it. */
+static int o2hb_highest_node(unsigned long *nodes,
+			     int numbits)
+{
+	int highest, node;
+
+	highest = numbits;
+	node = -1;
+	while ((node = find_next_bit(nodes, numbits, node + 1)) != -1) {
+		if (node >= numbits)
+			break;
+
+		highest = node;
+	}
+
+	return highest;
+}
+
+static void o2hb_do_disk_heartbeat(struct o2hb_region *reg)
+{
+	int i, ret, highest_node, change = 0;
+	unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	struct bio *write_bio;
+	struct o2hb_bio_wait_ctxt write_wc;
+
+	if (o2nm_configured_node_map(configured_nodes, sizeof(configured_nodes)))
+		return;
+
+	highest_node = o2hb_highest_node(configured_nodes, O2NM_MAX_NODES);
+	if (highest_node >= O2NM_MAX_NODES) {
+		mlog(ML_NOTICE, "ocfs2_heartbeat: no configured nodes found!\n");
+		return;
+	}
+
+	/* No sense in reading the slots of nodes that don't exist
+	 * yet. Of course, if the node definitions have holes in them
+	 * then we're reading an empty slot anyway... Consider this
+	 * best-effort. */
+	ret = o2hb_read_slots(reg, highest_node + 1);
+	if (ret < 0) {
+		mlog_errno(ret);
+		return;
+	}
+
+	/* With an up to date view of the slots, we can check that no
+	 * other node has been improperly configured to heartbeat in
+	 * our slot. */
+	if (!o2hb_check_last_timestamp(reg))
+		mlog(ML_ERROR, "Device \"%s\": another node is heartbeating "
+		     "in our slot!\n", reg->hr_dev_name);
+
+	/* fill in the proper info for our next heartbeat */
+	o2hb_prepare_block(reg, reg->hr_generation);
+
+	/* And fire off the write. Note that we don't wait on this I/O
+	 * until later. */
+	ret = o2hb_issue_node_write(reg, &write_bio, &write_wc);
+	if (ret < 0) {
+		mlog_errno(ret);
+		return;
+	}
+
+	i = -1;
+	while((i = find_next_bit(configured_nodes, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) {
+
+		change |= o2hb_check_slot(reg, &reg->hr_slots[i]);
+	}
+
+	/*
+	 * We have to be sure we've advertised ourselves on disk
+	 * before we can go to steady state.  This ensures that
+	 * people we find in our steady state have seen us.
+	 */
+	o2hb_wait_on_io(reg, &write_wc);
+	bio_put(write_bio);
+	o2hb_arm_write_timeout(reg);
+
+	/* let the person who launched us know when things are steady */
+	if (!change && (atomic_read(&reg->hr_steady_iterations) != 0)) {
+		if (atomic_dec_and_test(&reg->hr_steady_iterations))
+			wake_up(&o2hb_steady_queue);
+	}
+}
+
+/* Subtract b from a, storing the result in a. a *must* have a larger
+ * value than b. */
+static void o2hb_tv_subtract(struct timeval *a,
+			     struct timeval *b)
+{
+	/* just return 0 when a is after b */
+	if (a->tv_sec < b->tv_sec ||
+	    (a->tv_sec == b->tv_sec && a->tv_usec < b->tv_usec)) {
+		a->tv_sec = 0;
+		a->tv_usec = 0;
+		return;
+	}
+
+	a->tv_sec -= b->tv_sec;
+	a->tv_usec -= b->tv_usec;
+	while ( a->tv_usec < 0 ) {
+		a->tv_sec--;
+		a->tv_usec += 1000000;
+	}
+}
+
+static unsigned int o2hb_elapsed_msecs(struct timeval *start,
+				       struct timeval *end)
+{
+	struct timeval res = *end;
+
+	o2hb_tv_subtract(&res, start);
+
+	return res.tv_sec * 1000 + res.tv_usec / 1000;
+}
+
+/*
+ * we ride the region ref that the region dir holds.  before the region
+ * dir is removed and drops it ref it will wait to tear down this
+ * thread.
+ */
+static int o2hb_thread(void *data)
+{
+	int i, ret;
+	struct o2hb_region *reg = data;
+	struct bio *write_bio;
+	struct o2hb_bio_wait_ctxt write_wc;
+	struct timeval before_hb, after_hb;
+	unsigned int elapsed_msec;
+
+	mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread running\n");
+
+	set_user_nice(current, -20);
+
+	while (!kthread_should_stop() && !reg->hr_unclean_stop) {
+		/* We track the time spent inside
+		 * o2hb_do_disk_heartbeat so that we avoid more then
+		 * hr_timeout_ms between disk writes. On busy systems
+		 * this should result in a heartbeat which is less
+		 * likely to time itself out. */
+		do_gettimeofday(&before_hb);
+
+		o2hb_do_disk_heartbeat(reg);
+
+		do_gettimeofday(&after_hb);
+		elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
+
+		mlog(0, "start = %lu.%lu, end = %lu.%lu, msec = %u\n",
+		     before_hb.tv_sec, before_hb.tv_usec,
+		     after_hb.tv_sec, after_hb.tv_usec, elapsed_msec);
+
+		if (elapsed_msec < reg->hr_timeout_ms) {
+			/* the kthread api has blocked signals for us so no
+			 * need to record the return value. */
+			msleep_interruptible(reg->hr_timeout_ms - elapsed_msec);
+		}
+	}
+
+	o2hb_disarm_write_timeout(reg);
+
+	/* unclean stop is only used in very bad situation */
+	for(i = 0; !reg->hr_unclean_stop && i < reg->hr_blocks; i++)
+		o2hb_shutdown_slot(&reg->hr_slots[i]);
+
+	/* Explicit down notification - avoid forcing the other nodes
+	 * to timeout on this region when we could just as easily
+	 * write a clear generation - thus indicating to them that
+	 * this node has left this region.
+	 *
+	 * XXX: Should we skip this on unclean_stop? */
+	o2hb_prepare_block(reg, 0);
+	ret = o2hb_issue_node_write(reg, &write_bio, &write_wc);
+	if (ret == 0) {
+		o2hb_wait_on_io(reg, &write_wc);
+		bio_put(write_bio);
+	} else {
+		mlog_errno(ret);
+	}
+
+	mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread exiting\n");
+
+	return 0;
+}
+
+void o2hb_init(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(o2hb_callbacks); i++)
+		INIT_LIST_HEAD(&o2hb_callbacks[i].list);
+
+	for (i = 0; i < ARRAY_SIZE(o2hb_live_slots); i++)
+		INIT_LIST_HEAD(&o2hb_live_slots[i]);
+
+	INIT_LIST_HEAD(&o2hb_node_events);
+
+	memset(o2hb_live_node_bitmap, 0, sizeof(o2hb_live_node_bitmap));
+}
+
+/* if we're already in a callback then we're already serialized by the sem */
+static void o2hb_fill_node_map_from_callback(unsigned long *map,
+					     unsigned bytes)
+{
+	BUG_ON(bytes < (BITS_TO_LONGS(O2NM_MAX_NODES) * sizeof(unsigned long)));
+
+	memcpy(map, &o2hb_live_node_bitmap, bytes);
+}
+
+/*
+ * get a map of all nodes that are heartbeating in any regions
+ */
+void o2hb_fill_node_map(unsigned long *map, unsigned bytes)
+{
+	/* callers want to serialize this map and callbacks so that they
+	 * can trust that they don't miss nodes coming to the party */
+	down_read(&o2hb_callback_sem);
+	spin_lock(&o2hb_live_lock);
+	o2hb_fill_node_map_from_callback(map, bytes);
+	spin_unlock(&o2hb_live_lock);
+	up_read(&o2hb_callback_sem);
+}
+EXPORT_SYMBOL_GPL(o2hb_fill_node_map);
+
+/*
+ * heartbeat configfs bits.  The heartbeat set is a default set under
+ * the cluster set in nodemanager.c.
+ */
+
+static struct o2hb_region *to_o2hb_region(struct config_item *item)
+{
+	return item ? container_of(item, struct o2hb_region, hr_item) : NULL;
+}
+
+/* drop_item only drops its ref after killing the thread, nothing should
+ * be using the region anymore.  this has to clean up any state that
+ * attributes might have built up. */
+static void o2hb_region_release(struct config_item *item)
+{
+	int i;
+	struct page *page;
+	struct o2hb_region *reg = to_o2hb_region(item);
+
+	if (reg->hr_tmp_block)
+		kfree(reg->hr_tmp_block);
+
+	if (reg->hr_slot_data) {
+		for (i = 0; i < reg->hr_num_pages; i++) {
+			page = reg->hr_slot_data[i];
+			if (page)
+				__free_page(page);
+		}
+		kfree(reg->hr_slot_data);
+	}
+
+	if (reg->hr_bdev)
+		blkdev_put(reg->hr_bdev);
+
+	if (reg->hr_slots)
+		kfree(reg->hr_slots);
+
+	spin_lock(&o2hb_live_lock);
+	list_del(&reg->hr_all_item);
+	spin_unlock(&o2hb_live_lock);
+
+	kfree(reg);
+}
+
+static int o2hb_read_block_input(struct o2hb_region *reg,
+				 const char *page,
+				 size_t count,
+				 unsigned long *ret_bytes,
+				 unsigned int *ret_bits)
+{
+	unsigned long bytes;
+	char *p = (char *)page;
+
+	bytes = simple_strtoul(p, &p, 0);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	/* Heartbeat and fs min / max block sizes are the same. */
+	if (bytes > 4096 || bytes < 512)
+		return -ERANGE;
+	if (hweight16(bytes) != 1)
+		return -EINVAL;
+
+	if (ret_bytes)
+		*ret_bytes = bytes;
+	if (ret_bits)
+		*ret_bits = ffs(bytes) - 1;
+
+	return 0;
+}
+
+static ssize_t o2hb_region_block_bytes_read(struct o2hb_region *reg,
+					    char *page)
+{
+	return sprintf(page, "%u\n", reg->hr_block_bytes);
+}
+
+static ssize_t o2hb_region_block_bytes_write(struct o2hb_region *reg,
+					     const char *page,
+					     size_t count)
+{
+	int status;
+	unsigned long block_bytes;
+	unsigned int block_bits;
+
+	if (reg->hr_bdev)
+		return -EINVAL;
+
+	status = o2hb_read_block_input(reg, page, count,
+				       &block_bytes, &block_bits);
+	if (status)
+		return status;
+
+	reg->hr_block_bytes = (unsigned int)block_bytes;
+	reg->hr_block_bits = block_bits;
+
+	return count;
+}
+
+static ssize_t o2hb_region_start_block_read(struct o2hb_region *reg,
+					    char *page)
+{
+	return sprintf(page, "%llu\n", reg->hr_start_block);
+}
+
+static ssize_t o2hb_region_start_block_write(struct o2hb_region *reg,
+					     const char *page,
+					     size_t count)
+{
+	unsigned long long tmp;
+	char *p = (char *)page;
+
+	if (reg->hr_bdev)
+		return -EINVAL;
+
+	tmp = simple_strtoull(p, &p, 0);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	reg->hr_start_block = tmp;
+
+	return count;
+}
+
+static ssize_t o2hb_region_blocks_read(struct o2hb_region *reg,
+				       char *page)
+{
+	return sprintf(page, "%d\n", reg->hr_blocks);
+}
+
+static ssize_t o2hb_region_blocks_write(struct o2hb_region *reg,
+					const char *page,
+					size_t count)
+{
+	unsigned long tmp;
+	char *p = (char *)page;
+
+	if (reg->hr_bdev)
+		return -EINVAL;
+
+	tmp = simple_strtoul(p, &p, 0);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	if (tmp > O2NM_MAX_NODES || tmp == 0)
+		return -ERANGE;
+
+	reg->hr_blocks = (unsigned int)tmp;
+
+	return count;
+}
+
+static ssize_t o2hb_region_dev_read(struct o2hb_region *reg,
+				    char *page)
+{
+	unsigned int ret = 0;
+
+	if (reg->hr_bdev)
+		ret = sprintf(page, "%s\n", reg->hr_dev_name);
+
+	return ret;
+}
+
+static void o2hb_init_region_params(struct o2hb_region *reg)
+{
+	reg->hr_slots_per_page = PAGE_CACHE_SIZE >> reg->hr_block_bits;
+	reg->hr_timeout_ms = O2HB_REGION_TIMEOUT_MS;
+
+	mlog(ML_HEARTBEAT, "hr_start_block = %llu, hr_blocks = %u\n",
+	     reg->hr_start_block, reg->hr_blocks);
+	mlog(ML_HEARTBEAT, "hr_block_bytes = %u, hr_block_bits = %u\n",
+	     reg->hr_block_bytes, reg->hr_block_bits);
+	mlog(ML_HEARTBEAT, "hr_timeout_ms = %u\n", reg->hr_timeout_ms);
+	mlog(ML_HEARTBEAT, "dead threshold = %u\n", o2hb_dead_threshold);
+}
+
+static int o2hb_map_slot_data(struct o2hb_region *reg)
+{
+	int i, j;
+	unsigned int last_slot;
+	unsigned int spp = reg->hr_slots_per_page;
+	struct page *page;
+	char *raw;
+	struct o2hb_disk_slot *slot;
+
+	reg->hr_tmp_block = kmalloc(reg->hr_block_bytes, GFP_KERNEL);
+	if (reg->hr_tmp_block == NULL) {
+		mlog_errno(-ENOMEM);
+		return -ENOMEM;
+	}
+
+	reg->hr_slots = kcalloc(reg->hr_blocks,
+				sizeof(struct o2hb_disk_slot), GFP_KERNEL);
+	if (reg->hr_slots == NULL) {
+		mlog_errno(-ENOMEM);
+		return -ENOMEM;
+	}
+
+	for(i = 0; i < reg->hr_blocks; i++) {
+		slot = &reg->hr_slots[i];
+		slot->ds_node_num = i;
+		INIT_LIST_HEAD(&slot->ds_live_item);
+		slot->ds_raw_block = NULL;
+	}
+
+	reg->hr_num_pages = (reg->hr_blocks + spp - 1) / spp;
+	mlog(ML_HEARTBEAT, "Going to require %u pages to cover %u blocks "
+			   "at %u blocks per page\n",
+	     reg->hr_num_pages, reg->hr_blocks, spp);
+
+	reg->hr_slot_data = kcalloc(reg->hr_num_pages, sizeof(struct page *),
+				    GFP_KERNEL);
+	if (!reg->hr_slot_data) {
+		mlog_errno(-ENOMEM);
+		return -ENOMEM;
+	}
+
+	for(i = 0; i < reg->hr_num_pages; i++) {
+		page = alloc_page(GFP_KERNEL);
+		if (!page) {
+			mlog_errno(-ENOMEM);
+			return -ENOMEM;
+		}
+
+		reg->hr_slot_data[i] = page;
+
+		last_slot = i * spp;
+		raw = page_address(page);
+		for (j = 0;
+		     (j < spp) && ((j + last_slot) < reg->hr_blocks);
+		     j++) {
+			BUG_ON((j + last_slot) >= reg->hr_blocks);
+
+			slot = &reg->hr_slots[j + last_slot];
+			slot->ds_raw_block =
+				(struct o2hb_disk_heartbeat_block *) raw;
+
+			raw += reg->hr_block_bytes;
+		}
+	}
+
+	return 0;
+}
+
+/* Read in all the slots available and populate the tracking
+ * structures so that we can start with a baseline idea of what's
+ * there. */
+static int o2hb_populate_slot_data(struct o2hb_region *reg)
+{
+	int ret, i;
+	struct o2hb_disk_slot *slot;
+	struct o2hb_disk_heartbeat_block *hb_block;
+
+	mlog_entry_void();
+
+	ret = o2hb_read_slots(reg, reg->hr_blocks);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	/* We only want to get an idea of the values initially in each
+	 * slot, so we do no verification - o2hb_check_slot will
+	 * actually determine if each configured slot is valid and
+	 * whether any values have changed. */
+	for(i = 0; i < reg->hr_blocks; i++) {
+		slot = &reg->hr_slots[i];
+		hb_block = (struct o2hb_disk_heartbeat_block *) slot->ds_raw_block;
+
+		/* Only fill the values that o2hb_check_slot uses to
+		 * determine changing slots */
+		slot->ds_last_time = le64_to_cpu(hb_block->hb_seq);
+		slot->ds_last_generation = le64_to_cpu(hb_block->hb_generation);
+	}
+
+out:
+	mlog_exit(ret);
+	return ret;
+}
+
+/* this is acting as commit; we set up all of hr_bdev and hr_task or nothing */
+static ssize_t o2hb_region_dev_write(struct o2hb_region *reg,
+				     const char *page,
+				     size_t count)
+{
+	long fd;
+	int sectsize;
+	char *p = (char *)page;
+	struct file *filp = NULL;
+	struct inode *inode = NULL;
+	ssize_t ret = -EINVAL;
+
+	if (reg->hr_bdev)
+		goto out;
+
+	/* We can't heartbeat without having had our node number
+	 * configured yet. */
+	if (o2nm_this_node() == O2NM_MAX_NODES)
+		goto out;
+
+	fd = simple_strtol(p, &p, 0);
+	if (!p || (*p && (*p != '\n')))
+		goto out;
+
+	if (fd < 0 || fd >= INT_MAX)
+		goto out;
+
+	filp = fget(fd);
+	if (filp == NULL)
+		goto out;
+
+	if (reg->hr_blocks == 0 || reg->hr_start_block == 0 ||
+	    reg->hr_block_bytes == 0)
+		goto out;
+
+	inode = igrab(filp->f_mapping->host);
+	if (inode == NULL)
+		goto out;
+
+	if (!S_ISBLK(inode->i_mode))
+		goto out;
+
+	reg->hr_bdev = I_BDEV(filp->f_mapping->host);
+	ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, 0);
+	if (ret) {
+		reg->hr_bdev = NULL;
+		goto out;
+	}
+	inode = NULL;
+
+	bdevname(reg->hr_bdev, reg->hr_dev_name);
+
+	sectsize = bdev_hardsect_size(reg->hr_bdev);
+	if (sectsize != reg->hr_block_bytes) {
+		mlog(ML_ERROR,
+		     "blocksize %u incorrect for device, expected %d",
+		     reg->hr_block_bytes, sectsize);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	o2hb_init_region_params(reg);
+
+	/* Generation of zero is invalid */
+	do {
+		get_random_bytes(&reg->hr_generation,
+				 sizeof(reg->hr_generation));
+	} while (reg->hr_generation == 0);
+
+	ret = o2hb_map_slot_data(reg);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = o2hb_populate_slot_data(reg);
+	if (ret) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	INIT_WORK(&reg->hr_write_timeout_work, o2hb_write_timeout, reg);
+
+	/*
+	 * A node is considered live after it has beat LIVE_THRESHOLD
+	 * times.  We're not steady until we've given them a chance
+	 * _after_ our first read.
+	 */
+	atomic_set(&reg->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1);
+
+	reg->hr_task = kthread_run(o2hb_thread, reg, "o2hb-%s",
+				   reg->hr_item.ci_name);
+	if (IS_ERR(reg->hr_task)) {
+		ret = PTR_ERR(reg->hr_task);
+		mlog_errno(ret);
+		reg->hr_task = NULL;
+		goto out;
+	}
+
+	ret = wait_event_interruptible(o2hb_steady_queue,
+				atomic_read(&reg->hr_steady_iterations) == 0);
+	if (ret) {
+		kthread_stop(reg->hr_task);
+		reg->hr_task = NULL;
+		goto out;
+	}
+
+	ret = count;
+out:
+	if (filp)
+		fput(filp);
+	if (inode)
+		iput(inode);
+	if (ret < 0) {
+		if (reg->hr_bdev) {
+			blkdev_put(reg->hr_bdev);
+			reg->hr_bdev = NULL;
+		}
+	}
+	return ret;
+}
+
+struct o2hb_region_attribute {
+	struct configfs_attribute attr;
+	ssize_t (*show)(struct o2hb_region *, char *);
+	ssize_t (*store)(struct o2hb_region *, const char *, size_t);
+};
+
+static struct o2hb_region_attribute o2hb_region_attr_block_bytes = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "block_bytes",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= o2hb_region_block_bytes_read,
+	.store	= o2hb_region_block_bytes_write,
+};
+
+static struct o2hb_region_attribute o2hb_region_attr_start_block = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "start_block",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= o2hb_region_start_block_read,
+	.store	= o2hb_region_start_block_write,
+};
+
+static struct o2hb_region_attribute o2hb_region_attr_blocks = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "blocks",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= o2hb_region_blocks_read,
+	.store	= o2hb_region_blocks_write,
+};
+
+static struct o2hb_region_attribute o2hb_region_attr_dev = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "dev",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= o2hb_region_dev_read,
+	.store	= o2hb_region_dev_write,
+};
+
+static struct configfs_attribute *o2hb_region_attrs[] = {
+	&o2hb_region_attr_block_bytes.attr,
+	&o2hb_region_attr_start_block.attr,
+	&o2hb_region_attr_blocks.attr,
+	&o2hb_region_attr_dev.attr,
+	NULL,
+};
+
+static ssize_t o2hb_region_show(struct config_item *item,
+				struct configfs_attribute *attr,
+				char *page)
+{
+	struct o2hb_region *reg = to_o2hb_region(item);
+	struct o2hb_region_attribute *o2hb_region_attr =
+		container_of(attr, struct o2hb_region_attribute, attr);
+	ssize_t ret = 0;
+
+	if (o2hb_region_attr->show)
+		ret = o2hb_region_attr->show(reg, page);
+	return ret;
+}
+
+static ssize_t o2hb_region_store(struct config_item *item,
+				 struct configfs_attribute *attr,
+				 const char *page, size_t count)
+{
+	struct o2hb_region *reg = to_o2hb_region(item);
+	struct o2hb_region_attribute *o2hb_region_attr =
+		container_of(attr, struct o2hb_region_attribute, attr);
+	ssize_t ret = -EINVAL;
+
+	if (o2hb_region_attr->store)
+		ret = o2hb_region_attr->store(reg, page, count);
+	return ret;
+}
+
+static struct configfs_item_operations o2hb_region_item_ops = {
+	.release		= o2hb_region_release,
+	.show_attribute		= o2hb_region_show,
+	.store_attribute	= o2hb_region_store,
+};
+
+static struct config_item_type o2hb_region_type = {
+	.ct_item_ops	= &o2hb_region_item_ops,
+	.ct_attrs	= o2hb_region_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+/* heartbeat set */
+
+struct o2hb_heartbeat_group {
+	struct config_group hs_group;
+	/* some stuff? */
+};
+
+static struct o2hb_heartbeat_group *to_o2hb_heartbeat_group(struct config_group *group)
+{
+	return group ?
+		container_of(group, struct o2hb_heartbeat_group, hs_group)
+		: NULL;
+}
+
+static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *group,
+							  const char *name)
+{
+	struct o2hb_region *reg = NULL;
+	struct config_item *ret = NULL;
+
+	reg = kcalloc(1, sizeof(struct o2hb_region), GFP_KERNEL);
+	if (reg == NULL)
+		goto out; /* ENOMEM */
+
+	config_item_init_type_name(&reg->hr_item, name, &o2hb_region_type);
+
+	ret = &reg->hr_item;
+
+	spin_lock(&o2hb_live_lock);
+	list_add_tail(&reg->hr_all_item, &o2hb_all_regions);
+	spin_unlock(&o2hb_live_lock);
+out:
+	if (ret == NULL)
+		kfree(reg);
+
+	return ret;
+}
+
+static void o2hb_heartbeat_group_drop_item(struct config_group *group,
+					   struct config_item *item)
+{
+	struct o2hb_region *reg = to_o2hb_region(item);
+
+	/* stop the thread when the user removes the region dir */
+	if (reg->hr_task) {
+		kthread_stop(reg->hr_task);
+		reg->hr_task = NULL;
+	}
+
+	config_item_put(item);
+}
+
+struct o2hb_heartbeat_group_attribute {
+	struct configfs_attribute attr;
+	ssize_t (*show)(struct o2hb_heartbeat_group *, char *);
+	ssize_t (*store)(struct o2hb_heartbeat_group *, const char *, size_t);
+};
+
+static ssize_t o2hb_heartbeat_group_show(struct config_item *item,
+					 struct configfs_attribute *attr,
+					 char *page)
+{
+	struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item));
+	struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr =
+		container_of(attr, struct o2hb_heartbeat_group_attribute, attr);
+	ssize_t ret = 0;
+
+	if (o2hb_heartbeat_group_attr->show)
+		ret = o2hb_heartbeat_group_attr->show(reg, page);
+	return ret;
+}
+
+static ssize_t o2hb_heartbeat_group_store(struct config_item *item,
+					  struct configfs_attribute *attr,
+					  const char *page, size_t count)
+{
+	struct o2hb_heartbeat_group *reg = to_o2hb_heartbeat_group(to_config_group(item));
+	struct o2hb_heartbeat_group_attribute *o2hb_heartbeat_group_attr =
+		container_of(attr, struct o2hb_heartbeat_group_attribute, attr);
+	ssize_t ret = -EINVAL;
+
+	if (o2hb_heartbeat_group_attr->store)
+		ret = o2hb_heartbeat_group_attr->store(reg, page, count);
+	return ret;
+}
+
+static ssize_t o2hb_heartbeat_group_threshold_show(struct o2hb_heartbeat_group *group,
+						     char *page)
+{
+	return sprintf(page, "%u\n", o2hb_dead_threshold);
+}
+
+static ssize_t o2hb_heartbeat_group_threshold_store(struct o2hb_heartbeat_group *group,
+						    const char *page,
+						    size_t count)
+{
+	unsigned long tmp;
+	char *p = (char *)page;
+
+	tmp = simple_strtoul(p, &p, 10);
+	if (!p || (*p && (*p != '\n')))
+                return -EINVAL;
+
+	/* this will validate ranges for us. */
+	o2hb_dead_threshold_set((unsigned int) tmp);
+
+	return count;
+}
+
+static struct o2hb_heartbeat_group_attribute o2hb_heartbeat_group_attr_threshold = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "dead_threshold",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= o2hb_heartbeat_group_threshold_show,
+	.store	= o2hb_heartbeat_group_threshold_store,
+};
+
+static struct configfs_attribute *o2hb_heartbeat_group_attrs[] = {
+	&o2hb_heartbeat_group_attr_threshold.attr,
+	NULL,
+};
+
+static struct configfs_item_operations o2hb_hearbeat_group_item_ops = {
+	.show_attribute		= o2hb_heartbeat_group_show,
+	.store_attribute	= o2hb_heartbeat_group_store,
+};
+
+static struct configfs_group_operations o2hb_heartbeat_group_group_ops = {
+	.make_item	= o2hb_heartbeat_group_make_item,
+	.drop_item	= o2hb_heartbeat_group_drop_item,
+};
+
+static struct config_item_type o2hb_heartbeat_group_type = {
+	.ct_group_ops	= &o2hb_heartbeat_group_group_ops,
+	.ct_item_ops	= &o2hb_hearbeat_group_item_ops,
+	.ct_attrs	= o2hb_heartbeat_group_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+/* this is just here to avoid touching group in heartbeat.h which the
+ * entire damn world #includes */
+struct config_group *o2hb_alloc_hb_set(void)
+{
+	struct o2hb_heartbeat_group *hs = NULL;
+	struct config_group *ret = NULL;
+
+	hs = kcalloc(1, sizeof(struct o2hb_heartbeat_group), GFP_KERNEL);
+	if (hs == NULL)
+		goto out;
+
+	config_group_init_type_name(&hs->hs_group, "heartbeat",
+				    &o2hb_heartbeat_group_type);
+
+	ret = &hs->hs_group;
+out:
+	if (ret == NULL)
+		kfree(hs);
+	return ret;
+}
+
+void o2hb_free_hb_set(struct config_group *group)
+{
+	struct o2hb_heartbeat_group *hs = to_o2hb_heartbeat_group(group);
+	kfree(hs);
+}
+
+/* hb callback registration and issueing */
+
+static struct o2hb_callback *hbcall_from_type(enum o2hb_callback_type type)
+{
+	if (type == O2HB_NUM_CB)
+		return ERR_PTR(-EINVAL);
+
+	return &o2hb_callbacks[type];
+}
+
+void o2hb_setup_callback(struct o2hb_callback_func *hc,
+			 enum o2hb_callback_type type,
+			 o2hb_cb_func *func,
+			 void *data,
+			 int priority)
+{
+	INIT_LIST_HEAD(&hc->hc_item);
+	hc->hc_func = func;
+	hc->hc_data = data;
+	hc->hc_priority = priority;
+	hc->hc_type = type;
+	hc->hc_magic = O2HB_CB_MAGIC;
+}
+EXPORT_SYMBOL_GPL(o2hb_setup_callback);
+
+int o2hb_register_callback(struct o2hb_callback_func *hc)
+{
+	struct o2hb_callback_func *tmp;
+	struct list_head *iter;
+	struct o2hb_callback *hbcall;
+	int ret;
+
+	BUG_ON(hc->hc_magic != O2HB_CB_MAGIC);
+	BUG_ON(!list_empty(&hc->hc_item));
+
+	hbcall = hbcall_from_type(hc->hc_type);
+	if (IS_ERR(hbcall)) {
+		ret = PTR_ERR(hbcall);
+		goto out;
+	}
+
+	down_write(&o2hb_callback_sem);
+
+	list_for_each(iter, &hbcall->list) {
+		tmp = list_entry(iter, struct o2hb_callback_func, hc_item);
+		if (hc->hc_priority < tmp->hc_priority) {
+			list_add_tail(&hc->hc_item, iter);
+			break;
+		}
+	}
+	if (list_empty(&hc->hc_item))
+		list_add_tail(&hc->hc_item, &hbcall->list);
+
+	up_write(&o2hb_callback_sem);
+	ret = 0;
+out:
+	mlog(ML_HEARTBEAT, "returning %d on behalf of %p for funcs %p\n",
+	     ret, __builtin_return_address(0), hc);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(o2hb_register_callback);
+
+int o2hb_unregister_callback(struct o2hb_callback_func *hc)
+{
+	BUG_ON(hc->hc_magic != O2HB_CB_MAGIC);
+
+	mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n",
+	     __builtin_return_address(0), hc);
+
+	if (list_empty(&hc->hc_item))
+		return 0;
+
+	down_write(&o2hb_callback_sem);
+
+	list_del_init(&hc->hc_item);
+
+	up_write(&o2hb_callback_sem);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(o2hb_unregister_callback);
+
+int o2hb_check_node_heartbeating(u8 node_num)
+{
+	unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+
+	o2hb_fill_node_map(testing_map, sizeof(testing_map));
+	if (!test_bit(node_num, testing_map)) {
+		mlog(ML_HEARTBEAT,
+		     "node (%u) does not have heartbeating enabled.\n",
+		     node_num);
+		return 0;
+	}
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating);
+
+int o2hb_check_node_heartbeating_from_callback(u8 node_num)
+{
+	unsigned long testing_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+
+	o2hb_fill_node_map_from_callback(testing_map, sizeof(testing_map));
+	if (!test_bit(node_num, testing_map)) {
+		mlog(ML_HEARTBEAT,
+		     "node (%u) does not have heartbeating enabled.\n",
+		     node_num);
+		return 0;
+	}
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(o2hb_check_node_heartbeating_from_callback);
+
+/* Makes sure our local node is configured with a node number, and is
+ * heartbeating. */
+int o2hb_check_local_node_heartbeating(void)
+{
+	u8 node_num;
+
+	/* if this node was set then we have networking */
+	node_num = o2nm_this_node();
+	if (node_num == O2NM_MAX_NODES) {
+		mlog(ML_HEARTBEAT, "this node has not been configured.\n");
+		return 0;
+	}
+
+	return o2hb_check_node_heartbeating(node_num);
+}
+EXPORT_SYMBOL_GPL(o2hb_check_local_node_heartbeating);
+
+/*
+ * this is just a hack until we get the plumbing which flips file systems
+ * read only and drops the hb ref instead of killing the node dead.
+ */
+void o2hb_stop_all_regions(void)
+{
+	struct o2hb_region *reg;
+
+	mlog(ML_ERROR, "stopping heartbeat on all active regions.\n");
+
+	spin_lock(&o2hb_live_lock);
+
+	list_for_each_entry(reg, &o2hb_all_regions, hr_all_item)
+		reg->hr_unclean_stop = 1;
+
+	spin_unlock(&o2hb_live_lock);
+}
+EXPORT_SYMBOL_GPL(o2hb_stop_all_regions);
diff --git a/fs/ocfs2/cluster/heartbeat.h b/fs/ocfs2/cluster/heartbeat.h
new file mode 100644
index 0000000..cac6223
--- /dev/null
+++ b/fs/ocfs2/cluster/heartbeat.h
@@ -0,0 +1,82 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * heartbeat.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef O2CLUSTER_HEARTBEAT_H
+#define O2CLUSTER_HEARTBEAT_H
+
+#include "ocfs2_heartbeat.h"
+
+#define O2HB_REGION_TIMEOUT_MS		2000
+
+/* number of changes to be seen as live */
+#define O2HB_LIVE_THRESHOLD	   2
+/* number of equal samples to be seen as dead */
+extern unsigned int o2hb_dead_threshold;
+#define O2HB_DEFAULT_DEAD_THRESHOLD	   7
+/* Otherwise MAX_WRITE_TIMEOUT will be zero... */
+#define O2HB_MIN_DEAD_THRESHOLD	  2
+#define O2HB_MAX_WRITE_TIMEOUT_MS (O2HB_REGION_TIMEOUT_MS * (o2hb_dead_threshold - 1))
+
+#define O2HB_CB_MAGIC		0x51d1e4ec
+
+/* callback stuff */
+enum o2hb_callback_type {
+	O2HB_NODE_DOWN_CB = 0,
+	O2HB_NODE_UP_CB,
+	O2HB_NUM_CB
+};
+
+struct o2nm_node;
+typedef void (o2hb_cb_func)(struct o2nm_node *, int, void *);
+
+struct o2hb_callback_func {
+	u32			hc_magic;
+	struct list_head	hc_item;
+	o2hb_cb_func		*hc_func;
+	void			*hc_data;
+	int			hc_priority;
+	enum o2hb_callback_type hc_type;
+};
+
+struct config_group *o2hb_alloc_hb_set(void);
+void o2hb_free_hb_set(struct config_group *group);
+
+void o2hb_setup_callback(struct o2hb_callback_func *hc,
+			 enum o2hb_callback_type type,
+			 o2hb_cb_func *func,
+			 void *data,
+			 int priority);
+int o2hb_register_callback(struct o2hb_callback_func *hc);
+int o2hb_unregister_callback(struct o2hb_callback_func *hc);
+void o2hb_fill_node_map(unsigned long *map,
+			unsigned bytes);
+void o2hb_init(void);
+int o2hb_check_node_heartbeating(u8 node_num);
+int o2hb_check_node_heartbeating_from_callback(u8 node_num);
+int o2hb_check_local_node_heartbeating(void);
+void o2hb_stop_all_regions(void);
+
+#endif /* O2CLUSTER_HEARTBEAT_H */
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
new file mode 100644
index 0000000..fd741ce
--- /dev/null
+++ b/fs/ocfs2/cluster/masklog.c
@@ -0,0 +1,166 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2004, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/string.h>
+#include <asm/uaccess.h>
+
+#include "masklog.h"
+
+struct mlog_bits mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK);
+EXPORT_SYMBOL_GPL(mlog_and_bits);
+struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(MLOG_INITIAL_NOT_MASK);
+EXPORT_SYMBOL_GPL(mlog_not_bits);
+
+static ssize_t mlog_mask_show(u64 mask, char *buf)
+{
+	char *state;
+
+	if (__mlog_test_u64(mask, mlog_and_bits))
+		state = "allow";
+	else if (__mlog_test_u64(mask, mlog_not_bits))
+		state = "deny";
+	else
+		state = "off";
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", state);
+}
+
+static ssize_t mlog_mask_store(u64 mask, const char *buf, size_t count)
+{
+	if (!strnicmp(buf, "allow", 5)) {
+		__mlog_set_u64(mask, mlog_and_bits);
+		__mlog_clear_u64(mask, mlog_not_bits);
+	} else if (!strnicmp(buf, "deny", 4)) {
+		__mlog_set_u64(mask, mlog_not_bits);
+		__mlog_clear_u64(mask, mlog_and_bits);
+	} else if (!strnicmp(buf, "off", 3)) {
+		__mlog_clear_u64(mask, mlog_not_bits);
+		__mlog_clear_u64(mask, mlog_and_bits);
+	} else
+		return -EINVAL;
+
+	return count;
+}
+
+struct mlog_attribute {
+	struct attribute attr;
+	u64 mask;
+};
+
+#define to_mlog_attr(_attr) container_of(_attr, struct mlog_attribute, attr)
+
+#define define_mask(_name) {			\
+	.attr = {				\
+		.name = #_name,			\
+		.mode = S_IRUGO | S_IWUSR,	\
+	},					\
+	.mask = ML_##_name,			\
+}
+
+static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = {
+	define_mask(ENTRY),
+	define_mask(EXIT),
+	define_mask(TCP),
+	define_mask(MSG),
+	define_mask(SOCKET),
+	define_mask(HEARTBEAT),
+	define_mask(HB_BIO),
+	define_mask(DLMFS),
+	define_mask(DLM),
+	define_mask(DLM_DOMAIN),
+	define_mask(DLM_THREAD),
+	define_mask(DLM_MASTER),
+	define_mask(DLM_RECOVERY),
+	define_mask(AIO),
+	define_mask(JOURNAL),
+	define_mask(DISK_ALLOC),
+	define_mask(SUPER),
+	define_mask(FILE_IO),
+	define_mask(EXTENT_MAP),
+	define_mask(DLM_GLUE),
+	define_mask(BH_IO),
+	define_mask(UPTODATE),
+	define_mask(NAMEI),
+	define_mask(INODE),
+	define_mask(VOTE),
+	define_mask(DCACHE),
+	define_mask(CONN),
+	define_mask(QUORUM),
+	define_mask(EXPORT),
+	define_mask(ERROR),
+	define_mask(NOTICE),
+	define_mask(KTHREAD),
+};
+
+static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, };
+
+static ssize_t mlog_show(struct kobject *obj, struct attribute *attr,
+			 char *buf)
+{
+	struct mlog_attribute *mlog_attr = to_mlog_attr(attr);
+
+	return mlog_mask_show(mlog_attr->mask, buf);
+}
+
+static ssize_t mlog_store(struct kobject *obj, struct attribute *attr,
+			  const char *buf, size_t count)
+{
+	struct mlog_attribute *mlog_attr = to_mlog_attr(attr);
+
+	return mlog_mask_store(mlog_attr->mask, buf, count);
+}
+
+static struct sysfs_ops mlog_attr_ops = {
+	.show  = mlog_show,
+	.store = mlog_store,
+};
+
+static struct kobj_type mlog_ktype = {
+	.default_attrs = mlog_attr_ptrs,
+	.sysfs_ops     = &mlog_attr_ops,
+};
+
+static struct kset mlog_kset = {
+	.kobj   = {.name = "logmask", .ktype = &mlog_ktype},
+};
+
+int mlog_sys_init(struct subsystem *o2cb_subsys)
+{
+	int i = 0;
+
+	while (mlog_attrs[i].attr.mode) {
+		mlog_attr_ptrs[i] = &mlog_attrs[i].attr;
+		i++;
+	}
+	mlog_attr_ptrs[i] = NULL;
+
+	mlog_kset.subsys = o2cb_subsys;
+	return kset_register(&mlog_kset);
+}
+
+void mlog_sys_shutdown(void)
+{
+	kset_unregister(&mlog_kset);
+}
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
new file mode 100644
index 0000000..e8c56a3
--- /dev/null
+++ b/fs/ocfs2/cluster/masklog.h
@@ -0,0 +1,274 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef O2CLUSTER_MASKLOG_H
+#define O2CLUSTER_MASKLOG_H
+
+/*
+ * For now this is a trivial wrapper around printk() that gives the critical
+ * ability to enable sets of debugging output at run-time.  In the future this
+ * will almost certainly be redirected to relayfs so that it can pay a
+ * substantially lower heisenberg tax.
+ *
+ * Callers associate the message with a bitmask and a global bitmask is
+ * maintained with help from /proc.  If any of the bits match the message is
+ * output.
+ *
+ * We must have efficient bit tests on i386 and it seems gcc still emits crazy
+ * code for the 64bit compare.  It emits very good code for the dual unsigned
+ * long tests, though, completely avoiding tests that can never pass if the
+ * caller gives a constant bitmask that fills one of the longs with all 0s.  So
+ * the desire is to have almost all of the calls decided on by comparing just
+ * one of the longs.  This leads to having infrequently given bits that are
+ * frequently matched in the high bits.
+ *
+ * _ERROR and _NOTICE are used for messages that always go to the console and
+ * have appropriate KERN_ prefixes.  We wrap these in our function instead of
+ * just calling printk() so that this can eventually make its way through
+ * relayfs along with the debugging messages.  Everything else gets KERN_DEBUG.
+ * The inline tests and macro dance give GCC the opportunity to quite cleverly
+ * only emit the appropriage printk() when the caller passes in a constant
+ * mask, as is almost always the case.
+ *
+ * All this bitmask nonsense is hidden from the /proc interface so that Joel
+ * doesn't have an aneurism.  Reading the file gives a straight forward
+ * indication of which bits are on or off:
+ * 	ENTRY off
+ * 	EXIT off
+ * 	TCP off
+ * 	MSG off
+ * 	SOCKET off
+ * 	ERROR off
+ * 	NOTICE on
+ *
+ * Writing changes the state of a given bit and requires a strictly formatted
+ * single write() call:
+ *
+ * 	write(fd, "ENTRY on", 8);
+ *
+ * would turn the entry bit on.  "1" is also accepted in the place of "on", and
+ * "off" and "0" behave as expected.
+ *
+ * Some trivial shell can flip all the bits on or off:
+ *
+ * log_mask="/proc/fs/ocfs2_nodemanager/log_mask"
+ * cat $log_mask | (
+ * 	while read bit status; do
+ * 		# $1 is "on" or "off", say
+ * 		echo "$bit $1" > $log_mask
+ * 	done
+ * )
+ */
+
+/* for task_struct */
+#include <linux/sched.h>
+
+/* bits that are frequently given and infrequently matched in the low word */
+/* NOTE: If you add a flag, you need to also update mlog.c! */
+#define ML_ENTRY	0x0000000000000001ULL /* func call entry */
+#define ML_EXIT		0x0000000000000002ULL /* func call exit */
+#define ML_TCP		0x0000000000000004ULL /* net cluster/tcp.c */
+#define ML_MSG		0x0000000000000008ULL /* net network messages */
+#define ML_SOCKET	0x0000000000000010ULL /* net socket lifetime */
+#define ML_HEARTBEAT	0x0000000000000020ULL /* hb all heartbeat tracking */
+#define ML_HB_BIO	0x0000000000000040ULL /* hb io tracing */
+#define ML_DLMFS	0x0000000000000080ULL /* dlm user dlmfs */
+#define ML_DLM		0x0000000000000100ULL /* dlm general debugging */
+#define ML_DLM_DOMAIN	0x0000000000000200ULL /* dlm domain debugging */
+#define ML_DLM_THREAD	0x0000000000000400ULL /* dlm domain thread */
+#define ML_DLM_MASTER	0x0000000000000800ULL /* dlm master functions */
+#define ML_DLM_RECOVERY	0x0000000000001000ULL /* dlm master functions */
+#define ML_AIO		0x0000000000002000ULL /* ocfs2 aio read and write */
+#define ML_JOURNAL	0x0000000000004000ULL /* ocfs2 journalling functions */
+#define ML_DISK_ALLOC	0x0000000000008000ULL /* ocfs2 disk allocation */
+#define ML_SUPER	0x0000000000010000ULL /* ocfs2 mount / umount */
+#define ML_FILE_IO	0x0000000000020000ULL /* ocfs2 file I/O */
+#define ML_EXTENT_MAP	0x0000000000040000ULL /* ocfs2 extent map caching */
+#define ML_DLM_GLUE	0x0000000000080000ULL /* ocfs2 dlm glue layer */
+#define ML_BH_IO	0x0000000000100000ULL /* ocfs2 buffer I/O */
+#define ML_UPTODATE	0x0000000000200000ULL /* ocfs2 caching sequence #'s */
+#define ML_NAMEI	0x0000000000400000ULL /* ocfs2 directory / namespace */
+#define ML_INODE	0x0000000000800000ULL /* ocfs2 inode manipulation */
+#define ML_VOTE		0x0000000001000000ULL /* ocfs2 node messaging  */
+#define ML_DCACHE	0x0000000002000000ULL /* ocfs2 dcache operations */
+#define ML_CONN		0x0000000004000000ULL /* net connection management */
+#define ML_QUORUM	0x0000000008000000ULL /* net connection quorum */
+#define ML_EXPORT	0x0000000010000000ULL /* ocfs2 export operations */
+/* bits that are infrequently given and frequently matched in the high word */
+#define ML_ERROR	0x0000000100000000ULL /* sent to KERN_ERR */
+#define ML_NOTICE	0x0000000200000000ULL /* setn to KERN_NOTICE */
+#define ML_KTHREAD	0x0000000400000000ULL /* kernel thread activity */
+
+#define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE)
+#define MLOG_INITIAL_NOT_MASK (ML_ENTRY|ML_EXIT)
+#ifndef MLOG_MASK_PREFIX
+#define MLOG_MASK_PREFIX 0
+#endif
+
+#define MLOG_MAX_BITS 64
+
+struct mlog_bits {
+	unsigned long words[MLOG_MAX_BITS / BITS_PER_LONG];
+};
+
+extern struct mlog_bits mlog_and_bits, mlog_not_bits;
+
+#if BITS_PER_LONG == 32
+
+#define __mlog_test_u64(mask, bits)			\
+	( (u32)(mask & 0xffffffff) & bits.words[0] || 	\
+	  ((u64)(mask) >> 32) & bits.words[1] )
+#define __mlog_set_u64(mask, bits) do {			\
+	bits.words[0] |= (u32)(mask & 0xffffffff);	\
+       	bits.words[1] |= (u64)(mask) >> 32;		\
+} while (0)
+#define __mlog_clear_u64(mask, bits) do {		\
+	bits.words[0] &= ~((u32)(mask & 0xffffffff));	\
+       	bits.words[1] &= ~((u64)(mask) >> 32);		\
+} while (0)
+#define MLOG_BITS_RHS(mask) {				\
+	{						\
+		[0] = (u32)(mask & 0xffffffff),		\
+		[1] = (u64)(mask) >> 32,		\
+	}						\
+}
+
+#else /* 32bit long above, 64bit long below */
+
+#define __mlog_test_u64(mask, bits)	((mask) & bits.words[0])
+#define __mlog_set_u64(mask, bits) do {		\
+	bits.words[0] |= (mask);		\
+} while (0)
+#define __mlog_clear_u64(mask, bits) do {	\
+	bits.words[0] &= ~(mask);		\
+} while (0)
+#define MLOG_BITS_RHS(mask) { { (mask) } }
+
+#endif
+
+/*
+ * smp_processor_id() "helpfully" screams when called outside preemptible
+ * regions in current kernels.  sles doesn't have the variants that don't
+ * scream.  just do this instead of trying to guess which we're building
+ * against.. *sigh*.
+ */
+#define __mlog_cpu_guess ({		\
+	unsigned long _cpu = get_cpu();	\
+	put_cpu();			\
+	_cpu;				\
+})
+
+/* In the following two macros, the whitespace after the ',' just
+ * before ##args is intentional. Otherwise, gcc 2.95 will eat the
+ * previous token if args expands to nothing.
+ */
+#define __mlog_printk(level, fmt, args...)				\
+	printk(level "(%u,%lu):%s:%d " fmt, current->pid,		\
+	       __mlog_cpu_guess, __PRETTY_FUNCTION__, __LINE__ ,	\
+	       ##args)
+
+#define mlog(mask, fmt, args...) do {					\
+	u64 __m = MLOG_MASK_PREFIX | (mask);				\
+	if (__mlog_test_u64(__m, mlog_and_bits) &&			\
+	    !__mlog_test_u64(__m, mlog_not_bits)) {			\
+		if (__m & ML_ERROR)					\
+			__mlog_printk(KERN_ERR, "ERROR: "fmt , ##args);	\
+		else if (__m & ML_NOTICE)				\
+			__mlog_printk(KERN_NOTICE, fmt , ##args);	\
+		else __mlog_printk(KERN_INFO, fmt , ##args);		\
+	}								\
+} while (0)
+
+#define mlog_errno(st) do {						\
+	int _st = (st);							\
+	if (_st != -ERESTARTSYS && _st != -EINTR &&			\
+	    _st != AOP_TRUNCATED_PAGE)					\
+		mlog(ML_ERROR, "status = %lld\n", (long long)_st);	\
+} while (0)
+
+#define mlog_entry(fmt, args...) do {					\
+	mlog(ML_ENTRY, "ENTRY:" fmt , ##args);				\
+} while (0)
+
+#define mlog_entry_void() do {						\
+	mlog(ML_ENTRY, "ENTRY:\n");					\
+} while (0)
+
+/*
+ * We disable this for sparse.
+ */
+#if !defined(__CHECKER__)
+#define mlog_exit(st) do {						     \
+	if (__builtin_types_compatible_p(typeof(st), unsigned long))	     \
+		mlog(ML_EXIT, "EXIT: %lu\n", (unsigned long) (st));	     \
+	else if (__builtin_types_compatible_p(typeof(st), signed long))      \
+		mlog(ML_EXIT, "EXIT: %ld\n", (signed long) (st));	     \
+	else if (__builtin_types_compatible_p(typeof(st), unsigned int)	     \
+		 || __builtin_types_compatible_p(typeof(st), unsigned short) \
+		 || __builtin_types_compatible_p(typeof(st), unsigned char)) \
+		mlog(ML_EXIT, "EXIT: %u\n", (unsigned int) (st));	     \
+	else if (__builtin_types_compatible_p(typeof(st), signed int)	     \
+		 || __builtin_types_compatible_p(typeof(st), signed short)   \
+		 || __builtin_types_compatible_p(typeof(st), signed char))   \
+		mlog(ML_EXIT, "EXIT: %d\n", (signed int) (st));		     \
+	else if (__builtin_types_compatible_p(typeof(st), long long))	     \
+		mlog(ML_EXIT, "EXIT: %lld\n", (long long) (st));	     \
+	else								     \
+		mlog(ML_EXIT, "EXIT: %llu\n", (unsigned long long) (st));    \
+} while (0)
+#else
+#define mlog_exit(st) do {						     \
+	mlog(ML_EXIT, "EXIT: %lld\n", (long long) (st));		     \
+} while (0)
+#endif
+
+#define mlog_exit_ptr(ptr) do {						\
+	mlog(ML_EXIT, "EXIT: %p\n", ptr);				\
+} while (0)
+
+#define mlog_exit_void() do {						\
+	mlog(ML_EXIT, "EXIT\n");					\
+} while (0)
+
+#define mlog_bug_on_msg(cond, fmt, args...) do {			\
+	if (cond) {							\
+		mlog(ML_ERROR, "bug expression: " #cond "\n");		\
+		mlog(ML_ERROR, fmt, ##args);				\
+		BUG();							\
+	}								\
+} while (0)
+
+#if (BITS_PER_LONG == 32) || defined(CONFIG_X86_64)
+#define MLFi64 "lld"
+#define MLFu64 "llu"
+#define MLFx64 "llx"
+#else
+#define MLFi64 "ld"
+#define MLFu64 "lu"
+#define MLFx64 "lx"
+#endif
+
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+int mlog_sys_init(struct subsystem *o2cb_subsys);
+void mlog_sys_shutdown(void);
+
+#endif /* O2CLUSTER_MASKLOG_H */
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
new file mode 100644
index 0000000..5fd60c1
--- /dev/null
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -0,0 +1,791 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2004, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sysctl.h>
+#include <linux/configfs.h>
+
+#include "endian.h"
+#include "tcp.h"
+#include "nodemanager.h"
+#include "heartbeat.h"
+#include "masklog.h"
+#include "sys.h"
+#include "ver.h"
+
+/* for now we operate under the assertion that there can be only one
+ * cluster active at a time.  Changing this will require trickling
+ * cluster references throughout where nodes are looked up */
+static struct o2nm_cluster *o2nm_single_cluster = NULL;
+
+#define OCFS2_MAX_HB_CTL_PATH 256
+static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl";
+
+static ctl_table ocfs2_nm_table[] = {
+	{
+		.ctl_name	= 1,
+		.procname	= "hb_ctl_path",
+		.data		= ocfs2_hb_ctl_path,
+		.maxlen		= OCFS2_MAX_HB_CTL_PATH,
+		.mode		= 0644,
+		.proc_handler	= &proc_dostring,
+		.strategy	= &sysctl_string,
+	},
+	{ .ctl_name = 0 }
+};
+
+static ctl_table ocfs2_mod_table[] = {
+	{
+		.ctl_name	= KERN_OCFS2_NM,
+		.procname	= "nm",
+		.data		= NULL,
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ocfs2_nm_table
+	},
+	{ .ctl_name = 0}
+};
+
+static ctl_table ocfs2_kern_table[] = {
+	{
+		.ctl_name	= KERN_OCFS2,
+		.procname	= "ocfs2",
+		.data		= NULL,
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ocfs2_mod_table
+	},
+	{ .ctl_name = 0}
+};
+
+static ctl_table ocfs2_root_table[] = {
+	{
+		.ctl_name	= CTL_FS,
+		.procname	= "fs",
+		.data		= NULL,
+		.maxlen		= 0,
+		.mode		= 0555,
+		.child		= ocfs2_kern_table
+	},
+	{ .ctl_name = 0 }
+};
+
+static struct ctl_table_header *ocfs2_table_header = NULL;
+
+const char *o2nm_get_hb_ctl_path(void)
+{
+	return ocfs2_hb_ctl_path;
+}
+EXPORT_SYMBOL_GPL(o2nm_get_hb_ctl_path);
+
+struct o2nm_cluster {
+	struct config_group	cl_group;
+	unsigned		cl_has_local:1;
+	u8			cl_local_node;
+	rwlock_t		cl_nodes_lock;
+	struct o2nm_node  	*cl_nodes[O2NM_MAX_NODES];
+	struct rb_root		cl_node_ip_tree;
+	/* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */
+	unsigned long	cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+};
+
+struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
+{
+	struct o2nm_node *node = NULL;
+
+	if (node_num >= O2NM_MAX_NODES || o2nm_single_cluster == NULL)
+		goto out;
+
+	read_lock(&o2nm_single_cluster->cl_nodes_lock);
+	node = o2nm_single_cluster->cl_nodes[node_num];
+	if (node)
+		config_item_get(&node->nd_item);
+	read_unlock(&o2nm_single_cluster->cl_nodes_lock);
+out:
+	return node;
+}
+EXPORT_SYMBOL_GPL(o2nm_get_node_by_num);
+
+int o2nm_configured_node_map(unsigned long *map, unsigned bytes)
+{
+	struct o2nm_cluster *cluster = o2nm_single_cluster;
+
+	BUG_ON(bytes < (sizeof(cluster->cl_nodes_bitmap)));
+
+	if (cluster == NULL)
+		return -EINVAL;
+
+	read_lock(&cluster->cl_nodes_lock);
+	memcpy(map, cluster->cl_nodes_bitmap, sizeof(cluster->cl_nodes_bitmap));
+	read_unlock(&cluster->cl_nodes_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(o2nm_configured_node_map);
+
+static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster,
+						  __be32 ip_needle,
+						  struct rb_node ***ret_p,
+						  struct rb_node **ret_parent)
+{
+	struct rb_node **p = &cluster->cl_node_ip_tree.rb_node;
+	struct rb_node *parent = NULL;
+	struct o2nm_node *node, *ret = NULL;
+
+	while (*p) {
+		parent = *p;
+		node = rb_entry(parent, struct o2nm_node, nd_ip_node);
+
+		if (memcmp(&ip_needle, &node->nd_ipv4_address,
+		           sizeof(ip_needle)) < 0)
+			p = &(*p)->rb_left;
+		else if (memcmp(&ip_needle, &node->nd_ipv4_address,
+			        sizeof(ip_needle)) > 0)
+			p = &(*p)->rb_right;
+		else {
+			ret = node;
+			break;
+		}
+	}
+
+	if (ret_p != NULL)
+		*ret_p = p;
+	if (ret_parent != NULL)
+		*ret_parent = parent;
+
+	return ret;
+}
+
+struct o2nm_node *o2nm_get_node_by_ip(__be32 addr)
+{
+	struct o2nm_node *node = NULL;
+	struct o2nm_cluster *cluster = o2nm_single_cluster;
+
+	if (cluster == NULL)
+		goto out;
+
+	read_lock(&cluster->cl_nodes_lock);
+	node = o2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL);
+	if (node)
+		config_item_get(&node->nd_item);
+	read_unlock(&cluster->cl_nodes_lock);
+
+out:
+	return node;
+}
+EXPORT_SYMBOL_GPL(o2nm_get_node_by_ip);
+
+void o2nm_node_put(struct o2nm_node *node)
+{
+	config_item_put(&node->nd_item);
+}
+EXPORT_SYMBOL_GPL(o2nm_node_put);
+
+void o2nm_node_get(struct o2nm_node *node)
+{
+	config_item_get(&node->nd_item);
+}
+EXPORT_SYMBOL_GPL(o2nm_node_get);
+
+u8 o2nm_this_node(void)
+{
+	u8 node_num = O2NM_MAX_NODES;
+
+	if (o2nm_single_cluster && o2nm_single_cluster->cl_has_local)
+		node_num = o2nm_single_cluster->cl_local_node;
+
+	return node_num;
+}
+EXPORT_SYMBOL_GPL(o2nm_this_node);
+
+/* node configfs bits */
+
+static struct o2nm_cluster *to_o2nm_cluster(struct config_item *item)
+{
+	return item ?
+		container_of(to_config_group(item), struct o2nm_cluster,
+			     cl_group)
+		: NULL;
+}
+
+static struct o2nm_node *to_o2nm_node(struct config_item *item)
+{
+	return item ? container_of(item, struct o2nm_node, nd_item) : NULL;
+}
+
+static void o2nm_node_release(struct config_item *item)
+{
+	struct o2nm_node *node = to_o2nm_node(item);
+	kfree(node);
+}
+
+static ssize_t o2nm_node_num_read(struct o2nm_node *node, char *page)
+{
+	return sprintf(page, "%d\n", node->nd_num);
+}
+
+static struct o2nm_cluster *to_o2nm_cluster_from_node(struct o2nm_node *node)
+{
+	/* through the first node_set .parent
+	 * mycluster/nodes/mynode == o2nm_cluster->o2nm_node_group->o2nm_node */
+	return to_o2nm_cluster(node->nd_item.ci_parent->ci_parent);
+}
+
+enum {
+	O2NM_NODE_ATTR_NUM = 0,
+	O2NM_NODE_ATTR_PORT,
+	O2NM_NODE_ATTR_ADDRESS,
+	O2NM_NODE_ATTR_LOCAL,
+};
+
+static ssize_t o2nm_node_num_write(struct o2nm_node *node, const char *page,
+				   size_t count)
+{
+	struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
+	unsigned long tmp;
+	char *p = (char *)page;
+
+	tmp = simple_strtoul(p, &p, 0);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	if (tmp >= O2NM_MAX_NODES)
+		return -ERANGE;
+
+	/* once we're in the cl_nodes tree networking can look us up by
+	 * node number and try to use our address and port attributes
+	 * to connect to this node.. make sure that they've been set
+	 * before writing the node attribute? */
+	if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
+	    !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
+		return -EINVAL; /* XXX */
+
+	write_lock(&cluster->cl_nodes_lock);
+	if (cluster->cl_nodes[tmp])
+		p = NULL;
+	else  {
+		cluster->cl_nodes[tmp] = node;
+		node->nd_num = tmp;
+		set_bit(tmp, cluster->cl_nodes_bitmap);
+	}
+	write_unlock(&cluster->cl_nodes_lock);
+	if (p == NULL)
+		return -EEXIST;
+
+	return count;
+}
+static ssize_t o2nm_node_ipv4_port_read(struct o2nm_node *node, char *page)
+{
+	return sprintf(page, "%u\n", ntohs(node->nd_ipv4_port));
+}
+
+static ssize_t o2nm_node_ipv4_port_write(struct o2nm_node *node,
+					 const char *page, size_t count)
+{
+	unsigned long tmp;
+	char *p = (char *)page;
+
+	tmp = simple_strtoul(p, &p, 0);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	if (tmp == 0)
+		return -EINVAL;
+	if (tmp >= (u16)-1)
+		return -ERANGE;
+
+	node->nd_ipv4_port = htons(tmp);
+
+	return count;
+}
+
+static ssize_t o2nm_node_ipv4_address_read(struct o2nm_node *node, char *page)
+{
+	return sprintf(page, "%u.%u.%u.%u\n", NIPQUAD(node->nd_ipv4_address));
+}
+
+static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node,
+					    const char *page,
+					    size_t count)
+{
+	struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
+	int ret, i;
+	struct rb_node **p, *parent;
+	unsigned int octets[4];
+	__be32 ipv4_addr = 0;
+
+	ret = sscanf(page, "%3u.%3u.%3u.%3u", &octets[3], &octets[2],
+		     &octets[1], &octets[0]);
+	if (ret != 4)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(octets); i++) {
+		if (octets[i] > 255)
+			return -ERANGE;
+		be32_add_cpu(&ipv4_addr, octets[i] << (i * 8));
+	}
+
+	ret = 0;
+	write_lock(&cluster->cl_nodes_lock);
+	if (o2nm_node_ip_tree_lookup(cluster, ipv4_addr, &p, &parent))
+		ret = -EEXIST;
+	else {
+		rb_link_node(&node->nd_ip_node, parent, p);
+		rb_insert_color(&node->nd_ip_node, &cluster->cl_node_ip_tree);
+	}
+	write_unlock(&cluster->cl_nodes_lock);
+	if (ret)
+		return ret;
+
+	memcpy(&node->nd_ipv4_address, &ipv4_addr, sizeof(ipv4_addr));
+
+	return count;
+}
+
+static ssize_t o2nm_node_local_read(struct o2nm_node *node, char *page)
+{
+	return sprintf(page, "%d\n", node->nd_local);
+}
+
+static ssize_t o2nm_node_local_write(struct o2nm_node *node, const char *page,
+				     size_t count)
+{
+	struct o2nm_cluster *cluster = to_o2nm_cluster_from_node(node);
+	unsigned long tmp;
+	char *p = (char *)page;
+	ssize_t ret;
+
+	tmp = simple_strtoul(p, &p, 0);
+	if (!p || (*p && (*p != '\n')))
+		return -EINVAL;
+
+	tmp = !!tmp; /* boolean of whether this node wants to be local */
+
+	/* setting local turns on networking rx for now so we require having
+	 * set everything else first */
+	if (!test_bit(O2NM_NODE_ATTR_ADDRESS, &node->nd_set_attributes) ||
+	    !test_bit(O2NM_NODE_ATTR_NUM, &node->nd_set_attributes) ||
+	    !test_bit(O2NM_NODE_ATTR_PORT, &node->nd_set_attributes))
+		return -EINVAL; /* XXX */
+
+	/* the only failure case is trying to set a new local node
+	 * when a different one is already set */
+	if (tmp && tmp == cluster->cl_has_local &&
+	    cluster->cl_local_node != node->nd_num)
+		return -EBUSY;
+
+	/* bring up the rx thread if we're setting the new local node. */
+	if (tmp && !cluster->cl_has_local) {
+		ret = o2net_start_listening(node);
+		if (ret)
+			return ret;
+	}
+
+	if (!tmp && cluster->cl_has_local &&
+	    cluster->cl_local_node == node->nd_num) {
+		o2net_stop_listening(node);
+		cluster->cl_local_node = O2NM_INVALID_NODE_NUM;
+	}
+
+	node->nd_local = tmp;
+	if (node->nd_local) {
+		cluster->cl_has_local = tmp;
+		cluster->cl_local_node = node->nd_num;
+	}
+
+	return count;
+}
+
+struct o2nm_node_attribute {
+	struct configfs_attribute attr;
+	ssize_t (*show)(struct o2nm_node *, char *);
+	ssize_t (*store)(struct o2nm_node *, const char *, size_t);
+};
+
+static struct o2nm_node_attribute o2nm_node_attr_num = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "num",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= o2nm_node_num_read,
+	.store	= o2nm_node_num_write,
+};
+
+static struct o2nm_node_attribute o2nm_node_attr_ipv4_port = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "ipv4_port",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= o2nm_node_ipv4_port_read,
+	.store	= o2nm_node_ipv4_port_write,
+};
+
+static struct o2nm_node_attribute o2nm_node_attr_ipv4_address = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "ipv4_address",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= o2nm_node_ipv4_address_read,
+	.store	= o2nm_node_ipv4_address_write,
+};
+
+static struct o2nm_node_attribute o2nm_node_attr_local = {
+	.attr	= { .ca_owner = THIS_MODULE,
+		    .ca_name = "local",
+		    .ca_mode = S_IRUGO | S_IWUSR },
+	.show	= o2nm_node_local_read,
+	.store	= o2nm_node_local_write,
+};
+
+static struct configfs_attribute *o2nm_node_attrs[] = {
+	[O2NM_NODE_ATTR_NUM] = &o2nm_node_attr_num.attr,
+	[O2NM_NODE_ATTR_PORT] = &o2nm_node_attr_ipv4_port.attr,
+	[O2NM_NODE_ATTR_ADDRESS] = &o2nm_node_attr_ipv4_address.attr,
+	[O2NM_NODE_ATTR_LOCAL] = &o2nm_node_attr_local.attr,
+	NULL,
+};
+
+static int o2nm_attr_index(struct configfs_attribute *attr)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(o2nm_node_attrs); i++) {
+		if (attr == o2nm_node_attrs[i])
+			return i;
+	}
+	BUG();
+	return 0;
+}
+
+static ssize_t o2nm_node_show(struct config_item *item,
+			      struct configfs_attribute *attr,
+			      char *page)
+{
+	struct o2nm_node *node = to_o2nm_node(item);
+	struct o2nm_node_attribute *o2nm_node_attr =
+		container_of(attr, struct o2nm_node_attribute, attr);
+	ssize_t ret = 0;
+
+	if (o2nm_node_attr->show)
+		ret = o2nm_node_attr->show(node, page);
+	return ret;
+}
+
+static ssize_t o2nm_node_store(struct config_item *item,
+			       struct configfs_attribute *attr,
+			       const char *page, size_t count)
+{
+	struct o2nm_node *node = to_o2nm_node(item);
+	struct o2nm_node_attribute *o2nm_node_attr =
+		container_of(attr, struct o2nm_node_attribute, attr);
+	ssize_t ret;
+	int attr_index = o2nm_attr_index(attr);
+
+	if (o2nm_node_attr->store == NULL) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (test_bit(attr_index, &node->nd_set_attributes))
+		return -EBUSY;
+
+	ret = o2nm_node_attr->store(node, page, count);
+	if (ret < count)
+		goto out;
+
+	set_bit(attr_index, &node->nd_set_attributes);
+out:
+	return ret;
+}
+
+static struct configfs_item_operations o2nm_node_item_ops = {
+	.release		= o2nm_node_release,
+	.show_attribute		= o2nm_node_show,
+	.store_attribute	= o2nm_node_store,
+};
+
+static struct config_item_type o2nm_node_type = {
+	.ct_item_ops	= &o2nm_node_item_ops,
+	.ct_attrs	= o2nm_node_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+/* node set */
+
+struct o2nm_node_group {
+	struct config_group ns_group;
+	/* some stuff? */
+};
+
+#if 0
+static struct o2nm_node_group *to_o2nm_node_group(struct config_group *group)
+{
+	return group ?
+		container_of(group, struct o2nm_node_group, ns_group)
+		: NULL;
+}
+#endif
+
+static struct config_item *o2nm_node_group_make_item(struct config_group *group,
+						     const char *name)
+{
+	struct o2nm_node *node = NULL;
+	struct config_item *ret = NULL;
+
+	if (strlen(name) > O2NM_MAX_NAME_LEN)
+		goto out; /* ENAMETOOLONG */
+
+	node = kcalloc(1, sizeof(struct o2nm_node), GFP_KERNEL);
+	if (node == NULL)
+		goto out; /* ENOMEM */
+
+	strcpy(node->nd_name, name); /* use item.ci_namebuf instead? */
+	config_item_init_type_name(&node->nd_item, name, &o2nm_node_type);
+	spin_lock_init(&node->nd_lock);
+
+	ret = &node->nd_item;
+
+out:
+	if (ret == NULL)
+		kfree(node);
+
+	return ret;
+}
+
+static void o2nm_node_group_drop_item(struct config_group *group,
+				      struct config_item *item)
+{
+	struct o2nm_node *node = to_o2nm_node(item);
+	struct o2nm_cluster *cluster = to_o2nm_cluster(group->cg_item.ci_parent);
+
+	o2net_disconnect_node(node);
+
+	if (cluster->cl_has_local &&
+	    (cluster->cl_local_node == node->nd_num)) {
+		cluster->cl_has_local = 0;
+		cluster->cl_local_node = O2NM_INVALID_NODE_NUM;
+		o2net_stop_listening(node);
+	}
+
+	/* XXX call into net to stop this node from trading messages */
+
+	write_lock(&cluster->cl_nodes_lock);
+
+	/* XXX sloppy */
+	if (node->nd_ipv4_address)
+		rb_erase(&node->nd_ip_node, &cluster->cl_node_ip_tree);
+
+	/* nd_num might be 0 if the node number hasn't been set.. */
+	if (cluster->cl_nodes[node->nd_num] == node) {
+		cluster->cl_nodes[node->nd_num] = NULL;
+		clear_bit(node->nd_num, cluster->cl_nodes_bitmap);
+	}
+	write_unlock(&cluster->cl_nodes_lock);
+
+	config_item_put(item);
+}
+
+static struct configfs_group_operations o2nm_node_group_group_ops = {
+	.make_item	= o2nm_node_group_make_item,
+	.drop_item	= o2nm_node_group_drop_item,
+};
+
+static struct config_item_type o2nm_node_group_type = {
+	.ct_group_ops	= &o2nm_node_group_group_ops,
+	.ct_owner	= THIS_MODULE,
+};
+
+/* cluster */
+
+static void o2nm_cluster_release(struct config_item *item)
+{
+	struct o2nm_cluster *cluster = to_o2nm_cluster(item);
+
+	kfree(cluster->cl_group.default_groups);
+	kfree(cluster);
+}
+
+static struct configfs_item_operations o2nm_cluster_item_ops = {
+	.release	= o2nm_cluster_release,
+};
+
+static struct config_item_type o2nm_cluster_type = {
+	.ct_item_ops	= &o2nm_cluster_item_ops,
+	.ct_owner	= THIS_MODULE,
+};
+
+/* cluster set */
+
+struct o2nm_cluster_group {
+	struct configfs_subsystem cs_subsys;
+	/* some stuff? */
+};
+
+#if 0
+static struct o2nm_cluster_group *to_o2nm_cluster_group(struct config_group *group)
+{
+	return group ?
+		container_of(to_configfs_subsystem(group), struct o2nm_cluster_group, cs_subsys)
+	       : NULL;
+}
+#endif
+
+static struct config_group *o2nm_cluster_group_make_group(struct config_group *group,
+							  const char *name)
+{
+	struct o2nm_cluster *cluster = NULL;
+	struct o2nm_node_group *ns = NULL;
+	struct config_group *o2hb_group = NULL, *ret = NULL;
+	void *defs = NULL;
+
+	/* this runs under the parent dir's i_sem; there can be only
+	 * one caller in here at a time */
+	if (o2nm_single_cluster)
+		goto out; /* ENOSPC */
+
+	cluster = kcalloc(1, sizeof(struct o2nm_cluster), GFP_KERNEL);
+	ns = kcalloc(1, sizeof(struct o2nm_node_group), GFP_KERNEL);
+	defs = kcalloc(3, sizeof(struct config_group *), GFP_KERNEL);
+	o2hb_group = o2hb_alloc_hb_set();
+	if (cluster == NULL || ns == NULL || o2hb_group == NULL || defs == NULL)
+		goto out;
+
+	config_group_init_type_name(&cluster->cl_group, name,
+				    &o2nm_cluster_type);
+	config_group_init_type_name(&ns->ns_group, "node",
+				    &o2nm_node_group_type);
+
+	cluster->cl_group.default_groups = defs;
+	cluster->cl_group.default_groups[0] = &ns->ns_group;
+	cluster->cl_group.default_groups[1] = o2hb_group;
+	cluster->cl_group.default_groups[2] = NULL;
+	rwlock_init(&cluster->cl_nodes_lock);
+	cluster->cl_node_ip_tree = RB_ROOT;
+
+	ret = &cluster->cl_group;
+	o2nm_single_cluster = cluster;
+
+out:
+	if (ret == NULL) {
+		kfree(cluster);
+		kfree(ns);
+		o2hb_free_hb_set(o2hb_group);
+		kfree(defs);
+	}
+
+	return ret;
+}
+
+static void o2nm_cluster_group_drop_item(struct config_group *group, struct config_item *item)
+{
+	struct o2nm_cluster *cluster = to_o2nm_cluster(item);
+	int i;
+	struct config_item *killme;
+
+	BUG_ON(o2nm_single_cluster != cluster);
+	o2nm_single_cluster = NULL;
+
+	for (i = 0; cluster->cl_group.default_groups[i]; i++) {
+		killme = &cluster->cl_group.default_groups[i]->cg_item;
+		cluster->cl_group.default_groups[i] = NULL;
+		config_item_put(killme);
+	}
+
+	config_item_put(item);
+}
+
+static struct configfs_group_operations o2nm_cluster_group_group_ops = {
+	.make_group	= o2nm_cluster_group_make_group,
+	.drop_item	= o2nm_cluster_group_drop_item,
+};
+
+static struct config_item_type o2nm_cluster_group_type = {
+	.ct_group_ops	= &o2nm_cluster_group_group_ops,
+	.ct_owner	= THIS_MODULE,
+};
+
+static struct o2nm_cluster_group o2nm_cluster_group = {
+	.cs_subsys = {
+		.su_group = {
+			.cg_item = {
+				.ci_namebuf = "cluster",
+				.ci_type = &o2nm_cluster_group_type,
+			},
+		},
+	},
+};
+
+static void __exit exit_o2nm(void)
+{
+	if (ocfs2_table_header)
+		unregister_sysctl_table(ocfs2_table_header);
+
+	/* XXX sync with hb callbacks and shut down hb? */
+	o2net_unregister_hb_callbacks();
+	configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
+	o2cb_sys_shutdown();
+
+	o2net_exit();
+}
+
+static int __init init_o2nm(void)
+{
+	int ret = -1;
+
+	cluster_print_version();
+
+	o2hb_init();
+	o2net_init();
+
+	ocfs2_table_header = register_sysctl_table(ocfs2_root_table, 0);
+	if (!ocfs2_table_header) {
+		printk(KERN_ERR "nodemanager: unable to register sysctl\n");
+		ret = -ENOMEM; /* or something. */
+		goto out;
+	}
+
+	ret = o2net_register_hb_callbacks();
+	if (ret)
+		goto out_sysctl;
+
+	config_group_init(&o2nm_cluster_group.cs_subsys.su_group);
+	init_MUTEX(&o2nm_cluster_group.cs_subsys.su_sem);
+	ret = configfs_register_subsystem(&o2nm_cluster_group.cs_subsys);
+	if (ret) {
+		printk(KERN_ERR "nodemanager: Registration returned %d\n", ret);
+		goto out_callbacks;
+	}
+
+	ret = o2cb_sys_init();
+	if (!ret)
+		goto out;
+
+	configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys);
+out_callbacks:
+	o2net_unregister_hb_callbacks();
+out_sysctl:
+	unregister_sysctl_table(ocfs2_table_header);
+out:
+	return ret;
+}
+
+MODULE_AUTHOR("Oracle");
+MODULE_LICENSE("GPL");
+
+module_init(init_o2nm)
+module_exit(exit_o2nm)
diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h
new file mode 100644
index 0000000..fce8033
--- /dev/null
+++ b/fs/ocfs2/cluster/nodemanager.h
@@ -0,0 +1,64 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * nodemanager.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef O2CLUSTER_NODEMANAGER_H
+#define O2CLUSTER_NODEMANAGER_H
+
+#include "ocfs2_nodemanager.h"
+
+/* This totally doesn't belong here. */
+#include <linux/configfs.h>
+#include <linux/rbtree.h>
+
+#define KERN_OCFS2		988
+#define KERN_OCFS2_NM		1
+
+const char *o2nm_get_hb_ctl_path(void);
+
+struct o2nm_node {
+	spinlock_t		nd_lock;
+	struct config_item	nd_item;
+	char			nd_name[O2NM_MAX_NAME_LEN+1]; /* replace? */
+	__u8			nd_num;
+	/* only one address per node, as attributes, for now. */
+	__be32			nd_ipv4_address;
+	__be16			nd_ipv4_port;
+	struct rb_node		nd_ip_node;
+	/* there can be only one local node for now */
+	int			nd_local;
+
+	unsigned long		nd_set_attributes;
+};
+
+u8 o2nm_this_node(void);
+
+int o2nm_configured_node_map(unsigned long *map, unsigned bytes);
+struct o2nm_node *o2nm_get_node_by_num(u8 node_num);
+struct o2nm_node *o2nm_get_node_by_ip(__be32 addr);
+void o2nm_node_get(struct o2nm_node *node);
+void o2nm_node_put(struct o2nm_node *node);
+
+#endif /* O2CLUSTER_NODEMANAGER_H */
diff --git a/fs/ocfs2/cluster/ocfs2_heartbeat.h b/fs/ocfs2/cluster/ocfs2_heartbeat.h
new file mode 100644
index 0000000..9409606
--- /dev/null
+++ b/fs/ocfs2/cluster/ocfs2_heartbeat.h
@@ -0,0 +1,37 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ocfs2_heartbeat.h
+ *
+ * On-disk structures for ocfs2_heartbeat
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef _OCFS2_HEARTBEAT_H
+#define _OCFS2_HEARTBEAT_H
+
+struct o2hb_disk_heartbeat_block {
+	__le64 hb_seq;
+	__u8  hb_node;
+	__u8  hb_pad1[3];
+	__le32 hb_cksum;
+	__le64 hb_generation;
+};
+
+#endif /* _OCFS2_HEARTBEAT_H */
diff --git a/fs/ocfs2/cluster/ocfs2_nodemanager.h b/fs/ocfs2/cluster/ocfs2_nodemanager.h
new file mode 100644
index 0000000..5b9854b
--- /dev/null
+++ b/fs/ocfs2/cluster/ocfs2_nodemanager.h
@@ -0,0 +1,39 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ocfs2_nodemanager.h
+ *
+ * Header describing the interface between userspace and the kernel
+ * for the ocfs2_nodemanager module.
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef _OCFS2_NODEMANAGER_H
+#define _OCFS2_NODEMANAGER_H
+
+#define O2NM_API_VERSION	5
+
+#define O2NM_MAX_NODES		255
+#define O2NM_INVALID_NODE_NUM	255
+
+/* host name, group name, cluster name all 64 bytes */
+#define O2NM_MAX_NAME_LEN        64    // __NEW_UTS_LEN
+
+#endif /* _OCFS2_NODEMANAGER_H */
diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c
new file mode 100644
index 0000000..7bba98f
--- /dev/null
+++ b/fs/ocfs2/cluster/quorum.c
@@ -0,0 +1,315 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ *
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+/* This quorum hack is only here until we transition to some more rational
+ * approach that is driven from userspace.  Honest.  No foolin'.
+ *
+ * Imagine two nodes lose network connectivity to each other but they're still
+ * up and operating in every other way.  Presumably a network timeout indicates
+ * that a node is broken and should be recovered.  They can't both recover each
+ * other and both carry on without serialising their access to the file system.
+ * They need to decide who is authoritative.  Now extend that problem to
+ * arbitrary groups of nodes losing connectivity between each other.
+ *
+ * So we declare that a node which has given up on connecting to a majority
+ * of nodes who are still heartbeating will fence itself.
+ *
+ * There are huge opportunities for races here.  After we give up on a node's
+ * connection we need to wait long enough to give heartbeat an opportunity
+ * to declare the node as truly dead.  We also need to be careful with the
+ * race between when we see a node start heartbeating and when we connect
+ * to it.
+ *
+ * So nodes that are in this transtion put a hold on the quorum decision
+ * with a counter.  As they fall out of this transition they drop the count
+ * and if they're the last, they fire off the decision.
+ */
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+
+#include "heartbeat.h"
+#include "nodemanager.h"
+#define MLOG_MASK_PREFIX ML_QUORUM
+#include "masklog.h"
+#include "quorum.h"
+
+static struct o2quo_state {
+	spinlock_t		qs_lock;
+	struct work_struct	qs_work;
+	int			qs_pending;
+	int			qs_heartbeating;
+	unsigned long		qs_hb_bm[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	int			qs_connected;
+	unsigned long		qs_conn_bm[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	int			qs_holds;
+	unsigned long		qs_hold_bm[BITS_TO_LONGS(O2NM_MAX_NODES)];
+} o2quo_state;
+
+/* this is horribly heavy-handed.  It should instead flip the file
+ * system RO and call some userspace script. */
+static void o2quo_fence_self(void)
+{
+	/* panic spins with interrupts enabled.  with preempt
+	 * threads can still schedule, etc, etc */
+	o2hb_stop_all_regions();
+	panic("ocfs2 is very sorry to be fencing this system by panicing\n");
+}
+
+/* Indicate that a timeout occured on a hearbeat region write. The
+ * other nodes in the cluster may consider us dead at that time so we
+ * want to "fence" ourselves so that we don't scribble on the disk
+ * after they think they've recovered us. This can't solve all
+ * problems related to writeout after recovery but this hack can at
+ * least close some of those gaps. When we have real fencing, this can
+ * go away as our node would be fenced externally before other nodes
+ * begin recovery. */
+void o2quo_disk_timeout(void)
+{
+	o2quo_fence_self();
+}
+
+static void o2quo_make_decision(void *arg)
+{
+	int quorum;
+	int lowest_hb, lowest_reachable = 0, fence = 0;
+	struct o2quo_state *qs = &o2quo_state;
+
+	spin_lock(&qs->qs_lock);
+
+	lowest_hb = find_first_bit(qs->qs_hb_bm, O2NM_MAX_NODES);
+	if (lowest_hb != O2NM_MAX_NODES)
+		lowest_reachable = test_bit(lowest_hb, qs->qs_conn_bm);
+
+	mlog(0, "heartbeating: %d, connected: %d, "
+	     "lowest: %d (%sreachable)\n", qs->qs_heartbeating,
+	     qs->qs_connected, lowest_hb, lowest_reachable ? "" : "un");
+
+	if (!test_bit(o2nm_this_node(), qs->qs_hb_bm) ||
+	    qs->qs_heartbeating == 1)
+		goto out;
+
+	if (qs->qs_heartbeating & 1) {
+		/* the odd numbered cluster case is straight forward --
+		 * if we can't talk to the majority we're hosed */
+		quorum = (qs->qs_heartbeating + 1)/2;
+		if (qs->qs_connected < quorum) {
+			mlog(ML_ERROR, "fencing this node because it is "
+			     "only connected to %u nodes and %u is needed "
+			     "to make a quorum out of %u heartbeating nodes\n",
+			     qs->qs_connected, quorum,
+			     qs->qs_heartbeating);
+			fence = 1;
+		}
+	} else {
+		/* the even numbered cluster adds the possibility of each half
+		 * of the cluster being able to talk amongst themselves.. in
+		 * that case we're hosed if we can't talk to the group that has
+		 * the lowest numbered node */
+		quorum = qs->qs_heartbeating / 2;
+		if (qs->qs_connected < quorum) {
+			mlog(ML_ERROR, "fencing this node because it is "
+			     "only connected to %u nodes and %u is needed "
+			     "to make a quorum out of %u heartbeating nodes\n",
+			     qs->qs_connected, quorum,
+			     qs->qs_heartbeating);
+			fence = 1;
+		}
+		else if ((qs->qs_connected == quorum) &&
+			 !lowest_reachable) {
+			mlog(ML_ERROR, "fencing this node because it is "
+			     "connected to a half-quorum of %u out of %u "
+			     "nodes which doesn't include the lowest active "
+			     "node %u\n", quorum, qs->qs_heartbeating,
+			     lowest_hb);
+			fence = 1;
+		}
+	}
+
+out:
+	spin_unlock(&qs->qs_lock);
+	if (fence)
+		o2quo_fence_self();
+}
+
+static void o2quo_set_hold(struct o2quo_state *qs, u8 node)
+{
+	assert_spin_locked(&qs->qs_lock);
+
+	if (!test_and_set_bit(node, qs->qs_hold_bm)) {
+		qs->qs_holds++;
+		mlog_bug_on_msg(qs->qs_holds == O2NM_MAX_NODES,
+			        "node %u\n", node);
+		mlog(0, "node %u, %d total\n", node, qs->qs_holds);
+	}
+}
+
+static void o2quo_clear_hold(struct o2quo_state *qs, u8 node)
+{
+	assert_spin_locked(&qs->qs_lock);
+
+	if (test_and_clear_bit(node, qs->qs_hold_bm)) {
+		mlog(0, "node %u, %d total\n", node, qs->qs_holds - 1);
+		if (--qs->qs_holds == 0) {
+			if (qs->qs_pending) {
+				qs->qs_pending = 0;
+				schedule_work(&qs->qs_work);
+			}
+		}
+		mlog_bug_on_msg(qs->qs_holds < 0, "node %u, holds %d\n",
+				node, qs->qs_holds);
+	}
+}
+
+/* as a node comes up we delay the quorum decision until we know the fate of
+ * the connection.  the hold will be droped in conn_up or hb_down.  it might be
+ * perpetuated by con_err until hb_down.  if we already have a conn, we might
+ * be dropping a hold that conn_up got. */
+void o2quo_hb_up(u8 node)
+{
+	struct o2quo_state *qs = &o2quo_state;
+
+	spin_lock(&qs->qs_lock);
+
+	qs->qs_heartbeating++;
+	mlog_bug_on_msg(qs->qs_heartbeating == O2NM_MAX_NODES,
+		        "node %u\n", node);
+	mlog_bug_on_msg(test_bit(node, qs->qs_hb_bm), "node %u\n", node);
+	set_bit(node, qs->qs_hb_bm);
+
+	mlog(0, "node %u, %d total\n", node, qs->qs_heartbeating);
+
+	if (!test_bit(node, qs->qs_conn_bm))
+		o2quo_set_hold(qs, node);
+	else
+		o2quo_clear_hold(qs, node);
+
+	spin_unlock(&qs->qs_lock);
+}
+
+/* hb going down releases any holds we might have had due to this node from
+ * conn_up, conn_err, or hb_up */
+void o2quo_hb_down(u8 node)
+{
+	struct o2quo_state *qs = &o2quo_state;
+
+	spin_lock(&qs->qs_lock);
+
+	qs->qs_heartbeating--;
+	mlog_bug_on_msg(qs->qs_heartbeating < 0,
+			"node %u, %d heartbeating\n",
+			node, qs->qs_heartbeating);
+	mlog_bug_on_msg(!test_bit(node, qs->qs_hb_bm), "node %u\n", node);
+	clear_bit(node, qs->qs_hb_bm);
+
+	mlog(0, "node %u, %d total\n", node, qs->qs_heartbeating);
+
+	o2quo_clear_hold(qs, node);
+
+	spin_unlock(&qs->qs_lock);
+}
+
+/* this tells us that we've decided that the node is still heartbeating
+ * even though we've lost it's conn.  it must only be called after conn_err
+ * and indicates that we must now make a quorum decision in the future,
+ * though we might be doing so after waiting for holds to drain.  Here
+ * we'll be dropping the hold from conn_err. */
+void o2quo_hb_still_up(u8 node)
+{
+	struct o2quo_state *qs = &o2quo_state;
+
+	spin_lock(&qs->qs_lock);
+
+	mlog(0, "node %u\n", node);
+
+	qs->qs_pending = 1;
+	o2quo_clear_hold(qs, node);
+
+	spin_unlock(&qs->qs_lock);
+}
+
+/* This is analagous to hb_up.  as a node's connection comes up we delay the
+ * quorum decision until we see it heartbeating.  the hold will be droped in
+ * hb_up or hb_down.  it might be perpetuated by con_err until hb_down.  if
+ * it's already heartbeating we we might be dropping a hold that conn_up got.
+ * */
+void o2quo_conn_up(u8 node)
+{
+	struct o2quo_state *qs = &o2quo_state;
+
+	spin_lock(&qs->qs_lock);
+
+	qs->qs_connected++;
+	mlog_bug_on_msg(qs->qs_connected == O2NM_MAX_NODES,
+		        "node %u\n", node);
+	mlog_bug_on_msg(test_bit(node, qs->qs_conn_bm), "node %u\n", node);
+	set_bit(node, qs->qs_conn_bm);
+
+	mlog(0, "node %u, %d total\n", node, qs->qs_connected);
+
+	if (!test_bit(node, qs->qs_hb_bm))
+		o2quo_set_hold(qs, node);
+	else
+		o2quo_clear_hold(qs, node);
+
+	spin_unlock(&qs->qs_lock);
+}
+
+/* we've decided that we won't ever be connecting to the node again.  if it's
+ * still heartbeating we grab a hold that will delay decisions until either the
+ * node stops heartbeating from hb_down or the caller decides that the node is
+ * still up and calls still_up */
+void o2quo_conn_err(u8 node)
+{
+	struct o2quo_state *qs = &o2quo_state;
+
+	spin_lock(&qs->qs_lock);
+
+	if (test_bit(node, qs->qs_conn_bm)) {
+		qs->qs_connected--;
+		mlog_bug_on_msg(qs->qs_connected < 0,
+				"node %u, connected %d\n",
+				node, qs->qs_connected);
+
+		clear_bit(node, qs->qs_conn_bm);
+	}
+
+	mlog(0, "node %u, %d total\n", node, qs->qs_connected);
+
+	if (test_bit(node, qs->qs_hb_bm))
+		o2quo_set_hold(qs, node);
+
+	spin_unlock(&qs->qs_lock);
+}
+
+void o2quo_init(void)
+{
+	struct o2quo_state *qs = &o2quo_state;
+
+	spin_lock_init(&qs->qs_lock);
+	INIT_WORK(&qs->qs_work, o2quo_make_decision, NULL);
+}
+
+void o2quo_exit(void)
+{
+	flush_scheduled_work();
+}
diff --git a/fs/ocfs2/cluster/quorum.h b/fs/ocfs2/cluster/quorum.h
new file mode 100644
index 0000000..6649cc6
--- /dev/null
+++ b/fs/ocfs2/cluster/quorum.h
@@ -0,0 +1,36 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef O2CLUSTER_QUORUM_H
+#define O2CLUSTER_QUORUM_H
+
+void o2quo_init(void);
+void o2quo_exit(void);
+
+void o2quo_hb_up(u8 node);
+void o2quo_hb_down(u8 node);
+void o2quo_hb_still_up(u8 node);
+void o2quo_conn_up(u8 node);
+void o2quo_conn_err(u8 node);
+void o2quo_disk_timeout(void);
+
+#endif /* O2CLUSTER_QUORUM_H */
diff --git a/fs/ocfs2/cluster/sys.c b/fs/ocfs2/cluster/sys.c
new file mode 100644
index 0000000..1d9f6ac
--- /dev/null
+++ b/fs/ocfs2/cluster/sys.c
@@ -0,0 +1,124 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * sys.c
+ *
+ * OCFS2 cluster sysfs interface
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation,
+ * version 2 of the License.
+ *
+ * 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 021110-1307, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+
+#include "ocfs2_nodemanager.h"
+#include "masklog.h"
+#include "sys.h"
+
+struct o2cb_attribute {
+	struct attribute	attr;
+	ssize_t (*show)(char *buf);
+	ssize_t (*store)(const char *buf, size_t count);
+};
+
+#define O2CB_ATTR(_name, _mode, _show, _store)	\
+struct o2cb_attribute o2cb_attr_##_name = __ATTR(_name, _mode, _show, _store)
+
+#define to_o2cb_subsys(k) container_of(to_kset(k), struct subsystem, kset)
+#define to_o2cb_attr(_attr) container_of(_attr, struct o2cb_attribute, attr)
+
+static ssize_t o2cb_interface_revision_show(char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n", O2NM_API_VERSION);
+}
+
+static O2CB_ATTR(interface_revision, S_IFREG | S_IRUGO, o2cb_interface_revision_show, NULL);
+
+static struct attribute *o2cb_attrs[] = {
+	&o2cb_attr_interface_revision.attr,
+	NULL,
+};
+
+static ssize_t
+o2cb_show(struct kobject * kobj, struct attribute * attr, char * buffer);
+static ssize_t
+o2cb_store(struct kobject * kobj, struct attribute * attr,
+	   const char * buffer, size_t count);
+static struct sysfs_ops o2cb_sysfs_ops = {
+	.show	= o2cb_show,
+	.store	= o2cb_store,
+};
+
+static struct kobj_type o2cb_subsys_type = {
+	.default_attrs	= o2cb_attrs,
+	.sysfs_ops	= &o2cb_sysfs_ops,
+};
+
+/* gives us o2cb_subsys */
+static decl_subsys(o2cb, NULL, NULL);
+
+static ssize_t
+o2cb_show(struct kobject * kobj, struct attribute * attr, char * buffer)
+{
+	struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr);
+	struct subsystem *sbs = to_o2cb_subsys(kobj);
+
+	BUG_ON(sbs != &o2cb_subsys);
+
+	if (o2cb_attr->show)
+		return o2cb_attr->show(buffer);
+	return -EIO;
+}
+
+static ssize_t
+o2cb_store(struct kobject * kobj, struct attribute * attr,
+	     const char * buffer, size_t count)
+{
+	struct o2cb_attribute *o2cb_attr = to_o2cb_attr(attr);
+	struct subsystem *sbs = to_o2cb_subsys(kobj);
+
+	BUG_ON(sbs != &o2cb_subsys);
+
+	if (o2cb_attr->store)
+		return o2cb_attr->store(buffer, count);
+	return -EIO;
+}
+
+void o2cb_sys_shutdown(void)
+{
+	mlog_sys_shutdown();
+	subsystem_unregister(&o2cb_subsys);
+}
+
+int o2cb_sys_init(void)
+{
+	int ret;
+
+	o2cb_subsys.kset.kobj.ktype = &o2cb_subsys_type;
+	ret = subsystem_register(&o2cb_subsys);
+	if (ret)
+		return ret;
+
+	ret = mlog_sys_init(&o2cb_subsys);
+	if (ret)
+		subsystem_unregister(&o2cb_subsys);
+	return ret;
+}
diff --git a/fs/ocfs2/cluster/sys.h b/fs/ocfs2/cluster/sys.h
new file mode 100644
index 0000000..d66b8ab
--- /dev/null
+++ b/fs/ocfs2/cluster/sys.h
@@ -0,0 +1,33 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * sys.h
+ *
+ * Function prototypes for o2cb sysfs interface
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation,
+ * version 2 of the License.
+ *
+ * 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 021110-1307, USA.
+ *
+ */
+
+#ifndef O2CLUSTER_SYS_H
+#define O2CLUSTER_SYS_H
+
+void o2cb_sys_shutdown(void);
+int o2cb_sys_init(void);
+
+#endif /* O2CLUSTER_SYS_H */
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
new file mode 100644
index 0000000..35d92c0
--- /dev/null
+++ b/fs/ocfs2/cluster/tcp.c
@@ -0,0 +1,1829 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ *
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ * ----
+ *
+ * Callers for this were originally written against a very simple synchronus
+ * API.  This implementation reflects those simple callers.  Some day I'm sure
+ * we'll need to move to a more robust posting/callback mechanism.
+ *
+ * Transmit calls pass in kernel virtual addresses and block copying this into
+ * the socket's tx buffers via a usual blocking sendmsg.  They'll block waiting
+ * for a failed socket to timeout.  TX callers can also pass in a poniter to an
+ * 'int' which gets filled with an errno off the wire in response to the
+ * message they send.
+ *
+ * Handlers for unsolicited messages are registered.  Each socket has a page
+ * that incoming data is copied into.  First the header, then the data.
+ * Handlers are called from only one thread with a reference to this per-socket
+ * page.  This page is destroyed after the handler call, so it can't be
+ * referenced beyond the call.  Handlers may block but are discouraged from
+ * doing so.
+ *
+ * Any framing errors (bad magic, large payload lengths) close a connection.
+ *
+ * Our sock_container holds the state we associate with a socket.  It's current
+ * framing state is held there as well as the refcounting we do around when it
+ * is safe to tear down the socket.  The socket is only finally torn down from
+ * the container when the container loses all of its references -- so as long
+ * as you hold a ref on the container you can trust that the socket is valid
+ * for use with kernel socket APIs.
+ *
+ * Connections are initiated between a pair of nodes when the node with the
+ * higher node number gets a heartbeat callback which indicates that the lower
+ * numbered node has started heartbeating.  The lower numbered node is passive
+ * and only accepts the connection if the higher numbered node is heartbeating.
+ */
+
+#include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
+#include <linux/idr.h>
+#include <linux/kref.h>
+#include <net/tcp.h>
+
+#include <asm/uaccess.h>
+
+#include "heartbeat.h"
+#include "tcp.h"
+#include "nodemanager.h"
+#define MLOG_MASK_PREFIX ML_TCP
+#include "masklog.h"
+#include "quorum.h"
+
+#include "tcp_internal.h"
+
+/* 
+ * The linux network stack isn't sparse endian clean.. It has macros like
+ * ntohs() which perform the endian checks and structs like sockaddr_in
+ * which aren't annotated.  So __force is found here to get the build
+ * clean.  When they emerge from the dark ages and annotate the code
+ * we can remove these.
+ */
+
+#define SC_NODEF_FMT "node %s (num %u) at %u.%u.%u.%u:%u"
+#define SC_NODEF_ARGS(sc) sc->sc_node->nd_name, sc->sc_node->nd_num,	\
+			  NIPQUAD(sc->sc_node->nd_ipv4_address),	\
+			  ntohs(sc->sc_node->nd_ipv4_port)
+
+/*
+ * In the following two log macros, the whitespace after the ',' just
+ * before ##args is intentional. Otherwise, gcc 2.95 will eat the
+ * previous token if args expands to nothing.
+ */
+#define msglog(hdr, fmt, args...) do {					\
+	typeof(hdr) __hdr = (hdr);					\
+	mlog(ML_MSG, "[mag %u len %u typ %u stat %d sys_stat %d "	\
+	     "key %08x num %u] " fmt,					\
+	     be16_to_cpu(__hdr->magic), be16_to_cpu(__hdr->data_len), 	\
+	     be16_to_cpu(__hdr->msg_type), be32_to_cpu(__hdr->status),	\
+	     be32_to_cpu(__hdr->sys_status), be32_to_cpu(__hdr->key),	\
+	     be32_to_cpu(__hdr->msg_num) ,  ##args);			\
+} while (0)
+
+#define sclog(sc, fmt, args...) do {					\
+	typeof(sc) __sc = (sc);						\
+	mlog(ML_SOCKET, "[sc %p refs %d sock %p node %u page %p "	\
+	     "pg_off %zu] " fmt, __sc,					\
+	     atomic_read(&__sc->sc_kref.refcount), __sc->sc_sock,	\
+	    __sc->sc_node->nd_num, __sc->sc_page, __sc->sc_page_off ,	\
+	    ##args);							\
+} while (0)
+
+static rwlock_t o2net_handler_lock = RW_LOCK_UNLOCKED;
+static struct rb_root o2net_handler_tree = RB_ROOT;
+
+static struct o2net_node o2net_nodes[O2NM_MAX_NODES];
+
+/* XXX someday we'll need better accounting */
+static struct socket *o2net_listen_sock = NULL;
+
+/*
+ * listen work is only queued by the listening socket callbacks on the
+ * o2net_wq.  teardown detaches the callbacks before destroying the workqueue.
+ * quorum work is queued as sock containers are shutdown.. stop_listening
+ * tears down all the node's sock containers, preventing future shutdowns
+ * and queued quroum work, before canceling delayed quorum work and
+ * destroying the work queue.
+ */
+static struct workqueue_struct *o2net_wq;
+static struct work_struct o2net_listen_work;
+
+static struct o2hb_callback_func o2net_hb_up, o2net_hb_down;
+#define O2NET_HB_PRI 0x1
+
+static struct o2net_handshake *o2net_hand;
+static struct o2net_msg *o2net_keep_req, *o2net_keep_resp;
+
+static int o2net_sys_err_translations[O2NET_ERR_MAX] =
+		{[O2NET_ERR_NONE]	= 0,
+		 [O2NET_ERR_NO_HNDLR]	= -ENOPROTOOPT,
+		 [O2NET_ERR_OVERFLOW]	= -EOVERFLOW,
+		 [O2NET_ERR_DIED]	= -EHOSTDOWN,};
+
+/* can't quite avoid *all* internal declarations :/ */
+static void o2net_sc_connect_completed(void *arg);
+static void o2net_rx_until_empty(void *arg);
+static void o2net_shutdown_sc(void *arg);
+static void o2net_listen_data_ready(struct sock *sk, int bytes);
+static void o2net_sc_send_keep_req(void *arg);
+static void o2net_idle_timer(unsigned long data);
+static void o2net_sc_postpone_idle(struct o2net_sock_container *sc);
+
+static inline int o2net_sys_err_to_errno(enum o2net_system_error err)
+{
+	int trans;
+	BUG_ON(err >= O2NET_ERR_MAX);
+	trans = o2net_sys_err_translations[err];
+
+	/* Just in case we mess up the translation table above */
+	BUG_ON(err != O2NET_ERR_NONE && trans == 0);
+	return trans;
+}
+
+static struct o2net_node * o2net_nn_from_num(u8 node_num)
+{
+	BUG_ON(node_num >= ARRAY_SIZE(o2net_nodes));
+	return &o2net_nodes[node_num];
+}
+
+static u8 o2net_num_from_nn(struct o2net_node *nn)
+{
+	BUG_ON(nn == NULL);
+	return nn - o2net_nodes;
+}
+
+/* ------------------------------------------------------------ */
+
+static int o2net_prep_nsw(struct o2net_node *nn, struct o2net_status_wait *nsw)
+{
+	int ret = 0;
+
+	do {
+		if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) {
+			ret = -EAGAIN;
+			break;
+		}
+		spin_lock(&nn->nn_lock);
+		ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id);
+		if (ret == 0)
+			list_add_tail(&nsw->ns_node_item,
+				      &nn->nn_status_list);
+		spin_unlock(&nn->nn_lock);
+	} while (ret == -EAGAIN);
+
+	if (ret == 0)  {
+		init_waitqueue_head(&nsw->ns_wq);
+		nsw->ns_sys_status = O2NET_ERR_NONE;
+		nsw->ns_status = 0;
+	}
+
+	return ret;
+}
+
+static void o2net_complete_nsw_locked(struct o2net_node *nn,
+				      struct o2net_status_wait *nsw,
+				      enum o2net_system_error sys_status,
+				      s32 status)
+{
+	assert_spin_locked(&nn->nn_lock);
+
+	if (!list_empty(&nsw->ns_node_item)) {
+		list_del_init(&nsw->ns_node_item);
+		nsw->ns_sys_status = sys_status;
+		nsw->ns_status = status;
+		idr_remove(&nn->nn_status_idr, nsw->ns_id);
+		wake_up(&nsw->ns_wq);
+	}
+}
+
+static void o2net_complete_nsw(struct o2net_node *nn,
+			       struct o2net_status_wait *nsw,
+			       u64 id, enum o2net_system_error sys_status,
+			       s32 status)
+{
+	spin_lock(&nn->nn_lock);
+	if (nsw == NULL) {
+		if (id > INT_MAX)
+			goto out;
+
+		nsw = idr_find(&nn->nn_status_idr, id);
+		if (nsw == NULL)
+			goto out;
+	}
+
+	o2net_complete_nsw_locked(nn, nsw, sys_status, status);
+
+out:
+	spin_unlock(&nn->nn_lock);
+	return;
+}
+
+static void o2net_complete_nodes_nsw(struct o2net_node *nn)
+{
+	struct list_head *iter, *tmp;
+	unsigned int num_kills = 0;
+	struct o2net_status_wait *nsw;
+
+	assert_spin_locked(&nn->nn_lock);
+
+	list_for_each_safe(iter, tmp, &nn->nn_status_list) {
+		nsw = list_entry(iter, struct o2net_status_wait, ns_node_item);
+		o2net_complete_nsw_locked(nn, nsw, O2NET_ERR_DIED, 0);
+		num_kills++;
+	}
+
+	mlog(0, "completed %d messages for node %u\n", num_kills,
+	     o2net_num_from_nn(nn));
+}
+
+static int o2net_nsw_completed(struct o2net_node *nn,
+			       struct o2net_status_wait *nsw)
+{
+	int completed;
+	spin_lock(&nn->nn_lock);
+	completed = list_empty(&nsw->ns_node_item);
+	spin_unlock(&nn->nn_lock);
+	return completed;
+}
+
+/* ------------------------------------------------------------ */
+
+static void sc_kref_release(struct kref *kref)
+{
+	struct o2net_sock_container *sc = container_of(kref,
+					struct o2net_sock_container, sc_kref);
+	sclog(sc, "releasing\n");
+
+	if (sc->sc_sock) {
+		sock_release(sc->sc_sock);
+		sc->sc_sock = NULL;
+	}
+
+	o2nm_node_put(sc->sc_node);
+	sc->sc_node = NULL;
+
+	kfree(sc);
+}
+
+static void sc_put(struct o2net_sock_container *sc)
+{
+	sclog(sc, "put\n");
+	kref_put(&sc->sc_kref, sc_kref_release);
+}
+static void sc_get(struct o2net_sock_container *sc)
+{
+	sclog(sc, "get\n");
+	kref_get(&sc->sc_kref);
+}
+static struct o2net_sock_container *sc_alloc(struct o2nm_node *node)
+{
+	struct o2net_sock_container *sc, *ret = NULL;
+	struct page *page = NULL;
+
+	page = alloc_page(GFP_NOFS);
+	sc = kcalloc(1, sizeof(*sc), GFP_NOFS);
+	if (sc == NULL || page == NULL)
+		goto out;
+
+	kref_init(&sc->sc_kref);
+	o2nm_node_get(node);
+	sc->sc_node = node;
+
+	INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed, sc);
+	INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty, sc);
+	INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc, sc);
+	INIT_WORK(&sc->sc_keepalive_work, o2net_sc_send_keep_req, sc);
+
+	init_timer(&sc->sc_idle_timeout);
+	sc->sc_idle_timeout.function = o2net_idle_timer;
+	sc->sc_idle_timeout.data = (unsigned long)sc;
+
+	sclog(sc, "alloced\n");
+
+	ret = sc;
+	sc->sc_page = page;
+	sc = NULL;
+	page = NULL;
+
+out:
+	if (page)
+		__free_page(page);
+	kfree(sc);
+
+	return ret;
+}
+
+/* ------------------------------------------------------------ */
+
+static void o2net_sc_queue_work(struct o2net_sock_container *sc,
+				struct work_struct *work)
+{
+	sc_get(sc);
+	if (!queue_work(o2net_wq, work))
+		sc_put(sc);
+}
+static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc,
+					struct work_struct *work,
+					int delay)
+{
+	sc_get(sc);
+	if (!queue_delayed_work(o2net_wq, work, delay))
+		sc_put(sc);
+}
+static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc,
+					 struct work_struct *work)
+{
+	if (cancel_delayed_work(work))
+		sc_put(sc);
+}
+
+static void o2net_set_nn_state(struct o2net_node *nn,
+			       struct o2net_sock_container *sc,
+			       unsigned valid, int err)
+{
+	int was_valid = nn->nn_sc_valid;
+	int was_err = nn->nn_persistent_error;
+	struct o2net_sock_container *old_sc = nn->nn_sc;
+
+	assert_spin_locked(&nn->nn_lock);
+
+	/* the node num comparison and single connect/accept path should stop
+	 * an non-null sc from being overwritten with another */
+	BUG_ON(sc && nn->nn_sc && nn->nn_sc != sc);
+	mlog_bug_on_msg(err && valid, "err %d valid %u\n", err, valid);
+	mlog_bug_on_msg(valid && !sc, "valid %u sc %p\n", valid, sc);
+
+	/* we won't reconnect after our valid conn goes away for
+	 * this hb iteration.. here so it shows up in the logs */
+	if (was_valid && !valid && err == 0)
+		err = -ENOTCONN;
+
+	mlog(ML_CONN, "node %u sc: %p -> %p, valid %u -> %u, err %d -> %d\n",
+	     o2net_num_from_nn(nn), nn->nn_sc, sc, nn->nn_sc_valid, valid,
+	     nn->nn_persistent_error, err);
+
+	nn->nn_sc = sc;
+	nn->nn_sc_valid = valid ? 1 : 0;
+	nn->nn_persistent_error = err;
+
+	/* mirrors o2net_tx_can_proceed() */
+	if (nn->nn_persistent_error || nn->nn_sc_valid)
+		wake_up(&nn->nn_sc_wq);
+
+	if (!was_err && nn->nn_persistent_error) {
+		o2quo_conn_err(o2net_num_from_nn(nn));
+		queue_delayed_work(o2net_wq, &nn->nn_still_up,
+				   msecs_to_jiffies(O2NET_QUORUM_DELAY_MS));
+	}
+
+	if (was_valid && !valid) {
+		mlog(ML_NOTICE, "no longer connected to " SC_NODEF_FMT "\n",
+		     SC_NODEF_ARGS(old_sc));
+		o2net_complete_nodes_nsw(nn);
+	}
+
+	if (!was_valid && valid) {
+		o2quo_conn_up(o2net_num_from_nn(nn));
+		/* this is a bit of a hack.  we only try reconnecting
+		 * when heartbeating starts until we get a connection.
+		 * if that connection then dies we don't try reconnecting.
+		 * the only way to start connecting again is to down
+		 * heartbeat and bring it back up. */
+		cancel_delayed_work(&nn->nn_connect_expired);
+		mlog(ML_NOTICE, "%s " SC_NODEF_FMT "\n", 
+		     o2nm_this_node() > sc->sc_node->nd_num ?
+		     	"connected to" : "accepted connection from",
+		     SC_NODEF_ARGS(sc));
+	}
+
+	/* trigger the connecting worker func as long as we're not valid,
+	 * it will back off if it shouldn't connect.  This can be called
+	 * from node config teardown and so needs to be careful about
+	 * the work queue actually being up. */
+	if (!valid && o2net_wq) {
+		unsigned long delay;
+		/* delay if we're withing a RECONNECT_DELAY of the
+		 * last attempt */
+		delay = (nn->nn_last_connect_attempt +
+			 msecs_to_jiffies(O2NET_RECONNECT_DELAY_MS))
+			- jiffies;
+		if (delay > msecs_to_jiffies(O2NET_RECONNECT_DELAY_MS))
+			delay = 0;
+		mlog(ML_CONN, "queueing conn attempt in %lu jiffies\n", delay);
+		queue_delayed_work(o2net_wq, &nn->nn_connect_work, delay);
+	}
+
+	/* keep track of the nn's sc ref for the caller */
+	if ((old_sc == NULL) && sc)
+		sc_get(sc);
+	if (old_sc && (old_sc != sc)) {
+		o2net_sc_queue_work(old_sc, &old_sc->sc_shutdown_work);
+		sc_put(old_sc);
+	}
+}
+
+/* see o2net_register_callbacks() */
+static void o2net_data_ready(struct sock *sk, int bytes)
+{
+	void (*ready)(struct sock *sk, int bytes);
+
+	read_lock(&sk->sk_callback_lock);
+	if (sk->sk_user_data) {
+		struct o2net_sock_container *sc = sk->sk_user_data;
+		sclog(sc, "data_ready hit\n");
+		do_gettimeofday(&sc->sc_tv_data_ready);
+		o2net_sc_queue_work(sc, &sc->sc_rx_work);
+		ready = sc->sc_data_ready;
+	} else {
+		ready = sk->sk_data_ready;
+	}
+	read_unlock(&sk->sk_callback_lock);
+
+	ready(sk, bytes);
+}
+
+/* see o2net_register_callbacks() */
+static void o2net_state_change(struct sock *sk)
+{
+	void (*state_change)(struct sock *sk);
+	struct o2net_sock_container *sc;
+
+	read_lock(&sk->sk_callback_lock);
+	sc = sk->sk_user_data;
+	if (sc == NULL) {
+		state_change = sk->sk_state_change;
+		goto out;
+	}
+
+	sclog(sc, "state_change to %d\n", sk->sk_state);
+
+	state_change = sc->sc_state_change;
+
+	switch(sk->sk_state) {
+		/* ignore connecting sockets as they make progress */
+		case TCP_SYN_SENT:
+		case TCP_SYN_RECV:
+			break;
+		case TCP_ESTABLISHED:
+			o2net_sc_queue_work(sc, &sc->sc_connect_work);
+			break;
+		default:
+			o2net_sc_queue_work(sc, &sc->sc_shutdown_work);
+			break;
+	}
+out:
+	read_unlock(&sk->sk_callback_lock);
+	state_change(sk);
+}
+
+/*
+ * we register callbacks so we can queue work on events before calling
+ * the original callbacks.  our callbacks our careful to test user_data
+ * to discover when they've reaced with o2net_unregister_callbacks().
+ */
+static void o2net_register_callbacks(struct sock *sk,
+				     struct o2net_sock_container *sc)
+{
+	write_lock_bh(&sk->sk_callback_lock);
+
+	/* accepted sockets inherit the old listen socket data ready */
+	if (sk->sk_data_ready == o2net_listen_data_ready) {
+		sk->sk_data_ready = sk->sk_user_data;
+		sk->sk_user_data = NULL;
+	}
+
+	BUG_ON(sk->sk_user_data != NULL);
+	sk->sk_user_data = sc;
+	sc_get(sc);
+
+	sc->sc_data_ready = sk->sk_data_ready;
+	sc->sc_state_change = sk->sk_state_change;
+	sk->sk_data_ready = o2net_data_ready;
+	sk->sk_state_change = o2net_state_change;
+
+	write_unlock_bh(&sk->sk_callback_lock);
+}
+
+static int o2net_unregister_callbacks(struct sock *sk,
+			           struct o2net_sock_container *sc)
+{
+	int ret = 0;
+
+	write_lock_bh(&sk->sk_callback_lock);
+	if (sk->sk_user_data == sc) {
+		ret = 1;
+		sk->sk_user_data = NULL;
+		sk->sk_data_ready = sc->sc_data_ready;
+		sk->sk_state_change = sc->sc_state_change;
+	}
+	write_unlock_bh(&sk->sk_callback_lock);
+
+	return ret;
+}
+
+/*
+ * this is a little helper that is called by callers who have seen a problem
+ * with an sc and want to detach it from the nn if someone already hasn't beat
+ * them to it.  if an error is given then the shutdown will be persistent
+ * and pending transmits will be canceled.
+ */
+static void o2net_ensure_shutdown(struct o2net_node *nn,
+			           struct o2net_sock_container *sc,
+				   int err)
+{
+	spin_lock(&nn->nn_lock);
+	if (nn->nn_sc == sc)
+		o2net_set_nn_state(nn, NULL, 0, err);
+	spin_unlock(&nn->nn_lock);
+}
+
+/*
+ * This work queue function performs the blocking parts of socket shutdown.  A
+ * few paths lead here.  set_nn_state will trigger this callback if it sees an
+ * sc detached from the nn.  state_change will also trigger this callback
+ * directly when it sees errors.  In that case we need to call set_nn_state
+ * ourselves as state_change couldn't get the nn_lock and call set_nn_state
+ * itself.
+ */
+static void o2net_shutdown_sc(void *arg)
+{
+	struct o2net_sock_container *sc = arg;
+	struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
+
+	sclog(sc, "shutting down\n");
+
+	/* drop the callbacks ref and call shutdown only once */
+	if (o2net_unregister_callbacks(sc->sc_sock->sk, sc)) {
+		/* we shouldn't flush as we're in the thread, the
+		 * races with pending sc work structs are harmless */
+		del_timer_sync(&sc->sc_idle_timeout);
+		o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work);
+		sc_put(sc);
+		sc->sc_sock->ops->shutdown(sc->sc_sock,
+					   RCV_SHUTDOWN|SEND_SHUTDOWN);
+	}
+
+	/* not fatal so failed connects before the other guy has our
+	 * heartbeat can be retried */
+	o2net_ensure_shutdown(nn, sc, 0);
+	sc_put(sc);
+}
+
+/* ------------------------------------------------------------ */
+
+static int o2net_handler_cmp(struct o2net_msg_handler *nmh, u32 msg_type,
+			     u32 key)
+{
+	int ret = memcmp(&nmh->nh_key, &key, sizeof(key));
+
+	if (ret == 0)
+		ret = memcmp(&nmh->nh_msg_type, &msg_type, sizeof(msg_type));
+
+	return ret;
+}
+
+static struct o2net_msg_handler *
+o2net_handler_tree_lookup(u32 msg_type, u32 key, struct rb_node ***ret_p,
+			  struct rb_node **ret_parent)
+{
+        struct rb_node **p = &o2net_handler_tree.rb_node;
+        struct rb_node *parent = NULL;
+	struct o2net_msg_handler *nmh, *ret = NULL;
+	int cmp;
+
+        while (*p) {
+                parent = *p;
+                nmh = rb_entry(parent, struct o2net_msg_handler, nh_node);
+		cmp = o2net_handler_cmp(nmh, msg_type, key);
+
+                if (cmp < 0)
+                        p = &(*p)->rb_left;
+                else if (cmp > 0)
+                        p = &(*p)->rb_right;
+                else {
+			ret = nmh;
+                        break;
+		}
+        }
+
+        if (ret_p != NULL)
+                *ret_p = p;
+        if (ret_parent != NULL)
+                *ret_parent = parent;
+
+        return ret;
+}
+
+static void o2net_handler_kref_release(struct kref *kref)
+{
+	struct o2net_msg_handler *nmh;
+	nmh = container_of(kref, struct o2net_msg_handler, nh_kref);
+
+	kfree(nmh);
+}
+
+static void o2net_handler_put(struct o2net_msg_handler *nmh)
+{
+	kref_put(&nmh->nh_kref, o2net_handler_kref_release);
+}
+
+/* max_len is protection for the handler func.  incoming messages won't
+ * be given to the handler if their payload is longer than the max. */
+int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
+			   o2net_msg_handler_func *func, void *data,
+			   struct list_head *unreg_list)
+{
+	struct o2net_msg_handler *nmh = NULL;
+	struct rb_node **p, *parent;
+	int ret = 0;
+
+	if (max_len > O2NET_MAX_PAYLOAD_BYTES) {
+		mlog(0, "max_len for message handler out of range: %u\n",
+			max_len);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!msg_type) {
+		mlog(0, "no message type provided: %u, %p\n", msg_type, func);
+		ret = -EINVAL;
+		goto out;
+
+	}
+	if (!func) {
+		mlog(0, "no message handler provided: %u, %p\n",
+		       msg_type, func);
+		ret = -EINVAL;
+		goto out;
+	}
+
+       	nmh = kcalloc(1, sizeof(struct o2net_msg_handler), GFP_NOFS);
+	if (nmh == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	nmh->nh_func = func;
+	nmh->nh_func_data = data;
+	nmh->nh_msg_type = msg_type;
+	nmh->nh_max_len = max_len;
+	nmh->nh_key = key;
+	/* the tree and list get this ref.. they're both removed in
+	 * unregister when this ref is dropped */
+	kref_init(&nmh->nh_kref);
+	INIT_LIST_HEAD(&nmh->nh_unregister_item);
+
+	write_lock(&o2net_handler_lock);
+	if (o2net_handler_tree_lookup(msg_type, key, &p, &parent))
+		ret = -EEXIST;
+	else {
+	        rb_link_node(&nmh->nh_node, parent, p);
+		rb_insert_color(&nmh->nh_node, &o2net_handler_tree);
+		list_add_tail(&nmh->nh_unregister_item, unreg_list);
+
+		mlog(ML_TCP, "registered handler func %p type %u key %08x\n",
+		     func, msg_type, key);
+		/* we've had some trouble with handlers seemingly vanishing. */
+		mlog_bug_on_msg(o2net_handler_tree_lookup(msg_type, key, &p,
+							  &parent) == NULL,
+			        "couldn't find handler we *just* registerd "
+				"for type %u key %08x\n", msg_type, key);
+	}
+	write_unlock(&o2net_handler_lock);
+	if (ret)
+		goto out;
+
+out:
+	if (ret)
+		kfree(nmh);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(o2net_register_handler);
+
+void o2net_unregister_handler_list(struct list_head *list)
+{
+	struct list_head *pos, *n;
+	struct o2net_msg_handler *nmh;
+
+	write_lock(&o2net_handler_lock);
+	list_for_each_safe(pos, n, list) {
+		nmh = list_entry(pos, struct o2net_msg_handler,
+				 nh_unregister_item);
+		mlog(ML_TCP, "unregistering handler func %p type %u key %08x\n",
+		     nmh->nh_func, nmh->nh_msg_type, nmh->nh_key);
+		rb_erase(&nmh->nh_node, &o2net_handler_tree);
+		list_del_init(&nmh->nh_unregister_item);
+		kref_put(&nmh->nh_kref, o2net_handler_kref_release);
+	}
+	write_unlock(&o2net_handler_lock);
+}
+EXPORT_SYMBOL_GPL(o2net_unregister_handler_list);
+
+static struct o2net_msg_handler *o2net_handler_get(u32 msg_type, u32 key)
+{
+	struct o2net_msg_handler *nmh;
+
+	read_lock(&o2net_handler_lock);
+	nmh = o2net_handler_tree_lookup(msg_type, key, NULL, NULL);
+	if (nmh)
+		kref_get(&nmh->nh_kref);
+	read_unlock(&o2net_handler_lock);
+
+	return nmh;
+}
+
+/* ------------------------------------------------------------ */
+
+static int o2net_recv_tcp_msg(struct socket *sock, void *data, size_t len)
+{
+	int ret;
+	mm_segment_t oldfs;
+	struct kvec vec = {
+		.iov_len = len,
+		.iov_base = data,
+	};
+	struct msghdr msg = {
+		.msg_iovlen = 1,
+		.msg_iov = (struct iovec *)&vec,
+       		.msg_flags = MSG_DONTWAIT,
+	};
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+	ret = sock_recvmsg(sock, &msg, len, msg.msg_flags);
+	set_fs(oldfs);
+
+	return ret;
+}
+
+static int o2net_send_tcp_msg(struct socket *sock, struct kvec *vec,
+			      size_t veclen, size_t total)
+{
+	int ret;
+	mm_segment_t oldfs;
+	struct msghdr msg = {
+		.msg_iov = (struct iovec *)vec,
+		.msg_iovlen = veclen,
+	};
+
+	if (sock == NULL) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	oldfs = get_fs();
+	set_fs(get_ds());
+	ret = sock_sendmsg(sock, &msg, total);
+	set_fs(oldfs);
+	if (ret != total) {
+		mlog(ML_ERROR, "sendmsg returned %d instead of %zu\n", ret,
+		     total);
+		if (ret >= 0)
+			ret = -EPIPE; /* should be smarter, I bet */
+		goto out;
+	}
+
+	ret = 0;
+out:
+	if (ret < 0)
+		mlog(0, "returning error: %d\n", ret);
+	return ret;
+}
+
+static void o2net_sendpage(struct o2net_sock_container *sc,
+			   void *kmalloced_virt,
+			   size_t size)
+{
+	struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
+	ssize_t ret;
+
+
+	ret = sc->sc_sock->ops->sendpage(sc->sc_sock,
+					 virt_to_page(kmalloced_virt),
+					 (long)kmalloced_virt & ~PAGE_MASK,
+					 size, MSG_DONTWAIT);
+	if (ret != size) {
+		mlog(ML_ERROR, "sendpage of size %zu to " SC_NODEF_FMT 
+		     " failed with %zd\n", size, SC_NODEF_ARGS(sc), ret);
+		o2net_ensure_shutdown(nn, sc, 0);
+	}
+}
+
+static void o2net_init_msg(struct o2net_msg *msg, u16 data_len, u16 msg_type, u32 key)
+{
+	memset(msg, 0, sizeof(struct o2net_msg));
+	msg->magic = cpu_to_be16(O2NET_MSG_MAGIC);
+	msg->data_len = cpu_to_be16(data_len);
+	msg->msg_type = cpu_to_be16(msg_type);
+	msg->sys_status = cpu_to_be32(O2NET_ERR_NONE);
+	msg->status = 0;
+	msg->key = cpu_to_be32(key);
+}
+
+static int o2net_tx_can_proceed(struct o2net_node *nn,
+			        struct o2net_sock_container **sc_ret,
+				int *error)
+{
+	int ret = 0;
+
+	spin_lock(&nn->nn_lock);
+	if (nn->nn_persistent_error) {
+		ret = 1;
+		*sc_ret = NULL;
+		*error = nn->nn_persistent_error;
+	} else if (nn->nn_sc_valid) {
+		kref_get(&nn->nn_sc->sc_kref);
+
+		ret = 1;
+		*sc_ret = nn->nn_sc;
+		*error = 0;
+	}
+	spin_unlock(&nn->nn_lock);
+
+	return ret;
+}
+
+int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec,
+			   size_t caller_veclen, u8 target_node, int *status)
+{
+	int ret, error = 0;
+	struct o2net_msg *msg = NULL;
+	size_t veclen, caller_bytes = 0;
+	struct kvec *vec = NULL;
+	struct o2net_sock_container *sc = NULL;
+	struct o2net_node *nn = o2net_nn_from_num(target_node);
+	struct o2net_status_wait nsw = {
+		.ns_node_item = LIST_HEAD_INIT(nsw.ns_node_item),
+	};
+
+	if (o2net_wq == NULL) {
+		mlog(0, "attempt to tx without o2netd running\n");
+		ret = -ESRCH;
+		goto out;
+	}
+
+	if (caller_veclen == 0) {
+		mlog(0, "bad kvec array length\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	caller_bytes = iov_length((struct iovec *)caller_vec, caller_veclen);
+	if (caller_bytes > O2NET_MAX_PAYLOAD_BYTES) {
+		mlog(0, "total payload len %zu too large\n", caller_bytes);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (target_node == o2nm_this_node()) {
+		ret = -ELOOP;
+		goto out;
+	}
+
+	ret = wait_event_interruptible(nn->nn_sc_wq,
+				       o2net_tx_can_proceed(nn, &sc, &error));
+	if (!ret && error)
+		ret = error;
+	if (ret)
+		goto out;
+
+	veclen = caller_veclen + 1;
+	vec = kmalloc(sizeof(struct kvec) * veclen, GFP_ATOMIC);
+	if (vec == NULL) {
+		mlog(0, "failed to %zu element kvec!\n", veclen);
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	msg = kmalloc(sizeof(struct o2net_msg), GFP_ATOMIC);
+	if (!msg) {
+		mlog(0, "failed to allocate a o2net_msg!\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	o2net_init_msg(msg, caller_bytes, msg_type, key);
+
+	vec[0].iov_len = sizeof(struct o2net_msg);
+	vec[0].iov_base = msg;
+	memcpy(&vec[1], caller_vec, caller_veclen * sizeof(struct kvec));
+
+	ret = o2net_prep_nsw(nn, &nsw);
+	if (ret)
+		goto out;
+
+	msg->msg_num = cpu_to_be32(nsw.ns_id);
+
+	/* finally, convert the message header to network byte-order
+	 * and send */
+	ret = o2net_send_tcp_msg(sc->sc_sock, vec, veclen,
+				 sizeof(struct o2net_msg) + caller_bytes);
+	msglog(msg, "sending returned %d\n", ret);
+	if (ret < 0) {
+		mlog(0, "error returned from o2net_send_tcp_msg=%d\n", ret);
+		goto out;
+	}
+
+	/* wait on other node's handler */
+	wait_event(nsw.ns_wq, o2net_nsw_completed(nn, &nsw));
+
+	/* Note that we avoid overwriting the callers status return
+	 * variable if a system error was reported on the other
+	 * side. Callers beware. */
+	ret = o2net_sys_err_to_errno(nsw.ns_sys_status);
+	if (status && !ret)
+		*status = nsw.ns_status;
+
+	mlog(0, "woken, returning system status %d, user status %d\n",
+	     ret, nsw.ns_status);
+out:
+	if (sc)
+		sc_put(sc);
+	if (vec)
+		kfree(vec);
+	if (msg)
+		kfree(msg);
+	o2net_complete_nsw(nn, &nsw, 0, 0, 0);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(o2net_send_message_vec);
+
+int o2net_send_message(u32 msg_type, u32 key, void *data, u32 len,
+		       u8 target_node, int *status)
+{
+	struct kvec vec = {
+		.iov_base = data,
+		.iov_len = len,
+	};
+	return o2net_send_message_vec(msg_type, key, &vec, 1,
+				      target_node, status);
+}
+EXPORT_SYMBOL_GPL(o2net_send_message);
+
+static int o2net_send_status_magic(struct socket *sock, struct o2net_msg *hdr,
+				   enum o2net_system_error syserr, int err)
+{
+	struct kvec vec = {
+		.iov_base = hdr,
+		.iov_len = sizeof(struct o2net_msg),
+	};
+
+	BUG_ON(syserr >= O2NET_ERR_MAX);
+
+	/* leave other fields intact from the incoming message, msg_num
+	 * in particular */
+	hdr->sys_status = cpu_to_be32(syserr);
+	hdr->status = cpu_to_be32(err);
+	hdr->magic = cpu_to_be16(O2NET_MSG_STATUS_MAGIC);  // twiddle the magic
+	hdr->data_len = 0;
+
+	msglog(hdr, "about to send status magic %d\n", err);
+	/* hdr has been in host byteorder this whole time */
+	return o2net_send_tcp_msg(sock, &vec, 1, sizeof(struct o2net_msg));
+}
+
+/* this returns -errno if the header was unknown or too large, etc.
+ * after this is called the buffer us reused for the next message */
+static int o2net_process_message(struct o2net_sock_container *sc,
+				 struct o2net_msg *hdr)
+{
+	struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
+	int ret = 0, handler_status;
+	enum  o2net_system_error syserr;
+	struct o2net_msg_handler *nmh = NULL;
+
+	msglog(hdr, "processing message\n");
+
+	o2net_sc_postpone_idle(sc);
+
+	switch(be16_to_cpu(hdr->magic)) {
+		case O2NET_MSG_STATUS_MAGIC:
+			/* special type for returning message status */
+			o2net_complete_nsw(nn, NULL,
+					   be32_to_cpu(hdr->msg_num),
+					   be32_to_cpu(hdr->sys_status),
+					   be32_to_cpu(hdr->status));
+			goto out;
+		case O2NET_MSG_KEEP_REQ_MAGIC:
+			o2net_sendpage(sc, o2net_keep_resp,
+				       sizeof(*o2net_keep_resp));
+			goto out;
+		case O2NET_MSG_KEEP_RESP_MAGIC:
+			goto out;
+		case O2NET_MSG_MAGIC:
+			break;
+		default:
+			msglog(hdr, "bad magic\n");
+			ret = -EINVAL;
+			goto out;
+			break;
+	}
+
+	/* find a handler for it */
+	handler_status = 0;
+	nmh = o2net_handler_get(be16_to_cpu(hdr->msg_type),
+				be32_to_cpu(hdr->key));
+	if (!nmh) {
+		mlog(ML_TCP, "couldn't find handler for type %u key %08x\n",
+		     be16_to_cpu(hdr->msg_type), be32_to_cpu(hdr->key));
+		syserr = O2NET_ERR_NO_HNDLR;
+		goto out_respond;
+	}
+
+	syserr = O2NET_ERR_NONE;
+
+	if (be16_to_cpu(hdr->data_len) > nmh->nh_max_len)
+		syserr = O2NET_ERR_OVERFLOW;
+
+	if (syserr != O2NET_ERR_NONE)
+		goto out_respond;
+
+	do_gettimeofday(&sc->sc_tv_func_start);
+	sc->sc_msg_key = be32_to_cpu(hdr->key);
+	sc->sc_msg_type = be16_to_cpu(hdr->msg_type);
+	handler_status = (nmh->nh_func)(hdr, sizeof(struct o2net_msg) +
+					     be16_to_cpu(hdr->data_len),
+					nmh->nh_func_data);
+	do_gettimeofday(&sc->sc_tv_func_stop);
+
+out_respond:
+	/* this destroys the hdr, so don't use it after this */
+	ret = o2net_send_status_magic(sc->sc_sock, hdr, syserr,
+				      handler_status);
+	hdr = NULL;
+	mlog(0, "sending handler status %d, syserr %d returned %d\n",
+	     handler_status, syserr, ret);
+
+out:
+	if (nmh)
+		o2net_handler_put(nmh);
+	return ret;
+}
+
+static int o2net_check_handshake(struct o2net_sock_container *sc)
+{
+	struct o2net_handshake *hand = page_address(sc->sc_page);
+	struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
+
+	if (hand->protocol_version != cpu_to_be64(O2NET_PROTOCOL_VERSION)) {
+		mlog(ML_NOTICE, SC_NODEF_FMT " advertised net protocol "
+		     "version %llu but %llu is required, disconnecting\n",
+		     SC_NODEF_ARGS(sc),
+		     (unsigned long long)be64_to_cpu(hand->protocol_version),
+		     O2NET_PROTOCOL_VERSION);
+
+		/* don't bother reconnecting if its the wrong version. */
+		o2net_ensure_shutdown(nn, sc, -ENOTCONN);
+		return -1;
+	}
+
+	sc->sc_handshake_ok = 1;
+
+	spin_lock(&nn->nn_lock);
+	/* set valid and queue the idle timers only if it hasn't been
+	 * shut down already */
+	if (nn->nn_sc == sc) {
+		o2net_sc_postpone_idle(sc);
+		o2net_set_nn_state(nn, sc, 1, 0);
+	}
+	spin_unlock(&nn->nn_lock);
+
+	/* shift everything up as though it wasn't there */
+	sc->sc_page_off -= sizeof(struct o2net_handshake);
+	if (sc->sc_page_off)
+		memmove(hand, hand + 1, sc->sc_page_off);
+
+	return 0;
+}
+
+/* this demuxes the queued rx bytes into header or payload bits and calls
+ * handlers as each full message is read off the socket.  it returns -error,
+ * == 0 eof, or > 0 for progress made.*/
+static int o2net_advance_rx(struct o2net_sock_container *sc)
+{
+	struct o2net_msg *hdr;
+	int ret = 0;
+	void *data;
+	size_t datalen;
+
+	sclog(sc, "receiving\n");
+	do_gettimeofday(&sc->sc_tv_advance_start);
+
+	/* do we need more header? */
+	if (sc->sc_page_off < sizeof(struct o2net_msg)) {
+		data = page_address(sc->sc_page) + sc->sc_page_off;
+		datalen = sizeof(struct o2net_msg) - sc->sc_page_off;
+		ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen);
+		if (ret > 0) {
+			sc->sc_page_off += ret;
+
+			/* this working relies on the handshake being
+			 * smaller than the normal message header */
+			if (sc->sc_page_off >= sizeof(struct o2net_handshake)&&
+			    !sc->sc_handshake_ok && o2net_check_handshake(sc)) {
+				ret = -EPROTO;
+				goto out;
+			}
+
+			/* only swab incoming here.. we can
+			 * only get here once as we cross from
+			 * being under to over */
+			if (sc->sc_page_off == sizeof(struct o2net_msg)) {
+				hdr = page_address(sc->sc_page);
+				if (be16_to_cpu(hdr->data_len) >
+				    O2NET_MAX_PAYLOAD_BYTES)
+					ret = -EOVERFLOW;
+			}
+		}
+		if (ret <= 0)
+			goto out;
+	}
+
+	if (sc->sc_page_off < sizeof(struct o2net_msg)) {
+		/* oof, still don't have a header */
+		goto out;
+	}
+
+	/* this was swabbed above when we first read it */
+	hdr = page_address(sc->sc_page);
+
+	msglog(hdr, "at page_off %zu\n", sc->sc_page_off);
+
+	/* do we need more payload? */
+	if (sc->sc_page_off - sizeof(struct o2net_msg) < be16_to_cpu(hdr->data_len)) {
+		/* need more payload */
+		data = page_address(sc->sc_page) + sc->sc_page_off;
+		datalen = (sizeof(struct o2net_msg) + be16_to_cpu(hdr->data_len)) -
+			  sc->sc_page_off;
+		ret = o2net_recv_tcp_msg(sc->sc_sock, data, datalen);
+		if (ret > 0)
+			sc->sc_page_off += ret;
+		if (ret <= 0)
+			goto out;
+	}
+
+	if (sc->sc_page_off - sizeof(struct o2net_msg) == be16_to_cpu(hdr->data_len)) {
+		/* we can only get here once, the first time we read
+		 * the payload.. so set ret to progress if the handler
+		 * works out. after calling this the message is toast */
+		ret = o2net_process_message(sc, hdr);
+		if (ret == 0)
+			ret = 1;
+		sc->sc_page_off = 0;
+	}
+
+out:
+	sclog(sc, "ret = %d\n", ret);
+	do_gettimeofday(&sc->sc_tv_advance_stop);
+	return ret;
+}
+
+/* this work func is triggerd by data ready.  it reads until it can read no
+ * more.  it interprets 0, eof, as fatal.  if data_ready hits while we're doing
+ * our work the work struct will be marked and we'll be called again. */
+static void o2net_rx_until_empty(void *arg)
+{
+	struct o2net_sock_container *sc = arg;
+	int ret;
+
+	do {
+		ret = o2net_advance_rx(sc);
+	} while (ret > 0);
+
+	if (ret <= 0 && ret != -EAGAIN) {
+		struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num);
+		sclog(sc, "saw error %d, closing\n", ret);
+		/* not permanent so read failed handshake can retry */
+		o2net_ensure_shutdown(nn, sc, 0);
+	}
+
+	sc_put(sc);
+}
+
+static int o2net_set_nodelay(struct socket *sock)
+{
+	int ret, val = 1;
+	mm_segment_t oldfs;
+
+	oldfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	/*
+	 * Dear unsuspecting programmer,
+	 *
+	 * Don't use sock_setsockopt() for SOL_TCP.  It doesn't check its level
+	 * argument and assumes SOL_SOCKET so, say, your TCP_NODELAY will
+	 * silently turn into SO_DEBUG.
+	 *
+	 * Yours,
+	 * Keeper of hilariously fragile interfaces.
+	 */
+	ret = sock->ops->setsockopt(sock, SOL_TCP, TCP_NODELAY,
+				    (char __user *)&val, sizeof(val));
+
+	set_fs(oldfs);
+	return ret;
+}
+
+/* ------------------------------------------------------------ */
+
+/* called when a connect completes and after a sock is accepted.  the
+ * rx path will see the response and mark the sc valid */
+static void o2net_sc_connect_completed(void *arg)
+{
+	struct o2net_sock_container *sc = arg;
+
+	mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n",
+              (unsigned long long)O2NET_PROTOCOL_VERSION,
+	      (unsigned long long)be64_to_cpu(o2net_hand->connector_id));
+
+	o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand));
+	sc_put(sc);
+}
+
+/* this is called as a work_struct func. */
+static void o2net_sc_send_keep_req(void *arg)
+{
+	struct o2net_sock_container *sc = arg;
+
+	o2net_sendpage(sc, o2net_keep_req, sizeof(*o2net_keep_req));
+	sc_put(sc);
+}
+
+/* socket shutdown does a del_timer_sync against this as it tears down.
+ * we can't start this timer until we've got to the point in sc buildup
+ * where shutdown is going to be involved */
+static void o2net_idle_timer(unsigned long data)
+{
+	struct o2net_sock_container *sc = (struct o2net_sock_container *)data;
+	struct timeval now;
+
+	do_gettimeofday(&now);
+
+	mlog(ML_NOTICE, "connection to " SC_NODEF_FMT " has been idle for 10 "
+	     "seconds, shutting it down.\n", SC_NODEF_ARGS(sc));
+	mlog(ML_NOTICE, "here are some times that might help debug the "
+	     "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv "
+	     "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n",
+	     sc->sc_tv_timer.tv_sec, sc->sc_tv_timer.tv_usec, 
+	     now.tv_sec, now.tv_usec,
+	     sc->sc_tv_data_ready.tv_sec, sc->sc_tv_data_ready.tv_usec, 
+	     sc->sc_tv_advance_start.tv_sec, sc->sc_tv_advance_start.tv_usec, 
+	     sc->sc_tv_advance_stop.tv_sec, sc->sc_tv_advance_stop.tv_usec, 
+	     sc->sc_msg_key, sc->sc_msg_type,
+	     sc->sc_tv_func_start.tv_sec, sc->sc_tv_func_start.tv_usec,
+	     sc->sc_tv_func_stop.tv_sec, sc->sc_tv_func_stop.tv_usec);
+
+	o2net_sc_queue_work(sc, &sc->sc_shutdown_work);
+}
+
+static void o2net_sc_postpone_idle(struct o2net_sock_container *sc)
+{
+	o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work);
+	o2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work,
+				    O2NET_KEEPALIVE_DELAY_SECS * HZ);
+	do_gettimeofday(&sc->sc_tv_timer);
+	mod_timer(&sc->sc_idle_timeout,
+		  jiffies + (O2NET_IDLE_TIMEOUT_SECS * HZ));
+}
+
+/* this work func is kicked whenever a path sets the nn state which doesn't
+ * have valid set.  This includes seeing hb come up, losing a connection,
+ * having a connect attempt fail, etc. This centralizes the logic which decides
+ * if a connect attempt should be made or if we should give up and all future
+ * transmit attempts should fail */
+static void o2net_start_connect(void *arg)
+{
+	struct o2net_node *nn = arg;
+	struct o2net_sock_container *sc = NULL;
+	struct o2nm_node *node = NULL;
+	struct socket *sock = NULL;
+	struct sockaddr_in myaddr = {0, }, remoteaddr = {0, };
+	int ret = 0;
+
+	/* if we're greater we initiate tx, otherwise we accept */
+	if (o2nm_this_node() <= o2net_num_from_nn(nn))
+		goto out;
+
+	/* watch for racing with tearing a node down */
+	node = o2nm_get_node_by_num(o2net_num_from_nn(nn));
+	if (node == NULL) {
+		ret = 0;
+		goto out;
+	}
+
+	spin_lock(&nn->nn_lock);
+	/* see if we already have one pending or have given up */
+	if (nn->nn_sc || nn->nn_persistent_error)
+		arg = NULL;
+	spin_unlock(&nn->nn_lock);
+	if (arg == NULL) /* *shrug*, needed some indicator */
+		goto out;
+
+	nn->nn_last_connect_attempt = jiffies;
+
+	sc = sc_alloc(node);
+	if (sc == NULL) {
+		mlog(0, "couldn't allocate sc\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (ret < 0) {
+		mlog(0, "can't create socket: %d\n", ret);
+		goto out;
+	}
+	sc->sc_sock = sock; /* freed by sc_kref_release */
+
+	sock->sk->sk_allocation = GFP_ATOMIC;
+
+	myaddr.sin_family = AF_INET;
+	myaddr.sin_port = (__force u16)htons(0); /* any port */
+
+	ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr,
+			      sizeof(myaddr));
+	if (ret) {
+		mlog(0, "bind failed: %d\n", ret);
+		goto out;
+	}
+
+	ret = o2net_set_nodelay(sc->sc_sock);
+	if (ret) {
+		mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret);
+		goto out;
+	}
+
+	o2net_register_callbacks(sc->sc_sock->sk, sc);
+
+	spin_lock(&nn->nn_lock);
+	/* handshake completion will set nn->nn_sc_valid */
+	o2net_set_nn_state(nn, sc, 0, 0);
+	spin_unlock(&nn->nn_lock);
+
+	remoteaddr.sin_family = AF_INET;
+	remoteaddr.sin_addr.s_addr = (__force u32)node->nd_ipv4_address;
+	remoteaddr.sin_port = (__force u16)node->nd_ipv4_port;
+
+	ret = sc->sc_sock->ops->connect(sc->sc_sock,
+					(struct sockaddr *)&remoteaddr,
+					sizeof(remoteaddr),
+					O_NONBLOCK);
+	if (ret == -EINPROGRESS)
+		ret = 0;
+
+out:
+	if (ret) {
+		mlog(ML_NOTICE, "connect attempt to " SC_NODEF_FMT " failed "
+		     "with errno %d\n", SC_NODEF_ARGS(sc), ret);
+		/* 0 err so that another will be queued and attempted
+		 * from set_nn_state */
+		if (sc)
+			o2net_ensure_shutdown(nn, sc, 0);
+	}
+	if (sc)
+		sc_put(sc);
+	if (node)
+		o2nm_node_put(node);
+
+	return;
+}
+
+static void o2net_connect_expired(void *arg)
+{
+	struct o2net_node *nn = arg;
+
+	spin_lock(&nn->nn_lock);
+	if (!nn->nn_sc_valid) {
+		mlog(ML_ERROR, "no connection established with node %u after "
+		     "%u seconds, giving up and returning errors.\n",
+		     o2net_num_from_nn(nn), O2NET_IDLE_TIMEOUT_SECS);
+
+		o2net_set_nn_state(nn, NULL, 0, -ENOTCONN);
+	}
+	spin_unlock(&nn->nn_lock);
+}
+
+static void o2net_still_up(void *arg)
+{
+	struct o2net_node *nn = arg;
+
+	o2quo_hb_still_up(o2net_num_from_nn(nn));
+}
+
+/* ------------------------------------------------------------ */
+
+void o2net_disconnect_node(struct o2nm_node *node)
+{
+	struct o2net_node *nn = o2net_nn_from_num(node->nd_num);
+
+	/* don't reconnect until it's heartbeating again */
+	spin_lock(&nn->nn_lock);
+	o2net_set_nn_state(nn, NULL, 0, -ENOTCONN);
+	spin_unlock(&nn->nn_lock);
+
+	if (o2net_wq) {
+		cancel_delayed_work(&nn->nn_connect_expired);
+		cancel_delayed_work(&nn->nn_connect_work);
+		cancel_delayed_work(&nn->nn_still_up);
+		flush_workqueue(o2net_wq);
+	}
+}
+
+static void o2net_hb_node_down_cb(struct o2nm_node *node, int node_num,
+				  void *data)
+{
+	o2quo_hb_down(node_num);
+
+	if (node_num != o2nm_this_node())
+		o2net_disconnect_node(node);
+}
+
+static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num,
+				void *data)
+{
+	struct o2net_node *nn = o2net_nn_from_num(node_num);
+
+	o2quo_hb_up(node_num);
+
+	/* ensure an immediate connect attempt */
+	nn->nn_last_connect_attempt = jiffies -
+		(msecs_to_jiffies(O2NET_RECONNECT_DELAY_MS) + 1);
+
+	if (node_num != o2nm_this_node()) {
+		/* heartbeat doesn't work unless a local node number is
+		 * configured and doing so brings up the o2net_wq, so we can
+		 * use it.. */
+		queue_delayed_work(o2net_wq, &nn->nn_connect_expired,
+				   O2NET_IDLE_TIMEOUT_SECS * HZ);
+
+		/* believe it or not, accept and node hearbeating testing
+		 * can succeed for this node before we got here.. so
+		 * only use set_nn_state to clear the persistent error
+		 * if that hasn't already happened */
+		spin_lock(&nn->nn_lock);
+		if (nn->nn_persistent_error)
+			o2net_set_nn_state(nn, NULL, 0, 0);
+		spin_unlock(&nn->nn_lock);
+	}
+}
+
+void o2net_unregister_hb_callbacks(void)
+{
+	int ret;
+
+	ret = o2hb_unregister_callback(&o2net_hb_up);
+	if (ret < 0)
+		mlog(ML_ERROR, "Status return %d unregistering heartbeat up "
+		     "callback!\n", ret);
+
+	ret = o2hb_unregister_callback(&o2net_hb_down);
+	if (ret < 0)
+		mlog(ML_ERROR, "Status return %d unregistering heartbeat down "
+		     "callback!\n", ret);
+}
+
+int o2net_register_hb_callbacks(void)
+{
+	int ret;
+
+	o2hb_setup_callback(&o2net_hb_down, O2HB_NODE_DOWN_CB,
+			    o2net_hb_node_down_cb, NULL, O2NET_HB_PRI);
+	o2hb_setup_callback(&o2net_hb_up, O2HB_NODE_UP_CB,
+			    o2net_hb_node_up_cb, NULL, O2NET_HB_PRI);
+
+	ret = o2hb_register_callback(&o2net_hb_up);
+	if (ret == 0)
+		ret = o2hb_register_callback(&o2net_hb_down);
+
+	if (ret)
+		o2net_unregister_hb_callbacks();
+
+	return ret;
+}
+
+/* ------------------------------------------------------------ */
+
+static int o2net_accept_one(struct socket *sock)
+{
+	int ret, slen;
+	struct sockaddr_in sin;
+	struct socket *new_sock = NULL;
+	struct o2nm_node *node = NULL;
+	struct o2net_sock_container *sc = NULL;
+	struct o2net_node *nn;
+
+	BUG_ON(sock == NULL);
+	ret = sock_create_lite(sock->sk->sk_family, sock->sk->sk_type,
+			       sock->sk->sk_protocol, &new_sock);
+	if (ret)
+		goto out;
+
+	new_sock->type = sock->type;
+	new_sock->ops = sock->ops;
+	ret = sock->ops->accept(sock, new_sock, O_NONBLOCK);
+	if (ret < 0)
+		goto out;
+
+	new_sock->sk->sk_allocation = GFP_ATOMIC;
+
+	ret = o2net_set_nodelay(new_sock);
+	if (ret) {
+		mlog(ML_ERROR, "setting TCP_NODELAY failed with %d\n", ret);
+		goto out;
+	}
+
+	slen = sizeof(sin);
+	ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin,
+				       &slen, 1);
+	if (ret < 0)
+		goto out;
+
+	node = o2nm_get_node_by_ip((__force __be32)sin.sin_addr.s_addr);
+	if (node == NULL) {
+		mlog(ML_NOTICE, "attempt to connect from unknown node at "
+		     "%u.%u.%u.%u:%d\n", NIPQUAD(sin.sin_addr.s_addr),
+		     ntohs((__force __be16)sin.sin_port));
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (o2nm_this_node() > node->nd_num) {
+		mlog(ML_NOTICE, "unexpected connect attempted from a lower "
+		     "numbered node '%s' at " "%u.%u.%u.%u:%d with num %u\n",
+		     node->nd_name, NIPQUAD(sin.sin_addr.s_addr),
+		     ntohs((__force __be16)sin.sin_port), node->nd_num);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	/* this happens all the time when the other node sees our heartbeat
+	 * and tries to connect before we see their heartbeat */
+	if (!o2hb_check_node_heartbeating_from_callback(node->nd_num)) {
+		mlog(ML_CONN, "attempt to connect from node '%s' at "
+		     "%u.%u.%u.%u:%d but it isn't heartbeating\n",
+		     node->nd_name, NIPQUAD(sin.sin_addr.s_addr),
+		     ntohs((__force __be16)sin.sin_port));
+		ret = -EINVAL;
+		goto out;
+	}
+
+	nn = o2net_nn_from_num(node->nd_num);
+
+	spin_lock(&nn->nn_lock);
+	if (nn->nn_sc)
+		ret = -EBUSY;
+	else
+		ret = 0;
+	spin_unlock(&nn->nn_lock);
+	if (ret) {
+		mlog(ML_NOTICE, "attempt to connect from node '%s' at "
+		     "%u.%u.%u.%u:%d but it already has an open connection\n",
+		     node->nd_name, NIPQUAD(sin.sin_addr.s_addr),
+		     ntohs((__force __be16)sin.sin_port));
+		goto out;
+	}
+
+	sc = sc_alloc(node);
+	if (sc == NULL) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	sc->sc_sock = new_sock;
+	new_sock = NULL;
+
+	spin_lock(&nn->nn_lock);
+	o2net_set_nn_state(nn, sc, 0, 0);
+	spin_unlock(&nn->nn_lock);
+
+	o2net_register_callbacks(sc->sc_sock->sk, sc);
+	o2net_sc_queue_work(sc, &sc->sc_rx_work);
+
+	o2net_sendpage(sc, o2net_hand, sizeof(*o2net_hand));
+
+out:
+	if (new_sock)
+		sock_release(new_sock);
+	if (node)
+		o2nm_node_put(node);
+	if (sc)
+		sc_put(sc);
+	return ret;
+}
+
+static void o2net_accept_many(void *arg)
+{
+	struct socket *sock = arg;
+	while (o2net_accept_one(sock) == 0)
+		cond_resched();
+}
+
+static void o2net_listen_data_ready(struct sock *sk, int bytes)
+{
+	void (*ready)(struct sock *sk, int bytes);
+
+	read_lock(&sk->sk_callback_lock);
+	ready = sk->sk_user_data;
+	if (ready == NULL) { /* check for teardown race */
+		ready = sk->sk_data_ready;
+		goto out;
+	}
+
+	/* ->sk_data_ready is also called for a newly established child socket
+	 * before it has been accepted and the acceptor has set up their
+	 * data_ready.. we only want to queue listen work for our listening
+	 * socket */
+	if (sk->sk_state == TCP_LISTEN) {
+		mlog(ML_TCP, "bytes: %d\n", bytes);
+		queue_work(o2net_wq, &o2net_listen_work);
+	}
+
+out:
+	read_unlock(&sk->sk_callback_lock);
+	ready(sk, bytes);
+}
+
+static int o2net_open_listening_sock(__be16 port)
+{
+	struct socket *sock = NULL;
+	int ret;
+	struct sockaddr_in sin = {
+		.sin_family = PF_INET,
+		.sin_addr = { .s_addr = (__force u32)htonl(INADDR_ANY) },
+		.sin_port = (__force u16)port,
+	};
+
+	ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+	if (ret < 0) {
+		mlog(ML_ERROR, "unable to create socket, ret=%d\n", ret);
+		goto out;
+	}
+
+	sock->sk->sk_allocation = GFP_ATOMIC;
+
+	write_lock_bh(&sock->sk->sk_callback_lock);
+	sock->sk->sk_user_data = sock->sk->sk_data_ready;
+	sock->sk->sk_data_ready = o2net_listen_data_ready;
+	write_unlock_bh(&sock->sk->sk_callback_lock);
+
+	o2net_listen_sock = sock;
+	INIT_WORK(&o2net_listen_work, o2net_accept_many, sock);
+
+	sock->sk->sk_reuse = 1;
+	ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
+	if (ret < 0) {
+		mlog(ML_ERROR, "unable to bind socket to port %d, ret=%d\n",
+		     ntohs(port), ret);
+		goto out;
+	}
+
+	ret = sock->ops->listen(sock, 64);
+	if (ret < 0) {
+		mlog(ML_ERROR, "unable to listen on port %d, ret=%d\n",
+		     ntohs(port), ret);
+	}
+
+out:
+	if (ret) {
+		o2net_listen_sock = NULL;
+		if (sock)
+			sock_release(sock);
+	}
+	return ret;
+}
+
+/*
+ * called from node manager when we should bring up our network listening
+ * socket.  node manager handles all the serialization to only call this
+ * once and to match it with o2net_stop_listening().  note,
+ * o2nm_this_node() doesn't work yet as we're being called while it
+ * is being set up.
+ */
+int o2net_start_listening(struct o2nm_node *node)
+{
+	int ret = 0;
+
+	BUG_ON(o2net_wq != NULL);
+	BUG_ON(o2net_listen_sock != NULL);
+
+	mlog(ML_KTHREAD, "starting o2net thread...\n");
+	o2net_wq = create_singlethread_workqueue("o2net");
+	if (o2net_wq == NULL) {
+		mlog(ML_ERROR, "unable to launch o2net thread\n");
+		return -ENOMEM; /* ? */
+	}
+
+	ret = o2net_open_listening_sock(node->nd_ipv4_port);
+	if (ret) {
+		destroy_workqueue(o2net_wq);
+		o2net_wq = NULL;
+	} else
+		o2quo_conn_up(node->nd_num);
+
+	return ret;
+}
+
+/* again, o2nm_this_node() doesn't work here as we're involved in
+ * tearing it down */
+void o2net_stop_listening(struct o2nm_node *node)
+{
+	struct socket *sock = o2net_listen_sock;
+	size_t i;
+
+	BUG_ON(o2net_wq == NULL);
+	BUG_ON(o2net_listen_sock == NULL);
+
+	/* stop the listening socket from generating work */
+	write_lock_bh(&sock->sk->sk_callback_lock);
+	sock->sk->sk_data_ready = sock->sk->sk_user_data;
+	sock->sk->sk_user_data = NULL;
+	write_unlock_bh(&sock->sk->sk_callback_lock);
+
+	for (i = 0; i < ARRAY_SIZE(o2net_nodes); i++) {
+		struct o2nm_node *node = o2nm_get_node_by_num(i);
+		if (node) {
+			o2net_disconnect_node(node);
+			o2nm_node_put(node);
+		}
+	}
+
+	/* finish all work and tear down the work queue */
+	mlog(ML_KTHREAD, "waiting for o2net thread to exit....\n");
+	destroy_workqueue(o2net_wq);
+	o2net_wq = NULL;
+
+	sock_release(o2net_listen_sock);
+	o2net_listen_sock = NULL;
+
+	o2quo_conn_err(node->nd_num);
+}
+
+/* ------------------------------------------------------------ */
+
+int o2net_init(void)
+{
+	unsigned long i;
+
+	o2quo_init();
+
+	o2net_hand = kcalloc(1, sizeof(struct o2net_handshake), GFP_KERNEL);
+	o2net_keep_req = kcalloc(1, sizeof(struct o2net_msg), GFP_KERNEL);
+	o2net_keep_resp = kcalloc(1, sizeof(struct o2net_msg), GFP_KERNEL);
+	if (!o2net_hand || !o2net_keep_req || !o2net_keep_resp) {
+		kfree(o2net_hand);
+		kfree(o2net_keep_req);
+		kfree(o2net_keep_resp);
+		return -ENOMEM;
+	}
+
+	o2net_hand->protocol_version = cpu_to_be64(O2NET_PROTOCOL_VERSION);
+	o2net_hand->connector_id = cpu_to_be64(1);
+
+	o2net_keep_req->magic = cpu_to_be16(O2NET_MSG_KEEP_REQ_MAGIC);
+	o2net_keep_resp->magic = cpu_to_be16(O2NET_MSG_KEEP_RESP_MAGIC);
+
+	for (i = 0; i < ARRAY_SIZE(o2net_nodes); i++) {
+		struct o2net_node *nn = o2net_nn_from_num(i);
+
+		spin_lock_init(&nn->nn_lock);
+		INIT_WORK(&nn->nn_connect_work, o2net_start_connect, nn);
+		INIT_WORK(&nn->nn_connect_expired, o2net_connect_expired, nn);
+		INIT_WORK(&nn->nn_still_up, o2net_still_up, nn);
+		/* until we see hb from a node we'll return einval */
+		nn->nn_persistent_error = -ENOTCONN;
+		init_waitqueue_head(&nn->nn_sc_wq);
+		idr_init(&nn->nn_status_idr);
+		INIT_LIST_HEAD(&nn->nn_status_list);
+	}
+
+	return 0;
+}
+
+void o2net_exit(void)
+{
+	o2quo_exit();
+	kfree(o2net_hand);
+	kfree(o2net_keep_req);
+	kfree(o2net_keep_resp);
+}
diff --git a/fs/ocfs2/cluster/tcp.h b/fs/ocfs2/cluster/tcp.h
new file mode 100644
index 0000000..a6f4585
--- /dev/null
+++ b/fs/ocfs2/cluster/tcp.h
@@ -0,0 +1,113 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * tcp.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef O2CLUSTER_TCP_H
+#define O2CLUSTER_TCP_H
+
+#include <linux/socket.h>
+#ifdef __KERNEL__
+#include <net/sock.h>
+#include <linux/tcp.h>
+#else
+#include <sys/socket.h>
+#endif
+#include <linux/inet.h>
+#include <linux/in.h>
+
+struct o2net_msg
+{
+	__be16 magic;
+	__be16 data_len;
+	__be16 msg_type;
+	__be16 pad1;
+	__be32 sys_status;
+	__be32 status;
+	__be32 key;
+	__be32 msg_num;
+	__u8  buf[0];
+};
+
+typedef int (o2net_msg_handler_func)(struct o2net_msg *msg, u32 len, void *data);
+
+#define O2NET_MAX_PAYLOAD_BYTES  (4096 - sizeof(struct o2net_msg))
+
+/* TODO: figure this out.... */
+static inline int o2net_link_down(int err, struct socket *sock)
+{
+	if (sock) {
+		if (sock->sk->sk_state != TCP_ESTABLISHED &&
+	    	    sock->sk->sk_state != TCP_CLOSE_WAIT)
+			return 1;
+	}
+
+	if (err >= 0)
+		return 0;
+	switch (err) {
+		/* ????????????????????????? */
+		case -ERESTARTSYS:
+		case -EBADF:
+		/* When the server has died, an ICMP port unreachable
+		 * message prompts ECONNREFUSED. */
+		case -ECONNREFUSED:
+		case -ENOTCONN:
+		case -ECONNRESET:
+		case -EPIPE:
+			return 1;
+	}
+	return 0;
+}
+
+enum {
+	O2NET_DRIVER_UNINITED,
+	O2NET_DRIVER_READY,
+};
+
+int o2net_init_tcp_sock(struct inode *inode);
+int o2net_send_message(u32 msg_type, u32 key, void *data, u32 len,
+		       u8 target_node, int *status);
+int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *vec,
+			   size_t veclen, u8 target_node, int *status);
+int o2net_broadcast_message(u32 msg_type, u32 key, void *data, u32 len,
+			    struct inode *group);
+
+int o2net_register_handler(u32 msg_type, u32 key, u32 max_len,
+			   o2net_msg_handler_func *func, void *data,
+			   struct list_head *unreg_list);
+void o2net_unregister_handler_list(struct list_head *list);
+
+struct o2nm_node;
+int o2net_register_hb_callbacks(void);
+void o2net_unregister_hb_callbacks(void);
+int o2net_start_listening(struct o2nm_node *node);
+void o2net_stop_listening(struct o2nm_node *node);
+void o2net_disconnect_node(struct o2nm_node *node);
+
+int o2net_init(void);
+void o2net_exit(void);
+int o2net_proc_init(struct proc_dir_entry *parent);
+void o2net_proc_exit(struct proc_dir_entry *parent);
+
+#endif /* O2CLUSTER_TCP_H */
diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h
new file mode 100644
index 0000000..ff9e2e2
--- /dev/null
+++ b/fs/ocfs2/cluster/tcp_internal.h
@@ -0,0 +1,174 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef O2CLUSTER_TCP_INTERNAL_H
+#define O2CLUSTER_TCP_INTERNAL_H
+
+#define O2NET_MSG_MAGIC           ((u16)0xfa55)
+#define O2NET_MSG_STATUS_MAGIC    ((u16)0xfa56)
+#define O2NET_MSG_KEEP_REQ_MAGIC  ((u16)0xfa57)
+#define O2NET_MSG_KEEP_RESP_MAGIC ((u16)0xfa58)
+
+/* same as hb delay, we're waiting for another node to recognize our hb */
+#define O2NET_RECONNECT_DELAY_MS	O2HB_REGION_TIMEOUT_MS
+
+/* we're delaying our quorum decision so that heartbeat will have timed
+ * out truly dead nodes by the time we come around to making decisions
+ * on their number */
+#define O2NET_QUORUM_DELAY_MS	((o2hb_dead_threshold + 2) * O2HB_REGION_TIMEOUT_MS)
+
+#define O2NET_KEEPALIVE_DELAY_SECS	5
+#define O2NET_IDLE_TIMEOUT_SECS		10
+
+/* 
+ * This version number represents quite a lot, unfortunately.  It not
+ * only represents the raw network message protocol on the wire but also
+ * locking semantics of the file system using the protocol.  It should 
+ * be somewhere else, I'm sure, but right now it isn't.
+ *
+ * New in version 2:
+ * 	- full 64 bit i_size in the metadata lock lvbs
+ * 	- introduction of "rw" lock and pushing meta/data locking down
+ */
+#define O2NET_PROTOCOL_VERSION 2ULL
+struct o2net_handshake {
+	__be64	protocol_version;
+	__be64	connector_id;
+};
+
+struct o2net_node {
+	/* this is never called from int/bh */
+	spinlock_t			nn_lock;
+
+	/* set the moment an sc is allocated and a connect is started */
+	struct o2net_sock_container	*nn_sc;
+	/* _valid is only set after the handshake passes and tx can happen */
+	unsigned			nn_sc_valid:1;
+	/* if this is set tx just returns it */
+	int				nn_persistent_error;
+
+	/* threads waiting for an sc to arrive wait on the wq for generation
+	 * to increase.  it is increased when a connecting socket succeeds
+	 * or fails or when an accepted socket is attached. */
+	wait_queue_head_t		nn_sc_wq;
+
+	struct idr			nn_status_idr;
+	struct list_head		nn_status_list;
+
+	/* connects are attempted from when heartbeat comes up until either hb
+	 * goes down, the node is unconfigured, no connect attempts succeed
+	 * before O2NET_CONN_IDLE_DELAY, or a connect succeeds.  connect_work
+	 * is queued from set_nn_state both from hb up and from itself if a
+	 * connect attempt fails and so can be self-arming.  shutdown is
+	 * careful to first mark the nn such that no connects will be attempted
+	 * before canceling delayed connect work and flushing the queue. */
+	struct work_struct		nn_connect_work;
+	unsigned long			nn_last_connect_attempt;
+
+	/* this is queued as nodes come up and is canceled when a connection is
+	 * established.  this expiring gives up on the node and errors out
+	 * transmits */
+	struct work_struct		nn_connect_expired;
+
+	/* after we give up on a socket we wait a while before deciding
+	 * that it is still heartbeating and that we should do some
+	 * quorum work */
+	struct work_struct		nn_still_up;
+};
+
+struct o2net_sock_container {
+	struct kref		sc_kref;
+	/* the next two are vaild for the life time of the sc */
+	struct socket		*sc_sock;
+	struct o2nm_node	*sc_node;
+
+	/* all of these sc work structs hold refs on the sc while they are
+	 * queued.  they should not be able to ref a freed sc.  the teardown
+	 * race is with o2net_wq destruction in o2net_stop_listening() */
+
+	/* rx and connect work are generated from socket callbacks.  sc
+	 * shutdown removes the callbacks and then flushes the work queue */
+	struct work_struct	sc_rx_work;
+	struct work_struct	sc_connect_work;
+	/* shutdown work is triggered in two ways.  the simple way is
+	 * for a code path calls ensure_shutdown which gets a lock, removes
+	 * the sc from the nn, and queues the work.  in this case the
+	 * work is single-shot.  the work is also queued from a sock
+	 * callback, though, and in this case the work will find the sc
+	 * still on the nn and will call ensure_shutdown itself.. this
+	 * ends up triggering the shutdown work again, though nothing
+	 * will be done in that second iteration.  so work queue teardown
+	 * has to be careful to remove the sc from the nn before waiting
+	 * on the work queue so that the shutdown work doesn't remove the
+	 * sc and rearm itself.
+	 */
+	struct work_struct	sc_shutdown_work;
+
+	struct timer_list	sc_idle_timeout;
+	struct work_struct	sc_keepalive_work;
+
+	unsigned		sc_handshake_ok:1;
+
+	struct page 		*sc_page;
+	size_t			sc_page_off;
+
+	/* original handlers for the sockets */
+	void			(*sc_state_change)(struct sock *sk);
+	void			(*sc_data_ready)(struct sock *sk, int bytes);
+
+	struct timeval 		sc_tv_timer;
+	struct timeval 		sc_tv_data_ready;
+	struct timeval 		sc_tv_advance_start;
+	struct timeval 		sc_tv_advance_stop;
+	struct timeval 		sc_tv_func_start;
+	struct timeval 		sc_tv_func_stop;
+	u32			sc_msg_key;
+	u16			sc_msg_type;
+};
+
+struct o2net_msg_handler {
+	struct rb_node		nh_node;
+	u32			nh_max_len;
+	u32			nh_msg_type;
+	u32			nh_key;
+	o2net_msg_handler_func	*nh_func;
+	o2net_msg_handler_func	*nh_func_data;
+	struct kref		nh_kref;
+	struct list_head	nh_unregister_item;
+};
+
+enum o2net_system_error {
+	O2NET_ERR_NONE = 0,
+	O2NET_ERR_NO_HNDLR,
+	O2NET_ERR_OVERFLOW,
+	O2NET_ERR_DIED,
+	O2NET_ERR_MAX
+};
+
+struct o2net_status_wait {
+	enum o2net_system_error	ns_sys_status;
+	s32			ns_status;
+	int			ns_id;
+	wait_queue_head_t	ns_wq;
+	struct list_head	ns_node_item;
+};
+
+#endif /* O2CLUSTER_TCP_INTERNAL_H */
diff --git a/fs/ocfs2/cluster/ver.c b/fs/ocfs2/cluster/ver.c
new file mode 100644
index 0000000..7286c48
--- /dev/null
+++ b/fs/ocfs2/cluster/ver.c
@@ -0,0 +1,42 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ver.c
+ *
+ * version string
+ *
+ * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include "ver.h"
+
+#define CLUSTER_BUILD_VERSION "1.3.3"
+
+#define VERSION_STR "OCFS2 Node Manager " CLUSTER_BUILD_VERSION
+
+void cluster_print_version(void)
+{
+	printk(KERN_INFO "%s\n", VERSION_STR);
+}
+
+MODULE_DESCRIPTION(VERSION_STR);
+
+MODULE_VERSION(CLUSTER_BUILD_VERSION);
diff --git a/fs/ocfs2/cluster/ver.h b/fs/ocfs2/cluster/ver.h
new file mode 100644
index 0000000..32554c3
--- /dev/null
+++ b/fs/ocfs2/cluster/ver.h
@@ -0,0 +1,31 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ver.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef O2CLUSTER_VER_H
+#define O2CLUSTER_VER_H
+
+void cluster_print_version(void);
+
+#endif /* O2CLUSTER_VER_H */
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
new file mode 100644
index 0000000..bd85182
--- /dev/null
+++ b/fs/ocfs2/dcache.c
@@ -0,0 +1,91 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dcache.c
+ *
+ * dentry cache handling code
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/namei.h>
+
+#define MLOG_MASK_PREFIX ML_DCACHE
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dcache.h"
+#include "file.h"
+#include "inode.h"
+
+static int ocfs2_dentry_revalidate(struct dentry *dentry,
+				   struct nameidata *nd)
+{
+	struct inode *inode = dentry->d_inode;
+	int ret = 0;    /* if all else fails, just return false */
+	struct ocfs2_super *osb;
+
+	mlog_entry("(0x%p, '%.*s')\n", dentry,
+		   dentry->d_name.len, dentry->d_name.name);
+
+	/* Never trust a negative dentry - force a new lookup. */
+	if (inode == NULL) {
+		mlog(0, "negative dentry: %.*s\n", dentry->d_name.len,
+		     dentry->d_name.name);
+		goto bail;
+	}
+
+	osb = OCFS2_SB(inode->i_sb);
+
+	BUG_ON(!osb);
+
+	if (inode != osb->root_inode) {
+		spin_lock(&OCFS2_I(inode)->ip_lock);
+		/* did we or someone else delete this inode? */
+		if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
+			spin_unlock(&OCFS2_I(inode)->ip_lock);
+			mlog(0, "inode (%"MLFu64") deleted, returning false\n",
+			     OCFS2_I(inode)->ip_blkno);
+			goto bail;
+		}
+		spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+		if (!inode->i_nlink) {
+			mlog(0, "Inode %"MLFu64" orphaned, returning false "
+			     "dir = %d\n", OCFS2_I(inode)->ip_blkno,
+			     S_ISDIR(inode->i_mode));
+			goto bail;
+		}
+	}
+
+	ret = 1;
+
+bail:
+	mlog_exit(ret);
+
+	return ret;
+}
+
+struct dentry_operations ocfs2_dentry_ops = {
+	.d_revalidate		= ocfs2_dentry_revalidate,
+};
diff --git a/fs/ocfs2/dcache.h b/fs/ocfs2/dcache.h
new file mode 100644
index 0000000..9007277
--- /dev/null
+++ b/fs/ocfs2/dcache.h
@@ -0,0 +1,31 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dcache.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_DCACHE_H
+#define OCFS2_DCACHE_H
+
+extern struct dentry_operations ocfs2_dentry_ops;
+
+#endif /* OCFS2_DCACHE_H */
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
new file mode 100644
index 0000000..856e20a
--- /dev/null
+++ b/fs/ocfs2/dir.c
@@ -0,0 +1,618 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dir.c
+ *
+ * Creates, reads, walks and deletes directory-nodes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ *  Portions of this code from linux/fs/ext3/dir.c
+ *
+ *  Copyright (C) 1992, 1993, 1994, 1995
+ *  Remy Card (card@masi.ibp.fr)
+ *  Laboratoire MASI - Institut Blaise pascal
+ *  Universite Pierre et Marie Curie (Paris VI)
+ *
+ *   from
+ *
+ *   linux/fs/minix/dir.c
+ *
+ *   Copyright (C) 1991, 1992 Linux Torvalds
+ *
+ * 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+
+#define MLOG_MASK_PREFIX ML_NAMEI
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dir.h"
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "file.h"
+#include "inode.h"
+#include "journal.h"
+#include "namei.h"
+#include "suballoc.h"
+#include "uptodate.h"
+
+#include "buffer_head_io.h"
+
+static unsigned char ocfs2_filetype_table[] = {
+	DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
+};
+
+static int ocfs2_extend_dir(struct ocfs2_super *osb,
+			    struct inode *dir,
+			    struct buffer_head *parent_fe_bh,
+			    struct buffer_head **new_de_bh);
+/*
+ * ocfs2_readdir()
+ *
+ */
+int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
+{
+	int error = 0;
+	unsigned long offset, blk;
+	int i, num, stored;
+	struct buffer_head * bh, * tmp;
+	struct ocfs2_dir_entry * de;
+	int err;
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct super_block * sb = inode->i_sb;
+	int have_disk_lock = 0;
+
+	mlog_entry("dirino=%"MLFu64"\n", OCFS2_I(inode)->ip_blkno);
+
+	stored = 0;
+	bh = NULL;
+
+	error = ocfs2_meta_lock(inode, NULL, NULL, 0);
+	if (error < 0) {
+		if (error != -ENOENT)
+			mlog_errno(error);
+		/* we haven't got any yet, so propagate the error. */
+		stored = error;
+		goto bail;
+	}
+	have_disk_lock = 1;
+
+	offset = filp->f_pos & (sb->s_blocksize - 1);
+
+	while (!error && !stored && filp->f_pos < i_size_read(inode)) {
+		blk = (filp->f_pos) >> sb->s_blocksize_bits;
+		bh = ocfs2_bread(inode, blk, &err, 0);
+		if (!bh) {
+			mlog(ML_ERROR, "directory #%"MLFu64" contains a hole "
+				       "at offset %lld\n",
+			     OCFS2_I(inode)->ip_blkno,
+			     filp->f_pos);
+			filp->f_pos += sb->s_blocksize - offset;
+			continue;
+		}
+
+		/*
+		 * Do the readahead (8k)
+		 */
+		if (!offset) {
+			for (i = 16 >> (sb->s_blocksize_bits - 9), num = 0;
+			     i > 0; i--) {
+				tmp = ocfs2_bread(inode, ++blk, &err, 1);
+				if (tmp)
+					brelse(tmp);
+			}
+		}
+
+revalidate:
+		/* If the dir block has changed since the last call to
+		 * readdir(2), then we might be pointing to an invalid
+		 * dirent right now.  Scan from the start of the block
+		 * to make sure. */
+		if (filp->f_version != inode->i_version) {
+			for (i = 0; i < sb->s_blocksize && i < offset; ) {
+				de = (struct ocfs2_dir_entry *) (bh->b_data + i);
+				/* It's too expensive to do a full
+				 * dirent test each time round this
+				 * loop, but we do have to test at
+				 * least that it is non-zero.  A
+				 * failure will be detected in the
+				 * dirent test below. */
+				if (le16_to_cpu(de->rec_len) <
+				    OCFS2_DIR_REC_LEN(1))
+					break;
+				i += le16_to_cpu(de->rec_len);
+			}
+			offset = i;
+			filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
+				| offset;
+			filp->f_version = inode->i_version;
+		}
+
+		while (!error && filp->f_pos < i_size_read(inode)
+		       && offset < sb->s_blocksize) {
+			de = (struct ocfs2_dir_entry *) (bh->b_data + offset);
+			if (!ocfs2_check_dir_entry(inode, de, bh, offset)) {
+				/* On error, skip the f_pos to the
+				   next block. */
+				filp->f_pos = (filp->f_pos |
+					       (sb->s_blocksize - 1)) + 1;
+				brelse(bh);
+				goto bail;
+			}
+			offset += le16_to_cpu(de->rec_len);
+			if (le64_to_cpu(de->inode)) {
+				/* We might block in the next section
+				 * if the data destination is
+				 * currently swapped out.  So, use a
+				 * version stamp to detect whether or
+				 * not the directory has been modified
+				 * during the copy operation.
+				 */
+				unsigned long version = filp->f_version;
+				unsigned char d_type = DT_UNKNOWN;
+
+				if (de->file_type < OCFS2_FT_MAX)
+					d_type = ocfs2_filetype_table[de->file_type];
+				error = filldir(dirent, de->name,
+						de->name_len,
+						filp->f_pos,
+						ino_from_blkno(sb, le64_to_cpu(de->inode)),
+						d_type);
+				if (error)
+					break;
+				if (version != filp->f_version)
+					goto revalidate;
+				stored ++;
+			}
+			filp->f_pos += le16_to_cpu(de->rec_len);
+		}
+		offset = 0;
+		brelse(bh);
+	}
+
+	stored = 0;
+bail:
+	if (have_disk_lock)
+		ocfs2_meta_unlock(inode, 0);
+
+	mlog_exit(stored);
+
+	return stored;
+}
+
+/*
+ * NOTE: this should always be called with parent dir i_sem taken.
+ */
+int ocfs2_find_files_on_disk(const char *name,
+			     int namelen,
+			     u64 *blkno,
+			     struct inode *inode,
+			     struct buffer_head **dirent_bh,
+			     struct ocfs2_dir_entry **dirent)
+{
+	int status = -ENOENT;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	mlog_entry("(osb=%p, parent=%"MLFu64", name='%.*s', blkno=%p, "
+		   "inode=%p)\n",
+		   osb, OCFS2_I(inode)->ip_blkno, namelen, name, blkno, inode);
+
+	*dirent_bh = ocfs2_find_entry(name, namelen, inode, dirent);
+	if (!*dirent_bh || !*dirent) {
+		status = -ENOENT;
+		goto leave;
+	}
+
+	*blkno = le64_to_cpu((*dirent)->inode);
+
+	status = 0;
+leave:
+	if (status < 0) {
+		*dirent = NULL;
+		if (*dirent_bh) {
+			brelse(*dirent_bh);
+			*dirent_bh = NULL;
+		}
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+/* Check for a name within a directory.
+ *
+ * Return 0 if the name does not exist
+ * Return -EEXIST if the directory contains the name
+ *
+ * Callers should have i_sem + a cluster lock on dir
+ */
+int ocfs2_check_dir_for_entry(struct inode *dir,
+			      const char *name,
+			      int namelen)
+{
+	int ret;
+	struct buffer_head *dirent_bh = NULL;
+	struct ocfs2_dir_entry *dirent = NULL;
+
+	mlog_entry("dir %"MLFu64", name '%.*s'\n", OCFS2_I(dir)->ip_blkno,
+		   namelen, name);
+
+	ret = -EEXIST;
+	dirent_bh = ocfs2_find_entry(name, namelen, dir, &dirent);
+	if (dirent_bh)
+		goto bail;
+
+	ret = 0;
+bail:
+	if (dirent_bh)
+		brelse(dirent_bh);
+
+	mlog_exit(ret);
+	return ret;
+}
+
+/*
+ * routine to check that the specified directory is empty (for rmdir)
+ */
+int ocfs2_empty_dir(struct inode *inode)
+{
+	unsigned long offset;
+	struct buffer_head * bh;
+	struct ocfs2_dir_entry * de, * de1;
+	struct super_block * sb;
+	int err;
+
+	sb = inode->i_sb;
+	if ((i_size_read(inode) <
+	     (OCFS2_DIR_REC_LEN(1) + OCFS2_DIR_REC_LEN(2))) ||
+	    !(bh = ocfs2_bread(inode, 0, &err, 0))) {
+	    	mlog(ML_ERROR, "bad directory (dir #%"MLFu64") - "
+			       "no data block\n",
+		     OCFS2_I(inode)->ip_blkno);
+		return 1;
+	}
+
+	de = (struct ocfs2_dir_entry *) bh->b_data;
+	de1 = (struct ocfs2_dir_entry *)
+			((char *)de + le16_to_cpu(de->rec_len));
+	if ((le64_to_cpu(de->inode) != OCFS2_I(inode)->ip_blkno) ||
+			!le64_to_cpu(de1->inode) ||
+			strcmp(".", de->name) ||
+			strcmp("..", de1->name)) {
+	    	mlog(ML_ERROR, "bad directory (dir #%"MLFu64") - "
+			       "no `.' or `..'\n",
+		     OCFS2_I(inode)->ip_blkno);
+		brelse(bh);
+		return 1;
+	}
+	offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len);
+	de = (struct ocfs2_dir_entry *)((char *)de1 + le16_to_cpu(de1->rec_len));
+	while (offset < i_size_read(inode) ) {
+		if (!bh || (void *)de >= (void *)(bh->b_data + sb->s_blocksize)) {
+			brelse(bh);
+			bh = ocfs2_bread(inode,
+					 offset >> sb->s_blocksize_bits, &err, 0);
+			if (!bh) {
+				mlog(ML_ERROR, "directory #%"MLFu64" contains "
+					       "a hole at offset %lu\n",
+				     OCFS2_I(inode)->ip_blkno, offset);
+				offset += sb->s_blocksize;
+				continue;
+			}
+			de = (struct ocfs2_dir_entry *) bh->b_data;
+		}
+		if (!ocfs2_check_dir_entry(inode, de, bh, offset)) {
+			brelse(bh);
+			return 1;
+		}
+		if (le64_to_cpu(de->inode)) {
+			brelse(bh);
+			return 0;
+		}
+		offset += le16_to_cpu(de->rec_len);
+		de = (struct ocfs2_dir_entry *)
+			((char *)de + le16_to_cpu(de->rec_len));
+	}
+	brelse(bh);
+	return 1;
+}
+
+/* returns a bh of the 1st new block in the allocation. */
+int ocfs2_do_extend_dir(struct super_block *sb,
+			struct ocfs2_journal_handle *handle,
+			struct inode *dir,
+			struct buffer_head *parent_fe_bh,
+			struct ocfs2_alloc_context *data_ac,
+			struct ocfs2_alloc_context *meta_ac,
+			struct buffer_head **new_bh)
+{
+	int status;
+	int extend;
+	u64 p_blkno;
+
+	spin_lock(&OCFS2_I(dir)->ip_lock);
+	extend = (i_size_read(dir) == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters));
+	spin_unlock(&OCFS2_I(dir)->ip_lock);
+
+	if (extend) {
+		status = ocfs2_do_extend_allocation(OCFS2_SB(sb), dir, 1,
+						    parent_fe_bh, handle,
+						    data_ac, meta_ac, NULL);
+		BUG_ON(status == -EAGAIN);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	status = ocfs2_extent_map_get_blocks(dir, (dir->i_blocks >>
+						   (sb->s_blocksize_bits - 9)),
+					     1, &p_blkno, NULL);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	*new_bh = sb_getblk(sb, p_blkno);
+	if (!*new_bh) {
+		status = -EIO;
+		mlog_errno(status);
+		goto bail;
+	}
+	status = 0;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/* assumes you already have a cluster lock on the directory. */
+static int ocfs2_extend_dir(struct ocfs2_super *osb,
+			    struct inode *dir,
+			    struct buffer_head *parent_fe_bh,
+			    struct buffer_head **new_de_bh)
+{
+	int status = 0;
+	int credits, num_free_extents;
+	loff_t dir_i_size;
+	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
+	struct ocfs2_alloc_context *data_ac = NULL;
+	struct ocfs2_alloc_context *meta_ac = NULL;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct buffer_head *new_bh = NULL;
+	struct ocfs2_dir_entry * de;
+	struct super_block *sb = osb->sb;
+
+	mlog_entry_void();
+
+	dir_i_size = i_size_read(dir);
+	mlog(0, "extending dir %"MLFu64" (i_size = %lld)\n",
+	     OCFS2_I(dir)->ip_blkno, dir_i_size);
+
+	handle = ocfs2_alloc_handle(osb);
+	if (handle == NULL) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* dir->i_size is always block aligned. */
+	spin_lock(&OCFS2_I(dir)->ip_lock);
+	if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) {
+		spin_unlock(&OCFS2_I(dir)->ip_lock);
+		num_free_extents = ocfs2_num_free_extents(osb, dir, fe);
+		if (num_free_extents < 0) {
+			status = num_free_extents;
+			mlog_errno(status);
+			goto bail;
+		}
+
+		if (!num_free_extents) {
+			status = ocfs2_reserve_new_metadata(osb, handle,
+							    fe, &meta_ac);
+			if (status < 0) {
+				if (status != -ENOSPC)
+					mlog_errno(status);
+				goto bail;
+			}
+		}
+
+		status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac);
+		if (status < 0) {
+			if (status != -ENOSPC)
+				mlog_errno(status);
+			goto bail;
+		}
+
+		credits = ocfs2_calc_extend_credits(sb, fe, 1);
+	} else {
+		spin_unlock(&OCFS2_I(dir)->ip_lock);
+		credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS;
+	}
+
+	handle = ocfs2_start_trans(osb, handle, credits);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_do_extend_dir(osb->sb, handle, dir, parent_fe_bh,
+				     data_ac, meta_ac, &new_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	ocfs2_set_new_buffer_uptodate(dir, new_bh);
+
+	status = ocfs2_journal_access(handle, dir, new_bh,
+				      OCFS2_JOURNAL_ACCESS_CREATE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	memset(new_bh->b_data, 0, sb->s_blocksize);
+	de = (struct ocfs2_dir_entry *) new_bh->b_data;
+	de->inode = 0;
+	de->rec_len = cpu_to_le16(sb->s_blocksize);
+	status = ocfs2_journal_dirty(handle, new_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	dir_i_size += dir->i_sb->s_blocksize;
+	i_size_write(dir, dir_i_size);
+	dir->i_blocks = ocfs2_align_bytes_to_sectors(dir_i_size);
+	status = ocfs2_mark_inode_dirty(handle, dir, parent_fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	*new_de_bh = new_bh;
+	get_bh(*new_de_bh);
+bail:
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (data_ac)
+		ocfs2_free_alloc_context(data_ac);
+	if (meta_ac)
+		ocfs2_free_alloc_context(meta_ac);
+
+	if (new_bh)
+		brelse(new_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * Search the dir for a good spot, extending it if necessary. The
+ * block containing an appropriate record is returned in ret_de_bh.
+ */
+int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
+				 struct inode *dir,
+				 struct buffer_head *parent_fe_bh,
+				 const char *name,
+				 int namelen,
+				 struct buffer_head **ret_de_bh)
+{
+	unsigned long offset;
+	struct buffer_head * bh = NULL;
+	unsigned short rec_len;
+	struct ocfs2_dinode *fe;
+	struct ocfs2_dir_entry *de;
+	struct super_block *sb;
+	int status;
+
+	mlog_entry_void();
+
+	mlog(0, "getting ready to insert namelen %d into dir %"MLFu64"\n",
+	     namelen, OCFS2_I(dir)->ip_blkno);
+
+	BUG_ON(!S_ISDIR(dir->i_mode));
+	fe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
+	BUG_ON(le64_to_cpu(fe->i_size) != i_size_read(dir));
+
+	sb = dir->i_sb;
+
+	if (!namelen) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	bh = ocfs2_bread(dir, 0, &status, 0);
+	if (!bh) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	rec_len = OCFS2_DIR_REC_LEN(namelen);
+	offset = 0;
+	de = (struct ocfs2_dir_entry *) bh->b_data;
+	while (1) {
+		if ((char *)de >= sb->s_blocksize + bh->b_data) {
+			brelse(bh);
+			bh = NULL;
+
+			if (i_size_read(dir) <= offset) {
+				status = ocfs2_extend_dir(osb,
+							  dir,
+							  parent_fe_bh,
+							  &bh);
+				if (status < 0) {
+					mlog_errno(status);
+					goto bail;
+				}
+				BUG_ON(!bh);
+				*ret_de_bh = bh;
+				get_bh(*ret_de_bh);
+				goto bail;
+			}
+			bh = ocfs2_bread(dir,
+					 offset >> sb->s_blocksize_bits,
+					 &status,
+					 0);
+			if (!bh) {
+				mlog_errno(status);
+				goto bail;
+			}
+			/* move to next block */
+			de = (struct ocfs2_dir_entry *) bh->b_data;
+		}
+		if (!ocfs2_check_dir_entry(dir, de, bh, offset)) {
+			status = -ENOENT;
+			goto bail;
+		}
+		if (ocfs2_match(namelen, name, de)) {
+			status = -EEXIST;
+			goto bail;
+		}
+		if (((le64_to_cpu(de->inode) == 0) &&
+		     (le16_to_cpu(de->rec_len) >= rec_len)) ||
+		    (le16_to_cpu(de->rec_len) >=
+		     (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) {
+			/* Ok, we found a spot. Return this bh and let
+			 * the caller actually fill it in. */
+			*ret_de_bh = bh;
+			get_bh(*ret_de_bh);
+			status = 0;
+			goto bail;
+		}
+		offset += le16_to_cpu(de->rec_len);
+		de = (struct ocfs2_dir_entry *)((char *) de + le16_to_cpu(de->rec_len));
+	}
+
+	status = 0;
+bail:
+	if (bh)
+		brelse(bh);
+
+	mlog_exit(status);
+	return status;
+}
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h
new file mode 100644
index 0000000..5f614ec
--- /dev/null
+++ b/fs/ocfs2/dir.h
@@ -0,0 +1,54 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dir.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_DIR_H
+#define OCFS2_DIR_H
+
+int ocfs2_check_dir_for_entry(struct inode *dir,
+			      const char *name,
+			      int namelen);
+int ocfs2_empty_dir(struct inode *inode);  /* FIXME: to namei.c */
+int ocfs2_find_files_on_disk(const char *name,
+			     int namelen,
+			     u64 *blkno,
+			     struct inode *inode,
+			     struct buffer_head **dirent_bh,
+			     struct ocfs2_dir_entry **dirent);
+int ocfs2_readdir(struct file *filp, void *dirent, filldir_t filldir);
+int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
+				 struct inode *dir,
+				 struct buffer_head *parent_fe_bh,
+				 const char *name,
+				 int namelen,
+				 struct buffer_head **ret_de_bh);
+struct ocfs2_alloc_context;
+int ocfs2_do_extend_dir(struct super_block *sb,
+			struct ocfs2_journal_handle *handle,
+			struct inode *dir,
+			struct buffer_head *parent_fe_bh,
+			struct ocfs2_alloc_context *data_ac,
+			struct ocfs2_alloc_context *meta_ac,
+			struct buffer_head **new_bh);
+#endif /* OCFS2_DIR_H */
diff --git a/fs/ocfs2/dlm/Makefile b/fs/ocfs2/dlm/Makefile
new file mode 100644
index 0000000..ce3f7c2
--- /dev/null
+++ b/fs/ocfs2/dlm/Makefile
@@ -0,0 +1,8 @@
+EXTRA_CFLAGS += -Ifs/ocfs2
+
+obj-$(CONFIG_OCFS2_FS) += ocfs2_dlm.o ocfs2_dlmfs.o
+
+ocfs2_dlm-objs := dlmdomain.o dlmdebug.o dlmthread.o dlmrecovery.o \
+	dlmmaster.o dlmast.o dlmconvert.o dlmlock.o dlmunlock.o dlmver.o
+
+ocfs2_dlmfs-objs := userdlm.o dlmfs.o dlmfsver.o
diff --git a/fs/ocfs2/dlm/dlmapi.h b/fs/ocfs2/dlm/dlmapi.h
new file mode 100644
index 0000000..53652f5
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmapi.h
@@ -0,0 +1,214 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmapi.h
+ *
+ * externally exported dlm interfaces
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef DLMAPI_H
+#define DLMAPI_H
+
+struct dlm_lock;
+struct dlm_ctxt;
+
+/* NOTE: changes made to this enum should be reflected in dlmdebug.c */
+enum dlm_status {
+	DLM_NORMAL = 0,           /*  0: request in progress */
+	DLM_GRANTED,              /*  1: request granted */
+	DLM_DENIED,               /*  2: request denied */
+	DLM_DENIED_NOLOCKS,       /*  3: request denied, out of system resources */
+	DLM_WORKING,              /*  4: async request in progress */
+	DLM_BLOCKED,              /*  5: lock request blocked */
+	DLM_BLOCKED_ORPHAN,       /*  6: lock request blocked by a orphan lock*/
+	DLM_DENIED_GRACE_PERIOD,  /*  7: topological change in progress */
+	DLM_SYSERR,               /*  8: system error */
+	DLM_NOSUPPORT,            /*  9: unsupported */
+	DLM_CANCELGRANT,          /* 10: can't cancel convert: already granted */
+	DLM_IVLOCKID,             /* 11: bad lockid */
+	DLM_SYNC,                 /* 12: synchronous request granted */
+	DLM_BADTYPE,              /* 13: bad resource type */
+	DLM_BADRESOURCE,          /* 14: bad resource handle */
+	DLM_MAXHANDLES,           /* 15: no more resource handles */
+	DLM_NOCLINFO,             /* 16: can't contact cluster manager */
+	DLM_NOLOCKMGR,            /* 17: can't contact lock manager */
+	DLM_NOPURGED,             /* 18: can't contact purge daemon */
+	DLM_BADARGS,              /* 19: bad api args */
+	DLM_VOID,                 /* 20: no status */
+	DLM_NOTQUEUED,            /* 21: NOQUEUE was specified and request failed */
+	DLM_IVBUFLEN,             /* 22: invalid resource name length */
+	DLM_CVTUNGRANT,           /* 23: attempted to convert ungranted lock */
+	DLM_BADPARAM,             /* 24: invalid lock mode specified */
+	DLM_VALNOTVALID,          /* 25: value block has been invalidated */
+	DLM_REJECTED,             /* 26: request rejected, unrecognized client */
+	DLM_ABORT,                /* 27: blocked lock request cancelled */
+	DLM_CANCEL,               /* 28: conversion request cancelled */
+	DLM_IVRESHANDLE,          /* 29: invalid resource handle */
+	DLM_DEADLOCK,             /* 30: deadlock recovery refused this request */
+	DLM_DENIED_NOASTS,        /* 31: failed to allocate AST */
+	DLM_FORWARD,              /* 32: request must wait for primary's response */
+	DLM_TIMEOUT,              /* 33: timeout value for lock has expired */
+	DLM_IVGROUPID,            /* 34: invalid group specification */
+	DLM_VERS_CONFLICT,        /* 35: version conflicts prevent request handling */
+	DLM_BAD_DEVICE_PATH,      /* 36: Locks device does not exist or path wrong */
+	DLM_NO_DEVICE_PERMISSION, /* 37: Client has insufficient pers for device */
+	DLM_NO_CONTROL_DEVICE,    /* 38: Cannot set options on opened device */
+
+	DLM_RECOVERING,           /* 39: extension, allows caller to fail a lock
+				     request if it is being recovered */
+	DLM_MIGRATING,            /* 40: extension, allows caller to fail a lock
+				     request if it is being migrated */
+	DLM_MAXSTATS,             /* 41: upper limit for return code validation */
+};
+
+/* for pretty-printing dlm_status error messages */
+const char *dlm_errmsg(enum dlm_status err);
+/* for pretty-printing dlm_status error names */
+const char *dlm_errname(enum dlm_status err);
+
+/* Eventually the DLM will use standard errno values, but in the
+ * meantime this lets us track dlm errors as they bubble up. When we
+ * bring its error reporting into line with the rest of the stack,
+ * these can just be replaced with calls to mlog_errno. */
+#define dlm_error(st) do {						\
+	if ((st) != DLM_RECOVERING &&					\
+	    (st) != DLM_MIGRATING &&					\
+	    (st) != DLM_FORWARD)					\
+		mlog(ML_ERROR, "dlm status = %s\n", dlm_errname((st)));	\
+} while (0)
+
+#define DLM_LKSB_UNUSED1           0x01  
+#define DLM_LKSB_PUT_LVB           0x02
+#define DLM_LKSB_GET_LVB           0x04
+#define DLM_LKSB_UNUSED2           0x08
+#define DLM_LKSB_UNUSED3           0x10
+#define DLM_LKSB_UNUSED4           0x20
+#define DLM_LKSB_UNUSED5           0x40
+#define DLM_LKSB_UNUSED6           0x80
+
+#define DLM_LVB_LEN  64
+
+/* Callers are only allowed access to the lvb and status members of
+ * this struct. */
+struct dlm_lockstatus {
+	enum dlm_status status;
+	u32 flags;
+	struct dlm_lock *lockid;
+	char lvb[DLM_LVB_LEN];
+};
+
+/* Valid lock modes. */
+#define LKM_IVMODE      (-1)            /* invalid mode */
+#define LKM_NLMODE      0               /* null lock */
+#define LKM_CRMODE      1               /* concurrent read    unsupported */
+#define LKM_CWMODE      2               /* concurrent write   unsupported */
+#define LKM_PRMODE      3               /* protected read */
+#define LKM_PWMODE      4               /* protected write    unsupported */
+#define LKM_EXMODE      5               /* exclusive */
+#define LKM_MAXMODE     5
+#define LKM_MODEMASK    0xff
+
+/* Flags passed to dlmlock and dlmunlock:
+ * reserved: flags used by the "real" dlm
+ * only a few are supported by this dlm
+ * (U) = unsupported by ocfs2 dlm */
+#define LKM_ORPHAN       0x00000010  /* this lock is orphanable (U) */
+#define LKM_PARENTABLE   0x00000020  /* this lock was orphaned (U) */
+#define LKM_BLOCK        0x00000040  /* blocking lock request (U) */
+#define LKM_LOCAL        0x00000080  /* local lock request */
+#define LKM_VALBLK       0x00000100  /* lock value block request */
+#define LKM_NOQUEUE      0x00000200  /* non blocking request */
+#define LKM_CONVERT      0x00000400  /* conversion request */
+#define LKM_NODLCKWT     0x00000800  /* this lock wont deadlock (U) */
+#define LKM_UNLOCK       0x00001000  /* deallocate this lock */
+#define LKM_CANCEL       0x00002000  /* cancel conversion request */
+#define LKM_DEQALL       0x00004000  /* remove all locks held by proc (U) */
+#define LKM_INVVALBLK    0x00008000  /* invalidate lock value block */
+#define LKM_SYNCSTS      0x00010000  /* return synchronous status if poss (U) */
+#define LKM_TIMEOUT      0x00020000  /* lock request contains timeout (U) */
+#define LKM_SNGLDLCK     0x00040000  /* request can self-deadlock (U) */
+#define LKM_FINDLOCAL    0x00080000  /* find local lock request (U) */
+#define LKM_PROC_OWNED   0x00100000  /* owned by process, not group (U) */
+#define LKM_XID          0x00200000  /* use transaction id for deadlock (U) */
+#define LKM_XID_CONFLICT 0x00400000  /* do not allow lock inheritance (U) */
+#define LKM_FORCE        0x00800000  /* force unlock flag */
+#define LKM_REVVALBLK    0x01000000  /* temporary solution: re-validate
+					lock value block (U) */
+/* unused */
+#define LKM_UNUSED1      0x00000001  /* unused */
+#define LKM_UNUSED2      0x00000002  /* unused */
+#define LKM_UNUSED3      0x00000004  /* unused */
+#define LKM_UNUSED4      0x00000008  /* unused */
+#define LKM_UNUSED5      0x02000000  /* unused */
+#define LKM_UNUSED6      0x04000000  /* unused */
+#define LKM_UNUSED7      0x08000000  /* unused */
+
+/* ocfs2 extensions: internal only
+ * should never be used by caller */
+#define LKM_MIGRATION    0x10000000  /* extension: lockres is to be migrated
+					to another node */
+#define LKM_PUT_LVB      0x20000000  /* extension: lvb is being passed
+					should be applied to lockres */
+#define LKM_GET_LVB      0x40000000  /* extension: lvb should be copied
+					from lockres when lock is granted */
+#define LKM_RECOVERY     0x80000000  /* extension: flag for recovery lock
+					used to avoid recovery rwsem */
+
+
+typedef void (dlm_astlockfunc_t)(void *);
+typedef void (dlm_bastlockfunc_t)(void *, int);
+typedef void (dlm_astunlockfunc_t)(void *, enum dlm_status);
+
+enum dlm_status dlmlock(struct dlm_ctxt *dlm,
+			int mode,
+			struct dlm_lockstatus *lksb,
+			int flags,
+			const char *name,
+			dlm_astlockfunc_t *ast,
+			void *data,
+			dlm_bastlockfunc_t *bast);
+
+enum dlm_status dlmunlock(struct dlm_ctxt *dlm,
+			  struct dlm_lockstatus *lksb,
+			  int flags,
+			  dlm_astunlockfunc_t *unlockast,
+			  void *data);
+
+struct dlm_ctxt * dlm_register_domain(const char *domain, u32 key);
+
+void dlm_unregister_domain(struct dlm_ctxt *dlm);
+
+void dlm_print_one_lock(struct dlm_lock *lockid);
+
+typedef void (dlm_eviction_func)(int, void *);
+struct dlm_eviction_cb {
+	struct list_head        ec_item;
+	dlm_eviction_func       *ec_func;
+	void                    *ec_data;
+};
+void dlm_setup_eviction_cb(struct dlm_eviction_cb *cb,
+			   dlm_eviction_func *f,
+			   void *data);
+void dlm_register_eviction_cb(struct dlm_ctxt *dlm,
+			      struct dlm_eviction_cb *cb);
+void dlm_unregister_eviction_cb(struct dlm_eviction_cb *cb);
+
+#endif /* DLMAPI_H */
diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c
new file mode 100644
index 0000000..8d17d28
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmast.c
@@ -0,0 +1,466 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmast.c
+ *
+ * AST and BAST functionality for local and remote nodes
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include <linux/random.h>
+#include <linux/blkdev.h>
+#include <linux/socket.h>
+#include <linux/inet.h>
+#include <linux/spinlock.h>
+
+
+#include "cluster/heartbeat.h"
+#include "cluster/nodemanager.h"
+#include "cluster/tcp.h"
+#include "cluster/endian.h"
+
+#include "dlmapi.h"
+#include "dlmcommon.h"
+
+#define MLOG_MASK_PREFIX ML_DLM
+#include "cluster/masklog.h"
+
+static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
+			   struct dlm_lock *lock);
+static int dlm_should_cancel_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
+
+/* Should be called as an ast gets queued to see if the new
+ * lock level will obsolete a pending bast.
+ * For example, if dlm_thread queued a bast for an EX lock that
+ * was blocking another EX, but before sending the bast the
+ * lock owner downconverted to NL, the bast is now obsolete.
+ * Only the ast should be sent.
+ * This is needed because the lock and convert paths can queue
+ * asts out-of-band (not waiting for dlm_thread) in order to
+ * allow for LKM_NOQUEUE to get immediate responses. */
+static int dlm_should_cancel_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
+{
+	assert_spin_locked(&dlm->ast_lock);
+	assert_spin_locked(&lock->spinlock);
+
+	if (lock->ml.highest_blocked == LKM_IVMODE)
+		return 0;
+	BUG_ON(lock->ml.highest_blocked == LKM_NLMODE);
+
+	if (lock->bast_pending &&
+	    list_empty(&lock->bast_list))
+		/* old bast already sent, ok */
+		return 0;
+
+	if (lock->ml.type == LKM_EXMODE)
+		/* EX blocks anything left, any bast still valid */
+		return 0;
+	else if (lock->ml.type == LKM_NLMODE)
+		/* NL blocks nothing, no reason to send any bast, cancel it */
+		return 1;
+	else if (lock->ml.highest_blocked != LKM_EXMODE)
+		/* PR only blocks EX */
+		return 1;
+
+	return 0;
+}
+
+static void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
+{
+	mlog_entry_void();
+
+	BUG_ON(!dlm);
+	BUG_ON(!lock);
+
+	assert_spin_locked(&dlm->ast_lock);
+	if (!list_empty(&lock->ast_list)) {
+		mlog(ML_ERROR, "ast list not empty!!  pending=%d, newlevel=%d\n",
+		     lock->ast_pending, lock->ml.type);
+		BUG();
+	}
+	BUG_ON(!list_empty(&lock->ast_list));
+	if (lock->ast_pending)
+		mlog(0, "lock has an ast getting flushed right now\n");
+
+	/* putting lock on list, add a ref */
+	dlm_lock_get(lock);
+	spin_lock(&lock->spinlock);
+
+	/* check to see if this ast obsoletes the bast */
+	if (dlm_should_cancel_bast(dlm, lock)) {
+		struct dlm_lock_resource *res = lock->lockres;
+		mlog(0, "%s: cancelling bast for %.*s\n",
+		     dlm->name, res->lockname.len, res->lockname.name);
+		lock->bast_pending = 0;
+		list_del_init(&lock->bast_list);
+		lock->ml.highest_blocked = LKM_IVMODE;
+		/* removing lock from list, remove a ref.  guaranteed
+		 * this won't be the last ref because of the get above,
+		 * so res->spinlock will not be taken here */
+		dlm_lock_put(lock);
+		/* free up the reserved bast that we are cancelling.
+		 * guaranteed that this will not be the last reserved
+		 * ast because *both* an ast and a bast were reserved 
+		 * to get to this point.  the res->spinlock will not be
+		 * taken here */
+		dlm_lockres_release_ast(dlm, res);
+	}
+	list_add_tail(&lock->ast_list, &dlm->pending_asts);
+	lock->ast_pending = 1;
+	spin_unlock(&lock->spinlock);
+}
+
+void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
+{
+	mlog_entry_void();
+
+	BUG_ON(!dlm);
+	BUG_ON(!lock);
+
+	spin_lock(&dlm->ast_lock);
+	__dlm_queue_ast(dlm, lock);
+	spin_unlock(&dlm->ast_lock);
+}
+
+
+static void __dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
+{
+	mlog_entry_void();
+
+	BUG_ON(!dlm);
+	BUG_ON(!lock);
+	assert_spin_locked(&dlm->ast_lock);
+
+	BUG_ON(!list_empty(&lock->bast_list));
+	if (lock->bast_pending)
+		mlog(0, "lock has a bast getting flushed right now\n");
+
+	/* putting lock on list, add a ref */
+	dlm_lock_get(lock);
+	spin_lock(&lock->spinlock);
+	list_add_tail(&lock->bast_list, &dlm->pending_basts);
+	lock->bast_pending = 1;
+	spin_unlock(&lock->spinlock);
+}
+
+void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock)
+{
+	mlog_entry_void();
+
+	BUG_ON(!dlm);
+	BUG_ON(!lock);
+
+	spin_lock(&dlm->ast_lock);
+	__dlm_queue_bast(dlm, lock);
+	spin_unlock(&dlm->ast_lock);
+}
+
+static void dlm_update_lvb(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
+			   struct dlm_lock *lock)
+{
+	struct dlm_lockstatus *lksb = lock->lksb;
+	BUG_ON(!lksb);
+
+	/* only updates if this node masters the lockres */
+	if (res->owner == dlm->node_num) {
+
+		spin_lock(&res->spinlock);
+		/* check the lksb flags for the direction */
+		if (lksb->flags & DLM_LKSB_GET_LVB) {
+			mlog(0, "getting lvb from lockres for %s node\n",
+				  lock->ml.node == dlm->node_num ? "master" :
+				  "remote");
+			memcpy(lksb->lvb, res->lvb, DLM_LVB_LEN);
+		} else if (lksb->flags & DLM_LKSB_PUT_LVB) {
+			mlog(0, "setting lvb from lockres for %s node\n",
+				  lock->ml.node == dlm->node_num ? "master" :
+				  "remote");
+			memcpy(res->lvb, lksb->lvb, DLM_LVB_LEN);
+		}
+		spin_unlock(&res->spinlock);
+	}
+
+	/* reset any lvb flags on the lksb */
+	lksb->flags &= ~(DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB);
+}
+
+void dlm_do_local_ast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
+		      struct dlm_lock *lock)
+{
+	dlm_astlockfunc_t *fn;
+	struct dlm_lockstatus *lksb;
+
+	mlog_entry_void();
+
+	lksb = lock->lksb;
+	fn = lock->ast;
+	BUG_ON(lock->ml.node != dlm->node_num);
+
+	dlm_update_lvb(dlm, res, lock);
+	(*fn)(lock->astdata);
+}
+
+
+int dlm_do_remote_ast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
+		      struct dlm_lock *lock)
+{
+	int ret;
+	struct dlm_lockstatus *lksb;
+	int lksbflags;
+
+	mlog_entry_void();
+
+	lksb = lock->lksb;
+	BUG_ON(lock->ml.node == dlm->node_num);
+
+	lksbflags = lksb->flags;
+	dlm_update_lvb(dlm, res, lock);
+
+	/* lock request came from another node
+	 * go do the ast over there */
+	ret = dlm_send_proxy_ast(dlm, res, lock, lksbflags);
+	return ret;
+}
+
+void dlm_do_local_bast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
+		       struct dlm_lock *lock, int blocked_type)
+{
+	dlm_bastlockfunc_t *fn = lock->bast;
+
+	mlog_entry_void();
+	BUG_ON(lock->ml.node != dlm->node_num);
+
+	(*fn)(lock->astdata, blocked_type);
+}
+
+
+
+int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	int ret;
+	unsigned int locklen;
+	struct dlm_ctxt *dlm = data;
+	struct dlm_lock_resource *res = NULL;
+	struct dlm_lock *lock = NULL;
+	struct dlm_proxy_ast *past = (struct dlm_proxy_ast *) msg->buf;
+	char *name;
+	struct list_head *iter, *head=NULL;
+	u64 cookie;
+	u32 flags;
+
+	if (!dlm_grab(dlm)) {
+		dlm_error(DLM_REJECTED);
+		return DLM_REJECTED;
+	}
+
+	mlog_bug_on_msg(!dlm_domain_fully_joined(dlm),
+			"Domain %s not fully joined!\n", dlm->name);
+
+	name = past->name;
+	locklen = past->namelen;
+	cookie = be64_to_cpu(past->cookie);
+	flags = be32_to_cpu(past->flags);
+
+	if (locklen > DLM_LOCKID_NAME_MAX) {
+		ret = DLM_IVBUFLEN;
+		mlog(ML_ERROR, "Invalid name length in proxy ast handler!\n");
+		goto leave;
+	}
+
+	if ((flags & (LKM_PUT_LVB|LKM_GET_LVB)) ==
+	     (LKM_PUT_LVB|LKM_GET_LVB)) {
+		mlog(ML_ERROR, "both PUT and GET lvb specified\n");
+		ret = DLM_BADARGS;
+		goto leave;
+	}
+
+	mlog(0, "lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" :
+		  (flags & LKM_GET_LVB ? "get lvb" : "none"));
+
+	mlog(0, "type=%d, blocked_type=%d\n", past->type, past->blocked_type);
+
+	if (past->type != DLM_AST &&
+	    past->type != DLM_BAST) {
+		mlog(ML_ERROR, "Unknown ast type! %d, cookie=%"MLFu64", "
+		     "name=%.*s\n", past->type, cookie, locklen, name);
+		ret = DLM_IVLOCKID;
+		goto leave;
+	}
+
+	res = dlm_lookup_lockres(dlm, name, locklen);
+	if (!res) {
+		mlog(ML_ERROR, "got %sast for unknown lockres! "
+			       "cookie=%"MLFu64", name=%.*s, namelen=%u\n",
+		     past->type == DLM_AST ? "" : "b",
+		     cookie, locklen, name, locklen);
+		ret = DLM_IVLOCKID;
+		goto leave;
+	}
+
+	/* cannot get a proxy ast message if this node owns it */
+	BUG_ON(res->owner == dlm->node_num);
+
+	mlog(0, "lockres %.*s\n", res->lockname.len, res->lockname.name);
+
+	spin_lock(&res->spinlock);
+	if (res->state & DLM_LOCK_RES_RECOVERING) {
+		mlog(0, "responding with DLM_RECOVERING!\n");
+		ret = DLM_RECOVERING;
+		goto unlock_out;
+	}
+	if (res->state & DLM_LOCK_RES_MIGRATING) {
+		mlog(0, "responding with DLM_MIGRATING!\n");
+		ret = DLM_MIGRATING;
+		goto unlock_out;
+	}
+	/* try convert queue for both ast/bast */
+	head = &res->converting;
+	lock = NULL;
+	list_for_each(iter, head) {
+		lock = list_entry (iter, struct dlm_lock, list);
+		if (be64_to_cpu(lock->ml.cookie) == cookie)
+			goto do_ast;
+	}
+
+	/* if not on convert, try blocked for ast, granted for bast */
+	if (past->type == DLM_AST)
+		head = &res->blocked;
+	else
+		head = &res->granted;
+
+	list_for_each(iter, head) {
+		lock = list_entry (iter, struct dlm_lock, list);
+		if (be64_to_cpu(lock->ml.cookie) == cookie)
+			goto do_ast;
+	}
+
+	mlog(ML_ERROR, "got %sast for unknown lock!  cookie=%"MLFu64", "
+		       "name=%.*s, namelen=%u\n",
+             past->type == DLM_AST ? "" : "b", cookie, locklen, name, locklen);
+
+	ret = DLM_NORMAL;
+unlock_out:
+	spin_unlock(&res->spinlock);
+	goto leave;
+
+do_ast:
+	ret = DLM_NORMAL;
+	if (past->type == DLM_AST) {
+		/* do not alter lock refcount.  switching lists. */
+		list_del_init(&lock->list);
+		list_add_tail(&lock->list, &res->granted);
+		mlog(0, "ast: adding to granted list... type=%d, "
+			  "convert_type=%d\n", lock->ml.type, lock->ml.convert_type);
+		if (lock->ml.convert_type != LKM_IVMODE) {
+			lock->ml.type = lock->ml.convert_type;
+			lock->ml.convert_type = LKM_IVMODE;
+		} else {
+			// should already be there....
+		}
+
+		lock->lksb->status = DLM_NORMAL;
+
+		/* if we requested the lvb, fetch it into our lksb now */
+		if (flags & LKM_GET_LVB) {
+			BUG_ON(!(lock->lksb->flags & DLM_LKSB_GET_LVB));
+			memcpy(lock->lksb->lvb, past->lvb, DLM_LVB_LEN);
+		}
+	}
+	spin_unlock(&res->spinlock);
+
+	if (past->type == DLM_AST)
+		dlm_do_local_ast(dlm, res, lock);
+	else
+		dlm_do_local_bast(dlm, res, lock, past->blocked_type);
+
+leave:
+
+	if (res)
+		dlm_lockres_put(res);
+
+	dlm_put(dlm);
+	return ret;
+}
+
+
+
+int dlm_send_proxy_ast_msg(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
+			   struct dlm_lock *lock, int msg_type,
+			   int blocked_type, int flags)
+{
+	int ret = 0;
+	struct dlm_proxy_ast past;
+	struct kvec vec[2];
+	size_t veclen = 1;
+	int status;
+
+	mlog_entry("res %.*s, to=%u, type=%d, blocked_type=%d\n",
+		   res->lockname.len, res->lockname.name, lock->ml.node,
+		   msg_type, blocked_type);
+
+	memset(&past, 0, sizeof(struct dlm_proxy_ast));
+	past.node_idx = dlm->node_num;
+	past.type = msg_type;
+	past.blocked_type = blocked_type;
+	past.namelen = res->lockname.len;
+	memcpy(past.name, res->lockname.name, past.namelen);
+	past.cookie = lock->ml.cookie;
+
+	vec[0].iov_len = sizeof(struct dlm_proxy_ast);
+	vec[0].iov_base = &past;
+	if (flags & DLM_LKSB_GET_LVB) {
+		mlog(0, "returning requested LVB data\n");
+		be32_add_cpu(&past.flags, LKM_GET_LVB);
+		vec[1].iov_len = DLM_LVB_LEN;
+		vec[1].iov_base = lock->lksb->lvb;
+		veclen++;
+	}
+
+	ret = o2net_send_message_vec(DLM_PROXY_AST_MSG, dlm->key, vec, veclen,
+				     lock->ml.node, &status);
+	if (ret < 0)
+		mlog_errno(ret);
+	else {
+		if (status == DLM_RECOVERING) {
+			mlog(ML_ERROR, "sent AST to node %u, it thinks this "
+			     "node is dead!\n", lock->ml.node);
+			BUG();
+		} else if (status == DLM_MIGRATING) {
+			mlog(ML_ERROR, "sent AST to node %u, it returned "
+			     "DLM_MIGRATING!\n", lock->ml.node);
+			BUG();
+		} else if (status != DLM_NORMAL) {
+			mlog(ML_ERROR, "AST to node %u returned %d!\n",
+			     lock->ml.node, status);
+			/* ignore it */
+		}
+		ret = 0;
+	}
+	return ret;
+}
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
new file mode 100644
index 0000000..3fecba0
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -0,0 +1,884 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmcommon.h
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef DLMCOMMON_H
+#define DLMCOMMON_H
+
+#include <linux/kref.h>
+
+#define DLM_HB_NODE_DOWN_PRI     (0xf000000)
+#define DLM_HB_NODE_UP_PRI       (0x8000000)
+
+#define DLM_LOCKID_NAME_MAX    32
+
+#define DLM_DOMAIN_NAME_MAX_LEN    255
+#define DLM_LOCK_RES_OWNER_UNKNOWN     O2NM_MAX_NODES
+#define DLM_THREAD_SHUFFLE_INTERVAL    5     // flush everything every 5 passes
+#define DLM_THREAD_MS                  200   // flush at least every 200 ms
+
+#define DLM_HASH_BITS     7
+#define DLM_HASH_SIZE     (1 << DLM_HASH_BITS)
+#define DLM_HASH_MASK     (DLM_HASH_SIZE - 1)
+
+enum dlm_ast_type {
+	DLM_AST = 0,
+	DLM_BAST,
+	DLM_ASTUNLOCK
+};
+
+
+#define LKM_VALID_FLAGS (LKM_VALBLK | LKM_CONVERT | LKM_UNLOCK | \
+			 LKM_CANCEL | LKM_INVVALBLK | LKM_FORCE | \
+			 LKM_RECOVERY | LKM_LOCAL | LKM_NOQUEUE)
+
+#define DLM_RECOVERY_LOCK_NAME       "$RECOVERY"
+#define DLM_RECOVERY_LOCK_NAME_LEN   9
+
+static inline int dlm_is_recovery_lock(const char *lock_name, int name_len)
+{
+	if (name_len == DLM_RECOVERY_LOCK_NAME_LEN &&
+	    memcmp(lock_name, DLM_RECOVERY_LOCK_NAME, name_len)==0)
+		return 1;
+	return 0;
+}
+
+#define DLM_RECO_STATE_ACTIVE  0x0001
+
+struct dlm_recovery_ctxt
+{
+	struct list_head resources;
+	struct list_head received;
+	struct list_head node_data;
+	u8  new_master;
+	u8  dead_node;
+	u16 state;
+	unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	wait_queue_head_t event;
+};
+
+enum dlm_ctxt_state {
+	DLM_CTXT_NEW = 0,
+	DLM_CTXT_JOINED,
+	DLM_CTXT_IN_SHUTDOWN,
+	DLM_CTXT_LEAVING,
+};
+
+struct dlm_ctxt
+{
+	struct list_head list;
+	struct list_head *resources;
+	struct list_head dirty_list;
+	struct list_head purge_list;
+	struct list_head pending_asts;
+	struct list_head pending_basts;
+	unsigned int purge_count;
+	spinlock_t spinlock;
+	spinlock_t ast_lock;
+	char *name;
+	u8 node_num;
+	u32 key;
+	u8  joining_node;
+	wait_queue_head_t dlm_join_events;
+	unsigned long live_nodes_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	unsigned long domain_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	unsigned long recovery_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	struct dlm_recovery_ctxt reco;
+	spinlock_t master_lock;
+	struct list_head master_list;
+	struct list_head mle_hb_events;
+
+	/* these give a really vague idea of the system load */
+	atomic_t local_resources;
+	atomic_t remote_resources;
+	atomic_t unknown_resources;
+
+	/* NOTE: Next three are protected by dlm_domain_lock */
+	struct kref dlm_refs;
+	enum dlm_ctxt_state dlm_state;
+	unsigned int num_joins;
+
+	struct o2hb_callback_func dlm_hb_up;
+	struct o2hb_callback_func dlm_hb_down;
+	struct task_struct *dlm_thread_task;
+	struct task_struct *dlm_reco_thread_task;
+	wait_queue_head_t dlm_thread_wq;
+	wait_queue_head_t dlm_reco_thread_wq;
+	wait_queue_head_t ast_wq;
+	wait_queue_head_t migration_wq;
+
+	struct work_struct dispatched_work;
+	struct list_head work_list;
+	spinlock_t work_lock;
+	struct list_head dlm_domain_handlers;
+	struct list_head	dlm_eviction_callbacks;
+};
+
+/* these keventd work queue items are for less-frequently
+ * called functions that cannot be directly called from the
+ * net message handlers for some reason, usually because
+ * they need to send net messages of their own. */
+void dlm_dispatch_work(void *data);
+
+struct dlm_lock_resource;
+struct dlm_work_item;
+
+typedef void (dlm_workfunc_t)(struct dlm_work_item *, void *);
+
+struct dlm_request_all_locks_priv
+{
+	u8 reco_master;
+	u8 dead_node;
+};
+
+struct dlm_mig_lockres_priv
+{
+	struct dlm_lock_resource *lockres;
+	u8 real_master;
+};
+
+struct dlm_assert_master_priv
+{
+	struct dlm_lock_resource *lockres;
+	u8 request_from;
+	u32 flags;
+	unsigned ignore_higher:1;
+};
+
+
+struct dlm_work_item
+{
+	struct list_head list;
+	dlm_workfunc_t *func;
+	struct dlm_ctxt *dlm;
+	void *data;
+	union {
+		struct dlm_request_all_locks_priv ral;
+		struct dlm_mig_lockres_priv ml;
+		struct dlm_assert_master_priv am;
+	} u;
+};
+
+static inline void dlm_init_work_item(struct dlm_ctxt *dlm,
+				      struct dlm_work_item *i,
+				      dlm_workfunc_t *f, void *data)
+{
+	memset(i, 0, sizeof(*i));
+	i->func = f;
+	INIT_LIST_HEAD(&i->list);
+	i->data = data;
+	i->dlm = dlm;  /* must have already done a dlm_grab on this! */
+}
+
+
+
+static inline void __dlm_set_joining_node(struct dlm_ctxt *dlm,
+					  u8 node)
+{
+	assert_spin_locked(&dlm->spinlock);
+
+	dlm->joining_node = node;
+	wake_up(&dlm->dlm_join_events);
+}
+
+#define DLM_LOCK_RES_UNINITED             0x00000001
+#define DLM_LOCK_RES_RECOVERING           0x00000002
+#define DLM_LOCK_RES_READY                0x00000004
+#define DLM_LOCK_RES_DIRTY                0x00000008
+#define DLM_LOCK_RES_IN_PROGRESS          0x00000010
+#define DLM_LOCK_RES_MIGRATING            0x00000020
+
+#define DLM_PURGE_INTERVAL_MS   (8 * 1000)
+
+struct dlm_lock_resource
+{
+	/* WARNING: Please see the comment in dlm_init_lockres before
+	 * adding fields here. */
+	struct list_head list;
+	struct kref      refs;
+
+	/* please keep these next 3 in this order
+	 * some funcs want to iterate over all lists */
+	struct list_head granted;
+	struct list_head converting;
+	struct list_head blocked;
+
+	struct list_head dirty;
+	struct list_head recovering; // dlm_recovery_ctxt.resources list
+
+	/* unused lock resources have their last_used stamped and are
+	 * put on a list for the dlm thread to run. */
+	struct list_head purge;
+	unsigned long    last_used;
+
+	unsigned migration_pending:1;
+	atomic_t asts_reserved;
+	spinlock_t spinlock;
+	wait_queue_head_t wq;
+	u8  owner;              //node which owns the lock resource, or unknown
+	u16 state;
+	struct qstr lockname;
+	char lvb[DLM_LVB_LEN];
+};
+
+struct dlm_migratable_lock
+{
+	__be64 cookie;
+
+	/* these 3 are just padding for the in-memory structure, but
+	 * list and flags are actually used when sent over the wire */
+	__be16 pad1;
+	u8 list;  // 0=granted, 1=converting, 2=blocked
+	u8 flags;
+
+	s8 type;
+	s8 convert_type;
+	s8 highest_blocked;
+	u8 node;
+};  // 16 bytes
+
+struct dlm_lock
+{
+	struct dlm_migratable_lock ml;
+
+	struct list_head list;
+	struct list_head ast_list;
+	struct list_head bast_list;
+	struct dlm_lock_resource *lockres;
+	spinlock_t spinlock;
+	struct kref lock_refs;
+
+	// ast and bast must be callable while holding a spinlock!
+	dlm_astlockfunc_t *ast;
+	dlm_bastlockfunc_t *bast;
+	void *astdata;
+	struct dlm_lockstatus *lksb;
+	unsigned ast_pending:1,
+		 bast_pending:1,
+		 convert_pending:1,
+		 lock_pending:1,
+		 cancel_pending:1,
+		 unlock_pending:1,
+		 lksb_kernel_allocated:1;
+};
+
+
+#define DLM_LKSB_UNUSED1           0x01
+#define DLM_LKSB_PUT_LVB           0x02
+#define DLM_LKSB_GET_LVB           0x04
+#define DLM_LKSB_UNUSED2           0x08
+#define DLM_LKSB_UNUSED3           0x10
+#define DLM_LKSB_UNUSED4           0x20
+#define DLM_LKSB_UNUSED5           0x40
+#define DLM_LKSB_UNUSED6           0x80
+
+
+enum dlm_lockres_list {
+	DLM_GRANTED_LIST = 0,
+	DLM_CONVERTING_LIST,
+	DLM_BLOCKED_LIST
+};
+
+static inline struct list_head *
+dlm_list_idx_to_ptr(struct dlm_lock_resource *res, enum dlm_lockres_list idx)
+{
+	struct list_head *ret = NULL;
+	if (idx == DLM_GRANTED_LIST)
+		ret = &res->granted;
+	else if (idx == DLM_CONVERTING_LIST)
+		ret = &res->converting;
+	else if (idx == DLM_BLOCKED_LIST)
+		ret = &res->blocked;
+	else
+		BUG();
+	return ret;
+}
+
+
+
+
+struct dlm_node_iter
+{
+	unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	int curnode;
+};
+
+
+enum {
+	DLM_MASTER_REQUEST_MSG    = 500,
+	DLM_UNUSED_MSG1,         /* 501 */
+	DLM_ASSERT_MASTER_MSG,	 /* 502 */
+	DLM_CREATE_LOCK_MSG,	 /* 503 */
+	DLM_CONVERT_LOCK_MSG,	 /* 504 */
+	DLM_PROXY_AST_MSG,	 /* 505 */
+	DLM_UNLOCK_LOCK_MSG,	 /* 506 */
+	DLM_UNUSED_MSG2,	 /* 507 */
+	DLM_MIGRATE_REQUEST_MSG, /* 508 */
+	DLM_MIG_LOCKRES_MSG, 	 /* 509 */
+	DLM_QUERY_JOIN_MSG,	 /* 510 */
+	DLM_ASSERT_JOINED_MSG,	 /* 511 */
+	DLM_CANCEL_JOIN_MSG,	 /* 512 */
+	DLM_EXIT_DOMAIN_MSG,	 /* 513 */
+	DLM_MASTER_REQUERY_MSG,	 /* 514 */
+	DLM_LOCK_REQUEST_MSG,	 /* 515 */
+	DLM_RECO_DATA_DONE_MSG,	 /* 516 */
+	DLM_BEGIN_RECO_MSG,	 /* 517 */
+	DLM_FINALIZE_RECO_MSG	 /* 518 */
+};
+
+struct dlm_reco_node_data
+{
+	int state;
+	u8 node_num;
+	struct list_head list;
+};
+
+enum {
+	DLM_RECO_NODE_DATA_DEAD = -1,
+	DLM_RECO_NODE_DATA_INIT = 0,
+	DLM_RECO_NODE_DATA_REQUESTING,
+	DLM_RECO_NODE_DATA_REQUESTED,
+	DLM_RECO_NODE_DATA_RECEIVING,
+	DLM_RECO_NODE_DATA_DONE,
+	DLM_RECO_NODE_DATA_FINALIZE_SENT,
+};
+
+
+enum {
+	DLM_MASTER_RESP_NO = 0,
+	DLM_MASTER_RESP_YES,
+	DLM_MASTER_RESP_MAYBE,
+	DLM_MASTER_RESP_ERROR
+};
+
+
+struct dlm_master_request
+{
+	u8 node_idx;
+	u8 namelen;
+	__be16 pad1;
+	__be32 flags;
+
+	u8 name[O2NM_MAX_NAME_LEN];
+};
+
+#define DLM_ASSERT_MASTER_MLE_CLEANUP      0x00000001
+#define DLM_ASSERT_MASTER_REQUERY          0x00000002
+#define DLM_ASSERT_MASTER_FINISH_MIGRATION 0x00000004
+struct dlm_assert_master
+{
+	u8 node_idx;
+	u8 namelen;
+	__be16 pad1;
+	__be32 flags;
+
+	u8 name[O2NM_MAX_NAME_LEN];
+};
+
+struct dlm_migrate_request
+{
+	u8 master;
+	u8 new_master;
+	u8 namelen;
+	u8 pad1;
+	__be32 pad2;
+	u8 name[O2NM_MAX_NAME_LEN];
+};
+
+struct dlm_master_requery
+{
+	u8 pad1;
+	u8 pad2;
+	u8 node_idx;
+	u8 namelen;
+	__be32 pad3;
+	u8 name[O2NM_MAX_NAME_LEN];
+};
+
+#define DLM_MRES_RECOVERY   0x01
+#define DLM_MRES_MIGRATION  0x02
+#define DLM_MRES_ALL_DONE   0x04
+
+/*
+ * We would like to get one whole lockres into a single network
+ * message whenever possible.  Generally speaking, there will be
+ * at most one dlm_lock on a lockres for each node in the cluster,
+ * plus (infrequently) any additional locks coming in from userdlm.
+ *
+ * struct _dlm_lockres_page
+ * {
+ * 	dlm_migratable_lockres mres;
+ * 	dlm_migratable_lock ml[DLM_MAX_MIGRATABLE_LOCKS];
+ * 	u8 pad[DLM_MIG_LOCKRES_RESERVED];
+ * };
+ *
+ * from ../cluster/tcp.h
+ *    NET_MAX_PAYLOAD_BYTES  (4096 - sizeof(net_msg))
+ *    (roughly 4080 bytes)
+ * and sizeof(dlm_migratable_lockres) = 112 bytes
+ * and sizeof(dlm_migratable_lock) = 16 bytes
+ *
+ * Choosing DLM_MAX_MIGRATABLE_LOCKS=240 and
+ * DLM_MIG_LOCKRES_RESERVED=128 means we have this:
+ *
+ *  (DLM_MAX_MIGRATABLE_LOCKS * sizeof(dlm_migratable_lock)) +
+ *     sizeof(dlm_migratable_lockres) + DLM_MIG_LOCKRES_RESERVED =
+ *        NET_MAX_PAYLOAD_BYTES
+ *  (240 * 16) + 112 + 128 = 4080
+ *
+ * So a lockres would need more than 240 locks before it would
+ * use more than one network packet to recover.  Not too bad.
+ */
+#define DLM_MAX_MIGRATABLE_LOCKS   240
+
+struct dlm_migratable_lockres
+{
+	u8 master;
+	u8 lockname_len;
+	u8 num_locks;    // locks sent in this structure
+	u8 flags;
+	__be32 total_locks; // locks to be sent for this migration cookie
+	__be64 mig_cookie;  // cookie for this lockres migration
+			 // or zero if not needed
+	// 16 bytes
+	u8 lockname[DLM_LOCKID_NAME_MAX];
+	// 48 bytes
+	u8 lvb[DLM_LVB_LEN];
+	// 112 bytes
+	struct dlm_migratable_lock ml[0];  // 16 bytes each, begins at byte 112
+};
+#define DLM_MIG_LOCKRES_MAX_LEN  \
+	(sizeof(struct dlm_migratable_lockres) + \
+	 (sizeof(struct dlm_migratable_lock) * \
+	  DLM_MAX_MIGRATABLE_LOCKS) )
+
+/* from above, 128 bytes
+ * for some undetermined future use */
+#define DLM_MIG_LOCKRES_RESERVED   (NET_MAX_PAYLOAD_BYTES - \
+				    DLM_MIG_LOCKRES_MAX_LEN)
+
+struct dlm_create_lock
+{
+	__be64 cookie;
+
+	__be32 flags;
+	u8 pad1;
+	u8 node_idx;
+	s8 requested_type;
+	u8 namelen;
+
+	u8 name[O2NM_MAX_NAME_LEN];
+};
+
+struct dlm_convert_lock
+{
+	__be64 cookie;
+
+	__be32 flags;
+	u8 pad1;
+	u8 node_idx;
+	s8 requested_type;
+	u8 namelen;
+
+	u8 name[O2NM_MAX_NAME_LEN];
+
+	s8 lvb[0];
+};
+#define DLM_CONVERT_LOCK_MAX_LEN  (sizeof(struct dlm_convert_lock)+DLM_LVB_LEN)
+
+struct dlm_unlock_lock
+{
+	__be64 cookie;
+
+	__be32 flags;
+	__be16 pad1;
+	u8 node_idx;
+	u8 namelen;
+
+	u8 name[O2NM_MAX_NAME_LEN];
+
+	s8 lvb[0];
+};
+#define DLM_UNLOCK_LOCK_MAX_LEN  (sizeof(struct dlm_unlock_lock)+DLM_LVB_LEN)
+
+struct dlm_proxy_ast
+{
+	__be64 cookie;
+
+	__be32 flags;
+	u8 node_idx;
+	u8 type;
+	u8 blocked_type;
+	u8 namelen;
+
+	u8 name[O2NM_MAX_NAME_LEN];
+
+	s8 lvb[0];
+};
+#define DLM_PROXY_AST_MAX_LEN  (sizeof(struct dlm_proxy_ast)+DLM_LVB_LEN)
+
+#define DLM_MOD_KEY (0x666c6172)
+enum dlm_query_join_response {
+	JOIN_DISALLOW = 0,
+	JOIN_OK,
+	JOIN_OK_NO_MAP,
+};
+
+struct dlm_lock_request
+{
+	u8 node_idx;
+	u8 dead_node;
+	__be16 pad1;
+	__be32 pad2;
+};
+
+struct dlm_reco_data_done
+{
+	u8 node_idx;
+	u8 dead_node;
+	__be16 pad1;
+	__be32 pad2;
+
+	/* unused for now */
+	/* eventually we can use this to attempt
+	 * lvb recovery based on each node's info */
+	u8 reco_lvb[DLM_LVB_LEN];
+};
+
+struct dlm_begin_reco
+{
+	u8 node_idx;
+	u8 dead_node;
+	__be16 pad1;
+	__be32 pad2;
+};
+
+
+struct dlm_query_join_request
+{
+	u8 node_idx;
+	u8 pad1[2];
+	u8 name_len;
+	u8 domain[O2NM_MAX_NAME_LEN];
+};
+
+struct dlm_assert_joined
+{
+	u8 node_idx;
+	u8 pad1[2];
+	u8 name_len;
+	u8 domain[O2NM_MAX_NAME_LEN];
+};
+
+struct dlm_cancel_join
+{
+	u8 node_idx;
+	u8 pad1[2];
+	u8 name_len;
+	u8 domain[O2NM_MAX_NAME_LEN];
+};
+
+struct dlm_exit_domain
+{
+	u8 node_idx;
+	u8 pad1[3];
+};
+
+struct dlm_finalize_reco
+{
+	u8 node_idx;
+	u8 dead_node;
+	__be16 pad1;
+	__be32 pad2;
+};
+
+static inline enum dlm_status
+__dlm_lockres_state_to_status(struct dlm_lock_resource *res)
+{
+	enum dlm_status status = DLM_NORMAL;
+
+	assert_spin_locked(&res->spinlock);
+
+	if (res->state & DLM_LOCK_RES_RECOVERING)
+		status = DLM_RECOVERING;
+	else if (res->state & DLM_LOCK_RES_MIGRATING)
+		status = DLM_MIGRATING;
+	else if (res->state & DLM_LOCK_RES_IN_PROGRESS)
+		status = DLM_FORWARD;
+
+	return status;
+}
+
+struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
+			       struct dlm_lockstatus *lksb);
+void dlm_lock_get(struct dlm_lock *lock);
+void dlm_lock_put(struct dlm_lock *lock);
+
+void dlm_lock_attach_lockres(struct dlm_lock *lock,
+			     struct dlm_lock_resource *res);
+
+int dlm_create_lock_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data);
+
+void dlm_revert_pending_convert(struct dlm_lock_resource *res,
+				struct dlm_lock *lock);
+void dlm_revert_pending_lock(struct dlm_lock_resource *res,
+			     struct dlm_lock *lock);
+
+int dlm_unlock_lock_handler(struct o2net_msg *msg, u32 len, void *data);
+void dlm_commit_pending_cancel(struct dlm_lock_resource *res,
+			       struct dlm_lock *lock);
+void dlm_commit_pending_unlock(struct dlm_lock_resource *res,
+			       struct dlm_lock *lock);
+
+int dlm_launch_thread(struct dlm_ctxt *dlm);
+void dlm_complete_thread(struct dlm_ctxt *dlm);
+int dlm_launch_recovery_thread(struct dlm_ctxt *dlm);
+void dlm_complete_recovery_thread(struct dlm_ctxt *dlm);
+void dlm_wait_for_recovery(struct dlm_ctxt *dlm);
+
+void dlm_put(struct dlm_ctxt *dlm);
+struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm);
+int dlm_domain_fully_joined(struct dlm_ctxt *dlm);
+
+void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
+			      struct dlm_lock_resource *res);
+void dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
+			    struct dlm_lock_resource *res);
+void dlm_purge_lockres(struct dlm_ctxt *dlm,
+		       struct dlm_lock_resource *lockres);
+void dlm_lockres_get(struct dlm_lock_resource *res);
+void dlm_lockres_put(struct dlm_lock_resource *res);
+void __dlm_unhash_lockres(struct dlm_lock_resource *res);
+void __dlm_insert_lockres(struct dlm_ctxt *dlm,
+			  struct dlm_lock_resource *res);
+struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
+						const char *name,
+						unsigned int len);
+struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm,
+					      const char *name,
+					      unsigned int len);
+
+int dlm_is_host_down(int errno);
+void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
+			      struct dlm_lock_resource *res,
+			      u8 owner);
+struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
+						 const char *lockid,
+						 int flags);
+struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
+					  const char *name,
+					  unsigned int namelen);
+
+void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
+void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock);
+void dlm_do_local_ast(struct dlm_ctxt *dlm,
+		      struct dlm_lock_resource *res,
+		      struct dlm_lock *lock);
+int dlm_do_remote_ast(struct dlm_ctxt *dlm,
+		      struct dlm_lock_resource *res,
+		      struct dlm_lock *lock);
+void dlm_do_local_bast(struct dlm_ctxt *dlm,
+		       struct dlm_lock_resource *res,
+		       struct dlm_lock *lock,
+		       int blocked_type);
+int dlm_send_proxy_ast_msg(struct dlm_ctxt *dlm,
+			   struct dlm_lock_resource *res,
+			   struct dlm_lock *lock,
+			   int msg_type,
+			   int blocked_type, int flags);
+static inline int dlm_send_proxy_bast(struct dlm_ctxt *dlm,
+				      struct dlm_lock_resource *res,
+				      struct dlm_lock *lock,
+				      int blocked_type)
+{
+	return dlm_send_proxy_ast_msg(dlm, res, lock, DLM_BAST,
+				      blocked_type, 0);
+}
+
+static inline int dlm_send_proxy_ast(struct dlm_ctxt *dlm,
+				     struct dlm_lock_resource *res,
+				     struct dlm_lock *lock,
+				     int flags)
+{
+	return dlm_send_proxy_ast_msg(dlm, res, lock, DLM_AST,
+				      0, flags);
+}
+
+void dlm_print_one_lock_resource(struct dlm_lock_resource *res);
+void __dlm_print_one_lock_resource(struct dlm_lock_resource *res);
+
+u8 dlm_nm_this_node(struct dlm_ctxt *dlm);
+void dlm_kick_thread(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
+void __dlm_dirty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
+
+
+int dlm_nm_init(struct dlm_ctxt *dlm);
+int dlm_heartbeat_init(struct dlm_ctxt *dlm);
+void dlm_hb_node_down_cb(struct o2nm_node *node, int idx, void *data);
+void dlm_hb_node_up_cb(struct o2nm_node *node, int idx, void *data);
+
+int dlm_lockres_is_dirty(struct dlm_ctxt *dlm, struct dlm_lock_resource *res);
+int dlm_migrate_lockres(struct dlm_ctxt *dlm,
+			struct dlm_lock_resource *res,
+			u8 target);
+int dlm_finish_migration(struct dlm_ctxt *dlm,
+			 struct dlm_lock_resource *res,
+			 u8 old_master);
+void dlm_lockres_release_ast(struct dlm_ctxt *dlm,
+			     struct dlm_lock_resource *res);
+void __dlm_lockres_reserve_ast(struct dlm_lock_resource *res);
+
+int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_reco_data_done_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data);
+int dlm_finalize_reco_handler(struct o2net_msg *msg, u32 len, void *data);
+
+int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
+			       struct dlm_lock_resource *res,
+			       int ignore_higher,
+			       u8 request_from,
+			       u32 flags);
+
+
+int dlm_send_one_lockres(struct dlm_ctxt *dlm,
+			 struct dlm_lock_resource *res,
+			 struct dlm_migratable_lockres *mres,
+			 u8 send_to,
+			 u8 flags);
+void dlm_move_lockres_to_recovery_list(struct dlm_ctxt *dlm,
+				       struct dlm_lock_resource *res);
+
+/* will exit holding res->spinlock, but may drop in function */
+void __dlm_wait_on_lockres_flags(struct dlm_lock_resource *res, int flags);
+void __dlm_wait_on_lockres_flags_set(struct dlm_lock_resource *res, int flags);
+
+/* will exit holding res->spinlock, but may drop in function */
+static inline void __dlm_wait_on_lockres(struct dlm_lock_resource *res)
+{
+	__dlm_wait_on_lockres_flags(res, (DLM_LOCK_RES_IN_PROGRESS|
+				    	  DLM_LOCK_RES_RECOVERING|
+					  DLM_LOCK_RES_MIGRATING));
+}
+
+
+int dlm_init_mle_cache(void);
+void dlm_destroy_mle_cache(void);
+void dlm_hb_event_notify_attached(struct dlm_ctxt *dlm, int idx, int node_up);
+void dlm_clean_master_list(struct dlm_ctxt *dlm,
+			   u8 dead_node);
+int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock);
+
+
+static inline const char * dlm_lock_mode_name(int mode)
+{
+	switch (mode) {
+		case LKM_EXMODE:
+			return "EX";
+		case LKM_PRMODE:
+			return "PR";
+		case LKM_NLMODE:
+			return "NL";
+	}
+	return "UNKNOWN";
+}
+
+
+static inline int dlm_lock_compatible(int existing, int request)
+{
+	/* NO_LOCK compatible with all */
+	if (request == LKM_NLMODE ||
+	    existing == LKM_NLMODE)
+		return 1;
+
+	/* EX incompatible with all non-NO_LOCK */
+	if (request == LKM_EXMODE)
+		return 0;
+
+	/* request must be PR, which is compatible with PR */
+	if (existing == LKM_PRMODE)
+		return 1;
+
+	return 0;
+}
+
+static inline int dlm_lock_on_list(struct list_head *head,
+				   struct dlm_lock *lock)
+{
+	struct list_head *iter;
+	struct dlm_lock *tmplock;
+
+	list_for_each(iter, head) {
+		tmplock = list_entry(iter, struct dlm_lock, list);
+		if (tmplock == lock)
+			return 1;
+	}
+	return 0;
+}
+
+
+static inline enum dlm_status dlm_err_to_dlm_status(int err)
+{
+	enum dlm_status ret;
+	if (err == -ENOMEM)
+		ret = DLM_SYSERR;
+	else if (err == -ETIMEDOUT || o2net_link_down(err, NULL))
+		ret = DLM_NOLOCKMGR;
+	else if (err == -EINVAL)
+		ret = DLM_BADPARAM;
+	else if (err == -ENAMETOOLONG)
+		ret = DLM_IVBUFLEN;
+	else
+		ret = DLM_BADARGS;
+	return ret;
+}
+
+
+static inline void dlm_node_iter_init(unsigned long *map,
+				      struct dlm_node_iter *iter)
+{
+	memcpy(iter->node_map, map, sizeof(iter->node_map));
+	iter->curnode = -1;
+}
+
+static inline int dlm_node_iter_next(struct dlm_node_iter *iter)
+{
+	int bit;
+	bit = find_next_bit(iter->node_map, O2NM_MAX_NODES, iter->curnode+1);
+	if (bit >= O2NM_MAX_NODES) {
+		iter->curnode = O2NM_MAX_NODES;
+		return -ENOENT;
+	}
+	iter->curnode = bit;
+	return bit;
+}
+
+
+
+#endif /* DLMCOMMON_H */
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c
new file mode 100644
index 0000000..6001b22
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmconvert.c
@@ -0,0 +1,530 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmconvert.c
+ *
+ * underlying calls for lock conversion
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include <linux/random.h>
+#include <linux/blkdev.h>
+#include <linux/socket.h>
+#include <linux/inet.h>
+#include <linux/spinlock.h>
+
+
+#include "cluster/heartbeat.h"
+#include "cluster/nodemanager.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+#include "dlmcommon.h"
+
+#include "dlmconvert.h"
+
+#define MLOG_MASK_PREFIX ML_DLM
+#include "cluster/masklog.h"
+
+/* NOTE: __dlmconvert_master is the only function in here that
+ * needs a spinlock held on entry (res->spinlock) and it is the
+ * only one that holds a lock on exit (res->spinlock).
+ * All other functions in here need no locks and drop all of
+ * the locks that they acquire. */
+static enum dlm_status __dlmconvert_master(struct dlm_ctxt *dlm,
+					   struct dlm_lock_resource *res,
+					   struct dlm_lock *lock, int flags,
+					   int type, int *call_ast,
+					   int *kick_thread);
+static enum dlm_status dlm_send_remote_convert_request(struct dlm_ctxt *dlm,
+					   struct dlm_lock_resource *res,
+					   struct dlm_lock *lock, int flags, int type);
+
+/*
+ * this is only called directly by dlmlock(), and only when the
+ * local node is the owner of the lockres
+ * locking:
+ *   caller needs:  none
+ *   taken:         takes and drops res->spinlock
+ *   held on exit:  none
+ * returns: see __dlmconvert_master
+ */
+enum dlm_status dlmconvert_master(struct dlm_ctxt *dlm,
+				  struct dlm_lock_resource *res,
+				  struct dlm_lock *lock, int flags, int type)
+{
+	int call_ast = 0, kick_thread = 0;
+	enum dlm_status status;
+
+	spin_lock(&res->spinlock);
+	/* we are not in a network handler, this is fine */
+	__dlm_wait_on_lockres(res);
+	__dlm_lockres_reserve_ast(res);
+	res->state |= DLM_LOCK_RES_IN_PROGRESS;
+
+	status = __dlmconvert_master(dlm, res, lock, flags, type,
+				     &call_ast, &kick_thread);
+
+	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
+	spin_unlock(&res->spinlock);
+	wake_up(&res->wq);
+	if (status != DLM_NORMAL && status != DLM_NOTQUEUED)
+		dlm_error(status);
+
+	/* either queue the ast or release it */
+	if (call_ast)
+		dlm_queue_ast(dlm, lock);
+	else
+		dlm_lockres_release_ast(dlm, res);
+
+	if (kick_thread)
+		dlm_kick_thread(dlm, res);
+
+	return status;
+}
+
+/* performs lock conversion at the lockres master site
+ * locking:
+ *   caller needs:  res->spinlock
+ *   taken:         takes and drops lock->spinlock
+ *   held on exit:  res->spinlock
+ * returns: DLM_NORMAL, DLM_NOTQUEUED, DLM_DENIED
+ *   call_ast: whether ast should be called for this lock
+ *   kick_thread: whether dlm_kick_thread should be called
+ */
+static enum dlm_status __dlmconvert_master(struct dlm_ctxt *dlm,
+					   struct dlm_lock_resource *res,
+					   struct dlm_lock *lock, int flags,
+					   int type, int *call_ast,
+					   int *kick_thread)
+{
+	enum dlm_status status = DLM_NORMAL;
+	struct list_head *iter;
+	struct dlm_lock *tmplock=NULL;
+
+	assert_spin_locked(&res->spinlock);
+
+	mlog_entry("type=%d, convert_type=%d, new convert_type=%d\n",
+		   lock->ml.type, lock->ml.convert_type, type);
+
+	spin_lock(&lock->spinlock);
+
+	/* already converting? */
+	if (lock->ml.convert_type != LKM_IVMODE) {
+		mlog(ML_ERROR, "attempted to convert a lock with a lock "
+		     "conversion pending\n");
+		status = DLM_DENIED;
+		goto unlock_exit;
+	}
+
+	/* must be on grant queue to convert */
+	if (!dlm_lock_on_list(&res->granted, lock)) {
+		mlog(ML_ERROR, "attempted to convert a lock not on grant "
+		     "queue\n");
+		status = DLM_DENIED;
+		goto unlock_exit;
+	}
+
+	if (flags & LKM_VALBLK) {
+		switch (lock->ml.type) {
+			case LKM_EXMODE:
+				/* EX + LKM_VALBLK + convert == set lvb */
+				mlog(0, "will set lvb: converting %s->%s\n",
+				     dlm_lock_mode_name(lock->ml.type),
+				     dlm_lock_mode_name(type));
+				lock->lksb->flags |= DLM_LKSB_PUT_LVB;
+				break;
+			case LKM_PRMODE:
+			case LKM_NLMODE:
+				/* refetch if new level is not NL */
+				if (type > LKM_NLMODE) {
+					mlog(0, "will fetch new value into "
+					     "lvb: converting %s->%s\n",
+					     dlm_lock_mode_name(lock->ml.type),
+					     dlm_lock_mode_name(type));
+					lock->lksb->flags |= DLM_LKSB_GET_LVB;
+				} else {
+					mlog(0, "will NOT fetch new value "
+					     "into lvb: converting %s->%s\n",
+					     dlm_lock_mode_name(lock->ml.type),
+					     dlm_lock_mode_name(type));
+					flags &= ~(LKM_VALBLK);
+				}
+				break;
+		}
+	}
+
+
+	/* in-place downconvert? */
+	if (type <= lock->ml.type)
+		goto grant;
+
+	/* upconvert from here on */
+	status = DLM_NORMAL;
+	list_for_each(iter, &res->granted) {
+		tmplock = list_entry(iter, struct dlm_lock, list);
+		if (tmplock == lock)
+			continue;
+		if (!dlm_lock_compatible(tmplock->ml.type, type))
+			goto switch_queues;
+	}
+
+	list_for_each(iter, &res->converting) {
+		tmplock = list_entry(iter, struct dlm_lock, list);
+		if (!dlm_lock_compatible(tmplock->ml.type, type))
+			goto switch_queues;
+		/* existing conversion requests take precedence */
+		if (!dlm_lock_compatible(tmplock->ml.convert_type, type))
+			goto switch_queues;
+	}
+
+	/* fall thru to grant */
+
+grant:
+	mlog(0, "res %.*s, granting %s lock\n", res->lockname.len,
+	     res->lockname.name, dlm_lock_mode_name(type));
+	/* immediately grant the new lock type */
+	lock->lksb->status = DLM_NORMAL;
+	if (lock->ml.node == dlm->node_num)
+		mlog(0, "doing in-place convert for nonlocal lock\n");
+	lock->ml.type = type;
+	status = DLM_NORMAL;
+	*call_ast = 1;
+	goto unlock_exit;
+
+switch_queues:
+	if (flags & LKM_NOQUEUE) {
+		mlog(0, "failed to convert NOQUEUE lock %.*s from "
+		     "%d to %d...\n", res->lockname.len, res->lockname.name,
+		     lock->ml.type, type);
+		status = DLM_NOTQUEUED;
+		goto unlock_exit;
+	}
+	mlog(0, "res %.*s, queueing...\n", res->lockname.len,
+	     res->lockname.name);
+
+	lock->ml.convert_type = type;
+	/* do not alter lock refcount.  switching lists. */
+	list_del_init(&lock->list);
+	list_add_tail(&lock->list, &res->converting);
+
+unlock_exit:
+	spin_unlock(&lock->spinlock);
+	if (status == DLM_DENIED) {
+		__dlm_print_one_lock_resource(res);
+	}
+	if (status == DLM_NORMAL)
+		*kick_thread = 1;
+	return status;
+}
+
+void dlm_revert_pending_convert(struct dlm_lock_resource *res,
+				struct dlm_lock *lock)
+{
+	/* do not alter lock refcount.  switching lists. */
+	list_del_init(&lock->list);
+	list_add_tail(&lock->list, &res->granted);
+	lock->ml.convert_type = LKM_IVMODE;
+	lock->lksb->flags &= ~(DLM_LKSB_GET_LVB|DLM_LKSB_PUT_LVB);
+}
+
+/* messages the master site to do lock conversion
+ * locking:
+ *   caller needs:  none
+ *   taken:         takes and drops res->spinlock, uses DLM_LOCK_RES_IN_PROGRESS
+ *   held on exit:  none
+ * returns: DLM_NORMAL, DLM_RECOVERING, status from remote node
+ */
+enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm,
+				  struct dlm_lock_resource *res,
+				  struct dlm_lock *lock, int flags, int type)
+{
+	enum dlm_status status;
+
+	mlog(0, "type=%d, convert_type=%d, busy=%d\n", lock->ml.type,
+	     lock->ml.convert_type, res->state & DLM_LOCK_RES_IN_PROGRESS);
+
+	spin_lock(&res->spinlock);
+	if (res->state & DLM_LOCK_RES_RECOVERING) {
+		mlog(0, "bailing out early since res is RECOVERING "
+		     "on secondary queue\n");
+		/* __dlm_print_one_lock_resource(res); */
+		status = DLM_RECOVERING;
+		goto bail;
+	}
+	/* will exit this call with spinlock held */
+	__dlm_wait_on_lockres(res);
+
+	if (lock->ml.convert_type != LKM_IVMODE) {
+		__dlm_print_one_lock_resource(res);
+		mlog(ML_ERROR, "converting a remote lock that is already "
+		     "converting! (cookie=%"MLFu64", conv=%d)\n",
+		     lock->ml.cookie, lock->ml.convert_type);
+		status = DLM_DENIED;
+		goto bail;
+	}
+	res->state |= DLM_LOCK_RES_IN_PROGRESS;
+	/* move lock to local convert queue */
+	/* do not alter lock refcount.  switching lists. */
+	list_del_init(&lock->list);
+	list_add_tail(&lock->list, &res->converting);
+	lock->convert_pending = 1;
+	lock->ml.convert_type = type;
+
+	if (flags & LKM_VALBLK) {
+		if (lock->ml.type == LKM_EXMODE) {
+			flags |= LKM_PUT_LVB;
+			lock->lksb->flags |= DLM_LKSB_PUT_LVB;
+		} else {
+			if (lock->ml.convert_type == LKM_NLMODE)
+				flags &= ~LKM_VALBLK;
+			else {
+				flags |= LKM_GET_LVB;
+				lock->lksb->flags |= DLM_LKSB_GET_LVB;
+			}
+		}
+	}
+	spin_unlock(&res->spinlock);
+
+	/* no locks held here.
+	 * need to wait for a reply as to whether it got queued or not. */
+	status = dlm_send_remote_convert_request(dlm, res, lock, flags, type);
+
+	spin_lock(&res->spinlock);
+	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
+	lock->convert_pending = 0;
+	/* if it failed, move it back to granted queue */
+	if (status != DLM_NORMAL) {
+		if (status != DLM_NOTQUEUED)
+			dlm_error(status);
+		dlm_revert_pending_convert(res, lock);
+	}
+bail:
+	spin_unlock(&res->spinlock);
+
+	/* TODO: should this be a wake_one? */
+	/* wake up any IN_PROGRESS waiters */
+	wake_up(&res->wq);
+
+	return status;
+}
+
+/* sends DLM_CONVERT_LOCK_MSG to master site
+ * locking:
+ *   caller needs:  none
+ *   taken:         none
+ *   held on exit:  none
+ * returns: DLM_NOLOCKMGR, status from remote node
+ */
+static enum dlm_status dlm_send_remote_convert_request(struct dlm_ctxt *dlm,
+					   struct dlm_lock_resource *res,
+					   struct dlm_lock *lock, int flags, int type)
+{
+	struct dlm_convert_lock convert;
+	int tmpret;
+	enum dlm_status ret;
+	int status = 0;
+	struct kvec vec[2];
+	size_t veclen = 1;
+
+	mlog_entry("%.*s\n", res->lockname.len, res->lockname.name);
+
+	memset(&convert, 0, sizeof(struct dlm_convert_lock));
+	convert.node_idx = dlm->node_num;
+	convert.requested_type = type;
+	convert.cookie = lock->ml.cookie;
+	convert.namelen = res->lockname.len;
+	convert.flags = cpu_to_be32(flags);
+	memcpy(convert.name, res->lockname.name, convert.namelen);
+
+	vec[0].iov_len = sizeof(struct dlm_convert_lock);
+	vec[0].iov_base = &convert;
+
+	if (flags & LKM_PUT_LVB) {
+		/* extra data to send if we are updating lvb */
+		vec[1].iov_len = DLM_LVB_LEN;
+		vec[1].iov_base = lock->lksb->lvb;
+		veclen++;
+	}
+
+	tmpret = o2net_send_message_vec(DLM_CONVERT_LOCK_MSG, dlm->key,
+					vec, veclen, res->owner, &status);
+	if (tmpret >= 0) {
+		// successfully sent and received
+		ret = status;  // this is already a dlm_status
+		if (ret == DLM_RECOVERING) {
+			mlog(0, "node %u returned DLM_RECOVERING from convert "
+			     "message!\n", res->owner);
+		} else if (ret == DLM_MIGRATING) {
+			mlog(0, "node %u returned DLM_MIGRATING from convert "
+			     "message!\n", res->owner);
+		} else if (ret == DLM_FORWARD) {
+			mlog(0, "node %u returned DLM_FORWARD from convert "
+			     "message!\n", res->owner);
+		} else if (ret != DLM_NORMAL && ret != DLM_NOTQUEUED)
+			dlm_error(ret);
+	} else {
+		mlog_errno(tmpret);
+		if (dlm_is_host_down(tmpret)) {
+			ret = DLM_RECOVERING;
+			mlog(0, "node %u died so returning DLM_RECOVERING "
+			     "from convert message!\n", res->owner);
+		} else {
+			ret = dlm_err_to_dlm_status(tmpret);
+		}
+	}
+
+	return ret;
+}
+
+/* handler for DLM_CONVERT_LOCK_MSG on master site
+ * locking:
+ *   caller needs:  none
+ *   taken:         takes and drop res->spinlock
+ *   held on exit:  none
+ * returns: DLM_NORMAL, DLM_IVLOCKID, DLM_BADARGS,
+ *          status from __dlmconvert_master
+ */
+int dlm_convert_lock_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_convert_lock *cnv = (struct dlm_convert_lock *)msg->buf;
+	struct dlm_lock_resource *res = NULL;
+	struct list_head *iter;
+	struct dlm_lock *lock = NULL;
+	struct dlm_lockstatus *lksb;
+	enum dlm_status status = DLM_NORMAL;
+	u32 flags;
+	int call_ast = 0, kick_thread = 0;
+
+	if (!dlm_grab(dlm)) {
+		dlm_error(DLM_REJECTED);
+		return DLM_REJECTED;
+	}
+
+	mlog_bug_on_msg(!dlm_domain_fully_joined(dlm),
+			"Domain %s not fully joined!\n", dlm->name);
+
+	if (cnv->namelen > DLM_LOCKID_NAME_MAX) {
+		status = DLM_IVBUFLEN;
+		dlm_error(status);
+		goto leave;
+	}
+
+	flags = be32_to_cpu(cnv->flags);
+
+	if ((flags & (LKM_PUT_LVB|LKM_GET_LVB)) ==
+	     (LKM_PUT_LVB|LKM_GET_LVB)) {
+		mlog(ML_ERROR, "both PUT and GET lvb specified\n");
+		status = DLM_BADARGS;
+		goto leave;
+	}
+
+	mlog(0, "lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" :
+	     (flags & LKM_GET_LVB ? "get lvb" : "none"));
+
+	status = DLM_IVLOCKID;
+	res = dlm_lookup_lockres(dlm, cnv->name, cnv->namelen);
+	if (!res) {
+		dlm_error(status);
+		goto leave;
+	}
+
+	spin_lock(&res->spinlock);
+	list_for_each(iter, &res->granted) {
+		lock = list_entry(iter, struct dlm_lock, list);
+		if (lock->ml.cookie == cnv->cookie &&
+		    lock->ml.node == cnv->node_idx) {
+			dlm_lock_get(lock);
+			break;
+		}
+		lock = NULL;
+	}
+	spin_unlock(&res->spinlock);
+	if (!lock) {
+		status = DLM_IVLOCKID;
+		dlm_error(status);
+		goto leave;
+	}
+
+	/* found the lock */
+	lksb = lock->lksb;
+
+	/* see if caller needed to get/put lvb */
+	if (flags & LKM_PUT_LVB) {
+		BUG_ON(lksb->flags & (DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB));
+		lksb->flags |= DLM_LKSB_PUT_LVB;
+		memcpy(&lksb->lvb[0], &cnv->lvb[0], DLM_LVB_LEN);
+	} else if (flags & LKM_GET_LVB) {
+		BUG_ON(lksb->flags & (DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB));
+		lksb->flags |= DLM_LKSB_GET_LVB;
+	}
+
+	spin_lock(&res->spinlock);
+	status = __dlm_lockres_state_to_status(res);
+	if (status == DLM_NORMAL) {
+		__dlm_lockres_reserve_ast(res);
+		res->state |= DLM_LOCK_RES_IN_PROGRESS;
+		status = __dlmconvert_master(dlm, res, lock, flags,
+					     cnv->requested_type,
+					     &call_ast, &kick_thread);
+		res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
+	}
+	spin_unlock(&res->spinlock);
+
+	if (status != DLM_NORMAL) {
+		if (status != DLM_NOTQUEUED)
+			dlm_error(status);
+		lksb->flags &= ~(DLM_LKSB_GET_LVB|DLM_LKSB_PUT_LVB);
+	}
+
+leave:
+	if (!lock)
+		mlog(ML_ERROR, "did not find lock to convert on grant queue! "
+			       "cookie=%"MLFu64"\n",
+		     cnv->cookie);
+	else
+		dlm_lock_put(lock);
+
+	/* either queue the ast or release it */
+	if (call_ast)
+		dlm_queue_ast(dlm, lock);
+	else
+		dlm_lockres_release_ast(dlm, res);
+
+	if (kick_thread)
+		dlm_kick_thread(dlm, res);
+
+	if (res)
+		dlm_lockres_put(res);
+
+	dlm_put(dlm);
+
+	return status;
+}
diff --git a/fs/ocfs2/dlm/dlmconvert.h b/fs/ocfs2/dlm/dlmconvert.h
new file mode 100644
index 0000000..b2e3677
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmconvert.h
@@ -0,0 +1,35 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmconvert.h
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef DLMCONVERT_H
+#define DLMCONVERT_H
+
+enum dlm_status dlmconvert_master(struct dlm_ctxt *dlm,
+				  struct dlm_lock_resource *res,
+				  struct dlm_lock *lock, int flags, int type);
+enum dlm_status dlmconvert_remote(struct dlm_ctxt *dlm,
+				  struct dlm_lock_resource *res,
+				  struct dlm_lock *lock, int flags, int type);
+
+#endif
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
new file mode 100644
index 0000000..f339fe27
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -0,0 +1,246 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmdebug.c
+ *
+ * debug functionality for the dlm
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/sysctl.h>
+#include <linux/spinlock.h>
+
+#include "cluster/heartbeat.h"
+#include "cluster/nodemanager.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+#include "dlmcommon.h"
+#include "dlmdebug.h"
+
+#include "dlmdomain.h"
+#include "dlmdebug.h"
+
+#define MLOG_MASK_PREFIX ML_DLM
+#include "cluster/masklog.h"
+
+void dlm_print_one_lock_resource(struct dlm_lock_resource *res)
+{
+	mlog(ML_NOTICE, "lockres: %.*s, owner=%u, state=%u\n",
+	       res->lockname.len, res->lockname.name,
+	       res->owner, res->state);
+	spin_lock(&res->spinlock);
+	__dlm_print_one_lock_resource(res);
+	spin_unlock(&res->spinlock);
+}
+
+void __dlm_print_one_lock_resource(struct dlm_lock_resource *res)
+{
+	struct list_head *iter2;
+	struct dlm_lock *lock;
+
+	assert_spin_locked(&res->spinlock);
+
+	mlog(ML_NOTICE, "lockres: %.*s, owner=%u, state=%u\n",
+	       res->lockname.len, res->lockname.name,
+	       res->owner, res->state);
+	mlog(ML_NOTICE, "  last used: %lu, on purge list: %s\n",
+	     res->last_used, list_empty(&res->purge) ? "no" : "yes");
+	mlog(ML_NOTICE, "  granted queue: \n");
+	list_for_each(iter2, &res->granted) {
+		lock = list_entry(iter2, struct dlm_lock, list);
+		spin_lock(&lock->spinlock);
+		mlog(ML_NOTICE, "    type=%d, conv=%d, node=%u, "
+		       "cookie=%"MLFu64", ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c)\n", 
+		       lock->ml.type, lock->ml.convert_type, lock->ml.node, lock->ml.cookie, 
+		       list_empty(&lock->ast_list) ? 'y' : 'n',
+		       lock->ast_pending ? 'y' : 'n',
+		       list_empty(&lock->bast_list) ? 'y' : 'n',
+		       lock->bast_pending ? 'y' : 'n');
+		spin_unlock(&lock->spinlock);
+	}
+	mlog(ML_NOTICE, "  converting queue: \n");
+	list_for_each(iter2, &res->converting) {
+		lock = list_entry(iter2, struct dlm_lock, list);
+		spin_lock(&lock->spinlock);
+		mlog(ML_NOTICE, "    type=%d, conv=%d, node=%u, "
+		       "cookie=%"MLFu64", ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c)\n", 
+		       lock->ml.type, lock->ml.convert_type, lock->ml.node, lock->ml.cookie, 
+		       list_empty(&lock->ast_list) ? 'y' : 'n',
+		       lock->ast_pending ? 'y' : 'n',
+		       list_empty(&lock->bast_list) ? 'y' : 'n',
+		       lock->bast_pending ? 'y' : 'n');
+		spin_unlock(&lock->spinlock);
+	}
+	mlog(ML_NOTICE, "  blocked queue: \n");
+	list_for_each(iter2, &res->blocked) {
+		lock = list_entry(iter2, struct dlm_lock, list);
+		spin_lock(&lock->spinlock);
+		mlog(ML_NOTICE, "    type=%d, conv=%d, node=%u, "
+		       "cookie=%"MLFu64", ast=(empty=%c,pend=%c), bast=(empty=%c,pend=%c)\n", 
+		       lock->ml.type, lock->ml.convert_type, lock->ml.node, lock->ml.cookie, 
+		       list_empty(&lock->ast_list) ? 'y' : 'n',
+		       lock->ast_pending ? 'y' : 'n',
+		       list_empty(&lock->bast_list) ? 'y' : 'n',
+		       lock->bast_pending ? 'y' : 'n');
+		spin_unlock(&lock->spinlock);
+	}
+}
+
+void dlm_print_one_lock(struct dlm_lock *lockid)
+{
+	dlm_print_one_lock_resource(lockid->lockres);
+}
+EXPORT_SYMBOL_GPL(dlm_print_one_lock);
+
+void dlm_dump_lock_resources(struct dlm_ctxt *dlm)
+{
+	struct dlm_lock_resource *res;
+	struct list_head *iter;
+	struct list_head *bucket;
+	int i;
+
+	mlog(ML_NOTICE, "struct dlm_ctxt: %s, node=%u, key=%u\n",
+		  dlm->name, dlm->node_num, dlm->key);
+	if (!dlm || !dlm->name) {
+		mlog(ML_ERROR, "dlm=%p\n", dlm);
+		return;
+	}
+
+	spin_lock(&dlm->spinlock);
+	for (i=0; i<DLM_HASH_SIZE; i++) {
+		bucket = &(dlm->resources[i]);
+		list_for_each(iter, bucket) {
+			res = list_entry(iter, struct dlm_lock_resource, list);
+			dlm_print_one_lock_resource(res);
+		}
+	}
+	spin_unlock(&dlm->spinlock);
+}
+
+static const char *dlm_errnames[] = {
+	[DLM_NORMAL] =			"DLM_NORMAL",
+	[DLM_GRANTED] =			"DLM_GRANTED",
+	[DLM_DENIED] =			"DLM_DENIED",
+	[DLM_DENIED_NOLOCKS] =		"DLM_DENIED_NOLOCKS",
+	[DLM_WORKING] =			"DLM_WORKING",
+	[DLM_BLOCKED] =			"DLM_BLOCKED",
+	[DLM_BLOCKED_ORPHAN] =		"DLM_BLOCKED_ORPHAN",
+	[DLM_DENIED_GRACE_PERIOD] =	"DLM_DENIED_GRACE_PERIOD",
+	[DLM_SYSERR] =			"DLM_SYSERR",
+	[DLM_NOSUPPORT] =		"DLM_NOSUPPORT",
+	[DLM_CANCELGRANT] =		"DLM_CANCELGRANT",
+	[DLM_IVLOCKID] =		"DLM_IVLOCKID",
+	[DLM_SYNC] =			"DLM_SYNC",
+	[DLM_BADTYPE] =			"DLM_BADTYPE",
+	[DLM_BADRESOURCE] =		"DLM_BADRESOURCE",
+	[DLM_MAXHANDLES] =		"DLM_MAXHANDLES",
+	[DLM_NOCLINFO] =		"DLM_NOCLINFO",
+	[DLM_NOLOCKMGR] =		"DLM_NOLOCKMGR",
+	[DLM_NOPURGED] =		"DLM_NOPURGED",
+	[DLM_BADARGS] =			"DLM_BADARGS",
+	[DLM_VOID] =			"DLM_VOID",
+	[DLM_NOTQUEUED] =		"DLM_NOTQUEUED",
+	[DLM_IVBUFLEN] =		"DLM_IVBUFLEN",
+	[DLM_CVTUNGRANT] =		"DLM_CVTUNGRANT",
+	[DLM_BADPARAM] =		"DLM_BADPARAM",
+	[DLM_VALNOTVALID] =		"DLM_VALNOTVALID",
+	[DLM_REJECTED] =		"DLM_REJECTED",
+	[DLM_ABORT] =			"DLM_ABORT",
+	[DLM_CANCEL] =			"DLM_CANCEL",
+	[DLM_IVRESHANDLE] =		"DLM_IVRESHANDLE",
+	[DLM_DEADLOCK] =		"DLM_DEADLOCK",
+	[DLM_DENIED_NOASTS] =		"DLM_DENIED_NOASTS",
+	[DLM_FORWARD] =			"DLM_FORWARD",
+	[DLM_TIMEOUT] =			"DLM_TIMEOUT",
+	[DLM_IVGROUPID] =		"DLM_IVGROUPID",
+	[DLM_VERS_CONFLICT] =		"DLM_VERS_CONFLICT",
+	[DLM_BAD_DEVICE_PATH] =		"DLM_BAD_DEVICE_PATH",
+	[DLM_NO_DEVICE_PERMISSION] =	"DLM_NO_DEVICE_PERMISSION",
+	[DLM_NO_CONTROL_DEVICE ] =	"DLM_NO_CONTROL_DEVICE ",
+	[DLM_RECOVERING] =		"DLM_RECOVERING",
+	[DLM_MIGRATING] =		"DLM_MIGRATING",
+	[DLM_MAXSTATS] =		"DLM_MAXSTATS",
+};
+
+static const char *dlm_errmsgs[] = {
+	[DLM_NORMAL] = 			"request in progress",
+	[DLM_GRANTED] = 		"request granted",
+	[DLM_DENIED] = 			"request denied",
+	[DLM_DENIED_NOLOCKS] = 		"request denied, out of system resources",
+	[DLM_WORKING] = 		"async request in progress",
+	[DLM_BLOCKED] = 		"lock request blocked",
+	[DLM_BLOCKED_ORPHAN] = 		"lock request blocked by a orphan lock",
+	[DLM_DENIED_GRACE_PERIOD] = 	"topological change in progress",
+	[DLM_SYSERR] = 			"system error",
+	[DLM_NOSUPPORT] = 		"unsupported",
+	[DLM_CANCELGRANT] = 		"can't cancel convert: already granted",
+	[DLM_IVLOCKID] = 		"bad lockid",
+	[DLM_SYNC] = 			"synchronous request granted",
+	[DLM_BADTYPE] = 		"bad resource type",
+	[DLM_BADRESOURCE] = 		"bad resource handle",
+	[DLM_MAXHANDLES] = 		"no more resource handles",
+	[DLM_NOCLINFO] = 		"can't contact cluster manager",
+	[DLM_NOLOCKMGR] = 		"can't contact lock manager",
+	[DLM_NOPURGED] = 		"can't contact purge daemon",
+	[DLM_BADARGS] = 		"bad api args",
+	[DLM_VOID] = 			"no status",
+	[DLM_NOTQUEUED] = 		"NOQUEUE was specified and request failed",
+	[DLM_IVBUFLEN] = 		"invalid resource name length",
+	[DLM_CVTUNGRANT] = 		"attempted to convert ungranted lock",
+	[DLM_BADPARAM] = 		"invalid lock mode specified",
+	[DLM_VALNOTVALID] = 		"value block has been invalidated",
+	[DLM_REJECTED] = 		"request rejected, unrecognized client",
+	[DLM_ABORT] = 			"blocked lock request cancelled",
+	[DLM_CANCEL] = 			"conversion request cancelled",
+	[DLM_IVRESHANDLE] = 		"invalid resource handle",
+	[DLM_DEADLOCK] = 		"deadlock recovery refused this request",
+	[DLM_DENIED_NOASTS] = 		"failed to allocate AST",
+	[DLM_FORWARD] = 		"request must wait for primary's response",
+	[DLM_TIMEOUT] = 		"timeout value for lock has expired",
+	[DLM_IVGROUPID] = 		"invalid group specification",
+	[DLM_VERS_CONFLICT] = 		"version conflicts prevent request handling",
+	[DLM_BAD_DEVICE_PATH] = 	"Locks device does not exist or path wrong",
+	[DLM_NO_DEVICE_PERMISSION] = 	"Client has insufficient perms for device",
+	[DLM_NO_CONTROL_DEVICE] = 	"Cannot set options on opened device ",
+	[DLM_RECOVERING] = 		"lock resource being recovered",
+	[DLM_MIGRATING] = 		"lock resource being migrated",
+	[DLM_MAXSTATS] = 		"invalid error number",
+};
+
+const char *dlm_errmsg(enum dlm_status err)
+{
+	if (err >= DLM_MAXSTATS || err < 0)
+		return dlm_errmsgs[DLM_MAXSTATS];
+	return dlm_errmsgs[err];
+}
+EXPORT_SYMBOL_GPL(dlm_errmsg);
+
+const char *dlm_errname(enum dlm_status err)
+{
+	if (err >= DLM_MAXSTATS || err < 0)
+		return dlm_errnames[DLM_MAXSTATS];
+	return dlm_errnames[err];
+}
+EXPORT_SYMBOL_GPL(dlm_errname);
diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h
new file mode 100644
index 0000000..6858510
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmdebug.h
@@ -0,0 +1,30 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmdebug.h
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef DLMDEBUG_H
+#define DLMDEBUG_H
+
+void dlm_dump_lock_resources(struct dlm_ctxt *dlm);
+
+#endif
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
new file mode 100644
index 0000000..da3c220
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -0,0 +1,1469 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmdomain.c
+ *
+ * defines domain join / leave apis
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+
+#include "cluster/heartbeat.h"
+#include "cluster/nodemanager.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+#include "dlmcommon.h"
+
+#include "dlmdebug.h"
+#include "dlmdomain.h"
+
+#include "dlmver.h"
+
+#define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_DOMAIN)
+#include "cluster/masklog.h"
+
+/*
+ *
+ * spinlock lock ordering: if multiple locks are needed, obey this ordering:
+ *    dlm_domain_lock
+ *    struct dlm_ctxt->spinlock
+ *    struct dlm_lock_resource->spinlock
+ *    struct dlm_ctxt->master_lock
+ *    struct dlm_ctxt->ast_lock
+ *    dlm_master_list_entry->spinlock
+ *    dlm_lock->spinlock
+ *
+ */
+
+spinlock_t dlm_domain_lock = SPIN_LOCK_UNLOCKED;
+LIST_HEAD(dlm_domains);
+static DECLARE_WAIT_QUEUE_HEAD(dlm_domain_events);
+
+#define DLM_DOMAIN_BACKOFF_MS 200
+
+static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data);
+static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data);
+static int dlm_cancel_join_handler(struct o2net_msg *msg, u32 len, void *data);
+static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data);
+
+static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm);
+
+void __dlm_unhash_lockres(struct dlm_lock_resource *lockres)
+{
+	list_del_init(&lockres->list);
+	dlm_lockres_put(lockres);
+}
+
+void __dlm_insert_lockres(struct dlm_ctxt *dlm,
+		       struct dlm_lock_resource *res)
+{
+	struct list_head *bucket;
+	struct qstr *q;
+
+	assert_spin_locked(&dlm->spinlock);
+
+	q = &res->lockname;
+	q->hash = full_name_hash(q->name, q->len);
+	bucket = &(dlm->resources[q->hash & DLM_HASH_MASK]);
+
+	/* get a reference for our hashtable */
+	dlm_lockres_get(res);
+
+	list_add_tail(&res->list, bucket);
+}
+
+struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
+					 const char *name,
+					 unsigned int len)
+{
+	unsigned int hash;
+	struct list_head *iter;
+	struct dlm_lock_resource *tmpres=NULL;
+	struct list_head *bucket;
+
+	mlog_entry("%.*s\n", len, name);
+
+	assert_spin_locked(&dlm->spinlock);
+
+	hash = full_name_hash(name, len);
+
+	bucket = &(dlm->resources[hash & DLM_HASH_MASK]);
+
+	/* check for pre-existing lock */
+	list_for_each(iter, bucket) {
+		tmpres = list_entry(iter, struct dlm_lock_resource, list);
+		if (tmpres->lockname.len == len &&
+		    memcmp(tmpres->lockname.name, name, len) == 0) {
+			dlm_lockres_get(tmpres);
+			break;
+		}
+
+		tmpres = NULL;
+	}
+	return tmpres;
+}
+
+struct dlm_lock_resource * dlm_lookup_lockres(struct dlm_ctxt *dlm,
+				    const char *name,
+				    unsigned int len)
+{
+	struct dlm_lock_resource *res;
+
+	spin_lock(&dlm->spinlock);
+	res = __dlm_lookup_lockres(dlm, name, len);
+	spin_unlock(&dlm->spinlock);
+	return res;
+}
+
+static struct dlm_ctxt * __dlm_lookup_domain_full(const char *domain, int len)
+{
+	struct dlm_ctxt *tmp = NULL;
+	struct list_head *iter;
+
+	assert_spin_locked(&dlm_domain_lock);
+
+	/* tmp->name here is always NULL terminated,
+	 * but domain may not be! */
+	list_for_each(iter, &dlm_domains) {
+		tmp = list_entry (iter, struct dlm_ctxt, list);
+		if (strlen(tmp->name) == len &&
+		    memcmp(tmp->name, domain, len)==0)
+			break;
+		tmp = NULL;
+	}
+
+	return tmp;
+}
+
+/* For null terminated domain strings ONLY */
+static struct dlm_ctxt * __dlm_lookup_domain(const char *domain)
+{
+	assert_spin_locked(&dlm_domain_lock);
+
+	return __dlm_lookup_domain_full(domain, strlen(domain));
+}
+
+
+/* returns true on one of two conditions:
+ * 1) the domain does not exist
+ * 2) the domain exists and it's state is "joined" */
+static int dlm_wait_on_domain_helper(const char *domain)
+{
+	int ret = 0;
+	struct dlm_ctxt *tmp = NULL;
+
+	spin_lock(&dlm_domain_lock);
+
+	tmp = __dlm_lookup_domain(domain);
+	if (!tmp)
+		ret = 1;
+	else if (tmp->dlm_state == DLM_CTXT_JOINED)
+		ret = 1;
+
+	spin_unlock(&dlm_domain_lock);
+	return ret;
+}
+
+static void dlm_free_ctxt_mem(struct dlm_ctxt *dlm)
+{
+	if (dlm->resources)
+		free_page((unsigned long) dlm->resources);
+
+	if (dlm->name)
+		kfree(dlm->name);
+
+	kfree(dlm);
+}
+
+/* A little strange - this function will be called while holding
+ * dlm_domain_lock and is expected to be holding it on the way out. We
+ * will however drop and reacquire it multiple times */
+static void dlm_ctxt_release(struct kref *kref)
+{
+	struct dlm_ctxt *dlm;
+
+	dlm = container_of(kref, struct dlm_ctxt, dlm_refs);
+
+	BUG_ON(dlm->num_joins);
+	BUG_ON(dlm->dlm_state == DLM_CTXT_JOINED);
+
+	/* we may still be in the list if we hit an error during join. */
+	list_del_init(&dlm->list);
+
+	spin_unlock(&dlm_domain_lock);
+
+	mlog(0, "freeing memory from domain %s\n", dlm->name);
+
+	wake_up(&dlm_domain_events);
+
+	dlm_free_ctxt_mem(dlm);
+
+	spin_lock(&dlm_domain_lock);
+}
+
+void dlm_put(struct dlm_ctxt *dlm)
+{
+	spin_lock(&dlm_domain_lock);
+	kref_put(&dlm->dlm_refs, dlm_ctxt_release);
+	spin_unlock(&dlm_domain_lock);
+}
+
+static void __dlm_get(struct dlm_ctxt *dlm)
+{
+	kref_get(&dlm->dlm_refs);
+}
+
+/* given a questionable reference to a dlm object, gets a reference if
+ * it can find it in the list, otherwise returns NULL in which case
+ * you shouldn't trust your pointer. */
+struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm)
+{
+	struct list_head *iter;
+	struct dlm_ctxt *target = NULL;
+
+	spin_lock(&dlm_domain_lock);
+
+	list_for_each(iter, &dlm_domains) {
+		target = list_entry (iter, struct dlm_ctxt, list);
+
+		if (target == dlm) {
+			__dlm_get(target);
+			break;
+		}
+
+		target = NULL;
+	}
+
+	spin_unlock(&dlm_domain_lock);
+
+	return target;
+}
+
+int dlm_domain_fully_joined(struct dlm_ctxt *dlm)
+{
+	int ret;
+
+	spin_lock(&dlm_domain_lock);
+	ret = (dlm->dlm_state == DLM_CTXT_JOINED) ||
+		(dlm->dlm_state == DLM_CTXT_IN_SHUTDOWN);
+	spin_unlock(&dlm_domain_lock);
+
+	return ret;
+}
+
+static void dlm_complete_dlm_shutdown(struct dlm_ctxt *dlm)
+{
+	dlm_unregister_domain_handlers(dlm);
+	dlm_complete_thread(dlm);
+	dlm_complete_recovery_thread(dlm);
+
+	/* We've left the domain. Now we can take ourselves out of the
+	 * list and allow the kref stuff to help us free the
+	 * memory. */
+	spin_lock(&dlm_domain_lock);
+	list_del_init(&dlm->list);
+	spin_unlock(&dlm_domain_lock);
+
+	/* Wake up anyone waiting for us to remove this domain */
+	wake_up(&dlm_domain_events);
+}
+
+static void dlm_migrate_all_locks(struct dlm_ctxt *dlm)
+{
+	int i;
+	struct dlm_lock_resource *res;
+
+	mlog(0, "Migrating locks from domain %s\n", dlm->name);
+restart:
+	spin_lock(&dlm->spinlock);
+	for (i=0; i<DLM_HASH_SIZE; i++) {
+		while (!list_empty(&dlm->resources[i])) {
+			res = list_entry(dlm->resources[i].next,
+				     struct dlm_lock_resource, list);
+			/* need reference when manually grabbing lockres */
+			dlm_lockres_get(res);
+			/* this should unhash the lockres
+			 * and exit with dlm->spinlock */
+			mlog(0, "purging res=%p\n", res);
+			if (dlm_lockres_is_dirty(dlm, res)) {
+				/* HACK!  this should absolutely go.
+				 * need to figure out why some empty
+				 * lockreses are still marked dirty */
+				mlog(ML_ERROR, "lockres %.*s dirty!\n",
+				     res->lockname.len, res->lockname.name);
+
+				spin_unlock(&dlm->spinlock);
+				dlm_kick_thread(dlm, res);
+				wait_event(dlm->ast_wq, !dlm_lockres_is_dirty(dlm, res));
+				dlm_lockres_put(res);
+				goto restart;
+			}
+			dlm_purge_lockres(dlm, res);
+			dlm_lockres_put(res);
+		}
+	}
+	spin_unlock(&dlm->spinlock);
+
+	mlog(0, "DONE Migrating locks from domain %s\n", dlm->name);
+}
+
+static int dlm_no_joining_node(struct dlm_ctxt *dlm)
+{
+	int ret;
+
+	spin_lock(&dlm->spinlock);
+	ret = dlm->joining_node == DLM_LOCK_RES_OWNER_UNKNOWN;
+	spin_unlock(&dlm->spinlock);
+
+	return ret;
+}
+
+static void dlm_mark_domain_leaving(struct dlm_ctxt *dlm)
+{
+	/* Yikes, a double spinlock! I need domain_lock for the dlm
+	 * state and the dlm spinlock for join state... Sorry! */
+again:
+	spin_lock(&dlm_domain_lock);
+	spin_lock(&dlm->spinlock);
+
+	if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) {
+		mlog(0, "Node %d is joining, we wait on it.\n",
+			  dlm->joining_node);
+		spin_unlock(&dlm->spinlock);
+		spin_unlock(&dlm_domain_lock);
+
+		wait_event(dlm->dlm_join_events, dlm_no_joining_node(dlm));
+		goto again;
+	}
+
+	dlm->dlm_state = DLM_CTXT_LEAVING;
+	spin_unlock(&dlm->spinlock);
+	spin_unlock(&dlm_domain_lock);
+}
+
+static void __dlm_print_nodes(struct dlm_ctxt *dlm)
+{
+	int node = -1;
+
+	assert_spin_locked(&dlm->spinlock);
+
+	mlog(ML_NOTICE, "Nodes in my domain (\"%s\"):\n", dlm->name);
+
+	while ((node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES,
+				     node + 1)) < O2NM_MAX_NODES) {
+		mlog(ML_NOTICE, " node %d\n", node);
+	}
+}
+
+static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	unsigned int node;
+	struct dlm_exit_domain *exit_msg = (struct dlm_exit_domain *) msg->buf;
+
+	mlog_entry("%p %u %p", msg, len, data);
+
+	if (!dlm_grab(dlm))
+		return 0;
+
+	node = exit_msg->node_idx;
+
+	mlog(0, "Node %u leaves domain %s\n", node, dlm->name);
+
+	spin_lock(&dlm->spinlock);
+	clear_bit(node, dlm->domain_map);
+	__dlm_print_nodes(dlm);
+
+	/* notify anything attached to the heartbeat events */
+	dlm_hb_event_notify_attached(dlm, node, 0);
+
+	spin_unlock(&dlm->spinlock);
+
+	dlm_put(dlm);
+
+	return 0;
+}
+
+static int dlm_send_one_domain_exit(struct dlm_ctxt *dlm,
+				    unsigned int node)
+{
+	int status;
+	struct dlm_exit_domain leave_msg;
+
+	mlog(0, "Asking node %u if we can leave the domain %s me = %u\n",
+		  node, dlm->name, dlm->node_num);
+
+	memset(&leave_msg, 0, sizeof(leave_msg));
+	leave_msg.node_idx = dlm->node_num;
+
+	status = o2net_send_message(DLM_EXIT_DOMAIN_MSG, dlm->key,
+				    &leave_msg, sizeof(leave_msg), node,
+				    NULL);
+
+	mlog(0, "status return %d from o2net_send_message\n", status);
+
+	return status;
+}
+
+
+static void dlm_leave_domain(struct dlm_ctxt *dlm)
+{
+	int node, clear_node, status;
+
+	/* At this point we've migrated away all our locks and won't
+	 * accept mastership of new ones. The dlm is responsible for
+	 * almost nothing now. We make sure not to confuse any joining
+	 * nodes and then commence shutdown procedure. */
+
+	spin_lock(&dlm->spinlock);
+	/* Clear ourselves from the domain map */
+	clear_bit(dlm->node_num, dlm->domain_map);
+	while ((node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES,
+				     0)) < O2NM_MAX_NODES) {
+		/* Drop the dlm spinlock. This is safe wrt the domain_map.
+		 * -nodes cannot be added now as the
+		 *   query_join_handlers knows to respond with OK_NO_MAP
+		 * -we catch the right network errors if a node is
+		 *   removed from the map while we're sending him the
+		 *   exit message. */
+		spin_unlock(&dlm->spinlock);
+
+		clear_node = 1;
+
+		status = dlm_send_one_domain_exit(dlm, node);
+		if (status < 0 &&
+		    status != -ENOPROTOOPT &&
+		    status != -ENOTCONN) {
+			mlog(ML_NOTICE, "Error %d sending domain exit message "
+			     "to node %d\n", status, node);
+
+			/* Not sure what to do here but lets sleep for
+			 * a bit in case this was a transient
+			 * error... */
+			msleep(DLM_DOMAIN_BACKOFF_MS);
+			clear_node = 0;
+		}
+
+		spin_lock(&dlm->spinlock);
+		/* If we're not clearing the node bit then we intend
+		 * to loop back around to try again. */
+		if (clear_node)
+			clear_bit(node, dlm->domain_map);
+	}
+	spin_unlock(&dlm->spinlock);
+}
+
+int dlm_joined(struct dlm_ctxt *dlm)
+{
+	int ret = 0;
+
+	spin_lock(&dlm_domain_lock);
+
+	if (dlm->dlm_state == DLM_CTXT_JOINED)
+		ret = 1;
+
+	spin_unlock(&dlm_domain_lock);
+
+	return ret;
+}
+
+int dlm_shutting_down(struct dlm_ctxt *dlm)
+{
+	int ret = 0;
+
+	spin_lock(&dlm_domain_lock);
+
+	if (dlm->dlm_state == DLM_CTXT_IN_SHUTDOWN)
+		ret = 1;
+
+	spin_unlock(&dlm_domain_lock);
+
+	return ret;
+}
+
+void dlm_unregister_domain(struct dlm_ctxt *dlm)
+{
+	int leave = 0;
+
+	spin_lock(&dlm_domain_lock);
+	BUG_ON(dlm->dlm_state != DLM_CTXT_JOINED);
+	BUG_ON(!dlm->num_joins);
+
+	dlm->num_joins--;
+	if (!dlm->num_joins) {
+		/* We mark it "in shutdown" now so new register
+		 * requests wait until we've completely left the
+		 * domain. Don't use DLM_CTXT_LEAVING yet as we still
+		 * want new domain joins to communicate with us at
+		 * least until we've completed migration of our
+		 * resources. */
+		dlm->dlm_state = DLM_CTXT_IN_SHUTDOWN;
+		leave = 1;
+	}
+	spin_unlock(&dlm_domain_lock);
+
+	if (leave) {
+		mlog(0, "shutting down domain %s\n", dlm->name);
+
+		/* We changed dlm state, notify the thread */
+		dlm_kick_thread(dlm, NULL);
+
+		dlm_migrate_all_locks(dlm);
+		dlm_mark_domain_leaving(dlm);
+		dlm_leave_domain(dlm);
+		dlm_complete_dlm_shutdown(dlm);
+	}
+	dlm_put(dlm);
+}
+EXPORT_SYMBOL_GPL(dlm_unregister_domain);
+
+static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_query_join_request *query;
+	enum dlm_query_join_response response;
+	struct dlm_ctxt *dlm = NULL;
+
+	query = (struct dlm_query_join_request *) msg->buf;
+
+	mlog(0, "node %u wants to join domain %s\n", query->node_idx,
+		  query->domain);
+
+	/*
+	 * If heartbeat doesn't consider the node live, tell it
+	 * to back off and try again.  This gives heartbeat a chance
+	 * to catch up.
+	 */
+	if (!o2hb_check_node_heartbeating(query->node_idx)) {
+		mlog(0, "node %u is not in our live map yet\n",
+		     query->node_idx);
+
+		response = JOIN_DISALLOW;
+		goto respond;
+	}
+
+	response = JOIN_OK_NO_MAP;
+
+	spin_lock(&dlm_domain_lock);
+	dlm = __dlm_lookup_domain_full(query->domain, query->name_len);
+	/* Once the dlm ctxt is marked as leaving then we don't want
+	 * to be put in someone's domain map. */
+	if (dlm && dlm->dlm_state != DLM_CTXT_LEAVING) {
+		spin_lock(&dlm->spinlock);
+
+		if (dlm->dlm_state == DLM_CTXT_NEW &&
+		    dlm->joining_node == DLM_LOCK_RES_OWNER_UNKNOWN) {
+			/*If this is a brand new context and we
+			 * haven't started our join process yet, then
+			 * the other node won the race. */
+			response = JOIN_OK_NO_MAP;
+		} else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) {
+			/* Disallow parallel joins. */
+			response = JOIN_DISALLOW;
+		} else {
+			/* Alright we're fully a part of this domain
+			 * so we keep some state as to who's joining
+			 * and indicate to him that needs to be fixed
+			 * up. */
+			response = JOIN_OK;
+			__dlm_set_joining_node(dlm, query->node_idx);
+		}
+
+		spin_unlock(&dlm->spinlock);
+	}
+	spin_unlock(&dlm_domain_lock);
+
+respond:
+	mlog(0, "We respond with %u\n", response);
+
+	return response;
+}
+
+static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_assert_joined *assert;
+	struct dlm_ctxt *dlm = NULL;
+
+	assert = (struct dlm_assert_joined *) msg->buf;
+
+	mlog(0, "node %u asserts join on domain %s\n", assert->node_idx,
+		  assert->domain);
+
+	spin_lock(&dlm_domain_lock);
+	dlm = __dlm_lookup_domain_full(assert->domain, assert->name_len);
+	/* XXX should we consider no dlm ctxt an error? */
+	if (dlm) {
+		spin_lock(&dlm->spinlock);
+
+		/* Alright, this node has officially joined our
+		 * domain. Set him in the map and clean up our
+		 * leftover join state. */
+		BUG_ON(dlm->joining_node != assert->node_idx);
+		set_bit(assert->node_idx, dlm->domain_map);
+		__dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
+
+		__dlm_print_nodes(dlm);
+
+		/* notify anything attached to the heartbeat events */
+		dlm_hb_event_notify_attached(dlm, assert->node_idx, 1);
+
+		spin_unlock(&dlm->spinlock);
+	}
+	spin_unlock(&dlm_domain_lock);
+
+	return 0;
+}
+
+static int dlm_cancel_join_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_cancel_join *cancel;
+	struct dlm_ctxt *dlm = NULL;
+
+	cancel = (struct dlm_cancel_join *) msg->buf;
+
+	mlog(0, "node %u cancels join on domain %s\n", cancel->node_idx,
+		  cancel->domain);
+
+	spin_lock(&dlm_domain_lock);
+	dlm = __dlm_lookup_domain_full(cancel->domain, cancel->name_len);
+
+	if (dlm) {
+		spin_lock(&dlm->spinlock);
+
+		/* Yikes, this guy wants to cancel his join. No
+		 * problem, we simply cleanup our join state. */
+		BUG_ON(dlm->joining_node != cancel->node_idx);
+		__dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
+
+		spin_unlock(&dlm->spinlock);
+	}
+	spin_unlock(&dlm_domain_lock);
+
+	return 0;
+}
+
+static int dlm_send_one_join_cancel(struct dlm_ctxt *dlm,
+				    unsigned int node)
+{
+	int status;
+	struct dlm_cancel_join cancel_msg;
+
+	memset(&cancel_msg, 0, sizeof(cancel_msg));
+	cancel_msg.node_idx = dlm->node_num;
+	cancel_msg.name_len = strlen(dlm->name);
+	memcpy(cancel_msg.domain, dlm->name, cancel_msg.name_len);
+
+	status = o2net_send_message(DLM_CANCEL_JOIN_MSG, DLM_MOD_KEY,
+				    &cancel_msg, sizeof(cancel_msg), node,
+				    NULL);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+bail:
+	return status;
+}
+
+/* map_size should be in bytes. */
+static int dlm_send_join_cancels(struct dlm_ctxt *dlm,
+				 unsigned long *node_map,
+				 unsigned int map_size)
+{
+	int status, tmpstat;
+	unsigned int node;
+
+	if (map_size != (BITS_TO_LONGS(O2NM_MAX_NODES) *
+			 sizeof(unsigned long))) {
+		mlog(ML_ERROR,
+		     "map_size %u != BITS_TO_LONGS(O2NM_MAX_NODES) %u\n",
+		     map_size, BITS_TO_LONGS(O2NM_MAX_NODES));
+		return -EINVAL;
+	}
+
+	status = 0;
+	node = -1;
+	while ((node = find_next_bit(node_map, O2NM_MAX_NODES,
+				     node + 1)) < O2NM_MAX_NODES) {
+		if (node == dlm->node_num)
+			continue;
+
+		tmpstat = dlm_send_one_join_cancel(dlm, node);
+		if (tmpstat) {
+			mlog(ML_ERROR, "Error return %d cancelling join on "
+			     "node %d\n", tmpstat, node);
+			if (!status)
+				status = tmpstat;
+		}
+	}
+
+	if (status)
+		mlog_errno(status);
+	return status;
+}
+
+static int dlm_request_join(struct dlm_ctxt *dlm,
+			    int node,
+			    enum dlm_query_join_response *response)
+{
+	int status, retval;
+	struct dlm_query_join_request join_msg;
+
+	mlog(0, "querying node %d\n", node);
+
+	memset(&join_msg, 0, sizeof(join_msg));
+	join_msg.node_idx = dlm->node_num;
+	join_msg.name_len = strlen(dlm->name);
+	memcpy(join_msg.domain, dlm->name, join_msg.name_len);
+
+	status = o2net_send_message(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY, &join_msg,
+				    sizeof(join_msg), node, &retval);
+	if (status < 0 && status != -ENOPROTOOPT) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* -ENOPROTOOPT from the net code means the other side isn't
+	    listening for our message type -- that's fine, it means
+	    his dlm isn't up, so we can consider him a 'yes' but not
+	    joined into the domain.  */
+	if (status == -ENOPROTOOPT) {
+		status = 0;
+		*response = JOIN_OK_NO_MAP;
+	} else if (retval == JOIN_DISALLOW ||
+		   retval == JOIN_OK ||
+		   retval == JOIN_OK_NO_MAP) {
+		*response = retval;
+	} else {
+		status = -EINVAL;
+		mlog(ML_ERROR, "invalid response %d from node %u\n", retval,
+		     node);
+	}
+
+	mlog(0, "status %d, node %d response is %d\n", status, node,
+		  *response);
+
+bail:
+	return status;
+}
+
+static int dlm_send_one_join_assert(struct dlm_ctxt *dlm,
+				    unsigned int node)
+{
+	int status;
+	struct dlm_assert_joined assert_msg;
+
+	mlog(0, "Sending join assert to node %u\n", node);
+
+	memset(&assert_msg, 0, sizeof(assert_msg));
+	assert_msg.node_idx = dlm->node_num;
+	assert_msg.name_len = strlen(dlm->name);
+	memcpy(assert_msg.domain, dlm->name, assert_msg.name_len);
+
+	status = o2net_send_message(DLM_ASSERT_JOINED_MSG, DLM_MOD_KEY,
+				    &assert_msg, sizeof(assert_msg), node,
+				    NULL);
+	if (status < 0)
+		mlog_errno(status);
+
+	return status;
+}
+
+static void dlm_send_join_asserts(struct dlm_ctxt *dlm,
+				  unsigned long *node_map)
+{
+	int status, node, live;
+
+	status = 0;
+	node = -1;
+	while ((node = find_next_bit(node_map, O2NM_MAX_NODES,
+				     node + 1)) < O2NM_MAX_NODES) {
+		if (node == dlm->node_num)
+			continue;
+
+		do {
+			/* It is very important that this message be
+			 * received so we spin until either the node
+			 * has died or it gets the message. */
+			status = dlm_send_one_join_assert(dlm, node);
+
+			spin_lock(&dlm->spinlock);
+			live = test_bit(node, dlm->live_nodes_map);
+			spin_unlock(&dlm->spinlock);
+
+			if (status) {
+				mlog(ML_ERROR, "Error return %d asserting "
+				     "join on node %d\n", status, node);
+
+				/* give us some time between errors... */
+				if (live)
+					msleep(DLM_DOMAIN_BACKOFF_MS);
+			}
+		} while (status && live);
+	}
+}
+
+struct domain_join_ctxt {
+	unsigned long live_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	unsigned long yes_resp_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+};
+
+static int dlm_should_restart_join(struct dlm_ctxt *dlm,
+				   struct domain_join_ctxt *ctxt,
+				   enum dlm_query_join_response response)
+{
+	int ret;
+
+	if (response == JOIN_DISALLOW) {
+		mlog(0, "Latest response of disallow -- should restart\n");
+		return 1;
+	}
+
+	spin_lock(&dlm->spinlock);
+	/* For now, we restart the process if the node maps have
+	 * changed at all */
+	ret = memcmp(ctxt->live_map, dlm->live_nodes_map,
+		     sizeof(dlm->live_nodes_map));
+	spin_unlock(&dlm->spinlock);
+
+	if (ret)
+		mlog(0, "Node maps changed -- should restart\n");
+
+	return ret;
+}
+
+static int dlm_try_to_join_domain(struct dlm_ctxt *dlm)
+{
+	int status = 0, tmpstat, node;
+	struct domain_join_ctxt *ctxt;
+	enum dlm_query_join_response response;
+
+	mlog_entry("%p", dlm);
+
+	ctxt = kcalloc(1, sizeof(*ctxt), GFP_KERNEL);
+	if (!ctxt) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* group sem locking should work for us here -- we're already
+	 * registered for heartbeat events so filling this should be
+	 * atomic wrt getting those handlers called. */
+	o2hb_fill_node_map(dlm->live_nodes_map, sizeof(dlm->live_nodes_map));
+
+	spin_lock(&dlm->spinlock);
+	memcpy(ctxt->live_map, dlm->live_nodes_map, sizeof(ctxt->live_map));
+
+	__dlm_set_joining_node(dlm, dlm->node_num);
+
+	spin_unlock(&dlm->spinlock);
+
+	node = -1;
+	while ((node = find_next_bit(ctxt->live_map, O2NM_MAX_NODES,
+				     node + 1)) < O2NM_MAX_NODES) {
+		if (node == dlm->node_num)
+			continue;
+
+		status = dlm_request_join(dlm, node, &response);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		/* Ok, either we got a response or the node doesn't have a
+		 * dlm up. */
+		if (response == JOIN_OK)
+			set_bit(node, ctxt->yes_resp_map);
+
+		if (dlm_should_restart_join(dlm, ctxt, response)) {
+			status = -EAGAIN;
+			goto bail;
+		}
+	}
+
+	mlog(0, "Yay, done querying nodes!\n");
+
+	/* Yay, everyone agree's we can join the domain. My domain is
+	 * comprised of all nodes who were put in the
+	 * yes_resp_map. Copy that into our domain map and send a join
+	 * assert message to clean up everyone elses state. */
+	spin_lock(&dlm->spinlock);
+	memcpy(dlm->domain_map, ctxt->yes_resp_map,
+	       sizeof(ctxt->yes_resp_map));
+	set_bit(dlm->node_num, dlm->domain_map);
+	spin_unlock(&dlm->spinlock);
+
+	dlm_send_join_asserts(dlm, ctxt->yes_resp_map);
+
+	/* Joined state *must* be set before the joining node
+	 * information, otherwise the query_join handler may read no
+	 * current joiner but a state of NEW and tell joining nodes
+	 * we're not in the domain. */
+	spin_lock(&dlm_domain_lock);
+	dlm->dlm_state = DLM_CTXT_JOINED;
+	dlm->num_joins++;
+	spin_unlock(&dlm_domain_lock);
+
+bail:
+	spin_lock(&dlm->spinlock);
+	__dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
+	if (!status)
+		__dlm_print_nodes(dlm);
+	spin_unlock(&dlm->spinlock);
+
+	if (ctxt) {
+		/* Do we need to send a cancel message to any nodes? */
+		if (status < 0) {
+			tmpstat = dlm_send_join_cancels(dlm,
+							ctxt->yes_resp_map,
+							sizeof(ctxt->yes_resp_map));
+			if (tmpstat < 0)
+				mlog_errno(tmpstat);
+		}
+		kfree(ctxt);
+	}
+
+	mlog(0, "returning %d\n", status);
+	return status;
+}
+
+static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm)
+{
+	o2hb_unregister_callback(&dlm->dlm_hb_up);
+	o2hb_unregister_callback(&dlm->dlm_hb_down);
+	o2net_unregister_handler_list(&dlm->dlm_domain_handlers);
+}
+
+static int dlm_register_domain_handlers(struct dlm_ctxt *dlm)
+{
+	int status;
+
+	mlog(0, "registering handlers.\n");
+
+	o2hb_setup_callback(&dlm->dlm_hb_down, O2HB_NODE_DOWN_CB,
+			    dlm_hb_node_down_cb, dlm, DLM_HB_NODE_DOWN_PRI);
+	status = o2hb_register_callback(&dlm->dlm_hb_down);
+	if (status)
+		goto bail;
+
+	o2hb_setup_callback(&dlm->dlm_hb_up, O2HB_NODE_UP_CB,
+			    dlm_hb_node_up_cb, dlm, DLM_HB_NODE_UP_PRI);
+	status = o2hb_register_callback(&dlm->dlm_hb_up);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_MASTER_REQUEST_MSG, dlm->key,
+					sizeof(struct dlm_master_request),
+					dlm_master_request_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_ASSERT_MASTER_MSG, dlm->key,
+					sizeof(struct dlm_assert_master),
+					dlm_assert_master_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_CREATE_LOCK_MSG, dlm->key,
+					sizeof(struct dlm_create_lock),
+					dlm_create_lock_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_CONVERT_LOCK_MSG, dlm->key,
+					DLM_CONVERT_LOCK_MAX_LEN,
+					dlm_convert_lock_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_UNLOCK_LOCK_MSG, dlm->key,
+					DLM_UNLOCK_LOCK_MAX_LEN,
+					dlm_unlock_lock_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_PROXY_AST_MSG, dlm->key,
+					DLM_PROXY_AST_MAX_LEN,
+					dlm_proxy_ast_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_EXIT_DOMAIN_MSG, dlm->key,
+					sizeof(struct dlm_exit_domain),
+					dlm_exit_domain_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_MIGRATE_REQUEST_MSG, dlm->key,
+					sizeof(struct dlm_migrate_request),
+					dlm_migrate_request_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_MIG_LOCKRES_MSG, dlm->key,
+					DLM_MIG_LOCKRES_MAX_LEN,
+					dlm_mig_lockres_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_MASTER_REQUERY_MSG, dlm->key,
+					sizeof(struct dlm_master_requery),
+					dlm_master_requery_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_LOCK_REQUEST_MSG, dlm->key,
+					sizeof(struct dlm_lock_request),
+					dlm_request_all_locks_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_RECO_DATA_DONE_MSG, dlm->key,
+					sizeof(struct dlm_reco_data_done),
+					dlm_reco_data_done_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_BEGIN_RECO_MSG, dlm->key,
+					sizeof(struct dlm_begin_reco),
+					dlm_begin_reco_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_FINALIZE_RECO_MSG, dlm->key,
+					sizeof(struct dlm_finalize_reco),
+					dlm_finalize_reco_handler,
+					dlm, &dlm->dlm_domain_handlers);
+	if (status)
+		goto bail;
+
+bail:
+	if (status)
+		dlm_unregister_domain_handlers(dlm);
+
+	return status;
+}
+
+static int dlm_join_domain(struct dlm_ctxt *dlm)
+{
+	int status;
+
+	BUG_ON(!dlm);
+
+	mlog(0, "Join domain %s\n", dlm->name);
+
+	status = dlm_register_domain_handlers(dlm);
+	if (status) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = dlm_launch_thread(dlm);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = dlm_launch_recovery_thread(dlm);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	do {
+		unsigned int backoff;
+		status = dlm_try_to_join_domain(dlm);
+
+		/* If we're racing another node to the join, then we
+		 * need to back off temporarily and let them
+		 * complete. */
+		if (status == -EAGAIN) {
+			if (signal_pending(current)) {
+				status = -ERESTARTSYS;
+				goto bail;
+			}
+
+			/*
+			 * <chip> After you!
+			 * <dale> No, after you!
+			 * <chip> I insist!
+			 * <dale> But you first!
+			 * ...
+			 */
+			backoff = (unsigned int)(jiffies & 0x3);
+			backoff *= DLM_DOMAIN_BACKOFF_MS;
+			mlog(0, "backoff %d\n", backoff);
+			msleep(backoff);
+		}
+	} while (status == -EAGAIN);
+
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = 0;
+bail:
+	wake_up(&dlm_domain_events);
+
+	if (status) {
+		dlm_unregister_domain_handlers(dlm);
+		dlm_complete_thread(dlm);
+		dlm_complete_recovery_thread(dlm);
+	}
+
+	return status;
+}
+
+static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain,
+				u32 key)
+{
+	int i;
+	struct dlm_ctxt *dlm = NULL;
+
+	dlm = kcalloc(1, sizeof(*dlm), GFP_KERNEL);
+	if (!dlm) {
+		mlog_errno(-ENOMEM);
+		goto leave;
+	}
+
+	dlm->name = kmalloc(strlen(domain) + 1, GFP_KERNEL);
+	if (dlm->name == NULL) {
+		mlog_errno(-ENOMEM);
+		kfree(dlm);
+		dlm = NULL;
+		goto leave;
+	}
+
+	dlm->resources = (struct list_head *) __get_free_page(GFP_KERNEL);
+	if (!dlm->resources) {
+		mlog_errno(-ENOMEM);
+		kfree(dlm->name);
+		kfree(dlm);
+		dlm = NULL;
+		goto leave;
+	}
+	memset(dlm->resources, 0, PAGE_SIZE);
+
+	for (i=0; i<DLM_HASH_SIZE; i++)
+		INIT_LIST_HEAD(&dlm->resources[i]);
+
+	strcpy(dlm->name, domain);
+	dlm->key = key;
+	dlm->node_num = o2nm_this_node();
+
+	spin_lock_init(&dlm->spinlock);
+	spin_lock_init(&dlm->master_lock);
+	spin_lock_init(&dlm->ast_lock);
+	INIT_LIST_HEAD(&dlm->list);
+	INIT_LIST_HEAD(&dlm->dirty_list);
+	INIT_LIST_HEAD(&dlm->reco.resources);
+	INIT_LIST_HEAD(&dlm->reco.received);
+	INIT_LIST_HEAD(&dlm->reco.node_data);
+	INIT_LIST_HEAD(&dlm->purge_list);
+	INIT_LIST_HEAD(&dlm->dlm_domain_handlers);
+	dlm->reco.state = 0;
+
+	INIT_LIST_HEAD(&dlm->pending_asts);
+	INIT_LIST_HEAD(&dlm->pending_basts);
+
+	mlog(0, "dlm->recovery_map=%p, &(dlm->recovery_map[0])=%p\n",
+		  dlm->recovery_map, &(dlm->recovery_map[0]));
+
+	memset(dlm->recovery_map, 0, sizeof(dlm->recovery_map));
+	memset(dlm->live_nodes_map, 0, sizeof(dlm->live_nodes_map));
+	memset(dlm->domain_map, 0, sizeof(dlm->domain_map));
+
+	dlm->dlm_thread_task = NULL;
+	dlm->dlm_reco_thread_task = NULL;
+	init_waitqueue_head(&dlm->dlm_thread_wq);
+	init_waitqueue_head(&dlm->dlm_reco_thread_wq);
+	init_waitqueue_head(&dlm->reco.event);
+	init_waitqueue_head(&dlm->ast_wq);
+	init_waitqueue_head(&dlm->migration_wq);
+	INIT_LIST_HEAD(&dlm->master_list);
+	INIT_LIST_HEAD(&dlm->mle_hb_events);
+
+	dlm->joining_node = DLM_LOCK_RES_OWNER_UNKNOWN;
+	init_waitqueue_head(&dlm->dlm_join_events);
+
+	dlm->reco.new_master = O2NM_INVALID_NODE_NUM;
+	dlm->reco.dead_node = O2NM_INVALID_NODE_NUM;
+	atomic_set(&dlm->local_resources, 0);
+	atomic_set(&dlm->remote_resources, 0);
+	atomic_set(&dlm->unknown_resources, 0);
+
+	spin_lock_init(&dlm->work_lock);
+	INIT_LIST_HEAD(&dlm->work_list);
+	INIT_WORK(&dlm->dispatched_work, dlm_dispatch_work, dlm);
+
+	kref_init(&dlm->dlm_refs);
+	dlm->dlm_state = DLM_CTXT_NEW;
+
+	INIT_LIST_HEAD(&dlm->dlm_eviction_callbacks);
+
+	mlog(0, "context init: refcount %u\n",
+		  atomic_read(&dlm->dlm_refs.refcount));
+
+leave:
+	return dlm;
+}
+
+/*
+ * dlm_register_domain: one-time setup per "domain"
+ */
+struct dlm_ctxt * dlm_register_domain(const char *domain,
+			       u32 key)
+{
+	int ret;
+	struct dlm_ctxt *dlm = NULL;
+	struct dlm_ctxt *new_ctxt = NULL;
+
+	if (strlen(domain) > O2NM_MAX_NAME_LEN) {
+		ret = -ENAMETOOLONG;
+		mlog(ML_ERROR, "domain name length too long\n");
+		goto leave;
+	}
+
+	if (!o2hb_check_local_node_heartbeating()) {
+		mlog(ML_ERROR, "the local node has not been configured, or is "
+		     "not heartbeating\n");
+		ret = -EPROTO;
+		goto leave;
+	}
+
+	mlog(0, "register called for domain \"%s\"\n", domain);
+
+retry:
+	dlm = NULL;
+	if (signal_pending(current)) {
+		ret = -ERESTARTSYS;
+		mlog_errno(ret);
+		goto leave;
+	}
+
+	spin_lock(&dlm_domain_lock);
+
+	dlm = __dlm_lookup_domain(domain);
+	if (dlm) {
+		if (dlm->dlm_state != DLM_CTXT_JOINED) {
+			spin_unlock(&dlm_domain_lock);
+
+			mlog(0, "This ctxt is not joined yet!\n");
+			wait_event_interruptible(dlm_domain_events,
+						 dlm_wait_on_domain_helper(
+							 domain));
+			goto retry;
+		}
+
+		__dlm_get(dlm);
+		dlm->num_joins++;
+
+		spin_unlock(&dlm_domain_lock);
+
+		ret = 0;
+		goto leave;
+	}
+
+	/* doesn't exist */
+	if (!new_ctxt) {
+		spin_unlock(&dlm_domain_lock);
+
+		new_ctxt = dlm_alloc_ctxt(domain, key);
+		if (new_ctxt)
+			goto retry;
+
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto leave;
+	}
+
+	/* a little variable switch-a-roo here... */
+	dlm = new_ctxt;
+	new_ctxt = NULL;
+
+	/* add the new domain */
+	list_add_tail(&dlm->list, &dlm_domains);
+	spin_unlock(&dlm_domain_lock);
+
+	ret = dlm_join_domain(dlm);
+	if (ret) {
+		mlog_errno(ret);
+		dlm_put(dlm);
+		goto leave;
+	}
+
+	ret = 0;
+leave:
+	if (new_ctxt)
+		dlm_free_ctxt_mem(new_ctxt);
+
+	if (ret < 0)
+		dlm = ERR_PTR(ret);
+
+	return dlm;
+}
+EXPORT_SYMBOL_GPL(dlm_register_domain);
+
+static LIST_HEAD(dlm_join_handlers);
+
+static void dlm_unregister_net_handlers(void)
+{
+	o2net_unregister_handler_list(&dlm_join_handlers);
+}
+
+static int dlm_register_net_handlers(void)
+{
+	int status = 0;
+
+	status = o2net_register_handler(DLM_QUERY_JOIN_MSG, DLM_MOD_KEY,
+					sizeof(struct dlm_query_join_request),
+					dlm_query_join_handler,
+					NULL, &dlm_join_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_ASSERT_JOINED_MSG, DLM_MOD_KEY,
+					sizeof(struct dlm_assert_joined),
+					dlm_assert_joined_handler,
+					NULL, &dlm_join_handlers);
+	if (status)
+		goto bail;
+
+	status = o2net_register_handler(DLM_CANCEL_JOIN_MSG, DLM_MOD_KEY,
+					sizeof(struct dlm_cancel_join),
+					dlm_cancel_join_handler,
+					NULL, &dlm_join_handlers);
+
+bail:
+	if (status < 0)
+		dlm_unregister_net_handlers();
+
+	return status;
+}
+
+/* Domain eviction callback handling.
+ *
+ * The file system requires notification of node death *before* the
+ * dlm completes it's recovery work, otherwise it may be able to
+ * acquire locks on resources requiring recovery. Since the dlm can
+ * evict a node from it's domain *before* heartbeat fires, a similar
+ * mechanism is required. */
+
+/* Eviction is not expected to happen often, so a per-domain lock is
+ * not necessary. Eviction callbacks are allowed to sleep for short
+ * periods of time. */
+static DECLARE_RWSEM(dlm_callback_sem);
+
+void dlm_fire_domain_eviction_callbacks(struct dlm_ctxt *dlm,
+					int node_num)
+{
+	struct list_head *iter;
+	struct dlm_eviction_cb *cb;
+
+	down_read(&dlm_callback_sem);
+	list_for_each(iter, &dlm->dlm_eviction_callbacks) {
+		cb = list_entry(iter, struct dlm_eviction_cb, ec_item);
+
+		cb->ec_func(node_num, cb->ec_data);
+	}
+	up_read(&dlm_callback_sem);
+}
+
+void dlm_setup_eviction_cb(struct dlm_eviction_cb *cb,
+			   dlm_eviction_func *f,
+			   void *data)
+{
+	INIT_LIST_HEAD(&cb->ec_item);
+	cb->ec_func = f;
+	cb->ec_data = data;
+}
+EXPORT_SYMBOL_GPL(dlm_setup_eviction_cb);
+
+void dlm_register_eviction_cb(struct dlm_ctxt *dlm,
+			      struct dlm_eviction_cb *cb)
+{
+	down_write(&dlm_callback_sem);
+	list_add_tail(&cb->ec_item, &dlm->dlm_eviction_callbacks);
+	up_write(&dlm_callback_sem);
+}
+EXPORT_SYMBOL_GPL(dlm_register_eviction_cb);
+
+void dlm_unregister_eviction_cb(struct dlm_eviction_cb *cb)
+{
+	down_write(&dlm_callback_sem);
+	list_del_init(&cb->ec_item);
+	up_write(&dlm_callback_sem);
+}
+EXPORT_SYMBOL_GPL(dlm_unregister_eviction_cb);
+
+static int __init dlm_init(void)
+{
+	int status;
+
+	dlm_print_version();
+
+	status = dlm_init_mle_cache();
+	if (status)
+		return -1;
+
+	status = dlm_register_net_handlers();
+	if (status) {
+		dlm_destroy_mle_cache();
+		return -1;
+	}
+
+	return 0;
+}
+
+static void __exit dlm_exit (void)
+{
+	dlm_unregister_net_handlers();
+	dlm_destroy_mle_cache();
+}
+
+MODULE_AUTHOR("Oracle");
+MODULE_LICENSE("GPL");
+
+module_init(dlm_init);
+module_exit(dlm_exit);
diff --git a/fs/ocfs2/dlm/dlmdomain.h b/fs/ocfs2/dlm/dlmdomain.h
new file mode 100644
index 0000000..2f7f60b
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmdomain.h
@@ -0,0 +1,36 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmdomain.h
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+#ifndef DLMDOMAIN_H
+#define DLMDOMAIN_H
+
+extern spinlock_t dlm_domain_lock;
+extern struct list_head dlm_domains;
+
+int dlm_joined(struct dlm_ctxt *dlm);
+int dlm_shutting_down(struct dlm_ctxt *dlm);
+void dlm_fire_domain_eviction_callbacks(struct dlm_ctxt *dlm,
+					int node_num);
+
+#endif
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c
new file mode 100644
index 0000000..dd2d24d
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmfs.c
@@ -0,0 +1,640 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmfs.c
+ *
+ * Code which implements the kernel side of a minimal userspace
+ * interface to our DLM. This file handles the virtual file system
+ * used for communication with userspace. Credit should go to ramfs,
+ * which was a template for the fs side of this module.
+ *
+ * Copyright (C) 2003, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+/* Simple VFS hooks based on: */
+/*
+ * Resizable simple ram filesystem for Linux.
+ *
+ * Copyright (C) 2000 Linus Torvalds.
+ *               2000 Transmeta Corp.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/backing-dev.h>
+
+#include <asm/uaccess.h>
+
+
+#include "cluster/nodemanager.h"
+#include "cluster/heartbeat.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+
+#include "userdlm.h"
+
+#include "dlmfsver.h"
+
+#define MLOG_MASK_PREFIX ML_DLMFS
+#include "cluster/masklog.h"
+
+static struct super_operations dlmfs_ops;
+static struct file_operations dlmfs_file_operations;
+static struct inode_operations dlmfs_dir_inode_operations;
+static struct inode_operations dlmfs_root_inode_operations;
+static struct inode_operations dlmfs_file_inode_operations;
+static kmem_cache_t *dlmfs_inode_cache;
+
+struct workqueue_struct *user_dlm_worker;
+
+/*
+ * decodes a set of open flags into a valid lock level and a set of flags.
+ * returns < 0 if we have invalid flags
+ * flags which mean something to us:
+ * O_RDONLY -> PRMODE level
+ * O_WRONLY -> EXMODE level
+ *
+ * O_NONBLOCK -> LKM_NOQUEUE
+ */
+static int dlmfs_decode_open_flags(int open_flags,
+				   int *level,
+				   int *flags)
+{
+	if (open_flags & (O_WRONLY|O_RDWR))
+		*level = LKM_EXMODE;
+	else
+		*level = LKM_PRMODE;
+
+	*flags = 0;
+	if (open_flags & O_NONBLOCK)
+		*flags |= LKM_NOQUEUE;
+
+	return 0;
+}
+
+static int dlmfs_file_open(struct inode *inode,
+			   struct file *file)
+{
+	int status, level, flags;
+	struct dlmfs_filp_private *fp = NULL;
+	struct dlmfs_inode_private *ip;
+
+	if (S_ISDIR(inode->i_mode))
+		BUG();
+
+	mlog(0, "open called on inode %lu, flags 0x%x\n", inode->i_ino,
+		file->f_flags);
+
+	status = dlmfs_decode_open_flags(file->f_flags, &level, &flags);
+	if (status < 0)
+		goto bail;
+
+	/* We don't want to honor O_APPEND at read/write time as it
+	 * doesn't make sense for LVB writes. */
+	file->f_flags &= ~O_APPEND;
+
+	fp = kmalloc(sizeof(*fp), GFP_KERNEL);
+	if (!fp) {
+		status = -ENOMEM;
+		goto bail;
+	}
+	fp->fp_lock_level = level;
+
+	ip = DLMFS_I(inode);
+
+	status = user_dlm_cluster_lock(&ip->ip_lockres, level, flags);
+	if (status < 0) {
+		/* this is a strange error to return here but I want
+		 * to be able userspace to be able to distinguish a
+		 * valid lock request from one that simply couldn't be
+		 * granted. */
+		if (flags & LKM_NOQUEUE && status == -EAGAIN)
+			status = -ETXTBSY;
+		kfree(fp);
+		goto bail;
+	}
+
+	file->private_data = fp;
+bail:
+	return status;
+}
+
+static int dlmfs_file_release(struct inode *inode,
+			      struct file *file)
+{
+	int level, status;
+	struct dlmfs_inode_private *ip = DLMFS_I(inode);
+	struct dlmfs_filp_private *fp =
+		(struct dlmfs_filp_private *) file->private_data;
+
+	if (S_ISDIR(inode->i_mode))
+		BUG();
+
+	mlog(0, "close called on inode %lu\n", inode->i_ino);
+
+	status = 0;
+	if (fp) {
+		level = fp->fp_lock_level;
+		if (level != LKM_IVMODE)
+			user_dlm_cluster_unlock(&ip->ip_lockres, level);
+
+		kfree(fp);
+		file->private_data = NULL;
+	}
+
+	return 0;
+}
+
+static ssize_t dlmfs_file_read(struct file *filp,
+			       char __user *buf,
+			       size_t count,
+			       loff_t *ppos)
+{
+	int bytes_left;
+	ssize_t readlen;
+	char *lvb_buf;
+	struct inode *inode = filp->f_dentry->d_inode;
+
+	mlog(0, "inode %lu, count = %zu, *ppos = %llu\n",
+		inode->i_ino, count, *ppos);
+
+	if (*ppos >= i_size_read(inode))
+		return 0;
+
+	if (!count)
+		return 0;
+
+	if (!access_ok(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+
+	/* don't read past the lvb */
+	if ((count + *ppos) > i_size_read(inode))
+		readlen = i_size_read(inode) - *ppos;
+	else
+		readlen = count - *ppos;
+
+	lvb_buf = kmalloc(readlen, GFP_KERNEL);
+	if (!lvb_buf)
+		return -ENOMEM;
+
+	user_dlm_read_lvb(inode, lvb_buf, readlen);
+	bytes_left = __copy_to_user(buf, lvb_buf, readlen);
+	readlen -= bytes_left;
+
+	kfree(lvb_buf);
+
+	*ppos = *ppos + readlen;
+
+	mlog(0, "read %zd bytes\n", readlen);
+	return readlen;
+}
+
+static ssize_t dlmfs_file_write(struct file *filp,
+				const char __user *buf,
+				size_t count,
+				loff_t *ppos)
+{
+	int bytes_left;
+	ssize_t writelen;
+	char *lvb_buf;
+	struct inode *inode = filp->f_dentry->d_inode;
+
+	mlog(0, "inode %lu, count = %zu, *ppos = %llu\n",
+		inode->i_ino, count, *ppos);
+
+	if (*ppos >= i_size_read(inode))
+		return -ENOSPC;
+
+	if (!count)
+		return 0;
+
+	if (!access_ok(VERIFY_READ, buf, count))
+		return -EFAULT;
+
+	/* don't write past the lvb */
+	if ((count + *ppos) > i_size_read(inode))
+		writelen = i_size_read(inode) - *ppos;
+	else
+		writelen = count - *ppos;
+
+	lvb_buf = kmalloc(writelen, GFP_KERNEL);
+	if (!lvb_buf)
+		return -ENOMEM;
+
+	bytes_left = copy_from_user(lvb_buf, buf, writelen);
+	writelen -= bytes_left;
+	if (writelen)
+		user_dlm_write_lvb(inode, lvb_buf, writelen);
+
+	kfree(lvb_buf);
+
+	*ppos = *ppos + writelen;
+	mlog(0, "wrote %zd bytes\n", writelen);
+	return writelen;
+}
+
+static void dlmfs_init_once(void *foo,
+			    kmem_cache_t *cachep,
+			    unsigned long flags)
+{
+	struct dlmfs_inode_private *ip =
+		(struct dlmfs_inode_private *) foo;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		ip->ip_dlm = NULL;
+		ip->ip_parent = NULL;
+
+		inode_init_once(&ip->ip_vfs_inode);
+	}
+}
+
+static struct inode *dlmfs_alloc_inode(struct super_block *sb)
+{
+	struct dlmfs_inode_private *ip;
+
+	ip = kmem_cache_alloc(dlmfs_inode_cache, SLAB_NOFS);
+	if (!ip)
+		return NULL;
+
+	return &ip->ip_vfs_inode;
+}
+
+static void dlmfs_destroy_inode(struct inode *inode)
+{
+	kmem_cache_free(dlmfs_inode_cache, DLMFS_I(inode));
+}
+
+static void dlmfs_clear_inode(struct inode *inode)
+{
+	int status;
+	struct dlmfs_inode_private *ip;
+
+	if (!inode)
+		return;
+
+	mlog(0, "inode %lu\n", inode->i_ino);
+
+	ip = DLMFS_I(inode);
+
+	if (S_ISREG(inode->i_mode)) {
+		status = user_dlm_destroy_lock(&ip->ip_lockres);
+		if (status < 0)
+			mlog_errno(status);
+		iput(ip->ip_parent);
+		goto clear_fields;
+	}
+
+	mlog(0, "we're a directory, ip->ip_dlm = 0x%p\n", ip->ip_dlm);
+	/* we must be a directory. If required, lets unregister the
+	 * dlm context now. */
+	if (ip->ip_dlm)
+		user_dlm_unregister_context(ip->ip_dlm);
+clear_fields:
+	ip->ip_parent = NULL;
+	ip->ip_dlm = NULL;
+}
+
+static struct backing_dev_info dlmfs_backing_dev_info = {
+	.ra_pages	= 0,	/* No readahead */
+	.capabilities	= BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
+};
+
+static struct inode *dlmfs_get_root_inode(struct super_block *sb)
+{
+	struct inode *inode = new_inode(sb);
+	int mode = S_IFDIR | 0755;
+	struct dlmfs_inode_private *ip;
+
+	if (inode) {
+		ip = DLMFS_I(inode);
+
+		inode->i_mode = mode;
+		inode->i_uid = current->fsuid;
+		inode->i_gid = current->fsgid;
+		inode->i_blksize = PAGE_CACHE_SIZE;
+		inode->i_blocks = 0;
+		inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		inode->i_nlink++;
+
+		inode->i_fop = &simple_dir_operations;
+		inode->i_op = &dlmfs_root_inode_operations;
+	}
+
+	return inode;
+}
+
+static struct inode *dlmfs_get_inode(struct inode *parent,
+				     struct dentry *dentry,
+				     int mode)
+{
+	struct super_block *sb = parent->i_sb;
+	struct inode * inode = new_inode(sb);
+	struct dlmfs_inode_private *ip;
+
+	if (!inode)
+		return NULL;
+
+	inode->i_mode = mode;
+	inode->i_uid = current->fsuid;
+	inode->i_gid = current->fsgid;
+	inode->i_blksize = PAGE_CACHE_SIZE;
+	inode->i_blocks = 0;
+	inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+
+	ip = DLMFS_I(inode);
+	ip->ip_dlm = DLMFS_I(parent)->ip_dlm;
+
+	switch (mode & S_IFMT) {
+	default:
+		/* for now we don't support anything other than
+		 * directories and regular files. */
+		BUG();
+		break;
+	case S_IFREG:
+		inode->i_op = &dlmfs_file_inode_operations;
+		inode->i_fop = &dlmfs_file_operations;
+
+		i_size_write(inode,  DLM_LVB_LEN);
+
+		user_dlm_lock_res_init(&ip->ip_lockres, dentry);
+
+		/* released at clear_inode time, this insures that we
+		 * get to drop the dlm reference on each lock *before*
+		 * we call the unregister code for releasing parent
+		 * directories. */
+		ip->ip_parent = igrab(parent);
+		BUG_ON(!ip->ip_parent);
+		break;
+	case S_IFDIR:
+		inode->i_op = &dlmfs_dir_inode_operations;
+		inode->i_fop = &simple_dir_operations;
+
+		/* directory inodes start off with i_nlink ==
+		 * 2 (for "." entry) */
+		inode->i_nlink++;
+		break;
+	}
+
+	if (parent->i_mode & S_ISGID) {
+		inode->i_gid = parent->i_gid;
+		if (S_ISDIR(mode))
+			inode->i_mode |= S_ISGID;
+	}
+
+	return inode;
+}
+
+/*
+ * File creation. Allocate an inode, and we're done..
+ */
+/* SMP-safe */
+static int dlmfs_mkdir(struct inode * dir,
+		       struct dentry * dentry,
+		       int mode)
+{
+	int status;
+	struct inode *inode = NULL;
+	struct qstr *domain = &dentry->d_name;
+	struct dlmfs_inode_private *ip;
+	struct dlm_ctxt *dlm;
+
+	mlog(0, "mkdir %.*s\n", domain->len, domain->name);
+
+	/* verify that we have a proper domain */
+	if (domain->len >= O2NM_MAX_NAME_LEN) {
+		status = -EINVAL;
+		mlog(ML_ERROR, "invalid domain name for directory.\n");
+		goto bail;
+	}
+
+	inode = dlmfs_get_inode(dir, dentry, mode | S_IFDIR);
+	if (!inode) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	ip = DLMFS_I(inode);
+
+	dlm = user_dlm_register_context(domain);
+	if (IS_ERR(dlm)) {
+		status = PTR_ERR(dlm);
+		mlog(ML_ERROR, "Error %d could not register domain \"%.*s\"\n",
+		     status, domain->len, domain->name);
+		goto bail;
+	}
+	ip->ip_dlm = dlm;
+
+	dir->i_nlink++;
+	d_instantiate(dentry, inode);
+	dget(dentry);	/* Extra count - pin the dentry in core */
+
+	status = 0;
+bail:
+	if (status < 0)
+		iput(inode);
+	return status;
+}
+
+static int dlmfs_create(struct inode *dir,
+			struct dentry *dentry,
+			int mode,
+			struct nameidata *nd)
+{
+	int status = 0;
+	struct inode *inode;
+	struct qstr *name = &dentry->d_name;
+
+	mlog(0, "create %.*s\n", name->len, name->name);
+
+	/* verify name is valid and doesn't contain any dlm reserved
+	 * characters */
+	if (name->len >= USER_DLM_LOCK_ID_MAX_LEN ||
+	    name->name[0] == '$') {
+		status = -EINVAL;
+		mlog(ML_ERROR, "invalid lock name, %.*s\n", name->len,
+		     name->name);
+		goto bail;
+	}
+
+	inode = dlmfs_get_inode(dir, dentry, mode | S_IFREG);
+	if (!inode) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	d_instantiate(dentry, inode);
+	dget(dentry);	/* Extra count - pin the dentry in core */
+bail:
+	return status;
+}
+
+static int dlmfs_unlink(struct inode *dir,
+			struct dentry *dentry)
+{
+	int status;
+	struct inode *inode = dentry->d_inode;
+
+	mlog(0, "unlink inode %lu\n", inode->i_ino);
+
+	/* if there are no current holders, or none that are waiting
+	 * to acquire a lock, this basically destroys our lockres. */
+	status = user_dlm_destroy_lock(&DLMFS_I(inode)->ip_lockres);
+	if (status < 0) {
+		mlog(ML_ERROR, "unlink %.*s, error %d from destroy\n",
+		     dentry->d_name.len, dentry->d_name.name, status);
+		goto bail;
+	}
+	status = simple_unlink(dir, dentry);
+bail:
+	return status;
+}
+
+static int dlmfs_fill_super(struct super_block * sb,
+			    void * data,
+			    int silent)
+{
+	struct inode * inode;
+	struct dentry * root;
+
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = DLMFS_MAGIC;
+	sb->s_op = &dlmfs_ops;
+	inode = dlmfs_get_root_inode(sb);
+	if (!inode)
+		return -ENOMEM;
+
+	root = d_alloc_root(inode);
+	if (!root) {
+		iput(inode);
+		return -ENOMEM;
+	}
+	sb->s_root = root;
+	return 0;
+}
+
+static struct file_operations dlmfs_file_operations = {
+	.open		= dlmfs_file_open,
+	.release	= dlmfs_file_release,
+	.read		= dlmfs_file_read,
+	.write		= dlmfs_file_write,
+};
+
+static struct inode_operations dlmfs_dir_inode_operations = {
+	.create		= dlmfs_create,
+	.lookup		= simple_lookup,
+	.unlink		= dlmfs_unlink,
+};
+
+/* this way we can restrict mkdir to only the toplevel of the fs. */
+static struct inode_operations dlmfs_root_inode_operations = {
+	.lookup		= simple_lookup,
+	.mkdir		= dlmfs_mkdir,
+	.rmdir		= simple_rmdir,
+};
+
+static struct super_operations dlmfs_ops = {
+	.statfs		= simple_statfs,
+	.alloc_inode	= dlmfs_alloc_inode,
+	.destroy_inode	= dlmfs_destroy_inode,
+	.clear_inode	= dlmfs_clear_inode,
+	.drop_inode	= generic_delete_inode,
+};
+
+static struct inode_operations dlmfs_file_inode_operations = {
+	.getattr	= simple_getattr,
+};
+
+static struct super_block *dlmfs_get_sb(struct file_system_type *fs_type,
+	int flags, const char *dev_name, void *data)
+{
+	return get_sb_nodev(fs_type, flags, data, dlmfs_fill_super);
+}
+
+static struct file_system_type dlmfs_fs_type = {
+	.owner		= THIS_MODULE,
+	.name		= "ocfs2_dlmfs",
+	.get_sb		= dlmfs_get_sb,
+	.kill_sb	= kill_litter_super,
+};
+
+static int __init init_dlmfs_fs(void)
+{
+	int status;
+	int cleanup_inode = 0, cleanup_worker = 0;
+
+	dlmfs_print_version();
+
+	dlmfs_inode_cache = kmem_cache_create("dlmfs_inode_cache",
+				sizeof(struct dlmfs_inode_private),
+				0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+				dlmfs_init_once, NULL);
+	if (!dlmfs_inode_cache)
+		return -ENOMEM;
+	cleanup_inode = 1;
+
+	user_dlm_worker = create_singlethread_workqueue("user_dlm");
+	if (!user_dlm_worker) {
+		status = -ENOMEM;
+		goto bail;
+	}
+	cleanup_worker = 1;
+
+	status = register_filesystem(&dlmfs_fs_type);
+bail:
+	if (status) {
+		if (cleanup_inode)
+			kmem_cache_destroy(dlmfs_inode_cache);
+		if (cleanup_worker)
+			destroy_workqueue(user_dlm_worker);
+	} else
+		printk("OCFS2 User DLM kernel interface loaded\n");
+	return status;
+}
+
+static void __exit exit_dlmfs_fs(void)
+{
+	unregister_filesystem(&dlmfs_fs_type);
+
+	flush_workqueue(user_dlm_worker);
+	destroy_workqueue(user_dlm_worker);
+
+	if (kmem_cache_destroy(dlmfs_inode_cache))
+		printk(KERN_INFO "dlmfs_inode_cache: not all structures "
+		       "were freed\n");
+}
+
+MODULE_AUTHOR("Oracle");
+MODULE_LICENSE("GPL");
+
+module_init(init_dlmfs_fs)
+module_exit(exit_dlmfs_fs)
diff --git a/fs/ocfs2/dlm/dlmfsver.c b/fs/ocfs2/dlm/dlmfsver.c
new file mode 100644
index 0000000..d2be3ad
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmfsver.c
@@ -0,0 +1,42 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmfsver.c
+ *
+ * version string
+ *
+ * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include "dlmfsver.h"
+
+#define DLM_BUILD_VERSION "1.3.3"
+
+#define VERSION_STR "OCFS2 DLMFS " DLM_BUILD_VERSION
+
+void dlmfs_print_version(void)
+{
+	printk(KERN_INFO "%s\n", VERSION_STR);
+}
+
+MODULE_DESCRIPTION(VERSION_STR);
+
+MODULE_VERSION(DLM_BUILD_VERSION);
diff --git a/fs/ocfs2/dlm/dlmfsver.h b/fs/ocfs2/dlm/dlmfsver.h
new file mode 100644
index 0000000..f35eadb
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmfsver.h
@@ -0,0 +1,31 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmver.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef DLMFS_VER_H
+#define DLMFS_VER_H
+
+void dlmfs_print_version(void);
+
+#endif /* DLMFS_VER_H */
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c
new file mode 100644
index 0000000..d1a0038
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmlock.c
@@ -0,0 +1,676 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmlock.c
+ *
+ * underlying calls for lock creation
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include <linux/random.h>
+#include <linux/blkdev.h>
+#include <linux/socket.h>
+#include <linux/inet.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+
+
+#include "cluster/heartbeat.h"
+#include "cluster/nodemanager.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+#include "dlmcommon.h"
+
+#include "dlmconvert.h"
+
+#define MLOG_MASK_PREFIX ML_DLM
+#include "cluster/masklog.h"
+
+static spinlock_t dlm_cookie_lock = SPIN_LOCK_UNLOCKED;
+static u64 dlm_next_cookie = 1;
+
+static enum dlm_status dlm_send_remote_lock_request(struct dlm_ctxt *dlm,
+					       struct dlm_lock_resource *res,
+					       struct dlm_lock *lock, int flags);
+static void dlm_init_lock(struct dlm_lock *newlock, int type,
+			  u8 node, u64 cookie);
+static void dlm_lock_release(struct kref *kref);
+static void dlm_lock_detach_lockres(struct dlm_lock *lock);
+
+/* Tell us whether we can grant a new lock request.
+ * locking:
+ *   caller needs:  res->spinlock
+ *   taken:         none
+ *   held on exit:  none
+ * returns: 1 if the lock can be granted, 0 otherwise.
+ */
+static int dlm_can_grant_new_lock(struct dlm_lock_resource *res,
+				  struct dlm_lock *lock)
+{
+	struct list_head *iter;
+	struct dlm_lock *tmplock;
+
+	list_for_each(iter, &res->granted) {
+		tmplock = list_entry(iter, struct dlm_lock, list);
+
+		if (!dlm_lock_compatible(tmplock->ml.type, lock->ml.type))
+			return 0;
+	}
+
+	list_for_each(iter, &res->converting) {
+		tmplock = list_entry(iter, struct dlm_lock, list);
+
+		if (!dlm_lock_compatible(tmplock->ml.type, lock->ml.type))
+			return 0;
+	}
+
+	return 1;
+}
+
+/* performs lock creation at the lockres master site
+ * locking:
+ *   caller needs:  none
+ *   taken:         takes and drops res->spinlock
+ *   held on exit:  none
+ * returns: DLM_NORMAL, DLM_NOTQUEUED
+ */
+static enum dlm_status dlmlock_master(struct dlm_ctxt *dlm,
+				      struct dlm_lock_resource *res,
+				      struct dlm_lock *lock, int flags)
+{
+	int call_ast = 0, kick_thread = 0;
+	enum dlm_status status = DLM_NORMAL;
+
+	mlog_entry("type=%d\n", lock->ml.type);
+
+	spin_lock(&res->spinlock);
+	/* if called from dlm_create_lock_handler, need to
+	 * ensure it will not sleep in dlm_wait_on_lockres */
+	status = __dlm_lockres_state_to_status(res);
+	if (status != DLM_NORMAL &&
+	    lock->ml.node != dlm->node_num) {
+		/* erf.  state changed after lock was dropped. */
+		spin_unlock(&res->spinlock);
+		dlm_error(status);
+		return status;
+	}
+	__dlm_wait_on_lockres(res);
+	__dlm_lockres_reserve_ast(res);
+
+	if (dlm_can_grant_new_lock(res, lock)) {
+		mlog(0, "I can grant this lock right away\n");
+		/* got it right away */
+		lock->lksb->status = DLM_NORMAL;
+		status = DLM_NORMAL;
+		dlm_lock_get(lock);
+		list_add_tail(&lock->list, &res->granted);
+
+		/* for the recovery lock, we can't allow the ast
+		 * to be queued since the dlmthread is already
+		 * frozen.  but the recovery lock is always locked
+		 * with LKM_NOQUEUE so we do not need the ast in
+		 * this special case */
+		if (!dlm_is_recovery_lock(res->lockname.name,
+					  res->lockname.len)) {
+			kick_thread = 1;
+			call_ast = 1;
+		}
+	} else {
+		/* for NOQUEUE request, unless we get the
+		 * lock right away, return DLM_NOTQUEUED */
+		if (flags & LKM_NOQUEUE)
+			status = DLM_NOTQUEUED;
+		else {
+			dlm_lock_get(lock);
+			list_add_tail(&lock->list, &res->blocked);
+			kick_thread = 1;
+		}
+	}
+
+	spin_unlock(&res->spinlock);
+	wake_up(&res->wq);
+
+	/* either queue the ast or release it */
+	if (call_ast)
+		dlm_queue_ast(dlm, lock);
+	else
+		dlm_lockres_release_ast(dlm, res);
+
+	dlm_lockres_calc_usage(dlm, res);
+	if (kick_thread)
+		dlm_kick_thread(dlm, res);
+
+	return status;
+}
+
+void dlm_revert_pending_lock(struct dlm_lock_resource *res,
+			     struct dlm_lock *lock)
+{
+	/* remove from local queue if it failed */
+	list_del_init(&lock->list);
+	lock->lksb->flags &= ~DLM_LKSB_GET_LVB;
+}
+
+
+/*
+ * locking:
+ *   caller needs:  none
+ *   taken:         takes and drops res->spinlock
+ *   held on exit:  none
+ * returns: DLM_DENIED, DLM_RECOVERING, or net status
+ */
+static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm,
+				      struct dlm_lock_resource *res,
+				      struct dlm_lock *lock, int flags)
+{
+	enum dlm_status status = DLM_DENIED;
+
+	mlog_entry("type=%d\n", lock->ml.type);
+	mlog(0, "lockres %.*s, flags = 0x%x\n", res->lockname.len,
+	     res->lockname.name, flags);
+
+	spin_lock(&res->spinlock);
+
+	/* will exit this call with spinlock held */
+	__dlm_wait_on_lockres(res);
+	res->state |= DLM_LOCK_RES_IN_PROGRESS;
+
+	/* add lock to local (secondary) queue */
+	dlm_lock_get(lock);
+	list_add_tail(&lock->list, &res->blocked);
+	lock->lock_pending = 1;
+	spin_unlock(&res->spinlock);
+
+	/* spec seems to say that you will get DLM_NORMAL when the lock
+	 * has been queued, meaning we need to wait for a reply here. */
+	status = dlm_send_remote_lock_request(dlm, res, lock, flags);
+
+	spin_lock(&res->spinlock);
+	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
+	lock->lock_pending = 0;
+	if (status != DLM_NORMAL) {
+		if (status != DLM_NOTQUEUED)
+			dlm_error(status);
+		dlm_revert_pending_lock(res, lock);
+		dlm_lock_put(lock);
+	}
+	spin_unlock(&res->spinlock);
+
+	dlm_lockres_calc_usage(dlm, res);
+
+	wake_up(&res->wq);
+	return status;
+}
+
+
+/* for remote lock creation.
+ * locking:
+ *   caller needs:  none, but need res->state & DLM_LOCK_RES_IN_PROGRESS
+ *   taken:         none
+ *   held on exit:  none
+ * returns: DLM_NOLOCKMGR, or net status
+ */
+static enum dlm_status dlm_send_remote_lock_request(struct dlm_ctxt *dlm,
+					       struct dlm_lock_resource *res,
+					       struct dlm_lock *lock, int flags)
+{
+	struct dlm_create_lock create;
+	int tmpret, status = 0;
+	enum dlm_status ret;
+
+	mlog_entry_void();
+
+	memset(&create, 0, sizeof(create));
+	create.node_idx = dlm->node_num;
+	create.requested_type = lock->ml.type;
+	create.cookie = lock->ml.cookie;
+	create.namelen = res->lockname.len;
+	create.flags = cpu_to_be32(flags);
+	memcpy(create.name, res->lockname.name, create.namelen);
+
+	tmpret = o2net_send_message(DLM_CREATE_LOCK_MSG, dlm->key, &create,
+				    sizeof(create), res->owner, &status);
+	if (tmpret >= 0) {
+		// successfully sent and received
+		ret = status;  // this is already a dlm_status
+	} else {
+		mlog_errno(tmpret);
+		if (dlm_is_host_down(tmpret)) {
+			ret = DLM_RECOVERING;
+			mlog(0, "node %u died so returning DLM_RECOVERING "
+			     "from lock message!\n", res->owner);
+		} else {
+			ret = dlm_err_to_dlm_status(tmpret);
+		}
+	}
+
+	return ret;
+}
+
+void dlm_lock_get(struct dlm_lock *lock)
+{
+	kref_get(&lock->lock_refs);
+}
+
+void dlm_lock_put(struct dlm_lock *lock)
+{
+	kref_put(&lock->lock_refs, dlm_lock_release);
+}
+
+static void dlm_lock_release(struct kref *kref)
+{
+	struct dlm_lock *lock;
+
+	lock = container_of(kref, struct dlm_lock, lock_refs);
+
+	BUG_ON(!list_empty(&lock->list));
+	BUG_ON(!list_empty(&lock->ast_list));
+	BUG_ON(!list_empty(&lock->bast_list));
+	BUG_ON(lock->ast_pending);
+	BUG_ON(lock->bast_pending);
+
+	dlm_lock_detach_lockres(lock);
+
+	if (lock->lksb_kernel_allocated) {
+		mlog(0, "freeing kernel-allocated lksb\n");
+		kfree(lock->lksb);
+	}
+	kfree(lock);
+}
+
+/* associate a lock with it's lockres, getting a ref on the lockres */
+void dlm_lock_attach_lockres(struct dlm_lock *lock,
+			     struct dlm_lock_resource *res)
+{
+	dlm_lockres_get(res);
+	lock->lockres = res;
+}
+
+/* drop ref on lockres, if there is still one associated with lock */
+static void dlm_lock_detach_lockres(struct dlm_lock *lock)
+{
+	struct dlm_lock_resource *res;
+
+	res = lock->lockres;
+	if (res) {
+		lock->lockres = NULL;
+		mlog(0, "removing lock's lockres reference\n");
+		dlm_lockres_put(res);
+	}
+}
+
+static void dlm_init_lock(struct dlm_lock *newlock, int type,
+			  u8 node, u64 cookie)
+{
+	INIT_LIST_HEAD(&newlock->list);
+	INIT_LIST_HEAD(&newlock->ast_list);
+	INIT_LIST_HEAD(&newlock->bast_list);
+	spin_lock_init(&newlock->spinlock);
+	newlock->ml.type = type;
+	newlock->ml.convert_type = LKM_IVMODE;
+	newlock->ml.highest_blocked = LKM_IVMODE;
+	newlock->ml.node = node;
+	newlock->ml.pad1 = 0;
+	newlock->ml.list = 0;
+	newlock->ml.flags = 0;
+	newlock->ast = NULL;
+	newlock->bast = NULL;
+	newlock->astdata = NULL;
+	newlock->ml.cookie = cpu_to_be64(cookie);
+	newlock->ast_pending = 0;
+	newlock->bast_pending = 0;
+	newlock->convert_pending = 0;
+	newlock->lock_pending = 0;
+	newlock->unlock_pending = 0;
+	newlock->cancel_pending = 0;
+	newlock->lksb_kernel_allocated = 0;
+
+	kref_init(&newlock->lock_refs);
+}
+
+struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie,
+			       struct dlm_lockstatus *lksb)
+{
+	struct dlm_lock *lock;
+	int kernel_allocated = 0;
+
+	lock = kcalloc(1, sizeof(*lock), GFP_KERNEL);
+	if (!lock)
+		return NULL;
+
+	if (!lksb) {
+		/* zero memory only if kernel-allocated */
+		lksb = kcalloc(1, sizeof(*lksb), GFP_KERNEL);
+		if (!lksb) {
+			kfree(lock);
+			return NULL;
+		}
+		kernel_allocated = 1;
+	}
+
+	dlm_init_lock(lock, type, node, cookie);
+	if (kernel_allocated)
+		lock->lksb_kernel_allocated = 1;
+	lock->lksb = lksb;
+	lksb->lockid = lock;
+	return lock;
+}
+
+/* handler for lock creation net message
+ * locking:
+ *   caller needs:  none
+ *   taken:         takes and drops res->spinlock
+ *   held on exit:  none
+ * returns: DLM_NORMAL, DLM_SYSERR, DLM_IVLOCKID, DLM_NOTQUEUED
+ */
+int dlm_create_lock_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_create_lock *create = (struct dlm_create_lock *)msg->buf;
+	struct dlm_lock_resource *res = NULL;
+	struct dlm_lock *newlock = NULL;
+	struct dlm_lockstatus *lksb = NULL;
+	enum dlm_status status = DLM_NORMAL;
+	char *name;
+	unsigned int namelen;
+
+	BUG_ON(!dlm);
+
+	mlog_entry_void();
+
+	if (!dlm_grab(dlm))
+		return DLM_REJECTED;
+
+	mlog_bug_on_msg(!dlm_domain_fully_joined(dlm),
+			"Domain %s not fully joined!\n", dlm->name);
+
+	name = create->name;
+	namelen = create->namelen;
+
+	status = DLM_IVBUFLEN;
+	if (namelen > DLM_LOCKID_NAME_MAX) {
+		dlm_error(status);
+		goto leave;
+	}
+
+	status = DLM_SYSERR;
+	newlock = dlm_new_lock(create->requested_type,
+			       create->node_idx,
+			       be64_to_cpu(create->cookie), NULL);
+	if (!newlock) {
+		dlm_error(status);
+		goto leave;
+	}
+
+	lksb = newlock->lksb;
+
+	if (be32_to_cpu(create->flags) & LKM_GET_LVB) {
+		lksb->flags |= DLM_LKSB_GET_LVB;
+		mlog(0, "set DLM_LKSB_GET_LVB flag\n");
+	}
+
+	status = DLM_IVLOCKID;
+	res = dlm_lookup_lockres(dlm, name, namelen);
+	if (!res) {
+		dlm_error(status);
+		goto leave;
+	}
+
+	spin_lock(&res->spinlock);
+	status = __dlm_lockres_state_to_status(res);
+	spin_unlock(&res->spinlock);
+
+	if (status != DLM_NORMAL) {
+		mlog(0, "lockres recovering/migrating/in-progress\n");
+		goto leave;
+	}
+
+	dlm_lock_attach_lockres(newlock, res);
+
+	status = dlmlock_master(dlm, res, newlock, be32_to_cpu(create->flags));
+leave:
+	if (status != DLM_NORMAL)
+		if (newlock)
+			dlm_lock_put(newlock);
+
+	if (res)
+		dlm_lockres_put(res);
+
+	dlm_put(dlm);
+
+	return status;
+}
+
+
+/* fetch next node-local (u8 nodenum + u56 cookie) into u64 */
+static inline void dlm_get_next_cookie(u8 node_num, u64 *cookie)
+{
+	u64 tmpnode = node_num;
+
+	/* shift single byte of node num into top 8 bits */
+	tmpnode <<= 56;
+
+	spin_lock(&dlm_cookie_lock);
+	*cookie = (dlm_next_cookie | tmpnode);
+	if (++dlm_next_cookie & 0xff00000000000000ull) {
+		mlog(0, "This node's cookie will now wrap!\n");
+		dlm_next_cookie = 1;
+	}
+	spin_unlock(&dlm_cookie_lock);
+}
+
+enum dlm_status dlmlock(struct dlm_ctxt *dlm, int mode,
+			struct dlm_lockstatus *lksb, int flags,
+			const char *name, dlm_astlockfunc_t *ast, void *data,
+			dlm_bastlockfunc_t *bast)
+{
+	enum dlm_status status;
+	struct dlm_lock_resource *res = NULL;
+	struct dlm_lock *lock = NULL;
+	int convert = 0, recovery = 0;
+
+	/* yes this function is a mess.
+	 * TODO: clean this up.  lots of common code in the
+	 *       lock and convert paths, especially in the retry blocks */
+	if (!lksb) {
+		dlm_error(DLM_BADARGS);
+		return DLM_BADARGS;
+	}
+
+	status = DLM_BADPARAM;
+	if (mode != LKM_EXMODE && mode != LKM_PRMODE && mode != LKM_NLMODE) {
+		dlm_error(status);
+		goto error;
+	}
+
+	if (flags & ~LKM_VALID_FLAGS) {
+		dlm_error(status);
+		goto error;
+	}
+
+	convert = (flags & LKM_CONVERT);
+	recovery = (flags & LKM_RECOVERY);
+
+	if (recovery &&
+	    (!dlm_is_recovery_lock(name, strlen(name)) || convert) ) {
+		dlm_error(status);
+		goto error;
+	}
+	if (convert && (flags & LKM_LOCAL)) {
+		mlog(ML_ERROR, "strange LOCAL convert request!\n");
+		goto error;
+	}
+
+	if (convert) {
+		/* CONVERT request */
+
+		/* if converting, must pass in a valid dlm_lock */
+		lock = lksb->lockid;
+		if (!lock) {
+			mlog(ML_ERROR, "NULL lock pointer in convert "
+			     "request\n");
+			goto error;
+		}
+
+		res = lock->lockres;
+		if (!res) {
+			mlog(ML_ERROR, "NULL lockres pointer in convert "
+			     "request\n");
+			goto error;
+		}
+		dlm_lockres_get(res);
+
+		/* XXX: for ocfs2 purposes, the ast/bast/astdata/lksb are
+	 	 * static after the original lock call.  convert requests will
+		 * ensure that everything is the same, or return DLM_BADARGS.
+	 	 * this means that DLM_DENIED_NOASTS will never be returned.
+	 	 */
+		if (lock->lksb != lksb || lock->ast != ast ||
+		    lock->bast != bast || lock->astdata != data) {
+			status = DLM_BADARGS;
+			mlog(ML_ERROR, "new args:  lksb=%p, ast=%p, bast=%p, "
+			     "astdata=%p\n", lksb, ast, bast, data);
+			mlog(ML_ERROR, "orig args: lksb=%p, ast=%p, bast=%p, "
+			     "astdata=%p\n", lock->lksb, lock->ast,
+			     lock->bast, lock->astdata);
+			goto error;
+		}
+retry_convert:
+		dlm_wait_for_recovery(dlm);
+
+		if (res->owner == dlm->node_num)
+			status = dlmconvert_master(dlm, res, lock, flags, mode);
+		else
+			status = dlmconvert_remote(dlm, res, lock, flags, mode);
+		if (status == DLM_RECOVERING || status == DLM_MIGRATING ||
+		    status == DLM_FORWARD) {
+			/* for now, see how this works without sleeping
+			 * and just retry right away.  I suspect the reco
+			 * or migration will complete fast enough that
+			 * no waiting will be necessary */
+			mlog(0, "retrying convert with migration/recovery/"
+			     "in-progress\n");
+			msleep(100);
+			goto retry_convert;
+		}
+	} else {
+		u64 tmpcookie;
+
+		/* LOCK request */
+		status = DLM_BADARGS;
+		if (!name) {
+			dlm_error(status);
+			goto error;
+		}
+
+		status = DLM_IVBUFLEN;
+		if (strlen(name) > DLM_LOCKID_NAME_MAX || strlen(name) < 1) {
+			dlm_error(status);
+			goto error;
+		}
+
+		dlm_get_next_cookie(dlm->node_num, &tmpcookie);
+		lock = dlm_new_lock(mode, dlm->node_num, tmpcookie, lksb);
+		if (!lock) {
+			dlm_error(status);
+			goto error;
+		}
+
+		if (!recovery)
+			dlm_wait_for_recovery(dlm);
+
+		/* find or create the lock resource */
+		res = dlm_get_lock_resource(dlm, name, flags);
+		if (!res) {
+			status = DLM_IVLOCKID;
+			dlm_error(status);
+			goto error;
+		}
+
+		mlog(0, "type=%d, flags = 0x%x\n", mode, flags);
+		mlog(0, "creating lock: lock=%p res=%p\n", lock, res);
+
+		dlm_lock_attach_lockres(lock, res);
+		lock->ast = ast;
+		lock->bast = bast;
+		lock->astdata = data;
+
+retry_lock:
+		if (flags & LKM_VALBLK) {
+			mlog(0, "LKM_VALBLK passed by caller\n");
+
+			/* LVB requests for non PR, PW or EX locks are
+			 * ignored. */
+			if (mode < LKM_PRMODE)
+				flags &= ~LKM_VALBLK;
+			else {
+				flags |= LKM_GET_LVB;
+				lock->lksb->flags |= DLM_LKSB_GET_LVB;
+			}
+		}
+
+		if (res->owner == dlm->node_num)
+			status = dlmlock_master(dlm, res, lock, flags);
+		else
+			status = dlmlock_remote(dlm, res, lock, flags);
+
+		if (status == DLM_RECOVERING || status == DLM_MIGRATING ||
+		    status == DLM_FORWARD) {
+			mlog(0, "retrying lock with migration/"
+			     "recovery/in progress\n");
+			msleep(100);
+			dlm_wait_for_recovery(dlm);
+			goto retry_lock;
+		}
+
+		if (status != DLM_NORMAL) {
+			lock->lksb->flags &= ~DLM_LKSB_GET_LVB;
+			if (status != DLM_NOTQUEUED)
+				dlm_error(status);
+			goto error;
+		}
+	}
+
+error:
+	if (status != DLM_NORMAL) {
+		if (lock && !convert)
+			dlm_lock_put(lock);
+		// this is kind of unnecessary
+		lksb->status = status;
+	}
+
+	/* put lockres ref from the convert path
+	 * or from dlm_get_lock_resource */
+	if (res)
+		dlm_lockres_put(res);
+
+	return status;
+}
+EXPORT_SYMBOL_GPL(dlmlock);
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
new file mode 100644
index 0000000..27e984f
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -0,0 +1,2664 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmmod.c
+ *
+ * standalone DLM module
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include <linux/random.h>
+#include <linux/blkdev.h>
+#include <linux/socket.h>
+#include <linux/inet.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+
+
+#include "cluster/heartbeat.h"
+#include "cluster/nodemanager.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+#include "dlmcommon.h"
+#include "dlmdebug.h"
+#include "dlmdomain.h"
+
+#define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_MASTER)
+#include "cluster/masklog.h"
+
+enum dlm_mle_type {
+	DLM_MLE_BLOCK,
+	DLM_MLE_MASTER,
+	DLM_MLE_MIGRATION
+};
+
+struct dlm_lock_name
+{
+	u8 len;
+	u8 name[DLM_LOCKID_NAME_MAX];
+};
+
+struct dlm_master_list_entry
+{
+	struct list_head list;
+	struct list_head hb_events;
+	struct dlm_ctxt *dlm;
+	spinlock_t spinlock;
+	wait_queue_head_t wq;
+	atomic_t woken;
+	struct kref mle_refs;
+	unsigned long maybe_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	unsigned long vote_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	unsigned long response_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	unsigned long node_map[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	u8 master;
+	u8 new_master;
+	enum dlm_mle_type type;
+	struct o2hb_callback_func mle_hb_up;
+	struct o2hb_callback_func mle_hb_down;
+	union {
+		struct dlm_lock_resource *res;
+		struct dlm_lock_name name;
+	} u;
+};
+
+static void dlm_mle_node_down(struct dlm_ctxt *dlm,
+			      struct dlm_master_list_entry *mle,
+			      struct o2nm_node *node,
+			      int idx);
+static void dlm_mle_node_up(struct dlm_ctxt *dlm,
+			    struct dlm_master_list_entry *mle,
+			    struct o2nm_node *node,
+			    int idx);
+
+static void dlm_assert_master_worker(struct dlm_work_item *item, void *data);
+static int dlm_do_assert_master(struct dlm_ctxt *dlm, const char *lockname,
+				unsigned int namelen, void *nodemap,
+				u32 flags);
+
+static inline int dlm_mle_equal(struct dlm_ctxt *dlm,
+				struct dlm_master_list_entry *mle,
+				const char *name,
+				unsigned int namelen)
+{
+	struct dlm_lock_resource *res;
+
+	if (dlm != mle->dlm)
+		return 0;
+
+	if (mle->type == DLM_MLE_BLOCK ||
+	    mle->type == DLM_MLE_MIGRATION) {
+		if (namelen != mle->u.name.len ||
+    	    	    memcmp(name, mle->u.name.name, namelen)!=0)
+			return 0;
+	} else {
+		res = mle->u.res;
+		if (namelen != res->lockname.len ||
+		    memcmp(res->lockname.name, name, namelen) != 0)
+			return 0;
+	}
+	return 1;
+}
+
+#if 0
+/* Code here is included but defined out as it aids debugging */
+
+void dlm_print_one_mle(struct dlm_master_list_entry *mle)
+{
+	int i = 0, refs;
+	char *type;
+	char attached;
+	u8 master;
+	unsigned int namelen;
+	const char *name;
+	struct kref *k;
+
+	k = &mle->mle_refs;
+	if (mle->type == DLM_MLE_BLOCK)
+		type = "BLK";
+	else if (mle->type == DLM_MLE_MASTER)
+		type = "MAS";
+	else
+		type = "MIG";
+	refs = atomic_read(&k->refcount);
+	master = mle->master;
+	attached = (list_empty(&mle->hb_events) ? 'N' : 'Y');
+
+	if (mle->type != DLM_MLE_MASTER) {
+		namelen = mle->u.name.len;
+		name = mle->u.name.name;
+	} else {
+		namelen = mle->u.res->lockname.len;
+		name = mle->u.res->lockname.name;
+	}
+
+	mlog(ML_NOTICE, "  #%3d: %3s  %3d  %3u   %3u %c    (%d)%.*s\n",
+		  i, type, refs, master, mle->new_master, attached,
+		  namelen, namelen, name);
+}
+
+static void dlm_dump_mles(struct dlm_ctxt *dlm)
+{
+	struct dlm_master_list_entry *mle;
+	struct list_head *iter;
+	
+	mlog(ML_NOTICE, "dumping all mles for domain %s:\n", dlm->name);
+	mlog(ML_NOTICE, "  ####: type refs owner new events? lockname nodemap votemap respmap maybemap\n");
+	spin_lock(&dlm->master_lock);
+	list_for_each(iter, &dlm->master_list) {
+		mle = list_entry(iter, struct dlm_master_list_entry, list);
+		dlm_print_one_mle(mle);
+	}
+	spin_unlock(&dlm->master_lock);
+}
+
+int dlm_dump_all_mles(const char __user *data, unsigned int len)
+{
+	struct list_head *iter;
+	struct dlm_ctxt *dlm;
+
+	spin_lock(&dlm_domain_lock);
+	list_for_each(iter, &dlm_domains) {
+		dlm = list_entry (iter, struct dlm_ctxt, list);
+		mlog(ML_NOTICE, "found dlm: %p, name=%s\n", dlm, dlm->name);
+		dlm_dump_mles(dlm);
+	}
+	spin_unlock(&dlm_domain_lock);
+	return len;
+}
+EXPORT_SYMBOL_GPL(dlm_dump_all_mles);
+
+#endif  /*  0  */
+
+
+static kmem_cache_t *dlm_mle_cache = NULL;
+
+
+static void dlm_mle_release(struct kref *kref);
+static void dlm_init_mle(struct dlm_master_list_entry *mle,
+			enum dlm_mle_type type,
+			struct dlm_ctxt *dlm,
+			struct dlm_lock_resource *res,
+			const char *name,
+			unsigned int namelen);
+static void dlm_put_mle(struct dlm_master_list_entry *mle);
+static void __dlm_put_mle(struct dlm_master_list_entry *mle);
+static int dlm_find_mle(struct dlm_ctxt *dlm,
+			struct dlm_master_list_entry **mle,
+			char *name, unsigned int namelen);
+
+static int dlm_do_master_request(struct dlm_master_list_entry *mle, int to);
+
+
+static int dlm_wait_for_lock_mastery(struct dlm_ctxt *dlm,
+				     struct dlm_lock_resource *res,
+				     struct dlm_master_list_entry *mle,
+				     int *blocked);
+static int dlm_restart_lock_mastery(struct dlm_ctxt *dlm,
+				    struct dlm_lock_resource *res,
+				    struct dlm_master_list_entry *mle,
+				    int blocked);
+static int dlm_add_migration_mle(struct dlm_ctxt *dlm,
+				 struct dlm_lock_resource *res,
+				 struct dlm_master_list_entry *mle,
+				 struct dlm_master_list_entry **oldmle,
+				 const char *name, unsigned int namelen,
+				 u8 new_master, u8 master);
+
+static u8 dlm_pick_migration_target(struct dlm_ctxt *dlm,
+				    struct dlm_lock_resource *res);
+static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm,
+				      struct dlm_lock_resource *res);
+static int dlm_mark_lockres_migrating(struct dlm_ctxt *dlm,
+				       struct dlm_lock_resource *res,
+				       u8 target);
+
+
+int dlm_is_host_down(int errno)
+{
+	switch (errno) {
+		case -EBADF:
+		case -ECONNREFUSED:
+		case -ENOTCONN:
+		case -ECONNRESET:
+		case -EPIPE:
+		case -EHOSTDOWN:
+		case -EHOSTUNREACH:
+		case -ETIMEDOUT:
+		case -ECONNABORTED:
+		case -ENETDOWN:
+		case -ENETUNREACH:
+		case -ENETRESET:
+		case -ESHUTDOWN:
+		case -ENOPROTOOPT:
+		case -EINVAL:   /* if returned from our tcp code,
+				   this means there is no socket */
+			return 1;
+	}
+	return 0;
+}
+
+
+/*
+ * MASTER LIST FUNCTIONS
+ */
+
+
+/*
+ * regarding master list entries and heartbeat callbacks:
+ *
+ * in order to avoid sleeping and allocation that occurs in
+ * heartbeat, master list entries are simply attached to the
+ * dlm's established heartbeat callbacks.  the mle is attached
+ * when it is created, and since the dlm->spinlock is held at
+ * that time, any heartbeat event will be properly discovered
+ * by the mle.  the mle needs to be detached from the
+ * dlm->mle_hb_events list as soon as heartbeat events are no
+ * longer useful to the mle, and before the mle is freed.
+ *
+ * as a general rule, heartbeat events are no longer needed by
+ * the mle once an "answer" regarding the lock master has been
+ * received.
+ */
+static inline void __dlm_mle_attach_hb_events(struct dlm_ctxt *dlm,
+					      struct dlm_master_list_entry *mle)
+{
+	assert_spin_locked(&dlm->spinlock);
+
+	list_add_tail(&mle->hb_events, &dlm->mle_hb_events);
+}
+
+
+static inline void __dlm_mle_detach_hb_events(struct dlm_ctxt *dlm,
+					      struct dlm_master_list_entry *mle)
+{
+	if (!list_empty(&mle->hb_events))
+		list_del_init(&mle->hb_events);
+}
+
+
+static inline void dlm_mle_detach_hb_events(struct dlm_ctxt *dlm,
+					    struct dlm_master_list_entry *mle)
+{
+	spin_lock(&dlm->spinlock);
+	__dlm_mle_detach_hb_events(dlm, mle);
+	spin_unlock(&dlm->spinlock);
+}
+
+/* remove from list and free */
+static void __dlm_put_mle(struct dlm_master_list_entry *mle)
+{
+	struct dlm_ctxt *dlm;
+	dlm = mle->dlm;
+
+	assert_spin_locked(&dlm->spinlock);
+	assert_spin_locked(&dlm->master_lock);
+	BUG_ON(!atomic_read(&mle->mle_refs.refcount));
+
+	kref_put(&mle->mle_refs, dlm_mle_release);
+}
+
+
+/* must not have any spinlocks coming in */
+static void dlm_put_mle(struct dlm_master_list_entry *mle)
+{
+	struct dlm_ctxt *dlm;
+	dlm = mle->dlm;
+
+	spin_lock(&dlm->spinlock);
+	spin_lock(&dlm->master_lock);
+	__dlm_put_mle(mle);
+	spin_unlock(&dlm->master_lock);
+	spin_unlock(&dlm->spinlock);
+}
+
+static inline void dlm_get_mle(struct dlm_master_list_entry *mle)
+{
+	kref_get(&mle->mle_refs);
+}
+
+static void dlm_init_mle(struct dlm_master_list_entry *mle,
+			enum dlm_mle_type type,
+			struct dlm_ctxt *dlm,
+			struct dlm_lock_resource *res,
+			const char *name,
+			unsigned int namelen)
+{
+	assert_spin_locked(&dlm->spinlock);
+
+	mle->dlm = dlm;
+	mle->type = type;
+	INIT_LIST_HEAD(&mle->list);
+	INIT_LIST_HEAD(&mle->hb_events);
+	memset(mle->maybe_map, 0, sizeof(mle->maybe_map));
+	spin_lock_init(&mle->spinlock);
+	init_waitqueue_head(&mle->wq);
+	atomic_set(&mle->woken, 0);
+	kref_init(&mle->mle_refs);
+	memset(mle->response_map, 0, sizeof(mle->response_map));
+	mle->master = O2NM_MAX_NODES;
+	mle->new_master = O2NM_MAX_NODES;
+
+	if (mle->type == DLM_MLE_MASTER) {
+		BUG_ON(!res);
+		mle->u.res = res;
+	} else if (mle->type == DLM_MLE_BLOCK) {
+		BUG_ON(!name);
+		memcpy(mle->u.name.name, name, namelen);
+		mle->u.name.len = namelen;
+	} else /* DLM_MLE_MIGRATION */ {
+		BUG_ON(!name);
+		memcpy(mle->u.name.name, name, namelen);
+		mle->u.name.len = namelen;
+	}
+
+	/* copy off the node_map and register hb callbacks on our copy */
+	memcpy(mle->node_map, dlm->domain_map, sizeof(mle->node_map));
+	memcpy(mle->vote_map, dlm->domain_map, sizeof(mle->vote_map));
+	clear_bit(dlm->node_num, mle->vote_map);
+	clear_bit(dlm->node_num, mle->node_map);
+
+	/* attach the mle to the domain node up/down events */
+	__dlm_mle_attach_hb_events(dlm, mle);
+}
+
+
+/* returns 1 if found, 0 if not */
+static int dlm_find_mle(struct dlm_ctxt *dlm,
+			struct dlm_master_list_entry **mle,
+			char *name, unsigned int namelen)
+{
+	struct dlm_master_list_entry *tmpmle;
+	struct list_head *iter;
+
+	assert_spin_locked(&dlm->master_lock);
+
+	list_for_each(iter, &dlm->master_list) {
+		tmpmle = list_entry(iter, struct dlm_master_list_entry, list);
+		if (!dlm_mle_equal(dlm, tmpmle, name, namelen))
+			continue;
+		dlm_get_mle(tmpmle);
+		*mle = tmpmle;
+		return 1;
+	}
+	return 0;
+}
+
+void dlm_hb_event_notify_attached(struct dlm_ctxt *dlm, int idx, int node_up)
+{
+	struct dlm_master_list_entry *mle;
+	struct list_head *iter;
+
+	assert_spin_locked(&dlm->spinlock);
+	
+	list_for_each(iter, &dlm->mle_hb_events) {
+		mle = list_entry(iter, struct dlm_master_list_entry, 
+				 hb_events);
+		if (node_up)
+			dlm_mle_node_up(dlm, mle, NULL, idx);
+		else
+			dlm_mle_node_down(dlm, mle, NULL, idx);
+	}
+}
+
+static void dlm_mle_node_down(struct dlm_ctxt *dlm,
+			      struct dlm_master_list_entry *mle,
+			      struct o2nm_node *node, int idx)
+{
+	spin_lock(&mle->spinlock);
+
+	if (!test_bit(idx, mle->node_map))
+		mlog(0, "node %u already removed from nodemap!\n", idx);
+	else
+		clear_bit(idx, mle->node_map);
+
+	spin_unlock(&mle->spinlock);
+}
+
+static void dlm_mle_node_up(struct dlm_ctxt *dlm,
+			    struct dlm_master_list_entry *mle,
+			    struct o2nm_node *node, int idx)
+{
+	spin_lock(&mle->spinlock);
+
+	if (test_bit(idx, mle->node_map))
+		mlog(0, "node %u already in node map!\n", idx);
+	else
+		set_bit(idx, mle->node_map);
+
+	spin_unlock(&mle->spinlock);
+}
+
+
+int dlm_init_mle_cache(void)
+{
+	dlm_mle_cache = kmem_cache_create("dlm_mle_cache",
+					  sizeof(struct dlm_master_list_entry),
+					  0, SLAB_HWCACHE_ALIGN,
+					  NULL, NULL);
+	if (dlm_mle_cache == NULL)
+		return -ENOMEM;
+	return 0;
+}
+
+void dlm_destroy_mle_cache(void)
+{
+	if (dlm_mle_cache)
+		kmem_cache_destroy(dlm_mle_cache);
+}
+
+static void dlm_mle_release(struct kref *kref)
+{
+	struct dlm_master_list_entry *mle;
+	struct dlm_ctxt *dlm;
+
+	mlog_entry_void();
+
+	mle = container_of(kref, struct dlm_master_list_entry, mle_refs);
+	dlm = mle->dlm;
+
+	if (mle->type != DLM_MLE_MASTER) {
+		mlog(0, "calling mle_release for %.*s, type %d\n",
+		     mle->u.name.len, mle->u.name.name, mle->type);
+	} else {
+		mlog(0, "calling mle_release for %.*s, type %d\n",
+		     mle->u.res->lockname.len,
+		     mle->u.res->lockname.name, mle->type);
+	}
+	assert_spin_locked(&dlm->spinlock);
+	assert_spin_locked(&dlm->master_lock);
+
+	/* remove from list if not already */
+	if (!list_empty(&mle->list))
+		list_del_init(&mle->list);
+
+	/* detach the mle from the domain node up/down events */
+	__dlm_mle_detach_hb_events(dlm, mle);
+
+	/* NOTE: kfree under spinlock here.
+	 * if this is bad, we can move this to a freelist. */
+	kmem_cache_free(dlm_mle_cache, mle);
+}
+
+
+/*
+ * LOCK RESOURCE FUNCTIONS
+ */
+
+static void dlm_set_lockres_owner(struct dlm_ctxt *dlm,
+				  struct dlm_lock_resource *res,
+				  u8 owner)
+{
+	assert_spin_locked(&res->spinlock);
+
+	mlog_entry("%.*s, %u\n", res->lockname.len, res->lockname.name, owner);
+
+	if (owner == dlm->node_num)
+		atomic_inc(&dlm->local_resources);
+	else if (owner == DLM_LOCK_RES_OWNER_UNKNOWN)
+		atomic_inc(&dlm->unknown_resources);
+	else
+		atomic_inc(&dlm->remote_resources);
+
+	res->owner = owner;
+}
+
+void dlm_change_lockres_owner(struct dlm_ctxt *dlm,
+			      struct dlm_lock_resource *res, u8 owner)
+{
+	assert_spin_locked(&res->spinlock);
+
+	if (owner == res->owner)
+		return;
+
+	if (res->owner == dlm->node_num)
+		atomic_dec(&dlm->local_resources);
+	else if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN)
+		atomic_dec(&dlm->unknown_resources);
+	else
+		atomic_dec(&dlm->remote_resources);
+
+	dlm_set_lockres_owner(dlm, res, owner);
+}
+
+
+static void dlm_lockres_release(struct kref *kref)
+{
+	struct dlm_lock_resource *res;
+
+	res = container_of(kref, struct dlm_lock_resource, refs);
+
+	/* This should not happen -- all lockres' have a name
+	 * associated with them at init time. */
+	BUG_ON(!res->lockname.name);
+
+	mlog(0, "destroying lockres %.*s\n", res->lockname.len,
+	     res->lockname.name);
+
+	/* By the time we're ready to blow this guy away, we shouldn't
+	 * be on any lists. */
+	BUG_ON(!list_empty(&res->list));
+	BUG_ON(!list_empty(&res->granted));
+	BUG_ON(!list_empty(&res->converting));
+	BUG_ON(!list_empty(&res->blocked));
+	BUG_ON(!list_empty(&res->dirty));
+	BUG_ON(!list_empty(&res->recovering));
+	BUG_ON(!list_empty(&res->purge));
+
+	kfree(res->lockname.name);
+
+	kfree(res);
+}
+
+void dlm_lockres_get(struct dlm_lock_resource *res)
+{
+	kref_get(&res->refs);
+}
+
+void dlm_lockres_put(struct dlm_lock_resource *res)
+{
+	kref_put(&res->refs, dlm_lockres_release);
+}
+
+static void dlm_init_lockres(struct dlm_ctxt *dlm,
+			     struct dlm_lock_resource *res,
+			     const char *name, unsigned int namelen)
+{
+	char *qname;
+
+	/* If we memset here, we lose our reference to the kmalloc'd
+	 * res->lockname.name, so be sure to init every field
+	 * correctly! */
+
+	qname = (char *) res->lockname.name;
+	memcpy(qname, name, namelen);
+
+	res->lockname.len = namelen;
+	res->lockname.hash = full_name_hash(name, namelen);
+
+	init_waitqueue_head(&res->wq);
+	spin_lock_init(&res->spinlock);
+	INIT_LIST_HEAD(&res->list);
+	INIT_LIST_HEAD(&res->granted);
+	INIT_LIST_HEAD(&res->converting);
+	INIT_LIST_HEAD(&res->blocked);
+	INIT_LIST_HEAD(&res->dirty);
+	INIT_LIST_HEAD(&res->recovering);
+	INIT_LIST_HEAD(&res->purge);
+	atomic_set(&res->asts_reserved, 0);
+	res->migration_pending = 0;
+
+	kref_init(&res->refs);
+
+	/* just for consistency */
+	spin_lock(&res->spinlock);
+	dlm_set_lockres_owner(dlm, res, DLM_LOCK_RES_OWNER_UNKNOWN);
+	spin_unlock(&res->spinlock);
+
+	res->state = DLM_LOCK_RES_IN_PROGRESS;
+
+	res->last_used = 0;
+
+	memset(res->lvb, 0, DLM_LVB_LEN);
+}
+
+struct dlm_lock_resource *dlm_new_lockres(struct dlm_ctxt *dlm,
+				   const char *name,
+				   unsigned int namelen)
+{
+	struct dlm_lock_resource *res;
+
+	res = kmalloc(sizeof(struct dlm_lock_resource), GFP_KERNEL);
+	if (!res)
+		return NULL;
+
+	res->lockname.name = kmalloc(namelen, GFP_KERNEL);
+	if (!res->lockname.name) {
+		kfree(res);
+		return NULL;
+	}
+
+	dlm_init_lockres(dlm, res, name, namelen);
+	return res;
+}
+
+/*
+ * lookup a lock resource by name.
+ * may already exist in the hashtable.
+ * lockid is null terminated
+ *
+ * if not, allocate enough for the lockres and for
+ * the temporary structure used in doing the mastering.
+ *
+ * also, do a lookup in the dlm->master_list to see
+ * if another node has begun mastering the same lock.
+ * if so, there should be a block entry in there
+ * for this name, and we should *not* attempt to master
+ * the lock here.   need to wait around for that node
+ * to assert_master (or die).
+ *
+ */
+struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
+					  const char *lockid,
+					  int flags)
+{
+	struct dlm_lock_resource *tmpres=NULL, *res=NULL;
+	struct dlm_master_list_entry *mle = NULL;
+	struct dlm_master_list_entry *alloc_mle = NULL;
+	int blocked = 0;
+	int ret, nodenum;
+	struct dlm_node_iter iter;
+	unsigned int namelen;
+	int tries = 0;
+
+	BUG_ON(!lockid);
+
+	namelen = strlen(lockid);
+
+	mlog(0, "get lockres %s (len %d)\n", lockid, namelen);
+
+lookup:
+	spin_lock(&dlm->spinlock);
+	tmpres = __dlm_lookup_lockres(dlm, lockid, namelen);
+	if (tmpres) {
+		spin_unlock(&dlm->spinlock);
+		mlog(0, "found in hash!\n");
+		if (res)
+			dlm_lockres_put(res);
+		res = tmpres;
+		goto leave;
+	}
+
+	if (!res) {
+		spin_unlock(&dlm->spinlock);
+		mlog(0, "allocating a new resource\n");
+		/* nothing found and we need to allocate one. */
+		alloc_mle = (struct dlm_master_list_entry *)
+			kmem_cache_alloc(dlm_mle_cache, GFP_KERNEL);
+		if (!alloc_mle)
+			goto leave;
+		res = dlm_new_lockres(dlm, lockid, namelen);
+		if (!res)
+			goto leave;
+		goto lookup;
+	}
+
+	mlog(0, "no lockres found, allocated our own: %p\n", res);
+
+	if (flags & LKM_LOCAL) {
+		/* caller knows it's safe to assume it's not mastered elsewhere
+		 * DONE!  return right away */
+		spin_lock(&res->spinlock);
+		dlm_change_lockres_owner(dlm, res, dlm->node_num);
+		__dlm_insert_lockres(dlm, res);
+		spin_unlock(&res->spinlock);
+		spin_unlock(&dlm->spinlock);
+		/* lockres still marked IN_PROGRESS */
+		goto wake_waiters;
+	}
+
+	/* check master list to see if another node has started mastering it */
+	spin_lock(&dlm->master_lock);
+
+	/* if we found a block, wait for lock to be mastered by another node */
+	blocked = dlm_find_mle(dlm, &mle, (char *)lockid, namelen);
+	if (blocked) {
+		if (mle->type == DLM_MLE_MASTER) {
+			mlog(ML_ERROR, "master entry for nonexistent lock!\n");
+			BUG();
+		} else if (mle->type == DLM_MLE_MIGRATION) {
+			/* migration is in progress! */
+			/* the good news is that we now know the
+			 * "current" master (mle->master). */
+
+			spin_unlock(&dlm->master_lock);
+			assert_spin_locked(&dlm->spinlock);
+
+			/* set the lockres owner and hash it */
+			spin_lock(&res->spinlock);
+			dlm_set_lockres_owner(dlm, res, mle->master);
+			__dlm_insert_lockres(dlm, res);
+			spin_unlock(&res->spinlock);
+			spin_unlock(&dlm->spinlock);
+
+			/* master is known, detach */
+			dlm_mle_detach_hb_events(dlm, mle);
+			dlm_put_mle(mle);
+			mle = NULL;
+			goto wake_waiters;
+		}
+	} else {
+		/* go ahead and try to master lock on this node */
+		mle = alloc_mle;
+		/* make sure this does not get freed below */
+		alloc_mle = NULL;
+		dlm_init_mle(mle, DLM_MLE_MASTER, dlm, res, NULL, 0);
+		set_bit(dlm->node_num, mle->maybe_map);
+		list_add(&mle->list, &dlm->master_list);
+	}
+
+	/* at this point there is either a DLM_MLE_BLOCK or a
+	 * DLM_MLE_MASTER on the master list, so it's safe to add the
+	 * lockres to the hashtable.  anyone who finds the lock will
+	 * still have to wait on the IN_PROGRESS. */
+
+	/* finally add the lockres to its hash bucket */
+	__dlm_insert_lockres(dlm, res);
+	/* get an extra ref on the mle in case this is a BLOCK
+	 * if so, the creator of the BLOCK may try to put the last
+	 * ref at this time in the assert master handler, so we
+	 * need an extra one to keep from a bad ptr deref. */
+	dlm_get_mle(mle);
+	spin_unlock(&dlm->master_lock);
+	spin_unlock(&dlm->spinlock);
+
+	/* must wait for lock to be mastered elsewhere */
+	if (blocked)
+		goto wait;
+
+redo_request:
+	ret = -EINVAL;
+	dlm_node_iter_init(mle->vote_map, &iter);
+	while ((nodenum = dlm_node_iter_next(&iter)) >= 0) {
+		ret = dlm_do_master_request(mle, nodenum);
+		if (ret < 0)
+			mlog_errno(ret);
+		if (mle->master != O2NM_MAX_NODES) {
+			/* found a master ! */
+			break;
+		}
+	}
+
+wait:
+	/* keep going until the response map includes all nodes */
+	ret = dlm_wait_for_lock_mastery(dlm, res, mle, &blocked);
+	if (ret < 0) {
+		mlog(0, "%s:%.*s: node map changed, redo the "
+		     "master request now, blocked=%d\n",
+		     dlm->name, res->lockname.len,
+		     res->lockname.name, blocked);
+		if (++tries > 20) {
+			mlog(ML_ERROR, "%s:%.*s: spinning on "
+			     "dlm_wait_for_lock_mastery, blocked=%d\n", 
+			     dlm->name, res->lockname.len, 
+			     res->lockname.name, blocked);
+			dlm_print_one_lock_resource(res);
+			/* dlm_print_one_mle(mle); */
+			tries = 0;
+		}
+		goto redo_request;
+	}
+
+	mlog(0, "lockres mastered by %u\n", res->owner);
+	/* make sure we never continue without this */
+	BUG_ON(res->owner == O2NM_MAX_NODES);
+
+	/* master is known, detach if not already detached */
+	dlm_mle_detach_hb_events(dlm, mle);
+	dlm_put_mle(mle);
+	/* put the extra ref */
+	dlm_put_mle(mle);
+
+wake_waiters:
+	spin_lock(&res->spinlock);
+	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
+	spin_unlock(&res->spinlock);
+	wake_up(&res->wq);
+
+leave:
+	/* need to free the unused mle */
+	if (alloc_mle)
+		kmem_cache_free(dlm_mle_cache, alloc_mle);
+
+	return res;
+}
+
+
+#define DLM_MASTERY_TIMEOUT_MS   5000
+
+static int dlm_wait_for_lock_mastery(struct dlm_ctxt *dlm,
+				     struct dlm_lock_resource *res,
+				     struct dlm_master_list_entry *mle,
+				     int *blocked)
+{
+	u8 m;
+	int ret, bit;
+	int map_changed, voting_done;
+	int assert, sleep;
+
+recheck:
+	ret = 0;
+	assert = 0;
+
+	/* check if another node has already become the owner */
+	spin_lock(&res->spinlock);
+	if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) {
+		spin_unlock(&res->spinlock);
+		goto leave;
+	}
+	spin_unlock(&res->spinlock);
+
+	spin_lock(&mle->spinlock);
+	m = mle->master;
+	map_changed = (memcmp(mle->vote_map, mle->node_map,
+			      sizeof(mle->vote_map)) != 0);
+	voting_done = (memcmp(mle->vote_map, mle->response_map,
+			     sizeof(mle->vote_map)) == 0);
+
+	/* restart if we hit any errors */
+	if (map_changed) {
+		int b;
+		mlog(0, "%s: %.*s: node map changed, restarting\n",
+		     dlm->name, res->lockname.len, res->lockname.name);
+		ret = dlm_restart_lock_mastery(dlm, res, mle, *blocked);
+		b = (mle->type == DLM_MLE_BLOCK);
+		if ((*blocked && !b) || (!*blocked && b)) {
+			mlog(0, "%s:%.*s: status change: old=%d new=%d\n", 
+			     dlm->name, res->lockname.len, res->lockname.name,
+			     *blocked, b);
+			*blocked = b;
+		}
+		spin_unlock(&mle->spinlock);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto leave;
+		}
+		mlog(0, "%s:%.*s: restart lock mastery succeeded, "
+		     "rechecking now\n", dlm->name, res->lockname.len,
+		     res->lockname.name);
+		goto recheck;
+	}
+
+	if (m != O2NM_MAX_NODES) {
+		/* another node has done an assert!
+		 * all done! */
+		sleep = 0;
+	} else {
+		sleep = 1;
+		/* have all nodes responded? */
+		if (voting_done && !*blocked) {
+			bit = find_next_bit(mle->maybe_map, O2NM_MAX_NODES, 0);
+			if (dlm->node_num <= bit) {
+				/* my node number is lowest.
+			 	 * now tell other nodes that I am
+				 * mastering this. */
+				mle->master = dlm->node_num;
+				assert = 1;
+				sleep = 0;
+			}
+			/* if voting is done, but we have not received
+			 * an assert master yet, we must sleep */
+		}
+	}
+
+	spin_unlock(&mle->spinlock);
+
+	/* sleep if we haven't finished voting yet */
+	if (sleep) {
+		unsigned long timeo = msecs_to_jiffies(DLM_MASTERY_TIMEOUT_MS);
+
+		/*
+		if (atomic_read(&mle->mle_refs.refcount) < 2)
+			mlog(ML_ERROR, "mle (%p) refs=%d, name=%.*s\n", mle,
+			atomic_read(&mle->mle_refs.refcount),
+			res->lockname.len, res->lockname.name);
+		*/
+		atomic_set(&mle->woken, 0);
+		(void)wait_event_timeout(mle->wq,
+					 (atomic_read(&mle->woken) == 1),
+					 timeo);
+		if (res->owner == O2NM_MAX_NODES) {
+			mlog(0, "waiting again\n");
+			goto recheck;
+		}
+		mlog(0, "done waiting, master is %u\n", res->owner);
+		ret = 0;
+		goto leave;
+	}
+
+	ret = 0;   /* done */
+	if (assert) {
+		m = dlm->node_num;
+		mlog(0, "about to master %.*s here, this=%u\n",
+		     res->lockname.len, res->lockname.name, m);
+		ret = dlm_do_assert_master(dlm, res->lockname.name,
+					   res->lockname.len, mle->vote_map, 0);
+		if (ret) {
+			/* This is a failure in the network path,
+			 * not in the response to the assert_master
+			 * (any nonzero response is a BUG on this node).
+			 * Most likely a socket just got disconnected
+			 * due to node death. */
+			mlog_errno(ret);
+		}
+		/* no longer need to restart lock mastery.
+		 * all living nodes have been contacted. */
+		ret = 0;
+	}
+
+	/* set the lockres owner */
+	spin_lock(&res->spinlock);
+	dlm_change_lockres_owner(dlm, res, m);
+	spin_unlock(&res->spinlock);
+
+leave:
+	return ret;
+}
+
+struct dlm_bitmap_diff_iter
+{
+	int curnode;
+	unsigned long *orig_bm;
+	unsigned long *cur_bm;
+	unsigned long diff_bm[BITS_TO_LONGS(O2NM_MAX_NODES)];
+};
+
+enum dlm_node_state_change
+{
+	NODE_DOWN = -1,
+	NODE_NO_CHANGE = 0,
+	NODE_UP
+};
+
+static void dlm_bitmap_diff_iter_init(struct dlm_bitmap_diff_iter *iter,
+				      unsigned long *orig_bm,
+				      unsigned long *cur_bm)
+{
+	unsigned long p1, p2;
+	int i;
+
+	iter->curnode = -1;
+	iter->orig_bm = orig_bm;
+	iter->cur_bm = cur_bm;
+
+	for (i = 0; i < BITS_TO_LONGS(O2NM_MAX_NODES); i++) {
+       		p1 = *(iter->orig_bm + i);
+	       	p2 = *(iter->cur_bm + i);
+		iter->diff_bm[i] = (p1 & ~p2) | (p2 & ~p1);
+	}
+}
+
+static int dlm_bitmap_diff_iter_next(struct dlm_bitmap_diff_iter *iter,
+				     enum dlm_node_state_change *state)
+{
+	int bit;
+
+	if (iter->curnode >= O2NM_MAX_NODES)
+		return -ENOENT;
+
+	bit = find_next_bit(iter->diff_bm, O2NM_MAX_NODES,
+			    iter->curnode+1);
+	if (bit >= O2NM_MAX_NODES) {
+		iter->curnode = O2NM_MAX_NODES;
+		return -ENOENT;
+	}
+
+	/* if it was there in the original then this node died */
+	if (test_bit(bit, iter->orig_bm))
+		*state = NODE_DOWN;
+	else
+		*state = NODE_UP;
+
+	iter->curnode = bit;
+	return bit;
+}
+
+
+static int dlm_restart_lock_mastery(struct dlm_ctxt *dlm,
+				    struct dlm_lock_resource *res,
+				    struct dlm_master_list_entry *mle,
+				    int blocked)
+{
+	struct dlm_bitmap_diff_iter bdi;
+	enum dlm_node_state_change sc;
+	int node;
+	int ret = 0;
+
+	mlog(0, "something happened such that the "
+	     "master process may need to be restarted!\n");
+
+	assert_spin_locked(&mle->spinlock);
+
+	dlm_bitmap_diff_iter_init(&bdi, mle->vote_map, mle->node_map);
+	node = dlm_bitmap_diff_iter_next(&bdi, &sc);
+	while (node >= 0) {
+		if (sc == NODE_UP) {
+			/* a node came up.  easy.  might not even need
+			 * to talk to it if its node number is higher
+			 * or if we are already blocked. */
+			mlog(0, "node up! %d\n", node);
+			if (blocked)
+				goto next;
+
+			if (node > dlm->node_num) {
+				mlog(0, "node > this node. skipping.\n");
+				goto next;
+			}
+
+			/* redo the master request, but only for the new node */
+			mlog(0, "sending request to new node\n");
+			clear_bit(node, mle->response_map);
+			set_bit(node, mle->vote_map);
+		} else {
+			mlog(ML_ERROR, "node down! %d\n", node);
+
+			/* if the node wasn't involved in mastery skip it,
+			 * but clear it out from the maps so that it will
+			 * not affect mastery of this lockres */
+			clear_bit(node, mle->response_map);
+			clear_bit(node, mle->vote_map);
+			if (!test_bit(node, mle->maybe_map))
+				goto next;
+
+			/* if we're already blocked on lock mastery, and the
+			 * dead node wasn't the expected master, or there is
+			 * another node in the maybe_map, keep waiting */
+			if (blocked) {
+				int lowest = find_next_bit(mle->maybe_map,
+						       O2NM_MAX_NODES, 0);
+
+				/* act like it was never there */
+				clear_bit(node, mle->maybe_map);
+
+			       	if (node != lowest)
+					goto next;
+
+				mlog(ML_ERROR, "expected master %u died while "
+				     "this node was blocked waiting on it!\n",
+				     node);
+				lowest = find_next_bit(mle->maybe_map,
+						       O2NM_MAX_NODES,
+						       lowest+1);
+				if (lowest < O2NM_MAX_NODES) {
+					mlog(0, "still blocked. waiting "
+					     "on %u now\n", lowest);
+					goto next;
+				}
+
+				/* mle is an MLE_BLOCK, but there is now
+				 * nothing left to block on.  we need to return
+				 * all the way back out and try again with
+				 * an MLE_MASTER. dlm_do_local_recovery_cleanup
+				 * has already run, so the mle refcount is ok */
+				mlog(0, "no longer blocking. we can "
+				     "try to master this here\n");
+				mle->type = DLM_MLE_MASTER;
+				memset(mle->maybe_map, 0,
+				       sizeof(mle->maybe_map));
+				memset(mle->response_map, 0,
+				       sizeof(mle->maybe_map));
+				memcpy(mle->vote_map, mle->node_map,
+				       sizeof(mle->node_map));
+				mle->u.res = res;
+				set_bit(dlm->node_num, mle->maybe_map);
+
+				ret = -EAGAIN;
+				goto next;
+			}
+
+			clear_bit(node, mle->maybe_map);
+			if (node > dlm->node_num)
+				goto next;
+
+			mlog(0, "dead node in map!\n");
+			/* yuck. go back and re-contact all nodes
+			 * in the vote_map, removing this node. */
+			memset(mle->response_map, 0,
+			       sizeof(mle->response_map));
+		}
+		ret = -EAGAIN;
+next:
+		node = dlm_bitmap_diff_iter_next(&bdi, &sc);
+	}
+	return ret;
+}
+
+
+/*
+ * DLM_MASTER_REQUEST_MSG
+ *
+ * returns: 0 on success,
+ *          -errno on a network error
+ *
+ * on error, the caller should assume the target node is "dead"
+ *
+ */
+
+static int dlm_do_master_request(struct dlm_master_list_entry *mle, int to)
+{
+	struct dlm_ctxt *dlm = mle->dlm;
+	struct dlm_master_request request;
+	int ret, response=0, resend;
+
+	memset(&request, 0, sizeof(request));
+	request.node_idx = dlm->node_num;
+
+	BUG_ON(mle->type == DLM_MLE_MIGRATION);
+
+	if (mle->type != DLM_MLE_MASTER) {
+		request.namelen = mle->u.name.len;
+		memcpy(request.name, mle->u.name.name, request.namelen);
+	} else {
+		request.namelen = mle->u.res->lockname.len;
+		memcpy(request.name, mle->u.res->lockname.name,
+			request.namelen);
+	}
+
+again:
+	ret = o2net_send_message(DLM_MASTER_REQUEST_MSG, dlm->key, &request,
+				 sizeof(request), to, &response);
+	if (ret < 0)  {
+		if (ret == -ESRCH) {
+			/* should never happen */
+			mlog(ML_ERROR, "TCP stack not ready!\n");
+			BUG();
+		} else if (ret == -EINVAL) {
+			mlog(ML_ERROR, "bad args passed to o2net!\n");
+			BUG();
+		} else if (ret == -ENOMEM) {
+			mlog(ML_ERROR, "out of memory while trying to send "
+			     "network message!  retrying\n");
+			/* this is totally crude */
+			msleep(50);
+			goto again;
+		} else if (!dlm_is_host_down(ret)) {
+			/* not a network error. bad. */
+			mlog_errno(ret);
+			mlog(ML_ERROR, "unhandled error!");
+			BUG();
+		}
+		/* all other errors should be network errors,
+		 * and likely indicate node death */
+		mlog(ML_ERROR, "link to %d went down!\n", to);
+		goto out;
+	}
+
+	ret = 0;
+	resend = 0;
+	spin_lock(&mle->spinlock);
+	switch (response) {
+		case DLM_MASTER_RESP_YES:
+			set_bit(to, mle->response_map);
+			mlog(0, "node %u is the master, response=YES\n", to);
+			mle->master = to;
+			break;
+		case DLM_MASTER_RESP_NO:
+			mlog(0, "node %u not master, response=NO\n", to);
+			set_bit(to, mle->response_map);
+			break;
+		case DLM_MASTER_RESP_MAYBE:
+			mlog(0, "node %u not master, response=MAYBE\n", to);
+			set_bit(to, mle->response_map);
+			set_bit(to, mle->maybe_map);
+			break;
+		case DLM_MASTER_RESP_ERROR:
+			mlog(0, "node %u hit an error, resending\n", to);
+			resend = 1;
+			response = 0;
+			break;
+		default:
+			mlog(ML_ERROR, "bad response! %u\n", response);
+			BUG();
+	}
+	spin_unlock(&mle->spinlock);
+	if (resend) {
+		/* this is also totally crude */
+		msleep(50);
+		goto again;
+	}
+
+out:
+	return ret;
+}
+
+/*
+ * locks that can be taken here:
+ * dlm->spinlock
+ * res->spinlock
+ * mle->spinlock
+ * dlm->master_list
+ *
+ * if possible, TRIM THIS DOWN!!!
+ */
+int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	u8 response = DLM_MASTER_RESP_MAYBE;
+	struct dlm_ctxt *dlm = data;
+	struct dlm_lock_resource *res;
+	struct dlm_master_request *request = (struct dlm_master_request *) msg->buf;
+	struct dlm_master_list_entry *mle = NULL, *tmpmle = NULL;
+	char *name;
+	unsigned int namelen;
+	int found, ret;
+	int set_maybe;
+
+	if (!dlm_grab(dlm))
+		return DLM_MASTER_RESP_NO;
+
+	if (!dlm_domain_fully_joined(dlm)) {
+		response = DLM_MASTER_RESP_NO;
+		goto send_response;
+	}
+
+	name = request->name;
+	namelen = request->namelen;
+
+	if (namelen > DLM_LOCKID_NAME_MAX) {
+		response = DLM_IVBUFLEN;
+		goto send_response;
+	}
+
+way_up_top:
+	spin_lock(&dlm->spinlock);
+	res = __dlm_lookup_lockres(dlm, name, namelen);
+	if (res) {
+		spin_unlock(&dlm->spinlock);
+
+		/* take care of the easy cases up front */
+		spin_lock(&res->spinlock);
+		if (res->state & DLM_LOCK_RES_RECOVERING) {
+			spin_unlock(&res->spinlock);
+			mlog(0, "returning DLM_MASTER_RESP_ERROR since res is "
+			     "being recovered\n");
+			response = DLM_MASTER_RESP_ERROR;
+			if (mle)
+				kmem_cache_free(dlm_mle_cache, mle);
+			goto send_response;
+		}
+
+		if (res->owner == dlm->node_num) {
+			u32 flags = DLM_ASSERT_MASTER_MLE_CLEANUP;
+			spin_unlock(&res->spinlock);
+			// mlog(0, "this node is the master\n");
+			response = DLM_MASTER_RESP_YES;
+			if (mle)
+				kmem_cache_free(dlm_mle_cache, mle);
+
+			/* this node is the owner.
+			 * there is some extra work that needs to
+			 * happen now.  the requesting node has
+			 * caused all nodes up to this one to
+			 * create mles.  this node now needs to
+			 * go back and clean those up. */
+			mlog(0, "%u is the owner of %.*s, cleaning everyone else\n",
+			     dlm->node_num, res->lockname.len, res->lockname.name);
+			ret = dlm_dispatch_assert_master(dlm, res, 1,
+							 request->node_idx,
+							 flags);
+			if (ret < 0) {
+				mlog(ML_ERROR, "failed to dispatch assert "
+				     "master work\n");
+				response = DLM_MASTER_RESP_ERROR;
+			}
+			goto send_response;
+		} else if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) {
+			spin_unlock(&res->spinlock);
+			// mlog(0, "node %u is the master\n", res->owner);
+			response = DLM_MASTER_RESP_NO;
+			if (mle)
+				kmem_cache_free(dlm_mle_cache, mle);
+			goto send_response;
+		}
+
+		/* ok, there is no owner.  either this node is
+		 * being blocked, or it is actively trying to
+		 * master this lock. */
+		if (!(res->state & DLM_LOCK_RES_IN_PROGRESS)) {
+			mlog(ML_ERROR, "lock with no owner should be "
+			     "in-progress!\n");
+			BUG();
+		}
+
+		// mlog(0, "lockres is in progress...\n");
+		spin_lock(&dlm->master_lock);
+		found = dlm_find_mle(dlm, &tmpmle, name, namelen);
+		if (!found) {
+			mlog(ML_ERROR, "no mle found for this lock!\n");
+			BUG();
+		}
+		set_maybe = 1;
+		spin_lock(&tmpmle->spinlock);
+		if (tmpmle->type == DLM_MLE_BLOCK) {
+			// mlog(0, "this node is waiting for "
+			// "lockres to be mastered\n");
+			response = DLM_MASTER_RESP_NO;
+		} else if (tmpmle->type == DLM_MLE_MIGRATION) {
+			mlog(0, "node %u is master, but trying to migrate to "
+			     "node %u.\n", tmpmle->master, tmpmle->new_master);
+			if (tmpmle->master == dlm->node_num) {
+				response = DLM_MASTER_RESP_YES;
+				mlog(ML_ERROR, "no owner on lockres, but this "
+				     "node is trying to migrate it to %u?!\n",
+				     tmpmle->new_master);
+				BUG();
+			} else {
+				/* the real master can respond on its own */
+				response = DLM_MASTER_RESP_NO;
+			}
+		} else if (tmpmle->master != DLM_LOCK_RES_OWNER_UNKNOWN) {
+			set_maybe = 0;
+			if (tmpmle->master == dlm->node_num)
+				response = DLM_MASTER_RESP_YES;
+			else
+				response = DLM_MASTER_RESP_NO;
+		} else {
+			// mlog(0, "this node is attempting to "
+			// "master lockres\n");
+			response = DLM_MASTER_RESP_MAYBE;
+		}
+		if (set_maybe)
+			set_bit(request->node_idx, tmpmle->maybe_map);
+		spin_unlock(&tmpmle->spinlock);
+
+		spin_unlock(&dlm->master_lock);
+		spin_unlock(&res->spinlock);
+
+		/* keep the mle attached to heartbeat events */
+		dlm_put_mle(tmpmle);
+		if (mle)
+			kmem_cache_free(dlm_mle_cache, mle);
+		goto send_response;
+	}
+
+	/*
+	 * lockres doesn't exist on this node
+	 * if there is an MLE_BLOCK, return NO
+	 * if there is an MLE_MASTER, return MAYBE
+	 * otherwise, add an MLE_BLOCK, return NO
+	 */
+	spin_lock(&dlm->master_lock);
+	found = dlm_find_mle(dlm, &tmpmle, name, namelen);
+	if (!found) {
+		/* this lockid has never been seen on this node yet */
+		// mlog(0, "no mle found\n");
+		if (!mle) {
+			spin_unlock(&dlm->master_lock);
+			spin_unlock(&dlm->spinlock);
+
+			mle = (struct dlm_master_list_entry *)
+				kmem_cache_alloc(dlm_mle_cache, GFP_KERNEL);
+			if (!mle) {
+				// bad bad bad... this sucks.
+				response = DLM_MASTER_RESP_ERROR;
+				goto send_response;
+			}
+			spin_lock(&dlm->spinlock);
+			dlm_init_mle(mle, DLM_MLE_BLOCK, dlm, NULL,
+					 name, namelen);
+			spin_unlock(&dlm->spinlock);
+			goto way_up_top;
+		}
+
+		// mlog(0, "this is second time thru, already allocated, "
+		// "add the block.\n");
+		set_bit(request->node_idx, mle->maybe_map);
+		list_add(&mle->list, &dlm->master_list);
+		response = DLM_MASTER_RESP_NO;
+	} else {
+		// mlog(0, "mle was found\n");
+		set_maybe = 1;
+		spin_lock(&tmpmle->spinlock);
+		if (tmpmle->type == DLM_MLE_BLOCK)
+			response = DLM_MASTER_RESP_NO;
+		else if (tmpmle->type == DLM_MLE_MIGRATION) {
+			mlog(0, "migration mle was found (%u->%u)\n",
+			     tmpmle->master, tmpmle->new_master);
+			if (tmpmle->master == dlm->node_num) {
+				mlog(ML_ERROR, "no lockres, but migration mle "
+				     "says that this node is master!\n");
+				BUG();
+			}
+			/* real master can respond on its own */
+			response = DLM_MASTER_RESP_NO;
+		} else {
+			if (tmpmle->master == dlm->node_num) {
+				response = DLM_MASTER_RESP_YES;
+				set_maybe = 0;
+			} else
+				response = DLM_MASTER_RESP_MAYBE;
+		}
+		if (set_maybe)
+			set_bit(request->node_idx, tmpmle->maybe_map);
+		spin_unlock(&tmpmle->spinlock);
+	}
+	spin_unlock(&dlm->master_lock);
+	spin_unlock(&dlm->spinlock);
+
+	if (found) {
+		/* keep the mle attached to heartbeat events */
+		dlm_put_mle(tmpmle);
+	}
+send_response:
+	dlm_put(dlm);
+	return response;
+}
+
+/*
+ * DLM_ASSERT_MASTER_MSG
+ */
+
+
+/*
+ * NOTE: this can be used for debugging
+ * can periodically run all locks owned by this node
+ * and re-assert across the cluster...
+ */
+static int dlm_do_assert_master(struct dlm_ctxt *dlm, const char *lockname,
+				unsigned int namelen, void *nodemap,
+				u32 flags)
+{
+	struct dlm_assert_master assert;
+	int to, tmpret;
+	struct dlm_node_iter iter;
+	int ret = 0;
+
+	BUG_ON(namelen > O2NM_MAX_NAME_LEN);
+
+	/* note that if this nodemap is empty, it returns 0 */
+	dlm_node_iter_init(nodemap, &iter);
+	while ((to = dlm_node_iter_next(&iter)) >= 0) {
+		int r = 0;
+		mlog(0, "sending assert master to %d (%.*s)\n", to,
+		     namelen, lockname);
+		memset(&assert, 0, sizeof(assert));
+		assert.node_idx = dlm->node_num;
+		assert.namelen = namelen;
+		memcpy(assert.name, lockname, namelen);
+		assert.flags = cpu_to_be32(flags);
+
+		tmpret = o2net_send_message(DLM_ASSERT_MASTER_MSG, dlm->key,
+					    &assert, sizeof(assert), to, &r);
+		if (tmpret < 0) {
+			mlog(ML_ERROR, "assert_master returned %d!\n", tmpret);
+			if (!dlm_is_host_down(tmpret)) {
+				mlog(ML_ERROR, "unhandled error!\n");
+				BUG();
+			}
+			/* a node died.  finish out the rest of the nodes. */
+			mlog(ML_ERROR, "link to %d went down!\n", to);
+			/* any nonzero status return will do */
+			ret = tmpret;
+		} else if (r < 0) {
+			/* ok, something horribly messed.  kill thyself. */
+			mlog(ML_ERROR,"during assert master of %.*s to %u, "
+			     "got %d.\n", namelen, lockname, to, r);
+			dlm_dump_lock_resources(dlm);
+			BUG();
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * locks that can be taken here:
+ * dlm->spinlock
+ * res->spinlock
+ * mle->spinlock
+ * dlm->master_list
+ *
+ * if possible, TRIM THIS DOWN!!!
+ */
+int dlm_assert_master_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_master_list_entry *mle = NULL;
+	struct dlm_assert_master *assert = (struct dlm_assert_master *)msg->buf;
+	struct dlm_lock_resource *res = NULL;
+	char *name;
+	unsigned int namelen;
+	u32 flags;
+
+	if (!dlm_grab(dlm))
+		return 0;
+
+	name = assert->name;
+	namelen = assert->namelen;
+	flags = be32_to_cpu(assert->flags);
+
+	if (namelen > DLM_LOCKID_NAME_MAX) {
+		mlog(ML_ERROR, "Invalid name length!");
+		goto done;
+	}
+
+	spin_lock(&dlm->spinlock);
+
+	if (flags)
+		mlog(0, "assert_master with flags: %u\n", flags);
+
+	/* find the MLE */
+	spin_lock(&dlm->master_lock);
+	if (!dlm_find_mle(dlm, &mle, name, namelen)) {
+		/* not an error, could be master just re-asserting */
+		mlog(0, "just got an assert_master from %u, but no "
+		     "MLE for it! (%.*s)\n", assert->node_idx,
+		     namelen, name);
+	} else {
+		int bit = find_next_bit (mle->maybe_map, O2NM_MAX_NODES, 0);
+		if (bit >= O2NM_MAX_NODES) {
+			/* not necessarily an error, though less likely.
+			 * could be master just re-asserting. */
+			mlog(ML_ERROR, "no bits set in the maybe_map, but %u "
+			     "is asserting! (%.*s)\n", assert->node_idx,
+			     namelen, name);
+		} else if (bit != assert->node_idx) {
+			if (flags & DLM_ASSERT_MASTER_MLE_CLEANUP) {
+				mlog(0, "master %u was found, %u should "
+				     "back off\n", assert->node_idx, bit);
+			} else {
+				/* with the fix for bug 569, a higher node
+				 * number winning the mastery will respond
+				 * YES to mastery requests, but this node
+				 * had no way of knowing.  let it pass. */
+				mlog(ML_ERROR, "%u is the lowest node, "
+				     "%u is asserting. (%.*s)  %u must "
+				     "have begun after %u won.\n", bit,
+				     assert->node_idx, namelen, name, bit,
+				     assert->node_idx);
+			}
+		}
+	}
+	spin_unlock(&dlm->master_lock);
+
+	/* ok everything checks out with the MLE
+	 * now check to see if there is a lockres */
+	res = __dlm_lookup_lockres(dlm, name, namelen);
+	if (res) {
+		spin_lock(&res->spinlock);
+		if (res->state & DLM_LOCK_RES_RECOVERING)  {
+			mlog(ML_ERROR, "%u asserting but %.*s is "
+			     "RECOVERING!\n", assert->node_idx, namelen, name);
+			goto kill;
+		}
+		if (!mle) {
+			if (res->owner != assert->node_idx) {
+				mlog(ML_ERROR, "assert_master from "
+					  "%u, but current owner is "
+					  "%u! (%.*s)\n",
+				       assert->node_idx, res->owner,
+				       namelen, name);
+				goto kill;
+			}
+		} else if (mle->type != DLM_MLE_MIGRATION) {
+			if (res->owner != DLM_LOCK_RES_OWNER_UNKNOWN) {
+				/* owner is just re-asserting */
+				if (res->owner == assert->node_idx) {
+					mlog(0, "owner %u re-asserting on "
+					     "lock %.*s\n", assert->node_idx,
+					     namelen, name);
+					goto ok;
+				}
+				mlog(ML_ERROR, "got assert_master from "
+				     "node %u, but %u is the owner! "
+				     "(%.*s)\n", assert->node_idx,
+				     res->owner, namelen, name);
+				goto kill;
+			}
+			if (!(res->state & DLM_LOCK_RES_IN_PROGRESS)) {
+				mlog(ML_ERROR, "got assert from %u, but lock "
+				     "with no owner should be "
+				     "in-progress! (%.*s)\n",
+				     assert->node_idx,
+				     namelen, name);
+				goto kill;
+			}
+		} else /* mle->type == DLM_MLE_MIGRATION */ {
+			/* should only be getting an assert from new master */
+			if (assert->node_idx != mle->new_master) {
+				mlog(ML_ERROR, "got assert from %u, but "
+				     "new master is %u, and old master "
+				     "was %u (%.*s)\n",
+				     assert->node_idx, mle->new_master,
+				     mle->master, namelen, name);
+				goto kill;
+			}
+
+		}
+ok:
+		spin_unlock(&res->spinlock);
+	}
+	spin_unlock(&dlm->spinlock);
+
+	// mlog(0, "woo!  got an assert_master from node %u!\n",
+	// 	     assert->node_idx);
+	if (mle) {
+		int extra_ref;
+		
+		spin_lock(&mle->spinlock);
+		extra_ref = !!(mle->type == DLM_MLE_BLOCK
+			       || mle->type == DLM_MLE_MIGRATION);
+		mle->master = assert->node_idx;
+		atomic_set(&mle->woken, 1);
+		wake_up(&mle->wq);
+		spin_unlock(&mle->spinlock);
+
+		if (mle->type == DLM_MLE_MIGRATION && res) {
+			mlog(0, "finishing off migration of lockres %.*s, "
+			     "from %u to %u\n",
+			       res->lockname.len, res->lockname.name,
+			       dlm->node_num, mle->new_master);
+			spin_lock(&res->spinlock);
+			res->state &= ~DLM_LOCK_RES_MIGRATING;
+			dlm_change_lockres_owner(dlm, res, mle->new_master);
+			BUG_ON(res->state & DLM_LOCK_RES_DIRTY);
+			spin_unlock(&res->spinlock);
+		}
+		/* master is known, detach if not already detached */
+		dlm_mle_detach_hb_events(dlm, mle);
+		dlm_put_mle(mle);
+		
+		if (extra_ref) {
+			/* the assert master message now balances the extra
+		 	 * ref given by the master / migration request message.
+		 	 * if this is the last put, it will be removed
+		 	 * from the list. */
+			dlm_put_mle(mle);
+		}
+	}
+
+done:
+	if (res)
+		dlm_lockres_put(res);
+	dlm_put(dlm);
+	return 0;
+
+kill:
+	/* kill the caller! */
+	spin_unlock(&res->spinlock);
+	spin_unlock(&dlm->spinlock);
+	dlm_lockres_put(res);
+	mlog(ML_ERROR, "Bad message received from another node.  Dumping state "
+	     "and killing the other node now!  This node is OK and can continue.\n");
+	dlm_dump_lock_resources(dlm);
+	dlm_put(dlm);
+	return -EINVAL;
+}
+
+int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
+			       struct dlm_lock_resource *res,
+			       int ignore_higher, u8 request_from, u32 flags)
+{
+	struct dlm_work_item *item;
+	item = kcalloc(1, sizeof(*item), GFP_KERNEL);
+	if (!item)
+		return -ENOMEM;
+
+
+	/* queue up work for dlm_assert_master_worker */
+	dlm_grab(dlm);  /* get an extra ref for the work item */
+	dlm_init_work_item(dlm, item, dlm_assert_master_worker, NULL);
+	item->u.am.lockres = res; /* already have a ref */
+	/* can optionally ignore node numbers higher than this node */
+	item->u.am.ignore_higher = ignore_higher;
+	item->u.am.request_from = request_from;
+	item->u.am.flags = flags;
+
+	spin_lock(&dlm->work_lock);
+	list_add_tail(&item->list, &dlm->work_list);
+	spin_unlock(&dlm->work_lock);
+
+	schedule_work(&dlm->dispatched_work);
+	return 0;
+}
+
+static void dlm_assert_master_worker(struct dlm_work_item *item, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	int ret = 0;
+	struct dlm_lock_resource *res;
+	unsigned long nodemap[BITS_TO_LONGS(O2NM_MAX_NODES)];
+	int ignore_higher;
+	int bit;
+	u8 request_from;
+	u32 flags;
+
+	dlm = item->dlm;
+	res = item->u.am.lockres;
+	ignore_higher = item->u.am.ignore_higher;
+	request_from = item->u.am.request_from;
+	flags = item->u.am.flags;
+
+	spin_lock(&dlm->spinlock);
+	memcpy(nodemap, dlm->domain_map, sizeof(nodemap));
+	spin_unlock(&dlm->spinlock);
+
+	clear_bit(dlm->node_num, nodemap);
+	if (ignore_higher) {
+		/* if is this just to clear up mles for nodes below
+		 * this node, do not send the message to the original
+		 * caller or any node number higher than this */
+		clear_bit(request_from, nodemap);
+		bit = dlm->node_num;
+		while (1) {
+			bit = find_next_bit(nodemap, O2NM_MAX_NODES,
+					    bit+1);
+		       	if (bit >= O2NM_MAX_NODES)
+				break;
+			clear_bit(bit, nodemap);
+		}
+	}
+
+	/* this call now finishes out the nodemap
+	 * even if one or more nodes die */
+	mlog(0, "worker about to master %.*s here, this=%u\n",
+		     res->lockname.len, res->lockname.name, dlm->node_num);
+	ret = dlm_do_assert_master(dlm, res->lockname.name,
+				   res->lockname.len,
+				   nodemap, flags);
+	if (ret < 0) {
+		/* no need to restart, we are done */
+		mlog_errno(ret);
+	}
+
+	dlm_lockres_put(res);
+
+	mlog(0, "finished with dlm_assert_master_worker\n");
+}
+
+
+/*
+ * DLM_MIGRATE_LOCKRES
+ */
+
+
+int dlm_migrate_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
+			u8 target)
+{
+	struct dlm_master_list_entry *mle = NULL;
+	struct dlm_master_list_entry *oldmle = NULL;
+ 	struct dlm_migratable_lockres *mres = NULL;
+	int ret = -EINVAL;
+	const char *name;
+	unsigned int namelen;
+	int mle_added = 0;
+	struct list_head *queue, *iter;
+	int i;
+	struct dlm_lock *lock;
+	int empty = 1;
+
+	if (!dlm_grab(dlm))
+		return -EINVAL;
+
+	name = res->lockname.name;
+	namelen = res->lockname.len;
+
+	mlog(0, "migrating %.*s to %u\n", namelen, name, target);
+
+	/*
+	 * ensure this lockres is a proper candidate for migration
+	 */
+	spin_lock(&res->spinlock);
+	if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
+		mlog(0, "cannot migrate lockres with unknown owner!\n");
+		spin_unlock(&res->spinlock);
+		goto leave;
+	}
+	if (res->owner != dlm->node_num) {
+		mlog(0, "cannot migrate lockres this node doesn't own!\n");
+		spin_unlock(&res->spinlock);
+		goto leave;
+	}
+	mlog(0, "checking queues...\n");
+	queue = &res->granted;
+	for (i=0; i<3; i++) {
+		list_for_each(iter, queue) {
+			lock = list_entry (iter, struct dlm_lock, list);
+			empty = 0;
+			if (lock->ml.node == dlm->node_num) {
+				mlog(0, "found a lock owned by this node "
+				     "still on the %s queue!  will not "
+				     "migrate this lockres\n",
+				     i==0 ? "granted" :
+				     (i==1 ? "converting" : "blocked"));
+				spin_unlock(&res->spinlock);
+				ret = -ENOTEMPTY;
+				goto leave;
+			}
+		}
+		queue++;
+	}
+	mlog(0, "all locks on this lockres are nonlocal.  continuing\n");
+	spin_unlock(&res->spinlock);
+
+	/* no work to do */
+	if (empty) {
+		mlog(0, "no locks were found on this lockres! done!\n");
+		ret = 0;
+		goto leave;
+	}
+
+	/*
+	 * preallocate up front
+	 * if this fails, abort
+	 */
+
+	ret = -ENOMEM;
+	mres = (struct dlm_migratable_lockres *) __get_free_page(GFP_KERNEL);
+	if (!mres) {
+		mlog_errno(ret);
+		goto leave;
+	}
+
+	mle = (struct dlm_master_list_entry *) kmem_cache_alloc(dlm_mle_cache,
+								GFP_KERNEL);
+	if (!mle) {
+		mlog_errno(ret);
+		goto leave;
+	}
+	ret = 0;
+
+	/*
+	 * find a node to migrate the lockres to
+	 */
+
+	mlog(0, "picking a migration node\n");
+	spin_lock(&dlm->spinlock);
+	/* pick a new node */
+	if (!test_bit(target, dlm->domain_map) ||
+	    target >= O2NM_MAX_NODES) {
+		target = dlm_pick_migration_target(dlm, res);
+	}
+	mlog(0, "node %u chosen for migration\n", target);
+
+	if (target >= O2NM_MAX_NODES ||
+	    !test_bit(target, dlm->domain_map)) {
+		/* target chosen is not alive */
+		ret = -EINVAL;
+	}
+
+	if (ret) {
+		spin_unlock(&dlm->spinlock);
+		goto fail;
+	}
+
+	mlog(0, "continuing with target = %u\n", target);
+
+	/*
+	 * clear any existing master requests and
+	 * add the migration mle to the list
+	 */
+	spin_lock(&dlm->master_lock);
+	ret = dlm_add_migration_mle(dlm, res, mle, &oldmle, name,
+				    namelen, target, dlm->node_num);
+	spin_unlock(&dlm->master_lock);
+	spin_unlock(&dlm->spinlock);
+
+	if (ret == -EEXIST) {
+		mlog(0, "another process is already migrating it\n");
+		goto fail;
+	}
+	mle_added = 1;
+
+	/*
+	 * set the MIGRATING flag and flush asts
+	 * if we fail after this we need to re-dirty the lockres
+	 */
+	if (dlm_mark_lockres_migrating(dlm, res, target) < 0) {
+		mlog(ML_ERROR, "tried to migrate %.*s to %u, but "
+		     "the target went down.\n", res->lockname.len,
+		     res->lockname.name, target);
+		spin_lock(&res->spinlock);
+		res->state &= ~DLM_LOCK_RES_MIGRATING;
+		spin_unlock(&res->spinlock);
+		ret = -EINVAL;
+	}
+
+fail:
+	if (oldmle) {
+		/* master is known, detach if not already detached */
+		dlm_mle_detach_hb_events(dlm, oldmle);
+		dlm_put_mle(oldmle);
+	}
+
+	if (ret < 0) {
+		if (mle_added) {
+			dlm_mle_detach_hb_events(dlm, mle);
+			dlm_put_mle(mle);
+		} else if (mle) {
+			kmem_cache_free(dlm_mle_cache, mle);
+		}
+		goto leave;
+	}
+
+	/*
+	 * at this point, we have a migration target, an mle
+	 * in the master list, and the MIGRATING flag set on
+	 * the lockres
+	 */
+
+
+	/* get an extra reference on the mle.
+	 * otherwise the assert_master from the new
+	 * master will destroy this.
+	 * also, make sure that all callers of dlm_get_mle
+	 * take both dlm->spinlock and dlm->master_lock */
+	spin_lock(&dlm->spinlock);
+	spin_lock(&dlm->master_lock);
+	dlm_get_mle(mle);
+	spin_unlock(&dlm->master_lock);
+	spin_unlock(&dlm->spinlock);
+
+	/* notify new node and send all lock state */
+	/* call send_one_lockres with migration flag.
+	 * this serves as notice to the target node that a
+	 * migration is starting. */
+	ret = dlm_send_one_lockres(dlm, res, mres, target,
+				   DLM_MRES_MIGRATION);
+
+	if (ret < 0) {
+		mlog(0, "migration to node %u failed with %d\n",
+		     target, ret);
+		/* migration failed, detach and clean up mle */
+		dlm_mle_detach_hb_events(dlm, mle);
+		dlm_put_mle(mle);
+		dlm_put_mle(mle);
+		goto leave;
+	}
+
+	/* at this point, the target sends a message to all nodes,
+	 * (using dlm_do_migrate_request).  this node is skipped since
+	 * we had to put an mle in the list to begin the process.  this
+	 * node now waits for target to do an assert master.  this node
+	 * will be the last one notified, ensuring that the migration
+	 * is complete everywhere.  if the target dies while this is
+	 * going on, some nodes could potentially see the target as the
+	 * master, so it is important that my recovery finds the migration
+	 * mle and sets the master to UNKNONWN. */
+
+
+	/* wait for new node to assert master */
+	while (1) {
+		ret = wait_event_interruptible_timeout(mle->wq,
+					(atomic_read(&mle->woken) == 1),
+					msecs_to_jiffies(5000));
+
+		if (ret >= 0) {
+		       	if (atomic_read(&mle->woken) == 1 ||
+			    res->owner == target)
+				break;
+
+			mlog(0, "timed out during migration\n");
+		}
+		if (ret == -ERESTARTSYS) {
+			/* migration failed, detach and clean up mle */
+			dlm_mle_detach_hb_events(dlm, mle);
+			dlm_put_mle(mle);
+			dlm_put_mle(mle);
+			goto leave;
+		}
+		/* TODO: if node died: stop, clean up, return error */
+	}
+
+	/* all done, set the owner, clear the flag */
+	spin_lock(&res->spinlock);
+	dlm_set_lockres_owner(dlm, res, target);
+	res->state &= ~DLM_LOCK_RES_MIGRATING;
+	dlm_remove_nonlocal_locks(dlm, res);
+	spin_unlock(&res->spinlock);
+	wake_up(&res->wq);
+
+	/* master is known, detach if not already detached */
+	dlm_mle_detach_hb_events(dlm, mle);
+	dlm_put_mle(mle);
+	ret = 0;
+
+	dlm_lockres_calc_usage(dlm, res);
+
+leave:
+	/* re-dirty the lockres if we failed */
+	if (ret < 0)
+		dlm_kick_thread(dlm, res);
+
+	/* TODO: cleanup */
+	if (mres)
+		free_page((unsigned long)mres);
+
+	dlm_put(dlm);
+
+	mlog(0, "returning %d\n", ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dlm_migrate_lockres);
+
+int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock)
+{
+	int ret;
+	spin_lock(&dlm->ast_lock);
+	spin_lock(&lock->spinlock);
+	ret = (list_empty(&lock->bast_list) && !lock->bast_pending);
+	spin_unlock(&lock->spinlock);
+	spin_unlock(&dlm->ast_lock);
+	return ret;
+}
+
+static int dlm_migration_can_proceed(struct dlm_ctxt *dlm,
+				     struct dlm_lock_resource *res,
+				     u8 mig_target)
+{
+	int can_proceed;
+	spin_lock(&res->spinlock);
+	can_proceed = !!(res->state & DLM_LOCK_RES_MIGRATING);
+	spin_unlock(&res->spinlock);
+
+	/* target has died, so make the caller break out of the 
+	 * wait_event, but caller must recheck the domain_map */
+	spin_lock(&dlm->spinlock);
+	if (!test_bit(mig_target, dlm->domain_map))
+		can_proceed = 1;
+	spin_unlock(&dlm->spinlock);
+	return can_proceed;
+}
+
+int dlm_lockres_is_dirty(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
+{
+	int ret;
+	spin_lock(&res->spinlock);
+	ret = !!(res->state & DLM_LOCK_RES_DIRTY);
+	spin_unlock(&res->spinlock);
+	return ret;
+}
+
+
+static int dlm_mark_lockres_migrating(struct dlm_ctxt *dlm,
+				       struct dlm_lock_resource *res,
+				       u8 target)
+{
+	int ret = 0;
+
+	mlog(0, "dlm_mark_lockres_migrating: %.*s, from %u to %u\n",
+	       res->lockname.len, res->lockname.name, dlm->node_num,
+	       target);
+	/* need to set MIGRATING flag on lockres.  this is done by
+	 * ensuring that all asts have been flushed for this lockres. */
+	spin_lock(&res->spinlock);
+	BUG_ON(res->migration_pending);
+	res->migration_pending = 1;
+	/* strategy is to reserve an extra ast then release
+	 * it below, letting the release do all of the work */
+	__dlm_lockres_reserve_ast(res);
+	spin_unlock(&res->spinlock);
+
+	/* now flush all the pending asts.. hang out for a bit */
+	dlm_kick_thread(dlm, res);
+	wait_event(dlm->ast_wq, !dlm_lockres_is_dirty(dlm, res));
+	dlm_lockres_release_ast(dlm, res);
+
+	mlog(0, "about to wait on migration_wq, dirty=%s\n",
+	       res->state & DLM_LOCK_RES_DIRTY ? "yes" : "no");
+	/* if the extra ref we just put was the final one, this
+	 * will pass thru immediately.  otherwise, we need to wait
+	 * for the last ast to finish. */
+again:
+	ret = wait_event_interruptible_timeout(dlm->migration_wq,
+		   dlm_migration_can_proceed(dlm, res, target),
+		   msecs_to_jiffies(1000));
+	if (ret < 0) {
+		mlog(0, "woken again: migrating? %s, dead? %s\n",
+		       res->state & DLM_LOCK_RES_MIGRATING ? "yes":"no",
+		       test_bit(target, dlm->domain_map) ? "no":"yes");
+	} else {
+		mlog(0, "all is well: migrating? %s, dead? %s\n",
+		       res->state & DLM_LOCK_RES_MIGRATING ? "yes":"no",
+		       test_bit(target, dlm->domain_map) ? "no":"yes");
+	}
+	if (!dlm_migration_can_proceed(dlm, res, target)) {
+		mlog(0, "trying again...\n");
+		goto again;
+	}
+
+	/* did the target go down or die? */
+	spin_lock(&dlm->spinlock);
+	if (!test_bit(target, dlm->domain_map)) {
+		mlog(ML_ERROR, "aha. migration target %u just went down\n",
+		     target);
+		ret = -EHOSTDOWN;
+	}
+	spin_unlock(&dlm->spinlock);
+
+	/*
+	 * at this point:
+	 *
+	 *   o the DLM_LOCK_RES_MIGRATING flag is set
+	 *   o there are no pending asts on this lockres
+	 *   o all processes trying to reserve an ast on this
+	 *     lockres must wait for the MIGRATING flag to clear
+	 */
+	return ret;
+}
+
+/* last step in the migration process.
+ * original master calls this to free all of the dlm_lock
+ * structures that used to be for other nodes. */
+static void dlm_remove_nonlocal_locks(struct dlm_ctxt *dlm,
+				      struct dlm_lock_resource *res)
+{
+	struct list_head *iter, *iter2;
+	struct list_head *queue = &res->granted;
+	int i;
+	struct dlm_lock *lock;
+
+	assert_spin_locked(&res->spinlock);
+
+	BUG_ON(res->owner == dlm->node_num);
+
+	for (i=0; i<3; i++) {
+		list_for_each_safe(iter, iter2, queue) {
+			lock = list_entry (iter, struct dlm_lock, list);
+			if (lock->ml.node != dlm->node_num) {
+				mlog(0, "putting lock for node %u\n",
+				     lock->ml.node);
+				/* be extra careful */
+				BUG_ON(!list_empty(&lock->ast_list));
+				BUG_ON(!list_empty(&lock->bast_list));
+				BUG_ON(lock->ast_pending);
+				BUG_ON(lock->bast_pending);
+				list_del_init(&lock->list);
+				dlm_lock_put(lock);
+			}
+		}
+		queue++;
+	}
+}
+
+/* for now this is not too intelligent.  we will
+ * need stats to make this do the right thing.
+ * this just finds the first lock on one of the
+ * queues and uses that node as the target. */
+static u8 dlm_pick_migration_target(struct dlm_ctxt *dlm,
+				    struct dlm_lock_resource *res)
+{
+	int i;
+	struct list_head *queue = &res->granted;
+	struct list_head *iter;
+	struct dlm_lock *lock;
+	int nodenum;
+
+	assert_spin_locked(&dlm->spinlock);
+
+	spin_lock(&res->spinlock);
+	for (i=0; i<3; i++) {
+		list_for_each(iter, queue) {
+			/* up to the caller to make sure this node
+			 * is alive */
+			lock = list_entry (iter, struct dlm_lock, list);
+			if (lock->ml.node != dlm->node_num) {
+				spin_unlock(&res->spinlock);
+				return lock->ml.node;
+			}
+		}
+		queue++;
+	}
+	spin_unlock(&res->spinlock);
+	mlog(0, "have not found a suitable target yet! checking domain map\n");
+
+	/* ok now we're getting desperate.  pick anyone alive. */
+	nodenum = -1;
+	while (1) {
+		nodenum = find_next_bit(dlm->domain_map,
+					O2NM_MAX_NODES, nodenum+1);
+		mlog(0, "found %d in domain map\n", nodenum);
+		if (nodenum >= O2NM_MAX_NODES)
+			break;
+		if (nodenum != dlm->node_num) {
+			mlog(0, "picking %d\n", nodenum);
+			return nodenum;
+		}
+	}
+
+	mlog(0, "giving up.  no master to migrate to\n");
+	return DLM_LOCK_RES_OWNER_UNKNOWN;
+}
+
+
+
+/* this is called by the new master once all lockres
+ * data has been received */
+static int dlm_do_migrate_request(struct dlm_ctxt *dlm,
+				  struct dlm_lock_resource *res,
+				  u8 master, u8 new_master,
+				  struct dlm_node_iter *iter)
+{
+	struct dlm_migrate_request migrate;
+	int ret, status = 0;
+	int nodenum;
+
+	memset(&migrate, 0, sizeof(migrate));
+	migrate.namelen = res->lockname.len;
+	memcpy(migrate.name, res->lockname.name, migrate.namelen);
+	migrate.new_master = new_master;
+	migrate.master = master;
+
+	ret = 0;
+
+	/* send message to all nodes, except the master and myself */
+	while ((nodenum = dlm_node_iter_next(iter)) >= 0) {
+		if (nodenum == master ||
+		    nodenum == new_master)
+			continue;
+
+		ret = o2net_send_message(DLM_MIGRATE_REQUEST_MSG, dlm->key,
+					 &migrate, sizeof(migrate), nodenum,
+					 &status);
+		if (ret < 0)
+			mlog_errno(ret);
+		else if (status < 0) {
+			mlog(0, "migrate request (node %u) returned %d!\n",
+			     nodenum, status);
+			ret = status;
+		}
+	}
+
+	if (ret < 0)
+		mlog_errno(ret);
+
+	mlog(0, "returning ret=%d\n", ret);
+	return ret;
+}
+
+
+/* if there is an existing mle for this lockres, we now know who the master is.
+ * (the one who sent us *this* message) we can clear it up right away.
+ * since the process that put the mle on the list still has a reference to it,
+ * we can unhash it now, set the master and wake the process.  as a result,
+ * we will have no mle in the list to start with.  now we can add an mle for
+ * the migration and this should be the only one found for those scanning the
+ * list.  */
+int dlm_migrate_request_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_lock_resource *res = NULL;
+	struct dlm_migrate_request *migrate = (struct dlm_migrate_request *) msg->buf;
+	struct dlm_master_list_entry *mle = NULL, *oldmle = NULL;
+	const char *name;
+	unsigned int namelen;
+	int ret = 0;
+
+	if (!dlm_grab(dlm))
+		return -EINVAL;
+
+	name = migrate->name;
+	namelen = migrate->namelen;
+
+	/* preallocate.. if this fails, abort */
+	mle = (struct dlm_master_list_entry *) kmem_cache_alloc(dlm_mle_cache,
+							 GFP_KERNEL);
+
+	if (!mle) {
+		ret = -ENOMEM;
+		goto leave;
+	}
+
+	/* check for pre-existing lock */
+	spin_lock(&dlm->spinlock);
+	res = __dlm_lookup_lockres(dlm, name, namelen);
+	spin_lock(&dlm->master_lock);
+
+	if (res) {
+		spin_lock(&res->spinlock);
+		if (res->state & DLM_LOCK_RES_RECOVERING) {
+			/* if all is working ok, this can only mean that we got
+		 	* a migrate request from a node that we now see as
+		 	* dead.  what can we do here?  drop it to the floor? */
+			spin_unlock(&res->spinlock);
+			mlog(ML_ERROR, "Got a migrate request, but the "
+			     "lockres is marked as recovering!");
+			kmem_cache_free(dlm_mle_cache, mle);
+			ret = -EINVAL; /* need a better solution */
+			goto unlock;
+		}
+		res->state |= DLM_LOCK_RES_MIGRATING;
+		spin_unlock(&res->spinlock);
+	}
+
+	/* ignore status.  only nonzero status would BUG. */
+	ret = dlm_add_migration_mle(dlm, res, mle, &oldmle,
+				    name, namelen,
+				    migrate->new_master,
+				    migrate->master);
+
+unlock:
+	spin_unlock(&dlm->master_lock);
+	spin_unlock(&dlm->spinlock);
+
+	if (oldmle) {
+		/* master is known, detach if not already detached */
+		dlm_mle_detach_hb_events(dlm, oldmle);
+		dlm_put_mle(oldmle);
+	}
+
+	if (res)
+		dlm_lockres_put(res);
+leave:
+	dlm_put(dlm);
+	return ret;
+}
+
+/* must be holding dlm->spinlock and dlm->master_lock
+ * when adding a migration mle, we can clear any other mles
+ * in the master list because we know with certainty that
+ * the master is "master".  so we remove any old mle from
+ * the list after setting it's master field, and then add
+ * the new migration mle.  this way we can hold with the rule
+ * of having only one mle for a given lock name at all times. */
+static int dlm_add_migration_mle(struct dlm_ctxt *dlm,
+				 struct dlm_lock_resource *res,
+				 struct dlm_master_list_entry *mle,
+				 struct dlm_master_list_entry **oldmle,
+				 const char *name, unsigned int namelen,
+				 u8 new_master, u8 master)
+{
+	int found;
+	int ret = 0;
+
+	*oldmle = NULL;
+
+	mlog_entry_void();
+
+	assert_spin_locked(&dlm->spinlock);
+	assert_spin_locked(&dlm->master_lock);
+
+	/* caller is responsible for any ref taken here on oldmle */
+	found = dlm_find_mle(dlm, oldmle, (char *)name, namelen);
+	if (found) {
+		struct dlm_master_list_entry *tmp = *oldmle;
+		spin_lock(&tmp->spinlock);
+		if (tmp->type == DLM_MLE_MIGRATION) {
+			if (master == dlm->node_num) {
+				/* ah another process raced me to it */
+				mlog(0, "tried to migrate %.*s, but some "
+				     "process beat me to it\n",
+				     namelen, name);
+				ret = -EEXIST;
+			} else {
+				/* bad.  2 NODES are trying to migrate! */
+				mlog(ML_ERROR, "migration error  mle: "
+				     "master=%u new_master=%u // request: "
+				     "master=%u new_master=%u // "
+				     "lockres=%.*s\n",
+				     tmp->master, tmp->new_master,
+				     master, new_master,
+				     namelen, name);
+				BUG();
+			}
+		} else {
+			/* this is essentially what assert_master does */
+			tmp->master = master;
+			atomic_set(&tmp->woken, 1);
+			wake_up(&tmp->wq);
+			/* remove it from the list so that only one
+			 * mle will be found */
+			list_del_init(&tmp->list);
+		}
+		spin_unlock(&tmp->spinlock);
+	}
+
+	/* now add a migration mle to the tail of the list */
+	dlm_init_mle(mle, DLM_MLE_MIGRATION, dlm, res, name, namelen);
+	mle->new_master = new_master;
+	mle->master = master;
+	/* do this for consistency with other mle types */
+	set_bit(new_master, mle->maybe_map);
+	list_add(&mle->list, &dlm->master_list);
+
+	return ret;
+}
+
+
+void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
+{
+	struct list_head *iter, *iter2;
+	struct dlm_master_list_entry *mle;
+	struct dlm_lock_resource *res;
+
+	mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node);
+top:
+	assert_spin_locked(&dlm->spinlock);
+
+	/* clean the master list */
+	spin_lock(&dlm->master_lock);
+	list_for_each_safe(iter, iter2, &dlm->master_list) {
+		mle = list_entry(iter, struct dlm_master_list_entry, list);
+
+		BUG_ON(mle->type != DLM_MLE_BLOCK &&
+		       mle->type != DLM_MLE_MASTER &&
+		       mle->type != DLM_MLE_MIGRATION);
+
+		/* MASTER mles are initiated locally.  the waiting
+		 * process will notice the node map change
+		 * shortly.  let that happen as normal. */
+		if (mle->type == DLM_MLE_MASTER)
+			continue;
+
+
+		/* BLOCK mles are initiated by other nodes.
+		 * need to clean up if the dead node would have
+		 * been the master. */
+		if (mle->type == DLM_MLE_BLOCK) {
+			int bit;
+
+			spin_lock(&mle->spinlock);
+			bit = find_next_bit(mle->maybe_map, O2NM_MAX_NODES, 0);
+			if (bit != dead_node) {
+				mlog(0, "mle found, but dead node %u would "
+				     "not have been master\n", dead_node);
+				spin_unlock(&mle->spinlock);
+			} else {
+				/* must drop the refcount by one since the
+				 * assert_master will never arrive.  this
+				 * may result in the mle being unlinked and
+				 * freed, but there may still be a process
+				 * waiting in the dlmlock path which is fine. */
+				mlog(ML_ERROR, "node %u was expected master\n",
+				     dead_node);
+				atomic_set(&mle->woken, 1);
+				spin_unlock(&mle->spinlock);
+				wake_up(&mle->wq);
+				/* final put will take care of list removal */
+				__dlm_put_mle(mle);
+			}
+			continue;
+		}
+
+		/* everything else is a MIGRATION mle */
+
+		/* the rule for MIGRATION mles is that the master
+		 * becomes UNKNOWN if *either* the original or
+		 * the new master dies.  all UNKNOWN lockreses
+		 * are sent to whichever node becomes the recovery
+		 * master.  the new master is responsible for
+		 * determining if there is still a master for
+		 * this lockres, or if he needs to take over
+		 * mastery.  either way, this node should expect
+		 * another message to resolve this. */
+		if (mle->master != dead_node &&
+		    mle->new_master != dead_node)
+			continue;
+
+		/* if we have reached this point, this mle needs to
+		 * be removed from the list and freed. */
+
+		/* remove from the list early.  NOTE: unlinking
+		 * list_head while in list_for_each_safe */
+		spin_lock(&mle->spinlock);
+		list_del_init(&mle->list);
+		atomic_set(&mle->woken, 1);
+		spin_unlock(&mle->spinlock);
+		wake_up(&mle->wq);
+
+		mlog(0, "node %u died during migration from "
+		     "%u to %u!\n", dead_node,
+		     mle->master, mle->new_master);
+		/* if there is a lockres associated with this
+	 	 * mle, find it and set its owner to UNKNOWN */
+		res = __dlm_lookup_lockres(dlm, mle->u.name.name,
+					mle->u.name.len);
+		if (res) {
+			/* unfortunately if we hit this rare case, our
+		 	 * lock ordering is messed.  we need to drop
+		 	 * the master lock so that we can take the
+		  	 * lockres lock, meaning that we will have to
+			 * restart from the head of list. */
+			spin_unlock(&dlm->master_lock);
+
+			/* move lockres onto recovery list */
+			spin_lock(&res->spinlock);
+			dlm_set_lockres_owner(dlm, res,
+				      	DLM_LOCK_RES_OWNER_UNKNOWN);
+			dlm_move_lockres_to_recovery_list(dlm, res);
+			spin_unlock(&res->spinlock);
+			dlm_lockres_put(res);
+
+			/* dump the mle */
+			spin_lock(&dlm->master_lock);
+			__dlm_put_mle(mle);
+			spin_unlock(&dlm->master_lock);
+
+			/* restart */
+			goto top;
+		}
+
+		/* this may be the last reference */
+		__dlm_put_mle(mle);
+	}
+	spin_unlock(&dlm->master_lock);
+}
+
+
+int dlm_finish_migration(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
+			 u8 old_master)
+{
+	struct dlm_node_iter iter;
+	int ret = 0;
+
+	spin_lock(&dlm->spinlock);
+	dlm_node_iter_init(dlm->domain_map, &iter);
+	clear_bit(old_master, iter.node_map);
+	clear_bit(dlm->node_num, iter.node_map);
+	spin_unlock(&dlm->spinlock);
+
+	mlog(0, "now time to do a migrate request to other nodes\n");
+	ret = dlm_do_migrate_request(dlm, res, old_master,
+				     dlm->node_num, &iter);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto leave;
+	}
+
+	mlog(0, "doing assert master of %.*s to all except the original node\n",
+	     res->lockname.len, res->lockname.name);
+	/* this call now finishes out the nodemap
+	 * even if one or more nodes die */
+	ret = dlm_do_assert_master(dlm, res->lockname.name,
+				   res->lockname.len, iter.node_map,
+				   DLM_ASSERT_MASTER_FINISH_MIGRATION);
+	if (ret < 0) {
+		/* no longer need to retry.  all living nodes contacted. */
+		mlog_errno(ret);
+		ret = 0;
+	}
+
+	memset(iter.node_map, 0, sizeof(iter.node_map));
+	set_bit(old_master, iter.node_map);
+	mlog(0, "doing assert master of %.*s back to %u\n",
+	     res->lockname.len, res->lockname.name, old_master);
+	ret = dlm_do_assert_master(dlm, res->lockname.name,
+				   res->lockname.len, iter.node_map,
+				   DLM_ASSERT_MASTER_FINISH_MIGRATION);
+	if (ret < 0) {
+		mlog(0, "assert master to original master failed "
+		     "with %d.\n", ret);
+		/* the only nonzero status here would be because of
+		 * a dead original node.  we're done. */
+		ret = 0;
+	}
+
+	/* all done, set the owner, clear the flag */
+	spin_lock(&res->spinlock);
+	dlm_set_lockres_owner(dlm, res, dlm->node_num);
+	res->state &= ~DLM_LOCK_RES_MIGRATING;
+	spin_unlock(&res->spinlock);
+	/* re-dirty it on the new master */
+	dlm_kick_thread(dlm, res);
+	wake_up(&res->wq);
+leave:
+	return ret;
+}
+
+/*
+ * LOCKRES AST REFCOUNT
+ * this is integral to migration
+ */
+
+/* for future intent to call an ast, reserve one ahead of time.
+ * this should be called only after waiting on the lockres
+ * with dlm_wait_on_lockres, and while still holding the
+ * spinlock after the call. */
+void __dlm_lockres_reserve_ast(struct dlm_lock_resource *res)
+{
+	assert_spin_locked(&res->spinlock);
+	if (res->state & DLM_LOCK_RES_MIGRATING) {
+		__dlm_print_one_lock_resource(res);
+	}
+	BUG_ON(res->state & DLM_LOCK_RES_MIGRATING);
+
+	atomic_inc(&res->asts_reserved);
+}
+
+/*
+ * used to drop the reserved ast, either because it went unused,
+ * or because the ast/bast was actually called.
+ *
+ * also, if there is a pending migration on this lockres,
+ * and this was the last pending ast on the lockres,
+ * atomically set the MIGRATING flag before we drop the lock.
+ * this is how we ensure that migration can proceed with no
+ * asts in progress.  note that it is ok if the state of the
+ * queues is such that a lock should be granted in the future
+ * or that a bast should be fired, because the new master will
+ * shuffle the lists on this lockres as soon as it is migrated.
+ */
+void dlm_lockres_release_ast(struct dlm_ctxt *dlm,
+			     struct dlm_lock_resource *res)
+{
+	if (!atomic_dec_and_lock(&res->asts_reserved, &res->spinlock))
+		return;
+
+	if (!res->migration_pending) {
+		spin_unlock(&res->spinlock);
+		return;
+	}
+
+	BUG_ON(res->state & DLM_LOCK_RES_MIGRATING);
+	res->migration_pending = 0;
+	res->state |= DLM_LOCK_RES_MIGRATING;
+	spin_unlock(&res->spinlock);
+	wake_up(&res->wq);
+	wake_up(&dlm->migration_wq);
+}
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
new file mode 100644
index 0000000..0c8eb10
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -0,0 +1,2132 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmrecovery.c
+ *
+ * recovery stuff
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include <linux/random.h>
+#include <linux/blkdev.h>
+#include <linux/socket.h>
+#include <linux/inet.h>
+#include <linux/timer.h>
+#include <linux/kthread.h>
+
+
+#include "cluster/heartbeat.h"
+#include "cluster/nodemanager.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+#include "dlmcommon.h"
+#include "dlmdomain.h"
+
+#define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_RECOVERY)
+#include "cluster/masklog.h"
+
+static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node);
+
+static int dlm_recovery_thread(void *data);
+void dlm_complete_recovery_thread(struct dlm_ctxt *dlm);
+int dlm_launch_recovery_thread(struct dlm_ctxt *dlm);
+static void dlm_kick_recovery_thread(struct dlm_ctxt *dlm);
+static int dlm_do_recovery(struct dlm_ctxt *dlm);
+
+static int dlm_pick_recovery_master(struct dlm_ctxt *dlm);
+static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node);
+static int dlm_init_recovery_area(struct dlm_ctxt *dlm, u8 dead_node);
+static int dlm_request_all_locks(struct dlm_ctxt *dlm,
+				 u8 request_from, u8 dead_node);
+static void dlm_destroy_recovery_area(struct dlm_ctxt *dlm, u8 dead_node);
+
+static inline int dlm_num_locks_in_lockres(struct dlm_lock_resource *res);
+static void dlm_init_migratable_lockres(struct dlm_migratable_lockres *mres,
+					const char *lockname, int namelen,
+					int total_locks, u64 cookie,
+					u8 flags, u8 master);
+static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
+				    struct dlm_migratable_lockres *mres,
+				    u8 send_to,
+				    struct dlm_lock_resource *res,
+				    int total_locks);
+static int dlm_lockres_master_requery(struct dlm_ctxt *dlm,
+				      struct dlm_lock_resource *res,
+				      u8 *real_master);
+static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
+				     struct dlm_lock_resource *res,
+				     struct dlm_migratable_lockres *mres);
+static int dlm_do_master_requery(struct dlm_ctxt *dlm,
+				 struct dlm_lock_resource *res,
+				 u8 nodenum, u8 *real_master);
+static int dlm_send_finalize_reco_message(struct dlm_ctxt *dlm);
+static int dlm_send_all_done_msg(struct dlm_ctxt *dlm,
+				 u8 dead_node, u8 send_to);
+static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node);
+static void dlm_move_reco_locks_to_list(struct dlm_ctxt *dlm,
+					struct list_head *list, u8 dead_node);
+static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
+					      u8 dead_node, u8 new_master);
+static void dlm_reco_ast(void *astdata);
+static void dlm_reco_bast(void *astdata, int blocked_type);
+static void dlm_reco_unlock_ast(void *astdata, enum dlm_status st);
+static void dlm_request_all_locks_worker(struct dlm_work_item *item,
+					 void *data);
+static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data);
+
+static u64 dlm_get_next_mig_cookie(void);
+
+static spinlock_t dlm_reco_state_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t dlm_mig_cookie_lock = SPIN_LOCK_UNLOCKED;
+static u64 dlm_mig_cookie = 1;
+
+static u64 dlm_get_next_mig_cookie(void)
+{
+	u64 c;
+	spin_lock(&dlm_mig_cookie_lock);
+	c = dlm_mig_cookie;
+	if (dlm_mig_cookie == (~0ULL))
+		dlm_mig_cookie = 1;
+	else
+		dlm_mig_cookie++;
+	spin_unlock(&dlm_mig_cookie_lock);
+	return c;
+}
+
+static inline void dlm_reset_recovery(struct dlm_ctxt *dlm)
+{
+	spin_lock(&dlm->spinlock);
+	clear_bit(dlm->reco.dead_node, dlm->recovery_map);
+	dlm->reco.dead_node = O2NM_INVALID_NODE_NUM;
+	dlm->reco.new_master = O2NM_INVALID_NODE_NUM;
+	spin_unlock(&dlm->spinlock);
+}
+
+/* Worker function used during recovery. */
+void dlm_dispatch_work(void *data)
+{
+	struct dlm_ctxt *dlm = (struct dlm_ctxt *)data;
+	LIST_HEAD(tmp_list);
+	struct list_head *iter, *iter2;
+	struct dlm_work_item *item;
+	dlm_workfunc_t *workfunc;
+
+	spin_lock(&dlm->work_lock);
+	list_splice_init(&dlm->work_list, &tmp_list);
+	spin_unlock(&dlm->work_lock);
+
+	list_for_each_safe(iter, iter2, &tmp_list) {
+		item = list_entry(iter, struct dlm_work_item, list);
+		workfunc = item->func;
+		list_del_init(&item->list);
+
+		/* already have ref on dlm to avoid having
+		 * it disappear.  just double-check. */
+		BUG_ON(item->dlm != dlm);
+
+		/* this is allowed to sleep and
+		 * call network stuff */
+		workfunc(item, item->data);
+
+		dlm_put(dlm);
+		kfree(item);
+	}
+}
+
+/*
+ * RECOVERY THREAD
+ */
+
+static void dlm_kick_recovery_thread(struct dlm_ctxt *dlm)
+{
+	/* wake the recovery thread
+	 * this will wake the reco thread in one of three places
+	 * 1) sleeping with no recovery happening
+	 * 2) sleeping with recovery mastered elsewhere
+	 * 3) recovery mastered here, waiting on reco data */
+
+	wake_up(&dlm->dlm_reco_thread_wq);
+}
+
+/* Launch the recovery thread */
+int dlm_launch_recovery_thread(struct dlm_ctxt *dlm)
+{
+	mlog(0, "starting dlm recovery thread...\n");
+
+	dlm->dlm_reco_thread_task = kthread_run(dlm_recovery_thread, dlm,
+						"dlm_reco_thread");
+	if (IS_ERR(dlm->dlm_reco_thread_task)) {
+		mlog_errno(PTR_ERR(dlm->dlm_reco_thread_task));
+		dlm->dlm_reco_thread_task = NULL;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void dlm_complete_recovery_thread(struct dlm_ctxt *dlm)
+{
+	if (dlm->dlm_reco_thread_task) {
+		mlog(0, "waiting for dlm recovery thread to exit\n");
+		kthread_stop(dlm->dlm_reco_thread_task);
+		dlm->dlm_reco_thread_task = NULL;
+	}
+}
+
+
+
+/*
+ * this is lame, but here's how recovery works...
+ * 1) all recovery threads cluster wide will work on recovering
+ *    ONE node at a time
+ * 2) negotiate who will take over all the locks for the dead node.
+ *    thats right... ALL the locks.
+ * 3) once a new master is chosen, everyone scans all locks
+ *    and moves aside those mastered by the dead guy
+ * 4) each of these locks should be locked until recovery is done
+ * 5) the new master collects up all of secondary lock queue info
+ *    one lock at a time, forcing each node to communicate back
+ *    before continuing
+ * 6) each secondary lock queue responds with the full known lock info
+ * 7) once the new master has run all its locks, it sends a ALLDONE!
+ *    message to everyone
+ * 8) upon receiving this message, the secondary queue node unlocks
+ *    and responds to the ALLDONE
+ * 9) once the new master gets responses from everyone, he unlocks
+ *    everything and recovery for this dead node is done
+ *10) go back to 2) while there are still dead nodes
+ *
+ */
+
+
+#define DLM_RECO_THREAD_TIMEOUT_MS (5 * 1000)
+
+static int dlm_recovery_thread(void *data)
+{
+	int status;
+	struct dlm_ctxt *dlm = data;
+	unsigned long timeout = msecs_to_jiffies(DLM_RECO_THREAD_TIMEOUT_MS);
+
+	mlog(0, "dlm thread running for %s...\n", dlm->name);
+
+	while (!kthread_should_stop()) {
+		if (dlm_joined(dlm)) {
+			status = dlm_do_recovery(dlm);
+			if (status == -EAGAIN) {
+				/* do not sleep, recheck immediately. */
+				continue;
+			}
+			if (status < 0)
+				mlog_errno(status);
+		}
+
+		wait_event_interruptible_timeout(dlm->dlm_reco_thread_wq,
+						 kthread_should_stop(),
+						 timeout);
+	}
+
+	mlog(0, "quitting DLM recovery thread\n");
+	return 0;
+}
+
+/* callers of the top-level api calls (dlmlock/dlmunlock) should
+ * block on the dlm->reco.event when recovery is in progress.
+ * the dlm recovery thread will set this state when it begins
+ * recovering a dead node (as the new master or not) and clear
+ * the state and wake as soon as all affected lock resources have
+ * been marked with the RECOVERY flag */
+static int dlm_in_recovery(struct dlm_ctxt *dlm)
+{
+	int in_recovery;
+	spin_lock(&dlm->spinlock);
+	in_recovery = !!(dlm->reco.state & DLM_RECO_STATE_ACTIVE);
+	spin_unlock(&dlm->spinlock);
+	return in_recovery;
+}
+
+
+void dlm_wait_for_recovery(struct dlm_ctxt *dlm)
+{
+	wait_event(dlm->reco.event, !dlm_in_recovery(dlm));
+}
+
+static void dlm_begin_recovery(struct dlm_ctxt *dlm)
+{
+	spin_lock(&dlm->spinlock);
+	BUG_ON(dlm->reco.state & DLM_RECO_STATE_ACTIVE);
+	dlm->reco.state |= DLM_RECO_STATE_ACTIVE;
+	spin_unlock(&dlm->spinlock);
+}
+
+static void dlm_end_recovery(struct dlm_ctxt *dlm)
+{
+	spin_lock(&dlm->spinlock);
+	BUG_ON(!(dlm->reco.state & DLM_RECO_STATE_ACTIVE));
+	dlm->reco.state &= ~DLM_RECO_STATE_ACTIVE;
+	spin_unlock(&dlm->spinlock);
+	wake_up(&dlm->reco.event);
+}
+
+static int dlm_do_recovery(struct dlm_ctxt *dlm)
+{
+	int status = 0;
+
+	spin_lock(&dlm->spinlock);
+
+	/* check to see if the new master has died */
+	if (dlm->reco.new_master != O2NM_INVALID_NODE_NUM &&
+	    test_bit(dlm->reco.new_master, dlm->recovery_map)) {
+		mlog(0, "new master %u died while recovering %u!\n",
+		     dlm->reco.new_master, dlm->reco.dead_node);
+		/* unset the new_master, leave dead_node */
+		dlm->reco.new_master = O2NM_INVALID_NODE_NUM;
+	}
+
+	/* select a target to recover */
+	if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) {
+		int bit;
+
+		bit = find_next_bit (dlm->recovery_map, O2NM_MAX_NODES+1, 0);
+		if (bit >= O2NM_MAX_NODES || bit < 0)
+			dlm->reco.dead_node = O2NM_INVALID_NODE_NUM;
+		else
+			dlm->reco.dead_node = bit;
+	} else if (!test_bit(dlm->reco.dead_node, dlm->recovery_map)) {
+		/* BUG? */
+		mlog(ML_ERROR, "dead_node %u no longer in recovery map!\n",
+		     dlm->reco.dead_node);
+		dlm->reco.dead_node = O2NM_INVALID_NODE_NUM;
+	}
+
+	if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) {
+		// mlog(0, "nothing to recover!  sleeping now!\n");
+		spin_unlock(&dlm->spinlock);
+		/* return to main thread loop and sleep. */
+		return 0;
+	}
+	mlog(0, "recovery thread found node %u in the recovery map!\n",
+	     dlm->reco.dead_node);
+	spin_unlock(&dlm->spinlock);
+
+	/* take write barrier */
+	/* (stops the list reshuffling thread, proxy ast handling) */
+	dlm_begin_recovery(dlm);
+
+	if (dlm->reco.new_master == dlm->node_num)
+		goto master_here;
+
+	if (dlm->reco.new_master == O2NM_INVALID_NODE_NUM) {
+		/* choose a new master */
+		if (!dlm_pick_recovery_master(dlm)) {
+			/* already notified everyone.  go. */
+			dlm->reco.new_master = dlm->node_num;
+			goto master_here;
+		}
+		mlog(0, "another node will master this recovery session.\n");
+	}
+	mlog(0, "dlm=%s, new_master=%u, this node=%u, dead_node=%u\n",
+	     dlm->name, dlm->reco.new_master,
+	     dlm->node_num, dlm->reco.dead_node);
+
+	/* it is safe to start everything back up here
+	 * because all of the dead node's lock resources
+	 * have been marked as in-recovery */
+	dlm_end_recovery(dlm);
+
+	/* sleep out in main dlm_recovery_thread loop. */
+	return 0;
+
+master_here:
+	mlog(0, "mastering recovery of %s:%u here(this=%u)!\n",
+	     dlm->name, dlm->reco.dead_node, dlm->node_num);
+
+	status = dlm_remaster_locks(dlm, dlm->reco.dead_node);
+	if (status < 0) {
+		mlog(ML_ERROR, "error %d remastering locks for node %u, "
+		     "retrying.\n", status, dlm->reco.dead_node);
+	} else {
+		/* success!  see if any other nodes need recovery */
+		dlm_reset_recovery(dlm);
+	}
+	dlm_end_recovery(dlm);
+
+	/* continue and look for another dead node */
+	return -EAGAIN;
+}
+
+static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
+{
+	int status = 0;
+	struct dlm_reco_node_data *ndata;
+	struct list_head *iter;
+	int all_nodes_done;
+	int destroy = 0;
+	int pass = 0;
+
+	status = dlm_init_recovery_area(dlm, dead_node);
+	if (status < 0)
+		goto leave;
+
+	/* safe to access the node data list without a lock, since this
+	 * process is the only one to change the list */
+	list_for_each(iter, &dlm->reco.node_data) {
+		ndata = list_entry (iter, struct dlm_reco_node_data, list);
+		BUG_ON(ndata->state != DLM_RECO_NODE_DATA_INIT);
+		ndata->state = DLM_RECO_NODE_DATA_REQUESTING;
+
+		mlog(0, "requesting lock info from node %u\n",
+		     ndata->node_num);
+
+		if (ndata->node_num == dlm->node_num) {
+			ndata->state = DLM_RECO_NODE_DATA_DONE;
+			continue;
+		}
+
+		status = dlm_request_all_locks(dlm, ndata->node_num, dead_node);
+		if (status < 0) {
+			mlog_errno(status);
+			if (dlm_is_host_down(status))
+				ndata->state = DLM_RECO_NODE_DATA_DEAD;
+			else {
+				destroy = 1;
+				goto leave;
+			}
+		}
+
+		switch (ndata->state) {
+			case DLM_RECO_NODE_DATA_INIT:
+			case DLM_RECO_NODE_DATA_FINALIZE_SENT:
+			case DLM_RECO_NODE_DATA_REQUESTED:
+				BUG();
+				break;
+			case DLM_RECO_NODE_DATA_DEAD:
+				mlog(0, "node %u died after requesting "
+				     "recovery info for node %u\n",
+				     ndata->node_num, dead_node);
+				// start all over
+				destroy = 1;
+				status = -EAGAIN;
+				goto leave;
+			case DLM_RECO_NODE_DATA_REQUESTING:
+				ndata->state = DLM_RECO_NODE_DATA_REQUESTED;
+				mlog(0, "now receiving recovery data from "
+				     "node %u for dead node %u\n",
+				     ndata->node_num, dead_node);
+				break;
+			case DLM_RECO_NODE_DATA_RECEIVING:
+				mlog(0, "already receiving recovery data from "
+				     "node %u for dead node %u\n",
+				     ndata->node_num, dead_node);
+				break;
+			case DLM_RECO_NODE_DATA_DONE:
+				mlog(0, "already DONE receiving recovery data "
+				     "from node %u for dead node %u\n",
+				     ndata->node_num, dead_node);
+				break;
+		}
+	}
+
+	mlog(0, "done requesting all lock info\n");
+
+	/* nodes should be sending reco data now
+	 * just need to wait */
+
+	while (1) {
+		/* check all the nodes now to see if we are
+		 * done, or if anyone died */
+		all_nodes_done = 1;
+		spin_lock(&dlm_reco_state_lock);
+		list_for_each(iter, &dlm->reco.node_data) {
+			ndata = list_entry (iter, struct dlm_reco_node_data, list);
+
+			mlog(0, "checking recovery state of node %u\n",
+			     ndata->node_num);
+			switch (ndata->state) {
+				case DLM_RECO_NODE_DATA_INIT:
+				case DLM_RECO_NODE_DATA_REQUESTING:
+					mlog(ML_ERROR, "bad ndata state for "
+					     "node %u: state=%d\n",
+					     ndata->node_num, ndata->state);
+					BUG();
+					break;
+				case DLM_RECO_NODE_DATA_DEAD:
+					mlog(0, "node %u died after "
+					     "requesting recovery info for "
+					     "node %u\n", ndata->node_num,
+					     dead_node);
+					spin_unlock(&dlm_reco_state_lock);
+					// start all over
+					destroy = 1;
+					status = -EAGAIN;
+					goto leave;
+				case DLM_RECO_NODE_DATA_RECEIVING:
+				case DLM_RECO_NODE_DATA_REQUESTED:
+					all_nodes_done = 0;
+					break;
+				case DLM_RECO_NODE_DATA_DONE:
+					break;
+				case DLM_RECO_NODE_DATA_FINALIZE_SENT:
+					break;
+			}
+		}
+		spin_unlock(&dlm_reco_state_lock);
+
+		mlog(0, "pass #%d, all_nodes_done?: %s\n", ++pass,
+		     all_nodes_done?"yes":"no");
+		if (all_nodes_done) {
+			int ret;
+
+			/* all nodes are now in DLM_RECO_NODE_DATA_DONE state
+	 		 * just send a finalize message to everyone and
+	 		 * clean up */
+			mlog(0, "all nodes are done! send finalize\n");
+			ret = dlm_send_finalize_reco_message(dlm);
+			if (ret < 0)
+				mlog_errno(ret);
+
+			spin_lock(&dlm->spinlock);
+			dlm_finish_local_lockres_recovery(dlm, dead_node,
+							  dlm->node_num);
+			spin_unlock(&dlm->spinlock);
+			mlog(0, "should be done with recovery!\n");
+
+			mlog(0, "finishing recovery of %s at %lu, "
+			     "dead=%u, this=%u, new=%u\n", dlm->name,
+			     jiffies, dlm->reco.dead_node,
+			     dlm->node_num, dlm->reco.new_master);
+			destroy = 1;
+			status = ret;
+			/* rescan everything marked dirty along the way */
+			dlm_kick_thread(dlm, NULL);
+			break;
+		}
+		/* wait to be signalled, with periodic timeout
+		 * to check for node death */
+		wait_event_interruptible_timeout(dlm->dlm_reco_thread_wq,
+					 kthread_should_stop(),
+					 msecs_to_jiffies(DLM_RECO_THREAD_TIMEOUT_MS));
+
+	}
+
+leave:
+	if (destroy)
+		dlm_destroy_recovery_area(dlm, dead_node);
+
+	mlog_exit(status);
+	return status;
+}
+
+static int dlm_init_recovery_area(struct dlm_ctxt *dlm, u8 dead_node)
+{
+	int num=0;
+	struct dlm_reco_node_data *ndata;
+
+	spin_lock(&dlm->spinlock);
+	memcpy(dlm->reco.node_map, dlm->domain_map, sizeof(dlm->domain_map));
+	/* nodes can only be removed (by dying) after dropping
+	 * this lock, and death will be trapped later, so this should do */
+	spin_unlock(&dlm->spinlock);
+
+	while (1) {
+		num = find_next_bit (dlm->reco.node_map, O2NM_MAX_NODES, num);
+		if (num >= O2NM_MAX_NODES) {
+			break;
+		}
+		BUG_ON(num == dead_node);
+
+		ndata = kcalloc(1, sizeof(*ndata), GFP_KERNEL);
+		if (!ndata) {
+			dlm_destroy_recovery_area(dlm, dead_node);
+			return -ENOMEM;
+		}
+		ndata->node_num = num;
+		ndata->state = DLM_RECO_NODE_DATA_INIT;
+		spin_lock(&dlm_reco_state_lock);
+		list_add_tail(&ndata->list, &dlm->reco.node_data);
+		spin_unlock(&dlm_reco_state_lock);
+		num++;
+	}
+
+	return 0;
+}
+
+static void dlm_destroy_recovery_area(struct dlm_ctxt *dlm, u8 dead_node)
+{
+	struct list_head *iter, *iter2;
+	struct dlm_reco_node_data *ndata;
+	LIST_HEAD(tmplist);
+
+	spin_lock(&dlm_reco_state_lock);
+	list_splice_init(&dlm->reco.node_data, &tmplist);
+	spin_unlock(&dlm_reco_state_lock);
+
+	list_for_each_safe(iter, iter2, &tmplist) {
+		ndata = list_entry (iter, struct dlm_reco_node_data, list);
+		list_del_init(&ndata->list);
+		kfree(ndata);
+	}
+}
+
+static int dlm_request_all_locks(struct dlm_ctxt *dlm, u8 request_from,
+				 u8 dead_node)
+{
+	struct dlm_lock_request lr;
+	enum dlm_status ret;
+
+	mlog(0, "\n");
+
+
+	mlog(0, "dlm_request_all_locks: dead node is %u, sending request "
+		  "to %u\n", dead_node, request_from);
+
+	memset(&lr, 0, sizeof(lr));
+	lr.node_idx = dlm->node_num;
+	lr.dead_node = dead_node;
+
+	// send message
+	ret = DLM_NOLOCKMGR;
+	ret = o2net_send_message(DLM_LOCK_REQUEST_MSG, dlm->key,
+				 &lr, sizeof(lr), request_from, NULL);
+
+	/* negative status is handled by caller */
+	if (ret < 0)
+		mlog_errno(ret);
+
+	// return from here, then
+	// sleep until all received or error
+	return ret;
+
+}
+
+int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_lock_request *lr = (struct dlm_lock_request *)msg->buf;
+	char *buf = NULL;
+	struct dlm_work_item *item = NULL;
+
+	if (!dlm_grab(dlm))
+		return -EINVAL;
+
+	BUG_ON(lr->dead_node != dlm->reco.dead_node);
+
+	item = kcalloc(1, sizeof(*item), GFP_KERNEL);
+	if (!item) {
+		dlm_put(dlm);
+		return -ENOMEM;
+	}
+
+	/* this will get freed by dlm_request_all_locks_worker */
+	buf = (char *) __get_free_page(GFP_KERNEL);
+	if (!buf) {
+		kfree(item);
+		dlm_put(dlm);
+		return -ENOMEM;
+	}
+
+	/* queue up work for dlm_request_all_locks_worker */
+	dlm_grab(dlm);  /* get an extra ref for the work item */
+	dlm_init_work_item(dlm, item, dlm_request_all_locks_worker, buf);
+	item->u.ral.reco_master = lr->node_idx;
+	item->u.ral.dead_node = lr->dead_node;
+	spin_lock(&dlm->work_lock);
+	list_add_tail(&item->list, &dlm->work_list);
+	spin_unlock(&dlm->work_lock);
+	schedule_work(&dlm->dispatched_work);
+
+	dlm_put(dlm);
+	return 0;
+}
+
+static void dlm_request_all_locks_worker(struct dlm_work_item *item, void *data)
+{
+	struct dlm_migratable_lockres *mres;
+	struct dlm_lock_resource *res;
+	struct dlm_ctxt *dlm;
+	LIST_HEAD(resources);
+	struct list_head *iter;
+	int ret;
+	u8 dead_node, reco_master;
+
+	dlm = item->dlm;
+	dead_node = item->u.ral.dead_node;
+	reco_master = item->u.ral.reco_master;
+	BUG_ON(dead_node != dlm->reco.dead_node);
+	BUG_ON(reco_master != dlm->reco.new_master);
+
+	mres = (struct dlm_migratable_lockres *)data;
+
+	/* lock resources should have already been moved to the
+ 	 * dlm->reco.resources list.  now move items from that list
+ 	 * to a temp list if the dead owner matches.  note that the
+	 * whole cluster recovers only one node at a time, so we
+	 * can safely move UNKNOWN lock resources for each recovery
+	 * session. */
+	dlm_move_reco_locks_to_list(dlm, &resources, dead_node);
+
+	/* now we can begin blasting lockreses without the dlm lock */
+	list_for_each(iter, &resources) {
+		res = list_entry (iter, struct dlm_lock_resource, recovering);
+		ret = dlm_send_one_lockres(dlm, res, mres, reco_master,
+				   	DLM_MRES_RECOVERY);
+		if (ret < 0)
+			mlog_errno(ret);
+	}
+
+	/* move the resources back to the list */
+	spin_lock(&dlm->spinlock);
+	list_splice_init(&resources, &dlm->reco.resources);
+	spin_unlock(&dlm->spinlock);
+
+	ret = dlm_send_all_done_msg(dlm, dead_node, reco_master);
+	if (ret < 0)
+		mlog_errno(ret);
+
+	free_page((unsigned long)data);
+}
+
+
+static int dlm_send_all_done_msg(struct dlm_ctxt *dlm, u8 dead_node, u8 send_to)
+{
+	int ret, tmpret;
+	struct dlm_reco_data_done done_msg;
+
+	memset(&done_msg, 0, sizeof(done_msg));
+	done_msg.node_idx = dlm->node_num;
+	done_msg.dead_node = dead_node;
+	mlog(0, "sending DATA DONE message to %u, "
+	     "my node=%u, dead node=%u\n", send_to, done_msg.node_idx,
+	     done_msg.dead_node);
+
+	ret = o2net_send_message(DLM_RECO_DATA_DONE_MSG, dlm->key, &done_msg,
+				 sizeof(done_msg), send_to, &tmpret);
+	/* negative status is ignored by the caller */
+	if (ret >= 0)
+		ret = tmpret;
+	return ret;
+}
+
+
+int dlm_reco_data_done_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_reco_data_done *done = (struct dlm_reco_data_done *)msg->buf;
+	struct list_head *iter;
+	struct dlm_reco_node_data *ndata = NULL;
+	int ret = -EINVAL;
+
+	if (!dlm_grab(dlm))
+		return -EINVAL;
+
+	mlog(0, "got DATA DONE: dead_node=%u, reco.dead_node=%u, "
+	     "node_idx=%u, this node=%u\n", done->dead_node,
+	     dlm->reco.dead_node, done->node_idx, dlm->node_num);
+	BUG_ON(done->dead_node != dlm->reco.dead_node);
+
+	spin_lock(&dlm_reco_state_lock);
+	list_for_each(iter, &dlm->reco.node_data) {
+		ndata = list_entry (iter, struct dlm_reco_node_data, list);
+		if (ndata->node_num != done->node_idx)
+			continue;
+
+		switch (ndata->state) {
+			case DLM_RECO_NODE_DATA_INIT:
+			case DLM_RECO_NODE_DATA_DEAD:
+			case DLM_RECO_NODE_DATA_DONE:
+			case DLM_RECO_NODE_DATA_FINALIZE_SENT:
+				mlog(ML_ERROR, "bad ndata state for node %u:"
+				     " state=%d\n", ndata->node_num,
+				     ndata->state);
+				BUG();
+				break;
+			case DLM_RECO_NODE_DATA_RECEIVING:
+			case DLM_RECO_NODE_DATA_REQUESTED:
+			case DLM_RECO_NODE_DATA_REQUESTING:
+				mlog(0, "node %u is DONE sending "
+					  "recovery data!\n",
+					  ndata->node_num);
+
+				ndata->state = DLM_RECO_NODE_DATA_DONE;
+				ret = 0;
+				break;
+		}
+	}
+	spin_unlock(&dlm_reco_state_lock);
+
+	/* wake the recovery thread, some node is done */
+	if (!ret)
+		dlm_kick_recovery_thread(dlm);
+
+	if (ret < 0)
+		mlog(ML_ERROR, "failed to find recovery node data for node "
+		     "%u\n", done->node_idx);
+	dlm_put(dlm);
+
+	mlog(0, "leaving reco data done handler, ret=%d\n", ret);
+	return ret;
+}
+
+static void dlm_move_reco_locks_to_list(struct dlm_ctxt *dlm,
+					struct list_head *list,
+				       	u8 dead_node)
+{
+	struct dlm_lock_resource *res;
+	struct list_head *iter, *iter2;
+
+	spin_lock(&dlm->spinlock);
+	list_for_each_safe(iter, iter2, &dlm->reco.resources) {
+		res = list_entry (iter, struct dlm_lock_resource, recovering);
+		if (dlm_is_recovery_lock(res->lockname.name,
+					 res->lockname.len))
+			continue;
+		if (res->owner == dead_node) {
+			mlog(0, "found lockres owned by dead node while "
+				  "doing recovery for node %u. sending it.\n",
+				  dead_node);
+			list_del_init(&res->recovering);
+			list_add_tail(&res->recovering, list);
+		} else if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) {
+			mlog(0, "found UNKNOWN owner while doing recovery "
+				  "for node %u. sending it.\n", dead_node);
+			list_del_init(&res->recovering);
+			list_add_tail(&res->recovering, list);
+		}
+	}
+	spin_unlock(&dlm->spinlock);
+}
+
+static inline int dlm_num_locks_in_lockres(struct dlm_lock_resource *res)
+{
+	int total_locks = 0;
+	struct list_head *iter, *queue = &res->granted;
+	int i;
+
+	for (i=0; i<3; i++) {
+		list_for_each(iter, queue)
+			total_locks++;
+		queue++;
+	}
+	return total_locks;
+}
+
+
+static int dlm_send_mig_lockres_msg(struct dlm_ctxt *dlm,
+				      struct dlm_migratable_lockres *mres,
+				      u8 send_to,
+				      struct dlm_lock_resource *res,
+				      int total_locks)
+{
+	u64 mig_cookie = be64_to_cpu(mres->mig_cookie);
+	int mres_total_locks = be32_to_cpu(mres->total_locks);
+	int sz, ret = 0, status = 0;
+	u8 orig_flags = mres->flags,
+	   orig_master = mres->master;
+
+	BUG_ON(mres->num_locks > DLM_MAX_MIGRATABLE_LOCKS);
+	if (!mres->num_locks)
+		return 0;
+
+	sz = sizeof(struct dlm_migratable_lockres) +
+		(mres->num_locks * sizeof(struct dlm_migratable_lock));
+
+	/* add an all-done flag if we reached the last lock */
+	orig_flags = mres->flags;
+	BUG_ON(total_locks > mres_total_locks);
+	if (total_locks == mres_total_locks)
+		mres->flags |= DLM_MRES_ALL_DONE;
+
+	/* send it */
+	ret = o2net_send_message(DLM_MIG_LOCKRES_MSG, dlm->key, mres,
+				 sz, send_to, &status);
+	if (ret < 0) {
+		/* XXX: negative status is not handled.
+		 * this will end up killing this node. */
+		mlog_errno(ret);
+	} else {
+		/* might get an -ENOMEM back here */
+		ret = status;
+		if (ret < 0) {
+			mlog_errno(ret);
+
+			if (ret == -EFAULT) {
+				mlog(ML_ERROR, "node %u told me to kill "
+				     "myself!\n", send_to);
+				BUG();
+			}
+		}
+	}
+
+	/* zero and reinit the message buffer */
+	dlm_init_migratable_lockres(mres, res->lockname.name,
+				    res->lockname.len, mres_total_locks,
+				    mig_cookie, orig_flags, orig_master);
+	return ret;
+}
+
+static void dlm_init_migratable_lockres(struct dlm_migratable_lockres *mres,
+					const char *lockname, int namelen,
+					int total_locks, u64 cookie,
+					u8 flags, u8 master)
+{
+	/* mres here is one full page */
+	memset(mres, 0, PAGE_SIZE);
+	mres->lockname_len = namelen;
+	memcpy(mres->lockname, lockname, namelen);
+	mres->num_locks = 0;
+	mres->total_locks = cpu_to_be32(total_locks);
+	mres->mig_cookie = cpu_to_be64(cookie);
+	mres->flags = flags;
+	mres->master = master;
+}
+
+
+/* returns 1 if this lock fills the network structure,
+ * 0 otherwise */
+static int dlm_add_lock_to_array(struct dlm_lock *lock,
+				 struct dlm_migratable_lockres *mres, int queue)
+{
+	struct dlm_migratable_lock *ml;
+	int lock_num = mres->num_locks;
+
+	ml = &(mres->ml[lock_num]);
+	ml->cookie = lock->ml.cookie;
+	ml->type = lock->ml.type;
+	ml->convert_type = lock->ml.convert_type;
+	ml->highest_blocked = lock->ml.highest_blocked;
+	ml->list = queue;
+	if (lock->lksb) {
+		ml->flags = lock->lksb->flags;
+		/* send our current lvb */
+		if (ml->type == LKM_EXMODE ||
+		    ml->type == LKM_PRMODE) {
+			/* if it is already set, this had better be a PR
+			 * and it has to match */
+			if (mres->lvb[0] && (ml->type == LKM_EXMODE ||
+			    memcmp(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN))) {
+				mlog(ML_ERROR, "mismatched lvbs!\n");
+				__dlm_print_one_lock_resource(lock->lockres);
+				BUG();
+			}
+			memcpy(mres->lvb, lock->lksb->lvb, DLM_LVB_LEN);
+		}
+	}
+	ml->node = lock->ml.node;
+	mres->num_locks++;
+	/* we reached the max, send this network message */
+	if (mres->num_locks == DLM_MAX_MIGRATABLE_LOCKS)
+		return 1;
+	return 0;
+}
+
+
+int dlm_send_one_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
+			 struct dlm_migratable_lockres *mres,
+			 u8 send_to, u8 flags)
+{
+	struct list_head *queue, *iter;
+	int total_locks, i;
+	u64 mig_cookie = 0;
+	struct dlm_lock *lock;
+	int ret = 0;
+
+	BUG_ON(!(flags & (DLM_MRES_RECOVERY|DLM_MRES_MIGRATION)));
+
+	mlog(0, "sending to %u\n", send_to);
+
+	total_locks = dlm_num_locks_in_lockres(res);
+	if (total_locks > DLM_MAX_MIGRATABLE_LOCKS) {
+		/* rare, but possible */
+		mlog(0, "argh.  lockres has %d locks.  this will "
+			  "require more than one network packet to "
+			  "migrate\n", total_locks);
+		mig_cookie = dlm_get_next_mig_cookie();
+	}
+
+	dlm_init_migratable_lockres(mres, res->lockname.name,
+				    res->lockname.len, total_locks,
+				    mig_cookie, flags, res->owner);
+
+	total_locks = 0;
+	for (i=DLM_GRANTED_LIST; i<=DLM_BLOCKED_LIST; i++) {
+		queue = dlm_list_idx_to_ptr(res, i);
+		list_for_each(iter, queue) {
+			lock = list_entry (iter, struct dlm_lock, list);
+
+			/* add another lock. */
+			total_locks++;
+			if (!dlm_add_lock_to_array(lock, mres, i))
+				continue;
+
+			/* this filled the lock message,
+			 * we must send it immediately. */
+			ret = dlm_send_mig_lockres_msg(dlm, mres, send_to,
+						       res, total_locks);
+			if (ret < 0) {
+				// TODO
+				mlog(ML_ERROR, "dlm_send_mig_lockres_msg "
+				     "returned %d, TODO\n", ret);
+				BUG();
+			}
+		}
+	}
+	/* flush any remaining locks */
+	ret = dlm_send_mig_lockres_msg(dlm, mres, send_to, res, total_locks);
+	if (ret < 0) {
+		// TODO
+		mlog(ML_ERROR, "dlm_send_mig_lockres_msg returned %d, "
+		     "TODO\n", ret);
+		BUG();
+	}
+	return ret;
+}
+
+
+
+/*
+ * this message will contain no more than one page worth of
+ * recovery data, and it will work on only one lockres.
+ * there may be many locks in this page, and we may need to wait
+ * for additional packets to complete all the locks (rare, but
+ * possible).
+ */
+/*
+ * NOTE: the allocation error cases here are scary
+ * we really cannot afford to fail an alloc in recovery
+ * do we spin?  returning an error only delays the problem really
+ */
+
+int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_migratable_lockres *mres =
+		(struct dlm_migratable_lockres *)msg->buf;
+	int ret = 0;
+	u8 real_master;
+	char *buf = NULL;
+	struct dlm_work_item *item = NULL;
+	struct dlm_lock_resource *res = NULL;
+
+	if (!dlm_grab(dlm))
+		return -EINVAL;
+
+	BUG_ON(!(mres->flags & (DLM_MRES_RECOVERY|DLM_MRES_MIGRATION)));
+
+	real_master = mres->master;
+	if (real_master == DLM_LOCK_RES_OWNER_UNKNOWN) {
+		/* cannot migrate a lockres with no master */
+		BUG_ON(!(mres->flags & DLM_MRES_RECOVERY));
+	}
+
+	mlog(0, "%s message received from node %u\n",
+		  (mres->flags & DLM_MRES_RECOVERY) ?
+		  "recovery" : "migration", mres->master);
+	if (mres->flags & DLM_MRES_ALL_DONE)
+		mlog(0, "all done flag.  all lockres data received!\n");
+
+	ret = -ENOMEM;
+	buf = kmalloc(be16_to_cpu(msg->data_len), GFP_KERNEL);
+	item = kcalloc(1, sizeof(*item), GFP_KERNEL);
+	if (!buf || !item)
+		goto leave;
+
+	/* lookup the lock to see if we have a secondary queue for this
+	 * already...  just add the locks in and this will have its owner
+	 * and RECOVERY flag changed when it completes. */
+	res = dlm_lookup_lockres(dlm, mres->lockname, mres->lockname_len);
+	if (res) {
+	 	/* this will get a ref on res */
+		/* mark it as recovering/migrating and hash it */
+		spin_lock(&res->spinlock);
+		if (mres->flags & DLM_MRES_RECOVERY) {
+			res->state |= DLM_LOCK_RES_RECOVERING;
+		} else {
+			if (res->state & DLM_LOCK_RES_MIGRATING) {
+				/* this is at least the second
+				 * lockres message */
+				mlog(0, "lock %.*s is already migrating\n",
+					  mres->lockname_len,
+					  mres->lockname);
+			} else if (res->state & DLM_LOCK_RES_RECOVERING) {
+				/* caller should BUG */
+				mlog(ML_ERROR, "node is attempting to migrate "
+				     "lock %.*s, but marked as recovering!\n",
+				     mres->lockname_len, mres->lockname);
+				ret = -EFAULT;
+				spin_unlock(&res->spinlock);
+				goto leave;
+			}
+			res->state |= DLM_LOCK_RES_MIGRATING;
+		}
+		spin_unlock(&res->spinlock);
+	} else {
+		/* need to allocate, just like if it was
+		 * mastered here normally  */
+		res = dlm_new_lockres(dlm, mres->lockname, mres->lockname_len);
+		if (!res)
+			goto leave;
+
+		/* to match the ref that we would have gotten if
+		 * dlm_lookup_lockres had succeeded */
+		dlm_lockres_get(res);
+
+		/* mark it as recovering/migrating and hash it */
+		if (mres->flags & DLM_MRES_RECOVERY)
+			res->state |= DLM_LOCK_RES_RECOVERING;
+		else
+			res->state |= DLM_LOCK_RES_MIGRATING;
+
+		spin_lock(&dlm->spinlock);
+		__dlm_insert_lockres(dlm, res);
+		spin_unlock(&dlm->spinlock);
+
+		/* now that the new lockres is inserted,
+		 * make it usable by other processes */
+		spin_lock(&res->spinlock);
+		res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
+		spin_unlock(&res->spinlock);
+
+		/* add an extra ref for just-allocated lockres 
+		 * otherwise the lockres will be purged immediately */
+		dlm_lockres_get(res);
+
+	}
+
+	/* at this point we have allocated everything we need,
+	 * and we have a hashed lockres with an extra ref and
+	 * the proper res->state flags. */
+	ret = 0;
+	if (mres->master == DLM_LOCK_RES_OWNER_UNKNOWN) {
+		/* migration cannot have an unknown master */
+		BUG_ON(!(mres->flags & DLM_MRES_RECOVERY));
+		mlog(0, "recovery has passed me a lockres with an "
+			  "unknown owner.. will need to requery: "
+			  "%.*s\n", mres->lockname_len, mres->lockname);
+	} else {
+		spin_lock(&res->spinlock);
+		dlm_change_lockres_owner(dlm, res, dlm->node_num);
+		spin_unlock(&res->spinlock);
+	}
+
+	/* queue up work for dlm_mig_lockres_worker */
+	dlm_grab(dlm);  /* get an extra ref for the work item */
+	memcpy(buf, msg->buf, be16_to_cpu(msg->data_len));  /* copy the whole message */
+	dlm_init_work_item(dlm, item, dlm_mig_lockres_worker, buf);
+	item->u.ml.lockres = res; /* already have a ref */
+	item->u.ml.real_master = real_master;
+	spin_lock(&dlm->work_lock);
+	list_add_tail(&item->list, &dlm->work_list);
+	spin_unlock(&dlm->work_lock);
+	schedule_work(&dlm->dispatched_work);
+
+leave:
+	dlm_put(dlm);
+	if (ret < 0) {
+		if (buf)
+			kfree(buf);
+		if (item)
+			kfree(item);
+	}
+
+	mlog_exit(ret);
+	return ret;
+}
+
+
+static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_migratable_lockres *mres;
+	int ret = 0;
+	struct dlm_lock_resource *res;
+	u8 real_master;
+
+	dlm = item->dlm;
+	mres = (struct dlm_migratable_lockres *)data;
+
+	res = item->u.ml.lockres;
+	real_master = item->u.ml.real_master;
+
+	if (real_master == DLM_LOCK_RES_OWNER_UNKNOWN) {
+		/* this case is super-rare. only occurs if
+		 * node death happens during migration. */
+again:
+		ret = dlm_lockres_master_requery(dlm, res, &real_master);
+		if (ret < 0) {
+			mlog(0, "dlm_lockres_master_requery failure: %d\n",
+				  ret);
+			goto again;
+		}
+		if (real_master == DLM_LOCK_RES_OWNER_UNKNOWN) {
+			mlog(0, "lockres %.*s not claimed.  "
+				   "this node will take it.\n",
+				   res->lockname.len, res->lockname.name);
+		} else {
+			mlog(0, "master needs to respond to sender "
+				  "that node %u still owns %.*s\n",
+				  real_master, res->lockname.len,
+				  res->lockname.name);
+			/* cannot touch this lockres */
+			goto leave;
+		}
+	}
+
+	ret = dlm_process_recovery_data(dlm, res, mres);
+	if (ret < 0)
+		mlog(0, "dlm_process_recovery_data returned  %d\n", ret);
+	else
+		mlog(0, "dlm_process_recovery_data succeeded\n");
+
+	if ((mres->flags & (DLM_MRES_MIGRATION|DLM_MRES_ALL_DONE)) ==
+	                   (DLM_MRES_MIGRATION|DLM_MRES_ALL_DONE)) {
+		ret = dlm_finish_migration(dlm, res, mres->master);
+		if (ret < 0)
+			mlog_errno(ret);
+	}
+
+leave:
+	kfree(data);
+	mlog_exit(ret);
+}
+
+
+
+static int dlm_lockres_master_requery(struct dlm_ctxt *dlm,
+				      struct dlm_lock_resource *res,
+				      u8 *real_master)
+{
+	struct dlm_node_iter iter;
+	int nodenum;
+	int ret = 0;
+
+	*real_master = DLM_LOCK_RES_OWNER_UNKNOWN;
+
+	/* we only reach here if one of the two nodes in a
+	 * migration died while the migration was in progress.
+	 * at this point we need to requery the master.  we
+	 * know that the new_master got as far as creating
+	 * an mle on at least one node, but we do not know
+	 * if any nodes had actually cleared the mle and set
+	 * the master to the new_master.  the old master
+	 * is supposed to set the owner to UNKNOWN in the
+	 * event of a new_master death, so the only possible
+	 * responses that we can get from nodes here are
+	 * that the master is new_master, or that the master
+	 * is UNKNOWN.
+	 * if all nodes come back with UNKNOWN then we know
+	 * the lock needs remastering here.
+	 * if any node comes back with a valid master, check
+	 * to see if that master is the one that we are
+	 * recovering.  if so, then the new_master died and
+	 * we need to remaster this lock.  if not, then the
+	 * new_master survived and that node will respond to
+	 * other nodes about the owner.
+	 * if there is an owner, this node needs to dump this
+	 * lockres and alert the sender that this lockres
+	 * was rejected. */
+	spin_lock(&dlm->spinlock);
+	dlm_node_iter_init(dlm->domain_map, &iter);
+	spin_unlock(&dlm->spinlock);
+
+	while ((nodenum = dlm_node_iter_next(&iter)) >= 0) {
+		/* do not send to self */
+		if (nodenum == dlm->node_num)
+			continue;
+		ret = dlm_do_master_requery(dlm, res, nodenum, real_master);
+		if (ret < 0) {
+			mlog_errno(ret);
+			BUG();
+			/* TODO: need to figure a way to restart this */
+		}
+		if (*real_master != DLM_LOCK_RES_OWNER_UNKNOWN) {
+			mlog(0, "lock master is %u\n", *real_master);
+			break;
+		}
+	}
+	return ret;
+}
+
+
+static int dlm_do_master_requery(struct dlm_ctxt *dlm,
+				 struct dlm_lock_resource *res,
+				 u8 nodenum, u8 *real_master)
+{
+	int ret = -EINVAL;
+	struct dlm_master_requery req;
+	int status = DLM_LOCK_RES_OWNER_UNKNOWN;
+
+	memset(&req, 0, sizeof(req));
+	req.node_idx = dlm->node_num;
+	req.namelen = res->lockname.len;
+	memcpy(req.name, res->lockname.name, res->lockname.len);
+
+	ret = o2net_send_message(DLM_MASTER_REQUERY_MSG, dlm->key,
+				 &req, sizeof(req), nodenum, &status);
+	/* XXX: negative status not handled properly here. */
+	if (ret < 0)
+		mlog_errno(ret);
+	else {
+		BUG_ON(status < 0);
+		BUG_ON(status > DLM_LOCK_RES_OWNER_UNKNOWN);
+		*real_master = (u8) (status & 0xff);
+		mlog(0, "node %u responded to master requery with %u\n",
+			  nodenum, *real_master);
+		ret = 0;
+	}
+	return ret;
+}
+
+
+/* this function cannot error, so unless the sending
+ * or receiving of the message failed, the owner can
+ * be trusted */
+int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_master_requery *req = (struct dlm_master_requery *)msg->buf;
+	struct dlm_lock_resource *res = NULL;
+	int master = DLM_LOCK_RES_OWNER_UNKNOWN;
+	u32 flags = DLM_ASSERT_MASTER_REQUERY;
+
+	if (!dlm_grab(dlm)) {
+		/* since the domain has gone away on this
+		 * node, the proper response is UNKNOWN */
+		return master;
+	}
+
+	spin_lock(&dlm->spinlock);
+	res = __dlm_lookup_lockres(dlm, req->name, req->namelen);
+	if (res) {
+		spin_lock(&res->spinlock);
+		master = res->owner;
+		if (master == dlm->node_num) {
+			int ret = dlm_dispatch_assert_master(dlm, res,
+							     0, 0, flags);
+			if (ret < 0) {
+				mlog_errno(-ENOMEM);
+				/* retry!? */
+				BUG();
+			}
+		}
+		spin_unlock(&res->spinlock);
+	}
+	spin_unlock(&dlm->spinlock);
+
+	dlm_put(dlm);
+	return master;
+}
+
+static inline struct list_head *
+dlm_list_num_to_pointer(struct dlm_lock_resource *res, int list_num)
+{
+	struct list_head *ret;
+	BUG_ON(list_num < 0);
+	BUG_ON(list_num > 2);
+	ret = &(res->granted);
+	ret += list_num;
+	return ret;
+}
+/* TODO: do ast flush business
+ * TODO: do MIGRATING and RECOVERING spinning
+ */
+
+/*
+* NOTE about in-flight requests during migration:
+*
+* Before attempting the migrate, the master has marked the lockres as
+* MIGRATING and then flushed all of its pending ASTS.  So any in-flight
+* requests either got queued before the MIGRATING flag got set, in which
+* case the lock data will reflect the change and a return message is on
+* the way, or the request failed to get in before MIGRATING got set.  In
+* this case, the caller will be told to spin and wait for the MIGRATING
+* flag to be dropped, then recheck the master.
+* This holds true for the convert, cancel and unlock cases, and since lvb
+* updates are tied to these same messages, it applies to lvb updates as
+* well.  For the lock case, there is no way a lock can be on the master
+* queue and not be on the secondary queue since the lock is always added
+* locally first.  This means that the new target node will never be sent
+* a lock that he doesn't already have on the list.
+* In total, this means that the local lock is correct and should not be
+* updated to match the one sent by the master.  Any messages sent back
+* from the master before the MIGRATING flag will bring the lock properly
+* up-to-date, and the change will be ordered properly for the waiter.
+* We will *not* attempt to modify the lock underneath the waiter.
+*/
+
+static int dlm_process_recovery_data(struct dlm_ctxt *dlm,
+				     struct dlm_lock_resource *res,
+				     struct dlm_migratable_lockres *mres)
+{
+	struct dlm_migratable_lock *ml;
+	struct list_head *queue;
+	struct dlm_lock *newlock = NULL;
+	struct dlm_lockstatus *lksb = NULL;
+	int ret = 0;
+	int i;
+	struct list_head *iter;
+	struct dlm_lock *lock = NULL;
+
+	mlog(0, "running %d locks for this lockres\n", mres->num_locks);
+	for (i=0; i<mres->num_locks; i++) {
+		ml = &(mres->ml[i]);
+		BUG_ON(ml->highest_blocked != LKM_IVMODE);
+		newlock = NULL;
+		lksb = NULL;
+
+		queue = dlm_list_num_to_pointer(res, ml->list);
+
+		/* if the lock is for the local node it needs to
+		 * be moved to the proper location within the queue.
+		 * do not allocate a new lock structure. */
+		if (ml->node == dlm->node_num) {
+			/* MIGRATION ONLY! */
+			BUG_ON(!(mres->flags & DLM_MRES_MIGRATION));
+
+			spin_lock(&res->spinlock);
+			list_for_each(iter, queue) {
+				lock = list_entry (iter, struct dlm_lock, list);
+				if (lock->ml.cookie != ml->cookie)
+					lock = NULL;
+				else
+					break;
+			}
+
+			/* lock is always created locally first, and
+			 * destroyed locally last.  it must be on the list */
+			if (!lock) {
+				mlog(ML_ERROR, "could not find local lock "
+					       "with cookie %"MLFu64"!\n",
+				     ml->cookie);
+				BUG();
+			}
+			BUG_ON(lock->ml.node != ml->node);
+
+			/* see NOTE above about why we do not update
+			 * to match the master here */
+
+			/* move the lock to its proper place */
+			/* do not alter lock refcount.  switching lists. */
+			list_del_init(&lock->list);
+			list_add_tail(&lock->list, queue);
+			spin_unlock(&res->spinlock);
+
+			mlog(0, "just reordered a local lock!\n");
+			continue;
+		}
+
+		/* lock is for another node. */
+		newlock = dlm_new_lock(ml->type, ml->node,
+				       be64_to_cpu(ml->cookie), NULL);
+		if (!newlock) {
+			ret = -ENOMEM;
+			goto leave;
+		}
+		lksb = newlock->lksb;
+		dlm_lock_attach_lockres(newlock, res);
+
+		if (ml->convert_type != LKM_IVMODE) {
+			BUG_ON(queue != &res->converting);
+			newlock->ml.convert_type = ml->convert_type;
+		}
+		lksb->flags |= (ml->flags &
+				(DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB));
+			
+		if (mres->lvb[0]) {
+			if (lksb->flags & DLM_LKSB_PUT_LVB) {
+				/* other node was trying to update
+				 * lvb when node died.  recreate the
+				 * lksb with the updated lvb. */
+				memcpy(lksb->lvb, mres->lvb, DLM_LVB_LEN);
+			} else {
+				/* otherwise, the node is sending its 
+				 * most recent valid lvb info */
+				BUG_ON(ml->type != LKM_EXMODE &&
+				       ml->type != LKM_PRMODE);
+				if (res->lvb[0] && (ml->type == LKM_EXMODE ||
+				    memcmp(res->lvb, mres->lvb, DLM_LVB_LEN))) {
+					mlog(ML_ERROR, "received bad lvb!\n");
+					__dlm_print_one_lock_resource(res);
+					BUG();
+				}
+				memcpy(res->lvb, mres->lvb, DLM_LVB_LEN);
+			}
+		}
+
+
+		/* NOTE:
+		 * wrt lock queue ordering and recovery:
+		 *    1. order of locks on granted queue is
+		 *       meaningless.
+		 *    2. order of locks on converting queue is
+		 *       LOST with the node death.  sorry charlie.
+		 *    3. order of locks on the blocked queue is
+		 *       also LOST.
+		 * order of locks does not affect integrity, it
+		 * just means that a lock request may get pushed
+		 * back in line as a result of the node death.
+		 * also note that for a given node the lock order
+		 * for its secondary queue locks is preserved
+		 * relative to each other, but clearly *not*
+		 * preserved relative to locks from other nodes.
+		 */
+		spin_lock(&res->spinlock);
+		dlm_lock_get(newlock);
+		list_add_tail(&newlock->list, queue);
+		spin_unlock(&res->spinlock);
+	}
+	mlog(0, "done running all the locks\n");
+
+leave:
+	if (ret < 0) {
+		mlog_errno(ret);
+		if (newlock)
+			dlm_lock_put(newlock);
+	}
+
+	mlog_exit(ret);
+	return ret;
+}
+
+void dlm_move_lockres_to_recovery_list(struct dlm_ctxt *dlm,
+				       struct dlm_lock_resource *res)
+{
+	int i;
+	struct list_head *queue, *iter, *iter2;
+	struct dlm_lock *lock;
+
+	res->state |= DLM_LOCK_RES_RECOVERING;
+	if (!list_empty(&res->recovering))
+		list_del_init(&res->recovering);
+	list_add_tail(&res->recovering, &dlm->reco.resources);
+
+	/* find any pending locks and put them back on proper list */
+	for (i=DLM_BLOCKED_LIST; i>=DLM_GRANTED_LIST; i--) {
+		queue = dlm_list_idx_to_ptr(res, i);
+		list_for_each_safe(iter, iter2, queue) {
+			lock = list_entry (iter, struct dlm_lock, list);
+			dlm_lock_get(lock);
+			if (lock->convert_pending) {
+				/* move converting lock back to granted */
+				BUG_ON(i != DLM_CONVERTING_LIST);
+				mlog(0, "node died with convert pending "
+				     "on %.*s. move back to granted list.\n",
+				     res->lockname.len, res->lockname.name);
+				dlm_revert_pending_convert(res, lock);
+				lock->convert_pending = 0;
+			} else if (lock->lock_pending) {
+				/* remove pending lock requests completely */
+				BUG_ON(i != DLM_BLOCKED_LIST);
+				mlog(0, "node died with lock pending "
+				     "on %.*s. remove from blocked list and skip.\n",
+				     res->lockname.len, res->lockname.name);
+				/* lock will be floating until ref in
+				 * dlmlock_remote is freed after the network
+				 * call returns.  ok for it to not be on any
+				 * list since no ast can be called
+				 * (the master is dead). */
+				dlm_revert_pending_lock(res, lock);
+				lock->lock_pending = 0;
+			} else if (lock->unlock_pending) {
+				/* if an unlock was in progress, treat as
+				 * if this had completed successfully
+				 * before sending this lock state to the
+				 * new master.  note that the dlm_unlock
+				 * call is still responsible for calling
+				 * the unlockast.  that will happen after
+				 * the network call times out.  for now,
+				 * just move lists to prepare the new
+				 * recovery master.  */
+				BUG_ON(i != DLM_GRANTED_LIST);
+				mlog(0, "node died with unlock pending "
+				     "on %.*s. remove from blocked list and skip.\n",
+				     res->lockname.len, res->lockname.name);
+				dlm_commit_pending_unlock(res, lock);
+				lock->unlock_pending = 0;
+			} else if (lock->cancel_pending) {
+				/* if a cancel was in progress, treat as
+				 * if this had completed successfully
+				 * before sending this lock state to the
+				 * new master */
+				BUG_ON(i != DLM_CONVERTING_LIST);
+				mlog(0, "node died with cancel pending "
+				     "on %.*s. move back to granted list.\n",
+				     res->lockname.len, res->lockname.name);
+				dlm_commit_pending_cancel(res, lock);
+				lock->cancel_pending = 0;
+			}
+			dlm_lock_put(lock);
+		}
+	}
+}
+
+
+
+/* removes all recovered locks from the recovery list.
+ * sets the res->owner to the new master.
+ * unsets the RECOVERY flag and wakes waiters. */
+static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
+					      u8 dead_node, u8 new_master)
+{
+	int i;
+	struct list_head *iter, *iter2, *bucket;
+	struct dlm_lock_resource *res;
+
+	mlog_entry_void();
+
+	assert_spin_locked(&dlm->spinlock);
+
+	list_for_each_safe(iter, iter2, &dlm->reco.resources) {
+		res = list_entry (iter, struct dlm_lock_resource, recovering);
+		if (res->owner == dead_node) {
+			list_del_init(&res->recovering);
+			spin_lock(&res->spinlock);
+			dlm_change_lockres_owner(dlm, res, new_master);
+			res->state &= ~DLM_LOCK_RES_RECOVERING;
+			__dlm_dirty_lockres(dlm, res);
+			spin_unlock(&res->spinlock);
+			wake_up(&res->wq);
+		}
+	}
+
+	/* this will become unnecessary eventually, but
+	 * for now we need to run the whole hash, clear
+	 * the RECOVERING state and set the owner
+	 * if necessary */
+	for (i=0; i<DLM_HASH_SIZE; i++) {
+		bucket = &(dlm->resources[i]);
+		list_for_each(iter, bucket) {
+			res = list_entry (iter, struct dlm_lock_resource, list);
+			if (res->state & DLM_LOCK_RES_RECOVERING) {
+				if (res->owner == dead_node) {
+					mlog(0, "(this=%u) res %.*s owner=%u "
+					     "was not on recovering list, but "
+					     "clearing state anyway\n",
+					     dlm->node_num, res->lockname.len,
+					     res->lockname.name, new_master);
+				} else if (res->owner == dlm->node_num) {
+					mlog(0, "(this=%u) res %.*s owner=%u "
+					     "was not on recovering list, "
+					     "owner is THIS node, clearing\n",
+					     dlm->node_num, res->lockname.len,
+					     res->lockname.name, new_master);
+				} else
+					continue;
+
+				spin_lock(&res->spinlock);
+				dlm_change_lockres_owner(dlm, res, new_master);
+				res->state &= ~DLM_LOCK_RES_RECOVERING;
+				__dlm_dirty_lockres(dlm, res);
+				spin_unlock(&res->spinlock);
+				wake_up(&res->wq);
+			}
+		}
+	}
+}
+
+static inline int dlm_lvb_needs_invalidation(struct dlm_lock *lock, int local)
+{
+	if (local) {
+		if (lock->ml.type != LKM_EXMODE &&
+		    lock->ml.type != LKM_PRMODE)
+			return 1;
+	} else if (lock->ml.type == LKM_EXMODE)
+		return 1;
+	return 0;
+}
+
+static void dlm_revalidate_lvb(struct dlm_ctxt *dlm,
+			       struct dlm_lock_resource *res, u8 dead_node)
+{
+	struct list_head *iter, *queue;
+	struct dlm_lock *lock;
+	int blank_lvb = 0, local = 0;
+	int i;
+	u8 search_node;
+
+	assert_spin_locked(&dlm->spinlock);
+	assert_spin_locked(&res->spinlock);
+
+	if (res->owner == dlm->node_num)
+		/* if this node owned the lockres, and if the dead node 
+		 * had an EX when he died, blank out the lvb */
+		search_node = dead_node;
+	else {
+		/* if this is a secondary lockres, and we had no EX or PR
+		 * locks granted, we can no longer trust the lvb */
+		search_node = dlm->node_num;
+		local = 1;  /* check local state for valid lvb */
+	}
+
+	for (i=DLM_GRANTED_LIST; i<=DLM_CONVERTING_LIST; i++) {
+		queue = dlm_list_idx_to_ptr(res, i);
+		list_for_each(iter, queue) {
+			lock = list_entry (iter, struct dlm_lock, list);
+			if (lock->ml.node == search_node) {
+				if (dlm_lvb_needs_invalidation(lock, local)) {
+					/* zero the lksb lvb and lockres lvb */
+					blank_lvb = 1;
+					memset(lock->lksb->lvb, 0, DLM_LVB_LEN);
+				}
+			}
+		}
+	}
+
+	if (blank_lvb) {
+		mlog(0, "clearing %.*s lvb, dead node %u had EX\n",
+		     res->lockname.len, res->lockname.name, dead_node);
+		memset(res->lvb, 0, DLM_LVB_LEN);
+	}
+}
+
+static void dlm_free_dead_locks(struct dlm_ctxt *dlm,
+				struct dlm_lock_resource *res, u8 dead_node)
+{
+	struct list_head *iter, *tmpiter;
+	struct dlm_lock *lock;
+
+	/* this node is the lockres master:
+	 * 1) remove any stale locks for the dead node
+	 * 2) if the dead node had an EX when he died, blank out the lvb 
+	 */
+	assert_spin_locked(&dlm->spinlock);
+	assert_spin_locked(&res->spinlock);
+
+	/* TODO: check pending_asts, pending_basts here */
+	list_for_each_safe(iter, tmpiter, &res->granted) {
+		lock = list_entry (iter, struct dlm_lock, list);
+		if (lock->ml.node == dead_node) {
+			list_del_init(&lock->list);
+			dlm_lock_put(lock);
+		}
+	}
+	list_for_each_safe(iter, tmpiter, &res->converting) {
+		lock = list_entry (iter, struct dlm_lock, list);
+		if (lock->ml.node == dead_node) {
+			list_del_init(&lock->list);
+			dlm_lock_put(lock);
+		}
+	}
+	list_for_each_safe(iter, tmpiter, &res->blocked) {
+		lock = list_entry (iter, struct dlm_lock, list);
+		if (lock->ml.node == dead_node) {
+			list_del_init(&lock->list);
+			dlm_lock_put(lock);
+		}
+	}
+
+	/* do not kick thread yet */
+	__dlm_dirty_lockres(dlm, res);
+}
+
+/* if this node is the recovery master, and there are no
+ * locks for a given lockres owned by this node that are in
+ * either PR or EX mode, zero out the lvb before requesting.
+ *
+ */
+
+
+static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node)
+{
+	struct list_head *iter;
+	struct dlm_lock_resource *res;
+	int i;
+	struct list_head *bucket;
+
+
+	/* purge any stale mles */
+	dlm_clean_master_list(dlm, dead_node);
+
+	/*
+	 * now clean up all lock resources.  there are two rules:
+	 *
+	 * 1) if the dead node was the master, move the lockres
+	 *    to the recovering list.  set the RECOVERING flag.
+	 *    this lockres needs to be cleaned up before it can
+	 *    be used further.
+	 *
+	 * 2) if this node was the master, remove all locks from
+	 *    each of the lockres queues that were owned by the
+	 *    dead node.  once recovery finishes, the dlm thread
+	 *    can be kicked again to see if any ASTs or BASTs
+	 *    need to be fired as a result.
+	 */
+	for (i=0; i<DLM_HASH_SIZE; i++) {
+		bucket = &(dlm->resources[i]);
+		list_for_each(iter, bucket) {
+			res = list_entry (iter, struct dlm_lock_resource, list);
+			if (dlm_is_recovery_lock(res->lockname.name,
+						 res->lockname.len))
+				continue;
+			
+			spin_lock(&res->spinlock);
+			/* zero the lvb if necessary */
+			dlm_revalidate_lvb(dlm, res, dead_node);
+			if (res->owner == dead_node)
+				dlm_move_lockres_to_recovery_list(dlm, res);
+			else if (res->owner == dlm->node_num) {
+				dlm_free_dead_locks(dlm, res, dead_node);
+				__dlm_lockres_calc_usage(dlm, res);
+			}
+			spin_unlock(&res->spinlock);
+		}
+	}
+
+}
+
+static void __dlm_hb_node_down(struct dlm_ctxt *dlm, int idx)
+{
+	assert_spin_locked(&dlm->spinlock);
+
+	/* check to see if the node is already considered dead */
+	if (!test_bit(idx, dlm->live_nodes_map)) {
+		mlog(0, "for domain %s, node %d is already dead. "
+		     "another node likely did recovery already.\n",
+		     dlm->name, idx);
+		return;
+	}
+
+	/* check to see if we do not care about this node */
+	if (!test_bit(idx, dlm->domain_map)) {
+		/* This also catches the case that we get a node down
+		 * but haven't joined the domain yet. */
+		mlog(0, "node %u already removed from domain!\n", idx);
+		return;
+	}
+
+	clear_bit(idx, dlm->live_nodes_map);
+
+	/* Clean up join state on node death. */
+	if (dlm->joining_node == idx) {
+		mlog(0, "Clearing join state for node %u\n", idx);
+		__dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
+	}
+
+	/* make sure local cleanup occurs before the heartbeat events */
+	if (!test_bit(idx, dlm->recovery_map))
+		dlm_do_local_recovery_cleanup(dlm, idx);
+
+	/* notify anything attached to the heartbeat events */
+	dlm_hb_event_notify_attached(dlm, idx, 0);
+
+	mlog(0, "node %u being removed from domain map!\n", idx);
+	clear_bit(idx, dlm->domain_map);
+	/* wake up migration waiters if a node goes down.
+	 * perhaps later we can genericize this for other waiters. */
+	wake_up(&dlm->migration_wq);
+
+	if (test_bit(idx, dlm->recovery_map))
+		mlog(0, "domain %s, node %u already added "
+		     "to recovery map!\n", dlm->name, idx);
+	else
+		set_bit(idx, dlm->recovery_map);
+}
+
+void dlm_hb_node_down_cb(struct o2nm_node *node, int idx, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+
+	if (!dlm_grab(dlm))
+		return;
+
+	spin_lock(&dlm->spinlock);
+	__dlm_hb_node_down(dlm, idx);
+	spin_unlock(&dlm->spinlock);
+
+	dlm_put(dlm);
+}
+
+void dlm_hb_node_up_cb(struct o2nm_node *node, int idx, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+
+	if (!dlm_grab(dlm))
+		return;
+
+	spin_lock(&dlm->spinlock);
+
+	set_bit(idx, dlm->live_nodes_map);
+
+	/* notify any mles attached to the heartbeat events */
+	dlm_hb_event_notify_attached(dlm, idx, 1);
+
+	spin_unlock(&dlm->spinlock);
+
+	dlm_put(dlm);
+}
+
+static void dlm_reco_ast(void *astdata)
+{
+	struct dlm_ctxt *dlm = astdata;
+	mlog(0, "ast for recovery lock fired!, this=%u, dlm=%s\n",
+	     dlm->node_num, dlm->name);
+}
+static void dlm_reco_bast(void *astdata, int blocked_type)
+{
+	struct dlm_ctxt *dlm = astdata;
+	mlog(0, "bast for recovery lock fired!, this=%u, dlm=%s\n",
+	     dlm->node_num, dlm->name);
+}
+static void dlm_reco_unlock_ast(void *astdata, enum dlm_status st)
+{
+	mlog(0, "unlockast for recovery lock fired!\n");
+}
+
+
+static int dlm_pick_recovery_master(struct dlm_ctxt *dlm)
+{
+	enum dlm_status ret;
+	struct dlm_lockstatus lksb;
+	int status = -EINVAL;
+
+	mlog(0, "starting recovery of %s at %lu, dead=%u, this=%u\n",
+	     dlm->name, jiffies, dlm->reco.dead_node, dlm->node_num);
+retry:
+	memset(&lksb, 0, sizeof(lksb));
+
+	ret = dlmlock(dlm, LKM_EXMODE, &lksb, LKM_NOQUEUE|LKM_RECOVERY,
+		      DLM_RECOVERY_LOCK_NAME, dlm_reco_ast, dlm, dlm_reco_bast);
+
+	if (ret == DLM_NORMAL) {
+		mlog(0, "dlm=%s dlmlock says I got it (this=%u)\n",
+		     dlm->name, dlm->node_num);
+		/* I am master, send message to all nodes saying
+		 * that I am beginning a recovery session */
+		status = dlm_send_begin_reco_message(dlm,
+					      dlm->reco.dead_node);
+
+		/* recovery lock is a special case.  ast will not get fired,
+		 * so just go ahead and unlock it. */
+		ret = dlmunlock(dlm, &lksb, 0, dlm_reco_unlock_ast, dlm);
+		if (ret != DLM_NORMAL) {
+			/* this would really suck. this could only happen
+			 * if there was a network error during the unlock
+			 * because of node death.  this means the unlock
+			 * is actually "done" and the lock structure is
+			 * even freed.  we can continue, but only
+			 * because this specific lock name is special. */
+			mlog(0, "dlmunlock returned %d\n", ret);
+		}
+
+		if (status < 0) {
+			mlog(0, "failed to send recovery message. "
+				   "must retry with new node map.\n");
+			goto retry;
+		}
+	} else if (ret == DLM_NOTQUEUED) {
+		mlog(0, "dlm=%s dlmlock says another node got it (this=%u)\n",
+		     dlm->name, dlm->node_num);
+		/* another node is master. wait on
+		 * reco.new_master != O2NM_INVALID_NODE_NUM */
+		status = -EEXIST;
+	}
+
+	return status;
+}
+
+static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node)
+{
+	struct dlm_begin_reco br;
+	int ret = 0;
+	struct dlm_node_iter iter;
+	int nodenum;
+	int status;
+
+	mlog_entry("%u\n", dead_node);
+
+	mlog(0, "dead node is %u\n", dead_node);
+
+	spin_lock(&dlm->spinlock);
+	dlm_node_iter_init(dlm->domain_map, &iter);
+	spin_unlock(&dlm->spinlock);
+
+	clear_bit(dead_node, iter.node_map);
+
+	memset(&br, 0, sizeof(br));
+	br.node_idx = dlm->node_num;
+	br.dead_node = dead_node;
+
+	while ((nodenum = dlm_node_iter_next(&iter)) >= 0) {
+		ret = 0;
+		if (nodenum == dead_node) {
+			mlog(0, "not sending begin reco to dead node "
+				  "%u\n", dead_node);
+			continue;
+		}
+		if (nodenum == dlm->node_num) {
+			mlog(0, "not sending begin reco to self\n");
+			continue;
+		}
+
+		ret = -EINVAL;
+		mlog(0, "attempting to send begin reco msg to %d\n",
+			  nodenum);
+		ret = o2net_send_message(DLM_BEGIN_RECO_MSG, dlm->key,
+					 &br, sizeof(br), nodenum, &status);
+		/* negative status is handled ok by caller here */
+		if (ret >= 0)
+			ret = status;
+		if (ret < 0) {
+			struct dlm_lock_resource *res;
+			mlog_errno(ret);
+			mlog(ML_ERROR, "begin reco of dlm %s to node %u "
+			    " returned %d\n", dlm->name, nodenum, ret);
+			res = dlm_lookup_lockres(dlm, DLM_RECOVERY_LOCK_NAME,
+						 DLM_RECOVERY_LOCK_NAME_LEN);
+			if (res) {
+				dlm_print_one_lock_resource(res);
+				dlm_lockres_put(res);
+			} else {
+				mlog(ML_ERROR, "recovery lock not found\n");
+			}
+			break;
+		}
+	}
+
+	return ret;
+}
+
+int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_begin_reco *br = (struct dlm_begin_reco *)msg->buf;
+
+	/* ok to return 0, domain has gone away */
+	if (!dlm_grab(dlm))
+		return 0;
+
+	mlog(0, "node %u wants to recover node %u\n",
+		  br->node_idx, br->dead_node);
+
+	dlm_fire_domain_eviction_callbacks(dlm, br->dead_node);
+
+	spin_lock(&dlm->spinlock);
+	if (dlm->reco.new_master != O2NM_INVALID_NODE_NUM) {
+		mlog(0, "new_master already set to %u!\n",
+			  dlm->reco.new_master);
+	}
+	if (dlm->reco.dead_node != O2NM_INVALID_NODE_NUM) {
+		mlog(0, "dead_node already set to %u!\n",
+			  dlm->reco.dead_node);
+	}
+	dlm->reco.new_master = br->node_idx;
+	dlm->reco.dead_node = br->dead_node;
+	if (!test_bit(br->dead_node, dlm->recovery_map)) {
+		mlog(ML_ERROR, "recovery master %u sees %u as dead, but this "
+		     "node has not yet.  marking %u as dead\n",
+		     br->node_idx, br->dead_node, br->dead_node);
+		__dlm_hb_node_down(dlm, br->dead_node);
+	}
+	spin_unlock(&dlm->spinlock);
+
+	dlm_kick_recovery_thread(dlm);
+	dlm_put(dlm);
+	return 0;
+}
+
+static int dlm_send_finalize_reco_message(struct dlm_ctxt *dlm)
+{
+	int ret = 0;
+	struct dlm_finalize_reco fr;
+	struct dlm_node_iter iter;
+	int nodenum;
+	int status;
+
+	mlog(0, "finishing recovery for node %s:%u\n",
+	     dlm->name, dlm->reco.dead_node);
+
+	spin_lock(&dlm->spinlock);
+	dlm_node_iter_init(dlm->domain_map, &iter);
+	spin_unlock(&dlm->spinlock);
+
+	memset(&fr, 0, sizeof(fr));
+	fr.node_idx = dlm->node_num;
+	fr.dead_node = dlm->reco.dead_node;
+
+	while ((nodenum = dlm_node_iter_next(&iter)) >= 0) {
+		if (nodenum == dlm->node_num)
+			continue;
+		ret = o2net_send_message(DLM_FINALIZE_RECO_MSG, dlm->key,
+					 &fr, sizeof(fr), nodenum, &status);
+		if (ret >= 0) {
+			ret = status;
+			if (dlm_is_host_down(ret)) {
+				/* this has no effect on this recovery 
+				 * session, so set the status to zero to 
+				 * finish out the last recovery */
+				mlog(ML_ERROR, "node %u went down after this "
+				     "node finished recovery.\n", nodenum);
+				ret = 0;
+			}
+		}
+		if (ret < 0) {
+			mlog_errno(ret);
+			break;
+		}
+	}
+
+	return ret;
+}
+
+int dlm_finalize_reco_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_finalize_reco *fr = (struct dlm_finalize_reco *)msg->buf;
+
+	/* ok to return 0, domain has gone away */
+	if (!dlm_grab(dlm))
+		return 0;
+
+	mlog(0, "node %u finalizing recovery of node %u\n",
+	     fr->node_idx, fr->dead_node);
+
+	spin_lock(&dlm->spinlock);
+
+	if (dlm->reco.new_master != fr->node_idx) {
+		mlog(ML_ERROR, "node %u sent recovery finalize msg, but node "
+		     "%u is supposed to be the new master, dead=%u\n",
+		     fr->node_idx, dlm->reco.new_master, fr->dead_node);
+		BUG();
+	}
+	if (dlm->reco.dead_node != fr->dead_node) {
+		mlog(ML_ERROR, "node %u sent recovery finalize msg for dead "
+		     "node %u, but node %u is supposed to be dead\n",
+		     fr->node_idx, fr->dead_node, dlm->reco.dead_node);
+		BUG();
+	}
+
+	dlm_finish_local_lockres_recovery(dlm, fr->dead_node, fr->node_idx);
+
+	spin_unlock(&dlm->spinlock);
+
+	dlm_reset_recovery(dlm);
+
+	dlm_kick_recovery_thread(dlm);
+	dlm_put(dlm);
+	return 0;
+}
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c
new file mode 100644
index 0000000..5be9d14
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmthread.c
@@ -0,0 +1,692 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmthread.c
+ *
+ * standalone DLM module
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include <linux/random.h>
+#include <linux/blkdev.h>
+#include <linux/socket.h>
+#include <linux/inet.h>
+#include <linux/timer.h>
+#include <linux/kthread.h>
+
+
+#include "cluster/heartbeat.h"
+#include "cluster/nodemanager.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+#include "dlmcommon.h"
+#include "dlmdomain.h"
+
+#define MLOG_MASK_PREFIX (ML_DLM|ML_DLM_THREAD)
+#include "cluster/masklog.h"
+
+static int dlm_thread(void *data);
+
+static void dlm_flush_asts(struct dlm_ctxt *dlm);
+
+#define dlm_lock_is_remote(dlm, lock)     ((lock)->ml.node != (dlm)->node_num)
+
+/* will exit holding res->spinlock, but may drop in function */
+/* waits until flags are cleared on res->state */
+void __dlm_wait_on_lockres_flags(struct dlm_lock_resource *res, int flags)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	assert_spin_locked(&res->spinlock);
+
+	add_wait_queue(&res->wq, &wait);
+repeat:
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	if (res->state & flags) {
+		spin_unlock(&res->spinlock);
+		schedule();
+		spin_lock(&res->spinlock);
+		goto repeat;
+	}
+	remove_wait_queue(&res->wq, &wait);
+	current->state = TASK_RUNNING;
+}
+
+
+static int __dlm_lockres_unused(struct dlm_lock_resource *res)
+{
+	if (list_empty(&res->granted) &&
+	    list_empty(&res->converting) &&
+	    list_empty(&res->blocked) &&
+	    list_empty(&res->dirty))
+		return 1;
+	return 0;
+}
+
+
+/* Call whenever you may have added or deleted something from one of
+ * the lockres queue's. This will figure out whether it belongs on the
+ * unused list or not and does the appropriate thing. */
+void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
+			      struct dlm_lock_resource *res)
+{
+	mlog_entry("%.*s\n", res->lockname.len, res->lockname.name);
+
+	assert_spin_locked(&dlm->spinlock);
+	assert_spin_locked(&res->spinlock);
+
+	if (__dlm_lockres_unused(res)){
+		if (list_empty(&res->purge)) {
+			mlog(0, "putting lockres %.*s from purge list\n",
+			     res->lockname.len, res->lockname.name);
+
+			res->last_used = jiffies;
+			list_add_tail(&res->purge, &dlm->purge_list);
+			dlm->purge_count++;
+		}
+	} else if (!list_empty(&res->purge)) {
+		mlog(0, "removing lockres %.*s from purge list\n",
+		     res->lockname.len, res->lockname.name);
+
+		list_del_init(&res->purge);
+		dlm->purge_count--;
+	}
+}
+
+void dlm_lockres_calc_usage(struct dlm_ctxt *dlm,
+			    struct dlm_lock_resource *res)
+{
+	mlog_entry("%.*s\n", res->lockname.len, res->lockname.name);
+	spin_lock(&dlm->spinlock);
+	spin_lock(&res->spinlock);
+
+	__dlm_lockres_calc_usage(dlm, res);
+
+	spin_unlock(&res->spinlock);
+	spin_unlock(&dlm->spinlock);
+}
+
+/* TODO: Eventual API: Called with the dlm spinlock held, may drop it
+ * to do migration, but will re-acquire before exit. */
+void dlm_purge_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *lockres)
+{
+	int master;
+	int ret;
+
+	spin_lock(&lockres->spinlock);
+	master = lockres->owner == dlm->node_num;
+	spin_unlock(&lockres->spinlock);
+
+	mlog(0, "purging lockres %.*s, master = %d\n", lockres->lockname.len,
+	     lockres->lockname.name, master);
+
+	/* Non master is the easy case -- no migration required, just
+	 * quit. */
+	if (!master)
+		goto finish;
+
+	/* Wheee! Migrate lockres here! */
+	spin_unlock(&dlm->spinlock);
+again:
+
+	ret = dlm_migrate_lockres(dlm, lockres, O2NM_MAX_NODES);
+	if (ret == -ENOTEMPTY) {
+		mlog(ML_ERROR, "lockres %.*s still has local locks!\n",
+		     lockres->lockname.len, lockres->lockname.name);
+
+		BUG();
+	} else if (ret < 0) {
+		mlog(ML_NOTICE, "lockres %.*s: migrate failed, retrying\n",
+		     lockres->lockname.len, lockres->lockname.name);
+		goto again;
+	}
+
+	spin_lock(&dlm->spinlock);
+
+finish:
+	if (!list_empty(&lockres->purge)) {
+		list_del_init(&lockres->purge);
+		dlm->purge_count--;
+	}
+	__dlm_unhash_lockres(lockres);
+}
+
+static void dlm_run_purge_list(struct dlm_ctxt *dlm,
+			       int purge_now)
+{
+	unsigned int run_max, unused;
+	unsigned long purge_jiffies;
+	struct dlm_lock_resource *lockres;
+
+	spin_lock(&dlm->spinlock);
+	run_max = dlm->purge_count;
+
+	while(run_max && !list_empty(&dlm->purge_list)) {
+		run_max--;
+
+		lockres = list_entry(dlm->purge_list.next,
+				     struct dlm_lock_resource, purge);
+
+		/* Status of the lockres *might* change so double
+		 * check. If the lockres is unused, holding the dlm
+		 * spinlock will prevent people from getting and more
+		 * refs on it -- there's no need to keep the lockres
+		 * spinlock. */
+		spin_lock(&lockres->spinlock);
+		unused = __dlm_lockres_unused(lockres);
+		spin_unlock(&lockres->spinlock);
+
+		if (!unused)
+			continue;
+
+		purge_jiffies = lockres->last_used +
+			msecs_to_jiffies(DLM_PURGE_INTERVAL_MS);
+
+		/* Make sure that we want to be processing this guy at
+		 * this time. */
+		if (!purge_now && time_after(purge_jiffies, jiffies)) {
+			/* Since resources are added to the purge list
+			 * in tail order, we can stop at the first
+			 * unpurgable resource -- anyone added after
+			 * him will have a greater last_used value */
+			break;
+		}
+
+		list_del_init(&lockres->purge);
+		dlm->purge_count--;
+
+		/* This may drop and reacquire the dlm spinlock if it
+		 * has to do migration. */
+		mlog(0, "calling dlm_purge_lockres!\n");
+		dlm_purge_lockres(dlm, lockres);
+		mlog(0, "DONE calling dlm_purge_lockres!\n");
+
+		/* Avoid adding any scheduling latencies */
+		cond_resched_lock(&dlm->spinlock);
+	}
+
+	spin_unlock(&dlm->spinlock);
+}
+
+static void dlm_shuffle_lists(struct dlm_ctxt *dlm,
+			      struct dlm_lock_resource *res)
+{
+	struct dlm_lock *lock, *target;
+	struct list_head *iter;
+	struct list_head *head;
+	int can_grant = 1;
+
+	//mlog(0, "res->lockname.len=%d\n", res->lockname.len);
+	//mlog(0, "res->lockname.name=%p\n", res->lockname.name);
+	//mlog(0, "shuffle res %.*s\n", res->lockname.len,
+	//	  res->lockname.name);
+
+	/* because this function is called with the lockres
+	 * spinlock, and because we know that it is not migrating/
+	 * recovering/in-progress, it is fine to reserve asts and
+	 * basts right before queueing them all throughout */
+	assert_spin_locked(&res->spinlock);
+	BUG_ON((res->state & (DLM_LOCK_RES_MIGRATING|
+			      DLM_LOCK_RES_RECOVERING|
+			      DLM_LOCK_RES_IN_PROGRESS)));
+
+converting:
+	if (list_empty(&res->converting))
+		goto blocked;
+	mlog(0, "res %.*s has locks on a convert queue\n", res->lockname.len,
+	     res->lockname.name);
+
+	target = list_entry(res->converting.next, struct dlm_lock, list);
+	if (target->ml.convert_type == LKM_IVMODE) {
+		mlog(ML_ERROR, "%.*s: converting a lock with no "
+		     "convert_type!\n", res->lockname.len, res->lockname.name);
+		BUG();
+	}
+	head = &res->granted;
+	list_for_each(iter, head) {
+		lock = list_entry(iter, struct dlm_lock, list);
+		if (lock==target)
+			continue;
+		if (!dlm_lock_compatible(lock->ml.type,
+					 target->ml.convert_type)) {
+			can_grant = 0;
+			/* queue the BAST if not already */
+			if (lock->ml.highest_blocked == LKM_IVMODE) {
+				__dlm_lockres_reserve_ast(res);
+				dlm_queue_bast(dlm, lock);
+			}
+			/* update the highest_blocked if needed */
+			if (lock->ml.highest_blocked < target->ml.convert_type)
+				lock->ml.highest_blocked =
+					target->ml.convert_type;
+		}
+	}
+	head = &res->converting;
+	list_for_each(iter, head) {
+		lock = list_entry(iter, struct dlm_lock, list);
+		if (lock==target)
+			continue;
+		if (!dlm_lock_compatible(lock->ml.type,
+					 target->ml.convert_type)) {
+			can_grant = 0;
+			if (lock->ml.highest_blocked == LKM_IVMODE) {
+				__dlm_lockres_reserve_ast(res);
+				dlm_queue_bast(dlm, lock);
+			}
+			if (lock->ml.highest_blocked < target->ml.convert_type)
+				lock->ml.highest_blocked =
+					target->ml.convert_type;
+		}
+	}
+
+	/* we can convert the lock */
+	if (can_grant) {
+		spin_lock(&target->spinlock);
+		BUG_ON(target->ml.highest_blocked != LKM_IVMODE);
+
+		mlog(0, "calling ast for converting lock: %.*s, have: %d, "
+		     "granting: %d, node: %u\n", res->lockname.len,
+		     res->lockname.name, target->ml.type,
+		     target->ml.convert_type, target->ml.node);
+
+		target->ml.type = target->ml.convert_type;
+		target->ml.convert_type = LKM_IVMODE;
+		list_del_init(&target->list);
+		list_add_tail(&target->list, &res->granted);
+
+		BUG_ON(!target->lksb);
+		target->lksb->status = DLM_NORMAL;
+
+		spin_unlock(&target->spinlock);
+
+		__dlm_lockres_reserve_ast(res);
+		dlm_queue_ast(dlm, target);
+		/* go back and check for more */
+		goto converting;
+	}
+
+blocked:
+	if (list_empty(&res->blocked))
+		goto leave;
+	target = list_entry(res->blocked.next, struct dlm_lock, list);
+
+	head = &res->granted;
+	list_for_each(iter, head) {
+		lock = list_entry(iter, struct dlm_lock, list);
+		if (lock==target)
+			continue;
+		if (!dlm_lock_compatible(lock->ml.type, target->ml.type)) {
+			can_grant = 0;
+			if (lock->ml.highest_blocked == LKM_IVMODE) {
+				__dlm_lockres_reserve_ast(res);
+				dlm_queue_bast(dlm, lock);
+			}
+			if (lock->ml.highest_blocked < target->ml.type)
+				lock->ml.highest_blocked = target->ml.type;
+		}
+	}
+
+	head = &res->converting;
+	list_for_each(iter, head) {
+		lock = list_entry(iter, struct dlm_lock, list);
+		if (lock==target)
+			continue;
+		if (!dlm_lock_compatible(lock->ml.type, target->ml.type)) {
+			can_grant = 0;
+			if (lock->ml.highest_blocked == LKM_IVMODE) {
+				__dlm_lockres_reserve_ast(res);
+				dlm_queue_bast(dlm, lock);
+			}
+			if (lock->ml.highest_blocked < target->ml.type)
+				lock->ml.highest_blocked = target->ml.type;
+		}
+	}
+
+	/* we can grant the blocked lock (only
+	 * possible if converting list empty) */
+	if (can_grant) {
+		spin_lock(&target->spinlock);
+		BUG_ON(target->ml.highest_blocked != LKM_IVMODE);
+
+		mlog(0, "calling ast for blocked lock: %.*s, granting: %d, "
+		     "node: %u\n", res->lockname.len, res->lockname.name,
+		     target->ml.type, target->ml.node);
+
+		// target->ml.type is already correct
+		list_del_init(&target->list);
+		list_add_tail(&target->list, &res->granted);
+
+		BUG_ON(!target->lksb);
+		target->lksb->status = DLM_NORMAL;
+
+		spin_unlock(&target->spinlock);
+
+		__dlm_lockres_reserve_ast(res);
+		dlm_queue_ast(dlm, target);
+		/* go back and check for more */
+		goto converting;
+	}
+
+leave:
+	return;
+}
+
+/* must have NO locks when calling this with res !=NULL * */
+void dlm_kick_thread(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
+{
+	mlog_entry("dlm=%p, res=%p\n", dlm, res);
+	if (res) {
+		spin_lock(&dlm->spinlock);
+		spin_lock(&res->spinlock);
+		__dlm_dirty_lockres(dlm, res);
+		spin_unlock(&res->spinlock);
+		spin_unlock(&dlm->spinlock);
+	}
+	wake_up(&dlm->dlm_thread_wq);
+}
+
+void __dlm_dirty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res)
+{
+	mlog_entry("dlm=%p, res=%p\n", dlm, res);
+
+	assert_spin_locked(&dlm->spinlock);
+	assert_spin_locked(&res->spinlock);
+
+	/* don't shuffle secondary queues */
+	if ((res->owner == dlm->node_num) &&
+	    !(res->state & DLM_LOCK_RES_DIRTY)) {
+		list_add_tail(&res->dirty, &dlm->dirty_list);
+		res->state |= DLM_LOCK_RES_DIRTY;
+	}
+}
+
+
+/* Launch the NM thread for the mounted volume */
+int dlm_launch_thread(struct dlm_ctxt *dlm)
+{
+	mlog(0, "starting dlm thread...\n");
+
+	dlm->dlm_thread_task = kthread_run(dlm_thread, dlm, "dlm_thread");
+	if (IS_ERR(dlm->dlm_thread_task)) {
+		mlog_errno(PTR_ERR(dlm->dlm_thread_task));
+		dlm->dlm_thread_task = NULL;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void dlm_complete_thread(struct dlm_ctxt *dlm)
+{
+	if (dlm->dlm_thread_task) {
+		mlog(ML_KTHREAD, "waiting for dlm thread to exit\n");
+		kthread_stop(dlm->dlm_thread_task);
+		dlm->dlm_thread_task = NULL;
+	}
+}
+
+static int dlm_dirty_list_empty(struct dlm_ctxt *dlm)
+{
+	int empty;
+
+	spin_lock(&dlm->spinlock);
+	empty = list_empty(&dlm->dirty_list);
+	spin_unlock(&dlm->spinlock);
+
+	return empty;
+}
+
+static void dlm_flush_asts(struct dlm_ctxt *dlm)
+{
+	int ret;
+	struct dlm_lock *lock;
+	struct dlm_lock_resource *res;
+	u8 hi;
+
+	spin_lock(&dlm->ast_lock);
+	while (!list_empty(&dlm->pending_asts)) {
+		lock = list_entry(dlm->pending_asts.next,
+				  struct dlm_lock, ast_list);
+		/* get an extra ref on lock */
+		dlm_lock_get(lock);
+		res = lock->lockres;
+		mlog(0, "delivering an ast for this lockres\n");
+
+		BUG_ON(!lock->ast_pending);
+
+		/* remove from list (including ref) */
+		list_del_init(&lock->ast_list);
+		dlm_lock_put(lock);
+		spin_unlock(&dlm->ast_lock);
+
+		if (lock->ml.node != dlm->node_num) {
+			ret = dlm_do_remote_ast(dlm, res, lock);
+			if (ret < 0)
+				mlog_errno(ret);
+		} else
+			dlm_do_local_ast(dlm, res, lock);
+
+		spin_lock(&dlm->ast_lock);
+
+		/* possible that another ast was queued while
+		 * we were delivering the last one */
+		if (!list_empty(&lock->ast_list)) {
+			mlog(0, "aha another ast got queued while "
+			     "we were finishing the last one.  will "
+			     "keep the ast_pending flag set.\n");
+		} else
+			lock->ast_pending = 0;
+
+		/* drop the extra ref.
+		 * this may drop it completely. */
+		dlm_lock_put(lock);
+		dlm_lockres_release_ast(dlm, res);
+	}
+
+	while (!list_empty(&dlm->pending_basts)) {
+		lock = list_entry(dlm->pending_basts.next,
+				  struct dlm_lock, bast_list);
+		/* get an extra ref on lock */
+		dlm_lock_get(lock);
+		res = lock->lockres;
+
+		BUG_ON(!lock->bast_pending);
+
+		/* get the highest blocked lock, and reset */
+		spin_lock(&lock->spinlock);
+		BUG_ON(lock->ml.highest_blocked <= LKM_IVMODE);
+		hi = lock->ml.highest_blocked;
+		lock->ml.highest_blocked = LKM_IVMODE;
+		spin_unlock(&lock->spinlock);
+
+		/* remove from list (including ref) */
+		list_del_init(&lock->bast_list);
+		dlm_lock_put(lock);
+		spin_unlock(&dlm->ast_lock);
+
+		mlog(0, "delivering a bast for this lockres "
+		     "(blocked = %d\n", hi);
+
+		if (lock->ml.node != dlm->node_num) {
+			ret = dlm_send_proxy_bast(dlm, res, lock, hi);
+			if (ret < 0)
+				mlog_errno(ret);
+		} else
+			dlm_do_local_bast(dlm, res, lock, hi);
+
+		spin_lock(&dlm->ast_lock);
+
+		/* possible that another bast was queued while
+		 * we were delivering the last one */
+		if (!list_empty(&lock->bast_list)) {
+			mlog(0, "aha another bast got queued while "
+			     "we were finishing the last one.  will "
+			     "keep the bast_pending flag set.\n");
+		} else
+			lock->bast_pending = 0;
+
+		/* drop the extra ref.
+		 * this may drop it completely. */
+		dlm_lock_put(lock);
+		dlm_lockres_release_ast(dlm, res);
+	}
+	wake_up(&dlm->ast_wq);
+	spin_unlock(&dlm->ast_lock);
+}
+
+
+#define DLM_THREAD_TIMEOUT_MS (4 * 1000)
+#define DLM_THREAD_MAX_DIRTY  100
+#define DLM_THREAD_MAX_ASTS   10
+
+static int dlm_thread(void *data)
+{
+	struct dlm_lock_resource *res;
+	struct dlm_ctxt *dlm = data;
+	unsigned long timeout = msecs_to_jiffies(DLM_THREAD_TIMEOUT_MS);
+
+	mlog(0, "dlm thread running for %s...\n", dlm->name);
+
+	while (!kthread_should_stop()) {
+		int n = DLM_THREAD_MAX_DIRTY;
+
+		/* dlm_shutting_down is very point-in-time, but that
+		 * doesn't matter as we'll just loop back around if we
+		 * get false on the leading edge of a state
+		 * transition. */
+		dlm_run_purge_list(dlm, dlm_shutting_down(dlm));
+
+		/* We really don't want to hold dlm->spinlock while
+		 * calling dlm_shuffle_lists on each lockres that
+		 * needs to have its queues adjusted and AST/BASTs
+		 * run.  So let's pull each entry off the dirty_list
+		 * and drop dlm->spinlock ASAP.  Once off the list,
+		 * res->spinlock needs to be taken again to protect
+		 * the queues while calling dlm_shuffle_lists.  */
+		spin_lock(&dlm->spinlock);
+		while (!list_empty(&dlm->dirty_list)) {
+			int delay = 0;
+			res = list_entry(dlm->dirty_list.next,
+					 struct dlm_lock_resource, dirty);
+
+			/* peel a lockres off, remove it from the list,
+			 * unset the dirty flag and drop the dlm lock */
+			BUG_ON(!res);
+			dlm_lockres_get(res);
+
+			spin_lock(&res->spinlock);
+			res->state &= ~DLM_LOCK_RES_DIRTY;
+			list_del_init(&res->dirty);
+			spin_unlock(&res->spinlock);
+			spin_unlock(&dlm->spinlock);
+
+		 	/* lockres can be re-dirtied/re-added to the
+			 * dirty_list in this gap, but that is ok */
+
+			spin_lock(&res->spinlock);
+			if (res->owner != dlm->node_num) {
+				__dlm_print_one_lock_resource(res);
+				mlog(ML_ERROR, "inprog:%s, mig:%s, reco:%s, dirty:%s\n",
+				     res->state & DLM_LOCK_RES_IN_PROGRESS ? "yes" : "no",
+				     res->state & DLM_LOCK_RES_MIGRATING ? "yes" : "no",
+				     res->state & DLM_LOCK_RES_RECOVERING ? "yes" : "no",
+				     res->state & DLM_LOCK_RES_DIRTY ? "yes" : "no");
+			}
+			BUG_ON(res->owner != dlm->node_num);
+
+			/* it is now ok to move lockreses in these states
+			 * to the dirty list, assuming that they will only be
+			 * dirty for a short while. */
+			if (res->state & (DLM_LOCK_RES_IN_PROGRESS |
+					  DLM_LOCK_RES_MIGRATING |
+					  DLM_LOCK_RES_RECOVERING)) {
+				/* move it to the tail and keep going */
+				spin_unlock(&res->spinlock);
+				mlog(0, "delaying list shuffling for in-"
+				     "progress lockres %.*s, state=%d\n",
+				     res->lockname.len, res->lockname.name,
+				     res->state);
+				delay = 1;
+				goto in_progress;
+			}
+
+			/* at this point the lockres is not migrating/
+			 * recovering/in-progress.  we have the lockres
+			 * spinlock and do NOT have the dlm lock.
+			 * safe to reserve/queue asts and run the lists. */
+
+			mlog(0, "calling dlm_shuffle_lists with dlm=%p, "
+			     "res=%p\n", dlm, res);
+
+			/* called while holding lockres lock */
+			dlm_shuffle_lists(dlm, res);
+			spin_unlock(&res->spinlock);
+
+			dlm_lockres_calc_usage(dlm, res);
+
+in_progress:
+
+			spin_lock(&dlm->spinlock);
+			/* if the lock was in-progress, stick
+			 * it on the back of the list */
+			if (delay) {
+				spin_lock(&res->spinlock);
+				list_add_tail(&res->dirty, &dlm->dirty_list);
+				res->state |= DLM_LOCK_RES_DIRTY;
+				spin_unlock(&res->spinlock);
+			}
+			dlm_lockres_put(res);
+
+			/* unlikely, but we may need to give time to
+			 * other tasks */
+			if (!--n) {
+				mlog(0, "throttling dlm_thread\n");
+				break;
+			}
+		}
+
+		spin_unlock(&dlm->spinlock);
+		dlm_flush_asts(dlm);
+
+		/* yield and continue right away if there is more work to do */
+		if (!n) {
+			yield();
+			continue;
+		}
+
+		wait_event_interruptible_timeout(dlm->dlm_thread_wq,
+						 !dlm_dirty_list_empty(dlm) ||
+						 kthread_should_stop(),
+						 timeout);
+	}
+
+	mlog(0, "quitting DLM thread\n");
+	return 0;
+}
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c
new file mode 100644
index 0000000..cec2ce1
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmunlock.c
@@ -0,0 +1,672 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmunlock.c
+ *
+ * underlying calls for unlocking locks
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/sysctl.h>
+#include <linux/random.h>
+#include <linux/blkdev.h>
+#include <linux/socket.h>
+#include <linux/inet.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+
+#include "cluster/heartbeat.h"
+#include "cluster/nodemanager.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+#include "dlmcommon.h"
+
+#define MLOG_MASK_PREFIX ML_DLM
+#include "cluster/masklog.h"
+
+#define DLM_UNLOCK_FREE_LOCK           0x00000001
+#define DLM_UNLOCK_CALL_AST            0x00000002
+#define DLM_UNLOCK_REMOVE_LOCK         0x00000004
+#define DLM_UNLOCK_REGRANT_LOCK        0x00000008
+#define DLM_UNLOCK_CLEAR_CONVERT_TYPE  0x00000010
+
+
+static enum dlm_status dlm_get_cancel_actions(struct dlm_ctxt *dlm,
+					      struct dlm_lock_resource *res,
+					      struct dlm_lock *lock,
+					      struct dlm_lockstatus *lksb,
+					      int *actions);
+static enum dlm_status dlm_get_unlock_actions(struct dlm_ctxt *dlm,
+					      struct dlm_lock_resource *res,
+					      struct dlm_lock *lock,
+					      struct dlm_lockstatus *lksb,
+					      int *actions);
+
+static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm,
+						 struct dlm_lock_resource *res,
+						 struct dlm_lock *lock,
+						 struct dlm_lockstatus *lksb,
+						 int flags,
+						 u8 owner);
+
+
+/*
+ * according to the spec:
+ * http://opendlm.sourceforge.net/cvsmirror/opendlm/docs/dlmbook_final.pdf
+ *
+ *  flags & LKM_CANCEL != 0: must be converting or blocked
+ *  flags & LKM_CANCEL == 0: must be granted
+ *
+ * So to unlock a converting lock, you must first cancel the
+ * convert (passing LKM_CANCEL in flags), then call the unlock
+ * again (with no LKM_CANCEL in flags).
+ */
+
+
+/*
+ * locking:
+ *   caller needs:  none
+ *   taken:         res->spinlock and lock->spinlock taken and dropped
+ *   held on exit:  none
+ * returns: DLM_NORMAL, DLM_NOLOCKMGR, status from network
+ * all callers should have taken an extra ref on lock coming in
+ */
+static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm,
+					struct dlm_lock_resource *res,
+					struct dlm_lock *lock,
+					struct dlm_lockstatus *lksb,
+					int flags, int *call_ast,
+					int master_node)
+{
+	enum dlm_status status;
+	int actions = 0;
+	int in_use;
+        u8 owner;
+
+	mlog(0, "master_node = %d, valblk = %d\n", master_node,
+	     flags & LKM_VALBLK);
+
+	if (master_node)
+		BUG_ON(res->owner != dlm->node_num);
+	else
+		BUG_ON(res->owner == dlm->node_num);
+
+	spin_lock(&dlm->spinlock);
+	/* We want to be sure that we're not freeing a lock
+	 * that still has AST's pending... */
+	in_use = !list_empty(&lock->ast_list);
+	spin_unlock(&dlm->spinlock);
+	if (in_use) {
+	       mlog(ML_ERROR, "lockres %.*s: Someone is calling dlmunlock "
+		    "while waiting for an ast!", res->lockname.len,
+		    res->lockname.name);
+		return DLM_BADPARAM;
+	}
+
+	spin_lock(&res->spinlock);
+	if (res->state & DLM_LOCK_RES_IN_PROGRESS) {
+		if (master_node) {
+			mlog(ML_ERROR, "lockres in progress!\n");
+			spin_unlock(&res->spinlock);
+			return DLM_FORWARD;
+		}
+		/* ok for this to sleep if not in a network handler */
+		__dlm_wait_on_lockres(res);
+		res->state |= DLM_LOCK_RES_IN_PROGRESS;
+	}
+	spin_lock(&lock->spinlock);
+
+	if (res->state & DLM_LOCK_RES_RECOVERING) {
+		status = DLM_RECOVERING;
+		goto leave;
+	}
+
+
+	/* see above for what the spec says about
+	 * LKM_CANCEL and the lock queue state */
+	if (flags & LKM_CANCEL)
+		status = dlm_get_cancel_actions(dlm, res, lock, lksb, &actions);
+	else
+		status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions);
+
+	if (status != DLM_NORMAL)
+		goto leave;
+
+	/* By now this has been masked out of cancel requests. */
+	if (flags & LKM_VALBLK) {
+		/* make the final update to the lvb */
+		if (master_node)
+			memcpy(res->lvb, lksb->lvb, DLM_LVB_LEN);
+		else
+			flags |= LKM_PUT_LVB; /* let the send function
+					       * handle it. */
+	}
+
+	if (!master_node) {
+		owner = res->owner;
+		/* drop locks and send message */
+		if (flags & LKM_CANCEL)
+			lock->cancel_pending = 1;
+		else
+			lock->unlock_pending = 1;
+		spin_unlock(&lock->spinlock);
+		spin_unlock(&res->spinlock);
+		status = dlm_send_remote_unlock_request(dlm, res, lock, lksb,
+							flags, owner);
+		spin_lock(&res->spinlock);
+		spin_lock(&lock->spinlock);
+		/* if the master told us the lock was already granted,
+		 * let the ast handle all of these actions */
+		if (status == DLM_NORMAL &&
+		    lksb->status == DLM_CANCELGRANT) {
+			actions &= ~(DLM_UNLOCK_REMOVE_LOCK|
+				     DLM_UNLOCK_REGRANT_LOCK|
+				     DLM_UNLOCK_CLEAR_CONVERT_TYPE);
+		}
+		if (flags & LKM_CANCEL)
+			lock->cancel_pending = 0;
+		else
+			lock->unlock_pending = 0;
+
+	}
+
+	/* get an extra ref on lock.  if we are just switching
+	 * lists here, we dont want the lock to go away. */
+	dlm_lock_get(lock);
+
+	if (actions & DLM_UNLOCK_REMOVE_LOCK) {
+		list_del_init(&lock->list);
+		dlm_lock_put(lock);
+	}
+	if (actions & DLM_UNLOCK_REGRANT_LOCK) {
+		dlm_lock_get(lock);
+		list_add_tail(&lock->list, &res->granted);
+	}
+	if (actions & DLM_UNLOCK_CLEAR_CONVERT_TYPE) {
+		mlog(0, "clearing convert_type at %smaster node\n",
+		     master_node ? "" : "non-");
+		lock->ml.convert_type = LKM_IVMODE;
+	}
+
+	/* remove the extra ref on lock */
+	dlm_lock_put(lock);
+
+leave:
+	res->state &= ~DLM_LOCK_RES_IN_PROGRESS;
+	if (!dlm_lock_on_list(&res->converting, lock))
+		BUG_ON(lock->ml.convert_type != LKM_IVMODE);
+	else
+		BUG_ON(lock->ml.convert_type == LKM_IVMODE);
+	spin_unlock(&lock->spinlock);
+	spin_unlock(&res->spinlock);
+	wake_up(&res->wq);
+
+	/* let the caller's final dlm_lock_put handle the actual kfree */
+	if (actions & DLM_UNLOCK_FREE_LOCK) {
+		/* this should always be coupled with list removal */
+		BUG_ON(!(actions & DLM_UNLOCK_REMOVE_LOCK));
+		mlog(0, "lock %"MLFu64" should be gone now! refs=%d\n",
+		     lock->ml.cookie, atomic_read(&lock->lock_refs.refcount)-1);
+		dlm_lock_put(lock);
+	}
+	if (actions & DLM_UNLOCK_CALL_AST)
+		*call_ast = 1;
+
+	/* if cancel or unlock succeeded, lvb work is done */
+	if (status == DLM_NORMAL)
+		lksb->flags &= ~(DLM_LKSB_PUT_LVB|DLM_LKSB_GET_LVB);
+
+	return status;
+}
+
+void dlm_commit_pending_unlock(struct dlm_lock_resource *res,
+			       struct dlm_lock *lock)
+{
+	/* leave DLM_LKSB_PUT_LVB on the lksb so any final
+	 * update of the lvb will be sent to the new master */
+	list_del_init(&lock->list);
+}
+
+void dlm_commit_pending_cancel(struct dlm_lock_resource *res,
+			       struct dlm_lock *lock)
+{
+	list_del_init(&lock->list);
+	list_add_tail(&lock->list, &res->granted);
+	lock->ml.convert_type = LKM_IVMODE;
+}
+
+
+static inline enum dlm_status dlmunlock_master(struct dlm_ctxt *dlm,
+					  struct dlm_lock_resource *res,
+					  struct dlm_lock *lock,
+					  struct dlm_lockstatus *lksb,
+					  int flags,
+					  int *call_ast)
+{
+	return dlmunlock_common(dlm, res, lock, lksb, flags, call_ast, 1);
+}
+
+static inline enum dlm_status dlmunlock_remote(struct dlm_ctxt *dlm,
+					  struct dlm_lock_resource *res,
+					  struct dlm_lock *lock,
+					  struct dlm_lockstatus *lksb,
+					  int flags, int *call_ast)
+{
+	return dlmunlock_common(dlm, res, lock, lksb, flags, call_ast, 0);
+}
+
+/*
+ * locking:
+ *   caller needs:  none
+ *   taken:         none
+ *   held on exit:  none
+ * returns: DLM_NORMAL, DLM_NOLOCKMGR, status from network
+ */
+static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm,
+						 struct dlm_lock_resource *res,
+						 struct dlm_lock *lock,
+						 struct dlm_lockstatus *lksb,
+						 int flags,
+						 u8 owner)
+{
+	struct dlm_unlock_lock unlock;
+	int tmpret;
+	enum dlm_status ret;
+	int status = 0;
+	struct kvec vec[2];
+	size_t veclen = 1;
+
+	mlog_entry("%.*s\n", res->lockname.len, res->lockname.name);
+
+	memset(&unlock, 0, sizeof(unlock));
+	unlock.node_idx = dlm->node_num;
+	unlock.flags = cpu_to_be32(flags);
+	unlock.cookie = lock->ml.cookie;
+	unlock.namelen = res->lockname.len;
+	memcpy(unlock.name, res->lockname.name, unlock.namelen);
+
+	vec[0].iov_len = sizeof(struct dlm_unlock_lock);
+	vec[0].iov_base = &unlock;
+
+	if (flags & LKM_PUT_LVB) {
+		/* extra data to send if we are updating lvb */
+		vec[1].iov_len = DLM_LVB_LEN;
+		vec[1].iov_base = lock->lksb->lvb;
+		veclen++;
+	}
+
+	tmpret = o2net_send_message_vec(DLM_UNLOCK_LOCK_MSG, dlm->key,
+					vec, veclen, owner, &status);
+	if (tmpret >= 0) {
+		// successfully sent and received
+		if (status == DLM_CANCELGRANT)
+			ret = DLM_NORMAL;
+		else if (status == DLM_FORWARD) {
+			mlog(0, "master was in-progress.  retry\n");
+			ret = DLM_FORWARD;
+		} else
+			ret = status;
+		lksb->status = status;
+	} else {
+		mlog_errno(tmpret);
+		if (dlm_is_host_down(tmpret)) {
+			/* NOTE: this seems strange, but it is what we want.
+			 * when the master goes down during a cancel or
+			 * unlock, the recovery code completes the operation
+			 * as if the master had not died, then passes the
+			 * updated state to the recovery master.  this thread
+			 * just needs to finish out the operation and call
+			 * the unlockast. */
+			ret = DLM_NORMAL;
+		} else {
+			/* something bad.  this will BUG in ocfs2 */
+			ret = dlm_err_to_dlm_status(tmpret);
+		}
+		lksb->status = ret;
+	}
+
+	return ret;
+}
+
+/*
+ * locking:
+ *   caller needs:  none
+ *   taken:         takes and drops res->spinlock
+ *   held on exit:  none
+ * returns: DLM_NORMAL, DLM_BADARGS, DLM_IVLOCKID,
+ *          return value from dlmunlock_master
+ */
+int dlm_unlock_lock_handler(struct o2net_msg *msg, u32 len, void *data)
+{
+	struct dlm_ctxt *dlm = data;
+	struct dlm_unlock_lock *unlock = (struct dlm_unlock_lock *)msg->buf;
+	struct dlm_lock_resource *res = NULL;
+	struct list_head *iter;
+	struct dlm_lock *lock = NULL;
+	enum dlm_status status = DLM_NORMAL;
+	int found = 0, i;
+	struct dlm_lockstatus *lksb = NULL;
+	int ignore;
+	u32 flags;
+	struct list_head *queue;
+
+	flags = be32_to_cpu(unlock->flags);
+
+	if (flags & LKM_GET_LVB) {
+		mlog(ML_ERROR, "bad args!  GET_LVB specified on unlock!\n");
+		return DLM_BADARGS;
+	}
+
+	if ((flags & (LKM_PUT_LVB|LKM_CANCEL)) == (LKM_PUT_LVB|LKM_CANCEL)) {
+		mlog(ML_ERROR, "bad args!  cannot modify lvb on a CANCEL "
+		     "request!\n");
+		return DLM_BADARGS;
+	}
+
+	if (unlock->namelen > DLM_LOCKID_NAME_MAX) {
+		mlog(ML_ERROR, "Invalid name length in unlock handler!\n");
+		return DLM_IVBUFLEN;
+	}
+
+	if (!dlm_grab(dlm))
+		return DLM_REJECTED;
+
+	mlog_bug_on_msg(!dlm_domain_fully_joined(dlm),
+			"Domain %s not fully joined!\n", dlm->name);
+
+	mlog(0, "lvb: %s\n", flags & LKM_PUT_LVB ? "put lvb" : "none");
+
+	res = dlm_lookup_lockres(dlm, unlock->name, unlock->namelen);
+	if (!res) {
+		/* We assume here that a no lock resource simply means
+		 * it was migrated away and destroyed before the other
+		 * node could detect it. */
+		mlog(0, "returning DLM_FORWARD -- res no longer exists\n");
+		status = DLM_FORWARD;
+		goto not_found;
+	}
+
+	queue=&res->granted;
+	found = 0;
+	spin_lock(&res->spinlock);
+	if (res->state & DLM_LOCK_RES_RECOVERING) {
+		spin_unlock(&res->spinlock);
+		mlog(0, "returning DLM_RECOVERING\n");
+		status = DLM_RECOVERING;
+		goto leave;
+	}
+
+	if (res->state & DLM_LOCK_RES_MIGRATING) {
+		spin_unlock(&res->spinlock);
+		mlog(0, "returning DLM_MIGRATING\n");
+		status = DLM_MIGRATING;
+		goto leave;
+	}
+
+	if (res->owner != dlm->node_num) {
+		spin_unlock(&res->spinlock);
+		mlog(0, "returning DLM_FORWARD -- not master\n");
+		status = DLM_FORWARD;
+		goto leave;
+	}
+
+	for (i=0; i<3; i++) {
+		list_for_each(iter, queue) {
+			lock = list_entry(iter, struct dlm_lock, list);
+			if (lock->ml.cookie == unlock->cookie &&
+		    	    lock->ml.node == unlock->node_idx) {
+				dlm_lock_get(lock);
+				found = 1;
+				break;
+			}
+		}
+		if (found)
+			break;
+		/* scan granted -> converting -> blocked queues */
+		queue++;
+	}
+	spin_unlock(&res->spinlock);
+	if (!found) {
+		status = DLM_IVLOCKID;
+		goto not_found;
+	}
+
+	/* lock was found on queue */
+	lksb = lock->lksb;
+	/* unlockast only called on originating node */
+	if (flags & LKM_PUT_LVB) {
+		lksb->flags |= DLM_LKSB_PUT_LVB;
+		memcpy(&lksb->lvb[0], &unlock->lvb[0], DLM_LVB_LEN);
+	}
+
+	/* if this is in-progress, propagate the DLM_FORWARD
+	 * all the way back out */
+	status = dlmunlock_master(dlm, res, lock, lksb, flags, &ignore);
+	if (status == DLM_FORWARD)
+		mlog(0, "lockres is in progress\n");
+
+	if (flags & LKM_PUT_LVB)
+		lksb->flags &= ~DLM_LKSB_PUT_LVB;
+
+	dlm_lockres_calc_usage(dlm, res);
+	dlm_kick_thread(dlm, res);
+
+not_found:
+	if (!found)
+		mlog(ML_ERROR, "failed to find lock to unlock! "
+			       "cookie=%"MLFu64"\n",
+		     unlock->cookie);
+	else {
+		/* send the lksb->status back to the other node */
+		status = lksb->status;
+		dlm_lock_put(lock);
+	}
+
+leave:
+	if (res)
+		dlm_lockres_put(res);
+
+	dlm_put(dlm);
+
+	return status;
+}
+
+
+static enum dlm_status dlm_get_cancel_actions(struct dlm_ctxt *dlm,
+					      struct dlm_lock_resource *res,
+					      struct dlm_lock *lock,
+					      struct dlm_lockstatus *lksb,
+					      int *actions)
+{
+	enum dlm_status status;
+
+	if (dlm_lock_on_list(&res->blocked, lock)) {
+		/* cancel this outright */
+		lksb->status = DLM_NORMAL;
+		status = DLM_NORMAL;
+		*actions = (DLM_UNLOCK_CALL_AST |
+			    DLM_UNLOCK_REMOVE_LOCK);
+	} else if (dlm_lock_on_list(&res->converting, lock)) {
+		/* cancel the request, put back on granted */
+		lksb->status = DLM_NORMAL;
+		status = DLM_NORMAL;
+		*actions = (DLM_UNLOCK_CALL_AST |
+			    DLM_UNLOCK_REMOVE_LOCK |
+			    DLM_UNLOCK_REGRANT_LOCK |
+			    DLM_UNLOCK_CLEAR_CONVERT_TYPE);
+	} else if (dlm_lock_on_list(&res->granted, lock)) {
+		/* too late, already granted.  DLM_CANCELGRANT */
+		lksb->status = DLM_CANCELGRANT;
+		status = DLM_NORMAL;
+		*actions = DLM_UNLOCK_CALL_AST;
+	} else {
+		mlog(ML_ERROR, "lock to cancel is not on any list!\n");
+		lksb->status = DLM_IVLOCKID;
+		status = DLM_IVLOCKID;
+		*actions = 0;
+	}
+	return status;
+}
+
+static enum dlm_status dlm_get_unlock_actions(struct dlm_ctxt *dlm,
+					      struct dlm_lock_resource *res,
+					      struct dlm_lock *lock,
+					      struct dlm_lockstatus *lksb,
+					      int *actions)
+{
+	enum dlm_status status;
+
+	/* unlock request */
+	if (!dlm_lock_on_list(&res->granted, lock)) {
+		lksb->status = DLM_DENIED;
+		status = DLM_DENIED;
+		dlm_error(status);
+		*actions = 0;
+	} else {
+		/* unlock granted lock */
+		lksb->status = DLM_NORMAL;
+		status = DLM_NORMAL;
+		*actions = (DLM_UNLOCK_FREE_LOCK |
+			    DLM_UNLOCK_CALL_AST |
+			    DLM_UNLOCK_REMOVE_LOCK);
+	}
+	return status;
+}
+
+/* there seems to be no point in doing this async
+ * since (even for the remote case) there is really
+ * no work to queue up... so just do it and fire the
+ * unlockast by hand when done... */
+enum dlm_status dlmunlock(struct dlm_ctxt *dlm, struct dlm_lockstatus *lksb,
+			  int flags, dlm_astunlockfunc_t *unlockast, void *data)
+{
+	enum dlm_status status;
+	struct dlm_lock_resource *res;
+	struct dlm_lock *lock = NULL;
+	int call_ast, is_master;
+
+	mlog_entry_void();
+
+	if (!lksb) {
+		dlm_error(DLM_BADARGS);
+		return DLM_BADARGS;
+	}
+
+	if (flags & ~(LKM_CANCEL | LKM_VALBLK | LKM_INVVALBLK)) {
+		dlm_error(DLM_BADPARAM);
+		return DLM_BADPARAM;
+	}
+
+	if ((flags & (LKM_VALBLK | LKM_CANCEL)) == (LKM_VALBLK | LKM_CANCEL)) {
+		mlog(0, "VALBLK given with CANCEL: ignoring VALBLK\n");
+		flags &= ~LKM_VALBLK;
+	}
+
+	if (!lksb->lockid || !lksb->lockid->lockres) {
+		dlm_error(DLM_BADPARAM);
+		return DLM_BADPARAM;
+	}
+
+	lock = lksb->lockid;
+	BUG_ON(!lock);
+	dlm_lock_get(lock);
+
+	res = lock->lockres;
+	BUG_ON(!res);
+	dlm_lockres_get(res);
+retry:
+	call_ast = 0;
+	/* need to retry up here because owner may have changed */
+	mlog(0, "lock=%p res=%p\n", lock, res);
+
+	spin_lock(&res->spinlock);
+	is_master = (res->owner == dlm->node_num);
+	spin_unlock(&res->spinlock);
+
+	if (is_master) {
+		status = dlmunlock_master(dlm, res, lock, lksb, flags,
+					  &call_ast);
+		mlog(0, "done calling dlmunlock_master: returned %d, "
+		     "call_ast is %d\n", status, call_ast);
+	} else {
+		status = dlmunlock_remote(dlm, res, lock, lksb, flags,
+					  &call_ast);
+		mlog(0, "done calling dlmunlock_remote: returned %d, "
+		     "call_ast is %d\n", status, call_ast);
+	}
+
+	if (status == DLM_RECOVERING ||
+	    status == DLM_MIGRATING ||
+	    status == DLM_FORWARD) {
+		/* We want to go away for a tiny bit to allow recovery
+		 * / migration to complete on this resource. I don't
+		 * know of any wait queue we could sleep on as this
+		 * may be happening on another node. Perhaps the
+		 * proper solution is to queue up requests on the
+		 * other end? */
+
+		/* do we want to yield(); ?? */
+		msleep(50);
+
+		mlog(0, "retrying unlock due to pending recovery/"
+		     "migration/in-progress\n");
+		goto retry;
+	}
+
+	if (call_ast) {
+		mlog(0, "calling unlockast(%p, %d)\n", data, lksb->status);
+		if (is_master) {
+			/* it is possible that there is one last bast 
+			 * pending.  make sure it is flushed, then
+			 * call the unlockast.
+			 * not an issue if this is a mastered remotely,
+			 * since this lock has been removed from the
+			 * lockres queues and cannot be found. */
+			dlm_kick_thread(dlm, NULL);
+			wait_event(dlm->ast_wq, 
+				   dlm_lock_basts_flushed(dlm, lock));
+		}
+		(*unlockast)(data, lksb->status);
+	}
+
+	if (status == DLM_NORMAL) {
+		mlog(0, "kicking the thread\n");
+		dlm_kick_thread(dlm, res);
+	} else
+		dlm_error(status);
+
+	dlm_lockres_calc_usage(dlm, res);
+	dlm_lockres_put(res);
+	dlm_lock_put(lock);
+
+	mlog(0, "returning status=%d!\n", status);
+	return status;
+}
+EXPORT_SYMBOL_GPL(dlmunlock);
+
diff --git a/fs/ocfs2/dlm/dlmver.c b/fs/ocfs2/dlm/dlmver.c
new file mode 100644
index 0000000..7ef2653
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmver.c
@@ -0,0 +1,42 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmver.c
+ *
+ * version string
+ *
+ * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include "dlmver.h"
+
+#define DLM_BUILD_VERSION "1.3.3"
+
+#define VERSION_STR "OCFS2 DLM " DLM_BUILD_VERSION
+
+void dlm_print_version(void)
+{
+	printk(KERN_INFO "%s\n", VERSION_STR);
+}
+
+MODULE_DESCRIPTION(VERSION_STR);
+
+MODULE_VERSION(DLM_BUILD_VERSION);
diff --git a/fs/ocfs2/dlm/dlmver.h b/fs/ocfs2/dlm/dlmver.h
new file mode 100644
index 0000000..f674aee
--- /dev/null
+++ b/fs/ocfs2/dlm/dlmver.h
@@ -0,0 +1,31 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmfsver.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef DLM_VER_H
+#define DLM_VER_H
+
+void dlm_print_version(void);
+
+#endif /* DLM_VER_H */
diff --git a/fs/ocfs2/dlm/userdlm.c b/fs/ocfs2/dlm/userdlm.c
new file mode 100644
index 0000000..e1fdd28
--- /dev/null
+++ b/fs/ocfs2/dlm/userdlm.c
@@ -0,0 +1,658 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * userdlm.c
+ *
+ * Code which implements the kernel side of a minimal userspace
+ * interface to our DLM.
+ *
+ * Many of the functions here are pared down versions of dlmglue.c
+ * functions.
+ *
+ * Copyright (C) 2003, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <asm/signal.h>
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/crc32.h>
+
+
+#include "cluster/nodemanager.h"
+#include "cluster/heartbeat.h"
+#include "cluster/tcp.h"
+
+#include "dlmapi.h"
+
+#include "userdlm.h"
+
+#define MLOG_MASK_PREFIX ML_DLMFS
+#include "cluster/masklog.h"
+
+static inline int user_check_wait_flag(struct user_lock_res *lockres,
+				       int flag)
+{
+	int ret;
+
+	spin_lock(&lockres->l_lock);
+	ret = lockres->l_flags & flag;
+	spin_unlock(&lockres->l_lock);
+
+	return ret;
+}
+
+static inline void user_wait_on_busy_lock(struct user_lock_res *lockres)
+
+{
+	wait_event(lockres->l_event,
+		   !user_check_wait_flag(lockres, USER_LOCK_BUSY));
+}
+
+static inline void user_wait_on_blocked_lock(struct user_lock_res *lockres)
+
+{
+	wait_event(lockres->l_event,
+		   !user_check_wait_flag(lockres, USER_LOCK_BLOCKED));
+}
+
+/* I heart container_of... */
+static inline struct dlm_ctxt *
+dlm_ctxt_from_user_lockres(struct user_lock_res *lockres)
+{
+	struct dlmfs_inode_private *ip;
+
+	ip = container_of(lockres,
+			  struct dlmfs_inode_private,
+			  ip_lockres);
+	return ip->ip_dlm;
+}
+
+static struct inode *
+user_dlm_inode_from_user_lockres(struct user_lock_res *lockres)
+{
+	struct dlmfs_inode_private *ip;
+
+	ip = container_of(lockres,
+			  struct dlmfs_inode_private,
+			  ip_lockres);
+	return &ip->ip_vfs_inode;
+}
+
+static inline void user_recover_from_dlm_error(struct user_lock_res *lockres)
+{
+	spin_lock(&lockres->l_lock);
+	lockres->l_flags &= ~USER_LOCK_BUSY;
+	spin_unlock(&lockres->l_lock);
+}
+
+#define user_log_dlm_error(_func, _stat, _lockres) do {		\
+	mlog(ML_ERROR, "Dlm error \"%s\" while calling %s on "	\
+		"resource %s: %s\n", dlm_errname(_stat), _func,	\
+		_lockres->l_name, dlm_errmsg(_stat));		\
+} while (0)
+
+/* WARNING: This function lives in a world where the only three lock
+ * levels are EX, PR, and NL. It *will* have to be adjusted when more
+ * lock types are added. */
+static inline int user_highest_compat_lock_level(int level)
+{
+	int new_level = LKM_EXMODE;
+
+	if (level == LKM_EXMODE)
+		new_level = LKM_NLMODE;
+	else if (level == LKM_PRMODE)
+		new_level = LKM_PRMODE;
+	return new_level;
+}
+
+static void user_ast(void *opaque)
+{
+	struct user_lock_res *lockres = opaque;
+	struct dlm_lockstatus *lksb;
+
+	mlog(0, "AST fired for lockres %s\n", lockres->l_name);
+
+	spin_lock(&lockres->l_lock);
+
+	lksb = &(lockres->l_lksb);
+	if (lksb->status != DLM_NORMAL) {
+		mlog(ML_ERROR, "lksb status value of %u on lockres %s\n",
+		     lksb->status, lockres->l_name);
+		spin_unlock(&lockres->l_lock);
+		return;
+	}
+
+	/* we're downconverting. */
+	if (lockres->l_requested < lockres->l_level) {
+		if (lockres->l_requested <=
+		    user_highest_compat_lock_level(lockres->l_blocking)) {
+			lockres->l_blocking = LKM_NLMODE;
+			lockres->l_flags &= ~USER_LOCK_BLOCKED;
+		}
+	}
+
+	lockres->l_level = lockres->l_requested;
+	lockres->l_requested = LKM_IVMODE;
+	lockres->l_flags |= USER_LOCK_ATTACHED;
+	lockres->l_flags &= ~USER_LOCK_BUSY;
+
+	spin_unlock(&lockres->l_lock);
+
+	wake_up(&lockres->l_event);
+}
+
+static inline void user_dlm_grab_inode_ref(struct user_lock_res *lockres)
+{
+	struct inode *inode;
+	inode = user_dlm_inode_from_user_lockres(lockres);
+	if (!igrab(inode))
+		BUG();
+}
+
+static void user_dlm_unblock_lock(void *opaque);
+
+static void __user_dlm_queue_lockres(struct user_lock_res *lockres)
+{
+	if (!(lockres->l_flags & USER_LOCK_QUEUED)) {
+		user_dlm_grab_inode_ref(lockres);
+
+		INIT_WORK(&lockres->l_work, user_dlm_unblock_lock,
+			  lockres);
+
+		queue_work(user_dlm_worker, &lockres->l_work);
+		lockres->l_flags |= USER_LOCK_QUEUED;
+	}
+}
+
+static void __user_dlm_cond_queue_lockres(struct user_lock_res *lockres)
+{
+	int queue = 0;
+
+	if (!(lockres->l_flags & USER_LOCK_BLOCKED))
+		return;
+
+	switch (lockres->l_blocking) {
+	case LKM_EXMODE:
+		if (!lockres->l_ex_holders && !lockres->l_ro_holders)
+			queue = 1;
+		break;
+	case LKM_PRMODE:
+		if (!lockres->l_ex_holders)
+			queue = 1;
+		break;
+	default:
+		BUG();
+	}
+
+	if (queue)
+		__user_dlm_queue_lockres(lockres);
+}
+
+static void user_bast(void *opaque, int level)
+{
+	struct user_lock_res *lockres = opaque;
+
+	mlog(0, "Blocking AST fired for lockres %s. Blocking level %d\n",
+		lockres->l_name, level);
+
+	spin_lock(&lockres->l_lock);
+	lockres->l_flags |= USER_LOCK_BLOCKED;
+	if (level > lockres->l_blocking)
+		lockres->l_blocking = level;
+
+	__user_dlm_queue_lockres(lockres);
+	spin_unlock(&lockres->l_lock);
+
+	wake_up(&lockres->l_event);
+}
+
+static void user_unlock_ast(void *opaque, enum dlm_status status)
+{
+	struct user_lock_res *lockres = opaque;
+
+	mlog(0, "UNLOCK AST called on lock %s\n", lockres->l_name);
+
+	if (status != DLM_NORMAL)
+		mlog(ML_ERROR, "Dlm returns status %d\n", status);
+
+	spin_lock(&lockres->l_lock);
+	if (lockres->l_flags & USER_LOCK_IN_TEARDOWN)
+		lockres->l_level = LKM_IVMODE;
+	else {
+		lockres->l_requested = LKM_IVMODE; /* cancel an
+						    * upconvert
+						    * request. */
+		lockres->l_flags &= ~USER_LOCK_IN_CANCEL;
+		/* we want the unblock thread to look at it again
+		 * now. */
+		__user_dlm_queue_lockres(lockres);
+	}
+
+	lockres->l_flags &= ~USER_LOCK_BUSY;
+	spin_unlock(&lockres->l_lock);
+
+	wake_up(&lockres->l_event);
+}
+
+static inline void user_dlm_drop_inode_ref(struct user_lock_res *lockres)
+{
+	struct inode *inode;
+	inode = user_dlm_inode_from_user_lockres(lockres);
+	iput(inode);
+}
+
+static void user_dlm_unblock_lock(void *opaque)
+{
+	int new_level, status;
+	struct user_lock_res *lockres = (struct user_lock_res *) opaque;
+	struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres);
+
+	mlog(0, "processing lockres %s\n", lockres->l_name);
+
+	spin_lock(&lockres->l_lock);
+
+	BUG_ON(!(lockres->l_flags & USER_LOCK_BLOCKED));
+	BUG_ON(!(lockres->l_flags & USER_LOCK_QUEUED));
+
+	/* notice that we don't clear USER_LOCK_BLOCKED here. That's
+	 * for user_ast to do. */
+	lockres->l_flags &= ~USER_LOCK_QUEUED;
+
+	if (lockres->l_flags & USER_LOCK_IN_TEARDOWN) {
+		mlog(0, "lock is in teardown so we do nothing\n");
+		spin_unlock(&lockres->l_lock);
+		goto drop_ref;
+	}
+
+	if (lockres->l_flags & USER_LOCK_BUSY) {
+		mlog(0, "BUSY flag detected...\n");
+		if (lockres->l_flags & USER_LOCK_IN_CANCEL) {
+			spin_unlock(&lockres->l_lock);
+			goto drop_ref;
+		}
+
+		lockres->l_flags |= USER_LOCK_IN_CANCEL;
+		spin_unlock(&lockres->l_lock);
+
+		status = dlmunlock(dlm,
+				   &lockres->l_lksb,
+				   LKM_CANCEL,
+				   user_unlock_ast,
+				   lockres);
+		if (status == DLM_CANCELGRANT) {
+			/* If we got this, then the ast was fired
+			 * before we could cancel. We cleanup our
+			 * state, and restart the function. */
+			spin_lock(&lockres->l_lock);
+			lockres->l_flags &= ~USER_LOCK_IN_CANCEL;
+			spin_unlock(&lockres->l_lock);
+		} else if (status != DLM_NORMAL)
+			user_log_dlm_error("dlmunlock", status, lockres);
+		goto drop_ref;
+	}
+
+	/* If there are still incompat holders, we can exit safely
+	 * without worrying about re-queueing this lock as that will
+	 * happen on the last call to user_cluster_unlock. */
+	if ((lockres->l_blocking == LKM_EXMODE)
+	    && (lockres->l_ex_holders || lockres->l_ro_holders)) {
+		spin_unlock(&lockres->l_lock);
+		mlog(0, "can't downconvert for ex: ro = %u, ex = %u\n",
+			lockres->l_ro_holders, lockres->l_ex_holders);
+		goto drop_ref;
+	}
+
+	if ((lockres->l_blocking == LKM_PRMODE)
+	    && lockres->l_ex_holders) {
+		spin_unlock(&lockres->l_lock);
+		mlog(0, "can't downconvert for pr: ex = %u\n",
+			lockres->l_ex_holders);
+		goto drop_ref;
+	}
+
+	/* yay, we can downconvert now. */
+	new_level = user_highest_compat_lock_level(lockres->l_blocking);
+	lockres->l_requested = new_level;
+	lockres->l_flags |= USER_LOCK_BUSY;
+	mlog(0, "Downconvert lock from %d to %d\n",
+		lockres->l_level, new_level);
+	spin_unlock(&lockres->l_lock);
+
+	/* need lock downconvert request now... */
+	status = dlmlock(dlm,
+			 new_level,
+			 &lockres->l_lksb,
+			 LKM_CONVERT|LKM_VALBLK,
+			 lockres->l_name,
+			 user_ast,
+			 lockres,
+			 user_bast);
+	if (status != DLM_NORMAL) {
+		user_log_dlm_error("dlmlock", status, lockres);
+		user_recover_from_dlm_error(lockres);
+	}
+
+drop_ref:
+	user_dlm_drop_inode_ref(lockres);
+}
+
+static inline void user_dlm_inc_holders(struct user_lock_res *lockres,
+					int level)
+{
+	switch(level) {
+	case LKM_EXMODE:
+		lockres->l_ex_holders++;
+		break;
+	case LKM_PRMODE:
+		lockres->l_ro_holders++;
+		break;
+	default:
+		BUG();
+	}
+}
+
+/* predict what lock level we'll be dropping down to on behalf
+ * of another node, and return true if the currently wanted
+ * level will be compatible with it. */
+static inline int
+user_may_continue_on_blocked_lock(struct user_lock_res *lockres,
+				  int wanted)
+{
+	BUG_ON(!(lockres->l_flags & USER_LOCK_BLOCKED));
+
+	return wanted <= user_highest_compat_lock_level(lockres->l_blocking);
+}
+
+int user_dlm_cluster_lock(struct user_lock_res *lockres,
+			  int level,
+			  int lkm_flags)
+{
+	int status, local_flags;
+	struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres);
+
+	if (level != LKM_EXMODE &&
+	    level != LKM_PRMODE) {
+		mlog(ML_ERROR, "lockres %s: invalid request!\n",
+		     lockres->l_name);
+		status = -EINVAL;
+		goto bail;
+	}
+
+	mlog(0, "lockres %s: asking for %s lock, passed flags = 0x%x\n",
+		lockres->l_name,
+		(level == LKM_EXMODE) ? "LKM_EXMODE" : "LKM_PRMODE",
+		lkm_flags);
+
+again:
+	if (signal_pending(current)) {
+		status = -ERESTARTSYS;
+		goto bail;
+	}
+
+	spin_lock(&lockres->l_lock);
+
+	/* We only compare against the currently granted level
+	 * here. If the lock is blocked waiting on a downconvert,
+	 * we'll get caught below. */
+	if ((lockres->l_flags & USER_LOCK_BUSY) &&
+	    (level > lockres->l_level)) {
+		/* is someone sitting in dlm_lock? If so, wait on
+		 * them. */
+		spin_unlock(&lockres->l_lock);
+
+		user_wait_on_busy_lock(lockres);
+		goto again;
+	}
+
+	if ((lockres->l_flags & USER_LOCK_BLOCKED) &&
+	    (!user_may_continue_on_blocked_lock(lockres, level))) {
+		/* is the lock is currently blocked on behalf of
+		 * another node */
+		spin_unlock(&lockres->l_lock);
+
+		user_wait_on_blocked_lock(lockres);
+		goto again;
+	}
+
+	if (level > lockres->l_level) {
+		local_flags = lkm_flags | LKM_VALBLK;
+		if (lockres->l_level != LKM_IVMODE)
+			local_flags |= LKM_CONVERT;
+
+		lockres->l_requested = level;
+		lockres->l_flags |= USER_LOCK_BUSY;
+		spin_unlock(&lockres->l_lock);
+
+		BUG_ON(level == LKM_IVMODE);
+		BUG_ON(level == LKM_NLMODE);
+
+		mlog(0, "lock %s, get lock from %d to level = %d\n",
+			lockres->l_name, lockres->l_level, level);
+
+		/* call dlm_lock to upgrade lock now */
+		status = dlmlock(dlm,
+				 level,
+				 &lockres->l_lksb,
+				 local_flags,
+				 lockres->l_name,
+				 user_ast,
+				 lockres,
+				 user_bast);
+		if (status != DLM_NORMAL) {
+			if ((lkm_flags & LKM_NOQUEUE) &&
+			    (status == DLM_NOTQUEUED))
+				status = -EAGAIN;
+			else {
+				user_log_dlm_error("dlmlock", status, lockres);
+				status = -EINVAL;
+			}
+			user_recover_from_dlm_error(lockres);
+			goto bail;
+		}
+
+		mlog(0, "lock %s, successfull return from dlmlock\n",
+			lockres->l_name);
+
+		user_wait_on_busy_lock(lockres);
+		goto again;
+	}
+
+	user_dlm_inc_holders(lockres, level);
+	spin_unlock(&lockres->l_lock);
+
+	mlog(0, "lockres %s: Got %s lock!\n", lockres->l_name,
+		(level == LKM_EXMODE) ? "LKM_EXMODE" : "LKM_PRMODE");
+
+	status = 0;
+bail:
+	return status;
+}
+
+static inline void user_dlm_dec_holders(struct user_lock_res *lockres,
+					int level)
+{
+	switch(level) {
+	case LKM_EXMODE:
+		BUG_ON(!lockres->l_ex_holders);
+		lockres->l_ex_holders--;
+		break;
+	case LKM_PRMODE:
+		BUG_ON(!lockres->l_ro_holders);
+		lockres->l_ro_holders--;
+		break;
+	default:
+		BUG();
+	}
+}
+
+void user_dlm_cluster_unlock(struct user_lock_res *lockres,
+			     int level)
+{
+	if (level != LKM_EXMODE &&
+	    level != LKM_PRMODE) {
+		mlog(ML_ERROR, "lockres %s: invalid request!\n", lockres->l_name);
+		return;
+	}
+
+	mlog(0, "lockres %s: dropping %s lock\n", lockres->l_name,
+		(level == LKM_EXMODE) ? "LKM_EXMODE" : "LKM_PRMODE");
+
+	spin_lock(&lockres->l_lock);
+	user_dlm_dec_holders(lockres, level);
+	__user_dlm_cond_queue_lockres(lockres);
+	spin_unlock(&lockres->l_lock);
+}
+
+void user_dlm_write_lvb(struct inode *inode,
+			const char *val,
+			unsigned int len)
+{
+	struct user_lock_res *lockres = &DLMFS_I(inode)->ip_lockres;
+	char *lvb = lockres->l_lksb.lvb;
+
+	BUG_ON(len > DLM_LVB_LEN);
+
+	spin_lock(&lockres->l_lock);
+
+	BUG_ON(lockres->l_level < LKM_EXMODE);
+	memcpy(lvb, val, len);
+
+	spin_unlock(&lockres->l_lock);
+}
+
+void user_dlm_read_lvb(struct inode *inode,
+		       char *val,
+		       unsigned int len)
+{
+	struct user_lock_res *lockres = &DLMFS_I(inode)->ip_lockres;
+	char *lvb = lockres->l_lksb.lvb;
+
+	BUG_ON(len > DLM_LVB_LEN);
+
+	spin_lock(&lockres->l_lock);
+
+	BUG_ON(lockres->l_level < LKM_PRMODE);
+	memcpy(val, lvb, len);
+
+	spin_unlock(&lockres->l_lock);
+}
+
+void user_dlm_lock_res_init(struct user_lock_res *lockres,
+			    struct dentry *dentry)
+{
+	memset(lockres, 0, sizeof(*lockres));
+
+	spin_lock_init(&lockres->l_lock);
+	init_waitqueue_head(&lockres->l_event);
+	lockres->l_level = LKM_IVMODE;
+	lockres->l_requested = LKM_IVMODE;
+	lockres->l_blocking = LKM_IVMODE;
+
+	/* should have been checked before getting here. */
+	BUG_ON(dentry->d_name.len >= USER_DLM_LOCK_ID_MAX_LEN);
+
+	memcpy(lockres->l_name,
+	       dentry->d_name.name,
+	       dentry->d_name.len);
+}
+
+int user_dlm_destroy_lock(struct user_lock_res *lockres)
+{
+	int status = -EBUSY;
+	struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres);
+
+	mlog(0, "asked to destroy %s\n", lockres->l_name);
+
+	spin_lock(&lockres->l_lock);
+	while (lockres->l_flags & USER_LOCK_BUSY) {
+		spin_unlock(&lockres->l_lock);
+
+		mlog(0, "lock %s is busy\n", lockres->l_name);
+
+		user_wait_on_busy_lock(lockres);
+
+		spin_lock(&lockres->l_lock);
+	}
+
+	if (lockres->l_ro_holders || lockres->l_ex_holders) {
+		spin_unlock(&lockres->l_lock);
+		mlog(0, "lock %s has holders\n", lockres->l_name);
+		goto bail;
+	}
+
+	status = 0;
+	if (!(lockres->l_flags & USER_LOCK_ATTACHED)) {
+		spin_unlock(&lockres->l_lock);
+		mlog(0, "lock %s is not attached\n", lockres->l_name);
+		goto bail;
+	}
+
+	lockres->l_flags &= ~USER_LOCK_ATTACHED;
+	lockres->l_flags |= USER_LOCK_BUSY;
+	lockres->l_flags |= USER_LOCK_IN_TEARDOWN;
+	spin_unlock(&lockres->l_lock);
+
+	mlog(0, "unlocking lockres %s\n", lockres->l_name);
+	status = dlmunlock(dlm,
+			   &lockres->l_lksb,
+			   LKM_VALBLK,
+			   user_unlock_ast,
+			   lockres);
+	if (status != DLM_NORMAL) {
+		user_log_dlm_error("dlmunlock", status, lockres);
+		status = -EINVAL;
+		goto bail;
+	}
+
+	user_wait_on_busy_lock(lockres);
+
+	status = 0;
+bail:
+	return status;
+}
+
+struct dlm_ctxt *user_dlm_register_context(struct qstr *name)
+{
+	struct dlm_ctxt *dlm;
+	u32 dlm_key;
+	char *domain;
+
+	domain = kmalloc(name->len + 1, GFP_KERNEL);
+	if (!domain) {
+		mlog_errno(-ENOMEM);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	dlm_key = crc32_le(0, name->name, name->len);
+
+	snprintf(domain, name->len + 1, "%.*s", name->len, name->name);
+
+	dlm = dlm_register_domain(domain, dlm_key);
+	if (IS_ERR(dlm))
+		mlog_errno(PTR_ERR(dlm));
+
+	kfree(domain);
+	return dlm;
+}
+
+void user_dlm_unregister_context(struct dlm_ctxt *dlm)
+{
+	dlm_unregister_domain(dlm);
+}
diff --git a/fs/ocfs2/dlm/userdlm.h b/fs/ocfs2/dlm/userdlm.h
new file mode 100644
index 0000000..04178bc
--- /dev/null
+++ b/fs/ocfs2/dlm/userdlm.h
@@ -0,0 +1,111 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * userdlm.h
+ *
+ * Userspace dlm defines
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+
+#ifndef USERDLM_H
+#define USERDLM_H
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+
+/* user_lock_res->l_flags flags. */
+#define USER_LOCK_ATTACHED      (0x00000001) /* have we initialized
+					       * the lvb */
+#define USER_LOCK_BUSY          (0x00000002) /* we are currently in
+					       * dlm_lock */
+#define USER_LOCK_BLOCKED       (0x00000004) /* blocked waiting to
+					      * downconvert*/
+#define USER_LOCK_IN_TEARDOWN   (0x00000008) /* we're currently
+					      * destroying this
+					      * lock. */
+#define USER_LOCK_QUEUED        (0x00000010) /* lock is on the
+					      * workqueue */
+#define USER_LOCK_IN_CANCEL     (0x00000020)
+
+struct user_lock_res {
+	spinlock_t               l_lock;
+
+	int                      l_flags;
+
+#define USER_DLM_LOCK_ID_MAX_LEN  32
+	char                     l_name[USER_DLM_LOCK_ID_MAX_LEN];
+	int                      l_level;
+	unsigned int             l_ro_holders;
+	unsigned int             l_ex_holders;
+	struct dlm_lockstatus    l_lksb;
+
+	int                      l_requested;
+	int                      l_blocking;
+
+	wait_queue_head_t        l_event;
+
+	struct work_struct       l_work;
+};
+
+extern struct workqueue_struct *user_dlm_worker;
+
+void user_dlm_lock_res_init(struct user_lock_res *lockres,
+			    struct dentry *dentry);
+int user_dlm_destroy_lock(struct user_lock_res *lockres);
+int user_dlm_cluster_lock(struct user_lock_res *lockres,
+			  int level,
+			  int lkm_flags);
+void user_dlm_cluster_unlock(struct user_lock_res *lockres,
+			     int level);
+void user_dlm_write_lvb(struct inode *inode,
+			const char *val,
+			unsigned int len);
+void user_dlm_read_lvb(struct inode *inode,
+		       char *val,
+		       unsigned int len);
+struct dlm_ctxt *user_dlm_register_context(struct qstr *name);
+void user_dlm_unregister_context(struct dlm_ctxt *dlm);
+
+struct dlmfs_inode_private {
+	struct dlm_ctxt             *ip_dlm;
+
+	struct user_lock_res ip_lockres; /* unused for directories. */
+	struct inode         *ip_parent;
+
+	struct inode         ip_vfs_inode;
+};
+
+static inline struct dlmfs_inode_private *
+DLMFS_I(struct inode *inode)
+{
+        return container_of(inode,
+			    struct dlmfs_inode_private,
+			    ip_vfs_inode);
+}
+
+struct dlmfs_filp_private {
+	int                  fp_lock_level;
+};
+
+#define DLMFS_MAGIC	0x76a9f425
+
+#endif /* USERDLM_H */
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
new file mode 100644
index 0000000..e971ec2
--- /dev/null
+++ b/fs/ocfs2/dlmglue.c
@@ -0,0 +1,2904 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmglue.c
+ *
+ * Code which implements an OCFS2 specific interface to our DLM.
+ *
+ * Copyright (C) 2003, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/smp_lock.h>
+#include <linux/crc32.h>
+#include <linux/kthread.h>
+#include <linux/pagemap.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#include <cluster/heartbeat.h>
+#include <cluster/nodemanager.h>
+#include <cluster/tcp.h>
+
+#include <dlm/dlmapi.h>
+
+#define MLOG_MASK_PREFIX ML_DLM_GLUE
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "heartbeat.h"
+#include "inode.h"
+#include "journal.h"
+#include "slot_map.h"
+#include "super.h"
+#include "uptodate.h"
+#include "vote.h"
+
+#include "buffer_head_io.h"
+
+struct ocfs2_mask_waiter {
+	struct list_head	mw_item;
+	int			mw_status;
+	struct completion	mw_complete;
+	unsigned long		mw_mask;
+	unsigned long		mw_goal;
+};
+
+static void ocfs2_inode_ast_func(void *opaque);
+static void ocfs2_inode_bast_func(void *opaque,
+				  int level);
+static void ocfs2_super_ast_func(void *opaque);
+static void ocfs2_super_bast_func(void *opaque,
+				  int level);
+static void ocfs2_rename_ast_func(void *opaque);
+static void ocfs2_rename_bast_func(void *opaque,
+				   int level);
+
+/* so far, all locks have gotten along with the same unlock ast */
+static void ocfs2_unlock_ast_func(void *opaque,
+				  enum dlm_status status);
+static int ocfs2_do_unblock_meta(struct inode *inode,
+				 int *requeue);
+static int ocfs2_unblock_meta(struct ocfs2_lock_res *lockres,
+			      int *requeue);
+static int ocfs2_unblock_data(struct ocfs2_lock_res *lockres,
+			      int *requeue);
+static int ocfs2_unblock_inode_lock(struct ocfs2_lock_res *lockres,
+			      int *requeue);
+static int ocfs2_unblock_osb_lock(struct ocfs2_lock_res *lockres,
+				  int *requeue);
+typedef void (ocfs2_convert_worker_t)(struct ocfs2_lock_res *, int);
+static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb,
+				      struct ocfs2_lock_res *lockres,
+				      int *requeue,
+				      ocfs2_convert_worker_t *worker);
+
+struct ocfs2_lock_res_ops {
+	void (*ast)(void *);
+	void (*bast)(void *, int);
+	void (*unlock_ast)(void *, enum dlm_status);
+	int  (*unblock)(struct ocfs2_lock_res *, int *);
+};
+
+static struct ocfs2_lock_res_ops ocfs2_inode_rw_lops = {
+	.ast		= ocfs2_inode_ast_func,
+	.bast		= ocfs2_inode_bast_func,
+	.unlock_ast	= ocfs2_unlock_ast_func,
+	.unblock	= ocfs2_unblock_inode_lock,
+};
+
+static struct ocfs2_lock_res_ops ocfs2_inode_meta_lops = {
+	.ast		= ocfs2_inode_ast_func,
+	.bast		= ocfs2_inode_bast_func,
+	.unlock_ast	= ocfs2_unlock_ast_func,
+	.unblock	= ocfs2_unblock_meta,
+};
+
+static void ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres,
+				      int blocking);
+
+static struct ocfs2_lock_res_ops ocfs2_inode_data_lops = {
+	.ast		= ocfs2_inode_ast_func,
+	.bast		= ocfs2_inode_bast_func,
+	.unlock_ast	= ocfs2_unlock_ast_func,
+	.unblock	= ocfs2_unblock_data,
+};
+
+static struct ocfs2_lock_res_ops ocfs2_super_lops = {
+	.ast		= ocfs2_super_ast_func,
+	.bast		= ocfs2_super_bast_func,
+	.unlock_ast	= ocfs2_unlock_ast_func,
+	.unblock	= ocfs2_unblock_osb_lock,
+};
+
+static struct ocfs2_lock_res_ops ocfs2_rename_lops = {
+	.ast		= ocfs2_rename_ast_func,
+	.bast		= ocfs2_rename_bast_func,
+	.unlock_ast	= ocfs2_unlock_ast_func,
+	.unblock	= ocfs2_unblock_osb_lock,
+};
+
+static inline int ocfs2_is_inode_lock(struct ocfs2_lock_res *lockres)
+{
+	return lockres->l_type == OCFS2_LOCK_TYPE_META ||
+		lockres->l_type == OCFS2_LOCK_TYPE_DATA ||
+		lockres->l_type == OCFS2_LOCK_TYPE_RW;
+}
+
+static inline int ocfs2_is_super_lock(struct ocfs2_lock_res *lockres)
+{
+	return lockres->l_type == OCFS2_LOCK_TYPE_SUPER;
+}
+
+static inline int ocfs2_is_rename_lock(struct ocfs2_lock_res *lockres)
+{
+	return lockres->l_type == OCFS2_LOCK_TYPE_RENAME;
+}
+
+static inline struct ocfs2_super *ocfs2_lock_res_super(struct ocfs2_lock_res *lockres)
+{
+	BUG_ON(!ocfs2_is_super_lock(lockres)
+	       && !ocfs2_is_rename_lock(lockres));
+
+	return (struct ocfs2_super *) lockres->l_priv;
+}
+
+static inline struct inode *ocfs2_lock_res_inode(struct ocfs2_lock_res *lockres)
+{
+	BUG_ON(!ocfs2_is_inode_lock(lockres));
+
+	return (struct inode *) lockres->l_priv;
+}
+
+static int ocfs2_lock_create(struct ocfs2_super *osb,
+			     struct ocfs2_lock_res *lockres,
+			     int level,
+			     int dlm_flags);
+static inline int ocfs2_may_continue_on_blocked_lock(struct ocfs2_lock_res *lockres,
+						     int wanted);
+static void ocfs2_cluster_unlock(struct ocfs2_super *osb,
+				 struct ocfs2_lock_res *lockres,
+				 int level);
+static inline void ocfs2_generic_handle_downconvert_action(struct ocfs2_lock_res *lockres);
+static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lockres);
+static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *lockres);
+static int ocfs2_generic_handle_bast(struct ocfs2_lock_res *lockres, int level);
+static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb,
+					struct ocfs2_lock_res *lockres);
+static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
+						int convert);
+#define ocfs2_log_dlm_error(_func, _stat, _lockres) do {	\
+	mlog(ML_ERROR, "Dlm error \"%s\" while calling %s on "	\
+		"resource %s: %s\n", dlm_errname(_stat), _func,	\
+		_lockres->l_name, dlm_errmsg(_stat));		\
+} while (0)
+static void ocfs2_vote_on_unlock(struct ocfs2_super *osb,
+				 struct ocfs2_lock_res *lockres);
+static int ocfs2_meta_lock_update(struct inode *inode,
+				  struct buffer_head **bh);
+static void ocfs2_drop_osb_locks(struct ocfs2_super *osb);
+static inline int ocfs2_highest_compat_lock_level(int level);
+static inline int ocfs2_can_downconvert_meta_lock(struct inode *inode,
+						  struct ocfs2_lock_res *lockres,
+						  int new_level);
+
+static char *ocfs2_lock_type_strings[] = {
+	[OCFS2_LOCK_TYPE_META] = "Meta",
+	[OCFS2_LOCK_TYPE_DATA] = "Data",
+	[OCFS2_LOCK_TYPE_SUPER] = "Super",
+	[OCFS2_LOCK_TYPE_RENAME] = "Rename",
+	/* Need to differntiate from [R]ename.. serializing writes is the
+	 * important job it does, anyway. */
+	[OCFS2_LOCK_TYPE_RW] = "Write/Read",
+};
+
+static char *ocfs2_lock_type_string(enum ocfs2_lock_type type)
+{
+	mlog_bug_on_msg(type >= OCFS2_NUM_LOCK_TYPES, "%d\n", type);
+	return ocfs2_lock_type_strings[type];
+}
+
+static void ocfs2_build_lock_name(enum ocfs2_lock_type type,
+				  u64 blkno,
+				  u32 generation,
+				  char *name)
+{
+	int len;
+
+	mlog_entry_void();
+
+	BUG_ON(type >= OCFS2_NUM_LOCK_TYPES);
+
+	len = snprintf(name, OCFS2_LOCK_ID_MAX_LEN, "%c%s%016"MLFx64"%08x",
+		       ocfs2_lock_type_char(type), OCFS2_LOCK_ID_PAD, blkno,
+		       generation);
+
+	BUG_ON(len != (OCFS2_LOCK_ID_MAX_LEN - 1));
+
+	mlog(0, "built lock resource with name: %s\n", name);
+
+	mlog_exit_void();
+}
+
+static spinlock_t ocfs2_dlm_tracking_lock = SPIN_LOCK_UNLOCKED;
+
+static void ocfs2_add_lockres_tracking(struct ocfs2_lock_res *res,
+				       struct ocfs2_dlm_debug *dlm_debug)
+{
+	mlog(0, "Add tracking for lockres %s\n", res->l_name);
+
+	spin_lock(&ocfs2_dlm_tracking_lock);
+	list_add(&res->l_debug_list, &dlm_debug->d_lockres_tracking);
+	spin_unlock(&ocfs2_dlm_tracking_lock);
+}
+
+static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res)
+{
+	spin_lock(&ocfs2_dlm_tracking_lock);
+	if (!list_empty(&res->l_debug_list))
+		list_del_init(&res->l_debug_list);
+	spin_unlock(&ocfs2_dlm_tracking_lock);
+}
+
+static void ocfs2_lock_res_init_common(struct ocfs2_super *osb,
+				       struct ocfs2_lock_res *res,
+				       enum ocfs2_lock_type type,
+				       u64 blkno,
+				       u32 generation,
+				       struct ocfs2_lock_res_ops *ops,
+				       void *priv)
+{
+	ocfs2_build_lock_name(type, blkno, generation, res->l_name);
+
+	res->l_type          = type;
+	res->l_ops           = ops;
+	res->l_priv          = priv;
+
+	res->l_level         = LKM_IVMODE;
+	res->l_requested     = LKM_IVMODE;
+	res->l_blocking      = LKM_IVMODE;
+	res->l_action        = OCFS2_AST_INVALID;
+	res->l_unlock_action = OCFS2_UNLOCK_INVALID;
+
+	res->l_flags         = OCFS2_LOCK_INITIALIZED;
+
+	ocfs2_add_lockres_tracking(res, osb->osb_dlm_debug);
+}
+
+void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res)
+{
+	/* This also clears out the lock status block */
+	memset(res, 0, sizeof(struct ocfs2_lock_res));
+	spin_lock_init(&res->l_lock);
+	init_waitqueue_head(&res->l_event);
+	INIT_LIST_HEAD(&res->l_blocked_list);
+	INIT_LIST_HEAD(&res->l_mask_waiters);
+}
+
+void ocfs2_inode_lock_res_init(struct ocfs2_lock_res *res,
+			       enum ocfs2_lock_type type,
+			       struct inode *inode)
+{
+	struct ocfs2_lock_res_ops *ops;
+
+	switch(type) {
+		case OCFS2_LOCK_TYPE_RW:
+			ops = &ocfs2_inode_rw_lops;
+			break;
+		case OCFS2_LOCK_TYPE_META:
+			ops = &ocfs2_inode_meta_lops;
+			break;
+		case OCFS2_LOCK_TYPE_DATA:
+			ops = &ocfs2_inode_data_lops;
+			break;
+		default:
+			mlog_bug_on_msg(1, "type: %d\n", type);
+			ops = NULL; /* thanks, gcc */
+			break;
+	};
+
+	ocfs2_lock_res_init_common(OCFS2_SB(inode->i_sb), res, type,
+				   OCFS2_I(inode)->ip_blkno,
+				   inode->i_generation, ops, inode);
+}
+
+static void ocfs2_super_lock_res_init(struct ocfs2_lock_res *res,
+				      struct ocfs2_super *osb)
+{
+	/* Superblock lockres doesn't come from a slab so we call init
+	 * once on it manually.  */
+	ocfs2_lock_res_init_once(res);
+	ocfs2_lock_res_init_common(osb, res, OCFS2_LOCK_TYPE_SUPER,
+				   OCFS2_SUPER_BLOCK_BLKNO, 0,
+				   &ocfs2_super_lops, osb);
+}
+
+static void ocfs2_rename_lock_res_init(struct ocfs2_lock_res *res,
+				       struct ocfs2_super *osb)
+{
+	/* Rename lockres doesn't come from a slab so we call init
+	 * once on it manually.  */
+	ocfs2_lock_res_init_once(res);
+	ocfs2_lock_res_init_common(osb, res, OCFS2_LOCK_TYPE_RENAME, 0, 0,
+				   &ocfs2_rename_lops, osb);
+}
+
+void ocfs2_lock_res_free(struct ocfs2_lock_res *res)
+{
+	mlog_entry_void();
+
+	if (!(res->l_flags & OCFS2_LOCK_INITIALIZED))
+		return;
+
+	ocfs2_remove_lockres_tracking(res);
+
+	mlog_bug_on_msg(!list_empty(&res->l_blocked_list),
+			"Lockres %s is on the blocked list\n",
+			res->l_name);
+	mlog_bug_on_msg(!list_empty(&res->l_mask_waiters),
+			"Lockres %s has mask waiters pending\n",
+			res->l_name);
+	mlog_bug_on_msg(spin_is_locked(&res->l_lock),
+			"Lockres %s is locked\n",
+			res->l_name);
+	mlog_bug_on_msg(res->l_ro_holders,
+			"Lockres %s has %u ro holders\n",
+			res->l_name, res->l_ro_holders);
+	mlog_bug_on_msg(res->l_ex_holders,
+			"Lockres %s has %u ex holders\n",
+			res->l_name, res->l_ex_holders);
+
+	/* Need to clear out the lock status block for the dlm */
+	memset(&res->l_lksb, 0, sizeof(res->l_lksb));
+
+	res->l_flags = 0UL;
+	mlog_exit_void();
+}
+
+static inline void ocfs2_inc_holders(struct ocfs2_lock_res *lockres,
+				     int level)
+{
+	mlog_entry_void();
+
+	BUG_ON(!lockres);
+
+	switch(level) {
+	case LKM_EXMODE:
+		lockres->l_ex_holders++;
+		break;
+	case LKM_PRMODE:
+		lockres->l_ro_holders++;
+		break;
+	default:
+		BUG();
+	}
+
+	mlog_exit_void();
+}
+
+static inline void ocfs2_dec_holders(struct ocfs2_lock_res *lockres,
+				     int level)
+{
+	mlog_entry_void();
+
+	BUG_ON(!lockres);
+
+	switch(level) {
+	case LKM_EXMODE:
+		BUG_ON(!lockres->l_ex_holders);
+		lockres->l_ex_holders--;
+		break;
+	case LKM_PRMODE:
+		BUG_ON(!lockres->l_ro_holders);
+		lockres->l_ro_holders--;
+		break;
+	default:
+		BUG();
+	}
+	mlog_exit_void();
+}
+
+/* WARNING: This function lives in a world where the only three lock
+ * levels are EX, PR, and NL. It *will* have to be adjusted when more
+ * lock types are added. */
+static inline int ocfs2_highest_compat_lock_level(int level)
+{
+	int new_level = LKM_EXMODE;
+
+	if (level == LKM_EXMODE)
+		new_level = LKM_NLMODE;
+	else if (level == LKM_PRMODE)
+		new_level = LKM_PRMODE;
+	return new_level;
+}
+
+static void lockres_set_flags(struct ocfs2_lock_res *lockres,
+			      unsigned long newflags)
+{
+	struct list_head *pos, *tmp;
+	struct ocfs2_mask_waiter *mw;
+
+ 	assert_spin_locked(&lockres->l_lock);
+
+	lockres->l_flags = newflags;
+
+	list_for_each_safe(pos, tmp, &lockres->l_mask_waiters) {
+		mw = list_entry(pos, struct ocfs2_mask_waiter, mw_item);
+		if ((lockres->l_flags & mw->mw_mask) != mw->mw_goal)
+			continue;
+
+		list_del_init(&mw->mw_item);
+		mw->mw_status = 0;
+		complete(&mw->mw_complete);
+	}
+}
+static void lockres_or_flags(struct ocfs2_lock_res *lockres, unsigned long or)
+{
+	lockres_set_flags(lockres, lockres->l_flags | or);
+}
+static void lockres_clear_flags(struct ocfs2_lock_res *lockres,
+				unsigned long clear)
+{
+	lockres_set_flags(lockres, lockres->l_flags & ~clear);
+}
+
+static inline void ocfs2_generic_handle_downconvert_action(struct ocfs2_lock_res *lockres)
+{
+	mlog_entry_void();
+
+	BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BUSY));
+	BUG_ON(!(lockres->l_flags & OCFS2_LOCK_ATTACHED));
+	BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BLOCKED));
+	BUG_ON(lockres->l_blocking <= LKM_NLMODE);
+
+	lockres->l_level = lockres->l_requested;
+	if (lockres->l_level <=
+	    ocfs2_highest_compat_lock_level(lockres->l_blocking)) {
+		lockres->l_blocking = LKM_NLMODE;
+		lockres_clear_flags(lockres, OCFS2_LOCK_BLOCKED);
+	}
+	lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
+
+	mlog_exit_void();
+}
+
+static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lockres)
+{
+	mlog_entry_void();
+
+	BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BUSY));
+	BUG_ON(!(lockres->l_flags & OCFS2_LOCK_ATTACHED));
+
+	/* Convert from RO to EX doesn't really need anything as our
+	 * information is already up to data. Convert from NL to
+	 * *anything* however should mark ourselves as needing an
+	 * update */
+	if (lockres->l_level == LKM_NLMODE)
+		lockres_or_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
+
+	lockres->l_level = lockres->l_requested;
+	lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
+
+	mlog_exit_void();
+}
+
+static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *lockres)
+{
+	mlog_entry_void();
+
+	BUG_ON((!lockres->l_flags & OCFS2_LOCK_BUSY));
+	BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED);
+
+	if (lockres->l_requested > LKM_NLMODE &&
+	    !(lockres->l_flags & OCFS2_LOCK_LOCAL))
+		lockres_or_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
+
+	lockres->l_level = lockres->l_requested;
+	lockres_or_flags(lockres, OCFS2_LOCK_ATTACHED);
+	lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
+
+	mlog_exit_void();
+}
+
+static void ocfs2_inode_ast_func(void *opaque)
+{
+	struct ocfs2_lock_res *lockres = opaque;
+	struct inode *inode;
+	struct dlm_lockstatus *lksb;
+	unsigned long flags;
+
+	mlog_entry_void();
+
+	inode = ocfs2_lock_res_inode(lockres);
+
+	mlog(0, "AST fired for inode %"MLFu64", l_action = %u, type = %s\n",
+	     OCFS2_I(inode)->ip_blkno, lockres->l_action,
+	     ocfs2_lock_type_string(lockres->l_type));
+
+	BUG_ON(!ocfs2_is_inode_lock(lockres));
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+
+	lksb = &(lockres->l_lksb);
+	if (lksb->status != DLM_NORMAL) {
+		mlog(ML_ERROR, "ocfs2_inode_ast_func: lksb status value of %u "
+		     "on inode %"MLFu64"\n", lksb->status,
+		     OCFS2_I(inode)->ip_blkno);
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		mlog_exit_void();
+		return;
+	}
+
+	switch(lockres->l_action) {
+	case OCFS2_AST_ATTACH:
+		ocfs2_generic_handle_attach_action(lockres);
+		lockres_clear_flags(lockres, OCFS2_LOCK_LOCAL);
+		break;
+	case OCFS2_AST_CONVERT:
+		ocfs2_generic_handle_convert_action(lockres);
+		break;
+	case OCFS2_AST_DOWNCONVERT:
+		ocfs2_generic_handle_downconvert_action(lockres);
+		break;
+	default:
+		mlog(ML_ERROR, "lockres %s: ast fired with invalid action: %u "
+		     "lockres flags = 0x%lx, unlock action: %u\n",
+		     lockres->l_name, lockres->l_action, lockres->l_flags,
+		     lockres->l_unlock_action);
+
+		BUG();
+	}
+
+	/* data and rw locking ignores refresh flag for now. */
+	if (lockres->l_type != OCFS2_LOCK_TYPE_META)
+		lockres_clear_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
+
+	/* set it to something invalid so if we get called again we
+	 * can catch it. */
+	lockres->l_action = OCFS2_AST_INVALID;
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+	wake_up(&lockres->l_event);
+
+	mlog_exit_void();
+}
+
+static int ocfs2_generic_handle_bast(struct ocfs2_lock_res *lockres,
+				     int level)
+{
+	int needs_downconvert = 0;
+	mlog_entry_void();
+
+	assert_spin_locked(&lockres->l_lock);
+
+	lockres_or_flags(lockres, OCFS2_LOCK_BLOCKED);
+
+	if (level > lockres->l_blocking) {
+		/* only schedule a downconvert if we haven't already scheduled
+		 * one that goes low enough to satisfy the level we're
+		 * blocking.  this also catches the case where we get
+		 * duplicate BASTs */
+		if (ocfs2_highest_compat_lock_level(level) <
+		    ocfs2_highest_compat_lock_level(lockres->l_blocking))
+			needs_downconvert = 1;
+
+		lockres->l_blocking = level;
+	}
+
+	mlog_exit(needs_downconvert);
+	return needs_downconvert;
+}
+
+static void ocfs2_generic_bast_func(struct ocfs2_super *osb,
+				    struct ocfs2_lock_res *lockres,
+				    int level)
+{
+	int needs_downconvert;
+	unsigned long flags;
+
+	mlog_entry_void();
+
+	BUG_ON(level <= LKM_NLMODE);
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	needs_downconvert = ocfs2_generic_handle_bast(lockres, level);
+	if (needs_downconvert)
+		ocfs2_schedule_blocked_lock(osb, lockres);
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	ocfs2_kick_vote_thread(osb);
+
+	wake_up(&lockres->l_event);
+	mlog_exit_void();
+}
+
+static void ocfs2_inode_bast_func(void *opaque, int level)
+{
+	struct ocfs2_lock_res *lockres = opaque;
+	struct inode *inode;
+	struct ocfs2_super *osb;
+
+	mlog_entry_void();
+
+	BUG_ON(!ocfs2_is_inode_lock(lockres));
+
+	inode = ocfs2_lock_res_inode(lockres);
+	osb = OCFS2_SB(inode->i_sb);
+
+	mlog(0, "BAST fired for inode %"MLFu64", blocking = %d, level = %d "
+	     "type = %s\n", OCFS2_I(inode)->ip_blkno, level,
+	     lockres->l_level,
+	     ocfs2_lock_type_string(lockres->l_type));
+
+	ocfs2_generic_bast_func(osb, lockres, level);
+
+	mlog_exit_void();
+}
+
+static void ocfs2_generic_ast_func(struct ocfs2_lock_res *lockres,
+				   int ignore_refresh)
+{
+	struct dlm_lockstatus *lksb = &lockres->l_lksb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+
+	if (lksb->status != DLM_NORMAL) {
+		mlog(ML_ERROR, "lockres %s: lksb status value of %u!\n",
+		     lockres->l_name, lksb->status);
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		return;
+	}
+
+	switch(lockres->l_action) {
+	case OCFS2_AST_ATTACH:
+		ocfs2_generic_handle_attach_action(lockres);
+		break;
+	case OCFS2_AST_CONVERT:
+		ocfs2_generic_handle_convert_action(lockres);
+		break;
+	case OCFS2_AST_DOWNCONVERT:
+		ocfs2_generic_handle_downconvert_action(lockres);
+		break;
+	default:
+		BUG();
+	}
+
+	if (ignore_refresh)
+		lockres_clear_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
+
+	/* set it to something invalid so if we get called again we
+	 * can catch it. */
+	lockres->l_action = OCFS2_AST_INVALID;
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	wake_up(&lockres->l_event);
+}
+
+static void ocfs2_super_ast_func(void *opaque)
+{
+	struct ocfs2_lock_res *lockres = opaque;
+
+	mlog_entry_void();
+	mlog(0, "Superblock AST fired\n");
+
+	BUG_ON(!ocfs2_is_super_lock(lockres));
+	ocfs2_generic_ast_func(lockres, 0);
+
+	mlog_exit_void();
+}
+
+static void ocfs2_super_bast_func(void *opaque,
+				  int level)
+{
+	struct ocfs2_lock_res *lockres = opaque;
+	struct ocfs2_super *osb;
+
+	mlog_entry_void();
+	mlog(0, "Superblock BAST fired\n");
+
+	BUG_ON(!ocfs2_is_super_lock(lockres));
+       	osb = ocfs2_lock_res_super(lockres);
+	ocfs2_generic_bast_func(osb, lockres, level);
+
+	mlog_exit_void();
+}
+
+static void ocfs2_rename_ast_func(void *opaque)
+{
+	struct ocfs2_lock_res *lockres = opaque;
+
+	mlog_entry_void();
+
+	mlog(0, "Rename AST fired\n");
+
+	BUG_ON(!ocfs2_is_rename_lock(lockres));
+
+	ocfs2_generic_ast_func(lockres, 1);
+
+	mlog_exit_void();
+}
+
+static void ocfs2_rename_bast_func(void *opaque,
+				   int level)
+{
+	struct ocfs2_lock_res *lockres = opaque;
+	struct ocfs2_super *osb;
+
+	mlog_entry_void();
+
+	mlog(0, "Rename BAST fired\n");
+
+	BUG_ON(!ocfs2_is_rename_lock(lockres));
+
+	osb = ocfs2_lock_res_super(lockres);
+	ocfs2_generic_bast_func(osb, lockres, level);
+
+	mlog_exit_void();
+}
+
+static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
+						int convert)
+{
+	unsigned long flags;
+
+	mlog_entry_void();
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
+	if (convert)
+		lockres->l_action = OCFS2_AST_INVALID;
+	else
+		lockres->l_unlock_action = OCFS2_UNLOCK_INVALID;
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	wake_up(&lockres->l_event);
+	mlog_exit_void();
+}
+
+/* Note: If we detect another process working on the lock (i.e.,
+ * OCFS2_LOCK_BUSY), we'll bail out returning 0. It's up to the caller
+ * to do the right thing in that case.
+ */
+static int ocfs2_lock_create(struct ocfs2_super *osb,
+			     struct ocfs2_lock_res *lockres,
+			     int level,
+			     int dlm_flags)
+{
+	int ret = 0;
+	enum dlm_status status;
+	unsigned long flags;
+
+	mlog_entry_void();
+
+	mlog(0, "lock %s, level = %d, flags = %d\n", lockres->l_name, level,
+	     dlm_flags);
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	if ((lockres->l_flags & OCFS2_LOCK_ATTACHED) ||
+	    (lockres->l_flags & OCFS2_LOCK_BUSY)) {
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		goto bail;
+	}
+
+	lockres->l_action = OCFS2_AST_ATTACH;
+	lockres->l_requested = level;
+	lockres_or_flags(lockres, OCFS2_LOCK_BUSY);
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	status = dlmlock(osb->dlm,
+			 level,
+			 &lockres->l_lksb,
+			 dlm_flags,
+			 lockres->l_name,
+			 lockres->l_ops->ast,
+			 lockres,
+			 lockres->l_ops->bast);
+	if (status != DLM_NORMAL) {
+		ocfs2_log_dlm_error("dlmlock", status, lockres);
+		ret = -EINVAL;
+		ocfs2_recover_from_dlm_error(lockres, 1);
+	}
+
+	mlog(0, "lock %s, successfull return from dlmlock\n", lockres->l_name);
+
+bail:
+	mlog_exit(ret);
+	return ret;
+}
+
+static inline int ocfs2_check_wait_flag(struct ocfs2_lock_res *lockres,
+					int flag)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	ret = lockres->l_flags & flag;
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	return ret;
+}
+
+static inline void ocfs2_wait_on_busy_lock(struct ocfs2_lock_res *lockres)
+
+{
+	wait_event(lockres->l_event,
+		   !ocfs2_check_wait_flag(lockres, OCFS2_LOCK_BUSY));
+}
+
+static inline void ocfs2_wait_on_refreshing_lock(struct ocfs2_lock_res *lockres)
+
+{
+	wait_event(lockres->l_event,
+		   !ocfs2_check_wait_flag(lockres, OCFS2_LOCK_REFRESHING));
+}
+
+/* predict what lock level we'll be dropping down to on behalf
+ * of another node, and return true if the currently wanted
+ * level will be compatible with it. */
+static inline int ocfs2_may_continue_on_blocked_lock(struct ocfs2_lock_res *lockres,
+						     int wanted)
+{
+	BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BLOCKED));
+
+	return wanted <= ocfs2_highest_compat_lock_level(lockres->l_blocking);
+}
+
+static void ocfs2_init_mask_waiter(struct ocfs2_mask_waiter *mw)
+{
+	INIT_LIST_HEAD(&mw->mw_item);
+	init_completion(&mw->mw_complete);
+}
+
+static int ocfs2_wait_for_mask(struct ocfs2_mask_waiter *mw)
+{
+	wait_for_completion(&mw->mw_complete);
+	/* Re-arm the completion in case we want to wait on it again */
+	INIT_COMPLETION(mw->mw_complete);
+	return mw->mw_status;
+}
+
+static void lockres_add_mask_waiter(struct ocfs2_lock_res *lockres,
+				    struct ocfs2_mask_waiter *mw,
+				    unsigned long mask,
+				    unsigned long goal)
+{
+	BUG_ON(!list_empty(&mw->mw_item));
+
+	assert_spin_locked(&lockres->l_lock);
+
+	list_add_tail(&mw->mw_item, &lockres->l_mask_waiters);
+	mw->mw_mask = mask;
+	mw->mw_goal = goal;
+}
+
+/* returns 0 if the mw that was removed was already satisfied, -EBUSY
+ * if the mask still hadn't reached its goal */
+static int lockres_remove_mask_waiter(struct ocfs2_lock_res *lockres,
+				      struct ocfs2_mask_waiter *mw)
+{
+	unsigned long flags;
+	int ret = 0;
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	if (!list_empty(&mw->mw_item)) {
+		if ((lockres->l_flags & mw->mw_mask) != mw->mw_goal)
+			ret = -EBUSY;
+
+		list_del_init(&mw->mw_item);
+		init_completion(&mw->mw_complete);
+	}
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	return ret;
+
+}
+
+static int ocfs2_cluster_lock(struct ocfs2_super *osb,
+			      struct ocfs2_lock_res *lockres,
+			      int level,
+			      int lkm_flags,
+			      int arg_flags)
+{
+	struct ocfs2_mask_waiter mw;
+	enum dlm_status status;
+	int wait, catch_signals = !(osb->s_mount_opt & OCFS2_MOUNT_NOINTR);
+	int ret = 0; /* gcc doesn't realize wait = 1 guarantees ret is set */
+	unsigned long flags;
+
+	mlog_entry_void();
+
+	ocfs2_init_mask_waiter(&mw);
+
+again:
+	wait = 0;
+
+	if (catch_signals && signal_pending(current)) {
+		ret = -ERESTARTSYS;
+		goto out;
+	}
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+
+	mlog_bug_on_msg(lockres->l_flags & OCFS2_LOCK_FREEING,
+			"Cluster lock called on freeing lockres %s! flags "
+			"0x%lx\n", lockres->l_name, lockres->l_flags);
+
+	/* We only compare against the currently granted level
+	 * here. If the lock is blocked waiting on a downconvert,
+	 * we'll get caught below. */
+	if (lockres->l_flags & OCFS2_LOCK_BUSY &&
+	    level > lockres->l_level) {
+		/* is someone sitting in dlm_lock? If so, wait on
+		 * them. */
+		lockres_add_mask_waiter(lockres, &mw, OCFS2_LOCK_BUSY, 0);
+		wait = 1;
+		goto unlock;
+	}
+
+	if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) {
+		/* lock has not been created yet. */
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+		ret = ocfs2_lock_create(osb, lockres, LKM_NLMODE, 0);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto out;
+		}
+		goto again;
+	}
+
+	if (lockres->l_flags & OCFS2_LOCK_BLOCKED &&
+	    !ocfs2_may_continue_on_blocked_lock(lockres, level)) {
+		/* is the lock is currently blocked on behalf of
+		 * another node */
+		lockres_add_mask_waiter(lockres, &mw, OCFS2_LOCK_BLOCKED, 0);
+		wait = 1;
+		goto unlock;
+	}
+
+	if (level > lockres->l_level) {
+		if (lockres->l_action != OCFS2_AST_INVALID)
+			mlog(ML_ERROR, "lockres %s has action %u pending\n",
+			     lockres->l_name, lockres->l_action);
+
+		lockres->l_action = OCFS2_AST_CONVERT;
+		lockres->l_requested = level;
+		lockres_or_flags(lockres, OCFS2_LOCK_BUSY);
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+		BUG_ON(level == LKM_IVMODE);
+		BUG_ON(level == LKM_NLMODE);
+
+		mlog(0, "lock %s, convert from %d to level = %d\n",
+		     lockres->l_name, lockres->l_level, level);
+
+		/* call dlm_lock to upgrade lock now */
+		status = dlmlock(osb->dlm,
+				 level,
+				 &lockres->l_lksb,
+				 lkm_flags|LKM_CONVERT|LKM_VALBLK,
+				 lockres->l_name,
+				 lockres->l_ops->ast,
+				 lockres,
+				 lockres->l_ops->bast);
+		if (status != DLM_NORMAL) {
+			if ((lkm_flags & LKM_NOQUEUE) &&
+			    (status == DLM_NOTQUEUED))
+				ret = -EAGAIN;
+			else {
+				ocfs2_log_dlm_error("dlmlock", status,
+						    lockres);
+				ret = -EINVAL;
+			}
+			ocfs2_recover_from_dlm_error(lockres, 1);
+			goto out;
+		}
+
+		mlog(0, "lock %s, successfull return from dlmlock\n",
+		     lockres->l_name);
+
+		/* At this point we've gone inside the dlm and need to
+		 * complete our work regardless. */
+		catch_signals = 0;
+
+		/* wait for busy to clear and carry on */
+		goto again;
+	}
+
+	/* Ok, if we get here then we're good to go. */
+	ocfs2_inc_holders(lockres, level);
+
+	ret = 0;
+unlock:
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+out:
+	/*
+	 * This is helping work around a lock inversion between the page lock
+	 * and dlm locks.  One path holds the page lock while calling aops
+	 * which block acquiring dlm locks.  The voting thread holds dlm
+	 * locks while acquiring page locks while down converting data locks.
+	 * This block is helping an aop path notice the inversion and back
+	 * off to unlock its page lock before trying the dlm lock again.
+	 */
+	if (wait && arg_flags & OCFS2_LOCK_NONBLOCK &&
+	    mw.mw_mask & (OCFS2_LOCK_BUSY|OCFS2_LOCK_BLOCKED)) {
+		wait = 0;
+		if (lockres_remove_mask_waiter(lockres, &mw))
+			ret = -EAGAIN;
+		else
+			goto again;
+	}
+	if (wait) {
+		ret = ocfs2_wait_for_mask(&mw);
+		if (ret == 0)
+			goto again;
+		mlog_errno(ret);
+	}
+
+	mlog_exit(ret);
+	return ret;
+}
+
+static void ocfs2_cluster_unlock(struct ocfs2_super *osb,
+				 struct ocfs2_lock_res *lockres,
+				 int level)
+{
+	unsigned long flags;
+
+	mlog_entry_void();
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	ocfs2_dec_holders(lockres, level);
+	ocfs2_vote_on_unlock(osb, lockres);
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+	mlog_exit_void();
+}
+
+static int ocfs2_create_new_inode_lock(struct inode *inode,
+				       struct ocfs2_lock_res *lockres)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	unsigned long flags;
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED);
+	lockres_or_flags(lockres, OCFS2_LOCK_LOCAL);
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	return ocfs2_lock_create(osb, lockres, LKM_EXMODE, LKM_LOCAL);
+}
+
+/* Grants us an EX lock on the data and metadata resources, skipping
+ * the normal cluster directory lookup. Use this ONLY on newly created
+ * inodes which other nodes can't possibly see, and which haven't been
+ * hashed in the inode hash yet. This can give us a good performance
+ * increase as it'll skip the network broadcast normally associated
+ * with creating a new lock resource. */
+int ocfs2_create_new_inode_locks(struct inode *inode)
+{
+	int ret;
+
+	BUG_ON(!inode);
+	BUG_ON(!ocfs2_inode_is_new(inode));
+
+	mlog_entry_void();
+
+	mlog(0, "Inode %"MLFu64"\n", OCFS2_I(inode)->ip_blkno);
+
+	/* NOTE: That we don't increment any of the holder counts, nor
+	 * do we add anything to a journal handle. Since this is
+	 * supposed to be a new inode which the cluster doesn't know
+	 * about yet, there is no need to.  As far as the LVB handling
+	 * is concerned, this is basically like acquiring an EX lock
+	 * on a resource which has an invalid one -- we'll set it
+	 * valid when we release the EX. */
+
+	ret = ocfs2_create_new_inode_lock(inode,
+					  &OCFS2_I(inode)->ip_rw_lockres);
+	if (ret) {
+		mlog_errno(ret);
+		goto bail;
+	}
+
+	ret = ocfs2_create_new_inode_lock(inode,
+					  &OCFS2_I(inode)->ip_meta_lockres);
+	if (ret) {
+		mlog_errno(ret);
+		goto bail;
+	}
+
+	ret = ocfs2_create_new_inode_lock(inode,
+					  &OCFS2_I(inode)->ip_data_lockres);
+	if (ret) {
+		mlog_errno(ret);
+		goto bail;
+	}
+
+bail:
+	mlog_exit(ret);
+	return ret;
+}
+
+int ocfs2_rw_lock(struct inode *inode, int write)
+{
+	int status, level;
+	struct ocfs2_lock_res *lockres;
+
+	BUG_ON(!inode);
+
+	mlog_entry_void();
+
+	mlog(0, "inode %"MLFu64" take %s RW lock\n",
+	     OCFS2_I(inode)->ip_blkno,
+	     write ? "EXMODE" : "PRMODE");
+
+	lockres = &OCFS2_I(inode)->ip_rw_lockres;
+
+	level = write ? LKM_EXMODE : LKM_PRMODE;
+
+	status = ocfs2_cluster_lock(OCFS2_SB(inode->i_sb), lockres, level, 0,
+				    0);
+	if (status < 0)
+		mlog_errno(status);
+
+	mlog_exit(status);
+	return status;
+}
+
+void ocfs2_rw_unlock(struct inode *inode, int write)
+{
+	int level = write ? LKM_EXMODE : LKM_PRMODE;
+	struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_rw_lockres;
+
+	mlog_entry_void();
+
+	mlog(0, "inode %"MLFu64" drop %s RW lock\n",
+	     OCFS2_I(inode)->ip_blkno,
+	     write ? "EXMODE" : "PRMODE");
+
+	ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
+
+	mlog_exit_void();
+}
+
+int ocfs2_data_lock_full(struct inode *inode,
+			 int write,
+			 int arg_flags)
+{
+	int status = 0, level;
+	struct ocfs2_lock_res *lockres;
+
+	BUG_ON(!inode);
+
+	mlog_entry_void();
+
+	mlog(0, "inode %"MLFu64" take %s DATA lock\n",
+	     OCFS2_I(inode)->ip_blkno,
+	     write ? "EXMODE" : "PRMODE");
+
+	/* We'll allow faking a readonly data lock for
+	 * rodevices. */
+	if (ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb))) {
+		if (write) {
+			status = -EROFS;
+			mlog_errno(status);
+		}
+		goto out;
+	}
+
+	lockres = &OCFS2_I(inode)->ip_data_lockres;
+
+	level = write ? LKM_EXMODE : LKM_PRMODE;
+
+	status = ocfs2_cluster_lock(OCFS2_SB(inode->i_sb), lockres, level,
+				    0, arg_flags);
+	if (status < 0 && status != -EAGAIN)
+		mlog_errno(status);
+
+out:
+	mlog_exit(status);
+	return status;
+}
+
+/* see ocfs2_meta_lock_with_page() */
+int ocfs2_data_lock_with_page(struct inode *inode,
+			      int write,
+			      struct page *page)
+{
+	int ret;
+
+	ret = ocfs2_data_lock_full(inode, write, OCFS2_LOCK_NONBLOCK);
+	if (ret == -EAGAIN) {
+		unlock_page(page);
+		if (ocfs2_data_lock(inode, write) == 0)
+			ocfs2_data_unlock(inode, write);
+		ret = AOP_TRUNCATED_PAGE;
+	}
+
+	return ret;
+}
+
+static void ocfs2_vote_on_unlock(struct ocfs2_super *osb,
+				 struct ocfs2_lock_res *lockres)
+{
+	int kick = 0;
+
+	mlog_entry_void();
+
+	/* If we know that another node is waiting on our lock, kick
+	 * the vote thread * pre-emptively when we reach a release
+	 * condition. */
+	if (lockres->l_flags & OCFS2_LOCK_BLOCKED) {
+		switch(lockres->l_blocking) {
+		case LKM_EXMODE:
+			if (!lockres->l_ex_holders && !lockres->l_ro_holders)
+				kick = 1;
+			break;
+		case LKM_PRMODE:
+			if (!lockres->l_ex_holders)
+				kick = 1;
+			break;
+		default:
+			BUG();
+		}
+	}
+
+	if (kick)
+		ocfs2_kick_vote_thread(osb);
+
+	mlog_exit_void();
+}
+
+void ocfs2_data_unlock(struct inode *inode,
+		       int write)
+{
+	int level = write ? LKM_EXMODE : LKM_PRMODE;
+	struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_data_lockres;
+
+	mlog_entry_void();
+
+	mlog(0, "inode %"MLFu64" drop %s DATA lock\n",
+	     OCFS2_I(inode)->ip_blkno,
+	     write ? "EXMODE" : "PRMODE");
+
+	if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)))
+		ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
+
+	mlog_exit_void();
+}
+
+#define OCFS2_SEC_BITS   34
+#define OCFS2_SEC_SHIFT  (64 - 34)
+#define OCFS2_NSEC_MASK  ((1ULL << OCFS2_SEC_SHIFT) - 1)
+
+/* LVB only has room for 64 bits of time here so we pack it for
+ * now. */
+static u64 ocfs2_pack_timespec(struct timespec *spec)
+{
+	u64 res;
+	u64 sec = spec->tv_sec;
+	u32 nsec = spec->tv_nsec;
+
+	res = (sec << OCFS2_SEC_SHIFT) | (nsec & OCFS2_NSEC_MASK);
+
+	return res;
+}
+
+/* Call this with the lockres locked. I am reasonably sure we don't
+ * need ip_lock in this function as anyone who would be changing those
+ * values is supposed to be blocked in ocfs2_meta_lock right now. */
+static void __ocfs2_stuff_meta_lvb(struct inode *inode)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_lock_res *lockres = &oi->ip_meta_lockres;
+	struct ocfs2_meta_lvb *lvb;
+
+	mlog_entry_void();
+
+	lvb = (struct ocfs2_meta_lvb *) lockres->l_lksb.lvb;
+
+	lvb->lvb_version   = cpu_to_be32(OCFS2_LVB_VERSION);
+	lvb->lvb_isize	   = cpu_to_be64(i_size_read(inode));
+	lvb->lvb_iclusters = cpu_to_be32(oi->ip_clusters);
+	lvb->lvb_iuid      = cpu_to_be32(inode->i_uid);
+	lvb->lvb_igid      = cpu_to_be32(inode->i_gid);
+	lvb->lvb_imode     = cpu_to_be16(inode->i_mode);
+	lvb->lvb_inlink    = cpu_to_be16(inode->i_nlink);
+	lvb->lvb_iatime_packed  =
+		cpu_to_be64(ocfs2_pack_timespec(&inode->i_atime));
+	lvb->lvb_ictime_packed =
+		cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime));
+	lvb->lvb_imtime_packed =
+		cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
+
+	mlog_meta_lvb(0, lockres);
+
+	mlog_exit_void();
+}
+
+static void ocfs2_unpack_timespec(struct timespec *spec,
+				  u64 packed_time)
+{
+	spec->tv_sec = packed_time >> OCFS2_SEC_SHIFT;
+	spec->tv_nsec = packed_time & OCFS2_NSEC_MASK;
+}
+
+static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_lock_res *lockres = &oi->ip_meta_lockres;
+	struct ocfs2_meta_lvb *lvb;
+
+	mlog_entry_void();
+
+	mlog_meta_lvb(0, lockres);
+
+	lvb = (struct ocfs2_meta_lvb *) lockres->l_lksb.lvb;
+
+	/* We're safe here without the lockres lock... */
+	spin_lock(&oi->ip_lock);
+	oi->ip_clusters = be32_to_cpu(lvb->lvb_iclusters);
+	i_size_write(inode, be64_to_cpu(lvb->lvb_isize));
+
+	/* fast-symlinks are a special case */
+	if (S_ISLNK(inode->i_mode) && !oi->ip_clusters)
+		inode->i_blocks = 0;
+	else
+		inode->i_blocks =
+			ocfs2_align_bytes_to_sectors(i_size_read(inode));
+
+	inode->i_uid     = be32_to_cpu(lvb->lvb_iuid);
+	inode->i_gid     = be32_to_cpu(lvb->lvb_igid);
+	inode->i_mode    = be16_to_cpu(lvb->lvb_imode);
+	inode->i_nlink   = be16_to_cpu(lvb->lvb_inlink);
+	ocfs2_unpack_timespec(&inode->i_atime,
+			      be64_to_cpu(lvb->lvb_iatime_packed));
+	ocfs2_unpack_timespec(&inode->i_mtime,
+			      be64_to_cpu(lvb->lvb_imtime_packed));
+	ocfs2_unpack_timespec(&inode->i_ctime,
+			      be64_to_cpu(lvb->lvb_ictime_packed));
+	spin_unlock(&oi->ip_lock);
+
+	mlog_exit_void();
+}
+
+static inline int ocfs2_meta_lvb_is_trustable(struct ocfs2_lock_res *lockres)
+{
+	struct ocfs2_meta_lvb *lvb = (struct ocfs2_meta_lvb *) lockres->l_lksb.lvb;
+
+	if (be32_to_cpu(lvb->lvb_version) == OCFS2_LVB_VERSION)
+		return 1;
+	return 0;
+}
+
+/* Determine whether a lock resource needs to be refreshed, and
+ * arbitrate who gets to refresh it.
+ *
+ *   0 means no refresh needed.
+ *
+ *   > 0 means you need to refresh this and you MUST call
+ *   ocfs2_complete_lock_res_refresh afterwards. */
+static int ocfs2_should_refresh_lock_res(struct ocfs2_lock_res *lockres)
+{
+	unsigned long flags;
+	int status = 0;
+
+	mlog_entry_void();
+
+refresh_check:
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	if (!(lockres->l_flags & OCFS2_LOCK_NEEDS_REFRESH)) {
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		goto bail;
+	}
+
+	if (lockres->l_flags & OCFS2_LOCK_REFRESHING) {
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+		ocfs2_wait_on_refreshing_lock(lockres);
+		goto refresh_check;
+	}
+
+	/* Ok, I'll be the one to refresh this lock. */
+	lockres_or_flags(lockres, OCFS2_LOCK_REFRESHING);
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	status = 1;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/* If status is non zero, I'll mark it as not being in refresh
+ * anymroe, but i won't clear the needs refresh flag. */
+static inline void ocfs2_complete_lock_res_refresh(struct ocfs2_lock_res *lockres,
+						   int status)
+{
+	unsigned long flags;
+	mlog_entry_void();
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	lockres_clear_flags(lockres, OCFS2_LOCK_REFRESHING);
+	if (!status)
+		lockres_clear_flags(lockres, OCFS2_LOCK_NEEDS_REFRESH);
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	wake_up(&lockres->l_event);
+
+	mlog_exit_void();
+}
+
+/* may or may not return a bh if it went to disk. */
+static int ocfs2_meta_lock_update(struct inode *inode,
+				  struct buffer_head **bh)
+{
+	int status = 0;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_lock_res *lockres;
+	struct ocfs2_dinode *fe;
+
+	mlog_entry_void();
+
+	spin_lock(&oi->ip_lock);
+	if (oi->ip_flags & OCFS2_INODE_DELETED) {
+		mlog(0, "Orphaned inode %"MLFu64" was deleted while we "
+		     "were waiting on a lock. ip_flags = 0x%x\n",
+		     oi->ip_blkno, oi->ip_flags);
+		spin_unlock(&oi->ip_lock);
+		status = -ENOENT;
+		goto bail;
+	}
+	spin_unlock(&oi->ip_lock);
+
+	lockres = &oi->ip_meta_lockres;
+
+	if (!ocfs2_should_refresh_lock_res(lockres))
+		goto bail;
+
+	/* This will discard any caching information we might have had
+	 * for the inode metadata. */
+	ocfs2_metadata_cache_purge(inode);
+
+	/* will do nothing for inode types that don't use the extent
+	 * map (directories, bitmap files, etc) */
+	ocfs2_extent_map_trunc(inode, 0);
+
+	if (ocfs2_meta_lvb_is_trustable(lockres)) {
+		mlog(0, "Trusting LVB on inode %"MLFu64"\n",
+		     oi->ip_blkno);
+		ocfs2_refresh_inode_from_lvb(inode);
+	} else {
+		/* Boo, we have to go to disk. */
+		/* read bh, cast, ocfs2_refresh_inode */
+		status = ocfs2_read_block(OCFS2_SB(inode->i_sb), oi->ip_blkno,
+					  bh, OCFS2_BH_CACHED, inode);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail_refresh;
+		}
+		fe = (struct ocfs2_dinode *) (*bh)->b_data;
+
+		/* This is a good chance to make sure we're not
+		 * locking an invalid object.
+		 *
+		 * We bug on a stale inode here because we checked
+		 * above whether it was wiped from disk. The wiping
+		 * node provides a guarantee that we receive that
+		 * message and can mark the inode before dropping any
+		 * locks associated with it. */
+		if (!OCFS2_IS_VALID_DINODE(fe)) {
+			OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe);
+			status = -EIO;
+			goto bail_refresh;
+		}
+		mlog_bug_on_msg(inode->i_generation !=
+				le32_to_cpu(fe->i_generation),
+				"Invalid dinode %"MLFu64" disk generation: %u "
+				"inode->i_generation: %u\n",
+				oi->ip_blkno, le32_to_cpu(fe->i_generation),
+				inode->i_generation);
+		mlog_bug_on_msg(le64_to_cpu(fe->i_dtime) ||
+				!(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL)),
+				"Stale dinode %"MLFu64" dtime: %"MLFu64" "
+				"flags: 0x%x\n", oi->ip_blkno,
+				le64_to_cpu(fe->i_dtime),
+				le32_to_cpu(fe->i_flags));
+
+		ocfs2_refresh_inode(inode, fe);
+	}
+
+	status = 0;
+bail_refresh:
+	ocfs2_complete_lock_res_refresh(lockres, status);
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_assign_bh(struct inode *inode,
+			   struct buffer_head **ret_bh,
+			   struct buffer_head *passed_bh)
+{
+	int status;
+
+	if (passed_bh) {
+		/* Ok, the update went to disk for us, use the
+		 * returned bh. */
+		*ret_bh = passed_bh;
+		get_bh(*ret_bh);
+
+		return 0;
+	}
+
+	status = ocfs2_read_block(OCFS2_SB(inode->i_sb),
+				  OCFS2_I(inode)->ip_blkno,
+				  ret_bh,
+				  OCFS2_BH_CACHED,
+				  inode);
+	if (status < 0)
+		mlog_errno(status);
+
+	return status;
+}
+
+/*
+ * returns < 0 error if the callback will never be called, otherwise
+ * the result of the lock will be communicated via the callback.
+ */
+int ocfs2_meta_lock_full(struct inode *inode,
+			 struct ocfs2_journal_handle *handle,
+			 struct buffer_head **ret_bh,
+			 int ex,
+			 int arg_flags)
+{
+	int status, level, dlm_flags, acquired;
+	struct ocfs2_lock_res *lockres;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct buffer_head *local_bh = NULL;
+
+	BUG_ON(!inode);
+
+	mlog_entry_void();
+
+	mlog(0, "inode %"MLFu64", take %s META lock\n",
+	     OCFS2_I(inode)->ip_blkno,
+	     ex ? "EXMODE" : "PRMODE");
+
+	status = 0;
+	acquired = 0;
+	/* We'll allow faking a readonly metadata lock for
+	 * rodevices. */
+	if (ocfs2_is_hard_readonly(osb)) {
+		if (ex)
+			status = -EROFS;
+		goto bail;
+	}
+
+	if (!(arg_flags & OCFS2_META_LOCK_RECOVERY))
+		wait_event(osb->recovery_event,
+			   ocfs2_node_map_is_empty(osb, &osb->recovery_map));
+
+	acquired = 0;
+	lockres = &OCFS2_I(inode)->ip_meta_lockres;
+	level = ex ? LKM_EXMODE : LKM_PRMODE;
+	dlm_flags = 0;
+	if (arg_flags & OCFS2_META_LOCK_NOQUEUE)
+		dlm_flags |= LKM_NOQUEUE;
+
+	status = ocfs2_cluster_lock(osb, lockres, level, dlm_flags, arg_flags);
+	if (status < 0) {
+		if (status != -EAGAIN && status != -EIOCBRETRY)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	/* Notify the error cleanup path to drop the cluster lock. */
+	acquired = 1;
+
+	/* We wait twice because a node may have died while we were in
+	 * the lower dlm layers. The second time though, we've
+	 * committed to owning this lock so we don't allow signals to
+	 * abort the operation. */
+	if (!(arg_flags & OCFS2_META_LOCK_RECOVERY))
+		wait_event(osb->recovery_event,
+			   ocfs2_node_map_is_empty(osb, &osb->recovery_map));
+
+	/* This is fun. The caller may want a bh back, or it may
+	 * not. ocfs2_meta_lock_update definitely wants one in, but
+	 * may or may not read one, depending on what's in the
+	 * LVB. The result of all of this is that we've *only* gone to
+	 * disk if we have to, so the complexity is worthwhile. */
+	status = ocfs2_meta_lock_update(inode, &local_bh);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	if (ret_bh) {
+		status = ocfs2_assign_bh(inode, ret_bh, local_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	if (handle) {
+		status = ocfs2_handle_add_lock(handle, inode);
+		if (status < 0)
+			mlog_errno(status);
+	}
+
+bail:
+	if (status < 0) {
+		if (ret_bh && (*ret_bh)) {
+			brelse(*ret_bh);
+			*ret_bh = NULL;
+		}
+		if (acquired)
+			ocfs2_meta_unlock(inode, ex);
+	}
+
+	if (local_bh)
+		brelse(local_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * This is working around a lock inversion between tasks acquiring DLM locks
+ * while holding a page lock and the vote thread which blocks dlm lock acquiry
+ * while acquiring page locks.
+ *
+ * ** These _with_page variantes are only intended to be called from aop
+ * methods that hold page locks and return a very specific *positive* error
+ * code that aop methods pass up to the VFS -- test for errors with != 0. **
+ *
+ * The DLM is called such that it returns -EAGAIN if it would have blocked
+ * waiting for the vote thread.  In that case we unlock our page so the vote
+ * thread can make progress.  Once we've done this we have to return
+ * AOP_TRUNCATED_PAGE so the aop method that called us can bubble that back up
+ * into the VFS who will then immediately retry the aop call.
+ *
+ * We do a blocking lock and immediate unlock before returning, though, so that
+ * the lock has a great chance of being cached on this node by the time the VFS
+ * calls back to retry the aop.    This has a potential to livelock as nodes
+ * ping locks back and forth, but that's a risk we're willing to take to avoid
+ * the lock inversion simply.
+ */
+int ocfs2_meta_lock_with_page(struct inode *inode,
+			      struct ocfs2_journal_handle *handle,
+			      struct buffer_head **ret_bh,
+			      int ex,
+			      struct page *page)
+{
+	int ret;
+
+	ret = ocfs2_meta_lock_full(inode, handle, ret_bh, ex,
+				   OCFS2_LOCK_NONBLOCK);
+	if (ret == -EAGAIN) {
+		unlock_page(page);
+		if (ocfs2_meta_lock(inode, handle, ret_bh, ex) == 0)
+			ocfs2_meta_unlock(inode, ex);
+		ret = AOP_TRUNCATED_PAGE;
+	}
+
+	return ret;
+}
+
+void ocfs2_meta_unlock(struct inode *inode,
+		       int ex)
+{
+	int level = ex ? LKM_EXMODE : LKM_PRMODE;
+	struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_meta_lockres;
+
+	mlog_entry_void();
+
+	mlog(0, "inode %"MLFu64" drop %s META lock\n",
+	     OCFS2_I(inode)->ip_blkno,
+	     ex ? "EXMODE" : "PRMODE");
+
+	if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)))
+		ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
+
+	mlog_exit_void();
+}
+
+int ocfs2_super_lock(struct ocfs2_super *osb,
+		     int ex)
+{
+	int status;
+	int level = ex ? LKM_EXMODE : LKM_PRMODE;
+	struct ocfs2_lock_res *lockres = &osb->osb_super_lockres;
+	struct buffer_head *bh;
+	struct ocfs2_slot_info *si = osb->slot_info;
+
+	mlog_entry_void();
+
+	if (ocfs2_is_hard_readonly(osb))
+		return -EROFS;
+
+	status = ocfs2_cluster_lock(osb, lockres, level, 0, 0);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* The super block lock path is really in the best position to
+	 * know when resources covered by the lock need to be
+	 * refreshed, so we do it here. Of course, making sense of
+	 * everything is up to the caller :) */
+	status = ocfs2_should_refresh_lock_res(lockres);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	if (status) {
+		bh = si->si_bh;
+		status = ocfs2_read_block(osb, bh->b_blocknr, &bh, 0,
+					  si->si_inode);
+		if (status == 0)
+			ocfs2_update_slot_info(si);
+
+		ocfs2_complete_lock_res_refresh(lockres, status);
+
+		if (status < 0)
+			mlog_errno(status);
+	}
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+void ocfs2_super_unlock(struct ocfs2_super *osb,
+			int ex)
+{
+	int level = ex ? LKM_EXMODE : LKM_PRMODE;
+	struct ocfs2_lock_res *lockres = &osb->osb_super_lockres;
+
+	ocfs2_cluster_unlock(osb, lockres, level);
+}
+
+int ocfs2_rename_lock(struct ocfs2_super *osb)
+{
+	int status;
+	struct ocfs2_lock_res *lockres = &osb->osb_rename_lockres;
+
+	if (ocfs2_is_hard_readonly(osb))
+		return -EROFS;
+
+	status = ocfs2_cluster_lock(osb, lockres, LKM_EXMODE, 0, 0);
+	if (status < 0)
+		mlog_errno(status);
+
+	return status;
+}
+
+void ocfs2_rename_unlock(struct ocfs2_super *osb)
+{
+	struct ocfs2_lock_res *lockres = &osb->osb_rename_lockres;
+
+	ocfs2_cluster_unlock(osb, lockres, LKM_EXMODE);
+}
+
+/* Reference counting of the dlm debug structure. We want this because
+ * open references on the debug inodes can live on after a mount, so
+ * we can't rely on the ocfs2_super to always exist. */
+static void ocfs2_dlm_debug_free(struct kref *kref)
+{
+	struct ocfs2_dlm_debug *dlm_debug;
+
+	dlm_debug = container_of(kref, struct ocfs2_dlm_debug, d_refcnt);
+
+	kfree(dlm_debug);
+}
+
+void ocfs2_put_dlm_debug(struct ocfs2_dlm_debug *dlm_debug)
+{
+	if (dlm_debug)
+		kref_put(&dlm_debug->d_refcnt, ocfs2_dlm_debug_free);
+}
+
+static void ocfs2_get_dlm_debug(struct ocfs2_dlm_debug *debug)
+{
+	kref_get(&debug->d_refcnt);
+}
+
+struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void)
+{
+	struct ocfs2_dlm_debug *dlm_debug;
+
+	dlm_debug = kmalloc(sizeof(struct ocfs2_dlm_debug), GFP_KERNEL);
+	if (!dlm_debug) {
+		mlog_errno(-ENOMEM);
+		goto out;
+	}
+
+	kref_init(&dlm_debug->d_refcnt);
+	INIT_LIST_HEAD(&dlm_debug->d_lockres_tracking);
+	dlm_debug->d_locking_state = NULL;
+out:
+	return dlm_debug;
+}
+
+/* Access to this is arbitrated for us via seq_file->sem. */
+struct ocfs2_dlm_seq_priv {
+	struct ocfs2_dlm_debug *p_dlm_debug;
+	struct ocfs2_lock_res p_iter_res;
+	struct ocfs2_lock_res p_tmp_res;
+};
+
+static struct ocfs2_lock_res *ocfs2_dlm_next_res(struct ocfs2_lock_res *start,
+						 struct ocfs2_dlm_seq_priv *priv)
+{
+	struct ocfs2_lock_res *iter, *ret = NULL;
+	struct ocfs2_dlm_debug *dlm_debug = priv->p_dlm_debug;
+
+	assert_spin_locked(&ocfs2_dlm_tracking_lock);
+
+	list_for_each_entry(iter, &start->l_debug_list, l_debug_list) {
+		/* discover the head of the list */
+		if (&iter->l_debug_list == &dlm_debug->d_lockres_tracking) {
+			mlog(0, "End of list found, %p\n", ret);
+			break;
+		}
+
+		/* We track our "dummy" iteration lockres' by a NULL
+		 * l_ops field. */
+		if (iter->l_ops != NULL) {
+			ret = iter;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static void *ocfs2_dlm_seq_start(struct seq_file *m, loff_t *pos)
+{
+	struct ocfs2_dlm_seq_priv *priv = m->private;
+	struct ocfs2_lock_res *iter;
+
+	spin_lock(&ocfs2_dlm_tracking_lock);
+	iter = ocfs2_dlm_next_res(&priv->p_iter_res, priv);
+	if (iter) {
+		/* Since lockres' have the lifetime of their container
+		 * (which can be inodes, ocfs2_supers, etc) we want to
+		 * copy this out to a temporary lockres while still
+		 * under the spinlock. Obviously after this we can't
+		 * trust any pointers on the copy returned, but that's
+		 * ok as the information we want isn't typically held
+		 * in them. */
+		priv->p_tmp_res = *iter;
+		iter = &priv->p_tmp_res;
+	}
+	spin_unlock(&ocfs2_dlm_tracking_lock);
+
+	return iter;
+}
+
+static void ocfs2_dlm_seq_stop(struct seq_file *m, void *v)
+{
+}
+
+static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	struct ocfs2_dlm_seq_priv *priv = m->private;
+	struct ocfs2_lock_res *iter = v;
+	struct ocfs2_lock_res *dummy = &priv->p_iter_res;
+
+	spin_lock(&ocfs2_dlm_tracking_lock);
+	iter = ocfs2_dlm_next_res(iter, priv);
+	list_del_init(&dummy->l_debug_list);
+	if (iter) {
+		list_add(&dummy->l_debug_list, &iter->l_debug_list);
+		priv->p_tmp_res = *iter;
+		iter = &priv->p_tmp_res;
+	}
+	spin_unlock(&ocfs2_dlm_tracking_lock);
+
+	return iter;
+}
+
+/* So that debugfs.ocfs2 can determine which format is being used */
+#define OCFS2_DLM_DEBUG_STR_VERSION 1
+static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
+{
+	int i;
+	char *lvb;
+	struct ocfs2_lock_res *lockres = v;
+
+	if (!lockres)
+		return -EINVAL;
+
+	seq_printf(m, "0x%x\t"
+		   "%.*s\t"
+		   "%d\t"
+		   "0x%lx\t"
+		   "0x%x\t"
+		   "0x%x\t"
+		   "%u\t"
+		   "%u\t"
+		   "%d\t"
+		   "%d\t",
+		   OCFS2_DLM_DEBUG_STR_VERSION,
+		   OCFS2_LOCK_ID_MAX_LEN, lockres->l_name,
+		   lockres->l_level,
+		   lockres->l_flags,
+		   lockres->l_action,
+		   lockres->l_unlock_action,
+		   lockres->l_ro_holders,
+		   lockres->l_ex_holders,
+		   lockres->l_requested,
+		   lockres->l_blocking);
+
+	/* Dump the raw LVB */
+	lvb = lockres->l_lksb.lvb;
+	for(i = 0; i < DLM_LVB_LEN; i++)
+		seq_printf(m, "0x%x\t", lvb[i]);
+
+	/* End the line */
+	seq_printf(m, "\n");
+	return 0;
+}
+
+static struct seq_operations ocfs2_dlm_seq_ops = {
+	.start =	ocfs2_dlm_seq_start,
+	.stop =		ocfs2_dlm_seq_stop,
+	.next =		ocfs2_dlm_seq_next,
+	.show =		ocfs2_dlm_seq_show,
+};
+
+static int ocfs2_dlm_debug_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *seq = (struct seq_file *) file->private_data;
+	struct ocfs2_dlm_seq_priv *priv = seq->private;
+	struct ocfs2_lock_res *res = &priv->p_iter_res;
+
+	ocfs2_remove_lockres_tracking(res);
+	ocfs2_put_dlm_debug(priv->p_dlm_debug);
+	return seq_release_private(inode, file);
+}
+
+static int ocfs2_dlm_debug_open(struct inode *inode, struct file *file)
+{
+	int ret;
+	struct ocfs2_dlm_seq_priv *priv;
+	struct seq_file *seq;
+	struct ocfs2_super *osb;
+
+	priv = kzalloc(sizeof(struct ocfs2_dlm_seq_priv), GFP_KERNEL);
+	if (!priv) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+	osb = (struct ocfs2_super *) inode->u.generic_ip;
+	ocfs2_get_dlm_debug(osb->osb_dlm_debug);
+	priv->p_dlm_debug = osb->osb_dlm_debug;
+	INIT_LIST_HEAD(&priv->p_iter_res.l_debug_list);
+
+	ret = seq_open(file, &ocfs2_dlm_seq_ops);
+	if (ret) {
+		kfree(priv);
+		mlog_errno(ret);
+		goto out;
+	}
+
+	seq = (struct seq_file *) file->private_data;
+	seq->private = priv;
+
+	ocfs2_add_lockres_tracking(&priv->p_iter_res,
+				   priv->p_dlm_debug);
+
+out:
+	return ret;
+}
+
+static struct file_operations ocfs2_dlm_debug_fops = {
+	.open =		ocfs2_dlm_debug_open,
+	.release =	ocfs2_dlm_debug_release,
+	.read =		seq_read,
+	.llseek =	seq_lseek,
+};
+
+static int ocfs2_dlm_init_debug(struct ocfs2_super *osb)
+{
+	int ret = 0;
+	struct ocfs2_dlm_debug *dlm_debug = osb->osb_dlm_debug;
+
+	dlm_debug->d_locking_state = debugfs_create_file("locking_state",
+							 S_IFREG|S_IRUSR,
+							 osb->osb_debug_root,
+							 osb,
+							 &ocfs2_dlm_debug_fops);
+	if (!dlm_debug->d_locking_state) {
+		ret = -EINVAL;
+		mlog(ML_ERROR,
+		     "Unable to create locking state debugfs file.\n");
+		goto out;
+	}
+
+	ocfs2_get_dlm_debug(dlm_debug);
+out:
+	return ret;
+}
+
+static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb)
+{
+	struct ocfs2_dlm_debug *dlm_debug = osb->osb_dlm_debug;
+
+	if (dlm_debug) {
+		debugfs_remove(dlm_debug->d_locking_state);
+		ocfs2_put_dlm_debug(dlm_debug);
+	}
+}
+
+int ocfs2_dlm_init(struct ocfs2_super *osb)
+{
+	int status;
+	u32 dlm_key;
+	struct dlm_ctxt *dlm;
+
+	mlog_entry_void();
+
+	status = ocfs2_dlm_init_debug(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* launch vote thread */
+	osb->vote_task = kthread_run(ocfs2_vote_thread, osb, "ocfs2vote-%d",
+				     osb->osb_id);
+	if (IS_ERR(osb->vote_task)) {
+		status = PTR_ERR(osb->vote_task);
+		osb->vote_task = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* used by the dlm code to make message headers unique, each
+	 * node in this domain must agree on this. */
+	dlm_key = crc32_le(0, osb->uuid_str, strlen(osb->uuid_str));
+
+	/* for now, uuid == domain */
+	dlm = dlm_register_domain(osb->uuid_str, dlm_key);
+	if (IS_ERR(dlm)) {
+		status = PTR_ERR(dlm);
+		mlog_errno(status);
+		goto bail;
+	}
+
+	ocfs2_super_lock_res_init(&osb->osb_super_lockres, osb);
+	ocfs2_rename_lock_res_init(&osb->osb_rename_lockres, osb);
+
+	dlm_register_eviction_cb(dlm, &osb->osb_eviction_cb);
+
+	osb->dlm = dlm;
+
+	status = 0;
+bail:
+	if (status < 0) {
+		ocfs2_dlm_shutdown_debug(osb);
+		if (osb->vote_task)
+			kthread_stop(osb->vote_task);
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+void ocfs2_dlm_shutdown(struct ocfs2_super *osb)
+{
+	mlog_entry_void();
+
+	dlm_unregister_eviction_cb(&osb->osb_eviction_cb);
+
+	ocfs2_drop_osb_locks(osb);
+
+	if (osb->vote_task) {
+		kthread_stop(osb->vote_task);
+		osb->vote_task = NULL;
+	}
+
+	ocfs2_lock_res_free(&osb->osb_super_lockres);
+	ocfs2_lock_res_free(&osb->osb_rename_lockres);
+
+	dlm_unregister_domain(osb->dlm);
+	osb->dlm = NULL;
+
+	ocfs2_dlm_shutdown_debug(osb);
+
+	mlog_exit_void();
+}
+
+static void ocfs2_unlock_ast_func(void *opaque, enum dlm_status status)
+{
+	struct ocfs2_lock_res *lockres = opaque;
+	unsigned long flags;
+
+	mlog_entry_void();
+
+	mlog(0, "UNLOCK AST called on lock %s, action = %d\n", lockres->l_name,
+	     lockres->l_unlock_action);
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	/* We tried to cancel a convert request, but it was already
+	 * granted. All we want to do here is clear our unlock
+	 * state. The wake_up call done at the bottom is redundant
+	 * (ocfs2_prepare_cancel_convert doesn't sleep on this) but doesn't
+	 * hurt anything anyway */
+	if (status == DLM_CANCELGRANT &&
+	    lockres->l_unlock_action == OCFS2_UNLOCK_CANCEL_CONVERT) {
+		mlog(0, "Got cancelgrant for %s\n", lockres->l_name);
+
+		/* We don't clear the busy flag in this case as it
+		 * should have been cleared by the ast which the dlm
+		 * has called. */
+		goto complete_unlock;
+	}
+
+	if (status != DLM_NORMAL) {
+		mlog(ML_ERROR, "Dlm passes status %d for lock %s, "
+		     "unlock_action %d\n", status, lockres->l_name,
+		     lockres->l_unlock_action);
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		return;
+	}
+
+	switch(lockres->l_unlock_action) {
+	case OCFS2_UNLOCK_CANCEL_CONVERT:
+		mlog(0, "Cancel convert success for %s\n", lockres->l_name);
+		lockres->l_action = OCFS2_AST_INVALID;
+		break;
+	case OCFS2_UNLOCK_DROP_LOCK:
+		lockres->l_level = LKM_IVMODE;
+		break;
+	default:
+		BUG();
+	}
+
+	lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
+complete_unlock:
+	lockres->l_unlock_action = OCFS2_UNLOCK_INVALID;
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	wake_up(&lockres->l_event);
+
+	mlog_exit_void();
+}
+
+typedef void (ocfs2_pre_drop_cb_t)(struct ocfs2_lock_res *, void *);
+
+struct drop_lock_cb {
+	ocfs2_pre_drop_cb_t	*drop_func;
+	void			*drop_data;
+};
+
+static int ocfs2_drop_lock(struct ocfs2_super *osb,
+			   struct ocfs2_lock_res *lockres,
+			   struct drop_lock_cb *dcb)
+{
+	enum dlm_status status;
+	unsigned long flags;
+
+	/* We didn't get anywhere near actually using this lockres. */
+	if (!(lockres->l_flags & OCFS2_LOCK_INITIALIZED))
+		goto out;
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+
+	mlog_bug_on_msg(!(lockres->l_flags & OCFS2_LOCK_FREEING),
+			"lockres %s, flags 0x%lx\n",
+			lockres->l_name, lockres->l_flags);
+
+	while (lockres->l_flags & OCFS2_LOCK_BUSY) {
+		mlog(0, "waiting on busy lock \"%s\": flags = %lx, action = "
+		     "%u, unlock_action = %u\n",
+		     lockres->l_name, lockres->l_flags, lockres->l_action,
+		     lockres->l_unlock_action);
+
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+		/* XXX: Today we just wait on any busy
+		 * locks... Perhaps we need to cancel converts in the
+		 * future? */
+		ocfs2_wait_on_busy_lock(lockres);
+
+		spin_lock_irqsave(&lockres->l_lock, flags);
+	}
+
+	if (dcb)
+		dcb->drop_func(lockres, dcb->drop_data);
+
+	if (lockres->l_flags & OCFS2_LOCK_BUSY)
+		mlog(ML_ERROR, "destroying busy lock: \"%s\"\n",
+		     lockres->l_name);
+	if (lockres->l_flags & OCFS2_LOCK_BLOCKED)
+		mlog(0, "destroying blocked lock: \"%s\"\n", lockres->l_name);
+
+	if (!(lockres->l_flags & OCFS2_LOCK_ATTACHED)) {
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		goto out;
+	}
+
+	lockres_clear_flags(lockres, OCFS2_LOCK_ATTACHED);
+
+	/* make sure we never get here while waiting for an ast to
+	 * fire. */
+	BUG_ON(lockres->l_action != OCFS2_AST_INVALID);
+
+	/* is this necessary? */
+	lockres_or_flags(lockres, OCFS2_LOCK_BUSY);
+	lockres->l_unlock_action = OCFS2_UNLOCK_DROP_LOCK;
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	mlog(0, "lock %s\n", lockres->l_name);
+
+	status = dlmunlock(osb->dlm, &lockres->l_lksb, LKM_VALBLK,
+			   lockres->l_ops->unlock_ast, lockres);
+	if (status != DLM_NORMAL) {
+		ocfs2_log_dlm_error("dlmunlock", status, lockres);
+		mlog(ML_ERROR, "lockres flags: %lu\n", lockres->l_flags);
+		dlm_print_one_lock(lockres->l_lksb.lockid);
+		BUG();
+	}
+	mlog(0, "lock %s, successfull return from dlmunlock\n",
+	     lockres->l_name);
+
+	ocfs2_wait_on_busy_lock(lockres);
+out:
+	mlog_exit(0);
+	return 0;
+}
+
+/* Mark the lockres as being dropped. It will no longer be
+ * queued if blocking, but we still may have to wait on it
+ * being dequeued from the vote thread before we can consider
+ * it safe to drop. 
+ *
+ * You can *not* attempt to call cluster_lock on this lockres anymore. */
+void ocfs2_mark_lockres_freeing(struct ocfs2_lock_res *lockres)
+{
+	int status;
+	struct ocfs2_mask_waiter mw;
+	unsigned long flags;
+
+	ocfs2_init_mask_waiter(&mw);
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	lockres->l_flags |= OCFS2_LOCK_FREEING;
+	while (lockres->l_flags & OCFS2_LOCK_QUEUED) {
+		lockres_add_mask_waiter(lockres, &mw, OCFS2_LOCK_QUEUED, 0);
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+		mlog(0, "Waiting on lockres %s\n", lockres->l_name);
+
+		status = ocfs2_wait_for_mask(&mw);
+		if (status)
+			mlog_errno(status);
+
+		spin_lock_irqsave(&lockres->l_lock, flags);
+	}
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+}
+
+static void ocfs2_drop_osb_locks(struct ocfs2_super *osb)
+{
+	int status;
+
+	mlog_entry_void();
+
+	ocfs2_mark_lockres_freeing(&osb->osb_super_lockres);
+
+	status = ocfs2_drop_lock(osb, &osb->osb_super_lockres, NULL);
+	if (status < 0)
+		mlog_errno(status);
+
+	ocfs2_mark_lockres_freeing(&osb->osb_rename_lockres);
+
+	status = ocfs2_drop_lock(osb, &osb->osb_rename_lockres, NULL);
+	if (status < 0)
+		mlog_errno(status);
+
+	mlog_exit(status);
+}
+
+static void ocfs2_meta_pre_drop(struct ocfs2_lock_res *lockres, void *data)
+{
+	struct inode *inode = data;
+
+	/* the metadata lock requires a bit more work as we have an
+	 * LVB to worry about. */
+	if (lockres->l_flags & OCFS2_LOCK_ATTACHED &&
+	    lockres->l_level == LKM_EXMODE &&
+	    !(lockres->l_flags & OCFS2_LOCK_NEEDS_REFRESH))
+		__ocfs2_stuff_meta_lvb(inode);
+}
+
+int ocfs2_drop_inode_locks(struct inode *inode)
+{
+	int status, err;
+	struct drop_lock_cb meta_dcb = { ocfs2_meta_pre_drop, inode, };
+
+	mlog_entry_void();
+
+	/* No need to call ocfs2_mark_lockres_freeing here -
+	 * ocfs2_clear_inode has done it for us. */
+
+	err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
+			      &OCFS2_I(inode)->ip_data_lockres,
+			      NULL);
+	if (err < 0)
+		mlog_errno(err);
+
+	status = err;
+
+	err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
+			      &OCFS2_I(inode)->ip_meta_lockres,
+			      &meta_dcb);
+	if (err < 0)
+		mlog_errno(err);
+	if (err < 0 && !status)
+		status = err;
+
+	err = ocfs2_drop_lock(OCFS2_SB(inode->i_sb),
+			      &OCFS2_I(inode)->ip_rw_lockres,
+			      NULL);
+	if (err < 0)
+		mlog_errno(err);
+	if (err < 0 && !status)
+		status = err;
+
+	mlog_exit(status);
+	return status;
+}
+
+static void ocfs2_prepare_downconvert(struct ocfs2_lock_res *lockres,
+				      int new_level)
+{
+	assert_spin_locked(&lockres->l_lock);
+
+	BUG_ON(lockres->l_blocking <= LKM_NLMODE);
+
+	if (lockres->l_level <= new_level) {
+		mlog(ML_ERROR, "lockres->l_level (%u) <= new_level (%u)\n",
+		     lockres->l_level, new_level);
+		BUG();
+	}
+
+	mlog(0, "lock %s, new_level = %d, l_blocking = %d\n",
+	     lockres->l_name, new_level, lockres->l_blocking);
+
+	lockres->l_action = OCFS2_AST_DOWNCONVERT;
+	lockres->l_requested = new_level;
+	lockres_or_flags(lockres, OCFS2_LOCK_BUSY);
+}
+
+static int ocfs2_downconvert_lock(struct ocfs2_super *osb,
+				  struct ocfs2_lock_res *lockres,
+				  int new_level,
+				  int lvb)
+{
+	int ret, dlm_flags = LKM_CONVERT;
+	enum dlm_status status;
+
+	mlog_entry_void();
+
+	if (lvb)
+		dlm_flags |= LKM_VALBLK;
+
+	status = dlmlock(osb->dlm,
+			 new_level,
+			 &lockres->l_lksb,
+			 dlm_flags,
+			 lockres->l_name,
+			 lockres->l_ops->ast,
+			 lockres,
+			 lockres->l_ops->bast);
+	if (status != DLM_NORMAL) {
+		ocfs2_log_dlm_error("dlmlock", status, lockres);
+		ret = -EINVAL;
+		ocfs2_recover_from_dlm_error(lockres, 1);
+		goto bail;
+	}
+
+	ret = 0;
+bail:
+	mlog_exit(ret);
+	return ret;
+}
+
+/* returns 1 when the caller should unlock and call dlmunlock */
+static int ocfs2_prepare_cancel_convert(struct ocfs2_super *osb,
+				        struct ocfs2_lock_res *lockres)
+{
+	assert_spin_locked(&lockres->l_lock);
+
+	mlog_entry_void();
+	mlog(0, "lock %s\n", lockres->l_name);
+
+	if (lockres->l_unlock_action == OCFS2_UNLOCK_CANCEL_CONVERT) {
+		/* If we're already trying to cancel a lock conversion
+		 * then just drop the spinlock and allow the caller to
+		 * requeue this lock. */
+
+		mlog(0, "Lockres %s, skip convert\n", lockres->l_name);
+		return 0;
+	}
+
+	/* were we in a convert when we got the bast fire? */
+	BUG_ON(lockres->l_action != OCFS2_AST_CONVERT &&
+	       lockres->l_action != OCFS2_AST_DOWNCONVERT);
+	/* set things up for the unlockast to know to just
+	 * clear out the ast_action and unset busy, etc. */
+	lockres->l_unlock_action = OCFS2_UNLOCK_CANCEL_CONVERT;
+
+	mlog_bug_on_msg(!(lockres->l_flags & OCFS2_LOCK_BUSY),
+			"lock %s, invalid flags: 0x%lx\n",
+			lockres->l_name, lockres->l_flags);
+
+	return 1;
+}
+
+static int ocfs2_cancel_convert(struct ocfs2_super *osb,
+				struct ocfs2_lock_res *lockres)
+{
+	int ret;
+	enum dlm_status status;
+
+	mlog_entry_void();
+	mlog(0, "lock %s\n", lockres->l_name);
+
+	ret = 0;
+	status = dlmunlock(osb->dlm,
+			   &lockres->l_lksb,
+			   LKM_CANCEL,
+			   lockres->l_ops->unlock_ast,
+			   lockres);
+	if (status != DLM_NORMAL) {
+		ocfs2_log_dlm_error("dlmunlock", status, lockres);
+		ret = -EINVAL;
+		ocfs2_recover_from_dlm_error(lockres, 0);
+	}
+
+	mlog(0, "lock %s return from dlmunlock\n", lockres->l_name);
+
+	mlog_exit(ret);
+	return ret;
+}
+
+static inline int ocfs2_can_downconvert_meta_lock(struct inode *inode,
+						  struct ocfs2_lock_res *lockres,
+						  int new_level)
+{
+	int ret;
+
+	mlog_entry_void();
+
+	BUG_ON(new_level != LKM_NLMODE && new_level != LKM_PRMODE);
+
+	if (lockres->l_flags & OCFS2_LOCK_REFRESHING) {
+		ret = 0;
+		mlog(0, "lockres %s currently being refreshed -- backing "
+		     "off!\n", lockres->l_name);
+	} else if (new_level == LKM_PRMODE)
+		ret = !lockres->l_ex_holders &&
+			ocfs2_inode_fully_checkpointed(inode);
+	else /* Must be NLMODE we're converting to. */
+		ret = !lockres->l_ro_holders && !lockres->l_ex_holders &&
+			ocfs2_inode_fully_checkpointed(inode);
+
+	mlog_exit(ret);
+	return ret;
+}
+
+static int ocfs2_do_unblock_meta(struct inode *inode,
+				 int *requeue)
+{
+	int new_level;
+	int set_lvb = 0;
+	int ret = 0;
+	struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_meta_lockres;
+	unsigned long flags;
+
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	mlog_entry_void();
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+
+	BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BLOCKED));
+
+	mlog(0, "l_level=%d, l_blocking=%d\n", lockres->l_level,
+	     lockres->l_blocking);
+
+	BUG_ON(lockres->l_level != LKM_EXMODE &&
+	       lockres->l_level != LKM_PRMODE);
+
+	if (lockres->l_flags & OCFS2_LOCK_BUSY) {
+		*requeue = 1;
+		ret = ocfs2_prepare_cancel_convert(osb, lockres);
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		if (ret) {
+			ret = ocfs2_cancel_convert(osb, lockres);
+			if (ret < 0)
+				mlog_errno(ret);
+		}
+		goto leave;
+	}
+
+	new_level = ocfs2_highest_compat_lock_level(lockres->l_blocking);
+
+	mlog(0, "l_level=%d, l_blocking=%d, new_level=%d\n",
+	     lockres->l_level, lockres->l_blocking, new_level);
+
+	if (ocfs2_can_downconvert_meta_lock(inode, lockres, new_level)) {
+		if (lockres->l_level == LKM_EXMODE)
+			set_lvb = 1;
+
+		/* If the lock hasn't been refreshed yet (rare), then
+		 * our memory inode values are old and we skip
+		 * stuffing the lvb. There's no need to actually clear
+		 * out the lvb here as it's value is still valid. */
+		if (!(lockres->l_flags & OCFS2_LOCK_NEEDS_REFRESH)) {
+			if (set_lvb)
+				__ocfs2_stuff_meta_lvb(inode);
+		} else
+			mlog(0, "lockres %s: downconverting stale lock!\n",
+			     lockres->l_name);
+
+		mlog(0, "calling ocfs2_downconvert_lock with l_level=%d, "
+		     "l_blocking=%d, new_level=%d\n",
+		     lockres->l_level, lockres->l_blocking, new_level);
+
+		ocfs2_prepare_downconvert(lockres, new_level);
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		ret = ocfs2_downconvert_lock(osb, lockres, new_level, set_lvb);
+		goto leave;
+	}
+	if (!ocfs2_inode_fully_checkpointed(inode))
+		ocfs2_start_checkpoint(osb);
+
+	*requeue = 1;
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+	ret = 0;
+leave:
+	mlog_exit(ret);
+	return ret;
+}
+
+static int ocfs2_generic_unblock_lock(struct ocfs2_super *osb,
+				      struct ocfs2_lock_res *lockres,
+				      int *requeue,
+				      ocfs2_convert_worker_t *worker)
+{
+	unsigned long flags;
+	int blocking;
+	int new_level;
+	int ret = 0;
+
+	mlog_entry_void();
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+
+	BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BLOCKED));
+
+recheck:
+	if (lockres->l_flags & OCFS2_LOCK_BUSY) {
+		*requeue = 1;
+		ret = ocfs2_prepare_cancel_convert(osb, lockres);
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		if (ret) {
+			ret = ocfs2_cancel_convert(osb, lockres);
+			if (ret < 0)
+				mlog_errno(ret);
+		}
+		goto leave;
+	}
+
+	/* if we're blocking an exclusive and we have *any* holders,
+	 * then requeue. */
+	if ((lockres->l_blocking == LKM_EXMODE)
+	    && (lockres->l_ex_holders || lockres->l_ro_holders)) {
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		*requeue = 1;
+		ret = 0;
+		goto leave;
+	}
+
+	/* If it's a PR we're blocking, then only
+	 * requeue if we've got any EX holders */
+	if (lockres->l_blocking == LKM_PRMODE &&
+	    lockres->l_ex_holders) {
+		spin_unlock_irqrestore(&lockres->l_lock, flags);
+		*requeue = 1;
+		ret = 0;
+		goto leave;
+	}
+
+	/* If we get here, then we know that there are no more
+	 * incompatible holders (and anyone asking for an incompatible
+	 * lock is blocked). We can now downconvert the lock */
+	if (!worker)
+		goto downconvert;
+
+	/* Some lockres types want to do a bit of work before
+	 * downconverting a lock. Allow that here. The worker function
+	 * may sleep, so we save off a copy of what we're blocking as
+	 * it may change while we're not holding the spin lock. */
+	blocking = lockres->l_blocking;
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	worker(lockres, blocking);
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	if (blocking != lockres->l_blocking) {
+		/* If this changed underneath us, then we can't drop
+		 * it just yet. */
+		goto recheck;
+	}
+
+downconvert:
+	*requeue = 0;
+	new_level = ocfs2_highest_compat_lock_level(lockres->l_blocking);
+
+	ocfs2_prepare_downconvert(lockres, new_level);
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+	ret = ocfs2_downconvert_lock(osb, lockres, new_level, 0);
+leave:
+	mlog_exit(ret);
+	return ret;
+}
+
+static void ocfs2_data_convert_worker(struct ocfs2_lock_res *lockres,
+				      int blocking)
+{
+	struct inode *inode;
+	struct address_space *mapping;
+
+	mlog_entry_void();
+
+       	inode = ocfs2_lock_res_inode(lockres);
+	mapping = inode->i_mapping;
+
+	if (filemap_fdatawrite(mapping)) {
+		mlog(ML_ERROR, "Could not sync inode %"MLFu64" for downconvert!",
+		     OCFS2_I(inode)->ip_blkno);
+	}
+	sync_mapping_buffers(mapping);
+	if (blocking == LKM_EXMODE) {
+		truncate_inode_pages(mapping, 0);
+		unmap_mapping_range(mapping, 0, 0, 0);
+	} else {
+		/* We only need to wait on the I/O if we're not also
+		 * truncating pages because truncate_inode_pages waits
+		 * for us above. We don't truncate pages if we're
+		 * blocking anything < EXMODE because we want to keep
+		 * them around in that case. */
+		filemap_fdatawait(mapping);
+	}
+
+	mlog_exit_void();
+}
+
+int ocfs2_unblock_data(struct ocfs2_lock_res *lockres,
+		       int *requeue)
+{
+	int status;
+	struct inode *inode;
+	struct ocfs2_super *osb;
+
+	mlog_entry_void();
+
+	inode = ocfs2_lock_res_inode(lockres);
+	osb = OCFS2_SB(inode->i_sb);
+
+	mlog(0, "unblock inode %"MLFu64"\n", OCFS2_I(inode)->ip_blkno);
+
+	status = ocfs2_generic_unblock_lock(osb,
+					    lockres,
+					    requeue,
+					    ocfs2_data_convert_worker);
+	if (status < 0)
+		mlog_errno(status);
+
+	mlog(0, "inode %"MLFu64", requeue = %d\n",
+	     OCFS2_I(inode)->ip_blkno, *requeue);
+
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_unblock_inode_lock(struct ocfs2_lock_res *lockres,
+				    int *requeue)
+{
+	int status;
+	struct inode *inode;
+
+	mlog_entry_void();
+
+	mlog(0, "Unblock lockres %s\n", lockres->l_name);
+
+	inode  = ocfs2_lock_res_inode(lockres);
+
+	status = ocfs2_generic_unblock_lock(OCFS2_SB(inode->i_sb),
+					    lockres,
+					    requeue,
+					    NULL);
+	if (status < 0)
+		mlog_errno(status);
+
+	mlog_exit(status);
+	return status;
+}
+
+
+int ocfs2_unblock_meta(struct ocfs2_lock_res *lockres,
+		       int *requeue)
+{
+	int status;
+	struct inode *inode;
+
+	mlog_entry_void();
+
+       	inode = ocfs2_lock_res_inode(lockres);
+
+	mlog(0, "unblock inode %"MLFu64"\n", OCFS2_I(inode)->ip_blkno);
+
+	status = ocfs2_do_unblock_meta(inode, requeue);
+	if (status < 0)
+		mlog_errno(status);
+
+	mlog(0, "inode %"MLFu64", requeue = %d\n",
+	     OCFS2_I(inode)->ip_blkno, *requeue);
+
+	mlog_exit(status);
+	return status;
+}
+
+/* Generic unblock function for any lockres whose private data is an
+ * ocfs2_super pointer. */
+static int ocfs2_unblock_osb_lock(struct ocfs2_lock_res *lockres,
+				  int *requeue)
+{
+	int status;
+	struct ocfs2_super *osb;
+
+	mlog_entry_void();
+
+	mlog(0, "Unblock lockres %s\n", lockres->l_name);
+
+	osb = ocfs2_lock_res_super(lockres);
+
+	status = ocfs2_generic_unblock_lock(osb,
+					    lockres,
+					    requeue,
+					    NULL);
+	if (status < 0)
+		mlog_errno(status);
+
+	mlog_exit(status);
+	return status;
+}
+
+void ocfs2_process_blocked_lock(struct ocfs2_super *osb,
+				struct ocfs2_lock_res *lockres)
+{
+	int status;
+	int requeue = 0;
+	unsigned long flags;
+
+	/* Our reference to the lockres in this function can be
+	 * considered valid until we remove the OCFS2_LOCK_QUEUED
+	 * flag. */
+
+	mlog_entry_void();
+
+	BUG_ON(!lockres);
+	BUG_ON(!lockres->l_ops);
+	BUG_ON(!lockres->l_ops->unblock);
+
+	mlog(0, "lockres %s blocked.\n", lockres->l_name);
+
+	/* Detect whether a lock has been marked as going away while
+	 * the vote thread was processing other things. A lock can
+	 * still be marked with OCFS2_LOCK_FREEING after this check,
+	 * but short circuiting here will still save us some
+	 * performance. */
+	spin_lock_irqsave(&lockres->l_lock, flags);
+	if (lockres->l_flags & OCFS2_LOCK_FREEING)
+		goto unqueue;
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	status = lockres->l_ops->unblock(lockres, &requeue);
+	if (status < 0)
+		mlog_errno(status);
+
+	spin_lock_irqsave(&lockres->l_lock, flags);
+unqueue:
+	if (lockres->l_flags & OCFS2_LOCK_FREEING || !requeue) {
+		lockres_clear_flags(lockres, OCFS2_LOCK_QUEUED);
+	} else
+		ocfs2_schedule_blocked_lock(osb, lockres);
+
+	mlog(0, "lockres %s, requeue = %s.\n", lockres->l_name,
+	     requeue ? "yes" : "no");
+	spin_unlock_irqrestore(&lockres->l_lock, flags);
+
+	mlog_exit_void();
+}
+
+static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb,
+					struct ocfs2_lock_res *lockres)
+{
+	mlog_entry_void();
+
+	assert_spin_locked(&lockres->l_lock);
+
+	if (lockres->l_flags & OCFS2_LOCK_FREEING) {
+		/* Do not schedule a lock for downconvert when it's on
+		 * the way to destruction - any nodes wanting access
+		 * to the resource will get it soon. */
+		mlog(0, "Lockres %s won't be scheduled: flags 0x%lx\n",
+		     lockres->l_name, lockres->l_flags);
+		return;
+	}
+
+	lockres_or_flags(lockres, OCFS2_LOCK_QUEUED);
+
+	spin_lock(&osb->vote_task_lock);
+	if (list_empty(&lockres->l_blocked_list)) {
+		list_add_tail(&lockres->l_blocked_list,
+			      &osb->blocked_lock_list);
+		osb->blocked_lock_count++;
+	}
+	spin_unlock(&osb->vote_task_lock);
+
+	mlog_exit_void();
+}
+
+/* This aids in debugging situations where a bad LVB might be involved. */
+void ocfs2_dump_meta_lvb_info(u64 level,
+			      const char *function,
+			      unsigned int line,
+			      struct ocfs2_lock_res *lockres)
+{
+	struct ocfs2_meta_lvb *lvb = (struct ocfs2_meta_lvb *) lockres->l_lksb.lvb;
+
+	mlog(level, "LVB information for %s (called from %s:%u):\n",
+	     lockres->l_name, function, line);
+	mlog(level, "version: %u, clusters: %u\n",
+	     be32_to_cpu(lvb->lvb_version), be32_to_cpu(lvb->lvb_iclusters));
+	mlog(level, "size: %"MLFu64", uid %u, gid %u, mode 0x%x\n",
+	     be64_to_cpu(lvb->lvb_isize), be32_to_cpu(lvb->lvb_iuid),
+	     be32_to_cpu(lvb->lvb_igid), be16_to_cpu(lvb->lvb_imode));
+	mlog(level, "nlink %u, atime_packed 0x%"MLFx64", "
+	     "ctime_packed 0x%"MLFx64", mtime_packed 0x%"MLFx64"\n",
+	     be16_to_cpu(lvb->lvb_inlink), be64_to_cpu(lvb->lvb_iatime_packed),
+	     be64_to_cpu(lvb->lvb_ictime_packed),
+	     be64_to_cpu(lvb->lvb_imtime_packed));
+}
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h
new file mode 100644
index 0000000..8f2d1db
--- /dev/null
+++ b/fs/ocfs2/dlmglue.h
@@ -0,0 +1,111 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * dlmglue.h
+ *
+ * description here
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+
+#ifndef DLMGLUE_H
+#define DLMGLUE_H
+
+#define OCFS2_LVB_VERSION 2
+
+struct ocfs2_meta_lvb {
+	__be32       lvb_version;
+	__be32       lvb_iclusters;
+	__be32       lvb_iuid;
+	__be32       lvb_igid;
+	__be64       lvb_iatime_packed;
+	__be64       lvb_ictime_packed;
+	__be64       lvb_imtime_packed;
+	__be64       lvb_isize;
+	__be16       lvb_imode;
+	__be16       lvb_inlink;
+	__be32       lvb_reserved[3];
+};
+
+/* ocfs2_meta_lock_full() and ocfs2_data_lock_full() 'arg_flags' flags */
+/* don't wait on recovery. */
+#define OCFS2_META_LOCK_RECOVERY	(0x01)
+/* Instruct the dlm not to queue ourselves on the other node. */
+#define OCFS2_META_LOCK_NOQUEUE		(0x02)
+/* don't block waiting for the vote thread, instead return -EAGAIN */
+#define OCFS2_LOCK_NONBLOCK		(0x04)
+
+int ocfs2_dlm_init(struct ocfs2_super *osb);
+void ocfs2_dlm_shutdown(struct ocfs2_super *osb);
+void ocfs2_lock_res_init_once(struct ocfs2_lock_res *res);
+void ocfs2_inode_lock_res_init(struct ocfs2_lock_res *res,
+			       enum ocfs2_lock_type type,
+			       struct inode *inode);
+void ocfs2_lock_res_free(struct ocfs2_lock_res *res);
+int ocfs2_create_new_inode_locks(struct inode *inode);
+int ocfs2_drop_inode_locks(struct inode *inode);
+int ocfs2_data_lock_full(struct inode *inode,
+			 int write,
+			 int arg_flags);
+#define ocfs2_data_lock(inode, write) ocfs2_data_lock_full(inode, write, 0)
+int ocfs2_data_lock_with_page(struct inode *inode,
+			      int write,
+			      struct page *page);
+void ocfs2_data_unlock(struct inode *inode,
+		       int write);
+int ocfs2_rw_lock(struct inode *inode, int write);
+void ocfs2_rw_unlock(struct inode *inode, int write);
+int ocfs2_meta_lock_full(struct inode *inode,
+			 struct ocfs2_journal_handle *handle,
+			 struct buffer_head **ret_bh,
+			 int ex,
+			 int arg_flags);
+int ocfs2_meta_lock_with_page(struct inode *inode,
+			      struct ocfs2_journal_handle *handle,
+			      struct buffer_head **ret_bh,
+			      int ex,
+			      struct page *page);
+/* 99% of the time we don't want to supply any additional flags --
+ * those are for very specific cases only. */
+#define ocfs2_meta_lock(i, h, b, e) ocfs2_meta_lock_full(i, h, b, e, 0)
+void ocfs2_meta_unlock(struct inode *inode,
+		       int ex);
+int ocfs2_super_lock(struct ocfs2_super *osb,
+		     int ex);
+void ocfs2_super_unlock(struct ocfs2_super *osb,
+			int ex);
+int ocfs2_rename_lock(struct ocfs2_super *osb);
+void ocfs2_rename_unlock(struct ocfs2_super *osb);
+void ocfs2_mark_lockres_freeing(struct ocfs2_lock_res *lockres);
+
+/* for the vote thread */
+void ocfs2_process_blocked_lock(struct ocfs2_super *osb,
+				struct ocfs2_lock_res *lockres);
+
+struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void);
+void ocfs2_put_dlm_debug(struct ocfs2_dlm_debug *dlm_debug);
+
+/* aids in debugging and tracking lvbs */
+void ocfs2_dump_meta_lvb_info(u64 level,
+			      const char *function,
+			      unsigned int line,
+			      struct ocfs2_lock_res *lockres);
+#define mlog_meta_lvb(__level, __lockres) ocfs2_dump_meta_lvb_info(__level, __PRETTY_FUNCTION__, __LINE__, __lockres)
+
+#endif	/* DLMGLUE_H */
diff --git a/fs/ocfs2/endian.h b/fs/ocfs2/endian.h
new file mode 100644
index 0000000..f226b22
--- /dev/null
+++ b/fs/ocfs2/endian.h
@@ -0,0 +1,45 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_ENDIAN_H
+#define OCFS2_ENDIAN_H
+
+static inline void le16_add_cpu(__le16 *var, u16 val)
+{
+	*var = cpu_to_le16(le16_to_cpu(*var) + val);
+}
+
+static inline void le32_add_cpu(__le32 *var, u32 val)
+{
+	*var = cpu_to_le32(le32_to_cpu(*var) + val);
+}
+
+static inline void le32_and_cpu(__le32 *var, u32 val)
+{
+	*var = cpu_to_le32(le32_to_cpu(*var) & val);
+}
+
+static inline void be32_add_cpu(__be32 *var, u32 val)
+{
+	*var = cpu_to_be32(be32_to_cpu(*var) + val);
+}
+
+#endif /* OCFS2_ENDIAN_H */
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
new file mode 100644
index 0000000..5810160
--- /dev/null
+++ b/fs/ocfs2/export.c
@@ -0,0 +1,248 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * export.c
+ *
+ * Functions to facilitate NFS exporting
+ *
+ * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+
+#define MLOG_MASK_PREFIX ML_EXPORT
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "dir.h"
+#include "dlmglue.h"
+#include "export.h"
+#include "inode.h"
+
+#include "buffer_head_io.h"
+
+struct ocfs2_inode_handle
+{
+	u64 ih_blkno;
+	u32 ih_generation;
+};
+
+static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp)
+{
+	struct ocfs2_inode_handle *handle = vobjp;
+	struct inode *inode;
+	struct dentry *result;
+
+	mlog_entry("(0x%p, 0x%p)\n", sb, handle);
+
+	if (handle->ih_blkno == 0) {
+		mlog_errno(-ESTALE);
+		return ERR_PTR(-ESTALE);
+	}
+
+	inode = ocfs2_iget(OCFS2_SB(sb), handle->ih_blkno);
+
+	if (IS_ERR(inode)) {
+		mlog_errno(PTR_ERR(inode));
+		return (void *)inode;
+	}
+
+	if (handle->ih_generation != inode->i_generation) {
+		iput(inode);
+		mlog_errno(-ESTALE);
+		return ERR_PTR(-ESTALE);
+	}
+
+	result = d_alloc_anon(inode);
+
+	if (!result) {
+		iput(inode);
+		mlog_errno(-ENOMEM);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	mlog_exit_ptr(result);
+	return result;
+}
+
+static struct dentry *ocfs2_get_parent(struct dentry *child)
+{
+	int status;
+	u64 blkno;
+	struct dentry *parent;
+	struct inode *inode;
+	struct inode *dir = child->d_inode;
+	struct buffer_head *dirent_bh = NULL;
+	struct ocfs2_dir_entry *dirent;
+
+	mlog_entry("(0x%p, '%.*s')\n", child,
+		   child->d_name.len, child->d_name.name);
+
+	mlog(0, "find parent of directory %"MLFu64"\n",
+	     OCFS2_I(dir)->ip_blkno);
+
+	status = ocfs2_meta_lock(dir, NULL, NULL, 0);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		parent = ERR_PTR(status);
+		goto bail;
+	}
+
+	status = ocfs2_find_files_on_disk("..", 2, &blkno, dir, &dirent_bh,
+					  &dirent);
+	if (status < 0) {
+		parent = ERR_PTR(-ENOENT);
+		goto bail_unlock;
+	}
+
+	inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno);
+	if (IS_ERR(inode)) {
+		mlog(ML_ERROR, "Unable to create inode %"MLFu64"\n", blkno);
+		parent = ERR_PTR(-EACCES);
+		goto bail_unlock;
+	}
+
+	parent = d_alloc_anon(inode);
+	if (!parent) {
+		iput(inode);
+		parent = ERR_PTR(-ENOMEM);
+	}
+
+bail_unlock:
+	ocfs2_meta_unlock(dir, 0);
+
+	if (dirent_bh)
+		brelse(dirent_bh);
+
+bail:
+	mlog_exit_ptr(parent);
+
+	return parent;
+}
+
+static int ocfs2_encode_fh(struct dentry *dentry, __be32 *fh, int *max_len,
+			   int connectable)
+{
+	struct inode *inode = dentry->d_inode;
+	int len = *max_len;
+	int type = 1;
+	u64 blkno;
+	u32 generation;
+
+	mlog_entry("(0x%p, '%.*s', 0x%p, %d, %d)\n", dentry,
+		   dentry->d_name.len, dentry->d_name.name,
+		   fh, len, connectable);
+
+	if (len < 3 || (connectable && len < 6)) {
+		mlog(ML_ERROR, "fh buffer is too small for encoding\n");
+		type = 255;
+		goto bail;
+	}
+
+	blkno = OCFS2_I(inode)->ip_blkno;
+	generation = inode->i_generation;
+
+	mlog(0, "Encoding fh: blkno: %"MLFu64", generation: %u\n",
+	     blkno, generation);
+
+	len = 3;
+	fh[0] = cpu_to_le32((u32)(blkno >> 32));
+	fh[1] = cpu_to_le32((u32)(blkno & 0xffffffff));
+	fh[2] = cpu_to_le32(generation);
+
+	if (connectable && !S_ISDIR(inode->i_mode)) {
+		struct inode *parent;
+
+		spin_lock(&dentry->d_lock);
+
+		parent = dentry->d_parent->d_inode;
+		blkno = OCFS2_I(parent)->ip_blkno;
+		generation = parent->i_generation;
+
+		fh[3] = cpu_to_le32((u32)(blkno >> 32));
+		fh[4] = cpu_to_le32((u32)(blkno & 0xffffffff));
+		fh[5] = cpu_to_le32(generation);
+
+		spin_unlock(&dentry->d_lock);
+
+		len = 6;
+		type = 2;
+
+		mlog(0, "Encoding parent: blkno: %"MLFu64", generation: %u\n",
+		     blkno, generation);
+	}
+	
+	*max_len = len;
+
+bail:
+	mlog_exit(type);
+	return type;
+}
+
+static struct dentry *ocfs2_decode_fh(struct super_block *sb, __be32 *fh,
+				      int fh_len, int fileid_type,
+				      int (*acceptable)(void *context,
+						        struct dentry *de),
+				      void *context)
+{
+	struct ocfs2_inode_handle handle, parent;
+	struct dentry *ret = NULL;
+
+	mlog_entry("(0x%p, 0x%p, %d, %d, 0x%p, 0x%p)\n",
+		   sb, fh, fh_len, fileid_type, acceptable, context);
+
+	if (fh_len < 3 || fileid_type > 2)
+		goto bail;
+
+	if (fileid_type == 2) {
+		if (fh_len < 6)
+			goto bail;
+
+		parent.ih_blkno = (u64)le32_to_cpu(fh[3]) << 32;
+		parent.ih_blkno |= (u64)le32_to_cpu(fh[4]);
+		parent.ih_generation = le32_to_cpu(fh[5]);
+
+		mlog(0, "Decoding parent: blkno: %"MLFu64", generation: %u\n",
+		     parent.ih_blkno, parent.ih_generation);
+	}
+
+	handle.ih_blkno = (u64)le32_to_cpu(fh[0]) << 32;
+	handle.ih_blkno |= (u64)le32_to_cpu(fh[1]);
+	handle.ih_generation = le32_to_cpu(fh[2]);
+
+	mlog(0, "Encoding fh: blkno: %"MLFu64", generation: %u\n",
+	     handle.ih_blkno, handle.ih_generation);
+
+	ret = ocfs2_export_ops.find_exported_dentry(sb, &handle, &parent,
+						    acceptable, context);
+
+bail:
+	mlog_exit_ptr(ret);
+	return ret;
+}
+
+struct export_operations ocfs2_export_ops = {
+	.decode_fh	= ocfs2_decode_fh,
+	.encode_fh	= ocfs2_encode_fh,
+
+	.get_parent	= ocfs2_get_parent,
+	.get_dentry	= ocfs2_get_dentry,
+};
diff --git a/fs/ocfs2/export.h b/fs/ocfs2/export.h
new file mode 100644
index 0000000..5b77ee7
--- /dev/null
+++ b/fs/ocfs2/export.h
@@ -0,0 +1,31 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * export.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_EXPORT_H
+#define OCFS2_EXPORT_H
+
+extern struct export_operations ocfs2_export_ops;
+
+#endif /* OCFS2_EXPORT_H */
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
new file mode 100644
index 0000000..f2fb40c
--- /dev/null
+++ b/fs/ocfs2/extent_map.c
@@ -0,0 +1,994 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * extent_map.c
+ *
+ * In-memory extent map for OCFS2.  Man, this code was prettier in
+ * the library.
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/rbtree.h>
+
+#define MLOG_MASK_PREFIX ML_EXTENT_MAP
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "extent_map.h"
+#include "inode.h"
+#include "super.h"
+
+#include "buffer_head_io.h"
+
+
+/*
+ * SUCK SUCK SUCK
+ * Our headers are so bad that struct ocfs2_extent_map is in ocfs.h
+ */
+
+struct ocfs2_extent_map_entry {
+	struct rb_node e_node;
+	int e_tree_depth;
+	struct ocfs2_extent_rec e_rec;
+};
+
+struct ocfs2_em_insert_context {
+	int need_left;
+	int need_right;
+	struct ocfs2_extent_map_entry *new_ent;
+	struct ocfs2_extent_map_entry *old_ent;
+	struct ocfs2_extent_map_entry *left_ent;
+	struct ocfs2_extent_map_entry *right_ent;
+};
+
+static kmem_cache_t *ocfs2_em_ent_cachep = NULL;
+
+
+static struct ocfs2_extent_map_entry *
+ocfs2_extent_map_lookup(struct ocfs2_extent_map *em,
+			u32 cpos, u32 clusters,
+			struct rb_node ***ret_p,
+			struct rb_node **ret_parent);
+static int ocfs2_extent_map_insert(struct inode *inode,
+				   struct ocfs2_extent_rec *rec,
+				   int tree_depth);
+static int ocfs2_extent_map_insert_entry(struct ocfs2_extent_map *em,
+					 struct ocfs2_extent_map_entry *ent);
+static int ocfs2_extent_map_find_leaf(struct inode *inode,
+				      u32 cpos, u32 clusters,
+				      struct ocfs2_extent_list *el);
+static int ocfs2_extent_map_lookup_read(struct inode *inode,
+					u32 cpos, u32 clusters,
+					struct ocfs2_extent_map_entry **ret_ent);
+static int ocfs2_extent_map_try_insert(struct inode *inode,
+				       struct ocfs2_extent_rec *rec,
+				       int tree_depth,
+				       struct ocfs2_em_insert_context *ctxt);
+
+/* returns 1 only if the rec contains all the given clusters -- that is that
+ * rec's cpos is <= the cluster cpos and that the rec endpoint (cpos +
+ * clusters) is >= the argument's endpoint */
+static int ocfs2_extent_rec_contains_clusters(struct ocfs2_extent_rec *rec,
+					      u32 cpos, u32 clusters)
+{
+	if (le32_to_cpu(rec->e_cpos) > cpos)
+		return 0;
+	if (cpos + clusters > le32_to_cpu(rec->e_cpos) + 
+			      le32_to_cpu(rec->e_clusters))
+		return 0;
+	return 1;
+}
+
+
+/*
+ * Find an entry in the tree that intersects the region passed in.
+ * Note that this will find straddled intervals, it is up to the
+ * callers to enforce any boundary conditions.
+ *
+ * Callers must hold ip_lock.  This lookup is not guaranteed to return
+ * a tree_depth 0 match, and as such can race inserts if the lock
+ * were not held.
+ *
+ * The rb_node garbage lets insertion share the search.  Trivial
+ * callers pass NULL.
+ */
+static struct ocfs2_extent_map_entry *
+ocfs2_extent_map_lookup(struct ocfs2_extent_map *em,
+			u32 cpos, u32 clusters,
+			struct rb_node ***ret_p,
+			struct rb_node **ret_parent)
+{
+	struct rb_node **p = &em->em_extents.rb_node;
+	struct rb_node *parent = NULL;
+	struct ocfs2_extent_map_entry *ent = NULL;
+
+	while (*p)
+	{
+		parent = *p;
+		ent = rb_entry(parent, struct ocfs2_extent_map_entry,
+			       e_node);
+		if ((cpos + clusters) <= le32_to_cpu(ent->e_rec.e_cpos)) {
+			p = &(*p)->rb_left;
+			ent = NULL;
+		} else if (cpos >= (le32_to_cpu(ent->e_rec.e_cpos) +
+				    le32_to_cpu(ent->e_rec.e_clusters))) {
+			p = &(*p)->rb_right;
+			ent = NULL;
+		} else
+			break;
+	}
+
+	if (ret_p != NULL)
+		*ret_p = p;
+	if (ret_parent != NULL)
+		*ret_parent = parent;
+	return ent;
+}
+
+/*
+ * Find the leaf containing the interval we want.  While we're on our
+ * way down the tree, fill in every record we see at any depth, because
+ * we might want it later.
+ *
+ * Note that this code is run without ip_lock.  That's because it
+ * sleeps while reading.  If someone is also filling the extent list at
+ * the same time we are, we might have to restart.
+ */
+static int ocfs2_extent_map_find_leaf(struct inode *inode,
+				      u32 cpos, u32 clusters,
+				      struct ocfs2_extent_list *el)
+{
+	int i, ret;
+	struct buffer_head *eb_bh = NULL;
+	u64 blkno;
+	u32 rec_end;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_extent_rec *rec;
+
+	/*
+	 * The bh data containing the el cannot change here, because
+	 * we hold alloc_sem.  So we can do this without other
+	 * locks.
+	 */
+	while (el->l_tree_depth)
+	{
+		blkno = 0;
+		for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
+			rec = &el->l_recs[i];
+			rec_end = (le32_to_cpu(rec->e_cpos) +
+				   le32_to_cpu(rec->e_clusters));
+
+			ret = -EBADR;
+			if (rec_end > OCFS2_I(inode)->ip_clusters) {
+				mlog_errno(ret);
+				goto out_free;
+			}
+
+			if (rec_end <= cpos) {
+				ret = ocfs2_extent_map_insert(inode, rec,
+						le16_to_cpu(el->l_tree_depth));
+				if (ret && (ret != -EEXIST)) {
+					mlog_errno(ret);
+					goto out_free;
+				}
+				continue;
+			}
+			if ((cpos + clusters) <= le32_to_cpu(rec->e_cpos)) {
+				ret = ocfs2_extent_map_insert(inode, rec,
+						le16_to_cpu(el->l_tree_depth));
+				if (ret && (ret != -EEXIST)) {
+					mlog_errno(ret);
+					goto out_free;
+				}
+				continue;
+			}
+
+			/*
+			 * We've found a record that matches our
+			 * interval.  We don't insert it because we're
+			 * about to traverse it.
+			 */
+
+			/* Check to see if we're stradling */
+			ret = -ESRCH;
+			if (!ocfs2_extent_rec_contains_clusters(rec,
+							        cpos,
+								clusters)) {
+				mlog_errno(ret);
+				goto out_free;
+			}
+
+			/*
+			 * If we've already found a record, the el has
+			 * two records covering the same interval.
+			 * EEEK!
+			 */
+			ret = -EBADR;
+			if (blkno) {
+				mlog_errno(ret);
+				goto out_free;
+			}
+
+			blkno = le64_to_cpu(rec->e_blkno);
+		}
+
+		/*
+		 * We don't support holes, and we're still up
+		 * in the branches, so we'd better have found someone
+		 */
+		ret = -EBADR;
+		if (!blkno) {
+			mlog_errno(ret);
+			goto out_free;
+		}
+
+		if (eb_bh) {
+			brelse(eb_bh);
+			eb_bh = NULL;
+		}
+		ret = ocfs2_read_block(OCFS2_SB(inode->i_sb),
+				       blkno, &eb_bh, OCFS2_BH_CACHED,
+				       inode);
+		if (ret) {
+			mlog_errno(ret);
+			goto out_free;
+		}
+		eb = (struct ocfs2_extent_block *)eb_bh->b_data;
+		if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+			OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, eb);
+			ret = -EIO;
+			goto out_free;
+		}
+		el = &eb->h_list;
+	}
+
+	if (el->l_tree_depth)
+		BUG();
+
+	for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) {
+		rec = &el->l_recs[i];
+		ret = ocfs2_extent_map_insert(inode, rec,
+					      le16_to_cpu(el->l_tree_depth));
+		if (ret) {
+			mlog_errno(ret);
+			goto out_free;
+		}
+	}
+
+	ret = 0;
+
+out_free:
+	if (eb_bh)
+		brelse(eb_bh);
+
+	return ret;
+}
+
+/*
+ * This lookup actually will read from disk.  It has one invariant:
+ * It will never re-traverse blocks.  This means that all inserts should
+ * be new regions or more granular regions (both allowed by insert).
+ */
+static int ocfs2_extent_map_lookup_read(struct inode *inode,
+					u32 cpos,
+					u32 clusters,
+					struct ocfs2_extent_map_entry **ret_ent)
+{
+	int ret;
+	u64 blkno;
+	struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map;
+	struct ocfs2_extent_map_entry *ent;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_extent_block *eb;
+	struct ocfs2_dinode *di;
+	struct ocfs2_extent_list *el;
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	ent = ocfs2_extent_map_lookup(em, cpos, clusters, NULL, NULL);
+	if (ent) {
+		if (!ent->e_tree_depth) {
+			spin_unlock(&OCFS2_I(inode)->ip_lock);
+			*ret_ent = ent;
+			return 0;
+		}
+		blkno = le64_to_cpu(ent->e_rec.e_blkno);
+		spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+		ret = ocfs2_read_block(OCFS2_SB(inode->i_sb), blkno, &bh,
+				       OCFS2_BH_CACHED, inode);
+		if (ret) {
+			mlog_errno(ret);
+			if (bh)
+				brelse(bh);
+			return ret;
+		}
+		eb = (struct ocfs2_extent_block *)bh->b_data;
+		if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
+			OCFS2_RO_ON_INVALID_EXTENT_BLOCK(inode->i_sb, eb);
+			brelse(bh);
+			return -EIO;
+		}
+		el = &eb->h_list;
+	} else {
+		spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+		ret = ocfs2_read_block(OCFS2_SB(inode->i_sb),
+				       OCFS2_I(inode)->ip_blkno, &bh,
+				       OCFS2_BH_CACHED, inode);
+		if (ret) {
+			mlog_errno(ret);
+			if (bh)
+				brelse(bh);
+			return ret;
+		}
+		di = (struct ocfs2_dinode *)bh->b_data;
+		if (!OCFS2_IS_VALID_DINODE(di)) {
+			brelse(bh);
+			OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, di);
+			return -EIO;
+		}
+		el = &di->id2.i_list;
+	}
+
+	ret = ocfs2_extent_map_find_leaf(inode, cpos, clusters, el);
+	brelse(bh);
+	if (ret) {
+		mlog_errno(ret);
+		return ret;
+	}
+
+	ent = ocfs2_extent_map_lookup(em, cpos, clusters, NULL, NULL);
+	if (!ent) {
+		ret = -ESRCH;
+		mlog_errno(ret);
+		return ret;
+	}
+
+	if (ent->e_tree_depth)
+		BUG();  /* FIXME: Make sure this isn't a corruption */
+
+	*ret_ent = ent;
+
+	return 0;
+}
+
+/*
+ * Callers must hold ip_lock.  This can insert pieces of the tree,
+ * thus racing lookup if the lock weren't held.
+ */
+static int ocfs2_extent_map_insert_entry(struct ocfs2_extent_map *em,
+					 struct ocfs2_extent_map_entry *ent)
+{
+	struct rb_node **p, *parent;
+	struct ocfs2_extent_map_entry *old_ent;
+
+	old_ent = ocfs2_extent_map_lookup(em, le32_to_cpu(ent->e_rec.e_cpos),
+					  le32_to_cpu(ent->e_rec.e_clusters),
+					  &p, &parent);
+	if (old_ent)
+		return -EEXIST;
+
+	rb_link_node(&ent->e_node, parent, p);
+	rb_insert_color(&ent->e_node, &em->em_extents);
+
+	return 0;
+}
+
+
+/*
+ * Simple rule: on any return code other than -EAGAIN, anything left
+ * in the insert_context will be freed.
+ */
+static int ocfs2_extent_map_try_insert(struct inode *inode,
+				       struct ocfs2_extent_rec *rec,
+				       int tree_depth,
+				       struct ocfs2_em_insert_context *ctxt)
+{
+	int ret;
+	struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map;
+	struct ocfs2_extent_map_entry *old_ent;
+
+	ctxt->need_left = 0;
+	ctxt->need_right = 0;
+	ctxt->old_ent = NULL;
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	ret = ocfs2_extent_map_insert_entry(em, ctxt->new_ent);
+	if (!ret) {
+		ctxt->new_ent = NULL;
+		goto out_unlock;
+	}
+
+	old_ent = ocfs2_extent_map_lookup(em, le32_to_cpu(rec->e_cpos),
+					  le32_to_cpu(rec->e_clusters), NULL,
+					  NULL);
+
+	if (!old_ent)
+		BUG();
+
+	ret = -EEXIST;
+	if (old_ent->e_tree_depth < tree_depth)
+		goto out_unlock;
+
+	if (old_ent->e_tree_depth == tree_depth) {
+		if (!memcmp(rec, &old_ent->e_rec,
+			    sizeof(struct ocfs2_extent_rec)))
+			ret = 0;
+
+		/* FIXME: Should this be ESRCH/EBADR??? */
+		goto out_unlock;
+	}
+
+	/*
+	 * We do it in this order specifically so that no actual tree
+	 * changes occur until we have all the pieces we need.  We
+	 * don't want malloc failures to leave an inconsistent tree.
+	 * Whenever we drop the lock, another process could be
+	 * inserting.  Also note that, if another process just beat us
+	 * to an insert, we might not need the same pieces we needed
+	 * the first go round.  In the end, the pieces we need will
+	 * be used, and the pieces we don't will be freed.
+	 */
+	ctxt->need_left = !!(le32_to_cpu(rec->e_cpos) >
+			     le32_to_cpu(old_ent->e_rec.e_cpos));
+	ctxt->need_right = !!((le32_to_cpu(old_ent->e_rec.e_cpos) +
+			       le32_to_cpu(old_ent->e_rec.e_clusters)) >
+			      (le32_to_cpu(rec->e_cpos) + le32_to_cpu(rec->e_clusters)));
+	ret = -EAGAIN;
+	if (ctxt->need_left) {
+		if (!ctxt->left_ent)
+			goto out_unlock;
+		*(ctxt->left_ent) = *old_ent;
+		ctxt->left_ent->e_rec.e_clusters =
+			cpu_to_le32(le32_to_cpu(rec->e_cpos) -
+				    le32_to_cpu(ctxt->left_ent->e_rec.e_cpos));
+	}
+	if (ctxt->need_right) {
+		if (!ctxt->right_ent)
+			goto out_unlock;
+		*(ctxt->right_ent) = *old_ent;
+		ctxt->right_ent->e_rec.e_cpos =
+			cpu_to_le32(le32_to_cpu(rec->e_cpos) +
+				    le32_to_cpu(rec->e_clusters));
+		ctxt->right_ent->e_rec.e_clusters =
+			cpu_to_le32((le32_to_cpu(old_ent->e_rec.e_cpos) +
+				     le32_to_cpu(old_ent->e_rec.e_clusters)) -
+				    le32_to_cpu(ctxt->right_ent->e_rec.e_cpos));
+	}
+
+	rb_erase(&old_ent->e_node, &em->em_extents);
+	/* Now that he's erased, set him up for deletion */
+	ctxt->old_ent = old_ent;
+
+	if (ctxt->need_left) {
+		ret = ocfs2_extent_map_insert_entry(em,
+						    ctxt->left_ent);
+		if (ret)
+			goto out_unlock;
+		ctxt->left_ent = NULL;
+	}
+
+	if (ctxt->need_right) {
+		ret = ocfs2_extent_map_insert_entry(em,
+						    ctxt->right_ent);
+		if (ret)
+			goto out_unlock;
+		ctxt->right_ent = NULL;
+	}
+
+	ret = ocfs2_extent_map_insert_entry(em, ctxt->new_ent);
+
+	if (!ret)
+		ctxt->new_ent = NULL;
+
+out_unlock:
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	return ret;
+}
+
+
+static int ocfs2_extent_map_insert(struct inode *inode,
+				   struct ocfs2_extent_rec *rec,
+				   int tree_depth)
+{
+	int ret;
+	struct ocfs2_em_insert_context ctxt = {0, };
+
+	if ((le32_to_cpu(rec->e_cpos) + le32_to_cpu(rec->e_clusters)) >
+	    OCFS2_I(inode)->ip_map.em_clusters) {
+		ret = -EBADR;
+		mlog_errno(ret);
+		return ret;
+	}
+
+	/* Zero e_clusters means a truncated tail record.  It better be EOF */
+	if (!rec->e_clusters) {
+		if ((le32_to_cpu(rec->e_cpos) + le32_to_cpu(rec->e_clusters)) !=
+		    OCFS2_I(inode)->ip_map.em_clusters) {
+			ret = -EBADR;
+			mlog_errno(ret);
+			return ret;
+		}
+
+		/* Ignore the truncated tail */
+		return 0;
+	}
+
+	ret = -ENOMEM;
+	ctxt.new_ent = kmem_cache_alloc(ocfs2_em_ent_cachep,
+					GFP_KERNEL);
+	if (!ctxt.new_ent) {
+		mlog_errno(ret);
+		return ret;
+	}
+
+	ctxt.new_ent->e_rec = *rec;
+	ctxt.new_ent->e_tree_depth = tree_depth;
+
+	do {
+		ret = -ENOMEM;
+		if (ctxt.need_left && !ctxt.left_ent) {
+			ctxt.left_ent =
+				kmem_cache_alloc(ocfs2_em_ent_cachep,
+						 GFP_KERNEL);
+			if (!ctxt.left_ent)
+				break;
+		}
+		if (ctxt.need_right && !ctxt.right_ent) {
+			ctxt.right_ent =
+				kmem_cache_alloc(ocfs2_em_ent_cachep,
+						 GFP_KERNEL);
+			if (!ctxt.right_ent)
+				break;
+		}
+
+		ret = ocfs2_extent_map_try_insert(inode, rec,
+						  tree_depth, &ctxt);
+	} while (ret == -EAGAIN);
+
+	if (ret < 0)
+		mlog_errno(ret);
+
+	if (ctxt.left_ent)
+		kmem_cache_free(ocfs2_em_ent_cachep, ctxt.left_ent);
+	if (ctxt.right_ent)
+		kmem_cache_free(ocfs2_em_ent_cachep, ctxt.right_ent);
+	if (ctxt.old_ent)
+		kmem_cache_free(ocfs2_em_ent_cachep, ctxt.old_ent);
+	if (ctxt.new_ent)
+		kmem_cache_free(ocfs2_em_ent_cachep, ctxt.new_ent);
+
+	return ret;
+}
+
+/*
+ * Append this record to the tail of the extent map.  It must be
+ * tree_depth 0.  The record might be an extension of an existing
+ * record, and as such that needs to be handled.  eg:
+ *
+ * Existing record in the extent map:
+ *
+ *	cpos = 10, len = 10
+ * 	|---------|
+ *
+ * New Record:
+ *
+ *	cpos = 10, len = 20
+ * 	|------------------|
+ *
+ * The passed record is the new on-disk record.  The new_clusters value
+ * is how many clusters were added to the file.  If the append is a
+ * contiguous append, the new_clusters has been added to
+ * rec->e_clusters.  If the append is an entirely new extent, then
+ * rec->e_clusters is == new_clusters.
+ */
+int ocfs2_extent_map_append(struct inode *inode,
+			    struct ocfs2_extent_rec *rec,
+			    u32 new_clusters)
+{
+	int ret;
+	struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map;
+	struct ocfs2_extent_map_entry *ent;
+	struct ocfs2_extent_rec *old;
+
+	BUG_ON(!new_clusters);
+	BUG_ON(le32_to_cpu(rec->e_clusters) < new_clusters);
+
+	if (em->em_clusters < OCFS2_I(inode)->ip_clusters) {
+		/*
+		 * Size changed underneath us on disk.  Drop any
+		 * straddling records and update our idea of
+		 * i_clusters
+		 */
+		ocfs2_extent_map_drop(inode, em->em_clusters - 1);
+		em->em_clusters = OCFS2_I(inode)->ip_clusters;
+	}
+
+	mlog_bug_on_msg((le32_to_cpu(rec->e_cpos) +
+			 le32_to_cpu(rec->e_clusters)) !=
+			(em->em_clusters + new_clusters),
+			"Inode %"MLFu64":\n"
+			"rec->e_cpos = %u + rec->e_clusters = %u = %u\n"
+			"em->em_clusters = %u + new_clusters = %u = %u\n",
+			OCFS2_I(inode)->ip_blkno,
+			le32_to_cpu(rec->e_cpos), le32_to_cpu(rec->e_clusters),
+			le32_to_cpu(rec->e_cpos) + le32_to_cpu(rec->e_clusters),
+			em->em_clusters, new_clusters,
+			em->em_clusters + new_clusters);
+
+	em->em_clusters += new_clusters;
+
+	ret = -ENOENT;
+	if (le32_to_cpu(rec->e_clusters) > new_clusters) {
+		/* This is a contiguous append */
+		ent = ocfs2_extent_map_lookup(em, le32_to_cpu(rec->e_cpos), 1,
+					      NULL, NULL);
+		if (ent) {
+			old = &ent->e_rec;
+			BUG_ON((le32_to_cpu(rec->e_cpos) +
+				le32_to_cpu(rec->e_clusters)) !=
+				 (le32_to_cpu(old->e_cpos) +
+				  le32_to_cpu(old->e_clusters) +
+				  new_clusters));
+			if (ent->e_tree_depth == 0) {
+				BUG_ON(le32_to_cpu(old->e_cpos) !=
+				       le32_to_cpu(rec->e_cpos));
+				BUG_ON(le64_to_cpu(old->e_blkno) !=
+				       le64_to_cpu(rec->e_blkno));
+				ret = 0;
+			}
+			/*
+			 * Let non-leafs fall through as -ENOENT to
+			 * force insertion of the new leaf.
+			 */
+			le32_add_cpu(&old->e_clusters, new_clusters);
+		}
+	}
+
+	if (ret == -ENOENT)
+		ret = ocfs2_extent_map_insert(inode, rec, 0);
+	if (ret < 0)
+		mlog_errno(ret);
+	return ret;
+}
+
+#if 0
+/* Code here is included but defined out as it completes the extent
+ * map api and may be used in the future. */
+
+/*
+ * Look up the record containing this cluster offset.  This record is
+ * part of the extent map.  Do not free it.  Any changes you make to
+ * it will reflect in the extent map.  So, if your last extent
+ * is (cpos = 10, clusters = 10) and you truncate the file by 5
+ * clusters, you can do:
+ *
+ * ret = ocfs2_extent_map_get_rec(em, orig_size - 5, &rec);
+ * rec->e_clusters -= 5;
+ *
+ * The lookup does not read from disk.  If the map isn't filled in for
+ * an entry, you won't find it.
+ *
+ * Also note that the returned record is valid until alloc_sem is
+ * dropped.  After that, truncate and extend can happen.  Caveat Emptor.
+ */
+int ocfs2_extent_map_get_rec(struct inode *inode, u32 cpos,
+			     struct ocfs2_extent_rec **rec,
+			     int *tree_depth)
+{
+	int ret = -ENOENT;
+	struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map;
+	struct ocfs2_extent_map_entry *ent;
+
+	*rec = NULL;
+
+	if (cpos >= OCFS2_I(inode)->ip_clusters)
+		return -EINVAL;
+
+	if (cpos >= em->em_clusters) {
+		/*
+		 * Size changed underneath us on disk.  Drop any
+		 * straddling records and update our idea of
+		 * i_clusters
+		 */
+		ocfs2_extent_map_drop(inode, em->em_clusters - 1);
+		em->em_clusters = OCFS2_I(inode)->ip_clusters ;
+	}
+
+	ent = ocfs2_extent_map_lookup(&OCFS2_I(inode)->ip_map, cpos, 1,
+				      NULL, NULL);
+
+	if (ent) {
+		*rec = &ent->e_rec;
+		if (tree_depth)
+			*tree_depth = ent->e_tree_depth;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+int ocfs2_extent_map_get_clusters(struct inode *inode,
+				  u32 v_cpos, int count,
+				  u32 *p_cpos, int *ret_count)
+{
+	int ret;
+	u32 coff, ccount;
+	struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map;
+	struct ocfs2_extent_map_entry *ent = NULL;
+
+	*p_cpos = ccount = 0;
+
+	if ((v_cpos + count) > OCFS2_I(inode)->ip_clusters)
+		return -EINVAL;
+
+	if ((v_cpos + count) > em->em_clusters) {
+		/*
+		 * Size changed underneath us on disk.  Drop any
+		 * straddling records and update our idea of
+		 * i_clusters
+		 */
+		ocfs2_extent_map_drop(inode, em->em_clusters - 1);
+		em->em_clusters = OCFS2_I(inode)->ip_clusters;
+	}
+
+
+	ret = ocfs2_extent_map_lookup_read(inode, v_cpos, count, &ent);
+	if (ret)
+		return ret;
+
+	if (ent) {
+		/* We should never find ourselves straddling an interval */
+		if (!ocfs2_extent_rec_contains_clusters(&ent->e_rec,
+							v_cpos,
+							count))
+			return -ESRCH;
+
+		coff = v_cpos - le32_to_cpu(ent->e_rec.e_cpos);
+		*p_cpos = ocfs2_blocks_to_clusters(inode->i_sb,
+				le64_to_cpu(ent->e_rec.e_blkno)) +
+			  coff;
+
+		if (ret_count)
+			*ret_count = le32_to_cpu(ent->e_rec.e_clusters) - coff;
+
+		return 0;
+	}
+
+
+	return -ENOENT;
+}
+
+#endif  /*  0  */
+
+int ocfs2_extent_map_get_blocks(struct inode *inode,
+				u64 v_blkno, int count,
+				u64 *p_blkno, int *ret_count)
+{
+	int ret;
+	u64 boff;
+	u32 cpos, clusters;
+	int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
+	struct ocfs2_extent_map_entry *ent = NULL;
+	struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map;
+	struct ocfs2_extent_rec *rec;
+
+	*p_blkno = 0;
+
+	cpos = ocfs2_blocks_to_clusters(inode->i_sb, v_blkno);
+	clusters = ocfs2_blocks_to_clusters(inode->i_sb,
+					    (u64)count + bpc - 1);
+	if ((cpos + clusters) > OCFS2_I(inode)->ip_clusters) {
+		ret = -EINVAL;
+		mlog_errno(ret);
+		return ret;
+	}
+
+	if ((cpos + clusters) > em->em_clusters) {
+		/*
+		 * Size changed underneath us on disk.  Drop any
+		 * straddling records and update our idea of
+		 * i_clusters
+		 */
+		ocfs2_extent_map_drop(inode, em->em_clusters - 1);
+		em->em_clusters = OCFS2_I(inode)->ip_clusters;
+	}
+
+	ret = ocfs2_extent_map_lookup_read(inode, cpos, clusters, &ent);
+	if (ret) {
+		mlog_errno(ret);
+		return ret;
+	}
+
+	if (ent)
+	{
+		rec = &ent->e_rec;
+
+		/* We should never find ourselves straddling an interval */
+		if (!ocfs2_extent_rec_contains_clusters(rec, cpos, clusters)) {
+			ret = -ESRCH;
+			mlog_errno(ret);
+			return ret;
+		}
+
+		boff = ocfs2_clusters_to_blocks(inode->i_sb, cpos -
+						le32_to_cpu(rec->e_cpos));
+		boff += (v_blkno & (u64)(bpc - 1));
+		*p_blkno = le64_to_cpu(rec->e_blkno) + boff;
+
+		if (ret_count) {
+			*ret_count = ocfs2_clusters_to_blocks(inode->i_sb,
+					le32_to_cpu(rec->e_clusters)) - boff;
+		}
+
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+int ocfs2_extent_map_init(struct inode *inode)
+{
+	struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map;
+
+	em->em_extents = RB_ROOT;
+	em->em_clusters = 0;
+
+	return 0;
+}
+
+/* Needs the lock */
+static void __ocfs2_extent_map_drop(struct inode *inode,
+				    u32 new_clusters,
+				    struct rb_node **free_head,
+				    struct ocfs2_extent_map_entry **tail_ent)
+{
+	struct rb_node *node, *next;
+	struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map;
+	struct ocfs2_extent_map_entry *ent;
+
+	*free_head = NULL;
+
+	ent = NULL;
+	node = rb_last(&em->em_extents);
+	while (node)
+	{
+		next = rb_prev(node);
+
+		ent = rb_entry(node, struct ocfs2_extent_map_entry,
+			       e_node);
+		if (le32_to_cpu(ent->e_rec.e_cpos) < new_clusters)
+			break;
+
+		rb_erase(&ent->e_node, &em->em_extents);
+
+		node->rb_right = *free_head;
+		*free_head = node;
+
+		ent = NULL;
+		node = next;
+	}
+
+	/* Do we have an entry straddling new_clusters? */
+	if (tail_ent) {
+		if (ent &&
+		    ((le32_to_cpu(ent->e_rec.e_cpos) +
+		      le32_to_cpu(ent->e_rec.e_clusters)) > new_clusters))
+			*tail_ent = ent;
+		else
+			*tail_ent = NULL;
+	}
+}
+
+static void __ocfs2_extent_map_drop_cleanup(struct rb_node *free_head)
+{
+	struct rb_node *node;
+	struct ocfs2_extent_map_entry *ent;
+
+	while (free_head) {
+		node = free_head;
+		free_head = node->rb_right;
+
+		ent = rb_entry(node, struct ocfs2_extent_map_entry,
+			       e_node);
+		kmem_cache_free(ocfs2_em_ent_cachep, ent);
+	}
+}
+
+/*
+ * Remove all entries past new_clusters, inclusive of an entry that
+ * contains new_clusters.  This is effectively a cache forget.
+ *
+ * If you want to also clip the last extent by some number of clusters,
+ * you need to call ocfs2_extent_map_trunc().
+ * This code does not check or modify ip_clusters.
+ */
+int ocfs2_extent_map_drop(struct inode *inode, u32 new_clusters)
+{
+	struct rb_node *free_head = NULL;
+	struct ocfs2_extent_map *em = &OCFS2_I(inode)->ip_map;
+	struct ocfs2_extent_map_entry *ent;
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+
+	__ocfs2_extent_map_drop(inode, new_clusters, &free_head, &ent);
+
+	if (ent) {
+		rb_erase(&ent->e_node, &em->em_extents);
+		ent->e_node.rb_right = free_head;
+		free_head = &ent->e_node;
+	}
+
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	if (free_head)
+		__ocfs2_extent_map_drop_cleanup(free_head);
+
+	return 0;
+}
+
+/*
+ * Remove all entries past new_clusters and also clip any extent
+ * straddling new_clusters, if there is one.  This does not check
+ * or modify ip_clusters
+ */
+int ocfs2_extent_map_trunc(struct inode *inode, u32 new_clusters)
+{
+	struct rb_node *free_head = NULL;
+	struct ocfs2_extent_map_entry *ent = NULL;
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+
+	__ocfs2_extent_map_drop(inode, new_clusters, &free_head, &ent);
+
+	if (ent)
+		ent->e_rec.e_clusters = cpu_to_le32(new_clusters -
+					       le32_to_cpu(ent->e_rec.e_cpos));
+
+	OCFS2_I(inode)->ip_map.em_clusters = new_clusters;
+
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	if (free_head)
+		__ocfs2_extent_map_drop_cleanup(free_head);
+
+	return 0;
+}
+
+int __init init_ocfs2_extent_maps(void)
+{
+	ocfs2_em_ent_cachep =
+		kmem_cache_create("ocfs2_em_ent",
+				  sizeof(struct ocfs2_extent_map_entry),
+				  0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+	if (!ocfs2_em_ent_cachep)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void __exit exit_ocfs2_extent_maps(void)
+{
+	kmem_cache_destroy(ocfs2_em_ent_cachep);
+}
diff --git a/fs/ocfs2/extent_map.h b/fs/ocfs2/extent_map.h
new file mode 100644
index 0000000..fa3745e
--- /dev/null
+++ b/fs/ocfs2/extent_map.h
@@ -0,0 +1,46 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * extent_map.h
+ *
+ * In-memory file extent mappings for OCFS2.
+ *
+ * Copyright (C) 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, 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 021110-1307, USA.
+ */
+
+#ifndef _EXTENT_MAP_H
+#define _EXTENT_MAP_H
+
+int init_ocfs2_extent_maps(void);
+void exit_ocfs2_extent_maps(void);
+
+/*
+ * EVERY CALL here except _init, _trunc, and _drop expects alloc_sem
+ * to be held.  The allocation cannot change at all while the map is
+ * in the process of being updated.
+ */
+int ocfs2_extent_map_init(struct inode *inode);
+int ocfs2_extent_map_append(struct inode *inode,
+			    struct ocfs2_extent_rec *rec,
+			    u32 new_clusters);
+int ocfs2_extent_map_get_blocks(struct inode *inode,
+				u64 v_blkno, int count,
+				u64 *p_blkno, int *ret_count);
+int ocfs2_extent_map_drop(struct inode *inode, u32 new_clusters);
+int ocfs2_extent_map_trunc(struct inode *inode, u32 new_clusters);
+
+#endif  /* _EXTENT_MAP_H */
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
new file mode 100644
index 0000000..72ae9e3
--- /dev/null
+++ b/fs/ocfs2/file.c
@@ -0,0 +1,1237 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * file.c
+ *
+ * File open, close, extend, truncate
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/uio.h>
+
+#define MLOG_MASK_PREFIX ML_INODE
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "aops.h"
+#include "dir.h"
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "file.h"
+#include "sysfile.h"
+#include "inode.h"
+#include "journal.h"
+#include "mmap.h"
+#include "suballoc.h"
+#include "super.h"
+
+#include "buffer_head_io.h"
+
+static int ocfs2_sync_inode(struct inode *inode)
+{
+	filemap_fdatawrite(inode->i_mapping);
+	return sync_mapping_buffers(inode->i_mapping);
+}
+
+static int ocfs2_file_open(struct inode *inode, struct file *file)
+{
+	int status;
+	int mode = file->f_flags;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+	mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file,
+		   file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+
+	spin_lock(&oi->ip_lock);
+
+	/* Check that the inode hasn't been wiped from disk by another
+	 * node. If it hasn't then we're safe as long as we hold the
+	 * spin lock until our increment of open count. */
+	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
+		spin_unlock(&oi->ip_lock);
+
+		status = -ENOENT;
+		goto leave;
+	}
+
+	if (mode & O_DIRECT)
+		oi->ip_flags |= OCFS2_INODE_OPEN_DIRECT;
+
+	oi->ip_open_count++;
+	spin_unlock(&oi->ip_lock);
+	status = 0;
+leave:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_file_release(struct inode *inode, struct file *file)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+	mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file,
+		       file->f_dentry->d_name.len,
+		       file->f_dentry->d_name.name);
+
+	spin_lock(&oi->ip_lock);
+	if (!--oi->ip_open_count)
+		oi->ip_flags &= ~OCFS2_INODE_OPEN_DIRECT;
+	spin_unlock(&oi->ip_lock);
+
+	mlog_exit(0);
+
+	return 0;
+}
+
+static int ocfs2_sync_file(struct file *file,
+			   struct dentry *dentry,
+			   int datasync)
+{
+	int err = 0;
+	journal_t *journal;
+	struct inode *inode = dentry->d_inode;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", file, dentry, datasync,
+		   dentry->d_name.len, dentry->d_name.name);
+
+	err = ocfs2_sync_inode(dentry->d_inode);
+	if (err)
+		goto bail;
+
+	journal = osb->journal->j_journal;
+	err = journal_force_commit(journal);
+
+bail:
+	mlog_exit(err);
+
+	return (err < 0) ? -EIO : 0;
+}
+
+int ocfs2_set_inode_size(struct ocfs2_journal_handle *handle,
+			 struct inode *inode,
+			 struct buffer_head *fe_bh,
+			 u64 new_i_size)
+{
+	int status;
+
+	mlog_entry_void();
+	i_size_write(inode, new_i_size);
+	inode->i_blocks = ocfs2_align_bytes_to_sectors(new_i_size);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+
+	status = ocfs2_mark_inode_dirty(handle, inode, fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_simple_size_update(struct inode *inode,
+				    struct buffer_head *di_bh,
+				    u64 new_i_size)
+{
+	int ret;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct ocfs2_journal_handle *handle = NULL;
+
+	handle = ocfs2_start_trans(osb, NULL,
+				   OCFS2_INODE_UPDATE_CREDITS);
+	if (handle == NULL) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = ocfs2_set_inode_size(handle, inode, di_bh,
+				   new_i_size);
+	if (ret < 0)
+		mlog_errno(ret);
+
+	ocfs2_commit_trans(handle);
+out:
+	return ret;
+}
+
+static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb,
+				     struct inode *inode,
+				     struct buffer_head *fe_bh,
+				     u64 new_i_size)
+{
+	int status;
+	struct ocfs2_journal_handle *handle;
+
+	mlog_entry_void();
+
+	/* TODO: This needs to actually orphan the inode in this
+	 * transaction. */
+
+	handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		mlog_errno(status);
+		goto out;
+	}
+
+	status = ocfs2_set_inode_size(handle, inode, fe_bh, new_i_size);
+	if (status < 0)
+		mlog_errno(status);
+
+	ocfs2_commit_trans(handle);
+out:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_truncate_file(struct inode *inode,
+			       struct buffer_head *di_bh,
+			       u64 new_i_size)
+{
+	int status = 0;
+	struct ocfs2_dinode *fe = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct ocfs2_truncate_context *tc = NULL;
+
+	mlog_entry("(inode = %"MLFu64", new_i_size = %"MLFu64"\n",
+		   OCFS2_I(inode)->ip_blkno, new_i_size);
+
+	truncate_inode_pages(inode->i_mapping, new_i_size);
+
+	fe = (struct ocfs2_dinode *) di_bh->b_data;
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe);
+		status = -EIO;
+		goto bail;
+	}
+
+	mlog_bug_on_msg(le64_to_cpu(fe->i_size) != i_size_read(inode),
+			"Inode %"MLFu64", inode i_size = %lld != di "
+			"i_size = %"MLFu64", i_flags = 0x%x\n",
+			OCFS2_I(inode)->ip_blkno,
+			i_size_read(inode),
+			le64_to_cpu(fe->i_size), le32_to_cpu(fe->i_flags));
+
+	if (new_i_size > le64_to_cpu(fe->i_size)) {
+		mlog(0, "asked to truncate file with size (%"MLFu64") "
+		     "to size (%"MLFu64")!\n",
+		     le64_to_cpu(fe->i_size), new_i_size);
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	mlog(0, "inode %"MLFu64", i_size = %"MLFu64", new_i_size = %"MLFu64"\n",
+	     le64_to_cpu(fe->i_blkno), le64_to_cpu(fe->i_size), new_i_size);
+
+	/* lets handle the simple truncate cases before doing any more
+	 * cluster locking. */
+	if (new_i_size == le64_to_cpu(fe->i_size))
+		goto bail;
+
+	if (le32_to_cpu(fe->i_clusters) ==
+	    ocfs2_clusters_for_bytes(osb->sb, new_i_size)) {
+		mlog(0, "fe->i_clusters = %u, so we do a simple truncate\n",
+		     fe->i_clusters);
+		/* No allocation change is required, so lets fast path
+		 * this truncate. */
+		status = ocfs2_simple_size_update(inode, di_bh, new_i_size);
+		if (status < 0)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	/* This forces other nodes to sync and drop their pages */
+	status = ocfs2_data_lock(inode, 1);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	ocfs2_data_unlock(inode, 1);
+
+	/* alright, we're going to need to do a full blown alloc size
+	 * change. Orphan the inode so that recovery can complete the
+	 * truncate if necessary. This does the task of marking
+	 * i_size. */
+	status = ocfs2_orphan_for_truncate(osb, inode, di_bh, new_i_size);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_prepare_truncate(osb, inode, di_bh, &tc);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_commit_truncate(osb, inode, di_bh, tc);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* TODO: orphan dir cleanup here. */
+bail:
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * extend allocation only here.
+ * we'll update all the disk stuff, and oip->alloc_size
+ *
+ * expect stuff to be locked, a transaction started and enough data /
+ * metadata reservations in the contexts.
+ *
+ * Will return -EAGAIN, and a reason if a restart is needed.
+ * If passed in, *reason will always be set, even in error.
+ */
+int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
+			       struct inode *inode,
+			       u32 clusters_to_add,
+			       struct buffer_head *fe_bh,
+			       struct ocfs2_journal_handle *handle,
+			       struct ocfs2_alloc_context *data_ac,
+			       struct ocfs2_alloc_context *meta_ac,
+			       enum ocfs2_alloc_restarted *reason_ret)
+{
+	int status = 0;
+	int free_extents;
+	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
+	enum ocfs2_alloc_restarted reason = RESTART_NONE;
+	u32 bit_off, num_bits;
+	u64 block;
+
+	BUG_ON(!clusters_to_add);
+
+	free_extents = ocfs2_num_free_extents(osb, inode, fe);
+	if (free_extents < 0) {
+		status = free_extents;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	/* there are two cases which could cause us to EAGAIN in the
+	 * we-need-more-metadata case:
+	 * 1) we haven't reserved *any*
+	 * 2) we are so fragmented, we've needed to add metadata too
+	 *    many times. */
+	if (!free_extents && !meta_ac) {
+		mlog(0, "we haven't reserved any metadata!\n");
+		status = -EAGAIN;
+		reason = RESTART_META;
+		goto leave;
+	} else if ((!free_extents)
+		   && (ocfs2_alloc_context_bits_left(meta_ac)
+		       < ocfs2_extend_meta_needed(fe))) {
+		mlog(0, "filesystem is really fragmented...\n");
+		status = -EAGAIN;
+		reason = RESTART_META;
+		goto leave;
+	}
+
+	status = ocfs2_claim_clusters(osb, handle, data_ac, 1,
+				      &bit_off, &num_bits);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto leave;
+	}
+
+	BUG_ON(num_bits > clusters_to_add);
+
+	/* reserve our write early -- insert_extent may update the inode */
+	status = ocfs2_journal_access(handle, inode, fe_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
+	mlog(0, "Allocating %u clusters at block %u for inode %"MLFu64"\n",
+	     num_bits, bit_off, OCFS2_I(inode)->ip_blkno);
+	status = ocfs2_insert_extent(osb, handle, inode, fe_bh, block,
+				     num_bits, meta_ac);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	le32_add_cpu(&fe->i_clusters, num_bits);
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	status = ocfs2_journal_dirty(handle, fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	clusters_to_add -= num_bits;
+
+	if (clusters_to_add) {
+		mlog(0, "need to alloc once more, clusters = %u, wanted = "
+		     "%u\n", fe->i_clusters, clusters_to_add);
+		status = -EAGAIN;
+		reason = RESTART_TRANS;
+	}
+
+leave:
+	mlog_exit(status);
+	if (reason_ret)
+		*reason_ret = reason;
+	return status;
+}
+
+static int ocfs2_extend_allocation(struct inode *inode,
+				   u32 clusters_to_add)
+{
+	int status = 0;
+	int restart_func = 0;
+	int drop_alloc_sem = 0;
+	int credits, num_free_extents;
+	u32 prev_clusters;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_dinode *fe = NULL;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct ocfs2_alloc_context *data_ac = NULL;
+	struct ocfs2_alloc_context *meta_ac = NULL;
+	enum ocfs2_alloc_restarted why;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	mlog_entry("(clusters_to_add = %u)\n", clusters_to_add);
+
+	status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &bh,
+				  OCFS2_BH_CACHED, inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	fe = (struct ocfs2_dinode *) bh->b_data;
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe);
+		status = -EIO;
+		goto leave;
+	}
+
+restart_all:
+	BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters);
+
+	mlog(0, "extend inode %"MLFu64", i_size = %lld, fe->i_clusters = %u, "
+	     "clusters_to_add = %u\n",
+	     OCFS2_I(inode)->ip_blkno, i_size_read(inode),
+	     fe->i_clusters, clusters_to_add);
+
+	handle = ocfs2_alloc_handle(osb);
+	if (handle == NULL) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	num_free_extents = ocfs2_num_free_extents(osb,
+						  inode,
+						  fe);
+	if (num_free_extents < 0) {
+		status = num_free_extents;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	if (!num_free_extents) {
+		status = ocfs2_reserve_new_metadata(osb,
+						    handle,
+						    fe,
+						    &meta_ac);
+		if (status < 0) {
+			if (status != -ENOSPC)
+				mlog_errno(status);
+			goto leave;
+		}
+	}
+
+	status = ocfs2_reserve_clusters(osb,
+					handle,
+					clusters_to_add,
+					&data_ac);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto leave;
+	}
+
+	/* blocks peope in read/write from reading our allocation
+	 * until we're done changing it. We depend on i_sem to block
+	 * other extend/truncate calls while we're here. Ordering wrt
+	 * start_trans is important here -- always do it before! */
+	down_write(&OCFS2_I(inode)->ip_alloc_sem);
+	drop_alloc_sem = 1;
+
+	credits = ocfs2_calc_extend_credits(osb->sb, fe, clusters_to_add);
+	handle = ocfs2_start_trans(osb, handle, credits);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto leave;
+	}
+
+restarted_transaction:
+	/* reserve a write to the file entry early on - that we if we
+	 * run out of credits in the allocation path, we can still
+	 * update i_size. */
+	status = ocfs2_journal_access(handle, inode, bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	prev_clusters = OCFS2_I(inode)->ip_clusters;
+
+	status = ocfs2_do_extend_allocation(osb,
+					    inode,
+					    clusters_to_add,
+					    bh,
+					    handle,
+					    data_ac,
+					    meta_ac,
+					    &why);
+	if ((status < 0) && (status != -EAGAIN)) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_journal_dirty(handle, bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	clusters_to_add -= (OCFS2_I(inode)->ip_clusters - prev_clusters);
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	if (why != RESTART_NONE && clusters_to_add) {
+		if (why == RESTART_META) {
+			mlog(0, "restarting function.\n");
+			restart_func = 1;
+		} else {
+			BUG_ON(why != RESTART_TRANS);
+
+			mlog(0, "restarting transaction.\n");
+			/* TODO: This can be more intelligent. */
+			credits = ocfs2_calc_extend_credits(osb->sb,
+							    fe,
+							    clusters_to_add);
+			status = ocfs2_extend_trans(handle, credits);
+			if (status < 0) {
+				/* handle still has to be committed at
+				 * this point. */
+				status = -ENOMEM;
+				mlog_errno(status);
+				goto leave;
+			}
+			goto restarted_transaction;
+		}
+	}
+
+	mlog(0, "fe: i_clusters = %u, i_size=%"MLFu64"\n",
+	     fe->i_clusters, fe->i_size);
+	mlog(0, "inode: ip_clusters=%u, i_size=%lld\n",
+	     OCFS2_I(inode)->ip_clusters, i_size_read(inode));
+
+leave:
+	if (drop_alloc_sem) {
+		up_write(&OCFS2_I(inode)->ip_alloc_sem);
+		drop_alloc_sem = 0;
+	}
+	if (handle) {
+		ocfs2_commit_trans(handle);
+		handle = NULL;
+	}
+	if (data_ac) {
+		ocfs2_free_alloc_context(data_ac);
+		data_ac = NULL;
+	}
+	if (meta_ac) {
+		ocfs2_free_alloc_context(meta_ac);
+		meta_ac = NULL;
+	}
+	if ((!status) && restart_func) {
+		restart_func = 0;
+		goto restart_all;
+	}
+	if (bh) {
+		brelse(bh);
+		bh = NULL;
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+/* Some parts of this taken from generic_cont_expand, which turned out
+ * to be too fragile to do exactly what we need without us having to
+ * worry about recursive locking in ->commit_write(). */
+static int ocfs2_write_zero_page(struct inode *inode,
+				 u64 size)
+{
+	struct address_space *mapping = inode->i_mapping;
+	struct page *page;
+	unsigned long index;
+	unsigned int offset;
+	struct ocfs2_journal_handle *handle = NULL;
+	int ret;
+
+	offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */
+	/* ugh.  in prepare/commit_write, if from==to==start of block, we 
+	** skip the prepare.  make sure we never send an offset for the start
+	** of a block
+	*/
+	if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
+		offset++;
+	}
+	index = size >> PAGE_CACHE_SHIFT;
+
+	page = grab_cache_page(mapping, index);
+	if (!page) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = ocfs2_prepare_write(NULL, page, offset, offset);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out_unlock;
+	}
+
+	if (ocfs2_should_order_data(inode)) {
+		handle = ocfs2_start_walk_page_trans(inode, page, offset,
+						     offset);
+		if (IS_ERR(handle)) {
+			ret = PTR_ERR(handle);
+			handle = NULL;
+			goto out_unlock;
+		}
+	}
+
+	/* must not update i_size! */
+	ret = block_commit_write(page, offset, offset);
+	if (ret < 0)
+		mlog_errno(ret);
+	else
+		ret = 0;
+
+	if (handle)
+		ocfs2_commit_trans(handle);
+out_unlock:
+	unlock_page(page);
+	page_cache_release(page);
+out:
+	return ret;
+}
+
+static int ocfs2_zero_extend(struct inode *inode,
+			     u64 zero_to_size)
+{
+	int ret = 0;
+	u64 start_off;
+	struct super_block *sb = inode->i_sb;
+
+	start_off = ocfs2_align_bytes_to_blocks(sb, i_size_read(inode));
+	while (start_off < zero_to_size) {
+		ret = ocfs2_write_zero_page(inode, start_off);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		start_off += sb->s_blocksize;
+	}
+
+out:
+	return ret;
+}
+
+static int ocfs2_extend_file(struct inode *inode,
+			     struct buffer_head *di_bh,
+			     u64 new_i_size)
+{
+	int ret = 0;
+	u32 clusters_to_add;
+
+	/* setattr sometimes calls us like this. */
+	if (new_i_size == 0)
+		goto out;
+
+	if (i_size_read(inode) == new_i_size)
+  		goto out;
+	BUG_ON(new_i_size < i_size_read(inode));
+
+	clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size) - 
+		OCFS2_I(inode)->ip_clusters;
+
+	if (clusters_to_add) {
+		ret = ocfs2_extend_allocation(inode, clusters_to_add);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		ret = ocfs2_zero_extend(inode, new_i_size);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto out;
+		}
+	} 
+
+	/* No allocation required, we just use this helper to
+	 * do a trivial update of i_size. */
+	ret = ocfs2_simple_size_update(inode, di_bh, new_i_size);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
+{
+	int status = 0, size_change;
+	struct inode *inode = dentry->d_inode;
+	struct super_block *sb = inode->i_sb;
+	struct ocfs2_super *osb = OCFS2_SB(sb);
+	struct buffer_head *bh = NULL;
+	struct ocfs2_journal_handle *handle = NULL;
+
+	mlog_entry("(0x%p, '%.*s')\n", dentry,
+	           dentry->d_name.len, dentry->d_name.name);
+
+	if (attr->ia_valid & ATTR_MODE)
+		mlog(0, "mode change: %d\n", attr->ia_mode);
+	if (attr->ia_valid & ATTR_UID)
+		mlog(0, "uid change: %d\n", attr->ia_uid);
+	if (attr->ia_valid & ATTR_GID)
+		mlog(0, "gid change: %d\n", attr->ia_gid);
+	if (attr->ia_valid & ATTR_SIZE)
+		mlog(0, "size change...\n");
+	if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME))
+		mlog(0, "time change...\n");
+
+#define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
+			   | ATTR_GID | ATTR_UID | ATTR_MODE)
+	if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) {
+		mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid);
+		return 0;
+	}
+
+	status = inode_change_ok(inode, attr);
+	if (status)
+		return status;
+
+	size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE;
+	if (size_change) {
+		status = ocfs2_rw_lock(inode, 1);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	status = ocfs2_meta_lock(inode, NULL, &bh, 1);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		goto bail_unlock_rw;
+	}
+
+	if (size_change && attr->ia_size != i_size_read(inode)) {
+		if (i_size_read(inode) > attr->ia_size)
+			status = ocfs2_truncate_file(inode, bh, attr->ia_size);
+		else
+			status = ocfs2_extend_file(inode, bh, attr->ia_size);
+		if (status < 0) {
+			if (status != -ENOSPC)
+				mlog_errno(status);
+			status = -ENOSPC;
+			goto bail_unlock;
+		}
+	}
+
+	handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		mlog_errno(status);
+		goto bail_unlock;
+	}
+
+	status = inode_setattr(inode, attr);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail_commit;
+	}
+
+	status = ocfs2_mark_inode_dirty(handle, inode, bh);
+	if (status < 0)
+		mlog_errno(status);
+
+bail_commit:
+	ocfs2_commit_trans(handle);
+bail_unlock:
+	ocfs2_meta_unlock(inode, 1);
+bail_unlock_rw:
+	if (size_change)
+		ocfs2_rw_unlock(inode, 1);
+bail:
+	if (bh)
+		brelse(bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_getattr(struct vfsmount *mnt,
+		  struct dentry *dentry,
+		  struct kstat *stat)
+{
+	struct inode *inode = dentry->d_inode;
+	struct super_block *sb = dentry->d_inode->i_sb;
+	struct ocfs2_super *osb = sb->s_fs_info;
+	int err;
+
+	mlog_entry_void();
+
+	err = ocfs2_inode_revalidate(dentry);
+	if (err) {
+		if (err != -ENOENT)
+			mlog_errno(err);
+		goto bail;
+	}
+
+	generic_fillattr(inode, stat);
+
+	/* We set the blksize from the cluster size for performance */
+	stat->blksize = osb->s_clustersize;
+
+bail:
+	mlog_exit(err);
+
+	return err;
+}
+
+static int ocfs2_write_remove_suid(struct inode *inode)
+{
+	int ret;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_journal_handle *handle;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct ocfs2_dinode *di;
+
+	mlog_entry("(Inode %"MLFu64", mode 0%o)\n", oi->ip_blkno,
+		   inode->i_mode);
+
+	handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS);
+	if (handle == NULL) {
+		ret = -ENOMEM;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	ret = ocfs2_read_block(osb, oi->ip_blkno, &bh, OCFS2_BH_CACHED, inode);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out_trans;
+	}
+
+	ret = ocfs2_journal_access(handle, inode, bh,
+				   OCFS2_JOURNAL_ACCESS_WRITE);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out_bh;
+	}
+
+	inode->i_mode &= ~S_ISUID;
+	if ((inode->i_mode & S_ISGID) && (inode->i_mode & S_IXGRP))
+		inode->i_mode &= ~S_ISGID;
+
+	di = (struct ocfs2_dinode *) bh->b_data;
+	di->i_mode = cpu_to_le16(inode->i_mode);
+
+	ret = ocfs2_journal_dirty(handle, bh);
+	if (ret < 0)
+		mlog_errno(ret);
+out_bh:
+	brelse(bh);
+out_trans:
+	ocfs2_commit_trans(handle);
+out:
+	mlog_exit(ret);
+	return ret;
+}
+
+static inline int ocfs2_write_should_remove_suid(struct inode *inode)
+{
+	mode_t mode = inode->i_mode;
+
+	if (!capable(CAP_FSETID)) {
+		if (unlikely(mode & S_ISUID))
+			return 1;
+
+		if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
+			return 1;
+	}
+	return 0;
+}
+
+static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
+				    const char __user *buf,
+				    size_t count,
+				    loff_t pos)
+{
+	struct iovec local_iov = { .iov_base = (void __user *)buf,
+				   .iov_len = count };
+	int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0;
+	u32 clusters;
+	struct file *filp = iocb->ki_filp;
+	struct inode *inode = filp->f_dentry->d_inode;
+	loff_t newsize, saved_pos;
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+#endif
+
+	mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf,
+		   (unsigned int)count,
+		   filp->f_dentry->d_name.len,
+		   filp->f_dentry->d_name.name);
+
+	/* happy write of zero bytes */
+	if (count == 0)
+		return 0;
+
+	if (!inode) {
+		mlog(0, "bad inode\n");
+		return -EIO;
+	}
+
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	/* ugh, work around some applications which open everything O_DIRECT +
+	 * O_APPEND and really don't mean to use O_DIRECT. */
+	if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS &&
+	    (filp->f_flags & O_APPEND) && (filp->f_flags & O_DIRECT)) 
+		filp->f_flags &= ~O_DIRECT;
+#endif
+
+	down(&inode->i_sem);
+	/* to match setattr's i_sem -> i_alloc_sem -> rw_lock ordering */
+	if (filp->f_flags & O_DIRECT) {
+		have_alloc_sem = 1;
+		down_read(&inode->i_alloc_sem);
+	}
+
+	/* concurrent O_DIRECT writes are allowed */
+	rw_level = (filp->f_flags & O_DIRECT) ? 0 : 1;
+	ret = ocfs2_rw_lock(inode, rw_level);
+	if (ret < 0) {
+		rw_level = -1;
+		mlog_errno(ret);
+		goto out;
+	}
+
+	/* 
+	 * We sample i_size under a read level meta lock to see if our write
+	 * is extending the file, if it is we back off and get a write level
+	 * meta lock.
+	 */
+	meta_level = (filp->f_flags & O_APPEND) ? 1 : 0;
+	for(;;) {
+		ret = ocfs2_meta_lock(inode, NULL, NULL, meta_level);
+		if (ret < 0) {
+			meta_level = -1;
+			mlog_errno(ret);
+			goto out;
+		}
+
+		/* Clear suid / sgid if necessary. We do this here
+		 * instead of later in the write path because
+		 * remove_suid() calls ->setattr without any hint that
+		 * we may have already done our cluster locking. Since
+		 * ocfs2_setattr() *must* take cluster locks to
+		 * proceeed, this will lead us to recursively lock the
+		 * inode. There's also the dinode i_size state which
+		 * can be lost via setattr during extending writes (we
+		 * set inode->i_size at the end of a write. */
+		if (ocfs2_write_should_remove_suid(inode)) {
+			if (meta_level == 0) {
+				ocfs2_meta_unlock(inode, meta_level);
+				meta_level = 1;
+				continue;
+			}
+
+			ret = ocfs2_write_remove_suid(inode);
+			if (ret < 0) {
+				mlog_errno(ret);
+				goto out;
+			}
+		}
+
+		/* work on a copy of ppos until we're sure that we won't have
+		 * to recalculate it due to relocking. */
+		if (filp->f_flags & O_APPEND) {
+			saved_pos = i_size_read(inode);
+			mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos);
+		} else {
+			saved_pos = iocb->ki_pos;
+		}
+		newsize = count + saved_pos;
+
+		mlog(0, "pos=%lld newsize=%"MLFu64" cursize=%lld\n",
+		     saved_pos, newsize, i_size_read(inode));
+
+		/* No need for a higher level metadata lock if we're
+		 * never going past i_size. */
+		if (newsize <= i_size_read(inode))
+			break;
+
+		if (meta_level == 0) {
+			ocfs2_meta_unlock(inode, meta_level);
+			meta_level = 1;
+			continue;
+		}
+
+		spin_lock(&OCFS2_I(inode)->ip_lock);
+		clusters = ocfs2_clusters_for_bytes(inode->i_sb, newsize) -
+			OCFS2_I(inode)->ip_clusters;
+		spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+		mlog(0, "Writing at EOF, may need more allocation: "
+		     "i_size = %lld, newsize = %"MLFu64", need %u clusters\n",
+		     i_size_read(inode), newsize, clusters);
+
+		/* We only want to continue the rest of this loop if
+		 * our extend will actually require more
+		 * allocation. */
+		if (!clusters)
+			break;
+
+		ret = ocfs2_extend_allocation(inode, clusters);
+		if (ret < 0) {
+			if (ret != -ENOSPC)
+				mlog_errno(ret);
+			goto out;
+		}
+
+		/* Fill any holes which would've been created by this
+		 * write. If we're O_APPEND, this will wind up
+		 * (correctly) being a noop. */
+		ret = ocfs2_zero_extend(inode, (u64) newsize - count);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto out;
+		}
+		break;
+	}
+
+	/* ok, we're done with i_size and alloc work */
+	iocb->ki_pos = saved_pos;
+	ocfs2_meta_unlock(inode, meta_level);
+	meta_level = -1;
+
+	/* communicate with ocfs2_dio_end_io */
+	ocfs2_iocb_set_rw_locked(iocb);
+
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS &&
+	    filp->f_flags & O_DIRECT) {
+		unsigned int saved_flags = filp->f_flags;
+		int sector_size = 1 << osb->s_sectsize_bits;
+
+		if ((saved_pos & (sector_size - 1)) ||
+		    (count & (sector_size - 1)) ||
+		    ((unsigned long)buf & (sector_size - 1))) {
+			filp->f_flags |= O_SYNC;
+			filp->f_flags &= ~O_DIRECT;
+		}
+
+		ret = generic_file_aio_write_nolock(iocb, &local_iov, 1,
+						    &iocb->ki_pos);
+
+		filp->f_flags = saved_flags;
+	} else
+#endif
+		ret = generic_file_aio_write_nolock(iocb, &local_iov, 1,
+						    &iocb->ki_pos);
+
+	/* buffered aio wouldn't have proper lock coverage today */
+	BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT));
+
+	/* 
+	 * deep in g_f_a_w_n()->ocfs2_direct_IO we pass in a ocfs2_dio_end_io
+	 * function pointer which is called when o_direct io completes so that
+	 * it can unlock our rw lock.  (it's the clustered equivalent of
+	 * i_alloc_sem; protects truncate from racing with pending ios).
+	 * Unfortunately there are error cases which call end_io and others
+	 * that don't.  so we don't have to unlock the rw_lock if either an
+	 * async dio is going to do it in the future or an end_io after an
+	 * error has already done it.
+	 */
+	if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) {
+		rw_level = -1;
+		have_alloc_sem = 0;
+	}
+
+out:
+	if (meta_level != -1)
+		ocfs2_meta_unlock(inode, meta_level);
+	if (have_alloc_sem)
+		up_read(&inode->i_alloc_sem);
+	if (rw_level != -1) 
+		ocfs2_rw_unlock(inode, rw_level);
+	up(&inode->i_sem);
+
+	mlog_exit(ret);
+	return ret;
+}
+
+static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
+				   char __user *buf,
+				   size_t count,
+				   loff_t pos)
+{
+	int ret = 0, rw_level = -1, have_alloc_sem = 0;
+	struct file *filp = iocb->ki_filp;
+	struct inode *inode = filp->f_dentry->d_inode;
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+#endif
+
+	mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", filp, buf,
+		   (unsigned int)count,
+		   filp->f_dentry->d_name.len,
+		   filp->f_dentry->d_name.name);
+
+	if (!inode) {
+		ret = -EINVAL;
+		mlog_errno(ret);
+		goto bail;
+	}
+
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	if (osb->s_mount_opt & OCFS2_MOUNT_COMPAT_OCFS) {
+		if (filp->f_flags & O_DIRECT) {
+			int sector_size = 1 << osb->s_sectsize_bits;
+
+			if ((pos & (sector_size - 1)) ||
+			    (count & (sector_size - 1)) ||
+			    ((unsigned long)buf & (sector_size - 1)) ||
+			    (i_size_read(inode) & (sector_size -1))) {
+				filp->f_flags &= ~O_DIRECT;
+			}
+		}
+	}
+#endif
+
+	/* 
+	 * buffered reads protect themselves in ->readpage().  O_DIRECT reads
+	 * need locks to protect pending reads from racing with truncate.
+	 */
+	if (filp->f_flags & O_DIRECT) {
+		down_read(&inode->i_alloc_sem);
+		have_alloc_sem = 1;
+
+		ret = ocfs2_rw_lock(inode, 0);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto bail;
+		}
+		rw_level = 0;
+		/* communicate with ocfs2_dio_end_io */
+		ocfs2_iocb_set_rw_locked(iocb);
+	}
+
+	ret = generic_file_aio_read(iocb, buf, count, iocb->ki_pos);
+	if (ret == -EINVAL)
+		mlog(ML_ERROR, "generic_file_aio_read returned -EINVAL\n");
+
+	/* buffered aio wouldn't have proper lock coverage today */
+	BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT));
+
+	/* see ocfs2_file_aio_write */
+	if (ret == -EIOCBQUEUED || !ocfs2_iocb_is_rw_locked(iocb)) {
+		rw_level = -1;
+		have_alloc_sem = 0;
+	}
+
+bail:
+	if (have_alloc_sem)
+		up_read(&inode->i_alloc_sem);
+	if (rw_level != -1) 
+		ocfs2_rw_unlock(inode, rw_level);
+	mlog_exit(ret);
+
+	return ret;
+}
+
+struct inode_operations ocfs2_file_iops = {
+	.setattr	= ocfs2_setattr,
+	.getattr	= ocfs2_getattr,
+};
+
+struct inode_operations ocfs2_special_file_iops = {
+	.setattr	= ocfs2_setattr,
+	.getattr	= ocfs2_getattr,
+};
+
+struct file_operations ocfs2_fops = {
+	.read		= do_sync_read,
+	.write		= do_sync_write,
+	.sendfile	= generic_file_sendfile,
+	.mmap		= ocfs2_mmap,
+	.fsync		= ocfs2_sync_file,
+	.release	= ocfs2_file_release,
+	.open		= ocfs2_file_open,
+	.aio_read	= ocfs2_file_aio_read,
+	.aio_write	= ocfs2_file_aio_write,
+};
+
+struct file_operations ocfs2_dops = {
+	.read		= generic_read_dir,
+	.readdir	= ocfs2_readdir,
+	.fsync		= ocfs2_sync_file,
+};
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h
new file mode 100644
index 0000000..a5ea33b
--- /dev/null
+++ b/fs/ocfs2/file.h
@@ -0,0 +1,57 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * file.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_FILE_H
+#define OCFS2_FILE_H
+
+extern struct file_operations ocfs2_fops;
+extern struct file_operations ocfs2_dops;
+extern struct inode_operations ocfs2_file_iops;
+extern struct inode_operations ocfs2_special_file_iops;
+struct ocfs2_alloc_context;
+
+enum ocfs2_alloc_restarted {
+	RESTART_NONE = 0,
+	RESTART_TRANS,
+	RESTART_META
+};
+int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
+			       struct inode *inode,
+			       u32 clusters_to_add,
+			       struct buffer_head *fe_bh,
+			       struct ocfs2_journal_handle *handle,
+			       struct ocfs2_alloc_context *data_ac,
+			       struct ocfs2_alloc_context *meta_ac,
+			       enum ocfs2_alloc_restarted *reason);
+int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
+int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
+		  struct kstat *stat);
+
+int ocfs2_set_inode_size(struct ocfs2_journal_handle *handle,
+			 struct inode *inode,
+			 struct buffer_head *fe_bh,
+			 u64 new_i_size);
+
+#endif /* OCFS2_FILE_H */
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c
new file mode 100644
index 0000000..0bbd22f
--- /dev/null
+++ b/fs/ocfs2/heartbeat.c
@@ -0,0 +1,378 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * heartbeat.c
+ *
+ * Register ourselves with the heartbaet service, keep our node maps
+ * up to date, and fire off recovery when needed.
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/kmod.h>
+
+#include <cluster/heartbeat.h>
+#include <cluster/nodemanager.h>
+
+#include <dlm/dlmapi.h>
+
+#define MLOG_MASK_PREFIX ML_SUPER
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "heartbeat.h"
+#include "inode.h"
+#include "journal.h"
+#include "vote.h"
+
+#include "buffer_head_io.h"
+
+#define OCFS2_HB_NODE_DOWN_PRI     (0x0000002)
+#define OCFS2_HB_NODE_UP_PRI	   OCFS2_HB_NODE_DOWN_PRI
+
+static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map,
+					    int bit);
+static inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map,
+					      int bit);
+static inline int __ocfs2_node_map_is_empty(struct ocfs2_node_map *map);
+static void __ocfs2_node_map_dup(struct ocfs2_node_map *target,
+				 struct ocfs2_node_map *from);
+static void __ocfs2_node_map_set(struct ocfs2_node_map *target,
+				 struct ocfs2_node_map *from);
+
+void ocfs2_init_node_maps(struct ocfs2_super *osb)
+{
+	spin_lock_init(&osb->node_map_lock);
+	ocfs2_node_map_init(&osb->mounted_map);
+	ocfs2_node_map_init(&osb->recovery_map);
+	ocfs2_node_map_init(&osb->umount_map);
+}
+
+static void ocfs2_do_node_down(int node_num,
+			       struct ocfs2_super *osb)
+{
+	BUG_ON(osb->node_num == node_num);
+
+	mlog(0, "ocfs2: node down event for %d\n", node_num);
+
+	if (!osb->dlm) {
+		/*
+		 * No DLM means we're not even ready to participate yet.
+		 * We check the slots after the DLM comes up, so we will
+		 * notice the node death then.  We can safely ignore it
+		 * here.
+		 */
+		return;
+	}
+
+	if (ocfs2_node_map_test_bit(osb, &osb->umount_map, node_num)) {
+		/* If a node is in the umount map, then we've been
+		 * expecting him to go down and we know ahead of time
+		 * that recovery is not necessary. */
+		ocfs2_node_map_clear_bit(osb, &osb->umount_map, node_num);
+		return;
+	}
+
+	ocfs2_recovery_thread(osb, node_num);
+
+	ocfs2_remove_node_from_vote_queues(osb, node_num);
+}
+
+static void ocfs2_hb_node_down_cb(struct o2nm_node *node,
+				  int node_num,
+				  void *data)
+{
+	ocfs2_do_node_down(node_num, (struct ocfs2_super *) data);
+}
+
+/* Called from the dlm when it's about to evict a node. We may also
+ * get a heartbeat callback later. */
+static void ocfs2_dlm_eviction_cb(int node_num,
+				  void *data)
+{
+	struct ocfs2_super *osb = (struct ocfs2_super *) data;
+	struct super_block *sb = osb->sb;
+
+	mlog(ML_NOTICE, "device (%u,%u): dlm has evicted node %d\n",
+	     MAJOR(sb->s_dev), MINOR(sb->s_dev), node_num);
+
+	ocfs2_do_node_down(node_num, osb);
+}
+
+static void ocfs2_hb_node_up_cb(struct o2nm_node *node,
+				int node_num,
+				void *data)
+{
+	struct ocfs2_super *osb = data;
+
+	BUG_ON(osb->node_num == node_num);
+
+	mlog(0, "node up event for %d\n", node_num);
+	ocfs2_node_map_clear_bit(osb, &osb->umount_map, node_num);
+}
+
+void ocfs2_setup_hb_callbacks(struct ocfs2_super *osb)
+{
+	o2hb_setup_callback(&osb->osb_hb_down, O2HB_NODE_DOWN_CB,
+			    ocfs2_hb_node_down_cb, osb,
+			    OCFS2_HB_NODE_DOWN_PRI);
+
+	o2hb_setup_callback(&osb->osb_hb_up, O2HB_NODE_UP_CB,
+			    ocfs2_hb_node_up_cb, osb, OCFS2_HB_NODE_UP_PRI);
+
+	/* Not exactly a heartbeat callback, but leads to essentially
+	 * the same path so we set it up here. */
+	dlm_setup_eviction_cb(&osb->osb_eviction_cb,
+			      ocfs2_dlm_eviction_cb,
+			      osb);
+}
+
+/* Most functions here are just stubs for now... */
+int ocfs2_register_hb_callbacks(struct ocfs2_super *osb)
+{
+	int status;
+
+	status = o2hb_register_callback(&osb->osb_hb_down);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = o2hb_register_callback(&osb->osb_hb_up);
+	if (status < 0)
+		mlog_errno(status);
+
+bail:
+	return status;
+}
+
+void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb)
+{
+	int status;
+
+	status = o2hb_unregister_callback(&osb->osb_hb_down);
+	if (status < 0)
+		mlog_errno(status);
+
+	status = o2hb_unregister_callback(&osb->osb_hb_up);
+	if (status < 0)
+		mlog_errno(status);
+}
+
+void ocfs2_stop_heartbeat(struct ocfs2_super *osb)
+{
+	int ret;
+	char *argv[5], *envp[3];
+
+	if (!osb->uuid_str) {
+		/* This can happen if we don't get far enough in mount... */
+		mlog(0, "No UUID with which to stop heartbeat!\n\n");
+		return;
+	}
+
+	argv[0] = (char *)o2nm_get_hb_ctl_path();
+	argv[1] = "-K";
+	argv[2] = "-u";
+	argv[3] = osb->uuid_str;
+	argv[4] = NULL;
+
+	mlog(0, "Run: %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
+
+	/* minimal command environment taken from cpu_run_sbin_hotplug */
+	envp[0] = "HOME=/";
+	envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+	envp[2] = NULL;
+
+	ret = call_usermodehelper(argv[0], argv, envp, 1);
+	if (ret < 0)
+		mlog_errno(ret);
+}
+
+/* special case -1 for now
+ * TODO: should *really* make sure the calling func never passes -1!!  */
+void ocfs2_node_map_init(struct ocfs2_node_map *map)
+{
+	map->num_nodes = OCFS2_NODE_MAP_MAX_NODES;
+	memset(map->map, 0, BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES) *
+	       sizeof(unsigned long));
+}
+
+static inline void __ocfs2_node_map_set_bit(struct ocfs2_node_map *map,
+					    int bit)
+{
+	set_bit(bit, map->map);
+}
+
+void ocfs2_node_map_set_bit(struct ocfs2_super *osb,
+			    struct ocfs2_node_map *map,
+			    int bit)
+{
+	if (bit==-1)
+		return;
+	BUG_ON(bit >= map->num_nodes);
+	spin_lock(&osb->node_map_lock);
+	__ocfs2_node_map_set_bit(map, bit);
+	spin_unlock(&osb->node_map_lock);
+}
+
+static inline void __ocfs2_node_map_clear_bit(struct ocfs2_node_map *map,
+					      int bit)
+{
+	clear_bit(bit, map->map);
+}
+
+void ocfs2_node_map_clear_bit(struct ocfs2_super *osb,
+			      struct ocfs2_node_map *map,
+			      int bit)
+{
+	if (bit==-1)
+		return;
+	BUG_ON(bit >= map->num_nodes);
+	spin_lock(&osb->node_map_lock);
+	__ocfs2_node_map_clear_bit(map, bit);
+	spin_unlock(&osb->node_map_lock);
+}
+
+int ocfs2_node_map_test_bit(struct ocfs2_super *osb,
+			    struct ocfs2_node_map *map,
+			    int bit)
+{
+	int ret;
+	if (bit >= map->num_nodes) {
+		mlog(ML_ERROR, "bit=%d map->num_nodes=%d\n", bit, map->num_nodes);
+		BUG();
+	}
+	spin_lock(&osb->node_map_lock);
+	ret = test_bit(bit, map->map);
+	spin_unlock(&osb->node_map_lock);
+	return ret;
+}
+
+static inline int __ocfs2_node_map_is_empty(struct ocfs2_node_map *map)
+{
+	int bit;
+	bit = find_next_bit(map->map, map->num_nodes, 0);
+	if (bit < map->num_nodes)
+		return 0;
+	return 1;
+}
+
+int ocfs2_node_map_is_empty(struct ocfs2_super *osb,
+			    struct ocfs2_node_map *map)
+{
+	int ret;
+	BUG_ON(map->num_nodes == 0);
+	spin_lock(&osb->node_map_lock);
+	ret = __ocfs2_node_map_is_empty(map);
+	spin_unlock(&osb->node_map_lock);
+	return ret;
+}
+
+static void __ocfs2_node_map_dup(struct ocfs2_node_map *target,
+				 struct ocfs2_node_map *from)
+{
+	BUG_ON(from->num_nodes == 0);
+	ocfs2_node_map_init(target);
+	__ocfs2_node_map_set(target, from);
+}
+
+/* returns 1 if bit is the only bit set in target, 0 otherwise */
+int ocfs2_node_map_is_only(struct ocfs2_super *osb,
+			   struct ocfs2_node_map *target,
+			   int bit)
+{
+	struct ocfs2_node_map temp;
+	int ret;
+
+	spin_lock(&osb->node_map_lock);
+	__ocfs2_node_map_dup(&temp, target);
+	__ocfs2_node_map_clear_bit(&temp, bit);
+	ret = __ocfs2_node_map_is_empty(&temp);
+	spin_unlock(&osb->node_map_lock);
+
+	return ret;
+}
+
+static void __ocfs2_node_map_set(struct ocfs2_node_map *target,
+				 struct ocfs2_node_map *from)
+{
+	int num_longs, i;
+
+	BUG_ON(target->num_nodes != from->num_nodes);
+	BUG_ON(target->num_nodes == 0);
+
+	num_longs = BITS_TO_LONGS(target->num_nodes);
+	for (i = 0; i < num_longs; i++)
+		target->map[i] = from->map[i];
+}
+
+/* Returns whether the recovery bit was actually set - it may not be
+ * if a node is still marked as needing recovery */
+int ocfs2_recovery_map_set(struct ocfs2_super *osb,
+			   int num)
+{
+	int set = 0;
+
+	spin_lock(&osb->node_map_lock);
+
+	__ocfs2_node_map_clear_bit(&osb->mounted_map, num);
+
+	if (!test_bit(num, osb->recovery_map.map)) {
+	    __ocfs2_node_map_set_bit(&osb->recovery_map, num);
+	    set = 1;
+	}
+
+	spin_unlock(&osb->node_map_lock);
+
+	return set;
+}
+
+void ocfs2_recovery_map_clear(struct ocfs2_super *osb,
+			      int num)
+{
+	ocfs2_node_map_clear_bit(osb, &osb->recovery_map, num);
+}
+
+int ocfs2_node_map_iterate(struct ocfs2_super *osb,
+			   struct ocfs2_node_map *map,
+			   int idx)
+{
+	int i = idx;
+
+	idx = O2NM_INVALID_NODE_NUM;
+	spin_lock(&osb->node_map_lock);
+	if ((i != O2NM_INVALID_NODE_NUM) &&
+	    (i >= 0) &&
+	    (i < map->num_nodes)) {
+		while(i < map->num_nodes) {
+			if (test_bit(i, map->map)) {
+				idx = i;
+				break;
+			}
+			i++;
+		}
+	}
+	spin_unlock(&osb->node_map_lock);
+	return idx;
+}
diff --git a/fs/ocfs2/heartbeat.h b/fs/ocfs2/heartbeat.h
new file mode 100644
index 0000000..e8fb079
--- /dev/null
+++ b/fs/ocfs2/heartbeat.h
@@ -0,0 +1,67 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * heartbeat.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_HEARTBEAT_H
+#define OCFS2_HEARTBEAT_H
+
+void ocfs2_init_node_maps(struct ocfs2_super *osb);
+
+void ocfs2_setup_hb_callbacks(struct ocfs2_super *osb);
+int ocfs2_register_hb_callbacks(struct ocfs2_super *osb);
+void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb);
+void ocfs2_stop_heartbeat(struct ocfs2_super *osb);
+
+/* node map functions - used to keep track of mounted and in-recovery
+ * nodes. */
+void ocfs2_node_map_init(struct ocfs2_node_map *map);
+int ocfs2_node_map_is_empty(struct ocfs2_super *osb,
+			    struct ocfs2_node_map *map);
+void ocfs2_node_map_set_bit(struct ocfs2_super *osb,
+			    struct ocfs2_node_map *map,
+			    int bit);
+void ocfs2_node_map_clear_bit(struct ocfs2_super *osb,
+			      struct ocfs2_node_map *map,
+			      int bit);
+int ocfs2_node_map_test_bit(struct ocfs2_super *osb,
+			    struct ocfs2_node_map *map,
+			    int bit);
+int ocfs2_node_map_iterate(struct ocfs2_super *osb,
+			   struct ocfs2_node_map *map,
+			   int idx);
+static inline int ocfs2_node_map_first_set_bit(struct ocfs2_super *osb,
+					       struct ocfs2_node_map *map)
+{
+	return ocfs2_node_map_iterate(osb, map, 0);
+}
+int ocfs2_recovery_map_set(struct ocfs2_super *osb,
+			   int num);
+void ocfs2_recovery_map_clear(struct ocfs2_super *osb,
+			      int num);
+/* returns 1 if bit is the only bit set in target, 0 otherwise */
+int ocfs2_node_map_is_only(struct ocfs2_super *osb,
+			   struct ocfs2_node_map *target,
+			   int bit);
+
+#endif /* OCFS2_HEARTBEAT_H */
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
new file mode 100644
index 0000000..a91ba4d
--- /dev/null
+++ b/fs/ocfs2/inode.c
@@ -0,0 +1,1140 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * inode.c
+ *
+ * vfs' aops, fops, dops and iops
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+
+#include <asm/byteorder.h>
+
+#define MLOG_MASK_PREFIX ML_INODE
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "file.h"
+#include "inode.h"
+#include "journal.h"
+#include "namei.h"
+#include "suballoc.h"
+#include "super.h"
+#include "symlink.h"
+#include "sysfile.h"
+#include "uptodate.h"
+#include "vote.h"
+
+#include "buffer_head_io.h"
+
+#define OCFS2_FI_FLAG_NOWAIT	0x1
+#define OCFS2_FI_FLAG_DELETE	0x2
+struct ocfs2_find_inode_args
+{
+	u64		fi_blkno;
+	unsigned long	fi_ino;
+	unsigned int	fi_flags;
+};
+
+static int ocfs2_read_locked_inode(struct inode *inode,
+				   struct ocfs2_find_inode_args *args);
+static int ocfs2_init_locked_inode(struct inode *inode, void *opaque);
+static int ocfs2_find_actor(struct inode *inode, void *opaque);
+static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
+				    struct inode *inode,
+				    struct buffer_head *fe_bh);
+
+struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
+				     u64 blkno,
+				     int delete_vote)
+{
+	struct ocfs2_find_inode_args args;
+
+	/* ocfs2_ilookup_for_vote should *only* be called from the
+	 * vote thread */
+	BUG_ON(current != osb->vote_task);
+
+	args.fi_blkno = blkno;
+	args.fi_flags = OCFS2_FI_FLAG_NOWAIT;
+	if (delete_vote)
+		args.fi_flags |= OCFS2_FI_FLAG_DELETE;
+	args.fi_ino = ino_from_blkno(osb->sb, blkno);
+	return ilookup5(osb->sb, args.fi_ino, ocfs2_find_actor, &args);
+}
+
+struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno)
+{
+	struct inode *inode = NULL;
+	struct super_block *sb = osb->sb;
+	struct ocfs2_find_inode_args args;
+
+	mlog_entry("(blkno = %"MLFu64")\n", blkno);
+
+	/* Ok. By now we've either got the offsets passed to us by the
+	 * caller, or we just pulled them off the bh. Lets do some
+	 * sanity checks to make sure they're OK. */
+	if (blkno == 0) {
+		inode = ERR_PTR(-EINVAL);
+		mlog_errno(PTR_ERR(inode));
+		goto bail;
+	}
+
+	args.fi_blkno = blkno;
+	args.fi_flags = 0;
+	args.fi_ino = ino_from_blkno(sb, blkno);
+
+	inode = iget5_locked(sb, args.fi_ino, ocfs2_find_actor,
+			     ocfs2_init_locked_inode, &args);
+	/* inode was *not* in the inode cache. 2.6.x requires
+	 * us to do our own read_inode call and unlock it
+	 * afterwards. */
+	if (inode && inode->i_state & I_NEW) {
+		mlog(0, "Inode was not in inode cache, reading it.\n");
+		ocfs2_read_locked_inode(inode, &args);
+		unlock_new_inode(inode);
+	}
+	if (inode == NULL) {
+		inode = ERR_PTR(-ENOMEM);
+		mlog_errno(PTR_ERR(inode));
+		goto bail;
+	}
+	if (is_bad_inode(inode)) {
+		iput(inode);
+		inode = ERR_PTR(-ESTALE);
+		mlog_errno(PTR_ERR(inode));
+		goto bail;
+	}
+
+bail:
+	if (!IS_ERR(inode)) {
+		mlog(0, "returning inode with number %"MLFu64"\n",
+		     OCFS2_I(inode)->ip_blkno);
+		mlog_exit_ptr(inode);
+	} else
+		mlog_errno(PTR_ERR(inode));
+
+	return inode;
+}
+
+
+/*
+ * here's how inodes get read from disk:
+ * iget5_locked -> find_actor -> OCFS2_FIND_ACTOR
+ * found? : return the in-memory inode
+ * not found? : get_new_inode -> OCFS2_INIT_LOCKED_INODE
+ */
+
+static int ocfs2_find_actor(struct inode *inode, void *opaque)
+{
+	struct ocfs2_find_inode_args *args = NULL;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	int ret = 0;
+
+	mlog_entry("(0x%p, %lu, 0x%p)\n", inode, inode->i_ino, opaque);
+
+	args = opaque;
+
+	mlog_bug_on_msg(!inode, "No inode in find actor!\n");
+
+	if (oi->ip_blkno != args->fi_blkno)
+		goto bail;
+
+	/* OCFS2_FI_FLAG_NOWAIT is *only* set from
+	 * ocfs2_ilookup_for_vote which won't create an inode for one
+	 * that isn't found. The vote thread which doesn't want to get
+	 * an inode which is in the process of going away - otherwise
+	 * the call to __wait_on_freeing_inode in find_inode_fast will
+	 * cause it to deadlock on an inode which may be waiting on a
+	 * vote (or lock release) in delete_inode */
+	if ((args->fi_flags & OCFS2_FI_FLAG_NOWAIT) &&
+	    (inode->i_state & (I_FREEING|I_CLEAR))) {
+		/* As stated above, we're not going to return an
+		 * inode.  In the case of a delete vote, the voting
+		 * code is going to signal the other node to go
+		 * ahead. Mark that state here, so this freeing inode
+		 * has the state when it gets to delete_inode. */
+		if (args->fi_flags & OCFS2_FI_FLAG_DELETE) {
+			spin_lock(&oi->ip_lock);
+			ocfs2_mark_inode_remotely_deleted(inode);
+			spin_unlock(&oi->ip_lock);
+		}
+		goto bail;
+	}
+
+	ret = 1;
+bail:
+	mlog_exit(ret);
+	return ret;
+}
+
+/*
+ * initialize the new inode, but don't do anything that would cause
+ * us to sleep.
+ * return 0 on success, 1 on failure
+ */
+static int ocfs2_init_locked_inode(struct inode *inode, void *opaque)
+{
+	struct ocfs2_find_inode_args *args = opaque;
+
+	mlog_entry("inode = %p, opaque = %p\n", inode, opaque);
+
+	inode->i_ino = args->fi_ino;
+	OCFS2_I(inode)->ip_blkno = args->fi_blkno;
+
+	mlog_exit(0);
+	return 0;
+}
+
+int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
+		     	 int create_ino)
+{
+	struct super_block *sb;
+	struct ocfs2_super *osb;
+	int status = -EINVAL;
+
+	mlog_entry("(0x%p, size:%"MLFu64")\n", inode, fe->i_size);
+
+	sb = inode->i_sb;
+	osb = OCFS2_SB(sb);
+
+	/* this means that read_inode cannot create a superblock inode
+	 * today.  change if needed. */
+	if (!OCFS2_IS_VALID_DINODE(fe) ||
+	    !(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL))) {
+		mlog(ML_ERROR, "Invalid dinode: i_ino=%lu, i_blkno=%"MLFu64", "
+		     "signature = %.*s, flags = 0x%x\n",
+		     inode->i_ino, le64_to_cpu(fe->i_blkno), 7,
+		     fe->i_signature, le32_to_cpu(fe->i_flags));
+		goto bail;
+	}
+
+	if (le32_to_cpu(fe->i_fs_generation) != osb->fs_generation) {
+		mlog(ML_ERROR, "file entry generation does not match "
+		     "superblock! osb->fs_generation=%x, "
+		     "fe->i_fs_generation=%x\n",
+		     osb->fs_generation, le32_to_cpu(fe->i_fs_generation));
+		goto bail;
+	}
+
+	inode->i_version = 1;
+	inode->i_generation = le32_to_cpu(fe->i_generation);
+	inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
+	inode->i_mode = le16_to_cpu(fe->i_mode);
+	inode->i_uid = le32_to_cpu(fe->i_uid);
+	inode->i_gid = le32_to_cpu(fe->i_gid);
+	inode->i_blksize = (u32)osb->s_clustersize;
+
+	/* Fast symlinks will have i_size but no allocated clusters. */
+	if (S_ISLNK(inode->i_mode) && !fe->i_clusters)
+		inode->i_blocks = 0;
+	else
+		inode->i_blocks =
+			ocfs2_align_bytes_to_sectors(le64_to_cpu(fe->i_size));
+	inode->i_mapping->a_ops = &ocfs2_aops;
+	inode->i_flags |= S_NOATIME;
+	inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
+	inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
+	inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
+	inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec);
+	inode->i_ctime.tv_sec = le64_to_cpu(fe->i_ctime);
+	inode->i_ctime.tv_nsec = le32_to_cpu(fe->i_ctime_nsec);
+
+	if (OCFS2_I(inode)->ip_blkno != le64_to_cpu(fe->i_blkno))
+		mlog(ML_ERROR,
+		     "ip_blkno %"MLFu64" != i_blkno %"MLFu64"!\n",
+		     OCFS2_I(inode)->ip_blkno, fe->i_blkno);
+
+	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
+	OCFS2_I(inode)->ip_orphaned_slot = OCFS2_INVALID_SLOT;
+
+	if (create_ino)
+		inode->i_ino = ino_from_blkno(inode->i_sb,
+			       le64_to_cpu(fe->i_blkno));
+
+	mlog(0, "blkno = %"MLFu64", ino = %lu, create_ino = %s\n",
+	     fe->i_blkno, inode->i_ino, create_ino ? "true" : "false");
+
+	inode->i_nlink = le16_to_cpu(fe->i_links_count);
+
+	if (fe->i_flags & cpu_to_le32(OCFS2_LOCAL_ALLOC_FL)) {
+		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP;
+		mlog(0, "local alloc inode: i_ino=%lu\n", inode->i_ino);
+	} else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) {
+		OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP;
+	} else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) {
+		mlog(0, "superblock inode: i_ino=%lu\n", inode->i_ino);
+		/* we can't actually hit this as read_inode can't
+		 * handle superblocks today ;-) */
+		BUG();
+	}
+
+	switch (inode->i_mode & S_IFMT) {
+	    case S_IFREG:
+		    inode->i_fop = &ocfs2_fops;
+		    inode->i_op = &ocfs2_file_iops;
+		    i_size_write(inode, le64_to_cpu(fe->i_size));
+		    break;
+	    case S_IFDIR:
+		    inode->i_op = &ocfs2_dir_iops;
+		    inode->i_fop = &ocfs2_dops;
+		    i_size_write(inode, le64_to_cpu(fe->i_size));
+		    break;
+	    case S_IFLNK:
+		    if (ocfs2_inode_is_fast_symlink(inode))
+			inode->i_op = &ocfs2_fast_symlink_inode_operations;
+		    else
+			inode->i_op = &ocfs2_symlink_inode_operations;
+		    i_size_write(inode, le64_to_cpu(fe->i_size));
+		    break;
+	    default:
+		    inode->i_op = &ocfs2_special_file_iops;
+		    init_special_inode(inode, inode->i_mode,
+				       inode->i_rdev);
+		    break;
+	}
+
+	ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_rw_lockres,
+				  OCFS2_LOCK_TYPE_RW, inode);
+	ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_meta_lockres,
+				  OCFS2_LOCK_TYPE_META, inode);
+	ocfs2_inode_lock_res_init(&OCFS2_I(inode)->ip_data_lockres,
+				  OCFS2_LOCK_TYPE_DATA, inode);
+
+	status = 0;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_read_locked_inode(struct inode *inode,
+				   struct ocfs2_find_inode_args *args)
+{
+	struct super_block *sb;
+	struct ocfs2_super *osb;
+	struct ocfs2_dinode *fe;
+	struct buffer_head *bh = NULL;
+	int status;
+	int sysfile = 0;
+
+	mlog_entry("(0x%p, 0x%p)\n", inode, args);
+
+	status = -EINVAL;
+	if (inode == NULL || inode->i_sb == NULL) {
+		mlog(ML_ERROR, "bad inode\n");
+		goto bail;
+	}
+	sb = inode->i_sb;
+	osb = OCFS2_SB(sb);
+
+	if (!args) {
+		mlog(ML_ERROR, "bad inode args\n");
+		make_bad_inode(inode);
+		goto bail;
+	}
+
+	/* Read the FE off disk. This is safe because the kernel only
+	 * does one read_inode2 for a new inode, and if it doesn't
+	 * exist yet then nobody can be working on it! */
+	status = ocfs2_read_block(osb, args->fi_blkno, &bh, 0, NULL);
+	if (status < 0) {
+		mlog_errno(status);
+		make_bad_inode(inode);
+		goto bail;
+	}
+
+	fe = (struct ocfs2_dinode *) bh->b_data;
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		mlog(ML_ERROR, "Invalid dinode #%"MLFu64": signature = %.*s\n",
+		     fe->i_blkno, 7, fe->i_signature);
+		make_bad_inode(inode);
+		goto bail;
+	}
+
+	if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL))
+		sysfile = 1;
+
+	if (S_ISCHR(le16_to_cpu(fe->i_mode)) ||
+	    S_ISBLK(le16_to_cpu(fe->i_mode)))
+    		inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
+
+	status = -EINVAL;
+	if (ocfs2_populate_inode(inode, fe, 0) < 0) {
+		mlog(ML_ERROR, "populate inode failed! i_blkno=%"MLFu64", "
+		     "i_ino=%lu\n", fe->i_blkno, inode->i_ino);
+		make_bad_inode(inode);
+		goto bail;
+	}
+
+	BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno));
+
+	if (sysfile)
+	       OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE;
+
+	status = 0;
+
+bail:
+	if (args && bh)
+		brelse(bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+void ocfs2_sync_blockdev(struct super_block *sb)
+{
+	sync_blockdev(sb->s_bdev);
+}
+
+static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
+				     struct inode *inode,
+				     struct buffer_head *fe_bh)
+{
+	int status = 0;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct ocfs2_truncate_context *tc = NULL;
+	struct ocfs2_dinode *fe;
+
+	mlog_entry_void();
+
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+
+	/* zero allocation, zero truncate :) */
+	if (!fe->i_clusters)
+		goto bail;
+
+	handle = ocfs2_start_trans(osb, handle, OCFS2_INODE_UPDATE_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_set_inode_size(handle, inode, fe_bh, 0ULL);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	ocfs2_commit_trans(handle);
+	handle = NULL;
+
+	status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_commit_truncate(osb, inode, fe_bh, tc);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+bail:
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_remove_inode(struct inode *inode,
+			      struct buffer_head *di_bh,
+			      struct inode *orphan_dir_inode,
+			      struct buffer_head *orphan_dir_bh)
+{
+	int status;
+	struct inode *inode_alloc_inode = NULL;
+	struct buffer_head *inode_alloc_bh = NULL;
+	struct ocfs2_journal_handle *handle;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
+
+	inode_alloc_inode =
+		ocfs2_get_system_file_inode(osb, INODE_ALLOC_SYSTEM_INODE,
+					    le16_to_cpu(di->i_suballoc_slot));
+	if (!inode_alloc_inode) {
+		status = -EEXIST;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	down(&inode_alloc_inode->i_sem);
+	status = ocfs2_meta_lock(inode_alloc_inode, NULL, &inode_alloc_bh, 1);
+	if (status < 0) {
+		up(&inode_alloc_inode->i_sem);
+
+		mlog_errno(status);
+		goto bail;
+	}
+
+	handle = ocfs2_start_trans(osb, NULL, OCFS2_DELETE_INODE_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		mlog_errno(status);
+		goto bail_unlock;
+	}
+
+	status = ocfs2_orphan_del(osb, handle, orphan_dir_inode, inode,
+				  orphan_dir_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail_commit;
+	}
+
+	/* set the inodes dtime */
+	status = ocfs2_journal_access(handle, inode, di_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail_commit;
+	}
+
+	di->i_dtime = cpu_to_le64(CURRENT_TIME.tv_sec);
+	le32_and_cpu(&di->i_flags, ~(OCFS2_VALID_FL | OCFS2_ORPHANED_FL));
+
+	status = ocfs2_journal_dirty(handle, di_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail_commit;
+	}
+
+	ocfs2_remove_from_cache(inode, di_bh);
+
+	status = ocfs2_free_dinode(handle, inode_alloc_inode,
+				   inode_alloc_bh, di);
+	if (status < 0)
+		mlog_errno(status);
+
+bail_commit:
+	ocfs2_commit_trans(handle);
+bail_unlock:
+	ocfs2_meta_unlock(inode_alloc_inode, 1);
+	up(&inode_alloc_inode->i_sem);
+	brelse(inode_alloc_bh);
+bail:
+	iput(inode_alloc_inode);
+
+	return status;
+}
+
+static int ocfs2_wipe_inode(struct inode *inode,
+			    struct buffer_head *di_bh)
+{
+	int status, orphaned_slot;
+	struct inode *orphan_dir_inode = NULL;
+	struct buffer_head *orphan_dir_bh = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	/* We've already voted on this so it should be readonly - no
+	 * spinlock needed. */
+	orphaned_slot = OCFS2_I(inode)->ip_orphaned_slot;
+	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
+						       ORPHAN_DIR_SYSTEM_INODE,
+						       orphaned_slot);
+	if (!orphan_dir_inode) {
+		status = -EEXIST;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* Lock the orphan dir. The lock will be held for the entire
+	 * delete_inode operation. We do this now to avoid races with
+	 * recovery completion on other nodes. */
+	down(&orphan_dir_inode->i_sem);
+	status = ocfs2_meta_lock(orphan_dir_inode, NULL, &orphan_dir_bh, 1);
+	if (status < 0) {
+		up(&orphan_dir_inode->i_sem);
+
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* we do this while holding the orphan dir lock because we
+	 * don't want recovery being run from another node to vote for
+	 * an inode delete on us -- this will result in two nodes
+	 * truncating the same file! */
+	status = ocfs2_truncate_for_delete(osb, inode, di_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail_unlock_dir;
+	}
+
+	status = ocfs2_remove_inode(inode, di_bh, orphan_dir_inode,
+				    orphan_dir_bh);
+	if (status < 0)
+		mlog_errno(status);
+
+bail_unlock_dir:
+	ocfs2_meta_unlock(orphan_dir_inode, 1);
+	up(&orphan_dir_inode->i_sem);
+	brelse(orphan_dir_bh);
+bail:
+	iput(orphan_dir_inode);
+
+	return status;
+}
+
+/* There is a series of simple checks that should be done before a
+ * vote is even considered. Encapsulate those in this function. */
+static int ocfs2_inode_is_valid_to_delete(struct inode *inode)
+{
+	int ret = 0;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	/* We shouldn't be getting here for the root directory
+	 * inode.. */
+	if (inode == osb->root_inode) {
+		mlog(ML_ERROR, "Skipping delete of root inode.\n");
+		goto bail;
+	}
+
+	/* If we're coming from process_vote we can't go into our own
+	 * voting [hello, deadlock city!], so unforuntately we just
+	 * have to skip deleting this guy. That's OK though because
+	 * the node who's doing the actual deleting should handle it
+	 * anyway. */
+	if (current == osb->vote_task) {
+		mlog(0, "Skipping delete of %lu because we're currently "
+		     "in process_vote\n", inode->i_ino);
+		goto bail;
+	}
+
+	spin_lock(&oi->ip_lock);
+	/* OCFS2 *never* deletes system files. This should technically
+	 * never get here as system file inodes should always have a
+	 * positive link count. */
+	if (oi->ip_flags & OCFS2_INODE_SYSTEM_FILE) {
+		mlog(ML_ERROR, "Skipping delete of system file %"MLFu64".\n",
+		     oi->ip_blkno);
+		goto bail_unlock;
+	}
+
+	/* If we have voted "yes" on the wipe of this inode for
+	 * another node, it will be marked here so we can safely skip
+	 * it. Recovery will cleanup any inodes we might inadvertantly
+	 * skip here. */
+	if (oi->ip_flags & OCFS2_INODE_SKIP_DELETE) {
+		mlog(0, "Skipping delete of %lu because another node "
+		     "has done this for us.\n", inode->i_ino);
+		goto bail_unlock;
+	}
+
+	ret = 1;
+bail_unlock:
+	spin_unlock(&oi->ip_lock);
+bail:
+	return ret;
+}
+
+/* Query the cluster to determine whether we should wipe an inode from
+ * disk or not.
+ *
+ * Requires the inode to have the cluster lock. */
+static int ocfs2_query_inode_wipe(struct inode *inode,
+				  struct buffer_head *di_bh,
+				  int *wipe)
+{
+	int status = 0;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_dinode *di;
+
+	*wipe = 0;
+
+	/* While we were waiting for the cluster lock in
+	 * ocfs2_delete_inode, another node might have asked to delete
+	 * the inode. Recheck our flags to catch this. */
+	if (!ocfs2_inode_is_valid_to_delete(inode)) {
+		mlog(0, "Skipping delete of %"MLFu64" because flags changed\n",
+		     oi->ip_blkno);
+		goto bail;
+	}
+
+	/* Now that we have an up to date inode, we can double check
+	 * the link count. */
+	if (inode->i_nlink) {
+		mlog(0, "Skipping delete of %"MLFu64" because nlink = %u\n",
+		     oi->ip_blkno, inode->i_nlink);
+		goto bail;
+	}
+
+	/* Do some basic inode verification... */
+	di = (struct ocfs2_dinode *) di_bh->b_data;
+	if (!(di->i_flags & cpu_to_le32(OCFS2_ORPHANED_FL))) {
+		/* for lack of a better error? */
+		status = -EEXIST;
+		mlog(ML_ERROR,
+		     "Inode %"MLFu64" (on-disk %"MLFu64") not orphaned! "
+		     "Disk flags  0x%x, inode flags 0x%x\n",
+		     oi->ip_blkno, di->i_blkno, di->i_flags, oi->ip_flags);
+		goto bail;
+	}
+
+	/* has someone already deleted us?! baaad... */
+	if (di->i_dtime) {
+		status = -EEXIST;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_request_delete_vote(inode);
+	/* -EBUSY means that other nodes are still using the
+	 * inode. We're done here though, so avoid doing anything on
+	 * disk and let them worry about deleting it. */
+	if (status == -EBUSY) {
+		status = 0;
+		mlog(0, "Skipping delete of %"MLFu64" because it is in use on"
+		     "other nodes\n", oi->ip_blkno);
+		goto bail;
+	}
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	spin_lock(&oi->ip_lock);
+	if (oi->ip_orphaned_slot == OCFS2_INVALID_SLOT) {
+		/* Nobody knew which slot this inode was orphaned
+		 * into. This may happen during node death and
+		 * recovery knows how to clean it up so we can safely
+		 * ignore this inode for now on. */
+		mlog(0, "Nobody knew where inode %"MLFu64" was orphaned!\n",
+		     oi->ip_blkno);
+	} else {
+		*wipe = 1;
+
+		mlog(0, "Inode %"MLFu64" is ok to wipe from orphan dir %d\n",
+		     oi->ip_blkno, oi->ip_orphaned_slot);
+	}
+	spin_unlock(&oi->ip_lock);
+
+bail:
+	return status;
+}
+
+/* Support function for ocfs2_delete_inode. Will help us keep the
+ * inode data in a consistent state for clear_inode. Always truncates
+ * pages, optionally sync's them first. */
+static void ocfs2_cleanup_delete_inode(struct inode *inode,
+				       int sync_data)
+{
+	mlog(0, "Cleanup inode %"MLFu64", sync = %d\n",
+	     OCFS2_I(inode)->ip_blkno, sync_data);
+	if (sync_data)
+		write_inode_now(inode, 1);
+	truncate_inode_pages(&inode->i_data, 0);
+}
+
+void ocfs2_delete_inode(struct inode *inode)
+{
+	int wipe, status;
+	sigset_t blocked, oldset;
+	struct buffer_head *di_bh = NULL;
+
+	mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
+
+	if (is_bad_inode(inode)) {
+		mlog(0, "Skipping delete of bad inode\n");
+		goto bail;
+	}
+
+	if (!ocfs2_inode_is_valid_to_delete(inode)) {
+		/* It's probably not necessary to truncate_inode_pages
+		 * here but we do it for safety anyway (it will most
+		 * likely be a no-op anyway) */
+		ocfs2_cleanup_delete_inode(inode, 0);
+		goto bail;
+	}
+
+	/* We want to block signals in delete_inode as the lock and
+	 * messaging paths may return us -ERESTARTSYS. Which would
+	 * cause us to exit early, resulting in inodes being orphaned
+	 * forever. */
+	sigfillset(&blocked);
+	status = sigprocmask(SIG_BLOCK, &blocked, &oldset);
+	if (status < 0) {
+		mlog_errno(status);
+		ocfs2_cleanup_delete_inode(inode, 1);
+		goto bail;
+	}
+
+	/* Lock down the inode. This gives us an up to date view of
+	 * it's metadata (for verification), and allows us to
+	 * serialize delete_inode votes. 
+	 *
+	 * Even though we might be doing a truncate, we don't take the
+	 * allocation lock here as it won't be needed - nobody will
+	 * have the file open.
+	 */
+	status = ocfs2_meta_lock(inode, NULL, &di_bh, 1);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		ocfs2_cleanup_delete_inode(inode, 0);
+		goto bail_unblock;
+	}
+
+	/* Query the cluster. This will be the final decision made
+	 * before we go ahead and wipe the inode. */
+	status = ocfs2_query_inode_wipe(inode, di_bh, &wipe);
+	if (!wipe || status < 0) {
+		/* Error and inode busy vote both mean we won't be
+		 * removing the inode, so they take almost the same
+		 * path. */
+		if (status < 0)
+			mlog_errno(status);
+
+		/* Someone in the cluster has voted to not wipe this
+		 * inode, or it was never completely orphaned. Write
+		 * out the pages and exit now. */
+		ocfs2_cleanup_delete_inode(inode, 1);
+		goto bail_unlock_inode;
+	}
+
+	ocfs2_cleanup_delete_inode(inode, 0);
+
+	status = ocfs2_wipe_inode(inode, di_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail_unlock_inode;
+	}
+
+	/* Mark the inode as successfully deleted. This is important
+	 * for ocfs2_clear_inode as it will check this flag and skip
+	 * any checkpointing work */
+	OCFS2_I(inode)->ip_flags |= OCFS2_INODE_DELETED;
+
+bail_unlock_inode:
+	ocfs2_meta_unlock(inode, 1);
+	brelse(di_bh);
+bail_unblock:
+	status = sigprocmask(SIG_SETMASK, &oldset, NULL);
+	if (status < 0)
+		mlog_errno(status);
+bail:
+	clear_inode(inode);
+	mlog_exit_void();
+}
+
+void ocfs2_clear_inode(struct inode *inode)
+{
+	int status;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+	mlog_entry_void();
+
+	if (!inode)
+		goto bail;
+
+	mlog(0, "Clearing inode: %"MLFu64", nlink = %u\n",
+	     OCFS2_I(inode)->ip_blkno, inode->i_nlink);
+
+	mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,
+			"Inode=%lu\n", inode->i_ino);
+
+	/* Do these before all the other work so that we don't bounce
+	 * the vote thread while waiting to destroy the locks. */
+	ocfs2_mark_lockres_freeing(&oi->ip_rw_lockres);
+	ocfs2_mark_lockres_freeing(&oi->ip_meta_lockres);
+	ocfs2_mark_lockres_freeing(&oi->ip_data_lockres);
+
+	/* We very well may get a clear_inode before all an inodes
+	 * metadata has hit disk. Of course, we can't drop any cluster
+	 * locks until the journal has finished with it. The only
+	 * exception here are successfully wiped inodes - their
+	 * metadata can now be considered to be part of the system
+	 * inodes from which it came. */
+	if (!(OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED))
+		ocfs2_checkpoint_inode(inode);
+
+	mlog_bug_on_msg(!list_empty(&oi->ip_io_markers),
+			"Clear inode of %"MLFu64", inode has io markers\n",
+			oi->ip_blkno);
+
+	ocfs2_extent_map_drop(inode, 0);
+	ocfs2_extent_map_init(inode);
+
+	status = ocfs2_drop_inode_locks(inode);
+	if (status < 0)
+		mlog_errno(status);
+
+	ocfs2_lock_res_free(&oi->ip_rw_lockres);
+	ocfs2_lock_res_free(&oi->ip_meta_lockres);
+	ocfs2_lock_res_free(&oi->ip_data_lockres);
+
+	ocfs2_metadata_cache_purge(inode);
+
+	mlog_bug_on_msg(oi->ip_metadata_cache.ci_num_cached,
+			"Clear inode of %"MLFu64", inode has %u cache items\n",
+			oi->ip_blkno, oi->ip_metadata_cache.ci_num_cached);
+
+	mlog_bug_on_msg(!(oi->ip_flags & OCFS2_INODE_CACHE_INLINE),
+			"Clear inode of %"MLFu64", inode has a bad flag\n",
+			oi->ip_blkno);
+
+	mlog_bug_on_msg(spin_is_locked(&oi->ip_lock),
+			"Clear inode of %"MLFu64", inode is locked\n",
+			oi->ip_blkno);
+
+	mlog_bug_on_msg(down_trylock(&oi->ip_io_sem),
+			"Clear inode of %"MLFu64", io_sem is locked\n",
+			oi->ip_blkno);
+	up(&oi->ip_io_sem);
+
+	/*
+	 * down_trylock() returns 0, down_write_trylock() returns 1
+	 * kernel 1, world 0
+	 */
+	mlog_bug_on_msg(!down_write_trylock(&oi->ip_alloc_sem),
+			"Clear inode of %"MLFu64", alloc_sem is locked\n",
+			oi->ip_blkno);
+	up_write(&oi->ip_alloc_sem);
+
+	mlog_bug_on_msg(oi->ip_open_count,
+			"Clear inode of %"MLFu64" has open count %d\n",
+			oi->ip_blkno, oi->ip_open_count);
+	mlog_bug_on_msg(!list_empty(&oi->ip_handle_list),
+			"Clear inode of %"MLFu64" has non empty handle list\n",
+			oi->ip_blkno);
+	mlog_bug_on_msg(oi->ip_handle,
+			"Clear inode of %"MLFu64" has non empty handle pointer\n",
+			oi->ip_blkno);
+
+	/* Clear all other flags. */
+	oi->ip_flags = OCFS2_INODE_CACHE_INLINE;
+	oi->ip_created_trans = 0;
+	oi->ip_last_trans = 0;
+	oi->ip_dir_start_lookup = 0;
+	oi->ip_blkno = 0ULL;
+
+bail:
+	mlog_exit_void();
+}
+
+/* Called under inode_lock, with no more references on the
+ * struct inode, so it's safe here to check the flags field
+ * and to manipulate i_nlink without any other locks. */
+void ocfs2_drop_inode(struct inode *inode)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+	mlog_entry_void();
+
+	mlog(0, "Drop inode %"MLFu64", nlink = %u, ip_flags = 0x%x\n",
+	     oi->ip_blkno, inode->i_nlink, oi->ip_flags);
+
+	/* Testing ip_orphaned_slot here wouldn't work because we may
+	 * not have gotten a delete_inode vote from any other nodes
+	 * yet. */
+	if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED) {
+		mlog(0, "Inode was orphaned on another node, clearing nlink.\n");
+		inode->i_nlink = 0;
+	}
+
+	generic_drop_inode(inode);
+
+	mlog_exit_void();
+}
+
+/*
+ * TODO: this should probably be merged into ocfs2_get_block
+ *
+ * However, you now need to pay attention to the cont_prepare_write()
+ * stuff in ocfs2_get_block (that is, ocfs2_get_block pretty much
+ * expects never to extend).
+ */
+struct buffer_head *ocfs2_bread(struct inode *inode,
+				int block, int *err, int reada)
+{
+	struct buffer_head *bh = NULL;
+	int tmperr;
+	u64 p_blkno;
+	int readflags = OCFS2_BH_CACHED;
+
+#if 0
+	/* only turn this on if we know we can deal with read_block
+	 * returning nothing */
+	if (reada)
+		readflags |= OCFS2_BH_READAHEAD;
+#endif
+
+	if (((u64)block << inode->i_sb->s_blocksize_bits) >=
+	    i_size_read(inode)) {
+		BUG_ON(!reada);
+		return NULL;
+	}
+
+	tmperr = ocfs2_extent_map_get_blocks(inode, block, 1,
+					     &p_blkno, NULL);
+	if (tmperr < 0) {
+		mlog_errno(tmperr);
+		goto fail;
+	}
+
+	tmperr = ocfs2_read_block(OCFS2_SB(inode->i_sb), p_blkno, &bh,
+				  readflags, inode);
+	if (tmperr < 0)
+		goto fail;
+
+	tmperr = 0;
+
+	*err = 0;
+	return bh;
+
+fail:
+	if (bh) {
+		brelse(bh);
+		bh = NULL;
+	}
+	*err = -EIO;
+	return NULL;
+}
+
+/*
+ * This is called from our getattr.
+ */
+int ocfs2_inode_revalidate(struct dentry *dentry)
+{
+	struct inode *inode = dentry->d_inode;
+	int status = 0;
+
+	mlog_entry("(inode = 0x%p, ino = %"MLFu64")\n", inode,
+		   inode ? OCFS2_I(inode)->ip_blkno : 0ULL);
+
+	if (!inode) {
+		mlog(0, "eep, no inode!\n");
+		status = -ENOENT;
+		goto bail;
+	}
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
+		spin_unlock(&OCFS2_I(inode)->ip_lock);
+		mlog(0, "inode deleted!\n");
+		status = -ENOENT;
+		goto bail;
+	}
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	/* Let ocfs2_meta_lock do the work of updating our struct
+	 * inode for us. */
+	status = ocfs2_meta_lock(inode, NULL, NULL, 0);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		goto bail;
+	}
+	ocfs2_meta_unlock(inode, 0);
+bail:
+	mlog_exit(status);
+
+	return status;
+}
+
+/*
+ * Updates a disk inode from a
+ * struct inode.
+ * Only takes ip_lock.
+ */
+int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle,
+			   struct inode *inode,
+			   struct buffer_head *bh)
+{
+	int status;
+	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data;
+
+	mlog_entry("(inode %"MLFu64")\n", OCFS2_I(inode)->ip_blkno);
+
+	status = ocfs2_journal_access(handle, inode, bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	fe->i_size = cpu_to_le64(i_size_read(inode));
+	fe->i_links_count = cpu_to_le16(inode->i_nlink);
+	fe->i_uid = cpu_to_le32(inode->i_uid);
+	fe->i_gid = cpu_to_le32(inode->i_gid);
+	fe->i_mode = cpu_to_le16(inode->i_mode);
+	fe->i_atime = cpu_to_le64(inode->i_atime.tv_sec);
+	fe->i_atime_nsec = cpu_to_le32(inode->i_atime.tv_nsec);
+	fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
+	fe->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
+	fe->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec);
+	fe->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
+
+	status = ocfs2_journal_dirty(handle, bh);
+	if (status < 0)
+		mlog_errno(status);
+
+	status = 0;
+leave:
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ *
+ * Updates a struct inode from a disk inode.
+ * does no i/o, only takes ip_lock.
+ */
+void ocfs2_refresh_inode(struct inode *inode,
+			 struct ocfs2_dinode *fe)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+
+	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
+	i_size_write(inode, le64_to_cpu(fe->i_size));
+	inode->i_nlink = le16_to_cpu(fe->i_links_count);
+	inode->i_uid = le32_to_cpu(fe->i_uid);
+	inode->i_gid = le32_to_cpu(fe->i_gid);
+	inode->i_mode = le16_to_cpu(fe->i_mode);
+	inode->i_blksize = (u32) osb->s_clustersize;
+	if (S_ISLNK(inode->i_mode) && le32_to_cpu(fe->i_clusters) == 0)
+		inode->i_blocks = 0;
+	else
+		inode->i_blocks = ocfs2_align_bytes_to_sectors(i_size_read(inode));
+	inode->i_atime.tv_sec = le64_to_cpu(fe->i_atime);
+	inode->i_atime.tv_nsec = le32_to_cpu(fe->i_atime_nsec);
+	inode->i_mtime.tv_sec = le64_to_cpu(fe->i_mtime);
+	inode->i_mtime.tv_nsec = le32_to_cpu(fe->i_mtime_nsec);
+	inode->i_ctime.tv_sec = le64_to_cpu(fe->i_ctime);
+	inode->i_ctime.tv_nsec = le32_to_cpu(fe->i_ctime_nsec);
+
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+}
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
new file mode 100644
index 0000000..9b01774
--- /dev/null
+++ b/fs/ocfs2/inode.h
@@ -0,0 +1,145 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * inode.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_INODE_H
+#define OCFS2_INODE_H
+
+/* OCFS2 Inode Private Data */
+struct ocfs2_inode_info
+{
+	u64			ip_blkno;
+
+	struct ocfs2_lock_res		ip_rw_lockres;
+	struct ocfs2_lock_res		ip_meta_lockres;
+	struct ocfs2_lock_res		ip_data_lockres;
+
+	/* protects allocation changes on this inode. */
+	struct rw_semaphore		ip_alloc_sem;
+
+	/* These fields are protected by ip_lock */
+	spinlock_t			ip_lock;
+	u32				ip_open_count;
+	u32				ip_clusters;
+	struct ocfs2_extent_map		ip_map;
+	struct list_head		ip_io_markers;
+	int				ip_orphaned_slot;
+
+	struct semaphore		ip_io_sem;
+
+	/* Used by the journalling code to attach an inode to a
+	 * handle.  These are protected by ip_io_sem in order to lock
+	 * out other I/O to the inode until we either commit or
+	 * abort. */
+	struct list_head		ip_handle_list;
+	struct ocfs2_journal_handle	*ip_handle;
+
+	u32				ip_flags; /* see below */
+
+	/* protected by recovery_lock. */
+	struct inode			*ip_next_orphan;
+
+	u32				ip_dir_start_lookup;
+
+	/* next two are protected by trans_inc_lock */
+	/* which transaction were we created on? Zero if none. */
+	unsigned long			ip_created_trans;
+	/* last transaction we were a part of. */
+	unsigned long			ip_last_trans;
+
+	struct ocfs2_caching_info	ip_metadata_cache;
+
+	struct inode			vfs_inode;
+};
+
+/*
+ * Flags for the ip_flags field
+ */
+/* System file inodes  */
+#define OCFS2_INODE_SYSTEM_FILE		0x00000001
+#define OCFS2_INODE_JOURNAL		0x00000002
+#define OCFS2_INODE_BITMAP		0x00000004
+/* This inode has been wiped from disk */
+#define OCFS2_INODE_DELETED		0x00000008
+/* Another node is deleting, so our delete is a nop */
+#define OCFS2_INODE_SKIP_DELETE		0x00000010
+/* Has the inode been orphaned on another node?
+ *
+ * This hints to ocfs2_drop_inode that it should clear i_nlink before
+ * continuing.
+ *
+ * We *only* set this on unlink vote from another node. If the inode
+ * was locally orphaned, then we're sure of the state and don't need
+ * to twiddle i_nlink later - it's either zero or not depending on
+ * whether our unlink succeeded. Otherwise we got this from a node
+ * whose intention was to orphan the inode, however he may have
+ * crashed, failed etc, so we let ocfs2_drop_inode zero the value and
+ * rely on ocfs2_delete_inode to sort things out under the proper
+ * cluster locks.
+ */
+#define OCFS2_INODE_MAYBE_ORPHANED	0x00000020
+/* Does someone have the file open O_DIRECT */
+#define OCFS2_INODE_OPEN_DIRECT		0x00000040
+/* Indicates that the metadata cache should be used as an array. */
+#define OCFS2_INODE_CACHE_INLINE	0x00000080
+
+static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode)
+{
+	return container_of(inode, struct ocfs2_inode_info, vfs_inode);
+}
+
+#define INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags & OCFS2_INODE_JOURNAL)
+#define SET_INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags |= OCFS2_INODE_JOURNAL)
+
+extern kmem_cache_t *ocfs2_inode_cache;
+
+extern struct address_space_operations ocfs2_aops;
+
+struct buffer_head *ocfs2_bread(struct inode *inode, int block,
+				int *err, int reada);
+void ocfs2_clear_inode(struct inode *inode);
+void ocfs2_delete_inode(struct inode *inode);
+void ocfs2_drop_inode(struct inode *inode);
+struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 feoff);
+struct inode *ocfs2_ilookup_for_vote(struct ocfs2_super *osb,
+				     u64 blkno,
+				     int delete_vote);
+int ocfs2_inode_init_private(struct inode *inode);
+int ocfs2_inode_revalidate(struct dentry *dentry);
+int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
+			 int create_ino);
+void ocfs2_read_inode(struct inode *inode);
+void ocfs2_read_inode2(struct inode *inode, void *opaque);
+ssize_t ocfs2_rw_direct(int rw, struct file *filp, char *buf,
+			size_t size, loff_t *offp);
+void ocfs2_sync_blockdev(struct super_block *sb);
+void ocfs2_refresh_inode(struct inode *inode,
+			 struct ocfs2_dinode *fe);
+int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle,
+			   struct inode *inode,
+			   struct buffer_head *bh);
+int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb);
+int ocfs2_aio_write(struct file *file, struct kiocb *req, struct iocb *iocb);
+
+#endif /* OCFS2_INODE_H */
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
new file mode 100644
index 0000000..0442804
--- /dev/null
+++ b/fs/ocfs2/journal.c
@@ -0,0 +1,1652 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * journal.c
+ *
+ * Defines functions of journalling api
+ *
+ * Copyright (C) 2003, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/kthread.h>
+
+#define MLOG_MASK_PREFIX ML_JOURNAL
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "heartbeat.h"
+#include "inode.h"
+#include "journal.h"
+#include "localalloc.h"
+#include "namei.h"
+#include "slot_map.h"
+#include "super.h"
+#include "vote.h"
+#include "sysfile.h"
+
+#include "buffer_head_io.h"
+
+spinlock_t trans_inc_lock = SPIN_LOCK_UNLOCKED;
+
+static int ocfs2_force_read_journal(struct inode *inode);
+static int ocfs2_recover_node(struct ocfs2_super *osb,
+			      int node_num);
+static int __ocfs2_recovery_thread(void *arg);
+static int ocfs2_commit_cache(struct ocfs2_super *osb);
+static int ocfs2_wait_on_mount(struct ocfs2_super *osb);
+static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal,
+				       struct ocfs2_journal_handle *handle);
+static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle);
+static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
+				      int dirty);
+static int ocfs2_trylock_journal(struct ocfs2_super *osb,
+				 int slot_num);
+static int ocfs2_recover_orphans(struct ocfs2_super *osb,
+				 int slot);
+static int ocfs2_commit_thread(void *arg);
+
+static int ocfs2_commit_cache(struct ocfs2_super *osb)
+{
+	int status = 0;
+	unsigned int flushed;
+	unsigned long old_id;
+	struct ocfs2_journal *journal = NULL;
+
+	mlog_entry_void();
+
+	journal = osb->journal;
+
+	/* Flush all pending commits and checkpoint the journal. */
+	down_write(&journal->j_trans_barrier);
+
+	if (atomic_read(&journal->j_num_trans) == 0) {
+		up_write(&journal->j_trans_barrier);
+		mlog(0, "No transactions for me to flush!\n");
+		goto finally;
+	}
+
+	journal_lock_updates(journal->j_journal);
+	status = journal_flush(journal->j_journal);
+	journal_unlock_updates(journal->j_journal);
+	if (status < 0) {
+		up_write(&journal->j_trans_barrier);
+		mlog_errno(status);
+		goto finally;
+	}
+
+	old_id = ocfs2_inc_trans_id(journal);
+
+	flushed = atomic_read(&journal->j_num_trans);
+	atomic_set(&journal->j_num_trans, 0);
+	up_write(&journal->j_trans_barrier);
+
+	mlog(0, "commit_thread: flushed transaction %lu (%u handles)\n",
+	     journal->j_trans_id, flushed);
+
+	ocfs2_kick_vote_thread(osb);
+	wake_up(&journal->j_checkpointed);
+finally:
+	mlog_exit(status);
+	return status;
+}
+
+struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb)
+{
+	struct ocfs2_journal_handle *retval = NULL;
+
+	retval = kcalloc(1, sizeof(*retval), GFP_KERNEL);
+	if (!retval) {
+		mlog(ML_ERROR, "Failed to allocate memory for journal "
+		     "handle!\n");
+		return NULL;
+	}
+
+	retval->max_buffs = 0;
+	retval->num_locks = 0;
+	retval->k_handle = NULL;
+
+	INIT_LIST_HEAD(&retval->locks);
+	INIT_LIST_HEAD(&retval->inode_list);
+	retval->journal = osb->journal;
+
+	return retval;
+}
+
+/* pass it NULL and it will allocate a new handle object for you.  If
+ * you pass it a handle however, it may still return error, in which
+ * case it has free'd the passed handle for you. */
+struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb,
+					       struct ocfs2_journal_handle *handle,
+					       int max_buffs)
+{
+	int ret;
+	journal_t *journal = osb->journal->j_journal;
+
+	mlog_entry("(max_buffs = %d)\n", max_buffs);
+
+	if (!osb || !osb->journal->j_journal)
+		BUG();
+
+	if (ocfs2_is_hard_readonly(osb)) {
+		ret = -EROFS;
+		goto done_free;
+	}
+
+	BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE);
+	BUG_ON(max_buffs <= 0);
+
+	/* JBD might support this, but our journalling code doesn't yet. */
+	if (journal_current_handle()) {
+		mlog(ML_ERROR, "Recursive transaction attempted!\n");
+		BUG();
+	}
+
+	if (!handle)
+		handle = ocfs2_alloc_handle(osb);
+	if (!handle) {
+		ret = -ENOMEM;
+		mlog(ML_ERROR, "Failed to allocate memory for journal "
+		     "handle!\n");
+		goto done_free;
+	}
+
+	handle->max_buffs = max_buffs;
+
+	down_read(&osb->journal->j_trans_barrier);
+
+	/* actually start the transaction now */
+	handle->k_handle = journal_start(journal, max_buffs);
+	if (IS_ERR(handle->k_handle)) {
+		up_read(&osb->journal->j_trans_barrier);
+
+		ret = PTR_ERR(handle->k_handle);
+		handle->k_handle = NULL;
+		mlog_errno(ret);
+
+		if (is_journal_aborted(journal)) {
+			ocfs2_abort(osb->sb, "Detected aborted journal");
+			ret = -EROFS;
+		}
+		goto done_free;
+	}
+
+	atomic_inc(&(osb->journal->j_num_trans));
+	handle->flags |= OCFS2_HANDLE_STARTED;
+
+	mlog_exit_ptr(handle);
+	return handle;
+
+done_free:
+	if (handle)
+		ocfs2_commit_unstarted_handle(handle); /* will kfree handle */
+
+	mlog_exit(ret);
+	return ERR_PTR(ret);
+}
+
+void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle,
+			    struct inode *inode)
+{
+	BUG_ON(!handle);
+	BUG_ON(!inode);
+
+	atomic_inc(&inode->i_count);
+
+	/* we're obviously changing it... */
+	down(&inode->i_sem);
+
+	/* sanity check */
+	BUG_ON(OCFS2_I(inode)->ip_handle);
+	BUG_ON(!list_empty(&OCFS2_I(inode)->ip_handle_list));
+
+	OCFS2_I(inode)->ip_handle = handle;
+	list_del(&(OCFS2_I(inode)->ip_handle_list));
+	list_add_tail(&(OCFS2_I(inode)->ip_handle_list), &(handle->inode_list));
+}
+
+static void ocfs2_handle_unlock_inodes(struct ocfs2_journal_handle *handle)
+{
+	struct list_head *p, *n;
+	struct inode *inode;
+	struct ocfs2_inode_info *oi;
+
+	list_for_each_safe(p, n, &handle->inode_list) {
+		oi = list_entry(p, struct ocfs2_inode_info,
+				ip_handle_list);
+		inode = &oi->vfs_inode;
+
+		OCFS2_I(inode)->ip_handle = NULL;
+		list_del_init(&OCFS2_I(inode)->ip_handle_list);
+
+		up(&inode->i_sem);
+		iput(inode);
+	}
+}
+
+/* This is trivial so we do it out of the main commit
+ * paths. Beware, it can be called from start_trans too! */
+static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle)
+{
+	mlog_entry_void();
+
+	BUG_ON(handle->flags & OCFS2_HANDLE_STARTED);
+
+	ocfs2_handle_unlock_inodes(handle);
+	/* You are allowed to add journal locks before the transaction
+	 * has started. */
+	ocfs2_handle_cleanup_locks(handle->journal, handle);
+
+	kfree(handle);
+
+	mlog_exit_void();
+}
+
+void ocfs2_commit_trans(struct ocfs2_journal_handle *handle)
+{
+	handle_t *jbd_handle;
+	int retval;
+	struct ocfs2_journal *journal = handle->journal;
+
+	mlog_entry_void();
+
+	BUG_ON(!handle);
+
+	if (!(handle->flags & OCFS2_HANDLE_STARTED)) {
+		ocfs2_commit_unstarted_handle(handle);
+		mlog_exit_void();
+		return;
+	}
+
+	/* release inode semaphores we took during this transaction */
+	ocfs2_handle_unlock_inodes(handle);
+
+	/* ocfs2_extend_trans may have had to call journal_restart
+	 * which will always commit the transaction, but may return
+	 * error for any number of reasons. If this is the case, we
+	 * clear k_handle as it's not valid any more. */
+	if (handle->k_handle) {
+		jbd_handle = handle->k_handle;
+
+		if (handle->flags & OCFS2_HANDLE_SYNC)
+			jbd_handle->h_sync = 1;
+		else
+			jbd_handle->h_sync = 0;
+
+		/* actually stop the transaction. if we've set h_sync,
+		 * it'll have been committed when we return */
+		retval = journal_stop(jbd_handle);
+		if (retval < 0) {
+			mlog_errno(retval);
+			mlog(ML_ERROR, "Could not commit transaction\n");
+			BUG();
+		}
+
+		handle->k_handle = NULL; /* it's been free'd in journal_stop */
+	}
+
+	ocfs2_handle_cleanup_locks(journal, handle);
+
+	up_read(&journal->j_trans_barrier);
+
+	kfree(handle);
+	mlog_exit_void();
+}
+
+/*
+ * 'nblocks' is what you want to add to the current
+ * transaction. extend_trans will either extend the current handle by
+ * nblocks, or commit it and start a new one with nblocks credits.
+ *
+ * WARNING: This will not release any semaphores or disk locks taken
+ * during the transaction, so make sure they were taken *before*
+ * start_trans or we'll have ordering deadlocks.
+ *
+ * WARNING2: Note that we do *not* drop j_trans_barrier here. This is
+ * good because transaction ids haven't yet been recorded on the
+ * cluster locks associated with this handle.
+ */
+int ocfs2_extend_trans(struct ocfs2_journal_handle *handle,
+		       int nblocks)
+{
+	int status;
+
+	BUG_ON(!handle);
+	BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED));
+	BUG_ON(!nblocks);
+
+	mlog_entry_void();
+
+	mlog(0, "Trying to extend transaction by %d blocks\n", nblocks);
+
+	status = journal_extend(handle->k_handle, nblocks);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	if (status > 0) {
+		mlog(0, "journal_extend failed, trying journal_restart\n");
+		status = journal_restart(handle->k_handle, nblocks);
+		if (status < 0) {
+			handle->k_handle = NULL;
+			mlog_errno(status);
+			goto bail;
+		}
+		handle->max_buffs = nblocks;
+	} else
+		handle->max_buffs += nblocks;
+
+	status = 0;
+bail:
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
+			 struct inode *inode,
+			 struct buffer_head *bh,
+			 int type)
+{
+	int status;
+
+	BUG_ON(!inode);
+	BUG_ON(!handle);
+	BUG_ON(!bh);
+	BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED));
+
+	mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %hu\n",
+		   (unsigned long long)bh->b_blocknr, type,
+		   (type == OCFS2_JOURNAL_ACCESS_CREATE) ?
+		   "OCFS2_JOURNAL_ACCESS_CREATE" :
+		   "OCFS2_JOURNAL_ACCESS_WRITE",
+		   bh->b_size);
+
+	/* we can safely remove this assertion after testing. */
+	if (!buffer_uptodate(bh)) {
+		mlog(ML_ERROR, "giving me a buffer that's not uptodate!\n");
+		mlog(ML_ERROR, "b_blocknr=%llu\n",
+		     (unsigned long long)bh->b_blocknr);
+		BUG();
+	}
+
+	/* Set the current transaction information on the inode so
+	 * that the locking code knows whether it can drop it's locks
+	 * on this inode or not. We're protected from the commit
+	 * thread updating the current transaction id until
+	 * ocfs2_commit_trans() because ocfs2_start_trans() took
+	 * j_trans_barrier for us. */
+	ocfs2_set_inode_lock_trans(OCFS2_SB(inode->i_sb)->journal, inode);
+
+	down(&OCFS2_I(inode)->ip_io_sem);
+	switch (type) {
+	case OCFS2_JOURNAL_ACCESS_CREATE:
+	case OCFS2_JOURNAL_ACCESS_WRITE:
+		status = journal_get_write_access(handle->k_handle, bh);
+		break;
+
+	case OCFS2_JOURNAL_ACCESS_UNDO:
+		status = journal_get_undo_access(handle->k_handle, bh);
+		break;
+
+	default:
+		status = -EINVAL;
+		mlog(ML_ERROR, "Uknown access type!\n");
+	}
+	up(&OCFS2_I(inode)->ip_io_sem);
+
+	if (status < 0)
+		mlog(ML_ERROR, "Error %d getting %d access to buffer!\n",
+		     status, type);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_journal_dirty(struct ocfs2_journal_handle *handle,
+			struct buffer_head *bh)
+{
+	int status;
+
+	BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED));
+
+	mlog_entry("(bh->b_blocknr=%llu)\n",
+		   (unsigned long long)bh->b_blocknr);
+
+	status = journal_dirty_metadata(handle->k_handle, bh);
+	if (status < 0)
+		mlog(ML_ERROR, "Could not dirty metadata buffer. "
+		     "(bh->b_blocknr=%llu)\n",
+		     (unsigned long long)bh->b_blocknr);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_journal_dirty_data(handle_t *handle,
+			     struct buffer_head *bh)
+{
+	int err = journal_dirty_data(handle, bh);
+	if (err)
+		mlog_errno(err);
+	/* TODO: When we can handle it, abort the handle and go RO on
+	 * error here. */
+
+	return err;
+}
+
+/* We always assume you're adding a metadata lock at level 'ex' */
+int ocfs2_handle_add_lock(struct ocfs2_journal_handle *handle,
+			  struct inode *inode)
+{
+	int status;
+	struct ocfs2_journal_lock *lock;
+
+	BUG_ON(!inode);
+
+	lock = kmem_cache_alloc(ocfs2_lock_cache, GFP_NOFS);
+	if (!lock) {
+		status = -ENOMEM;
+		mlog_errno(-ENOMEM);
+		goto bail;
+	}
+
+	if (!igrab(inode))
+		BUG();
+	lock->jl_inode = inode;
+
+	list_add_tail(&(lock->jl_lock_list), &(handle->locks));
+	handle->num_locks++;
+
+	status = 0;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal,
+				       struct ocfs2_journal_handle *handle)
+{
+	struct list_head *p, *n;
+	struct ocfs2_journal_lock *lock;
+	struct inode *inode;
+
+	list_for_each_safe(p, n, &(handle->locks)) {
+		lock = list_entry(p, struct ocfs2_journal_lock,
+				  jl_lock_list);
+		list_del(&lock->jl_lock_list);
+		handle->num_locks--;
+
+		inode = lock->jl_inode;
+		ocfs2_meta_unlock(inode, 1);
+		if (atomic_read(&inode->i_count) == 1)
+			mlog(ML_ERROR,
+			     "Inode %"MLFu64", I'm doing a last iput for!",
+			     OCFS2_I(inode)->ip_blkno);
+		iput(inode);
+		kmem_cache_free(ocfs2_lock_cache, lock);
+	}
+}
+
+#define OCFS2_DEFAULT_COMMIT_INTERVAL 	(HZ * 5)
+
+void ocfs2_set_journal_params(struct ocfs2_super *osb)
+{
+	journal_t *journal = osb->journal->j_journal;
+
+	spin_lock(&journal->j_state_lock);
+	journal->j_commit_interval = OCFS2_DEFAULT_COMMIT_INTERVAL;
+	if (osb->s_mount_opt & OCFS2_MOUNT_BARRIER)
+		journal->j_flags |= JFS_BARRIER;
+	else
+		journal->j_flags &= ~JFS_BARRIER;
+	spin_unlock(&journal->j_state_lock);
+}
+
+int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty)
+{
+	int status = -1;
+	struct inode *inode = NULL; /* the journal inode */
+	journal_t *j_journal = NULL;
+	struct ocfs2_dinode *di = NULL;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_super *osb;
+	int meta_lock = 0;
+
+	mlog_entry_void();
+
+	BUG_ON(!journal);
+
+	osb = journal->j_osb;
+
+	/* already have the inode for our journal */
+	inode = ocfs2_get_system_file_inode(osb, JOURNAL_SYSTEM_INODE,
+					    osb->slot_num);
+	if (inode == NULL) {
+		status = -EACCES;
+		mlog_errno(status);
+		goto done;
+	}
+	if (is_bad_inode(inode)) {
+		mlog(ML_ERROR, "access error (bad inode)\n");
+		iput(inode);
+		inode = NULL;
+		status = -EACCES;
+		goto done;
+	}
+
+	SET_INODE_JOURNAL(inode);
+	OCFS2_I(inode)->ip_open_count++;
+
+	status = ocfs2_meta_lock(inode, NULL, &bh, 1);
+	if (status < 0) {
+		if (status != -ERESTARTSYS)
+			mlog(ML_ERROR, "Could not get lock on journal!\n");
+		goto done;
+	}
+
+	meta_lock = 1;
+	di = (struct ocfs2_dinode *)bh->b_data;
+
+	if (inode->i_size <  OCFS2_MIN_JOURNAL_SIZE) {
+		mlog(ML_ERROR, "Journal file size (%lld) is too small!\n",
+		     inode->i_size);
+		status = -EINVAL;
+		goto done;
+	}
+
+	mlog(0, "inode->i_size = %lld\n", inode->i_size);
+	mlog(0, "inode->i_blocks = %lu\n", inode->i_blocks);
+	mlog(0, "inode->ip_clusters = %u\n", OCFS2_I(inode)->ip_clusters);
+
+	/* call the kernels journal init function now */
+	j_journal = journal_init_inode(inode);
+	if (j_journal == NULL) {
+		mlog(ML_ERROR, "Linux journal layer error\n");
+		status = -EINVAL;
+		goto done;
+	}
+
+	mlog(0, "Returned from journal_init_inode\n");
+	mlog(0, "j_journal->j_maxlen = %u\n", j_journal->j_maxlen);
+
+	*dirty = (le32_to_cpu(di->id1.journal1.ij_flags) &
+		  OCFS2_JOURNAL_DIRTY_FL);
+
+	journal->j_journal = j_journal;
+	journal->j_inode = inode;
+	journal->j_bh = bh;
+
+	ocfs2_set_journal_params(osb);
+
+	journal->j_state = OCFS2_JOURNAL_LOADED;
+
+	status = 0;
+done:
+	if (status < 0) {
+		if (meta_lock)
+			ocfs2_meta_unlock(inode, 1);
+		if (bh != NULL)
+			brelse(bh);
+		if (inode) {
+			OCFS2_I(inode)->ip_open_count--;
+			iput(inode);
+		}
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
+				      int dirty)
+{
+	int status;
+	unsigned int flags;
+	struct ocfs2_journal *journal = osb->journal;
+	struct buffer_head *bh = journal->j_bh;
+	struct ocfs2_dinode *fe;
+
+	mlog_entry_void();
+
+	fe = (struct ocfs2_dinode *)bh->b_data;
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		/* This is called from startup/shutdown which will
+		 * handle the errors in a specific manner, so no need
+		 * to call ocfs2_error() here. */
+		mlog(ML_ERROR, "Journal dinode %"MLFu64"  has invalid "
+		     "signature: %.*s", fe->i_blkno, 7, fe->i_signature);
+		status = -EIO;
+		goto out;
+	}
+
+	flags = le32_to_cpu(fe->id1.journal1.ij_flags);
+	if (dirty)
+		flags |= OCFS2_JOURNAL_DIRTY_FL;
+	else
+		flags &= ~OCFS2_JOURNAL_DIRTY_FL;
+	fe->id1.journal1.ij_flags = cpu_to_le32(flags);
+
+	status = ocfs2_write_block(osb, bh, journal->j_inode);
+	if (status < 0)
+		mlog_errno(status);
+
+out:
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * If the journal has been kmalloc'd it needs to be freed after this
+ * call.
+ */
+void ocfs2_journal_shutdown(struct ocfs2_super *osb)
+{
+	struct ocfs2_journal *journal = NULL;
+	int status = 0;
+	struct inode *inode = NULL;
+	int num_running_trans = 0;
+
+	mlog_entry_void();
+
+	if (!osb)
+		BUG();
+
+	journal = osb->journal;
+	if (!journal)
+		goto done;
+
+	inode = journal->j_inode;
+
+	if (journal->j_state != OCFS2_JOURNAL_LOADED)
+		goto done;
+
+	/* need to inc inode use count as journal_destroy will iput. */
+	if (!igrab(inode))
+		BUG();
+
+	num_running_trans = atomic_read(&(osb->journal->j_num_trans));
+	if (num_running_trans > 0)
+		mlog(0, "Shutting down journal: must wait on %d "
+		     "running transactions!\n",
+		     num_running_trans);
+
+	/* Do a commit_cache here. It will flush our journal, *and*
+	 * release any locks that are still held.
+	 * set the SHUTDOWN flag and release the trans lock.
+	 * the commit thread will take the trans lock for us below. */
+	journal->j_state = OCFS2_JOURNAL_IN_SHUTDOWN;
+
+	/* The OCFS2_JOURNAL_IN_SHUTDOWN will signal to commit_cache to not
+	 * drop the trans_lock (which we want to hold until we
+	 * completely destroy the journal. */
+	if (osb->commit_task) {
+		/* Wait for the commit thread */
+		mlog(0, "Waiting for ocfs2commit to exit....\n");
+		kthread_stop(osb->commit_task);
+		osb->commit_task = NULL;
+	}
+
+	BUG_ON(atomic_read(&(osb->journal->j_num_trans)) != 0);
+
+	status = ocfs2_journal_toggle_dirty(osb, 0);
+	if (status < 0)
+		mlog_errno(status);
+
+	/* Shutdown the kernel journal system */
+	journal_destroy(journal->j_journal);
+
+	OCFS2_I(inode)->ip_open_count--;
+
+	/* unlock our journal */
+	ocfs2_meta_unlock(inode, 1);
+
+	brelse(journal->j_bh);
+	journal->j_bh = NULL;
+
+	journal->j_state = OCFS2_JOURNAL_FREE;
+
+//	up_write(&journal->j_trans_barrier);
+done:
+	if (inode)
+		iput(inode);
+	mlog_exit_void();
+}
+
+static void ocfs2_clear_journal_error(struct super_block *sb,
+				      journal_t *journal,
+				      int slot)
+{
+	int olderr;
+
+	olderr = journal_errno(journal);
+	if (olderr) {
+		mlog(ML_ERROR, "File system error %d recorded in "
+		     "journal %u.\n", olderr, slot);
+		mlog(ML_ERROR, "File system on device %s needs checking.\n",
+		     sb->s_id);
+
+		journal_ack_err(journal);
+		journal_clear_err(journal);
+	}
+}
+
+int ocfs2_journal_load(struct ocfs2_journal *journal)
+{
+	int status = 0;
+	struct ocfs2_super *osb;
+
+	mlog_entry_void();
+
+	if (!journal)
+		BUG();
+
+	osb = journal->j_osb;
+
+	status = journal_load(journal->j_journal);
+	if (status < 0) {
+		mlog(ML_ERROR, "Failed to load journal!\n");
+		goto done;
+	}
+
+	ocfs2_clear_journal_error(osb->sb, journal->j_journal, osb->slot_num);
+
+	status = ocfs2_journal_toggle_dirty(osb, 1);
+	if (status < 0) {
+		mlog_errno(status);
+		goto done;
+	}
+
+	/* Launch the commit thread */
+	osb->commit_task = kthread_run(ocfs2_commit_thread, osb, "ocfs2cmt-%d",
+				       osb->osb_id);
+	if (IS_ERR(osb->commit_task)) {
+		status = PTR_ERR(osb->commit_task);
+		osb->commit_task = NULL;
+		mlog(ML_ERROR, "unable to launch ocfs2commit thread, error=%d",
+		     status);
+		goto done;
+	}
+
+done:
+	mlog_exit(status);
+	return status;
+}
+
+
+/* 'full' flag tells us whether we clear out all blocks or if we just
+ * mark the journal clean */
+int ocfs2_journal_wipe(struct ocfs2_journal *journal, int full)
+{
+	int status;
+
+	mlog_entry_void();
+
+	if (!journal)
+		BUG();
+
+	status = journal_wipe(journal->j_journal, full);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_journal_toggle_dirty(journal->j_osb, 0);
+	if (status < 0)
+		mlog_errno(status);
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * JBD Might read a cached version of another nodes journal file. We
+ * don't want this as this file changes often and we get no
+ * notification on those changes. The only way to be sure that we've
+ * got the most up to date version of those blocks then is to force
+ * read them off disk. Just searching through the buffer cache won't
+ * work as there may be pages backing this file which are still marked
+ * up to date. We know things can't change on this file underneath us
+ * as we have the lock by now :)
+ */
+static int ocfs2_force_read_journal(struct inode *inode)
+{
+	int status = 0;
+	int i, p_blocks;
+	u64 v_blkno, p_blkno;
+#define CONCURRENT_JOURNAL_FILL 32
+	struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
+
+	mlog_entry_void();
+
+	BUG_ON(inode->i_blocks !=
+		     ocfs2_align_bytes_to_sectors(i_size_read(inode)));
+
+	memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
+
+	mlog(0, "Force reading %lu blocks\n",
+	     (inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9)));
+
+	v_blkno = 0;
+	while (v_blkno <
+	       (inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9))) {
+
+		status = ocfs2_extent_map_get_blocks(inode, v_blkno,
+						     1, &p_blkno,
+						     &p_blocks);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		if (p_blocks > CONCURRENT_JOURNAL_FILL)
+			p_blocks = CONCURRENT_JOURNAL_FILL;
+
+		status = ocfs2_read_blocks(OCFS2_SB(inode->i_sb),
+					   p_blkno, p_blocks, bhs, 0,
+					   inode);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		for(i = 0; i < p_blocks; i++) {
+			brelse(bhs[i]);
+			bhs[i] = NULL;
+		}
+
+		v_blkno += p_blocks;
+	}
+
+bail:
+	for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++)
+		if (bhs[i])
+			brelse(bhs[i]);
+	mlog_exit(status);
+	return status;
+}
+
+struct ocfs2_la_recovery_item {
+	struct list_head	lri_list;
+	int			lri_slot;
+	struct ocfs2_dinode	*lri_la_dinode;
+	struct ocfs2_dinode	*lri_tl_dinode;
+};
+
+/* Does the second half of the recovery process. By this point, the
+ * node is marked clean and can actually be considered recovered,
+ * hence it's no longer in the recovery map, but there's still some
+ * cleanup we can do which shouldn't happen within the recovery thread
+ * as locking in that context becomes very difficult if we are to take
+ * recovering nodes into account.
+ *
+ * NOTE: This function can and will sleep on recovery of other nodes
+ * during cluster locking, just like any other ocfs2 process.
+ */
+void ocfs2_complete_recovery(void *data)
+{
+	int ret;
+	struct ocfs2_super *osb = data;
+	struct ocfs2_journal *journal = osb->journal;
+	struct ocfs2_dinode *la_dinode, *tl_dinode;
+	struct ocfs2_la_recovery_item *item;
+	struct list_head *p, *n;
+	LIST_HEAD(tmp_la_list);
+
+	mlog_entry_void();
+
+	mlog(0, "completing recovery from keventd\n");
+
+	spin_lock(&journal->j_lock);
+	list_splice_init(&journal->j_la_cleanups, &tmp_la_list);
+	spin_unlock(&journal->j_lock);
+
+	list_for_each_safe(p, n, &tmp_la_list) {
+		item = list_entry(p, struct ocfs2_la_recovery_item, lri_list);
+		list_del_init(&item->lri_list);
+
+		mlog(0, "Complete recovery for slot %d\n", item->lri_slot);
+
+		la_dinode = item->lri_la_dinode;
+		if (la_dinode) {
+			mlog(0, "Clean up local alloc %"MLFu64"\n",
+			     la_dinode->i_blkno);
+
+			ret = ocfs2_complete_local_alloc_recovery(osb,
+								  la_dinode);
+			if (ret < 0)
+				mlog_errno(ret);
+
+			kfree(la_dinode);
+		}
+
+		tl_dinode = item->lri_tl_dinode;
+		if (tl_dinode) {
+			mlog(0, "Clean up truncate log %"MLFu64"\n",
+			     tl_dinode->i_blkno);
+
+			ret = ocfs2_complete_truncate_log_recovery(osb,
+								   tl_dinode);
+			if (ret < 0)
+				mlog_errno(ret);
+
+			kfree(tl_dinode);
+		}
+
+		ret = ocfs2_recover_orphans(osb, item->lri_slot);
+		if (ret < 0)
+			mlog_errno(ret);
+
+		kfree(item);
+	}
+
+	mlog(0, "Recovery completion\n");
+	mlog_exit_void();
+}
+
+/* NOTE: This function always eats your references to la_dinode and
+ * tl_dinode, either manually on error, or by passing them to
+ * ocfs2_complete_recovery */
+static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal,
+					    int slot_num,
+					    struct ocfs2_dinode *la_dinode,
+					    struct ocfs2_dinode *tl_dinode)
+{
+	struct ocfs2_la_recovery_item *item;
+
+	item = kmalloc(sizeof(struct ocfs2_la_recovery_item), GFP_KERNEL);
+	if (!item) {
+		/* Though we wish to avoid it, we are in fact safe in
+		 * skipping local alloc cleanup as fsck.ocfs2 is more
+		 * than capable of reclaiming unused space. */
+		if (la_dinode)
+			kfree(la_dinode);
+
+		if (tl_dinode)
+			kfree(tl_dinode);
+
+		mlog_errno(-ENOMEM);
+		return;
+	}
+
+	INIT_LIST_HEAD(&item->lri_list);
+	item->lri_la_dinode = la_dinode;
+	item->lri_slot = slot_num;
+	item->lri_tl_dinode = tl_dinode;
+
+	spin_lock(&journal->j_lock);
+	list_add_tail(&item->lri_list, &journal->j_la_cleanups);
+	queue_work(ocfs2_wq, &journal->j_recovery_work);
+	spin_unlock(&journal->j_lock);
+}
+
+/* Called by the mount code to queue recovery the last part of
+ * recovery for it's own slot. */
+void ocfs2_complete_mount_recovery(struct ocfs2_super *osb)
+{
+	struct ocfs2_journal *journal = osb->journal;
+
+	if (osb->dirty) {
+		/* No need to queue up our truncate_log as regular
+		 * cleanup will catch that. */
+		ocfs2_queue_recovery_completion(journal,
+						osb->slot_num,
+						osb->local_alloc_copy,
+						NULL);
+		ocfs2_schedule_truncate_log_flush(osb, 0);
+
+		osb->local_alloc_copy = NULL;
+		osb->dirty = 0;
+	}
+}
+
+static int __ocfs2_recovery_thread(void *arg)
+{
+	int status, node_num;
+	struct ocfs2_super *osb = arg;
+
+	mlog_entry_void();
+
+	status = ocfs2_wait_on_mount(osb);
+	if (status < 0) {
+		goto bail;
+	}
+
+restart:
+	status = ocfs2_super_lock(osb, 1);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	while(!ocfs2_node_map_is_empty(osb, &osb->recovery_map)) {
+		node_num = ocfs2_node_map_first_set_bit(osb,
+							&osb->recovery_map);
+		if (node_num == O2NM_INVALID_NODE_NUM) {
+			mlog(0, "Out of nodes to recover.\n");
+			break;
+		}
+
+		status = ocfs2_recover_node(osb, node_num);
+		if (status < 0) {
+			mlog(ML_ERROR,
+			     "Error %d recovering node %d on device (%u,%u)!\n",
+			     status, node_num,
+			     MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
+			mlog(ML_ERROR, "Volume requires unmount.\n");
+			continue;
+		}
+
+		ocfs2_recovery_map_clear(osb, node_num);
+	}
+	ocfs2_super_unlock(osb, 1);
+
+	/* We always run recovery on our own orphan dir - the dead
+	 * node(s) may have voted "no" on an inode delete earlier. A
+	 * revote is therefore required. */
+	ocfs2_queue_recovery_completion(osb->journal, osb->slot_num, NULL,
+					NULL);
+
+bail:
+	down(&osb->recovery_lock);
+	if (!status &&
+	    !ocfs2_node_map_is_empty(osb, &osb->recovery_map)) {
+		up(&osb->recovery_lock);
+		goto restart;
+	}
+
+	osb->recovery_thread_task = NULL;
+	mb(); /* sync with ocfs2_recovery_thread_running */
+	wake_up(&osb->recovery_event);
+
+	up(&osb->recovery_lock);
+
+	mlog_exit(status);
+	/* no one is callint kthread_stop() for us so the kthread() api
+	 * requires that we call do_exit().  And it isn't exported, but
+	 * complete_and_exit() seems to be a minimal wrapper around it. */
+	complete_and_exit(NULL, status);
+	return status;
+}
+
+void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
+{
+	mlog_entry("(node_num=%d, osb->node_num = %d)\n",
+		   node_num, osb->node_num);
+
+	down(&osb->recovery_lock);
+	if (osb->disable_recovery)
+		goto out;
+
+	/* People waiting on recovery will wait on
+	 * the recovery map to empty. */
+	if (!ocfs2_recovery_map_set(osb, node_num))
+		mlog(0, "node %d already be in recovery.\n", node_num);
+
+	mlog(0, "starting recovery thread...\n");
+
+	if (osb->recovery_thread_task)
+		goto out;
+
+	osb->recovery_thread_task =  kthread_run(__ocfs2_recovery_thread, osb,
+						 "ocfs2rec-%d", osb->osb_id);
+	if (IS_ERR(osb->recovery_thread_task)) {
+		mlog_errno((int)PTR_ERR(osb->recovery_thread_task));
+		osb->recovery_thread_task = NULL;
+	}
+
+out:
+	up(&osb->recovery_lock);
+	wake_up(&osb->recovery_event);
+
+	mlog_exit_void();
+}
+
+/* Does the actual journal replay and marks the journal inode as
+ * clean. Will only replay if the journal inode is marked dirty. */
+static int ocfs2_replay_journal(struct ocfs2_super *osb,
+				int node_num,
+				int slot_num)
+{
+	int status;
+	int got_lock = 0;
+	unsigned int flags;
+	struct inode *inode = NULL;
+	struct ocfs2_dinode *fe;
+	journal_t *journal = NULL;
+	struct buffer_head *bh = NULL;
+
+	inode = ocfs2_get_system_file_inode(osb, JOURNAL_SYSTEM_INODE,
+					    slot_num);
+	if (inode == NULL) {
+		status = -EACCES;
+		mlog_errno(status);
+		goto done;
+	}
+	if (is_bad_inode(inode)) {
+		status = -EACCES;
+		iput(inode);
+		inode = NULL;
+		mlog_errno(status);
+		goto done;
+	}
+	SET_INODE_JOURNAL(inode);
+
+	status = ocfs2_meta_lock_full(inode, NULL, &bh, 1,
+				      OCFS2_META_LOCK_RECOVERY);
+	if (status < 0) {
+		mlog(0, "status returned from ocfs2_meta_lock=%d\n", status);
+		if (status != -ERESTARTSYS)
+			mlog(ML_ERROR, "Could not lock journal!\n");
+		goto done;
+	}
+	got_lock = 1;
+
+	fe = (struct ocfs2_dinode *) bh->b_data;
+
+	flags = le32_to_cpu(fe->id1.journal1.ij_flags);
+
+	if (!(flags & OCFS2_JOURNAL_DIRTY_FL)) {
+		mlog(0, "No recovery required for node %d\n", node_num);
+		goto done;
+	}
+
+	mlog(ML_NOTICE, "Recovering node %d from slot %d on device (%u,%u)\n",
+	     node_num, slot_num,
+	     MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
+
+	OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
+
+	status = ocfs2_force_read_journal(inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto done;
+	}
+
+	mlog(0, "calling journal_init_inode\n");
+	journal = journal_init_inode(inode);
+	if (journal == NULL) {
+		mlog(ML_ERROR, "Linux journal layer error\n");
+		status = -EIO;
+		goto done;
+	}
+
+	status = journal_load(journal);
+	if (status < 0) {
+		mlog_errno(status);
+		if (!igrab(inode))
+			BUG();
+		journal_destroy(journal);
+		goto done;
+	}
+
+	ocfs2_clear_journal_error(osb->sb, journal, slot_num);
+
+	/* wipe the journal */
+	mlog(0, "flushing the journal.\n");
+	journal_lock_updates(journal);
+	status = journal_flush(journal);
+	journal_unlock_updates(journal);
+	if (status < 0)
+		mlog_errno(status);
+
+	/* This will mark the node clean */
+	flags = le32_to_cpu(fe->id1.journal1.ij_flags);
+	flags &= ~OCFS2_JOURNAL_DIRTY_FL;
+	fe->id1.journal1.ij_flags = cpu_to_le32(flags);
+
+	status = ocfs2_write_block(osb, bh, inode);
+	if (status < 0)
+		mlog_errno(status);
+
+	if (!igrab(inode))
+		BUG();
+
+	journal_destroy(journal);
+
+done:
+	/* drop the lock on this nodes journal */
+	if (got_lock)
+		ocfs2_meta_unlock(inode, 1);
+
+	if (inode)
+		iput(inode);
+
+	if (bh)
+		brelse(bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * Do the most important parts of node recovery:
+ *  - Replay it's journal
+ *  - Stamp a clean local allocator file
+ *  - Stamp a clean truncate log
+ *  - Mark the node clean
+ *
+ * If this function completes without error, a node in OCFS2 can be
+ * said to have been safely recovered. As a result, failure during the
+ * second part of a nodes recovery process (local alloc recovery) is
+ * far less concerning.
+ */
+static int ocfs2_recover_node(struct ocfs2_super *osb,
+			      int node_num)
+{
+	int status = 0;
+	int slot_num;
+	struct ocfs2_slot_info *si = osb->slot_info;
+	struct ocfs2_dinode *la_copy = NULL;
+	struct ocfs2_dinode *tl_copy = NULL;
+
+	mlog_entry("(node_num=%d, osb->node_num = %d)\n",
+		   node_num, osb->node_num);
+
+	mlog(0, "checking node %d\n", node_num);
+
+	/* Should not ever be called to recover ourselves -- in that
+	 * case we should've called ocfs2_journal_load instead. */
+	if (osb->node_num == node_num)
+		BUG();
+
+	slot_num = ocfs2_node_num_to_slot(si, node_num);
+	if (slot_num == OCFS2_INVALID_SLOT) {
+		status = 0;
+		mlog(0, "no slot for this node, so no recovery required.\n");
+		goto done;
+	}
+
+	mlog(0, "node %d was using slot %d\n", node_num, slot_num);
+
+	status = ocfs2_replay_journal(osb, node_num, slot_num);
+	if (status < 0) {
+		mlog_errno(status);
+		goto done;
+	}
+
+	/* Stamp a clean local alloc file AFTER recovering the journal... */
+	status = ocfs2_begin_local_alloc_recovery(osb, slot_num, &la_copy);
+	if (status < 0) {
+		mlog_errno(status);
+		goto done;
+	}
+
+	/* An error from begin_truncate_log_recovery is not
+	 * serious enough to warrant halting the rest of
+	 * recovery. */
+	status = ocfs2_begin_truncate_log_recovery(osb, slot_num, &tl_copy);
+	if (status < 0)
+		mlog_errno(status);
+
+	/* Likewise, this would be a strange but ultimately not so
+	 * harmful place to get an error... */
+	ocfs2_clear_slot(si, slot_num);
+	status = ocfs2_update_disk_slots(osb, si);
+	if (status < 0)
+		mlog_errno(status);
+
+	/* This will kfree the memory pointed to by la_copy and tl_copy */
+	ocfs2_queue_recovery_completion(osb->journal, slot_num, la_copy,
+					tl_copy);
+
+	status = 0;
+done:
+
+	mlog_exit(status);
+	return status;
+}
+
+/* Test node liveness by trylocking his journal. If we get the lock,
+ * we drop it here. Return 0 if we got the lock, -EAGAIN if node is
+ * still alive (we couldn't get the lock) and < 0 on error. */
+static int ocfs2_trylock_journal(struct ocfs2_super *osb,
+				 int slot_num)
+{
+	int status, flags;
+	struct inode *inode = NULL;
+
+	inode = ocfs2_get_system_file_inode(osb, JOURNAL_SYSTEM_INODE,
+					    slot_num);
+	if (inode == NULL) {
+		mlog(ML_ERROR, "access error\n");
+		status = -EACCES;
+		goto bail;
+	}
+	if (is_bad_inode(inode)) {
+		mlog(ML_ERROR, "access error (bad inode)\n");
+		iput(inode);
+		inode = NULL;
+		status = -EACCES;
+		goto bail;
+	}
+	SET_INODE_JOURNAL(inode);
+
+	flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE;
+	status = ocfs2_meta_lock_full(inode, NULL, NULL, 1, flags);
+	if (status < 0) {
+		if (status != -EAGAIN)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	ocfs2_meta_unlock(inode, 1);
+bail:
+	if (inode)
+		iput(inode);
+
+	return status;
+}
+
+/* Call this underneath ocfs2_super_lock. It also assumes that the
+ * slot info struct has been updated from disk. */
+int ocfs2_mark_dead_nodes(struct ocfs2_super *osb)
+{
+	int status, i, node_num;
+	struct ocfs2_slot_info *si = osb->slot_info;
+
+	/* This is called with the super block cluster lock, so we
+	 * know that the slot map can't change underneath us. */
+
+	spin_lock(&si->si_lock);
+	for(i = 0; i < si->si_num_slots; i++) {
+		if (i == osb->slot_num)
+			continue;
+		if (ocfs2_is_empty_slot(si, i))
+			continue;
+
+		node_num = si->si_global_node_nums[i];
+		if (ocfs2_node_map_test_bit(osb, &osb->recovery_map, node_num))
+			continue;
+		spin_unlock(&si->si_lock);
+
+		/* Ok, we have a slot occupied by another node which
+		 * is not in the recovery map. We trylock his journal
+		 * file here to test if he's alive. */
+		status = ocfs2_trylock_journal(osb, i);
+		if (!status) {
+			/* Since we're called from mount, we know that
+			 * the recovery thread can't race us on
+			 * setting / checking the recovery bits. */
+			ocfs2_recovery_thread(osb, node_num);
+		} else if ((status < 0) && (status != -EAGAIN)) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		spin_lock(&si->si_lock);
+	}
+	spin_unlock(&si->si_lock);
+
+	status = 0;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_recover_orphans(struct ocfs2_super *osb,
+				 int slot)
+{
+	int status = 0;
+	int have_disk_lock = 0;
+	struct inode *inode = NULL;
+	struct inode *iter;
+	struct inode *orphan_dir_inode = NULL;
+	unsigned long offset, blk, local;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_dir_entry *de;
+	struct super_block *sb = osb->sb;
+	struct ocfs2_inode_info *oi;
+
+	mlog(0, "Recover inodes from orphan dir in slot %d\n", slot);
+
+	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
+						       ORPHAN_DIR_SYSTEM_INODE,
+						       slot);
+	if  (!orphan_dir_inode) {
+		status = -ENOENT;
+		mlog_errno(status);
+		goto out;
+	}
+
+	down(&orphan_dir_inode->i_sem);
+	status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0);
+	if (status < 0) {
+		up(&orphan_dir_inode->i_sem);
+		mlog_errno(status);
+		goto out;
+	}
+	have_disk_lock = 1;
+
+	offset = 0;
+	iter = NULL;
+	while(offset < i_size_read(orphan_dir_inode)) {
+		blk = offset >> sb->s_blocksize_bits;
+
+		bh = ocfs2_bread(orphan_dir_inode, blk, &status, 0);
+		if (!bh)
+			status = -EINVAL;
+		if (status < 0) {
+			up(&orphan_dir_inode->i_sem);
+			if (bh)
+				brelse(bh);
+			mlog_errno(status);
+			goto out;
+		}
+
+		local = 0;
+		while(offset < i_size_read(orphan_dir_inode)
+		      && local < sb->s_blocksize) {
+			de = (struct ocfs2_dir_entry *) (bh->b_data + local);
+
+			if (!ocfs2_check_dir_entry(orphan_dir_inode,
+						  de, bh, local)) {
+				up(&orphan_dir_inode->i_sem);
+				status = -EINVAL;
+				mlog_errno(status);
+				brelse(bh);
+				goto out;
+			}
+
+			local += le16_to_cpu(de->rec_len);
+			offset += le16_to_cpu(de->rec_len);
+
+			/* I guess we silently fail on no inode? */
+			if (!le64_to_cpu(de->inode))
+				continue;
+			if (de->file_type > OCFS2_FT_MAX) {
+				mlog(ML_ERROR,
+				     "block %llu contains invalid de: "
+				     "inode = %"MLFu64", rec_len = %u, "
+				     "name_len = %u, file_type = %u, "
+				     "name='%.*s'\n",
+				     (unsigned long long)bh->b_blocknr,
+				     le64_to_cpu(de->inode),
+				     le16_to_cpu(de->rec_len),
+				     de->name_len,
+				     de->file_type,
+				     de->name_len,
+				     de->name);
+				continue;
+			}
+			if (de->name_len == 1 && !strncmp(".", de->name, 1))
+				continue;
+			if (de->name_len == 2 && !strncmp("..", de->name, 2))
+				continue;
+
+			iter = ocfs2_iget(osb, le64_to_cpu(de->inode));
+			if (IS_ERR(iter))
+				continue;
+
+			mlog(0, "queue orphan %"MLFu64"\n",
+			     OCFS2_I(iter)->ip_blkno);
+			OCFS2_I(iter)->ip_next_orphan = inode;
+			inode = iter;
+		}
+		brelse(bh);
+	}
+	up(&orphan_dir_inode->i_sem);
+
+	ocfs2_meta_unlock(orphan_dir_inode, 0);
+	have_disk_lock = 0;
+
+	iput(orphan_dir_inode);
+	orphan_dir_inode = NULL;
+
+	while (inode) {
+		oi = OCFS2_I(inode);
+		mlog(0, "iput orphan %"MLFu64"\n", oi->ip_blkno);
+
+		iter = oi->ip_next_orphan;
+
+		spin_lock(&oi->ip_lock);
+		/* Delete voting may have set these on the assumption
+		 * that the other node would wipe them successfully.
+		 * If they are still in the node's orphan dir, we need
+		 * to reset that state. */
+		oi->ip_flags &= ~(OCFS2_INODE_DELETED|OCFS2_INODE_SKIP_DELETE);
+
+		/* Set the proper information to get us going into
+		 * ocfs2_delete_inode. */
+		oi->ip_flags |= OCFS2_INODE_MAYBE_ORPHANED;
+		oi->ip_orphaned_slot = slot;
+		spin_unlock(&oi->ip_lock);
+
+		iput(inode);
+
+		inode = iter;
+	}
+
+out:
+	if (have_disk_lock)
+		ocfs2_meta_unlock(orphan_dir_inode, 0);
+
+	if (orphan_dir_inode)
+		iput(orphan_dir_inode);
+
+	return status;
+}
+
+static int ocfs2_wait_on_mount(struct ocfs2_super *osb)
+{
+	/* This check is good because ocfs2 will wait on our recovery
+	 * thread before changing it to something other than MOUNTED
+	 * or DISABLED. */
+	wait_event(osb->osb_mount_event,
+		   atomic_read(&osb->vol_state) == VOLUME_MOUNTED ||
+		   atomic_read(&osb->vol_state) == VOLUME_DISABLED);
+
+	/* If there's an error on mount, then we may never get to the
+	 * MOUNTED flag, but this is set right before
+	 * dismount_volume() so we can trust it. */
+	if (atomic_read(&osb->vol_state) == VOLUME_DISABLED) {
+		mlog(0, "mount error, exiting!\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static int ocfs2_commit_thread(void *arg)
+{
+	int status;
+	struct ocfs2_super *osb = arg;
+	struct ocfs2_journal *journal = osb->journal;
+
+	/* we can trust j_num_trans here because _should_stop() is only set in
+	 * shutdown and nobody other than ourselves should be able to start
+	 * transactions.  committing on shutdown might take a few iterations
+	 * as final transactions put deleted inodes on the list */
+	while (!(kthread_should_stop() &&
+		 atomic_read(&journal->j_num_trans) == 0)) {
+
+		wait_event_interruptible_timeout(osb->checkpoint_event,
+						 atomic_read(&journal->j_num_trans)
+						 || kthread_should_stop(),
+						 OCFS2_CHECKPOINT_INTERVAL);
+
+		status = ocfs2_commit_cache(osb);
+		if (status < 0)
+			mlog_errno(status);
+
+		if (kthread_should_stop() && atomic_read(&journal->j_num_trans)){
+			mlog(ML_KTHREAD,
+			     "commit_thread: %u transactions pending on "
+			     "shutdown\n",
+			     atomic_read(&journal->j_num_trans));
+		}
+	}
+
+	return 0;
+}
+
+/* Look for a dirty journal without taking any cluster locks. Used for
+ * hard readonly access to determine whether the file system journals
+ * require recovery. */
+int ocfs2_check_journals_nolocks(struct ocfs2_super *osb)
+{
+	int ret = 0;
+	unsigned int slot;
+	struct buffer_head *di_bh;
+	struct ocfs2_dinode *di;
+	struct inode *journal = NULL;
+
+	for(slot = 0; slot < osb->max_slots; slot++) {
+		journal = ocfs2_get_system_file_inode(osb,
+						      JOURNAL_SYSTEM_INODE,
+						      slot);
+		if (!journal || is_bad_inode(journal)) {
+			ret = -EACCES;
+			mlog_errno(ret);
+			goto out;
+		}
+
+		di_bh = NULL;
+		ret = ocfs2_read_block(osb, OCFS2_I(journal)->ip_blkno, &di_bh,
+				       0, journal);
+		if (ret < 0) {
+			mlog_errno(ret);
+			goto out;
+		}
+
+		di = (struct ocfs2_dinode *) di_bh->b_data;
+
+		if (le32_to_cpu(di->id1.journal1.ij_flags) &
+		    OCFS2_JOURNAL_DIRTY_FL)
+			ret = -EROFS;
+
+		brelse(di_bh);
+		if (ret)
+			break;
+	}
+
+out:
+	if (journal)
+		iput(journal);
+
+	return ret;
+}
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
new file mode 100644
index 0000000..7d0a816
--- /dev/null
+++ b/fs/ocfs2/journal.h
@@ -0,0 +1,457 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * journal.h
+ *
+ * Defines journalling api and structures.
+ *
+ * Copyright (C) 2003, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_JOURNAL_H
+#define OCFS2_JOURNAL_H
+
+#include <linux/fs.h>
+#include <linux/jbd.h>
+
+#define OCFS2_CHECKPOINT_INTERVAL        (8 * HZ)
+
+enum ocfs2_journal_state {
+	OCFS2_JOURNAL_FREE = 0,
+	OCFS2_JOURNAL_LOADED,
+	OCFS2_JOURNAL_IN_SHUTDOWN,
+};
+
+struct ocfs2_super;
+struct ocfs2_dinode;
+struct ocfs2_journal_handle;
+
+struct ocfs2_journal {
+	enum ocfs2_journal_state   j_state;    /* Journals current state   */
+
+	journal_t                 *j_journal; /* The kernels journal type */
+	struct inode              *j_inode;   /* Kernel inode pointing to
+					       * this journal             */
+	struct ocfs2_super        *j_osb;     /* pointer to the super
+					       * block for the node
+					       * we're currently
+					       * running on -- not
+					       * necessarily the super
+					       * block from the node
+					       * which we usually run
+					       * from (recovery,
+					       * etc)                     */
+	struct buffer_head        *j_bh;      /* Journal disk inode block */
+	atomic_t                  j_num_trans; /* Number of transactions
+					        * currently in the system. */
+	unsigned long             j_trans_id;
+	struct rw_semaphore       j_trans_barrier;
+	wait_queue_head_t         j_checkpointed;
+
+	spinlock_t                j_lock;
+	struct list_head          j_la_cleanups;
+	struct work_struct        j_recovery_work;
+};
+
+extern spinlock_t trans_inc_lock;
+
+/* wrap j_trans_id so we never have it equal to zero. */
+static inline unsigned long ocfs2_inc_trans_id(struct ocfs2_journal *j)
+{
+	unsigned long old_id;
+	spin_lock(&trans_inc_lock);
+	old_id = j->j_trans_id++;
+	if (unlikely(!j->j_trans_id))
+		j->j_trans_id = 1;
+	spin_unlock(&trans_inc_lock);
+	return old_id;
+}
+
+static inline void ocfs2_set_inode_lock_trans(struct ocfs2_journal *journal,
+					      struct inode *inode)
+{
+	spin_lock(&trans_inc_lock);
+	OCFS2_I(inode)->ip_last_trans = journal->j_trans_id;
+	spin_unlock(&trans_inc_lock);
+}
+
+/* Used to figure out whether it's safe to drop a metadata lock on an
+ * inode. Returns true if all the inodes changes have been
+ * checkpointed to disk. You should be holding the spinlock on the
+ * metadata lock while calling this to be sure that nobody can take
+ * the lock and put it on another transaction. */
+static inline int ocfs2_inode_fully_checkpointed(struct inode *inode)
+{
+	int ret;
+	struct ocfs2_journal *journal = OCFS2_SB(inode->i_sb)->journal;
+
+	spin_lock(&trans_inc_lock);
+	ret = time_after(journal->j_trans_id, OCFS2_I(inode)->ip_last_trans);
+	spin_unlock(&trans_inc_lock);
+	return ret;
+}
+
+/* convenience function to check if an inode is still new (has never
+ * hit disk) Will do you a favor and set created_trans = 0 when you've
+ * been checkpointed.  returns '1' if the inode is still new. */
+static inline int ocfs2_inode_is_new(struct inode *inode)
+{
+	int ret;
+
+	/* System files are never "new" as they're written out by
+	 * mkfs. This helps us early during mount, before we have the
+	 * journal open and j_trans_id could be junk. */
+	if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE)
+		return 0;
+	spin_lock(&trans_inc_lock);
+	ret = !(time_after(OCFS2_SB(inode->i_sb)->journal->j_trans_id,
+			   OCFS2_I(inode)->ip_created_trans));
+	if (!ret)
+		OCFS2_I(inode)->ip_created_trans = 0;
+	spin_unlock(&trans_inc_lock);
+	return ret;
+}
+
+static inline void ocfs2_inode_set_new(struct ocfs2_super *osb,
+				       struct inode *inode)
+{
+	spin_lock(&trans_inc_lock);
+	OCFS2_I(inode)->ip_created_trans = osb->journal->j_trans_id;
+	spin_unlock(&trans_inc_lock);
+}
+
+extern kmem_cache_t *ocfs2_lock_cache;
+
+struct ocfs2_journal_lock {
+	struct inode     *jl_inode;
+	struct list_head  jl_lock_list;
+};
+
+struct ocfs2_journal_handle {
+	handle_t            *k_handle; /* kernel handle.                */
+	struct ocfs2_journal        *journal;
+	u32                 flags;     /* see flags below.              */
+	int                 max_buffs; /* Buffs reserved by this handle */
+
+	/* The following two fields are for ocfs2_handle_add_lock */
+	int                 num_locks;
+	struct list_head    locks;     /* A bunch of locks to
+					* release on commit. This
+					* should be a list_head */
+
+	struct list_head     inode_list;
+};
+
+#define OCFS2_HANDLE_STARTED			1
+/* should we sync-commit this handle? */
+#define OCFS2_HANDLE_SYNC			2
+static inline int ocfs2_handle_started(struct ocfs2_journal_handle *handle)
+{
+	return handle->flags & OCFS2_HANDLE_STARTED;
+}
+
+static inline void ocfs2_handle_set_sync(struct ocfs2_journal_handle *handle, int sync)
+{
+	if (sync)
+		handle->flags |= OCFS2_HANDLE_SYNC;
+	else
+		handle->flags &= ~OCFS2_HANDLE_SYNC;
+}
+
+/* Exported only for the journal struct init code in super.c. Do not call. */
+void ocfs2_complete_recovery(void *data);
+
+/*
+ *  Journal Control:
+ *  Initialize, Load, Shutdown, Wipe a journal.
+ *
+ *  ocfs2_journal_init     - Initialize journal structures in the OSB.
+ *  ocfs2_journal_load     - Load the given journal off disk. Replay it if
+ *                          there's transactions still in there.
+ *  ocfs2_journal_shutdown - Shutdown a journal, this will flush all
+ *                          uncommitted, uncheckpointed transactions.
+ *  ocfs2_journal_wipe     - Wipe transactions from a journal. Optionally
+ *                          zero out each block.
+ *  ocfs2_recovery_thread  - Perform recovery on a node. osb is our own osb.
+ *  ocfs2_mark_dead_nodes - Start recovery on nodes we won't get a heartbeat
+ *                          event on.
+ *  ocfs2_start_checkpoint - Kick the commit thread to do a checkpoint.
+ */
+void   ocfs2_set_journal_params(struct ocfs2_super *osb);
+int    ocfs2_journal_init(struct ocfs2_journal *journal,
+			  int *dirty);
+void   ocfs2_journal_shutdown(struct ocfs2_super *osb);
+int    ocfs2_journal_wipe(struct ocfs2_journal *journal,
+			  int full);
+int    ocfs2_journal_load(struct ocfs2_journal *journal);
+int    ocfs2_check_journals_nolocks(struct ocfs2_super *osb);
+void   ocfs2_recovery_thread(struct ocfs2_super *osb,
+			     int node_num);
+int    ocfs2_mark_dead_nodes(struct ocfs2_super *osb);
+void   ocfs2_complete_mount_recovery(struct ocfs2_super *osb);
+
+static inline void ocfs2_start_checkpoint(struct ocfs2_super *osb)
+{
+	atomic_set(&osb->needs_checkpoint, 1);
+	wake_up(&osb->checkpoint_event);
+}
+
+static inline void ocfs2_checkpoint_inode(struct inode *inode)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (!ocfs2_inode_fully_checkpointed(inode)) {
+		/* WARNING: This only kicks off a single
+		 * checkpoint. If someone races you and adds more
+		 * metadata to the journal, you won't know, and will
+		 * wind up waiting *alot* longer than necessary. Right
+		 * now we only use this in clear_inode so that's
+		 * OK. */
+		ocfs2_start_checkpoint(osb);
+
+		wait_event(osb->journal->j_checkpointed,
+			   ocfs2_inode_fully_checkpointed(inode));
+	}
+}
+
+/*
+ *  Transaction Handling:
+ *  Manage the lifetime of a transaction handle.
+ *
+ *  ocfs2_alloc_handle     - Only allocate a handle so we can start putting
+ *                          cluster locks on it. To actually change blocks,
+ *                          call ocfs2_start_trans with the handle returned
+ *                          from this function. You may call ocfs2_commit_trans
+ *                           at any time in the lifetime of a handle.
+ *  ocfs2_start_trans      - Begin a transaction. Give it an upper estimate of
+ *                          the number of blocks that will be changed during
+ *                          this handle.
+ *  ocfs2_commit_trans     - Complete a handle.
+ *  ocfs2_extend_trans     - Extend a handle by nblocks credits. This may
+ *                          commit the handle to disk in the process, but will
+ *                          not release any locks taken during the transaction.
+ *  ocfs2_journal_access   - Notify the handle that we want to journal this
+ *                          buffer. Will have to call ocfs2_journal_dirty once
+ *                          we've actually dirtied it. Type is one of . or .
+ *  ocfs2_journal_dirty    - Mark a journalled buffer as having dirty data.
+ *  ocfs2_journal_dirty_data - Indicate that a data buffer should go out before
+ *                             the current handle commits.
+ *  ocfs2_handle_add_lock  - Sometimes we need to delay lock release
+ *                          until after a transaction has been completed. Use
+ *                          ocfs2_handle_add_lock to indicate that a lock needs
+ *                          to be released at the end of that handle. Locks
+ *                          will be released in the order that they are added.
+ *  ocfs2_handle_add_inode - Add a locked inode to a transaction.
+ */
+
+/* You must always start_trans with a number of buffs > 0, but it's
+ * perfectly legal to go through an entire transaction without having
+ * dirtied any buffers. */
+struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb);
+struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb,
+					       struct ocfs2_journal_handle *handle,
+					       int max_buffs);
+void			     ocfs2_commit_trans(struct ocfs2_journal_handle *handle);
+int			     ocfs2_extend_trans(struct ocfs2_journal_handle *handle,
+						int nblocks);
+
+/*
+ * Create access is for when we get a newly created buffer and we're
+ * not gonna read it off disk, but rather fill it ourselves.  Right
+ * now, we don't do anything special with this (it turns into a write
+ * request), but this is a good placeholder in case we do...
+ *
+ * Write access is for when we read a block off disk and are going to
+ * modify it. This way the journalling layer knows it may need to make
+ * a copy of that block (if it's part of another, uncommitted
+ * transaction) before we do so.
+ */
+#define OCFS2_JOURNAL_ACCESS_CREATE 0
+#define OCFS2_JOURNAL_ACCESS_WRITE  1
+#define OCFS2_JOURNAL_ACCESS_UNDO   2
+
+int                  ocfs2_journal_access(struct ocfs2_journal_handle *handle,
+					  struct inode *inode,
+					  struct buffer_head *bh,
+					  int type);
+/*
+ * A word about the journal_access/journal_dirty "dance". It is
+ * entirely legal to journal_access a buffer more than once (as long
+ * as the access type is the same -- I'm not sure what will happen if
+ * access type is different but this should never happen anyway) It is
+ * also legal to journal_dirty a buffer more than once. In fact, you
+ * can even journal_access a buffer after you've done a
+ * journal_access/journal_dirty pair. The only thing you cannot do
+ * however, is journal_dirty a buffer which you haven't yet passed to
+ * journal_access at least once.
+ *
+ * That said, 99% of the time this doesn't matter and this is what the
+ * path looks like:
+ *
+ *	<read a bh>
+ *	ocfs2_journal_access(handle, bh,	OCFS2_JOURNAL_ACCESS_WRITE);
+ *	<modify the bh>
+ * 	ocfs2_journal_dirty(handle, bh);
+ */
+int                  ocfs2_journal_dirty(struct ocfs2_journal_handle *handle,
+					 struct buffer_head *bh);
+int                  ocfs2_journal_dirty_data(handle_t *handle,
+					      struct buffer_head *bh);
+int                  ocfs2_handle_add_lock(struct ocfs2_journal_handle *handle,
+					   struct inode *inode);
+/*
+ * Use this to protect from other processes reading buffer state while
+ * it's in flight.
+ */
+void                 ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle,
+					    struct inode *inode);
+
+/*
+ *  Credit Macros:
+ *  Convenience macros to calculate number of credits needed.
+ *
+ *  For convenience sake, I have a set of macros here which calculate
+ *  the *maximum* number of sectors which will be changed for various
+ *  metadata updates.
+ */
+
+/* simple file updates like chmod, etc. */
+#define OCFS2_INODE_UPDATE_CREDITS 1
+
+/* get one bit out of a suballocator: dinode + group descriptor +
+ * prev. group desc. if we relink. */
+#define OCFS2_SUBALLOC_ALLOC (3)
+
+/* dinode + group descriptor update. We don't relink on free yet. */
+#define OCFS2_SUBALLOC_FREE  (2)
+
+#define OCFS2_TRUNCATE_LOG_UPDATE OCFS2_INODE_UPDATE_CREDITS
+#define OCFS2_TRUNCATE_LOG_FLUSH_ONE_REC (OCFS2_SUBALLOC_FREE 		      \
+					 + OCFS2_TRUNCATE_LOG_UPDATE)
+
+/* data block for new dir/symlink, 2 for bitmap updates (bitmap fe +
+ * bitmap block for the new bit) */
+#define OCFS2_DIR_LINK_ADDITIONAL_CREDITS (1 + 2)
+
+/* parent fe, parent block, new file entry, inode alloc fe, inode alloc
+ * group descriptor + mkdir/symlink blocks */
+#define OCFS2_MKNOD_CREDITS (3 + OCFS2_SUBALLOC_ALLOC                         \
+			    + OCFS2_DIR_LINK_ADDITIONAL_CREDITS)
+
+/* local alloc metadata change + main bitmap updates */
+#define OCFS2_WINDOW_MOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS                 \
+				  + OCFS2_SUBALLOC_ALLOC + OCFS2_SUBALLOC_FREE)
+
+/* used when we don't need an allocation change for a dir extend. One
+ * for the dinode, one for the new block. */
+#define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2)
+
+/* file update (nlink, etc) + dir entry block */
+#define OCFS2_LINK_CREDITS  (OCFS2_INODE_UPDATE_CREDITS + 1)
+
+/* inode + dir inode (if we unlink a dir), + dir entry block + orphan
+ * dir inode link */
+#define OCFS2_UNLINK_CREDITS  (2 * OCFS2_INODE_UPDATE_CREDITS + 1             \
+			      + OCFS2_LINK_CREDITS)
+
+/* dinode + orphan dir dinode + inode alloc dinode + orphan dir entry +
+ * inode alloc group descriptor */
+#define OCFS2_DELETE_INODE_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 1 + 1)
+
+/* dinode update, old dir dinode update, new dir dinode update, old
+ * dir dir entry, new dir dir entry, dir entry update for renaming
+ * directory + target unlink */
+#define OCFS2_RENAME_CREDITS (3 * OCFS2_INODE_UPDATE_CREDITS + 3              \
+			     + OCFS2_UNLINK_CREDITS)
+
+static inline int ocfs2_calc_extend_credits(struct super_block *sb,
+					    struct ocfs2_dinode *fe,
+					    u32 bits_wanted)
+{
+	int bitmap_blocks, sysfile_bitmap_blocks, dinode_blocks;
+
+	/* bitmap dinode, group desc. + relinked group. */
+	bitmap_blocks = OCFS2_SUBALLOC_ALLOC;
+
+	/* we might need to shift tree depth so lets assume an
+	 * absolute worst case of complete fragmentation.  Even with
+	 * that, we only need one update for the dinode, and then
+	 * however many metadata chunks needed * a remaining suballoc
+	 * alloc. */
+	sysfile_bitmap_blocks = 1 +
+		(OCFS2_SUBALLOC_ALLOC - 1) * ocfs2_extend_meta_needed(fe);
+
+	/* this does not include *new* metadata blocks, which are
+	 * accounted for in sysfile_bitmap_blocks. fe +
+	 * prev. last_eb_blk + blocks along edge of tree.
+	 * calc_symlink_credits passes because we just need 1
+	 * credit for the dinode there. */
+	dinode_blocks = 1 + 1 + le16_to_cpu(fe->id2.i_list.l_tree_depth);
+
+	return bitmap_blocks + sysfile_bitmap_blocks + dinode_blocks;
+}
+
+static inline int ocfs2_calc_symlink_credits(struct super_block *sb)
+{
+	int blocks = OCFS2_MKNOD_CREDITS;
+
+	/* links can be longer than one block so we may update many
+	 * within our single allocated extent. */
+	blocks += ocfs2_clusters_to_blocks(sb, 1);
+
+	return blocks;
+}
+
+static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb,
+						 unsigned int cpg)
+{
+	int blocks;
+	int bitmap_blocks = OCFS2_SUBALLOC_ALLOC + 1;
+	/* parent inode update + new block group header + bitmap inode update
+	   + bitmap blocks affected */
+	blocks = 1 + 1 + 1 + bitmap_blocks;
+	return blocks;
+}
+
+static inline int ocfs2_calc_tree_trunc_credits(struct super_block *sb,
+						unsigned int clusters_to_del,
+						struct ocfs2_dinode *fe,
+						struct ocfs2_extent_list *last_el)
+{
+ 	/* for dinode + all headers in this pass + update to next leaf */
+	u16 next_free = le16_to_cpu(last_el->l_next_free_rec);
+	u16 tree_depth = le16_to_cpu(fe->id2.i_list.l_tree_depth);
+	int credits = 1 + tree_depth + 1;
+	int i;
+
+	i = next_free - 1;
+	BUG_ON(i < 0);
+
+	/* We may be deleting metadata blocks, so metadata alloc dinode +
+	   one desc. block for each possible delete. */
+	if (tree_depth && next_free == 1 &&
+	    le32_to_cpu(last_el->l_recs[i].e_clusters) == clusters_to_del)
+		credits += 1 + tree_depth;
+
+	/* update to the truncate log. */
+	credits += OCFS2_TRUNCATE_LOG_UPDATE;
+
+	return credits;
+}
+
+#endif /* OCFS2_JOURNAL_H */
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
new file mode 100644
index 0000000..fe373a2
--- /dev/null
+++ b/fs/ocfs2/localalloc.c
@@ -0,0 +1,983 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * localalloc.c
+ *
+ * Node local data allocation
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/bitops.h>
+
+#define MLOG_MASK_PREFIX ML_DISK_ALLOC
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dlmglue.h"
+#include "inode.h"
+#include "journal.h"
+#include "localalloc.h"
+#include "suballoc.h"
+#include "super.h"
+#include "sysfile.h"
+
+#include "buffer_head_io.h"
+
+#define OCFS2_LOCAL_ALLOC(dinode)	(&((dinode)->id2.i_lab))
+
+static inline int ocfs2_local_alloc_window_bits(struct ocfs2_super *osb);
+
+static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc);
+
+static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
+					     struct ocfs2_dinode *alloc,
+					     u32 numbits);
+
+static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc);
+
+static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
+				    struct ocfs2_journal_handle *handle,
+				    struct ocfs2_dinode *alloc,
+				    struct inode *main_bm_inode,
+				    struct buffer_head *main_bm_bh);
+
+static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
+						struct ocfs2_journal_handle *handle,
+						struct ocfs2_alloc_context **ac,
+						struct inode **bitmap_inode,
+						struct buffer_head **bitmap_bh);
+
+static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
+					struct ocfs2_journal_handle *handle,
+					struct ocfs2_alloc_context *ac);
+
+static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
+					  struct inode *local_alloc_inode);
+
+/*
+ * Determine how large our local alloc window should be, in bits.
+ *
+ * These values (and the behavior in ocfs2_alloc_should_use_local) have
+ * been chosen so that most allocations, including new block groups go
+ * through local alloc.
+ */
+static inline int ocfs2_local_alloc_window_bits(struct ocfs2_super *osb)
+{
+	BUG_ON(osb->s_clustersize_bits < 12);
+
+	return 2048 >> (osb->s_clustersize_bits - 12);
+}
+
+/*
+ * Tell us whether a given allocation should use the local alloc
+ * file. Otherwise, it has to go to the main bitmap.
+ */
+int ocfs2_alloc_should_use_local(struct ocfs2_super *osb, u64 bits)
+{
+	int la_bits = ocfs2_local_alloc_window_bits(osb);
+
+	if (osb->local_alloc_state != OCFS2_LA_ENABLED)
+		return 0;
+
+	/* la_bits should be at least twice the size (in clusters) of
+	 * a new block group. We want to be sure block group
+	 * allocations go through the local alloc, so allow an
+	 * allocation to take up to half the bitmap. */
+	if (bits > (la_bits / 2))
+		return 0;
+
+	return 1;
+}
+
+int ocfs2_load_local_alloc(struct ocfs2_super *osb)
+{
+	int status = 0;
+	struct ocfs2_dinode *alloc = NULL;
+	struct buffer_head *alloc_bh = NULL;
+	u32 num_used;
+	struct inode *inode = NULL;
+	struct ocfs2_local_alloc *la;
+
+	mlog_entry_void();
+
+	/* read the alloc off disk */
+	inode = ocfs2_get_system_file_inode(osb, LOCAL_ALLOC_SYSTEM_INODE,
+					    osb->slot_num);
+	if (!inode) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno,
+				  &alloc_bh, 0, inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	alloc = (struct ocfs2_dinode *) alloc_bh->b_data;
+	la = OCFS2_LOCAL_ALLOC(alloc);
+
+	if (!(le32_to_cpu(alloc->i_flags) &
+	    (OCFS2_LOCAL_ALLOC_FL|OCFS2_BITMAP_FL))) {
+		mlog(ML_ERROR, "Invalid local alloc inode, %"MLFu64"\n",
+		     OCFS2_I(inode)->ip_blkno);
+		status = -EINVAL;
+		goto bail;
+	}
+
+	if ((la->la_size == 0) ||
+	    (le16_to_cpu(la->la_size) > ocfs2_local_alloc_size(inode->i_sb))) {
+		mlog(ML_ERROR, "Local alloc size is invalid (la_size = %u)\n",
+		     le16_to_cpu(la->la_size));
+		status = -EINVAL;
+		goto bail;
+	}
+
+	/* do a little verification. */
+	num_used = ocfs2_local_alloc_count_bits(alloc);
+
+	/* hopefully the local alloc has always been recovered before
+	 * we load it. */
+	if (num_used
+	    || alloc->id1.bitmap1.i_used
+	    || alloc->id1.bitmap1.i_total
+	    || la->la_bm_off)
+		mlog(ML_ERROR, "Local alloc hasn't been recovered!\n"
+		     "found = %u, set = %u, taken = %u, off = %u\n",
+		     num_used, le32_to_cpu(alloc->id1.bitmap1.i_used),
+		     le32_to_cpu(alloc->id1.bitmap1.i_total),
+		     OCFS2_LOCAL_ALLOC(alloc)->la_bm_off);
+
+	osb->local_alloc_bh = alloc_bh;
+	osb->local_alloc_state = OCFS2_LA_ENABLED;
+
+bail:
+	if (status < 0)
+		if (alloc_bh)
+			brelse(alloc_bh);
+	if (inode)
+		iput(inode);
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * return any unused bits to the bitmap and write out a clean
+ * local_alloc.
+ *
+ * local_alloc_bh is optional. If not passed, we will simply use the
+ * one off osb. If you do pass it however, be warned that it *will* be
+ * returned brelse'd and NULL'd out.*/
+void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
+{
+	int status;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct inode *local_alloc_inode = NULL;
+	struct buffer_head *bh = NULL;
+	struct buffer_head *main_bm_bh = NULL;
+	struct inode *main_bm_inode = NULL;
+	struct ocfs2_dinode *alloc_copy = NULL;
+	struct ocfs2_dinode *alloc = NULL;
+
+	mlog_entry_void();
+
+	if (osb->local_alloc_state == OCFS2_LA_UNUSED)
+		goto bail;
+
+	local_alloc_inode =
+		ocfs2_get_system_file_inode(osb,
+					    LOCAL_ALLOC_SYSTEM_INODE,
+					    osb->slot_num);
+	if (!local_alloc_inode) {
+		status = -ENOENT;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	osb->local_alloc_state = OCFS2_LA_DISABLED;
+
+	handle = ocfs2_alloc_handle(osb);
+	if (!handle) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	main_bm_inode = ocfs2_get_system_file_inode(osb,
+						    GLOBAL_BITMAP_SYSTEM_INODE,
+						    OCFS2_INVALID_SLOT);
+	if (!main_bm_inode) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	ocfs2_handle_add_inode(handle, main_bm_inode);
+	status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* WINDOW_MOVE_CREDITS is a bit heavy... */
+	handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS);
+	if (IS_ERR(handle)) {
+		mlog_errno(PTR_ERR(handle));
+		handle = NULL;
+		goto bail;
+	}
+
+	bh = osb->local_alloc_bh;
+	alloc = (struct ocfs2_dinode *) bh->b_data;
+
+	alloc_copy = kmalloc(bh->b_size, GFP_KERNEL);
+	if (!alloc_copy) {
+		status = -ENOMEM;
+		goto bail;
+	}
+	memcpy(alloc_copy, alloc, bh->b_size);
+
+	status = ocfs2_journal_access(handle, local_alloc_inode, bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	ocfs2_clear_local_alloc(alloc);
+
+	status = ocfs2_journal_dirty(handle, bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	brelse(bh);
+	osb->local_alloc_bh = NULL;
+	osb->local_alloc_state = OCFS2_LA_UNUSED;
+
+	status = ocfs2_sync_local_to_main(osb, handle, alloc_copy,
+					  main_bm_inode, main_bm_bh);
+	if (status < 0)
+		mlog_errno(status);
+
+bail:
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (main_bm_bh)
+		brelse(main_bm_bh);
+
+	if (main_bm_inode)
+		iput(main_bm_inode);
+
+	if (local_alloc_inode)
+		iput(local_alloc_inode);
+
+	if (alloc_copy)
+		kfree(alloc_copy);
+
+	mlog_exit_void();
+}
+
+/*
+ * We want to free the bitmap bits outside of any recovery context as
+ * we'll need a cluster lock to do so, but we must clear the local
+ * alloc before giving up the recovered nodes journal. To solve this,
+ * we kmalloc a copy of the local alloc before it's change for the
+ * caller to process with ocfs2_complete_local_alloc_recovery
+ */
+int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb,
+				     int slot_num,
+				     struct ocfs2_dinode **alloc_copy)
+{
+	int status = 0;
+	struct buffer_head *alloc_bh = NULL;
+	struct inode *inode = NULL;
+	struct ocfs2_dinode *alloc;
+
+	mlog_entry("(slot_num = %d)\n", slot_num);
+
+	*alloc_copy = NULL;
+
+	inode = ocfs2_get_system_file_inode(osb,
+					    LOCAL_ALLOC_SYSTEM_INODE,
+					    slot_num);
+	if (!inode) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	down(&inode->i_sem);
+
+	status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno,
+				  &alloc_bh, 0, inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	*alloc_copy = kmalloc(alloc_bh->b_size, GFP_KERNEL);
+	if (!(*alloc_copy)) {
+		status = -ENOMEM;
+		goto bail;
+	}
+	memcpy((*alloc_copy), alloc_bh->b_data, alloc_bh->b_size);
+
+	alloc = (struct ocfs2_dinode *) alloc_bh->b_data;
+	ocfs2_clear_local_alloc(alloc);
+
+	status = ocfs2_write_block(osb, alloc_bh, inode);
+	if (status < 0)
+		mlog_errno(status);
+
+bail:
+	if ((status < 0) && (*alloc_copy)) {
+		kfree(*alloc_copy);
+		*alloc_copy = NULL;
+	}
+
+	if (alloc_bh)
+		brelse(alloc_bh);
+
+	if (inode) {
+		up(&inode->i_sem);
+		iput(inode);
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * Step 2: By now, we've completed the journal recovery, we've stamped
+ * a clean local alloc on disk and dropped the node out of the
+ * recovery map. Dlm locks will no longer stall, so lets clear out the
+ * main bitmap.
+ */
+int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb,
+					struct ocfs2_dinode *alloc)
+{
+	int status;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct buffer_head *main_bm_bh = NULL;
+	struct inode *main_bm_inode = NULL;
+
+	mlog_entry_void();
+
+	handle = ocfs2_alloc_handle(osb);
+	if (!handle) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	main_bm_inode = ocfs2_get_system_file_inode(osb,
+						    GLOBAL_BITMAP_SYSTEM_INODE,
+						    OCFS2_INVALID_SLOT);
+	if (!main_bm_inode) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	ocfs2_handle_add_inode(handle, main_bm_inode);
+	status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* we want the bitmap change to be recorded on disk asap */
+	ocfs2_handle_set_sync(handle, 1);
+
+	status = ocfs2_sync_local_to_main(osb, handle, alloc,
+					  main_bm_inode, main_bm_bh);
+	if (status < 0)
+		mlog_errno(status);
+
+bail:
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (main_bm_bh)
+		brelse(main_bm_bh);
+
+	if (main_bm_inode)
+		iput(main_bm_inode);
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * make sure we've got at least bitswanted contiguous bits in the
+ * local alloc. You lose them when you drop i_sem.
+ *
+ * We will add ourselves to the transaction passed in, but may start
+ * our own in order to shift windows.
+ */
+int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
+				   struct ocfs2_journal_handle *passed_handle,
+				   u32 bits_wanted,
+				   struct ocfs2_alloc_context *ac)
+{
+	int status;
+	struct ocfs2_dinode *alloc;
+	struct inode *local_alloc_inode;
+	unsigned int free_bits;
+
+	mlog_entry_void();
+
+	BUG_ON(!passed_handle);
+	BUG_ON(!ac);
+	BUG_ON(passed_handle->flags & OCFS2_HANDLE_STARTED);
+
+	local_alloc_inode =
+		ocfs2_get_system_file_inode(osb,
+					    LOCAL_ALLOC_SYSTEM_INODE,
+					    osb->slot_num);
+	if (!local_alloc_inode) {
+		status = -ENOENT;
+		mlog_errno(status);
+		goto bail;
+	}
+	ocfs2_handle_add_inode(passed_handle, local_alloc_inode);
+
+	if (osb->local_alloc_state != OCFS2_LA_ENABLED) {
+		status = -ENOSPC;
+		goto bail;
+	}
+
+	if (bits_wanted > ocfs2_local_alloc_window_bits(osb)) {
+		mlog(0, "Asking for more than my max window size!\n");
+		status = -ENOSPC;
+		goto bail;
+	}
+
+	alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
+
+	if (le32_to_cpu(alloc->id1.bitmap1.i_used) !=
+	    ocfs2_local_alloc_count_bits(alloc)) {
+		ocfs2_error(osb->sb, "local alloc inode %"MLFu64" says it has "
+			    "%u free bits, but a count shows %u",
+			    le64_to_cpu(alloc->i_blkno),
+			    le32_to_cpu(alloc->id1.bitmap1.i_used),
+			    ocfs2_local_alloc_count_bits(alloc));
+		status = -EIO;
+		goto bail;
+	}
+
+	free_bits = le32_to_cpu(alloc->id1.bitmap1.i_total) -
+		le32_to_cpu(alloc->id1.bitmap1.i_used);
+	if (bits_wanted > free_bits) {
+		/* uhoh, window change time. */
+		status =
+			ocfs2_local_alloc_slide_window(osb, local_alloc_inode);
+		if (status < 0) {
+			if (status != -ENOSPC)
+				mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	ac->ac_inode = igrab(local_alloc_inode);
+	get_bh(osb->local_alloc_bh);
+	ac->ac_bh = osb->local_alloc_bh;
+	ac->ac_which = OCFS2_AC_USE_LOCAL;
+	status = 0;
+bail:
+	if (local_alloc_inode)
+		iput(local_alloc_inode);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
+				 struct ocfs2_journal_handle *handle,
+				 struct ocfs2_alloc_context *ac,
+				 u32 min_bits,
+				 u32 *bit_off,
+				 u32 *num_bits)
+{
+	int status, start;
+	struct inode *local_alloc_inode;
+	u32 bits_wanted;
+	void *bitmap;
+	struct ocfs2_dinode *alloc;
+	struct ocfs2_local_alloc *la;
+
+	mlog_entry_void();
+	BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL);
+
+	bits_wanted = ac->ac_bits_wanted - ac->ac_bits_given;
+	local_alloc_inode = ac->ac_inode;
+	alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
+	la = OCFS2_LOCAL_ALLOC(alloc);
+
+	start = ocfs2_local_alloc_find_clear_bits(osb, alloc, bits_wanted);
+	if (start == -1) {
+		/* TODO: Shouldn't we just BUG here? */
+		status = -ENOSPC;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	bitmap = la->la_bitmap;
+	*bit_off = le32_to_cpu(la->la_bm_off) + start;
+	/* local alloc is always contiguous by nature -- we never
+	 * delete bits from it! */
+	*num_bits = bits_wanted;
+
+	status = ocfs2_journal_access(handle, local_alloc_inode,
+				      osb->local_alloc_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	while(bits_wanted--)
+		ocfs2_set_bit(start++, bitmap);
+
+	alloc->id1.bitmap1.i_used = cpu_to_le32(*num_bits +
+				le32_to_cpu(alloc->id1.bitmap1.i_used));
+
+	status = ocfs2_journal_dirty(handle, osb->local_alloc_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = 0;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc)
+{
+	int i;
+	u8 *buffer;
+	u32 count = 0;
+	struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc);
+
+	mlog_entry_void();
+
+	buffer = la->la_bitmap;
+	for (i = 0; i < le16_to_cpu(la->la_size); i++)
+		count += hweight8(buffer[i]);
+
+	mlog_exit(count);
+	return count;
+}
+
+static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
+					     struct ocfs2_dinode *alloc,
+					     u32 numbits)
+{
+	int numfound, bitoff, left, startoff, lastzero;
+	void *bitmap = NULL;
+
+	mlog_entry("(numbits wanted = %u)\n", numbits);
+
+	if (!alloc->id1.bitmap1.i_total) {
+		mlog(0, "No bits in my window!\n");
+		bitoff = -1;
+		goto bail;
+	}
+
+	bitmap = OCFS2_LOCAL_ALLOC(alloc)->la_bitmap;
+
+	numfound = bitoff = startoff = 0;
+	lastzero = -1;
+	left = le32_to_cpu(alloc->id1.bitmap1.i_total);
+	while ((bitoff = ocfs2_find_next_zero_bit(bitmap, left, startoff)) != -1) {
+		if (bitoff == left) {
+			/* mlog(0, "bitoff (%d) == left", bitoff); */
+			break;
+		}
+		/* mlog(0, "Found a zero: bitoff = %d, startoff = %d, "
+		   "numfound = %d\n", bitoff, startoff, numfound);*/
+
+		/* Ok, we found a zero bit... is it contig. or do we
+		 * start over?*/
+		if (bitoff == startoff) {
+			/* we found a zero */
+			numfound++;
+			startoff++;
+		} else {
+			/* got a zero after some ones */
+			numfound = 1;
+			startoff = bitoff+1;
+		}
+		/* we got everything we needed */
+		if (numfound == numbits) {
+			/* mlog(0, "Found it all!\n"); */
+			break;
+		}
+	}
+
+	mlog(0, "Exiting loop, bitoff = %d, numfound = %d\n", bitoff,
+	     numfound);
+
+	if (numfound == numbits)
+		bitoff = startoff - numfound;
+	else
+		bitoff = -1;
+
+bail:
+	mlog_exit(bitoff);
+	return bitoff;
+}
+
+static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc)
+{
+	struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc);
+	int i;
+	mlog_entry_void();
+
+	alloc->id1.bitmap1.i_total = 0;
+	alloc->id1.bitmap1.i_used = 0;
+	la->la_bm_off = 0;
+	for(i = 0; i < le16_to_cpu(la->la_size); i++)
+		la->la_bitmap[i] = 0;
+
+	mlog_exit_void();
+}
+
+#if 0
+/* turn this on and uncomment below to aid debugging window shifts. */
+static void ocfs2_verify_zero_bits(unsigned long *bitmap,
+				   unsigned int start,
+				   unsigned int count)
+{
+	unsigned int tmp = count;
+	while(tmp--) {
+		if (ocfs2_test_bit(start + tmp, bitmap)) {
+			printk("ocfs2_verify_zero_bits: start = %u, count = "
+			       "%u\n", start, count);
+			printk("ocfs2_verify_zero_bits: bit %u is set!",
+			       start + tmp);
+			BUG();
+		}
+	}
+}
+#endif
+
+/*
+ * sync the local alloc to main bitmap.
+ *
+ * assumes you've already locked the main bitmap -- the bitmap inode
+ * passed is used for caching.
+ */
+static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
+				    struct ocfs2_journal_handle *handle,
+				    struct ocfs2_dinode *alloc,
+				    struct inode *main_bm_inode,
+				    struct buffer_head *main_bm_bh)
+{
+	int status = 0;
+	int bit_off, left, count, start;
+	u64 la_start_blk;
+	u64 blkno;
+	void *bitmap;
+	struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc);
+
+	mlog_entry("total = %u, COUNT = %u, used = %u\n",
+		   le32_to_cpu(alloc->id1.bitmap1.i_total),
+		   ocfs2_local_alloc_count_bits(alloc),
+		   le32_to_cpu(alloc->id1.bitmap1.i_used));
+
+	if (!alloc->id1.bitmap1.i_total) {
+		mlog(0, "nothing to sync!\n");
+		goto bail;
+	}
+
+	if (le32_to_cpu(alloc->id1.bitmap1.i_used) ==
+	    le32_to_cpu(alloc->id1.bitmap1.i_total)) {
+		mlog(0, "all bits were taken!\n");
+		goto bail;
+	}
+
+	la_start_blk = ocfs2_clusters_to_blocks(osb->sb,
+						le32_to_cpu(la->la_bm_off));
+	bitmap = la->la_bitmap;
+	start = count = bit_off = 0;
+	left = le32_to_cpu(alloc->id1.bitmap1.i_total);
+
+	while ((bit_off = ocfs2_find_next_zero_bit(bitmap, left, start))
+	       != -1) {
+		if ((bit_off < left) && (bit_off == start)) {
+			count++;
+			start++;
+			continue;
+		}
+		if (count) {
+			blkno = la_start_blk +
+				ocfs2_clusters_to_blocks(osb->sb,
+							 start - count);
+
+			mlog(0, "freeing %u bits starting at local "
+			     "alloc bit %u (la_start_blk = %"MLFu64", "
+			     "blkno = %"MLFu64")\n", count, start - count,
+			     la_start_blk, blkno);
+
+			status = ocfs2_free_clusters(handle, main_bm_inode,
+						     main_bm_bh, blkno, count);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+		}
+		if (bit_off >= left)
+			break;
+		count = 1;
+		start = bit_off + 1;
+	}
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
+						struct ocfs2_journal_handle *handle,
+						struct ocfs2_alloc_context **ac,
+						struct inode **bitmap_inode,
+						struct buffer_head **bitmap_bh)
+{
+	int status;
+
+	*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+	if (!(*ac)) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	(*ac)->ac_handle = handle;
+	(*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb);
+
+	status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	*bitmap_inode = (*ac)->ac_inode;
+	igrab(*bitmap_inode);
+	*bitmap_bh = (*ac)->ac_bh;
+	get_bh(*bitmap_bh);
+	status = 0;
+bail:
+	if ((status < 0) && *ac) {
+		ocfs2_free_alloc_context(*ac);
+		*ac = NULL;
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * pass it the bitmap lock in lock_bh if you have it.
+ */
+static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
+					struct ocfs2_journal_handle *handle,
+					struct ocfs2_alloc_context *ac)
+{
+	int status = 0;
+	u32 cluster_off, cluster_count;
+	struct ocfs2_dinode *alloc = NULL;
+	struct ocfs2_local_alloc *la;
+
+	mlog_entry_void();
+
+	alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
+	la = OCFS2_LOCAL_ALLOC(alloc);
+
+	if (alloc->id1.bitmap1.i_total)
+		mlog(0, "asking me to alloc a new window over a non-empty "
+		     "one\n");
+
+	mlog(0, "Allocating %u clusters for a new window.\n",
+	     ocfs2_local_alloc_window_bits(osb));
+	/* we used the generic suballoc reserve function, but we set
+	 * everything up nicely, so there's no reason why we can't use
+	 * the more specific cluster api to claim bits. */
+	status = ocfs2_claim_clusters(osb, handle, ac,
+				      ocfs2_local_alloc_window_bits(osb),
+				      &cluster_off, &cluster_count);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	la->la_bm_off = cpu_to_le32(cluster_off);
+	alloc->id1.bitmap1.i_total = cpu_to_le32(cluster_count);
+	/* just in case... In the future when we find space ourselves,
+	 * we don't have to get all contiguous -- but we'll have to
+	 * set all previously used bits in bitmap and update
+	 * la_bits_set before setting the bits in the main bitmap. */
+	alloc->id1.bitmap1.i_used = 0;
+	memset(OCFS2_LOCAL_ALLOC(alloc)->la_bitmap, 0,
+	       le16_to_cpu(la->la_size));
+
+	mlog(0, "New window allocated:\n");
+	mlog(0, "window la_bm_off = %u\n",
+	     OCFS2_LOCAL_ALLOC(alloc)->la_bm_off);
+	mlog(0, "window bits = %u\n", le32_to_cpu(alloc->id1.bitmap1.i_total));
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/* Note that we do *NOT* lock the local alloc inode here as
+ * it's been locked already for us. */
+static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
+					  struct inode *local_alloc_inode)
+{
+	int status = 0;
+	struct buffer_head *main_bm_bh = NULL;
+	struct inode *main_bm_inode = NULL;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct ocfs2_dinode *alloc;
+	struct ocfs2_dinode *alloc_copy = NULL;
+	struct ocfs2_alloc_context *ac = NULL;
+
+	mlog_entry_void();
+
+	handle = ocfs2_alloc_handle(osb);
+	if (!handle) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* This will lock the main bitmap for us. */
+	status = ocfs2_local_alloc_reserve_for_window(osb,
+						      handle,
+						      &ac,
+						      &main_bm_inode,
+						      &main_bm_bh);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
+
+	/* We want to clear the local alloc before doing anything
+	 * else, so that if we error later during this operation,
+	 * local alloc shutdown won't try to double free main bitmap
+	 * bits. Make a copy so the sync function knows which bits to
+	 * free. */
+	alloc_copy = kmalloc(osb->local_alloc_bh->b_size, GFP_KERNEL);
+	if (!alloc_copy) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+	memcpy(alloc_copy, alloc, osb->local_alloc_bh->b_size);
+
+	status = ocfs2_journal_access(handle, local_alloc_inode,
+				      osb->local_alloc_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	ocfs2_clear_local_alloc(alloc);
+
+	status = ocfs2_journal_dirty(handle, osb->local_alloc_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_sync_local_to_main(osb, handle, alloc_copy,
+					  main_bm_inode, main_bm_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_local_alloc_new_window(osb, handle, ac);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	atomic_inc(&osb->alloc_stats.moves);
+
+	status = 0;
+bail:
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (main_bm_bh)
+		brelse(main_bm_bh);
+
+	if (main_bm_inode)
+		iput(main_bm_inode);
+
+	if (alloc_copy)
+		kfree(alloc_copy);
+
+	if (ac)
+		ocfs2_free_alloc_context(ac);
+
+	mlog_exit(status);
+	return status;
+}
+
diff --git a/fs/ocfs2/localalloc.h b/fs/ocfs2/localalloc.h
new file mode 100644
index 0000000..30f88ce
--- /dev/null
+++ b/fs/ocfs2/localalloc.h
@@ -0,0 +1,56 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * localalloc.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_LOCALALLOC_H
+#define OCFS2_LOCALALLOC_H
+
+int ocfs2_load_local_alloc(struct ocfs2_super *osb);
+
+void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb);
+
+int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb,
+				     int node_num,
+				     struct ocfs2_dinode **alloc_copy);
+
+int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb,
+					struct ocfs2_dinode *alloc);
+
+int ocfs2_alloc_should_use_local(struct ocfs2_super *osb,
+				 u64 bits);
+
+struct ocfs2_alloc_context;
+int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
+				   struct ocfs2_journal_handle *passed_handle,
+				   u32 bits_wanted,
+				   struct ocfs2_alloc_context *ac);
+
+int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
+				 struct ocfs2_journal_handle *handle,
+				 struct ocfs2_alloc_context *ac,
+				 u32 min_bits,
+				 u32 *bit_off,
+				 u32 *num_bits);
+
+#endif /* OCFS2_LOCALALLOC_H */
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
new file mode 100644
index 0000000..afdeec4
--- /dev/null
+++ b/fs/ocfs2/mmap.c
@@ -0,0 +1,102 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * mmap.c
+ *
+ * Code to deal with the mess that is clustered mmap.
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/uio.h>
+#include <linux/signal.h>
+#include <linux/rbtree.h>
+
+#define MLOG_MASK_PREFIX ML_FILE_IO
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "dlmglue.h"
+#include "file.h"
+#include "inode.h"
+#include "mmap.h"
+
+static struct page *ocfs2_nopage(struct vm_area_struct * area,
+				 unsigned long address,
+				 int *type)
+{
+	struct inode *inode = area->vm_file->f_dentry->d_inode;
+	struct page *page = NOPAGE_SIGBUS;
+	sigset_t blocked, oldset;
+	int ret;
+
+	mlog_entry("(inode %lu, address %lu)\n", inode->i_ino, address);
+
+	/* The best way to deal with signals in this path is
+	 * to block them upfront, rather than allowing the
+	 * locking paths to return -ERESTARTSYS. */
+	sigfillset(&blocked);
+
+	/* We should technically never get a bad ret return
+	 * from sigprocmask */
+	ret = sigprocmask(SIG_BLOCK, &blocked, &oldset);
+	if (ret < 0) {
+		mlog_errno(ret);
+		goto out;
+	}
+
+	page = filemap_nopage(area, address, type);
+
+	ret = sigprocmask(SIG_SETMASK, &oldset, NULL);
+	if (ret < 0)
+		mlog_errno(ret);
+out:
+	mlog_exit_ptr(page);
+	return page;
+}
+
+static struct vm_operations_struct ocfs2_file_vm_ops = {
+	.nopage = ocfs2_nopage,
+};
+
+int ocfs2_mmap(struct file *file,
+	       struct vm_area_struct *vma)
+{
+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
+	struct inode *inode = mapping->host;
+
+	/* We don't want to support shared writable mappings yet. */
+	if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE))
+	    && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
+		mlog(0, "disallow shared writable mmaps %lx\n", vma->vm_flags);
+		/* This is -EINVAL because generic_file_readonly_mmap
+		 * returns it in a similar situation. */
+		return -EINVAL;
+	}
+
+	update_atime(inode);
+	vma->vm_ops = &ocfs2_file_vm_ops;
+	return 0;
+}
+
diff --git a/fs/ocfs2/mmap.h b/fs/ocfs2/mmap.h
new file mode 100644
index 0000000..1274ee0
--- /dev/null
+++ b/fs/ocfs2/mmap.h
@@ -0,0 +1,6 @@
+#ifndef OCFS2_MMAP_H
+#define OCFS2_MMAP_H
+
+int ocfs2_mmap(struct file *file, struct vm_area_struct *vma);
+
+#endif  /* OCFS2_MMAP_H */
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
new file mode 100644
index 0000000..f6b77ff1
--- /dev/null
+++ b/fs/ocfs2/namei.c
@@ -0,0 +1,2264 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * namei.c
+ *
+ * Create and rename file, directory, symlinks
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ *  Portions of this code from linux/fs/ext3/dir.c
+ *
+ *  Copyright (C) 1992, 1993, 1994, 1995
+ *  Remy Card (card@masi.ibp.fr)
+ *  Laboratoire MASI - Institut Blaise pascal
+ *  Universite Pierre et Marie Curie (Paris VI)
+ *
+ *   from
+ *
+ *   linux/fs/minix/dir.c
+ *
+ *   Copyright (C) 1991, 1992 Linux Torvalds
+ *
+ * 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+
+#define MLOG_MASK_PREFIX ML_NAMEI
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dcache.h"
+#include "dir.h"
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "file.h"
+#include "inode.h"
+#include "journal.h"
+#include "namei.h"
+#include "suballoc.h"
+#include "symlink.h"
+#include "sysfile.h"
+#include "uptodate.h"
+#include "vote.h"
+
+#include "buffer_head_io.h"
+
+#define NAMEI_RA_CHUNKS  2
+#define NAMEI_RA_BLOCKS  4
+#define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
+#define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
+
+static int inline ocfs2_search_dirblock(struct buffer_head *bh,
+					struct inode *dir,
+					const char *name, int namelen,
+					unsigned long offset,
+					struct ocfs2_dir_entry **res_dir);
+
+static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle,
+			      struct inode *dir,
+			      struct ocfs2_dir_entry *de_del,
+			      struct buffer_head *bh);
+
+static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle,
+			     struct inode *dir,
+			     const char *name, int namelen,
+			     struct inode *inode, u64 blkno,
+			     struct buffer_head *parent_fe_bh,
+			     struct buffer_head *insert_bh);
+
+static int ocfs2_mknod_locked(struct ocfs2_super *osb,
+			      struct inode *dir,
+			      struct dentry *dentry, int mode,
+			      dev_t dev,
+			      struct buffer_head **new_fe_bh,
+			      struct buffer_head *parent_fe_bh,
+			      struct ocfs2_journal_handle *handle,
+			      struct inode **ret_inode,
+			      struct ocfs2_alloc_context *inode_ac);
+
+static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
+			      struct ocfs2_journal_handle *handle,
+			      struct inode *parent,
+			      struct inode *inode,
+			      struct buffer_head *fe_bh,
+			      struct ocfs2_alloc_context *data_ac);
+
+static int ocfs2_double_lock(struct ocfs2_super *osb,
+			     struct ocfs2_journal_handle *handle,
+			     struct buffer_head **bh1,
+			     struct inode *inode1,
+			     struct buffer_head **bh2,
+			     struct inode *inode2);
+
+static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
+				    struct ocfs2_journal_handle *handle,
+				    struct inode *inode,
+				    char *name,
+				    struct buffer_head **de_bh);
+
+static int ocfs2_orphan_add(struct ocfs2_super *osb,
+			    struct ocfs2_journal_handle *handle,
+			    struct inode *inode,
+			    struct ocfs2_dinode *fe,
+			    char *name,
+			    struct buffer_head *de_bh);
+
+static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
+				     struct ocfs2_journal_handle *handle,
+				     struct inode *inode,
+				     const char *symname);
+
+static inline int ocfs2_add_entry(struct ocfs2_journal_handle *handle,
+				  struct dentry *dentry,
+				  struct inode *inode, u64 blkno,
+				  struct buffer_head *parent_fe_bh,
+				  struct buffer_head *insert_bh)
+{
+	return __ocfs2_add_entry(handle, dentry->d_parent->d_inode,
+				 dentry->d_name.name, dentry->d_name.len,
+				 inode, blkno, parent_fe_bh, insert_bh);
+}
+
+/* An orphan dir name is an 8 byte value, printed as a hex string */
+#define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64)))
+
+static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
+				   struct nameidata *nd)
+{
+	int status;
+	u64 blkno;
+	struct buffer_head *dirent_bh = NULL;
+	struct inode *inode = NULL;
+	struct dentry *ret;
+	struct ocfs2_dir_entry *dirent;
+	struct ocfs2_inode_info *oi;
+
+	mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry,
+		   dentry->d_name.len, dentry->d_name.name);
+
+	if (dentry->d_name.len > OCFS2_MAX_FILENAME_LEN) {
+		ret = ERR_PTR(-ENAMETOOLONG);
+		goto bail;
+	}
+
+	mlog(0, "find name %.*s in directory %"MLFu64"\n", dentry->d_name.len,
+	     dentry->d_name.name, OCFS2_I(dir)->ip_blkno);
+
+	status = ocfs2_meta_lock(dir, NULL, NULL, 0);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		ret = ERR_PTR(status);
+		goto bail;
+	}
+
+	status = ocfs2_find_files_on_disk(dentry->d_name.name,
+					  dentry->d_name.len, &blkno,
+					  dir, &dirent_bh, &dirent);
+	if (status < 0)
+		goto bail_add;
+
+	inode = ocfs2_iget(OCFS2_SB(dir->i_sb), blkno);
+	if (IS_ERR(inode)) {
+		mlog(ML_ERROR, "Unable to create inode %"MLFu64"\n", blkno);
+		ret = ERR_PTR(-EACCES);
+		goto bail_unlock;
+	}
+
+	oi = OCFS2_I(inode);
+	/* Clear any orphaned state... If we were able to look up the
+	 * inode from a directory, it certainly can't be orphaned. We
+	 * might have the bad state from a node which intended to
+	 * orphan this inode but crashed before it could commit the
+	 * unlink. */
+	spin_lock(&oi->ip_lock);
+	oi->ip_flags &= ~OCFS2_INODE_MAYBE_ORPHANED;
+	oi->ip_orphaned_slot = OCFS2_INVALID_SLOT;
+	spin_unlock(&oi->ip_lock);
+
+bail_add:
+
+	dentry->d_op = &ocfs2_dentry_ops;
+	ret = d_splice_alias(inode, dentry);
+
+bail_unlock:
+	/* Don't drop the cluster lock until *after* the d_add --
+	 * unlink on another node will message us to remove that
+	 * dentry under this lock so otherwise we can race this with
+	 * the vote thread and have a stale dentry. */
+	ocfs2_meta_unlock(dir, 0);
+
+bail:
+	if (dirent_bh)
+		brelse(dirent_bh);
+
+	mlog_exit_ptr(ret);
+
+	return ret;
+}
+
+static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
+			      struct ocfs2_journal_handle *handle,
+			      struct inode *parent,
+			      struct inode *inode,
+			      struct buffer_head *fe_bh,
+			      struct ocfs2_alloc_context *data_ac)
+{
+	int status;
+	struct buffer_head *new_bh = NULL;
+	struct ocfs2_dir_entry *de = NULL;
+
+	mlog_entry_void();
+
+	status = ocfs2_do_extend_dir(osb->sb, handle, inode, fe_bh,
+				     data_ac, NULL, &new_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	ocfs2_set_new_buffer_uptodate(inode, new_bh);
+
+	status = ocfs2_journal_access(handle, inode, new_bh,
+				      OCFS2_JOURNAL_ACCESS_CREATE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	memset(new_bh->b_data, 0, osb->sb->s_blocksize);
+
+	de = (struct ocfs2_dir_entry *) new_bh->b_data;
+	de->inode = cpu_to_le64(OCFS2_I(inode)->ip_blkno);
+	de->name_len = 1;
+	de->rec_len =
+		cpu_to_le16(OCFS2_DIR_REC_LEN(de->name_len));
+	strcpy(de->name, ".");
+	ocfs2_set_de_type(de, S_IFDIR);
+	de = (struct ocfs2_dir_entry *) ((char *)de + le16_to_cpu(de->rec_len));
+	de->inode = cpu_to_le64(OCFS2_I(parent)->ip_blkno);
+	de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize -
+				  OCFS2_DIR_REC_LEN(1));
+	de->name_len = 2;
+	strcpy(de->name, "..");
+	ocfs2_set_de_type(de, S_IFDIR);
+
+	status = ocfs2_journal_dirty(handle, new_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	i_size_write(inode, inode->i_sb->s_blocksize);
+	inode->i_nlink = 2;
+	inode->i_blocks = ocfs2_align_bytes_to_sectors(inode->i_sb->s_blocksize);
+	status = ocfs2_mark_inode_dirty(handle, inode, fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = 0;
+bail:
+	if (new_bh)
+		brelse(new_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_mknod(struct inode *dir,
+		       struct dentry *dentry,
+		       int mode,
+		       dev_t dev)
+{
+	int status = 0;
+	struct buffer_head *parent_fe_bh = NULL;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct ocfs2_super *osb;
+	struct ocfs2_dinode *dirfe;
+	struct buffer_head *new_fe_bh = NULL;
+	struct buffer_head *de_bh = NULL;
+	struct inode *inode = NULL;
+	struct ocfs2_alloc_context *inode_ac = NULL;
+	struct ocfs2_alloc_context *data_ac = NULL;
+
+	mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
+		   (unsigned long)dev, dentry->d_name.len,
+		   dentry->d_name.name);
+
+	/* get our super block */
+	osb = OCFS2_SB(dir->i_sb);
+
+	if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
+		mlog(ML_ERROR, "inode %"MLFu64" has i_nlink of %u\n",
+		     OCFS2_I(dir)->ip_blkno, dir->i_nlink);
+		status = -EMLINK;
+		goto leave;
+	}
+
+	handle = ocfs2_alloc_handle(osb);
+	if (handle == NULL) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		goto leave;
+	}
+
+	dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
+	if (!dirfe->i_links_count) {
+		/* can't make a file in a deleted directory. */
+		status = -ENOENT;
+		goto leave;
+	}
+
+	status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
+					   dentry->d_name.len);
+	if (status)
+		goto leave;
+
+	/* get a spot inside the dir. */
+	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
+					      dentry->d_name.name,
+					      dentry->d_name.len, &de_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	/* reserve an inode spot */
+	status = ocfs2_reserve_new_inode(osb, handle, &inode_ac);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto leave;
+	}
+
+	/* are we making a directory? If so, reserve a cluster for his
+	 * 1st extent. */
+	if (S_ISDIR(mode)) {
+		status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac);
+		if (status < 0) {
+			if (status != -ENOSPC)
+				mlog_errno(status);
+			goto leave;
+		}
+	}
+
+	handle = ocfs2_start_trans(osb, handle, OCFS2_MKNOD_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	/* do the real work now. */
+	status = ocfs2_mknod_locked(osb, dir, dentry, mode, dev,
+				    &new_fe_bh, parent_fe_bh, handle,
+				    &inode, inode_ac);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	if (S_ISDIR(mode)) {
+		status = ocfs2_fill_new_dir(osb, handle, dir, inode,
+					    new_fe_bh, data_ac);
+		if (status < 0) {
+			mlog_errno(status);
+			goto leave;
+		}
+
+		status = ocfs2_journal_access(handle, dir, parent_fe_bh,
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			mlog_errno(status);
+			goto leave;
+		}
+		le16_add_cpu(&dirfe->i_links_count, 1);
+		status = ocfs2_journal_dirty(handle, parent_fe_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto leave;
+		}
+		dir->i_nlink++;
+	}
+
+	status = ocfs2_add_entry(handle, dentry, inode,
+				 OCFS2_I(inode)->ip_blkno, parent_fe_bh,
+				 de_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	insert_inode_hash(inode);
+	dentry->d_op = &ocfs2_dentry_ops;
+	d_instantiate(dentry, inode);
+	status = 0;
+leave:
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (status == -ENOSPC)
+		mlog(0, "Disk is full\n");
+
+	if (new_fe_bh)
+		brelse(new_fe_bh);
+
+	if (de_bh)
+		brelse(de_bh);
+
+	if (parent_fe_bh)
+		brelse(parent_fe_bh);
+
+	if ((status < 0) && inode)
+		iput(inode);
+
+	if (inode_ac)
+		ocfs2_free_alloc_context(inode_ac);
+
+	if (data_ac)
+		ocfs2_free_alloc_context(data_ac);
+
+	mlog_exit(status);
+
+	return status;
+}
+
+static int ocfs2_mknod_locked(struct ocfs2_super *osb,
+			      struct inode *dir,
+			      struct dentry *dentry, int mode,
+			      dev_t dev,
+			      struct buffer_head **new_fe_bh,
+			      struct buffer_head *parent_fe_bh,
+			      struct ocfs2_journal_handle *handle,
+			      struct inode **ret_inode,
+			      struct ocfs2_alloc_context *inode_ac)
+{
+	int status = 0;
+	struct ocfs2_dinode *fe = NULL;
+	struct ocfs2_extent_list *fel;
+	u64 fe_blkno = 0;
+	u16 suballoc_bit;
+	struct inode *inode = NULL;
+
+	mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
+		   (unsigned long)dev, dentry->d_name.len,
+		   dentry->d_name.name);
+
+	*new_fe_bh = NULL;
+	*ret_inode = NULL;
+
+	status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit,
+				       &fe_blkno);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	inode = new_inode(dir->i_sb);
+	if (IS_ERR(inode)) {
+		status = PTR_ERR(inode);
+		mlog(ML_ERROR, "new_inode failed!\n");
+		goto leave;
+	}
+
+	/* populate as many fields early on as possible - many of
+	 * these are used by the support functions here and in
+	 * callers. */
+	inode->i_ino = ino_from_blkno(osb->sb, fe_blkno);
+	OCFS2_I(inode)->ip_blkno = fe_blkno;
+	if (S_ISDIR(mode))
+		inode->i_nlink = 2;
+	else
+		inode->i_nlink = 1;
+	inode->i_mode = mode;
+	spin_lock(&osb->osb_lock);
+	inode->i_generation = osb->s_next_generation++;
+	spin_unlock(&osb->osb_lock);
+
+	*new_fe_bh = sb_getblk(osb->sb, fe_blkno);
+	if (!*new_fe_bh) {
+		status = -EIO;
+		mlog_errno(status);
+		goto leave;
+	}
+	ocfs2_set_new_buffer_uptodate(inode, *new_fe_bh);
+
+	status = ocfs2_journal_access(handle, inode, *new_fe_bh,
+				      OCFS2_JOURNAL_ACCESS_CREATE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	fe = (struct ocfs2_dinode *) (*new_fe_bh)->b_data;
+	memset(fe, 0, osb->sb->s_blocksize);
+
+	fe->i_generation = cpu_to_le32(inode->i_generation);
+	fe->i_fs_generation = cpu_to_le32(osb->fs_generation);
+	fe->i_blkno = cpu_to_le64(fe_blkno);
+	fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
+	fe->i_suballoc_slot = cpu_to_le16(osb->slot_num);
+	fe->i_uid = cpu_to_le32(current->fsuid);
+	if (dir->i_mode & S_ISGID) {
+		fe->i_gid = cpu_to_le32(dir->i_gid);
+		if (S_ISDIR(mode))
+			mode |= S_ISGID;
+	} else
+		fe->i_gid = cpu_to_le32(current->fsgid);
+	fe->i_mode = cpu_to_le16(mode);
+	if (S_ISCHR(mode) || S_ISBLK(mode))
+		fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
+
+	fe->i_links_count = cpu_to_le16(inode->i_nlink);
+
+	fe->i_last_eb_blk = 0;
+	strcpy(fe->i_signature, OCFS2_INODE_SIGNATURE);
+	le32_add_cpu(&fe->i_flags, OCFS2_VALID_FL);
+	fe->i_atime = fe->i_ctime = fe->i_mtime =
+		cpu_to_le64(CURRENT_TIME.tv_sec);
+	fe->i_mtime_nsec = fe->i_ctime_nsec = fe->i_atime_nsec =
+		cpu_to_le32(CURRENT_TIME.tv_nsec);
+	fe->i_dtime = 0;
+
+	fel = &fe->id2.i_list;
+	fel->l_tree_depth = 0;
+	fel->l_next_free_rec = 0;
+	fel->l_count = cpu_to_le16(ocfs2_extent_recs_per_inode(osb->sb));
+
+	status = ocfs2_journal_dirty(handle, *new_fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	if (ocfs2_populate_inode(inode, fe, 1) < 0) {
+		mlog(ML_ERROR, "populate inode failed! bh->b_blocknr=%llu, "
+		     "i_blkno=%"MLFu64", i_ino=%lu\n",
+		     (unsigned long long) (*new_fe_bh)->b_blocknr,
+		     fe->i_blkno, inode->i_ino);
+		BUG();
+	}
+
+	ocfs2_inode_set_new(osb, inode);
+	status = ocfs2_create_new_inode_locks(inode);
+	if (status < 0)
+		mlog_errno(status);
+
+	status = 0; /* error in ocfs2_create_new_inode_locks is not
+		     * critical */
+
+	*ret_inode = inode;
+leave:
+	if (status < 0) {
+		if (*new_fe_bh) {
+			brelse(*new_fe_bh);
+			*new_fe_bh = NULL;
+		}
+		if (inode)
+			iput(inode);
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_mkdir(struct inode *dir,
+		       struct dentry *dentry,
+		       int mode)
+{
+	int ret;
+
+	mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry, mode,
+		   dentry->d_name.len, dentry->d_name.name);
+	ret = ocfs2_mknod(dir, dentry, mode | S_IFDIR, 0);
+	mlog_exit(ret);
+
+	return ret;
+}
+
+static int ocfs2_create(struct inode *dir,
+			struct dentry *dentry,
+			int mode,
+			struct nameidata *nd)
+{
+	int ret;
+
+	mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry, mode,
+		   dentry->d_name.len, dentry->d_name.name);
+	ret = ocfs2_mknod(dir, dentry, mode | S_IFREG, 0);
+	mlog_exit(ret);
+
+	return ret;
+}
+
+static int ocfs2_link(struct dentry *old_dentry,
+		      struct inode *dir,
+		      struct dentry *dentry)
+{
+	struct ocfs2_journal_handle *handle = NULL;
+	struct inode *inode = old_dentry->d_inode;
+	int err;
+	struct buffer_head *fe_bh = NULL;
+	struct buffer_head *parent_fe_bh = NULL;
+	struct buffer_head *de_bh = NULL;
+	struct ocfs2_dinode *fe = NULL;
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+
+	mlog_entry("(inode=%lu, old='%.*s' new='%.*s')\n", inode->i_ino,
+		   old_dentry->d_name.len, old_dentry->d_name.name,
+		   dentry->d_name.len, dentry->d_name.name);
+
+	if (S_ISDIR(inode->i_mode)) {
+		err = -EPERM;
+		goto bail;
+	}
+
+	if (inode->i_nlink >= OCFS2_LINK_MAX) {
+		err = -EMLINK;
+		goto bail;
+	}
+
+	handle = ocfs2_alloc_handle(osb);
+	if (handle == NULL) {
+		err = -ENOMEM;
+		goto bail;
+	}
+
+	err = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1);
+	if (err < 0) {
+		if (err != -ENOENT)
+			mlog_errno(err);
+		goto bail;
+	}
+
+	err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
+					dentry->d_name.len);
+	if (err)
+		goto bail;
+
+	err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
+					   dentry->d_name.name,
+					   dentry->d_name.len, &de_bh);
+	if (err < 0) {
+		mlog_errno(err);
+		goto bail;
+	}
+
+	err = ocfs2_meta_lock(inode, handle, &fe_bh, 1);
+	if (err < 0) {
+		if (err != -ENOENT)
+			mlog_errno(err);
+		goto bail;
+	}
+
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+	if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) {
+		err = -EMLINK;
+		goto bail;
+	}
+
+	handle = ocfs2_start_trans(osb, handle, OCFS2_LINK_CREDITS);
+	if (IS_ERR(handle)) {
+		err = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(err);
+		goto bail;
+	}
+
+	err = ocfs2_journal_access(handle, inode, fe_bh,
+				   OCFS2_JOURNAL_ACCESS_WRITE);
+	if (err < 0) {
+		mlog_errno(err);
+		goto bail;
+	}
+
+	inode->i_nlink++;
+	inode->i_ctime = CURRENT_TIME;
+	fe->i_links_count = cpu_to_le16(inode->i_nlink);
+	fe->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
+	fe->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
+
+	err = ocfs2_journal_dirty(handle, fe_bh);
+	if (err < 0) {
+		le16_add_cpu(&fe->i_links_count, -1);
+		inode->i_nlink--;
+		mlog_errno(err);
+		goto bail;
+	}
+
+	err = ocfs2_add_entry(handle, dentry, inode,
+			      OCFS2_I(inode)->ip_blkno,
+			      parent_fe_bh, de_bh);
+	if (err) {
+		le16_add_cpu(&fe->i_links_count, -1);
+		inode->i_nlink--;
+		mlog_errno(err);
+		goto bail;
+	}
+
+	atomic_inc(&inode->i_count);
+	dentry->d_op = &ocfs2_dentry_ops;
+	d_instantiate(dentry, inode);
+bail:
+	if (handle)
+		ocfs2_commit_trans(handle);
+	if (de_bh)
+		brelse(de_bh);
+	if (fe_bh)
+		brelse(fe_bh);
+	if (parent_fe_bh)
+		brelse(parent_fe_bh);
+
+	mlog_exit(err);
+
+	return err;
+}
+
+static int ocfs2_unlink(struct inode *dir,
+			struct dentry *dentry)
+{
+	int status;
+	unsigned int saved_nlink = 0;
+	struct inode *inode = dentry->d_inode;
+	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
+	u64 blkno;
+	struct ocfs2_dinode *fe = NULL;
+	struct buffer_head *fe_bh = NULL;
+	struct buffer_head *parent_node_bh = NULL;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct ocfs2_dir_entry *dirent = NULL;
+	struct buffer_head *dirent_bh = NULL;
+	char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
+	struct buffer_head *orphan_entry_bh = NULL;
+
+	mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry,
+		   dentry->d_name.len, dentry->d_name.name);
+
+	BUG_ON(dentry->d_parent->d_inode != dir);
+
+	mlog(0, "ino = %"MLFu64"\n", OCFS2_I(inode)->ip_blkno);
+
+	if (inode == osb->root_inode) {
+		mlog(0, "Cannot delete the root directory\n");
+		status = -EPERM;
+		goto leave;
+	}
+
+	handle = ocfs2_alloc_handle(osb);
+	if (handle == NULL) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_meta_lock(dir, handle, &parent_node_bh, 1);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_find_files_on_disk(dentry->d_name.name,
+					  dentry->d_name.len, &blkno,
+					  dir, &dirent_bh, &dirent);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		goto leave;
+	}
+
+	if (OCFS2_I(inode)->ip_blkno != blkno) {
+		status = -ENOENT;
+
+		mlog(0, "ip_blkno (%"MLFu64") != dirent blkno (%"MLFu64") "
+		     "ip_flags = %x\n", OCFS2_I(inode)->ip_blkno, blkno,
+		     OCFS2_I(inode)->ip_flags);
+		goto leave;
+	}
+
+	status = ocfs2_meta_lock(inode, handle, &fe_bh, 1);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		goto leave;
+	}
+
+	if (S_ISDIR(inode->i_mode)) {
+	       	if (!ocfs2_empty_dir(inode)) {
+			status = -ENOTEMPTY;
+			goto leave;
+		} else if (inode->i_nlink != 2) {
+			status = -ENOTEMPTY;
+			goto leave;
+		}
+	}
+
+	/* There are still a few steps left until we can consider the
+	 * unlink to have succeeded. Save off nlink here before
+	 * modification so we can set it back in case we hit an issue
+	 * before commit. */
+	saved_nlink = inode->i_nlink;
+	if (S_ISDIR(inode->i_mode))
+		inode->i_nlink = 0;
+	else
+		inode->i_nlink--;
+
+	status = ocfs2_request_unlink_vote(inode, dentry,
+					   (unsigned int) inode->i_nlink);
+	if (status < 0) {
+		/* This vote should succeed under all normal
+		 * circumstances. */
+		mlog_errno(status);
+		goto leave;
+	}
+
+	if (!inode->i_nlink) {
+		status = ocfs2_prepare_orphan_dir(osb, handle, inode,
+						  orphan_name,
+						  &orphan_entry_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto leave;
+		}
+	}
+
+	handle = ocfs2_start_trans(osb, handle, OCFS2_UNLINK_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_journal_access(handle, inode, fe_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	fe = (struct ocfs2_dinode *) fe_bh->b_data;
+
+	if (!inode->i_nlink) {
+		status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
+					  orphan_entry_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto leave;
+		}
+	}
+
+	/* delete the name from the parent dir */
+	status = ocfs2_delete_entry(handle, dir, dirent, dirent_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	/* We can set nlink on the dinode now. clear the saved version
+	 * so that it doesn't get set later. */
+	fe->i_links_count = cpu_to_le16(inode->i_nlink);
+	saved_nlink = 0;
+
+	status = ocfs2_journal_dirty(handle, fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	if (S_ISDIR(inode->i_mode)) {
+		dir->i_nlink--;
+		status = ocfs2_mark_inode_dirty(handle, dir,
+						parent_node_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			dir->i_nlink++;
+		}
+	}
+
+leave:
+	if (status < 0 && saved_nlink)
+		inode->i_nlink = saved_nlink;
+
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (fe_bh)
+		brelse(fe_bh);
+
+	if (dirent_bh)
+		brelse(dirent_bh);
+
+	if (parent_node_bh)
+		brelse(parent_node_bh);
+
+	if (orphan_entry_bh)
+		brelse(orphan_entry_bh);
+
+	mlog_exit(status);
+
+	return status;
+}
+
+/*
+ * The only place this should be used is rename!
+ * if they have the same id, then the 1st one is the only one locked.
+ */
+static int ocfs2_double_lock(struct ocfs2_super *osb,
+			     struct ocfs2_journal_handle *handle,
+			     struct buffer_head **bh1,
+			     struct inode *inode1,
+			     struct buffer_head **bh2,
+			     struct inode *inode2)
+{
+	int status;
+	struct ocfs2_inode_info *oi1 = OCFS2_I(inode1);
+	struct ocfs2_inode_info *oi2 = OCFS2_I(inode2);
+	struct buffer_head **tmpbh;
+	struct inode *tmpinode;
+
+	mlog_entry("(inode1 = %"MLFu64", inode2 = %"MLFu64")\n",
+		   oi1->ip_blkno, oi2->ip_blkno);
+
+	BUG_ON(!handle);
+
+	if (*bh1)
+		*bh1 = NULL;
+	if (*bh2)
+		*bh2 = NULL;
+
+	/* we always want to lock the one with the lower lockid first. */
+	if (oi1->ip_blkno != oi2->ip_blkno) {
+		if (oi1->ip_blkno < oi2->ip_blkno) {
+			/* switch id1 and id2 around */
+			mlog(0, "switching them around...\n");
+			tmpbh = bh2;
+			bh2 = bh1;
+			bh1 = tmpbh;
+
+			tmpinode = inode2;
+			inode2 = inode1;
+			inode1 = tmpinode;
+		}
+		/* lock id2 */
+		status = ocfs2_meta_lock(inode2, handle, bh2, 1);
+		if (status < 0) {
+			if (status != -ENOENT)
+				mlog_errno(status);
+			goto bail;
+		}
+	}
+	/* lock id1 */
+	status = ocfs2_meta_lock(inode1, handle, bh1, 1);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		goto bail;
+	}
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+#define PARENT_INO(buffer) \
+	((struct ocfs2_dir_entry *) \
+	 ((char *)buffer + \
+	  le16_to_cpu(((struct ocfs2_dir_entry *)buffer)->rec_len)))->inode
+
+static int ocfs2_rename(struct inode *old_dir,
+			struct dentry *old_dentry,
+			struct inode *new_dir,
+			struct dentry *new_dentry)
+{
+	int status = 0, rename_lock = 0;
+	struct inode *old_inode = old_dentry->d_inode;
+	struct inode *new_inode = new_dentry->d_inode;
+	struct ocfs2_dinode *newfe = NULL;
+	char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
+	struct buffer_head *orphan_entry_bh = NULL;
+	struct buffer_head *newfe_bh = NULL;
+	struct buffer_head *insert_entry_bh = NULL;
+	struct ocfs2_super *osb = NULL;
+	u64 newfe_blkno;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct buffer_head *old_dir_bh = NULL;
+	struct buffer_head *new_dir_bh = NULL;
+	struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry
+							       // and new_dentry
+	struct buffer_head *new_de_bh = NULL, *old_de_bh = NULL; // bhs for above
+	struct buffer_head *old_inode_de_bh = NULL; // if old_dentry is a dir,
+						    // this is the 1st dirent bh
+	nlink_t old_dir_nlink = old_dir->i_nlink, new_dir_nlink = new_dir->i_nlink;
+	unsigned int links_count;
+
+	/* At some point it might be nice to break this function up a
+	 * bit. */
+
+	mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p, from='%.*s' to='%.*s')\n",
+		   old_dir, old_dentry, new_dir, new_dentry,
+		   old_dentry->d_name.len, old_dentry->d_name.name,
+		   new_dentry->d_name.len, new_dentry->d_name.name);
+
+	osb = OCFS2_SB(old_dir->i_sb);
+
+	if (new_inode) {
+		if (!igrab(new_inode))
+			BUG();
+	}
+
+	if (atomic_read(&old_dentry->d_count) > 2) {
+		shrink_dcache_parent(old_dentry);
+		if (atomic_read(&old_dentry->d_count) > 2) {
+			status = -EBUSY;
+			goto bail;
+		}
+	}
+
+	/* Assume a directory heirarchy thusly:
+	 * a/b/c
+	 * a/d
+	 * a,b,c, and d are all directories.
+	 *
+	 * from cwd of 'a' on both nodes:
+	 * node1: mv b/c d
+	 * node2: mv d   b/c
+	 *
+	 * And that's why, just like the VFS, we need a file system
+	 * rename lock. */
+	if (old_dentry != new_dentry) {
+		status = ocfs2_rename_lock(osb);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		rename_lock = 1;
+	}
+
+	handle = ocfs2_alloc_handle(osb);
+	if (handle == NULL) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* if old and new are the same, this'll just do one lock. */
+	status = ocfs2_double_lock(osb, handle,
+				  &old_dir_bh, old_dir,
+				  &new_dir_bh, new_dir);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* make sure both dirs have bhs
+	 * get an extra ref on old_dir_bh if old==new */
+	if (!new_dir_bh) {
+		if (old_dir_bh) {
+			new_dir_bh = old_dir_bh;
+			get_bh(new_dir_bh);
+		} else {
+			mlog(ML_ERROR, "no old_dir_bh!\n");
+			status = -EIO;
+			goto bail;
+		}
+	}
+
+	if (S_ISDIR(old_inode->i_mode)) {
+		/* Directories actually require metadata updates to
+		 * the directory info so we can't get away with not
+		 * doing node locking on it. */
+		status = ocfs2_meta_lock(old_inode, handle, NULL, 1);
+		if (status < 0) {
+			if (status != -ENOENT)
+				mlog_errno(status);
+			goto bail;
+		}
+
+		status = ocfs2_request_rename_vote(old_inode, old_dentry);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		status = -EIO;
+		old_inode_de_bh = ocfs2_bread(old_inode, 0, &status, 0);
+		if (!old_inode_de_bh)
+			goto bail;
+
+		status = -EIO;
+		if (le64_to_cpu(PARENT_INO(old_inode_de_bh->b_data)) !=
+		    OCFS2_I(old_dir)->ip_blkno)
+			goto bail;
+		status = -EMLINK;
+		if (!new_inode && new_dir!=old_dir &&
+		    new_dir->i_nlink >= OCFS2_LINK_MAX)
+			goto bail;
+	} else {
+		/* Ah, the simple case - we're a file so just send a
+		 * message. */
+		status = ocfs2_request_rename_vote(old_inode, old_dentry);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	status = -ENOENT;
+	old_de_bh = ocfs2_find_entry(old_dentry->d_name.name,
+				     old_dentry->d_name.len,
+				     old_dir, &old_de);
+	if (!old_de_bh)
+		goto bail;
+
+	/*
+	 *  Check for inode number is _not_ due to possible IO errors.
+	 *  We might rmdir the source, keep it as pwd of some process
+	 *  and merrily kill the link to whatever was created under the
+	 *  same name. Goodbye sticky bit ;-<
+	 */
+	if (le64_to_cpu(old_de->inode) != OCFS2_I(old_inode)->ip_blkno)
+		goto bail;
+
+	/* check if the target already exists (in which case we need
+	 * to delete it */
+	status = ocfs2_find_files_on_disk(new_dentry->d_name.name,
+					  new_dentry->d_name.len,
+					  &newfe_blkno, new_dir, &new_de_bh,
+					  &new_de);
+	/* The only error we allow here is -ENOENT because the new
+	 * file not existing is perfectly valid. */
+	if ((status < 0) && (status != -ENOENT)) {
+		/* If we cannot find the file specified we should just */
+		/* return the error... */
+		mlog_errno(status);
+		goto bail;
+	}
+
+	if (!new_de && new_inode)
+		mlog(ML_ERROR, "inode %lu does not exist in it's parent "
+		     "directory!", new_inode->i_ino);
+
+	/* In case we need to overwrite an existing file, we blow it
+	 * away first */
+	if (new_de) {
+		/* VFS didn't think there existed an inode here, but
+		 * someone else in the cluster must have raced our
+		 * rename to create one. Today we error cleanly, in
+		 * the future we should consider calling iget to build
+		 * a new struct inode for this entry. */
+		if (!new_inode) {
+			status = -EACCES;
+
+			mlog(0, "We found an inode for name %.*s but VFS "
+			     "didn't give us one.\n", new_dentry->d_name.len,
+			     new_dentry->d_name.name);
+			goto bail;
+		}
+
+		if (OCFS2_I(new_inode)->ip_blkno != newfe_blkno) {
+			status = -EACCES;
+
+			mlog(0, "Inode blkno (%"MLFu64") and dir (%"MLFu64") "
+			     "disagree. ip_flags = %x\n",
+			     OCFS2_I(new_inode)->ip_blkno, newfe_blkno,
+			     OCFS2_I(new_inode)->ip_flags);
+			goto bail;
+		}
+
+		status = ocfs2_meta_lock(new_inode, handle, &newfe_bh, 1);
+		if (status < 0) {
+			if (status != -ENOENT)
+				mlog_errno(status);
+			goto bail;
+		}
+
+		if (S_ISDIR(new_inode->i_mode))
+			links_count = 0;
+		else
+			links_count = (unsigned int) (new_inode->i_nlink - 1);
+
+		status = ocfs2_request_unlink_vote(new_inode, new_dentry,
+						   links_count);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		newfe = (struct ocfs2_dinode *) newfe_bh->b_data;
+
+		mlog(0, "aha rename over existing... new_de=%p "
+		     "new_blkno=%"MLFu64" newfebh=%p bhblocknr=%llu\n",
+		     new_de, newfe_blkno, newfe_bh, newfe_bh ?
+		     (unsigned long long)newfe_bh->b_blocknr : 0ULL);
+
+		if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) {
+			status = ocfs2_prepare_orphan_dir(osb, handle,
+							  new_inode,
+							  orphan_name,
+							  &orphan_entry_bh);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+		}
+	} else {
+		BUG_ON(new_dentry->d_parent->d_inode != new_dir);
+
+		status = ocfs2_check_dir_for_entry(new_dir,
+						   new_dentry->d_name.name,
+						   new_dentry->d_name.len);
+		if (status)
+			goto bail;
+
+		status = ocfs2_prepare_dir_for_insert(osb, new_dir, new_dir_bh,
+						      new_dentry->d_name.name,
+						      new_dentry->d_name.len,
+						      &insert_entry_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	handle = ocfs2_start_trans(osb, handle, OCFS2_RENAME_CREDITS);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	if (new_de) {
+		if (S_ISDIR(new_inode->i_mode)) {
+			if (!ocfs2_empty_dir(new_inode) ||
+			    new_inode->i_nlink != 2) {
+				status = -ENOTEMPTY;
+				goto bail;
+			}
+		}
+		status = ocfs2_journal_access(handle, new_inode, newfe_bh,
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		if (S_ISDIR(new_inode->i_mode) ||
+		    (newfe->i_links_count == cpu_to_le16(1))){
+			status = ocfs2_orphan_add(osb, handle, new_inode,
+						  newfe, orphan_name,
+						  orphan_entry_bh);
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+		}
+
+		/* change the dirent to point to the correct inode */
+		status = ocfs2_journal_access(handle, new_dir, new_de_bh,
+					      OCFS2_JOURNAL_ACCESS_WRITE);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		new_de->inode = cpu_to_le64(OCFS2_I(old_inode)->ip_blkno);
+		new_de->file_type = old_de->file_type;
+		new_dir->i_version++;
+		status = ocfs2_journal_dirty(handle, new_de_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		if (S_ISDIR(new_inode->i_mode))
+			newfe->i_links_count = 0;
+		else
+			le16_add_cpu(&newfe->i_links_count, -1);
+
+		status = ocfs2_journal_dirty(handle, newfe_bh);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	} else {
+		/* if the name was not found in new_dir, add it now */
+		status = ocfs2_add_entry(handle, new_dentry, old_inode,
+					 OCFS2_I(old_inode)->ip_blkno,
+					 new_dir_bh, insert_entry_bh);
+	}
+
+	old_inode->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(old_inode);
+
+	/* now that the name has been added to new_dir, remove the old name */
+	status = ocfs2_delete_entry(handle, old_dir, old_de, old_de_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	if (new_inode) {
+		new_inode->i_nlink--;
+		new_inode->i_ctime = CURRENT_TIME;
+	}
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	if (old_inode_de_bh) {
+		status = ocfs2_journal_access(handle, old_inode,
+					     old_inode_de_bh,
+					     OCFS2_JOURNAL_ACCESS_WRITE);
+		PARENT_INO(old_inode_de_bh->b_data) =
+			cpu_to_le64(OCFS2_I(new_dir)->ip_blkno);
+		status = ocfs2_journal_dirty(handle, old_inode_de_bh);
+		old_dir->i_nlink--;
+		if (new_inode) {
+			new_inode->i_nlink--;
+		} else {
+			new_dir->i_nlink++;
+			mark_inode_dirty(new_dir);
+		}
+	}
+	mark_inode_dirty(old_dir);
+	if (new_inode)
+		mark_inode_dirty(new_inode);
+
+	if (old_dir != new_dir)
+		if (new_dir_nlink != new_dir->i_nlink) {
+			if (!new_dir_bh) {
+				mlog(ML_ERROR, "need to change nlink for new "
+				     "dir %"MLFu64" from %d to %d but bh is "
+				     "NULL\n", OCFS2_I(new_dir)->ip_blkno,
+				     (int)new_dir_nlink, new_dir->i_nlink);
+			} else {
+				struct ocfs2_dinode *fe;
+				status = ocfs2_journal_access(handle,
+							      new_dir,
+							      new_dir_bh,
+							      OCFS2_JOURNAL_ACCESS_WRITE);
+				fe = (struct ocfs2_dinode *) new_dir_bh->b_data;
+				fe->i_links_count = cpu_to_le16(new_dir->i_nlink);
+				status = ocfs2_journal_dirty(handle, new_dir_bh);
+			}
+		}
+
+	if (old_dir_nlink != old_dir->i_nlink) {
+		if (!old_dir_bh) {
+			mlog(ML_ERROR, "need to change nlink for old dir "
+			     "%"MLFu64" from %d to %d but bh is NULL!\n",
+			     OCFS2_I(old_dir)->ip_blkno,
+			     (int)old_dir_nlink,
+			     old_dir->i_nlink);
+		} else {
+			struct ocfs2_dinode *fe;
+			status = ocfs2_journal_access(handle, old_dir,
+						      old_dir_bh,
+						      OCFS2_JOURNAL_ACCESS_WRITE);
+			fe = (struct ocfs2_dinode *) old_dir_bh->b_data;
+			fe->i_links_count = cpu_to_le16(old_dir->i_nlink);
+			status = ocfs2_journal_dirty(handle, old_dir_bh);
+		}
+	}
+
+	status = 0;
+bail:
+	if (rename_lock)
+		ocfs2_rename_unlock(osb);
+
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (new_inode)
+		sync_mapping_buffers(old_inode->i_mapping);
+
+	if (new_inode)
+		iput(new_inode);
+	if (newfe_bh)
+		brelse(newfe_bh);
+	if (old_dir_bh)
+		brelse(old_dir_bh);
+	if (new_dir_bh)
+		brelse(new_dir_bh);
+	if (new_de_bh)
+		brelse(new_de_bh);
+	if (old_de_bh)
+		brelse(old_de_bh);
+	if (old_inode_de_bh)
+		brelse(old_inode_de_bh);
+	if (orphan_entry_bh)
+		brelse(orphan_entry_bh);
+	if (insert_entry_bh)
+		brelse(insert_entry_bh);
+
+	mlog_exit(status);
+
+	return status;
+}
+
+/*
+ * we expect i_size = strlen(symname). Copy symname into the file
+ * data, including the null terminator.
+ */
+static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
+				     struct ocfs2_journal_handle *handle,
+				     struct inode *inode,
+				     const char *symname)
+{
+	struct buffer_head **bhs = NULL;
+	const char *c;
+	struct super_block *sb = osb->sb;
+	u64 p_blkno;
+	int p_blocks;
+	int virtual, blocks, status, i, bytes_left;
+
+	bytes_left = i_size_read(inode) + 1;
+	/* we can't trust i_blocks because we're actually going to
+	 * write i_size + 1 bytes. */
+	blocks = (bytes_left + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
+
+	mlog_entry("i_blocks = %lu, i_size = %llu, blocks = %d\n",
+		       inode->i_blocks, i_size_read(inode), blocks);
+
+	/* Sanity check -- make sure we're going to fit. */
+	if (bytes_left >
+	    ocfs2_clusters_to_bytes(sb, OCFS2_I(inode)->ip_clusters)) {
+		status = -EIO;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	bhs = kcalloc(blocks, sizeof(struct buffer_head *), GFP_KERNEL);
+	if (!bhs) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_extent_map_get_blocks(inode, 0, 1, &p_blkno,
+					     &p_blocks);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* links can never be larger than one cluster so we know this
+	 * is all going to be contiguous, but do a sanity check
+	 * anyway. */
+	if ((p_blocks << sb->s_blocksize_bits) < bytes_left) {
+		status = -EIO;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	virtual = 0;
+	while(bytes_left > 0) {
+		c = &symname[virtual * sb->s_blocksize];
+
+		bhs[virtual] = sb_getblk(sb, p_blkno);
+		if (!bhs[virtual]) {
+			status = -ENOMEM;
+			mlog_errno(status);
+			goto bail;
+		}
+		ocfs2_set_new_buffer_uptodate(inode, bhs[virtual]);
+
+		status = ocfs2_journal_access(handle, inode, bhs[virtual],
+					      OCFS2_JOURNAL_ACCESS_CREATE);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		memset(bhs[virtual]->b_data, 0, sb->s_blocksize);
+
+		memcpy(bhs[virtual]->b_data, c,
+		       (bytes_left > sb->s_blocksize) ? sb->s_blocksize :
+		       bytes_left);
+
+		status = ocfs2_journal_dirty(handle, bhs[virtual]);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+
+		virtual++;
+		p_blkno++;
+		bytes_left -= sb->s_blocksize;
+	}
+
+	status = 0;
+bail:
+
+	if (bhs) {
+		for(i = 0; i < blocks; i++)
+			if (bhs[i])
+				brelse(bhs[i]);
+		kfree(bhs);
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_symlink(struct inode *dir,
+			 struct dentry *dentry,
+			 const char *symname)
+{
+	int status, l, credits;
+	u64 newsize;
+	struct ocfs2_super *osb = NULL;
+	struct inode *inode = NULL;
+	struct super_block *sb;
+	struct buffer_head *new_fe_bh = NULL;
+	struct buffer_head *de_bh = NULL;
+	struct buffer_head *parent_fe_bh = NULL;
+	struct ocfs2_dinode *fe = NULL;
+	struct ocfs2_dinode *dirfe;
+	struct ocfs2_journal_handle *handle = NULL;
+	struct ocfs2_alloc_context *inode_ac = NULL;
+	struct ocfs2_alloc_context *data_ac = NULL;
+
+	mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir,
+		   dentry, symname, dentry->d_name.len, dentry->d_name.name);
+
+	sb = dir->i_sb;
+	osb = OCFS2_SB(sb);
+
+	l = strlen(symname) + 1;
+
+	credits = ocfs2_calc_symlink_credits(sb);
+
+	handle = ocfs2_alloc_handle(osb);
+	if (handle == NULL) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/* lock the parent directory */
+	status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1);
+	if (status < 0) {
+		if (status != -ENOENT)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
+	if (!dirfe->i_links_count) {
+		/* can't make a file in a deleted directory. */
+		status = -ENOENT;
+		goto bail;
+	}
+
+	status = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
+					   dentry->d_name.len);
+	if (status)
+		goto bail;
+
+	status = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
+					      dentry->d_name.name,
+					      dentry->d_name.len, &de_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_reserve_new_inode(osb, handle, &inode_ac);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	/* don't reserve bitmap space for fast symlinks. */
+	if (l > ocfs2_fast_symlink_chars(sb)) {
+		status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac);
+		if (status < 0) {
+			if (status != -ENOSPC)
+				mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	handle = ocfs2_start_trans(osb, handle, credits);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_mknod_locked(osb, dir, dentry,
+				    S_IFLNK | S_IRWXUGO, 0,
+				    &new_fe_bh, parent_fe_bh, handle,
+				    &inode, inode_ac);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	fe = (struct ocfs2_dinode *) new_fe_bh->b_data;
+	inode->i_rdev = 0;
+	newsize = l - 1;
+	if (l > ocfs2_fast_symlink_chars(sb)) {
+		inode->i_op = &ocfs2_symlink_inode_operations;
+		status = ocfs2_do_extend_allocation(osb, inode, 1, new_fe_bh,
+						    handle, data_ac, NULL,
+						    NULL);
+		if (status < 0) {
+			if (status != -ENOSPC && status != -EINTR) {
+				mlog(ML_ERROR, "Failed to extend file to "
+					       "%"MLFu64"\n",
+				     newsize);
+				mlog_errno(status);
+				status = -ENOSPC;
+			}
+			goto bail;
+		}
+		i_size_write(inode, newsize);
+		inode->i_blocks = ocfs2_align_bytes_to_sectors(newsize);
+	} else {
+		inode->i_op = &ocfs2_fast_symlink_inode_operations;
+		memcpy((char *) fe->id2.i_symlink, symname, l);
+		i_size_write(inode, newsize);
+		inode->i_blocks = 0;
+	}
+
+	status = ocfs2_mark_inode_dirty(handle, inode, new_fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	if (!ocfs2_inode_is_fast_symlink(inode)) {
+		status = ocfs2_create_symlink_data(osb, handle, inode,
+						   symname);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	status = ocfs2_add_entry(handle, dentry, inode,
+				 le64_to_cpu(fe->i_blkno), parent_fe_bh,
+				 de_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	insert_inode_hash(inode);
+	dentry->d_op = &ocfs2_dentry_ops;
+	d_instantiate(dentry, inode);
+bail:
+	if (handle)
+		ocfs2_commit_trans(handle);
+	if (new_fe_bh)
+		brelse(new_fe_bh);
+	if (parent_fe_bh)
+		brelse(parent_fe_bh);
+	if (de_bh)
+		brelse(de_bh);
+	if (inode_ac)
+		ocfs2_free_alloc_context(inode_ac);
+	if (data_ac)
+		ocfs2_free_alloc_context(data_ac);
+	if ((status < 0) && inode)
+		iput(inode);
+
+	mlog_exit(status);
+
+	return status;
+}
+
+int ocfs2_check_dir_entry(struct inode * dir,
+			  struct ocfs2_dir_entry * de,
+			  struct buffer_head * bh,
+			  unsigned long offset)
+{
+	const char *error_msg = NULL;
+	const int rlen = le16_to_cpu(de->rec_len);
+
+	if (rlen < OCFS2_DIR_REC_LEN(1))
+		error_msg = "rec_len is smaller than minimal";
+	else if (rlen % 4 != 0)
+		error_msg = "rec_len % 4 != 0";
+	else if (rlen < OCFS2_DIR_REC_LEN(de->name_len))
+		error_msg = "rec_len is too small for name_len";
+	else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
+		error_msg = "directory entry across blocks";
+
+	if (error_msg != NULL)
+		mlog(ML_ERROR, "bad entry in directory #%"MLFu64": %s - "
+		     "offset=%lu, inode=%"MLFu64", rec_len=%d, name_len=%d\n",
+		     OCFS2_I(dir)->ip_blkno, error_msg, offset,
+		     le64_to_cpu(de->inode), rlen, de->name_len);
+	return error_msg == NULL ? 1 : 0;
+}
+
+/* we don't always have a dentry for what we want to add, so people
+ * like orphan dir can call this instead.
+ *
+ * If you pass me insert_bh, I'll skip the search of the other dir
+ * blocks and put the record in there.
+ */
+static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle,
+			     struct inode *dir,
+			     const char *name, int namelen,
+			     struct inode *inode, u64 blkno,
+			     struct buffer_head *parent_fe_bh,
+			     struct buffer_head *insert_bh)
+{
+	unsigned long offset;
+	unsigned short rec_len;
+	struct ocfs2_dir_entry *de, *de1;
+	struct super_block *sb;
+	int retval, status;
+
+	mlog_entry_void();
+
+	sb = dir->i_sb;
+
+	if (!namelen)
+		return -EINVAL;
+
+	rec_len = OCFS2_DIR_REC_LEN(namelen);
+	offset = 0;
+	de = (struct ocfs2_dir_entry *) insert_bh->b_data;
+	while (1) {
+		BUG_ON((char *)de >= sb->s_blocksize + insert_bh->b_data);
+		/* These checks should've already been passed by the
+		 * prepare function, but I guess we can leave them
+		 * here anyway. */
+		if (!ocfs2_check_dir_entry(dir, de, insert_bh, offset)) {
+			retval = -ENOENT;
+			goto bail;
+		}
+		if (ocfs2_match(namelen, name, de)) {
+			retval = -EEXIST;
+			goto bail;
+		}
+		if (((le64_to_cpu(de->inode) == 0) &&
+		     (le16_to_cpu(de->rec_len) >= rec_len)) ||
+		    (le16_to_cpu(de->rec_len) >=
+		     (OCFS2_DIR_REC_LEN(de->name_len) + rec_len))) {
+			status = ocfs2_journal_access(handle, dir, insert_bh,
+						      OCFS2_JOURNAL_ACCESS_WRITE);
+			/* By now the buffer is marked for journaling */
+			offset += le16_to_cpu(de->rec_len);
+			if (le64_to_cpu(de->inode)) {
+				de1 = (struct ocfs2_dir_entry *)((char *) de +
+					OCFS2_DIR_REC_LEN(de->name_len));
+				de1->rec_len =
+					cpu_to_le16(le16_to_cpu(de->rec_len) -
+					OCFS2_DIR_REC_LEN(de->name_len));
+				de->rec_len = cpu_to_le16(OCFS2_DIR_REC_LEN(de->name_len));
+				de = de1;
+			}
+			de->file_type = OCFS2_FT_UNKNOWN;
+			if (blkno) {
+				de->inode = cpu_to_le64(blkno);
+				ocfs2_set_de_type(de, inode->i_mode);
+			} else
+				de->inode = 0;
+			de->name_len = namelen;
+			memcpy(de->name, name, namelen);
+
+			dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+			dir->i_version++;
+			status = ocfs2_journal_dirty(handle, insert_bh);
+			retval = 0;
+			goto bail;
+		}
+		offset += le16_to_cpu(de->rec_len);
+		de = (struct ocfs2_dir_entry *) ((char *) de + le16_to_cpu(de->rec_len));
+	}
+
+	/* when you think about it, the assert above should prevent us
+	 * from ever getting here. */
+	retval = -ENOSPC;
+bail:
+
+	mlog_exit(retval);
+	return retval;
+}
+
+
+/*
+ * ocfs2_delete_entry deletes a directory entry by merging it with the
+ * previous entry
+ */
+static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle,
+			      struct inode *dir,
+			      struct ocfs2_dir_entry *de_del,
+			      struct buffer_head *bh)
+{
+	struct ocfs2_dir_entry *de, *pde;
+	int i, status = -ENOENT;
+
+	mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p)\n", handle, dir, de_del, bh);
+
+	i = 0;
+	pde = NULL;
+	de = (struct ocfs2_dir_entry *) bh->b_data;
+	while (i < bh->b_size) {
+		if (!ocfs2_check_dir_entry(dir, de, bh, i)) {
+			status = -EIO;
+			mlog_errno(status);
+			goto bail;
+		}
+		if (de == de_del)  {
+			status = ocfs2_journal_access(handle, dir, bh,
+						      OCFS2_JOURNAL_ACCESS_WRITE);
+			if (status < 0) {
+				status = -EIO;
+				mlog_errno(status);
+				goto bail;
+			}
+			if (pde)
+				pde->rec_len =
+					cpu_to_le16(le16_to_cpu(pde->rec_len) +
+						    le16_to_cpu(de->rec_len));
+			else
+				de->inode = 0;
+			dir->i_version++;
+			status = ocfs2_journal_dirty(handle, bh);
+			goto bail;
+		}
+		i += le16_to_cpu(de->rec_len);
+		pde = de;
+		de = (struct ocfs2_dir_entry *)((char *)de + le16_to_cpu(de->rec_len));
+	}
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * Returns 0 if not found, -1 on failure, and 1 on success
+ */
+static int inline ocfs2_search_dirblock(struct buffer_head *bh,
+					struct inode *dir,
+					const char *name, int namelen,
+					unsigned long offset,
+					struct ocfs2_dir_entry **res_dir)
+{
+	struct ocfs2_dir_entry *de;
+	char *dlimit, *de_buf;
+	int de_len;
+	int ret = 0;
+
+	mlog_entry_void();
+
+	de_buf = bh->b_data;
+	dlimit = de_buf + dir->i_sb->s_blocksize;
+
+	while (de_buf < dlimit) {
+		/* this code is executed quadratically often */
+		/* do minimal checking `by hand' */
+
+		de = (struct ocfs2_dir_entry *) de_buf;
+
+		if (de_buf + namelen <= dlimit &&
+		    ocfs2_match(namelen, name, de)) {
+			/* found a match - just to be sure, do a full check */
+			if (!ocfs2_check_dir_entry(dir, de, bh, offset)) {
+				ret = -1;
+				goto bail;
+			}
+			*res_dir = de;
+			ret = 1;
+			goto bail;
+		}
+
+		/* prevent looping on a bad block */
+		de_len = le16_to_cpu(de->rec_len);
+		if (de_len <= 0) {
+			ret = -1;
+			goto bail;
+		}
+
+		de_buf += de_len;
+		offset += de_len;
+	}
+
+bail:
+	mlog_exit(ret);
+	return ret;
+}
+
+struct buffer_head *ocfs2_find_entry(const char *name, int namelen,
+				     struct inode *dir,
+				     struct ocfs2_dir_entry **res_dir)
+{
+	struct super_block *sb;
+	struct buffer_head *bh_use[NAMEI_RA_SIZE];
+	struct buffer_head *bh, *ret = NULL;
+	unsigned long start, block, b;
+	int ra_max = 0;		/* Number of bh's in the readahead
+				   buffer, bh_use[] */
+	int ra_ptr = 0;		/* Current index into readahead
+				   buffer */
+	int num = 0;
+	int nblocks, i, err;
+
+	mlog_entry_void();
+
+	*res_dir = NULL;
+	sb = dir->i_sb;
+
+	nblocks = i_size_read(dir) >> sb->s_blocksize_bits;
+	start = OCFS2_I(dir)->ip_dir_start_lookup;
+	if (start >= nblocks)
+		start = 0;
+	block = start;
+
+restart:
+	do {
+		/*
+		 * We deal with the read-ahead logic here.
+		 */
+		if (ra_ptr >= ra_max) {
+			/* Refill the readahead buffer */
+			ra_ptr = 0;
+			b = block;
+			for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) {
+				/*
+				 * Terminate if we reach the end of the
+				 * directory and must wrap, or if our
+				 * search has finished at this block.
+				 */
+				if (b >= nblocks || (num && block == start)) {
+					bh_use[ra_max] = NULL;
+					break;
+				}
+				num++;
+
+				/* XXX: questionable readahead stuff here */
+				bh = ocfs2_bread(dir, b++, &err, 1);
+				bh_use[ra_max] = bh;
+#if 0		// ???
+				if (bh)
+					ll_rw_block(READ, 1, &bh);
+#endif
+			}
+		}
+		if ((bh = bh_use[ra_ptr++]) == NULL)
+			goto next;
+		wait_on_buffer(bh);
+		if (!buffer_uptodate(bh)) {
+			/* read error, skip block & hope for the best */
+			brelse(bh);
+			goto next;
+		}
+		i = ocfs2_search_dirblock(bh, dir, name, namelen,
+					  block << sb->s_blocksize_bits,
+					  res_dir);
+		if (i == 1) {
+			OCFS2_I(dir)->ip_dir_start_lookup = block;
+			ret = bh;
+			goto cleanup_and_exit;
+		} else {
+			brelse(bh);
+			if (i < 0)
+				goto cleanup_and_exit;
+		}
+	next:
+		if (++block >= nblocks)
+			block = 0;
+	} while (block != start);
+
+	/*
+	 * If the directory has grown while we were searching, then
+	 * search the last part of the directory before giving up.
+	 */
+	block = nblocks;
+	nblocks = i_size_read(dir) >> sb->s_blocksize_bits;
+	if (block < nblocks) {
+		start = 0;
+		goto restart;
+	}
+
+cleanup_and_exit:
+	/* Clean up the read-ahead blocks */
+	for (; ra_ptr < ra_max; ra_ptr++)
+		brelse(bh_use[ra_ptr]);
+
+	mlog_exit_ptr(ret);
+	return ret;
+}
+
+static int ocfs2_blkno_stringify(u64 blkno, char *name)
+{
+	int status, namelen;
+
+	mlog_entry_void();
+
+	namelen = snprintf(name, OCFS2_ORPHAN_NAMELEN + 1, "%016"MLFx64,
+			   blkno);
+	if (namelen <= 0) {
+		if (namelen)
+			status = namelen;
+		else
+			status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+	if (namelen != OCFS2_ORPHAN_NAMELEN) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	mlog(0, "built filename '%s' for orphan dir (len=%d)\n", name,
+	     namelen);
+
+	status = 0;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
+				    struct ocfs2_journal_handle *handle,
+				    struct inode *inode,
+				    char *name,
+				    struct buffer_head **de_bh)
+{
+	struct inode *orphan_dir_inode = NULL;
+	struct buffer_head *orphan_dir_bh = NULL;
+	int status = 0;
+
+	status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
+						       ORPHAN_DIR_SYSTEM_INODE,
+						       osb->slot_num);
+	if (!orphan_dir_inode) {
+		status = -ENOENT;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	ocfs2_handle_add_inode(handle, orphan_dir_inode);
+	status = ocfs2_meta_lock(orphan_dir_inode, handle, &orphan_dir_bh, 1);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_prepare_dir_for_insert(osb, orphan_dir_inode,
+					      orphan_dir_bh, name,
+					      OCFS2_ORPHAN_NAMELEN, de_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+leave:
+	if (orphan_dir_inode)
+		iput(orphan_dir_inode);
+
+	if (orphan_dir_bh)
+		brelse(orphan_dir_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_orphan_add(struct ocfs2_super *osb,
+			    struct ocfs2_journal_handle *handle,
+			    struct inode *inode,
+			    struct ocfs2_dinode *fe,
+			    char *name,
+			    struct buffer_head *de_bh)
+{
+	struct inode *orphan_dir_inode = NULL;
+	struct buffer_head *orphan_dir_bh = NULL;
+	int status = 0;
+	struct ocfs2_dinode *orphan_fe;
+
+	mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
+
+	orphan_dir_inode = ocfs2_get_system_file_inode(osb,
+						       ORPHAN_DIR_SYSTEM_INODE,
+						       osb->slot_num);
+	if (!orphan_dir_inode) {
+		status = -ENOENT;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_read_block(osb,
+				  OCFS2_I(orphan_dir_inode)->ip_blkno,
+				  &orphan_dir_bh, OCFS2_BH_CACHED,
+				  orphan_dir_inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_journal_access(handle, orphan_dir_inode, orphan_dir_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	/* we're a cluster, and nlink can change on disk from
+	 * underneath us... */
+	orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
+	if (S_ISDIR(inode->i_mode))
+		le16_add_cpu(&orphan_fe->i_links_count, 1);
+	orphan_dir_inode->i_nlink = le16_to_cpu(orphan_fe->i_links_count);
+
+	status = ocfs2_journal_dirty(handle, orphan_dir_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = __ocfs2_add_entry(handle, orphan_dir_inode, name,
+				   OCFS2_ORPHAN_NAMELEN, inode,
+				   OCFS2_I(inode)->ip_blkno,
+				   orphan_dir_bh, de_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	le32_add_cpu(&fe->i_flags, OCFS2_ORPHANED_FL);
+
+	/* Record which orphan dir our inode now resides
+	 * in. delete_inode will use this to determine which orphan
+	 * dir to lock. */
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	OCFS2_I(inode)->ip_orphaned_slot = osb->slot_num;
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	mlog(0, "Inode %"MLFu64" orphaned in slot %d\n",
+	     OCFS2_I(inode)->ip_blkno, osb->slot_num);
+
+leave:
+	if (orphan_dir_inode)
+		iput(orphan_dir_inode);
+
+	if (orphan_dir_bh)
+		brelse(orphan_dir_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+/* unlike orphan_add, we expect the orphan dir to already be locked here. */
+int ocfs2_orphan_del(struct ocfs2_super *osb,
+		     struct ocfs2_journal_handle *handle,
+		     struct inode *orphan_dir_inode,
+		     struct inode *inode,
+		     struct buffer_head *orphan_dir_bh)
+{
+	char name[OCFS2_ORPHAN_NAMELEN + 1];
+	struct ocfs2_dinode *orphan_fe;
+	int status = 0;
+	struct buffer_head *target_de_bh = NULL;
+	struct ocfs2_dir_entry *target_de = NULL;
+
+	mlog_entry_void();
+
+	status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	mlog(0, "removing '%s' from orphan dir %"MLFu64" (namelen=%d)\n",
+	     name, OCFS2_I(orphan_dir_inode)->ip_blkno, OCFS2_ORPHAN_NAMELEN);
+
+	/* find it's spot in the orphan directory */
+	target_de_bh = ocfs2_find_entry(name, OCFS2_ORPHAN_NAMELEN,
+					orphan_dir_inode, &target_de);
+	if (!target_de_bh) {
+		status = -ENOENT;
+		mlog_errno(status);
+		goto leave;
+	}
+
+	/* remove it from the orphan directory */
+	status = ocfs2_delete_entry(handle, orphan_dir_inode, target_de,
+				    target_de_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_journal_access(handle,orphan_dir_inode,  orphan_dir_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	/* do the i_nlink dance! :) */
+	orphan_fe = (struct ocfs2_dinode *) orphan_dir_bh->b_data;
+	if (S_ISDIR(inode->i_mode))
+		le16_add_cpu(&orphan_fe->i_links_count, -1);
+	orphan_dir_inode->i_nlink = le16_to_cpu(orphan_fe->i_links_count);
+
+	status = ocfs2_journal_dirty(handle, orphan_dir_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+leave:
+	if (target_de_bh)
+		brelse(target_de_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+struct inode_operations ocfs2_dir_iops = {
+	.create		= ocfs2_create,
+	.lookup		= ocfs2_lookup,
+	.link		= ocfs2_link,
+	.unlink		= ocfs2_unlink,
+	.rmdir		= ocfs2_unlink,
+	.symlink	= ocfs2_symlink,
+	.mkdir		= ocfs2_mkdir,
+	.mknod		= ocfs2_mknod,
+	.rename		= ocfs2_rename,
+	.setattr	= ocfs2_setattr,
+	.getattr	= ocfs2_getattr,
+};
diff --git a/fs/ocfs2/namei.h b/fs/ocfs2/namei.h
new file mode 100644
index 0000000..deaaa97
--- /dev/null
+++ b/fs/ocfs2/namei.h
@@ -0,0 +1,58 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * namei.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_NAMEI_H
+#define OCFS2_NAMEI_H
+
+extern struct inode_operations ocfs2_dir_iops;
+
+struct dentry *ocfs2_get_parent(struct dentry *child);
+
+int ocfs2_check_dir_entry (struct inode *dir,
+			   struct ocfs2_dir_entry *de,
+			   struct buffer_head *bh,
+			   unsigned long offset);
+struct buffer_head *ocfs2_find_entry(const char *name,
+				     int namelen,
+				     struct inode *dir,
+				     struct ocfs2_dir_entry **res_dir);
+int ocfs2_orphan_del(struct ocfs2_super *osb,
+		     struct ocfs2_journal_handle *handle,
+		     struct inode *orphan_dir_inode,
+		     struct inode *inode,
+		     struct buffer_head *orphan_dir_bh);
+
+static inline int ocfs2_match(int len,
+			      const char * const name,
+			      struct ocfs2_dir_entry *de)
+{
+	if (len != de->name_len)
+		return 0;
+	if (!de->inode)
+		return 0;
+	return !memcmp(name, de->name, len);
+}
+
+#endif /* OCFS2_NAMEI_H */
diff --git a/fs/ocfs2/ocfs1_fs_compat.h b/fs/ocfs2/ocfs1_fs_compat.h
new file mode 100644
index 0000000..0b499bc
--- /dev/null
+++ b/fs/ocfs2/ocfs1_fs_compat.h
@@ -0,0 +1,109 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ocfs1_fs_compat.h
+ *
+ * OCFS1 volume header definitions.  OCFS2 creates valid but unmountable
+ * OCFS1 volume headers on the first two sectors of an OCFS2 volume.
+ * This allows an OCFS1 volume to see the partition and cleanly fail to
+ * mount it.
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, 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 021110-1307, USA.
+ */
+
+#ifndef _OCFS1_FS_COMPAT_H
+#define _OCFS1_FS_COMPAT_H
+
+#define OCFS1_MAX_VOL_SIGNATURE_LEN          128
+#define OCFS1_MAX_MOUNT_POINT_LEN            128
+#define OCFS1_MAX_VOL_ID_LENGTH               16
+#define OCFS1_MAX_VOL_LABEL_LEN               64
+#define OCFS1_MAX_CLUSTER_NAME_LEN            64
+
+#define OCFS1_MAJOR_VERSION              (2)
+#define OCFS1_MINOR_VERSION              (0)
+#define OCFS1_VOLUME_SIGNATURE		 "OracleCFS"
+
+/*
+ * OCFS1 superblock.  Lives at sector 0.
+ */
+struct ocfs1_vol_disk_hdr
+{
+/*00*/	__u32 minor_version;
+	__u32 major_version;
+/*08*/	__u8 signature[OCFS1_MAX_VOL_SIGNATURE_LEN];
+/*88*/	__u8 mount_point[OCFS1_MAX_MOUNT_POINT_LEN];
+/*108*/	__u64 serial_num;
+/*110*/	__u64 device_size;
+	__u64 start_off;
+/*120*/	__u64 bitmap_off;
+	__u64 publ_off;
+/*130*/	__u64 vote_off;
+	__u64 root_bitmap_off;
+/*140*/	__u64 data_start_off;
+	__u64 root_bitmap_size;
+/*150*/	__u64 root_off;
+	__u64 root_size;
+/*160*/	__u64 cluster_size;
+	__u64 num_nodes;
+/*170*/	__u64 num_clusters;
+	__u64 dir_node_size;
+/*180*/	__u64 file_node_size;
+	__u64 internal_off;
+/*190*/	__u64 node_cfg_off;
+	__u64 node_cfg_size;
+/*1A0*/	__u64 new_cfg_off;
+	__u32 prot_bits;
+	__s32 excl_mount;
+/*1B0*/
+};
+
+
+struct ocfs1_disk_lock
+{
+/*00*/	__u32 curr_master;
+	__u8 file_lock;
+	__u8 compat_pad[3];  /* Not in orignal definition.  Used to
+				make the already existing alignment
+				explicit */
+	__u64 last_write_time;
+/*10*/	__u64 last_read_time;
+	__u32 writer_node_num;
+	__u32 reader_node_num;
+/*20*/	__u64 oin_node_map;
+	__u64 dlock_seq_num;
+/*30*/
+};
+
+/*
+ * OCFS1 volume label.  Lives at sector 1.
+ */
+struct ocfs1_vol_label
+{
+/*00*/	struct ocfs1_disk_lock disk_lock;
+/*30*/	__u8 label[OCFS1_MAX_VOL_LABEL_LEN];
+/*70*/	__u16 label_len;
+/*72*/	__u8 vol_id[OCFS1_MAX_VOL_ID_LENGTH];
+/*82*/	__u16 vol_id_len;
+/*84*/	__u8 cluster_name[OCFS1_MAX_CLUSTER_NAME_LEN];
+/*A4*/	__u16 cluster_name_len;
+/*A6*/
+};
+
+
+#endif /* _OCFS1_FS_COMPAT_H */
+
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
new file mode 100644
index 0000000..f468c60
--- /dev/null
+++ b/fs/ocfs2/ocfs2.h
@@ -0,0 +1,464 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ocfs2.h
+ *
+ * Defines macros and structures used in OCFS2
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_H
+#define OCFS2_H
+
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/rbtree.h>
+#include <linux/workqueue.h>
+#include <linux/kref.h>
+
+#include "cluster/nodemanager.h"
+#include "cluster/heartbeat.h"
+#include "cluster/tcp.h"
+
+#include "dlm/dlmapi.h"
+
+#include "ocfs2_fs.h"
+#include "endian.h"
+#include "ocfs2_lockid.h"
+
+struct ocfs2_extent_map {
+	u32		em_clusters;
+	struct rb_root	em_extents;
+};
+
+/* Most user visible OCFS2 inodes will have very few pieces of
+ * metadata, but larger files (including bitmaps, etc) must be taken
+ * into account when designing an access scheme. We allow a small
+ * amount of inlined blocks to be stored on an array and grow the
+ * structure into a rb tree when necessary. */
+#define OCFS2_INODE_MAX_CACHE_ARRAY 2
+
+struct ocfs2_caching_info {
+	unsigned int		ci_num_cached;
+	union {
+		sector_t	ci_array[OCFS2_INODE_MAX_CACHE_ARRAY];
+		struct rb_root	ci_tree;
+	} ci_cache;
+};
+
+/* this limits us to 256 nodes
+ * if we need more, we can do a kmalloc for the map */
+#define OCFS2_NODE_MAP_MAX_NODES    256
+struct ocfs2_node_map {
+	u16 num_nodes;
+	unsigned long map[BITS_TO_LONGS(OCFS2_NODE_MAP_MAX_NODES)];
+};
+
+enum ocfs2_ast_action {
+	OCFS2_AST_INVALID = 0,
+	OCFS2_AST_ATTACH,
+	OCFS2_AST_CONVERT,
+	OCFS2_AST_DOWNCONVERT,
+};
+
+/* actions for an unlockast function to take. */
+enum ocfs2_unlock_action {
+	OCFS2_UNLOCK_INVALID = 0,
+	OCFS2_UNLOCK_CANCEL_CONVERT,
+	OCFS2_UNLOCK_DROP_LOCK,
+};
+
+/* ocfs2_lock_res->l_flags flags. */
+#define OCFS2_LOCK_ATTACHED      (0x00000001) /* have we initialized
+					       * the lvb */
+#define OCFS2_LOCK_BUSY          (0x00000002) /* we are currently in
+					       * dlm_lock */
+#define OCFS2_LOCK_BLOCKED       (0x00000004) /* blocked waiting to
+					       * downconvert*/
+#define OCFS2_LOCK_LOCAL         (0x00000008) /* newly created inode */
+#define OCFS2_LOCK_NEEDS_REFRESH (0x00000010)
+#define OCFS2_LOCK_REFRESHING    (0x00000020)
+#define OCFS2_LOCK_INITIALIZED   (0x00000040) /* track initialization
+					       * for shutdown paths */
+#define OCFS2_LOCK_FREEING       (0x00000080) /* help dlmglue track
+					       * when to skip queueing
+					       * a lock because it's
+					       * about to be
+					       * dropped. */
+#define OCFS2_LOCK_QUEUED        (0x00000100) /* queued for downconvert */
+
+struct ocfs2_lock_res_ops;
+
+typedef void (*ocfs2_lock_callback)(int status, unsigned long data);
+
+struct ocfs2_lock_res {
+	void                    *l_priv;
+	struct ocfs2_lock_res_ops *l_ops;
+	spinlock_t               l_lock;
+
+	struct list_head         l_blocked_list;
+	struct list_head         l_mask_waiters;
+
+	enum ocfs2_lock_type     l_type;
+	unsigned long		 l_flags;
+	char                     l_name[OCFS2_LOCK_ID_MAX_LEN];
+	int                      l_level;
+	unsigned int             l_ro_holders;
+	unsigned int             l_ex_holders;
+	struct dlm_lockstatus    l_lksb;
+
+	/* used from AST/BAST funcs. */
+	enum ocfs2_ast_action    l_action;
+	enum ocfs2_unlock_action l_unlock_action;
+	int                      l_requested;
+	int                      l_blocking;
+
+	wait_queue_head_t        l_event;
+
+	struct list_head         l_debug_list;
+};
+
+struct ocfs2_dlm_debug {
+	struct kref d_refcnt;
+	struct dentry *d_locking_state;
+	struct list_head d_lockres_tracking;
+};
+
+enum ocfs2_vol_state
+{
+	VOLUME_INIT = 0,
+	VOLUME_MOUNTED,
+	VOLUME_DISMOUNTED,
+	VOLUME_DISABLED
+};
+
+struct ocfs2_alloc_stats
+{
+	atomic_t moves;
+	atomic_t local_data;
+	atomic_t bitmap_data;
+	atomic_t bg_allocs;
+	atomic_t bg_extends;
+};
+
+enum ocfs2_local_alloc_state
+{
+	OCFS2_LA_UNUSED = 0,
+	OCFS2_LA_ENABLED,
+	OCFS2_LA_DISABLED
+};
+
+enum ocfs2_mount_options
+{
+	OCFS2_MOUNT_HB_LOCAL   = 1 << 0, /* Heartbeat started in local mode */
+	OCFS2_MOUNT_BARRIER = 1 << 1,	/* Use block barriers */
+	OCFS2_MOUNT_NOINTR  = 1 << 2,   /* Don't catch signals */
+	OCFS2_MOUNT_ERRORS_PANIC = 1 << 3, /* Panic on errors */
+	OCFS2_MOUNT_DATA_WRITEBACK = 1 << 4, /* No data ordering */
+#ifdef OCFS2_ORACORE_WORKAROUNDS
+	OCFS2_MOUNT_COMPAT_OCFS = 1 << 30, /* ocfs1 compatibility mode */
+#endif
+};
+
+#define OCFS2_OSB_SOFT_RO	0x0001
+#define OCFS2_OSB_HARD_RO	0x0002
+#define OCFS2_OSB_ERROR_FS	0x0004
+
+struct ocfs2_journal;
+struct ocfs2_journal_handle;
+struct ocfs2_super
+{
+	u32 osb_id;		/* id used by the proc interface */
+	struct task_struct *commit_task;
+	struct super_block *sb;
+	struct inode *root_inode;
+	struct inode *sys_root_inode;
+	struct inode *system_inodes[NUM_SYSTEM_INODES];
+
+	struct ocfs2_slot_info *slot_info;
+
+	spinlock_t node_map_lock;
+	struct ocfs2_node_map mounted_map;
+	struct ocfs2_node_map recovery_map;
+	struct ocfs2_node_map umount_map;
+
+	u32 num_clusters;
+	u64 root_blkno;
+	u64 system_dir_blkno;
+	u64 bitmap_blkno;
+	u32 bitmap_cpg;
+	u8 *uuid;
+	char *uuid_str;
+	u8 *vol_label;
+	u64 first_cluster_group_blkno;
+	u32 fs_generation;
+
+	u32 s_feature_compat;
+	u32 s_feature_incompat;
+	u32 s_feature_ro_compat;
+
+	/* Protects s_next_generaion, osb_flags. Could protect more on
+	 * osb as it's very short lived. */
+	spinlock_t osb_lock;
+	u32 s_next_generation;
+	unsigned long osb_flags;
+
+	unsigned long s_mount_opt;
+
+	u16 max_slots;
+	u16 num_nodes;
+	s16 node_num;
+	s16 slot_num;
+	int s_sectsize_bits;
+	int s_clustersize;
+	int s_clustersize_bits;
+	struct proc_dir_entry *proc_sub_dir; /* points to /proc/fs/ocfs2/<maj_min> */
+
+	atomic_t vol_state;
+	struct semaphore recovery_lock;
+	struct task_struct *recovery_thread_task;
+	int disable_recovery;
+	wait_queue_head_t checkpoint_event;
+	atomic_t needs_checkpoint;
+	struct ocfs2_journal *journal;
+
+	enum ocfs2_local_alloc_state local_alloc_state;
+	struct buffer_head *local_alloc_bh;
+
+	/* Next two fields are for local node slot recovery during
+	 * mount. */
+	int dirty;
+	struct ocfs2_dinode *local_alloc_copy;
+
+	struct ocfs2_alloc_stats alloc_stats;
+	char dev_str[20];		/* "major,minor" of the device */
+
+	struct dlm_ctxt *dlm;
+	struct ocfs2_lock_res osb_super_lockres;
+	struct ocfs2_lock_res osb_rename_lockres;
+	struct dlm_eviction_cb osb_eviction_cb;
+	struct ocfs2_dlm_debug *osb_dlm_debug;
+
+	struct dentry *osb_debug_root;
+
+	wait_queue_head_t recovery_event;
+
+	spinlock_t vote_task_lock;
+	struct task_struct *vote_task;
+	wait_queue_head_t vote_event;
+	unsigned long vote_wake_sequence;
+	unsigned long vote_work_sequence;
+
+	struct list_head blocked_lock_list;
+	unsigned long blocked_lock_count;
+
+	struct list_head vote_list;
+	int vote_count;
+
+	u32 net_key;
+	spinlock_t net_response_lock;
+	unsigned int net_response_ids;
+	struct list_head net_response_list;
+
+	struct o2hb_callback_func osb_hb_up;
+	struct o2hb_callback_func osb_hb_down;
+
+	struct list_head	osb_net_handlers;
+
+	wait_queue_head_t		osb_mount_event;
+
+	/* Truncate log info */
+	struct inode			*osb_tl_inode;
+	struct buffer_head		*osb_tl_bh;
+	struct work_struct		osb_truncate_log_wq;
+};
+
+#define OCFS2_SB(sb)	    ((struct ocfs2_super *)(sb)->s_fs_info)
+#define OCFS2_MAX_OSB_ID             65536
+
+static inline int ocfs2_should_order_data(struct inode *inode)
+{
+	if (!S_ISREG(inode->i_mode))
+		return 0;
+	if (OCFS2_SB(inode->i_sb)->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK)
+		return 0;
+	return 1;
+}
+
+/* set / clear functions because cluster events can make these happen
+ * in parallel so we want the transitions to be atomic. this also
+ * means that any future flags osb_flags must be protected by spinlock
+ * too! */
+static inline void ocfs2_set_osb_flag(struct ocfs2_super *osb,
+				      unsigned long flag)
+{
+	spin_lock(&osb->osb_lock);
+	osb->osb_flags |= flag;
+	spin_unlock(&osb->osb_lock);
+}
+
+static inline void ocfs2_set_ro_flag(struct ocfs2_super *osb,
+				     int hard)
+{
+	spin_lock(&osb->osb_lock);
+	osb->osb_flags &= ~(OCFS2_OSB_SOFT_RO|OCFS2_OSB_HARD_RO);
+	if (hard)
+		osb->osb_flags |= OCFS2_OSB_HARD_RO;
+	else
+		osb->osb_flags |= OCFS2_OSB_SOFT_RO;
+	spin_unlock(&osb->osb_lock);
+}
+
+static inline int ocfs2_is_hard_readonly(struct ocfs2_super *osb)
+{
+	int ret;
+
+	spin_lock(&osb->osb_lock);
+	ret = osb->osb_flags & OCFS2_OSB_HARD_RO;
+	spin_unlock(&osb->osb_lock);
+
+	return ret;
+}
+
+static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb)
+{
+	int ret;
+
+	spin_lock(&osb->osb_lock);
+	ret = osb->osb_flags & OCFS2_OSB_SOFT_RO;
+	spin_unlock(&osb->osb_lock);
+
+	return ret;
+}
+
+#define OCFS2_IS_VALID_DINODE(ptr)					\
+	(!strcmp((ptr)->i_signature, OCFS2_INODE_SIGNATURE))
+
+#define OCFS2_RO_ON_INVALID_DINODE(__sb, __di)	do {			\
+	typeof(__di) ____di = (__di);					\
+	ocfs2_error((__sb), 						\
+		"Dinode # %"MLFu64" has bad signature %.*s",		\
+		(____di)->i_blkno, 7,					\
+		(____di)->i_signature);					\
+} while (0);
+
+#define OCFS2_IS_VALID_EXTENT_BLOCK(ptr)				\
+	(!strcmp((ptr)->h_signature, OCFS2_EXTENT_BLOCK_SIGNATURE))
+
+#define OCFS2_RO_ON_INVALID_EXTENT_BLOCK(__sb, __eb)	do {		\
+	typeof(__eb) ____eb = (__eb);					\
+	ocfs2_error((__sb), 						\
+		"Extent Block # %"MLFu64" has bad signature %.*s",	\
+		(____eb)->h_blkno, 7,					\
+		(____eb)->h_signature);					\
+} while (0);
+
+#define OCFS2_IS_VALID_GROUP_DESC(ptr)					\
+	(!strcmp((ptr)->bg_signature, OCFS2_GROUP_DESC_SIGNATURE))
+
+#define OCFS2_RO_ON_INVALID_GROUP_DESC(__sb, __gd)	do {		\
+	typeof(__gd) ____gd = (__gd);					\
+		ocfs2_error((__sb),					\
+		"Group Descriptor # %"MLFu64" has bad signature %.*s",	\
+		(____gd)->bg_blkno, 7,					\
+		(____gd)->bg_signature);				\
+} while (0);
+
+static inline unsigned long ino_from_blkno(struct super_block *sb,
+					   u64 blkno)
+{
+	return (unsigned long)(blkno & (u64)ULONG_MAX);
+}
+
+static inline u64 ocfs2_clusters_to_blocks(struct super_block *sb,
+					   u32 clusters)
+{
+	int c_to_b_bits = OCFS2_SB(sb)->s_clustersize_bits -
+		sb->s_blocksize_bits;
+
+	return (u64)clusters << c_to_b_bits;
+}
+
+static inline u32 ocfs2_blocks_to_clusters(struct super_block *sb,
+					   u64 blocks)
+{
+	int b_to_c_bits = OCFS2_SB(sb)->s_clustersize_bits -
+		sb->s_blocksize_bits;
+
+	return (u32)(blocks >> b_to_c_bits);
+}
+
+static inline unsigned int ocfs2_clusters_for_bytes(struct super_block *sb,
+						    u64 bytes)
+{
+	int cl_bits = OCFS2_SB(sb)->s_clustersize_bits;
+	unsigned int clusters;
+
+	bytes += OCFS2_SB(sb)->s_clustersize - 1;
+	/* OCFS2 just cannot have enough clusters to overflow this */
+	clusters = (unsigned int)(bytes >> cl_bits);
+
+	return clusters;
+}
+
+static inline u64 ocfs2_blocks_for_bytes(struct super_block *sb,
+					 u64 bytes)
+{
+	bytes += sb->s_blocksize - 1;
+	return bytes >> sb->s_blocksize_bits;
+}
+
+static inline u64 ocfs2_clusters_to_bytes(struct super_block *sb,
+					  u32 clusters)
+{
+	return (u64)clusters << OCFS2_SB(sb)->s_clustersize_bits;
+}
+
+static inline u64 ocfs2_align_bytes_to_clusters(struct super_block *sb,
+						u64 bytes)
+{
+	int cl_bits = OCFS2_SB(sb)->s_clustersize_bits;
+	unsigned int clusters;
+
+	clusters = ocfs2_clusters_for_bytes(sb, bytes);
+	return (u64)clusters << cl_bits;
+}
+
+static inline u64 ocfs2_align_bytes_to_blocks(struct super_block *sb,
+					      u64 bytes)
+{
+	u64 blocks;
+
+        blocks = ocfs2_blocks_for_bytes(sb, bytes);
+	return blocks << sb->s_blocksize_bits;
+}
+
+static inline unsigned long ocfs2_align_bytes_to_sectors(u64 bytes)
+{
+	return (unsigned long)((bytes + 511) >> 9);
+}
+
+#define ocfs2_set_bit ext2_set_bit
+#define ocfs2_clear_bit ext2_clear_bit
+#define ocfs2_test_bit ext2_test_bit
+#define ocfs2_find_next_zero_bit ext2_find_next_zero_bit
+#endif  /* OCFS2_H */
+
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
new file mode 100644
index 0000000..dfb8a5b
--- /dev/null
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -0,0 +1,638 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ocfs2_fs.h
+ *
+ * On-disk structures for OCFS2.
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, 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 021110-1307, USA.
+ */
+
+#ifndef _OCFS2_FS_H
+#define _OCFS2_FS_H
+
+/* Version */
+#define OCFS2_MAJOR_REV_LEVEL		0
+#define OCFS2_MINOR_REV_LEVEL          	90
+
+/*
+ * An OCFS2 volume starts this way:
+ * Sector 0: Valid ocfs1_vol_disk_hdr that cleanly fails to mount OCFS.
+ * Sector 1: Valid ocfs1_vol_label that cleanly fails to mount OCFS.
+ * Block OCFS2_SUPER_BLOCK_BLKNO: OCFS2 superblock.
+ *
+ * All other structures are found from the superblock information.
+ *
+ * OCFS2_SUPER_BLOCK_BLKNO is in blocks, not sectors.  eg, for a
+ * blocksize of 2K, it is 4096 bytes into disk.
+ */
+#define OCFS2_SUPER_BLOCK_BLKNO		2
+
+/*
+ * Cluster size limits. The maximum is kept arbitrarily at 1 MB, and could
+ * grow if needed.
+ */
+#define OCFS2_MIN_CLUSTERSIZE		4096
+#define OCFS2_MAX_CLUSTERSIZE		1048576
+
+/*
+ * Blocks cannot be bigger than clusters, so the maximum blocksize is the
+ * minimum cluster size.
+ */
+#define OCFS2_MIN_BLOCKSIZE		512
+#define OCFS2_MAX_BLOCKSIZE		OCFS2_MIN_CLUSTERSIZE
+
+/* Filesystem magic number */
+#define OCFS2_SUPER_MAGIC		0x7461636f
+
+/* Object signatures */
+#define OCFS2_SUPER_BLOCK_SIGNATURE	"OCFSV2"
+#define OCFS2_INODE_SIGNATURE		"INODE01"
+#define OCFS2_EXTENT_BLOCK_SIGNATURE	"EXBLK01"
+#define OCFS2_GROUP_DESC_SIGNATURE      "GROUP01"
+
+/* Compatibility flags */
+#define OCFS2_HAS_COMPAT_FEATURE(sb,mask)			\
+	( OCFS2_SB(sb)->s_feature_compat & (mask) )
+#define OCFS2_HAS_RO_COMPAT_FEATURE(sb,mask)			\
+	( OCFS2_SB(sb)->s_feature_ro_compat & (mask) )
+#define OCFS2_HAS_INCOMPAT_FEATURE(sb,mask)			\
+	( OCFS2_SB(sb)->s_feature_incompat & (mask) )
+#define OCFS2_SET_COMPAT_FEATURE(sb,mask)			\
+	OCFS2_SB(sb)->s_feature_compat |= (mask)
+#define OCFS2_SET_RO_COMPAT_FEATURE(sb,mask)			\
+	OCFS2_SB(sb)->s_feature_ro_compat |= (mask)
+#define OCFS2_SET_INCOMPAT_FEATURE(sb,mask)			\
+	OCFS2_SB(sb)->s_feature_incompat |= (mask)
+#define OCFS2_CLEAR_COMPAT_FEATURE(sb,mask)			\
+	OCFS2_SB(sb)->s_feature_compat &= ~(mask)
+#define OCFS2_CLEAR_RO_COMPAT_FEATURE(sb,mask)			\
+	OCFS2_SB(sb)->s_feature_ro_compat &= ~(mask)
+#define OCFS2_CLEAR_INCOMPAT_FEATURE(sb,mask)			\
+	OCFS2_SB(sb)->s_feature_incompat &= ~(mask)
+
+#define OCFS2_FEATURE_COMPAT_SUPP	0
+#define OCFS2_FEATURE_INCOMPAT_SUPP	0
+#define OCFS2_FEATURE_RO_COMPAT_SUPP	0
+
+/*
+ * Heartbeat-only devices are missing journals and other files.  The
+ * filesystem driver can't load them, but the library can.  Never put
+ * this in OCFS2_FEATURE_INCOMPAT_SUPP, *ever*.
+ */
+#define OCFS2_FEATURE_INCOMPAT_HEARTBEAT_DEV	0x0002
+
+
+/*
+ * Flags on ocfs2_dinode.i_flags
+ */
+#define OCFS2_VALID_FL		(0x00000001)	/* Inode is valid */
+#define OCFS2_UNUSED2_FL	(0x00000002)
+#define OCFS2_ORPHANED_FL	(0x00000004)	/* On the orphan list */
+#define OCFS2_UNUSED3_FL	(0x00000008)
+/* System inode flags */
+#define OCFS2_SYSTEM_FL		(0x00000010)	/* System inode */
+#define OCFS2_SUPER_BLOCK_FL	(0x00000020)	/* Super block */
+#define OCFS2_LOCAL_ALLOC_FL	(0x00000040)	/* Slot local alloc bitmap */
+#define OCFS2_BITMAP_FL		(0x00000080)	/* Allocation bitmap */
+#define OCFS2_JOURNAL_FL	(0x00000100)	/* Slot local journal */
+#define OCFS2_HEARTBEAT_FL	(0x00000200)	/* Heartbeat area */
+#define OCFS2_CHAIN_FL		(0x00000400)	/* Chain allocator */
+#define OCFS2_DEALLOC_FL	(0x00000800)	/* Truncate log */
+
+/*
+ * Journal Flags (ocfs2_dinode.id1.journal1.i_flags)
+ */
+#define OCFS2_JOURNAL_DIRTY_FL	(0x00000001)	/* Journal needs recovery */
+
+/*
+ * superblock s_state flags
+ */
+#define OCFS2_ERROR_FS		(0x00000001)	/* FS saw errors */
+
+/* Limit of space in ocfs2_dir_entry */
+#define OCFS2_MAX_FILENAME_LEN		255
+
+/* Maximum slots on an ocfs2 file system */
+#define OCFS2_MAX_SLOTS			255
+
+/* Slot map indicator for an empty slot */
+#define OCFS2_INVALID_SLOT		-1
+
+#define OCFS2_VOL_UUID_LEN		16
+#define OCFS2_MAX_VOL_LABEL_LEN		64
+
+/* Journal limits (in bytes) */
+#define OCFS2_MIN_JOURNAL_SIZE		(4 * 1024 * 1024)
+#define OCFS2_MAX_JOURNAL_SIZE		(500 * 1024 * 1024)
+
+struct ocfs2_system_inode_info {
+	char	*si_name;
+	int	si_iflags;
+	int	si_mode;
+};
+
+/* System file index */
+enum {
+	BAD_BLOCK_SYSTEM_INODE = 0,
+	GLOBAL_INODE_ALLOC_SYSTEM_INODE,
+	SLOT_MAP_SYSTEM_INODE,
+#define OCFS2_FIRST_ONLINE_SYSTEM_INODE SLOT_MAP_SYSTEM_INODE
+	HEARTBEAT_SYSTEM_INODE,
+	GLOBAL_BITMAP_SYSTEM_INODE,
+#define OCFS2_LAST_GLOBAL_SYSTEM_INODE GLOBAL_BITMAP_SYSTEM_INODE
+	ORPHAN_DIR_SYSTEM_INODE,
+	EXTENT_ALLOC_SYSTEM_INODE,
+	INODE_ALLOC_SYSTEM_INODE,
+	JOURNAL_SYSTEM_INODE,
+	LOCAL_ALLOC_SYSTEM_INODE,
+	TRUNCATE_LOG_SYSTEM_INODE,
+	NUM_SYSTEM_INODES
+};
+
+static struct ocfs2_system_inode_info ocfs2_system_inodes[NUM_SYSTEM_INODES] = {
+	/* Global system inodes (single copy) */
+	/* The first two are only used from userspace mfks/tunefs */
+	[BAD_BLOCK_SYSTEM_INODE]		= { "bad_blocks", 0, S_IFREG | 0644 },
+	[GLOBAL_INODE_ALLOC_SYSTEM_INODE] 	= { "global_inode_alloc", OCFS2_BITMAP_FL | OCFS2_CHAIN_FL, S_IFREG | 0644 },
+
+	/* These are used by the running filesystem */
+	[SLOT_MAP_SYSTEM_INODE]			= { "slot_map", 0, S_IFREG | 0644 },
+	[HEARTBEAT_SYSTEM_INODE]		= { "heartbeat", OCFS2_HEARTBEAT_FL, S_IFREG | 0644 },
+	[GLOBAL_BITMAP_SYSTEM_INODE]		= { "global_bitmap", 0, S_IFREG | 0644 },
+
+	/* Slot-specific system inodes (one copy per slot) */
+	[ORPHAN_DIR_SYSTEM_INODE]		= { "orphan_dir:%04d", 0, S_IFDIR | 0755 },
+	[EXTENT_ALLOC_SYSTEM_INODE]		= { "extent_alloc:%04d", OCFS2_BITMAP_FL | OCFS2_CHAIN_FL, S_IFREG | 0644 },
+	[INODE_ALLOC_SYSTEM_INODE]		= { "inode_alloc:%04d", OCFS2_BITMAP_FL | OCFS2_CHAIN_FL, S_IFREG | 0644 },
+	[JOURNAL_SYSTEM_INODE]			= { "journal:%04d", OCFS2_JOURNAL_FL, S_IFREG | 0644 },
+	[LOCAL_ALLOC_SYSTEM_INODE]		= { "local_alloc:%04d", OCFS2_BITMAP_FL | OCFS2_LOCAL_ALLOC_FL, S_IFREG | 0644 },
+	[TRUNCATE_LOG_SYSTEM_INODE]		= { "truncate_log:%04d", OCFS2_DEALLOC_FL, S_IFREG | 0644 }
+};
+
+/* Parameter passed from mount.ocfs2 to module */
+#define OCFS2_HB_NONE			"heartbeat=none"
+#define OCFS2_HB_LOCAL			"heartbeat=local"
+
+/*
+ * OCFS2 directory file types.  Only the low 3 bits are used.  The
+ * other bits are reserved for now.
+ */
+#define OCFS2_FT_UNKNOWN	0
+#define OCFS2_FT_REG_FILE	1
+#define OCFS2_FT_DIR		2
+#define OCFS2_FT_CHRDEV		3
+#define OCFS2_FT_BLKDEV		4
+#define OCFS2_FT_FIFO		5
+#define OCFS2_FT_SOCK		6
+#define OCFS2_FT_SYMLINK	7
+
+#define OCFS2_FT_MAX		8
+
+/*
+ * OCFS2_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define OCFS2_DIR_PAD			4
+#define OCFS2_DIR_ROUND			(OCFS2_DIR_PAD - 1)
+#define OCFS2_DIR_MEMBER_LEN 		offsetof(struct ocfs2_dir_entry, name)
+#define OCFS2_DIR_REC_LEN(name_len)	(((name_len) + OCFS2_DIR_MEMBER_LEN + \
+                                          OCFS2_DIR_ROUND) & \
+					 ~OCFS2_DIR_ROUND)
+
+#define OCFS2_LINK_MAX		32000
+
+#define S_SHIFT			12
+static unsigned char ocfs2_type_by_mode[S_IFMT >> S_SHIFT] = {
+	[S_IFREG >> S_SHIFT]  = OCFS2_FT_REG_FILE,
+	[S_IFDIR >> S_SHIFT]  = OCFS2_FT_DIR,
+	[S_IFCHR >> S_SHIFT]  = OCFS2_FT_CHRDEV,
+	[S_IFBLK >> S_SHIFT]  = OCFS2_FT_BLKDEV,
+	[S_IFIFO >> S_SHIFT]  = OCFS2_FT_FIFO,
+	[S_IFSOCK >> S_SHIFT] = OCFS2_FT_SOCK,
+	[S_IFLNK >> S_SHIFT]  = OCFS2_FT_SYMLINK,
+};
+
+
+/*
+ * Convenience casts
+ */
+#define OCFS2_RAW_SB(dinode)		(&((dinode)->id2.i_super))
+
+/*
+ * On disk extent record for OCFS2
+ * It describes a range of clusters on disk.
+ */
+struct ocfs2_extent_rec {
+/*00*/	__le32 e_cpos;		/* Offset into the file, in clusters */
+	__le32 e_clusters;	/* Clusters covered by this extent */
+	__le64 e_blkno;		/* Physical disk offset, in blocks */
+/*10*/
+};
+
+struct ocfs2_chain_rec {
+	__le32 c_free;	/* Number of free bits in this chain. */
+	__le32 c_total;	/* Number of total bits in this chain */
+	__le64 c_blkno;	/* Physical disk offset (blocks) of 1st group */
+};
+
+struct ocfs2_truncate_rec {
+	__le32 t_start;		/* 1st cluster in this log */
+	__le32 t_clusters;	/* Number of total clusters covered */
+};
+
+/*
+ * On disk extent list for OCFS2 (node in the tree).  Note that this
+ * is contained inside ocfs2_dinode or ocfs2_extent_block, so the
+ * offsets are relative to ocfs2_dinode.id2.i_list or
+ * ocfs2_extent_block.h_list, respectively.
+ */
+struct ocfs2_extent_list {
+/*00*/	__le16 l_tree_depth;		/* Extent tree depth from this
+					   point.  0 means data extents
+					   hang directly off this
+					   header (a leaf) */
+	__le16 l_count;			/* Number of extent records */
+	__le16 l_next_free_rec;		/* Next unused extent slot */
+	__le16 l_reserved1;
+	__le64 l_reserved2;		/* Pad to
+					   sizeof(ocfs2_extent_rec) */
+/*10*/	struct ocfs2_extent_rec l_recs[0];	/* Extent records */
+};
+
+/*
+ * On disk allocation chain list for OCFS2.  Note that this is
+ * contained inside ocfs2_dinode, so the offsets are relative to
+ * ocfs2_dinode.id2.i_chain.
+ */
+struct ocfs2_chain_list {
+/*00*/	__le16 cl_cpg;			/* Clusters per Block Group */
+	__le16 cl_bpc;			/* Bits per cluster */
+	__le16 cl_count;		/* Total chains in this list */
+	__le16 cl_next_free_rec;	/* Next unused chain slot */
+	__le64 cl_reserved1;
+/*10*/	struct ocfs2_chain_rec cl_recs[0];	/* Chain records */
+};
+
+/*
+ * On disk deallocation log for OCFS2.  Note that this is
+ * contained inside ocfs2_dinode, so the offsets are relative to
+ * ocfs2_dinode.id2.i_dealloc.
+ */
+struct ocfs2_truncate_log {
+/*00*/	__le16 tl_count;		/* Total records in this log */
+	__le16 tl_used;			/* Number of records in use */
+	__le32 tl_reserved1;
+/*08*/	struct ocfs2_truncate_rec tl_recs[0];	/* Truncate records */
+};
+
+/*
+ * On disk extent block (indirect block) for OCFS2
+ */
+struct ocfs2_extent_block
+{
+/*00*/	__u8 h_signature[8];		/* Signature for verification */
+	__le64 h_reserved1;
+/*10*/	__le16 h_suballoc_slot;		/* Slot suballocator this
+					   extent_header belongs to */
+	__le16 h_suballoc_bit;		/* Bit offset in suballocator
+					   block group */
+	__le32 h_fs_generation;		/* Must match super block */
+	__le64 h_blkno;			/* Offset on disk, in blocks */
+/*20*/	__le64 h_reserved3;
+	__le64 h_next_leaf_blk;		/* Offset on disk, in blocks,
+					   of next leaf header pointing
+					   to data */
+/*30*/	struct ocfs2_extent_list h_list;	/* Extent record list */
+/* Actual on-disk size is one block */
+};
+
+/*
+ * On disk superblock for OCFS2
+ * Note that it is contained inside an ocfs2_dinode, so all offsets
+ * are relative to the start of ocfs2_dinode.id2.
+ */
+struct ocfs2_super_block {
+/*00*/	__le16 s_major_rev_level;
+	__le16 s_minor_rev_level;
+	__le16 s_mnt_count;
+	__le16 s_max_mnt_count;
+	__le16 s_state;			/* File system state */
+	__le16 s_errors;			/* Behaviour when detecting errors */
+	__le32 s_checkinterval;		/* Max time between checks */
+/*10*/	__le64 s_lastcheck;		/* Time of last check */
+	__le32 s_creator_os;		/* OS */
+	__le32 s_feature_compat;		/* Compatible feature set */
+/*20*/	__le32 s_feature_incompat;	/* Incompatible feature set */
+	__le32 s_feature_ro_compat;	/* Readonly-compatible feature set */
+	__le64 s_root_blkno;		/* Offset, in blocks, of root directory
+					   dinode */
+/*30*/	__le64 s_system_dir_blkno;	/* Offset, in blocks, of system
+					   directory dinode */
+	__le32 s_blocksize_bits;		/* Blocksize for this fs */
+	__le32 s_clustersize_bits;	/* Clustersize for this fs */
+/*40*/	__le16 s_max_slots;		/* Max number of simultaneous mounts
+					   before tunefs required */
+	__le16 s_reserved1;
+	__le32 s_reserved2;
+	__le64 s_first_cluster_group;	/* Block offset of 1st cluster
+					 * group header */
+/*50*/	__u8  s_label[OCFS2_MAX_VOL_LABEL_LEN];	/* Label for mounting, etc. */
+/*90*/	__u8  s_uuid[OCFS2_VOL_UUID_LEN];	/* 128-bit uuid */
+/*A0*/
+};
+
+/*
+ * Local allocation bitmap for OCFS2 slots
+ * Note that it exists inside an ocfs2_dinode, so all offsets are
+ * relative to the start of ocfs2_dinode.id2.
+ */
+struct ocfs2_local_alloc
+{
+/*00*/	__le32 la_bm_off;	/* Starting bit offset in main bitmap */
+	__le16 la_size;		/* Size of included bitmap, in bytes */
+	__le16 la_reserved1;
+	__le64 la_reserved2;
+/*10*/	__u8   la_bitmap[0];
+};
+
+/*
+ * On disk inode for OCFS2
+ */
+struct ocfs2_dinode {
+/*00*/	__u8 i_signature[8];		/* Signature for validation */
+	__le32 i_generation;		/* Generation number */
+	__le16 i_suballoc_slot;		/* Slot suballocator this inode
+					   belongs to */
+	__le16 i_suballoc_bit;		/* Bit offset in suballocator
+					   block group */
+/*10*/	__le32 i_reserved0;
+	__le32 i_clusters;		/* Cluster count */
+	__le32 i_uid;			/* Owner UID */
+	__le32 i_gid;			/* Owning GID */
+/*20*/	__le64 i_size;			/* Size in bytes */
+	__le16 i_mode;			/* File mode */
+	__le16 i_links_count;		/* Links count */
+	__le32 i_flags;			/* File flags */
+/*30*/	__le64 i_atime;			/* Access time */
+	__le64 i_ctime;			/* Creation time */
+/*40*/	__le64 i_mtime;			/* Modification time */
+	__le64 i_dtime;			/* Deletion time */
+/*50*/	__le64 i_blkno;			/* Offset on disk, in blocks */
+	__le64 i_last_eb_blk;		/* Pointer to last extent
+					   block */
+/*60*/	__le32 i_fs_generation;		/* Generation per fs-instance */
+	__le32 i_atime_nsec;
+	__le32 i_ctime_nsec;
+	__le32 i_mtime_nsec;
+/*70*/	__le64 i_reserved1[9];
+/*B8*/	union {
+		__le64 i_pad1;		/* Generic way to refer to this
+					   64bit union */
+		struct {
+			__le64 i_rdev;	/* Device number */
+		} dev1;
+		struct {		/* Info for bitmap system
+					   inodes */
+			__le32 i_used;	/* Bits (ie, clusters) used  */
+			__le32 i_total;	/* Total bits (clusters)
+					   available */
+		} bitmap1;
+		struct {		/* Info for journal system
+					   inodes */
+			__le32 ij_flags;	/* Mounted, version, etc. */
+			__le32 ij_pad;
+		} journal1;
+	} id1;				/* Inode type dependant 1 */
+/*C0*/	union {
+		struct ocfs2_super_block	i_super;
+		struct ocfs2_local_alloc	i_lab;
+		struct ocfs2_chain_list		i_chain;
+		struct ocfs2_extent_list	i_list;
+		struct ocfs2_truncate_log	i_dealloc;
+		__u8               		i_symlink[0];
+	} id2;
+/* Actual on-disk size is one block */
+};
+
+/*
+ * On-disk directory entry structure for OCFS2
+ *
+ * Packed as this structure could be accessed unaligned on 64-bit platforms
+ */
+struct ocfs2_dir_entry {
+/*00*/	__le64   inode;                  /* Inode number */
+	__le16   rec_len;                /* Directory entry length */
+	__u8    name_len;               /* Name length */
+	__u8    file_type;
+/*0C*/	char    name[OCFS2_MAX_FILENAME_LEN];   /* File name */
+/* Actual on-disk length specified by rec_len */
+} __attribute__ ((packed));
+
+/*
+ * On disk allocator group structure for OCFS2
+ */
+struct ocfs2_group_desc
+{
+/*00*/	__u8    bg_signature[8];        /* Signature for validation */
+	__le16   bg_size;                /* Size of included bitmap in
+					   bytes. */
+	__le16   bg_bits;                /* Bits represented by this
+					   group. */
+	__le16	bg_free_bits_count;     /* Free bits count */
+	__le16   bg_chain;               /* What chain I am in. */
+/*10*/	__le32   bg_generation;
+	__le32	bg_reserved1;
+	__le64   bg_next_group;          /* Next group in my list, in
+					   blocks */
+/*20*/	__le64   bg_parent_dinode;       /* dinode which owns me, in
+					   blocks */
+	__le64   bg_blkno;               /* Offset on disk, in blocks */
+/*30*/	__le64   bg_reserved2[2];
+/*40*/	__u8    bg_bitmap[0];
+};
+
+#ifdef __KERNEL__
+static inline int ocfs2_fast_symlink_chars(struct super_block *sb)
+{
+	return  sb->s_blocksize -
+		 offsetof(struct ocfs2_dinode, id2.i_symlink);
+}
+
+static inline int ocfs2_extent_recs_per_inode(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct ocfs2_dinode, id2.i_list.l_recs);
+
+	return size / sizeof(struct ocfs2_extent_rec);
+}
+
+static inline int ocfs2_chain_recs_per_inode(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct ocfs2_dinode, id2.i_chain.cl_recs);
+
+	return size / sizeof(struct ocfs2_chain_rec);
+}
+
+static inline u16 ocfs2_extent_recs_per_eb(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct ocfs2_extent_block, h_list.l_recs);
+
+	return size / sizeof(struct ocfs2_extent_rec);
+}
+
+static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
+{
+	u16 size;
+
+	size = sb->s_blocksize -
+		offsetof(struct ocfs2_dinode, id2.i_lab.la_bitmap);
+
+	return size;
+}
+
+static inline int ocfs2_group_bitmap_size(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct ocfs2_group_desc, bg_bitmap);
+
+	return size;
+}
+
+static inline int ocfs2_truncate_recs_per_inode(struct super_block *sb)
+{
+	int size;
+
+	size = sb->s_blocksize -
+		offsetof(struct ocfs2_dinode, id2.i_dealloc.tl_recs);
+
+	return size / sizeof(struct ocfs2_truncate_rec);
+}
+#else
+static inline int ocfs2_fast_symlink_chars(int blocksize)
+{
+	return blocksize - offsetof(struct ocfs2_dinode, id2.i_symlink);
+}
+
+static inline int ocfs2_extent_recs_per_inode(int blocksize)
+{
+	int size;
+
+	size = blocksize -
+		offsetof(struct ocfs2_dinode, id2.i_list.l_recs);
+
+	return size / sizeof(struct ocfs2_extent_rec);
+}
+
+static inline int ocfs2_chain_recs_per_inode(int blocksize)
+{
+	int size;
+
+	size = blocksize -
+		offsetof(struct ocfs2_dinode, id2.i_chain.cl_recs);
+
+	return size / sizeof(struct ocfs2_chain_rec);
+}
+
+static inline int ocfs2_extent_recs_per_eb(int blocksize)
+{
+	int size;
+
+	size = blocksize -
+		offsetof(struct ocfs2_extent_block, h_list.l_recs);
+
+	return size / sizeof(struct ocfs2_extent_rec);
+}
+
+static inline int ocfs2_local_alloc_size(int blocksize)
+{
+	int size;
+
+	size = blocksize -
+		offsetof(struct ocfs2_dinode, id2.i_lab.la_bitmap);
+
+	return size;
+}
+
+static inline int ocfs2_group_bitmap_size(int blocksize)
+{
+	int size;
+
+	size = blocksize -
+		offsetof(struct ocfs2_group_desc, bg_bitmap);
+
+	return size;
+}
+
+static inline int ocfs2_truncate_recs_per_inode(int blocksize)
+{
+	int size;
+
+	size = blocksize -
+		offsetof(struct ocfs2_dinode, id2.i_dealloc.tl_recs);
+
+	return size / sizeof(struct ocfs2_truncate_rec);
+}
+#endif  /* __KERNEL__ */
+
+
+static inline int ocfs2_system_inode_is_global(int type)
+{
+	return ((type >= 0) &&
+		(type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE));
+}
+
+static inline int ocfs2_sprintf_system_inode_name(char *buf, int len,
+						  int type, int slot)
+{
+	int chars;
+
+        /*
+         * Global system inodes can only have one copy.  Everything
+         * after OCFS2_LAST_GLOBAL_SYSTEM_INODE in the system inode
+         * list has a copy per slot.
+         */
+	if (type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE)
+		chars = snprintf(buf, len,
+				 ocfs2_system_inodes[type].si_name);
+	else
+		chars = snprintf(buf, len,
+				 ocfs2_system_inodes[type].si_name,
+				 slot);
+
+	return chars;
+}
+
+static inline void ocfs2_set_de_type(struct ocfs2_dir_entry *de,
+				    umode_t mode)
+{
+	de->file_type = ocfs2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
+}
+
+#endif  /* _OCFS2_FS_H */
+
diff --git a/fs/ocfs2/ocfs2_lockid.h b/fs/ocfs2/ocfs2_lockid.h
new file mode 100644
index 0000000..7dd9e1e
--- /dev/null
+++ b/fs/ocfs2/ocfs2_lockid.h
@@ -0,0 +1,73 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ocfs2_lockid.h
+ *
+ * Defines OCFS2 lockid bits.
+ *
+ * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_LOCKID_H
+#define OCFS2_LOCKID_H
+
+/* lock ids are made up in the following manner:
+ * name[0]     --> type
+ * name[1-6]   --> 6 pad characters, reserved for now
+ * name[7-22]  --> block number, expressed in hex as 16 chars
+ * name[23-30] --> i_generation, expressed in hex 8 chars
+ * name[31]    --> '\0' */
+#define OCFS2_LOCK_ID_MAX_LEN  32
+#define OCFS2_LOCK_ID_PAD "000000"
+
+enum ocfs2_lock_type {
+	OCFS2_LOCK_TYPE_META = 0,
+	OCFS2_LOCK_TYPE_DATA,
+	OCFS2_LOCK_TYPE_SUPER,
+	OCFS2_LOCK_TYPE_RENAME,
+	OCFS2_LOCK_TYPE_RW,
+	OCFS2_NUM_LOCK_TYPES
+};
+
+static inline char ocfs2_lock_type_char(enum ocfs2_lock_type type)
+{
+	char c;
+	switch (type) {
+		case OCFS2_LOCK_TYPE_META:
+			c = 'M';
+			break;
+		case OCFS2_LOCK_TYPE_DATA:
+			c = 'D';
+			break;
+		case OCFS2_LOCK_TYPE_SUPER:
+			c = 'S';
+			break;
+		case OCFS2_LOCK_TYPE_RENAME:
+			c = 'R';
+			break;
+		case OCFS2_LOCK_TYPE_RW:
+			c = 'W';
+			break;
+		default:
+			c = '\0';
+	}
+
+	return c;
+}
+
+#endif  /* OCFS2_LOCKID_H */
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c
new file mode 100644
index 0000000..8716279
--- /dev/null
+++ b/fs/ocfs2/slot_map.c
@@ -0,0 +1,303 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * slot_map.c
+ *
+ *
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/smp_lock.h>
+
+#define MLOG_MASK_PREFIX ML_SUPER
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "heartbeat.h"
+#include "inode.h"
+#include "slot_map.h"
+#include "super.h"
+#include "sysfile.h"
+
+#include "buffer_head_io.h"
+
+static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si,
+				    s16 global);
+static void __ocfs2_fill_slot(struct ocfs2_slot_info *si,
+			      s16 slot_num,
+			      s16 node_num);
+
+/* Use the slot information we've collected to create a map of mounted
+ * nodes. Should be holding an EX on super block. assumes slot info is
+ * up to date. Note that we call this *after* we find a slot, so our
+ * own node should be set in the map too... */
+void ocfs2_populate_mounted_map(struct ocfs2_super *osb)
+{
+	int i;
+	struct ocfs2_slot_info *si = osb->slot_info;
+
+	spin_lock(&si->si_lock);
+
+	for (i = 0; i < si->si_size; i++)
+		if (si->si_global_node_nums[i] != OCFS2_INVALID_SLOT)
+			ocfs2_node_map_set_bit(osb, &osb->mounted_map,
+					      si->si_global_node_nums[i]);
+
+	spin_unlock(&si->si_lock);
+}
+
+/* post the slot information on disk into our slot_info struct. */
+void ocfs2_update_slot_info(struct ocfs2_slot_info *si)
+{
+	int i;
+	__le16 *disk_info;
+
+	/* we don't read the slot block here as ocfs2_super_lock
+	 * should've made sure we have the most recent copy. */
+	spin_lock(&si->si_lock);
+	disk_info = (__le16 *) si->si_bh->b_data;
+
+	for (i = 0; i < si->si_size; i++)
+		si->si_global_node_nums[i] = le16_to_cpu(disk_info[i]);
+
+	spin_unlock(&si->si_lock);
+}
+
+/* post the our slot info stuff into it's destination bh and write it
+ * out. */
+int ocfs2_update_disk_slots(struct ocfs2_super *osb,
+			    struct ocfs2_slot_info *si)
+{
+	int status, i;
+	__le16 *disk_info = (__le16 *) si->si_bh->b_data;
+
+	spin_lock(&si->si_lock);
+	for (i = 0; i < si->si_size; i++)
+		disk_info[i] = cpu_to_le16(si->si_global_node_nums[i]);
+	spin_unlock(&si->si_lock);
+
+	status = ocfs2_write_block(osb, si->si_bh, si->si_inode);
+	if (status < 0)
+		mlog_errno(status);
+
+	return status;
+}
+
+/* try to find global node in the slot info. Returns
+ * OCFS2_INVALID_SLOT if nothing is found. */
+static s16 __ocfs2_node_num_to_slot(struct ocfs2_slot_info *si,
+				    s16 global)
+{
+	int i;
+	s16 ret = OCFS2_INVALID_SLOT;
+
+	for(i = 0; i < si->si_num_slots; i++) {
+		if (global == si->si_global_node_nums[i]) {
+			ret = (s16) i;
+			break;
+		}
+	}
+	return ret;
+}
+
+static s16 __ocfs2_find_empty_slot(struct ocfs2_slot_info *si)
+{
+	int i;
+	s16 ret = OCFS2_INVALID_SLOT;
+
+	for(i = 0; i < si->si_num_slots; i++) {
+		if (OCFS2_INVALID_SLOT == si->si_global_node_nums[i]) {
+			ret = (s16) i;
+			break;
+		}
+	}
+	return ret;
+}
+
+s16 ocfs2_node_num_to_slot(struct ocfs2_slot_info *si,
+			   s16 global)
+{
+	s16 ret;
+
+	spin_lock(&si->si_lock);
+	ret = __ocfs2_node_num_to_slot(si, global);
+	spin_unlock(&si->si_lock);
+	return ret;
+}
+
+static void __ocfs2_fill_slot(struct ocfs2_slot_info *si,
+			      s16 slot_num,
+			      s16 node_num)
+{
+	BUG_ON(slot_num == OCFS2_INVALID_SLOT);
+	BUG_ON(slot_num >= si->si_num_slots);
+	BUG_ON((node_num != O2NM_INVALID_NODE_NUM) &&
+	       (node_num >= O2NM_MAX_NODES));
+
+	si->si_global_node_nums[slot_num] = node_num;
+}
+
+void ocfs2_clear_slot(struct ocfs2_slot_info *si,
+		      s16 slot_num)
+{
+	spin_lock(&si->si_lock);
+	__ocfs2_fill_slot(si, slot_num, OCFS2_INVALID_SLOT);
+	spin_unlock(&si->si_lock);
+}
+
+int ocfs2_init_slot_info(struct ocfs2_super *osb)
+{
+	int status, i;
+	u64 blkno;
+	struct inode *inode = NULL;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_slot_info *si;
+
+	si = kcalloc(1, sizeof(struct ocfs2_slot_info), GFP_KERNEL);
+	if (!si) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	spin_lock_init(&si->si_lock);
+	si->si_num_slots = osb->max_slots;
+	si->si_size = OCFS2_MAX_SLOTS;
+
+	for(i = 0; i < si->si_num_slots; i++)
+		si->si_global_node_nums[i] = OCFS2_INVALID_SLOT;
+
+	inode = ocfs2_get_system_file_inode(osb, SLOT_MAP_SYSTEM_INODE,
+					    OCFS2_INVALID_SLOT);
+	if (!inode) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_extent_map_get_blocks(inode, 0ULL, 1, &blkno, NULL);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_read_block(osb, blkno, &bh, 0, inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	si->si_inode = inode;
+	si->si_bh = bh;
+	osb->slot_info = si;
+bail:
+	if (status < 0 && si)
+		ocfs2_free_slot_info(si);
+
+	return status;
+}
+
+void ocfs2_free_slot_info(struct ocfs2_slot_info *si)
+{
+	if (si->si_inode)
+		iput(si->si_inode);
+	if (si->si_bh)
+		brelse(si->si_bh);
+	kfree(si);
+}
+
+int ocfs2_find_slot(struct ocfs2_super *osb)
+{
+	int status;
+	s16 slot;
+	struct ocfs2_slot_info *si;
+
+	mlog_entry_void();
+
+	si = osb->slot_info;
+
+	ocfs2_update_slot_info(si);
+
+	spin_lock(&si->si_lock);
+	/* search for ourselves first and take the slot if it already
+	 * exists. Perhaps we need to mark this in a variable for our
+	 * own journal recovery? Possibly not, though we certainly
+	 * need to warn to the user */
+	slot = __ocfs2_node_num_to_slot(si, osb->node_num);
+	if (slot == OCFS2_INVALID_SLOT) {
+		/* if no slot yet, then just take 1st available
+		 * one. */
+		slot = __ocfs2_find_empty_slot(si);
+		if (slot == OCFS2_INVALID_SLOT) {
+			spin_unlock(&si->si_lock);
+			mlog(ML_ERROR, "no free slots available!\n");
+			status = -EINVAL;
+			goto bail;
+		}
+	} else
+		mlog(ML_NOTICE, "slot %d is already allocated to this node!\n",
+		     slot);
+
+	__ocfs2_fill_slot(si, slot, osb->node_num);
+	osb->slot_num = slot;
+	spin_unlock(&si->si_lock);
+
+	mlog(ML_NOTICE, "taking node slot %d\n", osb->slot_num);
+
+	status = ocfs2_update_disk_slots(osb, si);
+	if (status < 0)
+		mlog_errno(status);
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+void ocfs2_put_slot(struct ocfs2_super *osb)
+{
+	int status;
+	struct ocfs2_slot_info *si = osb->slot_info;
+
+	if (!si)
+		return;
+
+	ocfs2_update_slot_info(si);
+
+	spin_lock(&si->si_lock);
+	__ocfs2_fill_slot(si, osb->slot_num, OCFS2_INVALID_SLOT);
+	osb->slot_num = OCFS2_INVALID_SLOT;
+	spin_unlock(&si->si_lock);
+
+	status = ocfs2_update_disk_slots(osb, si);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+bail:
+	osb->slot_info = NULL;
+	ocfs2_free_slot_info(si);
+}
+
diff --git a/fs/ocfs2/slot_map.h b/fs/ocfs2/slot_map.h
new file mode 100644
index 0000000..d8c8cee
--- /dev/null
+++ b/fs/ocfs2/slot_map.h
@@ -0,0 +1,66 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * slotmap.h
+ *
+ * description here
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+
+#ifndef SLOTMAP_H
+#define SLOTMAP_H
+
+struct ocfs2_slot_info {
+	spinlock_t si_lock;
+
+       	struct inode *si_inode;
+	struct buffer_head *si_bh;
+	unsigned int si_num_slots;
+	unsigned int si_size;
+	s16 si_global_node_nums[OCFS2_MAX_SLOTS];
+};
+
+int ocfs2_init_slot_info(struct ocfs2_super *osb);
+void ocfs2_free_slot_info(struct ocfs2_slot_info *si);
+
+int ocfs2_find_slot(struct ocfs2_super *osb);
+void ocfs2_put_slot(struct ocfs2_super *osb);
+
+void ocfs2_update_slot_info(struct ocfs2_slot_info *si);
+int ocfs2_update_disk_slots(struct ocfs2_super *osb,
+			    struct ocfs2_slot_info *si);
+
+s16 ocfs2_node_num_to_slot(struct ocfs2_slot_info *si,
+			   s16 global);
+void ocfs2_clear_slot(struct ocfs2_slot_info *si,
+		      s16 slot_num);
+
+void ocfs2_populate_mounted_map(struct ocfs2_super *osb);
+
+static inline int ocfs2_is_empty_slot(struct ocfs2_slot_info *si,
+				      int slot_num)
+{
+	BUG_ON(slot_num == OCFS2_INVALID_SLOT);
+	assert_spin_locked(&si->si_lock);
+
+	return si->si_global_node_nums[slot_num] == OCFS2_INVALID_SLOT;
+}
+
+#endif
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
new file mode 100644
index 0000000..c46c164
--- /dev/null
+++ b/fs/ocfs2/suballoc.c
@@ -0,0 +1,1651 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * suballoc.c
+ *
+ * metadata alloc and free
+ * Inspired by ext3 block groups.
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+
+#define MLOG_MASK_PREFIX ML_DISK_ALLOC
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dlmglue.h"
+#include "inode.h"
+#include "journal.h"
+#include "localalloc.h"
+#include "suballoc.h"
+#include "super.h"
+#include "sysfile.h"
+#include "uptodate.h"
+
+#include "buffer_head_io.h"
+
+static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg);
+static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe);
+static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl);
+static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle,
+				  struct inode *alloc_inode,
+				  struct buffer_head *bg_bh,
+				  u64 group_blkno,
+				  u16 my_chain,
+				  struct ocfs2_chain_list *cl);
+static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
+				   struct inode *alloc_inode,
+				   struct buffer_head *bh);
+
+static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
+				       struct ocfs2_alloc_context *ac);
+
+static int ocfs2_cluster_group_search(struct inode *inode,
+				      struct buffer_head *group_bh,
+				      u32 bits_wanted, u32 min_bits,
+				      u16 *bit_off, u16 *bits_found);
+static int ocfs2_block_group_search(struct inode *inode,
+				    struct buffer_head *group_bh,
+				    u32 bits_wanted, u32 min_bits,
+				    u16 *bit_off, u16 *bits_found);
+static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
+			      u32 bits_wanted,
+			      u32 min_bits,
+			      u16 *bit_off,
+			      unsigned int *num_bits,
+			      u64 *bg_blkno);
+static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
+				     struct ocfs2_alloc_context *ac,
+				     u32 bits_wanted,
+				     u32 min_bits,
+				     u16 *bit_off,
+				     unsigned int *num_bits,
+				     u64 *bg_blkno);
+static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,
+					 int nr);
+static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb,
+					     struct buffer_head *bg_bh,
+					     unsigned int bits_wanted,
+					     u16 *bit_off,
+					     u16 *bits_found);
+static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle,
+					     struct inode *alloc_inode,
+					     struct ocfs2_group_desc *bg,
+					     struct buffer_head *group_bh,
+					     unsigned int bit_off,
+					     unsigned int num_bits);
+static inline int ocfs2_block_group_clear_bits(struct ocfs2_journal_handle *handle,
+					       struct inode *alloc_inode,
+					       struct ocfs2_group_desc *bg,
+					       struct buffer_head *group_bh,
+					       unsigned int bit_off,
+					       unsigned int num_bits);
+
+static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle,
+				    struct inode *alloc_inode,
+				    struct buffer_head *fe_bh,
+				    struct buffer_head *bg_bh,
+				    struct buffer_head *prev_bg_bh,
+				    u16 chain);
+static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg,
+						     u32 wanted);
+static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle,
+				    struct inode *alloc_inode,
+				    struct buffer_head *alloc_bh,
+				    unsigned int start_bit,
+				    u64 bg_blkno,
+				    unsigned int count);
+static inline u64 ocfs2_which_suballoc_group(u64 block,
+					     unsigned int bit);
+static inline u32 ocfs2_desc_bitmap_to_cluster_off(struct inode *inode,
+						   u64 bg_blkno,
+						   u16 bg_bit_off);
+static inline u64 ocfs2_which_cluster_group(struct inode *inode,
+					    u32 cluster);
+static inline void ocfs2_block_to_cluster_group(struct inode *inode,
+						u64 data_blkno,
+						u64 *bg_blkno,
+						u16 *bg_bit_off);
+
+void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac)
+{
+	if (ac->ac_inode)
+		iput(ac->ac_inode);
+	if (ac->ac_bh)
+		brelse(ac->ac_bh);
+	kfree(ac);
+}
+
+static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl)
+{
+	return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc);
+}
+
+static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle,
+				  struct inode *alloc_inode,
+				  struct buffer_head *bg_bh,
+				  u64 group_blkno,
+				  u16 my_chain,
+				  struct ocfs2_chain_list *cl)
+{
+	int status = 0;
+	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;
+	struct super_block * sb = alloc_inode->i_sb;
+
+	mlog_entry_void();
+
+	if (((unsigned long long) bg_bh->b_blocknr) != group_blkno) {
+		ocfs2_error(alloc_inode->i_sb, "group block (%"MLFu64") "
+			    "!= b_blocknr (%llu)", group_blkno,
+			    (unsigned long long) bg_bh->b_blocknr);
+		status = -EIO;
+		goto bail;
+	}
+
+	status = ocfs2_journal_access(handle,
+				      alloc_inode,
+				      bg_bh,
+				      OCFS2_JOURNAL_ACCESS_CREATE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	memset(bg, 0, sb->s_blocksize);
+	strcpy(bg->bg_signature, OCFS2_GROUP_DESC_SIGNATURE);
+	bg->bg_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation);
+	bg->bg_size = cpu_to_le16(ocfs2_group_bitmap_size(sb));
+	bg->bg_bits = cpu_to_le16(ocfs2_bits_per_group(cl));
+	bg->bg_chain = cpu_to_le16(my_chain);
+	bg->bg_next_group = cl->cl_recs[my_chain].c_blkno;
+	bg->bg_parent_dinode = cpu_to_le64(OCFS2_I(alloc_inode)->ip_blkno);
+	bg->bg_blkno = cpu_to_le64(group_blkno);
+	/* set the 1st bit in the bitmap to account for the descriptor block */
+	ocfs2_set_bit(0, (unsigned long *)bg->bg_bitmap);
+	bg->bg_free_bits_count = cpu_to_le16(le16_to_cpu(bg->bg_bits) - 1);
+
+	status = ocfs2_journal_dirty(handle, bg_bh);
+	if (status < 0)
+		mlog_errno(status);
+
+	/* There is no need to zero out or otherwise initialize the
+	 * other blocks in a group - All valid FS metadata in a block
+	 * group stores the superblock fs_generation value at
+	 * allocation time. */
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static inline u16 ocfs2_find_smallest_chain(struct ocfs2_chain_list *cl)
+{
+	u16 curr, best;
+
+	best = curr = 0;
+	while (curr < le16_to_cpu(cl->cl_count)) {
+		if (le32_to_cpu(cl->cl_recs[best].c_total) >
+		    le32_to_cpu(cl->cl_recs[curr].c_total))
+			best = curr;
+		curr++;
+	}
+	return best;
+}
+
+/*
+ * We expect the block group allocator to already be locked.
+ */
+static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
+				   struct inode *alloc_inode,
+				   struct buffer_head *bh)
+{
+	int status, credits;
+	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data;
+	struct ocfs2_chain_list *cl;
+	struct ocfs2_alloc_context *ac = NULL;
+	struct ocfs2_journal_handle *handle = NULL;
+	u32 bit_off, num_bits;
+	u16 alloc_rec;
+	u64 bg_blkno;
+	struct buffer_head *bg_bh = NULL;
+	struct ocfs2_group_desc *bg;
+
+	BUG_ON(ocfs2_is_cluster_bitmap(alloc_inode));
+
+	mlog_entry_void();
+
+	handle = ocfs2_alloc_handle(osb);
+	if (!handle) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	cl = &fe->id2.i_chain;
+	status = ocfs2_reserve_clusters(osb,
+					handle,
+					le16_to_cpu(cl->cl_cpg),
+					&ac);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	credits = ocfs2_calc_group_alloc_credits(osb->sb,
+						 le16_to_cpu(cl->cl_cpg));
+	handle = ocfs2_start_trans(osb, handle, credits);
+	if (IS_ERR(handle)) {
+		status = PTR_ERR(handle);
+		handle = NULL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_claim_clusters(osb,
+				      handle,
+				      ac,
+				      le16_to_cpu(cl->cl_cpg),
+				      &bit_off,
+				      &num_bits);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	alloc_rec = ocfs2_find_smallest_chain(cl);
+
+	/* setup the group */
+	bg_blkno = ocfs2_clusters_to_blocks(osb->sb, bit_off);
+	mlog(0, "new descriptor, record %u, at block %"MLFu64"\n",
+	     alloc_rec, bg_blkno);
+
+	bg_bh = sb_getblk(osb->sb, bg_blkno);
+	if (!bg_bh) {
+		status = -EIO;
+		mlog_errno(status);
+		goto bail;
+	}
+	ocfs2_set_new_buffer_uptodate(alloc_inode, bg_bh);
+
+	status = ocfs2_block_group_fill(handle,
+					alloc_inode,
+					bg_bh,
+					bg_blkno,
+					alloc_rec,
+					cl);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	bg = (struct ocfs2_group_desc *) bg_bh->b_data;
+
+	status = ocfs2_journal_access(handle, alloc_inode,
+				      bh, OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	le32_add_cpu(&cl->cl_recs[alloc_rec].c_free,
+		     le16_to_cpu(bg->bg_free_bits_count));
+	le32_add_cpu(&cl->cl_recs[alloc_rec].c_total, le16_to_cpu(bg->bg_bits));
+	cl->cl_recs[alloc_rec].c_blkno  = cpu_to_le64(bg_blkno);
+	if (le16_to_cpu(cl->cl_next_free_rec) < le16_to_cpu(cl->cl_count))
+		le16_add_cpu(&cl->cl_next_free_rec, 1);
+
+	le32_add_cpu(&fe->id1.bitmap1.i_used, le16_to_cpu(bg->bg_bits) -
+					le16_to_cpu(bg->bg_free_bits_count));
+	le32_add_cpu(&fe->id1.bitmap1.i_total, le16_to_cpu(bg->bg_bits));
+	le32_add_cpu(&fe->i_clusters, le16_to_cpu(cl->cl_cpg));
+
+	status = ocfs2_journal_dirty(handle, bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	spin_lock(&OCFS2_I(alloc_inode)->ip_lock);
+	OCFS2_I(alloc_inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
+	fe->i_size = cpu_to_le64(ocfs2_clusters_to_bytes(alloc_inode->i_sb,
+					     le32_to_cpu(fe->i_clusters)));
+	spin_unlock(&OCFS2_I(alloc_inode)->ip_lock);
+	i_size_write(alloc_inode, le64_to_cpu(fe->i_size));
+	alloc_inode->i_blocks =
+		ocfs2_align_bytes_to_sectors(i_size_read(alloc_inode));
+
+	status = 0;
+bail:
+	if (handle)
+		ocfs2_commit_trans(handle);
+
+	if (ac)
+		ocfs2_free_alloc_context(ac);
+
+	if (bg_bh)
+		brelse(bg_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
+				       struct ocfs2_alloc_context *ac)
+{
+	int status;
+	u32 bits_wanted = ac->ac_bits_wanted;
+	struct inode *alloc_inode = ac->ac_inode;
+	struct buffer_head *bh = NULL;
+	struct ocfs2_journal_handle *handle = ac->ac_handle;
+	struct ocfs2_dinode *fe;
+	u32 free_bits;
+
+	mlog_entry_void();
+
+	BUG_ON(handle->flags & OCFS2_HANDLE_STARTED);
+
+	ocfs2_handle_add_inode(handle, alloc_inode);
+	status = ocfs2_meta_lock(alloc_inode, handle, &bh, 1);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	fe = (struct ocfs2_dinode *) bh->b_data;
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe);
+		status = -EIO;
+		goto bail;
+	}
+	if (!(fe->i_flags & cpu_to_le32(OCFS2_CHAIN_FL))) {
+		ocfs2_error(alloc_inode->i_sb, "Invalid chain allocator "
+			    "# %"MLFu64, le64_to_cpu(fe->i_blkno));
+		status = -EIO;
+		goto bail;
+	}
+
+	free_bits = le32_to_cpu(fe->id1.bitmap1.i_total) -
+		le32_to_cpu(fe->id1.bitmap1.i_used);
+
+	if (bits_wanted > free_bits) {
+		/* cluster bitmap never grows */
+		if (ocfs2_is_cluster_bitmap(alloc_inode)) {
+			mlog(0, "Disk Full: wanted=%u, free_bits=%u\n",
+			     bits_wanted, free_bits);
+			status = -ENOSPC;
+			goto bail;
+		}
+
+		status = ocfs2_block_group_alloc(osb, alloc_inode, bh);
+		if (status < 0) {
+			if (status != -ENOSPC)
+				mlog_errno(status);
+			goto bail;
+		}
+		atomic_inc(&osb->alloc_stats.bg_extends);
+
+		/* You should never ask for this much metadata */
+		BUG_ON(bits_wanted >
+		       (le32_to_cpu(fe->id1.bitmap1.i_total)
+			- le32_to_cpu(fe->id1.bitmap1.i_used)));
+	}
+
+	get_bh(bh);
+	ac->ac_bh = bh;
+bail:
+	if (bh)
+		brelse(bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
+			       struct ocfs2_journal_handle *handle,
+			       struct ocfs2_dinode *fe,
+			       struct ocfs2_alloc_context **ac)
+{
+	int status;
+	struct inode *alloc_inode = NULL;
+
+	*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+	if (!(*ac)) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	(*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe);
+	(*ac)->ac_handle = handle;
+	(*ac)->ac_which = OCFS2_AC_USE_META;
+
+#ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS
+	alloc_inode = ocfs2_get_system_file_inode(osb,
+						  EXTENT_ALLOC_SYSTEM_INODE,
+						  0);
+#else
+	alloc_inode = ocfs2_get_system_file_inode(osb,
+						  EXTENT_ALLOC_SYSTEM_INODE,
+						  osb->slot_num);
+#endif
+	if (!alloc_inode) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	(*ac)->ac_inode = igrab(alloc_inode);
+	(*ac)->ac_group_search = ocfs2_block_group_search;
+
+	status = ocfs2_reserve_suballoc_bits(osb, (*ac));
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	status = 0;
+bail:
+	if ((status < 0) && *ac) {
+		ocfs2_free_alloc_context(*ac);
+		*ac = NULL;
+	}
+
+	if (alloc_inode)
+		iput(alloc_inode);
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
+			    struct ocfs2_journal_handle *handle,
+			    struct ocfs2_alloc_context **ac)
+{
+	int status;
+	struct inode *alloc_inode = NULL;
+
+	*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+	if (!(*ac)) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	(*ac)->ac_bits_wanted = 1;
+	(*ac)->ac_handle = handle;
+	(*ac)->ac_which = OCFS2_AC_USE_INODE;
+
+	alloc_inode = ocfs2_get_system_file_inode(osb,
+						  INODE_ALLOC_SYSTEM_INODE,
+						  osb->slot_num);
+	if (!alloc_inode) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	(*ac)->ac_inode = igrab(alloc_inode);
+	(*ac)->ac_group_search = ocfs2_block_group_search;
+
+	status = ocfs2_reserve_suballoc_bits(osb, *ac);
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	status = 0;
+bail:
+	if ((status < 0) && *ac) {
+		ocfs2_free_alloc_context(*ac);
+		*ac = NULL;
+	}
+
+	if (alloc_inode)
+		iput(alloc_inode);
+
+	mlog_exit(status);
+	return status;
+}
+
+/* local alloc code has to do the same thing, so rather than do this
+ * twice.. */
+int ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb,
+				      struct ocfs2_alloc_context *ac)
+{
+	int status;
+
+	ac->ac_inode = ocfs2_get_system_file_inode(osb,
+						   GLOBAL_BITMAP_SYSTEM_INODE,
+						   OCFS2_INVALID_SLOT);
+	if (!ac->ac_inode) {
+		status = -EINVAL;
+		mlog(ML_ERROR, "Could not get bitmap inode!\n");
+		goto bail;
+	}
+	ac->ac_which = OCFS2_AC_USE_MAIN;
+	ac->ac_group_search = ocfs2_cluster_group_search;
+
+	status = ocfs2_reserve_suballoc_bits(osb, ac);
+	if (status < 0 && status != -ENOSPC)
+		mlog_errno(status);
+bail:
+	return status;
+}
+
+/* Callers don't need to care which bitmap (local alloc or main) to
+ * use so we figure it out for them, but unfortunately this clutters
+ * things a bit. */
+int ocfs2_reserve_clusters(struct ocfs2_super *osb,
+			   struct ocfs2_journal_handle *handle,
+			   u32 bits_wanted,
+			   struct ocfs2_alloc_context **ac)
+{
+	int status;
+
+	mlog_entry_void();
+
+	BUG_ON(!handle);
+
+	*ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
+	if (!(*ac)) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	(*ac)->ac_bits_wanted = bits_wanted;
+	(*ac)->ac_handle = handle;
+
+	status = -ENOSPC;
+	if (ocfs2_alloc_should_use_local(osb, bits_wanted)) {
+		status = ocfs2_reserve_local_alloc_bits(osb,
+							handle,
+							bits_wanted,
+							*ac);
+		if ((status < 0) && (status != -ENOSPC)) {
+			mlog_errno(status);
+			goto bail;
+		} else if (status == -ENOSPC) {
+			/* reserve_local_bits will return enospc with
+			 * the local alloc inode still locked, so we
+			 * can change this safely here. */
+			mlog(0, "Disabling local alloc\n");
+			/* We set to OCFS2_LA_DISABLED so that umount
+			 * can clean up what's left of the local
+			 * allocation */
+			osb->local_alloc_state = OCFS2_LA_DISABLED;
+		}
+	}
+
+	if (status == -ENOSPC) {
+		status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);
+		if (status < 0) {
+			if (status != -ENOSPC)
+				mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	status = 0;
+bail:
+	if ((status < 0) && *ac) {
+		ocfs2_free_alloc_context(*ac);
+		*ac = NULL;
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * More or less lifted from ext3. I'll leave their description below:
+ *
+ * "For ext3 allocations, we must not reuse any blocks which are
+ * allocated in the bitmap buffer's "last committed data" copy.  This
+ * prevents deletes from freeing up the page for reuse until we have
+ * committed the delete transaction.
+ *
+ * If we didn't do this, then deleting something and reallocating it as
+ * data would allow the old block to be overwritten before the
+ * transaction committed (because we force data to disk before commit).
+ * This would lead to corruption if we crashed between overwriting the
+ * data and committing the delete.
+ *
+ * @@@ We may want to make this allocation behaviour conditional on
+ * data-writes at some point, and disable it for metadata allocations or
+ * sync-data inodes."
+ *
+ * Note: OCFS2 already does this differently for metadata vs data
+ * allocations, as those bitmaps are seperate and undo access is never
+ * called on a metadata group descriptor.
+ */
+static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,
+					 int nr)
+{
+	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;
+
+	if (ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap))
+		return 0;
+	if (!buffer_jbd(bg_bh) || !bh2jh(bg_bh)->b_committed_data)
+		return 1;
+
+	bg = (struct ocfs2_group_desc *) bh2jh(bg_bh)->b_committed_data;
+	return !ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap);
+}
+
+static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb,
+					     struct buffer_head *bg_bh,
+					     unsigned int bits_wanted,
+					     u16 *bit_off,
+					     u16 *bits_found)
+{
+	void *bitmap;
+	u16 best_offset, best_size;
+	int offset, start, found, status = 0;
+	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;
+
+	if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
+		OCFS2_RO_ON_INVALID_GROUP_DESC(osb->sb, bg);
+		return -EIO;
+	}
+
+	found = start = best_offset = best_size = 0;
+	bitmap = bg->bg_bitmap;
+
+	while((offset = ocfs2_find_next_zero_bit(bitmap,
+						 le16_to_cpu(bg->bg_bits),
+						 start)) != -1) {
+		if (offset == le16_to_cpu(bg->bg_bits))
+			break;
+
+		if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) {
+			/* We found a zero, but we can't use it as it
+			 * hasn't been put to disk yet! */
+			found = 0;
+			start = offset + 1;
+		} else if (offset == start) {
+			/* we found a zero */
+			found++;
+			/* move start to the next bit to test */
+			start++;
+		} else {
+			/* got a zero after some ones */
+			found = 1;
+			start = offset + 1;
+		}
+		if (found > best_size) {
+			best_size = found;
+			best_offset = start - found;
+		}
+		/* we got everything we needed */
+		if (found == bits_wanted) {
+			/* mlog(0, "Found it all!\n"); */
+			break;
+		}
+	}
+
+	/* XXX: I think the first clause is equivalent to the second
+	 * 	- jlbec */
+	if (found == bits_wanted) {
+		*bit_off = start - found;
+		*bits_found = found;
+	} else if (best_size) {
+		*bit_off = best_offset;
+		*bits_found = best_size;
+	} else {
+		status = -ENOSPC;
+		/* No error log here -- see the comment above
+		 * ocfs2_test_bg_bit_allocatable */
+	}
+
+	return status;
+}
+
+static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle,
+					     struct inode *alloc_inode,
+					     struct ocfs2_group_desc *bg,
+					     struct buffer_head *group_bh,
+					     unsigned int bit_off,
+					     unsigned int num_bits)
+{
+	int status;
+	void *bitmap = bg->bg_bitmap;
+	int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;
+
+	mlog_entry_void();
+
+	if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
+		OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);
+		status = -EIO;
+		goto bail;
+	}
+	BUG_ON(le16_to_cpu(bg->bg_free_bits_count) < num_bits);
+
+	mlog(0, "block_group_set_bits: off = %u, num = %u\n", bit_off,
+	     num_bits);
+
+	if (ocfs2_is_cluster_bitmap(alloc_inode))
+		journal_type = OCFS2_JOURNAL_ACCESS_UNDO;
+
+	status = ocfs2_journal_access(handle,
+				      alloc_inode,
+				      group_bh,
+				      journal_type);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	le16_add_cpu(&bg->bg_free_bits_count, -num_bits);
+
+	while(num_bits--)
+		ocfs2_set_bit(bit_off++, bitmap);
+
+	status = ocfs2_journal_dirty(handle,
+				     group_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/* find the one with the most empty bits */
+static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl)
+{
+	u16 curr, best;
+
+	BUG_ON(!cl->cl_next_free_rec);
+
+	best = curr = 0;
+	while (curr < le16_to_cpu(cl->cl_next_free_rec)) {
+		if (le32_to_cpu(cl->cl_recs[curr].c_free) >
+		    le32_to_cpu(cl->cl_recs[best].c_free))
+			best = curr;
+		curr++;
+	}
+
+	BUG_ON(best >= le16_to_cpu(cl->cl_next_free_rec));
+	return best;
+}
+
+static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle,
+				    struct inode *alloc_inode,
+				    struct buffer_head *fe_bh,
+				    struct buffer_head *bg_bh,
+				    struct buffer_head *prev_bg_bh,
+				    u16 chain)
+{
+	int status;
+	/* there is a really tiny chance the journal calls could fail,
+	 * but we wouldn't want inconsistent blocks in *any* case. */
+	u64 fe_ptr, bg_ptr, prev_bg_ptr;
+	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
+	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;
+	struct ocfs2_group_desc *prev_bg = (struct ocfs2_group_desc *) prev_bg_bh->b_data;
+
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe);
+		status = -EIO;
+		goto out;
+	}
+	if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
+		OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);
+		status = -EIO;
+		goto out;
+	}
+	if (!OCFS2_IS_VALID_GROUP_DESC(prev_bg)) {
+		OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, prev_bg);
+		status = -EIO;
+		goto out;
+	}
+
+	mlog(0, "In suballoc %"MLFu64", chain %u, move group %"MLFu64" to "
+	     "top, prev = %"MLFu64"\n",
+	     fe->i_blkno, chain, bg->bg_blkno, prev_bg->bg_blkno);
+
+	fe_ptr = le64_to_cpu(fe->id2.i_chain.cl_recs[chain].c_blkno);
+	bg_ptr = le64_to_cpu(bg->bg_next_group);
+	prev_bg_ptr = le64_to_cpu(prev_bg->bg_next_group);
+
+	status = ocfs2_journal_access(handle, alloc_inode, prev_bg_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto out_rollback;
+	}
+
+	prev_bg->bg_next_group = bg->bg_next_group;
+
+	status = ocfs2_journal_dirty(handle, prev_bg_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto out_rollback;
+	}
+
+	status = ocfs2_journal_access(handle, alloc_inode, bg_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto out_rollback;
+	}
+
+	bg->bg_next_group = fe->id2.i_chain.cl_recs[chain].c_blkno;
+
+	status = ocfs2_journal_dirty(handle, bg_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto out_rollback;
+	}
+
+	status = ocfs2_journal_access(handle, alloc_inode, fe_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto out_rollback;
+	}
+
+	fe->id2.i_chain.cl_recs[chain].c_blkno = bg->bg_blkno;
+
+	status = ocfs2_journal_dirty(handle, fe_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto out_rollback;
+	}
+
+	status = 0;
+out_rollback:
+	if (status < 0) {
+		fe->id2.i_chain.cl_recs[chain].c_blkno = cpu_to_le64(fe_ptr);
+		bg->bg_next_group = cpu_to_le64(bg_ptr);
+		prev_bg->bg_next_group = cpu_to_le64(prev_bg_ptr);
+	}
+out:
+	mlog_exit(status);
+	return status;
+}
+
+static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg,
+						     u32 wanted)
+{
+	return le16_to_cpu(bg->bg_free_bits_count) > wanted;
+}
+
+/* return 0 on success, -ENOSPC to keep searching and any other < 0
+ * value on error. */
+static int ocfs2_cluster_group_search(struct inode *inode,
+				      struct buffer_head *group_bh,
+				      u32 bits_wanted, u32 min_bits,
+				      u16 *bit_off, u16 *bits_found)
+{
+	int search = -ENOSPC;
+	int ret;
+	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) group_bh->b_data;
+	u16 tmp_off, tmp_found;
+
+	BUG_ON(!ocfs2_is_cluster_bitmap(inode));
+
+	if (bg->bg_free_bits_count) {
+		ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
+							group_bh, bits_wanted,
+							&tmp_off, &tmp_found);
+		if (ret)
+			return ret;
+
+		/* ocfs2_block_group_find_clear_bits() might
+		 * return success, but we still want to return
+		 * -ENOSPC unless it found the minimum number
+		 * of bits. */
+		if (min_bits <= tmp_found) {
+			*bit_off = tmp_off;
+			*bits_found = tmp_found;
+			search = 0; /* success */
+		}
+	}
+
+	return search;
+}
+
+static int ocfs2_block_group_search(struct inode *inode,
+				    struct buffer_head *group_bh,
+				    u32 bits_wanted, u32 min_bits,
+				    u16 *bit_off, u16 *bits_found)
+{
+	int ret = -ENOSPC;
+	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) group_bh->b_data;
+
+	BUG_ON(min_bits != 1);
+	BUG_ON(ocfs2_is_cluster_bitmap(inode));
+
+	if (bg->bg_free_bits_count)
+		ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
+							group_bh, bits_wanted,
+							bit_off, bits_found);
+
+	return ret;
+}
+
+static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
+			      u32 bits_wanted,
+			      u32 min_bits,
+			      u16 *bit_off,
+			      unsigned int *num_bits,
+			      u64 *bg_blkno)
+{
+	int status;
+	u16 chain, tmp_bits;
+	u32 tmp_used;
+	u64 next_group;
+	struct ocfs2_journal_handle *handle = ac->ac_handle;
+	struct inode *alloc_inode = ac->ac_inode;
+	struct buffer_head *group_bh = NULL;
+	struct buffer_head *prev_group_bh = NULL;
+	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) ac->ac_bh->b_data;
+	struct ocfs2_chain_list *cl = (struct ocfs2_chain_list *) &fe->id2.i_chain;
+	struct ocfs2_group_desc *bg;
+
+	chain = ac->ac_chain;
+	mlog(0, "trying to alloc %u bits from chain %u, inode %"MLFu64"\n",
+	     bits_wanted, chain, OCFS2_I(alloc_inode)->ip_blkno);
+
+	status = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb),
+				  le64_to_cpu(cl->cl_recs[chain].c_blkno),
+				  &group_bh, OCFS2_BH_CACHED, alloc_inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	bg = (struct ocfs2_group_desc *) group_bh->b_data;
+	if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
+		OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);
+		status = -EIO;
+		goto bail;
+	}
+
+	status = -ENOSPC;
+	/* for now, the chain search is a bit simplistic. We just use
+	 * the 1st group with any empty bits. */
+	while ((status = ac->ac_group_search(alloc_inode, group_bh,
+					     bits_wanted, min_bits, bit_off,
+					     &tmp_bits)) == -ENOSPC) {
+		if (!bg->bg_next_group)
+			break;
+
+		if (prev_group_bh) {
+			brelse(prev_group_bh);
+			prev_group_bh = NULL;
+		}
+		next_group = le64_to_cpu(bg->bg_next_group);
+		prev_group_bh = group_bh;
+		group_bh = NULL;
+		status = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb),
+					  next_group, &group_bh,
+					  OCFS2_BH_CACHED, alloc_inode);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+		bg = (struct ocfs2_group_desc *) group_bh->b_data;
+		if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
+			OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);
+			status = -EIO;
+			goto bail;
+		}
+	}
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	mlog(0, "alloc succeeds: we give %u bits from block group %"MLFu64"\n",
+	     tmp_bits, bg->bg_blkno);
+
+	*num_bits = tmp_bits;
+
+	BUG_ON(*num_bits == 0);
+
+	/*
+	 * Keep track of previous block descriptor read. When
+	 * we find a target, if we have read more than X
+	 * number of descriptors, and the target is reasonably
+	 * empty, relink him to top of his chain.
+	 *
+	 * We've read 0 extra blocks and only send one more to
+	 * the transaction, yet the next guy to search has a
+	 * much easier time.
+	 *
+	 * Do this *after* figuring out how many bits we're taking out
+	 * of our target group.
+	 */
+	if (ac->ac_allow_chain_relink &&
+	    (prev_group_bh) &&
+	    (ocfs2_block_group_reasonably_empty(bg, *num_bits))) {
+		status = ocfs2_relink_block_group(handle, alloc_inode,
+						  ac->ac_bh, group_bh,
+						  prev_group_bh, chain);
+		if (status < 0) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+
+	/* Ok, claim our bits now: set the info on dinode, chainlist
+	 * and then the group */
+	status = ocfs2_journal_access(handle,
+				      alloc_inode,
+				      ac->ac_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	tmp_used = le32_to_cpu(fe->id1.bitmap1.i_used);
+	fe->id1.bitmap1.i_used = cpu_to_le32(*num_bits + tmp_used);
+	le32_add_cpu(&cl->cl_recs[chain].c_free, -(*num_bits));
+
+	status = ocfs2_journal_dirty(handle,
+				     ac->ac_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_block_group_set_bits(handle,
+					    alloc_inode,
+					    bg,
+					    group_bh,
+					    *bit_off,
+					    *num_bits);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	mlog(0, "Allocated %u bits from suballocator %"MLFu64"\n",
+	     *num_bits, fe->i_blkno);
+
+	*bg_blkno = le64_to_cpu(bg->bg_blkno);
+bail:
+	if (group_bh)
+		brelse(group_bh);
+	if (prev_group_bh)
+		brelse(prev_group_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+/* will give out up to bits_wanted contiguous bits. */
+static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
+				     struct ocfs2_alloc_context *ac,
+				     u32 bits_wanted,
+				     u32 min_bits,
+				     u16 *bit_off,
+				     unsigned int *num_bits,
+				     u64 *bg_blkno)
+{
+	int status;
+	u16 victim, i;
+	struct ocfs2_chain_list *cl;
+	struct ocfs2_dinode *fe;
+
+	mlog_entry_void();
+
+	BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted);
+	BUG_ON(bits_wanted > (ac->ac_bits_wanted - ac->ac_bits_given));
+	BUG_ON(!ac->ac_bh);
+
+	fe = (struct ocfs2_dinode *) ac->ac_bh->b_data;
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		OCFS2_RO_ON_INVALID_DINODE(osb->sb, fe);
+		status = -EIO;
+		goto bail;
+	}
+	if (le32_to_cpu(fe->id1.bitmap1.i_used) >=
+	    le32_to_cpu(fe->id1.bitmap1.i_total)) {
+		ocfs2_error(osb->sb, "Chain allocator dinode %"MLFu64" has %u"
+			    "used bits but only %u total.",
+			    le64_to_cpu(fe->i_blkno),
+			    le32_to_cpu(fe->id1.bitmap1.i_used),
+			    le32_to_cpu(fe->id1.bitmap1.i_total));
+		status = -EIO;
+		goto bail;
+	}
+
+	cl = (struct ocfs2_chain_list *) &fe->id2.i_chain;
+
+	victim = ocfs2_find_victim_chain(cl);
+	ac->ac_chain = victim;
+	ac->ac_allow_chain_relink = 1;
+
+	status = ocfs2_search_chain(ac, bits_wanted, min_bits, bit_off,
+				    num_bits, bg_blkno);
+	if (!status)
+		goto bail;
+	if (status < 0 && status != -ENOSPC) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	mlog(0, "Search of victim chain %u came up with nothing, "
+	     "trying all chains now.\n", victim);
+
+	/* If we didn't pick a good victim, then just default to
+	 * searching each chain in order. Don't allow chain relinking
+	 * because we only calculate enough journal credits for one
+	 * relink per alloc. */
+	ac->ac_allow_chain_relink = 0;
+	for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i ++) {
+		if (i == victim)
+			continue;
+		if (!cl->cl_recs[i].c_free)
+			continue;
+
+		ac->ac_chain = i;
+		status = ocfs2_search_chain(ac, bits_wanted, min_bits,
+					    bit_off, num_bits,
+					    bg_blkno);
+		if (!status)
+			break;
+		if (status < 0 && status != -ENOSPC) {
+			mlog_errno(status);
+			goto bail;
+		}
+	}
+bail:
+
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_claim_metadata(struct ocfs2_super *osb,
+			 struct ocfs2_journal_handle *handle,
+			 struct ocfs2_alloc_context *ac,
+			 u32 bits_wanted,
+			 u16 *suballoc_bit_start,
+			 unsigned int *num_bits,
+			 u64 *blkno_start)
+{
+	int status;
+	u64 bg_blkno;
+
+	BUG_ON(!ac);
+	BUG_ON(ac->ac_bits_wanted < (ac->ac_bits_given + bits_wanted));
+	BUG_ON(ac->ac_which != OCFS2_AC_USE_META);
+	BUG_ON(ac->ac_handle != handle);
+
+	status = ocfs2_claim_suballoc_bits(osb,
+					   ac,
+					   bits_wanted,
+					   1,
+					   suballoc_bit_start,
+					   num_bits,
+					   &bg_blkno);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	atomic_inc(&osb->alloc_stats.bg_allocs);
+
+	*blkno_start = bg_blkno + (u64) *suballoc_bit_start;
+	ac->ac_bits_given += (*num_bits);
+	status = 0;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+int ocfs2_claim_new_inode(struct ocfs2_super *osb,
+			  struct ocfs2_journal_handle *handle,
+			  struct ocfs2_alloc_context *ac,
+			  u16 *suballoc_bit,
+			  u64 *fe_blkno)
+{
+	int status;
+	unsigned int num_bits;
+	u64 bg_blkno;
+
+	mlog_entry_void();
+
+	BUG_ON(!ac);
+	BUG_ON(ac->ac_bits_given != 0);
+	BUG_ON(ac->ac_bits_wanted != 1);
+	BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE);
+	BUG_ON(ac->ac_handle != handle);
+
+	status = ocfs2_claim_suballoc_bits(osb,
+					   ac,
+					   1,
+					   1,
+					   suballoc_bit,
+					   &num_bits,
+					   &bg_blkno);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	atomic_inc(&osb->alloc_stats.bg_allocs);
+
+	BUG_ON(num_bits != 1);
+
+	*fe_blkno = bg_blkno + (u64) (*suballoc_bit);
+	ac->ac_bits_given++;
+	status = 0;
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/* translate a group desc. blkno and it's bitmap offset into
+ * disk cluster offset. */
+static inline u32 ocfs2_desc_bitmap_to_cluster_off(struct inode *inode,
+						   u64 bg_blkno,
+						   u16 bg_bit_off)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	u32 cluster = 0;
+
+	BUG_ON(!ocfs2_is_cluster_bitmap(inode));
+
+	if (bg_blkno != osb->first_cluster_group_blkno)
+		cluster = ocfs2_blocks_to_clusters(inode->i_sb, bg_blkno);
+	cluster += (u32) bg_bit_off;
+	return cluster;
+}
+
+/* given a cluster offset, calculate which block group it belongs to
+ * and return that block offset. */
+static inline u64 ocfs2_which_cluster_group(struct inode *inode,
+					    u32 cluster)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	u32 group_no;
+
+	BUG_ON(!ocfs2_is_cluster_bitmap(inode));
+
+	group_no = cluster / osb->bitmap_cpg;
+	if (!group_no)
+		return osb->first_cluster_group_blkno;
+	return ocfs2_clusters_to_blocks(inode->i_sb,
+					group_no * osb->bitmap_cpg);
+}
+
+/* given the block number of a cluster start, calculate which cluster
+ * group and descriptor bitmap offset that corresponds to. */
+static inline void ocfs2_block_to_cluster_group(struct inode *inode,
+						u64 data_blkno,
+						u64 *bg_blkno,
+						u16 *bg_bit_off)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	u32 data_cluster = ocfs2_blocks_to_clusters(osb->sb, data_blkno);
+
+	BUG_ON(!ocfs2_is_cluster_bitmap(inode));
+
+	*bg_blkno = ocfs2_which_cluster_group(inode,
+					      data_cluster);
+
+	if (*bg_blkno == osb->first_cluster_group_blkno)
+		*bg_bit_off = (u16) data_cluster;
+	else
+		*bg_bit_off = (u16) ocfs2_blocks_to_clusters(osb->sb,
+							     data_blkno - *bg_blkno);
+}
+
+/*
+ * min_bits - minimum contiguous chunk from this total allocation we
+ * can handle. set to what we asked for originally for a full
+ * contig. allocation, set to '1' to indicate we can deal with extents
+ * of any size.
+ */
+int ocfs2_claim_clusters(struct ocfs2_super *osb,
+			 struct ocfs2_journal_handle *handle,
+			 struct ocfs2_alloc_context *ac,
+			 u32 min_clusters,
+			 u32 *cluster_start,
+			 u32 *num_clusters)
+{
+	int status;
+	unsigned int bits_wanted = ac->ac_bits_wanted - ac->ac_bits_given;
+	u64 bg_blkno;
+	u16 bg_bit_off;
+
+	mlog_entry_void();
+
+	BUG_ON(!ac);
+	BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted);
+
+	BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL
+	       && ac->ac_which != OCFS2_AC_USE_MAIN);
+	BUG_ON(ac->ac_handle != handle);
+
+	if (ac->ac_which == OCFS2_AC_USE_LOCAL) {
+		status = ocfs2_claim_local_alloc_bits(osb,
+						      handle,
+						      ac,
+						      bits_wanted,
+						      cluster_start,
+						      num_clusters);
+		if (!status)
+			atomic_inc(&osb->alloc_stats.local_data);
+	} else {
+		if (min_clusters > (osb->bitmap_cpg - 1)) {
+			/* The only paths asking for contiguousness
+			 * should know about this already. */
+			mlog(ML_ERROR, "minimum allocation requested exceeds "
+				       "group bitmap size!");
+			status = -ENOSPC;
+			goto bail;
+		}
+		/* clamp the current request down to a realistic size. */
+		if (bits_wanted > (osb->bitmap_cpg - 1))
+			bits_wanted = osb->bitmap_cpg - 1;
+
+		status = ocfs2_claim_suballoc_bits(osb,
+						   ac,
+						   bits_wanted,
+						   min_clusters,
+						   &bg_bit_off,
+						   num_clusters,
+						   &bg_blkno);
+		if (!status) {
+			*cluster_start =
+				ocfs2_desc_bitmap_to_cluster_off(ac->ac_inode,
+								 bg_blkno,
+								 bg_bit_off);
+			atomic_inc(&osb->alloc_stats.bitmap_data);
+		}
+	}
+	if (status < 0) {
+		if (status != -ENOSPC)
+			mlog_errno(status);
+		goto bail;
+	}
+
+	ac->ac_bits_given += *num_clusters;
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static inline int ocfs2_block_group_clear_bits(struct ocfs2_journal_handle *handle,
+					       struct inode *alloc_inode,
+					       struct ocfs2_group_desc *bg,
+					       struct buffer_head *group_bh,
+					       unsigned int bit_off,
+					       unsigned int num_bits)
+{
+	int status;
+	unsigned int tmp;
+	int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;
+	struct ocfs2_group_desc *undo_bg = NULL;
+
+	mlog_entry_void();
+
+	if (!OCFS2_IS_VALID_GROUP_DESC(bg)) {
+		OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg);
+		status = -EIO;
+		goto bail;
+	}
+
+	mlog(0, "off = %u, num = %u\n", bit_off, num_bits);
+
+	if (ocfs2_is_cluster_bitmap(alloc_inode))
+		journal_type = OCFS2_JOURNAL_ACCESS_UNDO;
+
+	status = ocfs2_journal_access(handle, alloc_inode, group_bh,
+				      journal_type);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	if (ocfs2_is_cluster_bitmap(alloc_inode))
+		undo_bg = (struct ocfs2_group_desc *) bh2jh(group_bh)->b_committed_data;
+
+	tmp = num_bits;
+	while(tmp--) {
+		ocfs2_clear_bit((bit_off + tmp),
+				(unsigned long *) bg->bg_bitmap);
+		if (ocfs2_is_cluster_bitmap(alloc_inode))
+			ocfs2_set_bit(bit_off + tmp,
+				      (unsigned long *) undo_bg->bg_bitmap);
+	}
+	le16_add_cpu(&bg->bg_free_bits_count, num_bits);
+
+	status = ocfs2_journal_dirty(handle, group_bh);
+	if (status < 0)
+		mlog_errno(status);
+bail:
+	return status;
+}
+
+/*
+ * expects the suballoc inode to already be locked.
+ */
+static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle,
+				    struct inode *alloc_inode,
+				    struct buffer_head *alloc_bh,
+				    unsigned int start_bit,
+				    u64 bg_blkno,
+				    unsigned int count)
+{
+	int status = 0;
+	u32 tmp_used;
+	struct ocfs2_super *osb = OCFS2_SB(alloc_inode->i_sb);
+	struct ocfs2_dinode *fe = (struct ocfs2_dinode *) alloc_bh->b_data;
+	struct ocfs2_chain_list *cl = &fe->id2.i_chain;
+	struct buffer_head *group_bh = NULL;
+	struct ocfs2_group_desc *group;
+
+	mlog_entry_void();
+
+	if (!OCFS2_IS_VALID_DINODE(fe)) {
+		OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe);
+		status = -EIO;
+		goto bail;
+	}
+	BUG_ON((count + start_bit) > ocfs2_bits_per_group(cl));
+
+	mlog(0, "suballocator %"MLFu64": freeing %u bits from group %"MLFu64
+	     ", starting at %u\n",
+	     OCFS2_I(alloc_inode)->ip_blkno, count, bg_blkno,
+	     start_bit);
+
+	status = ocfs2_read_block(osb, bg_blkno, &group_bh, OCFS2_BH_CACHED,
+				  alloc_inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	group = (struct ocfs2_group_desc *) group_bh->b_data;
+	if (!OCFS2_IS_VALID_GROUP_DESC(group)) {
+		OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, group);
+		status = -EIO;
+		goto bail;
+	}
+	BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits));
+
+	status = ocfs2_block_group_clear_bits(handle, alloc_inode,
+					      group, group_bh,
+					      start_bit, count);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = ocfs2_journal_access(handle, alloc_inode, alloc_bh,
+				      OCFS2_JOURNAL_ACCESS_WRITE);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	le32_add_cpu(&cl->cl_recs[le16_to_cpu(group->bg_chain)].c_free,
+		     count);
+	tmp_used = le32_to_cpu(fe->id1.bitmap1.i_used);
+	fe->id1.bitmap1.i_used = cpu_to_le32(tmp_used - count);
+
+	status = ocfs2_journal_dirty(handle, alloc_bh);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+bail:
+	if (group_bh)
+		brelse(group_bh);
+
+	mlog_exit(status);
+	return status;
+}
+
+static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit)
+{
+	u64 group = block - (u64) bit;
+
+	return group;
+}
+
+int ocfs2_free_dinode(struct ocfs2_journal_handle *handle,
+		      struct inode *inode_alloc_inode,
+		      struct buffer_head *inode_alloc_bh,
+		      struct ocfs2_dinode *di)
+{
+	u64 blk = le64_to_cpu(di->i_blkno);
+	u16 bit = le16_to_cpu(di->i_suballoc_bit);
+	u64 bg_blkno = ocfs2_which_suballoc_group(blk, bit);
+
+	return ocfs2_free_suballoc_bits(handle, inode_alloc_inode,
+					inode_alloc_bh, bit, bg_blkno, 1);
+}
+
+int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle,
+			    struct inode *eb_alloc_inode,
+			    struct buffer_head *eb_alloc_bh,
+			    struct ocfs2_extent_block *eb)
+{
+	u64 blk = le64_to_cpu(eb->h_blkno);
+	u16 bit = le16_to_cpu(eb->h_suballoc_bit);
+	u64 bg_blkno = ocfs2_which_suballoc_group(blk, bit);
+
+	return ocfs2_free_suballoc_bits(handle, eb_alloc_inode, eb_alloc_bh,
+					bit, bg_blkno, 1);
+}
+
+int ocfs2_free_clusters(struct ocfs2_journal_handle *handle,
+		       struct inode *bitmap_inode,
+		       struct buffer_head *bitmap_bh,
+		       u64 start_blk,
+		       unsigned int num_clusters)
+{
+	int status;
+	u16 bg_start_bit;
+	u64 bg_blkno;
+	struct ocfs2_dinode *fe;
+
+	/* You can't ever have a contiguous set of clusters
+	 * bigger than a block group bitmap so we never have to worry
+	 * about looping on them. */
+
+	mlog_entry_void();
+
+	/* This is expensive. We can safely remove once this stuff has
+	 * gotten tested really well. */
+	BUG_ON(start_blk != ocfs2_clusters_to_blocks(bitmap_inode->i_sb, ocfs2_blocks_to_clusters(bitmap_inode->i_sb, start_blk)));
+
+	fe = (struct ocfs2_dinode *) bitmap_bh->b_data;
+
+	ocfs2_block_to_cluster_group(bitmap_inode, start_blk, &bg_blkno,
+				     &bg_start_bit);
+
+	mlog(0, "want to free %u clusters starting at block %"MLFu64"\n",
+	     num_clusters, start_blk);
+	mlog(0, "bg_blkno = %"MLFu64", bg_start_bit = %u\n",
+	     bg_blkno, bg_start_bit);
+
+	status = ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh,
+					  bg_start_bit, bg_blkno,
+					  num_clusters);
+	if (status < 0)
+		mlog_errno(status);
+
+	mlog_exit(status);
+	return status;
+}
+
+static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg)
+{
+	printk("Block Group:\n");
+	printk("bg_signature:       %s\n", bg->bg_signature);
+	printk("bg_size:            %u\n", bg->bg_size);
+	printk("bg_bits:            %u\n", bg->bg_bits);
+	printk("bg_free_bits_count: %u\n", bg->bg_free_bits_count);
+	printk("bg_chain:           %u\n", bg->bg_chain);
+	printk("bg_generation:      %u\n", le32_to_cpu(bg->bg_generation));
+	printk("bg_next_group:      %"MLFu64"\n", bg->bg_next_group);
+	printk("bg_parent_dinode:   %"MLFu64"\n", bg->bg_parent_dinode);
+	printk("bg_blkno:           %"MLFu64"\n", bg->bg_blkno);
+}
+
+static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe)
+{
+	int i;
+
+	printk("Suballoc Inode %"MLFu64":\n", fe->i_blkno);
+	printk("i_signature:                  %s\n", fe->i_signature);
+	printk("i_size:                       %"MLFu64"\n", fe->i_size);
+	printk("i_clusters:                   %u\n", fe->i_clusters);
+	printk("i_generation:                 %u\n",
+	       le32_to_cpu(fe->i_generation));
+	printk("id1.bitmap1.i_used:           %u\n",
+	       le32_to_cpu(fe->id1.bitmap1.i_used));
+	printk("id1.bitmap1.i_total:          %u\n",
+	       le32_to_cpu(fe->id1.bitmap1.i_total));
+	printk("id2.i_chain.cl_cpg:           %u\n", fe->id2.i_chain.cl_cpg);
+	printk("id2.i_chain.cl_bpc:           %u\n", fe->id2.i_chain.cl_bpc);
+	printk("id2.i_chain.cl_count:         %u\n", fe->id2.i_chain.cl_count);
+	printk("id2.i_chain.cl_next_free_rec: %u\n",
+	       fe->id2.i_chain.cl_next_free_rec);
+	for(i = 0; i < fe->id2.i_chain.cl_next_free_rec; i++) {
+		printk("fe->id2.i_chain.cl_recs[%d].c_free:  %u\n", i,
+		       fe->id2.i_chain.cl_recs[i].c_free);
+		printk("fe->id2.i_chain.cl_recs[%d].c_total: %u\n", i,
+		       fe->id2.i_chain.cl_recs[i].c_total);
+		printk("fe->id2.i_chain.cl_recs[%d].c_blkno: %"MLFu64"\n", i,
+		       fe->id2.i_chain.cl_recs[i].c_blkno);
+	}
+}
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
new file mode 100644
index 0000000..a76c82a
--- /dev/null
+++ b/fs/ocfs2/suballoc.h
@@ -0,0 +1,132 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * suballoc.h
+ *
+ * Defines sub allocator api
+ *
+ * Copyright (C) 2003, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef _CHAINALLOC_H_
+#define _CHAINALLOC_H_
+
+typedef int (group_search_t)(struct inode *,
+			     struct buffer_head *,
+			     u32,
+			     u32,
+			     u16 *,
+			     u16 *);
+
+struct ocfs2_alloc_context {
+	struct inode *ac_inode;    /* which bitmap are we allocating from? */
+	struct buffer_head *ac_bh; /* file entry bh */
+	u32    ac_bits_wanted;
+	u32    ac_bits_given;
+#define OCFS2_AC_USE_LOCAL 1
+#define OCFS2_AC_USE_MAIN  2
+#define OCFS2_AC_USE_INODE 3
+#define OCFS2_AC_USE_META  4
+	u32    ac_which;
+	struct ocfs2_journal_handle *ac_handle;
+
+	/* these are used by the chain search */
+	u16    ac_chain;
+	int    ac_allow_chain_relink;
+	group_search_t *ac_group_search;
+};
+
+void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac);
+static inline int ocfs2_alloc_context_bits_left(struct ocfs2_alloc_context *ac)
+{
+	return ac->ac_bits_wanted - ac->ac_bits_given;
+}
+
+int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
+			       struct ocfs2_journal_handle *handle,
+			       struct ocfs2_dinode *fe,
+			       struct ocfs2_alloc_context **ac);
+int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
+			    struct ocfs2_journal_handle *handle,
+			    struct ocfs2_alloc_context **ac);
+int ocfs2_reserve_clusters(struct ocfs2_super *osb,
+			   struct ocfs2_journal_handle *handle,
+			   u32 bits_wanted,
+			   struct ocfs2_alloc_context **ac);
+
+int ocfs2_claim_metadata(struct ocfs2_super *osb,
+			 struct ocfs2_journal_handle *handle,
+			 struct ocfs2_alloc_context *ac,
+			 u32 bits_wanted,
+			 u16 *suballoc_bit_start,
+			 u32 *num_bits,
+			 u64 *blkno_start);
+int ocfs2_claim_new_inode(struct ocfs2_super *osb,
+			  struct ocfs2_journal_handle *handle,
+			  struct ocfs2_alloc_context *ac,
+			  u16 *suballoc_bit,
+			  u64 *fe_blkno);
+int ocfs2_claim_clusters(struct ocfs2_super *osb,
+			 struct ocfs2_journal_handle *handle,
+			 struct ocfs2_alloc_context *ac,
+			 u32 min_clusters,
+			 u32 *cluster_start,
+			 u32 *num_clusters);
+
+int ocfs2_free_dinode(struct ocfs2_journal_handle *handle,
+		      struct inode *inode_alloc_inode,
+		      struct buffer_head *inode_alloc_bh,
+		      struct ocfs2_dinode *di);
+int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle,
+			    struct inode *eb_alloc_inode,
+			    struct buffer_head *eb_alloc_bh,
+			    struct ocfs2_extent_block *eb);
+int ocfs2_free_clusters(struct ocfs2_journal_handle *handle,
+			struct inode *bitmap_inode,
+			struct buffer_head *bitmap_bh,
+			u64 start_blk,
+			unsigned int num_clusters);
+
+static inline u32 ocfs2_cluster_from_desc(struct ocfs2_super *osb,
+					  u64 bg_blkno)
+{
+	/* This should work for all block group descriptors as only
+	 * the 1st group descriptor of the cluster bitmap is
+	 * different. */
+
+	if (bg_blkno == osb->first_cluster_group_blkno)
+		return 0;
+
+	/* the rest of the block groups are located at the beginning
+	 * of their 1st cluster, so a direct translation just
+	 * works. */
+	return ocfs2_blocks_to_clusters(osb->sb, bg_blkno);
+}
+
+static inline int ocfs2_is_cluster_bitmap(struct inode *inode)
+{
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	return osb->bitmap_blkno == OCFS2_I(inode)->ip_blkno;
+}
+
+/* This is for local alloc ONLY. Others should use the task-specific
+ * apis above. */
+int ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb,
+				      struct ocfs2_alloc_context *ac);
+
+#endif /* _CHAINALLOC_H_ */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
new file mode 100644
index 0000000..48bf7f0
--- /dev/null
+++ b/fs/ocfs2/super.c
@@ -0,0 +1,1733 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * super.c
+ *
+ * load/unload driver, mount/dismount volumes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/random.h>
+#include <linux/statfs.h>
+#include <linux/moduleparam.h>
+#include <linux/blkdev.h>
+#include <linux/socket.h>
+#include <linux/inet.h>
+#include <linux/parser.h>
+#include <linux/crc32.h>
+#include <linux/debugfs.h>
+
+#include <cluster/nodemanager.h>
+
+#define MLOG_MASK_PREFIX ML_SUPER
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+/* this should be the only file to include a version 1 header */
+#include "ocfs1_fs_compat.h"
+
+#include "alloc.h"
+#include "dlmglue.h"
+#include "export.h"
+#include "extent_map.h"
+#include "heartbeat.h"
+#include "inode.h"
+#include "journal.h"
+#include "localalloc.h"
+#include "namei.h"
+#include "slot_map.h"
+#include "super.h"
+#include "sysfile.h"
+#include "uptodate.h"
+#include "ver.h"
+#include "vote.h"
+
+#include "buffer_head_io.h"
+
+/*
+ * Globals
+ */
+static spinlock_t ocfs2_globals_lock = SPIN_LOCK_UNLOCKED;
+
+static u32 osb_id;             /* Keeps track of next available OSB Id */
+
+static kmem_cache_t *ocfs2_inode_cachep = NULL;
+
+kmem_cache_t *ocfs2_lock_cache = NULL;
+
+/* OCFS2 needs to schedule several differnt types of work which
+ * require cluster locking, disk I/O, recovery waits, etc. Since these
+ * types of work tend to be heavy we avoid using the kernel events
+ * workqueue and schedule on our own. */
+struct workqueue_struct *ocfs2_wq = NULL;
+
+static struct dentry *ocfs2_debugfs_root = NULL;
+
+MODULE_AUTHOR("Oracle");
+MODULE_LICENSE("GPL");
+
+static int ocfs2_parse_options(struct super_block *sb, char *options,
+			       unsigned long *mount_opt, int is_remount);
+static void ocfs2_put_super(struct super_block *sb);
+static int ocfs2_mount_volume(struct super_block *sb);
+static int ocfs2_remount(struct super_block *sb, int *flags, char *data);
+static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err);
+static int ocfs2_initialize_mem_caches(void);
+static void ocfs2_free_mem_caches(void);
+static void ocfs2_delete_osb(struct ocfs2_super *osb);
+
+static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf);
+
+static int ocfs2_sync_fs(struct super_block *sb, int wait);
+
+static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb);
+static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb);
+static int ocfs2_release_system_inodes(struct ocfs2_super *osb);
+static int ocfs2_fill_local_node_info(struct ocfs2_super *osb);
+static int ocfs2_check_volume(struct ocfs2_super *osb);
+static int ocfs2_verify_volume(struct ocfs2_dinode *di,
+			       struct buffer_head *bh,
+			       u32 sectsize);
+static int ocfs2_initialize_super(struct super_block *sb,
+				  struct buffer_head *bh,
+				  int sector_size);
+static int ocfs2_get_sector(struct super_block *sb,
+			    struct buffer_head **bh,
+			    int block,
+			    int sect_size);
+static void ocfs2_write_super(struct super_block *sb);
+static struct inode *ocfs2_alloc_inode(struct super_block *sb);
+static void ocfs2_destroy_inode(struct inode *inode);
+
+static unsigned long long ocfs2_max_file_offset(unsigned int blockshift);
+
+static struct super_operations ocfs2_sops = {
+	.statfs		= ocfs2_statfs,
+	.alloc_inode	= ocfs2_alloc_inode,
+	.destroy_inode	= ocfs2_destroy_inode,
+	.drop_inode	= ocfs2_drop_inode,
+	.clear_inode	= ocfs2_clear_inode,
+	.delete_inode	= ocfs2_delete_inode,
+	.sync_fs	= ocfs2_sync_fs,
+	.write_super	= ocfs2_write_super,
+	.put_super	= ocfs2_put_super,
+	.remount_fs	= ocfs2_remount,
+};
+
+enum {
+	Opt_barrier,
+	Opt_err_panic,
+	Opt_err_ro,
+	Opt_intr,
+	Opt_nointr,
+	Opt_hb_none,
+	Opt_hb_local,
+	Opt_data_ordered,
+	Opt_data_writeback,
+	Opt_err,
+};
+
+static match_table_t tokens = {
+	{Opt_barrier, "barrier=%u"},
+	{Opt_err_panic, "errors=panic"},
+	{Opt_err_ro, "errors=remount-ro"},
+	{Opt_intr, "intr"},
+	{Opt_nointr, "nointr"},
+	{Opt_hb_none, OCFS2_HB_NONE},
+	{Opt_hb_local, OCFS2_HB_LOCAL},
+	{Opt_data_ordered, "data=ordered"},
+	{Opt_data_writeback, "data=writeback"},
+	{Opt_err, NULL}
+};
+
+/*
+ * write_super and sync_fs ripped right out of ext3.
+ */
+static void ocfs2_write_super(struct super_block *sb)
+{
+	if (down_trylock(&sb->s_lock) == 0)
+		BUG();
+	sb->s_dirt = 0;
+}
+
+static int ocfs2_sync_fs(struct super_block *sb, int wait)
+{
+	int status = 0;
+	tid_t target;
+	struct ocfs2_super *osb = OCFS2_SB(sb);
+
+	sb->s_dirt = 0;
+
+	if (ocfs2_is_hard_readonly(osb))
+		return -EROFS;
+
+	if (wait) {
+		status = ocfs2_flush_truncate_log(osb);
+		if (status < 0)
+			mlog_errno(status);
+	} else {
+		ocfs2_schedule_truncate_log_flush(osb, 0);
+	}
+
+	if (journal_start_commit(OCFS2_SB(sb)->journal->j_journal, &target)) {
+		if (wait)
+			log_wait_commit(OCFS2_SB(sb)->journal->j_journal,
+					target);
+	}
+	return 0;
+}
+
+static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb)
+{
+	struct inode *new = NULL;
+	int status = 0;
+	int i;
+
+	mlog_entry_void();
+
+	new = ocfs2_iget(osb, osb->root_blkno);
+	if (IS_ERR(new)) {
+		status = PTR_ERR(new);
+		mlog_errno(status);
+		goto bail;
+	}
+	osb->root_inode = new;
+
+	new = ocfs2_iget(osb, osb->system_dir_blkno);
+	if (IS_ERR(new)) {
+		status = PTR_ERR(new);
+		mlog_errno(status);
+		goto bail;
+	}
+	osb->sys_root_inode = new;
+
+	for (i = OCFS2_FIRST_ONLINE_SYSTEM_INODE;
+	     i <= OCFS2_LAST_GLOBAL_SYSTEM_INODE; i++) {
+		new = ocfs2_get_system_file_inode(osb, i, osb->slot_num);
+		if (!new) {
+			ocfs2_release_system_inodes(osb);
+			status = -EINVAL;
+			mlog_errno(status);
+			/* FIXME: Should ERROR_RO_FS */
+			mlog(ML_ERROR, "Unable to load system inode %d, "
+			     "possibly corrupt fs?", i);
+			goto bail;
+		}
+		// the array now has one ref, so drop this one
+		iput(new);
+	}
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb)
+{
+	struct inode *new = NULL;
+	int status = 0;
+	int i;
+
+	mlog_entry_void();
+
+	for (i = OCFS2_LAST_GLOBAL_SYSTEM_INODE + 1;
+	     i < NUM_SYSTEM_INODES;
+	     i++) {
+		new = ocfs2_get_system_file_inode(osb, i, osb->slot_num);
+		if (!new) {
+			ocfs2_release_system_inodes(osb);
+			status = -EINVAL;
+			mlog(ML_ERROR, "status=%d, sysfile=%d, slot=%d\n",
+			     status, i, osb->slot_num);
+			goto bail;
+		}
+		/* the array now has one ref, so drop this one */
+		iput(new);
+	}
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_release_system_inodes(struct ocfs2_super *osb)
+{
+	int status = 0, i;
+	struct inode *inode;
+
+	mlog_entry_void();
+
+	for (i = 0; i < NUM_SYSTEM_INODES; i++) {
+		inode = osb->system_inodes[i];
+		if (inode) {
+			iput(inode);
+			osb->system_inodes[i] = NULL;
+		}
+	}
+
+	inode = osb->sys_root_inode;
+	if (inode) {
+		iput(inode);
+		osb->sys_root_inode = NULL;
+	}
+
+	inode = osb->root_inode;
+	if (inode) {
+		iput(inode);
+		osb->root_inode = NULL;
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+/* We're allocating fs objects, use GFP_NOFS */
+static struct inode *ocfs2_alloc_inode(struct super_block *sb)
+{
+	struct ocfs2_inode_info *oi;
+
+	oi = kmem_cache_alloc(ocfs2_inode_cachep, SLAB_NOFS);
+	if (!oi)
+		return NULL;
+
+	return &oi->vfs_inode;
+}
+
+static void ocfs2_destroy_inode(struct inode *inode)
+{
+	kmem_cache_free(ocfs2_inode_cachep, OCFS2_I(inode));
+}
+
+/* From xfs_super.c:xfs_max_file_offset
+ * Copyright (c) 2000-2004 Silicon Graphics, Inc.
+ */
+static unsigned long long ocfs2_max_file_offset(unsigned int blockshift)
+{
+	unsigned int pagefactor = 1;
+	unsigned int bitshift = BITS_PER_LONG - 1;
+
+	/* Figure out maximum filesize, on Linux this can depend on
+	 * the filesystem blocksize (on 32 bit platforms).
+	 * __block_prepare_write does this in an [unsigned] long...
+	 *      page->index << (PAGE_CACHE_SHIFT - bbits)
+	 * So, for page sized blocks (4K on 32 bit platforms),
+	 * this wraps at around 8Tb (hence MAX_LFS_FILESIZE which is
+	 *      (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
+	 * but for smaller blocksizes it is less (bbits = log2 bsize).
+	 * Note1: get_block_t takes a long (implicit cast from above)
+	 * Note2: The Large Block Device (LBD and HAVE_SECTOR_T) patch
+	 * can optionally convert the [unsigned] long from above into
+	 * an [unsigned] long long.
+	 */
+
+#if BITS_PER_LONG == 32
+# if defined(CONFIG_LBD)
+	BUG_ON(sizeof(sector_t) != 8);
+	pagefactor = PAGE_CACHE_SIZE;
+	bitshift = BITS_PER_LONG;
+# else
+	pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift);
+# endif
+#endif
+
+	return (((unsigned long long)pagefactor) << bitshift) - 1;
+}
+
+static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
+{
+	int incompat_features;
+	int ret = 0;
+	unsigned long parsed_options;
+	struct ocfs2_super *osb = OCFS2_SB(sb);
+
+	if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if ((osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) !=
+	    (parsed_options & OCFS2_MOUNT_HB_LOCAL)) {
+		ret = -EINVAL;
+		mlog(ML_ERROR, "Cannot change heartbeat mode on remount\n");
+		goto out;
+	}
+
+	if ((osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK) !=
+	    (parsed_options & OCFS2_MOUNT_DATA_WRITEBACK)) {
+		ret = -EINVAL;
+		mlog(ML_ERROR, "Cannot change data mode on remount\n");
+		goto out;
+	}
+
+	/* We're going to/from readonly mode. */
+	if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
+		/* Lock here so the check of HARD_RO and the potential
+		 * setting of SOFT_RO is atomic. */
+		spin_lock(&osb->osb_lock);
+		if (osb->osb_flags & OCFS2_OSB_HARD_RO) {
+			mlog(ML_ERROR, "Remount on readonly device is forbidden.\n");
+			ret = -EROFS;
+			goto unlock_osb;
+		}
+
+		if (*flags & MS_RDONLY) {
+			mlog(0, "Going to ro mode.\n");
+			sb->s_flags |= MS_RDONLY;
+			osb->osb_flags |= OCFS2_OSB_SOFT_RO;
+		} else {
+			mlog(0, "Making ro filesystem writeable.\n");
+
+			if (osb->osb_flags & OCFS2_OSB_ERROR_FS) {
+				mlog(ML_ERROR, "Cannot remount RDWR "
+				     "filesystem due to previous errors.\n");
+				ret = -EROFS;
+				goto unlock_osb;
+			}
+			incompat_features = OCFS2_HAS_RO_COMPAT_FEATURE(sb, ~OCFS2_FEATURE_RO_COMPAT_SUPP);
+			if (incompat_features) {
+				mlog(ML_ERROR, "Cannot remount RDWR because "
+				     "of unsupported optional features "
+				     "(%x).\n", incompat_features);
+				ret = -EINVAL;
+				goto unlock_osb;
+			}
+			sb->s_flags &= ~MS_RDONLY;
+			osb->osb_flags &= ~OCFS2_OSB_SOFT_RO;
+		}
+unlock_osb:
+		spin_unlock(&osb->osb_lock);
+	}
+
+	if (!ret) {
+		if (!ocfs2_is_hard_readonly(osb))
+			ocfs2_set_journal_params(osb);
+
+		/* Only save off the new mount options in case of a successful
+		 * remount. */
+		osb->s_mount_opt = parsed_options;
+	}
+out:
+	return ret;
+}
+
+static int ocfs2_sb_probe(struct super_block *sb,
+			  struct buffer_head **bh,
+			  int *sector_size)
+{
+	int status = 0, tmpstat;
+	struct ocfs1_vol_disk_hdr *hdr;
+	struct ocfs2_dinode *di;
+	int blksize;
+
+	*bh = NULL;
+
+	/* may be > 512 */
+	*sector_size = bdev_hardsect_size(sb->s_bdev);
+	if (*sector_size > OCFS2_MAX_BLOCKSIZE) {
+		mlog(ML_ERROR, "Hardware sector size too large: %d (max=%d)\n",
+		     *sector_size, OCFS2_MAX_BLOCKSIZE);
+		status = -EINVAL;
+		goto bail;
+	}
+
+	/* Can this really happen? */
+	if (*sector_size < OCFS2_MIN_BLOCKSIZE)
+		*sector_size = OCFS2_MIN_BLOCKSIZE;
+
+	/* check block zero for old format */
+	status = ocfs2_get_sector(sb, bh, 0, *sector_size);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+	hdr = (struct ocfs1_vol_disk_hdr *) (*bh)->b_data;
+	if (hdr->major_version == OCFS1_MAJOR_VERSION) {
+		mlog(ML_ERROR, "incompatible version: %u.%u\n",
+		     hdr->major_version, hdr->minor_version);
+		status = -EINVAL;
+	}
+	if (memcmp(hdr->signature, OCFS1_VOLUME_SIGNATURE,
+		   strlen(OCFS1_VOLUME_SIGNATURE)) == 0) {
+		mlog(ML_ERROR, "incompatible volume signature: %8s\n",
+		     hdr->signature);
+		status = -EINVAL;
+	}
+	brelse(*bh);
+	*bh = NULL;
+	if (status < 0) {
+		mlog(ML_ERROR, "This is an ocfs v1 filesystem which must be "
+		     "upgraded before mounting with ocfs v2\n");
+		goto bail;
+	}
+
+	/*
+	 * Now check at magic offset for 512, 1024, 2048, 4096
+	 * blocksizes.  4096 is the maximum blocksize because it is
+	 * the minimum clustersize.
+	 */
+	status = -EINVAL;
+	for (blksize = *sector_size;
+	     blksize <= OCFS2_MAX_BLOCKSIZE;
+	     blksize <<= 1) {
+		tmpstat = ocfs2_get_sector(sb, bh,
+					   OCFS2_SUPER_BLOCK_BLKNO,
+					   blksize);
+		if (tmpstat < 0) {
+			status = tmpstat;
+			mlog_errno(status);
+			goto bail;
+		}
+		di = (struct ocfs2_dinode *) (*bh)->b_data;
+		status = ocfs2_verify_volume(di, *bh, blksize);
+		if (status >= 0)
+			goto bail;
+		brelse(*bh);
+		*bh = NULL;
+		if (status != -EAGAIN)
+			break;
+	}
+
+bail:
+	return status;
+}
+
+static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
+{
+	struct dentry *root;
+	int status, sector_size;
+	unsigned long parsed_opt;
+	struct inode *inode = NULL;
+	struct ocfs2_super *osb = NULL;
+	struct buffer_head *bh = NULL;
+
+	mlog_entry("%p, %p, %i", sb, data, silent);
+
+	/* for now we only have one cluster/node, make sure we see it
+	 * in the heartbeat universe */
+	if (!o2hb_check_local_node_heartbeating()) {
+		status = -EINVAL;
+		goto read_super_error;
+	}
+
+	/* probe for superblock */
+	status = ocfs2_sb_probe(sb, &bh, &sector_size);
+	if (status < 0) {
+		mlog(ML_ERROR, "superblock probe failed!\n");
+		goto read_super_error;
+	}
+
+	status = ocfs2_initialize_super(sb, bh, sector_size);
+	osb = OCFS2_SB(sb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto read_super_error;
+	}
+	brelse(bh);
+	bh = NULL;
+
+	if (!ocfs2_parse_options(sb, data, &parsed_opt, 0)) {
+		status = -EINVAL;
+		goto read_super_error;
+	}
+	osb->s_mount_opt = parsed_opt;
+
+	sb->s_magic = OCFS2_SUPER_MAGIC;
+
+	/* Hard readonly mode only if: bdev_read_only, MS_RDONLY,
+	 * heartbeat=none */
+	if (bdev_read_only(sb->s_bdev)) {
+		if (!(sb->s_flags & MS_RDONLY)) {
+			status = -EACCES;
+			mlog(ML_ERROR, "Readonly device detected but readonly "
+			     "mount was not specified.\n");
+			goto read_super_error;
+		}
+
+		/* You should not be able to start a local heartbeat
+		 * on a readonly device. */
+		if (osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL) {
+			status = -EROFS;
+			mlog(ML_ERROR, "Local heartbeat specified on readonly "
+			     "device.\n");
+			goto read_super_error;
+		}
+
+		status = ocfs2_check_journals_nolocks(osb);
+		if (status < 0) {
+			if (status == -EROFS)
+				mlog(ML_ERROR, "Recovery required on readonly "
+				     "file system, but write access is "
+				     "unavailable.\n");
+			else
+				mlog_errno(status);			
+			goto read_super_error;
+		}
+
+		ocfs2_set_ro_flag(osb, 1);
+
+		printk(KERN_NOTICE "Readonly device detected. No cluster "
+		       "services will be utilized for this mount. Recovery "
+		       "will be skipped.\n");
+	}
+
+	if (!ocfs2_is_hard_readonly(osb)) {
+		/* If this isn't a hard readonly mount, then we need
+		 * to make sure that heartbeat is in a valid state,
+		 * and that we mark ourselves soft readonly is -oro
+		 * was specified. */
+		if (!(osb->s_mount_opt & OCFS2_MOUNT_HB_LOCAL)) {
+			mlog(ML_ERROR, "No heartbeat for device (%s)\n",
+			     sb->s_id);
+			status = -EINVAL;
+			goto read_super_error;
+		}
+
+		if (sb->s_flags & MS_RDONLY)
+			ocfs2_set_ro_flag(osb, 0);
+	}
+
+	osb->osb_debug_root = debugfs_create_dir(osb->uuid_str,
+						 ocfs2_debugfs_root);
+	if (!osb->osb_debug_root) {
+		status = -EINVAL;
+		mlog(ML_ERROR, "Unable to create per-mount debugfs root.\n");
+		goto read_super_error;
+	}
+
+	status = ocfs2_mount_volume(sb);
+	if (osb->root_inode)
+		inode = igrab(osb->root_inode);
+
+	if (status < 0)
+		goto read_super_error;
+
+	if (!inode) {
+		status = -EIO;
+		mlog_errno(status);
+		goto read_super_error;
+	}
+
+	root = d_alloc_root(inode);
+	if (!root) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto read_super_error;
+	}
+
+	sb->s_root = root;
+
+	ocfs2_complete_mount_recovery(osb);
+
+	printk("ocfs2: Mounting device (%u,%u) on (node %d, slot %d) with %s "
+	       "data mode.\n",
+	       MAJOR(sb->s_dev), MINOR(sb->s_dev), osb->node_num,
+	       osb->slot_num,
+	       osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" :
+	       "ordered");
+
+	atomic_set(&osb->vol_state, VOLUME_MOUNTED);
+	wake_up(&osb->osb_mount_event);
+
+	mlog_exit(status);
+	return status;
+
+read_super_error:
+	if (bh != NULL)
+		brelse(bh);
+
+	if (inode)
+		iput(inode);
+
+	if (osb) {
+		atomic_set(&osb->vol_state, VOLUME_DISABLED);
+		wake_up(&osb->osb_mount_event);
+		ocfs2_dismount_volume(sb, 1);
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+static struct super_block *ocfs2_get_sb(struct file_system_type *fs_type,
+					int flags,
+					const char *dev_name,
+					void *data)
+{
+	return get_sb_bdev(fs_type, flags, dev_name, data, ocfs2_fill_super);
+}
+
+static struct file_system_type ocfs2_fs_type = {
+	.owner          = THIS_MODULE,
+	.name           = "ocfs2",
+	.get_sb         = ocfs2_get_sb, /* is this called when we mount
+					* the fs? */
+	.kill_sb        = kill_block_super, /* set to the generic one
+					     * right now, but do we
+					     * need to change that? */
+	.fs_flags       = FS_REQUIRES_DEV,
+	.next           = NULL
+};
+
+static int ocfs2_parse_options(struct super_block *sb,
+			       char *options,
+			       unsigned long *mount_opt,
+			       int is_remount)
+{
+	int status;
+	char *p;
+
+	mlog_entry("remount: %d, options: \"%s\"\n", is_remount,
+		   options ? options : "(none)");
+
+	*mount_opt = 0;
+
+	if (!options) {
+		status = 1;
+		goto bail;
+	}
+
+	while ((p = strsep(&options, ",")) != NULL) {
+		int token, option;
+		substring_t args[MAX_OPT_ARGS];
+
+		if (!*p)
+			continue;
+
+		token = match_token(p, tokens, args);
+		switch (token) {
+		case Opt_hb_local:
+			*mount_opt |= OCFS2_MOUNT_HB_LOCAL;
+			break;
+		case Opt_hb_none:
+			*mount_opt &= ~OCFS2_MOUNT_HB_LOCAL;
+			break;
+		case Opt_barrier:
+			if (match_int(&args[0], &option)) {
+				status = 0;
+				goto bail;
+			}
+			if (option)
+				*mount_opt |= OCFS2_MOUNT_BARRIER;
+			else
+				*mount_opt &= ~OCFS2_MOUNT_BARRIER;
+			break;
+		case Opt_intr:
+			*mount_opt &= ~OCFS2_MOUNT_NOINTR;
+			break;
+		case Opt_nointr:
+			*mount_opt |= OCFS2_MOUNT_NOINTR;
+			break;
+		case Opt_err_panic:
+			*mount_opt |= OCFS2_MOUNT_ERRORS_PANIC;
+			break;
+		case Opt_err_ro:
+			*mount_opt &= ~OCFS2_MOUNT_ERRORS_PANIC;
+			break;
+		case Opt_data_ordered:
+			*mount_opt &= ~OCFS2_MOUNT_DATA_WRITEBACK;
+			break;
+		case Opt_data_writeback:
+			*mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;
+			break;
+		default:
+			mlog(ML_ERROR,
+			     "Unrecognized mount option \"%s\" "
+			     "or missing value\n", p);
+			status = 0;
+			goto bail;
+		}
+	}
+
+	status = 1;
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+static int __init ocfs2_init(void)
+{
+	int status;
+
+	mlog_entry_void();
+
+	ocfs2_print_version();
+
+	if (init_ocfs2_extent_maps())
+		return -ENOMEM;
+
+	status = init_ocfs2_uptodate_cache();
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_initialize_mem_caches();
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	ocfs2_wq = create_singlethread_workqueue("ocfs2_wq");
+	if (!ocfs2_wq) {
+		status = -ENOMEM;
+		goto leave;
+	}
+
+	spin_lock(&ocfs2_globals_lock);
+	osb_id = 0;
+	spin_unlock(&ocfs2_globals_lock);
+
+	ocfs2_debugfs_root = debugfs_create_dir("ocfs2", NULL);
+	if (!ocfs2_debugfs_root) {
+		status = -EFAULT;
+		mlog(ML_ERROR, "Unable to create ocfs2 debugfs root.\n");
+	}
+
+leave:
+	if (status < 0) {
+		ocfs2_free_mem_caches();
+		exit_ocfs2_uptodate_cache();
+		exit_ocfs2_extent_maps();
+	}
+
+	mlog_exit(status);
+
+	if (status >= 0) {
+		return register_filesystem(&ocfs2_fs_type);
+	} else
+		return -1;
+}
+
+static void __exit ocfs2_exit(void)
+{
+	mlog_entry_void();
+
+	if (ocfs2_wq) {
+		flush_workqueue(ocfs2_wq);
+		destroy_workqueue(ocfs2_wq);
+	}
+
+	debugfs_remove(ocfs2_debugfs_root);
+
+	ocfs2_free_mem_caches();
+
+	unregister_filesystem(&ocfs2_fs_type);
+
+	exit_ocfs2_extent_maps();
+
+	exit_ocfs2_uptodate_cache();
+
+	mlog_exit_void();
+}
+
+static void ocfs2_put_super(struct super_block *sb)
+{
+	mlog_entry("(0x%p)\n", sb);
+
+	ocfs2_sync_blockdev(sb);
+	ocfs2_dismount_volume(sb, 0);
+
+	mlog_exit_void();
+}
+
+static int ocfs2_statfs(struct super_block *sb, struct kstatfs *buf)
+{
+	struct ocfs2_super *osb;
+	u32 numbits, freebits;
+	int status;
+	struct ocfs2_dinode *bm_lock;
+	struct buffer_head *bh = NULL;
+	struct inode *inode = NULL;
+
+	mlog_entry("(%p, %p)\n", sb, buf);
+
+	osb = OCFS2_SB(sb);
+
+	inode = ocfs2_get_system_file_inode(osb,
+					    GLOBAL_BITMAP_SYSTEM_INODE,
+					    OCFS2_INVALID_SLOT);
+	if (!inode) {
+		mlog(ML_ERROR, "failed to get bitmap inode\n");
+		status = -EIO;
+		goto bail;
+	}
+
+	status = ocfs2_meta_lock(inode, NULL, &bh, 0);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	bm_lock = (struct ocfs2_dinode *) bh->b_data;
+
+	numbits = le32_to_cpu(bm_lock->id1.bitmap1.i_total);
+	freebits = numbits - le32_to_cpu(bm_lock->id1.bitmap1.i_used);
+
+	buf->f_type = OCFS2_SUPER_MAGIC;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_namelen = OCFS2_MAX_FILENAME_LEN;
+	buf->f_blocks = ((sector_t) numbits) *
+			(osb->s_clustersize >> osb->sb->s_blocksize_bits);
+	buf->f_bfree = ((sector_t) freebits) *
+		       (osb->s_clustersize >> osb->sb->s_blocksize_bits);
+	buf->f_bavail = buf->f_bfree;
+	buf->f_files = numbits;
+	buf->f_ffree = freebits;
+
+	brelse(bh);
+
+	ocfs2_meta_unlock(inode, 0);
+	status = 0;
+bail:
+	if (inode)
+		iput(inode);
+
+	mlog_exit(status);
+
+	return status;
+}
+
+static void ocfs2_inode_init_once(void *data,
+				  kmem_cache_t *cachep,
+				  unsigned long flags)
+{
+	struct ocfs2_inode_info *oi = data;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		oi->ip_flags = 0;
+		oi->ip_open_count = 0;
+		spin_lock_init(&oi->ip_lock);
+		ocfs2_extent_map_init(&oi->vfs_inode);
+		INIT_LIST_HEAD(&oi->ip_handle_list);
+		INIT_LIST_HEAD(&oi->ip_io_markers);
+		oi->ip_handle = NULL;
+		oi->ip_created_trans = 0;
+		oi->ip_last_trans = 0;
+		oi->ip_dir_start_lookup = 0;
+
+		init_rwsem(&oi->ip_alloc_sem);
+		init_MUTEX(&(oi->ip_io_sem));
+
+		oi->ip_blkno = 0ULL;
+		oi->ip_clusters = 0;
+
+		ocfs2_lock_res_init_once(&oi->ip_rw_lockres);
+		ocfs2_lock_res_init_once(&oi->ip_meta_lockres);
+		ocfs2_lock_res_init_once(&oi->ip_data_lockres);
+
+		ocfs2_metadata_cache_init(&oi->vfs_inode);
+
+		inode_init_once(&oi->vfs_inode);
+	}
+}
+
+static int ocfs2_initialize_mem_caches(void)
+{
+	ocfs2_inode_cachep = kmem_cache_create("ocfs2_inode_cache",
+					       sizeof(struct ocfs2_inode_info),
+					       0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
+					       ocfs2_inode_init_once, NULL);
+	if (!ocfs2_inode_cachep)
+		return -ENOMEM;
+
+	ocfs2_lock_cache = kmem_cache_create("ocfs2_lock",
+					     sizeof(struct ocfs2_journal_lock),
+					     0,
+					     SLAB_NO_REAP|SLAB_HWCACHE_ALIGN,
+					     NULL, NULL);
+	if (!ocfs2_lock_cache)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static void ocfs2_free_mem_caches(void)
+{
+	if (ocfs2_inode_cachep)
+		kmem_cache_destroy(ocfs2_inode_cachep);
+	if (ocfs2_lock_cache)
+		kmem_cache_destroy(ocfs2_lock_cache);
+
+	ocfs2_inode_cachep = NULL;
+	ocfs2_lock_cache = NULL;
+}
+
+static int ocfs2_get_sector(struct super_block *sb,
+			    struct buffer_head **bh,
+			    int block,
+			    int sect_size)
+{
+	if (!sb_set_blocksize(sb, sect_size)) {
+		mlog(ML_ERROR, "unable to set blocksize\n");
+		return -EIO;
+	}
+
+	*bh = sb_getblk(sb, block);
+	if (!*bh) {
+		mlog_errno(-EIO);
+		return -EIO;
+	}
+	lock_buffer(*bh);
+	if (!buffer_dirty(*bh))
+		clear_buffer_uptodate(*bh);
+	unlock_buffer(*bh);
+	ll_rw_block(READ, 1, bh);
+	wait_on_buffer(*bh);
+	return 0;
+}
+
+/* ocfs2 1.0 only allows one cluster and node identity per kernel image. */
+static int ocfs2_fill_local_node_info(struct ocfs2_super *osb)
+{
+	int status;
+
+	/* XXX hold a ref on the node while mounte?  easy enough, if
+	 * desirable. */
+	osb->node_num = o2nm_this_node();
+	if (osb->node_num == O2NM_MAX_NODES) {
+		mlog(ML_ERROR, "could not find this host's node number\n");
+		status = -ENOENT;
+		goto bail;
+	}
+
+	mlog(ML_NOTICE, "I am node %d\n", osb->node_num);
+
+	status = 0;
+bail:
+	return status;
+}
+
+static int ocfs2_mount_volume(struct super_block *sb)
+{
+	int status = 0;
+	int unlock_super = 0;
+	struct ocfs2_super *osb = OCFS2_SB(sb);
+
+	mlog_entry_void();
+
+	if (ocfs2_is_hard_readonly(osb))
+		goto leave;
+
+	status = ocfs2_fill_local_node_info(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_register_hb_callbacks(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_dlm_init(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	/* requires vote_thread to be running. */
+	status = ocfs2_register_net_handlers(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_super_lock(osb, 1);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+	unlock_super = 1;
+
+	/* This will load up the node map and add ourselves to it. */
+	status = ocfs2_find_slot(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	ocfs2_populate_mounted_map(osb);
+
+	/* load all node-local system inodes */
+	status = ocfs2_init_local_system_inodes(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_check_volume(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	status = ocfs2_truncate_log_init(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto leave;
+	}
+
+	/* This should be sent *after* we recovered our journal as it
+	 * will cause other nodes to unmark us as needing
+	 * recovery. However, we need to send it *before* dropping the
+	 * super block lock as otherwise their recovery threads might
+	 * try to clean us up while we're live! */
+	status = ocfs2_request_mount_vote(osb);
+	if (status < 0)
+		mlog_errno(status);
+
+leave:
+	if (unlock_super)
+		ocfs2_super_unlock(osb, 1);
+
+	mlog_exit(status);
+	return status;
+}
+
+/* we can't grab the goofy sem lock from inside wait_event, so we use
+ * memory barriers to make sure that we'll see the null task before
+ * being woken up */
+static int ocfs2_recovery_thread_running(struct ocfs2_super *osb)
+{
+	mb();
+	return osb->recovery_thread_task != NULL;
+}
+
+static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
+{
+	int tmp;
+	struct ocfs2_super *osb = NULL;
+
+	mlog_entry("(0x%p)\n", sb);
+
+	BUG_ON(!sb);
+	osb = OCFS2_SB(sb);
+	BUG_ON(!osb);
+
+	ocfs2_shutdown_local_alloc(osb);
+
+	ocfs2_truncate_log_shutdown(osb);
+
+	/* disable any new recovery threads and wait for any currently
+	 * running ones to exit. Do this before setting the vol_state. */
+	down(&osb->recovery_lock);
+	osb->disable_recovery = 1;
+	up(&osb->recovery_lock);
+	wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb));
+
+	/* At this point, we know that no more recovery threads can be
+	 * launched, so wait for any recovery completion work to
+	 * complete. */
+	flush_workqueue(ocfs2_wq);
+
+	ocfs2_journal_shutdown(osb);
+
+	ocfs2_sync_blockdev(sb);
+
+	/* No dlm means we've failed during mount, so skip all the
+	 * steps which depended on that to complete. */
+	if (osb->dlm) {
+		tmp = ocfs2_super_lock(osb, 1);
+		if (tmp < 0) {
+			mlog_errno(tmp);
+			return;
+		}
+
+		tmp = ocfs2_request_umount_vote(osb);
+		if (tmp < 0)
+			mlog_errno(tmp);
+
+		if (osb->slot_num != OCFS2_INVALID_SLOT)
+			ocfs2_put_slot(osb);
+
+		ocfs2_super_unlock(osb, 1);
+	}
+
+	ocfs2_release_system_inodes(osb);
+
+	if (osb->dlm) {
+		ocfs2_unregister_net_handlers(osb);
+
+		ocfs2_dlm_shutdown(osb);
+	}
+
+	ocfs2_clear_hb_callbacks(osb);
+
+	debugfs_remove(osb->osb_debug_root);
+
+	if (!mnt_err)
+		ocfs2_stop_heartbeat(osb);
+
+	atomic_set(&osb->vol_state, VOLUME_DISMOUNTED);
+
+	printk("ocfs2: Unmounting device (%u,%u) on (node %d)\n",
+	       MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev), osb->node_num);
+
+	ocfs2_delete_osb(osb);
+	kfree(osb);
+	sb->s_dev = 0;
+	sb->s_fs_info = NULL;
+}
+
+static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uuid,
+				unsigned uuid_bytes)
+{
+	int i, ret;
+	char *ptr;
+
+	BUG_ON(uuid_bytes != OCFS2_VOL_UUID_LEN);
+
+	osb->uuid_str = kcalloc(1, OCFS2_VOL_UUID_LEN * 2 + 1, GFP_KERNEL);
+	if (osb->uuid_str == NULL)
+		return -ENOMEM;
+
+	memcpy(osb->uuid, uuid, OCFS2_VOL_UUID_LEN);
+
+	for (i = 0, ptr = osb->uuid_str; i < OCFS2_VOL_UUID_LEN; i++) {
+		/* print with null */
+		ret = snprintf(ptr, 3, "%02X", uuid[i]);
+		if (ret != 2) /* drop super cleans up */
+			return -EINVAL;
+		/* then only advance past the last char */
+		ptr += 2;
+	}
+
+	return 0;
+}
+
+static int ocfs2_initialize_super(struct super_block *sb,
+				  struct buffer_head *bh,
+				  int sector_size)
+{
+	int status = 0;
+	int i;
+	struct ocfs2_dinode *di = NULL;
+	struct inode *inode = NULL;
+	struct buffer_head *bitmap_bh = NULL;
+	struct ocfs2_journal *journal;
+	__le32 uuid_net_key;
+	struct ocfs2_super *osb;
+
+	mlog_entry_void();
+
+	osb = kcalloc(1, sizeof(struct ocfs2_super), GFP_KERNEL);
+	if (!osb) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	sb->s_fs_info = osb;
+	sb->s_op = &ocfs2_sops;
+	sb->s_export_op = &ocfs2_export_ops;
+	sb->s_flags |= MS_NOATIME;
+	/* this is needed to support O_LARGEFILE */
+	sb->s_maxbytes = ocfs2_max_file_offset(sb->s_blocksize_bits);
+
+	osb->sb = sb;
+	/* Save off for ocfs2_rw_direct */
+	osb->s_sectsize_bits = blksize_bits(sector_size);
+	if (!osb->s_sectsize_bits)
+		BUG();
+
+	osb->net_response_ids = 0;
+	spin_lock_init(&osb->net_response_lock);
+	INIT_LIST_HEAD(&osb->net_response_list);
+
+	INIT_LIST_HEAD(&osb->osb_net_handlers);
+	init_waitqueue_head(&osb->recovery_event);
+	spin_lock_init(&osb->vote_task_lock);
+	init_waitqueue_head(&osb->vote_event);
+	osb->vote_work_sequence = 0;
+	osb->vote_wake_sequence = 0;
+	INIT_LIST_HEAD(&osb->blocked_lock_list);
+	osb->blocked_lock_count = 0;
+	INIT_LIST_HEAD(&osb->vote_list);
+	spin_lock_init(&osb->osb_lock);
+
+	atomic_set(&osb->alloc_stats.moves, 0);
+	atomic_set(&osb->alloc_stats.local_data, 0);
+	atomic_set(&osb->alloc_stats.bitmap_data, 0);
+	atomic_set(&osb->alloc_stats.bg_allocs, 0);
+	atomic_set(&osb->alloc_stats.bg_extends, 0);
+
+	ocfs2_init_node_maps(osb);
+
+	snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u",
+		 MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev));
+
+	init_MUTEX(&osb->recovery_lock);
+
+	osb->disable_recovery = 0;
+	osb->recovery_thread_task = NULL;
+
+	init_waitqueue_head(&osb->checkpoint_event);
+	atomic_set(&osb->needs_checkpoint, 0);
+
+	osb->node_num = O2NM_INVALID_NODE_NUM;
+	osb->slot_num = OCFS2_INVALID_SLOT;
+
+	osb->local_alloc_state = OCFS2_LA_UNUSED;
+	osb->local_alloc_bh = NULL;
+
+	ocfs2_setup_hb_callbacks(osb);
+
+	init_waitqueue_head(&osb->osb_mount_event);
+
+	osb->vol_label = kmalloc(OCFS2_MAX_VOL_LABEL_LEN, GFP_KERNEL);
+	if (!osb->vol_label) {
+		mlog(ML_ERROR, "unable to alloc vol label\n");
+		status = -ENOMEM;
+		goto bail;
+	}
+
+	osb->uuid = kmalloc(OCFS2_VOL_UUID_LEN, GFP_KERNEL);
+	if (!osb->uuid) {
+		mlog(ML_ERROR, "unable to alloc uuid\n");
+		status = -ENOMEM;
+		goto bail;
+	}
+
+	di = (struct ocfs2_dinode *)bh->b_data;
+
+	osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
+	if (osb->max_slots > OCFS2_MAX_SLOTS || osb->max_slots == 0) {
+		mlog(ML_ERROR, "Invalid number of node slots (%u)\n",
+		     osb->max_slots);
+		status = -EINVAL;
+		goto bail;
+	}
+	mlog(ML_NOTICE, "max_slots for this device: %u\n", osb->max_slots);
+
+	osb->s_feature_compat =
+		le32_to_cpu(OCFS2_RAW_SB(di)->s_feature_compat);
+	osb->s_feature_ro_compat =
+		le32_to_cpu(OCFS2_RAW_SB(di)->s_feature_ro_compat);
+	osb->s_feature_incompat =
+		le32_to_cpu(OCFS2_RAW_SB(di)->s_feature_incompat);
+
+	if ((i = OCFS2_HAS_INCOMPAT_FEATURE(osb->sb, ~OCFS2_FEATURE_INCOMPAT_SUPP))) {
+		mlog(ML_ERROR, "couldn't mount because of unsupported "
+		     "optional features (%x).\n", i);
+		status = -EINVAL;
+		goto bail;
+	}
+	if (!(osb->sb->s_flags & MS_RDONLY) &&
+	    (i = OCFS2_HAS_RO_COMPAT_FEATURE(osb->sb, ~OCFS2_FEATURE_RO_COMPAT_SUPP))) {
+		mlog(ML_ERROR, "couldn't mount RDWR because of "
+		     "unsupported optional features (%x).\n", i);
+		status = -EINVAL;
+		goto bail;
+	}
+
+	get_random_bytes(&osb->s_next_generation, sizeof(u32));
+
+	/* FIXME
+	 * This should be done in ocfs2_journal_init(), but unknown
+	 * ordering issues will cause the filesystem to crash.
+	 * If anyone wants to figure out what part of the code
+	 * refers to osb->journal before ocfs2_journal_init() is run,
+	 * be my guest.
+	 */
+	/* initialize our journal structure */
+
+	journal = kcalloc(1, sizeof(struct ocfs2_journal), GFP_KERNEL);
+	if (!journal) {
+		mlog(ML_ERROR, "unable to alloc journal\n");
+		status = -ENOMEM;
+		goto bail;
+	}
+	osb->journal = journal;
+	journal->j_osb = osb;
+
+	atomic_set(&journal->j_num_trans, 0);
+	init_rwsem(&journal->j_trans_barrier);
+	init_waitqueue_head(&journal->j_checkpointed);
+	spin_lock_init(&journal->j_lock);
+	journal->j_trans_id = (unsigned long) 1;
+	INIT_LIST_HEAD(&journal->j_la_cleanups);
+	INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery, osb);
+	journal->j_state = OCFS2_JOURNAL_FREE;
+
+	/* get some pseudo constants for clustersize bits */
+	osb->s_clustersize_bits =
+		le32_to_cpu(di->id2.i_super.s_clustersize_bits);
+	osb->s_clustersize = 1 << osb->s_clustersize_bits;
+	mlog(0, "clusterbits=%d\n", osb->s_clustersize_bits);
+
+	if (osb->s_clustersize < OCFS2_MIN_CLUSTERSIZE ||
+	    osb->s_clustersize > OCFS2_MAX_CLUSTERSIZE) {
+		mlog(ML_ERROR, "Volume has invalid cluster size (%d)\n",
+		     osb->s_clustersize);
+		status = -EINVAL;
+		goto bail;
+	}
+
+	if (ocfs2_clusters_to_blocks(osb->sb, le32_to_cpu(di->i_clusters) - 1)
+	    > (u32)~0UL) {
+		mlog(ML_ERROR, "Volume might try to write to blocks beyond "
+		     "what jbd can address in 32 bits.\n");
+		status = -EINVAL;
+		goto bail;
+	}
+
+	if (ocfs2_setup_osb_uuid(osb, di->id2.i_super.s_uuid,
+				 sizeof(di->id2.i_super.s_uuid))) {
+		mlog(ML_ERROR, "Out of memory trying to setup our uuid.\n");
+		status = -ENOMEM;
+		goto bail;
+	}
+
+	memcpy(&uuid_net_key, &osb->uuid[i], sizeof(osb->net_key));
+	osb->net_key = le32_to_cpu(uuid_net_key);
+
+	strncpy(osb->vol_label, di->id2.i_super.s_label, 63);
+	osb->vol_label[63] = '\0';
+	osb->root_blkno = le64_to_cpu(di->id2.i_super.s_root_blkno);
+	osb->system_dir_blkno = le64_to_cpu(di->id2.i_super.s_system_dir_blkno);
+	osb->first_cluster_group_blkno =
+		le64_to_cpu(di->id2.i_super.s_first_cluster_group);
+	osb->fs_generation = le32_to_cpu(di->i_fs_generation);
+	mlog(0, "vol_label: %s\n", osb->vol_label);
+	mlog(0, "uuid: %s\n", osb->uuid_str);
+	mlog(0, "root_blkno=%"MLFu64", system_dir_blkno=%"MLFu64"\n",
+	     osb->root_blkno, osb->system_dir_blkno);
+
+	osb->osb_dlm_debug = ocfs2_new_dlm_debug();
+	if (!osb->osb_dlm_debug) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	atomic_set(&osb->vol_state, VOLUME_INIT);
+
+	/* load root, system_dir, and all global system inodes */
+	status = ocfs2_init_global_system_inodes(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/*
+	 * global bitmap
+	 */
+	inode = ocfs2_get_system_file_inode(osb, GLOBAL_BITMAP_SYSTEM_INODE,
+					    OCFS2_INVALID_SLOT);
+	if (!inode) {
+		status = -EINVAL;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno;
+
+	status = ocfs2_read_block(osb, osb->bitmap_blkno, &bitmap_bh, 0,
+				  inode);
+	iput(inode);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	di = (struct ocfs2_dinode *) bitmap_bh->b_data;
+	osb->bitmap_cpg = le16_to_cpu(di->id2.i_chain.cl_cpg);
+	osb->num_clusters = le32_to_cpu(di->id1.bitmap1.i_total);
+	brelse(bitmap_bh);
+	mlog(0, "cluster bitmap inode: %"MLFu64", clusters per group: %u\n",
+	     osb->bitmap_blkno, osb->bitmap_cpg);
+
+	status = ocfs2_init_slot_info(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	/*  Link this osb onto the global linked list of all osb structures. */
+	/*  The Global Link List is mainted for the whole driver . */
+	spin_lock(&ocfs2_globals_lock);
+	osb->osb_id = osb_id;
+	if (osb_id < OCFS2_MAX_OSB_ID)
+		osb_id++;
+	else {
+		mlog(ML_ERROR, "Too many volumes mounted\n");
+		status = -ENOMEM;
+	}
+	spin_unlock(&ocfs2_globals_lock);
+
+bail:
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * will return: -EAGAIN if it is ok to keep searching for superblocks
+ *              -EINVAL if there is a bad superblock
+ *              0 on success
+ */
+static int ocfs2_verify_volume(struct ocfs2_dinode *di,
+			       struct buffer_head *bh,
+			       u32 blksz)
+{
+	int status = -EAGAIN;
+
+	mlog_entry_void();
+
+	if (memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE,
+		   strlen(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) {
+		status = -EINVAL;
+		if ((1 << le32_to_cpu(di->id2.i_super.s_blocksize_bits)) != blksz) {
+			mlog(ML_ERROR, "found superblock with incorrect block "
+			     "size: found %u, should be %u\n",
+			     1 << le32_to_cpu(di->id2.i_super.s_blocksize_bits),
+			       blksz);
+		} else if (le16_to_cpu(di->id2.i_super.s_major_rev_level) !=
+			   OCFS2_MAJOR_REV_LEVEL ||
+			   le16_to_cpu(di->id2.i_super.s_minor_rev_level) !=
+			   OCFS2_MINOR_REV_LEVEL) {
+			mlog(ML_ERROR, "found superblock with bad version: "
+			     "found %u.%u, should be %u.%u\n",
+			     le16_to_cpu(di->id2.i_super.s_major_rev_level),
+			     le16_to_cpu(di->id2.i_super.s_minor_rev_level),
+			     OCFS2_MAJOR_REV_LEVEL,
+			     OCFS2_MINOR_REV_LEVEL);
+		} else if (bh->b_blocknr != le64_to_cpu(di->i_blkno)) {
+			mlog(ML_ERROR, "bad block number on superblock: "
+			     "found %"MLFu64", should be %llu\n",
+			     di->i_blkno, (unsigned long long)bh->b_blocknr);
+		} else if (le32_to_cpu(di->id2.i_super.s_clustersize_bits) < 12 ||
+			    le32_to_cpu(di->id2.i_super.s_clustersize_bits) > 20) {
+			mlog(ML_ERROR, "bad cluster size found: %u\n",
+			     1 << le32_to_cpu(di->id2.i_super.s_clustersize_bits));
+		} else if (!le64_to_cpu(di->id2.i_super.s_root_blkno)) {
+			mlog(ML_ERROR, "bad root_blkno: 0\n");
+		} else if (!le64_to_cpu(di->id2.i_super.s_system_dir_blkno)) {
+			mlog(ML_ERROR, "bad system_dir_blkno: 0\n");
+		} else if (le16_to_cpu(di->id2.i_super.s_max_slots) > OCFS2_MAX_SLOTS) {
+			mlog(ML_ERROR,
+			     "Superblock slots found greater than file system "
+			     "maximum: found %u, max %u\n",
+			     le16_to_cpu(di->id2.i_super.s_max_slots),
+			     OCFS2_MAX_SLOTS);
+		} else {
+			/* found it! */
+			status = 0;
+		}
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+static int ocfs2_check_volume(struct ocfs2_super *osb)
+{
+	int status = 0;
+	int dirty;
+	struct ocfs2_dinode *local_alloc = NULL; /* only used if we
+						  * recover
+						  * ourselves. */
+
+	mlog_entry_void();
+
+	/* Init our journal object. */
+	status = ocfs2_journal_init(osb->journal, &dirty);
+	if (status < 0) {
+		mlog(ML_ERROR, "Could not initialize journal!\n");
+		goto finally;
+	}
+
+	/* If the journal was unmounted cleanly then we don't want to
+	 * recover anything. Otherwise, journal_load will do that
+	 * dirty work for us :) */
+	if (!dirty) {
+		status = ocfs2_journal_wipe(osb->journal, 0);
+		if (status < 0) {
+			mlog_errno(status);
+			goto finally;
+		}
+	} else {
+		mlog(ML_NOTICE, "File system was not unmounted cleanly, "
+		     "recovering volume.\n");
+	}
+
+	/* will play back anything left in the journal. */
+	ocfs2_journal_load(osb->journal);
+
+	if (dirty) {
+		/* recover my local alloc if we didn't unmount cleanly. */
+		status = ocfs2_begin_local_alloc_recovery(osb,
+							  osb->slot_num,
+							  &local_alloc);
+		if (status < 0) {
+			mlog_errno(status);
+			goto finally;
+		}
+		/* we complete the recovery process after we've marked
+		 * ourselves as mounted. */
+	}
+
+	mlog(0, "Journal loaded.\n");
+
+	status = ocfs2_load_local_alloc(osb);
+	if (status < 0) {
+		mlog_errno(status);
+		goto finally;
+	}
+
+	if (dirty) {
+		/* Recovery will be completed after we've mounted the
+		 * rest of the volume. */
+		osb->dirty = 1;
+		osb->local_alloc_copy = local_alloc;
+		local_alloc = NULL;
+	}
+
+	/* go through each journal, trylock it and if you get the
+	 * lock, and it's marked as dirty, set the bit in the recover
+	 * map and launch a recovery thread for it. */
+	status = ocfs2_mark_dead_nodes(osb);
+	if (status < 0)
+		mlog_errno(status);
+
+finally:
+	if (local_alloc)
+		kfree(local_alloc);
+
+	mlog_exit(status);
+	return status;
+}
+
+/*
+ * The routine gets called from dismount or close whenever a dismount on
+ * volume is requested and the osb open count becomes 1.
+ * It will remove the osb from the global list and also free up all the
+ * initialized resources and fileobject.
+ */
+static void ocfs2_delete_osb(struct ocfs2_super *osb)
+{
+	mlog_entry_void();
+
+	/* This function assumes that the caller has the main osb resource */
+
+	if (osb->slot_info)
+		ocfs2_free_slot_info(osb->slot_info);
+
+	/* FIXME
+	 * This belongs in journal shutdown, but because we have to
+	 * allocate osb->journal at the start of ocfs2_initalize_osb(),
+	 * we free it here.
+	 */
+	kfree(osb->journal);
+	if (osb->local_alloc_copy)
+		kfree(osb->local_alloc_copy);
+	kfree(osb->uuid_str);
+	ocfs2_put_dlm_debug(osb->osb_dlm_debug);
+	memset(osb, 0, sizeof(struct ocfs2_super));
+
+	mlog_exit_void();
+}
+
+/* Put OCFS2 into a readonly state, or (if the user specifies it),
+ * panic(). We do not support continue-on-error operation. */
+static void ocfs2_handle_error(struct super_block *sb)
+{
+	struct ocfs2_super *osb = OCFS2_SB(sb);
+
+	if (osb->s_mount_opt & OCFS2_MOUNT_ERRORS_PANIC)
+		panic("OCFS2: (device %s): panic forced after error\n",
+		      sb->s_id);
+
+	ocfs2_set_osb_flag(osb, OCFS2_OSB_ERROR_FS);
+
+	if (sb->s_flags & MS_RDONLY &&
+	    (ocfs2_is_soft_readonly(osb) ||
+	     ocfs2_is_hard_readonly(osb)))
+		return;
+
+	printk(KERN_CRIT "File system is now read-only due to the potential "
+	       "of on-disk corruption. Please run fsck.ocfs2 once the file "
+	       "system is unmounted.\n");
+	sb->s_flags |= MS_RDONLY;
+	ocfs2_set_ro_flag(osb, 0);
+}
+
+static char error_buf[1024];
+
+void __ocfs2_error(struct super_block *sb,
+		   const char *function,
+		   const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	vsprintf(error_buf, fmt, args);
+	va_end(args);
+
+	/* Not using mlog here because we want to show the actual
+	 * function the error came from. */
+	printk(KERN_CRIT "OCFS2: ERROR (device %s): %s: %s\n",
+	       sb->s_id, function, error_buf);
+
+	ocfs2_handle_error(sb);
+}
+
+/* Handle critical errors. This is intentionally more drastic than
+ * ocfs2_handle_error, so we only use for things like journal errors,
+ * etc. */
+void __ocfs2_abort(struct super_block* sb,
+		   const char *function,
+		   const char *fmt, ...)
+{
+	va_list args;
+
+	va_start(args, fmt);
+	vsprintf(error_buf, fmt, args);
+	va_end(args);
+
+	printk(KERN_CRIT "OCFS2: abort (device %s): %s: %s\n",
+	       sb->s_id, function, error_buf);
+
+	/* We don't have the cluster support yet to go straight to
+	 * hard readonly in here. Until then, we want to keep
+	 * ocfs2_abort() so that we can at least mark critical
+	 * errors.
+	 *
+	 * TODO: This should abort the journal and alert other nodes
+	 * that our slot needs recovery. */
+
+	/* Force a panic(). This stinks, but it's better than letting
+	 * things continue without having a proper hard readonly
+	 * here. */
+	OCFS2_SB(sb)->s_mount_opt |= OCFS2_MOUNT_ERRORS_PANIC;
+	ocfs2_handle_error(sb);
+}
+
+module_init(ocfs2_init);
+module_exit(ocfs2_exit);
diff --git a/fs/ocfs2/super.h b/fs/ocfs2/super.h
new file mode 100644
index 0000000..c564177
--- /dev/null
+++ b/fs/ocfs2/super.h
@@ -0,0 +1,44 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * super.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_SUPER_H
+#define OCFS2_SUPER_H
+
+extern struct workqueue_struct *ocfs2_wq;
+
+int ocfs2_publish_get_mount_state(struct ocfs2_super *osb,
+				  int node_num);
+
+void __ocfs2_error(struct super_block *sb,
+		   const char *function,
+		   const char *fmt, ...);
+#define ocfs2_error(sb, fmt, args...) __ocfs2_error(sb, __PRETTY_FUNCTION__, fmt, ##args)
+
+void __ocfs2_abort(struct super_block *sb,
+		   const char *function,
+		   const char *fmt, ...);
+#define ocfs2_abort(sb, fmt, args...) __ocfs2_abort(sb, __PRETTY_FUNCTION__, fmt, ##args)
+
+#endif /* OCFS2_SUPER_H */
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
new file mode 100644
index 0000000..f6986bd
--- /dev/null
+++ b/fs/ocfs2/symlink.c
@@ -0,0 +1,180 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ *  linux/cluster/ssi/cfs/symlink.c
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation; either version 2 of
+ *	the License, or (at your option) any later version.
+ *
+ *	This program is distributed in the hope that it will be useful,
+ *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *	MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE
+ *	or NON INFRINGEMENT.  See the GNU General Public License for more
+ *	details.
+ *
+ * 	You should have received a copy of the GNU General Public License
+ * 	along with this program; if not, write to the Free Software
+ * 	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *	Questions/Comments/Bugfixes to ssic-linux-devel@lists.sourceforge.net
+ *
+ *  Copyright (C) 1992  Rick Sladkey
+ *
+ *  Optimization changes Copyright (C) 1994 Florian La Roche
+ *
+ *  Jun 7 1999, cache symlink lookups in the page cache.  -DaveM
+ *
+ *  Portions Copyright (C) 2001 Compaq Computer Corporation
+ *
+ *  ocfs2 symlink handling code.
+ *
+ *  Copyright (C) 2004, 2005 Oracle.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/utsname.h>
+
+#define MLOG_MASK_PREFIX ML_NAMEI
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "file.h"
+#include "inode.h"
+#include "journal.h"
+#include "symlink.h"
+
+#include "buffer_head_io.h"
+
+static char *ocfs2_page_getlink(struct dentry * dentry,
+				struct page **ppage);
+static char *ocfs2_fast_symlink_getlink(struct inode *inode,
+					struct buffer_head **bh);
+
+/* get the link contents into pagecache */
+static char *ocfs2_page_getlink(struct dentry * dentry,
+				struct page **ppage)
+{
+	struct page * page;
+	struct address_space *mapping = dentry->d_inode->i_mapping;
+	page = read_cache_page(mapping, 0,
+			       (filler_t *)mapping->a_ops->readpage, NULL);
+	if (IS_ERR(page))
+		goto sync_fail;
+	wait_on_page_locked(page);
+	if (!PageUptodate(page))
+		goto async_fail;
+	*ppage = page;
+	return kmap(page);
+
+async_fail:
+	page_cache_release(page);
+	return ERR_PTR(-EIO);
+
+sync_fail:
+	return (char*)page;
+}
+
+static char *ocfs2_fast_symlink_getlink(struct inode *inode,
+					struct buffer_head **bh)
+{
+	int status;
+	char *link = NULL;
+	struct ocfs2_dinode *fe;
+
+	mlog_entry_void();
+
+	status = ocfs2_read_block(OCFS2_SB(inode->i_sb),
+				  OCFS2_I(inode)->ip_blkno,
+				  bh,
+				  OCFS2_BH_CACHED,
+				  inode);
+	if (status < 0) {
+		mlog_errno(status);
+		link = ERR_PTR(status);
+		goto bail;
+	}
+
+	fe = (struct ocfs2_dinode *) (*bh)->b_data;
+	link = (char *) fe->id2.i_symlink;
+bail:
+	mlog_exit(status);
+
+	return link;
+}
+
+static int ocfs2_readlink(struct dentry *dentry,
+			  char __user *buffer,
+			  int buflen)
+{
+	int ret;
+	char *link;
+	struct buffer_head *bh = NULL;
+	struct inode *inode = dentry->d_inode;
+
+	mlog_entry_void();
+
+	link = ocfs2_fast_symlink_getlink(inode, &bh);
+	if (IS_ERR(link)) {
+		ret = PTR_ERR(link);
+		goto out;
+	}
+
+	ret = vfs_readlink(dentry, buffer, buflen, link);
+
+	brelse(bh);
+out:
+	mlog_exit(ret);
+	return ret;
+}
+
+static void *ocfs2_follow_link(struct dentry *dentry,
+			       struct nameidata *nd)
+{
+	int status;
+	char *link;
+	struct inode *inode = dentry->d_inode;
+	struct page *page = NULL;
+	struct buffer_head *bh = NULL;
+	
+	if (ocfs2_inode_is_fast_symlink(inode))
+		link = ocfs2_fast_symlink_getlink(inode, &bh);
+	else
+		link = ocfs2_page_getlink(dentry, &page);
+	if (IS_ERR(link)) {
+		status = PTR_ERR(link);
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = vfs_follow_link(nd, link);
+	if (status)
+		mlog_errno(status);
+bail:
+	if (page) {
+		kunmap(page);
+		page_cache_release(page);
+	}
+	if (bh)
+		brelse(bh);
+
+	return ERR_PTR(status);
+}
+
+struct inode_operations ocfs2_symlink_inode_operations = {
+	.readlink	= page_readlink,
+	.follow_link	= ocfs2_follow_link,
+	.getattr	= ocfs2_getattr,
+};
+struct inode_operations ocfs2_fast_symlink_inode_operations = {
+	.readlink	= ocfs2_readlink,
+	.follow_link	= ocfs2_follow_link,
+	.getattr	= ocfs2_getattr,
+};
diff --git a/fs/ocfs2/symlink.h b/fs/ocfs2/symlink.h
new file mode 100644
index 0000000..1ea9e4d
--- /dev/null
+++ b/fs/ocfs2/symlink.h
@@ -0,0 +1,42 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * symlink.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_SYMLINK_H
+#define OCFS2_SYMLINK_H
+
+extern struct inode_operations ocfs2_symlink_inode_operations;
+extern struct inode_operations ocfs2_fast_symlink_inode_operations;
+
+/*
+ * Test whether an inode is a fast symlink.
+ */
+static inline int ocfs2_inode_is_fast_symlink(struct inode *inode)
+{
+	return (S_ISLNK(inode->i_mode) &&
+		inode->i_blocks == 0);
+}
+
+
+#endif /* OCFS2_SYMLINK_H */
diff --git a/fs/ocfs2/sysfile.c b/fs/ocfs2/sysfile.c
new file mode 100644
index 0000000..600a8bc
--- /dev/null
+++ b/fs/ocfs2/sysfile.c
@@ -0,0 +1,131 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * sysfile.c
+ *
+ * Initialize, read, write, etc. system files.
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+
+#include "ocfs2.h"
+
+#define MLOG_MASK_PREFIX ML_INODE
+#include <cluster/masklog.h>
+
+#include "alloc.h"
+#include "dir.h"
+#include "inode.h"
+#include "journal.h"
+#include "sysfile.h"
+
+#include "buffer_head_io.h"
+
+static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb,
+						   int type,
+						   u32 slot);
+
+static inline int is_global_system_inode(int type);
+static inline int is_in_system_inode_array(struct ocfs2_super *osb,
+					   int type,
+					   u32 slot);
+
+static inline int is_global_system_inode(int type)
+{
+	return type >= OCFS2_FIRST_ONLINE_SYSTEM_INODE &&
+		type <= OCFS2_LAST_GLOBAL_SYSTEM_INODE;
+}
+
+static inline int is_in_system_inode_array(struct ocfs2_super *osb,
+					   int type,
+					   u32 slot)
+{
+	return slot == osb->slot_num || is_global_system_inode(type);
+}
+
+struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb,
+					  int type,
+					  u32 slot)
+{
+	struct inode *inode = NULL;
+	struct inode **arr = NULL;
+
+	/* avoid the lookup if cached in local system file array */
+	if (is_in_system_inode_array(osb, type, slot))
+		arr = &(osb->system_inodes[type]);
+
+	if (arr && ((inode = *arr) != NULL)) {
+		/* get a ref in addition to the array ref */
+		inode = igrab(inode);
+		if (!inode)
+			BUG();
+
+		return inode;
+	}
+
+	/* this gets one ref thru iget */
+	inode = _ocfs2_get_system_file_inode(osb, type, slot);
+
+	/* add one more if putting into array for first time */
+	if (arr && inode) {
+		*arr = igrab(inode);
+		if (!*arr)
+			BUG();
+	}
+	return inode;
+}
+
+static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb,
+						   int type,
+						   u32 slot)
+{
+	char namebuf[40];
+	struct inode *inode = NULL;
+	u64 blkno;
+	struct buffer_head *dirent_bh = NULL;
+	struct ocfs2_dir_entry *de = NULL;
+	int status = 0;
+
+	ocfs2_sprintf_system_inode_name(namebuf,
+					sizeof(namebuf),
+					type, slot);
+
+	status = ocfs2_find_files_on_disk(namebuf, strlen(namebuf),
+					  &blkno, osb->sys_root_inode,
+					  &dirent_bh, &de);
+	if (status < 0) {
+		goto bail;
+	}
+
+	inode = ocfs2_iget(osb, blkno);
+	if (IS_ERR(inode)) {
+		mlog_errno(PTR_ERR(inode));
+		inode = NULL;
+		goto bail;
+	}
+bail:
+	if (dirent_bh)
+		brelse(dirent_bh);
+	return inode;
+}
+
diff --git a/fs/ocfs2/sysfile.h b/fs/ocfs2/sysfile.h
new file mode 100644
index 0000000..cc9ea66
--- /dev/null
+++ b/fs/ocfs2/sysfile.h
@@ -0,0 +1,33 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * sysfile.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_SYSFILE_H
+#define OCFS2_SYSFILE_H
+
+struct inode * ocfs2_get_system_file_inode(struct ocfs2_super *osb,
+					   int type,
+					   u32 slot);
+
+#endif /* OCFS2_SYSFILE_H */
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c
new file mode 100644
index 0000000..3a0458f
--- /dev/null
+++ b/fs/ocfs2/uptodate.c
@@ -0,0 +1,544 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * uptodate.c
+ *
+ * Tracking the up-to-date-ness of a local buffer_head with respect to
+ * the cluster.
+ *
+ * Copyright (C) 2002, 2004, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ *
+ * Standard buffer head caching flags (uptodate, etc) are insufficient
+ * in a clustered environment - a buffer may be marked up to date on
+ * our local node but could have been modified by another cluster
+ * member. As a result an additional (and performant) caching scheme
+ * is required. A further requirement is that we consume as little
+ * memory as possible - we never pin buffer_head structures in order
+ * to cache them.
+ *
+ * We track the existence of up to date buffers on the inodes which
+ * are associated with them. Because we don't want to pin
+ * buffer_heads, this is only a (strong) hint and several other checks
+ * are made in the I/O path to ensure that we don't use a stale or
+ * invalid buffer without going to disk:
+ *	- buffer_jbd is used liberally - if a bh is in the journal on
+ *	  this node then it *must* be up to date.
+ *	- the standard buffer_uptodate() macro is used to detect buffers
+ *	  which may be invalid (even if we have an up to date tracking
+ * 	  item for them)
+ *
+ * For a full understanding of how this code works together, one
+ * should read the callers in dlmglue.c, the I/O functions in
+ * buffer_head_io.c and ocfs2_journal_access in journal.c
+ */
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/buffer_head.h>
+#include <linux/rbtree.h>
+#include <linux/jbd.h>
+
+#define MLOG_MASK_PREFIX ML_UPTODATE
+
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "inode.h"
+#include "uptodate.h"
+
+struct ocfs2_meta_cache_item {
+	struct rb_node	c_node;
+	sector_t	c_block;
+};
+
+static kmem_cache_t *ocfs2_uptodate_cachep = NULL;
+
+void ocfs2_metadata_cache_init(struct inode *inode)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
+
+	oi->ip_flags |= OCFS2_INODE_CACHE_INLINE;
+	ci->ci_num_cached = 0;
+}
+
+/* No lock taken here as 'root' is not expected to be visible to other
+ * processes. */
+static unsigned int ocfs2_purge_copied_metadata_tree(struct rb_root *root)
+{
+	unsigned int purged = 0;
+	struct rb_node *node;
+	struct ocfs2_meta_cache_item *item;
+
+	while ((node = rb_last(root)) != NULL) {
+		item = rb_entry(node, struct ocfs2_meta_cache_item, c_node);
+
+		mlog(0, "Purge item %llu\n",
+		     (unsigned long long) item->c_block);
+
+		rb_erase(&item->c_node, root);
+		kmem_cache_free(ocfs2_uptodate_cachep, item);
+
+		purged++;
+	}
+	return purged;
+}
+
+/* Called from locking and called from ocfs2_clear_inode. Dump the
+ * cache for a given inode.
+ *
+ * This function is a few more lines longer than necessary due to some
+ * accounting done here, but I think it's worth tracking down those
+ * bugs sooner -- Mark */
+void ocfs2_metadata_cache_purge(struct inode *inode)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	unsigned int tree, to_purge, purged;
+	struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
+	struct rb_root root = RB_ROOT;
+
+	spin_lock(&oi->ip_lock);
+	tree = !(oi->ip_flags & OCFS2_INODE_CACHE_INLINE);
+	to_purge = ci->ci_num_cached;
+
+	mlog(0, "Purge %u %s items from Inode %"MLFu64"\n", to_purge,
+	     tree ? "array" : "tree", oi->ip_blkno);
+
+	/* If we're a tree, save off the root so that we can safely
+	 * initialize the cache. We do the work to free tree members
+	 * without the spinlock. */
+	if (tree)
+		root = ci->ci_cache.ci_tree;
+
+	ocfs2_metadata_cache_init(inode);
+	spin_unlock(&oi->ip_lock);
+
+	purged = ocfs2_purge_copied_metadata_tree(&root);
+	/* If possible, track the number wiped so that we can more
+	 * easily detect counting errors. Unfortunately, this is only
+	 * meaningful for trees. */
+	if (tree && purged != to_purge)
+		mlog(ML_ERROR, "Inode %"MLFu64", count = %u, purged = %u\n",
+		     oi->ip_blkno, to_purge, purged);
+}
+
+/* Returns the index in the cache array, -1 if not found.
+ * Requires ip_lock. */
+static int ocfs2_search_cache_array(struct ocfs2_caching_info *ci,
+				    sector_t item)
+{
+	int i;
+
+	for (i = 0; i < ci->ci_num_cached; i++) {
+		if (item == ci->ci_cache.ci_array[i])
+			return i;
+	}
+
+	return -1;
+}
+
+/* Returns the cache item if found, otherwise NULL.
+ * Requires ip_lock. */
+static struct ocfs2_meta_cache_item *
+ocfs2_search_cache_tree(struct ocfs2_caching_info *ci,
+			sector_t block)
+{
+	struct rb_node * n = ci->ci_cache.ci_tree.rb_node;
+	struct ocfs2_meta_cache_item *item = NULL;
+
+	while (n) {
+		item = rb_entry(n, struct ocfs2_meta_cache_item, c_node);
+
+		if (block < item->c_block)
+			n = n->rb_left;
+		else if (block > item->c_block)
+			n = n->rb_right;
+		else
+			return item;
+	}
+
+	return NULL;
+}
+
+static int ocfs2_buffer_cached(struct ocfs2_inode_info *oi,
+			       struct buffer_head *bh)
+{
+	int index = -1;
+	struct ocfs2_meta_cache_item *item = NULL;
+
+	spin_lock(&oi->ip_lock);
+
+	mlog(0, "Inode %"MLFu64", query block %llu (inline = %u)\n",
+	     oi->ip_blkno, (unsigned long long) bh->b_blocknr,
+	     !!(oi->ip_flags & OCFS2_INODE_CACHE_INLINE));
+
+	if (oi->ip_flags & OCFS2_INODE_CACHE_INLINE)
+		index = ocfs2_search_cache_array(&oi->ip_metadata_cache,
+						 bh->b_blocknr);
+	else
+		item = ocfs2_search_cache_tree(&oi->ip_metadata_cache,
+					       bh->b_blocknr);
+
+	spin_unlock(&oi->ip_lock);
+
+	mlog(0, "index = %d, item = %p\n", index, item);
+
+	return (index != -1) || (item != NULL);
+}
+
+/* Warning: even if it returns true, this does *not* guarantee that
+ * the block is stored in our inode metadata cache. */
+int ocfs2_buffer_uptodate(struct inode *inode,
+			  struct buffer_head *bh)
+{
+	/* Doesn't matter if the bh is in our cache or not -- if it's
+	 * not marked uptodate then we know it can't have correct
+	 * data. */
+	if (!buffer_uptodate(bh))
+		return 0;
+
+	/* OCFS2 does not allow multiple nodes to be changing the same
+	 * block at the same time. */
+	if (buffer_jbd(bh))
+		return 1;
+
+	/* Ok, locally the buffer is marked as up to date, now search
+	 * our cache to see if we can trust that. */
+	return ocfs2_buffer_cached(OCFS2_I(inode), bh);
+}
+
+/* Requires ip_lock */
+static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci,
+				     sector_t block)
+{
+	BUG_ON(ci->ci_num_cached >= OCFS2_INODE_MAX_CACHE_ARRAY);
+
+	mlog(0, "block %llu takes position %u\n", (unsigned long long) block,
+	     ci->ci_num_cached);
+
+	ci->ci_cache.ci_array[ci->ci_num_cached] = block;
+	ci->ci_num_cached++;
+}
+
+/* By now the caller should have checked that the item does *not*
+ * exist in the tree.
+ * Requires ip_lock. */
+static void __ocfs2_insert_cache_tree(struct ocfs2_caching_info *ci,
+				      struct ocfs2_meta_cache_item *new)
+{
+	sector_t block = new->c_block;
+	struct rb_node *parent = NULL;
+	struct rb_node **p = &ci->ci_cache.ci_tree.rb_node;
+	struct ocfs2_meta_cache_item *tmp;
+
+	mlog(0, "Insert block %llu num = %u\n", (unsigned long long) block,
+	     ci->ci_num_cached);
+
+	while(*p) {
+		parent = *p;
+
+		tmp = rb_entry(parent, struct ocfs2_meta_cache_item, c_node);
+
+		if (block < tmp->c_block)
+			p = &(*p)->rb_left;
+		else if (block > tmp->c_block)
+			p = &(*p)->rb_right;
+		else {
+			/* This should never happen! */
+			mlog(ML_ERROR, "Duplicate block %llu cached!\n",
+			     (unsigned long long) block);
+			BUG();
+		}
+	}
+
+	rb_link_node(&new->c_node, parent, p);
+	rb_insert_color(&new->c_node, &ci->ci_cache.ci_tree);
+	ci->ci_num_cached++;
+}
+
+static inline int ocfs2_insert_can_use_array(struct ocfs2_inode_info *oi,
+					     struct ocfs2_caching_info *ci)
+{
+	assert_spin_locked(&oi->ip_lock);
+
+	return (oi->ip_flags & OCFS2_INODE_CACHE_INLINE) &&
+		(ci->ci_num_cached < OCFS2_INODE_MAX_CACHE_ARRAY);
+}
+
+/* tree should be exactly OCFS2_INODE_MAX_CACHE_ARRAY wide. NULL the
+ * pointers in tree after we use them - this allows caller to detect
+ * when to free in case of error. */
+static void ocfs2_expand_cache(struct ocfs2_inode_info *oi,
+			       struct ocfs2_meta_cache_item **tree)
+{
+	int i;
+	struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
+
+	mlog_bug_on_msg(ci->ci_num_cached != OCFS2_INODE_MAX_CACHE_ARRAY,
+			"Inode %"MLFu64", num cached = %u, should be %u\n",
+			oi->ip_blkno, ci->ci_num_cached,
+			OCFS2_INODE_MAX_CACHE_ARRAY);
+	mlog_bug_on_msg(!(oi->ip_flags & OCFS2_INODE_CACHE_INLINE),
+			"Inode %"MLFu64" not marked as inline anymore!\n",
+			oi->ip_blkno);
+	assert_spin_locked(&oi->ip_lock);
+
+	/* Be careful to initialize the tree members *first* because
+	 * once the ci_tree is used, the array is junk... */
+	for(i = 0; i < OCFS2_INODE_MAX_CACHE_ARRAY; i++)
+		tree[i]->c_block = ci->ci_cache.ci_array[i];
+
+	oi->ip_flags &= ~OCFS2_INODE_CACHE_INLINE;
+	ci->ci_cache.ci_tree = RB_ROOT;
+	/* this will be set again by __ocfs2_insert_cache_tree */
+	ci->ci_num_cached = 0;
+
+	for(i = 0; i < OCFS2_INODE_MAX_CACHE_ARRAY; i++) {
+		__ocfs2_insert_cache_tree(ci, tree[i]);
+		tree[i] = NULL;
+	}
+
+	mlog(0, "Expanded %"MLFu64" to a tree cache: flags 0x%x, num = %u\n",
+	     oi->ip_blkno, oi->ip_flags, ci->ci_num_cached);
+}
+
+/* Slow path function - memory allocation is necessary. See the
+ * comment above ocfs2_set_buffer_uptodate for more information. */
+static void __ocfs2_set_buffer_uptodate(struct ocfs2_inode_info *oi,
+					sector_t block,
+					int expand_tree)
+{
+	int i;
+	struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
+	struct ocfs2_meta_cache_item *new = NULL;
+	struct ocfs2_meta_cache_item *tree[OCFS2_INODE_MAX_CACHE_ARRAY] =
+		{ NULL, };
+
+	mlog(0, "Inode %"MLFu64", block %llu, expand = %d\n",
+	     oi->ip_blkno, (unsigned long long) block, expand_tree);
+
+	new = kmem_cache_alloc(ocfs2_uptodate_cachep, GFP_KERNEL);
+	if (!new) {
+		mlog_errno(-ENOMEM);
+		return;
+	}
+	new->c_block = block;
+
+	if (expand_tree) {
+		/* Do *not* allocate an array here - the removal code
+		 * has no way of tracking that. */
+		for(i = 0; i < OCFS2_INODE_MAX_CACHE_ARRAY; i++) {
+			tree[i] = kmem_cache_alloc(ocfs2_uptodate_cachep,
+						   GFP_KERNEL);
+			if (!tree[i]) {
+				mlog_errno(-ENOMEM);
+				goto out_free;
+			}
+
+			/* These are initialized in ocfs2_expand_cache! */
+		}
+	}
+
+	spin_lock(&oi->ip_lock);
+	if (ocfs2_insert_can_use_array(oi, ci)) {
+		mlog(0, "Someone cleared the tree underneath us\n");
+		/* Ok, items were removed from the cache in between
+		 * locks. Detect this and revert back to the fast path */
+		ocfs2_append_cache_array(ci, block);
+		spin_unlock(&oi->ip_lock);
+		goto out_free;
+	}
+
+	if (expand_tree)
+		ocfs2_expand_cache(oi, tree);
+
+	__ocfs2_insert_cache_tree(ci, new);
+	spin_unlock(&oi->ip_lock);
+
+	new = NULL;
+out_free:
+	if (new)
+		kmem_cache_free(ocfs2_uptodate_cachep, new);
+
+	/* If these were used, then ocfs2_expand_cache re-set them to
+	 * NULL for us. */
+	if (tree[0]) {
+		for(i = 0; i < OCFS2_INODE_MAX_CACHE_ARRAY; i++)
+			if (tree[i])
+				kmem_cache_free(ocfs2_uptodate_cachep,
+						tree[i]);
+	}
+}
+
+/* Item insertion is guarded by ip_io_sem, so the insertion path takes
+ * advantage of this by not rechecking for a duplicate insert during
+ * the slow case. Additionally, if the cache needs to be bumped up to
+ * a tree, the code will not recheck after acquiring the lock --
+ * multiple paths cannot be expanding to a tree at the same time.
+ *
+ * The slow path takes into account that items can be removed
+ * (including the whole tree wiped and reset) when this process it out
+ * allocating memory. In those cases, it reverts back to the fast
+ * path.
+ *
+ * Note that this function may actually fail to insert the block if
+ * memory cannot be allocated. This is not fatal however (but may
+ * result in a performance penalty) */
+void ocfs2_set_buffer_uptodate(struct inode *inode,
+			       struct buffer_head *bh)
+{
+	int expand;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
+
+	/* The block may very well exist in our cache already, so avoid
+	 * doing any more work in that case. */
+	if (ocfs2_buffer_cached(oi, bh))
+		return;
+
+	mlog(0, "Inode %"MLFu64", inserting block %llu\n", oi->ip_blkno,
+	     (unsigned long long) bh->b_blocknr);
+
+	/* No need to recheck under spinlock - insertion is guarded by
+	 * ip_io_sem */
+	spin_lock(&oi->ip_lock);
+	if (ocfs2_insert_can_use_array(oi, ci)) {
+		/* Fast case - it's an array and there's a free
+		 * spot. */
+		ocfs2_append_cache_array(ci, bh->b_blocknr);
+		spin_unlock(&oi->ip_lock);
+		return;
+	}
+
+	expand = 0;
+	if (oi->ip_flags & OCFS2_INODE_CACHE_INLINE) {
+		/* We need to bump things up to a tree. */
+		expand = 1;
+	}
+	spin_unlock(&oi->ip_lock);
+
+	__ocfs2_set_buffer_uptodate(oi, bh->b_blocknr, expand);
+}
+
+/* Called against a newly allocated buffer. Most likely nobody should
+ * be able to read this sort of metadata while it's still being
+ * allocated, but this is careful to take ip_io_sem anyway. */
+void ocfs2_set_new_buffer_uptodate(struct inode *inode,
+				   struct buffer_head *bh)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+	/* This should definitely *not* exist in our cache */
+	BUG_ON(ocfs2_buffer_cached(oi, bh));
+
+	set_buffer_uptodate(bh);
+
+	down(&oi->ip_io_sem);
+	ocfs2_set_buffer_uptodate(inode, bh);
+	up(&oi->ip_io_sem);
+}
+
+/* Requires ip_lock. */
+static void ocfs2_remove_metadata_array(struct ocfs2_caching_info *ci,
+					int index)
+{
+	sector_t *array = ci->ci_cache.ci_array;
+	int bytes;
+
+	BUG_ON(index < 0 || index >= OCFS2_INODE_MAX_CACHE_ARRAY);
+	BUG_ON(index >= ci->ci_num_cached);
+	BUG_ON(!ci->ci_num_cached);
+
+	mlog(0, "remove index %d (num_cached = %u\n", index,
+	     ci->ci_num_cached);
+
+	ci->ci_num_cached--;
+
+	/* don't need to copy if the array is now empty, or if we
+	 * removed at the tail */
+	if (ci->ci_num_cached && index < ci->ci_num_cached) {
+		bytes = sizeof(sector_t) * (ci->ci_num_cached - index);
+		memmove(&array[index], &array[index + 1], bytes);
+	}
+}
+
+/* Requires ip_lock. */
+static void ocfs2_remove_metadata_tree(struct ocfs2_caching_info *ci,
+				       struct ocfs2_meta_cache_item *item)
+{
+	mlog(0, "remove block %llu from tree\n",
+	     (unsigned long long) item->c_block);
+
+	rb_erase(&item->c_node, &ci->ci_cache.ci_tree);
+	ci->ci_num_cached--;
+}
+
+/* Called when we remove a chunk of metadata from an inode. We don't
+ * bother reverting things to an inlined array in the case of a remove
+ * which moves us back under the limit. */
+void ocfs2_remove_from_cache(struct inode *inode,
+			     struct buffer_head *bh)
+{
+	int index;
+	sector_t block = bh->b_blocknr;
+	struct ocfs2_meta_cache_item *item = NULL;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+	struct ocfs2_caching_info *ci = &oi->ip_metadata_cache;
+
+	spin_lock(&oi->ip_lock);
+	mlog(0, "Inode %"MLFu64", remove %llu, items = %u, array = %u\n",
+	     oi->ip_blkno, (unsigned long long) block, ci->ci_num_cached,
+	     oi->ip_flags & OCFS2_INODE_CACHE_INLINE);
+
+	if (oi->ip_flags & OCFS2_INODE_CACHE_INLINE) {
+		index = ocfs2_search_cache_array(ci, block);
+		if (index != -1)
+			ocfs2_remove_metadata_array(ci, index);
+	} else {
+		item = ocfs2_search_cache_tree(ci, block);
+		if (item)
+			ocfs2_remove_metadata_tree(ci, item);
+	}
+	spin_unlock(&oi->ip_lock);
+
+	if (item)
+		kmem_cache_free(ocfs2_uptodate_cachep, item);
+}
+
+int __init init_ocfs2_uptodate_cache(void)
+{
+	ocfs2_uptodate_cachep = kmem_cache_create("ocfs2_uptodate",
+				  sizeof(struct ocfs2_meta_cache_item),
+				  0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+	if (!ocfs2_uptodate_cachep)
+		return -ENOMEM;
+
+	mlog(0, "%u inlined cache items per inode.\n",
+	     OCFS2_INODE_MAX_CACHE_ARRAY);
+
+	return 0;
+}
+
+void __exit exit_ocfs2_uptodate_cache(void)
+{
+	if (ocfs2_uptodate_cachep)
+		kmem_cache_destroy(ocfs2_uptodate_cachep);
+}
diff --git a/fs/ocfs2/uptodate.h b/fs/ocfs2/uptodate.h
new file mode 100644
index 0000000..e5aacdf
--- /dev/null
+++ b/fs/ocfs2/uptodate.h
@@ -0,0 +1,44 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * uptodate.h
+ *
+ * Cluster uptodate tracking
+ *
+ * Copyright (C) 2002, 2004, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_UPTODATE_H
+#define OCFS2_UPTODATE_H
+
+int __init init_ocfs2_uptodate_cache(void);
+void __exit exit_ocfs2_uptodate_cache(void);
+
+void ocfs2_metadata_cache_init(struct inode *inode);
+void ocfs2_metadata_cache_purge(struct inode *inode);
+
+int ocfs2_buffer_uptodate(struct inode *inode,
+			  struct buffer_head *bh);
+void ocfs2_set_buffer_uptodate(struct inode *inode,
+			       struct buffer_head *bh);
+void ocfs2_set_new_buffer_uptodate(struct inode *inode,
+				   struct buffer_head *bh);
+void ocfs2_remove_from_cache(struct inode *inode,
+			     struct buffer_head *bh);
+
+#endif /* OCFS2_UPTODATE_H */
diff --git a/fs/ocfs2/ver.c b/fs/ocfs2/ver.c
new file mode 100644
index 0000000..5405ce1
--- /dev/null
+++ b/fs/ocfs2/ver.c
@@ -0,0 +1,43 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ver.c
+ *
+ * version string
+ *
+ * Copyright (C) 2002, 2005 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#include "ver.h"
+
+#define OCFS2_BUILD_VERSION "1.3.3"
+
+#define VERSION_STR "OCFS2 " OCFS2_BUILD_VERSION
+
+void ocfs2_print_version(void)
+{
+	printk(KERN_INFO "%s\n", VERSION_STR);
+}
+
+MODULE_DESCRIPTION(VERSION_STR);
+
+MODULE_VERSION(OCFS2_BUILD_VERSION);
diff --git a/fs/ocfs2/ver.h b/fs/ocfs2/ver.h
new file mode 100644
index 0000000..d7395cb
--- /dev/null
+++ b/fs/ocfs2/ver.h
@@ -0,0 +1,31 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * ver.h
+ *
+ * Function prototypes
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#ifndef OCFS2_VER_H
+#define OCFS2_VER_H
+
+void ocfs2_print_version(void);
+
+#endif /* OCFS2_VER_H */
diff --git a/fs/ocfs2/vote.c b/fs/ocfs2/vote.c
new file mode 100644
index 0000000..021978e
--- /dev/null
+++ b/fs/ocfs2/vote.c
@@ -0,0 +1,1202 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * vote.c
+ *
+ * description here
+ *
+ * Copyright (C) 2003, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/highmem.h>
+#include <linux/smp_lock.h>
+#include <linux/kthread.h>
+
+#include <cluster/heartbeat.h>
+#include <cluster/nodemanager.h>
+#include <cluster/tcp.h>
+
+#include <dlm/dlmapi.h>
+
+#define MLOG_MASK_PREFIX ML_VOTE
+#include <cluster/masklog.h>
+
+#include "ocfs2.h"
+
+#include "alloc.h"
+#include "dlmglue.h"
+#include "extent_map.h"
+#include "heartbeat.h"
+#include "inode.h"
+#include "journal.h"
+#include "slot_map.h"
+#include "vote.h"
+
+#include "buffer_head_io.h"
+
+#define OCFS2_MESSAGE_TYPE_VOTE     (0x1)
+#define OCFS2_MESSAGE_TYPE_RESPONSE (0x2)
+struct ocfs2_msg_hdr
+{
+	__be32 h_response_id; /* used to lookup message handle on sending
+			    * node. */
+	__be32 h_request;
+	__be64 h_blkno;
+	__be32 h_generation;
+	__be32 h_node_num;    /* node sending this particular message. */
+};
+
+/* OCFS2_MAX_FILENAME_LEN is 255 characters, but we want to align this
+ * for the network. */
+#define OCFS2_VOTE_FILENAME_LEN 256
+struct ocfs2_vote_msg
+{
+	struct ocfs2_msg_hdr v_hdr;
+	union {
+		__be32 v_generic1;
+		__be32 v_orphaned_slot;	/* Used during delete votes */
+		__be32 v_nlink;		/* Used during unlink votes */
+	} md1;				/* Message type dependant 1 */
+	__be32 v_unlink_namelen;
+	__be64 v_unlink_parent;
+	u8  v_unlink_dirent[OCFS2_VOTE_FILENAME_LEN];
+};
+
+/* Responses are given these values to maintain backwards
+ * compatibility with older ocfs2 versions */
+#define OCFS2_RESPONSE_OK		(0)
+#define OCFS2_RESPONSE_BUSY		(-16)
+#define OCFS2_RESPONSE_BAD_MSG		(-22)
+
+struct ocfs2_response_msg
+{
+	struct ocfs2_msg_hdr r_hdr;
+	__be32 r_response;
+	__be32 r_orphaned_slot;
+};
+
+struct ocfs2_vote_work {
+	struct list_head   w_list;
+	struct ocfs2_vote_msg w_msg;
+};
+
+enum ocfs2_vote_request {
+	OCFS2_VOTE_REQ_INVALID = 0,
+	OCFS2_VOTE_REQ_DELETE,
+	OCFS2_VOTE_REQ_UNLINK,
+	OCFS2_VOTE_REQ_RENAME,
+	OCFS2_VOTE_REQ_MOUNT,
+	OCFS2_VOTE_REQ_UMOUNT,
+	OCFS2_VOTE_REQ_LAST
+};
+
+static inline int ocfs2_is_valid_vote_request(int request)
+{
+	return OCFS2_VOTE_REQ_INVALID < request &&
+		request < OCFS2_VOTE_REQ_LAST;
+}
+
+typedef void (*ocfs2_net_response_callback)(void *priv,
+					    struct ocfs2_response_msg *resp);
+struct ocfs2_net_response_cb {
+	ocfs2_net_response_callback	rc_cb;
+	void				*rc_priv;
+};
+
+struct ocfs2_net_wait_ctxt {
+	struct list_head        n_list;
+	u32                     n_response_id;
+	wait_queue_head_t       n_event;
+	struct ocfs2_node_map   n_node_map;
+	int                     n_response; /* an agreggate response. 0 if
+					     * all nodes are go, < 0 on any
+					     * negative response from any
+					     * node or network error. */
+	struct ocfs2_net_response_cb *n_callback;
+};
+
+static void ocfs2_process_mount_request(struct ocfs2_super *osb,
+					unsigned int node_num)
+{
+	mlog(0, "MOUNT vote from node %u\n", node_num);
+	/* The other node only sends us this message when he has an EX
+	 * on the superblock, so our recovery threads (if having been
+	 * launched) are waiting on it.*/
+	ocfs2_recovery_map_clear(osb, node_num);
+	ocfs2_node_map_set_bit(osb, &osb->mounted_map, node_num);
+
+	/* We clear the umount map here because a node may have been
+	 * previously mounted, safely unmounted but never stopped
+	 * heartbeating - in which case we'd have a stale entry. */
+	ocfs2_node_map_clear_bit(osb, &osb->umount_map, node_num);
+}
+
+static void ocfs2_process_umount_request(struct ocfs2_super *osb,
+					 unsigned int node_num)
+{
+	mlog(0, "UMOUNT vote from node %u\n", node_num);
+	ocfs2_node_map_clear_bit(osb, &osb->mounted_map, node_num);
+	ocfs2_node_map_set_bit(osb, &osb->umount_map, node_num);
+}
+
+void ocfs2_mark_inode_remotely_deleted(struct inode *inode)
+{
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+	assert_spin_locked(&oi->ip_lock);
+	/* We set the SKIP_DELETE flag on the inode so we don't try to
+	 * delete it in delete_inode ourselves, thus avoiding
+	 * unecessary lock pinging. If the other node failed to wipe
+	 * the inode as a result of a crash, then recovery will pick
+	 * up the slack. */
+	oi->ip_flags |= OCFS2_INODE_DELETED|OCFS2_INODE_SKIP_DELETE;
+}
+
+static int ocfs2_process_delete_request(struct inode *inode,
+					int *orphaned_slot)
+{
+	int response = OCFS2_RESPONSE_BUSY;
+
+	mlog(0, "DELETE vote on inode %lu, read lnk_cnt = %u, slot = %d\n",
+	     inode->i_ino, inode->i_nlink, *orphaned_slot);
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+
+	/* Whatever our vote response is, we want to make sure that
+	 * the orphaned slot is recorded properly on this node *and*
+	 * on the requesting node. Technically, if the requesting node
+	 * did not know which slot the inode is orphaned in but we
+	 * respond with BUSY he doesn't actually need the orphaned
+	 * slot, but it doesn't hurt to do it here anyway. */
+	if ((*orphaned_slot) != OCFS2_INVALID_SLOT) {
+		mlog_bug_on_msg(OCFS2_I(inode)->ip_orphaned_slot !=
+				OCFS2_INVALID_SLOT &&
+				OCFS2_I(inode)->ip_orphaned_slot !=
+				(*orphaned_slot),
+				"Inode %"MLFu64": This node thinks it's "
+				"orphaned in slot %d, messaged it's in %d\n",
+				OCFS2_I(inode)->ip_blkno,
+				OCFS2_I(inode)->ip_orphaned_slot,
+				*orphaned_slot);
+
+		mlog(0, "Setting orphaned slot for inode %"MLFu64" to %d\n",
+		     OCFS2_I(inode)->ip_blkno, *orphaned_slot);
+
+		OCFS2_I(inode)->ip_orphaned_slot = *orphaned_slot;
+	} else {
+		mlog(0, "Sending back orphaned slot %d for inode %"MLFu64"\n",
+		     OCFS2_I(inode)->ip_orphaned_slot,
+		     OCFS2_I(inode)->ip_blkno);
+
+		*orphaned_slot = OCFS2_I(inode)->ip_orphaned_slot;
+	}
+
+	/* vote no if the file is still open. */
+	if (OCFS2_I(inode)->ip_open_count) {
+		mlog(0, "open count = %u\n",
+		     OCFS2_I(inode)->ip_open_count);
+		spin_unlock(&OCFS2_I(inode)->ip_lock);
+		goto done;
+	}
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	/* directories are a bit ugly... What if someone is sitting in
+	 * it? We want to make sure the inode is removed completely as
+	 * a result of the iput in process_vote. */
+	if (S_ISDIR(inode->i_mode) && (atomic_read(&inode->i_count) != 1)) {
+		mlog(0, "i_count = %u\n", atomic_read(&inode->i_count));
+		goto done;
+	}
+
+	if (filemap_fdatawrite(inode->i_mapping)) {
+		mlog(ML_ERROR, "Could not sync inode %"MLFu64" for delete!\n",
+		     OCFS2_I(inode)->ip_blkno);
+		goto done;
+	}
+	sync_mapping_buffers(inode->i_mapping);
+	truncate_inode_pages(inode->i_mapping, 0);
+	ocfs2_extent_map_trunc(inode, 0);
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	/* double check open count - someone might have raced this
+	 * thread into ocfs2_file_open while we were writing out
+	 * data. If we're to allow a wipe of this inode now, we *must*
+	 * hold the spinlock until we've marked it. */
+	if (OCFS2_I(inode)->ip_open_count) {
+		mlog(0, "Raced to wipe! open count = %u\n",
+		     OCFS2_I(inode)->ip_open_count);
+		spin_unlock(&OCFS2_I(inode)->ip_lock);
+		goto done;
+	}
+
+	/* Mark the inode as being wiped from disk. */
+	ocfs2_mark_inode_remotely_deleted(inode);
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	/* Not sure this is necessary anymore. */
+	d_prune_aliases(inode);
+
+	/* If we get here, then we're voting 'yes', so commit the
+	 * delete on our side. */
+	response = OCFS2_RESPONSE_OK;
+done:
+	return response;
+}
+
+static int ocfs2_match_dentry(struct dentry *dentry,
+			      u64 parent_blkno,
+			      unsigned int namelen,
+			      const char *name)
+{
+	struct inode *parent;
+
+	if (!dentry->d_parent) {
+		mlog(0, "Detached from parent.\n");
+		return 0;
+	}
+
+	parent = dentry->d_parent->d_inode;
+	/* Negative parent dentry? */
+	if (!parent)
+		return 0;
+
+	/* Name is in a different directory. */
+	if (OCFS2_I(parent)->ip_blkno != parent_blkno)
+		return 0;
+
+	if (dentry->d_name.len != namelen)
+		return 0;
+
+	/* comparison above guarantees this is safe. */
+	if (memcmp(dentry->d_name.name, name, namelen))
+		return 0;
+
+	return 1;
+}
+
+static void ocfs2_process_dentry_request(struct inode *inode,
+					 int rename,
+					 unsigned int new_nlink,
+					 u64 parent_blkno,
+					 unsigned int namelen,
+					 const char *name)
+{
+	struct dentry *dentry = NULL;
+	struct list_head *p;
+	struct ocfs2_inode_info *oi = OCFS2_I(inode);
+
+	mlog(0, "parent %"MLFu64", namelen = %u, name = %.*s\n", parent_blkno,
+	     namelen, namelen, name);
+
+	spin_lock(&dcache_lock);
+
+	/* Another node is removing this name from the system. It is
+	 * up to us to find the corresponding dentry and if it exists,
+	 * unhash it from the dcache. */
+	list_for_each(p, &inode->i_dentry) {
+		dentry = list_entry(p, struct dentry, d_alias);
+
+		if (ocfs2_match_dentry(dentry, parent_blkno, namelen, name)) {
+			mlog(0, "dentry found: %.*s\n",
+			     dentry->d_name.len, dentry->d_name.name);
+
+			dget_locked(dentry);
+			break;
+		}
+
+		dentry = NULL;
+	}
+
+	spin_unlock(&dcache_lock);
+
+	if (dentry) {
+		d_delete(dentry);
+		dput(dentry);
+	}
+
+	/* rename votes don't send link counts */
+	if (!rename) {
+		mlog(0, "new_nlink = %u\n", new_nlink);
+
+		/* We don't have the proper locks here to directly
+		 * change i_nlink and besides, the vote is sent
+		 * *before* the operation so it may have failed on the
+		 * other node. This passes a hint to ocfs2_drop_inode
+		 * to force ocfs2_delete_inode, who will take the
+		 * proper cluster locks to sort things out. */
+		if (new_nlink == 0) {
+			spin_lock(&oi->ip_lock);
+			oi->ip_flags |= OCFS2_INODE_MAYBE_ORPHANED;
+			spin_unlock(&OCFS2_I(inode)->ip_lock);
+		}
+	}
+}
+
+static void ocfs2_process_vote(struct ocfs2_super *osb,
+			       struct ocfs2_vote_msg *msg)
+{
+	int net_status, vote_response;
+	int orphaned_slot = 0;
+	int rename = 0;
+	unsigned int node_num, generation, new_nlink, namelen;
+	u64 blkno, parent_blkno;
+	enum ocfs2_vote_request request;
+	struct inode *inode = NULL;
+	struct ocfs2_msg_hdr *hdr = &msg->v_hdr;
+	struct ocfs2_response_msg response;
+
+	/* decode the network mumbo jumbo into local variables. */
+	request = be32_to_cpu(hdr->h_request);
+	blkno = be64_to_cpu(hdr->h_blkno);
+	generation = be32_to_cpu(hdr->h_generation);
+	node_num = be32_to_cpu(hdr->h_node_num);
+	if (request == OCFS2_VOTE_REQ_DELETE)
+		orphaned_slot = be32_to_cpu(msg->md1.v_orphaned_slot);
+
+	mlog(0, "processing vote: request = %u, blkno = %"MLFu64", "
+	     "generation = %u, node_num = %u, priv1 = %u\n", request,
+	     blkno, generation, node_num, be32_to_cpu(msg->md1.v_generic1));
+
+	if (!ocfs2_is_valid_vote_request(request)) {
+		mlog(ML_ERROR, "Invalid vote request %d from node %u\n",
+		     request, node_num);
+		vote_response = OCFS2_RESPONSE_BAD_MSG;
+		goto respond;
+	}
+
+	vote_response = OCFS2_RESPONSE_OK;
+
+	switch (request) {
+	case OCFS2_VOTE_REQ_UMOUNT:
+		ocfs2_process_umount_request(osb, node_num);
+		goto respond;
+	case OCFS2_VOTE_REQ_MOUNT:
+		ocfs2_process_mount_request(osb, node_num);
+		goto respond;
+	default:
+		/* avoids a gcc warning */
+		break;
+	}
+
+	/* We cannot process the remaining message types before we're
+	 * fully mounted. It's perfectly safe however to send a 'yes'
+	 * response as we can't possibly have any of the state they're
+	 * asking us to modify yet. */
+	if (atomic_read(&osb->vol_state) == VOLUME_INIT)
+		goto respond;
+
+	/* If we get here, then the request is against an inode. */
+	inode = ocfs2_ilookup_for_vote(osb, blkno,
+				       request == OCFS2_VOTE_REQ_DELETE);
+
+	/* Not finding the inode is perfectly valid - it means we're
+	 * not interested in what the other node is about to do to it
+	 * so in those cases we automatically respond with an
+	 * affirmative. Cluster locking ensures that we won't race
+	 * interest in the inode with this vote request. */
+	if (!inode)
+		goto respond;
+
+	/* Check generation values. It's possible for us to get a
+	 * request against a stale inode. If so then we proceed as if
+	 * we had not found an inode in the first place. */
+	if (inode->i_generation != generation) {
+		mlog(0, "generation passed %u != inode generation = %u, "
+		     "ip_flags = %x, ip_blkno = %"MLFu64", msg %"MLFu64", "
+		     "i_count = %u, message type = %u\n",
+		     generation, inode->i_generation, OCFS2_I(inode)->ip_flags,
+		     OCFS2_I(inode)->ip_blkno, blkno,
+		     atomic_read(&inode->i_count), request);
+		iput(inode);
+		inode = NULL;
+		goto respond;
+	}
+
+	switch (request) {
+	case OCFS2_VOTE_REQ_DELETE:
+		vote_response = ocfs2_process_delete_request(inode,
+							     &orphaned_slot);
+		break;
+	case OCFS2_VOTE_REQ_RENAME:
+		rename = 1;
+		/* fall through */
+	case OCFS2_VOTE_REQ_UNLINK:
+		parent_blkno = be64_to_cpu(msg->v_unlink_parent);
+		namelen = be32_to_cpu(msg->v_unlink_namelen);
+		/* new_nlink will be ignored in case of a rename vote */
+		new_nlink = be32_to_cpu(msg->md1.v_nlink);
+		ocfs2_process_dentry_request(inode, rename, new_nlink,
+					     parent_blkno, namelen,
+					     msg->v_unlink_dirent);
+		break;
+	default:
+		mlog(ML_ERROR, "node %u, invalid request: %u\n",
+		     node_num, request);
+		vote_response = OCFS2_RESPONSE_BAD_MSG;
+	}
+
+respond:
+	/* Response struture is small so we just put it on the stack
+	 * and stuff it inline. */
+	memset(&response, 0, sizeof(struct ocfs2_response_msg));
+	response.r_hdr.h_response_id = hdr->h_response_id;
+	response.r_hdr.h_blkno = hdr->h_blkno;
+	response.r_hdr.h_generation = hdr->h_generation;
+	response.r_hdr.h_node_num = cpu_to_be32(osb->node_num);
+	response.r_response = cpu_to_be32(vote_response);
+	response.r_orphaned_slot = cpu_to_be32(orphaned_slot);
+
+	net_status = o2net_send_message(OCFS2_MESSAGE_TYPE_RESPONSE,
+					osb->net_key,
+					&response,
+					sizeof(struct ocfs2_response_msg),
+					node_num,
+					NULL);
+	/* We still want to error print for ENOPROTOOPT here. The
+	 * sending node shouldn't have unregistered his net handler
+	 * without sending an unmount vote 1st */
+	if (net_status < 0
+	    && net_status != -ETIMEDOUT
+	    && net_status != -ENOTCONN)
+		mlog(ML_ERROR, "message to node %u fails with error %d!\n",
+		     node_num, net_status);
+
+	if (inode)
+		iput(inode);
+}
+
+static void ocfs2_vote_thread_do_work(struct ocfs2_super *osb)
+{
+	unsigned long processed;
+	struct ocfs2_lock_res *lockres;
+	struct ocfs2_vote_work *work;
+
+	mlog_entry_void();
+
+	spin_lock(&osb->vote_task_lock);
+	/* grab this early so we know to try again if a state change and
+	 * wake happens part-way through our work  */
+	osb->vote_work_sequence = osb->vote_wake_sequence;
+
+	processed = osb->blocked_lock_count;
+	while (processed) {
+		BUG_ON(list_empty(&osb->blocked_lock_list));
+
+		lockres = list_entry(osb->blocked_lock_list.next,
+				     struct ocfs2_lock_res, l_blocked_list);
+		list_del_init(&lockres->l_blocked_list);
+		osb->blocked_lock_count--;
+		spin_unlock(&osb->vote_task_lock);
+
+		BUG_ON(!processed);
+		processed--;
+
+		ocfs2_process_blocked_lock(osb, lockres);
+
+		spin_lock(&osb->vote_task_lock);
+	}
+
+	while (osb->vote_count) {
+		BUG_ON(list_empty(&osb->vote_list));
+		work = list_entry(osb->vote_list.next,
+				  struct ocfs2_vote_work, w_list);
+		list_del(&work->w_list);
+		osb->vote_count--;
+		spin_unlock(&osb->vote_task_lock);
+
+		ocfs2_process_vote(osb, &work->w_msg);
+		kfree(work);
+
+		spin_lock(&osb->vote_task_lock);
+	}
+	spin_unlock(&osb->vote_task_lock);
+
+	mlog_exit_void();
+}
+
+static int ocfs2_vote_thread_lists_empty(struct ocfs2_super *osb)
+{
+	int empty = 0;
+
+	spin_lock(&osb->vote_task_lock);
+	if (list_empty(&osb->blocked_lock_list) &&
+	    list_empty(&osb->vote_list))
+		empty = 1;
+
+	spin_unlock(&osb->vote_task_lock);
+	return empty;
+}
+
+static int ocfs2_vote_thread_should_wake(struct ocfs2_super *osb)
+{
+	int should_wake = 0;
+
+	spin_lock(&osb->vote_task_lock);
+	if (osb->vote_work_sequence != osb->vote_wake_sequence)
+		should_wake = 1;
+	spin_unlock(&osb->vote_task_lock);
+
+	return should_wake;
+}
+
+int ocfs2_vote_thread(void *arg)
+{
+	int status = 0;
+	struct ocfs2_super *osb = arg;
+
+	/* only quit once we've been asked to stop and there is no more
+	 * work available */
+	while (!(kthread_should_stop() &&
+		 ocfs2_vote_thread_lists_empty(osb))) {
+
+		wait_event_interruptible(osb->vote_event,
+					 ocfs2_vote_thread_should_wake(osb) ||
+					 kthread_should_stop());
+
+		mlog(0, "vote_thread: awoken\n");
+
+		ocfs2_vote_thread_do_work(osb);
+	}
+
+	osb->vote_task = NULL;
+	return status;
+}
+
+static struct ocfs2_net_wait_ctxt *ocfs2_new_net_wait_ctxt(unsigned int response_id)
+{
+	struct ocfs2_net_wait_ctxt *w;
+
+	w = kcalloc(1, sizeof(*w), GFP_KERNEL);
+	if (!w) {
+		mlog_errno(-ENOMEM);
+		goto bail;
+	}
+
+	INIT_LIST_HEAD(&w->n_list);
+	init_waitqueue_head(&w->n_event);
+	ocfs2_node_map_init(&w->n_node_map);
+	w->n_response_id = response_id;
+	w->n_callback = NULL;
+bail:
+	return w;
+}
+
+static unsigned int ocfs2_new_response_id(struct ocfs2_super *osb)
+{
+	unsigned int ret;
+
+	spin_lock(&osb->net_response_lock);
+	ret = ++osb->net_response_ids;
+	spin_unlock(&osb->net_response_lock);
+
+	return ret;
+}
+
+static void ocfs2_dequeue_net_wait_ctxt(struct ocfs2_super *osb,
+					struct ocfs2_net_wait_ctxt *w)
+{
+	spin_lock(&osb->net_response_lock);
+	list_del(&w->n_list);
+	spin_unlock(&osb->net_response_lock);
+}
+
+static void ocfs2_queue_net_wait_ctxt(struct ocfs2_super *osb,
+				      struct ocfs2_net_wait_ctxt *w)
+{
+	spin_lock(&osb->net_response_lock);
+	list_add_tail(&w->n_list,
+		      &osb->net_response_list);
+	spin_unlock(&osb->net_response_lock);
+}
+
+static void __ocfs2_mark_node_responded(struct ocfs2_super *osb,
+					struct ocfs2_net_wait_ctxt *w,
+					int node_num)
+{
+	assert_spin_locked(&osb->net_response_lock);
+
+	ocfs2_node_map_clear_bit(osb, &w->n_node_map, node_num);
+	if (ocfs2_node_map_is_empty(osb, &w->n_node_map))
+		wake_up(&w->n_event);
+}
+
+/* Intended to be called from the node down callback, we fake remove
+ * the node from all our response contexts */
+void ocfs2_remove_node_from_vote_queues(struct ocfs2_super *osb,
+					int node_num)
+{
+	struct list_head *p;
+	struct ocfs2_net_wait_ctxt *w = NULL;
+
+	spin_lock(&osb->net_response_lock);
+
+	list_for_each(p, &osb->net_response_list) {
+		w = list_entry(p, struct ocfs2_net_wait_ctxt, n_list);
+
+		__ocfs2_mark_node_responded(osb, w, node_num);
+	}
+
+	spin_unlock(&osb->net_response_lock);
+}
+
+static int ocfs2_broadcast_vote(struct ocfs2_super *osb,
+				struct ocfs2_vote_msg *request,
+				unsigned int response_id,
+				int *response,
+				struct ocfs2_net_response_cb *callback)
+{
+	int status, i, remote_err;
+	struct ocfs2_net_wait_ctxt *w = NULL;
+	int dequeued = 0;
+
+	mlog_entry_void();
+
+	w = ocfs2_new_net_wait_ctxt(response_id);
+	if (!w) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+	w->n_callback = callback;
+
+	/* we're pretty much ready to go at this point, and this fills
+	 * in n_response which we need anyway... */
+	ocfs2_queue_net_wait_ctxt(osb, w);
+
+	i = ocfs2_node_map_iterate(osb, &osb->mounted_map, 0);
+
+	while (i != O2NM_INVALID_NODE_NUM) {
+		if (i != osb->node_num) {
+			mlog(0, "trying to send request to node %i\n", i);
+			ocfs2_node_map_set_bit(osb, &w->n_node_map, i);
+
+			remote_err = 0;
+			status = o2net_send_message(OCFS2_MESSAGE_TYPE_VOTE,
+						    osb->net_key,
+						    request,
+						    sizeof(*request),
+						    i,
+						    &remote_err);
+			if (status == -ETIMEDOUT) {
+				mlog(0, "remote node %d timed out!\n", i);
+				status = -EAGAIN;
+				goto bail;
+			}
+			if (remote_err < 0) {
+				status = remote_err;
+				mlog(0, "remote error %d on node %d!\n",
+				     remote_err, i);
+				mlog_errno(status);
+				goto bail;
+			}
+			if (status < 0) {
+				mlog_errno(status);
+				goto bail;
+			}
+		}
+		i++;
+		i = ocfs2_node_map_iterate(osb, &osb->mounted_map, i);
+		mlog(0, "next is %d, i am %d\n", i, osb->node_num);
+	}
+	mlog(0, "done sending, now waiting on responses...\n");
+
+	wait_event(w->n_event, ocfs2_node_map_is_empty(osb, &w->n_node_map));
+
+	ocfs2_dequeue_net_wait_ctxt(osb, w);
+	dequeued = 1;
+
+	*response = w->n_response;
+	status = 0;
+bail:
+	if (w) {
+		if (!dequeued)
+			ocfs2_dequeue_net_wait_ctxt(osb, w);
+		kfree(w);
+	}
+
+	mlog_exit(status);
+	return status;
+}
+
+static struct ocfs2_vote_msg * ocfs2_new_vote_request(struct ocfs2_super *osb,
+						      u64 blkno,
+						      unsigned int generation,
+						      enum ocfs2_vote_request type,
+						      u32 priv)
+{
+	struct ocfs2_vote_msg *request;
+	struct ocfs2_msg_hdr *hdr;
+
+	BUG_ON(!ocfs2_is_valid_vote_request(type));
+
+	request = kcalloc(1, sizeof(*request), GFP_KERNEL);
+	if (!request) {
+		mlog_errno(-ENOMEM);
+	} else {
+		hdr = &request->v_hdr;
+		hdr->h_node_num = cpu_to_be32(osb->node_num);
+		hdr->h_request = cpu_to_be32(type);
+		hdr->h_blkno = cpu_to_be64(blkno);
+		hdr->h_generation = cpu_to_be32(generation);
+
+		request->md1.v_generic1 = cpu_to_be32(priv);
+	}
+
+	return request;
+}
+
+/* Complete the buildup of a new vote request and process the
+ * broadcast return value. */
+static int ocfs2_do_request_vote(struct ocfs2_super *osb,
+				 struct ocfs2_vote_msg *request,
+				 struct ocfs2_net_response_cb *callback)
+{
+	int status, response;
+	unsigned int response_id;
+	struct ocfs2_msg_hdr *hdr;
+
+	response_id = ocfs2_new_response_id(osb);
+
+	hdr = &request->v_hdr;
+	hdr->h_response_id = cpu_to_be32(response_id);
+
+	status = ocfs2_broadcast_vote(osb, request, response_id, &response,
+				      callback);
+	if (status < 0) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = response;
+bail:
+
+	return status;
+}
+
+static int ocfs2_request_vote(struct inode *inode,
+			      struct ocfs2_vote_msg *request,
+			      struct ocfs2_net_response_cb *callback)
+{
+	int status;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+
+	if (ocfs2_inode_is_new(inode))
+		return 0;
+
+	status = -EAGAIN;
+	while (status == -EAGAIN) {
+		if (!(osb->s_mount_opt & OCFS2_MOUNT_NOINTR) &&
+		    signal_pending(current))
+			return -ERESTARTSYS;
+
+		status = ocfs2_super_lock(osb, 0);
+		if (status < 0) {
+			mlog_errno(status);
+			break;
+		}
+
+		status = 0;
+		if (!ocfs2_node_map_is_only(osb, &osb->mounted_map,
+					   osb->node_num))
+			status = ocfs2_do_request_vote(osb, request, callback);
+
+		ocfs2_super_unlock(osb, 0);
+	}
+	return status;
+}
+
+static void ocfs2_delete_response_cb(void *priv,
+				     struct ocfs2_response_msg *resp)
+{
+	int orphaned_slot, node;
+	struct inode *inode = priv;
+
+	orphaned_slot = be32_to_cpu(resp->r_orphaned_slot);
+	node = be32_to_cpu(resp->r_hdr.h_node_num);
+	mlog(0, "node %d tells us that inode %"MLFu64" is orphaned in slot "
+	     "%d\n", node, OCFS2_I(inode)->ip_blkno, orphaned_slot);
+
+	/* The other node may not actually know which slot the inode
+	 * is orphaned in. */
+	if (orphaned_slot == OCFS2_INVALID_SLOT)
+		return;
+
+	/* Ok, the responding node knows which slot this inode is
+	 * orphaned in. We verify that the information is correct and
+	 * then record this in the inode. ocfs2_delete_inode will use
+	 * this information to determine which lock to take. */
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	mlog_bug_on_msg(OCFS2_I(inode)->ip_orphaned_slot != orphaned_slot &&
+			OCFS2_I(inode)->ip_orphaned_slot
+			!= OCFS2_INVALID_SLOT, "Inode %"MLFu64": Node %d "
+			"says it's orphaned in slot %d, we think it's in %d\n",
+			OCFS2_I(inode)->ip_blkno,
+			be32_to_cpu(resp->r_hdr.h_node_num),
+			orphaned_slot, OCFS2_I(inode)->ip_orphaned_slot);
+
+	OCFS2_I(inode)->ip_orphaned_slot = orphaned_slot;
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+}
+
+int ocfs2_request_delete_vote(struct inode *inode)
+{
+	int orphaned_slot, status;
+	struct ocfs2_net_response_cb delete_cb;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct ocfs2_vote_msg *request;
+
+	spin_lock(&OCFS2_I(inode)->ip_lock);
+	orphaned_slot = OCFS2_I(inode)->ip_orphaned_slot;
+	spin_unlock(&OCFS2_I(inode)->ip_lock);
+
+	delete_cb.rc_cb = ocfs2_delete_response_cb;
+	delete_cb.rc_priv = inode;
+
+	mlog(0, "Inode %"MLFu64", we start thinking orphaned slot is %d\n",
+	     OCFS2_I(inode)->ip_blkno, orphaned_slot);
+
+	status = -ENOMEM;
+	request = ocfs2_new_vote_request(osb, OCFS2_I(inode)->ip_blkno,
+					 inode->i_generation,
+					 OCFS2_VOTE_REQ_DELETE, orphaned_slot);
+	if (request) {
+		status = ocfs2_request_vote(inode, request, &delete_cb);
+
+		kfree(request);
+	}
+
+	return status;
+}
+
+static void ocfs2_setup_unlink_vote(struct ocfs2_vote_msg *request,
+				    struct dentry *dentry)
+{
+	struct inode *parent = dentry->d_parent->d_inode;
+
+	/* We need some values which will uniquely identify a dentry
+	 * on the other nodes so that they can find it and run
+	 * d_delete against it. Parent directory block and full name
+	 * should suffice. */
+
+	mlog(0, "unlink/rename request: parent: %"MLFu64" name: %.*s\n",
+	     OCFS2_I(parent)->ip_blkno, dentry->d_name.len,
+	     dentry->d_name.name);
+
+	request->v_unlink_parent = cpu_to_be64(OCFS2_I(parent)->ip_blkno);
+	request->v_unlink_namelen = cpu_to_be32(dentry->d_name.len);
+	memcpy(request->v_unlink_dirent, dentry->d_name.name,
+	       dentry->d_name.len);
+}
+
+int ocfs2_request_unlink_vote(struct inode *inode,
+			      struct dentry *dentry,
+			      unsigned int nlink)
+{
+	int status;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct ocfs2_vote_msg *request;
+
+	if (dentry->d_name.len > OCFS2_VOTE_FILENAME_LEN)
+		return -ENAMETOOLONG;
+
+	status = -ENOMEM;
+	request = ocfs2_new_vote_request(osb, OCFS2_I(inode)->ip_blkno,
+					 inode->i_generation,
+					 OCFS2_VOTE_REQ_UNLINK, nlink);
+	if (request) {
+		ocfs2_setup_unlink_vote(request, dentry);
+
+		status = ocfs2_request_vote(inode, request, NULL);
+
+		kfree(request);
+	}
+	return status;
+}
+
+int ocfs2_request_rename_vote(struct inode *inode,
+			      struct dentry *dentry)
+{
+	int status;
+	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+	struct ocfs2_vote_msg *request;
+
+	if (dentry->d_name.len > OCFS2_VOTE_FILENAME_LEN)
+		return -ENAMETOOLONG;
+
+	status = -ENOMEM;
+	request = ocfs2_new_vote_request(osb, OCFS2_I(inode)->ip_blkno,
+					 inode->i_generation,
+					 OCFS2_VOTE_REQ_RENAME, 0);
+	if (request) {
+		ocfs2_setup_unlink_vote(request, dentry);
+
+		status = ocfs2_request_vote(inode, request, NULL);
+
+		kfree(request);
+	}
+	return status;
+}
+
+int ocfs2_request_mount_vote(struct ocfs2_super *osb)
+{
+	int status;
+	struct ocfs2_vote_msg *request = NULL;
+
+	request = ocfs2_new_vote_request(osb, 0ULL, 0,
+					 OCFS2_VOTE_REQ_MOUNT, 0);
+	if (!request) {
+		status = -ENOMEM;
+		goto bail;
+	}
+
+	status = -EAGAIN;
+	while (status == -EAGAIN) {
+		if (!(osb->s_mount_opt & OCFS2_MOUNT_NOINTR) &&
+		    signal_pending(current)) {
+			status = -ERESTARTSYS;
+			goto bail;
+		}
+
+		if (ocfs2_node_map_is_only(osb, &osb->mounted_map,
+					   osb->node_num)) {
+			status = 0;
+			goto bail;
+		}
+
+		status = ocfs2_do_request_vote(osb, request, NULL);
+	}
+
+bail:
+	if (request)
+		kfree(request);
+
+	return status;
+}
+
+int ocfs2_request_umount_vote(struct ocfs2_super *osb)
+{
+	int status;
+	struct ocfs2_vote_msg *request = NULL;
+
+	request = ocfs2_new_vote_request(osb, 0ULL, 0,
+					 OCFS2_VOTE_REQ_UMOUNT, 0);
+	if (!request) {
+		status = -ENOMEM;
+		goto bail;
+	}
+
+	status = -EAGAIN;
+	while (status == -EAGAIN) {
+		/* Do not check signals on this vote... We really want
+		 * this one to go all the way through. */
+
+		if (ocfs2_node_map_is_only(osb, &osb->mounted_map,
+					   osb->node_num)) {
+			status = 0;
+			goto bail;
+		}
+
+		status = ocfs2_do_request_vote(osb, request, NULL);
+	}
+
+bail:
+	if (request)
+		kfree(request);
+
+	return status;
+}
+
+/* TODO: This should eventually be a hash table! */
+static struct ocfs2_net_wait_ctxt * __ocfs2_find_net_wait_ctxt(struct ocfs2_super *osb,
+							       u32 response_id)
+{
+	struct list_head *p;
+	struct ocfs2_net_wait_ctxt *w = NULL;
+
+	list_for_each(p, &osb->net_response_list) {
+		w = list_entry(p, struct ocfs2_net_wait_ctxt, n_list);
+		if (response_id == w->n_response_id)
+			break;
+		w = NULL;
+	}
+
+	return w;
+}
+
+/* Translate response codes into local node errno values */
+static inline int ocfs2_translate_response(int response)
+{
+	int ret;
+
+	switch (response) {
+	case OCFS2_RESPONSE_OK:
+		ret = 0;
+		break;
+
+	case OCFS2_RESPONSE_BUSY:
+		ret = -EBUSY;
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int ocfs2_handle_response_message(struct o2net_msg *msg,
+					 u32 len,
+					 void *data)
+{
+	unsigned int response_id, node_num;
+	int response_status;
+	struct ocfs2_super *osb = data;
+	struct ocfs2_response_msg *resp;
+	struct ocfs2_net_wait_ctxt * w;
+	struct ocfs2_net_response_cb *resp_cb;
+
+	resp = (struct ocfs2_response_msg *) msg->buf;
+
+	response_id = be32_to_cpu(resp->r_hdr.h_response_id);
+	node_num = be32_to_cpu(resp->r_hdr.h_node_num);
+	response_status = 
+		ocfs2_translate_response(be32_to_cpu(resp->r_response));
+
+	mlog(0, "received response message:\n");
+	mlog(0, "h_response_id = %u\n", response_id);
+	mlog(0, "h_request = %u\n", be32_to_cpu(resp->r_hdr.h_request));
+	mlog(0, "h_blkno = %"MLFu64"\n", be64_to_cpu(resp->r_hdr.h_blkno));
+	mlog(0, "h_generation = %u\n", be32_to_cpu(resp->r_hdr.h_generation));
+	mlog(0, "h_node_num = %u\n", node_num);
+	mlog(0, "r_response = %d\n", response_status);
+
+	spin_lock(&osb->net_response_lock);
+	w = __ocfs2_find_net_wait_ctxt(osb, response_id);
+	if (!w) {
+		mlog(0, "request not found!\n");
+		goto bail;
+	}
+	resp_cb = w->n_callback;
+
+	if (response_status && (!w->n_response)) {
+		/* we only really need one negative response so don't
+		 * set it twice. */
+		w->n_response = response_status;
+	}
+
+	if (resp_cb) {
+		spin_unlock(&osb->net_response_lock);
+
+		resp_cb->rc_cb(resp_cb->rc_priv, resp);
+
+		spin_lock(&osb->net_response_lock);
+	}
+
+	__ocfs2_mark_node_responded(osb, w, node_num);
+bail:
+	spin_unlock(&osb->net_response_lock);
+
+	return 0;
+}
+
+static int ocfs2_handle_vote_message(struct o2net_msg *msg,
+				     u32 len,
+				     void *data)
+{
+	int status;
+	struct ocfs2_super *osb = data;
+	struct ocfs2_vote_work *work;
+
+	work = kmalloc(sizeof(struct ocfs2_vote_work), GFP_KERNEL);
+	if (!work) {
+		status = -ENOMEM;
+		mlog_errno(status);
+		goto bail;
+	}
+
+	INIT_LIST_HEAD(&work->w_list);
+	memcpy(&work->w_msg, msg->buf, sizeof(struct ocfs2_vote_msg));
+
+	mlog(0, "scheduling vote request:\n");
+	mlog(0, "h_response_id = %u\n",
+	     be32_to_cpu(work->w_msg.v_hdr.h_response_id));
+	mlog(0, "h_request = %u\n", be32_to_cpu(work->w_msg.v_hdr.h_request));
+	mlog(0, "h_blkno = %"MLFu64"\n",
+	     be64_to_cpu(work->w_msg.v_hdr.h_blkno));
+	mlog(0, "h_generation = %u\n",
+	     be32_to_cpu(work->w_msg.v_hdr.h_generation));
+	mlog(0, "h_node_num = %u\n",
+	     be32_to_cpu(work->w_msg.v_hdr.h_node_num));
+	mlog(0, "v_generic1 = %u\n", be32_to_cpu(work->w_msg.md1.v_generic1));
+
+	spin_lock(&osb->vote_task_lock);
+	list_add_tail(&work->w_list, &osb->vote_list);
+	osb->vote_count++;
+	spin_unlock(&osb->vote_task_lock);
+
+	ocfs2_kick_vote_thread(osb);
+
+	status = 0;
+bail:
+	return status;
+}
+
+void ocfs2_unregister_net_handlers(struct ocfs2_super *osb)
+{
+	if (!osb->net_key)
+		return;
+
+	o2net_unregister_handler_list(&osb->osb_net_handlers);
+
+	if (!list_empty(&osb->net_response_list))
+		mlog(ML_ERROR, "net response list not empty!\n");
+
+	osb->net_key = 0;
+}
+
+int ocfs2_register_net_handlers(struct ocfs2_super *osb)
+{
+	int status = 0;
+
+	status = o2net_register_handler(OCFS2_MESSAGE_TYPE_RESPONSE,
+					osb->net_key,
+					sizeof(struct ocfs2_response_msg),
+					ocfs2_handle_response_message,
+					osb, &osb->osb_net_handlers);
+	if (status) {
+		mlog_errno(status);
+		goto bail;
+	}
+
+	status = o2net_register_handler(OCFS2_MESSAGE_TYPE_VOTE,
+					osb->net_key,
+					sizeof(struct ocfs2_vote_msg),
+					ocfs2_handle_vote_message,
+					osb, &osb->osb_net_handlers);
+	if (status) {
+		mlog_errno(status);
+		goto bail;
+	}
+bail:
+	if (status < 0)
+		ocfs2_unregister_net_handlers(osb);
+
+	return status;
+}
diff --git a/fs/ocfs2/vote.h b/fs/ocfs2/vote.h
new file mode 100644
index 0000000..9cce607
--- /dev/null
+++ b/fs/ocfs2/vote.h
@@ -0,0 +1,56 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * vote.h
+ *
+ * description here
+ *
+ * Copyright (C) 2002, 2004 Oracle.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for 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 021110-1307, USA.
+ */
+
+
+#ifndef VOTE_H
+#define VOTE_H
+
+int ocfs2_vote_thread(void *arg);
+static inline void ocfs2_kick_vote_thread(struct ocfs2_super *osb)
+{
+	spin_lock(&osb->vote_task_lock);
+	/* make sure the voting thread gets a swipe at whatever changes
+	 * the caller may have made to the voting state */
+	osb->vote_wake_sequence++;
+	spin_unlock(&osb->vote_task_lock);
+	wake_up(&osb->vote_event);
+}
+
+int ocfs2_request_delete_vote(struct inode *inode);
+int ocfs2_request_unlink_vote(struct inode *inode,
+			      struct dentry *dentry,
+			      unsigned int nlink);
+int ocfs2_request_rename_vote(struct inode *inode,
+			      struct dentry *dentry);
+int ocfs2_request_mount_vote(struct ocfs2_super *osb);
+int ocfs2_request_umount_vote(struct ocfs2_super *osb);
+int ocfs2_register_net_handlers(struct ocfs2_super *osb);
+void ocfs2_unregister_net_handlers(struct ocfs2_super *osb);
+
+void ocfs2_mark_inode_remotely_deleted(struct inode *inode);
+
+void ocfs2_remove_node_from_vote_queues(struct ocfs2_super *osb,
+					int node_num);
+#endif
diff --git a/fs/open.c b/fs/open.c
index f53a5b9..75f3329 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -194,7 +194,8 @@
 	return error;
 }
 
-int do_truncate(struct dentry *dentry, loff_t length, struct file *filp)
+int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
+	struct file *filp)
 {
 	int err;
 	struct iattr newattrs;
@@ -204,7 +205,7 @@
 		return -EINVAL;
 
 	newattrs.ia_size = length;
-	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+	newattrs.ia_valid = ATTR_SIZE | time_attrs;
 	if (filp) {
 		newattrs.ia_file = filp;
 		newattrs.ia_valid |= ATTR_FILE;
@@ -216,7 +217,7 @@
 	return err;
 }
 
-static inline long do_sys_truncate(const char __user * path, loff_t length)
+static long do_sys_truncate(const char __user * path, loff_t length)
 {
 	struct nameidata nd;
 	struct inode * inode;
@@ -266,7 +267,7 @@
 	error = locks_verify_truncate(inode, NULL, length);
 	if (!error) {
 		DQUOT_INIT(inode);
-		error = do_truncate(nd.dentry, length, NULL);
+		error = do_truncate(nd.dentry, length, 0, NULL);
 	}
 	put_write_access(inode);
 
@@ -282,7 +283,7 @@
 	return do_sys_truncate(path, (long)length);
 }
 
-static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
+static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
 {
 	struct inode * inode;
 	struct dentry *dentry;
@@ -318,7 +319,7 @@
 
 	error = locks_verify_truncate(inode, file, length);
 	if (!error)
-		error = do_truncate(dentry, length, file);
+		error = do_truncate(dentry, length, 0, file);
 out_putf:
 	fput(file);
 out:
@@ -970,7 +971,7 @@
 
 EXPORT_SYMBOL(get_unused_fd);
 
-static inline void __put_unused_fd(struct files_struct *files, unsigned int fd)
+static void __put_unused_fd(struct files_struct *files, unsigned int fd)
 {
 	struct fdtable *fdt = files_fdtable(files);
 	__FD_CLR(fd, fdt->open_fds);
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig
index deb25b6..e227a04 100644
--- a/fs/partitions/Kconfig
+++ b/fs/partitions/Kconfig
@@ -85,7 +85,7 @@
 
 config IBM_PARTITION
 	bool "IBM disk label and partition support"
-	depends on PARTITION_ADVANCED && ARCH_S390
+	depends on PARTITION_ADVANCED && S390
 	help
 	  Say Y here if you would like to be able to read the hard disk
 	  partition table format used by IBM DASD disks operating under CMS.
@@ -203,7 +203,7 @@
 
 config SUN_PARTITION
 	bool "Sun partition tables support" if PARTITION_ADVANCED
-	default y if (SPARC32 || SPARC64 || SUN3 || SUN3X)
+	default y if (SPARC || SUN3 || SUN3X)
 	---help---
 	  Like most systems, SunOS uses its own hard disk partition table
 	  format, incompatible with all others. Saying Y here allows you to
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 8dc1822..7881ce0 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -226,7 +226,7 @@
 static ssize_t part_uevent_store(struct hd_struct * p,
 				 const char *page, size_t count)
 {
-	kobject_hotplug(&p->kobj, KOBJ_ADD);
+	kobject_uevent(&p->kobj, KOBJ_ADD);
 	return count;
 }
 static ssize_t part_dev_read(struct hd_struct * p, char *page)
@@ -336,12 +336,31 @@
 	disk->part[part-1] = p;
 }
 
+static char *make_block_name(struct gendisk *disk)
+{
+	char *name;
+	static char *block_str = "block:";
+	int size;
+
+	size = strlen(block_str) + strlen(disk->disk_name) + 1;
+	name = kmalloc(size, GFP_KERNEL);
+	if (!name)
+		return NULL;
+	strcpy(name, block_str);
+	strcat(name, disk->disk_name);
+	return name;
+}
+
 static void disk_sysfs_symlinks(struct gendisk *disk)
 {
 	struct device *target = get_device(disk->driverfs_dev);
 	if (target) {
+		char *disk_name = make_block_name(disk);
 		sysfs_create_link(&disk->kobj,&target->kobj,"device");
-		sysfs_create_link(&target->kobj,&disk->kobj,"block");
+		if (disk_name) {
+			sysfs_create_link(&target->kobj,&disk->kobj,disk_name);
+			kfree(disk_name);
+		}
 	}
 }
 
@@ -360,7 +379,7 @@
 	if ((err = kobject_add(&disk->kobj)))
 		return;
 	disk_sysfs_symlinks(disk);
-	kobject_hotplug(&disk->kobj, KOBJ_ADD);
+	kobject_uevent(&disk->kobj, KOBJ_ADD);
 
 	/* No minors to use for partitions */
 	if (disk->minors == 1) {
@@ -461,10 +480,14 @@
 	devfs_remove_disk(disk);
 
 	if (disk->driverfs_dev) {
+		char *disk_name = make_block_name(disk);
 		sysfs_remove_link(&disk->kobj, "device");
-		sysfs_remove_link(&disk->driverfs_dev->kobj, "block");
+		if (disk_name) {
+			sysfs_remove_link(&disk->driverfs_dev->kobj, disk_name);
+			kfree(disk_name);
+		}
 		put_device(disk->driverfs_dev);
 	}
-	kobject_hotplug(&disk->kobj, KOBJ_REMOVE);
+	kobject_uevent(&disk->kobj, KOBJ_REMOVE);
 	kobject_del(&disk->kobj);
 }
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index 6327bcb..78010ad 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -56,7 +56,10 @@
 	struct hd_geometry *geo;
 	char type[5] = {0,};
 	char name[7] = {0,};
-	struct vtoc_volume_label *vlabel;
+	union label_t {
+		struct vtoc_volume_label vol;
+		struct vtoc_cms_label cms;
+	} *label;
 	unsigned char *data;
 	Sector sect;
 
@@ -64,9 +67,8 @@
 		goto out_noinfo;
 	if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
 		goto out_nogeo;
-	if ((vlabel = kmalloc(sizeof(struct vtoc_volume_label),
-			      GFP_KERNEL)) == NULL)
-		goto out_novlab;
+	if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL)
+		goto out_nolab;
 	
 	if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
 	    ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
@@ -87,7 +89,7 @@
 		strncpy(name, data + 8, 6);
 	else
 		strncpy(name, data + 4, 6);
-	memcpy (vlabel, data, sizeof(struct vtoc_volume_label));
+	memcpy(label, data, sizeof(union label_t));
 	put_dev_sector(sect);
 
 	EBCASC(type, 4);
@@ -100,14 +102,12 @@
 		/*
 		 * VM style CMS1 labeled disk
 		 */
-		int *label = (int *) vlabel;
-
-		if (label[13] != 0) {
+		if (label->cms.disk_offset != 0) {
 			printk("CMS1/%8s(MDSK):", name);
 			/* disk is reserved minidisk */
-			blocksize = label[3];
-			offset = label[13];
-			size = (label[7] - 1)*(blocksize >> 9);
+			blocksize = label->cms.block_size;
+			offset = label->cms.disk_offset;
+			size = (label->cms.block_count - 1) * (blocksize >> 9);
 		} else {
 			printk("CMS1/%8s:", name);
 			offset = (info->label_block + 1);
@@ -126,7 +126,7 @@
 		printk("VOL1/%8s:", name);
 
 		/* get block number and read then go through format1 labels */
-		blk = cchhb2blk(&vlabel->vtoc, geo) + 1;
+		blk = cchhb2blk(&label->vol.vtoc, geo) + 1;
 		counter = 0;
 		while ((data = read_dev_sector(bdev, blk*(blocksize/512),
 					       &sect)) != NULL) {
@@ -174,7 +174,7 @@
 	}
 
 	printk("\n");
-	kfree(vlabel);
+	kfree(label);
 	kfree(geo);
 	kfree(info);
 	return 1;
@@ -182,8 +182,8 @@
 out_readerr:
 out_badsect:
 out_noioctl:
-	kfree(vlabel);
-out_novlab:
+	kfree(label);
+out_nolab:
 	kfree(geo);
 out_nogeo:
 	kfree(info);
diff --git a/fs/pnode.c b/fs/pnode.c
index aeeec8b..f1871f7 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -103,7 +103,7 @@
 		struct vfsmount *next;
 		struct vfsmount *master = m->mnt_master;
 
-		if ( master == origin->mnt_master ) {
+		if (master == origin->mnt_master) {
 			next = next_peer(m);
 			return ((next == origin) ? NULL : next);
 		} else if (m->mnt_slave.next != &master->mnt_slave_list)
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 3e1239e..5e9251f6 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -308,7 +308,7 @@
 	buffer = task_sig(task, buffer);
 	buffer = task_cap(task, buffer);
 	buffer = cpuset_task_status_allowed(task, buffer);
-#if defined(CONFIG_ARCH_S390)
+#if defined(CONFIG_S390)
 	buffer = task_show_regs(task, buffer);
 #endif
 	return buffer - orig;
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index b638fb5..20e5c45 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -21,6 +21,8 @@
 #include <linux/bitops.h>
 #include <asm/uaccess.h>
 
+#include "internal.h"
+
 static ssize_t proc_file_read(struct file *file, char __user *buf,
 			      size_t nbytes, loff_t *ppos);
 static ssize_t proc_file_write(struct file *file, const char __user *buffer,
@@ -54,6 +56,18 @@
 	ssize_t	n, count;
 	char	*start;
 	struct proc_dir_entry * dp;
+	unsigned long long pos;
+
+	/*
+	 * Gaah, please just use "seq_file" instead. The legacy /proc
+	 * interfaces cut loff_t down to off_t for reads, and ignore
+	 * the offset entirely for writes..
+	 */
+	pos = *ppos;
+	if (pos > MAX_NON_LFS)
+		return 0;
+	if (nbytes > MAX_NON_LFS - pos)
+		nbytes = MAX_NON_LFS - pos;
 
 	dp = PDE(inode);
 	if (!(page = (char*) __get_free_page(GFP_KERNEL)))
@@ -202,30 +216,17 @@
 static loff_t
 proc_file_lseek(struct file *file, loff_t offset, int orig)
 {
-    lock_kernel();
-
-    switch (orig) {
-    case 0:
-	if (offset < 0)
-	    goto out;
-	file->f_pos = offset;
-	unlock_kernel();
-	return(file->f_pos);
-    case 1:
-	if (offset + file->f_pos < 0)
-	    goto out;
-	file->f_pos += offset;
-	unlock_kernel();
-	return(file->f_pos);
-    case 2:
-	goto out;
-    default:
-	goto out;
-    }
-
-out:
-    unlock_kernel();
-    return -EINVAL;
+	loff_t retval = -EINVAL;
+	switch (orig) {
+	case 1:
+		offset += file->f_pos;
+	/* fallthrough */
+	case 0:
+		if (offset < 0 || offset > MAX_NON_LFS)
+			break;
+		file->f_pos = retval = offset;
+	}
+	return retval;
 }
 
 static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index e6a818a..6573f31 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -19,7 +19,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-extern void free_proc_entry(struct proc_dir_entry *);
+#include "internal.h"
 
 static inline struct proc_dir_entry * de_get(struct proc_dir_entry *de)
 {
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 3e55198..95a1cf3 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -37,6 +37,10 @@
 extern int proc_pid_status(struct task_struct *, char *);
 extern int proc_pid_statm(struct task_struct *, char *);
 
+void free_proc_entry(struct proc_dir_entry *de);
+
+int proc_init_inodecache(void);
+
 static inline struct task_struct *proc_task(struct inode *inode)
 {
 	return PROC_I(inode)->task;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 5b6b0b6..63bf6c0 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -323,6 +323,7 @@
 };
 #endif
 
+#ifdef CONFIG_SLAB
 extern struct seq_operations slabinfo_op;
 extern ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *);
 static int slabinfo_open(struct inode *inode, struct file *file)
@@ -336,6 +337,7 @@
 	.llseek		= seq_lseek,
 	.release	= seq_release,
 };
+#endif
 
 static int show_stat(struct seq_file *p, void *v)
 {
@@ -600,7 +602,9 @@
 	create_seq_entry("partitions", 0, &proc_partitions_operations);
 	create_seq_entry("stat", 0, &proc_stat_operations);
 	create_seq_entry("interrupts", 0, &proc_interrupts_operations);
+#ifdef CONFIG_SLAB
 	create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
+#endif
 	create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
 	create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
 	create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
diff --git a/fs/proc/root.c b/fs/proc/root.c
index aef148f..6889628 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -18,6 +18,8 @@
 #include <linux/bitops.h>
 #include <linux/smp_lock.h>
 
+#include "internal.h"
+
 struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
 
 #ifdef CONFIG_SYSCTL
@@ -36,7 +38,6 @@
 	.kill_sb	= kill_anon_super,
 };
 
-extern int __init proc_init_inodecache(void);
 void __init proc_root_init(void)
 {
 	int err = proc_init_inodecache();
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 9ab97ce..0eaad41 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -390,130 +390,12 @@
 };
 
 #ifdef CONFIG_NUMA
-
-struct numa_maps {
-	unsigned long pages;
-	unsigned long anon;
-	unsigned long mapped;
-	unsigned long mapcount_max;
-	unsigned long node[MAX_NUMNODES];
-};
-
-/*
- * Calculate numa node maps for a vma
- */
-static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma)
-{
-	struct page *page;
-	unsigned long vaddr;
-	struct mm_struct *mm = vma->vm_mm;
-	int i;
-	struct numa_maps *md = kmalloc(sizeof(struct numa_maps), GFP_KERNEL);
-
-	if (!md)
-		return NULL;
-	md->pages = 0;
-	md->anon = 0;
-	md->mapped = 0;
-	md->mapcount_max = 0;
-	for_each_node(i)
-		md->node[i] =0;
-
- 	for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) {
-		page = follow_page(mm, vaddr, 0);
-		if (page) {
-			int count = page_mapcount(page);
-
-			if (count)
-				md->mapped++;
-			if (count > md->mapcount_max)
-				md->mapcount_max = count;
-			md->pages++;
-			if (PageAnon(page))
-				md->anon++;
-			md->node[page_to_nid(page)]++;
-		}
-		cond_resched();
-	}
-	return md;
-}
-
-static int show_numa_map(struct seq_file *m, void *v)
-{
-	struct task_struct *task = m->private;
-	struct vm_area_struct *vma = v;
-	struct mempolicy *pol;
-	struct numa_maps *md;
-	struct zone **z;
-	int n;
-	int first;
-
-	if (!vma->vm_mm)
-		return 0;
-
-	md = get_numa_maps(vma);
-	if (!md)
-		return 0;
-
-	seq_printf(m, "%08lx", vma->vm_start);
-	pol = get_vma_policy(task, vma, vma->vm_start);
-	/* Print policy */
-	switch (pol->policy) {
-	case MPOL_PREFERRED:
-		seq_printf(m, " prefer=%d", pol->v.preferred_node);
-		break;
-	case MPOL_BIND:
-		seq_printf(m, " bind={");
-		first = 1;
-		for (z = pol->v.zonelist->zones; *z; z++) {
-
-			if (!first)
-				seq_putc(m, ',');
-			else
-				first = 0;
-			seq_printf(m, "%d/%s", (*z)->zone_pgdat->node_id,
-					(*z)->name);
-		}
-		seq_putc(m, '}');
-		break;
-	case MPOL_INTERLEAVE:
-		seq_printf(m, " interleave={");
-		first = 1;
-		for_each_node(n) {
-			if (node_isset(n, pol->v.nodes)) {
-				if (!first)
-					seq_putc(m,',');
-				else
-					first = 0;
-				seq_printf(m, "%d",n);
-			}
-		}
-		seq_putc(m, '}');
-		break;
-	default:
-		seq_printf(m," default");
-		break;
-	}
-	seq_printf(m, " MaxRef=%lu Pages=%lu Mapped=%lu",
-			md->mapcount_max, md->pages, md->mapped);
-	if (md->anon)
-		seq_printf(m," Anon=%lu",md->anon);
-
-	for_each_online_node(n) {
-		if (md->node[n])
-			seq_printf(m, " N%d=%lu", n, md->node[n]);
-	}
-	seq_putc(m, '\n');
-	kfree(md);
-	if (m->count < m->size)  /* vma is copied successfully */
-		m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
-	return 0;
-}
+extern int show_numa_map(struct seq_file *m, void *v);
 
 struct seq_operations proc_pid_numa_maps_op = {
-	.start	= m_start,
-	.next	= m_next,
-	.stop	= m_stop,
-	.show	= show_numa_map
+        .start  = m_start,
+        .next   = m_next,
+        .stop   = m_stop,
+        .show   = show_numa_map
 };
 #endif
diff --git a/fs/qnx4/bitmap.c b/fs/qnx4/bitmap.c
index 9912539..46efbf5 100644
--- a/fs/qnx4/bitmap.c
+++ b/fs/qnx4/bitmap.c
@@ -23,10 +23,12 @@
 #include <linux/buffer_head.h>
 #include <linux/bitops.h>
 
+#if 0
 int qnx4_new_block(struct super_block *sb)
 {
 	return 0;
 }
+#endif  /*  0  */
 
 static void count_bits(register const char *bmPart, register int size,
 		       int *const tf)
diff --git a/fs/ramfs/Makefile b/fs/ramfs/Makefile
index f096f30..5a0236e 100644
--- a/fs/ramfs/Makefile
+++ b/fs/ramfs/Makefile
@@ -4,4 +4,6 @@
 
 obj-$(CONFIG_RAMFS) += ramfs.o
 
-ramfs-objs := inode.o
+file-mmu-y := file-nommu.o
+file-mmu-$(CONFIG_MMU) := file-mmu.o
+ramfs-objs += inode.o $(file-mmu-y)
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
new file mode 100644
index 0000000..2115383
--- /dev/null
+++ b/fs/ramfs/file-mmu.c
@@ -0,0 +1,57 @@
+/* file-mmu.c: ramfs MMU-based file operations
+ *
+ * Resizable simple ram filesystem for Linux.
+ *
+ * Copyright (C) 2000 Linus Torvalds.
+ *               2000 Transmeta Corp.
+ *
+ * Usage limits added by David Gibson, Linuxcare Australia.
+ * This file is released under the GPL.
+ */
+
+/*
+ * NOTE! This filesystem is probably most useful
+ * not as a real filesystem, but as an example of
+ * how virtual filesystems can be written.
+ *
+ * It doesn't get much simpler than this. Consider
+ * that this file implements the full semantics of
+ * a POSIX-compliant read-write filesystem.
+ *
+ * Note in particular how the filesystem does not
+ * need to implement any data structures of its own
+ * to keep track of the virtual data: using the VFS
+ * caches is sufficient.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/backing-dev.h>
+#include <linux/ramfs.h>
+
+#include <asm/uaccess.h>
+#include "internal.h"
+
+struct address_space_operations ramfs_aops = {
+	.readpage	= simple_readpage,
+	.prepare_write	= simple_prepare_write,
+	.commit_write	= simple_commit_write
+};
+
+struct file_operations ramfs_file_operations = {
+	.read		= generic_file_read,
+	.write		= generic_file_write,
+	.mmap		= generic_file_mmap,
+	.fsync		= simple_sync_file,
+	.sendfile	= generic_file_sendfile,
+	.llseek		= generic_file_llseek,
+};
+
+struct inode_operations ramfs_file_inode_operations = {
+	.getattr	= simple_getattr,
+};
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
new file mode 100644
index 0000000..3f810ac
--- /dev/null
+++ b/fs/ramfs/file-nommu.c
@@ -0,0 +1,292 @@
+/* file-nommu.c: no-MMU version of ramfs
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/smp_lock.h>
+#include <linux/backing-dev.h>
+#include <linux/ramfs.h>
+#include <linux/quotaops.h>
+#include <linux/pagevec.h>
+#include <linux/mman.h>
+
+#include <asm/uaccess.h>
+#include "internal.h"
+
+static int ramfs_nommu_setattr(struct dentry *, struct iattr *);
+
+struct address_space_operations ramfs_aops = {
+	.readpage		= simple_readpage,
+	.prepare_write		= simple_prepare_write,
+	.commit_write		= simple_commit_write
+};
+
+struct file_operations ramfs_file_operations = {
+	.mmap			= ramfs_nommu_mmap,
+	.get_unmapped_area	= ramfs_nommu_get_unmapped_area,
+	.read			= generic_file_read,
+	.write			= generic_file_write,
+	.fsync			= simple_sync_file,
+	.sendfile		= generic_file_sendfile,
+	.llseek			= generic_file_llseek,
+};
+
+struct inode_operations ramfs_file_inode_operations = {
+	.setattr		= ramfs_nommu_setattr,
+	.getattr		= simple_getattr,
+};
+
+/*****************************************************************************/
+/*
+ * add a contiguous set of pages into a ramfs inode when it's truncated from
+ * size 0 on the assumption that it's going to be used for an mmap of shared
+ * memory
+ */
+static int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
+{
+	struct pagevec lru_pvec;
+	unsigned long npages, xpages, loop, limit;
+	struct page *pages;
+	unsigned order;
+	void *data;
+	int ret;
+
+	/* make various checks */
+	order = get_order(newsize);
+	if (unlikely(order >= MAX_ORDER))
+		goto too_big;
+
+	limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+	if (limit != RLIM_INFINITY && newsize > limit)
+		goto fsize_exceeded;
+
+	if (newsize > inode->i_sb->s_maxbytes)
+		goto too_big;
+
+	i_size_write(inode, newsize);
+
+	/* allocate enough contiguous pages to be able to satisfy the
+	 * request */
+	pages = alloc_pages(mapping_gfp_mask(inode->i_mapping), order);
+	if (!pages)
+		return -ENOMEM;
+
+	/* split the high-order page into an array of single pages */
+	xpages = 1UL << order;
+	npages = (newsize + PAGE_SIZE - 1) >> PAGE_SHIFT;
+
+	for (loop = 0; loop < npages; loop++)
+		set_page_count(pages + loop, 1);
+
+	/* trim off any pages we don't actually require */
+	for (loop = npages; loop < xpages; loop++)
+		__free_page(pages + loop);
+
+	/* clear the memory we allocated */
+	newsize = PAGE_SIZE * npages;
+	data = page_address(pages);
+	memset(data, 0, newsize);
+
+	/* attach all the pages to the inode's address space */
+	pagevec_init(&lru_pvec, 0);
+	for (loop = 0; loop < npages; loop++) {
+		struct page *page = pages + loop;
+
+		ret = add_to_page_cache(page, inode->i_mapping, loop, GFP_KERNEL);
+		if (ret < 0)
+			goto add_error;
+
+		if (!pagevec_add(&lru_pvec, page))
+			__pagevec_lru_add(&lru_pvec);
+
+		unlock_page(page);
+	}
+
+	pagevec_lru_add(&lru_pvec);
+	return 0;
+
+ fsize_exceeded:
+	send_sig(SIGXFSZ, current, 0);
+ too_big:
+	return -EFBIG;
+
+ add_error:
+	page_cache_release(pages + loop);
+	for (loop++; loop < npages; loop++)
+		__free_page(pages + loop);
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * check that file shrinkage doesn't leave any VMAs dangling in midair
+ */
+static int ramfs_nommu_check_mappings(struct inode *inode,
+				      size_t newsize, size_t size)
+{
+	struct vm_area_struct *vma;
+	struct prio_tree_iter iter;
+
+	/* search for VMAs that fall within the dead zone */
+	vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
+			      newsize >> PAGE_SHIFT,
+			      (size + PAGE_SIZE - 1) >> PAGE_SHIFT
+			      ) {
+		/* found one - only interested if it's shared out of the page
+		 * cache */
+		if (vma->vm_flags & VM_SHARED)
+			return -ETXTBSY; /* not quite true, but near enough */
+	}
+
+	return 0;
+}
+
+/*****************************************************************************/
+/*
+ *
+ */
+static int ramfs_nommu_resize(struct inode *inode, loff_t newsize, loff_t size)
+{
+	int ret;
+
+	/* assume a truncate from zero size is going to be for the purposes of
+	 * shared mmap */
+	if (size == 0) {
+		if (unlikely(newsize >> 32))
+			return -EFBIG;
+
+		return ramfs_nommu_expand_for_mapping(inode, newsize);
+	}
+
+	/* check that a decrease in size doesn't cut off any shared mappings */
+	if (newsize < size) {
+		ret = ramfs_nommu_check_mappings(inode, newsize, size);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = vmtruncate(inode, size);
+
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * handle a change of attributes
+ * - we're specifically interested in a change of size
+ */
+static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia)
+{
+	struct inode *inode = dentry->d_inode;
+	unsigned int old_ia_valid = ia->ia_valid;
+	int ret = 0;
+
+	/* by providing our own setattr() method, we skip this quotaism */
+	if ((old_ia_valid & ATTR_UID && ia->ia_uid != inode->i_uid) ||
+	    (old_ia_valid & ATTR_GID && ia->ia_gid != inode->i_gid))
+		ret = DQUOT_TRANSFER(inode, ia) ? -EDQUOT : 0;
+
+	/* pick out size-changing events */
+	if (ia->ia_valid & ATTR_SIZE) {
+		loff_t size = i_size_read(inode);
+		if (ia->ia_size != size) {
+			ret = ramfs_nommu_resize(inode, ia->ia_size, size);
+			if (ret < 0 || ia->ia_valid == ATTR_SIZE)
+				goto out;
+		} else {
+			/* we skipped the truncate but must still update
+			 * timestamps
+			 */
+			ia->ia_valid |= ATTR_MTIME|ATTR_CTIME;
+		}
+	}
+
+	ret = inode_setattr(inode, ia);
+ out:
+	ia->ia_valid = old_ia_valid;
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * try to determine where a shared mapping can be made
+ * - we require that:
+ *   - the pages to be mapped must exist
+ *   - the pages be physically contiguous in sequence
+ */
+unsigned long ramfs_nommu_get_unmapped_area(struct file *file,
+					    unsigned long addr, unsigned long len,
+					    unsigned long pgoff, unsigned long flags)
+{
+	unsigned long maxpages, lpages, nr, loop, ret;
+	struct inode *inode = file->f_dentry->d_inode;
+	struct page **pages = NULL, **ptr, *page;
+	loff_t isize;
+
+	if (!(flags & MAP_SHARED))
+		return addr;
+
+	/* the mapping mustn't extend beyond the EOF */
+	lpages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	isize = i_size_read(inode);
+
+	ret = -EINVAL;
+	maxpages = (isize + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	if (pgoff >= maxpages)
+		goto out;
+
+	if (maxpages - pgoff < lpages)
+		goto out;
+
+	/* gang-find the pages */
+	ret = -ENOMEM;
+	pages = kzalloc(lpages * sizeof(struct page *), GFP_KERNEL);
+	if (!pages)
+		goto out;
+
+	nr = find_get_pages(inode->i_mapping, pgoff, lpages, pages);
+	if (nr != lpages)
+		goto out; /* leave if some pages were missing */
+
+	/* check the pages for physical adjacency */
+	ptr = pages;
+	page = *ptr++;
+	page++;
+	for (loop = lpages; loop > 1; loop--)
+		if (*ptr++ != page++)
+			goto out;
+
+	/* okay - all conditions fulfilled */
+	ret = (unsigned long) page_address(pages[0]);
+
+ out:
+	if (pages) {
+		ptr = pages;
+		for (loop = lpages; loop > 0; loop--)
+			put_page(*ptr++);
+		kfree(pages);
+	}
+
+	return ret;
+}
+
+/*****************************************************************************/
+/*
+ * set up a mapping
+ */
+int ramfs_nommu_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	return 0;
+}
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index 0a88917..c66bd5e 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -34,13 +34,12 @@
 #include <linux/ramfs.h>
 
 #include <asm/uaccess.h>
+#include "internal.h"
 
 /* some random number */
 #define RAMFS_MAGIC	0x858458f6
 
 static struct super_operations ramfs_ops;
-static struct address_space_operations ramfs_aops;
-static struct inode_operations ramfs_file_inode_operations;
 static struct inode_operations ramfs_dir_inode_operations;
 
 static struct backing_dev_info ramfs_backing_dev_info = {
@@ -142,25 +141,6 @@
 	return error;
 }
 
-static struct address_space_operations ramfs_aops = {
-	.readpage	= simple_readpage,
-	.prepare_write	= simple_prepare_write,
-	.commit_write	= simple_commit_write
-};
-
-struct file_operations ramfs_file_operations = {
-	.read		= generic_file_read,
-	.write		= generic_file_write,
-	.mmap		= generic_file_mmap,
-	.fsync		= simple_sync_file,
-	.sendfile	= generic_file_sendfile,
-	.llseek		= generic_file_llseek,
-};
-
-static struct inode_operations ramfs_file_inode_operations = {
-	.getattr	= simple_getattr,
-};
-
 static struct inode_operations ramfs_dir_inode_operations = {
 	.create		= ramfs_create,
 	.lookup		= simple_lookup,
diff --git a/fs/ramfs/internal.h b/fs/ramfs/internal.h
new file mode 100644
index 0000000..272c8a7
--- /dev/null
+++ b/fs/ramfs/internal.h
@@ -0,0 +1,15 @@
+/* internal.h: ramfs internal definitions
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+
+extern struct address_space_operations ramfs_aops;
+extern struct file_operations ramfs_file_operations;
+extern struct inode_operations ramfs_file_inode_operations;
diff --git a/fs/read_write.c b/fs/read_write.c
index a091ee4..df3468a 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -14,6 +14,7 @@
 #include <linux/security.h>
 #include <linux/module.h>
 #include <linux/syscalls.h>
+#include <linux/pagemap.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -182,22 +183,33 @@
 }
 #endif
 
+/*
+ * rw_verify_area doesn't like huge counts. We limit
+ * them to something that fits in "int" so that others
+ * won't have to do range checks all the time.
+ */
+#define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
 
 int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count)
 {
 	struct inode *inode;
 	loff_t pos;
 
-	if (unlikely(count > INT_MAX))
+	if (unlikely((ssize_t) count < 0))
 		goto Einval;
 	pos = *ppos;
 	if (unlikely((pos < 0) || (loff_t) (pos + count) < 0))
 		goto Einval;
 
 	inode = file->f_dentry->d_inode;
-	if (inode->i_flock && MANDATORY_LOCK(inode))
-		return locks_mandatory_area(read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE, inode, file, pos, count);
-	return 0;
+	if (inode->i_flock && MANDATORY_LOCK(inode)) {
+		int retval = locks_mandatory_area(
+			read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
+			inode, file, pos, count);
+		if (retval < 0)
+			return retval;
+	}
+	return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
 
 Einval:
 	return -EINVAL;
@@ -244,7 +256,8 @@
 		return -EFAULT;
 
 	ret = rw_verify_area(READ, file, pos, count);
-	if (!ret) {
+	if (ret >= 0) {
+		count = ret;
 		ret = security_file_permission (file, MAY_READ);
 		if (!ret) {
 			if (file->f_op->read)
@@ -295,7 +308,8 @@
 		return -EFAULT;
 
 	ret = rw_verify_area(WRITE, file, pos, count);
-	if (!ret) {
+	if (ret >= 0) {
+		count = ret;
 		ret = security_file_permission (file, MAY_WRITE);
 		if (!ret) {
 			if (file->f_op->write)
@@ -497,7 +511,7 @@
 	}
 
 	ret = rw_verify_area(type, file, pos, tot_len);
-	if (ret)
+	if (ret < 0)
 		goto out;
 	ret = security_file_permission(file, type == READ ? MAY_READ : MAY_WRITE);
 	if (ret)
@@ -653,8 +667,9 @@
 		if (!(in_file->f_mode & FMODE_PREAD))
 			goto fput_in;
 	retval = rw_verify_area(READ, in_file, ppos, count);
-	if (retval)
+	if (retval < 0)
 		goto fput_in;
+	count = retval;
 
 	retval = security_file_permission (in_file, MAY_READ);
 	if (retval)
@@ -674,8 +689,9 @@
 		goto fput_out;
 	out_inode = out_file->f_dentry->d_inode;
 	retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
-	if (retval)
+	if (retval < 0)
 		goto fput_out;
+	count = retval;
 
 	retval = security_file_permission (out_file, MAY_WRITE);
 	if (retval)
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 5f82352..a5e3a0d 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -32,6 +32,7 @@
 	    JOURNAL_PER_BALANCE_CNT * 2 +
 	    2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb);
 	struct reiserfs_transaction_handle th;
+	int err;
 
 	truncate_inode_pages(&inode->i_data, 0);
 
@@ -49,15 +50,13 @@
 		}
 		reiserfs_update_inode_transaction(inode);
 
-		if (reiserfs_delete_object(&th, inode)) {
-			up(&inode->i_sem);
-			goto out;
-		}
+		err = reiserfs_delete_object(&th, inode);
 
 		/* Do quota update inside a transaction for journaled quotas. We must do that
 		 * after delete_object so that quota updates go into the same transaction as
 		 * stat data deletion */
-		DQUOT_FREE_INODE(inode);
+		if (!err) 
+			DQUOT_FREE_INODE(inode);
 
 		if (journal_end(&th, inode->i_sb, jbegin_count)) {
 			up(&inode->i_sem);
@@ -66,6 +65,12 @@
 
 		up(&inode->i_sem);
 
+		/* check return value from reiserfs_delete_object after
+		 * ending the transaction
+		 */
+		if (err)
+		    goto out;
+
 		/* all items of file are deleted, so we can remove "save" link */
 		remove_save_link(inode, 0 /* not truncate */ );	/* we can't do anything
 								 * about an error here */
@@ -2099,6 +2104,7 @@
 	struct page *page = NULL;
 	int error;
 	struct buffer_head *bh = NULL;
+	int err2;
 
 	reiserfs_write_lock(p_s_inode->i_sb);
 
@@ -2136,14 +2142,18 @@
 		   transaction of truncating gets committed - on reboot the file
 		   either appears truncated properly or not truncated at all */
 		add_save_link(&th, p_s_inode, 1);
-	error = reiserfs_do_truncate(&th, p_s_inode, page, update_timestamps);
-	if (error)
-		goto out;
+	err2 = reiserfs_do_truncate(&th, p_s_inode, page, update_timestamps);
 	error =
 	    journal_end(&th, p_s_inode->i_sb, JOURNAL_PER_BALANCE_CNT * 2 + 1);
 	if (error)
 		goto out;
 
+	/* check reiserfs_do_truncate after ending the transaction */
+	if (err2) {
+		error = err2;
+  		goto out;
+	}
+	
 	if (update_timestamps) {
 		error = remove_save_link(p_s_inode, 1 /* truncate */ );
 		if (error)
@@ -2194,7 +2204,7 @@
 	INITIALIZE_PATH(path);
 	int pos_in_item;
 	int jbegin_count = JOURNAL_PER_BALANCE_CNT;
-	loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1;
+	loff_t byte_offset = ((loff_t)block << inode->i_sb->s_blocksize_bits)+1;
 	int retval;
 	int use_get_block = 0;
 	int bytes_copied = 0;
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 4b15761..3f17ef8 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -1039,6 +1039,10 @@
 	}
 	atomic_dec(&journal->j_async_throttle);
 
+	/* We're skipping the commit if there's an error */
+	if (retval || reiserfs_is_journal_aborted(journal))
+		barrier = 0;
+
 	/* wait on everything written so far before writing the commit
 	 * if we are in barrier mode, send the commit down now
 	 */
@@ -1077,10 +1081,16 @@
 	BUG_ON(atomic_read(&(jl->j_commit_left)) != 1);
 
 	if (!barrier) {
-		if (buffer_dirty(jl->j_commit_bh))
-			BUG();
-		mark_buffer_dirty(jl->j_commit_bh);
-		sync_dirty_buffer(jl->j_commit_bh);
+		/* If there was a write error in the journal - we can't commit
+		 * this transaction - it will be invalid and, if successful,
+		 * will just end up propogating the write error out to
+		 * the file system. */
+		if (likely(!retval && !reiserfs_is_journal_aborted (journal))) {
+			if (buffer_dirty(jl->j_commit_bh))
+				BUG();
+			mark_buffer_dirty(jl->j_commit_bh) ;
+			sync_dirty_buffer(jl->j_commit_bh) ;
+		}
 	} else
 		wait_on_buffer(jl->j_commit_bh);
 
@@ -2757,6 +2767,15 @@
 	journal->j_cnode_used = 0;
 	journal->j_must_wait = 0;
 
+	if (journal->j_cnode_free == 0) {
+        	reiserfs_warning(p_s_sb, "journal-2004: Journal cnode memory "
+		                 "allocation failed (%ld bytes). Journal is "
+		                 "too large for available memory. Usually "
+		                 "this is due to a journal that is too large.",
+		                 sizeof (struct reiserfs_journal_cnode) * num_cnodes);
+        	goto free_and_return;
+	}
+
 	init_journal_hash(p_s_sb);
 	jl = journal->j_current_jl;
 	jl->j_list_bitmap = get_list_bitmap(p_s_sb, jl);
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 72e1207..02091ea 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -115,8 +115,8 @@
 }
 
 /* Returns the dentry (or NULL) referring to the root of the extended
- * attribute directory tree. If it has already been retreived, it is used.
- * Otherwise, we attempt to retreive it from disk. It may also return
+ * attribute directory tree. If it has already been retrieved, it is used.
+ * Otherwise, we attempt to retrieve it from disk. It may also return
  * a pointer-encoded error.
  */
 static inline struct dentry *get_xa_root(struct super_block *s)
diff --git a/fs/relayfs/buffers.c b/fs/relayfs/buffers.c
index 84e21ff..1018781 100644
--- a/fs/relayfs/buffers.c
+++ b/fs/relayfs/buffers.c
@@ -185,5 +185,6 @@
 void relay_remove_buf(struct kref *kref)
 {
 	struct rchan_buf *buf = container_of(kref, struct rchan_buf, kref);
-	relayfs_remove(buf->dentry);
+	buf->chan->cb->remove_buf_file(buf->dentry);
+	relay_destroy_buf(buf);
 }
diff --git a/fs/relayfs/inode.c b/fs/relayfs/inode.c
index 0f7f88d..7b7f2cb 100644
--- a/fs/relayfs/inode.c
+++ b/fs/relayfs/inode.c
@@ -26,31 +26,22 @@
 
 static struct vfsmount *		relayfs_mount;
 static int				relayfs_mount_count;
-static kmem_cache_t *			relayfs_inode_cachep;
 
 static struct backing_dev_info		relayfs_backing_dev_info = {
 	.ra_pages	= 0,	/* No readahead */
 	.capabilities	= BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
 };
 
-static struct inode *relayfs_get_inode(struct super_block *sb, int mode,
-				       struct rchan *chan)
+static struct inode *relayfs_get_inode(struct super_block *sb,
+				       int mode,
+ 				       struct file_operations *fops,
+				       void *data)
 {
-	struct rchan_buf *buf = NULL;
 	struct inode *inode;
 
-	if (S_ISREG(mode)) {
-		BUG_ON(!chan);
-		buf = relay_create_buf(chan);
-		if (!buf)
-			return NULL;
-	}
-
 	inode = new_inode(sb);
-	if (!inode) {
-		relay_destroy_buf(buf);
+	if (!inode)
 		return NULL;
-	}
 
 	inode->i_mode = mode;
 	inode->i_uid = 0;
@@ -61,8 +52,9 @@
 	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	switch (mode & S_IFMT) {
 	case S_IFREG:
-		inode->i_fop = &relayfs_file_operations;
-		RELAYFS_I(inode)->buf = buf;
+		inode->i_fop = fops;
+		if (data)
+			inode->u.generic_ip = data;
 		break;
 	case S_IFDIR:
 		inode->i_op = &simple_dir_inode_operations;
@@ -83,7 +75,8 @@
  *	@name: the name of the file to create
  *	@parent: parent directory
  *	@mode: mode
- *	@chan: relay channel associated with the file
+ *	@fops: file operations to use for the file
+ *	@data: user-associated data for this file
  *
  *	Returns the new dentry, NULL on failure
  *
@@ -92,7 +85,8 @@
 static struct dentry *relayfs_create_entry(const char *name,
 					   struct dentry *parent,
 					   int mode,
-					   struct rchan *chan)
+					   struct file_operations *fops,
+					   void *data)
 {
 	struct dentry *d;
 	struct inode *inode;
@@ -127,7 +121,7 @@
 		goto release_mount;
 	}
 
-	inode = relayfs_get_inode(parent->d_inode->i_sb, mode, chan);
+	inode = relayfs_get_inode(parent->d_inode->i_sb, mode, fops, data);
 	if (!inode) {
 		d = NULL;
 		goto release_mount;
@@ -155,20 +149,26 @@
  *	@name: the name of the file to create
  *	@parent: parent directory
  *	@mode: mode, if not specied the default perms are used
- *	@chan: channel associated with the file
+ *	@fops: file operations to use for the file
+ *	@data: user-associated data for this file
  *
  *	Returns file dentry if successful, NULL otherwise.
  *
  *	The file will be created user r on behalf of current user.
  */
-struct dentry *relayfs_create_file(const char *name, struct dentry *parent,
-				   int mode, struct rchan *chan)
+struct dentry *relayfs_create_file(const char *name,
+				   struct dentry *parent,
+				   int mode,
+				   struct file_operations *fops,
+				   void *data)
 {
+	BUG_ON(!fops);
+
 	if (!mode)
 		mode = S_IRUSR;
 	mode = (mode & S_IALLUGO) | S_IFREG;
 
-	return relayfs_create_entry(name, parent, mode, chan);
+	return relayfs_create_entry(name, parent, mode, fops, data);
 }
 
 /**
@@ -183,7 +183,7 @@
 struct dentry *relayfs_create_dir(const char *name, struct dentry *parent)
 {
 	int mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;
-	return relayfs_create_entry(name, parent, mode, NULL);
+	return relayfs_create_entry(name, parent, mode, NULL, NULL);
 }
 
 /**
@@ -225,6 +225,17 @@
 }
 
 /**
+ *	relayfs_remove_file - remove a file from relay filesystem
+ *	@dentry: directory dentry
+ *
+ *	Returns 0 if successful, negative otherwise.
+ */
+int relayfs_remove_file(struct dentry *dentry)
+{
+	return relayfs_remove(dentry);
+}
+
+/**
  *	relayfs_remove_dir - remove a directory in the relay filesystem
  *	@dentry: directory dentry
  *
@@ -236,45 +247,45 @@
 }
 
 /**
- *	relayfs_open - open file op for relayfs files
+ *	relay_file_open - open file op for relay files
  *	@inode: the inode
  *	@filp: the file
  *
  *	Increments the channel buffer refcount.
  */
-static int relayfs_open(struct inode *inode, struct file *filp)
+static int relay_file_open(struct inode *inode, struct file *filp)
 {
-	struct rchan_buf *buf = RELAYFS_I(inode)->buf;
+	struct rchan_buf *buf = inode->u.generic_ip;
 	kref_get(&buf->kref);
+	filp->private_data = buf;
 
 	return 0;
 }
 
 /**
- *	relayfs_mmap - mmap file op for relayfs files
+ *	relay_file_mmap - mmap file op for relay files
  *	@filp: the file
  *	@vma: the vma describing what to map
  *
  *	Calls upon relay_mmap_buf to map the file into user space.
  */
-static int relayfs_mmap(struct file *filp, struct vm_area_struct *vma)
+static int relay_file_mmap(struct file *filp, struct vm_area_struct *vma)
 {
-	struct inode *inode = filp->f_dentry->d_inode;
-	return relay_mmap_buf(RELAYFS_I(inode)->buf, vma);
+	struct rchan_buf *buf = filp->private_data;
+	return relay_mmap_buf(buf, vma);
 }
 
 /**
- *	relayfs_poll - poll file op for relayfs files
+ *	relay_file_poll - poll file op for relay files
  *	@filp: the file
  *	@wait: poll table
  *
  *	Poll implemention.
  */
-static unsigned int relayfs_poll(struct file *filp, poll_table *wait)
+static unsigned int relay_file_poll(struct file *filp, poll_table *wait)
 {
 	unsigned int mask = 0;
-	struct inode *inode = filp->f_dentry->d_inode;
-	struct rchan_buf *buf = RELAYFS_I(inode)->buf;
+	struct rchan_buf *buf = filp->private_data;
 
 	if (buf->finalized)
 		return POLLERR;
@@ -289,27 +300,27 @@
 }
 
 /**
- *	relayfs_release - release file op for relayfs files
+ *	relay_file_release - release file op for relay files
  *	@inode: the inode
  *	@filp: the file
  *
  *	Decrements the channel refcount, as the filesystem is
  *	no longer using it.
  */
-static int relayfs_release(struct inode *inode, struct file *filp)
+static int relay_file_release(struct inode *inode, struct file *filp)
 {
-	struct rchan_buf *buf = RELAYFS_I(inode)->buf;
+	struct rchan_buf *buf = filp->private_data;
 	kref_put(&buf->kref, relay_remove_buf);
 
 	return 0;
 }
 
 /**
- *	relayfs_read_consume - update the consumed count for the buffer
+ *	relay_file_read_consume - update the consumed count for the buffer
  */
-static void relayfs_read_consume(struct rchan_buf *buf,
-				 size_t read_pos,
-				 size_t bytes_consumed)
+static void relay_file_read_consume(struct rchan_buf *buf,
+				    size_t read_pos,
+				    size_t bytes_consumed)
 {
 	size_t subbuf_size = buf->chan->subbuf_size;
 	size_t n_subbufs = buf->chan->n_subbufs;
@@ -332,9 +343,9 @@
 }
 
 /**
- *	relayfs_read_avail - boolean, are there unconsumed bytes available?
+ *	relay_file_read_avail - boolean, are there unconsumed bytes available?
  */
-static int relayfs_read_avail(struct rchan_buf *buf, size_t read_pos)
+static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
 {
 	size_t bytes_produced, bytes_consumed, write_offset;
 	size_t subbuf_size = buf->chan->subbuf_size;
@@ -365,16 +376,16 @@
 	if (bytes_produced == bytes_consumed)
 		return 0;
 
-	relayfs_read_consume(buf, read_pos, 0);
+	relay_file_read_consume(buf, read_pos, 0);
 
 	return 1;
 }
 
 /**
- *	relayfs_read_subbuf_avail - return bytes available in sub-buffer
+ *	relay_file_read_subbuf_avail - return bytes available in sub-buffer
  */
-static size_t relayfs_read_subbuf_avail(size_t read_pos,
-					struct rchan_buf *buf)
+static size_t relay_file_read_subbuf_avail(size_t read_pos,
+					   struct rchan_buf *buf)
 {
 	size_t padding, avail = 0;
 	size_t read_subbuf, read_offset, write_subbuf, write_offset;
@@ -396,14 +407,14 @@
 }
 
 /**
- *	relayfs_read_start_pos - find the first available byte to read
+ *	relay_file_read_start_pos - find the first available byte to read
  *
  *	If the read_pos is in the middle of padding, return the
  *	position of the first actually available byte, otherwise
  *	return the original value.
  */
-static size_t relayfs_read_start_pos(size_t read_pos,
-				     struct rchan_buf *buf)
+static size_t relay_file_read_start_pos(size_t read_pos,
+					struct rchan_buf *buf)
 {
 	size_t read_subbuf, padding, padding_start, padding_end;
 	size_t subbuf_size = buf->chan->subbuf_size;
@@ -422,11 +433,11 @@
 }
 
 /**
- *	relayfs_read_end_pos - return the new read position
+ *	relay_file_read_end_pos - return the new read position
  */
-static size_t relayfs_read_end_pos(struct rchan_buf *buf,
-				   size_t read_pos,
-				   size_t count)
+static size_t relay_file_read_end_pos(struct rchan_buf *buf,
+				      size_t read_pos,
+				      size_t count)
 {
 	size_t read_subbuf, padding, end_pos;
 	size_t subbuf_size = buf->chan->subbuf_size;
@@ -445,7 +456,7 @@
 }
 
 /**
- *	relayfs_read - read file op for relayfs files
+ *	relay_file_read - read file op for relay files
  *	@filp: the file
  *	@buffer: the userspace buffer
  *	@count: number of bytes to read
@@ -454,23 +465,23 @@
  *	Reads count bytes or the number of bytes available in the
  *	current sub-buffer being read, whichever is smaller.
  */
-static ssize_t relayfs_read(struct file *filp,
-			    char __user *buffer,
-			    size_t count,
-			    loff_t *ppos)
+static ssize_t relay_file_read(struct file *filp,
+			       char __user *buffer,
+			       size_t count,
+			       loff_t *ppos)
 {
+	struct rchan_buf *buf = filp->private_data;
 	struct inode *inode = filp->f_dentry->d_inode;
-	struct rchan_buf *buf = RELAYFS_I(inode)->buf;
 	size_t read_start, avail;
 	ssize_t ret = 0;
 	void *from;
 
 	down(&inode->i_sem);
-	if(!relayfs_read_avail(buf, *ppos))
+	if(!relay_file_read_avail(buf, *ppos))
 		goto out;
 
-	read_start = relayfs_read_start_pos(*ppos, buf);
-	avail = relayfs_read_subbuf_avail(read_start, buf);
+	read_start = relay_file_read_start_pos(*ppos, buf);
+	avail = relay_file_read_subbuf_avail(read_start, buf);
 	if (!avail)
 		goto out;
 
@@ -480,58 +491,25 @@
 		ret = -EFAULT;
 		goto out;
 	}
-	relayfs_read_consume(buf, read_start, count);
-	*ppos = relayfs_read_end_pos(buf, read_start, count);
+	relay_file_read_consume(buf, read_start, count);
+	*ppos = relay_file_read_end_pos(buf, read_start, count);
 out:
 	up(&inode->i_sem);
 	return ret;
 }
 
-/**
- *	relayfs alloc_inode() implementation
- */
-static struct inode *relayfs_alloc_inode(struct super_block *sb)
-{
-	struct relayfs_inode_info *p = kmem_cache_alloc(relayfs_inode_cachep, SLAB_KERNEL);
-	if (!p)
-		return NULL;
-	p->buf = NULL;
-
-	return &p->vfs_inode;
-}
-
-/**
- *	relayfs destroy_inode() implementation
- */
-static void relayfs_destroy_inode(struct inode *inode)
-{
-	if (RELAYFS_I(inode)->buf)
-		relay_destroy_buf(RELAYFS_I(inode)->buf);
-
-	kmem_cache_free(relayfs_inode_cachep, RELAYFS_I(inode));
-}
-
-static void init_once(void *p, kmem_cache_t *cachep, unsigned long flags)
-{
-	struct relayfs_inode_info *i = p;
-	if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR)
-		inode_init_once(&i->vfs_inode);
-}
-
-struct file_operations relayfs_file_operations = {
-	.open		= relayfs_open,
-	.poll		= relayfs_poll,
-	.mmap		= relayfs_mmap,
-	.read		= relayfs_read,
+struct file_operations relay_file_operations = {
+	.open		= relay_file_open,
+	.poll		= relay_file_poll,
+	.mmap		= relay_file_mmap,
+	.read		= relay_file_read,
 	.llseek		= no_llseek,
-	.release	= relayfs_release,
+	.release	= relay_file_release,
 };
 
 static struct super_operations relayfs_ops = {
 	.statfs		= simple_statfs,
 	.drop_inode	= generic_delete_inode,
-	.alloc_inode	= relayfs_alloc_inode,
-	.destroy_inode	= relayfs_destroy_inode,
 };
 
 static int relayfs_fill_super(struct super_block * sb, void * data, int silent)
@@ -544,7 +522,7 @@
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = RELAYFS_MAGIC;
 	sb->s_op = &relayfs_ops;
-	inode = relayfs_get_inode(sb, mode, NULL);
+	inode = relayfs_get_inode(sb, mode, NULL, NULL);
 
 	if (!inode)
 		return -ENOMEM;
@@ -575,33 +553,27 @@
 
 static int __init init_relayfs_fs(void)
 {
-	int err;
-
-	relayfs_inode_cachep = kmem_cache_create("relayfs_inode_cache",
-				sizeof(struct relayfs_inode_info), 0,
-				0, init_once, NULL);
-	if (!relayfs_inode_cachep)
-		return -ENOMEM;
-
-	err = register_filesystem(&relayfs_fs_type);
-	if (err)
-		kmem_cache_destroy(relayfs_inode_cachep);
-
-	return err;
+	return register_filesystem(&relayfs_fs_type);
 }
 
 static void __exit exit_relayfs_fs(void)
 {
+
+
+
+
+
 	unregister_filesystem(&relayfs_fs_type);
-	kmem_cache_destroy(relayfs_inode_cachep);
 }
 
 module_init(init_relayfs_fs)
 module_exit(exit_relayfs_fs)
 
-EXPORT_SYMBOL_GPL(relayfs_file_operations);
+EXPORT_SYMBOL_GPL(relay_file_operations);
 EXPORT_SYMBOL_GPL(relayfs_create_dir);
 EXPORT_SYMBOL_GPL(relayfs_remove_dir);
+EXPORT_SYMBOL_GPL(relayfs_create_file);
+EXPORT_SYMBOL_GPL(relayfs_remove_file);
 
 MODULE_AUTHOR("Tom Zanussi <zanussi@us.ibm.com> and Karim Yaghmour <karim@opersys.com>");
 MODULE_DESCRIPTION("Relay Filesystem");
diff --git a/fs/relayfs/relay.c b/fs/relayfs/relay.c
index 16446a1..abf3cea 100644
--- a/fs/relayfs/relay.c
+++ b/fs/relayfs/relay.c
@@ -80,11 +80,34 @@
 {
 }
 
+/*
+ * create_buf_file_create() default callback.  Creates file to represent buf.
+ */
+static struct dentry *create_buf_file_default_callback(const char *filename,
+						       struct dentry *parent,
+						       int mode,
+						       struct rchan_buf *buf,
+						       int *is_global)
+{
+	return relayfs_create_file(filename, parent, mode,
+				   &relay_file_operations, buf);
+}
+
+/*
+ * remove_buf_file() default callback.  Removes file representing relay buffer.
+ */
+static int remove_buf_file_default_callback(struct dentry *dentry)
+{
+	return relayfs_remove(dentry);
+}
+
 /* relay channel default callbacks */
 static struct rchan_callbacks default_channel_callbacks = {
 	.subbuf_start = subbuf_start_default_callback,
 	.buf_mapped = buf_mapped_default_callback,
 	.buf_unmapped = buf_unmapped_default_callback,
+	.create_buf_file = create_buf_file_default_callback,
+	.remove_buf_file = remove_buf_file_default_callback,
 };
 
 /**
@@ -148,14 +171,16 @@
 void relay_reset(struct rchan *chan)
 {
 	unsigned int i;
+	struct rchan_buf *prev = NULL;
 
 	if (!chan)
 		return;
 
 	for (i = 0; i < NR_CPUS; i++) {
-		if (!chan->buf[i])
-			continue;
+		if (!chan->buf[i] || chan->buf[i] == prev)
+			break;
 		__relay_reset(chan->buf[i], 0);
+		prev = chan->buf[i];
 	}
 }
 
@@ -166,17 +191,27 @@
  */
 static struct rchan_buf *relay_open_buf(struct rchan *chan,
 					const char *filename,
-					struct dentry *parent)
+					struct dentry *parent,
+					int *is_global)
 {
 	struct rchan_buf *buf;
 	struct dentry *dentry;
 
-	/* Create file in fs */
-	dentry = relayfs_create_file(filename, parent, S_IRUSR, chan);
-	if (!dentry)
-		return NULL;
+	if (*is_global)
+		return chan->buf[0];
 
-	buf = RELAYFS_I(dentry->d_inode)->buf;
+ 	buf = relay_create_buf(chan);
+ 	if (!buf)
+ 		return NULL;
+
+	/* Create file in fs */
+ 	dentry = chan->cb->create_buf_file(filename, parent, S_IRUSR,
+ 					   buf, is_global);
+ 	if (!dentry) {
+ 		relay_destroy_buf(buf);
+		return NULL;
+ 	}
+
 	buf->dentry = dentry;
 	__relay_reset(buf, 1);
 
@@ -214,6 +249,10 @@
 		cb->buf_mapped = buf_mapped_default_callback;
 	if (!cb->buf_unmapped)
 		cb->buf_unmapped = buf_unmapped_default_callback;
+	if (!cb->create_buf_file)
+		cb->create_buf_file = create_buf_file_default_callback;
+	if (!cb->remove_buf_file)
+		cb->remove_buf_file = remove_buf_file_default_callback;
 	chan->cb = cb;
 }
 
@@ -241,6 +280,7 @@
 	unsigned int i;
 	struct rchan *chan;
 	char *tmpname;
+	int is_global = 0;
 
 	if (!base_filename)
 		return NULL;
@@ -265,7 +305,8 @@
 
 	for_each_online_cpu(i) {
 		sprintf(tmpname, "%s%d", base_filename, i);
-		chan->buf[i] = relay_open_buf(chan, tmpname, parent);
+		chan->buf[i] = relay_open_buf(chan, tmpname, parent,
+					      &is_global);
 		chan->buf[i]->cpu = i;
 		if (!chan->buf[i])
 			goto free_bufs;
@@ -279,6 +320,8 @@
 		if (!chan->buf[i])
 			break;
 		relay_close_buf(chan->buf[i]);
+		if (is_global)
+			break;
 	}
 	kfree(tmpname);
 
@@ -333,8 +376,7 @@
 	return length;
 
 toobig:
-	printk(KERN_WARNING "relayfs: event too large (%Zd)\n", length);
-	WARN_ON(1);
+	buf->chan->last_toobig = length;
 	return 0;
 }
 
@@ -389,16 +431,23 @@
 void relay_close(struct rchan *chan)
 {
 	unsigned int i;
+	struct rchan_buf *prev = NULL;
 
 	if (!chan)
 		return;
 
 	for (i = 0; i < NR_CPUS; i++) {
-		if (!chan->buf[i])
-			continue;
+		if (!chan->buf[i] || chan->buf[i] == prev)
+			break;
 		relay_close_buf(chan->buf[i]);
+		prev = chan->buf[i];
 	}
 
+	if (chan->last_toobig)
+		printk(KERN_WARNING "relayfs: one or more items not logged "
+		       "[item size (%Zd) > sub-buffer size (%Zd)]\n",
+		       chan->last_toobig, chan->subbuf_size);
+
 	kref_put(&chan->kref, relay_destroy_channel);
 }
 
@@ -411,14 +460,16 @@
 void relay_flush(struct rchan *chan)
 {
 	unsigned int i;
+	struct rchan_buf *prev = NULL;
 
 	if (!chan)
 		return;
 
 	for (i = 0; i < NR_CPUS; i++) {
-		if (!chan->buf[i])
-			continue;
+		if (!chan->buf[i] || chan->buf[i] == prev)
+			break;
 		relay_switch_subbuf(chan->buf[i], 0);
+		prev = chan->buf[i];
 	}
 }
 
diff --git a/fs/relayfs/relay.h b/fs/relayfs/relay.h
index 703503f..0993d3e 100644
--- a/fs/relayfs/relay.h
+++ b/fs/relayfs/relay.h
@@ -1,10 +1,6 @@
 #ifndef _RELAY_H
 #define _RELAY_H
 
-struct dentry *relayfs_create_file(const char *name,
-				   struct dentry *parent,
-				   int mode,
-				   struct rchan *chan);
 extern int relayfs_remove(struct dentry *dentry);
 extern int relay_buf_empty(struct rchan_buf *buf);
 extern void relay_destroy_channel(struct kref *kref);
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index c74f382..0a13859 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -418,7 +418,7 @@
 romfs_readpage(struct file *file, struct page * page)
 {
 	struct inode *inode = page->mapping->host;
-	unsigned long offset, avail, readlen;
+	loff_t offset, avail, readlen;
 	void *buf;
 	int result = -EIO;
 
@@ -429,8 +429,8 @@
 		goto err_out;
 
 	/* 32 bit warning -- but not for us :) */
-	offset = page->index << PAGE_CACHE_SHIFT;
-	if (offset < inode->i_size) {
+	offset = page_offset(page);
+	if (offset < i_size_read(inode)) {
 		avail = inode->i_size-offset;
 		readlen = min_t(unsigned long, avail, PAGE_SIZE);
 		if (romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen) == readlen) {
diff --git a/fs/smbfs/cache.c b/fs/smbfs/cache.c
index f3e6b81..74b86d9 100644
--- a/fs/smbfs/cache.c
+++ b/fs/smbfs/cache.c
@@ -66,7 +66,7 @@
 	spin_lock(&dcache_lock);
 	next = parent->d_subdirs.next;
 	while (next != &parent->d_subdirs) {
-		dentry = list_entry(next, struct dentry, d_child);
+		dentry = list_entry(next, struct dentry, d_u.d_child);
 		dentry->d_fsdata = NULL;
 		smb_age_dentry(server, dentry);
 		next = next->next;
@@ -100,7 +100,7 @@
 	spin_lock(&dcache_lock);
 	next = parent->d_subdirs.next;
 	while (next != &parent->d_subdirs) {
-		dent = list_entry(next, struct dentry, d_child);
+		dent = list_entry(next, struct dentry, d_u.d_child);
 		if ((unsigned long)dent->d_fsdata == fpos) {
 			if (dent->d_inode)
 				dget_locked(dent);
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index b4fcfa8..7042e62 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -209,8 +209,8 @@
 {
 	struct dentry *dentry = file->f_dentry;
 
-	DEBUG1("(%s/%s %d@%ld)\n", DENTRY_PATH(dentry), 
-	       count, (page->index << PAGE_CACHE_SHIFT)+offset);
+	DEBUG1("(%s/%s %d@%lld)\n", DENTRY_PATH(dentry), count,
+		((unsigned long long)page->index << PAGE_CACHE_SHIFT) + offset);
 
 	return smb_writepage_sync(dentry->d_inode, page, offset, count);
 }
@@ -374,8 +374,7 @@
 		/* We must flush any dirty pages now as we won't be able to
 		   write anything after close. mmap can trigger this.
 		   "openers" should perhaps include mmap'ers ... */
-		filemap_fdatawrite(inode->i_mapping);
-		filemap_fdatawait(inode->i_mapping);
+		filemap_write_and_wait(inode->i_mapping);
 		smb_close(inode);
 	}
 	unlock_kernel();
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 10b9944..6ec88bf 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -697,8 +697,7 @@
 			DENTRY_PATH(dentry),
 			(long) inode->i_size, (long) attr->ia_size);
 
-		filemap_fdatawrite(inode->i_mapping);
-		filemap_fdatawait(inode->i_mapping);
+		filemap_write_and_wait(inode->i_mapping);
 
 		error = smb_open(dentry, O_WRONLY);
 		if (error)
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c
index 38ab558..d6baec0 100644
--- a/fs/smbfs/proc.c
+++ b/fs/smbfs/proc.c
@@ -3113,7 +3113,7 @@
 	LSET(data, 32, SMB_TIME_NO_CHANGE);
 	LSET(data, 40, SMB_UID_NO_CHANGE);
 	LSET(data, 48, SMB_GID_NO_CHANGE);
-	LSET(data, 56, smb_filetype_from_mode(attr->ia_mode));
+	DSET(data, 56, smb_filetype_from_mode(attr->ia_mode));
 	LSET(data, 60, major);
 	LSET(data, 68, minor);
 	LSET(data, 76, 0);
diff --git a/fs/super.c b/fs/super.c
index 6689dde..0a30e51 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -665,16 +665,6 @@
 	return (void *)s->s_bdev == data;
 }
 
-static void bdev_uevent(struct block_device *bdev, enum kobject_action action)
-{
-	if (bdev->bd_disk) {
-		if (bdev->bd_part)
-			kobject_uevent(&bdev->bd_part->kobj, action, NULL);
-		else
-			kobject_uevent(&bdev->bd_disk->kobj, action, NULL);
-	}
-}
-
 struct super_block *get_sb_bdev(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data,
 	int (*fill_super)(struct super_block *, void *, int))
@@ -710,17 +700,14 @@
 
 		s->s_flags = flags;
 		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
-		s->s_old_blocksize = block_size(bdev);
-		sb_set_blocksize(s, s->s_old_blocksize);
+		sb_set_blocksize(s, block_size(bdev));
 		error = fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);
 		if (error) {
 			up_write(&s->s_umount);
 			deactivate_super(s);
 			s = ERR_PTR(error);
-		} else {
+		} else
 			s->s_flags |= MS_ACTIVE;
-			bdev_uevent(bdev, KOBJ_MOUNT);
-		}
 	}
 
 	return s;
@@ -736,7 +723,6 @@
 {
 	struct block_device *bdev = sb->s_bdev;
 
-	bdev_uevent(bdev, KOBJ_UMOUNT);
 	generic_shutdown_super(sb);
 	sync_blockdev(bdev);
 	close_bdev_excl(bdev);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 59734ba..d367803 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -112,7 +112,11 @@
 			}
 		}
 		if (error && (error != -EEXIST)) {
-			sysfs_put((*d)->d_fsdata);
+			struct sysfs_dirent *sd = (*d)->d_fsdata;
+			if (sd) {
+ 				list_del_init(&sd->s_sibling);
+				sysfs_put(sd);
+			}
 			d_drop(*d);
 		}
 		dput(*d);
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index 69a085a..cce8b05 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -103,7 +103,7 @@
 			offset = (char *)de - kaddr;
 
 			over = filldir(dirent, name, strnlen(name,SYSV_NAMELEN),
-					(n<<PAGE_CACHE_SHIFT) | offset,
+					((loff_t)n<<PAGE_CACHE_SHIFT) | offset,
 					fs16_to_cpu(SYSV_SB(sb), de->inode),
 					DT_UNKNOWN);
 			if (over) {
@@ -115,7 +115,7 @@
 	}
 
 done:
-	filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
+	filp->f_pos = ((loff_t)n << PAGE_CACHE_SHIFT) | offset;
 	unlock_kernel();
 	return 0;
 }
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index b9ded26..4fae57d 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *	Block allocation handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
@@ -46,7 +41,7 @@
 #define uint(x) xuint(x)
 #define xuint(x) __le ## x
 
-extern inline int find_next_one_bit (void * addr, int size, int offset)
+static inline int find_next_one_bit (void * addr, int size, int offset)
 {
 	uintBPL_t * p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG);
 	int result = offset & ~(BITS_PER_LONG-1);
diff --git a/fs/udf/crc.c b/fs/udf/crc.c
index d95c6e3..1b82a4a 100644
--- a/fs/udf/crc.c
+++ b/fs/udf/crc.c
@@ -14,11 +14,6 @@
  *
  *	AT&T gives permission for the free use of the CRC source code.
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
index 82440b7..f522252 100644
--- a/fs/udf/dir.c
+++ b/fs/udf/dir.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *  Directory handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/directory.c b/fs/udf/directory.c
index 9a61ecc..fe751a2 100644
--- a/fs/udf/directory.c
+++ b/fs/udf/directory.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *	Directory related functions
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 01f520c..8a38828 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *  File handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *  E-mail regarding any portion of the Linux UDF file system should be
- *  directed to the development team mailing list (run by majordomo):
- *    linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
  *  License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/fsync.c b/fs/udf/fsync.c
index 2dde6b8..5887d78 100644
--- a/fs/udf/fsync.c
+++ b/fs/udf/fsync.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *  Fsync handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *  E-mail regarding any portion of the Linux UDF file system should be
- *  directed to the development team mailing list (run by majordomo):
- *      linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
  *  License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index a7e5d40..c9b707b 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *	Inode allocation handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index b83890b..395e582 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *  Inode handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *  E-mail regarding any portion of the Linux UDF file system should be
- *  directed to the development team mailing list (run by majordomo):
- *    linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
  *  License (GPL). Copies of the GPL can be obtained from:
@@ -1962,11 +1957,6 @@
 		printk(KERN_ERR "udf: inode_bmap: block < 0\n");
 		return -1;
 	}
-	if (!inode)
-	{
-		printk(KERN_ERR "udf: inode_bmap: NULL inode\n");
-		return -1;
-	}
 
 	*extoffset = 0;
 	*elen = 0;
diff --git a/fs/udf/lowlevel.c b/fs/udf/lowlevel.c
index 2da5087..0842161 100644
--- a/fs/udf/lowlevel.c
+++ b/fs/udf/lowlevel.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *  Low Level Device Routines for the UDF filesystem
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/misc.c b/fs/udf/misc.c
index fd321f9..cc8ca32 100644
--- a/fs/udf/misc.c
+++ b/fs/udf/misc.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *	Miscellaneous routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index ac191ed..ca732e7 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *      Inode name handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *      E-mail regarding any portion of the Linux UDF file system should be
- *      directed to the development team mailing list (run by majordomo):
- *              linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *      This file is distributed under the terms of the GNU General Public
  *      License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index 4d36f26..dabf2b8 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *      Partition handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *      E-mail regarding any portion of the Linux UDF file system should be
- *      directed to the development team mailing list (run by majordomo):
- *              linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *      This file is distributed under the terms of the GNU General Public
  *      License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 15bd4f2..4a6f49ad 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -14,11 +14,6 @@
  *    http://www.ecma.ch/
  *    http://www.iso.org/
  *
- * CONTACTS
- *  E-mail regarding any portion of the Linux UDF file system should be
- *  directed to the development team mailing list (run by majordomo):
- *	  linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *  This file is distributed under the terms of the GNU General Public
  *  License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 43f3051..674bb40 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *	Symlink handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 7dc8a55..e1b0e8c 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -4,11 +4,6 @@
  * PURPOSE
  *	Truncate handling routines for the OSTA-UDF(tm) filesystem.
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index 5a80efd..706c92e 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -11,11 +11,6 @@
  *	UTF-8 is explained in the IETF RFC XXXX.
  *		ftp://ftp.internic.net/rfc/rfcxxxx.txt
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team's mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index d0915fb..7c10c68 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -491,7 +491,7 @@
 	
 	UFSD(("ino %u, reclen %u, namlen %u, name %s\n",
 		fs32_to_cpu(sb, de->d_ino),
-		fs16to_cpu(sb, de->d_reclen),
+		fs16_to_cpu(sb, de->d_reclen),
 		ufs_get_de_namlen(sb, de), de->d_name))
 
 	while (i < bh->b_size) {
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 54828eb..2ba11a9 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1296,8 +1296,10 @@
 		blk++;
 	}
 out:
-	if (len == towrite)
+	if (len == towrite) {
+		up(&inode->i_sem);
 		return err;
+	}
 	if (inode->i_size < off+len-towrite)
 		i_size_write(inode, off+len-towrite);
 	inode->i_version++;
diff --git a/fs/xattr.c b/fs/xattr.c
index a9db225..bcc2156 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -245,7 +245,7 @@
 		error = d->d_inode->i_op->listxattr(d, klist, size);
 	} else {
 		error = security_inode_listsecurity(d->d_inode, klist, size);
-		if (size && error >= size)
+		if (size && error > size)
 			error = -ERANGE;
 	}
 	if (error > 0) {
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index f89340c..4fa4b1a 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -79,8 +79,7 @@
 	struct inode	*ip = LINVFS_GET_IP(vp);
 
 	if (VN_CACHED(vp)) {
-		filemap_fdatawrite(ip->i_mapping);
-		filemap_fdatawait(ip->i_mapping);
+		filemap_write_and_wait(ip->i_mapping);
 
 		truncate_inode_pages(ip->i_mapping, first);
 	}
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 1aea42d..5328a293 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -78,7 +78,7 @@
 
 STATIC int	xfs_qm_init_quotainos(xfs_mount_t *);
 STATIC int	xfs_qm_init_quotainfo(xfs_mount_t *);
-STATIC int	xfs_qm_shake(int, unsigned int);
+STATIC int	xfs_qm_shake(int, gfp_t);
 
 #ifdef DEBUG
 extern mutex_t	qcheck_lock;
@@ -2197,7 +2197,7 @@
  */
 /* ARGSUSED */
 STATIC int
-xfs_qm_shake(int nr_to_scan, unsigned int gfp_mask)
+xfs_qm_shake(int nr_to_scan, gfp_t gfp_mask)
 {
 	int	ndqused, nfree, n;
 
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 158829c..f40d439 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -30,13 +30,7 @@
  * By comparing each compnent, we don't have to worry about extra
  * endian issues in treating two 32 bit numbers as one 64 bit number
  */
-static
-#if defined(__GNUC__) && (__GNUC__ == 2) && ( (__GNUC_MINOR__ == 95) || (__GNUC_MINOR__ == 96))
-__attribute__((unused))	/* gcc 2.95, 2.96 miscompile this when inlined */
-#else
-__inline__
-#endif
-xfs_lsn_t	_lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
+static inline xfs_lsn_t	_lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
 {
 	if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2))
 		return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999;
diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h
index e9c2790..4ab2ca1 100644
--- a/include/acpi/acglobal.h
+++ b/include/acpi/acglobal.h
@@ -211,7 +211,7 @@
 ACPI_EXTERN u32 acpi_gbl_rsdp_original_location;
 ACPI_EXTERN u32 acpi_gbl_ns_lookup_count;
 ACPI_EXTERN u32 acpi_gbl_ps_find_count;
-ACPI_EXTERN u32 acpi_gbl_owner_id_mask;
+ACPI_EXTERN u64 acpi_gbl_owner_id_mask;
 ACPI_EXTERN u16 acpi_gbl_pm1_enable_register_save;
 ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
 ACPI_EXTERN u8 acpi_gbl_debugger_configuration;
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h
index 6183eab..cb03bbe 100644
--- a/include/asm-alpha/atomic.h
+++ b/include/asm-alpha/atomic.h
@@ -216,4 +216,5 @@
 #define smp_mb__before_atomic_inc()	smp_mb()
 #define smp_mb__after_atomic_inc()	smp_mb()
 
+#include <asm-generic/atomic.h>
 #endif /* _ALPHA_ATOMIC_H */
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
index 578ed3f..302201f 100644
--- a/include/asm-alpha/bitops.h
+++ b/include/asm-alpha/bitops.h
@@ -321,6 +321,7 @@
 #else
 #define fls	generic_fls
 #endif
+#define fls64   generic_fls64
 
 /* Compute powers of two for the given integer.  */
 static inline long floor_log2(unsigned long word)
diff --git a/include/asm-alpha/cache.h b/include/asm-alpha/cache.h
index e69b295..e6d4d16 100644
--- a/include/asm-alpha/cache.h
+++ b/include/asm-alpha/cache.h
@@ -20,6 +20,5 @@
 
 #define L1_CACHE_ALIGN(x)  (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
 #define SMP_CACHE_BYTES    L1_CACHE_BYTES
-#define L1_CACHE_SHIFT_MAX L1_CACHE_SHIFT
 
 #endif
diff --git a/include/asm-alpha/compiler.h b/include/asm-alpha/compiler.h
index 0a4a8b4..00c6f57a 100644
--- a/include/asm-alpha/compiler.h
+++ b/include/asm-alpha/compiler.h
@@ -98,9 +98,7 @@
 #undef inline
 #undef __inline__
 #undef __inline
-#if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3
 #undef __always_inline
 #define __always_inline		inline __attribute__((always_inline))
-#endif
 
 #endif /* __ALPHA_COMPILER_H */
diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h
index 680f7ec..9dc7256 100644
--- a/include/asm-alpha/dma-mapping.h
+++ b/include/asm-alpha/dma-mapping.h
@@ -16,7 +16,7 @@
 #define dma_free_coherent(dev, size, va, addr)		\
 		pci_free_consistent(alpha_gendev_to_pci(dev), size, va, addr)
 #define dma_map_page(dev, page, off, size, dir)		\
-		pci_map_single(alpha_gendev_to_pci(dev), page, off, size, dir)
+		pci_map_page(alpha_gendev_to_pci(dev), page, off, size, dir)
 #define dma_unmap_page(dev, addr, size, dir)		\
 		pci_unmap_page(alpha_gendev_to_pci(dev), addr, size, dir)
 #define dma_map_sg(dev, sg, nents, dir)			\
diff --git a/include/asm-alpha/futex.h b/include/asm-alpha/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-alpha/futex.h
+++ b/include/asm-alpha/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h
index c0593f9..7bb6a36 100644
--- a/include/asm-alpha/hardirq.h
+++ b/include/asm-alpha/hardirq.h
@@ -13,6 +13,8 @@
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
+void ack_bad_irq(unsigned int irq);
+
 #define HARDIRQ_BITS	12
 
 /*
diff --git a/include/asm-alpha/mman.h b/include/asm-alpha/mman.h
index eb9c279..f643953 100644
--- a/include/asm-alpha/mman.h
+++ b/include/asm-alpha/mman.h
@@ -42,6 +42,7 @@
 #define MADV_WILLNEED	3		/* will need these pages */
 #define	MADV_SPACEAVAIL	5		/* ensure resources are available */
 #define MADV_DONTNEED	6		/* don't need these pages */
+#define MADV_REMOVE	7		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-alpha/processor.h b/include/asm-alpha/processor.h
index 059780a..bb1a7a3 100644
--- a/include/asm-alpha/processor.h
+++ b/include/asm-alpha/processor.h
@@ -77,7 +77,6 @@
 #define spin_lock_prefetch(lock)  	do { } while (0)
 #endif
 
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
 extern inline void prefetch(const void *ptr)  
 { 
 	__builtin_prefetch(ptr, 0, 3);
@@ -95,24 +94,4 @@
 }
 #endif
 
-#else
-extern inline void prefetch(const void *ptr)  
-{ 
-	__asm__ ("ldl $31,%0" : : "m"(*(char *)ptr)); 
-}
-
-extern inline void prefetchw(const void *ptr)  
-{
-	__asm__ ("ldq $31,%0" : : "m"(*(char *)ptr)); 
-}
-
-#ifdef CONFIG_SMP
-extern inline void spin_lock_prefetch(const void *ptr)  
-{
-	__asm__ ("ldq $31,%0" : : "m"(*(char *)ptr)); 
-}
-#endif
-
-#endif /* GCC 3.1 */
-
 #endif /* __ASM_ALPHA_PROCESSOR_H */
diff --git a/include/asm-arm/arch-aaec2000/dma.h b/include/asm-arm/arch-aaec2000/dma.h
index 28c890b..e100b1e 100644
--- a/include/asm-arm/arch-aaec2000/dma.h
+++ b/include/asm-arm/arch-aaec2000/dma.h
@@ -7,11 +7,3 @@
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
  */
-
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS         0xffffffff
-#define MAX_DMA_CHANNELS        0
-
-#endif
diff --git a/include/asm-arm/arch-cl7500/dma.h b/include/asm-arm/arch-cl7500/dma.h
index 1d6a882..591ed25 100644
--- a/include/asm-arm/arch-cl7500/dma.h
+++ b/include/asm-arm/arch-cl7500/dma.h
@@ -15,7 +15,6 @@
  * bytes of RAM.
  */
 #define MAX_DMA_ADDRESS		0xd0000000
-#define MAX_DMA_CHANNELS	0
 
 #define DMA_S0			0
 
diff --git a/include/asm-arm/arch-cl7500/entry-macro.S b/include/asm-arm/arch-cl7500/entry-macro.S
index 686f413..c9e5395 100644
--- a/include/asm-arm/arch-cl7500/entry-macro.S
+++ b/include/asm-arm/arch-cl7500/entry-macro.S
@@ -1,3 +1,3 @@
-
+#include <asm/hardware.h>
 #include <asm/hardware/entry-macro-iomd.S>
 
diff --git a/include/asm-arm/arch-clps711x/dma.h b/include/asm-arm/arch-clps711x/dma.h
index 3c4c5c8..6109979 100644
--- a/include/asm-arm/arch-clps711x/dma.h
+++ b/include/asm-arm/arch-clps711x/dma.h
@@ -17,12 +17,3 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS		0xffffffff
-
-#define MAX_DMA_CHANNELS	0
-
-#endif /* _ASM_ARCH_DMA_H */
-
diff --git a/include/asm-arm/arch-clps711x/entry-macro.S b/include/asm-arm/arch-clps711x/entry-macro.S
index b31079a..21f6ee4 100644
--- a/include/asm-arm/arch-clps711x/entry-macro.S
+++ b/include/asm-arm/arch-clps711x/entry-macro.S
@@ -7,6 +7,7 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/hardware.h>
 #include <asm/hardware/clps7111.h>
 
 		.macro	disable_fiq
diff --git a/include/asm-arm/arch-clps711x/system.h b/include/asm-arm/arch-clps711x/system.h
index 2ab981f..11e1491 100644
--- a/include/asm-arm/arch-clps711x/system.h
+++ b/include/asm-arm/arch-clps711x/system.h
@@ -20,7 +20,9 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
+#include <asm/hardware.h>
 #include <asm/hardware/clps7111.h>
+#include <asm/io.h>
 
 static inline void arch_idle(void)
 {
diff --git a/include/asm-arm/arch-ebsa110/dma.h b/include/asm-arm/arch-ebsa110/dma.h
index d491776..c52f9e2a 100644
--- a/include/asm-arm/arch-ebsa110/dma.h
+++ b/include/asm-arm/arch-ebsa110/dma.h
@@ -9,11 +9,3 @@
  *
  *  EBSA110 DMA definitions
  */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS		0xffffffff
-#define MAX_DMA_CHANNELS	0
-
-#endif /* _ASM_ARCH_DMA_H */
-
diff --git a/include/asm-arm/arch-ebsa285/dma.h b/include/asm-arm/arch-ebsa285/dma.h
index c43046e..0259ad4 100644
--- a/include/asm-arm/arch-ebsa285/dma.h
+++ b/include/asm-arm/arch-ebsa285/dma.h
@@ -10,11 +10,6 @@
 #define __ASM_ARCH_DMA_H
 
 /*
- * This is the maximum DMA address that can be DMAd to.
- */
-#define MAX_DMA_ADDRESS		0xffffffff
-
-/*
  * The 21285 has two internal DMA channels; we call these 8 and 9.
  * On CATS hardware we have an additional eight ISA dma channels
  * numbered 0..7.
diff --git a/include/asm-arm/arch-ebsa285/entry-macro.S b/include/asm-arm/arch-ebsa285/entry-macro.S
index db5729f..cf10ac9 100644
--- a/include/asm-arm/arch-ebsa285/entry-macro.S
+++ b/include/asm-arm/arch-ebsa285/entry-macro.S
@@ -7,6 +7,8 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/hardware.h>
+#include <asm/arch/irqs.h>
 #include <asm/hardware/dec21285.h>
 
 		.macro	disable_fiq
diff --git a/include/asm-arm/arch-epxa10db/dma.h b/include/asm-arm/arch-epxa10db/dma.h
index 5d97734..de20ec8 100644
--- a/include/asm-arm/arch-epxa10db/dma.h
+++ b/include/asm-arm/arch-epxa10db/dma.h
@@ -17,12 +17,3 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS		0xffffffff
-
-#define MAX_DMA_CHANNELS	0
-
-#endif /* _ASM_ARCH_DMA_H */
-
diff --git a/include/asm-arm/arch-imx/dma.h b/include/asm-arm/arch-imx/dma.h
index dbdc017..b45fa36 100644
--- a/include/asm-arm/arch-imx/dma.h
+++ b/include/asm-arm/arch-imx/dma.h
@@ -20,10 +20,6 @@
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
-#define MAX_DMA_ADDRESS		0xffffffff
-
-#define MAX_DMA_CHANNELS	0
-
 /*
  * DMA registration
  */
diff --git a/include/asm-arm/arch-imx/entry-macro.S b/include/asm-arm/arch-imx/entry-macro.S
index b40ea7c..3b9ef69 100644
--- a/include/asm-arm/arch-imx/entry-macro.S
+++ b/include/asm-arm/arch-imx/entry-macro.S
@@ -7,6 +7,8 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/hardware.h>
+
 		.macro	disable_fiq
 		.endm
 #define AITC_NIVECSR   0x40
diff --git a/include/asm-arm/arch-integrator/debug-macro.S b/include/asm-arm/arch-integrator/debug-macro.S
index 484a1aa..031d309 100644
--- a/include/asm-arm/arch-integrator/debug-macro.S
+++ b/include/asm-arm/arch-integrator/debug-macro.S
@@ -11,7 +11,7 @@
  *
 */
 
-#include <asm/hardware/amba_serial.h>
+#include <linux/amba/serial.h>
 
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
diff --git a/include/asm-arm/arch-integrator/dma.h b/include/asm-arm/arch-integrator/dma.h
index 7171792..83fd6bb 100644
--- a/include/asm-arm/arch-integrator/dma.h
+++ b/include/asm-arm/arch-integrator/dma.h
@@ -17,12 +17,3 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS		0xffffffff
-
-#define MAX_DMA_CHANNELS	0
-
-#endif /* _ASM_ARCH_DMA_H */
-
diff --git a/include/asm-arm/arch-integrator/entry-macro.S b/include/asm-arm/arch-integrator/entry-macro.S
index 44f7ee6..69838d0 100644
--- a/include/asm-arm/arch-integrator/entry-macro.S
+++ b/include/asm-arm/arch-integrator/entry-macro.S
@@ -7,6 +7,8 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/hardware.h>
+#include <asm/arch/irqs.h>
 
  		.macro	disable_fiq
 		.endm
diff --git a/include/asm-arm/arch-iop3xx/dma.h b/include/asm-arm/arch-iop3xx/dma.h
index 797f9e6..1e808db 100644
--- a/include/asm-arm/arch-iop3xx/dma.h
+++ b/include/asm-arm/arch-iop3xx/dma.h
@@ -7,10 +7,3 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
-#ifndef _IOP3XX_DMA_H_P
-#define _IOP3XX_DMA_H_P
-
-#define MAX_DMA_ADDRESS		0xffffffff
-
-#endif /* _ASM_ARCH_DMA_H_P */
diff --git a/include/asm-arm/arch-iop3xx/entry-macro.S b/include/asm-arm/arch-iop3xx/entry-macro.S
index e2ce7f5..926668c 100644
--- a/include/asm-arm/arch-iop3xx/entry-macro.S
+++ b/include/asm-arm/arch-iop3xx/entry-macro.S
@@ -7,6 +7,7 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/arch/irqs.h>
 
 #if defined(CONFIG_ARCH_IOP321)
 		.macro  disable_fiq
diff --git a/include/asm-arm/arch-ixp2000/dma.h b/include/asm-arm/arch-ixp2000/dma.h
index 0fb3568..548d8dc 100644
--- a/include/asm-arm/arch-ixp2000/dma.h
+++ b/include/asm-arm/arch-ixp2000/dma.h
@@ -7,12 +7,3 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS		0xffffffff
-
-/* No DMA */
-#define MAX_DMA_CHANNELS	0
-
-#endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-ixp2000/enp2611.h b/include/asm-arm/arch-ixp2000/enp2611.h
index 95128d9..42f3c28 100644
--- a/include/asm-arm/arch-ixp2000/enp2611.h
+++ b/include/asm-arm/arch-ixp2000/enp2611.h
@@ -36,5 +36,11 @@
 #define ENP2611_GPIO_SCL		7
 #define ENP2611_GPIO_SDA		6
 
+#define IRQ_ENP2611_THERMAL		IRQ_IXP2000_GPIO4
+#define IRQ_ENP2611_OPTION_BOARD	IRQ_IXP2000_GPIO3
+#define IRQ_ENP2611_CALEB		IRQ_IXP2000_GPIO2
+#define IRQ_ENP2611_PM3386_1		IRQ_IXP2000_GPIO1
+#define IRQ_ENP2611_PM3386_0		IRQ_IXP2000_GPIO0
+
 
 #endif
diff --git a/include/asm-arm/arch-ixp2000/entry-macro.S b/include/asm-arm/arch-ixp2000/entry-macro.S
index e3a4e41..16e1e61 100644
--- a/include/asm-arm/arch-ixp2000/entry-macro.S
+++ b/include/asm-arm/arch-ixp2000/entry-macro.S
@@ -7,6 +7,7 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/arch/irqs.h>
 
 		.macro  disable_fiq
 		.endm
diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h
index 7fbcdf9..c0ff2c6 100644
--- a/include/asm-arm/arch-ixp2000/io.h
+++ b/include/asm-arm/arch-ixp2000/io.h
@@ -131,102 +131,4 @@
 #endif
 
 
-#ifdef CONFIG_ARCH_IXDP2X01
-/*
- * This is an ugly hack but the CS8900 on the 2x01's does not sit in any sort
- * of "I/O space" and is just direct mapped into a 32-bit-only addressable
- * bus. The address space for this bus is such that we can't really easily
- * make it contiguous to the PCI I/O address range, and it also does not
- * need swapping like PCI addresses do (IXDP2x01 is a BE platform).
- * B/C of this we can't use the standard in/out functions and need to
- * runtime check if the incoming address is a PCI address or for
- * the CS89x0.
- */
-#undef inw
-#undef outw
-#undef insw
-#undef outsw
-
-#include <asm/mach-types.h>
-
-static inline void insw(u32 ptr, void *buf, int length)
-{
-	register volatile u32 *port = (volatile u32 *)ptr;
-
-	/*
-	 * Is this cycle meant for the CS8900?
-	 */
-	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
-		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
-		u8 *buf8 = (u8*)buf;
-		register u32 tmp32;
-
-		do {
-			tmp32 = *port;
-			*buf8++ = (u8)tmp32;
-			*buf8++ = (u8)(tmp32 >> 8);
-		} while(--length);
-
-		return;
-	}
-
-	__raw_readsw(alignw(___io(ptr)),buf,length);
-}
-
-static inline void outsw(u32 ptr, void *buf, int length)
-{
-	register volatile u32 *port = (volatile u32 *)ptr;
-
-	/*
-	 * Is this cycle meant for the CS8900?
-	 */
-	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
-		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
-		register u32 tmp32;
-		u8 *buf8 = (u8*)buf;
-		do {
-			tmp32 = *buf8++;
-			tmp32 |= (*buf8++) << 8;
-			*port = tmp32;
-		} while(--length);
-		return;
-	}
-
-	__raw_writesw(alignw(___io(ptr)),buf,length);
-}
-
-
-static inline u16 inw(u32 ptr)
-{
-	register volatile u32 *port = (volatile u32 *)ptr;
-
-	/*
-	 * Is this cycle meant for the CS8900?
-	 */
-	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
-		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
-		return (u16)(*port);  
-	}
-
-	return __raw_readw(alignw(___io(ptr)));
-}
-
-static inline void outw(u16 value, u32 ptr)
-{
-	register volatile u32 *port = (volatile u32 *)ptr;
-
-	if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && 
-		(((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) &&
-		 ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) {
-		*port = value;  
-		return;
-	}
-
-	__raw_writew((value),alignw(___io(ptr)));
-}
-#endif	/* IXDP2x01 */
-
 #endif
diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
index fc5ac6a..8cf70ff 100644
--- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h
+++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h
@@ -156,6 +156,14 @@
 #define IXP2000_IRQ_THD_RAW_STATUS_B_1	IXP2000_INTCTL_REG(0x84)
 #define IXP2000_IRQ_THD_RAW_STATUS_B_2	IXP2000_INTCTL_REG(0x88)
 #define IXP2000_IRQ_THD_RAW_STATUS_B_3	IXP2000_INTCTL_REG(0x8c)
+#define IXP2000_IRQ_THD_STATUS_A_0	IXP2000_INTCTL_REG(0xe0)
+#define IXP2000_IRQ_THD_STATUS_A_1	IXP2000_INTCTL_REG(0xe4)
+#define IXP2000_IRQ_THD_STATUS_A_2	IXP2000_INTCTL_REG(0xe8)
+#define IXP2000_IRQ_THD_STATUS_A_3	IXP2000_INTCTL_REG(0xec)
+#define IXP2000_IRQ_THD_STATUS_B_0	IXP2000_INTCTL_REG(0x100)
+#define IXP2000_IRQ_THD_STATUS_B_1	IXP2000_INTCTL_REG(0x104)
+#define IXP2000_IRQ_THD_STATUS_B_2	IXP2000_INTCTL_REG(0x108)
+#define IXP2000_IRQ_THD_STATUS_B_3	IXP2000_INTCTL_REG(0x10c)
 #define IXP2000_IRQ_THD_ENABLE_SET_A_0	IXP2000_INTCTL_REG(0x160)
 #define IXP2000_IRQ_THD_ENABLE_SET_A_1	IXP2000_INTCTL_REG(0x164)
 #define IXP2000_IRQ_THD_ENABLE_SET_A_2	IXP2000_INTCTL_REG(0x168)
diff --git a/include/asm-arm/arch-ixp4xx/coyote.h b/include/asm-arm/arch-ixp4xx/coyote.h
index dd0c2d2..7ac9ba2c 100644
--- a/include/asm-arm/arch-ixp4xx/coyote.h
+++ b/include/asm-arm/arch-ixp4xx/coyote.h
@@ -16,9 +16,6 @@
 #error "Do not include this directly, instead #include <asm/hardware.h>"
 #endif
 
-#define	COYOTE_FLASH_BASE	IXP4XX_EXP_BUS_CS0_BASE_PHYS
-#define	COYOTE_FLASH_SIZE	IXP4XX_EXP_BUS_CSX_REGION_SIZE * 2
-
 /* PCI controller GPIO to IRQ pin mappings */
 #define	COYOTE_PCI_SLOT0_PIN	6
 #define	COYOTE_PCI_SLOT1_PIN	11
@@ -26,7 +23,7 @@
 #define	COYOTE_PCI_SLOT0_DEVID	14
 #define	COYOTE_PCI_SLOT1_DEVID	15
 
-#define	COYOTE_IDE_BASE_PHYS	IXP4XX_EXP_BUS_CS3_BASE_PHYS
+#define	COYOTE_IDE_BASE_PHYS	IXP4XX_EXP_BUS_BASE(3)
 #define	COYOTE_IDE_BASE_VIRT	0xFFFE1000
 #define	COYOTE_IDE_REGION_SIZE	0x1000
 
diff --git a/include/asm-arm/arch-ixp4xx/dma.h b/include/asm-arm/arch-ixp4xx/dma.h
index 312065d..b1a071e 100644
--- a/include/asm-arm/arch-ixp4xx/dma.h
+++ b/include/asm-arm/arch-ixp4xx/dma.h
@@ -20,7 +20,4 @@
 
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_64M)
 
-/* No DMA */
-#define MAX_DMA_CHANNELS	0
-
 #endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-ixp4xx/entry-macro.S b/include/asm-arm/arch-ixp4xx/entry-macro.S
index 323b0bc..27e1241 100644
--- a/include/asm-arm/arch-ixp4xx/entry-macro.S
+++ b/include/asm-arm/arch-ixp4xx/entry-macro.S
@@ -7,6 +7,7 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/hardware.h>
 
 		.macro	disable_fiq
 		.endm
diff --git a/include/asm-arm/arch-ixp4xx/gtwx5715.h b/include/asm-arm/arch-ixp4xx/gtwx5715.h
index fc460af7..c3069d6 100644
--- a/include/asm-arm/arch-ixp4xx/gtwx5715.h
+++ b/include/asm-arm/arch-ixp4xx/gtwx5715.h
@@ -57,10 +57,6 @@
 #define GTWX5715_GPIO13_IRQ		IRQ_IXP4XX_SW_INT1
 #define GTWX5715_GPIO14_IRQ		IRQ_IXP4XX_SW_INT2
 
-
-#define	GTWX5715_FLASH_BASE	IXP4XX_EXP_BUS_CS0_BASE_PHYS
-#define	GTWX5715_FLASH_SIZE	(0x00800000)
-
 /* PCI controller GPIO to IRQ pin mappings
 
 			INTA	INTB
diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h
index cfb413c..6acb69c 100644
--- a/include/asm-arm/arch-ixp4xx/hardware.h
+++ b/include/asm-arm/arch-ixp4xx/hardware.h
@@ -45,5 +45,6 @@
 #include "coyote.h"
 #include "prpmc1100.h"
 #include "nslu2.h"
+#include "nas100d.h"
 
 #endif  /* _ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h
index 2cf4930..f24b763 100644
--- a/include/asm-arm/arch-ixp4xx/irqs.h
+++ b/include/asm-arm/arch-ixp4xx/irqs.h
@@ -100,4 +100,13 @@
 #define        IRQ_NSLU2_PCI_INTB      IRQ_IXP4XX_GPIO10
 #define        IRQ_NSLU2_PCI_INTC      IRQ_IXP4XX_GPIO9
 
+/*
+ * NAS100D board IRQs
+ */
+#define        IRQ_NAS100D_PCI_INTA    IRQ_IXP4XX_GPIO11
+#define        IRQ_NAS100D_PCI_INTB    IRQ_IXP4XX_GPIO10
+#define        IRQ_NAS100D_PCI_INTC    IRQ_IXP4XX_GPIO9
+#define        IRQ_NAS100D_PCI_INTD    IRQ_IXP4XX_GPIO8
+#define        IRQ_NAS100D_PCI_INTE    IRQ_IXP4XX_GPIO7
+
 #endif
diff --git a/include/asm-arm/arch-ixp4xx/ixdp425.h b/include/asm-arm/arch-ixp4xx/ixdp425.h
index 7d21bf9..3d3820d 100644
--- a/include/asm-arm/arch-ixp4xx/ixdp425.h
+++ b/include/asm-arm/arch-ixp4xx/ixdp425.h
@@ -16,9 +16,6 @@
 #error "Do not include this directly, instead #include <asm/hardware.h>"
 #endif
 
-#define	IXDP425_FLASH_BASE	IXP4XX_EXP_BUS_CS0_BASE_PHYS
-#define	IXDP425_FLASH_SIZE	IXP4XX_EXP_BUS_CSX_REGION_SIZE
-
 #define	IXDP425_SDA_PIN		7
 #define	IXDP425_SCL_PIN		6
 
diff --git a/include/asm-arm/arch-ixp4xx/memory.h b/include/asm-arm/arch-ixp4xx/memory.h
index e024d0a..ee211d2 100644
--- a/include/asm-arm/arch-ixp4xx/memory.h
+++ b/include/asm-arm/arch-ixp4xx/memory.h
@@ -16,31 +16,10 @@
 
 #ifndef __ASSEMBLY__
 
-/*
- * Only first 64MB of memory can be accessed via PCI.
- * We use GFP_DMA to allocate safe buffers to do map/unmap.
- * This is really ugly and we need a better way of specifying
- * DMA-capable regions of memory.
- */
-static inline void __arch_adjust_zones(int node, unsigned long *zone_size, 
-	unsigned long *zhole_size) 
-{
-	unsigned int sz = SZ_64M >> PAGE_SHIFT;
-
-	/*
-	 * Only adjust if > 64M on current system
-	 */
-	if (node || (zone_size[0] <= sz))
-		return;
-
-	zone_size[1] = zone_size[0] - sz;
-	zone_size[0] = sz;
-	zhole_size[1] = zhole_size[0];
-	zhole_size[0] = 0;
-}
+void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes);
 
 #define arch_adjust_zones(node, size, holes) \
-	__arch_adjust_zones(node, size, holes)
+	ixp4xx_adjust_zones(node, size, holes)
 
 #define ISA_DMA_THRESHOLD (SZ_64M - 1)
 
diff --git a/include/asm-arm/arch-ixp4xx/nas100d.h b/include/asm-arm/arch-ixp4xx/nas100d.h
new file mode 100644
index 0000000..51ac018
--- /dev/null
+++ b/include/asm-arm/arch-ixp4xx/nas100d.h
@@ -0,0 +1,72 @@
+/*
+ * include/asm-arm/arch-ixp4xx/nas100d.h
+ *
+ * NAS100D platform specific definitions
+ *
+ * Copyright (c) 2005 Tower Technologies
+ *
+ * Author: Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * based on ixdp425.h:
+ *	Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * This file is licensed under  the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H__
+#error "Do not include this directly, instead #include <asm/hardware.h>"
+#endif
+
+#define NAS100D_SDA_PIN		6
+#define NAS100D_SCL_PIN		5
+
+/*
+ * NAS100D PCI IRQs
+ */
+#define NAS100D_PCI_MAX_DEV	3
+#define NAS100D_PCI_IRQ_LINES	3
+
+
+/* PCI controller GPIO to IRQ pin mappings */
+#define NAS100D_PCI_INTA_PIN	11
+#define NAS100D_PCI_INTB_PIN	10
+#define NAS100D_PCI_INTC_PIN	9
+#define NAS100D_PCI_INTD_PIN	8
+#define NAS100D_PCI_INTE_PIN	7
+
+/* GPIO */
+
+#define NAS100D_GPIO0           0
+#define NAS100D_GPIO1           1
+#define NAS100D_GPIO2           2
+#define NAS100D_GPIO3           3
+#define NAS100D_GPIO4           4
+#define NAS100D_GPIO5           5
+#define NAS100D_GPIO6           6
+#define NAS100D_GPIO7           7
+#define NAS100D_GPIO8           8
+#define NAS100D_GPIO9           9
+#define NAS100D_GPIO10          10
+#define NAS100D_GPIO11          11
+#define NAS100D_GPIO12          12
+#define NAS100D_GPIO13          13
+#define NAS100D_GPIO14          14
+#define NAS100D_GPIO15          15
+
+
+/* Buttons */
+
+#define NAS100D_PB_GPIO         NAS100D_GPIO14
+#define NAS100D_RB_GPIO         NAS100D_GPIO4
+#define NAS100D_PO_GPIO         NAS100D_GPIO12   /* power off */
+
+#define NAS100D_PB_IRQ          IRQ_IXP4XX_GPIO14
+#define NAS100D_RB_IRQ          IRQ_IXP4XX_GPIO4
+
+/*
+#define NAS100D_PB_BM           (1L << NAS100D_PB_GPIO)
+#define NAS100D_PO_BM           (1L << NAS100D_PO_GPIO)
+#define NAS100D_RB_BM           (1L << NAS100D_RB_GPIO)
+*/
diff --git a/include/asm-arm/arch-ixp4xx/nslu2.h b/include/asm-arm/arch-ixp4xx/nslu2.h
index b8b347a..4281838 100644
--- a/include/asm-arm/arch-ixp4xx/nslu2.h
+++ b/include/asm-arm/arch-ixp4xx/nslu2.h
@@ -18,9 +18,6 @@
 #error "Do not include this directly, instead #include <asm/hardware.h>"
 #endif
 
-#define NSLU2_FLASH_BASE	IXP4XX_EXP_BUS_CS0_BASE_PHYS
-#define NSLU2_FLASH_SIZE	IXP4XX_EXP_BUS_CSX_REGION_SIZE
-
 #define NSLU2_SDA_PIN		7
 #define NSLU2_SCL_PIN		6
 
diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h
index f14ed63..daf9790 100644
--- a/include/asm-arm/arch-ixp4xx/platform.h
+++ b/include/asm-arm/arch-ixp4xx/platform.h
@@ -26,16 +26,17 @@
  */
 #define IXP4XX_EXP_BUS_BASE_PHYS	(0x50000000)
 
-#define	IXP4XX_EXP_BUS_CSX_REGION_SIZE	(0x01000000)
+/*
+ * The expansion bus on the IXP4xx can be configured for either 16 or
+ * 32MB windows and the CS offset for each region changes based on the
+ * current configuration. This means that we cannot simply hardcode
+ * each offset. ixp4xx_sys_init() looks at the expansion bus configuration
+ * as setup by the bootloader to determine our window size.
+ */
+extern unsigned long ixp4xx_exp_bus_size;
 
-#define IXP4XX_EXP_BUS_CS0_BASE_PHYS	(IXP4XX_EXP_BUS_BASE_PHYS + 0x00000000)
-#define IXP4XX_EXP_BUS_CS1_BASE_PHYS	(IXP4XX_EXP_BUS_BASE_PHYS + 0x01000000)
-#define IXP4XX_EXP_BUS_CS2_BASE_PHYS	(IXP4XX_EXP_BUS_BASE_PHYS + 0x02000000)
-#define IXP4XX_EXP_BUS_CS3_BASE_PHYS	(IXP4XX_EXP_BUS_BASE_PHYS + 0x03000000)
-#define IXP4XX_EXP_BUS_CS4_BASE_PHYS	(IXP4XX_EXP_BUS_BASE_PHYS + 0x04000000)
-#define IXP4XX_EXP_BUS_CS5_BASE_PHYS	(IXP4XX_EXP_BUS_BASE_PHYS + 0x05000000)
-#define IXP4XX_EXP_BUS_CS6_BASE_PHYS	(IXP4XX_EXP_BUS_BASE_PHYS + 0x06000000)
-#define IXP4XX_EXP_BUS_CS7_BASE_PHYS	(IXP4XX_EXP_BUS_BASE_PHYS + 0x07000000)
+#define	IXP4XX_EXP_BUS_BASE(region)\
+		(IXP4XX_EXP_BUS_BASE_PHYS + ((region) * ixp4xx_exp_bus_size))
 
 #define IXP4XX_FLASH_WRITABLE	(0x2)
 #define IXP4XX_FLASH_DEFAULT	(0xbcd23c40)
@@ -112,10 +113,5 @@
 	    *IXP4XX_GPIO_GPOUTR &= ~(1 << line);
 }
 
-static inline void gpio_line_isr_clear(u8 line)
-{
-	*IXP4XX_GPIO_GPISR = (1 << line);
-}
-
 #endif // __ASSEMBLY__
 
diff --git a/include/asm-arm/arch-l7200/dma.h b/include/asm-arm/arch-l7200/dma.h
index 6595b38..4c7eca6 100644
--- a/include/asm-arm/arch-l7200/dma.h
+++ b/include/asm-arm/arch-l7200/dma.h
@@ -17,7 +17,6 @@
  * bytes of RAM.
  */
 #define MAX_DMA_ADDRESS         0xd0000000
-#define MAX_DMA_CHANNELS        0
 
 #define DMA_S0                  0
 
diff --git a/include/asm-arm/arch-l7200/system.h b/include/asm-arm/arch-l7200/system.h
index cb4ff29..18825cf 100644
--- a/include/asm-arm/arch-l7200/system.h
+++ b/include/asm-arm/arch-l7200/system.h
@@ -12,6 +12,8 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
+#include <asm/hardware.h>
+
 static inline void arch_idle(void)
 {
 	*(unsigned long *)(IO_BASE + 0x50004) = 1;	/* idle mode */
diff --git a/include/asm-arm/arch-lh7a40x/dma.h b/include/asm-arm/arch-lh7a40x/dma.h
index 5797f01..15492e3 100644
--- a/include/asm-arm/arch-lh7a40x/dma.h
+++ b/include/asm-arm/arch-lh7a40x/dma.h
@@ -7,11 +7,3 @@
  *  version 2 as published by the Free Software Foundation.
  *
  */
-
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS		0xffffffff
-#define MAX_DMA_CHANNELS	0 /* All DMA is internal to CPU */
-
-#endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-lh7a40x/entry-macro.S b/include/asm-arm/arch-lh7a40x/entry-macro.S
index 865f396..a2f67c0 100644
--- a/include/asm-arm/arch-lh7a40x/entry-macro.S
+++ b/include/asm-arm/arch-lh7a40x/entry-macro.S
@@ -7,6 +7,8 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/hardware.h>
+#include <asm/arch/irqs.h>
 
 # if defined (CONFIG_ARCH_LH7A400) && defined (CONFIG_ARCH_LH7A404)
 #  error "LH7A400 and LH7A404 are mutually exclusive"
diff --git a/include/asm-arm/arch-omap/dma.h b/include/asm-arm/arch-omap/dma.h
index ccbcb58..d4e73ef 100644
--- a/include/asm-arm/arch-omap/dma.h
+++ b/include/asm-arm/arch-omap/dma.h
@@ -21,9 +21,6 @@
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
-#define MAX_DMA_ADDRESS			0xffffffff
-#define MAX_DMA_CHANNELS		0
-
 /* Hardware registers for omap1 */
 #define OMAP_DMA_BASE			(0xfffed800)
 #define OMAP_DMA_GCR			(OMAP_DMA_BASE + 0x400)
diff --git a/include/asm-arm/arch-omap/entry-macro.S b/include/asm-arm/arch-omap/entry-macro.S
index f8814a8..0ffb118 100644
--- a/include/asm-arm/arch-omap/entry-macro.S
+++ b/include/asm-arm/arch-omap/entry-macro.S
@@ -7,6 +7,8 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/hardware.h>
+#include <asm/arch/irqs.h>
 
 #if defined(CONFIG_ARCH_OMAP1)
 
diff --git a/include/asm-arm/arch-omap/system.h b/include/asm-arm/arch-omap/system.h
index 9af415d..6724a81 100644
--- a/include/asm-arm/arch-omap/system.h
+++ b/include/asm-arm/arch-omap/system.h
@@ -5,8 +5,9 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 #include <linux/config.h>
+#include <linux/clk.h>
+
 #include <asm/mach-types.h>
-#include <asm/hardware/clock.h>
 #include <asm/hardware.h>
 #include <asm/arch/prcm.h>
 
diff --git a/include/asm-arm/arch-pxa/dma.h b/include/asm-arm/arch-pxa/dma.h
index 56db3d4..3e88a2a 100644
--- a/include/asm-arm/arch-pxa/dma.h
+++ b/include/asm-arm/arch-pxa/dma.h
@@ -12,11 +12,6 @@
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
-#define MAX_DMA_ADDRESS		0xffffffff
-
-/* No DMA as the rest of the world see it */
-#define MAX_DMA_CHANNELS	0
-
 /*
  * Descriptor structure for PXA's DMA engine
  * Note: this structure must always be aligned to a 16-byte boundary.
diff --git a/include/asm-arm/arch-pxa/entry-macro.S b/include/asm-arm/arch-pxa/entry-macro.S
index 2abfc8b..4985e33 100644
--- a/include/asm-arm/arch-pxa/entry-macro.S
+++ b/include/asm-arm/arch-pxa/entry-macro.S
@@ -7,6 +7,8 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#include <asm/hardware.h>
+#include <asm/arch/irqs.h>
 
 		.macro	disable_fiq
 		.endm
diff --git a/include/asm-arm/arch-pxa/irq.h b/include/asm-arm/arch-pxa/irq.h
index d770e4b..48c60f5 100644
--- a/include/asm-arm/arch-pxa/irq.h
+++ b/include/asm-arm/arch-pxa/irq.h
@@ -12,8 +12,3 @@
 
 #define fixup_irq(x)	(x)
 
-/*
- * This prototype is required for cascading of multiplexed interrupts.
- * Since it doesn't exist elsewhere, we'll put it here for now.
- */
-extern void do_IRQ(int irq, struct pt_regs *regs);
diff --git a/include/asm-arm/arch-pxa/ohci.h b/include/asm-arm/arch-pxa/ohci.h
new file mode 100644
index 0000000..7da8956
--- /dev/null
+++ b/include/asm-arm/arch-pxa/ohci.h
@@ -0,0 +1,18 @@
+#ifndef ASMARM_ARCH_OHCI_H
+#define ASMARM_ARCH_OHCI_H
+
+struct device;
+
+struct pxaohci_platform_data {
+	int (*init)(struct device *);
+	void (*exit)(struct device *);
+
+	int port_mode;
+#define PMM_NPS_MODE           1
+#define PMM_GLOBAL_MODE        2
+#define PMM_PERPORT_MODE       3
+};
+
+extern void pxa_set_ohci_info(struct pxaohci_platform_data *info);
+
+#endif
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index a75a247..dae138b 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -2042,6 +2042,18 @@
 
 #ifdef CONFIG_PXA27x
 
+#define ARB_CNTRL	__REG(0x48000048)  /* Arbiter Control Register */
+
+#define ARB_DMA_SLV_PARK	(1<<31)	   /* Be parked with DMA slave when idle */
+#define ARB_CI_PARK		(1<<30)	   /* Be parked with Camera Interface when idle */
+#define ARB_EX_MEM_PARK 	(1<<29)	   /* Be parked with external MEMC when idle */
+#define ARB_INT_MEM_PARK	(1<<28)	   /* Be parked with internal MEMC when idle */
+#define ARB_USB_PARK		(1<<27)	   /* Be parked with USB when idle */
+#define ARB_LCD_PARK		(1<<26)	   /* Be parked with LCD when idle */
+#define ARB_DMA_PARK		(1<<25)	   /* Be parked with DMA when idle */
+#define ARB_CORE_PARK		(1<<24)	   /* Be parked with core when idle */
+#define ARB_LOCK_FLAG		(1<<23)	   /* Only Locking masters gain access to the bus */
+
 /*
  * Keypad
  */
diff --git a/include/asm-arm/arch-realview/debug-macro.S b/include/asm-arm/arch-realview/debug-macro.S
index ed28bd0..017ad99 100644
--- a/include/asm-arm/arch-realview/debug-macro.S
+++ b/include/asm-arm/arch-realview/debug-macro.S
@@ -11,7 +11,7 @@
  *
 */
 
-#include <asm/hardware/amba_serial.h>
+#include <linux/amba/serial.h>
 
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
diff --git a/include/asm-arm/arch-realview/dma.h b/include/asm-arm/arch-realview/dma.h
index 744491a..8342e3f 100644
--- a/include/asm-arm/arch-realview/dma.h
+++ b/include/asm-arm/arch-realview/dma.h
@@ -18,10 +18,3 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS		0xffffffff
-#define MAX_DMA_CHANNELS	0
-
-#endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-realview/entry-macro.S b/include/asm-arm/arch-realview/entry-macro.S
index 6288fad..1a6eec8 100644
--- a/include/asm-arm/arch-realview/entry-macro.S
+++ b/include/asm-arm/arch-realview/entry-macro.S
@@ -7,7 +7,7 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-
+#include <asm/hardware.h>
 #include <asm/hardware/gic.h>
 
 		.macro	disable_fiq
diff --git a/include/asm-arm/arch-rpc/entry-macro.S b/include/asm-arm/arch-rpc/entry-macro.S
index 686f413..c9e5395 100644
--- a/include/asm-arm/arch-rpc/entry-macro.S
+++ b/include/asm-arm/arch-rpc/entry-macro.S
@@ -1,3 +1,3 @@
-
+#include <asm/hardware.h>
 #include <asm/hardware/entry-macro-iomd.S>
 
diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h
index e830a40..b011e14 100644
--- a/include/asm-arm/arch-s3c2410/dma.h
+++ b/include/asm-arm/arch-s3c2410/dma.h
@@ -31,14 +31,6 @@
 #define MAX_DMA_TRANSFER_SIZE   0x100000 /* Data Unit is half word  */
 
 
-/* according to the samsung port, we cannot use the regular
- * dma channels... we must therefore provide our own interface
- * for DMA, and allow our drivers to use that.
- */
-
-#define MAX_DMA_CHANNELS	0
-
-
 /* we have 4 dma channels */
 #define S3C2410_DMA_CHANNELS        (4)
 
diff --git a/include/asm-arm/arch-s3c2410/entry-macro.S b/include/asm-arm/arch-s3c2410/entry-macro.S
index b7d4d7f..cc06b1b 100644
--- a/include/asm-arm/arch-s3c2410/entry-macro.S
+++ b/include/asm-arm/arch-s3c2410/entry-macro.S
@@ -10,6 +10,8 @@
  * Modifications:
  *     10-Mar-2005 LCVR  Changed S3C2410_VA to S3C24XX_VA
  */
+#include <asm/hardware.h>
+#include <asm/arch/irqs.h>
 
 
 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index cb33d57..7f1be48 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -21,6 +21,7 @@
  *    10-Mar-2005    LCVR    Changed S3C2410_VA to S3C24XX_VA
  *    28-Mar-2005    LCVR    Fixed definition of GPB10
  *    26-Oct-2005    BJD     Added generic configuration types
+ *    27-Nov-2005    LCVR    Added definitions to S3C2400 registers
 */
 
 
@@ -54,12 +55,16 @@
 
 #define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO)
 
-/* port A - 22bits, zero in bit X makes pin X output
+/* port A - S3C2410: 22bits, zero in bit X makes pin X output
+ *          S3C2400: 18bits, zero in bit X makes pin X output
  * 1 makes port special function, this is default
 */
 #define S3C2410_GPACON	   S3C2410_GPIOREG(0x00)
 #define S3C2410_GPADAT	   S3C2410_GPIOREG(0x04)
 
+#define S3C2400_GPACON	   S3C2410_GPIOREG(0x00)
+#define S3C2400_GPADAT	   S3C2410_GPIOREG(0x04)
+
 #define S3C2410_GPA0         S3C2410_GPIONO(S3C2410_GPIO_BANKA, 0)
 #define S3C2410_GPA0_OUT     (0<<0)
 #define S3C2410_GPA0_ADDR0   (1<<0)
@@ -103,34 +108,42 @@
 #define S3C2410_GPA10        S3C2410_GPIONO(S3C2410_GPIO_BANKA, 10)
 #define S3C2410_GPA10_OUT    (0<<10)
 #define S3C2410_GPA10_ADDR25 (1<<10)
+#define S3C2400_GPA10_SCKE   (1<<10)
 
 #define S3C2410_GPA11        S3C2410_GPIONO(S3C2410_GPIO_BANKA, 11)
 #define S3C2410_GPA11_OUT    (0<<11)
 #define S3C2410_GPA11_ADDR26 (1<<11)
+#define S3C2400_GPA11_nCAS0  (1<<11)
 
 #define S3C2410_GPA12        S3C2410_GPIONO(S3C2410_GPIO_BANKA, 12)
 #define S3C2410_GPA12_OUT    (0<<12)
 #define S3C2410_GPA12_nGCS1  (1<<12)
+#define S3C2400_GPA12_nCAS1  (1<<12)
 
 #define S3C2410_GPA13        S3C2410_GPIONO(S3C2410_GPIO_BANKA, 13)
 #define S3C2410_GPA13_OUT    (0<<13)
 #define S3C2410_GPA13_nGCS2  (1<<13)
+#define S3C2400_GPA13_nGCS1  (1<<13)
 
 #define S3C2410_GPA14        S3C2410_GPIONO(S3C2410_GPIO_BANKA, 14)
 #define S3C2410_GPA14_OUT    (0<<14)
 #define S3C2410_GPA14_nGCS3  (1<<14)
+#define S3C2400_GPA14_nGCS2  (1<<14)
 
 #define S3C2410_GPA15        S3C2410_GPIONO(S3C2410_GPIO_BANKA, 15)
 #define S3C2410_GPA15_OUT    (0<<15)
 #define S3C2410_GPA15_nGCS4  (1<<15)
+#define S3C2400_GPA15_nGCS3  (1<<15)
 
 #define S3C2410_GPA16        S3C2410_GPIONO(S3C2410_GPIO_BANKA, 16)
 #define S3C2410_GPA16_OUT    (0<<16)
 #define S3C2410_GPA16_nGCS5  (1<<16)
+#define S3C2400_GPA16_nGCS4  (1<<16)
 
 #define S3C2410_GPA17        S3C2410_GPIONO(S3C2410_GPIO_BANKA, 17)
 #define S3C2410_GPA17_OUT    (0<<17)
 #define S3C2410_GPA17_CLE    (1<<17)
+#define S3C2400_GPA17_nGCS5  (1<<17)
 
 #define S3C2410_GPA18        S3C2410_GPIONO(S3C2410_GPIO_BANKA, 18)
 #define S3C2410_GPA18_OUT    (0<<18)
@@ -152,10 +165,16 @@
 #define S3C2410_GPA22_OUT    (0<<22)
 #define S3C2410_GPA22_nFCE   (1<<22)
 
-/* 0x08 and 0x0c are reserved */
+/* 0x08 and 0x0c are reserved on S3C2410 */
 
-/* GPB is 10 IO pins, each configured by 2 bits each in GPBCON.
+/* S3C2410:
+ * GPB is 10 IO pins, each configured by 2 bits each in GPBCON.
  *   00 = input, 01 = output, 10=special function, 11=reserved
+
+ * S3C2400:
+ * GPB is 16 IO pins, each configured by 2 bits each in GPBCON.
+ *   00 = input, 01 = output, 10=data, 11=special function
+
  * bit 0,1 = pin 0, 2,3= pin 1...
  *
  * CPBUP = pull up resistor control, 1=disabled, 0=enabled
@@ -165,63 +184,113 @@
 #define S3C2410_GPBDAT	   S3C2410_GPIOREG(0x14)
 #define S3C2410_GPBUP	   S3C2410_GPIOREG(0x18)
 
+#define S3C2400_GPBCON	   S3C2410_GPIOREG(0x08)
+#define S3C2400_GPBDAT	   S3C2410_GPIOREG(0x0C)
+#define S3C2400_GPBUP	   S3C2410_GPIOREG(0x10)
+
 /* no i/o pin in port b can have value 3! */
 
 #define S3C2410_GPB0         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 0)
 #define S3C2410_GPB0_INP     (0x00 << 0)
 #define S3C2410_GPB0_OUTP    (0x01 << 0)
 #define S3C2410_GPB0_TOUT0   (0x02 << 0)
+#define S3C2400_GPB0_DATA16  (0x02 << 0)
 
 #define S3C2410_GPB1         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 1)
 #define S3C2410_GPB1_INP     (0x00 << 2)
 #define S3C2410_GPB1_OUTP    (0x01 << 2)
 #define S3C2410_GPB1_TOUT1   (0x02 << 2)
+#define S3C2400_GPB1_DATA17  (0x02 << 2)
 
 #define S3C2410_GPB2         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 2)
 #define S3C2410_GPB2_INP     (0x00 << 4)
 #define S3C2410_GPB2_OUTP    (0x01 << 4)
 #define S3C2410_GPB2_TOUT2   (0x02 << 4)
+#define S3C2400_GPB2_DATA18  (0x02 << 4)
+#define S3C2400_GPB2_TCLK1   (0x03 << 4)
 
 #define S3C2410_GPB3         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 3)
 #define S3C2410_GPB3_INP     (0x00 << 6)
 #define S3C2410_GPB3_OUTP    (0x01 << 6)
 #define S3C2410_GPB3_TOUT3   (0x02 << 6)
+#define S3C2400_GPB3_DATA19  (0x02 << 6)
+#define S3C2400_GPB3_TXD1    (0x03 << 6)
 
 #define S3C2410_GPB4         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 4)
 #define S3C2410_GPB4_INP     (0x00 << 8)
 #define S3C2410_GPB4_OUTP    (0x01 << 8)
 #define S3C2410_GPB4_TCLK0   (0x02 << 8)
+#define S3C2400_GPB4_DATA20  (0x02 << 8)
 #define S3C2410_GPB4_MASK    (0x03 << 8)
+#define S3C2400_GPB4_RXD1    (0x03 << 8)
+#define S3C2400_GPB4_MASK    (0x03 << 8)
 
 #define S3C2410_GPB5         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 5)
 #define S3C2410_GPB5_INP     (0x00 << 10)
 #define S3C2410_GPB5_OUTP    (0x01 << 10)
 #define S3C2410_GPB5_nXBACK  (0x02 << 10)
+#define S3C2400_GPB5_DATA21  (0x02 << 10)
+#define S3C2400_GPB5_nCTS1   (0x03 << 10)
 
 #define S3C2410_GPB6         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 6)
 #define S3C2410_GPB6_INP     (0x00 << 12)
 #define S3C2410_GPB6_OUTP    (0x01 << 12)
 #define S3C2410_GPB6_nXBREQ  (0x02 << 12)
+#define S3C2400_GPB6_DATA22  (0x02 << 12)
+#define S3C2400_GPB6_nRTS1   (0x03 << 12)
 
 #define S3C2410_GPB7         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 7)
 #define S3C2410_GPB7_INP     (0x00 << 14)
 #define S3C2410_GPB7_OUTP    (0x01 << 14)
 #define S3C2410_GPB7_nXDACK1 (0x02 << 14)
+#define S3C2400_GPB7_DATA23  (0x02 << 14)
 
 #define S3C2410_GPB8         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 8)
 #define S3C2410_GPB8_INP     (0x00 << 16)
 #define S3C2410_GPB8_OUTP    (0x01 << 16)
 #define S3C2410_GPB8_nXDREQ1 (0x02 << 16)
+#define S3C2400_GPB8_DATA24  (0x02 << 16)
 
 #define S3C2410_GPB9         S3C2410_GPIONO(S3C2410_GPIO_BANKB, 9)
 #define S3C2410_GPB9_INP     (0x00 << 18)
 #define S3C2410_GPB9_OUTP    (0x01 << 18)
 #define S3C2410_GPB9_nXDACK0 (0x02 << 18)
+#define S3C2400_GPB9_DATA25  (0x02 << 18)
+#define S3C2400_GPB9_I2SSDI  (0x03 << 18)
 
 #define S3C2410_GPB10        S3C2410_GPIONO(S3C2410_GPIO_BANKB, 10)
 #define S3C2410_GPB10_INP    (0x00 << 20)
 #define S3C2410_GPB10_OUTP   (0x01 << 20)
 #define S3C2410_GPB10_nXDRE0 (0x02 << 20)
+#define S3C2400_GPB10_DATA26 (0x02 << 20)
+#define S3C2400_GPB10_nSS    (0x03 << 20)
+
+#define S3C2400_GPB11        S3C2410_GPIONO(S3C2410_GPIO_BANKB, 11)
+#define S3C2400_GPB11_INP    (0x00 << 22)
+#define S3C2400_GPB11_OUTP   (0x01 << 22)
+#define S3C2400_GPB11_DATA27 (0x02 << 22)
+
+#define S3C2400_GPB12        S3C2410_GPIONO(S3C2410_GPIO_BANKB, 12)
+#define S3C2400_GPB12_INP    (0x00 << 24)
+#define S3C2400_GPB12_OUTP   (0x01 << 24)
+#define S3C2400_GPB12_DATA28 (0x02 << 24)
+
+#define S3C2400_GPB13        S3C2410_GPIONO(S3C2410_GPIO_BANKB, 13)
+#define S3C2400_GPB13_INP    (0x00 << 26)
+#define S3C2400_GPB13_OUTP   (0x01 << 26)
+#define S3C2400_GPB13_DATA29 (0x02 << 26)
+
+#define S3C2400_GPB14        S3C2410_GPIONO(S3C2410_GPIO_BANKB, 14)
+#define S3C2400_GPB14_INP    (0x00 << 28)
+#define S3C2400_GPB14_OUTP   (0x01 << 28)
+#define S3C2400_GPB14_DATA30 (0x02 << 28)
+
+#define S3C2400_GPB15        S3C2410_GPIONO(S3C2410_GPIO_BANKB, 15)
+#define S3C2400_GPB15_INP    (0x00 << 30)
+#define S3C2400_GPB15_OUTP   (0x01 << 30)
+#define S3C2400_GPB15_DATA31 (0x02 << 30)
+
+#define S3C2410_GPB_PUPDIS(x)  (1<<(x))
 
 /* Port C consits of 16 GPIO/Special function
  *
@@ -233,150 +302,193 @@
 #define S3C2410_GPCDAT	   S3C2410_GPIOREG(0x24)
 #define S3C2410_GPCUP	   S3C2410_GPIOREG(0x28)
 
+#define S3C2400_GPCCON	   S3C2410_GPIOREG(0x14)
+#define S3C2400_GPCDAT	   S3C2410_GPIOREG(0x18)
+#define S3C2400_GPCUP	   S3C2410_GPIOREG(0x1C)
+
 #define S3C2410_GPC0            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 0)
 #define S3C2410_GPC0_INP	(0x00 << 0)
 #define S3C2410_GPC0_OUTP	(0x01 << 0)
 #define S3C2410_GPC0_LEND	(0x02 << 0)
+#define S3C2400_GPC0_VD0 	(0x02 << 0)
 
 #define S3C2410_GPC1            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 1)
 #define S3C2410_GPC1_INP	(0x00 << 2)
 #define S3C2410_GPC1_OUTP	(0x01 << 2)
 #define S3C2410_GPC1_VCLK	(0x02 << 2)
+#define S3C2400_GPC1_VD1 	(0x02 << 2)
 
 #define S3C2410_GPC2            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 2)
 #define S3C2410_GPC2_INP	(0x00 << 4)
 #define S3C2410_GPC2_OUTP	(0x01 << 4)
 #define S3C2410_GPC2_VLINE	(0x02 << 4)
+#define S3C2400_GPC2_VD2  	(0x02 << 4)
 
 #define S3C2410_GPC3            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 3)
 #define S3C2410_GPC3_INP	(0x00 << 6)
 #define S3C2410_GPC3_OUTP	(0x01 << 6)
 #define S3C2410_GPC3_VFRAME	(0x02 << 6)
+#define S3C2400_GPC3_VD3   	(0x02 << 6)
 
 #define S3C2410_GPC4            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 4)
 #define S3C2410_GPC4_INP	(0x00 << 8)
 #define S3C2410_GPC4_OUTP	(0x01 << 8)
 #define S3C2410_GPC4_VM		(0x02 << 8)
+#define S3C2400_GPC4_VD4	(0x02 << 8)
 
 #define S3C2410_GPC5            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 5)
 #define S3C2410_GPC5_INP	(0x00 << 10)
 #define S3C2410_GPC5_OUTP	(0x01 << 10)
 #define S3C2410_GPC5_LCDVF0	(0x02 << 10)
+#define S3C2400_GPC5_VD5   	(0x02 << 10)
 
 #define S3C2410_GPC6            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 6)
 #define S3C2410_GPC6_INP	(0x00 << 12)
 #define S3C2410_GPC6_OUTP	(0x01 << 12)
 #define S3C2410_GPC6_LCDVF1	(0x02 << 12)
+#define S3C2400_GPC6_VD6   	(0x02 << 12)
 
 #define S3C2410_GPC7            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 7)
 #define S3C2410_GPC7_INP	(0x00 << 14)
 #define S3C2410_GPC7_OUTP	(0x01 << 14)
 #define S3C2410_GPC7_LCDVF2	(0x02 << 14)
+#define S3C2400_GPC7_VD7   	(0x02 << 14)
 
 #define S3C2410_GPC8            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 8)
 #define S3C2410_GPC8_INP	(0x00 << 16)
 #define S3C2410_GPC8_OUTP	(0x01 << 16)
 #define S3C2410_GPC8_VD0	(0x02 << 16)
+#define S3C2400_GPC8_VD8	(0x02 << 16)
 
 #define S3C2410_GPC9            S3C2410_GPIONO(S3C2410_GPIO_BANKC, 9)
 #define S3C2410_GPC9_INP	(0x00 << 18)
 #define S3C2410_GPC9_OUTP	(0x01 << 18)
 #define S3C2410_GPC9_VD1	(0x02 << 18)
+#define S3C2400_GPC9_VD9	(0x02 << 18)
 
 #define S3C2410_GPC10           S3C2410_GPIONO(S3C2410_GPIO_BANKC, 10)
 #define S3C2410_GPC10_INP	(0x00 << 20)
 #define S3C2410_GPC10_OUTP	(0x01 << 20)
 #define S3C2410_GPC10_VD2	(0x02 << 20)
+#define S3C2400_GPC10_VD10	(0x02 << 20)
 
 #define S3C2410_GPC11           S3C2410_GPIONO(S3C2410_GPIO_BANKC, 11)
 #define S3C2410_GPC11_INP	(0x00 << 22)
 #define S3C2410_GPC11_OUTP	(0x01 << 22)
 #define S3C2410_GPC11_VD3	(0x02 << 22)
+#define S3C2400_GPC11_VD11	(0x02 << 22)
 
 #define S3C2410_GPC12           S3C2410_GPIONO(S3C2410_GPIO_BANKC, 12)
 #define S3C2410_GPC12_INP	(0x00 << 24)
 #define S3C2410_GPC12_OUTP	(0x01 << 24)
 #define S3C2410_GPC12_VD4	(0x02 << 24)
+#define S3C2400_GPC12_VD12	(0x02 << 24)
 
 #define S3C2410_GPC13           S3C2410_GPIONO(S3C2410_GPIO_BANKC, 13)
 #define S3C2410_GPC13_INP	(0x00 << 26)
 #define S3C2410_GPC13_OUTP	(0x01 << 26)
 #define S3C2410_GPC13_VD5	(0x02 << 26)
+#define S3C2400_GPC13_VD13	(0x02 << 26)
 
 #define S3C2410_GPC14           S3C2410_GPIONO(S3C2410_GPIO_BANKC, 14)
 #define S3C2410_GPC14_INP	(0x00 << 28)
 #define S3C2410_GPC14_OUTP	(0x01 << 28)
 #define S3C2410_GPC14_VD6	(0x02 << 28)
+#define S3C2400_GPC14_VD14	(0x02 << 28)
 
 #define S3C2410_GPC15           S3C2410_GPIONO(S3C2410_GPIO_BANKC, 15)
 #define S3C2410_GPC15_INP	(0x00 << 30)
 #define S3C2410_GPC15_OUTP	(0x01 << 30)
 #define S3C2410_GPC15_VD7	(0x02 << 30)
+#define S3C2400_GPC15_VD15	(0x02 << 30)
 
-/* Port D consists of 16 GPIO/Special function
+#define S3C2410_GPC_PUPDIS(x)  (1<<(x))
+
+/*
+ * S3C2410: Port D consists of 16 GPIO/Special function
  *
  * almost identical setup to port b, but the special functions are mostly
  * to do with the video system's data.
+ *
+ * S3C2400: Port D consists of 11 GPIO/Special function
+ *
+ * almost identical setup to port c
 */
 
 #define S3C2410_GPDCON	   S3C2410_GPIOREG(0x30)
 #define S3C2410_GPDDAT	   S3C2410_GPIOREG(0x34)
 #define S3C2410_GPDUP	   S3C2410_GPIOREG(0x38)
 
+#define S3C2400_GPDCON	   S3C2410_GPIOREG(0x20)
+#define S3C2400_GPDDAT	   S3C2410_GPIOREG(0x24)
+#define S3C2400_GPDUP	   S3C2410_GPIOREG(0x28)
+
 #define S3C2410_GPD0            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 0)
 #define S3C2410_GPD0_INP	(0x00 << 0)
 #define S3C2410_GPD0_OUTP	(0x01 << 0)
 #define S3C2410_GPD0_VD8	(0x02 << 0)
+#define S3C2400_GPD0_VFRAME	(0x02 << 0)
 
 #define S3C2410_GPD1            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 1)
 #define S3C2410_GPD1_INP	(0x00 << 2)
 #define S3C2410_GPD1_OUTP	(0x01 << 2)
 #define S3C2410_GPD1_VD9	(0x02 << 2)
+#define S3C2400_GPD1_VM		(0x02 << 2)
 
 #define S3C2410_GPD2            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 2)
 #define S3C2410_GPD2_INP	(0x00 << 4)
 #define S3C2410_GPD2_OUTP	(0x01 << 4)
 #define S3C2410_GPD2_VD10	(0x02 << 4)
+#define S3C2400_GPD2_VLINE	(0x02 << 4)
 
 #define S3C2410_GPD3            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 3)
 #define S3C2410_GPD3_INP	(0x00 << 6)
 #define S3C2410_GPD3_OUTP	(0x01 << 6)
 #define S3C2410_GPD3_VD11	(0x02 << 6)
+#define S3C2400_GPD3_VCLK	(0x02 << 6)
 
 #define S3C2410_GPD4            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 4)
 #define S3C2410_GPD4_INP	(0x00 << 8)
 #define S3C2410_GPD4_OUTP	(0x01 << 8)
 #define S3C2410_GPD4_VD12	(0x02 << 8)
+#define S3C2400_GPD4_LEND	(0x02 << 8)
 
 #define S3C2410_GPD5            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 5)
 #define S3C2410_GPD5_INP	(0x00 << 10)
 #define S3C2410_GPD5_OUTP	(0x01 << 10)
 #define S3C2410_GPD5_VD13	(0x02 << 10)
+#define S3C2400_GPD5_TOUT0	(0x02 << 10)
 
 #define S3C2410_GPD6            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 6)
 #define S3C2410_GPD6_INP	(0x00 << 12)
 #define S3C2410_GPD6_OUTP	(0x01 << 12)
 #define S3C2410_GPD6_VD14	(0x02 << 12)
+#define S3C2400_GPD6_TOUT1	(0x02 << 12)
 
 #define S3C2410_GPD7            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 7)
 #define S3C2410_GPD7_INP	(0x00 << 14)
 #define S3C2410_GPD7_OUTP	(0x01 << 14)
 #define S3C2410_GPD7_VD15	(0x02 << 14)
+#define S3C2400_GPD7_TOUT2	(0x02 << 14)
 
 #define S3C2410_GPD8            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 8)
 #define S3C2410_GPD8_INP	(0x00 << 16)
 #define S3C2410_GPD8_OUTP	(0x01 << 16)
 #define S3C2410_GPD8_VD16	(0x02 << 16)
+#define S3C2400_GPD8_TOUT3	(0x02 << 16)
 
 #define S3C2410_GPD9            S3C2410_GPIONO(S3C2410_GPIO_BANKD, 9)
 #define S3C2410_GPD9_INP	(0x00 << 18)
 #define S3C2410_GPD9_OUTP	(0x01 << 18)
 #define S3C2410_GPD9_VD17	(0x02 << 18)
+#define S3C2400_GPD9_TCLK0	(0x02 << 18)
+#define S3C2410_GPD9_MASK       (0x03 << 18)
 
 #define S3C2410_GPD10           S3C2410_GPIONO(S3C2410_GPIO_BANKD, 10)
 #define S3C2410_GPD10_INP	(0x00 << 20)
 #define S3C2410_GPD10_OUTP	(0x01 << 20)
 #define S3C2410_GPD10_VD18	(0x02 << 20)
+#define S3C2400_GPD10_nWAIT	(0x02 << 20)
 
 #define S3C2410_GPD11           S3C2410_GPIONO(S3C2410_GPIO_BANKD, 11)
 #define S3C2410_GPD11_INP	(0x00 << 22)
@@ -403,37 +515,56 @@
 #define S3C2410_GPD15_OUTP	(0x01 << 30)
 #define S3C2410_GPD15_VD23	(0x02 << 30)
 
-/* Port E consists of 16 GPIO/Special function
+#define S3C2410_GPD_PUPDIS(x)  (1<<(x))
+
+/* S3C2410:
+ * Port E consists of 16 GPIO/Special function
  *
  * again, the same as port B, but dealing with I2S, SDI, and
  * more miscellaneous functions
+ *
+ * S3C2400:
+ * Port E consists of 12 GPIO/Special function
+ *
+ * GPIO / interrupt inputs
 */
 
 #define S3C2410_GPECON	   S3C2410_GPIOREG(0x40)
 #define S3C2410_GPEDAT	   S3C2410_GPIOREG(0x44)
 #define S3C2410_GPEUP	   S3C2410_GPIOREG(0x48)
 
+#define S3C2400_GPECON	   S3C2410_GPIOREG(0x2C)
+#define S3C2400_GPEDAT	   S3C2410_GPIOREG(0x30)
+#define S3C2400_GPEUP	   S3C2410_GPIOREG(0x34)
+
 #define S3C2410_GPE0           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 0)
 #define S3C2410_GPE0_INP       (0x00 << 0)
 #define S3C2410_GPE0_OUTP      (0x01 << 0)
 #define S3C2410_GPE0_I2SLRCK   (0x02 << 0)
+#define S3C2400_GPE0_EINT0     (0x02 << 0)
 #define S3C2410_GPE0_MASK      (0x03 << 0)
 
 #define S3C2410_GPE1           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 1)
 #define S3C2410_GPE1_INP       (0x00 << 2)
 #define S3C2410_GPE1_OUTP      (0x01 << 2)
 #define S3C2410_GPE1_I2SSCLK   (0x02 << 2)
+#define S3C2400_GPE1_EINT1     (0x02 << 2)
+#define S3C2400_GPE1_nSS       (0x03 << 2)
 #define S3C2410_GPE1_MASK      (0x03 << 2)
 
 #define S3C2410_GPE2           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 2)
 #define S3C2410_GPE2_INP       (0x00 << 4)
 #define S3C2410_GPE2_OUTP      (0x01 << 4)
 #define S3C2410_GPE2_CDCLK     (0x02 << 4)
+#define S3C2400_GPE2_EINT2     (0x02 << 4)
+#define S3C2400_GPE2_I2SSDI    (0x03 << 4)
 
 #define S3C2410_GPE3           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 3)
 #define S3C2410_GPE3_INP       (0x00 << 6)
 #define S3C2410_GPE3_OUTP      (0x01 << 6)
 #define S3C2410_GPE3_I2SSDI    (0x02 << 6)
+#define S3C2400_GPE3_EINT3     (0x02 << 6)
+#define S3C2400_GPE3_nCTS1     (0x03 << 6)
 #define S3C2410_GPE3_nSS0      (0x03 << 6)
 #define S3C2410_GPE3_MASK      (0x03 << 6)
 
@@ -441,6 +572,8 @@
 #define S3C2410_GPE4_INP       (0x00 << 8)
 #define S3C2410_GPE4_OUTP      (0x01 << 8)
 #define S3C2410_GPE4_I2SSDO    (0x02 << 8)
+#define S3C2400_GPE4_EINT4     (0x02 << 8)
+#define S3C2400_GPE4_nRTS1     (0x03 << 8)
 #define S3C2410_GPE4_I2SSDI    (0x03 << 8)
 #define S3C2410_GPE4_MASK      (0x03 << 8)
 
@@ -448,36 +581,46 @@
 #define S3C2410_GPE5_INP       (0x00 << 10)
 #define S3C2410_GPE5_OUTP      (0x01 << 10)
 #define S3C2410_GPE5_SDCLK     (0x02 << 10)
+#define S3C2400_GPE5_EINT5     (0x02 << 10)
+#define S3C2400_GPE5_TCLK1     (0x03 << 10)
 
 #define S3C2410_GPE6           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 6)
 #define S3C2410_GPE6_INP       (0x00 << 12)
 #define S3C2410_GPE6_OUTP      (0x01 << 12)
 #define S3C2410_GPE6_SDCMD     (0x02 << 12)
+#define S3C2400_GPE6_EINT6     (0x02 << 12)
 
 #define S3C2410_GPE7           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 7)
 #define S3C2410_GPE7_INP       (0x00 << 14)
 #define S3C2410_GPE7_OUTP      (0x01 << 14)
 #define S3C2410_GPE7_SDDAT0    (0x02 << 14)
+#define S3C2400_GPE7_EINT7     (0x02 << 14)
 
 #define S3C2410_GPE8           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 8)
 #define S3C2410_GPE8_INP       (0x00 << 16)
 #define S3C2410_GPE8_OUTP      (0x01 << 16)
 #define S3C2410_GPE8_SDDAT1    (0x02 << 16)
+#define S3C2400_GPE8_nXDACK0   (0x02 << 16)
 
 #define S3C2410_GPE9           S3C2410_GPIONO(S3C2410_GPIO_BANKE, 9)
 #define S3C2410_GPE9_INP       (0x00 << 18)
 #define S3C2410_GPE9_OUTP      (0x01 << 18)
 #define S3C2410_GPE9_SDDAT2    (0x02 << 18)
+#define S3C2400_GPE9_nXDACK1   (0x02 << 18)
+#define S3C2400_GPE9_nXBACK    (0x03 << 18)
 
 #define S3C2410_GPE10          S3C2410_GPIONO(S3C2410_GPIO_BANKE, 10)
 #define S3C2410_GPE10_INP      (0x00 << 20)
 #define S3C2410_GPE10_OUTP     (0x01 << 20)
 #define S3C2410_GPE10_SDDAT3   (0x02 << 20)
+#define S3C2400_GPE10_nXDREQ0  (0x02 << 20)
 
 #define S3C2410_GPE11          S3C2410_GPIONO(S3C2410_GPIO_BANKE, 11)
 #define S3C2410_GPE11_INP      (0x00 << 22)
 #define S3C2410_GPE11_OUTP     (0x01 << 22)
 #define S3C2410_GPE11_SPIMISO0 (0x02 << 22)
+#define S3C2400_GPE11_nXDREQ1  (0x02 << 22)
+#define S3C2400_GPE11_nXBREQ   (0x03 << 22)
 
 #define S3C2410_GPE12          S3C2410_GPIONO(S3C2410_GPIO_BANKE, 12)
 #define S3C2410_GPE12_INP      (0x00 << 24)
@@ -509,7 +652,8 @@
 
 #define S3C2410_GPE_PUPDIS(x)  (1<<(x))
 
-/* Port F consists of 8 GPIO/Special function
+/* S3C2410:
+ * Port F consists of 8 GPIO/Special function
  *
  * GPIO / interrupt inputs
  *
@@ -517,100 +661,141 @@
  *   00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 undefined
  *
  * pull up works like all other ports.
+ *
+ * S3C2400:
+ * Port F consists of 7 GPIO/Special function
+ *
+ * GPIO/serial/misc pins
 */
 
 #define S3C2410_GPFCON	   S3C2410_GPIOREG(0x50)
 #define S3C2410_GPFDAT	   S3C2410_GPIOREG(0x54)
 #define S3C2410_GPFUP	   S3C2410_GPIOREG(0x58)
 
+#define S3C2400_GPFCON	   S3C2410_GPIOREG(0x38)
+#define S3C2400_GPFDAT	   S3C2410_GPIOREG(0x3C)
+#define S3C2400_GPFUP	   S3C2410_GPIOREG(0x40)
+
 #define S3C2410_GPF0        S3C2410_GPIONO(S3C2410_GPIO_BANKF, 0)
 #define S3C2410_GPF0_INP    (0x00 << 0)
 #define S3C2410_GPF0_OUTP   (0x01 << 0)
 #define S3C2410_GPF0_EINT0  (0x02 << 0)
+#define S3C2400_GPF0_RXD0   (0x02 << 0)
 
 #define S3C2410_GPF1        S3C2410_GPIONO(S3C2410_GPIO_BANKF, 1)
 #define S3C2410_GPF1_INP    (0x00 << 2)
 #define S3C2410_GPF1_OUTP   (0x01 << 2)
 #define S3C2410_GPF1_EINT1  (0x02 << 2)
+#define S3C2400_GPF1_RXD1   (0x02 << 2)
+#define S3C2400_GPF1_IICSDA (0x03 << 2)
 
 #define S3C2410_GPF2        S3C2410_GPIONO(S3C2410_GPIO_BANKF, 2)
 #define S3C2410_GPF2_INP    (0x00 << 4)
 #define S3C2410_GPF2_OUTP   (0x01 << 4)
 #define S3C2410_GPF2_EINT2  (0x02 << 4)
+#define S3C2400_GPF2_TXD0   (0x02 << 4)
 
 #define S3C2410_GPF3        S3C2410_GPIONO(S3C2410_GPIO_BANKF, 3)
 #define S3C2410_GPF3_INP    (0x00 << 6)
 #define S3C2410_GPF3_OUTP   (0x01 << 6)
 #define S3C2410_GPF3_EINT3  (0x02 << 6)
+#define S3C2400_GPF3_TXD1   (0x02 << 6)
+#define S3C2400_GPF3_IICSCL (0x03 << 6)
 
 #define S3C2410_GPF4        S3C2410_GPIONO(S3C2410_GPIO_BANKF, 4)
 #define S3C2410_GPF4_INP    (0x00 << 8)
 #define S3C2410_GPF4_OUTP   (0x01 << 8)
 #define S3C2410_GPF4_EINT4  (0x02 << 8)
+#define S3C2400_GPF4_nRTS0  (0x02 << 8)
+#define S3C2400_GPF4_nXBACK (0x03 << 8)
 
 #define S3C2410_GPF5        S3C2410_GPIONO(S3C2410_GPIO_BANKF, 5)
 #define S3C2410_GPF5_INP    (0x00 << 10)
 #define S3C2410_GPF5_OUTP   (0x01 << 10)
 #define S3C2410_GPF5_EINT5  (0x02 << 10)
+#define S3C2400_GPF5_nCTS0  (0x02 << 10)
+#define S3C2400_GPF5_nXBREQ (0x03 << 10)
 
 #define S3C2410_GPF6        S3C2410_GPIONO(S3C2410_GPIO_BANKF, 6)
 #define S3C2410_GPF6_INP    (0x00 << 12)
 #define S3C2410_GPF6_OUTP   (0x01 << 12)
 #define S3C2410_GPF6_EINT6  (0x02 << 12)
+#define S3C2400_GPF6_CLKOUT (0x02 << 12)
 
 #define S3C2410_GPF7        S3C2410_GPIONO(S3C2410_GPIO_BANKF, 7)
 #define S3C2410_GPF7_INP    (0x00 << 14)
 #define S3C2410_GPF7_OUTP   (0x01 << 14)
 #define S3C2410_GPF7_EINT7  (0x02 << 14)
 
-/* Port G consists of 8 GPIO/IRQ/Special function
+#define S3C2410_GPF_PUPDIS(x)  (1<<(x))
+
+/* S3C2410:
+ * Port G consists of 8 GPIO/IRQ/Special function
  *
  * GPGCON has 2 bits for each of the input pins on port F
  *   00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
  *
  * pull up works like all other ports.
+ *
+ * S3C2400:
+ * Port G consists of 10 GPIO/Special function
 */
 
 #define S3C2410_GPGCON	   S3C2410_GPIOREG(0x60)
 #define S3C2410_GPGDAT	   S3C2410_GPIOREG(0x64)
 #define S3C2410_GPGUP	   S3C2410_GPIOREG(0x68)
 
+#define S3C2400_GPGCON	   S3C2410_GPIOREG(0x44)
+#define S3C2400_GPGDAT	   S3C2410_GPIOREG(0x48)
+#define S3C2400_GPGUP	   S3C2410_GPIOREG(0x4C)
+
 #define S3C2410_GPG0          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 0)
 #define S3C2410_GPG0_INP      (0x00 << 0)
 #define S3C2410_GPG0_OUTP     (0x01 << 0)
 #define S3C2410_GPG0_EINT8    (0x02 << 0)
+#define S3C2400_GPG0_I2SLRCK  (0x02 << 0)
 
 #define S3C2410_GPG1          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 1)
 #define S3C2410_GPG1_INP      (0x00 << 2)
 #define S3C2410_GPG1_OUTP     (0x01 << 2)
 #define S3C2410_GPG1_EINT9    (0x02 << 2)
+#define S3C2400_GPG1_I2SSCLK  (0x02 << 2)
 
 #define S3C2410_GPG2          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 2)
 #define S3C2410_GPG2_INP      (0x00 << 4)
 #define S3C2410_GPG2_OUTP     (0x01 << 4)
 #define S3C2410_GPG2_EINT10   (0x02 << 4)
+#define S3C2400_GPG2_CDCLK    (0x02 << 4)
 
 #define S3C2410_GPG3          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 3)
 #define S3C2410_GPG3_INP      (0x00 << 6)
 #define S3C2410_GPG3_OUTP     (0x01 << 6)
 #define S3C2410_GPG3_EINT11   (0x02 << 6)
+#define S3C2400_GPG3_I2SSDO   (0x02 << 6)
+#define S3C2400_GPG3_I2SSDI   (0x03 << 6)
 
 #define S3C2410_GPG4          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 4)
 #define S3C2410_GPG4_INP      (0x00 << 8)
 #define S3C2410_GPG4_OUTP     (0x01 << 8)
 #define S3C2410_GPG4_EINT12   (0x02 << 8)
+#define S3C2400_GPG4_MMCCLK   (0x02 << 8)
+#define S3C2400_GPG4_I2SSDI   (0x03 << 8)
 #define S3C2410_GPG4_LCDPWREN (0x03 << 8)
 
 #define S3C2410_GPG5          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 5)
 #define S3C2410_GPG5_INP      (0x00 << 10)
 #define S3C2410_GPG5_OUTP     (0x01 << 10)
 #define S3C2410_GPG5_EINT13   (0x02 << 10)
+#define S3C2400_GPG5_MMCCMD   (0x02 << 10)
+#define S3C2400_GPG5_IICSDA   (0x03 << 10)
 #define S3C2410_GPG5_SPIMISO1 (0x03 << 10)
 
 #define S3C2410_GPG6          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 6)
 #define S3C2410_GPG6_INP      (0x00 << 12)
 #define S3C2410_GPG6_OUTP     (0x01 << 12)
 #define S3C2410_GPG6_EINT14   (0x02 << 12)
+#define S3C2400_GPG6_MMCDAT   (0x02 << 12)
+#define S3C2400_GPG6_IICSCL   (0x03 << 12)
 #define S3C2410_GPG6_SPIMOSI1 (0x03 << 12)
 
 #define S3C2410_GPG7          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 7)
@@ -618,16 +803,22 @@
 #define S3C2410_GPG7_OUTP     (0x01 << 14)
 #define S3C2410_GPG7_EINT15   (0x02 << 14)
 #define S3C2410_GPG7_SPICLK1  (0x03 << 14)
+#define S3C2400_GPG7_SPIMISO  (0x02 << 14)
+#define S3C2400_GPG7_IICSDA   (0x03 << 14)
 
 #define S3C2410_GPG8          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 8)
 #define S3C2410_GPG8_INP      (0x00 << 16)
 #define S3C2410_GPG8_OUTP     (0x01 << 16)
 #define S3C2410_GPG8_EINT16   (0x02 << 16)
+#define S3C2400_GPG8_SPIMOSI  (0x02 << 16)
+#define S3C2400_GPG8_IICSCL   (0x03 << 16)
 
 #define S3C2410_GPG9          S3C2410_GPIONO(S3C2410_GPIO_BANKG, 9)
 #define S3C2410_GPG9_INP      (0x00 << 18)
 #define S3C2410_GPG9_OUTP     (0x01 << 18)
 #define S3C2410_GPG9_EINT17   (0x02 << 18)
+#define S3C2400_GPG9_SPICLK   (0x02 << 18)
+#define S3C2400_GPG9_MMCCLK   (0x03 << 18)
 
 #define S3C2410_GPG10         S3C2410_GPIONO(S3C2410_GPIO_BANKG, 10)
 #define S3C2410_GPG10_INP     (0x00 << 20)
@@ -737,19 +928,27 @@
 #define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
 
 /* miscellaneous control */
-
+#define S3C2400_MISCCR	   S3C2410_GPIOREG(0x54)
 #define S3C2410_MISCCR	   S3C2410_GPIOREG(0x80)
 #define S3C2410_DCLKCON	   S3C2410_GPIOREG(0x84)
 
 /* see clock.h for dclk definitions */
 
 /* pullup control on databus */
-#define S3C2410_MISCCR_SPUCR_HEN    (0)
+#define S3C2410_MISCCR_SPUCR_HEN    (0<<0)
 #define S3C2410_MISCCR_SPUCR_HDIS   (1<<0)
-#define S3C2410_MISCCR_SPUCR_LEN    (0)
+#define S3C2410_MISCCR_SPUCR_LEN    (0<<1)
 #define S3C2410_MISCCR_SPUCR_LDIS   (1<<1)
 
-#define S3C2410_MISCCR_USBDEV	    (0)
+#define S3C2400_MISCCR_SPUCR_LEN    (0<<0)
+#define S3C2400_MISCCR_SPUCR_LDIS   (1<<0)
+#define S3C2400_MISCCR_SPUCR_HEN    (0<<1)
+#define S3C2400_MISCCR_SPUCR_HDIS   (1<<1)
+
+#define S3C2400_MISCCR_HZ_STOPEN    (0<<2)
+#define S3C2400_MISCCR_HZ_STOPPREV  (1<<2)
+
+#define S3C2410_MISCCR_USBDEV	    (0<<3)
 #define S3C2410_MISCCR_USBHOST	    (1<<3)
 
 #define S3C2410_MISCCR_CLK0_MPLL    (0<<4)
@@ -785,7 +984,7 @@
  *
  * Samsung datasheet p9-25
 */
-
+#define S3C2400_EXTINT0    S3C2410_GPIOREG(0x58)
 #define S3C2410_EXTINT0	   S3C2410_GPIOREG(0x88)
 #define S3C2410_EXTINT1	   S3C2410_GPIOREG(0x8C)
 #define S3C2410_EXTINT2	   S3C2410_GPIOREG(0x90)
@@ -833,5 +1032,21 @@
 #define S3C2410_GSTATUS2_OFFRESET  (1<<1)
 #define S3C2410_GSTATUS2_PONRESET  (1<<0)
 
+/* open drain control register */
+#define S3C2400_OPENCR     S3C2410_GPIOREG(0x50)
+
+#define S3C2400_OPENCR_OPC_RXD1DIS  (0<<0)
+#define S3C2400_OPENCR_OPC_RXD1EN   (1<<0)
+#define S3C2400_OPENCR_OPC_TXD1DIS  (0<<1)
+#define S3C2400_OPENCR_OPC_TXD1EN   (1<<1)
+#define S3C2400_OPENCR_OPC_CMDDIS   (0<<2)
+#define S3C2400_OPENCR_OPC_CMDEN    (1<<2)
+#define S3C2400_OPENCR_OPC_DATDIS   (0<<3)
+#define S3C2400_OPENCR_OPC_DATEN    (1<<3)
+#define S3C2400_OPENCR_OPC_MISODIS  (0<<4)
+#define S3C2400_OPENCR_OPC_MISOEN   (1<<4)
+#define S3C2400_OPENCR_OPC_MOSIDIS  (0<<5)
+#define S3C2400_OPENCR_OPC_MOSIEN   (1<<5)
+
 #endif	/* __ASM_ARCH_REGS_GPIO_H */
 
diff --git a/include/asm-arm/arch-sa1100/dma.h b/include/asm-arm/arch-sa1100/dma.h
index 3d60ed9..02575d7 100644
--- a/include/asm-arm/arch-sa1100/dma.h
+++ b/include/asm-arm/arch-sa1100/dma.h
@@ -15,20 +15,6 @@
 
 
 /*
- * This is the maximum DMA address that can be DMAd to.
- */
-#define MAX_DMA_ADDRESS		0xffffffff
-
-
-/*
- * The regular generic DMA interface is inappropriate for the
- * SA1100 DMA model.  None of the SA1100 specific drivers using
- * DMA are portable anyway so it's pointless to try to twist the
- * regular DMA API to accommodate them.
- */
-#define MAX_DMA_CHANNELS	0
-
-/*
  * The SA1100 has six internal DMA channels.
  */
 #define SA1100_DMA_CHANNELS	6
diff --git a/include/asm-arm/arch-sa1100/io.h b/include/asm-arm/arch-sa1100/io.h
index 9d4fe6c..040ccde 100644
--- a/include/asm-arm/arch-sa1100/io.h
+++ b/include/asm-arm/arch-sa1100/io.h
@@ -10,8 +10,6 @@
 #ifndef __ASM_ARM_ARCH_IO_H
 #define __ASM_ARM_ARCH_IO_H
 
-#include <asm/hardware.h>
-
 #define IO_SPACE_LIMIT 0xffffffff
 
 /*
diff --git a/include/asm-arm/arch-versatile/debug-macro.S b/include/asm-arm/arch-versatile/debug-macro.S
index 89e38ac..ef61671 100644
--- a/include/asm-arm/arch-versatile/debug-macro.S
+++ b/include/asm-arm/arch-versatile/debug-macro.S
@@ -11,7 +11,7 @@
  *
 */
 
-#include <asm/hardware/amba_serial.h>
+#include <linux/amba/serial.h>
 
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
diff --git a/include/asm-arm/arch-versatile/dma.h b/include/asm-arm/arch-versatile/dma.h
index dcc8ac2..6425773 100644
--- a/include/asm-arm/arch-versatile/dma.h
+++ b/include/asm-arm/arch-versatile/dma.h
@@ -18,10 +18,3 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-#define MAX_DMA_ADDRESS		0xffffffff
-#define MAX_DMA_CHANNELS	0
-
-#endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-versatile/entry-macro.S b/include/asm-arm/arch-versatile/entry-macro.S
index 90e4e97..58f0d71 100644
--- a/include/asm-arm/arch-versatile/entry-macro.S
+++ b/include/asm-arm/arch-versatile/entry-macro.S
@@ -7,7 +7,9 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-			.macro	disable_fiq
+#include <asm/hardware.h>
+
+		.macro	disable_fiq
 		.endm
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
diff --git a/include/asm-arm/atomic.h b/include/asm-arm/atomic.h
index d586f65..f72b633 100644
--- a/include/asm-arm/atomic.h
+++ b/include/asm-arm/atomic.h
@@ -205,5 +205,6 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif
 #endif
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index 7399d43..d02de72 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -332,6 +332,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * ffs: find first bit set. This is defined the same way as
@@ -351,6 +352,7 @@
 #define fls(x) \
 	( __builtin_constant_p(x) ? generic_fls(x) : \
 	  ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) )
+#define fls64(x)   generic_fls64(x)
 #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
 #define __ffs(x) (ffs(x) - 1)
 #define ffz(x) __ffs( ~(x) )
diff --git a/include/asm-arm/byteorder.h b/include/asm-arm/byteorder.h
index d648a19..741f5bc 100644
--- a/include/asm-arm/byteorder.h
+++ b/include/asm-arm/byteorder.h
@@ -15,9 +15,23 @@
 #ifndef __ASM_ARM_BYTEORDER_H
 #define __ASM_ARM_BYTEORDER_H
 
-
+#include <linux/compiler.h>
 #include <asm/types.h>
 
+static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
+{
+	__u32 t;
+
+	t = x ^ ((x << 16) | (x >> 16));	/* eor r1,r0,r0,ror #16  */
+	x = (x << 24) | (x >> 8);		/* mov r0,r0,ror #8      */
+	t &= ~0x00FF0000;			/* bic r1,r1,#0x00FF0000 */
+	x ^= (t >> 8);				/* eor r0,r0,r1,lsr #8   */
+
+	return x;
+}
+
+#define __arch__swab32(x) ___arch__swab32(x)
+
 #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
 #  define __BYTEORDER_HAS_U64__
 #  define __SWAB_64_THRU_32__
diff --git a/include/asm-arm/cache.h b/include/asm-arm/cache.h
index 8d161f7..31332c8 100644
--- a/include/asm-arm/cache.h
+++ b/include/asm-arm/cache.h
@@ -7,9 +7,4 @@
 #define L1_CACHE_SHIFT		5
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
-/*
- * largest L1 which this arch supports
- */
-#define L1_CACHE_SHIFT_MAX	5
-
 #endif
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index e81baff..09e19a7 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -14,7 +14,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 
-#include <asm/mman.h>
 #include <asm/glue.h>
 #include <asm/shmparam.h>
 
diff --git a/include/asm-arm/dma.h b/include/asm-arm/dma.h
index ef41df43a..49c01e2 100644
--- a/include/asm-arm/dma.h
+++ b/include/asm-arm/dma.h
@@ -10,6 +10,13 @@
 #include <asm/arch/dma.h>
 
 /*
+ * This is the maximum virtual address which can be DMA'd from.
+ */
+#ifndef MAX_DMA_ADDRESS
+#define MAX_DMA_ADDRESS	0xffffffff
+#endif
+
+/*
  * DMA modes
  */
 typedef unsigned int dmamode_t;
@@ -91,7 +98,9 @@
  * especially since some DMA architectures don't update the
  * DMA address immediately, but defer it to the enable_dma().
  */
-extern void set_dma_addr(dmach_t channel, unsigned long physaddr);
+extern void __set_dma_addr(dmach_t channel, void *addr);
+#define set_dma_addr(channel, addr)				\
+	__set_dma_addr(channel, bus_to_virt(addr))
 
 /* Set the DMA byte count for this channel
  *
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index 7da97a9..2d44b42 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -22,6 +22,8 @@
 #define R_ARM_NONE	0
 #define R_ARM_PC24	1
 #define R_ARM_ABS32	2
+#define R_ARM_CALL	28
+#define R_ARM_JUMP24	29
 
 #define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
diff --git a/include/asm-arm/futex.h b/include/asm-arm/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-arm/futex.h
+++ b/include/asm-arm/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-arm/hardware/sharpsl_pm.h b/include/asm-arm/hardware/sharpsl_pm.h
new file mode 100644
index 0000000..36983e5
--- /dev/null
+++ b/include/asm-arm/hardware/sharpsl_pm.h
@@ -0,0 +1,94 @@
+/*
+ * SharpSL Battery/PM Driver
+ *
+ * Copyright (c) 2004-2005 Richard Purdie
+ *
+ * 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/interrupt.h>
+
+struct sharpsl_charger_machinfo {
+	void (*init)(void);
+	void (*exit)(void);
+	int gpio_acin;
+	int gpio_batfull;
+	int gpio_batlock;
+	int gpio_fatal;
+	void (*discharge)(int);
+	void (*discharge1)(int);
+	void (*charge)(int);
+	void (*measure_temp)(int);
+	void (*presuspend)(void);
+	void (*postsuspend)(void);
+	unsigned long (*read_devdata)(int);
+#define SHARPSL_BATT_VOLT       1
+#define SHARPSL_BATT_TEMP       2
+#define SHARPSL_ACIN_VOLT       3
+#define SHARPSL_STATUS_ACIN     4
+#define SHARPSL_STATUS_LOCK     5
+#define SHARPSL_STATUS_CHRGFULL 6
+#define SHARPSL_STATUS_FATAL    7
+	unsigned long (*charger_wakeup)(void);
+	int (*should_wakeup)(unsigned int resume_on_alarm);
+	int bat_levels;
+	struct battery_thresh *bat_levels_noac;
+	struct battery_thresh *bat_levels_acin;
+	int status_high_acin;
+	int status_low_acin;
+	int status_high_noac;
+	int status_low_noac;
+};
+
+struct battery_thresh {
+	int voltage;
+	int percentage;
+};
+
+struct battery_stat {
+	int ac_status;         /* APM AC Present/Not Present */
+	int mainbat_status;    /* APM Main Battery Status */
+	int mainbat_percent;   /* Main Battery Percentage Charge */
+	int mainbat_voltage;   /* Main Battery Voltage */
+};
+
+struct sharpsl_pm_status {
+	struct device *dev;
+	struct timer_list ac_timer;
+	struct timer_list chrg_full_timer;
+
+	int charge_mode;
+#define CHRG_ERROR    (-1)
+#define CHRG_OFF      (0)
+#define CHRG_ON       (1)
+#define CHRG_DONE     (2)
+
+	unsigned int flags;
+#define SHARPSL_SUSPENDED       (1 << 0)  /* Device is Suspended */
+#define SHARPSL_ALARM_ACTIVE    (1 << 1)  /* Alarm is for charging event (not user) */
+#define SHARPSL_BL_LIMIT        (1 << 2)  /* Backlight Intensity Limited */
+#define SHARPSL_APM_QUEUED      (1 << 3)  /* APM Event Queued */
+#define SHARPSL_DO_OFFLINE_CHRG (1 << 4)  /* Trigger the offline charger */
+
+	int full_count;
+	unsigned long charge_start_time;
+	struct sharpsl_charger_machinfo *machinfo;
+	struct battery_stat battstat;
+};
+
+extern struct sharpsl_pm_status sharpsl_pm;
+
+
+#define SHARPSL_LED_ERROR  2
+#define SHARPSL_LED_ON     1
+#define SHARPSL_LED_OFF    0
+
+void sharpsl_battery_kick(void);
+void sharpsl_pm_led(int val);
+irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp);
+irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp);
+irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp);
+
diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h
index ae69db4..0cf4d4f 100644
--- a/include/asm-arm/io.h
+++ b/include/asm-arm/io.h
@@ -42,9 +42,9 @@
 extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen);
 extern void __raw_writesl(void __iomem *addr, const void *data, int longlen);
 
-extern void __raw_readsb(void __iomem *addr, void *data, int bytelen);
-extern void __raw_readsw(void __iomem *addr, void *data, int wordlen);
-extern void __raw_readsl(void __iomem *addr, void *data, int longlen);
+extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen);
+extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);
+extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
 
 #define __raw_writeb(v,a)	(__chk_io_ptr(a), *(volatile unsigned char __force  *)(a) = (v))
 #define __raw_writew(v,a)	(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
diff --git a/include/asm-arm/irq.h b/include/asm-arm/irq.h
index 59975ee..7772432 100644
--- a/include/asm-arm/irq.h
+++ b/include/asm-arm/irq.h
@@ -25,10 +25,14 @@
 extern void disable_irq(unsigned int);
 extern void enable_irq(unsigned int);
 
-#define __IRQT_FALEDGE	(1 << 0)
-#define __IRQT_RISEDGE	(1 << 1)
-#define __IRQT_LOWLVL	(1 << 2)
-#define __IRQT_HIGHLVL	(1 << 3)
+/*
+ * These correspond with the SA_TRIGGER_* defines, and therefore the
+ * IRQRESOURCE_IRQ_* defines.
+ */
+#define __IRQT_RISEDGE	(1 << 0)
+#define __IRQT_FALEDGE	(1 << 1)
+#define __IRQT_HIGHLVL	(1 << 2)
+#define __IRQT_LOWLVL	(1 << 3)
 
 #define IRQT_NOEDGE	(0)
 #define IRQT_RISING	(__IRQT_RISEDGE)
diff --git a/include/asm-arm/mach/dma.h b/include/asm-arm/mach/dma.h
index 31bf716..e7c4a20 100644
--- a/include/asm-arm/mach/dma.h
+++ b/include/asm-arm/mach/dma.h
@@ -25,13 +25,15 @@
 };
 
 struct dma_struct {
+	void		*addr;		/* single DMA address		*/
+	unsigned long	count;		/* single DMA size		*/
 	struct scatterlist buf;		/* single DMA			*/
 	int		sgcount;	/* number of DMA SG		*/
 	struct scatterlist *sg;		/* DMA Scatter-Gather List	*/
 
 	unsigned int	active:1;	/* Transfer active		*/
 	unsigned int	invalid:1;	/* Address/Count changed	*/
-	unsigned int	using_sg:1;	/* using scatter list?		*/
+
 	dmamode_t	dma_mode;	/* DMA mode			*/
 	int		speed;		/* DMA speed			*/
 
diff --git a/include/asm-arm/memory.h b/include/asm-arm/memory.h
index a547ee5..3e57236 100644
--- a/include/asm-arm/memory.h
+++ b/include/asm-arm/memory.h
@@ -122,6 +122,7 @@
  */
 #define __pa(x)			__virt_to_phys((unsigned long)(x))
 #define __va(x)			((void *)__phys_to_virt((unsigned long)(x)))
+#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 
 /*
  * Virtual <-> DMA view memory address translations
diff --git a/include/asm-arm/mman.h b/include/asm-arm/mman.h
index 8e4f69c..f0bebca 100644
--- a/include/asm-arm/mman.h
+++ b/include/asm-arm/mman.h
@@ -35,6 +35,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-arm/scatterlist.h b/include/asm-arm/scatterlist.h
index 83b876f..de2f65e 100644
--- a/include/asm-arm/scatterlist.h
+++ b/include/asm-arm/scatterlist.h
@@ -9,7 +9,6 @@
 	unsigned int	offset;		/* buffer offset		 */
 	dma_addr_t	dma_address;	/* dma address			 */
 	unsigned int	length;		/* length			 */
-	char		*__address;	/* for set_dma_addr		 */
 };
 
 /*
diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h
index 71ca7d4..d5dc624 100644
--- a/include/asm-arm/semaphore.h
+++ b/include/asm-arm/semaphore.h
@@ -47,11 +47,6 @@
 	sema_init(sem, 0);
 }
 
-static inline int sema_count(struct semaphore *sem)
-{
-	return atomic_read(&sem->count);
-}
-
 /*
  * special register calling convention
  */
diff --git a/include/asm-arm/spinlock.h b/include/asm-arm/spinlock.h
index 6ed4f91..43ad4e5 100644
--- a/include/asm-arm/spinlock.h
+++ b/include/asm-arm/spinlock.h
@@ -30,6 +30,9 @@
 	__asm__ __volatile__(
 "1:	ldrex	%0, [%1]\n"
 "	teq	%0, #0\n"
+#ifdef CONFIG_CPU_32v6K
+"	wfene\n"
+#endif
 "	strexeq	%0, %2, [%1]\n"
 "	teqeq	%0, #0\n"
 "	bne	1b"
@@ -65,7 +68,11 @@
 	smp_mb();
 
 	__asm__ __volatile__(
-"	str	%1, [%0]"
+"	str	%1, [%0]\n"
+#ifdef CONFIG_CPU_32v6K
+"	mcr	p15, 0, %1, c7, c10, 4\n" /* DSB */
+"	sev"
+#endif
 	:
 	: "r" (&lock->lock), "r" (0)
 	: "cc");
@@ -87,6 +94,9 @@
 	__asm__ __volatile__(
 "1:	ldrex	%0, [%1]\n"
 "	teq	%0, #0\n"
+#ifdef CONFIG_CPU_32v6K
+"	wfene\n"
+#endif
 "	strexeq	%0, %2, [%1]\n"
 "	teq	%0, #0\n"
 "	bne	1b"
@@ -122,7 +132,11 @@
 	smp_mb();
 
 	__asm__ __volatile__(
-	"str	%1, [%0]"
+	"str	%1, [%0]\n"
+#ifdef CONFIG_CPU_32v6K
+"	mcr	p15, 0, %1, c7, c10, 4\n" /* DSB */
+"	sev\n"
+#endif
 	:
 	: "r" (&rw->lock), "r" (0)
 	: "cc");
@@ -148,6 +162,9 @@
 "1:	ldrex	%0, [%2]\n"
 "	adds	%0, %0, #1\n"
 "	strexpl	%1, %0, [%2]\n"
+#ifdef CONFIG_CPU_32v6K
+"	wfemi\n"
+#endif
 "	rsbpls	%0, %1, #0\n"
 "	bmi	1b"
 	: "=&r" (tmp), "=&r" (tmp2)
@@ -169,6 +186,11 @@
 "	strex	%1, %0, [%2]\n"
 "	teq	%1, #0\n"
 "	bne	1b"
+#ifdef CONFIG_CPU_32v6K
+"\n	cmp	%0, #0\n"
+"	mcreq   p15, 0, %0, c7, c10, 4\n"
+"	seveq"
+#endif
 	: "=&r" (tmp), "=&r" (tmp2)
 	: "r" (&rw->lock)
 	: "cc");
diff --git a/include/asm-arm26/atomic.h b/include/asm-arm26/atomic.h
index a47cadc..3074b0e 100644
--- a/include/asm-arm26/atomic.h
+++ b/include/asm-arm26/atomic.h
@@ -118,5 +118,6 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif
 #endif
diff --git a/include/asm-arm26/bitops.h b/include/asm-arm26/bitops.h
index 7d062fb..15cc6f2 100644
--- a/include/asm-arm26/bitops.h
+++ b/include/asm-arm26/bitops.h
@@ -259,6 +259,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * ffs: find first bit set. This is defined the same way as
diff --git a/include/asm-arm26/futex.h b/include/asm-arm26/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-arm26/futex.h
+++ b/include/asm-arm26/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-arm26/mman.h b/include/asm-arm26/mman.h
index cc27b82..0ed7780 100644
--- a/include/asm-arm26/mman.h
+++ b/include/asm-arm26/mman.h
@@ -35,6 +35,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-cris/arch-v10/cache.h b/include/asm-cris/arch-v10/cache.h
index 1d1d1ba..aea2718 100644
--- a/include/asm-cris/arch-v10/cache.h
+++ b/include/asm-cris/arch-v10/cache.h
@@ -4,6 +4,5 @@
 /* Etrax 100LX have 32-byte cache-lines. */
 #define L1_CACHE_BYTES 32
 #define L1_CACHE_SHIFT 5
-#define L1_CACHE_SHIFT_MAX 5
 
 #endif /* _ASM_ARCH_CACHE_H */
diff --git a/include/asm-cris/arch-v32/cache.h b/include/asm-cris/arch-v32/cache.h
index 4fed8d6..80b236b 100644
--- a/include/asm-cris/arch-v32/cache.h
+++ b/include/asm-cris/arch-v32/cache.h
@@ -4,6 +4,5 @@
 /* A cache-line is 32 bytes. */
 #define L1_CACHE_BYTES 32
 #define L1_CACHE_SHIFT 5
-#define L1_CACHE_SHIFT_MAX 5
 
 #endif /* _ASM_CRIS_ARCH_CACHE_H */
diff --git a/include/asm-cris/atomic.h b/include/asm-cris/atomic.h
index 683b05a..2df2c7a 100644
--- a/include/asm-cris/atomic.h
+++ b/include/asm-cris/atomic.h
@@ -156,4 +156,5 @@
 #define smp_mb__before_atomic_inc()    barrier()
 #define smp_mb__after_atomic_inc()     barrier()
 
+#include <asm-generic/atomic.h>
 #endif
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h
index 1bddb3f..d3eb0f1 100644
--- a/include/asm-cris/bitops.h
+++ b/include/asm-cris/bitops.h
@@ -240,6 +240,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN - returns the hamming weight of a N-bit word
diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h
index 8eff513..cbf1a98 100644
--- a/include/asm-cris/dma-mapping.h
+++ b/include/asm-cris/dma-mapping.h
@@ -153,7 +153,7 @@
 static inline int
 dma_get_cache_alignment(void)
 {
-	return (1 << L1_CACHE_SHIFT_MAX);
+	return (1 << INTERNODE_CACHE_SHIFT);
 }
 
 #define dma_is_consistent(d)	(1)
diff --git a/include/asm-cris/futex.h b/include/asm-cris/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-cris/futex.h
+++ b/include/asm-cris/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-cris/mman.h b/include/asm-cris/mman.h
index 8570e72..5a382b8 100644
--- a/include/asm-cris/mman.h
+++ b/include/asm-cris/mman.h
@@ -37,6 +37,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-frv/atomic.h b/include/asm-frv/atomic.h
index f6539ff..9c9e949 100644
--- a/include/asm-frv/atomic.h
+++ b/include/asm-frv/atomic.h
@@ -218,51 +218,12 @@
 	__typeof__(*(ptr)) __xg_orig;						\
 										\
 	switch (sizeof(__xg_orig)) {						\
-	case 1:									\
-		asm volatile(							\
-			"0:						\n"	\
-			"	orcc		gr0,gr0,gr0,icc3	\n"	\
-			"	ckeq		icc3,cc7		\n"	\
-			"	ldub.p		%M0,%1			\n"	\
-			"	orcr		cc7,cc7,cc3		\n"	\
-			"	cstb.p		%2,%M0		,cc3,#1	\n"	\
-			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
-			"	beq		icc3,#0,0b		\n"	\
-			: "+U"(*__xg_ptr), "=&r"(__xg_orig)			\
-			: "r"(x)						\
-			: "memory", "cc7", "cc3", "icc3"			\
-			);							\
-		break;								\
-										\
-	case 2:									\
-		asm volatile(							\
-			"0:						\n"	\
-			"	orcc		gr0,gr0,gr0,icc3	\n"	\
-			"	ckeq		icc3,cc7		\n"	\
-			"	lduh.p		%M0,%1			\n"	\
-			"	orcr		cc7,cc7,cc3		\n"	\
-			"	csth.p		%2,%M0		,cc3,#1	\n"	\
-			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
-			"	beq		icc3,#0,0b		\n"	\
-			: "+U"(*__xg_ptr), "=&r"(__xg_orig)			\
-			: "r"(x)						\
-			: "memory", "cc7", "cc3", "icc3"			\
-			);							\
-		break;								\
-										\
 	case 4:									\
 		asm volatile(							\
-			"0:						\n"	\
-			"	orcc		gr0,gr0,gr0,icc3	\n"	\
-			"	ckeq		icc3,cc7		\n"	\
-			"	ld.p		%M0,%1			\n"	\
-			"	orcr		cc7,cc7,cc3		\n"	\
-			"	cst.p		%2,%M0		,cc3,#1	\n"	\
-			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
-			"	beq		icc3,#0,0b		\n"	\
-			: "+U"(*__xg_ptr), "=&r"(__xg_orig)			\
+			"swap%I0 %2,%M0"					\
+			: "+m"(*__xg_ptr), "=&r"(__xg_orig)			\
 			: "r"(x)						\
-			: "memory", "cc7", "cc3", "icc3"			\
+			: "memory"						\
 			);							\
 		break;								\
 										\
@@ -277,8 +238,6 @@
 
 #else
 
-extern uint8_t  __xchg_8 (uint8_t i,  volatile void *v);
-extern uint16_t __xchg_16(uint16_t i, volatile void *v);
 extern uint32_t __xchg_32(uint32_t i, volatile void *v);
 
 #define xchg(ptr, x)										\
@@ -287,8 +246,6 @@
 	__typeof__(*(ptr)) __xg_orig;								\
 												\
 	switch (sizeof(__xg_orig)) {								\
-	case 1: __xg_orig = (__typeof__(*(ptr))) __xchg_8 ((uint8_t)  x, __xg_ptr);	break;	\
-	case 2: __xg_orig = (__typeof__(*(ptr))) __xchg_16((uint16_t) x, __xg_ptr);	break;	\
 	case 4: __xg_orig = (__typeof__(*(ptr))) __xchg_32((uint32_t) x, __xg_ptr);	break;	\
 	default:										\
 		__xg_orig = 0;									\
@@ -318,46 +275,6 @@
 	__typeof__(*(ptr)) __xg_new = (new);					\
 										\
 	switch (sizeof(__xg_orig)) {						\
-	case 1:									\
-		asm volatile(							\
-			"0:						\n"	\
-			"	orcc		gr0,gr0,gr0,icc3	\n"	\
-			"	ckeq		icc3,cc7		\n"	\
-			"	ldub.p		%M0,%1			\n"	\
-			"	orcr		cc7,cc7,cc3		\n"	\
-			"	sub%I4		%1,%4,%2		\n"	\
-			"	sllcc		%2,#24,gr0,icc0		\n"	\
-			"	bne		icc0,#0,1f		\n"	\
-			"	cstb.p		%3,%M0		,cc3,#1	\n"	\
-			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
-			"	beq		icc3,#0,0b		\n"	\
-			"1:						\n"	\
-			: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp)	\
-			: "r"(__xg_new), "NPr"(__xg_test)			\
-			: "memory", "cc7", "cc3", "icc3", "icc0"		\
-			);							\
-		break;								\
-										\
-	case 2:									\
-		asm volatile(							\
-			"0:						\n"	\
-			"	orcc		gr0,gr0,gr0,icc3	\n"	\
-			"	ckeq		icc3,cc7		\n"	\
-			"	lduh.p		%M0,%1			\n"	\
-			"	orcr		cc7,cc7,cc3		\n"	\
-			"	sub%I4		%1,%4,%2		\n"	\
-			"	sllcc		%2,#16,gr0,icc0		\n"	\
-			"	bne		icc0,#0,1f		\n"	\
-			"	csth.p		%3,%M0		,cc3,#1	\n"	\
-			"	corcc		gr29,gr29,gr0	,cc3,#1	\n"	\
-			"	beq		icc3,#0,0b		\n"	\
-			"1:						\n"	\
-			: "+U"(*__xg_ptr), "=&r"(__xg_orig), "=&r"(__xg_tmp)	\
-			: "r"(__xg_new), "NPr"(__xg_test)			\
-			: "memory", "cc7", "cc3", "icc3", "icc0"		\
-			);							\
-		break;								\
-										\
 	case 4:									\
 		asm volatile(							\
 			"0:						\n"	\
@@ -388,8 +305,6 @@
 
 #else
 
-extern uint8_t  __cmpxchg_8 (uint8_t *v,  uint8_t test,  uint8_t new);
-extern uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new);
 extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
 
 #define cmpxchg(ptr, test, new)							\
@@ -400,8 +315,6 @@
 	__typeof__(*(ptr)) __xg_new = (new);					\
 										\
 	switch (sizeof(__xg_orig)) {						\
-	case 1: __xg_orig = __cmpxchg_8 (__xg_ptr, __xg_test, __xg_new); break;	\
-	case 2: __xg_orig = __cmpxchg_16(__xg_ptr, __xg_test, __xg_new); break;	\
 	case 4: __xg_orig = __cmpxchg_32(__xg_ptr, __xg_test, __xg_new); break;	\
 	default:								\
 		__xg_orig = 0;							\
@@ -414,7 +327,7 @@
 
 #endif
 
-#define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new))
+#define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new))
 
 #define atomic_add_unless(v, a, u)				\
 ({								\
@@ -424,6 +337,8 @@
 		c = old;					\
 	c != (u);						\
 })
+
 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
 
+#include <asm-generic/atomic.h>
 #endif /* _ASM_ATOMIC_H */
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h
index b664bd5..02be7b3 100644
--- a/include/asm-frv/bitops.h
+++ b/include/asm-frv/bitops.h
@@ -228,6 +228,7 @@
 							\
 	bit ? 33 - bit : bit;				\
 })
+#define fls64(x)   generic_fls64(x)
 
 /*
  * Every architecture must define this function. It's the fastest
diff --git a/include/asm-frv/bug.h b/include/asm-frv/bug.h
index 074c0d5..451712c 100644
--- a/include/asm-frv/bug.h
+++ b/include/asm-frv/bug.h
@@ -12,6 +12,7 @@
 #define _ASM_BUG_H
 
 #include <linux/config.h>
+#include <linux/linkage.h>
 
 #ifdef CONFIG_BUG
 /*
diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h
index 5003e01..e9fc1d4 100644
--- a/include/asm-frv/dma-mapping.h
+++ b/include/asm-frv/dma-mapping.h
@@ -23,7 +23,7 @@
  * returns, or alternatively stop on the first sg_dma_len(sg) which
  * is 0.
  */
-#define sg_dma_address(sg)	((unsigned long) (page_to_phys((sg)->page) + (sg)->offset))
+#define sg_dma_address(sg)	((sg)->dma_address)
 #define sg_dma_len(sg)		((sg)->length)
 
 /*
diff --git a/include/asm-frv/futex.h b/include/asm-frv/futex.h
index 9feff4ce..fca9d90 100644
--- a/include/asm-frv/futex.h
+++ b/include/asm-frv/futex.h
@@ -7,47 +7,7 @@
 #include <asm/errno.h>
 #include <asm/uaccess.h>
 
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
+extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr);
 
 #endif
 #endif
diff --git a/include/asm-frv/hardirq.h b/include/asm-frv/hardirq.h
index 5248ca0..6851239 100644
--- a/include/asm-frv/hardirq.h
+++ b/include/asm-frv/hardirq.h
@@ -14,6 +14,7 @@
 
 #include <linux/config.h>
 #include <linux/threads.h>
+#include <linux/irq.h>
 
 typedef struct {
 	unsigned int __softirq_pending;
diff --git a/include/asm-frv/ide.h b/include/asm-frv/ide.h
index f9caecf..ae031ea 100644
--- a/include/asm-frv/ide.h
+++ b/include/asm-frv/ide.h
@@ -33,10 +33,10 @@
 /*
  * some bits needed for parts of the IDE subsystem to compile
  */
-#define __ide_mm_insw(port, addr, n)	insw(port, addr, n)
-#define __ide_mm_insl(port, addr, n)	insl(port, addr, n)
-#define __ide_mm_outsw(port, addr, n)	outsw(port, addr, n)
-#define __ide_mm_outsl(port, addr, n)	outsl(port, addr, n)
+#define __ide_mm_insw(port, addr, n)	insw((unsigned long) (port), addr, n)
+#define __ide_mm_insl(port, addr, n)	insl((unsigned long) (port), addr, n)
+#define __ide_mm_outsw(port, addr, n)	outsw((unsigned long) (port), addr, n)
+#define __ide_mm_outsl(port, addr, n)	outsl((unsigned long) (port), addr, n)
 
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-frv/io.h b/include/asm-frv/io.h
index 48829f7..075369b 100644
--- a/include/asm-frv/io.h
+++ b/include/asm-frv/io.h
@@ -18,6 +18,7 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
+#include <linux/types.h>
 #include <asm/virtconvert.h>
 #include <asm/string.h>
 #include <asm/mb-regs.h>
@@ -104,6 +105,8 @@
 		__insl_sw(addr, buf, len);
 }
 
+#define mmiowb() mb()
+
 /*
  *	make the short names macros so specific devices
  *	can override them as required
@@ -209,6 +212,10 @@
 	return ret;
 }
 
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
+
 static inline void writeb(uint8_t datum, volatile void __iomem *addr)
 {
 	__builtin_write8((volatile uint8_t __force *) addr, datum);
@@ -268,11 +275,106 @@
 
 extern void iounmap(void __iomem *addr);
 
+static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
+{
+	return (void __iomem *) port;
+}
+
+static inline void ioport_unmap(void __iomem *p)
+{
+}
+
 static inline void flush_write_buffers(void)
 {
 	__asm__ __volatile__ ("membar" : : :"memory");
 }
 
+/*
+ * do appropriate I/O accesses for token type
+ */
+static inline unsigned int ioread8(void __iomem *p)
+{
+	return __builtin_read8(p);
+}
+
+static inline unsigned int ioread16(void __iomem *p)
+{
+	uint16_t ret = __builtin_read16(p);
+	if (__is_PCI_addr(p))
+		ret = _swapw(ret);
+	return ret;
+}
+
+static inline unsigned int ioread32(void __iomem *p)
+{
+	uint32_t ret = __builtin_read32(p);
+	if (__is_PCI_addr(p))
+		ret = _swapl(ret);
+	return ret;
+}
+
+static inline void iowrite8(u8 val, void __iomem *p)
+{
+	__builtin_write8(p, val);
+	if (__is_PCI_MEM(p))
+		__flush_PCI_writes();
+}
+
+static inline void iowrite16(u16 val, void __iomem *p)
+{
+	if (__is_PCI_addr(p))
+		val = _swapw(val);
+	__builtin_write16(p, val);
+	if (__is_PCI_MEM(p))
+		__flush_PCI_writes();
+}
+
+static inline void iowrite32(u32 val, void __iomem *p)
+{
+	if (__is_PCI_addr(p))
+		val = _swapl(val);
+	__builtin_write32(p, val);
+	if (__is_PCI_MEM(p))
+		__flush_PCI_writes();
+}
+
+static inline void ioread8_rep(void __iomem *p, void *dst, unsigned long count)
+{
+	io_insb((unsigned long) p, dst, count);
+}
+
+static inline void ioread16_rep(void __iomem *p, void *dst, unsigned long count)
+{
+	io_insw((unsigned long) p, dst, count);
+}
+
+static inline void ioread32_rep(void __iomem *p, void *dst, unsigned long count)
+{
+	__insl_ns((unsigned long) p, dst, count);
+}
+
+static inline void iowrite8_rep(void __iomem *p, const void *src, unsigned long count)
+{
+	io_outsb((unsigned long) p, src, count);
+}
+
+static inline void iowrite16_rep(void __iomem *p, const void *src, unsigned long count)
+{
+	io_outsw((unsigned long) p, src, count);
+}
+
+static inline void iowrite32_rep(void __iomem *p, const void *src, unsigned long count)
+{
+	__outsl_ns((unsigned long) p, src, count);
+}
+
+/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
+struct pci_dev;
+extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
+{
+}
+
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
@@ -285,6 +387,27 @@
  */
 #define xlate_dev_kmem_ptr(p)	p
 
+/*
+ * Check BIOS signature
+ */
+static inline int check_signature(volatile void __iomem *io_addr,
+				  const unsigned char *signature, int length)
+{
+	int retval = 0;
+
+	do {
+		if (readb(io_addr) != *signature)
+			goto out;
+		io_addr++;
+		signature++;
+		length--;
+	} while (length);
+
+	retval = 1;
+out:
+	return retval;
+}
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_IO_H */
diff --git a/include/asm-frv/mb-regs.h b/include/asm-frv/mb-regs.h
index c8f575f..93fa732 100644
--- a/include/asm-frv/mb-regs.h
+++ b/include/asm-frv/mb-regs.h
@@ -68,6 +68,9 @@
 #define __is_PCI_MEM(addr) \
 	((unsigned long)(addr) - __region_PCI_MEM < 0x08000000UL)
 
+#define __is_PCI_addr(addr) \
+	((unsigned long)(addr) - __region_PCI_IO < 0x0c000000UL)
+
 #define __get_CLKSW()	({ *(volatile unsigned long *)(__region_CS2 + 0x0130000cUL) & 0xffUL; })
 #define __get_CLKIN()	(__get_CLKSW() * 125U * 100000U / 24U)
 
@@ -149,6 +152,7 @@
 
 #define __is_PCI_IO(addr)	0	/* no PCI */
 #define __is_PCI_MEM(addr)	0
+#define __is_PCI_addr(addr)	0
 #define __region_PCI_IO		0
 #define __region_PCI_MEM	0
 #define __flush_PCI_writes()	do { } while(0)
diff --git a/include/asm-frv/mc146818rtc.h b/include/asm-frv/mc146818rtc.h
new file mode 100644
index 0000000..90dfb7a
--- /dev/null
+++ b/include/asm-frv/mc146818rtc.h
@@ -0,0 +1,16 @@
+/* mc146818rtc.h: RTC defs
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+
+#endif /* _ASM_MC146818RTC_H */
diff --git a/include/asm-frv/mman.h b/include/asm-frv/mman.h
index c684720..8af4a41 100644
--- a/include/asm-frv/mman.h
+++ b/include/asm-frv/mman.h
@@ -35,6 +35,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-frv/module.h b/include/asm-frv/module.h
index 3223cfa..3d5c636 100644
--- a/include/asm-frv/module.h
+++ b/include/asm-frv/module.h
@@ -11,10 +11,18 @@
 #ifndef _ASM_MODULE_H
 #define _ASM_MODULE_H
 
-#define module_map(x)		vmalloc(x)
-#define module_unmap(x)		vfree(x)
-#define module_arch_init(x)	(0)
-#define arch_init_modules(x)	do { } while (0)
+struct mod_arch_specific
+{
+};
+
+#define Elf_Shdr	Elf32_Shdr
+#define Elf_Sym		Elf32_Sym
+#define Elf_Ehdr	Elf32_Ehdr
+
+/*
+ * Include the architecture version.
+ */
+#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " "
 
 #endif /* _ASM_MODULE_H */
 
diff --git a/include/asm-frv/page.h b/include/asm-frv/page.h
index 4feba56..b8221b6 100644
--- a/include/asm-frv/page.h
+++ b/include/asm-frv/page.h
@@ -47,8 +47,8 @@
 
 #define devmem_is_allowed(pfn)	1
 
-#define __pa(vaddr)		virt_to_phys((void *) vaddr)
-#define __va(paddr)		phys_to_virt((unsigned long) paddr)
+#define __pa(vaddr)		virt_to_phys((void *) (unsigned long) (vaddr))
+#define __va(paddr)		phys_to_virt((unsigned long) (paddr))
 
 #define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
 
diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h
index 1168451..598b0c6 100644
--- a/include/asm-frv/pci.h
+++ b/include/asm-frv/pci.h
@@ -57,6 +57,14 @@
  */
 #define PCI_DMA_BUS_IS_PHYS	(1)
 
+/* pci_unmap_{page,single} is a nop so... */
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
+#define pci_unmap_addr(PTR, ADDR_NAME)		(0)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)	do { } while (0)
+#define pci_unmap_len(PTR, LEN_NAME)		(0)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL)	do { } while (0)
+
 #ifdef CONFIG_PCI
 static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 					enum pci_dma_burst_strategy *strat,
diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h
index 8446663..d1c3b18 100644
--- a/include/asm-frv/pgtable.h
+++ b/include/asm-frv/pgtable.h
@@ -421,6 +421,11 @@
 }
 
 /*
+ * Macro to mark a page protection value as "uncacheable"
+ */
+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE))
+
+/*
  * Conversion functions: convert a page and protection to a page entry,
  * and a page entry and page directory to the page they refer to.
  */
diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h
index b183962..907c5c3 100644
--- a/include/asm-frv/semaphore.h
+++ b/include/asm-frv/semaphore.h
@@ -20,7 +20,7 @@
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
 
-#define SEMAPHORE_DEBUG		WAITQUEUE_DEBUG
+#define SEMAPHORE_DEBUG		0
 
 /*
  * the semaphore definition
diff --git a/include/asm-frv/signal.h b/include/asm-frv/signal.h
index d407bde..6736689 100644
--- a/include/asm-frv/signal.h
+++ b/include/asm-frv/signal.h
@@ -151,7 +151,6 @@
 	size_t ss_size;
 } stack_t;
 
-extern int do_signal(struct pt_regs *regs, sigset_t *oldset);
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
 #ifdef __KERNEL__
diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
index c8cba78..60f6b2a 100644
--- a/include/asm-frv/thread_info.h
+++ b/include/asm-frv/thread_info.h
@@ -58,7 +58,7 @@
 
 #endif
 
-#define PREEMPT_ACTIVE		0x4000000
+#define PREEMPT_ACTIVE		0x10000000
 
 /*
  * macros/functions for gaining access to the thread information structure
diff --git a/include/asm-frv/types.h b/include/asm-frv/types.h
index 50605df..2560f59 100644
--- a/include/asm-frv/types.h
+++ b/include/asm-frv/types.h
@@ -59,7 +59,6 @@
 
 typedef signed long long s64;
 typedef unsigned long long u64;
-typedef u64 u_quad_t;
 
 /* Dma addresses are 32-bits wide.  */
 
diff --git a/include/asm-frv/uaccess.h b/include/asm-frv/uaccess.h
index 991b50f..b6bcbe0 100644
--- a/include/asm-frv/uaccess.h
+++ b/include/asm-frv/uaccess.h
@@ -180,16 +180,16 @@
 									\
 	switch (sizeof(*(ptr))) {					\
 	case 1:								\
-		__get_user_asm(__gu_err, __gu_val, ptr, "ub", "=r");	\
+		__get_user_asm(__gu_err, *(u8*)&__gu_val, ptr, "ub", "=r"); \
 		break;							\
 	case 2:								\
-		__get_user_asm(__gu_err, __gu_val, ptr, "uh", "=r");	\
+		__get_user_asm(__gu_err, *(u16*)&__gu_val, ptr, "uh", "=r"); \
 		break;							\
 	case 4:								\
-		__get_user_asm(__gu_err, __gu_val, ptr, "", "=r");	\
+		__get_user_asm(__gu_err, *(u32*)&__gu_val, ptr, "", "=r"); \
 		break;							\
 	case 8:								\
-		__get_user_asm(__gu_err, __gu_val, ptr, "d", "=e");	\
+		__get_user_asm(__gu_err, *(u64*)&__gu_val, ptr, "d", "=e"); \
 		break;							\
 	default:							\
 		__gu_err = __get_user_bad();				\
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h
index 5cf989b..cde376a 100644
--- a/include/asm-frv/unistd.h
+++ b/include/asm-frv/unistd.h
@@ -313,7 +313,7 @@
         unsigned long __sr2 = (res);					\
 	if (__builtin_expect(__sr2 >= (unsigned long)(-4095), 0)) {	\
 		errno = (-__sr2);					\
-		__sr2 = ULONG_MAX;					\
+		__sr2 = ~0UL;						\
 	}								\
 	return (type) __sr2;						\
 } while (0)
diff --git a/include/asm-frv/vga.h b/include/asm-frv/vga.h
new file mode 100644
index 0000000..a702c80
--- /dev/null
+++ b/include/asm-frv/vga.h
@@ -0,0 +1,17 @@
+/* vga.h: VGA register stuff
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_VGA_H
+#define _ASM_VGA_H
+
+
+
+#endif /* _ASM_VGA_H */
diff --git a/include/asm-frv/xor.h b/include/asm-frv/xor.h
new file mode 100644
index 0000000..c82eb12
--- /dev/null
+++ b/include/asm-frv/xor.h
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
new file mode 100644
index 0000000..0fada8f
--- /dev/null
+++ b/include/asm-generic/atomic.h
@@ -0,0 +1,117 @@
+#ifndef _ASM_GENERIC_ATOMIC_H
+#define _ASM_GENERIC_ATOMIC_H
+/*
+ * Copyright (C) 2005 Silicon Graphics, Inc.
+ *	Christoph Lameter <clameter@sgi.com>
+ *
+ * Allows to provide arch independent atomic definitions without the need to
+ * edit all arch specific atomic.h files.
+ */
+
+#include <asm/types.h>
+
+/*
+ * Suppport for atomic_long_t
+ *
+ * Casts for parameters are avoided for existing atomic functions in order to
+ * avoid issues with cast-as-lval under gcc 4.x and other limitations that the
+ * macros of a platform may have.
+ */
+
+#if BITS_PER_LONG == 64
+
+typedef atomic64_t atomic_long_t;
+
+#define ATOMIC_LONG_INIT(i)	ATOMIC64_INIT(i)
+
+static inline long atomic_long_read(atomic_long_t *l)
+{
+	atomic64_t *v = (atomic64_t *)l;
+
+	return (long)atomic64_read(v);
+}
+
+static inline void atomic_long_set(atomic_long_t *l, long i)
+{
+	atomic64_t *v = (atomic64_t *)l;
+
+	atomic_set(v, i);
+}
+
+static inline void atomic_long_inc(atomic_long_t *l)
+{
+	atomic64_t *v = (atomic64_t *)l;
+
+	atomic64_inc(v);
+}
+
+static inline void atomic_long_dec(atomic_long_t *l)
+{
+	atomic64_t *v = (atomic64_t *)l;
+
+	atomic64_dec(v);
+}
+
+static inline void atomic_long_add(long i, atomic_long_t *l)
+{
+	atomic64_t *v = (atomic64_t *)l;
+
+	atomic64_add(i, v);
+}
+
+static inline void atomic_long_sub(long i, atomic_long_t *l)
+{
+	atomic64_t *v = (atomic64_t *)l;
+
+	atomic64_sub(i, v);
+}
+
+#else
+
+typedef atomic_t atomic_long_t;
+
+#define ATOMIC_LONG_INIT(i)	ATOMIC_INIT(i)
+static inline long atomic_long_read(atomic_long_t *l)
+{
+	atomic_t *v = (atomic_t *)l;
+
+	return (long)atomic_read(v);
+}
+
+static inline void atomic_long_set(atomic_long_t *l, long i)
+{
+	atomic_t *v = (atomic_t *)l;
+
+	atomic_set(v, i);
+}
+
+static inline void atomic_long_inc(atomic_long_t *l)
+{
+	atomic_t *v = (atomic_t *)l;
+
+	atomic_inc(v);
+}
+
+static inline void atomic_long_dec(atomic_long_t *l)
+{
+	atomic_t *v = (atomic_t *)l;
+
+	atomic_dec(v);
+}
+
+static inline void atomic_long_add(long i, atomic_long_t *l)
+{
+	atomic_t *v = (atomic_t *)l;
+
+	atomic_add(i, v);
+}
+
+static inline void atomic_long_sub(long i, atomic_long_t *l)
+{
+	atomic_t *v = (atomic_t *)l;
+
+	atomic_sub(i, v);
+}
+
+#endif
+#endif
diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h
index ce31b73..0e6d985 100644
--- a/include/asm-generic/bitops.h
+++ b/include/asm-generic/bitops.h
@@ -56,6 +56,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h
index 747d790..1b35620 100644
--- a/include/asm-generic/dma-mapping.h
+++ b/include/asm-generic/dma-mapping.h
@@ -274,7 +274,7 @@
 {
 	/* no easy way to get cache size on all processors, so return
 	 * the maximum possible, to be safe */
-	return (1 << L1_CACHE_SHIFT_MAX);
+	return (1 << INTERNODE_CACHE_SHIFT);
 }
 
 static inline void
diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h
new file mode 100644
index 0000000..3ae2c73
--- /dev/null
+++ b/include/asm-generic/futex.h
@@ -0,0 +1,53 @@
+#ifndef _ASM_GENERIC_FUTEX_H
+#define _ASM_GENERIC_FUTEX_H
+
+#ifdef __KERNEL__
+
+#include <linux/futex.h>
+#include <asm/errno.h>
+#include <asm/uaccess.h>
+
+static inline int
+futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
+{
+	int op = (encoded_op >> 28) & 7;
+	int cmp = (encoded_op >> 24) & 15;
+	int oparg = (encoded_op << 8) >> 20;
+	int cmparg = (encoded_op << 20) >> 20;
+	int oldval = 0, ret;
+	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+		oparg = 1 << oparg;
+
+	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
+		return -EFAULT;
+
+	inc_preempt_count();
+
+	switch (op) {
+	case FUTEX_OP_SET:
+	case FUTEX_OP_ADD:
+	case FUTEX_OP_OR:
+	case FUTEX_OP_ANDN:
+	case FUTEX_OP_XOR:
+	default:
+		ret = -ENOSYS;
+	}
+
+	dec_preempt_count();
+
+	if (!ret) {
+		switch (cmp) {
+		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
+		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
+		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
+		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
+		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
+		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
+		default: ret = -ENOSYS;
+		}
+	}
+	return ret;
+}
+
+#endif
+#endif
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 094d491..35de20c 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -10,6 +10,8 @@
 #define ALIGN_FUNCTION()  . = ALIGN(8)
 
 #define RODATA								\
+	. = ALIGN(4096);						\
+	__start_rodata = .;						\
 	.rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {		\
 		*(.rodata) *(.rodata.*)					\
 		*(__vermagic)		/* Kernel version magic */	\
@@ -74,6 +76,8 @@
         __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
 		*(__ksymtab_strings)					\
 	}								\
+	__end_rodata = .;						\
+	. = ALIGN(4096);						\
 									\
 	/* Built-in module parameters. */				\
 	__param : AT(ADDR(__param) - LOAD_OFFSET) {			\
diff --git a/include/asm-h8300/atomic.h b/include/asm-h8300/atomic.h
index f23d868..d891541 100644
--- a/include/asm-h8300/atomic.h
+++ b/include/asm-h8300/atomic.h
@@ -137,4 +137,5 @@
 #define smp_mb__before_atomic_inc()    barrier()
 #define smp_mb__after_atomic_inc() barrier()
 
+#include <asm-generic/atomic.h>
 #endif /* __ARCH_H8300_ATOMIC __ */
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h
index 5036f59..c0411ec 100644
--- a/include/asm-h8300/bitops.h
+++ b/include/asm-h8300/bitops.h
@@ -406,5 +406,6 @@
 #endif /* __KERNEL__ */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* _H8300_BITOPS_H */
diff --git a/include/asm-h8300/futex.h b/include/asm-h8300/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-h8300/futex.h
+++ b/include/asm-h8300/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-h8300/irq.h b/include/asm-h8300/irq.h
index 5027181..73065f5 100644
--- a/include/asm-h8300/irq.h
+++ b/include/asm-h8300/irq.h
@@ -61,11 +61,6 @@
 
 extern void enable_irq(unsigned int);
 extern void disable_irq(unsigned int);
-
-/*
- * Some drivers want these entry points
- */
-#define enable_irq_nosync(x)	enable_irq(x)
 #define disable_irq_nosync(x)	disable_irq(x)
 
 struct irqaction;
diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h
index 63f727a..744a8fb 100644
--- a/include/asm-h8300/mman.h
+++ b/include/asm-h8300/mman.h
@@ -35,6 +35,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h
index c68557a..7a5472d 100644
--- a/include/asm-i386/atomic.h
+++ b/include/asm-i386/atomic.h
@@ -254,4 +254,5 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif
diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h
index ddf1739..65679ac 100644
--- a/include/asm-i386/bitops.h
+++ b/include/asm-i386/bitops.h
@@ -332,9 +332,9 @@
  * Returns the bit-number of the first set bit, not the number of the byte
  * containing a bit.
  */
-static inline int find_first_bit(const unsigned long *addr, unsigned size)
+static inline unsigned find_first_bit(const unsigned long *addr, unsigned size)
 {
-	int x = 0;
+	unsigned x = 0;
 
 	while (x < size) {
 		unsigned long val = *addr++;
@@ -367,11 +367,7 @@
 	return word;
 }
 
-/*
- * fls: find last bit set.
- */
-
-#define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
@@ -414,6 +410,23 @@
 }
 
 /**
+ * fls - find last bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ */
+static inline int fls(int x)
+{
+	int r;
+
+	__asm__("bsrl %1,%0\n\t"
+		"jnz 1f\n\t"
+		"movl $-1,%0\n"
+		"1:" : "=r" (r) : "rm" (x));
+	return r+1;
+}
+
+/**
  * hweightN - returns the hamming weight of a N-bit word
  * @x: the word to weigh
  *
diff --git a/include/asm-i386/bugs.h b/include/asm-i386/bugs.h
index ea54540..50233e0 100644
--- a/include/asm-i386/bugs.h
+++ b/include/asm-i386/bugs.h
@@ -8,9 +8,6 @@
  *        <rreilova@ececs.uc.edu>
  *	- Channing Corn (tests & fixes),
  *	- Andrew D. Balsa (code cleanup).
- *
- *  Pentium III FXSR, SSE support
- *	Gareth Hughes <gareth@valinux.com>, May 2000
  */
 
 /*
@@ -76,25 +73,7 @@
 		return;
 	}
 
-/* Enable FXSR and company _before_ testing for FP problems. */
-	/*
-	 * Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
-	 */
-	if (offsetof(struct task_struct, thread.i387.fxsave) & 15) {
-		extern void __buggy_fxsr_alignment(void);
-		__buggy_fxsr_alignment();
-	}
-	if (cpu_has_fxsr) {
-		printk(KERN_INFO "Enabling fast FPU save and restore... ");
-		set_in_cr4(X86_CR4_OSFXSR);
-		printk("done.\n");
-	}
-	if (cpu_has_xmm) {
-		printk(KERN_INFO "Enabling unmasked SIMD FPU exception support... ");
-		set_in_cr4(X86_CR4_OSXMMEXCPT);
-		printk("done.\n");
-	}
-
+/* trap_init() enabled FXSR and company _before_ testing for FP problems here. */
 	/* Test for the divl bug.. */
 	__asm__("fninit\n\t"
 		"fldl %1\n\t"
diff --git a/include/asm-i386/cache.h b/include/asm-i386/cache.h
index 8497887..615911e 100644
--- a/include/asm-i386/cache.h
+++ b/include/asm-i386/cache.h
@@ -10,6 +10,4 @@
 #define L1_CACHE_SHIFT	(CONFIG_X86_L1_CACHE_SHIFT)
 #define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
 
-#define L1_CACHE_SHIFT_MAX 7	/* largest L1 which this arch supports */
-
 #endif
diff --git a/include/asm-i386/cacheflush.h b/include/asm-i386/cacheflush.h
index 2ea36de..7199f7b 100644
--- a/include/asm-i386/cacheflush.h
+++ b/include/asm-i386/cacheflush.h
@@ -31,4 +31,8 @@
 void kernel_map_pages(struct page *page, int numpages, int enable);
 #endif
 
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void);
+#endif
+
 #endif /* _I386_CACHEFLUSH_H */
diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h
index 29b851a..494e73b 100644
--- a/include/asm-i386/desc.h
+++ b/include/asm-i386/desc.h
@@ -15,9 +15,6 @@
 #include <asm/mmu.h>
 
 extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
-DECLARE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);
-
-#define get_cpu_gdt_table(_cpu) (per_cpu(cpu_gdt_table,_cpu))
 
 DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
 
@@ -29,6 +26,11 @@
 
 extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
 
+static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
+{
+	return ((struct desc_struct *)cpu_gdt_descr[cpu].address);
+}
+
 #define load_TR_desc() __asm__ __volatile__("ltr %w0"::"q" (GDT_ENTRY_TSS*8))
 #define load_LDT_desc() __asm__ __volatile__("lldt %w0"::"q" (GDT_ENTRY_LDT*8))
 
diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h
index e56c335..6c37a9a 100644
--- a/include/asm-i386/dma-mapping.h
+++ b/include/asm-i386/dma-mapping.h
@@ -150,7 +150,7 @@
 {
 	/* no easy way to get cache size on all x86, so return the
 	 * maximum possible, to be safe */
-	return (1 << L1_CACHE_SHIFT_MAX);
+	return (1 << INTERNODE_CACHE_SHIFT);
 }
 
 #define dma_is_consistent(d)	(1)
diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h
index 270f198..5169d7a 100644
--- a/include/asm-i386/irq.h
+++ b/include/asm-i386/irq.h
@@ -21,8 +21,6 @@
 	return ((irq == 2) ? 9 : irq);
 }
 
-extern void release_vm86_irqs(struct task_struct *);
-
 #ifdef CONFIG_X86_LOCAL_APIC
 # define ARCH_HAS_NMI_WATCHDOG		/* See include/linux/nmi.h */
 #endif
diff --git a/include/asm-i386/mach-bigsmp/mach_apic.h b/include/asm-i386/mach-bigsmp/mach_apic.h
index ba936d4..18b19a7 100644
--- a/include/asm-i386/mach-bigsmp/mach_apic.h
+++ b/include/asm-i386/mach-bigsmp/mach_apic.h
@@ -1,17 +1,10 @@
 #ifndef __ASM_MACH_APIC_H
 #define __ASM_MACH_APIC_H
-#include <asm/smp.h>
 
-#define SEQUENTIAL_APICID
-#ifdef SEQUENTIAL_APICID
-#define xapic_phys_to_log_apicid(phys_apic) ( (1ul << ((phys_apic) & 0x3)) |\
-		((phys_apic<<2) & (~0xf)) )
-#elif CLUSTERED_APICID
-#define xapic_phys_to_log_apicid(phys_apic) ( (1ul << ((phys_apic) & 0x3)) |\
-		((phys_apic) & (~0xf)) )
-#endif
 
-#define NO_BALANCE_IRQ (1)
+extern u8 bios_cpu_apicid[];
+
+#define xapic_phys_to_log_apicid(cpu) (bios_cpu_apicid[cpu])
 #define esr_disable (1)
 
 static inline int apic_id_registered(void)
@@ -19,7 +12,6 @@
 	return (1);
 }
 
-#define APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
 /* Round robin the irqs amoung the online cpus */
 static inline cpumask_t target_cpus(void)
 { 
@@ -32,29 +24,34 @@
 	} while (cpu >= NR_CPUS);
 	return cpumask_of_cpu(cpu);
 }
-#define TARGET_CPUS	(target_cpus())
 
-#define INT_DELIVERY_MODE dest_Fixed
-#define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
+#undef APIC_DEST_LOGICAL
+#define APIC_DEST_LOGICAL 	0
+#define TARGET_CPUS		(target_cpus())
+#define APIC_DFR_VALUE		(APIC_DFR_FLAT)
+#define INT_DELIVERY_MODE	(dest_Fixed)
+#define INT_DEST_MODE		(0)    /* phys delivery to target proc */
+#define NO_BALANCE_IRQ		(0)
+#define WAKE_SECONDARY_VIA_INIT
+
 
 static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
 {
-	return 0;
+	return (0);
 }
 
-/* we don't use the phys_cpu_present_map to indicate apicid presence */
-static inline unsigned long check_apicid_present(int bit) 
+static inline unsigned long check_apicid_present(int bit)
 {
-	return 1;
+	return (1);
 }
 
-#define apicid_cluster(apicid) (apicid & 0xF0)
-
-static inline unsigned long calculate_ldr(unsigned long old)
+static inline unsigned long calculate_ldr(int cpu)
 {
-	unsigned long id;
-	id = xapic_phys_to_log_apicid(hard_smp_processor_id());
-	return ((old & ~APIC_LDR_MASK) | SET_APIC_LOGICAL_ID(id));
+	unsigned long val, id;
+	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
+	id = xapic_phys_to_log_apicid(cpu);
+	val |= SET_APIC_LOGICAL_ID(id);
+	return val;
 }
 
 /*
@@ -67,37 +64,35 @@
 static inline void init_apic_ldr(void)
 {
 	unsigned long val;
+	int cpu = smp_processor_id();
 
 	apic_write_around(APIC_DFR, APIC_DFR_VALUE);
-	val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
-	val = calculate_ldr(val);
+	val = calculate_ldr(cpu);
 	apic_write_around(APIC_LDR, val);
 }
 
 static inline void clustered_apic_check(void)
 {
 	printk("Enabling APIC mode:  %s.  Using %d I/O APICs\n",
-		"Cluster", nr_ioapics);
+		"Physflat", nr_ioapics);
 }
 
 static inline int multi_timer_check(int apic, int irq)
 {
-	return 0;
+	return (0);
 }
 
 static inline int apicid_to_node(int logical_apicid)
 {
-	return 0;
+	return (0);
 }
 
-extern u8 bios_cpu_apicid[];
-
 static inline int cpu_present_to_apicid(int mps_cpu)
 {
 	if (mps_cpu < NR_CPUS)
-		return (int)bios_cpu_apicid[mps_cpu];
-	else
-		return BAD_APICID;
+		return (int) bios_cpu_apicid[mps_cpu];
+
+	return BAD_APICID;
 }
 
 static inline physid_mask_t apicid_to_cpu_present(int phys_apicid)
@@ -109,10 +104,10 @@
 /* Mapping from cpu number to logical apicid */
 static inline int cpu_to_logical_apicid(int cpu)
 {
-       if (cpu >= NR_CPUS)
-	       return BAD_APICID;
-       return (int)cpu_2_logical_apicid[cpu];
- }
+	if (cpu >= NR_CPUS)
+		return BAD_APICID;
+	return cpu_physical_id(cpu);
+}
 
 static inline int mpc_apic_id(struct mpc_config_processor *m,
 			struct mpc_config_translation *translation_record)
@@ -128,11 +123,9 @@
 static inline physid_mask_t ioapic_phys_id_map(physid_mask_t phys_map)
 {
 	/* For clustered we don't have a good way to do this yet - hack */
-	return physids_promote(0xFUL);
+	return physids_promote(0xFFL);
 }
 
-#define WAKE_SECONDARY_VIA_INIT
-
 static inline void setup_portio_remap(void)
 {
 }
diff --git a/include/asm-i386/mach-bigsmp/mach_apicdef.h b/include/asm-i386/mach-bigsmp/mach_apicdef.h
index 23e58b3..a58ab5a 100644
--- a/include/asm-i386/mach-bigsmp/mach_apicdef.h
+++ b/include/asm-i386/mach-bigsmp/mach_apicdef.h
@@ -1,11 +1,11 @@
 #ifndef __ASM_MACH_APICDEF_H
 #define __ASM_MACH_APICDEF_H
 
-#define		APIC_ID_MASK		(0x0F<<24)
+#define		APIC_ID_MASK		(0xFF<<24)
 
 static inline unsigned get_apic_id(unsigned long x) 
 { 
-	return (((x)>>24)&0x0F);
+	return (((x)>>24)&0xFF);
 } 
 
 #define		GET_APIC_ID(x)	get_apic_id(x)
diff --git a/include/asm-i386/mman.h b/include/asm-i386/mman.h
index 196619a..ba4941e 100644
--- a/include/asm-i386/mman.h
+++ b/include/asm-i386/mman.h
@@ -35,6 +35,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
index 620a906..74f595d 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -76,11 +76,6 @@
  * Following are macros that each numa implmentation must define.
  */
 
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-#define kvaddr_to_nid(kaddr)	pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
-
 #define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 #define node_end_pfn(nid)						\
 ({									\
diff --git a/include/asm-i386/module.h b/include/asm-i386/module.h
index eb7f2b4..424661d 100644
--- a/include/asm-i386/module.h
+++ b/include/asm-i386/module.h
@@ -52,8 +52,10 @@
 #define MODULE_PROC_FAMILY "CYRIXIII "
 #elif defined CONFIG_MVIAC3_2
 #define MODULE_PROC_FAMILY "VIAC3-2 "
-#elif CONFIG_MGEODEGX1
+#elif defined CONFIG_MGEODEGX1
 #define MODULE_PROC_FAMILY "GEODEGX1 "
+#elif defined CONFIG_MGEODE_LX
+#define MODULE_PROC_FAMILY "GEODE "
 #else
 #error unknown processor family
 #endif
diff --git a/include/asm-i386/mpspec_def.h b/include/asm-i386/mpspec_def.h
index a961093..76feedf 100644
--- a/include/asm-i386/mpspec_def.h
+++ b/include/asm-i386/mpspec_def.h
@@ -75,7 +75,7 @@
 {
 	unsigned char mpc_type;
 	unsigned char mpc_busid;
-	unsigned char mpc_bustype[6] __attribute((packed));
+	unsigned char mpc_bustype[6];
 };
 
 /* List of Bus Type string values, Intel MP Spec. */
diff --git a/include/asm-i386/param.h b/include/asm-i386/param.h
index fa02e67..095580f 100644
--- a/include/asm-i386/param.h
+++ b/include/asm-i386/param.h
@@ -1,9 +1,8 @@
-#include <linux/config.h>
-
 #ifndef _ASMi386_PARAM_H
 #define _ASMi386_PARAM_H
 
 #ifdef __KERNEL__
+# include <linux/config.h>
 # define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
 # define USER_HZ	100		/* .. some user interfaces are in "ticks" */
 # define CLOCKS_PER_SEC		(USER_HZ)	/* like times() */
diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h
index 7e0f294..f324c53 100644
--- a/include/asm-i386/ptrace.h
+++ b/include/asm-i386/ptrace.h
@@ -54,6 +54,9 @@
 #define PTRACE_GET_THREAD_AREA    25
 #define PTRACE_SET_THREAD_AREA    26
 
+#define PTRACE_SYSEMU		  31
+#define PTRACE_SYSEMU_SINGLESTEP  32
+
 #ifdef __KERNEL__
 
 #include <asm/vm86.h>
diff --git a/include/asm-i386/segment.h b/include/asm-i386/segment.h
index bb5ff5b..faf9953 100644
--- a/include/asm-i386/segment.h
+++ b/include/asm-i386/segment.h
@@ -91,6 +91,20 @@
 #define GDT_ENTRY_BOOT_DS		(GDT_ENTRY_BOOT_CS + 1)
 #define __BOOT_DS	(GDT_ENTRY_BOOT_DS * 8)
 
+/* The PnP BIOS entries in the GDT */
+#define GDT_ENTRY_PNPBIOS_CS32		(GDT_ENTRY_PNPBIOS_BASE + 0)
+#define GDT_ENTRY_PNPBIOS_CS16		(GDT_ENTRY_PNPBIOS_BASE + 1)
+#define GDT_ENTRY_PNPBIOS_DS		(GDT_ENTRY_PNPBIOS_BASE + 2)
+#define GDT_ENTRY_PNPBIOS_TS1		(GDT_ENTRY_PNPBIOS_BASE + 3)
+#define GDT_ENTRY_PNPBIOS_TS2		(GDT_ENTRY_PNPBIOS_BASE + 4)
+
+/* The PnP BIOS selectors */
+#define PNP_CS32   (GDT_ENTRY_PNPBIOS_CS32 * 8)	/* segment for calling fn */
+#define PNP_CS16   (GDT_ENTRY_PNPBIOS_CS16 * 8)	/* code segment for BIOS */
+#define PNP_DS     (GDT_ENTRY_PNPBIOS_DS * 8)	/* data segment for BIOS */
+#define PNP_TS1    (GDT_ENTRY_PNPBIOS_TS1 * 8)	/* transfer data segment */
+#define PNP_TS2    (GDT_ENTRY_PNPBIOS_TS2 * 8)	/* another data segment */
+
 /*
  * The interrupt descriptor table has room for 256 idt's,
  * the global descriptor table is dependent on the number
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h
index 772f85d..9c0593b 100644
--- a/include/asm-i386/system.h
+++ b/include/asm-i386/system.h
@@ -54,23 +54,7 @@
         ); } while(0)
 
 #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , (base) )
-#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1)>>12 )
-
-static inline unsigned long _get_base(char * addr)
-{
-	unsigned long __base;
-	__asm__("movb %3,%%dh\n\t"
-		"movb %2,%%dl\n\t"
-		"shll $16,%%edx\n\t"
-		"movw %1,%%dx"
-		:"=&d" (__base)
-		:"m" (*((addr)+2)),
-		 "m" (*((addr)+4)),
-		 "m" (*((addr)+7)));
-	return __base;
-}
-
-#define get_base(ldt) _get_base( ((char *)&(ldt)) )
+#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , ((limit)-1) )
 
 /*
  * Load a segment. Fall back on loading the zero
@@ -140,6 +124,19 @@
 		:"=r" (__dummy)); \
 	__dummy; \
 })
+
+#define read_cr4_safe() ({			      \
+	unsigned int __dummy;			      \
+	/* This could fault if %cr4 does not exist */ \
+	__asm__("1: movl %%cr4, %0		\n"   \
+		"2:				\n"   \
+		".section __ex_table,\"a\"	\n"   \
+		".long 1b,2b			\n"   \
+		".previous			\n"   \
+		: "=r" (__dummy): "0" (0));	      \
+	__dummy;				      \
+})
+
 #define write_cr4(x) \
 	__asm__ __volatile__("movl %0,%%cr4": :"r" (x));
 #define stts() write_cr0(8 | read_cr0())
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
index 0f92e78..481c3c0 100644
--- a/include/asm-i386/unistd.h
+++ b/include/asm-i386/unistd.h
@@ -256,7 +256,7 @@
 #define __NR_io_submit		248
 #define __NR_io_cancel		249
 #define __NR_fadvise64		250
-#define __NR_set_zone_reclaim	251
+/* 251 is available for reuse (was briefly sys_set_zone_reclaim) */
 #define __NR_exit_group		252
 #define __NR_lookup_dcookie	253
 #define __NR_epoll_create	254
@@ -299,8 +299,9 @@
 #define __NR_inotify_init	291
 #define __NR_inotify_add_watch	292
 #define __NR_inotify_rm_watch	293
+#define __NR_migrate_pages	294
 
-#define NR_syscalls 294
+#define NR_syscalls 295
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
diff --git a/include/asm-i386/vm86.h b/include/asm-i386/vm86.h
index 40ec82c..952fd69 100644
--- a/include/asm-i386/vm86.h
+++ b/include/asm-i386/vm86.h
@@ -16,7 +16,11 @@
 #define IF_MASK		0x00000200
 #define IOPL_MASK	0x00003000
 #define NT_MASK		0x00004000
+#ifdef CONFIG_VM86
 #define VM_MASK		0x00020000
+#else
+#define VM_MASK		0 /* ignored */
+#endif
 #define AC_MASK		0x00040000
 #define VIF_MASK	0x00080000	/* virtual interrupt flag */
 #define VIP_MASK	0x00100000	/* virtual interrupt pending */
@@ -200,9 +204,25 @@
  */
 };
 
+#ifdef CONFIG_VM86
+
 void handle_vm86_fault(struct kernel_vm86_regs *, long);
 int handle_vm86_trap(struct kernel_vm86_regs *, long, int);
 
+struct task_struct;
+void release_vm86_irqs(struct task_struct *);
+
+#else
+
+#define handle_vm86_fault(a, b)
+#define release_vm86_irqs(a)
+
+static inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c) {
+	return 0;
+}
+
+#endif /* CONFIG_VM86 */
+
 #endif /* __KERNEL__ */
 
 #endif
diff --git a/include/asm-ia64/atomic.h b/include/asm-ia64/atomic.h
index 2fbebf8..15cf798 100644
--- a/include/asm-ia64/atomic.h
+++ b/include/asm-ia64/atomic.h
@@ -192,4 +192,5 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif /* _ASM_IA64_ATOMIC_H */
diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h
index 7232528..36d0fb9 100644
--- a/include/asm-ia64/bitops.h
+++ b/include/asm-ia64/bitops.h
@@ -345,6 +345,7 @@
 	x |= x >> 16;
 	return ia64_popcnt(x);
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * ffs: find first bit set. This is defined the same way as the libc and compiler builtin
diff --git a/include/asm-ia64/bug.h b/include/asm-ia64/bug.h
index 3aa0a0a..823616b 100644
--- a/include/asm-ia64/bug.h
+++ b/include/asm-ia64/bug.h
@@ -2,11 +2,7 @@
 #define _ASM_IA64_BUG_H
 
 #ifdef CONFIG_BUG
-#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
-# define ia64_abort()	__builtin_trap()
-#else
-# define ia64_abort()	(*(volatile int *) 0 = 0)
-#endif
+#define ia64_abort()	__builtin_trap()
 #define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); ia64_abort(); } while (0)
 
 /* should this BUG be made generic? */
diff --git a/include/asm-ia64/cache.h b/include/asm-ia64/cache.h
index 666d8f1..40dd2519 100644
--- a/include/asm-ia64/cache.h
+++ b/include/asm-ia64/cache.h
@@ -12,8 +12,6 @@
 #define L1_CACHE_SHIFT		CONFIG_IA64_L1_CACHE_SHIFT
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
-#define L1_CACHE_SHIFT_MAX 7	/* largest L1 which this arch supports */
-
 #ifdef CONFIG_SMP
 # define SMP_CACHE_SHIFT	L1_CACHE_SHIFT
 # define SMP_CACHE_BYTES	L1_CACHE_BYTES
diff --git a/include/asm-ia64/delay.h b/include/asm-ia64/delay.h
index 57182d6..bba7020 100644
--- a/include/asm-ia64/delay.h
+++ b/include/asm-ia64/delay.h
@@ -84,14 +84,6 @@
 	ia64_delay_loop (loops - 1);
 }
 
-static __inline__ void
-udelay (unsigned long usecs)
-{
-	unsigned long start = ia64_get_itc();
-	unsigned long cycles = usecs*local_cpu_data->cyc_per_usec;
-
-	while (ia64_get_itc() - start < cycles)
-		cpu_relax();
-}
+extern void udelay (unsigned long usecs);
 
 #endif /* _ASM_IA64_DELAY_H */
diff --git a/include/asm-ia64/futex.h b/include/asm-ia64/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-ia64/futex.h
+++ b/include/asm-ia64/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-ia64/ia32.h b/include/asm-ia64/ia32.h
index 8e746b2..f8044a1 100644
--- a/include/asm-ia64/ia32.h
+++ b/include/asm-ia64/ia32.h
@@ -13,6 +13,8 @@
 
 # ifdef CONFIG_IA32_SUPPORT
 
+#define IA32_PAGE_OFFSET	0xc0000000
+
 extern void ia32_cpu_init (void);
 extern void ia32_mem_init (void);
 extern void ia32_gdt_init (void);
diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h
index cf772a6..b64fdb9 100644
--- a/include/asm-ia64/io.h
+++ b/include/asm-ia64/io.h
@@ -89,6 +89,7 @@
 
 #define ARCH_HAS_VALID_PHYS_ADDR_RANGE
 extern int valid_phys_addr_range (unsigned long addr, size_t *count); /* efi.c */
+extern int valid_mmap_phys_addr_range (unsigned long addr, size_t *count);
 
 /*
  * The following two macros are deprecated and scheduled for removal.
diff --git a/include/asm-ia64/local.h b/include/asm-ia64/local.h
index 1dbd584..dc51909 100644
--- a/include/asm-ia64/local.h
+++ b/include/asm-ia64/local.h
@@ -17,8 +17,8 @@
 #define local_set(l, i)	atomic64_set(&(l)->val, i)
 #define local_inc(l)	atomic64_inc(&(l)->val)
 #define local_dec(l)	atomic64_dec(&(l)->val)
-#define local_add(l)	atomic64_add(&(l)->val)
-#define local_sub(l)	atomic64_sub(&(l)->val)
+#define local_add(i, l)	atomic64_add((i), &(l)->val)
+#define local_sub(i, l)	atomic64_sub((i), &(l)->val)
 
 /* Non-atomic variants, i.e., preemption disabled and won't be touched in interrupt, etc.  */
 
diff --git a/include/asm-ia64/mman.h b/include/asm-ia64/mman.h
index 1c0a73a..828beb2 100644
--- a/include/asm-ia64/mman.h
+++ b/include/asm-ia64/mman.h
@@ -43,6 +43,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h
index 9dd9da1..5e6362a 100644
--- a/include/asm-ia64/page.h
+++ b/include/asm-ia64/page.h
@@ -110,8 +110,9 @@
 # define pfn_to_page(pfn)	(mem_map + (pfn))
 #elif defined(CONFIG_DISCONTIGMEM)
 extern struct page *vmem_map;
+extern unsigned long min_low_pfn;
 extern unsigned long max_low_pfn;
-# define pfn_valid(pfn)		(((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
+# define pfn_valid(pfn)		(((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn) && ia64_pfn_valid(pfn))
 # define page_to_pfn(page)	((unsigned long) (page - vmem_map))
 # define pfn_to_page(pfn)	(vmem_map + (pfn))
 #endif
diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h
index 29df88bd..313cad0 100644
--- a/include/asm-ia64/sal.h
+++ b/include/asm-ia64/sal.h
@@ -320,7 +320,8 @@
 typedef struct sal_log_record_header {
 	u64 id;				/* Unique monotonically increasing ID */
 	sal_log_revision_t revision;	/* Major and Minor revision of header */
-	u16 severity;			/* Error Severity */
+	u8 severity;			/* Error Severity */
+	u8 validation_bits;		/* 0: platform_guid, 1: !timestamp */
 	u32 len;			/* Length of this error log in bytes */
 	sal_log_timestamp_t timestamp;	/* Timestamp */
 	efi_guid_t platform_guid;	/* Unique OEM Platform ID */
diff --git a/include/asm-ia64/sn/pcidev.h b/include/asm-ia64/sn/pcidev.h
index 49711d0..f65d222 100644
--- a/include/asm-ia64/sn/pcidev.h
+++ b/include/asm-ia64/sn/pcidev.h
@@ -3,15 +3,27 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_PCI_PCIDEV_H
 #define _ASM_IA64_SN_PCI_PCIDEV_H
 
 #include <linux/pci.h>
 
-#define SN_PCIDEV_INFO(pci_dev) \
-        ((struct pcidev_info *)(pci_dev)->sysdata)
+/*
+ * In ia64, pci_dev->sysdata must be a *pci_controller. To provide access to
+ * the pcidev_info structs for all devices under a controller, we extend the
+ * definition of pci_controller, via sn_pci_controller, to include a list
+ * of pcidev_info.
+ */
+struct sn_pci_controller {
+	struct pci_controller pci_controller;
+	struct list_head pcidev_info;
+};
+
+#define SN_PCI_CONTROLLER(dev) ((struct sn_pci_controller *) dev->sysdata)
+
+#define SN_PCIDEV_INFO(dev)	sn_pcidev_info_get(dev)
 
 #define SN_PCIBUS_BUSSOFT_INFO(pci_bus) \
 	(struct pcibus_info *)((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data))
@@ -53,11 +65,13 @@
 	struct sn_irq_info	*pdi_sn_irq_info;
 	struct sn_pcibus_provider *pdi_provider;	/* sn pci ops */
 	struct pci_dev 		*host_pci_dev;		/* host bus link */
+	struct list_head	pdi_list;		/* List of pcidev_info */
 };
 
 extern void sn_irq_fixup(struct pci_dev *pci_dev,
 			 struct sn_irq_info *sn_irq_info);
 extern void sn_irq_unfixup(struct pci_dev *pci_dev);
+extern struct pcidev_info * sn_pcidev_info_get(struct pci_dev *);
 extern void sn_pci_controller_fixup(int segment, int busnum,
  				    struct pci_bus *bus);
 extern void sn_bus_store_sysdata(struct pci_dev *dev);
diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
index 5b78611..9e83210 100644
--- a/include/asm-ia64/spinlock.h
+++ b/include/asm-ia64/spinlock.h
@@ -34,7 +34,7 @@
 {
 	register volatile unsigned int *ptr asm ("r31") = &lock->lock;
 
-#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
 # ifdef CONFIG_ITANIUM
 	/* don't use brl on Itanium... */
 	asm volatile ("{\n\t"
@@ -201,6 +201,16 @@
 
 #endif /* !ASM_SUPPORTED */
 
-#define __raw_read_trylock(lock) generic__raw_read_trylock(lock)
+static inline int __raw_read_trylock(raw_rwlock_t *x)
+{
+	union {
+		raw_rwlock_t lock;
+		__u32 word;
+	} old, new;
+	old.lock = new.lock = *x;
+	old.lock.write_lock = new.lock.write_lock = 0;
+	++new.lock.read_counter;
+	return (u32)ia64_cmpxchg4_acq((__u32 *)(x), new.word, old.word) == old.word;
+}
 
 #endif /*  _ASM_IA64_SPINLOCK_H */
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
index a9f738b..f7c3304 100644
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -38,7 +38,7 @@
 /*
  * Returns the number of the first CPU on Node 'node'.
  */
-#define node_to_first_cpu(node) (__ffs(node_to_cpumask(node)))
+#define node_to_first_cpu(node) (first_cpu(node_to_cpumask(node)))
 
 /*
  * Determines the node for a given pci bus
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
index 6d96a67..962f9bd 100644
--- a/include/asm-ia64/unistd.h
+++ b/include/asm-ia64/unistd.h
@@ -265,16 +265,17 @@
 #define __NR_keyctl			1273
 #define __NR_ioprio_set			1274
 #define __NR_ioprio_get			1275
-#define __NR_set_zone_reclaim		1276
+/* 1276 is available for reuse (was briefly sys_set_zone_reclaim) */
 #define __NR_inotify_init		1277
 #define __NR_inotify_add_watch		1278
 #define __NR_inotify_rm_watch		1279
+#define __NR_migrate_pages		1280
 
 #ifdef __KERNEL__
 
 #include <linux/config.h>
 
-#define NR_syscalls			256 /* length of syscall table */
+#define NR_syscalls			270 /* length of syscall table */
 
 #define __ARCH_WANT_SYS_RT_SIGACTION
 
diff --git a/include/asm-m32r/assembler.h b/include/asm-m32r/assembler.h
index e1dff9d..b7f4d8a 100644
--- a/include/asm-m32r/assembler.h
+++ b/include/asm-m32r/assembler.h
@@ -52,7 +52,7 @@
 	or3	\reg, \reg, #low(\x)
 	.endm
 
-#if !defined(CONFIG_CHIP_M32102)
+#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
 #define STI(reg) STI_M reg
 	.macro STI_M reg
 	setpsw  #0x40	    ->	nop
@@ -64,7 +64,7 @@
 	clrpsw  #0x40	    ->	nop
 	; WORKAROUND: "-> nop" is a workaround for the M32700(TS1).
 	.endm
-#else	/* CONFIG_CHIP_M32102 */
+#else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
 #define STI(reg) STI_M reg
 	.macro STI_M reg
 	mvfc	\reg, psw
@@ -191,12 +191,12 @@
 	and  \reg, sp
 	.endm
 
-#if !defined(CONFIG_CHIP_M32102)
+#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
 	.macro	SWITCH_TO_KERNEL_STACK
 	; switch to kernel stack (spi)
 	clrpsw	#0x80	    ->	nop
 	.endm
-#else	/* CONFIG_CHIP_M32102 */
+#else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
 	.macro	SWITCH_TO_KERNEL_STACK
 	push	r0		; save r0 for working
 	mvfc	r0, psw
@@ -218,7 +218,7 @@
 	.fillinsn
 2:
 	.endm
-#endif	/* CONFIG_CHIP_M32102 */
+#endif	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
 
 #endif	/* __ASSEMBLY__ */
 
diff --git a/include/asm-m32r/atomic.h b/include/asm-m32r/atomic.h
index bfff69a..7076127 100644
--- a/include/asm-m32r/atomic.h
+++ b/include/asm-m32r/atomic.h
@@ -242,6 +242,27 @@
  */
 #define atomic_add_negative(i,v) (atomic_add_return((i), (v)) < 0)
 
+#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n)))
+
+/**
+ * atomic_add_unless - add unless the number is a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as it was not @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+#define atomic_add_unless(v, a, u)				\
+({								\
+	int c, old;						\
+	c = atomic_read(v);					\
+	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
+		c = old;					\
+	c != (u);						\
+})
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 static __inline__ void atomic_clear_mask(unsigned long  mask, atomic_t *addr)
 {
 	unsigned long flags;
@@ -292,4 +313,5 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif	/* _ASM_M32R_ATOMIC_H */
diff --git a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h
index e784439..abea2fd 100644
--- a/include/asm-m32r/bitops.h
+++ b/include/asm-m32r/bitops.h
@@ -465,6 +465,7 @@
  * fls: find last bit set.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-m32r/cache.h b/include/asm-m32r/cache.h
index 7248205..9c2b2d9 100644
--- a/include/asm-m32r/cache.h
+++ b/include/asm-m32r/cache.h
@@ -7,6 +7,4 @@
 #define L1_CACHE_SHIFT		4
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
-#define L1_CACHE_SHIFT_MAX	4
-
 #endif  /* _ASM_M32R_CACHE_H */
diff --git a/include/asm-m32r/cacheflush.h b/include/asm-m32r/cacheflush.h
index 46fc4c3..e57427b 100644
--- a/include/asm-m32r/cacheflush.h
+++ b/include/asm-m32r/cacheflush.h
@@ -7,7 +7,7 @@
 extern void _flush_cache_all(void);
 extern void _flush_cache_copyback_all(void);
 
-#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP)
+#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
 #define flush_cache_all()			do { } while (0)
 #define flush_cache_mm(mm)			do { } while (0)
 #define flush_cache_range(vma, start, end)	do { } while (0)
diff --git a/include/asm-m32r/futex.h b/include/asm-m32r/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-m32r/futex.h
+++ b/include/asm-m32r/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-m32r/ide.h b/include/asm-m32r/ide.h
index 194393b..f7aa969 100644
--- a/include/asm-m32r/ide.h
+++ b/include/asm-m32r/ide.h
@@ -25,20 +25,23 @@
 # endif
 #endif
 
-#if defined(CONFIG_PLAT_M32700UT)
-#include <asm/irq.h>
-#include <asm/m32700ut/m32700ut_pld.h>
-#endif
+#include <asm/m32r.h>
+
 
 #define IDE_ARCH_OBSOLETE_DEFAULTS
 
 static __inline__ int ide_default_irq(unsigned long base)
 {
 	switch (base) {
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2)
 		case 0x1f0: return PLD_IRQ_CFIREQ;
 		default:
 			return 0;
+#elif defined(CONFIG_PLAT_MAPPI3)
+		case 0x1f0: return PLD_IRQ_CFIREQ;
+		case 0x170: return PLD_IRQ_IDEIREQ;
+		default:
+			return 0;
 #else
 		case 0x1f0: return 14;
 		case 0x170: return 15;
diff --git a/include/asm-m32r/irq.h b/include/asm-m32r/irq.h
index 8ed7796..ca94395 100644
--- a/include/asm-m32r/irq.h
+++ b/include/asm-m32r/irq.h
@@ -65,6 +65,22 @@
 #define NR_IRQS \
 	(OPSPUT_NUM_CPU_IRQ + OPSPUT_NUM_PLD_IRQ \
 	+ OPSPUT_NUM_LCD_PLD_IRQ + OPSPUT_NUM_LAN_PLD_IRQ)
+
+#elif defined(CONFIG_PLAT_M32104UT)
+/*
+ * IRQ definitions for M32104UT
+ *  M32104 Chip: 64 interrupts
+ *  ICU of M32104UT-on-board PLD: 32 interrupts cascaded to INT1# chip pin
+ */
+#define	M32104UT_NUM_CPU_IRQ	(64)
+#define M32104UT_NUM_PLD_IRQ	(32)
+#define M32104UT_IRQ_BASE	0
+#define M32104UT_CPU_IRQ_BASE	M32104UT_IRQ_BASE
+#define M32104UT_PLD_IRQ_BASE	(M32104UT_CPU_IRQ_BASE + M32104UT_NUM_CPU_IRQ)
+
+#define NR_IRQS	\
+    (M32104UT_NUM_CPU_IRQ + M32104UT_NUM_PLD_IRQ)
+
 #else
 #define NR_IRQS	64
 #endif
diff --git a/include/asm-m32r/m32102.h b/include/asm-m32r/m32102.h
index cb98101..a1f0d1f 100644
--- a/include/asm-m32r/m32102.h
+++ b/include/asm-m32r/m32102.h
@@ -11,7 +11,11 @@
 /*======================================================================*
  * Special Function Register
  *======================================================================*/
+#if !defined(CONFIG_CHIP_M32104)
 #define M32R_SFR_OFFSET  (0x00E00000)  /* 0x00E00000-0x00EFFFFF 1[MB] */
+#else
+#define M32R_SFR_OFFSET  (0x00700000)  /* 0x00700000-0x007FFFFF 1[MB] */
+#endif
 
 /*
  * Clock and Power Management registers.
@@ -100,7 +104,7 @@
 #define M32R_MFT5RLD_PORTL     (0x0C+M32R_MFT5_OFFSET)  /* MFT4 reload */
 #define M32R_MFT5CMPRLD_PORTL  (0x10+M32R_MFT5_OFFSET)  /* MFT4 compare reload */
 
-#ifdef CONFIG_CHIP_M32700
+#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32104)
 #define M32R_MFTCR_MFT0MSK  (1UL<<31)  /* b0 */
 #define M32R_MFTCR_MFT1MSK  (1UL<<30)  /* b1 */
 #define M32R_MFTCR_MFT2MSK  (1UL<<29)  /* b2 */
@@ -113,7 +117,7 @@
 #define M32R_MFTCR_MFT3EN   (1UL<<20)  /* b11 */
 #define M32R_MFTCR_MFT4EN   (1UL<<19)  /* b12 */
 #define M32R_MFTCR_MFT5EN   (1UL<<18)  /* b13 */
-#else	/* not CONFIG_CHIP_M32700 */
+#else	/* not CONFIG_CHIP_M32700 && not CONFIG_CHIP_M32104 */
 #define M32R_MFTCR_MFT0MSK  (1UL<<15)  /* b16 */
 #define M32R_MFTCR_MFT1MSK  (1UL<<14)  /* b17 */
 #define M32R_MFTCR_MFT2MSK  (1UL<<13)  /* b18 */
@@ -126,7 +130,7 @@
 #define M32R_MFTCR_MFT3EN   (1UL<<4)   /* b27 */
 #define M32R_MFTCR_MFT4EN   (1UL<<3)   /* b28 */
 #define M32R_MFTCR_MFT5EN   (1UL<<2)   /* b29 */
-#endif	/* not CONFIG_CHIP_M32700 */
+#endif	/* not CONFIG_CHIP_M32700 && not CONFIG_CHIP_M32104 */
 
 #define M32R_MFTMOD_CC_MASK    (1UL<<15)  /* b16 */
 #define M32R_MFTMOD_TCCR       (1UL<<13)  /* b18 */
@@ -241,8 +245,24 @@
 #define M32R_IRQ_MFT1    (17)  /* MFT1 */
 #define M32R_IRQ_MFT2    (18)  /* MFT2 */
 #define M32R_IRQ_MFT3    (19)  /* MFT3 */
-#define M32R_IRQ_MFT4    (20)  /* MFT4 */
-#define M32R_IRQ_MFT5    (21)  /* MFT5 */
+#ifdef CONFIG_CHIP_M32104
+#define M32R_IRQ_MFTX0   (24)  /* MFTX0 */
+#define M32R_IRQ_MFTX1   (25)  /* MFTX1 */
+#define M32R_IRQ_DMA0    (32)  /* DMA0 */
+#define M32R_IRQ_DMA1    (33)  /* DMA1 */
+#define M32R_IRQ_DMA2    (34)  /* DMA2 */
+#define M32R_IRQ_DMA3    (35)  /* DMA3 */
+#define M32R_IRQ_SIO0_R  (40)  /* SIO0 send    */
+#define M32R_IRQ_SIO0_S  (41)  /* SIO0 receive */
+#define M32R_IRQ_SIO1_R  (42)  /* SIO1 send    */
+#define M32R_IRQ_SIO1_S  (43)  /* SIO1 receive */
+#define M32R_IRQ_SIO2_R  (44)  /* SIO2 send    */
+#define M32R_IRQ_SIO2_S  (45)  /* SIO2 receive */
+#define M32R_IRQ_SIO3_R  (46)  /* SIO3 send    */
+#define M32R_IRQ_SIO3_S  (47)  /* SIO3 receive */
+#define M32R_IRQ_ADC     (56)  /* ADC */
+#define M32R_IRQ_PC      (57)  /* PC */
+#else /* ! M32104 */
 #define M32R_IRQ_DMA0    (32)  /* DMA0 */
 #define M32R_IRQ_DMA1    (33)  /* DMA1 */
 #define M32R_IRQ_SIO0_R  (48)  /* SIO0 send    */
@@ -255,6 +275,7 @@
 #define M32R_IRQ_SIO3_S  (55)  /* SIO3 receive */
 #define M32R_IRQ_SIO4_R  (56)  /* SIO4 send    */
 #define M32R_IRQ_SIO4_S  (57)  /* SIO4 receive */
+#endif /* ! M32104 */
 
 #ifdef CONFIG_SMP
 #define M32R_IRQ_IPI0    (56)
@@ -281,15 +302,12 @@
 #define M32R_FPGA_VERSION0_PORTL    (0x30+M32R_FPGA_TOP)
 #define M32R_FPGA_VERSION1_PORTL    (0x34+M32R_FPGA_TOP)
 
+#endif /* CONFIG_SMP */
+
 #ifndef __ASSEMBLY__
-/* For NETDEV WATCHDOG */
 typedef struct {
 	unsigned long icucr;	/* ICU Control Register */
 } icu_data_t;
-
-extern icu_data_t icu_data[];
 #endif
 
-#endif /* CONFIG_SMP */
-
 #endif /* _M32102_H_ */
diff --git a/include/asm-m32r/m32104ut/m32104ut_pld.h b/include/asm-m32r/m32104ut/m32104ut_pld.h
new file mode 100644
index 0000000..a4eac20
--- /dev/null
+++ b/include/asm-m32r/m32104ut/m32104ut_pld.h
@@ -0,0 +1,163 @@
+/*
+ * include/asm/m32104ut/m32104ut_pld.h
+ *
+ * Definitions for Programable Logic Device(PLD) on M32104UT board.
+ * Based on m32700ut_pld.h
+ *
+ * Copyright (c) 2002	Takeo Takahashi
+ * Copyright (c) 2005	Naoto Sugai
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file "COPYING" in the main directory of
+ * this archive for more details.
+ */
+
+#ifndef _M32104UT_M32104UT_PLD_H
+#define _M32104UT_M32104UT_PLD_H
+
+#include <linux/config.h>
+
+#if defined(CONFIG_PLAT_M32104UT)
+#define PLD_PLAT_BASE		0x02c00000
+#else
+#error "no platform configuration"
+#endif
+
+#ifndef __ASSEMBLY__
+/*
+ * C functions use non-cache address.
+ */
+#define PLD_BASE		(PLD_PLAT_BASE /* + NONCACHE_OFFSET */)
+#define __reg8			(volatile unsigned char *)
+#define __reg16			(volatile unsigned short *)
+#define __reg32			(volatile unsigned int *)
+#else
+#define PLD_BASE		(PLD_PLAT_BASE + NONCACHE_OFFSET)
+#define __reg8
+#define __reg16
+#define __reg32
+#endif	/* __ASSEMBLY__ */
+
+/* CFC */
+#define	PLD_CFRSTCR		__reg16(PLD_BASE + 0x0000)
+#define PLD_CFSTS		__reg16(PLD_BASE + 0x0002)
+#define PLD_CFIMASK		__reg16(PLD_BASE + 0x0004)
+#define PLD_CFBUFCR		__reg16(PLD_BASE + 0x0006)
+
+/* MMC */
+#define PLD_MMCCR		__reg16(PLD_BASE + 0x4000)
+#define PLD_MMCMOD		__reg16(PLD_BASE + 0x4002)
+#define PLD_MMCSTS		__reg16(PLD_BASE + 0x4006)
+#define PLD_MMCBAUR		__reg16(PLD_BASE + 0x400a)
+#define PLD_MMCCMDBCUT		__reg16(PLD_BASE + 0x400c)
+#define PLD_MMCCDTBCUT		__reg16(PLD_BASE + 0x400e)
+#define PLD_MMCDET		__reg16(PLD_BASE + 0x4010)
+#define PLD_MMCWP		__reg16(PLD_BASE + 0x4012)
+#define PLD_MMCWDATA		__reg16(PLD_BASE + 0x5000)
+#define PLD_MMCRDATA		__reg16(PLD_BASE + 0x6000)
+#define PLD_MMCCMDDATA		__reg16(PLD_BASE + 0x7000)
+#define PLD_MMCRSPDATA		__reg16(PLD_BASE + 0x7006)
+
+/* ICU
+ *  ICUISTS:	status register
+ *  ICUIREQ0: 	request register
+ *  ICUIREQ1: 	request register
+ *  ICUCR3:	control register for CFIREQ# interrupt
+ *  ICUCR4:	control register for CFC Card insert interrupt
+ *  ICUCR5:	control register for CFC Card eject interrupt
+ *  ICUCR6:	control register for external interrupt
+ *  ICUCR11:	control register for MMC Card insert/eject interrupt
+ *  ICUCR13:	control register for SC error interrupt
+ *  ICUCR14:	control register for SC receive interrupt
+ *  ICUCR15:	control register for SC send interrupt
+ */
+
+#define PLD_IRQ_INT0		(M32104UT_PLD_IRQ_BASE + 0)	/* None */
+#define PLD_IRQ_CFIREQ		(M32104UT_PLD_IRQ_BASE + 3)	/* CF IREQ */
+#define PLD_IRQ_CFC_INSERT	(M32104UT_PLD_IRQ_BASE + 4)	/* CF Insert */
+#define PLD_IRQ_CFC_EJECT	(M32104UT_PLD_IRQ_BASE + 5)	/* CF Eject */
+#define PLD_IRQ_EXINT		(M32104UT_PLD_IRQ_BASE + 6)	/* EXINT */
+#define PLD_IRQ_MMCCARD		(M32104UT_PLD_IRQ_BASE + 11)	/* MMC Insert/Eject */
+#define PLD_IRQ_SC_ERROR	(M32104UT_PLD_IRQ_BASE + 13)	/* SC error */
+#define PLD_IRQ_SC_RCV		(M32104UT_PLD_IRQ_BASE + 14)	/* SC receive */
+#define PLD_IRQ_SC_SND		(M32104UT_PLD_IRQ_BASE + 15)	/* SC send */
+
+#define PLD_ICUISTS		__reg16(PLD_BASE + 0x8002)
+#define PLD_ICUISTS_VECB_MASK	(0xf000)
+#define PLD_ICUISTS_VECB(x)	((x) & PLD_ICUISTS_VECB_MASK)
+#define PLD_ICUISTS_ISN_MASK	(0x07c0)
+#define PLD_ICUISTS_ISN(x)	((x) & PLD_ICUISTS_ISN_MASK)
+#define PLD_ICUCR3		__reg16(PLD_BASE + 0x8104)
+#define PLD_ICUCR4		__reg16(PLD_BASE + 0x8106)
+#define PLD_ICUCR5		__reg16(PLD_BASE + 0x8108)
+#define PLD_ICUCR6		__reg16(PLD_BASE + 0x810a)
+#define PLD_ICUCR11		__reg16(PLD_BASE + 0x8114)
+#define PLD_ICUCR13		__reg16(PLD_BASE + 0x8118)
+#define PLD_ICUCR14		__reg16(PLD_BASE + 0x811a)
+#define PLD_ICUCR15		__reg16(PLD_BASE + 0x811c)
+#define PLD_ICUCR_IEN		(0x1000)
+#define PLD_ICUCR_IREQ		(0x0100)
+#define PLD_ICUCR_ISMOD00	(0x0000)	/* Low edge */
+#define PLD_ICUCR_ISMOD01	(0x0010)	/* Low level */
+#define PLD_ICUCR_ISMOD02	(0x0020)	/* High edge */
+#define PLD_ICUCR_ISMOD03	(0x0030)	/* High level */
+#define PLD_ICUCR_ILEVEL0	(0x0000)
+#define PLD_ICUCR_ILEVEL1	(0x0001)
+#define PLD_ICUCR_ILEVEL2	(0x0002)
+#define PLD_ICUCR_ILEVEL3	(0x0003)
+#define PLD_ICUCR_ILEVEL4	(0x0004)
+#define PLD_ICUCR_ILEVEL5	(0x0005)
+#define PLD_ICUCR_ILEVEL6	(0x0006)
+#define PLD_ICUCR_ILEVEL7	(0x0007)
+
+/* Power Control of MMC and CF */
+#define PLD_CPCR		__reg16(PLD_BASE + 0x14000)
+#define PLD_CPCR_CDP		0x0001
+
+/* LED Control
+ *
+ * 1: DIP swich side
+ * 2: Reset switch side
+ */
+#define PLD_IOLEDCR		__reg16(PLD_BASE + 0x14002)
+#define PLD_IOLED_1_ON		0x001
+#define PLD_IOLED_1_OFF		0x000
+#define PLD_IOLED_2_ON		0x002
+#define PLD_IOLED_2_OFF		0x000
+
+/* DIP Switch
+ *  0: Write-protect of Flash Memory (0:protected, 1:non-protected)
+ *  1: -
+ *  2: -
+ *  3: -
+ */
+#define PLD_IOSWSTS		__reg16(PLD_BASE + 0x14004)
+#define	PLD_IOSWSTS_IOSW2	0x0200
+#define	PLD_IOSWSTS_IOSW1	0x0100
+#define	PLD_IOSWSTS_IOWP0	0x0001
+
+/* CRC */
+#define PLD_CRC7DATA		__reg16(PLD_BASE + 0x18000)
+#define PLD_CRC7INDATA		__reg16(PLD_BASE + 0x18002)
+#define PLD_CRC16DATA		__reg16(PLD_BASE + 0x18004)
+#define PLD_CRC16INDATA		__reg16(PLD_BASE + 0x18006)
+#define PLD_CRC16ADATA		__reg16(PLD_BASE + 0x18008)
+#define PLD_CRC16AINDATA	__reg16(PLD_BASE + 0x1800a)
+
+/* RTC */
+#define PLD_RTCCR		__reg16(PLD_BASE + 0x1c000)
+#define PLD_RTCBAUR		__reg16(PLD_BASE + 0x1c002)
+#define PLD_RTCWRDATA		__reg16(PLD_BASE + 0x1c004)
+#define PLD_RTCRDDATA		__reg16(PLD_BASE + 0x1c006)
+#define PLD_RTCRSTODT		__reg16(PLD_BASE + 0x1c008)
+
+/* SIM Card */
+#define PLD_SCCR		__reg16(PLD_BASE + 0x38000)
+#define PLD_SCMOD		__reg16(PLD_BASE + 0x38004)
+#define PLD_SCSTS		__reg16(PLD_BASE + 0x38006)
+#define PLD_SCINTCR		__reg16(PLD_BASE + 0x38008)
+#define PLD_SCBAUR		__reg16(PLD_BASE + 0x3800a)
+#define PLD_SCTXB		__reg16(PLD_BASE + 0x3800c)
+#define PLD_SCRXB		__reg16(PLD_BASE + 0x3800e)
+
+#endif	/* _M32104UT_M32104UT_PLD_H */
diff --git a/include/asm-m32r/m32r.h b/include/asm-m32r/m32r.h
index ec142be..b133ca6 100644
--- a/include/asm-m32r/m32r.h
+++ b/include/asm-m32r/m32r.h
@@ -14,7 +14,7 @@
 #include <asm/m32r_mp_fpga.h>
 #elif defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2) \
 	|| defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
-        || defined(CONFIG_CHIP_OPSP)
+        || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
 #include <asm/m32102.h>
 #endif
 
@@ -43,6 +43,10 @@
 #include <asm/m32700ut/m32700ut_pld.h>
 #endif
 
+#if defined(CONFIG_PLAT_M32104UT)
+#include <asm/m32104ut/m32104ut_pld.h>
+#endif  /* CONFIG_PLAT_M32104 */
+
 /*
  * M32R Register
  */
@@ -122,7 +126,7 @@
 
 #include <asm/page.h>
 #ifdef CONFIG_MMU
-#define NONCACHE_OFFSET  __PAGE_OFFSET+0x20000000
+#define NONCACHE_OFFSET  (__PAGE_OFFSET + 0x20000000)
 #else
 #define NONCACHE_OFFSET  __PAGE_OFFSET
 #endif /* CONFIG_MMU */
diff --git a/include/asm-m32r/mappi3/mappi3_pld.h b/include/asm-m32r/mappi3/mappi3_pld.h
index 3f1551f..1d3c25d 100644
--- a/include/asm-m32r/mappi3/mappi3_pld.h
+++ b/include/asm-m32r/mappi3/mappi3_pld.h
@@ -59,7 +59,7 @@
 #define  M32R_IRQ_I2C          (28)  /* I2C-BUS     */
 #define  PLD_IRQ_CFIREQ       (6)  /* INT5 CFC Card Interrupt */
 #define  PLD_IRQ_CFC_INSERT   (7)  /* INT6 CFC Card Insert */
-#define  PLD_IRQ_CFC_EJECT    (8)  /* INT7 CFC Card Eject */
+#define  PLD_IRQ_IDEIREQ      (8)  /* INT7 IDE Interrupt   */
 #define  PLD_IRQ_MMCCARD      (43)  /* MMC Card Insert */
 #define  PLD_IRQ_MMCIRQ       (44)  /* MMC Transfer Done */
 
diff --git a/include/asm-m32r/mman.h b/include/asm-m32r/mman.h
index 011f6d9..12e2974 100644
--- a/include/asm-m32r/mman.h
+++ b/include/asm-m32r/mman.h
@@ -37,6 +37,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h
index 73348c3..dcf619a 100644
--- a/include/asm-m32r/system.h
+++ b/include/asm-m32r/system.h
@@ -11,6 +11,7 @@
  */
 
 #include <linux/config.h>
+#include <asm/assembler.h>
 
 #ifdef __KERNEL__
 
@@ -68,12 +69,12 @@
 } while(0)
 
 /* Interrupt Control */
-#if !defined(CONFIG_CHIP_M32102)
+#if !defined(CONFIG_CHIP_M32102) && !defined(CONFIG_CHIP_M32104)
 #define local_irq_enable() \
 	__asm__ __volatile__ ("setpsw #0x40 -> nop": : :"memory")
 #define local_irq_disable() \
 	__asm__ __volatile__ ("clrpsw #0x40 -> nop": : :"memory")
-#else	/* CONFIG_CHIP_M32102 */
+#else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
 static inline void local_irq_enable(void)
 {
 	unsigned long tmpreg;
@@ -95,7 +96,7 @@
 		"mvtc	%0, psw	\n\t"
 	: "=&r" (tmpreg0), "=&r" (tmpreg1) : : "cbit", "memory");
 }
-#endif	/* CONFIG_CHIP_M32102 */
+#endif	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
 
 #define local_save_flags(x) \
 	__asm__ __volatile__("mvfc %0,psw" : "=r"(x) : /* no input */)
@@ -104,13 +105,13 @@
 	__asm__ __volatile__("mvtc %0,psw" : /* no outputs */ \
 		: "r" (x) : "cbit", "memory")
 
-#if !defined(CONFIG_CHIP_M32102)
+#if !(defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_M32104))
 #define local_irq_save(x)				\
 	__asm__ __volatile__(				\
   		"mvfc	%0, psw;		\n\t"	\
 	  	"clrpsw	#0x40 -> nop;		\n\t"	\
   		: "=r" (x) : /* no input */ : "memory")
-#else	/* CONFIG_CHIP_M32102 */
+#else	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
 #define local_irq_save(x) 				\
 	({						\
 		unsigned long tmpreg;			\
@@ -123,7 +124,7 @@
 			: "=r" (x), "=&r" (tmpreg)	\
 			: : "cbit", "memory");		\
 	})
-#endif	/* CONFIG_CHIP_M32102 */
+#endif	/* CONFIG_CHIP_M32102 || CONFIG_CHIP_M32104 */
 
 #define irqs_disabled()					\
 	({						\
@@ -132,8 +133,6 @@
 		!(flags & 0x40);			\
 	})
 
-#endif  /* __KERNEL__ */
-
 #define nop()	__asm__ __volatile__ ("nop" : : )
 
 #define xchg(ptr,x) \
@@ -213,6 +212,67 @@
 	return (tmp);
 }
 
+#define __HAVE_ARCH_CMPXCHG	1
+
+static __inline__ unsigned long
+__cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
+{
+	unsigned long flags;
+	unsigned int retval;
+
+	local_irq_save(flags);
+	__asm__ __volatile__ (
+			DCACHE_CLEAR("%0", "r4", "%1")
+			M32R_LOCK" %0, @%1;	\n"
+		"	bne	%0, %2, 1f;	\n"
+			M32R_UNLOCK" %3, @%1;	\n"
+		"	bra	2f;		\n"
+                "       .fillinsn		\n"
+		"1:"
+			M32R_UNLOCK" %2, @%1;	\n"
+                "       .fillinsn		\n"
+		"2:"
+			: "=&r" (retval)
+			: "r" (p), "r" (old), "r" (new)
+			: "cbit", "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+			, "r4"
+#endif  /* CONFIG_CHIP_M32700_TS1 */
+		);
+	local_irq_restore(flags);
+
+	return retval;
+}
+
+/* This function doesn't exist, so you'll get a linker error
+   if something tries to do an invalid cmpxchg().  */
+extern void __cmpxchg_called_with_bad_pointer(void);
+
+static __inline__ unsigned long
+__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
+{
+	switch (size) {
+	case 4:
+		return __cmpxchg_u32(ptr, old, new);
+#if 0	/* we don't have __cmpxchg_u64 */
+	case 8:
+		return __cmpxchg_u64(ptr, old, new);
+#endif /* 0 */
+	}
+	__cmpxchg_called_with_bad_pointer();
+	return old;
+}
+
+#define cmpxchg(ptr,o,n)						 \
+  ({									 \
+     __typeof__(*(ptr)) _o_ = (o);					 \
+     __typeof__(*(ptr)) _n_ = (n);					 \
+     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		 \
+				    (unsigned long)_n_, sizeof(*(ptr))); \
+  })
+
+#endif  /* __KERNEL__ */
+
 /*
  * Memory barrier.
  *
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
index ac399e1..39be87c 100644
--- a/include/asm-m32r/unistd.h
+++ b/include/asm-m32r/unistd.h
@@ -319,7 +319,7 @@
 register long __scno __asm__ ("r7") = __NR_##name; \
 register long __res __asm__("r0"); \
 __asm__ __volatile__ (\
-	"trap #" SYSCALL_VECTOR \
+	"trap #" SYSCALL_VECTOR "|| nop"\
 	: "=r" (__res) \
 	: "r" (__scno) \
 	: "memory"); \
@@ -332,7 +332,7 @@
 register long __scno __asm__ ("r7") = __NR_##name; \
 register long __res __asm__ ("r0") = (long)(arg1); \
 __asm__ __volatile__ (\
-	"trap #" SYSCALL_VECTOR \
+	"trap #" SYSCALL_VECTOR "|| nop"\
 	: "=r" (__res) \
 	: "r" (__scno), "0" (__res) \
 	: "memory"); \
@@ -346,7 +346,7 @@
 register long __arg2 __asm__ ("r1") = (long)(arg2); \
 register long __res __asm__ ("r0") = (long)(arg1); \
 __asm__ __volatile__ (\
-	"trap #" SYSCALL_VECTOR \
+	"trap #" SYSCALL_VECTOR "|| nop"\
 	: "=r" (__res) \
 	: "r" (__scno), "0" (__res), "r" (__arg2) \
 	: "memory"); \
@@ -361,7 +361,7 @@
 register long __arg2 __asm__ ("r1") = (long)(arg2); \
 register long __res __asm__ ("r0") = (long)(arg1); \
 __asm__ __volatile__ (\
-	"trap #" SYSCALL_VECTOR \
+	"trap #" SYSCALL_VECTOR "|| nop"\
 	: "=r" (__res) \
 	: "r" (__scno), "0" (__res), "r" (__arg2), \
 		"r" (__arg3) \
@@ -378,7 +378,7 @@
 register long __arg2 __asm__ ("r1") = (long)(arg2); \
 register long __res __asm__ ("r0") = (long)(arg1); \
 __asm__ __volatile__ (\
-	"trap #" SYSCALL_VECTOR \
+	"trap #" SYSCALL_VECTOR "|| nop"\
 	: "=r" (__res) \
 	: "r" (__scno), "0" (__res), "r" (__arg2), \
 		"r" (__arg3), "r" (__arg4) \
@@ -397,7 +397,7 @@
 register long __arg2 __asm__ ("r1") = (long)(arg2); \
 register long __res __asm__ ("r0") = (long)(arg1); \
 __asm__ __volatile__ (\
-	"trap #" SYSCALL_VECTOR \
+	"trap #" SYSCALL_VECTOR "|| nop"\
 	: "=r" (__res) \
 	: "r" (__scno), "0" (__res), "r" (__arg2), \
 		"r" (__arg3), "r" (__arg4), "r" (__arg5) \
diff --git a/include/asm-m68k/atomic.h b/include/asm-m68k/atomic.h
index e3c962e..b8a4e75 100644
--- a/include/asm-m68k/atomic.h
+++ b/include/asm-m68k/atomic.h
@@ -157,4 +157,5 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif /* __ARCH_M68K_ATOMIC __ */
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
index b1bcf7c66..13f4c00 100644
--- a/include/asm-m68k/bitops.h
+++ b/include/asm-m68k/bitops.h
@@ -310,6 +310,7 @@
 
 	return 32 - cnt;
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * Every architecture must define this function. It's the fastest
diff --git a/include/asm-m68k/cache.h b/include/asm-m68k/cache.h
index 6161fd3..fed3fd3 100644
--- a/include/asm-m68k/cache.h
+++ b/include/asm-m68k/cache.h
@@ -8,6 +8,4 @@
 #define        L1_CACHE_SHIFT  4
 #define        L1_CACHE_BYTES  (1<< L1_CACHE_SHIFT)
 
-#define L1_CACHE_SHIFT_MAX 4	/* largest L1 which this arch supports */
-
 #endif
diff --git a/include/asm-m68k/futex.h b/include/asm-m68k/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-m68k/futex.h
+++ b/include/asm-m68k/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-m68k/irq.h b/include/asm-m68k/irq.h
index 1f56990..127ad19 100644
--- a/include/asm-m68k/irq.h
+++ b/include/asm-m68k/irq.h
@@ -70,8 +70,6 @@
 
 extern void (*enable_irq)(unsigned int);
 extern void (*disable_irq)(unsigned int);
-
-#define disable_irq_nosync	disable_irq
 #define enable_irq_nosync	enable_irq
 
 struct pt_regs;
diff --git a/include/asm-m68k/mman.h b/include/asm-m68k/mman.h
index f831c4e..ea262ab 100644
--- a/include/asm-m68k/mman.h
+++ b/include/asm-m68k/mman.h
@@ -35,6 +35,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-m68knommu/atomic.h b/include/asm-m68knommu/atomic.h
index 3c1cc15..1702dbe 100644
--- a/include/asm-m68knommu/atomic.h
+++ b/include/asm-m68knommu/atomic.h
@@ -143,4 +143,5 @@
 #define atomic_dec_return(v) atomic_sub_return(1,(v))
 #define atomic_inc_return(v) atomic_add_return(1,(v))
 
+#include <asm-generic/atomic.h>
 #endif /* __ARCH_M68KNOMMU_ATOMIC __ */
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
index c42f88a..4058dd0 100644
--- a/include/asm-m68knommu/bitops.h
+++ b/include/asm-m68knommu/bitops.h
@@ -499,5 +499,6 @@
  * fls: find last bit set.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* _M68KNOMMU_BITOPS_H */
diff --git a/include/asm-m68knommu/futex.h b/include/asm-m68knommu/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-m68knommu/futex.h
+++ b/include/asm-m68knommu/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-m68knommu/irq.h b/include/asm-m68knommu/irq.h
index a08fa9b..20c48ec 100644
--- a/include/asm-m68knommu/irq.h
+++ b/include/asm-m68knommu/irq.h
@@ -84,10 +84,8 @@
 /*
  * Some drivers want these entry points
  */
-#define enable_irq(x)	(mach_enable_irq  ? (*mach_enable_irq)(x)  : 0)
-#define disable_irq(x)	(mach_disable_irq ? (*mach_disable_irq)(x) : 0)
-
-#define enable_irq_nosync(x)	enable_irq(x)
+#define enable_irq(x)	0
+#define disable_irq(x)	do { } while (0)
 #define disable_irq_nosync(x)	disable_irq(x)
 
 struct irqaction;
diff --git a/include/asm-mips/.gitignore b/include/asm-mips/.gitignore
deleted file mode 100644
index 4ec57ad..0000000
--- a/include/asm-mips/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-asm_offsets.h
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 55c37c1..92256e4 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -713,4 +713,5 @@
 #define smp_mb__before_atomic_inc()	smp_mb()
 #define smp_mb__after_atomic_inc()	smp_mb()
 
+#include <asm-generic/atomic.h>
 #endif /* _ASM_ATOMIC_H */
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 5496f90..3b0c8aa 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -695,7 +695,7 @@
 
 	return flz(~word) + 1;
 }
-
+#define fls64(x)   generic_fls64(x)
 
 /*
  * find_next_zero_bit - find the first zero bit in a memory region
diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h
index 1a5d1a6..55e19f2 100644
--- a/include/asm-mips/cache.h
+++ b/include/asm-mips/cache.h
@@ -15,7 +15,6 @@
 #define L1_CACHE_SHIFT		CONFIG_MIPS_L1_CACHE_SHIFT
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
-#define L1_CACHE_SHIFT_MAX	6
 #define SMP_CACHE_SHIFT		L1_CACHE_SHIFT
 #define SMP_CACHE_BYTES		L1_CACHE_BYTES
 
diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h
index 33d275c..e867b4e 100644
--- a/include/asm-mips/mach-au1x00/au1xxx_ide.h
+++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h
@@ -74,9 +74,6 @@
         u8                      white_list, black_list;
         struct dbdma_cmd        *dma_table_cpu;
         dma_addr_t              dma_table_dma;
-        struct scatterlist      *sg_table;
-        int                     sg_nents;
-        int                     sg_dma_direction;
 #endif
         struct device           *dev;
 	int			irq;
@@ -87,11 +84,6 @@
 } _auide_hwif;
 
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-struct drive_list_entry {
-        const char * id_model;
-        const char * id_firmware;
-};
-
 /* HD white list */
 static const struct drive_list_entry dma_white_list [] = {
 /*
@@ -167,13 +159,9 @@
  * Multi-Word DMA + DbDMA functions
  */
 #ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-
-        static int in_drive_list(struct hd_driveid *id,
-                                 const struct drive_list_entry *drive_table);
         static int auide_build_sglist(ide_drive_t *drive,  struct request *rq);
         static int auide_build_dmatable(ide_drive_t *drive);
         static int auide_dma_end(ide_drive_t *drive);
-        static void auide_dma_start(ide_drive_t *drive );
         ide_startstop_t auide_dma_intr (ide_drive_t *drive);
         static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command);
         static int auide_dma_setup(ide_drive_t *drive);
@@ -188,8 +176,6 @@
         static void auide_ddma_rx_callback(int irq, void *param,
                                            struct pt_regs *regs);
         static int auide_dma_off_quietly(ide_drive_t *drive);
-        static int auide_dma_timeout(ide_drive_t *drive);
-
 #endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
 
 /*******************************************************************************
@@ -299,3 +285,11 @@
 #define SBC_IDE_MDMA2_TPM     (0x00<<6)
 #define SBC_IDE_MDMA2_TA      (0x12<<0)
 
+#define SBC_IDE_TIMING(mode) \
+         SBC_IDE_##mode##_TWCS | \
+         SBC_IDE_##mode##_TCSH | \
+         SBC_IDE_##mode##_TCSOFF | \
+         SBC_IDE_##mode##_TWP | \
+         SBC_IDE_##mode##_TCSW | \
+         SBC_IDE_##mode##_TPM | \
+         SBC_IDE_##mode##_TA
diff --git a/include/asm-mips/mach-qemu/timex.h b/include/asm-mips/mach-qemu/timex.h
new file mode 100644
index 0000000..cd54369
--- /dev/null
+++ b/include/asm-mips/mach-qemu/timex.h
@@ -0,0 +1,16 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005 Daniel Jacobowitz
+ */
+#ifndef __ASM_MACH_QEMU_TIMEX_H
+#define __ASM_MACH_QEMU_TIMEX_H
+
+/*
+ * We use a simulated i8254 PIC...
+ */
+#define CLOCK_TICK_RATE		1193182
+
+#endif /* __ASM_MACH_QEMU_TIMEX_H */
diff --git a/include/asm-mips/mman.h b/include/asm-mips/mman.h
index 6206095..dd17c8b 100644
--- a/include/asm-mips/mman.h
+++ b/include/asm-mips/mman.h
@@ -65,6 +65,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON       MAP_ANONYMOUS
diff --git a/include/asm-mips/riscos-syscall.h b/include/asm-mips/riscos-syscall.h
deleted file mode 100644
index 4d8eb15..0000000
--- a/include/asm-mips/riscos-syscall.h
+++ /dev/null
@@ -1,979 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1995, 96, 97, 98, 99, 2000 by Ralf Baechle
- */
-#ifndef _ASM_RISCOS_SYSCALL_H
-#define _ASM_RISCOS_SYSCALL_H
-
-/*
- * The syscalls 0 - 3999 are reserved for a down to the root syscall
- * compatibility with RISC/os and IRIX.  We'll see how to deal with the
- * various "real" BSD variants like Ultrix, NetBSD ...
- */
-
-/*
- * SVR4 syscalls are in the range from 1 to 999
- */
-#define __NR_SVR4			0
-#define __NR_SVR4_syscall		(__NR_SVR4 +   0)
-#define __NR_SVR4_exit			(__NR_SVR4 +   1)
-#define __NR_SVR4_fork			(__NR_SVR4 +   2)
-#define __NR_SVR4_read			(__NR_SVR4 +   3)
-#define __NR_SVR4_write			(__NR_SVR4 +   4)
-#define __NR_SVR4_open			(__NR_SVR4 +   5)
-#define __NR_SVR4_close			(__NR_SVR4 +   6)
-#define __NR_SVR4_wait			(__NR_SVR4 +   7)
-#define __NR_SVR4_creat			(__NR_SVR4 +   8)
-#define __NR_SVR4_link			(__NR_SVR4 +   9)
-#define __NR_SVR4_unlink		(__NR_SVR4 +  10)
-#define __NR_SVR4_exec			(__NR_SVR4 +  11)
-#define __NR_SVR4_chdir			(__NR_SVR4 +  12)
-#define __NR_SVR4_gtime			(__NR_SVR4 +  13)
-#define __NR_SVR4_mknod			(__NR_SVR4 +  14)
-#define __NR_SVR4_chmod			(__NR_SVR4 +  15)
-#define __NR_SVR4_chown			(__NR_SVR4 +  16)
-#define __NR_SVR4_sbreak		(__NR_SVR4 +  17)
-#define __NR_SVR4_stat			(__NR_SVR4 +  18)
-#define __NR_SVR4_lseek			(__NR_SVR4 +  19)
-#define __NR_SVR4_getpid		(__NR_SVR4 +  20)
-#define __NR_SVR4_mount			(__NR_SVR4 +  21)
-#define __NR_SVR4_umount		(__NR_SVR4 +  22)
-#define __NR_SVR4_setuid		(__NR_SVR4 +  23)
-#define __NR_SVR4_getuid		(__NR_SVR4 +  24)
-#define __NR_SVR4_stime			(__NR_SVR4 +  25)
-#define __NR_SVR4_ptrace		(__NR_SVR4 +  26)
-#define __NR_SVR4_alarm			(__NR_SVR4 +  27)
-#define __NR_SVR4_fstat			(__NR_SVR4 +  28)
-#define __NR_SVR4_pause			(__NR_SVR4 +  29)
-#define __NR_SVR4_utime			(__NR_SVR4 +  30)
-#define __NR_SVR4_stty			(__NR_SVR4 +  31)
-#define __NR_SVR4_gtty			(__NR_SVR4 +  32)
-#define __NR_SVR4_access		(__NR_SVR4 +  33)
-#define __NR_SVR4_nice			(__NR_SVR4 +  34)
-#define __NR_SVR4_statfs		(__NR_SVR4 +  35)
-#define __NR_SVR4_sync			(__NR_SVR4 +  36)
-#define __NR_SVR4_kill			(__NR_SVR4 +  37)
-#define __NR_SVR4_fstatfs		(__NR_SVR4 +  38)
-#define __NR_SVR4_setpgrp		(__NR_SVR4 +  39)
-#define __NR_SVR4_cxenix		(__NR_SVR4 +  40)
-#define __NR_SVR4_dup			(__NR_SVR4 +  41)
-#define __NR_SVR4_pipe			(__NR_SVR4 +  42)
-#define __NR_SVR4_times			(__NR_SVR4 +  43)
-#define __NR_SVR4_profil		(__NR_SVR4 +  44)
-#define __NR_SVR4_plock			(__NR_SVR4 +  45)
-#define __NR_SVR4_setgid		(__NR_SVR4 +  46)
-#define __NR_SVR4_getgid		(__NR_SVR4 +  47)
-#define __NR_SVR4_sig			(__NR_SVR4 +  48)
-#define __NR_SVR4_msgsys		(__NR_SVR4 +  49)
-#define __NR_SVR4_sysmips		(__NR_SVR4 +  50)
-#define __NR_SVR4_sysacct		(__NR_SVR4 +  51)
-#define __NR_SVR4_shmsys		(__NR_SVR4 +  52)
-#define __NR_SVR4_semsys		(__NR_SVR4 +  53)
-#define __NR_SVR4_ioctl			(__NR_SVR4 +  54)
-#define __NR_SVR4_uadmin		(__NR_SVR4 +  55)
-#define __NR_SVR4_exch 			(__NR_SVR4 +  56)
-#define __NR_SVR4_utssys		(__NR_SVR4 +  57)
-#define __NR_SVR4_fsync			(__NR_SVR4 +  58)
-#define __NR_SVR4_exece			(__NR_SVR4 +  59)
-#define __NR_SVR4_umask			(__NR_SVR4 +  60)
-#define __NR_SVR4_chroot		(__NR_SVR4 +  61)
-#define __NR_SVR4_fcntl			(__NR_SVR4 +  62)
-#define __NR_SVR4_ulimit		(__NR_SVR4 +  63)
-#define __NR_SVR4_reserved1		(__NR_SVR4 +  64)
-#define __NR_SVR4_reserved2		(__NR_SVR4 +  65)
-#define __NR_SVR4_reserved3		(__NR_SVR4 +  66)
-#define __NR_SVR4_reserved4		(__NR_SVR4 +  67)
-#define __NR_SVR4_reserved5		(__NR_SVR4 +  68)
-#define __NR_SVR4_reserved6		(__NR_SVR4 +  69)
-#define __NR_SVR4_advfs			(__NR_SVR4 +  70)
-#define __NR_SVR4_unadvfs		(__NR_SVR4 +  71)
-#define __NR_SVR4_unused1		(__NR_SVR4 +  72)
-#define __NR_SVR4_unused2		(__NR_SVR4 +  73)
-#define __NR_SVR4_rfstart		(__NR_SVR4 +  74)
-#define __NR_SVR4_unused3		(__NR_SVR4 +  75)
-#define __NR_SVR4_rdebug		(__NR_SVR4 +  76)
-#define __NR_SVR4_rfstop		(__NR_SVR4 +  77)
-#define __NR_SVR4_rfsys			(__NR_SVR4 +  78)
-#define __NR_SVR4_rmdir			(__NR_SVR4 +  79)
-#define __NR_SVR4_mkdir			(__NR_SVR4 +  80)
-#define __NR_SVR4_getdents		(__NR_SVR4 +  81)
-#define __NR_SVR4_libattach		(__NR_SVR4 +  82)
-#define __NR_SVR4_libdetach		(__NR_SVR4 +  83)
-#define __NR_SVR4_sysfs			(__NR_SVR4 +  84)
-#define __NR_SVR4_getmsg		(__NR_SVR4 +  85)
-#define __NR_SVR4_putmsg		(__NR_SVR4 +  86)
-#define __NR_SVR4_poll			(__NR_SVR4 +  87)
-#define __NR_SVR4_lstat			(__NR_SVR4 +  88)
-#define __NR_SVR4_symlink		(__NR_SVR4 +  89)
-#define __NR_SVR4_readlink		(__NR_SVR4 +  90)
-#define __NR_SVR4_setgroups		(__NR_SVR4 +  91)
-#define __NR_SVR4_getgroups		(__NR_SVR4 +  92)
-#define __NR_SVR4_fchmod		(__NR_SVR4 +  93)
-#define __NR_SVR4_fchown		(__NR_SVR4 +  94)
-#define __NR_SVR4_sigprocmask		(__NR_SVR4 +  95)
-#define __NR_SVR4_sigsuspend		(__NR_SVR4 +  96)
-#define __NR_SVR4_sigaltstack		(__NR_SVR4 +  97)
-#define __NR_SVR4_sigaction		(__NR_SVR4 +  98)
-#define __NR_SVR4_sigpending		(__NR_SVR4 +  99)
-#define __NR_SVR4_setcontext		(__NR_SVR4 + 100)
-#define __NR_SVR4_evsys			(__NR_SVR4 + 101)
-#define __NR_SVR4_evtrapret		(__NR_SVR4 + 102)
-#define __NR_SVR4_statvfs		(__NR_SVR4 + 103)
-#define __NR_SVR4_fstatvfs		(__NR_SVR4 + 104)
-#define __NR_SVR4_reserved7		(__NR_SVR4 + 105)
-#define __NR_SVR4_nfssys		(__NR_SVR4 + 106)
-#define __NR_SVR4_waitid		(__NR_SVR4 + 107)
-#define __NR_SVR4_sigsendset		(__NR_SVR4 + 108)
-#define __NR_SVR4_hrtsys		(__NR_SVR4 + 109)
-#define __NR_SVR4_acancel		(__NR_SVR4 + 110)
-#define __NR_SVR4_async			(__NR_SVR4 + 111)
-#define __NR_SVR4_priocntlset		(__NR_SVR4 + 112)
-#define __NR_SVR4_pathconf		(__NR_SVR4 + 113)
-#define __NR_SVR4_mincore		(__NR_SVR4 + 114)
-#define __NR_SVR4_mmap			(__NR_SVR4 + 115)
-#define __NR_SVR4_mprotect		(__NR_SVR4 + 116)
-#define __NR_SVR4_munmap		(__NR_SVR4 + 117)
-#define __NR_SVR4_fpathconf		(__NR_SVR4 + 118)
-#define __NR_SVR4_vfork			(__NR_SVR4 + 119)
-#define __NR_SVR4_fchdir		(__NR_SVR4 + 120)
-#define __NR_SVR4_readv			(__NR_SVR4 + 121)
-#define __NR_SVR4_writev		(__NR_SVR4 + 122)
-#define __NR_SVR4_xstat			(__NR_SVR4 + 123)
-#define __NR_SVR4_lxstat		(__NR_SVR4 + 124)
-#define __NR_SVR4_fxstat		(__NR_SVR4 + 125)
-#define __NR_SVR4_xmknod		(__NR_SVR4 + 126)
-#define __NR_SVR4_clocal		(__NR_SVR4 + 127)
-#define __NR_SVR4_setrlimit		(__NR_SVR4 + 128)
-#define __NR_SVR4_getrlimit		(__NR_SVR4 + 129)
-#define __NR_SVR4_lchown		(__NR_SVR4 + 130)
-#define __NR_SVR4_memcntl		(__NR_SVR4 + 131)
-#define __NR_SVR4_getpmsg		(__NR_SVR4 + 132)
-#define __NR_SVR4_putpmsg		(__NR_SVR4 + 133)
-#define __NR_SVR4_rename		(__NR_SVR4 + 134)
-#define __NR_SVR4_nuname		(__NR_SVR4 + 135)
-#define __NR_SVR4_setegid		(__NR_SVR4 + 136)
-#define __NR_SVR4_sysconf		(__NR_SVR4 + 137)
-#define __NR_SVR4_adjtime		(__NR_SVR4 + 138)
-#define __NR_SVR4_sysinfo		(__NR_SVR4 + 139)
-#define __NR_SVR4_reserved8		(__NR_SVR4 + 140)
-#define __NR_SVR4_seteuid		(__NR_SVR4 + 141)
-#define __NR_SVR4_PYRAMID_statis	(__NR_SVR4 + 142)
-#define __NR_SVR4_PYRAMID_tuning	(__NR_SVR4 + 143)
-#define __NR_SVR4_PYRAMID_forcerr	(__NR_SVR4 + 144)
-#define __NR_SVR4_PYRAMID_mpcntl	(__NR_SVR4 + 145)
-#define __NR_SVR4_reserved9		(__NR_SVR4 + 146)
-#define __NR_SVR4_reserved10		(__NR_SVR4 + 147)
-#define __NR_SVR4_reserved11		(__NR_SVR4 + 148)
-#define __NR_SVR4_reserved12		(__NR_SVR4 + 149)
-#define __NR_SVR4_reserved13		(__NR_SVR4 + 150)
-#define __NR_SVR4_reserved14		(__NR_SVR4 + 151)
-#define __NR_SVR4_reserved15		(__NR_SVR4 + 152)
-#define __NR_SVR4_reserved16		(__NR_SVR4 + 153)
-#define __NR_SVR4_reserved17		(__NR_SVR4 + 154)
-#define __NR_SVR4_reserved18		(__NR_SVR4 + 155)
-#define __NR_SVR4_reserved19		(__NR_SVR4 + 156)
-#define __NR_SVR4_reserved20		(__NR_SVR4 + 157)
-#define __NR_SVR4_reserved21		(__NR_SVR4 + 158)
-#define __NR_SVR4_reserved22		(__NR_SVR4 + 159)
-#define __NR_SVR4_reserved23		(__NR_SVR4 + 160)
-#define __NR_SVR4_reserved24		(__NR_SVR4 + 161)
-#define __NR_SVR4_reserved25		(__NR_SVR4 + 162)
-#define __NR_SVR4_reserved26		(__NR_SVR4 + 163)
-#define __NR_SVR4_reserved27		(__NR_SVR4 + 164)
-#define __NR_SVR4_reserved28		(__NR_SVR4 + 165)
-#define __NR_SVR4_reserved29		(__NR_SVR4 + 166)
-#define __NR_SVR4_reserved30		(__NR_SVR4 + 167)
-#define __NR_SVR4_reserved31		(__NR_SVR4 + 168)
-#define __NR_SVR4_reserved32		(__NR_SVR4 + 169)
-#define __NR_SVR4_reserved33		(__NR_SVR4 + 170)
-#define __NR_SVR4_reserved34		(__NR_SVR4 + 171)
-#define __NR_SVR4_reserved35		(__NR_SVR4 + 172)
-#define __NR_SVR4_reserved36		(__NR_SVR4 + 173)
-#define __NR_SVR4_reserved37		(__NR_SVR4 + 174)
-#define __NR_SVR4_reserved38		(__NR_SVR4 + 175)
-#define __NR_SVR4_reserved39		(__NR_SVR4 + 176)
-#define __NR_SVR4_reserved40		(__NR_SVR4 + 177)
-#define __NR_SVR4_reserved41		(__NR_SVR4 + 178)
-#define __NR_SVR4_reserved42		(__NR_SVR4 + 179)
-#define __NR_SVR4_reserved43		(__NR_SVR4 + 180)
-#define __NR_SVR4_reserved44		(__NR_SVR4 + 181)
-#define __NR_SVR4_reserved45		(__NR_SVR4 + 182)
-#define __NR_SVR4_reserved46		(__NR_SVR4 + 183)
-#define __NR_SVR4_reserved47		(__NR_SVR4 + 184)
-#define __NR_SVR4_reserved48		(__NR_SVR4 + 185)
-#define __NR_SVR4_reserved49		(__NR_SVR4 + 186)
-#define __NR_SVR4_reserved50		(__NR_SVR4 + 187)
-#define __NR_SVR4_reserved51		(__NR_SVR4 + 188)
-#define __NR_SVR4_reserved52		(__NR_SVR4 + 189)
-#define __NR_SVR4_reserved53		(__NR_SVR4 + 190)
-#define __NR_SVR4_reserved54		(__NR_SVR4 + 191)
-#define __NR_SVR4_reserved55		(__NR_SVR4 + 192)
-#define __NR_SVR4_reserved56		(__NR_SVR4 + 193)
-#define __NR_SVR4_reserved57		(__NR_SVR4 + 194)
-#define __NR_SVR4_reserved58		(__NR_SVR4 + 195)
-#define __NR_SVR4_reserved59		(__NR_SVR4 + 196)
-#define __NR_SVR4_reserved60		(__NR_SVR4 + 197)
-#define __NR_SVR4_reserved61		(__NR_SVR4 + 198)
-#define __NR_SVR4_reserved62		(__NR_SVR4 + 199)
-#define __NR_SVR4_reserved63		(__NR_SVR4 + 200)
-#define __NR_SVR4_aread			(__NR_SVR4 + 201)
-#define __NR_SVR4_awrite		(__NR_SVR4 + 202)
-#define __NR_SVR4_listio		(__NR_SVR4 + 203)
-#define __NR_SVR4_mips_acancel		(__NR_SVR4 + 204)
-#define __NR_SVR4_astatus		(__NR_SVR4 + 205)
-#define __NR_SVR4_await			(__NR_SVR4 + 206)
-#define __NR_SVR4_areadv		(__NR_SVR4 + 207)
-#define __NR_SVR4_awritev		(__NR_SVR4 + 208)
-#define __NR_SVR4_MIPS_reserved1	(__NR_SVR4 + 209)
-#define __NR_SVR4_MIPS_reserved2	(__NR_SVR4 + 210)
-#define __NR_SVR4_MIPS_reserved3	(__NR_SVR4 + 211)
-#define __NR_SVR4_MIPS_reserved4	(__NR_SVR4 + 212)
-#define __NR_SVR4_MIPS_reserved5	(__NR_SVR4 + 213)
-#define __NR_SVR4_MIPS_reserved6	(__NR_SVR4 + 214)
-#define __NR_SVR4_MIPS_reserved7	(__NR_SVR4 + 215)
-#define __NR_SVR4_MIPS_reserved8	(__NR_SVR4 + 216)
-#define __NR_SVR4_MIPS_reserved9	(__NR_SVR4 + 217)
-#define __NR_SVR4_MIPS_reserved10	(__NR_SVR4 + 218)
-#define __NR_SVR4_MIPS_reserved11	(__NR_SVR4 + 219)
-#define __NR_SVR4_MIPS_reserved12	(__NR_SVR4 + 220)
-#define __NR_SVR4_CDC_reserved1		(__NR_SVR4 + 221)
-#define __NR_SVR4_CDC_reserved2		(__NR_SVR4 + 222)
-#define __NR_SVR4_CDC_reserved3		(__NR_SVR4 + 223)
-#define __NR_SVR4_CDC_reserved4		(__NR_SVR4 + 224)
-#define __NR_SVR4_CDC_reserved5		(__NR_SVR4 + 225)
-#define __NR_SVR4_CDC_reserved6		(__NR_SVR4 + 226)
-#define __NR_SVR4_CDC_reserved7		(__NR_SVR4 + 227)
-#define __NR_SVR4_CDC_reserved8		(__NR_SVR4 + 228)
-#define __NR_SVR4_CDC_reserved9		(__NR_SVR4 + 229)
-#define __NR_SVR4_CDC_reserved10	(__NR_SVR4 + 230)
-#define __NR_SVR4_CDC_reserved11	(__NR_SVR4 + 231)
-#define __NR_SVR4_CDC_reserved12	(__NR_SVR4 + 232)
-#define __NR_SVR4_CDC_reserved13	(__NR_SVR4 + 233)
-#define __NR_SVR4_CDC_reserved14	(__NR_SVR4 + 234)
-#define __NR_SVR4_CDC_reserved15	(__NR_SVR4 + 235)
-#define __NR_SVR4_CDC_reserved16	(__NR_SVR4 + 236)
-#define __NR_SVR4_CDC_reserved17	(__NR_SVR4 + 237)
-#define __NR_SVR4_CDC_reserved18	(__NR_SVR4 + 238)
-#define __NR_SVR4_CDC_reserved19	(__NR_SVR4 + 239)
-#define __NR_SVR4_CDC_reserved20	(__NR_SVR4 + 240)
-
-/*
- * SYS V syscalls are in the range from 1000 to 1999
- */
-#define __NR_SYSV			1000
-#define __NR_SYSV_syscall		(__NR_SYSV +   0)
-#define __NR_SYSV_exit			(__NR_SYSV +   1)
-#define __NR_SYSV_fork			(__NR_SYSV +   2)
-#define __NR_SYSV_read			(__NR_SYSV +   3)
-#define __NR_SYSV_write			(__NR_SYSV +   4)
-#define __NR_SYSV_open			(__NR_SYSV +   5)
-#define __NR_SYSV_close			(__NR_SYSV +   6)
-#define __NR_SYSV_wait			(__NR_SYSV +   7)
-#define __NR_SYSV_creat			(__NR_SYSV +   8)
-#define __NR_SYSV_link			(__NR_SYSV +   9)
-#define __NR_SYSV_unlink		(__NR_SYSV +  10)
-#define __NR_SYSV_execv			(__NR_SYSV +  11)
-#define __NR_SYSV_chdir			(__NR_SYSV +  12)
-#define __NR_SYSV_time			(__NR_SYSV +  13)
-#define __NR_SYSV_mknod			(__NR_SYSV +  14)
-#define __NR_SYSV_chmod			(__NR_SYSV +  15)
-#define __NR_SYSV_chown			(__NR_SYSV +  16)
-#define __NR_SYSV_brk			(__NR_SYSV +  17)
-#define __NR_SYSV_stat			(__NR_SYSV +  18)
-#define __NR_SYSV_lseek			(__NR_SYSV +  19)
-#define __NR_SYSV_getpid		(__NR_SYSV +  20)
-#define __NR_SYSV_mount			(__NR_SYSV +  21)
-#define __NR_SYSV_umount		(__NR_SYSV +  22)
-#define __NR_SYSV_setuid		(__NR_SYSV +  23)
-#define __NR_SYSV_getuid		(__NR_SYSV +  24)
-#define __NR_SYSV_stime			(__NR_SYSV +  25)
-#define __NR_SYSV_ptrace		(__NR_SYSV +  26)
-#define __NR_SYSV_alarm			(__NR_SYSV +  27)
-#define __NR_SYSV_fstat			(__NR_SYSV +  28)
-#define __NR_SYSV_pause			(__NR_SYSV +  29)
-#define __NR_SYSV_utime			(__NR_SYSV +  30)
-#define __NR_SYSV_stty			(__NR_SYSV +  31)
-#define __NR_SYSV_gtty			(__NR_SYSV +  32)
-#define __NR_SYSV_access		(__NR_SYSV +  33)
-#define __NR_SYSV_nice			(__NR_SYSV +  34)
-#define __NR_SYSV_statfs		(__NR_SYSV +  35)
-#define __NR_SYSV_sync			(__NR_SYSV +  36)
-#define __NR_SYSV_kill			(__NR_SYSV +  37)
-#define __NR_SYSV_fstatfs		(__NR_SYSV +  38)
-#define __NR_SYSV_setpgrp		(__NR_SYSV +  39)
-#define __NR_SYSV_syssgi		(__NR_SYSV +  40)
-#define __NR_SYSV_dup			(__NR_SYSV +  41)
-#define __NR_SYSV_pipe			(__NR_SYSV +  42)
-#define __NR_SYSV_times			(__NR_SYSV +  43)
-#define __NR_SYSV_profil		(__NR_SYSV +  44)
-#define __NR_SYSV_plock			(__NR_SYSV +  45)
-#define __NR_SYSV_setgid		(__NR_SYSV +  46)
-#define __NR_SYSV_getgid		(__NR_SYSV +  47)
-#define __NR_SYSV_sig			(__NR_SYSV +  48)
-#define __NR_SYSV_msgsys		(__NR_SYSV +  49)
-#define __NR_SYSV_sysmips		(__NR_SYSV +  50)
-#define __NR_SYSV_acct			(__NR_SYSV +  51)
-#define __NR_SYSV_shmsys		(__NR_SYSV +  52)
-#define __NR_SYSV_semsys		(__NR_SYSV +  53)
-#define __NR_SYSV_ioctl			(__NR_SYSV +  54)
-#define __NR_SYSV_uadmin		(__NR_SYSV +  55)
-#define __NR_SYSV_sysmp			(__NR_SYSV +  56)
-#define __NR_SYSV_utssys		(__NR_SYSV +  57)
-#define __NR_SYSV_USG_reserved1		(__NR_SYSV +  58)
-#define __NR_SYSV_execve		(__NR_SYSV +  59)
-#define __NR_SYSV_umask			(__NR_SYSV +  60)
-#define __NR_SYSV_chroot		(__NR_SYSV +  61)
-#define __NR_SYSV_fcntl			(__NR_SYSV +  62)
-#define __NR_SYSV_ulimit		(__NR_SYSV +  63)
-#define __NR_SYSV_SAFARI4_reserved1	(__NR_SYSV +  64)
-#define __NR_SYSV_SAFARI4_reserved2	(__NR_SYSV +  65)
-#define __NR_SYSV_SAFARI4_reserved3	(__NR_SYSV +  66)
-#define __NR_SYSV_SAFARI4_reserved4	(__NR_SYSV +  67)
-#define __NR_SYSV_SAFARI4_reserved5	(__NR_SYSV +  68)
-#define __NR_SYSV_SAFARI4_reserved6	(__NR_SYSV +  69)
-#define __NR_SYSV_advfs			(__NR_SYSV +  70)
-#define __NR_SYSV_unadvfs		(__NR_SYSV +  71)
-#define __NR_SYSV_rmount		(__NR_SYSV +  72)
-#define __NR_SYSV_rumount		(__NR_SYSV +  73)
-#define __NR_SYSV_rfstart		(__NR_SYSV +  74)
-#define __NR_SYSV_getrlimit64		(__NR_SYSV +  75)
-#define __NR_SYSV_setrlimit64		(__NR_SYSV +  76)
-#define __NR_SYSV_nanosleep		(__NR_SYSV +  77)
-#define __NR_SYSV_lseek64		(__NR_SYSV +  78)
-#define __NR_SYSV_rmdir			(__NR_SYSV +  79)
-#define __NR_SYSV_mkdir			(__NR_SYSV +  80)
-#define __NR_SYSV_getdents		(__NR_SYSV +  81)
-#define __NR_SYSV_sginap		(__NR_SYSV +  82)
-#define __NR_SYSV_sgikopt		(__NR_SYSV +  83)
-#define __NR_SYSV_sysfs			(__NR_SYSV +  84)
-#define __NR_SYSV_getmsg		(__NR_SYSV +  85)
-#define __NR_SYSV_putmsg		(__NR_SYSV +  86)
-#define __NR_SYSV_poll			(__NR_SYSV +  87)
-#define __NR_SYSV_sigreturn		(__NR_SYSV +  88)
-#define __NR_SYSV_accept		(__NR_SYSV +  89)
-#define __NR_SYSV_bind			(__NR_SYSV +  90)
-#define __NR_SYSV_connect		(__NR_SYSV +  91)
-#define __NR_SYSV_gethostid		(__NR_SYSV +  92)
-#define __NR_SYSV_getpeername		(__NR_SYSV +  93)
-#define __NR_SYSV_getsockname		(__NR_SYSV +  94)
-#define __NR_SYSV_getsockopt		(__NR_SYSV +  95)
-#define __NR_SYSV_listen		(__NR_SYSV +  96)
-#define __NR_SYSV_recv			(__NR_SYSV +  97)
-#define __NR_SYSV_recvfrom		(__NR_SYSV +  98)
-#define __NR_SYSV_recvmsg		(__NR_SYSV +  99)
-#define __NR_SYSV_select		(__NR_SYSV + 100)
-#define __NR_SYSV_send			(__NR_SYSV + 101)
-#define __NR_SYSV_sendmsg		(__NR_SYSV + 102)
-#define __NR_SYSV_sendto		(__NR_SYSV + 103)
-#define __NR_SYSV_sethostid		(__NR_SYSV + 104)
-#define __NR_SYSV_setsockopt		(__NR_SYSV + 105)
-#define __NR_SYSV_shutdown		(__NR_SYSV + 106)
-#define __NR_SYSV_socket		(__NR_SYSV + 107)
-#define __NR_SYSV_gethostname		(__NR_SYSV + 108)
-#define __NR_SYSV_sethostname		(__NR_SYSV + 109)
-#define __NR_SYSV_getdomainname		(__NR_SYSV + 110)
-#define __NR_SYSV_setdomainname		(__NR_SYSV + 111)
-#define __NR_SYSV_truncate		(__NR_SYSV + 112)
-#define __NR_SYSV_ftruncate		(__NR_SYSV + 113)
-#define __NR_SYSV_rename		(__NR_SYSV + 114)
-#define __NR_SYSV_symlink		(__NR_SYSV + 115)
-#define __NR_SYSV_readlink		(__NR_SYSV + 116)
-#define __NR_SYSV_lstat			(__NR_SYSV + 117)
-#define __NR_SYSV_nfsmount		(__NR_SYSV + 118)
-#define __NR_SYSV_nfssvc		(__NR_SYSV + 119)
-#define __NR_SYSV_getfh			(__NR_SYSV + 120)
-#define __NR_SYSV_async_daemon		(__NR_SYSV + 121)
-#define __NR_SYSV_exportfs		(__NR_SYSV + 122)
-#define __NR_SYSV_setregid		(__NR_SYSV + 123)
-#define __NR_SYSV_setreuid		(__NR_SYSV + 124)
-#define __NR_SYSV_getitimer		(__NR_SYSV + 125)
-#define __NR_SYSV_setitimer		(__NR_SYSV + 126)
-#define __NR_SYSV_adjtime		(__NR_SYSV + 127)
-#define __NR_SYSV_BSD_getime		(__NR_SYSV + 128)
-#define __NR_SYSV_sproc			(__NR_SYSV + 129)
-#define __NR_SYSV_prctl			(__NR_SYSV + 130)
-#define __NR_SYSV_procblk		(__NR_SYSV + 131)
-#define __NR_SYSV_sprocsp		(__NR_SYSV + 132)
-#define __NR_SYSV_sgigsc		(__NR_SYSV + 133)
-#define __NR_SYSV_mmap			(__NR_SYSV + 134)
-#define __NR_SYSV_munmap		(__NR_SYSV + 135)
-#define __NR_SYSV_mprotect		(__NR_SYSV + 136)
-#define __NR_SYSV_msync			(__NR_SYSV + 137)
-#define __NR_SYSV_madvise		(__NR_SYSV + 138)
-#define __NR_SYSV_pagelock		(__NR_SYSV + 139)
-#define __NR_SYSV_getpagesize		(__NR_SYSV + 140)
-#define __NR_SYSV_quotactl		(__NR_SYSV + 141)
-#define __NR_SYSV_libdetach		(__NR_SYSV + 142)
-#define __NR_SYSV_BSDgetpgrp		(__NR_SYSV + 143)
-#define __NR_SYSV_BSDsetpgrp		(__NR_SYSV + 144)
-#define __NR_SYSV_vhangup		(__NR_SYSV + 145)
-#define __NR_SYSV_fsync			(__NR_SYSV + 146)
-#define __NR_SYSV_fchdir		(__NR_SYSV + 147)
-#define __NR_SYSV_getrlimit		(__NR_SYSV + 148)
-#define __NR_SYSV_setrlimit		(__NR_SYSV + 149)
-#define __NR_SYSV_cacheflush		(__NR_SYSV + 150)
-#define __NR_SYSV_cachectl		(__NR_SYSV + 151)
-#define __NR_SYSV_fchown		(__NR_SYSV + 152)
-#define __NR_SYSV_fchmod		(__NR_SYSV + 153)
-#define __NR_SYSV_wait3			(__NR_SYSV + 154)
-#define __NR_SYSV_socketpair		(__NR_SYSV + 155)
-#define __NR_SYSV_sysinfo		(__NR_SYSV + 156)
-#define __NR_SYSV_nuname		(__NR_SYSV + 157)
-#define __NR_SYSV_xstat			(__NR_SYSV + 158)
-#define __NR_SYSV_lxstat		(__NR_SYSV + 159)
-#define __NR_SYSV_fxstat		(__NR_SYSV + 160)
-#define __NR_SYSV_xmknod		(__NR_SYSV + 161)
-#define __NR_SYSV_ksigaction		(__NR_SYSV + 162)
-#define __NR_SYSV_sigpending		(__NR_SYSV + 163)
-#define __NR_SYSV_sigprocmask		(__NR_SYSV + 164)
-#define __NR_SYSV_sigsuspend		(__NR_SYSV + 165)
-#define __NR_SYSV_sigpoll		(__NR_SYSV + 166)
-#define __NR_SYSV_swapctl		(__NR_SYSV + 167)
-#define __NR_SYSV_getcontext		(__NR_SYSV + 168)
-#define __NR_SYSV_setcontext		(__NR_SYSV + 169)
-#define __NR_SYSV_waitsys		(__NR_SYSV + 170)
-#define __NR_SYSV_sigstack		(__NR_SYSV + 171)
-#define __NR_SYSV_sigaltstack		(__NR_SYSV + 172)
-#define __NR_SYSV_sigsendset		(__NR_SYSV + 173)
-#define __NR_SYSV_statvfs		(__NR_SYSV + 174)
-#define __NR_SYSV_fstatvfs		(__NR_SYSV + 175)
-#define __NR_SYSV_getpmsg		(__NR_SYSV + 176)
-#define __NR_SYSV_putpmsg		(__NR_SYSV + 177)
-#define __NR_SYSV_lchown		(__NR_SYSV + 178)
-#define __NR_SYSV_priocntl		(__NR_SYSV + 179)
-#define __NR_SYSV_ksigqueue		(__NR_SYSV + 180)
-#define __NR_SYSV_readv			(__NR_SYSV + 181)
-#define __NR_SYSV_writev		(__NR_SYSV + 182)
-#define __NR_SYSV_truncate64		(__NR_SYSV + 183)
-#define __NR_SYSV_ftruncate64		(__NR_SYSV + 184)
-#define __NR_SYSV_mmap64		(__NR_SYSV + 185)
-#define __NR_SYSV_dmi			(__NR_SYSV + 186)
-#define __NR_SYSV_pread			(__NR_SYSV + 187)
-#define __NR_SYSV_pwrite		(__NR_SYSV + 188)
-
-/*
- * BSD 4.3 syscalls are in the range from 2000 to 2999
- */
-#define __NR_BSD43			2000
-#define __NR_BSD43_syscall		(__NR_BSD43 +   0)
-#define __NR_BSD43_exit			(__NR_BSD43 +   1)
-#define __NR_BSD43_fork			(__NR_BSD43 +   2)
-#define __NR_BSD43_read			(__NR_BSD43 +   3)
-#define __NR_BSD43_write		(__NR_BSD43 +   4)
-#define __NR_BSD43_open			(__NR_BSD43 +   5)
-#define __NR_BSD43_close		(__NR_BSD43 +   6)
-#define __NR_BSD43_wait			(__NR_BSD43 +   7)
-#define __NR_BSD43_creat		(__NR_BSD43 +   8)
-#define __NR_BSD43_link			(__NR_BSD43 +   9)
-#define __NR_BSD43_unlink		(__NR_BSD43 +  10)
-#define __NR_BSD43_exec			(__NR_BSD43 +  11)
-#define __NR_BSD43_chdir		(__NR_BSD43 +  12)
-#define __NR_BSD43_time			(__NR_BSD43 +  13)
-#define __NR_BSD43_mknod		(__NR_BSD43 +  14)
-#define __NR_BSD43_chmod		(__NR_BSD43 +  15)
-#define __NR_BSD43_chown		(__NR_BSD43 +  16)
-#define __NR_BSD43_sbreak		(__NR_BSD43 +  17)
-#define __NR_BSD43_oldstat		(__NR_BSD43 +  18)
-#define __NR_BSD43_lseek		(__NR_BSD43 +  19)
-#define __NR_BSD43_getpid		(__NR_BSD43 +  20)
-#define __NR_BSD43_oldmount		(__NR_BSD43 +  21)
-#define __NR_BSD43_umount		(__NR_BSD43 +  22)
-#define __NR_BSD43_setuid		(__NR_BSD43 +  23)
-#define __NR_BSD43_getuid		(__NR_BSD43 +  24)
-#define __NR_BSD43_stime		(__NR_BSD43 +  25)
-#define __NR_BSD43_ptrace		(__NR_BSD43 +  26)
-#define __NR_BSD43_alarm		(__NR_BSD43 +  27)
-#define __NR_BSD43_oldfstat		(__NR_BSD43 +  28)
-#define __NR_BSD43_pause		(__NR_BSD43 +  29)
-#define __NR_BSD43_utime		(__NR_BSD43 +  30)
-#define __NR_BSD43_stty			(__NR_BSD43 +  31)
-#define __NR_BSD43_gtty			(__NR_BSD43 +  32)
-#define __NR_BSD43_access		(__NR_BSD43 +  33)
-#define __NR_BSD43_nice			(__NR_BSD43 +  34)
-#define __NR_BSD43_ftime		(__NR_BSD43 +  35)
-#define __NR_BSD43_sync			(__NR_BSD43 +  36)
-#define __NR_BSD43_kill			(__NR_BSD43 +  37)
-#define __NR_BSD43_stat			(__NR_BSD43 +  38)
-#define __NR_BSD43_oldsetpgrp		(__NR_BSD43 +  39)
-#define __NR_BSD43_lstat		(__NR_BSD43 +  40)
-#define __NR_BSD43_dup			(__NR_BSD43 +  41)
-#define __NR_BSD43_pipe			(__NR_BSD43 +  42)
-#define __NR_BSD43_times		(__NR_BSD43 +  43)
-#define __NR_BSD43_profil		(__NR_BSD43 +  44)
-#define __NR_BSD43_msgsys		(__NR_BSD43 +  45)
-#define __NR_BSD43_setgid		(__NR_BSD43 +  46)
-#define __NR_BSD43_getgid		(__NR_BSD43 +  47)
-#define __NR_BSD43_ssig			(__NR_BSD43 +  48)
-#define __NR_BSD43_reserved1		(__NR_BSD43 +  49)
-#define __NR_BSD43_reserved2		(__NR_BSD43 +  50)
-#define __NR_BSD43_sysacct		(__NR_BSD43 +  51)
-#define __NR_BSD43_phys			(__NR_BSD43 +  52)
-#define __NR_BSD43_lock			(__NR_BSD43 +  53)
-#define __NR_BSD43_ioctl		(__NR_BSD43 +  54)
-#define __NR_BSD43_reboot		(__NR_BSD43 +  55)
-#define __NR_BSD43_mpxchan		(__NR_BSD43 +  56)
-#define __NR_BSD43_symlink		(__NR_BSD43 +  57)
-#define __NR_BSD43_readlink		(__NR_BSD43 +  58)
-#define __NR_BSD43_execve		(__NR_BSD43 +  59)
-#define __NR_BSD43_umask		(__NR_BSD43 +  60)
-#define __NR_BSD43_chroot		(__NR_BSD43 +  61)
-#define __NR_BSD43_fstat		(__NR_BSD43 +  62)
-#define __NR_BSD43_reserved3		(__NR_BSD43 +  63)
-#define __NR_BSD43_getpagesize		(__NR_BSD43 +  64)
-#define __NR_BSD43_mremap		(__NR_BSD43 +  65)
-#define __NR_BSD43_vfork		(__NR_BSD43 +  66)
-#define __NR_BSD43_vread		(__NR_BSD43 +  67)
-#define __NR_BSD43_vwrite		(__NR_BSD43 +  68)
-#define __NR_BSD43_sbrk			(__NR_BSD43 +  69)
-#define __NR_BSD43_sstk			(__NR_BSD43 +  70)
-#define __NR_BSD43_mmap			(__NR_BSD43 +  71)
-#define __NR_BSD43_vadvise		(__NR_BSD43 +  72)
-#define __NR_BSD43_munmap		(__NR_BSD43 +  73)
-#define __NR_BSD43_mprotect		(__NR_BSD43 +  74)
-#define __NR_BSD43_madvise		(__NR_BSD43 +  75)
-#define __NR_BSD43_vhangup		(__NR_BSD43 +  76)
-#define __NR_BSD43_vlimit		(__NR_BSD43 +  77)
-#define __NR_BSD43_mincore		(__NR_BSD43 +  78)
-#define __NR_BSD43_getgroups		(__NR_BSD43 +  79)
-#define __NR_BSD43_setgroups		(__NR_BSD43 +  80)
-#define __NR_BSD43_getpgrp		(__NR_BSD43 +  81)
-#define __NR_BSD43_setpgrp		(__NR_BSD43 +  82)
-#define __NR_BSD43_setitimer		(__NR_BSD43 +  83)
-#define __NR_BSD43_wait3		(__NR_BSD43 +  84)
-#define __NR_BSD43_swapon		(__NR_BSD43 +  85)
-#define __NR_BSD43_getitimer		(__NR_BSD43 +  86)
-#define __NR_BSD43_gethostname		(__NR_BSD43 +  87)
-#define __NR_BSD43_sethostname		(__NR_BSD43 +  88)
-#define __NR_BSD43_getdtablesize	(__NR_BSD43 +  89)
-#define __NR_BSD43_dup2			(__NR_BSD43 +  90)
-#define __NR_BSD43_getdopt		(__NR_BSD43 +  91)
-#define __NR_BSD43_fcntl		(__NR_BSD43 +  92)
-#define __NR_BSD43_select		(__NR_BSD43 +  93)
-#define __NR_BSD43_setdopt		(__NR_BSD43 +  94)
-#define __NR_BSD43_fsync		(__NR_BSD43 +  95)
-#define __NR_BSD43_setpriority		(__NR_BSD43 +  96)
-#define __NR_BSD43_socket		(__NR_BSD43 +  97)
-#define __NR_BSD43_connect		(__NR_BSD43 +  98)
-#define __NR_BSD43_oldaccept		(__NR_BSD43 +  99)
-#define __NR_BSD43_getpriority		(__NR_BSD43 + 100)
-#define __NR_BSD43_send			(__NR_BSD43 + 101)
-#define __NR_BSD43_recv			(__NR_BSD43 + 102)
-#define __NR_BSD43_sigreturn		(__NR_BSD43 + 103)
-#define __NR_BSD43_bind			(__NR_BSD43 + 104)
-#define __NR_BSD43_setsockopt		(__NR_BSD43 + 105)
-#define __NR_BSD43_listen		(__NR_BSD43 + 106)
-#define __NR_BSD43_vtimes		(__NR_BSD43 + 107)
-#define __NR_BSD43_sigvec		(__NR_BSD43 + 108)
-#define __NR_BSD43_sigblock		(__NR_BSD43 + 109)
-#define __NR_BSD43_sigsetmask		(__NR_BSD43 + 110)
-#define __NR_BSD43_sigpause		(__NR_BSD43 + 111)
-#define __NR_BSD43_sigstack		(__NR_BSD43 + 112)
-#define __NR_BSD43_oldrecvmsg		(__NR_BSD43 + 113)
-#define __NR_BSD43_oldsendmsg		(__NR_BSD43 + 114)
-#define __NR_BSD43_vtrace		(__NR_BSD43 + 115)
-#define __NR_BSD43_gettimeofday		(__NR_BSD43 + 116)
-#define __NR_BSD43_getrusage		(__NR_BSD43 + 117)
-#define __NR_BSD43_getsockopt		(__NR_BSD43 + 118)
-#define __NR_BSD43_reserved4		(__NR_BSD43 + 119)
-#define __NR_BSD43_readv		(__NR_BSD43 + 120)
-#define __NR_BSD43_writev		(__NR_BSD43 + 121)
-#define __NR_BSD43_settimeofday		(__NR_BSD43 + 122)
-#define __NR_BSD43_fchown		(__NR_BSD43 + 123)
-#define __NR_BSD43_fchmod		(__NR_BSD43 + 124)
-#define __NR_BSD43_oldrecvfrom		(__NR_BSD43 + 125)
-#define __NR_BSD43_setreuid		(__NR_BSD43 + 126)
-#define __NR_BSD43_setregid		(__NR_BSD43 + 127)
-#define __NR_BSD43_rename		(__NR_BSD43 + 128)
-#define __NR_BSD43_truncate		(__NR_BSD43 + 129)
-#define __NR_BSD43_ftruncate		(__NR_BSD43 + 130)
-#define __NR_BSD43_flock		(__NR_BSD43 + 131)
-#define __NR_BSD43_semsys		(__NR_BSD43 + 132)
-#define __NR_BSD43_sendto		(__NR_BSD43 + 133)
-#define __NR_BSD43_shutdown		(__NR_BSD43 + 134)
-#define __NR_BSD43_socketpair		(__NR_BSD43 + 135)
-#define __NR_BSD43_mkdir		(__NR_BSD43 + 136)
-#define __NR_BSD43_rmdir		(__NR_BSD43 + 137)
-#define __NR_BSD43_utimes		(__NR_BSD43 + 138)
-#define __NR_BSD43_sigcleanup		(__NR_BSD43 + 139)
-#define __NR_BSD43_adjtime		(__NR_BSD43 + 140)
-#define __NR_BSD43_oldgetpeername	(__NR_BSD43 + 141)
-#define __NR_BSD43_gethostid		(__NR_BSD43 + 142)
-#define __NR_BSD43_sethostid		(__NR_BSD43 + 143)
-#define __NR_BSD43_getrlimit		(__NR_BSD43 + 144)
-#define __NR_BSD43_setrlimit		(__NR_BSD43 + 145)
-#define __NR_BSD43_killpg		(__NR_BSD43 + 146)
-#define __NR_BSD43_shmsys		(__NR_BSD43 + 147)
-#define __NR_BSD43_quota		(__NR_BSD43 + 148)
-#define __NR_BSD43_qquota		(__NR_BSD43 + 149)
-#define __NR_BSD43_oldgetsockname	(__NR_BSD43 + 150)
-#define __NR_BSD43_sysmips		(__NR_BSD43 + 151)
-#define __NR_BSD43_cacheflush		(__NR_BSD43 + 152)
-#define __NR_BSD43_cachectl		(__NR_BSD43 + 153)
-#define __NR_BSD43_debug		(__NR_BSD43 + 154)
-#define __NR_BSD43_reserved5		(__NR_BSD43 + 155)
-#define __NR_BSD43_reserved6		(__NR_BSD43 + 156)
-#define __NR_BSD43_nfs_mount		(__NR_BSD43 + 157)
-#define __NR_BSD43_nfs_svc		(__NR_BSD43 + 158)
-#define __NR_BSD43_getdirentries	(__NR_BSD43 + 159)
-#define __NR_BSD43_statfs		(__NR_BSD43 + 160)
-#define __NR_BSD43_fstatfs		(__NR_BSD43 + 161)
-#define __NR_BSD43_unmount		(__NR_BSD43 + 162)
-#define __NR_BSD43_async_daemon		(__NR_BSD43 + 163)
-#define __NR_BSD43_nfs_getfh		(__NR_BSD43 + 164)
-#define __NR_BSD43_getdomainname	(__NR_BSD43 + 165)
-#define __NR_BSD43_setdomainname	(__NR_BSD43 + 166)
-#define __NR_BSD43_pcfs_mount		(__NR_BSD43 + 167)
-#define __NR_BSD43_quotactl		(__NR_BSD43 + 168)
-#define __NR_BSD43_oldexportfs		(__NR_BSD43 + 169)
-#define __NR_BSD43_smount		(__NR_BSD43 + 170)
-#define __NR_BSD43_mipshwconf		(__NR_BSD43 + 171)
-#define __NR_BSD43_exportfs		(__NR_BSD43 + 172)
-#define __NR_BSD43_nfsfh_open		(__NR_BSD43 + 173)
-#define __NR_BSD43_libattach		(__NR_BSD43 + 174)
-#define __NR_BSD43_libdetach		(__NR_BSD43 + 175)
-#define __NR_BSD43_accept		(__NR_BSD43 + 176)
-#define __NR_BSD43_reserved7		(__NR_BSD43 + 177)
-#define __NR_BSD43_reserved8		(__NR_BSD43 + 178)
-#define __NR_BSD43_recvmsg		(__NR_BSD43 + 179)
-#define __NR_BSD43_recvfrom		(__NR_BSD43 + 180)
-#define __NR_BSD43_sendmsg		(__NR_BSD43 + 181)
-#define __NR_BSD43_getpeername		(__NR_BSD43 + 182)
-#define __NR_BSD43_getsockname		(__NR_BSD43 + 183)
-#define __NR_BSD43_aread		(__NR_BSD43 + 184)
-#define __NR_BSD43_awrite		(__NR_BSD43 + 185)
-#define __NR_BSD43_listio		(__NR_BSD43 + 186)
-#define __NR_BSD43_acancel		(__NR_BSD43 + 187)
-#define __NR_BSD43_astatus		(__NR_BSD43 + 188)
-#define __NR_BSD43_await		(__NR_BSD43 + 189)
-#define __NR_BSD43_areadv		(__NR_BSD43 + 190)
-#define __NR_BSD43_awritev		(__NR_BSD43 + 191)
-
-/*
- * POSIX syscalls are in the range from 3000 to 3999
- */
-#define __NR_POSIX			3000
-#define __NR_POSIX_syscall		(__NR_POSIX +   0)
-#define __NR_POSIX_exit			(__NR_POSIX +   1)
-#define __NR_POSIX_fork			(__NR_POSIX +   2)
-#define __NR_POSIX_read			(__NR_POSIX +   3)
-#define __NR_POSIX_write		(__NR_POSIX +   4)
-#define __NR_POSIX_open			(__NR_POSIX +   5)
-#define __NR_POSIX_close		(__NR_POSIX +   6)
-#define __NR_POSIX_wait			(__NR_POSIX +   7)
-#define __NR_POSIX_creat		(__NR_POSIX +   8)
-#define __NR_POSIX_link			(__NR_POSIX +   9)
-#define __NR_POSIX_unlink		(__NR_POSIX +  10)
-#define __NR_POSIX_exec			(__NR_POSIX +  11)
-#define __NR_POSIX_chdir		(__NR_POSIX +  12)
-#define __NR_POSIX_gtime		(__NR_POSIX +  13)
-#define __NR_POSIX_mknod		(__NR_POSIX +  14)
-#define __NR_POSIX_chmod		(__NR_POSIX +  15)
-#define __NR_POSIX_chown		(__NR_POSIX +  16)
-#define __NR_POSIX_sbreak		(__NR_POSIX +  17)
-#define __NR_POSIX_stat			(__NR_POSIX +  18)
-#define __NR_POSIX_lseek		(__NR_POSIX +  19)
-#define __NR_POSIX_getpid		(__NR_POSIX +  20)
-#define __NR_POSIX_mount		(__NR_POSIX +  21)
-#define __NR_POSIX_umount		(__NR_POSIX +  22)
-#define __NR_POSIX_setuid		(__NR_POSIX +  23)
-#define __NR_POSIX_getuid		(__NR_POSIX +  24)
-#define __NR_POSIX_stime		(__NR_POSIX +  25)
-#define __NR_POSIX_ptrace		(__NR_POSIX +  26)
-#define __NR_POSIX_alarm		(__NR_POSIX +  27)
-#define __NR_POSIX_fstat		(__NR_POSIX +  28)
-#define __NR_POSIX_pause		(__NR_POSIX +  29)
-#define __NR_POSIX_utime		(__NR_POSIX +  30)
-#define __NR_POSIX_stty			(__NR_POSIX +  31)
-#define __NR_POSIX_gtty			(__NR_POSIX +  32)
-#define __NR_POSIX_access		(__NR_POSIX +  33)
-#define __NR_POSIX_nice			(__NR_POSIX +  34)
-#define __NR_POSIX_statfs		(__NR_POSIX +  35)
-#define __NR_POSIX_sync			(__NR_POSIX +  36)
-#define __NR_POSIX_kill			(__NR_POSIX +  37)
-#define __NR_POSIX_fstatfs		(__NR_POSIX +  38)
-#define __NR_POSIX_getpgrp		(__NR_POSIX +  39)
-#define __NR_POSIX_syssgi		(__NR_POSIX +  40)
-#define __NR_POSIX_dup			(__NR_POSIX +  41)
-#define __NR_POSIX_pipe			(__NR_POSIX +  42)
-#define __NR_POSIX_times		(__NR_POSIX +  43)
-#define __NR_POSIX_profil		(__NR_POSIX +  44)
-#define __NR_POSIX_lock			(__NR_POSIX +  45)
-#define __NR_POSIX_setgid		(__NR_POSIX +  46)
-#define __NR_POSIX_getgid		(__NR_POSIX +  47)
-#define __NR_POSIX_sig			(__NR_POSIX +  48)
-#define __NR_POSIX_msgsys		(__NR_POSIX +  49)
-#define __NR_POSIX_sysmips		(__NR_POSIX +  50)
-#define __NR_POSIX_sysacct		(__NR_POSIX +  51)
-#define __NR_POSIX_shmsys		(__NR_POSIX +  52)
-#define __NR_POSIX_semsys		(__NR_POSIX +  53)
-#define __NR_POSIX_ioctl		(__NR_POSIX +  54)
-#define __NR_POSIX_uadmin		(__NR_POSIX +  55)
-#define __NR_POSIX_exch			(__NR_POSIX +  56)
-#define __NR_POSIX_utssys		(__NR_POSIX +  57)
-#define __NR_POSIX_USG_reserved1	(__NR_POSIX +  58)
-#define __NR_POSIX_exece		(__NR_POSIX +  59)
-#define __NR_POSIX_umask		(__NR_POSIX +  60)
-#define __NR_POSIX_chroot		(__NR_POSIX +  61)
-#define __NR_POSIX_fcntl		(__NR_POSIX +  62)
-#define __NR_POSIX_ulimit		(__NR_POSIX +  63)
-#define __NR_POSIX_SAFARI4_reserved1	(__NR_POSIX +  64)
-#define __NR_POSIX_SAFARI4_reserved2	(__NR_POSIX +  65)
-#define __NR_POSIX_SAFARI4_reserved3	(__NR_POSIX +  66)
-#define __NR_POSIX_SAFARI4_reserved4	(__NR_POSIX +  67)
-#define __NR_POSIX_SAFARI4_reserved5	(__NR_POSIX +  68)
-#define __NR_POSIX_SAFARI4_reserved6	(__NR_POSIX +  69)
-#define __NR_POSIX_advfs		(__NR_POSIX +  70)
-#define __NR_POSIX_unadvfs		(__NR_POSIX +  71)
-#define __NR_POSIX_rmount		(__NR_POSIX +  72)
-#define __NR_POSIX_rumount		(__NR_POSIX +  73)
-#define __NR_POSIX_rfstart		(__NR_POSIX +  74)
-#define __NR_POSIX_reserved1		(__NR_POSIX +  75)
-#define __NR_POSIX_rdebug		(__NR_POSIX +  76)
-#define __NR_POSIX_rfstop		(__NR_POSIX +  77)
-#define __NR_POSIX_rfsys		(__NR_POSIX +  78)
-#define __NR_POSIX_rmdir		(__NR_POSIX +  79)
-#define __NR_POSIX_mkdir		(__NR_POSIX +  80)
-#define __NR_POSIX_getdents		(__NR_POSIX +  81)
-#define __NR_POSIX_sginap		(__NR_POSIX +  82)
-#define __NR_POSIX_sgikopt		(__NR_POSIX +  83)
-#define __NR_POSIX_sysfs		(__NR_POSIX +  84)
-#define __NR_POSIX_getmsg		(__NR_POSIX +  85)
-#define __NR_POSIX_putmsg		(__NR_POSIX +  86)
-#define __NR_POSIX_poll			(__NR_POSIX +  87)
-#define __NR_POSIX_sigreturn		(__NR_POSIX +  88)
-#define __NR_POSIX_accept		(__NR_POSIX +  89)
-#define __NR_POSIX_bind			(__NR_POSIX +  90)
-#define __NR_POSIX_connect		(__NR_POSIX +  91)
-#define __NR_POSIX_gethostid		(__NR_POSIX +  92)
-#define __NR_POSIX_getpeername		(__NR_POSIX +  93)
-#define __NR_POSIX_getsockname		(__NR_POSIX +  94)
-#define __NR_POSIX_getsockopt		(__NR_POSIX +  95)
-#define __NR_POSIX_listen		(__NR_POSIX +  96)
-#define __NR_POSIX_recv			(__NR_POSIX +  97)
-#define __NR_POSIX_recvfrom		(__NR_POSIX +  98)
-#define __NR_POSIX_recvmsg		(__NR_POSIX +  99)
-#define __NR_POSIX_select		(__NR_POSIX + 100)
-#define __NR_POSIX_send			(__NR_POSIX + 101)
-#define __NR_POSIX_sendmsg		(__NR_POSIX + 102)
-#define __NR_POSIX_sendto		(__NR_POSIX + 103)
-#define __NR_POSIX_sethostid		(__NR_POSIX + 104)
-#define __NR_POSIX_setsockopt		(__NR_POSIX + 105)
-#define __NR_POSIX_shutdown		(__NR_POSIX + 106)
-#define __NR_POSIX_socket		(__NR_POSIX + 107)
-#define __NR_POSIX_gethostname		(__NR_POSIX + 108)
-#define __NR_POSIX_sethostname		(__NR_POSIX + 109)
-#define __NR_POSIX_getdomainname	(__NR_POSIX + 110)
-#define __NR_POSIX_setdomainname	(__NR_POSIX + 111)
-#define __NR_POSIX_truncate		(__NR_POSIX + 112)
-#define __NR_POSIX_ftruncate		(__NR_POSIX + 113)
-#define __NR_POSIX_rename		(__NR_POSIX + 114)
-#define __NR_POSIX_symlink		(__NR_POSIX + 115)
-#define __NR_POSIX_readlink		(__NR_POSIX + 116)
-#define __NR_POSIX_lstat		(__NR_POSIX + 117)
-#define __NR_POSIX_nfs_mount		(__NR_POSIX + 118)
-#define __NR_POSIX_nfs_svc		(__NR_POSIX + 119)
-#define __NR_POSIX_nfs_getfh		(__NR_POSIX + 120)
-#define __NR_POSIX_async_daemon		(__NR_POSIX + 121)
-#define __NR_POSIX_exportfs		(__NR_POSIX + 122)
-#define __NR_POSIX_SGI_setregid		(__NR_POSIX + 123)
-#define __NR_POSIX_SGI_setreuid		(__NR_POSIX + 124)
-#define __NR_POSIX_getitimer		(__NR_POSIX + 125)
-#define __NR_POSIX_setitimer		(__NR_POSIX + 126)
-#define __NR_POSIX_adjtime		(__NR_POSIX + 127)
-#define __NR_POSIX_SGI_bsdgettime	(__NR_POSIX + 128)
-#define __NR_POSIX_SGI_sproc		(__NR_POSIX + 129)
-#define __NR_POSIX_SGI_prctl		(__NR_POSIX + 130)
-#define __NR_POSIX_SGI_blkproc		(__NR_POSIX + 131)
-#define __NR_POSIX_SGI_reserved1	(__NR_POSIX + 132)
-#define __NR_POSIX_SGI_sgigsc		(__NR_POSIX + 133)
-#define __NR_POSIX_SGI_mmap		(__NR_POSIX + 134)
-#define __NR_POSIX_SGI_munmap		(__NR_POSIX + 135)
-#define __NR_POSIX_SGI_mprotect		(__NR_POSIX + 136)
-#define __NR_POSIX_SGI_msync		(__NR_POSIX + 137)
-#define __NR_POSIX_SGI_madvise		(__NR_POSIX + 138)
-#define __NR_POSIX_SGI_mpin		(__NR_POSIX + 139)
-#define __NR_POSIX_SGI_getpagesize	(__NR_POSIX + 140)
-#define __NR_POSIX_SGI_libattach	(__NR_POSIX + 141)
-#define __NR_POSIX_SGI_libdetach	(__NR_POSIX + 142)
-#define __NR_POSIX_SGI_getpgrp		(__NR_POSIX + 143)
-#define __NR_POSIX_SGI_setpgrp		(__NR_POSIX + 144)
-#define __NR_POSIX_SGI_reserved2	(__NR_POSIX + 145)
-#define __NR_POSIX_SGI_reserved3	(__NR_POSIX + 146)
-#define __NR_POSIX_SGI_reserved4	(__NR_POSIX + 147)
-#define __NR_POSIX_SGI_reserved5	(__NR_POSIX + 148)
-#define __NR_POSIX_SGI_reserved6	(__NR_POSIX + 149)
-#define __NR_POSIX_cacheflush		(__NR_POSIX + 150)
-#define __NR_POSIX_cachectl		(__NR_POSIX + 151)
-#define __NR_POSIX_fchown		(__NR_POSIX + 152)
-#define __NR_POSIX_fchmod		(__NR_POSIX + 153)
-#define __NR_POSIX_wait3		(__NR_POSIX + 154)
-#define __NR_POSIX_mmap			(__NR_POSIX + 155)
-#define __NR_POSIX_munmap		(__NR_POSIX + 156)
-#define __NR_POSIX_madvise		(__NR_POSIX + 157)
-#define __NR_POSIX_BSD_getpagesize	(__NR_POSIX + 158)
-#define __NR_POSIX_setreuid		(__NR_POSIX + 159)
-#define __NR_POSIX_setregid		(__NR_POSIX + 160)
-#define __NR_POSIX_setpgid		(__NR_POSIX + 161)
-#define __NR_POSIX_getgroups		(__NR_POSIX + 162)
-#define __NR_POSIX_setgroups		(__NR_POSIX + 163)
-#define __NR_POSIX_gettimeofday		(__NR_POSIX + 164)
-#define __NR_POSIX_getrusage		(__NR_POSIX + 165)
-#define __NR_POSIX_getrlimit		(__NR_POSIX + 166)
-#define __NR_POSIX_setrlimit		(__NR_POSIX + 167)
-#define __NR_POSIX_waitpid		(__NR_POSIX + 168)
-#define __NR_POSIX_dup2			(__NR_POSIX + 169)
-#define __NR_POSIX_reserved2		(__NR_POSIX + 170)
-#define __NR_POSIX_reserved3		(__NR_POSIX + 171)
-#define __NR_POSIX_reserved4		(__NR_POSIX + 172)
-#define __NR_POSIX_reserved5		(__NR_POSIX + 173)
-#define __NR_POSIX_reserved6		(__NR_POSIX + 174)
-#define __NR_POSIX_reserved7		(__NR_POSIX + 175)
-#define __NR_POSIX_reserved8		(__NR_POSIX + 176)
-#define __NR_POSIX_reserved9		(__NR_POSIX + 177)
-#define __NR_POSIX_reserved10		(__NR_POSIX + 178)
-#define __NR_POSIX_reserved11		(__NR_POSIX + 179)
-#define __NR_POSIX_reserved12		(__NR_POSIX + 180)
-#define __NR_POSIX_reserved13		(__NR_POSIX + 181)
-#define __NR_POSIX_reserved14		(__NR_POSIX + 182)
-#define __NR_POSIX_reserved15		(__NR_POSIX + 183)
-#define __NR_POSIX_reserved16		(__NR_POSIX + 184)
-#define __NR_POSIX_reserved17		(__NR_POSIX + 185)
-#define __NR_POSIX_reserved18		(__NR_POSIX + 186)
-#define __NR_POSIX_reserved19		(__NR_POSIX + 187)
-#define __NR_POSIX_reserved20		(__NR_POSIX + 188)
-#define __NR_POSIX_reserved21		(__NR_POSIX + 189)
-#define __NR_POSIX_reserved22		(__NR_POSIX + 190)
-#define __NR_POSIX_reserved23		(__NR_POSIX + 191)
-#define __NR_POSIX_reserved24		(__NR_POSIX + 192)
-#define __NR_POSIX_reserved25		(__NR_POSIX + 193)
-#define __NR_POSIX_reserved26		(__NR_POSIX + 194)
-#define __NR_POSIX_reserved27		(__NR_POSIX + 195)
-#define __NR_POSIX_reserved28		(__NR_POSIX + 196)
-#define __NR_POSIX_reserved29		(__NR_POSIX + 197)
-#define __NR_POSIX_reserved30		(__NR_POSIX + 198)
-#define __NR_POSIX_reserved31		(__NR_POSIX + 199)
-#define __NR_POSIX_reserved32		(__NR_POSIX + 200)
-#define __NR_POSIX_reserved33		(__NR_POSIX + 201)
-#define __NR_POSIX_reserved34		(__NR_POSIX + 202)
-#define __NR_POSIX_reserved35		(__NR_POSIX + 203)
-#define __NR_POSIX_reserved36		(__NR_POSIX + 204)
-#define __NR_POSIX_reserved37		(__NR_POSIX + 205)
-#define __NR_POSIX_reserved38		(__NR_POSIX + 206)
-#define __NR_POSIX_reserved39		(__NR_POSIX + 207)
-#define __NR_POSIX_reserved40		(__NR_POSIX + 208)
-#define __NR_POSIX_reserved41		(__NR_POSIX + 209)
-#define __NR_POSIX_reserved42		(__NR_POSIX + 210)
-#define __NR_POSIX_reserved43		(__NR_POSIX + 211)
-#define __NR_POSIX_reserved44		(__NR_POSIX + 212)
-#define __NR_POSIX_reserved45		(__NR_POSIX + 213)
-#define __NR_POSIX_reserved46		(__NR_POSIX + 214)
-#define __NR_POSIX_reserved47		(__NR_POSIX + 215)
-#define __NR_POSIX_reserved48		(__NR_POSIX + 216)
-#define __NR_POSIX_reserved49		(__NR_POSIX + 217)
-#define __NR_POSIX_reserved50		(__NR_POSIX + 218)
-#define __NR_POSIX_reserved51		(__NR_POSIX + 219)
-#define __NR_POSIX_reserved52		(__NR_POSIX + 220)
-#define __NR_POSIX_reserved53		(__NR_POSIX + 221)
-#define __NR_POSIX_reserved54		(__NR_POSIX + 222)
-#define __NR_POSIX_reserved55		(__NR_POSIX + 223)
-#define __NR_POSIX_reserved56		(__NR_POSIX + 224)
-#define __NR_POSIX_reserved57		(__NR_POSIX + 225)
-#define __NR_POSIX_reserved58		(__NR_POSIX + 226)
-#define __NR_POSIX_reserved59		(__NR_POSIX + 227)
-#define __NR_POSIX_reserved60		(__NR_POSIX + 228)
-#define __NR_POSIX_reserved61		(__NR_POSIX + 229)
-#define __NR_POSIX_reserved62		(__NR_POSIX + 230)
-#define __NR_POSIX_reserved63		(__NR_POSIX + 231)
-#define __NR_POSIX_reserved64		(__NR_POSIX + 232)
-#define __NR_POSIX_reserved65		(__NR_POSIX + 233)
-#define __NR_POSIX_reserved66		(__NR_POSIX + 234)
-#define __NR_POSIX_reserved67		(__NR_POSIX + 235)
-#define __NR_POSIX_reserved68		(__NR_POSIX + 236)
-#define __NR_POSIX_reserved69		(__NR_POSIX + 237)
-#define __NR_POSIX_reserved70		(__NR_POSIX + 238)
-#define __NR_POSIX_reserved71		(__NR_POSIX + 239)
-#define __NR_POSIX_reserved72		(__NR_POSIX + 240)
-#define __NR_POSIX_reserved73		(__NR_POSIX + 241)
-#define __NR_POSIX_reserved74		(__NR_POSIX + 242)
-#define __NR_POSIX_reserved75		(__NR_POSIX + 243)
-#define __NR_POSIX_reserved76		(__NR_POSIX + 244)
-#define __NR_POSIX_reserved77		(__NR_POSIX + 245)
-#define __NR_POSIX_reserved78		(__NR_POSIX + 246)
-#define __NR_POSIX_reserved79		(__NR_POSIX + 247)
-#define __NR_POSIX_reserved80		(__NR_POSIX + 248)
-#define __NR_POSIX_reserved81		(__NR_POSIX + 249)
-#define __NR_POSIX_reserved82		(__NR_POSIX + 250)
-#define __NR_POSIX_reserved83		(__NR_POSIX + 251)
-#define __NR_POSIX_reserved84		(__NR_POSIX + 252)
-#define __NR_POSIX_reserved85		(__NR_POSIX + 253)
-#define __NR_POSIX_reserved86		(__NR_POSIX + 254)
-#define __NR_POSIX_reserved87		(__NR_POSIX + 255)
-#define __NR_POSIX_reserved88		(__NR_POSIX + 256)
-#define __NR_POSIX_reserved89		(__NR_POSIX + 257)
-#define __NR_POSIX_reserved90		(__NR_POSIX + 258)
-#define __NR_POSIX_reserved91		(__NR_POSIX + 259)
-#define __NR_POSIX_netboot		(__NR_POSIX + 260)
-#define __NR_POSIX_netunboot		(__NR_POSIX + 261)
-#define __NR_POSIX_rdump		(__NR_POSIX + 262)
-#define __NR_POSIX_setsid		(__NR_POSIX + 263)
-#define __NR_POSIX_getmaxsig		(__NR_POSIX + 264)
-#define __NR_POSIX_sigpending		(__NR_POSIX + 265)
-#define __NR_POSIX_sigprocmask		(__NR_POSIX + 266)
-#define __NR_POSIX_sigsuspend		(__NR_POSIX + 267)
-#define __NR_POSIX_sigaction		(__NR_POSIX + 268)
-#define __NR_POSIX_MIPS_reserved1	(__NR_POSIX + 269)
-#define __NR_POSIX_MIPS_reserved2	(__NR_POSIX + 270)
-#define __NR_POSIX_MIPS_reserved3	(__NR_POSIX + 271)
-#define __NR_POSIX_MIPS_reserved4	(__NR_POSIX + 272)
-#define __NR_POSIX_MIPS_reserved5	(__NR_POSIX + 273)
-#define __NR_POSIX_MIPS_reserved6	(__NR_POSIX + 274)
-#define __NR_POSIX_MIPS_reserved7	(__NR_POSIX + 275)
-#define __NR_POSIX_MIPS_reserved8	(__NR_POSIX + 276)
-#define __NR_POSIX_MIPS_reserved9	(__NR_POSIX + 277)
-#define __NR_POSIX_MIPS_reserved10	(__NR_POSIX + 278)
-#define __NR_POSIX_MIPS_reserved11	(__NR_POSIX + 279)
-#define __NR_POSIX_TANDEM_reserved1	(__NR_POSIX + 280)
-#define __NR_POSIX_TANDEM_reserved2	(__NR_POSIX + 281)
-#define __NR_POSIX_TANDEM_reserved3	(__NR_POSIX + 282)
-#define __NR_POSIX_TANDEM_reserved4	(__NR_POSIX + 283)
-#define __NR_POSIX_TANDEM_reserved5	(__NR_POSIX + 284)
-#define __NR_POSIX_TANDEM_reserved6	(__NR_POSIX + 285)
-#define __NR_POSIX_TANDEM_reserved7	(__NR_POSIX + 286)
-#define __NR_POSIX_TANDEM_reserved8	(__NR_POSIX + 287)
-#define __NR_POSIX_TANDEM_reserved9	(__NR_POSIX + 288)
-#define __NR_POSIX_TANDEM_reserved10	(__NR_POSIX + 289)
-#define __NR_POSIX_TANDEM_reserved11	(__NR_POSIX + 290)
-#define __NR_POSIX_TANDEM_reserved12	(__NR_POSIX + 291)
-#define __NR_POSIX_TANDEM_reserved13	(__NR_POSIX + 292)
-#define __NR_POSIX_TANDEM_reserved14	(__NR_POSIX + 293)
-#define __NR_POSIX_TANDEM_reserved15	(__NR_POSIX + 294)
-#define __NR_POSIX_TANDEM_reserved16	(__NR_POSIX + 295)
-#define __NR_POSIX_TANDEM_reserved17	(__NR_POSIX + 296)
-#define __NR_POSIX_TANDEM_reserved18	(__NR_POSIX + 297)
-#define __NR_POSIX_TANDEM_reserved19	(__NR_POSIX + 298)
-#define __NR_POSIX_TANDEM_reserved20	(__NR_POSIX + 299)
-#define __NR_POSIX_SGI_reserved7	(__NR_POSIX + 300)
-#define __NR_POSIX_SGI_reserved8	(__NR_POSIX + 301)
-#define __NR_POSIX_SGI_reserved9	(__NR_POSIX + 302)
-#define __NR_POSIX_SGI_reserved10	(__NR_POSIX + 303)
-#define __NR_POSIX_SGI_reserved11	(__NR_POSIX + 304)
-#define __NR_POSIX_SGI_reserved12	(__NR_POSIX + 305)
-#define __NR_POSIX_SGI_reserved13	(__NR_POSIX + 306)
-#define __NR_POSIX_SGI_reserved14	(__NR_POSIX + 307)
-#define __NR_POSIX_SGI_reserved15	(__NR_POSIX + 308)
-#define __NR_POSIX_SGI_reserved16	(__NR_POSIX + 309)
-#define __NR_POSIX_SGI_reserved17	(__NR_POSIX + 310)
-#define __NR_POSIX_SGI_reserved18	(__NR_POSIX + 311)
-#define __NR_POSIX_SGI_reserved19	(__NR_POSIX + 312)
-#define __NR_POSIX_SGI_reserved20	(__NR_POSIX + 313)
-#define __NR_POSIX_SGI_reserved21	(__NR_POSIX + 314)
-#define __NR_POSIX_SGI_reserved22	(__NR_POSIX + 315)
-#define __NR_POSIX_SGI_reserved23	(__NR_POSIX + 316)
-#define __NR_POSIX_SGI_reserved24	(__NR_POSIX + 317)
-#define __NR_POSIX_SGI_reserved25	(__NR_POSIX + 318)
-#define __NR_POSIX_SGI_reserved26	(__NR_POSIX + 319)
-
-#endif /* _ASM_RISCOS_SYSCALL_H */
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h
index 983e9a2..64ebd08 100644
--- a/include/asm-parisc/atomic.h
+++ b/include/asm-parisc/atomic.h
@@ -216,4 +216,5 @@
 #define smp_mb__before_atomic_inc()	smp_mb()
 #define smp_mb__after_atomic_inc()	smp_mb()
 
+#include <asm-generic/atomic.h>
 #endif
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
index 55b98c6..15d8c2b 100644
--- a/include/asm-parisc/bitops.h
+++ b/include/asm-parisc/bitops.h
@@ -263,6 +263,7 @@
 
 	return ret;
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
diff --git a/include/asm-parisc/cache.h b/include/asm-parisc/cache.h
index 5da72e3..38d201b 100644
--- a/include/asm-parisc/cache.h
+++ b/include/asm-parisc/cache.h
@@ -28,7 +28,6 @@
 #define L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
 
 #define SMP_CACHE_BYTES L1_CACHE_BYTES
-#define L1_CACHE_SHIFT_MAX 5	/* largest L1 which this arch supports */
 
 extern void flush_data_cache_local(void);  /* flushes local data-cache only */
 extern void flush_instruction_cache_local(void); /* flushes local code-cache only */
diff --git a/include/asm-parisc/futex.h b/include/asm-parisc/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-parisc/futex.h
+++ b/include/asm-parisc/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-parisc/mman.h b/include/asm-parisc/mman.h
index e829607..736b0ab 100644
--- a/include/asm-parisc/mman.h
+++ b/include/asm-parisc/mman.h
@@ -38,6 +38,7 @@
 #define MADV_SPACEAVAIL 5               /* insure that resources are reserved */
 #define MADV_VPS_PURGE  6               /* Purge pages from VM page cache */
 #define MADV_VPS_INHERIT 7              /* Inherit parents page size */
+#define MADV_REMOVE     8		/* remove these pages & resources */
 
 /* The range 12-64 is reserved for page size specification. */
 #define MADV_4K_PAGES   12              /* Use 4K pages  */
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index ec4b144..ae395a0 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -402,5 +402,6 @@
 
 #endif /* __powerpc64__ */
 
+#include <asm-generic/atomic.h>
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_ATOMIC_H_ */
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index 5727229..1996eaa 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -310,6 +310,7 @@
 	asm ("cntlzw %0,%1" : "=r" (lz) : "r" (x));
 	return 32 - lz;
 }
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
diff --git a/include/asm-powerpc/cache.h b/include/asm-powerpc/cache.h
index 26ce502..6379c2d 100644
--- a/include/asm-powerpc/cache.h
+++ b/include/asm-powerpc/cache.h
@@ -19,7 +19,6 @@
 #define	L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
 #define	SMP_CACHE_BYTES		L1_CACHE_BYTES
-#define L1_CACHE_SHIFT_MAX	7 /* largest L1 which this arch supports */
 
 #if defined(__powerpc64__) && !defined(__ASSEMBLY__)
 struct ppc64_caches {
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 59a8016..a96e574 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -229,7 +229,7 @@
 #ifdef CONFIG_PPC64
 	/* no easy way to get cache size on all processors, so return
 	 * the maximum possible, to be safe */
-	return (1 << L1_CACHE_SHIFT_MAX);
+	return (1 << INTERNODE_CACHE_SHIFT);
 #else
 	/*
 	 * Each processor family will define its own L1_CACHE_SHIFT,
diff --git a/include/asm-powerpc/mman.h b/include/asm-powerpc/mman.h
index f5e5342..a2e34c2 100644
--- a/include/asm-powerpc/mman.h
+++ b/include/asm-powerpc/mman.h
@@ -44,6 +44,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h
index c1b4bba..29b0bb0 100644
--- a/include/asm-powerpc/mmu.h
+++ b/include/asm-powerpc/mmu.h
@@ -220,7 +220,8 @@
 			   unsigned int local);
 struct mm_struct;
 extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
-			  unsigned long ea, unsigned long vsid, int local);
+			  unsigned long ea, unsigned long vsid, int local,
+			  unsigned long trap);
 
 extern void htab_finish_init(void);
 extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
diff --git a/include/asm-ppc/ibm_ocp.h b/include/asm-ppc/ibm_ocp.h
index 9c21de1..ddce616 100644
--- a/include/asm-ppc/ibm_ocp.h
+++ b/include/asm-ppc/ibm_ocp.h
@@ -63,7 +63,6 @@
 	int	wol_irq;	/* WOL interrupt */
 	int	mdio_idx;	/* EMAC idx of MDIO master or -1 */
 	int	tah_idx;	/* TAH device index or -1 */
-	int	jumbo;		/* Jumbo frames capable flag */
 	int	phy_mode;	/* PHY type or configurable mode */
 	u8	mac_addr[6];	/* EMAC mac address */
 	u32	phy_map;	/* EMAC phy map */
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index 84ac6e2..df9cf6e 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -27,6 +27,8 @@
 
 #if defined(CONFIG_4xx)
 #include <asm/ibm4xx.h>
+#elif defined(CONFIG_PPC_MPC52xx)
+#include <asm/mpc52xx.h>
 #elif defined(CONFIG_8xx)
 #include <asm/mpc8xx.h>
 #elif defined(CONFIG_8260)
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index e5f80c2..a055e07 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -29,6 +29,17 @@
 #endif /* __ASSEMBLY__ */
 
 
+#ifdef CONFIG_PCI
+#define _IO_BASE	isa_io_base
+#define _ISA_MEM_BASE	isa_mem_base
+#define PCI_DRAM_OFFSET	pci_dram_offset
+#else
+#define _IO_BASE	0
+#define _ISA_MEM_BASE	0
+#define PCI_DRAM_OFFSET	0
+#endif
+
+
 /* ======================================================================== */
 /* PPC Sys devices definition                                               */
 /* ======================================================================== */
@@ -107,7 +118,7 @@
 #define MPC52xx_SDMA_IRQ_NUM	17
 #define MPC52xx_PERP_IRQ_NUM	23
 
-#define MPC52xx_CRIT_IRQ_BASE	0
+#define MPC52xx_CRIT_IRQ_BASE	1
 #define MPC52xx_MAIN_IRQ_BASE	(MPC52xx_CRIT_IRQ_BASE + MPC52xx_CRIT_IRQ_NUM)
 #define MPC52xx_SDMA_IRQ_BASE	(MPC52xx_MAIN_IRQ_BASE + MPC52xx_MAIN_IRQ_NUM)
 #define MPC52xx_PERP_IRQ_BASE	(MPC52xx_SDMA_IRQ_BASE + MPC52xx_SDMA_IRQ_NUM)
diff --git a/include/asm-ppc/ppc4xx_dma.h b/include/asm-ppc/ppc4xx_dma.h
index a415001..46a086f 100644
--- a/include/asm-ppc/ppc4xx_dma.h
+++ b/include/asm-ppc/ppc4xx_dma.h
@@ -33,9 +33,6 @@
 
 #define MAX_PPC4xx_DMA_CHANNELS		4
 
-/* in arch/ppc/kernel/setup.c -- Cort */
-extern unsigned long DMA_MODE_WRITE, DMA_MODE_READ;
-
 /*
  * Function return status codes
  * These values are used to indicate whether or not the function
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h
index b3bd4f6..d82aedf 100644
--- a/include/asm-s390/atomic.h
+++ b/include/asm-s390/atomic.h
@@ -5,7 +5,7 @@
  *  include/asm-s390/atomic.h
  *
  *  S390 version
- *    Copyright (C) 1999-2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
  *               Denis Joseph Barrow,
  *		 Arnd Bergmann (arndb@de.ibm.com)
@@ -45,59 +45,57 @@
 #define atomic_read(v)          ((v)->counter)
 #define atomic_set(v,i)         (((v)->counter) = (i))
 
-static __inline__ void atomic_add(int i, atomic_t * v)
-{
-	       __CS_LOOP(v, i, "ar");
-}
 static __inline__ int atomic_add_return(int i, atomic_t * v)
 {
 	return __CS_LOOP(v, i, "ar");
 }
-static __inline__ int atomic_add_negative(int i, atomic_t * v)
-{
-	return __CS_LOOP(v, i, "ar") < 0;
-}
-static __inline__ void atomic_sub(int i, atomic_t * v)
-{
-	       __CS_LOOP(v, i, "sr");
-}
+#define atomic_add(_i, _v)		atomic_add_return(_i, _v)
+#define atomic_add_negative(_i, _v)	(atomic_add_return(_i, _v) < 0)
+#define atomic_inc(_v)			atomic_add_return(1, _v)
+#define atomic_inc_return(_v)		atomic_add_return(1, _v)
+#define atomic_inc_and_test(_v)		(atomic_add_return(1, _v) == 0)
+
 static __inline__ int atomic_sub_return(int i, atomic_t * v)
 {
 	return __CS_LOOP(v, i, "sr");
 }
-static __inline__ void atomic_inc(volatile atomic_t * v)
-{
-	       __CS_LOOP(v, 1, "ar");
-}
-static __inline__ int atomic_inc_return(volatile atomic_t * v)
-{
-	return __CS_LOOP(v, 1, "ar");
-}
+#define atomic_sub(_i, _v)		atomic_sub_return(_i, _v)
+#define atomic_sub_and_test(_i, _v)	(atomic_sub_return(_i, _v) == 0)
+#define atomic_dec(_v)			atomic_sub_return(1, _v)
+#define atomic_dec_return(_v)		atomic_sub_return(1, _v)
+#define atomic_dec_and_test(_v)		(atomic_sub_return(1, _v) == 0)
 
-static __inline__ int atomic_inc_and_test(volatile atomic_t * v)
-{
-	return __CS_LOOP(v, 1, "ar") == 0;
-}
-static __inline__ void atomic_dec(volatile atomic_t * v)
-{
-	       __CS_LOOP(v, 1, "sr");
-}
-static __inline__ int atomic_dec_return(volatile atomic_t * v)
-{
-	return __CS_LOOP(v, 1, "sr");
-}
-static __inline__ int atomic_dec_and_test(volatile atomic_t * v)
-{
-	return __CS_LOOP(v, 1, "sr") == 0;
-}
 static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v)
 {
 	       __CS_LOOP(v, ~mask, "nr");
 }
+
 static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v)
 {
 	       __CS_LOOP(v, mask, "or");
 }
+
+static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	__asm__ __volatile__("  cs   %0,%3,0(%2)\n"
+			     : "+d" (old), "=m" (v->counter)
+			     : "a" (v), "d" (new), "m" (v->counter)
+			     : "cc", "memory" );
+	return old;
+}
+
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int c, old;
+
+	c = atomic_read(v);
+	while (c != u && (old = atomic_cmpxchg(v, c, c + a)) != c)
+		c = old;
+	return c != u;
+}
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
 #undef __CS_LOOP
 
 #ifdef __s390x__
@@ -123,97 +121,67 @@
 #define atomic64_read(v)          ((v)->counter)
 #define atomic64_set(v,i)         (((v)->counter) = (i))
 
-static __inline__ void atomic64_add(long long i, atomic64_t * v)
-{
-	       __CSG_LOOP(v, i, "agr");
-}
 static __inline__ long long atomic64_add_return(long long i, atomic64_t * v)
 {
 	return __CSG_LOOP(v, i, "agr");
 }
-static __inline__ long long atomic64_add_negative(long long i, atomic64_t * v)
+#define atomic64_add(_i, _v)		atomic64_add_return(_i, _v)
+#define atomic64_add_negative(_i, _v)	(atomic64_add_return(_i, _v) < 0)
+#define atomic64_inc(_v)		atomic64_add_return(1, _v)
+#define atomic64_inc_return(_v)		atomic64_add_return(1, _v)
+#define atomic64_inc_and_test(_v)	(atomic64_add_return(1, _v) == 0)
+
+static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v)
 {
-	return __CSG_LOOP(v, i, "agr") < 0;
+	return __CSG_LOOP(v, i, "sgr");
 }
-static __inline__ void atomic64_sub(long long i, atomic64_t * v)
-{
-	       __CSG_LOOP(v, i, "sgr");
-}
-static __inline__ void atomic64_inc(volatile atomic64_t * v)
-{
-	       __CSG_LOOP(v, 1, "agr");
-}
-static __inline__ long long atomic64_inc_return(volatile atomic64_t * v)
-{
-	return __CSG_LOOP(v, 1, "agr");
-}
-static __inline__ long long atomic64_inc_and_test(volatile atomic64_t * v)
-{
-	return __CSG_LOOP(v, 1, "agr") == 0;
-}
-static __inline__ void atomic64_dec(volatile atomic64_t * v)
-{
-	       __CSG_LOOP(v, 1, "sgr");
-}
-static __inline__ long long atomic64_dec_return(volatile atomic64_t * v)
-{
-	return __CSG_LOOP(v, 1, "sgr");
-}
-static __inline__ long long atomic64_dec_and_test(volatile atomic64_t * v)
-{
-	return __CSG_LOOP(v, 1, "sgr") == 0;
-}
+#define atomic64_sub(_i, _v)		atomic64_sub_return(_i, _v)
+#define atomic64_sub_and_test(_i, _v)	(atomic64_sub_return(_i, _v) == 0)
+#define atomic64_dec(_v)		atomic64_sub_return(1, _v)
+#define atomic64_dec_return(_v)		atomic64_sub_return(1, _v)
+#define atomic64_dec_and_test(_v)	(atomic64_sub_return(1, _v) == 0)
+
 static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v)
 {
 	       __CSG_LOOP(v, ~mask, "ngr");
 }
+
 static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v)
 {
 	       __CSG_LOOP(v, mask, "ogr");
 }
 
-#undef __CSG_LOOP
-#endif
-
-/*
-  returns 0  if expected_oldval==value in *v ( swap was successful )
-  returns 1  if unsuccessful.
-
-  This is non-portable, use bitops or spinlocks instead!
-*/
-static __inline__ int
-atomic_compare_and_swap(int expected_oldval,int new_val,atomic_t *v)
+static __inline__ long long atomic64_cmpxchg(atomic64_t *v,
+					     long long old, long long new)
 {
-        int retval;
-
-        __asm__ __volatile__(
-                "  lr   %0,%3\n"
-                "  cs   %0,%4,0(%2)\n"
-                "  ipm  %0\n"
-                "  srl  %0,28\n"
-                "0:"
-                : "=&d" (retval), "=m" (v->counter)
-                : "a" (v), "d" (expected_oldval) , "d" (new_val),
-		  "m" (v->counter) : "cc", "memory" );
-        return retval;
+	__asm__ __volatile__("  csg  %0,%3,0(%2)\n"
+			     : "+d" (old), "=m" (v->counter)
+			     : "a" (v), "d" (new), "m" (v->counter)
+			     : "cc", "memory" );
+	return old;
 }
 
-#define atomic_cmpxchg(v, o, n) (atomic_compare_and_swap((o), (n), &((v)->counter)))
+static __inline__ int atomic64_add_unless(atomic64_t *v,
+					  long long a, long long u)
+{
+	long long c, old;
 
-#define atomic_add_unless(v, a, u)				\
-({								\
-	int c, old;						\
-	c = atomic_read(v);					\
-	while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \
-		c = old;					\
-	c != (u);						\
-})
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+	c = atomic64_read(v);
+	while (c != u && (old = atomic64_cmpxchg(v, c, c + a)) != c)
+		c = old;
+	return c != u;
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
+#undef __CSG_LOOP
+#endif
 
 #define smp_mb__before_atomic_dec()	smp_mb()
 #define smp_mb__after_atomic_dec()	smp_mb()
 #define smp_mb__before_atomic_inc()	smp_mb()
 #define smp_mb__after_atomic_inc()	smp_mb()
 
+#include <asm-generic/atomic.h>
 #endif /* __KERNEL__ */
 #endif /* __ARCH_S390_ATOMIC__  */
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index b07c578..6123276 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -839,6 +839,7 @@
  * fls: find last bit set.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
diff --git a/include/asm-s390/cache.h b/include/asm-s390/cache.h
index 2984537..e20cdd9 100644
--- a/include/asm-s390/cache.h
+++ b/include/asm-s390/cache.h
@@ -13,7 +13,6 @@
 
 #define L1_CACHE_BYTES     256
 #define L1_CACHE_SHIFT     8
-#define L1_CACHE_SHIFT_MAX 8	/* largest L1 which this arch supports */
 
 #define ARCH_KMALLOC_MINALIGN	8
 
diff --git a/include/asm-s390/ccwdev.h b/include/asm-s390/ccwdev.h
index 3eb231a..12456cb 100644
--- a/include/asm-s390/ccwdev.h
+++ b/include/asm-s390/ccwdev.h
@@ -185,8 +185,5 @@
 extern int _ccw_device_get_device_number(struct ccw_device *);
 extern int _ccw_device_get_subchannel_number(struct ccw_device *);
 
-extern struct device *s390_root_dev_register(const char *);
-extern void s390_root_dev_unregister(struct device *);
-
 extern void *ccw_device_get_chp_desc(struct ccw_device *, int);
 #endif /* _S390_CCWDEV_H_ */
diff --git a/include/asm-s390/futex.h b/include/asm-s390/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-s390/futex.h
+++ b/include/asm-s390/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-s390/mman.h b/include/asm-s390/mman.h
index ea86bd1..c8d5409 100644
--- a/include/asm-s390/mman.h
+++ b/include/asm-s390/mman.h
@@ -43,6 +43,7 @@
 #define MADV_SEQUENTIAL        0x2             /* read-ahead aggressively */
 #define MADV_WILLNEED  0x3              /* pre-fault pages */
 #define MADV_DONTNEED  0x4              /* discard these pages */
+#define MADV_REMOVE    0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h
index 0ddf0a8..7bc15f0 100644
--- a/include/asm-s390/qdio.h
+++ b/include/asm-s390/qdio.h
@@ -195,12 +195,14 @@
 /*
  * queue information block (QIB)
  */
-#define QIB_AC_INBOUND_PCI_SUPPORTED 0x80
-#define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40
+#define QIB_AC_INBOUND_PCI_SUPPORTED 	0x80
+#define QIB_AC_OUTBOUND_PCI_SUPPORTED 	0x40
+#define QIB_RFLAGS_ENABLE_QEBSM		0x80
+
 struct qib {
 	unsigned int  qfmt    :  8;     /* queue format */
 	unsigned int  pfmt    :  8;     /* impl. dep. parameter format */
-	unsigned int  res1    :  8;     /* reserved */
+	unsigned int  rflags  :  8;	/* QEBSM */
 	unsigned int  ac      :  8;     /* adapter characteristics */
 	unsigned int  res2;             /* reserved */
 #ifdef QDIO_32_BIT
diff --git a/include/asm-s390/s390_rdev.h b/include/asm-s390/s390_rdev.h
new file mode 100644
index 0000000..3ad78f2
--- /dev/null
+++ b/include/asm-s390/s390_rdev.h
@@ -0,0 +1,15 @@
+/*
+ *  include/asm-s390/ccwdev.h
+ *
+ *    Copyright (C) 2002,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Cornelia Huck <cohuck@de.ibm.com>
+ *               Carsten Otte  <cotte@de.ibm.com>
+ *
+ *  Interface for s390 root device
+ */
+
+#ifndef _S390_RDEV_H_
+#define _S390_RDEV_H_
+extern struct device *s390_root_dev_register(const char *);
+extern void s390_root_dev_unregister(struct device *);
+#endif /* _S390_RDEV_H_ */
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h
index 10a619d..be104f2 100644
--- a/include/asm-s390/uaccess.h
+++ b/include/asm-s390/uaccess.h
@@ -61,8 +61,10 @@
 #define segment_eq(a,b) ((a).ar4 == (b).ar4)
 
 
-#define __access_ok(addr,size) (1)
-
+static inline int __access_ok(const void *addr, unsigned long size)
+{
+	return 1;
+}
 #define access_ok(type,addr,size) __access_ok(addr,size)
 
 /*
@@ -206,25 +208,25 @@
 	case 1: {						\
 		unsigned char __x;				\
 		__get_user_asm(__x, ptr, __gu_err);		\
-		(x) = (__typeof__(*(ptr))) __x;			\
+		(x) = *(__typeof__(*(ptr)) *) &__x;		\
 		break;						\
 	};							\
 	case 2: {						\
 		unsigned short __x;				\
 		__get_user_asm(__x, ptr, __gu_err);		\
-		(x) = (__typeof__(*(ptr))) __x;			\
+		(x) = *(__typeof__(*(ptr)) *) &__x;		\
 		break;						\
 	};							\
 	case 4: {						\
 		unsigned int __x;				\
 		__get_user_asm(__x, ptr, __gu_err);		\
-		(x) = (__typeof__(*(ptr))) __x;			\
+		(x) = *(__typeof__(*(ptr)) *) &__x;		\
 		break;						\
 	};							\
 	case 8: {						\
 		unsigned long long __x;				\
 		__get_user_asm(__x, ptr, __gu_err);		\
-		(x) = (__typeof__(*(ptr))) __x;			\
+		(x) = *(__typeof__(*(ptr)) *) &__x;		\
 		break;						\
 	};							\
 	default:						\
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h
index f97d926..2861cdc 100644
--- a/include/asm-s390/unistd.h
+++ b/include/asm-s390/unistd.h
@@ -539,7 +539,7 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
-# ifdef CONFIG_ARCH_S390_31
+# ifndef CONFIG_64BIT
 #   define __ARCH_WANT_STAT64
 #   define __ARCH_WANT_SYS_TIME
 # endif
diff --git a/include/asm-s390/vtoc.h b/include/asm-s390/vtoc.h
index 41d369f..d1de5b7 100644
--- a/include/asm-s390/vtoc.h
+++ b/include/asm-s390/vtoc.h
@@ -176,4 +176,28 @@
 	struct vtoc_cchhb DS7PTRDS; /* pointer to next FMT7 DSCB */
 } __attribute__ ((packed));
 
+struct vtoc_cms_label {
+	u8 label_id[4];		/* Label identifier */
+	u8 vol_id[6];		/* Volid */
+	u16 version_id;		/* Version identifier */
+	u32 block_size;		/* Disk block size */
+	u32 origin_ptr;		/* Disk origin pointer */
+	u32 usable_count;	/* Number of usable cylinders/blocks */
+	u32 formatted_count;	/* Maximum number of formatted cylinders/
+				 * blocks */
+	u32 block_count;	/* Disk size in CMS blocks */
+	u32 used_count;		/* Number of CMS blocks in use */
+	u32 fst_size;		/* File Status Table (FST) size */
+	u32 fst_count;		/* Number of FSTs per CMS block */
+	u8 format_date[6];	/* Disk FORMAT date */
+	u8 reserved1[2];
+	u32 disk_offset;	/* Disk offset when reserved*/
+	u32 map_block;		/* Allocation Map Block with next hole */
+	u32 hblk_disp;		/* Displacement into HBLK data of next hole */
+	u32 user_disp;		/* Displacement into user part of Allocation
+				 * map */
+	u8 reserved2[4];
+	u8 segment_name[8];	/* Name of shared segment */
+} __attribute__ ((packed));
+
 #endif /* _ASM_S390_VTOC_H */
diff --git a/include/asm-sh/atomic.h b/include/asm-sh/atomic.h
index aabfd33..618d8e0 100644
--- a/include/asm-sh/atomic.h
+++ b/include/asm-sh/atomic.h
@@ -140,4 +140,5 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif /* __ASM_SH_ATOMIC_H */
diff --git a/include/asm-sh/bitops.h b/include/asm-sh/bitops.h
index 5163d1f..1c52608 100644
--- a/include/asm-sh/bitops.h
+++ b/include/asm-sh/bitops.h
@@ -470,6 +470,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-sh/cache.h b/include/asm-sh/cache.h
index 9b4dd6d..656fdfe 100644
--- a/include/asm-sh/cache.h
+++ b/include/asm-sh/cache.h
@@ -22,8 +22,6 @@
 
 #define L1_CACHE_ALIGN(x)	(((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
 
-#define L1_CACHE_SHIFT_MAX 	5	/* largest L1 which this arch supports */
-
 struct cache_info {
 	unsigned int ways;
 	unsigned int sets;
diff --git a/include/asm-sh/futex.h b/include/asm-sh/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-sh/futex.h
+++ b/include/asm-sh/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-sh/mman.h b/include/asm-sh/mman.h
index 3ebab5f..693bd55 100644
--- a/include/asm-sh/mman.h
+++ b/include/asm-sh/mman.h
@@ -35,6 +35,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-sh64/atomic.h b/include/asm-sh64/atomic.h
index 927a2bc..f3ce5c0 100644
--- a/include/asm-sh64/atomic.h
+++ b/include/asm-sh64/atomic.h
@@ -152,4 +152,5 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif /* __ASM_SH64_ATOMIC_H */
diff --git a/include/asm-sh64/bitops.h b/include/asm-sh64/bitops.h
index e1ff63e..ce9c3ad 100644
--- a/include/asm-sh64/bitops.h
+++ b/include/asm-sh64/bitops.h
@@ -510,6 +510,7 @@
 
 #define ffs(x)	generic_ffs(x)
 #define fls(x)	generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #endif /* __KERNEL__ */
 
diff --git a/include/asm-sh64/cache.h b/include/asm-sh64/cache.h
index f54e85e..a4f36f0 100644
--- a/include/asm-sh64/cache.h
+++ b/include/asm-sh64/cache.h
@@ -20,8 +20,6 @@
 #define L1_CACHE_ALIGN_MASK	(~(L1_CACHE_BYTES - 1))
 #define L1_CACHE_ALIGN(x)	(((x)+(L1_CACHE_BYTES - 1)) & L1_CACHE_ALIGN_MASK)
 #define L1_CACHE_SIZE_BYTES	(L1_CACHE_BYTES << 10)
-/* Largest L1 which this arch supports */
-#define L1_CACHE_SHIFT_MAX	5
 
 #ifdef MODULE
 #define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
diff --git a/include/asm-sh64/futex.h b/include/asm-sh64/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-sh64/futex.h
+++ b/include/asm-sh64/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h
index 62bec7a..accb496 100644
--- a/include/asm-sparc/atomic.h
+++ b/include/asm-sparc/atomic.h
@@ -159,4 +159,5 @@
 
 #endif /* !(__KERNEL__) */
 
+#include <asm-generic/atomic.h>
 #endif /* !(__ARCH_SPARC_ATOMIC__) */
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
index bfbd795..41722b5 100644
--- a/include/asm-sparc/bitops.h
+++ b/include/asm-sparc/bitops.h
@@ -298,6 +298,7 @@
  * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
  */
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
diff --git a/include/asm-sparc/cache.h b/include/asm-sparc/cache.h
index a10522c..cb971e8 100644
--- a/include/asm-sparc/cache.h
+++ b/include/asm-sparc/cache.h
@@ -13,7 +13,6 @@
 #define L1_CACHE_SHIFT 5
 #define L1_CACHE_BYTES 32
 #define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)))
-#define L1_CACHE_SHIFT_MAX 5	/* largest L1 which this arch supports */
 
 #define SMP_CACHE_BYTES 32
 
diff --git a/include/asm-sparc/futex.h b/include/asm-sparc/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-sparc/futex.h
+++ b/include/asm-sparc/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-sparc/memreg.h b/include/asm-sparc/memreg.h
index c0498d3..5fb95c8 100644
--- a/include/asm-sparc/memreg.h
+++ b/include/asm-sparc/memreg.h
@@ -36,7 +36,7 @@
 
 /* Memory parity error register with associated bit constants. */
 #ifndef __ASSEMBLY__
-extern __volatile__ unsigned long *sun4c_memerr_reg;
+extern __volatile__ unsigned long __iomem *sun4c_memerr_reg;
 #endif
 
 #define	SUN4C_MPE_ERROR	0x80	/* Parity error detected. (ro) */
diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
index 138eb81..98435ad 100644
--- a/include/asm-sparc/mman.h
+++ b/include/asm-sparc/mman.h
@@ -54,6 +54,7 @@
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
 #define MADV_FREE	0x5		/* (Solaris) contents can be freed */
+#define MADV_REMOVE	0x6		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-sparc/pcic.h b/include/asm-sparc/pcic.h
index 301ae80..dedea14 100644
--- a/include/asm-sparc/pcic.h
+++ b/include/asm-sparc/pcic.h
@@ -16,10 +16,10 @@
 #include <asm/pbm.h>
 
 struct linux_pcic {
-        void * __iomem          pcic_regs;
+        void __iomem            *pcic_regs;
         unsigned long           pcic_io;
-        void * __iomem          pcic_config_space_addr;
-        void * __iomem          pcic_config_space_data;
+        void __iomem            *pcic_config_space_addr;
+        void __iomem            *pcic_config_space_data;
 	struct resource		pcic_res_regs;
 	struct resource		pcic_res_io;
 	struct resource		pcic_res_cfg_addr;
diff --git a/include/asm-sparc64/atomic.h b/include/asm-sparc64/atomic.h
index 3789fe3..11f5aa5 100644
--- a/include/asm-sparc64/atomic.h
+++ b/include/asm-sparc64/atomic.h
@@ -96,4 +96,5 @@
 #define smp_mb__after_atomic_inc()	barrier()
 #endif
 
+#include <asm-generic/atomic.h>
 #endif /* !(__ARCH_SPARC64_ATOMIC__) */
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
index 6388b83..6efc016 100644
--- a/include/asm-sparc64/bitops.h
+++ b/include/asm-sparc64/bitops.h
@@ -119,6 +119,7 @@
  */
 
 #define fls(x) generic_fls(x)
+#define fls64(x)   generic_fls64(x)
 
 #ifdef __KERNEL__
 
diff --git a/include/asm-sparc64/cache.h b/include/asm-sparc64/cache.h
index ade5ec3..f7d35a2 100644
--- a/include/asm-sparc64/cache.h
+++ b/include/asm-sparc64/cache.h
@@ -9,7 +9,6 @@
 #define        L1_CACHE_BYTES	32 /* Two 16-byte sub-blocks per line. */
 
 #define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
-#define		L1_CACHE_SHIFT_MAX 5	/* largest L1 which this arch supports */
 
 #define        SMP_CACHE_BYTES_SHIFT	6
 #define        SMP_CACHE_BYTES		(1 << SMP_CACHE_BYTES_SHIFT) /* L2 cache line size. */
diff --git a/include/asm-sparc64/futex.h b/include/asm-sparc64/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-sparc64/futex.h
+++ b/include/asm-sparc64/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h
index 01cecf5..cb4b615 100644
--- a/include/asm-sparc64/mman.h
+++ b/include/asm-sparc64/mman.h
@@ -54,6 +54,7 @@
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
 #define MADV_FREE	0x5		/* (Solaris) contents can be freed */
+#define MADV_REMOVE	0x6		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 9a02879..f0a9b44 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -348,16 +348,6 @@
 struct vm_area_struct;
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
-/* Make a non-present pseudo-TTE. */
-static inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space)
-{
-	pte_t pte;
-	pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E) &
-			~(unsigned long)_PAGE_CACHE);
-	pte_val(pte) |= (((unsigned long)space) << 32);
-	return pte;
-}
-
 /* Encode and de-code a swap entry */
 #define __swp_type(entry)	(((entry).val >> PAGE_SHIFT) & 0xffUL)
 #define __swp_offset(entry)	((entry).val >> (PAGE_SHIFT + 8UL))
diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
index b541752..309f146 100644
--- a/include/asm-sparc64/system.h
+++ b/include/asm-sparc64/system.h
@@ -193,11 +193,7 @@
 	 * not preserve it's value.  Hairy, but it lets us remove 2 loads
 	 * and 2 stores in this critical code path.  -DaveM
 	 */
-#if __GNUC__ >= 3
 #define EXTRA_CLOBBER ,"%l1"
-#else
-#define EXTRA_CLOBBER
-#endif
 #define switch_to(prev, next, last)					\
 do {	if (test_thread_flag(TIF_PERFCTR)) {				\
 		unsigned long __tmp;					\
diff --git a/include/asm-um/cache.h b/include/asm-um/cache.h
index a10602a..3d05870 100644
--- a/include/asm-um/cache.h
+++ b/include/asm-um/cache.h
@@ -13,9 +13,6 @@
 # define L1_CACHE_SHIFT		5
 #endif
 
-/* XXX: this is valid for x86 and x86_64. */
-#define L1_CACHE_SHIFT_MAX	7	/* largest L1 which this arch supports */
-
 #define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
 
 #endif
diff --git a/include/asm-um/futex.h b/include/asm-um/futex.h
index 142ee2d..6a332a9 100644
--- a/include/asm-um/futex.h
+++ b/include/asm-um/futex.h
@@ -1,12 +1,6 @@
-#ifndef __UM_FUTEX_H
-#define __UM_FUTEX_H
+#ifndef _ASM_FUTEX_H
+#define _ASM_FUTEX_H
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/system.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
-
-#include "asm/arch/futex.h"
+#include <asm-generic/futex.h>
 
 #endif
diff --git a/include/asm-um/rwsem.h b/include/asm-um/rwsem.h
index 661c0e5..b5fc449 100644
--- a/include/asm-um/rwsem.h
+++ b/include/asm-um/rwsem.h
@@ -1,10 +1,6 @@
 #ifndef __UM_RWSEM_H__
 #define __UM_RWSEM_H__
 
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
-#define __builtin_expect(exp,c) (exp)
-#endif
-
 #include "asm/arch/rwsem.h"
 
 #endif
diff --git a/include/asm-v850/atomic.h b/include/asm-v850/atomic.h
index bede317..f5b9ab6 100644
--- a/include/asm-v850/atomic.h
+++ b/include/asm-v850/atomic.h
@@ -126,4 +126,5 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif /* __V850_ATOMIC_H__ */
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
index b91e799..8955d23 100644
--- a/include/asm-v850/bitops.h
+++ b/include/asm-v850/bitops.h
@@ -276,6 +276,7 @@
 
 #define ffs(x) generic_ffs (x)
 #define fls(x) generic_fls (x)
+#define fls64(x) generic_fls64(x)
 #define __ffs(x) ffs(x)
 
 
diff --git a/include/asm-v850/cache.h b/include/asm-v850/cache.h
index cbf9096..8832c7e 100644
--- a/include/asm-v850/cache.h
+++ b/include/asm-v850/cache.h
@@ -23,6 +23,4 @@
 #define L1_CACHE_SHIFT		4
 #endif
 
-#define L1_CACHE_SHIFT_MAX	L1_CACHE_SHIFT
-
 #endif /* __V850_CACHE_H__ */
diff --git a/include/asm-v850/futex.h b/include/asm-v850/futex.h
index 9feff4ce..6a332a9 100644
--- a/include/asm-v850/futex.h
+++ b/include/asm-v850/futex.h
@@ -1,53 +1,6 @@
 #ifndef _ASM_FUTEX_H
 #define _ASM_FUTEX_H
 
-#ifdef __KERNEL__
+#include <asm-generic/futex.h>
 
-#include <linux/futex.h>
-#include <asm/errno.h>
-#include <asm/uaccess.h>
-
-static inline int
-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
-{
-	int op = (encoded_op >> 28) & 7;
-	int cmp = (encoded_op >> 24) & 15;
-	int oparg = (encoded_op << 8) >> 20;
-	int cmparg = (encoded_op << 20) >> 20;
-	int oldval = 0, ret;
-	if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
-		oparg = 1 << oparg;
-
-	if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))
-		return -EFAULT;
-
-	inc_preempt_count();
-
-	switch (op) {
-	case FUTEX_OP_SET:
-	case FUTEX_OP_ADD:
-	case FUTEX_OP_OR:
-	case FUTEX_OP_ANDN:
-	case FUTEX_OP_XOR:
-	default:
-		ret = -ENOSYS;
-	}
-
-	dec_preempt_count();
-
-	if (!ret) {
-		switch (cmp) {
-		case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
-		case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
-		case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
-		case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
-		case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
-		case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
-		default: ret = -ENOSYS;
-		}
-	}
-	return ret;
-}
-
-#endif
 #endif
diff --git a/include/asm-v850/mman.h b/include/asm-v850/mman.h
index e2b9008..edc7996 100644
--- a/include/asm-v850/mman.h
+++ b/include/asm-v850/mman.h
@@ -32,6 +32,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h
index 5a86f8e..82460a7 100644
--- a/include/asm-v850/unistd.h
+++ b/include/asm-v850/unistd.h
@@ -241,9 +241,6 @@
 /* User programs sometimes end up including this header file
    (indirectly, via uClibc header files), so I'm a bit nervous just
    including <linux/compiler.h>.  */
-#if !defined(__builtin_expect) && __GNUC__ == 2 && __GNUC_MINOR__ < 96
-#define __builtin_expect(x, expected_value) (x)
-#endif
 
 #define __syscall_return(type, res)					      \
   do {									      \
@@ -346,20 +343,6 @@
   __syscall_return (type, __ret);					      \
 }
 
-#if __GNUC__ < 3
-/* In older versions of gcc, `asm' statements with more than 10
-   input/output arguments produce a fatal error.  To work around this
-   problem, we use two versions, one for gcc-3.x and one for earlier
-   versions of gcc (the `earlier gcc' version doesn't work with gcc-3.x
-   because gcc-3.x doesn't allow clobbers to also be input arguments).  */
-#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f)			      \
-  __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP			      \
-			: "=r" (ret), "=r" (syscall)			      \
-			: "1" (syscall),				      \
-			"r" (a), "r" (b), "r" (c), "r" (d),		      \
- 			"r" (e), "r" (f)				      \
-			: SYSCALL_CLOBBERS, SYSCALL_ARG4, SYSCALL_ARG5);
-#else /* __GNUC__ >= 3 */
 #define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f)			      \
   __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP			      \
 			: "=r" (ret), "=r" (syscall),			      \
@@ -368,7 +351,6 @@
 			"r" (a), "r" (b), "r" (c), "r" (d),		      \
 			"2" (e), "3" (f)				      \
 			: SYSCALL_CLOBBERS);
-#endif
 
 #define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \
 type name (atype a, btype b, ctype c, dtype d, etype e, ftype f)	      \
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h
index 50db9f3..72eb071 100644
--- a/include/asm-x86_64/atomic.h
+++ b/include/asm-x86_64/atomic.h
@@ -424,4 +424,5 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
index 05a0d37..a4d5d09 100644
--- a/include/asm-x86_64/bitops.h
+++ b/include/asm-x86_64/bitops.h
@@ -340,6 +340,20 @@
 	return word;
 }
 
+/*
+ * __fls: find last bit set.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static __inline__ unsigned long __fls(unsigned long word)
+{
+	__asm__("bsrq %1,%0"
+		:"=r" (word)
+		:"rm" (word));
+	return word;
+}
+
 #ifdef __KERNEL__
 
 static inline int sched_find_first_bit(const unsigned long *b)
@@ -370,6 +384,19 @@
 }
 
 /**
+ * fls64 - find last bit set in 64 bit word
+ * @x: the word to search
+ *
+ * This is defined the same way as fls.
+ */
+static __inline__ int fls64(__u64 x)
+{
+	if (x == 0)
+		return 0;
+	return __fls(x) + 1;
+}
+
+/**
  * hweightN - returns the hamming weight of a N-bit word
  * @x: the word to weigh
  *
diff --git a/include/asm-x86_64/cache.h b/include/asm-x86_64/cache.h
index 33e5342..b4a2401 100644
--- a/include/asm-x86_64/cache.h
+++ b/include/asm-x86_64/cache.h
@@ -9,6 +9,5 @@
 /* L1 cache line size */
 #define L1_CACHE_SHIFT	(CONFIG_X86_L1_CACHE_SHIFT)
 #define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
-#define L1_CACHE_SHIFT_MAX 7	/* largest L1 which this arch supports */
 
 #endif
diff --git a/include/asm-x86_64/cacheflush.h b/include/asm-x86_64/cacheflush.h
index b3189fb..d32f7f5 100644
--- a/include/asm-x86_64/cacheflush.h
+++ b/include/asm-x86_64/cacheflush.h
@@ -27,4 +27,8 @@
 int change_page_attr(struct page *page, int numpages, pgprot_t prot);
 int change_page_attr_addr(unsigned long addr, int numpages, pgprot_t prot);
 
+#ifdef CONFIG_DEBUG_RODATA
+void mark_rodata_ro(void);
+#endif
+
 #endif /* _X8664_CACHEFLUSH_H */
diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h
index d5166ec..e884336 100644
--- a/include/asm-x86_64/ia32_unistd.h
+++ b/include/asm-x86_64/ia32_unistd.h
@@ -299,7 +299,8 @@
 #define __NR_ia32_inotify_init		291
 #define __NR_ia32_inotify_add_watch	292
 #define __NR_ia32_inotify_rm_watch	293
+#define __NR_ia32_migrate_pages		294
 
-#define IA32_NR_syscalls 294	/* must be > than biggest syscall! */
+#define IA32_NR_syscalls 295	/* must be > than biggest syscall! */
 
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
diff --git a/include/asm-x86_64/mman.h b/include/asm-x86_64/mman.h
index 78e60a4..d0e97b7 100644
--- a/include/asm-x86_64/mman.h
+++ b/include/asm-x86_64/mman.h
@@ -36,6 +36,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON	MAP_ANONYMOUS
diff --git a/include/asm-x86_64/mpspec.h b/include/asm-x86_64/mpspec.h
index 6f8a17d..10248a9 100644
--- a/include/asm-x86_64/mpspec.h
+++ b/include/asm-x86_64/mpspec.h
@@ -76,7 +76,7 @@
 {
 	unsigned char mpc_type;
 	unsigned char mpc_busid;
-	unsigned char mpc_bustype[6] __attribute((packed));
+	unsigned char mpc_bustype[6];
 };
 
 /* List of Bus Type string values, Intel MP Spec. */
diff --git a/include/asm-x86_64/param.h b/include/asm-x86_64/param.h
index 40b1193..5956b23 100644
--- a/include/asm-x86_64/param.h
+++ b/include/asm-x86_64/param.h
@@ -1,9 +1,8 @@
-#include <linux/config.h>
-
 #ifndef _ASMx86_64_PARAM_H
 #define _ASMx86_64_PARAM_H
 
 #ifdef __KERNEL__
+# include <linux/config.h>
 # define HZ            CONFIG_HZ	/* Internal kernel timer frequency */
 # define USER_HZ       100		/* .. some user interfaces are in "ticks */
 #define CLOCKS_PER_SEC        (USER_HZ)       /* like times() */
diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h
index ecf58c7..02888d7 100644
--- a/include/asm-x86_64/pgtable.h
+++ b/include/asm-x86_64/pgtable.h
@@ -122,6 +122,8 @@
 
 #define pte_same(a, b)		((a).pte == (b).pte)
 
+#define pte_pgprot(a)	(__pgprot((a).pte & ~PHYSICAL_PAGE_MASK))
+
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
 #define PUD_SIZE	(1UL << PUD_SHIFT)
diff --git a/include/asm-x86_64/rwlock.h b/include/asm-x86_64/rwlock.h
index 8a78a4a..9942cc3 100644
--- a/include/asm-x86_64/rwlock.h
+++ b/include/asm-x86_64/rwlock.h
@@ -64,7 +64,7 @@
 		     ::"a" (rw) : "memory")
 
 #define __build_write_lock_const(rw, helper) \
-	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",%0\n\t" \
 		     "jnz 2f\n" \
 		     "1:\n" \
 		    LOCK_SECTION_START("") \
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h
index 85348e0..b34cc2e 100644
--- a/include/asm-x86_64/system.h
+++ b/include/asm-x86_64/system.h
@@ -315,6 +315,8 @@
 #define local_irq_enable()	__asm__ __volatile__("sti": : :"memory")
 /* used in the idle loop; sti takes one instruction cycle to complete */
 #define safe_halt()		__asm__ __volatile__("sti; hlt": : :"memory")
+/* used when interrupts are already enabled or to shutdown the processor */
+#define halt()			__asm__ __volatile__("hlt": : :"memory")
 
 #define irqs_disabled()			\
 ({					\
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h
index d39ebd5..7d82bc5 100644
--- a/include/asm-x86_64/topology.h
+++ b/include/asm-x86_64/topology.h
@@ -23,7 +23,7 @@
 
 #define cpu_to_node(cpu)		(cpu_to_node[cpu])
 #define parent_node(node)		(node)
-#define node_to_first_cpu(node) 	(__ffs(node_to_cpumask[node]))
+#define node_to_first_cpu(node) 	(first_cpu(node_to_cpumask[node]))
 #define node_to_cpumask(node)		(node_to_cpumask[node])
 #define pcibus_to_node(bus)		((long)(bus->sysdata))	
 #define pcibus_to_cpumask(bus)		node_to_cpumask(pcibus_to_node(bus));
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h
index 2c42150..e6f89616 100644
--- a/include/asm-x86_64/unistd.h
+++ b/include/asm-x86_64/unistd.h
@@ -571,8 +571,10 @@
 __SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
 #define __NR_inotify_rm_watch	255
 __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
+#define __NR_migrate_pages	256
+__SYSCALL(__NR_migrate_pages, sys_migrate_pages)
 
-#define __NR_syscall_max __NR_inotify_rm_watch
+#define __NR_syscall_max __NR_migrate_pages
 #ifndef __NO_STUBS
 
 /* user-visible error numbers are in the range -1 - -4095 */
diff --git a/include/asm-xtensa/atomic.h b/include/asm-xtensa/atomic.h
index 3670cc7..e2ce06b 100644
--- a/include/asm-xtensa/atomic.h
+++ b/include/asm-xtensa/atomic.h
@@ -286,6 +286,7 @@
 #define smp_mb__before_atomic_inc()	barrier()
 #define smp_mb__after_atomic_inc()	barrier()
 
+#include <asm-generic/atomic.h>
 #endif /* __KERNEL__ */
 
 #endif /* _XTENSA_ATOMIC_H */
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
index e76ee88..0a2065f 100644
--- a/include/asm-xtensa/bitops.h
+++ b/include/asm-xtensa/bitops.h
@@ -245,6 +245,7 @@
 {
 	return __cntlz(x);
 }
+#define fls64(x)   generic_fls64(x)
 
 static __inline__ int
 find_next_bit(const unsigned long *addr, int size, int offset)
diff --git a/include/asm-xtensa/mman.h b/include/asm-xtensa/mman.h
index 9a95a45..082a750 100644
--- a/include/asm-xtensa/mman.h
+++ b/include/asm-xtensa/mman.h
@@ -72,6 +72,7 @@
 #define MADV_SEQUENTIAL	0x2		/* read-ahead aggressively */
 #define MADV_WILLNEED	0x3		/* pre-fault pages */
 #define MADV_DONTNEED	0x4		/* discard these pages */
+#define MADV_REMOVE	0x5		/* remove these pages & resources */
 
 /* compatibility flags */
 #define MAP_ANON       MAP_ANONYMOUS
diff --git a/include/keys/user-type.h b/include/keys/user-type.h
index 26f6ec3..a3dae18 100644
--- a/include/keys/user-type.h
+++ b/include/keys/user-type.h
@@ -35,7 +35,6 @@
 extern struct key_type key_type_user;
 
 extern int user_instantiate(struct key *key, const void *data, size_t datalen);
-extern int user_duplicate(struct key *key, const struct key *source);
 extern int user_update(struct key *key, const void *data, size_t datalen);
 extern int user_match(const struct key *key, const void *criterion);
 extern void user_destroy(struct key *key);
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 49fd376..00c8efa 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -94,26 +94,27 @@
 	ssize_t			(*ki_retry)(struct kiocb *);
 	void			(*ki_dtor)(struct kiocb *);
 
-	struct list_head	ki_list;	/* the aio core uses this
-						 * for cancellation */
-
 	union {
 		void __user		*user;
 		struct task_struct	*tsk;
 	} ki_obj;
+
 	__u64			ki_user_data;	/* user's data for completion */
+	wait_queue_t		ki_wait;
 	loff_t			ki_pos;
+
+	void			*private;
 	/* State that we remember to be able to restart/retry  */
 	unsigned short		ki_opcode;
 	size_t			ki_nbytes; 	/* copy of iocb->aio_nbytes */
 	char 			__user *ki_buf;	/* remaining iocb->aio_buf */
 	size_t			ki_left; 	/* remaining bytes */
-	wait_queue_t		ki_wait;
 	long			ki_retried; 	/* just for testing */
 	long			ki_kicked; 	/* just for testing */
 	long			ki_queued; 	/* just for testing */
 
-	void			*private;
+	struct list_head	ki_list;	/* the aio core uses this
+						 * for cancellation */
 };
 
 #define is_sync_kiocb(iocb)	((iocb)->ki_key == KIOCB_SYNC_KEY)
@@ -126,6 +127,7 @@
 		(x)->ki_filp = (filp);			\
 		(x)->ki_ctx = NULL;			\
 		(x)->ki_cancel = NULL;			\
+		(x)->ki_retry = NULL;			\
 		(x)->ki_dtor = NULL;			\
 		(x)->ki_obj.tsk = tsk;			\
 		(x)->ki_user_data = 0;                  \
diff --git a/include/asm-arm/hardware/amba.h b/include/linux/amba/bus.h
similarity index 100%
rename from include/asm-arm/hardware/amba.h
rename to include/linux/amba/bus.h
diff --git a/include/asm-arm/hardware/amba_clcd.h b/include/linux/amba/clcd.h
similarity index 100%
rename from include/asm-arm/hardware/amba_clcd.h
rename to include/linux/amba/clcd.h
diff --git a/include/asm-arm/hardware/amba_kmi.h b/include/linux/amba/kmi.h
similarity index 100%
rename from include/asm-arm/hardware/amba_kmi.h
rename to include/linux/amba/kmi.h
diff --git a/include/asm-arm/hardware/amba_serial.h b/include/linux/amba/serial.h
similarity index 100%
rename from include/asm-arm/hardware/amba_serial.h
rename to include/linux/amba/serial.h
diff --git a/include/linux/ata.h b/include/linux/ata.h
index d2873b7..94f77cc 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -129,6 +129,7 @@
 	ATA_CMD_READ_EXT	= 0x25,
 	ATA_CMD_WRITE		= 0xCA,
 	ATA_CMD_WRITE_EXT	= 0x35,
+	ATA_CMD_WRITE_FUA_EXT	= 0x3D,
 	ATA_CMD_PIO_READ	= 0x20,
 	ATA_CMD_PIO_READ_EXT	= 0x24,
 	ATA_CMD_PIO_WRITE	= 0x30,
@@ -137,10 +138,13 @@
 	ATA_CMD_READ_MULTI_EXT	= 0x29,
 	ATA_CMD_WRITE_MULTI	= 0xC5,
 	ATA_CMD_WRITE_MULTI_EXT	= 0x39,
+	ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE,
 	ATA_CMD_SET_FEATURES	= 0xEF,
 	ATA_CMD_PACKET		= 0xA0,
 	ATA_CMD_VERIFY		= 0x40,
 	ATA_CMD_VERIFY_EXT	= 0x42,
+ 	ATA_CMD_STANDBYNOW1	= 0xE0,
+ 	ATA_CMD_IDLEIMMEDIATE	= 0xE1,
 	ATA_CMD_INIT_DEV_PARAMS	= 0x91,
 
 	/* SETFEATURES stuff */
@@ -192,6 +196,7 @@
 	ATA_TFLAG_DEVICE	= (1 << 2), /* enable r/w to device reg */
 	ATA_TFLAG_WRITE		= (1 << 3), /* data dir: host->dev==1 (write) */
 	ATA_TFLAG_LBA		= (1 << 4), /* enable LBA */
+	ATA_TFLAG_FUA		= (1 << 5), /* enable FUA */
 };
 
 enum ata_tf_protocols {
@@ -245,7 +250,8 @@
 #define ata_id_is_sata(id)	((id)[93] == 0)
 #define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
 #define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
-#define ata_id_has_flush(id) ((id)[83] & (1 << 12))
+#define ata_id_has_fua(id)	((id)[84] & (1 << 6))
+#define ata_id_has_flush(id)	((id)[83] & (1 << 12))
 #define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13))
 #define ata_id_has_lba48(id)	((id)[83] & (1 << 10))
 #define ata_id_has_wcache(id)	((id)[82] & (1 << 5))
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index 911c09c..6ba3aa8 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -155,15 +155,15 @@
 #define AARP_REQUEST			1
 #define AARP_REPLY			2
 #define AARP_PROBE			3
-	__u8	hw_src[ETH_ALEN]	__attribute__ ((packed));
-	__u8	pa_src_zero		__attribute__ ((packed));
-	__be16	pa_src_net		__attribute__ ((packed));
-	__u8	pa_src_node		__attribute__ ((packed));
-	__u8	hw_dst[ETH_ALEN]	__attribute__ ((packed));
-	__u8	pa_dst_zero		__attribute__ ((packed));
-	__be16	pa_dst_net		__attribute__ ((packed));
-	__u8	pa_dst_node		__attribute__ ((packed));	
-};
+	__u8	hw_src[ETH_ALEN];
+	__u8	pa_src_zero;
+	__be16	pa_src_net;
+	__u8	pa_src_node;
+	__u8	hw_dst[ETH_ALEN];
+	__u8	pa_dst_zero;
+	__be16	pa_dst_net;
+	__u8	pa_dst_node;
+} __attribute__ ((packed));
 
 static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb)
 {
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index e7d0593..b203ea8 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -7,7 +7,6 @@
 #define LINUX_ATMDEV_H
 
 
-#include <linux/config.h>
 #include <linux/atmapi.h>
 #include <linux/atm.h>
 #include <linux/atmioc.h>
@@ -210,6 +209,7 @@
 
 #ifdef __KERNEL__
 
+#include <linux/config.h>
 #include <linux/wait.h> /* wait_queue_head_t */
 #include <linux/time.h> /* struct timeval */
 #include <linux/net.h>
@@ -274,7 +274,7 @@
 
 
 enum {
-	ATM_DF_CLOSE,		/* close device when last VCC is closed */
+	ATM_DF_REMOVED,		/* device was removed from atm_devs list */
 };
 
 
@@ -415,7 +415,6 @@
     int number,unsigned long *flags); /* number == -1: pick first available */
 struct atm_dev *atm_dev_lookup(int number);
 void atm_dev_deregister(struct atm_dev *dev);
-void shutdown_atm_dev(struct atm_dev *dev);
 void vcc_insert_socket(struct sock *sk);
 
 
@@ -457,18 +456,19 @@
 
 static inline void atm_dev_put(struct atm_dev *dev)
 {
-	atomic_dec(&dev->refcnt);
-
-	if ((atomic_read(&dev->refcnt) == 1) &&
-	    test_bit(ATM_DF_CLOSE,&dev->flags))
-		shutdown_atm_dev(dev);
+	if (atomic_dec_and_test(&dev->refcnt)) {
+		BUG_ON(!test_bit(ATM_DF_REMOVED, &dev->flags));
+		if (dev->ops->dev_close)
+			dev->ops->dev_close(dev);
+		kfree(dev);
+	}
 }
 
 
 int atm_charge(struct atm_vcc *vcc,int truesize);
 struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size,
     gfp_t gfp_flags);
-int atm_pcr_goal(struct atm_trafprm *tp);
+int atm_pcr_goal(const struct atm_trafprm *tp);
 
 void vcc_release_async(struct atm_vcc *vcc, int reply);
 
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 685fd37..b60ffe3 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -292,6 +292,8 @@
 extern void bio_init(struct bio *);
 
 extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
+extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
+			   unsigned int, unsigned int);
 extern int bio_get_nr_vecs(struct block_device *);
 extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
 				unsigned long, unsigned int, int);
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 38c2fb7..6a2a19f 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -76,6 +76,15 @@
  */
 #include <asm/bitops.h>
 
+
+static inline int generic_fls64(__u64 x)
+{
+	__u32 h = x >> 32;
+	if (h)
+		return fls(x) + 32;
+	return fls(x);
+}
+
 static __inline__ int get_bitmask_order(unsigned int count)
 {
 	int order;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index a33a31e..fb09853 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -102,7 +102,7 @@
 void swap_io_context(struct io_context **ioc1, struct io_context **ioc2);
 
 struct request;
-typedef void (rq_end_io_fn)(struct request *);
+typedef void (rq_end_io_fn)(struct request *, int);
 
 struct request_list {
 	int count[2];
@@ -184,6 +184,7 @@
 	void *sense;
 
 	unsigned int timeout;
+	int retries;
 
 	/*
 	 * For Power Management requests
@@ -206,6 +207,7 @@
 	__REQ_SORTED,		/* elevator knows about this request */
 	__REQ_SOFTBARRIER,	/* may not be passed by ioscheduler */
 	__REQ_HARDBARRIER,	/* may not be passed by drive either */
+	__REQ_FUA,		/* forced unit access */
 	__REQ_CMD,		/* is a regular fs rw request */
 	__REQ_NOMERGE,		/* don't touch this for merging */
 	__REQ_STARTED,		/* drive already may have started this one */
@@ -229,9 +231,7 @@
 	__REQ_PM_SUSPEND,	/* suspend request */
 	__REQ_PM_RESUME,	/* resume request */
 	__REQ_PM_SHUTDOWN,	/* shutdown request */
-	__REQ_BAR_PREFLUSH,	/* barrier pre-flush done */
-	__REQ_BAR_POSTFLUSH,	/* barrier post-flush */
-	__REQ_BAR_FLUSH,	/* rq is the flush request */
+	__REQ_ORDERED_COLOR,	/* is before or after barrier */
 	__REQ_NR_BITS,		/* stops here */
 };
 
@@ -240,6 +240,7 @@
 #define REQ_SORTED	(1 << __REQ_SORTED)
 #define REQ_SOFTBARRIER	(1 << __REQ_SOFTBARRIER)
 #define REQ_HARDBARRIER	(1 << __REQ_HARDBARRIER)
+#define REQ_FUA		(1 << __REQ_FUA)
 #define REQ_CMD		(1 << __REQ_CMD)
 #define REQ_NOMERGE	(1 << __REQ_NOMERGE)
 #define REQ_STARTED	(1 << __REQ_STARTED)
@@ -259,9 +260,7 @@
 #define REQ_PM_SUSPEND	(1 << __REQ_PM_SUSPEND)
 #define REQ_PM_RESUME	(1 << __REQ_PM_RESUME)
 #define REQ_PM_SHUTDOWN	(1 << __REQ_PM_SHUTDOWN)
-#define REQ_BAR_PREFLUSH	(1 << __REQ_BAR_PREFLUSH)
-#define REQ_BAR_POSTFLUSH	(1 << __REQ_BAR_POSTFLUSH)
-#define REQ_BAR_FLUSH	(1 << __REQ_BAR_FLUSH)
+#define REQ_ORDERED_COLOR	(1 << __REQ_ORDERED_COLOR)
 
 /*
  * State information carried for REQ_PM_SUSPEND and REQ_PM_RESUME
@@ -291,8 +290,7 @@
 typedef int (merge_bvec_fn) (request_queue_t *, struct bio *, struct bio_vec *);
 typedef void (activity_fn) (void *data, int rw);
 typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *);
-typedef int (prepare_flush_fn) (request_queue_t *, struct request *);
-typedef void (end_flush_fn) (request_queue_t *, struct request *);
+typedef void (prepare_flush_fn) (request_queue_t *, struct request *);
 
 enum blk_queue_state {
 	Queue_down,
@@ -334,7 +332,6 @@
 	activity_fn		*activity_fn;
 	issue_flush_fn		*issue_flush_fn;
 	prepare_flush_fn	*prepare_flush_fn;
-	end_flush_fn		*end_flush_fn;
 
 	/*
 	 * Dispatch queue sorting
@@ -419,14 +416,11 @@
 	/*
 	 * reserved for flush operations
 	 */
-	struct request		*flush_rq;
-	unsigned char		ordered;
-};
-
-enum {
-	QUEUE_ORDERED_NONE,
-	QUEUE_ORDERED_TAG,
-	QUEUE_ORDERED_FLUSH,
+	unsigned int		ordered, next_ordered, ordseq;
+	int			orderr, ordcolor;
+	struct request		pre_flush_rq, bar_rq, post_flush_rq;
+	struct request		*orig_bar_rq;
+	unsigned int		bi_size;
 };
 
 #define RQ_INACTIVE		(-1)
@@ -444,12 +438,51 @@
 #define QUEUE_FLAG_REENTER	6	/* Re-entrancy avoidance */
 #define QUEUE_FLAG_PLUGGED	7	/* queue is plugged */
 #define QUEUE_FLAG_ELVSWITCH	8	/* don't use elevator, just do FIFO */
-#define QUEUE_FLAG_FLUSH	9	/* doing barrier flush sequence */
+
+enum {
+	/*
+	 * Hardbarrier is supported with one of the following methods.
+	 *
+	 * NONE		: hardbarrier unsupported
+	 * DRAIN	: ordering by draining is enough
+	 * DRAIN_FLUSH	: ordering by draining w/ pre and post flushes
+	 * DRAIN_FUA	: ordering by draining w/ pre flush and FUA write
+	 * TAG		: ordering by tag is enough
+	 * TAG_FLUSH	: ordering by tag w/ pre and post flushes
+	 * TAG_FUA	: ordering by tag w/ pre flush and FUA write
+	 */
+	QUEUE_ORDERED_NONE	= 0x00,
+	QUEUE_ORDERED_DRAIN	= 0x01,
+	QUEUE_ORDERED_TAG	= 0x02,
+
+	QUEUE_ORDERED_PREFLUSH	= 0x10,
+	QUEUE_ORDERED_POSTFLUSH	= 0x20,
+	QUEUE_ORDERED_FUA	= 0x40,
+
+	QUEUE_ORDERED_DRAIN_FLUSH = QUEUE_ORDERED_DRAIN |
+			QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_POSTFLUSH,
+	QUEUE_ORDERED_DRAIN_FUA	= QUEUE_ORDERED_DRAIN |
+			QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_FUA,
+	QUEUE_ORDERED_TAG_FLUSH	= QUEUE_ORDERED_TAG |
+			QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_POSTFLUSH,
+	QUEUE_ORDERED_TAG_FUA	= QUEUE_ORDERED_TAG |
+			QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_FUA,
+
+	/*
+	 * Ordered operation sequence
+	 */
+	QUEUE_ORDSEQ_STARTED	= 0x01,	/* flushing in progress */
+	QUEUE_ORDSEQ_DRAIN	= 0x02,	/* waiting for the queue to be drained */
+	QUEUE_ORDSEQ_PREFLUSH	= 0x04,	/* pre-flushing in progress */
+	QUEUE_ORDSEQ_BAR	= 0x08,	/* original barrier req in progress */
+	QUEUE_ORDSEQ_POSTFLUSH	= 0x10,	/* post-flushing in progress */
+	QUEUE_ORDSEQ_DONE	= 0x20,
+};
 
 #define blk_queue_plugged(q)	test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
 #define blk_queue_tagged(q)	test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
 #define blk_queue_stopped(q)	test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
-#define blk_queue_flushing(q)	test_bit(QUEUE_FLAG_FLUSH, &(q)->queue_flags)
+#define blk_queue_flushing(q)	((q)->ordseq)
 
 #define blk_fs_request(rq)	((rq)->flags & REQ_CMD)
 #define blk_pc_request(rq)	((rq)->flags & REQ_BLOCK_PC)
@@ -465,8 +498,7 @@
 
 #define blk_sorted_rq(rq)	((rq)->flags & REQ_SORTED)
 #define blk_barrier_rq(rq)	((rq)->flags & REQ_HARDBARRIER)
-#define blk_barrier_preflush(rq)	((rq)->flags & REQ_BAR_PREFLUSH)
-#define blk_barrier_postflush(rq)	((rq)->flags & REQ_BAR_POSTFLUSH)
+#define blk_fua_rq(rq)		((rq)->flags & REQ_FUA)
 
 #define list_entry_rq(ptr)	list_entry((ptr), struct request, queuelist)
 
@@ -558,7 +590,8 @@
 extern void register_disk(struct gendisk *dev);
 extern void generic_make_request(struct bio *bio);
 extern void blk_put_request(struct request *);
-extern void blk_end_sync_rq(struct request *rq);
+extern void __blk_put_request(request_queue_t *, struct request *);
+extern void blk_end_sync_rq(struct request *rq, int error);
 extern void blk_attempt_remerge(request_queue_t *, struct request *);
 extern struct request *blk_get_request(request_queue_t *, int, gfp_t);
 extern void blk_insert_request(request_queue_t *, struct request *, int, void *);
@@ -579,6 +612,9 @@
 extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int);
 extern int blk_execute_rq(request_queue_t *, struct gendisk *,
 			  struct request *, int);
+extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *,
+				  struct request *, int, rq_end_io_fn *);
+
 static inline request_queue_t *bdev_get_queue(struct block_device *bdev)
 {
 	return bdev->bd_disk->queue;
@@ -608,7 +644,7 @@
  */
 extern int end_that_request_first(struct request *, int, int);
 extern int end_that_request_chunk(struct request *, int, int);
-extern void end_that_request_last(struct request *);
+extern void end_that_request_last(struct request *, int);
 extern void end_request(struct request *req, int uptodate);
 
 /*
@@ -659,11 +695,12 @@
 extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *);
 extern void blk_queue_dma_alignment(request_queue_t *, int);
 extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
-extern void blk_queue_ordered(request_queue_t *, int);
+extern int blk_queue_ordered(request_queue_t *, unsigned, prepare_flush_fn *);
 extern void blk_queue_issue_flush_fn(request_queue_t *, issue_flush_fn *);
-extern struct request *blk_start_pre_flush(request_queue_t *,struct request *);
-extern int blk_complete_barrier_rq(request_queue_t *, struct request *, int);
-extern int blk_complete_barrier_rq_locked(request_queue_t *, struct request *, int);
+extern int blk_do_ordered(request_queue_t *, struct request **);
+extern unsigned blk_ordered_cur_seq(request_queue_t *);
+extern unsigned blk_ordered_req_seq(struct request *);
+extern void blk_ordered_complete_seq(request_queue_t *, unsigned, int);
 
 extern int blk_rq_map_sg(request_queue_t *, struct request *, struct scatterlist *);
 extern void blk_dump_rq_flags(struct request *, char *);
@@ -696,7 +733,8 @@
 
 #define MAX_PHYS_SEGMENTS 128
 #define MAX_HW_SEGMENTS 128
-#define MAX_SECTORS 255
+#define SAFE_MAX_SECTORS 255
+#define BLK_DEF_MAX_SECTORS 1024
 
 #define MAX_SEGMENT_SIZE	65536
 
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h
index 3b03b0b..993da8c 100644
--- a/include/linux/bootmem.h
+++ b/include/linux/bootmem.h
@@ -43,50 +43,38 @@
 extern unsigned long __init bootmem_bootmap_pages (unsigned long);
 extern unsigned long __init init_bootmem (unsigned long addr, unsigned long memend);
 extern void __init free_bootmem (unsigned long addr, unsigned long size);
-extern void * __init __alloc_bootmem_limit (unsigned long size, unsigned long align, unsigned long goal, unsigned long limit);
+extern void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal);
+extern void * __init __alloc_bootmem_low(unsigned long size,
+					 unsigned long align,
+					 unsigned long goal);
+extern void * __init __alloc_bootmem_low_node(pg_data_t *pgdat,
+					      unsigned long size,
+					      unsigned long align,
+					      unsigned long goal);
 #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
 extern void __init reserve_bootmem (unsigned long addr, unsigned long size);
 #define alloc_bootmem(x) \
 	__alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_low(x) \
-	__alloc_bootmem((x), SMP_CACHE_BYTES, 0)
+	__alloc_bootmem_low((x), SMP_CACHE_BYTES, 0)
 #define alloc_bootmem_pages(x) \
 	__alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_low_pages(x) \
-	__alloc_bootmem((x), PAGE_SIZE, 0)
-
-#define alloc_bootmem_limit(x, limit)						\
-	__alloc_bootmem_limit((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS), (limit))
-#define alloc_bootmem_low_limit(x, limit)			\
-	__alloc_bootmem_limit((x), SMP_CACHE_BYTES, 0, (limit))
-#define alloc_bootmem_pages_limit(x, limit)					\
-	__alloc_bootmem_limit((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS), (limit))
-#define alloc_bootmem_low_pages_limit(x, limit)		\
-	__alloc_bootmem_limit((x), PAGE_SIZE, 0, (limit))
-
+	__alloc_bootmem_low((x), PAGE_SIZE, 0)
 #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
 extern unsigned long __init free_all_bootmem (void);
-
+extern void * __init __alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal);
 extern unsigned long __init init_bootmem_node (pg_data_t *pgdat, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn);
 extern void __init reserve_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, unsigned long size);
 extern void __init free_bootmem_node (pg_data_t *pgdat, unsigned long addr, unsigned long size);
 extern unsigned long __init free_all_bootmem_node (pg_data_t *pgdat);
-extern void * __init __alloc_bootmem_node_limit (pg_data_t *pgdat, unsigned long size, unsigned long align, unsigned long goal, unsigned long limit);
 #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
 #define alloc_bootmem_node(pgdat, x) \
 	__alloc_bootmem_node((pgdat), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_pages_node(pgdat, x) \
 	__alloc_bootmem_node((pgdat), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_low_pages_node(pgdat, x) \
-	__alloc_bootmem_node((pgdat), (x), PAGE_SIZE, 0)
-
-#define alloc_bootmem_node_limit(pgdat, x, limit)				\
-	__alloc_bootmem_node_limit((pgdat), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS), (limit))
-#define alloc_bootmem_pages_node_limit(pgdat, x, limit)				\
-	__alloc_bootmem_node_limit((pgdat), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS), (limit))
-#define alloc_bootmem_low_pages_node_limit(pgdat, x, limit)		\
-	__alloc_bootmem_node_limit((pgdat), (x), PAGE_SIZE, 0, (limit))
-
+	__alloc_bootmem_low_node((pgdat), (x), PAGE_SIZE, 0)
 #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
 
 #ifdef CONFIG_HAVE_ARCH_ALLOC_REMAP
@@ -123,15 +111,5 @@
 #endif
 extern int __initdata hashdist;		/* Distribute hashes across NUMA nodes? */
 
-static inline void *__alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)
-{
-	return __alloc_bootmem_limit(size, align, goal, 0);
-}
-
-static inline void *__alloc_bootmem_node (pg_data_t *pgdat, unsigned long size, unsigned long align,
-				     unsigned long goal)
-{
-	return __alloc_bootmem_node_limit(pgdat, size, align, goal, 0);
-}
 
 #endif /* _LINUX_BOOTMEM_H */
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 1db061b..9f159ba 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -197,7 +197,8 @@
 int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
 int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*,
 				loff_t *);
-int generic_cont_expand(struct inode *inode, loff_t size) ;
+int generic_cont_expand(struct inode *inode, loff_t size);
+int generic_cont_expand_simple(struct inode *inode, loff_t size);
 int block_commit_write(struct page *page, unsigned from, unsigned to);
 int block_sync_page(struct page *);
 sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
index 04bd756..e86e4a9 100644
--- a/include/linux/byteorder/generic.h
+++ b/include/linux/byteorder/generic.h
@@ -156,7 +156,7 @@
 extern __u16			ntohs(__be16);
 extern __be16			htons(__u16);
 
-#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__)
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
 
 #define ___htonl(x) __cpu_to_be32(x)
 #define ___htons(x) __cpu_to_be16(x)
diff --git a/include/linux/byteorder/swab.h b/include/linux/byteorder/swab.h
index 2f1cb77..25f7f32 100644
--- a/include/linux/byteorder/swab.h
+++ b/include/linux/byteorder/swab.h
@@ -110,7 +110,7 @@
 /*
  * Allow constant folding
  */
-#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__)
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
 #  define __swab16(x) \
 (__builtin_constant_p((__u16)(x)) ? \
  ___swab16((x)) : \
diff --git a/include/linux/byteorder/swabb.h b/include/linux/byteorder/swabb.h
index d5f2a32..ae5e5f9 100644
--- a/include/linux/byteorder/swabb.h
+++ b/include/linux/byteorder/swabb.h
@@ -77,7 +77,7 @@
 /*
  * Allow constant folding
  */
-#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__)
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
 #  define __swahw32(x) \
 (__builtin_constant_p((__u32)(x)) ? \
  ___swahw32((x)) : \
diff --git a/include/linux/cache.h b/include/linux/cache.h
index f6b5a46..ffe5221 100644
--- a/include/linux/cache.h
+++ b/include/linux/cache.h
@@ -13,7 +13,7 @@
 #define SMP_CACHE_BYTES L1_CACHE_BYTES
 #endif
 
-#if defined(CONFIG_X86) || defined(CONFIG_SPARC64)
+#if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_IA64)
 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
 #else
 #define __read_mostly
@@ -45,12 +45,21 @@
 #endif /* CONFIG_SMP */
 #endif
 
-#if !defined(____cacheline_maxaligned_in_smp)
+/*
+ * The maximum alignment needed for some critical structures
+ * These could be inter-node cacheline sizes/L3 cacheline
+ * size etc.  Define this in asm/cache.h for your arch
+ */
+#ifndef INTERNODE_CACHE_SHIFT
+#define INTERNODE_CACHE_SHIFT L1_CACHE_SHIFT
+#endif
+
+#if !defined(____cacheline_internodealigned_in_smp)
 #if defined(CONFIG_SMP)
-#define ____cacheline_maxaligned_in_smp \
-	__attribute__((__aligned__(1 << (L1_CACHE_SHIFT_MAX))))
+#define ____cacheline_internodealigned_in_smp \
+	__attribute__((__aligned__(1 << (INTERNODE_CACHE_SHIFT))))
 #else
-#define ____cacheline_maxaligned_in_smp
+#define ____cacheline_internodealigned_in_smp
 #endif
 #endif
 
diff --git a/include/asm-arm/hardware/clock.h b/include/linux/clk.h
similarity index 82%
rename from include/asm-arm/hardware/clock.h
rename to include/linux/clk.h
index 19da861..12848f8 100644
--- a/include/asm-arm/hardware/clock.h
+++ b/include/linux/clk.h
@@ -1,5 +1,5 @@
 /*
- *  linux/include/asm-arm/hardware/clock.h
+ *  linux/include/linux/clk.h
  *
  *  Copyright (C) 2004 ARM Limited.
  *  Written by Deep Blue Solutions Limited.
@@ -33,6 +33,8 @@
  * uses @dev and @id to determine the clock consumer, and thereby
  * the clock producer.  (IOW, @id may be identical strings, but
  * clk_get may return different clock producers depending on @dev.)
+ *
+ * Drivers must assume that the clock source is not enabled.
  */
 struct clk *clk_get(struct device *dev, const char *id);
 
@@ -49,24 +51,18 @@
 /**
  * clk_disable - inform the system when the clock source is no longer required.
  * @clk: clock source
+ *
+ * Inform the system that a clock source is no longer required by
+ * a driver and may be shut down.
+ *
+ * Implementation detail: if the clock source is shared between
+ * multiple drivers, clk_enable() calls must be balanced by the
+ * same number of clk_disable() calls for the clock source to be
+ * disabled.
  */
 void clk_disable(struct clk *clk);
 
 /**
- * clk_use - increment the use count
- * @clk: clock source
- *
- * Returns success (0) or negative errno.
- */
-int clk_use(struct clk *clk);
-
-/**
- * clk_unuse - decrement the use count
- * @clk: clock source
- */
-void clk_unuse(struct clk *clk);
-
-/**
  * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
  *		  This is only valid once the clock source has been enabled.
  * @clk: clock source
@@ -76,6 +72,10 @@
 /**
  * clk_put	- "free" the clock source
  * @clk: clock source
+ *
+ * Note: drivers must ensure that all clk_enable calls made on this
+ * clock source are balanced by clk_disable calls prior to calling
+ * this function.
  */
 void clk_put(struct clk *clk);
 
diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h
index 70ab563..1417de9 100644
--- a/include/linux/cn_proc.h
+++ b/include/linux/cn_proc.h
@@ -26,6 +26,7 @@
 #define CN_PROC_H
 
 #include <linux/types.h>
+#include <linux/time.h>
 #include <linux/connector.h>
 
 /*
@@ -65,6 +66,7 @@
 		PROC_EVENT_EXIT = 0x80000000
 	} what;
 	__u32 cpu;
+	struct timespec timestamp;
 	union { /* must be last field of proc_event struct */
 		struct {
 			__u32 err;
@@ -86,12 +88,12 @@
 			pid_t process_pid;
 			pid_t process_tgid;
 			union {
-				uid_t ruid; /* current->uid */
-				gid_t rgid; /* current->gid */
+				__u32 ruid; /* task uid */
+				__u32 rgid; /* task gid */
 			} r;
 			union {
-				uid_t euid;
-				gid_t egid;
+				__u32 euid;
+				__u32 egid;
 			} e;
 		} id;
 
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 1527340..2e05e1e 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -15,3 +15,12 @@
   ({ unsigned long __ptr;					\
     __asm__ ("" : "=g"(__ptr) : "0"(ptr));		\
     (typeof(ptr)) (__ptr + (off)); })
+
+
+#define inline		inline		__attribute__((always_inline))
+#define __inline__	__inline__	__attribute__((always_inline))
+#define __inline	__inline	__attribute__((always_inline))
+#define __deprecated			__attribute__((deprecated))
+#define  noinline			__attribute__((noinline))
+#define __attribute_pure__		__attribute__((pure))
+#define __attribute_const__		__attribute__((__const__))
diff --git a/include/linux/compiler-gcc2.h b/include/linux/compiler-gcc2.h
deleted file mode 100644
index ebed1766..0000000
--- a/include/linux/compiler-gcc2.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Never include this file directly.  Include <linux/compiler.h> instead.  */
-
-/* These definitions are for GCC v2.x.  */
-
-/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
-   a mechanism by which the user can annotate likely branch directions and
-   expect the blocks to be reordered appropriately.  Define __builtin_expect
-   to nothing for earlier compilers.  */
-#include <linux/compiler-gcc.h>
-
-#if __GNUC_MINOR__ < 96
-# define __builtin_expect(x, expected_value) (x)
-#endif
-
-#define __attribute_used__	__attribute__((__unused__))
-
-/*
- * The attribute `pure' is not implemented in GCC versions earlier
- * than 2.96.
- */
-#if __GNUC_MINOR__ >= 96
-# define __attribute_pure__	__attribute__((pure))
-# define __attribute_const__	__attribute__((__const__))
-#endif
-
-/* GCC 2.95.x/2.96 recognize __va_copy, but not va_copy. Actually later GCC's
- * define both va_copy and __va_copy, but the latter may go away, so limit this
- * to this header */
-#define va_copy			__va_copy
diff --git a/include/linux/compiler-gcc3.h b/include/linux/compiler-gcc3.h
index a6fa615..4209082 100644
--- a/include/linux/compiler-gcc3.h
+++ b/include/linux/compiler-gcc3.h
@@ -3,29 +3,12 @@
 /* These definitions are for GCC v3.x.  */
 #include <linux/compiler-gcc.h>
 
-#if __GNUC_MINOR__ >= 1
-# define inline		inline		__attribute__((always_inline))
-# define __inline__	__inline__	__attribute__((always_inline))
-# define __inline	__inline	__attribute__((always_inline))
-#endif
-
-#if __GNUC_MINOR__ > 0
-# define __deprecated		__attribute__((deprecated))
-#endif
-
 #if __GNUC_MINOR__ >= 3
 # define __attribute_used__	__attribute__((__used__))
 #else
 # define __attribute_used__	__attribute__((__unused__))
 #endif
 
-#define __attribute_pure__	__attribute__((pure))
-#define __attribute_const__	__attribute__((__const__))
-
-#if __GNUC_MINOR__ >= 1
-#define  noinline		__attribute__((noinline))
-#endif
-
 #if __GNUC_MINOR__ >= 4
 #define __must_check		__attribute__((warn_unused_result))
 #endif
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 53686c0..e913e9b 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -3,14 +3,7 @@
 /* These definitions are for GCC v4.x.  */
 #include <linux/compiler-gcc.h>
 
-#define inline			inline		__attribute__((always_inline))
-#define __inline__		__inline__	__attribute__((always_inline))
-#define __inline		__inline	__attribute__((always_inline))
-#define __deprecated		__attribute__((deprecated))
 #define __attribute_used__	__attribute__((__used__))
-#define __attribute_pure__	__attribute__((pure))
-#define __attribute_const__	__attribute__((__const__))
-#define  noinline		__attribute__((noinline))
 #define __must_check 		__attribute__((warn_unused_result))
 #define __compiler_offsetof(a,b) __builtin_offsetof(a,b)
 
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index d737821..f23d3c6 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -42,8 +42,6 @@
 # include <linux/compiler-gcc4.h>
 #elif __GNUC__ == 3
 # include <linux/compiler-gcc3.h>
-#elif __GNUC__ == 2
-# include <linux/compiler-gcc2.h>
 #else
 # error Sorry, your compiler is too old/not recognized.
 #endif
diff --git a/include/linux/configfs.h b/include/linux/configfs.h
new file mode 100644
index 0000000..acffb8c
--- /dev/null
+++ b/include/linux/configfs.h
@@ -0,0 +1,205 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * configfs.h - definitions for the device driver filesystem
+ *
+ * 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 021110-1307, USA.
+ *
+ * Based on sysfs:
+ * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
+ *
+ * Based on kobject.h:
+ *      Copyright (c) 2002-2003	Patrick Mochel
+ *      Copyright (c) 2002-2003	Open Source Development Labs
+ *
+ * configfs Copyright (C) 2005 Oracle.  All rights reserved.
+ *
+ * Please read Documentation/filesystems/configfs.txt before using the
+ * configfs interface, ESPECIALLY the parts about reference counts and
+ * item destructors.
+ */
+
+#ifndef _CONFIGFS_H_
+#define _CONFIGFS_H_
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/kref.h>
+
+#include <asm/atomic.h>
+#include <asm/semaphore.h>
+
+#define CONFIGFS_ITEM_NAME_LEN	20
+
+struct module;
+
+struct configfs_item_operations;
+struct configfs_group_operations;
+struct configfs_attribute;
+struct configfs_subsystem;
+
+struct config_item {
+	char			*ci_name;
+	char			ci_namebuf[CONFIGFS_ITEM_NAME_LEN];
+	struct kref		ci_kref;
+	struct list_head	ci_entry;
+	struct config_item	*ci_parent;
+	struct config_group	*ci_group;
+	struct config_item_type	*ci_type;
+	struct dentry		*ci_dentry;
+};
+
+extern int config_item_set_name(struct config_item *, const char *, ...);
+
+static inline char *config_item_name(struct config_item * item)
+{
+	return item->ci_name;
+}
+
+extern void config_item_init(struct config_item *);
+extern void config_item_init_type_name(struct config_item *item,
+				       const char *name,
+				       struct config_item_type *type);
+extern void config_item_cleanup(struct config_item *);
+
+extern struct config_item * config_item_get(struct config_item *);
+extern void config_item_put(struct config_item *);
+
+struct config_item_type {
+	struct module				*ct_owner;
+	struct configfs_item_operations		*ct_item_ops;
+	struct configfs_group_operations	*ct_group_ops;
+	struct configfs_attribute		**ct_attrs;
+};
+
+
+/**
+ *	group - a group of config_items of a specific type, belonging
+ *	to a specific subsystem.
+ */
+
+struct config_group {
+	struct config_item		cg_item;
+	struct list_head		cg_children;
+	struct configfs_subsystem 	*cg_subsys;
+	struct config_group		**default_groups;
+};
+
+
+extern void config_group_init(struct config_group *group);
+extern void config_group_init_type_name(struct config_group *group,
+					const char *name,
+					struct config_item_type *type);
+
+
+static inline struct config_group *to_config_group(struct config_item *item)
+{
+	return item ? container_of(item,struct config_group,cg_item) : NULL;
+}
+
+static inline struct config_group *config_group_get(struct config_group *group)
+{
+	return group ? to_config_group(config_item_get(&group->cg_item)) : NULL;
+}
+
+static inline void config_group_put(struct config_group *group)
+{
+	config_item_put(&group->cg_item);
+}
+
+extern struct config_item *config_group_find_obj(struct config_group *, const char *);
+
+
+struct configfs_attribute {
+	char			*ca_name;
+	struct module 		*ca_owner;
+	mode_t			ca_mode;
+};
+
+
+/*
+ * If allow_link() exists, the item can symlink(2) out to other
+ * items.  If the item is a group, it may support mkdir(2).
+ * Groups supply one of make_group() and make_item().  If the
+ * group supports make_group(), one can create group children.  If it
+ * supports make_item(), one can create config_item children.  If it has
+ * default_groups on group->default_groups, it has automatically created
+ * group children.  default_groups may coexist alongsize make_group() or
+ * make_item(), but if the group wishes to have only default_groups
+ * children (disallowing mkdir(2)), it need not provide either function.
+ * If the group has commit(), it supports pending and commited (active)
+ * items.
+ */
+struct configfs_item_operations {
+	void (*release)(struct config_item *);
+	ssize_t	(*show_attribute)(struct config_item *, struct configfs_attribute *,char *);
+	ssize_t	(*store_attribute)(struct config_item *,struct configfs_attribute *,const char *, size_t);
+	int (*allow_link)(struct config_item *src, struct config_item *target);
+	int (*drop_link)(struct config_item *src, struct config_item *target);
+};
+
+struct configfs_group_operations {
+	struct config_item *(*make_item)(struct config_group *group, const char *name);
+	struct config_group *(*make_group)(struct config_group *group, const char *name);
+	int (*commit_item)(struct config_item *item);
+	void (*drop_item)(struct config_group *group, struct config_item *item);
+};
+
+
+
+/**
+ * Use these macros to make defining attributes easier. See include/linux/device.h
+ * for examples..
+ */
+
+#if 0
+#define __ATTR(_name,_mode,_show,_store) { \
+	.attr = {.ca_name = __stringify(_name), .ca_mode = _mode, .ca_owner = THIS_MODULE },	\
+	.show	= _show,					\
+	.store	= _store,					\
+}
+
+#define __ATTR_RO(_name) { \
+	.attr	= { .ca_name = __stringify(_name), .ca_mode = 0444, .ca_owner = THIS_MODULE },	\
+	.show	= _name##_show,	\
+}
+
+#define __ATTR_NULL { .attr = { .name = NULL } }
+
+#define attr_name(_attr) (_attr).attr.name
+#endif
+
+
+struct configfs_subsystem {
+	struct config_group	su_group;
+	struct semaphore	su_sem;
+};
+
+static inline struct configfs_subsystem *to_configfs_subsystem(struct config_group *group)
+{
+	return group ?
+		container_of(group, struct configfs_subsystem, su_group) :
+		NULL;
+}
+
+int configfs_register_subsystem(struct configfs_subsystem *subsys);
+void configfs_unregister_subsystem(struct configfs_subsystem *subsys);
+
+#endif  /* __KERNEL__ */
+
+#endif /* _CONFIGFS_H_ */
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 43c4453..0ed1d48 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -65,10 +65,9 @@
 
 #ifdef CONFIG_HOTPLUG_CPU
 /* Stop CPUs going up and down. */
-extern struct semaphore cpucontrol;
-#define lock_cpu_hotplug()	down(&cpucontrol)
-#define unlock_cpu_hotplug()	up(&cpucontrol)
-#define lock_cpu_hotplug_interruptible() down_interruptible(&cpucontrol)
+extern void lock_cpu_hotplug(void);
+extern void unlock_cpu_hotplug(void);
+extern int lock_cpu_hotplug_interruptible(void);
 #define hotcpu_notifier(fn, pri) {				\
 	static struct notifier_block fn##_nb =			\
 		{ .notifier_call = fn, .priority = pri };	\
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index d068176..c31650d 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -256,6 +256,16 @@
 /* query the current CPU frequency (in kHz). If zero, cpufreq couldn't detect it */
 unsigned int cpufreq_get(unsigned int cpu);
 
+/* query the last known CPU freq (in kHz). If zero, cpufreq couldn't detect it */
+#ifdef CONFIG_CPU_FREQ
+unsigned int cpufreq_quick_get(unsigned int cpu);
+#else
+static inline unsigned int cpufreq_quick_get(unsigned int cpu)
+{
+	return 0;
+}
+#endif
+
 
 /*********************************************************************
  *                       CPUFREQ DEFAULT GOVERNOR                    *
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 6e2deef..c472f97 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -14,22 +14,43 @@
 
 #ifdef CONFIG_CPUSETS
 
+extern int number_of_cpusets;	/* How many cpusets are defined in system? */
+
+extern int cpuset_init_early(void);
 extern int cpuset_init(void);
 extern void cpuset_init_smp(void);
 extern void cpuset_fork(struct task_struct *p);
 extern void cpuset_exit(struct task_struct *p);
-extern cpumask_t cpuset_cpus_allowed(const struct task_struct *p);
+extern cpumask_t cpuset_cpus_allowed(struct task_struct *p);
+extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
 void cpuset_init_current_mems_allowed(void);
-void cpuset_update_current_mems_allowed(void);
-void cpuset_restrict_to_mems_allowed(unsigned long *nodes);
+void cpuset_update_task_memory_state(void);
+#define cpuset_nodes_subset_current_mems_allowed(nodes) \
+		nodes_subset((nodes), current->mems_allowed)
 int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl);
-extern int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask);
+
+extern int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask);
+static int inline cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
+{
+	return number_of_cpusets <= 1 || __cpuset_zone_allowed(z, gfp_mask);
+}
+
 extern int cpuset_excl_nodes_overlap(const struct task_struct *p);
+
+#define cpuset_memory_pressure_bump() 				\
+	do {							\
+		if (cpuset_memory_pressure_enabled)		\
+			__cpuset_memory_pressure_bump();	\
+	} while (0)
+extern int cpuset_memory_pressure_enabled;
+extern void __cpuset_memory_pressure_bump(void);
+
 extern struct file_operations proc_cpuset_operations;
 extern char *cpuset_task_status_allowed(struct task_struct *task, char *buffer);
 
 #else /* !CONFIG_CPUSETS */
 
+static inline int cpuset_init_early(void) { return 0; }
 static inline int cpuset_init(void) { return 0; }
 static inline void cpuset_init_smp(void) {}
 static inline void cpuset_fork(struct task_struct *p) {}
@@ -40,9 +61,14 @@
 	return cpu_possible_map;
 }
 
+static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
+{
+	return node_possible_map;
+}
+
 static inline void cpuset_init_current_mems_allowed(void) {}
-static inline void cpuset_update_current_mems_allowed(void) {}
-static inline void cpuset_restrict_to_mems_allowed(unsigned long *nodes) {}
+static inline void cpuset_update_task_memory_state(void) {}
+#define cpuset_nodes_subset_current_mems_allowed(nodes) (1)
 
 static inline int cpuset_zonelist_valid_mems_allowed(struct zonelist *zl)
 {
@@ -59,6 +85,8 @@
 	return 1;
 }
 
+static inline void cpuset_memory_pressure_bump(void) {}
+
 static inline char *cpuset_task_status_allowed(struct task_struct *task,
 							char *buffer)
 {
diff --git a/include/linux/cycx_x25.h b/include/linux/cycx_x25.h
index b10a7f3..f7a9065 100644
--- a/include/linux/cycx_x25.h
+++ b/include/linux/cycx_x25.h
@@ -38,11 +38,11 @@
 /* Data Structures */
 /* X.25 Command Block. */
 struct cycx_x25_cmd {
-	u16 command PACKED;
-	u16 link    PACKED; /* values: 0 or 1 */
-	u16 len     PACKED; /* values: 0 thru 0x205 (517) */
-	u32 buf     PACKED;
-};
+	u16 command;
+	u16 link;	/* values: 0 or 1 */
+	u16 len;	/* values: 0 thru 0x205 (517) */
+	u32 buf;
+} PACKED;
 
 /* Defines for the 'command' field. */
 #define X25_CONNECT_REQUEST             0x4401
@@ -92,34 +92,34 @@
  *	@flags - see dosx25.doc, in portuguese, for details
  */
 struct cycx_x25_config {
-	u8  link	PACKED;
-	u8  speed	PACKED;
-	u8  clock	PACKED;
-	u8  n2		PACKED;
-	u8  n2win	PACKED;
-	u8  n3win	PACKED;
-	u8  nvc		PACKED;
-	u8  pktlen	PACKED;
-	u8  locaddr	PACKED;
-	u8  remaddr	PACKED;
-	u16 t1		PACKED;
-	u16 t2		PACKED;
-	u8  t21		PACKED;
-	u8  npvc	PACKED;
-	u8  t23		PACKED;
-	u8  flags	PACKED;
-};
+	u8  link;
+	u8  speed;
+	u8  clock;
+	u8  n2;
+	u8  n2win;
+	u8  n3win;
+	u8  nvc;
+	u8  pktlen;
+	u8  locaddr;
+	u8  remaddr;
+	u16 t1;
+	u16 t2;
+	u8  t21;
+	u8  npvc;
+	u8  t23;
+	u8  flags;
+} PACKED;
 
 struct cycx_x25_stats {
-	u16 rx_crc_errors	PACKED;
-	u16 rx_over_errors	PACKED;
-	u16 n2_tx_frames 	PACKED;
-	u16 n2_rx_frames 	PACKED;
-	u16 tx_timeouts 	PACKED;
-	u16 rx_timeouts 	PACKED;
-	u16 n3_tx_packets 	PACKED;
-	u16 n3_rx_packets 	PACKED;
-	u16 tx_aborts	 	PACKED;
-	u16 rx_aborts	 	PACKED;
-};
+	u16 rx_crc_errors;
+	u16 rx_over_errors;
+	u16 n2_tx_frames;
+	u16 n2_rx_frames;
+	u16 tx_timeouts;
+	u16 rx_timeouts;
+	u16 n3_tx_packets;
+	u16 n3_rx_packets;
+	u16 tx_aborts;
+	u16 rx_aborts;
+} PACKED;
 #endif	/* _CYCX_X25_H */
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 46a2ba6..a3ed5e0 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -95,14 +95,19 @@
 	struct qstr d_name;
 
 	struct list_head d_lru;		/* LRU list */
-	struct list_head d_child;	/* child of parent list */
+	/*
+	 * d_child and d_rcu can share memory
+	 */
+	union {
+		struct list_head d_child;	/* child of parent list */
+	 	struct rcu_head d_rcu;
+	} d_u;
 	struct list_head d_subdirs;	/* our children */
 	struct list_head d_alias;	/* inode alias list */
 	unsigned long d_time;		/* used by d_revalidate */
 	struct dentry_operations *d_op;
 	struct super_block *d_sb;	/* The root of the dentry tree */
 	void *d_fsdata;			/* fs-specific data */
- 	struct rcu_head d_rcu;
 	struct dcookie_struct *d_cookie; /* cookie, if any */
 	int d_mounted;
 	unsigned char d_iname[DNAME_INLINE_LEN_MIN];	/* small names */
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 71fab43..088529f 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -192,10 +192,9 @@
 #include <linux/workqueue.h>
 
 #include <net/inet_connection_sock.h>
+#include <net/inet_sock.h>
 #include <net/inet_timewait_sock.h>
-#include <net/sock.h>
 #include <net/tcp_states.h>
-#include <net/tcp.h>
 
 enum dccp_state {
 	DCCP_OPEN	= TCP_ESTABLISHED,
@@ -408,8 +407,6 @@
  * @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss
  * @dccps_timestamp_time - time of latest TIMESTAMP option
  * @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option
- * @dccps_ext_header_len - network protocol overhead (IP/IPv6 options)
- * @dccps_pmtu_cookie - Last pmtu seen by socket
  * @dccps_packet_size - Set thru setsockopt
  * @dccps_role - Role of this sock, one of %dccp_role
  * @dccps_ndp_count - number of Non Data Packets since last data packet
@@ -434,8 +431,6 @@
 	__u32				dccps_timestamp_echo;
 	__u32				dccps_packet_size;
 	unsigned long			dccps_ndp_count;
-	__u16				dccps_ext_header_len;
-	__u32				dccps_pmtu_cookie;
 	__u32				dccps_mss_cache;
 	struct dccp_options		dccps_options;
 	struct dccp_ackvec		*dccps_hc_rx_ackvec;
diff --git a/include/linux/device.h b/include/linux/device.h
index 17cbc6d..0cdee78e 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -47,8 +47,8 @@
 	struct driver_attribute	* drv_attrs;
 
 	int		(*match)(struct device * dev, struct device_driver * drv);
-	int		(*hotplug) (struct device *dev, char **envp, 
-				    int num_envp, char *buffer, int buffer_size);
+	int		(*uevent)(struct device *dev, char **envp,
+				  int num_envp, char *buffer, int buffer_size);
 	int		(*suspend)(struct device * dev, pm_message_t state);
 	int		(*resume)(struct device * dev);
 };
@@ -151,7 +151,7 @@
 	struct class_attribute		* class_attrs;
 	struct class_device_attribute	* class_dev_attrs;
 
-	int	(*hotplug)(struct class_device *dev, char **envp, 
+	int	(*uevent)(struct class_device *dev, char **envp,
 			   int num_envp, char *buffer, int buffer_size);
 
 	void	(*release)(struct class_device *dev);
@@ -209,9 +209,9 @@
  * set, this will be called instead of the class specific release function.
  * Only use this if you want to override the default release function, like
  * when you are nesting class_device structures.
- * @hotplug: pointer to a hotplug function for this struct class_device.  If
- * set, this will be called instead of the class specific hotplug function.
- * Only use this if you want to override the default hotplug function, like
+ * @uevent: pointer to a uevent function for this struct class_device.  If
+ * set, this will be called instead of the class specific uevent function.
+ * Only use this if you want to override the default uevent function, like
  * when you are nesting class_device structures.
  */
 struct class_device {
@@ -227,7 +227,7 @@
 	struct class_device	*parent;	/* parent of this child device, if there is one */
 
 	void	(*release)(struct class_device *dev);
-	int	(*hotplug)(struct class_device *dev, char **envp,
+	int	(*uevent)(struct class_device *dev, char **envp,
 			   int num_envp, char *buffer, int buffer_size);
 	char	class_id[BUS_ID_SIZE];	/* unique to this class */
 };
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
index f5eb6b6..fa75ba0 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/linux/dm-ioctl.h
@@ -272,9 +272,9 @@
 #define DM_TARGET_MSG	 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR	4
-#define DM_VERSION_MINOR	4
+#define DM_VERSION_MINOR	5
 #define DM_VERSION_PATCHLEVEL	0
-#define DM_VERSION_EXTRA	"-ioctl (2005-01-12)"
+#define DM_VERSION_EXTRA	"-ioctl (2005-10-04)"
 
 /* Status bits */
 #define DM_READONLY_FLAG	(1 << 0) /* In/Out */
@@ -301,8 +301,13 @@
 #define DM_BUFFER_FULL_FLAG	(1 << 8) /* Out */
 
 /*
- * Set this to improve performance when you aren't going to use open_count
+ * Set this to improve performance when you aren't going to use open_count.
  */
 #define DM_SKIP_BDGET_FLAG	(1 << 9) /* In */
 
+/*
+ * Set this to avoid attempting to freeze any filesystem when suspending.
+ */
+#define DM_SKIP_LOCKFS_FLAG	(1 << 10) /* In */
+
 #endif				/* _LINUX_DM_IOCTL_H */
diff --git a/include/linux/dvb/audio.h b/include/linux/dvb/audio.h
index cc31444..2b87970 100644
--- a/include/linux/dvb/audio.h
+++ b/include/linux/dvb/audio.h
@@ -32,39 +32,39 @@
 
 
 typedef enum {
-        AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */
+	AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */
 	AUDIO_SOURCE_MEMORY /* Select internal memory as the main source */
 } audio_stream_source_t;
 
 
 typedef enum {
 	AUDIO_STOPPED,      /* Device is stopped */
-        AUDIO_PLAYING,      /* Device is currently playing */
+	AUDIO_PLAYING,      /* Device is currently playing */
 	AUDIO_PAUSED        /* Device is paused */
 } audio_play_state_t;
 
 
 typedef enum {
-        AUDIO_STEREO,
-        AUDIO_MONO_LEFT,
+	AUDIO_STEREO,
+	AUDIO_MONO_LEFT,
 	AUDIO_MONO_RIGHT
 } audio_channel_select_t;
 
 
 typedef struct audio_mixer {
-        unsigned int volume_left;
-        unsigned int volume_right;
+	unsigned int volume_left;
+	unsigned int volume_right;
   // what else do we need? bass, pass-through, ...
 } audio_mixer_t;
 
 
 typedef struct audio_status {
-        int                    AV_sync_state;  /* sync audio and video? */
-        int                    mute_state;     /* audio is muted */
-        audio_play_state_t     play_state;     /* current playback state */
-        audio_stream_source_t  stream_source;  /* current stream source */
-        audio_channel_select_t channel_select; /* currently selected channel */
-        int                    bypass_mode;    /* pass on audio data to */
+	int                    AV_sync_state;  /* sync audio and video? */
+	int                    mute_state;     /* audio is muted */
+	audio_play_state_t     play_state;     /* current playback state */
+	audio_stream_source_t  stream_source;  /* current stream source */
+	audio_channel_select_t channel_select; /* currently selected channel */
+	int                    bypass_mode;    /* pass on audio data to */
 	audio_mixer_t	       mixer_state;    /* current mixer state */
 } audio_status_t;                              /* separate decoder hardware */
 
@@ -74,8 +74,8 @@
 	int vocal1;    /* into left and right t at 70% each */
 	int vocal2;    /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets*/
 	int melody;    /* mixed into the left channel and */
-                       /* Vocal2 into the right channel at 100% each. */
-                       /* if Melody is non-zero, the melody channel gets mixed*/
+		       /* Vocal2 into the right channel at 100% each. */
+		       /* if Melody is non-zero, the melody channel gets mixed*/
 } audio_karaoke_t;     /* into left and right  */
 
 
diff --git a/include/linux/dvb/ca.h b/include/linux/dvb/ca.h
index 558af0c..c18537f 100644
--- a/include/linux/dvb/ca.h
+++ b/include/linux/dvb/ca.h
@@ -27,16 +27,16 @@
 /* slot interface types and info */
 
 typedef struct ca_slot_info {
-        int num;               /* slot number */
+	int num;               /* slot number */
 
-        int type;              /* CA interface this slot supports */
+	int type;              /* CA interface this slot supports */
 #define CA_CI            1     /* CI high level interface */
 #define CA_CI_LINK       2     /* CI link layer level interface */
 #define CA_CI_PHYS       4     /* CI physical layer level interface */
 #define CA_DESCR         8     /* built-in descrambler */
 #define CA_SC          128     /* simple smart card interface */
 
-        unsigned int flags;
+	unsigned int flags;
 #define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
 #define CA_CI_MODULE_READY   2
 } ca_slot_info_t;
@@ -45,37 +45,37 @@
 /* descrambler types and info */
 
 typedef struct ca_descr_info {
-        unsigned int num;          /* number of available descramblers (keys) */
-        unsigned int type;         /* type of supported scrambling system */
+	unsigned int num;          /* number of available descramblers (keys) */
+	unsigned int type;         /* type of supported scrambling system */
 #define CA_ECD           1
 #define CA_NDS           2
 #define CA_DSS           4
 } ca_descr_info_t;
 
 typedef struct ca_caps {
-        unsigned int slot_num;     /* total number of CA card and module slots */
-        unsigned int slot_type;    /* OR of all supported types */
-        unsigned int descr_num;    /* total number of descrambler slots (keys) */
-        unsigned int descr_type;   /* OR of all supported types */
+	unsigned int slot_num;     /* total number of CA card and module slots */
+	unsigned int slot_type;    /* OR of all supported types */
+	unsigned int descr_num;    /* total number of descrambler slots (keys) */
+	unsigned int descr_type;   /* OR of all supported types */
 } ca_caps_t;
 
 /* a message to/from a CI-CAM */
 typedef struct ca_msg {
-        unsigned int index;
-        unsigned int type;
-        unsigned int length;
-        unsigned char msg[256];
+	unsigned int index;
+	unsigned int type;
+	unsigned int length;
+	unsigned char msg[256];
 } ca_msg_t;
 
 typedef struct ca_descr {
-        unsigned int index;
-        unsigned int parity;	/* 0 == even, 1 == odd */
-        unsigned char cw[8];
+	unsigned int index;
+	unsigned int parity;	/* 0 == even, 1 == odd */
+	unsigned char cw[8];
 } ca_descr_t;
 
 typedef struct ca_pid {
-        unsigned int pid;
-        int index;		/* -1 == disable*/
+	unsigned int pid;
+	int index;		/* -1 == disable*/
 } ca_pid_t;
 
 #define CA_RESET          _IO('o', 128)
diff --git a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h
index ce3f829..2787b8a 100644
--- a/include/linux/dvb/dmx.h
+++ b/include/linux/dvb/dmx.h
@@ -1,4 +1,4 @@
-/* 
+/*
  * dmx.h
  *
  * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
@@ -38,10 +38,10 @@
 {
 	DMX_OUT_DECODER, /* Streaming directly to decoder. */
 	DMX_OUT_TAP,     /* Output going to a memory buffer */
-	                 /* (to be retrieved via the read command).*/
+			 /* (to be retrieved via the read command).*/
 	DMX_OUT_TS_TAP   /* Output multiplexed into a new TS  */
-	                 /* (to be retrieved by reading from the */
-	                 /* logical DVR device).                 */
+			 /* (to be retrieved by reading from the */
+			 /* logical DVR device).                 */
 } dmx_output_t;
 
 
@@ -54,25 +54,25 @@
 
 typedef enum
 {
-        DMX_PES_AUDIO0,
+	DMX_PES_AUDIO0,
 	DMX_PES_VIDEO0,
 	DMX_PES_TELETEXT0,
 	DMX_PES_SUBTITLE0,
 	DMX_PES_PCR0,
 
-        DMX_PES_AUDIO1,
+	DMX_PES_AUDIO1,
 	DMX_PES_VIDEO1,
 	DMX_PES_TELETEXT1,
 	DMX_PES_SUBTITLE1,
 	DMX_PES_PCR1,
 
-        DMX_PES_AUDIO2,
+	DMX_PES_AUDIO2,
 	DMX_PES_VIDEO2,
 	DMX_PES_TELETEXT2,
 	DMX_PES_SUBTITLE2,
 	DMX_PES_PCR2,
 
-        DMX_PES_AUDIO3,
+	DMX_PES_AUDIO3,
 	DMX_PES_VIDEO3,
 	DMX_PES_TELETEXT3,
 	DMX_PES_SUBTITLE3,
@@ -90,8 +90,8 @@
 
 typedef enum
 {
-        DMX_SCRAMBLING_EV,
-        DMX_FRONTEND_EV
+	DMX_SCRAMBLING_EV,
+	DMX_FRONTEND_EV
 } dmx_event_t;
 
 
diff --git a/include/linux/dvb/osd.h b/include/linux/dvb/osd.h
index 0e1973d..880e684 100644
--- a/include/linux/dvb/osd.h
+++ b/include/linux/dvb/osd.h
@@ -98,43 +98,43 @@
 } OSD_Command;
 
 typedef struct osd_cmd_s {
-        OSD_Command cmd;
-        int x0;
-        int y0;
-        int x1;
-        int y1;
-        int color;
-        void __user *data;
+	OSD_Command cmd;
+	int x0;
+	int y0;
+	int x1;
+	int y1;
+	int color;
+	void __user *data;
 } osd_cmd_t;
 
 /* OSD_OpenRaw: set 'color' to desired window type */
 typedef enum {
-        OSD_BITMAP1,           /* 1 bit bitmap */
-        OSD_BITMAP2,           /* 2 bit bitmap */
-        OSD_BITMAP4,           /* 4 bit bitmap */
-        OSD_BITMAP8,           /* 8 bit bitmap */
-        OSD_BITMAP1HR,         /* 1 Bit bitmap half resolution */
-        OSD_BITMAP2HR,         /* 2 bit bitmap half resolution */
-        OSD_BITMAP4HR,         /* 4 bit bitmap half resolution */
-        OSD_BITMAP8HR,         /* 8 bit bitmap half resolution */
-        OSD_YCRCB422,          /* 4:2:2 YCRCB Graphic Display */
-        OSD_YCRCB444,          /* 4:4:4 YCRCB Graphic Display */
-        OSD_YCRCB444HR,        /* 4:4:4 YCRCB graphic half resolution */
-        OSD_VIDEOTSIZE,        /* True Size Normal MPEG Video Display */
-        OSD_VIDEOHSIZE,        /* MPEG Video Display Half Resolution */
-        OSD_VIDEOQSIZE,        /* MPEG Video Display Quarter Resolution */
-        OSD_VIDEODSIZE,        /* MPEG Video Display Double Resolution */
-        OSD_VIDEOTHSIZE,       /* True Size MPEG Video Display Half Resolution */
-        OSD_VIDEOTQSIZE,       /* True Size MPEG Video Display Quarter Resolution*/
-        OSD_VIDEOTDSIZE,       /* True Size MPEG Video Display Double Resolution */
-        OSD_VIDEONSIZE,        /* Full Size MPEG Video Display */
-        OSD_CURSOR             /* Cursor */
+	OSD_BITMAP1,           /* 1 bit bitmap */
+	OSD_BITMAP2,           /* 2 bit bitmap */
+	OSD_BITMAP4,           /* 4 bit bitmap */
+	OSD_BITMAP8,           /* 8 bit bitmap */
+	OSD_BITMAP1HR,         /* 1 Bit bitmap half resolution */
+	OSD_BITMAP2HR,         /* 2 bit bitmap half resolution */
+	OSD_BITMAP4HR,         /* 4 bit bitmap half resolution */
+	OSD_BITMAP8HR,         /* 8 bit bitmap half resolution */
+	OSD_YCRCB422,          /* 4:2:2 YCRCB Graphic Display */
+	OSD_YCRCB444,          /* 4:4:4 YCRCB Graphic Display */
+	OSD_YCRCB444HR,        /* 4:4:4 YCRCB graphic half resolution */
+	OSD_VIDEOTSIZE,        /* True Size Normal MPEG Video Display */
+	OSD_VIDEOHSIZE,        /* MPEG Video Display Half Resolution */
+	OSD_VIDEOQSIZE,        /* MPEG Video Display Quarter Resolution */
+	OSD_VIDEODSIZE,        /* MPEG Video Display Double Resolution */
+	OSD_VIDEOTHSIZE,       /* True Size MPEG Video Display Half Resolution */
+	OSD_VIDEOTQSIZE,       /* True Size MPEG Video Display Quarter Resolution*/
+	OSD_VIDEOTDSIZE,       /* True Size MPEG Video Display Double Resolution */
+	OSD_VIDEONSIZE,        /* Full Size MPEG Video Display */
+	OSD_CURSOR             /* Cursor */
 } osd_raw_window_t;
 
 typedef struct osd_cap_s {
-        int  cmd;
+	int  cmd;
 #define OSD_CAP_MEMSIZE         1  /* memory size */
-        long val;
+	long val;
 } osd_cap_t;
 
 
diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h
index 941045e..b1999bf 100644
--- a/include/linux/dvb/video.h
+++ b/include/linux/dvb/video.h
@@ -36,7 +36,7 @@
 
 typedef enum {
 	VIDEO_FORMAT_4_3,     /* Select 4:3 format */
-        VIDEO_FORMAT_16_9,    /* Select 16:9 format. */
+	VIDEO_FORMAT_16_9,    /* Select 16:9 format. */
 	VIDEO_FORMAT_221_1    /* 2.21:1 */
 } video_format_t;
 
@@ -54,7 +54,7 @@
 
 
 typedef enum {
-        VIDEO_PAN_SCAN,       /* use pan and scan format */
+	VIDEO_PAN_SCAN,       /* use pan and scan format */
 	VIDEO_LETTER_BOX,     /* use letterbox format */
 	VIDEO_CENTER_CUT_OUT  /* use center cut out format */
 } video_displayformat_t;
@@ -66,7 +66,7 @@
 } video_size_t;
 
 typedef enum {
-        VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
+	VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */
 	VIDEO_SOURCE_MEMORY /* If this source is selected, the stream
 			       comes from the user through the write
 			       system call */
@@ -75,35 +75,35 @@
 
 typedef enum {
 	VIDEO_STOPPED, /* Video is stopped */
-        VIDEO_PLAYING, /* Video is currently playing */
+	VIDEO_PLAYING, /* Video is currently playing */
 	VIDEO_FREEZED  /* Video is freezed */
 } video_play_state_t;
 
 
 struct video_event {
-        int32_t type;
+	int32_t type;
 #define VIDEO_EVENT_SIZE_CHANGED	1
 #define VIDEO_EVENT_FRAME_RATE_CHANGED	2
-        time_t timestamp;
+	time_t timestamp;
 	union {
-	        video_size_t size;
+		video_size_t size;
 		unsigned int frame_rate;	/* in frames per 1000sec */
 	} u;
 };
 
 
 struct video_status {
-        int                   video_blank;   /* blank video on freeze? */
-        video_play_state_t    play_state;    /* current state of playback */
-        video_stream_source_t stream_source; /* current source (demux/memory) */
-        video_format_t        video_format;  /* current aspect ratio of stream*/
-        video_displayformat_t display_format;/* selected cropping mode */
+	int                   video_blank;   /* blank video on freeze? */
+	video_play_state_t    play_state;    /* current state of playback */
+	video_stream_source_t stream_source; /* current source (demux/memory) */
+	video_format_t        video_format;  /* current aspect ratio of stream*/
+	video_displayformat_t display_format;/* selected cropping mode */
 };
 
 
 struct video_still_picture {
-        char __user *iFrame;        /* pointer to a single iframe in memory */
-        int32_t size;
+	char __user *iFrame;        /* pointer to a single iframe in memory */
+	int32_t size;
 };
 
 
@@ -111,19 +111,19 @@
 struct video_highlight {
 	int     active;      /*    1=show highlight, 0=hide highlight */
 	uint8_t contrast1;   /*    7- 4  Pattern pixel contrast */
-                             /*    3- 0  Background pixel contrast */
+			     /*    3- 0  Background pixel contrast */
 	uint8_t contrast2;   /*    7- 4  Emphasis pixel-2 contrast */
-                             /*    3- 0  Emphasis pixel-1 contrast */
+			     /*    3- 0  Emphasis pixel-1 contrast */
 	uint8_t color1;      /*    7- 4  Pattern pixel color */
-                             /*    3- 0  Background pixel color */
+			     /*    3- 0  Background pixel color */
 	uint8_t color2;      /*    7- 4  Emphasis pixel-2 color */
-                             /*    3- 0  Emphasis pixel-1 color */
+			     /*    3- 0  Emphasis pixel-1 color */
 	uint32_t ypos;       /*   23-22  auto action mode */
-                             /*   21-12  start y */
-                             /*    9- 0  end y */
+			     /*   21-12  start y */
+			     /*    9- 0  end y */
 	uint32_t xpos;       /*   23-22  button color number */
-                             /*   21-12  start x */
-                             /*    9- 0  end x */
+			     /*   21-12  start x */
+			     /*    9- 0  end x */
 } video_highlight_t;
 
 
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index a74c27e..fb80fa4 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -130,6 +130,7 @@
 #define ELEVATOR_INSERT_FRONT	1
 #define ELEVATOR_INSERT_BACK	2
 #define ELEVATOR_INSERT_SORT	3
+#define ELEVATOR_INSERT_REQUEUE	4
 
 /*
  * return values from elevator_may_queue_fn
diff --git a/include/linux/elf.h b/include/linux/elf.h
index ff955db..d3bfacb 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -151,6 +151,8 @@
 #define STT_FUNC    2
 #define STT_SECTION 3
 #define STT_FILE    4
+#define STT_COMMON  5
+#define STT_TLS     6
 
 #define ELF_ST_BIND(x)		((x) >> 4)
 #define ELF_ST_TYPE(x)		(((unsigned int) x) & 0xf)
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 5f49a30..745c988 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -63,10 +63,11 @@
  * @addr: Pointer to a six-byte array containing the Ethernet address
  *
  * Return true if the address is a multicast address.
+ * By definition the broadcast address is also a multicast address.
  */
 static inline int is_multicast_ether_addr(const u8 *addr)
 {
-	return ((addr[0] != 0xff) && (0x01 & addr[0]));
+	return (0x01 & addr[0]);
 }
 
 /**
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 04a58f3..a973be2 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -617,6 +617,12 @@
 
 	/* perform fb specific mmap */
 	int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
+
+	/* save current hardware state */
+	void (*fb_save_state)(struct fb_info *info);
+
+	/* restore saved state */
+	void (*fb_restore_state)(struct fb_info *info);
 };
 
 #ifdef CONFIG_FB_TILEBLITTING
@@ -726,6 +732,18 @@
 						  from userspace */
 #define FBINFO_MISC_TILEBLITTING       0x20000 /* use tile blitting */
 
+/* A driver may set this flag to indicate that it does want a set_par to be
+ * called every time when fbcon_switch is executed. The advantage is that with
+ * this flag set you can really be shure that set_par is always called before
+ * any of the functions dependant on the correct hardware state or altering
+ * that state, even if you are using some broken X releases. The disadvantage
+ * is that it introduces unwanted delays to every console switch if set_par
+ * is slow. It is a good idea to try this flag in the drivers initialization
+ * code whenever there is a bug report related to switching between X and the
+ * framebuffer console.
+ */
+#define FBINFO_MISC_ALWAYS_SETPAR   0x40000
+
 struct fb_info {
 	int node;
 	int flags;
@@ -817,6 +835,18 @@
 
 #endif
 
+#if defined (__BIG_ENDIAN)
+#define FB_LEFT_POS(bpp)          (32 - bpp)
+#define FB_SHIFT_HIGH(val, bits)  ((val) >> (bits))
+#define FB_SHIFT_LOW(val, bits)   ((val) << (bits))
+#define FB_BIT_NR(b)              (7 - (b))
+#else
+#define FB_LEFT_POS(bpp)          (0)
+#define FB_SHIFT_HIGH(val, bits)  ((val) << (bits))
+#define FB_SHIFT_LOW(val, bits)   ((val) >> (bits))
+#define FB_BIT_NR(b)              (b)
+#endif
+
     /*
      *  `Generic' versions of the frame buffer device operations
      */
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 3ba843c..c6cb8f0 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -143,7 +143,7 @@
 struct sk_buff;
 struct sock;
 
-extern int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen);
+extern unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen);
 extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk);
 extern int sk_chk_filter(struct sock_filter *filter, int flen);
 #endif /* __KERNEL__ */
diff --git a/include/linux/firmware.h b/include/linux/firmware.h
index 2063c08..2d71608 100644
--- a/include/linux/firmware.h
+++ b/include/linux/firmware.h
@@ -14,7 +14,7 @@
 int request_firmware(const struct firmware **fw, const char *name,
 		     struct device *device);
 int request_firmware_nowait(
-	struct module *module, int hotplug,
+	struct module *module, int uevent,
 	const char *name, struct device *device, void *context,
 	void (*cont)(const struct firmware *fw, void *context));
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index cc35b6a..4c82219 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -9,7 +9,6 @@
 #include <linux/config.h>
 #include <linux/limits.h>
 #include <linux/ioctl.h>
-#include <linux/rcuref.h>
 
 /*
  * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
@@ -104,11 +103,11 @@
 #define MS_MOVE		8192
 #define MS_REC		16384
 #define MS_VERBOSE	32768
+#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
 #define MS_UNBINDABLE	(1<<17)	/* change to unbindable */
 #define MS_PRIVATE	(1<<18)	/* change to private */
 #define MS_SLAVE	(1<<19)	/* change to slave */
 #define MS_SHARED	(1<<20)	/* change to shared */
-#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
 #define MS_ACTIVE	(1<<30)
 #define MS_NOUSER	(1<<31)
 
@@ -225,6 +224,7 @@
 #include <asm/semaphore.h>
 #include <asm/byteorder.h>
 
+struct hd_geometry;
 struct iovec;
 struct nameidata;
 struct kiocb;
@@ -302,6 +302,37 @@
  */
 #include <linux/quota.h>
 
+/** 
+ * enum positive_aop_returns - aop return codes with specific semantics
+ *
+ * @AOP_WRITEPAGE_ACTIVATE: Informs the caller that page writeback has
+ * 			    completed, that the page is still locked, and
+ * 			    should be considered active.  The VM uses this hint
+ * 			    to return the page to the active list -- it won't
+ * 			    be a candidate for writeback again in the near
+ * 			    future.  Other callers must be careful to unlock
+ * 			    the page if they get this return.  Returned by
+ * 			    writepage(); 
+ *
+ * @AOP_TRUNCATED_PAGE: The AOP method that was handed a locked page has
+ *  			unlocked it and the page might have been truncated.
+ *  			The caller should back up to acquiring a new page and
+ *  			trying again.  The aop will be taking reasonable
+ *  			precautions not to livelock.  If the caller held a page
+ *  			reference, it should drop it before retrying.  Returned
+ *  			by readpage(), prepare_write(), and commit_write().
+ *
+ * address_space_operation functions return these large constants to indicate
+ * special semantics to the caller.  These are much larger than the bytes in a
+ * page to allow for functions that return the number of bytes operated on in a
+ * given page.
+ */
+
+enum positive_aop_returns {
+	AOP_WRITEPAGE_ACTIVATE	= 0x80000,
+	AOP_TRUNCATED_PAGE	= 0x80001,
+};
+
 /*
  * oh the beauties of C type declarations.
  */
@@ -622,7 +653,7 @@
 #define file_list_lock() spin_lock(&files_lock);
 #define file_list_unlock() spin_unlock(&files_lock);
 
-#define get_file(x)	rcuref_inc(&(x)->f_count)
+#define get_file(x)	atomic_inc(&(x)->f_count)
 #define file_count(x)	atomic_read(&(x)->f_count)
 
 #define	MAX_NON_LFS	((1UL<<31) - 1)
@@ -729,7 +760,7 @@
 extern int posix_lock_file(struct file *, struct file_lock *);
 extern int posix_lock_file_wait(struct file *, struct file_lock *);
 extern void posix_block_lock(struct file_lock *, struct file_lock *);
-extern void posix_unblock_lock(struct file *, struct file_lock *);
+extern int posix_unblock_lock(struct file *, struct file_lock *);
 extern int posix_locks_deadlock(struct file_lock *, struct file_lock *);
 extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
 extern int __break_lease(struct inode *inode, unsigned int flags);
@@ -777,7 +808,6 @@
 	struct list_head	s_list;		/* Keep this first */
 	dev_t			s_dev;		/* search index; _not_ kdev_t */
 	unsigned long		s_blocksize;
-	unsigned long		s_old_blocksize;
 	unsigned char		s_blocksize_bits;
 	unsigned char		s_dirt;
 	unsigned long long	s_maxbytes;	/* Max file size */
@@ -932,6 +962,7 @@
 	int (*direct_access) (struct block_device *, sector_t, unsigned long *);
 	int (*media_changed) (struct gendisk *);
 	int (*revalidate_disk) (struct gendisk *);
+	int (*getgeo)(struct block_device *, struct hd_geometry *);
 	struct module *owner;
 };
 
@@ -1019,6 +1050,7 @@
 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
 	int (*removexattr) (struct dentry *, const char *);
+	void (*truncate_range)(struct inode *, loff_t, loff_t);
 };
 
 struct seq_file;
@@ -1313,7 +1345,8 @@
 
 /* fs/open.c */
 
-extern int do_truncate(struct dentry *, loff_t start, struct file *filp);
+extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
+		       struct file *filp);
 extern long do_sys_open(const char __user *filename, int flags, int mode);
 extern struct file *filp_open(const char *, int, int);
 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index b76b558..528959c 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -14,7 +14,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 3
+#define FUSE_KERNEL_MINOR_VERSION 5
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -53,6 +53,9 @@
 	__u64	ffree;
 	__u32	bsize;
 	__u32	namelen;
+	__u32	frsize;
+	__u32	padding;
+	__u32	spare[6];
 };
 
 #define FATTR_MODE	(1 << 0)
@@ -105,12 +108,8 @@
 	FUSE_CREATE        = 35
 };
 
-/* Conservative buffer size for the client */
-#define FUSE_MAX_IN 8192
-
-#define FUSE_NAME_MAX 1024
-#define FUSE_SYMLINK_MAX 4096
-#define FUSE_XATTR_SIZE_MAX 4096
+/* The read buffer is required to be at least 8k, but may be much larger */
+#define FUSE_MIN_READ_BUFFER 8192
 
 struct fuse_entry_out {
 	__u64	nodeid;		/* Inode ID */
@@ -213,6 +212,8 @@
 	__u32	padding;
 };
 
+#define FUSE_COMPAT_STATFS_SIZE 48
+
 struct fuse_statfs_out {
 	struct fuse_kstatfs st;
 };
@@ -243,11 +244,18 @@
 	__u32	padding;
 };
 
-struct fuse_init_in_out {
+struct fuse_init_in {
 	__u32	major;
 	__u32	minor;
 };
 
+struct fuse_init_out {
+	__u32	major;
+	__u32	minor;
+	__u32	unused[3];
+	__u32	max_write;
+};
+
 struct fuse_in_header {
 	__u32	len;
 	__u32	opcode;
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 1056717..68d82ad 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -22,7 +22,7 @@
 int hugetlb_report_node_meminfo(int, char *);
 int is_hugepage_mem_enough(size_t);
 unsigned long hugetlb_total_pages(void);
-struct page *alloc_huge_page(void);
+struct page *alloc_huge_page(struct vm_area_struct *, unsigned long);
 void free_huge_page(struct page *);
 int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 			unsigned long address, int write_access);
@@ -97,7 +97,7 @@
 #define is_hugepage_only_range(mm, addr, len)	0
 #define hugetlb_free_pgd_range(tlb, addr, end, floor, ceiling) \
 						do { } while (0)
-#define alloc_huge_page()			({ NULL; })
+#define alloc_huge_page(vma, addr)		({ NULL; })
 #define free_huge_page(p)			({ (void)(p); BUG(); })
 #define hugetlb_fault(mm, vma, addr, write)	({ BUG(); 0; })
 
diff --git a/include/linux/hwmon-vid.h b/include/linux/hwmon-vid.h
index cd4b7a0..f346e4d 100644
--- a/include/linux/hwmon-vid.h
+++ b/include/linux/hwmon-vid.h
@@ -23,14 +23,14 @@
 #ifndef _LINUX_HWMON_VID_H
 #define _LINUX_HWMON_VID_H
 
-int vid_from_reg(int val, int vrm);
-int vid_which_vrm(void);
+int vid_from_reg(int val, u8 vrm);
+u8 vid_which_vrm(void);
 
 /* vrm is the VRM/VRD document version multiplied by 10.
    val is in mV to avoid floating point in the kernel.
    Returned value is the 4-, 5- or 6-bit VID code.
    Note that only VRM 9.x is supported for now. */
-static inline int vid_to_reg(int val, int vrm)
+static inline int vid_to_reg(int val, u8 vrm)
 {
 	switch (vrm) {
 	case 91:		/* VRM 9.1 */
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 1543daa..fb46f8d 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -25,12 +25,6 @@
 
 /*
  * ---- Driver types -----------------------------------------------------
- *       device id name + number        function description, i2c address(es)
- *
- *  Range 1000-1999 range is defined in sensors/sensors.h
- *  Range 0x100 - 0x1ff is for V4L2 Common Components
- *  Range 0xf000 - 0xffff is reserved for local experimentation, and should
- *        never be used in official drivers
  */
 
 #define I2C_DRIVERID_MSP3400	 1
@@ -108,14 +102,9 @@
 #define I2C_DRIVERID_SAA7127	72	/* saa7124 video encoder	*/
 #define I2C_DRIVERID_SAA711X	73	/* saa711x video encoders	*/
 #define I2C_DRIVERID_AKITAIOEXP	74	/* IO Expander on Sharp SL-C1000 */
-
-#define I2C_DRIVERID_EXP0	0xF0	/* experimental use id's	*/
-#define I2C_DRIVERID_EXP1	0xF1
-#define I2C_DRIVERID_EXP2	0xF2
-#define I2C_DRIVERID_EXP3	0xF3
+#define I2C_DRIVERID_INFRARED	75	/* I2C InfraRed on Video boards */
 
 #define I2C_DRIVERID_I2CDEV	900
-#define I2C_DRIVERID_I2CPROC	901
 #define I2C_DRIVERID_ARP        902    /* SMBus ARP Client              */
 #define I2C_DRIVERID_ALERT      903    /* SMBus Alert Responder Client  */
 
@@ -130,15 +119,12 @@
 #define I2C_DRIVERID_ADM1021 1008
 #define I2C_DRIVERID_ADM9240 1009
 #define I2C_DRIVERID_LTC1710 1010
-#define I2C_DRIVERID_SIS5595 1011
 #define I2C_DRIVERID_ICSPLL 1012
 #define I2C_DRIVERID_BT869 1013
 #define I2C_DRIVERID_MAXILIFE 1014
 #define I2C_DRIVERID_MATORB 1015
 #define I2C_DRIVERID_GL520 1016
 #define I2C_DRIVERID_THMC50 1017
-#define I2C_DRIVERID_DDCMON 1018
-#define I2C_DRIVERID_VIA686A 1019
 #define I2C_DRIVERID_ADM1025 1020
 #define I2C_DRIVERID_LM87 1021
 #define I2C_DRIVERID_PCF8574 1022
@@ -150,21 +136,16 @@
 #define I2C_DRIVERID_FSCPOS 1028
 #define I2C_DRIVERID_FSCSCY 1029
 #define I2C_DRIVERID_PCF8591 1030
-#define I2C_DRIVERID_SMSC47M1 1031
-#define I2C_DRIVERID_VT1211 1032
 #define I2C_DRIVERID_LM92 1033
-#define I2C_DRIVERID_VT8231 1034
 #define I2C_DRIVERID_SMARTBATT 1035
 #define I2C_DRIVERID_BMCSENSORS 1036
 #define I2C_DRIVERID_FS451 1037
-#define I2C_DRIVERID_W83627HF 1038
 #define I2C_DRIVERID_LM85 1039
 #define I2C_DRIVERID_LM83 1040
 #define I2C_DRIVERID_LM90 1042
 #define I2C_DRIVERID_ASB100 1043
 #define I2C_DRIVERID_FSCHER 1046
 #define I2C_DRIVERID_W83L785TS 1047
-#define I2C_DRIVERID_SMSC47B397 1050
 
 /*
  * ---- Adapter types ----------------------------------------------------
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 5e19a7b..7863a59 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -105,14 +105,14 @@
  * A driver is capable of handling one or more physical devices present on
  * I2C adapters. This information is used to inform the driver of adapter
  * events.
+ *
+ * The driver.owner field should be set to the module owner of this driver.
+ * The driver.name field should be set to the name of this driver.
  */
 
 struct i2c_driver {
-	struct module *owner;
-	char name[32];
 	int id;
 	unsigned int class;
-	unsigned int flags;		/* div., see below		*/
 
 	/* Notifies the driver that a new bus has appeared. This routine
 	 * can be used by the driver to test if the bus meets its conditions
@@ -250,18 +250,7 @@
 	dev_set_drvdata (&dev->dev, data);
 }
 
-/*flags for the driver struct: */
-#define I2C_DF_NOTIFY	0x01		/* notify on bus (de/a)ttaches 	*/
-#if 0
-/* this flag is gone -- there is a (optional) driver->detach_adapter
- * callback now which can be used instead */
-# define I2C_DF_DUMMY	0x02
-#endif
-
 /*flags for the client struct: */
-#define I2C_CLIENT_ALLOW_USE		0x01	/* Client allows access */
-#define I2C_CLIENT_ALLOW_MULTIPLE_USE 	0x02  	/* Allow multiple access-locks */
-						/* on an i2c_client */
 #define I2C_CLIENT_PEC  0x04			/* Use Packet Error Checking */
 #define I2C_CLIENT_TEN	0x10			/* we have a ten bit chip address	*/
 						/* Must equal I2C_M_TEN below */
@@ -302,26 +291,20 @@
 extern int i2c_add_adapter(struct i2c_adapter *);
 extern int i2c_del_adapter(struct i2c_adapter *);
 
-extern int i2c_add_driver(struct i2c_driver *);
+extern int i2c_register_driver(struct module *, struct i2c_driver *);
 extern int i2c_del_driver(struct i2c_driver *);
 
+static inline int i2c_add_driver(struct i2c_driver *driver)
+{
+	return i2c_register_driver(THIS_MODULE, driver);
+}
+
 extern int i2c_attach_client(struct i2c_client *);
 extern int i2c_detach_client(struct i2c_client *);
 
-/* New function: This is to get an i2c_client-struct for controlling the 
-   client either by using i2c_control-function or having the 
-   client-module export functions that can be used with the i2c_client
-   -struct. */
-extern struct i2c_client *i2c_get_client(int driver_id, int adapter_id, 
-					struct i2c_client *prev);
-
-/* Should be used with new function
-   extern struct i2c_client *i2c_get_client(int,int,struct i2c_client *);
-   to make sure that client-struct is valid and that it is okay to access
-   the i2c-client. 
-   returns -EACCES if client doesn't allow use (default)
-   returns -EBUSY if client doesn't allow multiple use (default) and 
-   usage_count >0 */
+/* Should be used to make sure that client-struct is valid and that it
+   is okay to access the i2c-client.
+   returns -ENODEV if client has gone in the meantime */
 extern int i2c_use_client(struct i2c_client *);
 extern int i2c_release_client(struct i2c_client *);
 
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index d79c8a4..9ba8067 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -30,6 +30,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>	/* work_struct */
+#include <linux/mempool.h>
 
 #include <asm/io.h>
 #include <asm/semaphore.h>	/* Needed for MUTEX init macros */
@@ -38,748 +39,6 @@
 #define I2O_QUEUE_EMPTY		0xffffffff
 
 /*
- *	Message structures
- */
-struct i2o_message {
-	union {
-		struct {
-			u8 version_offset;
-			u8 flags;
-			u16 size;
-			u32 target_tid:12;
-			u32 init_tid:12;
-			u32 function:8;
-			u32 icntxt;	/* initiator context */
-			u32 tcntxt;	/* transaction context */
-		} s;
-		u32 head[4];
-	} u;
-	/* List follows */
-	u32 body[0];
-};
-
-/*
- *	Each I2O device entity has one of these. There is one per device.
- */
-struct i2o_device {
-	i2o_lct_entry lct_data;	/* Device LCT information */
-
-	struct i2o_controller *iop;	/* Controlling IOP */
-	struct list_head list;	/* node in IOP devices list */
-
-	struct device device;
-
-	struct semaphore lock;	/* device lock */
-};
-
-/*
- *	Event structure provided to the event handling function
- */
-struct i2o_event {
-	struct work_struct work;
-	struct i2o_device *i2o_dev;	/* I2O device pointer from which the
-					   event reply was initiated */
-	u16 size;		/* Size of data in 32-bit words */
-	u32 tcntxt;		/* Transaction context used at
-				   registration */
-	u32 event_indicator;	/* Event indicator from reply */
-	u32 data[0];		/* Event data from reply */
-};
-
-/*
- *	I2O classes which could be handled by the OSM
- */
-struct i2o_class_id {
-	u16 class_id:12;
-};
-
-/*
- *	I2O driver structure for OSMs
- */
-struct i2o_driver {
-	char *name;		/* OSM name */
-	int context;		/* Low 8 bits of the transaction info */
-	struct i2o_class_id *classes;	/* I2O classes that this OSM handles */
-
-	/* Message reply handler */
-	int (*reply) (struct i2o_controller *, u32, struct i2o_message *);
-
-	/* Event handler */
-	void (*event) (struct i2o_event *);
-
-	struct workqueue_struct *event_queue;	/* Event queue */
-
-	struct device_driver driver;
-
-	/* notification of changes */
-	void (*notify_controller_add) (struct i2o_controller *);
-	void (*notify_controller_remove) (struct i2o_controller *);
-	void (*notify_device_add) (struct i2o_device *);
-	void (*notify_device_remove) (struct i2o_device *);
-
-	struct semaphore lock;
-};
-
-/*
- *	Contains DMA mapped address information
- */
-struct i2o_dma {
-	void *virt;
-	dma_addr_t phys;
-	size_t len;
-};
-
-/*
- *	Contains IO mapped address information
- */
-struct i2o_io {
-	void __iomem *virt;
-	unsigned long phys;
-	unsigned long len;
-};
-
-/*
- *	Context queue entry, used for 32-bit context on 64-bit systems
- */
-struct i2o_context_list_element {
-	struct list_head list;
-	u32 context;
-	void *ptr;
-	unsigned long timestamp;
-};
-
-/*
- * Each I2O controller has one of these objects
- */
-struct i2o_controller {
-	char name[16];
-	int unit;
-	int type;
-
-	struct pci_dev *pdev;	/* PCI device */
-
-	unsigned int promise:1;	/* Promise controller */
-	unsigned int adaptec:1;	/* DPT / Adaptec controller */
-	unsigned int raptor:1;	/* split bar */
-	unsigned int no_quiesce:1;	/* dont quiesce before reset */
-	unsigned int short_req:1;	/* use small block sizes */
-	unsigned int limit_sectors:1;	/* limit number of sectors / request */
-	unsigned int pae_support:1;	/* controller has 64-bit SGL support */
-
-	struct list_head devices;	/* list of I2O devices */
-	struct list_head list;	/* Controller list */
-
-	void __iomem *in_port;	/* Inbout port address */
-	void __iomem *out_port;	/* Outbound port address */
-	void __iomem *irq_status;	/* Interrupt status register address */
-	void __iomem *irq_mask;	/* Interrupt mask register address */
-
-	/* Dynamic LCT related data */
-
-	struct i2o_dma status;	/* IOP status block */
-
-	struct i2o_dma hrt;	/* HW Resource Table */
-	i2o_lct *lct;		/* Logical Config Table */
-	struct i2o_dma dlct;	/* Temp LCT */
-	struct semaphore lct_lock;	/* Lock for LCT updates */
-	struct i2o_dma status_block;	/* IOP status block */
-
-	struct i2o_io base;	/* controller messaging unit */
-	struct i2o_io in_queue;	/* inbound message queue Host->IOP */
-	struct i2o_dma out_queue;	/* outbound message queue IOP->Host */
-
-	unsigned int battery:1;	/* Has a battery backup */
-	unsigned int io_alloc:1;	/* An I/O resource was allocated */
-	unsigned int mem_alloc:1;	/* A memory resource was allocated */
-
-	struct resource io_resource;	/* I/O resource allocated to the IOP */
-	struct resource mem_resource;	/* Mem resource allocated to the IOP */
-
-	struct device device;
-	struct class_device *classdev;	/* I2O controller class device */
-	struct i2o_device *exec;	/* Executive */
-#if BITS_PER_LONG == 64
-	spinlock_t context_list_lock;	/* lock for context_list */
-	atomic_t context_list_counter;	/* needed for unique contexts */
-	struct list_head context_list;	/* list of context id's
-					   and pointers */
-#endif
-	spinlock_t lock;	/* lock for controller
-				   configuration */
-
-	void *driver_data[I2O_MAX_DRIVERS];	/* storage for drivers */
-};
-
-/*
- * I2O System table entry
- *
- * The system table contains information about all the IOPs in the
- * system.  It is sent to all IOPs so that they can create peer2peer
- * connections between them.
- */
-struct i2o_sys_tbl_entry {
-	u16 org_id;
-	u16 reserved1;
-	u32 iop_id:12;
-	u32 reserved2:20;
-	u16 seg_num:12;
-	u16 i2o_version:4;
-	u8 iop_state;
-	u8 msg_type;
-	u16 frame_size;
-	u16 reserved3;
-	u32 last_changed;
-	u32 iop_capabilities;
-	u32 inbound_low;
-	u32 inbound_high;
-};
-
-struct i2o_sys_tbl {
-	u8 num_entries;
-	u8 version;
-	u16 reserved1;
-	u32 change_ind;
-	u32 reserved2;
-	u32 reserved3;
-	struct i2o_sys_tbl_entry iops[0];
-};
-
-extern struct list_head i2o_controllers;
-
-/* Message functions */
-static inline u32 i2o_msg_get(struct i2o_controller *,
-			      struct i2o_message __iomem **);
-extern u32 i2o_msg_get_wait(struct i2o_controller *,
-			    struct i2o_message __iomem **, int);
-static inline void i2o_msg_post(struct i2o_controller *, u32);
-static inline int i2o_msg_post_wait(struct i2o_controller *, u32,
-				    unsigned long);
-extern int i2o_msg_post_wait_mem(struct i2o_controller *, u32, unsigned long,
-				 struct i2o_dma *);
-extern void i2o_msg_nop(struct i2o_controller *, u32);
-static inline void i2o_flush_reply(struct i2o_controller *, u32);
-
-/* IOP functions */
-extern int i2o_status_get(struct i2o_controller *);
-
-extern int i2o_event_register(struct i2o_device *, struct i2o_driver *, int,
-			      u32);
-extern struct i2o_device *i2o_iop_find_device(struct i2o_controller *, u16);
-extern struct i2o_controller *i2o_find_iop(int);
-
-/* Functions needed for handling 64-bit pointers in 32-bit context */
-#if BITS_PER_LONG == 64
-extern u32 i2o_cntxt_list_add(struct i2o_controller *, void *);
-extern void *i2o_cntxt_list_get(struct i2o_controller *, u32);
-extern u32 i2o_cntxt_list_remove(struct i2o_controller *, void *);
-extern u32 i2o_cntxt_list_get_ptr(struct i2o_controller *, void *);
-
-static inline u32 i2o_ptr_low(void *ptr)
-{
-	return (u32) (u64) ptr;
-};
-
-static inline u32 i2o_ptr_high(void *ptr)
-{
-	return (u32) ((u64) ptr >> 32);
-};
-
-static inline u32 i2o_dma_low(dma_addr_t dma_addr)
-{
-	return (u32) (u64) dma_addr;
-};
-
-static inline u32 i2o_dma_high(dma_addr_t dma_addr)
-{
-	return (u32) ((u64) dma_addr >> 32);
-};
-#else
-static inline u32 i2o_cntxt_list_add(struct i2o_controller *c, void *ptr)
-{
-	return (u32) ptr;
-};
-
-static inline void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context)
-{
-	return (void *)context;
-};
-
-static inline u32 i2o_cntxt_list_remove(struct i2o_controller *c, void *ptr)
-{
-	return (u32) ptr;
-};
-
-static inline u32 i2o_cntxt_list_get_ptr(struct i2o_controller *c, void *ptr)
-{
-	return (u32) ptr;
-};
-
-static inline u32 i2o_ptr_low(void *ptr)
-{
-	return (u32) ptr;
-};
-
-static inline u32 i2o_ptr_high(void *ptr)
-{
-	return 0;
-};
-
-static inline u32 i2o_dma_low(dma_addr_t dma_addr)
-{
-	return (u32) dma_addr;
-};
-
-static inline u32 i2o_dma_high(dma_addr_t dma_addr)
-{
-	return 0;
-};
-#endif
-
-/**
- *	i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
- *	@c: I2O controller for which the calculation should be done
- *	@body_size: maximum body size used for message in 32-bit words.
- *
- *	Return the maximum number of SG elements in a SG list.
- */
-static inline u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
-{
-	i2o_status_block *sb = c->status_block.virt;
-	u16 sg_count =
-	    (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
-	    body_size;
-
-	if (c->pae_support) {
-		/*
-		 * for 64-bit a SG attribute element must be added and each
-		 * SG element needs 12 bytes instead of 8.
-		 */
-		sg_count -= 2;
-		sg_count /= 3;
-	} else
-		sg_count /= 2;
-
-	if (c->short_req && (sg_count > 8))
-		sg_count = 8;
-
-	return sg_count;
-};
-
-/**
- *	i2o_dma_map_single - Map pointer to controller and fill in I2O message.
- *	@c: I2O controller
- *	@ptr: pointer to the data which should be mapped
- *	@size: size of data in bytes
- *	@direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
- *	@sg_ptr: pointer to the SG list inside the I2O message
- *
- *	This function does all necessary DMA handling and also writes the I2O
- *	SGL elements into the I2O message. For details on DMA handling see also
- *	dma_map_single(). The pointer sg_ptr will only be set to the end of the
- *	SG list if the allocation was successful.
- *
- *	Returns DMA address which must be checked for failures using
- *	dma_mapping_error().
- */
-static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
-					    size_t size,
-					    enum dma_data_direction direction,
-					    u32 __iomem ** sg_ptr)
-{
-	u32 sg_flags;
-	u32 __iomem *mptr = *sg_ptr;
-	dma_addr_t dma_addr;
-
-	switch (direction) {
-	case DMA_TO_DEVICE:
-		sg_flags = 0xd4000000;
-		break;
-	case DMA_FROM_DEVICE:
-		sg_flags = 0xd0000000;
-		break;
-	default:
-		return 0;
-	}
-
-	dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
-	if (!dma_mapping_error(dma_addr)) {
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
-		if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
-			writel(0x7C020002, mptr++);
-			writel(PAGE_SIZE, mptr++);
-		}
-#endif
-
-		writel(sg_flags | size, mptr++);
-		writel(i2o_dma_low(dma_addr), mptr++);
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
-		if ((sizeof(dma_addr_t) > 4) && c->pae_support)
-			writel(i2o_dma_high(dma_addr), mptr++);
-#endif
-		*sg_ptr = mptr;
-	}
-	return dma_addr;
-};
-
-/**
- *	i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
- *	@c: I2O controller
- *	@sg: SG list to be mapped
- *	@sg_count: number of elements in the SG list
- *	@direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
- *	@sg_ptr: pointer to the SG list inside the I2O message
- *
- *	This function does all necessary DMA handling and also writes the I2O
- *	SGL elements into the I2O message. For details on DMA handling see also
- *	dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
- *	list if the allocation was successful.
- *
- *	Returns 0 on failure or 1 on success.
- */
-static inline int i2o_dma_map_sg(struct i2o_controller *c,
-				 struct scatterlist *sg, int sg_count,
-				 enum dma_data_direction direction,
-				 u32 __iomem ** sg_ptr)
-{
-	u32 sg_flags;
-	u32 __iomem *mptr = *sg_ptr;
-
-	switch (direction) {
-	case DMA_TO_DEVICE:
-		sg_flags = 0x14000000;
-		break;
-	case DMA_FROM_DEVICE:
-		sg_flags = 0x10000000;
-		break;
-	default:
-		return 0;
-	}
-
-	sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
-	if (!sg_count)
-		return 0;
-
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
-	if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
-		writel(0x7C020002, mptr++);
-		writel(PAGE_SIZE, mptr++);
-	}
-#endif
-
-	while (sg_count-- > 0) {
-		if (!sg_count)
-			sg_flags |= 0xC0000000;
-		writel(sg_flags | sg_dma_len(sg), mptr++);
-		writel(i2o_dma_low(sg_dma_address(sg)), mptr++);
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
-		if ((sizeof(dma_addr_t) > 4) && c->pae_support)
-			writel(i2o_dma_high(sg_dma_address(sg)), mptr++);
-#endif
-		sg++;
-	}
-	*sg_ptr = mptr;
-
-	return 1;
-};
-
-/**
- *	i2o_dma_alloc - Allocate DMA memory
- *	@dev: struct device pointer to the PCI device of the I2O controller
- *	@addr: i2o_dma struct which should get the DMA buffer
- *	@len: length of the new DMA memory
- *	@gfp_mask: GFP mask
- *
- *	Allocate a coherent DMA memory and write the pointers into addr.
- *
- *	Returns 0 on success or -ENOMEM on failure.
- */
-static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
-				size_t len, gfp_t gfp_mask)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	int dma_64 = 0;
-
-	if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
-		dma_64 = 1;
-		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK))
-			return -ENOMEM;
-	}
-
-	addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
-
-	if ((sizeof(dma_addr_t) > 4) && dma_64)
-		if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
-			printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
-
-	if (!addr->virt)
-		return -ENOMEM;
-
-	memset(addr->virt, 0, len);
-	addr->len = len;
-
-	return 0;
-};
-
-/**
- *	i2o_dma_free - Free DMA memory
- *	@dev: struct device pointer to the PCI device of the I2O controller
- *	@addr: i2o_dma struct which contains the DMA buffer
- *
- *	Free a coherent DMA memory and set virtual address of addr to NULL.
- */
-static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
-{
-	if (addr->virt) {
-		if (addr->phys)
-			dma_free_coherent(dev, addr->len, addr->virt,
-					  addr->phys);
-		else
-			kfree(addr->virt);
-		addr->virt = NULL;
-	}
-};
-
-/**
- *	i2o_dma_realloc - Realloc DMA memory
- *	@dev: struct device pointer to the PCI device of the I2O controller
- *	@addr: pointer to a i2o_dma struct DMA buffer
- *	@len: new length of memory
- *	@gfp_mask: GFP mask
- *
- *	If there was something allocated in the addr, free it first. If len > 0
- *	than try to allocate it and write the addresses back to the addr
- *	structure. If len == 0 set the virtual address to NULL.
- *
- *	Returns the 0 on success or negative error code on failure.
- */
-static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
-				  size_t len, gfp_t gfp_mask)
-{
-	i2o_dma_free(dev, addr);
-
-	if (len)
-		return i2o_dma_alloc(dev, addr, len, gfp_mask);
-
-	return 0;
-};
-
-/* I2O driver (OSM) functions */
-extern int i2o_driver_register(struct i2o_driver *);
-extern void i2o_driver_unregister(struct i2o_driver *);
-
-/**
- *	i2o_driver_notify_controller_add - Send notification of added controller
- *					   to a single I2O driver
- *
- *	Send notification of added controller to a single registered driver.
- */
-static inline void i2o_driver_notify_controller_add(struct i2o_driver *drv,
-						    struct i2o_controller *c)
-{
-	if (drv->notify_controller_add)
-		drv->notify_controller_add(c);
-};
-
-/**
- *	i2o_driver_notify_controller_remove - Send notification of removed
- *					      controller to a single I2O driver
- *
- *	Send notification of removed controller to a single registered driver.
- */
-static inline void i2o_driver_notify_controller_remove(struct i2o_driver *drv,
-						       struct i2o_controller *c)
-{
-	if (drv->notify_controller_remove)
-		drv->notify_controller_remove(c);
-};
-
-/**
- *	i2o_driver_notify_device_add - Send notification of added device to a
- *				       single I2O driver
- *
- *	Send notification of added device to a single registered driver.
- */
-static inline void i2o_driver_notify_device_add(struct i2o_driver *drv,
-						struct i2o_device *i2o_dev)
-{
-	if (drv->notify_device_add)
-		drv->notify_device_add(i2o_dev);
-};
-
-/**
- *	i2o_driver_notify_device_remove - Send notification of removed device
- *					  to a single I2O driver
- *
- *	Send notification of removed device to a single registered driver.
- */
-static inline void i2o_driver_notify_device_remove(struct i2o_driver *drv,
-						   struct i2o_device *i2o_dev)
-{
-	if (drv->notify_device_remove)
-		drv->notify_device_remove(i2o_dev);
-};
-
-extern void i2o_driver_notify_controller_add_all(struct i2o_controller *);
-extern void i2o_driver_notify_controller_remove_all(struct i2o_controller *);
-extern void i2o_driver_notify_device_add_all(struct i2o_device *);
-extern void i2o_driver_notify_device_remove_all(struct i2o_device *);
-
-/* I2O device functions */
-extern int i2o_device_claim(struct i2o_device *);
-extern int i2o_device_claim_release(struct i2o_device *);
-
-/* Exec OSM functions */
-extern int i2o_exec_lct_get(struct i2o_controller *);
-
-/* device / driver / kobject conversion functions */
-#define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver)
-#define to_i2o_device(dev) container_of(dev, struct i2o_device, device)
-#define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)
-#define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj))
-
-/**
- *	i2o_msg_get - obtain an I2O message from the IOP
- *	@c: I2O controller
- *	@msg: pointer to a I2O message pointer
- *
- *	This function tries to get a message slot. If no message slot is
- *	available do not wait until one is availabe (see also i2o_msg_get_wait).
- *
- *	On a success the message is returned and the pointer to the message is
- *	set in msg. The returned message is the physical page frame offset
- *	address from the read port (see the i2o spec). If no message is
- *	available returns I2O_QUEUE_EMPTY and msg is leaved untouched.
- */
-static inline u32 i2o_msg_get(struct i2o_controller *c,
-			      struct i2o_message __iomem ** msg)
-{
-	u32 m = readl(c->in_port);
-
-	if (m != I2O_QUEUE_EMPTY)
-		*msg = c->in_queue.virt + m;
-
-	return m;
-};
-
-/**
- *	i2o_msg_post - Post I2O message to I2O controller
- *	@c: I2O controller to which the message should be send
- *	@m: the message identifier
- *
- *	Post the message to the I2O controller.
- */
-static inline void i2o_msg_post(struct i2o_controller *c, u32 m)
-{
-	writel(m, c->in_port);
-};
-
-/**
- * 	i2o_msg_post_wait - Post and wait a message and wait until return
- *	@c: controller
- *	@m: message to post
- *	@timeout: time in seconds to wait
- *
- * 	This API allows an OSM to post a message and then be told whether or
- *	not the system received a successful reply. If the message times out
- *	then the value '-ETIMEDOUT' is returned.
- *
- *	Returns 0 on success or negative error code on failure.
- */
-static inline int i2o_msg_post_wait(struct i2o_controller *c, u32 m,
-				    unsigned long timeout)
-{
-	return i2o_msg_post_wait_mem(c, m, timeout, NULL);
-};
-
-/**
- *	i2o_flush_reply - Flush reply from I2O controller
- *	@c: I2O controller
- *	@m: the message identifier
- *
- *	The I2O controller must be informed that the reply message is not needed
- *	anymore. If you forget to flush the reply, the message frame can't be
- *	used by the controller anymore and is therefore lost.
- */
-static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
-{
-	writel(m, c->out_port);
-};
-
-/**
- *	i2o_out_to_virt - Turn an I2O message to a virtual address
- *	@c: controller
- *	@m: message engine value
- *
- *	Turn a receive message from an I2O controller bus address into
- *	a Linux virtual address. The shared page frame is a linear block
- *	so we simply have to shift the offset. This function does not
- *	work for sender side messages as they are ioremap objects
- *	provided by the I2O controller.
- */
-static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller *c,
-						      u32 m)
-{
-	BUG_ON(m < c->out_queue.phys
-	       || m >= c->out_queue.phys + c->out_queue.len);
-
-	return c->out_queue.virt + (m - c->out_queue.phys);
-};
-
-/**
- *	i2o_msg_in_to_virt - Turn an I2O message to a virtual address
- *	@c: controller
- *	@m: message engine value
- *
- *	Turn a send message from an I2O controller bus address into
- *	a Linux virtual address. The shared page frame is a linear block
- *	so we simply have to shift the offset. This function does not
- *	work for receive side messages as they are kmalloc objects
- *	in a different pool.
- */
-static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct
-							     i2o_controller *c,
-							     u32 m)
-{
-	return c->in_queue.virt + m;
-};
-
-/*
- *	Endian handling wrapped into the macro - keeps the core code
- *	cleaner.
- */
-
-#define i2o_raw_writel(val, mem)	__raw_writel(cpu_to_le32(val), mem)
-
-extern int i2o_parm_field_get(struct i2o_device *, int, int, void *, int);
-extern int i2o_parm_table_get(struct i2o_device *, int, int, int, void *, int,
-			      void *, int);
-
-/* debugging and troubleshooting/diagnostic helpers. */
-#define osm_printk(level, format, arg...)  \
-	printk(level "%s: " format, OSM_NAME , ## arg)
-
-#ifdef DEBUG
-#define osm_debug(format, arg...) \
-	osm_printk(KERN_DEBUG, format , ## arg)
-#else
-#define osm_debug(format, arg...) \
-        do { } while (0)
-#endif
-
-#define osm_err(format, arg...)		\
-	osm_printk(KERN_ERR, format , ## arg)
-#define osm_info(format, arg...)		\
-	osm_printk(KERN_INFO, format , ## arg)
-#define osm_warn(format, arg...)		\
-	osm_printk(KERN_WARNING, format , ## arg)
-
-/* debugging functions */
-extern void i2o_report_status(const char *, const char *, struct i2o_message *);
-extern void i2o_dump_message(struct i2o_message *);
-extern void i2o_dump_hrt(struct i2o_controller *c);
-extern void i2o_debug_state(struct i2o_controller *c);
-
-/*
  *	Cache strategies
  */
 
@@ -1100,6 +359,10 @@
 #define I2O_MAX_OUTBOUND_MSG_FRAMES	128
 #define I2O_OUTBOUND_MSG_FRAME_SIZE	128	/* in 32-bit words */
 
+/* inbound queue definitions */
+#define I2O_MSG_INPOOL_MIN		32
+#define I2O_INBOUND_MSG_FRAME_SIZE	128	/* in 32-bit words */
+
 #define I2O_POST_WAIT_OK	0
 #define I2O_POST_WAIT_TIMEOUT	-ETIMEDOUT
 
@@ -1121,8 +384,873 @@
 
 /* defines for max_sectors and max_phys_segments */
 #define I2O_MAX_SECTORS			1024
-#define I2O_MAX_SECTORS_LIMITED		256
+#define I2O_MAX_SECTORS_LIMITED		128
 #define I2O_MAX_PHYS_SEGMENTS		MAX_PHYS_SEGMENTS
 
+/*
+ *	Message structures
+ */
+struct i2o_message {
+	union {
+		struct {
+			u8 version_offset;
+			u8 flags;
+			u16 size;
+			u32 target_tid:12;
+			u32 init_tid:12;
+			u32 function:8;
+			u32 icntxt;	/* initiator context */
+			u32 tcntxt;	/* transaction context */
+		} s;
+		u32 head[4];
+	} u;
+	/* List follows */
+	u32 body[0];
+};
+
+/* MFA and I2O message used by mempool */
+struct i2o_msg_mfa {
+	u32 mfa;		/* MFA returned by the controller */
+	struct i2o_message msg;	/* I2O message */
+};
+
+/*
+ *	Each I2O device entity has one of these. There is one per device.
+ */
+struct i2o_device {
+	i2o_lct_entry lct_data;	/* Device LCT information */
+
+	struct i2o_controller *iop;	/* Controlling IOP */
+	struct list_head list;	/* node in IOP devices list */
+
+	struct device device;
+
+	struct semaphore lock;	/* device lock */
+};
+
+/*
+ *	Event structure provided to the event handling function
+ */
+struct i2o_event {
+	struct work_struct work;
+	struct i2o_device *i2o_dev;	/* I2O device pointer from which the
+					   event reply was initiated */
+	u16 size;		/* Size of data in 32-bit words */
+	u32 tcntxt;		/* Transaction context used at
+				   registration */
+	u32 event_indicator;	/* Event indicator from reply */
+	u32 data[0];		/* Event data from reply */
+};
+
+/*
+ *	I2O classes which could be handled by the OSM
+ */
+struct i2o_class_id {
+	u16 class_id:12;
+};
+
+/*
+ *	I2O driver structure for OSMs
+ */
+struct i2o_driver {
+	char *name;		/* OSM name */
+	int context;		/* Low 8 bits of the transaction info */
+	struct i2o_class_id *classes;	/* I2O classes that this OSM handles */
+
+	/* Message reply handler */
+	int (*reply) (struct i2o_controller *, u32, struct i2o_message *);
+
+	/* Event handler */
+	void (*event) (struct i2o_event *);
+
+	struct workqueue_struct *event_queue;	/* Event queue */
+
+	struct device_driver driver;
+
+	/* notification of changes */
+	void (*notify_controller_add) (struct i2o_controller *);
+	void (*notify_controller_remove) (struct i2o_controller *);
+	void (*notify_device_add) (struct i2o_device *);
+	void (*notify_device_remove) (struct i2o_device *);
+
+	struct semaphore lock;
+};
+
+/*
+ *	Contains DMA mapped address information
+ */
+struct i2o_dma {
+	void *virt;
+	dma_addr_t phys;
+	size_t len;
+};
+
+/*
+ *	Contains slab cache and mempool information
+ */
+struct i2o_pool {
+	char *name;
+	kmem_cache_t *slab;
+	mempool_t *mempool;
+};
+
+/*
+ *	Contains IO mapped address information
+ */
+struct i2o_io {
+	void __iomem *virt;
+	unsigned long phys;
+	unsigned long len;
+};
+
+/*
+ *	Context queue entry, used for 32-bit context on 64-bit systems
+ */
+struct i2o_context_list_element {
+	struct list_head list;
+	u32 context;
+	void *ptr;
+	unsigned long timestamp;
+};
+
+/*
+ * Each I2O controller has one of these objects
+ */
+struct i2o_controller {
+	char name[16];
+	int unit;
+	int type;
+
+	struct pci_dev *pdev;	/* PCI device */
+
+	unsigned int promise:1;	/* Promise controller */
+	unsigned int adaptec:1;	/* DPT / Adaptec controller */
+	unsigned int raptor:1;	/* split bar */
+	unsigned int no_quiesce:1;	/* dont quiesce before reset */
+	unsigned int short_req:1;	/* use small block sizes */
+	unsigned int limit_sectors:1;	/* limit number of sectors / request */
+	unsigned int pae_support:1;	/* controller has 64-bit SGL support */
+
+	struct list_head devices;	/* list of I2O devices */
+	struct list_head list;	/* Controller list */
+
+	void __iomem *in_port;	/* Inbout port address */
+	void __iomem *out_port;	/* Outbound port address */
+	void __iomem *irq_status;	/* Interrupt status register address */
+	void __iomem *irq_mask;	/* Interrupt mask register address */
+
+	struct i2o_dma status;	/* IOP status block */
+
+	struct i2o_dma hrt;	/* HW Resource Table */
+	i2o_lct *lct;		/* Logical Config Table */
+	struct i2o_dma dlct;	/* Temp LCT */
+	struct semaphore lct_lock;	/* Lock for LCT updates */
+	struct i2o_dma status_block;	/* IOP status block */
+
+	struct i2o_io base;	/* controller messaging unit */
+	struct i2o_io in_queue;	/* inbound message queue Host->IOP */
+	struct i2o_dma out_queue;	/* outbound message queue IOP->Host */
+
+	struct i2o_pool in_msg;	/* mempool for inbound messages */
+
+	unsigned int battery:1;	/* Has a battery backup */
+	unsigned int io_alloc:1;	/* An I/O resource was allocated */
+	unsigned int mem_alloc:1;	/* A memory resource was allocated */
+
+	struct resource io_resource;	/* I/O resource allocated to the IOP */
+	struct resource mem_resource;	/* Mem resource allocated to the IOP */
+
+	struct device device;
+	struct i2o_device *exec;	/* Executive */
+#if BITS_PER_LONG == 64
+	spinlock_t context_list_lock;	/* lock for context_list */
+	atomic_t context_list_counter;	/* needed for unique contexts */
+	struct list_head context_list;	/* list of context id's
+					   and pointers */
+#endif
+	spinlock_t lock;	/* lock for controller
+				   configuration */
+
+	void *driver_data[I2O_MAX_DRIVERS];	/* storage for drivers */
+};
+
+/*
+ * I2O System table entry
+ *
+ * The system table contains information about all the IOPs in the
+ * system.  It is sent to all IOPs so that they can create peer2peer
+ * connections between them.
+ */
+struct i2o_sys_tbl_entry {
+	u16 org_id;
+	u16 reserved1;
+	u32 iop_id:12;
+	u32 reserved2:20;
+	u16 seg_num:12;
+	u16 i2o_version:4;
+	u8 iop_state;
+	u8 msg_type;
+	u16 frame_size;
+	u16 reserved3;
+	u32 last_changed;
+	u32 iop_capabilities;
+	u32 inbound_low;
+	u32 inbound_high;
+};
+
+struct i2o_sys_tbl {
+	u8 num_entries;
+	u8 version;
+	u16 reserved1;
+	u32 change_ind;
+	u32 reserved2;
+	u32 reserved3;
+	struct i2o_sys_tbl_entry iops[0];
+};
+
+extern struct list_head i2o_controllers;
+
+/* Message functions */
+static inline struct i2o_message *i2o_msg_get(struct i2o_controller *);
+extern struct i2o_message *i2o_msg_get_wait(struct i2o_controller *, int);
+static inline void i2o_msg_post(struct i2o_controller *, struct i2o_message *);
+static inline int i2o_msg_post_wait(struct i2o_controller *,
+				    struct i2o_message *, unsigned long);
+extern int i2o_msg_post_wait_mem(struct i2o_controller *, struct i2o_message *,
+				 unsigned long, struct i2o_dma *);
+static inline void i2o_flush_reply(struct i2o_controller *, u32);
+
+/* IOP functions */
+extern int i2o_status_get(struct i2o_controller *);
+
+extern int i2o_event_register(struct i2o_device *, struct i2o_driver *, int,
+			      u32);
+extern struct i2o_device *i2o_iop_find_device(struct i2o_controller *, u16);
+extern struct i2o_controller *i2o_find_iop(int);
+
+/* Functions needed for handling 64-bit pointers in 32-bit context */
+#if BITS_PER_LONG == 64
+extern u32 i2o_cntxt_list_add(struct i2o_controller *, void *);
+extern void *i2o_cntxt_list_get(struct i2o_controller *, u32);
+extern u32 i2o_cntxt_list_remove(struct i2o_controller *, void *);
+extern u32 i2o_cntxt_list_get_ptr(struct i2o_controller *, void *);
+
+static inline u32 i2o_ptr_low(void *ptr)
+{
+	return (u32) (u64) ptr;
+};
+
+static inline u32 i2o_ptr_high(void *ptr)
+{
+	return (u32) ((u64) ptr >> 32);
+};
+
+static inline u32 i2o_dma_low(dma_addr_t dma_addr)
+{
+	return (u32) (u64) dma_addr;
+};
+
+static inline u32 i2o_dma_high(dma_addr_t dma_addr)
+{
+	return (u32) ((u64) dma_addr >> 32);
+};
+#else
+static inline u32 i2o_cntxt_list_add(struct i2o_controller *c, void *ptr)
+{
+	return (u32) ptr;
+};
+
+static inline void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context)
+{
+	return (void *)context;
+};
+
+static inline u32 i2o_cntxt_list_remove(struct i2o_controller *c, void *ptr)
+{
+	return (u32) ptr;
+};
+
+static inline u32 i2o_cntxt_list_get_ptr(struct i2o_controller *c, void *ptr)
+{
+	return (u32) ptr;
+};
+
+static inline u32 i2o_ptr_low(void *ptr)
+{
+	return (u32) ptr;
+};
+
+static inline u32 i2o_ptr_high(void *ptr)
+{
+	return 0;
+};
+
+static inline u32 i2o_dma_low(dma_addr_t dma_addr)
+{
+	return (u32) dma_addr;
+};
+
+static inline u32 i2o_dma_high(dma_addr_t dma_addr)
+{
+	return 0;
+};
+#endif
+
+/**
+ *	i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
+ *	@c: I2O controller for which the calculation should be done
+ *	@body_size: maximum body size used for message in 32-bit words.
+ *
+ *	Return the maximum number of SG elements in a SG list.
+ */
+static inline u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
+{
+	i2o_status_block *sb = c->status_block.virt;
+	u16 sg_count =
+	    (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
+	    body_size;
+
+	if (c->pae_support) {
+		/*
+		 * for 64-bit a SG attribute element must be added and each
+		 * SG element needs 12 bytes instead of 8.
+		 */
+		sg_count -= 2;
+		sg_count /= 3;
+	} else
+		sg_count /= 2;
+
+	if (c->short_req && (sg_count > 8))
+		sg_count = 8;
+
+	return sg_count;
+};
+
+/**
+ *	i2o_dma_map_single - Map pointer to controller and fill in I2O message.
+ *	@c: I2O controller
+ *	@ptr: pointer to the data which should be mapped
+ *	@size: size of data in bytes
+ *	@direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
+ *	@sg_ptr: pointer to the SG list inside the I2O message
+ *
+ *	This function does all necessary DMA handling and also writes the I2O
+ *	SGL elements into the I2O message. For details on DMA handling see also
+ *	dma_map_single(). The pointer sg_ptr will only be set to the end of the
+ *	SG list if the allocation was successful.
+ *
+ *	Returns DMA address which must be checked for failures using
+ *	dma_mapping_error().
+ */
+static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
+					    size_t size,
+					    enum dma_data_direction direction,
+					    u32 ** sg_ptr)
+{
+	u32 sg_flags;
+	u32 *mptr = *sg_ptr;
+	dma_addr_t dma_addr;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		sg_flags = 0xd4000000;
+		break;
+	case DMA_FROM_DEVICE:
+		sg_flags = 0xd0000000;
+		break;
+	default:
+		return 0;
+	}
+
+	dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
+	if (!dma_mapping_error(dma_addr)) {
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+		if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
+			*mptr++ = cpu_to_le32(0x7C020002);
+			*mptr++ = cpu_to_le32(PAGE_SIZE);
+		}
+#endif
+
+		*mptr++ = cpu_to_le32(sg_flags | size);
+		*mptr++ = cpu_to_le32(i2o_dma_low(dma_addr));
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+		if ((sizeof(dma_addr_t) > 4) && c->pae_support)
+			*mptr++ = cpu_to_le32(i2o_dma_high(dma_addr));
+#endif
+		*sg_ptr = mptr;
+	}
+	return dma_addr;
+};
+
+/**
+ *	i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
+ *	@c: I2O controller
+ *	@sg: SG list to be mapped
+ *	@sg_count: number of elements in the SG list
+ *	@direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
+ *	@sg_ptr: pointer to the SG list inside the I2O message
+ *
+ *	This function does all necessary DMA handling and also writes the I2O
+ *	SGL elements into the I2O message. For details on DMA handling see also
+ *	dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
+ *	list if the allocation was successful.
+ *
+ *	Returns 0 on failure or 1 on success.
+ */
+static inline int i2o_dma_map_sg(struct i2o_controller *c,
+				 struct scatterlist *sg, int sg_count,
+				 enum dma_data_direction direction,
+				 u32 ** sg_ptr)
+{
+	u32 sg_flags;
+	u32 *mptr = *sg_ptr;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		sg_flags = 0x14000000;
+		break;
+	case DMA_FROM_DEVICE:
+		sg_flags = 0x10000000;
+		break;
+	default:
+		return 0;
+	}
+
+	sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
+	if (!sg_count)
+		return 0;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+	if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
+		*mptr++ = cpu_to_le32(0x7C020002);
+		*mptr++ = cpu_to_le32(PAGE_SIZE);
+	}
+#endif
+
+	while (sg_count-- > 0) {
+		if (!sg_count)
+			sg_flags |= 0xC0000000;
+		*mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg));
+		*mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg)));
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+		if ((sizeof(dma_addr_t) > 4) && c->pae_support)
+			*mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg)));
+#endif
+		sg++;
+	}
+	*sg_ptr = mptr;
+
+	return 1;
+};
+
+/**
+ *	i2o_dma_alloc - Allocate DMA memory
+ *	@dev: struct device pointer to the PCI device of the I2O controller
+ *	@addr: i2o_dma struct which should get the DMA buffer
+ *	@len: length of the new DMA memory
+ *	@gfp_mask: GFP mask
+ *
+ *	Allocate a coherent DMA memory and write the pointers into addr.
+ *
+ *	Returns 0 on success or -ENOMEM on failure.
+ */
+static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
+				size_t len, gfp_t gfp_mask)
+{
+	struct pci_dev *pdev = to_pci_dev(dev);
+	int dma_64 = 0;
+
+	if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
+		dma_64 = 1;
+		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK))
+			return -ENOMEM;
+	}
+
+	addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
+
+	if ((sizeof(dma_addr_t) > 4) && dma_64)
+		if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+			printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
+
+	if (!addr->virt)
+		return -ENOMEM;
+
+	memset(addr->virt, 0, len);
+	addr->len = len;
+
+	return 0;
+};
+
+/**
+ *	i2o_dma_free - Free DMA memory
+ *	@dev: struct device pointer to the PCI device of the I2O controller
+ *	@addr: i2o_dma struct which contains the DMA buffer
+ *
+ *	Free a coherent DMA memory and set virtual address of addr to NULL.
+ */
+static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
+{
+	if (addr->virt) {
+		if (addr->phys)
+			dma_free_coherent(dev, addr->len, addr->virt,
+					  addr->phys);
+		else
+			kfree(addr->virt);
+		addr->virt = NULL;
+	}
+};
+
+/**
+ *	i2o_dma_realloc - Realloc DMA memory
+ *	@dev: struct device pointer to the PCI device of the I2O controller
+ *	@addr: pointer to a i2o_dma struct DMA buffer
+ *	@len: new length of memory
+ *	@gfp_mask: GFP mask
+ *
+ *	If there was something allocated in the addr, free it first. If len > 0
+ *	than try to allocate it and write the addresses back to the addr
+ *	structure. If len == 0 set the virtual address to NULL.
+ *
+ *	Returns the 0 on success or negative error code on failure.
+ */
+static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
+				  size_t len, gfp_t gfp_mask)
+{
+	i2o_dma_free(dev, addr);
+
+	if (len)
+		return i2o_dma_alloc(dev, addr, len, gfp_mask);
+
+	return 0;
+};
+
+/*
+ *	i2o_pool_alloc - Allocate an slab cache and mempool
+ *	@mempool: pointer to struct i2o_pool to write data into.
+ *	@name: name which is used to identify cache
+ *	@size: size of each object
+ *	@min_nr: minimum number of objects
+ *
+ *	First allocates a slab cache with name and size. Then allocates a
+ *	mempool which uses the slab cache for allocation and freeing.
+ *
+ *	Returns 0 on success or negative error code on failure.
+ */
+static inline int i2o_pool_alloc(struct i2o_pool *pool, const char *name,
+				 size_t size, int min_nr)
+{
+	pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
+	if (!pool->name)
+		goto exit;
+	strcpy(pool->name, name);
+
+	pool->slab =
+	    kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL,
+			      NULL);
+	if (!pool->slab)
+		goto free_name;
+
+	pool->mempool =
+	    mempool_create(min_nr, mempool_alloc_slab, mempool_free_slab,
+			   pool->slab);
+	if (!pool->mempool)
+		goto free_slab;
+
+	return 0;
+
+      free_slab:
+	kmem_cache_destroy(pool->slab);
+
+      free_name:
+	kfree(pool->name);
+
+      exit:
+	return -ENOMEM;
+};
+
+/*
+ *	i2o_pool_free - Free slab cache and mempool again
+ *	@mempool: pointer to struct i2o_pool which should be freed
+ *
+ *	Note that you have to return all objects to the mempool again before
+ *	calling i2o_pool_free().
+ */
+static inline void i2o_pool_free(struct i2o_pool *pool)
+{
+	mempool_destroy(pool->mempool);
+	kmem_cache_destroy(pool->slab);
+	kfree(pool->name);
+};
+
+/* I2O driver (OSM) functions */
+extern int i2o_driver_register(struct i2o_driver *);
+extern void i2o_driver_unregister(struct i2o_driver *);
+
+/**
+ *	i2o_driver_notify_controller_add - Send notification of added controller
+ *					   to a single I2O driver
+ *
+ *	Send notification of added controller to a single registered driver.
+ */
+static inline void i2o_driver_notify_controller_add(struct i2o_driver *drv,
+						    struct i2o_controller *c)
+{
+	if (drv->notify_controller_add)
+		drv->notify_controller_add(c);
+};
+
+/**
+ *	i2o_driver_notify_controller_remove - Send notification of removed
+ *					      controller to a single I2O driver
+ *
+ *	Send notification of removed controller to a single registered driver.
+ */
+static inline void i2o_driver_notify_controller_remove(struct i2o_driver *drv,
+						       struct i2o_controller *c)
+{
+	if (drv->notify_controller_remove)
+		drv->notify_controller_remove(c);
+};
+
+/**
+ *	i2o_driver_notify_device_add - Send notification of added device to a
+ *				       single I2O driver
+ *
+ *	Send notification of added device to a single registered driver.
+ */
+static inline void i2o_driver_notify_device_add(struct i2o_driver *drv,
+						struct i2o_device *i2o_dev)
+{
+	if (drv->notify_device_add)
+		drv->notify_device_add(i2o_dev);
+};
+
+/**
+ *	i2o_driver_notify_device_remove - Send notification of removed device
+ *					  to a single I2O driver
+ *
+ *	Send notification of removed device to a single registered driver.
+ */
+static inline void i2o_driver_notify_device_remove(struct i2o_driver *drv,
+						   struct i2o_device *i2o_dev)
+{
+	if (drv->notify_device_remove)
+		drv->notify_device_remove(i2o_dev);
+};
+
+extern void i2o_driver_notify_controller_add_all(struct i2o_controller *);
+extern void i2o_driver_notify_controller_remove_all(struct i2o_controller *);
+extern void i2o_driver_notify_device_add_all(struct i2o_device *);
+extern void i2o_driver_notify_device_remove_all(struct i2o_device *);
+
+/* I2O device functions */
+extern int i2o_device_claim(struct i2o_device *);
+extern int i2o_device_claim_release(struct i2o_device *);
+
+/* Exec OSM functions */
+extern int i2o_exec_lct_get(struct i2o_controller *);
+
+/* device / driver / kobject conversion functions */
+#define to_i2o_driver(drv) container_of(drv,struct i2o_driver, driver)
+#define to_i2o_device(dev) container_of(dev, struct i2o_device, device)
+#define to_i2o_controller(dev) container_of(dev, struct i2o_controller, device)
+#define kobj_to_i2o_device(kobj) to_i2o_device(container_of(kobj, struct device, kobj))
+
+/**
+ *	i2o_out_to_virt - Turn an I2O message to a virtual address
+ *	@c: controller
+ *	@m: message engine value
+ *
+ *	Turn a receive message from an I2O controller bus address into
+ *	a Linux virtual address. The shared page frame is a linear block
+ *	so we simply have to shift the offset. This function does not
+ *	work for sender side messages as they are ioremap objects
+ *	provided by the I2O controller.
+ */
+static inline struct i2o_message *i2o_msg_out_to_virt(struct i2o_controller *c,
+						      u32 m)
+{
+	BUG_ON(m < c->out_queue.phys
+	       || m >= c->out_queue.phys + c->out_queue.len);
+
+	return c->out_queue.virt + (m - c->out_queue.phys);
+};
+
+/**
+ *	i2o_msg_in_to_virt - Turn an I2O message to a virtual address
+ *	@c: controller
+ *	@m: message engine value
+ *
+ *	Turn a send message from an I2O controller bus address into
+ *	a Linux virtual address. The shared page frame is a linear block
+ *	so we simply have to shift the offset. This function does not
+ *	work for receive side messages as they are kmalloc objects
+ *	in a different pool.
+ */
+static inline struct i2o_message __iomem *i2o_msg_in_to_virt(struct
+							     i2o_controller *c,
+							     u32 m)
+{
+	return c->in_queue.virt + m;
+};
+
+/**
+ *	i2o_msg_get - obtain an I2O message from the IOP
+ *	@c: I2O controller
+ *
+ *	This function tries to get a message frame. If no message frame is
+ *	available do not wait until one is availabe (see also i2o_msg_get_wait).
+ *	The returned pointer to the message frame is not in I/O memory, it is
+ *	allocated from a mempool. But because a MFA is allocated from the
+ *	controller too it is guaranteed that i2o_msg_post() will never fail.
+ *
+ *	On a success a pointer to the message frame is returned. If the message
+ *	queue is empty -EBUSY is returned and if no memory is available -ENOMEM
+ *	is returned.
+ */
+static inline struct i2o_message *i2o_msg_get(struct i2o_controller *c)
+{
+	struct i2o_msg_mfa *mmsg = mempool_alloc(c->in_msg.mempool, GFP_ATOMIC);
+	if (!mmsg)
+		return ERR_PTR(-ENOMEM);
+
+	mmsg->mfa = readl(c->in_port);
+	if (mmsg->mfa == I2O_QUEUE_EMPTY) {
+		mempool_free(mmsg, c->in_msg.mempool);
+		return ERR_PTR(-EBUSY);
+	}
+
+	return &mmsg->msg;
+};
+
+/**
+ *	i2o_msg_post - Post I2O message to I2O controller
+ *	@c: I2O controller to which the message should be send
+ *	@msg: message returned by i2o_msg_get()
+ *
+ *	Post the message to the I2O controller and return immediately.
+ */
+static inline void i2o_msg_post(struct i2o_controller *c,
+				struct i2o_message *msg)
+{
+	struct i2o_msg_mfa *mmsg;
+
+	mmsg = container_of(msg, struct i2o_msg_mfa, msg);
+	memcpy_toio(i2o_msg_in_to_virt(c, mmsg->mfa), msg,
+		    (le32_to_cpu(msg->u.head[0]) >> 16) << 2);
+	writel(mmsg->mfa, c->in_port);
+	mempool_free(mmsg, c->in_msg.mempool);
+};
+
+/**
+ * 	i2o_msg_post_wait - Post and wait a message and wait until return
+ *	@c: controller
+ *	@m: message to post
+ *	@timeout: time in seconds to wait
+ *
+ * 	This API allows an OSM to post a message and then be told whether or
+ *	not the system received a successful reply. If the message times out
+ *	then the value '-ETIMEDOUT' is returned.
+ *
+ *	Returns 0 on success or negative error code on failure.
+ */
+static inline int i2o_msg_post_wait(struct i2o_controller *c,
+				    struct i2o_message *msg,
+				    unsigned long timeout)
+{
+	return i2o_msg_post_wait_mem(c, msg, timeout, NULL);
+};
+
+/**
+ *	i2o_msg_nop_mfa - Returns a fetched MFA back to the controller
+ *	@c: I2O controller from which the MFA was fetched
+ *	@mfa: MFA which should be returned
+ *
+ *	This function must be used for preserved messages, because i2o_msg_nop()
+ *	also returns the allocated memory back to the msg_pool mempool.
+ */
+static inline void i2o_msg_nop_mfa(struct i2o_controller *c, u32 mfa)
+{
+	struct i2o_message __iomem *msg;
+	u32 nop[3] = {
+		THREE_WORD_MSG_SIZE | SGL_OFFSET_0,
+		I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | ADAPTER_TID,
+		0x00000000
+	};
+
+	msg = i2o_msg_in_to_virt(c, mfa);
+	memcpy_toio(msg, nop, sizeof(nop));
+	writel(mfa, c->in_port);
+};
+
+/**
+ *	i2o_msg_nop - Returns a message which is not used
+ *	@c: I2O controller from which the message was created
+ *	@msg: message which should be returned
+ *
+ *	If you fetch a message via i2o_msg_get, and can't use it, you must
+ *	return the message with this function. Otherwise the MFA is lost as well
+ *	as the allocated memory from the mempool.
+ */
+static inline void i2o_msg_nop(struct i2o_controller *c,
+			       struct i2o_message *msg)
+{
+	struct i2o_msg_mfa *mmsg;
+	mmsg = container_of(msg, struct i2o_msg_mfa, msg);
+
+	i2o_msg_nop_mfa(c, mmsg->mfa);
+	mempool_free(mmsg, c->in_msg.mempool);
+};
+
+/**
+ *	i2o_flush_reply - Flush reply from I2O controller
+ *	@c: I2O controller
+ *	@m: the message identifier
+ *
+ *	The I2O controller must be informed that the reply message is not needed
+ *	anymore. If you forget to flush the reply, the message frame can't be
+ *	used by the controller anymore and is therefore lost.
+ */
+static inline void i2o_flush_reply(struct i2o_controller *c, u32 m)
+{
+	writel(m, c->out_port);
+};
+
+/*
+ *	Endian handling wrapped into the macro - keeps the core code
+ *	cleaner.
+ */
+
+#define i2o_raw_writel(val, mem)	__raw_writel(cpu_to_le32(val), mem)
+
+extern int i2o_parm_field_get(struct i2o_device *, int, int, void *, int);
+extern int i2o_parm_table_get(struct i2o_device *, int, int, int, void *, int,
+			      void *, int);
+
+/* debugging and troubleshooting/diagnostic helpers. */
+#define osm_printk(level, format, arg...)  \
+	printk(level "%s: " format, OSM_NAME , ## arg)
+
+#ifdef DEBUG
+#define osm_debug(format, arg...) \
+	osm_printk(KERN_DEBUG, format , ## arg)
+#else
+#define osm_debug(format, arg...) \
+        do { } while (0)
+#endif
+
+#define osm_err(format, arg...)		\
+	osm_printk(KERN_ERR, format , ## arg)
+#define osm_info(format, arg...)		\
+	osm_printk(KERN_INFO, format , ## arg)
+#define osm_warn(format, arg...)		\
+	osm_printk(KERN_WARNING, format , ## arg)
+
+/* debugging functions */
+extern void i2o_report_status(const char *, const char *, struct i2o_message *);
+extern void i2o_dump_message(struct i2o_message *);
+extern void i2o_dump_hrt(struct i2o_controller *c);
+extern void i2o_debug_state(struct i2o_controller *c);
+
 #endif				/* __KERNEL__ */
 #endif				/* _I2O_H */
diff --git a/include/linux/ide.h b/include/linux/ide.h
index a39c3c5..4dd6694 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -23,17 +23,6 @@
 #include <asm/io.h>
 #include <asm/semaphore.h>
 
-/*
- * This is the multiple IDE interface driver, as evolved from hd.c.
- * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15).
- * There can be up to two drives per interface, as per the ATA-2 spec.
- *
- * Primary i/f:    ide0: major=3;  (hda)         minor=0; (hdb)         minor=64
- * Secondary i/f:  ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64
- * Tertiary i/f:   ide2: major=33; (hde)         minor=0; (hdf)         minor=64
- * Quaternary i/f: ide3: major=34; (hdg)         minor=0; (hdh)         minor=64
- */
-
 /******************************************************************************
  * IDE driver configuration options (play with these as desired):
  *
@@ -193,11 +182,6 @@
 #define WAIT_CMD	(10*HZ)	/* 10sec  - maximum wait for an IRQ to happen */
 #define WAIT_MIN_SLEEP	(2*HZ/100)	/* 20msec - minimum sleep time */
 
-#define HOST(hwif,chipset)					\
-{								\
-	return ((hwif)->chipset == chipset) ? 1 : 0;		\
-}
-
 /*
  * Check for an interrupt and acknowledge the interrupt status
  */
@@ -391,45 +375,6 @@
 } ata_nsector_t, ata_data_t, atapi_bcount_t, ata_index_t;
 
 /*
- * ATA-IDE Error Register
- *
- * mark		: Bad address mark
- * tzero	: Couldn't find track 0
- * abrt		: Aborted Command
- * mcr		: Media Change Request
- * id		: ID field not found
- * mce		: Media Change Event
- * ecc		: Uncorrectable ECC error
- * bdd		: dual meaing
- */
-typedef union {
-	unsigned all			:8;
-	struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-		unsigned mark		:1;
-		unsigned tzero		:1;
-		unsigned abrt		:1;
-		unsigned mcr		:1;
-		unsigned id		:1;
-		unsigned mce		:1;
-		unsigned ecc		:1;
-		unsigned bdd		:1;
-#elif defined(__BIG_ENDIAN_BITFIELD)
-		unsigned bdd		:1;
-		unsigned ecc		:1;
-		unsigned mce		:1;
-		unsigned id		:1;
-		unsigned mcr		:1;
-		unsigned abrt		:1;
-		unsigned tzero		:1;
-		unsigned mark		:1;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-	} b;
-} ata_error_t;
-
-/*
  * ATA-IDE Select Register, aka Device-Head
  *
  * head		: always zeros here
@@ -504,39 +449,6 @@
 } ata_status_t, atapi_status_t;
 
 /*
- * ATA-IDE Control Register
- *
- * bit0		: Should be set to zero
- * nIEN		: device INTRQ to host
- * SRST		: host soft reset bit
- * bit3		: ATA-2 thingy, Should be set to 1
- * reserved456	: Reserved
- * HOB		: 48-bit address ordering, High Ordered Bit
- */
-typedef union {
-	unsigned all			: 8;
-	struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-		unsigned bit0		: 1;
-		unsigned nIEN		: 1;
-		unsigned SRST		: 1;
-		unsigned bit3		: 1;
-		unsigned reserved456	: 3;
-		unsigned HOB		: 1;
-#elif defined(__BIG_ENDIAN_BITFIELD)
-		unsigned HOB		: 1;
-		unsigned reserved456	: 3;
-		unsigned bit3		: 1;
-		unsigned SRST		: 1;
-		unsigned nIEN		: 1;
-		unsigned bit0		: 1;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-	} b;
-} ata_control_t;
-
-/*
  * ATAPI Feature Register
  *
  * dma		: Using DMA or PIO
@@ -618,39 +530,6 @@
 } atapi_error_t;
 
 /*
- * ATAPI floppy Drive Select Register
- *
- * sam_lun	: Logical unit number
- * reserved3	: Reserved
- * drv		: The responding drive will be drive 0 (0) or drive 1 (1)
- * one5		: Should be set to 1
- * reserved6	: Reserved
- * one7		: Should be set to 1
- */
-typedef union {
-	unsigned all			:8;
-	struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-		unsigned sam_lun	:3;
-		unsigned reserved3	:1;
-		unsigned drv		:1;
-		unsigned one5		:1;
-		unsigned reserved6	:1;
-		unsigned one7		:1;
-#elif defined(__BIG_ENDIAN_BITFIELD)
-		unsigned one7		:1;
-		unsigned reserved6	:1;
-		unsigned one5		:1;
-		unsigned drv		:1;
-		unsigned reserved3	:1;
-		unsigned sam_lun	:3;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
-	} b;
-} atapi_select_t;
-
-/*
  * Status returned from various ide_ functions
  */
 typedef enum {
@@ -922,7 +801,7 @@
 	unsigned dma;
 
 	void (*led_act)(void *data, int rw);
-} ____cacheline_maxaligned_in_smp ide_hwif_t;
+} ____cacheline_internodealigned_in_smp ide_hwif_t;
 
 /*
  *  internal ide interrupt handler type
@@ -1101,10 +980,7 @@
 	int		(*end_request)(ide_drive_t *, int, int);
 	ide_startstop_t	(*error)(ide_drive_t *, struct request *rq, u8, u8);
 	ide_startstop_t	(*abort)(ide_drive_t *, struct request *rq);
-	int		(*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
 	ide_proc_entry_t	*proc;
-	void		(*ata_prebuilder)(ide_drive_t *);
-	void		(*atapi_prebuilder)(ide_drive_t *);
 	struct device_driver	gen_driver;
 } ide_driver_t;
 
@@ -1298,7 +1174,6 @@
 extern void ide_timer_expiry(unsigned long);
 extern irqreturn_t ide_intr(int irq, void *dev_id, struct pt_regs *regs);
 extern void do_ide_request(request_queue_t *);
-extern void ide_init_subdrivers(void);
 
 void ide_init_disk(struct gendisk *, ide_drive_t *);
 
@@ -1371,6 +1246,12 @@
 #define GOOD_DMA_DRIVE		1
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
+struct drive_list_entry {
+	const char *id_model;
+	const char *id_firmware;
+};
+
+int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *);
 int __ide_dma_bad_drive(ide_drive_t *);
 int __ide_dma_good_drive(ide_drive_t *);
 int ide_use_dma(ide_drive_t *);
diff --git a/include/linux/if_frad.h b/include/linux/if_frad.h
index 511999c..395f0aa 100644
--- a/include/linux/if_frad.h
+++ b/include/linux/if_frad.h
@@ -131,17 +131,17 @@
 /* these are the fields of an RFC 1490 header */
 struct frhdr
 {
-   unsigned char  control	__attribute__((packed));
+   unsigned char  control;
 
    /* for IP packets, this can be the NLPID */
-   unsigned char  pad		__attribute__((packed)); 
+   unsigned char  pad;
 
-   unsigned char  NLPID		__attribute__((packed));
-   unsigned char  OUI[3]	__attribute__((packed));
-   unsigned short PID		__attribute__((packed));
+   unsigned char  NLPID;
+   unsigned char  OUI[3];
+   unsigned short PID;
 
 #define IP_NLPID pad 
-};
+} __attribute__((packed));
 
 /* see RFC 1490 for the definition of the following */
 #define FRAD_I_UI		0x03
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
index e677f73..4fab3d0 100644
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -157,8 +157,7 @@
 extern int register_pppox_proto(int proto_num, struct pppox_proto *pp);
 extern void unregister_pppox_proto(int proto_num);
 extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
-extern int pppox_channel_ioctl(struct ppp_channel *pc, unsigned int cmd,
-			       unsigned long arg);
+extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 
 /* PPPoX socket states */
 enum {
diff --git a/include/linux/inet.h b/include/linux/inet.h
index 3b5e9fd..6c5587a 100644
--- a/include/linux/inet.h
+++ b/include/linux/inet.h
@@ -45,6 +45,6 @@
 #ifdef __KERNEL__
 #include <linux/types.h>
 
-extern __u32 in_aton(const char *str);
+extern __be32 in_aton(const char *str);
 #endif
 #endif	/* _LINUX_INET_H */
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index ee5b239..267c88b 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -47,6 +47,8 @@
 #define IN_MOVE			(IN_MOVED_FROM | IN_MOVED_TO) /* moves */
 
 /* special flags */
+#define IN_ONLYDIR		0x01000000	/* only watch the path if it is a directory */
+#define IN_DONT_FOLLOW		0x02000000	/* don't follow a sym link */
 #define IN_MASK_ADD		0x20000000	/* add to the mask of an already existing watch */
 #define IN_ISDIR		0x40000000	/* event occurred against dir */
 #define IN_ONESHOT		0x80000000	/* only send event once */
diff --git a/include/linux/input.h b/include/linux/input.h
index 3c58233..6d4cc3c 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -13,6 +13,7 @@
 #include <linux/time.h>
 #include <linux/list.h>
 #include <linux/device.h>
+#include <linux/mod_devicetable.h>
 #else
 #include <sys/time.h>
 #include <sys/ioctl.h>
@@ -511,6 +512,8 @@
 #define KEY_FN_S		0x1e3
 #define KEY_FN_B		0x1e4
 
+/* We avoid low common keys in module aliases so they don't get huge. */
+#define KEY_MIN_INTERESTING	KEY_MUTE
 #define KEY_MAX			0x1ff
 
 /*
@@ -793,6 +796,44 @@
 
 #define FF_MAX		0x7f
 
+struct input_device_id {
+
+	kernel_ulong_t flags;
+
+	struct input_id id;
+
+	kernel_ulong_t evbit[EV_MAX/BITS_PER_LONG+1];
+	kernel_ulong_t keybit[KEY_MAX/BITS_PER_LONG+1];
+	kernel_ulong_t relbit[REL_MAX/BITS_PER_LONG+1];
+	kernel_ulong_t absbit[ABS_MAX/BITS_PER_LONG+1];
+	kernel_ulong_t mscbit[MSC_MAX/BITS_PER_LONG+1];
+	kernel_ulong_t ledbit[LED_MAX/BITS_PER_LONG+1];
+	kernel_ulong_t sndbit[SND_MAX/BITS_PER_LONG+1];
+	kernel_ulong_t ffbit[FF_MAX/BITS_PER_LONG+1];
+	kernel_ulong_t swbit[SW_MAX/BITS_PER_LONG+1];
+
+	kernel_ulong_t driver_info;
+};
+
+/*
+ * Structure for hotplug & device<->driver matching.
+ */
+
+#define INPUT_DEVICE_ID_MATCH_BUS	1
+#define INPUT_DEVICE_ID_MATCH_VENDOR	2
+#define INPUT_DEVICE_ID_MATCH_PRODUCT	4
+#define INPUT_DEVICE_ID_MATCH_VERSION	8
+
+#define INPUT_DEVICE_ID_MATCH_EVBIT	0x010
+#define INPUT_DEVICE_ID_MATCH_KEYBIT	0x020
+#define INPUT_DEVICE_ID_MATCH_RELBIT	0x040
+#define INPUT_DEVICE_ID_MATCH_ABSBIT	0x080
+#define INPUT_DEVICE_ID_MATCH_MSCIT	0x100
+#define INPUT_DEVICE_ID_MATCH_LEDBIT	0x200
+#define INPUT_DEVICE_ID_MATCH_SNDBIT	0x400
+#define INPUT_DEVICE_ID_MATCH_FFBIT	0x800
+#define INPUT_DEVICE_ID_MATCH_SWBIT	0x1000
+
 #ifdef __KERNEL__
 
 /*
@@ -901,49 +942,11 @@
 };
 #define to_input_dev(d) container_of(d, struct input_dev, cdev)
 
-/*
- * Structure for hotplug & device<->driver matching.
- */
-
-#define INPUT_DEVICE_ID_MATCH_BUS	1
-#define INPUT_DEVICE_ID_MATCH_VENDOR	2
-#define INPUT_DEVICE_ID_MATCH_PRODUCT	4
-#define INPUT_DEVICE_ID_MATCH_VERSION	8
-
-#define INPUT_DEVICE_ID_MATCH_EVBIT	0x010
-#define INPUT_DEVICE_ID_MATCH_KEYBIT	0x020
-#define INPUT_DEVICE_ID_MATCH_RELBIT	0x040
-#define INPUT_DEVICE_ID_MATCH_ABSBIT	0x080
-#define INPUT_DEVICE_ID_MATCH_MSCIT	0x100
-#define INPUT_DEVICE_ID_MATCH_LEDBIT	0x200
-#define INPUT_DEVICE_ID_MATCH_SNDBIT	0x400
-#define INPUT_DEVICE_ID_MATCH_FFBIT	0x800
-#define INPUT_DEVICE_ID_MATCH_SWBIT	0x1000
-
 #define INPUT_DEVICE_ID_MATCH_DEVICE\
 	(INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)
 #define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\
 	(INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION)
 
-struct input_device_id {
-
-	unsigned long flags;
-
-	struct input_id id;
-
-	unsigned long evbit[NBITS(EV_MAX)];
-	unsigned long keybit[NBITS(KEY_MAX)];
-	unsigned long relbit[NBITS(REL_MAX)];
-	unsigned long absbit[NBITS(ABS_MAX)];
-	unsigned long mscbit[NBITS(MSC_MAX)];
-	unsigned long ledbit[NBITS(LED_MAX)];
-	unsigned long sndbit[NBITS(SND_MAX)];
-	unsigned long ffbit[NBITS(FF_MAX)];
-	unsigned long swbit[NBITS(SW_MAX)];
-
-	unsigned long driver_info;
-};
-
 struct input_handle;
 
 struct input_handler {
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 41f150a..e50a95f 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -79,7 +79,7 @@
 {
 	local_save_flags(*x);
 }
-#define save_flags(x) save_flags(&x);
+#define save_flags(x) save_flags(&x)
 static inline void __deprecated restore_flags(unsigned long x)
 {
 	local_irq_restore(x);
diff --git a/include/linux/ip.h b/include/linux/ip.h
index 33e8a19..4b55cf1 100644
--- a/include/linux/ip.h
+++ b/include/linux/ip.h
@@ -16,6 +16,7 @@
  */
 #ifndef _LINUX_IP_H
 #define _LINUX_IP_H
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
 #define IPTOS_TOS_MASK		0x1E
@@ -78,126 +79,6 @@
 #define	IPOPT_TS_TSANDADDR	1		/* timestamps and addresses */
 #define	IPOPT_TS_PRESPEC	3		/* specified modules only */
 
-#ifdef __KERNEL__
-#include <linux/config.h>
-#include <linux/types.h>
-#include <net/request_sock.h>
-#include <net/sock.h>
-#include <linux/igmp.h>
-#include <net/flow.h>
-
-struct ip_options {
-  __u32		faddr;				/* Saved first hop address */
-  unsigned char	optlen;
-  unsigned char srr;
-  unsigned char rr;
-  unsigned char ts;
-  unsigned char is_setbyuser:1,			/* Set by setsockopt?			*/
-                is_data:1,			/* Options in __data, rather than skb	*/
-                is_strictroute:1,		/* Strict source route			*/
-                srr_is_hit:1,			/* Packet destination addr was our one	*/
-                is_changed:1,			/* IP checksum more not valid		*/	
-                rr_needaddr:1,			/* Need to record addr of outgoing dev	*/
-                ts_needtime:1,			/* Need to record timestamp		*/
-                ts_needaddr:1;			/* Need to record addr of outgoing dev  */
-  unsigned char router_alert;
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __data[0];
-};
-
-#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
-
-struct inet_request_sock {
-	struct request_sock	req;
-	u32			loc_addr;
-	u32			rmt_addr;
-	u16			rmt_port;
-	u16			snd_wscale : 4, 
-				rcv_wscale : 4, 
-				tstamp_ok  : 1,
-				sack_ok	   : 1,
-				wscale_ok  : 1,
-				ecn_ok	   : 1,
-				acked	   : 1;
-	struct ip_options	*opt;
-};
-
-static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
-{
-	return (struct inet_request_sock *)sk;
-}
-
-struct ipv6_pinfo;
-
-struct inet_sock {
-	/* sk and pinet6 has to be the first two members of inet_sock */
-	struct sock		sk;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	struct ipv6_pinfo	*pinet6;
-#endif
-	/* Socket demultiplex comparisons on incoming packets. */
-	__u32			daddr;		/* Foreign IPv4 addr */
-	__u32			rcv_saddr;	/* Bound local IPv4 addr */
-	__u16			dport;		/* Destination port */
-	__u16			num;		/* Local port */
-	__u32			saddr;		/* Sending source */
-	__s16			uc_ttl;		/* Unicast TTL */
-	__u16			cmsg_flags;
-	struct ip_options	*opt;
-	__u16			sport;		/* Source port */
-	__u16			id;		/* ID counter for DF pkts */
-	__u8			tos;		/* TOS */
-	__u8			mc_ttl;		/* Multicasting TTL */
-	__u8			pmtudisc;
-	unsigned		recverr : 1,
-				freebind : 1,
-				hdrincl : 1,
-				mc_loop : 1;
-	int			mc_index;	/* Multicast device index */
-	__u32			mc_addr;
-	struct ip_mc_socklist	*mc_list;	/* Group array */
-	/*
-	 * Following members are used to retain the infomation to build
-	 * an ip header on each ip fragmentation while the socket is corked.
-	 */
-	struct {
-		unsigned int		flags;
-		unsigned int		fragsize;
-		struct ip_options	*opt;
-		struct rtable		*rt;
-		int			length; /* Total length of all frames */
-		u32			addr;
-		struct flowi		fl;
-	} cork;
-};
-
-#define IPCORK_OPT	1	/* ip-options has been held in ipcork.opt */
-#define IPCORK_ALLFRAG	2	/* always fragment (for ipv6 for now) */
-
-static inline struct inet_sock *inet_sk(const struct sock *sk)
-{
-	return (struct inet_sock *)sk;
-}
-
-static inline void __inet_sk_copy_descendant(struct sock *sk_to,
-					     const struct sock *sk_from,
-					     const int ancestor_size)
-{
-	memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1,
-	       sk_from->sk_prot->obj_size - ancestor_size);
-}
-#if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE))
-static inline void inet_sk_copy_descendant(struct sock *sk_to,
-					   const struct sock *sk_from)
-{
-	__inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock));
-}
-#endif
-#endif
-
-extern int inet_sk_rebuild_header(struct sock *sk);
-
 struct iphdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
 	__u8	ihl:4,
@@ -209,14 +90,14 @@
 #error	"Please fix <asm/byteorder.h>"
 #endif
 	__u8	tos;
-	__u16	tot_len;
-	__u16	id;
-	__u16	frag_off;
+	__be16	tot_len;
+	__be16	id;
+	__be16	frag_off;
 	__u8	ttl;
 	__u8	protocol;
 	__u16	check;
-	__u32	saddr;
-	__u32	daddr;
+	__be32	saddr;
+	__be32	daddr;
 	/*The options start here. */
 };
 
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index e0b9227..9c8f4c9 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -171,12 +171,13 @@
 };
 
 #ifdef __KERNEL__
-#include <linux/in6.h>          /* struct sockaddr_in6 */
 #include <linux/icmpv6.h>
-#include <net/if_inet6.h>       /* struct ipv6_mc_socklist */
 #include <linux/tcp.h>
 #include <linux/udp.h>
 
+#include <net/if_inet6.h>       /* struct ipv6_mc_socklist */
+#include <net/inet_sock.h>
+
 /* 
    This structure contains results of exthdrs parsing
    as offsets from skb->nh.
@@ -190,6 +191,10 @@
 	__u16			srcrt;
 	__u16			dst1;
 	__u16			lastopt;
+	__u32			nhoff;
+	__u16			flags;
+
+#define IP6SKB_XFRM_TRANSFORMED	1
 };
 
 #define IP6CB(skb)	((struct inet6_skb_parm*)((skb)->cb))
@@ -199,18 +204,17 @@
 	return IP6CB(skb)->iif;
 }
 
-struct tcp6_request_sock {
-	struct tcp_request_sock	req;
+struct inet6_request_sock {
 	struct in6_addr		loc_addr;
 	struct in6_addr		rmt_addr;
 	struct sk_buff		*pktopts;
 	int			iif;
 };
 
-static inline struct tcp6_request_sock *tcp6_rsk(const struct request_sock *sk)
-{
-	return (struct tcp6_request_sock *)sk;
-}
+struct tcp6_request_sock {
+	struct tcp_request_sock	  tcp6rsk_tcp;
+	struct inet6_request_sock tcp6rsk_inet6;
+};
 
 /**
  * struct ipv6_pinfo - ipv6 private area
@@ -298,12 +302,36 @@
 	struct ipv6_pinfo inet6;
 };
 
+extern int inet6_sk_rebuild_header(struct sock *sk);
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
 {
 	return inet_sk(__sk)->pinet6;
 }
 
+static inline struct inet6_request_sock *
+			inet6_rsk(const struct request_sock *rsk)
+{
+	return (struct inet6_request_sock *)(((u8 *)rsk) +
+					     inet_rsk(rsk)->inet6_rsk_offset);
+}
+
+static inline u32 inet6_rsk_offset(struct request_sock *rsk)
+{
+	return rsk->rsk_ops->obj_size - sizeof(struct inet6_request_sock);
+}
+
+static inline struct request_sock *inet6_reqsk_alloc(struct request_sock_ops *ops)
+{
+	struct request_sock *req = reqsk_alloc(ops);
+
+	if (req != NULL)
+		inet_rsk(req)->inet6_rsk_offset = inet6_rsk_offset(req);
+
+	return req;
+}
+
 static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 {
 	return (struct raw6_sock *)sk;
@@ -323,28 +351,37 @@
 #define __ipv6_only_sock(sk)	(inet6_sk(sk)->ipv6only)
 #define ipv6_only_sock(sk)	((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk))
 
-#include <linux/tcp.h>
-
-struct tcp6_timewait_sock {
-	struct tcp_timewait_sock tw_v6_sk;
-	struct in6_addr		 tw_v6_daddr;
-	struct in6_addr		 tw_v6_rcv_saddr;
+struct inet6_timewait_sock {
+	struct in6_addr tw_v6_daddr;
+	struct in6_addr	tw_v6_rcv_saddr;
 };
 
-static inline struct tcp6_timewait_sock *tcp6_twsk(const struct sock *sk)
+struct tcp6_timewait_sock {
+	struct tcp_timewait_sock   tcp6tw_tcp;
+	struct inet6_timewait_sock tcp6tw_inet6;
+};
+
+static inline u16 inet6_tw_offset(const struct proto *prot)
 {
-	return (struct tcp6_timewait_sock *)sk;
+	return prot->twsk_prot->twsk_obj_size -
+			sizeof(struct inet6_timewait_sock);
 }
 
-static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct inet6_timewait_sock *inet6_twsk(const struct sock *sk)
+{
+	return (struct inet6_timewait_sock *)(((u8 *)sk) +
+					      inet_twsk(sk)->tw_ipv6_offset);
+}
+
+static inline struct in6_addr *__inet6_rcv_saddr(const struct sock *sk)
 {
 	return likely(sk->sk_state != TCP_TIME_WAIT) ?
-		&inet6_sk(sk)->rcv_saddr : &tcp6_twsk(sk)->tw_v6_rcv_saddr;
+		&inet6_sk(sk)->rcv_saddr : &inet6_twsk(sk)->tw_v6_rcv_saddr;
 }
 
-static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
+static inline struct in6_addr *inet6_rcv_saddr(const struct sock *sk)
 {
-	return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL;
+	return sk->sk_family == AF_INET6 ? __inet6_rcv_saddr(sk) : NULL;
 }
 
 static inline int inet_v6_ipv6only(const struct sock *sk)
@@ -361,13 +398,19 @@
 	return NULL;
 }
 
+static inline struct inet6_request_sock *
+			inet6_rsk(const struct request_sock *rsk)
+{
+	return NULL;
+}
+
 static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 {
 	return NULL;
 }
 
-#define __tcp_v6_rcv_saddr(__sk)	NULL
-#define tcp_v6_rcv_saddr(__sk)		NULL
+#define __inet6_rcv_saddr(__sk)	NULL
+#define inet6_rcv_saddr(__sk)	NULL
 #define tcp_twsk_ipv6only(__sk)		0
 #define inet_v6_ipv6only(__sk)		0
 #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
diff --git a/include/linux/ipv6_route.h b/include/linux/ipv6_route.h
index e2f9350..d7c41d1 100644
--- a/include/linux/ipv6_route.h
+++ b/include/linux/ipv6_route.h
@@ -18,6 +18,7 @@
 					   fallback, no routers on link */
 #define RTF_ADDRCONF	0x00040000	/* addrconf route - RA		*/
 #define RTF_PREFIX_RT	0x00080000	/* A prefix only route - RA	*/
+#define RTF_ANYCAST	0x00100000	/* Anycast			*/
 
 #define RTF_NONEXTHOP	0x00200000	/* route with no nexthop	*/
 #define RTF_EXPIRES	0x00400000
diff --git a/include/linux/irq.h b/include/linux/irq.h
index c516382..6c5d4c8 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -10,9 +10,9 @@
  */
 
 #include <linux/config.h>
-#include <asm/smp.h>		/* cpu_online_map */
+#include <linux/smp.h>
 
-#if !defined(CONFIG_ARCH_S390)
+#if !defined(CONFIG_S390)
 
 #include <linux/linkage.h>
 #include <linux/cache.h>
@@ -221,6 +221,17 @@
 extern int can_request_irq(unsigned int irq, unsigned long irqflags);
 
 extern void init_irq_proc(void);
+
+#ifdef CONFIG_AUTO_IRQ_AFFINITY
+extern int select_smp_affinity(unsigned int irq);
+#else
+static inline int
+select_smp_affinity(unsigned int irq)
+{
+	return 1;
+}
+#endif
+
 #endif
 
 extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
diff --git a/include/linux/isdnif.h b/include/linux/isdnif.h
index 7a4eacd..04e10f9 100644
--- a/include/linux/isdnif.h
+++ b/include/linux/isdnif.h
@@ -282,43 +282,43 @@
 
 typedef struct T30_s {
 	/* session parameters */
-	__u8 resolution		__attribute__ ((packed));
-	__u8 rate		__attribute__ ((packed));
-	__u8 width		__attribute__ ((packed));
-	__u8 length		__attribute__ ((packed));
-	__u8 compression	__attribute__ ((packed));
-	__u8 ecm		__attribute__ ((packed));
-	__u8 binary		__attribute__ ((packed));
-	__u8 scantime		__attribute__ ((packed));
-	__u8 id[FAXIDLEN]	__attribute__ ((packed));
+	__u8 resolution;
+	__u8 rate;
+	__u8 width;
+	__u8 length;
+	__u8 compression;
+	__u8 ecm;
+	__u8 binary;
+	__u8 scantime;
+	__u8 id[FAXIDLEN];
 	/* additional parameters */
-	__u8 phase		__attribute__ ((packed));
-	__u8 direction		__attribute__ ((packed));
-	__u8 code		__attribute__ ((packed));
-	__u8 badlin		__attribute__ ((packed));
-	__u8 badmul		__attribute__ ((packed));
-	__u8 bor		__attribute__ ((packed));
-	__u8 fet		__attribute__ ((packed));
-	__u8 pollid[FAXIDLEN]	__attribute__ ((packed));
-	__u8 cq			__attribute__ ((packed));
-	__u8 cr			__attribute__ ((packed));
-	__u8 ctcrty		__attribute__ ((packed));
-	__u8 minsp		__attribute__ ((packed));
-	__u8 phcto		__attribute__ ((packed));
-	__u8 rel		__attribute__ ((packed));
-	__u8 nbc		__attribute__ ((packed));
+	__u8 phase;
+	__u8 direction;
+	__u8 code;
+	__u8 badlin;
+	__u8 badmul;
+	__u8 bor;
+	__u8 fet;
+	__u8 pollid[FAXIDLEN];
+	__u8 cq;
+	__u8 cr;
+	__u8 ctcrty;
+	__u8 minsp;
+	__u8 phcto;
+	__u8 rel;
+	__u8 nbc;
 	/* remote station parameters */
-	__u8 r_resolution	__attribute__ ((packed));
-	__u8 r_rate		__attribute__ ((packed));
-	__u8 r_width		__attribute__ ((packed));
-	__u8 r_length		__attribute__ ((packed));
-	__u8 r_compression	__attribute__ ((packed));
-	__u8 r_ecm		__attribute__ ((packed));
-	__u8 r_binary		__attribute__ ((packed));
-	__u8 r_scantime		__attribute__ ((packed));
-	__u8 r_id[FAXIDLEN]	__attribute__ ((packed));
-	__u8 r_code		__attribute__ ((packed));
-} T30_s;
+	__u8 r_resolution;
+	__u8 r_rate;
+	__u8 r_width;
+	__u8 r_length;
+	__u8 r_compression;
+	__u8 r_ecm;
+	__u8 r_binary;
+	__u8 r_scantime;
+	__u8 r_id[FAXIDLEN];
+	__u8 r_code;
+} __attribute__((packed)) T30_s;
 
 #define ISDN_TTY_FAX_CONN_IN	0
 #define ISDN_TTY_FAX_CONN_OUT	1
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index dcde7adf..558cb4c 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -498,6 +498,12 @@
 	struct journal_head	*t_checkpoint_list;
 
 	/*
+	 * Doubly-linked circular list of all buffers submitted for IO while
+	 * checkpointing. [j_list_lock]
+	 */
+	struct journal_head	*t_checkpoint_io_list;
+
+	/*
 	 * Doubly-linked circular list of temporary buffers currently undergoing
 	 * IO in the log [j_list_lock]
 	 */
@@ -843,7 +849,7 @@
 
 /* Checkpoint list management */
 int __journal_clean_checkpoint_list(journal_t *journal);
-void __journal_remove_checkpoint(struct journal_head *);
+int __journal_remove_checkpoint(struct journal_head *);
 void __journal_insert_checkpoint(struct journal_head *, transaction_t *);
 
 /* Buffer IO */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index b1e407a..ca7ff8f 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -316,8 +316,6 @@
 #endif
 
 /* Trap pasters of __FUNCTION__ at compile-time */
-#if __GNUC__ > 2 || __GNUC_MINOR__ >= 95
 #define __FUNCTION__ (__func__)
-#endif
 
 #endif
diff --git a/include/linux/key.h b/include/linux/key.h
index 53513a3..cbf464a 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -177,6 +177,8 @@
 /*
  * kernel managed key type definition
  */
+typedef int (*request_key_actor_t)(struct key *key, struct key *authkey, const char *op);
+
 struct key_type {
 	/* name of the type */
 	const char *name;
@@ -193,14 +195,6 @@
 	 */
 	int (*instantiate)(struct key *key, const void *data, size_t datalen);
 
-	/* duplicate a key of this type (optional)
-	 * - the source key will be locked against change
-	 * - the new description will be attached
-	 * - the quota will have been adjusted automatically from
-	 *   source->quotalen
-	 */
-	int (*duplicate)(struct key *key, const struct key *source);
-
 	/* update a key of this type (optional)
 	 * - this method should call key_payload_reserve() to recalculate the
 	 *   quota consumption
@@ -226,6 +220,16 @@
 	 */
 	long (*read)(const struct key *key, char __user *buffer, size_t buflen);
 
+	/* handle request_key() for this type instead of invoking
+	 * /sbin/request-key (optional)
+	 * - key is the key to instantiate
+	 * - authkey is the authority to assume when instantiating this key
+	 * - op is the operation to be done, usually "create"
+	 * - the call must not return until the instantiation process has run
+	 *   its course
+	 */
+	request_key_actor_t request_key;
+
 	/* internal fields */
 	struct list_head	link;		/* link in types list */
 };
diff --git a/include/linux/keyctl.h b/include/linux/keyctl.h
index 8d7c59a..3365945 100644
--- a/include/linux/keyctl.h
+++ b/include/linux/keyctl.h
@@ -19,6 +19,7 @@
 #define KEY_SPEC_USER_KEYRING		-4	/* - key ID for UID-specific keyring */
 #define KEY_SPEC_USER_SESSION_KEYRING	-5	/* - key ID for UID-session keyring */
 #define KEY_SPEC_GROUP_KEYRING		-6	/* - key ID for GID-specific keyring */
+#define KEY_SPEC_REQKEY_AUTH_KEY	-7	/* - key ID for assumed request_key auth key */
 
 /* request-key default keyrings */
 #define KEY_REQKEY_DEFL_NO_CHANGE		-1
@@ -46,5 +47,7 @@
 #define KEYCTL_INSTANTIATE		12	/* instantiate a partially constructed key */
 #define KEYCTL_NEGATE			13	/* negate a partially constructed key */
 #define KEYCTL_SET_REQKEY_KEYRING	14	/* set default request-key keyring */
+#define KEYCTL_SET_TIMEOUT		15	/* set key timeout */
+#define KEYCTL_ASSUME_AUTHORITY		16	/* assume request_key() authorisation */
 
 #endif /*  _LINUX_KEYCTL_H */
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 7f7403a..2a8d8da 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -23,14 +23,27 @@
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
 #include <linux/kref.h>
-#include <linux/kobject_uevent.h>
 #include <linux/kernel.h>
 #include <asm/atomic.h>
 
-#define KOBJ_NAME_LEN	20
+#define KOBJ_NAME_LEN			20
+#define UEVENT_HELPER_PATH_LEN		256
 
-/* counter to tag the hotplug event, read only except for the kobject core */
-extern u64 hotplug_seqnum;
+/* path to the userspace helper executed on an event */
+extern char uevent_helper[];
+
+/* counter to tag the uevent, read only except for the kobject core */
+extern u64 uevent_seqnum;
+
+/* the actions here must match the proper string in lib/kobject_uevent.c */
+typedef int __bitwise kobject_action_t;
+enum kobject_action {
+	KOBJ_ADD	= (__force kobject_action_t) 0x01,	/* exclusive to core */
+	KOBJ_REMOVE	= (__force kobject_action_t) 0x02,	/* exclusive to core */
+	KOBJ_CHANGE	= (__force kobject_action_t) 0x03,	/* device state change */
+	KOBJ_OFFLINE	= (__force kobject_action_t) 0x04,	/* device offline */
+	KOBJ_ONLINE	= (__force kobject_action_t) 0x05,	/* device online */
+};
 
 struct kobject {
 	const char		* k_name;
@@ -87,15 +100,14 @@
  *	of object; multiple ksets can belong to one subsystem. All 
  *	ksets of a subsystem share the subsystem's lock.
  *
- *      Each kset can support hotplugging; if it does, it will be given
- *      the opportunity to filter out specific kobjects from being
- *      reported, as well as to add its own "data" elements to the
- *      environment being passed to the hotplug helper.
+ *	Each kset can support specific event variables; it can
+ *	supress the event generation or add subsystem specific
+ *	variables carried with the event.
  */
-struct kset_hotplug_ops {
+struct kset_uevent_ops {
 	int (*filter)(struct kset *kset, struct kobject *kobj);
 	const char *(*name)(struct kset *kset, struct kobject *kobj);
-	int (*hotplug)(struct kset *kset, struct kobject *kobj, char **envp,
+	int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp,
 			int num_envp, char *buffer, int buffer_size);
 };
 
@@ -105,7 +117,7 @@
 	struct list_head	list;
 	spinlock_t		list_lock;
 	struct kobject		kobj;
-	struct kset_hotplug_ops	* hotplug_ops;
+	struct kset_uevent_ops	* uevent_ops;
 };
 
 
@@ -153,20 +165,20 @@
 	struct rw_semaphore	rwsem;
 };
 
-#define decl_subsys(_name,_type,_hotplug_ops) \
+#define decl_subsys(_name,_type,_uevent_ops) \
 struct subsystem _name##_subsys = { \
 	.kset = { \
 		.kobj = { .name = __stringify(_name) }, \
 		.ktype = _type, \
-		.hotplug_ops =_hotplug_ops, \
+		.uevent_ops =_uevent_ops, \
 	} \
 }
-#define decl_subsys_name(_varname,_name,_type,_hotplug_ops) \
+#define decl_subsys_name(_varname,_name,_type,_uevent_ops) \
 struct subsystem _varname##_subsys = { \
 	.kset = { \
 		.kobj = { .name = __stringify(_name) }, \
 		.ktype = _type, \
-		.hotplug_ops =_hotplug_ops, \
+		.uevent_ops =_uevent_ops, \
 	} \
 }
 
@@ -241,15 +253,17 @@
 extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
 extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
 
-#ifdef CONFIG_HOTPLUG
-void kobject_hotplug(struct kobject *kobj, enum kobject_action action);
-int add_hotplug_env_var(char **envp, int num_envp, int *cur_index,
+#if defined(CONFIG_HOTPLUG) & defined(CONFIG_NET)
+void kobject_uevent(struct kobject *kobj, enum kobject_action action);
+
+int add_uevent_var(char **envp, int num_envp, int *cur_index,
 			char *buffer, int buffer_size, int *cur_len,
 			const char *format, ...)
 	__attribute__((format (printf, 7, 8)));
 #else
-static inline void kobject_hotplug(struct kobject *kobj, enum kobject_action action) { }
-static inline int add_hotplug_env_var(char **envp, int num_envp, int *cur_index, 
+static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { }
+
+static inline int add_uevent_var(char **envp, int num_envp, int *cur_index,
 				      char *buffer, int buffer_size, int *cur_len, 
 				      const char *format, ...)
 { return 0; }
diff --git a/include/linux/kobject_uevent.h b/include/linux/kobject_uevent.h
deleted file mode 100644
index aa664fe..0000000
--- a/include/linux/kobject_uevent.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * kobject_uevent.h - list of kobject user events that can be generated
- *
- * Copyright (C) 2004 IBM Corp.
- * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
- *
- * This file is released under the GPLv2.
- *
- */
-
-#ifndef _KOBJECT_EVENT_H_
-#define _KOBJECT_EVENT_H_
-
-#define HOTPLUG_PATH_LEN	256
-
-/* path to the hotplug userspace helper executed on an event */
-extern char hotplug_path[];
-
-/*
- * If you add an action here, you must also add the proper string to the
- * lib/kobject_uevent.c file.
- */
-typedef int __bitwise kobject_action_t;
-enum kobject_action {
-	KOBJ_ADD	= (__force kobject_action_t) 0x01,	/* add event, for hotplug */
-	KOBJ_REMOVE	= (__force kobject_action_t) 0x02,	/* remove event, for hotplug */
-	KOBJ_CHANGE	= (__force kobject_action_t) 0x03,	/* a sysfs attribute file has changed */
-	KOBJ_MOUNT	= (__force kobject_action_t) 0x04,	/* mount event for block devices */
-	KOBJ_UMOUNT	= (__force kobject_action_t) 0x05,	/* umount event for block devices */
-	KOBJ_OFFLINE	= (__force kobject_action_t) 0x06,	/* offline event for hotplug devices */
-	KOBJ_ONLINE	= (__force kobject_action_t) 0x07,	/* online event for hotplug devices */
-};
-
-
-#ifdef CONFIG_KOBJECT_UEVENT
-int kobject_uevent(struct kobject *kobj,
-		   enum kobject_action action,
-		   struct attribute *attr);
-int kobject_uevent_atomic(struct kobject *kobj,
-			  enum kobject_action action,
-			  struct attribute *attr);
-#else
-static inline int kobject_uevent(struct kobject *kobj,
-				 enum kobject_action action,
-				 struct attribute *attr)
-{
-	return 0;
-}
-static inline int kobject_uevent_atomic(struct kobject *kobj,
-				        enum kobject_action action,
-					struct attribute *attr)
-{
-	return 0;
-}
-#endif
-
-#endif
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index e373c4a..c03f2dc 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -37,6 +37,7 @@
 #include <linux/spinlock.h>
 #include <linux/rcupdate.h>
 
+#ifdef CONFIG_KPROBES
 #include <asm/kprobes.h>
 
 /* kprobe_status settings */
@@ -147,7 +148,6 @@
 	struct task_struct *task;
 };
 
-#ifdef CONFIG_KPROBES
 extern spinlock_t kretprobe_lock;
 extern int arch_prepare_kprobe(struct kprobe *p);
 extern void arch_copy_kprobe(struct kprobe *p);
@@ -158,6 +158,7 @@
 extern void show_registers(struct pt_regs *regs);
 extern kprobe_opcode_t *get_insn_slot(void);
 extern void free_insn_slot(kprobe_opcode_t *slot);
+extern void kprobes_inc_nmissed_count(struct kprobe *p);
 
 /* Get the kprobe at this addr (if any) - called with preemption disabled */
 struct kprobe *get_kprobe(void *addr);
@@ -195,6 +196,11 @@
 void kprobe_flush_task(struct task_struct *tk);
 void recycle_rp_inst(struct kretprobe_instance *ri);
 #else /* CONFIG_KPROBES */
+
+#define __kprobes	/**/
+struct jprobe;
+struct kretprobe;
+
 static inline struct kprobe *kprobe_running(void)
 {
 	return NULL;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index f2dbb68..a43c95f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -122,6 +122,9 @@
 	ATA_FLAG_NOINTR		= (1 << 9), /* FIXME: Remove this once
 					     * proper HSM is in place. */
 	ATA_FLAG_DEBUGMSG	= (1 << 10),
+	ATA_FLAG_NO_ATAPI	= (1 << 11), /* No ATAPI support */
+
+	ATA_FLAG_SUSPENDED	= (1 << 12), /* port is suspended */
 
 	ATA_QCFLAG_ACTIVE	= (1 << 1), /* cmd not yet ack'd to scsi lyer */
 	ATA_QCFLAG_SG		= (1 << 3), /* have s/g table? */
@@ -135,6 +138,8 @@
 	ATA_TMOUT_BOOT_QUICK	= 7 * HZ,	/* hueristic */
 	ATA_TMOUT_CDB		= 30 * HZ,
 	ATA_TMOUT_CDB_QUICK	= 5 * HZ,
+	ATA_TMOUT_INTERNAL	= 30 * HZ,
+	ATA_TMOUT_INTERNAL_QUICK = 5 * HZ,
 
 	/* ATA bus states */
 	BUS_UNKNOWN		= 0,
@@ -194,7 +199,7 @@
 struct ata_queued_cmd;
 
 /* typedefs */
-typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc, unsigned int err_mask);
+typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
 
 struct ata_ioports {
 	unsigned long		cmd_addr;
@@ -279,9 +284,9 @@
 	/* DO NOT iterate over __sg manually, use ata_for_each_sg() */
 	struct scatterlist	*__sg;
 
-	ata_qc_cb_t		complete_fn;
+	unsigned int		err_mask;
 
-	struct completion	*waiting;
+	ata_qc_cb_t		complete_fn;
 
 	void			*private_data;
 };
@@ -330,8 +335,6 @@
 
 	u8			ctl;	/* cache of ATA control register */
 	u8			last_ctl;	/* Cache last written value */
-	unsigned int		bus_state;
-	unsigned int		port_state;
 	unsigned int		pio_mask;
 	unsigned int		mwdma_mask;
 	unsigned int		udma_mask;
@@ -435,6 +438,8 @@
 extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 			     unsigned int n_ports);
 extern void ata_pci_remove_one (struct pci_dev *pdev);
+extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state);
+extern int ata_pci_device_resume(struct pci_dev *pdev);
 #endif /* CONFIG_PCI */
 extern int ata_device_add(const struct ata_probe_ent *ent);
 extern void ata_host_set_remove(struct ata_host_set *host_set);
@@ -444,6 +449,10 @@
 extern int ata_scsi_error(struct Scsi_Host *host);
 extern int ata_scsi_release(struct Scsi_Host *host);
 extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
+extern int ata_scsi_device_resume(struct scsi_device *);
+extern int ata_scsi_device_suspend(struct scsi_device *);
+extern int ata_device_resume(struct ata_port *, struct ata_device *);
+extern int ata_device_suspend(struct ata_port *, struct ata_device *);
 extern int ata_ratelimit(void);
 
 /*
@@ -477,9 +486,10 @@
 extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
 extern u8   ata_bmdma_status(struct ata_port *ap);
 extern void ata_bmdma_irq_clear(struct ata_port *ap);
-extern void ata_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask);
+extern void ata_qc_complete(struct ata_queued_cmd *qc);
 extern void ata_eng_timeout(struct ata_port *ap);
-extern void ata_scsi_simulate(u16 *id, struct scsi_cmnd *cmd,
+extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
+			      struct scsi_cmnd *cmd,
 			      void (*done)(struct scsi_cmnd *));
 extern int ata_std_bios_param(struct scsi_device *sdev,
 			      struct block_device *bdev,
@@ -669,6 +679,7 @@
 	qc->cursect = qc->cursg = qc->cursg_ofs = 0;
 	qc->nsect = 0;
 	qc->nbytes = qc->curbytes = 0;
+	qc->err_mask = 0;
 
 	ata_tf_init(qc->ap, &qc->tf, qc->dev->devno);
 }
diff --git a/include/linux/list.h b/include/linux/list.h
index fbfca73..8e33882 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -202,12 +202,15 @@
  *
  * The old entry will be replaced with the new entry atomically.
  */
-static inline void list_replace_rcu(struct list_head *old, struct list_head *new){
+static inline void list_replace_rcu(struct list_head *old,
+				struct list_head *new)
+{
 	new->next = old->next;
 	new->prev = old->prev;
 	smp_wmb();
 	new->next->prev = new;
 	new->prev->next = new;
+	old->prev = LIST_POISON2;
 }
 
 /**
@@ -578,6 +581,27 @@
 	}
 }
 
+/*
+ * hlist_replace_rcu - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * The old entry will be replaced with the new entry atomically.
+ */
+static inline void hlist_replace_rcu(struct hlist_node *old,
+					struct hlist_node *new)
+{
+	struct hlist_node *next = old->next;
+
+	new->next = next;
+	new->pprev = old->pprev;
+	smp_wmb();
+	if (next)
+		new->next->pprev = &new->next;
+	*new->pprev = new;
+	old->pprev = LIST_POISON2;
+}
+
 static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
 {
 	struct hlist_node *first = h->first;
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 16d4e5a..95c8fea 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -172,7 +172,7 @@
 /*
  * Server-side lock handling
  */
-int		  nlmsvc_async_call(struct nlm_rqst *, u32, rpc_action);
+int		  nlmsvc_async_call(struct nlm_rqst *, u32, const struct rpc_call_ops *);
 u32		  nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
 					struct nlm_lock *, int, struct nlm_cookie *);
 u32		  nlmsvc_unlock(struct nlm_file *, struct nlm_lock *);
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 9a42438..e251dc4 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -70,22 +70,15 @@
 {
 }
 #else
-extern int register_memory(struct memory_block *, struct mem_section *section, struct node *);
 extern int register_new_memory(struct mem_section *);
 extern int unregister_memory_section(struct mem_section *);
 extern int memory_dev_init(void);
-extern int register_memory_notifier(struct notifier_block *nb);
-extern void unregister_memory_notifier(struct notifier_block *nb);
+extern int remove_memory_block(unsigned long, struct mem_section *, int);
 
 #define CONFIG_MEM_BLOCK_SIZE	(PAGES_PER_SECTION<<PAGE_SHIFT)
 
-extern int invalidate_phys_mapping(unsigned long, unsigned long);
 struct notifier_block;
 
-extern int register_memory_notifier(struct notifier_block *nb);
-extern void unregister_memory_notifier(struct notifier_block *nb);
-
-extern struct sysdev_class memory_sysdev_class;
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
 #define hotplug_memory_notifier(fn, pri) {			\
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 8b67cf8..c7ac77e 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -22,6 +22,9 @@
 
 /* Flags for mbind */
 #define MPOL_MF_STRICT	(1<<0)	/* Verify existing pages in the mapping */
+#define MPOL_MF_MOVE	(1<<1)	/* Move pages owned by this process to conform to mapping */
+#define MPOL_MF_MOVE_ALL (1<<2)	/* Move every page to conform to mapping */
+#define MPOL_MF_INTERNAL (1<<3)	/* Internal flags start here */
 
 #ifdef __KERNEL__
 
@@ -65,6 +68,7 @@
 		nodemask_t	 nodes;		/* interleave */
 		/* undefined for default */
 	} v;
+	nodemask_t cpuset_mems_allowed;	/* mempolicy relative to these nodes */
 };
 
 /*
@@ -110,14 +114,6 @@
 #define mpol_set_vma_default(vma) ((vma)->vm_policy = NULL)
 
 /*
- * Hugetlb policy. i386 hugetlb so far works with node numbers
- * instead of zone lists, so give it special interfaces for now.
- */
-extern int mpol_first_node(struct vm_area_struct *vma, unsigned long addr);
-extern int mpol_node_valid(int nid, struct vm_area_struct *vma,
-			unsigned long addr);
-
-/*
  * Tree of shared policies for a shared memory region.
  * Maintain the policies in a pseudo mm that contains vmas. The vmas
  * carry the policy. As a special twist the pseudo mm is indexed in pages, not
@@ -149,13 +145,37 @@
 struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp,
 					    unsigned long idx);
 
-struct mempolicy *get_vma_policy(struct task_struct *task,
-			struct vm_area_struct *vma, unsigned long addr);
-
 extern void numa_default_policy(void);
 extern void numa_policy_init(void);
-extern void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new);
+extern void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *new);
+extern void mpol_rebind_task(struct task_struct *tsk,
+					const nodemask_t *new);
+extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new);
+#define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x))
+
+#ifdef CONFIG_CPUSET
+#define current_cpuset_is_being_rebound() \
+				(cpuset_being_rebound == current->cpuset)
+#else
+#define current_cpuset_is_being_rebound() 0
+#endif
+
 extern struct mempolicy default_policy;
+extern struct zonelist *huge_zonelist(struct vm_area_struct *vma,
+		unsigned long addr);
+
+extern int policy_zone;
+
+static inline void check_highest_zone(int k)
+{
+	if (k > policy_zone)
+		policy_zone = k;
+}
+
+int do_migrate_pages(struct mm_struct *mm,
+	const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags);
+
+extern void *cpuset_being_rebound;	/* Trigger mpol_copy vma rebind */
 
 #else
 
@@ -182,17 +202,6 @@
 	return NULL;
 }
 
-static inline int mpol_first_node(struct vm_area_struct *vma, unsigned long a)
-{
-	return numa_node_id();
-}
-
-static inline int
-mpol_node_valid(int nid, struct vm_area_struct *vma, unsigned long a)
-{
-	return 1;
-}
-
 struct shared_policy {};
 
 static inline int mpol_set_shared_policy(struct shared_policy *info,
@@ -227,11 +236,38 @@
 {
 }
 
-static inline void numa_policy_rebind(const nodemask_t *old,
+static inline void mpol_rebind_policy(struct mempolicy *pol,
 					const nodemask_t *new)
 {
 }
 
+static inline void mpol_rebind_task(struct task_struct *tsk,
+					const nodemask_t *new)
+{
+}
+
+static inline void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new)
+{
+}
+
+#define set_cpuset_being_rebound(x) do {} while (0)
+
+static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma,
+		unsigned long addr)
+{
+	return NODE_DATA(0)->node_zonelists + gfp_zone(GFP_HIGHUSER);
+}
+
+static inline int do_migrate_pages(struct mm_struct *mm,
+			const nodemask_t *from_nodes,
+			const nodemask_t *to_nodes, int flags)
+{
+	return 0;
+}
+
+static inline void check_highest_zone(int k)
+{
+}
 #endif /* CONFIG_NUMA */
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/mm.h b/include/linux/mm.h
index f0cdfd1..df80e63 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -145,7 +145,7 @@
 #define VM_GROWSDOWN	0x00000100	/* general info on the segment */
 #define VM_GROWSUP	0x00000200
 #define VM_SHM		0x00000000	/* Means nothing: delete it later */
-#define VM_UNPAGED	0x00000400	/* Pages managed without map count */
+#define VM_PFNMAP	0x00000400	/* Page-ranges managed without "struct page", just pure PFN */
 #define VM_DENYWRITE	0x00000800	/* ETXTBSY on write attempts.. */
 
 #define VM_EXECUTABLE	0x00001000
@@ -163,6 +163,7 @@
 #define VM_HUGETLB	0x00400000	/* Huge TLB Page VM */
 #define VM_NONLINEAR	0x00800000	/* Is non-linear (remap_file_pages) */
 #define VM_MAPPED_COPY	0x01000000	/* T if mapped copy of data (nommu mmap) */
+#define VM_INSERTPAGE	0x02000000	/* The vma has had "vm_insert_page()" done on it */
 
 #ifndef VM_STACK_DEFAULT_FLAGS		/* arch can override this */
 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
@@ -222,24 +223,27 @@
 					 * & limit reverse map searches.
 					 */
 	union {
-		unsigned long private;	/* Mapping-private opaque data:
-					 * usually used for buffer_heads
-					 * if PagePrivate set; used for
-					 * swp_entry_t if PageSwapCache
-					 * When page is free, this indicates
-					 * order in the buddy system.
-					 */
+	    struct {
+		unsigned long private;		/* Mapping-private opaque data:
+					 	 * usually used for buffer_heads
+						 * if PagePrivate set; used for
+						 * swp_entry_t if PageSwapCache.
+						 * When page is free, this
+						 * indicates order in the buddy
+						 * system.
+						 */
+		struct address_space *mapping;	/* If low bit clear, points to
+						 * inode address_space, or NULL.
+						 * If page mapped as anonymous
+						 * memory, low bit is set, and
+						 * it points to anon_vma object:
+						 * see PAGE_MAPPING_ANON below.
+						 */
+	    };
 #if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
-		spinlock_t ptl;
+	    spinlock_t ptl;
 #endif
-	} u;
-	struct address_space *mapping;	/* If low bit clear, points to
-					 * inode address_space, or NULL.
-					 * If page mapped as anonymous
-					 * memory, low bit is set, and
-					 * it points to anon_vma object:
-					 * see PAGE_MAPPING_ANON below.
-					 */
+	};
 	pgoff_t index;			/* Our offset within mapping. */
 	struct list_head lru;		/* Pageout list, eg. active_list
 					 * protected by zone->lru_lock !
@@ -260,8 +264,8 @@
 #endif /* WANT_PAGE_VIRTUAL */
 };
 
-#define page_private(page)		((page)->u.private)
-#define set_page_private(page, v)	((page)->u.private = (v))
+#define page_private(page)		((page)->private)
+#define set_page_private(page, v)	((page)->private = (v))
 
 /*
  * FIXME: take this include out, include page-flags.h in
@@ -307,7 +311,7 @@
  */
 #define get_page_testone(p)	atomic_inc_and_test(&(p)->_count)
 
-#define set_page_count(p,v) 	atomic_set(&(p)->_count, v - 1)
+#define set_page_count(p,v) 	atomic_set(&(p)->_count, (v) - 1)
 #define __put_page(p)		atomic_dec(&(p)->_count)
 
 extern void FASTCALL(__page_cache_release(struct page *));
@@ -633,14 +637,38 @@
 int shmem_lock(struct file *file, int lock, struct user_struct *user);
 #else
 #define shmem_nopage filemap_nopage
-#define shmem_lock(a, b, c) 	({0;})	/* always in memory, no need to lock */
-#define shmem_set_policy(a, b)	(0)
-#define shmem_get_policy(a, b)	(NULL)
+
+static inline int shmem_lock(struct file *file, int lock,
+			     struct user_struct *user)
+{
+	return 0;
+}
+
+static inline int shmem_set_policy(struct vm_area_struct *vma,
+				   struct mempolicy *new)
+{
+	return 0;
+}
+
+static inline struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
+						 unsigned long addr)
+{
+	return NULL;
+}
 #endif
 struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags);
+extern int shmem_mmap(struct file *file, struct vm_area_struct *vma);
 
 int shmem_zero_setup(struct vm_area_struct *);
 
+#ifndef CONFIG_MMU
+extern unsigned long shmem_get_unmapped_area(struct file *file,
+					     unsigned long addr,
+					     unsigned long len,
+					     unsigned long pgoff,
+					     unsigned long flags);
+#endif
+
 static inline int can_do_mlock(void)
 {
 	if (capable(CAP_IPC_LOCK))
@@ -664,6 +692,7 @@
 	unsigned long truncate_count;		/* Compare vm_truncate_count */
 };
 
+struct page *vm_normal_page(struct vm_area_struct *, unsigned long, pte_t);
 unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address,
 		unsigned long size, struct zap_details *);
 unsigned long unmap_vmas(struct mmu_gather **tlb,
@@ -688,14 +717,31 @@
 }
 
 extern int vmtruncate(struct inode * inode, loff_t offset);
+extern int vmtruncate_range(struct inode * inode, loff_t offset, loff_t end);
 extern int install_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, struct page *page, pgprot_t prot);
 extern int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long pgoff, pgprot_t prot);
-extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma, unsigned long address, int write_access);
 
-static inline int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access)
+#ifdef CONFIG_MMU
+extern int __handle_mm_fault(struct mm_struct *mm,struct vm_area_struct *vma,
+			unsigned long address, int write_access);
+
+static inline int handle_mm_fault(struct mm_struct *mm,
+			struct vm_area_struct *vma, unsigned long address,
+			int write_access)
 {
-	return __handle_mm_fault(mm, vma, address, write_access) & (~VM_FAULT_WRITE);
+	return __handle_mm_fault(mm, vma, address, write_access) &
+				(~VM_FAULT_WRITE);
 }
+#else
+static inline int handle_mm_fault(struct mm_struct *mm,
+			struct vm_area_struct *vma, unsigned long address,
+			int write_access)
+{
+	/* should never happen if there's no MMU */
+	BUG();
+	return VM_FAULT_SIGBUS;
+}
+#endif
 
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
@@ -740,6 +786,8 @@
 extern struct shrinker *set_shrinker(int, shrinker_t);
 extern void remove_shrinker(struct shrinker *shrinker);
 
+extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl));
+
 int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address);
 int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address);
 int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address);
@@ -770,7 +818,7 @@
  * overflow into the next struct page (as it might with DEBUG_SPINLOCK).
  * When freeing, reset page->mapping so free_pages_check won't complain.
  */
-#define __pte_lockptr(page)	&((page)->u.ptl)
+#define __pte_lockptr(page)	&((page)->ptl)
 #define pte_lock_init(_page)	do {					\
 	spin_lock_init(__pte_lockptr(_page));				\
 } while (0)
@@ -892,6 +940,8 @@
 /* filemap.c */
 extern unsigned long page_unuse(struct page *);
 extern void truncate_inode_pages(struct address_space *, loff_t);
+extern void truncate_inode_pages_range(struct address_space *,
+				       loff_t lstart, loff_t lend);
 
 /* generic vm_area_ops exported for stackable file systems */
 extern struct page *filemap_nopage(struct vm_area_struct *, unsigned long, int *);
@@ -952,8 +1002,9 @@
 unsigned long vmalloc_to_pfn(void *addr);
 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
 			unsigned long pfn, unsigned long size, pgprot_t);
+int vm_insert_page(struct vm_area_struct *, unsigned long addr, struct page *);
 
-struct page *follow_page(struct mm_struct *, unsigned long address,
+struct page *follow_page(struct vm_area_struct *, unsigned long address,
 			unsigned int foll_flags);
 #define FOLL_WRITE	0x01	/* check pte is writable */
 #define FOLL_TOUCH	0x02	/* mark page accessed */
@@ -988,5 +1039,12 @@
 /* /proc/<pid>/oom_adj set to -17 protects from the oom-killer */
 #define OOM_DISABLE -17
 
+int drop_caches_sysctl_handler(struct ctl_table *, int, struct file *,
+					void __user *, size_t *, loff_t *);
+int shrink_slab(unsigned long scanned, gfp_t gfp_mask,
+			unsigned long lru_pages);
+void drop_pagecache(void);
+void drop_slab(void);
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MM_H */
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 47762ca..49cc68a 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -38,3 +38,25 @@
 		zone->nr_inactive--;
 	}
 }
+
+/*
+ * Isolate one page from the LRU lists.
+ *
+ * - zone->lru_lock must be held
+ */
+static inline int __isolate_lru_page(struct page *page)
+{
+	if (unlikely(!TestClearPageLRU(page)))
+		return 0;
+
+	if (get_page_testone(page)) {
+		/*
+		 * It is being freed elsewhere
+		 */
+		__put_page(page);
+		SetPageLRU(page);
+		return -ENOENT;
+	}
+
+	return 1;
+}
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 18fc77f..30dd978 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -30,7 +30,12 @@
 	unsigned int		tacc_ns;
 	unsigned int		max_dtr;
 	unsigned int		read_blkbits;
+	unsigned int		write_blkbits;
 	unsigned int		capacity;
+	unsigned int		read_partial:1,
+				read_misalign:1,
+				write_partial:1,
+				write_misalign:1;
 };
 
 struct sd_scr {
diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h
index f819cae..a14dc30 100644
--- a/include/linux/mmc/protocol.h
+++ b/include/linux/mmc/protocol.h
@@ -63,7 +63,7 @@
   /* class 5 */
 #define MMC_ERASE_GROUP_START    35   /* ac   [31:0] data addr   R1  */
 #define MMC_ERASE_GROUP_END      36   /* ac   [31:0] data addr   R1  */
-#define MMC_ERASE                37   /* ac                      R1b */
+#define MMC_ERASE                38   /* ac                      R1b */
 
   /* class 9 */
 #define MMC_FAST_IO              39   /* ac   <Complex>          R4  */
@@ -74,7 +74,7 @@
 
   /* class 8 */
 #define MMC_APP_CMD              55   /* ac   [31:16] RCA        R1  */
-#define MMC_GEN_CMD              56   /* adtc [0] RD/WR          R1b */
+#define MMC_GEN_CMD              56   /* adtc [0] RD/WR          R1  */
 
 /* SD commands                           type  argument     response */
   /* class 8 */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 9f22090d..7e4ae6a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -38,7 +38,7 @@
 #if defined(CONFIG_SMP)
 struct zone_padding {
 	char x[0];
-} ____cacheline_maxaligned_in_smp;
+} ____cacheline_internodealigned_in_smp;
 #define ZONE_PADDING(name)	struct zone_padding name;
 #else
 #define ZONE_PADDING(name)
@@ -46,7 +46,6 @@
 
 struct per_cpu_pages {
 	int count;		/* number of pages in the list */
-	int low;		/* low watermark, refill needed */
 	int high;		/* high watermark, emptying needed */
 	int batch;		/* chunk size for buddy add/remove */
 	struct list_head list;	/* the list of pages */
@@ -234,7 +233,7 @@
 	 * rarely used fields:
 	 */
 	char			*name;
-} ____cacheline_maxaligned_in_smp;
+} ____cacheline_internodealigned_in_smp;
 
 
 /*
@@ -389,6 +388,11 @@
 #define for_each_zone(zone) \
 	for (zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
 
+static inline int populated_zone(struct zone *zone)
+{
+	return (!!zone->present_pages);
+}
+
 static inline int is_highmem_idx(int idx)
 {
 	return (idx == ZONE_HIGHMEM);
@@ -398,6 +402,7 @@
 {
 	return (idx == ZONE_NORMAL);
 }
+
 /**
  * is_highmem - helper function to quickly check if a struct zone is a 
  *              highmem zone or not.  This is an attempt to keep references
@@ -414,6 +419,16 @@
 	return zone == zone->zone_pgdat->node_zones + ZONE_NORMAL;
 }
 
+static inline int is_dma32(struct zone *zone)
+{
+	return zone == zone->zone_pgdat->node_zones + ZONE_DMA32;
+}
+
+static inline int is_dma(struct zone *zone)
+{
+	return zone == zone->zone_pgdat->node_zones + ZONE_DMA;
+}
+
 /* These two functions are used to setup the per zone pages min values */
 struct ctl_table;
 struct file;
@@ -422,6 +437,8 @@
 extern int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1];
 int lowmem_reserve_ratio_sysctl_handler(struct ctl_table *, int, struct file *,
 					void __user *, size_t *, loff_t *);
+int percpu_pagelist_fraction_sysctl_handler(struct ctl_table *, int, struct file *,
+					void __user *, size_t *, loff_t *);
 
 #include <linux/topology.h>
 /* Returns the number of the current Node. */
@@ -435,7 +452,6 @@
 #define NODE_DATA(nid)		(&contig_page_data)
 #define NODE_MEM_MAP(nid)	mem_map
 #define MAX_NODES_SHIFT		1
-#define pfn_to_nid(pfn)		(0)
 
 #else /* CONFIG_NEED_MULTIPLE_NODES */
 
@@ -470,6 +486,10 @@
 #define early_pfn_to_nid(nid)  (0UL)
 #endif
 
+#ifdef CONFIG_FLATMEM
+#define pfn_to_nid(pfn)		(0)
+#endif
+
 #define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT)
 #define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT)
 
@@ -564,11 +584,6 @@
 	return valid_section(__nr_to_section(nr));
 }
 
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-#define kvaddr_to_nid(kaddr)	pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
-
 static inline struct mem_section *__pfn_to_section(unsigned long pfn)
 {
 	return __nr_to_section(pfn_to_section_nr(pfn));
@@ -598,13 +613,14 @@
  * this restriction.
  */
 #ifdef CONFIG_NUMA
-#define pfn_to_nid		early_pfn_to_nid
-#endif
-
-#define pfn_to_pgdat(pfn)						\
+#define pfn_to_nid(pfn)							\
 ({									\
-	NODE_DATA(pfn_to_nid(pfn));					\
+	unsigned long __pfn_to_nid_pfn = (pfn);				\
+	page_to_nid(pfn_to_page(__pfn_to_nid_pfn));			\
 })
+#else
+#define pfn_to_nid(pfn)		(0)
+#endif
 
 #define early_pfn_valid(pfn)	pfn_valid(pfn)
 void sparse_init(void);
@@ -613,12 +629,6 @@
 #define sparse_index_init(_sec, _nid)  do {} while (0)
 #endif /* CONFIG_SPARSEMEM */
 
-#ifdef CONFIG_NODES_SPAN_OTHER_NODES
-#define early_pfn_in_nid(pfn, nid)	(early_pfn_to_nid(pfn) == (nid))
-#else
-#define early_pfn_in_nid(pfn, nid)	(1)
-#endif
-
 #ifndef early_pfn_valid
 #define early_pfn_valid(pfn)	(1)
 #endif
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 368ec8e..b5c98c4 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -10,7 +10,7 @@
 #ifdef MODULE
 #define MODULE_PARAM_PREFIX /* empty */
 #else
-#define MODULE_PARAM_PREFIX __stringify(KBUILD_MODNAME) "."
+#define MODULE_PARAM_PREFIX KBUILD_MODNAME "."
 #endif
 
 #ifdef MODULE
diff --git a/include/linux/mount.h b/include/linux/mount.h
index dd4e83e..b98a709 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -22,7 +22,8 @@
 #define MNT_NOEXEC	0x04
 #define MNT_SHARED	0x10	/* if the vfsmount is a shared mount */
 #define MNT_UNBINDABLE	0x20	/* if the vfsmount is a unbindable mount */
-#define MNT_PNODE_MASK	0x30	/* propogation flag mask */
+
+#define MNT_PNODE_MASK	(MNT_SHARED | MNT_UNBINDABLE)
 
 struct vfsmount {
 	struct list_head mnt_hash;
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 941da5c..e933e2a 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -329,7 +329,8 @@
 extern void fat_cache_inval_inode(struct inode *inode);
 extern int fat_get_cluster(struct inode *inode, int cluster,
 			   int *fclus, int *dclus);
-extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys);
+extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
+		    unsigned long *mapped_blocks);
 
 /* fat/dir.c */
 extern struct file_operations fat_dir_operations;
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index 3c9ea4b..23a5689 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -1,7 +1,7 @@
 
 /* Common Flash Interface structures
  * See http://support.intel.com/design/flash/technote/index.htm
- * $Id: cfi.h,v 1.56 2005/11/07 11:14:54 gleixner Exp $
+ * $Id: cfi.h,v 1.57 2005/11/15 23:28:17 tpoynor Exp $
  */
 
 #ifndef __MTD_CFI_H__
@@ -426,6 +426,22 @@
 	}
 }
 
+static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr)
+{
+	map_word val = map_read(map, addr);
+
+	if (map_bankwidth_is_1(map)) {
+		return val.x[0] & 0xff;
+	} else if (map_bankwidth_is_2(map)) {
+		return cfi16_to_cpu(val.x[0]);
+	} else {
+		/* No point in a 64-bit byteswap since that would just be
+		   swapping the responses from different chips, and we are
+		   only interested in one chip (a representative sample) */
+		return cfi32_to_cpu(val.x[0]);
+	}
+}
+
 static inline void cfi_udelay(int us)
 {
 	if (us >= 1000) {
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index f1fd421..7419b5f 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -17,7 +17,6 @@
 #include <linux/mtd/bbm.h>
 
 #define MAX_BUFFERRAM		2
-#define MAX_ONENAND_PAGESIZE	(2048 + 64)
 
 /* Scan and identify a OneNAND device */
 extern int onenand_scan(struct mtd_info *mtd, int max_chips);
@@ -110,6 +109,7 @@
 	spinlock_t		chip_lock;
 	wait_queue_head_t	wq;
 	onenand_state_t		state;
+	unsigned char		*page_buf;
 
 	struct nand_oobinfo	*autooob;
 
@@ -134,13 +134,12 @@
  * Options bits
  */
 #define ONENAND_CONT_LOCK		(0x0001)
-
+#define ONENAND_PAGEBUF_ALLOC		(0x1000)
 
 /*
  * OneNAND Flash Manufacturer ID Codes
  */
 #define ONENAND_MFR_SAMSUNG	0xec
-#define ONENAND_MFR_UNKNOWN	0x00
 
 /**
  * struct nand_manufacturers - NAND Flash Manufacturer ID Structure
diff --git a/include/linux/n_r3964.h b/include/linux/n_r3964.h
index 2352bcd3..db4f377 100644
--- a/include/linux/n_r3964.h
+++ b/include/linux/n_r3964.h
@@ -13,6 +13,10 @@
  * L. Haag
  *
  * $Log: r3964.h,v $
+ * Revision 1.4  2005/12/21 19:54:24  Kurt Huwig <kurt huwig de>
+ * Fixed HZ usage on 2.6 kernels
+ * Removed unnecessary include
+ *
  * Revision 1.3  2001/03/18 13:02:24  dwmw2
  * Fix timer usage, use spinlocks properly.
  *
@@ -45,9 +49,11 @@
 #define __LINUX_N_R3964_H__
 
 /* line disciplines for r3964 protocol */
-#include <asm/termios.h>
 
 #ifdef __KERNEL__
+
+#include <linux/param.h>
+
 /*
  * Common ascii handshake characters:
  */
@@ -58,14 +64,14 @@
 #define NAK 0x15
 
 /*
- * Timeouts (msecs/10 msecs per timer interrupt):
+ * Timeouts (from milliseconds to jiffies)
  */
 
-#define R3964_TO_QVZ 550/10
-#define R3964_TO_ZVZ 220/10
-#define R3964_TO_NO_BUF 400/10
-#define R3964_NO_TX_ROOM 100/10
-#define R3964_TO_RX_PANIC 4000/10
+#define R3964_TO_QVZ ((550)*HZ/1000)
+#define R3964_TO_ZVZ ((220)*HZ/1000)
+#define R3964_TO_NO_BUF ((400)*HZ/1000)
+#define R3964_NO_TX_ROOM ((100)*HZ/1000)
+#define R3964_TO_RX_PANIC ((4000)*HZ/1000)
 #define R3964_MAX_RETRIES 5
 
 #endif
diff --git a/include/linux/nbd.h b/include/linux/nbd.h
index 090e210..f95d51f 100644
--- a/include/linux/nbd.h
+++ b/include/linux/nbd.h
@@ -37,18 +37,26 @@
 /* userspace doesn't need the nbd_device structure */
 #ifdef __KERNEL__
 
+#include <linux/wait.h>
+
 /* values for flags field */
 #define NBD_READ_ONLY 0x0001
 #define NBD_WRITE_NOCHK 0x0002
 
+struct request;
+
 struct nbd_device {
 	int flags;
 	int harderror;		/* Code of hard error			*/
 	struct socket * sock;
 	struct file * file; 	/* If == NULL, device is not ready, yet	*/
 	int magic;
+
 	spinlock_t queue_lock;
 	struct list_head queue_head;/* Requests are added here...	*/
+	struct request *active_req;
+	wait_queue_head_t active_wq;
+
 	struct semaphore tx_lock;
 	struct gendisk *disk;
 	int blksize;
diff --git a/include/linux/ncp.h b/include/linux/ncp.h
index 99f7787..99f0ade 100644
--- a/include/linux/ncp.h
+++ b/include/linux/ncp.h
@@ -20,29 +20,29 @@
 #define NCP_DEALLOC_SLOT_REQUEST (0x5555)
 
 struct ncp_request_header {
-	__u16 type __attribute__((packed));
-	__u8 sequence __attribute__((packed));
-	__u8 conn_low __attribute__((packed));
-	__u8 task __attribute__((packed));
-	__u8 conn_high __attribute__((packed));
-	__u8 function __attribute__((packed));
-	__u8 data[0] __attribute__((packed));
-};
+	__u16 type;
+	__u8 sequence;
+	__u8 conn_low;
+	__u8 task;
+	__u8 conn_high;
+	__u8 function;
+	__u8 data[0];
+} __attribute__((packed));
 
 #define NCP_REPLY                (0x3333)
 #define NCP_WATCHDOG		 (0x3E3E)
 #define NCP_POSITIVE_ACK         (0x9999)
 
 struct ncp_reply_header {
-	__u16 type __attribute__((packed));
-	__u8 sequence __attribute__((packed));
-	__u8 conn_low __attribute__((packed));
-	__u8 task __attribute__((packed));
-	__u8 conn_high __attribute__((packed));
-	__u8 completion_code __attribute__((packed));
-	__u8 connection_state __attribute__((packed));
-	__u8 data[0] __attribute__((packed));
-};
+	__u16 type;
+	__u8 sequence;
+	__u8 conn_low;
+	__u8 task;
+	__u8 conn_high;
+	__u8 completion_code;
+	__u8 connection_state;
+	__u8 data[0];
+} __attribute__((packed));
 
 #define NCP_VOLNAME_LEN (16)
 #define NCP_NUMBER_OF_VOLUMES (256)
@@ -128,37 +128,37 @@
 };
 
 struct nw_info_struct {
-	__u32 spaceAlloc __attribute__((packed));
-	__le32 attributes __attribute__((packed));
-	__u16 flags __attribute__((packed));
-	__le32 dataStreamSize __attribute__((packed));
-	__le32 totalStreamSize __attribute__((packed));
-	__u16 numberOfStreams __attribute__((packed));
-	__le16 creationTime __attribute__((packed));
-	__le16 creationDate __attribute__((packed));
-	__u32 creatorID __attribute__((packed));
-	__le16 modifyTime __attribute__((packed));
-	__le16 modifyDate __attribute__((packed));
-	__u32 modifierID __attribute__((packed));
-	__le16 lastAccessDate __attribute__((packed));
-	__u16 archiveTime __attribute__((packed));
-	__u16 archiveDate __attribute__((packed));
-	__u32 archiverID __attribute__((packed));
-	__u16 inheritedRightsMask __attribute__((packed));
-	__le32 dirEntNum __attribute__((packed));
-	__le32 DosDirNum __attribute__((packed));
-	__u32 volNumber __attribute__((packed));
-	__u32 EADataSize __attribute__((packed));
-	__u32 EAKeyCount __attribute__((packed));
-	__u32 EAKeySize __attribute__((packed));
-	__u32 NSCreator __attribute__((packed));
-	__u8 nameLen __attribute__((packed));
-	__u8 entryName[256] __attribute__((packed));
+	__u32 spaceAlloc;
+	__le32 attributes;
+	__u16 flags;
+	__le32 dataStreamSize;
+	__le32 totalStreamSize;
+	__u16 numberOfStreams;
+	__le16 creationTime;
+	__le16 creationDate;
+	__u32 creatorID;
+	__le16 modifyTime;
+	__le16 modifyDate;
+	__u32 modifierID;
+	__le16 lastAccessDate;
+	__u16 archiveTime;
+	__u16 archiveDate;
+	__u32 archiverID;
+	__u16 inheritedRightsMask;
+	__le32 dirEntNum;
+	__le32 DosDirNum;
+	__u32 volNumber;
+	__u32 EADataSize;
+	__u32 EAKeyCount;
+	__u32 EAKeySize;
+	__u32 NSCreator;
+	__u8 nameLen;
+	__u8 entryName[256];
 	/* libncp may depend on there being nothing after entryName */
 #ifdef __KERNEL__
 	struct nw_nfs_info nfs;
 #endif
-};
+} __attribute__((packed));
 
 /* modify mask - use with MODIFY_DOS_INFO structure */
 #define DM_ATTRIBUTES		  (cpu_to_le32(0x02))
@@ -176,26 +176,26 @@
 #define DM_MAXIMUM_SPACE	  (cpu_to_le32(0x2000))
 
 struct nw_modify_dos_info {
-	__le32 attributes __attribute__((packed));
-	__le16 creationDate __attribute__((packed));
-	__le16 creationTime __attribute__((packed));
-	__u32 creatorID __attribute__((packed));
-	__le16 modifyDate __attribute__((packed));
-	__le16 modifyTime __attribute__((packed));
-	__u32 modifierID __attribute__((packed));
-	__u16 archiveDate __attribute__((packed));
-	__u16 archiveTime __attribute__((packed));
-	__u32 archiverID __attribute__((packed));
-	__le16 lastAccessDate __attribute__((packed));
-	__u16 inheritanceGrantMask __attribute__((packed));
-	__u16 inheritanceRevokeMask __attribute__((packed));
-	__u32 maximumSpace __attribute__((packed));
-};
+	__le32 attributes;
+	__le16 creationDate;
+	__le16 creationTime;
+	__u32 creatorID;
+	__le16 modifyDate;
+	__le16 modifyTime;
+	__u32 modifierID;
+	__u16 archiveDate;
+	__u16 archiveTime;
+	__u32 archiverID;
+	__le16 lastAccessDate;
+	__u16 inheritanceGrantMask;
+	__u16 inheritanceRevokeMask;
+	__u32 maximumSpace;
+} __attribute__((packed));
 
 struct nw_search_sequence {
-	__u8 volNumber __attribute__((packed));
-	__u32 dirBase __attribute__((packed));
-	__u32 sequence __attribute__((packed));
-};
+	__u8 volNumber;
+	__u32 dirBase;
+	__u32 sequence;
+} __attribute__((packed));
 
 #endif				/* _LINUX_NCP_H */
diff --git a/include/linux/net.h b/include/linux/net.h
index d6a41e6..28195a2 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -107,7 +107,7 @@
 struct socket {
 	socket_state		state;
 	unsigned long		flags;
-	struct proto_ops	*ops;
+	const struct proto_ops	*ops;
 	struct fasync_struct	*fasync_list;
 	struct file		*file;
 	struct sock		*sk;
@@ -260,7 +260,7 @@
 SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock, struct vm_area_struct *vma), \
 	      (file, sock, vma)) \
 	      \
-static struct proto_ops name##_ops = {			\
+static const struct proto_ops name##_ops = {			\
 	.family		= fam,				\
 	.owner		= THIS_MODULE,			\
 	.release	= __lock_##name##_release,	\
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 936f8b7..7fda03d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -684,6 +684,7 @@
 extern int		netif_rx_ni(struct sk_buff *skb);
 #define HAVE_NETIF_RECEIVE_SKB 1
 extern int		netif_receive_skb(struct sk_buff *skb);
+extern int		dev_valid_name(const char *name);
 extern int		dev_ioctl(unsigned int cmd, void __user *);
 extern int		dev_ethtool(struct ifreq *);
 extern unsigned		dev_get_flags(const struct net_device *);
@@ -801,12 +802,16 @@
 	return (1 << debug_value) - 1;
 }
 
-/* Schedule rx intr now? */
+/* Test if receive needs to be scheduled */
+static inline int __netif_rx_schedule_prep(struct net_device *dev)
+{
+	return !test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state);
+}
 
+/* Test if receive needs to be scheduled but only if up */
 static inline int netif_rx_schedule_prep(struct net_device *dev)
 {
-	return netif_running(dev) &&
-		!test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state);
+	return netif_running(dev) && __netif_rx_schedule_prep(dev);
 }
 
 /* Add interface to tail of rx poll list. This assumes that _prep has
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index be365e7..4cf6088 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -168,6 +168,37 @@
 		   const struct net_device *out,
 		   struct nf_loginfo *li,
 		   const char *fmt, ...);
+
+int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
+		 struct net_device *indev, struct net_device *outdev,
+		 int (*okfn)(struct sk_buff *), int thresh);
+
+/**
+ *	nf_hook_thresh - call a netfilter hook
+ *	
+ *	Returns 1 if the hook has allowed the packet to pass.  The function
+ *	okfn must be invoked by the caller in this case.  Any other return
+ *	value indicates the packet has been consumed by the hook.
+ */
+static inline int nf_hook_thresh(int pf, unsigned int hook,
+				 struct sk_buff **pskb,
+				 struct net_device *indev,
+				 struct net_device *outdev,
+				 int (*okfn)(struct sk_buff *), int thresh)
+{
+#ifndef CONFIG_NETFILTER_DEBUG
+	if (list_empty(&nf_hooks[pf][hook]))
+		return 1;
+#endif
+	return nf_hook_slow(pf, hook, pskb, indev, outdev, okfn, thresh);
+}
+
+static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
+			  struct net_device *indev, struct net_device *outdev,
+			  int (*okfn)(struct sk_buff *))
+{
+	return nf_hook_thresh(pf, hook, pskb, indev, outdev, okfn, INT_MIN);
+}
                    
 /* Activate hook; either okfn or kfree_skb called, unless a hook
    returns NF_STOLEN (in which case, it's up to the hook to deal with
@@ -188,35 +219,17 @@
 
 /* This is gross, but inline doesn't cut it for avoiding the function
    call in fast path: gcc doesn't inline (needs value tracking?). --RR */
-#ifdef CONFIG_NETFILTER_DEBUG
-#define NF_HOOK(pf, hook, skb, indev, outdev, okfn)			       \
-({int __ret;								       \
-if ((__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \
-	__ret = (okfn)(skb);						       \
-__ret;})
-#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh)	       \
-({int __ret;								       \
-if ((__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1)  \
-	__ret = (okfn)(skb);						       \
-__ret;})
-#else
-#define NF_HOOK(pf, hook, skb, indev, outdev, okfn)			       \
-({int __ret;								       \
-if (list_empty(&nf_hooks[pf][hook]) ||					       \
-    (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, INT_MIN)) == 1) \
-	__ret = (okfn)(skb);						       \
-__ret;})
-#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh)	       \
-({int __ret;								       \
-if (list_empty(&nf_hooks[pf][hook]) ||					       \
-    (__ret=nf_hook_slow(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1)  \
-	__ret = (okfn)(skb);						       \
-__ret;})
-#endif
 
-int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb,
-		 struct net_device *indev, struct net_device *outdev,
-		 int (*okfn)(struct sk_buff *), int thresh);
+/* HX: It's slightly less gross now. */
+
+#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh)	       \
+({int __ret;								       \
+if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh)) == 1)\
+	__ret = (okfn)(skb);						       \
+__ret;})
+
+#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
+	NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)
 
 /* Call setsockopt() */
 int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt, 
@@ -261,6 +274,20 @@
 extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer);
 extern int nf_unregister_queue_rerouter(int pf);
 
+#include <net/flow.h>
+extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
+
+static inline void
+nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family)
+{
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+	void (*decodefn)(struct sk_buff *, struct flowi *);
+
+	if (family == AF_INET && (decodefn = ip_nat_decode_session) != NULL)
+		decodefn(skb, fl);
+#endif
+}
+
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 extern struct proc_dir_entry *proc_net_netfilter;
@@ -268,7 +295,24 @@
 
 #else /* !CONFIG_NETFILTER */
 #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
+static inline int nf_hook_thresh(int pf, unsigned int hook,
+				 struct sk_buff **pskb,
+				 struct net_device *indev,
+				 struct net_device *outdev,
+				 int (*okfn)(struct sk_buff *), int thresh)
+{
+	return okfn(*pskb);
+}
+static inline int nf_hook(int pf, unsigned int hook, struct sk_buff **pskb,
+			  struct net_device *indev, struct net_device *outdev,
+			  int (*okfn)(struct sk_buff *))
+{
+	return okfn(*pskb);
+}
 static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
+struct flowi;
+static inline void
+nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) {}
 #endif /*CONFIG_NETFILTER*/
 
 #endif /*__KERNEL__*/
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 116fcac..668ec94 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -64,6 +64,9 @@
 	CTA_PROTO_ICMP_ID,
 	CTA_PROTO_ICMP_TYPE,
 	CTA_PROTO_ICMP_CODE,
+	CTA_PROTO_ICMPV6_ID,
+	CTA_PROTO_ICMPV6_TYPE,
+	CTA_PROTO_ICMPV6_CODE,
 	__CTA_PROTO_MAX
 };
 #define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)
@@ -128,6 +131,4 @@
 };
 #define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
 
-#define CTA_HELP_MAXNAMESIZE	32
-
 #endif /* _IPCONNTRACK_NETLINK_H */
diff --git a/include/linux/netfilter_ipv4/ipt_policy.h b/include/linux/netfilter_ipv4/ipt_policy.h
new file mode 100644
index 0000000..7fd1bec
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ipt_policy.h
@@ -0,0 +1,52 @@
+#ifndef _IPT_POLICY_H
+#define _IPT_POLICY_H
+
+#define IPT_POLICY_MAX_ELEM	4
+
+enum ipt_policy_flags
+{
+	IPT_POLICY_MATCH_IN	= 0x1,
+	IPT_POLICY_MATCH_OUT	= 0x2,
+	IPT_POLICY_MATCH_NONE	= 0x4,
+	IPT_POLICY_MATCH_STRICT	= 0x8,
+};
+
+enum ipt_policy_modes
+{
+	IPT_POLICY_MODE_TRANSPORT,
+	IPT_POLICY_MODE_TUNNEL
+};
+
+struct ipt_policy_spec
+{
+	u_int8_t	saddr:1,
+			daddr:1,
+			proto:1,
+			mode:1,
+			spi:1,
+			reqid:1;
+};
+
+struct ipt_policy_elem
+{
+	u_int32_t	saddr;
+	u_int32_t	smask;
+	u_int32_t	daddr;
+	u_int32_t	dmask;
+	u_int32_t	spi;
+	u_int32_t	reqid;
+	u_int8_t	proto;
+	u_int8_t	mode;
+
+	struct ipt_policy_spec	match;
+	struct ipt_policy_spec	invert;
+};
+
+struct ipt_policy_info
+{
+	struct ipt_policy_elem pol[IPT_POLICY_MAX_ELEM];
+	u_int16_t flags;
+	u_int16_t len;
+};
+
+#endif /* _IPT_POLICY_H */
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 2efc046..c163ba3 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -474,7 +474,11 @@
 extern int ip6t_ext_hdr(u8 nexthdr);
 /* find specified header and get offset to it */
 extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
-			 u8 target);
+			 int target, unsigned short *fragoff);
+
+extern int ip6_masked_addrcmp(const struct in6_addr *addr1,
+			      const struct in6_addr *mask,
+			      const struct in6_addr *addr2);
 
 #define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1))
 
diff --git a/include/linux/netfilter_ipv6/ip6t_policy.h b/include/linux/netfilter_ipv6/ip6t_policy.h
new file mode 100644
index 0000000..5a93afc
--- /dev/null
+++ b/include/linux/netfilter_ipv6/ip6t_policy.h
@@ -0,0 +1,52 @@
+#ifndef _IP6T_POLICY_H
+#define _IP6T_POLICY_H
+
+#define IP6T_POLICY_MAX_ELEM	4
+
+enum ip6t_policy_flags
+{
+	IP6T_POLICY_MATCH_IN		= 0x1,
+	IP6T_POLICY_MATCH_OUT		= 0x2,
+	IP6T_POLICY_MATCH_NONE		= 0x4,
+	IP6T_POLICY_MATCH_STRICT	= 0x8,
+};
+
+enum ip6t_policy_modes
+{
+	IP6T_POLICY_MODE_TRANSPORT,
+	IP6T_POLICY_MODE_TUNNEL
+};
+
+struct ip6t_policy_spec
+{
+	u_int8_t	saddr:1,
+			daddr:1,
+			proto:1,
+			mode:1,
+			spi:1,
+			reqid:1;
+};
+
+struct ip6t_policy_elem
+{
+	struct in6_addr	saddr;
+	struct in6_addr	smask;
+	struct in6_addr	daddr;
+	struct in6_addr	dmask;
+	u_int32_t	spi;
+	u_int32_t	reqid;
+	u_int8_t	proto;
+	u_int8_t	mode;
+
+	struct ip6t_policy_spec	match;
+	struct ip6t_policy_spec	invert;
+};
+
+struct ip6t_policy_info
+{
+	struct ip6t_policy_elem pol[IP6T_POLICY_MAX_ELEM];
+	u_int16_t flags;
+	u_int16_t len;
+};
+
+#endif /* _IP6T_POLICY_H */
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 12787a9..547d649 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -38,9 +38,6 @@
 # define NFS_DEBUG
 #endif
 
-#define NFS_MAX_FILE_IO_BUFFER_SIZE	32768
-#define NFS_DEF_FILE_IO_BUFFER_SIZE	4096
-
 /* Default timeout values */
 #define NFS_MAX_UDP_TIMEOUT	(60*HZ)
 #define NFS_MAX_TCP_TIMEOUT	(600*HZ)
@@ -65,6 +62,7 @@
 #define FLUSH_STABLE		4	/* commit to stable storage */
 #define FLUSH_LOWPRI		8	/* low priority background flush */
 #define FLUSH_HIGHPRI		16	/* high priority memory reclaim flush */
+#define FLUSH_NOCOMMIT		32	/* Don't send the NFSv3/v4 COMMIT */
 
 #ifdef __KERNEL__
 
@@ -291,6 +289,7 @@
 /*
  * linux/fs/nfs/inode.c
  */
+extern int nfs_sync_mapping(struct address_space *mapping);
 extern void nfs_zap_caches(struct inode *);
 extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
 				struct nfs_fattr *);
@@ -393,6 +392,17 @@
 extern struct inode_operations nfs_symlink_inode_operations;
 
 /*
+ * linux/fs/nfs/sysctl.c
+ */
+#ifdef CONFIG_SYSCTL
+extern int nfs_register_sysctl(void);
+extern void nfs_unregister_sysctl(void);
+#else
+#define nfs_register_sysctl() do { } while(0)
+#define nfs_unregister_sysctl() do { } while(0)
+#endif
+
+/*
  * linux/fs/nfs/unlink.c
  */
 extern int  nfs_async_unlink(struct dentry *);
@@ -405,10 +415,12 @@
 extern int  nfs_writepages(struct address_space *, struct writeback_control *);
 extern int  nfs_flush_incompatible(struct file *file, struct page *page);
 extern int  nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
-extern void nfs_writeback_done(struct rpc_task *task);
+extern void nfs_writeback_done(struct rpc_task *task, void *data);
+extern void nfs_writedata_release(void *data);
 
 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
-extern void nfs_commit_done(struct rpc_task *);
+extern void nfs_commit_done(struct rpc_task *, void *data);
+extern void nfs_commit_release(void *data);
 #endif
 
 /*
@@ -459,18 +471,33 @@
  */
 extern mempool_t *nfs_wdata_mempool;
 
-static inline struct nfs_write_data *nfs_writedata_alloc(void)
+static inline struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount)
 {
 	struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, SLAB_NOFS);
+
 	if (p) {
 		memset(p, 0, sizeof(*p));
 		INIT_LIST_HEAD(&p->pages);
+		if (pagecount < NFS_PAGEVEC_SIZE)
+			p->pagevec = &p->page_array[0];
+		else {
+			size_t size = ++pagecount * sizeof(struct page *);
+			p->pagevec = kmalloc(size, GFP_NOFS);
+			if (p->pagevec) {
+				memset(p->pagevec, 0, size);
+			} else {
+				mempool_free(p, nfs_wdata_mempool);
+				p = NULL;
+			}
+		}
 	}
 	return p;
 }
 
 static inline void nfs_writedata_free(struct nfs_write_data *p)
 {
+	if (p && (p->pagevec != &p->page_array[0]))
+		kfree(p->pagevec);
 	mempool_free(p, nfs_wdata_mempool);
 }
 
@@ -480,28 +507,45 @@
 extern int  nfs_readpage(struct file *, struct page *);
 extern int  nfs_readpages(struct file *, struct address_space *,
 		struct list_head *, unsigned);
-extern void nfs_readpage_result(struct rpc_task *);
+extern void nfs_readpage_result(struct rpc_task *, void *);
+extern void  nfs_readdata_release(void *data);
+
 
 /*
  * Allocate and free nfs_read_data structures
  */
 extern mempool_t *nfs_rdata_mempool;
 
-static inline struct nfs_read_data *nfs_readdata_alloc(void)
+static inline struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount)
 {
 	struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, SLAB_NOFS);
-	if (p)
+
+	if (p) {
 		memset(p, 0, sizeof(*p));
+		INIT_LIST_HEAD(&p->pages);
+		if (pagecount < NFS_PAGEVEC_SIZE)
+			p->pagevec = &p->page_array[0];
+		else {
+			size_t size = ++pagecount * sizeof(struct page *);
+			p->pagevec = kmalloc(size, GFP_NOFS);
+			if (p->pagevec) {
+				memset(p->pagevec, 0, size);
+			} else {
+				mempool_free(p, nfs_rdata_mempool);
+				p = NULL;
+			}
+		}
+	}
 	return p;
 }
 
 static inline void nfs_readdata_free(struct nfs_read_data *p)
 {
+	if (p && (p->pagevec != &p->page_array[0]))
+		kfree(p->pagevec);
 	mempool_free(p, nfs_rdata_mempool);
 }
 
-extern void  nfs_readdata_release(struct rpc_task *task);
-
 /*
  * linux/fs/nfs3proc.c
  */
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h
index a0f1f25..102e560 100644
--- a/include/linux/nfs_idmap.h
+++ b/include/linux/nfs_idmap.h
@@ -71,6 +71,8 @@
 int nfs_map_group_to_gid(struct nfs4_client *, const char *, size_t, __u32 *);
 int nfs_map_uid_to_name(struct nfs4_client *, __u32, char *);
 int nfs_map_gid_to_group(struct nfs4_client *, __u32, char *);
+
+extern unsigned int nfs_idmap_cache_timeout;
 #endif /* __KERNEL__ */
 
 #endif /* NFS_IDMAP_H */
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index da2e077b..66e2ed6 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -79,9 +79,7 @@
 static inline int
 nfs_lock_request_dontget(struct nfs_page *req)
 {
-	if (test_and_set_bit(PG_BUSY, &req->wb_flags))
-		return 0;
-	return 1;
+	return !test_and_set_bit(PG_BUSY, &req->wb_flags);
 }
 
 /*
@@ -125,9 +123,7 @@
 static inline int
 nfs_defer_commit(struct nfs_page *req)
 {
-	if (test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags))
-		return 0;
-	return 1;
+	return !test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags);
 }
 
 static inline void
@@ -141,9 +137,7 @@
 static inline int
 nfs_defer_reschedule(struct nfs_page *req)
 {
-	if (test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags))
-		return 0;
-	return 1;
+	return !test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags);
 }
 
 static inline void
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 4071866..6d6f69e 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -4,6 +4,16 @@
 #include <linux/sunrpc/xprt.h>
 #include <linux/nfsacl.h>
 
+/*
+ * To change the maximum rsize and wsize supported by the NFS client, adjust
+ * NFS_MAX_FILE_IO_SIZE.  64KB is a typical maximum, but some servers can
+ * support a megabyte or more.  The default is left at 4096 bytes, which is
+ * reasonable for NFS over UDP.
+ */
+#define NFS_MAX_FILE_IO_SIZE	(1048576U)
+#define NFS_DEF_FILE_IO_SIZE	(4096U)
+#define NFS_MIN_FILE_IO_SIZE	(1024U)
+
 struct nfs4_fsid {
 	__u64 major;
 	__u64 minor;
@@ -137,7 +147,7 @@
  */
 struct nfs_open_confirmargs {
 	const struct nfs_fh *	fh;
-	nfs4_stateid            stateid;
+	nfs4_stateid *		stateid;
 	struct nfs_seqid *	seqid;
 };
 
@@ -165,66 +175,62 @@
  *  * Arguments to the lock,lockt, and locku call.
  *   */
 struct nfs_lowner {
-	__u64           clientid;
-	u32                     id;
+	__u64			clientid;
+	u32			id;
 };
 
-struct nfs_lock_opargs {
+struct nfs_lock_args {
+	struct nfs_fh *		fh;
+	struct file_lock *	fl;
 	struct nfs_seqid *	lock_seqid;
 	nfs4_stateid *		lock_stateid;
 	struct nfs_seqid *	open_seqid;
 	nfs4_stateid *		open_stateid;
-	struct nfs_lowner       lock_owner;
-	__u32                   reclaim;
-	__u32                   new_lock_owner;
+	struct nfs_lowner	lock_owner;
+	unsigned char		block : 1;
+	unsigned char		reclaim : 1;
+	unsigned char		new_lock_owner : 1;
 };
 
-struct nfs_locku_opargs {
+struct nfs_lock_res {
+	nfs4_stateid			stateid;
+};
+
+struct nfs_locku_args {
+	struct nfs_fh *		fh;
+	struct file_lock *	fl;
 	struct nfs_seqid *	seqid;
 	nfs4_stateid *		stateid;
 };
 
-struct nfs_lockargs {
-	struct nfs_fh *         fh;
-	__u32                   type;
-	__u64                   offset; 
-	__u64                   length; 
-	union {
-		struct nfs_lock_opargs  *lock;    /* LOCK  */
-		struct nfs_lowner       *lockt;  /* LOCKT */
-		struct nfs_locku_opargs *locku;  /* LOCKU */
-	} u;
+struct nfs_locku_res {
+	nfs4_stateid			stateid;
 };
 
-struct nfs_lock_denied {
-	__u64                   offset;
-	__u64                   length;
-	__u32                   type;
-	struct nfs_lowner   	owner;
+struct nfs_lockt_args {
+	struct nfs_fh *		fh;
+	struct file_lock *	fl;
+	struct nfs_lowner	lock_owner;
 };
 
-struct nfs_lockres {
-	union {
-		nfs4_stateid            stateid;/* LOCK success, LOCKU */
-		struct nfs_lock_denied  denied; /* LOCK failed, LOCKT success */
-	} u;
-	const struct nfs_server *	server;
+struct nfs_lockt_res {
+	struct file_lock *	denied; /* LOCK, LOCKT failed */
 };
 
 struct nfs4_delegreturnargs {
 	const struct nfs_fh *fhandle;
 	const nfs4_stateid *stateid;
+	const u32 * bitmask;
+};
+
+struct nfs4_delegreturnres {
+	struct nfs_fattr * fattr;
+	const struct nfs_server *server;
 };
 
 /*
  * Arguments to the read call.
  */
-
-#define NFS_READ_MAXIOV		(9U)
-#if (NFS_READ_MAXIOV > (MAX_IOVEC -2))
-#error "NFS_READ_MAXIOV is too large"
-#endif
-
 struct nfs_readargs {
 	struct nfs_fh *		fh;
 	struct nfs_open_context *context;
@@ -243,11 +249,6 @@
 /*
  * Arguments to the write call.
  */
-#define NFS_WRITE_MAXIOV	(9U)
-#if (NFS_WRITE_MAXIOV > (MAX_IOVEC -2))
-#error "NFS_WRITE_MAXIOV is too large"
-#endif
-
 struct nfs_writeargs {
 	struct nfs_fh *		fh;
 	struct nfs_open_context *context;
@@ -678,6 +679,8 @@
 
 struct nfs_page;
 
+#define NFS_PAGEVEC_SIZE	(8U)
+
 struct nfs_read_data {
 	int			flags;
 	struct rpc_task		task;
@@ -686,13 +689,14 @@
 	struct nfs_fattr	fattr;	/* fattr storage */
 	struct list_head	pages;	/* Coalesced read requests */
 	struct nfs_page		*req;	/* multi ops per nfs_page */
-	struct page		*pagevec[NFS_READ_MAXIOV];
+	struct page		**pagevec;
 	struct nfs_readargs args;
 	struct nfs_readres  res;
 #ifdef CONFIG_NFS_V4
 	unsigned long		timestamp;	/* For lease renewal */
 #endif
 	void (*complete) (struct nfs_read_data *, int);
+	struct page		*page_array[NFS_PAGEVEC_SIZE + 1];
 };
 
 struct nfs_write_data {
@@ -704,13 +708,14 @@
 	struct nfs_writeverf	verf;
 	struct list_head	pages;		/* Coalesced requests we wish to flush */
 	struct nfs_page		*req;		/* multi ops per nfs_page */
-	struct page		*pagevec[NFS_WRITE_MAXIOV];
+	struct page		**pagevec;
 	struct nfs_writeargs	args;		/* argument struct */
 	struct nfs_writeres	res;		/* result struct */
 #ifdef CONFIG_NFS_V4
 	unsigned long		timestamp;	/* For lease renewal */
 #endif
 	void (*complete) (struct nfs_write_data *, int);
+	struct page		*page_array[NFS_PAGEVEC_SIZE + 1];
 };
 
 struct nfs_access_entry;
diff --git a/include/linux/nfsd/xdr.h b/include/linux/nfsd/xdr.h
index 130d4f5..3f4f714 100644
--- a/include/linux/nfsd/xdr.h
+++ b/include/linux/nfsd/xdr.h
@@ -88,10 +88,12 @@
 
 struct nfsd_attrstat {
 	struct svc_fh		fh;
+	struct kstat		stat;
 };
 
 struct nfsd_diropres  {
 	struct svc_fh		fh;
+	struct kstat		stat;
 };
 
 struct nfsd_readlinkres {
@@ -101,6 +103,7 @@
 struct nfsd_readres {
 	struct svc_fh		fh;
 	unsigned long		count;
+	struct kstat		stat;
 };
 
 struct nfsd_readdirres {
diff --git a/include/linux/nfsd/xdr3.h b/include/linux/nfsd/xdr3.h
index 3c2a71b..a432274 100644
--- a/include/linux/nfsd/xdr3.h
+++ b/include/linux/nfsd/xdr3.h
@@ -126,6 +126,7 @@
 struct nfsd3_attrstat {
 	__u32			status;
 	struct svc_fh		fh;
+	struct kstat            stat;
 };
 
 /* LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 343083fe..d52999c 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -79,13 +79,23 @@
 /*
  * Global page accounting.  One instance per CPU.  Only unsigned longs are
  * allowed.
+ *
+ * - Fields can be modified with xxx_page_state and xxx_page_state_zone at
+ * any time safely (which protects the instance from modification by
+ * interrupt.
+ * - The __xxx_page_state variants can be used safely when interrupts are
+ * disabled.
+ * - The __xxx_page_state variants can be used if the field is only
+ * modified from process context, or only modified from interrupt context.
+ * In this case, the field should be commented here.
  */
 struct page_state {
 	unsigned long nr_dirty;		/* Dirty writeable pages */
 	unsigned long nr_writeback;	/* Pages under writeback */
 	unsigned long nr_unstable;	/* NFS unstable pages */
 	unsigned long nr_page_table_pages;/* Pages used for pagetables */
-	unsigned long nr_mapped;	/* mapped into pagetables */
+	unsigned long nr_mapped;	/* mapped into pagetables.
+					 * only modified from process context */
 	unsigned long nr_slab;		/* In slab */
 #define GET_PAGE_STATE_LAST nr_slab
 
@@ -97,32 +107,40 @@
 	unsigned long pgpgout;		/* Disk writes */
 	unsigned long pswpin;		/* swap reads */
 	unsigned long pswpout;		/* swap writes */
-	unsigned long pgalloc_high;	/* page allocations */
 
+	unsigned long pgalloc_high;	/* page allocations */
 	unsigned long pgalloc_normal;
+	unsigned long pgalloc_dma32;
 	unsigned long pgalloc_dma;
+
 	unsigned long pgfree;		/* page freeings */
 	unsigned long pgactivate;	/* pages moved inactive->active */
 	unsigned long pgdeactivate;	/* pages moved active->inactive */
 
 	unsigned long pgfault;		/* faults (major+minor) */
 	unsigned long pgmajfault;	/* faults (major only) */
+
 	unsigned long pgrefill_high;	/* inspected in refill_inactive_zone */
 	unsigned long pgrefill_normal;
+	unsigned long pgrefill_dma32;
 	unsigned long pgrefill_dma;
 
 	unsigned long pgsteal_high;	/* total highmem pages reclaimed */
 	unsigned long pgsteal_normal;
+	unsigned long pgsteal_dma32;
 	unsigned long pgsteal_dma;
+
 	unsigned long pgscan_kswapd_high;/* total highmem pages scanned */
 	unsigned long pgscan_kswapd_normal;
-
+	unsigned long pgscan_kswapd_dma32;
 	unsigned long pgscan_kswapd_dma;
+
 	unsigned long pgscan_direct_high;/* total highmem pages scanned */
 	unsigned long pgscan_direct_normal;
+	unsigned long pgscan_direct_dma32;
 	unsigned long pgscan_direct_dma;
-	unsigned long pginodesteal;	/* pages reclaimed via inode freeing */
 
+	unsigned long pginodesteal;	/* pages reclaimed via inode freeing */
 	unsigned long slabs_scanned;	/* slab objects scanned */
 	unsigned long kswapd_steal;	/* pages reclaimed by kswapd */
 	unsigned long kswapd_inodesteal;/* reclaimed via kswapd inode freeing */
@@ -136,31 +154,54 @@
 extern void get_page_state(struct page_state *ret);
 extern void get_page_state_node(struct page_state *ret, int node);
 extern void get_full_page_state(struct page_state *ret);
-extern unsigned long __read_page_state(unsigned long offset);
-extern void __mod_page_state(unsigned long offset, unsigned long delta);
+extern unsigned long read_page_state_offset(unsigned long offset);
+extern void mod_page_state_offset(unsigned long offset, unsigned long delta);
+extern void __mod_page_state_offset(unsigned long offset, unsigned long delta);
 
 #define read_page_state(member) \
-	__read_page_state(offsetof(struct page_state, member))
+	read_page_state_offset(offsetof(struct page_state, member))
 
 #define mod_page_state(member, delta)	\
-	__mod_page_state(offsetof(struct page_state, member), (delta))
+	mod_page_state_offset(offsetof(struct page_state, member), (delta))
 
-#define inc_page_state(member)	mod_page_state(member, 1UL)
-#define dec_page_state(member)	mod_page_state(member, 0UL - 1)
-#define add_page_state(member,delta) mod_page_state(member, (delta))
-#define sub_page_state(member,delta) mod_page_state(member, 0UL - (delta))
+#define __mod_page_state(member, delta)	\
+	__mod_page_state_offset(offsetof(struct page_state, member), (delta))
 
-#define mod_page_state_zone(zone, member, delta)				\
-	do {									\
-		unsigned offset;						\
-		if (is_highmem(zone))						\
-			offset = offsetof(struct page_state, member##_high);	\
-		else if (is_normal(zone))					\
-			offset = offsetof(struct page_state, member##_normal);	\
-		else								\
-			offset = offsetof(struct page_state, member##_dma);	\
-		__mod_page_state(offset, (delta));				\
-	} while (0)
+#define inc_page_state(member)		mod_page_state(member, 1UL)
+#define dec_page_state(member)		mod_page_state(member, 0UL - 1)
+#define add_page_state(member,delta)	mod_page_state(member, (delta))
+#define sub_page_state(member,delta)	mod_page_state(member, 0UL - (delta))
+
+#define __inc_page_state(member)	__mod_page_state(member, 1UL)
+#define __dec_page_state(member)	__mod_page_state(member, 0UL - 1)
+#define __add_page_state(member,delta)	__mod_page_state(member, (delta))
+#define __sub_page_state(member,delta)	__mod_page_state(member, 0UL - (delta))
+
+#define page_state(member) (*__page_state(offsetof(struct page_state, member)))
+
+#define state_zone_offset(zone, member)					\
+({									\
+	unsigned offset;						\
+	if (is_highmem(zone))						\
+		offset = offsetof(struct page_state, member##_high);	\
+	else if (is_normal(zone))					\
+		offset = offsetof(struct page_state, member##_normal);	\
+	else if (is_dma32(zone))					\
+		offset = offsetof(struct page_state, member##_dma32);	\
+	else								\
+		offset = offsetof(struct page_state, member##_dma);	\
+	offset;								\
+})
+
+#define __mod_page_state_zone(zone, member, delta)			\
+ do {									\
+	__mod_page_state_offset(state_zone_offset(zone, member), (delta)); \
+ } while (0)
+
+#define mod_page_state_zone(zone, member, delta)			\
+ do {									\
+	mod_page_state_offset(state_zone_offset(zone, member), (delta)); \
+ } while (0)
 
 /*
  * Manipulation of page state flags
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index def32c5..8eb7fa7 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -5,6 +5,9 @@
  * pages.  A pagevec is a multipage container which is used for that.
  */
 
+#ifndef _LINUX_PAGEVEC_H
+#define _LINUX_PAGEVEC_H
+
 /* 14 pointers + two long's align the pagevec structure to a power of two */
 #define PAGEVEC_SIZE	14
 
@@ -83,3 +86,5 @@
 	if (pagevec_count(pvec))
 		__pagevec_lru_add(pvec);
 }
+
+#endif /* _LINUX_PAGEVEC_H */
diff --git a/include/linux/parport.h b/include/linux/parport.h
index d2a4d9e..f67f838 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -236,7 +236,8 @@
 
 /* IEEE1284 information */
 
-/* IEEE1284 phases */
+/* IEEE1284 phases. These are exposed to userland through ppdev IOCTL
+ * PP[GS]ETPHASE, so do not change existing values. */
 enum ieee1284_phase {
 	IEEE1284_PH_FWD_DATA,
 	IEEE1284_PH_FWD_IDLE,
diff --git a/include/linux/parport_pc.h b/include/linux/parport_pc.h
index 7825c76..1cc0f6b 100644
--- a/include/linux/parport_pc.h
+++ b/include/linux/parport_pc.h
@@ -79,14 +79,14 @@
 }
 
 #ifdef DEBUG_PARPORT
-extern __inline__ void dump_parport_state (char *str, struct parport *p)
+static inline void dump_parport_state (char *str, struct parport *p)
 {
 	/* here's hoping that reading these ports won't side-effect anything underneath */
 	unsigned char ecr = inb (ECONTROL (p));
 	unsigned char dcr = inb (CONTROL (p));
 	unsigned char dsr = inb (STATUS (p));
-	static char *ecr_modes[] = {"SPP", "PS2", "PPFIFO", "ECP", "xXx", "yYy", "TST", "CFG"};
-	const struct parport_pc_private *priv = (parport_pc_private *)p->physport->private_data;
+	static const char *const ecr_modes[] = {"SPP", "PS2", "PPFIFO", "ECP", "xXx", "yYy", "TST", "CFG"};
+	const struct parport_pc_private *priv = p->physport->private_data;
 	int i;
 
 	printk (KERN_DEBUG "*** parport state (%s): ecr=[%s", str, ecr_modes[(ecr & 0xe0) >> 5]);
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 1e737e2..c3caa93 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -15,6 +15,7 @@
 #define PCI_CLASS_STORAGE_FLOPPY	0x0102
 #define PCI_CLASS_STORAGE_IPI		0x0103
 #define PCI_CLASS_STORAGE_RAID		0x0104
+#define PCI_CLASS_STORAGE_SAS		0x0107
 #define PCI_CLASS_STORAGE_OTHER		0x0180
 
 #define PCI_BASE_CLASS_NETWORK		0x02
@@ -376,6 +377,10 @@
 #define PCI_DEVICE_ID_NS_87560_USB	0x0012
 #define PCI_DEVICE_ID_NS_83815		0x0020
 #define PCI_DEVICE_ID_NS_83820		0x0022
+#define PCI_DEVICE_ID_NS_CS5535_IDE	0x002d
+#define PCI_DEVICE_ID_NS_CS5535_AUDIO	0x002e
+#define PCI_DEVICE_ID_NS_CS5535_USB	0x002f
+#define PCI_DEVICE_ID_NS_CS5535_VIDEO	0x0030
 #define PCI_DEVICE_ID_NS_SATURN		0x0035
 #define PCI_DEVICE_ID_NS_SCx200_BRIDGE	0x0500
 #define PCI_DEVICE_ID_NS_SCx200_SMI	0x0501
@@ -389,6 +394,13 @@
 #define PCI_DEVICE_ID_NS_87410		0xd001
 #define PCI_DEVICE_ID_NS_CS5535_IDE	0x002d
 
+#define PCI_DEVICE_ID_NS_CS5535_HOST_BRIDGE  0x0028
+#define PCI_DEVICE_ID_NS_CS5535_ISA_BRIDGE   0x002b
+#define PCI_DEVICE_ID_NS_CS5535_IDE          0x002d
+#define PCI_DEVICE_ID_NS_CS5535_AUDIO        0x002e
+#define PCI_DEVICE_ID_NS_CS5535_USB          0x002f
+#define PCI_DEVICE_ID_NS_CS5535_VIDEO        0x0030
+
 #define PCI_VENDOR_ID_TSENG		0x100c
 #define PCI_DEVICE_ID_TSENG_W32P_2	0x3202
 #define PCI_DEVICE_ID_TSENG_W32P_b	0x3205
@@ -491,6 +503,9 @@
 
 #define PCI_DEVICE_ID_AMD_CS5536_IDE	0x209A
 
+#define PCI_DEVICE_ID_AMD_LX_VIDEO  0x2081
+#define PCI_DEVICE_ID_AMD_LX_AES    0x2082
+
 #define PCI_VENDOR_ID_TRIDENT		0x1023
 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX	0x2000
 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX	0x2001
@@ -971,6 +986,7 @@
 #define PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN        0x002a
 #define PCI_DEVICE_ID_NVIDIA_VTNT2		0x002C
 #define PCI_DEVICE_ID_NVIDIA_UVTNT2		0x002D
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS	0x0034
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE	0x0035
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA	0x0036
 #define PCI_DEVICE_ID_NVIDIA_NVENET_10		0x0037
@@ -1244,6 +1260,7 @@
 #define PCI_DEVICE_ID_VIA_8378_0	0x3205
 #define PCI_DEVICE_ID_VIA_8783_0	0x3208
 #define PCI_DEVICE_ID_VIA_8237		0x3227
+#define PCI_DEVICE_ID_VIA_8251		0x3287
 #define PCI_DEVICE_ID_VIA_3296_0	0x0296
 #define PCI_DEVICE_ID_VIA_8231		0x8231
 #define PCI_DEVICE_ID_VIA_8231_4	0x8235
@@ -1566,6 +1583,23 @@
 #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6	0x0009
 #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1	0x000A
 #define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1	0x000B
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ		0x000C
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_PTM		0x000D
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_NT960PCI		0x0100
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2		0x0201
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4		0x0202
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232	0x0300
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232	0x0301
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232	0x0302
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1	0x0310
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2	0x0311
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4	0x0312
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2	0x0320
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4	0x0321
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8	0x0322
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485	0x0330
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485	0x0331
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485	0x0332
 
 
 #define PCI_VENDOR_ID_NVIDIA_SGS	0x12d2
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index fb8d2d2..cb9039a 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -19,7 +19,6 @@
 
 struct percpu_data {
 	void *ptrs[NR_CPUS];
-	void *blkp;
 };
 
 /* 
@@ -33,14 +32,14 @@
         (__typeof__(ptr))__p->ptrs[(cpu)];	\
 })
 
-extern void *__alloc_percpu(size_t size, size_t align);
+extern void *__alloc_percpu(size_t size);
 extern void free_percpu(const void *);
 
 #else /* CONFIG_SMP */
 
 #define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
 
-static inline void *__alloc_percpu(size_t size, size_t align)
+static inline void *__alloc_percpu(size_t size)
 {
 	void *ret = kmalloc(size, GFP_KERNEL);
 	if (ret)
@@ -55,7 +54,6 @@
 #endif /* CONFIG_SMP */
 
 /* Simple wrapper for the common case: zeros memory. */
-#define alloc_percpu(type) \
-	((type *)(__alloc_percpu(sizeof(type), __alignof__(type))))
+#define alloc_percpu(type)	((type *)(__alloc_percpu(sizeof(type))))
 
 #endif /* __LINUX_PERCPU_H */
diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h
index 7240667..6351c40 100644
--- a/include/linux/pfkeyv2.h
+++ b/include/linux/pfkeyv2.h
@@ -216,6 +216,16 @@
 } __attribute__((packed));
 /* sizeof(struct sadb_x_nat_t_port) == 8 */
 
+/* Generic LSM security context */
+struct sadb_x_sec_ctx {
+	uint16_t	sadb_x_sec_len;
+	uint16_t	sadb_x_sec_exttype;
+	uint8_t		sadb_x_ctx_alg;  /* LSMs: e.g., selinux == 1 */
+	uint8_t		sadb_x_ctx_doi;
+	uint16_t	sadb_x_ctx_len;
+} __attribute__((packed));
+/* sizeof(struct sadb_sec_ctx) = 8 */
+
 /* Message types */
 #define SADB_RESERVED		0
 #define SADB_GETSPI		1
@@ -325,7 +335,8 @@
 #define SADB_X_EXT_NAT_T_SPORT		21
 #define SADB_X_EXT_NAT_T_DPORT		22
 #define SADB_X_EXT_NAT_T_OA		23
-#define SADB_EXT_MAX			23
+#define SADB_X_EXT_SEC_CTX		24
+#define SADB_EXT_MAX			24
 
 /* Identity Extension values */
 #define SADB_IDENTTYPE_RESERVED	0
diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
index e87b233..d10f353 100644
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -429,6 +429,7 @@
 	TCA_NETEM_CORR,
 	TCA_NETEM_DELAY_DIST,
 	TCA_NETEM_REORDER,
+	TCA_NETEM_CORRUPT,
 	__TCA_NETEM_MAX,
 };
 
@@ -457,6 +458,12 @@
 	__u32	correlation;
 };
 
+struct tc_netem_corrupt
+{
+	__u32	probability;
+	__u32	correlation;
+};
+
 #define NETEM_DIST_SCALE	8192
 
 #endif
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 17e336f..782090c 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -41,6 +41,7 @@
 extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
 extern int platform_device_add_data(struct platform_device *pdev, void *data, size_t size);
 extern int platform_device_add(struct platform_device *pdev);
+extern void platform_device_del(struct platform_device *pdev);
 extern void platform_device_put(struct platform_device *pdev);
 
 struct platform_driver {
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index 584d57c..93b0959 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -162,6 +162,7 @@
 	struct pnp_card * card;
 	struct pnp_card_driver * driver;
 	void * driver_data;
+	pm_message_t pm_state;
 };
 
 static inline void *pnp_get_card_drvdata (struct pnp_card_link *pcard)
@@ -294,6 +295,8 @@
 	unsigned int flags;
 	int  (*probe)  (struct pnp_dev *dev, const struct pnp_device_id *dev_id);
 	void (*remove) (struct pnp_dev *dev);
+	int  (*suspend) (struct pnp_dev *dev, pm_message_t state);
+	int  (*resume) (struct pnp_dev *dev);
 	struct device_driver driver;
 };
 
@@ -306,6 +309,8 @@
 	unsigned int flags;
 	int  (*probe)  (struct pnp_card_link *card, const struct pnp_card_device_id *card_id);
 	void (*remove) (struct pnp_card_link *card);
+	int  (*suspend) (struct pnp_card_link *card, pm_message_t state);
+	int  (*resume) (struct pnp_card_link *card);
 	struct pnp_driver link;
 };
 
@@ -380,6 +385,8 @@
 int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode);
 int pnp_auto_config_dev(struct pnp_dev *dev);
 int pnp_validate_config(struct pnp_dev *dev);
+int pnp_start_dev(struct pnp_dev *dev);
+int pnp_stop_dev(struct pnp_dev *dev);
 int pnp_activate_dev(struct pnp_dev *dev);
 int pnp_disable_dev(struct pnp_dev *dev);
 void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size);
@@ -423,6 +430,8 @@
 static inline int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode) { return -ENODEV; }
 static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_validate_config(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_start_dev(struct pnp_dev *dev) { return -ENODEV; }
+static inline int pnp_stop_dev(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_activate_dev(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_disable_dev(struct pnp_dev *dev) { return -ENODEV; }
 static inline void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) { }
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index d9a2f52..5769d14 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -48,6 +48,7 @@
 #define preempt_enable() \
 do { \
 	preempt_enable_no_resched(); \
+	barrier(); \
 	preempt_check_resched(); \
 } while (0)
 
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index b2b3dba..9d5cd10 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -20,8 +20,6 @@
 #define PTRACE_DETACH		0x11
 
 #define PTRACE_SYSCALL		  24
-#define PTRACE_SYSEMU		  31
-#define PTRACE_SYSEMU_SINGLESTEP  32
 
 /* 0x4200-0x4300 are reserved for architecture-independent additions.  */
 #define PTRACE_SETOPTIONS	0x4200
@@ -80,6 +78,8 @@
 
 
 extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
+extern struct task_struct *ptrace_get_task_struct(pid_t pid);
+extern int ptrace_traceme(void);
 extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
 extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
 extern int ptrace_attach(struct task_struct *tsk);
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 36e5d26..c57ff2f 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -19,6 +19,7 @@
 #ifndef _LINUX_RADIX_TREE_H
 #define _LINUX_RADIX_TREE_H
 
+#include <linux/sched.h>
 #include <linux/preempt.h>
 #include <linux/types.h>
 
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index 13e7c4b..b6e0bca 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -71,8 +71,8 @@
  */
 #define MD_PATCHLEVEL_VERSION           3
 
-extern int register_md_personality (int p_num, mdk_personality_t *p);
-extern int unregister_md_personality (int p_num);
+extern int register_md_personality (struct mdk_personality *p);
+extern int unregister_md_personality (struct mdk_personality *p);
 extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev),
 				mddev_t *mddev, const char *name);
 extern void md_unregister_thread (mdk_thread_t *thread);
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 46629a2..617b950 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -18,62 +18,19 @@
 /* and dm-bio-list.h is not under include/linux because.... ??? */
 #include "../../../drivers/md/dm-bio-list.h"
 
-#define MD_RESERVED       0UL
-#define LINEAR            1UL
-#define RAID0             2UL
-#define RAID1             3UL
-#define RAID5             4UL
-#define TRANSLUCENT       5UL
-#define HSM               6UL
-#define MULTIPATH         7UL
-#define RAID6		  8UL
-#define	RAID10		  9UL
-#define FAULTY		  10UL
-#define MAX_PERSONALITY   11UL
-
 #define	LEVEL_MULTIPATH		(-4)
 #define	LEVEL_LINEAR		(-1)
 #define	LEVEL_FAULTY		(-5)
 
+/* we need a value for 'no level specified' and 0
+ * means 'raid0', so we need something else.  This is
+ * for internal use only
+ */
+#define	LEVEL_NONE		(-1000000)
+
 #define MaxSector (~(sector_t)0)
 #define MD_THREAD_NAME_MAX 14
 
-static inline int pers_to_level (int pers)
-{
-	switch (pers) {
-		case FAULTY:		return LEVEL_FAULTY;
-		case MULTIPATH:		return LEVEL_MULTIPATH;
-		case HSM:		return -3;
-		case TRANSLUCENT:	return -2;
-		case LINEAR:		return LEVEL_LINEAR;
-		case RAID0:		return 0;
-		case RAID1:		return 1;
-		case RAID5:		return 5;
-		case RAID6:		return 6;
-		case RAID10:		return 10;
-	}
-	BUG();
-	return MD_RESERVED;
-}
-
-static inline int level_to_pers (int level)
-{
-	switch (level) {
-		case LEVEL_FAULTY: return FAULTY;
-		case LEVEL_MULTIPATH: return MULTIPATH;
-		case -3: return HSM;
-		case -2: return TRANSLUCENT;
-		case LEVEL_LINEAR: return LINEAR;
-		case 0: return RAID0;
-		case 1: return RAID1;
-		case 4:
-		case 5: return RAID5;
-		case 6: return RAID6;
-		case 10: return RAID10;
-	}
-	return MD_RESERVED;
-}
-
 typedef struct mddev_s mddev_t;
 typedef struct mdk_rdev_s mdk_rdev_t;
 
@@ -138,14 +95,16 @@
 	atomic_t	read_errors;	/* number of consecutive read errors that
 					 * we have tried to ignore.
 					 */
+	atomic_t	corrected_errors; /* number of corrected read errors,
+					   * for reporting to userspace and storing
+					   * in superblock.
+					   */
 };
 
-typedef struct mdk_personality_s mdk_personality_t;
-
 struct mddev_s
 {
 	void				*private;
-	mdk_personality_t		*pers;
+	struct mdk_personality		*pers;
 	dev_t				unit;
 	int				md_minor;
 	struct list_head 		disks;
@@ -164,6 +123,7 @@
 	int				chunk_size;
 	time_t				ctime, utime;
 	int				level, layout;
+	char				clevel[16];
 	int				raid_disks;
 	int				max_disks;
 	sector_t			size; /* used size of component devices */
@@ -183,6 +143,11 @@
 	sector_t			resync_mismatches; /* count of sectors where
 							    * parity/replica mismatch found
 							    */
+	/* if zero, use the system-wide default */
+	int				sync_speed_min;
+	int				sync_speed_max;
+
+	int				ok_start_degraded;
 	/* recovery/resync flags 
 	 * NEEDED:   we might need to start a resync/recover
 	 * RUNNING:  a thread is running, or about to be started
@@ -265,9 +230,11 @@
         atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
 }
 
-struct mdk_personality_s
+struct mdk_personality
 {
 	char *name;
+	int level;
+	struct list_head list;
 	struct module *owner;
 	int (*make_request)(request_queue_t *q, struct bio *bio);
 	int (*run)(mddev_t *mddev);
@@ -305,8 +272,6 @@
 	return mddev->gendisk ? mddev->gendisk->disk_name : "mdX";
 }
 
-extern mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr);
-
 /*
  * iterates through some rdev ringlist. It's safe to remove the
  * current 'rdev'. Dont touch 'tmp' though.
@@ -366,5 +331,10 @@
 	__wait_event_lock_irq(wq, condition, lock, cmd);		\
 } while (0)
 
+static inline void safe_put_page(struct page *p)
+{
+	if (p) put_page(p);
+}
+
 #endif
 
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index 292b98f..9d5494a 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -45,6 +45,8 @@
 
 	spinlock_t		resync_lock;
 	int			nr_pending;
+	int			nr_waiting;
+	int			nr_queued;
 	int			barrier;
 	sector_t		next_resync;
 	int			fullsync;  /* set to 1 if a full sync is needed,
@@ -52,11 +54,12 @@
 					    * Cleared when a sync completes.
 					    */
 
-	wait_queue_head_t	wait_idle;
-	wait_queue_head_t	wait_resume;
+	wait_queue_head_t	wait_barrier;
 
 	struct pool_info	*poolinfo;
 
+	struct page		*tmppage;
+
 	mempool_t *r1bio_pool;
 	mempool_t *r1buf_pool;
 };
@@ -106,6 +109,13 @@
 	/* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/
 };
 
+/* when we get a read error on a read-only array, we redirect to another
+ * device without failing the first device, or trying to over-write to
+ * correct the read error.  To keep track of bad blocks on a per-bio
+ * level, we store IO_BLOCKED in the appropriate 'bios' pointer
+ */
+#define IO_BLOCKED ((struct bio*)1)
+
 /* bits for r1bio.state */
 #define	R1BIO_Uptodate	0
 #define	R1BIO_IsSync	1
diff --git a/include/linux/raid/raid10.h b/include/linux/raid/raid10.h
index 6070878..b110329 100644
--- a/include/linux/raid/raid10.h
+++ b/include/linux/raid/raid10.h
@@ -35,18 +35,26 @@
 	sector_t chunk_mask;
 
 	struct list_head	retry_list;
-	/* for use when syncing mirrors: */
+	/* queue pending writes and submit them on unplug */
+	struct bio_list		pending_bio_list;
+
 
 	spinlock_t		resync_lock;
 	int nr_pending;
+	int nr_waiting;
+	int nr_queued;
 	int barrier;
 	sector_t		next_resync;
+	int			fullsync;  /* set to 1 if a full sync is needed,
+					    * (fresh device added).
+					    * Cleared when a sync completes.
+					    */
 
-	wait_queue_head_t	wait_idle;
-	wait_queue_head_t	wait_resume;
+	wait_queue_head_t	wait_barrier;
 
 	mempool_t *r10bio_pool;
 	mempool_t *r10buf_pool;
+	struct page		*tmppage;
 };
 
 typedef struct r10_private_data_s conf_t;
@@ -96,8 +104,16 @@
 	} devs[0];
 };
 
+/* when we get a read error on a read-only array, we redirect to another
+ * device without failing the first device, or trying to over-write to
+ * correct the read error.  To keep track of bad blocks on a per-bio
+ * level, we store IO_BLOCKED in the appropriate 'bios' pointer
+ */
+#define IO_BLOCKED ((struct bio*)1)
+
 /* bits for r10bio.state */
 #define	R10BIO_Uptodate	0
 #define	R10BIO_IsSync	1
 #define	R10BIO_IsRecover 2
+#define	R10BIO_Degraded 3
 #endif
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
index f025ba6..394da82 100644
--- a/include/linux/raid/raid5.h
+++ b/include/linux/raid/raid5.h
@@ -126,7 +126,7 @@
  */
 
 struct stripe_head {
-	struct stripe_head	*hash_next, **hash_pprev; /* hash pointers */
+	struct hlist_node	hash;
 	struct list_head	lru;			/* inactive_list or handle_list */
 	struct raid5_private_data	*raid_conf;
 	sector_t		sector;			/* sector of this row */
@@ -152,7 +152,6 @@
 #define	R5_Insync	3	/* rdev && rdev->in_sync at start */
 #define	R5_Wantread	4	/* want to schedule a read */
 #define	R5_Wantwrite	5
-#define	R5_Syncio	6	/* this io need to be accounted as resync io */
 #define	R5_Overlap	7	/* There is a pending overlapping request on this block */
 #define	R5_ReadError	8	/* seen a read error here recently */
 #define	R5_ReWrite	9	/* have tried to over-write the readerror */
@@ -205,7 +204,7 @@
 };
 
 struct raid5_private_data {
-	struct stripe_head	**stripe_hashtbl;
+	struct hlist_head	*stripe_hashtbl;
 	mddev_t			*mddev;
 	struct disk_info	*spare;
 	int			chunk_size, level, algorithm;
@@ -228,6 +227,8 @@
 					    * Cleared when a sync completes.
 					    */
 
+	struct page 		*spare_page; /* Used when checking P/Q in raid6 */
+
 	/*
 	 * Free stripes pool
 	 */
diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h
index e0a4faa..953b6df 100644
--- a/include/linux/ramfs.h
+++ b/include/linux/ramfs.h
@@ -5,6 +5,16 @@
 struct super_block *ramfs_get_sb(struct file_system_type *fs_type,
 	 int flags, const char *dev_name, void *data);
 
+#ifndef CONFIG_MMU
+extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file,
+						   unsigned long addr,
+						   unsigned long len,
+						   unsigned long pgoff,
+						   unsigned long flags);
+
+extern int ramfs_nommu_mmap(struct file *file, struct vm_area_struct *vma);
+#endif
+
 extern struct file_operations ramfs_file_operations;
 extern struct vm_operations_struct generic_file_vm_ops;
 
diff --git a/include/linux/random.h b/include/linux/random.h
index 7b2adb3..5d6456b 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -52,9 +52,9 @@
 void generate_random_uuid(unsigned char uuid_out[16]);
 
 extern __u32 secure_ip_id(__u32 daddr);
-extern u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport);
-extern u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, 
-				       __u16 dport);
+extern u32 secure_ipv4_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport);
+extern u32 secure_ipv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, 
+				      __u16 dport);
 extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
 					__u16 sport, __u16 dport);
 extern __u32 secure_tcpv6_sequence_number(__u32 *saddr, __u32 *daddr,
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index cce2559..51747cd 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -65,7 +65,7 @@
 	long	cur;		/* Current batch number.                      */
 	long	completed;	/* Number of the last completed batch         */
 	int	next_pending;	/* Is the next batch already waiting?         */
-} ____cacheline_maxaligned_in_smp;
+} ____cacheline_internodealigned_in_smp;
 
 /* Is batch a before batch b ? */
 static inline int rcu_batch_before(long a, long b)
@@ -100,6 +100,7 @@
 	struct rcu_head *donelist;
 	struct rcu_head **donetail;
 	int cpu;
+	struct rcu_head barrier;
 };
 
 DECLARE_PER_CPU(struct rcu_data, rcu_data);
@@ -285,6 +286,7 @@
 extern __deprecated_for_modules void synchronize_kernel(void);
 extern void synchronize_rcu(void);
 void synchronize_idle(void);
+extern void rcu_barrier(void);
 
 #endif /* __KERNEL__ */
 #endif /* __LINUX_RCUPDATE_H */
diff --git a/include/linux/rcuref.h b/include/linux/rcuref.h
deleted file mode 100644
index e1adbba..0000000
--- a/include/linux/rcuref.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * rcuref.h
- *
- * Reference counting for elements of lists/arrays protected by
- * RCU.
- *
- * 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, 2005
- *
- * Author: Dipankar Sarma <dipankar@in.ibm.com>
- *	   Ravikiran Thirumalai <kiran_th@gmail.com>
- *
- * See Documentation/RCU/rcuref.txt for detailed user guide.
- *
- */
-
-#ifndef _RCUREF_H_
-#define _RCUREF_H_
-
-#ifdef __KERNEL__
-
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <asm/atomic.h>
-
-/*
- * These APIs work on traditional atomic_t counters used in the
- * kernel for reference counting. Under special circumstances
- * where a lock-free get() operation races with a put() operation
- * these APIs can be used. See Documentation/RCU/rcuref.txt.
- */
-
-#ifdef __HAVE_ARCH_CMPXCHG
-
-/**
- * rcuref_inc - increment refcount for object.
- * @rcuref: reference counter in the object in question.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference
- * in a lock-free reader-side critical section.
- */
-static inline void rcuref_inc(atomic_t *rcuref)
-{
-	atomic_inc(rcuref);
-}
-
-/**
- * rcuref_dec - decrement refcount for object.
- * @rcuref: reference counter in the object in question.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference
- * in a lock-free reader-side critical section.
- */
-static inline void rcuref_dec(atomic_t *rcuref)
-{
-	atomic_dec(rcuref);
-}
-
-/**
- * rcuref_dec_and_test - decrement refcount for object and test
- * @rcuref: reference counter in the object.
- * @release: pointer to the function that will clean up the object
- *	     when the last reference to the object is released.
- *	     This pointer is required.
- *
- * Decrement the refcount, and if 0, return 1. Else return 0.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference
- * in a lock-free reader-side critical section.
- */
-static inline int rcuref_dec_and_test(atomic_t *rcuref)
-{
-	return atomic_dec_and_test(rcuref);
-}
-
-/*
- * cmpxchg is needed on UP too, if deletions to the list/array can happen
- * in interrupt context.
- */
-
-/**
- * rcuref_inc_lf - Take reference to an object in a read-side
- * critical section protected by RCU.
- * @rcuref: reference counter in the object in question.
- *
- * Try and increment the refcount by 1.  The increment might fail if
- * the reference counter has been through a 1 to 0 transition and
- * is no longer part of the lock-free list.
- * Returns non-zero on successful increment and zero otherwise.
- */
-static inline int rcuref_inc_lf(atomic_t *rcuref)
-{
-	int c, old;
-	c = atomic_read(rcuref);
-	while (c && (old = cmpxchg(&rcuref->counter, c, c + 1)) != c)
-		c = old;
-	return c;
-}
-
-#else				/* !__HAVE_ARCH_CMPXCHG */
-
-extern spinlock_t __rcuref_hash[];
-
-/*
- * Use a hash table of locks to protect the reference count
- * since cmpxchg is not available in this arch.
- */
-#ifdef	CONFIG_SMP
-#define RCUREF_HASH_SIZE	4
-#define RCUREF_HASH(k) \
-	(&__rcuref_hash[(((unsigned long)k)>>8) & (RCUREF_HASH_SIZE-1)])
-#else
-#define	RCUREF_HASH_SIZE	1
-#define RCUREF_HASH(k) 	&__rcuref_hash[0]
-#endif				/* CONFIG_SMP */
-
-/**
- * rcuref_inc - increment refcount for object.
- * @rcuref: reference counter in the object in question.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference in a lock-free
- * reader-side critical section.
- */
-static inline void rcuref_inc(atomic_t *rcuref)
-{
-	unsigned long flags;
-	spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
-	rcuref->counter += 1;
-	spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
-}
-
-/**
- * rcuref_dec - decrement refcount for object.
- * @rcuref: reference counter in the object in question.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference in a lock-free
- * reader-side critical section.
- */
-static inline void rcuref_dec(atomic_t *rcuref)
-{
-	unsigned long flags;
-	spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
-	rcuref->counter -= 1;
-	spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
-}
-
-/**
- * rcuref_dec_and_test - decrement refcount for object and test
- * @rcuref: reference counter in the object.
- * @release: pointer to the function that will clean up the object
- *	     when the last reference to the object is released.
- *	     This pointer is required.
- *
- * Decrement the refcount, and if 0, return 1. Else return 0.
- *
- * This should be used only for objects where we use RCU and
- * use the rcuref_inc_lf() api to acquire a reference in a lock-free
- * reader-side critical section.
- */
-static inline int rcuref_dec_and_test(atomic_t *rcuref)
-{
-	unsigned long flags;
-	spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
-	rcuref->counter--;
-	if (!rcuref->counter) {
-		spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
-		return 1;
-	} else {
-		spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
-		return 0;
-	}
-}
-
-/**
- * rcuref_inc_lf - Take reference to an object of a lock-free collection
- * by traversing a lock-free list/array.
- * @rcuref: reference counter in the object in question.
- *
- * Try and increment the refcount by 1.  The increment might fail if
- * the reference counter has been through a 1 to 0 transition and
- * object is no longer part of the lock-free list.
- * Returns non-zero on successful increment and zero otherwise.
- */
-static inline int rcuref_inc_lf(atomic_t *rcuref)
-{
-	int ret;
-	unsigned long flags;
-	spin_lock_irqsave(RCUREF_HASH(rcuref), flags);
-	if (rcuref->counter)
-		ret = rcuref->counter++;
-	else
-		ret = 0;
-	spin_unlock_irqrestore(RCUREF_HASH(rcuref), flags);
-	return ret;
-}
-
-
-#endif /* !__HAVE_ARCH_CMPXCHG */
-
-#endif /* __KERNEL__ */
-#endif /* _RCUREF_H_ */
diff --git a/include/linux/relayfs_fs.h b/include/linux/relayfs_fs.h
index cfafc3e..7342e66 100644
--- a/include/linux/relayfs_fs.h
+++ b/include/linux/relayfs_fs.h
@@ -20,9 +20,9 @@
 #include <linux/kref.h>
 
 /*
- * Tracks changes to rchan_buf struct
+ * Tracks changes to rchan/rchan_buf structs
  */
-#define RELAYFS_CHANNEL_VERSION		5
+#define RELAYFS_CHANNEL_VERSION		6
 
 /*
  * Per-cpu relay channel buffer
@@ -60,24 +60,11 @@
 	struct rchan_callbacks *cb;	/* client callbacks */
 	struct kref kref;		/* channel refcount */
 	void *private_data;		/* for user-defined data */
+	size_t last_toobig;		/* tried to log event > subbuf size */
 	struct rchan_buf *buf[NR_CPUS]; /* per-cpu channel buffers */
 };
 
 /*
- * Relayfs inode
- */
-struct relayfs_inode_info
-{
-	struct inode vfs_inode;
-	struct rchan_buf *buf;
-};
-
-static inline struct relayfs_inode_info *RELAYFS_I(struct inode *inode)
-{
-	return container_of(inode, struct relayfs_inode_info, vfs_inode);
-}
-
-/*
  * Relay channel client callbacks
  */
 struct rchan_callbacks
@@ -123,6 +110,46 @@
 	 */
         void (*buf_unmapped)(struct rchan_buf *buf,
 			     struct file *filp);
+	/*
+	 * create_buf_file - create file to represent a relayfs channel buffer
+	 * @filename: the name of the file to create
+	 * @parent: the parent of the file to create
+	 * @mode: the mode of the file to create
+	 * @buf: the channel buffer
+	 * @is_global: outparam - set non-zero if the buffer should be global
+	 *
+	 * Called during relay_open(), once for each per-cpu buffer,
+	 * to allow the client to create a file to be used to
+	 * represent the corresponding channel buffer.  If the file is
+	 * created outside of relayfs, the parent must also exist in
+	 * that filesystem.
+	 *
+	 * The callback should return the dentry of the file created
+	 * to represent the relay buffer.
+	 *
+	 * Setting the is_global outparam to a non-zero value will
+	 * cause relay_open() to create a single global buffer rather
+	 * than the default set of per-cpu buffers.
+	 *
+	 * See Documentation/filesystems/relayfs.txt for more info.
+	 */
+	struct dentry *(*create_buf_file)(const char *filename,
+					  struct dentry *parent,
+					  int mode,
+					  struct rchan_buf *buf,
+					  int *is_global);
+
+	/*
+	 * remove_buf_file - remove file representing a relayfs channel buffer
+	 * @dentry: the dentry of the file to remove
+	 *
+	 * Called during relay_close(), once for each per-cpu buffer,
+	 * to allow the client to remove a file used to represent a
+	 * channel buffer.
+	 *
+	 * The callback should return 0 if successful, negative if not.
+	 */
+	int (*remove_buf_file)(struct dentry *dentry);
 };
 
 /*
@@ -147,6 +174,12 @@
 extern struct dentry *relayfs_create_dir(const char *name,
 					 struct dentry *parent);
 extern int relayfs_remove_dir(struct dentry *dentry);
+extern struct dentry *relayfs_create_file(const char *name,
+					  struct dentry *parent,
+					  int mode,
+					  struct file_operations *fops,
+					  void *data);
+extern int relayfs_remove_file(struct dentry *dentry);
 
 /**
  *	relay_write - write data into the channel
@@ -246,10 +279,9 @@
 }
 
 /*
- * exported relayfs file operations, fs/relayfs/inode.c
+ * exported relay file operations, fs/relayfs/inode.c
  */
-
-extern struct file_operations relayfs_file_operations;
+extern struct file_operations relay_file_operations;
 
 #endif /* _LINUX_RELAYFS_FS_H */
 
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index 3bd7cce..157d7e3 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -21,6 +21,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/device.h>
+#include <linux/string.h>
 #include <linux/rio.h>
 
 extern int __rio_local_read_config_32(struct rio_mport *port, u32 offset,
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 35b30e6..9d6fbee 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -71,6 +71,7 @@
  * rmap interfaces called when adding or removing pte of page
  */
 void page_add_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
+void page_add_new_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
 void page_add_file_rmap(struct page *);
 void page_remove_rmap(struct page *);
 
@@ -89,7 +90,7 @@
 /*
  * Called from mm/vmscan.c to handle paging out
  */
-int page_referenced(struct page *, int is_locked, int ignore_token);
+int page_referenced(struct page *, int is_locked);
 int try_to_unmap(struct page *);
 
 /*
@@ -109,7 +110,7 @@
 #define anon_vma_prepare(vma)	(0)
 #define anon_vma_link(vma)	do {} while (0)
 
-#define page_referenced(page,l,i) TestClearPageReferenced(page)
+#define page_referenced(page,l) TestClearPageReferenced(page)
 #define try_to_unmap(page)	SWAP_FAIL
 
 #endif	/* CONFIG_MMU */
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index e1aaf1f..0b2ba67 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -11,6 +11,8 @@
 #ifndef _LINUX_RTC_H_
 #define _LINUX_RTC_H_
 
+#include <linux/interrupt.h>
+
 /*
  * The struct used to pass data via the following ioctl. Similar to the
  * struct tm in <time.h>, but it needs to be here so that the kernel 
@@ -102,6 +104,7 @@
 int rtc_unregister(rtc_task_t *task);
 int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg);
 void rtc_get_rtc_time(struct rtc_time *rtc_tm);
+irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index c231e9a..d50482b 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -866,6 +866,7 @@
 #define	RTNLGRP_IPV4_MROUTE	RTNLGRP_IPV4_MROUTE
 	RTNLGRP_IPV4_ROUTE,
 #define RTNLGRP_IPV4_ROUTE	RTNLGRP_IPV4_ROUTE
+	RTNLGRP_NOP1,
 	RTNLGRP_IPV6_IFADDR,
 #define RTNLGRP_IPV6_IFADDR	RTNLGRP_IPV6_IFADDR
 	RTNLGRP_IPV6_MROUTE,
@@ -876,8 +877,11 @@
 #define RTNLGRP_IPV6_IFINFO	RTNLGRP_IPV6_IFINFO
 	RTNLGRP_DECnet_IFADDR,
 #define RTNLGRP_DECnet_IFADDR	RTNLGRP_DECnet_IFADDR
+	RTNLGRP_NOP2,
 	RTNLGRP_DECnet_ROUTE,
 #define RTNLGRP_DECnet_ROUTE	RTNLGRP_DECnet_ROUTE
+	RTNLGRP_NOP3,
+	RTNLGRP_NOP4,
 	RTNLGRP_IPV6_PREFIX,
 #define RTNLGRP_IPV6_PREFIX	RTNLGRP_IPV6_PREFIX
 	__RTNLGRP_MAX
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2038bd2..78eb92a 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -34,6 +34,7 @@
 #include <linux/percpu.h>
 #include <linux/topology.h>
 #include <linux/seccomp.h>
+#include <linux/rcupdate.h>
 
 #include <linux/auxvec.h>	/* For AT_VECTOR_SIZE */
 
@@ -254,25 +255,12 @@
  * The mm counters are not protected by its page_table_lock,
  * so must be incremented atomically.
  */
-#ifdef ATOMIC64_INIT
-#define set_mm_counter(mm, member, value) atomic64_set(&(mm)->_##member, value)
-#define get_mm_counter(mm, member) ((unsigned long)atomic64_read(&(mm)->_##member))
-#define add_mm_counter(mm, member, value) atomic64_add(value, &(mm)->_##member)
-#define inc_mm_counter(mm, member) atomic64_inc(&(mm)->_##member)
-#define dec_mm_counter(mm, member) atomic64_dec(&(mm)->_##member)
-typedef atomic64_t mm_counter_t;
-#else /* !ATOMIC64_INIT */
-/*
- * The counters wrap back to 0 at 2^32 * PAGE_SIZE,
- * that is, at 16TB if using 4kB page size.
- */
-#define set_mm_counter(mm, member, value) atomic_set(&(mm)->_##member, value)
-#define get_mm_counter(mm, member) ((unsigned long)atomic_read(&(mm)->_##member))
-#define add_mm_counter(mm, member, value) atomic_add(value, &(mm)->_##member)
-#define inc_mm_counter(mm, member) atomic_inc(&(mm)->_##member)
-#define dec_mm_counter(mm, member) atomic_dec(&(mm)->_##member)
-typedef atomic_t mm_counter_t;
-#endif /* !ATOMIC64_INIT */
+#define set_mm_counter(mm, member, value) atomic_long_set(&(mm)->_##member, value)
+#define get_mm_counter(mm, member) ((unsigned long)atomic_long_read(&(mm)->_##member))
+#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
+#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
+#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
+typedef atomic_long_t mm_counter_t;
 
 #else  /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
 /*
@@ -363,8 +351,16 @@
 	atomic_t		count;
 	struct k_sigaction	action[_NSIG];
 	spinlock_t		siglock;
+	struct rcu_head		rcu;
 };
 
+extern void sighand_free_cb(struct rcu_head *rhp);
+
+static inline void sighand_free(struct sighand_struct *sp)
+{
+	call_rcu(&sp->rcu, sighand_free_cb);
+}
+
 /*
  * NOTE! "signal_struct" does not have it's own
  * locking, because a shared signal_struct always
@@ -775,6 +771,7 @@
 	unsigned keep_capabilities:1;
 	struct user_struct *user;
 #ifdef CONFIG_KEYS
+	struct key *request_key_auth;	/* assumed request_key authority */
 	struct key *thread_keyring;	/* keyring private to this thread */
 	unsigned char jit_keyring;	/* default keyring to attach requested keys to */
 #endif
@@ -857,6 +854,7 @@
 	int cpuset_mems_generation;
 #endif
 	atomic_t fs_excl;	/* holding fs exclusive resources */
+	struct rcu_head rcu;
 };
 
 static inline pid_t process_group(struct task_struct *tsk)
@@ -880,8 +878,14 @@
 extern void free_task(struct task_struct *tsk);
 extern void __put_task_struct(struct task_struct *tsk);
 #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0)
-#define put_task_struct(tsk) \
-do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
+
+extern void __put_task_struct_cb(struct rcu_head *rhp);
+
+static inline void put_task_struct(struct task_struct *t)
+{
+	if (atomic_dec_and_test(&t->usage))
+		call_rcu(&t->rcu, __put_task_struct_cb);
+}
 
 /*
  * Per process flags
@@ -908,7 +912,7 @@
 #define PF_SYNCWRITE	0x00200000	/* I am doing a sync write */
 #define PF_BORROWED_MM	0x00400000	/* I am a kthread doing use_mm */
 #define PF_RANDOMIZE	0x00800000	/* randomize virtual address space */
-#define PF_HOTPLUG_CPU	0x01000000	/* Currently performing CPU hotplug */
+#define PF_SWAPWRITE	0x01000000	/* Allowed to write to swap */
 
 /*
  * Only the _current_ task can read/write to tsk->flags, but other
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
new file mode 100644
index 0000000..76850b7
--- /dev/null
+++ b/include/linux/screen_info.h
@@ -0,0 +1,77 @@
+#ifndef _SCREEN_INFO_H
+#define _SCREEN_INFO_H
+
+#include <linux/types.h>
+
+/*
+ * These are set up by the setup-routine at boot-time:
+ */
+
+struct screen_info {
+	u8  orig_x;		/* 0x00 */
+	u8  orig_y;		/* 0x01 */
+	u16 dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
+	u16 orig_video_page;	/* 0x04 */
+	u8  orig_video_mode;	/* 0x06 */
+	u8  orig_video_cols;	/* 0x07 */
+	u16 unused2;		/* 0x08 */
+	u16 orig_video_ega_bx;	/* 0x0a */
+	u16 unused3;		/* 0x0c */
+	u8  orig_video_lines;	/* 0x0e */
+	u8  orig_video_isVGA;	/* 0x0f */
+	u16 orig_video_points;	/* 0x10 */
+
+	/* VESA graphic mode -- linear frame buffer */
+	u16 lfb_width;		/* 0x12 */
+	u16 lfb_height;		/* 0x14 */
+	u16 lfb_depth;		/* 0x16 */
+	u32 lfb_base;		/* 0x18 */
+	u32 lfb_size;		/* 0x1c */
+	u16 dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
+	u16 lfb_linelength;	/* 0x24 */
+	u8  red_size;		/* 0x26 */
+	u8  red_pos;		/* 0x27 */
+	u8  green_size;		/* 0x28 */
+	u8  green_pos;		/* 0x29 */
+	u8  blue_size;		/* 0x2a */
+	u8  blue_pos;		/* 0x2b */
+	u8  rsvd_size;		/* 0x2c */
+	u8  rsvd_pos;		/* 0x2d */
+	u16 vesapm_seg;		/* 0x2e */
+	u16 vesapm_off;		/* 0x30 */
+	u16 pages;		/* 0x32 */
+	u16 vesa_attributes;	/* 0x34 */
+	u32  capabilities;      /* 0x36 */
+				/* 0x3a -- 0x3f reserved for future expansion */
+};
+
+extern struct screen_info screen_info;
+
+#define ORIG_X			(screen_info.orig_x)
+#define ORIG_Y			(screen_info.orig_y)
+#define ORIG_VIDEO_MODE		(screen_info.orig_video_mode)
+#define ORIG_VIDEO_COLS 	(screen_info.orig_video_cols)
+#define ORIG_VIDEO_EGA_BX	(screen_info.orig_video_ega_bx)
+#define ORIG_VIDEO_LINES	(screen_info.orig_video_lines)
+#define ORIG_VIDEO_ISVGA	(screen_info.orig_video_isVGA)
+#define ORIG_VIDEO_POINTS       (screen_info.orig_video_points)
+
+#define VIDEO_TYPE_MDA		0x10	/* Monochrome Text Display	*/
+#define VIDEO_TYPE_CGA		0x11	/* CGA Display 			*/
+#define VIDEO_TYPE_EGAM		0x20	/* EGA/VGA in Monochrome Mode	*/
+#define VIDEO_TYPE_EGAC		0x21	/* EGA in Color Mode		*/
+#define VIDEO_TYPE_VGAC		0x22	/* VGA+ in Color Mode		*/
+#define VIDEO_TYPE_VLFB		0x23	/* VESA VGA in graphic mode	*/
+
+#define VIDEO_TYPE_PICA_S3	0x30	/* ACER PICA-61 local S3 video	*/
+#define VIDEO_TYPE_MIPS_G364	0x31    /* MIPS Magnum 4000 G364 video  */
+#define VIDEO_TYPE_SGI          0x33    /* Various SGI graphics hardware */
+
+#define VIDEO_TYPE_TGAC		0x40	/* DEC TGA */
+
+#define VIDEO_TYPE_SUN          0x50    /* Sun frame buffer. */
+#define VIDEO_TYPE_SUNPCI       0x51    /* Sun PCI based frame buffer. */
+
+#define VIDEO_TYPE_PMAC		0x60	/* PowerMacintosh frame buffer. */
+
+#endif /* _SCREEN_INFO_H */
diff --git a/include/linux/sdla.h b/include/linux/sdla.h
index 3b6afb8..564acd3 100644
--- a/include/linux/sdla.h
+++ b/include/linux/sdla.h
@@ -293,46 +293,46 @@
 #define SDLA_S508_INTEN			0x10
 
 struct sdla_cmd {
-   char  opp_flag		__attribute__((packed));
-   char  cmd			__attribute__((packed));
-   short length			__attribute__((packed));
-   char  retval			__attribute__((packed));
-   short dlci			__attribute__((packed));
-   char  flags			__attribute__((packed));
-   short rxlost_int		__attribute__((packed));
-   long  rxlost_app		__attribute__((packed));
-   char  reserve[2]		__attribute__((packed));
-   char  data[SDLA_MAX_DATA]	__attribute__((packed));	/* transfer data buffer */
-};
+   char  opp_flag;
+   char  cmd;
+   short length;
+   char  retval;
+   short dlci;
+   char  flags;
+   short rxlost_int;
+   long  rxlost_app;
+   char  reserve[2];
+   char  data[SDLA_MAX_DATA];	/* transfer data buffer */
+} __attribute__((packed));
 
 struct intr_info {
-   char  flags		__attribute__((packed));
-   short txlen		__attribute__((packed));
-   char  irq		__attribute__((packed));
-   char  flags2		__attribute__((packed));
-   short timeout	__attribute__((packed));
-};
+   char  flags;
+   short txlen;
+   char  irq;
+   char  flags2;
+   short timeout;
+} __attribute__((packed));
 
 /* found in the 508's control window at RXBUF_INFO */
 struct buf_info {
-   unsigned short rse_num	__attribute__((packed));
-   unsigned long  rse_base	__attribute__((packed));
-   unsigned long  rse_next	__attribute__((packed));
-   unsigned long  buf_base	__attribute__((packed));
-   unsigned short reserved	__attribute__((packed));
-   unsigned long  buf_top	__attribute__((packed));
-};
+   unsigned short rse_num;
+   unsigned long  rse_base;
+   unsigned long  rse_next;
+   unsigned long  buf_base;
+   unsigned short reserved;
+   unsigned long  buf_top;
+} __attribute__((packed));
 
 /* structure pointed to by rse_base in RXBUF_INFO struct */
 struct buf_entry {
-   char  opp_flag	__attribute__((packed));
-   short length		__attribute__((packed));
-   short dlci		__attribute__((packed));
-   char  flags		__attribute__((packed));
-   short timestamp	__attribute__((packed));
-   short reserved[2]	__attribute__((packed));
-   long  buf_addr	__attribute__((packed));
-};
+   char  opp_flag;
+   short length;
+   short dlci;
+   char  flags;
+   short timestamp;
+   short reserved[2];
+   long  buf_addr;
+} __attribute__((packed));
 
 #endif
 
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index dc89116..cd2773b 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -26,11 +26,7 @@
 
 #else /* CONFIG_SECCOMP */
 
-#if (__GNUC__ > 2)
-  typedef struct { } seccomp_t;
-#else
-  typedef struct { int gcc_is_buggy; } seccomp_t;
-#endif
+typedef struct { } seccomp_t;
 
 #define secure_computing(x) do { } while (0)
 /* static inline to preserve typechecking */
diff --git a/include/linux/security.h b/include/linux/security.h
index f7e0ae0..ef75365 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -59,6 +59,12 @@
 struct sock;
 struct sockaddr;
 struct socket;
+struct flowi;
+struct dst_entry;
+struct xfrm_selector;
+struct xfrm_policy;
+struct xfrm_state;
+struct xfrm_user_sec_ctx;
 
 extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
 extern int cap_netlink_recv(struct sk_buff *skb);
@@ -788,6 +794,52 @@
  *      which is used to copy security attributes between local stream sockets.
  * @sk_free_security:
  *	Deallocate security structure.
+ * @sk_getsid:
+ *	Retrieve the LSM-specific sid for the sock to enable caching of network
+ *	authorizations.
+ *
+ * Security hooks for XFRM operations.
+ *
+ * @xfrm_policy_alloc_security:
+ *	@xp contains the xfrm_policy being added to Security Policy Database
+ *	used by the XFRM system.
+ *	@sec_ctx contains the security context information being provided by
+ *	the user-level policy update program (e.g., setkey).
+ *	Allocate a security structure to the xp->selector.security field.
+ *	The security field is initialized to NULL when the xfrm_policy is
+ *	allocated.
+ *	Return 0 if operation was successful (memory to allocate, legal context)
+ * @xfrm_policy_clone_security:
+ *	@old contains an existing xfrm_policy in the SPD.
+ *	@new contains a new xfrm_policy being cloned from old.
+ *	Allocate a security structure to the new->selector.security field
+ *	that contains the information from the old->selector.security field.
+ *	Return 0 if operation was successful (memory to allocate).
+ * @xfrm_policy_free_security:
+ *	@xp contains the xfrm_policy
+ *	Deallocate xp->selector.security.
+ * @xfrm_state_alloc_security:
+ *	@x contains the xfrm_state being added to the Security Association
+ *	Database by the XFRM system.
+ *	@sec_ctx contains the security context information being provided by
+ *	the user-level SA generation program (e.g., setkey or racoon).
+ *	Allocate a security structure to the x->sel.security field.  The
+ *	security field is initialized to NULL when the xfrm_state is
+ *	allocated.
+ *	Return 0 if operation was successful (memory to allocate, legal context).
+ * @xfrm_state_free_security:
+ *	@x contains the xfrm_state.
+ *	Deallocate x>sel.security.
+ * @xfrm_policy_lookup:
+ *	@xp contains the xfrm_policy for which the access control is being
+ *	checked.
+ *	@sk_sid contains the sock security label that is used to authorize
+ *	access to the policy xp.
+ *	@dir contains the direction of the flow (input or output).
+ *	Check permission when a sock selects a xfrm_policy for processing
+ *	XFRMs on a packet.  The hook is called when selecting either a
+ *	per-socket policy or a generic xfrm policy.
+ *	Return 0 if permission is granted.
  *
  * Security hooks affecting all Key Management operations
  *
@@ -1237,8 +1289,18 @@
 	int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
 	int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
 	void (*sk_free_security) (struct sock *sk);
+	unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir);
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+	int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
+	int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new);
+	void (*xfrm_policy_free_security) (struct xfrm_policy *xp);
+	int (*xfrm_state_alloc_security) (struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
+	void (*xfrm_state_free_security) (struct xfrm_state *x);
+	int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 sk_sid, u8 dir);
+#endif	/* CONFIG_SECURITY_NETWORK_XFRM */
+
 	/* key management security hooks */
 #ifdef CONFIG_KEYS
 	int (*key_alloc)(struct key *key);
@@ -2679,6 +2741,11 @@
 {
 	return security_ops->sk_free_security(sk);
 }
+
+static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
+{
+	return security_ops->sk_getsid(sk, fl, dir);
+}
 #else	/* CONFIG_SECURITY_NETWORK */
 static inline int security_unix_stream_connect(struct socket * sock,
 					       struct socket * other, 
@@ -2795,8 +2862,73 @@
 static inline void security_sk_free(struct sock *sk)
 {
 }
+
+static inline unsigned int security_sk_sid(struct sock *sk, struct flowi *fl, u8 dir)
+{
+	return 0;
+}
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return security_ops->xfrm_policy_alloc_security(xp, sec_ctx);
+}
+
+static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+	return security_ops->xfrm_policy_clone_security(old, new);
+}
+
+static inline void security_xfrm_policy_free(struct xfrm_policy *xp)
+{
+	security_ops->xfrm_policy_free_security(xp);
+}
+
+static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return security_ops->xfrm_state_alloc_security(x, sec_ctx);
+}
+
+static inline void security_xfrm_state_free(struct xfrm_state *x)
+{
+	security_ops->xfrm_state_free_security(x);
+}
+
+static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+	return security_ops->xfrm_policy_lookup(xp, sk_sid, dir);
+}
+#else	/* CONFIG_SECURITY_NETWORK_XFRM */
+static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return 0;
+}
+
+static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+	return 0;
+}
+
+static inline void security_xfrm_policy_free(struct xfrm_policy *xp)
+{
+}
+
+static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return 0;
+}
+
+static inline void security_xfrm_state_free(struct xfrm_state *x)
+{
+}
+
+static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+	return 0;
+}
+#endif	/* CONFIG_SECURITY_NETWORK_XFRM */
+
 #ifdef CONFIG_KEYS
 #ifdef CONFIG_SECURITY
 static inline int security_key_alloc(struct key *key)
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index a3ac92b..e3710d7 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -121,6 +121,9 @@
 
 #define PORT_IP3106	70
 
+/* Hilscher netx */
+#define PORT_NETX	71
+
 #ifdef __KERNEL__
 
 #include <linux/config.h>
diff --git a/include/linux/signal.h b/include/linux/signal.h
index 5dd5f02..b7d0935 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -18,6 +18,19 @@
 #define SA_PROBE		SA_ONESHOT
 #define SA_SAMPLE_RANDOM	SA_RESTART
 #define SA_SHIRQ		0x04000000
+/*
+ * As above, these correspond to the IORESOURCE_IRQ_* defines in
+ * linux/ioport.h to select the interrupt line behaviour.  When
+ * requesting an interrupt without specifying a SA_TRIGGER, the
+ * setting should be assumed to be "as already configured", which
+ * may be as per machine or firmware initialisation.
+ */
+#define SA_TRIGGER_LOW		0x00000008
+#define SA_TRIGGER_HIGH		0x00000004
+#define SA_TRIGGER_FALLING	0x00000002
+#define SA_TRIGGER_RISING	0x00000001
+#define SA_TRIGGER_MASK	(SA_TRIGGER_HIGH|SA_TRIGGER_LOW|\
+				 SA_TRIGGER_RISING|SA_TRIGGER_FALLING)
 
 /*
  * Real Time signals may be queued.
@@ -81,6 +94,23 @@
 
 #endif /* __HAVE_ARCH_SIG_BITOPS */
 
+static inline int sigisemptyset(sigset_t *set)
+{
+	extern void _NSIG_WORDS_is_unsupported_size(void);
+	switch (_NSIG_WORDS) {
+	case 4:
+		return (set->sig[3] | set->sig[2] |
+			set->sig[1] | set->sig[0]) == 0;
+	case 2:
+		return (set->sig[1] | set->sig[0]) == 0;
+	case 1:
+		return set->sig[0] == 0;
+	default:
+		_NSIG_WORDS_is_unsupported_size();
+		return 0;
+	}
+}
+
 #define sigmask(sig)	(1UL << ((sig) - 1))
 
 #ifndef __HAVE_ARCH_SIG_SETOPS
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 8c5d600..e5fd66c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -32,7 +32,6 @@
 
 #define HAVE_ALLOC_SKB		/* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB	/* Ditto 8)		   */
-#define SLAB_SKB 		/* Slabified skbuffs 	   */
 
 #define CHECKSUM_NONE 0
 #define CHECKSUM_HW 1
@@ -134,7 +133,7 @@
  */
 struct skb_shared_info {
 	atomic_t	dataref;
-	unsigned int	nr_frags;
+	unsigned short	nr_frags;
 	unsigned short	tso_size;
 	unsigned short	tso_segs;
 	unsigned short  ufo_size;
@@ -252,7 +251,7 @@
 	 * want to keep them across layers you have to do a skb_clone()
 	 * first. This is owned by whoever has the skb queued ATM.
 	 */
-	char			cb[40];
+	char			cb[48];
 
 	unsigned int		len,
 				data_len,
@@ -1239,6 +1238,8 @@
 							int hlen,
 							struct iovec *iov);
 extern void	       skb_free_datagram(struct sock *sk, struct sk_buff *skb);
+extern void	       skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
+					 unsigned int flags);
 extern unsigned int    skb_checksum(const struct sk_buff *skb, int offset,
 				    int len, unsigned int csum);
 extern int	       skb_copy_bits(const struct sk_buff *skb, int offset,
diff --git a/include/linux/slab.h b/include/linux/slab.h
index d1ea405..1fb77a9 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -53,6 +53,8 @@
 #define SLAB_CTOR_ATOMIC	0x002UL		/* tell constructor it can't sleep */
 #define	SLAB_CTOR_VERIFY	0x004UL		/* tell constructor it's a verify call */
 
+#ifndef CONFIG_SLOB
+
 /* prototypes */
 extern void __init kmem_cache_init(void);
 
@@ -134,6 +136,39 @@
 extern int FASTCALL(kmem_cache_reap(int));
 extern int FASTCALL(kmem_ptr_validate(kmem_cache_t *cachep, void *ptr));
 
+#else /* CONFIG_SLOB */
+
+/* SLOB allocator routines */
+
+void kmem_cache_init(void);
+struct kmem_cache *kmem_find_general_cachep(size_t, gfp_t gfpflags);
+struct kmem_cache *kmem_cache_create(const char *c, size_t, size_t,
+	unsigned long,
+	void (*)(void *, struct kmem_cache *, unsigned long),
+	void (*)(void *, struct kmem_cache *, unsigned long));
+int kmem_cache_destroy(struct kmem_cache *c);
+void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags);
+void kmem_cache_free(struct kmem_cache *c, void *b);
+const char *kmem_cache_name(struct kmem_cache *);
+void *kmalloc(size_t size, gfp_t flags);
+void *kzalloc(size_t size, gfp_t flags);
+void kfree(const void *m);
+unsigned int ksize(const void *m);
+unsigned int kmem_cache_size(struct kmem_cache *c);
+
+static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
+{
+	return kzalloc(n * size, flags);
+}
+
+#define kmem_cache_shrink(d) (0)
+#define kmem_cache_reap(a)
+#define kmem_ptr_validate(a, b) (0)
+#define kmem_cache_alloc_node(c, f, n) kmem_cache_alloc(c, f)
+#define kmalloc_node(s, f, n) kmalloc(s, f)
+
+#endif /* CONFIG_SLOB */
+
 /* System wide caches */
 extern kmem_cache_t	*vm_area_cachep;
 extern kmem_cache_t	*names_cachep;
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 1739c2d..9f40191 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -27,7 +27,6 @@
 #include <linux/compiler.h>		/* __user			*/
 
 extern int sysctl_somaxconn;
-extern void sock_init(void);
 #ifdef CONFIG_PROC_FS
 struct seq_file;
 extern void socket_seq_show(struct seq_file *seq);
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 0e9682c..799be67 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -59,8 +59,7 @@
 /*
  * Must define these before including other files, inline functions need them
  */
-#define LOCK_SECTION_NAME                       \
-        ".text.lock." __stringify(KBUILD_BASENAME)
+#define LOCK_SECTION_NAME ".text.lock."KBUILD_BASENAME
 
 #define LOCK_SECTION_START(extra)               \
         ".subsection 1\n\t"                     \
diff --git a/include/linux/spinlock_types_up.h b/include/linux/spinlock_types_up.h
index def2d17..04135b0 100644
--- a/include/linux/spinlock_types_up.h
+++ b/include/linux/spinlock_types_up.h
@@ -22,30 +22,16 @@
 
 #else
 
-/*
- * All gcc 2.95 versions and early versions of 2.96 have a nasty bug
- * with empty initializers.
- */
-#if (__GNUC__ > 2)
 typedef struct { } raw_spinlock_t;
 
 #define __RAW_SPIN_LOCK_UNLOCKED { }
-#else
-typedef struct { int gcc_is_buggy; } raw_spinlock_t;
-#define __RAW_SPIN_LOCK_UNLOCKED (raw_spinlock_t) { 0 }
-#endif
 
 #endif
 
-#if (__GNUC__ > 2)
 typedef struct {
 	/* no debug version on UP */
 } raw_rwlock_t;
 
 #define __RAW_RW_LOCK_UNLOCKED { }
-#else
-typedef struct { int gcc_is_buggy; } raw_rwlock_t;
-#define __RAW_RW_LOCK_UNLOCKED (raw_rwlock_t) { 0 }
-#endif
 
 #endif /* __LINUX_SPINLOCK_TYPES_UP_H */
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index ab151bb..f147e6b 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -49,7 +49,6 @@
 
 	unsigned int		cl_softrtry : 1,/* soft timeouts */
 				cl_intr     : 1,/* interruptible */
-				cl_chatty   : 1,/* be verbose */
 				cl_autobind : 1,/* use getport() */
 				cl_oneshot  : 1,/* dispose after use */
 				cl_dead     : 1;/* abandoned */
@@ -126,7 +125,8 @@
 void		rpc_call_setup(struct rpc_task *, struct rpc_message *, int);
 
 int		rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg,
-			       int flags, rpc_action callback, void *clntdata);
+			       int flags, const struct rpc_call_ops *tk_ops,
+			       void *calldata);
 int		rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg,
 			      int flags);
 void		rpc_restart_call(struct rpc_task *);
@@ -134,6 +134,7 @@
 void		rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
 void		rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
 size_t		rpc_max_payload(struct rpc_clnt *);
+void		rpc_force_rebind(struct rpc_clnt *);
 int		rpc_ping(struct rpc_clnt *clnt, int flags);
 
 static __inline__
diff --git a/include/linux/sunrpc/gss_spkm3.h b/include/linux/sunrpc/gss_spkm3.h
index 0beb2cf..336e218 100644
--- a/include/linux/sunrpc/gss_spkm3.h
+++ b/include/linux/sunrpc/gss_spkm3.h
@@ -48,7 +48,7 @@
 #define CKSUMTYPE_RSA_MD5            0x0007
 
 s32 make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
-                   struct xdr_netobj *cksum);
+                   int body_offset, struct xdr_netobj *cksum);
 void asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits);
 int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, 
                    int explen);
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index 4d77e90..8b25629 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -27,6 +27,7 @@
 	struct rpc_cred *	rpc_cred;	/* Credentials */
 };
 
+struct rpc_call_ops;
 struct rpc_wait_queue;
 struct rpc_wait {
 	struct list_head	list;		/* wait queue links */
@@ -41,6 +42,7 @@
 #ifdef RPC_DEBUG
 	unsigned long		tk_magic;	/* 0xf00baa */
 #endif
+	atomic_t		tk_count;	/* Reference count */
 	struct list_head	tk_task;	/* global list of tasks */
 	struct rpc_clnt *	tk_client;	/* RPC client */
 	struct rpc_rqst *	tk_rqstp;	/* RPC request */
@@ -50,8 +52,6 @@
 	 * RPC call state
 	 */
 	struct rpc_message	tk_msg;		/* RPC call info */
-	__u32 *			tk_buffer;	/* XDR buffer */
-	size_t			tk_bufsize;
 	__u8			tk_garb_retry;
 	__u8			tk_cred_retry;
 
@@ -61,13 +61,12 @@
 	 * timeout_fn   to be executed by timer bottom half
 	 * callback	to be executed after waking up
 	 * action	next procedure for async tasks
-	 * exit		exit async task and report to caller
+	 * tk_ops	caller callbacks
 	 */
 	void			(*tk_timeout_fn)(struct rpc_task *);
 	void			(*tk_callback)(struct rpc_task *);
 	void			(*tk_action)(struct rpc_task *);
-	void			(*tk_exit)(struct rpc_task *);
-	void			(*tk_release)(struct rpc_task *);
+	const struct rpc_call_ops *tk_ops;
 	void *			tk_calldata;
 
 	/*
@@ -78,7 +77,6 @@
 	struct timer_list	tk_timer;	/* kernel timer */
 	unsigned long		tk_timeout;	/* timeout for rpc_sleep() */
 	unsigned short		tk_flags;	/* misc flags */
-	unsigned char		tk_active   : 1;/* Task has been activated */
 	unsigned char		tk_priority : 2;/* Task priority */
 	unsigned long		tk_runstate;	/* Task run status */
 	struct workqueue_struct	*tk_workqueue;	/* Normally rpciod, but could
@@ -111,6 +109,13 @@
 
 typedef void			(*rpc_action)(struct rpc_task *);
 
+struct rpc_call_ops {
+	void (*rpc_call_prepare)(struct rpc_task *, void *);
+	void (*rpc_call_done)(struct rpc_task *, void *);
+	void (*rpc_release)(void *);
+};
+
+
 /*
  * RPC task flags
  */
@@ -129,7 +134,6 @@
 #define RPC_IS_SWAPPER(t)	((t)->tk_flags & RPC_TASK_SWAPPER)
 #define RPC_DO_ROOTOVERRIDE(t)	((t)->tk_flags & RPC_TASK_ROOTCREDS)
 #define RPC_ASSASSINATED(t)	((t)->tk_flags & RPC_TASK_KILLED)
-#define RPC_IS_ACTIVATED(t)	((t)->tk_active)
 #define RPC_DO_CALLBACK(t)	((t)->tk_callback != NULL)
 #define RPC_IS_SOFT(t)		((t)->tk_flags & RPC_TASK_SOFT)
 #define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR)
@@ -138,6 +142,7 @@
 #define RPC_TASK_QUEUED		1
 #define RPC_TASK_WAKEUP		2
 #define RPC_TASK_HAS_TIMER	3
+#define RPC_TASK_ACTIVE		4
 
 #define RPC_IS_RUNNING(t)	(test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
 #define rpc_set_running(t)	(set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
@@ -168,6 +173,15 @@
 		smp_mb__after_clear_bit(); \
 	} while (0)
 
+#define RPC_IS_ACTIVATED(t)	(test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate))
+#define rpc_set_active(t)	(set_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate))
+#define rpc_clear_active(t)	\
+	do { \
+		smp_mb__before_clear_bit(); \
+		clear_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate); \
+		smp_mb__after_clear_bit(); \
+	} while(0)
+
 /*
  * Task priorities.
  * Note: if you change these, you must also change
@@ -228,11 +242,16 @@
 /*
  * Function prototypes
  */
-struct rpc_task *rpc_new_task(struct rpc_clnt *, rpc_action, int flags);
+struct rpc_task *rpc_new_task(struct rpc_clnt *, int flags,
+				const struct rpc_call_ops *ops, void *data);
+struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
+				const struct rpc_call_ops *ops, void *data);
 struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent);
-void		rpc_init_task(struct rpc_task *, struct rpc_clnt *,
-					rpc_action exitfunc, int flags);
+void		rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt,
+				int flags, const struct rpc_call_ops *ops,
+				void *data);
 void		rpc_release_task(struct rpc_task *);
+void		rpc_exit_task(struct rpc_task *);
 void		rpc_killall_tasks(struct rpc_clnt *);
 int		rpc_execute(struct rpc_task *);
 void		rpc_run_child(struct rpc_task *parent, struct rpc_task *child,
@@ -247,9 +266,11 @@
 void		rpc_wake_up_status(struct rpc_wait_queue *, int);
 void		rpc_delay(struct rpc_task *, unsigned long);
 void *		rpc_malloc(struct rpc_task *, size_t);
+void		rpc_free(struct rpc_task *);
 int		rpciod_up(void);
 void		rpciod_down(void);
 void		rpciod_wake_up(void);
+int		__rpc_wait_for_completion_task(struct rpc_task *task, int (*)(void *));
 #ifdef RPC_DEBUG
 void		rpc_show_tasks(void);
 #endif
@@ -259,7 +280,12 @@
 static inline void rpc_exit(struct rpc_task *task, int status)
 {
 	task->tk_status = status;
-	task->tk_action = NULL;
+	task->tk_action = rpc_exit_task;
+}
+
+static inline int rpc_wait_for_completion_task(struct rpc_task *task)
+{
+	return __rpc_wait_for_completion_task(task, NULL);
 }
 
 #ifdef RPC_DEBUG
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
index 5da9687..84c35d4 100644
--- a/include/linux/sunrpc/xdr.h
+++ b/include/linux/sunrpc/xdr.h
@@ -91,7 +91,6 @@
 u32 *	xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len);
 u32 *	xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len);
 u32 *	xdr_encode_string(u32 *p, const char *s);
-u32 *	xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen);
 u32 *	xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen);
 u32 *	xdr_encode_netobj(u32 *p, const struct xdr_netobj *);
 u32 *	xdr_decode_netobj(u32 *p, struct xdr_netobj *);
@@ -135,11 +134,6 @@
 }
 
 /*
- * Maximum number of iov's we use.
- */
-#define MAX_IOVEC	(12)
-
-/*
  * XDR buffer helper functions
  */
 extern void xdr_shift_buf(struct xdr_buf *, size_t);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 3b8b6e8..6ef99b1 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -79,21 +79,19 @@
 	void (*rq_release_snd_buf)(struct rpc_rqst *); /* release rq_enc_pages */
 	struct list_head	rq_list;
 
+	__u32 *			rq_buffer;	/* XDR encode buffer */
+	size_t			rq_bufsize;
+
 	struct xdr_buf		rq_private_buf;		/* The receive buffer
 							 * used in the softirq.
 							 */
 	unsigned long		rq_majortimeo;	/* major timeout alarm */
 	unsigned long		rq_timeout;	/* Current timeout value */
 	unsigned int		rq_retries;	/* # of retries */
-	/*
-	 * For authentication (e.g. auth_des)
-	 */
-	u32			rq_creddata[2];
 	
 	/*
 	 * Partial send handling
 	 */
-	
 	u32			rq_bytes_sent;	/* Bytes we have sent */
 
 	unsigned long		rq_xtime;	/* when transmitted */
@@ -106,7 +104,10 @@
 	void		(*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize);
 	int		(*reserve_xprt)(struct rpc_task *task);
 	void		(*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task);
+	void		(*set_port)(struct rpc_xprt *xprt, unsigned short port);
 	void		(*connect)(struct rpc_task *task);
+	void *		(*buf_alloc)(struct rpc_task *task, size_t size);
+	void		(*buf_free)(struct rpc_task *task);
 	int		(*send_request)(struct rpc_task *task);
 	void		(*set_retrans_timeout)(struct rpc_task *task);
 	void		(*timer)(struct rpc_task *task);
@@ -253,6 +254,7 @@
 #define XPRT_LOCKED		(0)
 #define XPRT_CONNECTED		(1)
 #define XPRT_CONNECTING		(2)
+#define XPRT_CLOSE_WAIT		(3)
 
 static inline void xprt_set_connected(struct rpc_xprt *xprt)
 {
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index a61c04f..5dc94e7 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -14,11 +14,7 @@
 typedef struct pbe {
 	unsigned long address;		/* address of the copy */
 	unsigned long orig_address;	/* original address of page */
-	swp_entry_t swap_address;	
-
-	struct pbe *next;	/* also used as scratch space at
-				 * end of page (see link, diskpage)
-				 */
+	struct pbe *next;
 } suspend_pagedir_t;
 
 #define for_each_pbe(pbe, pblist) \
@@ -77,6 +73,6 @@
  * XXX: We try to keep some more pages free so that I/O operations succeed
  * without paging. Might this be more?
  */
-#define PAGES_FOR_IO	512
+#define PAGES_FOR_IO	1024
 
 #endif /* _LINUX_SWSUSP_H */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 20c9756..389d1c3 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -172,10 +172,16 @@
 
 /* linux/mm/vmscan.c */
 extern int try_to_free_pages(struct zone **, gfp_t);
-extern int zone_reclaim(struct zone *, gfp_t, unsigned int);
 extern int shrink_all_memory(int);
 extern int vm_swappiness;
 
+#ifdef CONFIG_MIGRATION
+extern int isolate_lru_page(struct page *p);
+extern int putback_lru_pages(struct list_head *l);
+extern int migrate_pages(struct list_head *l, struct list_head *t,
+		struct list_head *moved, struct list_head *failed);
+#endif
+
 #ifdef CONFIG_MMU
 /* linux/mm/shmem.c */
 extern int shmem_unuse(swp_entry_t entry, struct page *page);
@@ -193,7 +199,7 @@
 extern struct address_space swapper_space;
 #define total_swapcache_pages  swapper_space.nrpages
 extern void show_swap_cache_info(void);
-extern int add_to_swap(struct page *);
+extern int add_to_swap(struct page *, gfp_t);
 extern void __delete_from_swap_cache(struct page *);
 extern void delete_from_swap_cache(struct page *);
 extern int move_to_swap_cache(struct page *, swp_entry_t);
@@ -210,6 +216,7 @@
 extern struct swap_info_struct swap_info[];
 extern void si_swapinfo(struct sysinfo *);
 extern swp_entry_t get_swap_page(void);
+extern swp_entry_t get_swap_page_of_type(int type);
 extern int swap_duplicate(swp_entry_t);
 extern int valid_swaphandles(swp_entry_t, unsigned long *);
 extern void swap_free(swp_entry_t);
@@ -239,6 +246,11 @@
 		__put_swap_token(mm);
 }
 
+static inline void disable_swap_token(void)
+{
+	put_swap_token(swap_token_mm);
+}
+
 #else /* CONFIG_SWAP */
 
 #define total_swap_pages			0
@@ -283,6 +295,7 @@
 #define put_swap_token(x) do { } while(0)
 #define grab_swap_token()  do { } while(0)
 #define has_swap_token(x) 0
+#define disable_swap_token() do { } while(0)
 
 #endif /* CONFIG_SWAP */
 #endif /* __KERNEL__*/
diff --git a/include/linux/synclink.h b/include/linux/synclink.h
index 763bd290..1b7cd8d 100644
--- a/include/linux/synclink.h
+++ b/include/linux/synclink.h
@@ -1,7 +1,7 @@
 /*
  * SyncLink Multiprotocol Serial Adapter Driver
  *
- * $Id: synclink.h,v 3.6 2002/02/20 21:58:20 paulkf Exp $
+ * $Id: synclink.h,v 3.10 2005/11/08 19:50:54 paulkf Exp $
  *
  * Copyright (C) 1998-2000 by Microgate Corporation
  *
@@ -128,10 +128,14 @@
 #define MGSL_BUS_TYPE_EISA	2
 #define MGSL_BUS_TYPE_PCI	5
 
+#define MGSL_INTERFACE_MASK     0xf
 #define MGSL_INTERFACE_DISABLE  0
 #define MGSL_INTERFACE_RS232    1
 #define MGSL_INTERFACE_V35      2
 #define MGSL_INTERFACE_RS422    3
+#define MGSL_INTERFACE_RTS_EN   0x10
+#define MGSL_INTERFACE_LL       0x20
+#define MGSL_INTERFACE_RL       0x40
 
 typedef struct _MGSL_PARAMS
 {
@@ -163,6 +167,9 @@
 #define SYNCLINK_DEVICE_ID 0x0010
 #define MGSCC_DEVICE_ID 0x0020
 #define SYNCLINK_SCA_DEVICE_ID 0x0030
+#define SYNCLINK_GT_DEVICE_ID 0x0070
+#define SYNCLINK_GT4_DEVICE_ID 0x0080
+#define SYNCLINK_AC_DEVICE_ID  0x0090
 #define MGSL_MAX_SERIAL_NUMBER 30
 
 /*
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index c7007b1..e910d1a 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -511,5 +511,7 @@
 asmlinkage long sys_ioprio_get(int which, int who);
 asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
 					unsigned long maxnode);
+asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
+			const unsigned long __user *from, const unsigned long __user *to);
 
 #endif
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 6bc03c9..7f47212 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -124,7 +124,7 @@
 	KERN_OVERFLOWUID=46,	/* int: overflow UID */
 	KERN_OVERFLOWGID=47,	/* int: overflow GID */
 	KERN_SHMPATH=48,	/* string: path to shm fs */
-	KERN_HOTPLUG=49,	/* string: path to hotplug policy agent */
+	KERN_HOTPLUG=49,	/* string: path to uevent helper (deprecated) */
 	KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */
 	KERN_S390_USER_DEBUG_LOGGING=51,  /* int: dumps of user faults */
 	KERN_CORE_USES_PID=52,		/* int: use core or core.%pid */
@@ -180,6 +180,8 @@
 	VM_VFS_CACHE_PRESSURE=26, /* dcache/icache reclaim pressure */
 	VM_LEGACY_VA_LAYOUT=27, /* legacy/compatibility virtual address space layout */
 	VM_SWAP_TOKEN_TIMEOUT=28, /* default time for token time out */
+	VM_DROP_PAGECACHE=29,	/* int: nuke lots of pagecache */
+	VM_PERCPU_PAGELIST_FRACTION=30,/* int: fraction of pages in each percpu_pagelist */
 };
 
 
@@ -390,6 +392,7 @@
 	NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
 	NET_TCP_CONG_CONTROL=110,
 	NET_TCP_ABC=111,
+	NET_IPV4_IPFRAG_MAX_DIST=112,
 };
 
 enum {
@@ -670,6 +673,9 @@
 	NET_DECNET_DST_GC_INTERVAL = 9,
 	NET_DECNET_CONF = 10,
 	NET_DECNET_NO_FC_MAX_CWND = 11,
+	NET_DECNET_MEM = 12,
+	NET_DECNET_RMEM = 13,
+	NET_DECNET_WMEM = 14,
 	NET_DECNET_DEBUG_LEVEL = 255
 };
 
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 0e1da66..f2bb239 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -55,22 +55,6 @@
 	__u16	urg_ptr;
 };
 
-#define TCP_ACTION_FIN	(1 << 7)
-
-enum {
-  TCPF_ESTABLISHED = (1 << 1),
-  TCPF_SYN_SENT  = (1 << 2),
-  TCPF_SYN_RECV  = (1 << 3),
-  TCPF_FIN_WAIT1 = (1 << 4),
-  TCPF_FIN_WAIT2 = (1 << 5),
-  TCPF_TIME_WAIT = (1 << 6),
-  TCPF_CLOSE     = (1 << 7),
-  TCPF_CLOSE_WAIT = (1 << 8),
-  TCPF_LAST_ACK  = (1 << 9),
-  TCPF_LISTEN    = (1 << 10),
-  TCPF_CLOSING   = (1 << 11) 
-};
-
 /*
  *	The union cast uses a gcc extension to avoid aliasing problems
  *  (union is compatible to any of its members)
@@ -254,10 +238,9 @@
 	__u32	snd_wl1;	/* Sequence for window update		*/
 	__u32	snd_wnd;	/* The window we expect to receive	*/
 	__u32	max_window;	/* Maximal window ever seen from peer	*/
-	__u32	pmtu_cookie;	/* Last pmtu seen by socket		*/
 	__u32	mss_cache;	/* Cached effective mss, not including SACKS */
 	__u16	xmit_size_goal;	/* Goal for segmenting output packets	*/
-	__u16	ext_header_len;	/* Network protocol overhead (IP/IPv6 options) */
+	/* XXX Two bytes hole, try to pack */
 
 	__u32	window_clamp;	/* Maximal window to advertise		*/
 	__u32	rcv_ssthresh;	/* Current window clamp			*/
@@ -295,8 +278,6 @@
 
 	struct sk_buff_head	out_of_order_queue; /* Out of order segments go here */
 
-	struct tcp_func		*af_specific;	/* Operations which are AF_INET{4,6} specific	*/
-
  	__u32	rcv_wnd;	/* Current receiver window		*/
 	__u32	rcv_wup;	/* rcv_nxt on last window update sent	*/
 	__u32	write_seq;	/* Tail(+1) of data held in tcp send buffer */
diff --git a/include/linux/time.h b/include/linux/time.h
index bfbe92d..797ccd8 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -95,6 +95,7 @@
 extern int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue);
 extern int do_getitimer(int which, struct itimerval *value);
 extern void getnstimeofday (struct timespec *tv);
+extern void getnstimestamp(struct timespec *ts);
 
 extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
 
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 1267f88..5744970 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -23,6 +23,7 @@
 #include <linux/workqueue.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_ldisc.h>
+#include <linux/screen_info.h>
 
 #include <asm/system.h>
 
@@ -37,77 +38,6 @@
 #define NR_LDISCS		16
 
 /*
- * These are set up by the setup-routine at boot-time:
- */
-
-struct screen_info {
-	u8  orig_x;		/* 0x00 */
-	u8  orig_y;		/* 0x01 */
-	u16 dontuse1;		/* 0x02 -- EXT_MEM_K sits here */
-	u16 orig_video_page;	/* 0x04 */
-	u8  orig_video_mode;	/* 0x06 */
-	u8  orig_video_cols;	/* 0x07 */
-	u16 unused2;		/* 0x08 */
-	u16 orig_video_ega_bx;	/* 0x0a */
-	u16 unused3;		/* 0x0c */
-	u8  orig_video_lines;	/* 0x0e */
-	u8  orig_video_isVGA;	/* 0x0f */
-	u16 orig_video_points;	/* 0x10 */
-
-	/* VESA graphic mode -- linear frame buffer */
-	u16 lfb_width;		/* 0x12 */
-	u16 lfb_height;		/* 0x14 */
-	u16 lfb_depth;		/* 0x16 */
-	u32 lfb_base;		/* 0x18 */
-	u32 lfb_size;		/* 0x1c */
-	u16 dontuse2, dontuse3;	/* 0x20 -- CL_MAGIC and CL_OFFSET here */
-	u16 lfb_linelength;	/* 0x24 */
-	u8  red_size;		/* 0x26 */
-	u8  red_pos;		/* 0x27 */
-	u8  green_size;		/* 0x28 */
-	u8  green_pos;		/* 0x29 */
-	u8  blue_size;		/* 0x2a */
-	u8  blue_pos;		/* 0x2b */
-	u8  rsvd_size;		/* 0x2c */
-	u8  rsvd_pos;		/* 0x2d */
-	u16 vesapm_seg;		/* 0x2e */
-	u16 vesapm_off;		/* 0x30 */
-	u16 pages;		/* 0x32 */
-	u16 vesa_attributes;	/* 0x34 */
-	u32  capabilities;      /* 0x36 */
-				/* 0x3a -- 0x3f reserved for future expansion */
-};
-
-extern struct screen_info screen_info;
-
-#define ORIG_X			(screen_info.orig_x)
-#define ORIG_Y			(screen_info.orig_y)
-#define ORIG_VIDEO_MODE		(screen_info.orig_video_mode)
-#define ORIG_VIDEO_COLS 	(screen_info.orig_video_cols)
-#define ORIG_VIDEO_EGA_BX	(screen_info.orig_video_ega_bx)
-#define ORIG_VIDEO_LINES	(screen_info.orig_video_lines)
-#define ORIG_VIDEO_ISVGA	(screen_info.orig_video_isVGA)
-#define ORIG_VIDEO_POINTS       (screen_info.orig_video_points)
-
-#define VIDEO_TYPE_MDA		0x10	/* Monochrome Text Display	*/
-#define VIDEO_TYPE_CGA		0x11	/* CGA Display 			*/
-#define VIDEO_TYPE_EGAM		0x20	/* EGA/VGA in Monochrome Mode	*/
-#define VIDEO_TYPE_EGAC		0x21	/* EGA in Color Mode		*/
-#define VIDEO_TYPE_VGAC		0x22	/* VGA+ in Color Mode		*/
-#define VIDEO_TYPE_VLFB		0x23	/* VESA VGA in graphic mode	*/
-
-#define VIDEO_TYPE_PICA_S3	0x30	/* ACER PICA-61 local S3 video	*/
-#define VIDEO_TYPE_MIPS_G364	0x31    /* MIPS Magnum 4000 G364 video  */
-#define VIDEO_TYPE_SGI          0x33    /* Various SGI graphics hardware */
-
-#define VIDEO_TYPE_TGAC		0x40	/* DEC TGA */
-
-#define VIDEO_TYPE_SUN          0x50    /* Sun frame buffer. */
-#define VIDEO_TYPE_SUNPCI       0x51    /* Sun PCI based frame buffer. */
-
-#define VIDEO_TYPE_PMAC		0x60	/* PowerMacintosh frame buffer. */
-
-/*
  * This character is the same as _POSIX_VDISABLE: it cannot be used as
  * a c_cc[] character, but indicates that a particular special character
  * isn't in use (eg VINTR has no character etc)
diff --git a/include/linux/udf_fs.h b/include/linux/udf_fs.h
index 46e2bb9..36c684e 100644
--- a/include/linux/udf_fs.h
+++ b/include/linux/udf_fs.h
@@ -13,11 +13,6 @@
  *    http://www.osta.org/ *    http://www.ecma.ch/
  *    http://www.iso.org/
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/include/linux/udf_fs_i.h b/include/linux/udf_fs_i.h
index 62b15a4..1e75084 100644
--- a/include/linux/udf_fs_i.h
+++ b/include/linux/udf_fs_i.h
@@ -3,11 +3,6 @@
  *
  * This file is intended for the Linux kernel/module. 
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/include/linux/udf_fs_sb.h b/include/linux/udf_fs_sb.h
index 1966a6d..b15ff2e 100644
--- a/include/linux/udf_fs_sb.h
+++ b/include/linux/udf_fs_sb.h
@@ -3,11 +3,6 @@
  * 
  * This include file is for the Linux kernel/module.
  *
- * CONTACTS
- *	E-mail regarding any portion of the Linux UDF file system should be
- *	directed to the development team mailing list (run by majordomo):
- *		linux_udf@hpesjro.fc.hp.com
- *
  * COPYRIGHT
  *	This file is distributed under the terms of the GNU General Public
  *	License (GPL). Copies of the GPL can be obtained from:
diff --git a/include/linux/udp.h b/include/linux/udp.h
index b60e0b4..85a5565 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -35,10 +35,10 @@
 #define UDP_ENCAP_ESPINUDP	2 /* draft-ietf-ipsec-udp-encaps-06 */
 
 #ifdef __KERNEL__
-
 #include <linux/config.h>
-#include <net/sock.h>
-#include <linux/ip.h>
+#include <linux/types.h>
+
+#include <net/inet_sock.h>
 
 struct udp_sock {
 	/* inet_sock has to be the first member */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index d81b050..827cc6d 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -225,7 +225,7 @@
  * Device drivers should not attempt to activate configurations.  The choice
  * of which configuration to install is a policy decision based on such
  * considerations as available power, functionality provided, and the user's
- * desires (expressed through hotplug scripts).  However, drivers can call
+ * desires (expressed through userspace tools).  However, drivers can call
  * usb_reset_configuration() to reinitialize the current configuration and
  * all its interfaces.
  */
@@ -329,8 +329,6 @@
 	struct usb_tt	*tt; 		/* low/full speed dev, highspeed hub */
 	int		ttport;		/* device port on that tt hub */
 
-	struct semaphore serialize;
-
 	unsigned int toggle[2];		/* one bit for each endpoint
 					 * ([0] = IN, [1] = OUT) */
 
@@ -349,6 +347,9 @@
 
 	char **rawdescriptors;		/* Raw descriptors for each config */
 
+	unsigned short bus_mA;		/* Current available from the bus */
+	u8 portnum;			/* Parent port number (origin 1) */
+
 	int have_langid;		/* whether string_langid is valid */
 	int string_langid;		/* language ID for strings */
 
@@ -377,11 +378,12 @@
 extern struct usb_device *usb_get_dev(struct usb_device *dev);
 extern void usb_put_dev(struct usb_device *dev);
 
-extern void usb_lock_device(struct usb_device *udev);
-extern int usb_trylock_device(struct usb_device *udev);
+/* USB device locking */
+#define usb_lock_device(udev)		down(&(udev)->dev.sem)
+#define usb_unlock_device(udev)		up(&(udev)->dev.sem)
+#define usb_trylock_device(udev)	down_trylock(&(udev)->dev.sem)
 extern int usb_lock_device_for_reset(struct usb_device *udev,
 		struct usb_interface *iface);
-extern void usb_unlock_device(struct usb_device *udev);
 
 /* USB port reset for device reinitialization */
 extern int usb_reset_device(struct usb_device *dev);
@@ -529,10 +531,13 @@
 
 /* ----------------------------------------------------------------------- */
 
+struct usb_dynids {
+	spinlock_t lock;
+	struct list_head list;
+};
+
 /**
  * struct usb_driver - identifies USB driver to usbcore
- * @owner: Pointer to the module owner of this driver; initialize
- *	it using THIS_MODULE.
  * @name: The driver name should be unique among USB drivers,
  *	and should normally be the same as the module name.
  * @probe: Called to see if the driver is willing to manage a particular
@@ -553,7 +558,11 @@
  * @id_table: USB drivers use ID table to support hotplugging.
  *	Export this with MODULE_DEVICE_TABLE(usb,...).  This must be set
  *	or your driver's probe function will never get called.
+ * @dynids: used internally to hold the list of dynamically added device
+ *	ids for this driver.
  * @driver: the driver model core driver structure.
+ * @no_dynamic_id: if set to 1, the USB core will not allow dynamic ids to be
+ *	added to this driver by preventing the sysfs file from being created.
  *
  * USB drivers must provide a name, probe() and disconnect() methods,
  * and an id_table.  Other driver fields are optional.
@@ -571,8 +580,6 @@
  * them as necessary, and blocking until the unlinks complete).
  */
 struct usb_driver {
-	struct module *owner;
-
 	const char *name;
 
 	int (*probe) (struct usb_interface *intf,
@@ -588,7 +595,9 @@
 
 	const struct usb_device_id *id_table;
 
+	struct usb_dynids dynids;
 	struct device_driver driver;
+	unsigned int no_dynamic_id:1;
 };
 #define	to_usb_driver(d) container_of(d, struct usb_driver, driver)
 
@@ -614,7 +623,11 @@
  * use these in module_init()/module_exit()
  * and don't forget MODULE_DEVICE_TABLE(usb, ...)
  */
-extern int usb_register(struct usb_driver *);
+int usb_register_driver(struct usb_driver *, struct module *);
+static inline int usb_register(struct usb_driver *driver)
+{
+	return usb_register_driver(driver, THIS_MODULE);
+}
 extern void usb_deregister(struct usb_driver *);
 
 extern int usb_register_dev(struct usb_interface *intf,
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h
new file mode 100644
index 0000000..b2d0898
--- /dev/null
+++ b/include/linux/usb_usual.h
@@ -0,0 +1,126 @@
+/*
+ * Interface to the libusual.
+ *
+ * Copyright (c) 2005 Pete Zaitcev <zaitcev@redhat.com>
+ * Copyright (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
+ * Copyright (c) 1999 Michael Gee (michael@linuxspecific.com)
+ */
+
+#ifndef __LINUX_USB_USUAL_H
+#define __LINUX_USB_USUAL_H
+
+#include <linux/config.h>
+
+/* We should do this for cleanliness... But other usb_foo.h do not do this. */
+/* #include <linux/usb.h> */
+
+/*
+ * The flags field, which we store in usb_device_id.driver_info.
+ * It is compatible with the old usb-storage flags in lower 24 bits.
+ */
+
+/*
+ * Static flag definitions.  We use this roundabout technique so that the
+ * proc_info() routine can automatically display a message for each flag.
+ */
+#define US_DO_ALL_FLAGS						\
+	US_FLAG(SINGLE_LUN,	0x00000001)			\
+		/* allow access to only LUN 0 */		\
+	US_FLAG(NEED_OVERRIDE,	0x00000002)			\
+		/* unusual_devs entry is necessary */		\
+	US_FLAG(SCM_MULT_TARG,	0x00000004)			\
+		/* supports multiple targets */			\
+	US_FLAG(FIX_INQUIRY,	0x00000008)			\
+		/* INQUIRY response needs faking */		\
+	US_FLAG(FIX_CAPACITY,	0x00000010)			\
+		/* READ CAPACITY response too big */		\
+	US_FLAG(IGNORE_RESIDUE,	0x00000020)			\
+		/* reported residue is wrong */			\
+	US_FLAG(BULK32,		0x00000040)			\
+		/* Uses 32-byte CBW length */			\
+	US_FLAG(NOT_LOCKABLE,	0x00000080)			\
+		/* PREVENT/ALLOW not supported */		\
+	US_FLAG(GO_SLOW,	0x00000100)			\
+		/* Need delay after Command phase */		\
+	US_FLAG(NO_WP_DETECT,	0x00000200)			\
+		/* Don't check for write-protect */		\
+
+#define US_FLAG(name, value)	US_FL_##name = value ,
+enum { US_DO_ALL_FLAGS };
+#undef US_FLAG
+
+/*
+ * The bias field for libusual and friends.
+ */
+#define USB_US_TYPE_NONE   0
+#define USB_US_TYPE_STOR   1		/* usb-storage */
+#define USB_US_TYPE_UB     2		/* ub */
+
+#define USB_US_TYPE(flags) 		(((flags) >> 24) & 0xFF)
+#define USB_US_ORIG_FLAGS(flags)	((flags) & 0x00FFFFFF)
+
+/*
+ * This is probably not the best place to keep these constants, conceptually.
+ * But it's the only header included into all places which need them.
+ */
+
+/* Sub Classes */
+
+#define US_SC_RBC	0x01		/* Typically, flash devices */
+#define US_SC_8020	0x02		/* CD-ROM */
+#define US_SC_QIC	0x03		/* QIC-157 Tapes */
+#define US_SC_UFI	0x04		/* Floppy */
+#define US_SC_8070	0x05		/* Removable media */
+#define US_SC_SCSI	0x06		/* Transparent */
+#define US_SC_ISD200    0x07		/* ISD200 ATA */
+#define US_SC_MIN	US_SC_RBC
+#define US_SC_MAX	US_SC_ISD200
+
+#define US_SC_DEVICE	0xff		/* Use device's value */
+
+/* Protocols */
+
+#define US_PR_CBI	0x00		/* Control/Bulk/Interrupt */
+#define US_PR_CB	0x01		/* Control/Bulk w/o interrupt */
+#define US_PR_BULK	0x50		/* bulk only */
+#ifdef CONFIG_USB_STORAGE_USBAT
+#define US_PR_USBAT	0x80		/* SCM-ATAPI bridge */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR09
+#define US_PR_EUSB_SDDR09	0x81	/* SCM-SCSI bridge for SDDR-09 */
+#endif
+#ifdef CONFIG_USB_STORAGE_SDDR55
+#define US_PR_SDDR55	0x82		/* SDDR-55 (made up) */
+#endif
+#define US_PR_DPCM_USB  0xf0		/* Combination CB/SDDR09 */
+#ifdef CONFIG_USB_STORAGE_FREECOM
+#define US_PR_FREECOM   0xf1		/* Freecom */
+#endif
+#ifdef CONFIG_USB_STORAGE_DATAFAB
+#define US_PR_DATAFAB   0xf2		/* Datafab chipsets */
+#endif
+#ifdef CONFIG_USB_STORAGE_JUMPSHOT
+#define US_PR_JUMPSHOT  0xf3		/* Lexar Jumpshot */
+#endif
+#ifdef CONFIG_USB_STORAGE_ALAUDA
+#define US_PR_ALAUDA    0xf4		/* Alauda chipsets */
+#endif
+
+#define US_PR_DEVICE	0xff		/* Use device's value */
+
+/*
+ */
+#ifdef CONFIG_USB_LIBUSUAL
+
+extern struct usb_device_id storage_usb_ids[];
+extern void usb_usual_set_present(int type);
+extern void usb_usual_clear_present(int type);
+extern int usb_usual_check_type(const struct usb_device_id *, int type);
+#else
+
+#define usb_usual_set_present(t)	do { } while(0)
+#define usb_usual_clear_present(t)	do { } while(0)
+#define usb_usual_check_type(id, t)	(0)
+#endif /* CONFIG_USB_LIBUSUAL */
+
+#endif /* __LINUX_USB_USUAL_H */
diff --git a/include/linux/wavefront.h b/include/linux/wavefront.h
index 61bd0fd..51ab3c9 100644
--- a/include/linux/wavefront.h
+++ b/include/linux/wavefront.h
@@ -434,22 +434,22 @@
 } wavefront_multisample;
 
 typedef struct wf_alias {
-    INT16 OriginalSample __attribute__ ((packed));
+    INT16 OriginalSample;
 
-    struct wf_sample_offset sampleStartOffset __attribute__ ((packed));
-    struct wf_sample_offset loopStartOffset __attribute__ ((packed));
-    struct wf_sample_offset sampleEndOffset __attribute__ ((packed));
-    struct wf_sample_offset loopEndOffset __attribute__ ((packed));
+    struct wf_sample_offset sampleStartOffset;
+    struct wf_sample_offset loopStartOffset;
+    struct wf_sample_offset sampleEndOffset;
+    struct wf_sample_offset loopEndOffset;
 
-    INT16  FrequencyBias __attribute__ ((packed));
+    INT16  FrequencyBias;
 
-    UCHAR8 SampleResolution:2  __attribute__ ((packed));
-    UCHAR8 Unused1:1  __attribute__ ((packed));
-    UCHAR8 Loop:1 __attribute__ ((packed));
-    UCHAR8 Bidirectional:1  __attribute__ ((packed));
-    UCHAR8 Unused2:1 __attribute__ ((packed));
-    UCHAR8 Reverse:1 __attribute__ ((packed));
-    UCHAR8 Unused3:1 __attribute__ ((packed)); 
+    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
@@ -460,8 +460,8 @@
        standard 16->32 bit issues.
     */
 
-    UCHAR8 sixteen_bit_padding __attribute__ ((packed));
-} wavefront_alias;
+    UCHAR8 sixteen_bit_padding;
+} __attribute__((packed)) wavefront_alias;
 
 typedef struct wf_drum {
     UCHAR8 PatchNumber;
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index ac39d04..86b1113 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -65,6 +65,7 @@
 extern int FASTCALL(schedule_delayed_work(struct work_struct *work, unsigned long delay));
 
 extern int schedule_delayed_work_on(int cpu, struct work_struct *work, unsigned long delay);
+extern int schedule_on_each_cpu(void (*func)(void *info), void *info);
 extern void flush_scheduled_work(void);
 extern int current_is_keventd(void);
 extern int keventd_up(void);
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 343d883..beaef5c 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -53,19 +53,14 @@
 	loff_t start;
 	loff_t end;
 
-	unsigned nonblocking:1;			/* Don't get stuck on request queues */
-	unsigned encountered_congestion:1;	/* An output: a queue is full */
-	unsigned for_kupdate:1;			/* A kupdate writeback */
-	unsigned for_reclaim:1;			/* Invoked from the page allocator */
+	unsigned nonblocking:1;		/* Don't get stuck on request queues */
+	unsigned encountered_congestion:1; /* An output: a queue is full */
+	unsigned for_kupdate:1;		/* A kupdate writeback */
+	unsigned for_reclaim:1;		/* Invoked from the page allocator */
+	unsigned for_writepages:1;	/* This is a writepages() call */
 };
 
 /*
- * ->writepage() return values (make these much larger than a pagesize, in
- * case some fs is returning number-of-bytes-written from writepage)
- */
-#define WRITEPAGE_ACTIVATE	0x80000	/* IO was not started: activate page */
-
-/*
  * fs/fs-writeback.c
  */	
 void writeback_inodes(struct writeback_control *wbc);
@@ -108,7 +103,9 @@
 int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
 int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
 int sync_page_range(struct inode *inode, struct address_space *mapping,
-			loff_t pos, size_t count);
+			loff_t pos, loff_t count);
+int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
+			   loff_t pos, loff_t count);
 
 /* pdflush.c */
 extern int nr_pdflush_threads;	/* Global so it can be exported to sysctl
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 0fb077d..82fbb75 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -27,6 +27,22 @@
 	__u8		proto;
 };
 
+struct xfrm_sec_ctx {
+	__u8	ctx_doi;
+	__u8	ctx_alg;
+	__u16	ctx_len;
+	__u32	ctx_sid;
+	char	ctx_str[0];
+};
+
+/* Security Context Domains of Interpretation */
+#define XFRM_SC_DOI_RESERVED 0
+#define XFRM_SC_DOI_LSM 1
+
+/* Security Context Algorithms */
+#define XFRM_SC_ALG_RESERVED 0
+#define XFRM_SC_ALG_SELINUX 1
+
 /* Selector, used as selector both on policy rules (SPD) and SAs. */
 
 struct xfrm_selector
@@ -146,6 +162,18 @@
 
 #define XFRM_NR_MSGTYPES (XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)
 
+/*
+ * Generic LSM security context for comunicating to user space
+ * NOTE: Same format as sadb_x_sec_ctx
+ */
+struct xfrm_user_sec_ctx {
+	__u16			len;
+	__u16			exttype;
+	__u8			ctx_alg;  /* LSMs: e.g., selinux == 1 */
+	__u8			ctx_doi;
+	__u16			ctx_len;
+};
+
 struct xfrm_user_tmpl {
 	struct xfrm_id		id;
 	__u16			family;
@@ -176,6 +204,7 @@
 	XFRMA_TMPL,		/* 1 or more struct xfrm_user_tmpl */
 	XFRMA_SA,
 	XFRMA_POLICY,
+	XFRMA_SEC_CTX,		/* struct xfrm_sec_ctx */
 	__XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index 2a897c3..2bc634f 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -14,21 +14,21 @@
 #include <linux/vmalloc.h>	/* for vmalloc() */
 #include <linux/mm.h>		/* for vmalloc_to_page() */
 
-#define SAA7146_VERSION_CODE 0x000500   /* 0.5.0 */
+#define SAA7146_VERSION_CODE 0x000500	/* 0.5.0 */
 
 #define saa7146_write(sxy,adr,dat)    writel((dat),(sxy->mem+(adr)))
 #define saa7146_read(sxy,adr)         readl(sxy->mem+(adr))
 
 extern unsigned int saa7146_debug;
 
-//#define DEBUG_PROLOG printk("(0x%08x)(0x%08x) %s: %s(): ",(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,RPS_ADDR0))),(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,IER))),__stringify(KBUILD_MODNAME),__FUNCTION__)
+//#define DEBUG_PROLOG printk("(0x%08x)(0x%08x) %s: %s(): ",(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,RPS_ADDR0))),(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,IER))),KBUILD_MODNAME,__FUNCTION__)
 
 #ifndef DEBUG_VARIABLE
 	#define DEBUG_VARIABLE saa7146_debug
 #endif
 
-#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_MODNAME),__FUNCTION__)
-#define INFO(x) { printk("%s: ",__stringify(KBUILD_MODNAME)); printk x; }
+#define DEBUG_PROLOG printk("%s: %s(): ",KBUILD_MODNAME,__FUNCTION__)
+#define INFO(x) { printk("%s: ",KBUILD_MODNAME); printk x; }
 
 #define ERR(x) { DEBUG_PROLOG; printk x; }
 
@@ -112,7 +112,7 @@
 
 	/* different device locks */
 	spinlock_t			slock;
-        struct semaphore		lock;
+	struct semaphore		lock;
 
 	unsigned char			__iomem *mem;		/* pointer to mapped IO memory */
 	int				revision;	/* chip revision; needed for bug-workarounds*/
@@ -133,7 +133,7 @@
 	void (*vv_callback)(struct saa7146_dev *dev, unsigned long status);
 
 	/* i2c-stuff */
-        struct semaphore	i2c_lock;
+	struct semaphore	i2c_lock;
 	u32			i2c_bitrate;
 	struct saa7146_dma	d_i2c;	/* pointer to i2c memory */
 	wait_queue_head_t	i2c_wq;
diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h
index 6469175..16af929 100644
--- a/include/media/saa7146_vv.h
+++ b/include/media/saa7146_vv.h
@@ -113,7 +113,7 @@
 	/* vbi capture */
 	struct saa7146_dmaqueue		vbi_q;
 	/* vbi workaround interrupt queue */
-        wait_queue_head_t		vbi_wq;
+	wait_queue_head_t		vbi_wq;
 	int				vbi_fieldcount;
 	struct saa7146_fh		*vbi_streaming;
 
@@ -181,10 +181,10 @@
 };
 
 struct saa7146_use_ops  {
-        void (*init)(struct saa7146_dev *, struct saa7146_vv *);
-        int(*open)(struct saa7146_dev *, struct file *);
-        void (*release)(struct saa7146_dev *, struct file *);
-        void (*irq_done)(struct saa7146_dev *, unsigned long status);
+	void (*init)(struct saa7146_dev *, struct saa7146_vv *);
+	int(*open)(struct saa7146_dev *, struct file *);
+	void (*release)(struct saa7146_dev *, struct file *);
+	void (*irq_done)(struct saa7146_dev *, unsigned long status);
 	ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
 };
 
diff --git a/include/media/tuner.h b/include/media/tuner.h
index faa0f8e..b37cde6 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -218,14 +218,15 @@
 extern int tea5767_autodetection(struct i2c_client *c);
 
 #define tuner_warn(fmt, arg...) do {\
-	printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->name, \
+	printk(KERN_WARNING "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \
 			t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
 #define tuner_info(fmt, arg...) do {\
-	printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->name, \
+	printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.driver->driver.name, \
 			t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
 #define tuner_dbg(fmt, arg...) do {\
 	if (tuner_debug) \
-		printk(KERN_DEBUG "%s %d-%04x: " fmt, t->i2c.driver->name, \
+		printk(KERN_DEBUG "%s %d-%04x: " fmt, \
+			t->i2c.driver->driver.name, \
 			t->i2c.adapter->nr, t->i2c.addr , ##arg); } while (0)
 
 #endif /* __KERNEL__ */
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
index e2035c7..e9fc1a7 100644
--- a/include/media/tveeprom.h
+++ b/include/media/tveeprom.h
@@ -4,12 +4,15 @@
 struct tveeprom {
 	u32 has_radio;
 	u32 has_ir;     /* 0: no IR, 1: IR present, 2: unknown */
+	u32 has_MAC_address; /* 0: no MAC, 1: MAC present, 2: unknown */
 
 	u32 tuner_type;
 	u32 tuner_formats;
+	u32 tuner_hauppauge_model;
 
 	u32 tuner2_type;
 	u32 tuner2_formats;
+	u32 tuner2_hauppauge_model;
 
 	u32 digitizer;
 	u32 digitizer_formats;
@@ -21,6 +24,7 @@
 	u32 revision;
 	u32 serial_number;
 	char rev_str[5];
+	u8 MAC_address[6];
 };
 
 void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index b5d785a..bfc1779 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -13,7 +13,7 @@
 #define UNIX_HASH_SIZE	256
 
 extern struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
-extern rwlock_t unix_table_lock;
+extern spinlock_t unix_table_lock;
 
 extern atomic_t unix_tot_inflight;
 
@@ -58,10 +58,10 @@
 #define UNIXCB(skb) 	(*(struct unix_skb_parms*)&((skb)->cb))
 #define UNIXCREDS(skb)	(&UNIXCB((skb)).creds)
 
-#define unix_state_rlock(s)	read_lock(&unix_sk(s)->lock)
-#define unix_state_runlock(s)	read_unlock(&unix_sk(s)->lock)
-#define unix_state_wlock(s)	write_lock(&unix_sk(s)->lock)
-#define unix_state_wunlock(s)	write_unlock(&unix_sk(s)->lock)
+#define unix_state_rlock(s)	spin_lock(&unix_sk(s)->lock)
+#define unix_state_runlock(s)	spin_unlock(&unix_sk(s)->lock)
+#define unix_state_wlock(s)	spin_lock(&unix_sk(s)->lock)
+#define unix_state_wunlock(s)	spin_unlock(&unix_sk(s)->lock)
 
 #ifdef __KERNEL__
 /* The AF_UNIX socket */
@@ -76,7 +76,7 @@
         struct sock		*other;
         struct sock		*gc_tree;
         atomic_t                inflight;
-        rwlock_t                lock;
+        spinlock_t		lock;
         wait_queue_head_t       peer_wait;
 };
 #define unix_sk(__sk) ((struct unix_sock *)__sk)
diff --git a/include/net/atmclip.h b/include/net/atmclip.h
index 47048b1..90fcc98 100644
--- a/include/net/atmclip.h
+++ b/include/net/atmclip.h
@@ -7,7 +7,6 @@
 #define _ATMCLIP_H
 
 #include <linux/netdevice.h>
-#include <linux/skbuff.h>
 #include <linux/atm.h>
 #include <linux/atmdev.h>
 #include <linux/atmarp.h>
@@ -18,6 +17,7 @@
 #define CLIP_VCC(vcc) ((struct clip_vcc *) ((vcc)->user_back))
 #define NEIGH2ENTRY(neigh) ((struct atmarp_entry *) (neigh)->primary_key)
 
+struct sk_buff;
 
 struct clip_vcc {
 	struct atm_vcc	*vcc;		/* VCC descriptor */
diff --git a/include/net/dn.h b/include/net/dn.h
index c1dbbd2..a4b6168 100644
--- a/include/net/dn.h
+++ b/include/net/dn.h
@@ -234,4 +234,8 @@
 extern int decnet_dr_count;
 extern int decnet_no_fc_max_cwnd;
 
+extern int sysctl_decnet_mem[3];
+extern int sysctl_decnet_wmem[3];
+extern int sysctl_decnet_rmem[3];
+
 #endif /* _NET_DN_H */
diff --git a/include/net/dn_dev.h b/include/net/dn_dev.h
index 86e8e86..5a86e78 100644
--- a/include/net/dn_dev.h
+++ b/include/net/dn_dev.h
@@ -88,8 +88,8 @@
 	struct net_device *dev;
 	struct dn_dev_parms parms;
 	char use_long;
-        struct timer_list timer;
-        unsigned long t3;
+	struct timer_list timer;
+	unsigned long t3;
 	struct neigh_parms *neigh_parms;
 	unsigned char addr[ETH_ALEN];
 	struct neighbour *router; /* Default router on circuit */
@@ -99,57 +99,57 @@
 
 struct dn_short_packet
 {
-	unsigned char   msgflg          __attribute__((packed));
-        unsigned short  dstnode         __attribute__((packed));
-        unsigned short  srcnode         __attribute__((packed));
-        unsigned char   forward         __attribute__((packed));
-};
+	unsigned char   msgflg;
+	unsigned short  dstnode;
+	unsigned short  srcnode;
+	unsigned char   forward;
+} __attribute__((packed));
 
 struct dn_long_packet
 {
-	unsigned char   msgflg          __attribute__((packed));
-        unsigned char   d_area          __attribute__((packed));
-        unsigned char   d_subarea       __attribute__((packed));
-        unsigned char   d_id[6]         __attribute__((packed));
-        unsigned char   s_area          __attribute__((packed));
-        unsigned char   s_subarea       __attribute__((packed));
-        unsigned char   s_id[6]         __attribute__((packed));
-        unsigned char   nl2             __attribute__((packed));
-        unsigned char   visit_ct        __attribute__((packed));
-        unsigned char   s_class         __attribute__((packed));
-        unsigned char   pt              __attribute__((packed));
-};
+	unsigned char   msgflg;
+	unsigned char   d_area;
+	unsigned char   d_subarea;
+	unsigned char   d_id[6];
+	unsigned char   s_area;
+	unsigned char   s_subarea;
+	unsigned char   s_id[6];
+	unsigned char   nl2;
+	unsigned char   visit_ct;
+	unsigned char   s_class;
+	unsigned char   pt;
+} __attribute__((packed));
 
 /*------------------------- DRP - Routing messages ---------------------*/
 
 struct endnode_hello_message
 {
-	unsigned char   msgflg          __attribute__((packed));
-        unsigned char   tiver[3]        __attribute__((packed));
-        unsigned char   id[6]           __attribute__((packed));
-        unsigned char   iinfo           __attribute__((packed));
-        unsigned short  blksize         __attribute__((packed));
-        unsigned char   area            __attribute__((packed));
-        unsigned char   seed[8]         __attribute__((packed));
-        unsigned char   neighbor[6]     __attribute__((packed));
-        unsigned short  timer           __attribute__((packed));
-        unsigned char   mpd             __attribute__((packed));
-        unsigned char   datalen         __attribute__((packed));
-        unsigned char   data[2]         __attribute__((packed));
-};
+	unsigned char   msgflg;
+	unsigned char   tiver[3];
+	unsigned char   id[6];
+	unsigned char   iinfo;
+	unsigned short  blksize;
+	unsigned char   area;
+	unsigned char   seed[8];
+	unsigned char   neighbor[6];
+	unsigned short  timer;
+	unsigned char   mpd;
+	unsigned char   datalen;
+	unsigned char   data[2];
+} __attribute__((packed));
 
 struct rtnode_hello_message
 {
-	unsigned char   msgflg          __attribute__((packed));
-        unsigned char   tiver[3]        __attribute__((packed));
-        unsigned char   id[6]           __attribute__((packed));
-        unsigned char   iinfo           __attribute__((packed));
-        unsigned short  blksize         __attribute__((packed));
-        unsigned char   priority        __attribute__((packed));
-        unsigned char   area            __attribute__((packed));
-        unsigned short  timer           __attribute__((packed));
-        unsigned char   mpd             __attribute__((packed));
-};
+	unsigned char   msgflg;
+	unsigned char   tiver[3];
+	unsigned char   id[6];
+	unsigned char   iinfo;
+	unsigned short  blksize;
+	unsigned char   priority;
+	unsigned char   area;
+	unsigned short  timer;
+	unsigned char   mpd;
+} __attribute__((packed));
 
 
 extern void dn_dev_init(void);
diff --git a/include/net/dn_nsp.h b/include/net/dn_nsp.h
index 1ba03be..e6182b8 100644
--- a/include/net/dn_nsp.h
+++ b/include/net/dn_nsp.h
@@ -72,78 +72,78 @@
 
 struct nsp_data_seg_msg
 {
-	unsigned char   msgflg          __attribute__((packed));
-	unsigned short  dstaddr         __attribute__((packed));
-	unsigned short  srcaddr         __attribute__((packed));
-};
+	unsigned char   msgflg;
+	unsigned short  dstaddr;
+	unsigned short  srcaddr;
+} __attribute__((packed));
 
 struct nsp_data_opt_msg
 {
-	unsigned short  acknum          __attribute__((packed));
-	unsigned short  segnum          __attribute__((packed));
-	unsigned short  lsflgs          __attribute__((packed));
-};
+	unsigned short  acknum;
+	unsigned short  segnum;
+	unsigned short  lsflgs;
+} __attribute__((packed));
 
 struct nsp_data_opt_msg1
 {
-	unsigned short  acknum          __attribute__((packed));
-	unsigned short  segnum          __attribute__((packed));
-};
+	unsigned short  acknum;
+	unsigned short  segnum;
+} __attribute__((packed));
 
 
 /* Acknowledgment Message (data/other data)                             */
 struct nsp_data_ack_msg
 {
-	unsigned char   msgflg          __attribute__((packed));
-	unsigned short  dstaddr         __attribute__((packed));
-	unsigned short  srcaddr         __attribute__((packed));
-	unsigned short  acknum          __attribute__((packed));
-};
+	unsigned char   msgflg;
+	unsigned short  dstaddr;
+	unsigned short  srcaddr;
+	unsigned short  acknum;
+} __attribute__((packed));
 
 /* Connect Acknowledgment Message */
 struct  nsp_conn_ack_msg
 {
-	unsigned char   msgflg          __attribute__((packed));
-	unsigned short  dstaddr         __attribute__((packed));
-};
+	unsigned char   msgflg;
+	unsigned short  dstaddr;
+} __attribute__((packed));
 
 
 /* Connect Initiate/Retransmit Initiate/Connect Confirm */
 struct  nsp_conn_init_msg
 {
-	unsigned char   msgflg          __attribute__((packed));
+	unsigned char   msgflg;
 #define NSP_CI      0x18            /* Connect Initiate     */
 #define NSP_RCI     0x68            /* Retrans. Conn Init   */
-	unsigned short  dstaddr         __attribute__((packed));
-        unsigned short  srcaddr         __attribute__((packed));
-        unsigned char   services        __attribute__((packed));
+	unsigned short  dstaddr;
+	unsigned short  srcaddr;
+	unsigned char   services;
 #define NSP_FC_NONE   0x00            /* Flow Control None    */
 #define NSP_FC_SRC    0x04            /* Seg Req. Count       */
 #define NSP_FC_SCMC   0x08            /* Sess. Control Mess   */
 #define NSP_FC_MASK   0x0c            /* FC type mask         */
-	unsigned char   info            __attribute__((packed));
-        unsigned short  segsize         __attribute__((packed));
-};
+	unsigned char   info;
+	unsigned short  segsize;
+} __attribute__((packed));
 
 /* Disconnect Initiate/Disconnect Confirm */
 struct  nsp_disconn_init_msg
 {
-	unsigned char   msgflg          __attribute__((packed));
-        unsigned short  dstaddr         __attribute__((packed));
-        unsigned short  srcaddr         __attribute__((packed));
-        unsigned short  reason          __attribute__((packed));
-};
+	unsigned char   msgflg;
+	unsigned short  dstaddr;
+	unsigned short  srcaddr;
+	unsigned short  reason;
+} __attribute__((packed));
 
 
 
 struct  srcobj_fmt
 {
-	char            format          __attribute__((packed));
-        unsigned char   task            __attribute__((packed));
-        unsigned short  grpcode         __attribute__((packed));
-        unsigned short  usrcode         __attribute__((packed));
-        char            dlen            __attribute__((packed));
-};
+	char            format;
+	unsigned char   task;
+	unsigned short  grpcode;
+	unsigned short  usrcode;
+	char            dlen;
+} __attribute__((packed));
 
 /*
  * A collection of functions for manipulating the sequence
diff --git a/include/net/dst.h b/include/net/dst.h
index 6c196a5..5161e89 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -9,6 +9,7 @@
 #define _NET_DST_H
 
 #include <linux/config.h>
+#include <linux/netdevice.h>
 #include <linux/rtnetlink.h>
 #include <linux/rcupdate.h>
 #include <linux/jiffies.h>
@@ -224,16 +225,7 @@
 /* Output packet to network from transport.  */
 static inline int dst_output(struct sk_buff *skb)
 {
-	int err;
-
-	for (;;) {
-		err = skb->dst->output(skb);
-
-		if (likely(err == 0))
-			return err;
-		if (unlikely(err != NET_XMIT_BYPASS))
-			return err;
-	}
+	return skb->dst->output(skb);
 }
 
 /* Input packet from network to transport.  */
diff --git a/include/net/flow.h b/include/net/flow.h
index 9a5c94b..ec7eb86 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -84,11 +84,12 @@
 #define FLOW_DIR_OUT	1
 #define FLOW_DIR_FWD	2
 
-typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
+struct sock;
+typedef void (*flow_resolve_t)(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
 			       void **objp, atomic_t **obj_refp);
 
-extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
-			       flow_resolve_t resolver);
+extern void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
+	 		       flow_resolve_t resolver);
 extern void flow_cache_flush(void);
 extern atomic_t flow_cache_genid;
 
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 52d8b1a..c5b96b2 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -60,7 +60,7 @@
  */
 struct genl_ops
 {
-	unsigned int		cmd;
+	u8			cmd;
 	unsigned int		flags;
 	struct nla_policy	*policy;
 	int		       (*doit)(struct sk_buff *skb,
diff --git a/include/net/icmp.h b/include/net/icmp.h
index 6cdebee..e7c3f20 100644
--- a/include/net/icmp.h
+++ b/include/net/icmp.h
@@ -20,12 +20,9 @@
 
 #include <linux/config.h>
 #include <linux/icmp.h>
-#include <linux/skbuff.h>
 
-#include <net/sock.h>
-#include <net/protocol.h>
+#include <net/inet_sock.h>
 #include <net/snmp.h>
-#include <linux/ip.h>
 
 struct icmp_err {
   int		errno;
@@ -38,6 +35,10 @@
 #define ICMP_INC_STATS_BH(field)	SNMP_INC_STATS_BH(icmp_statistics, field)
 #define ICMP_INC_STATS_USER(field) 	SNMP_INC_STATS_USER(icmp_statistics, field)
 
+struct dst_entry;
+struct net_proto_family;
+struct sk_buff;
+
 extern void	icmp_send(struct sk_buff *skb_in,  int type, int code, u32 info);
 extern int	icmp_rcv(struct sk_buff *skb);
 extern int	icmp_ioctl(struct sock *sk, int cmd, unsigned long arg);
diff --git a/include/net/ieee80211_crypt.h b/include/net/ieee80211_crypt.h
index 225fc751..03b766a 100644
--- a/include/net/ieee80211_crypt.h
+++ b/include/net/ieee80211_crypt.h
@@ -23,12 +23,17 @@
 #ifndef IEEE80211_CRYPT_H
 #define IEEE80211_CRYPT_H
 
-#include <linux/skbuff.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <asm/atomic.h>
 
 enum {
 	IEEE80211_CRYPTO_TKIP_COUNTERMEASURES = (1 << 0),
 };
 
+struct sk_buff;
+struct module;
+
 struct ieee80211_crypto_ops {
 	const char *name;
 	struct list_head list;
@@ -87,6 +92,8 @@
 	atomic_t refcnt;
 };
 
+struct ieee80211_device;
+
 int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
 int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
 struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index e97a9ac..eb8afe3 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -24,6 +24,7 @@
 #define IF_RA_MANAGED	0x40
 #define IF_RA_RCVD	0x20
 #define IF_RS_SENT	0x10
+#define IF_READY	0x80000000
 
 /* prefix flags */
 #define IF_PREFIX_ONLINK	0x01
@@ -82,6 +83,7 @@
 	struct in6_addr		addr;
 	int			ifindex;
 	struct ipv6_mc_socklist *next;
+	rwlock_t		sflock;
 	unsigned int		sfmode;		/* MCAST_{INCLUDE,EXCLUDE} */
 	struct ip6_sf_socklist	*sflist;
 };
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h
new file mode 100644
index 0000000..b33b438
--- /dev/null
+++ b/include/net/inet6_connection_sock.h
@@ -0,0 +1,42 @@
+/*
+ * NET		Generic infrastructure for INET6 connection oriented protocols.
+ *
+ * Authors:	Many people, see the TCPv6 sources
+ *
+ * 		From code originally in TCPv6
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+#ifndef _INET6_CONNECTION_SOCK_H
+#define _INET6_CONNECTION_SOCK_H
+
+#include <linux/types.h>
+
+struct in6_addr;
+struct inet_bind_bucket;
+struct request_sock;
+struct sk_buff;
+struct sock;
+struct sockaddr;
+
+extern int inet6_csk_bind_conflict(const struct sock *sk,
+				   const struct inet_bind_bucket *tb);
+
+extern struct request_sock *inet6_csk_search_req(const struct sock *sk,
+						 struct request_sock ***prevp,
+						 const __u16 rport,
+						 const struct in6_addr *raddr,
+						 const struct in6_addr *laddr,
+						 const int iif);
+
+extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
+					   struct request_sock *req,
+					   const unsigned long timeout);
+
+extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
+
+extern int inet6_csk_xmit(struct sk_buff *skb, int ipfragok);
+#endif /* _INET6_CONNECTION_SOCK_H */
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index 5a2beed..25f708f 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -48,6 +48,32 @@
 	return inet6_ehashfn(laddr, lport, faddr, fport);
 }
 
+static inline void __inet6_hash(struct inet_hashinfo *hashinfo,
+				struct sock *sk)
+{
+	struct hlist_head *list;
+	rwlock_t *lock;
+
+	BUG_TRAP(sk_unhashed(sk));
+
+	if (sk->sk_state == TCP_LISTEN) {
+		list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
+		lock = &hashinfo->lhash_lock;
+		inet_listen_wlock(hashinfo);
+	} else {
+		unsigned int hash;
+		sk->sk_hash = hash = inet6_sk_ehashfn(sk);
+		hash &= (hashinfo->ehash_size - 1);
+		list = &hashinfo->ehash[hash].chain;
+		lock = &hashinfo->ehash[hash].lock;
+		write_lock(lock);
+	}
+
+	__sk_add_node(sk, list);
+	sock_prot_inc_use(sk->sk_prot);
+	write_unlock(lock);
+}
+
 /*
  * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
  * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
@@ -84,10 +110,10 @@
 
 		if(*((__u32 *)&(tw->tw_dport))	== ports	&&
 		   sk->sk_family		== PF_INET6) {
-			const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk);
+			const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
 
-			if (ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr)	&&
-			    ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr)	&&
+			if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr)	&&
+			    ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr)	&&
 			    (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif))
 				goto hit;
 		}
diff --git a/include/net/inet_common.h b/include/net/inet_common.h
index f943306..227adcb 100644
--- a/include/net/inet_common.h
+++ b/include/net/inet_common.h
@@ -1,8 +1,8 @@
 #ifndef _INET_COMMON_H
 #define _INET_COMMON_H
 
-extern struct proto_ops		inet_stream_ops;
-extern struct proto_ops		inet_dgram_ops;
+extern const struct proto_ops		inet_stream_ops;
+extern const struct proto_ops		inet_dgram_ops;
 
 /*
  *	INET4 prototypes used by INET6
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index b0c9906..50234fa 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -15,9 +15,11 @@
 #ifndef _INET_CONNECTION_SOCK_H
 #define _INET_CONNECTION_SOCK_H
 
-#include <linux/ip.h>
+#include <linux/compiler.h>
 #include <linux/string.h>
 #include <linux/timer.h>
+
+#include <net/inet_sock.h>
 #include <net/request_sock.h>
 
 #define INET_CSK_DEBUG 1
@@ -29,6 +31,29 @@
 struct inet_hashinfo;
 struct tcp_congestion_ops;
 
+/*
+ * Pointers to address related TCP functions
+ * (i.e. things that depend on the address family)
+ */
+struct inet_connection_sock_af_ops {
+	int	    (*queue_xmit)(struct sk_buff *skb, int ipfragok);
+	void	    (*send_check)(struct sock *sk, int len,
+				  struct sk_buff *skb);
+	int	    (*rebuild_header)(struct sock *sk);
+	int	    (*conn_request)(struct sock *sk, struct sk_buff *skb);
+	struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb,
+				      struct request_sock *req,
+				      struct dst_entry *dst);
+	int	    (*remember_stamp)(struct sock *sk);
+	__u16	    net_header_len;
+	int	    (*setsockopt)(struct sock *sk, int level, int optname, 
+				  char __user *optval, int optlen);
+	int	    (*getsockopt)(struct sock *sk, int level, int optname, 
+				  char __user *optval, int __user *optlen);
+	void	    (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
+	int sockaddr_len;
+};
+
 /** inet_connection_sock - INET connection oriented sock
  *
  * @icsk_accept_queue:	   FIFO of established children 
@@ -36,13 +61,16 @@
  * @icsk_timeout:	   Timeout
  * @icsk_retransmit_timer: Resend (no ack)
  * @icsk_rto:		   Retransmit timeout
+ * @icsk_pmtu_cookie	   Last pmtu seen by socket
  * @icsk_ca_ops		   Pluggable congestion control hook
+ * @icsk_af_ops		   Operations which are AF_INET{4,6} specific
  * @icsk_ca_state:	   Congestion control state
  * @icsk_retransmits:	   Number of unrecovered [RTO] timeouts
  * @icsk_pending:	   Scheduled timer event
  * @icsk_backoff:	   Backoff
  * @icsk_syn_retries:      Number of allowed SYN (or equivalent) retries
  * @icsk_probes_out:	   unanswered 0 window probes
+ * @icsk_ext_hdr_len:	   Network protocol overhead (IP/IPv6 options)
  * @icsk_ack:		   Delayed ACK control data
  */
 struct inet_connection_sock {
@@ -54,14 +82,17 @@
  	struct timer_list	  icsk_retransmit_timer;
  	struct timer_list	  icsk_delack_timer;
 	__u32			  icsk_rto;
+	__u32			  icsk_pmtu_cookie;
 	struct tcp_congestion_ops *icsk_ca_ops;
+	struct inet_connection_sock_af_ops *icsk_af_ops;
+	unsigned int		  (*icsk_sync_mss)(struct sock *sk, u32 pmtu);
 	__u8			  icsk_ca_state;
 	__u8			  icsk_retransmits;
 	__u8			  icsk_pending;
 	__u8			  icsk_backoff;
 	__u8			  icsk_syn_retries;
 	__u8			  icsk_probes_out;
-	/* 2 BYTES HOLE, TRY TO PACK! */
+	__u16			  icsk_ext_hdr_len;
 	struct {
 		__u8		  pending;	 /* ACK is pending			   */
 		__u8		  quick;	 /* Scheduled number of quick acks	   */
@@ -192,8 +223,12 @@
 						const __u16 rport,
 						const __u32 raddr,
 						const __u32 laddr);
+extern int inet_csk_bind_conflict(const struct sock *sk,
+				  const struct inet_bind_bucket *tb);
 extern int inet_csk_get_port(struct inet_hashinfo *hashinfo,
-			     struct sock *sk, unsigned short snum);
+			     struct sock *sk, unsigned short snum,
+			     int (*bind_conflict)(const struct sock *sk,
+						  const struct inet_bind_bucket *tb));
 
 extern struct dst_entry* inet_csk_route_req(struct sock *sk,
 					    const struct request_sock *req);
@@ -207,7 +242,7 @@
 
 extern void inet_csk_reqsk_queue_hash_add(struct sock *sk,
 					  struct request_sock *req,
-					  const unsigned timeout);
+					  unsigned long timeout);
 
 static inline void inet_csk_reqsk_queue_removed(struct sock *sk,
 						struct request_sock *req)
@@ -273,4 +308,6 @@
 extern int  inet_csk_listen_start(struct sock *sk, const int nr_table_entries);
 extern void inet_csk_listen_stop(struct sock *sk);
 
+extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
+
 #endif /* _INET_CONNECTION_SOCK_H */
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index b0c47e2..d599c6b 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -3,6 +3,8 @@
 
 #include <linux/ip.h>
 #include <linux/skbuff.h>
+
+#include <net/inet_sock.h>
 #include <net/dsfield.h>
 
 enum {
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 07840ba..135d80f 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -26,6 +26,7 @@
 #include <linux/wait.h>
 
 #include <net/inet_connection_sock.h>
+#include <net/inet_sock.h>
 #include <net/route.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
@@ -128,26 +129,6 @@
 	kmem_cache_t			*bind_bucket_cachep;
 };
 
-static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
-			       const __u32 faddr, const __u16 fport)
-{
-	unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
-	h ^= h >> 16;
-	h ^= h >> 8;
-	return h;
-}
-
-static inline int inet_sk_ehashfn(const struct sock *sk)
-{
-	const struct inet_sock *inet = inet_sk(sk);
-	const __u32 laddr = inet->rcv_saddr;
-	const __u16 lport = inet->num;
-	const __u32 faddr = inet->daddr;
-	const __u16 fport = inet->dport;
-
-	return inet_ehashfn(laddr, lport, faddr, fport);
-}
-
 static inline struct inet_ehash_bucket *inet_ehash_bucket(
 	struct inet_hashinfo *hashinfo,
 	unsigned int hash)
@@ -434,4 +415,7 @@
 
 	return sk;
 }
+
+extern int inet_hash_connect(struct inet_timewait_death_row *death_row,
+			     struct sock *sk);
 #endif /* _INET_HASHTABLES_H */
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
new file mode 100644
index 0000000..883eb52
--- /dev/null
+++ b/include/net/inet_sock.h
@@ -0,0 +1,193 @@
+/*
+ * INET		An implementation of the TCP/IP protocol suite for the LINUX
+ *		operating system.  INET is implemented using the  BSD Socket
+ *		interface as the means of communication with the user level.
+ *
+ *		Definitions for inet_sock
+ *
+ * Authors:	Many, reorganised here by
+ * 		Arnaldo Carvalho de Melo <acme@mandriva.com>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+#ifndef _INET_SOCK_H
+#define _INET_SOCK_H
+
+#include <linux/config.h>
+
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <net/flow.h>
+#include <net/sock.h>
+#include <net/request_sock.h>
+
+/** struct ip_options - IP Options
+ *
+ * @faddr - Saved first hop address
+ * @is_setbyuser - Set by setsockopt?
+ * @is_data - Options in __data, rather than skb
+ * @is_strictroute - Strict source route
+ * @srr_is_hit - Packet destination addr was our one
+ * @is_changed - IP checksum more not valid
+ * @rr_needaddr - Need to record addr of outgoing dev
+ * @ts_needtime - Need to record timestamp
+ * @ts_needaddr - Need to record addr of outgoing dev
+ */
+struct ip_options {
+	__u32		faddr;
+	unsigned char	optlen;
+	unsigned char	srr;
+	unsigned char	rr;
+	unsigned char	ts;
+	unsigned char	is_setbyuser:1,
+			is_data:1,
+			is_strictroute:1,
+			srr_is_hit:1,
+			is_changed:1,
+			rr_needaddr:1,
+			ts_needtime:1,
+			ts_needaddr:1;
+	unsigned char	router_alert;
+	unsigned char	__pad1;
+	unsigned char	__pad2;
+	unsigned char	__data[0];
+};
+
+#define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
+
+struct inet_request_sock {
+	struct request_sock	req;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	u16			inet6_rsk_offset;
+	/* 2 bytes hole, try to pack */
+#endif
+	u32			loc_addr;
+	u32			rmt_addr;
+	u16			rmt_port;
+	u16			snd_wscale : 4, 
+				rcv_wscale : 4, 
+				tstamp_ok  : 1,
+				sack_ok	   : 1,
+				wscale_ok  : 1,
+				ecn_ok	   : 1,
+				acked	   : 1;
+	struct ip_options	*opt;
+};
+
+static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
+{
+	return (struct inet_request_sock *)sk;
+}
+
+struct ip_mc_socklist;
+struct ipv6_pinfo;
+struct rtable;
+
+/** struct inet_sock - representation of INET sockets
+ *
+ * @sk - ancestor class
+ * @pinet6 - pointer to IPv6 control block
+ * @daddr - Foreign IPv4 addr
+ * @rcv_saddr - Bound local IPv4 addr
+ * @dport - Destination port
+ * @num - Local port
+ * @saddr - Sending source
+ * @uc_ttl - Unicast TTL
+ * @sport - Source port
+ * @id - ID counter for DF pkts
+ * @tos - TOS
+ * @mc_ttl - Multicasting TTL
+ * @is_icsk - is this an inet_connection_sock?
+ * @mc_index - Multicast device index
+ * @mc_list - Group array
+ * @cork - info to build ip hdr on each ip frag while socket is corked
+ */
+struct inet_sock {
+	/* sk and pinet6 has to be the first two members of inet_sock */
+	struct sock		sk;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+	struct ipv6_pinfo	*pinet6;
+#endif
+	/* Socket demultiplex comparisons on incoming packets. */
+	__u32			daddr;
+	__u32			rcv_saddr;
+	__u16			dport;
+	__u16			num;
+	__u32			saddr;
+	__s16			uc_ttl;
+	__u16			cmsg_flags;
+	struct ip_options	*opt;
+	__u16			sport;
+	__u16			id;
+	__u8			tos;
+	__u8			mc_ttl;
+	__u8			pmtudisc;
+	__u8			recverr:1,
+				is_icsk:1,
+				freebind:1,
+				hdrincl:1,
+				mc_loop:1;
+	int			mc_index;
+	__u32			mc_addr;
+	struct ip_mc_socklist	*mc_list;
+	struct {
+		unsigned int		flags;
+		unsigned int		fragsize;
+		struct ip_options	*opt;
+		struct rtable		*rt;
+		int			length; /* Total length of all frames */
+		u32			addr;
+		struct flowi		fl;
+	} cork;
+};
+
+#define IPCORK_OPT	1	/* ip-options has been held in ipcork.opt */
+#define IPCORK_ALLFRAG	2	/* always fragment (for ipv6 for now) */
+
+static inline struct inet_sock *inet_sk(const struct sock *sk)
+{
+	return (struct inet_sock *)sk;
+}
+
+static inline void __inet_sk_copy_descendant(struct sock *sk_to,
+					     const struct sock *sk_from,
+					     const int ancestor_size)
+{
+	memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1,
+	       sk_from->sk_prot->obj_size - ancestor_size);
+}
+#if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE))
+static inline void inet_sk_copy_descendant(struct sock *sk_to,
+					   const struct sock *sk_from)
+{
+	__inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock));
+}
+#endif
+
+extern int inet_sk_rebuild_header(struct sock *sk);
+
+static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
+					const __u32 faddr, const __u16 fport)
+{
+	unsigned int h = (laddr ^ lport) ^ (faddr ^ fport);
+	h ^= h >> 16;
+	h ^= h >> 8;
+	return h;
+}
+
+static inline int inet_sk_ehashfn(const struct sock *sk)
+{
+	const struct inet_sock *inet = inet_sk(sk);
+	const __u32 laddr = inet->rcv_saddr;
+	const __u16 lport = inet->num;
+	const __u32 faddr = inet->daddr;
+	const __u16 fport = inet->dport;
+
+	return inet_ehashfn(laddr, lport, faddr, fport);
+}
+
+#endif	/* _INET_SOCK_H */
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 28f7b21..1da294c 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -17,15 +17,16 @@
 
 #include <linux/config.h>
 
-#include <linux/ip.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/timer.h>
 #include <linux/types.h>
 #include <linux/workqueue.h>
 
+#include <net/inet_sock.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
+#include <net/timewait_sock.h>
 
 #include <asm/atomic.h>
 
@@ -127,7 +128,8 @@
 	__u16			tw_num;
 	/* And these are ours. */
 	__u8			tw_ipv6only:1;
-	/* 31 bits hole, try to pack */
+	/* 15 bits hole, try to pack */
+	__u16			tw_ipv6_offset;
 	int			tw_timeout;
 	unsigned long		tw_ttd;
 	struct inet_bind_bucket	*tw_tb;
@@ -199,7 +201,7 @@
 		printk(KERN_DEBUG "%s timewait_sock %p released\n",
 		       tw->tw_prot->name, tw);
 #endif
-		kmem_cache_free(tw->tw_prot->twsk_slab, tw);
+		kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
 		module_put(owner);
 	}
 }
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 7fda471..0965515 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -25,6 +25,7 @@
 	__u32			v4daddr;	/* peer's address */
 	__u16			avl_height;
 	__u16			ip_id_count;	/* IP ID for the next packet */
+	atomic_t		rid;		/* Frag reception counter */
 	__u32			tcp_ts;
 	unsigned long		tcp_ts_stamp;
 };
diff --git a/include/net/ip.h b/include/net/ip.h
index e4563bb..8de0697 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -24,14 +24,10 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
-#include <linux/socket.h>
 #include <linux/ip.h>
 #include <linux/in.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/in_route.h>
-#include <net/route.h>
-#include <net/arp.h>
+
+#include <net/inet_sock.h>
 #include <net/snmp.h>
 
 struct sock;
@@ -41,10 +37,10 @@
 	struct ip_options	opt;		/* Compiled IP options		*/
 	unsigned char		flags;
 
-#define IPSKB_MASQUERADED	1
-#define IPSKB_TRANSLATED	2
-#define IPSKB_FORWARDED		4
-#define IPSKB_XFRM_TUNNEL_SIZE	8
+#define IPSKB_FORWARDED		1
+#define IPSKB_XFRM_TUNNEL_SIZE	2
+#define IPSKB_XFRM_TRANSFORMED	4
+#define IPSKB_FRAG_COMPLETE	8
 };
 
 struct ipcm_cookie
@@ -74,6 +70,13 @@
 
 #define IP_FRAG_TIME	(30 * HZ)		/* fragment lifetime	*/
 
+struct msghdr;
+struct net_device;
+struct packet_type;
+struct rtable;
+struct sk_buff;
+struct sockaddr;
+
 extern void		ip_mc_dropsocket(struct sock *);
 extern void		ip_mc_dropdevice(struct net_device *dev);
 extern int		igmp_mc_proc_init(void);
@@ -91,7 +94,6 @@
 extern int		ip_mr_input(struct sk_buff *skb);
 extern int		ip_output(struct sk_buff *skb);
 extern int		ip_mc_output(struct sk_buff *skb);
-extern int		ip_fragment(struct sk_buff *skb, int (*out)(struct sk_buff*));
 extern int		ip_do_nat(struct sk_buff *skb);
 extern void		ip_send_check(struct iphdr *ip);
 extern int		ip_queue_xmit(struct sk_buff *skb, int ipfragok);
@@ -168,6 +170,7 @@
 extern int sysctl_ipfrag_low_thresh;
 extern int sysctl_ipfrag_time;
 extern int sysctl_ipfrag_secret_interval;
+extern int sysctl_ipfrag_max_dist;
 
 /* From inetpeer.c */
 extern int inet_peer_threshold;
@@ -182,6 +185,8 @@
 extern void ipfrag_init(void);
 
 #ifdef CONFIG_INET
+#include <net/dst.h>
+
 /* The function in 2.2 was invalid, producing wrong result for
  * check=0xFEFF. It was noticed by Arthur Skawina _year_ ago. --ANK(000625) */
 static inline
@@ -310,7 +315,6 @@
 	IP_DEFRAG_CALL_RA_CHAIN,
 	IP_DEFRAG_CONNTRACK_IN,
 	IP_DEFRAG_CONNTRACK_OUT,
-	IP_DEFRAG_NAT_OUT,
 	IP_DEFRAG_VS_IN,
 	IP_DEFRAG_VS_OUT,
 	IP_DEFRAG_VS_FWD
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 14de4eb..e000fa2 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -238,6 +238,8 @@
 			       struct net_device *dev, u32 *spec_dst, u32 *itag);
 extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
 
+struct rtentry;
+
 /* Exported by fib_semantics.c */
 extern int ip_fib_check_default(u32 gw, struct net_device *dev);
 extern int fib_sync_down(u32 local, struct net_device *dev, int force);
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 3b5559a..7d2674f 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -251,16 +251,15 @@
 #include <linux/config.h>
 #include <linux/list.h>                 /* for struct list_head */
 #include <linux/spinlock.h>             /* for struct rwlock_t */
-#include <linux/skbuff.h>               /* for struct sk_buff */
-#include <linux/ip.h>                   /* for struct iphdr */
 #include <asm/atomic.h>                 /* for struct atomic_t */
-#include <linux/netdevice.h>		/* for struct neighbour */
-#include <net/dst.h>			/* for struct dst_entry */
-#include <net/udp.h>
 #include <linux/compiler.h>
+#include <linux/timer.h>
 
+#include <net/checksum.h>
 
 #ifdef CONFIG_IP_VS_DEBUG
+#include <linux/net.h>
+
 extern int ip_vs_get_debug_level(void);
 #define IP_VS_DBG(level, msg...)			\
     do {						\
@@ -429,8 +428,11 @@
 	spinlock_t              lock;           /* spin lock */
 };
 
+struct dst_entry;
+struct iphdr;
 struct ip_vs_conn;
 struct ip_vs_app;
+struct sk_buff;
 
 struct ip_vs_protocol {
 	struct ip_vs_protocol	*next;
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 0a2ad51..3b1d963 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -240,6 +240,8 @@
 struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
 					  struct ipv6_txoptions *opt);
 
+extern int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb);
+
 extern int ip6_frag_nqueues;
 extern atomic_t ip6_frag_mem;
 
@@ -416,6 +418,8 @@
 					 struct packet_type *pt,
 					 struct net_device *orig_dev);
 
+extern int			ip6_rcv_finish(struct sk_buff *skb);
+
 /*
  *	upper-layer output functions
  */
@@ -525,6 +529,9 @@
 extern int inet6_ioctl(struct socket *sock, unsigned int cmd, 
 		       unsigned long arg);
 
+extern int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+			      struct sock *sk);
+
 /*
  * reassembly.c
  */
@@ -533,8 +540,11 @@
 extern int sysctl_ip6frag_time;
 extern int sysctl_ip6frag_secret_interval;
 
-extern struct proto_ops inet6_stream_ops;
-extern struct proto_ops inet6_dgram_ops;
+extern const struct proto_ops inet6_stream_ops;
+extern const struct proto_ops inet6_dgram_ops;
+
+struct group_source_req;
+struct group_filter;
 
 extern int ip6_mc_source(int add, int omode, struct sock *sk,
 			 struct group_source_req *pgsr);
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index f85d6e4..bbac87e 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -35,11 +35,20 @@
 
 #ifdef __KERNEL__
 
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
+#include <linux/config.h>
+#include <linux/compiler.h>
 #include <linux/icmpv6.h>
+#include <linux/in6.h>
+#include <linux/types.h>
+
 #include <net/neighbour.h>
-#include <asm/atomic.h>
+
+struct ctl_table;
+struct file;
+struct inet6_dev;
+struct net_device;
+struct net_proto_family;
+struct sk_buff;
 
 extern struct neigh_table nd_tbl;
 
@@ -108,7 +117,7 @@
 extern void			igmp6_cleanup(void);
 
 #ifdef CONFIG_SYSCTL
-extern int 			ndisc_ifinfo_sysctl_change(ctl_table *ctl,
+extern int 			ndisc_ifinfo_sysctl_change(struct ctl_table *ctl,
 							   int write,
 							   struct file * filp,
 							   void __user *buffer,
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 34c0773..6fa9ae1 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -49,8 +49,8 @@
 #ifdef __KERNEL__
 
 #include <asm/atomic.h>
-#include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/skbuff.h>
 #include <linux/rcupdate.h>
 #include <linux/seq_file.h>
 
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index cc48256..64b82b7 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -94,6 +94,9 @@
 	/* Current number of expected connections */
 	unsigned int expecting;
 
+	/* Unique ID that identifies this conntrack*/
+	unsigned int id;
+
 	/* Helper. if any */
 	struct nf_conntrack_helper *helper;
 
@@ -140,6 +143,9 @@
 	/* Usage count. */
 	atomic_t use;
 
+	/* Unique ID */
+	unsigned int id;
+
 	/* Flags */
 	unsigned int flags;
 
@@ -190,6 +196,31 @@
 	nf_conntrack_put(&ct->ct_general);
 }
 
+extern struct nf_conntrack_tuple_hash *
+__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
+		    const struct nf_conn *ignored_conntrack);
+
+extern void nf_conntrack_hash_insert(struct nf_conn *ct);
+
+extern struct nf_conntrack_expect *
+__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple);
+
+extern struct nf_conntrack_expect *
+nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple);
+
+extern void nf_ct_unlink_expect(struct nf_conntrack_expect *exp);
+
+extern void nf_ct_remove_expectations(struct nf_conn *ct);
+
+extern void nf_conntrack_flush(void);
+
+extern struct nf_conntrack_helper *
+nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple);
+extern void nf_ct_helper_put(struct nf_conntrack_helper *helper);
+
+extern struct nf_conntrack_helper *
+__nf_conntrack_helper_find_byname(const char *name);
+
 /* call to create an explicit dependency on nf_conntrack. */
 extern void need_nf_conntrack(void);
 
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index 5a66b2a..86ec817 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -33,6 +33,8 @@
 		    unsigned int protoff,
 		    struct nf_conn *ct,
 		    enum ip_conntrack_info conntrackinfo);
+
+	int (*to_nfattr)(struct sk_buff *skb, const struct nf_conn *ct);
 };
 
 extern int nf_conntrack_helper_register(struct nf_conntrack_helper *);
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 01663e5..67856eb 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -14,6 +14,8 @@
 #include <linux/seq_file.h>
 #include <net/netfilter/nf_conntrack.h>
 
+struct nfattr;
+
 struct nf_conntrack_l3proto
 {
 	/* Next pointer. */
@@ -70,6 +72,12 @@
 
 	u_int32_t (*get_features)(const struct nf_conntrack_tuple *tuple);
 
+	int (*tuple_to_nfattr)(struct sk_buff *skb,
+			       const struct nf_conntrack_tuple *t);
+
+	int (*nfattr_to_tuple)(struct nfattr *tb[],
+			       struct nf_conntrack_tuple *t);
+
 	/* Module (if any) which this is connected to. */
 	struct module *me;
 };
@@ -81,11 +89,16 @@
 extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto);
 
 static inline struct nf_conntrack_l3proto *
-nf_ct_find_l3proto(u_int16_t l3proto)
+__nf_ct_l3proto_find(u_int16_t l3proto)
 {
 	return nf_ct_l3protos[l3proto];
 }
 
+extern struct nf_conntrack_l3proto *
+nf_ct_l3proto_find_get(u_int16_t l3proto);
+
+extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p);
+
 /* Existing built-in protocols */
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
 extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
diff --git a/include/net/netfilter/nf_conntrack_protocol.h b/include/net/netfilter/nf_conntrack_protocol.h
index b3afda3..1f33737 100644
--- a/include/net/netfilter/nf_conntrack_protocol.h
+++ b/include/net/netfilter/nf_conntrack_protocol.h
@@ -12,6 +12,7 @@
 #include <net/netfilter/nf_conntrack.h>
 
 struct seq_file;
+struct nfattr;
 
 struct nf_conntrack_protocol
 {
@@ -66,6 +67,18 @@
 		     enum ip_conntrack_info *ctinfo,
 		     int pf, unsigned int hooknum);
 
+	/* convert protoinfo to nfnetink attributes */
+	int (*to_nfattr)(struct sk_buff *skb, struct nfattr *nfa,
+			 const struct nf_conn *ct);
+
+	/* convert nfnetlink attributes to protoinfo */
+	int (*from_nfattr)(struct nfattr *tb[], struct nf_conn *ct);
+
+	int (*tuple_to_nfattr)(struct sk_buff *skb,
+			       const struct nf_conntrack_tuple *t);
+	int (*nfattr_to_tuple)(struct nfattr *tb[],
+			       struct nf_conntrack_tuple *t);
+
 	/* Module (if any) which this is connected to. */
 	struct module *me;
 };
@@ -80,12 +93,23 @@
 extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX];
 
 extern struct nf_conntrack_protocol *
-nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol);
+__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol);
+
+extern struct nf_conntrack_protocol *
+nf_ct_proto_find_get(u_int16_t l3proto, u_int8_t protocol);
+
+extern void nf_ct_proto_put(struct nf_conntrack_protocol *p);
 
 /* Protocol registration. */
 extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto);
 extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto);
 
+/* Generic netlink helpers */
+extern int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb,
+				      const struct nf_conntrack_tuple *tuple);
+extern int nf_ct_port_nfattr_to_tuple(struct nfattr *tb[],
+				      struct nf_conntrack_tuple *t);
+
 /* Log invalid packets */
 extern unsigned int nf_ct_log_invalid;
 
diff --git a/include/net/pkt_act.h b/include/net/pkt_act.h
index bd08964..b225d84 100644
--- a/include/net/pkt_act.h
+++ b/include/net/pkt_act.h
@@ -15,7 +15,6 @@
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
-#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/rtnetlink.h>
 #include <linux/module.h>
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 357691f..6dc5970 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -43,7 +43,7 @@
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 struct inet6_protocol 
 {
-	int	(*handler)(struct sk_buff **skb, unsigned int *nhoffp);
+	int	(*handler)(struct sk_buff **skb);
 
 	void	(*err_handler)(struct sk_buff *skb,
 			       struct inet6_skb_parm *opt,
@@ -65,7 +65,7 @@
 	int		 protocol; /* This is the L4 protocol number.  */
 
 	struct proto	 *prot;
-	struct proto_ops *ops;
+	const struct proto_ops *ops;
   
 	int              capability; /* Which (if any) capability do
 				      * we need to use this socket
@@ -76,6 +76,7 @@
 };
 #define INET_PROTOSW_REUSE 0x01	     /* Are ports automatically reusable? */
 #define INET_PROTOSW_PERMANENT 0x02  /* Permanent protocols are unremovable. */
+#define INET_PROTOSW_ICSK      0x04  /* Is this an inet_connection_sock? */
 
 extern struct net_protocol *inet_protocol_base;
 extern struct net_protocol *inet_protos[MAX_INET_PROTOS];
diff --git a/include/net/raw.h b/include/net/raw.h
index f479174..e67b28a 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -19,6 +19,8 @@
 
 #include <linux/config.h>
 
+#include <net/protocol.h>
+
 extern struct proto raw_prot;
 
 extern void 	raw_err(struct sock *, struct sk_buff *, u32 info);
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index b52cc52..11641c9 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -244,7 +244,7 @@
 
 static inline void reqsk_queue_hash_req(struct request_sock_queue *queue,
 					u32 hash, struct request_sock *req,
-					unsigned timeout)
+					unsigned long timeout)
 {
 	struct listen_sock *lopt = queue->listen_opt;
 
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 8e7794e..f5c22d7 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -277,6 +277,24 @@
 	__u32 default_context;
 	__u32 default_timetolive;
 
+	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
+	 * the destination address every heartbeat interval. This value
+	 * will be inherited by all new associations.
+	 */
+	__u32 hbinterval;
+
+	/* This is the max_retrans value for new associations. */
+	__u16 pathmaxrxt;
+
+	/* The initial Path MTU to use for new associations. */
+	__u32 pathmtu;
+
+	/* The default SACK delay timeout for new associations. */
+	__u32 sackdelay;
+
+	/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+	__u32 param_flags;
+
 	struct sctp_initmsg initmsg;
 	struct sctp_rtoinfo rtoinfo;
 	struct sctp_paddrparams paddrparam;
@@ -845,9 +863,6 @@
 	/* Data that has been sent, but not acknowledged. */
 	__u32 flight_size;
 
-	/* PMTU	      : The current known path MTU.  */
-	__u32 pmtu;
-
 	/* Destination */
 	struct dst_entry *dst;
 	/* Source address. */
@@ -862,7 +877,22 @@
 	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
 	 * the destination address every heartbeat interval.
 	 */
-	int hb_interval;
+	__u32 hbinterval;
+
+	/* This is the max_retrans value for the transport and will
+	 * be initialized from the assocs value.  This can be changed
+	 * using SCTP_SET_PEER_ADDR_PARAMS socket option.
+	 */
+	__u16 pathmaxrxt;
+
+	/* PMTU	      : The current known path MTU.  */
+	__u32 pathmtu;
+
+	/* SACK delay timeout */
+	__u32 sackdelay;
+
+	/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+	__u32 param_flags;
 
 	/* When was the last time (in jiffies) that we heard from this
 	 * transport?  We use this to pick new active and retran paths.
@@ -882,22 +912,11 @@
 	 */
 	int state;
 
-	/* hb_allowed  : The current heartbeat state of this destination,
-	 *	       :  i.e. ALLOW-HB, NO-HEARTBEAT, etc.
-	 */
-	int hb_allowed;
-
 	/* These are the error stats for this destination.  */
 
 	/* Error count : The current error count for this destination.	*/
 	unsigned short error_count;
 
-	/* This is the max_retrans value for the transport and will
-	 * be initialized to proto.max_retrans.path.  This can be changed
-	 * using SCTP_SET_PEER_ADDR_PARAMS socket option.
-	 */
-	int max_retrans;
-
 	/* Per	       : A timer used by each destination.
 	 * Destination :
 	 * Timer       :
@@ -1502,6 +1521,28 @@
 	/* The largest timeout or RTO value to use in attempting an INIT */
 	__u16 max_init_timeo;
 
+	/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
+	 * the destination address every heartbeat interval. This value
+	 * will be inherited by all new transports.
+	 */
+	__u32 hbinterval;
+
+	/* This is the max_retrans value for new transports in the
+	 * association.
+	 */
+	__u16 pathmaxrxt;
+
+	/* Association : The smallest PMTU discovered for all of the
+	 * PMTU	       : peer's transport addresses.
+	 */
+	__u32 pathmtu;
+
+	/* SACK delay timeout */
+	__u32 sackdelay;
+
+	/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
+	__u32 param_flags;
+
 	int timeouts[SCTP_NUM_TIMEOUT_TYPES];
 	struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES];
 
@@ -1571,11 +1612,6 @@
 	 */
 	wait_queue_head_t	wait;
 
-	/* Association : The smallest PMTU discovered for all of the
-	 * PMTU	       : peer's transport addresses.
-	 */
-	__u32 pmtu;
-
 	/* The message size at which SCTP fragmentation will occur. */
 	__u32 frag_point;
 
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index f1c3bc5..8a6bef6 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -93,6 +93,8 @@
 #define SCTP_STATUS SCTP_STATUS
 	SCTP_GET_PEER_ADDR_INFO,
 #define SCTP_GET_PEER_ADDR_INFO SCTP_GET_PEER_ADDR_INFO
+	SCTP_DELAYED_ACK_TIME,
+#define SCTP_DELAYED_ACK_TIME SCTP_DELAYED_ACK_TIME
 
 	/* Internal Socket Options. Some of the sctp library functions are 
 	 * implemented using these socket options.
@@ -503,13 +505,41 @@
  *   unreachable. The following structure is used to access and modify an
  *   address's parameters:
  */
+enum  sctp_spp_flags {
+	SPP_HB_ENABLE = 1,		/*Enable heartbeats*/
+	SPP_HB_DISABLE = 2,		/*Disable heartbeats*/
+	SPP_HB = SPP_HB_ENABLE | SPP_HB_DISABLE,
+	SPP_HB_DEMAND = 4,		/*Send heartbeat immediately*/
+	SPP_PMTUD_ENABLE = 8,		/*Enable PMTU discovery*/
+	SPP_PMTUD_DISABLE = 16,		/*Disable PMTU discovery*/
+	SPP_PMTUD = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE,
+	SPP_SACKDELAY_ENABLE = 32,	/*Enable SACK*/
+	SPP_SACKDELAY_DISABLE = 64,	/*Disable SACK*/
+	SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE,
+};
+
 struct sctp_paddrparams {
 	sctp_assoc_t		spp_assoc_id;
 	struct sockaddr_storage	spp_address;
 	__u32			spp_hbinterval;
 	__u16			spp_pathmaxrxt;
+	__u32			spp_pathmtu;
+	__u32			spp_sackdelay;
+	__u32			spp_flags;
 } __attribute__((packed, aligned(4)));
 
+/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
+ *
+ *   This options will get or set the delayed ack timer.  The time is set
+ *   in milliseconds.  If the assoc_id is 0, then this sets or gets the
+ *   endpoints default delayed ack timer value.  If the assoc_id field is
+ *   non-zero, then the set or get effects the specified association.
+ */
+struct sctp_assoc_value {
+    sctp_assoc_t            assoc_id;
+    uint32_t                assoc_value;
+};
+
 /*
  * 7.2.2 Peer Address Information
  *
diff --git a/include/net/sock.h b/include/net/sock.h
index 982b4ec..1806e5b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -493,6 +493,7 @@
 extern int sk_wait_data(struct sock *sk, long *timeo);
 
 struct request_sock_ops;
+struct timewait_sock_ops;
 
 /* Networking protocol blocks we attach to sockets.
  * socket layer -> transport layer interface
@@ -557,11 +558,10 @@
 	kmem_cache_t		*slab;
 	unsigned int		obj_size;
 
-	kmem_cache_t		*twsk_slab;
-	unsigned int		twsk_obj_size;
 	atomic_t		*orphan_count;
 
 	struct request_sock_ops	*rsk_prot;
+	struct timewait_sock_ops *twsk_prot;
 
 	struct module		*owner;
 
@@ -856,8 +856,8 @@
 		
 		filter = sk->sk_filter;
 		if (filter) {
-			int pkt_len = sk_run_filter(skb, filter->insns,
-						    filter->len);
+			unsigned int pkt_len = sk_run_filter(skb, filter->insns,
+							     filter->len);
 			if (!pkt_len)
 				err = -EPERM;
 			else
@@ -926,6 +926,29 @@
 		sk_free(sk);
 }
 
+static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
+{
+	int rc = NET_RX_SUCCESS;
+
+	if (sk_filter(sk, skb, 0))
+		goto discard_and_relse;
+
+	skb->dev = NULL;
+
+	bh_lock_sock(sk);
+	if (!sock_owned_by_user(sk))
+		rc = sk->sk_backlog_rcv(sk, skb);
+	else
+		sk_add_backlog(sk, skb);
+	bh_unlock_sock(sk);
+out:
+	sock_put(sk);
+	return rc;
+discard_and_relse:
+	kfree_skb(skb);
+	goto out;
+}
+
 /* Detach socket from process context.
  * Announce socket dead, detach it from wait queue and inode.
  * Note that parent inode held reference count on this struct sock,
@@ -1166,7 +1189,10 @@
  
 static inline int sock_error(struct sock *sk)
 {
-	int err = xchg(&sk->sk_err, 0);
+	int err;
+	if (likely(!sk->sk_err))
+		return 0;
+	err = xchg(&sk->sk_err, 0);
 	return -err;
 }
 
diff --git a/include/net/tcp.h b/include/net/tcp.h
index d78025f..77f21c6 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -225,53 +225,6 @@
 extern int tcp_memory_pressure;
 
 /*
- *	Pointers to address related TCP functions
- *	(i.e. things that depend on the address family)
- */
-
-struct tcp_func {
-	int			(*queue_xmit)		(struct sk_buff *skb,
-							 int ipfragok);
-
-	void			(*send_check)		(struct sock *sk,
-							 struct tcphdr *th,
-							 int len,
-							 struct sk_buff *skb);
-
-	int			(*rebuild_header)	(struct sock *sk);
-
-	int			(*conn_request)		(struct sock *sk,
-							 struct sk_buff *skb);
-
-	struct sock *		(*syn_recv_sock)	(struct sock *sk,
-							 struct sk_buff *skb,
-							 struct request_sock *req,
-							 struct dst_entry *dst);
-    
-	int			(*remember_stamp)	(struct sock *sk);
-
-	__u16			net_header_len;
-
-	int			(*setsockopt)		(struct sock *sk, 
-							 int level, 
-							 int optname, 
-							 char __user *optval, 
-							 int optlen);
-
-	int			(*getsockopt)		(struct sock *sk, 
-							 int level, 
-							 int optname, 
-							 char __user *optval, 
-							 int __user *optlen);
-
-
-	void			(*addr2sockaddr)	(struct sock *sk,
-							 struct sockaddr *);
-
-	int sockaddr_len;
-};
-
-/*
  * The next routines deal with comparing 32 bit unsigned ints
  * and worry about wraparound (automatic with unsigned arithmetic).
  */
@@ -334,6 +287,9 @@
 
 extern void			tcp_rcv_space_adjust(struct sock *sk);
 
+extern int			tcp_twsk_unique(struct sock *sk,
+						struct sock *sktw, void *twp);
+
 static inline void tcp_dec_quickack_mode(struct sock *sk,
 					 const unsigned int pkts)
 {
@@ -405,8 +361,7 @@
  *	TCP v4 functions exported for the inet6 API
  */
 
-extern void		       	tcp_v4_send_check(struct sock *sk, 
-						  struct tcphdr *th, int len, 
+extern void		       	tcp_v4_send_check(struct sock *sk, int len,
 						  struct sk_buff *skb);
 
 extern int			tcp_v4_conn_request(struct sock *sk,
@@ -490,34 +445,16 @@
 extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
 			 sk_read_actor_t recv_actor);
 
-/* Initialize RCV_MSS value.
- * RCV_MSS is an our guess about MSS used by the peer.
- * We haven't any direct information about the MSS.
- * It's better to underestimate the RCV_MSS rather than overestimate.
- * Overestimations make us ACKing less frequently than needed.
- * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss().
- */
+extern void tcp_initialize_rcv_mss(struct sock *sk);
 
-static inline void tcp_initialize_rcv_mss(struct sock *sk)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-	unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
-
-	hint = min(hint, tp->rcv_wnd/2);
-	hint = min(hint, TCP_MIN_RCVMSS);
-	hint = max(hint, TCP_MIN_MSS);
-
-	inet_csk(sk)->icsk_ack.rcv_mss = hint;
-}
-
-static __inline__ void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
+static inline void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
 {
 	tp->pred_flags = htonl((tp->tcp_header_len << 26) |
 			       ntohl(TCP_FLAG_ACK) |
 			       snd_wnd);
 }
 
-static __inline__ void tcp_fast_path_on(struct tcp_sock *tp)
+static inline void tcp_fast_path_on(struct tcp_sock *tp)
 {
 	__tcp_fast_path_on(tp, tp->snd_wnd >> tp->rx_opt.snd_wscale);
 }
@@ -535,7 +472,7 @@
  * Rcv_nxt can be after the window if our peer push more data
  * than the offered window.
  */
-static __inline__ u32 tcp_receive_window(const struct tcp_sock *tp)
+static inline u32 tcp_receive_window(const struct tcp_sock *tp)
 {
 	s32 win = tp->rcv_wup + tp->rcv_wnd - tp->rcv_nxt;
 
@@ -707,6 +644,7 @@
 extern int tcp_set_default_congestion_control(const char *name);
 extern void tcp_get_default_congestion_control(char *name);
 extern int tcp_set_congestion_control(struct sock *sk, const char *name);
+extern void tcp_slow_start(struct tcp_sock *tp);
 
 extern struct tcp_congestion_ops tcp_init_congestion_ops;
 extern u32 tcp_reno_ssthresh(struct sock *sk);
@@ -746,7 +684,7 @@
  *	"Packets left network, but not honestly ACKed yet" PLUS
  *	"Packets fast retransmitted"
  */
-static __inline__ unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
+static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
 {
 	return (tp->packets_out - tp->left_out + tp->retrans_out);
 }
@@ -766,33 +704,6 @@
 			    (tp->snd_cwnd >> 2)));
 }
 
-/*
- * Linear increase during slow start
- */
-static inline void tcp_slow_start(struct tcp_sock *tp)
-{
-	if (sysctl_tcp_abc) {
-		/* RFC3465: Slow Start
-		 * TCP sender SHOULD increase cwnd by the number of
-		 * previously unacknowledged bytes ACKed by each incoming
-		 * acknowledgment, provided the increase is not more than L
-		 */
-		if (tp->bytes_acked < tp->mss_cache)
-			return;
-
-		/* We MAY increase by 2 if discovered delayed ack */
-		if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) {
-			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-				tp->snd_cwnd++;
-		}
-	}
-	tp->bytes_acked = 0;
-
-	if (tp->snd_cwnd < tp->snd_cwnd_clamp)
-		tp->snd_cwnd++;
-}
-
-
 static inline void tcp_sync_left_out(struct tcp_sock *tp)
 {
 	if (tp->rx_opt.sack_ok &&
@@ -801,34 +712,7 @@
 	tp->left_out = tp->sacked_out + tp->lost_out;
 }
 
-/* Set slow start threshold and cwnd not falling to slow start */
-static inline void __tcp_enter_cwr(struct sock *sk)
-{
-	const struct inet_connection_sock *icsk = inet_csk(sk);
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	tp->undo_marker = 0;
-	tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk);
-	tp->snd_cwnd = min(tp->snd_cwnd,
-			   tcp_packets_in_flight(tp) + 1U);
-	tp->snd_cwnd_cnt = 0;
-	tp->high_seq = tp->snd_nxt;
-	tp->snd_cwnd_stamp = tcp_time_stamp;
-	TCP_ECN_queue_cwr(tp);
-}
-
-static inline void tcp_enter_cwr(struct sock *sk)
-{
-	struct tcp_sock *tp = tcp_sk(sk);
-
-	tp->prior_ssthresh = 0;
-	tp->bytes_acked = 0;
-	if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
-		__tcp_enter_cwr(sk);
-		tcp_set_ca_state(sk, TCP_CA_CWR);
-	}
-}
-
+extern void tcp_enter_cwr(struct sock *sk);
 extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst);
 
 /* Slow start with delack produces 3 packets of burst, so that
@@ -860,14 +744,14 @@
 		return left <= tcp_max_burst(tp);
 }
 
-static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, 
-					   const struct sk_buff *skb)
+static inline void tcp_minshall_update(struct tcp_sock *tp, int mss,
+				       const struct sk_buff *skb)
 {
 	if (skb->len < mss)
 		tp->snd_sml = TCP_SKB_CB(skb)->end_seq;
 }
 
-static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
+static inline void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp)
 {
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 	if (!tp->packets_out && !icsk->icsk_pending)
@@ -875,18 +759,18 @@
 					  icsk->icsk_rto, TCP_RTO_MAX);
 }
 
-static __inline__ void tcp_push_pending_frames(struct sock *sk,
-					       struct tcp_sock *tp)
+static inline void tcp_push_pending_frames(struct sock *sk,
+					   struct tcp_sock *tp)
 {
 	__tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle);
 }
 
-static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
+static inline void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 {
 	tp->snd_wl1 = seq;
 }
 
-static __inline__ void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
+static inline void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq)
 {
 	tp->snd_wl1 = seq;
 }
@@ -894,19 +778,19 @@
 /*
  * Calculate(/check) TCP checksum
  */
-static __inline__ u16 tcp_v4_check(struct tcphdr *th, int len,
-				   unsigned long saddr, unsigned long daddr, 
-				   unsigned long base)
+static inline u16 tcp_v4_check(struct tcphdr *th, int len,
+			       unsigned long saddr, unsigned long daddr, 
+			       unsigned long base)
 {
 	return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
 }
 
-static __inline__ int __tcp_checksum_complete(struct sk_buff *skb)
+static inline int __tcp_checksum_complete(struct sk_buff *skb)
 {
 	return __skb_checksum_complete(skb);
 }
 
-static __inline__ int tcp_checksum_complete(struct sk_buff *skb)
+static inline int tcp_checksum_complete(struct sk_buff *skb)
 {
 	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
 		__tcp_checksum_complete(skb);
@@ -914,7 +798,7 @@
 
 /* Prequeue for VJ style copy to user, combined with checksumming. */
 
-static __inline__ void tcp_prequeue_init(struct tcp_sock *tp)
+static inline void tcp_prequeue_init(struct tcp_sock *tp)
 {
 	tp->ucopy.task = NULL;
 	tp->ucopy.len = 0;
@@ -930,7 +814,7 @@
  *
  * NOTE: is this not too big to inline?
  */
-static __inline__ int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
+static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 
@@ -971,7 +855,7 @@
 };
 #endif
 
-static __inline__ void tcp_set_state(struct sock *sk, int state)
+static inline void tcp_set_state(struct sock *sk, int state)
 {
 	int oldstate = sk->sk_state;
 
@@ -1005,7 +889,7 @@
 #endif	
 }
 
-static __inline__ void tcp_done(struct sock *sk)
+static inline void tcp_done(struct sock *sk)
 {
 	tcp_set_state(sk, TCP_CLOSE);
 	tcp_clear_xmit_timers(sk);
@@ -1018,81 +902,13 @@
 		inet_csk_destroy_sock(sk);
 }
 
-static __inline__ void tcp_sack_reset(struct tcp_options_received *rx_opt)
+static inline void tcp_sack_reset(struct tcp_options_received *rx_opt)
 {
 	rx_opt->dsack = 0;
 	rx_opt->eff_sacks = 0;
 	rx_opt->num_sacks = 0;
 }
 
-static __inline__ void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp, __u32 tstamp)
-{
-	if (tp->rx_opt.tstamp_ok) {
-		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
-					  (TCPOPT_NOP << 16) |
-					  (TCPOPT_TIMESTAMP << 8) |
-					  TCPOLEN_TIMESTAMP);
-		*ptr++ = htonl(tstamp);
-		*ptr++ = htonl(tp->rx_opt.ts_recent);
-	}
-	if (tp->rx_opt.eff_sacks) {
-		struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks;
-		int this_sack;
-
-		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
-					  (TCPOPT_NOP << 16) |
-					  (TCPOPT_SACK << 8) |
-					  (TCPOLEN_SACK_BASE +
-					   (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)));
-		for(this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) {
-			*ptr++ = htonl(sp[this_sack].start_seq);
-			*ptr++ = htonl(sp[this_sack].end_seq);
-		}
-		if (tp->rx_opt.dsack) {
-			tp->rx_opt.dsack = 0;
-			tp->rx_opt.eff_sacks--;
-		}
-	}
-}
-
-/* Construct a tcp options header for a SYN or SYN_ACK packet.
- * If this is every changed make sure to change the definition of
- * MAX_SYN_SIZE to match the new maximum number of options that you
- * can generate.
- */
-static inline void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
-					     int offer_wscale, int wscale, __u32 tstamp, __u32 ts_recent)
-{
-	/* We always get an MSS option.
-	 * The option bytes which will be seen in normal data
-	 * packets should timestamps be used, must be in the MSS
-	 * advertised.  But we subtract them from tp->mss_cache so
-	 * that calculations in tcp_sendmsg are simpler etc.
-	 * So account for this fact here if necessary.  If we
-	 * don't do this correctly, as a receiver we won't
-	 * recognize data packets as being full sized when we
-	 * should, and thus we won't abide by the delayed ACK
-	 * rules correctly.
-	 * SACKs don't matter, we never delay an ACK when we
-	 * have any of those going out.
-	 */
-	*ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
-	if (ts) {
-		if(sack)
-			*ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) |
-						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
-		else
-			*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
-		*ptr++ = htonl(tstamp);		/* TSVAL */
-		*ptr++ = htonl(ts_recent);	/* TSECR */
-	} else if(sack)
-		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
-					  (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM);
-	if (offer_wscale)
-		*ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale));
-}
-
 /* Determine a window scaling and initial window to offer. */
 extern void tcp_select_initial_window(int __space, __u32 mss,
 				      __u32 *rcv_wnd, __u32 *window_clamp,
@@ -1117,9 +933,9 @@
 	return tcp_win_from_space(sk->sk_rcvbuf); 
 }
 
-static __inline__ void tcp_openreq_init(struct request_sock *req,
-					struct tcp_options_received *rx_opt,
-					struct sk_buff *skb)
+static inline void tcp_openreq_init(struct request_sock *req,
+				    struct tcp_options_received *rx_opt,
+				    struct sk_buff *skb)
 {
 	struct inet_request_sock *ireq = inet_rsk(req);
 
diff --git a/include/net/tcp_states.h b/include/net/tcp_states.h
index b9d4176..b0b6459 100644
--- a/include/net/tcp_states.h
+++ b/include/net/tcp_states.h
@@ -31,4 +31,20 @@
 
 #define TCP_STATE_MASK	0xF
 
+#define TCP_ACTION_FIN	(1 << 7)
+
+enum {
+	TCPF_ESTABLISHED = (1 << 1),
+	TCPF_SYN_SENT	 = (1 << 2),
+	TCPF_SYN_RECV	 = (1 << 3),
+	TCPF_FIN_WAIT1	 = (1 << 4),
+	TCPF_FIN_WAIT2	 = (1 << 5),
+	TCPF_TIME_WAIT	 = (1 << 6),
+	TCPF_CLOSE	 = (1 << 7),
+	TCPF_CLOSE_WAIT	 = (1 << 8),
+	TCPF_LAST_ACK	 = (1 << 9),
+	TCPF_LISTEN	 = (1 << 10),
+	TCPF_CLOSING	 = (1 << 11) 
+};
+
 #endif	/* _LINUX_TCP_STATES_H */
diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h
new file mode 100644
index 0000000..2544281
--- /dev/null
+++ b/include/net/timewait_sock.h
@@ -0,0 +1,31 @@
+/*
+ * NET		Generic infrastructure for Network protocols.
+ *
+ * Authors:	Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ */
+#ifndef _TIMEWAIT_SOCK_H
+#define _TIMEWAIT_SOCK_H
+
+#include <linux/slab.h>
+#include <net/sock.h>
+
+struct timewait_sock_ops {
+	kmem_cache_t	*twsk_slab;
+	unsigned int	twsk_obj_size;
+	int		(*twsk_unique)(struct sock *sk,
+				       struct sock *sktw, void *twp);
+};
+
+static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
+{
+	if (sk->sk_prot->twsk_prot->twsk_unique != NULL)
+		return sk->sk_prot->twsk_prot->twsk_unique(sk, sktw, twp);
+	return 0;
+}
+
+#endif /* _TIMEWAIT_SOCK_H */
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 4e86f2d..61f724c 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -44,7 +44,7 @@
 /*
  *	address family specific functions
  */
-extern struct tcp_func	ipv4_specific;
+extern struct inet_connection_sock_af_ops ipv4_specific;
 
 extern int inet6_destroy_sock(struct sock *sk);
 
diff --git a/include/net/udp.h b/include/net/udp.h
index 107b9d7..766fba1 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -22,9 +22,8 @@
 #ifndef _UDP_H
 #define _UDP_H
 
-#include <linux/udp.h>
-#include <linux/ip.h>
 #include <linux/list.h>
+#include <net/inet_sock.h>
 #include <net/sock.h>
 #include <net/snmp.h>
 #include <linux/seq_file.h>
@@ -62,6 +61,7 @@
 
 extern struct proto udp_prot;
 
+struct sk_buff;
 
 extern void	udp_err(struct sk_buff *, u32);
 
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 5beae1c..d09ca0e 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -2,11 +2,12 @@
 #define _NET_XFRM_H
 
 #include <linux/compiler.h>
+#include <linux/in.h>
 #include <linux/xfrm.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
 #include <linux/skbuff.h>
-#include <linux/netdevice.h>
+#include <linux/socket.h>
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
 #include <linux/in6.h>
@@ -144,6 +145,9 @@
 	 * transformer. */
 	struct xfrm_type	*type;
 
+	/* Security context */
+	struct xfrm_sec_ctx	*security;
+
 	/* Private data of this transformer, format is opaque,
 	 * interpreted by xfrm_type methods. */
 	void			*data;
@@ -298,6 +302,7 @@
 	__u8			flags;
 	__u8			dead;
 	__u8			xfrm_nr;
+	struct xfrm_sec_ctx	*security;
 	struct xfrm_tmpl       	xfrm_vec[XFRM_MAX_DEPTH];
 };
 
@@ -510,6 +515,25 @@
 	return 0;
 }
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+/*	If neither has a context --> match
+ * 	Otherwise, both must have a context and the sids, doi, alg must match
+ */
+static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
+{
+	return ((!s1 && !s2) ||
+		(s1 && s2 &&
+		 (s1->ctx_sid == s2->ctx_sid) &&
+		 (s1->ctx_doi == s2->ctx_doi) &&
+		 (s1->ctx_alg == s2->ctx_alg)));
+}
+#else
+static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct xfrm_sec_ctx *s2)
+{
+	return 1;
+}
+#endif
+
 /* A struct encoding bundle of transformations to apply to some set of flow.
  *
  * dst->child points to the next element of bundle.
@@ -644,7 +668,7 @@
 	return xfrm_policy_check(sk, dir, skb, AF_INET6);
 }
 
-
+extern int xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family);
 extern int __xfrm_route_forward(struct sk_buff *skb, unsigned short family);
 
 static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
@@ -807,7 +831,7 @@
 };
 
 struct xfrm6_tunnel {
-	int (*handler)(struct sk_buff **pskb, unsigned int *nhoffp);
+	int (*handler)(struct sk_buff **pskb);
 	void (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,
 			    int type, int code, int offset, __u32 info);
 };
@@ -842,10 +866,11 @@
 extern int xfrm_init_state(struct xfrm_state *x);
 extern int xfrm4_rcv(struct sk_buff *skb);
 extern int xfrm4_output(struct sk_buff *skb);
+extern int xfrm4_output_finish(struct sk_buff *skb);
 extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);
 extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);
-extern int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi);
-extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp);
+extern int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi);
+extern int xfrm6_rcv(struct sk_buff **pskb);
 extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler);
 extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);
 extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);
@@ -878,8 +903,8 @@
 struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
 extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
-struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
-				      int delete);
+struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
+					  struct xfrm_sec_ctx *ctx, int delete);
 struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);
 void xfrm_policy_flush(void);
 u32 xfrm_get_acqseq(void);
@@ -890,6 +915,7 @@
 extern void xfrm_policy_flush(void);
 extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
 extern int xfrm_flush_bundles(void);
+extern void xfrm_flush_all_bundles(void);
 extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family);
 extern void xfrm_init_pmtu(struct dst_entry *dst);
 
diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h
index 2cab39f..52660f3 100644
--- a/include/pcmcia/cs.h
+++ b/include/pcmcia/cs.h
@@ -382,7 +382,6 @@
 struct pcmcia_socket;
 
 int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg);
-int pcmcia_deregister_client(struct pcmcia_device *p_dev);
 int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config);
 int pcmcia_get_first_window(window_handle_t *win, win_req_t *req);
 int pcmcia_get_next_window(window_handle_t *win, win_req_t *req);
@@ -390,7 +389,6 @@
 int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
 int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
 int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
-int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);
 int pcmcia_release_configuration(struct pcmcia_device *p_dev);
 int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req);
 int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req);
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index cb8b6e6..8e2a963 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -133,10 +133,12 @@
 struct pcmcia_socket;
 
 struct pcmcia_driver {
-	dev_link_t		*(*attach)(void);
-	int (*event)		(event_t event, int priority,
-				 event_callback_args_t *);
-	void			(*detach)(dev_link_t *);
+	int (*probe)		(struct pcmcia_device *dev);
+	void (*remove)		(struct pcmcia_device *dev);
+
+	int (*suspend)		(struct pcmcia_device *dev);
+	int (*resume)		(struct pcmcia_device *dev);
+
 	struct module		*owner;
 	struct pcmcia_device_id	*id_table;
 	struct device_driver	drv;
@@ -164,7 +166,6 @@
 	/* deprecated, a cleaned up version will be moved into this
 	   struct soon */
 	dev_link_t		*instance;
-	event_callback_args_t 	event_callback_args;
 	u_int			state;
 
 	/* information about this device */
@@ -193,6 +194,8 @@
 #define handle_to_pdev(handle) (handle)
 #define handle_to_dev(handle) (handle->dev)
 
+#define dev_to_instance(dev) (dev->instance)
+
 /* error reporting */
 void cs_error(client_handle_t handle, int func, int ret);
 
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index e788bbc..2889a69 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -118,16 +118,14 @@
 struct pccard_operations {
 	int (*init)(struct pcmcia_socket *sock);
 	int (*suspend)(struct pcmcia_socket *sock);
-	int (*register_callback)(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info);
 	int (*get_status)(struct pcmcia_socket *sock, u_int *value);
-	int (*get_socket)(struct pcmcia_socket *sock, socket_state_t *state);
 	int (*set_socket)(struct pcmcia_socket *sock, socket_state_t *state);
 	int (*set_io_map)(struct pcmcia_socket *sock, struct pccard_io_map *io);
 	int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem);
 };
 
 struct pccard_resource_ops {
-	void	(*validate_mem)		(struct pcmcia_socket *s);
+	int	(*validate_mem)		(struct pcmcia_socket *s);
 	int	(*adjust_io_region)	(struct resource *res,
 					 unsigned long r_start,
 					 unsigned long r_end,
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 7529f43..41cfc29 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -151,5 +151,6 @@
 extern void scsi_put_command(struct scsi_cmnd *);
 extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
 extern void scsi_finish_command(struct scsi_cmnd *cmd);
+extern void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd);
 
 #endif /* _SCSI_SCSI_CMND_H */
diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
index b090a11..4d69dee 100644
--- a/include/scsi/scsi_dbg.h
+++ b/include/scsi/scsi_dbg.h
@@ -16,7 +16,6 @@
 extern void scsi_print_driverbyte(int);
 extern void scsi_print_hostbyte(int);
 extern void scsi_print_status(unsigned char);
-extern int scsi_print_msg(const unsigned char *);
 extern const char *scsi_sense_key_string(unsigned char);
 extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
 
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 85cfd88..e94ca4d 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -79,9 +79,9 @@
 	char inq_periph_qual;	/* PQ from INQUIRY data */	
 	unsigned char inquiry_len;	/* valid bytes in 'inquiry' */
 	unsigned char * inquiry;	/* INQUIRY response data */
-	char * vendor;		/* [back_compat] point into 'inquiry' ... */
-	char * model;		/* ... after scan; point to static string */
-	char * rev;		/* ... "nullnullnullnull" before scan */
+	const char * vendor;		/* [back_compat] point into 'inquiry' ... */
+	const char * model;		/* ... after scan; point to static string */
+	const char * rev;		/* ... "nullnullnullnull" before scan */
 	unsigned char current_tag;	/* current tag */
 	struct scsi_target      *sdev_target;   /* used only for single_lun */
 
@@ -274,6 +274,12 @@
 extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
 			    int data_direction, void *buffer, unsigned bufflen,
 			    struct scsi_sense_hdr *, int timeout, int retries);
+extern int scsi_execute_async(struct scsi_device *sdev,
+			      const unsigned char *cmd, int data_direction,
+			      void *buffer, unsigned bufflen, int use_sg,
+			      int timeout, int retries, void *privdata,
+			      void (*done)(void *, char *, int, int),
+			      gfp_t gfp);
 
 static inline unsigned int sdev_channel(struct scsi_device *sdev)
 {
diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h
index 850dfa8..02e26c1 100644
--- a/include/scsi/scsi_driver.h
+++ b/include/scsi/scsi_driver.h
@@ -15,7 +15,6 @@
 	void (*rescan)(struct device *);
 	int (*issue_flush)(struct device *, sector_t *);
 	int (*prepare_flush)(struct request_queue *, struct request *);
-	void (*end_flush)(struct request_queue *, struct request *);
 };
 #define to_scsi_driver(drv) \
 	container_of((drv), struct scsi_driver, gendrv)
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 6cbb198..230bc55 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -296,6 +296,12 @@
 	int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
 
 	/*
+	 * suspend support
+	 */
+	int (*resume)(struct scsi_device *);
+	int (*suspend)(struct scsi_device *);
+
+	/*
 	 * Name of proc directory
 	 */
 	char *proc_name;
@@ -392,7 +398,6 @@
 	/*
 	 * ordered write support
 	 */
-	unsigned ordered_flush:1;
 	unsigned ordered_tag:1;
 
 	/*
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index fac547d..394f14a 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -79,6 +79,7 @@
 	FC_PORTSTATE_LINKDOWN,
 	FC_PORTSTATE_ERROR,
 	FC_PORTSTATE_LOOPBACK,
+	FC_PORTSTATE_DELETED,
 };
 
 
@@ -325,8 +326,14 @@
 	struct list_head rport_bindings;
 	u32 next_rport_number;
 	u32 next_target_id;
+	u8 flags;
+ 	struct work_struct rport_del_work;
 };
 
+/* values for struct fc_host_attrs "flags" field: */
+#define FC_SHOST_RPORT_DEL_SCHEDULED	0x01
+
+
 #define fc_host_node_name(x) \
 	(((struct fc_host_attrs *)(x)->shost_data)->node_name)
 #define fc_host_port_name(x)	\
@@ -365,6 +372,10 @@
 	(((struct fc_host_attrs *)(x)->shost_data)->next_rport_number)
 #define fc_host_next_target_id(x) \
 	(((struct fc_host_attrs *)(x)->shost_data)->next_target_id)
+#define fc_host_flags(x) \
+	(((struct fc_host_attrs *)(x)->shost_data)->flags)
+#define fc_host_rport_del_work(x) \
+	(((struct fc_host_attrs *)(x)->shost_data)->rport_del_work)
 
 
 /* The functions by which the transport class and the driver communicate */
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h
index 6bdc4af..54a8961 100644
--- a/include/scsi/scsi_transport_spi.h
+++ b/include/scsi/scsi_transport_spi.h
@@ -24,6 +24,9 @@
 #include <linux/transport_class.h>
 
 struct scsi_transport_template;
+struct scsi_target;
+struct scsi_device;
+struct Scsi_Host;
 
 struct spi_transport_attrs {
 	int period;		/* value in the PPR/SDTR command */
@@ -143,5 +146,6 @@
 void spi_schedule_dv_device(struct scsi_device *);
 void spi_dv_device(struct scsi_device *);
 void spi_display_xfer_agreement(struct scsi_target *);
+int spi_print_msg(const unsigned char *);
 
 #endif /* SCSI_TRANSPORT_SPI_H */
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 7f0ca79..b0b3ea7 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -391,65 +391,35 @@
  *
  */
 
-typedef struct _snd_ac97_bus ac97_bus_t;
-typedef struct _snd_ac97_bus_ops ac97_bus_ops_t;
-typedef struct _snd_ac97_template ac97_template_t;
-typedef struct _snd_ac97 ac97_t;
-
-enum ac97_pcm_cfg {
-	AC97_PCM_CFG_FRONT = 2,
-	AC97_PCM_CFG_REAR = 10,		/* alias surround */
-	AC97_PCM_CFG_LFE = 11,		/* center + lfe */
-	AC97_PCM_CFG_40 = 4,		/* front + rear */
-	AC97_PCM_CFG_51 = 6,		/* front + rear + center/lfe */
-	AC97_PCM_CFG_SPDIF = 20
-};
-
-/* PCM allocation */
-struct ac97_pcm {
-	ac97_bus_t *bus;
-	unsigned int stream: 1,	   	   /* stream type: 1 = capture */
-		     exclusive: 1,	   /* exclusive mode, don't override with other pcms */
-		     copy_flag: 1,	   /* lowlevel driver must fill all entries */
-		     spdif: 1;		   /* spdif pcm */
-	unsigned short aslots;		   /* active slots */
-	unsigned int rates;		   /* available rates */
-	struct {
-		unsigned short slots;	   /* driver input: requested AC97 slot numbers */
-		unsigned short rslots[4];  /* allocated slots per codecs */
-		unsigned char rate_table[4];
-		ac97_t *codec[4];	   /* allocated codecs */
-	} r[2];				   /* 0 = standard rates, 1 = double rates */
-	unsigned long private_value;	   /* used by the hardware driver */
-};
+struct snd_ac97;
 
 struct snd_ac97_build_ops {
-	int (*build_3d) (ac97_t *ac97);
-	int (*build_specific) (ac97_t *ac97);
-	int (*build_spdif) (ac97_t *ac97);
-	int (*build_post_spdif) (ac97_t *ac97);
+	int (*build_3d) (struct snd_ac97 *ac97);
+	int (*build_specific) (struct snd_ac97 *ac97);
+	int (*build_spdif) (struct snd_ac97 *ac97);
+	int (*build_post_spdif) (struct snd_ac97 *ac97);
 #ifdef CONFIG_PM
-	void (*suspend) (ac97_t *ac97);
-	void (*resume) (ac97_t *ac97);
+	void (*suspend) (struct snd_ac97 *ac97);
+	void (*resume) (struct snd_ac97 *ac97);
 #endif
-	void (*update_jacks) (ac97_t *ac97);	/* for jack-sharing */
+	void (*update_jacks) (struct snd_ac97 *ac97);	/* for jack-sharing */
 };
 
-struct _snd_ac97_bus_ops {
-	void (*reset) (ac97_t *ac97);
-	void (*write) (ac97_t *ac97, unsigned short reg, unsigned short val);
-	unsigned short (*read) (ac97_t *ac97, unsigned short reg);
-	void (*wait) (ac97_t *ac97);
-	void (*init) (ac97_t *ac97);
+struct snd_ac97_bus_ops {
+	void (*reset) (struct snd_ac97 *ac97);
+	void (*write) (struct snd_ac97 *ac97, unsigned short reg, unsigned short val);
+	unsigned short (*read) (struct snd_ac97 *ac97, unsigned short reg);
+	void (*wait) (struct snd_ac97 *ac97);
+	void (*init) (struct snd_ac97 *ac97);
 };
 
-struct _snd_ac97_bus {
+struct snd_ac97_bus {
 	/* -- lowlevel (hardware) driver specific -- */
-	ac97_bus_ops_t *ops;
+	struct snd_ac97_bus_ops *ops;
 	void *private_data;
-	void (*private_free) (ac97_bus_t *bus);
+	void (*private_free) (struct snd_ac97_bus *bus);
 	/* --- */
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned short num;	/* bus number */
 	unsigned short no_vra: 1, /* bridge doesn't support VRA */
 		       dra: 1,	/* bridge supports double rate */
@@ -459,13 +429,13 @@
 	unsigned short used_slots[2][4]; /* actually used PCM slots */
 	unsigned short pcms_count; /* count of PCMs */
 	struct ac97_pcm *pcms;
-	ac97_t *codec[4];
-	snd_info_entry_t *proc;
+	struct snd_ac97 *codec[4];
+	struct snd_info_entry *proc;
 };
 
-struct _snd_ac97_template {
+struct snd_ac97_template {
 	void *private_data;
-	void (*private_free) (ac97_t *ac97);
+	void (*private_free) (struct snd_ac97 *ac97);
 	struct pci_dev *pci;	/* assigned PCI device - used for quirks */
 	unsigned short num;	/* number of codec: 0 = primary, 1 = secondary */
 	unsigned short addr;	/* physical address of codec [0-3] */
@@ -474,16 +444,16 @@
 	DECLARE_BITMAP(reg_accessed, 0x80); /* bit flags */
 };
 
-struct _snd_ac97 {
+struct snd_ac97 {
 	/* -- lowlevel (hardware) driver specific -- */
 	struct snd_ac97_build_ops * build_ops;
 	void *private_data;
-	void (*private_free) (ac97_t *ac97);
+	void (*private_free) (struct snd_ac97 *ac97);
 	/* --- */
-	ac97_bus_t *bus;
+	struct snd_ac97_bus *bus;
 	struct pci_dev *pci;	/* assigned PCI device - used for quirks */
-	snd_info_entry_t *proc;
-	snd_info_entry_t *proc_regs;
+	struct snd_info_entry *proc;
+	struct snd_info_entry *proc_regs;
 	unsigned short subsystem_vendor;
 	unsigned short subsystem_device;
 	struct semaphore reg_mutex;
@@ -517,43 +487,47 @@
 	struct device dev;
 };
 
-#define to_ac97_t(d) container_of(d, struct _snd_ac97, dev)
+#define to_ac97_t(d) container_of(d, struct snd_ac97, dev)
 
 /* conditions */
-static inline int ac97_is_audio(ac97_t * ac97)
+static inline int ac97_is_audio(struct snd_ac97 * ac97)
 {
 	return (ac97->scaps & AC97_SCAP_AUDIO);
 }
-static inline int ac97_is_modem(ac97_t * ac97)
+static inline int ac97_is_modem(struct snd_ac97 * ac97)
 {
 	return (ac97->scaps & AC97_SCAP_MODEM);
 }
-static inline int ac97_is_rev22(ac97_t * ac97)
+static inline int ac97_is_rev22(struct snd_ac97 * ac97)
 {
 	return (ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_22;
 }
-static inline int ac97_can_amap(ac97_t * ac97)
+static inline int ac97_can_amap(struct snd_ac97 * ac97)
 {
 	return (ac97->ext_id & AC97_EI_AMAP) != 0;
 }
-static inline int ac97_can_spdif(ac97_t * ac97)
+static inline int ac97_can_spdif(struct snd_ac97 * ac97)
 {
 	return (ac97->ext_id & AC97_EI_SPDIF) != 0;
 }
 
 /* functions */
-int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops, void *private_data, ac97_bus_t **rbus); /* create new AC97 bus */
-int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97);	/* create mixer controls */
-const char *snd_ac97_get_short_name(ac97_t *ac97);
+/* create new AC97 bus */
+int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
+		 void *private_data, struct snd_ac97_bus **rbus);
+/* create mixer controls */
+int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
+		   struct snd_ac97 **rac97);
+const char *snd_ac97_get_short_name(struct snd_ac97 *ac97);
 
-void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value);
-unsigned short snd_ac97_read(ac97_t *ac97, unsigned short reg);
-void snd_ac97_write_cache(ac97_t *ac97, unsigned short reg, unsigned short value);
-int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value);
-int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value);
+void snd_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short value);
+unsigned short snd_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
+void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned short value);
+int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short value);
+int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value);
 #ifdef CONFIG_PM
-void snd_ac97_suspend(ac97_t *ac97);
-void snd_ac97_resume(ac97_t *ac97);
+void snd_ac97_suspend(struct snd_ac97 *ac97);
+void snd_ac97_resume(struct snd_ac97 *ac97);
 #endif
 
 /* quirk types */
@@ -567,6 +541,7 @@
 	AC97_TUNE_ALC_JACK,	/* for Realtek, enable JACK detection */
 	AC97_TUNE_INV_EAPD,	/* inverted EAPD implementation */
 	AC97_TUNE_MUTE_LED,	/* EAPD bit works as mute LED */
+	AC97_TUNE_HP_MUTE_LED,  /* EAPD bit works as mute LED, use headphone control as master */
 };
 
 struct ac97_quirk {
@@ -578,24 +553,46 @@
 	int type;		/* quirk type above */
 };
 
-int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *override);
-int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate);
+int snd_ac97_tune_hardware(struct snd_ac97 *ac97, struct ac97_quirk *quirk, const char *override);
+int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate);
 
-int snd_ac97_pcm_assign(ac97_bus_t *ac97,
+/*
+ * PCM allocation
+ */
+
+enum ac97_pcm_cfg {
+	AC97_PCM_CFG_FRONT = 2,
+	AC97_PCM_CFG_REAR = 10,		/* alias surround */
+	AC97_PCM_CFG_LFE = 11,		/* center + lfe */
+	AC97_PCM_CFG_40 = 4,		/* front + rear */
+	AC97_PCM_CFG_51 = 6,		/* front + rear + center/lfe */
+	AC97_PCM_CFG_SPDIF = 20
+};
+
+struct ac97_pcm {
+	struct snd_ac97_bus *bus;
+	unsigned int stream: 1,	   	   /* stream type: 1 = capture */
+		     exclusive: 1,	   /* exclusive mode, don't override with other pcms */
+		     copy_flag: 1,	   /* lowlevel driver must fill all entries */
+		     spdif: 1;		   /* spdif pcm */
+	unsigned short aslots;		   /* active slots */
+	unsigned int rates;		   /* available rates */
+	struct {
+		unsigned short slots;	   /* driver input: requested AC97 slot numbers */
+		unsigned short rslots[4];  /* allocated slots per codecs */
+		unsigned char rate_table[4];
+		struct snd_ac97 *codec[4];	   /* allocated codecs */
+	} r[2];				   /* 0 = standard rates, 1 = double rates */
+	unsigned long private_value;	   /* used by the hardware driver */
+};
+
+int snd_ac97_pcm_assign(struct snd_ac97_bus *ac97,
 			unsigned short pcms_count,
 			const struct ac97_pcm *pcms);
 int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate,
 		      enum ac97_pcm_cfg cfg, unsigned short slots);
 int snd_ac97_pcm_close(struct ac97_pcm *pcm);
-int snd_ac97_pcm_double_rate_rules(snd_pcm_runtime_t *runtime);
-
-struct ac97_enum {
-	unsigned char reg;
-	unsigned char shift_l;
-	unsigned char shift_r;
-	unsigned short mask;
-	const char **texts;
-};
+int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime);
 
 /* ad hoc AC97 device driver access */
 extern struct bus_type ac97_bus_type;
diff --git a/include/sound/ad1816a.h b/include/sound/ad1816a.h
index ca2e0e4..b3aa62e 100644
--- a/include/sound/ad1816a.h
+++ b/include/sound/ad1816a.h
@@ -123,9 +123,7 @@
 #define AD1816A_CAPTURE_NOT_EQUAL	0x1000
 #define AD1816A_WSS_ENABLE		0x8000
 
-typedef struct _snd_ad1816a ad1816a_t;
-
-struct _snd_ad1816a {
+struct snd_ad1816a {
 	unsigned long port;
 	struct resource *res_port;
 	int irq;
@@ -140,15 +138,15 @@
 	unsigned short mode;
 	unsigned int clock_freq;
 
-	snd_card_t *card;
-	snd_pcm_t *pcm;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
 
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
 	unsigned int p_dma_size;
 	unsigned int c_dma_size;
 
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 };
 
 
@@ -165,11 +163,11 @@
 				AD1816A_MODE_TIMER)
 
 
-extern int snd_ad1816a_create(snd_card_t *card, unsigned long port,
+extern int snd_ad1816a_create(struct snd_card *card, unsigned long port,
 			      int irq, int dma1, int dma2,
-			      ad1816a_t **chip);
+			      struct snd_ad1816a **chip);
 
-extern int snd_ad1816a_pcm(ad1816a_t *chip, int device, snd_pcm_t **rpcm);
-extern int snd_ad1816a_mixer(ad1816a_t *chip);
+extern int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm);
+extern int snd_ad1816a_mixer(struct snd_ad1816a *chip);
 
 #endif	/* __SOUND_AD1816A_H */
diff --git a/include/sound/ad1848.h b/include/sound/ad1848.h
index 7e33b11..1a2759f 100644
--- a/include/sound/ad1848.h
+++ b/include/sound/ad1848.h
@@ -127,7 +127,7 @@
 #define AD1848_THINKPAD_CTL_PORT2		0x15e9
 #define AD1848_THINKPAD_CS4248_ENABLE_BIT	0x02
 
-struct _snd_ad1848 {
+struct snd_ad1848 {
 	unsigned long port;		/* i/o port */
 	struct resource *res_port;
 	int irq;			/* IRQ line */
@@ -137,10 +137,10 @@
 	unsigned short hardware;	/* see to AD1848_HW_XXXX */
 	unsigned short single_dma:1;	/* forced single DMA mode (GUS 16-bit daughter board) or dma1 == dma2 */
 
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
-	snd_card_t *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+	struct snd_card *card;
 
 	unsigned char image[32];	/* SGalaxy needs an access to extended registers */
 	int mce_bit;
@@ -148,25 +148,28 @@
 	int dma_size;
 	int thinkpad_flag;		/* Thinkpad CS4248 needs some extra help */
 
+#ifdef CONFIG_PM
+	void (*suspend)(struct snd_ad1848 *chip);
+	void (*resume)(struct snd_ad1848 *chip);
+#endif
+
 	spinlock_t reg_lock;
 	struct semaphore open_mutex;
 };
 
-typedef struct _snd_ad1848 ad1848_t;
-
 /* exported functions */
 
-void snd_ad1848_out(ad1848_t *chip, unsigned char reg, unsigned char value);
+void snd_ad1848_out(struct snd_ad1848 *chip, unsigned char reg, unsigned char value);
 
-int snd_ad1848_create(snd_card_t * card,
+int snd_ad1848_create(struct snd_card *card,
 		      unsigned long port,
 		      int irq, int dma,
 		      unsigned short hardware,
-		      ad1848_t ** chip);
+		      struct snd_ad1848 ** chip);
 
-int snd_ad1848_pcm(ad1848_t * chip, int device, snd_pcm_t **rpcm);
-const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction);
-int snd_ad1848_mixer(ad1848_t * chip);
+int snd_ad1848_pcm(struct snd_ad1848 * chip, int device, struct snd_pcm **rpcm);
+const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction);
+int snd_ad1848_mixer(struct snd_ad1848 * chip);
 
 /* exported mixer stuffs */
 enum { AD1848_MIX_SINGLE, AD1848_MIX_DOUBLE, AD1848_MIX_CAPTURE };
@@ -176,7 +179,7 @@
 #define AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) \
 	((left_reg) | ((right_reg) << 8) | ((shift_left) << 16) | ((shift_right) << 19) | ((mask) << 24) | ((invert) << 22))
 
-int snd_ad1848_add_ctl(ad1848_t *chip, const char *name, int index, int type, unsigned long value);
+int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int type, unsigned long value);
 
 /* for ease of use */
 struct ad1848_mix_elem {
@@ -198,7 +201,7 @@
   .type = AD1848_MIX_DOUBLE, \
   .private_value = AD1848_MIXVAL_DOUBLE(left_reg, right_reg, shift_left, shift_right, mask, invert) }
 
-static inline int snd_ad1848_add_ctl_elem(ad1848_t *chip, const struct ad1848_mix_elem *c)
+static inline int snd_ad1848_add_ctl_elem(struct snd_ad1848 *chip, const struct ad1848_mix_elem *c)
 {
 	return snd_ad1848_add_ctl(chip, c->name, c->index, c->type, c->private_value);
 }
diff --git a/include/sound/ainstr_fm.h b/include/sound/ainstr_fm.h
index 0ec0295..c4afb1f 100644
--- a/include/sound/ainstr_fm.h
+++ b/include/sound/ainstr_fm.h
@@ -39,13 +39,13 @@
  * FM operator
  */
 
-typedef struct fm_operator {
+struct fm_operator {
 	unsigned char am_vib;
 	unsigned char ksl_level;
 	unsigned char attack_decay;
 	unsigned char sustain_release;
 	unsigned char wave_select;
-} fm_operator_t;
+};
 
 /*
  *  Instrument
@@ -54,11 +54,11 @@
 #define FM_PATCH_OPL2	0x01		/* OPL2 2 operators FM instrument */
 #define FM_PATCH_OPL3	0x02		/* OPL3 4 operators FM instrument */
 
-typedef struct {
+struct fm_instrument {
 	unsigned int share_id[4];	/* share id - zero = no sharing */
 	unsigned char type;		/* instrument type */
 
-	fm_operator_t op[4];
+	struct fm_operator op[4];
 	unsigned char feedback_connection[2];
 
 	unsigned char echo_delay;
@@ -68,7 +68,7 @@
 	unsigned char fix_dur;
 	unsigned char modes;
 	unsigned char fix_key;
-} fm_instrument_t;
+};
 
 /*
  *
@@ -88,25 +88,25 @@
  * FM operator
  */
 
-typedef struct fm_xoperator {
+struct fm_xoperator {
 	__u8 am_vib;
 	__u8 ksl_level;
 	__u8 attack_decay;
 	__u8 sustain_release;
 	__u8 wave_select;
-} fm_xoperator_t;
+};
 
 /*
  *  Instrument
  */
 
-typedef struct fm_xinstrument {
+struct fm_xinstrument {
 	__u32 stype;			/* structure type */
 
 	__u32 share_id[4];		/* share id - zero = no sharing */
 	__u8 type;			/* instrument type */
 
-	fm_xoperator_t op[4];		/* fm operators */
+	struct fm_xoperator op[4];		/* fm operators */
 	__u8 feedback_connection[2];
 
 	__u8 echo_delay;
@@ -116,15 +116,19 @@
 	__u8 fix_dur;
 	__u8 modes;
 	__u8 fix_key;
-} fm_xinstrument_t;
+};
 
 #ifdef __KERNEL__
 
 #include "seq_instr.h"
 
-int snd_seq_fm_init(snd_seq_kinstr_ops_t * ops,
-		    snd_seq_kinstr_ops_t * next);
+int snd_seq_fm_init(struct snd_seq_kinstr_ops * ops,
+		    struct snd_seq_kinstr_ops * next);
 
 #endif
 
+/* typedefs for compatibility to user-space */
+typedef struct fm_xoperator fm_xoperator_t;
+typedef struct fm_xinstrument fm_xinstrument_t;
+
 #endif	/* __SOUND_AINSTR_FM_H */
diff --git a/include/sound/ainstr_gf1.h b/include/sound/ainstr_gf1.h
index ae2ddda..47726fe 100644
--- a/include/sound/ainstr_gf1.h
+++ b/include/sound/ainstr_gf1.h
@@ -52,7 +52,7 @@
  *  Wavetable definitions
  */
 
-typedef struct gf1_wave {
+struct gf1_wave {
 	unsigned int share_id[4];	/* share id - zero = no sharing */
 	unsigned int format;		/* wave format */
 
@@ -88,7 +88,7 @@
 	unsigned short scale_factor;	/* 0-2048 or 0-2 */
   
 	struct gf1_wave *next;
-} gf1_wave_t;
+};
 
 /*
  *  Instrument
@@ -103,7 +103,7 @@
 #define IWFFFF_EFFECT_CHORUS		2
 #define IWFFFF_EFFECT_ECHO		3
 
-typedef struct {
+struct gf1_instrument {
 	unsigned short exclusion;
 	unsigned short exclusion_group;	/* 0 - none, 1-65535 */
 
@@ -112,8 +112,8 @@
 	unsigned char effect2;		/* effect 2 */
 	unsigned char effect2_depth;	/* 0-127 */
 
-	gf1_wave_t *wave;		/* first waveform */
-} gf1_instrument_t;
+	struct gf1_wave *wave;		/* first waveform */
+};
 
 /*
  *
@@ -135,7 +135,7 @@
  *  Wavetable definitions
  */
 
-typedef struct gf1_xwave {
+struct gf1_xwave {
 	__u32 stype;			/* structure type */
 
 	__u32 share_id[4];		/* share id - zero = no sharing */
@@ -165,13 +165,13 @@
 	__u8 vibrato_depth;
 	__u16 scale_frequency;
 	__u16 scale_factor;		/* 0-2048 or 0-2 */  
-} gf1_xwave_t;
+};
 
 /*
  *  Instrument
  */
 
-typedef struct gf1_xinstrument {
+struct gf1_xinstrument {
 	__u32 stype;
 	
 	__u16 exclusion;
@@ -181,7 +181,7 @@
 	__u8 effect1_depth;		/* 0-127 */
 	__u8 effect2;			/* effect 2 */
 	__u8 effect2_depth;		/* 0-127 */
-} gf1_xinstrument_t;
+};
 
 /*
  *  Instrument info
@@ -191,35 +191,39 @@
 #define GF1_INFO_TREMOLO		(1<<1)
 #define GF1_INFO_VIBRATO		(1<<2)
 
-typedef struct gf1_info {
+struct gf1_info {
 	unsigned char flags;		/* supported wave flags */
 	unsigned char pad[3];
 	unsigned int features;		/* supported features */
 	unsigned int max8_len;		/* maximum 8-bit wave length */
 	unsigned int max16_len;		/* maximum 16-bit wave length */
-} gf1_info_t;
+};
 
 #ifdef __KERNEL__
 
 #include "seq_instr.h"
 
-typedef struct {
+struct snd_gf1_ops {
 	void *private_data;
-	int (*info)(void *private_data, gf1_info_t *info);
-	int (*put_sample)(void *private_data, gf1_wave_t *wave,
+	int (*info)(void *private_data, struct gf1_info *info);
+	int (*put_sample)(void *private_data, struct gf1_wave *wave,
 	                  char __user *data, long len, int atomic);
-	int (*get_sample)(void *private_data, gf1_wave_t *wave,
+	int (*get_sample)(void *private_data, struct gf1_wave *wave,
 			  char __user *data, long len, int atomic);
-	int (*remove_sample)(void *private_data, gf1_wave_t *wave,
+	int (*remove_sample)(void *private_data, struct gf1_wave *wave,
 			     int atomic);
-	void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
-	snd_seq_kinstr_ops_t kops;
-} snd_gf1_ops_t;
+	void (*notify)(void *private_data, struct snd_seq_kinstr *instr, int what);
+	struct snd_seq_kinstr_ops kops;
+};
 
-int snd_seq_gf1_init(snd_gf1_ops_t *ops,
+int snd_seq_gf1_init(struct snd_gf1_ops *ops,
 		     void *private_data,
-		     snd_seq_kinstr_ops_t *next);
+		     struct snd_seq_kinstr_ops *next);
 
 #endif
 
+/* typedefs for compatibility to user-space */
+typedef struct gf1_xwave gf1_xwave_t;
+typedef struct gf1_xinstrument gf1_xinstrument_t;
+
 #endif /* __SOUND_AINSTR_GF1_H */
diff --git a/include/sound/ainstr_iw.h b/include/sound/ainstr_iw.h
index 8adf744..251feaf 100644
--- a/include/sound/ainstr_iw.h
+++ b/include/sound/ainstr_iw.h
@@ -54,7 +54,7 @@
  *  Wavetable definitions
  */
 
-typedef struct iwffff_wave {
+struct iwffff_wave {
 	unsigned int share_id[4];	/* share id - zero = no sharing */
 	unsigned int format;		/* wave format */
 
@@ -76,7 +76,7 @@
 	unsigned char pad;
   
 	struct iwffff_wave *next;
-} iwffff_wave_t;
+};
 
 /*
  *  Layer
@@ -85,13 +85,13 @@
 #define IWFFFF_LFO_SHAPE_TRIANGLE	0
 #define IWFFFF_LFO_SHAPE_POSTRIANGLE	1
 
-typedef struct iwffff_lfo {
+struct iwffff_lfo {
 	unsigned short freq;		/* (0-2047) 0.01Hz - 21.5Hz */
 	signed short depth;		/* volume +- (0-255) 0.48675dB/step */
 	signed short sweep;		/* 0 - 950 deciseconds */
 	unsigned char shape;		/* see to IWFFFF_LFO_SHAPE_XXXX */
 	unsigned char delay;		/* 0 - 255 deciseconds */
-} iwffff_lfo_t;
+};
 
 #define IWFFFF_ENV_FLAG_RETRIGGER	0x0001	/* flag - retrigger */
 
@@ -102,12 +102,12 @@
 #define IWFFFF_ENV_INDEX_VELOCITY	0x0001	/* index - velocity */
 #define IWFFFF_ENV_INDEX_FREQUENCY	0x0002	/* index - frequency */
 
-typedef struct iwffff_env_point {
+struct iwffff_env_point {
 	unsigned short offset;
 	unsigned short rate;
-} iwffff_env_point_t;
+};
 
-typedef struct iwffff_env_record {
+struct iwffff_env_record {
 	unsigned short nattack;
 	unsigned short nrelease;
 	unsigned short sustain_offset;
@@ -118,15 +118,15 @@
 	struct iwffff_env_record *next;
 	/* points are stored here */
 	/* count of points = nattack + nrelease */
-} iwffff_env_record_t;
+};
 
-typedef struct iwffff_env {
+struct iwffff_env {
 	unsigned char flags;
   	unsigned char mode;
   	unsigned char index;
 	unsigned char pad;
 	struct iwffff_env_record *record;
-} iwffff_env_t;
+};
 
 #define IWFFFF_LAYER_FLAG_RETRIGGER	0x0001	/* retrigger */
 
@@ -138,7 +138,7 @@
 #define IWFFFF_LAYER_EVENT_RETRIG	0x0002	/* layer event - retrigger */
 #define IWFFFF_LAYER_EVENT_LEGATO	0x0003	/* layer event - legato */
 
-typedef struct iwffff_layer {
+struct iwffff_layer {
 	unsigned char flags;
 	unsigned char velocity_mode;
       	unsigned char layer_event;
@@ -147,17 +147,17 @@
 	unsigned char pan;		/* pan offset from CC1 (0 left - 127 right) */
 	unsigned char pan_freq_scale;	/* position based on frequency (0-127) */
 	unsigned char attenuation;	/* 0-127 (no corresponding midi controller) */
-	iwffff_lfo_t tremolo;		/* tremolo effect */
-	iwffff_lfo_t vibrato;		/* vibrato effect */
+	struct iwffff_lfo tremolo;		/* tremolo effect */
+	struct iwffff_lfo vibrato;		/* vibrato effect */
 	unsigned short freq_scale;	/* 0-2048, 1024 is equal to semitone scaling */
 	unsigned char freq_center;	/* center for keyboard frequency scaling */
 	unsigned char pad;
-	iwffff_env_t penv;		/* pitch envelope */
-	iwffff_env_t venv;		/* volume envelope */
+	struct iwffff_env penv;		/* pitch envelope */
+	struct iwffff_env venv;		/* volume envelope */
 
-	iwffff_wave_t *wave;
+	struct iwffff_wave *wave;
 	struct iwffff_layer *next;
-} iwffff_layer_t;
+};
 
 /*
  *  Instrument
@@ -177,7 +177,7 @@
 #define IWFFFF_EFFECT_CHORUS		2
 #define IWFFFF_EFFECT_ECHO		3
 
-typedef struct {
+struct iwffff_instrument {
 	unsigned short exclusion;
 	unsigned short layer_type;
 	unsigned short exclusion_group;	/* 0 - none, 1-65535 */
@@ -187,8 +187,8 @@
 	unsigned char effect2;		/* effect 2 */
 	unsigned char effect2_depth;	/* 0-127 */
 
-	iwffff_layer_t *layer;		/* first layer */
-} iwffff_instrument_t;
+	struct iwffff_layer *layer;		/* first layer */
+};
 
 /*
  *
@@ -216,7 +216,7 @@
  *  Wavetable definitions
  */
 
-typedef struct iwffff_xwave {
+struct iwffff_xwave {
 	__u32 stype;			/* structure type */
 
 	__u32 share_id[4];		/* share id - zero = no sharing */
@@ -234,26 +234,26 @@
 	__u8 low_note;			/* lower frequency range for this waveform */
 	__u8 high_note;			/* higher frequency range for this waveform */
 	__u8 pad;
-} iwffff_xwave_t;
+};
 
 /*
  *  Layer
  */
 
-typedef struct iwffff_xlfo {
+struct iwffff_xlfo {
 	__u16 freq;			/* (0-2047) 0.01Hz - 21.5Hz */
 	__s16 depth;			/* volume +- (0-255) 0.48675dB/step */
 	__s16 sweep;			/* 0 - 950 deciseconds */
 	__u8 shape;			/* see to ULTRA_IW_LFO_SHAPE_XXXX */
 	__u8 delay;			/* 0 - 255 deciseconds */
-} iwffff_xlfo_t;
+};
 
-typedef struct iwffff_xenv_point {
+struct iwffff_xenv_point {
 	__u16 offset;
 	__u16 rate;
-} iwffff_xenv_point_t;
+};
 
-typedef struct iwffff_xenv_record {
+struct iwffff_xenv_record {
 	__u32 stype;
 	__u16 nattack;
 	__u16 nrelease;
@@ -264,16 +264,16 @@
 	__u8 pad;
 	/* points are stored here.. */
 	/* count of points = nattack + nrelease */
-} iwffff_xenv_record_t;
+};
 
-typedef struct iwffff_xenv {
+struct iwffff_xenv {
 	__u8 flags;
   	__u8 mode;
   	__u8 index;
 	__u8 pad;
-} iwffff_xenv_t;
+};
 
-typedef struct iwffff_xlayer {
+struct iwffff_xlayer {
 	__u32 stype;
 	__u8 flags;
 	__u8 velocity_mode;
@@ -283,20 +283,20 @@
 	__u8 pan;			/* pan offset from CC1 (0 left - 127 right) */
 	__u8 pan_freq_scale;		/* position based on frequency (0-127) */
 	__u8 attenuation;		/* 0-127 (no corresponding midi controller) */
-	iwffff_xlfo_t tremolo;		/* tremolo effect */
-	iwffff_xlfo_t vibrato;		/* vibrato effect */
+	struct iwffff_xlfo tremolo;		/* tremolo effect */
+	struct iwffff_xlfo vibrato;		/* vibrato effect */
 	__u16 freq_scale;		/* 0-2048, 1024 is equal to semitone scaling */
 	__u8 freq_center;		/* center for keyboard frequency scaling */
 	__u8 pad;
-	iwffff_xenv_t penv;		/* pitch envelope */
-	iwffff_xenv_t venv;		/* volume envelope */
-} iwffff_xlayer_t;
+	struct iwffff_xenv penv;		/* pitch envelope */
+	struct iwffff_xenv venv;		/* volume envelope */
+};
 
 /*
  *  Instrument
  */
 
-typedef struct iwffff_xinstrument {
+struct iwffff_xinstrument {
 	__u32 stype;
 	
 	__u16 exclusion;
@@ -307,7 +307,7 @@
 	__u8 effect1_depth;		/* 0-127 */
 	__u8 effect2;			/* effect 2 */
 	__u8 effect2_depth;		/* 0-127 */
-} iwffff_xinstrument_t;
+};
 
 /*
  *  ROM support
@@ -316,7 +316,7 @@
 
 #define IWFFFF_ROM_HDR_SIZE	512
 
-typedef struct {
+struct iwffff_rom_header {
 	__u8 iwave[8];
 	__u8 revision;
 	__u8 series_number;
@@ -328,7 +328,7 @@
 	__u8 copyright[128];
 	__u8 vendor_name[64];
 	__u8 description[128];
-} iwffff_rom_header_t;
+};
 
 /*
  *  Instrument info
@@ -339,35 +339,46 @@
 #define IWFFFF_INFO_LFO_TREMOLO		(1<<2)
 #define IWFFFF_INFO_LFO_TREMOLO_SHAPE	(1<<3)
 
-typedef struct iwffff_info {
+struct iwffff_info {
 	unsigned int format;		/* supported format bits */
 	unsigned int effects;		/* supported effects (1 << IWFFFF_EFFECT*) */
 	unsigned int lfos;		/* LFO effects */
 	unsigned int max8_len;		/* maximum 8-bit wave length */
 	unsigned int max16_len;		/* maximum 16-bit wave length */
-} iwffff_info_t;
+};
 
 #ifdef __KERNEL__
 
 #include "seq_instr.h"
 
-typedef struct {
+struct snd_iwffff_ops {
 	void *private_data;
-	int (*info)(void *private_data, iwffff_info_t *info);
-	int (*put_sample)(void *private_data, iwffff_wave_t *wave,
+	int (*info)(void *private_data, struct iwffff_info *info);
+	int (*put_sample)(void *private_data, struct iwffff_wave *wave,
 	                  char __user *data, long len, int atomic);
-	int (*get_sample)(void *private_data, iwffff_wave_t *wave,
+	int (*get_sample)(void *private_data, struct iwffff_wave *wave,
 			  char __user *data, long len, int atomic);
-	int (*remove_sample)(void *private_data, iwffff_wave_t *wave,
+	int (*remove_sample)(void *private_data, struct iwffff_wave *wave,
 			     int atomic);
-	void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
-	snd_seq_kinstr_ops_t kops;
-} snd_iwffff_ops_t;
+	void (*notify)(void *private_data, struct snd_seq_kinstr *instr, int what);
+	struct snd_seq_kinstr_ops kops;
+};
 
-int snd_seq_iwffff_init(snd_iwffff_ops_t *ops,
+int snd_seq_iwffff_init(struct snd_iwffff_ops *ops,
 			void *private_data,
-                        snd_seq_kinstr_ops_t *next);
+                        struct snd_seq_kinstr_ops *next);
 
 #endif
 
+/* typedefs for compatibility to user-space */
+typedef struct iwffff_xwave iwffff_xwave_t;
+typedef struct iwffff_xlfo iwffff_xlfo_t;
+typedef struct iwffff_xenv_point iwffff_xenv_point_t;
+typedef struct iwffff_xenv_record iwffff_xenv_record_t;
+typedef struct iwffff_xenv iwffff_xenv_t;
+typedef struct iwffff_xlayer iwffff_xlayer_t;
+typedef struct iwffff_xinstrument iwffff_xinstrument_t;
+typedef struct iwffff_rom_header iwffff_rom_header_t;
+typedef struct iwffff_info iwffff_info_t;
+
 #endif /* __SOUND_AINSTR_IW_H */
diff --git a/include/sound/ainstr_simple.h b/include/sound/ainstr_simple.h
index 40824b4..5eead12 100644
--- a/include/sound/ainstr_simple.h
+++ b/include/sound/ainstr_simple.h
@@ -61,18 +61,18 @@
  *  instrument info
  */
 
-typedef struct simple_instrument_info {
+struct simple_instrument_info {
 	unsigned int format;		/* supported format bits */
 	unsigned int effects;		/* supported effects (1 << SIMPLE_EFFECT_*) */
 	unsigned int max8_len;		/* maximum 8-bit wave length */
 	unsigned int max16_len;		/* maximum 16-bit wave length */
-} simple_instrument_info_t;
+};
 
 /*
  *  Instrument
  */
 
-typedef struct {
+struct simple_instrument {
 	unsigned int share_id[4];	/* share id - zero = no sharing */
 	unsigned int format;		/* wave format */
 
@@ -92,7 +92,7 @@
 	unsigned char effect1_depth;	/* 0-127 */
 	unsigned char effect2;		/* effect 2 */
 	unsigned char effect2_depth;	/* 0-127 */
-} simple_instrument_t;
+};
 
 /*
  *
@@ -112,7 +112,7 @@
  *  Instrument
  */
 
-typedef struct simple_xinstrument {
+struct simple_xinstrument {
 	__u32 stype;
 
 	__u32 share_id[4];		/* share id - zero = no sharing */
@@ -128,29 +128,32 @@
 	__u8 effect1_depth;		/* 0-127 */
 	__u8 effect2;			/* effect 2 */
 	__u8 effect2_depth;		/* 0-127 */
-} simple_xinstrument_t;
+};
 
 #ifdef __KERNEL__
 
 #include "seq_instr.h"
 
-typedef struct {
+struct snd_simple_ops {
 	void *private_data;
-	int (*info)(void *private_data, simple_instrument_info_t *info);
-	int (*put_sample)(void *private_data, simple_instrument_t *instr,
+	int (*info)(void *private_data, struct simple_instrument_info *info);
+	int (*put_sample)(void *private_data, struct simple_instrument *instr,
 	                  char __user *data, long len, int atomic);
-	int (*get_sample)(void *private_data, simple_instrument_t *instr,
+	int (*get_sample)(void *private_data, struct simple_instrument *instr,
 			  char __user *data, long len, int atomic);
-	int (*remove_sample)(void *private_data, simple_instrument_t *instr,
+	int (*remove_sample)(void *private_data, struct simple_instrument *instr,
 			     int atomic);
-	void (*notify)(void *private_data, snd_seq_kinstr_t *instr, int what);
-	snd_seq_kinstr_ops_t kops;
-} snd_simple_ops_t;
+	void (*notify)(void *private_data, struct snd_seq_kinstr *instr, int what);
+	struct snd_seq_kinstr_ops kops;
+};
 
-int snd_seq_simple_init(snd_simple_ops_t *ops,
+int snd_seq_simple_init(struct snd_simple_ops *ops,
 			void *private_data,
-			snd_seq_kinstr_ops_t *next);
+			struct snd_seq_kinstr_ops *next);
 
 #endif
 
+/* typedefs for compatibility to user-space */
+typedef struct simple_xinstrument simple_xinstrument_t;
+
 #endif /* __SOUND_AINSTR_SIMPLE_H */
diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h
index f3f2c3e..11702aa 100644
--- a/include/sound/ak4114.h
+++ b/include/sound/ak4114.h
@@ -163,10 +163,8 @@
 typedef void (ak4114_write_t)(void *private_data, unsigned char addr, unsigned char data);
 typedef unsigned char (ak4114_read_t)(void *private_data, unsigned char addr);
 
-typedef struct ak4114 ak4114_t;
-
 struct ak4114 {
-	snd_card_t * card;
+	struct snd_card *card;
 	ak4114_write_t * write;
 	ak4114_read_t * read;
 	void * private_data;
@@ -174,9 +172,9 @@
 	spinlock_t lock;
 	unsigned char regmap[7];
 	unsigned char txcsb[5];
-	snd_kcontrol_t *kctls[AK4114_CONTROLS];
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_kcontrol *kctls[AK4114_CONTROLS];
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
 	unsigned long parity_errors;
 	unsigned long v_bit_errors;
 	unsigned long qcrc_errors;
@@ -186,20 +184,20 @@
 	struct workqueue_struct *workqueue;
 	struct work_struct work;
 	void *change_callback_private;
-	void (*change_callback)(ak4114_t *ak4114, unsigned char c0, unsigned char c1);
+	void (*change_callback)(struct ak4114 *ak4114, unsigned char c0, unsigned char c1);
 };
 
-int snd_ak4114_create(snd_card_t *card,
+int snd_ak4114_create(struct snd_card *card,
 		      ak4114_read_t *read, ak4114_write_t *write,
 		      unsigned char pgm[7], unsigned char txcsb[5],
-		      void *private_data, ak4114_t **r_ak4114);
-void snd_ak4114_reg_write(ak4114_t *ak4114, unsigned char reg, unsigned char mask, unsigned char val);
-void snd_ak4114_reinit(ak4114_t *ak4114);
-int snd_ak4114_build(ak4114_t *ak4114,
-		     snd_pcm_substream_t *playback_substream,
-                     snd_pcm_substream_t *capture_substream);
-int snd_ak4114_external_rate(ak4114_t *ak4114);
-int snd_ak4114_check_rate_and_errors(ak4114_t *ak4114, unsigned int flags);
+		      void *private_data, struct ak4114 **r_ak4114);
+void snd_ak4114_reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char mask, unsigned char val);
+void snd_ak4114_reinit(struct ak4114 *ak4114);
+int snd_ak4114_build(struct ak4114 *ak4114,
+		     struct snd_pcm_substream *playback_substream,
+                     struct snd_pcm_substream *capture_substream);
+int snd_ak4114_external_rate(struct ak4114 *ak4114);
+int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags);
 
 #endif /* __SOUND_AK4114_H */
 
diff --git a/include/sound/ak4117.h b/include/sound/ak4117.h
index 9e1dab1..2b96c32 100644
--- a/include/sound/ak4117.h
+++ b/include/sound/ak4117.h
@@ -155,18 +155,16 @@
 typedef void (ak4117_write_t)(void *private_data, unsigned char addr, unsigned char data);
 typedef unsigned char (ak4117_read_t)(void *private_data, unsigned char addr);
 
-typedef struct ak4117 ak4117_t;
-
 struct ak4117 {
-	snd_card_t * card;
+	struct snd_card *card;
 	ak4117_write_t * write;
 	ak4117_read_t * read;
 	void * private_data;
 	unsigned int init: 1;
 	spinlock_t lock;
 	unsigned char regmap[5];
-	snd_kcontrol_t *kctls[AK4117_CONTROLS];
-	snd_pcm_substream_t *substream;
+	struct snd_kcontrol *kctls[AK4117_CONTROLS];
+	struct snd_pcm_substream *substream;
 	unsigned long parity_errors;
 	unsigned long v_bit_errors;
 	unsigned long qcrc_errors;
@@ -176,16 +174,16 @@
 	unsigned char rcs2;
 	struct timer_list timer;	/* statistic timer */
 	void *change_callback_private;
-	void (*change_callback)(ak4117_t *ak4117, unsigned char c0, unsigned char c1);
+	void (*change_callback)(struct ak4117 *ak4117, unsigned char c0, unsigned char c1);
 };
 
-int snd_ak4117_create(snd_card_t *card, ak4117_read_t *read, ak4117_write_t *write,
-		      unsigned char pgm[5], void *private_data, ak4117_t **r_ak4117);
-void snd_ak4117_reg_write(ak4117_t *ak4117, unsigned char reg, unsigned char mask, unsigned char val);
-void snd_ak4117_reinit(ak4117_t *ak4117);
-int snd_ak4117_build(ak4117_t *ak4117, snd_pcm_substream_t *capture_substream);
-int snd_ak4117_external_rate(ak4117_t *ak4117);
-int snd_ak4117_check_rate_and_errors(ak4117_t *ak4117, unsigned int flags);
+int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t *write,
+		      unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117);
+void snd_ak4117_reg_write(struct ak4117 *ak4117, unsigned char reg, unsigned char mask, unsigned char val);
+void snd_ak4117_reinit(struct ak4117 *ak4117);
+int snd_ak4117_build(struct ak4117 *ak4117, struct snd_pcm_substream *capture_substream);
+int snd_ak4117_external_rate(struct ak4117 *ak4117);
+int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags);
 
 #endif /* __SOUND_AK4117_H */
 
diff --git a/include/sound/ak4531_codec.h b/include/sound/ak4531_codec.h
index 8b18992..edf0407 100644
--- a/include/sound/ak4531_codec.h
+++ b/include/sound/ak4531_codec.h
@@ -64,17 +64,22 @@
 #define AK4531_AD_IN    0x18	/* AD input select */
 #define AK4531_MIC_GAIN 0x19	/* MIC amplified gain */
 
-typedef struct _snd_ak4531 ak4531_t;
-
-struct _snd_ak4531 {
-	void (*write) (ak4531_t *ak4531, unsigned short reg, unsigned short val);
+struct snd_ak4531 {
+	void (*write) (struct snd_ak4531 *ak4531, unsigned short reg,
+		       unsigned short val);
 	void *private_data;
-	void (*private_free) (ak4531_t *ak4531);
+	void (*private_free) (struct snd_ak4531 *ak4531);
 	/* --- */
 	unsigned char regs[0x20];
 	struct semaphore reg_mutex;
 };
 
-int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531);
+int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531,
+		     struct snd_ak4531 **rak4531);
+
+#ifdef CONFIG_PM
+void snd_ak4531_suspend(struct snd_ak4531 *ak4531);
+void snd_ak4531_resume(struct snd_ak4531 *ak4531);
+#endif
 
 #endif /* __SOUND_AK4531_CODEC_H */
diff --git a/include/sound/ak4xxx-adda.h b/include/sound/ak4xxx-adda.h
index e94ac02..3bf5911 100644
--- a/include/sound/ak4xxx-adda.h
+++ b/include/sound/ak4xxx-adda.h
@@ -27,20 +27,20 @@
 #define AK4XXX_MAX_CHIPS	4
 #endif
 
-typedef struct snd_akm4xxx akm4xxx_t;
+struct snd_akm4xxx;
 
 struct snd_ak4xxx_ops {
-	void (*lock)(akm4xxx_t *ak, int chip);
-	void (*unlock)(akm4xxx_t *ak, int chip);
-	void (*write)(akm4xxx_t *ak, int chip, unsigned char reg, unsigned char val);
-	// unsigned char (*read)(akm4xxx_t *ak, int chip, unsigned char reg);
-	void (*set_rate_val)(akm4xxx_t *ak, unsigned int rate);
+	void (*lock)(struct snd_akm4xxx *ak, int chip);
+	void (*unlock)(struct snd_akm4xxx *ak, int chip);
+	void (*write)(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val);
+	// unsigned char (*read)(struct snd_akm4xxx *ak, int chip, unsigned char reg);
+	void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate);
 };
 
 #define AK4XXX_IMAGE_SIZE	(AK4XXX_MAX_CHIPS * 16)	/* 64 bytes */
 
 struct snd_akm4xxx {
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned int num_adcs;				/* AK4524 or AK4528 ADCs */
 	unsigned int num_dacs;				/* AK4524 or AK4528 DACs */
 	unsigned char images[AK4XXX_IMAGE_SIZE];	/* saved register image */
@@ -56,10 +56,10 @@
 	struct snd_ak4xxx_ops ops;
 };
 
-void snd_akm4xxx_write(akm4xxx_t *ak, int chip, unsigned char reg, unsigned char val);
-void snd_akm4xxx_reset(akm4xxx_t *ak, int state);
-void snd_akm4xxx_init(akm4xxx_t *ak);
-int snd_akm4xxx_build_controls(akm4xxx_t *ak);
+void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val);
+void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state);
+void snd_akm4xxx_init(struct snd_akm4xxx *ak);
+int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak);
 
 #define snd_akm4xxx_get(ak,chip,reg) (ak)->images[(chip) * 16 + (reg)]
 #define snd_akm4xxx_set(ak,chip,reg,val) ((ak)->images[(chip) * 16 + (reg)] = (val))
diff --git a/include/sound/asequencer.h b/include/sound/asequencer.h
index 728efd5..6691e4a 100644
--- a/include/sound/asequencer.h
+++ b/include/sound/asequencer.h
@@ -22,11 +22,10 @@
 #ifndef __SOUND_ASEQUENCER_H
 #define __SOUND_ASEQUENCER_H
 
-#ifndef __KERNEL__
+#ifdef __KERNEL__
 #include <linux/ioctl.h>
-#endif
-
 #include <sound/asound.h>
+#endif
 
 /** version of the sequencer */
 #define SNDRV_SEQ_VERSION SNDRV_PROTOCOL_VERSION (1, 0, 1)
@@ -36,13 +35,13 @@
  */
 
 /** system messages
- * event data type = #sndrv_seq_result_t
+ * event data type = #snd_seq_result
  */
 #define SNDRV_SEQ_EVENT_SYSTEM		0
 #define SNDRV_SEQ_EVENT_RESULT		1
 
 /** note messages (channel specific)
- * event data type = #sndrv_seq_ev_note
+ * event data type = #snd_seq_ev_note
  */
 #define SNDRV_SEQ_EVENT_NOTE		5
 #define SNDRV_SEQ_EVENT_NOTEON		6
@@ -50,7 +49,7 @@
 #define SNDRV_SEQ_EVENT_KEYPRESS	8
 	
 /** control messages (channel specific)
- * event data type = #sndrv_seq_ev_ctrl
+ * event data type = #snd_seq_ev_ctrl
  */
 #define SNDRV_SEQ_EVENT_CONTROLLER	10
 #define SNDRV_SEQ_EVENT_PGMCHANGE	11
@@ -61,7 +60,7 @@
 #define SNDRV_SEQ_EVENT_REGPARAM	16	/**< 14 bit RPN address + 14 bit unsigned value */
 
 /** synchronisation messages
- * event data type = #sndrv_seq_ev_ctrl
+ * event data type = #snd_seq_ev_ctrl
  */
 #define SNDRV_SEQ_EVENT_SONGPOS		20	/* Song Position Pointer with LSB and MSB values */
 #define SNDRV_SEQ_EVENT_SONGSEL		21	/* Song Select with song ID number */
@@ -70,7 +69,7 @@
 #define SNDRV_SEQ_EVENT_KEYSIGN		24	/* SMF Key Signature event */
 	        
 /** timer messages
- * event data type = sndrv_seq_ev_queue_control_t
+ * event data type = snd_seq_ev_queue_control
  */
 #define SNDRV_SEQ_EVENT_START		30	/* midi Real Time Start message */
 #define SNDRV_SEQ_EVENT_CONTINUE	31	/* midi Real Time Continue message */
@@ -96,7 +95,7 @@
 #define SNDRV_SEQ_EVENT_OSS		51	/* OSS raw event */
 
 /** system status messages (broadcast for subscribers)
- * event data type = sndrv_seq_addr_t
+ * event data type = snd_seq_addr
  */
 #define SNDRV_SEQ_EVENT_CLIENT_START	60	/* new client has connected */
 #define SNDRV_SEQ_EVENT_CLIENT_EXIT	61	/* client has left the system */
@@ -106,13 +105,13 @@
 #define SNDRV_SEQ_EVENT_PORT_CHANGE	65	/* port status/info has changed */
 
 /** port connection changes
- * event data type = sndrv_seq_connect_t
+ * event data type = snd_seq_connect
  */
 #define SNDRV_SEQ_EVENT_PORT_SUBSCRIBED	66	/* ports connected */
 #define SNDRV_SEQ_EVENT_PORT_UNSUBSCRIBED 67	/* ports disconnected */
 
 /** synthesizer events
- * event data type = sndrv_seq_eve_sample_control_t
+ * event data type = snd_seq_eve_sample_control
  */
 #define SNDRV_SEQ_EVENT_SAMPLE		70	/* sample select */
 #define SNDRV_SEQ_EVENT_SAMPLE_CLUSTER	71	/* sample cluster select */
@@ -163,7 +162,7 @@
 /* 119-129: reserved */
 
 /* 130-139: variable length events
- * event data type = sndrv_seq_ev_ext
+ * event data type = snd_seq_ev_ext
  * (SNDRV_SEQ_EVENT_LENGTH_VARIABLE must be set)
  */
 #define SNDRV_SEQ_EVENT_SYSEX		130	/* system exclusive data (variable length) */
@@ -187,18 +186,18 @@
 #define SNDRV_SEQ_EVENT_NONE		255
 
 
-typedef unsigned char sndrv_seq_event_type_t;
+typedef unsigned char snd_seq_event_type_t;
 
 /** event address */
-struct sndrv_seq_addr {
+struct snd_seq_addr {
 	unsigned char client;	/**< Client number:         0..255, 255 = broadcast to all clients */
 	unsigned char port;	/**< Port within client:    0..255, 255 = broadcast to all ports */
 };
 
 /** port connection */
-struct sndrv_seq_connect {
-	struct sndrv_seq_addr sender;
-	struct sndrv_seq_addr dest;
+struct snd_seq_connect {
+	struct snd_seq_addr sender;
+	struct snd_seq_addr dest;
 };
 
 
@@ -227,7 +226,7 @@
 
 
 	/* note event */
-struct sndrv_seq_ev_note {
+struct snd_seq_ev_note {
 	unsigned char channel;
 	unsigned char note;
 	unsigned char velocity;
@@ -236,7 +235,7 @@
 };
 
 	/* controller event */
-struct sndrv_seq_ev_ctrl {
+struct snd_seq_ev_ctrl {
 	unsigned char channel;
 	unsigned char unused1, unused2, unused3;	/* pad */
 	unsigned int param;
@@ -244,59 +243,59 @@
 };
 
 	/* generic set of bytes (12x8 bit) */
-struct sndrv_seq_ev_raw8 {
+struct snd_seq_ev_raw8 {
 	unsigned char d[12];	/* 8 bit value */
 };
 
 	/* generic set of integers (3x32 bit) */
-struct sndrv_seq_ev_raw32 {
+struct snd_seq_ev_raw32 {
 	unsigned int d[3];	/* 32 bit value */
 };
 
 	/* external stored data */
-struct sndrv_seq_ev_ext {
+struct snd_seq_ev_ext {
 	unsigned int len;	/* length of data */
 	void *ptr;		/* pointer to data (note: maybe 64-bit) */
 } __attribute__((packed));
 
 /* Instrument cluster type */
-typedef unsigned int sndrv_seq_instr_cluster_t;
+typedef unsigned int snd_seq_instr_cluster_t;
 
 /* Instrument type */
-struct sndrv_seq_instr {
-	sndrv_seq_instr_cluster_t cluster;
+struct snd_seq_instr {
+	snd_seq_instr_cluster_t cluster;
 	unsigned int std;		/* the upper byte means a private instrument (owner - client #) */
 	unsigned short bank;
 	unsigned short prg;
 };
 
 	/* sample number */
-struct sndrv_seq_ev_sample {
+struct snd_seq_ev_sample {
 	unsigned int std;
 	unsigned short bank;
 	unsigned short prg;
 };
 
 	/* sample cluster */
-struct sndrv_seq_ev_cluster {
-	sndrv_seq_instr_cluster_t cluster;
+struct snd_seq_ev_cluster {
+	snd_seq_instr_cluster_t cluster;
 };
 
 	/* sample position */
-typedef unsigned int sndrv_seq_position_t; /* playback position (in samples) * 16 */
+typedef unsigned int snd_seq_position_t; /* playback position (in samples) * 16 */
 
 	/* sample stop mode */
-enum sndrv_seq_stop_mode {
+enum {
 	SAMPLE_STOP_IMMEDIATELY = 0,	/* terminate playing immediately */
 	SAMPLE_STOP_VENVELOPE = 1,	/* finish volume envelope */
 	SAMPLE_STOP_LOOP = 2		/* terminate loop and finish wave */
 };
 
 	/* sample frequency */
-typedef int sndrv_seq_frequency_t; /* playback frequency in HZ * 16 */
+typedef int snd_seq_frequency_t; /* playback frequency in HZ * 16 */
 
 	/* sample volume control; if any value is set to -1 == do not change */
-struct sndrv_seq_ev_volume {
+struct snd_seq_ev_volume {
 	signed short volume;	/* range: 0-16383 */
 	signed short lr;	/* left-right balance; range: 0-16383 */
 	signed short fr;	/* front-rear balance; range: 0-16383 */
@@ -304,22 +303,22 @@
 };
 
 	/* simple loop redefinition */
-struct sndrv_seq_ev_loop {
+struct snd_seq_ev_loop {
 	unsigned int start;	/* loop start (in samples) * 16 */
 	unsigned int end;	/* loop end (in samples) * 16 */
 };
 
-struct sndrv_seq_ev_sample_control {
+struct snd_seq_ev_sample_control {
 	unsigned char channel;
 	unsigned char unused1, unused2, unused3;	/* pad */
 	union {
-		struct sndrv_seq_ev_sample sample;
-		struct sndrv_seq_ev_cluster cluster;
-		sndrv_seq_position_t position;
-		enum sndrv_seq_stop_mode stop_mode;
-		sndrv_seq_frequency_t frequency;
-		struct sndrv_seq_ev_volume volume;
-		struct sndrv_seq_ev_loop loop;
+		struct snd_seq_ev_sample sample;
+		struct snd_seq_ev_cluster cluster;
+		snd_seq_position_t position;
+		int stop_mode;
+		snd_seq_frequency_t frequency;
+		struct snd_seq_ev_volume volume;
+		struct snd_seq_ev_loop loop;
 		unsigned char raw8[8];
 	} param;
 };
@@ -327,82 +326,82 @@
 
 
 /* INSTR_BEGIN event */
-struct sndrv_seq_ev_instr_begin {
+struct snd_seq_ev_instr_begin {
 	int timeout;		/* zero = forever, otherwise timeout in ms */
 };
 
-struct sndrv_seq_result {
+struct snd_seq_result {
 	int event;		/* processed event type */
 	int result;
 };
 
 
-struct sndrv_seq_real_time {
+struct snd_seq_real_time {
 	unsigned int tv_sec;	/* seconds */
 	unsigned int tv_nsec;	/* nanoseconds */
 };
 
-typedef unsigned int sndrv_seq_tick_time_t;	/* midi ticks */
+typedef unsigned int snd_seq_tick_time_t;	/* midi ticks */
 
-union sndrv_seq_timestamp {
-	sndrv_seq_tick_time_t tick;
-	struct sndrv_seq_real_time time;
+union snd_seq_timestamp {
+	snd_seq_tick_time_t tick;
+	struct snd_seq_real_time time;
 };
 
-struct sndrv_seq_queue_skew {
+struct snd_seq_queue_skew {
 	unsigned int value;
 	unsigned int base;
 };
 
 	/* queue timer control */
-struct sndrv_seq_ev_queue_control {
+struct snd_seq_ev_queue_control {
 	unsigned char queue;			/* affected queue */
 	unsigned char pad[3];			/* reserved */
 	union {
 		signed int value;		/* affected value (e.g. tempo) */
-		union sndrv_seq_timestamp time;	/* time */
+		union snd_seq_timestamp time;	/* time */
 		unsigned int position;		/* sync position */
-		struct sndrv_seq_queue_skew skew;
+		struct snd_seq_queue_skew skew;
 		unsigned int d32[2];
 		unsigned char d8[8];
 	} param;
 };
 
 	/* quoted event - inside the kernel only */
-struct sndrv_seq_ev_quote {
-	struct sndrv_seq_addr origin;		/* original sender */
+struct snd_seq_ev_quote {
+	struct snd_seq_addr origin;		/* original sender */
 	unsigned short value;		/* optional data */
-	struct sndrv_seq_event *event;		/* quoted event */
+	struct snd_seq_event *event;		/* quoted event */
 } __attribute__((packed));
 
 
 	/* sequencer event */
-struct sndrv_seq_event {
-	sndrv_seq_event_type_t type;	/* event type */
+struct snd_seq_event {
+	snd_seq_event_type_t type;	/* event type */
 	unsigned char flags;		/* event flags */
 	char tag;
 	
 	unsigned char queue;		/* schedule queue */
-	union sndrv_seq_timestamp time;	/* schedule time */
+	union snd_seq_timestamp time;	/* schedule time */
 
 
-	struct sndrv_seq_addr source;	/* source address */
-	struct sndrv_seq_addr dest;	/* destination address */
+	struct snd_seq_addr source;	/* source address */
+	struct snd_seq_addr dest;	/* destination address */
 
 	union {				/* event data... */
-		struct sndrv_seq_ev_note note;
-		struct sndrv_seq_ev_ctrl control;
-		struct sndrv_seq_ev_raw8 raw8;
-		struct sndrv_seq_ev_raw32 raw32;
-		struct sndrv_seq_ev_ext ext;
-		struct sndrv_seq_ev_queue_control queue;
-		union sndrv_seq_timestamp time;
-		struct sndrv_seq_addr addr;
-		struct sndrv_seq_connect connect;
-		struct sndrv_seq_result result;
-		struct sndrv_seq_ev_instr_begin instr_begin;
-		struct sndrv_seq_ev_sample_control sample;
-		struct sndrv_seq_ev_quote quote;
+		struct snd_seq_ev_note note;
+		struct snd_seq_ev_ctrl control;
+		struct snd_seq_ev_raw8 raw8;
+		struct snd_seq_ev_raw32 raw32;
+		struct snd_seq_ev_ext ext;
+		struct snd_seq_ev_queue_control queue;
+		union snd_seq_timestamp time;
+		struct snd_seq_addr addr;
+		struct snd_seq_connect connect;
+		struct snd_seq_result result;
+		struct snd_seq_ev_instr_begin instr_begin;
+		struct snd_seq_ev_sample_control sample;
+		struct snd_seq_ev_quote quote;
 	} data;
 };
 
@@ -410,72 +409,77 @@
 /*
  * bounce event - stored as variable size data
  */
-struct sndrv_seq_event_bounce {
+struct snd_seq_event_bounce {
 	int err;
-	struct sndrv_seq_event event;
+	struct snd_seq_event event;
 	/* external data follows here. */
 };
 
-#define sndrv_seq_event_bounce_ext_data(ev) ((void*)((char *)(ev)->data.ext.ptr + sizeof(sndrv_seq_event_bounce_t)))
+#ifdef __KERNEL__
+
+/* helper macro */
+#define snd_seq_event_bounce_ext_data(ev) ((void*)((char *)(ev)->data.ext.ptr + sizeof(struct snd_seq_event_bounce)))
 
 /*
  * type check macros
  */
 /* result events: 0-4 */
-#define sndrv_seq_ev_is_result_type(ev)	((ev)->type < 5)
+#define snd_seq_ev_is_result_type(ev)	((ev)->type < 5)
 /* channel specific events: 5-19 */
-#define sndrv_seq_ev_is_channel_type(ev)	((ev)->type >= 5 && (ev)->type < 20)
+#define snd_seq_ev_is_channel_type(ev)	((ev)->type >= 5 && (ev)->type < 20)
 /* note events: 5-9 */
-#define sndrv_seq_ev_is_note_type(ev)	((ev)->type >= 5 && (ev)->type < 10)
+#define snd_seq_ev_is_note_type(ev)	((ev)->type >= 5 && (ev)->type < 10)
 /* control events: 10-19 */
-#define sndrv_seq_ev_is_control_type(ev)	((ev)->type >= 10 && (ev)->type < 20)
+#define snd_seq_ev_is_control_type(ev)	((ev)->type >= 10 && (ev)->type < 20)
 /* queue control events: 30-39 */
-#define sndrv_seq_ev_is_queue_type(ev)	((ev)->type >= 30 && (ev)->type < 40)
+#define snd_seq_ev_is_queue_type(ev)	((ev)->type >= 30 && (ev)->type < 40)
 /* system status messages */
-#define sndrv_seq_ev_is_message_type(ev)	((ev)->type >= 60 && (ev)->type < 69)
+#define snd_seq_ev_is_message_type(ev)	((ev)->type >= 60 && (ev)->type < 69)
 /* sample messages */
-#define sndrv_seq_ev_is_sample_type(ev)	((ev)->type >= 70 && (ev)->type < 79)
+#define snd_seq_ev_is_sample_type(ev)	((ev)->type >= 70 && (ev)->type < 79)
 /* user-defined messages */
-#define sndrv_seq_ev_is_user_type(ev)	((ev)->type >= 90 && (ev)->type < 99)
+#define snd_seq_ev_is_user_type(ev)	((ev)->type >= 90 && (ev)->type < 99)
 /* fixed length events: 0-99 */
-#define sndrv_seq_ev_is_fixed_type(ev)	((ev)->type < 100)
+#define snd_seq_ev_is_fixed_type(ev)	((ev)->type < 100)
 /* instrument layer events: 100-129 */
-#define sndrv_seq_ev_is_instr_type(ev)	((ev)->type >= 100 && (ev)->type < 130)
+#define snd_seq_ev_is_instr_type(ev)	((ev)->type >= 100 && (ev)->type < 130)
 /* variable length events: 130-139 */
-#define sndrv_seq_ev_is_variable_type(ev)	((ev)->type >= 130 && (ev)->type < 140)
+#define snd_seq_ev_is_variable_type(ev)	((ev)->type >= 130 && (ev)->type < 140)
 /* reserved for kernel */
-#define sndrv_seq_ev_is_reserved(ev)	((ev)->type >= 150)
+#define snd_seq_ev_is_reserved(ev)	((ev)->type >= 150)
 
 /* direct dispatched events */
-#define sndrv_seq_ev_is_direct(ev)	((ev)->queue == SNDRV_SEQ_QUEUE_DIRECT)
+#define snd_seq_ev_is_direct(ev)	((ev)->queue == SNDRV_SEQ_QUEUE_DIRECT)
 
 /*
  * macros to check event flags
  */
 /* prior events */
-#define sndrv_seq_ev_is_prior(ev)		(((ev)->flags & SNDRV_SEQ_PRIORITY_MASK) == SNDRV_SEQ_PRIORITY_HIGH)
+#define snd_seq_ev_is_prior(ev)		(((ev)->flags & SNDRV_SEQ_PRIORITY_MASK) == SNDRV_SEQ_PRIORITY_HIGH)
 
 /* event length type */
-#define sndrv_seq_ev_length_type(ev)	((ev)->flags & SNDRV_SEQ_EVENT_LENGTH_MASK)
-#define sndrv_seq_ev_is_fixed(ev)		(sndrv_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_FIXED)
-#define sndrv_seq_ev_is_variable(ev)	(sndrv_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
-#define sndrv_seq_ev_is_varusr(ev)	(sndrv_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_VARUSR)
+#define snd_seq_ev_length_type(ev)	((ev)->flags & SNDRV_SEQ_EVENT_LENGTH_MASK)
+#define snd_seq_ev_is_fixed(ev)		(snd_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_FIXED)
+#define snd_seq_ev_is_variable(ev)	(snd_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
+#define snd_seq_ev_is_varusr(ev)	(snd_seq_ev_length_type(ev) == SNDRV_SEQ_EVENT_LENGTH_VARUSR)
 
 /* time-stamp type */
-#define sndrv_seq_ev_timestamp_type(ev)	((ev)->flags & SNDRV_SEQ_TIME_STAMP_MASK)
-#define sndrv_seq_ev_is_tick(ev)		(sndrv_seq_ev_timestamp_type(ev) == SNDRV_SEQ_TIME_STAMP_TICK)
-#define sndrv_seq_ev_is_real(ev)		(sndrv_seq_ev_timestamp_type(ev) == SNDRV_SEQ_TIME_STAMP_REAL)
+#define snd_seq_ev_timestamp_type(ev)	((ev)->flags & SNDRV_SEQ_TIME_STAMP_MASK)
+#define snd_seq_ev_is_tick(ev)		(snd_seq_ev_timestamp_type(ev) == SNDRV_SEQ_TIME_STAMP_TICK)
+#define snd_seq_ev_is_real(ev)		(snd_seq_ev_timestamp_type(ev) == SNDRV_SEQ_TIME_STAMP_REAL)
 
 /* time-mode type */
-#define sndrv_seq_ev_timemode_type(ev)	((ev)->flags & SNDRV_SEQ_TIME_MODE_MASK)
-#define sndrv_seq_ev_is_abstime(ev)	(sndrv_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_ABS)
-#define sndrv_seq_ev_is_reltime(ev)	(sndrv_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_REL)
+#define snd_seq_ev_timemode_type(ev)	((ev)->flags & SNDRV_SEQ_TIME_MODE_MASK)
+#define snd_seq_ev_is_abstime(ev)	(snd_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_ABS)
+#define snd_seq_ev_is_reltime(ev)	(snd_seq_ev_timemode_type(ev) == SNDRV_SEQ_TIME_MODE_REL)
 
 /* queue sync port */
-#define sndrv_seq_queue_sync_port(q)	((q) + 16)
+#define snd_seq_queue_sync_port(q)	((q) + 16)
+
+#endif /* __KERNEL__ */
 
 	/* system information */
-struct sndrv_seq_system_info {
+struct snd_seq_system_info {
 	int queues;			/* maximum queues count */
 	int clients;			/* maximum clients count */
 	int ports;			/* maximum ports per client */
@@ -487,7 +491,7 @@
 
 
 	/* system running information */
-struct sndrv_seq_running_info {
+struct snd_seq_running_info {
 	unsigned char client;		/* client id */
 	unsigned char big_endian;	/* 1 = big-endian */
 	unsigned char cpu_mode;		/* 4 = 32bit, 8 = 64bit */
@@ -498,16 +502,16 @@
 
 	/* known client numbers */
 #define SNDRV_SEQ_CLIENT_SYSTEM		0
-#define SNDRV_SEQ_CLIENT_DUMMY		62	/* dummy ports */
-#define SNDRV_SEQ_CLIENT_OSS		63	/* oss sequencer emulator */
+	/* internal client numbers */
+#define SNDRV_SEQ_CLIENT_DUMMY		14	/* midi through */
+#define SNDRV_SEQ_CLIENT_OSS		15	/* oss sequencer emulator */
 
 
 	/* client types */
-enum sndrv_seq_client_type {
-	NO_CLIENT       = 0,
-	USER_CLIENT     = 1,
-	KERNEL_CLIENT   = 2
-};
+typedef int __bitwise snd_seq_client_type_t;
+#define	NO_CLIENT	((__force snd_seq_client_type_t) 0)
+#define	USER_CLIENT	((__force snd_seq_client_type_t) 1)
+#define	KERNEL_CLIENT	((__force snd_seq_client_type_t) 2)
                         
 	/* event filter flags */
 #define SNDRV_SEQ_FILTER_BROADCAST	(1<<0)	/* accept broadcast messages */
@@ -515,9 +519,9 @@
 #define SNDRV_SEQ_FILTER_BOUNCE		(1<<2)	/* accept bounce event in error */
 #define SNDRV_SEQ_FILTER_USE_EVENT	(1<<31)	/* use event filter */
 
-struct sndrv_seq_client_info {
+struct snd_seq_client_info {
 	int client;			/* client number to inquire */
-	enum sndrv_seq_client_type type;	/* client type */
+	snd_seq_client_type_t type;	/* client type */
 	char name[64];			/* client name */
 	unsigned int filter;		/* filter flags */
 	unsigned char multicast_filter[8]; /* multicast filter bitmap */
@@ -529,7 +533,7 @@
 
 
 /* client pool size */
-struct sndrv_seq_client_pool {
+struct snd_seq_client_pool {
 	int client;			/* client number to inquire */
 	int output_pool;		/* outgoing (write) pool size */
 	int input_pool;			/* incoming (read) pool size */
@@ -553,13 +557,13 @@
 #define SNDRV_SEQ_REMOVE_IGNORE_OFF 	(1<<8)	/* Do not flush off events */
 #define SNDRV_SEQ_REMOVE_TAG_MATCH 	(1<<9)	/* Restrict to events with given tag */
 
-struct sndrv_seq_remove_events {
+struct snd_seq_remove_events {
 	unsigned int  remove_mode;	/* Flags that determine what gets removed */
 
-	union sndrv_seq_timestamp time;
+	union snd_seq_timestamp time;
 
 	unsigned char queue;	/* Queue for REMOVE_DEST */
-	struct sndrv_seq_addr dest;	/* Address for REMOVE_DEST */
+	struct snd_seq_addr dest;	/* Address for REMOVE_DEST */
 	unsigned char channel;	/* Channel for REMOVE_DEST */
 
 	int  type;	/* For REMOVE_EVENT_TYPE */
@@ -608,8 +612,8 @@
 #define SNDRV_SEQ_PORT_FLG_TIMESTAMP	(1<<1)
 #define SNDRV_SEQ_PORT_FLG_TIME_REAL	(1<<2)
 
-struct sndrv_seq_port_info {
-	struct sndrv_seq_addr addr;	/* client/port numbers */
+struct snd_seq_port_info {
+	struct snd_seq_addr addr;	/* client/port numbers */
 	char name[64];			/* port name */
 
 	unsigned int capability;	/* port capability bits */
@@ -632,7 +636,7 @@
 #define SNDRV_SEQ_QUEUE_FLG_SYNC	(1<<0)	/* sync enabled */
 
 /* queue information */
-struct sndrv_seq_queue_info {
+struct snd_seq_queue_info {
 	int queue;		/* queue id */
 
 	/*
@@ -648,11 +652,11 @@
 };
 
 /* queue info/status */
-struct sndrv_seq_queue_status {
+struct snd_seq_queue_status {
 	int queue;			/* queue id */
 	int events;			/* read-only - queue size */
-	sndrv_seq_tick_time_t tick;	/* current tick */
-	struct sndrv_seq_real_time time; /* current time */
+	snd_seq_tick_time_t tick;	/* current tick */
+	struct snd_seq_real_time time;	/* current time */
 	int running;			/* running state of queue */
 	int flags;			/* various flags */
 	char reserved[64];		/* for the future */
@@ -660,7 +664,7 @@
 
 
 /* queue tempo */
-struct sndrv_seq_queue_tempo {
+struct snd_seq_queue_tempo {
 	int queue;			/* sequencer queue */
 	unsigned int tempo;		/* current tempo, us/tick */
 	int ppq;			/* time resolution, ticks/quarter */
@@ -676,12 +680,12 @@
 #define SNDRV_SEQ_TIMER_MIDI_TICK	2	/* Midi Timer Tick (TICK event) */
 
 /* queue timer info */
-struct sndrv_seq_queue_timer {
+struct snd_seq_queue_timer {
 	int queue;			/* sequencer queue */
 	int type;			/* source timer type */
 	union {
 		struct {
-			struct sndrv_timer_id id;	/* ALSA's timer ID */
+			struct snd_timer_id id;	/* ALSA's timer ID */
 			unsigned int resolution;	/* resolution in Hz */
 		} alsa;
 	} u;
@@ -689,7 +693,7 @@
 };
 
 
-struct sndrv_seq_queue_client {
+struct snd_seq_queue_client {
 	int queue;		/* sequencer queue */
 	int client;		/* sequencer client */
 	int used;		/* queue is used with this client
@@ -703,9 +707,9 @@
 #define SNDRV_SEQ_PORT_SUBS_TIMESTAMP	(1<<1)
 #define SNDRV_SEQ_PORT_SUBS_TIME_REAL	(1<<2)
 
-struct sndrv_seq_port_subscribe {
-	struct sndrv_seq_addr sender;	/* sender address */
-	struct sndrv_seq_addr dest;	/* destination address */
+struct snd_seq_port_subscribe {
+	struct snd_seq_addr sender;	/* sender address */
+	struct snd_seq_addr dest;	/* destination address */
 	unsigned int voices;		/* number of voices to be allocated (0 = don't care) */
 	unsigned int flags;		/* modes */
 	unsigned char queue;		/* input time-stamp queue (optional) */
@@ -717,12 +721,12 @@
 #define SNDRV_SEQ_QUERY_SUBS_READ	0
 #define SNDRV_SEQ_QUERY_SUBS_WRITE	1
 
-struct sndrv_seq_query_subs {
-	struct sndrv_seq_addr root;	/* client/port id to be searched */
+struct snd_seq_query_subs {
+	struct snd_seq_addr root;	/* client/port id to be searched */
 	int type;		/* READ or WRITE */
 	int index;		/* 0..N-1 */
 	int num_subs;		/* R/O: number of subscriptions on this port */
-	struct sndrv_seq_addr addr;	/* R/O: result */
+	struct snd_seq_addr addr;	/* R/O: result */
 	unsigned char queue;	/* R/O: result */
 	unsigned int flags;	/* R/O: result */
 	char reserved[64];	/* for future use */
@@ -779,72 +783,72 @@
 #define SNDRV_SEQ_INSTR_FREE_CMD_SINGLE		3
 
 /* size of ROM/RAM */
-typedef unsigned int sndrv_seq_instr_size_t;
+typedef unsigned int snd_seq_instr_size_t;
 
 /* INSTR_INFO */
 
-struct sndrv_seq_instr_info {
+struct snd_seq_instr_info {
 	int result;			/* operation result */
 	unsigned int formats[8];	/* bitmap of supported formats */
 	int ram_count;			/* count of RAM banks */
-	sndrv_seq_instr_size_t ram_sizes[16]; /* size of RAM banks */
+	snd_seq_instr_size_t ram_sizes[16]; /* size of RAM banks */
 	int rom_count;			/* count of ROM banks */
-	sndrv_seq_instr_size_t rom_sizes[8]; /* size of ROM banks */
+	snd_seq_instr_size_t rom_sizes[8]; /* size of ROM banks */
 	char reserved[128];
 };
 
 /* INSTR_STATUS */
 
-struct sndrv_seq_instr_status {
+struct snd_seq_instr_status {
 	int result;			/* operation result */
-	sndrv_seq_instr_size_t free_ram[16]; /* free RAM in banks */
+	snd_seq_instr_size_t free_ram[16]; /* free RAM in banks */
 	int instrument_count;		/* count of downloaded instruments */
 	char reserved[128];
 };
 
 /* INSTR_FORMAT_INFO */
 
-struct sndrv_seq_instr_format_info {
+struct snd_seq_instr_format_info {
 	char format[16];		/* format identifier - SNDRV_SEQ_INSTR_ID_* */	
 	unsigned int len;		/* max data length (without this structure) */
 };
 
-struct sndrv_seq_instr_format_info_result {
+struct snd_seq_instr_format_info_result {
 	int result;			/* operation result */
 	char format[16];		/* format identifier */
 	unsigned int len;		/* filled data length (without this structure) */
 };
 
 /* instrument data */
-struct sndrv_seq_instr_data {
+struct snd_seq_instr_data {
 	char name[32];			/* instrument name */
 	char reserved[16];		/* for the future use */
 	int type;			/* instrument type */
 	union {
 		char format[16];	/* format identifier */
-		struct sndrv_seq_instr alias;
+		struct snd_seq_instr alias;
 	} data;
 };
 
 /* INSTR_PUT/GET, data are stored in one block (extended), header + data */
 
-struct sndrv_seq_instr_header {
+struct snd_seq_instr_header {
 	union {
-		struct sndrv_seq_instr instr;
-		sndrv_seq_instr_cluster_t cluster;
+		struct snd_seq_instr instr;
+		snd_seq_instr_cluster_t cluster;
 	} id;				/* instrument identifier */
 	unsigned int cmd;		/* get/put/free command */
 	unsigned int flags;		/* query flags (only for get) */
 	unsigned int len;		/* real instrument data length (without header) */
 	int result;			/* operation result */
 	char reserved[16];		/* for the future */
-	struct sndrv_seq_instr_data data; /* instrument data (for put/get result) */
+	struct snd_seq_instr_data data; /* instrument data (for put/get result) */
 };
 
 /* INSTR_CLUSTER_SET */
 
-struct sndrv_seq_instr_cluster_set {
-	sndrv_seq_instr_cluster_t cluster; /* cluster identifier */
+struct snd_seq_instr_cluster_set {
+	snd_seq_instr_cluster_t cluster; /* cluster identifier */
 	char name[32];			/* cluster name */
 	int priority;			/* cluster priority */
 	char reserved[64];		/* for the future use */
@@ -852,8 +856,8 @@
 
 /* INSTR_CLUSTER_GET */
 
-struct sndrv_seq_instr_cluster_get {
-	sndrv_seq_instr_cluster_t cluster; /* cluster identifier */
+struct snd_seq_instr_cluster_get {
+	snd_seq_instr_cluster_t cluster; /* cluster identifier */
 	char name[32];			/* cluster name */
 	int priority;			/* cluster priority */
 	char reserved[64];		/* for the future use */
@@ -865,44 +869,44 @@
 
 #define SNDRV_SEQ_IOCTL_PVERSION	_IOR ('S', 0x00, int)
 #define SNDRV_SEQ_IOCTL_CLIENT_ID	_IOR ('S', 0x01, int)
-#define SNDRV_SEQ_IOCTL_SYSTEM_INFO	_IOWR('S', 0x02, struct sndrv_seq_system_info)
-#define SNDRV_SEQ_IOCTL_RUNNING_MODE	_IOWR('S', 0x03, struct sndrv_seq_running_info)
+#define SNDRV_SEQ_IOCTL_SYSTEM_INFO	_IOWR('S', 0x02, struct snd_seq_system_info)
+#define SNDRV_SEQ_IOCTL_RUNNING_MODE	_IOWR('S', 0x03, struct snd_seq_running_info)
 
-#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO	_IOWR('S', 0x10, struct sndrv_seq_client_info)
-#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO	_IOW ('S', 0x11, struct sndrv_seq_client_info)
+#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO	_IOWR('S', 0x10, struct snd_seq_client_info)
+#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO	_IOW ('S', 0x11, struct snd_seq_client_info)
 
-#define SNDRV_SEQ_IOCTL_CREATE_PORT	_IOWR('S', 0x20, struct sndrv_seq_port_info)
-#define SNDRV_SEQ_IOCTL_DELETE_PORT	_IOW ('S', 0x21, struct sndrv_seq_port_info)
-#define SNDRV_SEQ_IOCTL_GET_PORT_INFO	_IOWR('S', 0x22, struct sndrv_seq_port_info)
-#define SNDRV_SEQ_IOCTL_SET_PORT_INFO	_IOW ('S', 0x23, struct sndrv_seq_port_info)
+#define SNDRV_SEQ_IOCTL_CREATE_PORT	_IOWR('S', 0x20, struct snd_seq_port_info)
+#define SNDRV_SEQ_IOCTL_DELETE_PORT	_IOW ('S', 0x21, struct snd_seq_port_info)
+#define SNDRV_SEQ_IOCTL_GET_PORT_INFO	_IOWR('S', 0x22, struct snd_seq_port_info)
+#define SNDRV_SEQ_IOCTL_SET_PORT_INFO	_IOW ('S', 0x23, struct snd_seq_port_info)
 
-#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT	_IOW ('S', 0x30, struct sndrv_seq_port_subscribe)
-#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct sndrv_seq_port_subscribe)
+#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT	_IOW ('S', 0x30, struct snd_seq_port_subscribe)
+#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct snd_seq_port_subscribe)
 
-#define SNDRV_SEQ_IOCTL_CREATE_QUEUE	_IOWR('S', 0x32, struct sndrv_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_DELETE_QUEUE	_IOW ('S', 0x33, struct sndrv_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO	_IOWR('S', 0x34, struct sndrv_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO	_IOWR('S', 0x35, struct sndrv_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE	_IOWR('S', 0x36, struct sndrv_seq_queue_info)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct sndrv_seq_queue_status)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO	_IOWR('S', 0x41, struct sndrv_seq_queue_tempo)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO	_IOW ('S', 0x42, struct sndrv_seq_queue_tempo)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER	_IOWR('S', 0x43, struct sndrv_seq_queue_owner)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER	_IOW ('S', 0x44, struct sndrv_seq_queue_owner)
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER	_IOWR('S', 0x45, struct sndrv_seq_queue_timer)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER	_IOW ('S', 0x46, struct sndrv_seq_queue_timer)
+#define SNDRV_SEQ_IOCTL_CREATE_QUEUE	_IOWR('S', 0x32, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_DELETE_QUEUE	_IOW ('S', 0x33, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO	_IOWR('S', 0x34, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO	_IOWR('S', 0x35, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE	_IOWR('S', 0x36, struct snd_seq_queue_info)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct snd_seq_queue_status)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO	_IOWR('S', 0x41, struct snd_seq_queue_tempo)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO	_IOW ('S', 0x42, struct snd_seq_queue_tempo)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER	_IOWR('S', 0x43, struct snd_seq_queue_owner)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER	_IOW ('S', 0x44, struct snd_seq_queue_owner)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER	_IOWR('S', 0x45, struct snd_seq_queue_timer)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER	_IOW ('S', 0x46, struct snd_seq_queue_timer)
 /* XXX
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC	_IOWR('S', 0x53, struct sndrv_seq_queue_sync)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC	_IOW ('S', 0x54, struct sndrv_seq_queue_sync)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC	_IOWR('S', 0x53, struct snd_seq_queue_sync)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC	_IOW ('S', 0x54, struct snd_seq_queue_sync)
 */
-#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT	_IOWR('S', 0x49, struct sndrv_seq_queue_client)
-#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT	_IOW ('S', 0x4a, struct sndrv_seq_queue_client)
-#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL	_IOWR('S', 0x4b, struct sndrv_seq_client_pool)
-#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL	_IOW ('S', 0x4c, struct sndrv_seq_client_pool)
-#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS	_IOW ('S', 0x4e, struct sndrv_seq_remove_events)
-#define SNDRV_SEQ_IOCTL_QUERY_SUBS	_IOWR('S', 0x4f, struct sndrv_seq_query_subs)
-#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION	_IOWR('S', 0x50, struct sndrv_seq_port_subscribe)
-#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT	_IOWR('S', 0x51, struct sndrv_seq_client_info)
-#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT	_IOWR('S', 0x52, struct sndrv_seq_port_info)
+#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT	_IOWR('S', 0x49, struct snd_seq_queue_client)
+#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT	_IOW ('S', 0x4a, struct snd_seq_queue_client)
+#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL	_IOWR('S', 0x4b, struct snd_seq_client_pool)
+#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL	_IOW ('S', 0x4c, struct snd_seq_client_pool)
+#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS	_IOW ('S', 0x4e, struct snd_seq_remove_events)
+#define SNDRV_SEQ_IOCTL_QUERY_SUBS	_IOWR('S', 0x4f, struct snd_seq_query_subs)
+#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION	_IOWR('S', 0x50, struct snd_seq_port_subscribe)
+#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT	_IOWR('S', 0x51, struct snd_seq_client_info)
+#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT	_IOWR('S', 0x52, struct snd_seq_port_info)
 
 #endif /* __SOUND_ASEQUENCER_H */
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 8e552d6..9cc021c 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -23,12 +23,8 @@
 #ifndef __SOUND_ASOUND_H
 #define __SOUND_ASOUND_H
 
-#if defined(LINUX) || defined(__LINUX__) || defined(__linux__)
-
-#include <linux/ioctl.h>
-
 #ifdef __KERNEL__
-
+#include <linux/ioctl.h>
 #include <linux/types.h>
 #include <linux/time.h>
 #include <asm/byteorder.h>
@@ -43,25 +39,7 @@
 #endif
 #endif
 
-#else /* !__KERNEL__ */
-
-#include <endian.h>
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define SNDRV_LITTLE_ENDIAN
-#elif __BYTE_ORDER == __BIG_ENDIAN
-#define SNDRV_BIG_ENDIAN
-#else
-#error "Unsupported endian..."
-#endif
-
-#endif /* __KERNEL **/
-
-#endif /* LINUX */
-
-#ifndef __KERNEL__
-#include <sys/time.h>
-#include <sys/types.h>
-#endif
+#endif /* __KERNEL__ **/
 
 /*
  *  protocol version
@@ -82,7 +60,7 @@
  *                                                                          *
  ****************************************************************************/
 
-struct sndrv_aes_iec958 {
+struct snd_aes_iec958 {
 	unsigned char status[24];	/* AES/IEC958 channel status bits */
 	unsigned char subcode[147];	/* AES/IEC958 subcode bits */
 	unsigned char pad;		/* nothing */
@@ -97,7 +75,7 @@
 
 #define SNDRV_HWDEP_VERSION		SNDRV_PROTOCOL_VERSION(1, 0, 1)
 
-enum sndrv_hwdep_iface {
+enum {
 	SNDRV_HWDEP_IFACE_OPL2 = 0,
 	SNDRV_HWDEP_IFACE_OPL3,
 	SNDRV_HWDEP_IFACE_OPL4,
@@ -119,17 +97,17 @@
 	SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_SB_RC
 };
 
-struct sndrv_hwdep_info {
+struct snd_hwdep_info {
 	unsigned int device;		/* WR: device number */
 	int card;			/* R: card number */
 	unsigned char id[64];		/* ID (user selectable) */
 	unsigned char name[80];		/* hwdep name */
-	enum sndrv_hwdep_iface iface;	/* hwdep interface */
+	int iface;			/* hwdep interface */
 	unsigned char reserved[64];	/* reserved for future */
 };
 
 /* generic DSP loader */
-struct sndrv_hwdep_dsp_status {
+struct snd_hwdep_dsp_status {
 	unsigned int version;		/* R: driver-specific version */
 	unsigned char id[32];		/* R: driver-specific ID string */
 	unsigned int num_dsps;		/* R: number of DSP images to transfer */
@@ -138,7 +116,7 @@
 	unsigned char reserved[16];	/* reserved for future use */
 };
 
-struct sndrv_hwdep_dsp_image {
+struct snd_hwdep_dsp_image {
 	unsigned int index;		/* W: DSP index */
 	unsigned char name[64];		/* W: ID (e.g. file name) */
 	unsigned char __user *image;	/* W: binary image */
@@ -148,9 +126,9 @@
 
 enum {
 	SNDRV_HWDEP_IOCTL_PVERSION = _IOR ('H', 0x00, int),
-	SNDRV_HWDEP_IOCTL_INFO = _IOR ('H', 0x01, struct sndrv_hwdep_info),
-	SNDRV_HWDEP_IOCTL_DSP_STATUS = _IOR('H', 0x02, struct sndrv_hwdep_dsp_status),
-	SNDRV_HWDEP_IOCTL_DSP_LOAD   = _IOW('H', 0x03, struct sndrv_hwdep_dsp_image)
+	SNDRV_HWDEP_IOCTL_INFO = _IOR ('H', 0x01, struct snd_hwdep_info),
+	SNDRV_HWDEP_IOCTL_DSP_STATUS = _IOR('H', 0x02, struct snd_hwdep_dsp_status),
+	SNDRV_HWDEP_IOCTL_DSP_LOAD   = _IOW('H', 0x03, struct snd_hwdep_dsp_image)
 };
 
 /*****************************************************************************
@@ -161,10 +139,10 @@
 
 #define SNDRV_PCM_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 7)
 
-typedef unsigned long sndrv_pcm_uframes_t;
-typedef long sndrv_pcm_sframes_t;
+typedef unsigned long snd_pcm_uframes_t;
+typedef signed long snd_pcm_sframes_t;
 
-enum sndrv_pcm_class {
+enum {
 	SNDRV_PCM_CLASS_GENERIC = 0,	/* standard mono or stereo device */
 	SNDRV_PCM_CLASS_MULTI,		/* multichannel device */
 	SNDRV_PCM_CLASS_MODEM,		/* software modem class */
@@ -173,97 +151,94 @@
 	SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER,
 };
 
-enum sndrv_pcm_subclass {
+enum {
 	SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0, /* mono or stereo subdevices are mixed together */
 	SNDRV_PCM_SUBCLASS_MULTI_MIX,	/* multichannel subdevices are mixed together */
 	/* Don't forget to change the following: */
 	SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX,
 };
 
-enum sndrv_pcm_stream {
+enum {
 	SNDRV_PCM_STREAM_PLAYBACK = 0,
 	SNDRV_PCM_STREAM_CAPTURE,
 	SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE,
 };
 
-enum sndrv_pcm_access {
-	SNDRV_PCM_ACCESS_MMAP_INTERLEAVED = 0,	/* interleaved mmap */
-	SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED, 	/* noninterleaved mmap */
-	SNDRV_PCM_ACCESS_MMAP_COMPLEX,		/* complex mmap */
-	SNDRV_PCM_ACCESS_RW_INTERLEAVED,	/* readi/writei */
-	SNDRV_PCM_ACCESS_RW_NONINTERLEAVED,	/* readn/writen */
-	SNDRV_PCM_ACCESS_LAST = SNDRV_PCM_ACCESS_RW_NONINTERLEAVED,
-};
+typedef int __bitwise snd_pcm_access_t;
+#define	SNDRV_PCM_ACCESS_MMAP_INTERLEAVED	((__force snd_pcm_access_t) 0) /* interleaved mmap */
+#define	SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED	((__force snd_pcm_access_t) 1) /* noninterleaved mmap */
+#define	SNDRV_PCM_ACCESS_MMAP_COMPLEX		((__force snd_pcm_access_t) 2) /* complex mmap */
+#define	SNDRV_PCM_ACCESS_RW_INTERLEAVED		((__force snd_pcm_access_t) 3) /* readi/writei */
+#define	SNDRV_PCM_ACCESS_RW_NONINTERLEAVED	((__force snd_pcm_access_t) 4) /* readn/writen */
+#define	SNDRV_PCM_ACCESS_LAST		SNDRV_PCM_ACCESS_RW_NONINTERLEAVED
 
-enum sndrv_pcm_format {
-	SNDRV_PCM_FORMAT_S8 = 0,
-	SNDRV_PCM_FORMAT_U8,
-	SNDRV_PCM_FORMAT_S16_LE,
-	SNDRV_PCM_FORMAT_S16_BE,
-	SNDRV_PCM_FORMAT_U16_LE,
-	SNDRV_PCM_FORMAT_U16_BE,
-	SNDRV_PCM_FORMAT_S24_LE,	/* low three bytes */
-	SNDRV_PCM_FORMAT_S24_BE,	/* low three bytes */
-	SNDRV_PCM_FORMAT_U24_LE,	/* low three bytes */
-	SNDRV_PCM_FORMAT_U24_BE,	/* low three bytes */
-	SNDRV_PCM_FORMAT_S32_LE,
-	SNDRV_PCM_FORMAT_S32_BE,
-	SNDRV_PCM_FORMAT_U32_LE,
-	SNDRV_PCM_FORMAT_U32_BE,
-	SNDRV_PCM_FORMAT_FLOAT_LE,	/* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
-	SNDRV_PCM_FORMAT_FLOAT_BE,	/* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
-	SNDRV_PCM_FORMAT_FLOAT64_LE,	/* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
-	SNDRV_PCM_FORMAT_FLOAT64_BE,	/* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
-	SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE,	/* IEC-958 subframe, Little Endian */
-	SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE,	/* IEC-958 subframe, Big Endian */
-	SNDRV_PCM_FORMAT_MU_LAW,
-	SNDRV_PCM_FORMAT_A_LAW,
-	SNDRV_PCM_FORMAT_IMA_ADPCM,
-	SNDRV_PCM_FORMAT_MPEG,
-	SNDRV_PCM_FORMAT_GSM,
-	SNDRV_PCM_FORMAT_SPECIAL = 31,
-	SNDRV_PCM_FORMAT_S24_3LE = 32,	/* in three bytes */
-	SNDRV_PCM_FORMAT_S24_3BE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_U24_3LE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_U24_3BE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_S20_3LE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_S20_3BE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_U20_3LE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_U20_3BE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_S18_3LE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_S18_3BE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_U18_3LE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_U18_3BE,	/* in three bytes */
-	SNDRV_PCM_FORMAT_LAST = SNDRV_PCM_FORMAT_U18_3BE,
+typedef int __bitwise snd_pcm_format_t;
+#define	SNDRV_PCM_FORMAT_S8	((__force snd_pcm_format_t) 0)
+#define	SNDRV_PCM_FORMAT_U8	((__force snd_pcm_format_t) 1)
+#define	SNDRV_PCM_FORMAT_S16_LE	((__force snd_pcm_format_t) 2)
+#define	SNDRV_PCM_FORMAT_S16_BE	((__force snd_pcm_format_t) 3)
+#define	SNDRV_PCM_FORMAT_U16_LE	((__force snd_pcm_format_t) 4)
+#define	SNDRV_PCM_FORMAT_U16_BE	((__force snd_pcm_format_t) 5)
+#define	SNDRV_PCM_FORMAT_S24_LE	((__force snd_pcm_format_t) 6) /* low three bytes */
+#define	SNDRV_PCM_FORMAT_S24_BE	((__force snd_pcm_format_t) 7) /* low three bytes */
+#define	SNDRV_PCM_FORMAT_U24_LE	((__force snd_pcm_format_t) 8) /* low three bytes */
+#define	SNDRV_PCM_FORMAT_U24_BE	((__force snd_pcm_format_t) 9) /* low three bytes */
+#define	SNDRV_PCM_FORMAT_S32_LE	((__force snd_pcm_format_t) 10)
+#define	SNDRV_PCM_FORMAT_S32_BE	((__force snd_pcm_format_t) 11)
+#define	SNDRV_PCM_FORMAT_U32_LE	((__force snd_pcm_format_t) 12)
+#define	SNDRV_PCM_FORMAT_U32_BE	((__force snd_pcm_format_t) 13)
+#define	SNDRV_PCM_FORMAT_FLOAT_LE	((__force snd_pcm_format_t) 14) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
+#define	SNDRV_PCM_FORMAT_FLOAT_BE	((__force snd_pcm_format_t) 15) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */
+#define	SNDRV_PCM_FORMAT_FLOAT64_LE	((__force snd_pcm_format_t) 16) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
+#define	SNDRV_PCM_FORMAT_FLOAT64_BE	((__force snd_pcm_format_t) 17) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */
+#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18) /* IEC-958 subframe, Little Endian */
+#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19) /* IEC-958 subframe, Big Endian */
+#define	SNDRV_PCM_FORMAT_MU_LAW		((__force snd_pcm_format_t) 20)
+#define	SNDRV_PCM_FORMAT_A_LAW		((__force snd_pcm_format_t) 21)
+#define	SNDRV_PCM_FORMAT_IMA_ADPCM	((__force snd_pcm_format_t) 22)
+#define	SNDRV_PCM_FORMAT_MPEG		((__force snd_pcm_format_t) 23)
+#define	SNDRV_PCM_FORMAT_GSM		((__force snd_pcm_format_t) 24)
+#define	SNDRV_PCM_FORMAT_SPECIAL	((__force snd_pcm_format_t) 31)
+#define	SNDRV_PCM_FORMAT_S24_3LE	((__force snd_pcm_format_t) 32)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S24_3BE	((__force snd_pcm_format_t) 33)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U24_3LE	((__force snd_pcm_format_t) 34)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U24_3BE	((__force snd_pcm_format_t) 35)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S20_3LE	((__force snd_pcm_format_t) 36)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S20_3BE	((__force snd_pcm_format_t) 37)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U20_3LE	((__force snd_pcm_format_t) 38)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U20_3BE	((__force snd_pcm_format_t) 39)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S18_3LE	((__force snd_pcm_format_t) 40)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_S18_3BE	((__force snd_pcm_format_t) 41)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U18_3LE	((__force snd_pcm_format_t) 42)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_U18_3BE	((__force snd_pcm_format_t) 43)	/* in three bytes */
+#define	SNDRV_PCM_FORMAT_LAST		SNDRV_PCM_FORMAT_U18_3BE
 
 #ifdef SNDRV_LITTLE_ENDIAN
-	SNDRV_PCM_FORMAT_S16 = SNDRV_PCM_FORMAT_S16_LE,
-	SNDRV_PCM_FORMAT_U16 = SNDRV_PCM_FORMAT_U16_LE,
-	SNDRV_PCM_FORMAT_S24 = SNDRV_PCM_FORMAT_S24_LE,
-	SNDRV_PCM_FORMAT_U24 = SNDRV_PCM_FORMAT_U24_LE,
-	SNDRV_PCM_FORMAT_S32 = SNDRV_PCM_FORMAT_S32_LE,
-	SNDRV_PCM_FORMAT_U32 = SNDRV_PCM_FORMAT_U32_LE,
-	SNDRV_PCM_FORMAT_FLOAT = SNDRV_PCM_FORMAT_FLOAT_LE,
-	SNDRV_PCM_FORMAT_FLOAT64 = SNDRV_PCM_FORMAT_FLOAT64_LE,
-	SNDRV_PCM_FORMAT_IEC958_SUBFRAME = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE,
+#define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_LE
+#define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_LE
+#define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_LE
+#define	SNDRV_PCM_FORMAT_U24		SNDRV_PCM_FORMAT_U24_LE
+#define	SNDRV_PCM_FORMAT_S32		SNDRV_PCM_FORMAT_S32_LE
+#define	SNDRV_PCM_FORMAT_U32		SNDRV_PCM_FORMAT_U32_LE
+#define	SNDRV_PCM_FORMAT_FLOAT		SNDRV_PCM_FORMAT_FLOAT_LE
+#define	SNDRV_PCM_FORMAT_FLOAT64	SNDRV_PCM_FORMAT_FLOAT64_LE
+#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
 #endif
 #ifdef SNDRV_BIG_ENDIAN
-	SNDRV_PCM_FORMAT_S16 = SNDRV_PCM_FORMAT_S16_BE,
-	SNDRV_PCM_FORMAT_U16 = SNDRV_PCM_FORMAT_U16_BE,
-	SNDRV_PCM_FORMAT_S24 = SNDRV_PCM_FORMAT_S24_BE,
-	SNDRV_PCM_FORMAT_U24 = SNDRV_PCM_FORMAT_U24_BE,
-	SNDRV_PCM_FORMAT_S32 = SNDRV_PCM_FORMAT_S32_BE,
-	SNDRV_PCM_FORMAT_U32 = SNDRV_PCM_FORMAT_U32_BE,
-	SNDRV_PCM_FORMAT_FLOAT = SNDRV_PCM_FORMAT_FLOAT_BE,
-	SNDRV_PCM_FORMAT_FLOAT64 = SNDRV_PCM_FORMAT_FLOAT64_BE,
-	SNDRV_PCM_FORMAT_IEC958_SUBFRAME = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE,
+#define	SNDRV_PCM_FORMAT_S16		SNDRV_PCM_FORMAT_S16_BE
+#define	SNDRV_PCM_FORMAT_U16		SNDRV_PCM_FORMAT_U16_BE
+#define	SNDRV_PCM_FORMAT_S24		SNDRV_PCM_FORMAT_S24_BE
+#define	SNDRV_PCM_FORMAT_U24		SNDRV_PCM_FORMAT_U24_BE
+#define	SNDRV_PCM_FORMAT_S32		SNDRV_PCM_FORMAT_S32_BE
+#define	SNDRV_PCM_FORMAT_U32		SNDRV_PCM_FORMAT_U32_BE
+#define	SNDRV_PCM_FORMAT_FLOAT		SNDRV_PCM_FORMAT_FLOAT_BE
+#define	SNDRV_PCM_FORMAT_FLOAT64	SNDRV_PCM_FORMAT_FLOAT64_BE
+#define	SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
 #endif
-};
 
-enum sndrv_pcm_subformat {
-	SNDRV_PCM_SUBFORMAT_STD = 0,
-	SNDRV_PCM_SUBFORMAT_LAST = SNDRV_PCM_SUBFORMAT_STD,
-};
+typedef int __bitwise snd_pcm_subformat_t;
+#define	SNDRV_PCM_SUBFORMAT_STD		((__force snd_pcm_subformat_t) 0)
+#define	SNDRV_PCM_SUBFORMAT_LAST	SNDRV_PCM_SUBFORMAT_STD
 
 #define SNDRV_PCM_INFO_MMAP		0x00000001	/* hardware supports mmap */
 #define SNDRV_PCM_INFO_MMAP_VALID	0x00000002	/* period data are valid during transfer */
@@ -280,18 +255,17 @@
 #define SNDRV_PCM_INFO_JOINT_DUPLEX	0x00200000	/* playback and capture stream are somewhat correlated */
 #define SNDRV_PCM_INFO_SYNC_START	0x00400000	/* pcm support some kind of sync go */
 
-enum sndrv_pcm_state {
-	SNDRV_PCM_STATE_OPEN = 0,	/* stream is open */
-	SNDRV_PCM_STATE_SETUP,		/* stream has a setup */
-	SNDRV_PCM_STATE_PREPARED,	/* stream is ready to start */
-	SNDRV_PCM_STATE_RUNNING,	/* stream is running */
-	SNDRV_PCM_STATE_XRUN,		/* stream reached an xrun */
-	SNDRV_PCM_STATE_DRAINING,	/* stream is draining */
-	SNDRV_PCM_STATE_PAUSED,		/* stream is paused */
-	SNDRV_PCM_STATE_SUSPENDED,	/* hardware is suspended */
-	SNDRV_PCM_STATE_DISCONNECTED,	/* hardware is disconnected */
-	SNDRV_PCM_STATE_LAST = SNDRV_PCM_STATE_DISCONNECTED,
-};
+typedef int __bitwise snd_pcm_state_t;
+#define	SNDRV_PCM_STATE_OPEN		((__force snd_pcm_state_t) 0) /* stream is open */
+#define	SNDRV_PCM_STATE_SETUP		((__force snd_pcm_state_t) 1) /* stream has a setup */
+#define	SNDRV_PCM_STATE_PREPARED	((__force snd_pcm_state_t) 2) /* stream is ready to start */
+#define	SNDRV_PCM_STATE_RUNNING		((__force snd_pcm_state_t) 3) /* stream is running */
+#define	SNDRV_PCM_STATE_XRUN		((__force snd_pcm_state_t) 4) /* stream reached an xrun */
+#define	SNDRV_PCM_STATE_DRAINING	((__force snd_pcm_state_t) 5) /* stream is draining */
+#define	SNDRV_PCM_STATE_PAUSED		((__force snd_pcm_state_t) 6) /* stream is paused */
+#define	SNDRV_PCM_STATE_SUSPENDED	((__force snd_pcm_state_t) 7) /* hardware is suspended */
+#define	SNDRV_PCM_STATE_DISCONNECTED	((__force snd_pcm_state_t) 8) /* hardware is disconnected */
+#define	SNDRV_PCM_STATE_LAST		SNDRV_PCM_STATE_DISCONNECTED
 
 enum {
 	SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
@@ -299,55 +273,53 @@
 	SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000,
 };
 
-union sndrv_pcm_sync_id {
+union snd_pcm_sync_id {
 	unsigned char id[16];
 	unsigned short id16[8];
 	unsigned int id32[4];
 };
 
-struct sndrv_pcm_info {
+struct snd_pcm_info {
 	unsigned int device;		/* RO/WR (control): device number */
 	unsigned int subdevice;		/* RO/WR (control): subdevice number */
-	enum sndrv_pcm_stream stream;	/* RO/WR (control): stream number */
+	int stream;			/* RO/WR (control): stream direction */
 	int card;			/* R: card number */
 	unsigned char id[64];		/* ID (user selectable) */
 	unsigned char name[80];		/* name of this device */
 	unsigned char subname[32];	/* subdevice name */
-	enum sndrv_pcm_class dev_class;	/* SNDRV_PCM_CLASS_* */
-	enum sndrv_pcm_subclass dev_subclass; /* SNDRV_PCM_SUBCLASS_* */
+	int dev_class;			/* SNDRV_PCM_CLASS_* */
+	int dev_subclass;		/* SNDRV_PCM_SUBCLASS_* */
 	unsigned int subdevices_count;
 	unsigned int subdevices_avail;
-	union sndrv_pcm_sync_id sync;	/* hardware synchronization ID */
+	union snd_pcm_sync_id sync;	/* hardware synchronization ID */
 	unsigned char reserved[64];	/* reserved for future... */
 };
 
-enum sndrv_pcm_hw_param {
-	SNDRV_PCM_HW_PARAM_ACCESS = 0,	/* Access type */
-	SNDRV_PCM_HW_PARAM_FIRST_MASK = SNDRV_PCM_HW_PARAM_ACCESS,
-	SNDRV_PCM_HW_PARAM_FORMAT,	/* Format */
-	SNDRV_PCM_HW_PARAM_SUBFORMAT,	/* Subformat */
-	SNDRV_PCM_HW_PARAM_LAST_MASK = SNDRV_PCM_HW_PARAM_SUBFORMAT,
+typedef int __bitwise snd_pcm_hw_param_t;
+#define	SNDRV_PCM_HW_PARAM_ACCESS	((__force snd_pcm_hw_param_t) 0) /* Access type */
+#define	SNDRV_PCM_HW_PARAM_FORMAT	((__force snd_pcm_hw_param_t) 1) /* Format */
+#define	SNDRV_PCM_HW_PARAM_SUBFORMAT	((__force snd_pcm_hw_param_t) 2) /* Subformat */
+#define	SNDRV_PCM_HW_PARAM_FIRST_MASK	SNDRV_PCM_HW_PARAM_ACCESS
+#define	SNDRV_PCM_HW_PARAM_LAST_MASK	SNDRV_PCM_HW_PARAM_SUBFORMAT
 
-	SNDRV_PCM_HW_PARAM_SAMPLE_BITS = 8, /* Bits per sample */
-	SNDRV_PCM_HW_PARAM_FIRST_INTERVAL = SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
-	SNDRV_PCM_HW_PARAM_FRAME_BITS,	/* Bits per frame */
-	SNDRV_PCM_HW_PARAM_CHANNELS,	/* Channels */
-	SNDRV_PCM_HW_PARAM_RATE,	/* Approx rate */
-	SNDRV_PCM_HW_PARAM_PERIOD_TIME,	/* Approx distance between interrupts
-					   in us */
-	SNDRV_PCM_HW_PARAM_PERIOD_SIZE,	/* Approx frames between interrupts */
-	SNDRV_PCM_HW_PARAM_PERIOD_BYTES, /* Approx bytes between interrupts */
-	SNDRV_PCM_HW_PARAM_PERIODS,	/* Approx interrupts per buffer */
-	SNDRV_PCM_HW_PARAM_BUFFER_TIME,	/* Approx duration of buffer in us */
-	SNDRV_PCM_HW_PARAM_BUFFER_SIZE,	/* Size of buffer in frames */
-	SNDRV_PCM_HW_PARAM_BUFFER_BYTES, /* Size of buffer in bytes */
-	SNDRV_PCM_HW_PARAM_TICK_TIME,	/* Approx tick duration in us */
-	SNDRV_PCM_HW_PARAM_LAST_INTERVAL = SNDRV_PCM_HW_PARAM_TICK_TIME
-};
+#define	SNDRV_PCM_HW_PARAM_SAMPLE_BITS	((__force snd_pcm_hw_param_t) 8) /* Bits per sample */
+#define	SNDRV_PCM_HW_PARAM_FRAME_BITS	((__force snd_pcm_hw_param_t) 9) /* Bits per frame */
+#define	SNDRV_PCM_HW_PARAM_CHANNELS	((__force snd_pcm_hw_param_t) 10) /* Channels */
+#define	SNDRV_PCM_HW_PARAM_RATE		((__force snd_pcm_hw_param_t) 11) /* Approx rate */
+#define	SNDRV_PCM_HW_PARAM_PERIOD_TIME	((__force snd_pcm_hw_param_t) 12) /* Approx distance between interrupts in us */
+#define	SNDRV_PCM_HW_PARAM_PERIOD_SIZE	((__force snd_pcm_hw_param_t) 13) /* Approx frames between interrupts */
+#define	SNDRV_PCM_HW_PARAM_PERIOD_BYTES	((__force snd_pcm_hw_param_t) 14) /* Approx bytes between interrupts */
+#define	SNDRV_PCM_HW_PARAM_PERIODS	((__force snd_pcm_hw_param_t) 15) /* Approx interrupts per buffer */
+#define	SNDRV_PCM_HW_PARAM_BUFFER_TIME	((__force snd_pcm_hw_param_t) 16) /* Approx duration of buffer in us */
+#define	SNDRV_PCM_HW_PARAM_BUFFER_SIZE	((__force snd_pcm_hw_param_t) 17) /* Size of buffer in frames */
+#define	SNDRV_PCM_HW_PARAM_BUFFER_BYTES	((__force snd_pcm_hw_param_t) 18) /* Size of buffer in bytes */
+#define	SNDRV_PCM_HW_PARAM_TICK_TIME	((__force snd_pcm_hw_param_t) 19) /* Approx tick duration in us */
+#define	SNDRV_PCM_HW_PARAM_FIRST_INTERVAL	SNDRV_PCM_HW_PARAM_SAMPLE_BITS
+#define	SNDRV_PCM_HW_PARAM_LAST_INTERVAL	SNDRV_PCM_HW_PARAM_TICK_TIME
 
 #define SNDRV_PCM_HW_PARAMS_NORESAMPLE		(1<<0)	/* avoid rate resampling */
 
-struct sndrv_interval {
+struct snd_interval {
 	unsigned int min, max;
 	unsigned int openmin:1,
 		     openmax:1,
@@ -357,137 +329,137 @@
 
 #define SNDRV_MASK_MAX	256
 
-struct sndrv_mask {
+struct snd_mask {
 	u_int32_t bits[(SNDRV_MASK_MAX+31)/32];
 };
 
-struct sndrv_pcm_hw_params {
+struct snd_pcm_hw_params {
 	unsigned int flags;
-	struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - 
+	struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - 
 			       SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
-	struct sndrv_mask mres[5];	/* reserved masks */
-	struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
+	struct snd_mask mres[5];	/* reserved masks */
+	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
 				        SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
-	struct sndrv_interval ires[9];	/* reserved intervals */
+	struct snd_interval ires[9];	/* reserved intervals */
 	unsigned int rmask;		/* W: requested masks */
 	unsigned int cmask;		/* R: changed masks */
 	unsigned int info;		/* R: Info flags for returned setup */
 	unsigned int msbits;		/* R: used most significant bits */
 	unsigned int rate_num;		/* R: rate numerator */
 	unsigned int rate_den;		/* R: rate denominator */
-	sndrv_pcm_uframes_t fifo_size;	/* R: chip FIFO size in frames */
+	snd_pcm_uframes_t fifo_size;	/* R: chip FIFO size in frames */
 	unsigned char reserved[64];	/* reserved for future */
 };
 
-enum sndrv_pcm_tstamp {
+enum {
 	SNDRV_PCM_TSTAMP_NONE = 0,
 	SNDRV_PCM_TSTAMP_MMAP,
 	SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_MMAP,
 };
 
-struct sndrv_pcm_sw_params {
-	enum sndrv_pcm_tstamp tstamp_mode;	/* timestamp mode */
+struct snd_pcm_sw_params {
+	int tstamp_mode;			/* timestamp mode */
 	unsigned int period_step;
 	unsigned int sleep_min;			/* min ticks to sleep */
-	sndrv_pcm_uframes_t avail_min;		/* min avail frames for wakeup */
-	sndrv_pcm_uframes_t xfer_align;		/* xfer size need to be a multiple */
-	sndrv_pcm_uframes_t start_threshold;	/* min hw_avail frames for automatic start */
-	sndrv_pcm_uframes_t stop_threshold;	/* min avail frames for automatic stop */
-	sndrv_pcm_uframes_t silence_threshold;	/* min distance from noise for silence filling */
-	sndrv_pcm_uframes_t silence_size;	/* silence block size */
-	sndrv_pcm_uframes_t boundary;		/* pointers wrap point */
+	snd_pcm_uframes_t avail_min;		/* min avail frames for wakeup */
+	snd_pcm_uframes_t xfer_align;		/* xfer size need to be a multiple */
+	snd_pcm_uframes_t start_threshold;	/* min hw_avail frames for automatic start */
+	snd_pcm_uframes_t stop_threshold;	/* min avail frames for automatic stop */
+	snd_pcm_uframes_t silence_threshold;	/* min distance from noise for silence filling */
+	snd_pcm_uframes_t silence_size;		/* silence block size */
+	snd_pcm_uframes_t boundary;		/* pointers wrap point */
 	unsigned char reserved[64];		/* reserved for future */
 };
 
-struct sndrv_pcm_channel_info {
+struct snd_pcm_channel_info {
 	unsigned int channel;
 	off_t offset;			/* mmap offset */
 	unsigned int first;		/* offset to first sample in bits */
 	unsigned int step;		/* samples distance in bits */
 };
 
-struct sndrv_pcm_status {
-	enum sndrv_pcm_state state;	/* stream state */
+struct snd_pcm_status {
+	snd_pcm_state_t state;		/* stream state */
 	struct timespec trigger_tstamp;	/* time when stream was started/stopped/paused */
 	struct timespec tstamp;		/* reference timestamp */
-	sndrv_pcm_uframes_t appl_ptr;	/* appl ptr */
-	sndrv_pcm_uframes_t hw_ptr;	/* hw ptr */
-	sndrv_pcm_sframes_t delay;	/* current delay in frames */
-	sndrv_pcm_uframes_t avail;	/* number of frames available */
-	sndrv_pcm_uframes_t avail_max;	/* max frames available on hw since last status */
-	sndrv_pcm_uframes_t overrange;	/* count of ADC (capture) overrange detections from last status */
-	enum sndrv_pcm_state suspended_state; /* suspended stream state */
+	snd_pcm_uframes_t appl_ptr;	/* appl ptr */
+	snd_pcm_uframes_t hw_ptr;	/* hw ptr */
+	snd_pcm_sframes_t delay;	/* current delay in frames */
+	snd_pcm_uframes_t avail;	/* number of frames available */
+	snd_pcm_uframes_t avail_max;	/* max frames available on hw since last status */
+	snd_pcm_uframes_t overrange;	/* count of ADC (capture) overrange detections from last status */
+	snd_pcm_state_t suspended_state; /* suspended stream state */
 	unsigned char reserved[60];	/* must be filled with zero */
 };
 
-struct sndrv_pcm_mmap_status {
-	enum sndrv_pcm_state state;	/* RO: state - SNDRV_PCM_STATE_XXXX */
+struct snd_pcm_mmap_status {
+	snd_pcm_state_t state;		/* RO: state - SNDRV_PCM_STATE_XXXX */
 	int pad1;			/* Needed for 64 bit alignment */
-	sndrv_pcm_uframes_t hw_ptr;	/* RO: hw ptr (0...boundary-1) */
+	snd_pcm_uframes_t hw_ptr;	/* RO: hw ptr (0...boundary-1) */
 	struct timespec tstamp;		/* Timestamp */
-	enum sndrv_pcm_state suspended_state; /* RO: suspended stream state */
+	snd_pcm_state_t suspended_state; /* RO: suspended stream state */
 };
 
-struct sndrv_pcm_mmap_control {
-	sndrv_pcm_uframes_t appl_ptr;	/* RW: appl ptr (0...boundary-1) */
-	sndrv_pcm_uframes_t avail_min;	/* RW: min available frames for wakeup */
+struct snd_pcm_mmap_control {
+	snd_pcm_uframes_t appl_ptr;	/* RW: appl ptr (0...boundary-1) */
+	snd_pcm_uframes_t avail_min;	/* RW: min available frames for wakeup */
 };
 
 #define SNDRV_PCM_SYNC_PTR_HWSYNC	(1<<0)	/* execute hwsync */
 #define SNDRV_PCM_SYNC_PTR_APPL		(1<<1)	/* get appl_ptr from driver (r/w op) */
 #define SNDRV_PCM_SYNC_PTR_AVAIL_MIN	(1<<2)	/* get avail_min from driver */
 
-struct sndrv_pcm_sync_ptr {
+struct snd_pcm_sync_ptr {
 	unsigned int flags;
 	union {
-		struct sndrv_pcm_mmap_status status;
+		struct snd_pcm_mmap_status status;
 		unsigned char reserved[64];
 	} s;
 	union {
-		struct sndrv_pcm_mmap_control control;
+		struct snd_pcm_mmap_control control;
 		unsigned char reserved[64];
 	} c;
 };
 
-struct sndrv_xferi {
-	sndrv_pcm_sframes_t result;
+struct snd_xferi {
+	snd_pcm_sframes_t result;
 	void __user *buf;
-	sndrv_pcm_uframes_t frames;
+	snd_pcm_uframes_t frames;
 };
 
-struct sndrv_xfern {
-	sndrv_pcm_sframes_t result;
+struct snd_xfern {
+	snd_pcm_sframes_t result;
 	void __user * __user *bufs;
-	sndrv_pcm_uframes_t frames;
+	snd_pcm_uframes_t frames;
 };
 
 enum {
 	SNDRV_PCM_IOCTL_PVERSION = _IOR('A', 0x00, int),
-	SNDRV_PCM_IOCTL_INFO = _IOR('A', 0x01, struct sndrv_pcm_info),
+	SNDRV_PCM_IOCTL_INFO = _IOR('A', 0x01, struct snd_pcm_info),
 	SNDRV_PCM_IOCTL_TSTAMP = _IOW('A', 0x02, int),
-	SNDRV_PCM_IOCTL_HW_REFINE = _IOWR('A', 0x10, struct sndrv_pcm_hw_params),
-	SNDRV_PCM_IOCTL_HW_PARAMS = _IOWR('A', 0x11, struct sndrv_pcm_hw_params),
+	SNDRV_PCM_IOCTL_HW_REFINE = _IOWR('A', 0x10, struct snd_pcm_hw_params),
+	SNDRV_PCM_IOCTL_HW_PARAMS = _IOWR('A', 0x11, struct snd_pcm_hw_params),
 	SNDRV_PCM_IOCTL_HW_FREE = _IO('A', 0x12),
-	SNDRV_PCM_IOCTL_SW_PARAMS = _IOWR('A', 0x13, struct sndrv_pcm_sw_params),
-	SNDRV_PCM_IOCTL_STATUS = _IOR('A', 0x20, struct sndrv_pcm_status),
-	SNDRV_PCM_IOCTL_DELAY = _IOR('A', 0x21, sndrv_pcm_sframes_t),
+	SNDRV_PCM_IOCTL_SW_PARAMS = _IOWR('A', 0x13, struct snd_pcm_sw_params),
+	SNDRV_PCM_IOCTL_STATUS = _IOR('A', 0x20, struct snd_pcm_status),
+	SNDRV_PCM_IOCTL_DELAY = _IOR('A', 0x21, snd_pcm_sframes_t),
 	SNDRV_PCM_IOCTL_HWSYNC = _IO('A', 0x22),
-	SNDRV_PCM_IOCTL_SYNC_PTR = _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr),
-	SNDRV_PCM_IOCTL_CHANNEL_INFO = _IOR('A', 0x32, struct sndrv_pcm_channel_info),
+	SNDRV_PCM_IOCTL_SYNC_PTR = _IOWR('A', 0x23, struct snd_pcm_sync_ptr),
+	SNDRV_PCM_IOCTL_CHANNEL_INFO = _IOR('A', 0x32, struct snd_pcm_channel_info),
 	SNDRV_PCM_IOCTL_PREPARE = _IO('A', 0x40),
 	SNDRV_PCM_IOCTL_RESET = _IO('A', 0x41),
 	SNDRV_PCM_IOCTL_START = _IO('A', 0x42),
 	SNDRV_PCM_IOCTL_DROP = _IO('A', 0x43),
 	SNDRV_PCM_IOCTL_DRAIN = _IO('A', 0x44),
 	SNDRV_PCM_IOCTL_PAUSE = _IOW('A', 0x45, int),
-	SNDRV_PCM_IOCTL_REWIND = _IOW('A', 0x46, sndrv_pcm_uframes_t),
+	SNDRV_PCM_IOCTL_REWIND = _IOW('A', 0x46, snd_pcm_uframes_t),
 	SNDRV_PCM_IOCTL_RESUME = _IO('A', 0x47),
 	SNDRV_PCM_IOCTL_XRUN = _IO('A', 0x48),
-	SNDRV_PCM_IOCTL_FORWARD = _IOW('A', 0x49, sndrv_pcm_uframes_t),
-	SNDRV_PCM_IOCTL_WRITEI_FRAMES = _IOW('A', 0x50, struct sndrv_xferi),
-	SNDRV_PCM_IOCTL_READI_FRAMES = _IOR('A', 0x51, struct sndrv_xferi),
-	SNDRV_PCM_IOCTL_WRITEN_FRAMES = _IOW('A', 0x52, struct sndrv_xfern),
-	SNDRV_PCM_IOCTL_READN_FRAMES = _IOR('A', 0x53, struct sndrv_xfern),
+	SNDRV_PCM_IOCTL_FORWARD = _IOW('A', 0x49, snd_pcm_uframes_t),
+	SNDRV_PCM_IOCTL_WRITEI_FRAMES = _IOW('A', 0x50, struct snd_xferi),
+	SNDRV_PCM_IOCTL_READI_FRAMES = _IOR('A', 0x51, struct snd_xferi),
+	SNDRV_PCM_IOCTL_WRITEN_FRAMES = _IOW('A', 0x52, struct snd_xfern),
+	SNDRV_PCM_IOCTL_READN_FRAMES = _IOR('A', 0x53, struct snd_xfern),
 	SNDRV_PCM_IOCTL_LINK = _IOW('A', 0x60, int),
 	SNDRV_PCM_IOCTL_UNLINK = _IO('A', 0x61),
 };
@@ -507,7 +479,7 @@
 
 #define SNDRV_RAWMIDI_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 0)
 
-enum sndrv_rawmidi_stream {
+enum {
 	SNDRV_RAWMIDI_STREAM_OUTPUT = 0,
 	SNDRV_RAWMIDI_STREAM_INPUT,
 	SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT,
@@ -517,10 +489,10 @@
 #define SNDRV_RAWMIDI_INFO_INPUT		0x00000002
 #define SNDRV_RAWMIDI_INFO_DUPLEX		0x00000004
 
-struct sndrv_rawmidi_info {
+struct snd_rawmidi_info {
 	unsigned int device;		/* RO/WR (control): device number */
 	unsigned int subdevice;		/* RO/WR (control): subdevice number */
-	enum sndrv_rawmidi_stream stream; /* WR: stream */
+	int stream;			/* WR: stream */
 	int card;			/* R: card number */
 	unsigned int flags;		/* SNDRV_RAWMIDI_INFO_XXXX */
 	unsigned char id[64];		/* ID (user selectable) */
@@ -531,16 +503,16 @@
 	unsigned char reserved[64];	/* reserved for future use */
 };
 
-struct sndrv_rawmidi_params {
-	enum sndrv_rawmidi_stream stream;
+struct snd_rawmidi_params {
+	int stream;
 	size_t buffer_size;		/* queue size in bytes */
 	size_t avail_min;		/* minimum avail bytes for wakeup */
 	unsigned int no_active_sensing: 1; /* do not send active sensing byte in close() */
 	unsigned char reserved[16];	/* reserved for future use */
 };
 
-struct sndrv_rawmidi_status {
-	enum sndrv_rawmidi_stream stream;
+struct snd_rawmidi_status {
+	int stream;
 	struct timespec tstamp;		/* Timestamp */
 	size_t avail;			/* available bytes */
 	size_t xruns;			/* count of overruns since last status (in bytes) */
@@ -549,9 +521,9 @@
 
 enum {
 	SNDRV_RAWMIDI_IOCTL_PVERSION = _IOR('W', 0x00, int),
-	SNDRV_RAWMIDI_IOCTL_INFO = _IOR('W', 0x01, struct sndrv_rawmidi_info),
-	SNDRV_RAWMIDI_IOCTL_PARAMS = _IOWR('W', 0x10, struct sndrv_rawmidi_params),
-	SNDRV_RAWMIDI_IOCTL_STATUS = _IOWR('W', 0x20, struct sndrv_rawmidi_status),
+	SNDRV_RAWMIDI_IOCTL_INFO = _IOR('W', 0x01, struct snd_rawmidi_info),
+	SNDRV_RAWMIDI_IOCTL_PARAMS = _IOWR('W', 0x10, struct snd_rawmidi_params),
+	SNDRV_RAWMIDI_IOCTL_STATUS = _IOWR('W', 0x20, struct snd_rawmidi_status),
 	SNDRV_RAWMIDI_IOCTL_DROP = _IOW('W', 0x30, int),
 	SNDRV_RAWMIDI_IOCTL_DRAIN = _IOW('W', 0x31, int),
 };
@@ -562,7 +534,7 @@
 
 #define SNDRV_TIMER_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 5)
 
-enum sndrv_timer_class {
+enum {
 	SNDRV_TIMER_CLASS_NONE = -1,
 	SNDRV_TIMER_CLASS_SLAVE = 0,
 	SNDRV_TIMER_CLASS_GLOBAL,
@@ -572,7 +544,7 @@
 };
 
 /* slave timer classes */
-enum sndrv_timer_slave_class {
+enum {
 	SNDRV_TIMER_SCLASS_NONE = 0,
 	SNDRV_TIMER_SCLASS_APPLICATION,
 	SNDRV_TIMER_SCLASS_SEQUENCER,		/* alias */
@@ -588,16 +560,16 @@
 /* info flags */
 #define SNDRV_TIMER_FLG_SLAVE		(1<<0)	/* cannot be controlled */
 
-struct sndrv_timer_id {
-	enum sndrv_timer_class dev_class;	
-	enum sndrv_timer_slave_class dev_sclass;
+struct snd_timer_id {
+	int dev_class;	
+	int dev_sclass;
 	int card;
 	int device;
 	int subdevice;
 };
 
-struct sndrv_timer_ginfo {
-	struct sndrv_timer_id tid;	/* requested timer ID */
+struct snd_timer_ginfo {
+	struct snd_timer_id tid;	/* requested timer ID */
 	unsigned int flags;		/* timer flags - SNDRV_TIMER_FLG_* */
 	int card;			/* card number */
 	unsigned char id[64];		/* timer identification */
@@ -610,27 +582,27 @@
 	unsigned char reserved[32];
 };
 
-struct sndrv_timer_gparams {
-	struct sndrv_timer_id tid;	/* requested timer ID */
+struct snd_timer_gparams {
+	struct snd_timer_id tid;	/* requested timer ID */
 	unsigned long period_num;	/* requested precise period duration (in seconds) - numerator */
 	unsigned long period_den;	/* requested precise period duration (in seconds) - denominator */
 	unsigned char reserved[32];
 };
 
-struct sndrv_timer_gstatus {
-	struct sndrv_timer_id tid;	/* requested timer ID */
+struct snd_timer_gstatus {
+	struct snd_timer_id tid;	/* requested timer ID */
 	unsigned long resolution;	/* current period resolution in ns */
 	unsigned long resolution_num;	/* precise current period resolution (in seconds) - numerator */
 	unsigned long resolution_den;	/* precise current period resolution (in seconds) - denominator */
 	unsigned char reserved[32];
 };
 
-struct sndrv_timer_select {
-	struct sndrv_timer_id id;	/* bind to timer ID */
+struct snd_timer_select {
+	struct snd_timer_id id;	/* bind to timer ID */
 	unsigned char reserved[32];	/* reserved */
 };
 
-struct sndrv_timer_info {
+struct snd_timer_info {
 	unsigned int flags;		/* timer flags - SNDRV_TIMER_FLG_* */
 	int card;			/* card number */
 	unsigned char id[64];		/* timer identificator */
@@ -644,7 +616,7 @@
 #define SNDRV_TIMER_PSFLG_EXCLUSIVE	(1<<1)	/* exclusive use, precise start/stop/pause/continue */
 #define SNDRV_TIMER_PSFLG_EARLY_EVENT	(1<<2)	/* write early event to the poll queue */
 
-struct sndrv_timer_params {
+struct snd_timer_params {
 	unsigned int flags;		/* flags - SNDRV_MIXER_PSFLG_* */
 	unsigned int ticks;		/* requested resolution in ticks */
 	unsigned int queue_size;	/* total size of queue (32-1024) */
@@ -653,7 +625,7 @@
 	unsigned char reserved[60];	/* reserved */
 };
 
-struct sndrv_timer_status {
+struct snd_timer_status {
 	struct timespec tstamp;		/* Timestamp - last update */
 	unsigned int resolution;	/* current period resolution in ns */
 	unsigned int lost;		/* counter of master tick lost */
@@ -664,15 +636,15 @@
 
 enum {
 	SNDRV_TIMER_IOCTL_PVERSION = _IOR('T', 0x00, int),
-	SNDRV_TIMER_IOCTL_NEXT_DEVICE = _IOWR('T', 0x01, struct sndrv_timer_id),
+	SNDRV_TIMER_IOCTL_NEXT_DEVICE = _IOWR('T', 0x01, struct snd_timer_id),
 	SNDRV_TIMER_IOCTL_TREAD = _IOW('T', 0x02, int),
-	SNDRV_TIMER_IOCTL_GINFO = _IOWR('T', 0x03, struct sndrv_timer_ginfo),
-	SNDRV_TIMER_IOCTL_GPARAMS = _IOW('T', 0x04, struct sndrv_timer_gparams),
-	SNDRV_TIMER_IOCTL_GSTATUS = _IOWR('T', 0x05, struct sndrv_timer_gstatus),
-	SNDRV_TIMER_IOCTL_SELECT = _IOW('T', 0x10, struct sndrv_timer_select),
-	SNDRV_TIMER_IOCTL_INFO = _IOR('T', 0x11, struct sndrv_timer_info),
-	SNDRV_TIMER_IOCTL_PARAMS = _IOW('T', 0x12, struct sndrv_timer_params),
-	SNDRV_TIMER_IOCTL_STATUS = _IOR('T', 0x14, struct sndrv_timer_status),
+	SNDRV_TIMER_IOCTL_GINFO = _IOWR('T', 0x03, struct snd_timer_ginfo),
+	SNDRV_TIMER_IOCTL_GPARAMS = _IOW('T', 0x04, struct snd_timer_gparams),
+	SNDRV_TIMER_IOCTL_GSTATUS = _IOWR('T', 0x05, struct snd_timer_gstatus),
+	SNDRV_TIMER_IOCTL_SELECT = _IOW('T', 0x10, struct snd_timer_select),
+	SNDRV_TIMER_IOCTL_INFO = _IOR('T', 0x11, struct snd_timer_info),
+	SNDRV_TIMER_IOCTL_PARAMS = _IOW('T', 0x12, struct snd_timer_params),
+	SNDRV_TIMER_IOCTL_STATUS = _IOR('T', 0x14, struct snd_timer_status),
 	/* The following four ioctls are changed since 1.0.9 due to confliction */
 	SNDRV_TIMER_IOCTL_START = _IO('T', 0xa0),
 	SNDRV_TIMER_IOCTL_STOP = _IO('T', 0xa1),
@@ -680,12 +652,12 @@
 	SNDRV_TIMER_IOCTL_PAUSE = _IO('T', 0xa3),
 };
 
-struct sndrv_timer_read {
+struct snd_timer_read {
 	unsigned int resolution;
 	unsigned int ticks;
 };
 
-enum sndrv_timer_event {
+enum {
 	SNDRV_TIMER_EVENT_RESOLUTION = 0,	/* val = resolution in ns */
 	SNDRV_TIMER_EVENT_TICK,			/* val = ticks */
 	SNDRV_TIMER_EVENT_START,		/* val = resolution in ns */
@@ -704,8 +676,8 @@
 	SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10,
 };
 
-struct sndrv_timer_tread {
-	enum sndrv_timer_event event;
+struct snd_timer_tread {
+	int event;
 	struct timespec tstamp;
 	unsigned int val;
 };
@@ -718,7 +690,7 @@
 
 #define SNDRV_CTL_VERSION		SNDRV_PROTOCOL_VERSION(2, 0, 3)
 
-struct sndrv_ctl_card_info {
+struct snd_ctl_card_info {
 	int card;			/* card number */
 	int pad;			/* reserved for future (was type) */
 	unsigned char id[16];		/* ID of card (user selectable) */
@@ -731,27 +703,25 @@
 	unsigned char reserved[48];	/* reserved for future */
 };
 
-enum sndrv_ctl_elem_type {
-	SNDRV_CTL_ELEM_TYPE_NONE = 0,		/* invalid */
-	SNDRV_CTL_ELEM_TYPE_BOOLEAN,		/* boolean type */
-	SNDRV_CTL_ELEM_TYPE_INTEGER,		/* integer type */
-	SNDRV_CTL_ELEM_TYPE_ENUMERATED,		/* enumerated type */
-	SNDRV_CTL_ELEM_TYPE_BYTES,		/* byte array */
-	SNDRV_CTL_ELEM_TYPE_IEC958,		/* IEC958 (S/PDIF) setup */
-	SNDRV_CTL_ELEM_TYPE_INTEGER64,		/* 64-bit integer type */
-	SNDRV_CTL_ELEM_TYPE_LAST = SNDRV_CTL_ELEM_TYPE_INTEGER64,
-};
+typedef int __bitwise snd_ctl_elem_type_t;
+#define	SNDRV_CTL_ELEM_TYPE_NONE	((__force snd_ctl_elem_type_t) 0) /* invalid */
+#define	SNDRV_CTL_ELEM_TYPE_BOOLEAN	((__force snd_ctl_elem_type_t) 1) /* boolean type */
+#define	SNDRV_CTL_ELEM_TYPE_INTEGER	((__force snd_ctl_elem_type_t) 2) /* integer type */
+#define	SNDRV_CTL_ELEM_TYPE_ENUMERATED	((__force snd_ctl_elem_type_t) 3) /* enumerated type */
+#define	SNDRV_CTL_ELEM_TYPE_BYTES	((__force snd_ctl_elem_type_t) 4) /* byte array */
+#define	SNDRV_CTL_ELEM_TYPE_IEC958	((__force snd_ctl_elem_type_t) 5) /* IEC958 (S/PDIF) setup */
+#define	SNDRV_CTL_ELEM_TYPE_INTEGER64	((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */
+#define	SNDRV_CTL_ELEM_TYPE_LAST	SNDRV_CTL_ELEM_TYPE_INTEGER64
 
-enum sndrv_ctl_elem_iface {
-	SNDRV_CTL_ELEM_IFACE_CARD = 0,		/* global control */
-	SNDRV_CTL_ELEM_IFACE_HWDEP,		/* hardware dependent device */
-	SNDRV_CTL_ELEM_IFACE_MIXER,		/* virtual mixer device */
-	SNDRV_CTL_ELEM_IFACE_PCM,		/* PCM device */
-	SNDRV_CTL_ELEM_IFACE_RAWMIDI,		/* RawMidi device */
-	SNDRV_CTL_ELEM_IFACE_TIMER,		/* timer device */
-	SNDRV_CTL_ELEM_IFACE_SEQUENCER,		/* sequencer client */
-	SNDRV_CTL_ELEM_IFACE_LAST = SNDRV_CTL_ELEM_IFACE_SEQUENCER,
-};
+typedef int __bitwise snd_ctl_elem_iface_t;
+#define	SNDRV_CTL_ELEM_IFACE_CARD	((__force snd_ctl_elem_iface_t) 0) /* global control */
+#define	SNDRV_CTL_ELEM_IFACE_HWDEP	((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */
+#define	SNDRV_CTL_ELEM_IFACE_MIXER	((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */
+#define	SNDRV_CTL_ELEM_IFACE_PCM	((__force snd_ctl_elem_iface_t) 3) /* PCM device */
+#define	SNDRV_CTL_ELEM_IFACE_RAWMIDI	((__force snd_ctl_elem_iface_t) 4) /* RawMidi device */
+#define	SNDRV_CTL_ELEM_IFACE_TIMER	((__force snd_ctl_elem_iface_t) 5) /* timer device */
+#define	SNDRV_CTL_ELEM_IFACE_SEQUENCER	((__force snd_ctl_elem_iface_t) 6) /* sequencer client */
+#define	SNDRV_CTL_ELEM_IFACE_LAST	SNDRV_CTL_ELEM_IFACE_SEQUENCER
 
 #define SNDRV_CTL_ELEM_ACCESS_READ		(1<<0)
 #define SNDRV_CTL_ELEM_ACCESS_WRITE		(1<<1)
@@ -773,27 +743,27 @@
 #define SNDRV_CTL_POWER_D3hot		(SNDRV_CTL_POWER_D3|0x0000)	/* Off, with power */
 #define SNDRV_CTL_POWER_D3cold		(SNDRV_CTL_POWER_D3|0x0001)	/* Off, without power */
 
-struct sndrv_ctl_elem_id {
+struct snd_ctl_elem_id {
 	unsigned int numid;		/* numeric identifier, zero = invalid */
-	enum sndrv_ctl_elem_iface iface; /* interface identifier */
+	snd_ctl_elem_iface_t iface;	/* interface identifier */
 	unsigned int device;		/* device/client number */
 	unsigned int subdevice;		/* subdevice (substream) number */
         unsigned char name[44];		/* ASCII name of item */
 	unsigned int index;		/* index of item */
 };
 
-struct sndrv_ctl_elem_list {
+struct snd_ctl_elem_list {
 	unsigned int offset;		/* W: first element ID to get */
 	unsigned int space;		/* W: count of element IDs to get */
 	unsigned int used;		/* R: count of element IDs set */
 	unsigned int count;		/* R: count of all elements */
-	struct sndrv_ctl_elem_id __user *pids; /* R: IDs */
+	struct snd_ctl_elem_id __user *pids; /* R: IDs */
 	unsigned char reserved[50];
 };
 
-struct sndrv_ctl_elem_info {
-	struct sndrv_ctl_elem_id id;	/* W: element ID */
-	enum sndrv_ctl_elem_type type;	/* R: value type - SNDRV_CTL_ELEM_TYPE_* */
+struct snd_ctl_elem_info {
+	struct snd_ctl_elem_id id;	/* W: element ID */
+	snd_ctl_elem_type_t type;	/* R: value type - SNDRV_CTL_ELEM_TYPE_* */
 	unsigned int access;		/* R: value access (bitmask) - SNDRV_CTL_ELEM_ACCESS_* */
 	unsigned int count;		/* count of values */
 	pid_t owner;			/* owner's PID of this control */
@@ -822,8 +792,8 @@
 	unsigned char reserved[64-4*sizeof(unsigned short)];
 };
 
-struct sndrv_ctl_elem_value {
-	struct sndrv_ctl_elem_id id;	/* W: element ID */
+struct snd_ctl_elem_value {
+	struct snd_ctl_elem_id id;	/* W: element ID */
 	unsigned int indirect: 1;	/* W: use indirect pointer (xxx_ptr member) */
         union {
 		union {
@@ -842,7 +812,7 @@
 			unsigned char data[512];
 			unsigned char *data_ptr;
 		} bytes;
-		struct sndrv_aes_iec958 iec958;
+		struct snd_aes_iec958 iec958;
         } value;                /* RO */
 	struct timespec tstamp;
         unsigned char reserved[128-sizeof(struct timespec)];
@@ -850,24 +820,24 @@
 
 enum {
 	SNDRV_CTL_IOCTL_PVERSION = _IOR('U', 0x00, int),
-	SNDRV_CTL_IOCTL_CARD_INFO = _IOR('U', 0x01, struct sndrv_ctl_card_info),
-	SNDRV_CTL_IOCTL_ELEM_LIST = _IOWR('U', 0x10, struct sndrv_ctl_elem_list),
-	SNDRV_CTL_IOCTL_ELEM_INFO = _IOWR('U', 0x11, struct sndrv_ctl_elem_info),
-	SNDRV_CTL_IOCTL_ELEM_READ = _IOWR('U', 0x12, struct sndrv_ctl_elem_value),
-	SNDRV_CTL_IOCTL_ELEM_WRITE = _IOWR('U', 0x13, struct sndrv_ctl_elem_value),
-	SNDRV_CTL_IOCTL_ELEM_LOCK = _IOW('U', 0x14, struct sndrv_ctl_elem_id),
-	SNDRV_CTL_IOCTL_ELEM_UNLOCK = _IOW('U', 0x15, struct sndrv_ctl_elem_id),
+	SNDRV_CTL_IOCTL_CARD_INFO = _IOR('U', 0x01, struct snd_ctl_card_info),
+	SNDRV_CTL_IOCTL_ELEM_LIST = _IOWR('U', 0x10, struct snd_ctl_elem_list),
+	SNDRV_CTL_IOCTL_ELEM_INFO = _IOWR('U', 0x11, struct snd_ctl_elem_info),
+	SNDRV_CTL_IOCTL_ELEM_READ = _IOWR('U', 0x12, struct snd_ctl_elem_value),
+	SNDRV_CTL_IOCTL_ELEM_WRITE = _IOWR('U', 0x13, struct snd_ctl_elem_value),
+	SNDRV_CTL_IOCTL_ELEM_LOCK = _IOW('U', 0x14, struct snd_ctl_elem_id),
+	SNDRV_CTL_IOCTL_ELEM_UNLOCK = _IOW('U', 0x15, struct snd_ctl_elem_id),
 	SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS = _IOWR('U', 0x16, int),
-	SNDRV_CTL_IOCTL_ELEM_ADD = _IOWR('U', 0x17, struct sndrv_ctl_elem_info),
-	SNDRV_CTL_IOCTL_ELEM_REPLACE = _IOWR('U', 0x18, struct sndrv_ctl_elem_info),
-	SNDRV_CTL_IOCTL_ELEM_REMOVE = _IOWR('U', 0x19, struct sndrv_ctl_elem_id),
+	SNDRV_CTL_IOCTL_ELEM_ADD = _IOWR('U', 0x17, struct snd_ctl_elem_info),
+	SNDRV_CTL_IOCTL_ELEM_REPLACE = _IOWR('U', 0x18, struct snd_ctl_elem_info),
+	SNDRV_CTL_IOCTL_ELEM_REMOVE = _IOWR('U', 0x19, struct snd_ctl_elem_id),
 	SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE = _IOWR('U', 0x20, int),
-	SNDRV_CTL_IOCTL_HWDEP_INFO = _IOR('U', 0x21, struct sndrv_hwdep_info),
+	SNDRV_CTL_IOCTL_HWDEP_INFO = _IOR('U', 0x21, struct snd_hwdep_info),
 	SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE = _IOR('U', 0x30, int),
-	SNDRV_CTL_IOCTL_PCM_INFO = _IOWR('U', 0x31, struct sndrv_pcm_info),
+	SNDRV_CTL_IOCTL_PCM_INFO = _IOWR('U', 0x31, struct snd_pcm_info),
 	SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE = _IOW('U', 0x32, int),
 	SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE = _IOWR('U', 0x40, int),
-	SNDRV_CTL_IOCTL_RAWMIDI_INFO = _IOWR('U', 0x41, struct sndrv_rawmidi_info),
+	SNDRV_CTL_IOCTL_RAWMIDI_INFO = _IOWR('U', 0x41, struct snd_rawmidi_info),
 	SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE = _IOW('U', 0x42, int),
 	SNDRV_CTL_IOCTL_POWER = _IOWR('U', 0xd0, int),
 	SNDRV_CTL_IOCTL_POWER_STATE = _IOR('U', 0xd1, int),
@@ -887,12 +857,12 @@
 #define SNDRV_CTL_EVENT_MASK_ADD	(1<<2)	/* element was added */
 #define SNDRV_CTL_EVENT_MASK_REMOVE	(~0U)	/* element was removed */
 
-struct sndrv_ctl_event {
-	enum sndrv_ctl_event_type type;	/* event type - SNDRV_CTL_EVENT_* */
+struct snd_ctl_event {
+	int type;	/* event type - SNDRV_CTL_EVENT_* */
 	union {
 		struct {
 			unsigned int mask;
-			struct sndrv_ctl_elem_id id;
+			struct snd_ctl_elem_id id;
 		} elem;
                 unsigned char data8[60];
         } data;
@@ -920,14 +890,14 @@
  *
  */
 
-struct sndrv_xferv {
+struct snd_xferv {
 	const struct iovec *vector;
 	unsigned long count;
 };
 
 enum {
-	SNDRV_IOCTL_READV = _IOW('K', 0x00, struct sndrv_xferv),
-	SNDRV_IOCTL_WRITEV = _IOW('K', 0x01, struct sndrv_xferv),
+	SNDRV_IOCTL_READV = _IOW('K', 0x00, struct snd_xferv),
+	SNDRV_IOCTL_WRITEV = _IOW('K', 0x01, struct snd_xferv),
 };
 
 #endif /* __SOUND_ASOUND_H */
diff --git a/include/sound/asound_fm.h b/include/sound/asound_fm.h
index b0da677..956fdc2 100644
--- a/include/sound/asound_fm.h
+++ b/include/sound/asound_fm.h
@@ -29,16 +29,16 @@
 #define SNDRV_DM_FM_MODE_OPL2	0x00
 #define SNDRV_DM_FM_MODE_OPL3	0x01
 
-typedef struct snd_dm_fm_info {
+struct snd_dm_fm_info {
 	unsigned char fm_mode;		/* OPL mode, see SNDRV_DM_FM_MODE_XXX */
 	unsigned char rhythm;		/* percussion mode flag */
-} snd_dm_fm_info_t;
+};
 
 /*
  *  Data structure composing an FM "note" or sound event.
  */
 
-typedef struct snd_dm_fm_voice {
+struct snd_dm_fm_voice {
 	unsigned char op;		/* operator cell (0 or 1) */
 	unsigned char voice;		/* FM voice (0 to 17) */
 
@@ -60,25 +60,25 @@
 	unsigned char left;		/* stereo left */
 	unsigned char right;		/* stereo right */
 	unsigned char waveform;		/* 3 bits: waveform shape */
-} snd_dm_fm_voice_t;
+};
 
 /*
  *  This describes an FM note by its voice, octave, frequency number (10bit)
  *  and key on/off.
  */
 
-typedef struct snd_dm_fm_note {
+struct snd_dm_fm_note {
 	unsigned char voice;	/* 0-17 voice channel */
 	unsigned char octave;	/* 3 bits: what octave to play */
 	unsigned int fnum;	/* 10 bits: frequency number */
 	unsigned char key_on;	/* set for active, clear for silent */
-} snd_dm_fm_note_t;
+};
 
 /*
  *  FM parameters that apply globally to all voices, and thus are not "notes"
  */
 
-typedef struct snd_dm_fm_params {
+struct snd_dm_fm_params {
 	unsigned char am_depth;		/* amplitude modulation depth (1=hi) */
 	unsigned char vib_depth;	/* vibrato depth (1=hi) */
 	unsigned char kbd_split;	/* keyboard split */
@@ -90,17 +90,17 @@
 	unsigned char tomtom;
 	unsigned char cymbal;
 	unsigned char hihat;
-} snd_dm_fm_params_t;
+};
 
 /*
  *  FM mode ioctl settings
  */
 
-#define SNDRV_DM_FM_IOCTL_INFO		_IOR('H', 0x20, snd_dm_fm_info_t)
+#define SNDRV_DM_FM_IOCTL_INFO		_IOR('H', 0x20, struct snd_dm_fm_info)
 #define SNDRV_DM_FM_IOCTL_RESET		_IO ('H', 0x21)
-#define SNDRV_DM_FM_IOCTL_PLAY_NOTE	_IOW('H', 0x22, snd_dm_fm_note_t)
-#define SNDRV_DM_FM_IOCTL_SET_VOICE	_IOW('H', 0x23, snd_dm_fm_voice_t)
-#define SNDRV_DM_FM_IOCTL_SET_PARAMS	_IOW('H', 0x24, snd_dm_fm_params_t)
+#define SNDRV_DM_FM_IOCTL_PLAY_NOTE	_IOW('H', 0x22, struct snd_dm_fm_note)
+#define SNDRV_DM_FM_IOCTL_SET_VOICE	_IOW('H', 0x23, struct snd_dm_fm_voice)
+#define SNDRV_DM_FM_IOCTL_SET_PARAMS	_IOW('H', 0x24, struct snd_dm_fm_params)
 #define SNDRV_DM_FM_IOCTL_SET_MODE	_IOW('H', 0x25, int)
 /* for OPL3 only */
 #define SNDRV_DM_FM_IOCTL_SET_CONNECTION	_IOW('H', 0x26, int)
diff --git a/include/sound/control.h b/include/sound/control.h
index ef7903c..2489b1e 100644
--- a/include/sound/control.h
+++ b/include/sound/control.h
@@ -24,24 +24,14 @@
 
 #include <sound/asound.h>
 
-typedef struct sndrv_aes_iec958 snd_aes_iec958_t;
-typedef struct sndrv_ctl_card_info snd_ctl_card_info_t;
-typedef enum sndrv_ctl_elem_type snd_ctl_elem_type_t;
-typedef enum sndrv_ctl_elem_iface snd_ctl_elem_iface_t;
-typedef struct sndrv_ctl_elem_id snd_ctl_elem_id_t;
-typedef struct sndrv_ctl_elem_list snd_ctl_elem_list_t;
-typedef struct sndrv_ctl_elem_info snd_ctl_elem_info_t;
-typedef struct sndrv_ctl_elem_value snd_ctl_elem_value_t;
-typedef enum sndrv_ctl_event_type snd_ctl_event_type_t;
-typedef struct sndrv_ctl_event snd_ctl_event_t;
-
 #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
 
-typedef int (snd_kcontrol_info_t) (snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo);
-typedef int (snd_kcontrol_get_t) (snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-typedef int (snd_kcontrol_put_t) (snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+struct snd_kcontrol;
+typedef int (snd_kcontrol_info_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_info * uinfo);
+typedef int (snd_kcontrol_get_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
+typedef int (snd_kcontrol_put_t) (struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol);
 
-typedef struct _snd_kcontrol_new {
+struct snd_kcontrol_new {
 	snd_ctl_elem_iface_t iface;	/* interface identifier */
 	unsigned int device;		/* device/client number */
 	unsigned int subdevice;		/* subdevice (substream) number */
@@ -53,40 +43,40 @@
 	snd_kcontrol_get_t *get;
 	snd_kcontrol_put_t *put;
 	unsigned long private_value;
-} snd_kcontrol_new_t;
+};
 
-typedef struct _snd_kcontrol_volatile {
-	snd_ctl_file_t *owner;	/* locked */
+struct snd_kcontrol_volatile {
+	struct snd_ctl_file *owner;	/* locked */
 	pid_t owner_pid;
 	unsigned int access;	/* access rights */
-} snd_kcontrol_volatile_t;
+};
 
-struct _snd_kcontrol {
+struct snd_kcontrol {
 	struct list_head list;		/* list of controls */
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 	unsigned int count;		/* count of same elements */
 	snd_kcontrol_info_t *info;
 	snd_kcontrol_get_t *get;
 	snd_kcontrol_put_t *put;
 	unsigned long private_value;
 	void *private_data;
-	void (*private_free)(snd_kcontrol_t *kcontrol);
-	snd_kcontrol_volatile_t vd[0];	/* volatile data */
+	void (*private_free)(struct snd_kcontrol *kcontrol);
+	struct snd_kcontrol_volatile vd[0];	/* volatile data */
 };
 
-#define snd_kcontrol(n) list_entry(n, snd_kcontrol_t, list)
+#define snd_kcontrol(n) list_entry(n, struct snd_kcontrol, list)
 
-typedef struct _snd_kctl_event {
+struct snd_kctl_event {
 	struct list_head list;	/* list of events */
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 	unsigned int mask;
-} snd_kctl_event_t;
+};
 
-#define snd_kctl_event(n) list_entry(n, snd_kctl_event_t, list)
+#define snd_kctl_event(n) list_entry(n, struct snd_kctl_event, list)
 
-struct _snd_ctl_file {
+struct snd_ctl_file {
 	struct list_head list;		/* list of all control files */
-	snd_card_t *card;
+	struct snd_card *card;
 	pid_t pid;
 	int prefer_pcm_subdevice;
 	int prefer_rawmidi_subdevice;
@@ -97,25 +87,25 @@
 	struct list_head events;	/* waiting events for read */
 };
 
-#define snd_ctl_file(n) list_entry(n, snd_ctl_file_t, list)
+#define snd_ctl_file(n) list_entry(n, struct snd_ctl_file, list)
 
-typedef int (*snd_kctl_ioctl_func_t) (snd_card_t * card,
-				 snd_ctl_file_t * control,
-				 unsigned int cmd, unsigned long arg);
+typedef int (*snd_kctl_ioctl_func_t) (struct snd_card * card,
+				      struct snd_ctl_file * control,
+				      unsigned int cmd, unsigned long arg);
 
-void snd_ctl_notify(snd_card_t * card, unsigned int mask, snd_ctl_elem_id_t * id);
+void snd_ctl_notify(struct snd_card * card, unsigned int mask, struct snd_ctl_elem_id * id);
 
-snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * kcontrol, unsigned int access);
-snd_kcontrol_t *snd_ctl_new1(const snd_kcontrol_new_t * kcontrolnew, void * private_data);
-void snd_ctl_free_one(snd_kcontrol_t * kcontrol);
-int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol);
-int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol);
-int snd_ctl_remove_id(snd_card_t * card, snd_ctl_elem_id_t *id);
-int snd_ctl_rename_id(snd_card_t * card, snd_ctl_elem_id_t *src_id, snd_ctl_elem_id_t *dst_id);
-snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid);
-snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id);
+struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol * kcontrol, unsigned int access);
+struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new * kcontrolnew, void * private_data);
+void snd_ctl_free_one(struct snd_kcontrol * kcontrol);
+int snd_ctl_add(struct snd_card * card, struct snd_kcontrol * kcontrol);
+int snd_ctl_remove(struct snd_card * card, struct snd_kcontrol * kcontrol);
+int snd_ctl_remove_id(struct snd_card * card, struct snd_ctl_elem_id *id);
+int snd_ctl_rename_id(struct snd_card * card, struct snd_ctl_elem_id *src_id, struct snd_ctl_elem_id *dst_id);
+struct snd_kcontrol *snd_ctl_find_numid(struct snd_card * card, unsigned int numid);
+struct snd_kcontrol *snd_ctl_find_id(struct snd_card * card, struct snd_ctl_elem_id *id);
 
-int snd_ctl_create(snd_card_t *card);
+int snd_ctl_create(struct snd_card *card);
 
 int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn);
 int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn);
@@ -127,20 +117,20 @@
 #define snd_ctl_unregister_ioctl_compat(fcn)
 #endif
 
-int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *control);
-int snd_ctl_elem_write(snd_card_t *card, snd_ctl_file_t *file, snd_ctl_elem_value_t *control);
+int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control);
+int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file, struct snd_ctl_elem_value *control);
 
-static inline unsigned int snd_ctl_get_ioffnum(snd_kcontrol_t *kctl, snd_ctl_elem_id_t *id)
+static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
 {
 	return id->numid - kctl->id.numid;
 }
 
-static inline unsigned int snd_ctl_get_ioffidx(snd_kcontrol_t *kctl, snd_ctl_elem_id_t *id)
+static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
 {
 	return id->index - kctl->id.index;
 }
 
-static inline unsigned int snd_ctl_get_ioff(snd_kcontrol_t *kctl, snd_ctl_elem_id_t *id)
+static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
 {
 	if (id->numid) {
 		return snd_ctl_get_ioffnum(kctl, id);
@@ -149,8 +139,8 @@
 	}
 }
 
-static inline snd_ctl_elem_id_t *snd_ctl_build_ioff(snd_ctl_elem_id_t *dst_id,
-						    snd_kcontrol_t *src_kctl,
+static inline struct snd_ctl_elem_id *snd_ctl_build_ioff(struct snd_ctl_elem_id *dst_id,
+						    struct snd_kcontrol *src_kctl,
 						    unsigned int offset)
 {
 	*dst_id = src_kctl->id;
diff --git a/include/sound/core.h b/include/sound/core.h
index 2be65ad..90ac613 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -28,13 +28,6 @@
 #include <linux/workqueue.h>		/* struct workqueue_struct */
 #include <linux/pm.h>			/* pm_message_t */
 
-/* Typedef's */
-typedef struct sndrv_interval snd_interval_t;
-typedef enum sndrv_card_type snd_card_type;
-typedef struct sndrv_xferi snd_xferi_t;
-typedef struct sndrv_xfern snd_xfern_t;
-typedef struct sndrv_xferv snd_xferv_t;
-
 /* forward declarations */
 #ifdef CONFIG_PCI
 struct pci_dev;
@@ -47,76 +40,50 @@
 
 #define SNDRV_DEV_TYPE_RANGE_SIZE		0x1000
 
-typedef enum {
-	SNDRV_DEV_TOPLEVEL =		(0*SNDRV_DEV_TYPE_RANGE_SIZE),
-	SNDRV_DEV_CONTROL,
-	SNDRV_DEV_LOWLEVEL_PRE,
-	SNDRV_DEV_LOWLEVEL_NORMAL =	(1*SNDRV_DEV_TYPE_RANGE_SIZE),
-	SNDRV_DEV_PCM,
-	SNDRV_DEV_RAWMIDI,
-	SNDRV_DEV_TIMER,
-	SNDRV_DEV_SEQUENCER,
-	SNDRV_DEV_HWDEP,
-	SNDRV_DEV_INFO,
-	SNDRV_DEV_BUS,
-	SNDRV_DEV_CODEC,
-	SNDRV_DEV_LOWLEVEL =		(2*SNDRV_DEV_TYPE_RANGE_SIZE)
-} snd_device_type_t;
+typedef int __bitwise snd_device_type_t;
+#define	SNDRV_DEV_TOPLEVEL	((__force snd_device_type_t) 0)
+#define	SNDRV_DEV_CONTROL	((__force snd_device_type_t) 1)
+#define	SNDRV_DEV_LOWLEVEL_PRE	((__force snd_device_type_t) 2)
+#define	SNDRV_DEV_LOWLEVEL_NORMAL ((__force snd_device_type_t) 0x1000)
+#define	SNDRV_DEV_PCM		((__force snd_device_type_t) 0x1001)
+#define	SNDRV_DEV_RAWMIDI	((__force snd_device_type_t) 0x1002)
+#define	SNDRV_DEV_TIMER		((__force snd_device_type_t) 0x1003)
+#define	SNDRV_DEV_SEQUENCER	((__force snd_device_type_t) 0x1004)
+#define	SNDRV_DEV_HWDEP		((__force snd_device_type_t) 0x1005)
+#define	SNDRV_DEV_INFO		((__force snd_device_type_t) 0x1006)
+#define	SNDRV_DEV_BUS		((__force snd_device_type_t) 0x1007)
+#define	SNDRV_DEV_CODEC		((__force snd_device_type_t) 0x1008)
+#define	SNDRV_DEV_LOWLEVEL	((__force snd_device_type_t) 0x2000)
 
-typedef enum {
-	SNDRV_DEV_BUILD,
-	SNDRV_DEV_REGISTERED,
-	SNDRV_DEV_DISCONNECTED
-} snd_device_state_t;
+typedef int __bitwise snd_device_state_t;
+#define	SNDRV_DEV_BUILD		((__force snd_device_state_t) 0)
+#define	SNDRV_DEV_REGISTERED	((__force snd_device_state_t) 1)
+#define	SNDRV_DEV_DISCONNECTED	((__force snd_device_state_t) 2)
 
-typedef enum {
-	SNDRV_DEV_CMD_PRE = 0,
-	SNDRV_DEV_CMD_NORMAL = 1,
-	SNDRV_DEV_CMD_POST = 2
-} snd_device_cmd_t;
+typedef int __bitwise snd_device_cmd_t;
+#define	SNDRV_DEV_CMD_PRE	((__force snd_device_cmd_t) 0)
+#define	SNDRV_DEV_CMD_NORMAL	((__force snd_device_cmd_t) 1)	
+#define	SNDRV_DEV_CMD_POST	((__force snd_device_cmd_t) 2)
 
-typedef struct _snd_card snd_card_t;
-typedef struct _snd_device snd_device_t;
+struct snd_device;
 
-typedef int (snd_dev_free_t)(snd_device_t *device);
-typedef int (snd_dev_register_t)(snd_device_t *device);
-typedef int (snd_dev_disconnect_t)(snd_device_t *device);
-typedef int (snd_dev_unregister_t)(snd_device_t *device);
+struct snd_device_ops {
+	int (*dev_free)(struct snd_device *dev);
+	int (*dev_register)(struct snd_device *dev);
+	int (*dev_disconnect)(struct snd_device *dev);
+	int (*dev_unregister)(struct snd_device *dev);
+};
 
-typedef struct {
-	snd_dev_free_t *dev_free;
-	snd_dev_register_t *dev_register;
-	snd_dev_disconnect_t *dev_disconnect;
-	snd_dev_unregister_t *dev_unregister;
-} snd_device_ops_t;
-
-struct _snd_device {
+struct snd_device {
 	struct list_head list;		/* list of registered devices */
-	snd_card_t *card;		/* card which holds this device */
+	struct snd_card *card;		/* card which holds this device */
 	snd_device_state_t state;	/* state of the device */
 	snd_device_type_t type;		/* device type */
 	void *device_data;		/* device structure */
-	snd_device_ops_t *ops;		/* operations */
+	struct snd_device_ops *ops;	/* operations */
 };
 
-#define snd_device(n) list_entry(n, snd_device_t, list)
-
-/* various typedefs */
-
-typedef struct snd_info_entry snd_info_entry_t;
-typedef struct _snd_pcm snd_pcm_t;
-typedef struct _snd_pcm_str snd_pcm_str_t;
-typedef struct _snd_pcm_substream snd_pcm_substream_t;
-typedef struct _snd_mixer snd_kmixer_t;
-typedef struct _snd_rawmidi snd_rawmidi_t;
-typedef struct _snd_ctl_file snd_ctl_file_t;
-typedef struct _snd_kcontrol snd_kcontrol_t;
-typedef struct _snd_timer snd_timer_t;
-typedef struct _snd_timer_instance snd_timer_instance_t;
-typedef struct _snd_hwdep snd_hwdep_t;
-#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
-typedef struct _snd_oss_mixer snd_mixer_oss_t;
-#endif
+#define snd_device(n) list_entry(n, struct snd_device, list)
 
 /* monitor files for graceful shutdown (hotplug) */
 
@@ -129,7 +96,7 @@
 
 /* main structure for soundcard */
 
-struct _snd_card {
+struct snd_card {
 	int number;			/* number of soundcard (index to
 								snd_cards) */
 
@@ -143,7 +110,7 @@
 	struct module *module;		/* top-level module */
 
 	void *private_data;		/* private data for soundcard */
-	void (*private_free) (snd_card_t *card); /* callback for freeing of
+	void (*private_free) (struct snd_card *card); /* callback for freeing of
 								private data */
 	struct list_head devices;	/* devices */
 
@@ -155,8 +122,8 @@
 	struct list_head controls;	/* all controls for this card */
 	struct list_head ctl_files;	/* active control files */
 
-	snd_info_entry_t *proc_root;	/* root for soundcard specific files */
-	snd_info_entry_t *proc_id;	/* the card id */
+	struct snd_info_entry *proc_root;	/* root for soundcard specific files */
+	struct snd_info_entry *proc_id;	/* the card id */
 	struct proc_dir_entry *proc_root_link;	/* number link to real id */
 
 	struct snd_monitor_file *files; /* all files associated to this card */
@@ -167,92 +134,64 @@
 	wait_queue_head_t shutdown_sleep;
 	struct work_struct free_workq;	/* for free in workqueue */
 	struct device *dev;
-#ifdef CONFIG_SND_GENERIC_DRIVER
-	struct snd_generic_device *generic_dev;
-#endif
 
 #ifdef CONFIG_PM
-	int (*pm_suspend)(snd_card_t *card, pm_message_t state);
-	int (*pm_resume)(snd_card_t *card);
-	void *pm_private_data;
 	unsigned int power_state;	/* power state */
 	struct semaphore power_lock;	/* power lock */
 	wait_queue_head_t power_sleep;
 #endif
 
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
-	snd_mixer_oss_t *mixer_oss;
+	struct snd_mixer_oss *mixer_oss;
 	int mixer_oss_change_count;
 #endif
 };
 
 #ifdef CONFIG_PM
-static inline void snd_power_lock(snd_card_t *card)
+static inline void snd_power_lock(struct snd_card *card)
 {
 	down(&card->power_lock);
 }
 
-static inline void snd_power_unlock(snd_card_t *card)
+static inline void snd_power_unlock(struct snd_card *card)
 {
 	up(&card->power_lock);
 }
 
-static inline unsigned int snd_power_get_state(snd_card_t *card)
+static inline unsigned int snd_power_get_state(struct snd_card *card)
 {
 	return card->power_state;
 }
 
-static inline void snd_power_change_state(snd_card_t *card, unsigned int state)
+static inline void snd_power_change_state(struct snd_card *card, unsigned int state)
 {
 	card->power_state = state;
 	wake_up(&card->power_sleep);
 }
 
 /* init.c */
-int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file);
-
-int snd_card_set_pm_callback(snd_card_t *card,
-			     int (*suspend)(snd_card_t *, pm_message_t),
-			     int (*resume)(snd_card_t *),
-			     void *private_data);
-int snd_card_set_generic_pm_callback(snd_card_t *card,
-				     int (*suspend)(snd_card_t *, pm_message_t),
-				     int (*resume)(snd_card_t *),
-				     void *private_data);
-#define snd_card_set_isa_pm_callback(card,suspend,resume,data) \
-	snd_card_set_generic_pm_callback(card, suspend, resume, data)
-struct pci_dev;
-int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state);
-int snd_card_pci_resume(struct pci_dev *dev);
-#define SND_PCI_PM_CALLBACKS \
-	.suspend = snd_card_pci_suspend,  .resume = snd_card_pci_resume
+int snd_power_wait(struct snd_card *card, unsigned int power_state, struct file *file);
 
 #else /* ! CONFIG_PM */
 
 #define snd_power_lock(card)		do { (void)(card); } while (0)
 #define snd_power_unlock(card)		do { (void)(card); } while (0)
-static inline int snd_power_wait(snd_card_t *card, unsigned int state, struct file *file) { return 0; }
+static inline int snd_power_wait(struct snd_card *card, unsigned int state, struct file *file) { return 0; }
 #define snd_power_get_state(card)	SNDRV_CTL_POWER_D0
 #define snd_power_change_state(card, state)	do { (void)(card); } while (0)
-#define snd_card_set_pm_callback(card,suspend,resume,data)
-#define snd_card_set_generic_pm_callback(card,suspend,resume,data)
-#define snd_card_set_isa_pm_callback(card,suspend,resume,data)
-#define SND_PCI_PM_CALLBACKS
 
 #endif /* CONFIG_PM */
 
-struct _snd_minor {
-	struct list_head list;		/* list of all minors per card */
-	int number;			/* minor number */
+struct snd_minor {
+	int type;			/* SNDRV_DEVICE_TYPE_XXX */
+	int card;			/* card number */
 	int device;			/* device number */
-	const char *comment;		/* for /proc/asound/devices */
 	struct file_operations *f_ops;	/* file operations */
+	void *private_data;		/* private data for f_ops->open */
 	char name[0];			/* device name (keep at the end of
 								structure) */
 };
 
-typedef struct _snd_minor snd_minor_t;
-
 /* sound.c */
 
 extern int snd_major;
@@ -260,12 +199,18 @@
 
 void snd_request_card(int card);
 
-int snd_register_device(int type, snd_card_t *card, int dev, snd_minor_t *reg, const char *name);
-int snd_unregister_device(int type, snd_card_t *card, int dev);
+int snd_register_device(int type, struct snd_card *card, int dev,
+			struct file_operations *f_ops, void *private_data,
+			const char *name);
+int snd_unregister_device(int type, struct snd_card *card, int dev);
+void *snd_lookup_minor_data(unsigned int minor, int type);
 
 #ifdef CONFIG_SND_OSSEMUL
-int snd_register_oss_device(int type, snd_card_t *card, int dev, snd_minor_t *reg, const char *name);
-int snd_unregister_oss_device(int type, snd_card_t *card, int dev);
+int snd_register_oss_device(int type, struct snd_card *card, int dev,
+			    struct file_operations *f_ops, void *private_data,
+			    const char *name);
+int snd_unregister_oss_device(int type, struct snd_card *card, int dev);
+void *snd_lookup_oss_minor_data(unsigned int minor, int type);
 #endif
 
 int snd_minor_info_init(void);
@@ -276,11 +221,9 @@
 #ifdef CONFIG_SND_OSSEMUL
 int snd_minor_info_oss_init(void);
 int snd_minor_info_oss_done(void);
-int snd_oss_init_module(void);
 #else
 #define snd_minor_info_oss_init() /*NOP*/
 #define snd_minor_info_oss_done() /*NOP*/
-#define snd_oss_init_module() 0
 #endif
 
 /* memory.c */
@@ -291,43 +234,41 @@
 /* init.c */
 
 extern unsigned int snd_cards_lock;
-extern snd_card_t *snd_cards[SNDRV_CARDS];
+extern struct snd_card *snd_cards[SNDRV_CARDS];
 extern rwlock_t snd_card_rwlock;
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 #define SND_MIXER_OSS_NOTIFY_REGISTER	0
 #define SND_MIXER_OSS_NOTIFY_DISCONNECT	1
 #define SND_MIXER_OSS_NOTIFY_FREE	2
-extern int (*snd_mixer_oss_notify_callback)(snd_card_t *card, int cmd);
+extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd);
 #endif
 
-snd_card_t *snd_card_new(int idx, const char *id,
+struct snd_card *snd_card_new(int idx, const char *id,
 			 struct module *module, int extra_size);
-int snd_card_disconnect(snd_card_t *card);
-int snd_card_free(snd_card_t *card);
-int snd_card_free_in_thread(snd_card_t *card);
-int snd_card_register(snd_card_t *card);
+int snd_card_disconnect(struct snd_card *card);
+int snd_card_free(struct snd_card *card);
+int snd_card_free_in_thread(struct snd_card *card);
+int snd_card_register(struct snd_card *card);
 int snd_card_info_init(void);
 int snd_card_info_done(void);
-int snd_component_add(snd_card_t *card, const char *component);
-int snd_card_file_add(snd_card_t *card, struct file *file);
-int snd_card_file_remove(snd_card_t *card, struct file *file);
+int snd_component_add(struct snd_card *card, const char *component);
+int snd_card_file_add(struct snd_card *card, struct file *file);
+int snd_card_file_remove(struct snd_card *card, struct file *file);
 
 #ifndef snd_card_set_dev
 #define snd_card_set_dev(card,devptr) ((card)->dev = (devptr))
 #endif
-/* register a generic device (for ISA, etc) */
-int snd_card_set_generic_dev(snd_card_t *card);
 
 /* device.c */
 
-int snd_device_new(snd_card_t *card, snd_device_type_t type,
-		   void *device_data, snd_device_ops_t *ops);
-int snd_device_register(snd_card_t *card, void *device_data);
-int snd_device_register_all(snd_card_t *card);
-int snd_device_disconnect(snd_card_t *card, void *device_data);
-int snd_device_disconnect_all(snd_card_t *card);
-int snd_device_free(snd_card_t *card, void *device_data);
-int snd_device_free_all(snd_card_t *card, snd_device_cmd_t cmd);
+int snd_device_new(struct snd_card *card, snd_device_type_t type,
+		   void *device_data, struct snd_device_ops *ops);
+int snd_device_register(struct snd_card *card, void *device_data);
+int snd_device_register_all(struct snd_card *card);
+int snd_device_disconnect(struct snd_card *card, void *device_data);
+int snd_device_disconnect_all(struct snd_card *card);
+int snd_device_free(struct snd_card *card, void *device_data);
+int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd);
 
 /* isadma.c */
 
@@ -443,4 +384,6 @@
 #endif
 #endif
 
+#include "typedefs.h"
+
 #endif /* __SOUND_CORE_H */
diff --git a/include/sound/cs4231.h b/include/sound/cs4231.h
index d7f9082..ac6a5d8 100644
--- a/include/sound/cs4231.h
+++ b/include/sound/cs4231.h
@@ -26,21 +26,6 @@
 #include "pcm.h"
 #include "timer.h"
 
-#ifdef CONFIG_SBUS
-#define SBUS_SUPPORT
-#include <asm/sbus.h>
-#endif
-
-#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
-#define EBUS_SUPPORT
-#include <linux/pci.h>
-#include <asm/ebus.h>
-#endif
-
-#if !defined(SBUS_SUPPORT) && !defined(EBUS_SUPPORT)
-#define LEGACY_SUPPORT
-#endif
-
 /* IO ports */
 
 #define CS4231P(x)		(c_d_c_CS4231##x)
@@ -232,18 +217,14 @@
 #define CS4231_HWSHARE_DMA1	(1<<1)
 #define CS4231_HWSHARE_DMA2	(1<<2)
 
-typedef struct _snd_cs4231 cs4231_t;
-
-struct _snd_cs4231 {
+struct snd_cs4231 {
 	unsigned long port;		/* base i/o port */
-#ifdef LEGACY_SUPPORT
 	struct resource *res_port;
 	unsigned long cport;		/* control base i/o port (CS4236) */
 	struct resource *res_cport;
 	int irq;			/* IRQ line */
 	int dma1;			/* playback DMA */
 	int dma2;			/* record DMA */
-#endif
 	unsigned short version;		/* version of CODEC chip */
 	unsigned short mode;		/* see to CS4231_MODE_XXXX */
 	unsigned short hardware;	/* see to CS4231_HW_XXXX */
@@ -251,29 +232,11 @@
 	unsigned short single_dma:1,	/* forced single DMA mode (GUS 16-bit daughter board) or dma1 == dma2 */
 		       ebus_flag:1;	/* SPARC: EBUS present */
 
-#ifdef EBUS_SUPPORT
-	struct ebus_dma_info eb2c;
-        struct ebus_dma_info eb2p;
-#endif
-
-#if defined(SBUS_SUPPORT) || defined(EBUS_SUPPORT)
-	union {
-#ifdef SBUS_SUPPORT
-		struct sbus_dev         *sdev;
-#endif
-#ifdef EBUS_SUPPORT
-		struct pci_dev          *pdev;
-#endif
-	} dev_u;
-	unsigned int p_periods_sent;
-	unsigned int c_periods_sent;
-#endif
-
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
-	snd_timer_t *timer;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+	struct snd_timer *timer;
 
 	unsigned char image[32];	/* registers image */
 	unsigned char eimage[32];	/* extended registers image */
@@ -281,63 +244,59 @@
 	int mce_bit;
 	int calibrate_mute;
 	int sw_3d_bit;
-#ifdef LEGACY_SUPPORT
 	unsigned int p_dma_size;
 	unsigned int c_dma_size;
-#endif
 
 	spinlock_t reg_lock;
 	struct semaphore mce_mutex;
 	struct semaphore open_mutex;
 
-	int (*rate_constraint) (snd_pcm_runtime_t *runtime);
-	void (*set_playback_format) (cs4231_t *chip, snd_pcm_hw_params_t *hw_params, unsigned char pdfr);
-	void (*set_capture_format) (cs4231_t *chip, snd_pcm_hw_params_t *hw_params, unsigned char cdfr);
-	void (*trigger) (cs4231_t *chip, unsigned int what, int start);
+	int (*rate_constraint) (struct snd_pcm_runtime *runtime);
+	void (*set_playback_format) (struct snd_cs4231 *chip, struct snd_pcm_hw_params *hw_params, unsigned char pdfr);
+	void (*set_capture_format) (struct snd_cs4231 *chip, struct snd_pcm_hw_params *hw_params, unsigned char cdfr);
+	void (*trigger) (struct snd_cs4231 *chip, unsigned int what, int start);
 #ifdef CONFIG_PM
-	void (*suspend) (cs4231_t *chip);
-	void (*resume) (cs4231_t *chip);
+	void (*suspend) (struct snd_cs4231 *chip);
+	void (*resume) (struct snd_cs4231 *chip);
 #endif
 	void *dma_private_data;
-#ifdef LEGACY_SUPPORT
-	int (*claim_dma) (cs4231_t *chip, void *dma_private_data, int dma);
-	int (*release_dma) (cs4231_t *chip, void *dma_private_data, int dma);
-#endif
+	int (*claim_dma) (struct snd_cs4231 *chip, void *dma_private_data, int dma);
+	int (*release_dma) (struct snd_cs4231 *chip, void *dma_private_data, int dma);
 };
 
 /* exported functions */
 
-void snd_cs4231_out(cs4231_t *chip, unsigned char reg, unsigned char val);
-unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg);
-void snd_cs4236_ext_out(cs4231_t *chip, unsigned char reg, unsigned char val);
-unsigned char snd_cs4236_ext_in(cs4231_t *chip, unsigned char reg);
-void snd_cs4231_mce_up(cs4231_t *chip);
-void snd_cs4231_mce_down(cs4231_t *chip);
+void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val);
+unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg);
+void snd_cs4236_ext_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val);
+unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg);
+void snd_cs4231_mce_up(struct snd_cs4231 *chip);
+void snd_cs4231_mce_down(struct snd_cs4231 *chip);
 
 irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
-const char *snd_cs4231_chip_id(cs4231_t *chip);
+const char *snd_cs4231_chip_id(struct snd_cs4231 *chip);
 
-int snd_cs4231_create(snd_card_t * card,
+int snd_cs4231_create(struct snd_card *card,
 		      unsigned long port,
 		      unsigned long cport,
 		      int irq, int dma1, int dma2,
 		      unsigned short hardware,
 		      unsigned short hwshare,
-		      cs4231_t ** rchip);
-int snd_cs4231_pcm(cs4231_t * chip, int device, snd_pcm_t **rpcm);
-int snd_cs4231_timer(cs4231_t * chip, int device, snd_timer_t **rtimer);
-int snd_cs4231_mixer(cs4231_t * chip);
+		      struct snd_cs4231 ** rchip);
+int snd_cs4231_pcm(struct snd_cs4231 * chip, int device, struct snd_pcm **rpcm);
+int snd_cs4231_timer(struct snd_cs4231 * chip, int device, struct snd_timer **rtimer);
+int snd_cs4231_mixer(struct snd_cs4231 * chip);
 
-int snd_cs4236_create(snd_card_t * card,
+int snd_cs4236_create(struct snd_card *card,
 		      unsigned long port,
 		      unsigned long cport,
 		      int irq, int dma1, int dma2,
 		      unsigned short hardware,
 		      unsigned short hwshare,
-		      cs4231_t ** rchip);
-int snd_cs4236_pcm(cs4231_t * chip, int device, snd_pcm_t **rpcm);
-int snd_cs4236_mixer(cs4231_t * chip);
+		      struct snd_cs4231 ** rchip);
+int snd_cs4236_pcm(struct snd_cs4231 * chip, int device, struct snd_pcm **rpcm);
+int snd_cs4236_mixer(struct snd_cs4231 * chip);
 
 /*
  *  mixer library
@@ -349,9 +308,9 @@
   .get = snd_cs4231_get_single, .put = snd_cs4231_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-int snd_cs4231_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
-int snd_cs4231_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_cs4231_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_cs4231_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
+int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
 
 #define CS4231_DOUBLE(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
@@ -359,8 +318,8 @@
   .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-int snd_cs4231_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
-int snd_cs4231_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_cs4231_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_cs4231_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
+int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
 
 #endif /* __SOUND_CS4231_H */
diff --git a/include/sound/cs46xx.h b/include/sound/cs46xx.h
index b0c0e19..199b509 100644
--- a/include/sound/cs46xx.h
+++ b/include/sound/cs46xx.h
@@ -1631,42 +1631,41 @@
 #define CS46XX_MIXER_SPDIF_INPUT_ELEMENT    1
 #define CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT   2
 
-typedef struct _snd_cs46xx cs46xx_t;
 
-typedef struct _snd_cs46xx_pcm_t {
+struct snd_cs46xx_pcm {
 	struct snd_dma_buffer hw_buf;
   
 	unsigned int ctl;
 	unsigned int shift;	/* Shift count to trasform frames in bytes */
-	snd_pcm_indirect_t pcm_rec;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_indirect pcm_rec;
+	struct snd_pcm_substream *substream;
 
-	pcm_channel_descriptor_t * pcm_channel;
+	struct dsp_pcm_channel_descriptor * pcm_channel;
 
 	int pcm_channel_id;    /* Fron Rear, Center Lfe  ... */
-} cs46xx_pcm_t;
+};
 
-typedef struct {
+struct snd_cs46xx_region {
 	char name[24];
 	unsigned long base;
 	void __iomem *remap_addr;
 	unsigned long size;
 	struct resource *resource;
-} snd_cs46xx_region_t;
+};
 
-struct _snd_cs46xx {
+struct snd_cs46xx {
 	int irq;
 	unsigned long ba0_addr;
 	unsigned long ba1_addr;
 	union {
 		struct {
-			snd_cs46xx_region_t ba0;
-			snd_cs46xx_region_t data0;
-			snd_cs46xx_region_t data1;
-			snd_cs46xx_region_t pmem;
-			snd_cs46xx_region_t reg;
+			struct snd_cs46xx_region ba0;
+			struct snd_cs46xx_region data0;
+			struct snd_cs46xx_region data1;
+			struct snd_cs46xx_region pmem;
+			struct snd_cs46xx_region reg;
 		} name;
-		snd_cs46xx_region_t idx[5];
+		struct snd_cs46xx_region idx[5];
 	} region;
 
 	unsigned int mode;
@@ -1676,34 +1675,34 @@
 
 		unsigned int ctl;
 		unsigned int shift;	/* Shift count to trasform frames in bytes */
-		snd_pcm_indirect_t pcm_rec;
-		snd_pcm_substream_t *substream;
+		struct snd_pcm_indirect pcm_rec;
+		struct snd_pcm_substream *substream;
 	} capt;
 
 
 	int nr_ac97_codecs;
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97[MAX_NR_AC97];
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97[MAX_NR_AC97];
 
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
 
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *midi_input;
-	snd_rawmidi_substream_t *midi_output;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *midi_input;
+	struct snd_rawmidi_substream *midi_output;
 
 	spinlock_t reg_lock;
 	unsigned int midcr;
 	unsigned int uartm;
 
 	int amplifier;
-	void (*amplifier_ctrl)(cs46xx_t *, int);
-	void (*active_ctrl)(cs46xx_t *, int);
-  	void (*mixer_init)(cs46xx_t *);
+	void (*amplifier_ctrl)(struct snd_cs46xx *, int);
+	void (*active_ctrl)(struct snd_cs46xx *, int);
+  	void (*mixer_init)(struct snd_cs46xx *);
 
 	int acpi_port;
-	snd_kcontrol_t *eapd_switch; /* for amplifier hack */
+	struct snd_kcontrol *eapd_switch; /* for amplifier hack */
 	int accept_valid;	/* accept mmap valid (for OSS) */
 
 	struct gameport *gameport;
@@ -1714,29 +1713,31 @@
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	struct semaphore spos_mutex;
 
-	dsp_spos_instance_t * dsp_spos_instance;
+	struct dsp_spos_instance * dsp_spos_instance;
 
-	snd_pcm_t *pcm_rear;
-	snd_pcm_t *pcm_center_lfe;
-	snd_pcm_t *pcm_iec958;
+	struct snd_pcm *pcm_rear;
+	struct snd_pcm *pcm_center_lfe;
+	struct snd_pcm *pcm_iec958;
 #else /* for compatibility */
-	cs46xx_pcm_t *playback_pcm;
+	struct snd_cs46xx_pcm *playback_pcm;
 	unsigned int play_ctl;
 #endif
 };
 
-int snd_cs46xx_create(snd_card_t *card,
+int snd_cs46xx_create(struct snd_card *card,
 		      struct pci_dev *pci,
 		      int external_amp, int thinkpad,
-		      cs46xx_t **rcodec);
+		      struct snd_cs46xx **rcodec);
+int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state);
+int snd_cs46xx_resume(struct pci_dev *pci);
 
-int snd_cs46xx_pcm(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
-int snd_cs46xx_pcm_rear(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
-int snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
-int snd_cs46xx_pcm_center_lfe(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
-int snd_cs46xx_mixer(cs46xx_t *chip, int spdif_device);
-int snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rmidi);
-int snd_cs46xx_start_dsp(cs46xx_t *chip);
-int snd_cs46xx_gameport(cs46xx_t *chip);
+int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
+int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
+int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
+int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
+int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device);
+int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rmidi);
+int snd_cs46xx_start_dsp(struct snd_cs46xx *chip);
+int snd_cs46xx_gameport(struct snd_cs46xx *chip);
 
 #endif /* __SOUND_CS46XX_H */
diff --git a/include/sound/cs46xx_dsp_scb_types.h b/include/sound/cs46xx_dsp_scb_types.h
index 3f990a3..9cb6c7d 100644
--- a/include/sound/cs46xx_dsp_scb_types.h
+++ b/include/sound/cs46xx_dsp_scb_types.h
@@ -41,7 +41,7 @@
 
 /* This structs are used internally by the SP */
 
-typedef struct _basic_dma_req_t {
+struct dsp_basic_dma_req {
 	/* DMA Requestor Word 0 (DCW)  fields:
 
 	   31 [30-28]27  [26:24] 23 22 21 20 [19:18] [17:16] 15 14 13  12  11 10 9 8 7 6  [5:0]
@@ -53,9 +53,9 @@
 	u32 dmw;                 /* DMA Mode Word */
 	u32 saw;                 /* Source Address Word */
 	u32 daw;                 /* Destination Address Word  */
-} basic_dma_req_t;
+};
 
-typedef struct _scatter_gather_ext_t {
+struct dsp_scatter_gather_ext {
 	u32 npaw;                /* Next-Page Address Word */
 
 	/* DMA Requestor Word 5 (NPCW)  fields:
@@ -69,9 +69,9 @@
 	u32 lbaw;                /* Loop-Begin Address Word */
 	u32 nplbaw;              /* Next-Page after Loop-Begin Address Word */
 	u32 sgaw;                /* Scatter/Gather Address Word */
-} scatter_gather_ext_t;
+};
 
-typedef struct _volume_control_t {
+struct dsp_volume_control {
 	___DSP_DUAL_16BIT_ALLOC(
 	   rightTarg,  /* Target volume for left & right channels */
 	   leftTarg
@@ -80,10 +80,10 @@
 	   rightVol,   /* Current left & right channel volumes */
 	   leftVol
 	)
-} volume_control_t;
+};
 
 /* Generic stream control block (SCB) structure definition */
-typedef struct _generic_scb_t {
+struct dsp_generic_scb {
 	/* For streaming I/O, the DSP should never alter any words in the DMA
 	   requestor or the scatter/gather extension.  Only ad hoc DMA request
 	   streams are free to alter the requestor (currently only occur in the
@@ -99,13 +99,13 @@
   
 	/* Initialized by the host, only modified by DMA 
 	   R/O for the DSP task */
-	basic_dma_req_t  basic_req;  /* Optional */
+	struct dsp_basic_dma_req  basic_req;  /* Optional */
 
 	/* Scatter/gather DMA requestor extension   (5 ints) 
 	   Initialized by the host, only modified by DMA
 	   DSP task never needs to even read these.
 	*/
-	scatter_gather_ext_t sg_ext;  /* Optional */
+	struct dsp_scatter_gather_ext sg_ext;  /* Optional */
 
 	/* Sublist pointer & next stream control block (SCB) link.
 	   Initialized & modified by the host R/O for the DSP task
@@ -179,11 +179,11 @@
      
 	   These two 32-bit words are redefined for wavetable & 3-D voices.    
 	*/
-	volume_control_t vol_ctrl_t;   /* Optional */
-} generic_scb_t;
+	struct dsp_volume_control vol_ctrl_t;   /* Optional */
+};
 
 
-typedef struct _spos_control_block_t {
+struct dsp_spos_control_block {
 	/* WARNING: Certain items in this structure are modified by the host
 	            Any dword that can be modified by the host, must not be
 		    modified by the SP as the host can only do atomic dword
@@ -273,10 +273,10 @@
 	u32 r32_save_for_spurious_int;
 	u32 r32_save_for_trap;
 	u32 r32_save_for_HFG;
-} spos_control_block_t;
+};
 
 /* SPB for MIX_TO_OSTREAM algorithm family */
-typedef struct _mix2_ostream_spb_t
+struct dsp_mix2_ostream_spb
 {
 	/* 16b.16b integer.frac approximation to the
 	   number of 3 sample triplets to output each
@@ -290,13 +290,13 @@
 	   output triplets since the start of group 
 	*/
 	u32 accumOutTriplets;  
-} mix2_ostream_spb_t;
+};
 
 /* SCB for Timing master algorithm */
-typedef struct _timing_master_scb_t {
+struct dsp_timing_master_scb {
 	/* First 12 dwords from generic_scb_t */
-	basic_dma_req_t  basic_req;  /* Optional */
-	scatter_gather_ext_t sg_ext;  /* Optional */
+	struct dsp_basic_dma_req  basic_req;  /* Optional */
+	struct dsp_scatter_gather_ext sg_ext;  /* Optional */
 	___DSP_DUAL_16BIT_ALLOC(
 	    next_scb,     /* REQUIRED */
 	    sub_list_ptr  /* REQUIRED */
@@ -358,13 +358,13 @@
 	   number of samples to output each frame.
 	   (approximation must be floor, to insure */
 	u32 nsamp_per_frm_q15;
-} timing_master_scb_t;
+};
 
 /* SCB for CODEC output algorithm */
-typedef struct _codec_output_scb_t {
+struct dsp_codec_output_scb {
 	/* First 13 dwords from generic_scb_t */
-	basic_dma_req_t  basic_req;  /* Optional */
-	scatter_gather_ext_t sg_ext;  /* Optional */
+	struct dsp_basic_dma_req  basic_req;  /* Optional */
+	struct dsp_scatter_gather_ext sg_ext;  /* Optional */
 	___DSP_DUAL_16BIT_ALLOC(
 	    next_scb,       /* REQUIRED */
 	    sub_list_ptr    /* REQUIRED */
@@ -422,13 +422,13 @@
 	    reserved,
 	    last_sub_ptr
 	)
-} codec_output_scb_t;
+};
 
 /* SCB for CODEC input algorithm */
-typedef struct _codec_input_scb_t {
+struct dsp_codec_input_scb {
 	/* First 13 dwords from generic_scb_t */
-	basic_dma_req_t  basic_req;  /* Optional */
-	scatter_gather_ext_t sg_ext;  /* Optional */
+	struct dsp_basic_dma_req  basic_req;  /* Optional */
+	struct dsp_scatter_gather_ext sg_ext;  /* Optional */
 	___DSP_DUAL_16BIT_ALLOC(
 	    next_scb,       /* REQUIRED */
 	    sub_list_ptr    /* REQUIRED */
@@ -479,13 +479,13 @@
 	)
 
 	u32  reserved2;
-} codec_input_scb_t;
+};
 
 
-typedef struct _pcm_serial_input_scb_t {
+struct dsp_pcm_serial_input_scb {
 	/* First 13 dwords from generic_scb_t */
-	basic_dma_req_t  basic_req;  /* Optional */
-	scatter_gather_ext_t sg_ext;  /* Optional */
+	struct dsp_basic_dma_req  basic_req;  /* Optional */
+	struct dsp_scatter_gather_ext sg_ext;  /* Optional */
 	___DSP_DUAL_16BIT_ALLOC(
 	    next_scb,       /* REQUIRED */
 	    sub_list_ptr    /* REQUIRED */
@@ -512,11 +512,11 @@
 	)
 
 	/* Initialized by the host (host updates target volumes) */
-	volume_control_t psi_vol_ctrl;   
+	struct dsp_volume_control psi_vol_ctrl;   
   
-} pcm_serial_input_scb_t;
+};
 
-typedef struct _src_task_scb_t {
+struct dsp_src_task_scb {
 	___DSP_DUAL_16BIT_ALLOC(
 	    frames_left_in_gof,
 	    gofs_left_in_sec
@@ -571,10 +571,10 @@
   
 	u32   phiIncr6int_26frac;
   
-	volume_control_t src_vol_ctrl;
-} src_task_scb_t;
+	struct dsp_volume_control src_vol_ctrl;
+};
 
-typedef struct _decimate_by_pow2_scb_t {
+struct dsp_decimate_by_pow2_scb {
 	/* decimationFactor = 2, 4, or 8 (larger factors waste too much memory
 	                                  when compared to cascading decimators)
 	*/
@@ -648,10 +648,10 @@
 
 	u32  dec2_reserved4;
 
-	volume_control_t dec2_vol_ctrl; /* Not used! */
-} decimate_by_pow2_scb_t;
+	struct dsp_volume_control dec2_vol_ctrl; /* Not used! */
+};
 
-typedef struct _vari_decimate_scb_t {
+struct dsp_vari_decimate_scb {
 	___DSP_DUAL_16BIT_ALLOC(
 	    vdec_frames_left_in_gof,
 	    vdec_gofs_left_in_sec
@@ -711,15 +711,15 @@
 
 	u32 vdec_phi_incr_6int_26frac;
 
-	volume_control_t vdec_vol_ctrl;
-} vari_decimate_scb_t;
+	struct dsp_volume_control vdec_vol_ctrl;
+};
 
 
 /* SCB for MIX_TO_OSTREAM algorithm family */
-typedef struct _mix2_ostream_scb_t {
+struct dsp_mix2_ostream_scb {
 	/* First 13 dwords from generic_scb_t */
-	basic_dma_req_t  basic_req;  /* Optional */
-	scatter_gather_ext_t sg_ext;  /* Optional */
+	struct dsp_basic_dma_req  basic_req;  /* Optional */
+	struct dsp_scatter_gather_ext sg_ext;  /* Optional */
 	___DSP_DUAL_16BIT_ALLOC(
 	    next_scb,       /* REQUIRED */
 	    sub_list_ptr    /* REQUIRED */
@@ -758,14 +758,14 @@
 	    const_FFFF,
 	    const_zero
 	)
-} mix2_ostream_scb_t;
+};
 
 
 /* SCB for S16_MIX algorithm */
-typedef struct _mix_only_scb_t {
+struct dsp_mix_only_scb {
 	/* First 13 dwords from generic_scb_t */
-	basic_dma_req_t  basic_req;  /* Optional */
-	scatter_gather_ext_t sg_ext;  /* Optional */
+	struct dsp_basic_dma_req  basic_req;  /* Optional */
+	struct dsp_scatter_gather_ext sg_ext;  /* Optional */
 	___DSP_DUAL_16BIT_ALLOC(
 	    next_scb,       /* REQUIRED */
 	    sub_list_ptr    /* REQUIRED */
@@ -780,11 +780,11 @@
 	u32 strm_buf_ptr;   /* REQUIRED */
 
 	u32 reserved;
-	volume_control_t vol_ctrl;
-} mix_only_scb_t;
+	struct dsp_volume_control vol_ctrl;
+};
 
 /* SCB for the async. CODEC input algorithm */
-typedef struct _async_codec_input_scb_t {		 
+struct dsp_async_codec_input_scb {
 	u32 io_free2;     
   
 	u32 io_current_total;
@@ -837,11 +837,11 @@
 	)
 
 	u32 i_free;
-} async_codec_input_scb_t;
+};
 
 
 /* SCB for the SP/DIF CODEC input and output */
-typedef struct _spdifiscb_t {
+struct dsp_spdifiscb {
 	___DSP_DUAL_16BIT_ALLOC(
 	    status_ptr,     
 	    status_start_ptr
@@ -895,12 +895,11 @@
 	)
 
 	u32  free1;
-} spdifiscb_t;
+};
 
 
 /* SCB for the SP/DIF CODEC input and output  */
-typedef struct _spdifoscb_t {		 
-
+struct dsp_spdifoscb {		 
 
 	u32 free2;     
 
@@ -941,11 +940,10 @@
 	)
 
 	u32  free1;                                         
-} spdifoscb_t;
+};
 
 
-
-typedef struct _asynch_fg_rx_scb_t {
+struct dsp_asynch_fg_rx_scb {
 	___DSP_DUAL_16BIT_ALLOC(
 	    bot_buf_mask,
 	    buf_Mask
@@ -993,11 +991,10 @@
 	    right_vol,
 	    left_vol
 	)
-} asynch_fg_rx_scb_t;
+};
 
 
-
-typedef struct _asynch_fg_tx_scb_t {
+struct dsp_asynch_fg_tx_scb {
 	___DSP_DUAL_16BIT_ALLOC(
 	    not_buf_mask,
 	    buf_mask
@@ -1052,13 +1049,13 @@
 	    unused_right_vol,
 	    unused_left_vol
 	)
-} asynch_fg_tx_scb_t;
+};
 
 
-typedef struct _output_snoop_scb_t {
+struct dsp_output_snoop_scb {
 	/* First 13 dwords from generic_scb_t */
-	basic_dma_req_t  basic_req;  /* Optional */
-	scatter_gather_ext_t sg_ext;  /* Optional */
+	struct dsp_basic_dma_req  basic_req;  /* Optional */
+	struct dsp_scatter_gather_ext sg_ext;  /* Optional */
 	___DSP_DUAL_16BIT_ALLOC(
 	    next_scb,       /* REQUIRED */
 	    sub_list_ptr    /* REQUIRED */
@@ -1083,9 +1080,9 @@
 	    reserved,
 	    input_scb
 	)
-} output_snoop_scb_t;
+};
 
-typedef struct _spio_write_scb_t {
+struct dsp_spio_write_scb {
 	___DSP_DUAL_16BIT_ALLOC(
 	    address1,
 	    address2
@@ -1122,9 +1119,9 @@
 	)
 
 	u32 unused3[5];
-} spio_write_scb_t;
+};
 
-typedef struct _magic_snoop_task_t {
+struct dsp_magic_snoop_task {
 	u32 i0;
 	u32 i1;
 
@@ -1155,11 +1152,11 @@
 
 	u32 i8;
 
-	volume_control_t vdec_vol_ctrl;
-} magic_snoop_task_t;
+	struct dsp_volume_control vdec_vol_ctrl;
+};
 
 
-typedef struct _filter_scb_t {
+struct dsp_filter_scb {
 	___DSP_DUAL_16BIT_ALLOC(
 	      a0_right,          /* 0x00 */
 	      a0_left
@@ -1212,5 +1209,5 @@
               b2_right,          /* 0x0F */
 	      b2_left
 	)
-} filter_scb_t;
+};
 #endif /* __DSP_SCB_TYPES_H__ */
diff --git a/include/sound/cs46xx_dsp_spos.h b/include/sound/cs46xx_dsp_spos.h
index 10014cb6..da934de 100644
--- a/include/sound/cs46xx_dsp_spos.h
+++ b/include/sound/cs46xx_dsp_spos.h
@@ -65,133 +65,130 @@
 #define DSP_SPDIF_STATUS_HW_ENABLED           4
 #define DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED   8
 
-struct _dsp_module_desc_t;
-
-typedef struct _symbol_entry_t {
+struct dsp_symbol_entry {
 	u32 address;
 	char symbol_name[DSP_MAX_SYMBOL_NAME];
 	int symbol_type;
 
 	/* initialized by driver */
-	struct _dsp_module_desc_t * module;
+	struct dsp_module_desc * module;
 	int deleted;
-} symbol_entry_t;
+};
 
-typedef struct _symbol_desc_t {
+struct dsp_symbol_desc {
 	int nsymbols;
 
-	symbol_entry_t * symbols;
+	struct dsp_symbol_entry *symbols;
 
 	/* initialized by driver */
 	int highest_frag_index;
-} symbol_desc_t;
+};
 
-
-typedef struct _segment_desc_t {
+struct dsp_segment_desc {
 	int segment_type;
 	u32 offset;
 	u32 size;
 	u32 * data;
-} segment_desc_t;
+};
 
-typedef struct _dsp_module_desc_t {
+struct dsp_module_desc {
 	char * module_name;
-	symbol_desc_t symbol_table;
+	struct dsp_symbol_desc symbol_table;
 	int nsegments;
-	segment_desc_t * segments;
+	struct dsp_segment_desc * segments;
 
 	/* initialized by driver */
 	u32 overlay_begin_address;
 	u32 load_address;
 	int nfixups;
-} dsp_module_desc_t;
+};
 
-typedef struct _dsp_scb_descriptor_t {
+struct dsp_scb_descriptor {
 	char scb_name[DSP_MAX_SCB_NAME];
 	u32 address;
 	int index;
 
-	struct _dsp_scb_descriptor_t * sub_list_ptr;
-	struct _dsp_scb_descriptor_t * next_scb_ptr;
-	struct _dsp_scb_descriptor_t * parent_scb_ptr;
+	struct dsp_scb_descriptor * sub_list_ptr;
+	struct dsp_scb_descriptor * next_scb_ptr;
+	struct dsp_scb_descriptor * parent_scb_ptr;
 
-	symbol_entry_t * task_entry;
-	symbol_entry_t * scb_symbol;
+	struct dsp_symbol_entry * task_entry;
+	struct dsp_symbol_entry * scb_symbol;
 
-	snd_info_entry_t *proc_info;
+	struct snd_info_entry *proc_info;
 	int ref_count;
 	spinlock_t lock;
 
 	int deleted;
-} dsp_scb_descriptor_t;
+};
 
-typedef struct _dsp_task_descriptor_t {
+struct dsp_task_descriptor {
 	char task_name[DSP_MAX_TASK_NAME];
 	int size;
 	u32 address;
 	int index;
-} dsp_task_descriptor_t;
+};
 
-typedef struct _pcm_channel_descriptor_t {
+struct dsp_pcm_channel_descriptor {
 	int active;
 	int src_slot;
 	int pcm_slot;
 	u32 sample_rate;
 	u32 unlinked;
-	dsp_scb_descriptor_t * pcm_reader_scb;
-	dsp_scb_descriptor_t * src_scb;
-	dsp_scb_descriptor_t * mixer_scb;
+	struct dsp_scb_descriptor * pcm_reader_scb;
+	struct dsp_scb_descriptor * src_scb;
+	struct dsp_scb_descriptor * mixer_scb;
 
 	void * private_data;
-} pcm_channel_descriptor_t;
+};
 
-typedef struct _dsp_spos_instance_t {
-	symbol_desc_t symbol_table; /* currently availble loaded symbols in SP */
+struct dsp_spos_instance {
+	struct dsp_symbol_desc symbol_table; /* currently availble loaded symbols in SP */
 
 	int nmodules;
-	dsp_module_desc_t * modules; /* modules loaded into SP */
+	struct dsp_module_desc * modules; /* modules loaded into SP */
 
-	segment_desc_t code;
+	struct dsp_segment_desc code;
 
 	/* Main PCM playback mixer */
-	dsp_scb_descriptor_t * master_mix_scb;
+	struct dsp_scb_descriptor * master_mix_scb;
 	u16 dac_volume_right;
 	u16 dac_volume_left;
 
 	/* Rear/surround PCM playback mixer */
-	dsp_scb_descriptor_t * rear_mix_scb;
+	struct dsp_scb_descriptor * rear_mix_scb;
 
 	/* Center/LFE mixer */
-	dsp_scb_descriptor_t * center_lfe_mix_scb;
+	struct dsp_scb_descriptor * center_lfe_mix_scb;
 
 	int npcm_channels;
 	int nsrc_scb;
-	pcm_channel_descriptor_t pcm_channels[DSP_MAX_PCM_CHANNELS];
+	struct dsp_pcm_channel_descriptor pcm_channels[DSP_MAX_PCM_CHANNELS];
 	int src_scb_slots[DSP_MAX_SRC_NR];
 
 	/* cache this symbols */
-	symbol_entry_t * null_algorithm; /* used by PCMreaderSCB's */
-	symbol_entry_t * s16_up;         /* used by SRCtaskSCB's */
+	struct dsp_symbol_entry * null_algorithm; /* used by PCMreaderSCB's */
+	struct dsp_symbol_entry * s16_up;         /* used by SRCtaskSCB's */
 
 	/* proc fs */  
-	snd_card_t * snd_card;
-	snd_info_entry_t * proc_dsp_dir;
-	snd_info_entry_t * proc_sym_info_entry;
-	snd_info_entry_t * proc_modules_info_entry;
-	snd_info_entry_t * proc_parameter_dump_info_entry;
-	snd_info_entry_t * proc_sample_dump_info_entry;
+	struct snd_card *snd_card;
+	struct snd_info_entry * proc_dsp_dir;
+	struct snd_info_entry * proc_sym_info_entry;
+	struct snd_info_entry * proc_modules_info_entry;
+	struct snd_info_entry * proc_parameter_dump_info_entry;
+	struct snd_info_entry * proc_sample_dump_info_entry;
 
 	/* SCB's descriptors */
 	int nscb;
 	int scb_highest_frag_index;
-	dsp_scb_descriptor_t scbs[DSP_MAX_SCB_DESC];
-	snd_info_entry_t * proc_scb_info_entry;
-	dsp_scb_descriptor_t * the_null_scb;
+	struct dsp_scb_descriptor scbs[DSP_MAX_SCB_DESC];
+	struct snd_info_entry * proc_scb_info_entry;
+	struct dsp_scb_descriptor * the_null_scb;
 
 	/* Task's descriptors */
 	int ntask;
-	dsp_task_descriptor_t tasks[DSP_MAX_TASK_DESC];
-	snd_info_entry_t * proc_task_info_entry;
+	struct dsp_task_descriptor tasks[DSP_MAX_TASK_DESC];
+	struct snd_info_entry * proc_task_info_entry;
 
 	/* SPDIF status */
 	int spdif_status_out;
@@ -204,30 +201,30 @@
 	unsigned int spdif_csuv_stream;
 
 	/* SPDIF input sample rate converter */
-	dsp_scb_descriptor_t * spdif_in_src;
+	struct dsp_scb_descriptor * spdif_in_src;
 	/* SPDIF input asynch. receiver */
-	dsp_scb_descriptor_t * asynch_rx_scb;
+	struct dsp_scb_descriptor * asynch_rx_scb;
 
 	/* Capture record mixer SCB */
-	dsp_scb_descriptor_t * record_mixer_scb;
+	struct dsp_scb_descriptor * record_mixer_scb;
     
 	/* CODEC input SCB */
-	dsp_scb_descriptor_t * codec_in_scb;
+	struct dsp_scb_descriptor * codec_in_scb;
 
 	/* reference snooper */
-	dsp_scb_descriptor_t * ref_snoop_scb;
+	struct dsp_scb_descriptor * ref_snoop_scb;
 
 	/* SPDIF output  PCM reference  */
-	dsp_scb_descriptor_t * spdif_pcm_input_scb;
+	struct dsp_scb_descriptor * spdif_pcm_input_scb;
 
 	/* asynch TX task */
-	dsp_scb_descriptor_t * asynch_tx_scb;
+	struct dsp_scb_descriptor * asynch_tx_scb;
 
 	/* record sources */
-	dsp_scb_descriptor_t * pcm_input;
-	dsp_scb_descriptor_t * adc_input;
+	struct dsp_scb_descriptor * pcm_input;
+	struct dsp_scb_descriptor * adc_input;
 
 	int spdif_in_sample_rate;
-} dsp_spos_instance_t;
+};
 
 #endif /* __DSP_SPOS_H__ */
diff --git a/include/sound/cs46xx_dsp_task_types.h b/include/sound/cs46xx_dsp_task_types.h
index 5dd3bf6..b3076c48 100644
--- a/include/sound/cs46xx_dsp_task_types.h
+++ b/include/sound/cs46xx_dsp_task_types.h
@@ -71,7 +71,7 @@
                                                at the end of BG */
 
 /* Minimal context save area for Hyper Forground */
-typedef struct _hf_save_area_t {
+struct dsp_hf_save_area {
 	u32	r10_save;
 	u32	r54_save;
 	u32	r98_save;
@@ -96,11 +96,11 @@
 	      rsa2Save
 	)
 	/* saved as part of HFG context  */
-} hf_save_area_t;
+};
 
 
 /* Task link data structure */
-typedef struct _tree_link_t {
+struct dsp_tree_link {
 	___DSP_DUAL_16BIT_ALLOC(
 	/* Pointer to sibling task control block */
 	    next_scb,
@@ -114,10 +114,10 @@
 	/* Pointer to local data */
 	    this_spb
 	)
-} tree_link_t;
+};
 
 
-typedef struct _task_tree_data_t {
+struct dsp_task_tree_data {
 	___DSP_DUAL_16BIT_ALLOC(
 	/* Initial tock count; controls task tree execution rate */
 	    tock_count_limit,
@@ -155,11 +155,10 @@
 	    data_stack_base_ptr
 	)
 
-} task_tree_data_t;
+};
 
 
-
-typedef struct _interval_timer_data_t
+struct dsp_interval_timer_data
 {
 	/* These data items have the same relative locations to those */
 	___DSP_DUAL_16BIT_ALLOC(
@@ -172,12 +171,12 @@
 	     num_FG_ticks_this_interval,        
 	     num_intervals
 	)
-} interval_timer_data_t;    
+};
 
 
 /* This structure contains extra storage for the task tree
    Currently, this additional data is related only to a full context save */
-typedef struct _task_tree_context_block_t {
+struct dsp_task_tree_context_block {
 	/* Up to 10 values are saved onto the stack.  8 for the task tree, 1 for
 	   The access to the context switch (call or interrupt), and 1 spare that
 	   users should never use.  This last may be required by the system */
@@ -238,16 +237,16 @@
 	u32		saveaux2xaux3x;
 	u32		savershouthl;
 	u32		savershoutxmacmode;
-} task_tree_context_block_t;						  
+};
                 
 
-typedef struct _task_tree_control_block_t	{
-	hf_save_area_t		 	context;
-	tree_link_t			links;
-	task_tree_data_t		data;
-	task_tree_context_block_t	context_blk;
-	interval_timer_data_t		int_timer;
-} task_tree_control_block_t;
+struct dsp_task_tree_control_block {
+	struct dsp_hf_save_area			context;
+	struct dsp_tree_link			links;
+	struct dsp_task_tree_data		data;
+	struct dsp_task_tree_context_block	context_blk;
+	struct dsp_interval_timer_data		int_timer;
+};
 
 
 #endif /* __DSP_TASK_TYPES_H__ */
diff --git a/include/sound/cs8403.h b/include/sound/cs8403.h
index 0b7d216..c6c3f9f 100644
--- a/include/sound/cs8403.h
+++ b/include/sound/cs8403.h
@@ -36,7 +36,7 @@
 #endif
 
 
-SND_CS8403_DECL void SND_CS8403_DECODE(snd_aes_iec958_t *diga, unsigned char bits)
+SND_CS8403_DECL void SND_CS8403_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
 {
 	if (bits & 0x01) {	/* consumer */
 		if (!(bits & 0x02))
@@ -79,7 +79,7 @@
 	}
 }
 
-SND_CS8403_DECL unsigned char SND_CS8403_ENCODE(snd_aes_iec958_t *diga)
+SND_CS8403_DECL unsigned char SND_CS8403_ENCODE(struct snd_aes_iec958 *diga)
 {
 	unsigned char bits;
 
@@ -166,7 +166,7 @@
 #endif
 
 
-SND_CS8404_DECL void SND_CS8404_DECODE(snd_aes_iec958_t *diga, unsigned char bits)
+SND_CS8404_DECL void SND_CS8404_DECODE(struct snd_aes_iec958 *diga, unsigned char bits)
 {
 	if (bits & 0x10) {	/* consumer */
 		if (!(bits & 0x20))
@@ -205,7 +205,7 @@
 	}
 }
 
-SND_CS8404_DECL unsigned char SND_CS8404_ENCODE(snd_aes_iec958_t *diga)
+SND_CS8404_DECL unsigned char SND_CS8404_ENCODE(struct snd_aes_iec958 *diga)
 {
 	unsigned char bits;
 
diff --git a/include/sound/cs8427.h b/include/sound/cs8427.h
index e725b70..97fd9ac 100644
--- a/include/sound/cs8427.h
+++ b/include/sound/cs8427.h
@@ -186,11 +186,16 @@
 #define CS8427_VERSHIFT		0
 #define CS8427_VER8427A		0x71
 
-int snd_cs8427_create(snd_i2c_bus_t *bus, unsigned char addr,
-		      unsigned int reset_timeout, snd_i2c_device_t **r_cs8427);
-int snd_cs8427_reg_write(snd_i2c_device_t *device, unsigned char reg, unsigned char val);
-int snd_cs8427_iec958_build(snd_i2c_device_t *cs8427, snd_pcm_substream_t *playback_substream, snd_pcm_substream_t *capture_substream);
-int snd_cs8427_iec958_active(snd_i2c_device_t *cs8427, int active);
-int snd_cs8427_iec958_pcm(snd_i2c_device_t *cs8427, unsigned int rate);
+struct snd_pcm_substream;
+
+int snd_cs8427_create(struct snd_i2c_bus *bus, unsigned char addr,
+		      unsigned int reset_timeout, struct snd_i2c_device **r_cs8427);
+int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
+			 unsigned char val);
+int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
+			    struct snd_pcm_substream *playback_substream,
+			    struct snd_pcm_substream *capture_substream);
+int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active);
+int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate);
 
 #endif /* __SOUND_CS8427_H */
diff --git a/include/sound/driver.h b/include/sound/driver.h
index 3f0416a..89c6a73 100644
--- a/include/sound/driver.h
+++ b/include/sound/driver.h
@@ -28,7 +28,12 @@
 
 #include <linux/config.h>
 
-#define SNDRV_CARDS		8	/* number of supported soundcards - don't change - minor numbers */
+/* number of supported soundcards */
+#ifdef CONFIG_SND_DYNAMIC_MINORS
+#define SNDRV_CARDS 32
+#else
+#define SNDRV_CARDS 8		/* don't change - minor numbers */
+#endif
 
 #ifndef CONFIG_SND_MAJOR	/* standard configuration */
 #define CONFIG_SND_MAJOR	116
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 8411c7e..951e40d 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -887,47 +887,45 @@
 
 /* ------------------- STRUCTURES -------------------- */
 
-typedef struct _snd_emu10k1 emu10k1_t;
-typedef struct _snd_emu10k1_voice emu10k1_voice_t;
-typedef struct _snd_emu10k1_pcm emu10k1_pcm_t;
-
-typedef enum {
+enum {
 	EMU10K1_EFX,
 	EMU10K1_PCM,
 	EMU10K1_SYNTH,
 	EMU10K1_MIDI
-} emu10k1_voice_type_t;
+};
 
-struct _snd_emu10k1_voice {
-	emu10k1_t *emu;
+struct snd_emu10k1;
+
+struct snd_emu10k1_voice {
+	struct snd_emu10k1 *emu;
 	int number;
 	unsigned int use: 1,
 	    pcm: 1,
 	    efx: 1,
 	    synth: 1,
 	    midi: 1;
-	void (*interrupt)(emu10k1_t *emu, emu10k1_voice_t *pvoice);
+	void (*interrupt)(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice);
 
-	emu10k1_pcm_t *epcm;
+	struct snd_emu10k1_pcm *epcm;
 };
 
-typedef enum {
+enum {
 	PLAYBACK_EMUVOICE,
 	PLAYBACK_EFX,
 	CAPTURE_AC97ADC,
 	CAPTURE_AC97MIC,
 	CAPTURE_EFX
-} snd_emu10k1_pcm_type_t;
+};
 
-struct _snd_emu10k1_pcm {
-	emu10k1_t *emu;
-	snd_emu10k1_pcm_type_t type;
-	snd_pcm_substream_t *substream;
-	emu10k1_voice_t *voices[NUM_EFX_PLAYBACK];
-	emu10k1_voice_t *extra;
+struct snd_emu10k1_pcm {
+	struct snd_emu10k1 *emu;
+	int type;
+	struct snd_pcm_substream *substream;
+	struct snd_emu10k1_voice *voices[NUM_EFX_PLAYBACK];
+	struct snd_emu10k1_voice *extra;
 	unsigned short running;
 	unsigned short first_ptr;
-	snd_util_memblk_t *memblk;
+	struct snd_util_memblk *memblk;
 	unsigned int start_addr;
 	unsigned int ccca_start_addr;
 	unsigned int capture_ipr;	/* interrupt acknowledge mask */
@@ -941,13 +939,13 @@
 	unsigned int capture_bufsize;	/* buffer size in bytes */
 };
 
-typedef struct {
+struct snd_emu10k1_pcm_mixer {
 	/* mono, left, right x 8 sends (4 on emu10k1) */
 	unsigned char send_routing[3][8];
 	unsigned char send_volume[3][8];
 	unsigned short attn[3];
-	emu10k1_pcm_t *epcm;
-} emu10k1_pcm_mixer_t;
+	struct snd_emu10k1_pcm *epcm;
+};
 
 #define snd_emu10k1_compose_send_routing(route) \
 ((route[0] | (route[1] << 4) | (route[2] << 8) | (route[3] << 12)) << 16)
@@ -958,20 +956,20 @@
 #define snd_emu10k1_compose_audigy_fxrt2(route) \
 ((unsigned int)route[4] | ((unsigned int)route[5] << 8) | ((unsigned int)route[6] << 16) | ((unsigned int)route[7] << 24))
 
-typedef struct snd_emu10k1_memblk {
-	snd_util_memblk_t mem;
+struct snd_emu10k1_memblk {
+	struct snd_util_memblk mem;
 	/* private part */
 	int first_page, last_page, pages, mapped_page;
 	unsigned int map_locked;
 	struct list_head mapped_link;
 	struct list_head mapped_order_link;
-} emu10k1_memblk_t;
+};
 
 #define snd_emu10k1_memblk_offset(blk)	(((blk)->mapped_page << PAGE_SHIFT) | ((blk)->mem.offset & (PAGE_SIZE - 1)))
 
 #define EMU10K1_MAX_TRAM_BLOCKS_PER_CODE	16
 
-typedef struct {
+struct snd_emu10k1_fx8010_ctl {
 	struct list_head list;		/* list link container */
 	unsigned int vcount;
 	unsigned int count;		/* count of GPR (1..16) */
@@ -980,19 +978,19 @@
 	unsigned int min;		/* minimum range */
 	unsigned int max;		/* maximum range */
 	unsigned int translation;	/* translation type (EMU10K1_GPR_TRANSLATION*) */
-	snd_kcontrol_t *kcontrol;
-} snd_emu10k1_fx8010_ctl_t;
+	struct snd_kcontrol *kcontrol;
+};
 
-typedef void (snd_fx8010_irq_handler_t)(emu10k1_t *emu, void *private_data);
+typedef void (snd_fx8010_irq_handler_t)(struct snd_emu10k1 *emu, void *private_data);
 
-typedef struct _snd_emu10k1_fx8010_irq {
-	struct _snd_emu10k1_fx8010_irq *next;
+struct snd_emu10k1_fx8010_irq {
+	struct snd_emu10k1_fx8010_irq *next;
 	snd_fx8010_irq_handler_t *handler;
 	unsigned short gpr_running;
 	void *private_data;
-} snd_emu10k1_fx8010_irq_t;
+};
 
-typedef struct {
+struct snd_emu10k1_fx8010_pcm {
 	unsigned int valid: 1,
 		     opened: 1,
 		     active: 1;
@@ -1006,13 +1004,13 @@
 	unsigned short gpr_trigger;	/* GPR containing trigger (activate) information (host) */
 	unsigned short gpr_running;	/* GPR containing info if PCM is running (FX8010) */
 	unsigned char etram[32];	/* external TRAM address & data */
-	snd_pcm_indirect_t pcm_rec;
+	struct snd_pcm_indirect pcm_rec;
 	unsigned int tram_pos;
 	unsigned int tram_shift;
-	snd_emu10k1_fx8010_irq_t *irq;
-} snd_emu10k1_fx8010_pcm_t;
+	struct snd_emu10k1_fx8010_irq *irq;
+};
 
-typedef struct {
+struct snd_emu10k1_fx8010 {
 	unsigned short fxbus_mask;	/* used FX buses (bitmask) */
 	unsigned short extin_mask;	/* used external inputs (bitmask) */
 	unsigned short extout_mask;	/* used external outputs (bitmask) */
@@ -1025,18 +1023,18 @@
 	int gpr_count;			/* count of used kcontrols */
 	struct list_head gpr_ctl;	/* GPR controls */
 	struct semaphore lock;
-	snd_emu10k1_fx8010_pcm_t pcm[8];
+	struct snd_emu10k1_fx8010_pcm pcm[8];
 	spinlock_t irq_lock;
-	snd_emu10k1_fx8010_irq_t *irq_handlers;
-} snd_emu10k1_fx8010_t;
+	struct snd_emu10k1_fx8010_irq *irq_handlers;
+};
 
-#define emu10k1_gpr_ctl(n) list_entry(n, snd_emu10k1_fx8010_ctl_t, list)
+#define emu10k1_gpr_ctl(n) list_entry(n, struct snd_emu10k1_fx8010_ctl, list)
 
-typedef struct {
-	struct _snd_emu10k1 *emu;
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *substream_input;
-	snd_rawmidi_substream_t *substream_output;
+struct snd_emu10k1_midi {
+	struct snd_emu10k1 *emu;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *substream_input;
+	struct snd_rawmidi_substream *substream_output;
 	unsigned int midi_mode;
 	spinlock_t input_lock;
 	spinlock_t output_lock;
@@ -1044,10 +1042,10 @@
 	int tx_enable, rx_enable;
 	int port;
 	int ipr_tx, ipr_rx;
-	void (*interrupt)(emu10k1_t *emu, unsigned int status);
-} emu10k1_midi_t;
+	void (*interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+};
 
-typedef struct {
+struct snd_emu_chip_details {
 	u32 vendor;
 	u32 device;
 	u32 subsystem;
@@ -1063,18 +1061,23 @@
 	unsigned char spdif_bug;    /* Has Spdif phasing bug */
 	unsigned char ac97_chip;    /* Has an AC97 chip: 1 = mandatory, 2 = optional */
 	unsigned char ecard;        /* APS EEPROM */
+	unsigned char emu1212m;     /* EMU 1212m card */
+	unsigned char spi_dac;      /* SPI interface for DAC */
+	unsigned char i2c_adc;      /* I2C interface for ADC */
 	const char *driver;
 	const char *name;
 	const char *id;		/* for backward compatibility - can be NULL if not needed */
-} emu_chip_details_t;
+};
 
-struct _snd_emu10k1 {
+struct snd_emu10k1 {
 	int irq;
 
 	unsigned long port;			/* I/O port number */
 	unsigned int tos_link: 1,		/* tos link detected */
-	    rear_ac97: 1;			/* rear channels are on AC'97 */
-	const emu_chip_details_t *card_capabilities;	/* Contains profile of card capabilities */
+		rear_ac97: 1,			/* rear channels are on AC'97 */
+		enable_ir: 1;
+	/* Contains profile of card capabilities */
+	const struct snd_emu_chip_details *card_capabilities;
 	unsigned int audigy;			/* is Audigy? */
 	unsigned int revision;			/* chip revision */
 	unsigned int serial;			/* serial number */
@@ -1088,8 +1091,8 @@
 	struct snd_dma_device p16v_dma_dev;
 	struct snd_dma_buffer p16v_buffer;
 
-	snd_util_memhdr_t *memhdr;		/* page allocation list */
-	emu10k1_memblk_t *reserved_page;	/* reserved page */
+	struct snd_util_memhdr *memhdr;		/* page allocation list */
+	struct snd_emu10k1_memblk *reserved_page;	/* reserved page */
 
 	struct list_head mapped_link_head;
 	struct list_head mapped_order_link_head;
@@ -1099,142 +1102,169 @@
 
 	unsigned int spdif_bits[3];		/* s/pdif out setup */
 
-	snd_emu10k1_fx8010_t fx8010;		/* FX8010 info */
+	struct snd_emu10k1_fx8010 fx8010;		/* FX8010 info */
 	int gpr_base;
 	
-	ac97_t *ac97;
+	struct snd_ac97 *ac97;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_t *pcm_mic;
-	snd_pcm_t *pcm_efx;
-	snd_pcm_t *pcm_p16v;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm *pcm_mic;
+	struct snd_pcm *pcm_efx;
+	struct snd_pcm *pcm_multi;
+	struct snd_pcm *pcm_p16v;
 
 	spinlock_t synth_lock;
 	void *synth;
-	int (*get_synth_voice)(emu10k1_t *emu);
+	int (*get_synth_voice)(struct snd_emu10k1 *emu);
 
 	spinlock_t reg_lock;
 	spinlock_t emu_lock;
 	spinlock_t voice_lock;
 	struct semaphore ptb_lock;
 
-	emu10k1_voice_t voices[NUM_G];
-	emu10k1_voice_t p16v_voices[4];
-	emu10k1_voice_t p16v_capture_voice;
+	struct snd_emu10k1_voice voices[NUM_G];
+	struct snd_emu10k1_voice p16v_voices[4];
+	struct snd_emu10k1_voice p16v_capture_voice;
 	int p16v_device_offset;
 	u32 p16v_capture_source;
 	u32 p16v_capture_channel;
-	emu10k1_pcm_mixer_t pcm_mixer[32];
-	emu10k1_pcm_mixer_t efx_pcm_mixer[NUM_EFX_PLAYBACK];
-	snd_kcontrol_t *ctl_send_routing;
-	snd_kcontrol_t *ctl_send_volume;
-	snd_kcontrol_t *ctl_attn;
-	snd_kcontrol_t *ctl_efx_send_routing;
-	snd_kcontrol_t *ctl_efx_send_volume;
-	snd_kcontrol_t *ctl_efx_attn;
+	struct snd_emu10k1_pcm_mixer pcm_mixer[32];
+	struct snd_emu10k1_pcm_mixer efx_pcm_mixer[NUM_EFX_PLAYBACK];
+	struct snd_kcontrol *ctl_send_routing;
+	struct snd_kcontrol *ctl_send_volume;
+	struct snd_kcontrol *ctl_attn;
+	struct snd_kcontrol *ctl_efx_send_routing;
+	struct snd_kcontrol *ctl_efx_send_volume;
+	struct snd_kcontrol *ctl_efx_attn;
 
-	void (*hwvol_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*capture_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*capture_mic_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*capture_efx_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*spdif_interrupt)(emu10k1_t *emu, unsigned int status);
-	void (*dsp_interrupt)(emu10k1_t *emu);
+	void (*hwvol_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*capture_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*capture_mic_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*capture_efx_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*spdif_interrupt)(struct snd_emu10k1 *emu, unsigned int status);
+	void (*dsp_interrupt)(struct snd_emu10k1 *emu);
 
-	snd_pcm_substream_t *pcm_capture_substream;
-	snd_pcm_substream_t *pcm_capture_mic_substream;
-	snd_pcm_substream_t *pcm_capture_efx_substream;
-	snd_pcm_substream_t *pcm_playback_efx_substream;
+	struct snd_pcm_substream *pcm_capture_substream;
+	struct snd_pcm_substream *pcm_capture_mic_substream;
+	struct snd_pcm_substream *pcm_capture_efx_substream;
+	struct snd_pcm_substream *pcm_playback_efx_substream;
 
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 
-	emu10k1_midi_t midi;
-	emu10k1_midi_t midi2; /* for audigy */
+	struct snd_emu10k1_midi midi;
+	struct snd_emu10k1_midi midi2; /* for audigy */
 
 	unsigned int efx_voices_mask[2];
 	unsigned int next_free_voice;
+
+#ifdef CONFIG_PM
+	unsigned int *saved_ptr;
+	unsigned int *saved_gpr;
+	unsigned int *tram_val_saved;
+	unsigned int *tram_addr_saved;
+	unsigned int *saved_icode;
+	unsigned int *p16v_saved;
+	unsigned int saved_a_iocfg, saved_hcfg;
+#endif
+
 };
 
-int snd_emu10k1_create(snd_card_t * card,
+int snd_emu10k1_create(struct snd_card *card,
 		       struct pci_dev *pci,
 		       unsigned short extin_mask,
 		       unsigned short extout_mask,
 		       long max_cache_bytes,
 		       int enable_ir,
 		       uint subsystem,
-		       emu10k1_t ** remu);
+		       struct snd_emu10k1 ** remu);
 
-int snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_p16v_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_p16v_free(emu10k1_t * emu);
-int snd_p16v_mixer(emu10k1_t * emu);
-int snd_emu10k1_pcm_multi(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_emu10k1_fx8010_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm);
-int snd_emu10k1_mixer(emu10k1_t * emu, int pcm_device, int multi_device);
-int snd_emu10k1_timer(emu10k1_t * emu, int device);
-int snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep);
+int snd_emu10k1_pcm(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
+int snd_emu10k1_pcm_mic(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
+int snd_emu10k1_pcm_efx(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
+int snd_p16v_pcm(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
+int snd_p16v_free(struct snd_emu10k1 * emu);
+int snd_p16v_mixer(struct snd_emu10k1 * emu);
+int snd_emu10k1_pcm_multi(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
+int snd_emu10k1_fx8010_pcm(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm);
+int snd_emu10k1_mixer(struct snd_emu10k1 * emu, int pcm_device, int multi_device);
+int snd_emu10k1_timer(struct snd_emu10k1 * emu, int device);
+int snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep);
 
 irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
-/* initialization */
-void snd_emu10k1_voice_init(emu10k1_t * emu, int voice);
-int snd_emu10k1_init_efx(emu10k1_t *emu);
-void snd_emu10k1_free_efx(emu10k1_t *emu);
-int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size);
+void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int voice);
+int snd_emu10k1_init_efx(struct snd_emu10k1 *emu);
+void snd_emu10k1_free_efx(struct snd_emu10k1 *emu);
+int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size);
+int snd_emu10k1_done(struct snd_emu10k1 * emu);
 
 /* I/O functions */
-unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
-void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
-unsigned int snd_emu10k1_ptr20_read(emu10k1_t * emu, unsigned int reg, unsigned int chn);
-void snd_emu10k1_ptr20_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data);
-unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc);
-void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb);
-void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb);
-void snd_emu10k1_voice_intr_enable(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_intr_disable(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_intr_ack(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_half_loop_intr_enable(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_half_loop_intr_disable(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_half_loop_intr_ack(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_set_loop_stop(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_voice_clear_loop_stop(emu10k1_t *emu, unsigned int voicenum);
-void snd_emu10k1_wait(emu10k1_t *emu, unsigned int wait);
-static inline unsigned int snd_emu10k1_wc(emu10k1_t *emu) { return (inl(emu->port + WC) >> 6) & 0xfffff; }
-unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg);
-void snd_emu10k1_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short data);
+unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn);
+void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
+unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn);
+void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data);
+int snd_emu10k1_spi_write(struct snd_emu10k1 * emu, unsigned int data);
+unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc);
+void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb);
+void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb);
+void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum);
+void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait);
+static inline unsigned int snd_emu10k1_wc(struct snd_emu10k1 *emu) { return (inl(emu->port + WC) >> 6) & 0xfffff; }
+unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg);
+void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data);
 unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
 
+#ifdef CONFIG_PM
+void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu);
+void snd_emu10k1_resume_init(struct snd_emu10k1 *emu);
+void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu);
+int snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu);
+void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu);
+void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu);
+void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu);
+int snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu);
+void snd_p16v_free_pm_buffer(struct snd_emu10k1 *emu);
+void snd_p16v_suspend(struct snd_emu10k1 *emu);
+void snd_p16v_resume(struct snd_emu10k1 *emu);
+#endif
+
 /* memory allocation */
-snd_util_memblk_t *snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream);
-int snd_emu10k1_free_pages(emu10k1_t *emu, snd_util_memblk_t *blk);
-snd_util_memblk_t *snd_emu10k1_synth_alloc(emu10k1_t *emu, unsigned int size);
-int snd_emu10k1_synth_free(emu10k1_t *emu, snd_util_memblk_t *blk);
-int snd_emu10k1_synth_bzero(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, int size);
-int snd_emu10k1_synth_copy_from_user(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, const char __user *data, int size);
-int snd_emu10k1_memblk_map(emu10k1_t *emu, emu10k1_memblk_t *blk);
+struct snd_util_memblk *snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream);
+int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk);
+struct snd_util_memblk *snd_emu10k1_synth_alloc(struct snd_emu10k1 *emu, unsigned int size);
+int snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *blk);
+int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk, int offset, int size);
+int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_memblk *blk, int offset, const char __user *data, int size);
+int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk);
 
 /* voice allocation */
-int snd_emu10k1_voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int pair, emu10k1_voice_t **rvoice);
-int snd_emu10k1_voice_free(emu10k1_t *emu, emu10k1_voice_t *pvoice);
+int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int pair, struct snd_emu10k1_voice **rvoice);
+int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *pvoice);
 
 /* MIDI uart */
-int snd_emu10k1_midi(emu10k1_t * emu);
-int snd_emu10k1_audigy_midi(emu10k1_t * emu);
+int snd_emu10k1_midi(struct snd_emu10k1 * emu);
+int snd_emu10k1_audigy_midi(struct snd_emu10k1 * emu);
 
 /* proc interface */
-int snd_emu10k1_proc_init(emu10k1_t * emu);
+int snd_emu10k1_proc_init(struct snd_emu10k1 * emu);
 
 /* fx8010 irq handler */
-int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
+int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
 					    snd_fx8010_irq_handler_t *handler,
 					    unsigned char gpr_running,
 					    void *private_data,
-					    snd_emu10k1_fx8010_irq_t **r_irq);
-int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
-					      snd_emu10k1_fx8010_irq_t *irq);
+					    struct snd_emu10k1_fx8010_irq **r_irq);
+int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
+					      struct snd_emu10k1_fx8010_irq *irq);
 
 #endif /* __KERNEL__ */
 
@@ -1469,14 +1499,14 @@
 #define TANKMEMADDRREG_READ	 0x00100000	/* Read from tank memory			*/
 #endif
 
-typedef struct {
+struct snd_emu10k1_fx8010_info {
 	unsigned int internal_tram_size;	/* in samples */
 	unsigned int external_tram_size;	/* in samples */
 	char fxbus_names[16][32];		/* names of FXBUSes */
 	char extin_names[16][32];		/* names of external inputs */
 	char extout_names[32][32];		/* names of external outputs */
 	unsigned int gpr_controls;		/* count of GPR controls */
-} emu10k1_fx8010_info_t;
+};
 
 #define EMU10K1_GPR_TRANSLATION_NONE		0
 #define EMU10K1_GPR_TRANSLATION_TABLE100	1
@@ -1484,8 +1514,8 @@
 #define EMU10K1_GPR_TRANSLATION_TREBLE		3
 #define EMU10K1_GPR_TRANSLATION_ONOFF		4
 
-typedef struct {
-	snd_ctl_elem_id_t id;		/* full control ID definition */
+struct snd_emu10k1_fx8010_control_gpr {
+	struct snd_ctl_elem_id id;		/* full control ID definition */
 	unsigned int vcount;		/* visible count */
 	unsigned int count;		/* count of GPR (1..16) */
 	unsigned short gpr[32];		/* GPR number(s) */
@@ -1493,23 +1523,23 @@
 	unsigned int min;		/* minimum range */
 	unsigned int max;		/* maximum range */
 	unsigned int translation;	/* translation type (EMU10K1_GPR_TRANSLATION*) */
-} emu10k1_fx8010_control_gpr_t;
+};
 
-typedef struct {
+struct snd_emu10k1_fx8010_code {
 	char name[128];
 
 	DECLARE_BITMAP(gpr_valid, 0x200); /* bitmask of valid initializers */
 	u_int32_t __user *gpr_map;	  /* initializers */
 
 	unsigned int gpr_add_control_count; /* count of GPR controls to add/replace */
-	emu10k1_fx8010_control_gpr_t __user *gpr_add_controls; /* GPR controls to add/replace */
+	struct snd_emu10k1_fx8010_control_gpr __user *gpr_add_controls; /* GPR controls to add/replace */
 
 	unsigned int gpr_del_control_count; /* count of GPR controls to remove */
-	snd_ctl_elem_id_t __user *gpr_del_controls; /* IDs of GPR controls to remove */
+	struct snd_ctl_elem_id __user *gpr_del_controls; /* IDs of GPR controls to remove */
 
 	unsigned int gpr_list_control_count; /* count of GPR controls to list */
 	unsigned int gpr_list_control_total; /* total count of GPR controls */
-	emu10k1_fx8010_control_gpr_t __user *gpr_list_controls; /* listed GPR controls */
+	struct snd_emu10k1_fx8010_control_gpr __user *gpr_list_controls; /* listed GPR controls */
 
 	DECLARE_BITMAP(tram_valid, 0x100); /* bitmask of valid initializers */
 	u_int32_t __user *tram_data_map;  /* data initializers */
@@ -1517,16 +1547,16 @@
 
 	DECLARE_BITMAP(code_valid, 1024); /* bitmask of valid instructions */
 	u_int32_t __user *code;		  /* one instruction - 64 bits */
-} emu10k1_fx8010_code_t;
+};
 
-typedef struct {
+struct snd_emu10k1_fx8010_tram {
 	unsigned int address;		/* 31.bit == 1 -> external TRAM */
 	unsigned int size;		/* size in samples (4 bytes) */
 	unsigned int *samples;		/* pointer to samples (20-bit) */
 					/* NULL->clear memory */
-} emu10k1_fx8010_tram_t;
+};
 
-typedef struct {
+struct snd_emu10k1_fx8010_pcm_rec {
 	unsigned int substream;		/* substream number */
 	unsigned int res1;		/* reserved */
 	unsigned int channels;		/* 16-bit channels count, zero = remove this substream */
@@ -1541,20 +1571,27 @@
 	unsigned char pad;		/* reserved */
 	unsigned char etram[32];	/* external TRAM address & data (one per channel) */
 	unsigned int res2;		/* reserved */
-} emu10k1_fx8010_pcm_t;
+};
 
-#define SNDRV_EMU10K1_IOCTL_INFO	_IOR ('H', 0x10, emu10k1_fx8010_info_t)
-#define SNDRV_EMU10K1_IOCTL_CODE_POKE	_IOW ('H', 0x11, emu10k1_fx8010_code_t)
-#define SNDRV_EMU10K1_IOCTL_CODE_PEEK	_IOWR('H', 0x12, emu10k1_fx8010_code_t)
+#define SNDRV_EMU10K1_IOCTL_INFO	_IOR ('H', 0x10, struct snd_emu10k1_fx8010_info)
+#define SNDRV_EMU10K1_IOCTL_CODE_POKE	_IOW ('H', 0x11, struct snd_emu10k1_fx8010_code)
+#define SNDRV_EMU10K1_IOCTL_CODE_PEEK	_IOWR('H', 0x12, struct snd_emu10k1_fx8010_code)
 #define SNDRV_EMU10K1_IOCTL_TRAM_SETUP	_IOW ('H', 0x20, int)
-#define SNDRV_EMU10K1_IOCTL_TRAM_POKE	_IOW ('H', 0x21, emu10k1_fx8010_tram_t)
-#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK	_IOWR('H', 0x22, emu10k1_fx8010_tram_t)
-#define SNDRV_EMU10K1_IOCTL_PCM_POKE	_IOW ('H', 0x30, emu10k1_fx8010_pcm_t)
-#define SNDRV_EMU10K1_IOCTL_PCM_PEEK	_IOWR('H', 0x31, emu10k1_fx8010_pcm_t)
+#define SNDRV_EMU10K1_IOCTL_TRAM_POKE	_IOW ('H', 0x21, struct snd_emu10k1_fx8010_tram)
+#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK	_IOWR('H', 0x22, struct snd_emu10k1_fx8010_tram)
+#define SNDRV_EMU10K1_IOCTL_PCM_POKE	_IOW ('H', 0x30, struct snd_emu10k1_fx8010_pcm_rec)
+#define SNDRV_EMU10K1_IOCTL_PCM_PEEK	_IOWR('H', 0x31, struct snd_emu10k1_fx8010_pcm_rec)
 #define SNDRV_EMU10K1_IOCTL_STOP	_IO  ('H', 0x80)
 #define SNDRV_EMU10K1_IOCTL_CONTINUE	_IO  ('H', 0x81)
 #define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
 #define SNDRV_EMU10K1_IOCTL_SINGLE_STEP	_IOW ('H', 0x83, int)
 #define SNDRV_EMU10K1_IOCTL_DBG_READ	_IOR ('H', 0x84, int)
 
+/* typedefs for compatibility to user-space */
+typedef struct snd_emu10k1_fx8010_info emu10k1_fx8010_info_t;
+typedef struct snd_emu10k1_fx8010_control_gpr emu10k1_fx8010_control_gpr_t;
+typedef struct snd_emu10k1_fx8010_code emu10k1_fx8010_code_t;
+typedef struct snd_emu10k1_fx8010_tram emu10k1_fx8010_tram_t;
+typedef struct snd_emu10k1_fx8010_pcm_rec emu10k1_fx8010_pcm_t;
+
 #endif	/* __SOUND_EMU10K1_H */
diff --git a/include/sound/emu10k1_synth.h b/include/sound/emu10k1_synth.h
index df0df1d..6ef61c4 100644
--- a/include/sound/emu10k1_synth.h
+++ b/include/sound/emu10k1_synth.h
@@ -27,12 +27,12 @@
 #define SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH	"emu10k1-synth"
 
 /* argument for snd_seq_device_new */
-typedef struct snd_emu10k1_synth_arg {
-	emu10k1_t *hwptr;	/* chip */
+struct snd_emu10k1_synth_arg {
+	struct snd_emu10k1 *hwptr;	/* chip */
 	int index;		/* sequencer client index */
 	int seq_ports;		/* number of sequencer ports to be created */
 	int max_voices;		/* maximum number of voices for wavetable */
-} snd_emu10k1_synth_arg_t;
+};
 
 #define EMU10K1_MAX_MEMSIZE	(32 * 1024 * 1024) /* 32MB */
 
diff --git a/include/sound/emu8000.h b/include/sound/emu8000.h
index 4362c54..c8f66bd 100644
--- a/include/sound/emu8000.h
+++ b/include/sound/emu8000.h
@@ -56,9 +56,9 @@
  * some of the channels may be used for other things so max_channels is
  * the number in use for wave voices.
  */
-typedef struct snd_emu8000 {
+struct snd_emu8000 {
 
-	snd_emux_t *emu;
+	struct snd_emux *emu;
 
 	int index;		/* sequencer client index */
 	int seq_ports;		/* number of sequencer ports */
@@ -77,44 +77,45 @@
 
 	int dram_checked;
 
-	snd_card_t *card;		/* The card that this belongs to */
+	struct snd_card *card;		/* The card that this belongs to */
 
 	int chorus_mode;
 	int reverb_mode;
 	int bass_level;
 	int treble_level;
 
-	snd_util_memhdr_t *memhdr;
+	struct snd_util_memhdr *memhdr;
 
 	spinlock_t control_lock;
-	snd_kcontrol_t *controls[EMU8000_NUM_CONTROLS];
+	struct snd_kcontrol *controls[EMU8000_NUM_CONTROLS];
 
-	snd_pcm_t *pcm; /* pcm on emu8000 wavetable */
+	struct snd_pcm *pcm; /* pcm on emu8000 wavetable */
 
-} emu8000_t;
+};
 
 /* sequencer device id */
 #define SNDRV_SEQ_DEV_ID_EMU8000	"emu8000-synth"
 
 
 /* exported functions */
-int snd_emu8000_new(snd_card_t *card, int device, long port, int seq_ports, snd_seq_device_t **ret);
-void snd_emu8000_poke(emu8000_t *emu, unsigned int port, unsigned int reg,
+int snd_emu8000_new(struct snd_card *card, int device, long port, int seq_ports,
+		    struct snd_seq_device **ret);
+void snd_emu8000_poke(struct snd_emu8000 *emu, unsigned int port, unsigned int reg,
 		      unsigned int val);
-unsigned short snd_emu8000_peek(emu8000_t *emu, unsigned int port,
+unsigned short snd_emu8000_peek(struct snd_emu8000 *emu, unsigned int port,
 				unsigned int reg);
-void snd_emu8000_poke_dw(emu8000_t *emu, unsigned int port, unsigned int reg,
+void snd_emu8000_poke_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg,
 			 unsigned int val);
-unsigned int snd_emu8000_peek_dw(emu8000_t *emu, unsigned int port,
+unsigned int snd_emu8000_peek_dw(struct snd_emu8000 *emu, unsigned int port,
 				 unsigned int reg);
-void snd_emu8000_dma_chan(emu8000_t *emu, int ch, int mode);
+void snd_emu8000_dma_chan(struct snd_emu8000 *emu, int ch, int mode);
 
-void snd_emu8000_init_fm(emu8000_t *emu);
+void snd_emu8000_init_fm(struct snd_emu8000 *emu);
 
-void snd_emu8000_update_chorus_mode(emu8000_t *emu);
-void snd_emu8000_update_reverb_mode(emu8000_t *emu);
-void snd_emu8000_update_equalizer(emu8000_t *emu);
-int snd_emu8000_load_chorus_fx(emu8000_t *emu, int mode, const void __user *buf, long len);
-int snd_emu8000_load_reverb_fx(emu8000_t *emu, int mode, const void __user *buf, long len);
+void snd_emu8000_update_chorus_mode(struct snd_emu8000 *emu);
+void snd_emu8000_update_reverb_mode(struct snd_emu8000 *emu);
+void snd_emu8000_update_equalizer(struct snd_emu8000 *emu);
+int snd_emu8000_load_chorus_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len);
+int snd_emu8000_load_reverb_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len);
 
 #endif /* __SOUND_EMU8000_H */
diff --git a/include/sound/emux_synth.h b/include/sound/emux_synth.h
index c6970aa..b2d6b2a 100644
--- a/include/sound/emux_synth.h
+++ b/include/sound/emux_synth.h
@@ -36,39 +36,40 @@
  */
 #define SNDRV_EMUX_USE_RAW_EFFECT
 
-
-/*
- * typedefs
- */
-typedef struct snd_emux_effect_table snd_emux_effect_table_t;
-typedef struct snd_emux_port snd_emux_port_t;
-typedef struct snd_emux_voice snd_emux_voice_t;
-typedef struct snd_emux snd_emux_t;
-
+struct snd_emux;
+struct snd_emux_port;
+struct snd_emux_voice;
+struct snd_emux_effect_table;
 
 /*
  * operators
  */
-typedef struct snd_emux_operators {
+struct snd_emux_operators {
 	struct module *owner;
-	snd_emux_voice_t *(*get_voice)(snd_emux_t *emu, snd_emux_port_t *port);
-	int (*prepare)(snd_emux_voice_t *vp);
-	void (*trigger)(snd_emux_voice_t *vp);
-	void (*release)(snd_emux_voice_t *vp);
-	void (*update)(snd_emux_voice_t *vp, int update);
-	void (*terminate)(snd_emux_voice_t *vp);
-	void (*free_voice)(snd_emux_voice_t *vp);
-	void (*reset)(snd_emux_t *emu, int ch);
-	/* the first parameters are snd_emux_t */
-	int (*sample_new)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void __user *data, long count);
-	int (*sample_free)(snd_emux_t *emu, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr);
-	void (*sample_reset)(snd_emux_t *emu);
-	int (*load_fx)(snd_emux_t *emu, int type, int arg, const void __user *data, long count);
-	void (*sysex)(snd_emux_t *emu, char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
+	struct snd_emux_voice *(*get_voice)(struct snd_emux *emu,
+					    struct snd_emux_port *port);
+	int (*prepare)(struct snd_emux_voice *vp);
+	void (*trigger)(struct snd_emux_voice *vp);
+	void (*release)(struct snd_emux_voice *vp);
+	void (*update)(struct snd_emux_voice *vp, int update);
+	void (*terminate)(struct snd_emux_voice *vp);
+	void (*free_voice)(struct snd_emux_voice *vp);
+	void (*reset)(struct snd_emux *emu, int ch);
+	/* the first parameters are struct snd_emux */
+	int (*sample_new)(struct snd_emux *emu, struct snd_sf_sample *sp,
+			  struct snd_util_memhdr *hdr,
+			  const void __user *data, long count);
+	int (*sample_free)(struct snd_emux *emu, struct snd_sf_sample *sp,
+			   struct snd_util_memhdr *hdr);
+	void (*sample_reset)(struct snd_emux *emu);
+	int (*load_fx)(struct snd_emux *emu, int type, int arg,
+		       const void __user *data, long count);
+	void (*sysex)(struct snd_emux *emu, char *buf, int len, int parsed,
+		      struct snd_midi_channel_set *chset);
 #ifdef CONFIG_SND_SEQUENCER_OSS
-	int (*oss_ioctl)(snd_emux_t *emu, int cmd, int p1, int p2);
+	int (*oss_ioctl)(struct snd_emux *emu, int cmd, int p1, int p2);
 #endif
-} snd_emux_operators_t;
+};
 
 
 /*
@@ -90,46 +91,46 @@
  */
 struct snd_emux {
 
-	snd_card_t *card;	/* assigned card */
+	struct snd_card *card;	/* assigned card */
 
 	/* following should be initialized before registration */
 	int max_voices;		/* Number of voices */
 	int mem_size;		/* memory size (in byte) */
 	int num_ports;		/* number of ports to be created */
 	int pitch_shift;	/* pitch shift value (for Emu10k1) */
-	snd_emux_operators_t ops;	/* operators */
+	struct snd_emux_operators ops;	/* operators */
 	void *hw;		/* hardware */
 	unsigned long flags;	/* other conditions */
 	int midi_ports;		/* number of virtual midi devices */
 	int midi_devidx;	/* device offset of virtual midi */
 	unsigned int linear_panning: 1; /* panning is linear (sbawe = 1, emu10k1 = 0) */
 	int hwdep_idx;		/* hwdep device index */
-	snd_hwdep_t *hwdep;	/* hwdep device */
+	struct snd_hwdep *hwdep;	/* hwdep device */
 
 	/* private */
 	int num_voices;		/* current number of voices */
-	snd_sf_list_t *sflist;	/* root of SoundFont list */
-	snd_emux_voice_t *voices;	/* Voices (EMU 'channel') */
+	struct snd_sf_list *sflist;	/* root of SoundFont list */
+	struct snd_emux_voice *voices;	/* Voices (EMU 'channel') */
 	int use_time;	/* allocation counter */
 	spinlock_t voice_lock;	/* Lock for voice access */
 	struct semaphore register_mutex;
 	int client;		/* For the sequencer client */
 	int ports[SNDRV_EMUX_MAX_PORTS];	/* The ports for this device */
-	snd_emux_port_t *portptrs[SNDRV_EMUX_MAX_PORTS];
+	struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS];
 	int used;	/* use counter */
 	char *name;	/* name of the device (internal) */
-	snd_rawmidi_t **vmidi;
+	struct snd_rawmidi **vmidi;
 	struct timer_list tlist;	/* for pending note-offs */
 	int timer_active;
 
-	snd_util_memhdr_t *memhdr;	/* memory chunk information */
+	struct snd_util_memhdr *memhdr;	/* memory chunk information */
 
 #ifdef CONFIG_PROC_FS
-	snd_info_entry_t *proc;
+	struct snd_info_entry *proc;
 #endif
 
 #ifdef CONFIG_SND_SEQUENCER_OSS
-	snd_seq_device_t *oss_synth;
+	struct snd_seq_device *oss_synth;
 #endif
 };
 
@@ -139,18 +140,18 @@
  */
 struct snd_emux_port {
 
-	snd_midi_channel_set_t chset;
-	snd_emux_t *emu;
+	struct snd_midi_channel_set chset;
+	struct snd_emux *emu;
 
 	char port_mode;			/* operation mode */
 	int volume_atten;		/* emuX raw attenuation */
 	unsigned long drum_flags;	/* drum bitmaps */
 	int ctrls[EMUX_MD_END];		/* control parameters */
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
-	snd_emux_effect_table_t *effect;
+	struct snd_emux_effect_table *effect;
 #endif
 #ifdef CONFIG_SND_SEQUENCER_OSS
-	snd_seq_oss_arg_t *oss_arg;
+	struct snd_seq_oss_arg *oss_arg;
 #endif
 };
 
@@ -179,16 +180,16 @@
 	unsigned char key;
 	unsigned char velocity;	/* Velocity of current note */
 
-	snd_sf_zone_t *zone;	/* Zone assigned to this note */
+	struct snd_sf_zone *zone;	/* Zone assigned to this note */
 	void *block;		/* sample block pointer (optional) */
-	snd_midi_channel_t *chan;	/* Midi channel for this note */
-	snd_emux_port_t *port;	/* associated port */
-	snd_emux_t *emu;	/* assigned root info */
-	void *hw;		/* hardware pointer (emu8000_t or emu10k1_t) */
+	struct snd_midi_channel *chan;	/* Midi channel for this note */
+	struct snd_emux_port *port;	/* associated port */
+	struct snd_emux *emu;	/* assigned root info */
+	void *hw;		/* hardware pointer (emu8000 or emu10k1) */
 	unsigned long ontime;	/* jiffies at note triggered */
 	
 	/* Emu8k/Emu10k1 registers */
-	soundfont_voice_info_t reg;
+	struct soundfont_voice_info reg;
 
 	/* additional registers */
 	int avol;		/* volume attenuation */
@@ -229,15 +230,15 @@
 /*
  * prototypes - interface to Emu10k1 and Emu8k routines
  */
-int snd_emux_new(snd_emux_t **remu);
-int snd_emux_register(snd_emux_t *emu, snd_card_t *card, int index, char *name);
-int snd_emux_free(snd_emux_t *emu);
+int snd_emux_new(struct snd_emux **remu);
+int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, char *name);
+int snd_emux_free(struct snd_emux *emu);
 
 /*
  * exported functions
  */
-void snd_emux_terminate_all(snd_emux_t *emu);
-void snd_emux_lock_voice(snd_emux_t *emu, int voice);
-void snd_emux_unlock_voice(snd_emux_t *emu, int voice);
+void snd_emux_terminate_all(struct snd_emux *emu);
+void snd_emux_lock_voice(struct snd_emux *emu, int voice);
+void snd_emux_unlock_voice(struct snd_emux *emu, int voice);
 
 #endif /* __SOUND_EMUX_SYNTH_H */
diff --git a/include/sound/es1688.h b/include/sound/es1688.h
index 604f495..fc1c47d 100644
--- a/include/sound/es1688.h
+++ b/include/sound/es1688.h
@@ -30,7 +30,7 @@
 #define ES1688_HW_688		0x0001
 #define ES1688_HW_1688		0x0002
 
-struct _snd_es1688 {
+struct snd_es1688 {
 	unsigned long port;		/* port of ESS chip */
 	struct resource *res_port;
 	unsigned long mpu_port;		/* MPU-401 port of ESS chip */
@@ -44,17 +44,15 @@
 	unsigned char pad;
 	unsigned int dma_size;
 
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
 
 	spinlock_t reg_lock;
 	spinlock_t mixer_lock;
 };
 
-typedef struct _snd_es1688 es1688_t;
-
 /* I/O ports */
 
 #define ES1688P(codec, x) ((codec)->port + e_s_s_ESS1688##x)
@@ -107,17 +105,17 @@
 
  */
 
-void snd_es1688_mixer_write(es1688_t *chip, unsigned char reg, unsigned char data);
+void snd_es1688_mixer_write(struct snd_es1688 *chip, unsigned char reg, unsigned char data);
 
-int snd_es1688_create(snd_card_t * card,
+int snd_es1688_create(struct snd_card *card,
 		      unsigned long port,
 		      unsigned long mpu_port,
 		      int irq,
 		      int mpu_irq,
 		      int dma8,
 		      unsigned short hardware,
-		      es1688_t ** rchip);
-int snd_es1688_pcm(es1688_t *chip, int device, snd_pcm_t ** rpcm);
-int snd_es1688_mixer(es1688_t *chip);
+		      struct snd_es1688 ** rchip);
+int snd_es1688_pcm(struct snd_es1688 *chip, int device, struct snd_pcm ** rpcm);
+int snd_es1688_mixer(struct snd_es1688 *chip);
 
 #endif /* __SOUND_ES1688_H */
diff --git a/include/sound/gus.h b/include/sound/gus.h
index 7000d9d..63da50f 100644
--- a/include/sound/gus.h
+++ b/include/sound/gus.h
@@ -49,32 +49,32 @@
 #define SNDRV_g_u_s_IRQSTAT		(0x226-0x220)
 #define SNDRV_g_u_s_TIMERCNTRL		(0x228-0x220)
 #define SNDRV_g_u_s_TIMERDATA		(0x229-0x220)
-#define SNDRV_g_u_s_DRAM			(0x327-0x220)
+#define SNDRV_g_u_s_DRAM		(0x327-0x220)
 #define SNDRV_g_u_s_MIXCNTRLREG		(0x220-0x220)
 #define SNDRV_g_u_s_IRQDMACNTRLREG	(0x22b-0x220)
 #define SNDRV_g_u_s_REGCNTRLS		(0x22f-0x220)
-#define SNDRV_g_u_s_BOARDVERSION		(0x726-0x220)
-#define SNDRV_g_u_s_MIXCNTRLPORT		(0x726-0x220)
-#define SNDRV_g_u_s_IVER			(0x325-0x220)
+#define SNDRV_g_u_s_BOARDVERSION	(0x726-0x220)
+#define SNDRV_g_u_s_MIXCNTRLPORT	(0x726-0x220)
+#define SNDRV_g_u_s_IVER		(0x325-0x220)
 #define SNDRV_g_u_s_MIXDATAPORT		(0x326-0x220)
-#define SNDRV_g_u_s_MAXCNTRLPORT		(0x326-0x220)
+#define SNDRV_g_u_s_MAXCNTRLPORT	(0x326-0x220)
 
 /* GF1 registers */
 
 /* global registers */
 #define SNDRV_GF1_GB_ACTIVE_VOICES		0x0e
 #define SNDRV_GF1_GB_VOICES_IRQ			0x0f
-#define SNDRV_GF1_GB_GLOBAL_MODE			0x19
+#define SNDRV_GF1_GB_GLOBAL_MODE		0x19
 #define SNDRV_GF1_GW_LFO_BASE			0x1a
 #define SNDRV_GF1_GB_VOICES_IRQ_READ		0x1f
 #define SNDRV_GF1_GB_DRAM_DMA_CONTROL		0x41
-#define SNDRV_GF1_GW_DRAM_DMA_LOW			0x42
-#define SNDRV_GF1_GW_DRAM_IO_LOW			0x43
-#define SNDRV_GF1_GB_DRAM_IO_HIGH			0x44
+#define SNDRV_GF1_GW_DRAM_DMA_LOW		0x42
+#define SNDRV_GF1_GW_DRAM_IO_LOW		0x43
+#define SNDRV_GF1_GB_DRAM_IO_HIGH		0x44
 #define SNDRV_GF1_GB_SOUND_BLASTER_CONTROL	0x45
 #define SNDRV_GF1_GB_ADLIB_TIMER_1		0x46
 #define SNDRV_GF1_GB_ADLIB_TIMER_2		0x47
-#define SNDRV_GF1_GB_RECORD_RATE			0x48
+#define SNDRV_GF1_GB_RECORD_RATE		0x48
 #define SNDRV_GF1_GB_REC_DMA_CONTROL		0x49
 #define SNDRV_GF1_GB_JOYSTICK_DAC_LEVEL		0x4b
 #define SNDRV_GF1_GB_RESET			0x4c
@@ -83,7 +83,7 @@
 #define SNDRV_GF1_GW_MEMORY_CONFIG		0x52
 #define SNDRV_GF1_GB_MEMORY_CONTROL		0x53
 #define SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR	0x54
-#define SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR		0x55
+#define SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR	0x55
 #define SNDRV_GF1_GW_FIFO_SIZE			0x56
 #define SNDRV_GF1_GW_INTERLEAVE			0x57
 #define SNDRV_GF1_GB_COMPATIBILITY		0x59
@@ -100,39 +100,39 @@
 #define SNDRV_GF1_VA_START			SNDRV_GF1_VW_START_HIGH
 #define SNDRV_GF1_VW_END_HIGH			0x04
 #define SNDRV_GF1_VW_END_LOW			0x05
-#define SNDRV_GF1_VA_END				SNDRV_GF1_VW_END_HIGH
-#define SNDRV_GF1_VB_VOLUME_RATE			0x06
-#define SNDRV_GF1_VB_VOLUME_START			0x07
+#define SNDRV_GF1_VA_END			SNDRV_GF1_VW_END_HIGH
+#define SNDRV_GF1_VB_VOLUME_RATE		0x06
+#define SNDRV_GF1_VB_VOLUME_START		0x07
 #define SNDRV_GF1_VB_VOLUME_END			0x08
 #define SNDRV_GF1_VW_VOLUME			0x09
-#define SNDRV_GF1_VW_CURRENT_HIGH			0x0a
-#define SNDRV_GF1_VW_CURRENT_LOW			0x0b
+#define SNDRV_GF1_VW_CURRENT_HIGH		0x0a
+#define SNDRV_GF1_VW_CURRENT_LOW		0x0b
 #define SNDRV_GF1_VA_CURRENT			SNDRV_GF1_VW_CURRENT_HIGH
-#define SNDRV_GF1_VB_PAN				0x0c
-#define SNDRV_GF1_VW_OFFSET_RIGHT			0x0c
+#define SNDRV_GF1_VB_PAN			0x0c
+#define SNDRV_GF1_VW_OFFSET_RIGHT		0x0c
 #define SNDRV_GF1_VB_VOLUME_CONTROL		0x0d
 #define SNDRV_GF1_VB_UPPER_ADDRESS		0x10
-#define SNDRV_GF1_VW_EFFECT_HIGH			0x11
+#define SNDRV_GF1_VW_EFFECT_HIGH		0x11
 #define SNDRV_GF1_VW_EFFECT_LOW			0x12
 #define SNDRV_GF1_VA_EFFECT			SNDRV_GF1_VW_EFFECT_HIGH
-#define SNDRV_GF1_VW_OFFSET_LEFT			0x13
-#define SNDRV_GF1_VB_ACCUMULATOR			0x14
-#define SNDRV_GF1_VB_MODE				0x15
+#define SNDRV_GF1_VW_OFFSET_LEFT		0x13
+#define SNDRV_GF1_VB_ACCUMULATOR		0x14
+#define SNDRV_GF1_VB_MODE			0x15
 #define SNDRV_GF1_VW_EFFECT_VOLUME		0x16
 #define SNDRV_GF1_VB_FREQUENCY_LFO		0x17
 #define SNDRV_GF1_VB_VOLUME_LFO			0x18
 #define SNDRV_GF1_VW_OFFSET_RIGHT_FINAL		0x1b
 #define SNDRV_GF1_VW_OFFSET_LEFT_FINAL		0x1c
-#define SNDRV_GF1_VW_EFFECT_VOLUME_FINAL		0x1d
+#define SNDRV_GF1_VW_EFFECT_VOLUME_FINAL	0x1d
 
 /* ICS registers */
 
 #define SNDRV_ICS_MIC_DEV		0
-#define SNDRV_ICS_LINE_DEV	1
+#define SNDRV_ICS_LINE_DEV		1
 #define SNDRV_ICS_CD_DEV		2
 #define SNDRV_ICS_GF1_DEV		3
-#define SNDRV_ICS_NONE_DEV	4
-#define SNDRV_ICS_MASTER_DEV	5
+#define SNDRV_ICS_NONE_DEV		4
+#define SNDRV_ICS_MASTER_DEV		5
 
 /* LFO */
 
@@ -143,7 +143,7 @@
 
 #define SNDRV_GF1_DMA_UNSIGNED	0x80
 #define SNDRV_GF1_DMA_16BIT	0x40
-#define SNDRV_GF1_DMA_IRQ		0x20
+#define SNDRV_GF1_DMA_IRQ	0x20
 #define SNDRV_GF1_DMA_WIDTH16	0x04
 #define SNDRV_GF1_DMA_READ	0x02	/* read from GUS's DRAM */
 #define SNDRV_GF1_DMA_ENABLE	0x01
@@ -159,7 +159,7 @@
 
 /* defines for memory manager */
 
-#define SNDRV_GF1_MEM_BLOCK_16BIT		0x0001
+#define SNDRV_GF1_MEM_BLOCK_16BIT	0x0001
 
 #define SNDRV_GF1_MEM_OWNER_DRIVER	0x0001
 #define SNDRV_GF1_MEM_OWNER_WAVE_SIMPLE	0x0002
@@ -169,9 +169,9 @@
 /* constants for interrupt handlers */
 
 #define SNDRV_GF1_HANDLER_MIDI_OUT	0x00010000
-#define SNDRV_GF1_HANDLER_MIDI_IN		0x00020000
-#define SNDRV_GF1_HANDLER_TIMER1		0x00040000
-#define SNDRV_GF1_HANDLER_TIMER2		0x00080000
+#define SNDRV_GF1_HANDLER_MIDI_IN	0x00020000
+#define SNDRV_GF1_HANDLER_TIMER1	0x00040000
+#define SNDRV_GF1_HANDLER_TIMER2	0x00080000
 #define SNDRV_GF1_HANDLER_VOICE		0x00100000
 #define SNDRV_GF1_HANDLER_DMA_WRITE	0x00200000
 #define SNDRV_GF1_HANDLER_DMA_READ	0x00400000
@@ -183,17 +183,16 @@
 
 /* --- */
 
-struct _snd_gus_card;
-typedef struct _snd_gus_card snd_gus_card_t;
+struct snd_gus_card;
 
 /* GF1 specific structure */
 
-typedef struct _snd_gf1_bank_info {
+struct snd_gf1_bank_info {
 	unsigned int address;
 	unsigned int size;
-} snd_gf1_bank_info_t;
+};
 
-typedef struct _snd_gf1_mem_block {
+struct snd_gf1_mem_block {
 	unsigned short flags;	/* flags - SNDRV_GF1_MEM_BLOCK_XXXX */
 	unsigned short owner;	/* owner - SNDRV_GF1_MEM_OWNER_XXXX */
 	unsigned int share;	/* share count */
@@ -201,68 +200,68 @@
 	unsigned int ptr;
 	unsigned int size;
 	char *name;
-	struct _snd_gf1_mem_block *next;
-	struct _snd_gf1_mem_block *prev;
-} snd_gf1_mem_block_t;
+	struct snd_gf1_mem_block *next;
+	struct snd_gf1_mem_block *prev;
+};
 
-typedef struct _snd_gf1_mem {
-	snd_gf1_bank_info_t banks_8[4];
-	snd_gf1_bank_info_t banks_16[4];
-	snd_gf1_mem_block_t *first;
-	snd_gf1_mem_block_t *last;
+struct snd_gf1_mem {
+	struct snd_gf1_bank_info banks_8[4];
+	struct snd_gf1_bank_info banks_16[4];
+	struct snd_gf1_mem_block *first;
+	struct snd_gf1_mem_block *last;
 	struct semaphore memory_mutex;
-} snd_gf1_mem_t;
+};
 
-typedef struct snd_gf1_dma_block {
+struct snd_gf1_dma_block {
 	void *buffer;		/* buffer in computer's RAM */
 	unsigned long buf_addr;	/* buffer address */
 	unsigned int addr;	/* address in onboard memory */
 	unsigned int count;	/* count in bytes */
 	unsigned int cmd;	/* DMA command (format) */
-	void (*ack)(snd_gus_card_t * gus, void *private_data);
+	void (*ack)(struct snd_gus_card * gus, void *private_data);
 	void *private_data;
 	struct snd_gf1_dma_block *next;
-} snd_gf1_dma_block_t;
+};
 
-typedef struct {
-	snd_midi_channel_set_t * chset;
-	snd_gus_card_t * gus;
+struct snd_gus_port {
+	struct snd_midi_channel_set * chset;
+	struct snd_gus_card * gus;
 	int mode;		/* operation mode */
 	int client;		/* sequencer client number */
 	int port;		/* sequencer port number */
 	unsigned int midi_has_voices: 1;
-} snd_gus_port_t;
+};
 
-typedef struct _snd_gus_voice snd_gus_voice_t;
+struct snd_gus_voice;
 
-typedef struct {
-	void (*sample_start)(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_position_t position);
-	void (*sample_stop)(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_stop_mode_t mode);
-	void (*sample_freq)(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_frequency_t freq);
-	void (*sample_volume)(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_ev_volume_t *volume);
-	void (*sample_loop)(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_ev_loop_t *loop);
-	void (*sample_pos)(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_position_t position);
-	void (*sample_private1)(snd_gus_card_t *card, snd_gus_voice_t *voice, unsigned char *data);
-} snd_gus_sample_ops_t;
+struct snd_gus_sample_ops {
+	void (*sample_start)(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_position_t position);
+	void (*sample_stop)(struct snd_gus_card *gus, struct snd_gus_voice *voice, int mode);
+	void (*sample_freq)(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_frequency_t freq);
+	void (*sample_volume)(struct snd_gus_card *gus, struct snd_gus_voice *voice, struct snd_seq_ev_volume *volume);
+	void (*sample_loop)(struct snd_gus_card *card, struct snd_gus_voice *voice, struct snd_seq_ev_loop *loop);
+	void (*sample_pos)(struct snd_gus_card *card, struct snd_gus_voice *voice, snd_seq_position_t position);
+	void (*sample_private1)(struct snd_gus_card *card, struct snd_gus_voice *voice, unsigned char *data);
+};
 
-#define SNDRV_GF1_VOICE_TYPE_PCM		0
+#define SNDRV_GF1_VOICE_TYPE_PCM	0
 #define SNDRV_GF1_VOICE_TYPE_SYNTH 	1
-#define SNDRV_GF1_VOICE_TYPE_MIDI		2
+#define SNDRV_GF1_VOICE_TYPE_MIDI	2
 
 #define SNDRV_GF1_VFLG_RUNNING		(1<<0)
 #define SNDRV_GF1_VFLG_EFFECT_TIMER1	(1<<1)
 #define SNDRV_GF1_VFLG_PAN		(1<<2)
 
-typedef enum {
+enum snd_gus_volume_state {
 	VENV_BEFORE,
 	VENV_ATTACK,
 	VENV_SUSTAIN,
 	VENV_RELEASE,
 	VENV_DONE,
 	VENV_VOLUME
-} snd_gus_volume_state_t;
+};
 
-struct _snd_gus_voice {
+struct snd_gus_voice {
 	int number;
 	unsigned int use: 1,
 	    pcm: 1,
@@ -278,18 +277,18 @@
 	unsigned int interrupt_stat_wave;
 	unsigned int interrupt_stat_volume;
 #endif
-	void (*handler_wave) (snd_gus_card_t * gus, snd_gus_voice_t * voice);
-	void (*handler_volume) (snd_gus_card_t * gus, snd_gus_voice_t * voice);
-	void (*handler_effect) (snd_gus_card_t * gus, snd_gus_voice_t * voice);
-	void (*volume_change) (snd_gus_card_t * gus);
+	void (*handler_wave) (struct snd_gus_card * gus, struct snd_gus_voice * voice);
+	void (*handler_volume) (struct snd_gus_card * gus, struct snd_gus_voice * voice);
+	void (*handler_effect) (struct snd_gus_card * gus, struct snd_gus_voice * voice);
+	void (*volume_change) (struct snd_gus_card * gus);
 
-	snd_gus_sample_ops_t *sample_ops;
+	struct snd_gus_sample_ops *sample_ops;
 
-	snd_seq_instr_t instr;
+	struct snd_seq_instr instr;
 
 	/* running status / registers */
 
-	snd_seq_ev_volume_t sample_volume;
+	struct snd_seq_ev_volume sample_volume;
 
 	unsigned short fc_register;
 	unsigned short fc_lfo;
@@ -300,8 +299,8 @@
 	unsigned char effect_accumulator;
 	unsigned char volume_control;
 	unsigned char venv_value_next;
-	snd_gus_volume_state_t venv_state;
-	snd_gus_volume_state_t venv_state_prev;
+	enum snd_gus_volume_state venv_state;
+	enum snd_gus_volume_state venv_state_prev;
 	unsigned short vlo;
 	unsigned short vro;
 	unsigned short gf1_effect_volume;
@@ -309,10 +308,10 @@
 	/* --- */
 
 	void *private_data;
-	void (*private_free)(snd_gus_voice_t *voice);
+	void (*private_free)(struct snd_gus_voice *voice);
 };
 
-struct _snd_gf1 {
+struct snd_gf1 {
 
 	unsigned int enh_mode:1,	/* enhanced mode (GFA1) */
 		     hw_lfo:1,		/* use hardware LFO */
@@ -330,7 +329,7 @@
 	unsigned int rom_present;	/* bitmask */
 	unsigned int rom_banks;		/* GUS's ROM banks */
 
-	snd_gf1_mem_t mem_alloc;
+	struct snd_gf1_mem mem_alloc;
 
 	/* registers */
 	unsigned short reg_page;
@@ -347,7 +346,7 @@
 	unsigned char active_voices;	/* active voices */
 	unsigned char active_voice;	/* selected voice (GF1PAGE register) */
 
-	snd_gus_voice_t voices[32];	/* GF1 voices */
+	struct snd_gus_voice voices[32];	/* GF1 voices */
 
 	unsigned int default_voice_address;
 
@@ -362,12 +361,12 @@
 
 	/* interrupt handlers */
 
-	void (*interrupt_handler_midi_out) (snd_gus_card_t * gus);
-	void (*interrupt_handler_midi_in) (snd_gus_card_t * gus);
-	void (*interrupt_handler_timer1) (snd_gus_card_t * gus);
-	void (*interrupt_handler_timer2) (snd_gus_card_t * gus);
-	void (*interrupt_handler_dma_write) (snd_gus_card_t * gus);
-	void (*interrupt_handler_dma_read) (snd_gus_card_t * gus);
+	void (*interrupt_handler_midi_out) (struct snd_gus_card * gus);
+	void (*interrupt_handler_midi_in) (struct snd_gus_card * gus);
+	void (*interrupt_handler_timer1) (struct snd_gus_card * gus);
+	void (*interrupt_handler_timer2) (struct snd_gus_card * gus);
+	void (*interrupt_handler_dma_write) (struct snd_gus_card * gus);
+	void (*interrupt_handler_dma_read) (struct snd_gus_card * gus);
 
 #ifdef CONFIG_SND_DEBUG
 	unsigned int interrupt_stat_midi_out;
@@ -382,17 +381,17 @@
 	/* synthesizer */
 
 	int seq_client;
-	snd_gus_port_t seq_ports[4];
-	snd_seq_kinstr_list_t *ilist;
-	snd_iwffff_ops_t iwffff_ops;
-	snd_gf1_ops_t gf1_ops;
-	snd_simple_ops_t simple_ops;
+	struct snd_gus_port seq_ports[4];
+	struct snd_seq_kinstr_list *ilist;
+	struct snd_iwffff_ops iwffff_ops;
+	struct snd_gf1_ops gf1_ops;
+	struct snd_simple_ops simple_ops;
 
 	/* timer */
 
 	unsigned short timer_enabled;
-	snd_timer_t *timer1;
-	snd_timer_t *timer2;
+	struct snd_timer *timer1;
+	struct snd_timer *timer2;
 
 	/* midi */
 
@@ -404,11 +403,11 @@
 
 	unsigned int dma_flags;
 	unsigned int dma_shared;
-	snd_gf1_dma_block_t *dma_data_pcm;
-	snd_gf1_dma_block_t *dma_data_pcm_last;
-	snd_gf1_dma_block_t *dma_data_synth;
-	snd_gf1_dma_block_t *dma_data_synth_last;
-	void (*dma_ack)(snd_gus_card_t * gus, void *private_data);
+	struct snd_gf1_dma_block *dma_data_pcm;
+	struct snd_gf1_dma_block *dma_data_pcm_last;
+	struct snd_gf1_dma_block *dma_data_synth;
+	struct snd_gf1_dma_block *dma_data_synth_last;
+	void (*dma_ack)(struct snd_gus_card * gus, void *private_data);
 	void *dma_private_data;
 
 	/* pcm */
@@ -425,8 +424,8 @@
 
 /* main structure for GUS card */
 
-struct _snd_gus_card {
-	snd_card_t *card;
+struct snd_gus_card {
+	struct snd_card *card;
 
 	unsigned int
 	 initialized: 1,		/* resources were initialized */
@@ -448,18 +447,18 @@
 	unsigned short joystick_dac;	/* joystick DAC level */
 	int timer_dev;			/* timer device */
 
-	struct _snd_gf1 gf1;	/* gf1 specific variables */
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *pcm_cap_substream;
+	struct snd_gf1 gf1;	/* gf1 specific variables */
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *pcm_cap_substream;
 	unsigned int c_dma_size;
 	unsigned int c_period_size;
 	unsigned int c_pos;
 
-	snd_rawmidi_t *midi_uart;
-	snd_rawmidi_substream_t *midi_substream_output;
-	snd_rawmidi_substream_t *midi_substream_input;
+	struct snd_rawmidi *midi_uart;
+	struct snd_rawmidi_substream *midi_substream_output;
+	struct snd_rawmidi_substream *midi_substream_input;
 
-	snd_seq_device_t *seq_dev;
+	struct snd_seq_device *seq_dev;
 
 	spinlock_t reg_lock;
 	spinlock_t voice_alloc;
@@ -474,7 +473,7 @@
 
 /* I/O functions for GF1/InterWave chip - gus_io.c */
 
-static inline void snd_gf1_select_voice(snd_gus_card_t * gus, int voice)
+static inline void snd_gf1_select_voice(struct snd_gus_card * gus, int voice)
 {
 	unsigned long flags;
 
@@ -486,63 +485,63 @@
 	spin_unlock_irqrestore(&gus->active_voice_lock, flags);
 }
 
-static inline void snd_gf1_uart_cmd(snd_gus_card_t * gus, unsigned char b)
+static inline void snd_gf1_uart_cmd(struct snd_gus_card * gus, unsigned char b)
 {
 	outb(gus->gf1.uart_cmd = b, GUSP(gus, MIDICTRL));
 }
 
-static inline unsigned char snd_gf1_uart_stat(snd_gus_card_t * gus)
+static inline unsigned char snd_gf1_uart_stat(struct snd_gus_card * gus)
 {
 	return inb(GUSP(gus, MIDISTAT));
 }
 
-static inline void snd_gf1_uart_put(snd_gus_card_t * gus, unsigned char b)
+static inline void snd_gf1_uart_put(struct snd_gus_card * gus, unsigned char b)
 {
 	outb(b, GUSP(gus, MIDIDATA));
 }
 
-static inline unsigned char snd_gf1_uart_get(snd_gus_card_t * gus)
+static inline unsigned char snd_gf1_uart_get(struct snd_gus_card * gus)
 {
 	return inb(GUSP(gus, MIDIDATA));
 }
 
-extern void snd_gf1_delay(snd_gus_card_t * gus);
+extern void snd_gf1_delay(struct snd_gus_card * gus);
 
-extern void snd_gf1_ctrl_stop(snd_gus_card_t * gus, unsigned char reg);
+extern void snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg);
 
-extern void snd_gf1_write8(snd_gus_card_t * gus, unsigned char reg, unsigned char data);
-extern unsigned char snd_gf1_look8(snd_gus_card_t * gus, unsigned char reg);
-static inline unsigned char snd_gf1_read8(snd_gus_card_t * gus, unsigned char reg)
+extern void snd_gf1_write8(struct snd_gus_card * gus, unsigned char reg, unsigned char data);
+extern unsigned char snd_gf1_look8(struct snd_gus_card * gus, unsigned char reg);
+static inline unsigned char snd_gf1_read8(struct snd_gus_card * gus, unsigned char reg)
 {
 	return snd_gf1_look8(gus, reg | 0x80);
 }
-extern void snd_gf1_write16(snd_gus_card_t * gus, unsigned char reg, unsigned int data);
-extern unsigned short snd_gf1_look16(snd_gus_card_t * gus, unsigned char reg);
-static inline unsigned short snd_gf1_read16(snd_gus_card_t * gus, unsigned char reg)
+extern void snd_gf1_write16(struct snd_gus_card * gus, unsigned char reg, unsigned int data);
+extern unsigned short snd_gf1_look16(struct snd_gus_card * gus, unsigned char reg);
+static inline unsigned short snd_gf1_read16(struct snd_gus_card * gus, unsigned char reg)
 {
 	return snd_gf1_look16(gus, reg | 0x80);
 }
-extern void snd_gf1_adlib_write(snd_gus_card_t * gus, unsigned char reg, unsigned char data);
-extern void snd_gf1_dram_addr(snd_gus_card_t * gus, unsigned int addr);
-extern void snd_gf1_poke(snd_gus_card_t * gus, unsigned int addr, unsigned char data);
-extern unsigned char snd_gf1_peek(snd_gus_card_t * gus, unsigned int addr);
-extern void snd_gf1_write_addr(snd_gus_card_t * gus, unsigned char reg, unsigned int addr, short w_16bit);
-extern unsigned int snd_gf1_read_addr(snd_gus_card_t * gus, unsigned char reg, short w_16bit);
-extern void snd_gf1_i_ctrl_stop(snd_gus_card_t * gus, unsigned char reg);
-extern void snd_gf1_i_write8(snd_gus_card_t * gus, unsigned char reg, unsigned char data);
-extern unsigned char snd_gf1_i_look8(snd_gus_card_t * gus, unsigned char reg);
-extern void snd_gf1_i_write16(snd_gus_card_t * gus, unsigned char reg, unsigned int data);
-static inline unsigned char snd_gf1_i_read8(snd_gus_card_t * gus, unsigned char reg)
+extern void snd_gf1_adlib_write(struct snd_gus_card * gus, unsigned char reg, unsigned char data);
+extern void snd_gf1_dram_addr(struct snd_gus_card * gus, unsigned int addr);
+extern void snd_gf1_poke(struct snd_gus_card * gus, unsigned int addr, unsigned char data);
+extern unsigned char snd_gf1_peek(struct snd_gus_card * gus, unsigned int addr);
+extern void snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg, unsigned int addr, short w_16bit);
+extern unsigned int snd_gf1_read_addr(struct snd_gus_card * gus, unsigned char reg, short w_16bit);
+extern void snd_gf1_i_ctrl_stop(struct snd_gus_card * gus, unsigned char reg);
+extern void snd_gf1_i_write8(struct snd_gus_card * gus, unsigned char reg, unsigned char data);
+extern unsigned char snd_gf1_i_look8(struct snd_gus_card * gus, unsigned char reg);
+extern void snd_gf1_i_write16(struct snd_gus_card * gus, unsigned char reg, unsigned int data);
+static inline unsigned char snd_gf1_i_read8(struct snd_gus_card * gus, unsigned char reg)
 {
 	return snd_gf1_i_look8(gus, reg | 0x80);
 }
-extern unsigned short snd_gf1_i_look16(snd_gus_card_t * gus, unsigned char reg);
-static inline unsigned short snd_gf1_i_read16(snd_gus_card_t * gus, unsigned char reg)
+extern unsigned short snd_gf1_i_look16(struct snd_gus_card * gus, unsigned char reg);
+static inline unsigned short snd_gf1_i_read16(struct snd_gus_card * gus, unsigned char reg)
 {
 	return snd_gf1_i_look16(gus, reg | 0x80);
 }
 
-extern void snd_gf1_select_active_voices(snd_gus_card_t * gus);
+extern void snd_gf1_select_active_voices(struct snd_gus_card * gus);
 
 /* gus_lfo.c */
 
@@ -555,98 +554,98 @@
 };
 
 #if 0
-extern irqreturn_t snd_gf1_lfo_effect_interrupt(snd_gus_card_t * gus, snd_gf1_voice_t * voice);
+extern irqreturn_t snd_gf1_lfo_effect_interrupt(struct snd_gus_card * gus, snd_gf1_voice_t * voice);
 #endif
-extern void snd_gf1_lfo_init(snd_gus_card_t * gus);
-extern void snd_gf1_lfo_done(snd_gus_card_t * gus);
-extern void snd_gf1_lfo_program(snd_gus_card_t * gus, int voice, int lfo_type, struct _SND_IW_LFO_PROGRAM *program);
-extern void snd_gf1_lfo_enable(snd_gus_card_t * gus, int voice, int lfo_type);
-extern void snd_gf1_lfo_disable(snd_gus_card_t * gus, int voice, int lfo_type);
-extern void snd_gf1_lfo_change_freq(snd_gus_card_t * gus, int voice, int lfo_type, int freq);
-extern void snd_gf1_lfo_change_depth(snd_gus_card_t * gus, int voice, int lfo_type, int depth);
-extern void snd_gf1_lfo_setup(snd_gus_card_t * gus, int voice, int lfo_type, int freq, int current_depth, int depth, int sweep, int shape);
-extern void snd_gf1_lfo_shutdown(snd_gus_card_t * gus, int voice, int lfo_type);
+extern void snd_gf1_lfo_init(struct snd_gus_card * gus);
+extern void snd_gf1_lfo_done(struct snd_gus_card * gus);
+extern void snd_gf1_lfo_program(struct snd_gus_card * gus, int voice, int lfo_type, struct _SND_IW_LFO_PROGRAM *program);
+extern void snd_gf1_lfo_enable(struct snd_gus_card * gus, int voice, int lfo_type);
+extern void snd_gf1_lfo_disable(struct snd_gus_card * gus, int voice, int lfo_type);
+extern void snd_gf1_lfo_change_freq(struct snd_gus_card * gus, int voice, int lfo_type, int freq);
+extern void snd_gf1_lfo_change_depth(struct snd_gus_card * gus, int voice, int lfo_type, int depth);
+extern void snd_gf1_lfo_setup(struct snd_gus_card * gus, int voice, int lfo_type, int freq, int current_depth, int depth, int sweep, int shape);
+extern void snd_gf1_lfo_shutdown(struct snd_gus_card * gus, int voice, int lfo_type);
 #if 0
-extern void snd_gf1_lfo_command(snd_gus_card_t * gus, int voice, unsigned char *command);
+extern void snd_gf1_lfo_command(struct snd_gus_card * gus, int voice, unsigned char *command);
 #endif
 
 /* gus_mem.c */
 
-void snd_gf1_mem_lock(snd_gf1_mem_t * alloc, int xup);
-int snd_gf1_mem_xfree(snd_gf1_mem_t * alloc, snd_gf1_mem_block_t * block);
-snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner,
+void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup);
+int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * block);
+struct snd_gf1_mem_block *snd_gf1_mem_alloc(struct snd_gf1_mem * alloc, int owner,
 				       char *name, int size, int w_16,
 				       int align, unsigned int *share_id);
-int snd_gf1_mem_free(snd_gf1_mem_t * alloc, unsigned int address);
-int snd_gf1_mem_free_owner(snd_gf1_mem_t * alloc, int owner);
-int snd_gf1_mem_init(snd_gus_card_t * gus);
-int snd_gf1_mem_done(snd_gus_card_t * gus);
+int snd_gf1_mem_free(struct snd_gf1_mem * alloc, unsigned int address);
+int snd_gf1_mem_free_owner(struct snd_gf1_mem * alloc, int owner);
+int snd_gf1_mem_init(struct snd_gus_card * gus);
+int snd_gf1_mem_done(struct snd_gus_card * gus);
 
 /* gus_mem_proc.c */
 
-int snd_gf1_mem_proc_init(snd_gus_card_t * gus);
+int snd_gf1_mem_proc_init(struct snd_gus_card * gus);
 
 /* gus_dma.c */
 
-int snd_gf1_dma_init(snd_gus_card_t * gus);
-int snd_gf1_dma_done(snd_gus_card_t * gus);
-int snd_gf1_dma_transfer_block(snd_gus_card_t * gus,
-			       snd_gf1_dma_block_t * block,
+int snd_gf1_dma_init(struct snd_gus_card * gus);
+int snd_gf1_dma_done(struct snd_gus_card * gus);
+int snd_gf1_dma_transfer_block(struct snd_gus_card * gus,
+			       struct snd_gf1_dma_block * block,
 			       int atomic,
 			       int synth);
 
 /* gus_volume.c */
 
 unsigned short snd_gf1_lvol_to_gvol_raw(unsigned int vol);
-unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq2);
+unsigned short snd_gf1_translate_freq(struct snd_gus_card * gus, unsigned int freq2);
 
 /* gus_reset.c */
 
-void snd_gf1_set_default_handlers(snd_gus_card_t * gus, unsigned int what);
-void snd_gf1_smart_stop_voice(snd_gus_card_t * gus, unsigned short voice);
-void snd_gf1_stop_voice(snd_gus_card_t * gus, unsigned short voice);
-void snd_gf1_stop_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max);
-snd_gus_voice_t *snd_gf1_alloc_voice(snd_gus_card_t * gus, int type, int client, int port);
-void snd_gf1_free_voice(snd_gus_card_t * gus, snd_gus_voice_t *voice);
-int snd_gf1_start(snd_gus_card_t * gus);
-int snd_gf1_stop(snd_gus_card_t * gus);
+void snd_gf1_set_default_handlers(struct snd_gus_card * gus, unsigned int what);
+void snd_gf1_smart_stop_voice(struct snd_gus_card * gus, unsigned short voice);
+void snd_gf1_stop_voice(struct snd_gus_card * gus, unsigned short voice);
+void snd_gf1_stop_voices(struct snd_gus_card * gus, unsigned short v_min, unsigned short v_max);
+struct snd_gus_voice *snd_gf1_alloc_voice(struct snd_gus_card * gus, int type, int client, int port);
+void snd_gf1_free_voice(struct snd_gus_card * gus, struct snd_gus_voice *voice);
+int snd_gf1_start(struct snd_gus_card * gus);
+int snd_gf1_stop(struct snd_gus_card * gus);
 
 /* gus_mixer.c */
 
-int snd_gf1_new_mixer(snd_gus_card_t * gus);
+int snd_gf1_new_mixer(struct snd_gus_card * gus);
 
 /* gus_pcm.c */
 
-int snd_gf1_pcm_new(snd_gus_card_t * gus, int pcm_dev, int control_index, snd_pcm_t ** rpcm);
+int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, struct snd_pcm ** rpcm);
 
 #ifdef CONFIG_SND_DEBUG
-extern void snd_gf1_print_voice_registers(snd_gus_card_t * gus);
+extern void snd_gf1_print_voice_registers(struct snd_gus_card * gus);
 #endif
 
 /* gus.c */
 
-int snd_gus_use_inc(snd_gus_card_t * gus);
-void snd_gus_use_dec(snd_gus_card_t * gus);
-int snd_gus_create(snd_card_t * card,
+int snd_gus_use_inc(struct snd_gus_card * gus);
+void snd_gus_use_dec(struct snd_gus_card * gus);
+int snd_gus_create(struct snd_card *card,
 		   unsigned long port,
 		   int irq, int dma1, int dma2,
 		   int timer_dev,
 		   int voices,
 		   int pcm_channels,
 		   int effect,
-		   snd_gus_card_t ** rgus);
-int snd_gus_initialize(snd_gus_card_t * gus);
+		   struct snd_gus_card ** rgus);
+int snd_gus_initialize(struct snd_gus_card * gus);
 
 /* gus_irq.c */
 
 irqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 #ifdef CONFIG_SND_DEBUG
-void snd_gus_irq_profile_init(snd_gus_card_t *gus);
+void snd_gus_irq_profile_init(struct snd_gus_card *gus);
 #endif
 
 /* gus_uart.c */
 
-int snd_gf1_rawmidi_new(snd_gus_card_t * gus, int device, snd_rawmidi_t **rrawmidi);
+int snd_gf1_rawmidi_new(struct snd_gus_card * gus, int device, struct snd_rawmidi **rrawmidi);
 
 #if 0
 extern void snd_engine_instrument_register(unsigned short mode,
@@ -657,37 +656,37 @@
 #endif
 
 /* gus_dram.c */
-int snd_gus_dram_write(snd_gus_card_t *gus, char __user *ptr,
+int snd_gus_dram_write(struct snd_gus_card *gus, char __user *ptr,
 		       unsigned int addr, unsigned int size);
-int snd_gus_dram_read(snd_gus_card_t *gus, char __user *ptr,
+int snd_gus_dram_read(struct snd_gus_card *gus, char __user *ptr,
 		      unsigned int addr, unsigned int size, int rom);
 
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
 
 /* gus_sample.c */
-void snd_gus_sample_event(snd_seq_event_t *ev, snd_gus_port_t *p);
+void snd_gus_sample_event(struct snd_seq_event *ev, struct snd_gus_port *p);
 
 /* gus_simple.c */
-void snd_gf1_simple_init(snd_gus_voice_t *voice);
+void snd_gf1_simple_init(struct snd_gus_voice *voice);
 
 /* gus_instr.c */
-int snd_gus_iwffff_put_sample(void *private_data, iwffff_wave_t *wave,
+int snd_gus_iwffff_put_sample(void *private_data, struct iwffff_wave *wave,
 			      char __user *data, long len, int atomic);
-int snd_gus_iwffff_get_sample(void *private_data, iwffff_wave_t *wave,
+int snd_gus_iwffff_get_sample(void *private_data, struct iwffff_wave *wave,
 			      char __user *data, long len, int atomic);
-int snd_gus_iwffff_remove_sample(void *private_data, iwffff_wave_t *wave,
+int snd_gus_iwffff_remove_sample(void *private_data, struct iwffff_wave *wave,
 				 int atomic);
-int snd_gus_gf1_put_sample(void *private_data, gf1_wave_t *wave,
+int snd_gus_gf1_put_sample(void *private_data, struct gf1_wave *wave,
 			   char __user *data, long len, int atomic);
-int snd_gus_gf1_get_sample(void *private_data, gf1_wave_t *wave,
+int snd_gus_gf1_get_sample(void *private_data, struct gf1_wave *wave,
 			   char __user *data, long len, int atomic);
-int snd_gus_gf1_remove_sample(void *private_data, gf1_wave_t *wave,
+int snd_gus_gf1_remove_sample(void *private_data, struct gf1_wave *wave,
 			      int atomic);
-int snd_gus_simple_put_sample(void *private_data, simple_instrument_t *instr,
+int snd_gus_simple_put_sample(void *private_data, struct simple_instrument *instr,
 			      char __user *data, long len, int atomic);
-int snd_gus_simple_get_sample(void *private_data, simple_instrument_t *instr,
+int snd_gus_simple_get_sample(void *private_data, struct simple_instrument *instr,
 			      char __user *data, long len, int atomic);
-int snd_gus_simple_remove_sample(void *private_data, simple_instrument_t *instr,
+int snd_gus_simple_remove_sample(void *private_data, struct simple_instrument *instr,
 				 int atomic);
 
 #endif /* CONFIG_SND_SEQUENCER */
diff --git a/include/sound/hdsp.h b/include/sound/hdsp.h
index 7ce3aa6..25e1951 100644
--- a/include/sound/hdsp.h
+++ b/include/sound/hdsp.h
@@ -21,17 +21,15 @@
 
 #define HDSP_MATRIX_MIXER_SIZE 2048
 
-typedef enum {
+enum HDSP_IO_Type {
 	Digiface,
 	Multiface,
 	H9652,
 	H9632,
 	Undefined,
-} HDSP_IO_Type;
+};
 
-typedef struct _snd_hdsp_peak_rms hdsp_peak_rms_t;
-
-struct _snd_hdsp_peak_rms {
+struct hdsp_peak_rms {
 	u32 input_peaks[26];
 	u32 playback_peaks[26];
 	u32 output_peaks[28];
@@ -41,11 +39,9 @@
 	u64 output_rms[26];
 };
 
-#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t)
+#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, struct hdsp_peak_rms)
 
-typedef struct _snd_hdsp_config_info hdsp_config_info_t;
-
-struct _snd_hdsp_config_info {
+struct hdsp_config_info {
 	unsigned char pref_sync_ref;
 	unsigned char wordclock_sync_check;
 	unsigned char spdif_sync_check;
@@ -71,40 +67,41 @@
 	unsigned char analog_extension_board;
 };
 
-#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t)
+#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, struct hdsp_config_info)
 
-typedef struct _snd_hdsp_firmware hdsp_firmware_t;
-
-struct _snd_hdsp_firmware {
+struct hdsp_firmware {
 	void __user *firmware_data;	/* 24413 x 4 bytes */
 };
 
-#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t)
+#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, struct hdsp_firmware)
 
-typedef struct _snd_hdsp_version hdsp_version_t;
-
-struct _snd_hdsp_version {
-	HDSP_IO_Type io_type;
+struct hdsp_version {
+	enum HDSP_IO_Type io_type;
 	unsigned short firmware_rev;
 };
 
-#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t)
+#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, struct hdsp_version)
 
-typedef struct _snd_hdsp_mixer hdsp_mixer_t;
-
-struct _snd_hdsp_mixer {
+struct hdsp_mixer {
 	unsigned short matrix[HDSP_MATRIX_MIXER_SIZE];
 };
 
-#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t)
+#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, struct hdsp_mixer)
 
-typedef struct _snd_hdsp_9632_aeb hdsp_9632_aeb_t;
-
-struct _snd_hdsp_9632_aeb {
+struct hdsp_9632_aeb {
 	int aebi;
 	int aebo;
 };
 
-#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t)
+#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, struct hdsp_9632_aeb)
+
+/* typedefs for compatibility to user-space */
+typedef enum HDSP_IO_Type HDSP_IO_Type;
+typedef struct hdsp_peak_rms hdsp_peak_rms_t;
+typedef struct hdsp_config_info hdsp_config_info_t;
+typedef struct hdsp_firmware hdsp_firmware_t;
+typedef struct hdsp_version hdsp_version_t;
+typedef struct hdsp_mixer hdsp_mixer_t;
+typedef struct hdsp_9632_aeb hdsp_9632_aeb_t;
 
 #endif /* __SOUND_HDSP_H */
diff --git a/include/sound/hdspm.h b/include/sound/hdspm.h
index c34427c..c3c854d 100644
--- a/include/sound/hdspm.h
+++ b/include/sound/hdspm.h
@@ -25,8 +25,6 @@
 
 /* -------------------- IOCTL Peak/RMS Meters -------------------- */
 
-typedef struct _snd_hdspm_peak_rms hdspm_peak_rms_t;
-
 /* peam rms level structure like we get from hardware 
   
    maybe in future we can memory map it so I just copy it
@@ -36,7 +34,7 @@
    (i asume so from the code)
 */
 
-struct _snd_hdspm_peak_rms {
+struct hdspm_peak_rms {
 
 	unsigned int level_offset[1024];
 
@@ -58,18 +56,16 @@
 	unsigned int xxx_rms_h[64];	/* not used */
 };
 
-struct sndrv_hdspm_peak_rms_ioctl {
-	hdspm_peak_rms_t *peak;
+struct hdspm_peak_rms_ioctl {
+	struct hdspm_peak_rms *peak;
 };
 
 /* use indirect access due to the limit of ioctl bit size */
-#define SNDRV_HDSPM_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, struct sndrv_hdspm_peak_rms_ioctl)
+#define SNDRV_HDSPM_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, struct hdspm_peak_rms_ioctl)
 
 /* ------------ CONFIG block IOCTL ---------------------- */
 
-typedef struct _snd_hdspm_config_info hdspm_config_info_t;
-
-struct _snd_hdspm_config_info {
+struct hdspm_config_info {
 	unsigned char pref_sync_ref;
 	unsigned char wordclock_sync_check;
 	unsigned char madi_sync_check;
@@ -83,18 +79,16 @@
 	unsigned int analog_out;
 };
 
-#define SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdspm_config_info_t)
+#define SNDRV_HDSPM_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, struct hdspm_config_info)
 
 
 /* get Soundcard Version */
 
-typedef struct _snd_hdspm_version hdspm_version_t;
-
-struct _snd_hdspm_version {
+struct hdspm_version {
 	unsigned short firmware_rev;
 };
 
-#define SNDRV_HDSPM_IOCTL_GET_VERSION _IOR('H', 0x43, hdspm_version_t)
+#define SNDRV_HDSPM_IOCTL_GET_VERSION _IOR('H', 0x43, struct hdspm_version)
 
 
 /* ------------- get Matrix Mixer IOCTL --------------- */
@@ -108,24 +102,27 @@
 
 #define HDSPM_MIXER_CHANNELS HDSPM_MAX_CHANNELS
 
-typedef struct _snd_hdspm_channelfader snd_hdspm_channelfader_t;
-
-struct _snd_hdspm_channelfader {
+struct hdspm_channelfader {
 	unsigned int in[HDSPM_MIXER_CHANNELS];
 	unsigned int pb[HDSPM_MIXER_CHANNELS];
 };
 
-typedef struct _snd_hdspm_mixer hdspm_mixer_t;
-
-struct _snd_hdspm_mixer {
-	snd_hdspm_channelfader_t ch[HDSPM_MIXER_CHANNELS];
+struct hdspm_mixer {
+	struct hdspm_channelfader ch[HDSPM_MIXER_CHANNELS];
 };
 
-struct sndrv_hdspm_mixer_ioctl {
-	hdspm_mixer_t *mixer;
+struct hdspm_mixer_ioctl {
+	struct hdspm_mixer *mixer;
 };
 
 /* use indirect access due to the limit of ioctl bit size */
-#define SNDRV_HDSPM_IOCTL_GET_MIXER _IOR('H', 0x44, struct sndrv_hdspm_mixer_ioctl)
+#define SNDRV_HDSPM_IOCTL_GET_MIXER _IOR('H', 0x44, struct hdspm_mixer_ioctl)
+
+/* typedefs for compatibility to user-space */
+typedef struct hdspm_peak_rms hdspm_peak_rms_t;
+typedef struct hdspm_config_info hdspm_config_info_t;
+typedef struct hdspm_version hdspm_version_t;
+typedef struct hdspm_channelfader snd_hdspm_channelfader_t;
+typedef struct hdspm_mixer hdspm_mixer_t;
 
 #endif				/* __SOUND_HDSPM_H */
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h
index 0438763..c679e5b 100644
--- a/include/sound/hwdep.h
+++ b/include/sound/hwdep.h
@@ -25,27 +25,25 @@
 #include <sound/asound.h>
 #include <linux/poll.h>
 
-typedef enum sndrv_hwdep_iface snd_hwdep_iface_t;
-typedef struct sndrv_hwdep_info snd_hwdep_info_t;
-typedef struct sndrv_hwdep_dsp_status snd_hwdep_dsp_status_t;
-typedef struct sndrv_hwdep_dsp_image snd_hwdep_dsp_image_t;
+struct snd_hwdep;
 
-typedef struct _snd_hwdep_ops {
-	long long (*llseek) (snd_hwdep_t *hw, struct file * file, long long offset, int orig);
-	long (*read) (snd_hwdep_t * hw, char __user *buf, long count, loff_t *offset);
-	long (*write) (snd_hwdep_t * hw, const char __user *buf, long count, loff_t *offset);
-	int (*open) (snd_hwdep_t * hw, struct file * file);
-	int (*release) (snd_hwdep_t * hw, struct file * file);
-	unsigned int (*poll) (snd_hwdep_t * hw, struct file * file, poll_table * wait);
-	int (*ioctl) (snd_hwdep_t * hw, struct file * file, unsigned int cmd, unsigned long arg);
-	int (*ioctl_compat) (snd_hwdep_t * hw, struct file * file, unsigned int cmd, unsigned long arg);
-	int (*mmap) (snd_hwdep_t * hw, struct file * file, struct vm_area_struct * vma);
-	int (*dsp_status) (snd_hwdep_t * hw, snd_hwdep_dsp_status_t * status);
-	int (*dsp_load) (snd_hwdep_t * hw, snd_hwdep_dsp_image_t * image);
-} snd_hwdep_ops_t;
+struct snd_hwdep_ops {
+	long long (*llseek) (struct snd_hwdep *hw, struct file * file, long long offset, int orig);
+	long (*read) (struct snd_hwdep *hw, char __user *buf, long count, loff_t *offset);
+	long (*write) (struct snd_hwdep *hw, const char __user *buf, long count, loff_t *offset);
+	int (*open) (struct snd_hwdep * hw, struct file * file);
+	int (*release) (struct snd_hwdep *hw, struct file * file);
+	unsigned int (*poll) (struct snd_hwdep *hw, struct file * file, poll_table * wait);
+	int (*ioctl) (struct snd_hwdep *hw, struct file * file, unsigned int cmd, unsigned long arg);
+	int (*ioctl_compat) (struct snd_hwdep *hw, struct file * file, unsigned int cmd, unsigned long arg);
+	int (*mmap) (struct snd_hwdep *hw, struct file * file, struct vm_area_struct * vma);
+	int (*dsp_status) (struct snd_hwdep *hw, struct snd_hwdep_dsp_status *status);
+	int (*dsp_load) (struct snd_hwdep *hw, struct snd_hwdep_dsp_image *image);
+};
 
-struct _snd_hwdep {
-	snd_card_t *card;
+struct snd_hwdep {
+	struct snd_card *card;
+	struct list_head list;
 	int device;
 	char id[32];
 	char name[80];
@@ -57,10 +55,10 @@
 	int ossreg;
 #endif
 
-	snd_hwdep_ops_t ops;
+	struct snd_hwdep_ops ops;
 	wait_queue_head_t open_wait;
 	void *private_data;
-	void (*private_free) (snd_hwdep_t *hwdep);
+	void (*private_free) (struct snd_hwdep *hwdep);
 
 	struct semaphore open_mutex;
 	int used;
@@ -68,6 +66,7 @@
 	unsigned int exclusive: 1;
 };
 
-extern int snd_hwdep_new(snd_card_t * card, char *id, int device, snd_hwdep_t ** rhwdep);
+extern int snd_hwdep_new(struct snd_card *card, char *id, int device,
+			 struct snd_hwdep **rhwdep);
 
 #endif /* __SOUND_HWDEP_H */
diff --git a/include/sound/i2c.h b/include/sound/i2c.h
index a665ddf..81eb23e 100644
--- a/include/sound/i2c.h
+++ b/include/sound/i2c.h
@@ -21,82 +21,84 @@
  *
  */
 
-typedef struct _snd_i2c_device snd_i2c_device_t;
-typedef struct _snd_i2c_bus snd_i2c_bus_t;
-
 #define SND_I2C_DEVICE_ADDRTEN	(1<<0)	/* 10-bit I2C address */
 
-struct _snd_i2c_device {
+struct snd_i2c_device {
 	struct list_head list;
-	snd_i2c_bus_t *bus;	/* I2C bus */
+	struct snd_i2c_bus *bus;	/* I2C bus */
 	char name[32];		/* some useful device name */
 	unsigned short flags;	/* device flags */
 	unsigned short addr;	/* device address (might be 10-bit) */
 	unsigned long private_value;
 	void *private_data;
-	void (*private_free)(snd_i2c_device_t *device);
+	void (*private_free)(struct snd_i2c_device *device);
 };
 
-#define snd_i2c_device(n) list_entry(n, snd_i2c_device_t, list)
+#define snd_i2c_device(n) list_entry(n, struct snd_i2c_device, list)
 
-typedef struct _snd_i2c_bit_ops {
-	void (*start)(snd_i2c_bus_t *bus);	/* transfer start */
-	void (*stop)(snd_i2c_bus_t *bus);	/* transfer stop */
-	void (*direction)(snd_i2c_bus_t *bus, int clock, int data);  /* set line direction (0 = write, 1 = read) */
-	void (*setlines)(snd_i2c_bus_t *bus, int clock, int data);
-	int (*getclock)(snd_i2c_bus_t *bus);
-	int (*getdata)(snd_i2c_bus_t *bus, int ack);
-} snd_i2c_bit_ops_t;
+struct snd_i2c_bit_ops {
+	void (*start)(struct snd_i2c_bus *bus);	/* transfer start */
+	void (*stop)(struct snd_i2c_bus *bus);	/* transfer stop */
+	void (*direction)(struct snd_i2c_bus *bus, int clock, int data);  /* set line direction (0 = write, 1 = read) */
+	void (*setlines)(struct snd_i2c_bus *bus, int clock, int data);
+	int (*getclock)(struct snd_i2c_bus *bus);
+	int (*getdata)(struct snd_i2c_bus *bus, int ack);
+};
 
-typedef struct _snd_i2c_ops {
-	int (*sendbytes)(snd_i2c_device_t *device, unsigned char *bytes, int count);
-	int (*readbytes)(snd_i2c_device_t *device, unsigned char *bytes, int count);
-	int (*probeaddr)(snd_i2c_bus_t *bus, unsigned short addr);
-} snd_i2c_ops_t;
+struct snd_i2c_ops {
+	int (*sendbytes)(struct snd_i2c_device *device, unsigned char *bytes, int count);
+	int (*readbytes)(struct snd_i2c_device *device, unsigned char *bytes, int count);
+	int (*probeaddr)(struct snd_i2c_bus *bus, unsigned short addr);
+};
 
-struct _snd_i2c_bus {
-	snd_card_t *card;	/* card which I2C belongs to */
+struct snd_i2c_bus {
+	struct snd_card *card;	/* card which I2C belongs to */
 	char name[32];		/* some useful label */
 
 	struct semaphore lock_mutex;
 
-	snd_i2c_bus_t *master;	/* master bus when SCK/SCL is shared */
+	struct snd_i2c_bus *master;	/* master bus when SCK/SCL is shared */
 	struct list_head buses;	/* master: slave buses sharing SCK/SCL, slave: link list */
 
 	struct list_head devices; /* attached devices to this bus */
 
 	union {
-		snd_i2c_bit_ops_t *bit;
+		struct snd_i2c_bit_ops *bit;
 		void *ops;
 	} hw_ops;		/* lowlevel operations */
-	snd_i2c_ops_t *ops;	/* midlevel operations */
+	struct snd_i2c_ops *ops;	/* midlevel operations */
 
 	unsigned long private_value;
 	void *private_data;
-	void (*private_free)(snd_i2c_bus_t *bus);
+	void (*private_free)(struct snd_i2c_bus *bus);
 };
 
-#define snd_i2c_slave_bus(n) list_entry(n, snd_i2c_bus_t, buses)
+#define snd_i2c_slave_bus(n) list_entry(n, struct snd_i2c_bus, buses)
 
-int snd_i2c_bus_create(snd_card_t *card, const char *name, snd_i2c_bus_t *master, snd_i2c_bus_t **ri2c);
-int snd_i2c_device_create(snd_i2c_bus_t *bus, const char *name, unsigned char addr, snd_i2c_device_t **rdevice);
-int snd_i2c_device_free(snd_i2c_device_t *device);
+int snd_i2c_bus_create(struct snd_card *card, const char *name,
+		       struct snd_i2c_bus *master, struct snd_i2c_bus **ri2c);
+int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
+			  unsigned char addr, struct snd_i2c_device **rdevice);
+int snd_i2c_device_free(struct snd_i2c_device *device);
 
-static inline void snd_i2c_lock(snd_i2c_bus_t *bus) {
+static inline void snd_i2c_lock(struct snd_i2c_bus *bus)
+{
 	if (bus->master)
 		down(&bus->master->lock_mutex);
 	else
 		down(&bus->lock_mutex);
 }
-static inline void snd_i2c_unlock(snd_i2c_bus_t *bus) {
+
+static inline void snd_i2c_unlock(struct snd_i2c_bus *bus)
+{
 	if (bus->master)
 		up(&bus->master->lock_mutex);
 	else
 		up(&bus->lock_mutex);
 }
 
-int snd_i2c_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count);
-int snd_i2c_readbytes(snd_i2c_device_t *device, unsigned char *bytes, int count);
-int snd_i2c_probeaddr(snd_i2c_bus_t *bus, unsigned short addr);
+int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count);
+int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count);
+int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr);
 
 #endif /* __SOUND_I2C_H */
diff --git a/include/sound/info.h b/include/sound/info.h
index 1d76bf3..8ea5c74 100644
--- a/include/sound/info.h
+++ b/include/sound/info.h
@@ -34,8 +34,6 @@
 	int error;		/* error code */
 };
 
-typedef struct snd_info_buffer snd_info_buffer_t;
-
 #define SNDRV_INFO_CONTENT_TEXT		0
 #define SNDRV_INFO_CONTENT_DATA		1
 
@@ -44,28 +42,28 @@
 struct snd_info_entry_text {
 	unsigned long read_size;
 	unsigned long write_size;
-	void (*read) (snd_info_entry_t *entry, snd_info_buffer_t * buffer);
-	void (*write) (snd_info_entry_t *entry, snd_info_buffer_t * buffer);
+	void (*read) (struct snd_info_entry *entry, struct snd_info_buffer *buffer);
+	void (*write) (struct snd_info_entry *entry, struct snd_info_buffer *buffer);
 };
 
 struct snd_info_entry_ops {
-	int (*open) (snd_info_entry_t *entry,
+	int (*open) (struct snd_info_entry *entry,
 		     unsigned short mode, void **file_private_data);
-	int (*release) (snd_info_entry_t * entry,
+	int (*release) (struct snd_info_entry * entry,
 			unsigned short mode, void *file_private_data);
-	long (*read) (snd_info_entry_t *entry, void *file_private_data,
+	long (*read) (struct snd_info_entry *entry, void *file_private_data,
 		      struct file * file, char __user *buf,
 		      unsigned long count, unsigned long pos);
-	long (*write) (snd_info_entry_t *entry, void *file_private_data,
+	long (*write) (struct snd_info_entry *entry, void *file_private_data,
 		       struct file * file, const char __user *buf,
 		       unsigned long count, unsigned long pos);
-	long long (*llseek) (snd_info_entry_t *entry, void *file_private_data,
+	long long (*llseek) (struct snd_info_entry *entry, void *file_private_data,
 			    struct file * file, long long offset, int orig);
-	unsigned int (*poll) (snd_info_entry_t *entry, void *file_private_data,
+	unsigned int (*poll) (struct snd_info_entry *entry, void *file_private_data,
 			      struct file * file, poll_table * wait);
-	int (*ioctl) (snd_info_entry_t *entry, void *file_private_data,
+	int (*ioctl) (struct snd_info_entry *entry, void *file_private_data,
 		      struct file * file, unsigned int cmd, unsigned long arg);
-	int (*mmap) (snd_info_entry_t *entry, void *file_private_data,
+	int (*mmap) (struct snd_info_entry *entry, void *file_private_data,
 		     struct inode * inode, struct file * file,
 		     struct vm_area_struct * vma);
 };
@@ -80,20 +78,18 @@
 		struct snd_info_entry_text text;
 		struct snd_info_entry_ops *ops;
 	} c;
-	snd_info_entry_t *parent;
-	snd_card_t *card;
+	struct snd_info_entry *parent;
+	struct snd_card *card;
 	struct module *module;
 	void *private_data;
-	void (*private_free)(snd_info_entry_t *entry);
+	void (*private_free)(struct snd_info_entry *entry);
 	struct proc_dir_entry *p;
 	struct semaphore access;
 };
 
-extern int snd_info_check_reserved_words(const char *str);
-
 #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
-extern int snd_info_minor_register(void);
-extern int snd_info_minor_unregister(void);
+int snd_info_minor_register(void);
+int snd_info_minor_unregister(void);
 #else
 #define snd_info_minor_register() /* NOP */
 #define snd_info_minor_unregister() /* NOP */
@@ -102,72 +98,79 @@
 
 #ifdef CONFIG_PROC_FS
 
-extern snd_info_entry_t *snd_seq_root;
+extern struct snd_info_entry *snd_seq_root;
 #ifdef CONFIG_SND_OSSEMUL
-extern snd_info_entry_t *snd_oss_root;
+extern struct snd_info_entry *snd_oss_root;
 #else
 #define snd_oss_root NULL
 #endif
 
-int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...) __attribute__ ((format (printf, 2, 3)));
+int snd_iprintf(struct snd_info_buffer * buffer, char *fmt,...) __attribute__ ((format (printf, 2, 3)));
 int snd_info_init(void);
 int snd_info_done(void);
 
-int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len);
+int snd_info_get_line(struct snd_info_buffer * buffer, char *line, int len);
 char *snd_info_get_str(char *dest, char *src, int len);
-snd_info_entry_t *snd_info_create_module_entry(struct module * module,
+struct snd_info_entry *snd_info_create_module_entry(struct module * module,
 					       const char *name,
-					       snd_info_entry_t * parent);
-snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card,
+					       struct snd_info_entry * parent);
+struct snd_info_entry *snd_info_create_card_entry(struct snd_card * card,
 					     const char *name,
-					     snd_info_entry_t * parent);
-void snd_info_free_entry(snd_info_entry_t * entry);
-int snd_info_store_text(snd_info_entry_t * entry);
-int snd_info_restore_text(snd_info_entry_t * entry);
+					     struct snd_info_entry * parent);
+void snd_info_free_entry(struct snd_info_entry * entry);
+int snd_info_store_text(struct snd_info_entry * entry);
+int snd_info_restore_text(struct snd_info_entry * entry);
 
-int snd_info_card_create(snd_card_t * card);
-int snd_info_card_register(snd_card_t * card);
-int snd_info_card_free(snd_card_t * card);
-int snd_info_register(snd_info_entry_t * entry);
-int snd_info_unregister(snd_info_entry_t * entry);
+int snd_info_card_create(struct snd_card * card);
+int snd_info_card_register(struct snd_card * card);
+int snd_info_card_free(struct snd_card * card);
+int snd_info_register(struct snd_info_entry * entry);
+int snd_info_unregister(struct snd_info_entry * entry);
 
 /* for card drivers */
-int snd_card_proc_new(snd_card_t *card, const char *name, snd_info_entry_t **entryp);
+int snd_card_proc_new(struct snd_card *card, const char *name, struct snd_info_entry **entryp);
 
-static inline void snd_info_set_text_ops(snd_info_entry_t *entry, 
+static inline void snd_info_set_text_ops(struct snd_info_entry *entry, 
 					 void *private_data,
 					 long read_size,
-					 void (*read)(snd_info_entry_t *, snd_info_buffer_t *))
+					 void (*read)(struct snd_info_entry *, struct snd_info_buffer *))
 {
 	entry->private_data = private_data;
 	entry->c.text.read_size = read_size;
 	entry->c.text.read = read;
 }
 
+int snd_info_check_reserved_words(const char *str);
 
 #else
 
 #define snd_seq_root NULL
 #define snd_oss_root NULL
 
-static inline int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...) { return 0; }
+static inline int snd_iprintf(struct snd_info_buffer * buffer, char *fmt,...) { return 0; }
 static inline int snd_info_init(void) { return 0; }
 static inline int snd_info_done(void) { return 0; }
 
-static inline int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len) { return 0; }
+static inline int snd_info_get_line(struct snd_info_buffer * buffer, char *line, int len) { return 0; }
 static inline char *snd_info_get_str(char *dest, char *src, int len) { return NULL; }
-static inline snd_info_entry_t *snd_info_create_module_entry(struct module * module, const char *name, snd_info_entry_t * parent) { return NULL; }
-static inline snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card, const char *name, snd_info_entry_t * parent) { return NULL; }
-static inline void snd_info_free_entry(snd_info_entry_t * entry) { ; }
+static inline struct snd_info_entry *snd_info_create_module_entry(struct module * module, const char *name, struct snd_info_entry * parent) { return NULL; }
+static inline struct snd_info_entry *snd_info_create_card_entry(struct snd_card * card, const char *name, struct snd_info_entry * parent) { return NULL; }
+static inline void snd_info_free_entry(struct snd_info_entry * entry) { ; }
 
-static inline int snd_info_card_create(snd_card_t * card) { return 0; }
-static inline int snd_info_card_register(snd_card_t * card) { return 0; }
-static inline int snd_info_card_free(snd_card_t * card) { return 0; }
-static inline int snd_info_register(snd_info_entry_t * entry) { return 0; }
-static inline int snd_info_unregister(snd_info_entry_t * entry) { return 0; }
+static inline int snd_info_card_create(struct snd_card * card) { return 0; }
+static inline int snd_info_card_register(struct snd_card * card) { return 0; }
+static inline int snd_info_card_free(struct snd_card * card) { return 0; }
+static inline int snd_info_register(struct snd_info_entry * entry) { return 0; }
+static inline int snd_info_unregister(struct snd_info_entry * entry) { return 0; }
 
-#define snd_card_proc_new(card,name,entryp)  0 /* always success */
-#define snd_info_set_text_ops(entry,private_data,read_size,read) /*NOP*/
+static inline int snd_card_proc_new(struct snd_card *card, const char *name,
+				    struct snd_info_entry **entryp) { return -EINVAL; }
+static inline void snd_info_set_text_ops(struct snd_info_entry *entry __attribute__((unused)),
+					 void *private_data,
+					 long read_size,
+					 void (*read)(struct snd_info_entry *, struct snd_info_buffer *)) {}
+
+static inline int snd_info_check_reserved_words(const char *str) { return 1; }
 
 #endif
 
@@ -185,7 +188,7 @@
 
 #define SNDRV_OSS_INFO_DEV_COUNT	6
 
-extern int snd_oss_info_register(int dev, int num, char *string);
+int snd_oss_info_register(int dev, int num, char *string);
 #define snd_oss_info_unregister(dev, num) snd_oss_info_register(dev, num, NULL)
 
 #endif /* CONFIG_SND_OSSEMUL && CONFIG_PROC_FS */
diff --git a/include/sound/initval.h b/include/sound/initval.h
index 2bf1508..d29e3d3 100644
--- a/include/sound/initval.h
+++ b/include/sound/initval.h
@@ -50,20 +50,6 @@
 #define SNDRV_DEFAULT_DMA_SIZE	{ [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_DMA_SIZE }
 #define SNDRV_DEFAULT_PTR	SNDRV_DEFAULT_STR
 
-#ifdef SNDRV_LEGACY_AUTO_PROBE
-static int snd_legacy_auto_probe(unsigned long *ports, int (*probe)(unsigned long port))
-{
-	int result = 0;	/* number of detected cards */
-
-	while ((signed long)*ports != -1) {
-		if (probe(*ports) >= 0)
-			result++;
-		ports++;
-	}
-	return result;
-}
-#endif
-
 #ifdef SNDRV_LEGACY_FIND_FREE_IRQ
 #include <linux/interrupt.h>
 
diff --git a/include/sound/minors.h b/include/sound/minors.h
index a17b5c9..46bcd20 100644
--- a/include/sound/minors.h
+++ b/include/sound/minors.h
@@ -26,18 +26,20 @@
 #define SNDRV_MINOR_DEVICE(minor)	((minor) & 0x001f)
 #define SNDRV_MINOR(card, dev)		(((card) << 5) | (dev))
 
-#define SNDRV_MINOR_CONTROL		0	/* 0 - 0 */
+/* these minors can still be used for autoloading devices (/dev/aload*) */
+#define SNDRV_MINOR_CONTROL		0	/* 0 */
 #define SNDRV_MINOR_GLOBAL		1	/* 1 */
 #define SNDRV_MINOR_SEQUENCER		(SNDRV_MINOR_GLOBAL + 0 * 32)
 #define SNDRV_MINOR_TIMER		(SNDRV_MINOR_GLOBAL + 1 * 32)
+
+#ifndef CONFIG_SND_DYNAMIC_MINORS
+						/* 2 - 3 (reserved) */
 #define SNDRV_MINOR_HWDEP		4	/* 4 - 7 */
-#define SNDRV_MINOR_HWDEPS		4
 #define SNDRV_MINOR_RAWMIDI		8	/* 8 - 15 */
-#define SNDRV_MINOR_RAWMIDIS		8
 #define SNDRV_MINOR_PCM_PLAYBACK	16	/* 16 - 23 */
 #define SNDRV_MINOR_PCM_CAPTURE		24	/* 24 - 31 */
-#define SNDRV_MINOR_PCMS		8
 
+/* same as first respective minor number to make minor allocation easier */
 #define SNDRV_DEVICE_TYPE_CONTROL	SNDRV_MINOR_CONTROL
 #define SNDRV_DEVICE_TYPE_HWDEP		SNDRV_MINOR_HWDEP
 #define SNDRV_DEVICE_TYPE_RAWMIDI	SNDRV_MINOR_RAWMIDI
@@ -46,6 +48,25 @@
 #define SNDRV_DEVICE_TYPE_SEQUENCER	SNDRV_MINOR_SEQUENCER
 #define SNDRV_DEVICE_TYPE_TIMER		SNDRV_MINOR_TIMER
 
+#else /* CONFIG_SND_DYNAMIC_MINORS */
+
+enum {
+	SNDRV_DEVICE_TYPE_CONTROL,
+	SNDRV_DEVICE_TYPE_SEQUENCER,
+	SNDRV_DEVICE_TYPE_TIMER,
+	SNDRV_DEVICE_TYPE_HWDEP,
+	SNDRV_DEVICE_TYPE_RAWMIDI,
+	SNDRV_DEVICE_TYPE_PCM_PLAYBACK,
+	SNDRV_DEVICE_TYPE_PCM_CAPTURE,
+};
+
+#endif /* CONFIG_SND_DYNAMIC_MINORS */
+
+#define SNDRV_MINOR_HWDEPS		4
+#define SNDRV_MINOR_RAWMIDIS		8
+#define SNDRV_MINOR_PCMS		8
+
+
 #ifdef CONFIG_SND_OSSEMUL
 
 #define SNDRV_MINOR_OSS_DEVICES		16
diff --git a/include/sound/mixer_oss.h b/include/sound/mixer_oss.h
index ed75b2f..ca5b482 100644
--- a/include/sound/mixer_oss.h
+++ b/include/sound/mixer_oss.h
@@ -24,51 +24,53 @@
 
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 
-typedef struct _snd_oss_mixer_slot snd_mixer_oss_slot_t;
-typedef struct _snd_oss_file snd_mixer_oss_file_t;
-
-typedef int (*snd_mixer_oss_get_volume_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int *left, int *right);
-typedef int (*snd_mixer_oss_put_volume_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int left, int right);
-typedef int (*snd_mixer_oss_get_recsrc_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int *active);
-typedef int (*snd_mixer_oss_put_recsrc_t)(snd_mixer_oss_file_t *fmixer, snd_mixer_oss_slot_t *chn, int active);
-typedef int (*snd_mixer_oss_get_recsrce_t)(snd_mixer_oss_file_t *fmixer, unsigned int *active_index);
-typedef int (*snd_mixer_oss_put_recsrce_t)(snd_mixer_oss_file_t *fmixer, unsigned int active_index);
-
 #define SNDRV_OSS_MAX_MIXERS	32
 
-struct _snd_oss_mixer_slot {
+struct snd_mixer_oss_file;
+
+struct snd_mixer_oss_slot {
 	int number;
 	unsigned int stereo: 1;
-	snd_mixer_oss_get_volume_t get_volume;
-	snd_mixer_oss_put_volume_t put_volume;
-	snd_mixer_oss_get_recsrc_t get_recsrc;
-	snd_mixer_oss_put_recsrc_t put_recsrc;
+	int (*get_volume)(struct snd_mixer_oss_file *fmixer,
+			  struct snd_mixer_oss_slot *chn,
+			  int *left, int *right);
+	int (*put_volume)(struct snd_mixer_oss_file *fmixer,
+			  struct snd_mixer_oss_slot *chn,
+			  int left, int right);
+	int (*get_recsrc)(struct snd_mixer_oss_file *fmixer,
+			  struct snd_mixer_oss_slot *chn,
+			  int *active);
+	int (*put_recsrc)(struct snd_mixer_oss_file *fmixer,
+			  struct snd_mixer_oss_slot *chn,
+			  int active);
 	unsigned long private_value;
 	void *private_data;
-	void (*private_free)(snd_mixer_oss_slot_t *slot);
+	void (*private_free)(struct snd_mixer_oss_slot *slot);
 	int volume[2];
 };
 
-struct _snd_oss_mixer {
-	snd_card_t *card;
+struct snd_mixer_oss {
+	struct snd_card *card;
 	char id[16];
 	char name[32];
-	snd_mixer_oss_slot_t slots[SNDRV_OSS_MAX_MIXERS]; /* OSS mixer slots */
+	struct snd_mixer_oss_slot slots[SNDRV_OSS_MAX_MIXERS]; /* OSS mixer slots */
 	unsigned int mask_recsrc;		/* exclusive recsrc mask */
-	snd_mixer_oss_get_recsrce_t get_recsrc;
-	snd_mixer_oss_put_recsrce_t put_recsrc;
+	int (*get_recsrc)(struct snd_mixer_oss_file *fmixer,
+			  unsigned int *active_index);
+	int (*put_recsrc)(struct snd_mixer_oss_file *fmixer,
+			  unsigned int active_index);
 	void *private_data_recsrc;
-	void (*private_free_recsrc)(snd_mixer_oss_t *mixer);
+	void (*private_free_recsrc)(struct snd_mixer_oss *mixer);
 	struct semaphore reg_mutex;
-	snd_info_entry_t *proc_entry;
+	struct snd_info_entry *proc_entry;
 	int oss_dev_alloc;
 	/* --- */
 	int oss_recsrc;
 };
 
-struct _snd_oss_file {
-	snd_card_t *card;
-	snd_mixer_oss_t *mixer;
+struct snd_mixer_oss_file {
+	struct snd_card *card;
+	struct snd_mixer_oss *mixer;
 };
 
 #endif /* CONFIG_SND_MIXER_OSS */
diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h
index ae39e38..8e97ace 100644
--- a/include/sound/mpu401.h
+++ b/include/sound/mpu401.h
@@ -58,10 +58,8 @@
 #define MPU401_MODE_INPUT_TIMER		(1<<0)
 #define MPU401_MODE_OUTPUT_TIMER	(1<<1)
 
-typedef struct _snd_mpu401 mpu401_t;
-
-struct _snd_mpu401 {
-	snd_rawmidi_t *rmidi;
+struct snd_mpu401 {
+	struct snd_rawmidi *rmidi;
 
 	unsigned short hardware;	/* MPU401_HW_XXXX */
 	unsigned long port;		/* base port of MPU-401 chip */
@@ -73,14 +71,14 @@
 	unsigned long mode;		/* MPU401_MODE_XXXX */
 	int timer_invoked;
 
-	int (*open_input) (mpu401_t * mpu);
-	void (*close_input) (mpu401_t * mpu);
-	int (*open_output) (mpu401_t * mpu);
-	void (*close_output) (mpu401_t * mpu);
+	int (*open_input) (struct snd_mpu401 * mpu);
+	void (*close_input) (struct snd_mpu401 * mpu);
+	int (*open_output) (struct snd_mpu401 * mpu);
+	void (*close_output) (struct snd_mpu401 * mpu);
 	void *private_data;
 
-	snd_rawmidi_substream_t *substream_input;
-	snd_rawmidi_substream_t *substream_output;
+	struct snd_rawmidi_substream *substream_input;
+	struct snd_rawmidi_substream *substream_output;
 
 	spinlock_t input_lock;
 	spinlock_t output_lock;
@@ -88,8 +86,8 @@
 	
 	struct timer_list timer;
 
-	void (*write) (mpu401_t * mpu, unsigned char data, unsigned long addr);
-	unsigned char (*read) (mpu401_t * mpu, unsigned long addr);
+	void (*write) (struct snd_mpu401 * mpu, unsigned char data, unsigned long addr);
+	unsigned char (*read) (struct snd_mpu401 *mpu, unsigned long addr);
 };
 
 /* I/O ports */
@@ -103,13 +101,13 @@
 
 irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
-int snd_mpu401_uart_new(snd_card_t * card,
+int snd_mpu401_uart_new(struct snd_card *card,
 			int device,
 			unsigned short hardware,
 			unsigned long port,
 			int integrated,
 			int irq,
 			int irq_flags,
-			snd_rawmidi_t ** rrawmidi);
+			struct snd_rawmidi ** rrawmidi);
 
 #endif /* __SOUND_MPU401_H */
diff --git a/include/sound/opl3.h b/include/sound/opl3.h
index 19f657d..8339264 100644
--- a/include/sound/opl3.h
+++ b/include/sound/opl3.h
@@ -237,12 +237,12 @@
 #define MAX_OPL2_VOICES		9
 #define MAX_OPL3_VOICES		18
 
-typedef struct snd_opl3 opl3_t;
+struct snd_opl3;
 
 /*
  * A structure to keep track of each hardware voice
  */
-typedef struct snd_opl3_voice {
+struct snd_opl3_voice {
 	int  state;		/* status */
 #define SNDRV_OPL3_ST_OFF		0	/* Not playing */
 #define SNDRV_OPL3_ST_ON_2OP	1	/* 2op voice is allocated */
@@ -257,8 +257,8 @@
 
 	unsigned char keyon_reg;	/* KON register shadow */
 
-	snd_midi_channel_t *chan;	/* Midi channel for this note */
-} snd_opl3_voice_t;
+	struct snd_midi_channel *chan;	/* Midi channel for this note */
+};
 
 struct snd_opl3 {
 	unsigned long l_port;
@@ -267,18 +267,18 @@
 	struct resource *res_r_port;
 	unsigned short hardware;
 	/* hardware access */
-	void (*command) (opl3_t * opl3, unsigned short cmd, unsigned char val);
+	void (*command) (struct snd_opl3 * opl3, unsigned short cmd, unsigned char val);
 	unsigned short timer_enable;
 	int seq_dev_num;	/* sequencer device number */
-	snd_timer_t *timer1;
-	snd_timer_t *timer2;
+	struct snd_timer *timer1;
+	struct snd_timer *timer2;
 	spinlock_t timer_lock;
 
 	void *private_data;
-	void (*private_free)(opl3_t *);
+	void (*private_free)(struct snd_opl3 *);
 
 	spinlock_t reg_lock;
-	snd_card_t *card;		/* The card that this belongs to */
+	struct snd_card *card;		/* The card that this belongs to */
 	int used;			/* usage flag - exclusive */
 	unsigned char fm_mode;		/* OPL mode, see SNDRV_DM_FM_MODE_XXX */
 	unsigned char rhythm;		/* percussion mode flag */
@@ -289,18 +289,18 @@
 	int synth_mode;			/* synth mode */
 	int seq_client;
 
-	snd_seq_device_t *seq_dev;	/* sequencer device */
-	snd_midi_channel_set_t * chset;
+	struct snd_seq_device *seq_dev;	/* sequencer device */
+	struct snd_midi_channel_set * chset;
 
 #ifdef CONFIG_SND_SEQUENCER_OSS
-	snd_seq_device_t *oss_seq_dev;	/* OSS sequencer device */
-	snd_midi_channel_set_t * oss_chset;
+	struct snd_seq_device *oss_seq_dev;	/* OSS sequencer device */
+	struct snd_midi_channel_set * oss_chset;
 #endif
  
-	snd_seq_kinstr_ops_t fm_ops;
-	snd_seq_kinstr_list_t *ilist;
+	struct snd_seq_kinstr_ops fm_ops;
+	struct snd_seq_kinstr_list *ilist;
 
-	snd_opl3_voice_t voices[MAX_OPL3_VOICES]; /* Voices (OPL3 'channel') */
+	struct snd_opl3_voice voices[MAX_OPL3_VOICES]; /* Voices (OPL3 'channel') */
 	int use_time;			/* allocation counter */
 
 	unsigned short connection_reg;	/* connection reg shadow */
@@ -316,24 +316,25 @@
 };
 
 /* opl3.c */
-void snd_opl3_interrupt(snd_hwdep_t * hw);
-int snd_opl3_new(snd_card_t *card, unsigned short hardware, opl3_t **ropl3);
-int snd_opl3_init(opl3_t *opl3);
-int snd_opl3_create(snd_card_t * card,
+void snd_opl3_interrupt(struct snd_hwdep * hw);
+int snd_opl3_new(struct snd_card *card, unsigned short hardware,
+		 struct snd_opl3 **ropl3);
+int snd_opl3_init(struct snd_opl3 *opl3);
+int snd_opl3_create(struct snd_card *card,
 		    unsigned long l_port, unsigned long r_port,
 		    unsigned short hardware,
 		    int integrated,
-		    opl3_t ** opl3);
-int snd_opl3_timer_new(opl3_t * opl3, int timer1_dev, int timer2_dev);
-int snd_opl3_hwdep_new(opl3_t * opl3, int device, int seq_device,
-		       snd_hwdep_t ** rhwdep);
+		    struct snd_opl3 ** opl3);
+int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev);
+int snd_opl3_hwdep_new(struct snd_opl3 * opl3, int device, int seq_device,
+		       struct snd_hwdep ** rhwdep);
 
 /* opl3_synth */
-int snd_opl3_open(snd_hwdep_t * hw, struct file *file);
-int snd_opl3_ioctl(snd_hwdep_t * hw, struct file *file,
+int snd_opl3_open(struct snd_hwdep * hw, struct file *file);
+int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
 		   unsigned int cmd, unsigned long arg);
-int snd_opl3_release(snd_hwdep_t * hw, struct file *file);
+int snd_opl3_release(struct snd_hwdep * hw, struct file *file);
 
-void snd_opl3_reset(opl3_t * opl3);
+void snd_opl3_reset(struct snd_opl3 * opl3);
 
 #endif /* __SOUND_OPL3_H */
diff --git a/include/sound/opl4.h b/include/sound/opl4.h
index 20c0442..60ae845 100644
--- a/include/sound/opl4.h
+++ b/include/sound/opl4.h
@@ -22,11 +22,11 @@
 
 #include <sound/opl3.h>
 
-typedef struct opl4 opl4_t;
+struct snd_opl4;
 
-extern int snd_opl4_create(snd_card_t *card,
+extern int snd_opl4_create(struct snd_card *card,
 			   unsigned long fm_port, unsigned long pcm_port,
 			   int seq_device,
-			   opl3_t **opl3, opl4_t **opl4);
+			   struct snd_opl3 **opl3, struct snd_opl4 **opl4);
 
 #endif /* __SOUND_OPL4_H */
diff --git a/include/sound/pcm-indirect.h b/include/sound/pcm-indirect.h
index 31fa7a5..7003d77 100644
--- a/include/sound/pcm-indirect.h
+++ b/include/sound/pcm-indirect.h
@@ -24,7 +24,7 @@
 
 #include <sound/pcm.h>
 
-typedef struct sndrv_pcm_indirect {
+struct snd_pcm_indirect {
 	unsigned int hw_buffer_size;	/* Byte size of hardware buffer */
 	unsigned int hw_queue_size;	/* Max queue size of hw buffer (0 = buffer size) */
 	unsigned int hw_data;	/* Offset to next dst (or src) in hw ring buffer */
@@ -35,20 +35,20 @@
 	unsigned int sw_io;	/* Current software pointer in bytes */
 	int sw_ready;		/* Bytes ready to be transferred to/from hw */
 	snd_pcm_uframes_t appl_ptr;	/* Last seen appl_ptr */
-} snd_pcm_indirect_t;
+};
 
-typedef void (*snd_pcm_indirect_copy_t)(snd_pcm_substream_t *substream,
-					snd_pcm_indirect_t *rec, size_t bytes);
+typedef void (*snd_pcm_indirect_copy_t)(struct snd_pcm_substream *substream,
+					struct snd_pcm_indirect *rec, size_t bytes);
 
 /*
  * helper function for playback ack callback
  */
 static inline void
-snd_pcm_indirect_playback_transfer(snd_pcm_substream_t *substream,
-				   snd_pcm_indirect_t *rec,
+snd_pcm_indirect_playback_transfer(struct snd_pcm_substream *substream,
+				   struct snd_pcm_indirect *rec,
 				   snd_pcm_indirect_copy_t copy)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
 	snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
 	int qsize;
@@ -89,8 +89,8 @@
  * ptr = current byte pointer
  */
 static inline snd_pcm_uframes_t
-snd_pcm_indirect_playback_pointer(snd_pcm_substream_t *substream,
-				  snd_pcm_indirect_t *rec, unsigned int ptr)
+snd_pcm_indirect_playback_pointer(struct snd_pcm_substream *substream,
+				  struct snd_pcm_indirect *rec, unsigned int ptr)
 {
 	int bytes = ptr - rec->hw_io;
 	if (bytes < 0)
@@ -110,11 +110,11 @@
  * helper function for capture ack callback
  */
 static inline void
-snd_pcm_indirect_capture_transfer(snd_pcm_substream_t *substream,
-				  snd_pcm_indirect_t *rec,
+snd_pcm_indirect_capture_transfer(struct snd_pcm_substream *substream,
+				  struct snd_pcm_indirect *rec,
 				  snd_pcm_indirect_copy_t copy)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
 	snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
 
@@ -154,8 +154,8 @@
  * ptr = current byte pointer
  */
 static inline snd_pcm_uframes_t
-snd_pcm_indirect_capture_pointer(snd_pcm_substream_t *substream,
-				 snd_pcm_indirect_t *rec, unsigned int ptr)
+snd_pcm_indirect_capture_pointer(struct snd_pcm_substream *substream,
+				 struct snd_pcm_indirect *rec, unsigned int ptr)
 {
 	int qsize;
 	int bytes = ptr - rec->hw_io;
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index acc4fa9..314268a 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -28,36 +28,9 @@
 #include <linux/poll.h>
 #include <linux/bitops.h>
 
-typedef sndrv_pcm_uframes_t snd_pcm_uframes_t;
-typedef sndrv_pcm_sframes_t snd_pcm_sframes_t;
-typedef enum sndrv_pcm_class snd_pcm_class_t;
-typedef enum sndrv_pcm_subclass snd_pcm_subclass_t;
-typedef enum sndrv_pcm_stream snd_pcm_stream_t;
-typedef enum sndrv_pcm_access snd_pcm_access_t;
-typedef enum sndrv_pcm_format snd_pcm_format_t;
-typedef enum sndrv_pcm_subformat snd_pcm_subformat_t;
-typedef enum sndrv_pcm_state snd_pcm_state_t;
-typedef union sndrv_pcm_sync_id snd_pcm_sync_id_t;
-typedef struct sndrv_pcm_info snd_pcm_info_t;
-typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t;
-typedef struct sndrv_pcm_hw_params snd_pcm_hw_params_t;
-typedef enum sndrv_pcm_start snd_pcm_start_t;
-typedef enum sndrv_pcm_xrun snd_pcm_xrun_t;
-typedef enum sndrv_pcm_tstamp snd_pcm_tstamp_t;
-typedef struct sndrv_pcm_sw_params snd_pcm_sw_params_t;
-typedef struct sndrv_pcm_channel_info snd_pcm_channel_info_t;
-typedef struct sndrv_pcm_status snd_pcm_status_t;
-typedef struct sndrv_pcm_mmap_status snd_pcm_mmap_status_t;
-typedef struct sndrv_pcm_mmap_control snd_pcm_mmap_control_t;
-typedef struct sndrv_mask snd_mask_t;
-typedef struct snd_sg_buf snd_pcm_sgbuf_t;
-
 #define snd_pcm_substream_chip(substream) ((substream)->private_data)
 #define snd_pcm_chip(pcm) ((pcm)->private_data)
 
-typedef struct _snd_pcm_file snd_pcm_file_t;
-typedef struct _snd_pcm_runtime snd_pcm_runtime_t;
-
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 #include "pcm_oss.h"
 #endif
@@ -66,7 +39,7 @@
  *  Hardware (lowlevel) section
  */
 
-typedef struct _snd_pcm_hardware {
+struct snd_pcm_hardware {
 	unsigned int info;		/* SNDRV_PCM_INFO_* */
 	u64 formats;			/* SNDRV_PCM_FMTBIT_* */
 	unsigned int rates;		/* SNDRV_PCM_RATE_* */
@@ -80,26 +53,29 @@
 	unsigned int periods_min;	/* min # of periods */
 	unsigned int periods_max;	/* max # of periods */
 	size_t fifo_size;		/* fifo size in bytes */
-} snd_pcm_hardware_t;
+};
 
-typedef struct _snd_pcm_ops {
-	int (*open)(snd_pcm_substream_t *substream);
-	int (*close)(snd_pcm_substream_t *substream);
-	int (*ioctl)(snd_pcm_substream_t * substream,
+struct snd_pcm_ops {
+	int (*open)(struct snd_pcm_substream *substream);
+	int (*close)(struct snd_pcm_substream *substream);
+	int (*ioctl)(struct snd_pcm_substream * substream,
 		     unsigned int cmd, void *arg);
-	int (*hw_params)(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * params);
-	int (*hw_free)(snd_pcm_substream_t *substream);
-	int (*prepare)(snd_pcm_substream_t * substream);
-	int (*trigger)(snd_pcm_substream_t * substream, int cmd);
-	snd_pcm_uframes_t (*pointer)(snd_pcm_substream_t * substream);
-	int (*copy)(snd_pcm_substream_t *substream, int channel, snd_pcm_uframes_t pos,
+	int (*hw_params)(struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *params);
+	int (*hw_free)(struct snd_pcm_substream *substream);
+	int (*prepare)(struct snd_pcm_substream *substream);
+	int (*trigger)(struct snd_pcm_substream *substream, int cmd);
+	snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *substream);
+	int (*copy)(struct snd_pcm_substream *substream, int channel,
+		    snd_pcm_uframes_t pos,
 		    void __user *buf, snd_pcm_uframes_t count);
-	int (*silence)(snd_pcm_substream_t *substream, int channel, 
+	int (*silence)(struct snd_pcm_substream *substream, int channel, 
 		       snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
-	struct page *(*page)(snd_pcm_substream_t *substream, unsigned long offset);
-	int (*mmap)(snd_pcm_substream_t *substream, struct vm_area_struct *vma);
-	int (*ack)(snd_pcm_substream_t *substream);
-} snd_pcm_ops_t;
+	struct page *(*page)(struct snd_pcm_substream *substream,
+			     unsigned long offset);
+	int (*mmap)(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
+	int (*ack)(struct snd_pcm_substream *substream);
+};
 
 /*
  *
@@ -212,17 +188,16 @@
 #define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE
 #endif
 
-struct _snd_pcm_file {
-	snd_pcm_substream_t * substream;
-	struct _snd_pcm_file * next;
+struct snd_pcm_file {
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_file *next;
 };
 
-typedef struct _snd_pcm_hw_rule snd_pcm_hw_rule_t;
+struct snd_pcm_hw_rule;
+typedef int (*snd_pcm_hw_rule_func_t)(struct snd_pcm_hw_params *params,
+				      struct snd_pcm_hw_rule *rule);
 
-typedef int (*snd_pcm_hw_rule_func_t)(snd_pcm_hw_params_t *params,
-				      snd_pcm_hw_rule_t *rule);
-
-struct _snd_pcm_hw_rule {
+struct snd_pcm_hw_rule {
 	unsigned int cond;
 	snd_pcm_hw_rule_func_t func;
 	int var;
@@ -230,57 +205,57 @@
 	void *private;
 };
 
-typedef struct _snd_pcm_hw_constraints {
-	snd_mask_t masks[SNDRV_PCM_HW_PARAM_LAST_MASK - 
+struct snd_pcm_hw_constraints {
+	struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - 
 			 SNDRV_PCM_HW_PARAM_FIRST_MASK + 1];
-	snd_interval_t intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
+	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL -
 			     SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
 	unsigned int rules_num;
 	unsigned int rules_all;
-	snd_pcm_hw_rule_t *rules;
-} snd_pcm_hw_constraints_t;
+	struct snd_pcm_hw_rule *rules;
+};
 
-static inline snd_mask_t *constrs_mask(snd_pcm_hw_constraints_t *constrs,
-				       snd_pcm_hw_param_t var)
+static inline struct snd_mask *constrs_mask(struct snd_pcm_hw_constraints *constrs,
+					    snd_pcm_hw_param_t var)
 {
 	return &constrs->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
 }
 
-static inline snd_interval_t *constrs_interval(snd_pcm_hw_constraints_t *constrs,
-					  snd_pcm_hw_param_t var)
+static inline struct snd_interval *constrs_interval(struct snd_pcm_hw_constraints *constrs,
+						    snd_pcm_hw_param_t var)
 {
 	return &constrs->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
 }
 
-typedef struct {
+struct snd_ratnum {
 	unsigned int num;
 	unsigned int den_min, den_max, den_step;
-} ratnum_t;
+};
 
-typedef struct {
+struct snd_ratden {
 	unsigned int num_min, num_max, num_step;
 	unsigned int den;
-} ratden_t;
+};
 
-typedef struct {
+struct snd_pcm_hw_constraint_ratnums {
 	int nrats;
-	ratnum_t *rats;
-} snd_pcm_hw_constraint_ratnums_t;
+	struct snd_ratnum *rats;
+};
 
-typedef struct {
+struct snd_pcm_hw_constraint_ratdens {
 	int nrats;
-	ratden_t *rats;
-} snd_pcm_hw_constraint_ratdens_t;
+	struct snd_ratden *rats;
+};
 
-typedef struct {
+struct snd_pcm_hw_constraint_list {
 	unsigned int count;
 	unsigned int *list;
 	unsigned int mask;
-} snd_pcm_hw_constraint_list_t;
+};
 
-struct _snd_pcm_runtime {
+struct snd_pcm_runtime {
 	/* -- Status -- */
-	snd_pcm_substream_t *trigger_master;
+	struct snd_pcm_substream *trigger_master;
 	struct timespec trigger_tstamp;	/* trigger timestamp */
 	int overrange;
 	snd_pcm_uframes_t avail_max;
@@ -306,7 +281,7 @@
 	unsigned int rate_den;
 
 	/* -- SW params -- */
-	snd_pcm_tstamp_t tstamp_mode;	/* mmap timestamp is updated */
+	int tstamp_mode;		/* mmap timestamp is updated */
   	unsigned int period_step;
 	unsigned int sleep_min;		/* min ticks to sleep */
 	snd_pcm_uframes_t xfer_align;	/* xfer size need to be a multiple */
@@ -320,11 +295,11 @@
 	snd_pcm_uframes_t silence_start; /* starting pointer to silence area */
 	snd_pcm_uframes_t silence_filled; /* size filled with silence */
 
-	snd_pcm_sync_id_t sync;		/* hardware synchronization ID */
+	union snd_pcm_sync_id sync;	/* hardware synchronization ID */
 
 	/* -- mmap -- */
-	volatile snd_pcm_mmap_status_t *status;
-	volatile snd_pcm_mmap_control_t *control;
+	volatile struct snd_pcm_mmap_status *status;
+	volatile struct snd_pcm_mmap_control *control;
 	atomic_t mmap_count;
 
 	/* -- locking / scheduling -- */
@@ -334,15 +309,15 @@
 
 	/* -- private section -- */
 	void *private_data;
-	void (*private_free)(snd_pcm_runtime_t *runtime);
+	void (*private_free)(struct snd_pcm_runtime *runtime);
 
 	/* -- hardware description -- */
-	snd_pcm_hardware_t hw;
-	snd_pcm_hw_constraints_t hw_constraints;
+	struct snd_pcm_hardware hw;
+	struct snd_pcm_hw_constraints hw_constraints;
 
 	/* -- interrupt callbacks -- */
-	void (*transfer_ack_begin)(snd_pcm_substream_t *substream);
-	void (*transfer_ack_end)(snd_pcm_substream_t *substream);
+	void (*transfer_ack_begin)(struct snd_pcm_substream *substream);
+	void (*transfer_ack_end)(struct snd_pcm_substream *substream);
 
 	/* -- timer -- */
 	unsigned int timer_resolution;	/* timer resolution */
@@ -356,19 +331,19 @@
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	/* -- OSS things -- */
-	snd_pcm_oss_runtime_t oss;
+	struct snd_pcm_oss_runtime oss;
 #endif
 };
 
-typedef struct _snd_pcm_group {		/* keep linked substreams */
+struct snd_pcm_group {		/* keep linked substreams */
 	spinlock_t lock;
 	struct list_head substreams;
 	int count;
-} snd_pcm_group_t;
+};
 
-struct _snd_pcm_substream {
-	snd_pcm_t *pcm;
-	snd_pcm_str_t *pstr;
+struct snd_pcm_substream {
+	struct snd_pcm *pcm;
+	struct snd_pcm_str *pstr;
 	void *private_data;		/* copied from pcm->private_data */
 	int number;
 	char name[32];			/* substream name */
@@ -378,32 +353,32 @@
 	unsigned int dma_buf_id;
 	size_t dma_max;
 	/* -- hardware operations -- */
-	snd_pcm_ops_t *ops;
+	struct snd_pcm_ops *ops;
 	/* -- runtime information -- */
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
         /* -- timer section -- */
-	snd_timer_t *timer;		/* timer */
+	struct snd_timer *timer;		/* timer */
 	unsigned timer_running: 1;	/* time is running */
 	spinlock_t timer_lock;
 	/* -- next substream -- */
-	snd_pcm_substream_t *next;
+	struct snd_pcm_substream *next;
 	/* -- linked substreams -- */
 	struct list_head link_list;	/* linked list member */
-	snd_pcm_group_t self_group;	/* fake group for non linked substream (with substream lock inside) */
-	snd_pcm_group_t *group;		/* pointer to current group */
+	struct snd_pcm_group self_group;	/* fake group for non linked substream (with substream lock inside) */
+	struct snd_pcm_group *group;		/* pointer to current group */
 	/* -- assigned files -- */
-	snd_pcm_file_t *file;
+	struct snd_pcm_file *file;
 	struct file *ffile;
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	/* -- OSS things -- */
-	snd_pcm_oss_substream_t oss;
+	struct snd_pcm_oss_substream oss;
 #endif
-	snd_info_entry_t *proc_root;
-	snd_info_entry_t *proc_info_entry;
-	snd_info_entry_t *proc_hw_params_entry;
-	snd_info_entry_t *proc_sw_params_entry;
-	snd_info_entry_t *proc_status_entry;
-	snd_info_entry_t *proc_prealloc_entry;
+	struct snd_info_entry *proc_root;
+	struct snd_info_entry *proc_info_entry;
+	struct snd_info_entry *proc_hw_params_entry;
+	struct snd_info_entry *proc_sw_params_entry;
+	struct snd_info_entry *proc_status_entry;
+	struct snd_info_entry *proc_prealloc_entry;
 	/* misc flags */
 	unsigned int no_mmap_ctrl: 1;
 };
@@ -415,65 +390,64 @@
 #endif
 
 
-struct _snd_pcm_str {
+struct snd_pcm_str {
 	int stream;				/* stream (direction) */
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	/* -- substreams -- */
 	unsigned int substream_count;
 	unsigned int substream_opened;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	/* -- OSS things -- */
-	snd_pcm_oss_stream_t oss;
+	struct snd_pcm_oss_stream oss;
 #endif
-	snd_pcm_file_t *files;
-	snd_minor_t *reg;
-	snd_info_entry_t *proc_root;
-	snd_info_entry_t *proc_info_entry;
+	struct snd_pcm_file *files;
+	struct snd_info_entry *proc_root;
+	struct snd_info_entry *proc_info_entry;
 #ifdef CONFIG_SND_DEBUG
 	unsigned int xrun_debug;	/* 0 = disabled, 1 = verbose, 2 = stacktrace */
-	snd_info_entry_t *proc_xrun_debug_entry;
+	struct snd_info_entry *proc_xrun_debug_entry;
 #endif
 };
 
-struct _snd_pcm {
-	snd_card_t *card;
+struct snd_pcm {
+	struct snd_card *card;
+	struct list_head list;
 	unsigned int device;	/* device number */
 	unsigned int info_flags;
 	unsigned short dev_class;
 	unsigned short dev_subclass;
 	char id[64];
 	char name[80];
-	snd_pcm_str_t streams[2];
+	struct snd_pcm_str streams[2];
 	struct semaphore open_mutex;
 	wait_queue_head_t open_wait;
 	void *private_data;
-	void (*private_free) (snd_pcm_t *pcm);
+	void (*private_free) (struct snd_pcm *pcm);
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
-	snd_pcm_oss_t oss;
+	struct snd_pcm_oss oss;
 #endif
 };
 
-typedef struct _snd_pcm_notify {
-	int (*n_register) (snd_pcm_t * pcm);
-	int (*n_disconnect) (snd_pcm_t * pcm);
-	int (*n_unregister) (snd_pcm_t * pcm);
+struct snd_pcm_notify {
+	int (*n_register) (struct snd_pcm * pcm);
+	int (*n_disconnect) (struct snd_pcm * pcm);
+	int (*n_unregister) (struct snd_pcm * pcm);
 	struct list_head list;
-} snd_pcm_notify_t;
+};
 
 /*
  *  Registering
  */
 
-extern snd_pcm_t *snd_pcm_devices[];
-extern snd_minor_t snd_pcm_reg[2];
+extern struct file_operations snd_pcm_f_ops[2];
 
-int snd_pcm_new(snd_card_t * card, char *id, int device,
+int snd_pcm_new(struct snd_card *card, char *id, int device,
 		int playback_count, int capture_count,
-		snd_pcm_t **rpcm);
-int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count);
+		struct snd_pcm **rpcm);
+int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count);
 
-int snd_pcm_notify(snd_pcm_notify_t *notify, int nfree);
+int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree);
 
 /*
  *  Native I/O
@@ -481,24 +455,26 @@
 
 extern rwlock_t snd_pcm_link_rwlock;
 
-int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
-int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t __user *info);
-int snd_pcm_status(snd_pcm_substream_t * substream, snd_pcm_status_t *status);
-int snd_pcm_prepare(snd_pcm_substream_t *substream);
-int snd_pcm_start(snd_pcm_substream_t *substream);
-int snd_pcm_stop(snd_pcm_substream_t *substream, int status);
-int snd_pcm_drain_done(snd_pcm_substream_t *substream);
+int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info);
+int snd_pcm_info_user(struct snd_pcm_substream *substream,
+		      struct snd_pcm_info __user *info);
+int snd_pcm_status(struct snd_pcm_substream *substream,
+		   struct snd_pcm_status *status);
+int snd_pcm_prepare(struct snd_pcm_substream *substream);
+int snd_pcm_start(struct snd_pcm_substream *substream);
+int snd_pcm_stop(struct snd_pcm_substream *substream, int status);
+int snd_pcm_drain_done(struct snd_pcm_substream *substream);
 #ifdef CONFIG_PM
-int snd_pcm_suspend(snd_pcm_substream_t *substream);
-int snd_pcm_suspend_all(snd_pcm_t *pcm);
+int snd_pcm_suspend(struct snd_pcm_substream *substream);
+int snd_pcm_suspend_all(struct snd_pcm *pcm);
 #endif
-int snd_pcm_kernel_playback_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
-int snd_pcm_kernel_capture_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
-int snd_pcm_kernel_ioctl(snd_pcm_substream_t *substream, unsigned int cmd, void *arg);
-int snd_pcm_open_substream(snd_pcm_t *pcm, int stream, snd_pcm_substream_t **rsubstream);
-void snd_pcm_release_substream(snd_pcm_substream_t *substream);
+int snd_pcm_kernel_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg);
+int snd_pcm_kernel_capture_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg);
+int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg);
+int snd_pcm_open_substream(struct snd_pcm *pcm, int stream, struct snd_pcm_substream **rsubstream);
+void snd_pcm_release_substream(struct snd_pcm_substream *substream);
 void snd_pcm_vma_notify_data(void *client, void *data);
-int snd_pcm_mmap_data(snd_pcm_substream_t *substream, struct file *file, struct vm_area_struct *area);
+int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, struct vm_area_struct *area);
 
 #if BITS_PER_LONG >= 64
 
@@ -578,30 +554,30 @@
  *  PCM library
  */
 
-static inline int snd_pcm_stream_linked(snd_pcm_substream_t *substream)
+static inline int snd_pcm_stream_linked(struct snd_pcm_substream *substream)
 {
 	return substream->group != &substream->self_group;
 }
 
-static inline void snd_pcm_stream_lock(snd_pcm_substream_t *substream)
+static inline void snd_pcm_stream_lock(struct snd_pcm_substream *substream)
 {
 	read_lock(&snd_pcm_link_rwlock);
 	spin_lock(&substream->self_group.lock);
 }
 
-static inline void snd_pcm_stream_unlock(snd_pcm_substream_t *substream)
+static inline void snd_pcm_stream_unlock(struct snd_pcm_substream *substream)
 {
 	spin_unlock(&substream->self_group.lock);
 	read_unlock(&snd_pcm_link_rwlock);
 }
 
-static inline void snd_pcm_stream_lock_irq(snd_pcm_substream_t *substream)
+static inline void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
 {
 	read_lock_irq(&snd_pcm_link_rwlock);
 	spin_lock(&substream->self_group.lock);
 }
 
-static inline void snd_pcm_stream_unlock_irq(snd_pcm_substream_t *substream)
+static inline void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream)
 {
 	spin_unlock(&substream->self_group.lock);
 	read_unlock_irq(&snd_pcm_link_rwlock);
@@ -623,56 +599,56 @@
 	list_for_each(pos, &substream->group->substreams)
 
 #define snd_pcm_group_substream_entry(pos) \
-	list_entry(pos, snd_pcm_substream_t, link_list)
+	list_entry(pos, struct snd_pcm_substream, link_list)
 
-static inline int snd_pcm_running(snd_pcm_substream_t *substream)
+static inline int snd_pcm_running(struct snd_pcm_substream *substream)
 {
 	return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
 		(substream->runtime->status->state == SNDRV_PCM_STATE_DRAINING &&
 		 substream->stream == SNDRV_PCM_STREAM_PLAYBACK));
 }
 
-static inline ssize_t bytes_to_samples(snd_pcm_runtime_t *runtime, ssize_t size)
+static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t size)
 {
 	return size * 8 / runtime->sample_bits;
 }
 
-static inline snd_pcm_sframes_t bytes_to_frames(snd_pcm_runtime_t *runtime, ssize_t size)
+static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size)
 {
 	return size * 8 / runtime->frame_bits;
 }
 
-static inline ssize_t samples_to_bytes(snd_pcm_runtime_t *runtime, ssize_t size)
+static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t size)
 {
 	return size * runtime->sample_bits / 8;
 }
 
-static inline ssize_t frames_to_bytes(snd_pcm_runtime_t *runtime, snd_pcm_sframes_t size)
+static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size)
 {
 	return size * runtime->frame_bits / 8;
 }
 
-static inline int frame_aligned(snd_pcm_runtime_t *runtime, ssize_t bytes)
+static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes)
 {
 	return bytes % runtime->byte_align == 0;
 }
 
-static inline size_t snd_pcm_lib_buffer_bytes(snd_pcm_substream_t *substream)
+static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	return frames_to_bytes(runtime, runtime->buffer_size);
 }
 
-static inline size_t snd_pcm_lib_period_bytes(snd_pcm_substream_t *substream)
+static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	return frames_to_bytes(runtime, runtime->period_size);
 }
 
 /*
  *  result is: 0 ... (boundary - 1)
  */
-static inline snd_pcm_uframes_t snd_pcm_playback_avail(snd_pcm_runtime_t *runtime)
+static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime)
 {
 	snd_pcm_sframes_t avail = runtime->status->hw_ptr + runtime->buffer_size - runtime->control->appl_ptr;
 	if (avail < 0)
@@ -685,7 +661,7 @@
 /*
  *  result is: 0 ... (boundary - 1)
  */
-static inline snd_pcm_uframes_t snd_pcm_capture_avail(snd_pcm_runtime_t *runtime)
+static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime)
 {
 	snd_pcm_sframes_t avail = runtime->status->hw_ptr - runtime->control->appl_ptr;
 	if (avail < 0)
@@ -693,12 +669,12 @@
 	return avail;
 }
 
-static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(snd_pcm_runtime_t *runtime)
+static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime)
 {
 	return runtime->buffer_size - snd_pcm_playback_avail(runtime);
 }
 
-static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(snd_pcm_runtime_t *runtime)
+static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime)
 {
 	return runtime->buffer_size - snd_pcm_capture_avail(runtime);
 }
@@ -711,9 +687,9 @@
  *
  * Returns non-zero if available, or zero if not.
  */
-static inline int snd_pcm_playback_ready(snd_pcm_substream_t *substream)
+static inline int snd_pcm_playback_ready(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	return snd_pcm_playback_avail(runtime) >= runtime->control->avail_min;
 }
 
@@ -725,9 +701,9 @@
  *
  * Returns non-zero if available, or zero if not.
  */
-static inline int snd_pcm_capture_ready(snd_pcm_substream_t *substream)
+static inline int snd_pcm_capture_ready(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	return snd_pcm_capture_avail(runtime) >= runtime->control->avail_min;
 }
 
@@ -740,9 +716,9 @@
  *
  * Returns non-zero if exists, or zero if not.
  */
-static inline int snd_pcm_playback_data(snd_pcm_substream_t *substream)
+static inline int snd_pcm_playback_data(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	
 	if (runtime->stop_threshold >= runtime->boundary)
 		return 1;
@@ -757,9 +733,9 @@
  *
  * Returns non-zero if empty, or zero if not.
  */
-static inline int snd_pcm_playback_empty(snd_pcm_substream_t *substream)
+static inline int snd_pcm_playback_empty(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	return snd_pcm_playback_avail(runtime) >= runtime->buffer_size;
 }
 
@@ -771,14 +747,14 @@
  *
  * Returns non-zero if empty, or zero if not.
  */
-static inline int snd_pcm_capture_empty(snd_pcm_substream_t *substream)
+static inline int snd_pcm_capture_empty(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	return snd_pcm_capture_avail(runtime) == 0;
 }
 
-static inline void snd_pcm_trigger_done(snd_pcm_substream_t *substream, 
-					snd_pcm_substream_t *master)
+static inline void snd_pcm_trigger_done(struct snd_pcm_substream *substream, 
+					struct snd_pcm_substream *master)
 {
 	substream->runtime->trigger_master = master;
 }
@@ -795,28 +771,28 @@
 		var <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL;
 }
 
-static inline snd_mask_t *hw_param_mask(snd_pcm_hw_params_t *params,
+static inline struct snd_mask *hw_param_mask(struct snd_pcm_hw_params *params,
 				     snd_pcm_hw_param_t var)
 {
 	return &params->masks[var - SNDRV_PCM_HW_PARAM_FIRST_MASK];
 }
 
-static inline snd_interval_t *hw_param_interval(snd_pcm_hw_params_t *params,
+static inline struct snd_interval *hw_param_interval(struct snd_pcm_hw_params *params,
 					     snd_pcm_hw_param_t var)
 {
 	return &params->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
 }
 
-static inline const snd_mask_t *hw_param_mask_c(const snd_pcm_hw_params_t *params,
+static inline const struct snd_mask *hw_param_mask_c(const struct snd_pcm_hw_params *params,
 					     snd_pcm_hw_param_t var)
 {
-	return (const snd_mask_t *)hw_param_mask((snd_pcm_hw_params_t*) params, var);
+	return (const struct snd_mask *)hw_param_mask((struct snd_pcm_hw_params*) params, var);
 }
 
-static inline const snd_interval_t *hw_param_interval_c(const snd_pcm_hw_params_t *params,
+static inline const struct snd_interval *hw_param_interval_c(const struct snd_pcm_hw_params *params,
 						     snd_pcm_hw_param_t var)
 {
-	return (const snd_interval_t *)hw_param_interval((snd_pcm_hw_params_t*) params, var);
+	return (const struct snd_interval *)hw_param_interval((struct snd_pcm_hw_params*) params, var);
 }
 
 #define params_access(p) snd_mask_min(hw_param_mask((p), SNDRV_PCM_HW_PARAM_ACCESS))
@@ -832,66 +808,66 @@
 #define params_tick_time(p) hw_param_interval((p), SNDRV_PCM_HW_PARAM_TICK_TIME)->min
 
 
-int snd_interval_refine(snd_interval_t *i, const snd_interval_t *v);
-void snd_interval_mul(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c);
-void snd_interval_div(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c);
-void snd_interval_muldivk(const snd_interval_t *a, const snd_interval_t *b, 
-			  unsigned int k, snd_interval_t *c);
-void snd_interval_mulkdiv(const snd_interval_t *a, unsigned int k,
-			  const snd_interval_t *b, snd_interval_t *c);
-int snd_interval_list(snd_interval_t *i, unsigned int count, unsigned int *list, unsigned int mask);
-int snd_interval_ratnum(snd_interval_t *i,
-			unsigned int rats_count, ratnum_t *rats,
+int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v);
+void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c);
+void snd_interval_div(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c);
+void snd_interval_muldivk(const struct snd_interval *a, const struct snd_interval *b, 
+			  unsigned int k, struct snd_interval *c);
+void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
+			  const struct snd_interval *b, struct snd_interval *c);
+int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask);
+int snd_interval_ratnum(struct snd_interval *i,
+			unsigned int rats_count, struct snd_ratnum *rats,
 			unsigned int *nump, unsigned int *denp);
 
-void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params);
-void _snd_pcm_hw_param_setempty(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var);
-int snd_pcm_hw_param_near(snd_pcm_substream_t *substream, 
-			  snd_pcm_hw_params_t *params,
+void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params);
+void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params, snd_pcm_hw_param_t var);
+int snd_pcm_hw_param_near(struct snd_pcm_substream *substream, 
+			  struct snd_pcm_hw_params *params,
 			  snd_pcm_hw_param_t var, 
 			  unsigned int val, int *dir);
-int snd_pcm_hw_param_set(snd_pcm_substream_t *pcm,
-			 snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
+			 struct snd_pcm_hw_params *params,
 			 snd_pcm_hw_param_t var,
 			 unsigned int val, int dir);
-int snd_pcm_hw_params_choose(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_params_choose(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
 
-int snd_pcm_hw_refine(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_refine(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params);
 
-int snd_pcm_hw_constraints_init(snd_pcm_substream_t *substream);
-int snd_pcm_hw_constraints_complete(snd_pcm_substream_t *substream);
+int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream);
+int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream);
 
-int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
 			       u_int32_t mask);
-int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
 				 u_int64_t mask);
-int snd_pcm_hw_constraint_minmax(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
 				 unsigned int min, unsigned int max);
-int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var);
-int snd_pcm_hw_constraint_list(snd_pcm_runtime_t *runtime, 
+int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var);
+int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, 
 			       unsigned int cond,
 			       snd_pcm_hw_param_t var,
-			       snd_pcm_hw_constraint_list_t *l);
-int snd_pcm_hw_constraint_ratnums(snd_pcm_runtime_t *runtime, 
+			       struct snd_pcm_hw_constraint_list *l);
+int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, 
 				  unsigned int cond,
 				  snd_pcm_hw_param_t var,
-				  snd_pcm_hw_constraint_ratnums_t *r);
-int snd_pcm_hw_constraint_ratdens(snd_pcm_runtime_t *runtime, 
+				  struct snd_pcm_hw_constraint_ratnums *r);
+int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, 
 				  unsigned int cond,
 				  snd_pcm_hw_param_t var,
-				  snd_pcm_hw_constraint_ratdens_t *r);
-int snd_pcm_hw_constraint_msbits(snd_pcm_runtime_t *runtime, 
+				  struct snd_pcm_hw_constraint_ratdens *r);
+int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, 
 				 unsigned int cond,
 				 unsigned int width,
 				 unsigned int msbits);
-int snd_pcm_hw_constraint_step(snd_pcm_runtime_t *runtime,
+int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
 			       unsigned int cond,
 			       snd_pcm_hw_param_t var,
 			       unsigned long step);
-int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime,
+int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
 			       unsigned int cond,
 			       snd_pcm_hw_param_t var);
-int snd_pcm_hw_rule_add(snd_pcm_runtime_t *runtime,
+int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime,
 			unsigned int cond,
 			int var,
 			snd_pcm_hw_rule_func_t func, void *private,
@@ -925,37 +901,37 @@
 snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian);
 const char *snd_pcm_format_name(snd_pcm_format_t format);
 
-void snd_pcm_set_ops(snd_pcm_t * pcm, int direction, snd_pcm_ops_t *ops);
-void snd_pcm_set_sync(snd_pcm_substream_t * substream);
-int snd_pcm_lib_interleave_len(snd_pcm_substream_t *substream);
-int snd_pcm_lib_ioctl(snd_pcm_substream_t *substream,
+void snd_pcm_set_ops(struct snd_pcm * pcm, int direction, struct snd_pcm_ops *ops);
+void snd_pcm_set_sync(struct snd_pcm_substream *substream);
+int snd_pcm_lib_interleave_len(struct snd_pcm_substream *substream);
+int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
 		      unsigned int cmd, void *arg);                      
-int snd_pcm_update_hw_ptr(snd_pcm_substream_t *substream);
-int snd_pcm_playback_xrun_check(snd_pcm_substream_t *substream);
-int snd_pcm_capture_xrun_check(snd_pcm_substream_t *substream);
-int snd_pcm_playback_xrun_asap(snd_pcm_substream_t *substream);
-int snd_pcm_capture_xrun_asap(snd_pcm_substream_t *substream);
-void snd_pcm_playback_silence(snd_pcm_substream_t *substream, snd_pcm_uframes_t new_hw_ptr);
-void snd_pcm_tick_prepare(snd_pcm_substream_t *substream);
-void snd_pcm_tick_set(snd_pcm_substream_t *substream, unsigned long ticks);
-void snd_pcm_tick_elapsed(snd_pcm_substream_t *substream);
-void snd_pcm_period_elapsed(snd_pcm_substream_t *substream);
-snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream,
+int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream);
+int snd_pcm_playback_xrun_check(struct snd_pcm_substream *substream);
+int snd_pcm_capture_xrun_check(struct snd_pcm_substream *substream);
+int snd_pcm_playback_xrun_asap(struct snd_pcm_substream *substream);
+int snd_pcm_capture_xrun_asap(struct snd_pcm_substream *substream);
+void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr);
+void snd_pcm_tick_prepare(struct snd_pcm_substream *substream);
+void snd_pcm_tick_set(struct snd_pcm_substream *substream, unsigned long ticks);
+void snd_pcm_tick_elapsed(struct snd_pcm_substream *substream);
+void snd_pcm_period_elapsed(struct snd_pcm_substream *substream);
+snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream,
 				    const void __user *buf,
 				    snd_pcm_uframes_t frames);
-snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream,
+snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream,
 				   void __user *buf, snd_pcm_uframes_t frames);
-snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream,
+snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
 				     void __user **bufs, snd_pcm_uframes_t frames);
-snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream,
+snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
 				    void __user **bufs, snd_pcm_uframes_t frames);
 
-int snd_pcm_limit_hw_rates(snd_pcm_runtime_t *runtime);
+int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime);
 
-static inline void snd_pcm_set_runtime_buffer(snd_pcm_substream_t *substream,
+static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
 					      struct snd_dma_buffer *bufp)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (bufp) {
 		runtime->dma_buffer_p = bufp;
 		runtime->dma_area = bufp->area;
@@ -973,47 +949,47 @@
  *  Timer interface
  */
 
-void snd_pcm_timer_resolution_change(snd_pcm_substream_t *substream);
-void snd_pcm_timer_init(snd_pcm_substream_t * substream);
-void snd_pcm_timer_done(snd_pcm_substream_t * substream);
+void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream);
+void snd_pcm_timer_init(struct snd_pcm_substream *substream);
+void snd_pcm_timer_done(struct snd_pcm_substream *substream);
 
 /*
  *  Memory
  */
 
-int snd_pcm_lib_preallocate_free(snd_pcm_substream_t *substream);
-int snd_pcm_lib_preallocate_free_for_all(snd_pcm_t *pcm);
-int snd_pcm_lib_preallocate_pages(snd_pcm_substream_t *substream,
+int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream);
+int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm);
+int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
 				  int type, struct device *data,
 				  size_t size, size_t max);
-int snd_pcm_lib_preallocate_pages_for_all(snd_pcm_t *pcm,
+int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
 					  int type, void *data,
 					  size_t size, size_t max);
-int snd_pcm_lib_malloc_pages(snd_pcm_substream_t *substream, size_t size);
-int snd_pcm_lib_free_pages(snd_pcm_substream_t *substream);
+int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
+int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
 
 #define snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_buffer_p->private_data)
 #define snd_pcm_sgbuf_pages(size) snd_sgbuf_aligned_pages(size)
 #define snd_pcm_sgbuf_get_addr(sgbuf,ofs) snd_sgbuf_get_addr(sgbuf,ofs)
-struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
+struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset);
 
 /* handle mmap counter - PCM mmap callback should handle this counter properly */
 static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
 	atomic_inc(&substream->runtime->mmap_count);
 }
 
 static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
 	atomic_dec(&substream->runtime->mmap_count);
 }
 
 /* mmap for io-memory area */
 #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA)
 #define SNDRV_PCM_INFO_MMAP_IOMEM	SNDRV_PCM_INFO_MMAP
-int snd_pcm_lib_mmap_iomem(snd_pcm_substream_t *substream, struct vm_area_struct *area);
+int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_struct *area);
 #else
 #define SNDRV_PCM_INFO_MMAP_IOMEM	0
 #define snd_pcm_lib_mmap_iomem	NULL
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index 0b67c9d..fddaddd 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -22,10 +22,7 @@
  *
  */
 
-typedef struct _snd_pcm_plugin snd_pcm_plugin_t;
-typedef struct _snd_pcm_oss_setup snd_pcm_oss_setup_t;
-
-struct _snd_pcm_oss_setup {
+struct snd_pcm_oss_setup {
 	char *task_name;
 	unsigned int disable:1,
 		     direct:1,
@@ -36,10 +33,10 @@
 		     buggyptr:1;
 	unsigned int periods;
 	unsigned int period_size;
-	snd_pcm_oss_setup_t *next;
+	struct snd_pcm_oss_setup *next;
 };
 
-typedef struct _snd_pcm_oss_runtime {
+struct snd_pcm_oss_runtime {
 	unsigned params: 1,			/* format/parameter change */
 		 prepare: 1,			/* need to prepare the operation */
 		 trigger: 1,			/* trigger flag */
@@ -59,30 +56,30 @@
 	size_t mmap_bytes;
 	char *buffer;				/* vmallocated period */
 	size_t buffer_used;			/* used length from period buffer */
-	snd_pcm_plugin_t *plugin_first;
-	snd_pcm_plugin_t *plugin_last;
+	struct snd_pcm_plugin *plugin_first;
+	struct snd_pcm_plugin *plugin_last;
 	unsigned int prev_hw_ptr_interrupt;
-} snd_pcm_oss_runtime_t;
+};
 
-typedef struct _snd_pcm_oss_file {
-	snd_pcm_substream_t *streams[2];
-} snd_pcm_oss_file_t;
+struct snd_pcm_oss_file {
+	struct snd_pcm_substream *streams[2];
+};
 
-typedef struct _snd_pcm_oss_substream {
+struct snd_pcm_oss_substream {
 	unsigned oss: 1;			/* oss mode */
-	snd_pcm_oss_setup_t *setup;		/* active setup */
-	snd_pcm_oss_file_t *file;
-} snd_pcm_oss_substream_t;
+	struct snd_pcm_oss_setup *setup;		/* active setup */
+	struct snd_pcm_oss_file *file;
+};
 
-typedef struct _snd_pcm_oss_stream {
-	snd_pcm_oss_setup_t *setup_list;	/* setup list */
+struct snd_pcm_oss_stream {
+	struct snd_pcm_oss_setup *setup_list;	/* setup list */
         struct semaphore setup_mutex;
-	snd_info_entry_t *proc_entry;
-} snd_pcm_oss_stream_t;
+	struct snd_info_entry *proc_entry;
+};
 
-typedef struct _snd_pcm_oss {
+struct snd_pcm_oss {
 	int reg;
 	unsigned int reg_mask;
-} snd_pcm_oss_t;
+};
 
 #endif /* __SOUND_PCM_OSS_H */
diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h
index 60b0e92..fb18aef7 100644
--- a/include/sound/pcm_params.h
+++ b/include/sound/pcm_params.h
@@ -22,17 +22,17 @@
  *
  */
 
-extern int snd_pcm_hw_param_mask(snd_pcm_substream_t *pcm, snd_pcm_hw_params_t *params,
-				 snd_pcm_hw_param_t var, const snd_mask_t *val);
-extern unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
+extern int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
+				 snd_pcm_hw_param_t var, const struct snd_mask *val);
+extern unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
 					       snd_pcm_hw_param_t var, int *dir);
-extern unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
+extern unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
 					       snd_pcm_hw_param_t var, int *dir);
-extern int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params,
+extern int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params,
 				 snd_pcm_hw_param_t var, unsigned int val, int dir);
-extern int _snd_pcm_hw_param_setinteger(snd_pcm_hw_params_t *params,
+extern int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
 					snd_pcm_hw_param_t var);
-extern int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params,
+extern int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
 				 snd_pcm_hw_param_t var, unsigned int val, int dir);
 
 /* To share the same code we have  alsa-lib */
@@ -71,20 +71,20 @@
 
 INLINE size_t snd_mask_sizeof(void)
 {
-	return sizeof(snd_mask_t);
+	return sizeof(struct snd_mask);
 }
 
-INLINE void snd_mask_none(snd_mask_t *mask)
+INLINE void snd_mask_none(struct snd_mask *mask)
 {
 	memset(mask, 0, sizeof(*mask));
 }
 
-INLINE void snd_mask_any(snd_mask_t *mask)
+INLINE void snd_mask_any(struct snd_mask *mask)
 {
 	memset(mask, 0xff, SNDRV_MASK_SIZE * sizeof(u_int32_t));
 }
 
-INLINE int snd_mask_empty(const snd_mask_t *mask)
+INLINE int snd_mask_empty(const struct snd_mask *mask)
 {
 	int i;
 	for (i = 0; i < SNDRV_MASK_SIZE; i++)
@@ -93,7 +93,7 @@
 	return 1;
 }
 
-INLINE unsigned int snd_mask_min(const snd_mask_t *mask)
+INLINE unsigned int snd_mask_min(const struct snd_mask *mask)
 {
 	int i;
 	assert(!snd_mask_empty(mask));
@@ -104,7 +104,7 @@
 	return 0;
 }
 
-INLINE unsigned int snd_mask_max(const snd_mask_t *mask)
+INLINE unsigned int snd_mask_max(const struct snd_mask *mask)
 {
 	int i;
 	assert(!snd_mask_empty(mask));
@@ -115,19 +115,19 @@
 	return 0;
 }
 
-INLINE void snd_mask_set(snd_mask_t *mask, unsigned int val)
+INLINE void snd_mask_set(struct snd_mask *mask, unsigned int val)
 {
 	assert(val <= SNDRV_MASK_BITS);
 	mask->bits[MASK_OFS(val)] |= MASK_BIT(val);
 }
 
-INLINE void snd_mask_reset(snd_mask_t *mask, unsigned int val)
+INLINE void snd_mask_reset(struct snd_mask *mask, unsigned int val)
 {
 	assert(val <= SNDRV_MASK_BITS);
 	mask->bits[MASK_OFS(val)] &= ~MASK_BIT(val);
 }
 
-INLINE void snd_mask_set_range(snd_mask_t *mask, unsigned int from, unsigned int to)
+INLINE void snd_mask_set_range(struct snd_mask *mask, unsigned int from, unsigned int to)
 {
 	unsigned int i;
 	assert(to <= SNDRV_MASK_BITS && from <= to);
@@ -135,7 +135,7 @@
 		mask->bits[MASK_OFS(i)] |= MASK_BIT(i);
 }
 
-INLINE void snd_mask_reset_range(snd_mask_t *mask, unsigned int from, unsigned int to)
+INLINE void snd_mask_reset_range(struct snd_mask *mask, unsigned int from, unsigned int to)
 {
 	unsigned int i;
 	assert(to <= SNDRV_MASK_BITS && from <= to);
@@ -143,7 +143,7 @@
 		mask->bits[MASK_OFS(i)] &= ~MASK_BIT(i);
 }
 
-INLINE void snd_mask_leave(snd_mask_t *mask, unsigned int val)
+INLINE void snd_mask_leave(struct snd_mask *mask, unsigned int val)
 {
 	unsigned int v;
 	assert(val <= SNDRV_MASK_BITS);
@@ -152,30 +152,30 @@
 	mask->bits[MASK_OFS(val)] = v;
 }
 
-INLINE void snd_mask_intersect(snd_mask_t *mask, const snd_mask_t *v)
+INLINE void snd_mask_intersect(struct snd_mask *mask, const struct snd_mask *v)
 {
 	int i;
 	for (i = 0; i < SNDRV_MASK_SIZE; i++)
 		mask->bits[i] &= v->bits[i];
 }
 
-INLINE int snd_mask_eq(const snd_mask_t *mask, const snd_mask_t *v)
+INLINE int snd_mask_eq(const struct snd_mask *mask, const struct snd_mask *v)
 {
 	return ! memcmp(mask, v, SNDRV_MASK_SIZE * sizeof(u_int32_t));
 }
 
-INLINE void snd_mask_copy(snd_mask_t *mask, const snd_mask_t *v)
+INLINE void snd_mask_copy(struct snd_mask *mask, const struct snd_mask *v)
 {
 	*mask = *v;
 }
 
-INLINE int snd_mask_test(const snd_mask_t *mask, unsigned int val)
+INLINE int snd_mask_test(const struct snd_mask *mask, unsigned int val)
 {
 	assert(val <= SNDRV_MASK_BITS);
 	return mask->bits[MASK_OFS(val)] & MASK_BIT(val);
 }
 
-INLINE int snd_mask_single(const snd_mask_t *mask)
+INLINE int snd_mask_single(const struct snd_mask *mask)
 {
 	int i, c = 0;
 	assert(!snd_mask_empty(mask));
@@ -191,9 +191,9 @@
 	return 1;
 }
 
-INLINE int snd_mask_refine(snd_mask_t *mask, const snd_mask_t *v)
+INLINE int snd_mask_refine(struct snd_mask *mask, const struct snd_mask *v)
 {
-	snd_mask_t old;
+	struct snd_mask old;
 	assert(!snd_mask_empty(mask));
 	snd_mask_copy(&old, mask);
 	snd_mask_intersect(mask, v);
@@ -202,7 +202,7 @@
 	return !snd_mask_eq(mask, &old);
 }
 
-INLINE int snd_mask_refine_first(snd_mask_t *mask)
+INLINE int snd_mask_refine_first(struct snd_mask *mask)
 {
 	assert(!snd_mask_empty(mask));
 	if (snd_mask_single(mask))
@@ -211,7 +211,7 @@
 	return 1;
 }
 
-INLINE int snd_mask_refine_last(snd_mask_t *mask)
+INLINE int snd_mask_refine_last(struct snd_mask *mask)
 {
 	assert(!snd_mask_empty(mask));
 	if (snd_mask_single(mask))
@@ -220,7 +220,7 @@
 	return 1;
 }
 
-INLINE int snd_mask_refine_min(snd_mask_t *mask, unsigned int val)
+INLINE int snd_mask_refine_min(struct snd_mask *mask, unsigned int val)
 {
 	assert(!snd_mask_empty(mask));
 	if (snd_mask_min(mask) >= val)
@@ -231,7 +231,7 @@
 	return 1;
 }
 
-INLINE int snd_mask_refine_max(snd_mask_t *mask, unsigned int val)
+INLINE int snd_mask_refine_max(struct snd_mask *mask, unsigned int val)
 {
 	assert(!snd_mask_empty(mask));
 	if (snd_mask_max(mask) <= val)
@@ -242,7 +242,7 @@
 	return 1;
 }
 
-INLINE int snd_mask_refine_set(snd_mask_t *mask, unsigned int val)
+INLINE int snd_mask_refine_set(struct snd_mask *mask, unsigned int val)
 {
 	int changed;
 	assert(!snd_mask_empty(mask));
@@ -253,13 +253,13 @@
 	return changed;
 }
 
-INLINE int snd_mask_value(const snd_mask_t *mask)
+INLINE int snd_mask_value(const struct snd_mask *mask)
 {
 	assert(!snd_mask_empty(mask));
 	return snd_mask_min(mask);
 }
 
-INLINE void snd_interval_any(snd_interval_t *i)
+INLINE void snd_interval_any(struct snd_interval *i)
 {
 	i->min = 0;
 	i->openmin = 0;
@@ -269,42 +269,42 @@
 	i->empty = 0;
 }
 
-INLINE void snd_interval_none(snd_interval_t *i)
+INLINE void snd_interval_none(struct snd_interval *i)
 {
 	i->empty = 1;
 }
 
-INLINE int snd_interval_checkempty(const snd_interval_t *i)
+INLINE int snd_interval_checkempty(const struct snd_interval *i)
 {
 	return (i->min > i->max ||
 		(i->min == i->max && (i->openmin || i->openmax)));
 }
 
-INLINE int snd_interval_empty(const snd_interval_t *i)
+INLINE int snd_interval_empty(const struct snd_interval *i)
 {
 	return i->empty;
 }
 
-INLINE int snd_interval_single(const snd_interval_t *i)
+INLINE int snd_interval_single(const struct snd_interval *i)
 {
 	assert(!snd_interval_empty(i));
 	return (i->min == i->max || 
 		(i->min + 1 == i->max && i->openmax));
 }
 
-INLINE int snd_interval_value(const snd_interval_t *i)
+INLINE int snd_interval_value(const struct snd_interval *i)
 {
 	assert(snd_interval_single(i));
 	return i->min;
 }
 
-INLINE int snd_interval_min(const snd_interval_t *i)
+INLINE int snd_interval_min(const struct snd_interval *i)
 {
 	assert(!snd_interval_empty(i));
 	return i->min;
 }
 
-INLINE int snd_interval_max(const snd_interval_t *i)
+INLINE int snd_interval_max(const struct snd_interval *i)
 {
 	unsigned int v;
 	assert(!snd_interval_empty(i));
@@ -314,18 +314,18 @@
 	return v;
 }
 
-INLINE int snd_interval_test(const snd_interval_t *i, unsigned int val)
+INLINE int snd_interval_test(const struct snd_interval *i, unsigned int val)
 {
 	return !((i->min > val || (i->min == val && i->openmin) ||
 		  i->max < val || (i->max == val && i->openmax)));
 }
 
-INLINE void snd_interval_copy(snd_interval_t *d, const snd_interval_t *s)
+INLINE void snd_interval_copy(struct snd_interval *d, const struct snd_interval *s)
 {
 	*d = *s;
 }
 
-INLINE int snd_interval_setinteger(snd_interval_t *i)
+INLINE int snd_interval_setinteger(struct snd_interval *i)
 {
 	if (i->integer)
 		return 0;
@@ -335,7 +335,7 @@
 	return 1;
 }
 
-INLINE int snd_interval_eq(const snd_interval_t *i1, const snd_interval_t *i2)
+INLINE int snd_interval_eq(const struct snd_interval *i1, const struct snd_interval *i2)
 {
 	if (i1->empty)
 		return i2->empty;
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index 3f9db51..d19bddf 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -36,11 +36,6 @@
  *  Raw MIDI interface
  */
 
-typedef enum sndrv_rawmidi_stream snd_rawmidi_stream_t;
-typedef struct sndrv_rawmidi_info snd_rawmidi_info_t;
-typedef struct sndrv_rawmidi_params snd_rawmidi_params_t;
-typedef struct sndrv_rawmidi_status snd_rawmidi_status_t;
-
 #define SNDRV_RAWMIDI_DEVICES		8
 
 #define SNDRV_RAWMIDI_LFLG_OUTPUT	(1<<0)
@@ -49,23 +44,22 @@
 #define SNDRV_RAWMIDI_LFLG_APPEND	(1<<2)
 #define	SNDRV_RAWMIDI_LFLG_NOOPENLOCK	(1<<3)
 
-typedef struct _snd_rawmidi_runtime snd_rawmidi_runtime_t;
-typedef struct _snd_rawmidi_substream snd_rawmidi_substream_t;
-typedef struct _snd_rawmidi_str snd_rawmidi_str_t;
+struct snd_rawmidi;
+struct snd_rawmidi_substream;
 
-typedef struct _snd_rawmidi_ops {
-	int (*open) (snd_rawmidi_substream_t * substream);
-	int (*close) (snd_rawmidi_substream_t * substream);
-	void (*trigger) (snd_rawmidi_substream_t * substream, int up);
-	void (*drain) (snd_rawmidi_substream_t * substream);
-} snd_rawmidi_ops_t;
+struct snd_rawmidi_ops {
+	int (*open) (struct snd_rawmidi_substream * substream);
+	int (*close) (struct snd_rawmidi_substream * substream);
+	void (*trigger) (struct snd_rawmidi_substream * substream, int up);
+	void (*drain) (struct snd_rawmidi_substream * substream);
+};
 
-typedef struct _snd_rawmidi_global_ops {
-	int (*dev_register) (snd_rawmidi_t * rmidi);
-	int (*dev_unregister) (snd_rawmidi_t * rmidi);
-} snd_rawmidi_global_ops_t;
+struct snd_rawmidi_global_ops {
+	int (*dev_register) (struct snd_rawmidi * rmidi);
+	int (*dev_unregister) (struct snd_rawmidi * rmidi);
+};
 
-struct _snd_rawmidi_runtime {
+struct snd_rawmidi_runtime {
 	unsigned int drain: 1,	/* drain stage */
 		     oss: 1;	/* OSS compatible mode */
 	/* midi stream buffer */
@@ -80,15 +74,15 @@
 	spinlock_t lock;
 	wait_queue_head_t sleep;
 	/* event handler (new bytes, input only) */
-	void (*event)(snd_rawmidi_substream_t *substream);
+	void (*event)(struct snd_rawmidi_substream *substream);
 	/* defers calls to event [input] or ops->trigger [output] */
 	struct tasklet_struct tasklet;
 	/* private data */
 	void *private_data;
-	void (*private_free)(snd_rawmidi_substream_t *substream);
+	void (*private_free)(struct snd_rawmidi_substream *substream);
 };
 
-struct _snd_rawmidi_substream {
+struct snd_rawmidi_substream {
 	struct list_head list;		/* list of all substream for given stream */
 	int stream;			/* direction */
 	int number;			/* substream number */
@@ -97,29 +91,29 @@
 		     active_sensing: 1; /* send active sensing when close */
 	int use_count;			/* use counter (for output) */
 	size_t bytes;
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_str_t *pstr;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_str *pstr;
 	char name[32];
-	snd_rawmidi_runtime_t *runtime;
+	struct snd_rawmidi_runtime *runtime;
 	/* hardware layer */
-	snd_rawmidi_ops_t *ops;
+	struct snd_rawmidi_ops *ops;
 };
 
-typedef struct _snd_rawmidi_file {
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *input;
-	snd_rawmidi_substream_t *output;
-} snd_rawmidi_file_t;
+struct snd_rawmidi_file {
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *input;
+	struct snd_rawmidi_substream *output;
+};
 
-struct _snd_rawmidi_str {
+struct snd_rawmidi_str {
 	unsigned int substream_count;
 	unsigned int substream_opened;
 	struct list_head substreams;
 };
 
-struct _snd_rawmidi {
-	snd_card_t *card;
-
+struct snd_rawmidi {
+	struct snd_card *card;
+	struct list_head list;
 	unsigned int device;		/* device number */
 	unsigned int info_flags;	/* SNDRV_RAWMIDI_INFO_XXXX */
 	char id[64];
@@ -129,52 +123,61 @@
 	int ossreg;
 #endif
 
-	snd_rawmidi_global_ops_t *ops;
+	struct snd_rawmidi_global_ops *ops;
 
-	snd_rawmidi_str_t streams[2];
+	struct snd_rawmidi_str streams[2];
 
 	void *private_data;
-	void (*private_free) (snd_rawmidi_t *rmidi);
+	void (*private_free) (struct snd_rawmidi *rmidi);
 
 	struct semaphore open_mutex;
 	wait_queue_head_t open_wait;
 
-	snd_info_entry_t *dev;
-	snd_info_entry_t *proc_entry;
+	struct snd_info_entry *dev;
+	struct snd_info_entry *proc_entry;
 
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
-	snd_seq_device_t *seq_dev;
+	struct snd_seq_device *seq_dev;
 #endif
 };
 
 /* main rawmidi functions */
 
-int snd_rawmidi_new(snd_card_t * card, char *id, int device,
+int snd_rawmidi_new(struct snd_card *card, char *id, int device,
 		    int output_count, int input_count,
-		    snd_rawmidi_t ** rmidi);
-void snd_rawmidi_set_ops(snd_rawmidi_t * rmidi, int stream, snd_rawmidi_ops_t * ops);
+		    struct snd_rawmidi **rmidi);
+void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
+			 struct snd_rawmidi_ops *ops);
 
 /* callbacks */
 
-void snd_rawmidi_receive_reset(snd_rawmidi_substream_t * substream);
-int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count);
-void snd_rawmidi_transmit_reset(snd_rawmidi_substream_t * substream);
-int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream);
-int snd_rawmidi_transmit_peek(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count);
-int snd_rawmidi_transmit_ack(snd_rawmidi_substream_t * substream, int count);
-int snd_rawmidi_transmit(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count);
+void snd_rawmidi_receive_reset(struct snd_rawmidi_substream *substream);
+int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
+			const unsigned char *buffer, int count);
+void snd_rawmidi_transmit_reset(struct snd_rawmidi_substream *substream);
+int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream);
+int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+			      unsigned char *buffer, int count);
+int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count);
+int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
+			 unsigned char *buffer, int count);
 
 /* main midi functions */
 
-int snd_rawmidi_info_select(snd_card_t *card, snd_rawmidi_info_t *info);
-int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, int mode, snd_rawmidi_file_t * rfile);
-int snd_rawmidi_kernel_release(snd_rawmidi_file_t * rfile);
-int snd_rawmidi_output_params(snd_rawmidi_substream_t * substream, snd_rawmidi_params_t * params);
-int snd_rawmidi_input_params(snd_rawmidi_substream_t * substream, snd_rawmidi_params_t * params);
-int snd_rawmidi_drop_output(snd_rawmidi_substream_t * substream);
-int snd_rawmidi_drain_output(snd_rawmidi_substream_t * substream);
-int snd_rawmidi_drain_input(snd_rawmidi_substream_t * substream);
-long snd_rawmidi_kernel_read(snd_rawmidi_substream_t * substream, unsigned char *buf, long count);
-long snd_rawmidi_kernel_write(snd_rawmidi_substream_t * substream, const unsigned char *buf, long count);
+int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info);
+int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
+			    int mode, struct snd_rawmidi_file *rfile);
+int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile);
+int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
+			      struct snd_rawmidi_params *params);
+int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
+			     struct snd_rawmidi_params *params);
+int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream);
+int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream);
+int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream);
+long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream,
+			     unsigned char *buf, long count);
+long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream,
+			      const unsigned char *buf, long count);
 
 #endif /* __SOUND_RAWMIDI_H */
diff --git a/include/sound/sb.h b/include/sound/sb.h
index 7960452..431d066 100644
--- a/include/sound/sb.h
+++ b/include/sound/sb.h
@@ -60,7 +60,7 @@
 
 #define SB_MPU_INPUT		1
 
-struct _snd_sb {
+struct snd_sb {
 	unsigned long port;		/* base port of DSP chip */
 	struct resource *res_port;
 	unsigned long mpu_port;		/* MPU port for SB DSP 4.0+ */
@@ -92,24 +92,26 @@
 
 	void *csp; /* used only when CONFIG_SND_SB16_CSP is set */
 
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
 
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *midi_substream_input;
-	snd_rawmidi_substream_t *midi_substream_output;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *midi_substream_input;
+	struct snd_rawmidi_substream *midi_substream_output;
 	irqreturn_t (*rmidi_callback)(int irq, void *dev_id, struct pt_regs *regs);
 
 	spinlock_t reg_lock;
 	spinlock_t open_lock;
 	spinlock_t midi_input_lock;
 
-	snd_info_entry_t *proc_entry;
-};
+	struct snd_info_entry *proc_entry;
 
-typedef struct _snd_sb sb_t;
+#ifdef CONFIG_PM
+	unsigned char saved_regs[0x20];
+#endif
+};
 
 /* I/O ports */
 
@@ -267,48 +269,52 @@
  *
  */
 
-static inline void snd_sb_ack_8bit(sb_t *chip)
+static inline void snd_sb_ack_8bit(struct snd_sb *chip)
 {
 	inb(SBP(chip, DATA_AVAIL));
 }
 
-static inline void snd_sb_ack_16bit(sb_t *chip)
+static inline void snd_sb_ack_16bit(struct snd_sb *chip)
 {
 	inb(SBP(chip, DATA_AVAIL_16));
 }
 
 /* sb_common.c */
-int snd_sbdsp_command(sb_t *chip, unsigned char val);
-int snd_sbdsp_get_byte(sb_t *chip);
-int snd_sbdsp_reset(sb_t *chip);
-int snd_sbdsp_create(snd_card_t *card,
+int snd_sbdsp_command(struct snd_sb *chip, unsigned char val);
+int snd_sbdsp_get_byte(struct snd_sb *chip);
+int snd_sbdsp_reset(struct snd_sb *chip);
+int snd_sbdsp_create(struct snd_card *card,
 		     unsigned long port,
 		     int irq,
 		     irqreturn_t (*irq_handler)(int, void *, struct pt_regs *),
 		     int dma8, int dma16,
 		     unsigned short hardware,
-		     sb_t **r_chip);
+		     struct snd_sb **r_chip);
 /* sb_mixer.c */
-void snd_sbmixer_write(sb_t *chip, unsigned char reg, unsigned char data);
-unsigned char snd_sbmixer_read(sb_t *chip, unsigned char reg);
-int snd_sbmixer_new(sb_t *chip);
+void snd_sbmixer_write(struct snd_sb *chip, unsigned char reg, unsigned char data);
+unsigned char snd_sbmixer_read(struct snd_sb *chip, unsigned char reg);
+int snd_sbmixer_new(struct snd_sb *chip);
+#ifdef CONFIG_PM
+void snd_sbmixer_suspend(struct snd_sb *chip);
+void snd_sbmixer_resume(struct snd_sb *chip);
+#endif
 
 /* sb8_init.c */
-int snd_sb8dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm);
+int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm);
 /* sb8.c */
-irqreturn_t snd_sb8dsp_interrupt(sb_t *chip);
-int snd_sb8_playback_open(snd_pcm_substream_t *substream);
-int snd_sb8_capture_open(snd_pcm_substream_t *substream);
-int snd_sb8_playback_close(snd_pcm_substream_t *substream);
-int snd_sb8_capture_close(snd_pcm_substream_t *substream);
+irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip);
+int snd_sb8_playback_open(struct snd_pcm_substream *substream);
+int snd_sb8_capture_open(struct snd_pcm_substream *substream);
+int snd_sb8_playback_close(struct snd_pcm_substream *substream);
+int snd_sb8_capture_close(struct snd_pcm_substream *substream);
 /* midi8.c */
-irqreturn_t snd_sb8dsp_midi_interrupt(sb_t *chip);
-int snd_sb8dsp_midi(sb_t *chip, int device, snd_rawmidi_t ** rrawmidi);
+irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb *chip);
+int snd_sb8dsp_midi(struct snd_sb *chip, int device, struct snd_rawmidi ** rrawmidi);
 
 /* sb16_init.c */
-int snd_sb16dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm);
-const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction);
-int snd_sb16dsp_configure(sb_t *chip);
+int snd_sb16dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm);
+const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction);
+int snd_sb16dsp_configure(struct snd_sb *chip);
 /* sb16.c */
 irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
@@ -328,7 +334,7 @@
 #define SB_MIXVAL_INPUT_SW(reg1, reg2, left_shift, right_shift) \
   ((reg1) | ((reg2) << 8) | ((left_shift) << 16) | ((right_shift) << 24))
 
-int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsigned long value);
+int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int type, unsigned long value);
 
 /* for ease of use */
 struct sbmix_elem {
@@ -352,7 +358,7 @@
   .type = SB_MIX_INPUT_SW, \
   .private_value = SB_MIXVAL_INPUT_SW(reg1, reg2, left_shift, right_shift) }
 
-static inline int snd_sbmixer_add_ctl_elem(sb_t *chip, const struct sbmix_elem *c)
+static inline int snd_sbmixer_add_ctl_elem(struct snd_sb *chip, const struct sbmix_elem *c)
 {
 	return snd_sbmixer_add_ctl(chip, c->name, 0, c->type, c->private_value);
 }
diff --git a/include/sound/sb16_csp.h b/include/sound/sb16_csp.h
index eb8368b..3b44d4b 100644
--- a/include/sound/sb16_csp.h
+++ b/include/sound/sb16_csp.h
@@ -63,25 +63,25 @@
 #define SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE	0x3000
 
 /* microcode header */
-typedef struct snd_sb_csp_mc_header {
+struct snd_sb_csp_mc_header {
 	char codec_name[16];		/* id name of codec */
 	unsigned short func_req;	/* requested function */
-} snd_sb_csp_mc_header_t;
+};
 
 /* microcode to be loaded */
-typedef struct snd_sb_csp_microcode {
-	snd_sb_csp_mc_header_t info;
+struct snd_sb_csp_microcode {
+	struct snd_sb_csp_mc_header info;
 	unsigned char data[SNDRV_SB_CSP_MAX_MICROCODE_FILE_SIZE];
-} snd_sb_csp_microcode_t;
+};
 
 /* start CSP with sample_width in mono/stereo */
-typedef struct snd_sb_csp_start {
+struct snd_sb_csp_start {
 	int sample_width;	/* sample width, look above */
 	int channels;		/* channels, look above */
-} snd_sb_csp_start_t;
+};
 
 /* CSP information */
-typedef struct snd_sb_csp_info {
+struct snd_sb_csp_info {
 	char codec_name[16];		/* id name of codec */
 	unsigned short func_nr;		/* function number */
 	unsigned int acc_format;	/* accepted PCM formats */
@@ -93,17 +93,17 @@
 	unsigned short run_width;	/* current sample width */
 	unsigned short version;		/* version id: 0x10 - 0x1f */
 	unsigned short state;		/* state bits */
-} snd_sb_csp_info_t;
+};
 
 /* HWDEP controls */
 /* get CSP information */
-#define SNDRV_SB_CSP_IOCTL_INFO		_IOR('H', 0x10, snd_sb_csp_info_t)
+#define SNDRV_SB_CSP_IOCTL_INFO		_IOR('H', 0x10, struct snd_sb_csp_info)
 /* load microcode to CSP */
-#define SNDRV_SB_CSP_IOCTL_LOAD_CODE	_IOW('H', 0x11, snd_sb_csp_microcode_t)
+#define SNDRV_SB_CSP_IOCTL_LOAD_CODE	_IOW('H', 0x11, struct snd_sb_csp_microcode)
 /* unload microcode from CSP */
 #define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE	_IO('H', 0x12)
 /* start CSP */
-#define SNDRV_SB_CSP_IOCTL_START		_IOW('H', 0x13, snd_sb_csp_start_t)
+#define SNDRV_SB_CSP_IOCTL_START		_IOW('H', 0x13, struct snd_sb_csp_start)
 /* stop CSP */
 #define SNDRV_SB_CSP_IOCTL_STOP		_IO('H', 0x14)
 /* pause CSP and DMA transfer */
@@ -115,25 +115,25 @@
 #include "sb.h"
 #include "hwdep.h"
 
-typedef struct snd_sb_csp snd_sb_csp_t;
+struct snd_sb_csp;
 
 /*
  * CSP operators
  */
-typedef struct {
-	int (*csp_use) (snd_sb_csp_t * p);
-	int (*csp_unuse) (snd_sb_csp_t * p);
-	int (*csp_autoload) (snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode);
-	int (*csp_start) (snd_sb_csp_t * p, int sample_width, int channels);
-	int (*csp_stop) (snd_sb_csp_t * p);
-	int (*csp_qsound_transfer) (snd_sb_csp_t * p);
-} snd_sb_csp_ops_t;
+struct snd_sb_csp_ops {
+	int (*csp_use) (struct snd_sb_csp * p);
+	int (*csp_unuse) (struct snd_sb_csp * p);
+	int (*csp_autoload) (struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode);
+	int (*csp_start) (struct snd_sb_csp * p, int sample_width, int channels);
+	int (*csp_stop) (struct snd_sb_csp * p);
+	int (*csp_qsound_transfer) (struct snd_sb_csp * p);
+};
 
 /*
  * CSP private data
  */
 struct snd_sb_csp {
-	sb_t *chip;		/* SB16 DSP */
+	struct snd_sb *chip;		/* SB16 DSP */
 	int used;		/* usage flag - exclusive */
 	char codec_name[16];	/* name of codec */
 	unsigned short func_nr;	/* function number */
@@ -147,7 +147,7 @@
 	int version;		/* CSP version (0x10 - 0x1f) */
 	int running;		/* running state */
 
-	snd_sb_csp_ops_t ops;	/* operators */
+	struct snd_sb_csp_ops ops;	/* operators */
 
 	spinlock_t q_lock;	/* locking */
 	int q_enabled;		/* enabled flag */
@@ -155,13 +155,13 @@
 	int qpos_right;		/* right position */
 	int qpos_changed;	/* position changed flag */
 
-	snd_kcontrol_t *qsound_switch;
-	snd_kcontrol_t *qsound_space;
+	struct snd_kcontrol *qsound_switch;
+	struct snd_kcontrol *qsound_space;
 
 	struct semaphore access_mutex;	/* locking */
 };
 
-int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep);
+int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep);
 #endif
 
 #endif /* __SOUND_SB16_CSP */
diff --git a/include/sound/seq_device.h b/include/sound/seq_device.h
index 204ca54..2b5f24c 100644
--- a/include/sound/seq_device.h
+++ b/include/sound/seq_device.h
@@ -21,9 +21,6 @@
  *
  */
 
-typedef struct snd_seq_device snd_seq_device_t;
-typedef struct snd_seq_dev_ops snd_seq_dev_ops_t;
-
 /*
  * registered device information
  */
@@ -36,7 +33,7 @@
 
 struct snd_seq_device {
 	/* device info */
-	snd_card_t *card;	/* sound card */
+	struct snd_card *card;	/* sound card */
 	int device;		/* device number */
 	char id[ID_LEN];	/* driver id */
 	char name[80];		/* device name */
@@ -44,7 +41,7 @@
 	void *driver_data;	/* private data for driver */
 	int status;		/* flag - read only */
 	void *private_data;	/* private data for the caller */
-	void (*private_free)(snd_seq_device_t *device);
+	void (*private_free)(struct snd_seq_device *device);
 	struct list_head list;	/* link to next device */
 };
 
@@ -63,19 +60,19 @@
  *	Typically, call snd_device_free(dev->card, dev->driver_data)
  */
 struct snd_seq_dev_ops {
-	int (*init_device)(snd_seq_device_t *dev);
-	int (*free_device)(snd_seq_device_t *dev);
+	int (*init_device)(struct snd_seq_device *dev);
+	int (*free_device)(struct snd_seq_device *dev);
 };
 
 /*
  * prototypes
  */
 void snd_seq_device_load_drivers(void);
-int snd_seq_device_new(snd_card_t *card, int device, char *id, int argsize, snd_seq_device_t **result);
-int snd_seq_device_register_driver(char *id, snd_seq_dev_ops_t *entry, int argsize);
+int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize, struct snd_seq_device **result);
+int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry, int argsize);
 int snd_seq_device_unregister_driver(char *id);
 
-#define SNDRV_SEQ_DEVICE_ARGPTR(dev) (void *)((char *)(dev) + sizeof(snd_seq_device_t))
+#define SNDRV_SEQ_DEVICE_ARGPTR(dev) (void *)((char *)(dev) + sizeof(struct snd_seq_device))
 
 
 /*
@@ -84,5 +81,4 @@
 #define SNDRV_SEQ_DEV_ID_MIDISYNTH	"seq-midi"
 #define SNDRV_SEQ_DEV_ID_OPL3		"opl3-synth"
 
-
 #endif /* __SOUND_SEQ_DEVICE_H */
diff --git a/include/sound/seq_instr.h b/include/sound/seq_instr.h
index 1a654df..db764f0 100644
--- a/include/sound/seq_instr.h
+++ b/include/sound/seq_instr.h
@@ -24,29 +24,27 @@
 #include "seq_kernel.h"
 
 /* Instrument cluster */
-typedef struct _snd_seq_kcluster {
+struct snd_seq_kcluster {
 	snd_seq_instr_cluster_t cluster;
 	char name[32];
 	int priority;
-	struct _snd_seq_kcluster *next;
-} snd_seq_kcluster_t;
+	struct snd_seq_kcluster *next;
+};
 
 /* return pointer to private data */
-#define KINSTR_DATA(kinstr)	(void *)(((char *)kinstr) + sizeof(snd_seq_kinstr_t))
-
-typedef struct snd_seq_kinstr_ops snd_seq_kinstr_ops_t;
+#define KINSTR_DATA(kinstr)	(void *)(((char *)kinstr) + sizeof(struct snd_seq_kinstr))
 
 /* Instrument structure */
-typedef struct _snd_seq_kinstr {
-	snd_seq_instr_t instr;
+struct snd_seq_kinstr {
+	struct snd_seq_instr instr;
 	char name[32];
 	int type;			/* instrument type */
 	int use;			/* use count */
 	int busy;			/* not useable */
 	int add_len;			/* additional length */
-	snd_seq_kinstr_ops_t *ops;	/* operations */
-	struct _snd_seq_kinstr *next;
-} snd_seq_kinstr_t;
+	struct snd_seq_kinstr_ops *ops;	/* operations */
+	struct snd_seq_kinstr *next;
+};
 
 #define SNDRV_SEQ_INSTR_HASH_SIZE		32
 
@@ -54,11 +52,11 @@
 #define SNDRV_SEQ_INSTR_FLG_DIRECT	(1<<0)	/* accept only direct events */
 
 /* List of all instruments */
-typedef struct {
-	snd_seq_kinstr_t *hash[SNDRV_SEQ_INSTR_HASH_SIZE];
+struct snd_seq_kinstr_list {
+	struct snd_seq_kinstr *hash[SNDRV_SEQ_INSTR_HASH_SIZE];
 	int count;			/* count of all instruments */
 	
-	snd_seq_kcluster_t *chash[SNDRV_SEQ_INSTR_HASH_SIZE];
+	struct snd_seq_kcluster *chash[SNDRV_SEQ_INSTR_HASH_SIZE];
 	int ccount;			/* count of all clusters */
 
 	int owner;			/* current owner of the instrument list */
@@ -68,7 +66,7 @@
 	spinlock_t ops_lock;
 	struct semaphore ops_mutex;
 	unsigned long ops_flags;
-} snd_seq_kinstr_list_t;
+};
 
 #define SNDRV_SEQ_INSTR_NOTIFY_REMOVE	0
 #define SNDRV_SEQ_INSTR_NOTIFY_CHANGE	1
@@ -78,33 +76,33 @@
 	long add_len;			/* additional length */
 	char *instr_type;
 	int (*info)(void *private_data, char *info_data, long len);
-	int (*put)(void *private_data, snd_seq_kinstr_t *kinstr,
+	int (*put)(void *private_data, struct snd_seq_kinstr *kinstr,
 		   char __user *instr_data, long len, int atomic, int cmd);
-	int (*get)(void *private_data, snd_seq_kinstr_t *kinstr,
+	int (*get)(void *private_data, struct snd_seq_kinstr *kinstr,
 		   char __user *instr_data, long len, int atomic, int cmd);
-	int (*get_size)(void *private_data, snd_seq_kinstr_t *kinstr, long *size);
-	int (*remove)(void *private_data, snd_seq_kinstr_t *kinstr, int atomic);
-	void (*notify)(void *private_data, snd_seq_kinstr_t *kinstr, int what);
+	int (*get_size)(void *private_data, struct snd_seq_kinstr *kinstr, long *size);
+	int (*remove)(void *private_data, struct snd_seq_kinstr *kinstr, int atomic);
+	void (*notify)(void *private_data, struct snd_seq_kinstr *kinstr, int what);
 	struct snd_seq_kinstr_ops *next;
 };
 
 
 /* instrument operations */
-snd_seq_kinstr_list_t *snd_seq_instr_list_new(void);
-void snd_seq_instr_list_free(snd_seq_kinstr_list_t **list);
-int snd_seq_instr_list_free_cond(snd_seq_kinstr_list_t *list,
-				 snd_seq_instr_header_t *ifree,
+struct snd_seq_kinstr_list *snd_seq_instr_list_new(void);
+void snd_seq_instr_list_free(struct snd_seq_kinstr_list **list);
+int snd_seq_instr_list_free_cond(struct snd_seq_kinstr_list *list,
+				 struct snd_seq_instr_header *ifree,
 				 int client,
 				 int atomic);
-snd_seq_kinstr_t *snd_seq_instr_find(snd_seq_kinstr_list_t *list,
-				     snd_seq_instr_t *instr,
-				     int exact,
-				     int follow_alias);
-void snd_seq_instr_free_use(snd_seq_kinstr_list_t *list,
-			    snd_seq_kinstr_t *instr);
-int snd_seq_instr_event(snd_seq_kinstr_ops_t *ops,
-			snd_seq_kinstr_list_t *list,
-			snd_seq_event_t *ev,
+struct snd_seq_kinstr *snd_seq_instr_find(struct snd_seq_kinstr_list *list,
+					  struct snd_seq_instr *instr,
+					  int exact,
+					  int follow_alias);
+void snd_seq_instr_free_use(struct snd_seq_kinstr_list *list,
+			    struct snd_seq_kinstr *instr);
+int snd_seq_instr_event(struct snd_seq_kinstr_ops *ops,
+			struct snd_seq_kinstr_list *list,
+			struct snd_seq_event *ev,
 			int client,
 			int atomic,
 			int hop);
diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
index 4beca19..f023c1b 100644
--- a/include/sound/seq_kernel.h
+++ b/include/sound/seq_kernel.h
@@ -24,62 +24,8 @@
 #include <linux/time.h>
 #include "asequencer.h"
 
-typedef sndrv_seq_tick_time_t snd_seq_tick_time_t;
-typedef sndrv_seq_position_t snd_seq_position_t;
-typedef sndrv_seq_frequency_t snd_seq_frequency_t;
-typedef sndrv_seq_instr_cluster_t snd_seq_instr_cluster_t;
-typedef enum sndrv_seq_client_type snd_seq_client_type_t;
-typedef enum sndrv_seq_stop_mode snd_seq_stop_mode_t;
-typedef struct sndrv_seq_port_info snd_seq_port_info_t;
-typedef struct sndrv_seq_port_subscribe snd_seq_port_subscribe_t;
-typedef struct sndrv_seq_event snd_seq_event_t;
-typedef struct sndrv_seq_addr snd_seq_addr_t;
-typedef struct sndrv_seq_ev_volume snd_seq_ev_volume_t;
-typedef struct sndrv_seq_ev_loop snd_seq_ev_loop_t;
-typedef struct sndrv_seq_remove_events snd_seq_remove_events_t;
-typedef struct sndrv_seq_query_subs snd_seq_query_subs_t;
-typedef struct sndrv_seq_real_time snd_seq_real_time_t;
-typedef struct sndrv_seq_system_info snd_seq_system_info_t;
-typedef struct sndrv_seq_client_info snd_seq_client_info_t;
-typedef struct sndrv_seq_queue_info snd_seq_queue_info_t;
-typedef struct sndrv_seq_queue_status snd_seq_queue_status_t;
-typedef struct sndrv_seq_queue_tempo snd_seq_queue_tempo_t;
-typedef struct sndrv_seq_queue_owner snd_seq_queue_owner_t;
-typedef struct sndrv_seq_queue_timer snd_seq_queue_timer_t;
-typedef struct sndrv_seq_queue_client snd_seq_queue_client_t;
-typedef struct sndrv_seq_client_pool snd_seq_client_pool_t;
-typedef struct sndrv_seq_instr snd_seq_instr_t;
-typedef struct sndrv_seq_instr_data snd_seq_instr_data_t;
-typedef struct sndrv_seq_instr_header snd_seq_instr_header_t;
-typedef union sndrv_seq_timestamp snd_seq_timestamp_t;
-
-#define snd_seq_event_bounce_ext_data	sndrv_seq_event_bounce_ext_data 
-#define snd_seq_ev_is_result_type	sndrv_seq_ev_is_result_type     
-#define snd_seq_ev_is_channel_type	sndrv_seq_ev_is_channel_type    
-#define snd_seq_ev_is_note_type		sndrv_seq_ev_is_note_type       
-#define snd_seq_ev_is_control_type	sndrv_seq_ev_is_control_type    
-#define snd_seq_ev_is_queue_type	sndrv_seq_ev_is_queue_type      
-#define snd_seq_ev_is_message_type	sndrv_seq_ev_is_message_type    
-#define snd_seq_ev_is_sample_type	sndrv_seq_ev_is_sample_type     
-#define snd_seq_ev_is_user_type		sndrv_seq_ev_is_user_type       
-#define snd_seq_ev_is_fixed_type	sndrv_seq_ev_is_fixed_type      
-#define snd_seq_ev_is_instr_type	sndrv_seq_ev_is_instr_type      
-#define snd_seq_ev_is_variable_type	sndrv_seq_ev_is_variable_type   
-#define snd_seq_ev_is_reserved		sndrv_seq_ev_is_reserved        
-#define snd_seq_ev_is_direct		sndrv_seq_ev_is_direct          
-#define snd_seq_ev_is_prior		sndrv_seq_ev_is_prior           
-#define snd_seq_ev_length_type		sndrv_seq_ev_length_type        
-#define snd_seq_ev_is_fixed		sndrv_seq_ev_is_fixed           
-#define snd_seq_ev_is_variable		sndrv_seq_ev_is_variable        
-#define snd_seq_ev_is_varusr		sndrv_seq_ev_is_varusr          
-#define snd_seq_ev_timestamp_type	sndrv_seq_ev_timestamp_type     
-#define snd_seq_ev_is_tick		sndrv_seq_ev_is_tick            
-#define snd_seq_ev_is_real		sndrv_seq_ev_is_real            
-#define snd_seq_ev_timemode_type	sndrv_seq_ev_timemode_type      
-#define snd_seq_ev_is_abstime		sndrv_seq_ev_is_abstime         
-#define snd_seq_ev_is_reltime		sndrv_seq_ev_is_reltime         
-#define snd_seq_queue_sync_port		sndrv_seq_queue_sync_port       
-#define snd_seq_queue_owner		sndrv_seq_queue_owner           
+typedef struct snd_seq_real_time snd_seq_real_time_t;
+typedef union snd_seq_timestamp snd_seq_timestamp_t;
 
 /* maximum number of events dequeued per schedule interval */
 #define SNDRV_SEQ_MAX_DEQUEUE		50
@@ -114,69 +60,48 @@
 /* max size of event size */
 #define SNDRV_SEQ_MAX_EVENT_LEN		0x3fffffff
 
-/* typedefs */
-struct _snd_seq_user_client;
-struct _snd_seq_kernel_client;
-struct _snd_seq_client;
-struct _snd_seq_queue;
-
-typedef struct _snd_seq_user_client user_client_t;
-typedef struct _snd_seq_kernel_client kernel_client_t;
-typedef struct _snd_seq_client client_t;
-typedef struct _snd_seq_queue queue_t;
-
-/* call-backs for kernel client */
-
-typedef struct {
-	void *private_data;
-	unsigned allow_input: 1,
-		 allow_output: 1;
-	/*...*/
-} snd_seq_client_callback_t;
-
 /* call-backs for kernel port */
-typedef int (snd_seq_kernel_port_open_t)(void *private_data, snd_seq_port_subscribe_t *info);
-typedef int (snd_seq_kernel_port_close_t)(void *private_data, snd_seq_port_subscribe_t *info);
-typedef int (snd_seq_kernel_port_input_t)(snd_seq_event_t *ev, int direct, void *private_data, int atomic, int hop);
-typedef void (snd_seq_kernel_port_private_free_t)(void *private_data);
-
-typedef struct {
+struct snd_seq_port_callback {
 	struct module *owner;
 	void *private_data;
-	snd_seq_kernel_port_open_t *subscribe;
-	snd_seq_kernel_port_close_t *unsubscribe;
-	snd_seq_kernel_port_open_t *use;
-	snd_seq_kernel_port_close_t *unuse;
-	snd_seq_kernel_port_input_t *event_input;
-	snd_seq_kernel_port_private_free_t *private_free;
+	int (*subscribe)(void *private_data, struct snd_seq_port_subscribe *info);
+	int (*unsubscribe)(void *private_data, struct snd_seq_port_subscribe *info);
+	int (*use)(void *private_data, struct snd_seq_port_subscribe *info);
+	int (*unuse)(void *private_data, struct snd_seq_port_subscribe *info);
+	int (*event_input)(struct snd_seq_event *ev, int direct, void *private_data, int atomic, int hop);
+	void (*private_free)(void *private_data);
 	unsigned int callback_all;	/* call subscribe callbacks at each connection/disconnection */
 	/*...*/
-} snd_seq_port_callback_t;
+};
 
 /* interface for kernel client */
-extern int snd_seq_create_kernel_client(snd_card_t *card, int client_index, snd_seq_client_callback_t *callback);
-extern int snd_seq_delete_kernel_client(int client);
-extern int snd_seq_kernel_client_enqueue(int client, snd_seq_event_t *ev, int atomic, int hop);
-extern int snd_seq_kernel_client_dispatch(int client, snd_seq_event_t *ev, int atomic, int hop);
-extern int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void *arg);
+int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
+				 const char *name_fmt, ...)
+	__attribute__ ((format (printf, 3, 4)));
+int snd_seq_delete_kernel_client(int client);
+int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev, int atomic, int hop);
+int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event *ev, int atomic, int hop);
+int snd_seq_kernel_client_ctl(int client, unsigned int cmd, void *arg);
 
 #define SNDRV_SEQ_EXT_MASK	0xc0000000
 #define SNDRV_SEQ_EXT_USRPTR	0x80000000
 #define SNDRV_SEQ_EXT_CHAINED	0x40000000
 
 typedef int (*snd_seq_dump_func_t)(void *ptr, void *buf, int count);
-int snd_seq_expand_var_event(const snd_seq_event_t *event, int count, char *buf, int in_kernel, int size_aligned);
-int snd_seq_dump_var_event(const snd_seq_event_t *event, snd_seq_dump_func_t func, void *private_data);
+int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char *buf,
+			     int in_kernel, int size_aligned);
+int snd_seq_dump_var_event(const struct snd_seq_event *event,
+			   snd_seq_dump_func_t func, void *private_data);
 
 /* interface for OSS emulation */
-int snd_seq_set_queue_tempo(int client, snd_seq_queue_tempo_t *tempo);
+int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo);
 
 /* port callback routines */
-void snd_port_init_callback(snd_seq_port_callback_t *p);
-snd_seq_port_callback_t *snd_port_alloc_callback(void);
+void snd_port_init_callback(struct snd_seq_port_callback *p);
+struct snd_seq_port_callback *snd_port_alloc_callback(void);
 
 /* port attach/detach */
-int snd_seq_event_port_attach(int client, snd_seq_port_callback_t *pcbp,
+int snd_seq_event_port_attach(int client, struct snd_seq_port_callback *pcbp,
 			      int cap, int type, int midi_channels, int midi_voices, char *portname);
 int snd_seq_event_port_detach(int client, int port);
 
diff --git a/include/sound/seq_midi_emul.h b/include/sound/seq_midi_emul.h
index e58ca45..d6c4615 100644
--- a/include/sound/seq_midi_emul.h
+++ b/include/sound/seq_midi_emul.h
@@ -29,7 +29,7 @@
  * channel.  All drivers for hardware that does not understand midi
  * directly will probably need to use this structure.
  */
-typedef struct snd_midi_channel {
+struct snd_midi_channel {
 	void *private;		/* A back pointer to driver data */
 	int  number;		/* The channel number */
 	int  client;		/* The client associated with this channel */
@@ -53,41 +53,43 @@
 	short gm_rpn_fine_tuning; 	/* Master fine tuning */
 	short gm_rpn_coarse_tuning;	/* Master coarse tuning */
 
-} snd_midi_channel_t;
+};
 
 /*
  * A structure that represets a set of channels bound to a port.  There
  * would usually be 16 channels per port.  But fewer could be used for
  * particular cases.
  * The channel set consists of information describing the client and
- * port for this midi synth and an array of snd_midi_channel_t structures.
- * A driver that had no need for snd_midi_channel_t could still use the
+ * port for this midi synth and an array of snd_midi_channel structures.
+ * A driver that had no need for snd_midi_channel could still use the
  * channel set type if it wished with the channel array null.
  */
-typedef struct snd_midi_channel_set {
+struct snd_midi_channel_set {
 	void *private_data;		/* Driver data */
 	int  client;			/* Client for this port */
 	int  port;			/* The port number */
 
 	int  max_channels;		/* Size of the channels array */
-	snd_midi_channel_t *channels;
+	struct snd_midi_channel *channels;
 
 	unsigned char midi_mode;	/* MIDI operating mode */
 	unsigned char gs_master_volume;	/* SYSEX master volume: 0-127 */
 	unsigned char gs_chorus_mode;
 	unsigned char gs_reverb_mode;
 
-} snd_midi_channel_set_t;
+};
 
-typedef struct snd_seq_midi_op {
-	void (*note_on)(void *private_data, int note, int vel, snd_midi_channel_t *chan);
-	void (*note_off)(void *private_data,int note, int vel, snd_midi_channel_t *chan); /* release note */
-	void (*key_press)(void *private_data, int note, int vel, snd_midi_channel_t *chan);
-	void (*note_terminate)(void *private_data, int note, snd_midi_channel_t *chan); /* terminate note immediately */
-	void (*control)(void *private_data, int type, snd_midi_channel_t *chan);
-	void (*nrpn)(void *private_data, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);
-	void (*sysex)(void *private_data, unsigned char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
-} snd_midi_op_t;
+struct snd_midi_op {
+	void (*note_on)(void *private_data, int note, int vel, struct snd_midi_channel *chan);
+	void (*note_off)(void *private_data,int note, int vel, struct snd_midi_channel *chan); /* release note */
+	void (*key_press)(void *private_data, int note, int vel, struct snd_midi_channel *chan);
+	void (*note_terminate)(void *private_data, int note, struct snd_midi_channel *chan); /* terminate note immediately */
+	void (*control)(void *private_data, int type, struct snd_midi_channel *chan);
+	void (*nrpn)(void *private_data, struct snd_midi_channel *chan,
+		     struct snd_midi_channel_set *chset);
+	void (*sysex)(void *private_data, unsigned char *buf, int len, int parsed,
+		      struct snd_midi_channel_set *chset);
+};
 
 /*
  * These defines are used so that pitchbend, aftertouch etc, can be
@@ -186,10 +188,10 @@
 };
 
 /* Prototypes for midi_process.c */
-void snd_midi_process_event(snd_midi_op_t *ops, snd_seq_event_t *ev,
-			    snd_midi_channel_set_t *chanset);
-void snd_midi_channel_set_clear(snd_midi_channel_set_t *chset);
-snd_midi_channel_set_t *snd_midi_channel_alloc_set(int n);
-void snd_midi_channel_free_set(snd_midi_channel_set_t *chset);
+void snd_midi_process_event(struct snd_midi_op *ops, struct snd_seq_event *ev,
+			    struct snd_midi_channel_set *chanset);
+void snd_midi_channel_set_clear(struct snd_midi_channel_set *chset);
+struct snd_midi_channel_set *snd_midi_channel_alloc_set(int n);
+void snd_midi_channel_free_set(struct snd_midi_channel_set *chset);
 
 #endif /* __SOUND_SEQ_MIDI_EMUL_H */
diff --git a/include/sound/seq_midi_event.h b/include/sound/seq_midi_event.h
index 8857e2b..dd789e7 100644
--- a/include/sound/seq_midi_event.h
+++ b/include/sound/seq_midi_event.h
@@ -26,10 +26,8 @@
 
 #define MAX_MIDI_EVENT_BUF	256
 
-typedef struct snd_midi_event_t snd_midi_event_t;
-
 /* midi status */
-struct snd_midi_event_t {
+struct snd_midi_event {
 	int qlen;		/* queue length */
 	int read;		/* chars read */
 	int type;		/* current event type */
@@ -40,15 +38,17 @@
 	spinlock_t lock;
 };
 
-int snd_midi_event_new(int bufsize, snd_midi_event_t **rdev);
-void snd_midi_event_free(snd_midi_event_t *dev);
-void snd_midi_event_reset_encode(snd_midi_event_t *dev);
-void snd_midi_event_reset_decode(snd_midi_event_t *dev);
-void snd_midi_event_no_status(snd_midi_event_t *dev, int on);
+int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev);
+void snd_midi_event_free(struct snd_midi_event *dev);
+void snd_midi_event_reset_encode(struct snd_midi_event *dev);
+void snd_midi_event_reset_decode(struct snd_midi_event *dev);
+void snd_midi_event_no_status(struct snd_midi_event *dev, int on);
 /* encode from byte stream - return number of written bytes if success */
-long snd_midi_event_encode(snd_midi_event_t *dev, unsigned char *buf, long count, snd_seq_event_t *ev);
-int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev);
+long snd_midi_event_encode(struct snd_midi_event *dev, unsigned char *buf, long count,
+			   struct snd_seq_event *ev);
+int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c, struct snd_seq_event *ev);
 /* decode from event to bytes - return number of written bytes if success */
-long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, snd_seq_event_t *ev);
+long snd_midi_event_decode(struct snd_midi_event *dev, unsigned char *buf, long count,
+			   struct snd_seq_event *ev);
 
 #endif /* __SOUND_SEQ_MIDI_EVENT_H */
diff --git a/include/sound/seq_oss.h b/include/sound/seq_oss.h
index bd7e573..9b060bb 100644
--- a/include/sound/seq_oss.h
+++ b/include/sound/seq_oss.h
@@ -25,22 +25,16 @@
 #include "seq_kernel.h"
 
 /*
- * type definitions
- */
-typedef struct snd_seq_oss_arg_t snd_seq_oss_arg_t;
-typedef struct snd_seq_oss_callback_t snd_seq_oss_callback_t;
-
-/*
  * argument structure for synthesizer operations
  */
-struct snd_seq_oss_arg_t {
+struct snd_seq_oss_arg {
 	/* given by OSS sequencer */
 	int app_index;	/* application unique index */
 	int file_mode;	/* file mode - see below */
 	int seq_mode;	/* sequencer mode - see below */
 
 	/* following must be initialized in open callback */
-	snd_seq_addr_t addr;	/* opened port address */
+	struct snd_seq_addr addr;	/* opened port address */
 	void *private_data;	/* private data for lowlevel drivers */
 
 	/* note-on event passing mode: initially given by OSS seq,
@@ -53,14 +47,14 @@
 /*
  * synthesizer operation callbacks
  */
-struct snd_seq_oss_callback_t {
+struct snd_seq_oss_callback {
 	struct module *owner;
-	int (*open)(snd_seq_oss_arg_t *p, void *closure);
-	int (*close)(snd_seq_oss_arg_t *p);
-	int (*ioctl)(snd_seq_oss_arg_t *p, unsigned int cmd, unsigned long arg);
-	int (*load_patch)(snd_seq_oss_arg_t *p, int format, const char __user *buf, int offs, int count);
-	int (*reset)(snd_seq_oss_arg_t *p);
-	int (*raw_event)(snd_seq_oss_arg_t *p, unsigned char *data);
+	int (*open)(struct snd_seq_oss_arg *p, void *closure);
+	int (*close)(struct snd_seq_oss_arg *p);
+	int (*ioctl)(struct snd_seq_oss_arg *p, unsigned int cmd, unsigned long arg);
+	int (*load_patch)(struct snd_seq_oss_arg *p, int format, const char __user *buf, int offs, int count);
+	int (*reset)(struct snd_seq_oss_arg *p);
+	int (*raw_event)(struct snd_seq_oss_arg *p, unsigned char *data);
 };
 
 /* flag: file_mode */
@@ -88,13 +82,13 @@
 /*
  * data pointer to snd_seq_register_device
  */
-typedef struct snd_seq_oss_reg {
+struct snd_seq_oss_reg {
 	int type;
 	int subtype;
 	int nvoices;
-	snd_seq_oss_callback_t oper;
+	struct snd_seq_oss_callback oper;
 	void *private_data;
-} snd_seq_oss_reg_t;
+};
 
 /* device id */
 #define SNDRV_SEQ_DEV_ID_OSS		"seq-oss"
diff --git a/include/sound/seq_virmidi.h b/include/sound/seq_virmidi.h
index 1ad27e8..8d5aea7 100644
--- a/include/sound/seq_virmidi.h
+++ b/include/sound/seq_virmidi.h
@@ -25,25 +25,23 @@
 #include "rawmidi.h"
 #include "seq_midi_event.h"
 
-typedef struct _snd_virmidi_dev snd_virmidi_dev_t;
-
 /*
  * device file instance:
  * This instance is created at each time the midi device file is
  * opened.  Each instance has its own input buffer and MIDI parser
  * (buffer), and is associated with the device instance.
  */
-typedef struct _snd_virmidi {
+struct snd_virmidi {
 	struct list_head list;
 	int seq_mode;
 	int client;
 	int port;
 	unsigned int trigger: 1;
-	snd_midi_event_t *parser;
-	snd_seq_event_t event;
-	snd_virmidi_dev_t *rdev;
-	snd_rawmidi_substream_t *substream;
-} snd_virmidi_t;
+	struct snd_midi_event *parser;
+	struct snd_seq_event event;
+	struct snd_virmidi_dev *rdev;
+	struct snd_rawmidi_substream *substream;
+};
 
 #define SNDRV_VIRMIDI_SUBSCRIBE		(1<<0)
 #define SNDRV_VIRMIDI_USE		(1<<1)
@@ -53,9 +51,9 @@
  * Each virtual midi device has one device instance.  It contains
  * common information and the linked-list of opened files, 
  */
-struct _snd_virmidi_dev {
-	snd_card_t *card;		/* associated card */
-	snd_rawmidi_t *rmidi;		/* rawmidi device */
+struct snd_virmidi_dev {
+	struct snd_card *card;		/* associated card */
+	struct snd_rawmidi *rmidi;		/* rawmidi device */
 	int seq_mode;			/* SNDRV_VIRMIDI_XXX */
 	int device;			/* sequencer device */
 	int client;			/* created/attached client */
@@ -78,6 +76,6 @@
 #define SNDRV_VIRMIDI_SEQ_ATTACH	1
 #define SNDRV_VIRMIDI_SEQ_DISPATCH	2
 
-int snd_virmidi_new(snd_card_t *card, int device, snd_rawmidi_t **rrmidi);
+int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmidi);
 
 #endif /* __SOUND_SEQ_VIRMIDI */
diff --git a/include/sound/sfnt_info.h b/include/sound/sfnt_info.h
index 674585f..5d1ab9c 100644
--- a/include/sound/sfnt_info.h
+++ b/include/sound/sfnt_info.h
@@ -35,7 +35,7 @@
 #endif
 
 /* patch interface header: 16 bytes */
-typedef struct soundfont_patch_info_t {
+struct soundfont_patch_info {
 	unsigned short key;		/* use the key below */
 #define SNDRV_OSS_SOUNDFONT_PATCH		SNDRV_OSS_PATCHKEY(0x07)
 
@@ -59,7 +59,7 @@
 	short reserved;			/* word alignment data */
 
 	/* the actual patch data begins after this */
-} soundfont_patch_info_t;
+};
 
 
 /*
@@ -68,7 +68,7 @@
 
 #define SNDRV_SFNT_PATCH_NAME_LEN	32
 
-typedef struct soundfont_open_parm_t {
+struct soundfont_open_parm {
 	unsigned short type;		/* sample type */
 #define SNDRV_SFNT_PAT_TYPE_MISC	0
 #define SNDRV_SFNT_PAT_TYPE_GUS	6
@@ -78,7 +78,7 @@
 
 	short reserved;
 	char name[SNDRV_SFNT_PATCH_NAME_LEN];
-} soundfont_open_parm_t;
+};
 
 
 /*
@@ -86,7 +86,7 @@
  */
 
 /* wave table envelope & effect parameters to control EMU8000 */
-typedef struct soundfont_voice_parm_t {
+struct soundfont_voice_parm {
 	unsigned short moddelay;	/* modulation delay (0x8000) */
 	unsigned short modatkhld;	/* modulation attack & hold time (0x7f7f) */
 	unsigned short moddcysus;	/* modulation decay & sustain (0x7f7f) */
@@ -108,11 +108,11 @@
 	unsigned char chorus;		/* chorus send (0x00) */
 	unsigned char reverb;		/* reverb send (0x00) */
 	unsigned short reserved[4];	/* not used */
-} soundfont_voice_parm_t;
+};
 
 
 /* wave table parameters: 92 bytes */
-typedef struct soundfont_voice_info_t {
+struct soundfont_voice_info {
 	unsigned short sf_id;		/* file id (should be zero) */
 	unsigned short sample;		/* sample id */
 	int start, end;			/* sample offset correction */
@@ -135,13 +135,13 @@
 	unsigned char amplitude;	/* sample volume (127 max) */
 	unsigned char attenuation;	/* attenuation (0.375dB) */
 	short scaleTuning;		/* pitch scale tuning(%), normally 100 */
-	soundfont_voice_parm_t parm;	/* voice envelope parameters */
+	struct soundfont_voice_parm parm;	/* voice envelope parameters */
 	unsigned short sample_mode;	/* sample mode_flag (set by driver) */
-} soundfont_voice_info_t;
+};
 
 
 /* instrument info header: 4 bytes */
-typedef struct soundfont_voice_rec_hdr_t {
+struct soundfont_voice_rec_hdr {
 	unsigned char bank;		/* midi bank number */
 	unsigned char instr;		/* midi preset number */
 	char nvoices;			/* number of voices */
@@ -149,7 +149,7 @@
 #define SNDRV_SFNT_WR_APPEND		0	/* append anyway */
 #define SNDRV_SFNT_WR_EXCLUSIVE		1	/* skip if already exists */
 #define SNDRV_SFNT_WR_REPLACE		2	/* replace if already exists */
-} soundfont_voice_rec_hdr_t;
+};
 
 
 /*
@@ -157,7 +157,7 @@
  */
 
 /* wave table sample header: 32 bytes */
-typedef struct soundfont_sample_info_t {
+struct soundfont_sample_info {
 	unsigned short sf_id;		/* file id (should be zero) */
 	unsigned short sample;		/* sample id */
 	int start, end;			/* start & end offset */
@@ -174,17 +174,17 @@
 #define SNDRV_SFNT_SAMPLE_STEREO_RIGHT	64	/* stereo right sound */
 #define SNDRV_SFNT_SAMPLE_REVERSE_LOOP	128	/* reverse looping */
 	unsigned int truesize;		/* used memory size (set by driver) */
-} soundfont_sample_info_t;
+};
 
 
 /*
  * voice preset mapping (aliasing)
  */
 
-typedef struct soundfont_voice_map_t {
+struct soundfont_voice_map {
 	int map_bank, map_instr, map_key;	/* key = -1 means all keys */
 	int src_bank, src_instr, src_key;
-} soundfont_voice_map_t;
+};
 
 
 /*
@@ -195,7 +195,7 @@
 
 #define SNDRV_EMUX_VERSION	((1 << 16) | (0 << 8) | 0)	/* 1.0.0 */
 
-struct sndrv_emux_misc_mode {
+struct snd_emux_misc_mode {
 	int port;	/* -1 = all */
 	int mode;
 	int value;
@@ -204,11 +204,11 @@
 
 enum {
 	SNDRV_EMUX_IOCTL_VERSION = _IOR('H', 0x80, unsigned int),
-	SNDRV_EMUX_IOCTL_LOAD_PATCH = _IOWR('H', 0x81, soundfont_patch_info_t),
+	SNDRV_EMUX_IOCTL_LOAD_PATCH = _IOWR('H', 0x81, struct soundfont_patch_info),
 	SNDRV_EMUX_IOCTL_RESET_SAMPLES = _IO('H', 0x82),
 	SNDRV_EMUX_IOCTL_REMOVE_LAST_SAMPLES = _IO('H', 0x83),
 	SNDRV_EMUX_IOCTL_MEM_AVAIL = _IOW('H', 0x84, int),
-	SNDRV_EMUX_IOCTL_MISC_MODE = _IOWR('H', 0x84, struct sndrv_emux_misc_mode),
+	SNDRV_EMUX_IOCTL_MISC_MODE = _IOWR('H', 0x84, struct snd_emux_misc_mode),
 };
 
 #endif /* __SOUND_SFNT_INFO_H */
diff --git a/include/sound/snd_wavefront.h b/include/sound/snd_wavefront.h
index 4b0b2b93..0b9e5de 100644
--- a/include/sound/snd_wavefront.h
+++ b/include/sound/snd_wavefront.h
@@ -26,8 +26,8 @@
         snd_wavefront_mpu_id     output_mpu;  /* most-recently-used */
         snd_wavefront_mpu_id     input_mpu;   /* most-recently-used */
         unsigned int             mode[2];     /* MPU401_MODE_XXX */
-	snd_rawmidi_substream_t	 *substream_output[2];
-	snd_rawmidi_substream_t	 *substream_input[2];
+	struct snd_rawmidi_substream	 *substream_output[2];
+	struct snd_rawmidi_substream	 *substream_input[2];
 	struct timer_list	 timer;
         spinlock_t               open;
         spinlock_t               virtual;     /* protects isvirtual */
@@ -38,8 +38,8 @@
 #define	MPU_ACK		0xFE
 #define	UART_MODE_ON	0x3F
 
-extern snd_rawmidi_ops_t snd_wavefront_midi_output;
-extern snd_rawmidi_ops_t snd_wavefront_midi_input;
+extern struct snd_rawmidi_ops snd_wavefront_midi_output;
+extern struct snd_rawmidi_ops snd_wavefront_midi_input;
 
 extern void   snd_wavefront_midi_enable_virtual (snd_wavefront_card_t *);
 extern void   snd_wavefront_midi_disable_virtual (snd_wavefront_card_t *);
@@ -116,23 +116,23 @@
 extern int  snd_wavefront_cmd (snd_wavefront_t *, int, unsigned char *,
 			       unsigned char *);
 
-extern int snd_wavefront_synth_ioctl   (snd_hwdep_t *, 
+extern int snd_wavefront_synth_ioctl   (struct snd_hwdep *, 
 					struct file *,
 					unsigned int cmd, 
 					unsigned long arg);
-extern int  snd_wavefront_synth_open    (snd_hwdep_t *, struct file *);
-extern int  snd_wavefront_synth_release (snd_hwdep_t *, struct file *);
+extern int  snd_wavefront_synth_open    (struct snd_hwdep *, struct file *);
+extern int  snd_wavefront_synth_release (struct snd_hwdep *, struct file *);
 
 /* FX processor - see also yss225.[ch] */
 
 extern int  snd_wavefront_fx_start  (snd_wavefront_t *);
 extern int  snd_wavefront_fx_detect (snd_wavefront_t *);
-extern int  snd_wavefront_fx_ioctl  (snd_hwdep_t *, 
+extern int  snd_wavefront_fx_ioctl  (struct snd_hwdep *, 
 				     struct file *,
 				     unsigned int cmd, 
 				     unsigned long arg);
-extern int snd_wavefront_fx_open    (snd_hwdep_t *, struct file *);
-extern int snd_wavefront_fx_release (snd_hwdep_t *, struct file *);
+extern int snd_wavefront_fx_open    (struct snd_hwdep *, struct file *);
+extern int snd_wavefront_fx_release (struct snd_hwdep *, struct file *);
 
 /* prefix in all snd_printk() delivered messages */
 
diff --git a/include/sound/soundfont.h b/include/sound/soundfont.h
index c992958..61a010c 100644
--- a/include/sound/soundfont.h
+++ b/include/sound/soundfont.h
@@ -29,94 +29,93 @@
 #define SF_MAX_PRESETS  256	/* drums are mapped from 128 to 256 */
 #define SF_IS_DRUM_BANK(z) ((z) == 128)
 
-typedef struct snd_sf_zone {
+struct snd_sf_zone {
 	struct snd_sf_zone *next;	/* Link to next */
 	unsigned char bank;		/* Midi bank for this zone */
 	unsigned char instr;		/* Midi program for this zone */
 	unsigned char mapped;		/* True if mapped to something else */
 
-	soundfont_voice_info_t v;	/* All the soundfont parameters */
+	struct soundfont_voice_info v;	/* All the soundfont parameters */
 	int counter;
 	struct snd_sf_sample *sample;	/* Link to sample */
 
 	/* The following deals with preset numbers (programs) */
 	struct snd_sf_zone *next_instr;	/* Next zone of this instrument */
 	struct snd_sf_zone *next_zone;	/* Next zone in play list */
-} snd_sf_zone_t;
+};
 
-typedef struct snd_sf_sample {
-	soundfont_sample_info_t v;
+struct snd_sf_sample {
+	struct soundfont_sample_info v;
 	int counter;
-	snd_util_memblk_t *block;	/* allocated data block */
+	struct snd_util_memblk *block;	/* allocated data block */
 	struct snd_sf_sample *next;
-} snd_sf_sample_t;
+};
 
 /*
  * This represents all the information relating to a soundfont.
  */
-typedef struct snd_soundfont {
+struct snd_soundfont {
 	struct snd_soundfont *next;	/* Link to next */
 	/*struct snd_soundfont *prev;*/	/* Link to previous */
 	short  id;		/* file id */
 	short  type;		/* font type */
 	unsigned char name[SNDRV_SFNT_PATCH_NAME_LEN];	/* identifier */
-	snd_sf_zone_t *zones; /* Font information */
-	snd_sf_sample_t *samples; /* The sample headers */
-} snd_soundfont_t;
+	struct snd_sf_zone *zones; /* Font information */
+	struct snd_sf_sample *samples; /* The sample headers */
+};
 
 /*
  * Type of the sample access callback
  */
-typedef int (*snd_sf_sample_new_t)(void *private_data, snd_sf_sample_t *sp,
-				   snd_util_memhdr_t *hdr, const void __user *buf, long count);
-typedef int (*snd_sf_sample_free_t)(void *private_data, snd_sf_sample_t *sp,
-				    snd_util_memhdr_t *hdr);
-typedef void (*snd_sf_sample_reset_t)(void *private);
-
-typedef struct snd_sf_callback {
+struct snd_sf_callback {
 	void *private_data;
-	snd_sf_sample_new_t sample_new;
-	snd_sf_sample_free_t sample_free;
-	snd_sf_sample_reset_t sample_reset;
-} snd_sf_callback_t;
+	int (*sample_new)(void *private_data, struct snd_sf_sample *sp,
+			  struct snd_util_memhdr *hdr,
+			  const void __user *buf, long count);
+	int (*sample_free)(void *private_data, struct snd_sf_sample *sp,
+			   struct snd_util_memhdr *hdr);
+	void (*sample_reset)(void *private);
+};
 
 /*
  * List of soundfonts.
  */
-typedef struct snd_sf_list {
-	snd_soundfont_t *currsf; /* The currently open soundfont */
+struct snd_sf_list {
+	struct snd_soundfont *currsf; /* The currently open soundfont */
 	int open_client;	/* client pointer for lock */
 	int mem_used;		/* used memory size */
-	snd_sf_zone_t *presets[SF_MAX_PRESETS];
-	snd_soundfont_t *fonts; /* The list of soundfonts */
+	struct snd_sf_zone *presets[SF_MAX_PRESETS];
+	struct snd_soundfont *fonts; /* The list of soundfonts */
 	int fonts_size;	/* number of fonts allocated */
 	int zone_counter;	/* last allocated time for zone */
 	int sample_counter;	/* last allocated time for sample */
 	int zone_locked;	/* locked time for zone */
 	int sample_locked;	/* locked time for sample */
-	snd_sf_callback_t callback;	/* callback functions */
+	struct snd_sf_callback callback;	/* callback functions */
 	int presets_locked;
 	struct semaphore presets_mutex;
 	spinlock_t lock;
-	snd_util_memhdr_t *memhdr;
-} snd_sf_list_t;
+	struct snd_util_memhdr *memhdr;
+};
 
 /* Prototypes for soundfont.c */
-int snd_soundfont_load(snd_sf_list_t *sflist, const void __user *data, long count, int client);
-int snd_soundfont_load_guspatch(snd_sf_list_t *sflist, const char __user *data,
+int snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data,
+		       long count, int client);
+int snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
 				long count, int client);
-int snd_soundfont_close_check(snd_sf_list_t *sflist, int client);
+int snd_soundfont_close_check(struct snd_sf_list *sflist, int client);
 
-snd_sf_list_t *snd_sf_new(snd_sf_callback_t *callback, snd_util_memhdr_t *hdr);
-void snd_sf_free(snd_sf_list_t *sflist);
+struct snd_sf_list *snd_sf_new(struct snd_sf_callback *callback,
+			       struct snd_util_memhdr *hdr);
+void snd_sf_free(struct snd_sf_list *sflist);
 
-int snd_soundfont_remove_samples(snd_sf_list_t *sflist);
-int snd_soundfont_remove_unlocked(snd_sf_list_t *sflist);
+int snd_soundfont_remove_samples(struct snd_sf_list *sflist);
+int snd_soundfont_remove_unlocked(struct snd_sf_list *sflist);
 
-int snd_soundfont_search_zone(snd_sf_list_t *sflist, int *notep, int vel,
+int snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
 			      int preset, int bank,
 			      int def_preset, int def_bank,
-			      snd_sf_zone_t **table, int max_layers);
+			      struct snd_sf_zone **table, int max_layers);
 
 /* Parameter conversions */
 int snd_sf_calc_parm_hold(int msec);
diff --git a/include/sound/tea575x-tuner.h b/include/sound/tea575x-tuner.h
index b82e408..a4f55452 100644
--- a/include/sound/tea575x-tuner.h
+++ b/include/sound/tea575x-tuner.h
@@ -24,15 +24,15 @@
 
 #include <linux/videodev.h>
 
-typedef struct snd_tea575x tea575x_t;
+struct snd_tea575x;
 
 struct snd_tea575x_ops {
-	void (*write)(tea575x_t *tea, unsigned int val);
-	unsigned int (*read)(tea575x_t *tea);
+	void (*write)(struct snd_tea575x *tea, unsigned int val);
+	unsigned int (*read)(struct snd_tea575x *tea);
 };
 
 struct snd_tea575x {
-	snd_card_t *card;
+	struct snd_card *card;
 	struct video_device vd;		/* video device */
 	struct file_operations fops;
 	int dev_nr;			/* requested device number + 1 */
@@ -45,7 +45,7 @@
 	void *private_data;
 };
 
-void snd_tea575x_init(tea575x_t *tea);
-void snd_tea575x_exit(tea575x_t *tea);
+void snd_tea575x_init(struct snd_tea575x *tea);
+void snd_tea575x_exit(struct snd_tea575x *tea);
 
 #endif /* __SOUND_TEA575X_TUNER_H */
diff --git a/include/sound/tea6330t.h b/include/sound/tea6330t.h
index 3896c0a..51b282b 100644
--- a/include/sound/tea6330t.h
+++ b/include/sound/tea6330t.h
@@ -22,21 +22,10 @@
  *
  */
 
-#include "control.h"
 #include "i2c.h"		/* generic i2c support */
 
-typedef struct {
-	snd_i2c_device_t *device;
-	snd_i2c_bus_t *bus;
-	int equalizer;
-	int fader;
-	unsigned char regs[8];
-	unsigned char mleft, mright;
-	unsigned char bass, treble;
-	unsigned char max_bass, max_treble;
-} tea6330t_t;
-
-extern int snd_tea6330t_detect(snd_i2c_bus_t *bus, int equalizer);
-extern int snd_tea6330t_update_mixer(snd_card_t * card, snd_i2c_bus_t * bus, int equalizer, int fader);
+int snd_tea6330t_detect(struct snd_i2c_bus *bus, int equalizer);
+int snd_tea6330t_update_mixer(struct snd_card *card, struct snd_i2c_bus *bus,
+			      int equalizer, int fader);
 
 #endif /* __SOUND_TEA6330T_H */
diff --git a/include/sound/timer.h b/include/sound/timer.h
index b55f38a..5ece2bf 100644
--- a/include/sound/timer.h
+++ b/include/sound/timer.h
@@ -26,20 +26,6 @@
 #include <sound/asound.h>
 #include <linux/interrupt.h>
 
-typedef enum sndrv_timer_class snd_timer_class_t;
-typedef enum sndrv_timer_slave_class snd_timer_slave_class_t;
-typedef enum sndrv_timer_global snd_timer_global_t;
-typedef struct sndrv_timer_id snd_timer_id_t;
-typedef struct sndrv_timer_ginfo snd_timer_ginfo_t;
-typedef struct sndrv_timer_gparams snd_timer_gparams_t;
-typedef struct sndrv_timer_gstatus snd_timer_gstatus_t;
-typedef struct sndrv_timer_select snd_timer_select_t;
-typedef struct sndrv_timer_info snd_timer_info_t;
-typedef struct sndrv_timer_params snd_timer_params_t;
-typedef struct sndrv_timer_status snd_timer_status_t;
-typedef struct sndrv_timer_read snd_timer_read_t;
-typedef struct sndrv_timer_tread snd_timer_tread_t;
-
 #define snd_timer_chip(timer) ((timer)->private_data)
 
 #define SNDRV_TIMER_DEVICES	16
@@ -64,11 +50,9 @@
 #define SNDRV_TIMER_FLG_CHANGE	0x00000001
 #define SNDRV_TIMER_FLG_RESCHED	0x00000002	/* need reschedule */
 
-typedef void (*snd_timer_callback_t) (snd_timer_instance_t * timeri, unsigned long ticks, unsigned long resolution);
-typedef void (*snd_timer_ccallback_t) (snd_timer_instance_t * timeri, enum sndrv_timer_event event,
-				       struct timespec * tstamp, unsigned long resolution);
+struct snd_timer;
 
-struct _snd_timer_hardware {
+struct snd_timer_hardware {
 	/* -- must be filled with low-level driver */
 	unsigned int flags;		/* various flags */
 	unsigned long resolution;	/* average timer resolution for one tick in nsec */
@@ -76,18 +60,18 @@
 	unsigned long resolution_max;	/* maximal resolution */
 	unsigned long ticks;		/* max timer ticks per interrupt */
 	/* -- low-level functions -- */
-	int (*open) (snd_timer_t * timer);
-	int (*close) (snd_timer_t * timer);
-	unsigned long (*c_resolution) (snd_timer_t * timer);
-	int (*start) (snd_timer_t * timer);
-	int (*stop) (snd_timer_t * timer);
-	int (*set_period) (snd_timer_t * timer, unsigned long period_num, unsigned long period_den);
-	int (*precise_resolution) (snd_timer_t * timer, unsigned long *num, unsigned long *den);
+	int (*open) (struct snd_timer * timer);
+	int (*close) (struct snd_timer * timer);
+	unsigned long (*c_resolution) (struct snd_timer * timer);
+	int (*start) (struct snd_timer * timer);
+	int (*stop) (struct snd_timer * timer);
+	int (*set_period) (struct snd_timer * timer, unsigned long period_num, unsigned long period_den);
+	int (*precise_resolution) (struct snd_timer * timer, unsigned long *num, unsigned long *den);
 };
 
-struct _snd_timer {
-	snd_timer_class_t tmr_class;
-	snd_card_t *card;
+struct snd_timer {
+	int tmr_class;
+	struct snd_card *card;
 	struct module *module;
 	int tmr_device;
 	int tmr_subdevice;
@@ -97,8 +81,8 @@
 	int running;			/* running instances */
 	unsigned long sticks;		/* schedule ticks */
 	void *private_data;
-	void (*private_free) (snd_timer_t *timer);
-	struct _snd_timer_hardware hw;
+	void (*private_free) (struct snd_timer *timer);
+	struct snd_timer_hardware hw;
 	spinlock_t lock;
 	struct list_head device_list;
 	struct list_head open_list_head;
@@ -108,49 +92,53 @@
 	struct tasklet_struct task_queue;
 };
 
-struct _snd_timer_instance {
-	snd_timer_t * timer;
+struct snd_timer_instance {
+	struct snd_timer *timer;
 	char *owner;
 	unsigned int flags;
 	void *private_data;
-	void (*private_free) (snd_timer_instance_t *ti);
-	snd_timer_callback_t callback;
-	snd_timer_ccallback_t ccallback;
+	void (*private_free) (struct snd_timer_instance *ti);
+	void (*callback) (struct snd_timer_instance *timeri,
+			  unsigned long ticks, unsigned long resolution);
+	void (*ccallback) (struct snd_timer_instance * timeri,
+			   int event,
+			   struct timespec * tstamp,
+			   unsigned long resolution);
 	void *callback_data;
 	unsigned long ticks;		/* auto-load ticks when expired */
 	unsigned long cticks;		/* current ticks */
 	unsigned long pticks;		/* accumulated ticks for callback */
 	unsigned long resolution;	/* current resolution for tasklet */
 	unsigned long lost;		/* lost ticks */
-	snd_timer_slave_class_t slave_class;
+	int slave_class;
 	unsigned int slave_id;
 	struct list_head open_list;
 	struct list_head active_list;
 	struct list_head ack_list;
 	struct list_head slave_list_head;
 	struct list_head slave_active_head;
-	snd_timer_instance_t *master;
+	struct snd_timer_instance *master;
 };
 
 /*
  *  Registering
  */
 
-extern int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer);
-extern void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp);
-extern int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer);
-extern int snd_timer_global_free(snd_timer_t *timer);
-extern int snd_timer_global_register(snd_timer_t *timer);
-extern int snd_timer_global_unregister(snd_timer_t *timer);
+int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, struct snd_timer **rtimer);
+void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp);
+int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer);
+int snd_timer_global_free(struct snd_timer *timer);
+int snd_timer_global_register(struct snd_timer *timer);
+int snd_timer_global_unregister(struct snd_timer *timer);
 
-extern int snd_timer_open(snd_timer_instance_t ** ti, char *owner, snd_timer_id_t *tid, unsigned int slave_id);
-extern int snd_timer_close(snd_timer_instance_t * timeri);
-extern unsigned long snd_timer_resolution(snd_timer_instance_t * timeri);
-extern int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks);
-extern int snd_timer_stop(snd_timer_instance_t * timeri);
-extern int snd_timer_continue(snd_timer_instance_t * timeri);
-extern int snd_timer_pause(snd_timer_instance_t * timeri);
+int snd_timer_open(struct snd_timer_instance **ti, char *owner, struct snd_timer_id *tid, unsigned int slave_id);
+int snd_timer_close(struct snd_timer_instance *timeri);
+unsigned long snd_timer_resolution(struct snd_timer_instance *timeri);
+int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks);
+int snd_timer_stop(struct snd_timer_instance *timeri);
+int snd_timer_continue(struct snd_timer_instance *timeri);
+int snd_timer_pause(struct snd_timer_instance *timeri);
 
-extern void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left);
+void snd_timer_interrupt(struct snd_timer *timer, unsigned long ticks_left);
 
 #endif /* __SOUND_TIMER_H */
diff --git a/include/sound/trident.h b/include/sound/trident.h
index a408d39..9752243 100644
--- a/include/sound/trident.h
+++ b/include/sound/trident.h
@@ -253,43 +253,43 @@
 #define T4D_DEFAULT_PCM_RVOL	127	/* 0 - 127 */
 #define T4D_DEFAULT_PCM_CVOL	127	/* 0 - 127 */
 
-typedef struct _snd_trident trident_t;
-typedef struct _snd_trident_voice snd_trident_voice_t;
-typedef struct _snd_trident_pcm_mixer snd_trident_pcm_mixer_t;
+struct snd_trident;
+struct snd_trident_voice;
+struct snd_trident_pcm_mixer;
 
-typedef struct {
-	void (*sample_start)(trident_t *gus, snd_trident_voice_t *voice, snd_seq_position_t position);
-	void (*sample_stop)(trident_t *gus, snd_trident_voice_t *voice, snd_seq_stop_mode_t mode);
-	void (*sample_freq)(trident_t *gus, snd_trident_voice_t *voice, snd_seq_frequency_t freq);
-	void (*sample_volume)(trident_t *gus, snd_trident_voice_t *voice, snd_seq_ev_volume_t *volume);
-	void (*sample_loop)(trident_t *card, snd_trident_voice_t *voice, snd_seq_ev_loop_t *loop);
-	void (*sample_pos)(trident_t *card, snd_trident_voice_t *voice, snd_seq_position_t position);
-	void (*sample_private1)(trident_t *card, snd_trident_voice_t *voice, unsigned char *data);
-} snd_trident_sample_ops_t;
+struct snd_trident_sample_ops {
+	void (*sample_start)(struct snd_trident *gus, struct snd_trident_voice *voice, snd_seq_position_t position);
+	void (*sample_stop)(struct snd_trident *gus, struct snd_trident_voice *voice, int mode);
+	void (*sample_freq)(struct snd_trident *gus, struct snd_trident_voice *voice, snd_seq_frequency_t freq);
+	void (*sample_volume)(struct snd_trident *gus, struct snd_trident_voice *voice, struct snd_seq_ev_volume *volume);
+	void (*sample_loop)(struct snd_trident *card, struct snd_trident_voice *voice, struct snd_seq_ev_loop *loop);
+	void (*sample_pos)(struct snd_trident *card, struct snd_trident_voice *voice, snd_seq_position_t position);
+	void (*sample_private1)(struct snd_trident *card, struct snd_trident_voice *voice, unsigned char *data);
+};
 
-typedef struct {
-	snd_midi_channel_set_t * chset;
-	trident_t * trident;
+struct snd_trident_port {
+	struct snd_midi_channel_set * chset;
+	struct snd_trident * trident;
 	int mode;		/* operation mode */
 	int client;		/* sequencer client number */
 	int port;		/* sequencer port number */
 	unsigned int midi_has_voices: 1;
-} snd_trident_port_t;
+};
 
-typedef struct snd_trident_memblk_arg {
+struct snd_trident_memblk_arg {
 	short first_page, last_page;
-} snd_trident_memblk_arg_t;
+};
 
-typedef struct {
+struct snd_trident_tlb {
 	unsigned int * entries;		/* 16k-aligned TLB table */
 	dma_addr_t entries_dmaaddr;	/* 16k-aligned PCI address to TLB table */
 	unsigned long * shadow_entries;	/* shadow entries with virtual addresses */
 	struct snd_dma_buffer buffer;
-	snd_util_memhdr_t * memhdr;	/* page allocation list */
+	struct snd_util_memhdr * memhdr;	/* page allocation list */
 	struct snd_dma_buffer silent_page;
-} snd_trident_tlb_t;
+};
 
-struct _snd_trident_voice {
+struct snd_trident_voice {
 	unsigned int number;
 	unsigned int use: 1,
 	    pcm: 1,
@@ -300,8 +300,8 @@
 	unsigned char port;
 	unsigned char index;
 
-	snd_seq_instr_t instr;
-	snd_trident_sample_ops_t *sample_ops;
+	struct snd_seq_instr instr;
+	struct snd_trident_sample_ops *sample_ops;
 
 	/* channel parameters */
 	unsigned int CSO;		/* 24 bits (16 on DX) */
@@ -323,13 +323,13 @@
 
 	unsigned int negCSO;	/* nonzero - use negative CSO */
 
-	snd_util_memblk_t *memblk;	/* memory block if TLB enabled */
+	struct snd_util_memblk *memblk;	/* memory block if TLB enabled */
 
 	/* PCM data */
 
-	trident_t *trident;
-	snd_pcm_substream_t *substream;
-	snd_trident_voice_t *extra;	/* extra PCM voice (acts as interrupt generator) */
+	struct snd_trident *trident;
+	struct snd_pcm_substream *substream;
+	struct snd_trident_voice *extra;	/* extra PCM voice (acts as interrupt generator) */
 	unsigned int running: 1,
             capture: 1,
             spdif: 1,
@@ -347,25 +347,25 @@
 	/* --- */
 
 	void *private_data;
-	void (*private_free)(snd_trident_voice_t *voice);
+	void (*private_free)(struct snd_trident_voice *voice);
 };
 
-struct _snd_4dwave {
+struct snd_4dwave {
 	int seq_client;
 
-	snd_trident_port_t seq_ports[4];
-	snd_simple_ops_t simple_ops;
-	snd_seq_kinstr_list_t *ilist;
+	struct snd_trident_port seq_ports[4];
+	struct snd_simple_ops simple_ops;
+	struct snd_seq_kinstr_list *ilist;
 
-	snd_trident_voice_t voices[64];	
+	struct snd_trident_voice voices[64];	
 
 	int ChanSynthCount;		/* number of allocated synth channels */
 	int max_size;			/* maximum synth memory size in bytes */
 	int current_size;		/* current allocated synth mem in bytes */
 };
 
-struct _snd_trident_pcm_mixer {
-	snd_trident_voice_t *voice;	/* active voice */
+struct snd_trident_pcm_mixer {
+	struct snd_trident_voice *voice;	/* active voice */
 	unsigned short vol;		/* front volume */
 	unsigned char pan;		/* pan control */
 	unsigned char rvol;		/* rear volume */
@@ -373,7 +373,7 @@
 	unsigned char pad;
 };
 
-struct _snd_trident {
+struct snd_trident {
 	int irq;
 
 	unsigned int device;	/* device ID */
@@ -386,13 +386,13 @@
 	unsigned int spurious_irq_count;
 	unsigned int spurious_irq_max_delta;
 
-        snd_trident_tlb_t tlb;	/* TLB entries for NX cards */
+        struct snd_trident_tlb tlb;	/* TLB entries for NX cards */
 
 	unsigned char spdif_ctrl;
 	unsigned char spdif_pcm_ctrl;
 	unsigned int spdif_bits;
 	unsigned int spdif_pcm_bits;
-	snd_kcontrol_t *spdif_pcm_ctl;	/* S/PDIF settings */
+	struct snd_kcontrol *spdif_pcm_ctl;	/* S/PDIF settings */
 	unsigned int ac97_ctrl;
         
         unsigned int ChanMap[2];	/* allocation map for hardware channels */
@@ -403,7 +403,7 @@
 	unsigned int ac97_detect: 1;	/* 1 = AC97 in detection phase */
 	unsigned int in_suspend: 1;	/* 1 during suspend/resume */
 
-	struct _snd_4dwave synth;	/* synth specific variables */
+	struct snd_4dwave synth;	/* synth specific variables */
 
 	spinlock_t event_lock;
 	spinlock_t voice_alloc;
@@ -411,52 +411,57 @@
 	struct snd_dma_device dma_dev;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;		/* ADC/DAC PCM */
-	snd_pcm_t *foldback;	/* Foldback PCM */
-	snd_pcm_t *spdif;	/* SPDIF PCM */
-	snd_rawmidi_t *rmidi;
-	snd_seq_device_t *seq_dev;
+	struct snd_card *card;
+	struct snd_pcm *pcm;		/* ADC/DAC PCM */
+	struct snd_pcm *foldback;	/* Foldback PCM */
+	struct snd_pcm *spdif;	/* SPDIF PCM */
+	struct snd_rawmidi *rmidi;
+	struct snd_seq_device *seq_dev;
 
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97;
-	ac97_t *ac97_sec;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97;
+	struct snd_ac97 *ac97_sec;
 
 	unsigned int musicvol_wavevol;
-	snd_trident_pcm_mixer_t pcm_mixer[32];
-	snd_kcontrol_t *ctl_vol;	/* front volume */
-	snd_kcontrol_t *ctl_pan;	/* pan */
-	snd_kcontrol_t *ctl_rvol;	/* rear volume */
-	snd_kcontrol_t *ctl_cvol;	/* center volume */
+	struct snd_trident_pcm_mixer pcm_mixer[32];
+	struct snd_kcontrol *ctl_vol;	/* front volume */
+	struct snd_kcontrol *ctl_pan;	/* pan */
+	struct snd_kcontrol *ctl_rvol;	/* rear volume */
+	struct snd_kcontrol *ctl_cvol;	/* center volume */
 
 	spinlock_t reg_lock;
 
 	struct gameport *gameport;
 };
 
-int snd_trident_create(snd_card_t * card,
+int snd_trident_create(struct snd_card *card,
 		       struct pci_dev *pci,
 		       int pcm_streams,
 		       int pcm_spdif_device,
 		       int max_wavetable_size,
-		       trident_t ** rtrident);
-int snd_trident_create_gameport(trident_t *trident);
+		       struct snd_trident ** rtrident);
+int snd_trident_create_gameport(struct snd_trident *trident);
 
-int snd_trident_pcm(trident_t * trident, int device, snd_pcm_t **rpcm);
-int snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t **rpcm);
-int snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t **rpcm);
-int snd_trident_attach_synthesizer(trident_t * trident);
-snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port);
-void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice);
-void snd_trident_start_voice(trident_t * trident, unsigned int voice);
-void snd_trident_stop_voice(trident_t * trident, unsigned int voice);
-void snd_trident_write_voice_regs(trident_t * trident, snd_trident_voice_t *voice);
+int snd_trident_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
+int snd_trident_foldback_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
+int snd_trident_spdif_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
+int snd_trident_attach_synthesizer(struct snd_trident * trident);
+struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type,
+					     int client, int port);
+void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice);
+void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice);
+void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice);
+void snd_trident_write_voice_regs(struct snd_trident * trident, struct snd_trident_voice *voice);
+int snd_trident_suspend(struct pci_dev *pci, pm_message_t state);
+int snd_trident_resume(struct pci_dev *pci);
 
 /* TLB memory allocation */
-snd_util_memblk_t *snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream);
-int snd_trident_free_pages(trident_t *trident, snd_util_memblk_t *blk);
-snd_util_memblk_t *snd_trident_synth_alloc(trident_t *trident, unsigned int size);
-int snd_trident_synth_free(trident_t *trident, snd_util_memblk_t *blk);
-int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size);
+struct snd_util_memblk *snd_trident_alloc_pages(struct snd_trident *trident,
+						struct snd_pcm_substream *substream);
+int snd_trident_free_pages(struct snd_trident *trident, struct snd_util_memblk *blk);
+struct snd_util_memblk *snd_trident_synth_alloc(struct snd_trident *trident, unsigned int size);
+int snd_trident_synth_free(struct snd_trident *trident, struct snd_util_memblk *blk);
+int snd_trident_synth_copy_from_user(struct snd_trident *trident, struct snd_util_memblk *blk,
+				     int offset, const char __user *data, int size);
 
 #endif /* __SOUND_TRIDENT_H */
diff --git a/include/sound/typedefs.h b/include/sound/typedefs.h
new file mode 100644
index 0000000..f454b02
--- /dev/null
+++ b/include/sound/typedefs.h
@@ -0,0 +1,173 @@
+/*
+ * Typedef's for backward compatibility (for out-of-kernel drivers)
+ *
+ * This file will be removed soon in future
+ */
+
+/* core stuff */
+typedef struct snd_card snd_card_t;
+typedef struct snd_device snd_device_t;
+typedef struct snd_device_ops snd_device_ops_t;
+typedef enum snd_card_type snd_card_type_t;
+typedef struct snd_minor snd_minor_t;
+
+/* info */
+typedef struct snd_info_entry snd_info_entry_t;
+typedef struct snd_info_buffer snd_info_buffer_t;
+
+/* control */
+typedef struct snd_ctl_file snd_ctl_file_t;
+typedef struct snd_kcontrol snd_kcontrol_t;
+typedef struct snd_kcontrol_new snd_kcontrol_new_t;
+typedef struct snd_kcontrol_volatile snd_kcontrol_volatile_t;
+typedef struct snd_kctl_event snd_kctl_event_t;
+typedef struct snd_aes_iec958 snd_aes_iec958_t;
+typedef struct snd_ctl_card_info snd_ctl_card_info_t;
+typedef struct snd_ctl_elem_id snd_ctl_elem_id_t;
+typedef struct snd_ctl_elem_list snd_ctl_elem_list_t;
+typedef struct snd_ctl_elem_info snd_ctl_elem_info_t;
+typedef struct snd_ctl_elem_value snd_ctl_elem_value_t;
+typedef struct snd_ctl_event snd_ctl_event_t;
+#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
+typedef struct snd_mixer_oss snd_mixer_oss_t;
+#endif
+
+/* timer */
+typedef struct snd_timer snd_timer_t;
+typedef struct snd_timer_instance snd_timer_instance_t;
+typedef struct snd_timer_id snd_timer_id_t;
+typedef struct snd_timer_ginfo snd_timer_ginfo_t;
+typedef struct snd_timer_gparams snd_timer_gparams_t;
+typedef struct snd_timer_gstatus snd_timer_gstatus_t;
+typedef struct snd_timer_select snd_timer_select_t;
+typedef struct snd_timer_info snd_timer_info_t;
+typedef struct snd_timer_params snd_timer_params_t;
+typedef struct snd_timer_status snd_timer_status_t;
+typedef struct snd_timer_read snd_timer_read_t;
+typedef struct snd_timer_tread snd_timer_tread_t;
+
+/* PCM */
+typedef struct snd_pcm snd_pcm_t;
+typedef struct snd_pcm_str snd_pcm_str_t;
+typedef struct snd_pcm_substream snd_pcm_substream_t;
+typedef struct snd_pcm_info snd_pcm_info_t;
+typedef struct snd_pcm_hw_params snd_pcm_hw_params_t;
+typedef struct snd_pcm_sw_params snd_pcm_sw_params_t;
+typedef struct snd_pcm_channel_info snd_pcm_channel_info_t;
+typedef struct snd_pcm_status snd_pcm_status_t;
+typedef struct snd_pcm_mmap_status snd_pcm_mmap_status_t;
+typedef struct snd_pcm_mmap_control snd_pcm_mmap_control_t;
+typedef struct snd_mask snd_mask_t;
+typedef struct snd_sg_buf snd_pcm_sgbuf_t;
+
+typedef struct snd_interval snd_interval_t;
+typedef struct snd_xferi snd_xferi_t;
+typedef struct snd_xfern snd_xfern_t;
+typedef struct snd_xferv snd_xferv_t;
+
+typedef struct snd_pcm_file snd_pcm_file_t;
+typedef struct snd_pcm_runtime snd_pcm_runtime_t;
+typedef struct snd_pcm_hardware snd_pcm_hardware_t;
+typedef struct snd_pcm_ops snd_pcm_ops_t;
+typedef struct snd_pcm_hw_rule snd_pcm_hw_rule_t;
+typedef struct snd_pcm_hw_constraints snd_pcm_hw_constraints_t;
+typedef struct snd_ratnum ratnum_t;
+typedef struct snd_ratden ratden_t;
+typedef struct snd_pcm_hw_constraint_ratnums snd_pcm_hw_constraint_ratnums_t;
+typedef struct snd_pcm_hw_constraint_ratdens snd_pcm_hw_constraint_ratdens_t;
+typedef struct snd_pcm_hw_constraint_list snd_pcm_hw_constraint_list_t;
+typedef struct snd_pcm_group snd_pcm_group_t;
+typedef struct snd_pcm_notify snd_pcm_notify_t;
+
+/* rawmidi */
+typedef struct snd_rawmidi snd_rawmidi_t;
+typedef struct snd_rawmidi_info snd_rawmidi_info_t;
+typedef struct snd_rawmidi_params snd_rawmidi_params_t;
+typedef struct snd_rawmidi_status snd_rawmidi_status_t;
+typedef struct snd_rawmidi_runtime snd_rawmidi_runtime_t;
+typedef struct snd_rawmidi_substream snd_rawmidi_substream_t;
+typedef struct snd_rawmidi_str snd_rawmidi_str_t;
+typedef struct snd_rawmidi_ops snd_rawmidi_ops_t;
+typedef struct snd_rawmidi_global_ops snd_rawmidi_global_ops_t;
+typedef struct snd_rawmidi_file snd_rawmidi_file_t;
+
+/* hwdep */
+typedef struct snd_hwdep snd_hwdep_t;
+typedef struct snd_hwdep_info snd_hwdep_info_t;
+typedef struct snd_hwdep_dsp_status snd_hwdep_dsp_status_t;
+typedef struct snd_hwdep_dsp_image snd_hwdep_dsp_image_t;
+typedef struct snd_hwdep_ops snd_hwdep_ops_t;
+
+/* sequencer */
+typedef struct snd_seq_port_info snd_seq_port_info_t;
+typedef struct snd_seq_port_subscribe snd_seq_port_subscribe_t;
+typedef struct snd_seq_event snd_seq_event_t;
+typedef struct snd_seq_addr snd_seq_addr_t;
+typedef struct snd_seq_ev_volume snd_seq_ev_volume_t;
+typedef struct snd_seq_ev_loop snd_seq_ev_loop_t;
+typedef struct snd_seq_remove_events snd_seq_remove_events_t;
+typedef struct snd_seq_query_subs snd_seq_query_subs_t;
+typedef struct snd_seq_system_info snd_seq_system_info_t;
+typedef struct snd_seq_client_info snd_seq_client_info_t;
+typedef struct snd_seq_queue_info snd_seq_queue_info_t;
+typedef struct snd_seq_queue_status snd_seq_queue_status_t;
+typedef struct snd_seq_queue_tempo snd_seq_queue_tempo_t;
+typedef struct snd_seq_queue_owner snd_seq_queue_owner_t;
+typedef struct snd_seq_queue_timer snd_seq_queue_timer_t;
+typedef struct snd_seq_queue_client snd_seq_queue_client_t;
+typedef struct snd_seq_client_pool snd_seq_client_pool_t;
+typedef struct snd_seq_instr snd_seq_instr_t;
+typedef struct snd_seq_instr_data snd_seq_instr_data_t;
+typedef struct snd_seq_instr_header snd_seq_instr_header_t;
+
+typedef struct snd_seq_user_client user_client_t;
+typedef struct snd_seq_kernel_client kernel_client_t;
+typedef struct snd_seq_client client_t;
+typedef struct snd_seq_queue queue_t;
+
+/* seq_device */
+typedef struct snd_seq_device snd_seq_device_t;
+typedef struct snd_seq_dev_ops snd_seq_dev_ops_t;
+
+/* seq_midi */
+typedef struct snd_midi_event snd_midi_event_t;
+
+/* seq_midi_emul */
+typedef struct snd_midi_channel snd_midi_channel_t;
+typedef struct snd_midi_channel_set snd_midi_channel_set_t;
+typedef struct snd_midi_op snd_midi_op_t;
+
+/* seq_oss */
+typedef struct snd_seq_oss_arg snd_seq_oss_arg_t;
+typedef struct snd_seq_oss_callback snd_seq_oss_callback_t;
+typedef struct snd_seq_oss_reg snd_seq_oss_reg_t;
+
+/* virmidi */
+typedef struct snd_virmidi_dev snd_virmidi_dev_t;
+typedef struct snd_virmidi snd_virmidi_t;
+
+/* seq_instr */
+typedef struct snd_seq_kcluster snd_seq_kcluster_t;
+typedef struct snd_seq_kinstr_ops snd_seq_kinstr_ops_t;
+typedef struct snd_seq_kinstr snd_seq_kinstr_t;
+typedef struct snd_seq_kinstr_list snd_seq_kinstr_list_t;
+
+/* ac97 */
+typedef struct snd_ac97_bus ac97_bus_t;
+typedef struct snd_ac97_bus_ops ac97_bus_ops_t;
+typedef struct snd_ac97_template ac97_template_t;
+typedef struct snd_ac97 ac97_t;
+
+/* opl3/4 */
+typedef struct snd_opl3 opl3_t;
+typedef struct snd_opl4 opl4_t;
+
+/* mpu401 */
+typedef struct snd_mpu401 mpu401_t;
+
+/* i2c */
+typedef struct snd_i2c_device snd_i2c_device_t;
+typedef struct snd_i2c_bus snd_i2c_bus_t;
+
+typedef struct snd_ak4531 ak4531_t;
+
diff --git a/include/sound/uda1341.h b/include/sound/uda1341.h
index 61ff65a..2e564bf 100644
--- a/include/sound/uda1341.h
+++ b/include/sound/uda1341.h
@@ -15,7 +15,7 @@
  *                           features support
  */
 
-/* $Id: uda1341.h,v 1.6 2004/05/03 17:36:50 tiwai Exp $ */
+/* $Id: uda1341.h,v 1.8 2005/11/17 14:17:21 tiwai Exp $ */
 
 #define UDA1341_ALSA_NAME "snd-uda1341"
 
@@ -37,11 +37,6 @@
 	ON,
 };
 
-const char *onoff_names[] = {
-	"Off",
-	"On",
-};
-
 enum uda1341_format {
 	I2S=0,
 	LSB16,
@@ -53,17 +48,6 @@
 	LSB20MSB,        
 };
 
-const char *format_names[] = {
-	"I2S-bus",
-	"LSB 16bits",
-	"LSB 18bits",
-	"LSB 20bits",
-	"MSB",
-	"in LSB 16bits/out MSB",
-	"in LSB 18bits/out MSB",
-	"in LSB 20bits/out MSB",        
-};
-
 enum uda1341_fs {
 	F512=0,
 	F384,
@@ -71,23 +55,11 @@
 	Funused,
 };
 
-const char *fs_names[] = {
-	"512*fs",
-	"384*fs",
-	"256*fs",
-	"Unused - bad value!",
-};
-
 enum uda1341_peak {
 	BEFORE=0,
 	AFTER,
 };
 
-const char *peak_names[] = {
-	"before",
-	"after",
-};
-
 enum uda1341_filter {
 	FLAT=0,
 	MIN,
@@ -95,24 +67,6 @@
 	MAX,
 };
 
-const char *filter_names[] = {
-	"flat",
-	"min",
-	"min",
-	"max",
-};
-
-const char*bass_values[][16] = {
-	{"0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB",
-	 "0 dB", "0 dB", "0 dB", "0 dB", "undefined", }, //flat
-	{"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB",
-	 "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min
-	{"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB",
-	 "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min
-	{"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "20 dB",
-	 "22 dB", "24 dB", "24 dB", "24 dB", "undefined",}, // max
-};
-
 enum uda1341_mixer {
 	DOUBLE,
 	LINE,
@@ -120,13 +74,6 @@
 	MIXER,
 };
 
-const char *mixer_names[] = {
-	"double differential",
-	"input channel 1 (line in)",
-	"input channel 2 (microphone)",
-	"digital mixer",
-};
-
 enum uda1341_deemp {
 	NONE,
 	D32,
@@ -134,58 +81,6 @@
 	D48,
 };
 
-const char *deemp_names[] = {
-	"none",
-	"32 kHz",
-	"44.1 kHz",
-	"48 kHz",        
-};
-
-const char *mic_sens_value[] = {
-	"-3 dB", "0 dB", "3 dB", "9 dB", "15 dB", "21 dB", "27 dB", "not used",
-};
-
-const unsigned short AGC_atime[] = {
-	11, 16, 11, 16, 21, 11, 16, 21,
-};
-
-const unsigned short AGC_dtime[] = {
-	100, 100, 200, 200, 200, 400, 400, 400,
-};
-
-const char *AGC_level[] = {
-	"-9.0", "-11.5", "-15.0", "-17.5",
-};
-
-const char *ig_small_value[] = {
-	"-3.0", "-2.5", "-2.0", "-1.5", "-1.0", "-0.5",
-};
-
-/*
- * this was computed as peak_value[i] = pow((63-i)*1.42,1.013)
- *
- * UDA1341 datasheet on page 21: Peak value (dB) = (Peak level - 63.5)*5*log2
- * There is an table with these values [level]=value: [3]=-90.31, [7]=-84.29
- * [61]=-2.78, [62] = -1.48, [63] = 0.0
- * I tried to compute it, but using but even using logarithm with base either 10 or 2
- * i was'n able to get values in the table from the formula. So I constructed another
- * formula (see above) to interpolate the values as good as possible. If there is some
- * mistake, please contact me on tomas.kasparek@seznam.cz. Thanks.
- * UDA1341TS datasheet is available at:
- *   http://www-us9.semiconductors.com/acrobat/datasheets/UDA1341TS_3.pdf 
- */
-const char *peak_value[] = {
-	"-INF dB", "N.A.", "N.A", "90.31 dB", "N.A.", "N.A.", "N.A.", "-84.29 dB",
-	"-82.65 dB", "-81.13 dB", "-79.61 dB", "-78.09 dB", "-76.57 dB", "-75.05 dB", "-73.53 dB",
-	"-72.01 dB", "-70.49 dB", "-68.97 dB", "-67.45 dB", "-65.93 dB", "-64.41 dB", "-62.90 dB",
-	"-61.38 dB", "-59.86 dB", "-58.35 dB", "-56.83 dB", "-55.32 dB", "-53.80 dB", "-52.29 dB",
-	"-50.78 dB", "-49.26 dB", "-47.75 dB", "-46.24 dB", "-44.73 dB", "-43.22 dB", "-41.71 dB",
-	"-40.20 dB", "-38.69 dB", "-37.19 dB", "-35.68 dB", "-34.17 dB", "-32.67 dB", "-31.17 dB",
-	"-29.66 dB", "-28.16 dB", "-26.66 dB", "-25.16 dB", "-23.66 dB", "-22.16 dB", "-20.67 dB",
-	"-19.17 dB", "-17.68 dB", "-16.19 dB", "-14.70 dB", "-13.21 dB", "-11.72 dB", "-10.24 dB",
-	"-8.76 dB", "-7.28 dB", "-5.81 dB", "-4.34 dB", "-2.88 dB", "-1.43 dB", "0.00 dB",
-};
-
 enum uda1341_config {
 	CMD_READ_REG = 0,
 	CMD_RESET,
@@ -224,7 +119,7 @@
 	FLUSH,
 };
 
-int __init snd_chip_uda1341_mixer_new(snd_card_t *card, struct l3_client **clnt);
+int __init snd_chip_uda1341_mixer_new(struct snd_card *card, struct l3_client **clnt);
 
 /*
  * Local variables:
diff --git a/include/sound/util_mem.h b/include/sound/util_mem.h
index 9d2cdfa..69944bbb 100644
--- a/include/sound/util_mem.h
+++ b/include/sound/util_mem.h
@@ -20,29 +20,25 @@
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
-typedef struct snd_util_memblk snd_util_memblk_t;
-typedef struct snd_util_memhdr snd_util_memhdr_t;
-typedef unsigned int snd_util_unit_t;
-
 /*
  * memory block
  */
 struct snd_util_memblk {
-	snd_util_unit_t size;		/* size of this block */
-	snd_util_unit_t offset;		/* zero-offset of this block */
+	unsigned int size;		/* size of this block */
+	unsigned int offset;		/* zero-offset of this block */
 	struct list_head list;		/* link */
 };
 
-#define snd_util_memblk_argptr(blk)	(void*)((char*)(blk) + sizeof(snd_util_memblk_t))
+#define snd_util_memblk_argptr(blk)	(void*)((char*)(blk) + sizeof(struct snd_util_memblk))
 
 /*
  * memory management information
  */
 struct snd_util_memhdr {
-	snd_util_unit_t size;		/* size of whole data */
+	unsigned int size;		/* size of whole data */
 	struct list_head block;		/* block linked-list header */
 	int nblocks;			/* # of allocated blocks */
-	snd_util_unit_t used;		/* used memory size */
+	unsigned int used;		/* used memory size */
 	int block_extra_size;		/* extra data size of chunk */
 	struct semaphore block_mutex;	/* lock */
 };
@@ -50,15 +46,17 @@
 /*
  * prototypes
  */
-snd_util_memhdr_t *snd_util_memhdr_new(int memsize);
-void snd_util_memhdr_free(snd_util_memhdr_t *hdr);
-snd_util_memblk_t *snd_util_mem_alloc(snd_util_memhdr_t *hdr, int size);
-int snd_util_mem_free(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk);
-int snd_util_mem_avail(snd_util_memhdr_t *hdr);
+struct snd_util_memhdr *snd_util_memhdr_new(int memsize);
+void snd_util_memhdr_free(struct snd_util_memhdr *hdr);
+struct snd_util_memblk *snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size);
+int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk);
+int snd_util_mem_avail(struct snd_util_memhdr *hdr);
 
 /* functions without mutex */
-snd_util_memblk_t *__snd_util_mem_alloc(snd_util_memhdr_t *hdr, int size);
-void __snd_util_mem_free(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk);
-snd_util_memblk_t *__snd_util_memblk_new(snd_util_memhdr_t *hdr, snd_util_unit_t units, struct list_head *prev);
+struct snd_util_memblk *__snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size);
+void __snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk);
+struct snd_util_memblk *__snd_util_memblk_new(struct snd_util_memhdr *hdr,
+					      unsigned int units,
+					      struct list_head *prev);
 
 #endif /* __SOUND_UTIL_MEM_H */
diff --git a/include/sound/version.h b/include/sound/version.h
index d1bd3b7..919da0d 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by configure.  */
-#define CONFIG_SND_VERSION "1.0.10rc3"
-#define CONFIG_SND_DATE " (Mon Nov 07 13:30:21 2005 UTC)"
+#define CONFIG_SND_VERSION "1.0.11rc2"
+#define CONFIG_SND_DATE " (Wed Jan 04 08:57:20 2006 UTC)"
diff --git a/include/sound/vx_core.h b/include/sound/vx_core.h
index 7a60a38..5fd6f33 100644
--- a/include/sound/vx_core.h
+++ b/include/sound/vx_core.h
@@ -36,9 +36,6 @@
 struct firmware;
 struct device;
 
-typedef struct snd_vx_core vx_core_t;
-typedef struct vx_pipe vx_pipe_t;
-
 #define VX_DRIVER_VERSION	0x010000	/* 1.0.0 */
 
 /*
@@ -76,7 +73,7 @@
 	int channels;
 	unsigned int differed_type;
 	pcx_time_t pcx_time;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 
 	int hbuf_size;		/* H-buffer size in bytes */
 	int buffer_bytes;	/* the ALSA pcm buffer size in bytes */
@@ -88,36 +85,38 @@
 	u64 cur_count;		/* current sample position (for playback) */
 
 	unsigned int references;     /* an output pipe may be used for monitoring and/or playback */
-	vx_pipe_t *monitoring_pipe;  /* pointer to the monitoring pipe (capture pipe only)*/
+	struct vx_pipe *monitoring_pipe;  /* pointer to the monitoring pipe (capture pipe only)*/
 
 	struct tasklet_struct start_tq;
 };
 
+struct vx_core;
+
 struct snd_vx_ops {
 	/* low-level i/o */
-	unsigned char (*in8)(vx_core_t *chip, int reg);
-	unsigned int (*in32)(vx_core_t *chip, int reg);
-	void (*out8)(vx_core_t *chip, int reg, unsigned char val);
-	void (*out32)(vx_core_t *chip, int reg, unsigned int val);
+	unsigned char (*in8)(struct vx_core *chip, int reg);
+	unsigned int (*in32)(struct vx_core *chip, int reg);
+	void (*out8)(struct vx_core *chip, int reg, unsigned char val);
+	void (*out32)(struct vx_core *chip, int reg, unsigned int val);
 	/* irq */
-	int (*test_and_ack)(vx_core_t *chip);
-	void (*validate_irq)(vx_core_t *chip, int enable);
+	int (*test_and_ack)(struct vx_core *chip);
+	void (*validate_irq)(struct vx_core *chip, int enable);
 	/* codec */
-	void (*write_codec)(vx_core_t *chip, int codec, unsigned int data);
-	void (*akm_write)(vx_core_t *chip, int reg, unsigned int data);
-	void (*reset_codec)(vx_core_t *chip);
-	void (*change_audio_source)(vx_core_t *chip, int src);
-	void (*set_clock_source)(vx_core_t *chp, int src);
+	void (*write_codec)(struct vx_core *chip, int codec, unsigned int data);
+	void (*akm_write)(struct vx_core *chip, int reg, unsigned int data);
+	void (*reset_codec)(struct vx_core *chip);
+	void (*change_audio_source)(struct vx_core *chip, int src);
+	void (*set_clock_source)(struct vx_core *chp, int src);
 	/* chip init */
-	int (*load_dsp)(vx_core_t *chip, int idx, const struct firmware *fw);
-	void (*reset_dsp)(vx_core_t *chip);
-	void (*reset_board)(vx_core_t *chip, int cold_reset);
-	int (*add_controls)(vx_core_t *chip);
+	int (*load_dsp)(struct vx_core *chip, int idx, const struct firmware *fw);
+	void (*reset_dsp)(struct vx_core *chip);
+	void (*reset_board)(struct vx_core *chip, int cold_reset);
+	int (*add_controls)(struct vx_core *chip);
 	/* pcm */
-	void (*dma_write)(vx_core_t *chip, snd_pcm_runtime_t *runtime,
-			  vx_pipe_t *pipe, int count);
-	void (*dma_read)(vx_core_t *chip, snd_pcm_runtime_t *runtime,
-			  vx_pipe_t *pipe, int count);
+	void (*dma_write)(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+			  struct vx_pipe *pipe, int count);
+	void (*dma_read)(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+			  struct vx_pipe *pipe, int count);
 };
 
 struct snd_vx_hardware {
@@ -158,10 +157,10 @@
 /* min/max values for analog output for old codecs */
 #define VX_ANALOG_OUT_LEVEL_MAX		0xe3
 
-struct snd_vx_core {
+struct vx_core {
 	/* ALSA stuff */
-	snd_card_t *card;
-	snd_pcm_t *pcm[VX_MAX_CODECS];
+	struct snd_card *card;
+	struct snd_pcm *pcm[VX_MAX_CODECS];
 	int type;	/* VX_TYPE_XXX */
 
 	int irq;
@@ -179,7 +178,7 @@
 	unsigned int pcm_running;
 
 	struct device *dev;
-	snd_hwdep_t *hwdep;
+	struct snd_hwdep *hwdep;
 
 	struct vx_rmh irq_rmh;	/* RMH used in interrupts */
 
@@ -216,14 +215,14 @@
 /*
  * constructor
  */
-vx_core_t *snd_vx_create(snd_card_t *card, struct snd_vx_hardware *hw,
-			 struct snd_vx_ops *ops, int extra_size);
-int snd_vx_setup_firmware(vx_core_t *chip);
-int snd_vx_load_boot_image(vx_core_t *chip, const struct firmware *dsp);
-int snd_vx_dsp_boot(vx_core_t *chip, const struct firmware *dsp);
-int snd_vx_dsp_load(vx_core_t *chip, const struct firmware *dsp);
+struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
+			      struct snd_vx_ops *ops, int extra_size);
+int snd_vx_setup_firmware(struct vx_core *chip);
+int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *dsp);
+int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *dsp);
+int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp);
 
-void snd_vx_free_firmware(vx_core_t *chip);
+void snd_vx_free_firmware(struct vx_core *chip);
 
 /*
  * interrupt handler; exported for pcmcia
@@ -233,37 +232,37 @@
 /*
  * lowlevel functions
  */
-static inline int vx_test_and_ack(vx_core_t *chip)
+static inline int vx_test_and_ack(struct vx_core *chip)
 {
 	snd_assert(chip->ops->test_and_ack, return -ENXIO);
 	return chip->ops->test_and_ack(chip);
 }
 
-static inline void vx_validate_irq(vx_core_t *chip, int enable)
+static inline void vx_validate_irq(struct vx_core *chip, int enable)
 {
 	snd_assert(chip->ops->validate_irq, return);
 	chip->ops->validate_irq(chip, enable);
 }
 
-static inline unsigned char snd_vx_inb(vx_core_t *chip, int reg)
+static inline unsigned char snd_vx_inb(struct vx_core *chip, int reg)
 {
 	snd_assert(chip->ops->in8, return 0);
 	return chip->ops->in8(chip, reg);
 }
 
-static inline unsigned int snd_vx_inl(vx_core_t *chip, int reg)
+static inline unsigned int snd_vx_inl(struct vx_core *chip, int reg)
 {
 	snd_assert(chip->ops->in32, return 0);
 	return chip->ops->in32(chip, reg);
 }
 
-static inline void snd_vx_outb(vx_core_t *chip, int reg, unsigned char val)
+static inline void snd_vx_outb(struct vx_core *chip, int reg, unsigned char val)
 {
 	snd_assert(chip->ops->out8, return);
 	chip->ops->out8(chip, reg, val);
 }
 
-static inline void snd_vx_outl(vx_core_t *chip, int reg, unsigned int val)
+static inline void snd_vx_outl(struct vx_core *chip, int reg, unsigned int val)
 {
 	snd_assert(chip->ops->out32, return);
 	chip->ops->out32(chip, reg, val);
@@ -274,27 +273,25 @@
 #define vx_inl(chip,reg)	snd_vx_inl(chip, VX_##reg)
 #define vx_outl(chip,reg,val)	snd_vx_outl(chip, VX_##reg,val)
 
-void snd_vx_delay(vx_core_t *chip, int msec);
-
-static inline void vx_reset_dsp(vx_core_t *chip)
+static inline void vx_reset_dsp(struct vx_core *chip)
 {
 	snd_assert(chip->ops->reset_dsp, return);
 	chip->ops->reset_dsp(chip);
 }
 
-int vx_send_msg(vx_core_t *chip, struct vx_rmh *rmh);
-int vx_send_msg_nolock(vx_core_t *chip, struct vx_rmh *rmh);
-int vx_send_rih(vx_core_t *chip, int cmd);
-int vx_send_rih_nolock(vx_core_t *chip, int cmd);
+int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh);
+int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh);
+int vx_send_rih(struct vx_core *chip, int cmd);
+int vx_send_rih_nolock(struct vx_core *chip, int cmd);
 
-void vx_reset_codec(vx_core_t *chip, int cold_reset);
+void vx_reset_codec(struct vx_core *chip, int cold_reset);
 
 /*
  * check the bit on the specified register
  * returns zero if a bit matches, or a negative error code.
  * exported for vxpocket driver
  */
-int snd_vx_check_reg_bit(vx_core_t *chip, int reg, int mask, int bit, int time);
+int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int time);
 #define vx_check_isr(chip,mask,bit,time) snd_vx_check_reg_bit(chip, VX_ISR, mask, bit, time)
 #define vx_wait_isr_bit(chip,bit) vx_check_isr(chip, bit, bit, 200)
 #define vx_wait_for_rx_full(chip) vx_wait_isr_bit(chip, ISR_RX_FULL)
@@ -303,15 +300,15 @@
 /*
  * pseudo-DMA transfer
  */
-static inline void vx_pseudo_dma_write(vx_core_t *chip, snd_pcm_runtime_t *runtime,
-				       vx_pipe_t *pipe, int count)
+static inline void vx_pseudo_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+				       struct vx_pipe *pipe, int count)
 {
 	snd_assert(chip->ops->dma_write, return);
 	chip->ops->dma_write(chip, runtime, pipe, count);
 }
 
-static inline void vx_pseudo_dma_read(vx_core_t *chip, snd_pcm_runtime_t *runtime,
-				      vx_pipe_t *pipe, int count)
+static inline void vx_pseudo_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+				      struct vx_pipe *pipe, int count)
 {
 	snd_assert(chip->ops->dma_read, return);
 	chip->ops->dma_read(chip, runtime, pipe, count);
@@ -329,27 +326,33 @@
 /*
  * pcm stuff
  */
-int snd_vx_pcm_new(vx_core_t *chip);
-void vx_pcm_update_intr(vx_core_t *chip, unsigned int events);
+int snd_vx_pcm_new(struct vx_core *chip);
+void vx_pcm_update_intr(struct vx_core *chip, unsigned int events);
 
 /*
  * mixer stuff
  */
-int snd_vx_mixer_new(vx_core_t *chip);
-void vx_toggle_dac_mute(vx_core_t *chip, int mute);
-int vx_sync_audio_source(vx_core_t *chip);
-int vx_set_monitor_level(vx_core_t *chip, int audio, int level, int active);
+int snd_vx_mixer_new(struct vx_core *chip);
+void vx_toggle_dac_mute(struct vx_core *chip, int mute);
+int vx_sync_audio_source(struct vx_core *chip);
+int vx_set_monitor_level(struct vx_core *chip, int audio, int level, int active);
 
 /*
  * IEC958 & clock stuff
  */
-void vx_set_iec958_status(vx_core_t *chip, unsigned int bits);
-int vx_set_clock(vx_core_t *chip, unsigned int freq);
-void vx_set_internal_clock(vx_core_t *chip, unsigned int freq);
-int vx_change_frequency(vx_core_t *chip);
+void vx_set_iec958_status(struct vx_core *chip, unsigned int bits);
+int vx_set_clock(struct vx_core *chip, unsigned int freq);
+void vx_set_internal_clock(struct vx_core *chip, unsigned int freq);
+int vx_change_frequency(struct vx_core *chip);
 
 
 /*
+ * PM
+ */
+int snd_vx_suspend(struct vx_core *card, pm_message_t state);
+int snd_vx_resume(struct vx_core *card);
+
+/*
  * hardware constants
  */
 
diff --git a/include/sound/wavefront.h b/include/sound/wavefront.h
index 9e572ae..15d82e5 100644
--- a/include/sound/wavefront.h
+++ b/include/sound/wavefront.h
@@ -454,22 +454,22 @@
 } wavefront_multisample;
 
 typedef struct wf_alias {
-    s16 OriginalSample __attribute__ ((packed));
+    s16 OriginalSample;
 
-    struct wf_sample_offset sampleStartOffset __attribute__ ((packed));
-    struct wf_sample_offset loopStartOffset __attribute__ ((packed));
-    struct wf_sample_offset sampleEndOffset __attribute__ ((packed));
-    struct wf_sample_offset loopEndOffset __attribute__ ((packed));
+    struct wf_sample_offset sampleStartOffset;
+    struct wf_sample_offset loopStartOffset;
+    struct wf_sample_offset sampleEndOffset;
+    struct wf_sample_offset loopEndOffset;
 
-    s16  FrequencyBias __attribute__ ((packed));
+    s16  FrequencyBias;
 
-    u8 SampleResolution:2  __attribute__ ((packed));
-    u8 Unused1:1  __attribute__ ((packed));
-    u8 Loop:1 __attribute__ ((packed));
-    u8 Bidirectional:1  __attribute__ ((packed));
-    u8 Unused2:1 __attribute__ ((packed));
-    u8 Reverse:1 __attribute__ ((packed));
-    u8 Unused3:1 __attribute__ ((packed)); 
+    u8 SampleResolution:2;
+    u8 Unused1:1;
+    u8 Loop:1;
+    u8 Bidirectional:1;
+    u8 Unused2:1;
+    u8 Reverse:1;
+    u8 Unused3:1;
     
     /* This structure is meant to be padded only to 16 bits on their
        original. Of course, whoever wrote their documentation didn't
@@ -480,8 +480,8 @@
        standard 16->32 bit issues.
     */
 
-    u8 sixteen_bit_padding __attribute__ ((packed));
-} wavefront_alias;
+    u8 sixteen_bit_padding;
+} __attribute__((packed)) wavefront_alias;
 
 typedef struct wf_drum {
     u8 PatchNumber;
diff --git a/include/sound/ymfpci.h b/include/sound/ymfpci.h
index c3bccbfd..d567bfd 100644
--- a/include/sound/ymfpci.h
+++ b/include/sound/ymfpci.h
@@ -184,7 +184,7 @@
  *
  */
 
-typedef struct _snd_ymfpci_playback_bank {
+struct snd_ymfpci_playback_bank {
 	u32 format;
 	u32 loop_default;
 	u32 base;			/* 32-bit address */
@@ -215,46 +215,45 @@
 	u32 eff3_gain;
 	u32 lpfD1;
 	u32 lpfD2;
-} snd_ymfpci_playback_bank_t;
+ };
 
-typedef struct _snd_ymfpci_capture_bank {
+struct snd_ymfpci_capture_bank {
 	u32 base;			/* 32-bit address */
 	u32 loop_end;			/* 32-bit offset */
 	u32 start;			/* 32-bit offset */
 	u32 num_of_loops;		/* counter */
-} snd_ymfpci_capture_bank_t;
+};
 
-typedef struct _snd_ymfpci_effect_bank {
+struct snd_ymfpci_effect_bank {
 	u32 base;			/* 32-bit address */
 	u32 loop_end;			/* 32-bit offset */
 	u32 start;			/* 32-bit offset */
 	u32 temp;
-} snd_ymfpci_effect_bank_t;
+};
 
-typedef struct _snd_ymfpci_voice ymfpci_voice_t;
-typedef struct _snd_ymfpci_pcm ymfpci_pcm_t;
-typedef struct _snd_ymfpci ymfpci_t;
+struct snd_ymfpci_pcm;
+struct snd_ymfpci;
 
-typedef enum {
+enum snd_ymfpci_voice_type {
 	YMFPCI_PCM,
 	YMFPCI_SYNTH,
 	YMFPCI_MIDI
-} ymfpci_voice_type_t;
+};
 
-struct _snd_ymfpci_voice {
-	ymfpci_t *chip;
+struct snd_ymfpci_voice {
+	struct snd_ymfpci *chip;
 	int number;
 	unsigned int use: 1,
 	    pcm: 1,
 	    synth: 1,
 	    midi: 1;
-	snd_ymfpci_playback_bank_t *bank;
+	struct snd_ymfpci_playback_bank *bank;
 	dma_addr_t bank_addr;
-	void (*interrupt)(ymfpci_t *chip, ymfpci_voice_t *voice);
-	ymfpci_pcm_t *ypcm;
+	void (*interrupt)(struct snd_ymfpci *chip, struct snd_ymfpci_voice *voice);
+	struct snd_ymfpci_pcm *ypcm;
 };
 
-typedef enum {
+enum snd_ymfpci_pcm_type {
 	PLAYBACK_VOICE,
 	CAPTURE_REC,
 	CAPTURE_AC97,
@@ -263,13 +262,13 @@
 	EFFECT_EFF1,
 	EFFECT_EFF2,
 	EFFECT_EFF3
-} snd_ymfpci_pcm_type_t;
+};
 
-struct _snd_ymfpci_pcm {
-	ymfpci_t *chip;
-	snd_ymfpci_pcm_type_t type;
-	snd_pcm_substream_t *substream;
-	ymfpci_voice_t *voices[2];	/* playback only */
+struct snd_ymfpci_pcm {
+	struct snd_ymfpci *chip;
+	enum snd_ymfpci_pcm_type type;
+	struct snd_pcm_substream *substream;
+	struct snd_ymfpci_voice *voices[2];	/* playback only */
 	unsigned int running: 1;
 	unsigned int output_front: 1;
 	unsigned int output_rear: 1;
@@ -282,7 +281,7 @@
 	u32 shift;
 };
 
-struct _snd_ymfpci {
+struct snd_ymfpci {
 	int irq;
 
 	unsigned int device_id;	/* PCI device ID */
@@ -316,47 +315,47 @@
 	struct snd_dma_buffer ac3_tmp_base;
 
 	u32 *ctrl_playback;
-	snd_ymfpci_playback_bank_t *bank_playback[YDSXG_PLAYBACK_VOICES][2];
-	snd_ymfpci_capture_bank_t *bank_capture[YDSXG_CAPTURE_VOICES][2];
-	snd_ymfpci_effect_bank_t *bank_effect[YDSXG_EFFECT_VOICES][2];
+	struct snd_ymfpci_playback_bank *bank_playback[YDSXG_PLAYBACK_VOICES][2];
+	struct snd_ymfpci_capture_bank *bank_capture[YDSXG_CAPTURE_VOICES][2];
+	struct snd_ymfpci_effect_bank *bank_effect[YDSXG_EFFECT_VOICES][2];
 
 	int start_count;
 
 	u32 active_bank;
-	ymfpci_voice_t voices[64];
+	struct snd_ymfpci_voice voices[64];
 
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97;
-	snd_rawmidi_t *rawmidi;
-	snd_timer_t *timer;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97;
+	struct snd_rawmidi *rawmidi;
+	struct snd_timer *timer;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_t *pcm2;
-	snd_pcm_t *pcm_spdif;
-	snd_pcm_t *pcm_4ch;
-	snd_pcm_substream_t *capture_substream[YDSXG_CAPTURE_VOICES];
-	snd_pcm_substream_t *effect_substream[YDSXG_EFFECT_VOICES];
-	snd_kcontrol_t *ctl_vol_recsrc;
-	snd_kcontrol_t *ctl_vol_adcrec;
-	snd_kcontrol_t *ctl_vol_spdifrec;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm *pcm2;
+	struct snd_pcm *pcm_spdif;
+	struct snd_pcm *pcm_4ch;
+	struct snd_pcm_substream *capture_substream[YDSXG_CAPTURE_VOICES];
+	struct snd_pcm_substream *effect_substream[YDSXG_EFFECT_VOICES];
+	struct snd_kcontrol *ctl_vol_recsrc;
+	struct snd_kcontrol *ctl_vol_adcrec;
+	struct snd_kcontrol *ctl_vol_spdifrec;
 	unsigned short spdif_bits, spdif_pcm_bits;
-	snd_kcontrol_t *spdif_pcm_ctl;
+	struct snd_kcontrol *spdif_pcm_ctl;
 	int mode_dup4ch;
 	int rear_opened;
 	int spdif_opened;
 	struct {
 		u16 left;
 		u16 right;
-		snd_kcontrol_t *ctl;
+		struct snd_kcontrol *ctl;
 	} pcm_mixer[32];
 
 	spinlock_t reg_lock;
 	spinlock_t voice_lock;
 	wait_queue_head_t interrupt_sleep;
 	atomic_t interrupt_sleep_count;
-	snd_info_entry_t *proc_entry;
+	struct snd_info_entry *proc_entry;
 
 #ifdef CONFIG_PM
 	u32 *saved_regs;
@@ -364,17 +363,20 @@
 #endif
 };
 
-int snd_ymfpci_create(snd_card_t * card,
+int snd_ymfpci_create(struct snd_card *card,
 		      struct pci_dev *pci,
 		      unsigned short old_legacy_ctrl,
-		      ymfpci_t ** rcodec);
-void snd_ymfpci_free_gameport(ymfpci_t *chip);
+		      struct snd_ymfpci ** rcodec);
+void snd_ymfpci_free_gameport(struct snd_ymfpci *chip);
 
-int snd_ymfpci_pcm(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
-int snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
-int snd_ymfpci_pcm_spdif(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
-int snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
-int snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch);
-int snd_ymfpci_timer(ymfpci_t *chip, int device);
+int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state);
+int snd_ymfpci_resume(struct pci_dev *pci);
+
+int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
+int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
+int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
+int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
+int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch);
+int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);
 
 #endif /* __SOUND_YMFPCI_H */
diff --git a/init/Kconfig b/init/Kconfig
index ea097e0..f8f6929 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -105,7 +105,6 @@
 
 config SYSVIPC
 	bool "System V IPC"
-	depends on MMU
 	---help---
 	  Inter Process Communication is a suite of library functions and
 	  system calls which let processes (running programs) synchronize and
@@ -190,40 +189,13 @@
 
 config AUDITSYSCALL
 	bool "Enable system-call auditing support"
-	depends on AUDIT && (X86 || PPC || PPC64 || ARCH_S390 || IA64 || UML || SPARC64)
+	depends on AUDIT && (X86 || PPC || PPC64 || S390 || IA64 || UML || SPARC64)
 	default y if SECURITY_SELINUX
 	help
 	  Enable low-overhead system-call auditing infrastructure that
 	  can be used independently or with another kernel subsystem,
 	  such as SELinux.
 
-config HOTPLUG
-	bool "Support for hot-pluggable devices" if !ARCH_S390
-	default ARCH_S390
-	help
-	  This option is provided for the case where no in-kernel-tree
-	  modules require HOTPLUG functionality, but a module built
-	  outside the kernel tree does. Such modules require Y here.
-
-config KOBJECT_UEVENT
-	bool "Kernel Userspace Events"
-	depends on NET
-	default y
-	help
-	  This option enables the kernel userspace event layer, which is a
-	  simple mechanism for kernel-to-user communication over a netlink
-	  socket.
-	  The goal of the kernel userspace events layer is to provide a simple
-	  and efficient events system, that notifies userspace about kobject
-	  state changes. This will enable applications to just listen for
-	  events instead of polling system devices and files.
-	  Hotplug events (kobject addition and removal) are also available on
-	  the netlink socket in addition to the execution of /sbin/hotplug if
-	  CONFIG_HOTPLUG is enabled.
-
-	  Say Y, unless you are building a system requiring minimal memory
-	  consumption.
-
 config IKCONFIG
 	bool "Kernel .config support"
 	---help---
@@ -256,6 +228,38 @@
 
 source "usr/Kconfig"
 
+config UID16
+	bool "Enable 16-bit UID system calls" if EMBEDDED
+	depends !ALPHA && !PPC && !PPC64 && !PARISC && !V850 && !ARCH_S390X
+	depends !X86_64 || IA32_EMULATION
+	depends !SPARC64 || SPARC32_COMPAT
+	default y
+	help
+	  This enables the legacy 16-bit UID syscall wrappers.
+
+config VM86
+	depends X86
+	default y
+	bool "Enable VM86 support" if EMBEDDED
+	help
+          This option is required by programs like DOSEMU to run 16-bit legacy
+	  code on X86 processors. It also may be needed by software like
+          XFree86 to initialize some video cards via BIOS. Disabling this
+          option saves about 6k.
+
+config CC_OPTIMIZE_FOR_SIZE
+	bool "Optimize for size (Look out for broken compilers!)"
+	default y
+	depends on ARM || H8300 || EXPERIMENTAL
+	help
+	  Enabling this option will pass "-Os" instead of "-O2" to gcc
+	  resulting in a smaller kernel.
+
+	  WARNING: some versions of gcc may generate incorrect code with this
+	  option.  If problems are observed, a gcc upgrade may be needed.
+
+	  If unsure, say N.
+
 menuconfig EMBEDDED
 	bool "Configure standard kernel features (for small systems)"
 	help
@@ -295,6 +299,15 @@
 	   you wait for kallsyms to be fixed.
 
 
+config HOTPLUG
+	bool "Support for hot-pluggable devices" if EMBEDDED
+	default y
+	help
+	  This option is provided for the case where no hotplug or uevent
+	  capabilities is wanted by the kernel.  You should only consider
+	  disabling this option for embedded systems that do not use modules, a
+	  dynamic /dev tree, or dynamic device discovery.  Just say Y.
+
 config PRINTK
 	default y
 	bool "Enable support for printk" if EMBEDDED
@@ -315,6 +328,21 @@
           option for embedded systems with no facilities for reporting errors.
           Just say Y.
 
+config DOUBLEFAULT
+	depends X86
+	default y if X86
+	bool "Enable doublefault exception handler" if EMBEDDED
+	help
+          This option allows trapping of rare doublefault exceptions that
+          would otherwise cause a system to silently reboot. Disabling this
+          option saves about 4k.
+
+config ELF_CORE
+	default y
+	bool "Enable ELF core dumps" if EMBEDDED
+	help
+	  Enable support for generating core dumps. Disabling saves about 4k.
+
 config BASE_FULL
 	default y
 	bool "Enable full-sized data structures for core" if EMBEDDED
@@ -338,18 +366,6 @@
 	  Disabling this option will cause the kernel to be built without
 	  support for epoll family of system calls.
 
-config CC_OPTIMIZE_FOR_SIZE
-	bool "Optimize for size" if EMBEDDED
-	default y if ARM || H8300
-	help
-	  Enabling this option will pass "-Os" instead of "-O2" to gcc
-	  resulting in a smaller kernel.
-
-	  WARNING: some versions of gcc may generate incorrect code with this
-	  option.  If problems are observed, a gcc upgrade may be needed.
-
-	  If unsure, say N.
-
 config SHMEM
 	bool "Use full shmem filesystem" if EMBEDDED
 	default y
@@ -398,6 +414,15 @@
 	  no dummy operations need be executed.
 	  Zero means use compiler's default.
 
+config SLAB
+	default y
+	bool "Use full SLAB allocator" if EMBEDDED
+	help
+	  Disabling this replaces the advanced SLAB allocator and
+	  kmalloc support with the drastically simpler SLOB allocator.
+	  SLOB is more space efficient but does not scale well and is
+	  more susceptible to fragmentation.
+
 endmenu		# General setup
 
 config TINY_SHMEM
@@ -409,6 +434,10 @@
 	default 0 if BASE_FULL
 	default 1 if !BASE_FULL
 
+config SLOB
+	default !SLAB
+	bool
+
 menu "Loadable module support"
 
 config MODULES
@@ -460,8 +489,8 @@
 	  If unsure, say Y.
 
 config MODVERSIONS
-	bool "Module versioning support (EXPERIMENTAL)"
-	depends on MODULES && EXPERIMENTAL
+	bool "Module versioning support"
+	depends on MODULES
 	help
 	  Usually, you have to use modules compiled with your kernel.
 	  Saying Y here makes it sometimes possible to use modules
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
index 3fbc355..f6f3680 100644
--- a/init/do_mounts_md.c
+++ b/init/do_mounts_md.c
@@ -17,7 +17,7 @@
 static struct {
 	int minor;
 	int partitioned;
-	int pers;
+	int level;
 	int chunk;
 	char *device_names;
 } md_setup_args[MAX_MD_DEVS] __initdata;
@@ -47,7 +47,7 @@
  */
 static int __init md_setup(char *str)
 {
-	int minor, level, factor, fault, pers, partitioned = 0;
+	int minor, level, factor, fault, partitioned = 0;
 	char *pername = "";
 	char *str1;
 	int ent;
@@ -78,7 +78,7 @@
 	}
 	if (ent >= md_setup_ents)
 		md_setup_ents++;
-	switch (get_option(&str, &level)) {	/* RAID Personality */
+	switch (get_option(&str, &level)) {	/* RAID level */
 	case 2: /* could be 0 or -1.. */
 		if (level == 0 || level == LEVEL_LINEAR) {
 			if (get_option(&str, &factor) != 2 ||	/* Chunk Size */
@@ -86,16 +86,12 @@
 				printk(KERN_WARNING "md: Too few arguments supplied to md=.\n");
 				return 0;
 			}
-			md_setup_args[ent].pers = level;
+			md_setup_args[ent].level = level;
 			md_setup_args[ent].chunk = 1 << (factor+12);
-			if (level ==  LEVEL_LINEAR) {
-				pers = LINEAR;
+			if (level ==  LEVEL_LINEAR)
 				pername = "linear";
-			} else {
-				pers = RAID0;
+			else
 				pername = "raid0";
-			}
-			md_setup_args[ent].pers = pers;
 			break;
 		}
 		/* FALL THROUGH */
@@ -103,7 +99,7 @@
 		str = str1;
 		/* FALL THROUGH */
 	case 0:
-		md_setup_args[ent].pers = 0;
+		md_setup_args[ent].level = LEVEL_NONE;
 		pername="super-block";
 	}
 
@@ -190,10 +186,10 @@
 			continue;
 		}
 
-		if (md_setup_args[ent].pers) {
+		if (md_setup_args[ent].level != LEVEL_NONE) {
 			/* non-persistent */
 			mdu_array_info_t ainfo;
-			ainfo.level = pers_to_level(md_setup_args[ent].pers);
+			ainfo.level = md_setup_args[ent].level;
 			ainfo.size = 0;
 			ainfo.nr_disks =0;
 			ainfo.raid_disks =0;
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index c10b08a..c2683fc 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -145,7 +145,7 @@
 	int nblocks, i, disk;
 	char *buf = NULL;
 	unsigned short rotate = 0;
-#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
 	char rotator[4] = { '|' , '/' , '-' , '\\' };
 #endif
 
@@ -237,7 +237,7 @@
 		}
 		sys_read(in_fd, buf, BLOCK_SIZE);
 		sys_write(out_fd, buf, BLOCK_SIZE);
-#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_PPC_ISERIES)
+#if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)
 		if (!(i % 16)) {
 			printk("%c\b", rotator[rotate & 0x3]);
 			rotate++;
diff --git a/init/main.c b/init/main.c
index 27f97f9..8342c28 100644
--- a/init/main.c
+++ b/init/main.c
@@ -47,22 +47,17 @@
 #include <linux/rmap.h>
 #include <linux/mempolicy.h>
 #include <linux/key.h>
-#include <net/sock.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
+#include <asm/cacheflush.h>
 
 /*
  * This is one of the first .c files built. Error out early
  * if we have compiler trouble..
  */
-#if __GNUC__ == 2 && __GNUC_MINOR__ == 96
-#ifdef CONFIG_FRAME_POINTER
-#error This compiler cannot compile correctly with frame pointers enabled
-#endif
-#endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/smp.h>
@@ -74,7 +69,7 @@
  * To avoid associated bogus bug reports, we flatly refuse to compile
  * with a gcc that is known to be too old from the very beginning.
  */
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)
+#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
 #error Sorry, your GCC is too old. It builds incorrect kernels.
 #endif
 
@@ -100,6 +95,9 @@
 #else
 static inline void acpi_early_init(void) { }
 #endif
+#ifndef CONFIG_DEBUG_RODATA
+static inline void mark_rodata_ro(void) { }
+#endif
 
 #ifdef CONFIG_TC
 extern void tc_init(void);
@@ -509,6 +507,7 @@
 	}
 #endif
 	vfs_caches_init_early();
+	cpuset_init_early();
 	mem_init();
 	kmem_cache_init();
 	setup_per_cpu_pageset();
@@ -614,9 +613,6 @@
 	sysctl_init();
 #endif
 
-	/* Networking initialization needs a process context */ 
-	sock_init();
-
 	do_initcalls();
 }
 
@@ -712,6 +708,7 @@
 	 */
 	free_initmem();
 	unlock_kernel();
+	mark_rodata_ro();
 	system_state = SYSTEM_RUNNING;
 	numa_default_policy();
 
diff --git a/ipc/sem.c b/ipc/sem.c
index 19af028..cb5bb2a 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -381,6 +381,7 @@
 			/* hands-off: q will disappear immediately after
 			 * writing q->status.
 			 */
+			smp_wmb();
 			q->status = error;
 			q = n;
 		} else {
@@ -461,6 +462,7 @@
 		n = q->next;
 		q->status = IN_WAKEUP;
 		wake_up_process(q->sleeper); /* doesn't sleep */
+		smp_wmb();
 		q->status = -EIDRM;	/* hands-off q */
 		q = n;
 	}
diff --git a/ipc/shm.c b/ipc/shm.c
index 587d836..0b92e87 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -34,8 +34,6 @@
 
 #include "util.h"
 
-#define shm_flags	shm_perm.mode
-
 static struct file_operations shm_file_operations;
 static struct vm_operations_struct shm_vm_ops;
 
@@ -148,7 +146,7 @@
 	shp->shm_dtim = get_seconds();
 	shp->shm_nattch--;
 	if(shp->shm_nattch == 0 &&
-	   shp->shm_flags & SHM_DEST)
+	   shp->shm_perm.mode & SHM_DEST)
 		shm_destroy (shp);
 	else
 		shm_unlock(shp);
@@ -157,14 +155,22 @@
 
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
 {
-	file_accessed(file);
-	vma->vm_ops = &shm_vm_ops;
-	shm_inc(file->f_dentry->d_inode->i_ino);
-	return 0;
+	int ret;
+
+	ret = shmem_mmap(file, vma);
+	if (ret == 0) {
+		vma->vm_ops = &shm_vm_ops;
+		shm_inc(file->f_dentry->d_inode->i_ino);
+	}
+
+	return ret;
 }
 
 static struct file_operations shm_file_operations = {
-	.mmap	= shm_mmap
+	.mmap	= shm_mmap,
+#ifndef CONFIG_MMU
+	.get_unmapped_area = shmem_get_unmapped_area,
+#endif
 };
 
 static struct vm_operations_struct shm_vm_ops = {
@@ -197,7 +203,7 @@
 		return -ENOMEM;
 
 	shp->shm_perm.key = key;
-	shp->shm_flags = (shmflg & S_IRWXUGO);
+	shp->shm_perm.mode = (shmflg & S_IRWXUGO);
 	shp->mlock_user = NULL;
 
 	shp->shm_perm.security = NULL;
@@ -337,7 +343,7 @@
 
 		out->uid	= tbuf.shm_perm.uid;
 		out->gid	= tbuf.shm_perm.gid;
-		out->mode	= tbuf.shm_flags;
+		out->mode	= tbuf.shm_perm.mode;
 
 		return 0;
 	    }
@@ -350,7 +356,7 @@
 
 		out->uid	= tbuf_old.shm_perm.uid;
 		out->gid	= tbuf_old.shm_perm.gid;
-		out->mode	= tbuf_old.shm_flags;
+		out->mode	= tbuf_old.shm_perm.mode;
 
 		return 0;
 	    }
@@ -552,13 +558,13 @@
 			if (!is_file_hugepages(shp->shm_file)) {
 				err = shmem_lock(shp->shm_file, 1, user);
 				if (!err) {
-					shp->shm_flags |= SHM_LOCKED;
+					shp->shm_perm.mode |= SHM_LOCKED;
 					shp->mlock_user = user;
 				}
 			}
 		} else if (!is_file_hugepages(shp->shm_file)) {
 			shmem_lock(shp->shm_file, 0, shp->mlock_user);
-			shp->shm_flags &= ~SHM_LOCKED;
+			shp->shm_perm.mode &= ~SHM_LOCKED;
 			shp->mlock_user = NULL;
 		}
 		shm_unlock(shp);
@@ -597,7 +603,7 @@
 			goto out_unlock_up;
 
 		if (shp->shm_nattch){
-			shp->shm_flags |= SHM_DEST;
+			shp->shm_perm.mode |= SHM_DEST;
 			/* Do not find it any more */
 			shp->shm_perm.key = IPC_PRIVATE;
 			shm_unlock(shp);
@@ -636,7 +642,7 @@
 		
 		shp->shm_perm.uid = setbuf.uid;
 		shp->shm_perm.gid = setbuf.gid;
-		shp->shm_flags = (shp->shm_flags & ~S_IRWXUGO)
+		shp->shm_perm.mode = (shp->shm_perm.mode & ~S_IRWXUGO)
 			| (setbuf.mode & S_IRWXUGO);
 		shp->shm_ctim = get_seconds();
 		break;
@@ -769,7 +775,7 @@
 		BUG();
 	shp->shm_nattch--;
 	if(shp->shm_nattch == 0 &&
-	   shp->shm_flags & SHM_DEST)
+	   shp->shm_perm.mode & SHM_DEST)
 		shm_destroy (shp);
 	else
 		shm_unlock(shp);
@@ -894,7 +900,7 @@
 	return seq_printf(s, format,
 			  shp->shm_perm.key,
 			  shp->id,
-			  shp->shm_flags,
+			  shp->shm_perm.mode,
 			  shp->shm_segsz,
 			  shp->shm_cprid,
 			  shp->shm_lprid,
diff --git a/kernel/.gitignore b/kernel/.gitignore
new file mode 100644
index 0000000..f2ab700
--- /dev/null
+++ b/kernel/.gitignore
@@ -0,0 +1,5 @@
+#
+# Generated files
+#
+config_data.h
+config_data.gz
diff --git a/kernel/acct.c b/kernel/acct.c
index 6312d6b..38d57fa 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -427,6 +427,7 @@
 	u64 elapsed;
 	u64 run_time;
 	struct timespec uptime;
+	unsigned long jiffies;
 
 	/*
 	 * First check to see if there is enough free_space to continue
@@ -467,12 +468,12 @@
 #endif
 	do_div(elapsed, AHZ);
 	ac.ac_btime = xtime.tv_sec - elapsed;
-	ac.ac_utime = encode_comp_t(jiffies_to_AHZ(
-					    current->signal->utime +
-					    current->group_leader->utime));
-	ac.ac_stime = encode_comp_t(jiffies_to_AHZ(
-					    current->signal->stime +
-					    current->group_leader->stime));
+	jiffies = cputime_to_jiffies(cputime_add(current->group_leader->utime,
+						 current->signal->utime));
+	ac.ac_utime = encode_comp_t(jiffies_to_AHZ(jiffies));
+	jiffies = cputime_to_jiffies(cputime_add(current->group_leader->stime,
+						 current->signal->stime));
+	ac.ac_stime = encode_comp_t(jiffies_to_AHZ(jiffies));
 	/* we really need to bite the bullet and change layout */
 	ac.ac_uid = current->uid;
 	ac.ac_gid = current->gid;
@@ -580,7 +581,8 @@
 void acct_update_integrals(struct task_struct *tsk)
 {
 	if (likely(tsk->mm)) {
-		long delta = tsk->stime - tsk->acct_stimexpd;
+		long delta =
+			cputime_to_jiffies(tsk->stime) - tsk->acct_stimexpd;
 
 		if (delta == 0)
 			return;
diff --git a/kernel/audit.c b/kernel/audit.c
index 0c56320..d13ab7d 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -267,7 +267,7 @@
 	return old;
 }
 
-int kauditd_thread(void *dummy)
+static int kauditd_thread(void *dummy)
 {
 	struct sk_buff *skb;
 
@@ -291,8 +291,10 @@
 			set_current_state(TASK_INTERRUPTIBLE);
 			add_wait_queue(&kauditd_wait, &wait);
 
-			if (!skb_queue_len(&audit_skb_queue))
+			if (!skb_queue_len(&audit_skb_queue)) {
+				try_to_freeze();
 				schedule();
+			}
 
 			__set_current_state(TASK_RUNNING);
 			remove_wait_queue(&kauditd_wait, &wait);
diff --git a/kernel/configs.c b/kernel/configs.c
index 986f7af..009e1eb 100644
--- a/kernel/configs.c
+++ b/kernel/configs.c
@@ -3,7 +3,7 @@
  * Echo the kernel .config file used to build the kernel
  *
  * Copyright (C) 2002 Khalid Aziz <khalid_aziz@hp.com>
- * Copyright (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+ * Copyright (C) 2002 Randy Dunlap <rdunlap@xenotime.net>
  * Copyright (C) 2002 Al Stone <ahs3@fc.hp.com>
  * Copyright (C) 2002 Hewlett-Packard Company
  *
diff --git a/kernel/cpu.c b/kernel/cpu.c
index d61ba88..e882c6b 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -16,47 +16,76 @@
 #include <asm/semaphore.h>
 
 /* This protects CPUs going up and down... */
-DECLARE_MUTEX(cpucontrol);
-EXPORT_SYMBOL_GPL(cpucontrol);
+static DECLARE_MUTEX(cpucontrol);
 
 static struct notifier_block *cpu_chain;
 
-/*
- * Used to check by callers if they need to acquire the cpucontrol
- * or not to protect a cpu from being removed. Its sometimes required to
- * call these functions both for normal operations, and in response to
- * a cpu being added/removed. If the context of the call is in the same
- * thread context as a CPU hotplug thread, we dont need to take the lock
- * since its already protected
- * check drivers/cpufreq/cpufreq.c for its usage - Ashok Raj
- */
+#ifdef CONFIG_HOTPLUG_CPU
+static struct task_struct *lock_cpu_hotplug_owner;
+static int lock_cpu_hotplug_depth;
 
-int current_in_cpu_hotplug(void)
+static int __lock_cpu_hotplug(int interruptible)
 {
-	return (current->flags & PF_HOTPLUG_CPU);
+	int ret = 0;
+
+	if (lock_cpu_hotplug_owner != current) {
+		if (interruptible)
+			ret = down_interruptible(&cpucontrol);
+		else
+			down(&cpucontrol);
+	}
+
+	/*
+	 * Set only if we succeed in locking
+	 */
+	if (!ret) {
+		lock_cpu_hotplug_depth++;
+		lock_cpu_hotplug_owner = current;
+	}
+
+	return ret;
 }
 
-EXPORT_SYMBOL_GPL(current_in_cpu_hotplug);
+void lock_cpu_hotplug(void)
+{
+	__lock_cpu_hotplug(0);
+}
+EXPORT_SYMBOL_GPL(lock_cpu_hotplug);
 
+void unlock_cpu_hotplug(void)
+{
+	if (--lock_cpu_hotplug_depth == 0) {
+		lock_cpu_hotplug_owner = NULL;
+		up(&cpucontrol);
+	}
+}
+EXPORT_SYMBOL_GPL(unlock_cpu_hotplug);
+
+int lock_cpu_hotplug_interruptible(void)
+{
+	return __lock_cpu_hotplug(1);
+}
+EXPORT_SYMBOL_GPL(lock_cpu_hotplug_interruptible);
+#endif	/* CONFIG_HOTPLUG_CPU */
 
 /* Need to know about CPUs going up/down? */
 int register_cpu_notifier(struct notifier_block *nb)
 {
 	int ret;
 
-	if ((ret = down_interruptible(&cpucontrol)) != 0)
+	if ((ret = lock_cpu_hotplug_interruptible()) != 0)
 		return ret;
 	ret = notifier_chain_register(&cpu_chain, nb);
-	up(&cpucontrol);
+	unlock_cpu_hotplug();
 	return ret;
 }
 EXPORT_SYMBOL(register_cpu_notifier);
 
 void unregister_cpu_notifier(struct notifier_block *nb)
 {
-	down(&cpucontrol);
+	lock_cpu_hotplug();
 	notifier_chain_unregister(&cpu_chain, nb);
-	up(&cpucontrol);
+	unlock_cpu_hotplug();
 }
 EXPORT_SYMBOL(unregister_cpu_notifier);
 
@@ -112,13 +141,6 @@
 		goto out;
 	}
 
-	/*
-	 * Leave a trace in current->flags indicating we are already in
-	 * process of performing CPU hotplug. Callers can check if cpucontrol
-	 * is already acquired by current thread, and if so not cause
-	 * a dead lock by not acquiring the lock
-	 */
-	current->flags |= PF_HOTPLUG_CPU;
 	err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE,
 						(void *)(long)cpu);
 	if (err == NOTIFY_BAD) {
@@ -171,7 +193,6 @@
 out_allowed:
 	set_cpus_allowed(current, old_allowed);
 out:
-	current->flags &= ~PF_HOTPLUG_CPU;
 	unlock_cpu_hotplug();
 	return err;
 }
@@ -182,7 +203,7 @@
 	int ret;
 	void *hcpu = (void *)(long)cpu;
 
-	if ((ret = down_interruptible(&cpucontrol)) != 0)
+	if ((ret = lock_cpu_hotplug_interruptible()) != 0)
 		return ret;
 
 	if (cpu_online(cpu) || !cpu_present(cpu)) {
@@ -190,11 +211,6 @@
 		goto out;
 	}
 
-	/*
-	 * Leave a trace in current->flags indicating we are already in
-	 * process of performing CPU hotplug.
-	 */
-	current->flags |= PF_HOTPLUG_CPU;
 	ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu);
 	if (ret == NOTIFY_BAD) {
 		printk("%s: attempt to bring up CPU %u failed\n",
@@ -217,7 +233,6 @@
 	if (ret != 0)
 		notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu);
 out:
-	current->flags &= ~PF_HOTPLUG_CPU;
-	up(&cpucontrol);
+	unlock_cpu_hotplug();
 	return ret;
 }
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 7430640..eab64e2 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -39,6 +39,7 @@
 #include <linux/namei.h>
 #include <linux/pagemap.h>
 #include <linux/proc_fs.h>
+#include <linux/rcupdate.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
@@ -54,7 +55,23 @@
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
 
-#define CPUSET_SUPER_MAGIC 		0x27e0eb
+#define CPUSET_SUPER_MAGIC		0x27e0eb
+
+/*
+ * Tracks how many cpusets are currently defined in system.
+ * When there is only one cpuset (the root cpuset) we can
+ * short circuit some hooks.
+ */
+int number_of_cpusets __read_mostly;
+
+/* See "Frequency meter" comments, below. */
+
+struct fmeter {
+	int cnt;		/* unprocessed events count */
+	int val;		/* most recent output value */
+	time_t time;		/* clock (secs) when val computed */
+	spinlock_t lock;	/* guards read or write of above */
+};
 
 struct cpuset {
 	unsigned long flags;		/* "unsigned long" so bitops work */
@@ -80,13 +97,16 @@
 	 * Copy of global cpuset_mems_generation as of the most
 	 * recent time this cpuset changed its mems_allowed.
 	 */
-	 int mems_generation;
+	int mems_generation;
+
+	struct fmeter fmeter;		/* memory_pressure filter */
 };
 
 /* bits in struct cpuset flags field */
 typedef enum {
 	CS_CPU_EXCLUSIVE,
 	CS_MEM_EXCLUSIVE,
+	CS_MEMORY_MIGRATE,
 	CS_REMOVED,
 	CS_NOTIFY_ON_RELEASE
 } cpuset_flagbits_t;
@@ -112,6 +132,11 @@
 	return !!test_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
 }
 
+static inline int is_memory_migrate(const struct cpuset *cs)
+{
+	return !!test_bit(CS_MEMORY_MIGRATE, &cs->flags);
+}
+
 /*
  * Increment this atomic integer everytime any cpuset changes its
  * mems_allowed value.  Users of cpusets can track this generation
@@ -137,13 +162,10 @@
 	.count = ATOMIC_INIT(0),
 	.sibling = LIST_HEAD_INIT(top_cpuset.sibling),
 	.children = LIST_HEAD_INIT(top_cpuset.children),
-	.parent = NULL,
-	.dentry = NULL,
-	.mems_generation = 0,
 };
 
 static struct vfsmount *cpuset_mount;
-static struct super_block *cpuset_sb = NULL;
+static struct super_block *cpuset_sb;
 
 /*
  * We have two global cpuset semaphores below.  They can nest.
@@ -227,6 +249,11 @@
  * a tasks cpuset pointer we use task_lock(), which acts on a spinlock
  * (task->alloc_lock) already in the task_struct routinely used for
  * such matters.
+ *
+ * P.S.  One more locking exception.  RCU is used to guard the
+ * update of a tasks cpuset pointer by attach_task() and the
+ * access of task->cpuset->mems_generation via that pointer in
+ * the routine cpuset_update_task_memory_state().
  */
 
 static DECLARE_MUTEX(manage_sem);
@@ -304,7 +331,7 @@
 	spin_lock(&dcache_lock);
 	node = dentry->d_subdirs.next;
 	while (node != &dentry->d_subdirs) {
-		struct dentry *d = list_entry(node, struct dentry, d_child);
+		struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
 		list_del_init(node);
 		if (d->d_inode) {
 			d = dget_locked(d);
@@ -316,7 +343,7 @@
 		}
 		node = dentry->d_subdirs.next;
 	}
-	list_del_init(&dentry->d_child);
+	list_del_init(&dentry->d_u.d_child);
 	spin_unlock(&dcache_lock);
 	remove_dir(dentry);
 }
@@ -570,20 +597,43 @@
 	BUG_ON(!nodes_intersects(*pmask, node_online_map));
 }
 
-/*
- * Refresh current tasks mems_allowed and mems_generation from current
- * tasks cpuset.
+/**
+ * cpuset_update_task_memory_state - update task memory placement
  *
- * Call without callback_sem or task_lock() held.  May be called with
- * or without manage_sem held.  Will acquire task_lock() and might
- * acquire callback_sem during call.
+ * If the current tasks cpusets mems_allowed changed behind our
+ * backs, update current->mems_allowed, mems_generation and task NUMA
+ * mempolicy to the new value.
  *
- * The task_lock() is required to dereference current->cpuset safely.
- * Without it, we could pick up the pointer value of current->cpuset
- * in one instruction, and then attach_task could give us a different
- * cpuset, and then the cpuset we had could be removed and freed,
- * and then on our next instruction, we could dereference a no longer
- * valid cpuset pointer to get its mems_generation field.
+ * Task mempolicy is updated by rebinding it relative to the
+ * current->cpuset if a task has its memory placement changed.
+ * Do not call this routine if in_interrupt().
+ *
+ * Call without callback_sem or task_lock() held.  May be called
+ * with or without manage_sem held.  Doesn't need task_lock to guard
+ * against another task changing a non-NULL cpuset pointer to NULL,
+ * as that is only done by a task on itself, and if the current task
+ * is here, it is not simultaneously in the exit code NULL'ing its
+ * cpuset pointer.  This routine also might acquire callback_sem and
+ * current->mm->mmap_sem during call.
+ *
+ * Reading current->cpuset->mems_generation doesn't need task_lock
+ * to guard the current->cpuset derefence, because it is guarded
+ * from concurrent freeing of current->cpuset by attach_task(),
+ * using RCU.
+ *
+ * The rcu_dereference() is technically probably not needed,
+ * as I don't actually mind if I see a new cpuset pointer but
+ * an old value of mems_generation.  However this really only
+ * matters on alpha systems using cpusets heavily.  If I dropped
+ * that rcu_dereference(), it would save them a memory barrier.
+ * For all other arch's, rcu_dereference is a no-op anyway, and for
+ * alpha systems not using cpusets, another planned optimization,
+ * avoiding the rcu critical section for tasks in the root cpuset
+ * which is statically allocated, so can't vanish, will make this
+ * irrelevant.  Better to use RCU as intended, than to engage in
+ * some cute trick to save a memory barrier that is impossible to
+ * test, for alpha systems using cpusets heavily, which might not
+ * even exist.
  *
  * This routine is needed to update the per-task mems_allowed data,
  * within the tasks context, when it is trying to allocate memory
@@ -591,27 +641,31 @@
  * task has been modifying its cpuset.
  */
 
-static void refresh_mems(void)
+void cpuset_update_task_memory_state()
 {
 	int my_cpusets_mem_gen;
+	struct task_struct *tsk = current;
+	struct cpuset *cs;
 
-	task_lock(current);
-	my_cpusets_mem_gen = current->cpuset->mems_generation;
-	task_unlock(current);
+	if (tsk->cpuset == &top_cpuset) {
+		/* Don't need rcu for top_cpuset.  It's never freed. */
+		my_cpusets_mem_gen = top_cpuset.mems_generation;
+	} else {
+		rcu_read_lock();
+		cs = rcu_dereference(tsk->cpuset);
+		my_cpusets_mem_gen = cs->mems_generation;
+		rcu_read_unlock();
+	}
 
-	if (current->cpuset_mems_generation != my_cpusets_mem_gen) {
-		struct cpuset *cs;
-		nodemask_t oldmem = current->mems_allowed;
-
+	if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) {
 		down(&callback_sem);
-		task_lock(current);
-		cs = current->cpuset;
-		guarantee_online_mems(cs, &current->mems_allowed);
-		current->cpuset_mems_generation = cs->mems_generation;
-		task_unlock(current);
+		task_lock(tsk);
+		cs = tsk->cpuset;	/* Maybe changed when task not locked */
+		guarantee_online_mems(cs, &tsk->mems_allowed);
+		tsk->cpuset_mems_generation = cs->mems_generation;
+		task_unlock(tsk);
 		up(&callback_sem);
-		if (!nodes_equal(oldmem, current->mems_allowed))
-			numa_policy_rebind(&oldmem, &current->mems_allowed);
+		mpol_rebind_task(tsk, &tsk->mems_allowed);
 	}
 }
 
@@ -766,36 +820,150 @@
 }
 
 /*
+ * Handle user request to change the 'mems' memory placement
+ * of a cpuset.  Needs to validate the request, update the
+ * cpusets mems_allowed and mems_generation, and for each
+ * task in the cpuset, rebind any vma mempolicies and if
+ * the cpuset is marked 'memory_migrate', migrate the tasks
+ * pages to the new memory.
+ *
  * Call with manage_sem held.  May take callback_sem during call.
+ * Will take tasklist_lock, scan tasklist for tasks in cpuset cs,
+ * lock each such tasks mm->mmap_sem, scan its vma's and rebind
+ * their mempolicies to the cpusets new mems_allowed.
  */
 
 static int update_nodemask(struct cpuset *cs, char *buf)
 {
 	struct cpuset trialcs;
+	nodemask_t oldmem;
+	struct task_struct *g, *p;
+	struct mm_struct **mmarray;
+	int i, n, ntasks;
+	int migrate;
+	int fudge;
 	int retval;
 
 	trialcs = *cs;
 	retval = nodelist_parse(buf, trialcs.mems_allowed);
 	if (retval < 0)
-		return retval;
+		goto done;
 	nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map);
-	if (nodes_empty(trialcs.mems_allowed))
-		return -ENOSPC;
-	retval = validate_change(cs, &trialcs);
-	if (retval == 0) {
-		down(&callback_sem);
-		cs->mems_allowed = trialcs.mems_allowed;
-		atomic_inc(&cpuset_mems_generation);
-		cs->mems_generation = atomic_read(&cpuset_mems_generation);
-		up(&callback_sem);
+	oldmem = cs->mems_allowed;
+	if (nodes_equal(oldmem, trialcs.mems_allowed)) {
+		retval = 0;		/* Too easy - nothing to do */
+		goto done;
 	}
+	if (nodes_empty(trialcs.mems_allowed)) {
+		retval = -ENOSPC;
+		goto done;
+	}
+	retval = validate_change(cs, &trialcs);
+	if (retval < 0)
+		goto done;
+
+	down(&callback_sem);
+	cs->mems_allowed = trialcs.mems_allowed;
+	atomic_inc(&cpuset_mems_generation);
+	cs->mems_generation = atomic_read(&cpuset_mems_generation);
+	up(&callback_sem);
+
+	set_cpuset_being_rebound(cs);		/* causes mpol_copy() rebind */
+
+	fudge = 10;				/* spare mmarray[] slots */
+	fudge += cpus_weight(cs->cpus_allowed);	/* imagine one fork-bomb/cpu */
+	retval = -ENOMEM;
+
+	/*
+	 * Allocate mmarray[] to hold mm reference for each task
+	 * in cpuset cs.  Can't kmalloc GFP_KERNEL while holding
+	 * tasklist_lock.  We could use GFP_ATOMIC, but with a
+	 * few more lines of code, we can retry until we get a big
+	 * enough mmarray[] w/o using GFP_ATOMIC.
+	 */
+	while (1) {
+		ntasks = atomic_read(&cs->count);	/* guess */
+		ntasks += fudge;
+		mmarray = kmalloc(ntasks * sizeof(*mmarray), GFP_KERNEL);
+		if (!mmarray)
+			goto done;
+		write_lock_irq(&tasklist_lock);		/* block fork */
+		if (atomic_read(&cs->count) <= ntasks)
+			break;				/* got enough */
+		write_unlock_irq(&tasklist_lock);	/* try again */
+		kfree(mmarray);
+	}
+
+	n = 0;
+
+	/* Load up mmarray[] with mm reference for each task in cpuset. */
+	do_each_thread(g, p) {
+		struct mm_struct *mm;
+
+		if (n >= ntasks) {
+			printk(KERN_WARNING
+				"Cpuset mempolicy rebind incomplete.\n");
+			continue;
+		}
+		if (p->cpuset != cs)
+			continue;
+		mm = get_task_mm(p);
+		if (!mm)
+			continue;
+		mmarray[n++] = mm;
+	} while_each_thread(g, p);
+	write_unlock_irq(&tasklist_lock);
+
+	/*
+	 * Now that we've dropped the tasklist spinlock, we can
+	 * rebind the vma mempolicies of each mm in mmarray[] to their
+	 * new cpuset, and release that mm.  The mpol_rebind_mm()
+	 * call takes mmap_sem, which we couldn't take while holding
+	 * tasklist_lock.  Forks can happen again now - the mpol_copy()
+	 * cpuset_being_rebound check will catch such forks, and rebind
+	 * their vma mempolicies too.  Because we still hold the global
+	 * cpuset manage_sem, we know that no other rebind effort will
+	 * be contending for the global variable cpuset_being_rebound.
+	 * It's ok if we rebind the same mm twice; mpol_rebind_mm()
+	 * is idempotent.  Also migrate pages in each mm to new nodes.
+	 */
+	migrate = is_memory_migrate(cs);
+	for (i = 0; i < n; i++) {
+		struct mm_struct *mm = mmarray[i];
+
+		mpol_rebind_mm(mm, &cs->mems_allowed);
+		if (migrate) {
+			do_migrate_pages(mm, &oldmem, &cs->mems_allowed,
+							MPOL_MF_MOVE_ALL);
+		}
+		mmput(mm);
+	}
+
+	/* We're done rebinding vma's to this cpusets new mems_allowed. */
+	kfree(mmarray);
+	set_cpuset_being_rebound(NULL);
+	retval = 0;
+done:
 	return retval;
 }
 
 /*
+ * Call with manage_sem held.
+ */
+
+static int update_memory_pressure_enabled(struct cpuset *cs, char *buf)
+{
+	if (simple_strtoul(buf, NULL, 10) != 0)
+		cpuset_memory_pressure_enabled = 1;
+	else
+		cpuset_memory_pressure_enabled = 0;
+	return 0;
+}
+
+/*
  * update_flag - read a 0 or a 1 in a file and update associated flag
  * bit:	the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE,
- *						CS_NOTIFY_ON_RELEASE)
+ *				CS_NOTIFY_ON_RELEASE, CS_MEMORY_MIGRATE)
  * cs:	the cpuset to update
  * buf:	the buffer where we read the 0 or 1
  *
@@ -834,6 +1002,104 @@
 }
 
 /*
+ * Frequency meter - How fast is some event occuring?
+ *
+ * These routines manage a digitally filtered, constant time based,
+ * event frequency meter.  There are four routines:
+ *   fmeter_init() - initialize a frequency meter.
+ *   fmeter_markevent() - called each time the event happens.
+ *   fmeter_getrate() - returns the recent rate of such events.
+ *   fmeter_update() - internal routine used to update fmeter.
+ *
+ * A common data structure is passed to each of these routines,
+ * which is used to keep track of the state required to manage the
+ * frequency meter and its digital filter.
+ *
+ * The filter works on the number of events marked per unit time.
+ * The filter is single-pole low-pass recursive (IIR).  The time unit
+ * is 1 second.  Arithmetic is done using 32-bit integers scaled to
+ * simulate 3 decimal digits of precision (multiplied by 1000).
+ *
+ * With an FM_COEF of 933, and a time base of 1 second, the filter
+ * has a half-life of 10 seconds, meaning that if the events quit
+ * happening, then the rate returned from the fmeter_getrate()
+ * will be cut in half each 10 seconds, until it converges to zero.
+ *
+ * It is not worth doing a real infinitely recursive filter.  If more
+ * than FM_MAXTICKS ticks have elapsed since the last filter event,
+ * just compute FM_MAXTICKS ticks worth, by which point the level
+ * will be stable.
+ *
+ * Limit the count of unprocessed events to FM_MAXCNT, so as to avoid
+ * arithmetic overflow in the fmeter_update() routine.
+ *
+ * Given the simple 32 bit integer arithmetic used, this meter works
+ * best for reporting rates between one per millisecond (msec) and
+ * one per 32 (approx) seconds.  At constant rates faster than one
+ * per msec it maxes out at values just under 1,000,000.  At constant
+ * rates between one per msec, and one per second it will stabilize
+ * to a value N*1000, where N is the rate of events per second.
+ * At constant rates between one per second and one per 32 seconds,
+ * it will be choppy, moving up on the seconds that have an event,
+ * and then decaying until the next event.  At rates slower than
+ * about one in 32 seconds, it decays all the way back to zero between
+ * each event.
+ */
+
+#define FM_COEF 933		/* coefficient for half-life of 10 secs */
+#define FM_MAXTICKS ((time_t)99) /* useless computing more ticks than this */
+#define FM_MAXCNT 1000000	/* limit cnt to avoid overflow */
+#define FM_SCALE 1000		/* faux fixed point scale */
+
+/* Initialize a frequency meter */
+static void fmeter_init(struct fmeter *fmp)
+{
+	fmp->cnt = 0;
+	fmp->val = 0;
+	fmp->time = 0;
+	spin_lock_init(&fmp->lock);
+}
+
+/* Internal meter update - process cnt events and update value */
+static void fmeter_update(struct fmeter *fmp)
+{
+	time_t now = get_seconds();
+	time_t ticks = now - fmp->time;
+
+	if (ticks == 0)
+		return;
+
+	ticks = min(FM_MAXTICKS, ticks);
+	while (ticks-- > 0)
+		fmp->val = (FM_COEF * fmp->val) / FM_SCALE;
+	fmp->time = now;
+
+	fmp->val += ((FM_SCALE - FM_COEF) * fmp->cnt) / FM_SCALE;
+	fmp->cnt = 0;
+}
+
+/* Process any previous ticks, then bump cnt by one (times scale). */
+static void fmeter_markevent(struct fmeter *fmp)
+{
+	spin_lock(&fmp->lock);
+	fmeter_update(fmp);
+	fmp->cnt = min(FM_MAXCNT, fmp->cnt + FM_SCALE);
+	spin_unlock(&fmp->lock);
+}
+
+/* Process any previous ticks, then return current value. */
+static int fmeter_getrate(struct fmeter *fmp)
+{
+	int val;
+
+	spin_lock(&fmp->lock);
+	fmeter_update(fmp);
+	val = fmp->val;
+	spin_unlock(&fmp->lock);
+	return val;
+}
+
+/*
  * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly
  * writing the path of the old cpuset in 'ppathbuf' if it needs to be
  * notified on release.
@@ -848,6 +1114,8 @@
 	struct task_struct *tsk;
 	struct cpuset *oldcs;
 	cpumask_t cpus;
+	nodemask_t from, to;
+	struct mm_struct *mm;
 
 	if (sscanf(pidbuf, "%d", &pid) != 1)
 		return -EIO;
@@ -887,14 +1155,27 @@
 		return -ESRCH;
 	}
 	atomic_inc(&cs->count);
-	tsk->cpuset = cs;
+	rcu_assign_pointer(tsk->cpuset, cs);
 	task_unlock(tsk);
 
 	guarantee_online_cpus(cs, &cpus);
 	set_cpus_allowed(tsk, cpus);
 
+	from = oldcs->mems_allowed;
+	to = cs->mems_allowed;
+
 	up(&callback_sem);
+
+	mm = get_task_mm(tsk);
+	if (mm) {
+		mpol_rebind_mm(mm, &to);
+		mmput(mm);
+	}
+
+	if (is_memory_migrate(cs))
+		do_migrate_pages(tsk->mm, &from, &to, MPOL_MF_MOVE_ALL);
 	put_task_struct(tsk);
+	synchronize_rcu();
 	if (atomic_dec_and_test(&oldcs->count))
 		check_for_release(oldcs, ppathbuf);
 	return 0;
@@ -905,11 +1186,14 @@
 typedef enum {
 	FILE_ROOT,
 	FILE_DIR,
+	FILE_MEMORY_MIGRATE,
 	FILE_CPULIST,
 	FILE_MEMLIST,
 	FILE_CPU_EXCLUSIVE,
 	FILE_MEM_EXCLUSIVE,
 	FILE_NOTIFY_ON_RELEASE,
+	FILE_MEMORY_PRESSURE_ENABLED,
+	FILE_MEMORY_PRESSURE,
 	FILE_TASKLIST,
 } cpuset_filetype_t;
 
@@ -960,6 +1244,15 @@
 	case FILE_NOTIFY_ON_RELEASE:
 		retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer);
 		break;
+	case FILE_MEMORY_MIGRATE:
+		retval = update_flag(CS_MEMORY_MIGRATE, cs, buffer);
+		break;
+	case FILE_MEMORY_PRESSURE_ENABLED:
+		retval = update_memory_pressure_enabled(cs, buffer);
+		break;
+	case FILE_MEMORY_PRESSURE:
+		retval = -EACCES;
+		break;
 	case FILE_TASKLIST:
 		retval = attach_task(cs, buffer, &pathbuf);
 		break;
@@ -1060,6 +1353,15 @@
 	case FILE_NOTIFY_ON_RELEASE:
 		*s++ = notify_on_release(cs) ? '1' : '0';
 		break;
+	case FILE_MEMORY_MIGRATE:
+		*s++ = is_memory_migrate(cs) ? '1' : '0';
+		break;
+	case FILE_MEMORY_PRESSURE_ENABLED:
+		*s++ = cpuset_memory_pressure_enabled ? '1' : '0';
+		break;
+	case FILE_MEMORY_PRESSURE:
+		s += sprintf(s, "%d", fmeter_getrate(&cs->fmeter));
+		break;
 	default:
 		retval = -EINVAL;
 		goto out;
@@ -1178,7 +1480,7 @@
 
 /*
  *	cpuset_create_dir - create a directory for an object.
- *	cs: 	the cpuset we create the directory for.
+ *	cs:	the cpuset we create the directory for.
  *		It must have a valid ->parent field
  *		And we are going to fill its ->dentry field.
  *	name:	The name to give to the cpuset directory. Will be copied.
@@ -1408,6 +1710,21 @@
 	.private = FILE_NOTIFY_ON_RELEASE,
 };
 
+static struct cftype cft_memory_migrate = {
+	.name = "memory_migrate",
+	.private = FILE_MEMORY_MIGRATE,
+};
+
+static struct cftype cft_memory_pressure_enabled = {
+	.name = "memory_pressure_enabled",
+	.private = FILE_MEMORY_PRESSURE_ENABLED,
+};
+
+static struct cftype cft_memory_pressure = {
+	.name = "memory_pressure",
+	.private = FILE_MEMORY_PRESSURE,
+};
+
 static int cpuset_populate_dir(struct dentry *cs_dentry)
 {
 	int err;
@@ -1422,6 +1739,10 @@
 		return err;
 	if ((err = cpuset_add_file(cs_dentry, &cft_notify_on_release)) < 0)
 		return err;
+	if ((err = cpuset_add_file(cs_dentry, &cft_memory_migrate)) < 0)
+		return err;
+	if ((err = cpuset_add_file(cs_dentry, &cft_memory_pressure)) < 0)
+		return err;
 	if ((err = cpuset_add_file(cs_dentry, &cft_tasks)) < 0)
 		return err;
 	return 0;
@@ -1446,7 +1767,7 @@
 		return -ENOMEM;
 
 	down(&manage_sem);
-	refresh_mems();
+	cpuset_update_task_memory_state();
 	cs->flags = 0;
 	if (notify_on_release(parent))
 		set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
@@ -1457,11 +1778,13 @@
 	INIT_LIST_HEAD(&cs->children);
 	atomic_inc(&cpuset_mems_generation);
 	cs->mems_generation = atomic_read(&cpuset_mems_generation);
+	fmeter_init(&cs->fmeter);
 
 	cs->parent = parent;
 
 	down(&callback_sem);
 	list_add(&cs->sibling, &cs->parent->children);
+	number_of_cpusets++;
 	up(&callback_sem);
 
 	err = cpuset_create_dir(cs, name, mode);
@@ -1503,7 +1826,7 @@
 	/* the vfs holds both inode->i_sem already */
 
 	down(&manage_sem);
-	refresh_mems();
+	cpuset_update_task_memory_state();
 	if (atomic_read(&cs->count) > 0) {
 		up(&manage_sem);
 		return -EBUSY;
@@ -1524,6 +1847,7 @@
 	spin_unlock(&d->d_lock);
 	cpuset_d_remove_dir(d);
 	dput(d);
+	number_of_cpusets--;
 	up(&callback_sem);
 	if (list_empty(&parent->children))
 		check_for_release(parent, &pathbuf);
@@ -1532,6 +1856,21 @@
 	return 0;
 }
 
+/*
+ * cpuset_init_early - just enough so that the calls to
+ * cpuset_update_task_memory_state() in early init code
+ * are harmless.
+ */
+
+int __init cpuset_init_early(void)
+{
+	struct task_struct *tsk = current;
+
+	tsk->cpuset = &top_cpuset;
+	tsk->cpuset->mems_generation = atomic_read(&cpuset_mems_generation);
+	return 0;
+}
+
 /**
  * cpuset_init - initialize cpusets at system boot
  *
@@ -1546,6 +1885,7 @@
 	top_cpuset.cpus_allowed = CPU_MASK_ALL;
 	top_cpuset.mems_allowed = NODE_MASK_ALL;
 
+	fmeter_init(&top_cpuset.fmeter);
 	atomic_inc(&cpuset_mems_generation);
 	top_cpuset.mems_generation = atomic_read(&cpuset_mems_generation);
 
@@ -1566,7 +1906,11 @@
 	root->d_inode->i_nlink++;
 	top_cpuset.dentry = root;
 	root->d_inode->i_op = &cpuset_dir_inode_operations;
+	number_of_cpusets = 1;
 	err = cpuset_populate_dir(root);
+	/* memory_pressure_enabled is in root cpuset only */
+	if (err == 0)
+		err = cpuset_add_file(root, &cft_memory_pressure_enabled);
 out:
 	return err;
 }
@@ -1632,15 +1976,13 @@
  *
  * We don't need to task_lock() this reference to tsk->cpuset,
  * because tsk is already marked PF_EXITING, so attach_task() won't
- * mess with it.
+ * mess with it, or task is a failed fork, never visible to attach_task.
  **/
 
 void cpuset_exit(struct task_struct *tsk)
 {
 	struct cpuset *cs;
 
-	BUG_ON(!(tsk->flags & PF_EXITING));
-
 	cs = tsk->cpuset;
 	tsk->cpuset = NULL;
 
@@ -1667,14 +2009,14 @@
  * tasks cpuset.
  **/
 
-cpumask_t cpuset_cpus_allowed(const struct task_struct *tsk)
+cpumask_t cpuset_cpus_allowed(struct task_struct *tsk)
 {
 	cpumask_t mask;
 
 	down(&callback_sem);
-	task_lock((struct task_struct *)tsk);
+	task_lock(tsk);
 	guarantee_online_cpus(tsk->cpuset, &mask);
-	task_unlock((struct task_struct *)tsk);
+	task_unlock(tsk);
 	up(&callback_sem);
 
 	return mask;
@@ -1686,43 +2028,26 @@
 }
 
 /**
- * cpuset_update_current_mems_allowed - update mems parameters to new values
+ * cpuset_mems_allowed - return mems_allowed mask from a tasks cpuset.
+ * @tsk: pointer to task_struct from which to obtain cpuset->mems_allowed.
  *
- * If the current tasks cpusets mems_allowed changed behind our backs,
- * update current->mems_allowed and mems_generation to the new value.
- * Do not call this routine if in_interrupt().
- *
- * Call without callback_sem or task_lock() held.  May be called
- * with or without manage_sem held.  Unless exiting, it will acquire
- * task_lock().  Also might acquire callback_sem during call to
- * refresh_mems().
- */
+ * Description: Returns the nodemask_t mems_allowed of the cpuset
+ * attached to the specified @tsk.  Guaranteed to return some non-empty
+ * subset of node_online_map, even if this means going outside the
+ * tasks cpuset.
+ **/
 
-void cpuset_update_current_mems_allowed(void)
+nodemask_t cpuset_mems_allowed(struct task_struct *tsk)
 {
-	struct cpuset *cs;
-	int need_to_refresh = 0;
+	nodemask_t mask;
 
-	task_lock(current);
-	cs = current->cpuset;
-	if (!cs)
-		goto done;
-	if (current->cpuset_mems_generation != cs->mems_generation)
-		need_to_refresh = 1;
-done:
-	task_unlock(current);
-	if (need_to_refresh)
-		refresh_mems();
-}
+	down(&callback_sem);
+	task_lock(tsk);
+	guarantee_online_mems(tsk->cpuset, &mask);
+	task_unlock(tsk);
+	up(&callback_sem);
 
-/**
- * cpuset_restrict_to_mems_allowed - limit nodes to current mems_allowed
- * @nodes: pointer to a node bitmap that is and-ed with mems_allowed
- */
-void cpuset_restrict_to_mems_allowed(unsigned long *nodes)
-{
-	bitmap_and(nodes, nodes, nodes_addr(current->mems_allowed),
-							MAX_NUMNODES);
+	return mask;
 }
 
 /**
@@ -1795,7 +2120,7 @@
  *	GFP_USER     - only nodes in current tasks mems allowed ok.
  **/
 
-int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
+int __cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
 {
 	int node;			/* node that zone z is on */
 	const struct cpuset *cs;	/* current cpuset ancestors */
@@ -1867,6 +2192,42 @@
 }
 
 /*
+ * Collection of memory_pressure is suppressed unless
+ * this flag is enabled by writing "1" to the special
+ * cpuset file 'memory_pressure_enabled' in the root cpuset.
+ */
+
+int cpuset_memory_pressure_enabled __read_mostly;
+
+/**
+ * cpuset_memory_pressure_bump - keep stats of per-cpuset reclaims.
+ *
+ * Keep a running average of the rate of synchronous (direct)
+ * page reclaim efforts initiated by tasks in each cpuset.
+ *
+ * This represents the rate at which some task in the cpuset
+ * ran low on memory on all nodes it was allowed to use, and
+ * had to enter the kernels page reclaim code in an effort to
+ * create more free memory by tossing clean pages or swapping
+ * or writing dirty pages.
+ *
+ * Display to user space in the per-cpuset read-only file
+ * "memory_pressure".  Value displayed is an integer
+ * representing the recent rate of entry into the synchronous
+ * (direct) page reclaim by any task attached to the cpuset.
+ **/
+
+void __cpuset_memory_pressure_bump(void)
+{
+	struct cpuset *cs;
+
+	task_lock(current);
+	cs = current->cpuset;
+	fmeter_markevent(&cs->fmeter);
+	task_unlock(current);
+}
+
+/*
  * proc_cpuset_show()
  *  - Print tasks cpuset path into seq_file.
  *  - Used for /proc/<pid>/cpuset.
diff --git a/kernel/exit.c b/kernel/exit.c
index ee51568..caceabf 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -72,7 +72,6 @@
 		__ptrace_unlink(p);
 	BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
 	__exit_signal(p);
-	__exit_sighand(p);
 	/*
 	 * Note that the fastpath in sys_times depends on __exit_signal having
 	 * updated the counters before a task is removed from the tasklist of
@@ -258,7 +257,7 @@
 
 void __set_special_pids(pid_t session, pid_t pgrp)
 {
-	struct task_struct *curr = current;
+	struct task_struct *curr = current->group_leader;
 
 	if (curr->signal->session != session) {
 		detach_pid(curr, PIDTYPE_SID);
@@ -926,7 +925,6 @@
 			/* Another thread got here before we took the lock.  */
 			exit_code = sig->group_exit_code;
 		else {
-			sig->flags = SIGNAL_GROUP_EXIT;
 			sig->group_exit_code = exit_code;
 			zap_other_threads(current);
 		}
diff --git a/kernel/fork.c b/kernel/fork.c
index 1c1cf8d..72e3252 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -743,6 +743,14 @@
 
 EXPORT_SYMBOL(unshare_files);
 
+void sighand_free_cb(struct rcu_head *rhp)
+{
+	struct sighand_struct *sp;
+
+	sp = container_of(rhp, struct sighand_struct, rcu);
+	kmem_cache_free(sighand_cachep, sp);
+}
+
 static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
 {
 	struct sighand_struct *sig;
@@ -752,7 +760,7 @@
 		return 0;
 	}
 	sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
-	tsk->sighand = sig;
+	rcu_assign_pointer(tsk->sighand, sig);
 	if (!sig)
 		return -ENOMEM;
 	spin_lock_init(&sig->siglock);
@@ -803,9 +811,6 @@
 	sig->it_prof_expires = cputime_zero;
 	sig->it_prof_incr = cputime_zero;
 
-	sig->tty = current->signal->tty;
-	sig->pgrp = process_group(current);
-	sig->session = current->signal->session;
 	sig->leader = 0;	/* session leadership doesn't inherit */
 	sig->tty_old_pgrp = 0;
 
@@ -964,12 +969,13 @@
 	p->io_context = NULL;
 	p->io_wait = NULL;
 	p->audit_context = NULL;
+	cpuset_fork(p);
 #ifdef CONFIG_NUMA
  	p->mempolicy = mpol_copy(p->mempolicy);
  	if (IS_ERR(p->mempolicy)) {
  		retval = PTR_ERR(p->mempolicy);
  		p->mempolicy = NULL;
- 		goto bad_fork_cleanup;
+ 		goto bad_fork_cleanup_cpuset;
  	}
 #endif
 
@@ -1124,29 +1130,22 @@
 	if (unlikely(p->ptrace & PT_PTRACED))
 		__ptrace_link(p, current->parent);
 
-	cpuset_fork(p);
-
 	attach_pid(p, PIDTYPE_PID, p->pid);
 	attach_pid(p, PIDTYPE_TGID, p->tgid);
 	if (thread_group_leader(p)) {
+		p->signal->tty = current->signal->tty;
+		p->signal->pgrp = process_group(current);
+		p->signal->session = current->signal->session;
 		attach_pid(p, PIDTYPE_PGID, process_group(p));
 		attach_pid(p, PIDTYPE_SID, p->signal->session);
 		if (p->pid)
 			__get_cpu_var(process_counts)++;
 	}
 
-	proc_fork_connector(p);
-	if (!current->signal->tty && p->signal->tty)
-		p->signal->tty = NULL;
-
 	nr_threads++;
 	total_forks++;
 	write_unlock_irq(&tasklist_lock);
-	retval = 0;
-
-fork_out:
-	if (retval)
-		return ERR_PTR(retval);
+	proc_fork_connector(p);
 	return p;
 
 bad_fork_cleanup_namespace:
@@ -1173,7 +1172,9 @@
 bad_fork_cleanup_policy:
 #ifdef CONFIG_NUMA
 	mpol_free(p->mempolicy);
+bad_fork_cleanup_cpuset:
 #endif
+	cpuset_exit(p);
 bad_fork_cleanup:
 	if (p->binfmt)
 		module_put(p->binfmt->module);
@@ -1185,7 +1186,8 @@
 	free_uid(p->user);
 bad_fork_free:
 	free_task(p);
-	goto fork_out;
+fork_out:
+	return ERR_PTR(retval);
 }
 
 struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs)
diff --git a/kernel/futex.c b/kernel/futex.c
index 5872e35..5efa2f9 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -270,7 +270,13 @@
 	/*
 	 * The waiting task can free the futex_q as soon as this is written,
 	 * without taking any locks.  This must come last.
+	 *
+	 * A memory barrier is required here to prevent the following store
+	 * to lock_ptr from getting ahead of the wakeup. Clearing the lock
+	 * at the end of wake_up_all() does not prevent this store from
+	 * moving.
 	 */
+	wmb();
 	q->lock_ptr = NULL;
 }
 
@@ -350,6 +356,13 @@
 		if (bh1 != bh2)
 			spin_unlock(&bh2->lock);
 
+#ifndef CONFIG_MMU
+		/* we don't get EFAULT from MMU faults if we don't have an MMU,
+		 * but we might get them from range checking */
+		ret = op_ret;
+		goto out;
+#endif
+
 		if (unlikely(op_ret != -EFAULT)) {
 			ret = op_ret;
 			goto out;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 81c49a4..97d5559 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -366,6 +366,8 @@
 	action->next = NULL;
 	action->dev_id = dev_id;
 
+	select_smp_affinity(irq);
+
 	retval = setup_irq(irq, action);
 	if (retval)
 		kfree(action);
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index f26e534..d03b5ee 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -10,6 +10,8 @@
 #include <linux/proc_fs.h>
 #include <linux/interrupt.h>
 
+#include "internals.h"
+
 static struct proc_dir_entry *root_irq_dir, *irq_dir[NR_IRQS];
 
 #ifdef CONFIG_SMP
@@ -68,7 +70,9 @@
 	 */
 	cpus_and(tmp, new_value, cpu_online_map);
 	if (cpus_empty(tmp))
-		return -EINVAL;
+		/* Special case for empty set - allow the architecture
+		   code to set default SMP affinity. */
+		return select_smp_affinity(irq) ? -EINVAL : full_count;
 
 	proc_set_irq_affinity(irq, new_value);
 
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 5beda37..3bb71e6 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -246,6 +246,19 @@
 	return ret;
 }
 
+/* Walks the list and increments nmissed count for multiprobe case */
+void __kprobes kprobes_inc_nmissed_count(struct kprobe *p)
+{
+	struct kprobe *kp;
+	if (p->pre_handler != aggr_pre_handler) {
+		p->nmissed++;
+	} else {
+		list_for_each_entry_rcu(kp, &p->list, list)
+			kp->nmissed++;
+	}
+	return;
+}
+
 /* Called with kretprobe_lock held */
 struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
 {
@@ -399,10 +412,7 @@
 	INIT_LIST_HEAD(&ap->list);
 	list_add_rcu(&p->list, &ap->list);
 
-	INIT_HLIST_NODE(&ap->hlist);
-	hlist_del_rcu(&p->hlist);
-	hlist_add_head_rcu(&ap->hlist,
-		&kprobe_table[hash_ptr(ap->addr, KPROBE_HASH_BITS)]);
+	hlist_replace_rcu(&p->hlist, &ap->hlist);
 }
 
 /*
@@ -462,9 +472,16 @@
 	int ret = 0;
 	unsigned long flags = 0;
 	struct kprobe *old_p;
+	struct module *mod;
 
-	if ((ret = in_kprobes_functions((unsigned long) p->addr)) != 0)
-		return ret;
+	if ((!kernel_text_address((unsigned long) p->addr)) ||
+		in_kprobes_functions((unsigned long) p->addr))
+		return -EINVAL;
+
+	if ((mod = module_text_address((unsigned long) p->addr)) &&
+			(unlikely(!try_module_get(mod))))
+		return -EINVAL;
+
 	if ((ret = arch_prepare_kprobe(p)) != 0)
 		goto rm_kprobe;
 
@@ -488,6 +505,8 @@
 rm_kprobe:
 	if (ret == -EEXIST)
 		arch_remove_kprobe(p);
+	if (ret && mod)
+		module_put(mod);
 	return ret;
 }
 
@@ -495,6 +514,7 @@
 {
 	unsigned long flags;
 	struct kprobe *old_p;
+	struct module *mod;
 
 	spin_lock_irqsave(&kprobe_lock, flags);
 	old_p = get_kprobe(p->addr);
@@ -506,6 +526,10 @@
 			cleanup_kprobe(p, flags);
 
 		synchronize_sched();
+
+		if ((mod = module_text_address((unsigned long)p->addr)))
+			module_put(mod);
+
 		if (old_p->pre_handler == aggr_pre_handler &&
 				list_empty(&old_p->list))
 			kfree(old_p);
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 015fb69..99af8b0 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -15,6 +15,9 @@
 #include <linux/module.h>
 #include <linux/init.h>
 
+u64 uevent_seqnum;
+char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
+
 #define KERNEL_ATTR_RO(_name) \
 static struct subsys_attribute _name##_attr = __ATTR_RO(_name)
 
@@ -23,11 +26,29 @@
 	__ATTR(_name, 0644, _name##_show, _name##_store)
 
 #ifdef CONFIG_HOTPLUG
-static ssize_t hotplug_seqnum_show(struct subsystem *subsys, char *page)
+/* current uevent sequence number */
+static ssize_t uevent_seqnum_show(struct subsystem *subsys, char *page)
 {
-	return sprintf(page, "%llu\n", (unsigned long long)hotplug_seqnum);
+	return sprintf(page, "%llu\n", (unsigned long long)uevent_seqnum);
 }
-KERNEL_ATTR_RO(hotplug_seqnum);
+KERNEL_ATTR_RO(uevent_seqnum);
+
+/* uevent helper program, used during early boo */
+static ssize_t uevent_helper_show(struct subsystem *subsys, char *page)
+{
+	return sprintf(page, "%s\n", uevent_helper);
+}
+static ssize_t uevent_helper_store(struct subsystem *subsys, const char *page, size_t count)
+{
+	if (count+1 > UEVENT_HELPER_PATH_LEN)
+		return -ENOENT;
+	memcpy(uevent_helper, page, count);
+	uevent_helper[count] = '\0';
+	if (count && uevent_helper[count-1] == '\n')
+		uevent_helper[count-1] = '\0';
+	return count;
+}
+KERNEL_ATTR_RW(uevent_helper);
 #endif
 
 #ifdef CONFIG_KEXEC
@@ -45,7 +66,8 @@
 
 static struct attribute * kernel_attrs[] = {
 #ifdef CONFIG_HOTPLUG
-	&hotplug_seqnum_attr.attr,
+	&uevent_seqnum_attr.attr,
+	&uevent_helper_attr.attr,
 #endif
 #ifdef CONFIG_KEXEC
 	&crash_notes_attr.attr,
diff --git a/kernel/module.c b/kernel/module.c
index 2ea929d..e427604 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -496,15 +496,15 @@
 }
 
 #ifdef CONFIG_MODULE_FORCE_UNLOAD
-static inline int try_force(unsigned int flags)
+static inline int try_force_unload(unsigned int flags)
 {
 	int ret = (flags & O_TRUNC);
 	if (ret)
-		add_taint(TAINT_FORCED_MODULE);
+		add_taint(TAINT_FORCED_RMMOD);
 	return ret;
 }
 #else
-static inline int try_force(unsigned int flags)
+static inline int try_force_unload(unsigned int flags)
 {
 	return 0;
 }
@@ -524,7 +524,7 @@
 
 	/* If it's not unused, quit unless we are told to block. */
 	if ((sref->flags & O_NONBLOCK) && module_refcount(sref->mod) != 0) {
-		if (!(*sref->forced = try_force(sref->flags)))
+		if (!(*sref->forced = try_force_unload(sref->flags)))
 			return -EWOULDBLOCK;
 	}
 
@@ -609,7 +609,7 @@
 	/* If it has an init func, it must have an exit func to unload */
 	if ((mod->init != NULL && mod->exit == NULL)
 	    || mod->unsafe) {
-		forced = try_force(flags);
+		forced = try_force_unload(flags);
 		if (!forced) {
 			/* This module can't be removed */
 			ret = -EBUSY;
@@ -958,7 +958,6 @@
 	unsigned long ret;
 	const unsigned long *crc;
 
-	spin_lock_irq(&modlist_lock);
 	ret = __find_symbol(name, &owner, &crc, mod->license_gplok);
 	if (ret) {
 		/* use_module can fail due to OOM, or module unloading */
@@ -966,7 +965,6 @@
 		    !use_module(mod, owner))
 			ret = 0;
 	}
-	spin_unlock_irq(&modlist_lock);
 	return ret;
 }
 
@@ -1204,6 +1202,39 @@
 }
 EXPORT_SYMBOL_GPL(__symbol_get);
 
+/*
+ * Ensure that an exported symbol [global namespace] does not already exist
+ * in the Kernel or in some other modules exported symbol table.
+ */
+static int verify_export_symbols(struct module *mod)
+{
+	const char *name = NULL;
+	unsigned long i, ret = 0;
+	struct module *owner;
+	const unsigned long *crc;
+
+	for (i = 0; i < mod->num_syms; i++)
+	        if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) {
+			name = mod->syms[i].name;
+			ret = -ENOEXEC;
+			goto dup;
+		}
+
+	for (i = 0; i < mod->num_gpl_syms; i++)
+	        if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) {
+			name = mod->gpl_syms[i].name;
+			ret = -ENOEXEC;
+			goto dup;
+		}
+
+dup:
+	if (ret)
+		printk(KERN_ERR "%s: exports duplicate symbol %s (owned by %s)\n",
+			mod->name, name, module_name(owner));
+
+	return ret;
+}
+
 /* Change all symbols so that sh_value encodes the pointer directly. */
 static int simplify_symbols(Elf_Shdr *sechdrs,
 			    unsigned int symindex,
@@ -1715,6 +1746,11 @@
 	/* Set up license info based on the info section */
 	set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
 
+	if (strcmp(mod->name, "ndiswrapper") == 0)
+		add_taint(TAINT_PROPRIETARY_MODULE);
+	if (strcmp(mod->name, "driverloader") == 0)
+		add_taint(TAINT_PROPRIETARY_MODULE);
+
 #ifdef CONFIG_MODULE_UNLOAD
 	/* Set up MODINFO_ATTR fields */
 	setup_modinfo(mod, sechdrs, infoindex);
@@ -1767,6 +1803,12 @@
 			goto cleanup;
 	}
 
+        /* Find duplicate symbols */
+	err = verify_export_symbols(mod);
+
+	if (err < 0)
+		goto cleanup;
+
   	/* Set up and sort exception table */
 	mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
 	mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
@@ -1854,8 +1896,7 @@
 	kfree(args);
  free_hdr:
 	vfree(hdr);
-	if (err < 0) return ERR_PTR(err);
-	else return ptr;
+	return ERR_PTR(err);
 
  truncated:
 	printk(KERN_ERR "Module len %lu truncated\n", len);
diff --git a/kernel/panic.c b/kernel/panic.c
index aabc5f8..c5c4ab2 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -60,7 +60,7 @@
 	long i;
 	static char buf[1024];
 	va_list args;
-#if defined(CONFIG_ARCH_S390)
+#if defined(CONFIG_S390)
         unsigned long caller = (unsigned long) __builtin_return_address(0);
 #endif
 
@@ -125,7 +125,7 @@
 		printk(KERN_EMERG "Press Stop-A (L1-A) to return to the boot prom\n");
 	}
 #endif
-#if defined(CONFIG_ARCH_S390)
+#if defined(CONFIG_S390)
         disabled_wait(caller);
 #endif
 	local_irq_enable();
diff --git a/kernel/params.c b/kernel/params.c
index 47ba695..c76ad25 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -619,7 +619,7 @@
 
 
 /* module-related sysfs stuff */
-#ifdef CONFIG_MODULES
+#ifdef CONFIG_SYSFS
 
 #define to_module_attr(n) container_of(n, struct module_attribute, attr);
 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
diff --git a/kernel/pid.c b/kernel/pid.c
index edba31c..1acc072 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -136,7 +136,7 @@
 	struct hlist_node *elem;
 	struct pid *pid;
 
-	hlist_for_each_entry(pid, elem,
+	hlist_for_each_entry_rcu(pid, elem,
 			&pid_hash[type][pid_hashfn(nr)], pid_chain) {
 		if (pid->nr == nr)
 			return pid;
@@ -150,15 +150,15 @@
 
 	task_pid = &task->pids[type];
 	pid = find_pid(type, nr);
+	task_pid->nr = nr;
 	if (pid == NULL) {
-		hlist_add_head(&task_pid->pid_chain,
-				&pid_hash[type][pid_hashfn(nr)]);
 		INIT_LIST_HEAD(&task_pid->pid_list);
+		hlist_add_head_rcu(&task_pid->pid_chain,
+				   &pid_hash[type][pid_hashfn(nr)]);
 	} else {
 		INIT_HLIST_NODE(&task_pid->pid_chain);
-		list_add_tail(&task_pid->pid_list, &pid->pid_list);
+		list_add_tail_rcu(&task_pid->pid_list, &pid->pid_list);
 	}
-	task_pid->nr = nr;
 
 	return 0;
 }
@@ -170,20 +170,20 @@
 
 	pid = &task->pids[type];
 	if (!hlist_unhashed(&pid->pid_chain)) {
-		hlist_del(&pid->pid_chain);
 
-		if (list_empty(&pid->pid_list))
+		if (list_empty(&pid->pid_list)) {
 			nr = pid->nr;
-		else {
+			hlist_del_rcu(&pid->pid_chain);
+		} else {
 			pid_next = list_entry(pid->pid_list.next,
 						struct pid, pid_list);
 			/* insert next pid from pid_list to hash */
-			hlist_add_head(&pid_next->pid_chain,
-				&pid_hash[type][pid_hashfn(pid_next->nr)]);
+			hlist_replace_rcu(&pid->pid_chain,
+					  &pid_next->pid_chain);
 		}
 	}
 
-	list_del(&pid->pid_list);
+	list_del_rcu(&pid->pid_list);
 	pid->nr = 0;
 
 	return nr;
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 84af54c..4c68edf 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -36,7 +36,7 @@
 	union cpu_time_count ret;
 	ret.sched = 0;		/* high half always zero when .cpu used */
 	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) {
-		ret.sched = tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec;
+		ret.sched = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec;
 	} else {
 		ret.cpu = timespec_to_cputime(tp);
 	}
@@ -238,18 +238,7 @@
 		while ((t = next_thread(t)) != p) {
 			cpu->sched += t->sched_time;
 		}
-		if (p->tgid == current->tgid) {
-			/*
-			 * We're sampling ourselves, so include the
-			 * cycles not yet banked.  We still omit
-			 * other threads running on other CPUs,
-			 * so the total can always be behind as
-			 * much as max(nthreads-1,ncpus) * (NSEC_PER_SEC/HZ).
-			 */
-			cpu->sched += current_sched_time(current);
-		} else {
-			cpu->sched += p->sched_time;
-		}
+		cpu->sched += sched_ns(p);
 		break;
 	}
 	return 0;
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index 027322a..e24446f 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -24,10 +24,11 @@
 
 extern suspend_disk_method_t pm_disk_mode;
 
+extern int swsusp_shrink_memory(void);
 extern int swsusp_suspend(void);
-extern int swsusp_write(void);
+extern int swsusp_write(struct pbe *pblist, unsigned int nr_pages);
 extern int swsusp_check(void);
-extern int swsusp_read(void);
+extern int swsusp_read(struct pbe **pblist_ptr);
 extern void swsusp_close(void);
 extern int swsusp_resume(void);
 
@@ -73,31 +74,6 @@
 static int in_suspend __nosavedata = 0;
 
 
-/**
- *	free_some_memory -  Try to free as much memory as possible
- *
- *	... but do not OOM-kill anyone
- *
- *	Notice: all userland should be stopped at this point, or
- *	livelock is possible.
- */
-
-static void free_some_memory(void)
-{
-	unsigned int i = 0;
-	unsigned int tmp;
-	unsigned long pages = 0;
-	char *p = "-\\|/";
-
-	printk("Freeing memory...  ");
-	while ((tmp = shrink_all_memory(10000))) {
-		pages += tmp;
-		printk("\b%c", p[i++ % 4]);
-	}
-	printk("\bdone (%li pages freed)\n", pages);
-}
-
-
 static inline void platform_finish(void)
 {
 	if (pm_disk_mode == PM_DISK_PLATFORM) {
@@ -127,8 +103,8 @@
 	}
 
 	/* Free memory before shutting down devices. */
-	free_some_memory();
-	return 0;
+	if (!(error = swsusp_shrink_memory()))
+		return 0;
 thaw:
 	thaw_processes();
 	enable_nonboot_cpus();
@@ -176,7 +152,7 @@
 	if (in_suspend) {
 		device_resume();
 		pr_debug("PM: writing image.\n");
-		error = swsusp_write();
+		error = swsusp_write(pagedir_nosave, nr_copy_pages);
 		if (!error)
 			power_down(pm_disk_mode);
 		else {
@@ -247,7 +223,7 @@
 
 	pr_debug("PM: Reading swsusp image.\n");
 
-	if ((error = swsusp_read())) {
+	if ((error = swsusp_read(&pagedir_nosave))) {
 		swsusp_free();
 		goto Thaw;
 	}
@@ -363,37 +339,55 @@
 		       MINOR(swsusp_resume_device));
 }
 
-static ssize_t resume_store(struct subsystem * subsys, const char * buf, size_t n)
+static ssize_t resume_store(struct subsystem *subsys, const char *buf, size_t n)
 {
-	int len;
-	char *p;
 	unsigned int maj, min;
-	int error = -EINVAL;
 	dev_t res;
+	int ret = -EINVAL;
 
-	p = memchr(buf, '\n', n);
-	len = p ? p - buf : n;
+	if (sscanf(buf, "%u:%u", &maj, &min) != 2)
+		goto out;
 
-	if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
-		res = MKDEV(maj,min);
-		if (maj == MAJOR(res) && min == MINOR(res)) {
-			down(&pm_sem);
-			swsusp_resume_device = res;
-			up(&pm_sem);
-			printk("Attempting manual resume\n");
-			noresume = 0;
-			software_resume();
-		}
-	}
+	res = MKDEV(maj,min);
+	if (maj != MAJOR(res) || min != MINOR(res))
+		goto out;
 
-	return error >= 0 ? n : error;
+	down(&pm_sem);
+	swsusp_resume_device = res;
+	up(&pm_sem);
+	printk("Attempting manual resume\n");
+	noresume = 0;
+	software_resume();
+	ret = n;
+out:
+	return ret;
 }
 
 power_attr(resume);
 
+static ssize_t image_size_show(struct subsystem * subsys, char *buf)
+{
+	return sprintf(buf, "%u\n", image_size);
+}
+
+static ssize_t image_size_store(struct subsystem * subsys, const char * buf, size_t n)
+{
+	unsigned int size;
+
+	if (sscanf(buf, "%u", &size) == 1) {
+		image_size = size;
+		return n;
+	}
+
+	return -EINVAL;
+}
+
+power_attr(image_size);
+
 static struct attribute * g[] = {
 	&disk_attr.attr,
 	&resume_attr.attr,
+	&image_size_attr.attr,
 	NULL,
 };
 
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 6ee2cad..d253f3a 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -24,7 +24,7 @@
 
 DECLARE_MUTEX(pm_sem);
 
-struct pm_ops * pm_ops = NULL;
+struct pm_ops *pm_ops;
 suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN;
 
 /**
@@ -151,6 +151,18 @@
 #endif
 };
 
+static inline int valid_state(suspend_state_t state)
+{
+	/* Suspend-to-disk does not really need low-level support.
+	 * It can work with reboot if needed. */
+	if (state == PM_SUSPEND_DISK)
+		return 1;
+
+	if (pm_ops && pm_ops->valid && !pm_ops->valid(state))
+		return 0;
+	return 1;
+}
+
 
 /**
  *	enter_state - Do common work of entering low-power state.
@@ -167,7 +179,7 @@
 {
 	int error;
 
-	if (pm_ops && pm_ops->valid && !pm_ops->valid(state))
+	if (!valid_state(state))
 		return -ENODEV;
 	if (down_trylock(&pm_sem))
 		return -EBUSY;
@@ -238,9 +250,8 @@
 	char * s = buf;
 
 	for (i = 0; i < PM_SUSPEND_MAX; i++) {
-		if (pm_states[i] && pm_ops && (!pm_ops->valid
-			||(pm_ops->valid && pm_ops->valid(i))))
-			s += sprintf(s,"%s ",pm_states[i]);
+		if (pm_states[i] && valid_state(i))
+			s += sprintf(s,"%s ", pm_states[i]);
 	}
 	s += sprintf(s,"\n");
 	return (s - buf);
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 6c042b5..7e8492f 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -9,19 +9,13 @@
 #define SUSPEND_CONSOLE	(MAX_NR_CONSOLES-1)
 #endif
 
-#define MAX_PBES	((PAGE_SIZE - sizeof(struct new_utsname) \
-			- 4 - 3*sizeof(unsigned long) - sizeof(int) \
-			- sizeof(void *)) / sizeof(swp_entry_t))
-
 struct swsusp_info {
 	struct new_utsname	uts;
 	u32			version_code;
 	unsigned long		num_physpages;
 	int			cpus;
 	unsigned long		image_pages;
-	unsigned long		pagedir_pages;
-	suspend_pagedir_t	* suspend_pagedir;
-	swp_entry_t		pagedir[MAX_PBES];
+	unsigned long		pages;
 } __attribute__((aligned(PAGE_SIZE)));
 
 
@@ -48,25 +42,27 @@
 
 extern struct subsystem power_subsys;
 
-extern int freeze_processes(void);
-extern void thaw_processes(void);
-
 extern int pm_prepare_console(void);
 extern void pm_restore_console(void);
 
-
 /* References to section boundaries */
 extern const void __nosave_begin, __nosave_end;
 
 extern unsigned int nr_copy_pages;
-extern suspend_pagedir_t *pagedir_nosave;
-extern suspend_pagedir_t *pagedir_save;
+extern struct pbe *pagedir_nosave;
+
+/* Preferred image size in MB (default 500) */
+extern unsigned int image_size;
 
 extern asmlinkage int swsusp_arch_suspend(void);
 extern asmlinkage int swsusp_arch_resume(void);
 
+extern unsigned int count_data_pages(void);
 extern void free_pagedir(struct pbe *pblist);
+extern void release_eaten_pages(void);
 extern struct pbe *alloc_pagedir(unsigned nr_pages, gfp_t gfp_mask, int safe_needed);
-extern void create_pbe_list(struct pbe *pblist, unsigned nr_pages);
 extern void swsusp_free(void);
 extern int alloc_data_pages(struct pbe *pblist, gfp_t gfp_mask, int safe_needed);
+extern unsigned int snapshot_nr_pages(void);
+extern struct pbe *snapshot_pblist(void);
+extern void snapshot_pblist_set(struct pbe *pblist);
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 4a6dbce..41f6636 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -33,7 +33,35 @@
 
 #include "power.h"
 
+struct pbe *pagedir_nosave;
+unsigned int nr_copy_pages;
+
 #ifdef CONFIG_HIGHMEM
+unsigned int count_highmem_pages(void)
+{
+	struct zone *zone;
+	unsigned long zone_pfn;
+	unsigned int n = 0;
+
+	for_each_zone (zone)
+		if (is_highmem(zone)) {
+			mark_free_pages(zone);
+			for (zone_pfn = 0; zone_pfn < zone->spanned_pages; zone_pfn++) {
+				struct page *page;
+				unsigned long pfn = zone_pfn + zone->zone_start_pfn;
+				if (!pfn_valid(pfn))
+					continue;
+				page = pfn_to_page(pfn);
+				if (PageReserved(page))
+					continue;
+				if (PageNosaveFree(page))
+					continue;
+				n++;
+			}
+		}
+	return n;
+}
+
 struct highmem_page {
 	char *data;
 	struct page *page;
@@ -149,17 +177,15 @@
 	BUG_ON(PageReserved(page) && PageNosave(page));
 	if (PageNosave(page))
 		return 0;
-	if (PageReserved(page) && pfn_is_nosave(pfn)) {
-		pr_debug("[nosave pfn 0x%lx]", pfn);
+	if (PageReserved(page) && pfn_is_nosave(pfn))
 		return 0;
-	}
 	if (PageNosaveFree(page))
 		return 0;
 
 	return 1;
 }
 
-static unsigned count_data_pages(void)
+unsigned int count_data_pages(void)
 {
 	struct zone *zone;
 	unsigned long zone_pfn;
@@ -244,7 +270,7 @@
  *	of memory pages allocated with alloc_pagedir()
  */
 
-void create_pbe_list(struct pbe *pblist, unsigned int nr_pages)
+static inline void create_pbe_list(struct pbe *pblist, unsigned int nr_pages)
 {
 	struct pbe *pbpage, *p;
 	unsigned int num = PBES_PER_PAGE;
@@ -261,7 +287,35 @@
 			p->next = p + 1;
 		p->next = NULL;
 	}
-	pr_debug("create_pbe_list(): initialized %d PBEs\n", num);
+}
+
+/**
+ *	On resume it is necessary to trace and eventually free the unsafe
+ *	pages that have been allocated, because they are needed for I/O
+ *	(on x86-64 we likely will "eat" these pages once again while
+ *	creating the temporary page translation tables)
+ */
+
+struct eaten_page {
+	struct eaten_page *next;
+	char padding[PAGE_SIZE - sizeof(void *)];
+};
+
+static struct eaten_page *eaten_pages = NULL;
+
+void release_eaten_pages(void)
+{
+	struct eaten_page *p, *q;
+
+	p = eaten_pages;
+	while (p) {
+		q = p->next;
+		/* We don't want swsusp_free() to free this page again */
+		ClearPageNosave(virt_to_page(p));
+		free_page((unsigned long)p);
+		p = q;
+	}
+	eaten_pages = NULL;
 }
 
 /**
@@ -282,9 +336,12 @@
 	if (safe_needed)
 		do {
 			res = (void *)get_zeroed_page(gfp_mask);
-			if (res && PageNosaveFree(virt_to_page(res)))
+			if (res && PageNosaveFree(virt_to_page(res))) {
 				/* This is for swsusp_free() */
 				SetPageNosave(virt_to_page(res));
+				((struct eaten_page *)res)->next = eaten_pages;
+				eaten_pages = res;
+			}
 		} while (res && PageNosaveFree(virt_to_page(res)));
 	else
 		res = (void *)get_zeroed_page(gfp_mask);
@@ -332,7 +389,8 @@
 	if (!pbe) { /* get_zeroed_page() failed */
 		free_pagedir(pblist);
 		pblist = NULL;
-        }
+        } else
+        	create_pbe_list(pblist, nr_pages);
 	return pblist;
 }
 
@@ -370,8 +428,14 @@
 
 static int enough_free_mem(unsigned int nr_pages)
 {
-	pr_debug("swsusp: available memory: %u pages\n", nr_free_pages());
-	return nr_free_pages() > (nr_pages + PAGES_FOR_IO +
+	struct zone *zone;
+	unsigned int n = 0;
+
+	for_each_zone (zone)
+		if (!is_highmem(zone))
+			n += zone->free_pages;
+	pr_debug("swsusp: available memory: %u pages\n", n);
+	return n > (nr_pages + PAGES_FOR_IO +
 		(nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
 }
 
@@ -395,7 +459,6 @@
 		printk(KERN_ERR "suspend: Allocating pagedir failed.\n");
 		return NULL;
 	}
-	create_pbe_list(pblist, nr_pages);
 
 	if (alloc_data_pages(pblist, GFP_ATOMIC | __GFP_COLD, 0)) {
 		printk(KERN_ERR "suspend: Allocating image pages failed.\n");
@@ -421,10 +484,6 @@
 		 (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE,
 		 PAGES_FOR_IO, nr_free_pages());
 
-	/* This is needed because of the fixed size of swsusp_info */
-	if (MAX_PBES < (nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE)
-		return -ENOSPC;
-
 	if (!enough_free_mem(nr_pages)) {
 		printk(KERN_ERR "swsusp: Not enough free memory\n");
 		return -ENOMEM;
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c
index c05f46e..55a18d2 100644
--- a/kernel/power/swsusp.c
+++ b/kernel/power/swsusp.c
@@ -30,8 +30,8 @@
  * Alex Badea <vampire@go.ro>:
  * Fixed runaway init
  *
- * Andreas Steinmetz <ast@domdv.de>:
- * Added encrypted suspend option
+ * Rafael J. Wysocki <rjw@sisk.pl>
+ * Added the swap map data structure and reworked the handling of swap
  *
  * More state savers are welcome. Especially for the scsi layer...
  *
@@ -67,44 +67,33 @@
 #include <asm/tlbflush.h>
 #include <asm/io.h>
 
-#include <linux/random.h>
-#include <linux/crypto.h>
-#include <asm/scatterlist.h>
-
 #include "power.h"
 
+/*
+ * Preferred image size in MB (tunable via /sys/power/image_size).
+ * When it is set to N, swsusp will do its best to ensure the image
+ * size will not exceed N MB, but if that is impossible, it will
+ * try to create the smallest image possible.
+ */
+unsigned int image_size = 500;
+
 #ifdef CONFIG_HIGHMEM
+unsigned int count_highmem_pages(void);
 int save_highmem(void);
 int restore_highmem(void);
 #else
 static int save_highmem(void) { return 0; }
 static int restore_highmem(void) { return 0; }
+static unsigned int count_highmem_pages(void) { return 0; }
 #endif
 
-#define CIPHER "aes"
-#define MAXKEY 32
-#define MAXIV  32
-
 extern char resume_file[];
 
-/* Local variables that should not be affected by save */
-unsigned int nr_copy_pages __nosavedata = 0;
-
-/* Suspend pagedir is allocated before final copy, therefore it
-   must be freed after resume
-
-   Warning: this is even more evil than it seems. Pagedirs this file
-   talks about are completely different from page directories used by
-   MMU hardware.
- */
-suspend_pagedir_t *pagedir_nosave __nosavedata = NULL;
-
 #define SWSUSP_SIG	"S1SUSPEND"
 
 static struct swsusp_header {
-	char reserved[PAGE_SIZE - 20 - MAXKEY - MAXIV - sizeof(swp_entry_t)];
-	u8 key_iv[MAXKEY+MAXIV];
-	swp_entry_t swsusp_info;
+	char reserved[PAGE_SIZE - 20 - sizeof(swp_entry_t)];
+	swp_entry_t image;
 	char	orig_sig[10];
 	char	sig[10];
 } __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;
@@ -115,140 +104,9 @@
  * Saving part...
  */
 
-/* We memorize in swapfile_used what swap devices are used for suspension */
-#define SWAPFILE_UNUSED    0
-#define SWAPFILE_SUSPEND   1	/* This is the suspending device */
-#define SWAPFILE_IGNORED   2	/* Those are other swap devices ignored for suspension */
+static unsigned short root_swap = 0xffff;
 
-static unsigned short swapfile_used[MAX_SWAPFILES];
-static unsigned short root_swap;
-
-static int write_page(unsigned long addr, swp_entry_t *loc);
-static int bio_read_page(pgoff_t page_off, void *page);
-
-static u8 key_iv[MAXKEY+MAXIV];
-
-#ifdef CONFIG_SWSUSP_ENCRYPT
-
-static int crypto_init(int mode, void **mem)
-{
-	int error = 0;
-	int len;
-	char *modemsg;
-	struct crypto_tfm *tfm;
-
-	modemsg = mode ? "suspend not possible" : "resume not possible";
-
-	tfm = crypto_alloc_tfm(CIPHER, CRYPTO_TFM_MODE_CBC);
-	if(!tfm) {
-		printk(KERN_ERR "swsusp: no tfm, %s\n", modemsg);
-		error = -EINVAL;
-		goto out;
-	}
-
-	if(MAXKEY < crypto_tfm_alg_min_keysize(tfm)) {
-		printk(KERN_ERR "swsusp: key buffer too small, %s\n", modemsg);
-		error = -ENOKEY;
-		goto fail;
-	}
-
-	if (mode)
-		get_random_bytes(key_iv, MAXKEY+MAXIV);
-
-	len = crypto_tfm_alg_max_keysize(tfm);
-	if (len > MAXKEY)
-		len = MAXKEY;
-
-	if (crypto_cipher_setkey(tfm, key_iv, len)) {
-		printk(KERN_ERR "swsusp: key setup failure, %s\n", modemsg);
-		error = -EKEYREJECTED;
-		goto fail;
-	}
-
-	len = crypto_tfm_alg_ivsize(tfm);
-
-	if (MAXIV < len) {
-		printk(KERN_ERR "swsusp: iv buffer too small, %s\n", modemsg);
-		error = -EOVERFLOW;
-		goto fail;
-	}
-
-	crypto_cipher_set_iv(tfm, key_iv+MAXKEY, len);
-
-	*mem=(void *)tfm;
-
-	goto out;
-
-fail:	crypto_free_tfm(tfm);
-out:	return error;
-}
-
-static __inline__ void crypto_exit(void *mem)
-{
-	crypto_free_tfm((struct crypto_tfm *)mem);
-}
-
-static __inline__ int crypto_write(struct pbe *p, void *mem)
-{
-	int error = 0;
-	struct scatterlist src, dst;
-
-	src.page   = virt_to_page(p->address);
-	src.offset = 0;
-	src.length = PAGE_SIZE;
-	dst.page   = virt_to_page((void *)&swsusp_header);
-	dst.offset = 0;
-	dst.length = PAGE_SIZE;
-
-	error = crypto_cipher_encrypt((struct crypto_tfm *)mem, &dst, &src,
-					PAGE_SIZE);
-
-	if (!error)
-		error = write_page((unsigned long)&swsusp_header,
-				&(p->swap_address));
-	return error;
-}
-
-static __inline__ int crypto_read(struct pbe *p, void *mem)
-{
-	int error = 0;
-	struct scatterlist src, dst;
-
-	error = bio_read_page(swp_offset(p->swap_address), (void *)p->address);
-	if (!error) {
-		src.offset = 0;
-		src.length = PAGE_SIZE;
-		dst.offset = 0;
-		dst.length = PAGE_SIZE;
-		src.page = dst.page = virt_to_page((void *)p->address);
-
-		error = crypto_cipher_decrypt((struct crypto_tfm *)mem, &dst,
-						&src, PAGE_SIZE);
-	}
-	return error;
-}
-#else
-static __inline__ int crypto_init(int mode, void *mem)
-{
-	return 0;
-}
-
-static __inline__ void crypto_exit(void *mem)
-{
-}
-
-static __inline__ int crypto_write(struct pbe *p, void *mem)
-{
-	return write_page(p->address, &(p->swap_address));
-}
-
-static __inline__ int crypto_read(struct pbe *p, void *mem)
-{
-	return bio_read_page(swp_offset(p->swap_address), (void *)p->address);
-}
-#endif
-
-static int mark_swapfiles(swp_entry_t prev)
+static int mark_swapfiles(swp_entry_t start)
 {
 	int error;
 
@@ -259,8 +117,7 @@
 	    !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
 		memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
 		memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
-		memcpy(swsusp_header.key_iv, key_iv, MAXKEY+MAXIV);
-		swsusp_header.swsusp_info = prev;
+		swsusp_header.image = start;
 		error = rw_swap_page_sync(WRITE,
 					  swp_entry(root_swap, 0),
 					  virt_to_page((unsigned long)
@@ -283,7 +140,7 @@
  * devfs, since the resume code can only recognize the form /dev/hda4,
  * but the suspend code would see the long name.)
  */
-static int is_resume_device(const struct swap_info_struct *swap_info)
+static inline int is_resume_device(const struct swap_info_struct *swap_info)
 {
 	struct file *file = swap_info->swap_file;
 	struct inode *inode = file->f_dentry->d_inode;
@@ -294,54 +151,22 @@
 
 static int swsusp_swap_check(void) /* This is called before saving image */
 {
-	int i, len;
+	int i;
 
-	len=strlen(resume_file);
-	root_swap = 0xFFFF;
-
+	if (!swsusp_resume_device)
+		return -ENODEV;
 	spin_lock(&swap_lock);
-	for (i=0; i<MAX_SWAPFILES; i++) {
-		if (!(swap_info[i].flags & SWP_WRITEOK)) {
-			swapfile_used[i]=SWAPFILE_UNUSED;
-		} else {
-			if (!len) {
-	    			printk(KERN_WARNING "resume= option should be used to set suspend device" );
-				if (root_swap == 0xFFFF) {
-					swapfile_used[i] = SWAPFILE_SUSPEND;
-					root_swap = i;
-				} else
-					swapfile_used[i] = SWAPFILE_IGNORED;
-			} else {
-	  			/* we ignore all swap devices that are not the resume_file */
-				if (is_resume_device(&swap_info[i])) {
-					swapfile_used[i] = SWAPFILE_SUSPEND;
-					root_swap = i;
-				} else {
-				  	swapfile_used[i] = SWAPFILE_IGNORED;
-				}
-			}
+	for (i = 0; i < MAX_SWAPFILES; i++) {
+		if (!(swap_info[i].flags & SWP_WRITEOK))
+			continue;
+		if (is_resume_device(swap_info + i)) {
+			spin_unlock(&swap_lock);
+			root_swap = i;
+			return 0;
 		}
 	}
 	spin_unlock(&swap_lock);
-	return (root_swap != 0xffff) ? 0 : -ENODEV;
-}
-
-/**
- * This is called after saving image so modification
- * will be lost after resume... and that's what we want.
- * we make the device unusable. A new call to
- * lock_swapdevices can unlock the devices.
- */
-static void lock_swapdevices(void)
-{
-	int i;
-
-	spin_lock(&swap_lock);
-	for (i = 0; i< MAX_SWAPFILES; i++)
-		if (swapfile_used[i] == SWAPFILE_IGNORED) {
-			swap_info[i].flags ^= SWP_WRITEOK;
-		}
-	spin_unlock(&swap_lock);
+	return -ENODEV;
 }
 
 /**
@@ -359,72 +184,217 @@
 static int write_page(unsigned long addr, swp_entry_t *loc)
 {
 	swp_entry_t entry;
-	int error = 0;
+	int error = -ENOSPC;
 
-	entry = get_swap_page();
-	if (swp_offset(entry) &&
-	    swapfile_used[swp_type(entry)] == SWAPFILE_SUSPEND) {
-		error = rw_swap_page_sync(WRITE, entry,
-					  virt_to_page(addr));
-		if (error == -EIO)
-			error = 0;
-		if (!error)
+	entry = get_swap_page_of_type(root_swap);
+	if (swp_offset(entry)) {
+		error = rw_swap_page_sync(WRITE, entry, virt_to_page(addr));
+		if (!error || error == -EIO)
 			*loc = entry;
-	} else
-		error = -ENOSPC;
+	}
 	return error;
 }
 
 /**
- *	data_free - Free the swap entries used by the saved image.
+ *	Swap map-handling functions
  *
- *	Walk the list of used swap entries and free each one.
- *	This is only used for cleanup when suspend fails.
+ *	The swap map is a data structure used for keeping track of each page
+ *	written to the swap.  It consists of many swap_map_page structures
+ *	that contain each an array of MAP_PAGE_SIZE swap entries.
+ *	These structures are linked together with the help of either the
+ *	.next (in memory) or the .next_swap (in swap) member.
+ *
+ *	The swap map is created during suspend.  At that time we need to keep
+ *	it in memory, because we have to free all of the allocated swap
+ *	entries if an error occurs.  The memory needed is preallocated
+ *	so that we know in advance if there's enough of it.
+ *
+ *	The first swap_map_page structure is filled with the swap entries that
+ *	correspond to the first MAP_PAGE_SIZE data pages written to swap and
+ *	so on.  After the all of the data pages have been written, the order
+ *	of the swap_map_page structures in the map is reversed so that they
+ *	can be read from swap in the original order.  This causes the data
+ *	pages to be loaded in exactly the same order in which they have been
+ *	saved.
+ *
+ *	During resume we only need to use one swap_map_page structure
+ *	at a time, which means that we only need to use two memory pages for
+ *	reading the image - one for reading the swap_map_page structures
+ *	and the second for reading the data pages from swap.
  */
-static void data_free(void)
-{
-	swp_entry_t entry;
-	struct pbe *p;
 
-	for_each_pbe (p, pagedir_nosave) {
-		entry = p->swap_address;
-		if (entry.val)
-			swap_free(entry);
-		else
-			break;
+#define MAP_PAGE_SIZE	((PAGE_SIZE - sizeof(swp_entry_t) - sizeof(void *)) \
+			/ sizeof(swp_entry_t))
+
+struct swap_map_page {
+	swp_entry_t		entries[MAP_PAGE_SIZE];
+	swp_entry_t		next_swap;
+	struct swap_map_page	*next;
+};
+
+static inline void free_swap_map(struct swap_map_page *swap_map)
+{
+	struct swap_map_page *swp;
+
+	while (swap_map) {
+		swp = swap_map->next;
+		free_page((unsigned long)swap_map);
+		swap_map = swp;
+	}
+}
+
+static struct swap_map_page *alloc_swap_map(unsigned int nr_pages)
+{
+	struct swap_map_page *swap_map, *swp;
+	unsigned n = 0;
+
+	if (!nr_pages)
+		return NULL;
+
+	pr_debug("alloc_swap_map(): nr_pages = %d\n", nr_pages);
+	swap_map = (struct swap_map_page *)get_zeroed_page(GFP_ATOMIC);
+	swp = swap_map;
+	for (n = MAP_PAGE_SIZE; n < nr_pages; n += MAP_PAGE_SIZE) {
+		swp->next = (struct swap_map_page *)get_zeroed_page(GFP_ATOMIC);
+		swp = swp->next;
+		if (!swp) {
+			free_swap_map(swap_map);
+			return NULL;
+		}
+	}
+	return swap_map;
+}
+
+/**
+ *	reverse_swap_map - reverse the order of pages in the swap map
+ *	@swap_map
+ */
+
+static inline struct swap_map_page *reverse_swap_map(struct swap_map_page *swap_map)
+{
+	struct swap_map_page *prev, *next;
+
+	prev = NULL;
+	while (swap_map) {
+		next = swap_map->next;
+		swap_map->next = prev;
+		prev = swap_map;
+		swap_map = next;
+	}
+	return prev;
+}
+
+/**
+ *	free_swap_map_entries - free the swap entries allocated to store
+ *	the swap map @swap_map (this is only called in case of an error)
+ */
+static inline void free_swap_map_entries(struct swap_map_page *swap_map)
+{
+	while (swap_map) {
+		if (swap_map->next_swap.val)
+			swap_free(swap_map->next_swap);
+		swap_map = swap_map->next;
 	}
 }
 
 /**
- *	data_write - Write saved image to swap.
- *
- *	Walk the list of pages in the image and sync each one to swap.
+ *	save_swap_map - save the swap map used for tracing the data pages
+ *	stored in the swap
  */
-static int data_write(void)
+
+static int save_swap_map(struct swap_map_page *swap_map, swp_entry_t *start)
 {
-	int error = 0, i = 0;
-	unsigned int mod = nr_copy_pages / 100;
-	struct pbe *p;
-	void *tfm;
+	swp_entry_t entry = (swp_entry_t){0};
+	int error;
 
-	if ((error = crypto_init(1, &tfm)))
-		return error;
-
-	if (!mod)
-		mod = 1;
-
-	printk( "Writing data to swap (%d pages)...     ", nr_copy_pages );
-	for_each_pbe (p, pagedir_nosave) {
-		if (!(i%mod))
-			printk( "\b\b\b\b%3d%%", i / mod );
-		if ((error = crypto_write(p, tfm))) {
-			crypto_exit(tfm);
+	while (swap_map) {
+		swap_map->next_swap = entry;
+		if ((error = write_page((unsigned long)swap_map, &entry)))
 			return error;
-		}
-		i++;
+		swap_map = swap_map->next;
 	}
-	printk("\b\b\b\bdone\n");
-	crypto_exit(tfm);
+	*start = entry;
+	return 0;
+}
+
+/**
+ *	free_image_entries - free the swap entries allocated to store
+ *	the image data pages (this is only called in case of an error)
+ */
+
+static inline void free_image_entries(struct swap_map_page *swp)
+{
+	unsigned k;
+
+	while (swp) {
+		for (k = 0; k < MAP_PAGE_SIZE; k++)
+			if (swp->entries[k].val)
+				swap_free(swp->entries[k]);
+		swp = swp->next;
+	}
+}
+
+/**
+ *	The swap_map_handle structure is used for handling the swap map in
+ *	a file-alike way
+ */
+
+struct swap_map_handle {
+	struct swap_map_page *cur;
+	unsigned int k;
+};
+
+static inline void init_swap_map_handle(struct swap_map_handle *handle,
+                                        struct swap_map_page *map)
+{
+	handle->cur = map;
+	handle->k = 0;
+}
+
+static inline int swap_map_write_page(struct swap_map_handle *handle,
+                                      unsigned long addr)
+{
+	int error;
+
+	error = write_page(addr, handle->cur->entries + handle->k);
+	if (error)
+		return error;
+	if (++handle->k >= MAP_PAGE_SIZE) {
+		handle->cur = handle->cur->next;
+		handle->k = 0;
+	}
+	return 0;
+}
+
+/**
+ *	save_image_data - save the data pages pointed to by the PBEs
+ *	from the list @pblist using the swap map handle @handle
+ *	(assume there are @nr_pages data pages to save)
+ */
+
+static int save_image_data(struct pbe *pblist,
+                           struct swap_map_handle *handle,
+                           unsigned int nr_pages)
+{
+	unsigned int m;
+	struct pbe *p;
+	int error = 0;
+
+	printk("Saving image data pages (%u pages) ...     ", nr_pages);
+	m = nr_pages / 100;
+	if (!m)
+		m = 1;
+	nr_pages = 0;
+	for_each_pbe (p, pblist) {
+		error = swap_map_write_page(handle, p->address);
+		if (error)
+			break;
+		if (!(nr_pages % m))
+			printk("\b\b\b\b%3d%%", nr_pages / m);
+		nr_pages++;
+	}
+	if (!error)
+		printk("\b\b\b\bdone\n");
 	return error;
 }
 
@@ -440,70 +410,70 @@
 	pr_debug(" swsusp: UTS Domain: %s\n",swsusp_info.uts.domainname);
 	pr_debug(" swsusp: CPUs: %d\n",swsusp_info.cpus);
 	pr_debug(" swsusp: Image: %ld Pages\n",swsusp_info.image_pages);
-	pr_debug(" swsusp: Pagedir: %ld Pages\n",swsusp_info.pagedir_pages);
+	pr_debug(" swsusp: Total: %ld Pages\n", swsusp_info.pages);
 }
 
-static void init_header(void)
+static void init_header(unsigned int nr_pages)
 {
 	memset(&swsusp_info, 0, sizeof(swsusp_info));
 	swsusp_info.version_code = LINUX_VERSION_CODE;
 	swsusp_info.num_physpages = num_physpages;
 	memcpy(&swsusp_info.uts, &system_utsname, sizeof(system_utsname));
 
-	swsusp_info.suspend_pagedir = pagedir_nosave;
 	swsusp_info.cpus = num_online_cpus();
-	swsusp_info.image_pages = nr_copy_pages;
+	swsusp_info.image_pages = nr_pages;
+	swsusp_info.pages = nr_pages +
+		((nr_pages * sizeof(long) + PAGE_SIZE - 1) >> PAGE_SHIFT) + 1;
 }
 
-static int close_swap(void)
-{
-	swp_entry_t entry;
-	int error;
+/**
+ *	pack_orig_addresses - the .orig_address fields of the PBEs from the
+ *	list starting at @pbe are stored in the array @buf[] (1 page)
+ */
 
-	dump_info();
-	error = write_page((unsigned long)&swsusp_info, &entry);
-	if (!error) {
-		printk( "S" );
-		error = mark_swapfiles(entry);
-		printk( "|\n" );
+static inline struct pbe *pack_orig_addresses(unsigned long *buf,
+                                              struct pbe *pbe)
+{
+	int j;
+
+	for (j = 0; j < PAGE_SIZE / sizeof(long) && pbe; j++) {
+		buf[j] = pbe->orig_address;
+		pbe = pbe->next;
 	}
-	return error;
+	if (!pbe)
+		for (; j < PAGE_SIZE / sizeof(long); j++)
+			buf[j] = 0;
+	return pbe;
 }
 
 /**
- *	free_pagedir_entries - Free pages used by the page directory.
- *
- *	This is used during suspend for error recovery.
+ *	save_image_metadata - save the .orig_address fields of the PBEs
+ *	from the list @pblist using the swap map handle @handle
  */
 
-static void free_pagedir_entries(void)
+static int save_image_metadata(struct pbe *pblist,
+                               struct swap_map_handle *handle)
 {
-	int i;
-
-	for (i = 0; i < swsusp_info.pagedir_pages; i++)
-		swap_free(swsusp_info.pagedir[i]);
-}
-
-
-/**
- *	write_pagedir - Write the array of pages holding the page directory.
- *	@last:	Last swap entry we write (needed for header).
- */
-
-static int write_pagedir(void)
-{
-	int error = 0;
+	unsigned long *buf;
 	unsigned int n = 0;
-	struct pbe *pbe;
+	struct pbe *p;
+	int error = 0;
 
-	printk( "Writing pagedir...");
-	for_each_pb_page (pbe, pagedir_nosave) {
-		if ((error = write_page((unsigned long)pbe, &swsusp_info.pagedir[n++])))
-			return error;
+	printk("Saving image metadata ... ");
+	buf = (unsigned long *)get_zeroed_page(GFP_ATOMIC);
+	if (!buf)
+		return -ENOMEM;
+	p = pblist;
+	while (p) {
+		p = pack_orig_addresses(buf, p);
+		error = swap_map_write_page(handle, (unsigned long)buf);
+		if (error)
+			break;
+		n++;
 	}
-
-	swsusp_info.pagedir_pages = n;
-	printk("done (%u pages)\n", n);
+	free_page((unsigned long)buf);
+	if (!error)
+		printk("done (%u pages saved)\n", n);
 	return error;
 }
 
@@ -511,76 +481,126 @@
  *	enough_swap - Make sure we have enough swap to save the image.
  *
  *	Returns TRUE or FALSE after checking the total amount of swap
- *	space avaiable.
- *
- *	FIXME: si_swapinfo(&i) returns all swap devices information.
- *	We should only consider resume_device.
+ *	space avaiable from the resume partition.
  */
 
 static int enough_swap(unsigned int nr_pages)
 {
-	struct sysinfo i;
+	unsigned int free_swap = swap_info[root_swap].pages -
+		swap_info[root_swap].inuse_pages;
 
-	si_swapinfo(&i);
-	pr_debug("swsusp: available swap: %lu pages\n", i.freeswap);
-	return i.freeswap > (nr_pages + PAGES_FOR_IO +
+	pr_debug("swsusp: free swap pages: %u\n", free_swap);
+	return free_swap > (nr_pages + PAGES_FOR_IO +
 		(nr_pages + PBES_PER_PAGE - 1) / PBES_PER_PAGE);
 }
 
 /**
- *	write_suspend_image - Write entire image and metadata.
+ *	swsusp_write - Write entire image and metadata.
  *
+ *	It is important _NOT_ to umount filesystems at this point. We want
+ *	them synced (in case something goes wrong) but we DO not want to mark
+ *	filesystem clean: it is not. (And it does not matter, if we resume
+ *	correctly, we'll mark system clean, anyway.)
  */
-static int write_suspend_image(void)
+
+int swsusp_write(struct pbe *pblist, unsigned int nr_pages)
 {
+	struct swap_map_page *swap_map;
+	struct swap_map_handle handle;
+	swp_entry_t start;
 	int error;
 
-	if (!enough_swap(nr_copy_pages)) {
+	if ((error = swsusp_swap_check())) {
+		printk(KERN_ERR "swsusp: Cannot find swap device, try swapon -a.\n");
+		return error;
+	}
+	if (!enough_swap(nr_pages)) {
 		printk(KERN_ERR "swsusp: Not enough free swap\n");
 		return -ENOSPC;
 	}
 
-	init_header();
-	if ((error = data_write()))
-		goto FreeData;
+	init_header(nr_pages);
+	swap_map = alloc_swap_map(swsusp_info.pages);
+	if (!swap_map)
+		return -ENOMEM;
+	init_swap_map_handle(&handle, swap_map);
 
-	if ((error = write_pagedir()))
-		goto FreePagedir;
+	error = swap_map_write_page(&handle, (unsigned long)&swsusp_info);
+	if (!error)
+		error = save_image_metadata(pblist, &handle);
+	if (!error)
+		error = save_image_data(pblist, &handle, nr_pages);
+	if (error)
+		goto Free_image_entries;
 
-	if ((error = close_swap()))
-		goto FreePagedir;
- Done:
-	memset(key_iv, 0, MAXKEY+MAXIV);
+	swap_map = reverse_swap_map(swap_map);
+	error = save_swap_map(swap_map, &start);
+	if (error)
+		goto Free_map_entries;
+
+	dump_info();
+	printk( "S" );
+	error = mark_swapfiles(start);
+	printk( "|\n" );
+	if (error)
+		goto Free_map_entries;
+
+Free_swap_map:
+	free_swap_map(swap_map);
 	return error;
- FreePagedir:
-	free_pagedir_entries();
- FreeData:
-	data_free();
-	goto Done;
+
+Free_map_entries:
+	free_swap_map_entries(swap_map);
+Free_image_entries:
+	free_image_entries(swap_map);
+	goto Free_swap_map;
 }
 
-/* It is important _NOT_ to umount filesystems at this point. We want
- * them synced (in case something goes wrong) but we DO not want to mark
- * filesystem clean: it is not. (And it does not matter, if we resume
- * correctly, we'll mark system clean, anyway.)
+/**
+ *	swsusp_shrink_memory -  Try to free as much memory as needed
+ *
+ *	... but do not OOM-kill anyone
+ *
+ *	Notice: all userland should be stopped before it is called, or
+ *	livelock is possible.
  */
-int swsusp_write(void)
+
+#define SHRINK_BITE	10000
+
+int swsusp_shrink_memory(void)
 {
-	int error;
+	long size, tmp;
+	struct zone *zone;
+	unsigned long pages = 0;
+	unsigned int i = 0;
+	char *p = "-\\|/";
 
-	if ((error = swsusp_swap_check())) {
-		printk(KERN_ERR "swsusp: cannot find swap device, try swapon -a.\n");
-		return error;
-	}
-	lock_swapdevices();
-	error = write_suspend_image();
-	/* This will unlock ignored swap devices since writing is finished */
-	lock_swapdevices();
-	return error;
+	printk("Shrinking memory...  ");
+	do {
+		size = 2 * count_highmem_pages();
+		size += size / 50 + count_data_pages();
+		size += (size + PBES_PER_PAGE - 1) / PBES_PER_PAGE +
+			PAGES_FOR_IO;
+		tmp = size;
+		for_each_zone (zone)
+			if (!is_highmem(zone))
+				tmp -= zone->free_pages;
+		if (tmp > 0) {
+			tmp = shrink_all_memory(SHRINK_BITE);
+			if (!tmp)
+				return -ENOMEM;
+			pages += tmp;
+		} else if (size > (image_size * 1024 * 1024) / PAGE_SIZE) {
+			tmp = shrink_all_memory(SHRINK_BITE);
+			pages += tmp;
+		}
+		printk("\b%c", p[i++%4]);
+	} while (tmp > 0);
+	printk("\bdone (%lu pages freed)\n", pages);
+
+	return 0;
 }
 
-
-
 int swsusp_suspend(void)
 {
 	int error;
@@ -677,7 +697,6 @@
 	/* We assume both lists contain the same number of elements */
 	while (src) {
 		dst->orig_address = src->orig_address;
-		dst->swap_address = src->swap_address;
 		dst = dst->next;
 		src = src->next;
 	}
@@ -757,198 +776,224 @@
 	return submit(WRITE, page_off, page);
 }
 
-/*
- * Sanity check if this image makes sense with this kernel/swap context
- * I really don't think that it's foolproof but more than nothing..
+/**
+ *	The following functions allow us to read data using a swap map
+ *	in a file-alike way
  */
 
-static const char *sanity_check(void)
+static inline void release_swap_map_reader(struct swap_map_handle *handle)
 {
-	dump_info();
-	if (swsusp_info.version_code != LINUX_VERSION_CODE)
-		return "kernel version";
-	if (swsusp_info.num_physpages != num_physpages)
-		return "memory size";
-	if (strcmp(swsusp_info.uts.sysname,system_utsname.sysname))
-		return "system type";
-	if (strcmp(swsusp_info.uts.release,system_utsname.release))
-		return "kernel release";
-	if (strcmp(swsusp_info.uts.version,system_utsname.version))
-		return "version";
-	if (strcmp(swsusp_info.uts.machine,system_utsname.machine))
-		return "machine";
-#if 0
-	/* We can't use number of online CPUs when we use hotplug to remove them ;-))) */
-	if (swsusp_info.cpus != num_possible_cpus())
-		return "number of cpus";
-#endif
-	return NULL;
+	if (handle->cur)
+		free_page((unsigned long)handle->cur);
+	handle->cur = NULL;
 }
 
-
-static int check_header(void)
-{
-	const char *reason = NULL;
-	int error;
-
-	if ((error = bio_read_page(swp_offset(swsusp_header.swsusp_info), &swsusp_info)))
-		return error;
-
- 	/* Is this same machine? */
-	if ((reason = sanity_check())) {
-		printk(KERN_ERR "swsusp: Resume mismatch: %s\n",reason);
-		return -EPERM;
-	}
-	nr_copy_pages = swsusp_info.image_pages;
-	return error;
-}
-
-static int check_sig(void)
+static inline int get_swap_map_reader(struct swap_map_handle *handle,
+                                      swp_entry_t start)
 {
 	int error;
 
-	memset(&swsusp_header, 0, sizeof(swsusp_header));
-	if ((error = bio_read_page(0, &swsusp_header)))
-		return error;
-	if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
-		memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
-		memcpy(key_iv, swsusp_header.key_iv, MAXKEY+MAXIV);
-		memset(swsusp_header.key_iv, 0, MAXKEY+MAXIV);
-
-		/*
-		 * Reset swap signature now.
-		 */
-		error = bio_write_page(0, &swsusp_header);
-	} else {
+	if (!swp_offset(start))
 		return -EINVAL;
-	}
-	if (!error)
-		pr_debug("swsusp: Signature found, resuming\n");
-	return error;
-}
-
-/**
- *	data_read - Read image pages from swap.
- *
- *	You do not need to check for overlaps, check_pagedir()
- *	already did that.
- */
-
-static int data_read(struct pbe *pblist)
-{
-	struct pbe *p;
-	int error = 0;
-	int i = 0;
-	int mod = swsusp_info.image_pages / 100;
-	void *tfm;
-
-	if ((error = crypto_init(0, &tfm)))
+	handle->cur = (struct swap_map_page *)get_zeroed_page(GFP_ATOMIC);
+	if (!handle->cur)
+		return -ENOMEM;
+	error = bio_read_page(swp_offset(start), handle->cur);
+	if (error) {
+		release_swap_map_reader(handle);
 		return error;
-
-	if (!mod)
-		mod = 1;
-
-	printk("swsusp: Reading image data (%lu pages):     ",
-			swsusp_info.image_pages);
-
-	for_each_pbe (p, pblist) {
-		if (!(i % mod))
-			printk("\b\b\b\b%3d%%", i / mod);
-
-		if ((error = crypto_read(p, tfm))) {
-			crypto_exit(tfm);
-			return error;
-		}
-
-		i++;
 	}
-	printk("\b\b\b\bdone\n");
-	crypto_exit(tfm);
-	return error;
-}
-
-/**
- *	read_pagedir - Read page backup list pages from swap
- */
-
-static int read_pagedir(struct pbe *pblist)
-{
-	struct pbe *pbpage, *p;
-	unsigned int i = 0;
-	int error;
-
-	if (!pblist)
-		return -EFAULT;
-
-	printk("swsusp: Reading pagedir (%lu pages)\n",
-			swsusp_info.pagedir_pages);
-
-	for_each_pb_page (pbpage, pblist) {
-		unsigned long offset = swp_offset(swsusp_info.pagedir[i++]);
-
-		error = -EFAULT;
-		if (offset) {
-			p = (pbpage + PB_PAGE_SKIP)->next;
-			error = bio_read_page(offset, (void *)pbpage);
-			(pbpage + PB_PAGE_SKIP)->next = p;
-		}
-		if (error)
-			break;
-	}
-
-	if (!error)
-		BUG_ON(i != swsusp_info.pagedir_pages);
-
-	return error;
-}
-
-
-static int check_suspend_image(void)
-{
-	int error = 0;
-
-	if ((error = check_sig()))
-		return error;
-
-	if ((error = check_header()))
-		return error;
-
+	handle->k = 0;
 	return 0;
 }
 
-static int read_suspend_image(void)
+static inline int swap_map_read_page(struct swap_map_handle *handle, void *buf)
 {
-	int error = 0;
+	unsigned long offset;
+	int error;
+
+	if (!handle->cur)
+		return -EINVAL;
+	offset = swp_offset(handle->cur->entries[handle->k]);
+	if (!offset)
+		return -EINVAL;
+	error = bio_read_page(offset, buf);
+	if (error)
+		return error;
+	if (++handle->k >= MAP_PAGE_SIZE) {
+		handle->k = 0;
+		offset = swp_offset(handle->cur->next_swap);
+		if (!offset)
+			release_swap_map_reader(handle);
+		else
+			error = bio_read_page(offset, handle->cur);
+	}
+	return error;
+}
+
+static int check_header(void)
+{
+	char *reason = NULL;
+
+	dump_info();
+	if (swsusp_info.version_code != LINUX_VERSION_CODE)
+		reason = "kernel version";
+	if (swsusp_info.num_physpages != num_physpages)
+		reason = "memory size";
+	if (strcmp(swsusp_info.uts.sysname,system_utsname.sysname))
+		reason = "system type";
+	if (strcmp(swsusp_info.uts.release,system_utsname.release))
+		reason = "kernel release";
+	if (strcmp(swsusp_info.uts.version,system_utsname.version))
+		reason = "version";
+	if (strcmp(swsusp_info.uts.machine,system_utsname.machine))
+		reason = "machine";
+	if (reason) {
+		printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason);
+		return -EPERM;
+	}
+	return 0;
+}
+
+/**
+ *	load_image_data - load the image data using the swap map handle
+ *	@handle and store them using the page backup list @pblist
+ *	(assume there are @nr_pages pages to load)
+ */
+
+static int load_image_data(struct pbe *pblist,
+                           struct swap_map_handle *handle,
+                           unsigned int nr_pages)
+{
+	int error;
+	unsigned int m;
 	struct pbe *p;
 
-	if (!(p = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 0)))
-		return -ENOMEM;
-
-	if ((error = read_pagedir(p)))
-		return error;
-	create_pbe_list(p, nr_copy_pages);
-	mark_unsafe_pages(p);
-	pagedir_nosave = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 1);
-	if (pagedir_nosave) {
-		create_pbe_list(pagedir_nosave, nr_copy_pages);
-		copy_page_backup_list(pagedir_nosave, p);
+	if (!pblist)
+		return -EINVAL;
+	printk("Loading image data pages (%u pages) ...     ", nr_pages);
+	m = nr_pages / 100;
+	if (!m)
+		m = 1;
+	nr_pages = 0;
+	p = pblist;
+	while (p) {
+		error = swap_map_read_page(handle, (void *)p->address);
+		if (error)
+			break;
+		p = p->next;
+		if (!(nr_pages % m))
+			printk("\b\b\b\b%3d%%", nr_pages / m);
+		nr_pages++;
 	}
-	free_pagedir(p);
-	if (!pagedir_nosave)
-		return -ENOMEM;
-
-	/* Allocate memory for the image and read the data from swap */
-
-	error = alloc_data_pages(pagedir_nosave, GFP_ATOMIC, 1);
-
 	if (!error)
-		error = data_read(pagedir_nosave);
-
+		printk("\b\b\b\bdone\n");
 	return error;
 }
 
 /**
- *      swsusp_check - Check for saved image in swap
+ *	unpack_orig_addresses - copy the elements of @buf[] (1 page) to
+ *	the PBEs in the list starting at @pbe
+ */
+
+static inline struct pbe *unpack_orig_addresses(unsigned long *buf,
+                                                struct pbe *pbe)
+{
+	int j;
+
+	for (j = 0; j < PAGE_SIZE / sizeof(long) && pbe; j++) {
+		pbe->orig_address = buf[j];
+		pbe = pbe->next;
+	}
+	return pbe;
+}
+
+/**
+ *	load_image_metadata - load the image metadata using the swap map
+ *	handle @handle and put them into the PBEs in the list @pblist
+ */
+
+static int load_image_metadata(struct pbe *pblist, struct swap_map_handle *handle)
+{
+	struct pbe *p;
+	unsigned long *buf;
+	unsigned int n = 0;
+	int error = 0;
+
+	printk("Loading image metadata ... ");
+	buf = (unsigned long *)get_zeroed_page(GFP_ATOMIC);
+	if (!buf)
+		return -ENOMEM;
+	p = pblist;
+	while (p) {
+		error = swap_map_read_page(handle, buf);
+		if (error)
+			break;
+		p = unpack_orig_addresses(buf, p);
+		n++;
+	}
+	free_page((unsigned long)buf);
+	if (!error)
+		printk("done (%u pages loaded)\n", n);
+	return error;
+}
+
+int swsusp_read(struct pbe **pblist_ptr)
+{
+	int error;
+	struct pbe *p, *pblist;
+	struct swap_map_handle handle;
+	unsigned int nr_pages;
+
+	if (IS_ERR(resume_bdev)) {
+		pr_debug("swsusp: block device not initialised\n");
+		return PTR_ERR(resume_bdev);
+	}
+
+	error = get_swap_map_reader(&handle, swsusp_header.image);
+	if (!error)
+		error = swap_map_read_page(&handle, &swsusp_info);
+	if (!error)
+		error = check_header();
+	if (error)
+		return error;
+	nr_pages = swsusp_info.image_pages;
+	p = alloc_pagedir(nr_pages, GFP_ATOMIC, 0);
+	if (!p)
+		return -ENOMEM;
+	error = load_image_metadata(p, &handle);
+	if (!error) {
+		mark_unsafe_pages(p);
+		pblist = alloc_pagedir(nr_pages, GFP_ATOMIC, 1);
+		if (pblist)
+			copy_page_backup_list(pblist, p);
+		free_pagedir(p);
+		if (!pblist)
+			error = -ENOMEM;
+
+		/* Allocate memory for the image and read the data from swap */
+		if (!error)
+			error = alloc_data_pages(pblist, GFP_ATOMIC, 1);
+		if (!error) {
+			release_eaten_pages();
+			error = load_image_data(pblist, &handle, nr_pages);
+		}
+		if (!error)
+			*pblist_ptr = pblist;
+	}
+	release_swap_map_reader(&handle);
+
+	blkdev_put(resume_bdev);
+
+	if (!error)
+		pr_debug("swsusp: Reading resume file was successful\n");
+	else
+		pr_debug("swsusp: Error %d resuming\n", error);
+	return error;
+}
+
+/**
+ *      swsusp_check - Check for swsusp signature in the resume device
  */
 
 int swsusp_check(void)
@@ -958,40 +1003,27 @@
 	resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ);
 	if (!IS_ERR(resume_bdev)) {
 		set_blocksize(resume_bdev, PAGE_SIZE);
-		error = check_suspend_image();
+		memset(&swsusp_header, 0, sizeof(swsusp_header));
+		if ((error = bio_read_page(0, &swsusp_header)))
+			return error;
+		if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
+			memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
+			/* Reset swap signature now */
+			error = bio_write_page(0, &swsusp_header);
+		} else {
+			return -EINVAL;
+		}
 		if (error)
-		    blkdev_put(resume_bdev);
-	} else
+			blkdev_put(resume_bdev);
+		else
+			pr_debug("swsusp: Signature found, resuming\n");
+	} else {
 		error = PTR_ERR(resume_bdev);
-
-	if (!error)
-		pr_debug("swsusp: resume file found\n");
-	else
-		pr_debug("swsusp: Error %d check for resume file\n", error);
-	return error;
-}
-
-/**
- *	swsusp_read - Read saved image from swap.
- */
-
-int swsusp_read(void)
-{
-	int error;
-
-	if (IS_ERR(resume_bdev)) {
-		pr_debug("swsusp: block device not initialised\n");
-		return PTR_ERR(resume_bdev);
 	}
 
-	error = read_suspend_image();
-	blkdev_put(resume_bdev);
-	memset(key_iv, 0, MAXKEY+MAXIV);
+	if (error)
+		pr_debug("swsusp: Error %d check for resume file\n", error);
 
-	if (!error)
-		pr_debug("swsusp: Reading resume file was successful\n");
-	else
-		pr_debug("swsusp: Error %d resuming\n", error);
 	return error;
 }
 
diff --git a/kernel/printk.c b/kernel/printk.c
index 5287be8..2251be8 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -569,7 +569,7 @@
 				   p[1] <= '7' && p[2] == '>') {
 					loglev_char = p[1];
 					p += 3;
-					printed_len += 3;
+					printed_len -= 3;
 				} else {
 					loglev_char = default_message_loglevel
 						+ '0';
@@ -584,7 +584,7 @@
 
 				for (tp = tbuf; tp < tbuf + tlen; tp++)
 					emit_log_char(*tp);
-				printed_len += tlen - 3;
+				printed_len += tlen;
 			} else {
 				if (p[0] != '<' || p[1] < '0' ||
 				   p[1] > '7' || p[2] != '>') {
@@ -592,8 +592,8 @@
 					emit_log_char(default_message_loglevel
 						+ '0');
 					emit_log_char('>');
+					printed_len += 3;
 				}
-				printed_len += 3;
 			}
 			log_level_unknown = 0;
 			if (!*p)
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 17ee7e5..cceaf09 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -241,7 +241,8 @@
 		if (write) {
 			copy_to_user_page(vma, page, addr,
 					  maddr + offset, buf, bytes);
-			set_page_dirty_lock(page);
+			if (!PageCompound(page))
+				set_page_dirty_lock(page);
 		} else {
 			copy_from_user_page(vma, page, addr,
 					    buf, maddr + offset, bytes);
@@ -407,54 +408,62 @@
 	return ret;
 }
 
-#ifndef __ARCH_SYS_PTRACE
-static int ptrace_get_task_struct(long request, long pid,
-		struct task_struct **childp)
+/**
+ * ptrace_traceme  --  helper for PTRACE_TRACEME
+ *
+ * Performs checks and sets PT_PTRACED.
+ * Should be used by all ptrace implementations for PTRACE_TRACEME.
+ */
+int ptrace_traceme(void)
 {
-	struct task_struct *child;
 	int ret;
 
 	/*
-	 * Callers use child == NULL as an indication to exit early even
-	 * when the return value is 0, so make sure it is non-NULL here.
+	 * Are we already being traced?
 	 */
-	*childp = NULL;
+	if (current->ptrace & PT_PTRACED)
+		return -EPERM;
+	ret = security_ptrace(current->parent, current);
+	if (ret)
+		return -EPERM;
+	/*
+	 * Set the ptrace bit in the process ptrace flags.
+	 */
+	current->ptrace |= PT_PTRACED;
+	return 0;
+}
 
-	if (request == PTRACE_TRACEME) {
-		/*
-		 * Are we already being traced?
-		 */
-		if (current->ptrace & PT_PTRACED)
-			return -EPERM;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			return -EPERM;
-		/*
-		 * Set the ptrace bit in the process ptrace flags.
-		 */
-		current->ptrace |= PT_PTRACED;
-		return 0;
-	}
+/**
+ * ptrace_get_task_struct  --  grab a task struct reference for ptrace
+ * @pid:       process id to grab a task_struct reference of
+ *
+ * This function is a helper for ptrace implementations.  It checks
+ * permissions and then grabs a task struct for use of the actual
+ * ptrace implementation.
+ *
+ * Returns the task_struct for @pid or an ERR_PTR() on failure.
+ */
+struct task_struct *ptrace_get_task_struct(pid_t pid)
+{
+	struct task_struct *child;
 
 	/*
-	 * You may not mess with init
+	 * Tracing init is not allowed.
 	 */
 	if (pid == 1)
-		return -EPERM;
+		return ERR_PTR(-EPERM);
 
-	ret = -ESRCH;
 	read_lock(&tasklist_lock);
 	child = find_task_by_pid(pid);
 	if (child)
 		get_task_struct(child);
 	read_unlock(&tasklist_lock);
 	if (!child)
-		return -ESRCH;
-
-	*childp = child;
-	return 0;
+		return ERR_PTR(-ESRCH);
+	return child;
 }
 
+#ifndef __ARCH_SYS_PTRACE
 asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
 	struct task_struct *child;
@@ -464,9 +473,16 @@
 	 * This lock_kernel fixes a subtle race with suid exec
 	 */
 	lock_kernel();
-	ret = ptrace_get_task_struct(request, pid, &child);
-	if (!child)
+	if (request == PTRACE_TRACEME) {
+		ret = ptrace_traceme();
 		goto out;
+	}
+
+	child = ptrace_get_task_struct(pid);
+	if (IS_ERR(child)) {
+		ret = PTR_ERR(child);
+		goto out;
+	}
 
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index c4d159a..30b0bba 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/smp.h>
+#include <linux/rcupdate.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <asm/atomic.h>
@@ -45,7 +46,6 @@
 #include <linux/percpu.h>
 #include <linux/notifier.h>
 #include <linux/rcupdate.h>
-#include <linux/rcuref.h>
 #include <linux/cpu.h>
 
 /* Definition for rcupdate control block. */
@@ -61,9 +61,9 @@
 	                              /* for current batch to proceed.        */
 };
 
-static struct rcu_state rcu_state ____cacheline_maxaligned_in_smp =
+static struct rcu_state rcu_state ____cacheline_internodealigned_in_smp =
 	  {.lock = SPIN_LOCK_UNLOCKED, .cpumask = CPU_MASK_NONE };
-static struct rcu_state rcu_bh_state ____cacheline_maxaligned_in_smp =
+static struct rcu_state rcu_bh_state ____cacheline_internodealigned_in_smp =
 	  {.lock = SPIN_LOCK_UNLOCKED, .cpumask = CPU_MASK_NONE };
 
 DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
@@ -73,19 +73,6 @@
 static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
 static int maxbatch = 10000;
 
-#ifndef __HAVE_ARCH_CMPXCHG
-/*
- * We use an array of spinlocks for the rcurefs -- similar to ones in sparc
- * 32 bit atomic_t implementations, and a hash function similar to that
- * for our refcounting needs.
- * Can't help multiprocessors which donot have cmpxchg :(
- */
-
-spinlock_t __rcuref_hash[RCUREF_HASH_SIZE] = {
-	[0 ... (RCUREF_HASH_SIZE-1)] = SPIN_LOCK_UNLOCKED
-};
-#endif
-
 /**
  * call_rcu - Queue an RCU callback for invocation after a grace period.
  * @head: structure to be used for queueing the RCU updates.
@@ -116,6 +103,10 @@
 	local_irq_restore(flags);
 }
 
+static atomic_t rcu_barrier_cpu_count;
+static struct semaphore rcu_barrier_sema;
+static struct completion rcu_barrier_completion;
+
 /**
  * call_rcu_bh - Queue an RCU for invocation after a quicker grace period.
  * @head: structure to be used for queueing the RCU updates.
@@ -162,6 +153,42 @@
 	return rcu_ctrlblk.completed;
 }
 
+static void rcu_barrier_callback(struct rcu_head *notused)
+{
+	if (atomic_dec_and_test(&rcu_barrier_cpu_count))
+		complete(&rcu_barrier_completion);
+}
+
+/*
+ * Called with preemption disabled, and from cross-cpu IRQ context.
+ */
+static void rcu_barrier_func(void *notused)
+{
+	int cpu = smp_processor_id();
+	struct rcu_data *rdp = &per_cpu(rcu_data, cpu);
+	struct rcu_head *head;
+
+	head = &rdp->barrier;
+	atomic_inc(&rcu_barrier_cpu_count);
+	call_rcu(head, rcu_barrier_callback);
+}
+
+/**
+ * rcu_barrier - Wait until all the in-flight RCUs are complete.
+ */
+void rcu_barrier(void)
+{
+	BUG_ON(in_interrupt());
+	/* Take cpucontrol semaphore to protect against CPU hotplug */
+	down(&rcu_barrier_sema);
+	init_completion(&rcu_barrier_completion);
+	atomic_set(&rcu_barrier_cpu_count, 0);
+	on_each_cpu(rcu_barrier_func, NULL, 0, 1);
+	wait_for_completion(&rcu_barrier_completion);
+	up(&rcu_barrier_sema);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier);
+
 /*
  * Invoke the completed RCU callbacks. They are expected to be in
  * a per-cpu list.
@@ -217,15 +244,23 @@
 
 	if (rcp->next_pending &&
 			rcp->completed == rcp->cur) {
-		/* Can't change, since spin lock held. */
-		cpus_andnot(rsp->cpumask, cpu_online_map, nohz_cpu_mask);
-
 		rcp->next_pending = 0;
-		/* next_pending == 0 must be visible in __rcu_process_callbacks()
-		 * before it can see new value of cur.
+		/*
+		 * next_pending == 0 must be visible in
+		 * __rcu_process_callbacks() before it can see new value of cur.
 		 */
 		smp_wmb();
 		rcp->cur++;
+
+		/*
+		 * Accessing nohz_cpu_mask before incrementing rcp->cur needs a
+		 * Barrier  Otherwise it can cause tickless idle CPUs to be
+		 * included in rsp->cpumask, which will extend graceperiods
+		 * unnecessarily.
+		 */
+		smp_mb();
+		cpus_andnot(rsp->cpumask, cpu_online_map, nohz_cpu_mask);
+
 	}
 }
 
@@ -457,6 +492,7 @@
  */
 void __init rcu_init(void)
 {
+	sema_init(&rcu_barrier_sema, 1);
 	rcu_cpu_notify(&rcu_nb, CPU_UP_PREPARE,
 			(void *)(long)smp_processor_id());
 	/* Register notifier for non-boot CPUs */
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 88c28d4..7732199 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -39,7 +39,6 @@
 #include <linux/moduleparam.h>
 #include <linux/percpu.h>
 #include <linux/notifier.h>
-#include <linux/rcuref.h>
 #include <linux/cpu.h>
 #include <linux/random.h>
 #include <linux/delay.h>
@@ -49,9 +48,11 @@
 MODULE_LICENSE("GPL");
 
 static int nreaders = -1;	/* # reader threads, defaults to 4*ncpus */
-static int stat_interval = 0;	/* Interval between stats, in seconds. */
+static int stat_interval;	/* Interval between stats, in seconds. */
 				/*  Defaults to "only at end of test". */
-static int verbose = 0;		/* Print more debug info. */
+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)*/
 
 MODULE_PARM(nreaders, "i");
 MODULE_PARM_DESC(nreaders, "Number of RCU reader threads");
@@ -59,6 +60,10 @@
 MODULE_PARM_DESC(stat_interval, "Number of seconds between stats printk()s");
 MODULE_PARM(verbose, "i");
 MODULE_PARM_DESC(verbose, "Enable verbose debugging printk()s");
+MODULE_PARM(test_no_idle_hz, "i");
+MODULE_PARM_DESC(test_no_idle_hz, "Test support for tickless idle CPUs");
+MODULE_PARM(shuffle_interval, "i");
+MODULE_PARM_DESC(shuffle_interval, "Number of seconds between shuffles");
 #define TORTURE_FLAG "rcutorture: "
 #define PRINTK_STRING(s) \
 	do { printk(KERN_ALERT TORTURE_FLAG s "\n"); } while (0)
@@ -73,6 +78,7 @@
 static struct task_struct *writer_task;
 static struct task_struct **reader_tasks;
 static struct task_struct *stats_task;
+static struct task_struct *shuffler_task;
 
 #define RCU_TORTURE_PIPE_LEN 10
 
@@ -103,7 +109,7 @@
 /*
  * Allocate an element from the rcu_tortures pool.
  */
-struct rcu_torture *
+static struct rcu_torture *
 rcu_torture_alloc(void)
 {
 	struct list_head *p;
@@ -376,12 +382,77 @@
 	return 0;
 }
 
+static int rcu_idle_cpu;	/* Force all torture tasks off this CPU */
+
+/* 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)
+{
+	cpumask_t tmp_mask = CPU_MASK_ALL;
+	int i;
+
+	lock_cpu_hotplug();
+
+	/* No point in shuffling if there is only one online CPU (ex: UP) */
+	if (num_online_cpus() == 1) {
+		unlock_cpu_hotplug();
+		return;
+	}
+
+	if (rcu_idle_cpu != -1)
+		cpu_clear(rcu_idle_cpu, tmp_mask);
+
+	set_cpus_allowed(current, tmp_mask);
+
+	if (reader_tasks != NULL) {
+		for (i = 0; i < nrealreaders; i++)
+			if (reader_tasks[i])
+				set_cpus_allowed(reader_tasks[i], tmp_mask);
+	}
+
+	if (writer_task)
+		set_cpus_allowed(writer_task, tmp_mask);
+
+	if (stats_task)
+		set_cpus_allowed(stats_task, tmp_mask);
+
+	if (rcu_idle_cpu == -1)
+		rcu_idle_cpu = num_online_cpus() - 1;
+	else
+		rcu_idle_cpu--;
+
+	unlock_cpu_hotplug();
+}
+
+/* Shuffle tasks across CPUs, with the intent of allowing each CPU in the
+ * system to become idle at a time and cut off its timer ticks. This is meant
+ * to test the support for such tickless idle CPU in RCU.
+ */
+static int
+rcu_torture_shuffle(void *arg)
+{
+	VERBOSE_PRINTK_STRING("rcu_torture_shuffle task started");
+	do {
+		schedule_timeout_interruptible(shuffle_interval * HZ);
+		rcu_torture_shuffle_tasks();
+	} while (!kthread_should_stop());
+	VERBOSE_PRINTK_STRING("rcu_torture_shuffle task stopping");
+	return 0;
+}
+
 static void
 rcu_torture_cleanup(void)
 {
 	int i;
 
 	fullstop = 1;
+	if (shuffler_task != NULL) {
+		VERBOSE_PRINTK_STRING("Stopping rcu_torture_shuffle task");
+		kthread_stop(shuffler_task);
+	}
+	shuffler_task = NULL;
+
 	if (writer_task != NULL) {
 		VERBOSE_PRINTK_STRING("Stopping rcu_torture_writer task");
 		kthread_stop(writer_task);
@@ -409,9 +480,8 @@
 	stats_task = NULL;
 
 	/* Wait for all RCU callbacks to fire.  */
+	rcu_barrier();
 
-	for (i = 0; i < RCU_TORTURE_PIPE_LEN; i++)
-		synchronize_rcu();
 	rcu_torture_stats_print();  /* -After- the stats thread is stopped! */
 	printk(KERN_ALERT TORTURE_FLAG
 	       "--- End of test: %s\n",
@@ -431,9 +501,11 @@
 		nrealreaders = nreaders;
 	else
 		nrealreaders = 2 * num_online_cpus();
-	printk(KERN_ALERT TORTURE_FLAG
-	       "--- Start of test: nreaders=%d stat_interval=%d verbose=%d\n",
-	       nrealreaders, stat_interval, verbose);
+	printk(KERN_ALERT TORTURE_FLAG "--- Start of test: nreaders=%d "
+		"stat_interval=%d verbose=%d test_no_idle_hz=%d "
+		"shuffle_interval = %d\n",
+		nrealreaders, stat_interval, verbose, test_no_idle_hz,
+		shuffle_interval);
 	fullstop = 0;
 
 	/* Set up the freelist. */
@@ -503,6 +575,18 @@
 			goto unwind;
 		}
 	}
+	if (test_no_idle_hz) {
+		rcu_idle_cpu = num_online_cpus() - 1;
+		/* Create the shuffler thread */
+		shuffler_task = kthread_run(rcu_torture_shuffle, NULL,
+					  "rcu_torture_shuffle");
+		if (IS_ERR(shuffler_task)) {
+			firsterr = PTR_ERR(shuffler_task);
+			VERBOSE_PRINTK_ERRSTRING("Failed to create shuffler");
+			shuffler_task = NULL;
+			goto unwind;
+		}
+	}
 	return 0;
 
 unwind:
diff --git a/kernel/sched.c b/kernel/sched.c
index 6f46c94..9273309 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -176,6 +176,13 @@
 #define task_hot(p, now, sd) ((long long) ((now) - (p)->last_ran)	\
 				< (long long) (sd)->cache_hot_time)
 
+void __put_task_struct_cb(struct rcu_head *rhp)
+{
+	__put_task_struct(container_of(rhp, struct task_struct, rcu));
+}
+
+EXPORT_SYMBOL_GPL(__put_task_struct_cb);
+
 /*
  * These are the runqueue data structures:
  */
diff --git a/kernel/signal.c b/kernel/signal.c
index d7611f1..08aa5b2 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -329,13 +329,20 @@
 	/* Ok, we're done with the signal handlers */
 	tsk->sighand = NULL;
 	if (atomic_dec_and_test(&sighand->count))
-		kmem_cache_free(sighand_cachep, sighand);
+		sighand_free(sighand);
 }
 
 void exit_sighand(struct task_struct *tsk)
 {
 	write_lock_irq(&tasklist_lock);
-	__exit_sighand(tsk);
+	rcu_read_lock();
+	if (tsk->sighand != NULL) {
+		struct sighand_struct *sighand = rcu_dereference(tsk->sighand);
+		spin_lock(&sighand->siglock);
+		__exit_sighand(tsk);
+		spin_unlock(&sighand->siglock);
+	}
+	rcu_read_unlock();
 	write_unlock_irq(&tasklist_lock);
 }
 
@@ -345,19 +352,20 @@
 void __exit_signal(struct task_struct *tsk)
 {
 	struct signal_struct * sig = tsk->signal;
-	struct sighand_struct * sighand = tsk->sighand;
+	struct sighand_struct * sighand;
 
 	if (!sig)
 		BUG();
 	if (!atomic_read(&sig->count))
 		BUG();
+	rcu_read_lock();
+	sighand = rcu_dereference(tsk->sighand);
 	spin_lock(&sighand->siglock);
 	posix_cpu_timers_exit(tsk);
 	if (atomic_dec_and_test(&sig->count)) {
 		posix_cpu_timers_exit_group(tsk);
-		if (tsk == sig->curr_target)
-			sig->curr_target = next_thread(tsk);
 		tsk->signal = NULL;
+		__exit_sighand(tsk);
 		spin_unlock(&sighand->siglock);
 		flush_sigqueue(&sig->shared_pending);
 	} else {
@@ -389,9 +397,11 @@
 		sig->nvcsw += tsk->nvcsw;
 		sig->nivcsw += tsk->nivcsw;
 		sig->sched_time += tsk->sched_time;
+		__exit_sighand(tsk);
 		spin_unlock(&sighand->siglock);
 		sig = NULL;	/* Marker for below.  */
 	}
+	rcu_read_unlock();
 	clear_tsk_thread_flag(tsk,TIF_SIGPENDING);
 	flush_sigqueue(&tsk->pending);
 	if (sig) {
@@ -613,6 +623,33 @@
  * Returns 1 if any signals were found.
  *
  * All callers must be holding the siglock.
+ *
+ * This version takes a sigset mask and looks at all signals,
+ * not just those in the first mask word.
+ */
+static int rm_from_queue_full(sigset_t *mask, struct sigpending *s)
+{
+	struct sigqueue *q, *n;
+	sigset_t m;
+
+	sigandsets(&m, mask, &s->signal);
+	if (sigisemptyset(&m))
+		return 0;
+
+	signandsets(&s->signal, &s->signal, mask);
+	list_for_each_entry_safe(q, n, &s->list, list) {
+		if (sigismember(mask, q->info.si_signo)) {
+			list_del_init(&q->list);
+			__sigqueue_free(q);
+		}
+	}
+	return 1;
+}
+/*
+ * Remove signals in mask from the pending set and queue.
+ * Returns 1 if any signals were found.
+ *
+ * All callers must be holding the siglock.
  */
 static int rm_from_queue(unsigned long mask, struct sigpending *s)
 {
@@ -1080,18 +1117,29 @@
 }
 
 /*
- * Must be called with the tasklist_lock held for reading!
+ * Must be called under rcu_read_lock() or with tasklist_lock read-held.
  */
 int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 {
 	unsigned long flags;
+	struct sighand_struct *sp;
 	int ret;
 
+retry:
 	ret = check_kill_permission(sig, info, p);
-	if (!ret && sig && p->sighand) {
-		spin_lock_irqsave(&p->sighand->siglock, flags);
+	if (!ret && sig && (sp = rcu_dereference(p->sighand))) {
+		spin_lock_irqsave(&sp->siglock, flags);
+		if (p->sighand != sp) {
+			spin_unlock_irqrestore(&sp->siglock, flags);
+			goto retry;
+		}
+		if ((atomic_read(&sp->count) == 0) ||
+				(atomic_read(&p->usage) == 0)) {
+			spin_unlock_irqrestore(&sp->siglock, flags);
+			return -ESRCH;
+		}
 		ret = __group_send_sig_info(sig, info, p);
-		spin_unlock_irqrestore(&p->sighand->siglock, flags);
+		spin_unlock_irqrestore(&sp->siglock, flags);
 	}
 
 	return ret;
@@ -1136,14 +1184,21 @@
 kill_proc_info(int sig, struct siginfo *info, pid_t pid)
 {
 	int error;
+	int acquired_tasklist_lock = 0;
 	struct task_struct *p;
 
-	read_lock(&tasklist_lock);
+	rcu_read_lock();
+	if (unlikely(sig_kernel_stop(sig) || sig == SIGCONT)) {
+		read_lock(&tasklist_lock);
+		acquired_tasklist_lock = 1;
+	}
 	p = find_task_by_pid(pid);
 	error = -ESRCH;
 	if (p)
 		error = group_send_sig_info(sig, info, p);
-	read_unlock(&tasklist_lock);
+	if (unlikely(acquired_tasklist_lock))
+		read_unlock(&tasklist_lock);
+	rcu_read_unlock();
 	return error;
 }
 
@@ -1163,8 +1218,7 @@
 		ret = -ESRCH;
 		goto out_unlock;
 	}
-	if ((!info || ((unsigned long)info != 1 &&
-			(unsigned long)info != 2 && SI_FROMUSER(info)))
+	if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info)))
 	    && (euid != p->suid) && (euid != p->uid)
 	    && (uid != p->suid) && (uid != p->uid)) {
 		ret = -EPERM;
@@ -1355,16 +1409,54 @@
 {
 	unsigned long flags;
 	int ret = 0;
+	struct sighand_struct *sh;
 
 	BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
-	read_lock(&tasklist_lock);
+
+	/*
+	 * The rcu based delayed sighand destroy makes it possible to
+	 * run this without tasklist lock held. The task struct itself
+	 * cannot go away as create_timer did get_task_struct().
+	 *
+	 * We return -1, when the task is marked exiting, so
+	 * posix_timer_event can redirect it to the group leader
+	 */
+	rcu_read_lock();
 
 	if (unlikely(p->flags & PF_EXITING)) {
 		ret = -1;
 		goto out_err;
 	}
 
-	spin_lock_irqsave(&p->sighand->siglock, flags);
+retry:
+	sh = rcu_dereference(p->sighand);
+
+	spin_lock_irqsave(&sh->siglock, flags);
+	if (p->sighand != sh) {
+		/* We raced with exec() in a multithreaded process... */
+		spin_unlock_irqrestore(&sh->siglock, flags);
+		goto retry;
+	}
+
+	/*
+	 * We do the check here again to handle the following scenario:
+	 *
+	 * CPU 0		CPU 1
+	 * send_sigqueue
+	 * check PF_EXITING
+	 * interrupt		exit code running
+	 *			__exit_signal
+	 *			lock sighand->siglock
+	 *			unlock sighand->siglock
+	 * lock sh->siglock
+	 * add(tsk->pending) 	flush_sigqueue(tsk->pending)
+	 *
+	 */
+
+	if (unlikely(p->flags & PF_EXITING)) {
+		ret = -1;
+		goto out;
+	}
 
 	if (unlikely(!list_empty(&q->list))) {
 		/*
@@ -1388,9 +1480,9 @@
 		signal_wake_up(p, sig == SIGKILL);
 
 out:
-	spin_unlock_irqrestore(&p->sighand->siglock, flags);
+	spin_unlock_irqrestore(&sh->siglock, flags);
 out_err:
-	read_unlock(&tasklist_lock);
+	rcu_read_unlock();
 
 	return ret;
 }
@@ -1402,7 +1494,9 @@
 	int ret = 0;
 
 	BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
+
 	read_lock(&tasklist_lock);
+	/* Since it_lock is held, p->sighand cannot be NULL. */
 	spin_lock_irqsave(&p->sighand->siglock, flags);
 	handle_stop_signal(sig, p);
 
@@ -1436,7 +1530,7 @@
 out:
 	spin_unlock_irqrestore(&p->sighand->siglock, flags);
 	read_unlock(&tasklist_lock);
-	return(ret);
+	return ret;
 }
 
 /*
@@ -2338,6 +2432,7 @@
 do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
 {
 	struct k_sigaction *k;
+	sigset_t mask;
 
 	if (!valid_signal(sig) || sig < 1 || (act && sig_kernel_only(sig)))
 		return -EINVAL;
@@ -2385,9 +2480,11 @@
 			*k = *act;
 			sigdelsetmask(&k->sa.sa_mask,
 				      sigmask(SIGKILL) | sigmask(SIGSTOP));
-			rm_from_queue(sigmask(sig), &t->signal->shared_pending);
+			sigemptyset(&mask);
+			sigaddset(&mask, sig);
+			rm_from_queue_full(&mask, &t->signal->shared_pending);
 			do {
-				rm_from_queue(sigmask(sig), &t->pending);
+				rm_from_queue_full(&mask, &t->pending);
 				recalc_sigpending_tsk(t);
 				t = next_thread(t);
 			} while (t != current);
diff --git a/kernel/sys.c b/kernel/sys.c
index bce933e..b6941e0 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -32,6 +32,7 @@
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
+#include <linux/kprobes.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -168,7 +169,7 @@
  *	of the last notifier function called.
  */
  
-int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
+int __kprobes notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
 {
 	int ret=NOTIFY_DONE;
 	struct notifier_block *nb = *n;
@@ -488,6 +489,12 @@
 	                magic2 != LINUX_REBOOT_MAGIC2C))
 		return -EINVAL;
 
+	/* Instead of trying to make the power_off code look like
+	 * halt when pm_power_off is not set do it the easy way.
+	 */
+	if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
+		cmd = LINUX_REBOOT_CMD_HALT;
+
 	lock_kernel();
 	switch (cmd) {
 	case LINUX_REBOOT_CMD_RESTART:
@@ -1083,10 +1090,11 @@
 asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
 {
 	struct task_struct *p;
+	struct task_struct *group_leader = current->group_leader;
 	int err = -EINVAL;
 
 	if (!pid)
-		pid = current->pid;
+		pid = group_leader->pid;
 	if (!pgid)
 		pgid = pid;
 	if (pgid < 0)
@@ -1106,16 +1114,16 @@
 	if (!thread_group_leader(p))
 		goto out;
 
-	if (p->parent == current || p->real_parent == current) {
+	if (p->real_parent == group_leader) {
 		err = -EPERM;
-		if (p->signal->session != current->signal->session)
+		if (p->signal->session != group_leader->signal->session)
 			goto out;
 		err = -EACCES;
 		if (p->did_exec)
 			goto out;
 	} else {
 		err = -ESRCH;
-		if (p != current)
+		if (p != group_leader)
 			goto out;
 	}
 
@@ -1127,7 +1135,7 @@
 		struct task_struct *p;
 
 		do_each_task_pid(pgid, PIDTYPE_PGID, p) {
-			if (p->signal->session == current->signal->session)
+			if (p->signal->session == group_leader->signal->session)
 				goto ok_pgid;
 		} while_each_task_pid(pgid, PIDTYPE_PGID, p);
 		goto out;
@@ -1207,24 +1215,22 @@
 
 asmlinkage long sys_setsid(void)
 {
+	struct task_struct *group_leader = current->group_leader;
 	struct pid *pid;
 	int err = -EPERM;
 
-	if (!thread_group_leader(current))
-		return -EINVAL;
-
 	down(&tty_sem);
 	write_lock_irq(&tasklist_lock);
 
-	pid = find_pid(PIDTYPE_PGID, current->pid);
+	pid = find_pid(PIDTYPE_PGID, group_leader->pid);
 	if (pid)
 		goto out;
 
-	current->signal->leader = 1;
-	__set_special_pids(current->pid, current->pid);
-	current->signal->tty = NULL;
-	current->signal->tty_old_pgrp = 0;
-	err = process_group(current);
+	group_leader->signal->leader = 1;
+	__set_special_pids(group_leader->pid, group_leader->pid);
+	group_leader->signal->tty = NULL;
+	group_leader->signal->tty_old_pgrp = 0;
+	err = process_group(group_leader);
 out:
 	write_unlock_irq(&tasklist_lock);
 	up(&tty_sem);
@@ -1686,7 +1692,10 @@
 	if (unlikely(!p->signal))
 		return;
 
+	utime = stime = cputime_zero;
+
 	switch (who) {
+		case RUSAGE_BOTH:
 		case RUSAGE_CHILDREN:
 			spin_lock_irqsave(&p->sighand->siglock, flags);
 			utime = p->signal->cutime;
@@ -1696,22 +1705,11 @@
 			r->ru_minflt = p->signal->cmin_flt;
 			r->ru_majflt = p->signal->cmaj_flt;
 			spin_unlock_irqrestore(&p->sighand->siglock, flags);
-			cputime_to_timeval(utime, &r->ru_utime);
-			cputime_to_timeval(stime, &r->ru_stime);
-			break;
+
+			if (who == RUSAGE_CHILDREN)
+				break;
+
 		case RUSAGE_SELF:
-			spin_lock_irqsave(&p->sighand->siglock, flags);
-			utime = stime = cputime_zero;
-			goto sum_group;
-		case RUSAGE_BOTH:
-			spin_lock_irqsave(&p->sighand->siglock, flags);
-			utime = p->signal->cutime;
-			stime = p->signal->cstime;
-			r->ru_nvcsw = p->signal->cnvcsw;
-			r->ru_nivcsw = p->signal->cnivcsw;
-			r->ru_minflt = p->signal->cmin_flt;
-			r->ru_majflt = p->signal->cmaj_flt;
-		sum_group:
 			utime = cputime_add(utime, p->signal->utime);
 			stime = cputime_add(stime, p->signal->stime);
 			r->ru_nvcsw += p->signal->nvcsw;
@@ -1728,13 +1726,14 @@
 				r->ru_majflt += t->maj_flt;
 				t = next_thread(t);
 			} while (t != p);
-			spin_unlock_irqrestore(&p->sighand->siglock, flags);
-			cputime_to_timeval(utime, &r->ru_utime);
-			cputime_to_timeval(stime, &r->ru_stime);
 			break;
+
 		default:
 			BUG();
 	}
+
+	cputime_to_timeval(utime, &r->ru_utime);
+	cputime_to_timeval(stime, &r->ru_stime);
 }
 
 int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 1ab2370..bd3b9bf 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -82,6 +82,28 @@
 cond_syscall(sys_inotify_init);
 cond_syscall(sys_inotify_add_watch);
 cond_syscall(sys_inotify_rm_watch);
+cond_syscall(sys_migrate_pages);
+cond_syscall(sys_chown16);
+cond_syscall(sys_fchown16);
+cond_syscall(sys_getegid16);
+cond_syscall(sys_geteuid16);
+cond_syscall(sys_getgid16);
+cond_syscall(sys_getgroups16);
+cond_syscall(sys_getresgid16);
+cond_syscall(sys_getresuid16);
+cond_syscall(sys_getuid16);
+cond_syscall(sys_lchown16);
+cond_syscall(sys_setfsgid16);
+cond_syscall(sys_setfsuid16);
+cond_syscall(sys_setgid16);
+cond_syscall(sys_setgroups16);
+cond_syscall(sys_setregid16);
+cond_syscall(sys_setresgid16);
+cond_syscall(sys_setresuid16);
+cond_syscall(sys_setreuid16);
+cond_syscall(sys_setuid16);
+cond_syscall(sys_vm86old);
+cond_syscall(sys_vm86);
 
 /* arch-specific weak syscall entries */
 cond_syscall(sys_pciconfig_read);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 9990e10..03b0598 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -31,6 +31,7 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/kobject.h>
 #include <linux/net.h>
 #include <linux/sysrq.h>
 #include <linux/highuid.h>
@@ -67,6 +68,8 @@
 extern int printk_ratelimit_jiffies;
 extern int printk_ratelimit_burst;
 extern int pid_max_min, pid_max_max;
+extern int sysctl_drop_caches;
+extern int percpu_pagelist_fraction;
 
 #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
 int unknown_nmi_panic;
@@ -77,15 +80,13 @@
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
+static int min_percpu_pagelist_fract = 8;
 
 static int ngroups_max = NGROUPS_MAX;
 
 #ifdef CONFIG_KMOD
 extern char modprobe_path[];
 #endif
-#ifdef CONFIG_HOTPLUG
-extern char hotplug_path[];
-#endif
 #ifdef CONFIG_CHR_DEV_SG
 extern int sg_big_buff;
 #endif
@@ -110,7 +111,7 @@
 extern int unaligned_enabled;
 #endif
 
-#ifdef CONFIG_ARCH_S390
+#ifdef CONFIG_S390
 #ifdef CONFIG_MATHEMU
 extern int sysctl_ieee_emulation_warnings;
 #endif
@@ -397,8 +398,8 @@
 	{
 		.ctl_name	= KERN_HOTPLUG,
 		.procname	= "hotplug",
-		.data		= &hotplug_path,
-		.maxlen		= HOTPLUG_PATH_LEN,
+		.data		= &uevent_helper,
+		.maxlen		= UEVENT_HELPER_PATH_LEN,
 		.mode		= 0644,
 		.proc_handler	= &proc_dostring,
 		.strategy	= &sysctl_string,
@@ -544,7 +545,7 @@
 		.extra1		= &minolduid,
 		.extra2		= &maxolduid,
 	},
-#ifdef CONFIG_ARCH_S390
+#ifdef CONFIG_S390
 #ifdef CONFIG_MATHEMU
 	{
 		.ctl_name	= KERN_IEEE_EMULATION_WARNINGS,
@@ -646,7 +647,7 @@
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
-#if defined(CONFIG_ARCH_S390)
+#if defined(CONFIG_S390)
 	{
 		.ctl_name	= KERN_SPIN_RETRY,
 		.procname	= "spin_retry",
@@ -777,6 +778,15 @@
 		.strategy	= &sysctl_intvec,
 	},
 	{
+		.ctl_name	= VM_DROP_PAGECACHE,
+		.procname	= "drop_caches",
+		.data		= &sysctl_drop_caches,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= drop_caches_sysctl_handler,
+		.strategy	= &sysctl_intvec,
+	},
+	{
 		.ctl_name	= VM_MIN_FREE_KBYTES,
 		.procname	= "min_free_kbytes",
 		.data		= &min_free_kbytes,
@@ -786,6 +796,16 @@
 		.strategy	= &sysctl_intvec,
 		.extra1		= &zero,
 	},
+	{
+		.ctl_name	= VM_PERCPU_PAGELIST_FRACTION,
+		.procname	= "percpu_pagelist_fraction",
+		.data		= &percpu_pagelist_fraction,
+		.maxlen		= sizeof(percpu_pagelist_fraction),
+		.mode		= 0644,
+		.proc_handler	= &percpu_pagelist_fraction_sysctl_handler,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &min_percpu_pagelist_fract,
+	},
 #ifdef CONFIG_MMU
 	{
 		.ctl_name	= VM_MAX_MAP_COUNT,
@@ -2192,29 +2212,32 @@
 		  void __user *oldval, size_t __user *oldlenp,
 		  void __user *newval, size_t newlen, void **context)
 {
-	size_t l, len;
-	
 	if (!table->data || !table->maxlen) 
 		return -ENOTDIR;
 	
 	if (oldval && oldlenp) {
-		if (get_user(len, oldlenp))
+		size_t bufsize;
+		if (get_user(bufsize, oldlenp))
 			return -EFAULT;
-		if (len) {
-			l = strlen(table->data);
-			if (len > l) len = l;
-			if (len >= table->maxlen)
+		if (bufsize) {
+			size_t len = strlen(table->data), copied;
+
+			/* This shouldn't trigger for a well-formed sysctl */
+			if (len > table->maxlen)
 				len = table->maxlen;
-			if(copy_to_user(oldval, table->data, len))
+
+			/* Copy up to a max of bufsize-1 bytes of the string */
+			copied = (len >= bufsize) ? bufsize - 1 : len;
+
+			if (copy_to_user(oldval, table->data, copied) ||
+			    put_user(0, (char __user *)(oldval + copied)))
 				return -EFAULT;
-			if(put_user(0, ((char __user *) oldval) + len))
-				return -EFAULT;
-			if(put_user(len, oldlenp))
+			if (put_user(len, oldlenp))
 				return -EFAULT;
 		}
 	}
 	if (newval && newlen) {
-		len = newlen;
+		size_t len = newlen;
 		if (len > table->maxlen)
 			len = table->maxlen;
 		if(copy_from_user(table->data, newval, len))
@@ -2223,7 +2246,7 @@
 			len--;
 		((char *) table->data)[len] = 0;
 	}
-	return 0;
+	return 1;
 }
 
 /*
diff --git a/kernel/time.c b/kernel/time.c
index 245d595..b94bfa8 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -561,6 +561,28 @@
 EXPORT_SYMBOL_GPL(getnstimeofday);
 #endif
 
+void getnstimestamp(struct timespec *ts)
+{
+	unsigned int seq;
+	struct timespec wall2mono;
+
+	/* synchronize with settimeofday() changes */
+	do {
+		seq = read_seqbegin(&xtime_lock);
+		getnstimeofday(ts);
+		wall2mono = wall_to_monotonic;
+	} while(unlikely(read_seqretry(&xtime_lock, seq)));
+
+	/* adjust to monotonicaly-increasing values */
+	ts->tv_sec += wall2mono.tv_sec;
+	ts->tv_nsec += wall2mono.tv_nsec;
+	while (unlikely(ts->tv_nsec >= NSEC_PER_SEC)) {
+		ts->tv_nsec -= NSEC_PER_SEC;
+		ts->tv_sec++;
+	}
+}
+EXPORT_SYMBOL_GPL(getnstimestamp);
+
 #if (BITS_PER_LONG < 64)
 u64 get_jiffies_64(void)
 {
diff --git a/kernel/timer.c b/kernel/timer.c
index fd74268..074b4bd 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -33,6 +33,7 @@
 #include <linux/posix-timers.h>
 #include <linux/cpu.h>
 #include <linux/syscalls.h>
+#include <linux/delay.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 42df83d..82c4fa7 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -29,7 +29,8 @@
 #include <linux/kthread.h>
 
 /*
- * The per-CPU workqueue (if single thread, we always use cpu 0's).
+ * The per-CPU workqueue (if single thread, we always use the first
+ * 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
@@ -69,6 +70,8 @@
 static DEFINE_SPINLOCK(workqueue_lock);
 static LIST_HEAD(workqueues);
 
+static int singlethread_cpu;
+
 /* If it's single threaded, it isn't in the list of workqueues. */
 static inline int is_single_threaded(struct workqueue_struct *wq)
 {
@@ -102,7 +105,7 @@
 
 	if (!test_and_set_bit(0, &work->pending)) {
 		if (unlikely(is_single_threaded(wq)))
-			cpu = 0;
+			cpu = singlethread_cpu;
 		BUG_ON(!list_empty(&work->entry));
 		__queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
 		ret = 1;
@@ -118,7 +121,7 @@
 	int cpu = smp_processor_id();
 
 	if (unlikely(is_single_threaded(wq)))
-		cpu = 0;
+		cpu = singlethread_cpu;
 
 	__queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work);
 }
@@ -266,8 +269,8 @@
 	might_sleep();
 
 	if (is_single_threaded(wq)) {
-		/* Always use cpu 0's area. */
-		flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, 0));
+		/* Always use first cpu's area. */
+		flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, singlethread_cpu));
 	} else {
 		int cpu;
 
@@ -315,12 +318,17 @@
 		return NULL;
 
 	wq->cpu_wq = alloc_percpu(struct cpu_workqueue_struct);
+	if (!wq->cpu_wq) {
+		kfree(wq);
+		return NULL;
+	}
+
 	wq->name = name;
 	/* We don't need the distraction of CPUs appearing and vanishing. */
 	lock_cpu_hotplug();
 	if (singlethread) {
 		INIT_LIST_HEAD(&wq->list);
-		p = create_workqueue_thread(wq, 0);
+		p = create_workqueue_thread(wq, singlethread_cpu);
 		if (!p)
 			destroy = 1;
 		else
@@ -374,7 +382,7 @@
 	/* We don't need the distraction of CPUs appearing and vanishing. */
 	lock_cpu_hotplug();
 	if (is_single_threaded(wq))
-		cleanup_workqueue_thread(wq, 0);
+		cleanup_workqueue_thread(wq, singlethread_cpu);
 	else {
 		for_each_online_cpu(cpu)
 			cleanup_workqueue_thread(wq, cpu);
@@ -419,6 +427,25 @@
 	return ret;
 }
 
+int schedule_on_each_cpu(void (*func) (void *info), void *info)
+{
+	int cpu;
+	struct work_struct *work;
+
+	work = kmalloc(NR_CPUS * sizeof(struct work_struct), GFP_KERNEL);
+
+	if (!work)
+		return -ENOMEM;
+	for_each_online_cpu(cpu) {
+		INIT_WORK(work + cpu, func, info);
+		__queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu),
+				work + cpu);
+	}
+	flush_workqueue(keventd_wq);
+	kfree(work);
+	return 0;
+}
+
 void flush_scheduled_work(void)
 {
 	flush_workqueue(keventd_wq);
@@ -543,6 +570,7 @@
 
 void init_workqueues(void)
 {
+	singlethread_cpu = first_cpu(cpu_possible_map);
 	hotcpu_notifier(workqueue_cpu_callback, 0);
 	keventd_wq = create_workqueue("events");
 	BUG_ON(!keventd_wq);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 156822e..c48260f 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -32,7 +32,7 @@
 config LOG_BUF_SHIFT
 	int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" if DEBUG_KERNEL
 	range 12 21
-	default 17 if ARCH_S390
+	default 17 if S390
 	default 16 if X86_NUMAQ || IA64
 	default 15 if SMP
 	default 14
@@ -79,7 +79,7 @@
 
 config DEBUG_SLAB
 	bool "Debug memory allocations"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && SLAB
 	help
 	  Say Y here to have the kernel do limited verification on memory
 	  allocation as well as poisoning memory on free to catch use of freed
@@ -172,7 +172,8 @@
 	bool "Debug VM"
 	depends on DEBUG_KERNEL
 	help
-	  Enable this to debug the virtual-memory system.
+	  Enable this to turn on extended checks in the virtual-memory system
+          that may impact performance.
 
 	  If unsure, say N.
 
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 23d3b11..48e7083 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -519,7 +519,7 @@
  *
  * Map the bit at position @pos in @buf (of length @bits) to the
  * ordinal of which set bit it is.  If it is not set or if @pos
- * is not a valid bit position, map to zero (0).
+ * is not a valid bit position, map to -1.
  *
  * If for example, just bits 4 through 7 are set in @buf, then @pos
  * values 4 through 7 will get mapped to 0 through 3, respectively,
@@ -531,18 +531,19 @@
  */
 static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits)
 {
-	int ord = 0;
+	int i, ord;
 
-	if (pos >= 0 && pos < bits) {
-		int i;
+	if (pos < 0 || pos >= bits || !test_bit(pos, buf))
+		return -1;
 
-		for (i = find_first_bit(buf, bits);
-		     i < pos;
-		     i = find_next_bit(buf, bits, i + 1))
-	     		ord++;
-		if (i > pos)
-			ord = 0;
+	i = find_first_bit(buf, bits);
+	ord = 0;
+	while (i < pos) {
+		i = find_next_bit(buf, bits, i + 1);
+	     	ord++;
 	}
+	BUG_ON(i != pos);
+
 	return ord;
 }
 
@@ -553,11 +554,12 @@
  *	@bits: number of valid bit positions in @buf
  *
  * Map the ordinal offset of bit @ord in @buf to its position in @buf.
- * If @ord is not the ordinal offset of a set bit in @buf, map to zero (0).
+ * Value of @ord should be in range 0 <= @ord < weight(buf), else
+ * results are undefined.
  *
  * If for example, just bits 4 through 7 are set in @buf, then @ord
  * values 0 through 3 will get mapped to 4 through 7, respectively,
- * and all other @ord valuds will get mapped to 0.  When @ord value 3
+ * and all other @ord values return undefined values.  When @ord value 3
  * gets mapped to (returns) @pos value 7 in this example, that means
  * that the 3rd set bit (starting with 0th) is at position 7 in @buf.
  *
@@ -583,8 +585,8 @@
 
 /**
  * bitmap_remap - Apply map defined by a pair of bitmaps to another bitmap
- *	@src: subset to be remapped
  *	@dst: remapped result
+ *	@src: subset to be remapped
  *	@old: defines domain of map
  *	@new: defines range of map
  *	@bits: number of bits in each of these bitmaps
@@ -596,49 +598,42 @@
  * weight of @old, map the position of the n-th set bit in @old to
  * the position of the m-th set bit in @new, where m == n % w.
  *
- * If either of the @old and @new bitmaps are empty, or if@src and @dst
- * point to the same location, then this routine does nothing.
+ * If either of the @old and @new bitmaps are empty, or if @src and
+ * @dst point to the same location, then this routine copies @src
+ * to @dst.
  *
- * The positions of unset bits in @old are mapped to the position of
- * the first set bit in @new.
+ * The positions of unset bits in @old are mapped to themselves
+ * (the identify map).
  *
  * Apply the above specified mapping to @src, placing the result in
  * @dst, clearing any bits previously set in @dst.
  *
- * The resulting value of @dst will have either the same weight as
- * @src, or less weight in the general case that the mapping wasn't
- * injective due to the weight of @new being less than that of @old.
- * The resulting value of @dst will never have greater weight than
- * that of @src, except perhaps in the case that one of the above
- * conditions was not met and this routine just returned.
- *
  * For example, lets say that @old has bits 4 through 7 set, and
  * @new has bits 12 through 15 set.  This defines the mapping of bit
  * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
- * bit positions to 12 (the first set bit in @new.  So if say @src
- * comes into this routine with bits 1, 5 and 7 set, then @dst should
- * leave with bits 12, 13 and 15 set.
+ * bit positions unchanged.  So if say @src comes into this routine
+ * with bits 1, 5 and 7 set, then @dst should leave with bits 1,
+ * 13 and 15 set.
  */
 void bitmap_remap(unsigned long *dst, const unsigned long *src,
 		const unsigned long *old, const unsigned long *new,
 		int bits)
 {
-	int s;
+	int oldbit, w;
 
-	if (bitmap_weight(old, bits) == 0)
-		return;
-	if (bitmap_weight(new, bits) == 0)
-		return;
 	if (dst == src)		/* following doesn't handle inplace remaps */
 		return;
-
 	bitmap_zero(dst, bits);
-	for (s = find_first_bit(src, bits);
-	     s < bits;
-	     s = find_next_bit(src, bits, s + 1)) {
-	     	int x = bitmap_pos_to_ord(old, s, bits);
-		int y = bitmap_ord_to_pos(new, x, bits);
-		set_bit(y, dst);
+
+	w = bitmap_weight(new, bits);
+	for (oldbit = find_first_bit(src, bits);
+	     oldbit < bits;
+	     oldbit = find_next_bit(src, bits, oldbit + 1)) {
+	     	int n = bitmap_pos_to_ord(old, oldbit, bits);
+		if (n < 0 || w == 0)
+			set_bit(oldbit, dst);	/* identity map */
+		else
+			set_bit(bitmap_ord_to_pos(new, n % w, bits), dst);
 	}
 }
 EXPORT_SYMBOL(bitmap_remap);
@@ -657,8 +652,8 @@
  * weight of @old, map the position of the n-th set bit in @old to
  * the position of the m-th set bit in @new, where m == n % w.
  *
- * The positions of unset bits in @old are mapped to the position of
- * the first set bit in @new.
+ * The positions of unset bits in @old are mapped to themselves
+ * (the identify map).
  *
  * Apply the above specified mapping to bit position @oldbit, returning
  * the new bit position.
@@ -666,14 +661,18 @@
  * For example, lets say that @old has bits 4 through 7 set, and
  * @new has bits 12 through 15 set.  This defines the mapping of bit
  * position 4 to 12, 5 to 13, 6 to 14 and 7 to 15, and of all other
- * bit positions to 12 (the first set bit in @new.  So if say @oldbit
- * is 5, then this routine returns 13.
+ * bit positions unchanged.  So if say @oldbit is 5, then this routine
+ * returns 13.
  */
 int bitmap_bitremap(int oldbit, const unsigned long *old,
 				const unsigned long *new, int bits)
 {
-	int x = bitmap_pos_to_ord(old, oldbit, bits);
-	return bitmap_ord_to_pos(new, x, bits);
+	int w = bitmap_weight(new, bits);
+	int n = bitmap_pos_to_ord(old, oldbit, bits);
+	if (n < 0 || w == 0)
+		return oldbit;
+	else
+		return bitmap_ord_to_pos(new, n % w, bits);
 }
 EXPORT_SYMBOL(bitmap_bitremap);
 
diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c
index 305a966..a65c314 100644
--- a/lib/dec_and_lock.c
+++ b/lib/dec_and_lock.c
@@ -1,47 +1,11 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
-#include <asm/system.h>
 
-#ifdef __HAVE_ARCH_CMPXCHG
 /*
  * This is an implementation of the notion of "decrement a
  * reference count, and return locked if it decremented to zero".
  *
- * This implementation can be used on any architecture that
- * has a cmpxchg, and where atomic->value is an int holding
- * the value of the atomic (i.e. the high bits aren't used
- * for a lock or anything like that).
- */
-int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
-{
-	int counter;
-	int newcount;
-
-	for (;;) {
-		counter = atomic_read(atomic);
-		newcount = counter - 1;
-		if (!newcount)
-			break;		/* do it the slow way */
-
-		newcount = cmpxchg(&atomic->counter, counter, newcount);
-		if (newcount == counter)
-			return 0;
-	}
-
-	spin_lock(lock);
-	if (atomic_dec_and_test(atomic))
-		return 1;
-	spin_unlock(lock);
-	return 0;
-}
-#else
-/*
- * This is an architecture-neutral, but slow,
- * implementation of the notion of "decrement
- * a reference count, and return locked if it
- * decremented to zero".
- *
  * NOTE NOTE NOTE! This is _not_ equivalent to
  *
  *	if (atomic_dec_and_test(&atomic)) {
@@ -52,21 +16,20 @@
  *
  * because the spin-lock and the decrement must be
  * "atomic".
- *
- * This slow version gets the spinlock unconditionally,
- * and releases it if it isn't needed. Architectures
- * are encouraged to come up with better approaches,
- * this is trivially done efficiently using a load-locked
- * store-conditional approach, for example.
  */
 int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
 {
+#ifdef CONFIG_SMP
+	/* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */
+	if (atomic_add_unless(atomic, -1, 1))
+		return 0;
+#endif
+	/* Otherwise do it the slow way */
 	spin_lock(lock);
 	if (atomic_dec_and_test(atomic))
 		return 1;
 	spin_unlock(lock);
 	return 0;
 }
-#endif
 
 EXPORT_SYMBOL(_atomic_dec_and_lock);
diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c
index d08302d..c05b4b1 100644
--- a/lib/find_next_bit.c
+++ b/lib/find_next_bit.c
@@ -10,6 +10,7 @@
  */
 
 #include <linux/bitops.h>
+#include <linux/module.h>
 
 int find_next_bit(const unsigned long *addr, int size, int offset)
 {
@@ -53,3 +54,5 @@
 
 	return offset;
 }
+
+EXPORT_SYMBOL(find_next_bit);
diff --git a/lib/genalloc.c b/lib/genalloc.c
index d6d30d2e..9ce0a6a 100644
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -95,12 +95,10 @@
 	if (size > max_chunk_size)
 		return 0;
 
-	i = 0;
-
 	size = max(size, 1 << ALLOC_MIN_SHIFT);
-	s = roundup_pow_of_two(size);
-
-	j = i;
+	i = fls(size - 1);
+	s = 1 << i;
+	j = i -= ALLOC_MIN_SHIFT;
 
 	spin_lock_irqsave(&poolp->lock, flags);
 	while (!h[j].next) {
@@ -153,10 +151,10 @@
 	if (size > max_chunk_size)
 		return;
 
-	i = 0;
-
 	size = max(size, 1 << ALLOC_MIN_SHIFT);
-	s = roundup_pow_of_two(size);
+	i = fls(size - 1);
+	s = 1 << i;
+	i -= ALLOC_MIN_SHIFT;
 
 	a = ptr;
 
diff --git a/lib/klist.c b/lib/klist.c
index bb2f355..9c94f0b 100644
--- a/lib/klist.c
+++ b/lib/klist.c
@@ -199,6 +199,8 @@
 	i->i_klist = k;
 	i->i_head = &k->k_list;
 	i->i_cur = n;
+	if (n)
+		kref_get(&n->n_ref);
 }
 
 EXPORT_SYMBOL_GPL(klist_iter_init_node);
diff --git a/lib/kobject.c b/lib/kobject.c
index a181abe..7a0e680 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -207,7 +207,7 @@
 			       kobject_name(kobj),error);
 			dump_stack();
 		} else
-			kobject_hotplug(kobj, KOBJ_ADD);
+			kobject_uevent(kobj, KOBJ_ADD);
 	} else
 		error = -EINVAL;
 	return error;
@@ -312,7 +312,7 @@
 void kobject_unregister(struct kobject * kobj)
 {
 	pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
-	kobject_hotplug(kobj, KOBJ_REMOVE);
+	kobject_uevent(kobj, KOBJ_REMOVE);
 	kobject_del(kobj);
 	kobject_put(kobj);
 }
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 3ab3754..f56e27a 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -19,14 +19,16 @@
 #include <linux/skbuff.h>
 #include <linux/netlink.h>
 #include <linux/string.h>
-#include <linux/kobject_uevent.h>
 #include <linux/kobject.h>
 #include <net/sock.h>
 
-#define BUFFER_SIZE	1024	/* buffer for the hotplug env */
+#define BUFFER_SIZE	1024	/* buffer for the variables */
 #define NUM_ENVP	32	/* number of env pointers */
 
-#if defined(CONFIG_KOBJECT_UEVENT) || defined(CONFIG_HOTPLUG)
+#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
+static DEFINE_SPINLOCK(sequence_lock);
+static struct sock *uevent_sock;
+
 static char *action_to_string(enum kobject_action action)
 {
 	switch (action) {
@@ -36,10 +38,6 @@
 		return "remove";
 	case KOBJ_CHANGE:
 		return "change";
-	case KOBJ_MOUNT:
-		return "mount";
-	case KOBJ_UMOUNT:
-		return "umount";
 	case KOBJ_OFFLINE:
 		return "offline";
 	case KOBJ_ONLINE:
@@ -48,306 +46,183 @@
 		return NULL;
 	}
 }
-#endif
-
-#ifdef CONFIG_KOBJECT_UEVENT
-static struct sock *uevent_sock;
 
 /**
- * send_uevent - notify userspace by sending event through netlink socket
+ * kobject_uevent - notify userspace by ending an uevent
  *
- * @signal: signal name
- * @obj: object path (kobject)
- * @envp: possible hotplug environment to pass with the message
- * @gfp_mask:
- */
-static int send_uevent(const char *signal, const char *obj,
-		       char **envp, gfp_t gfp_mask)
-{
-	struct sk_buff *skb;
-	char *pos;
-	int len;
-
-	if (!uevent_sock)
-		return -EIO;
-
-	len = strlen(signal) + 1;
-	len += strlen(obj) + 1;
-
-	/* allocate buffer with the maximum possible message size */
-	skb = alloc_skb(len + BUFFER_SIZE, gfp_mask);
-	if (!skb)
-		return -ENOMEM;
-
-	pos = skb_put(skb, len);
-	sprintf(pos, "%s@%s", signal, obj);
-
-	/* copy the environment key by key to our continuous buffer */
-	if (envp) {
-		int i;
-
-		for (i = 2; envp[i]; i++) {
-			len = strlen(envp[i]) + 1;
-			pos = skb_put(skb, len);
-			strcpy(pos, envp[i]);
-		}
-	}
-
-	NETLINK_CB(skb).dst_group = 1;
-	return netlink_broadcast(uevent_sock, skb, 0, 1, gfp_mask);
-}
-
-static int do_kobject_uevent(struct kobject *kobj, enum kobject_action action, 
-			     struct attribute *attr, gfp_t gfp_mask)
-{
-	char *path;
-	char *attrpath;
-	char *signal;
-	int len;
-	int rc = -ENOMEM;
-
-	path = kobject_get_path(kobj, gfp_mask);
-	if (!path)
-		return -ENOMEM;
-
-	signal = action_to_string(action);
-	if (!signal)
-		return -EINVAL;
-
-	if (attr) {
-		len = strlen(path);
-		len += strlen(attr->name) + 2;
-		attrpath = kmalloc(len, gfp_mask);
-		if (!attrpath)
-			goto exit;
-		sprintf(attrpath, "%s/%s", path, attr->name);
-		rc = send_uevent(signal, attrpath, NULL, gfp_mask);
-		kfree(attrpath);
-	} else
-		rc = send_uevent(signal, path, NULL, gfp_mask);
-
-exit:
-	kfree(path);
-	return rc;
-}
-
-/**
- * kobject_uevent - notify userspace by sending event through netlink socket
- * 
- * @signal: signal name
- * @kobj: struct kobject that the event is happening to
- * @attr: optional struct attribute the event belongs to
- */
-int kobject_uevent(struct kobject *kobj, enum kobject_action action,
-		   struct attribute *attr)
-{
-	return do_kobject_uevent(kobj, action, attr, GFP_KERNEL);
-}
-EXPORT_SYMBOL_GPL(kobject_uevent);
-
-int kobject_uevent_atomic(struct kobject *kobj, enum kobject_action action,
-			  struct attribute *attr)
-{
-	return do_kobject_uevent(kobj, action, attr, GFP_ATOMIC);
-}
-EXPORT_SYMBOL_GPL(kobject_uevent_atomic);
-
-static int __init kobject_uevent_init(void)
-{
-	uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL,
-					    THIS_MODULE);
-
-	if (!uevent_sock) {
-		printk(KERN_ERR
-		       "kobject_uevent: unable to create netlink socket!\n");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
-postcore_initcall(kobject_uevent_init);
-
-#else
-static inline int send_uevent(const char *signal, const char *obj,
-			      char **envp, int gfp_mask)
-{
-	return 0;
-}
-
-#endif /* CONFIG_KOBJECT_UEVENT */
-
-
-#ifdef CONFIG_HOTPLUG
-char hotplug_path[HOTPLUG_PATH_LEN] = "/sbin/hotplug";
-u64 hotplug_seqnum;
-static DEFINE_SPINLOCK(sequence_lock);
-
-/**
- * kobject_hotplug - notify userspace by executing /sbin/hotplug
- *
- * @action: action that is happening (usually "ADD" or "REMOVE")
+ * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE)
  * @kobj: struct kobject that the action is happening to
  */
-void kobject_hotplug(struct kobject *kobj, enum kobject_action action)
+void kobject_uevent(struct kobject *kobj, enum kobject_action action)
 {
-	char *argv [3];
-	char **envp = NULL;
-	char *buffer = NULL;
-	char *seq_buff;
+	char **envp;
+	char *buffer;
 	char *scratch;
+	const char *action_string;
+	const char *devpath = NULL;
+	const char *subsystem;
+	struct kobject *top_kobj;
+	struct kset *kset;
+	struct kset_uevent_ops *uevent_ops;
+	u64 seq;
+	char *seq_buff;
 	int i = 0;
 	int retval;
-	char *kobj_path = NULL;
-	const char *name = NULL;
-	char *action_string;
-	u64 seq;
-	struct kobject *top_kobj = kobj;
-	struct kset *kset;
-	static struct kset_hotplug_ops null_hotplug_ops;
-	struct kset_hotplug_ops *hotplug_ops = &null_hotplug_ops;
 
-	/* If this kobj does not belong to a kset,
-	   try to find a parent that does. */
-	if (!top_kobj->kset && top_kobj->parent) {
-		do {
-			top_kobj = top_kobj->parent;
-		} while (!top_kobj->kset && top_kobj->parent);
-	}
-
-	if (top_kobj->kset)
-		kset = top_kobj->kset;
-	else
-		return;
-
-	if (kset->hotplug_ops)
-		hotplug_ops = kset->hotplug_ops;
-
-	/* If the kset has a filter operation, call it.
-	   Skip the event, if the filter returns zero. */
-	if (hotplug_ops->filter) {
-		if (!hotplug_ops->filter(kset, kobj))
-			return;
-	}
-
-	pr_debug ("%s\n", __FUNCTION__);
+	pr_debug("%s\n", __FUNCTION__);
 
 	action_string = action_to_string(action);
 	if (!action_string)
 		return;
 
-	envp = kmalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
+	/* search the kset we belong to */
+	top_kobj = kobj;
+	if (!top_kobj->kset && top_kobj->parent) {
+		do {
+			top_kobj = top_kobj->parent;
+		} while (!top_kobj->kset && top_kobj->parent);
+	}
+	if (!top_kobj->kset)
+		return;
+
+	kset = top_kobj->kset;
+	uevent_ops = kset->uevent_ops;
+
+	/*  skip the event, if the filter returns zero. */
+	if (uevent_ops && uevent_ops->filter)
+		if (!uevent_ops->filter(kset, kobj))
+			return;
+
+	/* environment index */
+	envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
 	if (!envp)
 		return;
-	memset (envp, 0x00, NUM_ENVP * sizeof (char *));
 
+	/* environment values */
 	buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
 	if (!buffer)
 		goto exit;
 
-	if (hotplug_ops->name)
-		name = hotplug_ops->name(kset, kobj);
-	if (name == NULL)
-		name = kobject_name(&kset->kobj);
-
-	argv [0] = hotplug_path;
-	argv [1] = (char *)name; /* won't be changed but 'const' has to go */
-	argv [2] = NULL;
-
-	/* minimal command environment */
-	envp [i++] = "HOME=/";
-	envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-
-	scratch = buffer;
-
-	envp [i++] = scratch;
-	scratch += sprintf(scratch, "ACTION=%s", action_string) + 1;
-
-	kobj_path = kobject_get_path(kobj, GFP_KERNEL);
-	if (!kobj_path)
+	/* complete object path */
+	devpath = kobject_get_path(kobj, GFP_KERNEL);
+	if (!devpath)
 		goto exit;
 
-	envp [i++] = scratch;
-	scratch += sprintf (scratch, "DEVPATH=%s", kobj_path) + 1;
+	/* originating subsystem */
+	if (uevent_ops && uevent_ops->name)
+		subsystem = uevent_ops->name(kset, kobj);
+	else
+		subsystem = kobject_name(&kset->kobj);
 
-	envp [i++] = scratch;
-	scratch += sprintf(scratch, "SUBSYSTEM=%s", name) + 1;
+	/* event environemnt for helper process only */
+	envp[i++] = "HOME=/";
+	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
 
-	/* reserve space for the sequence,
-	 * put the real one in after the hotplug call */
+	/* default keys */
+	scratch = buffer;
+	envp [i++] = scratch;
+	scratch += sprintf(scratch, "ACTION=%s", action_string) + 1;
+	envp [i++] = scratch;
+	scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;
+	envp [i++] = scratch;
+	scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;
+
+	/* just reserve the space, overwrite it after kset call has returned */
 	envp[i++] = seq_buff = scratch;
 	scratch += strlen("SEQNUM=18446744073709551616") + 1;
 
-	if (hotplug_ops->hotplug) {
-		/* have the kset specific function add its stuff */
-		retval = hotplug_ops->hotplug (kset, kobj,
+	/* let the kset specific function add its stuff */
+	if (uevent_ops && uevent_ops->uevent) {
+		retval = uevent_ops->uevent(kset, kobj,
 				  &envp[i], NUM_ENVP - i, scratch,
 				  BUFFER_SIZE - (scratch - buffer));
 		if (retval) {
-			pr_debug ("%s - hotplug() returned %d\n",
+			pr_debug ("%s - uevent() returned %d\n",
 				  __FUNCTION__, retval);
 			goto exit;
 		}
 	}
 
+	/* we will send an event, request a new sequence number */
 	spin_lock(&sequence_lock);
-	seq = ++hotplug_seqnum;
+	seq = ++uevent_seqnum;
 	spin_unlock(&sequence_lock);
 	sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq);
 
-	pr_debug ("%s: %s %s seq=%llu %s %s %s %s %s\n",
-		  __FUNCTION__, argv[0], argv[1], (unsigned long long)seq,
-		  envp[0], envp[1], envp[2], envp[3], envp[4]);
+	/* send netlink message */
+	if (uevent_sock) {
+		struct sk_buff *skb;
+		size_t len;
 
-	send_uevent(action_string, kobj_path, envp, GFP_KERNEL);
+		/* allocate message with the maximum possible size */
+		len = strlen(action_string) + strlen(devpath) + 2;
+		skb = alloc_skb(len + BUFFER_SIZE, GFP_KERNEL);
+		if (skb) {
+			/* add header */
+			scratch = skb_put(skb, len);
+			sprintf(scratch, "%s@%s", action_string, devpath);
 
-	if (!hotplug_path[0])
-		goto exit;
+			/* copy keys to our continuous event payload buffer */
+			for (i = 2; envp[i]; i++) {
+				len = strlen(envp[i]) + 1;
+				scratch = skb_put(skb, len);
+				strcpy(scratch, envp[i]);
+			}
 
-	retval = call_usermodehelper (argv[0], argv, envp, 0);
-	if (retval)
-		pr_debug ("%s - call_usermodehelper returned %d\n",
-			  __FUNCTION__, retval);
+			NETLINK_CB(skb).dst_group = 1;
+			netlink_broadcast(uevent_sock, skb, 0, 1, GFP_KERNEL);
+		}
+	}
+
+	/* call uevent_helper, usually only enabled during early boot */
+	if (uevent_helper[0]) {
+		char *argv [3];
+
+		argv [0] = uevent_helper;
+		argv [1] = (char *)subsystem;
+		argv [2] = NULL;
+		call_usermodehelper (argv[0], argv, envp, 0);
+	}
 
 exit:
-	kfree(kobj_path);
+	kfree(devpath);
 	kfree(buffer);
 	kfree(envp);
 	return;
 }
-EXPORT_SYMBOL(kobject_hotplug);
+EXPORT_SYMBOL_GPL(kobject_uevent);
 
 /**
- * add_hotplug_env_var - helper for creating hotplug environment variables
+ * add_uevent_var - helper for creating event variables
  * @envp: Pointer to table of environment variables, as passed into
- * hotplug() method.
+ * uevent() method.
  * @num_envp: Number of environment variable slots available, as
- * passed into hotplug() method.
+ * passed into uevent() method.
  * @cur_index: Pointer to current index into @envp.  It should be
- * initialized to 0 before the first call to add_hotplug_env_var(),
+ * initialized to 0 before the first call to add_uevent_var(),
  * and will be incremented on success.
  * @buffer: Pointer to buffer for environment variables, as passed
- * into hotplug() method.
- * @buffer_size: Length of @buffer, as passed into hotplug() method.
+ * into uevent() method.
+ * @buffer_size: Length of @buffer, as passed into uevent() method.
  * @cur_len: Pointer to current length of space used in @buffer.
  * Should be initialized to 0 before the first call to
- * add_hotplug_env_var(), and will be incremented on success.
+ * add_uevent_var(), and will be incremented on success.
  * @format: Format for creating environment variable (of the form
  * "XXX=%x") for snprintf().
  *
  * Returns 0 if environment variable was added successfully or -ENOMEM
  * if no space was available.
  */
-int add_hotplug_env_var(char **envp, int num_envp, int *cur_index,
-			char *buffer, int buffer_size, int *cur_len,
-			const char *format, ...)
+int add_uevent_var(char **envp, int num_envp, int *cur_index,
+		   char *buffer, int buffer_size, int *cur_len,
+		   const char *format, ...)
 {
 	va_list args;
 
 	/*
 	 * We check against num_envp - 1 to make sure there is at
-	 * least one slot left after we return, since the hotplug
-	 * method needs to set the last slot to NULL.
+	 * least one slot left after we return, since kobject_uevent()
+	 * needs to set the last slot to NULL.
 	 */
 	if (*cur_index >= num_envp - 1)
 		return -ENOMEM;
@@ -366,6 +241,22 @@
 	(*cur_index)++;
 	return 0;
 }
-EXPORT_SYMBOL(add_hotplug_env_var);
+EXPORT_SYMBOL_GPL(add_uevent_var);
+
+static int __init kobject_uevent_init(void)
+{
+	uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL,
+					    THIS_MODULE);
+
+	if (!uevent_sock) {
+		printk(KERN_ERR
+		       "kobject_uevent: unable to create netlink socket!\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+postcore_initcall(kobject_uevent_init);
 
 #endif /* CONFIG_HOTPLUG */
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 88511c3..c0bd4a9 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -137,18 +137,31 @@
 
 static inline void tag_set(struct radix_tree_node *node, int tag, int offset)
 {
-	if (!test_bit(offset, &node->tags[tag][0]))
-		__set_bit(offset, &node->tags[tag][0]);
+	__set_bit(offset, node->tags[tag]);
 }
 
 static inline void tag_clear(struct radix_tree_node *node, int tag, int offset)
 {
-	__clear_bit(offset, &node->tags[tag][0]);
+	__clear_bit(offset, node->tags[tag]);
 }
 
 static inline int tag_get(struct radix_tree_node *node, int tag, int offset)
 {
-	return test_bit(offset, &node->tags[tag][0]);
+	return test_bit(offset, node->tags[tag]);
+}
+
+/*
+ * Returns 1 if any slot in the node has this tag set.
+ * Otherwise returns 0.
+ */
+static inline int any_tag_set(struct radix_tree_node *node, int tag)
+{
+	int idx;
+	for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
+		if (node->tags[tag][idx])
+			return 1;
+	}
+	return 0;
 }
 
 /*
@@ -185,15 +198,9 @@
 	 * into the newly-pushed top-level node(s)
 	 */
 	for (tag = 0; tag < RADIX_TREE_TAGS; tag++) {
-		int idx;
-
 		tags[tag] = 0;
-		for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
-			if (root->rnode->tags[tag][idx]) {
-				tags[tag] = 1;
-				break;
-			}
-		}
+		if (any_tag_set(root->rnode, tag))
+			tags[tag] = 1;
 	}
 
 	do {
@@ -246,7 +253,7 @@
 	shift = (height-1) * RADIX_TREE_MAP_SHIFT;
 
 	offset = 0;			/* uninitialised var warning */
-	while (height > 0) {
+	do {
 		if (slot == NULL) {
 			/* Have to add a child node.  */
 			if (!(slot = radix_tree_node_alloc(root)))
@@ -264,18 +271,16 @@
 		slot = node->slots[offset];
 		shift -= RADIX_TREE_MAP_SHIFT;
 		height--;
-	}
+	} while (height > 0);
 
 	if (slot != NULL)
 		return -EEXIST;
 
-	if (node) {
-		node->count++;
-		node->slots[offset] = item;
-		BUG_ON(tag_get(node, 0, offset));
-		BUG_ON(tag_get(node, 1, offset));
-	} else
-		root->rnode = item;
+	BUG_ON(!node);
+	node->count++;
+	node->slots[offset] = item;
+	BUG_ON(tag_get(node, 0, offset));
+	BUG_ON(tag_get(node, 1, offset));
 
 	return 0;
 }
@@ -367,7 +372,8 @@
 		int offset;
 
 		offset = (index >> shift) & RADIX_TREE_MAP_MASK;
-		tag_set(slot, tag, offset);
+		if (!tag_get(slot, tag, offset))
+			tag_set(slot, tag, offset);
 		slot = slot->slots[offset];
 		BUG_ON(slot == NULL);
 		shift -= RADIX_TREE_MAP_SHIFT;
@@ -427,13 +433,11 @@
 		goto out;
 
 	do {
-		int idx;
-
+		if (!tag_get(pathp->node, tag, pathp->offset))
+			goto out;
 		tag_clear(pathp->node, tag, pathp->offset);
-		for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
-			if (pathp->node->tags[tag][idx])
-				goto out;
-		}
+		if (any_tag_set(pathp->node, tag))
+			goto out;
 		pathp--;
 	} while (pathp->node);
 out:
@@ -674,6 +678,29 @@
 EXPORT_SYMBOL(radix_tree_gang_lookup_tag);
 
 /**
+ *	radix_tree_shrink    -    shrink height of a radix tree to minimal
+ *	@root		radix tree root
+ */
+static inline void radix_tree_shrink(struct radix_tree_root *root)
+{
+	/* try to shrink tree height */
+	while (root->height > 1 &&
+			root->rnode->count == 1 &&
+			root->rnode->slots[0]) {
+		struct radix_tree_node *to_free = root->rnode;
+
+		root->rnode = to_free->slots[0];
+		root->height--;
+		/* must only free zeroed nodes into the slab */
+		tag_clear(to_free, 0, 0);
+		tag_clear(to_free, 1, 0);
+		to_free->slots[0] = NULL;
+		to_free->count = 0;
+		radix_tree_node_free(to_free);
+	}
+}
+
+/**
  *	radix_tree_delete    -    delete an item from a radix tree
  *	@root:		radix tree root
  *	@index:		index key
@@ -691,6 +718,8 @@
 	void *ret = NULL;
 	char tags[RADIX_TREE_TAGS];
 	int nr_cleared_tags;
+	int tag;
+	int offset;
 
 	height = root->height;
 	if (index > radix_tree_maxindex(height))
@@ -701,16 +730,14 @@
 	slot = root->rnode;
 
 	for ( ; height > 0; height--) {
-		int offset;
-
 		if (slot == NULL)
 			goto out;
 
-		offset = (index >> shift) & RADIX_TREE_MAP_MASK;
-		pathp[1].offset = offset;
-		pathp[1].node = slot;
-		slot = slot->slots[offset];
 		pathp++;
+		offset = (index >> shift) & RADIX_TREE_MAP_MASK;
+		pathp->offset = offset;
+		pathp->node = slot;
+		slot = slot->slots[offset];
 		shift -= RADIX_TREE_MAP_SHIFT;
 	}
 
@@ -723,35 +750,39 @@
 	/*
 	 * Clear all tags associated with the just-deleted item
 	 */
-	memset(tags, 0, sizeof(tags));
-	do {
-		int tag;
+	nr_cleared_tags = 0;
+	for (tag = 0; tag < RADIX_TREE_TAGS; tag++) {
+		if (tag_get(pathp->node, tag, pathp->offset)) {
+			tag_clear(pathp->node, tag, pathp->offset);
+			tags[tag] = 0;
+			nr_cleared_tags++;
+		} else
+			tags[tag] = 1;
+	}
 
-		nr_cleared_tags = RADIX_TREE_TAGS;
+	for (pathp--; nr_cleared_tags && pathp->node; pathp--) {
 		for (tag = 0; tag < RADIX_TREE_TAGS; tag++) {
-			int idx;
-
 			if (tags[tag])
 				continue;
 
 			tag_clear(pathp->node, tag, pathp->offset);
-
-			for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
-				if (pathp->node->tags[tag][idx]) {
-					tags[tag] = 1;
-					nr_cleared_tags--;
-					break;
-				}
+			if (any_tag_set(pathp->node, tag)) {
+				tags[tag] = 1;
+				nr_cleared_tags--;
 			}
 		}
-		pathp--;
-	} while (pathp->node && nr_cleared_tags);
+	}
 
 	/* Now free the nodes we do not need anymore */
 	for (pathp = orig_pathp; pathp->node; pathp--) {
 		pathp->node->slots[pathp->offset] = NULL;
-		if (--pathp->node->count)
+		pathp->node->count--;
+
+		if (pathp->node->count) {
+			if (pathp->node == root->rnode)
+				radix_tree_shrink(root);
 			goto out;
+		}
 
 		/* Node with zero slots in use so free it */
 		radix_tree_node_free(pathp->node);
@@ -770,15 +801,11 @@
  */
 int radix_tree_tagged(struct radix_tree_root *root, int tag)
 {
-	int idx;
-
-	if (!root->rnode)
-		return 0;
-	for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) {
-		if (root->rnode->tags[tag][idx])
-			return 1;
-	}
-	return 0;
+  	struct radix_tree_node *rnode;
+  	rnode = root->rnode;
+  	if (!rnode)
+  		return 0;
+	return any_tag_set(rnode, tag);
 }
 EXPORT_SYMBOL(radix_tree_tagged);
 
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 906ad10..dcd4be9 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -20,7 +20,8 @@
 		if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT)
 			owner = lock->owner;
 		printk("BUG: spinlock %s on CPU#%d, %s/%d\n",
-			msg, smp_processor_id(), current->comm, current->pid);
+			msg, raw_smp_processor_id(),
+			current->comm, current->pid);
 		printk(" lock: %p, .magic: %08x, .owner: %s/%d, .owner_cpu: %d\n",
 			lock, lock->magic,
 			owner ? owner->comm : "<none>",
@@ -78,8 +79,8 @@
 		if (print_once) {
 			print_once = 0;
 			printk("BUG: spinlock lockup on CPU#%d, %s/%d, %p\n",
-				smp_processor_id(), current->comm, current->pid,
-					lock);
+				raw_smp_processor_id(), current->comm,
+				current->pid, lock);
 			dump_stack();
 		}
 	}
@@ -120,7 +121,8 @@
 
 	if (xchg(&print_once, 0)) {
 		printk("BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg,
-			smp_processor_id(), current->comm, current->pid, lock);
+			raw_smp_processor_id(), current->comm,
+			current->pid, lock);
 		dump_stack();
 #ifdef CONFIG_SMP
 		/*
@@ -148,8 +150,8 @@
 		if (print_once) {
 			print_once = 0;
 			printk("BUG: read-lock lockup on CPU#%d, %s/%d, %p\n",
-				smp_processor_id(), current->comm, current->pid,
-					lock);
+				raw_smp_processor_id(), current->comm,
+				current->pid, lock);
 			dump_stack();
 		}
 	}
@@ -220,8 +222,8 @@
 		if (print_once) {
 			print_once = 0;
 			printk("BUG: write-lock lockup on CPU#%d, %s/%d, %p\n",
-				smp_processor_id(), current->comm, current->pid,
-					lock);
+				raw_smp_processor_id(), current->comm,
+				current->pid, lock);
 			dump_stack();
 		}
 	}
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 57216f3..3b48205 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -142,8 +142,7 @@
 	/*
 	 * Get IO TLB memory from the low pages
 	 */
-	io_tlb_start = alloc_bootmem_low_pages_limit(io_tlb_nslabs *
-					     (1 << IO_TLB_SHIFT), 0x100000000);
+	io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs * (1 << IO_TLB_SHIFT));
 	if (!io_tlb_start)
 		panic("Cannot allocate SWIOTLB buffer");
 	io_tlb_end = io_tlb_start + io_tlb_nslabs * (1 << IO_TLB_SHIFT);
@@ -704,8 +703,9 @@
 		addr = SG_ENT_VIRT_ADDRESS(sg);
 		dev_addr = virt_to_phys(addr);
 		if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) {
-			sg->dma_address = (dma_addr_t) virt_to_phys(map_single(hwdev, addr, sg->length, dir));
-			if (!sg->dma_address) {
+			void *map = map_single(hwdev, addr, sg->length, dir);
+			sg->dma_address = virt_to_bus(map);
+			if (!map) {
 				/* Don't panic here, we expect map_sg users
 				   to do proper error handling. */
 				swiotlb_full(hwdev, sg->length, dir, 0);
diff --git a/mm/Kconfig b/mm/Kconfig
index 21eb51d..a9cb80a 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -11,7 +11,7 @@
 
 config FLATMEM_MANUAL
 	bool "Flat Memory"
-	depends on !ARCH_DISCONTIGMEM_ENABLE || ARCH_FLATMEM_ENABLE
+	depends on !(ARCH_DISCONTIGMEM_ENABLE || ARCH_SPARSEMEM_ENABLE) || ARCH_FLATMEM_ENABLE
 	help
 	  This option allows you to change some of the ways that
 	  Linux manages its memory internally.  Most users will
@@ -132,3 +132,10 @@
 	default "4096" if ARM && !CPU_CACHE_VIPT
 	default "4096" if PARISC && !PA20
 	default "4"
+
+#
+# support for page migration
+#
+config MIGRATION
+	def_bool y if NUMA || SPARSEMEM || DISCONTIGMEM
+	depends on SWAP
diff --git a/mm/Makefile b/mm/Makefile
index 2fa6d2c..9aa03fa 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -9,8 +9,8 @@
 
 obj-y			:= bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
 			   page_alloc.o page-writeback.o pdflush.o \
-			   readahead.o slab.o swap.o truncate.o vmscan.o \
-			   prio_tree.o $(mmu-y)
+			   readahead.o swap.o truncate.o vmscan.o \
+			   prio_tree.o util.o $(mmu-y)
 
 obj-$(CONFIG_SWAP)	+= page_io.o swap_state.o swapfile.o thrash.o
 obj-$(CONFIG_HUGETLBFS)	+= hugetlb.o
@@ -18,5 +18,7 @@
 obj-$(CONFIG_SPARSEMEM)	+= sparse.o
 obj-$(CONFIG_SHMEM) += shmem.o
 obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
+obj-$(CONFIG_SLOB) += slob.o
+obj-$(CONFIG_SLAB) += slab.o
 obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
 obj-$(CONFIG_FS_XIP) += filemap_xip.o
diff --git a/mm/bootmem.c b/mm/bootmem.c
index e8c5671..35c3229 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -204,6 +204,8 @@
 		unsigned long j;
 		i = find_next_zero_bit(bdata->node_bootmem_map, eidx, i);
 		i = ALIGN(i, incr);
+		if (i >= eidx)
+			break;
 		if (test_bit(i, bdata->node_bootmem_map))
 			continue;
 		for (j = i + 1; j < i + areasize; ++j) {
@@ -294,20 +296,12 @@
 		unsigned long v = ~map[i / BITS_PER_LONG];
 
 		if (gofast && v == ~0UL) {
-			int j, order;
+			int order;
 
 			page = pfn_to_page(pfn);
 			count += BITS_PER_LONG;
-			__ClearPageReserved(page);
 			order = ffs(BITS_PER_LONG) - 1;
-			set_page_refs(page, order);
-			for (j = 1; j < BITS_PER_LONG; j++) {
-				if (j + 16 < BITS_PER_LONG)
-					prefetchw(page + j + 16);
-				__ClearPageReserved(page + j);
-				set_page_count(page + j, 0);
-			}
-			__free_pages(page, order);
+			__free_pages_bootmem(page, order);
 			i += BITS_PER_LONG;
 			page += BITS_PER_LONG;
 		} else if (v) {
@@ -317,9 +311,7 @@
 			for (m = 1; m && i < idx; m<<=1, page++, i++) {
 				if (v & m) {
 					count++;
-					__ClearPageReserved(page);
-					set_page_refs(page, 0);
-					__free_page(page);
+					__free_pages_bootmem(page, 0);
 				}
 			}
 		} else {
@@ -337,9 +329,7 @@
 	count = 0;
 	for (i = 0; i < ((bdata->node_low_pfn-(bdata->node_boot_start >> PAGE_SHIFT))/8 + PAGE_SIZE-1)/PAGE_SIZE; i++,page++) {
 		count++;
-		__ClearPageReserved(page);
-		set_page_count(page, 1);
-		__free_page(page);
+		__free_pages_bootmem(page, 0);
 	}
 	total += count;
 	bdata->node_bootmem_map = NULL;
@@ -391,15 +381,14 @@
 	return(free_all_bootmem_core(NODE_DATA(0)));
 }
 
-void * __init __alloc_bootmem_limit (unsigned long size, unsigned long align, unsigned long goal,
-				unsigned long limit)
+void * __init __alloc_bootmem(unsigned long size, unsigned long align, unsigned long goal)
 {
 	pg_data_t *pgdat = pgdat_list;
 	void *ptr;
 
 	for_each_pgdat(pgdat)
 		if ((ptr = __alloc_bootmem_core(pgdat->bdata, size,
-						 align, goal, limit)))
+						 align, goal, 0)))
 			return(ptr);
 
 	/*
@@ -411,15 +400,40 @@
 }
 
 
-void * __init __alloc_bootmem_node_limit (pg_data_t *pgdat, unsigned long size, unsigned long align,
-				     unsigned long goal, unsigned long limit)
+void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size, unsigned long align,
+				   unsigned long goal)
 {
 	void *ptr;
 
-	ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal, limit);
+	ptr = __alloc_bootmem_core(pgdat->bdata, size, align, goal, 0);
 	if (ptr)
 		return (ptr);
 
-	return __alloc_bootmem_limit(size, align, goal, limit);
+	return __alloc_bootmem(size, align, goal);
 }
 
+#define LOW32LIMIT 0xffffffff
+
+void * __init __alloc_bootmem_low(unsigned long size, unsigned long align, unsigned long goal)
+{
+	pg_data_t *pgdat = pgdat_list;
+	void *ptr;
+
+	for_each_pgdat(pgdat)
+		if ((ptr = __alloc_bootmem_core(pgdat->bdata, size,
+						 align, goal, LOW32LIMIT)))
+			return(ptr);
+
+	/*
+	 * Whoops, we cannot satisfy the allocation request.
+	 */
+	printk(KERN_ALERT "low bootmem alloc of %lu bytes failed!\n", size);
+	panic("Out of low memory");
+	return NULL;
+}
+
+void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
+				       unsigned long align, unsigned long goal)
+{
+	return __alloc_bootmem_core(pgdat->bdata, size, align, goal, LOW32LIMIT);
+}
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 5f19e87..d257c89 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -37,6 +37,11 @@
 	if (!file)
 		return -EBADF;
 
+	if (S_ISFIFO(file->f_dentry->d_inode->i_mode)) {
+		ret = -ESPIPE;
+		goto out;
+	}
+
 	mapping = file->f_mapping;
 	if (!mapping || len < 0) {
 		ret = -EINVAL;
diff --git a/mm/filemap.c b/mm/filemap.c
index 33a28bf..478f4c7 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -280,7 +280,7 @@
  * it is otherwise livelockable.
  */
 int sync_page_range(struct inode *inode, struct address_space *mapping,
-			loff_t pos, size_t count)
+			loff_t pos, loff_t count)
 {
 	pgoff_t start = pos >> PAGE_CACHE_SHIFT;
 	pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
@@ -305,9 +305,8 @@
  * as it forces O_SYNC writers to different parts of the same file
  * to be serialised right until io completion.
  */
-static int sync_page_range_nolock(struct inode *inode,
-				  struct address_space *mapping,
-				  loff_t pos, size_t count)
+int sync_page_range_nolock(struct inode *inode, struct address_space *mapping,
+			   loff_t pos, loff_t count)
 {
 	pgoff_t start = pos >> PAGE_CACHE_SHIFT;
 	pgoff_t end = (pos + count - 1) >> PAGE_CACHE_SHIFT;
@@ -322,6 +321,7 @@
 		ret = wait_on_page_writeback_range(mapping, start, end);
 	return ret;
 }
+EXPORT_SYMBOL(sync_page_range_nolock);
 
 /**
  * filemap_fdatawait - walk the list of under-writeback pages of the given
@@ -343,30 +343,44 @@
 
 int filemap_write_and_wait(struct address_space *mapping)
 {
-	int retval = 0;
+	int err = 0;
 
 	if (mapping->nrpages) {
-		retval = filemap_fdatawrite(mapping);
-		if (retval == 0)
-			retval = filemap_fdatawait(mapping);
+		err = filemap_fdatawrite(mapping);
+		/*
+		 * Even if the above returned error, the pages may be
+		 * written partially (e.g. -ENOSPC), so we wait for it.
+		 * But the -EIO is special case, it may indicate the worst
+		 * thing (e.g. bug) happened, so we avoid waiting for it.
+		 */
+		if (err != -EIO) {
+			int err2 = filemap_fdatawait(mapping);
+			if (!err)
+				err = err2;
+		}
 	}
-	return retval;
+	return err;
 }
+EXPORT_SYMBOL(filemap_write_and_wait);
 
 int filemap_write_and_wait_range(struct address_space *mapping,
 				 loff_t lstart, loff_t lend)
 {
-	int retval = 0;
+	int err = 0;
 
 	if (mapping->nrpages) {
-		retval = __filemap_fdatawrite_range(mapping, lstart, lend,
-						    WB_SYNC_ALL);
-		if (retval == 0)
-			retval = wait_on_page_writeback_range(mapping,
-						    lstart >> PAGE_CACHE_SHIFT,
-						    lend >> PAGE_CACHE_SHIFT);
+		err = __filemap_fdatawrite_range(mapping, lstart, lend,
+						 WB_SYNC_ALL);
+		/* See comment of filemap_write_and_wait() */
+		if (err != -EIO) {
+			int err2 = wait_on_page_writeback_range(mapping,
+						lstart >> PAGE_CACHE_SHIFT,
+						lend >> PAGE_CACHE_SHIFT);
+			if (!err)
+				err = err2;
+		}
 	}
-	return retval;
+	return err;
 }
 
 /*
@@ -555,11 +569,12 @@
 		page_cache_get(page);
 		if (TestSetPageLocked(page)) {
 			read_unlock_irq(&mapping->tree_lock);
-			lock_page(page);
+			__lock_page(page);
 			read_lock_irq(&mapping->tree_lock);
 
 			/* Has the page been truncated while we slept? */
-			if (page->mapping != mapping || page->index != offset) {
+			if (unlikely(page->mapping != mapping ||
+				     page->index != offset)) {
 				unlock_page(page);
 				page_cache_release(page);
 				goto repeat;
@@ -831,8 +846,13 @@
 		/* Start the actual read. The read will unlock the page. */
 		error = mapping->a_ops->readpage(filp, page);
 
-		if (unlikely(error))
+		if (unlikely(error)) {
+			if (error == AOP_TRUNCATED_PAGE) {
+				page_cache_release(page);
+				goto find_page;
+			}
 			goto readpage_error;
+		}
 
 		if (!PageUptodate(page)) {
 			lock_page(page);
@@ -1152,26 +1172,24 @@
 {
 	struct address_space *mapping = file->f_mapping;
 	struct page *page; 
-	int error;
+	int ret;
 
-	page = page_cache_alloc_cold(mapping);
-	if (!page)
-		return -ENOMEM;
+	do {
+		page = page_cache_alloc_cold(mapping);
+		if (!page)
+			return -ENOMEM;
 
-	error = add_to_page_cache_lru(page, mapping, offset, GFP_KERNEL);
-	if (!error) {
-		error = mapping->a_ops->readpage(file, page);
+		ret = add_to_page_cache_lru(page, mapping, offset, GFP_KERNEL);
+		if (ret == 0)
+			ret = mapping->a_ops->readpage(file, page);
+		else if (ret == -EEXIST)
+			ret = 0; /* losing race to add is OK */
+
 		page_cache_release(page);
-		return error;
-	}
 
-	/*
-	 * We arrive here in the unlikely event that someone 
-	 * raced with us and added our page to the cache first
-	 * or we are out of memory for radix-tree nodes.
-	 */
-	page_cache_release(page);
-	return error == -EEXIST ? 0 : error;
+	} while (ret == AOP_TRUNCATED_PAGE);
+		
+	return ret;
 }
 
 #define MMAP_LOTSAMISS  (100)
@@ -1331,10 +1349,14 @@
 		goto success;
 	}
 
-	if (!mapping->a_ops->readpage(file, page)) {
+	error = mapping->a_ops->readpage(file, page);
+	if (!error) {
 		wait_on_page_locked(page);
 		if (PageUptodate(page))
 			goto success;
+	} else if (error == AOP_TRUNCATED_PAGE) {
+		page_cache_release(page);
+		goto retry_find;
 	}
 
 	/*
@@ -1358,10 +1380,14 @@
 		goto success;
 	}
 	ClearPageError(page);
-	if (!mapping->a_ops->readpage(file, page)) {
+	error = mapping->a_ops->readpage(file, page);
+	if (!error) {
 		wait_on_page_locked(page);
 		if (PageUptodate(page))
 			goto success;
+	} else if (error == AOP_TRUNCATED_PAGE) {
+		page_cache_release(page);
+		goto retry_find;
 	}
 
 	/*
@@ -1444,10 +1470,14 @@
 		goto success;
 	}
 
-	if (!mapping->a_ops->readpage(file, page)) {
+	error = mapping->a_ops->readpage(file, page);
+	if (!error) {
 		wait_on_page_locked(page);
 		if (PageUptodate(page))
 			goto success;
+	} else if (error == AOP_TRUNCATED_PAGE) {
+		page_cache_release(page);
+		goto retry_find;
 	}
 
 	/*
@@ -1470,10 +1500,14 @@
 	}
 
 	ClearPageError(page);
-	if (!mapping->a_ops->readpage(file, page)) {
+	error = mapping->a_ops->readpage(file, page);
+	if (!error) {
 		wait_on_page_locked(page);
 		if (PageUptodate(page))
 			goto success;
+	} else if (error == AOP_TRUNCATED_PAGE) {
+		page_cache_release(page);
+		goto retry_find;
 	}
 
 	/*
@@ -1934,12 +1968,16 @@
 		status = a_ops->prepare_write(file, page, offset, offset+bytes);
 		if (unlikely(status)) {
 			loff_t isize = i_size_read(inode);
+
+			if (status != AOP_TRUNCATED_PAGE)
+				unlock_page(page);
+			page_cache_release(page);
+			if (status == AOP_TRUNCATED_PAGE)
+				continue;
 			/*
 			 * prepare_write() may have instantiated a few blocks
 			 * outside i_size.  Trim these off again.
 			 */
-			unlock_page(page);
-			page_cache_release(page);
 			if (pos + bytes > isize)
 				vmtruncate(inode, isize);
 			break;
@@ -1952,6 +1990,10 @@
 						cur_iov, iov_base, bytes);
 		flush_dcache_page(page);
 		status = a_ops->commit_write(file, page, offset, offset+bytes);
+		if (status == AOP_TRUNCATED_PAGE) {
+			page_cache_release(page);
+			continue;
+		}
 		if (likely(copied > 0)) {
 			if (!status)
 				status = copied;
diff --git a/mm/fremap.c b/mm/fremap.c
index 007cbad..9f381e5 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -27,24 +27,20 @@
 	struct page *page = NULL;
 
 	if (pte_present(pte)) {
-		unsigned long pfn = pte_pfn(pte);
-		flush_cache_page(vma, addr, pfn);
+		flush_cache_page(vma, addr, pte_pfn(pte));
 		pte = ptep_clear_flush(vma, addr, ptep);
-		if (unlikely(!pfn_valid(pfn))) {
-			print_bad_pte(vma, pte, addr);
-			goto out;
+		page = vm_normal_page(vma, addr, pte);
+		if (page) {
+			if (pte_dirty(pte))
+				set_page_dirty(page);
+			page_remove_rmap(page);
+			page_cache_release(page);
 		}
-		page = pfn_to_page(pfn);
-		if (pte_dirty(pte))
-			set_page_dirty(page);
-		page_remove_rmap(page);
-		page_cache_release(page);
 	} else {
 		if (!pte_file(pte))
 			free_swap_and_cache(pte_to_swp_entry(pte));
 		pte_clear(mm, addr, ptep);
 	}
-out:
 	return !!page;
 }
 
@@ -59,22 +55,10 @@
 	pgoff_t size;
 	int err = -ENOMEM;
 	pte_t *pte;
-	pmd_t *pmd;
-	pud_t *pud;
-	pgd_t *pgd;
 	pte_t pte_val;
 	spinlock_t *ptl;
 
-	BUG_ON(vma->vm_flags & VM_UNPAGED);
-
-	pgd = pgd_offset(mm, addr);
-	pud = pud_alloc(mm, pgd, addr);
-	if (!pud)
-		goto out;
-	pmd = pmd_alloc(mm, pud, addr);
-	if (!pmd)
-		goto out;
-	pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
+	pte = get_locked_pte(mm, addr, &ptl);
 	if (!pte)
 		goto out;
 
@@ -116,22 +100,10 @@
 {
 	int err = -ENOMEM;
 	pte_t *pte;
-	pmd_t *pmd;
-	pud_t *pud;
-	pgd_t *pgd;
 	pte_t pte_val;
 	spinlock_t *ptl;
 
-	BUG_ON(vma->vm_flags & VM_UNPAGED);
-
-	pgd = pgd_offset(mm, addr);
-	pud = pud_alloc(mm, pgd, addr);
-	if (!pud)
-		goto out;
-	pmd = pmd_alloc(mm, pud, addr);
-	if (!pmd)
-		goto out;
-	pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
+	pte = get_locked_pte(mm, addr, &ptl);
 	if (!pte)
 		goto out;
 
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 3e52df7..b21d78c 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -11,6 +11,9 @@
 #include <linux/highmem.h>
 #include <linux/nodemask.h>
 #include <linux/pagemap.h>
+#include <linux/mempolicy.h>
+#include <linux/cpuset.h>
+
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
@@ -36,18 +39,22 @@
 	free_huge_pages_node[nid]++;
 }
 
-static struct page *dequeue_huge_page(void)
+static struct page *dequeue_huge_page(struct vm_area_struct *vma,
+				unsigned long address)
 {
 	int nid = numa_node_id();
 	struct page *page = NULL;
+	struct zonelist *zonelist = huge_zonelist(vma, address);
+	struct zone **z;
 
-	if (list_empty(&hugepage_freelists[nid])) {
-		for (nid = 0; nid < MAX_NUMNODES; ++nid)
-			if (!list_empty(&hugepage_freelists[nid]))
-				break;
+	for (z = zonelist->zones; *z; z++) {
+		nid = (*z)->zone_pgdat->node_id;
+		if (cpuset_zone_allowed(*z, GFP_HIGHUSER) &&
+		    !list_empty(&hugepage_freelists[nid]))
+			break;
 	}
-	if (nid >= 0 && nid < MAX_NUMNODES &&
-	    !list_empty(&hugepage_freelists[nid])) {
+
+	if (*z) {
 		page = list_entry(hugepage_freelists[nid].next,
 				  struct page, lru);
 		list_del(&page->lru);
@@ -85,13 +92,13 @@
 	spin_unlock(&hugetlb_lock);
 }
 
-struct page *alloc_huge_page(void)
+struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr)
 {
 	struct page *page;
 	int i;
 
 	spin_lock(&hugetlb_lock);
-	page = dequeue_huge_page();
+	page = dequeue_huge_page(vma, addr);
 	if (!page) {
 		spin_unlock(&hugetlb_lock);
 		return NULL;
@@ -194,7 +201,7 @@
 	spin_lock(&hugetlb_lock);
 	try_to_free_low(count);
 	while (count < nr_huge_pages) {
-		struct page *page = dequeue_huge_page();
+		struct page *page = dequeue_huge_page(NULL, 0);
 		if (!page)
 			break;
 		update_and_free_page(page);
@@ -261,11 +268,12 @@
 	.nopage = hugetlb_nopage,
 };
 
-static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page)
+static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page,
+				int writable)
 {
 	pte_t entry;
 
-	if (vma->vm_flags & VM_WRITE) {
+	if (writable) {
 		entry =
 		    pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
 	} else {
@@ -277,12 +285,27 @@
 	return entry;
 }
 
+static void set_huge_ptep_writable(struct vm_area_struct *vma,
+				   unsigned long address, pte_t *ptep)
+{
+	pte_t entry;
+
+	entry = pte_mkwrite(pte_mkdirty(*ptep));
+	ptep_set_access_flags(vma, address, ptep, entry, 1);
+	update_mmu_cache(vma, address, entry);
+	lazy_mmu_prot_update(entry);
+}
+
+
 int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
 			    struct vm_area_struct *vma)
 {
 	pte_t *src_pte, *dst_pte, entry;
 	struct page *ptepage;
 	unsigned long addr;
+	int cow;
+
+	cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
 
 	for (addr = vma->vm_start; addr < vma->vm_end; addr += HPAGE_SIZE) {
 		src_pte = huge_pte_offset(src, addr);
@@ -294,6 +317,8 @@
 		spin_lock(&dst->page_table_lock);
 		spin_lock(&src->page_table_lock);
 		if (!pte_none(*src_pte)) {
+			if (cow)
+				ptep_set_wrprotect(src, addr, src_pte);
 			entry = *src_pte;
 			ptepage = pte_page(entry);
 			get_page(ptepage);
@@ -345,57 +370,63 @@
 	flush_tlb_range(vma, start, end);
 }
 
-static struct page *find_lock_huge_page(struct address_space *mapping,
-			unsigned long idx)
+static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
+			unsigned long address, pte_t *ptep, pte_t pte)
 {
-	struct page *page;
-	int err;
-	struct inode *inode = mapping->host;
-	unsigned long size;
+	struct page *old_page, *new_page;
+	int i, avoidcopy;
 
-retry:
-	page = find_lock_page(mapping, idx);
-	if (page)
-		goto out;
+	old_page = pte_page(pte);
 
-	/* Check to make sure the mapping hasn't been truncated */
-	size = i_size_read(inode) >> HPAGE_SHIFT;
-	if (idx >= size)
-		goto out;
-
-	if (hugetlb_get_quota(mapping))
-		goto out;
-	page = alloc_huge_page();
-	if (!page) {
-		hugetlb_put_quota(mapping);
-		goto out;
+	/* If no-one else is actually using this page, avoid the copy
+	 * and just make the page writable */
+	avoidcopy = (page_count(old_page) == 1);
+	if (avoidcopy) {
+		set_huge_ptep_writable(vma, address, ptep);
+		return VM_FAULT_MINOR;
 	}
 
-	err = add_to_page_cache(page, mapping, idx, GFP_KERNEL);
-	if (err) {
-		put_page(page);
-		hugetlb_put_quota(mapping);
-		if (err == -EEXIST)
-			goto retry;
-		page = NULL;
+	page_cache_get(old_page);
+	new_page = alloc_huge_page(vma, address);
+
+	if (!new_page) {
+		page_cache_release(old_page);
+
+		/* Logically this is OOM, not a SIGBUS, but an OOM
+		 * could cause the kernel to go killing other
+		 * processes which won't help the hugepage situation
+		 * at all (?) */
+		return VM_FAULT_SIGBUS;
 	}
-out:
-	return page;
+
+	spin_unlock(&mm->page_table_lock);
+	for (i = 0; i < HPAGE_SIZE/PAGE_SIZE; i++)
+		copy_user_highpage(new_page + i, old_page + i,
+				   address + i*PAGE_SIZE);
+	spin_lock(&mm->page_table_lock);
+
+	ptep = huge_pte_offset(mm, address & HPAGE_MASK);
+	if (likely(pte_same(*ptep, pte))) {
+		/* Break COW */
+		set_huge_pte_at(mm, address, ptep,
+				make_huge_pte(vma, new_page, 1));
+		/* Make the old page be freed below */
+		new_page = old_page;
+	}
+	page_cache_release(new_page);
+	page_cache_release(old_page);
+	return VM_FAULT_MINOR;
 }
 
-int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
-			unsigned long address, int write_access)
+int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
+			unsigned long address, pte_t *ptep, int write_access)
 {
 	int ret = VM_FAULT_SIGBUS;
 	unsigned long idx;
 	unsigned long size;
-	pte_t *pte;
 	struct page *page;
 	struct address_space *mapping;
-
-	pte = huge_pte_alloc(mm, address);
-	if (!pte)
-		goto out;
+	pte_t new_pte;
 
 	mapping = vma->vm_file->f_mapping;
 	idx = ((address - vma->vm_start) >> HPAGE_SHIFT)
@@ -405,9 +436,31 @@
 	 * Use page lock to guard against racing truncation
 	 * before we get page_table_lock.
 	 */
-	page = find_lock_huge_page(mapping, idx);
-	if (!page)
-		goto out;
+retry:
+	page = find_lock_page(mapping, idx);
+	if (!page) {
+		if (hugetlb_get_quota(mapping))
+			goto out;
+		page = alloc_huge_page(vma, address);
+		if (!page) {
+			hugetlb_put_quota(mapping);
+			goto out;
+		}
+
+		if (vma->vm_flags & VM_SHARED) {
+			int err;
+
+			err = add_to_page_cache(page, mapping, idx, GFP_KERNEL);
+			if (err) {
+				put_page(page);
+				hugetlb_put_quota(mapping);
+				if (err == -EEXIST)
+					goto retry;
+				goto out;
+			}
+		} else
+			lock_page(page);
+	}
 
 	spin_lock(&mm->page_table_lock);
 	size = i_size_read(mapping->host) >> HPAGE_SHIFT;
@@ -415,11 +468,19 @@
 		goto backout;
 
 	ret = VM_FAULT_MINOR;
-	if (!pte_none(*pte))
+	if (!pte_none(*ptep))
 		goto backout;
 
 	add_mm_counter(mm, file_rss, HPAGE_SIZE / PAGE_SIZE);
-	set_huge_pte_at(mm, address, pte, make_huge_pte(vma, page));
+	new_pte = make_huge_pte(vma, page, ((vma->vm_flags & VM_WRITE)
+				&& (vma->vm_flags & VM_SHARED)));
+	set_huge_pte_at(mm, address, ptep, new_pte);
+
+	if (write_access && !(vma->vm_flags & VM_SHARED)) {
+		/* Optimization, do the COW without a second fault */
+		ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
+	}
+
 	spin_unlock(&mm->page_table_lock);
 	unlock_page(page);
 out:
@@ -433,6 +494,33 @@
 	goto out;
 }
 
+int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
+			unsigned long address, int write_access)
+{
+	pte_t *ptep;
+	pte_t entry;
+	int ret;
+
+	ptep = huge_pte_alloc(mm, address);
+	if (!ptep)
+		return VM_FAULT_OOM;
+
+	entry = *ptep;
+	if (pte_none(entry))
+		return hugetlb_no_page(mm, vma, address, ptep, write_access);
+
+	ret = VM_FAULT_MINOR;
+
+	spin_lock(&mm->page_table_lock);
+	/* Check for a racing update before calling hugetlb_cow */
+	if (likely(pte_same(entry, *ptep)))
+		if (write_access && !pte_write(entry))
+			ret = hugetlb_cow(mm, vma, address, ptep, entry);
+	spin_unlock(&mm->page_table_lock);
+
+	return ret;
+}
+
 int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
 			struct page **pages, struct vm_area_struct **vmas,
 			unsigned long *position, int *length, int i)
diff --git a/mm/internal.h b/mm/internal.h
index 6bf134e..17256bb 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -9,5 +9,22 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-/* page_alloc.c */
-extern void set_page_refs(struct page *page, int order);
+static inline void set_page_refs(struct page *page, int order)
+{
+#ifdef CONFIG_MMU
+	set_page_count(page, 1);
+#else
+	int i;
+
+	/*
+	 * We need to reference all the pages for this order, otherwise if
+	 * anyone accesses one of the pages with (get/put) it will be freed.
+	 * - eg: access_process_vm()
+	 */
+	for (i = 0; i < (1 << order); i++)
+		set_page_count(page + i, 1);
+#endif /* CONFIG_MMU */
+}
+
+extern void fastcall __init __free_pages_bootmem(struct page *page,
+						unsigned int order);
diff --git a/mm/madvise.c b/mm/madvise.c
index 328a3bc..ae0ae3e 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -126,7 +126,7 @@
 			     unsigned long start, unsigned long end)
 {
 	*prev = vma;
-	if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_UNPAGED))
+	if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
 		return -EINVAL;
 
 	if (unlikely(vma->vm_flags & VM_NONLINEAR)) {
@@ -140,6 +140,36 @@
 	return 0;
 }
 
+/*
+ * Application wants to free up the pages and associated backing store.
+ * This is effectively punching a hole into the middle of a file.
+ *
+ * NOTE: Currently, only shmfs/tmpfs is supported for this operation.
+ * Other filesystems return -ENOSYS.
+ */
+static long madvise_remove(struct vm_area_struct *vma,
+				unsigned long start, unsigned long end)
+{
+	struct address_space *mapping;
+        loff_t offset, endoff;
+
+	if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB))
+		return -EINVAL;
+
+	if (!vma->vm_file || !vma->vm_file->f_mapping
+		|| !vma->vm_file->f_mapping->host) {
+			return -EINVAL;
+	}
+
+	mapping = vma->vm_file->f_mapping;
+
+	offset = (loff_t)(start - vma->vm_start)
+			+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
+	endoff = (loff_t)(end - vma->vm_start - 1)
+			+ ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
+	return  vmtruncate_range(mapping->host, offset, endoff);
+}
+
 static long
 madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
 		unsigned long start, unsigned long end, int behavior)
@@ -152,6 +182,9 @@
 	case MADV_RANDOM:
 		error = madvise_behavior(vma, prev, start, end, behavior);
 		break;
+	case MADV_REMOVE:
+		error = madvise_remove(vma, start, end);
+		break;
 
 	case MADV_WILLNEED:
 		error = madvise_willneed(vma, prev, start, end);
@@ -190,6 +223,8 @@
  *		some pages ahead.
  *  MADV_DONTNEED - the application is finished with the given range,
  *		so the kernel can free resources associated with it.
+ *  MADV_REMOVE - the application wants to free up the given range of
+ *		pages and associated backing store.
  *
  * return values:
  *  zero    - success
diff --git a/mm/memory.c b/mm/memory.c
index d1f46f4..7197f9b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -333,9 +333,9 @@
 }
 
 /*
- * This function is called to print an error when a pte in a
- * !VM_UNPAGED region is found pointing to an invalid pfn (which
- * is an error.
+ * This function is called to print an error when a bad pte
+ * is found. For example, we might have a PFN-mapped pte in
+ * a region that doesn't allow it.
  *
  * The calling function must still handle the error.
  */
@@ -349,20 +349,64 @@
 	dump_stack();
 }
 
-/*
- * page_is_anon applies strict checks for an anonymous page belonging to
- * this vma at this address.  It is used on VM_UNPAGED vmas, which are
- * usually populated with shared originals (which must not be counted),
- * but occasionally contain private COWed copies (when !VM_SHARED, or
- * perhaps via ptrace when VM_SHARED).  An mmap of /dev/mem might window
- * free pages, pages from other processes, or from other parts of this:
- * it's tricky, but try not to be deceived by foreign anonymous pages.
- */
-static inline int page_is_anon(struct page *page,
-			struct vm_area_struct *vma, unsigned long addr)
+static inline int is_cow_mapping(unsigned int flags)
 {
-	return page && PageAnon(page) && page_mapped(page) &&
-		page_address_in_vma(page, vma) == addr;
+	return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
+}
+
+/*
+ * This function gets the "struct page" associated with a pte.
+ *
+ * NOTE! Some mappings do not have "struct pages". A raw PFN mapping
+ * will have each page table entry just pointing to a raw page frame
+ * number, and as far as the VM layer is concerned, those do not have
+ * pages associated with them - even if the PFN might point to memory
+ * that otherwise is perfectly fine and has a "struct page".
+ *
+ * The way we recognize those mappings is through the rules set up
+ * by "remap_pfn_range()": the vma will have the VM_PFNMAP bit set,
+ * and the vm_pgoff will point to the first PFN mapped: thus every
+ * page that is a raw mapping will always honor the rule
+ *
+ *	pfn_of_page == vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT)
+ *
+ * and if that isn't true, the page has been COW'ed (in which case it
+ * _does_ have a "struct page" associated with it even if it is in a
+ * VM_PFNMAP range).
+ */
+struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+{
+	unsigned long pfn = pte_pfn(pte);
+
+	if (vma->vm_flags & VM_PFNMAP) {
+		unsigned long off = (addr - vma->vm_start) >> PAGE_SHIFT;
+		if (pfn == vma->vm_pgoff + off)
+			return NULL;
+		if (!is_cow_mapping(vma->vm_flags))
+			return NULL;
+	}
+
+	/*
+	 * Add some anal sanity checks for now. Eventually,
+	 * we should just do "return pfn_to_page(pfn)", but
+	 * in the meantime we check that we get a valid pfn,
+	 * and that the resulting page looks ok.
+	 *
+	 * Remove this test eventually!
+	 */
+	if (unlikely(!pfn_valid(pfn))) {
+		print_bad_pte(vma, pte, addr);
+		return NULL;
+	}
+
+	/*
+	 * NOTE! We still have PageReserved() pages in the page 
+	 * tables. 
+	 *
+	 * The PAGE_ZERO() pages and various VDSO mappings can
+	 * cause them to exist.
+	 */
+	return pfn_to_page(pfn);
 }
 
 /*
@@ -379,7 +423,6 @@
 	unsigned long vm_flags = vma->vm_flags;
 	pte_t pte = *src_pte;
 	struct page *page;
-	unsigned long pfn;
 
 	/* pte contains position in swap or file, so copy. */
 	if (unlikely(!pte_present(pte))) {
@@ -397,27 +440,11 @@
 		goto out_set_pte;
 	}
 
-	pfn = pte_pfn(pte);
-	page = pfn_valid(pfn)? pfn_to_page(pfn): NULL;
-
-	if (unlikely(vm_flags & VM_UNPAGED))
-		if (!page_is_anon(page, vma, addr))
-			goto out_set_pte;
-
-	/*
-	 * If the pte points outside of valid memory but
-	 * the region is not VM_UNPAGED, we have a problem.
-	 */
-	if (unlikely(!page)) {
-		print_bad_pte(vma, pte, addr);
-		goto out_set_pte; /* try to do something sane */
-	}
-
 	/*
 	 * If it's a COW mapping, write protect it both
 	 * in the parent and the child
 	 */
-	if ((vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE) {
+	if (is_cow_mapping(vm_flags)) {
 		ptep_set_wrprotect(src_mm, addr, src_pte);
 		pte = *src_pte;
 	}
@@ -429,9 +456,13 @@
 	if (vm_flags & VM_SHARED)
 		pte = pte_mkclean(pte);
 	pte = pte_mkold(pte);
-	get_page(page);
-	page_dup_rmap(page);
-	rss[!!PageAnon(page)]++;
+
+	page = vm_normal_page(vma, addr, pte);
+	if (page) {
+		get_page(page);
+		page_dup_rmap(page);
+		rss[!!PageAnon(page)]++;
+	}
 
 out_set_pte:
 	set_pte_at(dst_mm, addr, dst_pte, pte);
@@ -543,7 +574,7 @@
 	 * readonly mappings. The tradeoff is that copy_page_range is more
 	 * efficient than faulting.
 	 */
-	if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_UNPAGED))) {
+	if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP|VM_INSERTPAGE))) {
 		if (!vma->anon_vma)
 			return 0;
 	}
@@ -584,19 +615,10 @@
 		}
 		if (pte_present(ptent)) {
 			struct page *page;
-			unsigned long pfn;
 
 			(*zap_work) -= PAGE_SIZE;
 
-			pfn = pte_pfn(ptent);
-			page = pfn_valid(pfn)? pfn_to_page(pfn): NULL;
-
-			if (unlikely(vma->vm_flags & VM_UNPAGED)) {
-				if (!page_is_anon(page, vma, addr))
-					page = NULL;
-			} else if (unlikely(!page))
-				print_bad_pte(vma, ptent, addr);
-
+			page = vm_normal_page(vma, addr, ptent);
 			if (unlikely(details) && page) {
 				/*
 				 * unmap_shared_mapping_pages() wants to
@@ -852,7 +874,7 @@
 /*
  * Do a quick page-table lookup for a single page.
  */
-struct page *follow_page(struct mm_struct *mm, unsigned long address,
+struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
 			unsigned int flags)
 {
 	pgd_t *pgd;
@@ -860,8 +882,8 @@
 	pmd_t *pmd;
 	pte_t *ptep, pte;
 	spinlock_t *ptl;
-	unsigned long pfn;
 	struct page *page;
+	struct mm_struct *mm = vma->vm_mm;
 
 	page = follow_huge_addr(mm, address, flags & FOLL_WRITE);
 	if (!IS_ERR(page)) {
@@ -897,11 +919,10 @@
 		goto unlock;
 	if ((flags & FOLL_WRITE) && !pte_write(pte))
 		goto unlock;
-	pfn = pte_pfn(pte);
-	if (!pfn_valid(pfn))
+	page = vm_normal_page(vma, address, pte);
+	if (unlikely(!page))
 		goto unlock;
 
-	page = pfn_to_page(pfn);
 	if (flags & FOLL_GET)
 		get_page(page);
 	if (flags & FOLL_TOUCH) {
@@ -974,8 +995,10 @@
 				return i ? : -EFAULT;
 			}
 			if (pages) {
-				pages[i] = pte_page(*pte);
-				get_page(pages[i]);
+				struct page *page = vm_normal_page(gate_vma, start, *pte);
+				pages[i] = page;
+				if (page)
+					get_page(page);
 			}
 			pte_unmap(pte);
 			if (vmas)
@@ -986,7 +1009,7 @@
 			continue;
 		}
 
-		if (!vma || (vma->vm_flags & VM_IO)
+		if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
 				|| !(vm_flags & vma->vm_flags))
 			return i ? : -EFAULT;
 
@@ -1010,7 +1033,7 @@
 				foll_flags |= FOLL_WRITE;
 
 			cond_resched();
-			while (!(page = follow_page(mm, start, foll_flags))) {
+			while (!(page = follow_page(vma, start, foll_flags))) {
 				int ret;
 				ret = __handle_mm_fault(mm, vma, start,
 						foll_flags & FOLL_WRITE);
@@ -1130,6 +1153,86 @@
 	return err;
 }
 
+pte_t * fastcall get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)
+{
+	pgd_t * pgd = pgd_offset(mm, addr);
+	pud_t * pud = pud_alloc(mm, pgd, addr);
+	if (pud) {
+		pmd_t * pmd = pmd_alloc(mm, pud, addr);
+		if (pmd)
+			return pte_alloc_map_lock(mm, pmd, addr, ptl);
+	}
+	return NULL;
+}
+
+/*
+ * This is the old fallback for page remapping.
+ *
+ * For historical reasons, it only allows reserved pages. Only
+ * old drivers should use this, and they needed to mark their
+ * pages reserved for the old functions anyway.
+ */
+static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *page, pgprot_t prot)
+{
+	int retval;
+	pte_t *pte;
+	spinlock_t *ptl;  
+
+	retval = -EINVAL;
+	if (PageAnon(page))
+		goto out;
+	retval = -ENOMEM;
+	flush_dcache_page(page);
+	pte = get_locked_pte(mm, addr, &ptl);
+	if (!pte)
+		goto out;
+	retval = -EBUSY;
+	if (!pte_none(*pte))
+		goto out_unlock;
+
+	/* Ok, finally just insert the thing.. */
+	get_page(page);
+	inc_mm_counter(mm, file_rss);
+	page_add_file_rmap(page);
+	set_pte_at(mm, addr, pte, mk_pte(page, prot));
+
+	retval = 0;
+out_unlock:
+	pte_unmap_unlock(pte, ptl);
+out:
+	return retval;
+}
+
+/*
+ * This allows drivers to insert individual pages they've allocated
+ * into a user vma.
+ *
+ * The page has to be a nice clean _individual_ kernel allocation.
+ * If you allocate a compound page, you need to have marked it as
+ * such (__GFP_COMP), or manually just split the page up yourself
+ * (which is mainly an issue of doing "set_page_count(page, 1)" for
+ * each sub-page, and then freeing them one by one when you free
+ * them rather than freeing it as a compound page).
+ *
+ * NOTE! Traditionally this was done with "remap_pfn_range()" which
+ * took an arbitrary page protection parameter. This doesn't allow
+ * that. Your vma protection will have to be set up correctly, which
+ * means that if you want a shared writable mapping, you'd better
+ * ask for a shared writable mapping!
+ *
+ * The page does not need to be reserved.
+ */
+int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, struct page *page)
+{
+	if (addr < vma->vm_start || addr >= vma->vm_end)
+		return -EFAULT;
+	if (!page_count(page))
+		return -EINVAL;
+	vma->vm_flags |= VM_INSERTPAGE;
+	return insert_page(vma->vm_mm, addr, page, vma->vm_page_prot);
+}
+EXPORT_SYMBOL(vm_insert_page);
+
 /*
  * maps a range of physical memory into the requested pages. the old
  * mappings are removed. any references to nonexistent pages results
@@ -1214,11 +1317,21 @@
 	 *	in 2.6 the LRU scan won't even find its pages, so this
 	 *	flag means no more than count its pages in reserved_vm,
 	 * 	and omit it from core dump, even when VM_IO turned off.
-	 *   VM_UNPAGED tells the core MM not to "manage" these pages
-         *	(e.g. refcount, mapcount, try to swap them out): in
-	 *	particular, zap_pte_range does not try to free them.
+	 *   VM_PFNMAP tells the core MM that the base pages are just
+	 *	raw PFN mappings, and do not have a "struct page" associated
+	 *	with them.
+	 *
+	 * There's a horrible special case to handle copy-on-write
+	 * behaviour that some programs depend on. We mark the "original"
+	 * un-COW'ed pages by matching them up with "vma->vm_pgoff".
 	 */
-	vma->vm_flags |= VM_IO | VM_RESERVED | VM_UNPAGED;
+	if (is_cow_mapping(vma->vm_flags)) {
+		if (addr != vma->vm_start || end != vma->vm_end)
+			return -EINVAL;
+		vma->vm_pgoff = pfn;
+	}
+
+	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
 
 	BUG_ON(addr >= end);
 	pfn -= addr >> PAGE_SHIFT;
@@ -1273,6 +1386,33 @@
 	return pte;
 }
 
+static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va)
+{
+	/*
+	 * If the source page was a PFN mapping, we don't have
+	 * a "struct page" for it. We do a best-effort copy by
+	 * just copying from the original user address. If that
+	 * fails, we just zero-fill it. Live with it.
+	 */
+	if (unlikely(!src)) {
+		void *kaddr = kmap_atomic(dst, KM_USER0);
+		void __user *uaddr = (void __user *)(va & PAGE_MASK);
+
+		/*
+		 * This really shouldn't fail, because the page is there
+		 * in the page tables. But it might just be unreadable,
+		 * in which case we just give up and fill the result with
+		 * zeroes.
+		 */
+		if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE))
+			memset(kaddr, 0, PAGE_SIZE);
+		kunmap_atomic(kaddr, KM_USER0);
+		return;
+		
+	}
+	copy_user_highpage(dst, src, va);
+}
+
 /*
  * This routine handles present pages, when users try to write
  * to a shared page. It is done by copying the page to a new address
@@ -1295,35 +1435,19 @@
 		unsigned long address, pte_t *page_table, pmd_t *pmd,
 		spinlock_t *ptl, pte_t orig_pte)
 {
-	struct page *old_page, *src_page, *new_page;
-	unsigned long pfn = pte_pfn(orig_pte);
+	struct page *old_page, *new_page;
 	pte_t entry;
 	int ret = VM_FAULT_MINOR;
 
-	if (unlikely(!pfn_valid(pfn))) {
-		/*
-		 * Page table corrupted: show pte and kill process.
-		 * Or it's an attempt to COW an out-of-map VM_UNPAGED
-		 * entry, which copy_user_highpage does not support.
-		 */
-		print_bad_pte(vma, orig_pte, address);
-		ret = VM_FAULT_OOM;
-		goto unlock;
-	}
-	old_page = pfn_to_page(pfn);
-	src_page = old_page;
-
-	if (unlikely(vma->vm_flags & VM_UNPAGED))
-		if (!page_is_anon(old_page, vma, address)) {
-			old_page = NULL;
-			goto gotten;
-		}
+	old_page = vm_normal_page(vma, address, orig_pte);
+	if (!old_page)
+		goto gotten;
 
 	if (PageAnon(old_page) && !TestSetPageLocked(old_page)) {
 		int reuse = can_share_swap_page(old_page);
 		unlock_page(old_page);
 		if (reuse) {
-			flush_cache_page(vma, address, pfn);
+			flush_cache_page(vma, address, pte_pfn(orig_pte));
 			entry = pte_mkyoung(orig_pte);
 			entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 			ptep_set_access_flags(vma, address, page_table, entry, 1);
@@ -1343,7 +1467,7 @@
 
 	if (unlikely(anon_vma_prepare(vma)))
 		goto oom;
-	if (src_page == ZERO_PAGE(address)) {
+	if (old_page == ZERO_PAGE(address)) {
 		new_page = alloc_zeroed_user_highpage(vma, address);
 		if (!new_page)
 			goto oom;
@@ -1351,7 +1475,7 @@
 		new_page = alloc_page_vma(GFP_HIGHUSER, vma, address);
 		if (!new_page)
 			goto oom;
-		copy_user_highpage(new_page, src_page, address);
+		cow_user_page(new_page, old_page, address);
 	}
 
 	/*
@@ -1367,14 +1491,14 @@
 			}
 		} else
 			inc_mm_counter(mm, anon_rss);
-		flush_cache_page(vma, address, pfn);
+		flush_cache_page(vma, address, pte_pfn(orig_pte));
 		entry = mk_pte(new_page, vma->vm_page_prot);
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 		ptep_establish(vma, address, page_table, entry);
 		update_mmu_cache(vma, address, entry);
 		lazy_mmu_prot_update(entry);
 		lru_cache_add_active(new_page);
-		page_add_anon_rmap(new_page, vma, address);
+		page_add_new_anon_rmap(new_page, vma, address);
 
 		/* Free the old page.. */
 		new_page = old_page;
@@ -1646,9 +1770,32 @@
 out_busy:
 	return -ETXTBSY;
 }
-
 EXPORT_SYMBOL(vmtruncate);
 
+int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end)
+{
+	struct address_space *mapping = inode->i_mapping;
+
+	/*
+	 * If the underlying filesystem is not going to provide
+	 * a way to truncate a range of blocks (punch a hole) -
+	 * we should return failure right now.
+	 */
+	if (!inode->i_op || !inode->i_op->truncate_range)
+		return -ENOSYS;
+
+	down(&inode->i_sem);
+	down_write(&inode->i_alloc_sem);
+	unmap_mapping_range(mapping, offset, (end - offset), 1);
+	truncate_inode_pages_range(mapping, offset, end);
+	inode->i_op->truncate_range(inode, offset, end);
+	up_write(&inode->i_alloc_sem);
+	up(&inode->i_sem);
+
+	return 0;
+}
+EXPORT_SYMBOL(vmtruncate_range);
+
 /* 
  * Primitive swap readahead code. We simply read an aligned block of
  * (1 << page_cluster) entries in the swap area. This method is chosen
@@ -1812,16 +1959,7 @@
 	spinlock_t *ptl;
 	pte_t entry;
 
-	/*
-	 * A VM_UNPAGED vma will normally be filled with present ptes
-	 * by remap_pfn_range, and never arrive here; but it might have
-	 * holes, or if !VM_DONTEXPAND, mremap might have expanded it.
-	 * It's weird enough handling anon pages in unpaged vmas, we do
-	 * not want to worry about ZERO_PAGEs too (it may or may not
-	 * matter if their counts wrap): just give them anon pages.
-	 */
-
-	if (write_access || (vma->vm_flags & VM_UNPAGED)) {
+	if (write_access) {
 		/* Allocate our own private page. */
 		pte_unmap(page_table);
 
@@ -1839,8 +1977,7 @@
 			goto release;
 		inc_mm_counter(mm, anon_rss);
 		lru_cache_add_active(page);
-		SetPageReferenced(page);
-		page_add_anon_rmap(page, vma, address);
+		page_add_new_anon_rmap(page, vma, address);
 	} else {
 		/* Map the ZERO_PAGE - vm_page_prot is readonly */
 		page = ZERO_PAGE(address);
@@ -1896,7 +2033,7 @@
 	int anon = 0;
 
 	pte_unmap(page_table);
-	BUG_ON(vma->vm_flags & VM_UNPAGED);
+	BUG_ON(vma->vm_flags & VM_PFNMAP);
 
 	if (vma->vm_file) {
 		mapping = vma->vm_file->f_mapping;
@@ -1971,7 +2108,7 @@
 		if (anon) {
 			inc_mm_counter(mm, anon_rss);
 			lru_cache_add_active(new_page);
-			page_add_anon_rmap(new_page, vma, address);
+			page_add_new_anon_rmap(new_page, vma, address);
 		} else {
 			inc_mm_counter(mm, file_rss);
 			page_add_file_rmap(new_page);
@@ -2149,6 +2286,12 @@
 	spin_unlock(&mm->page_table_lock);
 	return 0;
 }
+#else
+/* Workaround for gcc 2.96 */
+int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address)
+{
+	return 0;
+}
 #endif /* __PAGETABLE_PUD_FOLDED */
 
 #ifndef __PAGETABLE_PMD_FOLDED
@@ -2177,6 +2320,12 @@
 	spin_unlock(&mm->page_table_lock);
 	return 0;
 }
+#else
+/* Workaround for gcc 2.96 */
+int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address)
+{
+	return 0;
+}
 #endif /* __PAGETABLE_PMD_FOLDED */
 
 int make_pages_present(unsigned long addr, unsigned long end)
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 431a64f..a918f77 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -42,7 +42,6 @@
 				  int nr_pages);
 static int __add_section(struct zone *zone, unsigned long phys_start_pfn)
 {
-	struct pglist_data *pgdat = zone->zone_pgdat;
 	int nr_pages = PAGES_PER_SECTION;
 	int ret;
 
@@ -104,7 +103,7 @@
 		pgdat->node_start_pfn = start_pfn;
 
 	if (end_pfn > old_pgdat_end_pfn)
-		pgdat->node_spanned_pages = end_pfn - pgdat->node_spanned_pages;
+		pgdat->node_spanned_pages = end_pfn - pgdat->node_start_pfn;
 }
 
 int online_pages(unsigned long pfn, unsigned long nr_pages)
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 5609a31..1850d0a 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -83,9 +83,18 @@
 #include <linux/init.h>
 #include <linux/compat.h>
 #include <linux/mempolicy.h>
+#include <linux/swap.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+
 #include <asm/tlbflush.h>
 #include <asm/uaccess.h>
 
+/* Internal flags */
+#define MPOL_MF_DISCONTIG_OK (MPOL_MF_INTERNAL << 0)	/* Skip checks for continuous vmas */
+#define MPOL_MF_INVERT (MPOL_MF_INTERNAL << 1)		/* Invert check for nodemask */
+#define MPOL_MF_STATS (MPOL_MF_INTERNAL << 2)		/* Gather statistics */
+
 static kmem_cache_t *policy_cache;
 static kmem_cache_t *sn_cache;
 
@@ -93,7 +102,7 @@
 
 /* Highest zone. An specific allocation for a zone below that is not
    policied. */
-static int policy_zone;
+int policy_zone = ZONE_DMA;
 
 struct mempolicy default_policy = {
 	.refcnt = ATOMIC_INIT(1), /* never free it */
@@ -131,17 +140,8 @@
 	if (!zl)
 		return NULL;
 	num = 0;
-	for_each_node_mask(nd, *nodes) {
-		int k;
-		for (k = MAX_NR_ZONES-1; k >= 0; k--) {
-			struct zone *z = &NODE_DATA(nd)->node_zones[k];
-			if (!z->present_pages)
-				continue;
-			zl->zones[num++] = z;
-			if (k > policy_zone)
-				policy_zone = k;
-		}
-	}
+	for_each_node_mask(nd, *nodes)
+		zl->zones[num++] = &NODE_DATA(nd)->node_zones[policy_zone];
 	zl->zones[num] = NULL;
 	return zl;
 }
@@ -161,6 +161,10 @@
 	switch (mode) {
 	case MPOL_INTERLEAVE:
 		policy->v.nodes = *nodes;
+		if (nodes_weight(*nodes) == 0) {
+			kmem_cache_free(policy_cache, policy);
+			return ERR_PTR(-EINVAL);
+		}
 		break;
 	case MPOL_PREFERRED:
 		policy->v.preferred_node = first_node(*nodes);
@@ -176,12 +180,19 @@
 		break;
 	}
 	policy->policy = mode;
+	policy->cpuset_mems_allowed = cpuset_mems_allowed(current);
 	return policy;
 }
 
-/* Ensure all existing pages follow the policy. */
+static void gather_stats(struct page *, void *);
+static void migrate_page_add(struct vm_area_struct *vma,
+	struct page *page, struct list_head *pagelist, unsigned long flags);
+
+/* Scan through pages checking if pages follow certain conditions. */
 static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
-		unsigned long addr, unsigned long end, nodemask_t *nodes)
+		unsigned long addr, unsigned long end,
+		const nodemask_t *nodes, unsigned long flags,
+		void *private)
 {
 	pte_t *orig_pte;
 	pte_t *pte;
@@ -189,18 +200,26 @@
 
 	orig_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
 	do {
-		unsigned long pfn;
+		struct page *page;
 		unsigned int nid;
 
 		if (!pte_present(*pte))
 			continue;
-		pfn = pte_pfn(*pte);
-		if (!pfn_valid(pfn)) {
-			print_bad_pte(vma, *pte, addr);
+		page = vm_normal_page(vma, addr, *pte);
+		if (!page)
 			continue;
+		nid = page_to_nid(page);
+		if (node_isset(nid, *nodes) == !!(flags & MPOL_MF_INVERT))
+			continue;
+
+		if (flags & MPOL_MF_STATS)
+			gather_stats(page, private);
+		else if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) {
+			spin_unlock(ptl);
+			migrate_page_add(vma, page, private, flags);
+			spin_lock(ptl);
 		}
-		nid = pfn_to_nid(pfn);
-		if (!node_isset(nid, *nodes))
+		else
 			break;
 	} while (pte++, addr += PAGE_SIZE, addr != end);
 	pte_unmap_unlock(orig_pte, ptl);
@@ -208,7 +227,9 @@
 }
 
 static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud,
-		unsigned long addr, unsigned long end, nodemask_t *nodes)
+		unsigned long addr, unsigned long end,
+		const nodemask_t *nodes, unsigned long flags,
+		void *private)
 {
 	pmd_t *pmd;
 	unsigned long next;
@@ -218,14 +239,17 @@
 		next = pmd_addr_end(addr, end);
 		if (pmd_none_or_clear_bad(pmd))
 			continue;
-		if (check_pte_range(vma, pmd, addr, next, nodes))
+		if (check_pte_range(vma, pmd, addr, next, nodes,
+				    flags, private))
 			return -EIO;
 	} while (pmd++, addr = next, addr != end);
 	return 0;
 }
 
 static inline int check_pud_range(struct vm_area_struct *vma, pgd_t *pgd,
-		unsigned long addr, unsigned long end, nodemask_t *nodes)
+		unsigned long addr, unsigned long end,
+		const nodemask_t *nodes, unsigned long flags,
+		void *private)
 {
 	pud_t *pud;
 	unsigned long next;
@@ -235,14 +259,17 @@
 		next = pud_addr_end(addr, end);
 		if (pud_none_or_clear_bad(pud))
 			continue;
-		if (check_pmd_range(vma, pud, addr, next, nodes))
+		if (check_pmd_range(vma, pud, addr, next, nodes,
+				    flags, private))
 			return -EIO;
 	} while (pud++, addr = next, addr != end);
 	return 0;
 }
 
 static inline int check_pgd_range(struct vm_area_struct *vma,
-		unsigned long addr, unsigned long end, nodemask_t *nodes)
+		unsigned long addr, unsigned long end,
+		const nodemask_t *nodes, unsigned long flags,
+		void *private)
 {
 	pgd_t *pgd;
 	unsigned long next;
@@ -252,16 +279,30 @@
 		next = pgd_addr_end(addr, end);
 		if (pgd_none_or_clear_bad(pgd))
 			continue;
-		if (check_pud_range(vma, pgd, addr, next, nodes))
+		if (check_pud_range(vma, pgd, addr, next, nodes,
+				    flags, private))
 			return -EIO;
 	} while (pgd++, addr = next, addr != end);
 	return 0;
 }
 
-/* Step 1: check the range */
+/* Check if a vma is migratable */
+static inline int vma_migratable(struct vm_area_struct *vma)
+{
+	if (vma->vm_flags & (
+		VM_LOCKED|VM_IO|VM_HUGETLB|VM_PFNMAP))
+		return 0;
+	return 1;
+}
+
+/*
+ * Check if all pages in a range are on a set of nodes.
+ * If pagelist != NULL then isolate pages from the LRU and
+ * put them on the pagelist.
+ */
 static struct vm_area_struct *
 check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
-	    nodemask_t *nodes, unsigned long flags)
+		const nodemask_t *nodes, unsigned long flags, void *private)
 {
 	int err;
 	struct vm_area_struct *first, *vma, *prev;
@@ -269,21 +310,26 @@
 	first = find_vma(mm, start);
 	if (!first)
 		return ERR_PTR(-EFAULT);
-	if (first->vm_flags & VM_UNPAGED)
-		return ERR_PTR(-EACCES);
 	prev = NULL;
 	for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) {
-		if (!vma->vm_next && vma->vm_end < end)
-			return ERR_PTR(-EFAULT);
-		if (prev && prev->vm_end < vma->vm_start)
-			return ERR_PTR(-EFAULT);
-		if ((flags & MPOL_MF_STRICT) && !is_vm_hugetlb_page(vma)) {
+		if (!(flags & MPOL_MF_DISCONTIG_OK)) {
+			if (!vma->vm_next && vma->vm_end < end)
+				return ERR_PTR(-EFAULT);
+			if (prev && prev->vm_end < vma->vm_start)
+				return ERR_PTR(-EFAULT);
+		}
+		if (!is_vm_hugetlb_page(vma) &&
+		    ((flags & MPOL_MF_STRICT) ||
+		     ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
+				vma_migratable(vma)))) {
 			unsigned long endvma = vma->vm_end;
+
 			if (endvma > end)
 				endvma = end;
 			if (vma->vm_start > start)
 				start = vma->vm_start;
-			err = check_pgd_range(vma, start, endvma, nodes);
+			err = check_pgd_range(vma, start, endvma, nodes,
+						flags, private);
 			if (err) {
 				first = ERR_PTR(err);
 				break;
@@ -342,53 +388,12 @@
 	if (!nodes)
 		return 0;
 
-	/* Update current mems_allowed */
-	cpuset_update_current_mems_allowed();
-	/* Ignore nodes not set in current->mems_allowed */
-	cpuset_restrict_to_mems_allowed(nodes->bits);
+	cpuset_update_task_memory_state();
+	if (!cpuset_nodes_subset_current_mems_allowed(*nodes))
+		return -EINVAL;
 	return mpol_check_policy(mode, nodes);
 }
 
-long do_mbind(unsigned long start, unsigned long len,
-		unsigned long mode, nodemask_t *nmask, unsigned long flags)
-{
-	struct vm_area_struct *vma;
-	struct mm_struct *mm = current->mm;
-	struct mempolicy *new;
-	unsigned long end;
-	int err;
-
-	if ((flags & ~(unsigned long)(MPOL_MF_STRICT)) || mode > MPOL_MAX)
-		return -EINVAL;
-	if (start & ~PAGE_MASK)
-		return -EINVAL;
-	if (mode == MPOL_DEFAULT)
-		flags &= ~MPOL_MF_STRICT;
-	len = (len + PAGE_SIZE - 1) & PAGE_MASK;
-	end = start + len;
-	if (end < start)
-		return -EINVAL;
-	if (end == start)
-		return 0;
-	if (mpol_check_policy(mode, nmask))
-		return -EINVAL;
-	new = mpol_new(mode, nmask);
-	if (IS_ERR(new))
-		return PTR_ERR(new);
-
-	PDprintk("mbind %lx-%lx mode:%ld nodes:%lx\n",start,start+len,
-			mode,nodes_addr(nodes)[0]);
-
-	down_write(&mm->mmap_sem);
-	vma = check_range(mm, start, end, nmask, flags);
-	err = PTR_ERR(vma);
-	if (!IS_ERR(vma))
-		err = mbind_range(vma, start, end, new);
-	up_write(&mm->mmap_sem);
-	mpol_free(new);
-	return err;
-}
-
 /* Set the process memory policy */
 long do_set_mempolicy(int mode, nodemask_t *nodes)
 {
@@ -457,7 +462,7 @@
 	struct vm_area_struct *vma = NULL;
 	struct mempolicy *pol = current->mempolicy;
 
-	cpuset_update_current_mems_allowed();
+	cpuset_update_task_memory_state();
 	if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR))
 		return -EINVAL;
 	if (flags & MPOL_F_ADDR) {
@@ -509,11 +514,177 @@
 }
 
 /*
+ * page migration
+ */
+
+/* Check if we are the only process mapping the page in question */
+static inline int single_mm_mapping(struct mm_struct *mm,
+			struct address_space *mapping)
+{
+	struct vm_area_struct *vma;
+	struct prio_tree_iter iter;
+	int rc = 1;
+
+	spin_lock(&mapping->i_mmap_lock);
+	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, 0, ULONG_MAX)
+		if (mm != vma->vm_mm) {
+			rc = 0;
+			goto out;
+		}
+	list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list)
+		if (mm != vma->vm_mm) {
+			rc = 0;
+			goto out;
+		}
+out:
+	spin_unlock(&mapping->i_mmap_lock);
+	return rc;
+}
+
+/*
+ * Add a page to be migrated to the pagelist
+ */
+static void migrate_page_add(struct vm_area_struct *vma,
+	struct page *page, struct list_head *pagelist, unsigned long flags)
+{
+	/*
+	 * Avoid migrating a page that is shared by others and not writable.
+	 */
+	if ((flags & MPOL_MF_MOVE_ALL) || !page->mapping || PageAnon(page) ||
+	    mapping_writably_mapped(page->mapping) ||
+	    single_mm_mapping(vma->vm_mm, page->mapping)) {
+		int rc = isolate_lru_page(page);
+
+		if (rc == 1)
+			list_add(&page->lru, pagelist);
+		/*
+		 * If the isolate attempt was not successful then we just
+		 * encountered an unswappable page. Something must be wrong.
+	 	 */
+		WARN_ON(rc == 0);
+	}
+}
+
+static int swap_pages(struct list_head *pagelist)
+{
+	LIST_HEAD(moved);
+	LIST_HEAD(failed);
+	int n;
+
+	n = migrate_pages(pagelist, NULL, &moved, &failed);
+	putback_lru_pages(&failed);
+	putback_lru_pages(&moved);
+
+	return n;
+}
+
+/*
+ * For now migrate_pages simply swaps out the pages from nodes that are in
+ * the source set but not in the target set. In the future, we would
+ * want a function that moves pages between the two nodesets in such
+ * a way as to preserve the physical layout as much as possible.
+ *
+ * Returns the number of page that could not be moved.
+ */
+int do_migrate_pages(struct mm_struct *mm,
+	const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags)
+{
+	LIST_HEAD(pagelist);
+	int count = 0;
+	nodemask_t nodes;
+
+	nodes_andnot(nodes, *from_nodes, *to_nodes);
+
+	down_read(&mm->mmap_sem);
+	check_range(mm, mm->mmap->vm_start, TASK_SIZE, &nodes,
+			flags | MPOL_MF_DISCONTIG_OK, &pagelist);
+
+	if (!list_empty(&pagelist)) {
+		count = swap_pages(&pagelist);
+		putback_lru_pages(&pagelist);
+	}
+
+	up_read(&mm->mmap_sem);
+	return count;
+}
+
+long do_mbind(unsigned long start, unsigned long len,
+		unsigned long mode, nodemask_t *nmask, unsigned long flags)
+{
+	struct vm_area_struct *vma;
+	struct mm_struct *mm = current->mm;
+	struct mempolicy *new;
+	unsigned long end;
+	int err;
+	LIST_HEAD(pagelist);
+
+	if ((flags & ~(unsigned long)(MPOL_MF_STRICT |
+				      MPOL_MF_MOVE | MPOL_MF_MOVE_ALL))
+	    || mode > MPOL_MAX)
+		return -EINVAL;
+	if ((flags & MPOL_MF_MOVE_ALL) && !capable(CAP_SYS_RESOURCE))
+		return -EPERM;
+
+	if (start & ~PAGE_MASK)
+		return -EINVAL;
+
+	if (mode == MPOL_DEFAULT)
+		flags &= ~MPOL_MF_STRICT;
+
+	len = (len + PAGE_SIZE - 1) & PAGE_MASK;
+	end = start + len;
+
+	if (end < start)
+		return -EINVAL;
+	if (end == start)
+		return 0;
+
+	if (mpol_check_policy(mode, nmask))
+		return -EINVAL;
+
+	new = mpol_new(mode, nmask);
+	if (IS_ERR(new))
+		return PTR_ERR(new);
+
+	/*
+	 * If we are using the default policy then operation
+	 * on discontinuous address spaces is okay after all
+	 */
+	if (!new)
+		flags |= MPOL_MF_DISCONTIG_OK;
+
+	PDprintk("mbind %lx-%lx mode:%ld nodes:%lx\n",start,start+len,
+			mode,nodes_addr(nodes)[0]);
+
+	down_write(&mm->mmap_sem);
+	vma = check_range(mm, start, end, nmask,
+			  flags | MPOL_MF_INVERT, &pagelist);
+
+	err = PTR_ERR(vma);
+	if (!IS_ERR(vma)) {
+		int nr_failed = 0;
+
+		err = mbind_range(vma, start, end, new);
+		if (!list_empty(&pagelist))
+			nr_failed = swap_pages(&pagelist);
+
+		if (!err && nr_failed && (flags & MPOL_MF_STRICT))
+			err = -EIO;
+	}
+	if (!list_empty(&pagelist))
+		putback_lru_pages(&pagelist);
+
+	up_write(&mm->mmap_sem);
+	mpol_free(new);
+	return err;
+}
+
+/*
  * User space interface with variable sized bitmaps for nodelists.
  */
 
 /* Copy a node mask from user space. */
-static int get_nodes(nodemask_t *nodes, unsigned long __user *nmask,
+static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask,
 		     unsigned long maxnode)
 {
 	unsigned long k;
@@ -602,6 +773,65 @@
 	return do_set_mempolicy(mode, &nodes);
 }
 
+asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
+		const unsigned long __user *old_nodes,
+		const unsigned long __user *new_nodes)
+{
+	struct mm_struct *mm;
+	struct task_struct *task;
+	nodemask_t old;
+	nodemask_t new;
+	nodemask_t task_nodes;
+	int err;
+
+	err = get_nodes(&old, old_nodes, maxnode);
+	if (err)
+		return err;
+
+	err = get_nodes(&new, new_nodes, maxnode);
+	if (err)
+		return err;
+
+	/* Find the mm_struct */
+	read_lock(&tasklist_lock);
+	task = pid ? find_task_by_pid(pid) : current;
+	if (!task) {
+		read_unlock(&tasklist_lock);
+		return -ESRCH;
+	}
+	mm = get_task_mm(task);
+	read_unlock(&tasklist_lock);
+
+	if (!mm)
+		return -EINVAL;
+
+	/*
+	 * Check if this process has the right to modify the specified
+	 * process. The right exists if the process has administrative
+	 * capabilities, superuser priviledges or the same
+	 * userid as the target process.
+	 */
+	if ((current->euid != task->suid) && (current->euid != task->uid) &&
+	    (current->uid != task->suid) && (current->uid != task->uid) &&
+	    !capable(CAP_SYS_ADMIN)) {
+		err = -EPERM;
+		goto out;
+	}
+
+	task_nodes = cpuset_mems_allowed(task);
+	/* Is the user allowed to access the target nodes? */
+	if (!nodes_subset(new, task_nodes) && !capable(CAP_SYS_ADMIN)) {
+		err = -EPERM;
+		goto out;
+	}
+
+	err = do_migrate_pages(mm, &old, &new, MPOL_MF_MOVE);
+out:
+	mmput(mm);
+	return err;
+}
+
+
 /* Retrieve NUMA policy */
 asmlinkage long sys_get_mempolicy(int __user *policy,
 				unsigned long __user *nmask,
@@ -708,8 +938,8 @@
 #endif
 
 /* Return effective policy for a VMA */
-struct mempolicy *
-get_vma_policy(struct task_struct *task, struct vm_area_struct *vma, unsigned long addr)
+static struct mempolicy * get_vma_policy(struct task_struct *task,
+		struct vm_area_struct *vma, unsigned long addr)
 {
 	struct mempolicy *pol = task->mempolicy;
 
@@ -785,6 +1015,34 @@
 	return nid;
 }
 
+/* Determine a node number for interleave */
+static inline unsigned interleave_nid(struct mempolicy *pol,
+		 struct vm_area_struct *vma, unsigned long addr, int shift)
+{
+	if (vma) {
+		unsigned long off;
+
+		off = vma->vm_pgoff;
+		off += (addr - vma->vm_start) >> shift;
+		return offset_il_node(pol, vma, off);
+	} else
+		return interleave_nodes(pol);
+}
+
+/* Return a zonelist suitable for a huge page allocation. */
+struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr)
+{
+	struct mempolicy *pol = get_vma_policy(current, vma, addr);
+
+	if (pol->policy == MPOL_INTERLEAVE) {
+		unsigned nid;
+
+		nid = interleave_nid(pol, vma, addr, HPAGE_SHIFT);
+		return NODE_DATA(nid)->node_zonelists + gfp_zone(GFP_HIGHUSER);
+	}
+	return zonelist_policy(GFP_HIGHUSER, pol);
+}
+
 /* Allocate a page in interleaved policy.
    Own path because it needs to do special accounting. */
 static struct page *alloc_page_interleave(gfp_t gfp, unsigned order,
@@ -829,19 +1087,12 @@
 {
 	struct mempolicy *pol = get_vma_policy(current, vma, addr);
 
-	cpuset_update_current_mems_allowed();
+	cpuset_update_task_memory_state();
 
 	if (unlikely(pol->policy == MPOL_INTERLEAVE)) {
 		unsigned nid;
-		if (vma) {
-			unsigned long off;
-			off = vma->vm_pgoff;
-			off += (addr - vma->vm_start) >> PAGE_SHIFT;
-			nid = offset_il_node(pol, vma, off);
-		} else {
-			/* fall back to process interleaving */
-			nid = interleave_nodes(pol);
-		}
+
+		nid = interleave_nid(pol, vma, addr, PAGE_SHIFT);
 		return alloc_page_interleave(gfp, 0, nid);
 	}
 	return __alloc_pages(gfp, 0, zonelist_policy(gfp, pol));
@@ -862,7 +1113,7 @@
  *	interrupt context and apply the current process NUMA policy.
  *	Returns NULL when no page can be allocated.
  *
- *	Don't call cpuset_update_current_mems_allowed() unless
+ *	Don't call cpuset_update_task_memory_state() unless
  *	1) it's ok to take cpuset_sem (can WAIT), and
  *	2) allocating for current task (not interrupt).
  */
@@ -871,7 +1122,7 @@
 	struct mempolicy *pol = current->mempolicy;
 
 	if ((gfp & __GFP_WAIT) && !in_interrupt())
-		cpuset_update_current_mems_allowed();
+		cpuset_update_task_memory_state();
 	if (!pol || in_interrupt())
 		pol = &default_policy;
 	if (pol->policy == MPOL_INTERLEAVE)
@@ -880,6 +1131,15 @@
 }
 EXPORT_SYMBOL(alloc_pages_current);
 
+/*
+ * If mpol_copy() sees current->cpuset == cpuset_being_rebound, then it
+ * rebinds the mempolicy its copying by calling mpol_rebind_policy()
+ * with the mems_allowed returned by cpuset_mems_allowed().  This
+ * keeps mempolicies cpuset relative after its cpuset moves.  See
+ * further kernel/cpuset.c update_nodemask().
+ */
+void *cpuset_being_rebound;
+
 /* Slow path of a mempolicy copy */
 struct mempolicy *__mpol_copy(struct mempolicy *old)
 {
@@ -887,6 +1147,10 @@
 
 	if (!new)
 		return ERR_PTR(-ENOMEM);
+	if (current_cpuset_is_being_rebound()) {
+		nodemask_t mems = cpuset_mems_allowed(current);
+		mpol_rebind_policy(old, &mems);
+	}
 	*new = *old;
 	atomic_set(&new->refcnt, 1);
 	if (new->policy == MPOL_BIND) {
@@ -940,54 +1204,6 @@
 }
 
 /*
- * Hugetlb policy. Same as above, just works with node numbers instead of
- * zonelists.
- */
-
-/* Find first node suitable for an allocation */
-int mpol_first_node(struct vm_area_struct *vma, unsigned long addr)
-{
-	struct mempolicy *pol = get_vma_policy(current, vma, addr);
-
-	switch (pol->policy) {
-	case MPOL_DEFAULT:
-		return numa_node_id();
-	case MPOL_BIND:
-		return pol->v.zonelist->zones[0]->zone_pgdat->node_id;
-	case MPOL_INTERLEAVE:
-		return interleave_nodes(pol);
-	case MPOL_PREFERRED:
-		return pol->v.preferred_node >= 0 ?
-				pol->v.preferred_node : numa_node_id();
-	}
-	BUG();
-	return 0;
-}
-
-/* Find secondary valid nodes for an allocation */
-int mpol_node_valid(int nid, struct vm_area_struct *vma, unsigned long addr)
-{
-	struct mempolicy *pol = get_vma_policy(current, vma, addr);
-
-	switch (pol->policy) {
-	case MPOL_PREFERRED:
-	case MPOL_DEFAULT:
-	case MPOL_INTERLEAVE:
-		return 1;
-	case MPOL_BIND: {
-		struct zone **z;
-		for (z = pol->v.zonelist->zones; *z; z++)
-			if ((*z)->zone_pgdat->node_id == nid)
-				return 1;
-		return 0;
-	}
-	default:
-		BUG();
-		return 0;
-	}
-}
-
-/*
  * Shared memory backing store policy support.
  *
  * Remember policies even when nobody has shared memory mapped.
@@ -1209,25 +1425,31 @@
 }
 
 /* Migrate a policy to a different set of nodes */
-static void rebind_policy(struct mempolicy *pol, const nodemask_t *old,
-							const nodemask_t *new)
+void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *newmask)
 {
+	nodemask_t *mpolmask;
 	nodemask_t tmp;
 
 	if (!pol)
 		return;
+	mpolmask = &pol->cpuset_mems_allowed;
+	if (nodes_equal(*mpolmask, *newmask))
+		return;
 
 	switch (pol->policy) {
 	case MPOL_DEFAULT:
 		break;
 	case MPOL_INTERLEAVE:
-		nodes_remap(tmp, pol->v.nodes, *old, *new);
+		nodes_remap(tmp, pol->v.nodes, *mpolmask, *newmask);
 		pol->v.nodes = tmp;
-		current->il_next = node_remap(current->il_next, *old, *new);
+		*mpolmask = *newmask;
+		current->il_next = node_remap(current->il_next,
+						*mpolmask, *newmask);
 		break;
 	case MPOL_PREFERRED:
 		pol->v.preferred_node = node_remap(pol->v.preferred_node,
-								*old, *new);
+						*mpolmask, *newmask);
+		*mpolmask = *newmask;
 		break;
 	case MPOL_BIND: {
 		nodemask_t nodes;
@@ -1237,7 +1459,7 @@
 		nodes_clear(nodes);
 		for (z = pol->v.zonelist->zones; *z; z++)
 			node_set((*z)->zone_pgdat->node_id, nodes);
-		nodes_remap(tmp, nodes, *old, *new);
+		nodes_remap(tmp, nodes, *mpolmask, *newmask);
 		nodes = tmp;
 
 		zonelist = bind_zonelist(&nodes);
@@ -1252,6 +1474,7 @@
 			kfree(pol->v.zonelist);
 			pol->v.zonelist = zonelist;
 		}
+		*mpolmask = *newmask;
 		break;
 	}
 	default:
@@ -1261,12 +1484,156 @@
 }
 
 /*
- * Someone moved this task to different nodes.  Fixup mempolicies.
- *
- * TODO - fixup current->mm->vma and shmfs/tmpfs/hugetlbfs policies as well,
- * once we have a cpuset mechanism to mark which cpuset subtree is migrating.
+ * Wrapper for mpol_rebind_policy() that just requires task
+ * pointer, and updates task mempolicy.
  */
-void numa_policy_rebind(const nodemask_t *old, const nodemask_t *new)
+
+void mpol_rebind_task(struct task_struct *tsk, const nodemask_t *new)
 {
-	rebind_policy(current->mempolicy, old, new);
+	mpol_rebind_policy(tsk->mempolicy, new);
 }
+
+/*
+ * Rebind each vma in mm to new nodemask.
+ *
+ * Call holding a reference to mm.  Takes mm->mmap_sem during call.
+ */
+
+void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new)
+{
+	struct vm_area_struct *vma;
+
+	down_write(&mm->mmap_sem);
+	for (vma = mm->mmap; vma; vma = vma->vm_next)
+		mpol_rebind_policy(vma->vm_policy, new);
+	up_write(&mm->mmap_sem);
+}
+
+/*
+ * Display pages allocated per node and memory policy via /proc.
+ */
+
+static const char *policy_types[] = { "default", "prefer", "bind",
+				      "interleave" };
+
+/*
+ * Convert a mempolicy into a string.
+ * Returns the number of characters in buffer (if positive)
+ * or an error (negative)
+ */
+static inline int mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol)
+{
+	char *p = buffer;
+	int l;
+	nodemask_t nodes;
+	int mode = pol ? pol->policy : MPOL_DEFAULT;
+
+	switch (mode) {
+	case MPOL_DEFAULT:
+		nodes_clear(nodes);
+		break;
+
+	case MPOL_PREFERRED:
+		nodes_clear(nodes);
+		node_set(pol->v.preferred_node, nodes);
+		break;
+
+	case MPOL_BIND:
+		get_zonemask(pol, &nodes);
+		break;
+
+	case MPOL_INTERLEAVE:
+		nodes = pol->v.nodes;
+		break;
+
+	default:
+		BUG();
+		return -EFAULT;
+	}
+
+	l = strlen(policy_types[mode]);
+ 	if (buffer + maxlen < p + l + 1)
+ 		return -ENOSPC;
+
+	strcpy(p, policy_types[mode]);
+	p += l;
+
+	if (!nodes_empty(nodes)) {
+		if (buffer + maxlen < p + 2)
+			return -ENOSPC;
+		*p++ = '=';
+	 	p += nodelist_scnprintf(p, buffer + maxlen - p, nodes);
+	}
+	return p - buffer;
+}
+
+struct numa_maps {
+	unsigned long pages;
+	unsigned long anon;
+	unsigned long mapped;
+	unsigned long mapcount_max;
+	unsigned long node[MAX_NUMNODES];
+};
+
+static void gather_stats(struct page *page, void *private)
+{
+	struct numa_maps *md = private;
+	int count = page_mapcount(page);
+
+	if (count)
+		md->mapped++;
+
+	if (count > md->mapcount_max)
+		md->mapcount_max = count;
+
+	md->pages++;
+
+	if (PageAnon(page))
+		md->anon++;
+
+	md->node[page_to_nid(page)]++;
+	cond_resched();
+}
+
+int show_numa_map(struct seq_file *m, void *v)
+{
+	struct task_struct *task = m->private;
+	struct vm_area_struct *vma = v;
+	struct numa_maps *md;
+	int n;
+	char buffer[50];
+
+	if (!vma->vm_mm)
+		return 0;
+
+	md = kzalloc(sizeof(struct numa_maps), GFP_KERNEL);
+	if (!md)
+		return 0;
+
+	check_pgd_range(vma, vma->vm_start, vma->vm_end,
+		    &node_online_map, MPOL_MF_STATS, md);
+
+	if (md->pages) {
+		mpol_to_str(buffer, sizeof(buffer),
+			    get_vma_policy(task, vma, vma->vm_start));
+
+		seq_printf(m, "%08lx %s pages=%lu mapped=%lu maxref=%lu",
+			   vma->vm_start, buffer, md->pages,
+			   md->mapped, md->mapcount_max);
+
+		if (md->anon)
+			seq_printf(m," anon=%lu",md->anon);
+
+		for_each_online_node(n)
+			if (md->node[n])
+				seq_printf(m, " N%d=%lu", n, md->node[n]);
+
+		seq_putc(m, '\n');
+	}
+	kfree(md);
+
+	if (m->count < m->size)
+		m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0;
+	return 0;
+}
+
diff --git a/mm/mmap.c b/mm/mmap.c
index 11ca592..64ba4db 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -611,7 +611,7 @@
  * If the vma has a ->close operation then the driver probably needs to release
  * per-vma resources, so we don't attempt to merge those.
  */
-#define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
+#define VM_SPECIAL (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
 
 static inline int is_mergeable_vma(struct vm_area_struct *vma,
 			struct file *file, unsigned long vm_flags)
diff --git a/mm/mremap.c b/mm/mremap.c
index b535438..ddaeee9 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -323,7 +323,7 @@
 	/* We can't remap across vm area boundaries */
 	if (old_len > vma->vm_end - addr)
 		goto out;
-	if (vma->vm_flags & VM_DONTEXPAND) {
+	if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) {
 		if (new_len > old_len)
 			goto out;
 	}
diff --git a/mm/msync.c b/mm/msync.c
index b3f4caf..1b5b6f6 100644
--- a/mm/msync.c
+++ b/mm/msync.c
@@ -27,7 +27,6 @@
 again:
 	pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
 	do {
-		unsigned long pfn;
 		struct page *page;
 
 		if (progress >= 64) {
@@ -40,13 +39,9 @@
 			continue;
 		if (!pte_maybe_dirty(*pte))
 			continue;
-		pfn = pte_pfn(*pte);
-		if (unlikely(!pfn_valid(pfn))) {
-			print_bad_pte(vma, *pte, addr);
+		page = vm_normal_page(vma, addr, *pte);
+		if (!page)
 			continue;
-		}
-		page = pfn_to_page(pfn);
-
 		if (ptep_clear_flush_dirty(vma, addr, pte) ||
 		    page_test_and_clear_dirty(page))
 			set_page_dirty(page);
@@ -97,9 +92,8 @@
 	/* For hugepages we can't go walking the page table normally,
 	 * but that's ok, hugetlbfs is memory based, so we don't need
 	 * to do anything more on an msync().
-	 * Can't do anything with VM_UNPAGED regions either.
 	 */
-	if (vma->vm_flags & (VM_HUGETLB|VM_UNPAGED))
+	if (vma->vm_flags & VM_HUGETLB)
 		return;
 
 	BUG_ON(addr >= end);
diff --git a/mm/nommu.c b/mm/nommu.c
index 6deb6ab..c10262d 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1045,7 +1045,7 @@
 
 EXPORT_SYMBOL(find_vma);
 
-struct page *follow_page(struct mm_struct *mm, unsigned long address,
+struct page *follow_page(struct vm_area_struct *vma, unsigned long address,
 			unsigned int foll_flags)
 {
 	return NULL;
@@ -1177,3 +1177,10 @@
 {
 	return 0;
 }
+
+struct page *filemap_nopage(struct vm_area_struct *area,
+			unsigned long address, int *type)
+{
+	BUG();
+	return NULL;
+}
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index d348b90..4748b90 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -298,7 +298,8 @@
 
 	/*
 	 * Give "p" a good chance of killing itself before we
-	 * retry to allocate memory.
+	 * retry to allocate memory unless "p" is current
 	 */
-	schedule_timeout_interruptible(1);
+	if (!test_thread_flag(TIF_MEMDIE))
+		schedule_timeout_interruptible(1);
 }
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 0166ea15..5240e42 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -550,11 +550,17 @@
 
 int do_writepages(struct address_space *mapping, struct writeback_control *wbc)
 {
+	int ret;
+
 	if (wbc->nr_to_write <= 0)
 		return 0;
+	wbc->for_writepages = 1;
 	if (mapping->a_ops->writepages)
-		return mapping->a_ops->writepages(mapping, wbc);
-	return generic_writepages(mapping, wbc);
+		ret =  mapping->a_ops->writepages(mapping, wbc);
+	else
+		ret = generic_writepages(mapping, wbc);
+	wbc->for_writepages = 0;
+	return ret;
 }
 
 /**
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1731236..e0e8492 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -36,6 +36,7 @@
 #include <linux/memory_hotplug.h>
 #include <linux/nodemask.h>
 #include <linux/vmalloc.h>
+#include <linux/mempolicy.h>
 
 #include <asm/tlbflush.h>
 #include "internal.h"
@@ -52,6 +53,9 @@
 unsigned long totalram_pages __read_mostly;
 unsigned long totalhigh_pages __read_mostly;
 long nr_swap_pages;
+int percpu_pagelist_fraction;
+
+static void fastcall free_hot_cold_page(struct page *page, int cold);
 
 /*
  * results with 256, 32 in the lowmem_reserve sysctl:
@@ -81,6 +85,7 @@
 unsigned long __initdata nr_kernel_pages;
 unsigned long __initdata nr_all_pages;
 
+#ifdef CONFIG_DEBUG_VM
 static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
 {
 	int ret = 0;
@@ -122,16 +127,23 @@
 	return 0;
 }
 
-static void bad_page(const char *function, struct page *page)
+#else
+static inline int bad_range(struct zone *zone, struct page *page)
 {
-	printk(KERN_EMERG "Bad page state at %s (in process '%s', page %p)\n",
-		function, current->comm, page);
-	printk(KERN_EMERG "flags:0x%0*lx mapping:%p mapcount:%d count:%d\n",
-		(int)(2*sizeof(unsigned long)), (unsigned long)page->flags,
-		page->mapping, page_mapcount(page), page_count(page));
-	printk(KERN_EMERG "Backtrace:\n");
+	return 0;
+}
+#endif
+
+static void bad_page(struct page *page)
+{
+	printk(KERN_EMERG "Bad page state in process '%s'\n"
+		"page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n"
+		"Trying to fix it up, but a reboot is needed\n"
+		"Backtrace:\n",
+		current->comm, page, (int)(2*sizeof(unsigned long)),
+		(unsigned long)page->flags, page->mapping,
+		page_mapcount(page), page_count(page));
 	dump_stack();
-	printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n");
 	page->flags &= ~(1 << PG_lru	|
 			1 << PG_private |
 			1 << PG_locked	|
@@ -184,19 +196,15 @@
 	int i;
 	int nr_pages = 1 << order;
 
-	if (!PageCompound(page))
-		return;
-
-	if (page[1].index != order)
-		bad_page(__FUNCTION__, page);
+	if (unlikely(page[1].index != order))
+		bad_page(page);
 
 	for (i = 0; i < nr_pages; i++) {
 		struct page *p = page + i;
 
-		if (!PageCompound(p))
-			bad_page(__FUNCTION__, page);
-		if (page_private(p) != (unsigned long)page)
-			bad_page(__FUNCTION__, page);
+		if (unlikely(!PageCompound(p) |
+				(page_private(p) != (unsigned long)page)))
+			bad_page(page);
 		ClearPageCompound(p);
 	}
 }
@@ -255,14 +263,20 @@
 /*
  * This function checks whether a page is free && is the buddy
  * we can do coalesce a page and its buddy if
- * (a) the buddy is free &&
- * (b) the buddy is on the buddy system &&
- * (c) a page and its buddy have the same order.
+ * (a) the buddy is not in a hole &&
+ * (b) the buddy is free &&
+ * (c) the buddy is on the buddy system &&
+ * (d) a page and its buddy have the same order.
  * for recording page's order, we use page_private(page) and PG_private.
  *
  */
 static inline int page_is_buddy(struct page *page, int order)
 {
+#ifdef CONFIG_HOLES_IN_ZONE
+	if (!pfn_valid(page_to_pfn(page)))
+		return 0;
+#endif
+
        if (PagePrivate(page)           &&
            (page_order(page) == order) &&
             page_count(page) == 0)
@@ -294,13 +308,13 @@
  * -- wli
  */
 
-static inline void __free_pages_bulk (struct page *page,
+static inline void __free_one_page(struct page *page,
 		struct zone *zone, unsigned int order)
 {
 	unsigned long page_idx;
 	int order_size = 1 << order;
 
-	if (unlikely(order))
+	if (unlikely(PageCompound(page)))
 		destroy_compound_page(page, order);
 
 	page_idx = page_to_pfn(page) & ((1 << MAX_ORDER) - 1);
@@ -314,17 +328,15 @@
 		struct free_area *area;
 		struct page *buddy;
 
-		combined_idx = __find_combined_index(page_idx, order);
 		buddy = __page_find_buddy(page, page_idx, order);
-
-		if (bad_range(zone, buddy))
-			break;
 		if (!page_is_buddy(buddy, order))
 			break;		/* Move the buddy up one level. */
+
 		list_del(&buddy->lru);
 		area = zone->free_area + order;
 		area->nr_free--;
 		rmv_page_order(buddy);
+		combined_idx = __find_combined_index(page_idx, order);
 		page = page + (combined_idx - page_idx);
 		page_idx = combined_idx;
 		order++;
@@ -334,11 +346,11 @@
 	zone->free_area[order].nr_free++;
 }
 
-static inline int free_pages_check(const char *function, struct page *page)
+static inline int free_pages_check(struct page *page)
 {
-	if (	page_mapcount(page) ||
-		page->mapping != NULL ||
-		page_count(page) != 0 ||
+	if (unlikely(page_mapcount(page) |
+		(page->mapping != NULL)  |
+		(page_count(page) != 0)  |
 		(page->flags & (
 			1 << PG_lru	|
 			1 << PG_private |
@@ -348,8 +360,8 @@
 			1 << PG_slab	|
 			1 << PG_swapcache |
 			1 << PG_writeback |
-			1 << PG_reserved )))
-		bad_page(function, page);
+			1 << PG_reserved ))))
+		bad_page(page);
 	if (PageDirty(page))
 		__ClearPageDirty(page);
 	/*
@@ -371,51 +383,87 @@
  * And clear the zone's pages_scanned counter, to hold off the "all pages are
  * pinned" detection logic.
  */
-static int
-free_pages_bulk(struct zone *zone, int count,
-		struct list_head *list, unsigned int order)
+static void free_pages_bulk(struct zone *zone, int count,
+					struct list_head *list, int order)
 {
-	unsigned long flags;
-	struct page *page = NULL;
-	int ret = 0;
-
-	spin_lock_irqsave(&zone->lock, flags);
+	spin_lock(&zone->lock);
 	zone->all_unreclaimable = 0;
 	zone->pages_scanned = 0;
-	while (!list_empty(list) && count--) {
+	while (count--) {
+		struct page *page;
+
+		BUG_ON(list_empty(list));
 		page = list_entry(list->prev, struct page, lru);
-		/* have to delete it as __free_pages_bulk list manipulates */
+		/* have to delete it as __free_one_page list manipulates */
 		list_del(&page->lru);
-		__free_pages_bulk(page, zone, order);
-		ret++;
+		__free_one_page(page, zone, order);
 	}
-	spin_unlock_irqrestore(&zone->lock, flags);
-	return ret;
+	spin_unlock(&zone->lock);
 }
 
-void __free_pages_ok(struct page *page, unsigned int order)
+static void free_one_page(struct zone *zone, struct page *page, int order)
 {
 	LIST_HEAD(list);
+	list_add(&page->lru, &list);
+	free_pages_bulk(zone, 1, &list, order);
+}
+
+static void __free_pages_ok(struct page *page, unsigned int order)
+{
+	unsigned long flags;
 	int i;
 	int reserved = 0;
 
 	arch_free_page(page, order);
 
 #ifndef CONFIG_MMU
-	if (order > 0)
-		for (i = 1 ; i < (1 << order) ; ++i)
-			__put_page(page + i);
+	for (i = 1 ; i < (1 << order) ; ++i)
+		__put_page(page + i);
 #endif
 
 	for (i = 0 ; i < (1 << order) ; ++i)
-		reserved += free_pages_check(__FUNCTION__, page + i);
+		reserved += free_pages_check(page + i);
 	if (reserved)
 		return;
 
-	list_add(&page->lru, &list);
-	mod_page_state(pgfree, 1 << order);
-	kernel_map_pages(page, 1<<order, 0);
-	free_pages_bulk(page_zone(page), 1, &list, order);
+	kernel_map_pages(page, 1 << order, 0);
+	local_irq_save(flags);
+	__mod_page_state(pgfree, 1 << order);
+	free_one_page(page_zone(page), page, order);
+	local_irq_restore(flags);
+}
+
+/*
+ * permit the bootmem allocator to evade page validation on high-order frees
+ */
+void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order)
+{
+	if (order == 0) {
+		__ClearPageReserved(page);
+		set_page_count(page, 0);
+
+		free_hot_cold_page(page, 0);
+	} else {
+		LIST_HEAD(list);
+		int loop;
+
+		for (loop = 0; loop < BITS_PER_LONG; loop++) {
+			struct page *p = &page[loop];
+
+			if (loop + 16 < BITS_PER_LONG)
+				prefetchw(p + 16);
+			__ClearPageReserved(p);
+			set_page_count(p, 0);
+		}
+
+		arch_free_page(page, order);
+
+		mod_page_state(pgfree, 1 << order);
+
+		list_add(&page->lru, &list);
+		kernel_map_pages(page, 1 << order, 0);
+		free_pages_bulk(page_zone(page), 1, &list, order);
+	}
 }
 
 
@@ -433,8 +481,7 @@
  *
  * -- wli
  */
-static inline struct page *
-expand(struct zone *zone, struct page *page,
+static inline void expand(struct zone *zone, struct page *page,
  	int low, int high, struct free_area *area)
 {
 	unsigned long size = 1 << high;
@@ -448,24 +495,6 @@
 		area->nr_free++;
 		set_page_order(&page[size], high);
 	}
-	return page;
-}
-
-void set_page_refs(struct page *page, int order)
-{
-#ifdef CONFIG_MMU
-	set_page_count(page, 1);
-#else
-	int i;
-
-	/*
-	 * We need to reference all the pages for this order, otherwise if
-	 * anyone accesses one of the pages with (get/put) it will be freed.
-	 * - eg: access_process_vm()
-	 */
-	for (i = 0; i < (1 << order); i++)
-		set_page_count(page + i, 1);
-#endif /* CONFIG_MMU */
 }
 
 /*
@@ -473,9 +502,9 @@
  */
 static int prep_new_page(struct page *page, int order)
 {
-	if (	page_mapcount(page) ||
-		page->mapping != NULL ||
-		page_count(page) != 0 ||
+	if (unlikely(page_mapcount(page) |
+		(page->mapping != NULL)  |
+		(page_count(page) != 0)  |
 		(page->flags & (
 			1 << PG_lru	|
 			1 << PG_private	|
@@ -486,8 +515,8 @@
 			1 << PG_slab    |
 			1 << PG_swapcache |
 			1 << PG_writeback |
-			1 << PG_reserved )))
-		bad_page(__FUNCTION__, page);
+			1 << PG_reserved ))))
+		bad_page(page);
 
 	/*
 	 * For now, we report if PG_reserved was found set, but do not
@@ -525,7 +554,8 @@
 		rmv_page_order(page);
 		area->nr_free--;
 		zone->free_pages -= 1UL << order;
-		return expand(zone, page, order, current_order, area);
+		expand(zone, page, order, current_order, area);
+		return page;
 	}
 
 	return NULL;
@@ -539,21 +569,17 @@
 static int rmqueue_bulk(struct zone *zone, unsigned int order, 
 			unsigned long count, struct list_head *list)
 {
-	unsigned long flags;
 	int i;
-	int allocated = 0;
-	struct page *page;
 	
-	spin_lock_irqsave(&zone->lock, flags);
+	spin_lock(&zone->lock);
 	for (i = 0; i < count; ++i) {
-		page = __rmqueue(zone, order);
-		if (page == NULL)
+		struct page *page = __rmqueue(zone, order);
+		if (unlikely(page == NULL))
 			break;
-		allocated++;
 		list_add_tail(&page->lru, list);
 	}
-	spin_unlock_irqrestore(&zone->lock, flags);
-	return allocated;
+	spin_unlock(&zone->lock);
+	return i;
 }
 
 #ifdef CONFIG_NUMA
@@ -572,14 +598,13 @@
 		if (zone->zone_pgdat->node_id == numa_node_id())
 			continue;
 
-		pset = zone->pageset[smp_processor_id()];
+		pset = zone_pcp(zone, smp_processor_id());
 		for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
 			struct per_cpu_pages *pcp;
 
 			pcp = &pset->pcp[i];
-			if (pcp->count)
-				pcp->count -= free_pages_bulk(zone, pcp->count,
-						&pcp->list, 0);
+			free_pages_bulk(zone, pcp->count, &pcp->list, 0);
+			pcp->count = 0;
 		}
 	}
 	local_irq_restore(flags);
@@ -589,6 +614,7 @@
 #if defined(CONFIG_PM) || defined(CONFIG_HOTPLUG_CPU)
 static void __drain_pages(unsigned int cpu)
 {
+	unsigned long flags;
 	struct zone *zone;
 	int i;
 
@@ -600,8 +626,10 @@
 			struct per_cpu_pages *pcp;
 
 			pcp = &pset->pcp[i];
-			pcp->count -= free_pages_bulk(zone, pcp->count,
-						&pcp->list, 0);
+			local_irq_save(flags);
+			free_pages_bulk(zone, pcp->count, &pcp->list, 0);
+			pcp->count = 0;
+			local_irq_restore(flags);
 		}
 	}
 }
@@ -647,18 +675,14 @@
 }
 #endif /* CONFIG_PM */
 
-static void zone_statistics(struct zonelist *zonelist, struct zone *z)
+static void zone_statistics(struct zonelist *zonelist, struct zone *z, int cpu)
 {
 #ifdef CONFIG_NUMA
-	unsigned long flags;
-	int cpu;
 	pg_data_t *pg = z->zone_pgdat;
 	pg_data_t *orig = zonelist->zones[0]->zone_pgdat;
 	struct per_cpu_pageset *p;
 
-	local_irq_save(flags);
-	cpu = smp_processor_id();
-	p = zone_pcp(z,cpu);
+	p = zone_pcp(z, cpu);
 	if (pg == orig) {
 		p->numa_hit++;
 	} else {
@@ -669,14 +693,12 @@
 		p->local_node++;
 	else
 		p->other_node++;
-	local_irq_restore(flags);
 #endif
 }
 
 /*
  * Free a 0-order page
  */
-static void FASTCALL(free_hot_cold_page(struct page *page, int cold));
 static void fastcall free_hot_cold_page(struct page *page, int cold)
 {
 	struct zone *zone = page_zone(page);
@@ -687,18 +709,20 @@
 
 	if (PageAnon(page))
 		page->mapping = NULL;
-	if (free_pages_check(__FUNCTION__, page))
+	if (free_pages_check(page))
 		return;
 
-	inc_page_state(pgfree);
 	kernel_map_pages(page, 1, 0);
 
 	pcp = &zone_pcp(zone, get_cpu())->pcp[cold];
 	local_irq_save(flags);
+	__inc_page_state(pgfree);
 	list_add(&page->lru, &pcp->list);
 	pcp->count++;
-	if (pcp->count >= pcp->high)
-		pcp->count -= free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
+	if (pcp->count >= pcp->high) {
+		free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
+		pcp->count -= pcp->batch;
+	}
 	local_irq_restore(flags);
 	put_cpu();
 }
@@ -727,55 +751,67 @@
  * we cheat by calling it from here, in the order > 0 path.  Saves a branch
  * or two.
  */
-static struct page *
-buffered_rmqueue(struct zone *zone, int order, gfp_t gfp_flags)
+static struct page *buffered_rmqueue(struct zonelist *zonelist,
+			struct zone *zone, int order, gfp_t gfp_flags)
 {
 	unsigned long flags;
 	struct page *page;
 	int cold = !!(gfp_flags & __GFP_COLD);
+	int cpu;
 
 again:
-	if (order == 0) {
+	cpu  = get_cpu();
+	if (likely(order == 0)) {
 		struct per_cpu_pages *pcp;
 
-		page = NULL;
-		pcp = &zone_pcp(zone, get_cpu())->pcp[cold];
+		pcp = &zone_pcp(zone, cpu)->pcp[cold];
 		local_irq_save(flags);
-		if (pcp->count <= pcp->low)
+		if (!pcp->count) {
 			pcp->count += rmqueue_bulk(zone, 0,
 						pcp->batch, &pcp->list);
-		if (pcp->count) {
-			page = list_entry(pcp->list.next, struct page, lru);
-			list_del(&page->lru);
-			pcp->count--;
+			if (unlikely(!pcp->count))
+				goto failed;
 		}
-		local_irq_restore(flags);
-		put_cpu();
+		page = list_entry(pcp->list.next, struct page, lru);
+		list_del(&page->lru);
+		pcp->count--;
 	} else {
 		spin_lock_irqsave(&zone->lock, flags);
 		page = __rmqueue(zone, order);
-		spin_unlock_irqrestore(&zone->lock, flags);
+		spin_unlock(&zone->lock);
+		if (!page)
+			goto failed;
 	}
 
-	if (page != NULL) {
-		BUG_ON(bad_range(zone, page));
-		mod_page_state_zone(zone, pgalloc, 1 << order);
-		if (prep_new_page(page, order))
-			goto again;
+	__mod_page_state_zone(zone, pgalloc, 1 << order);
+	zone_statistics(zonelist, zone, cpu);
+	local_irq_restore(flags);
+	put_cpu();
 
-		if (gfp_flags & __GFP_ZERO)
-			prep_zero_page(page, order, gfp_flags);
+	BUG_ON(bad_range(zone, page));
+	if (prep_new_page(page, order))
+		goto again;
 
-		if (order && (gfp_flags & __GFP_COMP))
-			prep_compound_page(page, order);
-	}
+	if (gfp_flags & __GFP_ZERO)
+		prep_zero_page(page, order, gfp_flags);
+
+	if (order && (gfp_flags & __GFP_COMP))
+		prep_compound_page(page, order);
 	return page;
+
+failed:
+	local_irq_restore(flags);
+	put_cpu();
+	return NULL;
 }
 
 #define ALLOC_NO_WATERMARKS	0x01 /* don't check watermarks at all */
-#define ALLOC_HARDER		0x02 /* try to alloc harder */
-#define ALLOC_HIGH		0x04 /* __GFP_HIGH set */
-#define ALLOC_CPUSET		0x08 /* check for correct cpuset */
+#define ALLOC_WMARK_MIN		0x02 /* use pages_min watermark */
+#define ALLOC_WMARK_LOW		0x04 /* use pages_low watermark */
+#define ALLOC_WMARK_HIGH	0x08 /* use pages_high watermark */
+#define ALLOC_HARDER		0x10 /* try to alloc harder */
+#define ALLOC_HIGH		0x20 /* __GFP_HIGH set */
+#define ALLOC_CPUSET		0x40 /* check for correct cpuset */
 
 /*
  * Return 1 if free pages are above 'mark'. This takes into account the order
@@ -830,14 +866,20 @@
 			continue;
 
 		if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
-			if (!zone_watermark_ok(*z, order, (*z)->pages_low,
+			unsigned long mark;
+			if (alloc_flags & ALLOC_WMARK_MIN)
+				mark = (*z)->pages_min;
+			else if (alloc_flags & ALLOC_WMARK_LOW)
+				mark = (*z)->pages_low;
+			else
+				mark = (*z)->pages_high;
+			if (!zone_watermark_ok(*z, order, mark,
 				    classzone_idx, alloc_flags))
 				continue;
 		}
 
-		page = buffered_rmqueue(*z, order, gfp_mask);
+		page = buffered_rmqueue(zonelist, *z, order, gfp_mask);
 		if (page) {
-			zone_statistics(zonelist, *z);
 			break;
 		}
 	} while (*(++z) != NULL);
@@ -871,7 +913,7 @@
 	}
 
 	page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
-				zonelist, ALLOC_CPUSET);
+				zonelist, ALLOC_WMARK_LOW|ALLOC_CPUSET);
 	if (page)
 		goto got_pg;
 
@@ -888,13 +930,12 @@
 	 * cannot run direct reclaim, or if the caller has realtime scheduling
 	 * policy.
 	 */
-	alloc_flags = 0;
+	alloc_flags = ALLOC_WMARK_MIN;
 	if ((unlikely(rt_task(p)) && !in_interrupt()) || !wait)
 		alloc_flags |= ALLOC_HARDER;
 	if (gfp_mask & __GFP_HIGH)
 		alloc_flags |= ALLOC_HIGH;
-	if (wait)
-		alloc_flags |= ALLOC_CPUSET;
+	alloc_flags |= ALLOC_CPUSET;
 
 	/*
 	 * Go through the zonelist again. Let __GFP_HIGH and allocations
@@ -916,7 +957,7 @@
 nofail_alloc:
 			/* go through the zonelist yet again, ignoring mins */
 			page = get_page_from_freelist(gfp_mask, order,
-				zonelist, ALLOC_NO_WATERMARKS|ALLOC_CPUSET);
+				zonelist, ALLOC_NO_WATERMARKS);
 			if (page)
 				goto got_pg;
 			if (gfp_mask & __GFP_NOFAIL) {
@@ -935,6 +976,7 @@
 	cond_resched();
 
 	/* We now go into synchronous reclaim */
+	cpuset_memory_pressure_bump();
 	p->flags |= PF_MEMALLOC;
 	reclaim_state.reclaimed_slab = 0;
 	p->reclaim_state = &reclaim_state;
@@ -959,7 +1001,7 @@
 		 * under heavy pressure.
 		 */
 		page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order,
-						zonelist, ALLOC_CPUSET);
+				zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET);
 		if (page)
 			goto got_pg;
 
@@ -1161,7 +1203,7 @@
 DEFINE_PER_CPU(long, nr_pagecache_local) = 0;
 #endif
 
-void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask)
+static void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask)
 {
 	int cpu = 0;
 
@@ -1214,7 +1256,7 @@
 	__get_page_state(ret, sizeof(*ret) / sizeof(unsigned long), &mask);
 }
 
-unsigned long __read_page_state(unsigned long offset)
+unsigned long read_page_state_offset(unsigned long offset)
 {
 	unsigned long ret = 0;
 	int cpu;
@@ -1228,18 +1270,26 @@
 	return ret;
 }
 
-void __mod_page_state(unsigned long offset, unsigned long delta)
+void __mod_page_state_offset(unsigned long offset, unsigned long delta)
+{
+	void *ptr;
+
+	ptr = &__get_cpu_var(page_states);
+	*(unsigned long *)(ptr + offset) += delta;
+}
+EXPORT_SYMBOL(__mod_page_state_offset);
+
+void mod_page_state_offset(unsigned long offset, unsigned long delta)
 {
 	unsigned long flags;
-	void* ptr;
+	void *ptr;
 
 	local_irq_save(flags);
 	ptr = &__get_cpu_var(page_states);
-	*(unsigned long*)(ptr + offset) += delta;
+	*(unsigned long *)(ptr + offset) += delta;
 	local_irq_restore(flags);
 }
-
-EXPORT_SYMBOL(__mod_page_state);
+EXPORT_SYMBOL(mod_page_state_offset);
 
 void __get_zone_counts(unsigned long *active, unsigned long *inactive,
 			unsigned long *free, struct pglist_data *pgdat)
@@ -1325,7 +1375,7 @@
 		show_node(zone);
 		printk("%s per-cpu:", zone->name);
 
-		if (!zone->present_pages) {
+		if (!populated_zone(zone)) {
 			printk(" empty\n");
 			continue;
 		} else
@@ -1337,10 +1387,9 @@
 			pageset = zone_pcp(zone, cpu);
 
 			for (temperature = 0; temperature < 2; temperature++)
-				printk("cpu %d %s: low %d, high %d, batch %d used:%d\n",
+				printk("cpu %d %s: high %d, batch %d used:%d\n",
 					cpu,
 					temperature ? "cold" : "hot",
-					pageset->pcp[temperature].low,
 					pageset->pcp[temperature].high,
 					pageset->pcp[temperature].batch,
 					pageset->pcp[temperature].count);
@@ -1403,7 +1452,7 @@
 
 		show_node(zone);
 		printk("%s: ", zone->name);
-		if (!zone->present_pages) {
+		if (!populated_zone(zone)) {
 			printk("empty\n");
 			continue;
 		}
@@ -1423,36 +1472,29 @@
 
 /*
  * Builds allocation fallback zone lists.
+ *
+ * Add all populated zones of a node to the zonelist.
  */
-static int __init build_zonelists_node(pg_data_t *pgdat, struct zonelist *zonelist, int j, int k)
+static int __init build_zonelists_node(pg_data_t *pgdat,
+			struct zonelist *zonelist, int nr_zones, int zone_type)
 {
-	switch (k) {
-		struct zone *zone;
-	default:
-		BUG();
-	case ZONE_HIGHMEM:
-		zone = pgdat->node_zones + ZONE_HIGHMEM;
-		if (zone->present_pages) {
-#ifndef CONFIG_HIGHMEM
-			BUG();
-#endif
-			zonelist->zones[j++] = zone;
-		}
-	case ZONE_NORMAL:
-		zone = pgdat->node_zones + ZONE_NORMAL;
-		if (zone->present_pages)
-			zonelist->zones[j++] = zone;
-	case ZONE_DMA32:
-		zone = pgdat->node_zones + ZONE_DMA32;
-		if (zone->present_pages)
-			zonelist->zones[j++] = zone;
-	case ZONE_DMA:
-		zone = pgdat->node_zones + ZONE_DMA;
-		if (zone->present_pages)
-			zonelist->zones[j++] = zone;
-	}
+	struct zone *zone;
 
-	return j;
+	BUG_ON(zone_type > ZONE_HIGHMEM);
+
+	do {
+		zone = pgdat->node_zones + zone_type;
+		if (populated_zone(zone)) {
+#ifndef CONFIG_HIGHMEM
+			BUG_ON(zone_type > ZONE_NORMAL);
+#endif
+			zonelist->zones[nr_zones++] = zone;
+			check_highest_zone(zone_type);
+		}
+		zone_type--;
+
+	} while (zone_type >= 0);
+	return nr_zones;
 }
 
 static inline int highest_zone(int zone_bits)
@@ -1699,8 +1741,6 @@
 	for (pfn = start_pfn; pfn < end_pfn; pfn++, page++) {
 		if (!early_pfn_valid(pfn))
 			continue;
-		if (!early_pfn_in_nid(pfn, nid))
-			continue;
 		page = pfn_to_page(pfn);
 		set_page_links(page, zone, nid, pfn);
 		set_page_count(page, 1);
@@ -1762,16 +1802,16 @@
 		batch = 1;
 
 	/*
-	 * We will be trying to allcoate bigger chunks of contiguous
-	 * memory of the order of fls(batch).  This should result in
-	 * better cache coloring.
+	 * Clamp the batch to a 2^n - 1 value. Having a power
+	 * of 2 value was found to be more likely to have
+	 * suboptimal cache aliasing properties in some cases.
 	 *
-	 * A sanity check also to ensure that batch is still in limits.
+	 * For example if 2 tasks are alternately allocating
+	 * batches of pages, one task can end up with a lot
+	 * of pages of one half of the possible page colors
+	 * and the other with pages of the other colors.
 	 */
-	batch = (1 << fls(batch + batch/2));
-
-	if (fls(batch) >= (PAGE_SHIFT + MAX_ORDER - 2))
-		batch = PAGE_SHIFT + ((MAX_ORDER - 1 - PAGE_SHIFT)/2);
+	batch = (1 << (fls(batch + batch/2)-1)) - 1;
 
 	return batch;
 }
@@ -1784,19 +1824,35 @@
 
 	pcp = &p->pcp[0];		/* hot */
 	pcp->count = 0;
-	pcp->low = 0;
 	pcp->high = 6 * batch;
 	pcp->batch = max(1UL, 1 * batch);
 	INIT_LIST_HEAD(&pcp->list);
 
 	pcp = &p->pcp[1];		/* cold*/
 	pcp->count = 0;
-	pcp->low = 0;
 	pcp->high = 2 * batch;
 	pcp->batch = max(1UL, batch/2);
 	INIT_LIST_HEAD(&pcp->list);
 }
 
+/*
+ * setup_pagelist_highmark() sets the high water mark for hot per_cpu_pagelist
+ * to the value high for the pageset p.
+ */
+
+static void setup_pagelist_highmark(struct per_cpu_pageset *p,
+				unsigned long high)
+{
+	struct per_cpu_pages *pcp;
+
+	pcp = &p->pcp[0]; /* hot list */
+	pcp->high = high;
+	pcp->batch = max(1UL, high/4);
+	if ((high/4) > (PAGE_SHIFT * 8))
+		pcp->batch = PAGE_SHIFT * 8;
+}
+
+
 #ifdef CONFIG_NUMA
 /*
  * Boot pageset table. One per cpu which is going to be used for all
@@ -1828,12 +1884,16 @@
 
 	for_each_zone(zone) {
 
-		zone->pageset[cpu] = kmalloc_node(sizeof(struct per_cpu_pageset),
+		zone_pcp(zone, cpu) = kmalloc_node(sizeof(struct per_cpu_pageset),
 					 GFP_KERNEL, cpu_to_node(cpu));
-		if (!zone->pageset[cpu])
+		if (!zone_pcp(zone, cpu))
 			goto bad;
 
-		setup_pageset(zone->pageset[cpu], zone_batchsize(zone));
+		setup_pageset(zone_pcp(zone, cpu), zone_batchsize(zone));
+
+		if (percpu_pagelist_fraction)
+			setup_pagelist_highmark(zone_pcp(zone, cpu),
+			 	(zone->present_pages / percpu_pagelist_fraction));
 	}
 
 	return 0;
@@ -1841,15 +1901,14 @@
 	for_each_zone(dzone) {
 		if (dzone == zone)
 			break;
-		kfree(dzone->pageset[cpu]);
-		dzone->pageset[cpu] = NULL;
+		kfree(zone_pcp(dzone, cpu));
+		zone_pcp(dzone, cpu) = NULL;
 	}
 	return -ENOMEM;
 }
 
 static inline void free_zone_pagesets(int cpu)
 {
-#ifdef CONFIG_NUMA
 	struct zone *zone;
 
 	for_each_zone(zone) {
@@ -1858,7 +1917,6 @@
 		zone_pcp(zone, cpu) = NULL;
 		kfree(pset);
 	}
-#endif
 }
 
 static int __devinit pageset_cpuup_callback(struct notifier_block *nfb,
@@ -1886,7 +1944,7 @@
 static struct notifier_block pageset_notifier =
 	{ &pageset_cpuup_callback, NULL, 0 };
 
-void __init setup_per_cpu_pageset()
+void __init setup_per_cpu_pageset(void)
 {
 	int err;
 
@@ -1929,7 +1987,7 @@
 	for (cpu = 0; cpu < NR_CPUS; cpu++) {
 #ifdef CONFIG_NUMA
 		/* Early boot. Slab allocator not functional yet */
-		zone->pageset[cpu] = &boot_pageset[cpu];
+		zone_pcp(zone, cpu) = &boot_pageset[cpu];
 		setup_pageset(&boot_pageset[cpu],0);
 #else
 		setup_pageset(zone_pcp(zone,cpu), batch);
@@ -2106,7 +2164,7 @@
 	int order;
 
 	for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
-		if (!zone->present_pages)
+		if (!populated_zone(zone))
 			continue;
 
 		spin_lock_irqsave(&zone->lock, flags);
@@ -2139,7 +2197,7 @@
 	for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; zone++) {
 		int i;
 
-		if (!zone->present_pages)
+		if (!populated_zone(zone))
 			continue;
 
 		spin_lock_irqsave(&zone->lock, flags);
@@ -2172,7 +2230,7 @@
 		seq_printf(m,
 			   ")"
 			   "\n  pagesets");
-		for (i = 0; i < ARRAY_SIZE(zone->pageset); i++) {
+		for_each_online_cpu(i) {
 			struct per_cpu_pageset *pageset;
 			int j;
 
@@ -2187,12 +2245,10 @@
 				seq_printf(m,
 					   "\n    cpu: %i pcp: %i"
 					   "\n              count: %i"
-					   "\n              low:   %i"
 					   "\n              high:  %i"
 					   "\n              batch: %i",
 					   i, j,
 					   pageset->pcp[j].count,
-					   pageset->pcp[j].low,
 					   pageset->pcp[j].high,
 					   pageset->pcp[j].batch);
 			}
@@ -2247,32 +2303,40 @@
 	"pgpgout",
 	"pswpin",
 	"pswpout",
-	"pgalloc_high",
 
+	"pgalloc_high",
 	"pgalloc_normal",
+	"pgalloc_dma32",
 	"pgalloc_dma",
+
 	"pgfree",
 	"pgactivate",
 	"pgdeactivate",
 
 	"pgfault",
 	"pgmajfault",
+
 	"pgrefill_high",
 	"pgrefill_normal",
+	"pgrefill_dma32",
 	"pgrefill_dma",
 
 	"pgsteal_high",
 	"pgsteal_normal",
+	"pgsteal_dma32",
 	"pgsteal_dma",
+
 	"pgscan_kswapd_high",
 	"pgscan_kswapd_normal",
-
+	"pgscan_kswapd_dma32",
 	"pgscan_kswapd_dma",
+
 	"pgscan_direct_high",
 	"pgscan_direct_normal",
+	"pgscan_direct_dma32",
 	"pgscan_direct_dma",
-	"pginodesteal",
 
+	"pginodesteal",
 	"slabs_scanned",
 	"kswapd_steal",
 	"kswapd_inodesteal",
@@ -2529,6 +2593,32 @@
 	return 0;
 }
 
+/*
+ * percpu_pagelist_fraction - changes the pcp->high for each zone on each
+ * cpu.  It is the fraction of total pages in each zone that a hot per cpu pagelist
+ * can have before it gets flushed back to buddy allocator.
+ */
+
+int percpu_pagelist_fraction_sysctl_handler(ctl_table *table, int write,
+	struct file *file, void __user *buffer, size_t *length, loff_t *ppos)
+{
+	struct zone *zone;
+	unsigned int cpu;
+	int ret;
+
+	ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
+	if (!write || (ret == -EINVAL))
+		return ret;
+	for_each_zone(zone) {
+		for_each_online_cpu(cpu) {
+			unsigned long  high;
+			high = zone->present_pages / percpu_pagelist_fraction;
+			setup_pagelist_highmark(zone_pcp(zone, cpu), high);
+		}
+	}
+	return 0;
+}
+
 __initdata int hashdist = HASHDIST_DEFAULT;
 
 #ifdef CONFIG_NUMA
diff --git a/mm/pdflush.c b/mm/pdflush.c
index 52822c9..c4b6d0a 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -90,7 +90,7 @@
 
 static int __pdflush(struct pdflush_work *my_work)
 {
-	current->flags |= PF_FLUSHER;
+	current->flags |= PF_FLUSHER | PF_SWAPWRITE;
 	my_work->fn = NULL;
 	my_work->who = current;
 	INIT_LIST_HEAD(&my_work->list);
diff --git a/mm/readahead.c b/mm/readahead.c
index 72e7adb..8d6eeaa 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -158,7 +158,7 @@
 {
 	unsigned page_idx;
 	struct pagevec lru_pvec;
-	int ret = 0;
+	int ret;
 
 	if (mapping->a_ops->readpages) {
 		ret = mapping->a_ops->readpages(filp, mapping, pages, nr_pages);
@@ -171,14 +171,17 @@
 		list_del(&page->lru);
 		if (!add_to_page_cache(page, mapping,
 					page->index, GFP_KERNEL)) {
-			mapping->a_ops->readpage(filp, page);
-			if (!pagevec_add(&lru_pvec, page))
-				__pagevec_lru_add(&lru_pvec);
-		} else {
-			page_cache_release(page);
+			ret = mapping->a_ops->readpage(filp, page);
+			if (ret != AOP_TRUNCATED_PAGE) {
+				if (!pagevec_add(&lru_pvec, page))
+					__pagevec_lru_add(&lru_pvec);
+				continue;
+			} /* else fall through to release */
 		}
+		page_cache_release(page);
 	}
 	pagevec_lru_add(&lru_pvec);
+	ret = 0;
 out:
 	return ret;
 }
diff --git a/mm/rmap.c b/mm/rmap.c
index 2e034a0..66ec430 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -226,8 +226,6 @@
 /*
  * At what user virtual address is page expected in vma? checking that the
  * page matches the vma: currently only used on anon pages, by unuse_vma;
- * and by extraordinary checks on anon pages in VM_UNPAGED vmas, taking
- * care that an mmap of /dev/mem might window free and foreign pages.
  */
 unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
 {
@@ -292,7 +290,7 @@
  * repeatedly from either page_referenced_anon or page_referenced_file.
  */
 static int page_referenced_one(struct page *page,
-	struct vm_area_struct *vma, unsigned int *mapcount, int ignore_token)
+	struct vm_area_struct *vma, unsigned int *mapcount)
 {
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long address;
@@ -313,7 +311,7 @@
 
 	/* Pretend the page is referenced if the task has the
 	   swap token and is in the middle of a page fault. */
-	if (mm != current->mm && !ignore_token && has_swap_token(mm) &&
+	if (mm != current->mm && has_swap_token(mm) &&
 			rwsem_is_locked(&mm->mmap_sem))
 		referenced++;
 
@@ -323,7 +321,7 @@
 	return referenced;
 }
 
-static int page_referenced_anon(struct page *page, int ignore_token)
+static int page_referenced_anon(struct page *page)
 {
 	unsigned int mapcount;
 	struct anon_vma *anon_vma;
@@ -336,8 +334,7 @@
 
 	mapcount = page_mapcount(page);
 	list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
-		referenced += page_referenced_one(page, vma, &mapcount,
-							ignore_token);
+		referenced += page_referenced_one(page, vma, &mapcount);
 		if (!mapcount)
 			break;
 	}
@@ -356,7 +353,7 @@
  *
  * This function is only called from page_referenced for object-based pages.
  */
-static int page_referenced_file(struct page *page, int ignore_token)
+static int page_referenced_file(struct page *page)
 {
 	unsigned int mapcount;
 	struct address_space *mapping = page->mapping;
@@ -394,8 +391,7 @@
 			referenced++;
 			break;
 		}
-		referenced += page_referenced_one(page, vma, &mapcount,
-							ignore_token);
+		referenced += page_referenced_one(page, vma, &mapcount);
 		if (!mapcount)
 			break;
 	}
@@ -412,13 +408,10 @@
  * Quick test_and_clear_referenced for all mappings to a page,
  * returns the number of ptes which referenced the page.
  */
-int page_referenced(struct page *page, int is_locked, int ignore_token)
+int page_referenced(struct page *page, int is_locked)
 {
 	int referenced = 0;
 
-	if (!swap_token_default_timeout)
-		ignore_token = 1;
-
 	if (page_test_and_clear_young(page))
 		referenced++;
 
@@ -427,15 +420,14 @@
 
 	if (page_mapped(page) && page->mapping) {
 		if (PageAnon(page))
-			referenced += page_referenced_anon(page, ignore_token);
+			referenced += page_referenced_anon(page);
 		else if (is_locked)
-			referenced += page_referenced_file(page, ignore_token);
+			referenced += page_referenced_file(page);
 		else if (TestSetPageLocked(page))
 			referenced++;
 		else {
 			if (page->mapping)
-				referenced += page_referenced_file(page,
-								ignore_token);
+				referenced += page_referenced_file(page);
 			unlock_page(page);
 		}
 	}
@@ -443,6 +435,30 @@
 }
 
 /**
+ * page_set_anon_rmap - setup new anonymous rmap
+ * @page:	the page to add the mapping to
+ * @vma:	the vm area in which the mapping is added
+ * @address:	the user virtual address mapped
+ */
+static void __page_set_anon_rmap(struct page *page,
+	struct vm_area_struct *vma, unsigned long address)
+{
+	struct anon_vma *anon_vma = vma->anon_vma;
+
+	BUG_ON(!anon_vma);
+	anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
+	page->mapping = (struct address_space *) anon_vma;
+
+	page->index = linear_page_index(vma, address);
+
+	/*
+	 * nr_mapped state can be updated without turning off
+	 * interrupts because it is not modified via interrupt.
+	 */
+	__inc_page_state(nr_mapped);
+}
+
+/**
  * page_add_anon_rmap - add pte mapping to an anonymous page
  * @page:	the page to add the mapping to
  * @vma:	the vm area in which the mapping is added
@@ -453,20 +469,27 @@
 void page_add_anon_rmap(struct page *page,
 	struct vm_area_struct *vma, unsigned long address)
 {
-	if (atomic_inc_and_test(&page->_mapcount)) {
-		struct anon_vma *anon_vma = vma->anon_vma;
-
-		BUG_ON(!anon_vma);
-		anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
-		page->mapping = (struct address_space *) anon_vma;
-
-		page->index = linear_page_index(vma, address);
-
-		inc_page_state(nr_mapped);
-	}
+	if (atomic_inc_and_test(&page->_mapcount))
+		__page_set_anon_rmap(page, vma, address);
 	/* else checking page index and mapping is racy */
 }
 
+/*
+ * page_add_new_anon_rmap - add pte mapping to a new anonymous page
+ * @page:	the page to add the mapping to
+ * @vma:	the vm area in which the mapping is added
+ * @address:	the user virtual address mapped
+ *
+ * Same as page_add_anon_rmap but must only be called on *new* pages.
+ * This means the inc-and-test can be bypassed.
+ */
+void page_add_new_anon_rmap(struct page *page,
+	struct vm_area_struct *vma, unsigned long address)
+{
+	atomic_set(&page->_mapcount, 0); /* elevate count by 1 (starts at -1) */
+	__page_set_anon_rmap(page, vma, address);
+}
+
 /**
  * page_add_file_rmap - add pte mapping to a file page
  * @page: the page to add the mapping to
@@ -479,7 +502,7 @@
 	BUG_ON(!pfn_valid(page_to_pfn(page)));
 
 	if (atomic_inc_and_test(&page->_mapcount))
-		inc_page_state(nr_mapped);
+		__inc_page_state(nr_mapped);
 }
 
 /**
@@ -491,6 +514,13 @@
 void page_remove_rmap(struct page *page)
 {
 	if (atomic_add_negative(-1, &page->_mapcount)) {
+		if (page_mapcount(page) < 0) {
+			printk (KERN_EMERG "Eeek! page_mapcount(page) went negative! (%d)\n", page_mapcount(page));
+			printk (KERN_EMERG "  page->flags = %lx\n", page->flags);
+			printk (KERN_EMERG "  page->count = %x\n", page_count(page));
+			printk (KERN_EMERG "  page->mapping = %p\n", page->mapping);
+		}
+
 		BUG_ON(page_mapcount(page) < 0);
 		/*
 		 * It would be tidy to reset the PageAnon mapping here,
@@ -503,7 +533,7 @@
 		 */
 		if (page_test_and_clear_dirty(page))
 			set_page_dirty(page);
-		dec_page_state(nr_mapped);
+		__dec_page_state(nr_mapped);
 	}
 }
 
@@ -614,7 +644,6 @@
 	struct page *page;
 	unsigned long address;
 	unsigned long end;
-	unsigned long pfn;
 
 	address = (vma->vm_start + cursor) & CLUSTER_MASK;
 	end = address + CLUSTER_SIZE;
@@ -643,21 +672,14 @@
 	for (; address < end; pte++, address += PAGE_SIZE) {
 		if (!pte_present(*pte))
 			continue;
-
-		pfn = pte_pfn(*pte);
-		if (unlikely(!pfn_valid(pfn))) {
-			print_bad_pte(vma, *pte, address);
-			continue;
-		}
-
-		page = pfn_to_page(pfn);
-		BUG_ON(PageAnon(page));
+		page = vm_normal_page(vma, address, *pte);
+		BUG_ON(!page || PageAnon(page));
 
 		if (ptep_clear_flush_young(vma, address, pte))
 			continue;
 
 		/* Nuke the page table entry. */
-		flush_cache_page(vma, address, pfn);
+		flush_cache_page(vma, address, pte_pfn(*pte));
 		pteval = ptep_clear_flush(vma, address, pte);
 
 		/* If nonlinear, store the file page offset in the pte. */
diff --git a/mm/shmem.c b/mm/shmem.c
index dc25565..a1f2f02 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -457,7 +457,7 @@
 	} while (next);
 }
 
-static void shmem_truncate(struct inode *inode)
+static void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end)
 {
 	struct shmem_inode_info *info = SHMEM_I(inode);
 	unsigned long idx;
@@ -475,18 +475,27 @@
 	long nr_swaps_freed = 0;
 	int offset;
 	int freed;
+	int punch_hole = 0;
 
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-	idx = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	idx = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	if (idx >= info->next_index)
 		return;
 
 	spin_lock(&info->lock);
 	info->flags |= SHMEM_TRUNCATE;
-	limit = info->next_index;
-	info->next_index = idx;
+	if (likely(end == (loff_t) -1)) {
+		limit = info->next_index;
+		info->next_index = idx;
+	} else {
+		limit = (end + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+		if (limit > info->next_index)
+			limit = info->next_index;
+		punch_hole = 1;
+	}
+
 	topdir = info->i_indirect;
-	if (topdir && idx <= SHMEM_NR_DIRECT) {
+	if (topdir && idx <= SHMEM_NR_DIRECT && !punch_hole) {
 		info->i_indirect = NULL;
 		nr_pages_to_free++;
 		list_add(&topdir->lru, &pages_to_free);
@@ -573,11 +582,12 @@
 			set_page_private(subdir, page_private(subdir) - freed);
 			if (offset)
 				spin_unlock(&info->lock);
-			BUG_ON(page_private(subdir) > offset);
+			if (!punch_hole)
+				BUG_ON(page_private(subdir) > offset);
 		}
 		if (offset)
 			offset = 0;
-		else if (subdir) {
+		else if (subdir && !page_private(subdir)) {
 			dir[diroff] = NULL;
 			nr_pages_to_free++;
 			list_add(&subdir->lru, &pages_to_free);
@@ -594,7 +604,7 @@
 		 * Also, though shmem_getpage checks i_size before adding to
 		 * cache, no recheck after: so fix the narrow window there too.
 		 */
-		truncate_inode_pages(inode->i_mapping, inode->i_size);
+		truncate_inode_pages_range(inode->i_mapping, start, end);
 	}
 
 	spin_lock(&info->lock);
@@ -614,6 +624,11 @@
 	}
 }
 
+static void shmem_truncate(struct inode *inode)
+{
+	shmem_truncate_range(inode, inode->i_size, (loff_t)-1);
+}
+
 static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
 {
 	struct inode *inode = dentry->d_inode;
@@ -855,7 +870,7 @@
 	swap_free(swap);
 redirty:
 	set_page_dirty(page);
-	return WRITEPAGE_ACTIVATE;	/* Return with the page locked */
+	return AOP_WRITEPAGE_ACTIVATE;	/* Return with the page locked */
 }
 
 #ifdef CONFIG_NUMA
@@ -1255,7 +1270,7 @@
 	return retval;
 }
 
-static int shmem_mmap(struct file *file, struct vm_area_struct *vma)
+int shmem_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	file_accessed(file);
 	vma->vm_ops = &shmem_vm_ops;
@@ -2083,6 +2098,7 @@
 static struct inode_operations shmem_inode_operations = {
 	.truncate	= shmem_truncate,
 	.setattr	= shmem_notify_change,
+	.truncate_range	= shmem_truncate_range,
 };
 
 static struct inode_operations shmem_dir_inode_operations = {
diff --git a/mm/slab.c b/mm/slab.c
index e5ec26e..1c46c63 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -130,7 +130,6 @@
 #define	FORCED_DEBUG	0
 #endif
 
-
 /* Shouldn't this be in a header file somewhere? */
 #define	BYTES_PER_WORD		sizeof(void *)
 
@@ -217,12 +216,12 @@
  * Slabs are chained into three list: fully used, partial, fully free slabs.
  */
 struct slab {
-	struct list_head	list;
-	unsigned long		colouroff;
-	void			*s_mem;		/* including colour offset */
-	unsigned int		inuse;		/* num of objs active in slab */
-	kmem_bufctl_t		free;
-	unsigned short          nodeid;
+	struct list_head list;
+	unsigned long colouroff;
+	void *s_mem;		/* including colour offset */
+	unsigned int inuse;	/* num of objs active in slab */
+	kmem_bufctl_t free;
+	unsigned short nodeid;
 };
 
 /*
@@ -242,9 +241,9 @@
  * We assume struct slab_rcu can overlay struct slab when destroying.
  */
 struct slab_rcu {
-	struct rcu_head		head;
-	kmem_cache_t		*cachep;
-	void			*addr;
+	struct rcu_head head;
+	kmem_cache_t *cachep;
+	void *addr;
 };
 
 /*
@@ -279,23 +278,23 @@
 #define BOOT_CPUCACHE_ENTRIES	1
 struct arraycache_init {
 	struct array_cache cache;
-	void * entries[BOOT_CPUCACHE_ENTRIES];
+	void *entries[BOOT_CPUCACHE_ENTRIES];
 };
 
 /*
  * The slab lists for all objects.
  */
 struct kmem_list3 {
-	struct list_head	slabs_partial;	/* partial list first, better asm code */
-	struct list_head	slabs_full;
-	struct list_head	slabs_free;
-	unsigned long	free_objects;
-	unsigned long	next_reap;
-	int		free_touched;
-	unsigned int 	free_limit;
-	spinlock_t      list_lock;
-	struct array_cache	*shared;	/* shared per node */
-	struct array_cache	**alien;	/* on other nodes */
+	struct list_head slabs_partial;	/* partial list first, better asm code */
+	struct list_head slabs_full;
+	struct list_head slabs_free;
+	unsigned long free_objects;
+	unsigned long next_reap;
+	int free_touched;
+	unsigned int free_limit;
+	spinlock_t list_lock;
+	struct array_cache *shared;	/* shared per node */
+	struct array_cache **alien;	/* on other nodes */
 };
 
 /*
@@ -367,63 +366,63 @@
  *
  * manages a cache.
  */
-	
+
 struct kmem_cache {
 /* 1) per-cpu data, touched during every alloc/free */
-	struct array_cache	*array[NR_CPUS];
-	unsigned int		batchcount;
-	unsigned int		limit;
-	unsigned int 		shared;
-	unsigned int		objsize;
+	struct array_cache *array[NR_CPUS];
+	unsigned int batchcount;
+	unsigned int limit;
+	unsigned int shared;
+	unsigned int objsize;
 /* 2) touched by every alloc & free from the backend */
-	struct kmem_list3	*nodelists[MAX_NUMNODES];
-	unsigned int	 	flags;	/* constant flags */
-	unsigned int		num;	/* # of objs per slab */
-	spinlock_t		spinlock;
+	struct kmem_list3 *nodelists[MAX_NUMNODES];
+	unsigned int flags;	/* constant flags */
+	unsigned int num;	/* # of objs per slab */
+	spinlock_t spinlock;
 
 /* 3) cache_grow/shrink */
 	/* order of pgs per slab (2^n) */
-	unsigned int		gfporder;
+	unsigned int gfporder;
 
 	/* force GFP flags, e.g. GFP_DMA */
-	gfp_t			gfpflags;
+	gfp_t gfpflags;
 
-	size_t			colour;		/* cache colouring range */
-	unsigned int		colour_off;	/* colour offset */
-	unsigned int		colour_next;	/* cache colouring */
-	kmem_cache_t		*slabp_cache;
-	unsigned int		slab_size;
-	unsigned int		dflags;		/* dynamic flags */
+	size_t colour;		/* cache colouring range */
+	unsigned int colour_off;	/* colour offset */
+	unsigned int colour_next;	/* cache colouring */
+	kmem_cache_t *slabp_cache;
+	unsigned int slab_size;
+	unsigned int dflags;	/* dynamic flags */
 
 	/* constructor func */
-	void (*ctor)(void *, kmem_cache_t *, unsigned long);
+	void (*ctor) (void *, kmem_cache_t *, unsigned long);
 
 	/* de-constructor func */
-	void (*dtor)(void *, kmem_cache_t *, unsigned long);
+	void (*dtor) (void *, kmem_cache_t *, unsigned long);
 
 /* 4) cache creation/removal */
-	const char		*name;
-	struct list_head	next;
+	const char *name;
+	struct list_head next;
 
 /* 5) statistics */
 #if STATS
-	unsigned long		num_active;
-	unsigned long		num_allocations;
-	unsigned long		high_mark;
-	unsigned long		grown;
-	unsigned long		reaped;
-	unsigned long 		errors;
-	unsigned long		max_freeable;
-	unsigned long		node_allocs;
-	unsigned long		node_frees;
-	atomic_t		allochit;
-	atomic_t		allocmiss;
-	atomic_t		freehit;
-	atomic_t		freemiss;
+	unsigned long num_active;
+	unsigned long num_allocations;
+	unsigned long high_mark;
+	unsigned long grown;
+	unsigned long reaped;
+	unsigned long errors;
+	unsigned long max_freeable;
+	unsigned long node_allocs;
+	unsigned long node_frees;
+	atomic_t allochit;
+	atomic_t allocmiss;
+	atomic_t freehit;
+	atomic_t freemiss;
 #endif
 #if DEBUG
-	int			dbghead;
-	int			reallen;
+	int dbghead;
+	int reallen;
 #endif
 };
 
@@ -523,14 +522,15 @@
 {
 	BUG_ON(!(cachep->flags & SLAB_RED_ZONE));
 	if (cachep->flags & SLAB_STORE_USER)
-		return (unsigned long*) (objp+cachep->objsize-2*BYTES_PER_WORD);
-	return (unsigned long*) (objp+cachep->objsize-BYTES_PER_WORD);
+		return (unsigned long *)(objp + cachep->objsize -
+					 2 * BYTES_PER_WORD);
+	return (unsigned long *)(objp + cachep->objsize - BYTES_PER_WORD);
 }
 
 static void **dbg_userword(kmem_cache_t *cachep, void *objp)
 {
 	BUG_ON(!(cachep->flags & SLAB_STORE_USER));
-	return (void**)(objp+cachep->objsize-BYTES_PER_WORD);
+	return (void **)(objp + cachep->objsize - BYTES_PER_WORD);
 }
 
 #else
@@ -607,31 +607,31 @@
 static struct cache_names __initdata cache_names[] = {
 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
 #include <linux/kmalloc_sizes.h>
-	{ NULL, }
+	{NULL,}
 #undef CACHE
 };
 
 static struct arraycache_init initarray_cache __initdata =
-	{ { 0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
+    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
 static struct arraycache_init initarray_generic =
-	{ { 0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
+    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
 
 /* internal cache of cache description objs */
 static kmem_cache_t cache_cache = {
-	.batchcount	= 1,
-	.limit		= BOOT_CPUCACHE_ENTRIES,
-	.shared		= 1,
-	.objsize	= sizeof(kmem_cache_t),
-	.flags		= SLAB_NO_REAP,
-	.spinlock	= SPIN_LOCK_UNLOCKED,
-	.name		= "kmem_cache",
+	.batchcount = 1,
+	.limit = BOOT_CPUCACHE_ENTRIES,
+	.shared = 1,
+	.objsize = sizeof(kmem_cache_t),
+	.flags = SLAB_NO_REAP,
+	.spinlock = SPIN_LOCK_UNLOCKED,
+	.name = "kmem_cache",
 #if DEBUG
-	.reallen	= sizeof(kmem_cache_t),
+	.reallen = sizeof(kmem_cache_t),
 #endif
 };
 
 /* Guard access to the cache-chain. */
-static struct semaphore	cache_chain_sem;
+static struct semaphore cache_chain_sem;
 static struct list_head cache_chain;
 
 /*
@@ -655,9 +655,9 @@
 
 static DEFINE_PER_CPU(struct work_struct, reap_work);
 
-static void free_block(kmem_cache_t* cachep, void** objpp, int len, int node);
-static void enable_cpucache (kmem_cache_t *cachep);
-static void cache_reap (void *unused);
+static void free_block(kmem_cache_t *cachep, void **objpp, int len, int node);
+static void enable_cpucache(kmem_cache_t *cachep);
+static void cache_reap(void *unused);
 static int __node_shrink(kmem_cache_t *cachep, int node);
 
 static inline struct array_cache *ac_data(kmem_cache_t *cachep)
@@ -671,9 +671,9 @@
 
 #if DEBUG
 	/* This happens if someone tries to call
- 	* kmem_cache_create(), or __kmalloc(), before
- 	* the generic caches are initialized.
- 	*/
+	 * kmem_cache_create(), or __kmalloc(), before
+	 * the generic caches are initialized.
+	 */
 	BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL);
 #endif
 	while (size > csizep->cs_size)
@@ -697,10 +697,10 @@
 
 /* Cal the num objs, wastage, and bytes left over for a given slab size. */
 static void cache_estimate(unsigned long gfporder, size_t size, size_t align,
-		 int flags, size_t *left_over, unsigned int *num)
+			   int flags, size_t *left_over, unsigned int *num)
 {
 	int i;
-	size_t wastage = PAGE_SIZE<<gfporder;
+	size_t wastage = PAGE_SIZE << gfporder;
 	size_t extra = 0;
 	size_t base = 0;
 
@@ -709,7 +709,7 @@
 		extra = sizeof(kmem_bufctl_t);
 	}
 	i = 0;
-	while (i*size + ALIGN(base+i*extra, align) <= wastage)
+	while (i * size + ALIGN(base + i * extra, align) <= wastage)
 		i++;
 	if (i > 0)
 		i--;
@@ -718,8 +718,8 @@
 		i = SLAB_LIMIT;
 
 	*num = i;
-	wastage -= i*size;
-	wastage -= ALIGN(base+i*extra, align);
+	wastage -= i * size;
+	wastage -= ALIGN(base + i * extra, align);
 	*left_over = wastage;
 }
 
@@ -728,7 +728,7 @@
 static void __slab_error(const char *function, kmem_cache_t *cachep, char *msg)
 {
 	printk(KERN_ERR "slab error in %s(): cache `%s': %s\n",
-		function, cachep->name, msg);
+	       function, cachep->name, msg);
 	dump_stack();
 }
 
@@ -755,9 +755,9 @@
 }
 
 static struct array_cache *alloc_arraycache(int node, int entries,
-						int batchcount)
+					    int batchcount)
 {
-	int memsize = sizeof(void*)*entries+sizeof(struct array_cache);
+	int memsize = sizeof(void *) * entries + sizeof(struct array_cache);
 	struct array_cache *nc = NULL;
 
 	nc = kmalloc_node(memsize, GFP_KERNEL, node);
@@ -775,7 +775,7 @@
 static inline struct array_cache **alloc_alien_cache(int node, int limit)
 {
 	struct array_cache **ac_ptr;
-	int memsize = sizeof(void*)*MAX_NUMNODES;
+	int memsize = sizeof(void *) * MAX_NUMNODES;
 	int i;
 
 	if (limit > 1)
@@ -789,7 +789,7 @@
 			}
 			ac_ptr[i] = alloc_arraycache(node, limit, 0xbaadf00d);
 			if (!ac_ptr[i]) {
-				for (i--; i <=0; i--)
+				for (i--; i <= 0; i--)
 					kfree(ac_ptr[i]);
 				kfree(ac_ptr);
 				return NULL;
@@ -807,12 +807,13 @@
 		return;
 
 	for_each_node(i)
-		kfree(ac_ptr[i]);
+	    kfree(ac_ptr[i]);
 
 	kfree(ac_ptr);
 }
 
-static inline void __drain_alien_cache(kmem_cache_t *cachep, struct array_cache *ac, int node)
+static inline void __drain_alien_cache(kmem_cache_t *cachep,
+				       struct array_cache *ac, int node)
 {
 	struct kmem_list3 *rl3 = cachep->nodelists[node];
 
@@ -826,7 +827,7 @@
 
 static void drain_alien_cache(kmem_cache_t *cachep, struct kmem_list3 *l3)
 {
-	int i=0;
+	int i = 0;
 	struct array_cache *ac;
 	unsigned long flags;
 
@@ -846,14 +847,13 @@
 #endif
 
 static int __devinit cpuup_callback(struct notifier_block *nfb,
-				  unsigned long action, void *hcpu)
+				    unsigned long action, void *hcpu)
 {
 	long cpu = (long)hcpu;
-	kmem_cache_t* cachep;
+	kmem_cache_t *cachep;
 	struct kmem_list3 *l3 = NULL;
 	int node = cpu_to_node(cpu);
 	int memsize = sizeof(struct kmem_list3);
-	struct array_cache *nc = NULL;
 
 	switch (action) {
 	case CPU_UP_PREPARE:
@@ -871,27 +871,29 @@
 			 */
 			if (!cachep->nodelists[node]) {
 				if (!(l3 = kmalloc_node(memsize,
-						GFP_KERNEL, node)))
+							GFP_KERNEL, node)))
 					goto bad;
 				kmem_list3_init(l3);
 				l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
-				  ((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+				    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 
 				cachep->nodelists[node] = l3;
 			}
 
 			spin_lock_irq(&cachep->nodelists[node]->list_lock);
 			cachep->nodelists[node]->free_limit =
-				(1 + nr_cpus_node(node)) *
-				cachep->batchcount + cachep->num;
+			    (1 + nr_cpus_node(node)) *
+			    cachep->batchcount + cachep->num;
 			spin_unlock_irq(&cachep->nodelists[node]->list_lock);
 		}
 
 		/* Now we can go ahead with allocating the shared array's
-		  & array cache's */
+		   & array cache's */
 		list_for_each_entry(cachep, &cache_chain, next) {
+			struct array_cache *nc;
+
 			nc = alloc_arraycache(node, cachep->limit,
-					cachep->batchcount);
+					      cachep->batchcount);
 			if (!nc)
 				goto bad;
 			cachep->array[cpu] = nc;
@@ -900,12 +902,13 @@
 			BUG_ON(!l3);
 			if (!l3->shared) {
 				if (!(nc = alloc_arraycache(node,
-					cachep->shared*cachep->batchcount,
-					0xbaadf00d)))
-					goto  bad;
+							    cachep->shared *
+							    cachep->batchcount,
+							    0xbaadf00d)))
+					goto bad;
 
 				/* we are serialised from CPU_DEAD or
-				  CPU_UP_CANCELLED by the cpucontrol lock */
+				   CPU_UP_CANCELLED by the cpucontrol lock */
 				l3->shared = nc;
 			}
 		}
@@ -942,13 +945,13 @@
 				free_block(cachep, nc->entry, nc->avail, node);
 
 			if (!cpus_empty(mask)) {
-                                spin_unlock(&l3->list_lock);
-                                goto unlock_cache;
-                        }
+				spin_unlock(&l3->list_lock);
+				goto unlock_cache;
+			}
 
 			if (l3->shared) {
 				free_block(cachep, l3->shared->entry,
-						l3->shared->avail, node);
+					   l3->shared->avail, node);
 				kfree(l3->shared);
 				l3->shared = NULL;
 			}
@@ -966,7 +969,7 @@
 			} else {
 				spin_unlock(&l3->list_lock);
 			}
-unlock_cache:
+		      unlock_cache:
 			spin_unlock_irq(&cachep->spinlock);
 			kfree(nc);
 		}
@@ -975,7 +978,7 @@
 #endif
 	}
 	return NOTIFY_OK;
-bad:
+      bad:
 	up(&cache_chain_sem);
 	return NOTIFY_BAD;
 }
@@ -985,8 +988,7 @@
 /*
  * swap the static kmem_list3 with kmalloced memory
  */
-static void init_list(kmem_cache_t *cachep, struct kmem_list3 *list,
-		int nodeid)
+static void init_list(kmem_cache_t *cachep, struct kmem_list3 *list, int nodeid)
 {
 	struct kmem_list3 *ptr;
 
@@ -1055,14 +1057,14 @@
 	cache_cache.objsize = ALIGN(cache_cache.objsize, cache_line_size());
 
 	cache_estimate(0, cache_cache.objsize, cache_line_size(), 0,
-				&left_over, &cache_cache.num);
+		       &left_over, &cache_cache.num);
 	if (!cache_cache.num)
 		BUG();
 
-	cache_cache.colour = left_over/cache_cache.colour_off;
+	cache_cache.colour = left_over / cache_cache.colour_off;
 	cache_cache.colour_next = 0;
-	cache_cache.slab_size = ALIGN(cache_cache.num*sizeof(kmem_bufctl_t) +
-				sizeof(struct slab), cache_line_size());
+	cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) +
+				      sizeof(struct slab), cache_line_size());
 
 	/* 2+3) create the kmalloc caches */
 	sizes = malloc_sizes;
@@ -1074,14 +1076,18 @@
 	 */
 
 	sizes[INDEX_AC].cs_cachep = kmem_cache_create(names[INDEX_AC].name,
-				sizes[INDEX_AC].cs_size, ARCH_KMALLOC_MINALIGN,
-				(ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
+						      sizes[INDEX_AC].cs_size,
+						      ARCH_KMALLOC_MINALIGN,
+						      (ARCH_KMALLOC_FLAGS |
+						       SLAB_PANIC), NULL, NULL);
 
 	if (INDEX_AC != INDEX_L3)
 		sizes[INDEX_L3].cs_cachep =
-			kmem_cache_create(names[INDEX_L3].name,
-				sizes[INDEX_L3].cs_size, ARCH_KMALLOC_MINALIGN,
-				(ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
+		    kmem_cache_create(names[INDEX_L3].name,
+				      sizes[INDEX_L3].cs_size,
+				      ARCH_KMALLOC_MINALIGN,
+				      (ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL,
+				      NULL);
 
 	while (sizes->cs_size != ULONG_MAX) {
 		/*
@@ -1091,35 +1097,41 @@
 		 * Note for systems short on memory removing the alignment will
 		 * allow tighter packing of the smaller caches.
 		 */
-		if(!sizes->cs_cachep)
+		if (!sizes->cs_cachep)
 			sizes->cs_cachep = kmem_cache_create(names->name,
-				sizes->cs_size, ARCH_KMALLOC_MINALIGN,
-				(ARCH_KMALLOC_FLAGS | SLAB_PANIC), NULL, NULL);
+							     sizes->cs_size,
+							     ARCH_KMALLOC_MINALIGN,
+							     (ARCH_KMALLOC_FLAGS
+							      | SLAB_PANIC),
+							     NULL, NULL);
 
 		/* Inc off-slab bufctl limit until the ceiling is hit. */
 		if (!(OFF_SLAB(sizes->cs_cachep))) {
-			offslab_limit = sizes->cs_size-sizeof(struct slab);
+			offslab_limit = sizes->cs_size - sizeof(struct slab);
 			offslab_limit /= sizeof(kmem_bufctl_t);
 		}
 
 		sizes->cs_dmacachep = kmem_cache_create(names->name_dma,
-			sizes->cs_size, ARCH_KMALLOC_MINALIGN,
-			(ARCH_KMALLOC_FLAGS | SLAB_CACHE_DMA | SLAB_PANIC),
-			NULL, NULL);
+							sizes->cs_size,
+							ARCH_KMALLOC_MINALIGN,
+							(ARCH_KMALLOC_FLAGS |
+							 SLAB_CACHE_DMA |
+							 SLAB_PANIC), NULL,
+							NULL);
 
 		sizes++;
 		names++;
 	}
 	/* 4) Replace the bootstrap head arrays */
 	{
-		void * ptr;
+		void *ptr;
 
 		ptr = kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
 
 		local_irq_disable();
 		BUG_ON(ac_data(&cache_cache) != &initarray_cache.cache);
 		memcpy(ptr, ac_data(&cache_cache),
-				sizeof(struct arraycache_init));
+		       sizeof(struct arraycache_init));
 		cache_cache.array[smp_processor_id()] = ptr;
 		local_irq_enable();
 
@@ -1127,11 +1139,11 @@
 
 		local_irq_disable();
 		BUG_ON(ac_data(malloc_sizes[INDEX_AC].cs_cachep)
-				!= &initarray_generic.cache);
+		       != &initarray_generic.cache);
 		memcpy(ptr, ac_data(malloc_sizes[INDEX_AC].cs_cachep),
-				sizeof(struct arraycache_init));
+		       sizeof(struct arraycache_init));
 		malloc_sizes[INDEX_AC].cs_cachep->array[smp_processor_id()] =
-						ptr;
+		    ptr;
 		local_irq_enable();
 	}
 	/* 5) Replace the bootstrap kmem_list3's */
@@ -1139,16 +1151,16 @@
 		int node;
 		/* Replace the static kmem_list3 structures for the boot cpu */
 		init_list(&cache_cache, &initkmem_list3[CACHE_CACHE],
-				numa_node_id());
+			  numa_node_id());
 
 		for_each_online_node(node) {
 			init_list(malloc_sizes[INDEX_AC].cs_cachep,
-					&initkmem_list3[SIZE_AC+node], node);
+				  &initkmem_list3[SIZE_AC + node], node);
 
 			if (INDEX_AC != INDEX_L3) {
 				init_list(malloc_sizes[INDEX_L3].cs_cachep,
-						&initkmem_list3[SIZE_L3+node],
-						node);
+					  &initkmem_list3[SIZE_L3 + node],
+					  node);
 			}
 		}
 	}
@@ -1158,7 +1170,7 @@
 		kmem_cache_t *cachep;
 		down(&cache_chain_sem);
 		list_for_each_entry(cachep, &cache_chain, next)
-			enable_cpucache(cachep);
+		    enable_cpucache(cachep);
 		up(&cache_chain_sem);
 	}
 
@@ -1184,7 +1196,7 @@
 	 * pages to gfp.
 	 */
 	for_each_online_cpu(cpu)
-		start_cpu_timer(cpu);
+	    start_cpu_timer(cpu);
 
 	return 0;
 }
@@ -1226,7 +1238,7 @@
  */
 static void kmem_freepages(kmem_cache_t *cachep, void *addr)
 {
-	unsigned long i = (1<<cachep->gfporder);
+	unsigned long i = (1 << cachep->gfporder);
 	struct page *page = virt_to_page(addr);
 	const unsigned long nr_freed = i;
 
@@ -1239,13 +1251,13 @@
 	if (current->reclaim_state)
 		current->reclaim_state->reclaimed_slab += nr_freed;
 	free_pages((unsigned long)addr, cachep->gfporder);
-	if (cachep->flags & SLAB_RECLAIM_ACCOUNT) 
-		atomic_sub(1<<cachep->gfporder, &slab_reclaim_pages);
+	if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
+		atomic_sub(1 << cachep->gfporder, &slab_reclaim_pages);
 }
 
 static void kmem_rcu_free(struct rcu_head *head)
 {
-	struct slab_rcu *slab_rcu = (struct slab_rcu *) head;
+	struct slab_rcu *slab_rcu = (struct slab_rcu *)head;
 	kmem_cache_t *cachep = slab_rcu->cachep;
 
 	kmem_freepages(cachep, slab_rcu->addr);
@@ -1257,19 +1269,19 @@
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
 static void store_stackinfo(kmem_cache_t *cachep, unsigned long *addr,
-				unsigned long caller)
+			    unsigned long caller)
 {
 	int size = obj_reallen(cachep);
 
-	addr = (unsigned long *)&((char*)addr)[obj_dbghead(cachep)];
+	addr = (unsigned long *)&((char *)addr)[obj_dbghead(cachep)];
 
-	if (size < 5*sizeof(unsigned long))
+	if (size < 5 * sizeof(unsigned long))
 		return;
 
-	*addr++=0x12345678;
-	*addr++=caller;
-	*addr++=smp_processor_id();
-	size -= 3*sizeof(unsigned long);
+	*addr++ = 0x12345678;
+	*addr++ = caller;
+	*addr++ = smp_processor_id();
+	size -= 3 * sizeof(unsigned long);
 	{
 		unsigned long *sptr = &caller;
 		unsigned long svalue;
@@ -1277,7 +1289,7 @@
 		while (!kstack_end(sptr)) {
 			svalue = *sptr++;
 			if (kernel_text_address(svalue)) {
-				*addr++=svalue;
+				*addr++ = svalue;
 				size -= sizeof(unsigned long);
 				if (size <= sizeof(unsigned long))
 					break;
@@ -1285,25 +1297,25 @@
 		}
 
 	}
-	*addr++=0x87654321;
+	*addr++ = 0x87654321;
 }
 #endif
 
 static void poison_obj(kmem_cache_t *cachep, void *addr, unsigned char val)
 {
 	int size = obj_reallen(cachep);
-	addr = &((char*)addr)[obj_dbghead(cachep)];
+	addr = &((char *)addr)[obj_dbghead(cachep)];
 
 	memset(addr, val, size);
-	*(unsigned char *)(addr+size-1) = POISON_END;
+	*(unsigned char *)(addr + size - 1) = POISON_END;
 }
 
 static void dump_line(char *data, int offset, int limit)
 {
 	int i;
 	printk(KERN_ERR "%03x:", offset);
-	for (i=0;i<limit;i++) {
-		printk(" %02x", (unsigned char)data[offset+i]);
+	for (i = 0; i < limit; i++) {
+		printk(" %02x", (unsigned char)data[offset + i]);
 	}
 	printk("\n");
 }
@@ -1318,24 +1330,24 @@
 
 	if (cachep->flags & SLAB_RED_ZONE) {
 		printk(KERN_ERR "Redzone: 0x%lx/0x%lx.\n",
-			*dbg_redzone1(cachep, objp),
-			*dbg_redzone2(cachep, objp));
+		       *dbg_redzone1(cachep, objp),
+		       *dbg_redzone2(cachep, objp));
 	}
 
 	if (cachep->flags & SLAB_STORE_USER) {
 		printk(KERN_ERR "Last user: [<%p>]",
-				*dbg_userword(cachep, objp));
+		       *dbg_userword(cachep, objp));
 		print_symbol("(%s)",
-				(unsigned long)*dbg_userword(cachep, objp));
+			     (unsigned long)*dbg_userword(cachep, objp));
 		printk("\n");
 	}
-	realobj = (char*)objp+obj_dbghead(cachep);
+	realobj = (char *)objp + obj_dbghead(cachep);
 	size = obj_reallen(cachep);
-	for (i=0; i<size && lines;i+=16, lines--) {
+	for (i = 0; i < size && lines; i += 16, lines--) {
 		int limit;
 		limit = 16;
-		if (i+limit > size)
-			limit = size-i;
+		if (i + limit > size)
+			limit = size - i;
 		dump_line(realobj, i, limit);
 	}
 }
@@ -1346,27 +1358,28 @@
 	int size, i;
 	int lines = 0;
 
-	realobj = (char*)objp+obj_dbghead(cachep);
+	realobj = (char *)objp + obj_dbghead(cachep);
 	size = obj_reallen(cachep);
 
-	for (i=0;i<size;i++) {
+	for (i = 0; i < size; i++) {
 		char exp = POISON_FREE;
-		if (i == size-1)
+		if (i == size - 1)
 			exp = POISON_END;
 		if (realobj[i] != exp) {
 			int limit;
 			/* Mismatch ! */
 			/* Print header */
 			if (lines == 0) {
-				printk(KERN_ERR "Slab corruption: start=%p, len=%d\n",
-						realobj, size);
+				printk(KERN_ERR
+				       "Slab corruption: start=%p, len=%d\n",
+				       realobj, size);
 				print_objinfo(cachep, objp, 0);
 			}
 			/* Hexdump the affected line */
-			i = (i/16)*16;
+			i = (i / 16) * 16;
 			limit = 16;
-			if (i+limit > size)
-				limit = size-i;
+			if (i + limit > size)
+				limit = size - i;
 			dump_line(realobj, i, limit);
 			i += 16;
 			lines++;
@@ -1382,19 +1395,19 @@
 		struct slab *slabp = page_get_slab(virt_to_page(objp));
 		int objnr;
 
-		objnr = (objp-slabp->s_mem)/cachep->objsize;
+		objnr = (objp - slabp->s_mem) / cachep->objsize;
 		if (objnr) {
-			objp = slabp->s_mem+(objnr-1)*cachep->objsize;
-			realobj = (char*)objp+obj_dbghead(cachep);
+			objp = slabp->s_mem + (objnr - 1) * cachep->objsize;
+			realobj = (char *)objp + obj_dbghead(cachep);
 			printk(KERN_ERR "Prev obj: start=%p, len=%d\n",
-						realobj, size);
+			       realobj, size);
 			print_objinfo(cachep, objp, 2);
 		}
-		if (objnr+1 < cachep->num) {
-			objp = slabp->s_mem+(objnr+1)*cachep->objsize;
-			realobj = (char*)objp+obj_dbghead(cachep);
+		if (objnr + 1 < cachep->num) {
+			objp = slabp->s_mem + (objnr + 1) * cachep->objsize;
+			realobj = (char *)objp + obj_dbghead(cachep);
 			printk(KERN_ERR "Next obj: start=%p, len=%d\n",
-						realobj, size);
+			       realobj, size);
 			print_objinfo(cachep, objp, 2);
 		}
 	}
@@ -1405,7 +1418,7 @@
  * Before calling the slab must have been unlinked from the cache.
  * The cache-lock is not held/needed.
  */
-static void slab_destroy (kmem_cache_t *cachep, struct slab *slabp)
+static void slab_destroy(kmem_cache_t *cachep, struct slab *slabp)
 {
 	void *addr = slabp->s_mem - slabp->colouroff;
 
@@ -1416,8 +1429,11 @@
 
 		if (cachep->flags & SLAB_POISON) {
 #ifdef CONFIG_DEBUG_PAGEALLOC
-			if ((cachep->objsize%PAGE_SIZE)==0 && OFF_SLAB(cachep))
-				kernel_map_pages(virt_to_page(objp), cachep->objsize/PAGE_SIZE,1);
+			if ((cachep->objsize % PAGE_SIZE) == 0
+			    && OFF_SLAB(cachep))
+				kernel_map_pages(virt_to_page(objp),
+						 cachep->objsize / PAGE_SIZE,
+						 1);
 			else
 				check_poison_obj(cachep, objp);
 #else
@@ -1427,20 +1443,20 @@
 		if (cachep->flags & SLAB_RED_ZONE) {
 			if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
 				slab_error(cachep, "start of a freed object "
-							"was overwritten");
+					   "was overwritten");
 			if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
 				slab_error(cachep, "end of a freed object "
-							"was overwritten");
+					   "was overwritten");
 		}
 		if (cachep->dtor && !(cachep->flags & SLAB_POISON))
-			(cachep->dtor)(objp+obj_dbghead(cachep), cachep, 0);
+			(cachep->dtor) (objp + obj_dbghead(cachep), cachep, 0);
 	}
 #else
 	if (cachep->dtor) {
 		int i;
 		for (i = 0; i < cachep->num; i++) {
-			void* objp = slabp->s_mem+cachep->objsize*i;
-			(cachep->dtor)(objp, cachep, 0);
+			void *objp = slabp->s_mem + cachep->objsize * i;
+			(cachep->dtor) (objp, cachep, 0);
 		}
 	}
 #endif
@@ -1448,7 +1464,7 @@
 	if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) {
 		struct slab_rcu *slab_rcu;
 
-		slab_rcu = (struct slab_rcu *) slabp;
+		slab_rcu = (struct slab_rcu *)slabp;
 		slab_rcu->cachep = cachep;
 		slab_rcu->addr = addr;
 		call_rcu(&slab_rcu->head, kmem_rcu_free);
@@ -1466,14 +1482,61 @@
 	int node;
 
 	for_each_online_node(node) {
-		cachep->nodelists[node] = &initkmem_list3[index+node];
+		cachep->nodelists[node] = &initkmem_list3[index + node];
 		cachep->nodelists[node]->next_reap = jiffies +
-			REAPTIMEOUT_LIST3 +
-			((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+		    REAPTIMEOUT_LIST3 +
+		    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 	}
 }
 
 /**
+ * calculate_slab_order - calculate size (page order) of slabs and the number
+ *                        of objects per slab.
+ *
+ * This could be made much more intelligent.  For now, try to avoid using
+ * high order pages for slabs.  When the gfp() functions are more friendly
+ * towards high-order requests, this should be changed.
+ */
+static inline size_t calculate_slab_order(kmem_cache_t *cachep, size_t size,
+					  size_t align, gfp_t flags)
+{
+	size_t left_over = 0;
+
+	for (;; cachep->gfporder++) {
+		unsigned int num;
+		size_t remainder;
+
+		if (cachep->gfporder > MAX_GFP_ORDER) {
+			cachep->num = 0;
+			break;
+		}
+
+		cache_estimate(cachep->gfporder, size, align, flags,
+			       &remainder, &num);
+		if (!num)
+			continue;
+		/* More than offslab_limit objects will cause problems */
+		if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit)
+			break;
+
+		cachep->num = num;
+		left_over = remainder;
+
+		/*
+		 * Large number of objects is good, but very large slabs are
+		 * currently bad for the gfp()s.
+		 */
+		if (cachep->gfporder >= slab_break_gfp_order)
+			break;
+
+		if ((left_over * 8) <= (PAGE_SIZE << cachep->gfporder))
+			/* Acceptable internal fragmentation */
+			break;
+	}
+	return left_over;
+}
+
+/**
  * kmem_cache_create - Create a cache.
  * @name: A string which is used in /proc/slabinfo to identify this cache.
  * @size: The size of objects to be created in this cache.
@@ -1519,14 +1582,13 @@
 	 * Sanity checks... these are all serious usage bugs.
 	 */
 	if ((!name) ||
-		in_interrupt() ||
-		(size < BYTES_PER_WORD) ||
-		(size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) ||
-		(dtor && !ctor)) {
-			printk(KERN_ERR "%s: Early error in slab %s\n",
-					__FUNCTION__, name);
-			BUG();
-		}
+	    in_interrupt() ||
+	    (size < BYTES_PER_WORD) ||
+	    (size > (1 << MAX_OBJ_ORDER) * PAGE_SIZE) || (dtor && !ctor)) {
+		printk(KERN_ERR "%s: Early error in slab %s\n",
+		       __FUNCTION__, name);
+		BUG();
+	}
 
 	down(&cache_chain_sem);
 
@@ -1546,11 +1608,11 @@
 		set_fs(old_fs);
 		if (res) {
 			printk("SLAB: cache with size %d has lost its name\n",
-					pc->objsize);
+			       pc->objsize);
 			continue;
 		}
 
-		if (!strcmp(pc->name,name)) {
+		if (!strcmp(pc->name, name)) {
 			printk("kmem_cache_create: duplicate cache %s\n", name);
 			dump_stack();
 			goto oops;
@@ -1562,10 +1624,9 @@
 	if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
 		/* No constructor, but inital state check requested */
 		printk(KERN_ERR "%s: No con, but init state check "
-				"requested - %s\n", __FUNCTION__, name);
+		       "requested - %s\n", __FUNCTION__, name);
 		flags &= ~SLAB_DEBUG_INITIAL;
 	}
-
 #if FORCED_DEBUG
 	/*
 	 * Enable redzoning and last user accounting, except for caches with
@@ -1573,8 +1634,9 @@
 	 * above the next power of two: caches with object sizes just above a
 	 * power of two have a significant amount of internal fragmentation.
 	 */
-	if ((size < 4096 || fls(size-1) == fls(size-1+3*BYTES_PER_WORD)))
-		flags |= SLAB_RED_ZONE|SLAB_STORE_USER;
+	if ((size < 4096
+	     || fls(size - 1) == fls(size - 1 + 3 * BYTES_PER_WORD)))
+		flags |= SLAB_RED_ZONE | SLAB_STORE_USER;
 	if (!(flags & SLAB_DESTROY_BY_RCU))
 		flags |= SLAB_POISON;
 #endif
@@ -1595,9 +1657,9 @@
 	 * unaligned accesses for some archs when redzoning is used, and makes
 	 * sure any on-slab bufctl's are also correctly aligned.
 	 */
-	if (size & (BYTES_PER_WORD-1)) {
-		size += (BYTES_PER_WORD-1);
-		size &= ~(BYTES_PER_WORD-1);
+	if (size & (BYTES_PER_WORD - 1)) {
+		size += (BYTES_PER_WORD - 1);
+		size &= ~(BYTES_PER_WORD - 1);
 	}
 
 	/* calculate out the final buffer alignment: */
@@ -1608,7 +1670,7 @@
 		 * objects into one cacheline.
 		 */
 		ralign = cache_line_size();
-		while (size <= ralign/2)
+		while (size <= ralign / 2)
 			ralign /= 2;
 	} else {
 		ralign = BYTES_PER_WORD;
@@ -1617,13 +1679,13 @@
 	if (ralign < ARCH_SLAB_MINALIGN) {
 		ralign = ARCH_SLAB_MINALIGN;
 		if (ralign > BYTES_PER_WORD)
-			flags &= ~(SLAB_RED_ZONE|SLAB_STORE_USER);
+			flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
 	}
 	/* 3) caller mandated alignment: disables debug if necessary */
 	if (ralign < align) {
 		ralign = align;
 		if (ralign > BYTES_PER_WORD)
-			flags &= ~(SLAB_RED_ZONE|SLAB_STORE_USER);
+			flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
 	}
 	/* 4) Store it. Note that the debug code below can reduce
 	 *    the alignment to BYTES_PER_WORD.
@@ -1645,7 +1707,7 @@
 
 		/* add space for red zone words */
 		cachep->dbghead += BYTES_PER_WORD;
-		size += 2*BYTES_PER_WORD;
+		size += 2 * BYTES_PER_WORD;
 	}
 	if (flags & SLAB_STORE_USER) {
 		/* user store requires word alignment and
@@ -1656,7 +1718,8 @@
 		size += BYTES_PER_WORD;
 	}
 #if FORCED_DEBUG && defined(CONFIG_DEBUG_PAGEALLOC)
-	if (size >= malloc_sizes[INDEX_L3+1].cs_size && cachep->reallen > cache_line_size() && size < PAGE_SIZE) {
+	if (size >= malloc_sizes[INDEX_L3 + 1].cs_size
+	    && cachep->reallen > cache_line_size() && size < PAGE_SIZE) {
 		cachep->dbghead += PAGE_SIZE - size;
 		size = PAGE_SIZE;
 	}
@@ -1664,7 +1727,7 @@
 #endif
 
 	/* Determine if the slab management is 'on' or 'off' slab. */
-	if (size >= (PAGE_SIZE>>3))
+	if (size >= (PAGE_SIZE >> 3))
 		/*
 		 * Size is large, assume best to place the slab management obj
 		 * off-slab (should allow better packing of objs).
@@ -1681,47 +1744,9 @@
 		 */
 		cachep->gfporder = 0;
 		cache_estimate(cachep->gfporder, size, align, flags,
-					&left_over, &cachep->num);
-	} else {
-		/*
-		 * Calculate size (in pages) of slabs, and the num of objs per
-		 * slab.  This could be made much more intelligent.  For now,
-		 * try to avoid using high page-orders for slabs.  When the
-		 * gfp() funcs are more friendly towards high-order requests,
-		 * this should be changed.
-		 */
-		do {
-			unsigned int break_flag = 0;
-cal_wastage:
-			cache_estimate(cachep->gfporder, size, align, flags,
-						&left_over, &cachep->num);
-			if (break_flag)
-				break;
-			if (cachep->gfporder >= MAX_GFP_ORDER)
-				break;
-			if (!cachep->num)
-				goto next;
-			if (flags & CFLGS_OFF_SLAB &&
-					cachep->num > offslab_limit) {
-				/* This num of objs will cause problems. */
-				cachep->gfporder--;
-				break_flag++;
-				goto cal_wastage;
-			}
-
-			/*
-			 * Large num of objs is good, but v. large slabs are
-			 * currently bad for the gfp()s.
-			 */
-			if (cachep->gfporder >= slab_break_gfp_order)
-				break;
-
-			if ((left_over*8) <= (PAGE_SIZE<<cachep->gfporder))
-				break;	/* Acceptable internal fragmentation. */
-next:
-			cachep->gfporder++;
-		} while (1);
-	}
+			       &left_over, &cachep->num);
+	} else
+		left_over = calculate_slab_order(cachep, size, align, flags);
 
 	if (!cachep->num) {
 		printk("kmem_cache_create: couldn't create cache %s.\n", name);
@@ -1729,8 +1754,8 @@
 		cachep = NULL;
 		goto oops;
 	}
-	slab_size = ALIGN(cachep->num*sizeof(kmem_bufctl_t)
-				+ sizeof(struct slab), align);
+	slab_size = ALIGN(cachep->num * sizeof(kmem_bufctl_t)
+			  + sizeof(struct slab), align);
 
 	/*
 	 * If the slab has been placed off-slab, and we have enough space then
@@ -1743,14 +1768,15 @@
 
 	if (flags & CFLGS_OFF_SLAB) {
 		/* really off slab. No need for manual alignment */
-		slab_size = cachep->num*sizeof(kmem_bufctl_t)+sizeof(struct slab);
+		slab_size =
+		    cachep->num * sizeof(kmem_bufctl_t) + sizeof(struct slab);
 	}
 
 	cachep->colour_off = cache_line_size();
 	/* Offset must be a multiple of the alignment. */
 	if (cachep->colour_off < align)
 		cachep->colour_off = align;
-	cachep->colour = left_over/cachep->colour_off;
+	cachep->colour = left_over / cachep->colour_off;
 	cachep->slab_size = slab_size;
 	cachep->flags = flags;
 	cachep->gfpflags = 0;
@@ -1777,7 +1803,7 @@
 			 * the creation of further caches will BUG().
 			 */
 			cachep->array[smp_processor_id()] =
-				&initarray_generic.cache;
+			    &initarray_generic.cache;
 
 			/* If the cache that's used by
 			 * kmalloc(sizeof(kmem_list3)) is the first cache,
@@ -1791,8 +1817,7 @@
 				g_cpucache_up = PARTIAL_AC;
 		} else {
 			cachep->array[smp_processor_id()] =
-				kmalloc(sizeof(struct arraycache_init),
-						GFP_KERNEL);
+			    kmalloc(sizeof(struct arraycache_init), GFP_KERNEL);
 
 			if (g_cpucache_up == PARTIAL_AC) {
 				set_up_list3s(cachep, SIZE_L3);
@@ -1802,16 +1827,18 @@
 				for_each_online_node(node) {
 
 					cachep->nodelists[node] =
-						kmalloc_node(sizeof(struct kmem_list3),
-								GFP_KERNEL, node);
+					    kmalloc_node(sizeof
+							 (struct kmem_list3),
+							 GFP_KERNEL, node);
 					BUG_ON(!cachep->nodelists[node]);
-					kmem_list3_init(cachep->nodelists[node]);
+					kmem_list3_init(cachep->
+							nodelists[node]);
 				}
 			}
 		}
 		cachep->nodelists[numa_node_id()]->next_reap =
-			jiffies + REAPTIMEOUT_LIST3 +
-			((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+		    jiffies + REAPTIMEOUT_LIST3 +
+		    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 
 		BUG_ON(!ac_data(cachep));
 		ac_data(cachep)->avail = 0;
@@ -1820,15 +1847,15 @@
 		ac_data(cachep)->touched = 0;
 		cachep->batchcount = 1;
 		cachep->limit = BOOT_CPUCACHE_ENTRIES;
-	} 
+	}
 
 	/* cache setup completed, link it into the list */
 	list_add(&cachep->next, &cache_chain);
 	unlock_cpu_hotplug();
-oops:
+      oops:
 	if (!cachep && (flags & SLAB_PANIC))
 		panic("kmem_cache_create(): failed to create slab `%s'\n",
-			name);
+		      name);
 	up(&cache_chain_sem);
 	return cachep;
 }
@@ -1871,7 +1898,7 @@
 /*
  * Waits for all CPUs to execute func().
  */
-static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg)
+static void smp_call_function_all_cpus(void (*func)(void *arg), void *arg)
 {
 	check_irq_on();
 	preempt_disable();
@@ -1886,12 +1913,12 @@
 	preempt_enable();
 }
 
-static void drain_array_locked(kmem_cache_t* cachep,
-				struct array_cache *ac, int force, int node);
+static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac,
+				int force, int node);
 
 static void do_drain(void *arg)
 {
-	kmem_cache_t *cachep = (kmem_cache_t*)arg;
+	kmem_cache_t *cachep = (kmem_cache_t *) arg;
 	struct array_cache *ac;
 	int node = numa_node_id();
 
@@ -1911,7 +1938,7 @@
 	smp_call_function_all_cpus(do_drain, cachep);
 	check_irq_on();
 	spin_lock_irq(&cachep->spinlock);
-	for_each_online_node(node)  {
+	for_each_online_node(node) {
 		l3 = cachep->nodelists[node];
 		if (l3) {
 			spin_lock(&l3->list_lock);
@@ -1949,8 +1976,7 @@
 		slab_destroy(cachep, slabp);
 		spin_lock_irq(&l3->list_lock);
 	}
-	ret = !list_empty(&l3->slabs_full) ||
-		!list_empty(&l3->slabs_partial);
+	ret = !list_empty(&l3->slabs_full) || !list_empty(&l3->slabs_partial);
 	return ret;
 }
 
@@ -2006,7 +2032,7 @@
  * The caller must guarantee that noone will allocate memory from the cache
  * during the kmem_cache_destroy().
  */
-int kmem_cache_destroy(kmem_cache_t * cachep)
+int kmem_cache_destroy(kmem_cache_t *cachep)
 {
 	int i;
 	struct kmem_list3 *l3;
@@ -2028,7 +2054,7 @@
 	if (__cache_shrink(cachep)) {
 		slab_error(cachep, "Can't free all objects");
 		down(&cache_chain_sem);
-		list_add(&cachep->next,&cache_chain);
+		list_add(&cachep->next, &cache_chain);
 		up(&cache_chain_sem);
 		unlock_cpu_hotplug();
 		return 1;
@@ -2038,7 +2064,7 @@
 		synchronize_rcu();
 
 	for_each_online_cpu(i)
-		kfree(cachep->array[i]);
+	    kfree(cachep->array[i]);
 
 	/* NUMA: free the list3 structures */
 	for_each_online_node(i) {
@@ -2057,39 +2083,39 @@
 EXPORT_SYMBOL(kmem_cache_destroy);
 
 /* Get the memory for a slab management obj. */
-static struct slab* alloc_slabmgmt(kmem_cache_t *cachep, void *objp,
-			int colour_off, gfp_t local_flags)
+static struct slab *alloc_slabmgmt(kmem_cache_t *cachep, void *objp,
+				   int colour_off, gfp_t local_flags)
 {
 	struct slab *slabp;
-	
+
 	if (OFF_SLAB(cachep)) {
 		/* Slab management obj is off-slab. */
 		slabp = kmem_cache_alloc(cachep->slabp_cache, local_flags);
 		if (!slabp)
 			return NULL;
 	} else {
-		slabp = objp+colour_off;
+		slabp = objp + colour_off;
 		colour_off += cachep->slab_size;
 	}
 	slabp->inuse = 0;
 	slabp->colouroff = colour_off;
-	slabp->s_mem = objp+colour_off;
+	slabp->s_mem = objp + colour_off;
 
 	return slabp;
 }
 
 static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp)
 {
-	return (kmem_bufctl_t *)(slabp+1);
+	return (kmem_bufctl_t *) (slabp + 1);
 }
 
 static void cache_init_objs(kmem_cache_t *cachep,
-			struct slab *slabp, unsigned long ctor_flags)
+			    struct slab *slabp, unsigned long ctor_flags)
 {
 	int i;
 
 	for (i = 0; i < cachep->num; i++) {
-		void *objp = slabp->s_mem+cachep->objsize*i;
+		void *objp = slabp->s_mem + cachep->objsize * i;
 #if DEBUG
 		/* need to poison the objs? */
 		if (cachep->flags & SLAB_POISON)
@@ -2107,25 +2133,28 @@
 		 * Otherwise, deadlock. They must also be threaded.
 		 */
 		if (cachep->ctor && !(cachep->flags & SLAB_POISON))
-			cachep->ctor(objp+obj_dbghead(cachep), cachep, ctor_flags);
+			cachep->ctor(objp + obj_dbghead(cachep), cachep,
+				     ctor_flags);
 
 		if (cachep->flags & SLAB_RED_ZONE) {
 			if (*dbg_redzone2(cachep, objp) != RED_INACTIVE)
 				slab_error(cachep, "constructor overwrote the"
-							" end of an object");
+					   " end of an object");
 			if (*dbg_redzone1(cachep, objp) != RED_INACTIVE)
 				slab_error(cachep, "constructor overwrote the"
-							" start of an object");
+					   " start of an object");
 		}
-		if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep) && cachep->flags & SLAB_POISON)
-	       		kernel_map_pages(virt_to_page(objp), cachep->objsize/PAGE_SIZE, 0);
+		if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)
+		    && cachep->flags & SLAB_POISON)
+			kernel_map_pages(virt_to_page(objp),
+					 cachep->objsize / PAGE_SIZE, 0);
 #else
 		if (cachep->ctor)
 			cachep->ctor(objp, cachep, ctor_flags);
 #endif
-		slab_bufctl(slabp)[i] = i+1;
+		slab_bufctl(slabp)[i] = i + 1;
 	}
-	slab_bufctl(slabp)[i-1] = BUFCTL_END;
+	slab_bufctl(slabp)[i - 1] = BUFCTL_END;
 	slabp->free = 0;
 }
 
@@ -2161,17 +2190,17 @@
  */
 static int cache_grow(kmem_cache_t *cachep, gfp_t flags, int nodeid)
 {
-	struct slab	*slabp;
-	void		*objp;
-	size_t		 offset;
-	gfp_t	 	 local_flags;
-	unsigned long	 ctor_flags;
+	struct slab *slabp;
+	void *objp;
+	size_t offset;
+	gfp_t local_flags;
+	unsigned long ctor_flags;
 	struct kmem_list3 *l3;
 
 	/* Be lazy and only check for valid flags here,
- 	 * keeping it out of the critical path in kmem_cache_alloc().
+	 * keeping it out of the critical path in kmem_cache_alloc().
 	 */
-	if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW))
+	if (flags & ~(SLAB_DMA | SLAB_LEVEL_MASK | SLAB_NO_GROW))
 		BUG();
 	if (flags & SLAB_NO_GROW)
 		return 0;
@@ -2237,9 +2266,9 @@
 	l3->free_objects += cachep->num;
 	spin_unlock(&l3->list_lock);
 	return 1;
-opps1:
+      opps1:
 	kmem_freepages(cachep, objp);
-failed:
+      failed:
 	if (local_flags & __GFP_WAIT)
 		local_irq_disable();
 	return 0;
@@ -2259,18 +2288,19 @@
 
 	if (!virt_addr_valid(objp)) {
 		printk(KERN_ERR "kfree_debugcheck: out of range ptr %lxh.\n",
-			(unsigned long)objp);	
-		BUG();	
+		       (unsigned long)objp);
+		BUG();
 	}
 	page = virt_to_page(objp);
 	if (!PageSlab(page)) {
-		printk(KERN_ERR "kfree_debugcheck: bad ptr %lxh.\n", (unsigned long)objp);
+		printk(KERN_ERR "kfree_debugcheck: bad ptr %lxh.\n",
+		       (unsigned long)objp);
 		BUG();
 	}
 }
 
 static void *cache_free_debugcheck(kmem_cache_t *cachep, void *objp,
-					void *caller)
+				   void *caller)
 {
 	struct page *page;
 	unsigned int objnr;
@@ -2281,20 +2311,26 @@
 	page = virt_to_page(objp);
 
 	if (page_get_cache(page) != cachep) {
-		printk(KERN_ERR "mismatch in kmem_cache_free: expected cache %p, got %p\n",
-				page_get_cache(page),cachep);
+		printk(KERN_ERR
+		       "mismatch in kmem_cache_free: expected cache %p, got %p\n",
+		       page_get_cache(page), cachep);
 		printk(KERN_ERR "%p is %s.\n", cachep, cachep->name);
-		printk(KERN_ERR "%p is %s.\n", page_get_cache(page), page_get_cache(page)->name);
+		printk(KERN_ERR "%p is %s.\n", page_get_cache(page),
+		       page_get_cache(page)->name);
 		WARN_ON(1);
 	}
 	slabp = page_get_slab(page);
 
 	if (cachep->flags & SLAB_RED_ZONE) {
-		if (*dbg_redzone1(cachep, objp) != RED_ACTIVE || *dbg_redzone2(cachep, objp) != RED_ACTIVE) {
-			slab_error(cachep, "double free, or memory outside"
-						" object was overwritten");
-			printk(KERN_ERR "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
-					objp, *dbg_redzone1(cachep, objp), *dbg_redzone2(cachep, objp));
+		if (*dbg_redzone1(cachep, objp) != RED_ACTIVE
+		    || *dbg_redzone2(cachep, objp) != RED_ACTIVE) {
+			slab_error(cachep,
+				   "double free, or memory outside"
+				   " object was overwritten");
+			printk(KERN_ERR
+			       "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
+			       objp, *dbg_redzone1(cachep, objp),
+			       *dbg_redzone2(cachep, objp));
 		}
 		*dbg_redzone1(cachep, objp) = RED_INACTIVE;
 		*dbg_redzone2(cachep, objp) = RED_INACTIVE;
@@ -2302,30 +2338,31 @@
 	if (cachep->flags & SLAB_STORE_USER)
 		*dbg_userword(cachep, objp) = caller;
 
-	objnr = (objp-slabp->s_mem)/cachep->objsize;
+	objnr = (objp - slabp->s_mem) / cachep->objsize;
 
 	BUG_ON(objnr >= cachep->num);
-	BUG_ON(objp != slabp->s_mem + objnr*cachep->objsize);
+	BUG_ON(objp != slabp->s_mem + objnr * cachep->objsize);
 
 	if (cachep->flags & SLAB_DEBUG_INITIAL) {
 		/* Need to call the slab's constructor so the
 		 * caller can perform a verify of its state (debugging).
 		 * Called without the cache-lock held.
 		 */
-		cachep->ctor(objp+obj_dbghead(cachep),
-					cachep, SLAB_CTOR_CONSTRUCTOR|SLAB_CTOR_VERIFY);
+		cachep->ctor(objp + obj_dbghead(cachep),
+			     cachep, SLAB_CTOR_CONSTRUCTOR | SLAB_CTOR_VERIFY);
 	}
 	if (cachep->flags & SLAB_POISON && cachep->dtor) {
 		/* we want to cache poison the object,
 		 * call the destruction callback
 		 */
-		cachep->dtor(objp+obj_dbghead(cachep), cachep, 0);
+		cachep->dtor(objp + obj_dbghead(cachep), cachep, 0);
 	}
 	if (cachep->flags & SLAB_POISON) {
 #ifdef CONFIG_DEBUG_PAGEALLOC
 		if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep)) {
 			store_stackinfo(cachep, objp, (unsigned long)caller);
-	       		kernel_map_pages(virt_to_page(objp), cachep->objsize/PAGE_SIZE, 0);
+			kernel_map_pages(virt_to_page(objp),
+					 cachep->objsize / PAGE_SIZE, 0);
 		} else {
 			poison_obj(cachep, objp, POISON_FREE);
 		}
@@ -2340,7 +2377,7 @@
 {
 	kmem_bufctl_t i;
 	int entries = 0;
-	
+
 	/* Check slab's freelist to see if this obj is there. */
 	for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
 		entries++;
@@ -2348,13 +2385,16 @@
 			goto bad;
 	}
 	if (entries != cachep->num - slabp->inuse) {
-bad:
-		printk(KERN_ERR "slab: Internal list corruption detected in cache '%s'(%d), slabp %p(%d). Hexdump:\n",
-				cachep->name, cachep->num, slabp, slabp->inuse);
-		for (i=0;i<sizeof(slabp)+cachep->num*sizeof(kmem_bufctl_t);i++) {
-			if ((i%16)==0)
+	      bad:
+		printk(KERN_ERR
+		       "slab: Internal list corruption detected in cache '%s'(%d), slabp %p(%d). Hexdump:\n",
+		       cachep->name, cachep->num, slabp, slabp->inuse);
+		for (i = 0;
+		     i < sizeof(slabp) + cachep->num * sizeof(kmem_bufctl_t);
+		     i++) {
+			if ((i % 16) == 0)
 				printk("\n%03x:", i);
-			printk(" %02x", ((unsigned char*)slabp)[i]);
+			printk(" %02x", ((unsigned char *)slabp)[i]);
 		}
 		printk("\n");
 		BUG();
@@ -2374,7 +2414,7 @@
 
 	check_irq_off();
 	ac = ac_data(cachep);
-retry:
+      retry:
 	batchcount = ac->batchcount;
 	if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {
 		/* if there was little recent activity on this
@@ -2396,8 +2436,8 @@
 			shared_array->avail -= batchcount;
 			ac->avail = batchcount;
 			memcpy(ac->entry,
-				&(shared_array->entry[shared_array->avail]),
-				sizeof(void*)*batchcount);
+			       &(shared_array->entry[shared_array->avail]),
+			       sizeof(void *) * batchcount);
 			shared_array->touched = 1;
 			goto alloc_done;
 		}
@@ -2425,7 +2465,7 @@
 
 			/* get obj pointer */
 			ac->entry[ac->avail++] = slabp->s_mem +
-				slabp->free*cachep->objsize;
+			    slabp->free * cachep->objsize;
 
 			slabp->inuse++;
 			next = slab_bufctl(slabp)[slabp->free];
@@ -2433,7 +2473,7 @@
 			slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
 			WARN_ON(numa_node_id() != slabp->nodeid);
 #endif
-		       	slabp->free = next;
+			slabp->free = next;
 		}
 		check_slabp(cachep, slabp);
 
@@ -2445,9 +2485,9 @@
 			list_add(&slabp->list, &l3->slabs_partial);
 	}
 
-must_grow:
+      must_grow:
 	l3->free_objects -= ac->avail;
-alloc_done:
+      alloc_done:
 	spin_unlock(&l3->list_lock);
 
 	if (unlikely(!ac->avail)) {
@@ -2459,7 +2499,7 @@
 		if (!x && ac->avail == 0)	// no objects in sight? abort
 			return NULL;
 
-		if (!ac->avail)		// objects refilled by interrupt?
+		if (!ac->avail)	// objects refilled by interrupt?
 			goto retry;
 	}
 	ac->touched = 1;
@@ -2476,16 +2516,16 @@
 }
 
 #if DEBUG
-static void *
-cache_alloc_debugcheck_after(kmem_cache_t *cachep,
-			gfp_t flags, void *objp, void *caller)
+static void *cache_alloc_debugcheck_after(kmem_cache_t *cachep, gfp_t flags,
+					void *objp, void *caller)
 {
-	if (!objp)	
+	if (!objp)
 		return objp;
- 	if (cachep->flags & SLAB_POISON) {
+	if (cachep->flags & SLAB_POISON) {
 #ifdef CONFIG_DEBUG_PAGEALLOC
 		if ((cachep->objsize % PAGE_SIZE) == 0 && OFF_SLAB(cachep))
-			kernel_map_pages(virt_to_page(objp), cachep->objsize/PAGE_SIZE, 1);
+			kernel_map_pages(virt_to_page(objp),
+					 cachep->objsize / PAGE_SIZE, 1);
 		else
 			check_poison_obj(cachep, objp);
 #else
@@ -2497,24 +2537,28 @@
 		*dbg_userword(cachep, objp) = caller;
 
 	if (cachep->flags & SLAB_RED_ZONE) {
-		if (*dbg_redzone1(cachep, objp) != RED_INACTIVE || *dbg_redzone2(cachep, objp) != RED_INACTIVE) {
-			slab_error(cachep, "double free, or memory outside"
-						" object was overwritten");
-			printk(KERN_ERR "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
-					objp, *dbg_redzone1(cachep, objp), *dbg_redzone2(cachep, objp));
+		if (*dbg_redzone1(cachep, objp) != RED_INACTIVE
+		    || *dbg_redzone2(cachep, objp) != RED_INACTIVE) {
+			slab_error(cachep,
+				   "double free, or memory outside"
+				   " object was overwritten");
+			printk(KERN_ERR
+			       "%p: redzone 1: 0x%lx, redzone 2: 0x%lx.\n",
+			       objp, *dbg_redzone1(cachep, objp),
+			       *dbg_redzone2(cachep, objp));
 		}
 		*dbg_redzone1(cachep, objp) = RED_ACTIVE;
 		*dbg_redzone2(cachep, objp) = RED_ACTIVE;
 	}
 	objp += obj_dbghead(cachep);
 	if (cachep->ctor && cachep->flags & SLAB_POISON) {
-		unsigned long	ctor_flags = SLAB_CTOR_CONSTRUCTOR;
+		unsigned long ctor_flags = SLAB_CTOR_CONSTRUCTOR;
 
 		if (!(flags & __GFP_WAIT))
 			ctor_flags |= SLAB_CTOR_ATOMIC;
 
 		cachep->ctor(objp, cachep, ctor_flags);
-	}	
+	}
 	return objp;
 }
 #else
@@ -2523,7 +2567,7 @@
 
 static inline void *____cache_alloc(kmem_cache_t *cachep, gfp_t flags)
 {
-	void* objp;
+	void *objp;
 	struct array_cache *ac;
 
 	check_irq_off();
@@ -2542,7 +2586,7 @@
 static inline void *__cache_alloc(kmem_cache_t *cachep, gfp_t flags)
 {
 	unsigned long save_flags;
-	void* objp;
+	void *objp;
 
 	cache_alloc_debugcheck_before(cachep, flags);
 
@@ -2550,7 +2594,7 @@
 	objp = ____cache_alloc(cachep, flags);
 	local_irq_restore(save_flags);
 	objp = cache_alloc_debugcheck_after(cachep, flags, objp,
-					__builtin_return_address(0));
+					    __builtin_return_address(0));
 	prefetchw(objp);
 	return objp;
 }
@@ -2562,74 +2606,75 @@
 static void *__cache_alloc_node(kmem_cache_t *cachep, gfp_t flags, int nodeid)
 {
 	struct list_head *entry;
- 	struct slab *slabp;
- 	struct kmem_list3 *l3;
- 	void *obj;
- 	kmem_bufctl_t next;
- 	int x;
+	struct slab *slabp;
+	struct kmem_list3 *l3;
+	void *obj;
+	kmem_bufctl_t next;
+	int x;
 
- 	l3 = cachep->nodelists[nodeid];
- 	BUG_ON(!l3);
+	l3 = cachep->nodelists[nodeid];
+	BUG_ON(!l3);
 
-retry:
- 	spin_lock(&l3->list_lock);
- 	entry = l3->slabs_partial.next;
- 	if (entry == &l3->slabs_partial) {
- 		l3->free_touched = 1;
- 		entry = l3->slabs_free.next;
- 		if (entry == &l3->slabs_free)
- 			goto must_grow;
- 	}
+      retry:
+	spin_lock(&l3->list_lock);
+	entry = l3->slabs_partial.next;
+	if (entry == &l3->slabs_partial) {
+		l3->free_touched = 1;
+		entry = l3->slabs_free.next;
+		if (entry == &l3->slabs_free)
+			goto must_grow;
+	}
 
- 	slabp = list_entry(entry, struct slab, list);
- 	check_spinlock_acquired_node(cachep, nodeid);
- 	check_slabp(cachep, slabp);
+	slabp = list_entry(entry, struct slab, list);
+	check_spinlock_acquired_node(cachep, nodeid);
+	check_slabp(cachep, slabp);
 
- 	STATS_INC_NODEALLOCS(cachep);
- 	STATS_INC_ACTIVE(cachep);
- 	STATS_SET_HIGH(cachep);
+	STATS_INC_NODEALLOCS(cachep);
+	STATS_INC_ACTIVE(cachep);
+	STATS_SET_HIGH(cachep);
 
- 	BUG_ON(slabp->inuse == cachep->num);
+	BUG_ON(slabp->inuse == cachep->num);
 
- 	/* get obj pointer */
- 	obj =  slabp->s_mem + slabp->free*cachep->objsize;
- 	slabp->inuse++;
- 	next = slab_bufctl(slabp)[slabp->free];
+	/* get obj pointer */
+	obj = slabp->s_mem + slabp->free * cachep->objsize;
+	slabp->inuse++;
+	next = slab_bufctl(slabp)[slabp->free];
 #if DEBUG
- 	slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
+	slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
 #endif
- 	slabp->free = next;
- 	check_slabp(cachep, slabp);
- 	l3->free_objects--;
- 	/* move slabp to correct slabp list: */
- 	list_del(&slabp->list);
+	slabp->free = next;
+	check_slabp(cachep, slabp);
+	l3->free_objects--;
+	/* move slabp to correct slabp list: */
+	list_del(&slabp->list);
 
- 	if (slabp->free == BUFCTL_END) {
- 		list_add(&slabp->list, &l3->slabs_full);
- 	} else {
- 		list_add(&slabp->list, &l3->slabs_partial);
- 	}
+	if (slabp->free == BUFCTL_END) {
+		list_add(&slabp->list, &l3->slabs_full);
+	} else {
+		list_add(&slabp->list, &l3->slabs_partial);
+	}
 
- 	spin_unlock(&l3->list_lock);
- 	goto done;
+	spin_unlock(&l3->list_lock);
+	goto done;
 
-must_grow:
- 	spin_unlock(&l3->list_lock);
- 	x = cache_grow(cachep, flags, nodeid);
+      must_grow:
+	spin_unlock(&l3->list_lock);
+	x = cache_grow(cachep, flags, nodeid);
 
- 	if (!x)
- 		return NULL;
+	if (!x)
+		return NULL;
 
- 	goto retry;
-done:
- 	return obj;
+	goto retry;
+      done:
+	return obj;
 }
 #endif
 
 /*
  * Caller needs to acquire correct kmem_list's list_lock
  */
-static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects, int node)
+static void free_block(kmem_cache_t *cachep, void **objpp, int nr_objects,
+		       int node)
 {
 	int i;
 	struct kmem_list3 *l3;
@@ -2652,7 +2697,7 @@
 
 		if (slab_bufctl(slabp)[objnr] != BUFCTL_FREE) {
 			printk(KERN_ERR "slab: double free detected in cache "
-					"'%s', objp %p\n", cachep->name, objp);
+			       "'%s', objp %p\n", cachep->name, objp);
 			BUG();
 		}
 #endif
@@ -2696,20 +2741,19 @@
 	spin_lock(&l3->list_lock);
 	if (l3->shared) {
 		struct array_cache *shared_array = l3->shared;
-		int max = shared_array->limit-shared_array->avail;
+		int max = shared_array->limit - shared_array->avail;
 		if (max) {
 			if (batchcount > max)
 				batchcount = max;
 			memcpy(&(shared_array->entry[shared_array->avail]),
-					ac->entry,
-					sizeof(void*)*batchcount);
+			       ac->entry, sizeof(void *) * batchcount);
 			shared_array->avail += batchcount;
 			goto free_done;
 		}
 	}
 
 	free_block(cachep, ac->entry, batchcount, node);
-free_done:
+      free_done:
 #if STATS
 	{
 		int i = 0;
@@ -2731,10 +2775,9 @@
 	spin_unlock(&l3->list_lock);
 	ac->avail -= batchcount;
 	memmove(ac->entry, &(ac->entry[batchcount]),
-			sizeof(void*)*ac->avail);
+		sizeof(void *) * ac->avail);
 }
 
-
 /*
  * __cache_free
  * Release an obj back to its cache. If the obj has a constructed
@@ -2759,7 +2802,8 @@
 		if (unlikely(slabp->nodeid != numa_node_id())) {
 			struct array_cache *alien = NULL;
 			int nodeid = slabp->nodeid;
-			struct kmem_list3 *l3 = cachep->nodelists[numa_node_id()];
+			struct kmem_list3 *l3 =
+			    cachep->nodelists[numa_node_id()];
 
 			STATS_INC_NODEFREES(cachep);
 			if (l3->alien && l3->alien[nodeid]) {
@@ -2767,15 +2811,15 @@
 				spin_lock(&alien->lock);
 				if (unlikely(alien->avail == alien->limit))
 					__drain_alien_cache(cachep,
-							alien, nodeid);
+							    alien, nodeid);
 				alien->entry[alien->avail++] = objp;
 				spin_unlock(&alien->lock);
 			} else {
 				spin_lock(&(cachep->nodelists[nodeid])->
-						list_lock);
+					  list_lock);
 				free_block(cachep, &objp, 1, nodeid);
 				spin_unlock(&(cachep->nodelists[nodeid])->
-						list_lock);
+					    list_lock);
 			}
 			return;
 		}
@@ -2822,9 +2866,9 @@
  */
 int fastcall kmem_ptr_validate(kmem_cache_t *cachep, void *ptr)
 {
-	unsigned long addr = (unsigned long) ptr;
+	unsigned long addr = (unsigned long)ptr;
 	unsigned long min_addr = PAGE_OFFSET;
-	unsigned long align_mask = BYTES_PER_WORD-1;
+	unsigned long align_mask = BYTES_PER_WORD - 1;
 	unsigned long size = cachep->objsize;
 	struct page *page;
 
@@ -2844,7 +2888,7 @@
 	if (unlikely(page_get_cache(page) != cachep))
 		goto out;
 	return 1;
-out:
+      out:
 	return 0;
 }
 
@@ -2871,8 +2915,10 @@
 
 	if (unlikely(!cachep->nodelists[nodeid])) {
 		/* Fall back to __cache_alloc if we run into trouble */
-		printk(KERN_WARNING "slab: not allocating in inactive node %d for cache %s\n", nodeid, cachep->name);
-		return __cache_alloc(cachep,flags);
+		printk(KERN_WARNING
+		       "slab: not allocating in inactive node %d for cache %s\n",
+		       nodeid, cachep->name);
+		return __cache_alloc(cachep, flags);
 	}
 
 	cache_alloc_debugcheck_before(cachep, flags);
@@ -2882,7 +2928,9 @@
 	else
 		ptr = __cache_alloc_node(cachep, flags, nodeid);
 	local_irq_restore(save_flags);
-	ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, __builtin_return_address(0));
+	ptr =
+	    cache_alloc_debugcheck_after(cachep, flags, ptr,
+					 __builtin_return_address(0));
 
 	return ptr;
 }
@@ -2944,12 +2992,11 @@
  * Objects should be dereferenced using the per_cpu_ptr macro only.
  *
  * @size: how many bytes of memory are required.
- * @align: the alignment, which can't be greater than SMP_CACHE_BYTES.
  */
-void *__alloc_percpu(size_t size, size_t align)
+void *__alloc_percpu(size_t size)
 {
 	int i;
-	struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL);
+	struct percpu_data *pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
 
 	if (!pdata)
 		return NULL;
@@ -2973,9 +3020,9 @@
 	}
 
 	/* Catch derefs w/o wrappers */
-	return (void *) (~(unsigned long) pdata);
+	return (void *)(~(unsigned long)pdata);
 
-unwind_oom:
+      unwind_oom:
 	while (--i >= 0) {
 		if (!cpu_possible(i))
 			continue;
@@ -3006,20 +3053,6 @@
 EXPORT_SYMBOL(kmem_cache_free);
 
 /**
- * kzalloc - allocate memory. The memory is set to zero.
- * @size: how many bytes of memory are required.
- * @flags: the type of memory to allocate.
- */
-void *kzalloc(size_t size, gfp_t flags)
-{
-	void *ret = kmalloc(size, flags);
-	if (ret)
-		memset(ret, 0, size);
-	return ret;
-}
-EXPORT_SYMBOL(kzalloc);
-
-/**
  * kfree - free previously allocated memory
  * @objp: pointer returned by kmalloc.
  *
@@ -3038,7 +3071,7 @@
 	local_irq_save(flags);
 	kfree_debugcheck(objp);
 	c = page_get_cache(virt_to_page(objp));
-	__cache_free(c, (void*)objp);
+	__cache_free(c, (void *)objp);
 	local_irq_restore(flags);
 }
 EXPORT_SYMBOL(kfree);
@@ -3051,17 +3084,16 @@
  * Don't free memory not originally allocated by alloc_percpu()
  * The complemented objp is to check for that.
  */
-void
-free_percpu(const void *objp)
+void free_percpu(const void *objp)
 {
 	int i;
-	struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp);
+	struct percpu_data *p = (struct percpu_data *)(~(unsigned long)objp);
 
 	/*
 	 * We allocate for all cpus so we cannot use for online cpu here.
 	 */
 	for_each_cpu(i)
-		kfree(p->ptrs[i]);
+	    kfree(p->ptrs[i]);
 	kfree(p);
 }
 EXPORT_SYMBOL(free_percpu);
@@ -3095,44 +3127,44 @@
 		if (!(new_alien = alloc_alien_cache(node, cachep->limit)))
 			goto fail;
 #endif
-		if (!(new = alloc_arraycache(node, (cachep->shared*
-				cachep->batchcount), 0xbaadf00d)))
+		if (!(new = alloc_arraycache(node, (cachep->shared *
+						    cachep->batchcount),
+					     0xbaadf00d)))
 			goto fail;
 		if ((l3 = cachep->nodelists[node])) {
 
 			spin_lock_irq(&l3->list_lock);
 
 			if ((nc = cachep->nodelists[node]->shared))
-				free_block(cachep, nc->entry,
-							nc->avail, node);
+				free_block(cachep, nc->entry, nc->avail, node);
 
 			l3->shared = new;
 			if (!cachep->nodelists[node]->alien) {
 				l3->alien = new_alien;
 				new_alien = NULL;
 			}
-			l3->free_limit = (1 + nr_cpus_node(node))*
-				cachep->batchcount + cachep->num;
+			l3->free_limit = (1 + nr_cpus_node(node)) *
+			    cachep->batchcount + cachep->num;
 			spin_unlock_irq(&l3->list_lock);
 			kfree(nc);
 			free_alien_cache(new_alien);
 			continue;
 		}
 		if (!(l3 = kmalloc_node(sizeof(struct kmem_list3),
-						GFP_KERNEL, node)))
+					GFP_KERNEL, node)))
 			goto fail;
 
 		kmem_list3_init(l3);
 		l3->next_reap = jiffies + REAPTIMEOUT_LIST3 +
-			((unsigned long)cachep)%REAPTIMEOUT_LIST3;
+		    ((unsigned long)cachep) % REAPTIMEOUT_LIST3;
 		l3->shared = new;
 		l3->alien = new_alien;
-		l3->free_limit = (1 + nr_cpus_node(node))*
-			cachep->batchcount + cachep->num;
+		l3->free_limit = (1 + nr_cpus_node(node)) *
+		    cachep->batchcount + cachep->num;
 		cachep->nodelists[node] = l3;
 	}
 	return err;
-fail:
+      fail:
 	err = -ENOMEM;
 	return err;
 }
@@ -3154,18 +3186,19 @@
 	new->new[smp_processor_id()] = old;
 }
 
-
 static int do_tune_cpucache(kmem_cache_t *cachep, int limit, int batchcount,
-				int shared)
+			    int shared)
 {
 	struct ccupdate_struct new;
 	int i, err;
 
-	memset(&new.new,0,sizeof(new.new));
+	memset(&new.new, 0, sizeof(new.new));
 	for_each_online_cpu(i) {
-		new.new[i] = alloc_arraycache(cpu_to_node(i), limit, batchcount);
+		new.new[i] =
+		    alloc_arraycache(cpu_to_node(i), limit, batchcount);
 		if (!new.new[i]) {
-			for (i--; i >= 0; i--) kfree(new.new[i]);
+			for (i--; i >= 0; i--)
+				kfree(new.new[i]);
 			return -ENOMEM;
 		}
 	}
@@ -3193,13 +3226,12 @@
 	err = alloc_kmemlist(cachep);
 	if (err) {
 		printk(KERN_ERR "alloc_kmemlist failed for %s, error %d.\n",
-				cachep->name, -err);
+		       cachep->name, -err);
 		BUG();
 	}
 	return 0;
 }
 
-
 static void enable_cpucache(kmem_cache_t *cachep)
 {
 	int err;
@@ -3246,14 +3278,14 @@
 	if (limit > 32)
 		limit = 32;
 #endif
-	err = do_tune_cpucache(cachep, limit, (limit+1)/2, shared);
+	err = do_tune_cpucache(cachep, limit, (limit + 1) / 2, shared);
 	if (err)
 		printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",
-					cachep->name, -err);
+		       cachep->name, -err);
 }
 
-static void drain_array_locked(kmem_cache_t *cachep,
-				struct array_cache *ac, int force, int node)
+static void drain_array_locked(kmem_cache_t *cachep, struct array_cache *ac,
+				int force, int node)
 {
 	int tofree;
 
@@ -3261,14 +3293,14 @@
 	if (ac->touched && !force) {
 		ac->touched = 0;
 	} else if (ac->avail) {
-		tofree = force ? ac->avail : (ac->limit+4)/5;
+		tofree = force ? ac->avail : (ac->limit + 4) / 5;
 		if (tofree > ac->avail) {
-			tofree = (ac->avail+1)/2;
+			tofree = (ac->avail + 1) / 2;
 		}
 		free_block(cachep, ac->entry, tofree, node);
 		ac->avail -= tofree;
 		memmove(ac->entry, &(ac->entry[tofree]),
-					sizeof(void*)*ac->avail);
+			sizeof(void *) * ac->avail);
 	}
 }
 
@@ -3291,13 +3323,14 @@
 
 	if (down_trylock(&cache_chain_sem)) {
 		/* Give up. Setup the next iteration. */
-		schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC);
+		schedule_delayed_work(&__get_cpu_var(reap_work),
+				      REAPTIMEOUT_CPUC);
 		return;
 	}
 
 	list_for_each(walk, &cache_chain) {
 		kmem_cache_t *searchp;
-		struct list_head* p;
+		struct list_head *p;
 		int tofree;
 		struct slab *slabp;
 
@@ -3314,7 +3347,7 @@
 		spin_lock_irq(&l3->list_lock);
 
 		drain_array_locked(searchp, ac_data(searchp), 0,
-				numa_node_id());
+				   numa_node_id());
 
 		if (time_after(l3->next_reap, jiffies))
 			goto next_unlock;
@@ -3323,14 +3356,16 @@
 
 		if (l3->shared)
 			drain_array_locked(searchp, l3->shared, 0,
-				numa_node_id());
+					   numa_node_id());
 
 		if (l3->free_touched) {
 			l3->free_touched = 0;
 			goto next_unlock;
 		}
 
-		tofree = (l3->free_limit+5*searchp->num-1)/(5*searchp->num);
+		tofree =
+		    (l3->free_limit + 5 * searchp->num -
+		     1) / (5 * searchp->num);
 		do {
 			p = l3->slabs_free.next;
 			if (p == &(l3->slabs_free))
@@ -3350,10 +3385,10 @@
 			spin_unlock_irq(&l3->list_lock);
 			slab_destroy(searchp, slabp);
 			spin_lock_irq(&l3->list_lock);
-		} while(--tofree > 0);
-next_unlock:
+		} while (--tofree > 0);
+	      next_unlock:
 		spin_unlock_irq(&l3->list_lock);
-next:
+	      next:
 		cond_resched();
 	}
 	check_irq_on();
@@ -3365,32 +3400,37 @@
 
 #ifdef CONFIG_PROC_FS
 
+static void print_slabinfo_header(struct seq_file *m)
+{
+	/*
+	 * Output format version, so at least we can change it
+	 * without _too_ many complaints.
+	 */
+#if STATS
+	seq_puts(m, "slabinfo - version: 2.1 (statistics)\n");
+#else
+	seq_puts(m, "slabinfo - version: 2.1\n");
+#endif
+	seq_puts(m, "# name            <active_objs> <num_objs> <objsize> "
+		 "<objperslab> <pagesperslab>");
+	seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>");
+	seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
+#if STATS
+	seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> "
+		 "<error> <maxfreeable> <nodeallocs> <remotefrees>");
+	seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>");
+#endif
+	seq_putc(m, '\n');
+}
+
 static void *s_start(struct seq_file *m, loff_t *pos)
 {
 	loff_t n = *pos;
 	struct list_head *p;
 
 	down(&cache_chain_sem);
-	if (!n) {
-		/*
-		 * Output format version, so at least we can change it
-		 * without _too_ many complaints.
-		 */
-#if STATS
-		seq_puts(m, "slabinfo - version: 2.1 (statistics)\n");
-#else
-		seq_puts(m, "slabinfo - version: 2.1\n");
-#endif
-		seq_puts(m, "# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab>");
-		seq_puts(m, " : tunables <limit> <batchcount> <sharedfactor>");
-		seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
-#if STATS
-		seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped>"
-				" <error> <maxfreeable> <nodeallocs> <remotefrees>");
-		seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>");
-#endif
-		seq_putc(m, '\n');
-	}
+	if (!n)
+		print_slabinfo_header(m);
 	p = cache_chain.next;
 	while (n--) {
 		p = p->next;
@@ -3405,7 +3445,7 @@
 	kmem_cache_t *cachep = p;
 	++*pos;
 	return cachep->next.next == &cache_chain ? NULL
-		: list_entry(cachep->next.next, kmem_cache_t, next);
+	    : list_entry(cachep->next.next, kmem_cache_t, next);
 }
 
 static void s_stop(struct seq_file *m, void *p)
@@ -3417,11 +3457,11 @@
 {
 	kmem_cache_t *cachep = p;
 	struct list_head *q;
-	struct slab	*slabp;
-	unsigned long	active_objs;
-	unsigned long	num_objs;
-	unsigned long	active_slabs = 0;
-	unsigned long	num_slabs, free_objects = 0, shared_avail = 0;
+	struct slab *slabp;
+	unsigned long active_objs;
+	unsigned long num_objs;
+	unsigned long active_slabs = 0;
+	unsigned long num_slabs, free_objects = 0, shared_avail = 0;
 	const char *name;
 	char *error = NULL;
 	int node;
@@ -3438,14 +3478,14 @@
 
 		spin_lock(&l3->list_lock);
 
-		list_for_each(q,&l3->slabs_full) {
+		list_for_each(q, &l3->slabs_full) {
 			slabp = list_entry(q, struct slab, list);
 			if (slabp->inuse != cachep->num && !error)
 				error = "slabs_full accounting error";
 			active_objs += cachep->num;
 			active_slabs++;
 		}
-		list_for_each(q,&l3->slabs_partial) {
+		list_for_each(q, &l3->slabs_partial) {
 			slabp = list_entry(q, struct slab, list);
 			if (slabp->inuse == cachep->num && !error)
 				error = "slabs_partial inuse accounting error";
@@ -3454,7 +3494,7 @@
 			active_objs += slabp->inuse;
 			active_slabs++;
 		}
-		list_for_each(q,&l3->slabs_free) {
+		list_for_each(q, &l3->slabs_free) {
 			slabp = list_entry(q, struct slab, list);
 			if (slabp->inuse && !error)
 				error = "slabs_free/inuse accounting error";
@@ -3465,25 +3505,24 @@
 
 		spin_unlock(&l3->list_lock);
 	}
-	num_slabs+=active_slabs;
-	num_objs = num_slabs*cachep->num;
+	num_slabs += active_slabs;
+	num_objs = num_slabs * cachep->num;
 	if (num_objs - active_objs != free_objects && !error)
 		error = "free_objects accounting error";
 
-	name = cachep->name; 
+	name = cachep->name;
 	if (error)
 		printk(KERN_ERR "slab: cache %s error: %s\n", name, error);
 
 	seq_printf(m, "%-17s %6lu %6lu %6u %4u %4d",
-		name, active_objs, num_objs, cachep->objsize,
-		cachep->num, (1<<cachep->gfporder));
+		   name, active_objs, num_objs, cachep->objsize,
+		   cachep->num, (1 << cachep->gfporder));
 	seq_printf(m, " : tunables %4u %4u %4u",
-			cachep->limit, cachep->batchcount,
-			cachep->shared);
+		   cachep->limit, cachep->batchcount, cachep->shared);
 	seq_printf(m, " : slabdata %6lu %6lu %6lu",
-			active_slabs, num_slabs, shared_avail);
+		   active_slabs, num_slabs, shared_avail);
 #if STATS
-	{	/* list3 stats */
+	{			/* list3 stats */
 		unsigned long high = cachep->high_mark;
 		unsigned long allocs = cachep->num_allocations;
 		unsigned long grown = cachep->grown;
@@ -3494,9 +3533,7 @@
 		unsigned long node_frees = cachep->node_frees;
 
 		seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu \
-				%4lu %4lu %4lu %4lu",
-				allocs, high, grown, reaped, errors,
-				max_freeable, node_allocs, node_frees);
+				%4lu %4lu %4lu %4lu", allocs, high, grown, reaped, errors, max_freeable, node_allocs, node_frees);
 	}
 	/* cpu stats */
 	{
@@ -3506,7 +3543,7 @@
 		unsigned long freemiss = atomic_read(&cachep->freemiss);
 
 		seq_printf(m, " : cpustat %6lu %6lu %6lu %6lu",
-			allochit, allocmiss, freehit, freemiss);
+			   allochit, allocmiss, freehit, freemiss);
 	}
 #endif
 	seq_putc(m, '\n');
@@ -3529,10 +3566,10 @@
  */
 
 struct seq_operations slabinfo_op = {
-	.start	= s_start,
-	.next	= s_next,
-	.stop	= s_stop,
-	.show	= s_show,
+	.start = s_start,
+	.next = s_next,
+	.stop = s_stop,
+	.show = s_show,
 };
 
 #define MAX_SLABINFO_WRITE 128
@@ -3543,18 +3580,18 @@
  * @count: data length
  * @ppos: unused
  */
-ssize_t slabinfo_write(struct file *file, const char __user *buffer,
-				size_t count, loff_t *ppos)
+ssize_t slabinfo_write(struct file *file, const char __user * buffer,
+		       size_t count, loff_t *ppos)
 {
-	char kbuf[MAX_SLABINFO_WRITE+1], *tmp;
+	char kbuf[MAX_SLABINFO_WRITE + 1], *tmp;
 	int limit, batchcount, shared, res;
 	struct list_head *p;
-	
+
 	if (count > MAX_SLABINFO_WRITE)
 		return -EINVAL;
 	if (copy_from_user(&kbuf, buffer, count))
 		return -EFAULT;
-	kbuf[MAX_SLABINFO_WRITE] = '\0'; 
+	kbuf[MAX_SLABINFO_WRITE] = '\0';
 
 	tmp = strchr(kbuf, ' ');
 	if (!tmp)
@@ -3567,18 +3604,17 @@
 	/* Find the cache in the chain of caches. */
 	down(&cache_chain_sem);
 	res = -EINVAL;
-	list_for_each(p,&cache_chain) {
+	list_for_each(p, &cache_chain) {
 		kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next);
 
 		if (!strcmp(cachep->name, kbuf)) {
 			if (limit < 1 ||
 			    batchcount < 1 ||
-			    batchcount > limit ||
-			    shared < 0) {
+			    batchcount > limit || shared < 0) {
 				res = 0;
 			} else {
 				res = do_tune_cpucache(cachep, limit,
-							batchcount, shared);
+						       batchcount, shared);
 			}
 			break;
 		}
@@ -3609,26 +3645,3 @@
 
 	return obj_reallen(page_get_cache(virt_to_page(objp)));
 }
-
-
-/*
- * kstrdup - allocate space for and copy an existing string
- *
- * @s: the string to duplicate
- * @gfp: the GFP mask used in the kmalloc() call when allocating memory
- */
-char *kstrdup(const char *s, gfp_t gfp)
-{
-	size_t len;
-	char *buf;
-
-	if (!s)
-		return NULL;
-
-	len = strlen(s) + 1;
-	buf = kmalloc(len, gfp);
-	if (buf)
-		memcpy(buf, s, len);
-	return buf;
-}
-EXPORT_SYMBOL(kstrdup);
diff --git a/mm/slob.c b/mm/slob.c
new file mode 100644
index 0000000..1c240c4
--- /dev/null
+++ b/mm/slob.c
@@ -0,0 +1,385 @@
+/*
+ * SLOB Allocator: Simple List Of Blocks
+ *
+ * Matt Mackall <mpm@selenic.com> 12/30/03
+ *
+ * How SLOB works:
+ *
+ * The core of SLOB is a traditional K&R style heap allocator, with
+ * support for returning aligned objects. The granularity of this
+ * allocator is 8 bytes on x86, though it's perhaps possible to reduce
+ * this to 4 if it's deemed worth the effort. The slob heap is a
+ * singly-linked list of pages from __get_free_page, grown on demand
+ * and allocation from the heap is currently first-fit.
+ *
+ * Above this is an implementation of kmalloc/kfree. Blocks returned
+ * from kmalloc are 8-byte aligned and prepended with a 8-byte header.
+ * If kmalloc is asked for objects of PAGE_SIZE or larger, it calls
+ * __get_free_pages directly so that it can return page-aligned blocks
+ * and keeps a linked list of such pages and their orders. These
+ * objects are detected in kfree() by their page alignment.
+ *
+ * SLAB is emulated on top of SLOB by simply calling constructors and
+ * destructors for every SLAB allocation. Objects are returned with
+ * the 8-byte alignment unless the SLAB_MUST_HWCACHE_ALIGN flag is
+ * set, in which case the low-level allocator will fragment blocks to
+ * create the proper alignment. Again, objects of page-size or greater
+ * are allocated by calling __get_free_pages. As SLAB objects know
+ * their size, no separate size bookkeeping is necessary and there is
+ * essentially no allocation space overhead.
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/cache.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/timer.h>
+
+struct slob_block {
+	int units;
+	struct slob_block *next;
+};
+typedef struct slob_block slob_t;
+
+#define SLOB_UNIT sizeof(slob_t)
+#define SLOB_UNITS(size) (((size) + SLOB_UNIT - 1)/SLOB_UNIT)
+#define SLOB_ALIGN L1_CACHE_BYTES
+
+struct bigblock {
+	int order;
+	void *pages;
+	struct bigblock *next;
+};
+typedef struct bigblock bigblock_t;
+
+static slob_t arena = { .next = &arena, .units = 1 };
+static slob_t *slobfree = &arena;
+static bigblock_t *bigblocks;
+static DEFINE_SPINLOCK(slob_lock);
+static DEFINE_SPINLOCK(block_lock);
+
+static void slob_free(void *b, int size);
+
+static void *slob_alloc(size_t size, gfp_t gfp, int align)
+{
+	slob_t *prev, *cur, *aligned = 0;
+	int delta = 0, units = SLOB_UNITS(size);
+	unsigned long flags;
+
+	spin_lock_irqsave(&slob_lock, flags);
+	prev = slobfree;
+	for (cur = prev->next; ; prev = cur, cur = cur->next) {
+		if (align) {
+			aligned = (slob_t *)ALIGN((unsigned long)cur, align);
+			delta = aligned - cur;
+		}
+		if (cur->units >= units + delta) { /* room enough? */
+			if (delta) { /* need to fragment head to align? */
+				aligned->units = cur->units - delta;
+				aligned->next = cur->next;
+				cur->next = aligned;
+				cur->units = delta;
+				prev = cur;
+				cur = aligned;
+			}
+
+			if (cur->units == units) /* exact fit? */
+				prev->next = cur->next; /* unlink */
+			else { /* fragment */
+				prev->next = cur + units;
+				prev->next->units = cur->units - units;
+				prev->next->next = cur->next;
+				cur->units = units;
+			}
+
+			slobfree = prev;
+			spin_unlock_irqrestore(&slob_lock, flags);
+			return cur;
+		}
+		if (cur == slobfree) {
+			spin_unlock_irqrestore(&slob_lock, flags);
+
+			if (size == PAGE_SIZE) /* trying to shrink arena? */
+				return 0;
+
+			cur = (slob_t *)__get_free_page(gfp);
+			if (!cur)
+				return 0;
+
+			slob_free(cur, PAGE_SIZE);
+			spin_lock_irqsave(&slob_lock, flags);
+			cur = slobfree;
+		}
+	}
+}
+
+static void slob_free(void *block, int size)
+{
+	slob_t *cur, *b = (slob_t *)block;
+	unsigned long flags;
+
+	if (!block)
+		return;
+
+	if (size)
+		b->units = SLOB_UNITS(size);
+
+	/* Find reinsertion point */
+	spin_lock_irqsave(&slob_lock, flags);
+	for (cur = slobfree; !(b > cur && b < cur->next); cur = cur->next)
+		if (cur >= cur->next && (b > cur || b < cur->next))
+			break;
+
+	if (b + b->units == cur->next) {
+		b->units += cur->next->units;
+		b->next = cur->next->next;
+	} else
+		b->next = cur->next;
+
+	if (cur + cur->units == b) {
+		cur->units += b->units;
+		cur->next = b->next;
+	} else
+		cur->next = b;
+
+	slobfree = cur;
+
+	spin_unlock_irqrestore(&slob_lock, flags);
+}
+
+static int FASTCALL(find_order(int size));
+static int fastcall find_order(int size)
+{
+	int order = 0;
+	for ( ; size > 4096 ; size >>=1)
+		order++;
+	return order;
+}
+
+void *kmalloc(size_t size, gfp_t gfp)
+{
+	slob_t *m;
+	bigblock_t *bb;
+	unsigned long flags;
+
+	if (size < PAGE_SIZE - SLOB_UNIT) {
+		m = slob_alloc(size + SLOB_UNIT, gfp, 0);
+		return m ? (void *)(m + 1) : 0;
+	}
+
+	bb = slob_alloc(sizeof(bigblock_t), gfp, 0);
+	if (!bb)
+		return 0;
+
+	bb->order = find_order(size);
+	bb->pages = (void *)__get_free_pages(gfp, bb->order);
+
+	if (bb->pages) {
+		spin_lock_irqsave(&block_lock, flags);
+		bb->next = bigblocks;
+		bigblocks = bb;
+		spin_unlock_irqrestore(&block_lock, flags);
+		return bb->pages;
+	}
+
+	slob_free(bb, sizeof(bigblock_t));
+	return 0;
+}
+
+EXPORT_SYMBOL(kmalloc);
+
+void kfree(const void *block)
+{
+	bigblock_t *bb, **last = &bigblocks;
+	unsigned long flags;
+
+	if (!block)
+		return;
+
+	if (!((unsigned long)block & (PAGE_SIZE-1))) {
+		/* might be on the big block list */
+		spin_lock_irqsave(&block_lock, flags);
+		for (bb = bigblocks; bb; last = &bb->next, bb = bb->next) {
+			if (bb->pages == block) {
+				*last = bb->next;
+				spin_unlock_irqrestore(&block_lock, flags);
+				free_pages((unsigned long)block, bb->order);
+				slob_free(bb, sizeof(bigblock_t));
+				return;
+			}
+		}
+		spin_unlock_irqrestore(&block_lock, flags);
+	}
+
+	slob_free((slob_t *)block - 1, 0);
+	return;
+}
+
+EXPORT_SYMBOL(kfree);
+
+unsigned int ksize(const void *block)
+{
+	bigblock_t *bb;
+	unsigned long flags;
+
+	if (!block)
+		return 0;
+
+	if (!((unsigned long)block & (PAGE_SIZE-1))) {
+		spin_lock_irqsave(&block_lock, flags);
+		for (bb = bigblocks; bb; bb = bb->next)
+			if (bb->pages == block) {
+				spin_unlock_irqrestore(&slob_lock, flags);
+				return PAGE_SIZE << bb->order;
+			}
+		spin_unlock_irqrestore(&block_lock, flags);
+	}
+
+	return ((slob_t *)block - 1)->units * SLOB_UNIT;
+}
+
+struct kmem_cache {
+	unsigned int size, align;
+	const char *name;
+	void (*ctor)(void *, struct kmem_cache *, unsigned long);
+	void (*dtor)(void *, struct kmem_cache *, unsigned long);
+};
+
+struct kmem_cache *kmem_cache_create(const char *name, size_t size,
+	size_t align, unsigned long flags,
+	void (*ctor)(void*, struct kmem_cache *, unsigned long),
+	void (*dtor)(void*, struct kmem_cache *, unsigned long))
+{
+	struct kmem_cache *c;
+
+	c = slob_alloc(sizeof(struct kmem_cache), flags, 0);
+
+	if (c) {
+		c->name = name;
+		c->size = size;
+		c->ctor = ctor;
+		c->dtor = dtor;
+		/* ignore alignment unless it's forced */
+		c->align = (flags & SLAB_MUST_HWCACHE_ALIGN) ? SLOB_ALIGN : 0;
+		if (c->align < align)
+			c->align = align;
+	}
+
+	return c;
+}
+EXPORT_SYMBOL(kmem_cache_create);
+
+int kmem_cache_destroy(struct kmem_cache *c)
+{
+	slob_free(c, sizeof(struct kmem_cache));
+	return 0;
+}
+EXPORT_SYMBOL(kmem_cache_destroy);
+
+void *kmem_cache_alloc(struct kmem_cache *c, gfp_t flags)
+{
+	void *b;
+
+	if (c->size < PAGE_SIZE)
+		b = slob_alloc(c->size, flags, c->align);
+	else
+		b = (void *)__get_free_pages(flags, find_order(c->size));
+
+	if (c->ctor)
+		c->ctor(b, c, SLAB_CTOR_CONSTRUCTOR);
+
+	return b;
+}
+EXPORT_SYMBOL(kmem_cache_alloc);
+
+void kmem_cache_free(struct kmem_cache *c, void *b)
+{
+	if (c->dtor)
+		c->dtor(b, c, 0);
+
+	if (c->size < PAGE_SIZE)
+		slob_free(b, c->size);
+	else
+		free_pages((unsigned long)b, find_order(c->size));
+}
+EXPORT_SYMBOL(kmem_cache_free);
+
+unsigned int kmem_cache_size(struct kmem_cache *c)
+{
+	return c->size;
+}
+EXPORT_SYMBOL(kmem_cache_size);
+
+const char *kmem_cache_name(struct kmem_cache *c)
+{
+	return c->name;
+}
+EXPORT_SYMBOL(kmem_cache_name);
+
+static struct timer_list slob_timer = TIMER_INITIALIZER(
+	(void (*)(unsigned long))kmem_cache_init, 0, 0);
+
+void kmem_cache_init(void)
+{
+	void *p = slob_alloc(PAGE_SIZE, 0, PAGE_SIZE-1);
+
+	if (p)
+		free_page((unsigned long)p);
+
+	mod_timer(&slob_timer, jiffies + HZ);
+}
+
+atomic_t slab_reclaim_pages = ATOMIC_INIT(0);
+EXPORT_SYMBOL(slab_reclaim_pages);
+
+#ifdef CONFIG_SMP
+
+void *__alloc_percpu(size_t size, size_t align)
+{
+	int i;
+	struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL);
+
+	if (!pdata)
+		return NULL;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (!cpu_possible(i))
+			continue;
+		pdata->ptrs[i] = kmalloc(size, GFP_KERNEL);
+		if (!pdata->ptrs[i])
+			goto unwind_oom;
+		memset(pdata->ptrs[i], 0, size);
+	}
+
+	/* Catch derefs w/o wrappers */
+	return (void *) (~(unsigned long) pdata);
+
+unwind_oom:
+	while (--i >= 0) {
+		if (!cpu_possible(i))
+			continue;
+		kfree(pdata->ptrs[i]);
+	}
+	kfree(pdata);
+	return NULL;
+}
+EXPORT_SYMBOL(__alloc_percpu);
+
+void
+free_percpu(const void *objp)
+{
+	int i;
+	struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp);
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (!cpu_possible(i))
+			continue;
+		kfree(p->ptrs[i]);
+	}
+	kfree(p);
+}
+EXPORT_SYMBOL(free_percpu);
+
+#endif
diff --git a/mm/sparse.c b/mm/sparse.c
index 72079b5..0a51f36 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -18,10 +18,10 @@
  */
 #ifdef CONFIG_SPARSEMEM_EXTREME
 struct mem_section *mem_section[NR_SECTION_ROOTS]
-	____cacheline_maxaligned_in_smp;
+	____cacheline_internodealigned_in_smp;
 #else
 struct mem_section mem_section[NR_SECTION_ROOTS][SECTIONS_PER_ROOT]
-	____cacheline_maxaligned_in_smp;
+	____cacheline_internodealigned_in_smp;
 #endif
 EXPORT_SYMBOL(mem_section);
 
diff --git a/mm/swap.c b/mm/swap.c
index 73d3514..ee6d71c 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -156,16 +156,22 @@
 	put_cpu_var(lru_add_active_pvecs);
 }
 
-void lru_add_drain(void)
+static void __lru_add_drain(int cpu)
 {
-	struct pagevec *pvec = &get_cpu_var(lru_add_pvecs);
+	struct pagevec *pvec = &per_cpu(lru_add_pvecs, cpu);
 
+	/* CPU is dead, so no locking needed. */
 	if (pagevec_count(pvec))
 		__pagevec_lru_add(pvec);
-	pvec = &__get_cpu_var(lru_add_active_pvecs);
+	pvec = &per_cpu(lru_add_active_pvecs, cpu);
 	if (pagevec_count(pvec))
 		__pagevec_lru_add_active(pvec);
-	put_cpu_var(lru_add_pvecs);
+}
+
+void lru_add_drain(void)
+{
+	__lru_add_drain(get_cpu());
+	put_cpu();
 }
 
 /*
@@ -412,17 +418,6 @@
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static void lru_drain_cache(unsigned int cpu)
-{
-	struct pagevec *pvec = &per_cpu(lru_add_pvecs, cpu);
-
-	/* CPU is dead, so no locking needed. */
-	if (pagevec_count(pvec))
-		__pagevec_lru_add(pvec);
-	pvec = &per_cpu(lru_add_active_pvecs, cpu);
-	if (pagevec_count(pvec))
-		__pagevec_lru_add_active(pvec);
-}
 
 /* Drop the CPU's cached committed space back into the central pool. */
 static int cpu_swap_callback(struct notifier_block *nfb,
@@ -435,7 +430,7 @@
 	if (action == CPU_DEAD) {
 		atomic_add(*committed, &vm_committed_space);
 		*committed = 0;
-		lru_drain_cache((long)hcpu);
+		__lru_add_drain((long)hcpu);
 	}
 	return NOTIFY_OK;
 }
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 0df9a57..7b09ac5 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -14,6 +14,7 @@
 #include <linux/pagemap.h>
 #include <linux/buffer_head.h>
 #include <linux/backing-dev.h>
+#include <linux/pagevec.h>
 
 #include <asm/pgtable.h>
 
@@ -140,7 +141,7 @@
  * Allocate swap space for the page and add the page to the
  * swap cache.  Caller needs to hold the page lock. 
  */
-int add_to_swap(struct page * page)
+int add_to_swap(struct page * page, gfp_t gfp_mask)
 {
 	swp_entry_t entry;
 	int err;
@@ -165,7 +166,7 @@
 		 * Add it to the swap cache and mark it dirty
 		 */
 		err = __add_to_swap_cache(page, entry,
-				GFP_ATOMIC|__GFP_NOMEMALLOC|__GFP_NOWARN);
+				gfp_mask|__GFP_NOMEMALLOC|__GFP_NOWARN);
 
 		switch (err) {
 		case 0:				/* Success */
@@ -272,12 +273,11 @@
  */
 void free_pages_and_swap_cache(struct page **pages, int nr)
 {
-	int chunk = 16;
 	struct page **pagep = pages;
 
 	lru_add_drain();
 	while (nr) {
-		int todo = min(chunk, nr);
+		int todo = min(nr, PAGEVEC_SIZE);
 		int i;
 
 		for (i = 0; i < todo; i++)
diff --git a/mm/swapfile.c b/mm/swapfile.c
index edafeac..80f948a 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -211,6 +211,26 @@
 	return (swp_entry_t) {0};
 }
 
+swp_entry_t get_swap_page_of_type(int type)
+{
+	struct swap_info_struct *si;
+	pgoff_t offset;
+
+	spin_lock(&swap_lock);
+	si = swap_info + type;
+	if (si->flags & SWP_WRITEOK) {
+		nr_swap_pages--;
+		offset = scan_swap_map(si);
+		if (offset) {
+			spin_unlock(&swap_lock);
+			return swp_entry(type, offset);
+		}
+		nr_swap_pages++;
+	}
+	spin_unlock(&swap_lock);
+	return (swp_entry_t) {0};
+}
+
 static struct swap_info_struct * swap_info_get(swp_entry_t entry)
 {
 	struct swap_info_struct * p;
@@ -1473,7 +1493,7 @@
 			goto bad_swap;
 		if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
 			goto bad_swap;
-		
+
 		/* OK, set up the swap map and apply the bad block list */
 		if (!(p->swap_map = vmalloc(maxpages * sizeof(short)))) {
 			error = -ENOMEM;
@@ -1482,17 +1502,17 @@
 
 		error = 0;
 		memset(p->swap_map, 0, maxpages * sizeof(short));
-		for (i=0; i<swap_header->info.nr_badpages; i++) {
-			int page = swap_header->info.badpages[i];
-			if (page <= 0 || page >= swap_header->info.last_page)
+		for (i = 0; i < swap_header->info.nr_badpages; i++) {
+			int page_nr = swap_header->info.badpages[i];
+			if (page_nr <= 0 || page_nr >= swap_header->info.last_page)
 				error = -EINVAL;
 			else
-				p->swap_map[page] = SWAP_MAP_BAD;
+				p->swap_map[page_nr] = SWAP_MAP_BAD;
 		}
 		nr_good_pages = swap_header->info.last_page -
 				swap_header->info.nr_badpages -
 				1 /* header page */;
-		if (error) 
+		if (error)
 			goto bad_swap;
 	}
 
diff --git a/mm/thrash.c b/mm/thrash.c
index eff3c18..f4c560b 100644
--- a/mm/thrash.c
+++ b/mm/thrash.c
@@ -57,14 +57,17 @@
 	/* We have the token. Let others know we still need it. */
 	if (has_swap_token(current->mm)) {
 		current->mm->recent_pagein = 1;
+		if (unlikely(!swap_token_default_timeout))
+			disable_swap_token();
 		return;
 	}
 
 	if (time_after(jiffies, swap_token_check)) {
 
-		/* Can't get swapout protection if we exceed our RSS limit. */
-		// if (current->mm->rss > current->mm->rlimit_rss)
-		//	return;
+		if (!swap_token_default_timeout) {
+			swap_token_check = jiffies + SWAP_TOKEN_CHECK_INTERVAL;
+			return;
+		}
 
 		/* ... or if we recently held the token. */
 		if (time_before(jiffies, current->mm->swap_token_time))
@@ -95,6 +98,7 @@
 {
 	spin_lock(&swap_token_lock);
 	if (likely(mm == swap_token_mm)) {
+		mm->swap_token_time = jiffies + SWAP_TOKEN_CHECK_INTERVAL;
 		swap_token_mm = &init_mm;
 		swap_token_check = jiffies;
 	}
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c
index b58abcf..cdc6d43 100644
--- a/mm/tiny-shmem.c
+++ b/mm/tiny-shmem.c
@@ -81,13 +81,19 @@
 		goto close_file;
 
 	d_instantiate(dentry, inode);
-	inode->i_size = size;
 	inode->i_nlink = 0;	/* It is unlinked */
+
 	file->f_vfsmnt = mntget(shm_mnt);
 	file->f_dentry = dentry;
 	file->f_mapping = inode->i_mapping;
 	file->f_op = &ramfs_file_operations;
 	file->f_mode = FMODE_WRITE | FMODE_READ;
+
+	/* notify everyone as to the change of file size */
+	error = do_truncate(dentry, size, file);
+	if (error < 0)
+		goto close_file;
+
 	return file;
 
 close_file:
@@ -123,3 +129,24 @@
 {
 	return 0;
 }
+
+int shmem_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	file_accessed(file);
+#ifndef CONFIG_MMU
+	return ramfs_nommu_mmap(file, vma);
+#else
+	return 0;
+#endif
+}
+
+#ifndef CONFIG_MMU
+unsigned long shmem_get_unmapped_area(struct file *file,
+				      unsigned long addr,
+				      unsigned long len,
+				      unsigned long pgoff,
+				      unsigned long flags)
+{
+	return ramfs_nommu_get_unmapped_area(file, addr, len, pgoff, flags);
+}
+#endif
diff --git a/mm/truncate.c b/mm/truncate.c
index 9173ab50..b1a463d 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -82,12 +82,15 @@
 }
 
 /**
- * truncate_inode_pages - truncate *all* the pages from an offset
+ * truncate_inode_pages - truncate range of pages specified by start and
+ * end byte offsets
  * @mapping: mapping to truncate
  * @lstart: offset from which to truncate
+ * @lend: offset to which to truncate
  *
- * Truncate the page cache at a set offset, removing the pages that are beyond
- * that offset (and zeroing out partial pages).
+ * Truncate the page cache, removing the pages that are between
+ * specified offsets (and zeroing out partial page
+ * (if lstart is not page aligned)).
  *
  * Truncate takes two passes - the first pass is nonblocking.  It will not
  * block on page locks and it will not block on writeback.  The second pass
@@ -101,12 +104,12 @@
  * We pass down the cache-hot hint to the page freeing code.  Even if the
  * mapping is large, it is probably the case that the final pages are the most
  * recently touched, and freeing happens in ascending file offset order.
- *
- * Called under (and serialised by) inode->i_sem.
  */
-void truncate_inode_pages(struct address_space *mapping, loff_t lstart)
+void truncate_inode_pages_range(struct address_space *mapping,
+				loff_t lstart, loff_t lend)
 {
 	const pgoff_t start = (lstart + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
+	pgoff_t end;
 	const unsigned partial = lstart & (PAGE_CACHE_SIZE - 1);
 	struct pagevec pvec;
 	pgoff_t next;
@@ -115,13 +118,22 @@
 	if (mapping->nrpages == 0)
 		return;
 
+	BUG_ON((lend & (PAGE_CACHE_SIZE - 1)) != (PAGE_CACHE_SIZE - 1));
+	end = (lend >> PAGE_CACHE_SHIFT);
+
 	pagevec_init(&pvec, 0);
 	next = start;
-	while (pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
+	while (next <= end &&
+	       pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 			pgoff_t page_index = page->index;
 
+			if (page_index > end) {
+				next = page_index;
+				break;
+			}
+
 			if (page_index > next)
 				next = page_index;
 			next++;
@@ -157,9 +169,15 @@
 			next = start;
 			continue;
 		}
+		if (pvec.pages[0]->index > end) {
+			pagevec_release(&pvec);
+			break;
+		}
 		for (i = 0; i < pagevec_count(&pvec); i++) {
 			struct page *page = pvec.pages[i];
 
+			if (page->index > end)
+				break;
 			lock_page(page);
 			wait_on_page_writeback(page);
 			if (page->index > next)
@@ -171,7 +189,19 @@
 		pagevec_release(&pvec);
 	}
 }
+EXPORT_SYMBOL(truncate_inode_pages_range);
 
+/**
+ * truncate_inode_pages - truncate *all* the pages from an offset
+ * @mapping: mapping to truncate
+ * @lstart: offset from which to truncate
+ *
+ * Called under (and serialised by) inode->i_sem.
+ */
+void truncate_inode_pages(struct address_space *mapping, loff_t lstart)
+{
+	truncate_inode_pages_range(mapping, lstart, (loff_t)-1);
+}
 EXPORT_SYMBOL(truncate_inode_pages);
 
 /**
@@ -219,7 +249,6 @@
 				break;
 		}
 		pagevec_release(&pvec);
-		cond_resched();
 	}
 	return ret;
 }
diff --git a/mm/util.c b/mm/util.c
new file mode 100644
index 0000000..5f4bb59
--- /dev/null
+++ b/mm/util.c
@@ -0,0 +1,39 @@
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+/**
+ * kzalloc - allocate memory. The memory is set to zero.
+ * @size: how many bytes of memory are required.
+ * @flags: the type of memory to allocate.
+ */
+void *kzalloc(size_t size, gfp_t flags)
+{
+	void *ret = kmalloc(size, flags);
+	if (ret)
+		memset(ret, 0, size);
+	return ret;
+}
+EXPORT_SYMBOL(kzalloc);
+
+/*
+ * kstrdup - allocate space for and copy an existing string
+ *
+ * @s: the string to duplicate
+ * @gfp: the GFP mask used in the kmalloc() call when allocating memory
+ */
+char *kstrdup(const char *s, gfp_t gfp)
+{
+	size_t len;
+	char *buf;
+
+	if (!s)
+		return NULL;
+
+	len = strlen(s) + 1;
+	buf = kmalloc(len, gfp);
+	if (buf)
+		memcpy(buf, s, len);
+	return buf;
+}
+EXPORT_SYMBOL(kstrdup);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 2813054..bf903b2 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -63,9 +63,6 @@
 
 	unsigned long nr_mapped;	/* From page_state */
 
-	/* How many pages shrink_cache() should reclaim */
-	int nr_to_reclaim;
-
 	/* Ask shrink_caches, or shrink_zone to scan at this priority */
 	unsigned int priority;
 
@@ -74,9 +71,6 @@
 
 	int may_writepage;
 
-	/* Can pages be swapped as part of reclaim? */
-	int may_swap;
-
 	/* This context's SWAP_CLUSTER_MAX. If freeing memory for
 	 * suspend, we effectively ignore SWAP_CLUSTER_MAX.
 	 * In this context, it doesn't matter that we scan the
@@ -186,8 +180,7 @@
  *
  * Returns the number of slab objects which we shrunk.
  */
-static int shrink_slab(unsigned long scanned, gfp_t gfp_mask,
-			unsigned long lru_pages)
+int shrink_slab(unsigned long scanned, gfp_t gfp_mask, unsigned long lru_pages)
 {
 	struct shrinker *shrinker;
 	int ret = 0;
@@ -201,13 +194,25 @@
 	list_for_each_entry(shrinker, &shrinker_list, list) {
 		unsigned long long delta;
 		unsigned long total_scan;
+		unsigned long max_pass = (*shrinker->shrinker)(0, gfp_mask);
 
 		delta = (4 * scanned) / shrinker->seeks;
-		delta *= (*shrinker->shrinker)(0, gfp_mask);
+		delta *= max_pass;
 		do_div(delta, lru_pages + 1);
 		shrinker->nr += delta;
-		if (shrinker->nr < 0)
-			shrinker->nr = LONG_MAX;	/* It wrapped! */
+		if (shrinker->nr < 0) {
+			printk(KERN_ERR "%s: nr=%ld\n",
+					__FUNCTION__, shrinker->nr);
+			shrinker->nr = max_pass;
+		}
+
+		/*
+		 * Avoid risking looping forever due to too large nr value:
+		 * never try to free more than twice the estimate number of
+		 * freeable entries.
+		 */
+		if (shrinker->nr > max_pass * 2)
+			shrinker->nr = max_pass * 2;
 
 		total_scan = shrinker->nr;
 		shrinker->nr = 0;
@@ -263,9 +268,7 @@
 
 static int may_write_to_queue(struct backing_dev_info *bdi)
 {
-	if (current_is_kswapd())
-		return 1;
-	if (current_is_pdflush())	/* This is unlikely, but why not... */
+	if (current->flags & PF_SWAPWRITE)
 		return 1;
 	if (!bdi_write_congested(bdi))
 		return 1;
@@ -355,7 +358,7 @@
 		res = mapping->a_ops->writepage(page, &wbc);
 		if (res < 0)
 			handle_write_error(mapping, page, res);
-		if (res == WRITEPAGE_ACTIVATE) {
+		if (res == AOP_WRITEPAGE_ACTIVATE) {
 			ClearPageReclaim(page);
 			return PAGE_ACTIVATE;
 		}
@@ -370,6 +373,43 @@
 	return PAGE_CLEAN;
 }
 
+static int remove_mapping(struct address_space *mapping, struct page *page)
+{
+	if (!mapping)
+		return 0;		/* truncate got there first */
+
+	write_lock_irq(&mapping->tree_lock);
+
+	/*
+	 * The non-racy check for busy page.  It is critical to check
+	 * PageDirty _after_ making sure that the page is freeable and
+	 * not in use by anybody. 	(pagecache + us == 2)
+	 */
+	if (unlikely(page_count(page) != 2))
+		goto cannot_free;
+	smp_rmb();
+	if (unlikely(PageDirty(page)))
+		goto cannot_free;
+
+	if (PageSwapCache(page)) {
+		swp_entry_t swap = { .val = page_private(page) };
+		__delete_from_swap_cache(page);
+		write_unlock_irq(&mapping->tree_lock);
+		swap_free(swap);
+		__put_page(page);	/* The pagecache ref */
+		return 1;
+	}
+
+	__remove_from_page_cache(page);
+	write_unlock_irq(&mapping->tree_lock);
+	__put_page(page);
+	return 1;
+
+cannot_free:
+	write_unlock_irq(&mapping->tree_lock);
+	return 0;
+}
+
 /*
  * shrink_list adds the number of reclaimed pages to sc->nr_reclaimed
  */
@@ -407,7 +447,7 @@
 		if (PageWriteback(page))
 			goto keep_locked;
 
-		referenced = page_referenced(page, 1, sc->priority <= 0);
+		referenced = page_referenced(page, 1);
 		/* In active use or really unfreeable?  Activate it. */
 		if (referenced && page_mapping_inuse(page))
 			goto activate_locked;
@@ -418,9 +458,7 @@
 		 * Try to allocate it some swap space here.
 		 */
 		if (PageAnon(page) && !PageSwapCache(page)) {
-			if (!sc->may_swap)
-				goto keep_locked;
-			if (!add_to_swap(page))
+			if (!add_to_swap(page, GFP_ATOMIC))
 				goto activate_locked;
 		}
 #endif /* CONFIG_SWAP */
@@ -503,36 +541,8 @@
 				goto free_it;
 		}
 
-		if (!mapping)
-			goto keep_locked;	/* truncate got there first */
-
-		write_lock_irq(&mapping->tree_lock);
-
-		/*
-		 * The non-racy check for busy page.  It is critical to check
-		 * PageDirty _after_ making sure that the page is freeable and
-		 * not in use by anybody. 	(pagecache + us == 2)
-		 */
-		if (unlikely(page_count(page) != 2))
-			goto cannot_free;
-		smp_rmb();
-		if (unlikely(PageDirty(page)))
-			goto cannot_free;
-
-#ifdef CONFIG_SWAP
-		if (PageSwapCache(page)) {
-			swp_entry_t swap = { .val = page_private(page) };
-			__delete_from_swap_cache(page);
-			write_unlock_irq(&mapping->tree_lock);
-			swap_free(swap);
-			__put_page(page);	/* The pagecache ref */
-			goto free_it;
-		}
-#endif /* CONFIG_SWAP */
-
-		__remove_from_page_cache(page);
-		write_unlock_irq(&mapping->tree_lock);
-		__put_page(page);
+		if (!remove_mapping(mapping, page))
+			goto keep_locked;
 
 free_it:
 		unlock_page(page);
@@ -541,10 +551,6 @@
 			__pagevec_release_nonlru(&freed_pvec);
 		continue;
 
-cannot_free:
-		write_unlock_irq(&mapping->tree_lock);
-		goto keep_locked;
-
 activate_locked:
 		SetPageActive(page);
 		pgactivate++;
@@ -562,6 +568,241 @@
 	return reclaimed;
 }
 
+#ifdef CONFIG_MIGRATION
+static inline void move_to_lru(struct page *page)
+{
+	list_del(&page->lru);
+	if (PageActive(page)) {
+		/*
+		 * lru_cache_add_active checks that
+		 * the PG_active bit is off.
+		 */
+		ClearPageActive(page);
+		lru_cache_add_active(page);
+	} else {
+		lru_cache_add(page);
+	}
+	put_page(page);
+}
+
+/*
+ * Add isolated pages on the list back to the LRU
+ *
+ * returns the number of pages put back.
+ */
+int putback_lru_pages(struct list_head *l)
+{
+	struct page *page;
+	struct page *page2;
+	int count = 0;
+
+	list_for_each_entry_safe(page, page2, l, lru) {
+		move_to_lru(page);
+		count++;
+	}
+	return count;
+}
+
+/*
+ * swapout a single page
+ * page is locked upon entry, unlocked on exit
+ */
+static int swap_page(struct page *page)
+{
+	struct address_space *mapping = page_mapping(page);
+
+	if (page_mapped(page) && mapping)
+		if (try_to_unmap(page) != SWAP_SUCCESS)
+			goto unlock_retry;
+
+	if (PageDirty(page)) {
+		/* Page is dirty, try to write it out here */
+		switch(pageout(page, mapping)) {
+		case PAGE_KEEP:
+		case PAGE_ACTIVATE:
+			goto unlock_retry;
+
+		case PAGE_SUCCESS:
+			goto retry;
+
+		case PAGE_CLEAN:
+			; /* try to free the page below */
+		}
+	}
+
+	if (PagePrivate(page)) {
+		if (!try_to_release_page(page, GFP_KERNEL) ||
+		    (!mapping && page_count(page) == 1))
+			goto unlock_retry;
+	}
+
+	if (remove_mapping(mapping, page)) {
+		/* Success */
+		unlock_page(page);
+		return 0;
+	}
+
+unlock_retry:
+	unlock_page(page);
+
+retry:
+	return -EAGAIN;
+}
+/*
+ * migrate_pages
+ *
+ * Two lists are passed to this function. The first list
+ * contains the pages isolated from the LRU to be migrated.
+ * The second list contains new pages that the pages isolated
+ * can be moved to. If the second list is NULL then all
+ * pages are swapped out.
+ *
+ * The function returns after 10 attempts or if no pages
+ * are movable anymore because t has become empty
+ * or no retryable pages exist anymore.
+ *
+ * SIMPLIFIED VERSION: This implementation of migrate_pages
+ * is only swapping out pages and never touches the second
+ * list. The direct migration patchset
+ * extends this function to avoid the use of swap.
+ *
+ * Return: Number of pages not migrated when "to" ran empty.
+ */
+int migrate_pages(struct list_head *from, struct list_head *to,
+		  struct list_head *moved, struct list_head *failed)
+{
+	int retry;
+	int nr_failed = 0;
+	int pass = 0;
+	struct page *page;
+	struct page *page2;
+	int swapwrite = current->flags & PF_SWAPWRITE;
+	int rc;
+
+	if (!swapwrite)
+		current->flags |= PF_SWAPWRITE;
+
+redo:
+	retry = 0;
+
+	list_for_each_entry_safe(page, page2, from, lru) {
+		cond_resched();
+
+		rc = 0;
+		if (page_count(page) == 1)
+			/* page was freed from under us. So we are done. */
+			goto next;
+
+		/*
+		 * Skip locked pages during the first two passes to give the
+		 * functions holding the lock time to release the page. Later we
+		 * use lock_page() to have a higher chance of acquiring the
+		 * lock.
+		 */
+		rc = -EAGAIN;
+		if (pass > 2)
+			lock_page(page);
+		else
+			if (TestSetPageLocked(page))
+				goto next;
+
+		/*
+		 * Only wait on writeback if we have already done a pass where
+		 * we we may have triggered writeouts for lots of pages.
+		 */
+		if (pass > 0) {
+			wait_on_page_writeback(page);
+		} else {
+			if (PageWriteback(page))
+				goto unlock_page;
+		}
+
+		/*
+		 * Anonymous pages must have swap cache references otherwise
+		 * the information contained in the page maps cannot be
+		 * preserved.
+		 */
+		if (PageAnon(page) && !PageSwapCache(page)) {
+			if (!add_to_swap(page, GFP_KERNEL)) {
+				rc = -ENOMEM;
+				goto unlock_page;
+			}
+		}
+
+		/*
+		 * Page is properly locked and writeback is complete.
+		 * Try to migrate the page.
+		 */
+		rc = swap_page(page);
+		goto next;
+
+unlock_page:
+		unlock_page(page);
+
+next:
+		if (rc == -EAGAIN) {
+			retry++;
+		} else if (rc) {
+			/* Permanent failure */
+			list_move(&page->lru, failed);
+			nr_failed++;
+		} else {
+			/* Success */
+			list_move(&page->lru, moved);
+		}
+	}
+	if (retry && pass++ < 10)
+		goto redo;
+
+	if (!swapwrite)
+		current->flags &= ~PF_SWAPWRITE;
+
+	return nr_failed + retry;
+}
+
+static void lru_add_drain_per_cpu(void *dummy)
+{
+	lru_add_drain();
+}
+
+/*
+ * Isolate one page from the LRU lists and put it on the
+ * indicated list. Do necessary cache draining if the
+ * page is not on the LRU lists yet.
+ *
+ * Result:
+ *  0 = page not on LRU list
+ *  1 = page removed from LRU list and added to the specified list.
+ * -ENOENT = page is being freed elsewhere.
+ */
+int isolate_lru_page(struct page *page)
+{
+	int rc = 0;
+	struct zone *zone = page_zone(page);
+
+redo:
+	spin_lock_irq(&zone->lru_lock);
+	rc = __isolate_lru_page(page);
+	if (rc == 1) {
+		if (PageActive(page))
+			del_page_from_active_list(zone, page);
+		else
+			del_page_from_inactive_list(zone, page);
+	}
+	spin_unlock_irq(&zone->lru_lock);
+	if (rc == 0) {
+		/*
+		 * Maybe this page is still waiting for a cpu to drain it
+		 * from one of the lru lists?
+		 */
+		rc = schedule_on_each_cpu(lru_add_drain_per_cpu, NULL);
+		if (rc == 0 && PageLRU(page))
+			goto redo;
+	}
+	return rc;
+}
+#endif
+
 /*
  * zone->lru_lock is heavily contended.  Some of the functions that
  * shrink the lists perform better by taking out a batch of pages
@@ -590,20 +831,18 @@
 		page = lru_to_page(src);
 		prefetchw_prev_lru_page(page, src, flags);
 
-		if (!TestClearPageLRU(page))
-			BUG();
-		list_del(&page->lru);
-		if (get_page_testone(page)) {
-			/*
-			 * It is being freed elsewhere
-			 */
-			__put_page(page);
-			SetPageLRU(page);
-			list_add(&page->lru, src);
-			continue;
-		} else {
-			list_add(&page->lru, dst);
+		switch (__isolate_lru_page(page)) {
+		case 1:
+			/* Succeeded to isolate page */
+			list_move(&page->lru, dst);
 			nr_taken++;
+			break;
+		case -ENOENT:
+			/* Not possible to isolate */
+			list_move(&page->lru, src);
+			break;
+		default:
+			BUG();
 		}
 	}
 
@@ -641,17 +880,17 @@
 			goto done;
 
 		max_scan -= nr_scan;
-		if (current_is_kswapd())
-			mod_page_state_zone(zone, pgscan_kswapd, nr_scan);
-		else
-			mod_page_state_zone(zone, pgscan_direct, nr_scan);
 		nr_freed = shrink_list(&page_list, sc);
-		if (current_is_kswapd())
-			mod_page_state(kswapd_steal, nr_freed);
-		mod_page_state_zone(zone, pgsteal, nr_freed);
-		sc->nr_to_reclaim -= nr_freed;
 
-		spin_lock_irq(&zone->lru_lock);
+		local_irq_disable();
+		if (current_is_kswapd()) {
+			__mod_page_state_zone(zone, pgscan_kswapd, nr_scan);
+			__mod_page_state(kswapd_steal, nr_freed);
+		} else
+			__mod_page_state_zone(zone, pgscan_direct, nr_scan);
+		__mod_page_state_zone(zone, pgsteal, nr_freed);
+
+		spin_lock(&zone->lru_lock);
 		/*
 		 * Put back any unfreeable pages.
 		 */
@@ -756,7 +995,7 @@
 		if (page_mapped(page)) {
 			if (!reclaim_mapped ||
 			    (total_swap_pages == 0 && PageAnon(page)) ||
-			    page_referenced(page, 0, sc->priority <= 0)) {
+			    page_referenced(page, 0)) {
 				list_add(&page->lru, &l_active);
 				continue;
 			}
@@ -813,11 +1052,13 @@
 		}
 	}
 	zone->nr_active += pgmoved;
-	spin_unlock_irq(&zone->lru_lock);
-	pagevec_release(&pvec);
+	spin_unlock(&zone->lru_lock);
 
-	mod_page_state_zone(zone, pgrefill, pgscanned);
-	mod_page_state(pgdeactivate, pgdeactivate);
+	__mod_page_state_zone(zone, pgrefill, pgscanned);
+	__mod_page_state(pgdeactivate, pgdeactivate);
+	local_irq_enable();
+
+	pagevec_release(&pvec);
 }
 
 /*
@@ -849,8 +1090,6 @@
 	else
 		nr_inactive = 0;
 
-	sc->nr_to_reclaim = sc->swap_cluster_max;
-
 	while (nr_active || nr_inactive) {
 		if (nr_active) {
 			sc->nr_to_scan = min(nr_active,
@@ -864,8 +1103,6 @@
 					(unsigned long)sc->swap_cluster_max);
 			nr_inactive -= sc->nr_to_scan;
 			shrink_cache(zone, sc);
-			if (sc->nr_to_reclaim <= 0)
-				break;
 		}
 	}
 
@@ -898,7 +1135,7 @@
 	for (i = 0; zones[i] != NULL; i++) {
 		struct zone *zone = zones[i];
 
-		if (zone->present_pages == 0)
+		if (!populated_zone(zone))
 			continue;
 
 		if (!cpuset_zone_allowed(zone, __GFP_HARDWALL))
@@ -940,7 +1177,6 @@
 
 	sc.gfp_mask = gfp_mask;
 	sc.may_writepage = 0;
-	sc.may_swap = 1;
 
 	inc_page_state(allocstall);
 
@@ -960,6 +1196,8 @@
 		sc.nr_reclaimed = 0;
 		sc.priority = priority;
 		sc.swap_cluster_max = SWAP_CLUSTER_MAX;
+		if (!priority)
+			disable_swap_token();
 		shrink_caches(zones, &sc);
 		shrink_slab(sc.nr_scanned, gfp_mask, lru_pages);
 		if (reclaim_state) {
@@ -1041,7 +1279,6 @@
 	total_reclaimed = 0;
 	sc.gfp_mask = GFP_KERNEL;
 	sc.may_writepage = 0;
-	sc.may_swap = 1;
 	sc.nr_mapped = read_page_state(nr_mapped);
 
 	inc_page_state(pageoutrun);
@@ -1056,6 +1293,10 @@
 		int end_zone = 0;	/* Inclusive.  0 = ZONE_DMA */
 		unsigned long lru_pages = 0;
 
+		/* The swap token gets in the way of swapout... */
+		if (!priority)
+			disable_swap_token();
+
 		all_zones_ok = 1;
 
 		if (nr_pages == 0) {
@@ -1066,7 +1307,7 @@
 			for (i = pgdat->nr_zones - 1; i >= 0; i--) {
 				struct zone *zone = pgdat->node_zones + i;
 
-				if (zone->present_pages == 0)
+				if (!populated_zone(zone))
 					continue;
 
 				if (zone->all_unreclaimable &&
@@ -1103,7 +1344,7 @@
 			struct zone *zone = pgdat->node_zones + i;
 			int nr_slab;
 
-			if (zone->present_pages == 0)
+			if (!populated_zone(zone))
 				continue;
 
 			if (zone->all_unreclaimable && priority != DEF_PRIORITY)
@@ -1220,7 +1461,7 @@
 	 * us from recursively trying to free more memory as we're
 	 * trying to free the first piece of memory in the first place).
 	 */
-	tsk->flags |= PF_MEMALLOC|PF_KSWAPD;
+	tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
 
 	order = 0;
 	for ( ; ; ) {
@@ -1255,7 +1496,7 @@
 {
 	pg_data_t *pgdat;
 
-	if (zone->present_pages == 0)
+	if (!populated_zone(zone))
 		return;
 
 	pgdat = zone->zone_pgdat;
@@ -1335,75 +1576,3 @@
 }
 
 module_init(kswapd_init)
-
-
-/*
- * Try to free up some pages from this zone through reclaim.
- */
-int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
-{
-	struct scan_control sc;
-	int nr_pages = 1 << order;
-	int total_reclaimed = 0;
-
-	/* The reclaim may sleep, so don't do it if sleep isn't allowed */
-	if (!(gfp_mask & __GFP_WAIT))
-		return 0;
-	if (zone->all_unreclaimable)
-		return 0;
-
-	sc.gfp_mask = gfp_mask;
-	sc.may_writepage = 0;
-	sc.may_swap = 0;
-	sc.nr_mapped = read_page_state(nr_mapped);
-	sc.nr_scanned = 0;
-	sc.nr_reclaimed = 0;
-	/* scan at the highest priority */
-	sc.priority = 0;
-
-	if (nr_pages > SWAP_CLUSTER_MAX)
-		sc.swap_cluster_max = nr_pages;
-	else
-		sc.swap_cluster_max = SWAP_CLUSTER_MAX;
-
-	/* Don't reclaim the zone if there are other reclaimers active */
-	if (atomic_read(&zone->reclaim_in_progress) > 0)
-		goto out;
-
-	shrink_zone(zone, &sc);
-	total_reclaimed = sc.nr_reclaimed;
-
- out:
-	return total_reclaimed;
-}
-
-asmlinkage long sys_set_zone_reclaim(unsigned int node, unsigned int zone,
-				     unsigned int state)
-{
-	struct zone *z;
-	int i;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EACCES;
-
-	if (node >= MAX_NUMNODES || !node_online(node))
-		return -EINVAL;
-
-	/* This will break if we ever add more zones */
-	if (!(zone & (1<<ZONE_DMA|1<<ZONE_NORMAL|1<<ZONE_HIGHMEM)))
-		return -EINVAL;
-
-	for (i = 0; i < MAX_NR_ZONES; i++) {
-		if (!(zone & 1<<i))
-			continue;
-
-		z = &NODE_DATA(node)->node_zones[i];
-
-		if (state)
-			z->reclaim_pages = 1;
-		else
-			z->reclaim_pages = 0;
-	}
-
-	return 0;
-}
diff --git a/net/802/Makefile b/net/802/Makefile
index 0186192..977704a 100644
--- a/net/802/Makefile
+++ b/net/802/Makefile
@@ -2,8 +2,6 @@
 # Makefile for the Linux 802.x protocol layers.
 #
 
-obj-y			:= p8023.o
-
 # Check the p8022 selections against net/core/Makefile.
 obj-$(CONFIG_SYSCTL)	+= sysctl_net_802.o
 obj-$(CONFIG_LLC)	+= p8022.o psnap.o
@@ -11,5 +9,5 @@
 obj-$(CONFIG_NET_FC)	+=                 fc.o
 obj-$(CONFIG_FDDI)	+=                 fddi.o
 obj-$(CONFIG_HIPPI)	+=                 hippi.o
-obj-$(CONFIG_IPX)	+= p8022.o psnap.o
+obj-$(CONFIG_IPX)	+= p8022.o psnap.o p8023.o
 obj-$(CONFIG_ATALK)	+= p8022.o psnap.o
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 91e412b..67465b6 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -753,6 +753,8 @@
 		break;
 	case GET_VLAN_REALDEV_NAME_CMD:
 		err = vlan_dev_get_realdev_name(args.device1, args.u.device2);
+		if (err)
+			goto out;
 		if (copy_to_user(arg, &args,
 				 sizeof(struct vlan_ioctl_args))) {
 			err = -EFAULT;
@@ -761,6 +763,8 @@
 
 	case GET_VLAN_VID_CMD:
 		err = vlan_dev_get_vid(args.device1, &vid);
+		if (err)
+			goto out;
 		args.u.VID = vid;
 		if (copy_to_user(arg, &args,
 				 sizeof(struct vlan_ioctl_args))) {
@@ -774,7 +778,7 @@
 			__FUNCTION__, args.cmd);
 		return -EINVAL;
 	};
-
+out:
 	return err;
 }
 
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index b748648..f2a8750 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -165,6 +165,9 @@
 
 	skb_pull(skb, VLAN_HLEN); /* take off the VLAN header (4 bytes currently) */
 
+	/* Need to correct hardware checksum */
+	skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
+
 	/* Ok, lets check to make sure the device (dev) we
 	 * came in on is what this VLAN is attached to.
 	 */
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 7982656..a5144e4 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -63,7 +63,7 @@
 #include <linux/atalk.h>
 
 struct datalink_proto *ddp_dl, *aarp_dl;
-static struct proto_ops atalk_dgram_ops;
+static const struct proto_ops atalk_dgram_ops;
 
 /**************************************************************************\
 *                                                                          *
@@ -1763,7 +1763,7 @@
  */
 static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
-	int rc = -EINVAL;
+	int rc = -ENOIOCTLCMD;
 	struct sock *sk = sock->sk;
 	void __user *argp = (void __user *)arg;
 
@@ -1813,23 +1813,6 @@
 			rc = atif_ioctl(cmd, argp);
 			rtnl_unlock();
 			break;
-		/* Physical layer ioctl calls */
-		case SIOCSIFLINK:
-		case SIOCGIFHWADDR:
-		case SIOCSIFHWADDR:
-		case SIOCGIFFLAGS:
-		case SIOCSIFFLAGS:
-		case SIOCGIFTXQLEN:
-		case SIOCSIFTXQLEN:
-		case SIOCGIFMTU:
-		case SIOCGIFCONF:
-		case SIOCADDMULTI:
-		case SIOCDELMULTI:
-		case SIOCGIFCOUNT:
-		case SIOCGIFINDEX:
-		case SIOCGIFNAME:
-			rc = dev_ioctl(cmd, argp);
-			break;
 	}
 
 	return rc;
@@ -1841,7 +1824,7 @@
 	.owner		= THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
 	.family		= PF_APPLETALK,
 	.owner		= THIS_MODULE,
 	.release	= atalk_release,
diff --git a/net/atm/atm_misc.c b/net/atm/atm_misc.c
index 223c7ad..02cc7e7 100644
--- a/net/atm/atm_misc.c
+++ b/net/atm/atm_misc.c
@@ -74,11 +74,14 @@
  */
 
 
-int atm_pcr_goal(struct atm_trafprm *tp)
+int atm_pcr_goal(const struct atm_trafprm *tp)
 {
-	if (tp->pcr && tp->pcr != ATM_MAX_PCR) return -tp->pcr;
-	if (tp->min_pcr && !tp->pcr) return tp->min_pcr;
-	if (tp->max_pcr != ATM_MAX_PCR) return -tp->max_pcr;
+	if (tp->pcr && tp->pcr != ATM_MAX_PCR)
+		return -tp->pcr;
+	if (tp->min_pcr && !tp->pcr)
+		return tp->min_pcr;
+	if (tp->max_pcr != ATM_MAX_PCR)
+		return -tp->max_pcr;
 	return 0;
 }
 
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 72f3f7b..bdb4d89 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -295,7 +295,7 @@
 	unsigned char *rawp;
 	eth = eth_hdr(skb);
 
-	if (*eth->h_dest & 1) {
+	if (is_multicast_ether_addr(eth->h_dest)) {
 		if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0)
 			skb->pkt_type = PACKET_BROADCAST;
 		else
diff --git a/net/atm/common.c b/net/atm/common.c
index 63feea4..6656b11 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -221,6 +221,29 @@
 EXPORT_SYMBOL(vcc_release_async);
 
 
+void atm_dev_release_vccs(struct atm_dev *dev)
+{
+	int i;
+
+	write_lock_irq(&vcc_sklist_lock);
+	for (i = 0; i < VCC_HTABLE_SIZE; i++) {
+		struct hlist_head *head = &vcc_hash[i];
+		struct hlist_node *node, *tmp;
+		struct sock *s;
+		struct atm_vcc *vcc;
+
+		sk_for_each_safe(s, node, tmp, head) {
+			vcc = atm_sk(s);
+			if (vcc->dev == dev) {
+				vcc_release_async(vcc, -EPIPE);
+				sk_del_node_init(s);
+			}
+		}
+	}
+	write_unlock_irq(&vcc_sklist_lock);
+}
+
+
 static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
 {
 	int max_sdu;
@@ -332,12 +355,13 @@
 		return -EINVAL;
 	if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE))
 		return -EPERM;
-	error = 0;
+	error = -ENODEV;
 	if (!try_module_get(dev->ops->owner))
-		return -ENODEV;
+		return error;
 	vcc->dev = dev;
 	write_lock_irq(&vcc_sklist_lock);
-	if ((error = find_ci(vcc, &vpi, &vci))) {
+	if (test_bit(ATM_DF_REMOVED, &dev->flags) || 
+	    (error = find_ci(vcc, &vpi, &vci))) {
 		write_unlock_irq(&vcc_sklist_lock);
 		goto fail_module_put;
 	}
@@ -423,33 +447,23 @@
 	if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
 	    vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
 		return -EINVAL;
-	if (itf != ATM_ITF_ANY) {
-		dev = atm_dev_lookup(itf);
-		if (!dev)
-			return -ENODEV;
-		error = __vcc_connect(vcc, dev, vpi, vci);
-		if (error) {
-			atm_dev_put(dev);
-			return error;
-		}
+	if (likely(itf != ATM_ITF_ANY)) {
+		dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf);
 	} else {
-		struct list_head *p, *next;
-
 		dev = NULL;
-		spin_lock(&atm_dev_lock);
-		list_for_each_safe(p, next, &atm_devs) {
-			dev = list_entry(p, struct atm_dev, dev_list);
+		down(&atm_dev_mutex);
+		if (!list_empty(&atm_devs)) {
+			dev = list_entry(atm_devs.next, struct atm_dev, dev_list);
 			atm_dev_hold(dev);
-			spin_unlock(&atm_dev_lock);
-			if (!__vcc_connect(vcc, dev, vpi, vci))
-				break;
-			atm_dev_put(dev);
-			dev = NULL;
-			spin_lock(&atm_dev_lock);
 		}
-		spin_unlock(&atm_dev_lock);
-		if (!dev)
-			return -ENODEV;
+		up(&atm_dev_mutex);
+	}
+	if (!dev)
+		return -ENODEV;
+	error = __vcc_connect(vcc, dev, vpi, vci);
+	if (error) {
+		atm_dev_put(dev);
+		return error;
 	}
 	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
 		set_bit(ATM_VF_PARTIAL,&vcc->flags);
diff --git a/net/atm/common.h b/net/atm/common.h
index e49ed41c..4887c31 100644
--- a/net/atm/common.h
+++ b/net/atm/common.h
@@ -47,4 +47,6 @@
 /* SVC */
 int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos);
 
+void atm_dev_release_vccs(struct atm_dev *dev);
+
 #endif
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index 2684a92..f2c5417 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -102,7 +102,7 @@
 }
 
 
-static struct proto_ops pvc_proto_ops = {
+static const struct proto_ops pvc_proto_ops = {
 	.family =	PF_ATMPVC,
 	.owner =	THIS_MODULE,
 
diff --git a/net/atm/resources.c b/net/atm/resources.c
index 415d261..c8c459f 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -25,7 +25,7 @@
 
 
 LIST_HEAD(atm_devs);
-DEFINE_SPINLOCK(atm_dev_lock);
+DECLARE_MUTEX(atm_dev_mutex);
 
 static struct atm_dev *__alloc_atm_dev(const char *type)
 {
@@ -52,7 +52,7 @@
 
 	list_for_each(p, &atm_devs) {
 		dev = list_entry(p, struct atm_dev, dev_list);
-		if ((dev->ops) && (dev->number == number)) {
+		if (dev->number == number) {
 			atm_dev_hold(dev);
 			return dev;
 		}
@@ -64,12 +64,13 @@
 {
 	struct atm_dev *dev;
 
-	spin_lock(&atm_dev_lock);
+	down(&atm_dev_mutex);
 	dev = __atm_dev_lookup(number);
-	spin_unlock(&atm_dev_lock);
+	up(&atm_dev_mutex);
 	return dev;
 }
 
+
 struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
 				 int number, unsigned long *flags)
 {
@@ -81,11 +82,11 @@
 		    type);
 		return NULL;
 	}
-	spin_lock(&atm_dev_lock);
+	down(&atm_dev_mutex);
 	if (number != -1) {
 		if ((inuse = __atm_dev_lookup(number))) {
 			atm_dev_put(inuse);
-			spin_unlock(&atm_dev_lock);
+			up(&atm_dev_mutex);
 			kfree(dev);
 			return NULL;
 		}
@@ -105,19 +106,17 @@
 		memset(&dev->flags, 0, sizeof(dev->flags));
 	memset(&dev->stats, 0, sizeof(dev->stats));
 	atomic_set(&dev->refcnt, 1);
-	list_add_tail(&dev->dev_list, &atm_devs);
-	spin_unlock(&atm_dev_lock);
 
 	if (atm_proc_dev_register(dev) < 0) {
 		printk(KERN_ERR "atm_dev_register: "
 		       "atm_proc_dev_register failed for dev %s\n",
 		       type);
-		spin_lock(&atm_dev_lock);
-		list_del(&dev->dev_list);
-		spin_unlock(&atm_dev_lock);
+		up(&atm_dev_mutex);
 		kfree(dev);
 		return NULL;
 	}
+	list_add_tail(&dev->dev_list, &atm_devs);
+	up(&atm_dev_mutex);
 
 	return dev;
 }
@@ -125,37 +124,22 @@
 
 void atm_dev_deregister(struct atm_dev *dev)
 {
-	unsigned long warning_time;
+	BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags));
+	set_bit(ATM_DF_REMOVED, &dev->flags);
 
+	/*
+	 * if we remove current device from atm_devs list, new device 
+	 * with same number can appear, such we need deregister proc, 
+	 * release async all vccs and remove them from vccs list too
+	 */
+	down(&atm_dev_mutex);
+	list_del(&dev->dev_list);
+	up(&atm_dev_mutex);
+
+	atm_dev_release_vccs(dev);
 	atm_proc_dev_deregister(dev);
 
-	spin_lock(&atm_dev_lock);
-	list_del(&dev->dev_list);
-	spin_unlock(&atm_dev_lock);
-
-        warning_time = jiffies;
-        while (atomic_read(&dev->refcnt) != 1) {
-                msleep(250);
-                if ((jiffies - warning_time) > 10 * HZ) {
-                        printk(KERN_EMERG "atm_dev_deregister: waiting for "
-                               "dev %d to become free. Usage count = %d\n",
-                               dev->number, atomic_read(&dev->refcnt));
-                        warning_time = jiffies;
-                }
-        }
-
-	kfree(dev);
-}
-
-void shutdown_atm_dev(struct atm_dev *dev)
-{
-	if (atomic_read(&dev->refcnt) > 1) {
-		set_bit(ATM_DF_CLOSE, &dev->flags);
-		return;
-	}
-	if (dev->ops->dev_close)
-		dev->ops->dev_close(dev);
-	atm_dev_deregister(dev);
+	atm_dev_put(dev);
 }
 
 
@@ -211,16 +195,16 @@
 				return -EFAULT;
 			if (get_user(len, &iobuf->length))
 				return -EFAULT;
-			spin_lock(&atm_dev_lock);
+			down(&atm_dev_mutex);
 			list_for_each(p, &atm_devs)
 				size += sizeof(int);
 			if (size > len) {
-				spin_unlock(&atm_dev_lock);
+				up(&atm_dev_mutex);
 				return -E2BIG;
 			}
 			tmp_buf = kmalloc(size, GFP_ATOMIC);
 			if (!tmp_buf) {
-				spin_unlock(&atm_dev_lock);
+				up(&atm_dev_mutex);
 				return -ENOMEM;
 			}
 			tmp_p = tmp_buf;
@@ -228,7 +212,7 @@
 				dev = list_entry(p, struct atm_dev, dev_list);
 				*tmp_p++ = dev->number;
 			}
-			spin_unlock(&atm_dev_lock);
+			up(&atm_dev_mutex);
 		        error = ((copy_to_user(buf, tmp_buf, size)) ||
 					put_user(size, &iobuf->length))
 						? -EFAULT : 0;
@@ -245,7 +229,8 @@
 	if (get_user(number, &sioc->number))
 		return -EFAULT;
 
-	if (!(dev = atm_dev_lookup(number)))
+	if (!(dev = try_then_request_module(atm_dev_lookup(number),
+					    "atm-device-%d", number)))
 		return -ENODEV;
 	
 	switch (cmd) {
@@ -414,13 +399,13 @@
 
 void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
 {
- 	spin_lock(&atm_dev_lock);
+ 	down(&atm_dev_mutex);
 	return *pos ? dev_get_idx(*pos) : (void *) 1;
 }
 
 void atm_dev_seq_stop(struct seq_file *seq, void *v)
 {
- 	spin_unlock(&atm_dev_lock);
+ 	up(&atm_dev_mutex);
 }
  
 void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
@@ -434,4 +419,3 @@
 EXPORT_SYMBOL(atm_dev_register);
 EXPORT_SYMBOL(atm_dev_deregister);
 EXPORT_SYMBOL(atm_dev_lookup);
-EXPORT_SYMBOL(shutdown_atm_dev);
diff --git a/net/atm/resources.h b/net/atm/resources.h
index 1291061..b7fb82a 100644
--- a/net/atm/resources.h
+++ b/net/atm/resources.h
@@ -11,8 +11,7 @@
 
 
 extern struct list_head atm_devs;
-extern spinlock_t atm_dev_lock;
-
+extern struct semaphore atm_dev_mutex;
 
 int atm_dev_ioctl(unsigned int cmd, void __user *arg);
 
diff --git a/net/atm/svc.c b/net/atm/svc.c
index d7b2661..3a180cf 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -613,7 +613,7 @@
 	return error;
 }
 
-static struct proto_ops svc_proto_ops = {
+static const struct proto_ops svc_proto_ops = {
 	.family =	PF_ATMSVC,
 	.owner =	THIS_MODULE,
 
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 1b683f3..e8753c7 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -54,7 +54,7 @@
 HLIST_HEAD(ax25_list);
 DEFINE_SPINLOCK(ax25_list_lock);
 
-static struct proto_ops ax25_proto_ops;
+static const struct proto_ops ax25_proto_ops;
 
 static void ax25_free_sock(struct sock *sk)
 {
@@ -1827,7 +1827,7 @@
 		break;
 
 	default:
-		res = dev_ioctl(cmd, argp);
+		res = -ENOIOCTLCMD;
 		break;
 	}
 	release_sock(sk);
@@ -1944,7 +1944,7 @@
 	.owner	=	THIS_MODULE,
 };
 
-static struct proto_ops ax25_proto_ops = {
+static const struct proto_ops ax25_proto_ops = {
 	.family		= PF_AX25,
 	.owner		= THIS_MODULE,
 	.release	= ax25_release,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index ea616e3..fb031fe 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -287,10 +287,9 @@
 		timeo = schedule_timeout(timeo);
 		lock_sock(sk);
 
-		if (sk->sk_err) {
-			err = sock_error(sk);
+		err = sock_error(sk);
+		if (err)
 			break;
-		}
 	}
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(sk->sk_sleep, &wait);
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c
index 9778c6a..ccbaf69 100644
--- a/net/bluetooth/bnep/sock.c
+++ b/net/bluetooth/bnep/sock.c
@@ -146,7 +146,7 @@
 	return 0;
 }
 
-static struct proto_ops bnep_sock_ops = {
+static const struct proto_ops bnep_sock_ops = {
 	.family     = PF_BLUETOOTH,
 	.owner      = THIS_MODULE,
 	.release    = bnep_sock_release,
diff --git a/net/bluetooth/cmtp/sock.c b/net/bluetooth/cmtp/sock.c
index beb045b..5e22343 100644
--- a/net/bluetooth/cmtp/sock.c
+++ b/net/bluetooth/cmtp/sock.c
@@ -137,7 +137,7 @@
 	return -EINVAL;
 }
 
-static struct proto_ops cmtp_sock_ops = {
+static const struct proto_ops cmtp_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= cmtp_sock_release,
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 1d6d0a1..84e6c93 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -575,7 +575,7 @@
 	return 0;
 }
 
-static struct proto_ops hci_sock_ops = {
+static const struct proto_ops hci_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= hci_sock_release,
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index bd7568a..0ed3874 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -78,7 +78,7 @@
 };
 
 #ifdef CONFIG_HOTPLUG
-static int bt_hotplug(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
+static int bt_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
 {
 	struct hci_dev *hdev = class_get_devdata(cdev);
 	int n, i = 0;
@@ -107,7 +107,7 @@
 	.name		= "bluetooth",
 	.release	= bt_release,
 #ifdef CONFIG_HOTPLUG
-	.hotplug	= bt_hotplug,
+	.uevent		= bt_uevent,
 #endif
 };
 
diff --git a/net/bluetooth/hidp/sock.c b/net/bluetooth/hidp/sock.c
index f8986f8..8f8dd93 100644
--- a/net/bluetooth/hidp/sock.c
+++ b/net/bluetooth/hidp/sock.c
@@ -143,7 +143,7 @@
 	return -EINVAL;
 }
 
-static struct proto_ops hidp_sock_ops = {
+static const struct proto_ops hidp_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= hidp_sock_release,
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index e3bb11c..7f0781e 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -57,7 +57,7 @@
 
 #define VERSION "2.8"
 
-static struct proto_ops l2cap_sock_ops;
+static const struct proto_ops l2cap_sock_ops;
 
 static struct bt_sock_list l2cap_sk_list = {
 	.lock = RW_LOCK_UNLOCKED
@@ -767,8 +767,9 @@
 
 	BT_DBG("sock %p, sk %p", sock, sk);
 
-	if (sk->sk_err)
-		return sock_error(sk);
+	err = sock_error(sk);
+	if (err)
+		return err;
 
 	if (msg->msg_flags & MSG_OOB)
 		return -EOPNOTSUPP;
@@ -2160,7 +2161,7 @@
 
 static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
 
-static struct proto_ops l2cap_sock_ops = {
+static const struct proto_ops l2cap_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= l2cap_sock_release,
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 6c34261..757d2dd 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -58,7 +58,7 @@
 #define BT_DBG(D...)
 #endif
 
-static struct proto_ops rfcomm_sock_ops;
+static const struct proto_ops rfcomm_sock_ops;
 
 static struct bt_sock_list rfcomm_sk_list = {
 	.lock = RW_LOCK_UNLOCKED
@@ -907,7 +907,7 @@
 
 static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
 
-static struct proto_ops rfcomm_sock_ops = {
+static const struct proto_ops rfcomm_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= rfcomm_sock_release,
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 9cb00dc..6b61323 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -56,7 +56,7 @@
 
 #define VERSION "0.5"
 
-static struct proto_ops sco_sock_ops;
+static const struct proto_ops sco_sock_ops;
 
 static struct bt_sock_list sco_sk_list = {
 	.lock = RW_LOCK_UNLOCKED
@@ -637,8 +637,9 @@
 
 	BT_DBG("sock %p, sk %p", sock, sk);
 
-	if (sk->sk_err)
-		return sock_error(sk);
+	err = sock_error(sk);
+	if (err)
+		return err;
 
 	if (msg->msg_flags & MSG_OOB)
 		return -EOPNOTSUPP;
@@ -913,7 +914,7 @@
 
 static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
 
-static struct proto_ops sco_sock_ops = {
+static const struct proto_ops sco_sock_ops = {
 	.family		= PF_BLUETOOTH,
 	.owner		= THIS_MODULE,
 	.release	= sco_sock_release,
diff --git a/net/bridge/br.c b/net/bridge/br.c
index f8f1849..188cc1a 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -67,3 +67,4 @@
 module_init(br_init)
 module_exit(br_deinit)
 MODULE_LICENSE("GPL");
+MODULE_VERSION(BR_VERSION);
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index f564ee9..0b33a7b 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -15,7 +15,9 @@
 
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
-#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+
 #include <asm/uaccess.h>
 #include "br_private.h"
 
@@ -82,6 +84,87 @@
 	return 0;
 }
 
+/* Allow setting mac address of pseudo-bridge to be same as
+ * any of the bound interfaces
+ */
+static int br_set_mac_address(struct net_device *dev, void *p)
+{
+	struct net_bridge *br = netdev_priv(dev);
+	struct sockaddr *addr = p;
+	struct net_bridge_port *port;
+	int err = -EADDRNOTAVAIL;
+
+	spin_lock_bh(&br->lock);
+	list_for_each_entry(port, &br->port_list, list) {
+		if (!compare_ether_addr(port->dev->dev_addr, addr->sa_data)) {
+			br_stp_change_bridge_id(br, addr->sa_data);
+			err = 0;
+			break;
+		}
+	}
+	spin_unlock_bh(&br->lock);
+
+	return err;
+}
+
+static void br_getinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, "bridge");
+	strcpy(info->version, BR_VERSION);
+	strcpy(info->fw_version, "N/A");
+	strcpy(info->bus_info, "N/A");
+}
+
+static int br_set_sg(struct net_device *dev, u32 data)
+{
+	struct net_bridge *br = netdev_priv(dev);
+
+	if (data)
+		br->feature_mask |= NETIF_F_SG;
+	else
+		br->feature_mask &= ~NETIF_F_SG;
+
+	br_features_recompute(br);
+	return 0;
+}
+
+static int br_set_tso(struct net_device *dev, u32 data)
+{
+	struct net_bridge *br = netdev_priv(dev);
+
+	if (data)
+		br->feature_mask |= NETIF_F_TSO;
+	else
+		br->feature_mask &= ~NETIF_F_TSO;
+
+	br_features_recompute(br);
+	return 0;
+}
+
+static int br_set_tx_csum(struct net_device *dev, u32 data)
+{
+	struct net_bridge *br = netdev_priv(dev);
+
+	if (data)
+		br->feature_mask |= NETIF_F_IP_CSUM;
+	else
+		br->feature_mask &= ~NETIF_F_IP_CSUM;
+
+	br_features_recompute(br);
+	return 0;
+}
+
+static struct ethtool_ops br_ethtool_ops = {
+	.get_drvinfo = br_getinfo,
+	.get_link = ethtool_op_get_link,
+	.get_sg = ethtool_op_get_sg,
+	.set_sg = br_set_sg,
+	.get_tx_csum = ethtool_op_get_tx_csum,
+	.set_tx_csum = br_set_tx_csum,
+	.get_tso = ethtool_op_get_tso,
+	.set_tso = br_set_tso,
+};
+
 void br_dev_setup(struct net_device *dev)
 {
 	memset(dev->dev_addr, 0, ETH_ALEN);
@@ -96,8 +179,12 @@
 	dev->change_mtu = br_change_mtu;
 	dev->destructor = free_netdev;
 	SET_MODULE_OWNER(dev);
+ 	SET_ETHTOOL_OPS(dev, &br_ethtool_ops);
 	dev->stop = br_dev_stop;
 	dev->tx_queue_len = 0;
-	dev->set_mac_address = NULL;
+	dev->set_mac_address = br_set_mac_address;
 	dev->priv_flags = IFF_EBRIDGE;
+
+ 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST
+ 		| NETIF_F_HIGHDMA | NETIF_F_TSO | NETIF_F_IP_CSUM;
 }
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 975abe2..ba44288 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
+#include <linux/if_ether.h>
 #include <net/sock.h>
 
 #include "br_private.h"
@@ -32,9 +33,8 @@
  * ethtool, use ethtool_ops.  Also, since driver might sleep need to
  * not be holding any locks.
  */
-static int br_initial_port_cost(struct net_device *dev)
+static int port_cost(struct net_device *dev)
 {
-
 	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
 	struct ifreq ifr;
 	mm_segment_t old_fs;
@@ -58,10 +58,6 @@
 			return 2;
 		case SPEED_10:
 			return 100;
-		default:
-			pr_info("bridge: can't decode speed from %s: %d\n",
-				dev->name, ecmd.speed);
-			return 100;
 		}
 	}
 
@@ -75,6 +71,35 @@
 	return 100;	/* assume old 10Mbps */
 }
 
+
+/*
+ * Check for port carrier transistions.
+ * Called from work queue to allow for calling functions that
+ * might sleep (such as speed check), and to debounce.
+ */
+static void port_carrier_check(void *arg)
+{
+	struct net_bridge_port *p = arg;
+
+	rtnl_lock();
+	if (netif_carrier_ok(p->dev)) {
+		u32 cost = port_cost(p->dev);
+
+		spin_lock_bh(&p->br->lock);
+		if (p->state == BR_STATE_DISABLED) {
+			p->path_cost = cost;
+			br_stp_enable_port(p);
+		}
+		spin_unlock_bh(&p->br->lock);
+	} else {
+		spin_lock_bh(&p->br->lock);
+		if (p->state != BR_STATE_DISABLED)
+			br_stp_disable_port(p);
+		spin_unlock_bh(&p->br->lock);
+	}
+	rtnl_unlock();
+}
+
 static void destroy_nbp(struct net_bridge_port *p)
 {
 	struct net_device *dev = p->dev;
@@ -102,6 +127,9 @@
 	dev->br_port = NULL;
 	dev_set_promiscuity(dev, -1);
 
+	cancel_delayed_work(&p->carrier_check);
+	flush_scheduled_work();
+
 	spin_lock_bh(&br->lock);
 	br_stp_disable_port(p);
 	spin_unlock_bh(&br->lock);
@@ -155,6 +183,7 @@
 	br->bridge_id.prio[1] = 0x00;
 	memset(br->bridge_id.addr, 0, ETH_ALEN);
 
+	br->feature_mask = dev->features;
 	br->stp_enabled = 0;
 	br->designated_root = br->bridge_id;
 	br->root_path_cost = 0;
@@ -195,10 +224,9 @@
 	return (index >= BR_MAX_PORTS) ? -EXFULL : index;
 }
 
-/* called with RTNL */
+/* called with RTNL but without bridge lock */
 static struct net_bridge_port *new_nbp(struct net_bridge *br, 
-				       struct net_device *dev,
-				       unsigned long cost)
+				       struct net_device *dev)
 {
 	int index;
 	struct net_bridge_port *p;
@@ -215,12 +243,13 @@
 	p->br = br;
 	dev_hold(dev);
 	p->dev = dev;
-	p->path_cost = cost;
+	p->path_cost = port_cost(dev);
  	p->priority = 0x8000 >> BR_PORT_BITS;
 	dev->br_port = p;
 	p->port_no = index;
 	br_init_port(p);
 	p->state = BR_STATE_DISABLED;
+	INIT_WORK(&p->carrier_check, port_carrier_check, p);
 	kobject_init(&p->kobj);
 
 	return p;
@@ -295,7 +324,7 @@
 	return ret;
 }
 
-/* Mtu of the bridge pseudo-device 1500 or the minimum of the ports */
+/* MTU of the bridge pseudo-device: ETH_DATA_LEN or the minimum of the ports */
 int br_min_mtu(const struct net_bridge *br)
 {
 	const struct net_bridge_port *p;
@@ -304,7 +333,7 @@
 	ASSERT_RTNL();
 
 	if (list_empty(&br->port_list))
-		mtu = 1500;
+		mtu = ETH_DATA_LEN;
 	else {
 		list_for_each_entry(p, &br->port_list, list) {
 			if (!mtu  || p->dev->mtu < mtu)
@@ -322,9 +351,8 @@
 	struct net_bridge_port *p;
 	unsigned long features, checksum;
 
-	features = NETIF_F_SG | NETIF_F_FRAGLIST 
-		| NETIF_F_HIGHDMA | NETIF_F_TSO;
-	checksum = NETIF_F_IP_CSUM;	/* least commmon subset */
+	features = br->feature_mask &~ NETIF_F_IP_CSUM;
+	checksum = br->feature_mask & NETIF_F_IP_CSUM;
 
 	list_for_each_entry(p, &br->port_list, list) {
 		if (!(p->dev->features 
@@ -351,7 +379,7 @@
 	if (dev->br_port != NULL)
 		return -EBUSY;
 
-	if (IS_ERR(p = new_nbp(br, dev, br_initial_port_cost(dev))))
+	if (IS_ERR(p = new_nbp(br, dev)))
 		return PTR_ERR(p);
 
  	if ((err = br_fdb_insert(br, p, dev->dev_addr)))
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index b88220a..e3a73ce 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -53,6 +53,11 @@
 	/* insert into forwarding database after filtering to avoid spoofing */
 	br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
 
+	if (p->state == BR_STATE_LEARNING) {
+		kfree_skb(skb);
+		goto out;
+	}
+
 	if (br->dev->flags & IFF_PROMISC) {
 		struct sk_buff *skb2;
 
@@ -63,7 +68,7 @@
 		}
 	}
 
-	if (dest[0] & 1) {
+	if (is_multicast_ether_addr(dest)) {
 		br_flood_forward(br, skb, !passedup);
 		if (!passedup)
 			br_pass_frame_up(br, skb);
@@ -107,9 +112,6 @@
 	if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
 		goto err;
 
-	if (p->state == BR_STATE_LEARNING)
-		br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
-
 	if (p->br->stp_enabled &&
 	    !memcmp(dest, bridge_ula, 5) &&
 	    !(dest[5] & 0xF0)) {
@@ -118,9 +120,10 @@
 				NULL, br_stp_handle_bpdu);
 			return 1;
 		}
+		goto err;
 	}
 
-	else if (p->state == BR_STATE_FORWARDING) {
+	if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {
 		if (br_should_route_hook) {
 			if (br_should_route_hook(pskb)) 
 				return 0;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index d8e36b7..7cac3fb 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -26,6 +26,7 @@
 #include <linux/ip.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/if_vlan.h>
 #include <linux/netfilter_bridge.h>
@@ -33,8 +34,11 @@
 #include <linux/netfilter_ipv6.h>
 #include <linux/netfilter_arp.h>
 #include <linux/in_route.h>
+
 #include <net/ip.h>
 #include <net/ipv6.h>
+#include <net/route.h>
+
 #include <asm/uaccess.h>
 #include <asm/checksum.h>
 #include "br_private.h"
@@ -295,7 +299,7 @@
 	len -= 2;
 
 	while (len > 0) {
-		int optlen = raw[off+1]+2;
+		int optlen = skb->nh.raw[off+1]+2;
 
 		switch (skb->nh.raw[off]) {
 		case IPV6_TLV_PAD0:
@@ -308,18 +312,15 @@
 		case IPV6_TLV_JUMBO:
 			if (skb->nh.raw[off+1] != 4 || (off&3) != 2)
 				goto bad;
-
 			pkt_len = ntohl(*(u32*)(skb->nh.raw+off+2));
-
+			if (pkt_len <= IPV6_MAXPLEN ||
+			    skb->nh.ipv6h->payload_len)
+				goto bad;
 			if (pkt_len > skb->len - sizeof(struct ipv6hdr))
 				goto bad;
-			if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
-				if (__pskb_trim(skb,
-				    pkt_len + sizeof(struct ipv6hdr)))
-					goto bad;
-				if (skb->ip_summed == CHECKSUM_HW)
-					skb->ip_summed = CHECKSUM_NONE;
-			}
+			if (pskb_trim_rcsum(skb,
+			    pkt_len+sizeof(struct ipv6hdr)))
+				goto bad;
 			break;
 		default:
 			if (optlen > len)
@@ -372,6 +373,7 @@
 	if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb))
 			goto inhdr_error;
 
+ 	nf_bridge_put(skb->nf_bridge);
 	if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
 		return NF_DROP;
 	setup_pre_routing(skb);
@@ -392,8 +394,9 @@
  * target in particular.  Save the original destination IP
  * address to be able to detect DNAT afterwards. */
 static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
-   const struct net_device *in, const struct net_device *out,
-   int (*okfn)(struct sk_buff *))
+				      const struct net_device *in,
+				      const struct net_device *out,
+				      int (*okfn)(struct sk_buff *))
 {
 	struct iphdr *iph;
 	__u32 len;
@@ -410,8 +413,10 @@
 			goto out;
 
 		if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+			u8 *vhdr = skb->data;
 			skb_pull(skb, VLAN_HLEN);
-			(skb)->nh.raw += VLAN_HLEN;
+			skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
+			skb->nh.raw += VLAN_HLEN;
 		}
 		return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
 	}
@@ -427,8 +432,10 @@
 		goto out;
 
 	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+		u8 *vhdr = skb->data;
 		skb_pull(skb, VLAN_HLEN);
-		(skb)->nh.raw += VLAN_HLEN;
+		skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
+		skb->nh.raw += VLAN_HLEN;
 	}
 
 	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
@@ -455,6 +462,7 @@
 			skb->ip_summed = CHECKSUM_NONE;
 	}
 
+ 	nf_bridge_put(skb->nf_bridge);
 	if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
 		return NF_DROP;
 	setup_pre_routing(skb);
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 917311c..a43a9c1 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -52,17 +52,9 @@
 		br_stp_recalculate_bridge_id(br);
 		break;
 
-	case NETDEV_CHANGE:	/* device is up but carrier changed */
-		if (!(br->dev->flags & IFF_UP))
-			break;
-
-		if (netif_carrier_ok(dev)) {
-			if (p->state == BR_STATE_DISABLED)
-				br_stp_enable_port(p);
-		} else {
-			if (p->state != BR_STATE_DISABLED)
-				br_stp_disable_port(p);
-		}
+	case NETDEV_CHANGE:
+		if (br->dev->flags & IFF_UP)
+			schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
 		break;
 
 	case NETDEV_FEAT_CHANGE:
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index bdf95a7..c5bd631 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -27,6 +27,10 @@
 #define BR_PORT_BITS	10
 #define BR_MAX_PORTS	(1<<BR_PORT_BITS)
 
+#define BR_PORT_DEBOUNCE (HZ/10)
+
+#define BR_VERSION	"2.1"
+
 typedef struct bridge_id bridge_id;
 typedef struct mac_addr mac_addr;
 typedef __u16 port_id;
@@ -78,6 +82,7 @@
 	struct timer_list		hold_timer;
 	struct timer_list		message_age_timer;
 	struct kobject			kobj;
+	struct work_struct		carrier_check;
 	struct rcu_head			rcu;
 };
 
@@ -90,6 +95,7 @@
 	spinlock_t			hash_lock;
 	struct hlist_head		hash[BR_HASH_SIZE];
 	struct list_head		age_list;
+	unsigned long			feature_mask;
 
 	/* STP */
 	bridge_id			designated_root;
@@ -201,6 +207,7 @@
 extern void br_stp_enable_port(struct net_bridge_port *p);
 extern void br_stp_disable_port(struct net_bridge_port *p);
 extern void br_stp_recalculate_bridge_id(struct net_bridge *br);
+extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
 extern void br_stp_set_bridge_priority(struct net_bridge *br,
 				       u16 newprio);
 extern void br_stp_set_port_priority(struct net_bridge_port *p,
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index ac09b6a..cc047f7 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -120,8 +120,7 @@
 }
 
 /* called under bridge lock */
-static void br_stp_change_bridge_id(struct net_bridge *br, 
-				    const unsigned char *addr)
+void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
 {
 	unsigned char oldaddr[6];
 	struct net_bridge_port *p;
@@ -158,7 +157,7 @@
 
 	list_for_each_entry(p, &br->port_list, list) {
 		if (addr == br_mac_zero ||
-		    compare_ether_addr(p->dev->dev_addr, addr) < 0)
+		    memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
 			addr = p->dev->dev_addr;
 
 	}
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index f6a19d5..2ebdc23 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -248,7 +248,7 @@
 	if (err)
 		goto out2;
 
-	kobject_hotplug(&p->kobj, KOBJ_ADD);
+	kobject_uevent(&p->kobj, KOBJ_ADD);
 	return 0;
  out2:
 	kobject_del(&p->kobj);
@@ -260,7 +260,7 @@
 {
 	pr_debug("br_sysfs_removeif\n");
 	sysfs_remove_link(&p->br->ifobj, p->dev->name);
-	kobject_hotplug(&p->kobj, KOBJ_REMOVE);
+	kobject_uevent(&p->kobj, KOBJ_REMOVE);
 	kobject_del(&p->kobj);
 }
 
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index c70b3be..b84fc60 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -196,9 +196,13 @@
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 config BRIDGE_EBT_ULOG
-	tristate "ebt: ulog support"
+	tristate "ebt: ulog support (OBSOLETE)"
 	depends on BRIDGE_NF_EBTABLES
 	help
+	  This option enables the old bridge-specific "ebt_ulog" implementation
+	  which has been obsoleted by the new "nfnetlink_log" code (see
+	  CONFIG_NETFILTER_NETLINK_LOG).
+
 	  This option adds the ulog watcher, that you can use in any rule
 	  in any ebtables table. The packet is passed to a userspace
 	  logging daemon using netlink multicast sockets. This differs
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 662975b..9f6e019 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -3,13 +3,16 @@
  *
  *	Authors:
  *	Bart De Schuymer <bdschuym@pandora.be>
+ *	Harald Welte <laforge@netfilter.org>
  *
  *  April, 2002
  *
  */
 
+#include <linux/in.h>
 #include <linux/netfilter_bridge/ebtables.h>
 #include <linux/netfilter_bridge/ebt_log.h>
+#include <linux/netfilter.h>
 #include <linux/module.h>
 #include <linux/ip.h>
 #include <linux/if_arp.h>
@@ -55,27 +58,30 @@
 }
 
 #define myNIPQUAD(a) a[0], a[1], a[2], a[3]
-static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
-   const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+static void
+ebt_log_packet(unsigned int pf, unsigned int hooknum,
+   const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, const struct nf_loginfo *loginfo,
+   const char *prefix)
 {
-	struct ebt_log_info *info = (struct ebt_log_info *)data;
-	char level_string[4] = "< >";
+	unsigned int bitmask;
 
-	level_string[1] = '0' + info->loglevel;
 	spin_lock_bh(&ebt_log_lock);
-	printk(level_string);
-	printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "",
-	   out ? out->name : "");
+	printk("<%c>%s IN=%s OUT=%s MAC source = ", '0' + loginfo->u.log.level,
+	       prefix, in ? in->name : "", out ? out->name : "");
 
-	printk("MAC source = ");
 	print_MAC(eth_hdr(skb)->h_source);
 	printk("MAC dest = ");
 	print_MAC(eth_hdr(skb)->h_dest);
 
 	printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto));
 
-	if ((info->bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
+	if (loginfo->type == NF_LOG_TYPE_LOG)
+		bitmask = loginfo->u.log.logflags;
+	else
+		bitmask = NF_LOG_MASK;
+
+	if ((bitmask & EBT_LOG_IP) && eth_hdr(skb)->h_proto ==
 	   htons(ETH_P_IP)){
 		struct iphdr _iph, *ih;
 
@@ -84,10 +90,9 @@
 			printk(" INCOMPLETE IP header");
 			goto out;
 		}
-		printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,",
-		   NIPQUAD(ih->saddr), NIPQUAD(ih->daddr));
-		printk(" IP tos=0x%02X, IP proto=%d", ih->tos,
-		       ih->protocol);
+		printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u, IP "
+		       "tos=0x%02X, IP proto=%d", NIPQUAD(ih->saddr),
+		       NIPQUAD(ih->daddr), ih->tos, ih->protocol);
 		if (ih->protocol == IPPROTO_TCP ||
 		    ih->protocol == IPPROTO_UDP) {
 			struct tcpudphdr _ports, *pptr;
@@ -104,7 +109,7 @@
 		goto out;
 	}
 
-	if ((info->bitmask & EBT_LOG_ARP) &&
+	if ((bitmask & EBT_LOG_ARP) &&
 	    ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) ||
 	     (eth_hdr(skb)->h_proto == htons(ETH_P_RARP)))) {
 		struct arphdr _arph, *ah;
@@ -144,6 +149,21 @@
 out:
 	printk("\n");
 	spin_unlock_bh(&ebt_log_lock);
+
+}
+
+static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+	struct ebt_log_info *info = (struct ebt_log_info *)data;
+	struct nf_loginfo li;
+
+	li.type = NF_LOG_TYPE_LOG;
+	li.u.log.level = info->loglevel;
+	li.u.log.logflags = info->bitmask;
+
+	nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, info->prefix);
 }
 
 static struct ebt_watcher log =
@@ -154,13 +174,32 @@
 	.me		= THIS_MODULE,
 };
 
+static struct nf_logger ebt_log_logger = {
+	.name 		= "ebt_log",
+	.logfn		= &ebt_log_packet,
+	.me		= THIS_MODULE,
+};
+
 static int __init init(void)
 {
-	return ebt_register_watcher(&log);
+	int ret;
+
+	ret = ebt_register_watcher(&log);
+	if (ret < 0)
+		return ret;
+	if (nf_log_register(PF_BRIDGE, &ebt_log_logger) < 0) {
+		printk(KERN_WARNING "ebt_log: not logging via system console "
+		       "since somebody else already registered for PF_INET\n");
+		/* we cannot make module load fail here, since otherwise 
+		 * ebtables userspace would abort */
+	}
+
+	return 0;
 }
 
 static void __exit fini(void)
 {
+	nf_log_unregister_logger(&ebt_log_logger);
 	ebt_unregister_watcher(&log);
 }
 
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index aae26ae..ce617b3 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -3,6 +3,7 @@
  *
  *	Authors:
  *	Bart De Schuymer <bdschuym@pandora.be>
+ *	Harald Welte <laforge@netfilter.org>
  *
  *  November, 2004
  *
@@ -115,14 +116,13 @@
 	return skb;
 }
 
-static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
+static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
-   const void *data, unsigned int datalen)
+   const struct ebt_ulog_info *uloginfo, const char *prefix)
 {
 	ebt_ulog_packet_msg_t *pm;
 	size_t size, copy_len;
 	struct nlmsghdr *nlh;
-	struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
 	unsigned int group = uloginfo->nlgroup;
 	ebt_ulog_buff_t *ub = &ulog_buffers[group];
 	spinlock_t *lock = &ub->lock;
@@ -216,6 +216,39 @@
 	goto unlock;
 }
 
+/* this function is registered with the netfilter core */
+static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
+   const struct sk_buff *skb, const struct net_device *in,
+   const struct net_device *out, const struct nf_loginfo *li,
+   const char *prefix)
+{
+	struct ebt_ulog_info loginfo;
+
+	if (!li || li->type != NF_LOG_TYPE_ULOG) {
+		loginfo.nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
+		loginfo.cprange = 0;
+		loginfo.qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
+		loginfo.prefix[0] = '\0';
+	} else {
+		loginfo.nlgroup = li->u.ulog.group;
+		loginfo.cprange = li->u.ulog.copy_len;
+		loginfo.qthreshold = li->u.ulog.qthreshold;
+		strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
+	}
+
+	ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
+}
+
+static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+	struct ebt_ulog_info *uloginfo = (struct ebt_ulog_info *)data;
+
+	ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL);
+}
+
+
 static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
    const struct ebt_entry *e, void *data, unsigned int datalen)
 {
@@ -240,6 +273,12 @@
 	.me		= THIS_MODULE,
 };
 
+static struct nf_logger ebt_ulog_logger = {
+	.name		= EBT_ULOG_WATCHER,
+	.logfn		= &ebt_log_packet,
+	.me		= THIS_MODULE,
+};
+
 static int __init init(void)
 {
 	int i, ret = 0;
@@ -265,6 +304,13 @@
 	else if ((ret = ebt_register_watcher(&ulog)))
 		sock_release(ebtulognl->sk_socket);
 
+	if (nf_log_register(PF_BRIDGE, &ebt_ulog_logger) < 0) {
+		printk(KERN_WARNING "ebt_ulog: not logging via ulog "
+		       "since somebody else already registered for PF_BRIDGE\n");
+		/* we cannot make module load fail here, since otherwise
+		 * ebtables userspace would abort */
+	}
+
 	return ret;
 }
 
@@ -273,6 +319,7 @@
 	ebt_ulog_buff_t *ub;
 	int i;
 
+	nf_log_unregister_logger(&ebt_ulog_logger);
 	ebt_unregister_watcher(&ulog);
 	for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
 		ub = &ulog_buffers[i];
diff --git a/net/core/datagram.c b/net/core/datagram.c
index 1bcfef5..f8d322e 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -47,6 +47,7 @@
 #include <linux/rtnetlink.h>
 #include <linux/poll.h>
 #include <linux/highmem.h>
+#include <linux/spinlock.h>
 
 #include <net/protocol.h>
 #include <linux/skbuff.h>
@@ -200,6 +201,41 @@
 }
 
 /**
+ *	skb_kill_datagram - Free a datagram skbuff forcibly
+ *	@sk: socket
+ *	@skb: datagram skbuff
+ *	@flags: MSG_ flags
+ *
+ *	This function frees a datagram skbuff that was received by
+ *	skb_recv_datagram.  The flags argument must match the one
+ *	used for skb_recv_datagram.
+ *
+ *	If the MSG_PEEK flag is set, and the packet is still on the
+ *	receive queue of the socket, it will be taken off the queue
+ *	before it is freed.
+ *
+ *	This function currently only disables BH when acquiring the
+ *	sk_receive_queue lock.  Therefore it must not be used in a
+ *	context where that lock is acquired in an IRQ context.
+ */
+
+void skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
+{
+	if (flags & MSG_PEEK) {
+		spin_lock_bh(&sk->sk_receive_queue.lock);
+		if (skb == skb_peek(&sk->sk_receive_queue)) {
+			__skb_unlink(skb, &sk->sk_receive_queue);
+			atomic_dec(&skb->users);
+		}
+		spin_unlock_bh(&sk->sk_receive_queue.lock);
+	}
+
+	kfree_skb(skb);
+}
+
+EXPORT_SYMBOL(skb_kill_datagram);
+
+/**
  *	skb_copy_datagram_iovec - Copy a datagram to an iovec.
  *	@skb: buffer to copy
  *	@offset: offset in the buffer to start copying from
diff --git a/net/core/dev.c b/net/core/dev.c
index 0b48e29..5081287 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -626,7 +626,7 @@
  *	Network device names need to be valid file names to
  *	to allow sysfs to work
  */
-static int dev_valid_name(const char *name)
+int dev_valid_name(const char *name)
 {
 	return !(*name == '\0' 
 		 || !strcmp(name, ".")
@@ -1113,7 +1113,8 @@
 void netdev_rx_csum_fault(struct net_device *dev)
 {
 	if (net_ratelimit()) {
-		printk(KERN_ERR "%s: hw csum failure.\n", dev->name);
+		printk(KERN_ERR "%s: hw csum failure.\n", 
+			dev ? dev->name : "<unknown>");
 		dump_stack();
 	}
 }
@@ -3269,13 +3270,13 @@
 EXPORT_SYMBOL(__dev_get_by_name);
 EXPORT_SYMBOL(__dev_remove_pack);
 EXPORT_SYMBOL(__skb_linearize);
+EXPORT_SYMBOL(dev_valid_name);
 EXPORT_SYMBOL(dev_add_pack);
 EXPORT_SYMBOL(dev_alloc_name);
 EXPORT_SYMBOL(dev_close);
 EXPORT_SYMBOL(dev_get_by_flags);
 EXPORT_SYMBOL(dev_get_by_index);
 EXPORT_SYMBOL(dev_get_by_name);
-EXPORT_SYMBOL(dev_ioctl);
 EXPORT_SYMBOL(dev_open);
 EXPORT_SYMBOL(dev_queue_xmit);
 EXPORT_SYMBOL(dev_remove_pack);
diff --git a/net/core/filter.c b/net/core/filter.c
index 2841bfc..9eb9d00 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -13,6 +13,7 @@
  * 2 of the License, or (at your option) any later version.
  *
  * Andi Kleen - Fix a few bad bugs and races.
+ * Kris Katterjohn - Added many additional checks in sk_chk_filter()
  */
 
 #include <linux/module.h>
@@ -74,7 +75,7 @@
  * len is the number of filter blocks in the array.
  */
  
-int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
+unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen)
 {
 	struct sock_filter *fentry;	/* We walk down these */
 	void *ptr;
@@ -240,9 +241,9 @@
 			A = X;
 			continue;
 		case BPF_RET|BPF_K:
-			return ((unsigned int)fentry->k);
+			return fentry->k;
 		case BPF_RET|BPF_A:
-			return ((unsigned int)A);
+			return A;
 		case BPF_ST:
 			mem[fentry->k] = A;
 			continue;
@@ -250,7 +251,7 @@
 			mem[fentry->k] = X;
 			continue;
 		default:
-			/* Invalid instruction counts as RET */
+			WARN_ON(1);
 			return 0;
 		}
 
@@ -283,8 +284,8 @@
  *
  * Check the user's filter code. If we let some ugly
  * filter code slip through kaboom! The filter must contain
- * no references or jumps that are out of range, no illegal instructions
- * and no backward jumps. It must end with a RET instruction
+ * no references or jumps that are out of range, no illegal
+ * instructions, and must end with a RET instruction.
  *
  * Returns 0 if the rule set is legal or a negative errno code if not.
  */
@@ -293,45 +294,92 @@
 	struct sock_filter *ftest;
 	int pc;
 
-	if (((unsigned int)flen >= (~0U / sizeof(struct sock_filter))) || flen == 0)
+	if (flen == 0 || flen > BPF_MAXINSNS)
 		return -EINVAL;
 
 	/* check the filter code now */
 	for (pc = 0; pc < flen; pc++) {
 		/* all jumps are forward as they are not signed */
 		ftest = &filter[pc];
-		if (BPF_CLASS(ftest->code) == BPF_JMP) {
-			/* but they mustn't jump off the end */
-			if (BPF_OP(ftest->code) == BPF_JA) {
-				/*
-				 * Note, the large ftest->k might cause loops.
-				 * Compare this with conditional jumps below,
-				 * where offsets are limited. --ANK (981016)
-				 */
-				if (ftest->k >= (unsigned)(flen-pc-1))
-					return -EINVAL;
-			} else {
-				/* for conditionals both must be safe */
- 				if (pc + ftest->jt +1 >= flen ||
-				    pc + ftest->jf +1 >= flen)
-					return -EINVAL;
-			}
-		}
 
-		/* check for division by zero   -Kris Katterjohn 2005-10-30 */
-		if (ftest->code == (BPF_ALU|BPF_DIV|BPF_K) && ftest->k == 0)
-			return -EINVAL;
+		/* Only allow valid instructions */
+		switch (ftest->code) {
+		case BPF_ALU|BPF_ADD|BPF_K:
+		case BPF_ALU|BPF_ADD|BPF_X:
+		case BPF_ALU|BPF_SUB|BPF_K:
+		case BPF_ALU|BPF_SUB|BPF_X:
+		case BPF_ALU|BPF_MUL|BPF_K:
+		case BPF_ALU|BPF_MUL|BPF_X:
+		case BPF_ALU|BPF_DIV|BPF_X:
+		case BPF_ALU|BPF_AND|BPF_K:
+		case BPF_ALU|BPF_AND|BPF_X:
+		case BPF_ALU|BPF_OR|BPF_K:
+		case BPF_ALU|BPF_OR|BPF_X:
+		case BPF_ALU|BPF_LSH|BPF_K:
+		case BPF_ALU|BPF_LSH|BPF_X:
+		case BPF_ALU|BPF_RSH|BPF_K:
+		case BPF_ALU|BPF_RSH|BPF_X:
+		case BPF_ALU|BPF_NEG:
+		case BPF_LD|BPF_W|BPF_ABS:
+		case BPF_LD|BPF_H|BPF_ABS:
+		case BPF_LD|BPF_B|BPF_ABS:
+		case BPF_LD|BPF_W|BPF_LEN:
+		case BPF_LD|BPF_W|BPF_IND:
+		case BPF_LD|BPF_H|BPF_IND:
+		case BPF_LD|BPF_B|BPF_IND:
+		case BPF_LD|BPF_IMM:
+		case BPF_LDX|BPF_W|BPF_LEN:
+		case BPF_LDX|BPF_B|BPF_MSH:
+		case BPF_LDX|BPF_IMM:
+		case BPF_MISC|BPF_TAX:
+		case BPF_MISC|BPF_TXA:
+		case BPF_RET|BPF_K:
+		case BPF_RET|BPF_A:
+			break;
 
-		/* check that memory operations use valid addresses. */
-		if (ftest->k >= BPF_MEMWORDS) {
-			/* but it might not be a memory operation... */
-			switch (ftest->code) {
-			case BPF_ST:	
-			case BPF_STX:	
-			case BPF_LD|BPF_MEM:	
-			case BPF_LDX|BPF_MEM:	
+		/* Some instructions need special checks */
+
+		case BPF_ALU|BPF_DIV|BPF_K:
+			/* check for division by zero */
+			if (ftest->k == 0)
 				return -EINVAL;
-			}
+			break;
+
+		case BPF_LD|BPF_MEM:
+		case BPF_LDX|BPF_MEM:
+		case BPF_ST:
+		case BPF_STX:
+			/* check for invalid memory addresses */
+			if (ftest->k >= BPF_MEMWORDS)
+				return -EINVAL;
+			break;
+
+		case BPF_JMP|BPF_JA:
+			/*
+			 * Note, the large ftest->k might cause loops.
+			 * Compare this with conditional jumps below,
+			 * where offsets are limited. --ANK (981016)
+			 */
+			if (ftest->k >= (unsigned)(flen-pc-1))
+				return -EINVAL;
+			break;
+
+		case BPF_JMP|BPF_JEQ|BPF_K:
+		case BPF_JMP|BPF_JEQ|BPF_X:
+		case BPF_JMP|BPF_JGE|BPF_K:
+		case BPF_JMP|BPF_JGE|BPF_X:
+		case BPF_JMP|BPF_JGT|BPF_K:
+		case BPF_JMP|BPF_JGT|BPF_X:
+		case BPF_JMP|BPF_JSET|BPF_K:
+		case BPF_JMP|BPF_JSET|BPF_X:
+			/* for conditionals both must be safe */
+ 			if (pc + ftest->jt + 1 >= flen ||
+			    pc + ftest->jf + 1 >= flen)
+				return -EINVAL;
+			break;
+
+		default:
+			return -EINVAL;
 		}
 	}
 
@@ -360,7 +408,7 @@
 	int err;
 
 	/* Make sure new filter is there and in the right amounts. */
-        if (fprog->filter == NULL || fprog->len > BPF_MAXINSNS)
+        if (fprog->filter == NULL)
                 return -EINVAL;
 
 	fp = sock_kmalloc(sk, fsize+sizeof(*fp), GFP_KERNEL);
diff --git a/net/core/flow.c b/net/core/flow.c
index 7e95b39..c4f2538 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -23,6 +23,7 @@
 #include <net/flow.h>
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
+#include <linux/security.h>
 
 struct flow_cache_entry {
 	struct flow_cache_entry	*next;
@@ -30,6 +31,7 @@
 	u8			dir;
 	struct flowi		key;
 	u32			genid;
+	u32			sk_sid;
 	void			*object;
 	atomic_t		*object_ref;
 };
@@ -162,7 +164,7 @@
 	return 0;
 }
 
-void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
+void *flow_cache_lookup(struct flowi *key, u32 sk_sid, u16 family, u8 dir,
 			flow_resolve_t resolver)
 {
 	struct flow_cache_entry *fle, **head;
@@ -186,6 +188,7 @@
 	for (fle = *head; fle; fle = fle->next) {
 		if (fle->family == family &&
 		    fle->dir == dir &&
+		    fle->sk_sid == sk_sid &&
 		    flow_key_compare(key, &fle->key) == 0) {
 			if (fle->genid == atomic_read(&flow_cache_genid)) {
 				void *ret = fle->object;
@@ -210,6 +213,7 @@
 			*head = fle;
 			fle->family = family;
 			fle->dir = dir;
+			fle->sk_sid = sk_sid;
 			memcpy(&fle->key, key, sizeof(*key));
 			fle->object = NULL;
 			flow_count(cpu)++;
@@ -221,7 +225,7 @@
 		void *obj;
 		atomic_t *obj_ref;
 
-		resolver(key, family, dir, &obj, &obj_ref);
+		resolver(key, sk_sid, family, dir, &obj, &obj_ref);
 
 		if (fle) {
 			fle->genid = atomic_read(&flow_cache_genid);
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index e2137f3..e1da81d 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -84,16 +84,11 @@
 	return ret;
 }
 
-/* generate a read-only network device class attribute */
-#define NETDEVICE_ATTR(field, format_string)				\
-NETDEVICE_SHOW(field, format_string)					\
-static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)		\
-
-NETDEVICE_ATTR(addr_len, fmt_dec);
-NETDEVICE_ATTR(iflink, fmt_dec);
-NETDEVICE_ATTR(ifindex, fmt_dec);
-NETDEVICE_ATTR(features, fmt_long_hex);
-NETDEVICE_ATTR(type, fmt_dec);
+NETDEVICE_SHOW(addr_len, fmt_dec);
+NETDEVICE_SHOW(iflink, fmt_dec);
+NETDEVICE_SHOW(ifindex, fmt_dec);
+NETDEVICE_SHOW(features, fmt_long_hex);
+NETDEVICE_SHOW(type, fmt_dec);
 
 /* use same locking rules as GIFHWADDR ioctl's */
 static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
@@ -136,10 +131,6 @@
 	return -EINVAL;
 }
 
-static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
-static CLASS_DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL);
-static CLASS_DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL);
-
 /* read-write attributes */
 NETDEVICE_SHOW(mtu, fmt_dec);
 
@@ -153,8 +144,6 @@
 	return netdev_store(dev, buf, len, change_mtu);
 }
 
-static CLASS_DEVICE_ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu);
-
 NETDEVICE_SHOW(flags, fmt_hex);
 
 static int change_flags(struct net_device *net, unsigned long new_flags)
@@ -167,8 +156,6 @@
 	return netdev_store(dev, buf, len, change_flags);
 }
 
-static CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags);
-
 NETDEVICE_SHOW(tx_queue_len, fmt_ulong);
 
 static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
@@ -182,9 +169,6 @@
 	return netdev_store(dev, buf, len, change_tx_queue_len);
 }
 
-static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, 
-			 store_tx_queue_len);
-
 NETDEVICE_SHOW(weight, fmt_dec);
 
 static int change_weight(struct net_device *net, unsigned long new_weight)
@@ -198,24 +182,21 @@
 	return netdev_store(dev, buf, len, change_weight);
 }
 
-static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, 
-			 store_weight);
-
-
-static struct class_device_attribute *net_class_attributes[] = {
-	&class_device_attr_ifindex,
-	&class_device_attr_iflink,
-	&class_device_attr_addr_len,
-	&class_device_attr_tx_queue_len,
-	&class_device_attr_features,
-	&class_device_attr_mtu,
-	&class_device_attr_flags,
-	&class_device_attr_weight,
-	&class_device_attr_type,
-	&class_device_attr_address,
-	&class_device_attr_broadcast,
-	&class_device_attr_carrier,
-	NULL
+static struct class_device_attribute net_class_attributes[] = {
+	__ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
+	__ATTR(iflink, S_IRUGO, show_iflink, NULL),
+	__ATTR(ifindex, S_IRUGO, show_ifindex, NULL),
+	__ATTR(features, S_IRUGO, show_features, NULL),
+	__ATTR(type, S_IRUGO, show_type, NULL),
+	__ATTR(address, S_IRUGO, show_address, NULL),
+	__ATTR(broadcast, S_IRUGO, show_broadcast, NULL),
+	__ATTR(carrier, S_IRUGO, show_carrier, NULL),
+	__ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu),
+	__ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags),
+	__ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
+	       store_tx_queue_len),
+	__ATTR(weight, S_IRUGO | S_IWUSR, show_weight, store_weight),
+	{}
 };
 
 /* Show a given an attribute in the statistics group */
@@ -369,14 +350,14 @@
 #endif
 
 #ifdef CONFIG_HOTPLUG
-static int netdev_hotplug(struct class_device *cd, char **envp,
-			  int num_envp, char *buf, int size)
+static int netdev_uevent(struct class_device *cd, char **envp,
+			 int num_envp, char *buf, int size)
 {
 	struct net_device *dev = to_net_dev(cd);
 	int i = 0;
 	int n;
 
-	/* pass interface in env to hotplug. */
+	/* pass interface to uevent. */
 	envp[i++] = buf;
 	n = snprintf(buf, size, "INTERFACE=%s", dev->name) + 1;
 	buf += n;
@@ -407,8 +388,9 @@
 static struct class net_class = {
 	.name = "net",
 	.release = netdev_release,
+	.class_dev_attrs = net_class_attributes,
 #ifdef CONFIG_HOTPLUG
-	.hotplug = netdev_hotplug,
+	.uevent = netdev_uevent,
 #endif
 };
 
@@ -431,8 +413,6 @@
 int netdev_register_sysfs(struct net_device *net)
 {
 	struct class_device *class_dev = &(net->class_dev);
-	int i;
-	struct class_device_attribute *attr;
 	int ret;
 
 	class_dev->class = &net_class;
@@ -442,12 +422,6 @@
 	if ((ret = class_device_register(class_dev)))
 		goto out;
 
-	for (i = 0; (attr = net_class_attributes[i]) != NULL; i++) {
-		if ((ret = class_device_create_file(class_dev, attr)))
-		    goto out_unreg;
-	}
-
-
 	if (net->get_stats &&
 	    (ret = sysfs_create_group(&class_dev->kobj, &netstat_group)))
 		goto out_unreg; 
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 49424a4..281a632 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -13,6 +13,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/string.h>
+#include <linux/if_arp.h>
 #include <linux/inetdevice.h>
 #include <linux/inet.h>
 #include <linux/interrupt.h>
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 7fc3e9e..631056d 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -473,7 +473,6 @@
 
 static int pktgen_remove_device(struct pktgen_thread* t, struct pktgen_dev *i);
 static int pktgen_add_device(struct pktgen_thread* t, const char* ifname);
-static struct pktgen_thread* pktgen_find_thread(const char* name);
 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread* t, const char* ifname);
 static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
 static void pktgen_run_all_threads(void);
@@ -487,9 +486,9 @@
 
 /* Module parameters, defaults. */
 static int pg_count_d = 1000; /* 1000 pkts by default */
-static int pg_delay_d = 0;
-static int pg_clone_skb_d = 0;
-static int debug = 0;
+static int pg_delay_d;
+static int pg_clone_skb_d;
+static int debug;
 
 static DECLARE_MUTEX(pktgen_sem);
 static struct pktgen_thread *pktgen_threads = NULL;
@@ -2883,7 +2882,7 @@
 	return add_dev_to_thread(t, pkt_dev);
 }
 
-static struct pktgen_thread *pktgen_find_thread(const char* name) 
+static struct pktgen_thread * __init pktgen_find_thread(const char* name) 
 {
         struct pktgen_thread *t = NULL;
 
@@ -2900,7 +2899,7 @@
         return t;
 }
 
-static int pktgen_create_thread(const char* name, int cpu) 
+static int __init pktgen_create_thread(const char* name, int cpu) 
 {
         struct pktgen_thread *t = NULL;
 	struct proc_dir_entry *pe;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index b7d13a4..070f91c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -135,17 +135,13 @@
 struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
 			    int fclone)
 {
+	struct skb_shared_info *shinfo;
 	struct sk_buff *skb;
 	u8 *data;
 
 	/* Get the HEAD */
-	if (fclone)
-		skb = kmem_cache_alloc(skbuff_fclone_cache,
-				       gfp_mask & ~__GFP_DMA);
-	else
-		skb = kmem_cache_alloc(skbuff_head_cache,
-				       gfp_mask & ~__GFP_DMA);
-
+	skb = kmem_cache_alloc(fclone ? skbuff_fclone_cache : skbuff_head_cache,
+				gfp_mask & ~__GFP_DMA);
 	if (!skb)
 		goto out;
 
@@ -162,6 +158,16 @@
 	skb->data = data;
 	skb->tail = data;
 	skb->end  = data + size;
+	/* make sure we initialize shinfo sequentially */
+	shinfo = skb_shinfo(skb);
+	atomic_set(&shinfo->dataref, 1);
+	shinfo->nr_frags  = 0;
+	shinfo->tso_size = 0;
+	shinfo->tso_segs = 0;
+	shinfo->ufo_size = 0;
+	shinfo->ip6_frag_id = 0;
+	shinfo->frag_list = NULL;
+
 	if (fclone) {
 		struct sk_buff *child = skb + 1;
 		atomic_t *fclone_ref = (atomic_t *) (child + 1);
@@ -171,13 +177,6 @@
 
 		child->fclone = SKB_FCLONE_UNAVAILABLE;
 	}
-	atomic_set(&(skb_shinfo(skb)->dataref), 1);
-	skb_shinfo(skb)->nr_frags  = 0;
-	skb_shinfo(skb)->tso_size = 0;
-	skb_shinfo(skb)->tso_segs = 0;
-	skb_shinfo(skb)->frag_list = NULL;
-	skb_shinfo(skb)->ufo_size = 0;
-	skb_shinfo(skb)->ip6_frag_id = 0;
 out:
 	return skb;
 nodata:
@@ -1725,7 +1724,7 @@
  * of the skb if any page alloc fails user this procedure returns  -ENOMEM
  */
 int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
-			int getfrag(void *from, char *to, int offset,
+			int (*getfrag)(void *from, char *to, int offset,
 					int len, int odd, struct sk_buff *skb),
 			void *from, int length)
 {
diff --git a/net/core/sock.c b/net/core/sock.c
index 13cc3be..6465b0e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1488,7 +1488,7 @@
 			}
 		}
 
-		if (prot->twsk_obj_size) {
+		if (prot->twsk_prot != NULL) {
 			static const char mask[] = "tw_sock_%s";
 
 			timewait_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);
@@ -1497,11 +1497,12 @@
 				goto out_free_request_sock_slab;
 
 			sprintf(timewait_sock_slab_name, mask, prot->name);
-			prot->twsk_slab = kmem_cache_create(timewait_sock_slab_name,
-							    prot->twsk_obj_size,
-							    0, SLAB_HWCACHE_ALIGN,
-							    NULL, NULL);
-			if (prot->twsk_slab == NULL)
+			prot->twsk_prot->twsk_slab =
+				kmem_cache_create(timewait_sock_slab_name,
+						  prot->twsk_prot->twsk_obj_size,
+						  0, SLAB_HWCACHE_ALIGN,
+						  NULL, NULL);
+			if (prot->twsk_prot->twsk_slab == NULL)
 				goto out_free_timewait_sock_slab_name;
 		}
 	}
@@ -1548,12 +1549,12 @@
 		prot->rsk_prot->slab = NULL;
 	}
 
-	if (prot->twsk_slab != NULL) {
-		const char *name = kmem_cache_name(prot->twsk_slab);
+	if (prot->twsk_prot != NULL && prot->twsk_prot->twsk_slab != NULL) {
+		const char *name = kmem_cache_name(prot->twsk_prot->twsk_slab);
 
-		kmem_cache_destroy(prot->twsk_slab);
+		kmem_cache_destroy(prot->twsk_prot->twsk_slab);
 		kfree(name);
-		prot->twsk_slab = NULL;
+		prot->twsk_prot->twsk_slab = NULL;
 	}
 }
 
diff --git a/net/core/stream.c b/net/core/stream.c
index 15bfd03..35e2525 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -55,8 +55,9 @@
 	int done;
 
 	do {
-		if (sk->sk_err)
-			return sock_error(sk);
+		int err = sock_error(sk);
+		if (err)
+			return err;
 		if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
 			return -EPIPE;
 		if (!*timeo_p)
@@ -67,6 +68,7 @@
 		prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
 		sk->sk_write_pending++;
 		done = sk_wait_event(sk, timeo_p,
+				     !sk->sk_err &&
 				     !((1 << sk->sk_state) & 
 				       ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)));
 		finish_wait(sk->sk_sleep, &wait);
@@ -137,7 +139,9 @@
 
 		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
 		sk->sk_write_pending++;
-		sk_wait_event(sk, &current_timeo, sk_stream_memory_free(sk) &&
+		sk_wait_event(sk, &current_timeo, !sk->sk_err && 
+						  !(sk->sk_shutdown & SEND_SHUTDOWN) &&
+						  sk_stream_memory_free(sk) &&
 						  vm_wait);
 		sk->sk_write_pending--;
 
diff --git a/net/core/utils.c b/net/core/utils.c
index 7b5970f..ac1d1fc 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -162,7 +162,7 @@
  * is otherwise not dependent on the TCP/IP stack.
  */
 
-__u32 in_aton(const char *str)
+__be32 in_aton(const char *str)
 {
 	unsigned long l;
 	unsigned int val;
@@ -175,7 +175,7 @@
 		if (*str != '\0')
 		{
 			val = 0;
-			while (*str != '\0' && *str != '.')
+			while (*str != '\0' && *str != '.' && *str != '\n')
 			{
 				val *= 10;
 				val += *str - '0';
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index 344a8da..87b27ff 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -1,3 +1,7 @@
+obj-$(CONFIG_IPV6) += dccp_ipv6.o
+
+dccp_ipv6-y := ipv6.o
+
 obj-$(CONFIG_IP_DCCP) += dccp.o
 
 dccp-y := ccid.o input.o ipv4.o minisocks.o options.o output.o proto.o \
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
index c9a62cc..ce9cb77 100644
--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -55,8 +55,8 @@
 	from = av->dccpav_buf + av->dccpav_buf_head;
 
 	/* Check if buf_head wraps */
-	if (av->dccpav_buf_head + len > av->dccpav_vec_len) {
-		const u32 tailsize = (av->dccpav_vec_len - av->dccpav_buf_head);
+	if ((int)av->dccpav_buf_head + len > av->dccpav_vec_len) {
+		const u32 tailsize = av->dccpav_vec_len - av->dccpav_buf_head;
 
 		memcpy(to, from, tailsize);
 		to   += tailsize;
@@ -93,8 +93,14 @@
 struct dccp_ackvec *dccp_ackvec_alloc(const unsigned int len,
 				      const gfp_t priority)
 {
-	struct dccp_ackvec *av = kmalloc(sizeof(*av) + len, priority);
+	struct dccp_ackvec *av;
 
+	BUG_ON(len == 0);
+
+	if (len > DCCP_MAX_ACKVEC_LEN)
+		return NULL;
+
+	av = kmalloc(sizeof(*av) + len, priority);
 	if (av != NULL) {
 		av->dccpav_buf_len	= len;
 		av->dccpav_buf_head	=
@@ -117,13 +123,13 @@
 }
 
 static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av,
-				   const unsigned int index)
+				   const u8 index)
 {
 	return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK;
 }
 
 static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av,
-				 const unsigned int index)
+				 const u8 index)
 {
 	return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK;
 }
@@ -135,7 +141,7 @@
  */
 static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
 						 const unsigned int packets,
-						  const unsigned char state)
+						 const unsigned char state)
 {
 	unsigned int gap;
 	signed long new_head;
@@ -223,7 +229,7 @@
 		 *	could reduce the complexity of this scan.)
 		 */
 		u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno);
-		unsigned int index = av->dccpav_buf_head;
+		u8 index = av->dccpav_buf_head;
 
 		while (1) {
 			const u8 len = dccp_ackvec_len(av, index);
@@ -291,7 +297,7 @@
 }
 #endif
 
-static void dccp_ackvec_trow_away_ack_record(struct dccp_ackvec *av)
+static void dccp_ackvec_throw_away_ack_record(struct dccp_ackvec *av)
 {
 	/*
 	 * As we're keeping track of the ack vector size (dccpav_vec_len) and
@@ -301,9 +307,10 @@
 	 * draft-ietf-dccp-spec-11.txt Appendix A. -acme
 	 */
 #if 0
-	av->dccpav_buf_tail = av->dccpav_ack_ptr + 1;
-	if (av->dccpav_buf_tail >= av->dccpav_vec_len)
-		av->dccpav_buf_tail -= av->dccpav_vec_len;
+	u32 new_buf_tail = av->dccpav_ack_ptr + 1;
+	if (new_buf_tail >= av->dccpav_vec_len)
+		new_buf_tail -= av->dccpav_vec_len;
+	av->dccpav_buf_tail = new_buf_tail;
 #endif
 	av->dccpav_vec_len -= av->dccpav_sent_len;
 }
@@ -326,7 +333,7 @@
 			      debug_prefix, 1,
 			      (unsigned long long)av->dccpav_ack_seqno,
 			      (unsigned long long)av->dccpav_ack_ackno);
-		dccp_ackvec_trow_away_ack_record(av);
+		dccp_ackvec_throw_away_ack_record(av);
 		av->dccpav_ack_seqno = DCCP_MAX_SEQNO + 1;
 	}
 }
@@ -389,7 +396,7 @@
 					      av->dccpav_ack_seqno,
 					      (unsigned long long)
 					      av->dccpav_ack_ackno);
-				dccp_ackvec_trow_away_ack_record(av);
+				dccp_ackvec_throw_away_ack_record(av);
 			}
 			/*
 			 * If dccpav_ack_seqno was not received, no problem
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
index d0fd6c6..f7dfb5f 100644
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -54,16 +54,16 @@
  * @dccpav_buf - circular buffer of acknowledgeable packets
  */
 struct dccp_ackvec {
-	unsigned int	dccpav_buf_head;
-	unsigned int	dccpav_buf_tail;
 	u64		dccpav_buf_ackno;
 	u64		dccpav_ack_seqno;
 	u64		dccpav_ack_ackno;
-	unsigned int	dccpav_ack_ptr;
-	unsigned int	dccpav_sent_len;
-	unsigned int	dccpav_vec_len;
-	unsigned int	dccpav_buf_len;
 	struct timeval	dccpav_time;
+	u8		dccpav_buf_head;
+	u8		dccpav_buf_tail;
+	u8		dccpav_ack_ptr;
+	u8		dccpav_sent_len;
+	u8		dccpav_vec_len;
+	u8		dccpav_buf_len;
 	u8		dccpav_buf_nonce;
 	u8		dccpav_ack_nonce;
 	u8		dccpav_buf[0];
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index c37eeea..de681c6 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -21,6 +21,8 @@
 
 #define CCID_MAX 255
 
+struct tcp_info;
+
 struct ccid {
 	unsigned char	ccid_id;
 	const char	*ccid_name;
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index f97b85d..93f26dd 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -59,7 +59,7 @@
 
 #define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */
 
-extern struct proto dccp_v4_prot;
+extern struct proto dccp_prot;
 
 /* is seq1 < seq2 ? */
 static inline int before48(const u64 seq1, const u64 seq2)
@@ -228,6 +228,9 @@
 extern int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
 				const struct dccp_hdr *dh, const unsigned len);
 
+extern int dccp_v4_init_sock(struct sock *sk);
+extern int dccp_v4_destroy_sock(struct sock *sk);
+
 extern void		dccp_close(struct sock *sk, long timeout);
 extern struct sk_buff	*dccp_make_response(struct sock *sk,
 					    struct dst_entry *dst,
@@ -238,6 +241,7 @@
 
 extern int	   dccp_connect(struct sock *sk);
 extern int	   dccp_disconnect(struct sock *sk, int flags);
+extern void	   dccp_unhash(struct sock *sk);
 extern int	   dccp_getsockopt(struct sock *sk, int level, int optname,
 				   char __user *optval, int __user *optlen);
 extern int	   dccp_setsockopt(struct sock *sk, int level, int optname,
@@ -249,6 +253,13 @@
 				struct msghdr *msg, size_t len, int nonblock,
 				int flags, int *addr_len);
 extern void	   dccp_shutdown(struct sock *sk, int how);
+extern int	   inet_dccp_listen(struct socket *sock, int backlog);
+extern unsigned int dccp_poll(struct file *file, struct socket *sock,
+			     poll_table *wait);
+extern void	   dccp_v4_send_check(struct sock *sk, int len,
+				      struct sk_buff *skb);
+extern int	   dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
+				   int addr_len);
 
 extern int	   dccp_v4_checksum(const struct sk_buff *skb,
 				    const u32 saddr, const u32 daddr);
@@ -256,6 +267,17 @@
 extern int	   dccp_v4_send_reset(struct sock *sk,
 				      enum dccp_reset_codes code);
 extern void	   dccp_send_close(struct sock *sk, const int active);
+extern int	   dccp_invalid_packet(struct sk_buff *skb);
+
+static inline int dccp_bad_service_code(const struct sock *sk,
+					const __u32 service)
+{
+	const struct dccp_sock *dp = dccp_sk(sk);
+
+	if (dp->dccps_service == service)
+		return 0;
+	return !dccp_list_has_service(dp->dccps_service_list, service);
+}
 
 struct dccp_skb_cb {
 	__u8  dccpd_type:4;
diff --git a/net/dccp/diag.c b/net/dccp/diag.c
index f675d8e6..3f78c00 100644
--- a/net/dccp/diag.c
+++ b/net/dccp/diag.c
@@ -28,7 +28,7 @@
 	info->tcpi_retransmits	= icsk->icsk_retransmits;
 	info->tcpi_probes	= icsk->icsk_probes_out;
 	info->tcpi_backoff	= icsk->icsk_backoff;
-	info->tcpi_pmtu		= dp->dccps_pmtu_cookie;
+	info->tcpi_pmtu		= icsk->icsk_pmtu_cookie;
 
 	if (dp->dccps_options.dccpo_send_ack_vector)
 		info->tcpi_options |= TCPI_OPT_SACK;
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 3454d59..b6cba72 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -151,29 +151,12 @@
 	return 0;
 }
 
-int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
-			 const struct dccp_hdr *dh, const unsigned len)
+static inline int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
+					 const struct dccp_hdr *dh,
+					 const unsigned len)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 
-	if (dccp_check_seqno(sk, skb))
-		goto discard;
-
-	if (dccp_parse_options(sk, skb))
-		goto discard;
-
-	if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
-		dccp_event_ack_recv(sk, skb);
-
-	if (dp->dccps_options.dccpo_send_ack_vector &&
-	    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
-			    DCCP_SKB_CB(skb)->dccpd_seq,
-			    DCCP_ACKVEC_STATE_RECEIVED))
-		goto discard;
-
-	ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
-	ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-
 	switch (dccp_hdr(skb)->dccph_type) {
 	case DCCP_PKT_DATAACK:
 	case DCCP_PKT_DATA:
@@ -250,6 +233,37 @@
 	return 0;
 }
 
+int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
+			 const struct dccp_hdr *dh, const unsigned len)
+{
+	struct dccp_sock *dp = dccp_sk(sk);
+
+	if (dccp_check_seqno(sk, skb))
+		goto discard;
+
+	if (dccp_parse_options(sk, skb))
+		goto discard;
+
+	if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+		dccp_event_ack_recv(sk, skb);
+
+	if (dp->dccps_options.dccpo_send_ack_vector &&
+	    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+			    DCCP_SKB_CB(skb)->dccpd_seq,
+			    DCCP_ACKVEC_STATE_RECEIVED))
+		goto discard;
+
+	ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+	ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
+
+	return __dccp_rcv_established(sk, skb, dh, len);
+discard:
+	__kfree_skb(skb);
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(dccp_rcv_established);
+
 static int dccp_rcv_request_sent_state_process(struct sock *sk,
 					       struct sk_buff *skb,
 					       const struct dccp_hdr *dh,
@@ -286,6 +300,12 @@
 			goto out_invalid_packet;
 		}
 
+                if (dp->dccps_options.dccpo_send_ack_vector &&
+                    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
+                                    DCCP_SKB_CB(skb)->dccpd_seq,
+                                    DCCP_ACKVEC_STATE_RECEIVED))
+                        goto out_invalid_packet; /* FIXME: change error code */
+
 		dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
 		dccp_update_gsr(sk, dp->dccps_isr);
 		/*
@@ -309,7 +329,7 @@
 			goto out_invalid_packet;
 		}
 
-		dccp_sync_mss(sk, dp->dccps_pmtu_cookie);
+		dccp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 
 		/*
 		 *    Step 10: Process REQUEST state (second part)
@@ -329,7 +349,7 @@
 		dccp_set_state(sk, DCCP_PARTOPEN);
 
 		/* Make sure socket is routed, for correct metrics. */
-		inet_sk_rebuild_header(sk);
+		icsk->icsk_af_ops->rebuild_header(sk);
 
 		if (!sock_flag(sk, SOCK_DEAD)) {
 			sk->sk_state_change(sk);
@@ -398,9 +418,9 @@
 
 		if (dh->dccph_type == DCCP_PKT_DATAACK ||
 		    dh->dccph_type == DCCP_PKT_DATA) {
-			dccp_rcv_established(sk, skb, dh, len);
+			__dccp_rcv_established(sk, skb, dh, len);
 			queued = 1; /* packet was queued
-				       (by dccp_rcv_established) */
+				       (by __dccp_rcv_established) */
 		}
 		break;
 	}
@@ -444,7 +464,8 @@
 	 */
 	if (sk->sk_state == DCCP_LISTEN) {
 		if (dh->dccph_type == DCCP_PKT_REQUEST) {
-			if (dccp_v4_conn_request(sk, skb) < 0)
+			if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
+								    skb) < 0)
 				return 1;
 
 			/* FIXME: do congestion control initialization */
@@ -471,14 +492,14 @@
 		if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
 			dccp_event_ack_recv(sk, skb);
 
-		ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
-		ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
-
  		if (dp->dccps_options.dccpo_send_ack_vector &&
 		    dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
  				    DCCP_SKB_CB(skb)->dccpd_seq,
  				    DCCP_ACKVEC_STATE_RECEIVED))
  			goto discard;
+
+		ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
+		ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
 	}
 
 	/*
@@ -566,3 +587,5 @@
 	}
 	return 0;
 }
+
+EXPORT_SYMBOL_GPL(dccp_rcv_state_process);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index ca03521..00f9832 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -19,7 +19,9 @@
 
 #include <net/icmp.h>
 #include <net/inet_hashtables.h>
+#include <net/inet_sock.h>
 #include <net/sock.h>
+#include <net/timewait_sock.h>
 #include <net/tcp_states.h>
 #include <net/xfrm.h>
 
@@ -37,7 +39,8 @@
 
 static int dccp_v4_get_port(struct sock *sk, const unsigned short snum)
 {
-	return inet_csk_get_port(&dccp_hashinfo, sk, snum);
+	return inet_csk_get_port(&dccp_hashinfo, sk, snum,
+				 inet_csk_bind_conflict);
 }
 
 static void dccp_v4_hash(struct sock *sk)
@@ -45,171 +48,14 @@
 	inet_hash(&dccp_hashinfo, sk);
 }
 
-static void dccp_v4_unhash(struct sock *sk)
+void dccp_unhash(struct sock *sk)
 {
 	inet_unhash(&dccp_hashinfo, sk);
 }
 
-/* called with local bh disabled */
-static int __dccp_v4_check_established(struct sock *sk, const __u16 lport,
-				      struct inet_timewait_sock **twp)
-{
-	struct inet_sock *inet = inet_sk(sk);
-	const u32 daddr = inet->rcv_saddr;
-	const u32 saddr = inet->daddr;
-	const int dif = sk->sk_bound_dev_if;
-	INET_ADDR_COOKIE(acookie, saddr, daddr)
-	const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
-	unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
-	struct inet_ehash_bucket *head = inet_ehash_bucket(&dccp_hashinfo, hash);
-	const struct sock *sk2;
-	const struct hlist_node *node;
-	struct inet_timewait_sock *tw;
+EXPORT_SYMBOL_GPL(dccp_unhash);
 
-	prefetch(head->chain.first);
-	write_lock(&head->lock);
-
-	/* Check TIME-WAIT sockets first. */
-	sk_for_each(sk2, node, &(head + dccp_hashinfo.ehash_size)->chain) {
-		tw = inet_twsk(sk2);
-
-		if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
-			goto not_unique;
-	}
-	tw = NULL;
-
-	/* And established part... */
-	sk_for_each(sk2, node, &head->chain) {
-		if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
-			goto not_unique;
-	}
-
-	/* Must record num and sport now. Otherwise we will see
-	 * in hash table socket with a funny identity. */
-	inet->num = lport;
-	inet->sport = htons(lport);
-	sk->sk_hash = hash;
-	BUG_TRAP(sk_unhashed(sk));
-	__sk_add_node(sk, &head->chain);
-	sock_prot_inc_use(sk->sk_prot);
-	write_unlock(&head->lock);
-
-	if (twp != NULL) {
-		*twp = tw;
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-	} else if (tw != NULL) {
-		/* Silly. Should hash-dance instead... */
-		inet_twsk_deschedule(tw, &dccp_death_row);
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-
-		inet_twsk_put(tw);
-	}
-
-	return 0;
-
-not_unique:
-	write_unlock(&head->lock);
-	return -EADDRNOTAVAIL;
-}
-
-/*
- * Bind a port for a connect operation and hash it.
- */
-static int dccp_v4_hash_connect(struct sock *sk)
-{
-	const unsigned short snum = inet_sk(sk)->num;
- 	struct inet_bind_hashbucket *head;
- 	struct inet_bind_bucket *tb;
-	int ret;
-
- 	if (snum == 0) {
- 		int low = sysctl_local_port_range[0];
- 		int high = sysctl_local_port_range[1];
- 		int remaining = (high - low) + 1;
- 		int rover = net_random() % (high - low) + low;
-		struct hlist_node *node;
- 		struct inet_timewait_sock *tw = NULL;
-
- 		local_bh_disable();
- 		do {
- 			head = &dccp_hashinfo.bhash[inet_bhashfn(rover,
-						    dccp_hashinfo.bhash_size)];
- 			spin_lock(&head->lock);
-
- 			/* Does not bother with rcv_saddr checks,
- 			 * because the established check is already
- 			 * unique enough.
- 			 */
-			inet_bind_bucket_for_each(tb, node, &head->chain) {
- 				if (tb->port == rover) {
- 					BUG_TRAP(!hlist_empty(&tb->owners));
- 					if (tb->fastreuse >= 0)
- 						goto next_port;
- 					if (!__dccp_v4_check_established(sk,
-									 rover,
-									 &tw))
- 						goto ok;
- 					goto next_port;
- 				}
- 			}
-
- 			tb = inet_bind_bucket_create(dccp_hashinfo.bind_bucket_cachep,
-						     head, rover);
- 			if (tb == NULL) {
- 				spin_unlock(&head->lock);
- 				break;
- 			}
- 			tb->fastreuse = -1;
- 			goto ok;
-
- 		next_port:
- 			spin_unlock(&head->lock);
- 			if (++rover > high)
- 				rover = low;
- 		} while (--remaining > 0);
-
- 		local_bh_enable();
-
- 		return -EADDRNOTAVAIL;
-
-ok:
- 		/* All locks still held and bhs disabled */
- 		inet_bind_hash(sk, tb, rover);
-		if (sk_unhashed(sk)) {
- 			inet_sk(sk)->sport = htons(rover);
- 			__inet_hash(&dccp_hashinfo, sk, 0);
- 		}
- 		spin_unlock(&head->lock);
-
- 		if (tw != NULL) {
- 			inet_twsk_deschedule(tw, &dccp_death_row);
- 			inet_twsk_put(tw);
- 		}
-
-		ret = 0;
-		goto out;
- 	}
-
- 	head = &dccp_hashinfo.bhash[inet_bhashfn(snum,
-						 dccp_hashinfo.bhash_size)];
- 	tb   = inet_csk(sk)->icsk_bind_hash;
-	spin_lock_bh(&head->lock);
-	if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {
-		__inet_hash(&dccp_hashinfo, sk, 0);
-		spin_unlock_bh(&head->lock);
-		return 0;
-	} else {
-		spin_unlock(&head->lock);
-		/* No definite answer... Walk to established hash table */
-		ret = __dccp_v4_check_established(sk, snum, NULL);
-out:
-		local_bh_enable();
-		return ret;
-	}
-}
-
-static int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
-			   int addr_len)
+int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 {
 	struct inet_sock *inet = inet_sk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
@@ -259,9 +105,9 @@
 	inet->dport = usin->sin_port;
 	inet->daddr = daddr;
 
-	dp->dccps_ext_header_len = 0;
+	inet_csk(sk)->icsk_ext_hdr_len = 0;
 	if (inet->opt != NULL)
-		dp->dccps_ext_header_len = inet->opt->optlen;
+		inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
 	/*
 	 * Socket identity is still unknown (sport may be zero).
 	 * However we set state to DCCP_REQUESTING and not releasing socket
@@ -269,7 +115,7 @@
 	 * complete initialization after this.
 	 */
 	dccp_set_state(sk, DCCP_REQUESTING);
-	err = dccp_v4_hash_connect(sk);
+	err = inet_hash_connect(&dccp_death_row, sk);
 	if (err != 0)
 		goto failure;
 
@@ -287,16 +133,6 @@
 							    usin->sin_port);
 	dccp_update_gss(sk, dp->dccps_iss);
 
-	/*
-	 * SWL and AWL are initially adjusted so that they are not less than
-	 * the initial Sequence Numbers received and sent, respectively:
-	 *	SWL := max(GSR + 1 - floor(W/4), ISR),
-	 *	AWL := max(GSS - W' + 1, ISS).
-	 * These adjustments MUST be applied only at the beginning of the
-	 * connection.
-	 */
-	dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
-
 	inet->id = dp->dccps_iss ^ jiffies;
 
 	err = dccp_connect(sk);
@@ -316,6 +152,8 @@
 	goto out;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_connect);
+
 /*
  * This routine does path mtu discovery as defined in RFC1191.
  */
@@ -354,7 +192,7 @@
 	mtu = dst_mtu(dst);
 
 	if (inet->pmtudisc != IP_PMTUDISC_DONT &&
-	    dp->dccps_pmtu_cookie > mtu) {
+	    inet_csk(sk)->icsk_pmtu_cookie > mtu) {
 		dccp_sync_mss(sk, mtu);
 
 		/*
@@ -606,6 +444,17 @@
 	sock_put(sk);
 }
 
+/* This routine computes an IPv4 DCCP checksum. */
+void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
+{
+	const struct inet_sock *inet = inet_sk(sk);
+	struct dccp_hdr *dh = dccp_hdr(skb);
+
+	dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr);
+}
+
+EXPORT_SYMBOL_GPL(dccp_v4_send_check);
+
 int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code)
 {
 	struct sk_buff *skb;
@@ -641,16 +490,6 @@
 					   dccp_hdr(skb)->dccph_sport);
 }
 
-static inline int dccp_bad_service_code(const struct sock *sk,
-					const __u32 service)
-{
-	const struct dccp_sock *dp = dccp_sk(sk);
-
-	if (dp->dccps_service == service)
-		return 0;
-	return !dccp_list_has_service(dp->dccps_service_list, service);
-}
-
 int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
 	struct inet_request_sock *ireq;
@@ -662,7 +501,6 @@
  	const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
 	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
 	__u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
-	struct dst_entry *dst = NULL;
 
 	/* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
 	if (((struct rtable *)skb->dst)->rt_flags &
@@ -703,7 +541,6 @@
 	ireq = inet_rsk(req);
 	ireq->loc_addr = daddr;
 	ireq->rmt_addr = saddr;
-	/* FIXME: Merge Aristeu's option parsing code when ready */
 	req->rcv_wnd	= 100; /* Fake, option parsing will get the
 				  right value */
 	ireq->opt	= NULL;
@@ -721,23 +558,22 @@
 	dreq->dreq_iss	   = dccp_v4_init_sequence(sk, skb);
 	dreq->dreq_service = service;
 
-	if (dccp_v4_send_response(sk, req, dst))
+	if (dccp_v4_send_response(sk, req, NULL))
 		goto drop_and_free;
 
 	inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
 	return 0;
 
 drop_and_free:
-	/*
-	 * FIXME: should be reqsk_free after implementing req->rsk_ops
-	 */
-	__reqsk_free(req);
+	reqsk_free(req);
 drop:
 	DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
 	dcb->dccpd_reset_code = reset_code;
 	return -1;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_conn_request);
+
 /*
  * The three way handshake has completed - we got a valid ACK or DATAACK -
  * now create the new socket.
@@ -792,6 +628,8 @@
 	return NULL;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_request_recv_sock);
+
 static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
 {
 	const struct dccp_hdr *dh = dccp_hdr(skb);
@@ -1011,7 +849,9 @@
 	return 0;
 }
 
-static inline int dccp_invalid_packet(struct sk_buff *skb)
+EXPORT_SYMBOL_GPL(dccp_v4_do_rcv);
+
+int dccp_invalid_packet(struct sk_buff *skb)
 {
 	const struct dccp_hdr *dh;
 
@@ -1065,29 +905,30 @@
 		return 1;
 	}
 
-	/* If the header checksum is incorrect, drop packet and return */
-	if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
-				    skb->nh.iph->daddr) < 0) {
-		LIMIT_NETDEBUG(KERN_WARNING "DCCP: header checksum is "
-					    "incorrect\n");
-		return 1;
-	}
-
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_invalid_packet);
+
 /* this is called when real data arrives */
 int dccp_v4_rcv(struct sk_buff *skb)
 {
 	const struct dccp_hdr *dh;
 	struct sock *sk;
-	int rc;
 
 	/* Step 1: Check header basics: */
 
 	if (dccp_invalid_packet(skb))
 		goto discard_it;
 
+	/* If the header checksum is incorrect, drop packet and return */
+	if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr,
+				    skb->nh.iph->daddr) < 0) {
+		LIMIT_NETDEBUG(KERN_WARNING "%s: incorrect header checksum\n",
+			       __FUNCTION__);
+		goto discard_it;
+	}
+
 	dh = dccp_hdr(skb);
 
 	DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(skb);
@@ -1143,28 +984,11 @@
                 goto do_time_wait;
 	}
 
-	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) {
-		dccp_pr_debug("xfrm4_policy_check failed\n");
+	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_and_relse;
-	}
+	nf_reset(skb);
 
-        if (sk_filter(sk, skb, 0)) {
-		dccp_pr_debug("sk_filter failed\n");
-                goto discard_and_relse;
-	}
-
-	skb->dev = NULL;
-
-	bh_lock_sock(sk);
-	rc = 0;
-	if (!sock_owned_by_user(sk))
-		rc = dccp_v4_do_rcv(sk, skb);
-	else
-		sk_add_backlog(sk, skb);
-	bh_unlock_sock(sk);
-
-	sock_put(sk);
-	return rc;
+	return sk_receive_skb(sk, skb);
 
 no_dccp_socket:
 	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
@@ -1194,9 +1018,23 @@
 	goto no_dccp_socket;
 }
 
-static int dccp_v4_init_sock(struct sock *sk)
+struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
+	.queue_xmit	= ip_queue_xmit,
+	.send_check	= dccp_v4_send_check,
+	.rebuild_header	= inet_sk_rebuild_header,
+	.conn_request	= dccp_v4_conn_request,
+	.syn_recv_sock	= dccp_v4_request_recv_sock,
+	.net_header_len	= sizeof(struct iphdr),
+	.setsockopt	= ip_setsockopt,
+	.getsockopt	= ip_getsockopt,
+	.addr2sockaddr	= inet_csk_addr2sockaddr,
+	.sockaddr_len	= sizeof(struct sockaddr_in),
+};
+
+int dccp_v4_init_sock(struct sock *sk)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	static int dccp_ctl_socket_init = 1;
 
 	dccp_options_init(&dp->dccps_options);
@@ -1236,9 +1074,11 @@
 		dccp_ctl_socket_init = 0;
 
 	dccp_init_xmit_timers(sk);
-	inet_csk(sk)->icsk_rto = DCCP_TIMEOUT_INIT;
+	icsk->icsk_rto = DCCP_TIMEOUT_INIT;
 	sk->sk_state = DCCP_CLOSED;
 	sk->sk_write_space = dccp_write_space;
+	icsk->icsk_af_ops = &dccp_ipv4_af_ops;
+	icsk->icsk_sync_mss = dccp_sync_mss;
 	dp->dccps_mss_cache = 536;
 	dp->dccps_role = DCCP_ROLE_UNDEFINED;
 	dp->dccps_service = DCCP_SERVICE_INVALID_VALUE;
@@ -1246,12 +1086,14 @@
 	return 0;
 }
 
-static int dccp_v4_destroy_sock(struct sock *sk)
+EXPORT_SYMBOL_GPL(dccp_v4_init_sock);
+
+int dccp_v4_destroy_sock(struct sock *sk)
 {
 	struct dccp_sock *dp = dccp_sk(sk);
 
 	/*
-	 * DCCP doesn't use sk_qrite_queue, just sk_send_head
+	 * DCCP doesn't use sk_write_queue, just sk_send_head
 	 * for retransmissions
 	 */
 	if (sk->sk_send_head != NULL) {
@@ -1279,6 +1121,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_v4_destroy_sock);
+
 static void dccp_v4_reqsk_destructor(struct request_sock *req)
 {
 	kfree(inet_rsk(req)->opt);
@@ -1293,7 +1137,11 @@
 	.send_reset	= dccp_v4_ctl_send_reset,
 };
 
-struct proto dccp_v4_prot = {
+static struct timewait_sock_ops dccp_timewait_sock_ops = {
+	.twsk_obj_size	= sizeof(struct inet_timewait_sock),
+};
+
+struct proto dccp_prot = {
 	.name			= "DCCP",
 	.owner			= THIS_MODULE,
 	.close			= dccp_close,
@@ -1307,7 +1155,7 @@
 	.recvmsg		= dccp_recvmsg,
 	.backlog_rcv		= dccp_v4_do_rcv,
 	.hash			= dccp_v4_hash,
-	.unhash			= dccp_v4_unhash,
+	.unhash			= dccp_unhash,
 	.accept			= inet_csk_accept,
 	.get_port		= dccp_v4_get_port,
 	.shutdown		= dccp_shutdown,
@@ -1316,5 +1164,7 @@
 	.max_header		= MAX_DCCP_HEADER,
 	.obj_size		= sizeof(struct dccp_sock),
 	.rsk_prot		= &dccp_request_sock_ops,
-	.twsk_obj_size		= sizeof(struct inet_timewait_sock),
+	.twsk_prot		= &dccp_timewait_sock_ops,
 };
+
+EXPORT_SYMBOL_GPL(dccp_prot);
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
new file mode 100644
index 0000000..df07425
--- /dev/null
+++ b/net/dccp/ipv6.c
@@ -0,0 +1,1262 @@
+/*
+ *	DCCP over IPv6
+ *	Linux INET6 implementation 
+ *
+ *	Based on net/dccp6/ipv6.c
+ *
+ *	Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/xfrm.h>
+
+#include <net/addrconf.h>
+#include <net/inet_common.h>
+#include <net/inet_hashtables.h>
+#include <net/inet_sock.h>
+#include <net/inet6_connection_sock.h>
+#include <net/inet6_hashtables.h>
+#include <net/ip6_route.h>
+#include <net/ipv6.h>
+#include <net/protocol.h>
+#include <net/transp_v6.h>
+#include <net/ip6_checksum.h>
+#include <net/xfrm.h>
+
+#include "dccp.h"
+#include "ipv6.h"
+
+static void dccp_v6_ctl_send_reset(struct sk_buff *skb);
+static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
+				   struct request_sock *req);
+static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb);
+
+static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
+
+static struct inet_connection_sock_af_ops dccp_ipv6_mapped;
+static struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
+
+static int dccp_v6_get_port(struct sock *sk, unsigned short snum)
+{
+	return inet_csk_get_port(&dccp_hashinfo, sk, snum,
+				 inet6_csk_bind_conflict);
+}
+
+static void dccp_v6_hash(struct sock *sk)
+{
+	if (sk->sk_state != DCCP_CLOSED) {
+		if (inet_csk(sk)->icsk_af_ops == &dccp_ipv6_mapped) {
+			dccp_prot.hash(sk);
+			return;
+		}
+		local_bh_disable();
+		__inet6_hash(&dccp_hashinfo, sk);
+		local_bh_enable();
+	}
+}
+
+static inline u16 dccp_v6_check(struct dccp_hdr *dh, int len,
+				struct in6_addr *saddr, 
+				struct in6_addr *daddr, 
+				unsigned long base)
+{
+	return csum_ipv6_magic(saddr, daddr, len, IPPROTO_DCCP, base);
+}
+
+static __u32 dccp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
+{
+	const struct dccp_hdr *dh = dccp_hdr(skb);
+
+	if (skb->protocol == htons(ETH_P_IPV6))
+		return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
+						    skb->nh.ipv6h->saddr.s6_addr32,
+						    dh->dccph_dport,
+						    dh->dccph_sport);
+	else
+		return secure_dccp_sequence_number(skb->nh.iph->daddr,
+						   skb->nh.iph->saddr,
+						   dh->dccph_dport,
+						   dh->dccph_sport);
+}
+
+static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 
+			   int addr_len)
+{
+	struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
+	struct inet_connection_sock *icsk = inet_csk(sk);
+	struct inet_sock *inet = inet_sk(sk);
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct dccp_sock *dp = dccp_sk(sk);
+	struct in6_addr *saddr = NULL, *final_p = NULL, final;
+	struct flowi fl;
+	struct dst_entry *dst;
+	int addr_type;
+	int err;
+
+	dp->dccps_role = DCCP_ROLE_CLIENT;
+
+	if (addr_len < SIN6_LEN_RFC2133) 
+		return -EINVAL;
+
+	if (usin->sin6_family != AF_INET6) 
+		return -EAFNOSUPPORT;
+
+	memset(&fl, 0, sizeof(fl));
+
+	if (np->sndflow) {
+		fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
+		IP6_ECN_flow_init(fl.fl6_flowlabel);
+		if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
+			struct ip6_flowlabel *flowlabel;
+			flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
+			if (flowlabel == NULL)
+				return -EINVAL;
+			ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
+			fl6_sock_release(flowlabel);
+		}
+	}
+
+	/*
+  	 *	connect() to INADDR_ANY means loopback (BSD'ism).
+  	 */
+  	
+  	if (ipv6_addr_any(&usin->sin6_addr))
+		usin->sin6_addr.s6_addr[15] = 0x1; 
+
+	addr_type = ipv6_addr_type(&usin->sin6_addr);
+
+	if(addr_type & IPV6_ADDR_MULTICAST)
+		return -ENETUNREACH;
+
+	if (addr_type & IPV6_ADDR_LINKLOCAL) {
+		if (addr_len >= sizeof(struct sockaddr_in6) &&
+		    usin->sin6_scope_id) {
+			/* If interface is set while binding, indices
+			 * must coincide.
+			 */
+			if (sk->sk_bound_dev_if &&
+			    sk->sk_bound_dev_if != usin->sin6_scope_id)
+				return -EINVAL;
+
+			sk->sk_bound_dev_if = usin->sin6_scope_id;
+		}
+
+		/* Connect to link-local address requires an interface */
+		if (!sk->sk_bound_dev_if)
+			return -EINVAL;
+	}
+
+	ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
+	np->flow_label = fl.fl6_flowlabel;
+
+	/*
+	 *	DCCP over IPv4
+	 */
+
+	if (addr_type == IPV6_ADDR_MAPPED) {
+		u32 exthdrlen = icsk->icsk_ext_hdr_len;
+		struct sockaddr_in sin;
+
+		SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
+
+		if (__ipv6_only_sock(sk))
+			return -ENETUNREACH;
+
+		sin.sin_family = AF_INET;
+		sin.sin_port = usin->sin6_port;
+		sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
+
+		icsk->icsk_af_ops = &dccp_ipv6_mapped;
+		sk->sk_backlog_rcv = dccp_v4_do_rcv;
+
+		err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
+
+		if (err) {
+			icsk->icsk_ext_hdr_len = exthdrlen;
+			icsk->icsk_af_ops = &dccp_ipv6_af_ops;
+			sk->sk_backlog_rcv = dccp_v6_do_rcv;
+			goto failure;
+		} else {
+			ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
+				      inet->saddr);
+			ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
+				      inet->rcv_saddr);
+		}
+
+		return err;
+	}
+
+	if (!ipv6_addr_any(&np->rcv_saddr))
+		saddr = &np->rcv_saddr;
+
+	fl.proto = IPPROTO_DCCP;
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+	ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
+	fl.oif = sk->sk_bound_dev_if;
+	fl.fl_ip_dport = usin->sin6_port;
+	fl.fl_ip_sport = inet->sport;
+
+	if (np->opt && np->opt->srcrt) {
+		struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
+		ipv6_addr_copy(&final, &fl.fl6_dst);
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		final_p = &final;
+	}
+
+	err = ip6_dst_lookup(sk, &dst, &fl);
+	if (err)
+		goto failure;
+	if (final_p)
+		ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+		goto failure;
+
+	if (saddr == NULL) {
+		saddr = &fl.fl6_src;
+		ipv6_addr_copy(&np->rcv_saddr, saddr);
+	}
+
+	/* set the source address */
+	ipv6_addr_copy(&np->saddr, saddr);
+	inet->rcv_saddr = LOOPBACK4_IPV6;
+
+	ip6_dst_store(sk, dst, NULL);
+
+	icsk->icsk_ext_hdr_len = 0;
+	if (np->opt)
+		icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
+					  np->opt->opt_nflen);
+
+	inet->dport = usin->sin6_port;
+
+	dccp_set_state(sk, DCCP_REQUESTING);
+	err = inet6_hash_connect(&dccp_death_row, sk);
+	if (err)
+		goto late_failure;
+	/* FIXME */
+#if 0
+	dp->dccps_gar = secure_dccp_v6_sequence_number(np->saddr.s6_addr32,
+						       np->daddr.s6_addr32,
+						       inet->sport,
+						       inet->dport);
+#endif
+	err = dccp_connect(sk);
+	if (err)
+		goto late_failure;
+
+	return 0;
+
+late_failure:
+	dccp_set_state(sk, DCCP_CLOSED);
+	__sk_dst_reset(sk);
+failure:
+	inet->dport = 0;
+	sk->sk_route_caps = 0;
+	return err;
+}
+
+static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+			int type, int code, int offset, __u32 info)
+{
+	struct ipv6hdr *hdr = (struct ipv6hdr *)skb->data;
+	const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
+	struct ipv6_pinfo *np;
+	struct sock *sk;
+	int err;
+	__u64 seq;
+
+	sk = inet6_lookup(&dccp_hashinfo, &hdr->daddr, dh->dccph_dport,
+			  &hdr->saddr, dh->dccph_sport, skb->dev->ifindex);
+
+	if (sk == NULL) {
+		ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS);
+		return;
+	}
+
+	if (sk->sk_state == DCCP_TIME_WAIT) {
+		inet_twsk_put((struct inet_timewait_sock *)sk);
+		return;
+	}
+
+	bh_lock_sock(sk);
+	if (sock_owned_by_user(sk))
+		NET_INC_STATS_BH(LINUX_MIB_LOCKDROPPEDICMPS);
+
+	if (sk->sk_state == DCCP_CLOSED)
+		goto out;
+
+	np = inet6_sk(sk);
+
+	if (type == ICMPV6_PKT_TOOBIG) {
+		struct dst_entry *dst = NULL;
+
+		if (sock_owned_by_user(sk))
+			goto out;
+		if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED))
+			goto out;
+
+		/* icmp should have updated the destination cache entry */
+		dst = __sk_dst_check(sk, np->dst_cookie);
+
+		if (dst == NULL) {
+			struct inet_sock *inet = inet_sk(sk);
+			struct flowi fl;
+
+			/* BUGGG_FUTURE: Again, it is not clear how
+			   to handle rthdr case. Ignore this complexity
+			   for now.
+			 */
+			memset(&fl, 0, sizeof(fl));
+			fl.proto = IPPROTO_DCCP;
+			ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+			ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+			fl.oif = sk->sk_bound_dev_if;
+			fl.fl_ip_dport = inet->dport;
+			fl.fl_ip_sport = inet->sport;
+
+			if ((err = ip6_dst_lookup(sk, &dst, &fl))) {
+				sk->sk_err_soft = -err;
+				goto out;
+			}
+
+			if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+				sk->sk_err_soft = -err;
+				goto out;
+			}
+
+		} else
+			dst_hold(dst);
+
+		if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
+			dccp_sync_mss(sk, dst_mtu(dst));
+		} /* else let the usual retransmit timer handle it */
+		dst_release(dst);
+		goto out;
+	}
+
+	icmpv6_err_convert(type, code, &err);
+
+	seq = DCCP_SKB_CB(skb)->dccpd_seq;
+	/* Might be for an request_sock */
+	switch (sk->sk_state) {
+		struct request_sock *req, **prev;
+	case DCCP_LISTEN:
+		if (sock_owned_by_user(sk))
+			goto out;
+
+		req = inet6_csk_search_req(sk, &prev, dh->dccph_dport,
+					   &hdr->daddr, &hdr->saddr,
+					   inet6_iif(skb));
+		if (!req)
+			goto out;
+
+		/* ICMPs are not backlogged, hence we cannot get
+		 * an established socket here.
+		 */
+		BUG_TRAP(req->sk == NULL);
+
+		if (seq != dccp_rsk(req)->dreq_iss) {
+			NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
+			goto out;
+		}
+
+		inet_csk_reqsk_queue_drop(sk, req, prev);
+		goto out;
+
+	case DCCP_REQUESTING:
+	case DCCP_RESPOND:  /* Cannot happen.
+			       It can, it SYNs are crossed. --ANK */ 
+		if (!sock_owned_by_user(sk)) {
+			DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
+			sk->sk_err = err;
+			/*
+			 * Wake people up to see the error
+			 * (see connect in sock.c)
+			 */
+			sk->sk_error_report(sk);
+
+			dccp_done(sk);
+		} else
+			sk->sk_err_soft = err;
+		goto out;
+	}
+
+	if (!sock_owned_by_user(sk) && np->recverr) {
+		sk->sk_err = err;
+		sk->sk_error_report(sk);
+	} else
+		sk->sk_err_soft = err;
+
+out:
+	bh_unlock_sock(sk);
+	sock_put(sk);
+}
+
+
+static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
+				 struct dst_entry *dst)
+{
+	struct inet6_request_sock *ireq6 = inet6_rsk(req);
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct sk_buff *skb;
+	struct ipv6_txoptions *opt = NULL;
+	struct in6_addr *final_p = NULL, final;
+	struct flowi fl;
+	int err = -1;
+
+	memset(&fl, 0, sizeof(fl));
+	fl.proto = IPPROTO_DCCP;
+	ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+	ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
+	fl.fl6_flowlabel = 0;
+	fl.oif = ireq6->iif;
+	fl.fl_ip_dport = inet_rsk(req)->rmt_port;
+	fl.fl_ip_sport = inet_sk(sk)->sport;
+
+	if (dst == NULL) {
+		opt = np->opt;
+		if (opt == NULL &&
+		    np->rxopt.bits.osrcrt == 2 &&
+		    ireq6->pktopts) {
+			struct sk_buff *pktopts = ireq6->pktopts;
+			struct inet6_skb_parm *rxopt = IP6CB(pktopts);
+			if (rxopt->srcrt)
+				opt = ipv6_invert_rthdr(sk,
+					(struct ipv6_rt_hdr *)(pktopts->nh.raw +
+							       rxopt->srcrt));
+		}
+
+		if (opt && opt->srcrt) {
+			struct rt0_hdr *rt0 = (struct rt0_hdr *)opt->srcrt;
+			ipv6_addr_copy(&final, &fl.fl6_dst);
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			final_p = &final;
+		}
+
+		err = ip6_dst_lookup(sk, &dst, &fl);
+		if (err)
+			goto done;
+		if (final_p)
+			ipv6_addr_copy(&fl.fl6_dst, final_p);
+		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+			goto done;
+	}
+
+	skb = dccp_make_response(sk, dst, req);
+	if (skb != NULL) {
+		struct dccp_hdr *dh = dccp_hdr(skb);
+		dh->dccph_checksum = dccp_v6_check(dh, skb->len,
+						   &ireq6->loc_addr,
+						   &ireq6->rmt_addr,
+						   csum_partial((char *)dh,
+								skb->len,
+								skb->csum));
+		ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+		err = ip6_xmit(sk, skb, &fl, opt, 0);
+		if (err == NET_XMIT_CN)
+			err = 0;
+	}
+
+done:
+        if (opt && opt != np->opt)
+		sock_kfree_s(sk, opt, opt->tot_len);
+	return err;
+}
+
+static void dccp_v6_reqsk_destructor(struct request_sock *req)
+{
+	if (inet6_rsk(req)->pktopts != NULL)
+		kfree_skb(inet6_rsk(req)->pktopts);
+}
+
+static struct request_sock_ops dccp6_request_sock_ops = {
+	.family		= AF_INET6,
+	.obj_size	= sizeof(struct dccp6_request_sock),
+	.rtx_syn_ack	= dccp_v6_send_response,
+	.send_ack	= dccp_v6_reqsk_send_ack,
+	.destructor	= dccp_v6_reqsk_destructor,
+	.send_reset	= dccp_v6_ctl_send_reset,
+};
+
+static struct timewait_sock_ops dccp6_timewait_sock_ops = {
+	.twsk_obj_size	= sizeof(struct dccp6_timewait_sock),
+};
+
+static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct dccp_hdr *dh = dccp_hdr(skb);
+
+	dh->dccph_checksum = csum_ipv6_magic(&np->saddr, &np->daddr,
+					     len, IPPROTO_DCCP, 
+					     csum_partial((char *)dh,
+							  dh->dccph_doff << 2,
+							  skb->csum));
+}
+
+static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
+{
+	struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 
+	const int dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
+				       sizeof(struct dccp_hdr_ext) +
+				       sizeof(struct dccp_hdr_reset);
+	struct sk_buff *skb;
+	struct flowi fl;
+	u64 seqno;
+
+	if (rxdh->dccph_type == DCCP_PKT_RESET)
+		return;
+
+	if (!ipv6_unicast_destination(rxskb))
+		return; 
+
+	/*
+	 * We need to grab some memory, and put together an RST,
+	 * and then put it into the queue to be sent.
+	 */
+
+	skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) +
+			dccp_hdr_reset_len, GFP_ATOMIC);
+	if (skb == NULL) 
+	  	return;
+
+	skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) +
+		    dccp_hdr_reset_len);
+
+	skb->h.raw = skb_push(skb, dccp_hdr_reset_len);
+	dh = dccp_hdr(skb);
+	memset(dh, 0, dccp_hdr_reset_len);
+
+	/* Swap the send and the receive. */
+	dh->dccph_type	= DCCP_PKT_RESET;
+	dh->dccph_sport	= rxdh->dccph_dport;
+	dh->dccph_dport	= rxdh->dccph_sport;
+	dh->dccph_doff	= dccp_hdr_reset_len / 4;
+	dh->dccph_x	= 1;
+	dccp_hdr_reset(skb)->dccph_reset_code =
+				DCCP_SKB_CB(rxskb)->dccpd_reset_code;
+
+	/* See "8.3.1. Abnormal Termination" in draft-ietf-dccp-spec-11 */
+	seqno = 0;
+	if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
+		dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
+
+	dccp_hdr_set_seq(dh, seqno);
+	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
+			 DCCP_SKB_CB(rxskb)->dccpd_seq);
+
+	memset(&fl, 0, sizeof(fl));
+	ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
+	ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
+	dh->dccph_checksum = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
+					     sizeof(*dh), IPPROTO_DCCP,
+					     skb->csum);
+	fl.proto = IPPROTO_DCCP;
+	fl.oif = inet6_iif(rxskb);
+	fl.fl_ip_dport = dh->dccph_dport;
+	fl.fl_ip_sport = dh->dccph_sport;
+
+	/* sk = NULL, but it is safe for now. RST socket required. */
+	if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
+		if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
+			ip6_xmit(NULL, skb, &fl, NULL, 0);
+			DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
+			DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
+			return;
+		}
+	}
+
+	kfree_skb(skb);
+}
+
+static void dccp_v6_ctl_send_ack(struct sk_buff *rxskb)
+{
+	struct flowi fl;
+	struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
+	const int dccp_hdr_ack_len = sizeof(struct dccp_hdr) +
+				     sizeof(struct dccp_hdr_ext) +
+				     sizeof(struct dccp_hdr_ack_bits);
+	struct sk_buff *skb;
+
+	skb = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) +
+			dccp_hdr_ack_len, GFP_ATOMIC);
+	if (skb == NULL)
+		return;
+
+	skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr) +
+			 dccp_hdr_ack_len);
+
+	skb->h.raw = skb_push(skb, dccp_hdr_ack_len);
+	dh = dccp_hdr(skb);
+	memset(dh, 0, dccp_hdr_ack_len);
+
+	/* Build DCCP header and checksum it. */
+	dh->dccph_type	= DCCP_PKT_ACK;
+	dh->dccph_sport = rxdh->dccph_dport;
+	dh->dccph_dport = rxdh->dccph_sport;
+	dh->dccph_doff	= dccp_hdr_ack_len / 4;
+	dh->dccph_x	= 1;
+	
+	dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq);
+	dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
+			 DCCP_SKB_CB(rxskb)->dccpd_seq);
+
+	memset(&fl, 0, sizeof(fl));
+	ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
+	ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
+
+	/* FIXME: calculate checksum, IPv4 also should... */
+
+	fl.proto = IPPROTO_DCCP;
+	fl.oif = inet6_iif(rxskb);
+	fl.fl_ip_dport = dh->dccph_dport;
+	fl.fl_ip_sport = dh->dccph_sport;
+
+	if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
+		if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
+			ip6_xmit(NULL, skb, &fl, NULL, 0);
+			DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
+			return;
+		}
+	}
+
+	kfree_skb(skb);
+}
+
+static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
+				   struct request_sock *req)
+{
+	dccp_v6_ctl_send_ack(skb);
+}
+
+static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
+{
+	const struct dccp_hdr *dh = dccp_hdr(skb);
+	const struct ipv6hdr *iph = skb->nh.ipv6h;
+	struct sock *nsk;
+	struct request_sock **prev;
+	/* Find possible connection requests. */
+	struct request_sock *req = inet6_csk_search_req(sk, &prev,
+							dh->dccph_sport,
+							&iph->saddr,
+							&iph->daddr,
+							inet6_iif(skb));
+	if (req != NULL)
+		return dccp_check_req(sk, skb, req, prev);
+
+	nsk = __inet6_lookup_established(&dccp_hashinfo,
+					 &iph->saddr, dh->dccph_sport,
+					 &iph->daddr, ntohs(dh->dccph_dport),
+					 inet6_iif(skb));
+
+	if (nsk != NULL) {
+		if (nsk->sk_state != DCCP_TIME_WAIT) {
+			bh_lock_sock(nsk);
+			return nsk;
+		}
+		inet_twsk_put((struct inet_timewait_sock *)nsk);
+		return NULL;
+	}
+
+	return sk;
+}
+
+static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
+{
+	struct inet_request_sock *ireq;
+	struct dccp_sock dp;
+	struct request_sock *req;
+	struct dccp_request_sock *dreq;
+	struct inet6_request_sock *ireq6;
+	struct ipv6_pinfo *np = inet6_sk(sk);
+ 	const __u32 service = dccp_hdr_request(skb)->dccph_req_service;
+	struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
+	__u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
+
+	if (skb->protocol == htons(ETH_P_IP))
+		return dccp_v4_conn_request(sk, skb);
+
+	if (!ipv6_unicast_destination(skb))
+		goto drop; 
+
+	if (dccp_bad_service_code(sk, service)) {
+		reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
+		goto drop;
+ 	}
+	/*
+	 *	There are no SYN attacks on IPv6, yet...	
+	 */
+	if (inet_csk_reqsk_queue_is_full(sk))
+		goto drop;		
+
+	if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
+		goto drop;
+
+	req = inet6_reqsk_alloc(sk->sk_prot->rsk_prot);
+	if (req == NULL)
+		goto drop;
+
+	/* FIXME: process options */
+
+	dccp_openreq_init(req, &dp, skb);
+
+	ireq6 = inet6_rsk(req);
+	ireq = inet_rsk(req);
+	ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
+	ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
+	req->rcv_wnd	= 100; /* Fake, option parsing will get the
+				  right value */
+	ireq6->pktopts	= NULL;
+
+	if (ipv6_opt_accepted(sk, skb) ||
+	    np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
+	    np->rxopt.bits.rxhlim || np->rxopt.bits.rxohlim) {
+		atomic_inc(&skb->users);
+		ireq6->pktopts = skb;
+	}
+	ireq6->iif = sk->sk_bound_dev_if;
+
+	/* So that link locals have meaning */
+	if (!sk->sk_bound_dev_if &&
+	    ipv6_addr_type(&ireq6->rmt_addr) & IPV6_ADDR_LINKLOCAL)
+		ireq6->iif = inet6_iif(skb);
+
+	/* 
+	 * Step 3: Process LISTEN state
+	 *
+	 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
+	 *
+	 * In fact we defer setting S.GSR, S.SWL, S.SWH to
+	 * dccp_create_openreq_child.
+	 */
+	dreq = dccp_rsk(req);
+	dreq->dreq_isr	   = dcb->dccpd_seq;
+	dreq->dreq_iss	   = dccp_v6_init_sequence(sk, skb);
+	dreq->dreq_service = service;
+
+	if (dccp_v6_send_response(sk, req, NULL))
+		goto drop_and_free;
+
+	inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
+	return 0;
+
+drop_and_free:
+	reqsk_free(req);
+drop:
+	DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
+	dcb->dccpd_reset_code = reset_code;
+	return -1;
+}
+
+static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
+					      struct sk_buff *skb,
+					      struct request_sock *req,
+					      struct dst_entry *dst)
+{
+	struct inet6_request_sock *ireq6 = inet6_rsk(req);
+	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+	struct inet_sock *newinet;
+	struct dccp_sock *newdp;
+	struct dccp6_sock *newdp6;
+	struct sock *newsk;
+	struct ipv6_txoptions *opt;
+
+	if (skb->protocol == htons(ETH_P_IP)) {
+		/*
+		 *	v6 mapped
+		 */
+
+		newsk = dccp_v4_request_recv_sock(sk, skb, req, dst);
+		if (newsk == NULL) 
+			return NULL;
+
+		newdp6 = (struct dccp6_sock *)newsk;
+		newdp = dccp_sk(newsk);
+		newinet = inet_sk(newsk);
+		newinet->pinet6 = &newdp6->inet6;
+		newnp = inet6_sk(newsk);
+
+		memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+
+		ipv6_addr_set(&newnp->daddr, 0, 0, htonl(0x0000FFFF),
+			      newinet->daddr);
+
+		ipv6_addr_set(&newnp->saddr, 0, 0, htonl(0x0000FFFF),
+			      newinet->saddr);
+
+		ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
+
+		inet_csk(newsk)->icsk_af_ops = &dccp_ipv6_mapped;
+		newsk->sk_backlog_rcv = dccp_v4_do_rcv;
+		newnp->pktoptions  = NULL;
+		newnp->opt	   = NULL;
+		newnp->mcast_oif   = inet6_iif(skb);
+		newnp->mcast_hops  = skb->nh.ipv6h->hop_limit;
+
+		/*
+		 * No need to charge this sock to the relevant IPv6 refcnt debug socks count
+		 * here, dccp_create_openreq_child now does this for us, see the comment in
+		 * that function for the gory details. -acme
+		 */
+
+		/* It is tricky place. Until this moment IPv4 tcp
+		   worked with IPv6 icsk.icsk_af_ops.
+		   Sync it now.
+		 */
+		dccp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
+
+		return newsk;
+	}
+
+	opt = np->opt;
+
+	if (sk_acceptq_is_full(sk))
+		goto out_overflow;
+
+	if (np->rxopt.bits.osrcrt == 2 &&
+	    opt == NULL && ireq6->pktopts) {
+		struct inet6_skb_parm *rxopt = IP6CB(ireq6->pktopts);
+		if (rxopt->srcrt)
+			opt = ipv6_invert_rthdr(sk,
+				(struct ipv6_rt_hdr *)(ireq6->pktopts->nh.raw +
+						       rxopt->srcrt));
+	}
+
+	if (dst == NULL) {
+		struct in6_addr *final_p = NULL, final;
+		struct flowi fl;
+
+		memset(&fl, 0, sizeof(fl));
+		fl.proto = IPPROTO_DCCP;
+		ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
+		if (opt && opt->srcrt) {
+			struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
+			ipv6_addr_copy(&final, &fl.fl6_dst);
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			final_p = &final;
+		}
+		ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
+		fl.oif = sk->sk_bound_dev_if;
+		fl.fl_ip_dport = inet_rsk(req)->rmt_port;
+		fl.fl_ip_sport = inet_sk(sk)->sport;
+
+		if (ip6_dst_lookup(sk, &dst, &fl))
+			goto out;
+
+		if (final_p)
+			ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+		if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
+			goto out;
+	} 
+
+	newsk = dccp_create_openreq_child(sk, req, skb);
+	if (newsk == NULL)
+		goto out;
+
+	/*
+	 * No need to charge this sock to the relevant IPv6 refcnt debug socks
+	 * count here, dccp_create_openreq_child now does this for us, see the
+	 * comment in that function for the gory details. -acme
+	 */
+
+	ip6_dst_store(newsk, dst, NULL);
+	newsk->sk_route_caps = dst->dev->features &
+		~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+	newdp6 = (struct dccp6_sock *)newsk;
+	newinet = inet_sk(newsk);
+	newinet->pinet6 = &newdp6->inet6;
+	newdp = dccp_sk(newsk);
+	newnp = inet6_sk(newsk);
+
+	memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+
+	ipv6_addr_copy(&newnp->daddr, &ireq6->rmt_addr);
+	ipv6_addr_copy(&newnp->saddr, &ireq6->loc_addr);
+	ipv6_addr_copy(&newnp->rcv_saddr, &ireq6->loc_addr);
+	newsk->sk_bound_dev_if = ireq6->iif;
+
+	/* Now IPv6 options... 
+
+	   First: no IPv4 options.
+	 */
+	newinet->opt = NULL;
+
+	/* Clone RX bits */
+	newnp->rxopt.all = np->rxopt.all;
+
+	/* Clone pktoptions received with SYN */
+	newnp->pktoptions = NULL;
+	if (ireq6->pktopts != NULL) {
+		newnp->pktoptions = skb_clone(ireq6->pktopts, GFP_ATOMIC);
+		kfree_skb(ireq6->pktopts);
+		ireq6->pktopts = NULL;
+		if (newnp->pktoptions)
+			skb_set_owner_r(newnp->pktoptions, newsk);
+	}
+	newnp->opt	  = NULL;
+	newnp->mcast_oif  = inet6_iif(skb);
+	newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
+
+	/* Clone native IPv6 options from listening socket (if any)
+
+	   Yes, keeping reference count would be much more clever,
+	   but we make one more one thing there: reattach optmem
+	   to newsk.
+	 */
+	if (opt) {
+		newnp->opt = ipv6_dup_options(newsk, opt);
+		if (opt != np->opt)
+			sock_kfree_s(sk, opt, opt->tot_len);
+	}
+
+	inet_csk(newsk)->icsk_ext_hdr_len = 0;
+	if (newnp->opt)
+		inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
+						     newnp->opt->opt_flen);
+
+	dccp_sync_mss(newsk, dst_mtu(dst));
+
+	newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
+
+	__inet6_hash(&dccp_hashinfo, newsk);
+	inet_inherit_port(&dccp_hashinfo, sk, newsk);
+
+	return newsk;
+
+out_overflow:
+	NET_INC_STATS_BH(LINUX_MIB_LISTENOVERFLOWS);
+out:
+	NET_INC_STATS_BH(LINUX_MIB_LISTENDROPS);
+	if (opt && opt != np->opt)
+		sock_kfree_s(sk, opt, opt->tot_len);
+	dst_release(dst);
+	return NULL;
+}
+
+/* The socket must have it's spinlock held when we get
+ * here.
+ *
+ * We have a potential double-lock case here, so even when
+ * doing backlog processing we use the BH locking scheme.
+ * This is because we cannot sleep with the original spinlock
+ * held.
+ */
+static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct sk_buff *opt_skb = NULL;
+
+	/* Imagine: socket is IPv6. IPv4 packet arrives,
+	   goes to IPv4 receive handler and backlogged.
+	   From backlog it always goes here. Kerboom...
+	   Fortunately, dccp_rcv_established and rcv_established
+	   handle them correctly, but it is not case with
+	   dccp_v6_hnd_req and dccp_v6_ctl_send_reset().   --ANK
+	 */
+
+	if (skb->protocol == htons(ETH_P_IP))
+		return dccp_v4_do_rcv(sk, skb);
+
+	if (sk_filter(sk, skb, 0))
+		goto discard;
+
+	/*
+	 *	socket locking is here for SMP purposes as backlog rcv
+	 *	is currently called with bh processing disabled.
+	 */
+
+	/* Do Stevens' IPV6_PKTOPTIONS.
+
+	   Yes, guys, it is the only place in our code, where we
+	   may make it not affecting IPv4.
+	   The rest of code is protocol independent,
+	   and I do not like idea to uglify IPv4.
+
+	   Actually, all the idea behind IPV6_PKTOPTIONS
+	   looks not very well thought. For now we latch
+	   options, received in the last packet, enqueued
+	   by tcp. Feel free to propose better solution.
+	                                       --ANK (980728)
+	 */
+	if (np->rxopt.all)
+		opt_skb = skb_clone(skb, GFP_ATOMIC);
+
+	if (sk->sk_state == DCCP_OPEN) { /* Fast path */
+		if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
+			goto reset;
+		return 0;
+	}
+
+	if (sk->sk_state == DCCP_LISTEN) { 
+		struct sock *nsk = dccp_v6_hnd_req(sk, skb);
+		if (!nsk)
+			goto discard;
+
+		/*
+		 * Queue it on the new socket if the new socket is active,
+		 * otherwise we just shortcircuit this and continue with
+		 * the new socket..
+		 */
+ 		if(nsk != sk) {
+			if (dccp_child_process(sk, nsk, skb))
+				goto reset;
+			if (opt_skb)
+				__kfree_skb(opt_skb);
+			return 0;
+		}
+	}
+
+	if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
+		goto reset;
+	return 0;
+
+reset:
+	dccp_v6_ctl_send_reset(skb);
+discard:
+	if (opt_skb)
+		__kfree_skb(opt_skb);
+	kfree_skb(skb);
+	return 0;
+}
+
+static int dccp_v6_rcv(struct sk_buff **pskb)
+{
+	const struct dccp_hdr *dh;
+	struct sk_buff *skb = *pskb;
+	struct sock *sk;
+
+	/* Step 1: Check header basics: */
+
+	if (dccp_invalid_packet(skb))
+		goto discard_it;
+
+	dh = dccp_hdr(skb);
+
+	DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(skb);
+	DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
+
+	if (dccp_packet_without_ack(skb))
+		DCCP_SKB_CB(skb)->dccpd_ack_seq = DCCP_PKT_WITHOUT_ACK_SEQ;
+	else
+		DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
+
+	/* Step 2:
+	 * 	Look up flow ID in table and get corresponding socket */
+	sk = __inet6_lookup(&dccp_hashinfo, &skb->nh.ipv6h->saddr,
+			    dh->dccph_sport,
+			    &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport),
+			    inet6_iif(skb));
+	/* 
+	 * Step 2:
+	 * 	If no socket ...
+	 *		Generate Reset(No Connection) unless P.type == Reset
+	 *		Drop packet and return
+	 */
+	if (sk == NULL)
+		goto no_dccp_socket;
+
+	/* 
+	 * Step 2:
+	 * 	... or S.state == TIMEWAIT,
+	 *		Generate Reset(No Connection) unless P.type == Reset
+	 *		Drop packet and return
+	 */
+	       
+	if (sk->sk_state == DCCP_TIME_WAIT)
+                goto do_time_wait;
+
+	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
+		goto discard_and_relse;
+
+	return sk_receive_skb(sk, skb) ? -1 : 0;
+
+no_dccp_socket:
+	if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
+		goto discard_it;
+	/*
+	 * Step 2:
+	 *		Generate Reset(No Connection) unless P.type == Reset
+	 *		Drop packet and return
+	 */
+	if (dh->dccph_type != DCCP_PKT_RESET) {
+		DCCP_SKB_CB(skb)->dccpd_reset_code =
+					DCCP_RESET_CODE_NO_CONNECTION;
+		dccp_v6_ctl_send_reset(skb);
+	}
+discard_it:
+
+	/*
+	 *	Discard frame
+	 */
+
+	kfree_skb(skb);
+	return 0;
+
+discard_and_relse:
+	sock_put(sk);
+	goto discard_it;
+
+do_time_wait:
+	inet_twsk_put((struct inet_timewait_sock *)sk);
+	goto no_dccp_socket;
+}
+
+static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
+	.queue_xmit	=	inet6_csk_xmit,
+	.send_check	=	dccp_v6_send_check,
+	.rebuild_header	=	inet6_sk_rebuild_header,
+	.conn_request	=	dccp_v6_conn_request,
+	.syn_recv_sock	=	dccp_v6_request_recv_sock,
+	.net_header_len	=	sizeof(struct ipv6hdr),
+	.setsockopt	=	ipv6_setsockopt,
+	.getsockopt	=	ipv6_getsockopt,
+	.addr2sockaddr	=	inet6_csk_addr2sockaddr,
+	.sockaddr_len	=	sizeof(struct sockaddr_in6)
+};
+
+/*
+ *	DCCP over IPv4 via INET6 API
+ */
+static struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
+	.queue_xmit	=	ip_queue_xmit,
+	.send_check	=	dccp_v4_send_check,
+	.rebuild_header	=	inet_sk_rebuild_header,
+	.conn_request	=	dccp_v6_conn_request,
+	.syn_recv_sock	=	dccp_v6_request_recv_sock,
+	.net_header_len	=	sizeof(struct iphdr),
+	.setsockopt	=	ipv6_setsockopt,
+	.getsockopt	=	ipv6_getsockopt,
+	.addr2sockaddr	=	inet6_csk_addr2sockaddr,
+	.sockaddr_len	=	sizeof(struct sockaddr_in6)
+};
+
+/* NOTE: A lot of things set to zero explicitly by call to
+ *       sk_alloc() so need not be done here.
+ */
+static int dccp_v6_init_sock(struct sock *sk)
+{
+	int err = dccp_v4_init_sock(sk);
+
+	if (err == 0)
+		inet_csk(sk)->icsk_af_ops = &dccp_ipv6_af_ops;
+
+	return err;
+}
+
+static int dccp_v6_destroy_sock(struct sock *sk)
+{
+	dccp_v4_destroy_sock(sk);
+	return inet6_destroy_sock(sk);
+}
+
+static struct proto dccp_v6_prot = {
+	.name			= "DCCPv6",
+	.owner			= THIS_MODULE,
+	.close			= dccp_close,
+	.connect		= dccp_v6_connect,
+	.disconnect		= dccp_disconnect,
+	.ioctl			= dccp_ioctl,
+	.init			= dccp_v6_init_sock,
+	.setsockopt		= dccp_setsockopt,
+	.getsockopt		= dccp_getsockopt,
+	.sendmsg		= dccp_sendmsg,
+	.recvmsg		= dccp_recvmsg,
+	.backlog_rcv		= dccp_v6_do_rcv,
+	.hash			= dccp_v6_hash,
+	.unhash			= dccp_unhash,
+	.accept			= inet_csk_accept,
+	.get_port		= dccp_v6_get_port,
+	.shutdown		= dccp_shutdown,
+	.destroy		= dccp_v6_destroy_sock,
+	.orphan_count		= &dccp_orphan_count,
+	.max_header		= MAX_DCCP_HEADER,
+	.obj_size		= sizeof(struct dccp6_sock),
+	.rsk_prot		= &dccp6_request_sock_ops,
+	.twsk_prot		= &dccp6_timewait_sock_ops,
+};
+
+static struct inet6_protocol dccp_v6_protocol = {
+	.handler	=	dccp_v6_rcv,
+	.err_handler	=	dccp_v6_err,
+	.flags		=	INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL,
+};
+
+static struct proto_ops inet6_dccp_ops = {
+	.family		= PF_INET6,
+	.owner		= THIS_MODULE,
+	.release	= inet6_release,
+	.bind		= inet6_bind,
+	.connect	= inet_stream_connect,
+	.socketpair	= sock_no_socketpair,
+	.accept		= inet_accept,
+	.getname	= inet6_getname,
+	.poll		= dccp_poll,
+	.ioctl		= inet6_ioctl,
+	.listen		= inet_dccp_listen,
+	.shutdown	= inet_shutdown,
+	.setsockopt	= sock_common_setsockopt,
+	.getsockopt	= sock_common_getsockopt,
+	.sendmsg	= inet_sendmsg,
+	.recvmsg	= sock_common_recvmsg,
+	.mmap		= sock_no_mmap,
+	.sendpage	= sock_no_sendpage,
+};
+
+static struct inet_protosw dccp_v6_protosw = {
+	.type		= SOCK_DCCP,
+	.protocol	= IPPROTO_DCCP,
+	.prot		= &dccp_v6_prot,
+	.ops		= &inet6_dccp_ops,
+	.capability	= -1,
+	.flags		= INET_PROTOSW_ICSK,
+};
+
+static int __init dccp_v6_init(void)
+{
+	int err = proto_register(&dccp_v6_prot, 1);
+
+	if (err != 0)
+		goto out;
+
+	err = inet6_add_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
+	if (err != 0)
+		goto out_unregister_proto;
+
+	inet6_register_protosw(&dccp_v6_protosw);
+out:
+	return err;
+out_unregister_proto:
+	proto_unregister(&dccp_v6_prot);
+	goto out;
+}
+
+static void __exit dccp_v6_exit(void)
+{
+	inet6_del_protocol(&dccp_v6_protocol, IPPROTO_DCCP);
+	inet6_unregister_protosw(&dccp_v6_protosw);
+	proto_unregister(&dccp_v6_prot);
+}
+
+module_init(dccp_v6_init);
+module_exit(dccp_v6_exit);
+
+/*
+ * __stringify doesn't likes enums, so use SOCK_DCCP (6) and IPPROTO_DCCP (33)
+ * values directly, Also cover the case where the protocol is not specified,
+ * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
+ */
+MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-33-type-6");
+MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-0-type-6");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
+MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");
diff --git a/net/dccp/ipv6.h b/net/dccp/ipv6.h
new file mode 100644
index 0000000..e4d4e93
--- /dev/null
+++ b/net/dccp/ipv6.h
@@ -0,0 +1,37 @@
+#ifndef _DCCP_IPV6_H
+#define _DCCP_IPV6_H
+/*
+ *  net/dccp/ipv6.h
+ *
+ *  An implementation of the DCCP protocol
+ *  Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+ *
+ *	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/config.h>
+#include <linux/dccp.h>
+#include <linux/ipv6.h>
+
+struct dccp6_sock {
+	struct dccp_sock  dccp;
+	/*
+	 * ipv6_pinfo has to be the last member of dccp6_sock,
+	 * see inet6_sk_generic.
+	 */
+	struct ipv6_pinfo inet6;
+};
+
+struct dccp6_request_sock {
+	struct dccp_request_sock  dccp;
+	struct inet6_request_sock inet6;
+};
+
+struct dccp6_timewait_sock {
+	struct inet_timewait_sock   inet;
+	struct inet6_timewait_sock  tw6;
+};
+
+#endif /* _DCCP_IPV6_H */
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 1393461..29261fc 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -40,6 +40,8 @@
 					    (unsigned long)&dccp_death_row),
 };
 
+EXPORT_SYMBOL_GPL(dccp_death_row);
+
 void dccp_time_wait(struct sock *sk, int state, int timeo)
 {
 	struct inet_timewait_sock *tw = NULL;
@@ -50,7 +52,18 @@
 	if (tw != NULL) {
 		const struct inet_connection_sock *icsk = inet_csk(sk);
 		const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		if (tw->tw_family == PF_INET6) {
+			const struct ipv6_pinfo *np = inet6_sk(sk);
+			struct inet6_timewait_sock *tw6;
 
+			tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot);
+			tw6 = inet6_twsk((struct sock *)tw);
+			ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr);
+			ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr);
+			tw->tw_ipv6only = np->ipv6only;
+		}
+#endif
 		/* Linkage updates. */
 		__inet_twsk_hashdance(tw, sk, &dccp_hashinfo);
 
@@ -170,6 +183,8 @@
 	return newsk;
 }
 
+EXPORT_SYMBOL_GPL(dccp_create_openreq_child);
+
 /* 
  * Process an incoming packet for RESPOND sockets represented
  * as an request_sock.
@@ -214,7 +229,7 @@
 		goto drop;
 	}
 
-	child = dccp_v4_request_recv_sock(sk, skb, req, NULL);
+	child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL);
 	if (child == NULL)
 		goto listen_overflow;
 
@@ -236,6 +251,8 @@
 	goto out;
 }
 
+EXPORT_SYMBOL_GPL(dccp_check_req);
+
 /*
  *  Queue segment on the new socket if the new socket is active,
  *  otherwise we just shortcircuit this and continue with
@@ -266,3 +283,5 @@
 	sock_put(child);
 	return ret;
 }
+
+EXPORT_SYMBOL_GPL(dccp_child_process);
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 74ff870..efd7ffb 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 
+#include <net/inet_sock.h>
 #include <net/sock.h>
 
 #include "ackvec.h"
@@ -43,6 +44,7 @@
 {
 	if (likely(skb != NULL)) {
 		const struct inet_sock *inet = inet_sk(sk);
+		const struct inet_connection_sock *icsk = inet_csk(sk);
 		struct dccp_sock *dp = dccp_sk(sk);
 		struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
 		struct dccp_hdr *dh;
@@ -108,8 +110,7 @@
 			break;
 		}
 
-		dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr,
-						      inet->daddr);
+		icsk->icsk_af_ops->send_check(sk, skb->len, skb);
 
 		if (set_ack)
 			dccp_event_ack_sent(sk);
@@ -117,7 +118,7 @@
 		DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
 
 		memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
-		err = ip_queue_xmit(skb, 0);
+		err = icsk->icsk_af_ops->queue_xmit(skb, 0);
 		if (err <= 0)
 			return err;
 
@@ -134,20 +135,13 @@
 
 unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu)
 {
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct dccp_sock *dp = dccp_sk(sk);
-	int mss_now;
-
-	/*
-	 * FIXME: we really should be using the af_specific thing to support
-	 * 	  IPv6.
-	 * mss_now = pmtu - tp->af_specific->net_header_len -
-	 * 	     sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext);
-	 */
-	mss_now = pmtu - sizeof(struct iphdr) - sizeof(struct dccp_hdr) -
-		  sizeof(struct dccp_hdr_ext);
+	int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
+		       sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext));
 
 	/* Now subtract optional transport overhead */
-	mss_now -= dp->dccps_ext_header_len;
+	mss_now -= icsk->icsk_ext_hdr_len;
 
 	/*
 	 * FIXME: this should come from the CCID infrastructure, where, say,
@@ -160,12 +154,14 @@
 	mss_now -= ((5 + 6 + 10 + 6 + 6 + 6 + 3) / 4) * 4;
 
 	/* And store cached results */
-	dp->dccps_pmtu_cookie = pmtu;
+	icsk->icsk_pmtu_cookie = pmtu;
 	dp->dccps_mss_cache = mss_now;
 
 	return mss_now;
 }
 
+EXPORT_SYMBOL_GPL(dccp_sync_mss);
+
 void dccp_write_space(struct sock *sk)
 {
 	read_lock(&sk->sk_callback_lock);
@@ -266,7 +262,7 @@
 
 int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 {
-	if (inet_sk_rebuild_header(sk) != 0)
+	if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk) != 0)
 		return -EHOSTUNREACH; /* Routing failure or similar. */
 
 	return dccp_transmit_skb(sk, (skb_cloned(skb) ?
@@ -321,6 +317,8 @@
 	return skb;
 }
 
+EXPORT_SYMBOL_GPL(dccp_make_response);
+
 struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
 				const enum dccp_reset_codes code)
 				   
@@ -377,6 +375,7 @@
  */
 static inline void dccp_connect_init(struct sock *sk)
 {
+	struct dccp_sock *dp = dccp_sk(sk);
 	struct dst_entry *dst = __sk_dst_get(sk);
 	struct inet_connection_sock *icsk = inet_csk(sk);
 
@@ -385,10 +384,16 @@
 	
 	dccp_sync_mss(sk, dst_mtu(dst));
 
-	/*
-	 * FIXME: set dp->{dccps_swh,dccps_swl}, with
-	 * something like dccp_inc_seq
-	 */
+	dccp_update_gss(sk, dp->dccps_iss);
+ 	/*
+	 * SWL and AWL are initially adjusted so that they are not less than
+	 * the initial Sequence Numbers received and sent, respectively:
+	 *	SWL := max(GSR + 1 - floor(W/4), ISR),
+	 *	AWL := max(GSS - W' + 1, ISS).
+	 * These adjustments MUST be applied only at the beginning of the
+	 * connection.
+ 	 */
+	dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
 
 	icsk->icsk_retransmits = 0;
 }
@@ -420,6 +425,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_connect);
+
 void dccp_send_ack(struct sock *sk)
 {
 	/* If we have been reset, we may not send again. */
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 8a6b2a9..65b11ea 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -24,7 +24,7 @@
 #include <net/checksum.h>
 
 #include <net/inet_common.h>
-#include <net/ip.h>
+#include <net/inet_sock.h>
 #include <net/protocol.h>
 #include <net/sock.h>
 #include <net/xfrm.h>
@@ -34,15 +34,18 @@
 #include <linux/timer.h>
 #include <linux/delay.h>
 #include <linux/poll.h>
-#include <linux/dccp.h>
 
 #include "ccid.h"
 #include "dccp.h"
 
 DEFINE_SNMP_STAT(struct dccp_mib, dccp_statistics) __read_mostly;
 
+EXPORT_SYMBOL_GPL(dccp_statistics);
+
 atomic_t dccp_orphan_count = ATOMIC_INIT(0);
 
+EXPORT_SYMBOL_GPL(dccp_orphan_count);
+
 static struct net_protocol dccp_protocol = {
 	.handler	= dccp_v4_rcv,
 	.err_handler	= dccp_v4_err,
@@ -149,6 +152,8 @@
 	return err;
 }
 
+EXPORT_SYMBOL_GPL(dccp_disconnect);
+
 /*
  *	Wait for a DCCP event.
  *
@@ -156,8 +161,8 @@
  *	take care of normal races (between the test and the event) and we don't
  *	go look at any of the socket buffers directly.
  */
-static unsigned int dccp_poll(struct file *file, struct socket *sock,
-			      poll_table *wait)
+unsigned int dccp_poll(struct file *file, struct socket *sock,
+		       poll_table *wait)
 {
 	unsigned int mask;
 	struct sock *sk = sock->sk;
@@ -205,12 +210,16 @@
 	return mask;
 }
 
+EXPORT_SYMBOL_GPL(dccp_poll);
+
 int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 {
 	dccp_pr_debug("entry\n");
 	return -ENOIOCTLCMD;
 }
 
+EXPORT_SYMBOL_GPL(dccp_ioctl);
+
 static int dccp_setsockopt_service(struct sock *sk, const u32 service,
 				   char __user *optval, int optlen)
 {
@@ -254,7 +263,9 @@
 	int val;
 
 	if (level != SOL_DCCP)
-		return ip_setsockopt(sk, level, optname, optval, optlen);
+		return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
+							     optname, optval,
+							     optlen);
 
 	if (optlen < sizeof(int))
 		return -EINVAL;
@@ -282,6 +293,8 @@
 	return err;
 }
 
+EXPORT_SYMBOL_GPL(dccp_setsockopt);
+
 static int dccp_getsockopt_service(struct sock *sk, int len,
 				   u32 __user *optval,
 				   int __user *optlen)
@@ -320,8 +333,9 @@
 	int val, len;
 
 	if (level != SOL_DCCP)
-		return ip_getsockopt(sk, level, optname, optval, optlen);
-
+		return inet_csk(sk)->icsk_af_ops->getsockopt(sk, level,
+							     optname, optval,
+							     optlen);
 	if (get_user(len, optlen))
 		return -EFAULT;
 
@@ -354,6 +368,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(dccp_getsockopt);
+
 int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		 size_t len)
 {
@@ -410,6 +426,8 @@
 	goto out_release;
 }
 
+EXPORT_SYMBOL_GPL(dccp_sendmsg);
+
 int dccp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		 size_t len, int nonblock, int flags, int *addr_len)
 {
@@ -507,7 +525,9 @@
 	return len;
 }
 
-static int inet_dccp_listen(struct socket *sock, int backlog)
+EXPORT_SYMBOL_GPL(dccp_recvmsg);
+
+int inet_dccp_listen(struct socket *sock, int backlog)
 {
 	struct sock *sk = sock->sk;
 	unsigned char old_state;
@@ -543,6 +563,8 @@
 	return err;
 }
 
+EXPORT_SYMBOL_GPL(inet_dccp_listen);
+
 static const unsigned char dccp_new_state[] = {
 	/* current state:   new state:      action:	*/
 	[0]		  = DCCP_CLOSED,
@@ -648,12 +670,16 @@
 	sock_put(sk);
 }
 
+EXPORT_SYMBOL_GPL(dccp_close);
+
 void dccp_shutdown(struct sock *sk, int how)
 {
 	dccp_pr_debug("entry\n");
 }
 
-static struct proto_ops inet_dccp_ops = {
+EXPORT_SYMBOL_GPL(dccp_shutdown);
+
+static const struct proto_ops inet_dccp_ops = {
 	.family		= PF_INET,
 	.owner		= THIS_MODULE,
 	.release	= inet_release,
@@ -681,11 +707,11 @@
 static struct inet_protosw dccp_v4_protosw = {
 	.type		= SOCK_DCCP,
 	.protocol	= IPPROTO_DCCP,
-	.prot		= &dccp_v4_prot,
+	.prot		= &dccp_prot,
 	.ops		= &inet_dccp_ops,
 	.capability	= -1,
 	.no_check	= 0,
-	.flags		= 0,
+	.flags		= INET_PROTOSW_ICSK,
 };
 
 /*
@@ -760,13 +786,15 @@
 int dccp_debug;
 module_param(dccp_debug, int, 0444);
 MODULE_PARM_DESC(dccp_debug, "Enable debug messages");
+
+EXPORT_SYMBOL_GPL(dccp_debug);
 #endif
 
 static int __init dccp_init(void)
 {
 	unsigned long goal;
 	int ehash_order, bhash_order, i;
-	int rc = proto_register(&dccp_v4_prot, 1);
+	int rc = proto_register(&dccp_prot, 1);
 
 	if (rc)
 		goto out;
@@ -869,7 +897,7 @@
 	kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
 	dccp_hashinfo.bind_bucket_cachep = NULL;
 out_proto_unregister:
-	proto_unregister(&dccp_v4_prot);
+	proto_unregister(&dccp_prot);
 	goto out;
 }
 
@@ -892,7 +920,7 @@
 		   get_order(dccp_hashinfo.ehash_size *
 			     sizeof(struct inet_ehash_bucket)));
 	kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
-	proto_unregister(&dccp_v4_prot);
+	proto_unregister(&dccp_prot);
 }
 
 module_init(dccp_init);
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index f89e55f..78ec534 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -149,10 +149,11 @@
 #define DN_SK_HASH_MASK (DN_SK_HASH_SIZE - 1)
 
 
-static struct proto_ops dn_proto_ops;
+static const struct proto_ops dn_proto_ops;
 static DEFINE_RWLOCK(dn_hash_lock);
 static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
 static struct hlist_head dn_wild_sk;
+static atomic_t decnet_memory_allocated;
 
 static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen, int flags);
 static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
@@ -446,10 +447,26 @@
 	dst_release(xchg(&sk->sk_dst_cache, NULL));
 }
 
+static int dn_memory_pressure;
+
+static void dn_enter_memory_pressure(void)
+{
+	if (!dn_memory_pressure) {
+		dn_memory_pressure = 1;
+	}
+}
+
 static struct proto dn_proto = {
-	.name	  = "DECNET",
-	.owner	  = THIS_MODULE,
-	.obj_size = sizeof(struct dn_sock),
+	.name			= "NSP",
+	.owner			= THIS_MODULE,
+	.enter_memory_pressure	= dn_enter_memory_pressure,
+	.memory_pressure	= &dn_memory_pressure,
+	.memory_allocated	= &decnet_memory_allocated,
+	.sysctl_mem		= sysctl_decnet_mem,
+	.sysctl_wmem		= sysctl_decnet_wmem,
+	.sysctl_rmem		= sysctl_decnet_rmem,
+	.max_header		= DN_MAX_NSP_DATA_HEADER + 64,
+	.obj_size		= sizeof(struct dn_sock),
 };
 
 static struct sock *dn_alloc_sock(struct socket *sock, gfp_t gfp)
@@ -470,6 +487,8 @@
 	sk->sk_family      = PF_DECnet;
 	sk->sk_protocol    = 0;
 	sk->sk_allocation  = gfp;
+	sk->sk_sndbuf	   = sysctl_decnet_wmem[1];
+	sk->sk_rcvbuf	   = sysctl_decnet_rmem[1];
 
 	/* Initialization of DECnet Session Control Port		*/
 	scp = DN_SK(sk);
@@ -1233,7 +1252,7 @@
 		break;
 
 	default:
-		err = dev_ioctl(cmd, (void __user *)arg);
+		err = -ENOIOCTLCMD;
 		break;
 	}
 
@@ -2323,7 +2342,7 @@
 	.owner	=	THIS_MODULE,
 };
 
-static struct proto_ops dn_proto_ops = {
+static const struct proto_ops dn_proto_ops = {
 	.family =	AF_DECnet,
 	.owner =	THIS_MODULE,
 	.release =	dn_release,
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 8d0cc3c..33ab256 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -408,11 +408,14 @@
 			}
 		}
 
-		if (!dn_db->router) {
-			dn_db->router = neigh_clone(neigh);
-		} else {
-			if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority)
-				neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
+		/* Only use routers in our area */
+		if ((dn_ntohs(src)>>10) == dn_ntohs((decnet_address)>>10)) {
+			if (!dn_db->router) {
+				dn_db->router = neigh_clone(neigh);
+			} else {
+				if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority)
+					neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
+			}
 		}
 		write_unlock(&neigh->lock);
 		neigh_release(neigh);
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
index 369f25b..44bda85 100644
--- a/net/decnet/dn_nsp_in.c
+++ b/net/decnet/dn_nsp_in.c
@@ -793,7 +793,6 @@
 got_it:
 	if (sk != NULL) {
 		struct dn_scp *scp = DN_SK(sk);
-		int ret;
 
 		/* Reset backoff */
 		scp->nsp_rxtshift = 0;
@@ -807,21 +806,7 @@
 				goto free_out;
 		}
 
-		bh_lock_sock(sk);
-		ret = NET_RX_SUCCESS;
-		if (decnet_debug_level & 8)
-			printk(KERN_DEBUG "NSP: 0x%02x 0x%02x 0x%04x 0x%04x %d\n",
-				(int)cb->rt_flags, (int)cb->nsp_flags, 
-				(int)cb->src_port, (int)cb->dst_port, 
-				!!sock_owned_by_user(sk));
-		if (!sock_owned_by_user(sk))
-			ret = dn_nsp_backlog_rcv(sk, skb);
-		else
-			sk_add_backlog(sk, skb);
-		bh_unlock_sock(sk);
-		sock_put(sk);
-
-		return ret;
+		return sk_receive_skb(sk, skb);
 	}
 
 	return dn_nsp_no_socket(skb, reason);
diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c
index 02bca49..0e9d2c5 100644
--- a/net/decnet/sysctl_net_decnet.c
+++ b/net/decnet/sysctl_net_decnet.c
@@ -10,6 +10,7 @@
  *
  * Changes:
  * Steve Whitehouse - C99 changes and default device handling
+ * Steve Whitehouse - Memory buffer settings, like the tcp ones
  *
  */
 #include <linux/config.h>
@@ -37,6 +38,11 @@
 int decnet_log_martians = 1;
 int decnet_no_fc_max_cwnd = NSP_MIN_WINDOW;
 
+/* Reasonable defaults, I hope, based on tcp's defaults */
+int sysctl_decnet_mem[3] = { 768 << 3, 1024 << 3, 1536 << 3 };
+int sysctl_decnet_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
+int sysctl_decnet_rmem[3] = { 4 * 1024, 87380, 87380 * 2 };
+
 #ifdef CONFIG_SYSCTL
 extern int decnet_dst_gc_interval;
 static int min_decnet_time_wait[] = { 5 };
@@ -428,6 +434,33 @@
 		.extra1 = &min_decnet_no_fc_max_cwnd,
 		.extra2 = &max_decnet_no_fc_max_cwnd
 	},
+       {
+                .ctl_name = NET_DECNET_MEM,
+                .procname = "decnet_mem",
+                .data = &sysctl_decnet_mem,
+                .maxlen = sizeof(sysctl_decnet_mem),
+                .mode = 0644,
+                .proc_handler = &proc_dointvec,
+                .strategy = &sysctl_intvec,
+        },
+        {
+                .ctl_name = NET_DECNET_RMEM,
+                .procname = "decnet_rmem",
+                .data = &sysctl_decnet_rmem,
+                .maxlen = sizeof(sysctl_decnet_rmem),
+                .mode = 0644,
+                .proc_handler = &proc_dointvec,
+                .strategy = &sysctl_intvec,
+        },
+        {
+                .ctl_name = NET_DECNET_WMEM,
+                .procname = "decnet_wmem",
+                .data = &sysctl_decnet_wmem,
+                .maxlen = sizeof(sysctl_decnet_wmem),
+                .mode = 0644,
+                .proc_handler = &proc_dointvec,
+                .strategy = &sysctl_intvec,
+        },
 	{
 		.ctl_name = NET_DECNET_DEBUG_LEVEL,
 		.procname = "debug",
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
index 34fdac5..c792994 100644
--- a/net/econet/af_econet.c
+++ b/net/econet/af_econet.c
@@ -31,6 +31,7 @@
 #include <linux/if_arp.h>
 #include <linux/wireless.h>
 #include <linux/skbuff.h>
+#include <linux/udp.h>
 #include <net/sock.h>
 #include <net/inet_common.h>
 #include <linux/stat.h>
@@ -45,7 +46,7 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
-static struct proto_ops econet_ops;
+static const struct proto_ops econet_ops;
 static struct hlist_head econet_sklist;
 static DEFINE_RWLOCK(econet_lock);
 
@@ -56,7 +57,7 @@
 #define EC_PORT_IP	0xd2
 
 #ifdef CONFIG_ECONET_AUNUDP
-static spinlock_t aun_queue_lock;
+static DEFINE_SPINLOCK(aun_queue_lock);
 static struct socket *udpsock;
 #define AUN_PORT	0x8000
 
@@ -686,7 +687,7 @@
 			break;
 
 		default:
-			return dev_ioctl(cmd, argp);
+			return -ENOIOCTLCMD;
 	}
 	/*NOTREACHED*/
 	return 0;
@@ -698,7 +699,7 @@
 	.owner	=	THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
 	.family =	PF_ECONET,
 	.owner =	THIS_MODULE,
 	.release =	econet_release,
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index e245773..9890fd9 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -53,6 +53,7 @@
 #include <linux/errno.h>
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/if_ether.h>
 #include <net/dst.h>
 #include <net/arp.h>
 #include <net/sock.h>
@@ -162,7 +163,7 @@
 	skb_pull(skb,ETH_HLEN);
 	eth = eth_hdr(skb);
 	
-	if (*eth->h_dest&1) {
+	if (is_multicast_ether_addr(eth->h_dest)) {
 		if (!compare_ether_addr(eth->h_dest, dev->broadcast))
 			skb->pkt_type = PACKET_BROADCAST;
 		else
@@ -251,7 +252,7 @@
 
 static int eth_change_mtu(struct net_device *dev, int new_mtu)
 {
-	if ((new_mtu < 68) || (new_mtu > 1500))
+	if (new_mtu < 68 || new_mtu > ETH_DATA_LEN)
 		return -EINVAL;
 	dev->mtu = new_mtu;
 	return 0;
@@ -272,7 +273,7 @@
 
 	dev->type		= ARPHRD_ETHER;
 	dev->hard_header_len 	= ETH_HLEN;
-	dev->mtu		= 1500; /* eth_mtu */
+	dev->mtu		= ETH_DATA_LEN;
 	dev->addr_len		= ETH_ALEN;
 	dev->tx_queue_len	= 1000;	/* Ethernet wants good queues */	
 	dev->flags		= IFF_BROADCAST|IFF_MULTICAST;
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index 91b16fb..d18ccba 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -55,7 +55,7 @@
 
 config IEEE80211_CRYPT_TKIP
 	tristate "IEEE 802.11i TKIP encryption"
-	depends on IEEE80211
+	depends on IEEE80211 && NET_RADIO
 	select CRYPTO
 	select CRYPTO_MICHAEL_MIC
 	---help---
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 03efaac..4cc6f41 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -410,9 +410,8 @@
 		return 1;
 	}
 
-	if ((is_multicast_ether_addr(hdr->addr1) ||
-	     is_broadcast_ether_addr(hdr->addr2)) ? ieee->host_mc_decrypt :
-	    ieee->host_decrypt) {
+	if (is_multicast_ether_addr(hdr->addr1)
+	    ? ieee->host_mc_decrypt : ieee->host_decrypt) {
 		int idx = 0;
 		if (skb->len >= hdrlen + 3)
 			idx = skb->data[hdrlen + 3] >> 6;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index e55136a..011cca7 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -456,6 +456,14 @@
 	increase provides TCP friendliness.
 	See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/
 
+config TCP_CONG_CUBIC
+	tristate "CUBIC TCP"
+	default m
+	---help---
+	This is version 2.0 of BIC-TCP which uses a cubic growth function
+	among other techniques.
+	See http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/cubic-paper.pdf
+
 config TCP_CONG_WESTWOOD
 	tristate "TCP Westwood+"
 	default m
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index f0435d0..c54edd7 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -34,6 +34,7 @@
 obj-$(CONFIG_IP_ROUTE_MULTIPATH_CACHED) += multipath.o
 obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
 obj-$(CONFIG_TCP_CONG_BIC) += tcp_bic.o
+obj-$(CONFIG_TCP_CONG_CUBIC) += tcp_cubic.o
 obj-$(CONFIG_TCP_CONG_WESTWOOD) += tcp_westwood.o
 obj-$(CONFIG_TCP_CONG_HSTCP) += tcp_highspeed.o
 obj-$(CONFIG_TCP_CONG_HYBLA) += tcp_hybla.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index eaa150c..966a071 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -93,6 +93,7 @@
 #include <linux/smp_lock.h>
 #include <linux/inet.h>
 #include <linux/igmp.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <net/ip.h>
 #include <net/protocol.h>
@@ -228,13 +229,14 @@
 	unsigned char answer_flags;
 	char answer_no_check;
 	int try_loading_module = 0;
-	int err = -ESOCKTNOSUPPORT;
+	int err;
 
 	sock->state = SS_UNCONNECTED;
 
 	/* Look for the requested type/protocol pair. */
 	answer = NULL;
 lookup_protocol:
+	err = -ESOCKTNOSUPPORT;
 	rcu_read_lock();
 	list_for_each_rcu(p, &inetsw[sock->type]) {
 		answer = list_entry(p, struct inet_protosw, list);
@@ -252,6 +254,7 @@
 			if (IPPROTO_IP == answer->protocol)
 				break;
 		}
+		err = -EPROTONOSUPPORT;
 		answer = NULL;
 	}
 
@@ -280,9 +283,6 @@
 	err = -EPERM;
 	if (answer->capability > 0 && !capable(answer->capability))
 		goto out_rcu_unlock;
-	err = -EPROTONOSUPPORT;
-	if (!protocol)
-		goto out_rcu_unlock;
 
 	sock->ops = answer->ops;
 	answer_prot = answer->prot;
@@ -303,6 +303,7 @@
 		sk->sk_reuse = 1;
 
 	inet = inet_sk(sk);
+	inet->is_icsk = INET_PROTOSW_ICSK & answer_flags;
 
 	if (SOCK_RAW == sock->type) {
 		inet->num = protocol;
@@ -776,16 +777,16 @@
 			err = devinet_ioctl(cmd, (void __user *)arg);
 			break;
 		default:
-			if (!sk->sk_prot->ioctl ||
-			    (err = sk->sk_prot->ioctl(sk, cmd, arg)) ==
-			    					-ENOIOCTLCMD)
-				err = dev_ioctl(cmd, (void __user *)arg);
+			if (sk->sk_prot->ioctl)
+				err = sk->sk_prot->ioctl(sk, cmd, arg);
+			else
+				err = -ENOIOCTLCMD;
 			break;
 	}
 	return err;
 }
 
-struct proto_ops inet_stream_ops = {
+const struct proto_ops inet_stream_ops = {
 	.family =	PF_INET,
 	.owner =	THIS_MODULE,
 	.release =	inet_release,
@@ -806,7 +807,7 @@
 	.sendpage =	tcp_sendpage
 };
 
-struct proto_ops inet_dgram_ops = {
+const struct proto_ops inet_dgram_ops = {
 	.family =	PF_INET,
 	.owner =	THIS_MODULE,
 	.release =	inet_release,
@@ -831,7 +832,7 @@
  * For SOCK_RAW sockets; should be the same as inet_dgram_ops but without
  * udp_poll
  */
-static struct proto_ops inet_sockraw_ops = {
+static const struct proto_ops inet_sockraw_ops = {
 	.family =	PF_INET,
 	.owner =	THIS_MODULE,
 	.release =	inet_release,
@@ -870,7 +871,8 @@
                 .ops =        &inet_stream_ops,
                 .capability = -1,
                 .no_check =   0,
-                .flags =      INET_PROTOSW_PERMANENT,
+                .flags =      INET_PROTOSW_PERMANENT |
+			      INET_PROTOSW_ICSK,
         },
 
         {
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 035ad2c..aed537f 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -6,6 +6,7 @@
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
 #include <net/icmp.h>
+#include <net/protocol.h>
 #include <asm/scatterlist.h>
 
 
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index b425748..3743208 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -86,6 +86,7 @@
 #include <linux/in.h>
 #include <linux/mm.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/fddidevice.h>
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 04a6fe3..7b9bb28 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -58,6 +58,7 @@
 #endif
 #include <linux/kmod.h>
 
+#include <net/arp.h>
 #include <net/ip.h>
 #include <net/route.h>
 #include <net/ip_fib.h>
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 1b18ce6..73bfcae 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -9,6 +9,7 @@
 #include <linux/pfkeyv2.h>
 #include <linux/random.h>
 #include <net/icmp.h>
+#include <net/protocol.h>
 #include <net/udp.h>
 
 /* decapsulation data for use when post-processing */
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 882f88f..18f5e50 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -30,6 +30,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
@@ -544,12 +545,16 @@
 	struct sk_buff *skb = NULL;
         struct nlmsghdr *nlh = NULL;
 	struct fib_result_nl *frn;
-	int err;
 	u32 pid;     
 	struct fib_table *tb;
 	
-	skb = skb_recv_datagram(sk, 0, 0, &err);
+	skb = skb_dequeue(&sk->sk_receive_queue);
 	nlh = (struct nlmsghdr *)skb->data;
+	if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len ||
+	    nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) {
+		kfree_skb(skb);
+		return;
+	}
 	
 	frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
 	tb = fib_get_table(frn->tb_id_in);
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 2a8c9af..e2890ec 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -29,6 +29,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
@@ -975,7 +976,7 @@
 
 static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi)
 {
-	static unsigned type2flags[RTN_MAX + 1] = {
+	static const unsigned type2flags[RTN_MAX + 1] = {
 		[7] = RTF_REJECT, [8] = RTF_REJECT,
 	};
 	unsigned flags = type2flags[type];
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 0b298bb..0dd4d06 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -33,6 +33,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 186f20c..ef4724d 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -29,6 +29,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
@@ -36,6 +37,7 @@
 #include <linux/netlink.h>
 #include <linux/init.h>
 
+#include <net/arp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/route.h>
@@ -83,7 +85,7 @@
 #define endfor_nexthops(fi) }
 
 
-static struct 
+static const struct 
 {
 	int	error;
 	u8	scope;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 705e3ce..e320b32 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -41,6 +41,13 @@
  *		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.
+ *
+ * Substantial contributions to this work comes from:
+ *
+ *		David S. Miller, <davem@davemloft.net>
+ *		Stephen Hemminger <shemminger@osdl.org>
+ *		Paul E. McKenney <paulmck@us.ibm.com>
+ *		Patrick McHardy <kaber@trash.net>
  */
 
 #define VERSION "0.404"
@@ -59,6 +66,7 @@
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/proc_fs.h>
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index e3eceec..be5a519 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -73,6 +73,7 @@
 #include <linux/socket.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/string.h>
 #include <linux/netfilter_ipv4.h>
@@ -220,7 +221,7 @@
 	short   error;		/* This ICMP is classed as an error message */
 };
 
-static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
+static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1];
 
 /*
  *	The ICMP socket(s). This is the most convenient way to flow control
@@ -994,7 +995,7 @@
 /*
  *	This table is the definition of how we handle ICMP.
  */
-static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = {
+static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = {
 	[ICMP_ECHOREPLY] = {
 		.output_entry = ICMP_MIB_OUTECHOREPS,
 		.input_entry = ICMP_MIB_INECHOREPS,
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index c04607b..3475811 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -91,6 +91,8 @@
 #include <linux/if_arp.h>
 #include <linux/rtnetlink.h>
 #include <linux/times.h>
+
+#include <net/arp.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <net/route.h>
@@ -897,7 +899,10 @@
 		/* Is it our report looped back? */
 		if (((struct rtable*)skb->dst)->fl.iif == 0)
 			break;
-		igmp_heard_report(in_dev, ih->group);
+		/* don't rely on MC router hearing unicast reports */
+		if (skb->pkt_type == PACKET_MULTICAST ||
+		    skb->pkt_type == PACKET_BROADCAST)
+			igmp_heard_report(in_dev, ih->group);
 		break;
 	case IGMP_PIM:
 #ifdef CONFIG_IP_PIMSM_V1
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 3fe021f..ae20281 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -37,7 +37,8 @@
  */
 int sysctl_local_port_range[2] = { 1024, 4999 };
 
-static inline int inet_csk_bind_conflict(struct sock *sk, struct inet_bind_bucket *tb)
+int inet_csk_bind_conflict(const struct sock *sk,
+			   const struct inet_bind_bucket *tb)
 {
 	const u32 sk_rcv_saddr = inet_rcv_saddr(sk);
 	struct sock *sk2;
@@ -62,11 +63,15 @@
 	return node != NULL;
 }
 
+EXPORT_SYMBOL_GPL(inet_csk_bind_conflict);
+
 /* Obtain a reference to a local port for the given sock,
  * if snum is zero it means select any available local port.
  */
 int inet_csk_get_port(struct inet_hashinfo *hashinfo,
-		      struct sock *sk, unsigned short snum)
+		      struct sock *sk, unsigned short snum,
+		      int (*bind_conflict)(const struct sock *sk,
+					   const struct inet_bind_bucket *tb))
 {
 	struct inet_bind_hashbucket *head;
 	struct hlist_node *node;
@@ -125,7 +130,7 @@
 			goto success;
 		} else {
 			ret = 1;
-			if (inet_csk_bind_conflict(sk, tb))
+			if (bind_conflict(sk, tb))
 				goto fail_unlock;
 		}
 	}
@@ -380,7 +385,7 @@
 EXPORT_SYMBOL_GPL(inet_csk_search_req);
 
 void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req,
-				   const unsigned timeout)
+				   unsigned long timeout)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
@@ -631,3 +636,15 @@
 }
 
 EXPORT_SYMBOL_GPL(inet_csk_listen_stop);
+
+void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
+{
+	struct sockaddr_in *sin = (struct sockaddr_in *)uaddr;
+	const struct inet_sock *inet = inet_sk(sk);
+
+	sin->sin_family		= AF_INET;
+	sin->sin_addr.s_addr	= inet->daddr;
+	sin->sin_port		= inet->dport;
+}
+
+EXPORT_SYMBOL_GPL(inet_csk_addr2sockaddr);
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 39061ed..c499081 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -112,12 +112,12 @@
 		r->idiag_inode = 0;
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 		if (r->idiag_family == AF_INET6) {
-			const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk);
+			const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
 
 			ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
-				       &tcp6tw->tw_v6_rcv_saddr);
+				       &tw6->tw_v6_rcv_saddr);
 			ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
-				       &tcp6tw->tw_v6_daddr);
+				       &tw6->tw_v6_daddr);
 		}
 #endif
 		nlh->nlmsg_len = skb->tail - b;
@@ -489,9 +489,9 @@
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 	if (r->idiag_family == AF_INET6) {
 		ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
-			       &tcp6_rsk(req)->loc_addr);
+			       &inet6_rsk(req)->loc_addr);
 		ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
-			       &tcp6_rsk(req)->rmt_addr);
+			       &inet6_rsk(req)->rmt_addr);
 	}
 #endif
 	nlh->nlmsg_len = skb->tail - b;
@@ -553,13 +553,13 @@
 				entry.saddr =
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 					(entry.family == AF_INET6) ?
-					tcp6_rsk(req)->loc_addr.s6_addr32 :
+					inet6_rsk(req)->loc_addr.s6_addr32 :
 #endif
 					&ireq->loc_addr;
 				entry.daddr = 
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 					(entry.family == AF_INET6) ?
-					tcp6_rsk(req)->rmt_addr.s6_addr32 :
+					inet6_rsk(req)->rmt_addr.s6_addr32 :
 #endif
 					&ireq->rmt_addr;
 				entry.dport = ntohs(ireq->rmt_port);
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index e8d29fe..3322811 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -15,12 +15,14 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/random.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_hashtables.h>
+#include <net/ip.h>
 
 /*
  * Allocate and initialize a new local port bind bucket.
@@ -163,3 +165,179 @@
 }
 
 EXPORT_SYMBOL_GPL(__inet_lookup_listener);
+
+/* called with local bh disabled */
+static int __inet_check_established(struct inet_timewait_death_row *death_row,
+				    struct sock *sk, __u16 lport,
+				    struct inet_timewait_sock **twp)
+{
+	struct inet_hashinfo *hinfo = death_row->hashinfo;
+	struct inet_sock *inet = inet_sk(sk);
+	u32 daddr = inet->rcv_saddr;
+	u32 saddr = inet->daddr;
+	int dif = sk->sk_bound_dev_if;
+	INET_ADDR_COOKIE(acookie, saddr, daddr)
+	const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+	unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
+	struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+	struct sock *sk2;
+	const struct hlist_node *node;
+	struct inet_timewait_sock *tw;
+
+	prefetch(head->chain.first);
+	write_lock(&head->lock);
+
+	/* Check TIME-WAIT sockets first. */
+	sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) {
+		tw = inet_twsk(sk2);
+
+		if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
+			if (twsk_unique(sk, sk2, twp))
+				goto unique;
+			else
+				goto not_unique;
+		}
+	}
+	tw = NULL;
+
+	/* And established part... */
+	sk_for_each(sk2, node, &head->chain) {
+		if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
+			goto not_unique;
+	}
+
+unique:
+	/* Must record num and sport now. Otherwise we will see
+	 * in hash table socket with a funny identity. */
+	inet->num = lport;
+	inet->sport = htons(lport);
+	sk->sk_hash = hash;
+	BUG_TRAP(sk_unhashed(sk));
+	__sk_add_node(sk, &head->chain);
+	sock_prot_inc_use(sk->sk_prot);
+	write_unlock(&head->lock);
+
+	if (twp) {
+		*twp = tw;
+		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+	} else if (tw) {
+		/* Silly. Should hash-dance instead... */
+		inet_twsk_deschedule(tw, death_row);
+		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+
+		inet_twsk_put(tw);
+	}
+
+	return 0;
+
+not_unique:
+	write_unlock(&head->lock);
+	return -EADDRNOTAVAIL;
+}
+
+static inline u32 inet_sk_port_offset(const struct sock *sk)
+{
+	const struct inet_sock *inet = inet_sk(sk);
+	return secure_ipv4_port_ephemeral(inet->rcv_saddr, inet->daddr, 
+					  inet->dport);
+}
+
+/*
+ * Bind a port for a connect operation and hash it.
+ */
+int inet_hash_connect(struct inet_timewait_death_row *death_row,
+		      struct sock *sk)
+{
+	struct inet_hashinfo *hinfo = death_row->hashinfo;
+	const unsigned short snum = inet_sk(sk)->num;
+ 	struct inet_bind_hashbucket *head;
+ 	struct inet_bind_bucket *tb;
+	int ret;
+
+ 	if (!snum) {
+ 		int low = sysctl_local_port_range[0];
+ 		int high = sysctl_local_port_range[1];
+		int range = high - low;
+ 		int i;
+		int port;
+		static u32 hint;
+		u32 offset = hint + inet_sk_port_offset(sk);
+		struct hlist_node *node;
+ 		struct inet_timewait_sock *tw = NULL;
+
+ 		local_bh_disable();
+		for (i = 1; i <= range; i++) {
+			port = low + (i + offset) % range;
+ 			head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
+ 			spin_lock(&head->lock);
+
+ 			/* Does not bother with rcv_saddr checks,
+ 			 * because the established check is already
+ 			 * unique enough.
+ 			 */
+			inet_bind_bucket_for_each(tb, node, &head->chain) {
+ 				if (tb->port == port) {
+ 					BUG_TRAP(!hlist_empty(&tb->owners));
+ 					if (tb->fastreuse >= 0)
+ 						goto next_port;
+ 					if (!__inet_check_established(death_row,
+								      sk, port,
+								      &tw))
+ 						goto ok;
+ 					goto next_port;
+ 				}
+ 			}
+
+ 			tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep, head, port);
+ 			if (!tb) {
+ 				spin_unlock(&head->lock);
+ 				break;
+ 			}
+ 			tb->fastreuse = -1;
+ 			goto ok;
+
+ 		next_port:
+ 			spin_unlock(&head->lock);
+ 		}
+ 		local_bh_enable();
+
+ 		return -EADDRNOTAVAIL;
+
+ok:
+		hint += i;
+
+ 		/* Head lock still held and bh's disabled */
+ 		inet_bind_hash(sk, tb, port);
+		if (sk_unhashed(sk)) {
+ 			inet_sk(sk)->sport = htons(port);
+ 			__inet_hash(hinfo, sk, 0);
+ 		}
+ 		spin_unlock(&head->lock);
+
+ 		if (tw) {
+ 			inet_twsk_deschedule(tw, death_row);;
+ 			inet_twsk_put(tw);
+ 		}
+
+		ret = 0;
+		goto out;
+ 	}
+
+ 	head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
+ 	tb  = inet_csk(sk)->icsk_bind_hash;
+	spin_lock_bh(&head->lock);
+	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
+		__inet_hash(hinfo, sk, 0);
+		spin_unlock_bh(&head->lock);
+		return 0;
+	} else {
+		spin_unlock(&head->lock);
+		/* No definite answer... Walk to established hash table */
+		ret = __inet_check_established(death_row, sk, snum, NULL);
+out:
+		local_bh_enable();
+		return ret;
+	}
+}
+
+EXPORT_SYMBOL_GPL(inet_hash_connect);
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index a010e9a..417f126 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -90,8 +90,9 @@
 
 struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state)
 {
-	struct inet_timewait_sock *tw = kmem_cache_alloc(sk->sk_prot_creator->twsk_slab,
-							 SLAB_ATOMIC);
+	struct inet_timewait_sock *tw =
+		kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab,
+				 SLAB_ATOMIC);
 	if (tw != NULL) {
 		const struct inet_sock *inet = inet_sk(sk);
 
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 2fc3fd3..ce5fe3f 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -401,6 +401,7 @@
 		return NULL;
 	n->v4daddr = daddr;
 	atomic_set(&n->refcnt, 1);
+	atomic_set(&n->rid, 0);
 	n->ip_id_count = secure_ip_id(daddr);
 	n->tcp_ts_stamp = 0;
 
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 8ce0ce2..2a8adda 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -22,6 +22,7 @@
  *		Patrick McHardy :	LRU queue of frag heads for evictor.
  */
 
+#include <linux/compiler.h>
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -38,6 +39,7 @@
 #include <net/ip.h>
 #include <net/icmp.h>
 #include <net/checksum.h>
+#include <net/inetpeer.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/inet.h>
@@ -56,6 +58,8 @@
 int sysctl_ipfrag_high_thresh = 256*1024;
 int sysctl_ipfrag_low_thresh = 192*1024;
 
+int sysctl_ipfrag_max_dist = 64;
+
 /* Important NOTE! Fragment queue must be destroyed before MSL expires.
  * RFC791 is wrong proposing to prolongate timer each fragment arrival by TTL.
  */
@@ -89,8 +93,10 @@
 	spinlock_t	lock;
 	atomic_t	refcnt;
 	struct timer_list timer;	/* when will this queue expire?		*/
-	int		iif;
 	struct timeval	stamp;
+	int             iif;
+	unsigned int    rid;
+	struct inet_peer *peer;
 };
 
 /* Hash table. */
@@ -195,6 +201,9 @@
 	BUG_TRAP(qp->last_in&COMPLETE);
 	BUG_TRAP(del_timer(&qp->timer) == 0);
 
+	if (qp->peer)
+		inet_putpeer(qp->peer);
+
 	/* Release all fragment data. */
 	fp = qp->fragments;
 	while (fp) {
@@ -353,6 +362,7 @@
 	qp->meat = 0;
 	qp->fragments = NULL;
 	qp->iif = 0;
+	qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL;
 
 	/* Initialize a timer for this entry. */
 	init_timer(&qp->timer);
@@ -373,7 +383,7 @@
  */
 static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
 {
-	__u16 id = iph->id;
+	__be16 id = iph->id;
 	__u32 saddr = iph->saddr;
 	__u32 daddr = iph->daddr;
 	__u8 protocol = iph->protocol;
@@ -398,6 +408,56 @@
 	return ip_frag_create(hash, iph, user);
 }
 
+/* Is the fragment too far ahead to be part of ipq? */
+static inline int ip_frag_too_far(struct ipq *qp)
+{
+	struct inet_peer *peer = qp->peer;
+	unsigned int max = sysctl_ipfrag_max_dist;
+	unsigned int start, end;
+
+	int rc;
+
+	if (!peer || !max)
+		return 0;
+
+	start = qp->rid;
+	end = atomic_inc_return(&peer->rid);
+	qp->rid = end;
+
+	rc = qp->fragments && (end - start) > max;
+
+	if (rc) {
+		IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS);
+	}
+
+	return rc;
+}
+
+static int ip_frag_reinit(struct ipq *qp)
+{
+	struct sk_buff *fp;
+
+	if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time)) {
+		atomic_inc(&qp->refcnt);
+		return -ETIMEDOUT;
+	}
+
+	fp = qp->fragments;
+	do {
+		struct sk_buff *xp = fp->next;
+		frag_kfree_skb(fp, NULL);
+		fp = xp;
+	} while (fp);
+
+	qp->last_in = 0;
+	qp->len = 0;
+	qp->meat = 0;
+	qp->fragments = NULL;
+	qp->iif = 0;
+
+	return 0;
+}
+
 /* Add new segment to existing queue. */
 static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 {
@@ -408,6 +468,12 @@
 	if (qp->last_in & COMPLETE)
 		goto err;
 
+	if (!(IPCB(skb)->flags & IPSKB_FRAG_COMPLETE) &&
+	    unlikely(ip_frag_too_far(qp)) && unlikely(ip_frag_reinit(qp))) {
+		ipq_kill(qp);
+		goto err;
+	}
+
  	offset = ntohs(skb->nh.iph->frag_off);
 	flags = offset & ~IP_OFFSET;
 	offset &= IP_OFFSET;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 4e9c74b..de16e94 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -28,6 +28,7 @@
 #include <linux/inetdevice.h>
 #include <linux/igmp.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/if_ether.h>
 
 #include <net/sock.h>
 #include <net/ip.h>
@@ -618,7 +619,7 @@
 
 		skb->mac.raw = skb->nh.raw;
 		skb->nh.raw = __pskb_pull(skb, offset);
-		skb_postpull_rcsum(skb, skb->mac.raw, offset);
+		skb_postpull_rcsum(skb, skb->h.raw, offset);
 		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
 		skb->pkt_type = PACKET_HOST;
 #ifdef CONFIG_NET_IPGRE_BROADCAST
@@ -831,6 +832,7 @@
 	skb->h.raw = skb->nh.raw;
 	skb->nh.raw = skb_push(skb, gre_hlen);
 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+	IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED);
 	dst_release(skb->dst);
 	skb->dst = &rt->u.dst;
 
@@ -1140,7 +1142,7 @@
 
 	dev->type		= ARPHRD_IPGRE;
 	dev->hard_header_len 	= LL_MAX_HEADER + sizeof(struct iphdr) + 4;
-	dev->mtu		= 1500 - sizeof(struct iphdr) - 4;
+	dev->mtu		= ETH_DATA_LEN - sizeof(struct iphdr) - 4;
 	dev->flags		= IFF_NOARP;
 	dev->iflink		= 0;
 	dev->addr_len		= 4;
@@ -1152,7 +1154,7 @@
 	struct ip_tunnel *tunnel;
 	struct iphdr *iph;
 	int hlen = LL_MAX_HEADER;
-	int mtu = 1500;
+	int mtu = ETH_DATA_LEN;
 	int addend = sizeof(struct iphdr) + 4;
 
 	tunnel = (struct ip_tunnel*)dev->priv;
@@ -1217,7 +1219,7 @@
 	return 0;
 }
 
-int __init ipgre_fb_tunnel_init(struct net_device *dev)
+static int __init ipgre_fb_tunnel_init(struct net_device *dev)
 {
 	struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
 	struct iphdr *iph = &tunnel->parms.iph;
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 473d0f2..18d7fad 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -128,6 +128,7 @@
 #include <linux/sockios.h>
 #include <linux/in.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 
@@ -184,7 +185,6 @@
 					raw_rcv(last, skb2);
 			}
 			last = sk;
-			nf_reset(skb);
 		}
 	}
 
@@ -203,10 +203,6 @@
 
 	__skb_pull(skb, ihl);
 
-	/* Free reference early: we don't need it any more, and it may
-           hold ip_conntrack module loaded indefinitely. */
-	nf_reset(skb);
-
         /* Point into the IP datagram, just past the header. */
         skb->h.raw = skb->data;
 
@@ -231,10 +227,12 @@
 		if ((ipprot = rcu_dereference(inet_protos[hash])) != NULL) {
 			int ret;
 
-			if (!ipprot->no_policy &&
-			    !xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
-				kfree_skb(skb);
-				goto out;
+			if (!ipprot->no_policy) {
+				if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
+					kfree_skb(skb);
+					goto out;
+				}
+				nf_reset(skb);
 			}
 			ret = ipprot->handler(skb);
 			if (ret < 0) {
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index dbe12da..d3f6c46 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -22,6 +22,7 @@
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
+#include <net/route.h>
 
 /* 
  * Write options to IP header, record destination address to
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 11c2f68..c2169b4 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -85,6 +85,8 @@
 
 int sysctl_ip_default_ttl = IPDEFTTL;
 
+static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*));
+
 /* Generate a checksum for an outgoing IP datagram. */
 __inline__ void ip_send_check(struct iphdr *iph)
 {
@@ -202,13 +204,16 @@
 
 static inline int ip_finish_output(struct sk_buff *skb)
 {
-	struct net_device *dev = skb->dst->dev;
-
-	skb->dev = dev;
-	skb->protocol = htons(ETH_P_IP);
-
-	return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
-		       ip_finish_output2);
+#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
+	/* Policy lookup after SNAT yielded a new policy */
+	if (skb->dst->xfrm != NULL)
+		return xfrm4_output_finish(skb);
+#endif
+	if (skb->len > dst_mtu(skb->dst) &&
+	    !(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
+		return ip_fragment(skb, ip_finish_output2);
+	else
+		return ip_finish_output2(skb);
 }
 
 int ip_mc_output(struct sk_buff *skb)
@@ -265,21 +270,21 @@
 				newskb->dev, ip_dev_loopback_xmit);
 	}
 
-	if (skb->len > dst_mtu(&rt->u.dst))
-		return ip_fragment(skb, ip_finish_output);
-	else
-		return ip_finish_output(skb);
+	return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dev,
+		       ip_finish_output);
 }
 
 int ip_output(struct sk_buff *skb)
 {
+	struct net_device *dev = skb->dst->dev;
+
 	IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
 
-	if (skb->len > dst_mtu(skb->dst) &&
-		!(skb_shinfo(skb)->ufo_size || skb_shinfo(skb)->tso_size))
-		return ip_fragment(skb, ip_finish_output);
-	else
-		return ip_finish_output(skb);
+	skb->dev = dev;
+	skb->protocol = htons(ETH_P_IP);
+
+	return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
+		       ip_finish_output);
 }
 
 int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
@@ -411,7 +416,7 @@
  *	single device frame, and queue such a frame for sending.
  */
 
-int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
+static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
 {
 	struct iphdr *iph;
 	int raw = 0;
@@ -420,7 +425,7 @@
 	struct sk_buff *skb2;
 	unsigned int mtu, hlen, left, len, ll_rs;
 	int offset;
-	int not_last_frag;
+	__be16 not_last_frag;
 	struct rtable *rt = (struct rtable*)skb->dst;
 	int err = 0;
 
@@ -445,6 +450,7 @@
 
 	hlen = iph->ihl * 4;
 	mtu = dst_mtu(&rt->u.dst) - hlen;	/* Size of data space */
+	IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
 
 	/* When frag_list is given, use it. First, check its validity:
 	 * some transformers could create wrong frag_list or break existing
@@ -690,7 +696,7 @@
 	return csum;
 }
 
-inline int ip_ufo_append_data(struct sock *sk,
+static inline int ip_ufo_append_data(struct sock *sk,
 			int getfrag(void *from, char *to, int offset, int len,
 			       int odd, struct sk_buff *skb),
 			void *from, int length, int hh_len, int fragheaderlen,
@@ -1181,7 +1187,7 @@
 	struct ip_options *opt = NULL;
 	struct rtable *rt = inet->cork.rt;
 	struct iphdr *iph;
-	int df = 0;
+	__be16 df = 0;
 	__u8 ttl;
 	int err = 0;
 
@@ -1392,7 +1398,6 @@
 #endif
 }
 
-EXPORT_SYMBOL(ip_fragment);
 EXPORT_SYMBOL(ip_generic_getfrag);
 EXPORT_SYMBOL(ip_queue_xmit);
 EXPORT_SYMBOL(ip_send_check);
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 4f2d872..6986e11d 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -25,12 +25,12 @@
 #include <linux/skbuff.h>
 #include <linux/ip.h>
 #include <linux/icmp.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
-#include <net/tcp.h>
-#include <linux/tcp.h>
+#include <net/tcp_states.h>
 #include <linux/udp.h>
 #include <linux/igmp.h>
 #include <linux/netfilter.h>
@@ -427,8 +427,8 @@
 			err = ip_options_get_from_user(&opt, optval, optlen);
 			if (err)
 				break;
-			if (sk->sk_type == SOCK_STREAM) {
-				struct tcp_sock *tp = tcp_sk(sk);
+			if (inet->is_icsk) {
+				struct inet_connection_sock *icsk = inet_csk(sk);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 				if (sk->sk_family == PF_INET ||
 				    (!((1 << sk->sk_state) &
@@ -436,10 +436,10 @@
 				     inet->daddr != LOOPBACK4_IPV6)) {
 #endif
 					if (inet->opt)
-						tp->ext_header_len -= inet->opt->optlen;
+						icsk->icsk_ext_hdr_len -= inet->opt->optlen;
 					if (opt)
-						tp->ext_header_len += opt->optlen;
-					tcp_sync_mss(sk, tp->pmtu_cookie);
+						icsk->icsk_ext_hdr_len += opt->optlen;
+					icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 				}
 #endif
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index fc718df..d64e2ec 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -28,6 +28,7 @@
 #include <net/xfrm.h>
 #include <net/icmp.h>
 #include <net/ipcomp.h>
+#include <net/protocol.h>
 
 struct ipcomp_tfms {
 	struct list_head list;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index e8674ba..bb3613e 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -42,6 +42,7 @@
 #include <linux/in.h>
 #include <linux/if.h>
 #include <linux/inet.h>
+#include <linux/inetdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
@@ -58,6 +59,7 @@
 #include <net/arp.h>
 #include <net/ip.h>
 #include <net/ipconfig.h>
+#include <net/route.h>
 
 #include <asm/uaccess.h>
 #include <net/checksum.h>
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index c05c1df..bbd85f5 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -108,6 +108,7 @@
 #include <linux/mroute.h>
 #include <linux/init.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/if_ether.h>
 
 #include <net/sock.h>
 #include <net/ip.h>
@@ -620,6 +621,7 @@
 	skb->h.raw = skb->nh.raw;
 	skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+	IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE|IPSKB_XFRM_TRANSFORMED);
 	dst_release(skb->dst);
 	skb->dst = &rt->u.dst;
 
@@ -786,7 +788,7 @@
 
 	dev->type		= ARPHRD_TUNNEL;
 	dev->hard_header_len 	= LL_MAX_HEADER + sizeof(struct iphdr);
-	dev->mtu		= 1500 - sizeof(struct iphdr);
+	dev->mtu		= ETH_DATA_LEN - sizeof(struct iphdr);
 	dev->flags		= IFF_NOARP;
 	dev->iflink		= 0;
 	dev->addr_len		= 4;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 302b7eb..9a5c0ce 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -49,9 +49,11 @@
 #include <linux/seq_file.h>
 #include <linux/mroute.h>
 #include <linux/init.h>
+#include <linux/if_ether.h>
 #include <net/ip.h>
 #include <net/protocol.h>
 #include <linux/skbuff.h>
+#include <net/route.h>
 #include <net/sock.h>
 #include <net/icmp.h>
 #include <net/udp.h>
@@ -192,7 +194,7 @@
 static void reg_vif_setup(struct net_device *dev)
 {
 	dev->type		= ARPHRD_PIMREG;
-	dev->mtu		= 1500 - sizeof(struct iphdr) - 8;
+	dev->mtu		= ETH_DATA_LEN - sizeof(struct iphdr) - 8;
 	dev->flags		= IFF_NOARP;
 	dev->hard_start_xmit	= reg_vif_xmit;
 	dev->get_stats		= reg_vif_get_stats;
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index d7eb680..9b176a9 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -224,34 +224,6 @@
 }
 
 
-#if 0000
-/*
- *	Get reference to app by name (called from user context)
- */
-struct ip_vs_app *ip_vs_app_get_by_name(char *appname)
-{
-	struct ip_vs_app *app, *a = NULL;
-
-	down(&__ip_vs_app_mutex);
-
-	list_for_each_entry(ent, &ip_vs_app_list, a_list) {
-		if (strcmp(app->name, appname))
-			continue;
-
-		/* softirq may call ip_vs_app_get too, so the caller
-		   must disable softirq on the current CPU */
-		if (ip_vs_app_get(app))
-			a = app;
-		break;
-	}
-
-	up(&__ip_vs_app_mutex);
-
-	return a;
-}
-#endif
-
-
 /*
  *	Bind ip_vs_conn to its ip_vs_app (called by cp constructor)
  */
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index f828fa2..87b8381 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -24,7 +24,11 @@
  *
  */
 
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/net.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/vmalloc.h>
 #include <linux/proc_fs.h>		/* for proc_net_* */
 #include <linux/seq_file.h>
@@ -219,7 +223,7 @@
 	if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt))
 		cp = __ip_vs_conn_in_get(protocol, s_addr, 0, d_addr, d_port);
 
-	IP_VS_DBG(7, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+	IP_VS_DBG(9, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
 		  ip_vs_proto_name(protocol),
 		  NIPQUAD(s_addr), ntohs(s_port),
 		  NIPQUAD(d_addr), ntohs(d_port),
@@ -254,7 +258,7 @@
   out:
 	ct_read_unlock(hash);
 
-	IP_VS_DBG(7, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+	IP_VS_DBG(9, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
 		  ip_vs_proto_name(protocol),
 		  NIPQUAD(s_addr), ntohs(s_port),
 		  NIPQUAD(d_addr), ntohs(d_port),
@@ -295,7 +299,7 @@
 
 	ct_read_unlock(hash);
 
-	IP_VS_DBG(7, "lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
+	IP_VS_DBG(9, "lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n",
 		  ip_vs_proto_name(protocol),
 		  NIPQUAD(s_addr), ntohs(s_port),
 		  NIPQUAD(d_addr), ntohs(d_port),
@@ -391,8 +395,9 @@
 	cp->flags |= atomic_read(&dest->conn_flags);
 	cp->dest = dest;
 
-	IP_VS_DBG(9, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
-		  "d:%u.%u.%u.%u:%d fwd:%c s:%u flg:%X cnt:%d destcnt:%d\n",
+	IP_VS_DBG(7, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
+		  "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
+		  "dest->refcnt:%d\n",
 		  ip_vs_proto_name(cp->protocol),
 		  NIPQUAD(cp->caddr), ntohs(cp->cport),
 		  NIPQUAD(cp->vaddr), ntohs(cp->vport),
@@ -430,8 +435,9 @@
 	if (!dest)
 		return;
 
-	IP_VS_DBG(9, "Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
-		  "d:%u.%u.%u.%u:%d fwd:%c s:%u flg:%X cnt:%d destcnt:%d\n",
+	IP_VS_DBG(7, "Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d "
+		  "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
+		  "dest->refcnt:%d\n",
 		  ip_vs_proto_name(cp->protocol),
 		  NIPQUAD(cp->caddr), ntohs(cp->cport),
 		  NIPQUAD(cp->vaddr), ntohs(cp->vport),
@@ -571,7 +577,7 @@
 	ip_vs_conn_hash(cp);
 
   expire_later:
-	IP_VS_DBG(7, "delayed: refcnt-1=%d conn.n_control=%d\n",
+	IP_VS_DBG(7, "delayed: conn->refcnt-1=%d conn->n_control=%d\n",
 		  atomic_read(&cp->refcnt)-1,
 		  atomic_read(&cp->n_control));
 
@@ -771,7 +777,7 @@
 	 * The drop rate array needs tuning for real environments.
 	 * Called from timer bh only => no locking
 	 */
-	static char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+	static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
 	static char todrop_counter[9] = {0};
 	int i;
 
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 1a0843c..3f47ad8 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -426,7 +426,7 @@
 		return NULL;
 
 	IP_VS_DBG(6, "Schedule fwd:%c c:%u.%u.%u.%u:%u v:%u.%u.%u.%u:%u "
-		  "d:%u.%u.%u.%u:%u flg:%X cnt:%d\n",
+		  "d:%u.%u.%u.%u:%u conn->flags:%X conn->refcnt:%d\n",
 		  ip_vs_fwd_tag(cp),
 		  NIPQUAD(cp->caddr), ntohs(cp->cport),
 		  NIPQUAD(cp->vaddr), ntohs(cp->vport),
@@ -532,11 +532,8 @@
 {
 	if (!((*pskb)->ipvs_property))
 		return NF_ACCEPT;
-
 	/* The packet was sent from IPVS, exit this chain */
-	(*okfn)(*pskb);
-
-	return NF_STOLEN;
+	return NF_STOP;
 }
 
 u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 2d66848..c935c50 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -35,6 +35,7 @@
 #include <linux/netfilter_ipv4.h>
 
 #include <net/ip.h>
+#include <net/route.h>
 #include <net/sock.h>
 
 #include <asm/uaccess.h>
@@ -447,7 +448,7 @@
   out:
 	read_unlock(&__ip_vs_svc_lock);
 
-	IP_VS_DBG(6, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n",
+	IP_VS_DBG(9, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n",
 		  fwmark, ip_vs_proto_name(protocol),
 		  NIPQUAD(vaddr), ntohs(vport),
 		  svc?"hit":"not hit");
@@ -597,7 +598,7 @@
 	 */
 	list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) {
 		IP_VS_DBG(3, "Destination %u/%u.%u.%u.%u:%u still in trash, "
-			  "refcnt=%d\n",
+			  "dest->refcnt=%d\n",
 			  dest->vfwmark,
 			  NIPQUAD(dest->addr), ntohs(dest->port),
 			  atomic_read(&dest->refcnt));
@@ -804,7 +805,7 @@
 	dest = ip_vs_trash_get_dest(svc, daddr, dport);
 	if (dest != NULL) {
 		IP_VS_DBG(3, "Get destination %u.%u.%u.%u:%u from trash, "
-			  "refcnt=%d, service %u/%u.%u.%u.%u:%u\n",
+			  "dest->refcnt=%d, service %u/%u.%u.%u.%u:%u\n",
 			  NIPQUAD(daddr), ntohs(dport),
 			  atomic_read(&dest->refcnt),
 			  dest->vfwmark,
@@ -949,7 +950,8 @@
 		atomic_dec(&dest->svc->refcnt);
 		kfree(dest);
 	} else {
-		IP_VS_DBG(3, "Moving dest %u.%u.%u.%u:%u into trash, refcnt=%d\n",
+		IP_VS_DBG(3, "Moving dest %u.%u.%u.%u:%u into trash, "
+			  "dest->refcnt=%d\n",
 			  NIPQUAD(dest->addr), ntohs(dest->port),
 			  atomic_read(&dest->refcnt));
 		list_add(&dest->n_list, &ip_vs_dest_trash);
@@ -1909,7 +1911,7 @@
 #define DAEMON_ARG_LEN		(sizeof(struct ip_vs_daemon_user))
 #define MAX_ARG_LEN		SVCDEST_ARG_LEN
 
-static unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = {
+static const unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = {
 	[SET_CMDID(IP_VS_SO_SET_ADD)]		= SERVICE_ARG_LEN,
 	[SET_CMDID(IP_VS_SO_SET_EDIT)]		= SERVICE_ARG_LEN,
 	[SET_CMDID(IP_VS_SO_SET_DEL)]		= SERVICE_ARG_LEN,
@@ -2180,7 +2182,7 @@
 #define GET_TIMEOUT_ARG_LEN	(sizeof(struct ip_vs_timeout_user))
 #define GET_DAEMON_ARG_LEN	(sizeof(struct ip_vs_daemon_user) * 2)
 
-static unsigned char get_arglen[GET_CMDID(IP_VS_SO_GET_MAX)+1] = {
+static const unsigned char get_arglen[GET_CMDID(IP_VS_SO_GET_MAX)+1] = {
 	[GET_CMDID(IP_VS_SO_GET_VERSION)]	= 64,
 	[GET_CMDID(IP_VS_SO_GET_INFO)]		= GET_INFO_ARG_LEN,
 	[GET_CMDID(IP_VS_SO_GET_SERVICES)]	= GET_SERVICES_ARG_LEN,
diff --git a/net/ipv4/ipvs/ip_vs_dh.c b/net/ipv4/ipvs/ip_vs_dh.c
index f3bc320..9fee19c 100644
--- a/net/ipv4/ipvs/ip_vs_dh.c
+++ b/net/ipv4/ipvs/ip_vs_dh.c
@@ -37,8 +37,10 @@
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 #include <net/ip_vs.h>
 
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c
index 67b3e2f..c453e1e 100644
--- a/net/ipv4/ipvs/ip_vs_est.c
+++ b/net/ipv4/ipvs/ip_vs_est.c
@@ -13,8 +13,12 @@
  * Changes:
  *
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/interrupt.h>
 
 #include <net/ip_vs.h>
 
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c
index 561cda3..6e5cb92 100644
--- a/net/ipv4/ipvs/ip_vs_lblc.c
+++ b/net/ipv4/ipvs/ip_vs_lblc.c
@@ -41,8 +41,10 @@
  * me to write this module.
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 /* for sysctl */
 #include <linux/fs.h>
@@ -228,33 +230,6 @@
 }
 
 
-#if 0000
-/*
- *	Unhash ip_vs_lblc_entry from ip_vs_lblc_table.
- *	returns bool success.
- */
-static int ip_vs_lblc_unhash(struct ip_vs_lblc_table *tbl,
-			     struct ip_vs_lblc_entry *en)
-{
-	if (list_empty(&en->list)) {
-		IP_VS_ERR("ip_vs_lblc_unhash(): request for not hashed entry, "
-			  "called from %p\n", __builtin_return_address(0));
-		return 0;
-	}
-
-	/*
-	 * Remove it from the table
-	 */
-	write_lock(&tbl->lock);
-	list_del(&en->list);
-	INIT_LIST_HEAD(&en->list);
-	write_unlock(&tbl->lock);
-
-	return 1;
-}
-#endif
-
-
 /*
  *  Get ip_vs_lblc_entry associated with supplied parameters.
  */
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c
index ce456db..32ba37b 100644
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/ipv4/ipvs/ip_vs_lblcr.c
@@ -39,8 +39,10 @@
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 /* for sysctl */
 #include <linux/fs.h>
@@ -414,33 +416,6 @@
 }
 
 
-#if 0000
-/*
- *	Unhash ip_vs_lblcr_entry from ip_vs_lblcr_table.
- *	returns bool success.
- */
-static int ip_vs_lblcr_unhash(struct ip_vs_lblcr_table *tbl,
-			     struct ip_vs_lblcr_entry *en)
-{
-	if (list_empty(&en->list)) {
-		IP_VS_ERR("ip_vs_lblcr_unhash(): request for not hashed entry, "
-			  "called from %p\n", __builtin_return_address(0));
-		return 0;
-	}
-
-	/*
-	 * Remove it from the table
-	 */
-	write_lock(&tbl->lock);
-	list_del(&en->list);
-	INIT_LIST_HEAD(&en->list);
-	write_unlock(&tbl->lock);
-
-	return 1;
-}
-#endif
-
-
 /*
  *  Get ip_vs_lblcr_entry associated with supplied parameters.
  */
diff --git a/net/ipv4/ipvs/ip_vs_proto_ah.c b/net/ipv4/ipvs/ip_vs_proto_ah.c
index 453e94a..8b0505b 100644
--- a/net/ipv4/ipvs/ip_vs_proto_ah.c
+++ b/net/ipv4/ipvs/ip_vs_proto_ah.c
@@ -12,6 +12,8 @@
  *
  */
 
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/netfilter.h>
diff --git a/net/ipv4/ipvs/ip_vs_proto_esp.c b/net/ipv4/ipvs/ip_vs_proto_esp.c
index 478e5c7c..c36ccf0 100644
--- a/net/ipv4/ipvs/ip_vs_proto_esp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_esp.c
@@ -12,6 +12,8 @@
  *
  */
 
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/netfilter.h>
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index c194089..bc28b11 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -251,7 +251,7 @@
 #define TCP_DIR_OUTPUT		4
 #define TCP_DIR_INPUT_ONLY	8
 
-static int tcp_state_off[IP_VS_DIR_LAST] = {
+static const int tcp_state_off[IP_VS_DIR_LAST] = {
 	[IP_VS_DIR_INPUT]		=	TCP_DIR_INPUT,
 	[IP_VS_DIR_OUTPUT]		=	TCP_DIR_OUTPUT,
 	[IP_VS_DIR_INPUT_ONLY]		=	TCP_DIR_INPUT_ONLY,
@@ -275,28 +275,6 @@
 	[IP_VS_TCP_S_LAST]		=	2*HZ,
 };
 
-
-#if 0
-
-/* FIXME: This is going to die */
-
-static int tcp_timeouts_dos[IP_VS_TCP_S_LAST+1] = {
-	[IP_VS_TCP_S_NONE]		=	2*HZ,
-	[IP_VS_TCP_S_ESTABLISHED]	=	8*60*HZ,
-	[IP_VS_TCP_S_SYN_SENT]		=	60*HZ,
-	[IP_VS_TCP_S_SYN_RECV]		=	10*HZ,
-	[IP_VS_TCP_S_FIN_WAIT]		=	60*HZ,
-	[IP_VS_TCP_S_TIME_WAIT]		=	60*HZ,
-	[IP_VS_TCP_S_CLOSE]		=	10*HZ,
-	[IP_VS_TCP_S_CLOSE_WAIT]	=	60*HZ,
-	[IP_VS_TCP_S_LAST_ACK]		=	30*HZ,
-	[IP_VS_TCP_S_LISTEN]		=	2*60*HZ,
-	[IP_VS_TCP_S_SYNACK]		=	100*HZ,
-	[IP_VS_TCP_S_LAST]		=	2*HZ,
-};
-
-#endif
-
 static char * tcp_state_name_table[IP_VS_TCP_S_LAST+1] = {
 	[IP_VS_TCP_S_NONE]		=	"NONE",
 	[IP_VS_TCP_S_ESTABLISHED]	=	"ESTABLISHED",
@@ -448,7 +426,7 @@
 		struct ip_vs_dest *dest = cp->dest;
 
 		IP_VS_DBG(8, "%s %s [%c%c%c%c] %u.%u.%u.%u:%d->"
-			  "%u.%u.%u.%u:%d state: %s->%s cnt:%d\n",
+			  "%u.%u.%u.%u:%d state: %s->%s conn->refcnt:%d\n",
 			  pp->name,
 			  (state_off==TCP_DIR_OUTPUT)?"output ":"input ",
 			  th->syn? 'S' : '.',
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 8ae5f2e..89d9175 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -15,8 +15,11 @@
  *
  */
 
+#include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/kernel.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/udp.h>
 
 #include <net/ip_vs.h>
 
diff --git a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c
index 0f7c56a..8bc42b7 100644
--- a/net/ipv4/ipvs/ip_vs_sched.c
+++ b/net/ipv4/ipvs/ip_vs_sched.c
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/spinlock.h>
+#include <linux/interrupt.h>
 #include <asm/string.h>
 #include <linux/kmod.h>
 
diff --git a/net/ipv4/ipvs/ip_vs_sh.c b/net/ipv4/ipvs/ip_vs_sh.c
index 6f7c50e..7775e6c 100644
--- a/net/ipv4/ipvs/ip_vs_sh.c
+++ b/net/ipv4/ipvs/ip_vs_sh.c
@@ -34,8 +34,10 @@
  *
  */
 
+#include <linux/ip.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/skbuff.h>
 
 #include <net/ip_vs.h>
 
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 2e5ced3..1bca714 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -21,12 +21,14 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/inetdevice.h>
 #include <linux/net.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
 #include <linux/igmp.h>                 /* for ip_mc_join_group */
+#include <linux/udp.h>
 
 #include <net/ip.h>
 #include <net/sock.h>
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c
index 3b87482..52c12e9 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/ipv4/ipvs/ip_vs_xmit.c
@@ -322,7 +322,7 @@
 	struct net_device *tdev;		/* Device to other host */
 	struct iphdr  *old_iph = skb->nh.iph;
 	u8     tos = old_iph->tos;
-	u16    df = old_iph->frag_off;
+	__be16 df = old_iph->frag_off;
 	struct iphdr  *iph;			/* Our new IP header */
 	int    max_headroom;			/* The extra header space needed */
 	int    mtu;
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index ae0779d..3321092 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -7,11 +7,13 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4.h>
 
+#include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
 #include <linux/icmp.h>
 #include <net/route.h>
-#include <linux/ip.h>
+#include <net/xfrm.h>
+#include <net/ip.h>
 
 /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
 int ip_route_me_harder(struct sk_buff **pskb)
@@ -33,7 +35,6 @@
 #ifdef CONFIG_IP_ROUTE_FWMARK
 		fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark;
 #endif
-		fl.proto = iph->protocol;
 		if (ip_route_output_key(&rt, &fl) != 0)
 			return -1;
 
@@ -60,6 +61,13 @@
 	if ((*pskb)->dst->error)
 		return -1;
 
+#ifdef CONFIG_XFRM
+	if (!(IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED) &&
+	    xfrm_decode_session(*pskb, &fl, AF_INET) == 0)
+		if (xfrm_lookup(&(*pskb)->dst, &fl, (*pskb)->sk, 0))
+			return -1;
+#endif
+
 	/* Change in oif may mean change in hh_len. */
 	hh_len = (*pskb)->dst->dev->hard_header_len;
 	if (skb_headroom(*pskb) < hh_len) {
@@ -78,6 +86,9 @@
 }
 EXPORT_SYMBOL(ip_route_me_harder);
 
+void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *);
+EXPORT_SYMBOL(ip_nat_decode_session);
+
 /*
  * Extra routing may needed on local out, as the QUEUE target never
  * returns control to the table.
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 0bc0052..a9893ec 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -56,8 +56,8 @@
 	  instead of the individual packets.
 	
 config IP_NF_CONNTRACK_EVENTS
-	bool "Connection tracking events"
-	depends on IP_NF_CONNTRACK
+	bool "Connection tracking events (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && IP_NF_CONNTRACK
 	help
 	  If this option is enabled, the connection tracking code will
 	  provide a notifier chain that can be used by other kernel code
@@ -66,8 +66,8 @@
 	  IF unsure, say `N'.
 
 config IP_NF_CONNTRACK_NETLINK
-	tristate 'Connection tracking netlink interface'
-	depends on IP_NF_CONNTRACK && NETFILTER_NETLINK
+	tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
+	depends on EXPERIMENTAL && IP_NF_CONNTRACK && NETFILTER_NETLINK
 	depends on IP_NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
 	help
 	  This option enables support for a netlink-based userspace interface
@@ -487,6 +487,16 @@
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config IP_NF_MATCH_POLICY
+       tristate "IPsec policy match support"
+       depends on IP_NF_IPTABLES && XFRM
+       help
+         Policy matching allows you to match packets based on the
+         IPsec policy that was used during decapsulation/will
+         be used during encapsulation.
+
+         To compile it as a module, choose M here.  If unsure, say N.
+
 # `filter', generic and specific targets
 config IP_NF_FILTER
 	tristate "Packet filtering"
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 058c48e..549b01a 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -12,6 +12,7 @@
 
 # connection tracking
 obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
+obj-$(CONFIG_IP_NF_NAT) += ip_nat.o
 
 # conntrack netlink interface
 obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o
@@ -41,7 +42,7 @@
 # the three instances of ip_tables
 obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
 obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
-obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o ip_nat.o
+obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
 obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
 
 # matches
@@ -71,6 +72,7 @@
 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
 obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o
+obj-$(CONFIG_IP_NF_MATCH_POLICY) += ipt_policy.o
 obj-$(CONFIG_IP_NF_MATCH_COMMENT) += ipt_comment.o
 obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
 
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 3c2e963..bba1563 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -68,19 +68,14 @@
 	unsigned int initial_entries;
 	unsigned int hook_entry[NF_ARP_NUMHOOKS];
 	unsigned int underflow[NF_ARP_NUMHOOKS];
-	char entries[0] __attribute__((aligned(SMP_CACHE_BYTES)));
+	void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(arpt_target);
 static LIST_HEAD(arpt_tables);
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
-
 static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
 				      char *hdr_addr, int len)
 {
@@ -269,9 +264,7 @@
 	outdev = out ? out->name : nulldevname;
 
 	read_lock_bh(&table->lock);
-	table_base = (void *)table->private->entries
-		+ TABLE_OFFSET(table->private,
-			       smp_processor_id());
+	table_base = (void *)table->private->entries[smp_processor_id()];
 	e = get_entry(table_base, table->private->hook_entry[hook]);
 	back = get_entry(table_base, table->private->underflow[hook]);
 
@@ -462,7 +455,8 @@
 /* Figures out from what hook each rule can be called: returns 0 if
  * there are loops.  Puts hook bitmask in comefrom.
  */
-static int mark_source_chains(struct arpt_table_info *newinfo, unsigned int valid_hooks)
+static int mark_source_chains(struct arpt_table_info *newinfo,
+			      unsigned int valid_hooks, void *entry0)
 {
 	unsigned int hook;
 
@@ -472,7 +466,7 @@
 	for (hook = 0; hook < NF_ARP_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct arpt_entry *e
-			= (struct arpt_entry *)(newinfo->entries + pos);
+			= (struct arpt_entry *)(entry0 + pos);
 
 		if (!(valid_hooks & (1 << hook)))
 			continue;
@@ -514,13 +508,13 @@
 						goto next;
 
 					e = (struct arpt_entry *)
-						(newinfo->entries + pos);
+						(entry0 + pos);
 				} while (oldpos == pos + e->next_offset);
 
 				/* Move along one */
 				size = e->next_offset;
 				e = (struct arpt_entry *)
-					(newinfo->entries + pos + size);
+					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -537,7 +531,7 @@
 					newpos = pos + e->next_offset;
 				}
 				e = (struct arpt_entry *)
-					(newinfo->entries + newpos);
+					(entry0 + newpos);
 				e->counters.pcnt = pos;
 				pos = newpos;
 			}
@@ -689,6 +683,7 @@
 static int translate_table(const char *name,
 			   unsigned int valid_hooks,
 			   struct arpt_table_info *newinfo,
+			   void *entry0,
 			   unsigned int size,
 			   unsigned int number,
 			   const unsigned int *hook_entries,
@@ -710,11 +705,11 @@
 	i = 0;
 
 	/* Walk through entries, checking offsets. */
-	ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
 				 check_entry_size_and_hooks,
 				 newinfo,
-				 newinfo->entries,
-				 newinfo->entries + size,
+				 entry0,
+				 entry0 + size,
 				 hook_entries, underflows, &i);
 	duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
 	if (ret != 0)
@@ -743,29 +738,26 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks)) {
+	if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
 		duprintf("Looping hook\n");
 		return -ELOOP;
 	}
 
 	/* Finally, each sanity check must pass */
 	i = 0;
-	ret = ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
 				 check_entry, name, size, &i);
 
 	if (ret != 0) {
-		ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+		ARPT_ENTRY_ITERATE(entry0, newinfo->size,
 				   cleanup_entry, &i);
 		return ret;
 	}
 
 	/* And one copy for every other CPU */
 	for_each_cpu(i) {
-		if (i == 0)
-			continue;
-		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
-		       newinfo->entries,
-		       SMP_ALIGN(newinfo->size));
+		if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
 	return ret;
@@ -807,15 +799,42 @@
 	return 0;
 }
 
+static inline int set_entry_to_counter(const struct arpt_entry *e,
+				       struct arpt_counters total[],
+				       unsigned int *i)
+{
+	SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+	(*i)++;
+	return 0;
+}
+
 static void get_counters(const struct arpt_table_info *t,
 			 struct arpt_counters counters[])
 {
 	unsigned int cpu;
 	unsigned int i;
+	unsigned int curcpu;
+
+	/* Instead of clearing (by a previous call to memset())
+	 * the counters and using adds, we set the counters
+	 * with data used by 'current' CPU
+	 * We dont care about preemption here.
+	 */
+	curcpu = raw_smp_processor_id();
+
+	i = 0;
+	ARPT_ENTRY_ITERATE(t->entries[curcpu],
+			   t->size,
+			   set_entry_to_counter,
+			   counters,
+			   &i);
 
 	for_each_cpu(cpu) {
+		if (cpu == curcpu)
+			continue;
 		i = 0;
-		ARPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+		ARPT_ENTRY_ITERATE(t->entries[cpu],
 				   t->size,
 				   add_entry_to_counter,
 				   counters,
@@ -831,6 +850,7 @@
 	struct arpt_entry *e;
 	struct arpt_counters *counters;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	/* We need atomic snapshot of counters: rest doesn't change
 	 * (other than comefrom, which userspace doesn't care
@@ -843,13 +863,13 @@
 		return -ENOMEM;
 
 	/* First, sum counters... */
-	memset(counters, 0, countersize);
 	write_lock_bh(&table->lock);
 	get_counters(table->private, counters);
 	write_unlock_bh(&table->lock);
 
-	/* ... then copy entire thing from CPU 0... */
-	if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	/* ... then copy entire thing ... */
+	if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
 		ret = -EFAULT;
 		goto free_counters;
 	}
@@ -859,7 +879,7 @@
 	for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
 		struct arpt_entry_target *t;
 
-		e = (struct arpt_entry *)(table->private->entries + off);
+		e = (struct arpt_entry *)(loc_cpu_entry + off);
 		if (copy_to_user(userptr + off
 				 + offsetof(struct arpt_entry, counters),
 				 &counters[num],
@@ -911,6 +931,47 @@
 	return ret;
 }
 
+static void free_table_info(struct arpt_table_info *info)
+{
+	int cpu;
+	for_each_cpu(cpu) {
+		if (info->size <= PAGE_SIZE)
+			kfree(info->entries[cpu]);
+		else
+			vfree(info->entries[cpu]);
+	}
+	kfree(info);
+}
+
+static struct arpt_table_info *alloc_table_info(unsigned int size)
+{
+	struct arpt_table_info *newinfo;
+	int cpu;
+	
+	newinfo = kzalloc(sizeof(struct arpt_table_info), GFP_KERNEL);
+	if (!newinfo)
+		return NULL;
+
+	newinfo->size = size;
+
+	for_each_cpu(cpu) {
+		if (size <= PAGE_SIZE)
+			newinfo->entries[cpu] = kmalloc_node(size,
+							GFP_KERNEL,
+							cpu_to_node(cpu));
+		else
+			newinfo->entries[cpu] = vmalloc_node(size,
+							     cpu_to_node(cpu));
+
+		if (newinfo->entries[cpu] == NULL) {
+			free_table_info(newinfo);
+			return NULL;
+		}
+	}
+
+	return newinfo;
+}
+
 static int do_replace(void __user *user, unsigned int len)
 {
 	int ret;
@@ -918,6 +979,7 @@
 	struct arpt_table *t;
 	struct arpt_table_info *newinfo, *oldinfo;
 	struct arpt_counters *counters;
+	void *loc_cpu_entry, *loc_cpu_old_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -930,13 +992,13 @@
 	if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
 		return -ENOMEM;
 
-	newinfo = vmalloc(sizeof(struct arpt_table_info)
-			  + SMP_ALIGN(tmp.size) *
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+	/* choose the copy that is on our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
 			   tmp.size) != 0) {
 		ret = -EFAULT;
 		goto free_newinfo;
@@ -947,10 +1009,9 @@
 		ret = -ENOMEM;
 		goto free_newinfo;
 	}
-	memset(counters, 0, tmp.num_counters * sizeof(struct arpt_counters));
 
 	ret = translate_table(tmp.name, tmp.valid_hooks,
-			      newinfo, tmp.size, tmp.num_entries,
+			      newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
 			      tmp.hook_entry, tmp.underflow);
 	if (ret != 0)
 		goto free_newinfo_counters;
@@ -989,8 +1050,10 @@
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
 	/* Decrease module usage counts and free resource */
-	ARPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-	vfree(oldinfo);
+	loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+	ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+
+	free_table_info(oldinfo);
 	if (copy_to_user(tmp.counters, counters,
 			 sizeof(struct arpt_counters) * tmp.num_counters) != 0)
 		ret = -EFAULT;
@@ -1002,11 +1065,11 @@
 	module_put(t->me);
 	up(&arpt_mutex);
  free_newinfo_counters_untrans:
-	ARPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry, NULL);
+	ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL);
  free_newinfo_counters:
 	vfree(counters);
  free_newinfo:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	return ret;
 }
 
@@ -1030,6 +1093,7 @@
 	struct arpt_counters_info tmp, *paddc;
 	struct arpt_table *t;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1059,7 +1123,9 @@
 	}
 
 	i = 0;
-	ARPT_ENTRY_ITERATE(t->private->entries,
+	/* Choose the copy that is on our node */
+	loc_cpu_entry = t->private->entries[smp_processor_id()];
+	ARPT_ENTRY_ITERATE(loc_cpu_entry,
 			   t->private->size,
 			   add_counter_to_entry,
 			   paddc->counters,
@@ -1220,30 +1286,32 @@
 	struct arpt_table_info *newinfo;
 	static struct arpt_table_info bootstrap
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
+	void *loc_cpu_entry;
 
-	newinfo = vmalloc(sizeof(struct arpt_table_info)
-			  + SMP_ALIGN(repl->size) *
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(repl->size);
 	if (!newinfo) {
 		ret = -ENOMEM;
 		return ret;
 	}
-	memcpy(newinfo->entries, repl->entries, repl->size);
+
+	/* choose the copy on our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	memcpy(loc_cpu_entry, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, repl->size,
+			      newinfo, loc_cpu_entry, repl->size,
 			      repl->num_entries,
 			      repl->hook_entry,
 			      repl->underflow);
 	duprintf("arpt_register_table: translate table gives %d\n", ret);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
 	ret = down_interruptible(&arpt_mutex);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
@@ -1272,20 +1340,23 @@
 	return ret;
 
  free_unlock:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	goto unlock;
 }
 
 void arpt_unregister_table(struct arpt_table *table)
 {
+	void *loc_cpu_entry;
+
 	down(&arpt_mutex);
 	LIST_DELETE(&arpt_tables, table);
 	up(&arpt_mutex);
 
 	/* Decrease module usage counts and free resources */
-	ARPT_ENTRY_ITERATE(table->private->entries, table->private->size,
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	ARPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
 			   cleanup_entry, NULL);
-	vfree(table->private);
+	free_table_info(table->private);
 }
 
 /* The built-in targets: standard (NULL) and error. */
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index fa3f914..84e4f79 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -18,11 +18,13 @@
  *
  */
 
+#include <linux/in.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/netfilter.h>
 #include <linux/ip.h>
 #include <linux/moduleparam.h>
+#include <linux/udp.h>
 #include <net/checksum.h>
 #include <net/udp.h>
 
@@ -34,10 +36,10 @@
 MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
 MODULE_DESCRIPTION("Amanda connection tracking module");
 MODULE_LICENSE("GPL");
-module_param(master_timeout, int, 0600);
+module_param(master_timeout, uint, 0600);
 MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
 
-static char *conns[] = { "DATA ", "MESG ", "INDEX " };
+static const char *conns[] = { "DATA ", "MESG ", "INDEX " };
 
 /* This is slow, but it's simple. --RR */
 static char *amanda_buffer;
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 422ab68..84c66db 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -1345,6 +1345,11 @@
 	return 1;
 }
 
+void ip_conntrack_flush(void)
+{
+	ip_ct_iterate_cleanup(kill_all, NULL);
+}
+
 static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size)
 {
 	if (vmalloced)
@@ -1354,8 +1359,12 @@
 			   get_order(sizeof(struct list_head) * size));
 }
 
-void ip_conntrack_flush()
+/* Mishearing the voices in his head, our hero wonders how he's
+   supposed to kill the mall. */
+void ip_conntrack_cleanup(void)
 {
+	ip_ct_attach = NULL;
+
 	/* This makes sure all current packets have passed through
            netfilter framework.  Roll on, two-stage module
            delete... */
@@ -1363,7 +1372,7 @@
 
 	ip_ct_event_cache_flush();
  i_see_dead_people:
-	ip_ct_iterate_cleanup(kill_all, NULL);
+	ip_conntrack_flush();
 	if (atomic_read(&ip_conntrack_count) != 0) {
 		schedule();
 		goto i_see_dead_people;
@@ -1371,14 +1380,7 @@
 	/* wait until all references to ip_conntrack_untracked are dropped */
 	while (atomic_read(&ip_conntrack_untracked.ct_general.use) > 1)
 		schedule();
-}
 
-/* Mishearing the voices in his head, our hero wonders how he's
-   supposed to kill the mall. */
-void ip_conntrack_cleanup(void)
-{
-	ip_ct_attach = NULL;
-	ip_conntrack_flush();
 	kmem_cache_destroy(ip_conntrack_cachep);
 	kmem_cache_destroy(ip_conntrack_expect_cachep);
 	free_conntrack_hash(ip_conntrack_hash, ip_conntrack_vmalloc,
@@ -1408,7 +1410,7 @@
 	return hash;
 }
 
-int set_hashsize(const char *val, struct kernel_param *kp)
+static int set_hashsize(const char *val, struct kernel_param *kp)
 {
 	int i, bucket, hashsize, vmalloced;
 	int old_vmalloced, old_size;
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 59e12b0..e627e58 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -34,7 +34,7 @@
 module_param_array(ports, ushort, &ports_c, 0400);
 
 static int loose;
-module_param(loose, int, 0600);
+module_param(loose, bool, 0600);
 
 unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
 				enum ip_conntrack_info ctinfo,
@@ -55,7 +55,7 @@
 static int try_eprt(const char *, size_t, u_int32_t [], char);
 static int try_epsv_response(const char *, size_t, u_int32_t [], char);
 
-static struct ftp_search {
+static const struct ftp_search {
 	enum ip_conntrack_dir dir;
 	const char *pattern;
 	size_t plen;
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index 2dea1db..c51a2cf 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -36,7 +36,7 @@
 #define MAX_PORTS 8
 static unsigned short ports[MAX_PORTS];
 static int ports_c;
-static int max_dcc_channels = 8;
+static unsigned int max_dcc_channels = 8;
 static unsigned int dcc_timeout = 300;
 /* This is slow, but it's simple. --RR */
 static char *irc_buffer;
@@ -54,12 +54,12 @@
 MODULE_LICENSE("GPL");
 module_param_array(ports, ushort, &ports_c, 0400);
 MODULE_PARM_DESC(ports, "port numbers of IRC servers");
-module_param(max_dcc_channels, int, 0400);
+module_param(max_dcc_channels, uint, 0400);
 MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC session");
-module_param(dcc_timeout, int, 0400);
+module_param(dcc_timeout, uint, 0400);
 MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
 
-static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
+static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " };
 #define MINMATCHLEN	5
 
 #if 0
@@ -254,10 +254,6 @@
 		printk("ip_conntrack_irc: max_dcc_channels must be a positive integer\n");
 		return -EBUSY;
 	}
-	if (dcc_timeout < 0) {
-		printk("ip_conntrack_irc: dcc_timeout must be a positive integer\n");
-		return -EBUSY;
-	}
 
 	irc_buffer = kmalloc(65536, GFP_KERNEL);
 	if (!irc_buffer)
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
index 186646e..4e68e16 100644
--- a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
+++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
@@ -37,7 +37,7 @@
 MODULE_LICENSE("GPL");
 
 static unsigned int timeout = 3;
-module_param(timeout, int, 0600);
+module_param(timeout, uint, 0400);
 MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
 
 static int help(struct sk_buff **pskb,
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 3fce91b..c9ebbe0 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -79,6 +79,7 @@
 		      const struct ip_conntrack_tuple *tuple)
 {
 	struct nfattr *nest_parms;
+	int ret;
 	
 	nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
 	NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip);
@@ -86,10 +87,10 @@
 	NFA_NEST_END(skb, nest_parms);
 
 	nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
-	ctnetlink_dump_tuples_proto(skb, tuple);
+	ret = ctnetlink_dump_tuples_proto(skb, tuple);
 	NFA_NEST_END(skb, nest_parms);
 
-	return 0;
+	return ret;
 
 nfattr_failure:
 	return -1;
@@ -160,7 +161,7 @@
 		return 0;
 		
 	nest_helper = NFA_NEST(skb, CTA_HELP);
-	NFA_PUT(skb, CTA_HELP_NAME, CTA_HELP_MAXNAMESIZE, &ct->helper->name);
+	NFA_PUT(skb, CTA_HELP_NAME, strlen(ct->helper->name), ct->helper->name);
 
 	if (ct->helper->to_nfattr)
 		ct->helper->to_nfattr(skb, ct);
@@ -229,7 +230,7 @@
 static inline int
 ctnetlink_dump_use(struct sk_buff *skb, const struct ip_conntrack *ct)
 {
-	unsigned int use = htonl(atomic_read(&ct->ct_general.use));
+	u_int32_t use = htonl(atomic_read(&ct->ct_general.use));
 	
 	NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
 	return 0;
@@ -311,29 +312,22 @@
 	if (events & IPCT_DESTROY) {
 		type = IPCTNL_MSG_CT_DELETE;
 		group = NFNLGRP_CONNTRACK_DESTROY;
-		goto alloc_skb;
-	}
-	if (events & (IPCT_NEW | IPCT_RELATED)) {
+	} else if (events & (IPCT_NEW | IPCT_RELATED)) {
 		type = IPCTNL_MSG_CT_NEW;
 		flags = NLM_F_CREATE|NLM_F_EXCL;
 		/* dump everything */
 		events = ~0UL;
 		group = NFNLGRP_CONNTRACK_NEW;
-		goto alloc_skb;
-	}
-	if (events & (IPCT_STATUS |
+	} else if (events & (IPCT_STATUS |
 		      IPCT_PROTOINFO |
 		      IPCT_HELPER |
 		      IPCT_HELPINFO |
 		      IPCT_NATINFO)) {
 		type = IPCTNL_MSG_CT_NEW;
 		group = NFNLGRP_CONNTRACK_UPDATE;
-		goto alloc_skb;
-	} 
+	} else 
+		return NOTIFY_DONE;
 	
-	return NOTIFY_DONE;
-
-alloc_skb:
   /* FIXME: Check if there are any listeners before, don't hurt performance */
 	
 	skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
@@ -503,7 +497,7 @@
 }
 
 static const size_t cta_min_proto[CTA_PROTO_MAX] = {
-	[CTA_PROTO_NUM-1]	= sizeof(u_int16_t),
+	[CTA_PROTO_NUM-1]	= sizeof(u_int8_t),
 	[CTA_PROTO_SRC_PORT-1]	= sizeof(u_int16_t),
 	[CTA_PROTO_DST_PORT-1]	= sizeof(u_int16_t),
 	[CTA_PROTO_ICMP_TYPE-1]	= sizeof(u_int8_t),
@@ -528,7 +522,7 @@
 
 	if (!tb[CTA_PROTO_NUM-1])
 		return -EINVAL;
-	tuple->dst.protonum = *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
+	tuple->dst.protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
 
 	proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
 
@@ -728,11 +722,9 @@
 			return -ENOENT;
 		}
 	}	
-	if (del_timer(&ct->timeout)) {
-		ip_conntrack_put(ct);
+	if (del_timer(&ct->timeout))
 		ct->timeout.function((unsigned long)ct);
-		return 0;
-	}
+
 	ip_conntrack_put(ct);
 	DEBUGP("leaving\n");
 
@@ -877,7 +869,7 @@
 		DEBUGP("NAT status: %lu\n", 
 		       status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK));
 		
-		if (ip_nat_initialized(ct, hooknum))
+		if (ip_nat_initialized(ct, HOOK2MANIP(hooknum)))
 			return -EEXIST;
 		ip_nat_setup_info(ct, &range, hooknum);
 
@@ -1039,6 +1031,11 @@
 			return err;
 	}
 
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+	if (cda[CTA_MARK-1])
+		ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+#endif
+
 	ct->helper = ip_conntrack_helper_find_get(rtuple);
 
 	add_timer(&ct->timeout);
@@ -1047,11 +1044,6 @@
 	if (ct->helper)
 		ip_conntrack_helper_put(ct->helper);
 
-#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
-	if (cda[CTA_MARK-1])
-		ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
-#endif
-
 	DEBUGP("conntrack with id %u inserted\n", ct->id);
 	return 0;
 
@@ -1211,7 +1203,6 @@
 	unsigned int type;
 	unsigned char *b;
 	int flags = 0;
-	u16 proto;
 
 	if (events & IPEXP_NEW) {
 		type = IPCTNL_MSG_EXP_NEW;
@@ -1238,7 +1229,6 @@
 		goto nfattr_failure;
 
 	nlh->nlmsg_len = skb->tail - b;
-	proto = exp->tuple.dst.protonum;
 	nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0);
 	return NOTIFY_DONE;
 
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_gre.c b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
index 744abb9..57956de 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_gre.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
@@ -31,6 +31,7 @@
 #include <linux/ip.h>
 #include <linux/in.h>
 #include <linux/list.h>
+#include <linux/seq_file.h>
 
 static DEFINE_RWLOCK(ip_ct_gre_lock);
 #define ASSERT_READ_LOCK(x)
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index e4d6b26..30fc21d 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -47,20 +47,21 @@
 	return 1;
 }
 
+/* Add 1; spaces filled with 0. */
+static const u_int8_t invmap[] = {
+	[ICMP_ECHO] = ICMP_ECHOREPLY + 1,
+	[ICMP_ECHOREPLY] = ICMP_ECHO + 1,
+	[ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
+	[ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
+	[ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
+	[ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
+	[ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
+	[ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1
+};
+
 static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple,
 			     const struct ip_conntrack_tuple *orig)
 {
-	/* Add 1; spaces filled with 0. */
-	static u_int8_t invmap[]
-		= { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
-		    [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
-		    [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
-		    [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
-		    [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
-		    [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
-		    [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
-		    [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
-
 	if (orig->dst.u.icmp.type >= sizeof(invmap)
 	    || !invmap[orig->dst.u.icmp.type])
 		return 0;
@@ -110,17 +111,17 @@
 	return NF_ACCEPT;
 }
 
-static u_int8_t valid_new[] = { 
-	[ICMP_ECHO] = 1,
-	[ICMP_TIMESTAMP] = 1,
-	[ICMP_INFO_REQUEST] = 1,
-	[ICMP_ADDRESS] = 1 
-};
-
 /* Called when a new connection for this protocol found. */
 static int icmp_new(struct ip_conntrack *conntrack,
 		    const struct sk_buff *skb)
 {
+	static const u_int8_t valid_new[] = { 
+		[ICMP_ECHO] = 1,
+		[ICMP_TIMESTAMP] = 1,
+		[ICMP_INFO_REQUEST] = 1,
+		[ICMP_ADDRESS] = 1 
+	};
+
 	if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
 	    || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
 		/* Can't create a new ICMP `conn' with this. */
@@ -279,10 +280,6 @@
 	NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t),
 		&t->dst.u.icmp.code);
 
-	if (t->dst.u.icmp.type >= sizeof(valid_new) 
-	    || !valid_new[t->dst.u.icmp.type])
-		return -EINVAL;
-
 	return 0;
 
 nfattr_failure:
@@ -295,7 +292,7 @@
 	if (!tb[CTA_PROTO_ICMP_TYPE-1]
 	    || !tb[CTA_PROTO_ICMP_CODE-1]
 	    || !tb[CTA_PROTO_ICMP_ID-1])
-		return -1;
+		return -EINVAL;
 
 	tuple->dst.u.icmp.type = 
 			*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]);
@@ -304,6 +301,10 @@
 	tuple->src.u.icmp.id =
 			*(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
 
+	if (tuple->dst.u.icmp.type >= sizeof(invmap)
+	    || !invmap[tuple->dst.u.icmp.type])
+		return -EINVAL;
+
 	return 0;
 }
 #endif
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
index 59a4a01..0b25050 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
+#include <linux/interrupt.h>
 #include <linux/netfilter.h>
 #include <linux/module.h>
 #include <linux/in.h>
@@ -65,7 +66,7 @@
 static unsigned long ip_ct_sctp_timeout_shutdown_recd     = 300 SECS / 1000;
 static unsigned long ip_ct_sctp_timeout_shutdown_ack_sent =   3 SECS;
 
-static unsigned long * sctp_timeouts[]
+static const unsigned long * sctp_timeouts[]
 = { NULL,                                  /* SCTP_CONNTRACK_NONE  */
     &ip_ct_sctp_timeout_closed,	           /* SCTP_CONNTRACK_CLOSED */
     &ip_ct_sctp_timeout_cookie_wait,       /* SCTP_CONNTRACK_COOKIE_WAIT */
@@ -118,7 +119,7 @@
 */
 
 /* SCTP conntrack state transitions */
-static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
+static const enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
 	{
 /*	ORIGINAL	*/
 /*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index ee3b7d6..e7fa29e 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -99,7 +99,7 @@
    to ~13-30min depending on RTO. */
 unsigned long ip_ct_tcp_timeout_max_retrans =     5 MINS;
  
-static unsigned long * tcp_timeouts[]
+static const unsigned long * tcp_timeouts[]
 = { NULL,                              /*      TCP_CONNTRACK_NONE */
     &ip_ct_tcp_timeout_syn_sent,       /*      TCP_CONNTRACK_SYN_SENT, */
     &ip_ct_tcp_timeout_syn_recv,       /*      TCP_CONNTRACK_SYN_RECV, */
@@ -170,7 +170,7 @@
  *	if they are invalid
  *	or we do not support the request (simultaneous open)
  */
-static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
+static const enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
 	{
 /* ORIGINAL */
 /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI	*/
@@ -272,9 +272,9 @@
  *	sCL -> sCL
  */
 /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI	*/
-/*ack*/	   { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
+/*ack*/	   { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
 /*
- *	sSS -> sIV	Might be a half-open connection.
+ *	sSS -> sIG	Might be a half-open connection.
  *	sSR -> sSR	Might answer late resent SYN.
  *	sES -> sES	:-)
  *	sFW -> sCW	Normal close request answered by ACK.
@@ -341,9 +341,10 @@
 static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
 			 const struct ip_conntrack *ct)
 {
-	struct nfattr *nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP);
+	struct nfattr *nest_parms;
 	
 	read_lock_bh(&tcp_lock);
+	nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP);
 	NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
 		&ct->proto.tcp.state);
 	read_unlock_bh(&tcp_lock);
@@ -817,7 +818,7 @@
 #define	TH_CWR	0x80
 
 /* table of valid flag combinations - ECE and CWR are always valid */
-static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
+static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
 {
 	[TH_SYN]			= 1,
 	[TH_SYN|TH_ACK]			= 1,
@@ -917,8 +918,12 @@
 
 	switch (new_state) {
 	case TCP_CONNTRACK_IGNORE:
-		/* Either SYN in ORIGINAL
-		 * or SYN/ACK in REPLY. */
+		/* Ignored packets:
+		 * 
+		 * a) SYN in ORIGINAL
+		 * b) SYN/ACK in REPLY
+		 * c) ACK in reply direction after initial SYN in original.
+		 */
 		if (index == TCP_SYNACK_SET
 		    && conntrack->proto.tcp.last_index == TCP_SYN_SET
 		    && conntrack->proto.tcp.last_dir != dir
@@ -985,13 +990,20 @@
 		}
 	case TCP_CONNTRACK_CLOSE:
 		if (index == TCP_RST_SET
-		    && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
-		    && conntrack->proto.tcp.last_index == TCP_SYN_SET
+		    && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
+		         && conntrack->proto.tcp.last_index == TCP_SYN_SET)
+		        || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
+		            && conntrack->proto.tcp.last_index == TCP_ACK_SET))
 		    && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
-			/* RST sent to invalid SYN we had let trough
-			 * SYN was in window then, tear down connection.
+			/* RST sent to invalid SYN or ACK we had let trough
+			 * at a) and c) above:
+			 *
+			 * a) SYN was in window then
+			 * c) we hold a half-open connection.
+			 *
+			 * Delete our connection entry.
 			 * We skip window checking, because packet might ACK
-			 * segments we ignored in the SYN. */
+			 * segments we ignored. */
 			goto in_window;
 		}
 		/* Just fall trough */
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
index f2dcac7..46becbe 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
@@ -11,6 +11,7 @@
 #include <linux/timer.h>
 #include <linux/netfilter.h>
 #include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/udp.h>
 #include <linux/seq_file.h>
 #include <net/checksum.h>
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index dd476b1..7ba9778 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -27,6 +27,7 @@
 #endif
 #include <net/checksum.h>
 #include <net/ip.h>
+#include <net/route.h>
 
 #define ASSERT_READ_LOCK(x)
 #define ASSERT_WRITE_LOCK(x)
@@ -450,30 +451,6 @@
 	return NF_ACCEPT;
 }
 
-static unsigned int ip_refrag(unsigned int hooknum,
-			      struct sk_buff **pskb,
-			      const struct net_device *in,
-			      const struct net_device *out,
-			      int (*okfn)(struct sk_buff *))
-{
-	struct rtable *rt = (struct rtable *)(*pskb)->dst;
-
-	/* We've seen it coming out the other side: confirm */
-	if (ip_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
-		return NF_DROP;
-
-	/* Local packets are never produced too large for their
-	   interface.  We degfragment them at LOCAL_OUT, however,
-	   so we have to refragment them here. */
-	if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
-	    !skb_shinfo(*pskb)->tso_size) {
-		/* No hook can be after us, so this should be OK. */
-		ip_fragment(*pskb, okfn);
-		return NF_STOLEN;
-	}
-	return NF_ACCEPT;
-}
-
 static unsigned int ip_conntrack_local(unsigned int hooknum,
 				       struct sk_buff **pskb,
 				       const struct net_device *in,
@@ -543,7 +520,7 @@
 
 /* Refragmenter; last chance. */
 static struct nf_hook_ops ip_conntrack_out_ops = {
-	.hook		= ip_refrag,
+	.hook		= ip_confirm,
 	.owner		= THIS_MODULE,
 	.pf		= PF_INET,
 	.hooknum	= NF_IP_POST_ROUTING,
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 762f4d9..c1a6146 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -49,7 +49,7 @@
 static struct list_head *bysource;
 
 #define MAX_IP_NAT_PROTO 256
-struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO];
+static struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO];
 
 static inline struct ip_nat_protocol *
 __ip_nat_proto_find(u_int8_t protonum)
diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c
index d83757a..b8daab3 100644
--- a/net/ipv4/netfilter/ip_nat_ftp.c
+++ b/net/ipv4/netfilter/ip_nat_ftp.c
@@ -171,7 +171,7 @@
 /* Prior to 2.6.11, we had a ports param.  No longer, but don't break users. */
 static int warn_set(const char *val, struct kernel_param *kp)
 {
-	printk(KERN_INFO __stringify(KBUILD_MODNAME)
+	printk(KERN_INFO KBUILD_MODNAME
 	       ": kernel >= 2.6.10 only uses 'ports' for conntrack modules\n");
 	return 0;
 }
diff --git a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c
index de31942..461c833 100644
--- a/net/ipv4/netfilter/ip_nat_irc.c
+++ b/net/ipv4/netfilter/ip_nat_irc.c
@@ -113,7 +113,7 @@
 /* Prior to 2.6.11, we had a ports param.  No longer, but don't break users. */
 static int warn_set(const char *val, struct kernel_param *kp)
 {
-	printk(KERN_INFO __stringify(KBUILD_MODNAME)
+	printk(KERN_INFO KBUILD_MODNAME
 	       ": kernel >= 2.6.10 only uses 'ports' for conntrack modules\n");
 	return 0;
 }
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index 8acb7ed..4f95d47 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -44,6 +44,7 @@
  *
  */
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -53,6 +54,7 @@
 #include <linux/netfilter_ipv4/ip_conntrack_helper.h>
 #include <linux/netfilter_ipv4/ip_nat_helper.h>
 #include <linux/ip.h>
+#include <linux/udp.h>
 #include <net/checksum.h>
 #include <net/udp.h>
 #include <asm/uaccess.h>
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index 30cd4e1..8b8a1f0 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -55,6 +55,44 @@
 			         : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN"  \
 				    : "*ERROR*")))
 
+#ifdef CONFIG_XFRM
+static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
+{
+	struct ip_conntrack *ct;
+	struct ip_conntrack_tuple *t;
+	enum ip_conntrack_info ctinfo;
+	enum ip_conntrack_dir dir;
+	unsigned long statusbit;
+
+	ct = ip_conntrack_get(skb, &ctinfo);
+	if (ct == NULL)
+		return;
+	dir = CTINFO2DIR(ctinfo);
+	t = &ct->tuplehash[dir].tuple;
+
+	if (dir == IP_CT_DIR_ORIGINAL)
+		statusbit = IPS_DST_NAT;
+	else
+		statusbit = IPS_SRC_NAT;
+
+	if (ct->status & statusbit) {
+		fl->fl4_dst = t->dst.ip;
+		if (t->dst.protonum == IPPROTO_TCP ||
+		    t->dst.protonum == IPPROTO_UDP)
+			fl->fl_ip_dport = t->dst.u.tcp.port;
+	}
+
+	statusbit ^= IPS_NAT_MASK;
+
+	if (ct->status & statusbit) {
+		fl->fl4_src = t->src.ip;
+		if (t->dst.protonum == IPPROTO_TCP ||
+		    t->dst.protonum == IPPROTO_UDP)
+			fl->fl_ip_sport = t->src.u.tcp.port;
+	}
+}
+#endif
+		
 static unsigned int
 ip_nat_fn(unsigned int hooknum,
 	  struct sk_buff **pskb,
@@ -162,18 +200,20 @@
           const struct net_device *out,
           int (*okfn)(struct sk_buff *))
 {
-	u_int32_t saddr, daddr;
+	struct ip_conntrack *ct;
+	enum ip_conntrack_info ctinfo;
 	unsigned int ret;
 
-	saddr = (*pskb)->nh.iph->saddr;
-	daddr = (*pskb)->nh.iph->daddr;
-
 	ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
 	if (ret != NF_DROP && ret != NF_STOLEN
-	    && ((*pskb)->nh.iph->saddr != saddr
-	        || (*pskb)->nh.iph->daddr != daddr)) {
-		dst_release((*pskb)->dst);
-		(*pskb)->dst = NULL;
+	    && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
+		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+
+		if (ct->tuplehash[dir].tuple.src.ip !=
+		    ct->tuplehash[!dir].tuple.dst.ip) {
+			dst_release((*pskb)->dst);
+			(*pskb)->dst = NULL;
+		}
 	}
 	return ret;
 }
@@ -185,29 +225,30 @@
 	   const struct net_device *out,
 	   int (*okfn)(struct sk_buff *))
 {
+	struct ip_conntrack *ct;
+	enum ip_conntrack_info ctinfo;
+	unsigned int ret;
+
 	/* root is playing with raw sockets. */
 	if ((*pskb)->len < sizeof(struct iphdr)
 	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
 		return NF_ACCEPT;
 
-	/* We can hit fragment here; forwarded packets get
-	   defragmented by connection tracking coming in, then
-	   fragmented (grr) by the forward code.
+	ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
+	if (ret != NF_DROP && ret != NF_STOLEN
+	    && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
+		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 
-	   In future: If we have nfct != NULL, AND we have NAT
-	   initialized, AND there is no helper, then we can do full
-	   NAPT on the head, and IP-address-only NAT on the rest.
-
-	   I'm starting to have nightmares about fragments.  */
-
-	if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
-		*pskb = ip_ct_gather_frags(*pskb, IP_DEFRAG_NAT_OUT);
-
-		if (!*pskb)
-			return NF_STOLEN;
+		if (ct->tuplehash[dir].tuple.src.ip !=
+		    ct->tuplehash[!dir].tuple.dst.ip
+#ifdef CONFIG_XFRM
+		    || ct->tuplehash[dir].tuple.src.u.all !=
+		       ct->tuplehash[!dir].tuple.dst.u.all
+#endif
+		    )
+			return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
 	}
-
-	return ip_nat_fn(hooknum, pskb, in, out, okfn);
+	return ret;
 }
 
 static unsigned int
@@ -217,7 +258,8 @@
 		const struct net_device *out,
 		int (*okfn)(struct sk_buff *))
 {
-	u_int32_t saddr, daddr;
+	struct ip_conntrack *ct;
+	enum ip_conntrack_info ctinfo;
 	unsigned int ret;
 
 	/* root is playing with raw sockets. */
@@ -225,14 +267,20 @@
 	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
 		return NF_ACCEPT;
 
-	saddr = (*pskb)->nh.iph->saddr;
-	daddr = (*pskb)->nh.iph->daddr;
-
 	ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
 	if (ret != NF_DROP && ret != NF_STOLEN
-	    && ((*pskb)->nh.iph->saddr != saddr
-		|| (*pskb)->nh.iph->daddr != daddr))
-		return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+	    && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
+		enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
+
+		if (ct->tuplehash[dir].tuple.dst.ip !=
+		    ct->tuplehash[!dir].tuple.src.ip
+#ifdef CONFIG_XFRM
+		    || ct->tuplehash[dir].tuple.dst.u.all !=
+		       ct->tuplehash[dir].tuple.src.u.all
+#endif
+		    )
+			return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
+	}
 	return ret;
 }
 
@@ -320,10 +368,14 @@
 
 	if (!init) goto cleanup;
 
+#ifdef CONFIG_XFRM
+	BUG_ON(ip_nat_decode_session != NULL);
+	ip_nat_decode_session = nat_decode_session;
+#endif
 	ret = ip_nat_rule_init();
 	if (ret < 0) {
 		printk("ip_nat_init: can't setup rules.\n");
-		goto cleanup_nothing;
+		goto cleanup_decode_session;
 	}
 	ret = nf_register_hook(&ip_nat_in_ops);
 	if (ret < 0) {
@@ -371,7 +423,11 @@
 	nf_unregister_hook(&ip_nat_in_ops);
  cleanup_rule_init:
 	ip_nat_rule_cleanup();
- cleanup_nothing:
+ cleanup_decode_session:
+#ifdef CONFIG_XFRM
+	ip_nat_decode_session = NULL;
+	synchronize_net();
+#endif
 	return ret;
 }
 
diff --git a/net/ipv4/netfilter/ip_nat_tftp.c b/net/ipv4/netfilter/ip_nat_tftp.c
index 2215317..43c3bd7 100644
--- a/net/ipv4/netfilter/ip_nat_tftp.c
+++ b/net/ipv4/netfilter/ip_nat_tftp.c
@@ -42,7 +42,10 @@
 			 enum ip_conntrack_info ctinfo,
 			 struct ip_conntrack_expect *exp)
 {
-	exp->saved_proto.udp.port = exp->tuple.dst.u.tcp.port;
+	struct ip_conntrack *ct = exp->master;
+
+	exp->saved_proto.udp.port
+		= ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
 	exp->dir = IP_CT_DIR_REPLY;
 	exp->expectfn = ip_nat_follow_master;
 	if (ip_conntrack_expect_related(exp) != 0)
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 75c27e9..2a26d16 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -83,11 +83,6 @@
    context stops packets coming through and allows user context to read
    the counters or update the rules.
 
-   To be cache friendly on SMP, we arrange them like so:
-   [ n-entries ]
-   ... cache-align padding ...
-   [ n-entries ]
-
    Hence the start of any table is given by get_table() below.  */
 
 /* The table itself */
@@ -105,20 +100,15 @@
 	unsigned int underflow[NF_IP_NUMHOOKS];
 
 	/* ipt_entry tables: one per CPU */
-	char entries[0] ____cacheline_aligned;
+	void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(ipt_target);
 static LIST_HEAD(ipt_match);
 static LIST_HEAD(ipt_tables);
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
-
 #if 0
 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
 #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; })
@@ -290,8 +280,7 @@
 
 	read_lock_bh(&table->lock);
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
-	table_base = (void *)table->private->entries
-		+ TABLE_OFFSET(table->private, smp_processor_id());
+	table_base = (void *)table->private->entries[smp_processor_id()];
 	e = get_entry(table_base, table->private->hook_entry[hook]);
 
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -563,7 +552,8 @@
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
-mark_source_chains(struct ipt_table_info *newinfo, unsigned int valid_hooks)
+mark_source_chains(struct ipt_table_info *newinfo,
+		   unsigned int valid_hooks, void *entry0)
 {
 	unsigned int hook;
 
@@ -572,7 +562,7 @@
 	for (hook = 0; hook < NF_IP_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct ipt_entry *e
-			= (struct ipt_entry *)(newinfo->entries + pos);
+			= (struct ipt_entry *)(entry0 + pos);
 
 		if (!(valid_hooks & (1 << hook)))
 			continue;
@@ -622,13 +612,13 @@
 						goto next;
 
 					e = (struct ipt_entry *)
-						(newinfo->entries + pos);
+						(entry0 + pos);
 				} while (oldpos == pos + e->next_offset);
 
 				/* Move along one */
 				size = e->next_offset;
 				e = (struct ipt_entry *)
-					(newinfo->entries + pos + size);
+					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -645,7 +635,7 @@
 					newpos = pos + e->next_offset;
 				}
 				e = (struct ipt_entry *)
-					(newinfo->entries + newpos);
+					(entry0 + newpos);
 				e->counters.pcnt = pos;
 				pos = newpos;
 			}
@@ -855,6 +845,7 @@
 translate_table(const char *name,
 		unsigned int valid_hooks,
 		struct ipt_table_info *newinfo,
+		void *entry0,
 		unsigned int size,
 		unsigned int number,
 		const unsigned int *hook_entries,
@@ -875,11 +866,11 @@
 	duprintf("translate_table: size %u\n", newinfo->size);
 	i = 0;
 	/* Walk through entries, checking offsets. */
-	ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry_size_and_hooks,
 				newinfo,
-				newinfo->entries,
-				newinfo->entries + size,
+				entry0,
+				entry0 + size,
 				hook_entries, underflows, &i);
 	if (ret != 0)
 		return ret;
@@ -907,27 +898,24 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks))
+	if (!mark_source_chains(newinfo, valid_hooks, entry0))
 		return -ELOOP;
 
 	/* Finally, each sanity check must pass */
 	i = 0;
-	ret = IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry, name, size, &i);
 
 	if (ret != 0) {
-		IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+		IPT_ENTRY_ITERATE(entry0, newinfo->size,
 				  cleanup_entry, &i);
 		return ret;
 	}
 
 	/* And one copy for every other CPU */
 	for_each_cpu(i) {
-		if (i == 0)
-			continue;
-		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
-		       newinfo->entries,
-		       SMP_ALIGN(newinfo->size));
+		if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
 	return ret;
@@ -943,15 +931,12 @@
 
 #ifdef CONFIG_NETFILTER_DEBUG
 	{
-		struct ipt_entry *table_base;
-		unsigned int i;
+		int cpu;
 
-		for_each_cpu(i) {
-			table_base =
-				(void *)newinfo->entries
-				+ TABLE_OFFSET(newinfo, i);
-
-			table_base->comefrom = 0xdead57ac;
+		for_each_cpu(cpu) {
+			struct ipt_entry *table_base = newinfo->entries[cpu];
+			if (table_base)
+				table_base->comefrom = 0xdead57ac;
 		}
 	}
 #endif
@@ -986,16 +971,44 @@
 	return 0;
 }
 
+static inline int
+set_entry_to_counter(const struct ipt_entry *e,
+		     struct ipt_counters total[],
+		     unsigned int *i)
+{
+	SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+	(*i)++;
+	return 0;
+}
+
 static void
 get_counters(const struct ipt_table_info *t,
 	     struct ipt_counters counters[])
 {
 	unsigned int cpu;
 	unsigned int i;
+	unsigned int curcpu;
+
+	/* Instead of clearing (by a previous call to memset())
+	 * the counters and using adds, we set the counters
+	 * with data used by 'current' CPU
+	 * We dont care about preemption here.
+	 */
+	curcpu = raw_smp_processor_id();
+
+	i = 0;
+	IPT_ENTRY_ITERATE(t->entries[curcpu],
+			  t->size,
+			  set_entry_to_counter,
+			  counters,
+			  &i);
 
 	for_each_cpu(cpu) {
+		if (cpu == curcpu)
+			continue;
 		i = 0;
-		IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+		IPT_ENTRY_ITERATE(t->entries[cpu],
 				  t->size,
 				  add_entry_to_counter,
 				  counters,
@@ -1012,24 +1025,29 @@
 	struct ipt_entry *e;
 	struct ipt_counters *counters;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	/* We need atomic snapshot of counters: rest doesn't change
 	   (other than comefrom, which userspace doesn't care
 	   about). */
 	countersize = sizeof(struct ipt_counters) * table->private->number;
-	counters = vmalloc(countersize);
+	counters = vmalloc_node(countersize, numa_node_id());
 
 	if (counters == NULL)
 		return -ENOMEM;
 
 	/* First, sum counters... */
-	memset(counters, 0, countersize);
 	write_lock_bh(&table->lock);
 	get_counters(table->private, counters);
 	write_unlock_bh(&table->lock);
 
-	/* ... then copy entire thing from CPU 0... */
-	if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+	/* choose the copy that is on our node/cpu, ...
+	 * This choice is lazy (because current thread is
+	 * allowed to migrate to another cpu)
+	 */
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	/* ... then copy entire thing ... */
+	if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
 		ret = -EFAULT;
 		goto free_counters;
 	}
@@ -1041,7 +1059,7 @@
 		struct ipt_entry_match *m;
 		struct ipt_entry_target *t;
 
-		e = (struct ipt_entry *)(table->private->entries + off);
+		e = (struct ipt_entry *)(loc_cpu_entry + off);
 		if (copy_to_user(userptr + off
 				 + offsetof(struct ipt_entry, counters),
 				 &counters[num],
@@ -1110,6 +1128,45 @@
 	return ret;
 }
 
+static void free_table_info(struct ipt_table_info *info)
+{
+	int cpu;
+	for_each_cpu(cpu) {
+		if (info->size <= PAGE_SIZE)
+			kfree(info->entries[cpu]);
+		else
+			vfree(info->entries[cpu]);
+	}
+	kfree(info);
+}
+
+static struct ipt_table_info *alloc_table_info(unsigned int size)
+{
+	struct ipt_table_info *newinfo;
+	int cpu;
+
+	newinfo = kzalloc(sizeof(struct ipt_table_info), GFP_KERNEL);
+	if (!newinfo)
+		return NULL;
+
+	newinfo->size = size;
+
+	for_each_cpu(cpu) {
+		if (size <= PAGE_SIZE)
+			newinfo->entries[cpu] = kmalloc_node(size,
+				GFP_KERNEL,
+				cpu_to_node(cpu));
+		else
+			newinfo->entries[cpu] = vmalloc_node(size, cpu_to_node(cpu));
+		if (newinfo->entries[cpu] == 0) {
+			free_table_info(newinfo);
+			return NULL;
+		}
+	}
+
+	return newinfo;
+}
+
 static int
 do_replace(void __user *user, unsigned int len)
 {
@@ -1118,6 +1175,7 @@
 	struct ipt_table *t;
 	struct ipt_table_info *newinfo, *oldinfo;
 	struct ipt_counters *counters;
+	void *loc_cpu_entry, *loc_cpu_old_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1130,13 +1188,13 @@
 	if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
 		return -ENOMEM;
 
-	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(tmp.size) * 
-			  	(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+	/* choose the copy that is our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
 			   tmp.size) != 0) {
 		ret = -EFAULT;
 		goto free_newinfo;
@@ -1147,10 +1205,9 @@
 		ret = -ENOMEM;
 		goto free_newinfo;
 	}
-	memset(counters, 0, tmp.num_counters * sizeof(struct ipt_counters));
 
 	ret = translate_table(tmp.name, tmp.valid_hooks,
-			      newinfo, tmp.size, tmp.num_entries,
+			      newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
 			      tmp.hook_entry, tmp.underflow);
 	if (ret != 0)
 		goto free_newinfo_counters;
@@ -1189,8 +1246,9 @@
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
 	/* Decrease module usage counts and free resource */
-	IPT_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-	vfree(oldinfo);
+	loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+	IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+	free_table_info(oldinfo);
 	if (copy_to_user(tmp.counters, counters,
 			 sizeof(struct ipt_counters) * tmp.num_counters) != 0)
 		ret = -EFAULT;
@@ -1202,11 +1260,11 @@
 	module_put(t->me);
 	up(&ipt_mutex);
  free_newinfo_counters_untrans:
-	IPT_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
+	IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
  free_newinfo_counters:
 	vfree(counters);
  free_newinfo:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	return ret;
 }
 
@@ -1239,6 +1297,7 @@
 	struct ipt_counters_info tmp, *paddc;
 	struct ipt_table *t;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1246,7 +1305,7 @@
 	if (len != sizeof(tmp) + tmp.num_counters*sizeof(struct ipt_counters))
 		return -EINVAL;
 
-	paddc = vmalloc(len);
+	paddc = vmalloc_node(len, numa_node_id());
 	if (!paddc)
 		return -ENOMEM;
 
@@ -1268,7 +1327,9 @@
 	}
 
 	i = 0;
-	IPT_ENTRY_ITERATE(t->private->entries,
+	/* Choose the copy that is on our node */
+	loc_cpu_entry = t->private->entries[raw_smp_processor_id()];
+	IPT_ENTRY_ITERATE(loc_cpu_entry,
 			  t->private->size,
 			  add_counter_to_entry,
 			  paddc->counters,
@@ -1460,28 +1521,31 @@
 	struct ipt_table_info *newinfo;
 	static struct ipt_table_info bootstrap
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
+	void *loc_cpu_entry;
 
-	newinfo = vmalloc(sizeof(struct ipt_table_info)
-			  + SMP_ALIGN(repl->size) * 
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(repl->size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	memcpy(newinfo->entries, repl->entries, repl->size);
+	/* choose the copy on our node/cpu
+	 * but dont care of preemption
+	 */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	memcpy(loc_cpu_entry, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, repl->size,
+			      newinfo, loc_cpu_entry, repl->size,
 			      repl->num_entries,
 			      repl->hook_entry,
 			      repl->underflow);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
 	ret = down_interruptible(&ipt_mutex);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
@@ -1510,20 +1574,23 @@
 	return ret;
 
  free_unlock:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	goto unlock;
 }
 
 void ipt_unregister_table(struct ipt_table *table)
 {
+	void *loc_cpu_entry;
+
 	down(&ipt_mutex);
 	LIST_DELETE(&ipt_tables, table);
 	up(&ipt_mutex);
 
 	/* Decrease module usage counts and free resources */
-	IPT_ENTRY_ITERATE(table->private->entries, table->private->size,
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	IPT_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
 			  cleanup_entry, NULL);
-	vfree(table->private);
+	free_table_info(table->private);
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
@@ -1892,7 +1959,7 @@
 	return pos;
 }
 
-static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] =
+static const struct { char *name; get_info_t *get_info; } ipt_proc_entry[] =
 { { "ip_tables_names", ipt_get_tables },
   { "ip_tables_targets", ipt_get_targets },
   { "ip_tables_matches", ipt_get_matches },
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 92ed050..30be0f1 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -197,7 +197,7 @@
 	}
 	case IPPROTO_ICMP: {
 		struct icmphdr _icmph, *ich;
-		static size_t required_len[NR_ICMP_TYPES+1]
+		static const size_t required_len[NR_ICMP_TYPES+1]
 			= { [ICMP_ECHOREPLY] = 4,
 			    [ICMP_DEST_UNREACH]
 			    = 8 + sizeof(struct iphdr),
@@ -351,7 +351,7 @@
 	/* maxlen = 230+   91  + 230 + 252 = 803 */
 }
 
-struct nf_loginfo default_loginfo = {
+static struct nf_loginfo default_loginfo = {
 	.type	= NF_LOG_TYPE_LOG,
 	.u = {
 		.log = {
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 275a174..2786051 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -11,6 +11,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
+#include <linux/inetdevice.h>
 #include <linux/ip.h>
 #include <linux/timer.h>
 #include <linux/module.h>
@@ -18,6 +19,7 @@
 #include <net/protocol.h>
 #include <net/ip.h>
 #include <net/checksum.h>
+#include <net/route.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index f057025..6693526 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -203,7 +203,7 @@
 						sizeof(struct tcphdr), 0));
 
 	/* Adjust IP TTL, DF */
-	nskb->nh.iph->ttl = MAXTTL;
+	nskb->nh.iph->ttl = dst_metric(nskb->dst, RTAX_HOPLIMIT);
 	/* Set DF, id = 0 */
 	nskb->nh.iph->frag_off = htons(IP_DF);
 	nskb->nh.iph->id = 0;
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 2883ccd..38641cd 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -77,15 +77,15 @@
 #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0)
 
 static unsigned int nlbufsiz = 4096;
-module_param(nlbufsiz, uint, 0600); /* FIXME: Check size < 128k --RR */
+module_param(nlbufsiz, uint, 0400);
 MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
 
 static unsigned int flushtimeout = 10;
-module_param(flushtimeout, int, 0600);
+module_param(flushtimeout, uint, 0600);
 MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)");
 
-static unsigned int nflog = 1;
-module_param(nflog, int, 0400);
+static int nflog = 1;
+module_param(nflog, bool, 0400);
 MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
 
 /* global data structures */
@@ -376,7 +376,7 @@
 
 	DEBUGP("ipt_ULOG: init module\n");
 
-	if (nlbufsiz >= 128*1024) {
+	if (nlbufsiz > 128*1024) {
 		printk("Netlink buffer has to be <= 128kB\n");
 		return -EINVAL;
 	}
diff --git a/net/ipv4/netfilter/ipt_helper.c b/net/ipv4/netfilter/ipt_helper.c
index bf14e1c..aef649e 100644
--- a/net/ipv4/netfilter/ipt_helper.c
+++ b/net/ipv4/netfilter/ipt_helper.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter.h>
+#include <linux/interrupt.h>
 #if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_conntrack_core.h>
diff --git a/net/ipv4/netfilter/ipt_physdev.c b/net/ipv4/netfilter/ipt_physdev.c
index 1a53924..03f5548 100644
--- a/net/ipv4/netfilter/ipt_physdev.c
+++ b/net/ipv4/netfilter/ipt_physdev.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4/ipt_physdev.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
diff --git a/net/ipv4/netfilter/ipt_policy.c b/net/ipv4/netfilter/ipt_policy.c
new file mode 100644
index 0000000..709debc
--- /dev/null
+++ b/net/ipv4/netfilter/ipt_policy.c
@@ -0,0 +1,170 @@
+/* IP tables module for matching IPsec policy
+ *
+ * Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <net/xfrm.h>
+
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_policy.h>
+
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("IPtables IPsec policy matching module");
+MODULE_LICENSE("GPL");
+
+
+static inline int
+match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e)
+{
+#define MATCH(x,y)	(!e->match.x || ((e->x == (y)) ^ e->invert.x))
+
+	return MATCH(saddr, x->props.saddr.a4 & e->smask) &&
+	       MATCH(daddr, x->id.daddr.a4 & e->dmask) &&
+	       MATCH(proto, x->id.proto) &&
+	       MATCH(mode, x->props.mode) &&
+	       MATCH(spi, x->id.spi) &&
+	       MATCH(reqid, x->props.reqid);
+}
+
+static int
+match_policy_in(const struct sk_buff *skb, const struct ipt_policy_info *info)
+{
+	const struct ipt_policy_elem *e;
+	struct sec_path *sp = skb->sp;
+	int strict = info->flags & IPT_POLICY_MATCH_STRICT;
+	int i, pos;
+
+	if (sp == NULL)
+		return -1;
+	if (strict && info->len != sp->len)
+		return 0;
+
+	for (i = sp->len - 1; i >= 0; i--) {
+		pos = strict ? i - sp->len + 1 : 0;
+		if (pos >= info->len)
+			return 0;
+		e = &info->pol[pos];
+
+		if (match_xfrm_state(sp->x[i].xvec, e)) {
+			if (!strict)
+				return 1;
+		} else if (strict)
+			return 0;
+	}
+
+	return strict ? 1 : 0;
+}
+
+static int
+match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info)
+{
+	const struct ipt_policy_elem *e;
+	struct dst_entry *dst = skb->dst;
+	int strict = info->flags & IPT_POLICY_MATCH_STRICT;
+	int i, pos;
+
+	if (dst->xfrm == NULL)
+		return -1;
+
+	for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
+		pos = strict ? i : 0;
+		if (pos >= info->len)
+			return 0;
+		e = &info->pol[pos];
+
+		if (match_xfrm_state(dst->xfrm, e)) {
+			if (!strict)
+				return 1;
+		} else if (strict)
+			return 0;
+	}
+
+	return strict ? 1 : 0;
+}
+
+static int match(const struct sk_buff *skb,
+                 const struct net_device *in,
+                 const struct net_device *out,
+                 const void *matchinfo, int offset, int *hotdrop)
+{
+	const struct ipt_policy_info *info = matchinfo;
+	int ret;
+
+	if (info->flags & IPT_POLICY_MATCH_IN)
+		ret = match_policy_in(skb, info);
+	else
+		ret = match_policy_out(skb, info);
+
+	if (ret < 0)
+		ret = info->flags & IPT_POLICY_MATCH_NONE ? 1 : 0;
+	else if (info->flags & IPT_POLICY_MATCH_NONE)
+		ret = 0;
+
+	return ret;
+}
+
+static int checkentry(const char *tablename, const struct ipt_ip *ip,
+                      void *matchinfo, unsigned int matchsize,
+                      unsigned int hook_mask)
+{
+	struct ipt_policy_info *info = matchinfo;
+
+	if (matchsize != IPT_ALIGN(sizeof(*info))) {
+		printk(KERN_ERR "ipt_policy: matchsize %u != %zu\n",
+		       matchsize, IPT_ALIGN(sizeof(*info)));
+		return 0;
+	}
+	if (!(info->flags & (IPT_POLICY_MATCH_IN|IPT_POLICY_MATCH_OUT))) {
+		printk(KERN_ERR "ipt_policy: neither incoming nor "
+		                "outgoing policy selected\n");
+		return 0;
+	}
+	if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
+	    && info->flags & IPT_POLICY_MATCH_OUT) {
+		printk(KERN_ERR "ipt_policy: output policy not valid in "
+		                "PRE_ROUTING and INPUT\n");
+		return 0;
+	}
+	if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
+	    && info->flags & IPT_POLICY_MATCH_IN) {
+		printk(KERN_ERR "ipt_policy: input policy not valid in "
+		                "POST_ROUTING and OUTPUT\n");
+		return 0;
+	}
+	if (info->len > IPT_POLICY_MAX_ELEM) {
+		printk(KERN_ERR "ipt_policy: too many policy elements\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+static struct ipt_match policy_match = {
+	.name		= "policy",
+	.match		= match,
+	.checkentry 	= checkentry,
+	.me		= THIS_MODULE,
+};
+
+static int __init init(void)
+{
+	return ipt_register_match(&policy_match);
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&policy_match);
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 2d44b07..5ddccb1 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -24,10 +24,10 @@
 #define HASH_LOG 9
 
 /* Defaults, these can be overridden on the module command-line. */
-static int ip_list_tot = 100;
-static int ip_pkt_list_tot = 20;
-static int ip_list_hash_size = 0;
-static int ip_list_perms = 0644;
+static unsigned int ip_list_tot = 100;
+static unsigned int ip_pkt_list_tot = 20;
+static unsigned int ip_list_hash_size = 0;
+static unsigned int ip_list_perms = 0644;
 #ifdef DEBUG
 static int debug = 1;
 #endif
@@ -38,13 +38,13 @@
 MODULE_AUTHOR("Stephen Frost <sfrost@snowman.net>");
 MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER);
 MODULE_LICENSE("GPL");
-module_param(ip_list_tot, int, 0400);
-module_param(ip_pkt_list_tot, int, 0400);
-module_param(ip_list_hash_size, int, 0400);
-module_param(ip_list_perms, int, 0400);
+module_param(ip_list_tot, uint, 0400);
+module_param(ip_pkt_list_tot, uint, 0400);
+module_param(ip_list_hash_size, uint, 0400);
+module_param(ip_list_perms, uint, 0400);
 #ifdef DEBUG
-module_param(debug, int, 0600);
-MODULE_PARM_DESC(debug,"debugging level, defaults to 1");
+module_param(debug, bool, 0600);
+MODULE_PARM_DESC(debug,"enable debugging output");
 #endif
 MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list");
 MODULE_PARM_DESC(ip_pkt_list_tot,"number of packets per IP to remember");
@@ -532,6 +532,7 @@
 			}
 			if(info->seconds && info->hit_count) {
 				for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) {
+					if(r_list[location].last_pkts[pkt_count] == 0) break;
 					if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++;
 				}
 				if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert;
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 8202c1c..9bdbb77 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -22,6 +22,7 @@
 #include <linux/skbuff.h>
 #include <linux/icmp.h>
 #include <linux/sysctl.h>
+#include <net/route.h>
 #include <net/ip.h>
 
 #include <linux/netfilter_ipv4.h>
@@ -180,30 +181,6 @@
 	return NF_ACCEPT;
 }
 
-static unsigned int ipv4_refrag(unsigned int hooknum,
-				struct sk_buff **pskb,
-				const struct net_device *in,
-				const struct net_device *out,
-				int (*okfn)(struct sk_buff *))
-{
-	struct rtable *rt = (struct rtable *)(*pskb)->dst;
-
-	/* We've seen it coming out the other side: confirm */
-	if (ipv4_confirm(hooknum, pskb, in, out, okfn) != NF_ACCEPT)
-		return NF_DROP;
-
-	/* Local packets are never produced too large for their
-	   interface.  We degfragment them at LOCAL_OUT, however,
-	   so we have to refragment them here. */
-	if ((*pskb)->len > dst_mtu(&rt->u.dst) &&
-	    !skb_shinfo(*pskb)->tso_size) {
-		/* No hook can be after us, so this should be OK. */
-		ip_fragment(*pskb, okfn);
-		return NF_STOLEN;
-	}
-	return NF_ACCEPT;
-}
-
 static unsigned int ipv4_conntrack_in(unsigned int hooknum,
 				      struct sk_buff **pskb,
 				      const struct net_device *in,
@@ -283,7 +260,7 @@
 
 /* Refragmenter; last chance. */
 static struct nf_hook_ops ipv4_conntrack_out_ops = {
-	.hook		= ipv4_refrag,
+	.hook		= ipv4_confirm,
 	.owner		= THIS_MODULE,
 	.pf		= PF_INET,
 	.hooknum	= NF_IP_POST_ROUTING,
@@ -392,6 +369,48 @@
 	return -ENOENT;
 }
 
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+static int ipv4_tuple_to_nfattr(struct sk_buff *skb,
+				const struct nf_conntrack_tuple *tuple)
+{
+	NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t),
+		&tuple->src.u3.ip);
+	NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t),
+		&tuple->dst.u3.ip);
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+static const size_t cta_min_ip[CTA_IP_MAX] = {
+	[CTA_IP_V4_SRC-1]       = sizeof(u_int32_t),
+	[CTA_IP_V4_DST-1]       = sizeof(u_int32_t),
+};
+
+static int ipv4_nfattr_to_tuple(struct nfattr *tb[],
+				struct nf_conntrack_tuple *t)
+{
+	if (!tb[CTA_IP_V4_SRC-1] || !tb[CTA_IP_V4_DST-1])
+		return -EINVAL;
+
+	if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
+		return -EINVAL;
+
+	t->src.u3.ip =
+		*(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
+	t->dst.u3.ip =
+		*(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
+
+	return 0;
+}
+#endif
+
 static struct nf_sockopt_ops so_getorigdst = {
 	.pf		= PF_INET,
 	.get_optmin	= SO_ORIGINAL_DST,
@@ -408,6 +427,11 @@
 	.print_conntrack = ipv4_print_conntrack,
 	.prepare	 = ipv4_prepare,
 	.get_features	 = ipv4_get_features,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.tuple_to_nfattr = ipv4_tuple_to_nfattr,
+	.nfattr_to_tuple = ipv4_nfattr_to_tuple,
+#endif
 	.me		 = THIS_MODULE,
 };
 
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 7ddb5c0..52dc175 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -50,20 +50,21 @@
 	return 1;
 }
 
+/* Add 1; spaces filled with 0. */
+static const u_int8_t invmap[] = {
+	[ICMP_ECHO] = ICMP_ECHOREPLY + 1,
+	[ICMP_ECHOREPLY] = ICMP_ECHO + 1,
+	[ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
+	[ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
+	[ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
+	[ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
+	[ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
+	[ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1
+};
+
 static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
 			     const struct nf_conntrack_tuple *orig)
 {
-	/* Add 1; spaces filled with 0. */
-	static u_int8_t invmap[]
-		= { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
-		    [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
-		    [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
-		    [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
-		    [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
-		    [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
-		    [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
-		    [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
-
 	if (orig->dst.u.icmp.type >= sizeof(invmap)
 	    || !invmap[orig->dst.u.icmp.type])
 		return 0;
@@ -120,11 +121,12 @@
 static int icmp_new(struct nf_conn *conntrack,
 		    const struct sk_buff *skb, unsigned int dataoff)
 {
-	static u_int8_t valid_new[]
-		= { [ICMP_ECHO] = 1,
-		    [ICMP_TIMESTAMP] = 1,
-		    [ICMP_INFO_REQUEST] = 1,
-		    [ICMP_ADDRESS] = 1 };
+	static const u_int8_t valid_new[] = {
+		[ICMP_ECHO] = 1,
+		[ICMP_TIMESTAMP] = 1,
+		[ICMP_INFO_REQUEST] = 1,
+		[ICMP_ADDRESS] = 1
+	};
 
 	if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
 	    || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
@@ -168,7 +170,7 @@
 		return -NF_ACCEPT;
 	}
 
-	innerproto = nf_ct_find_proto(PF_INET, inside->ip.protocol);
+	innerproto = __nf_ct_proto_find(PF_INET, inside->ip.protocol);
 	dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp);
 	/* Are they talking about one of our connections? */
 	if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
@@ -281,6 +283,60 @@
 	return icmp_error_message(skb, ctinfo, hooknum);
 }
 
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+static int icmp_tuple_to_nfattr(struct sk_buff *skb,
+				const struct nf_conntrack_tuple *t)
+{
+	NFA_PUT(skb, CTA_PROTO_ICMP_ID, sizeof(u_int16_t),
+		&t->src.u.icmp.id);
+	NFA_PUT(skb, CTA_PROTO_ICMP_TYPE, sizeof(u_int8_t),
+		&t->dst.u.icmp.type);
+	NFA_PUT(skb, CTA_PROTO_ICMP_CODE, sizeof(u_int8_t),
+		&t->dst.u.icmp.code);
+
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+static const size_t cta_min_proto[CTA_PROTO_MAX] = {
+	[CTA_PROTO_ICMP_TYPE-1] = sizeof(u_int8_t),
+	[CTA_PROTO_ICMP_CODE-1] = sizeof(u_int8_t),
+	[CTA_PROTO_ICMP_ID-1]   = sizeof(u_int16_t)
+};
+
+static int icmp_nfattr_to_tuple(struct nfattr *tb[],
+				struct nf_conntrack_tuple *tuple)
+{
+	if (!tb[CTA_PROTO_ICMP_TYPE-1]
+	    || !tb[CTA_PROTO_ICMP_CODE-1]
+	    || !tb[CTA_PROTO_ICMP_ID-1])
+		return -EINVAL;
+
+	if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
+		return -EINVAL;
+
+	tuple->dst.u.icmp.type = 
+			*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]);
+	tuple->dst.u.icmp.code =
+			*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
+	tuple->src.u.icmp.id =
+			*(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
+
+	if (tuple->dst.u.icmp.type >= sizeof(invmap)
+	    || !invmap[tuple->dst.u.icmp.type])
+		return -EINVAL;
+
+	return 0;
+}
+#endif
+
 struct nf_conntrack_protocol nf_conntrack_protocol_icmp =
 {
 	.list			= { NULL, NULL },
@@ -295,7 +351,12 @@
 	.new			= icmp_new,
 	.error			= icmp_error,
 	.destroy		= NULL,
-	.me			= NULL
+	.me			= NULL,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.tuple_to_nfattr	= icmp_tuple_to_nfattr,
+	.nfattr_to_tuple	= icmp_nfattr_to_tuple,
+#endif
 };
 
 EXPORT_SYMBOL(nf_conntrack_protocol_icmp);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index a65e508..39d49dc 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -38,6 +38,7 @@
 #include <net/protocol.h>
 #include <net/tcp.h>
 #include <net/udp.h>
+#include <linux/inetdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <net/sock.h>
@@ -98,7 +99,7 @@
 }
 
 /* snmp items */
-static struct snmp_mib snmp4_ipstats_list[] = {
+static const struct snmp_mib snmp4_ipstats_list[] = {
 	SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES),
 	SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS),
 	SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS),
@@ -119,7 +120,7 @@
 	SNMP_MIB_SENTINEL
 };
 
-static struct snmp_mib snmp4_icmp_list[] = {
+static const struct snmp_mib snmp4_icmp_list[] = {
 	SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS),
 	SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS),
 	SNMP_MIB_ITEM("InDestUnreachs", ICMP_MIB_INDESTUNREACHS),
@@ -149,7 +150,7 @@
 	SNMP_MIB_SENTINEL
 };
 
-static struct snmp_mib snmp4_tcp_list[] = {
+static const struct snmp_mib snmp4_tcp_list[] = {
 	SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM),
 	SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN),
 	SNMP_MIB_ITEM("RtoMax", TCP_MIB_RTOMAX),
@@ -167,7 +168,7 @@
 	SNMP_MIB_SENTINEL
 };
 
-static struct snmp_mib snmp4_udp_list[] = {
+static const struct snmp_mib snmp4_udp_list[] = {
 	SNMP_MIB_ITEM("InDatagrams", UDP_MIB_INDATAGRAMS),
 	SNMP_MIB_ITEM("NoPorts", UDP_MIB_NOPORTS),
 	SNMP_MIB_ITEM("InErrors", UDP_MIB_INERRORS),
@@ -175,7 +176,7 @@
 	SNMP_MIB_SENTINEL
 };
 
-static struct snmp_mib snmp4_net_list[] = {
+static const struct snmp_mib snmp4_net_list[] = {
 	SNMP_MIB_ITEM("SyncookiesSent", LINUX_MIB_SYNCOOKIESSENT),
 	SNMP_MIB_ITEM("SyncookiesRecv", LINUX_MIB_SYNCOOKIESRECV),
 	SNMP_MIB_ITEM("SyncookiesFailed", LINUX_MIB_SYNCOOKIESFAILED),
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 4b0d7e4..165a4d8 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -255,6 +255,7 @@
 		kfree_skb(skb);
 		return NET_RX_DROP;
 	}
+	nf_reset(skb);
 
 	skb_push(skb, skb->data - skb->nh.raw);
 
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 381dd6a..f701a13 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1371,7 +1371,7 @@
  *	are needed for AMPRnet AX.25 paths.
  */
 
-static unsigned short mtu_plateau[] =
+static const unsigned short mtu_plateau[] =
 {32000, 17914, 8166, 4352, 2002, 1492, 576, 296, 216, 128 };
 
 static __inline__ unsigned short guess_mtu(unsigned short old_mtu)
@@ -3149,8 +3149,7 @@
 					sizeof(struct rt_hash_bucket),
 					rhash_entries,
 					(num_physpages >= 128 * 1024) ?
-						(27 - PAGE_SHIFT) :
-						(29 - PAGE_SHIFT),
+					15 : 17,
 					HASH_HIGHMEM,
 					&rt_hash_log,
 					&rt_hash_mask,
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index a34e60e..e20be33 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -173,10 +173,10 @@
 					   struct request_sock *req,
 					   struct dst_entry *dst)
 {
-	struct tcp_sock *tp = tcp_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct sock *child;
 
-	child = tp->af_specific->syn_recv_sock(sk, skb, req, dst);
+	child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst);
 	if (child)
 		inet_csk_reqsk_queue_add(sk, req, child);
 	else
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 01444a0..16984d4 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -12,6 +12,7 @@
 #include <linux/sysctl.h>
 #include <linux/config.h>
 #include <linux/igmp.h>
+#include <linux/inetdevice.h>
 #include <net/snmp.h>
 #include <net/icmp.h>
 #include <net/ip.h>
@@ -22,6 +23,7 @@
 extern int sysctl_ip_nonlocal_bind;
 
 #ifdef CONFIG_SYSCTL
+static int zero;
 static int tcp_retr1_max = 255; 
 static int ip_local_port_range_min[] = { 1, 1 };
 static int ip_local_port_range_max[] = { 65535, 65535 };
@@ -614,6 +616,15 @@
 		.strategy	= &sysctl_jiffies
 	},
 	{
+		.ctl_name	= NET_IPV4_IPFRAG_MAX_DIST,
+		.procname	= "ipfrag_max_dist",
+		.data		= &sysctl_ipfrag_max_dist,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_minmax,
+		.extra1		= &zero
+	},
+	{
 		.ctl_name	= NET_TCP_NO_METRICS_SAVE,
 		.procname	= "tcp_no_metrics_save",
 		.data		= &sysctl_tcp_nometrics_save,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 9ac7a4f..00aa80e 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1413,7 +1413,7 @@
  *	closed.
  */
 
-static unsigned char new_state[16] = {
+static const unsigned char new_state[16] = {
   /* current state:        new state:      action:	*/
   /* (Invalid)		*/ TCP_CLOSE,
   /* TCP_ESTABLISHED	*/ TCP_FIN_WAIT1 | TCP_ACTION_FIN,
@@ -1696,8 +1696,8 @@
 	int err = 0;
 
 	if (level != SOL_TCP)
-		return tp->af_specific->setsockopt(sk, level, optname,
-						   optval, optlen);
+		return icsk->icsk_af_ops->setsockopt(sk, level, optname,
+						     optval, optlen);
 
 	/* This is a string value all the others are int's */
 	if (optname == TCP_CONGESTION) {
@@ -1914,7 +1914,7 @@
 	info->tcpi_last_data_recv = jiffies_to_msecs(now - icsk->icsk_ack.lrcvtime);
 	info->tcpi_last_ack_recv = jiffies_to_msecs(now - tp->rcv_tstamp);
 
-	info->tcpi_pmtu = tp->pmtu_cookie;
+	info->tcpi_pmtu = icsk->icsk_pmtu_cookie;
 	info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
 	info->tcpi_rtt = jiffies_to_usecs(tp->srtt)>>3;
 	info->tcpi_rttvar = jiffies_to_usecs(tp->mdev)>>2;
@@ -1939,8 +1939,8 @@
 	int val, len;
 
 	if (level != SOL_TCP)
-		return tp->af_specific->getsockopt(sk, level, optname,
-						   optval, optlen);
+		return icsk->icsk_af_ops->getsockopt(sk, level, optname,
+						     optval, optlen);
 
 	if (get_user(len, optlen))
 		return -EFAULT;
@@ -2065,8 +2065,7 @@
 					sizeof(struct inet_ehash_bucket),
 					thash_entries,
 					(num_physpages >= 128 * 1024) ?
-						(25 - PAGE_SHIFT) :
-						(27 - PAGE_SHIFT),
+					13 : 15,
 					HASH_HIGHMEM,
 					&tcp_hashinfo.ehash_size,
 					NULL,
@@ -2082,8 +2081,7 @@
 					sizeof(struct inet_bind_hashbucket),
 					tcp_hashinfo.ehash_size,
 					(num_physpages >= 128 * 1024) ?
-						(25 - PAGE_SHIFT) :
-						(27 - PAGE_SHIFT),
+					13 : 15,
 					HASH_HIGHMEM,
 					&tcp_hashinfo.bhash_size,
 					NULL,
diff --git a/net/ipv4/tcp_bic.c b/net/ipv4/tcp_bic.c
index 1d0cd86..035f209 100644
--- a/net/ipv4/tcp_bic.c
+++ b/net/ipv4/tcp_bic.c
@@ -30,8 +30,6 @@
 static int max_increment = 16;
 static int low_window = 14;
 static int beta = 819;		/* = 819/1024 (BICTCP_BETA_SCALE) */
-static int low_utilization_threshold = 153;
-static int low_utilization_period = 2;
 static int initial_ssthresh = 100;
 static int smooth_part = 20;
 
@@ -43,10 +41,6 @@
 MODULE_PARM_DESC(low_window, "lower bound on congestion window (for TCP friendliness)");
 module_param(beta, int, 0644);
 MODULE_PARM_DESC(beta, "beta for multiplicative increase");
-module_param(low_utilization_threshold, int, 0644);
-MODULE_PARM_DESC(low_utilization_threshold, "percent (scaled by 1024) for low utilization mode");
-module_param(low_utilization_period, int, 0644);
-MODULE_PARM_DESC(low_utilization_period, "if average delay exceeds then goto to low utilization mode (seconds)");
 module_param(initial_ssthresh, int, 0644);
 MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
 module_param(smooth_part, int, 0644);
@@ -60,11 +54,6 @@
 	u32	loss_cwnd;	/* congestion window at last loss */
 	u32	last_cwnd;	/* the last snd_cwnd */
 	u32	last_time;	/* time when updated last_cwnd */
-	u32	delay_min;	/* min delay */
-	u32	delay_max;	/* max delay */
-	u32	last_delay;
-	u8	low_utilization;/* 0: high; 1: low */
-	u32	low_utilization_start;	/* starting time of low utilization detection*/
 	u32	epoch_start;	/* beginning of an epoch */
 #define ACK_RATIO_SHIFT	4
 	u32	delayed_ack;	/* estimate the ratio of Packets/ACKs << 4 */
@@ -77,11 +66,6 @@
 	ca->loss_cwnd = 0;
 	ca->last_cwnd = 0;
 	ca->last_time = 0;
-	ca->delay_min = 0;
-	ca->delay_max = 0;
-	ca->last_delay = 0;
-	ca->low_utilization = 0;
-	ca->low_utilization_start = 0;
 	ca->epoch_start = 0;
 	ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
 }
@@ -143,8 +127,7 @@
 	}
 
 	/* if in slow start or link utilization is very low */
-	if ( ca->loss_cwnd == 0 ||
-	     (cwnd > ca->loss_cwnd && ca->low_utilization)) {
+	if (ca->loss_cwnd == 0) {
 		if (ca->cnt > 20) /* increase cwnd 5% per RTT */
 			ca->cnt = 20;
 	}
@@ -154,69 +137,12 @@
 		ca->cnt = 1;
 }
 
-
-/* Detect low utilization in congestion avoidance */
-static inline void bictcp_low_utilization(struct sock *sk, int flag)
-{
-	const struct tcp_sock *tp = tcp_sk(sk);
-	struct bictcp *ca = inet_csk_ca(sk);
-	u32 dist, delay;
-
-	/* No time stamp */
-	if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) ||
-	     /* Discard delay samples right after fast recovery */
-	     tcp_time_stamp < ca->epoch_start + HZ ||
-	     /* this delay samples may not be accurate */
-	     flag == 0) {
-		ca->last_delay = 0;
-		goto notlow;
-	}
-
-	delay = ca->last_delay<<3;	/* use the same scale as tp->srtt*/
-	ca->last_delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
-	if (delay == 0) 		/* no previous delay sample */
-		goto notlow;
-
-	/* first time call or link delay decreases */
-	if (ca->delay_min == 0 || ca->delay_min > delay) {
-		ca->delay_min = ca->delay_max = delay;
-		goto notlow;
-	}
-
-	if (ca->delay_max < delay)
-		ca->delay_max = delay;
-
-	/* utilization is low, if avg delay < dist*threshold
-	   for checking_period time */
-	dist = ca->delay_max - ca->delay_min;
-	if (dist <= ca->delay_min>>6 ||
-	    tp->srtt - ca->delay_min >=  (dist*low_utilization_threshold)>>10)
-		goto notlow;
-
-	if (ca->low_utilization_start == 0) {
-		ca->low_utilization = 0;
-		ca->low_utilization_start = tcp_time_stamp;
-	} else if ((s32)(tcp_time_stamp - ca->low_utilization_start)
-			> low_utilization_period*HZ) {
-		ca->low_utilization = 1;
-	}
-
-	return;
-
- notlow:
-	ca->low_utilization = 0;
-	ca->low_utilization_start = 0;
-
-}
-
 static void bictcp_cong_avoid(struct sock *sk, u32 ack,
 			      u32 seq_rtt, u32 in_flight, int data_acked)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct bictcp *ca = inet_csk_ca(sk);
 
-	bictcp_low_utilization(sk, data_acked);
-
 	if (!tcp_is_cwnd_limited(sk, in_flight))
 		return;
 
@@ -249,11 +175,6 @@
 
 	ca->epoch_start = 0;	/* end of epoch */
 
-	/* in case of wrong delay_max*/
-	if (ca->delay_min > 0 && ca->delay_max > ca->delay_min)
-		ca->delay_max = ca->delay_min
-			+ ((ca->delay_max - ca->delay_min)* 90) / 100;
-
 	/* Wmax and fast convergence */
 	if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
 		ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
@@ -289,14 +210,14 @@
 		bictcp_reset(inet_csk_ca(sk));
 }
 
-/* Track delayed acknowledgement ratio using sliding window
+/* Track delayed acknowledgment ratio using sliding window
  * ratio = (15*ratio + sample) / 16
  */
 static void bictcp_acked(struct sock *sk, u32 cnt)
 {
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 
-	if (cnt > 0 && 	icsk->icsk_ca_state == TCP_CA_Open) {
+	if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) {
 		struct bictcp *ca = inet_csk_ca(sk);
 		cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
 		ca->delayed_ack += cnt;
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index c7cc62c..e688c68 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -174,6 +174,34 @@
 	return err;
 }
 
+
+/*
+ * Linear increase during slow start
+ */
+void tcp_slow_start(struct tcp_sock *tp)
+{
+	if (sysctl_tcp_abc) {
+		/* RFC3465: Slow Start
+		 * TCP sender SHOULD increase cwnd by the number of
+		 * previously unacknowledged bytes ACKed by each incoming
+		 * acknowledgment, provided the increase is not more than L
+		 */
+		if (tp->bytes_acked < tp->mss_cache)
+			return;
+
+		/* We MAY increase by 2 if discovered delayed ack */
+		if (sysctl_tcp_abc > 1 && tp->bytes_acked > 2*tp->mss_cache) {
+			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+				tp->snd_cwnd++;
+		}
+	}
+	tp->bytes_acked = 0;
+
+	if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+		tp->snd_cwnd++;
+}
+EXPORT_SYMBOL_GPL(tcp_slow_start);
+
 /*
  * TCP Reno congestion control
  * This is special case used for fallback as well.
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
new file mode 100644
index 0000000..31a4986
--- /dev/null
+++ b/net/ipv4/tcp_cubic.c
@@ -0,0 +1,411 @@
+/*
+ * TCP CUBIC: Binary Increase Congestion control for TCP v2.0
+ *
+ * This is from the implementation of CUBIC TCP in
+ * Injong Rhee, Lisong Xu.
+ *  "CUBIC: A New TCP-Friendly High-Speed TCP Variant
+ *  in PFLDnet 2005
+ * Available from:
+ *  http://www.csc.ncsu.edu/faculty/rhee/export/bitcp/cubic-paper.pdf
+ *
+ * Unless CUBIC is enabled and congestion window is large
+ * this behaves the same as the original Reno.
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <net/tcp.h>
+#include <asm/div64.h>
+
+#define BICTCP_BETA_SCALE    1024	/* Scale factor beta calculation
+					 * max_cwnd = snd_cwnd * beta
+					 */
+#define BICTCP_B		4	 /*
+					  * In binary search,
+					  * go to point (max+min)/N
+					  */
+#define	BICTCP_HZ		10	/* BIC HZ 2^10 = 1024 */
+
+static int fast_convergence = 1;
+static int max_increment = 16;
+static int beta = 819;		/* = 819/1024 (BICTCP_BETA_SCALE) */
+static int initial_ssthresh = 100;
+static int bic_scale = 41;
+static int tcp_friendliness = 1;
+
+static u32 cube_rtt_scale;
+static u32 beta_scale;
+static u64 cube_factor;
+
+/* Note parameters that are used for precomputing scale factors are read-only */
+module_param(fast_convergence, int, 0644);
+MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence");
+module_param(max_increment, int, 0644);
+MODULE_PARM_DESC(max_increment, "Limit on increment allowed during binary search");
+module_param(beta, int, 0444);
+MODULE_PARM_DESC(beta, "beta for multiplicative increase");
+module_param(initial_ssthresh, int, 0644);
+MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
+module_param(bic_scale, int, 0444);
+MODULE_PARM_DESC(bic_scale, "scale (scaled by 1024) value for bic function (bic_scale/1024)");
+module_param(tcp_friendliness, int, 0644);
+MODULE_PARM_DESC(tcp_friendliness, "turn on/off tcp friendliness");
+
+#include <asm/div64.h>
+
+/* BIC TCP Parameters */
+struct bictcp {
+	u32	cnt;		/* increase cwnd by 1 after ACKs */
+	u32 	last_max_cwnd;	/* last maximum snd_cwnd */
+	u32	loss_cwnd;	/* congestion window at last loss */
+	u32	last_cwnd;	/* the last snd_cwnd */
+	u32	last_time;	/* time when updated last_cwnd */
+	u32	bic_origin_point;/* origin point of bic function */
+	u32	bic_K;		/* time to origin point from the beginning of the current epoch */
+	u32	delay_min;	/* min delay */
+	u32	epoch_start;	/* beginning of an epoch */
+	u32	ack_cnt;	/* number of acks */
+	u32	tcp_cwnd;	/* estimated tcp cwnd */
+#define ACK_RATIO_SHIFT	4
+	u32	delayed_ack;	/* estimate the ratio of Packets/ACKs << 4 */
+};
+
+static inline void bictcp_reset(struct bictcp *ca)
+{
+	ca->cnt = 0;
+	ca->last_max_cwnd = 0;
+	ca->loss_cwnd = 0;
+	ca->last_cwnd = 0;
+	ca->last_time = 0;
+	ca->bic_origin_point = 0;
+	ca->bic_K = 0;
+	ca->delay_min = 0;
+	ca->epoch_start = 0;
+	ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
+	ca->ack_cnt = 0;
+	ca->tcp_cwnd = 0;
+}
+
+static void bictcp_init(struct sock *sk)
+{
+	bictcp_reset(inet_csk_ca(sk));
+	if (initial_ssthresh)
+		tcp_sk(sk)->snd_ssthresh = initial_ssthresh;
+}
+
+/* 64bit divisor, dividend and result. dynamic precision */
+static inline u_int64_t div64_64(u_int64_t dividend, u_int64_t divisor)
+{
+	u_int32_t d = divisor;
+
+	if (divisor > 0xffffffffULL) {
+		unsigned int shift = fls(divisor >> 32);
+
+		d = divisor >> shift;
+		dividend >>= shift;
+	}
+
+	/* avoid 64 bit division if possible */
+	if (dividend >> 32)
+		do_div(dividend, d);
+	else
+		dividend = (uint32_t) dividend / d;
+
+	return dividend;
+}
+
+/*
+ * calculate the cubic root of x using Newton-Raphson
+ */
+static u32 cubic_root(u64 a)
+{
+	u32 x, x1;
+
+	/* Initial estimate is based on:
+	 * cbrt(x) = exp(log(x) / 3)
+	 */
+	x = 1u << (fls64(a)/3);
+
+	/*
+	 * Iteration based on:
+	 *                         2
+	 * x    = ( 2 * x  +  a / x  ) / 3
+	 *  k+1          k         k
+	 */
+	do {
+		x1 = x;
+		x = (2 * x + (uint32_t) div64_64(a, x*x)) / 3;
+	} while (abs(x1 - x) > 1);
+
+	return x;
+}
+
+/*
+ * Compute congestion window to use.
+ */
+static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
+{
+	u64 offs;
+	u32 delta, t, bic_target, min_cnt, max_cnt;
+
+	ca->ack_cnt++;	/* count the number of ACKs */
+
+	if (ca->last_cwnd == cwnd &&
+	    (s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
+		return;
+
+	ca->last_cwnd = cwnd;
+	ca->last_time = tcp_time_stamp;
+
+	if (ca->epoch_start == 0) {
+		ca->epoch_start = tcp_time_stamp;	/* record the beginning of an epoch */
+		ca->ack_cnt = 1;			/* start counting */
+		ca->tcp_cwnd = cwnd;			/* syn with cubic */
+
+		if (ca->last_max_cwnd <= cwnd) {
+			ca->bic_K = 0;
+			ca->bic_origin_point = cwnd;
+		} else {
+			/* Compute new K based on
+			 * (wmax-cwnd) * (srtt>>3 / HZ) / c * 2^(3*bictcp_HZ)
+			 */
+			ca->bic_K = cubic_root(cube_factor
+					       * (ca->last_max_cwnd - cwnd));
+			ca->bic_origin_point = ca->last_max_cwnd;
+		}
+	}
+
+        /* cubic function - calc*/
+        /* calculate c * time^3 / rtt,
+         *  while considering overflow in calculation of time^3
+	 * (so time^3 is done by using 64 bit)
+	 * and without the support of division of 64bit numbers
+	 * (so all divisions are done by using 32 bit)
+         *  also NOTE the unit of those veriables
+         *	  time  = (t - K) / 2^bictcp_HZ
+         *	  c = bic_scale >> 10
+	 * rtt  = (srtt >> 3) / HZ
+	 * !!! The following code does not have overflow problems,
+	 * if the cwnd < 1 million packets !!!
+         */
+
+	/* change the unit from HZ to bictcp_HZ */
+        t = ((tcp_time_stamp + ca->delay_min - ca->epoch_start)
+	     << BICTCP_HZ) / HZ;
+
+        if (t < ca->bic_K)		/* t - K */
+		offs = ca->bic_K - t;
+        else
+                offs = t - ca->bic_K;
+
+	/* c/rtt * (t-K)^3 */
+	delta = (cube_rtt_scale * offs * offs * offs) >> (10+3*BICTCP_HZ);
+        if (t < ca->bic_K)                                	/* below origin*/
+                bic_target = ca->bic_origin_point - delta;
+        else                                                	/* above origin*/
+                bic_target = ca->bic_origin_point + delta;
+
+        /* cubic function - calc bictcp_cnt*/
+        if (bic_target > cwnd) {
+		ca->cnt = cwnd / (bic_target - cwnd);
+        } else {
+                ca->cnt = 100 * cwnd;              /* very small increment*/
+        }
+
+	if (ca->delay_min > 0) {
+		/* max increment = Smax * rtt / 0.1  */
+		min_cnt = (cwnd * HZ * 8)/(10 * max_increment * ca->delay_min);
+		if (ca->cnt < min_cnt)
+			ca->cnt = min_cnt;
+	}
+
+        /* slow start and low utilization  */
+	if (ca->loss_cwnd == 0)		/* could be aggressive in slow start */
+		ca->cnt = 50;
+
+	/* TCP Friendly */
+	if (tcp_friendliness) {
+		u32 scale = beta_scale;
+		delta = (cwnd * scale) >> 3;
+	        while (ca->ack_cnt > delta) {		/* update tcp cwnd */
+	                ca->ack_cnt -= delta;
+        	        ca->tcp_cwnd++;
+		}
+
+		if (ca->tcp_cwnd > cwnd){	/* if bic is slower than tcp */
+			delta = ca->tcp_cwnd - cwnd;
+			max_cnt = cwnd / delta;
+			if (ca->cnt > max_cnt)
+				ca->cnt = max_cnt;
+		}
+        }
+
+	ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
+	if (ca->cnt == 0)			/* cannot be zero */
+		ca->cnt = 1;
+}
+
+
+/* Keep track of minimum rtt */
+static inline void measure_delay(struct sock *sk)
+{
+	const struct tcp_sock *tp = tcp_sk(sk);
+	struct bictcp *ca = inet_csk_ca(sk);
+	u32 delay;
+
+	/* No time stamp */
+	if (!(tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr) ||
+	     /* Discard delay samples right after fast recovery */
+	    (s32)(tcp_time_stamp - ca->epoch_start) < HZ)
+		return;
+
+	delay = tcp_time_stamp - tp->rx_opt.rcv_tsecr;
+	if (delay == 0)
+		delay = 1;
+
+	/* first time call or link delay decreases */
+	if (ca->delay_min == 0 || ca->delay_min > delay)
+		ca->delay_min = delay;
+}
+
+static void bictcp_cong_avoid(struct sock *sk, u32 ack,
+			      u32 seq_rtt, u32 in_flight, int data_acked)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	struct bictcp *ca = inet_csk_ca(sk);
+
+	if (data_acked)
+		measure_delay(sk);
+
+	if (!tcp_is_cwnd_limited(sk, in_flight))
+		return;
+
+	if (tp->snd_cwnd <= tp->snd_ssthresh)
+		tcp_slow_start(tp);
+	else {
+		bictcp_update(ca, tp->snd_cwnd);
+
+		/* In dangerous area, increase slowly.
+		 * In theory this is tp->snd_cwnd += 1 / tp->snd_cwnd
+		 */
+		if (tp->snd_cwnd_cnt >= ca->cnt) {
+			if (tp->snd_cwnd < tp->snd_cwnd_clamp)
+				tp->snd_cwnd++;
+			tp->snd_cwnd_cnt = 0;
+		} else
+			tp->snd_cwnd_cnt++;
+	}
+
+}
+
+static u32 bictcp_recalc_ssthresh(struct sock *sk)
+{
+	const struct tcp_sock *tp = tcp_sk(sk);
+	struct bictcp *ca = inet_csk_ca(sk);
+
+	ca->epoch_start = 0;	/* end of epoch */
+
+	/* Wmax and fast convergence */
+	if (tp->snd_cwnd < ca->last_max_cwnd && fast_convergence)
+		ca->last_max_cwnd = (tp->snd_cwnd * (BICTCP_BETA_SCALE + beta))
+			/ (2 * BICTCP_BETA_SCALE);
+	else
+		ca->last_max_cwnd = tp->snd_cwnd;
+
+	ca->loss_cwnd = tp->snd_cwnd;
+
+	return max((tp->snd_cwnd * beta) / BICTCP_BETA_SCALE, 2U);
+}
+
+static u32 bictcp_undo_cwnd(struct sock *sk)
+{
+	struct bictcp *ca = inet_csk_ca(sk);
+
+	return max(tcp_sk(sk)->snd_cwnd, ca->last_max_cwnd);
+}
+
+static u32 bictcp_min_cwnd(struct sock *sk)
+{
+	return tcp_sk(sk)->snd_ssthresh;
+}
+
+static void bictcp_state(struct sock *sk, u8 new_state)
+{
+	if (new_state == TCP_CA_Loss)
+		bictcp_reset(inet_csk_ca(sk));
+}
+
+/* Track delayed acknowledgment ratio using sliding window
+ * ratio = (15*ratio + sample) / 16
+ */
+static void bictcp_acked(struct sock *sk, u32 cnt)
+{
+	const struct inet_connection_sock *icsk = inet_csk(sk);
+
+	if (cnt > 0 && icsk->icsk_ca_state == TCP_CA_Open) {
+		struct bictcp *ca = inet_csk_ca(sk);
+		cnt -= ca->delayed_ack >> ACK_RATIO_SHIFT;
+		ca->delayed_ack += cnt;
+	}
+}
+
+
+static struct tcp_congestion_ops cubictcp = {
+	.init		= bictcp_init,
+	.ssthresh	= bictcp_recalc_ssthresh,
+	.cong_avoid	= bictcp_cong_avoid,
+	.set_state	= bictcp_state,
+	.undo_cwnd	= bictcp_undo_cwnd,
+	.min_cwnd	= bictcp_min_cwnd,
+	.pkts_acked     = bictcp_acked,
+	.owner		= THIS_MODULE,
+	.name		= "cubic",
+};
+
+static int __init cubictcp_register(void)
+{
+	BUG_ON(sizeof(struct bictcp) > ICSK_CA_PRIV_SIZE);
+
+	/* Precompute a bunch of the scaling factors that are used per-packet
+	 * based on SRTT of 100ms
+	 */
+
+	beta_scale = 8*(BICTCP_BETA_SCALE+beta)/ 3 / (BICTCP_BETA_SCALE - beta);
+
+	cube_rtt_scale = (bic_scale << 3) / 10;	/* 1024*c/rtt */
+
+	/* calculate the "K" for (wmax-cwnd) = c/rtt * K^3
+	 *  so K = cubic_root( (wmax-cwnd)*rtt/c )
+	 * the unit of K is bictcp_HZ=2^10, not HZ
+	 *
+	 *  c = bic_scale >> 10
+	 *  rtt = 100ms
+	 *
+	 * the following code has been designed and tested for
+	 * cwnd < 1 million packets
+	 * RTT < 100 seconds
+	 * HZ < 1,000,00  (corresponding to 10 nano-second)
+	 */
+
+	/* 1/c * 2^2*bictcp_HZ * srtt */
+	cube_factor = 1ull << (10+3*BICTCP_HZ); /* 2^40 */
+
+	/* divide by bic_scale and by constant Srtt (100ms) */
+	do_div(cube_factor, bic_scale * 10);
+
+	return tcp_register_congestion_control(&cubictcp);
+}
+
+static void __exit cubictcp_unregister(void)
+{
+	tcp_unregister_congestion_control(&cubictcp);
+}
+
+module_init(cubictcp_register);
+module_exit(cubictcp_unregister);
+
+MODULE_AUTHOR("Sangtae Ha, Stephen Hemminger");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CUBIC TCP");
+MODULE_VERSION("2.0");
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index bf2e230..0a46123 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -115,8 +115,8 @@
 /* Adapt the MSS value used to make delayed ack decision to the 
  * real world.
  */ 
-static inline void tcp_measure_rcv_mss(struct sock *sk,
-				       const struct sk_buff *skb)
+static void tcp_measure_rcv_mss(struct sock *sk,
+				const struct sk_buff *skb)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	const unsigned int lss = icsk->icsk_ack.last_seg_size; 
@@ -246,8 +246,8 @@
 	return 0;
 }
 
-static inline void tcp_grow_window(struct sock *sk, struct tcp_sock *tp,
-				   struct sk_buff *skb)
+static void tcp_grow_window(struct sock *sk, struct tcp_sock *tp,
+			    struct sk_buff *skb)
 {
 	/* Check #1 */
 	if (tp->rcv_ssthresh < tp->window_clamp &&
@@ -341,6 +341,26 @@
 		tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
 }
 
+
+/* Initialize RCV_MSS value.
+ * RCV_MSS is an our guess about MSS used by the peer.
+ * We haven't any direct information about the MSS.
+ * It's better to underestimate the RCV_MSS rather than overestimate.
+ * Overestimations make us ACKing less frequently than needed.
+ * Underestimations are more easy to detect and fix by tcp_measure_rcv_mss().
+ */
+void tcp_initialize_rcv_mss(struct sock *sk)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+	unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache);
+
+	hint = min(hint, tp->rcv_wnd/2);
+	hint = min(hint, TCP_MIN_RCVMSS);
+	hint = max(hint, TCP_MIN_MSS);
+
+	inet_csk(sk)->icsk_ack.rcv_mss = hint;
+}
+
 /* Receiver "autotuning" code.
  *
  * The algorithm for RTT estimation w/o timestamps is based on
@@ -735,6 +755,27 @@
 	return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
 }
 
+/* Set slow start threshold and cwnd not falling to slow start */
+void tcp_enter_cwr(struct sock *sk)
+{
+	struct tcp_sock *tp = tcp_sk(sk);
+
+	tp->prior_ssthresh = 0;
+	tp->bytes_acked = 0;
+	if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) {
+		tp->undo_marker = 0;
+		tp->snd_ssthresh = inet_csk(sk)->icsk_ca_ops->ssthresh(sk);
+		tp->snd_cwnd = min(tp->snd_cwnd,
+				   tcp_packets_in_flight(tp) + 1U);
+		tp->snd_cwnd_cnt = 0;
+		tp->high_seq = tp->snd_nxt;
+		tp->snd_cwnd_stamp = tcp_time_stamp;
+		TCP_ECN_queue_cwr(tp);
+
+		tcp_set_ca_state(sk, TCP_CA_CWR);
+	}
+}
+
 /* Initialize metrics on socket. */
 
 static void tcp_init_metrics(struct sock *sk)
@@ -2070,8 +2111,8 @@
 		tcp_ack_no_tstamp(sk, seq_rtt, flag);
 }
 
-static inline void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
-				  u32 in_flight, int good)
+static void tcp_cong_avoid(struct sock *sk, u32 ack, u32 rtt,
+			   u32 in_flight, int good)
 {
 	const struct inet_connection_sock *icsk = inet_csk(sk);
 	icsk->icsk_ca_ops->cong_avoid(sk, ack, rtt, in_flight, good);
@@ -2082,7 +2123,7 @@
  * RFC2988 recommends to restart timer to now+rto.
  */
 
-static inline void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp)
+static void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp)
 {
 	if (!tp->packets_out) {
 		inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
@@ -2147,7 +2188,7 @@
 	return acked;
 }
 
-static inline u32 tcp_usrtt(const struct sk_buff *skb)
+static u32 tcp_usrtt(const struct sk_buff *skb)
 {
 	struct timeval tv, now;
 
@@ -2342,7 +2383,7 @@
 
 			if (nwin > tp->max_window) {
 				tp->max_window = nwin;
-				tcp_sync_mss(sk, tp->pmtu_cookie);
+				tcp_sync_mss(sk, inet_csk(sk)->icsk_pmtu_cookie);
 			}
 		}
 	}
@@ -2583,8 +2624,8 @@
 /* Fast parse options. This hopes to only see timestamps.
  * If it is wrong it falls back on tcp_parse_options().
  */
-static inline int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
-					 struct tcp_sock *tp)
+static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
+				  struct tcp_sock *tp)
 {
 	if (th->doff == sizeof(struct tcphdr)>>2) {
 		tp->rx_opt.saw_tstamp = 0;
@@ -2804,8 +2845,7 @@
 	}
 }
 
-static __inline__ int
-tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq)
+static inline int tcp_sack_extend(struct tcp_sack_block *sp, u32 seq, u32 end_seq)
 {
 	if (!after(seq, sp->end_seq) && !after(sp->start_seq, end_seq)) {
 		if (before(seq, sp->start_seq))
@@ -2817,7 +2857,7 @@
 	return 0;
 }
 
-static inline void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq)
+static void tcp_dsack_set(struct tcp_sock *tp, u32 seq, u32 end_seq)
 {
 	if (tp->rx_opt.sack_ok && sysctl_tcp_dsack) {
 		if (before(seq, tp->rcv_nxt))
@@ -2832,7 +2872,7 @@
 	}
 }
 
-static inline void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq)
+static void tcp_dsack_extend(struct tcp_sock *tp, u32 seq, u32 end_seq)
 {
 	if (!tp->rx_opt.dsack)
 		tcp_dsack_set(tp, seq, end_seq);
@@ -2890,7 +2930,7 @@
 	}
 }
 
-static __inline__ void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2)
+static inline void tcp_sack_swap(struct tcp_sack_block *sack1, struct tcp_sack_block *sack2)
 {
 	__u32 tmp;
 
@@ -3455,7 +3495,7 @@
 	tp->snd_cwnd_stamp = tcp_time_stamp;
 }
 
-static inline int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp)
+static int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp)
 {
 	/* If the user specified a specific send buffer setting, do
 	 * not modify it.
@@ -3502,7 +3542,7 @@
 	sk->sk_write_space(sk);
 }
 
-static inline void tcp_check_space(struct sock *sk)
+static void tcp_check_space(struct sock *sk)
 {
 	if (sock_flag(sk, SOCK_QUEUE_SHRUNK)) {
 		sock_reset_flag(sk, SOCK_QUEUE_SHRUNK);
@@ -3512,7 +3552,7 @@
 	}
 }
 
-static __inline__ void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp)
+static inline void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp)
 {
 	tcp_push_pending_frames(sk, tp);
 	tcp_check_space(sk);
@@ -3544,7 +3584,7 @@
 	}
 }
 
-static __inline__ void tcp_ack_snd_check(struct sock *sk)
+static inline void tcp_ack_snd_check(struct sock *sk)
 {
 	if (!inet_csk_ack_scheduled(sk)) {
 		/* We sent a data segment already. */
@@ -3692,8 +3732,7 @@
 	return result;
 }
 
-static __inline__ int
-tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
+static inline int tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
 {
 	return skb->ip_summed != CHECKSUM_UNNECESSARY &&
 		__tcp_checksum_complete_user(sk, skb);
@@ -3967,12 +4006,12 @@
 					 struct tcphdr *th, unsigned len)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	int saved_clamp = tp->rx_opt.mss_clamp;
 
 	tcp_parse_options(skb, &tp->rx_opt, 0);
 
 	if (th->ack) {
-		struct inet_connection_sock *icsk;
 		/* rfc793:
 		 * "If the state is SYN-SENT then
 		 *    first check the ACK bit
@@ -4061,7 +4100,7 @@
 		if (tp->rx_opt.sack_ok && sysctl_tcp_fack)
 			tp->rx_opt.sack_ok |= 2;
 
-		tcp_sync_mss(sk, tp->pmtu_cookie);
+		tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 		tcp_initialize_rcv_mss(sk);
 
 		/* Remember, tcp_poll() does not lock socket!
@@ -4072,7 +4111,7 @@
 		tcp_set_state(sk, TCP_ESTABLISHED);
 
 		/* Make sure socket is routed, for correct metrics.  */
-		tp->af_specific->rebuild_header(sk);
+		icsk->icsk_af_ops->rebuild_header(sk);
 
 		tcp_init_metrics(sk);
 
@@ -4098,8 +4137,6 @@
 			sk_wake_async(sk, 0, POLL_OUT);
 		}
 
-		icsk = inet_csk(sk);
-
 		if (sk->sk_write_pending ||
 		    icsk->icsk_accept_queue.rskq_defer_accept ||
 		    icsk->icsk_ack.pingpong) {
@@ -4173,7 +4210,7 @@
 		if (tp->ecn_flags&TCP_ECN_OK)
 			sock_set_flag(sk, SOCK_NO_LARGESEND);
 
-		tcp_sync_mss(sk, tp->pmtu_cookie);
+		tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 		tcp_initialize_rcv_mss(sk);
 
 
@@ -4220,6 +4257,7 @@
 			  struct tcphdr *th, unsigned len)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	int queued = 0;
 
 	tp->rx_opt.saw_tstamp = 0;
@@ -4236,7 +4274,7 @@
 			goto discard;
 
 		if(th->syn) {
-			if(tp->af_specific->conn_request(sk, skb) < 0)
+			if (icsk->icsk_af_ops->conn_request(sk, skb) < 0)
 				return 1;
 
 			/* Now we have several options: In theory there is 
@@ -4349,7 +4387,7 @@
 				/* Make sure socket is routed, for
 				 * correct metrics.
 				 */
-				tp->af_specific->rebuild_header(sk);
+				icsk->icsk_af_ops->rebuild_header(sk);
 
 				tcp_init_metrics(sk);
 
@@ -4475,3 +4513,4 @@
 EXPORT_SYMBOL(tcp_parse_options);
 EXPORT_SYMBOL(tcp_rcv_established);
 EXPORT_SYMBOL(tcp_rcv_state_process);
+EXPORT_SYMBOL(tcp_initialize_rcv_mss);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 4d5021e..6ea3539 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -69,6 +69,7 @@
 #include <net/transp_v6.h>
 #include <net/ipv6.h>
 #include <net/inet_common.h>
+#include <net/timewait_sock.h>
 #include <net/xfrm.h>
 
 #include <linux/inet.h>
@@ -86,8 +87,7 @@
 /* Socket used for sending RSTs */
 static struct socket *tcp_socket;
 
-void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
-		       struct sk_buff *skb);
+void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb);
 
 struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
 	.lhash_lock	= RW_LOCK_UNLOCKED,
@@ -97,7 +97,8 @@
 
 static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
 {
-	return inet_csk_get_port(&tcp_hashinfo, sk, snum);
+	return inet_csk_get_port(&tcp_hashinfo, sk, snum,
+				 inet_csk_bind_conflict);
 }
 
 static void tcp_v4_hash(struct sock *sk)
@@ -118,202 +119,38 @@
 					  skb->h.th->source);
 }
 
-/* called with local bh disabled */
-static int __tcp_v4_check_established(struct sock *sk, __u16 lport,
-				      struct inet_timewait_sock **twp)
+int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
 {
-	struct inet_sock *inet = inet_sk(sk);
-	u32 daddr = inet->rcv_saddr;
-	u32 saddr = inet->daddr;
-	int dif = sk->sk_bound_dev_if;
-	INET_ADDR_COOKIE(acookie, saddr, daddr)
-	const __u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
-	unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport);
-	struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash);
-	struct sock *sk2;
-	const struct hlist_node *node;
-	struct inet_timewait_sock *tw;
+	const struct tcp_timewait_sock *tcptw = tcp_twsk(sktw);
+	struct tcp_sock *tp = tcp_sk(sk);
 
-	prefetch(head->chain.first);
-	write_lock(&head->lock);
+	/* With PAWS, it is safe from the viewpoint
+	   of data integrity. Even without PAWS it is safe provided sequence
+	   spaces do not overlap i.e. at data rates <= 80Mbit/sec.
 
-	/* Check TIME-WAIT sockets first. */
-	sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) {
-		tw = inet_twsk(sk2);
+	   Actually, the idea is close to VJ's one, only timestamp cache is
+	   held not per host, but per port pair and TW bucket is used as state
+	   holder.
 
-		if (INET_TW_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif)) {
-			const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2);
-			struct tcp_sock *tp = tcp_sk(sk);
-
-			/* With PAWS, it is safe from the viewpoint
-			   of data integrity. Even without PAWS it
-			   is safe provided sequence spaces do not
-			   overlap i.e. at data rates <= 80Mbit/sec.
-
-			   Actually, the idea is close to VJ's one,
-			   only timestamp cache is held not per host,
-			   but per port pair and TW bucket is used
-			   as state holder.
-
-			   If TW bucket has been already destroyed we
-			   fall back to VJ's scheme and use initial
-			   timestamp retrieved from peer table.
-			 */
-			if (tcptw->tw_ts_recent_stamp &&
-			    (!twp || (sysctl_tcp_tw_reuse &&
-				      xtime.tv_sec -
-				      tcptw->tw_ts_recent_stamp > 1))) {
-				tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
-				if (tp->write_seq == 0)
-					tp->write_seq = 1;
-				tp->rx_opt.ts_recent	   = tcptw->tw_ts_recent;
-				tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
-				sock_hold(sk2);
-				goto unique;
-			} else
-				goto not_unique;
-		}
-	}
-	tw = NULL;
-
-	/* And established part... */
-	sk_for_each(sk2, node, &head->chain) {
-		if (INET_MATCH(sk2, hash, acookie, saddr, daddr, ports, dif))
-			goto not_unique;
-	}
-
-unique:
-	/* Must record num and sport now. Otherwise we will see
-	 * in hash table socket with a funny identity. */
-	inet->num = lport;
-	inet->sport = htons(lport);
-	sk->sk_hash = hash;
-	BUG_TRAP(sk_unhashed(sk));
-	__sk_add_node(sk, &head->chain);
-	sock_prot_inc_use(sk->sk_prot);
-	write_unlock(&head->lock);
-
-	if (twp) {
-		*twp = tw;
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-	} else if (tw) {
-		/* Silly. Should hash-dance instead... */
-		inet_twsk_deschedule(tw, &tcp_death_row);
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-
-		inet_twsk_put(tw);
+	   If TW bucket has been already destroyed we fall back to VJ's scheme
+	   and use initial timestamp retrieved from peer table.
+	 */
+	if (tcptw->tw_ts_recent_stamp &&
+	    (twp == NULL || (sysctl_tcp_tw_reuse &&
+			     xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) {
+		tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
+		if (tp->write_seq == 0)
+			tp->write_seq = 1;
+		tp->rx_opt.ts_recent	   = tcptw->tw_ts_recent;
+		tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
+		sock_hold(sktw);
+		return 1;
 	}
 
 	return 0;
-
-not_unique:
-	write_unlock(&head->lock);
-	return -EADDRNOTAVAIL;
 }
 
-static inline u32 connect_port_offset(const struct sock *sk)
-{
-	const struct inet_sock *inet = inet_sk(sk);
-
-	return secure_tcp_port_ephemeral(inet->rcv_saddr, inet->daddr, 
-					 inet->dport);
-}
-
-/*
- * Bind a port for a connect operation and hash it.
- */
-static inline int tcp_v4_hash_connect(struct sock *sk)
-{
-	const unsigned short snum = inet_sk(sk)->num;
- 	struct inet_bind_hashbucket *head;
- 	struct inet_bind_bucket *tb;
-	int ret;
-
- 	if (!snum) {
- 		int low = sysctl_local_port_range[0];
- 		int high = sysctl_local_port_range[1];
-		int range = high - low;
- 		int i;
-		int port;
-		static u32 hint;
-		u32 offset = hint + connect_port_offset(sk);
-		struct hlist_node *node;
- 		struct inet_timewait_sock *tw = NULL;
-
- 		local_bh_disable();
-		for (i = 1; i <= range; i++) {
-			port = low + (i + offset) % range;
- 			head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)];
- 			spin_lock(&head->lock);
-
- 			/* Does not bother with rcv_saddr checks,
- 			 * because the established check is already
- 			 * unique enough.
- 			 */
-			inet_bind_bucket_for_each(tb, node, &head->chain) {
- 				if (tb->port == port) {
- 					BUG_TRAP(!hlist_empty(&tb->owners));
- 					if (tb->fastreuse >= 0)
- 						goto next_port;
- 					if (!__tcp_v4_check_established(sk,
-									port,
-									&tw))
- 						goto ok;
- 					goto next_port;
- 				}
- 			}
-
- 			tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port);
- 			if (!tb) {
- 				spin_unlock(&head->lock);
- 				break;
- 			}
- 			tb->fastreuse = -1;
- 			goto ok;
-
- 		next_port:
- 			spin_unlock(&head->lock);
- 		}
- 		local_bh_enable();
-
- 		return -EADDRNOTAVAIL;
-
-ok:
-		hint += i;
-
- 		/* Head lock still held and bh's disabled */
- 		inet_bind_hash(sk, tb, port);
-		if (sk_unhashed(sk)) {
- 			inet_sk(sk)->sport = htons(port);
- 			__inet_hash(&tcp_hashinfo, sk, 0);
- 		}
- 		spin_unlock(&head->lock);
-
- 		if (tw) {
- 			inet_twsk_deschedule(tw, &tcp_death_row);;
- 			inet_twsk_put(tw);
- 		}
-
-		ret = 0;
-		goto out;
- 	}
-
- 	head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
- 	tb  = inet_csk(sk)->icsk_bind_hash;
-	spin_lock_bh(&head->lock);
-	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
-		__inet_hash(&tcp_hashinfo, sk, 0);
-		spin_unlock_bh(&head->lock);
-		return 0;
-	} else {
-		spin_unlock(&head->lock);
-		/* No definite answer... Walk to established hash table */
-		ret = __tcp_v4_check_established(sk, snum, NULL);
-out:
-		local_bh_enable();
-		return ret;
-	}
-}
+EXPORT_SYMBOL_GPL(tcp_twsk_unique);
 
 /* This will initiate an outgoing connection. */
 int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
@@ -383,9 +220,9 @@
 	inet->dport = usin->sin_port;
 	inet->daddr = daddr;
 
-	tp->ext_header_len = 0;
+	inet_csk(sk)->icsk_ext_hdr_len = 0;
 	if (inet->opt)
-		tp->ext_header_len = inet->opt->optlen;
+		inet_csk(sk)->icsk_ext_hdr_len = inet->opt->optlen;
 
 	tp->rx_opt.mss_clamp = 536;
 
@@ -395,7 +232,7 @@
 	 * complete initialization after this.
 	 */
 	tcp_set_state(sk, TCP_SYN_SENT);
-	err = tcp_v4_hash_connect(sk);
+	err = inet_hash_connect(&tcp_death_row, sk);
 	if (err)
 		goto failure;
 
@@ -433,12 +270,10 @@
 /*
  * This routine does path mtu discovery as defined in RFC1191.
  */
-static inline void do_pmtu_discovery(struct sock *sk, struct iphdr *iph,
-				     u32 mtu)
+static void do_pmtu_discovery(struct sock *sk, struct iphdr *iph, u32 mtu)
 {
 	struct dst_entry *dst;
 	struct inet_sock *inet = inet_sk(sk);
-	struct tcp_sock *tp = tcp_sk(sk);
 
 	/* We are not interested in TCP_LISTEN and open_requests (SYN-ACKs
 	 * send out by Linux are always <576bytes so they should go through
@@ -467,7 +302,7 @@
 	mtu = dst_mtu(dst);
 
 	if (inet->pmtudisc != IP_PMTUDISC_DONT &&
-	    tp->pmtu_cookie > mtu) {
+	    inet_csk(sk)->icsk_pmtu_cookie > mtu) {
 		tcp_sync_mss(sk, mtu);
 
 		/* Resend the TCP packet because it's
@@ -644,10 +479,10 @@
 }
 
 /* This routine computes an IPv4 TCP checksum. */
-void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
-		       struct sk_buff *skb)
+void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
 {
 	struct inet_sock *inet = inet_sk(sk);
+	struct tcphdr *th = skb->h.th;
 
 	if (skb->ip_summed == CHECKSUM_HW) {
 		th->check = ~tcp_v4_check(th, len, inet->saddr, inet->daddr, 0);
@@ -826,7 +661,8 @@
 	kfree(inet_rsk(req)->opt);
 }
 
-static inline void syn_flood_warning(struct sk_buff *skb)
+#ifdef CONFIG_SYN_COOKIES
+static void syn_flood_warning(struct sk_buff *skb)
 {
 	static unsigned long warntime;
 
@@ -837,12 +673,13 @@
 		       ntohs(skb->h.th->dest));
 	}
 }
+#endif
 
 /*
  * Save and compile IPv4 options into the request_sock if needed.
  */
-static inline struct ip_options *tcp_v4_save_options(struct sock *sk,
-						     struct sk_buff *skb)
+static struct ip_options *tcp_v4_save_options(struct sock *sk,
+					      struct sk_buff *skb)
 {
 	struct ip_options *opt = &(IPCB(skb)->opt);
 	struct ip_options *dopt = NULL;
@@ -869,6 +706,11 @@
 	.send_reset	=	tcp_v4_send_reset,
 };
 
+static struct timewait_sock_ops tcp_timewait_sock_ops = {
+	.twsk_obj_size	= sizeof(struct tcp_timewait_sock),
+	.twsk_unique	= tcp_twsk_unique,
+};
+
 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 {
 	struct inet_request_sock *ireq;
@@ -1053,9 +895,9 @@
 	ireq->opt	      = NULL;
 	newinet->mc_index     = inet_iif(skb);
 	newinet->mc_ttl	      = skb->nh.iph->ttl;
-	newtp->ext_header_len = 0;
+	inet_csk(newsk)->icsk_ext_hdr_len = 0;
 	if (newinet->opt)
-		newtp->ext_header_len = newinet->opt->optlen;
+		inet_csk(newsk)->icsk_ext_hdr_len = newinet->opt->optlen;
 	newinet->id = newtp->write_seq ^ jiffies;
 
 	tcp_sync_mss(newsk, dst_mtu(dst));
@@ -1238,6 +1080,7 @@
 
 	if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto discard_and_relse;
+	nf_reset(skb);
 
 	if (sk_filter(sk, skb, 0))
 		goto discard_and_relse;
@@ -1314,16 +1157,6 @@
 	goto discard_it;
 }
 
-static void v4_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
-{
-	struct sockaddr_in *sin = (struct sockaddr_in *) uaddr;
-	struct inet_sock *inet = inet_sk(sk);
-
-	sin->sin_family		= AF_INET;
-	sin->sin_addr.s_addr	= inet->daddr;
-	sin->sin_port		= inet->dport;
-}
-
 /* VJ's idea. Save last timestamp seen from this destination
  * and hold it at least for normal timewait interval to use for duplicate
  * segment detection in subsequent connections, before they enter synchronized
@@ -1382,7 +1215,7 @@
 	return 0;
 }
 
-struct tcp_func ipv4_specific = {
+struct inet_connection_sock_af_ops ipv4_specific = {
 	.queue_xmit	=	ip_queue_xmit,
 	.send_check	=	tcp_v4_send_check,
 	.rebuild_header	=	inet_sk_rebuild_header,
@@ -1392,7 +1225,7 @@
 	.net_header_len	=	sizeof(struct iphdr),
 	.setsockopt	=	ip_setsockopt,
 	.getsockopt	=	ip_getsockopt,
-	.addr2sockaddr	=	v4_addr2sockaddr,
+	.addr2sockaddr	=	inet_csk_addr2sockaddr,
 	.sockaddr_len	=	sizeof(struct sockaddr_in),
 };
 
@@ -1433,7 +1266,8 @@
 	sk->sk_write_space = sk_stream_write_space;
 	sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
-	tp->af_specific = &ipv4_specific;
+	icsk->icsk_af_ops = &ipv4_specific;
+	icsk->icsk_sync_mss = tcp_sync_mss;
 
 	sk->sk_sndbuf = sysctl_tcp_wmem[1];
 	sk->sk_rcvbuf = sysctl_tcp_rmem[1];
@@ -1989,7 +1823,7 @@
 	.sysctl_rmem		= sysctl_tcp_rmem,
 	.max_header		= MAX_TCP_HEADER,
 	.obj_size		= sizeof(struct tcp_sock),
-	.twsk_obj_size		= sizeof(struct tcp_timewait_sock),
+	.twsk_prot		= &tcp_timewait_sock_ops,
 	.rsk_prot		= &tcp_request_sock_ops,
 };
 
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 1b66a2a..2b9b7f6 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -274,18 +274,18 @@
 void tcp_time_wait(struct sock *sk, int state, int timeo)
 {
 	struct inet_timewait_sock *tw = NULL;
+	const struct inet_connection_sock *icsk = inet_csk(sk);
 	const struct tcp_sock *tp = tcp_sk(sk);
 	int recycle_ok = 0;
 
 	if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp)
-		recycle_ok = tp->af_specific->remember_stamp(sk);
+		recycle_ok = icsk->icsk_af_ops->remember_stamp(sk);
 
 	if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets)
 		tw = inet_twsk_alloc(sk, state);
 
 	if (tw != NULL) {
 		struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
-		const struct inet_connection_sock *icsk = inet_csk(sk);
 		const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
 
 		tw->tw_rcv_wscale	= tp->rx_opt.rcv_wscale;
@@ -298,10 +298,12 @@
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 		if (tw->tw_family == PF_INET6) {
 			struct ipv6_pinfo *np = inet6_sk(sk);
-			struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw);
+			struct inet6_timewait_sock *tw6;
 
-			ipv6_addr_copy(&tcp6tw->tw_v6_daddr, &np->daddr);
-			ipv6_addr_copy(&tcp6tw->tw_v6_rcv_saddr, &np->rcv_saddr);
+			tw->tw_ipv6_offset = inet6_tw_offset(sk->sk_prot);
+			tw6 = inet6_twsk((struct sock *)tw);
+			ipv6_addr_copy(&tw6->tw_v6_daddr, &np->daddr);
+			ipv6_addr_copy(&tw6->tw_v6_rcv_saddr, &np->rcv_saddr);
 			tw->tw_ipv6only = np->ipv6only;
 		}
 #endif
@@ -456,7 +458,6 @@
 			   struct request_sock **prev)
 {
 	struct tcphdr *th = skb->h.th;
-	struct tcp_sock *tp = tcp_sk(sk);
 	u32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK);
 	int paws_reject = 0;
 	struct tcp_options_received tmp_opt;
@@ -613,7 +614,8 @@
 		 * ESTABLISHED STATE. If it will be dropped after
 		 * socket is created, wait for troubles.
 		 */
-		child = tp->af_specific->syn_recv_sock(sk, skb, req, NULL);
+		child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb,
+								 req, NULL);
 		if (child == NULL)
 			goto listen_overflow;
 
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 029c70d..a7623ea 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -51,8 +51,8 @@
  */
 int sysctl_tcp_tso_win_divisor = 3;
 
-static inline void update_send_head(struct sock *sk, struct tcp_sock *tp,
-				    struct sk_buff *skb)
+static void update_send_head(struct sock *sk, struct tcp_sock *tp,
+			     struct sk_buff *skb)
 {
 	sk->sk_send_head = skb->next;
 	if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue)
@@ -124,8 +124,8 @@
 	tp->snd_cwnd_used = 0;
 }
 
-static inline void tcp_event_data_sent(struct tcp_sock *tp,
-				       struct sk_buff *skb, struct sock *sk)
+static void tcp_event_data_sent(struct tcp_sock *tp,
+				struct sk_buff *skb, struct sock *sk)
 {
 	struct inet_connection_sock *icsk = inet_csk(sk);
 	const u32 now = tcp_time_stamp;
@@ -142,7 +142,7 @@
 		icsk->icsk_ack.pingpong = 1;
 }
 
-static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
+static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
 {
 	tcp_dec_quickack_mode(sk, pkts);
 	inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
@@ -212,7 +212,7 @@
  * value can be stuffed directly into th->window for an outgoing
  * frame.
  */
-static __inline__ u16 tcp_select_window(struct sock *sk)
+static u16 tcp_select_window(struct sock *sk)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
 	u32 cur_win = tcp_receive_window(tp);
@@ -250,6 +250,75 @@
 	return new_win;
 }
 
+static void tcp_build_and_update_options(__u32 *ptr, struct tcp_sock *tp,
+					 __u32 tstamp)
+{
+	if (tp->rx_opt.tstamp_ok) {
+		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
+					  (TCPOPT_NOP << 16) |
+					  (TCPOPT_TIMESTAMP << 8) |
+					  TCPOLEN_TIMESTAMP);
+		*ptr++ = htonl(tstamp);
+		*ptr++ = htonl(tp->rx_opt.ts_recent);
+	}
+	if (tp->rx_opt.eff_sacks) {
+		struct tcp_sack_block *sp = tp->rx_opt.dsack ? tp->duplicate_sack : tp->selective_acks;
+		int this_sack;
+
+		*ptr++ = htonl((TCPOPT_NOP  << 24) |
+			       (TCPOPT_NOP  << 16) |
+			       (TCPOPT_SACK <<  8) |
+			       (TCPOLEN_SACK_BASE + (tp->rx_opt.eff_sacks *
+						     TCPOLEN_SACK_PERBLOCK)));
+		for(this_sack = 0; this_sack < tp->rx_opt.eff_sacks; this_sack++) {
+			*ptr++ = htonl(sp[this_sack].start_seq);
+			*ptr++ = htonl(sp[this_sack].end_seq);
+		}
+		if (tp->rx_opt.dsack) {
+			tp->rx_opt.dsack = 0;
+			tp->rx_opt.eff_sacks--;
+		}
+	}
+}
+
+/* Construct a tcp options header for a SYN or SYN_ACK packet.
+ * If this is every changed make sure to change the definition of
+ * MAX_SYN_SIZE to match the new maximum number of options that you
+ * can generate.
+ */
+static void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sack,
+				  int offer_wscale, int wscale, __u32 tstamp,
+				  __u32 ts_recent)
+{
+	/* We always get an MSS option.
+	 * The option bytes which will be seen in normal data
+	 * packets should timestamps be used, must be in the MSS
+	 * advertised.  But we subtract them from tp->mss_cache so
+	 * that calculations in tcp_sendmsg are simpler etc.
+	 * So account for this fact here if necessary.  If we
+	 * don't do this correctly, as a receiver we won't
+	 * recognize data packets as being full sized when we
+	 * should, and thus we won't abide by the delayed ACK
+	 * rules correctly.
+	 * SACKs don't matter, we never delay an ACK when we
+	 * have any of those going out.
+	 */
+	*ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
+	if (ts) {
+		if(sack)
+			*ptr++ = __constant_htonl((TCPOPT_SACK_PERM << 24) | (TCPOLEN_SACK_PERM << 16) |
+						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+		else
+			*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+						  (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
+		*ptr++ = htonl(tstamp);		/* TSVAL */
+		*ptr++ = htonl(ts_recent);	/* TSECR */
+	} else if(sack)
+		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+					  (TCPOPT_SACK_PERM << 8) | TCPOLEN_SACK_PERM);
+	if (offer_wscale)
+		*ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale));
+}
 
 /* This routine actually transmits TCP packets queued in by
  * tcp_do_sendmsg().  This is used by both the initial
@@ -262,122 +331,139 @@
  * We are working here with either a clone of the original
  * SKB, or a fresh unique copy made by the retransmit engine.
  */
-static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
+static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, gfp_t gfp_mask)
 {
-	if (skb != NULL) {
-		const struct inet_connection_sock *icsk = inet_csk(sk);
-		struct inet_sock *inet = inet_sk(sk);
-		struct tcp_sock *tp = tcp_sk(sk);
-		struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
-		int tcp_header_size = tp->tcp_header_len;
-		struct tcphdr *th;
-		int sysctl_flags;
-		int err;
+	const struct inet_connection_sock *icsk = inet_csk(sk);
+	struct inet_sock *inet;
+	struct tcp_sock *tp;
+	struct tcp_skb_cb *tcb;
+	int tcp_header_size;
+	struct tcphdr *th;
+	int sysctl_flags;
+	int err;
 
-		BUG_ON(!tcp_skb_pcount(skb));
+	BUG_ON(!skb || !tcp_skb_pcount(skb));
+
+	/* If congestion control is doing timestamping, we must
+	 * take such a timestamp before we potentially clone/copy.
+	 */
+	if (icsk->icsk_ca_ops->rtt_sample)
+		__net_timestamp(skb);
+
+	if (likely(clone_it)) {
+		if (unlikely(skb_cloned(skb)))
+			skb = pskb_copy(skb, gfp_mask);
+		else
+			skb = skb_clone(skb, gfp_mask);
+		if (unlikely(!skb))
+			return -ENOBUFS;
+	}
+
+	inet = inet_sk(sk);
+	tp = tcp_sk(sk);
+	tcb = TCP_SKB_CB(skb);
+	tcp_header_size = tp->tcp_header_len;
 
 #define SYSCTL_FLAG_TSTAMPS	0x1
 #define SYSCTL_FLAG_WSCALE	0x2
 #define SYSCTL_FLAG_SACK	0x4
 
-		/* If congestion control is doing timestamping */
-		if (icsk->icsk_ca_ops->rtt_sample)
-			__net_timestamp(skb);
-
-		sysctl_flags = 0;
-		if (tcb->flags & TCPCB_FLAG_SYN) {
-			tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS;
-			if(sysctl_tcp_timestamps) {
-				tcp_header_size += TCPOLEN_TSTAMP_ALIGNED;
-				sysctl_flags |= SYSCTL_FLAG_TSTAMPS;
-			}
-			if(sysctl_tcp_window_scaling) {
-				tcp_header_size += TCPOLEN_WSCALE_ALIGNED;
-				sysctl_flags |= SYSCTL_FLAG_WSCALE;
-			}
-			if(sysctl_tcp_sack) {
-				sysctl_flags |= SYSCTL_FLAG_SACK;
-				if(!(sysctl_flags & SYSCTL_FLAG_TSTAMPS))
-					tcp_header_size += TCPOLEN_SACKPERM_ALIGNED;
-			}
-		} else if (tp->rx_opt.eff_sacks) {
-			/* A SACK is 2 pad bytes, a 2 byte header, plus
-			 * 2 32-bit sequence numbers for each SACK block.
-			 */
-			tcp_header_size += (TCPOLEN_SACK_BASE_ALIGNED +
-					    (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK));
+	sysctl_flags = 0;
+	if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
+		tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS;
+		if(sysctl_tcp_timestamps) {
+			tcp_header_size += TCPOLEN_TSTAMP_ALIGNED;
+			sysctl_flags |= SYSCTL_FLAG_TSTAMPS;
 		}
-		
-		if (tcp_packets_in_flight(tp) == 0)
-			tcp_ca_event(sk, CA_EVENT_TX_START);
-
-		th = (struct tcphdr *) skb_push(skb, tcp_header_size);
-		skb->h.th = th;
-		skb_set_owner_w(skb, sk);
-
-		/* Build TCP header and checksum it. */
-		th->source		= inet->sport;
-		th->dest		= inet->dport;
-		th->seq			= htonl(tcb->seq);
-		th->ack_seq		= htonl(tp->rcv_nxt);
-		*(((__u16 *)th) + 6)	= htons(((tcp_header_size >> 2) << 12) | tcb->flags);
-		if (tcb->flags & TCPCB_FLAG_SYN) {
-			/* RFC1323: The window in SYN & SYN/ACK segments
-			 * is never scaled.
-			 */
-			th->window	= htons(tp->rcv_wnd);
-		} else {
-			th->window	= htons(tcp_select_window(sk));
+		if (sysctl_tcp_window_scaling) {
+			tcp_header_size += TCPOLEN_WSCALE_ALIGNED;
+			sysctl_flags |= SYSCTL_FLAG_WSCALE;
 		}
-		th->check		= 0;
-		th->urg_ptr		= 0;
-
-		if (tp->urg_mode &&
-		    between(tp->snd_up, tcb->seq+1, tcb->seq+0xFFFF)) {
-			th->urg_ptr		= htons(tp->snd_up-tcb->seq);
-			th->urg			= 1;
+		if (sysctl_tcp_sack) {
+			sysctl_flags |= SYSCTL_FLAG_SACK;
+			if (!(sysctl_flags & SYSCTL_FLAG_TSTAMPS))
+				tcp_header_size += TCPOLEN_SACKPERM_ALIGNED;
 		}
-
-		if (tcb->flags & TCPCB_FLAG_SYN) {
-			tcp_syn_build_options((__u32 *)(th + 1),
-					      tcp_advertise_mss(sk),
-					      (sysctl_flags & SYSCTL_FLAG_TSTAMPS),
-					      (sysctl_flags & SYSCTL_FLAG_SACK),
-					      (sysctl_flags & SYSCTL_FLAG_WSCALE),
-					      tp->rx_opt.rcv_wscale,
-					      tcb->when,
-		      			      tp->rx_opt.ts_recent);
-		} else {
-			tcp_build_and_update_options((__u32 *)(th + 1),
-						     tp, tcb->when);
-
-			TCP_ECN_send(sk, tp, skb, tcp_header_size);
-		}
-		tp->af_specific->send_check(sk, th, skb->len, skb);
-
-		if (tcb->flags & TCPCB_FLAG_ACK)
-			tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
-
-		if (skb->len != tcp_header_size)
-			tcp_event_data_sent(tp, skb, sk);
-
-		TCP_INC_STATS(TCP_MIB_OUTSEGS);
-
-		err = tp->af_specific->queue_xmit(skb, 0);
-		if (err <= 0)
-			return err;
-
-		tcp_enter_cwr(sk);
-
-		/* NET_XMIT_CN is special. It does not guarantee,
-		 * that this packet is lost. It tells that device
-		 * is about to start to drop packets or already
-		 * drops some packets of the same priority and
-		 * invokes us to send less aggressively.
+	} else if (unlikely(tp->rx_opt.eff_sacks)) {
+		/* A SACK is 2 pad bytes, a 2 byte header, plus
+		 * 2 32-bit sequence numbers for each SACK block.
 		 */
-		return err == NET_XMIT_CN ? 0 : err;
+		tcp_header_size += (TCPOLEN_SACK_BASE_ALIGNED +
+				    (tp->rx_opt.eff_sacks *
+				     TCPOLEN_SACK_PERBLOCK));
 	}
-	return -ENOBUFS;
+		
+	if (tcp_packets_in_flight(tp) == 0)
+		tcp_ca_event(sk, CA_EVENT_TX_START);
+
+	th = (struct tcphdr *) skb_push(skb, tcp_header_size);
+	skb->h.th = th;
+	skb_set_owner_w(skb, sk);
+
+	/* Build TCP header and checksum it. */
+	th->source		= inet->sport;
+	th->dest		= inet->dport;
+	th->seq			= htonl(tcb->seq);
+	th->ack_seq		= htonl(tp->rcv_nxt);
+	*(((__u16 *)th) + 6)	= htons(((tcp_header_size >> 2) << 12) |
+					tcb->flags);
+
+	if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
+		/* RFC1323: The window in SYN & SYN/ACK segments
+		 * is never scaled.
+		 */
+		th->window	= htons(tp->rcv_wnd);
+	} else {
+		th->window	= htons(tcp_select_window(sk));
+	}
+	th->check		= 0;
+	th->urg_ptr		= 0;
+
+	if (unlikely(tp->urg_mode &&
+		     between(tp->snd_up, tcb->seq+1, tcb->seq+0xFFFF))) {
+		th->urg_ptr		= htons(tp->snd_up-tcb->seq);
+		th->urg			= 1;
+	}
+
+	if (unlikely(tcb->flags & TCPCB_FLAG_SYN)) {
+		tcp_syn_build_options((__u32 *)(th + 1),
+				      tcp_advertise_mss(sk),
+				      (sysctl_flags & SYSCTL_FLAG_TSTAMPS),
+				      (sysctl_flags & SYSCTL_FLAG_SACK),
+				      (sysctl_flags & SYSCTL_FLAG_WSCALE),
+				      tp->rx_opt.rcv_wscale,
+				      tcb->when,
+				      tp->rx_opt.ts_recent);
+	} else {
+		tcp_build_and_update_options((__u32 *)(th + 1),
+					     tp, tcb->when);
+		TCP_ECN_send(sk, tp, skb, tcp_header_size);
+	}
+
+	icsk->icsk_af_ops->send_check(sk, skb->len, skb);
+
+	if (likely(tcb->flags & TCPCB_FLAG_ACK))
+		tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
+
+	if (skb->len != tcp_header_size)
+		tcp_event_data_sent(tp, skb, sk);
+
+	TCP_INC_STATS(TCP_MIB_OUTSEGS);
+
+	err = icsk->icsk_af_ops->queue_xmit(skb, 0);
+	if (unlikely(err <= 0))
+		return err;
+
+	tcp_enter_cwr(sk);
+
+	/* NET_XMIT_CN is special. It does not guarantee,
+	 * that this packet is lost. It tells that device
+	 * is about to start to drop packets or already
+	 * drops some packets of the same priority and
+	 * invokes us to send less aggressively.
+	 */
+	return err == NET_XMIT_CN ? 0 : err;
+
 #undef SYSCTL_FLAG_TSTAMPS
 #undef SYSCTL_FLAG_WSCALE
 #undef SYSCTL_FLAG_SACK
@@ -604,7 +690,7 @@
    It is minimum of user_mss and mss received with SYN.
    It also does not include TCP options.
 
-   tp->pmtu_cookie is last pmtu, seen by this function.
+   inet_csk(sk)->icsk_pmtu_cookie is last pmtu, seen by this function.
 
    tp->mss_cache is current effective sending mss, including
    all tcp options except for SACKs. It is evaluated,
@@ -614,26 +700,26 @@
    NOTE1. rfc1122 clearly states that advertised MSS
    DOES NOT include either tcp or ip options.
 
-   NOTE2. tp->pmtu_cookie and tp->mss_cache are READ ONLY outside
-   this function.			--ANK (980731)
+   NOTE2. inet_csk(sk)->icsk_pmtu_cookie and tp->mss_cache
+   are READ ONLY outside this function.		--ANK (980731)
  */
 
 unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
 {
 	struct tcp_sock *tp = tcp_sk(sk);
-	int mss_now;
-
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	/* Calculate base mss without TCP options:
 	   It is MMS_S - sizeof(tcphdr) of rfc1122
 	 */
-	mss_now = pmtu - tp->af_specific->net_header_len - sizeof(struct tcphdr);
+	int mss_now = (pmtu - icsk->icsk_af_ops->net_header_len -
+		       sizeof(struct tcphdr));
 
 	/* Clamp it (mss_clamp does not include tcp options) */
 	if (mss_now > tp->rx_opt.mss_clamp)
 		mss_now = tp->rx_opt.mss_clamp;
 
 	/* Now subtract optional transport overhead */
-	mss_now -= tp->ext_header_len;
+	mss_now -= icsk->icsk_ext_hdr_len;
 
 	/* Then reserve room for full set of TCP options and 8 bytes of data */
 	if (mss_now < 48)
@@ -647,7 +733,7 @@
 		mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len);
 
 	/* And store cached results */
-	tp->pmtu_cookie = pmtu;
+	icsk->icsk_pmtu_cookie = pmtu;
 	tp->mss_cache = mss_now;
 
 	return mss_now;
@@ -677,7 +763,7 @@
 
 	if (dst) {
 		u32 mtu = dst_mtu(dst);
-		if (mtu != tp->pmtu_cookie)
+		if (mtu != inet_csk(sk)->icsk_pmtu_cookie)
 			mss_now = tcp_sync_mss(sk, mtu);
 	}
 
@@ -688,9 +774,10 @@
 	xmit_size_goal = mss_now;
 
 	if (doing_tso) {
-		xmit_size_goal = 65535 -
-			tp->af_specific->net_header_len -
-			tp->ext_header_len - tp->tcp_header_len;
+		xmit_size_goal = (65535 -
+				  inet_csk(sk)->icsk_af_ops->net_header_len -
+				  inet_csk(sk)->icsk_ext_hdr_len -
+				  tp->tcp_header_len);
 
 		if (tp->max_window &&
 		    (xmit_size_goal > (tp->max_window >> 1)))
@@ -706,7 +793,7 @@
 
 /* Congestion window validation. (RFC2861) */
 
-static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
+static void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp)
 {
 	__u32 packets_out = tp->packets_out;
 
@@ -755,7 +842,7 @@
 /* This must be invoked the first time we consider transmitting
  * SKB onto the wire.
  */
-static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
+static int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb, unsigned int mss_now)
 {
 	int tso_segs = tcp_skb_pcount(skb);
 
@@ -1036,7 +1123,7 @@
 
 		TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
-		if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))))
+		if (unlikely(tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC)))
 			break;
 
 		/* Advance the send_head.  This one is sent out.
@@ -1109,7 +1196,7 @@
 		/* Send it out now. */
 		TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
-		if (likely(!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation)))) {
+		if (likely(!tcp_transmit_skb(sk, skb, 1, sk->sk_allocation))) {
 			update_send_head(sk, tp, skb);
 			tcp_cwnd_validate(sk, tp);
 			return;
@@ -1405,7 +1492,7 @@
 	   (sysctl_tcp_retrans_collapse != 0))
 		tcp_retrans_try_collapse(sk, skb, cur_mss);
 
-	if(tp->af_specific->rebuild_header(sk))
+	if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk))
 		return -EHOSTUNREACH; /* Routing failure or similar. */
 
 	/* Some Solaris stacks overoptimize and ignore the FIN on a
@@ -1429,9 +1516,7 @@
 	 */
 	TCP_SKB_CB(skb)->when = tcp_time_stamp;
 
-	err = tcp_transmit_skb(sk, (skb_cloned(skb) ?
-				    pskb_copy(skb, GFP_ATOMIC):
-				    skb_clone(skb, GFP_ATOMIC)));
+	err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
 
 	if (err == 0) {
 		/* Update global TCP statistics. */
@@ -1665,7 +1750,7 @@
 	TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk, tp);
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
 	TCP_SKB_CB(skb)->when = tcp_time_stamp;
-	if (tcp_transmit_skb(sk, skb))
+	if (tcp_transmit_skb(sk, skb, 0, priority))
 		NET_INC_STATS(LINUX_MIB_TCPABORTFAILED);
 }
 
@@ -1700,7 +1785,7 @@
 		TCP_ECN_send_synack(tcp_sk(sk), skb);
 	}
 	TCP_SKB_CB(skb)->when = tcp_time_stamp;
-	return tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
+	return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
 }
 
 /*
@@ -1778,7 +1863,7 @@
 /* 
  * Do all connect socket setups that can be done AF independent.
  */ 
-static inline void tcp_connect_init(struct sock *sk)
+static void tcp_connect_init(struct sock *sk)
 {
 	struct dst_entry *dst = __sk_dst_get(sk);
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -1861,7 +1946,7 @@
 	__skb_queue_tail(&sk->sk_write_queue, buff);
 	sk_charge_skb(sk, buff);
 	tp->packets_out += tcp_skb_pcount(buff);
-	tcp_transmit_skb(sk, skb_clone(buff, GFP_KERNEL));
+	tcp_transmit_skb(sk, buff, 1, GFP_KERNEL);
 	TCP_INC_STATS(TCP_MIB_ACTIVEOPENS);
 
 	/* Timer for repeating the SYN until an answer. */
@@ -1957,7 +2042,7 @@
 		/* Send it off, this clears delayed acks for us. */
 		TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk, tp);
 		TCP_SKB_CB(buff)->when = tcp_time_stamp;
-		tcp_transmit_skb(sk, buff);
+		tcp_transmit_skb(sk, buff, 0, GFP_ATOMIC);
 	}
 }
 
@@ -1997,7 +2082,7 @@
 	TCP_SKB_CB(skb)->seq = urgent ? tp->snd_una : tp->snd_una - 1;
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
 	TCP_SKB_CB(skb)->when = tcp_time_stamp;
-	return tcp_transmit_skb(sk, skb);
+	return tcp_transmit_skb(sk, skb, 0, GFP_ATOMIC);
 }
 
 int tcp_write_wakeup(struct sock *sk)
@@ -2030,7 +2115,7 @@
 
 			TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
 			TCP_SKB_CB(skb)->when = tcp_time_stamp;
-			err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC));
+			err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
 			if (!err) {
 				update_send_head(sk, tp, skb);
 			}
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index b7d296a..3b74034 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -215,14 +215,6 @@
 		vegas->beg_snd_nxt  = tp->snd_nxt;
 		vegas->beg_snd_cwnd = tp->snd_cwnd;
 
-		/* Take into account the current RTT sample too, to
-		 * decrease the impact of delayed acks. This double counts
-		 * this sample since we count it for the next window as well,
-		 * but that's not too awful, since we're taking the min,
-		 * rather than averaging.
-		 */
-		tcp_vegas_rtt_calc(sk, seq_rtt * 1000);
-
 		/* We do the Vegas calculations only if we got enough RTT
 		 * samples that we can be reasonably sure that we got
 		 * at least one RTT sample that wasn't from a delayed ACK.
@@ -333,11 +325,15 @@
 			else if (tp->snd_cwnd > tp->snd_cwnd_clamp)
 				tp->snd_cwnd = tp->snd_cwnd_clamp;
 		}
-	}
 
-	/* Wipe the slate clean for the next RTT. */
-	vegas->cntRTT = 0;
-	vegas->minRTT = 0x7fffffff;
+		/* Wipe the slate clean for the next RTT. */
+		vegas->cntRTT = 0;
+		vegas->minRTT = 0x7fffffff;
+	}
+	/* Use normal slow start */
+	else if (tp->snd_cwnd <= tp->snd_ssthresh) 
+		tcp_slow_start(tp);
+	
 }
 
 /* Extract info for Tcp socket info provided via netlink. */
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 2422a5f..0084047 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -86,6 +86,7 @@
 #include <linux/module.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
+#include <linux/igmp.h>
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
@@ -846,20 +847,7 @@
 csum_copy_err:
 	UDP_INC_STATS_BH(UDP_MIB_INERRORS);
 
-	/* Clear queue. */
-	if (flags&MSG_PEEK) {
-		int clear = 0;
-		spin_lock_bh(&sk->sk_receive_queue.lock);
-		if (skb == skb_peek(&sk->sk_receive_queue)) {
-			__skb_unlink(skb, &sk->sk_receive_queue);
-			clear = 1;
-		}
-		spin_unlock_bh(&sk->sk_receive_queue.lock);
-		if (clear)
-			kfree_skb(skb);
-	}
-
-	skb_free_datagram(sk, skb);
+	skb_kill_datagram(sk, skb, flags);
 
 	if (noblock)
 		return -EAGAIN;	
@@ -1001,6 +989,7 @@
 		kfree_skb(skb);
 		return -1;
 	}
+	nf_reset(skb);
 
 	if (up->encap_type) {
 		/*
@@ -1094,7 +1083,7 @@
  * Otherwise, csum completion requires chacksumming packet body,
  * including udp header and folding it to skb->csum.
  */
-static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
+static void udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
 			     unsigned short ulen, u32 saddr, u32 daddr)
 {
 	if (uh->check == 0) {
@@ -1108,7 +1097,6 @@
 	/* Probably, we should checksum udp header (it should be in cache
 	 * in any case) and data in tiny packets (< rx copybreak).
 	 */
-	return 0;
 }
 
 /*
@@ -1141,8 +1129,7 @@
 	if (pskb_trim_rcsum(skb, ulen))
 		goto short_packet;
 
-	if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0)
-		goto csum_error;
+	udp_checksum_init(skb, uh, ulen, saddr, daddr);
 
 	if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
 		return udp_v4_mcast_deliver(skb, uh, saddr, daddr);
@@ -1163,6 +1150,7 @@
 
 	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
 		goto drop;
+	nf_reset(skb);
 
 	/* No socket. Drop packet silently, if checksum is wrong */
 	if (udp_checksum_complete(skb))
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 2d3849c..850d919 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -11,6 +11,8 @@
 
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
 #include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
@@ -45,6 +47,23 @@
 	return xfrm_parse_spi(skb, nexthdr, spi, seq);
 }
 
+#ifdef CONFIG_NETFILTER
+static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
+{
+	struct iphdr *iph = skb->nh.iph;
+
+	if (skb->dst == NULL) {
+		if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
+		                   skb->dev))
+			goto drop;
+	}
+	return dst_input(skb);
+drop:
+	kfree_skb(skb);
+	return NET_RX_DROP;
+}
+#endif
+
 int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
 {
 	int err;
@@ -137,6 +156,8 @@
 	memcpy(skb->sp->x+skb->sp->len, xfrm_vec, xfrm_nr*sizeof(struct sec_decap_state));
 	skb->sp->len += xfrm_nr;
 
+	nf_reset(skb);
+
 	if (decaps) {
 		if (!(skb->dev->flags&IFF_LOOPBACK)) {
 			dst_release(skb->dst);
@@ -145,7 +166,17 @@
 		netif_rx(skb);
 		return 0;
 	} else {
+#ifdef CONFIG_NETFILTER
+		__skb_push(skb, skb->data - skb->nh.raw);
+		skb->nh.iph->tot_len = htons(skb->len);
+		ip_send_check(skb->nh.iph);
+
+		NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
+		        xfrm4_rcv_encap_finish);
+		return 0;
+#else
 		return -skb->nh.iph->protocol;
+#endif
 	}
 
 drop_unlock:
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 66620a9..d4df0dd 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -8,8 +8,10 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/compiler.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
+#include <linux/netfilter_ipv4.h>
 #include <net/inet_ecn.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
@@ -95,7 +97,7 @@
 	return ret;
 }
 
-int xfrm4_output(struct sk_buff *skb)
+static int xfrm4_output_one(struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb->dst;
 	struct xfrm_state *x = dst->xfrm;
@@ -113,27 +115,33 @@
 			goto error_nolock;
 	}
 
-	spin_lock_bh(&x->lock);
-	err = xfrm_state_check(x, skb);
-	if (err)
-		goto error;
+	do {
+		spin_lock_bh(&x->lock);
+		err = xfrm_state_check(x, skb);
+		if (err)
+			goto error;
 
-	xfrm4_encap(skb);
+		xfrm4_encap(skb);
 
-	err = x->type->output(x, skb);
-	if (err)
-		goto error;
+		err = x->type->output(x, skb);
+		if (err)
+			goto error;
 
-	x->curlft.bytes += skb->len;
-	x->curlft.packets++;
+		x->curlft.bytes += skb->len;
+		x->curlft.packets++;
 
-	spin_unlock_bh(&x->lock);
+		spin_unlock_bh(&x->lock);
 	
-	if (!(skb->dst = dst_pop(dst))) {
-		err = -EHOSTUNREACH;
-		goto error_nolock;
-	}
-	err = NET_XMIT_BYPASS;
+		if (!(skb->dst = dst_pop(dst))) {
+			err = -EHOSTUNREACH;
+			goto error_nolock;
+		}
+		dst = skb->dst;
+		x = dst->xfrm;
+	} while (x && !x->props.mode);
+
+	IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
+	err = 0;
 
 out_exit:
 	return err;
@@ -143,3 +151,33 @@
 	kfree_skb(skb);
 	goto out_exit;
 }
+
+int xfrm4_output_finish(struct sk_buff *skb)
+{
+	int err;
+
+	while (likely((err = xfrm4_output_one(skb)) == 0)) {
+		nf_reset(skb);
+
+		err = nf_hook(PF_INET, NF_IP_LOCAL_OUT, &skb, NULL,
+			      skb->dst->dev, dst_output);
+		if (unlikely(err != 1))
+			break;
+
+		if (!skb->dst->xfrm)
+			return dst_output(skb);
+
+		err = nf_hook(PF_INET, NF_IP_POST_ROUTING, &skb, NULL,
+			      skb->dst->dev, xfrm4_output_finish);
+		if (unlikely(err != 1))
+			break;
+	}
+
+	return err;
+}
+
+int xfrm4_output(struct sk_buff *skb)
+{
+	return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, skb->dst->dev,
+		       xfrm4_output_finish);
+}
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index b2b60f3..42196ba 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -182,6 +182,7 @@
 		case IPPROTO_UDP:
 		case IPPROTO_TCP:
 		case IPPROTO_SCTP:
+		case IPPROTO_DCCP:
 			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
 				u16 *ports = (u16 *)xprth;
 
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 6460eec..9601fd7 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -8,7 +8,8 @@
 		route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
 		protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
 		exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
-		ip6_flowlabel.o ipv6_syms.o netfilter.o
+		ip6_flowlabel.o ipv6_syms.o netfilter.o \
+		inet6_connection_sock.o
 
 ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
 	xfrm6_output.o
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a16064b..e53e421 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -137,6 +137,7 @@
 static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags);
 static void addrconf_dad_timer(unsigned long data);
 static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
+static void addrconf_dad_run(struct inet6_dev *idev);
 static void addrconf_rs_timer(unsigned long data);
 static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
 static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
@@ -379,8 +380,8 @@
 		    dev->type == ARPHRD_NONE ||
 		    dev->type == ARPHRD_SIT) {
 			printk(KERN_INFO
-				"Disabled Privacy Extensions on device %p(%s)\n",
-				dev, dev->name);
+			       "%s: Disabled Privacy Extensions\n",
+			       dev->name);
 			ndev->cnf.use_tempaddr = -1;
 		} else {
 			in6_dev_hold(ndev);
@@ -388,6 +389,9 @@
 		}
 #endif
 
+		if (netif_carrier_ok(dev))
+			ndev->if_flags |= IF_READY;
+
 		write_lock_bh(&addrconf_lock);
 		dev->ip6_ptr = ndev;
 		write_unlock_bh(&addrconf_lock);
@@ -415,6 +419,7 @@
 		if ((idev = ipv6_add_dev(dev)) == NULL)
 			return NULL;
 	}
+
 	if (dev->flags&IFF_UP)
 		ipv6_mc_up(idev);
 	return idev;
@@ -634,8 +639,7 @@
 	}
 #endif
 
-	for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;
-	     ifap = &ifa->if_next) {
+	for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;) {
 		if (ifa == ifp) {
 			*ifap = ifa->if_next;
 			__in6_ifa_put(ifp);
@@ -643,6 +647,7 @@
 			if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0)
 				break;
 			deleted = 1;
+			continue;
 		} else if (ifp->flags & IFA_F_PERMANENT) {
 			if (ipv6_prefix_equal(&ifa->addr, &ifp->addr,
 					      ifp->prefix_len)) {
@@ -666,6 +671,7 @@
 				}
 			}
 		}
+		ifap = &ifa->if_next;
 	}
 	write_unlock_bh(&idev->lock);
 
@@ -903,11 +909,18 @@
 
 			score.addr_type = __ipv6_addr_type(&ifa->addr);
 
-			/* Rule 0: Candidate Source Address (section 4)
+			/* Rule 0:
+			 * - Tentative Address (RFC2462 section 5.4)
+			 *  - A tentative address is not considered
+			 *    "assigned to an interface" in the traditional
+			 *    sense.
+			 * - Candidate Source Address (section 4)
 			 *  - In any case, anycast addresses, multicast
 			 *    addresses, and the unspecified address MUST
 			 *    NOT be included in a candidate set.
 			 */
+			if (ifa->flags & IFA_F_TENTATIVE)
+				continue;
 			if (unlikely(score.addr_type == IPV6_ADDR_ANY ||
 				     score.addr_type & IPV6_ADDR_MULTICAST)) {
 				LIMIT_NETDEBUG(KERN_DEBUG
@@ -985,6 +998,8 @@
 			}
 
 			/* Rule 4: Prefer home address -- not implemented yet */
+			if (hiscore.rule < 4)
+				hiscore.rule++;
 
 			/* Rule 5: Prefer outgoing interface */
 			if (hiscore.rule < 5) {
@@ -1180,7 +1195,7 @@
 int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
 {
 	const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr;
-	const struct in6_addr *sk2_rcv_saddr6 = tcp_v6_rcv_saddr(sk2);
+	const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
 	u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr;
 	u32 sk2_rcv_saddr = inet_rcv_saddr(sk2);
 	int sk_ipv6only = ipv6_only_sock(sk);
@@ -1213,10 +1228,8 @@
 
 /* Gets referenced address, destroys ifaddr */
 
-void addrconf_dad_failure(struct inet6_ifaddr *ifp)
+static void addrconf_dad_stop(struct inet6_ifaddr *ifp)
 {
-	if (net_ratelimit())
-		printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
 	if (ifp->flags&IFA_F_PERMANENT) {
 		spin_lock_bh(&ifp->lock);
 		addrconf_del_timer(ifp);
@@ -1242,6 +1255,12 @@
 		ipv6_del_addr(ifp);
 }
 
+void addrconf_dad_failure(struct inet6_ifaddr *ifp)
+{
+	if (net_ratelimit())
+		printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
+	addrconf_dad_stop(ifp);
+}
 
 /* Join to solicited addr multicast group. */
 
@@ -1594,9 +1613,17 @@
 	   not good.
 	 */
 	if (valid_lft >= 0x7FFFFFFF/HZ)
-		rt_expires = 0;
+		rt_expires = 0x7FFFFFFF - (0x7FFFFFFF % HZ);
 	else
-		rt_expires = jiffies + valid_lft * HZ;
+		rt_expires = valid_lft * HZ;
+
+	/*
+	 * We convert this (in jiffies) to clock_t later.
+	 * Avoid arithmetic overflow there as well.
+	 * Overflow can happen only if HZ < USER_HZ.
+	 */
+	if (HZ < USER_HZ && rt_expires > 0x7FFFFFFF / USER_HZ)
+		rt_expires = 0x7FFFFFFF / USER_HZ;
 
 	if (pinfo->onlink) {
 		struct rt6_info *rt;
@@ -1608,12 +1635,12 @@
 					ip6_del_rt(rt, NULL, NULL, NULL);
 					rt = NULL;
 				} else {
-					rt->rt6i_expires = rt_expires;
+					rt->rt6i_expires = jiffies + rt_expires;
 				}
 			}
 		} else if (valid_lft) {
 			addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
-					      dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT);
+					      dev, jiffies_to_clock_t(rt_expires), RTF_ADDRCONF|RTF_EXPIRES|RTF_PREFIX_RT);
 		}
 		if (rt)
 			dst_release(&rt->u.dst);
@@ -2123,9 +2150,42 @@
 {
 	struct net_device *dev = (struct net_device *) data;
 	struct inet6_dev *idev = __in6_dev_get(dev);
+	int run_pending = 0;
 
 	switch(event) {
 	case NETDEV_UP:
+	case NETDEV_CHANGE:
+		if (event == NETDEV_UP) {
+			if (!netif_carrier_ok(dev)) {
+				/* device is not ready yet. */
+				printk(KERN_INFO
+					"ADDRCONF(NETDEV_UP): %s: "
+					"link is not ready\n",
+					dev->name);
+				break;
+			}
+		} else {
+			if (!netif_carrier_ok(dev)) {
+				/* device is still not ready. */
+				break;
+			}
+
+			if (idev) {
+				if (idev->if_flags & IF_READY) {
+					/* device is already configured. */
+					break;
+				}
+				idev->if_flags |= IF_READY;
+			}
+
+			printk(KERN_INFO
+					"ADDRCONF(NETDEV_CHANGE): %s: "
+					"link becomes ready\n",
+					dev->name);
+
+			run_pending = 1;
+		}
+
 		switch(dev->type) {
 		case ARPHRD_SIT:
 			addrconf_sit_config(dev);
@@ -2142,6 +2202,9 @@
 			break;
 		};
 		if (idev) {
+			if (run_pending)
+				addrconf_dad_run(idev);
+
 			/* If the MTU changed during the interface down, when the
 			   interface up, the changed MTU must be reflected in the
 			   idev as well as routers.
@@ -2176,8 +2239,7 @@
 		 */
 		addrconf_ifdown(dev, event != NETDEV_DOWN);
 		break;
-	case NETDEV_CHANGE:
-		break;
+
 	case NETDEV_CHANGENAME:
 #ifdef CONFIG_SYSCTL
 		if (idev) {
@@ -2258,7 +2320,7 @@
 
 	/* Step 3: clear flags for stateless addrconf */
 	if (how != 1)
-		idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD);
+		idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
 
 	/* Step 4: clear address list */
 #ifdef CONFIG_IPV6_PRIVACY
@@ -2367,11 +2429,20 @@
 /*
  *	Duplicate Address Detection
  */
+static void addrconf_dad_kick(struct inet6_ifaddr *ifp)
+{
+	unsigned long rand_num;
+	struct inet6_dev *idev = ifp->idev;
+
+	rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1);
+	ifp->probes = idev->cnf.dad_transmits;
+	addrconf_mod_timer(ifp, AC_DAD, rand_num);
+}
+
 static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags)
 {
 	struct inet6_dev *idev = ifp->idev;
 	struct net_device *dev = idev->dev;
-	unsigned long rand_num;
 
 	addrconf_join_solict(dev, &ifp->addr);
 
@@ -2380,7 +2451,6 @@
 					flags);
 
 	net_srandom(ifp->addr.s6_addr32[3]);
-	rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1);
 
 	read_lock_bh(&idev->lock);
 	if (ifp->dead)
@@ -2397,9 +2467,19 @@
 		return;
 	}
 
-	ifp->probes = idev->cnf.dad_transmits;
-	addrconf_mod_timer(ifp, AC_DAD, rand_num);
-
+	if (!(idev->if_flags & IF_READY)) {
+		spin_unlock_bh(&ifp->lock);
+		read_unlock_bh(&idev->lock);
+		/*
+		 * If the defice is not ready:
+		 * - keep it tentative if it is a permanent address.
+		 * - otherwise, kill it.
+		 */
+		in6_ifa_hold(ifp);
+		addrconf_dad_stop(ifp);
+		return;
+	}
+	addrconf_dad_kick(ifp);
 	spin_unlock_bh(&ifp->lock);
 out:
 	read_unlock_bh(&idev->lock);
@@ -2482,6 +2562,22 @@
 	}
 }
 
+static void addrconf_dad_run(struct inet6_dev *idev) {
+	struct inet6_ifaddr *ifp;
+
+	read_lock_bh(&idev->lock);
+	for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) {
+		spin_lock_bh(&ifp->lock);
+		if (!(ifp->flags & IFA_F_TENTATIVE)) {
+			spin_unlock_bh(&ifp->lock);
+			continue;
+		}
+		spin_unlock_bh(&ifp->lock);
+		addrconf_dad_kick(ifp);
+	}
+	read_unlock_bh(&idev->lock);
+}
+
 #ifdef CONFIG_PROC_FS
 struct if6_iter_state {
 	int bucket;
@@ -2687,6 +2783,9 @@
 						in6_ifa_hold(ifpub);
 						spin_unlock(&ifp->lock);
 						read_unlock(&addrconf_hash_lock);
+						spin_lock(&ifpub->lock);
+						ifpub->regen_count = 0;
+						spin_unlock(&ifpub->lock);
 						ipv6_create_tempaddr(ifpub, ifp);
 						in6_ifa_put(ifpub);
 						in6_ifa_put(ifp);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index c63b8ce..25c3fe5 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -92,10 +92,13 @@
 	struct proto *answer_prot;
 	unsigned char answer_flags;
 	char answer_no_check;
-	int rc;
+	int try_loading_module = 0;
+	int err;
 
 	/* Look for the requested type/protocol pair. */
 	answer = NULL;
+lookup_protocol:
+	err = -ESOCKTNOSUPPORT;
 	rcu_read_lock();
 	list_for_each_rcu(p, &inetsw6[sock->type]) {
 		answer = list_entry(p, struct inet_protosw, list);
@@ -113,21 +116,37 @@
 			if (IPPROTO_IP == answer->protocol)
 				break;
 		}
+		err = -EPROTONOSUPPORT;
 		answer = NULL;
 	}
 
-	rc = -ESOCKTNOSUPPORT;
-	if (!answer)
-		goto out_rcu_unlock;
-	rc = -EPERM;
+	if (!answer) {
+		if (try_loading_module < 2) {
+			rcu_read_unlock();
+			/*
+			 * Be more specific, e.g. net-pf-10-proto-132-type-1
+			 * (net-pf-PF_INET6-proto-IPPROTO_SCTP-type-SOCK_STREAM)
+			 */
+			if (++try_loading_module == 1)
+				request_module("net-pf-%d-proto-%d-type-%d",
+						PF_INET6, protocol, sock->type);
+			/*
+			 * Fall back to generic, e.g. net-pf-10-proto-132
+			 * (net-pf-PF_INET6-proto-IPPROTO_SCTP)
+			 */
+			else
+				request_module("net-pf-%d-proto-%d",
+						PF_INET6, protocol);
+			goto lookup_protocol;
+		} else
+			goto out_rcu_unlock;
+	}
+
+	err = -EPERM;
 	if (answer->capability > 0 && !capable(answer->capability))
 		goto out_rcu_unlock;
-	rc = -EPROTONOSUPPORT;
-	if (!protocol)
-		goto out_rcu_unlock;
 
 	sock->ops = answer->ops;
-
 	answer_prot = answer->prot;
 	answer_no_check = answer->no_check;
 	answer_flags = answer->flags;
@@ -135,19 +154,20 @@
 
 	BUG_TRAP(answer_prot->slab != NULL);
 
-	rc = -ENOBUFS;
+	err = -ENOBUFS;
 	sk = sk_alloc(PF_INET6, GFP_KERNEL, answer_prot, 1);
 	if (sk == NULL)
 		goto out;
 
 	sock_init_data(sock, sk);
 
-	rc = 0;
+	err = 0;
 	sk->sk_no_check = answer_no_check;
 	if (INET_PROTOSW_REUSE & answer_flags)
 		sk->sk_reuse = 1;
 
 	inet = inet_sk(sk);
+	inet->is_icsk = INET_PROTOSW_ICSK & answer_flags;
 
 	if (SOCK_RAW == sock->type) {
 		inet->num = protocol;
@@ -202,14 +222,14 @@
 		sk->sk_prot->hash(sk);
 	}
 	if (sk->sk_prot->init) {
-		rc = sk->sk_prot->init(sk);
-		if (rc) {
+		err = sk->sk_prot->init(sk);
+		if (err) {
 			sk_common_release(sk);
 			goto out;
 		}
 	}
 out:
-	return rc;
+	return err;
 out_rcu_unlock:
 	rcu_read_unlock();
 	goto out;
@@ -370,6 +390,8 @@
 	return 0;
 }
 
+EXPORT_SYMBOL_GPL(inet6_destroy_sock);
+
 /*
  *	This does both peername and sockname.
  */
@@ -412,7 +434,6 @@
 int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
 	struct sock *sk = sock->sk;
-	int err = -EINVAL;
 
 	switch(cmd) 
 	{
@@ -431,16 +452,15 @@
 	case SIOCSIFDSTADDR:
 		return addrconf_set_dstaddr((void __user *) arg);
 	default:
-		if (!sk->sk_prot->ioctl ||
-		    (err = sk->sk_prot->ioctl(sk, cmd, arg)) == -ENOIOCTLCMD)
-			return(dev_ioctl(cmd,(void __user *) arg));		
-		return err;
+		if (!sk->sk_prot->ioctl)
+			return -ENOIOCTLCMD;
+		return sk->sk_prot->ioctl(sk, cmd, arg);
 	}
 	/*NOTREACHED*/
 	return(0);
 }
 
-struct proto_ops inet6_stream_ops = {
+const struct proto_ops inet6_stream_ops = {
 	.family =	PF_INET6,
 	.owner =	THIS_MODULE,
 	.release =	inet6_release,
@@ -461,7 +481,7 @@
 	.sendpage =	tcp_sendpage
 };
 
-struct proto_ops inet6_dgram_ops = {
+const struct proto_ops inet6_dgram_ops = {
 	.family =	PF_INET6,
 	.owner =	THIS_MODULE,
 	.release =	inet6_release,
@@ -489,7 +509,7 @@
 };
 
 /* Same as inet6_dgram_ops, sans udp_poll.  */
-static struct proto_ops inet6_sockraw_ops = {
+static const struct proto_ops inet6_sockraw_ops = {
 	.family =	PF_INET6,
 	.owner =	THIS_MODULE,
 	.release =	inet6_release,
@@ -590,17 +610,90 @@
 	}
 }
 
+int inet6_sk_rebuild_header(struct sock *sk)
+{
+	int err;
+	struct dst_entry *dst;
+	struct ipv6_pinfo *np = inet6_sk(sk);
+
+	dst = __sk_dst_check(sk, np->dst_cookie);
+
+	if (dst == NULL) {
+		struct inet_sock *inet = inet_sk(sk);
+		struct in6_addr *final_p = NULL, final;
+		struct flowi fl;
+
+		memset(&fl, 0, sizeof(fl));
+		fl.proto = sk->sk_protocol;
+		ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+		fl.fl6_flowlabel = np->flow_label;
+		fl.oif = sk->sk_bound_dev_if;
+		fl.fl_ip_dport = inet->dport;
+		fl.fl_ip_sport = inet->sport;
+
+		if (np->opt && np->opt->srcrt) {
+			struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
+			ipv6_addr_copy(&final, &fl.fl6_dst);
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+			final_p = &final;
+		}
+
+		err = ip6_dst_lookup(sk, &dst, &fl);
+		if (err) {
+			sk->sk_route_caps = 0;
+			return err;
+		}
+		if (final_p)
+			ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+			sk->sk_err_soft = -err;
+			return err;
+		}
+
+		ip6_dst_store(sk, dst, NULL);
+		sk->sk_route_caps = dst->dev->features &
+			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+	}
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(inet6_sk_rebuild_header);
+
+int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct inet6_skb_parm *opt = IP6CB(skb);
+
+	if (np->rxopt.all) {
+		if ((opt->hop && (np->rxopt.bits.hopopts ||
+				  np->rxopt.bits.ohopopts)) ||
+		    ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) &&
+		     np->rxopt.bits.rxflow) ||
+		    (opt->srcrt && (np->rxopt.bits.srcrt ||
+		     np->rxopt.bits.osrcrt)) ||
+		    ((opt->dst1 || opt->dst0) &&
+		     (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
+			return 1;
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(ipv6_opt_accepted);
+
 int
 snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign)
 {
 	if (ptr == NULL)
 		return -EINVAL;
 
-	ptr[0] = __alloc_percpu(mibsize, mibalign);
+	ptr[0] = __alloc_percpu(mibsize);
 	if (!ptr[0])
 		goto err0;
 
-	ptr[1] = __alloc_percpu(mibsize, mibalign);
+	ptr[1] = __alloc_percpu(mibsize);
 	if (!ptr[1])
 		goto err1;
 
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index f362973..13cc7f8 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -33,6 +33,7 @@
 #include <linux/string.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
+#include <net/protocol.h>
 #include <net/xfrm.h>
 #include <asm/scatterlist.h>
 
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 40d9a19..6de8ee1 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -36,6 +36,7 @@
 #include <linux/random.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
+#include <net/protocol.h>
 #include <linux/icmpv6.h>
 
 static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
@@ -248,7 +249,7 @@
 	if (esp->conf.padlen)
 		mtu = ALIGN(mtu, esp->conf.padlen);
 
-	return mtu + x->props.header_len + esp->auth.icv_full_len;
+	return mtu + x->props.header_len + esp->auth.icv_trunc_len;
 }
 
 static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index be6faf3..2a1e7e4 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -152,7 +152,7 @@
 	{-1,			NULL}
 };
 
-static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
+static int ipv6_destopt_rcv(struct sk_buff **skbp)
 {
 	struct sk_buff *skb = *skbp;
 	struct inet6_skb_parm *opt = IP6CB(skb);
@@ -169,7 +169,7 @@
 
 	if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
 		skb->h.raw += ((skb->h.raw[1]+1)<<3);
-		*nhoffp = opt->dst1;
+		opt->nhoff = opt->dst1;
 		return 1;
 	}
 
@@ -192,7 +192,7 @@
   NONE header. No data in packet.
  ********************************/
 
-static int ipv6_nodata_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
+static int ipv6_nodata_rcv(struct sk_buff **skbp)
 {
 	struct sk_buff *skb = *skbp;
 
@@ -215,7 +215,7 @@
   Routing header.
  ********************************/
 
-static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
+static int ipv6_rthdr_rcv(struct sk_buff **skbp)
 {
 	struct sk_buff *skb = *skbp;
 	struct inet6_skb_parm *opt = IP6CB(skb);
@@ -249,7 +249,7 @@
 		skb->h.raw += (hdr->hdrlen + 1) << 3;
 		opt->dst0 = opt->dst1;
 		opt->dst1 = 0;
-		*nhoffp = (&hdr->nexthdr) - skb->nh.raw;
+		opt->nhoff = (&hdr->nexthdr) - skb->nh.raw;
 		return 1;
 	}
 
@@ -413,6 +413,8 @@
 	return opt;
 }
 
+EXPORT_SYMBOL_GPL(ipv6_invert_rthdr);
+
 /**********************************
   Hop-by-hop options.
  **********************************/
@@ -485,9 +487,14 @@
 
 int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
 {
-	IP6CB(skb)->hop = sizeof(struct ipv6hdr);
-	if (ip6_parse_tlv(tlvprochopopt_lst, skb))
+	struct inet6_skb_parm *opt = IP6CB(skb);
+
+	opt->hop = sizeof(struct ipv6hdr);
+	if (ip6_parse_tlv(tlvprochopopt_lst, skb)) {
+		skb->h.raw += (skb->h.raw[1]+1)<<3;
+		opt->nhoff = sizeof(struct ipv6hdr);
 		return sizeof(struct ipv6hdr);
+	}
 	return -1;
 }
 
@@ -579,6 +586,8 @@
 	return opt2;
 }
 
+EXPORT_SYMBOL_GPL(ipv6_dup_options);
+
 static int ipv6_renew_option(void *ohdr,
 			     struct ipv6_opt_hdr __user *newopt, int newoptlen,
 			     int inherit,
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 1bdf0fb..53c81fc 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -79,7 +79,7 @@
 static DEFINE_PER_CPU(struct socket *, __icmpv6_socket) = NULL;
 #define icmpv6_socket	__get_cpu_var(__icmpv6_socket)
 
-static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp);
+static int icmpv6_rcv(struct sk_buff **pskb);
 
 static struct inet6_protocol icmpv6_protocol = {
 	.handler	=	icmpv6_rcv,
@@ -328,8 +328,10 @@
 		iif = skb->dev->ifindex;
 
 	/*
-	 *	Must not send if we know that source is Anycast also.
-	 *	for now we don't know that.
+	 *	Must not send error if the source does not uniquely
+	 *	identify a single node (RFC2463 Section 2.4).
+	 *	We check unspecified / multicast addresses here,
+	 *	and anycast addresses will be checked later.
 	 */
 	if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
 		LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n");
@@ -373,6 +375,16 @@
 	err = ip6_dst_lookup(sk, &dst, &fl);
 	if (err)
 		goto out;
+
+	/*
+	 * We won't send icmp if the destination is known
+	 * anycast.
+	 */
+	if (((struct rt6_info *)dst)->rt6i_flags & RTF_ANYCAST) {
+		LIMIT_NETDEBUG(KERN_DEBUG "icmpv6_send: acast source\n");
+		goto out_dst_release;
+	}
+
 	if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
 		goto out;
 
@@ -569,7 +581,7 @@
  *	Handle icmp messages
  */
 
-static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+static int icmpv6_rcv(struct sk_buff **pskb)
 {
 	struct sk_buff *skb = *pskb;
 	struct net_device *dev = skb->dev;
@@ -751,7 +763,7 @@
 	inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);
 }
 
-static struct icmp6_err {
+static const struct icmp6_err {
 	int err;
 	int fatal;
 } tab_unreach[] = {
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
new file mode 100644
index 0000000..f8f3a37
--- /dev/null
+++ b/net/ipv6/inet6_connection_sock.c
@@ -0,0 +1,200 @@
+/*
+ * INET        An implementation of the TCP/IP protocol suite for the LINUX
+ *             operating system.  INET is implemented using the  BSD Socket
+ *             interface as the means of communication with the user level.
+ *
+ *             Support for INET6 connection oriented protocols.
+ *
+ * Authors:    See the TCPv6 sources
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version
+ *             2 of the License, or(at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/in6.h>
+#include <linux/ipv6.h>
+#include <linux/jhash.h>
+
+#include <net/addrconf.h>
+#include <net/inet_connection_sock.h>
+#include <net/inet_ecn.h>
+#include <net/inet_hashtables.h>
+#include <net/ip6_route.h>
+#include <net/sock.h>
+#include <net/inet6_connection_sock.h>
+
+int inet6_csk_bind_conflict(const struct sock *sk,
+			    const struct inet_bind_bucket *tb)
+{
+	const struct sock *sk2;
+	const struct hlist_node *node;
+
+	/* We must walk the whole port owner list in this case. -DaveM */
+	sk_for_each_bound(sk2, node, &tb->owners) {
+		if (sk != sk2 &&
+		    (!sk->sk_bound_dev_if ||
+		     !sk2->sk_bound_dev_if ||
+		     sk->sk_bound_dev_if == sk2->sk_bound_dev_if) &&
+		    (!sk->sk_reuse || !sk2->sk_reuse ||
+		     sk2->sk_state == TCP_LISTEN) &&
+		     ipv6_rcv_saddr_equal(sk, sk2))
+			break;
+	}
+
+	return node != NULL;
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict);
+
+/*
+ * request_sock (formerly open request) hash tables.
+ */
+static u32 inet6_synq_hash(const struct in6_addr *raddr, const u16 rport,
+			   const u32 rnd, const u16 synq_hsize)
+{
+	u32 a = raddr->s6_addr32[0];
+	u32 b = raddr->s6_addr32[1];
+	u32 c = raddr->s6_addr32[2];
+
+	a += JHASH_GOLDEN_RATIO;
+	b += JHASH_GOLDEN_RATIO;
+	c += rnd;
+	__jhash_mix(a, b, c);
+
+	a += raddr->s6_addr32[3];
+	b += (u32)rport;
+	__jhash_mix(a, b, c);
+
+	return c & (synq_hsize - 1);
+}
+
+struct request_sock *inet6_csk_search_req(const struct sock *sk,
+					  struct request_sock ***prevp,
+					  const __u16 rport,
+					  const struct in6_addr *raddr,
+					  const struct in6_addr *laddr,
+					  const int iif)
+{
+	const struct inet_connection_sock *icsk = inet_csk(sk);
+	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
+	struct request_sock *req, **prev;
+
+	for (prev = &lopt->syn_table[inet6_synq_hash(raddr, rport,
+						     lopt->hash_rnd,
+						     lopt->nr_table_entries)];
+	     (req = *prev) != NULL;
+	     prev = &req->dl_next) {
+		const struct inet6_request_sock *treq = inet6_rsk(req);
+
+		if (inet_rsk(req)->rmt_port == rport &&
+		    req->rsk_ops->family == AF_INET6 &&
+		    ipv6_addr_equal(&treq->rmt_addr, raddr) &&
+		    ipv6_addr_equal(&treq->loc_addr, laddr) &&
+		    (!treq->iif || treq->iif == iif)) {
+			BUG_TRAP(req->sk == NULL);
+			*prevp = prev;
+			return req;
+		}
+	}
+
+	return NULL;
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_search_req);
+
+void inet6_csk_reqsk_queue_hash_add(struct sock *sk,
+				    struct request_sock *req,
+				    const unsigned long timeout)
+{
+	struct inet_connection_sock *icsk = inet_csk(sk);
+	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
+	const u32 h = inet6_synq_hash(&inet6_rsk(req)->rmt_addr,
+				      inet_rsk(req)->rmt_port,
+				      lopt->hash_rnd, lopt->nr_table_entries);
+
+	reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, timeout);
+	inet_csk_reqsk_queue_added(sk, timeout);
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_reqsk_queue_hash_add);
+
+void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
+
+	sin6->sin6_family = AF_INET6;
+	ipv6_addr_copy(&sin6->sin6_addr, &np->daddr);
+	sin6->sin6_port	= inet_sk(sk)->dport;
+	/* We do not store received flowlabel for TCP */
+	sin6->sin6_flowinfo = 0;
+	sin6->sin6_scope_id = 0;
+	if (sk->sk_bound_dev_if &&
+	    ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
+		sin6->sin6_scope_id = sk->sk_bound_dev_if;
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
+
+int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
+{
+	struct sock *sk = skb->sk;
+	struct inet_sock *inet = inet_sk(sk);
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct flowi fl;
+	struct dst_entry *dst;
+	struct in6_addr *final_p = NULL, final;
+
+	memset(&fl, 0, sizeof(fl));
+	fl.proto = sk->sk_protocol;
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+	ipv6_addr_copy(&fl.fl6_src, &np->saddr);
+	fl.fl6_flowlabel = np->flow_label;
+	IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
+	fl.oif = sk->sk_bound_dev_if;
+	fl.fl_ip_sport = inet->sport;
+	fl.fl_ip_dport = inet->dport;
+
+	if (np->opt && np->opt->srcrt) {
+		struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
+		ipv6_addr_copy(&final, &fl.fl6_dst);
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
+		final_p = &final;
+	}
+
+	dst = __sk_dst_check(sk, np->dst_cookie);
+
+	if (dst == NULL) {
+		int err = ip6_dst_lookup(sk, &dst, &fl);
+
+		if (err) {
+			sk->sk_err_soft = -err;
+			return err;
+		}
+
+		if (final_p)
+			ipv6_addr_copy(&fl.fl6_dst, final_p);
+
+		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
+			sk->sk_route_caps = 0;
+			return err;
+		}
+
+		ip6_dst_store(sk, dst, NULL);
+		sk->sk_route_caps = dst->dev->features &
+			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
+	}
+
+	skb->dst = dst_clone(dst);
+
+	/* Restore final destination back after routing done */
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+
+	return ip6_xmit(sk, skb, &fl, np->opt, 0);
+}
+
+EXPORT_SYMBOL_GPL(inet6_csk_xmit);
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 01d5f46..4154f3a 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -5,7 +5,8 @@
  *
  *		Generic INET6 transport hashtables
  *
- * Authors:	Lotsa people, from code originally in tcp
+ * Authors:	Lotsa people, from code originally in tcp, generalised here
+ * 		by Arnaldo Carvalho de Melo <acme@mandriva.com>
  *
  *	This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -14,12 +15,13 @@
  */
 
 #include <linux/config.h>
-
 #include <linux/module.h>
+#include <linux/random.h>
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_hashtables.h>
 #include <net/inet6_hashtables.h>
+#include <net/ip.h>
 
 struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
 				   const struct in6_addr *daddr,
@@ -79,3 +81,180 @@
 }
 
 EXPORT_SYMBOL_GPL(inet6_lookup);
+
+static int __inet6_check_established(struct inet_timewait_death_row *death_row,
+				     struct sock *sk, const __u16 lport,
+				     struct inet_timewait_sock **twp)
+{
+	struct inet_hashinfo *hinfo = death_row->hashinfo;
+	const struct inet_sock *inet = inet_sk(sk);
+	const struct ipv6_pinfo *np = inet6_sk(sk);
+	const struct in6_addr *daddr = &np->rcv_saddr;
+	const struct in6_addr *saddr = &np->daddr;
+	const int dif = sk->sk_bound_dev_if;
+	const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
+	const unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr,
+						inet->dport);
+	struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash);
+	struct sock *sk2;
+	const struct hlist_node *node;
+	struct inet_timewait_sock *tw;
+
+	prefetch(head->chain.first);
+	write_lock(&head->lock);
+
+	/* Check TIME-WAIT sockets first. */
+	sk_for_each(sk2, node, &(head + hinfo->ehash_size)->chain) {
+		const struct inet6_timewait_sock *tw6 = inet6_twsk(sk2);
+
+		tw = inet_twsk(sk2);
+
+		if(*((__u32 *)&(tw->tw_dport)) == ports		 &&
+		   sk2->sk_family	       == PF_INET6	 &&
+		   ipv6_addr_equal(&tw6->tw_v6_daddr, saddr)	 &&
+		   ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
+		   sk2->sk_bound_dev_if == sk->sk_bound_dev_if) {
+			if (twsk_unique(sk, sk2, twp))
+				goto unique;
+			else
+				goto not_unique;
+		}
+	}
+	tw = NULL;
+
+	/* And established part... */
+	sk_for_each(sk2, node, &head->chain) {
+		if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
+			goto not_unique;
+	}
+
+unique:
+	BUG_TRAP(sk_unhashed(sk));
+	__sk_add_node(sk, &head->chain);
+	sk->sk_hash = hash;
+	sock_prot_inc_use(sk->sk_prot);
+	write_unlock(&head->lock);
+
+	if (twp != NULL) {
+		*twp = tw;
+		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+	} else if (tw != NULL) {
+		/* Silly. Should hash-dance instead... */
+		inet_twsk_deschedule(tw, death_row);
+		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
+
+		inet_twsk_put(tw);
+	}
+	return 0;
+
+not_unique:
+	write_unlock(&head->lock);
+	return -EADDRNOTAVAIL;
+}
+
+static inline u32 inet6_sk_port_offset(const struct sock *sk)
+{
+	const struct inet_sock *inet = inet_sk(sk);
+	const struct ipv6_pinfo *np = inet6_sk(sk);
+	return secure_ipv6_port_ephemeral(np->rcv_saddr.s6_addr32,
+					  np->daddr.s6_addr32,
+					  inet->dport);
+}
+
+int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+		       struct sock *sk)
+{
+	struct inet_hashinfo *hinfo = death_row->hashinfo;
+	const unsigned short snum = inet_sk(sk)->num;
+ 	struct inet_bind_hashbucket *head;
+ 	struct inet_bind_bucket *tb;
+	int ret;
+
+ 	if (snum == 0) {
+ 		const int low = sysctl_local_port_range[0];
+ 		const int high = sysctl_local_port_range[1];
+		const int range = high - low;
+ 		int i, port;
+		static u32 hint;
+		const u32 offset = hint + inet6_sk_port_offset(sk);
+		struct hlist_node *node;
+ 		struct inet_timewait_sock *tw = NULL;
+
+ 		local_bh_disable();
+		for (i = 1; i <= range; i++) {
+			port = low + (i + offset) % range;
+ 			head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)];
+ 			spin_lock(&head->lock);
+
+ 			/* Does not bother with rcv_saddr checks,
+ 			 * because the established check is already
+ 			 * unique enough.
+ 			 */
+			inet_bind_bucket_for_each(tb, node, &head->chain) {
+ 				if (tb->port == port) {
+ 					BUG_TRAP(!hlist_empty(&tb->owners));
+ 					if (tb->fastreuse >= 0)
+ 						goto next_port;
+ 					if (!__inet6_check_established(death_row,
+								       sk, port,
+								       &tw))
+ 						goto ok;
+ 					goto next_port;
+ 				}
+ 			}
+
+ 			tb = inet_bind_bucket_create(hinfo->bind_bucket_cachep,
+						     head, port);
+ 			if (!tb) {
+ 				spin_unlock(&head->lock);
+ 				break;
+ 			}
+ 			tb->fastreuse = -1;
+ 			goto ok;
+
+ 		next_port:
+ 			spin_unlock(&head->lock);
+ 		}
+ 		local_bh_enable();
+
+ 		return -EADDRNOTAVAIL;
+
+ok:
+		hint += i;
+
+ 		/* Head lock still held and bh's disabled */
+ 		inet_bind_hash(sk, tb, port);
+		if (sk_unhashed(sk)) {
+ 			inet_sk(sk)->sport = htons(port);
+ 			__inet6_hash(hinfo, sk);
+ 		}
+ 		spin_unlock(&head->lock);
+
+ 		if (tw) {
+ 			inet_twsk_deschedule(tw, death_row);
+ 			inet_twsk_put(tw);
+ 		}
+
+		ret = 0;
+		goto out;
+ 	}
+
+ 	head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)];
+ 	tb   = inet_csk(sk)->icsk_bind_hash;
+	spin_lock_bh(&head->lock);
+
+	if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {
+		__inet6_hash(hinfo, sk);
+		spin_unlock_bh(&head->lock);
+		return 0;
+	} else {
+		spin_unlock(&head->lock);
+		/* No definite answer... Walk to established hash table */
+		ret = __inet6_check_established(death_row, sk, snum, NULL);
+out:
+		local_bh_enable();
+		return ret;
+	}
+}
+
+EXPORT_SYMBOL_GPL(inet6_hash_connect);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 1cf0276..89d12b4 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -200,6 +200,8 @@
 	return NULL;
 }
 
+EXPORT_SYMBOL_GPL(fl6_sock_lookup);
+
 void fl6_free_socklist(struct sock *sk)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index a6026d2..29f7359 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -48,7 +48,7 @@
 
 
 
-static inline int ip6_rcv_finish( struct sk_buff *skb) 
+inline int ip6_rcv_finish( struct sk_buff *skb) 
 {
 	if (skb->dst == NULL)
 		ip6_route_input(skb);
@@ -97,6 +97,9 @@
 	if (hdr->version != 6)
 		goto err;
 
+	skb->h.raw = (u8 *)(hdr + 1);
+	IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
+
 	pkt_len = ntohs(hdr->payload_len);
 
 	/* pkt_len may be zero if Jumbo payload option is present */
@@ -111,8 +114,7 @@
 	}
 
 	if (hdr->nexthdr == NEXTHDR_HOP) {
-		skb->h.raw = (u8*)(hdr+1);
-		if (ipv6_parse_hopopts(skb, offsetof(struct ipv6hdr, nexthdr)) < 0) {
+		if (ipv6_parse_hopopts(skb, IP6CB(skb)->nhoff) < 0) {
 			IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
 			return 0;
 		}
@@ -143,26 +145,15 @@
 	int nexthdr;
 	u8 hash;
 
-	skb->h.raw = skb->nh.raw + sizeof(struct ipv6hdr);
-
 	/*
 	 *	Parse extension headers
 	 */
 
-	nexthdr = skb->nh.ipv6h->nexthdr;
-	nhoff = offsetof(struct ipv6hdr, nexthdr);
-
-	/* Skip hop-by-hop options, they are already parsed. */
-	if (nexthdr == NEXTHDR_HOP) {
-		nhoff = sizeof(struct ipv6hdr);
-		nexthdr = skb->h.raw[0];
-		skb->h.raw += (skb->h.raw[1]+1)<<3;
-	}
-
 	rcu_read_lock();
 resubmit:
 	if (!pskb_pull(skb, skb->h.raw - skb->data))
 		goto discard;
+	nhoff = IP6CB(skb)->nhoff;
 	nexthdr = skb->nh.raw[nhoff];
 
 	raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
@@ -194,7 +185,7 @@
 		    !xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 
 			goto discard;
 		
-		ret = ipprot->handler(&skb, &nhoff);
+		ret = ipprot->handler(&skb);
 		if (ret > 0)
 			goto resubmit;
 		else if (ret == 0)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index c1fa693..b4c4beb 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -774,7 +774,10 @@
 	*dst = NULL;
 	return err;
 }
-inline int ip6_ufo_append_data(struct sock *sk,
+
+EXPORT_SYMBOL_GPL(ip6_dst_lookup);
+
+static inline int ip6_ufo_append_data(struct sock *sk,
 			int getfrag(void *from, char *to, int offset, int len,
 			int odd, struct sk_buff *skb),
 			void *from, int length, int hh_len, int fragheaderlen,
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index e315d0f..f079621 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -510,7 +510,7 @@
  **/
 
 static int 
-ip6ip6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+ip6ip6_rcv(struct sk_buff **pskb)
 {
 	struct sk_buff *skb = *pskb;
 	struct ipv6hdr *ipv6h;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 55917fb..626dd39 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -47,6 +47,7 @@
 #include <linux/rtnetlink.h>
 #include <net/icmp.h>
 #include <net/ipv6.h>
+#include <net/protocol.h>
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 25757ade..c63868d 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -163,17 +163,17 @@
 			sk_refcnt_debug_dec(sk);
 
 			if (sk->sk_protocol == IPPROTO_TCP) {
-				struct tcp_sock *tp = tcp_sk(sk);
+				struct inet_connection_sock *icsk = inet_csk(sk);
 
 				local_bh_disable();
 				sock_prot_dec_use(sk->sk_prot);
 				sock_prot_inc_use(&tcp_prot);
 				local_bh_enable();
 				sk->sk_prot = &tcp_prot;
-				tp->af_specific = &ipv4_specific;
+				icsk->icsk_af_ops = &ipv4_specific;
 				sk->sk_socket->ops = &inet_stream_ops;
 				sk->sk_family = PF_INET;
-				tcp_sync_mss(sk, tp->pmtu_cookie);
+				tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
 			} else {
 				local_bh_disable();
 				sock_prot_dec_use(sk->sk_prot);
@@ -317,14 +317,15 @@
 		}
 
 		retv = 0;
-		if (sk->sk_type == SOCK_STREAM) {
+		if (inet_sk(sk)->is_icsk) {
 			if (opt) {
-				struct tcp_sock *tp = tcp_sk(sk);
+				struct inet_connection_sock *icsk = inet_csk(sk);
 				if (!((1 << sk->sk_state) &
 				      (TCPF_LISTEN | TCPF_CLOSE))
 				    && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
-					tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
-					tcp_sync_mss(sk, tp->pmtu_cookie);
+					icsk->icsk_ext_hdr_len =
+						opt->opt_flen + opt->opt_nflen;
+					icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 				}
 			}
 			opt = xchg(&np->opt, opt);
@@ -380,14 +381,15 @@
 			goto done;
 update:
 		retv = 0;
-		if (sk->sk_type == SOCK_STREAM) {
+		if (inet_sk(sk)->is_icsk) {
 			if (opt) {
-				struct tcp_sock *tp = tcp_sk(sk);
+				struct inet_connection_sock *icsk = inet_csk(sk);
 				if (!((1 << sk->sk_state) &
 				      (TCPF_LISTEN | TCPF_CLOSE))
 				    && inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
-					tp->ext_header_len = opt->opt_flen + opt->opt_nflen;
-					tcp_sync_mss(sk, tp->pmtu_cookie);
+					icsk->icsk_ext_hdr_len =
+						opt->opt_flen + opt->opt_nflen;
+					icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
 				}
 			}
 			opt = xchg(&np->opt, opt);
@@ -628,8 +630,8 @@
 	return -EINVAL;
 }
 
-int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
-			   char __user *optval, int len)
+static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr,
+				  char __user *optval, int len)
 {
 	if (!hdr)
 		return 0;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index f15e04a..1cf305a 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -170,7 +170,7 @@
 #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
 #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
 
-#define IPV6_MLD_MAX_MSF	10
+#define IPV6_MLD_MAX_MSF	64
 
 int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF;
 
@@ -224,6 +224,7 @@
 
 	mc_lst->ifindex = dev->ifindex;
 	mc_lst->sfmode = MCAST_EXCLUDE;
+	rwlock_init(&mc_lst->sflock);
 	mc_lst->sflist = NULL;
 
 	/*
@@ -360,6 +361,7 @@
 	struct ip6_sf_socklist *psl;
 	int i, j, rv;
 	int leavegroup = 0;
+	int pmclocked = 0;
 	int err;
 
 	if (pgsr->gsr_group.ss_family != AF_INET6 ||
@@ -403,6 +405,9 @@
 		pmc->sfmode = omode;
 	}
 
+	write_lock_bh(&pmc->sflock);
+	pmclocked = 1;
+
 	psl = pmc->sflist;
 	if (!add) {
 		if (!psl)
@@ -475,6 +480,8 @@
 	/* update the interface list */
 	ip6_mc_add_src(idev, group, omode, 1, source, 1);
 done:
+	if (pmclocked)
+		write_unlock_bh(&pmc->sflock);
 	read_unlock_bh(&ipv6_sk_mc_lock);
 	read_unlock_bh(&idev->lock);
 	in6_dev_put(idev);
@@ -510,6 +517,8 @@
 	dev = idev->dev;
 
 	err = 0;
+	read_lock_bh(&ipv6_sk_mc_lock);
+
 	if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) {
 		leavegroup = 1;
 		goto done;
@@ -549,6 +558,8 @@
 		newpsl = NULL;
 		(void) ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0);
 	}
+
+	write_lock_bh(&pmc->sflock);
 	psl = pmc->sflist;
 	if (psl) {
 		(void) ip6_mc_del_src(idev, group, pmc->sfmode,
@@ -558,8 +569,10 @@
 		(void) ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0);
 	pmc->sflist = newpsl;
 	pmc->sfmode = gsf->gf_fmode;
+	write_unlock_bh(&pmc->sflock);
 	err = 0;
 done:
+	read_unlock_bh(&ipv6_sk_mc_lock);
 	read_unlock_bh(&idev->lock);
 	in6_dev_put(idev);
 	dev_put(dev);
@@ -592,6 +605,11 @@
 	dev = idev->dev;
 
 	err = -EADDRNOTAVAIL;
+	/*
+	 * changes to the ipv6_mc_list require the socket lock and
+	 * a read lock on ip6_sk_mc_lock. We have the socket lock,
+	 * so reading the list is safe.
+	 */
 
 	for (pmc=inet6->ipv6_mc_list; pmc; pmc=pmc->next) {
 		if (pmc->ifindex != gsf->gf_interface)
@@ -614,6 +632,10 @@
 	    copy_to_user(optval, gsf, GROUP_FILTER_SIZE(0))) {
 		return -EFAULT;
 	}
+	/* changes to psl require the socket lock, a read lock on
+	 * on ipv6_sk_mc_lock and a write lock on pmc->sflock. We
+	 * have the socket lock, so reading here is safe.
+	 */
 	for (i=0; i<copycount; i++) {
 		struct sockaddr_in6 *psin6;
 		struct sockaddr_storage ss;
@@ -650,6 +672,7 @@
 		read_unlock(&ipv6_sk_mc_lock);
 		return 1;
 	}
+	read_lock(&mc->sflock);
 	psl = mc->sflist;
 	if (!psl) {
 		rv = mc->sfmode == MCAST_EXCLUDE;
@@ -665,6 +688,7 @@
 		if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count)
 			rv = 0;
 	}
+	read_unlock(&mc->sflock);
 	read_unlock(&ipv6_sk_mc_lock);
 
 	return rv;
@@ -1068,7 +1092,8 @@
 	ma->mca_flags |= MAF_TIMER_RUNNING;
 }
 
-static void mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
+/* mark EXCLUDE-mode sources */
+static int mld_xmarksources(struct ifmcaddr6 *pmc, int nsrcs,
 	struct in6_addr *srcs)
 {
 	struct ip6_sf_list *psf;
@@ -1078,13 +1103,53 @@
 	for (psf=pmc->mca_sources; psf; psf=psf->sf_next) {
 		if (scount == nsrcs)
 			break;
-		for (i=0; i<nsrcs; i++)
+		for (i=0; i<nsrcs; i++) {
+			/* skip inactive filters */
+			if (pmc->mca_sfcount[MCAST_INCLUDE] ||
+			    pmc->mca_sfcount[MCAST_EXCLUDE] !=
+			    psf->sf_count[MCAST_EXCLUDE])
+				continue;
+			if (ipv6_addr_equal(&srcs[i], &psf->sf_addr)) {
+				scount++;
+				break;
+			}
+		}
+	}
+	pmc->mca_flags &= ~MAF_GSQUERY;
+	if (scount == nsrcs)	/* all sources excluded */
+		return 0;
+	return 1;
+}
+
+static int mld_marksources(struct ifmcaddr6 *pmc, int nsrcs,
+	struct in6_addr *srcs)
+{
+	struct ip6_sf_list *psf;
+	int i, scount;
+
+	if (pmc->mca_sfmode == MCAST_EXCLUDE)
+		return mld_xmarksources(pmc, nsrcs, srcs);
+
+	/* mark INCLUDE-mode sources */
+
+	scount = 0;
+	for (psf=pmc->mca_sources; psf; psf=psf->sf_next) {
+		if (scount == nsrcs)
+			break;
+		for (i=0; i<nsrcs; i++) {
 			if (ipv6_addr_equal(&srcs[i], &psf->sf_addr)) {
 				psf->sf_gsresp = 1;
 				scount++;
 				break;
 			}
+		}
 	}
+	if (!scount) {
+		pmc->mca_flags &= ~MAF_GSQUERY;
+		return 0;
+	}
+	pmc->mca_flags |= MAF_GSQUERY;
+	return 1;
 }
 
 int igmp6_event_query(struct sk_buff *skb)
@@ -1167,7 +1232,7 @@
 		/* mark sources to include, if group & source-specific */
 		if (mlh2->nsrcs != 0) {
 			if (!pskb_may_pull(skb, srcs_offset + 
-				mlh2->nsrcs * sizeof(struct in6_addr))) {
+			    ntohs(mlh2->nsrcs) * sizeof(struct in6_addr))) {
 				in6_dev_put(idev);
 				return -EINVAL;
 			}
@@ -1203,10 +1268,9 @@
 				else
 					ma->mca_flags &= ~MAF_GSQUERY;
 			}
-			if (ma->mca_flags & MAF_GSQUERY)
-				mld_marksources(ma, ntohs(mlh2->nsrcs),
-					mlh2->srcs);
-			igmp6_group_queried(ma, max_delay);
+			if (!(ma->mca_flags & MAF_GSQUERY) ||
+			   mld_marksources(ma, ntohs(mlh2->nsrcs), mlh2->srcs))
+				igmp6_group_queried(ma, max_delay);
 			spin_unlock_bh(&ma->mca_lock);
 			if (group_type != IPV6_ADDR_ANY)
 				break;
@@ -1231,6 +1295,11 @@
 	if (skb->pkt_type == PACKET_LOOPBACK)
 		return 0;
 
+	/* send our report if the MC router may not have heard this report */
+	if (skb->pkt_type != PACKET_MULTICAST &&
+	    skb->pkt_type != PACKET_BROADCAST)
+		return 0;
+
 	if (!pskb_may_pull(skb, sizeof(struct in6_addr)))
 		return -EINVAL;
 
@@ -1276,7 +1345,18 @@
 	case MLD2_MODE_IS_EXCLUDE:
 		if (gdeleted || sdeleted)
 			return 0;
-		return !((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp);
+		if (!((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp)) {
+			if (pmc->mca_sfmode == MCAST_INCLUDE)
+				return 1;
+			/* don't include if this source is excluded
+			 * in all filters
+			 */
+			if (psf->sf_count[MCAST_INCLUDE])
+				return 0;
+			return pmc->mca_sfcount[MCAST_EXCLUDE] ==
+				psf->sf_count[MCAST_EXCLUDE];
+		}
+		return 0;
 	case MLD2_CHANGE_TO_INCLUDE:
 		if (gdeleted || sdeleted)
 			return 0;
@@ -1445,7 +1525,7 @@
 	struct mld2_report *pmr;
 	struct mld2_grec *pgr = NULL;
 	struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list;
-	int scount, first, isquery, truncate;
+	int scount, stotal, first, isquery, truncate;
 
 	if (pmc->mca_flags & MAF_NOREPORT)
 		return skb;
@@ -1455,25 +1535,13 @@
 	truncate = type == MLD2_MODE_IS_EXCLUDE ||
 		    type == MLD2_CHANGE_TO_EXCLUDE;
 
+	stotal = scount = 0;
+
 	psf_list = sdeleted ? &pmc->mca_tomb : &pmc->mca_sources;
 
-	if (!*psf_list) {
-		if (type == MLD2_ALLOW_NEW_SOURCES ||
-		    type == MLD2_BLOCK_OLD_SOURCES)
-			return skb;
-		if (pmc->mca_crcount || isquery) {
-			/* make sure we have room for group header and at
-			 * least one source.
-			 */
-			if (skb && AVAILABLE(skb) < sizeof(struct mld2_grec)+
-			    sizeof(struct in6_addr)) {
-				mld_sendpack(skb);
-				skb = NULL; /* add_grhead will get a new one */
-			}
-			skb = add_grhead(skb, pmc, type, &pgr);
-		}
-		return skb;
-	}
+	if (!*psf_list)
+		goto empty_source;
+
 	pmr = skb ? (struct mld2_report *)skb->h.raw : NULL;
 
 	/* EX and TO_EX get a fresh packet, if needed */
@@ -1486,7 +1554,6 @@
 		}
 	}
 	first = 1;
-	scount = 0;
 	psf_prev = NULL;
 	for (psf=*psf_list; psf; psf=psf_next) {
 		struct in6_addr *psrc;
@@ -1520,7 +1587,7 @@
 		}
 		psrc = (struct in6_addr *)skb_put(skb, sizeof(*psrc));
 		*psrc = psf->sf_addr;
-		scount++;
+		scount++; stotal++;
 		if ((type == MLD2_ALLOW_NEW_SOURCES ||
 		     type == MLD2_BLOCK_OLD_SOURCES) && psf->sf_crcount) {
 			psf->sf_crcount--;
@@ -1535,6 +1602,21 @@
 		}
 		psf_prev = psf;
 	}
+
+empty_source:
+	if (!stotal) {
+		if (type == MLD2_ALLOW_NEW_SOURCES ||
+		    type == MLD2_BLOCK_OLD_SOURCES)
+			return skb;
+		if (pmc->mca_crcount || isquery) {
+			/* make sure we have room for group header */
+			if (skb && AVAILABLE(skb) < sizeof(struct mld2_grec)) {
+				mld_sendpack(skb);
+				skb = NULL; /* add_grhead will get a new one */
+			}
+			skb = add_grhead(skb, pmc, type, &pgr);
+		}
+	}
 	if (pgr)
 		pgr->grec_nsrcs = htons(scount);
 
@@ -1616,11 +1698,11 @@
 			skb = add_grec(skb, pmc, dtype, 1, 1);
 		}
 		if (pmc->mca_crcount) {
-			pmc->mca_crcount--;
 			if (pmc->mca_sfmode == MCAST_EXCLUDE) {
 				type = MLD2_CHANGE_TO_INCLUDE;
 				skb = add_grec(skb, pmc, type, 1, 0);
 			}
+			pmc->mca_crcount--;
 			if (pmc->mca_crcount == 0) {
 				mld_clear_zeros(&pmc->mca_tomb);
 				mld_clear_zeros(&pmc->mca_sources);
@@ -1654,12 +1736,12 @@
 
 		/* filter mode changes */
 		if (pmc->mca_crcount) {
-			pmc->mca_crcount--;
 			if (pmc->mca_sfmode == MCAST_EXCLUDE)
 				type = MLD2_CHANGE_TO_EXCLUDE;
 			else
 				type = MLD2_CHANGE_TO_INCLUDE;
 			skb = add_grec(skb, pmc, type, 0, 0);
+			pmc->mca_crcount--;
 		}
 		spin_unlock_bh(&pmc->mca_lock);
 	}
@@ -2018,6 +2100,9 @@
 {
 	int err;
 
+	/* callers have the socket lock and a write lock on ipv6_sk_mc_lock,
+	 * so no other readers or writers of iml or its sflist
+	 */
 	if (iml->sflist == 0) {
 		/* any-source empty exclude case */
 		return ip6_mc_del_src(idev, &iml->addr, iml->sfmode, 0, NULL, 0);
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index f8626eb..b636783 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -10,6 +10,7 @@
 #include <net/dst.h>
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
+#include <net/xfrm.h>
 
 int ip6_route_me_harder(struct sk_buff *skb)
 {
@@ -21,11 +22,17 @@
 		{ .ip6_u =
 		  { .daddr = iph->daddr,
 		    .saddr = iph->saddr, } },
-		.proto = iph->nexthdr,
 	};
 
 	dst = ip6_route_output(skb->sk, &fl);
 
+#ifdef CONFIG_XFRM
+	if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
+	    xfrm_decode_session(skb, &fl, AF_INET6) == 0)
+		if (xfrm_lookup(&skb->dst, &fl, skb->sk, 0))
+			return -1;
+#endif
+
 	if (dst->error) {
 		IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES);
 		LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 060d612..105dd69 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -179,6 +179,16 @@
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config IP6_NF_MATCH_POLICY
+	tristate "IPsec policy match support"
+	depends on IP6_NF_IPTABLES && XFRM
+	help
+	  Policy matching allows you to match packets based on the
+	  IPsec policy that was used during decapsulation/will
+	  be used during encapsulation.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 # The targets
 config IP6_NF_FILTER
 	tristate "Packet filtering"
@@ -211,7 +221,7 @@
 
 config IP6_NF_TARGET_NFQUEUE
 	tristate "NFQUEUE Target Support"
-	depends on IP_NF_IPTABLES
+	depends on IP6_NF_IPTABLES
 	help
 	  This Target replaced the old obsolete QUEUE target.
 
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 9ab5b2c..c0c809b 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -13,6 +13,7 @@
 obj-$(CONFIG_IP6_NF_MATCH_IPV6HEADER) += ip6t_ipv6header.o
 obj-$(CONFIG_IP6_NF_MATCH_FRAG) += ip6t_frag.o
 obj-$(CONFIG_IP6_NF_MATCH_AHESP) += ip6t_esp.o ip6t_ah.o
+obj-$(CONFIG_IP6_NF_MATCH_POLICY) += ip6t_policy.o
 obj-$(CONFIG_IP6_NF_MATCH_EUI64) += ip6t_eui64.o
 obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
 obj-$(CONFIG_IP6_NF_MATCH_OWNER) += ip6t_owner.o
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 7d49222..925b42d4 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -15,6 +15,7 @@
  *      - new extension header parser code
  */
 #include <linux/config.h>
+#include <linux/in.h>
 #include <linux/skbuff.h>
 #include <linux/kmod.h>
 #include <linux/vmalloc.h>
@@ -86,11 +87,6 @@
    context stops packets coming through and allows user context to read
    the counters or update the rules.
 
-   To be cache friendly on SMP, we arrange them like so:
-   [ n-entries ]
-   ... cache-align padding ...
-   [ n-entries ]
-
    Hence the start of any table is given by get_table() below.  */
 
 /* The table itself */
@@ -108,33 +104,29 @@
 	unsigned int underflow[NF_IP6_NUMHOOKS];
 
 	/* ip6t_entry tables: one per CPU */
-	char entries[0] ____cacheline_aligned;
+	void *entries[NR_CPUS];
 };
 
 static LIST_HEAD(ip6t_target);
 static LIST_HEAD(ip6t_match);
 static LIST_HEAD(ip6t_tables);
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
 #define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
 
-#ifdef CONFIG_SMP
-#define TABLE_OFFSET(t,p) (SMP_ALIGN((t)->size)*(p))
-#else
-#define TABLE_OFFSET(t,p) 0
-#endif
-
 #if 0
 #define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0)
 #define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; })
 #define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0)
 #endif
 
-static int ip6_masked_addrcmp(struct in6_addr addr1, struct in6_addr mask,
-			      struct in6_addr addr2)
+int
+ip6_masked_addrcmp(const struct in6_addr *addr1, const struct in6_addr *mask,
+                   const struct in6_addr *addr2)
 {
 	int i;
 	for( i = 0; i < 16; i++){
-		if((addr1.s6_addr[i] & mask.s6_addr[i]) != 
-		   (addr2.s6_addr[i] & mask.s6_addr[i]))
+		if((addr1->s6_addr[i] & mask->s6_addr[i]) != 
+		   (addr2->s6_addr[i] & mask->s6_addr[i]))
 			return 1;
 	}
 	return 0;
@@ -168,10 +160,10 @@
 
 #define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
 
-	if (FWINV(ip6_masked_addrcmp(ipv6->saddr,ip6info->smsk,ip6info->src),
-		  IP6T_INV_SRCIP)
-	    || FWINV(ip6_masked_addrcmp(ipv6->daddr,ip6info->dmsk,ip6info->dst),
-		     IP6T_INV_DSTIP)) {
+	if (FWINV(ip6_masked_addrcmp(&ipv6->saddr, &ip6info->smsk,
+	                             &ip6info->src), IP6T_INV_SRCIP)
+	    || FWINV(ip6_masked_addrcmp(&ipv6->daddr, &ip6info->dmsk,
+	                                &ip6info->dst), IP6T_INV_DSTIP)) {
 		dprintf("Source or dest mismatch.\n");
 /*
 		dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
@@ -214,69 +206,21 @@
 
 	/* look for the desired protocol header */
 	if((ip6info->flags & IP6T_F_PROTO)) {
-		u_int8_t currenthdr = ipv6->nexthdr;
-		struct ipv6_opt_hdr _hdr, *hp;
-		u_int16_t ptr;		/* Header offset in skb */
-		u_int16_t hdrlen;	/* Header */
-		u_int16_t _fragoff = 0, *fp = NULL;
+		int protohdr;
+		unsigned short _frag_off;
 
-		ptr = IPV6_HDR_LEN;
+		protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off);
+		if (protohdr < 0)
+			return 0;
 
-		while (ip6t_ext_hdr(currenthdr)) {
-	                /* Is there enough space for the next ext header? */
-	                if (skb->len - ptr < IPV6_OPTHDR_LEN)
-	                        return 0;
-
-			/* NONE or ESP: there isn't protocol part */
-			/* If we want to count these packets in '-p all',
-			 * we will change the return 0 to 1*/
-			if ((currenthdr == IPPROTO_NONE) || 
-				(currenthdr == IPPROTO_ESP))
-				break;
-
-			hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
-			BUG_ON(hp == NULL);
-
-			/* Size calculation */
-	                if (currenthdr == IPPROTO_FRAGMENT) {
-				fp = skb_header_pointer(skb,
-						   ptr+offsetof(struct frag_hdr,
-								frag_off),
-						   sizeof(_fragoff),
-						   &_fragoff);
-				if (fp == NULL)
-					return 0;
-
-				_fragoff = ntohs(*fp) & ~0x7;
-	                        hdrlen = 8;
-	                } else if (currenthdr == IPPROTO_AH)
-	                        hdrlen = (hp->hdrlen+2)<<2;
-	                else
-	                        hdrlen = ipv6_optlen(hp);
-
-			currenthdr = hp->nexthdr;
-	                ptr += hdrlen;
-			/* ptr is too large */
-	                if ( ptr > skb->len ) 
-				return 0;
-			if (_fragoff) {
-				if (ip6t_ext_hdr(currenthdr))
-					return 0;
-				break;
-			}
-		}
-
-		*protoff = ptr;
-		*fragoff = _fragoff;
-
-		/* currenthdr contains the protocol header */
+		*fragoff = _frag_off;
 
 		dprintf("Packet protocol %hi ?= %s%hi.\n",
-				currenthdr, 
+				protohdr, 
 				ip6info->invflags & IP6T_INV_PROTO ? "!":"",
 				ip6info->proto);
 
-		if (ip6info->proto == currenthdr) {
+		if (ip6info->proto == protohdr) {
 			if(ip6info->invflags & IP6T_INV_PROTO) {
 				return 0;
 			}
@@ -376,8 +320,7 @@
 
 	read_lock_bh(&table->lock);
 	IP_NF_ASSERT(table->valid_hooks & (1 << hook));
-	table_base = (void *)table->private->entries
-		+ TABLE_OFFSET(table->private, smp_processor_id());
+	table_base = (void *)table->private->entries[smp_processor_id()];
 	e = get_entry(table_base, table->private->hook_entry[hook]);
 
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -649,7 +592,8 @@
 /* Figures out from what hook each rule can be called: returns 0 if
    there are loops.  Puts hook bitmask in comefrom. */
 static int
-mark_source_chains(struct ip6t_table_info *newinfo, unsigned int valid_hooks)
+mark_source_chains(struct ip6t_table_info *newinfo,
+		   unsigned int valid_hooks, void *entry0)
 {
 	unsigned int hook;
 
@@ -658,7 +602,7 @@
 	for (hook = 0; hook < NF_IP6_NUMHOOKS; hook++) {
 		unsigned int pos = newinfo->hook_entry[hook];
 		struct ip6t_entry *e
-			= (struct ip6t_entry *)(newinfo->entries + pos);
+			= (struct ip6t_entry *)(entry0 + pos);
 
 		if (!(valid_hooks & (1 << hook)))
 			continue;
@@ -708,13 +652,13 @@
 						goto next;
 
 					e = (struct ip6t_entry *)
-						(newinfo->entries + pos);
+						(entry0 + pos);
 				} while (oldpos == pos + e->next_offset);
 
 				/* Move along one */
 				size = e->next_offset;
 				e = (struct ip6t_entry *)
-					(newinfo->entries + pos + size);
+					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
 			} else {
@@ -731,7 +675,7 @@
 					newpos = pos + e->next_offset;
 				}
 				e = (struct ip6t_entry *)
-					(newinfo->entries + newpos);
+					(entry0 + newpos);
 				e->counters.pcnt = pos;
 				pos = newpos;
 			}
@@ -941,6 +885,7 @@
 translate_table(const char *name,
 		unsigned int valid_hooks,
 		struct ip6t_table_info *newinfo,
+		void *entry0,
 		unsigned int size,
 		unsigned int number,
 		const unsigned int *hook_entries,
@@ -961,11 +906,11 @@
 	duprintf("translate_table: size %u\n", newinfo->size);
 	i = 0;
 	/* Walk through entries, checking offsets. */
-	ret = IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry_size_and_hooks,
 				newinfo,
-				newinfo->entries,
-				newinfo->entries + size,
+				entry0,
+				entry0 + size,
 				hook_entries, underflows, &i);
 	if (ret != 0)
 		return ret;
@@ -993,27 +938,24 @@
 		}
 	}
 
-	if (!mark_source_chains(newinfo, valid_hooks))
+	if (!mark_source_chains(newinfo, valid_hooks, entry0))
 		return -ELOOP;
 
 	/* Finally, each sanity check must pass */
 	i = 0;
-	ret = IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+	ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
 				check_entry, name, size, &i);
 
 	if (ret != 0) {
-		IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size,
+		IP6T_ENTRY_ITERATE(entry0, newinfo->size,
 				  cleanup_entry, &i);
 		return ret;
 	}
 
 	/* And one copy for every other CPU */
 	for_each_cpu(i) {
-		if (i == 0)
-			continue;
-		memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
-		       newinfo->entries,
-		       SMP_ALIGN(newinfo->size));
+		if (newinfo->entries[i] && newinfo->entries[i] != entry0)
+			memcpy(newinfo->entries[i], entry0, newinfo->size);
 	}
 
 	return ret;
@@ -1029,15 +971,12 @@
 
 #ifdef CONFIG_NETFILTER_DEBUG
 	{
-		struct ip6t_entry *table_base;
-		unsigned int i;
+		int cpu;
 
-		for_each_cpu(i) {
-			table_base =
-				(void *)newinfo->entries
-				+ TABLE_OFFSET(newinfo, i);
-
-			table_base->comefrom = 0xdead57ac;
+		for_each_cpu(cpu) {
+			struct ip6t_entry *table_base = newinfo->entries[cpu];
+			if (table_base)
+				table_base->comefrom = 0xdead57ac;
 		}
 	}
 #endif
@@ -1072,16 +1011,44 @@
 	return 0;
 }
 
+static inline int
+set_entry_to_counter(const struct ip6t_entry *e,
+		     struct ip6t_counters total[],
+		     unsigned int *i)
+{
+	SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt);
+
+	(*i)++;
+	return 0;
+}
+
 static void
 get_counters(const struct ip6t_table_info *t,
 	     struct ip6t_counters counters[])
 {
 	unsigned int cpu;
 	unsigned int i;
+	unsigned int curcpu;
+
+	/* Instead of clearing (by a previous call to memset())
+	 * the counters and using adds, we set the counters
+	 * with data used by 'current' CPU
+	 * We dont care about preemption here.
+	 */
+	curcpu = raw_smp_processor_id();
+
+	i = 0;
+	IP6T_ENTRY_ITERATE(t->entries[curcpu],
+			   t->size,
+			   set_entry_to_counter,
+			   counters,
+			   &i);
 
 	for_each_cpu(cpu) {
+		if (cpu == curcpu)
+			continue;
 		i = 0;
-		IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
+		IP6T_ENTRY_ITERATE(t->entries[cpu],
 				  t->size,
 				  add_entry_to_counter,
 				  counters,
@@ -1098,6 +1065,7 @@
 	struct ip6t_entry *e;
 	struct ip6t_counters *counters;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	/* We need atomic snapshot of counters: rest doesn't change
 	   (other than comefrom, which userspace doesn't care
@@ -1109,13 +1077,13 @@
 		return -ENOMEM;
 
 	/* First, sum counters... */
-	memset(counters, 0, countersize);
 	write_lock_bh(&table->lock);
 	get_counters(table->private, counters);
 	write_unlock_bh(&table->lock);
 
-	/* ... then copy entire thing from CPU 0... */
-	if (copy_to_user(userptr, table->private->entries, total_size) != 0) {
+	/* choose the copy that is on ourc node/cpu */
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
 		ret = -EFAULT;
 		goto free_counters;
 	}
@@ -1127,7 +1095,7 @@
 		struct ip6t_entry_match *m;
 		struct ip6t_entry_target *t;
 
-		e = (struct ip6t_entry *)(table->private->entries + off);
+		e = (struct ip6t_entry *)(loc_cpu_entry + off);
 		if (copy_to_user(userptr + off
 				 + offsetof(struct ip6t_entry, counters),
 				 &counters[num],
@@ -1196,6 +1164,46 @@
 	return ret;
 }
 
+static void free_table_info(struct ip6t_table_info *info)
+{
+	int cpu;
+	for_each_cpu(cpu) {
+		if (info->size <= PAGE_SIZE)
+			kfree(info->entries[cpu]);
+		else
+			vfree(info->entries[cpu]);
+	}
+	kfree(info);
+}
+
+static struct ip6t_table_info *alloc_table_info(unsigned int size)
+{
+	struct ip6t_table_info *newinfo;
+	int cpu;
+
+	newinfo = kzalloc(sizeof(struct ip6t_table_info), GFP_KERNEL);
+	if (!newinfo)
+		return NULL;
+
+	newinfo->size = size;
+
+	for_each_cpu(cpu) {
+		if (size <= PAGE_SIZE)
+			newinfo->entries[cpu] = kmalloc_node(size,
+							GFP_KERNEL,
+							cpu_to_node(cpu));
+		else
+			newinfo->entries[cpu] = vmalloc_node(size,
+							     cpu_to_node(cpu));
+		if (newinfo->entries[cpu] == NULL) {
+			free_table_info(newinfo);
+			return NULL;
+		}
+	}
+
+	return newinfo;
+}
+
 static int
 do_replace(void __user *user, unsigned int len)
 {
@@ -1204,6 +1212,7 @@
 	struct ip6t_table *t;
 	struct ip6t_table_info *newinfo, *oldinfo;
 	struct ip6t_counters *counters;
+	void *loc_cpu_entry, *loc_cpu_old_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1212,13 +1221,13 @@
 	if ((SMP_ALIGN(tmp.size) >> PAGE_SHIFT) + 2 > num_physpages)
 		return -ENOMEM;
 
-	newinfo = vmalloc(sizeof(struct ip6t_table_info)
-			  + SMP_ALIGN(tmp.size) *
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(tmp.size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	if (copy_from_user(newinfo->entries, user + sizeof(tmp),
+	/* choose the copy that is on our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
 			   tmp.size) != 0) {
 		ret = -EFAULT;
 		goto free_newinfo;
@@ -1229,10 +1238,9 @@
 		ret = -ENOMEM;
 		goto free_newinfo;
 	}
-	memset(counters, 0, tmp.num_counters * sizeof(struct ip6t_counters));
 
 	ret = translate_table(tmp.name, tmp.valid_hooks,
-			      newinfo, tmp.size, tmp.num_entries,
+			      newinfo, loc_cpu_entry, tmp.size, tmp.num_entries,
 			      tmp.hook_entry, tmp.underflow);
 	if (ret != 0)
 		goto free_newinfo_counters;
@@ -1271,8 +1279,9 @@
 	/* Get the old counters. */
 	get_counters(oldinfo, counters);
 	/* Decrease module usage counts and free resource */
-	IP6T_ENTRY_ITERATE(oldinfo->entries, oldinfo->size, cleanup_entry,NULL);
-	vfree(oldinfo);
+	loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
+	IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry,NULL);
+	free_table_info(oldinfo);
 	if (copy_to_user(tmp.counters, counters,
 			 sizeof(struct ip6t_counters) * tmp.num_counters) != 0)
 		ret = -EFAULT;
@@ -1284,11 +1293,11 @@
 	module_put(t->me);
 	up(&ip6t_mutex);
  free_newinfo_counters_untrans:
-	IP6T_ENTRY_ITERATE(newinfo->entries, newinfo->size, cleanup_entry,NULL);
+	IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry,NULL);
  free_newinfo_counters:
 	vfree(counters);
  free_newinfo:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	return ret;
 }
 
@@ -1321,6 +1330,7 @@
 	struct ip6t_counters_info tmp, *paddc;
 	struct ip6t_table *t;
 	int ret = 0;
+	void *loc_cpu_entry;
 
 	if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
 		return -EFAULT;
@@ -1350,7 +1360,9 @@
 	}
 
 	i = 0;
-	IP6T_ENTRY_ITERATE(t->private->entries,
+	/* Choose the copy that is on our node */
+	loc_cpu_entry = t->private->entries[smp_processor_id()];
+	IP6T_ENTRY_ITERATE(loc_cpu_entry,
 			  t->private->size,
 			  add_counter_to_entry,
 			  paddc->counters,
@@ -1543,28 +1555,29 @@
 	struct ip6t_table_info *newinfo;
 	static struct ip6t_table_info bootstrap
 		= { 0, 0, 0, { 0 }, { 0 }, { } };
+	void *loc_cpu_entry;
 
-	newinfo = vmalloc(sizeof(struct ip6t_table_info)
-			  + SMP_ALIGN(repl->size) *
-			  		(highest_possible_processor_id()+1));
+	newinfo = alloc_table_info(repl->size);
 	if (!newinfo)
 		return -ENOMEM;
 
-	memcpy(newinfo->entries, repl->entries, repl->size);
+	/* choose the copy on our node/cpu */
+	loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
+	memcpy(loc_cpu_entry, repl->entries, repl->size);
 
 	ret = translate_table(table->name, table->valid_hooks,
-			      newinfo, repl->size,
+			      newinfo, loc_cpu_entry, repl->size,
 			      repl->num_entries,
 			      repl->hook_entry,
 			      repl->underflow);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
 	ret = down_interruptible(&ip6t_mutex);
 	if (ret != 0) {
-		vfree(newinfo);
+		free_table_info(newinfo);
 		return ret;
 	}
 
@@ -1593,20 +1606,23 @@
 	return ret;
 
  free_unlock:
-	vfree(newinfo);
+	free_table_info(newinfo);
 	goto unlock;
 }
 
 void ip6t_unregister_table(struct ip6t_table *table)
 {
+	void *loc_cpu_entry;
+
 	down(&ip6t_mutex);
 	LIST_DELETE(&ip6t_tables, table);
 	up(&ip6t_mutex);
 
 	/* Decrease module usage counts and free resources */
-	IP6T_ENTRY_ITERATE(table->private->entries, table->private->size,
+	loc_cpu_entry = table->private->entries[raw_smp_processor_id()];
+	IP6T_ENTRY_ITERATE(loc_cpu_entry, table->private->size,
 			  cleanup_entry, NULL);
-	vfree(table->private);
+	free_table_info(table->private);
 }
 
 /* Returns 1 if the port is matched by the range, 0 otherwise */
@@ -1972,7 +1988,7 @@
 	return pos;
 }
 
-static struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] =
+static const struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] =
 { { "ip6_tables_names", ip6t_get_tables },
   { "ip6_tables_targets", ip6t_get_targets },
   { "ip6_tables_matches", ip6t_get_matches },
@@ -2035,26 +2051,39 @@
 }
 
 /*
- * find specified header up to transport protocol header.
- * If found target header, the offset to the header is set to *offset
- * and return 0. otherwise, return -1.
+ * find the offset to specified header or the protocol number of last header
+ * if target < 0. "last header" is transport protocol header, ESP, or
+ * "No next header".
  *
- * Notes: - non-1st Fragment Header isn't skipped.
- *	  - ESP header isn't skipped.
- *	  - The target header may be trancated.
+ * If target header is found, its offset is set in *offset and return protocol
+ * number. Otherwise, return -1.
+ *
+ * Note that non-1st fragment is special case that "the protocol number
+ * of last header" is "next header" field in Fragment header. In this case,
+ * *offset is meaningless and fragment offset is stored in *fragoff if fragoff
+ * isn't NULL.
+ *
  */
-int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, u8 target)
+int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
+		  int target, unsigned short *fragoff)
 {
 	unsigned int start = (u8*)(skb->nh.ipv6h + 1) - skb->data;
 	u8 nexthdr = skb->nh.ipv6h->nexthdr;
 	unsigned int len = skb->len - start;
 
+	if (fragoff)
+		*fragoff = 0;
+
 	while (nexthdr != target) {
 		struct ipv6_opt_hdr _hdr, *hp;
 		unsigned int hdrlen;
 
-		if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE)
+		if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
+			if (target < 0)
+				break;
 			return -1;
+		}
+
 		hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
 		if (hp == NULL)
 			return -1;
@@ -2068,8 +2097,17 @@
 			if (fp == NULL)
 				return -1;
 
-			if (ntohs(*fp) & ~0x7)
+			_frag_off = ntohs(*fp) & ~0x7;
+			if (_frag_off) {
+				if (target < 0 &&
+				    ((!ipv6_ext_hdr(hp->nexthdr)) ||
+				     nexthdr == NEXTHDR_NONE)) {
+					if (fragoff)
+						*fragoff = _frag_off;
+					return hp->nexthdr;
+				}
 				return -1;
+			}
 			hdrlen = 8;
 		} else if (nexthdr == NEXTHDR_AUTH)
 			hdrlen = (hp->hdrlen + 2) << 2; 
@@ -2082,7 +2120,7 @@
 	}
 
 	*offset = start;
-	return 0;
+	return nexthdr;
 }
 
 EXPORT_SYMBOL(ip6t_register_table);
@@ -2094,6 +2132,7 @@
 EXPORT_SYMBOL(ip6t_unregister_target);
 EXPORT_SYMBOL(ip6t_ext_hdr);
 EXPORT_SYMBOL(ipv6_find_hdr);
+EXPORT_SYMBOL(ip6_masked_addrcmp);
 
 module_init(init);
 module_exit(fini);
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 0cd1d1b..ae4653b 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/skbuff.h>
+#include <linux/if_arp.h>
 #include <linux/ip.h>
 #include <linux/spinlock.h>
 #include <linux/icmpv6.h>
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index dde3779..f5c1a7f 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/types.h>
 #include <net/checksum.h>
@@ -53,7 +54,7 @@
 	unsigned int ptr;
 	unsigned int hdrlen = 0;
 
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH) < 0)
+	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0)
 		return 0;
 
 	ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
diff --git a/net/ipv6/netfilter/ip6t_dst.c b/net/ipv6/netfilter/ip6t_dst.c
index c450a63..48cf5f9 100644
--- a/net/ipv6/netfilter/ip6t_dst.c
+++ b/net/ipv6/netfilter/ip6t_dst.c
@@ -71,9 +71,9 @@
        unsigned int optlen;
        
 #if HOPBYHOP
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP) < 0)
+	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
 #else
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST) < 0)
+	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL) < 0)
 #endif
 		return 0;
 
diff --git a/net/ipv6/netfilter/ip6t_esp.c b/net/ipv6/netfilter/ip6t_esp.c
index 24bc0cd..e1828f6 100644
--- a/net/ipv6/netfilter/ip6t_esp.c
+++ b/net/ipv6/netfilter/ip6t_esp.c
@@ -9,6 +9,7 @@
 
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/types.h>
 #include <net/checksum.h>
@@ -55,7 +56,7 @@
 	/* Make sure this isn't an evil packet */
 	/*DEBUGP("ipv6_esp entered \n");*/
 
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP) < 0)
+	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ESP, NULL) < 0)
 		return 0;
 
 	eh = skb_header_pointer(skb, ptr, sizeof(_esp), &_esp);
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index 085d5f8..d1549b2 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -52,7 +52,7 @@
        const struct ip6t_frag *fraginfo = matchinfo;
        unsigned int ptr;
 
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT) < 0)
+	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0)
 		return 0;
 
 	fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index 1d09485..e3bc8e2 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -71,9 +71,9 @@
        unsigned int optlen;
        
 #if HOPBYHOP
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP) < 0)
+	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
 #else
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST) < 0)
+	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL) < 0)
 #endif
 		return 0;
 
diff --git a/net/ipv6/netfilter/ip6t_policy.c b/net/ipv6/netfilter/ip6t_policy.c
new file mode 100644
index 0000000..13fedad
--- /dev/null
+++ b/net/ipv6/netfilter/ip6t_policy.c
@@ -0,0 +1,175 @@
+/* IP tables module for matching IPsec policy
+ *
+ * Copyright (c) 2004,2005 Patrick McHardy, <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <net/xfrm.h>
+
+#include <linux/netfilter_ipv6.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_policy.h>
+
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("IPtables IPsec policy matching module");
+MODULE_LICENSE("GPL");
+
+
+static inline int
+match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e)
+{
+#define MATCH_ADDR(x,y,z)	(!e->match.x || \
+				 ((ip6_masked_addrcmp((z), &e->x, &e->y)) == 0) ^ e->invert.x)
+#define MATCH(x,y)		(!e->match.x || ((e->x == (y)) ^ e->invert.x))
+	
+	return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) &&
+	       MATCH_ADDR(daddr, dmask, (struct in6_addr *)&x->id.daddr.a6) &&
+	       MATCH(proto, x->id.proto) &&
+	       MATCH(mode, x->props.mode) &&
+	       MATCH(spi, x->id.spi) &&
+	       MATCH(reqid, x->props.reqid);
+}
+
+static int
+match_policy_in(const struct sk_buff *skb, const struct ip6t_policy_info *info)
+{
+	const struct ip6t_policy_elem *e;
+	struct sec_path *sp = skb->sp;
+	int strict = info->flags & IP6T_POLICY_MATCH_STRICT;
+	int i, pos;
+
+	if (sp == NULL)
+		return -1;
+	if (strict && info->len != sp->len)
+		return 0;
+
+	for (i = sp->len - 1; i >= 0; i--) {
+		pos = strict ? i - sp->len + 1 : 0;
+		if (pos >= info->len)
+			return 0;
+		e = &info->pol[pos];
+
+		if (match_xfrm_state(sp->x[i].xvec, e)) {
+			if (!strict)
+				return 1;
+		} else if (strict)
+			return 0;
+	}
+
+	return strict ? 1 : 0;
+}
+
+static int
+match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info)
+{
+	const struct ip6t_policy_elem *e;
+	struct dst_entry *dst = skb->dst;
+	int strict = info->flags & IP6T_POLICY_MATCH_STRICT;
+	int i, pos;
+
+	if (dst->xfrm == NULL)
+		return -1;
+
+	for (i = 0; dst && dst->xfrm; dst = dst->child, i++) {
+		pos = strict ? i : 0;
+		if (pos >= info->len)
+			return 0;
+		e = &info->pol[pos];
+
+		if (match_xfrm_state(dst->xfrm, e)) {
+			if (!strict)
+				return 1;
+		} else if (strict)
+			return 0;
+	}
+
+	return strict ? 1 : 0;
+}
+
+static int match(const struct sk_buff *skb,
+                 const struct net_device *in,
+                 const struct net_device *out,
+                 const void *matchinfo,
+		 int offset,
+		 unsigned int protoff,
+		 int *hotdrop)
+{
+	const struct ip6t_policy_info *info = matchinfo;
+	int ret;
+
+	if (info->flags & IP6T_POLICY_MATCH_IN)
+		ret = match_policy_in(skb, info);
+	else
+		ret = match_policy_out(skb, info);
+
+	if (ret < 0)
+		ret = info->flags & IP6T_POLICY_MATCH_NONE ? 1 : 0;
+	else if (info->flags & IP6T_POLICY_MATCH_NONE)
+		ret = 0;
+
+	return ret;
+}
+
+static int checkentry(const char *tablename, const struct ip6t_ip6 *ip,
+                      void *matchinfo, unsigned int matchsize,
+                      unsigned int hook_mask)
+{
+	struct ip6t_policy_info *info = matchinfo;
+
+	if (matchsize != IP6T_ALIGN(sizeof(*info))) {
+		printk(KERN_ERR "ip6t_policy: matchsize %u != %zu\n",
+		       matchsize, IP6T_ALIGN(sizeof(*info)));
+		return 0;
+	}
+	if (!(info->flags & (IP6T_POLICY_MATCH_IN|IP6T_POLICY_MATCH_OUT))) {
+		printk(KERN_ERR "ip6t_policy: neither incoming nor "
+		                "outgoing policy selected\n");
+		return 0;
+	}
+	if (hook_mask & (1 << NF_IP6_PRE_ROUTING | 1 << NF_IP6_LOCAL_IN)
+	    && info->flags & IP6T_POLICY_MATCH_OUT) {
+		printk(KERN_ERR "ip6t_policy: output policy not valid in "
+		                "PRE_ROUTING and INPUT\n");
+		return 0;
+	}
+	if (hook_mask & (1 << NF_IP6_POST_ROUTING | 1 << NF_IP6_LOCAL_OUT)
+	    && info->flags & IP6T_POLICY_MATCH_IN) {
+		printk(KERN_ERR "ip6t_policy: input policy not valid in "
+		                "POST_ROUTING and OUTPUT\n");
+		return 0;
+	}
+	if (info->len > IP6T_POLICY_MAX_ELEM) {
+		printk(KERN_ERR "ip6t_policy: too many policy elements\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+static struct ip6t_match policy_match = {
+	.name		= "policy",
+	.match		= match,
+	.checkentry 	= checkentry,
+	.me		= THIS_MODULE,
+};
+
+static int __init init(void)
+{
+	return ip6t_register_match(&policy_match);
+}
+
+static void __exit fini(void)
+{
+	ip6t_unregister_match(&policy_match);
+}
+
+module_init(init);
+module_exit(fini);
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index beb2fd5..c1e770e 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -58,7 +58,7 @@
        unsigned int ret = 0;
        struct in6_addr *ap, _addr;
 
-	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING) < 0)
+	if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0)
 		return 0;
 
        rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 753a3ae..704fbbe 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -401,6 +401,48 @@
 };
 #endif
 
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+static int ipv6_tuple_to_nfattr(struct sk_buff *skb,
+				const struct nf_conntrack_tuple *tuple)
+{
+	NFA_PUT(skb, CTA_IP_V6_SRC, sizeof(u_int32_t) * 4,
+		&tuple->src.u3.ip6);
+	NFA_PUT(skb, CTA_IP_V6_DST, sizeof(u_int32_t) * 4,
+		&tuple->dst.u3.ip6);
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+static const size_t cta_min_ip[CTA_IP_MAX] = {
+	[CTA_IP_V6_SRC-1]       = sizeof(u_int32_t)*4,
+	[CTA_IP_V6_DST-1]       = sizeof(u_int32_t)*4,
+};
+
+static int ipv6_nfattr_to_tuple(struct nfattr *tb[],
+				struct nf_conntrack_tuple *t)
+{
+	if (!tb[CTA_IP_V6_SRC-1] || !tb[CTA_IP_V6_DST-1])
+		return -EINVAL;
+
+	if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
+		return -EINVAL;
+
+	memcpy(&t->src.u3.ip6, NFA_DATA(tb[CTA_IP_V6_SRC-1]), 
+	       sizeof(u_int32_t) * 4);
+	memcpy(&t->dst.u3.ip6, NFA_DATA(tb[CTA_IP_V6_DST-1]),
+	       sizeof(u_int32_t) * 4);
+
+	return 0;
+}
+#endif
+
 struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
 	.l3proto		= PF_INET6,
 	.name			= "ipv6",
@@ -409,6 +451,11 @@
 	.print_tuple		= ipv6_print_tuple,
 	.print_conntrack	= ipv6_print_conntrack,
 	.prepare		= ipv6_prepare,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.tuple_to_nfattr	= ipv6_tuple_to_nfattr,
+	.nfattr_to_tuple	= ipv6_nfattr_to_tuple,
+#endif
 	.get_features		= ipv6_get_features,
 	.me			= THIS_MODULE,
 };
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index c0f1da5..09945c3 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -57,19 +57,19 @@
 	return 1;
 }
 
+/* Add 1; spaces filled with 0. */
+static u_int8_t invmap[] = {
+	[ICMPV6_ECHO_REQUEST - 128]	= ICMPV6_ECHO_REPLY + 1,
+	[ICMPV6_ECHO_REPLY - 128]	= ICMPV6_ECHO_REQUEST + 1,
+	[ICMPV6_NI_QUERY - 128]		= ICMPV6_NI_QUERY + 1,
+	[ICMPV6_NI_REPLY - 128]		= ICMPV6_NI_REPLY +1
+};
+
 static int icmpv6_invert_tuple(struct nf_conntrack_tuple *tuple,
 			       const struct nf_conntrack_tuple *orig)
 {
-	/* Add 1; spaces filled with 0. */
-	static u_int8_t invmap[] = {
-		[ICMPV6_ECHO_REQUEST - 128]	= ICMPV6_ECHO_REPLY + 1,
-		[ICMPV6_ECHO_REPLY - 128]	= ICMPV6_ECHO_REQUEST + 1,
-		[ICMPV6_NI_QUERY - 128]		= ICMPV6_NI_QUERY + 1,
-		[ICMPV6_NI_REPLY - 128]		= ICMPV6_NI_REPLY +1
-	};
-
-	__u8 type = orig->dst.u.icmp.type - 128;
-	if (type >= sizeof(invmap) || !invmap[type])
+	int type = orig->dst.u.icmp.type - 128;
+	if (type < 0 || type >= sizeof(invmap) || !invmap[type])
 		return 0;
 
 	tuple->src.u.icmp.id   = orig->src.u.icmp.id;
@@ -129,12 +129,12 @@
 		[ICMPV6_ECHO_REQUEST - 128] = 1,
 		[ICMPV6_NI_QUERY - 128] = 1
 	};
+	int type = conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128;
 
-	if (conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128 >= sizeof(valid_new)
-	    || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type - 128]) {
+	if (type < 0 || type >= sizeof(valid_new) || !valid_new[type]) {
 		/* Can't create a new ICMPv6 `conn' with this. */
-		DEBUGP("icmp: can't create new conn with type %u\n",
-		       conntrack->tuplehash[0].tuple.dst.u.icmp.type);
+		DEBUGP("icmpv6: can't create new conn with type %u\n",
+		       type + 128);
 		NF_CT_DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
 		return 0;
 	}
@@ -185,7 +185,7 @@
 		return -NF_ACCEPT;
 	}
 
-	inproto = nf_ct_find_proto(PF_INET6, inprotonum);
+	inproto = __nf_ct_proto_find(PF_INET6, inprotonum);
 
 	/* Are they talking about one of our connections? */
 	if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
@@ -255,6 +255,60 @@
 	return icmpv6_error_message(skb, dataoff, ctinfo, hooknum);
 }
 
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+static int icmpv6_tuple_to_nfattr(struct sk_buff *skb,
+				  const struct nf_conntrack_tuple *t)
+{
+	NFA_PUT(skb, CTA_PROTO_ICMPV6_ID, sizeof(u_int16_t),
+		&t->src.u.icmp.id);
+	NFA_PUT(skb, CTA_PROTO_ICMPV6_TYPE, sizeof(u_int8_t),
+		&t->dst.u.icmp.type);
+	NFA_PUT(skb, CTA_PROTO_ICMPV6_CODE, sizeof(u_int8_t),
+		&t->dst.u.icmp.code);
+
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+static const size_t cta_min_proto[CTA_PROTO_MAX] = {
+	[CTA_PROTO_ICMPV6_TYPE-1] = sizeof(u_int8_t),
+	[CTA_PROTO_ICMPV6_CODE-1] = sizeof(u_int8_t),
+	[CTA_PROTO_ICMPV6_ID-1]   = sizeof(u_int16_t)
+};
+
+static int icmpv6_nfattr_to_tuple(struct nfattr *tb[],
+				struct nf_conntrack_tuple *tuple)
+{
+	if (!tb[CTA_PROTO_ICMPV6_TYPE-1]
+	    || !tb[CTA_PROTO_ICMPV6_CODE-1]
+	    || !tb[CTA_PROTO_ICMPV6_ID-1])
+		return -EINVAL;
+
+	if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
+		return -EINVAL;
+
+	tuple->dst.u.icmp.type =
+			*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_TYPE-1]);
+	tuple->dst.u.icmp.code =
+			*(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]);
+	tuple->src.u.icmp.id =
+			*(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]);
+
+	if (tuple->dst.u.icmp.type < 128
+	    || tuple->dst.u.icmp.type - 128 >= sizeof(invmap)
+	    || !invmap[tuple->dst.u.icmp.type - 128])
+		return -EINVAL;
+
+	return 0;
+}
+#endif
+
 struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
 {
 	.l3proto		= PF_INET6,
@@ -267,6 +321,11 @@
 	.packet			= icmpv6_packet,
 	.new			= icmpv6_new,
 	.error			= icmpv6_error,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.tuple_to_nfattr	= icmpv6_tuple_to_nfattr,
+	.nfattr_to_tuple	= icmpv6_nfattr_to_tuple,
+#endif
 };
 
 EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index c2c52af..f3e5ffb 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -98,7 +98,7 @@
 #define FRAG6Q_HASHSZ	64
 
 static struct nf_ct_frag6_queue *nf_ct_frag6_hash[FRAG6Q_HASHSZ];
-static rwlock_t nf_ct_frag6_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(nf_ct_frag6_lock);
 static u32 nf_ct_frag6_hash_rnd;
 static LIST_HEAD(nf_ct_frag6_lru_list);
 int nf_ct_frag6_nqueues = 0;
@@ -371,7 +371,7 @@
 	init_timer(&fq->timer);
 	fq->timer.function = nf_ct_frag6_expire;
 	fq->timer.data = (long) fq;
-	fq->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&fq->lock);
 	atomic_set(&fq->refcnt, 1);
 
 	return nf_ct_frag6_intern(hash, fq);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index a66900c..66f1d12 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -32,6 +32,7 @@
 #include <linux/icmpv6.h>
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv6.h>
+#include <linux/skbuff.h>
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 #include <asm/bug.h>
@@ -433,25 +434,14 @@
 	return err;
 
 csum_copy_err:
-	/* Clear queue. */
-	if (flags&MSG_PEEK) {
-		int clear = 0;
-		spin_lock_bh(&sk->sk_receive_queue.lock);
-		if (skb == skb_peek(&sk->sk_receive_queue)) {
-			__skb_unlink(skb, &sk->sk_receive_queue);
-			clear = 1;
-		}
-		spin_unlock_bh(&sk->sk_receive_queue.lock);
-		if (clear)
-			kfree_skb(skb);
-	}
+	skb_kill_datagram(sk, skb, flags);
 
 	/* Error for blocking case is chosen to masquerade
 	   as some normal condition.
 	 */
 	err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
 	/* FIXME: increment a raw6 drops counter here */
-	goto out_free;
+	goto out;
 }
 
 static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 5d316cb..15e1456 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -581,7 +581,6 @@
  *	the last and the first frames arrived and all the bits are here.
  */
 static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
-			  unsigned int *nhoffp,
 			  struct net_device *dev)
 {
 	struct sk_buff *fp, *head = fq->fragments;
@@ -654,6 +653,7 @@
 	head->dev = dev;
 	skb_set_timestamp(head, &fq->stamp);
 	head->nh.ipv6h->payload_len = htons(payload_len);
+	IP6CB(head)->nhoff = nhoff;
 
 	*skb_in = head;
 
@@ -663,7 +663,6 @@
 
 	IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS);
 	fq->fragments = NULL;
-	*nhoffp = nhoff;
 	return 1;
 
 out_oversize:
@@ -678,7 +677,7 @@
 	return -1;
 }
 
-static int ipv6_frag_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
+static int ipv6_frag_rcv(struct sk_buff **skbp)
 {
 	struct sk_buff *skb = *skbp; 
 	struct net_device *dev = skb->dev;
@@ -710,7 +709,7 @@
 		skb->h.raw += sizeof(struct frag_hdr);
 		IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS);
 
-		*nhoffp = (u8*)fhdr - skb->nh.raw;
+		IP6CB(skb)->nhoff = (u8*)fhdr - skb->nh.raw;
 		return 1;
 	}
 
@@ -722,11 +721,11 @@
 
 		spin_lock(&fq->lock);
 
-		ip6_frag_queue(fq, skb, fhdr, *nhoffp);
+		ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
 
 		if (fq->last_in == (FIRST_IN|LAST_IN) &&
 		    fq->meat == fq->len)
-			ret = ip6_frag_reasm(fq, skbp, nhoffp, dev);
+			ret = ip6_frag_reasm(fq, skbp, dev);
 
 		spin_unlock(&fq->lock);
 		fq_put(fq, NULL);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a7a537b..66140f1 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -413,11 +413,14 @@
 	rt = ip6_rt_copy(ort);
 
 	if (rt) {
-		ipv6_addr_copy(&rt->rt6i_dst.addr, daddr);
-
-		if (!(rt->rt6i_flags&RTF_GATEWAY))
+		if (!(rt->rt6i_flags&RTF_GATEWAY)) {
+			if (rt->rt6i_dst.plen != 128 &&
+			    ipv6_addr_equal(&rt->rt6i_dst.addr, daddr))
+				rt->rt6i_flags |= RTF_ANYCAST;
 			ipv6_addr_copy(&rt->rt6i_gateway, daddr);
+		}
 
+		ipv6_addr_copy(&rt->rt6i_dst.addr, daddr);
 		rt->rt6i_dst.plen = 128;
 		rt->rt6i_flags |= RTF_CACHE;
 		rt->u.dst.flags |= DST_HOST;
@@ -829,7 +832,7 @@
 	}
 
 	rt->u.dst.obsolete = -1;
-	rt->rt6i_expires = clock_t_to_jiffies(rtmsg->rtmsg_info);
+	rt->rt6i_expires = jiffies + clock_t_to_jiffies(rtmsg->rtmsg_info);
 	if (nlh && (r = NLMSG_DATA(nlh))) {
 		rt->rt6i_protocol = r->rtm_protocol;
 	} else {
@@ -1413,7 +1416,9 @@
 	rt->u.dst.obsolete = -1;
 
 	rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
-	if (!anycast)
+	if (anycast)
+		rt->rt6i_flags |= RTF_ANYCAST;
+	else
 		rt->rt6i_flags |= RTF_LOCAL;
 	rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway);
 	if (rt->rt6i_nexthop == NULL) {
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index c3123c9..02872ae 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -33,6 +33,7 @@
 #include <asm/uaccess.h>
 #include <linux/init.h>
 #include <linux/netfilter_ipv4.h>
+#include <linux/if_ether.h>
 
 #include <net/sock.h>
 #include <net/snmp.h>
@@ -380,6 +381,7 @@
 		skb->mac.raw = skb->nh.raw;
 		skb->nh.raw = skb->data;
 		memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
+		IPCB(skb)->flags = 0;
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
 		tunnel->stat.rx_packets++;
@@ -551,6 +553,7 @@
 	skb->h.raw = skb->nh.raw;
 	skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+	IPCB(skb)->flags = 0;
 	dst_release(skb->dst);
 	skb->dst = &rt->u.dst;
 
@@ -720,7 +723,7 @@
 
 	dev->type		= ARPHRD_SIT;
 	dev->hard_header_len 	= LL_MAX_HEADER + sizeof(struct iphdr);
-	dev->mtu		= 1500 - sizeof(struct iphdr);
+	dev->mtu		= ETH_DATA_LEN - sizeof(struct iphdr);
 	dev->flags		= IFF_NOARP;
 	dev->iflink		= 0;
 	dev->addr_len		= 4;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 62c0e5b..a25f4e8 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -48,6 +48,7 @@
 #include <net/tcp.h>
 #include <net/ndisc.h>
 #include <net/inet6_hashtables.h>
+#include <net/inet6_connection_sock.h>
 #include <net/ipv6.h>
 #include <net/transp_v6.h>
 #include <net/addrconf.h>
@@ -59,6 +60,7 @@
 #include <net/addrconf.h>
 #include <net/snmp.h>
 #include <net/dsfield.h>
+#include <net/timewait_sock.h>
 
 #include <asm/uaccess.h>
 
@@ -67,224 +69,33 @@
 
 static void	tcp_v6_send_reset(struct sk_buff *skb);
 static void	tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
-static void	tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, 
+static void	tcp_v6_send_check(struct sock *sk, int len, 
 				  struct sk_buff *skb);
 
 static int	tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
-static int	tcp_v6_xmit(struct sk_buff *skb, int ipfragok);
 
-static struct tcp_func ipv6_mapped;
-static struct tcp_func ipv6_specific;
+static struct inet_connection_sock_af_ops ipv6_mapped;
+static struct inet_connection_sock_af_ops ipv6_specific;
 
-static inline int tcp_v6_bind_conflict(const struct sock *sk,
-				       const struct inet_bind_bucket *tb)
-{
-	const struct sock *sk2;
-	const struct hlist_node *node;
-
-	/* We must walk the whole port owner list in this case. -DaveM */
-	sk_for_each_bound(sk2, node, &tb->owners) {
-		if (sk != sk2 &&
-		    (!sk->sk_bound_dev_if ||
-		     !sk2->sk_bound_dev_if ||
-		     sk->sk_bound_dev_if == sk2->sk_bound_dev_if) &&
-		    (!sk->sk_reuse || !sk2->sk_reuse ||
-		     sk2->sk_state == TCP_LISTEN) &&
-		     ipv6_rcv_saddr_equal(sk, sk2))
-			break;
-	}
-
-	return node != NULL;
-}
-
-/* Grrr, addr_type already calculated by caller, but I don't want
- * to add some silly "cookie" argument to this method just for that.
- * But it doesn't matter, the recalculation is in the rarest path
- * this function ever takes.
- */
 static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
 {
-	struct inet_bind_hashbucket *head;
-	struct inet_bind_bucket *tb;
-	struct hlist_node *node;
-	int ret;
-
-	local_bh_disable();
-	if (snum == 0) {
-		int low = sysctl_local_port_range[0];
-		int high = sysctl_local_port_range[1];
-		int remaining = (high - low) + 1;
-		int rover = net_random() % (high - low) + low;
-
-		do {
-			head = &tcp_hashinfo.bhash[inet_bhashfn(rover, tcp_hashinfo.bhash_size)];
-			spin_lock(&head->lock);
-			inet_bind_bucket_for_each(tb, node, &head->chain)
-				if (tb->port == rover)
-					goto next;
-			break;
-		next:
-			spin_unlock(&head->lock);
-			if (++rover > high)
-				rover = low;
-		} while (--remaining > 0);
-
-		/* Exhausted local port range during search?  It is not
-		 * possible for us to be holding one of the bind hash
-		 * locks if this test triggers, because if 'remaining'
-		 * drops to zero, we broke out of the do/while loop at
-		 * the top level, not from the 'break;' statement.
-		 */
-		ret = 1;
-		if (unlikely(remaining <= 0))
-			goto fail;
-
-		/* OK, here is the one we will use. */
-		snum = rover;
-	} else {
-		head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
-		spin_lock(&head->lock);
-		inet_bind_bucket_for_each(tb, node, &head->chain)
-			if (tb->port == snum)
-				goto tb_found;
-	}
-	tb = NULL;
-	goto tb_not_found;
-tb_found:
-	if (tb && !hlist_empty(&tb->owners)) {
-		if (tb->fastreuse > 0 && sk->sk_reuse &&
-		    sk->sk_state != TCP_LISTEN) {
-			goto success;
-		} else {
-			ret = 1;
-			if (tcp_v6_bind_conflict(sk, tb))
-				goto fail_unlock;
-		}
-	}
-tb_not_found:
-	ret = 1;
-	if (tb == NULL) {
-	       	tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, snum);
-		if (tb == NULL)
-			goto fail_unlock;
-	}
-	if (hlist_empty(&tb->owners)) {
-		if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
-			tb->fastreuse = 1;
-		else
-			tb->fastreuse = 0;
-	} else if (tb->fastreuse &&
-		   (!sk->sk_reuse || sk->sk_state == TCP_LISTEN))
-		tb->fastreuse = 0;
-
-success:
-	if (!inet_csk(sk)->icsk_bind_hash)
-		inet_bind_hash(sk, tb, snum);
-	BUG_TRAP(inet_csk(sk)->icsk_bind_hash == tb);
-	ret = 0;
-
-fail_unlock:
-	spin_unlock(&head->lock);
-fail:
-	local_bh_enable();
-	return ret;
+	return inet_csk_get_port(&tcp_hashinfo, sk, snum,
+				 inet6_csk_bind_conflict);
 }
 
-static __inline__ void __tcp_v6_hash(struct sock *sk)
-{
-	struct hlist_head *list;
-	rwlock_t *lock;
-
-	BUG_TRAP(sk_unhashed(sk));
-
-	if (sk->sk_state == TCP_LISTEN) {
-		list = &tcp_hashinfo.listening_hash[inet_sk_listen_hashfn(sk)];
-		lock = &tcp_hashinfo.lhash_lock;
-		inet_listen_wlock(&tcp_hashinfo);
-	} else {
-		unsigned int hash;
-		sk->sk_hash = hash = inet6_sk_ehashfn(sk);
-		hash &= (tcp_hashinfo.ehash_size - 1);
-		list = &tcp_hashinfo.ehash[hash].chain;
-		lock = &tcp_hashinfo.ehash[hash].lock;
-		write_lock(lock);
-	}
-
-	__sk_add_node(sk, list);
-	sock_prot_inc_use(sk->sk_prot);
-	write_unlock(lock);
-}
-
-
 static void tcp_v6_hash(struct sock *sk)
 {
 	if (sk->sk_state != TCP_CLOSE) {
-		struct tcp_sock *tp = tcp_sk(sk);
-
-		if (tp->af_specific == &ipv6_mapped) {
+		if (inet_csk(sk)->icsk_af_ops == &ipv6_mapped) {
 			tcp_prot.hash(sk);
 			return;
 		}
 		local_bh_disable();
-		__tcp_v6_hash(sk);
+		__inet6_hash(&tcp_hashinfo, sk);
 		local_bh_enable();
 	}
 }
 
-/*
- * Open request hash tables.
- */
-
-static u32 tcp_v6_synq_hash(const struct in6_addr *raddr, const u16 rport, const u32 rnd)
-{
-	u32 a, b, c;
-
-	a = raddr->s6_addr32[0];
-	b = raddr->s6_addr32[1];
-	c = raddr->s6_addr32[2];
-
-	a += JHASH_GOLDEN_RATIO;
-	b += JHASH_GOLDEN_RATIO;
-	c += rnd;
-	__jhash_mix(a, b, c);
-
-	a += raddr->s6_addr32[3];
-	b += (u32) rport;
-	__jhash_mix(a, b, c);
-
-	return c & (TCP_SYNQ_HSIZE - 1);
-}
-
-static struct request_sock *tcp_v6_search_req(const struct sock *sk,
-					      struct request_sock ***prevp,
-					      __u16 rport,
-					      struct in6_addr *raddr,
-					      struct in6_addr *laddr,
-					      int iif)
-{
-	const struct inet_connection_sock *icsk = inet_csk(sk);
-	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
-	struct request_sock *req, **prev;  
-
-	for (prev = &lopt->syn_table[tcp_v6_synq_hash(raddr, rport, lopt->hash_rnd)];
-	     (req = *prev) != NULL;
-	     prev = &req->dl_next) {
-		const struct tcp6_request_sock *treq = tcp6_rsk(req);
-
-		if (inet_rsk(req)->rmt_port == rport &&
-		    req->rsk_ops->family == AF_INET6 &&
-		    ipv6_addr_equal(&treq->rmt_addr, raddr) &&
-		    ipv6_addr_equal(&treq->loc_addr, laddr) &&
-		    (!treq->iif || treq->iif == iif)) {
-			BUG_TRAP(req->sk == NULL);
-			*prevp = prev;
-			return req;
-		}
-	}
-
-	return NULL;
-}
-
 static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len,
 				   struct in6_addr *saddr, 
 				   struct in6_addr *daddr, 
@@ -308,195 +119,12 @@
 	}
 }
 
-static int __tcp_v6_check_established(struct sock *sk, const __u16 lport,
-				      struct inet_timewait_sock **twp)
-{
-	struct inet_sock *inet = inet_sk(sk);
-	const struct ipv6_pinfo *np = inet6_sk(sk);
-	const struct in6_addr *daddr = &np->rcv_saddr;
-	const struct in6_addr *saddr = &np->daddr;
-	const int dif = sk->sk_bound_dev_if;
-	const u32 ports = INET_COMBINED_PORTS(inet->dport, lport);
-	unsigned int hash = inet6_ehashfn(daddr, inet->num, saddr, inet->dport);
-	struct inet_ehash_bucket *head = inet_ehash_bucket(&tcp_hashinfo, hash);
-	struct sock *sk2;
-	const struct hlist_node *node;
-	struct inet_timewait_sock *tw;
-
-	prefetch(head->chain.first);
-	write_lock(&head->lock);
-
-	/* Check TIME-WAIT sockets first. */
-	sk_for_each(sk2, node, &(head + tcp_hashinfo.ehash_size)->chain) {
-		const struct tcp6_timewait_sock *tcp6tw = tcp6_twsk(sk2);
-
-		tw = inet_twsk(sk2);
-
-		if(*((__u32 *)&(tw->tw_dport))	== ports	&&
-		   sk2->sk_family		== PF_INET6	&&
-		   ipv6_addr_equal(&tcp6tw->tw_v6_daddr, saddr)	&&
-		   ipv6_addr_equal(&tcp6tw->tw_v6_rcv_saddr, daddr)	&&
-		   sk2->sk_bound_dev_if == sk->sk_bound_dev_if) {
-			const struct tcp_timewait_sock *tcptw = tcp_twsk(sk2);
-			struct tcp_sock *tp = tcp_sk(sk);
-
-			if (tcptw->tw_ts_recent_stamp &&
-			    (!twp ||
-			     (sysctl_tcp_tw_reuse &&
-			      xtime.tv_sec - tcptw->tw_ts_recent_stamp > 1))) {
-				/* See comment in tcp_ipv4.c */
-				tp->write_seq = tcptw->tw_snd_nxt + 65535 + 2;
-				if (!tp->write_seq)
-					tp->write_seq = 1;
-				tp->rx_opt.ts_recent	   = tcptw->tw_ts_recent;
-				tp->rx_opt.ts_recent_stamp = tcptw->tw_ts_recent_stamp;
-				sock_hold(sk2);
-				goto unique;
-			} else
-				goto not_unique;
-		}
-	}
-	tw = NULL;
-
-	/* And established part... */
-	sk_for_each(sk2, node, &head->chain) {
-		if (INET6_MATCH(sk2, hash, saddr, daddr, ports, dif))
-			goto not_unique;
-	}
-
-unique:
-	BUG_TRAP(sk_unhashed(sk));
-	__sk_add_node(sk, &head->chain);
-	sk->sk_hash = hash;
-	sock_prot_inc_use(sk->sk_prot);
-	write_unlock(&head->lock);
-
-	if (twp) {
-		*twp = tw;
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-	} else if (tw) {
-		/* Silly. Should hash-dance instead... */
-		inet_twsk_deschedule(tw, &tcp_death_row);
-		NET_INC_STATS_BH(LINUX_MIB_TIMEWAITRECYCLED);
-
-		inet_twsk_put(tw);
-	}
-	return 0;
-
-not_unique:
-	write_unlock(&head->lock);
-	return -EADDRNOTAVAIL;
-}
-
-static inline u32 tcpv6_port_offset(const struct sock *sk)
-{
-	const struct inet_sock *inet = inet_sk(sk);
-	const struct ipv6_pinfo *np = inet6_sk(sk);
-
-	return secure_tcpv6_port_ephemeral(np->rcv_saddr.s6_addr32,
-					   np->daddr.s6_addr32,
-					   inet->dport);
-}
-
-static int tcp_v6_hash_connect(struct sock *sk)
-{
-	unsigned short snum = inet_sk(sk)->num;
- 	struct inet_bind_hashbucket *head;
- 	struct inet_bind_bucket *tb;
-	int ret;
-
- 	if (!snum) {
- 		int low = sysctl_local_port_range[0];
- 		int high = sysctl_local_port_range[1];
-		int range = high - low;
- 		int i;
-		int port;
-		static u32 hint;
-		u32 offset = hint + tcpv6_port_offset(sk);
-		struct hlist_node *node;
- 		struct inet_timewait_sock *tw = NULL;
-
- 		local_bh_disable();
-		for (i = 1; i <= range; i++) {
-			port = low + (i + offset) % range;
- 			head = &tcp_hashinfo.bhash[inet_bhashfn(port, tcp_hashinfo.bhash_size)];
- 			spin_lock(&head->lock);
-
- 			/* Does not bother with rcv_saddr checks,
- 			 * because the established check is already
- 			 * unique enough.
- 			 */
-			inet_bind_bucket_for_each(tb, node, &head->chain) {
- 				if (tb->port == port) {
- 					BUG_TRAP(!hlist_empty(&tb->owners));
- 					if (tb->fastreuse >= 0)
- 						goto next_port;
- 					if (!__tcp_v6_check_established(sk,
-									port,
-									&tw))
- 						goto ok;
- 					goto next_port;
- 				}
- 			}
-
- 			tb = inet_bind_bucket_create(tcp_hashinfo.bind_bucket_cachep, head, port);
- 			if (!tb) {
- 				spin_unlock(&head->lock);
- 				break;
- 			}
- 			tb->fastreuse = -1;
- 			goto ok;
-
- 		next_port:
- 			spin_unlock(&head->lock);
- 		}
- 		local_bh_enable();
-
- 		return -EADDRNOTAVAIL;
-
-ok:
-		hint += i;
-
- 		/* Head lock still held and bh's disabled */
- 		inet_bind_hash(sk, tb, port);
-		if (sk_unhashed(sk)) {
- 			inet_sk(sk)->sport = htons(port);
- 			__tcp_v6_hash(sk);
- 		}
- 		spin_unlock(&head->lock);
-
- 		if (tw) {
- 			inet_twsk_deschedule(tw, &tcp_death_row);
- 			inet_twsk_put(tw);
- 		}
-
-		ret = 0;
-		goto out;
- 	}
-
- 	head = &tcp_hashinfo.bhash[inet_bhashfn(snum, tcp_hashinfo.bhash_size)];
- 	tb   = inet_csk(sk)->icsk_bind_hash;
-	spin_lock_bh(&head->lock);
-
-	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
-		__tcp_v6_hash(sk);
-		spin_unlock_bh(&head->lock);
-		return 0;
-	} else {
-		spin_unlock(&head->lock);
-		/* No definite answer... Walk to established hash table */
-		ret = __tcp_v6_check_established(sk, snum, NULL);
-out:
-		local_bh_enable();
-		return ret;
-	}
-}
-
 static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 
 			  int addr_len)
 {
 	struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
-	struct inet_sock *inet = inet_sk(sk);
+ 	struct inet_sock *inet = inet_sk(sk);
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct tcp_sock *tp = tcp_sk(sk);
 	struct in6_addr *saddr = NULL, *final_p = NULL, final;
@@ -571,7 +199,7 @@
 	 */
 
 	if (addr_type == IPV6_ADDR_MAPPED) {
-		u32 exthdrlen = tp->ext_header_len;
+		u32 exthdrlen = icsk->icsk_ext_hdr_len;
 		struct sockaddr_in sin;
 
 		SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
@@ -583,14 +211,14 @@
 		sin.sin_port = usin->sin6_port;
 		sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
 
-		tp->af_specific = &ipv6_mapped;
+		icsk->icsk_af_ops = &ipv6_mapped;
 		sk->sk_backlog_rcv = tcp_v4_do_rcv;
 
 		err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
 
 		if (err) {
-			tp->ext_header_len = exthdrlen;
-			tp->af_specific = &ipv6_specific;
+			icsk->icsk_ext_hdr_len = exthdrlen;
+			icsk->icsk_af_ops = &ipv6_specific;
 			sk->sk_backlog_rcv = tcp_v6_do_rcv;
 			goto failure;
 		} else {
@@ -643,16 +271,17 @@
 	sk->sk_route_caps = dst->dev->features &
 		~(NETIF_F_IP_CSUM | NETIF_F_TSO);
 
-	tp->ext_header_len = 0;
+	icsk->icsk_ext_hdr_len = 0;
 	if (np->opt)
-		tp->ext_header_len = np->opt->opt_flen + np->opt->opt_nflen;
+		icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
+					  np->opt->opt_nflen);
 
 	tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
 
 	inet->dport = usin->sin6_port;
 
 	tcp_set_state(sk, TCP_SYN_SENT);
-	err = tcp_v6_hash_connect(sk);
+	err = inet6_hash_connect(&tcp_death_row, sk);
 	if (err)
 		goto late_failure;
 
@@ -758,7 +387,7 @@
 		} else
 			dst_hold(dst);
 
-		if (tp->pmtu_cookie > dst_mtu(dst)) {
+		if (inet_csk(sk)->icsk_pmtu_cookie > dst_mtu(dst)) {
 			tcp_sync_mss(sk, dst_mtu(dst));
 			tcp_simple_retransmit(sk);
 		} /* else let the usual retransmit timer handle it */
@@ -775,8 +404,8 @@
 		if (sock_owned_by_user(sk))
 			goto out;
 
-		req = tcp_v6_search_req(sk, &prev, th->dest, &hdr->daddr,
-					&hdr->saddr, inet6_iif(skb));
+		req = inet6_csk_search_req(sk, &prev, th->dest, &hdr->daddr,
+					   &hdr->saddr, inet6_iif(skb));
 		if (!req)
 			goto out;
 
@@ -822,7 +451,7 @@
 static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
 			      struct dst_entry *dst)
 {
-	struct tcp6_request_sock *treq = tcp6_rsk(req);
+	struct inet6_request_sock *treq = inet6_rsk(req);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sk_buff * skb;
 	struct ipv6_txoptions *opt = NULL;
@@ -888,8 +517,8 @@
 
 static void tcp_v6_reqsk_destructor(struct request_sock *req)
 {
-	if (tcp6_rsk(req)->pktopts)
-		kfree_skb(tcp6_rsk(req)->pktopts);
+	if (inet6_rsk(req)->pktopts)
+		kfree_skb(inet6_rsk(req)->pktopts);
 }
 
 static struct request_sock_ops tcp6_request_sock_ops = {
@@ -901,26 +530,15 @@
 	.send_reset	=	tcp_v6_send_reset
 };
 
-static int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
+static struct timewait_sock_ops tcp6_timewait_sock_ops = {
+	.twsk_obj_size	= sizeof(struct tcp6_timewait_sock),
+	.twsk_unique	= tcp_twsk_unique,
+};
+
+static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct inet6_skb_parm *opt = IP6CB(skb);
-
-	if (np->rxopt.all) {
-		if ((opt->hop && (np->rxopt.bits.hopopts || np->rxopt.bits.ohopopts)) ||
-		    ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && np->rxopt.bits.rxflow) ||
-		    (opt->srcrt && (np->rxopt.bits.srcrt || np->rxopt.bits.osrcrt)) ||
-		    ((opt->dst1 || opt->dst0) && (np->rxopt.bits.dstopts || np->rxopt.bits.odstopts)))
-			return 1;
-	}
-	return 0;
-}
-
-
-static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, 
-			      struct sk_buff *skb)
-{
-	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct tcphdr *th = skb->h.th;
 
 	if (skb->ip_summed == CHECKSUM_HW) {
 		th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,  0);
@@ -992,13 +610,12 @@
 	/* sk = NULL, but it is safe for now. RST socket required. */
 	if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
 
-		if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
+		if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
+			ip6_xmit(NULL, buff, &fl, NULL, 0);
+			TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
+			TCP_INC_STATS_BH(TCP_MIB_OUTRSTS);
 			return;
-
-		ip6_xmit(NULL, buff, &fl, NULL, 0);
-		TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
-		TCP_INC_STATS_BH(TCP_MIB_OUTRSTS);
-		return;
+		}
 	}
 
 	kfree_skb(buff);
@@ -1057,11 +674,11 @@
 	fl.fl_ip_sport = t1->source;
 
 	if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) {
-		if ((xfrm_lookup(&buff->dst, &fl, NULL, 0)) < 0)
+		if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
+			ip6_xmit(NULL, buff, &fl, NULL, 0);
+			TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
 			return;
-		ip6_xmit(NULL, buff, &fl, NULL, 0);
-		TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
-		return;
+		}
 	}
 
 	kfree_skb(buff);
@@ -1092,8 +709,9 @@
 	struct sock *nsk;
 
 	/* Find possible connection requests. */
-	req = tcp_v6_search_req(sk, &prev, th->source, &skb->nh.ipv6h->saddr,
-				&skb->nh.ipv6h->daddr, inet6_iif(skb));
+	req = inet6_csk_search_req(sk, &prev, th->source,
+				   &skb->nh.ipv6h->saddr,
+				   &skb->nh.ipv6h->daddr, inet6_iif(skb));
 	if (req)
 		return tcp_check_req(sk, skb, req, prev);
 
@@ -1117,23 +735,12 @@
 	return sk;
 }
 
-static void tcp_v6_synq_add(struct sock *sk, struct request_sock *req)
-{
-	struct inet_connection_sock *icsk = inet_csk(sk);
-	struct listen_sock *lopt = icsk->icsk_accept_queue.listen_opt;
-	const u32 h = tcp_v6_synq_hash(&tcp6_rsk(req)->rmt_addr, inet_rsk(req)->rmt_port, lopt->hash_rnd);
-
-	reqsk_queue_hash_req(&icsk->icsk_accept_queue, h, req, TCP_TIMEOUT_INIT);
-	inet_csk_reqsk_queue_added(sk, TCP_TIMEOUT_INIT);
-}
-
-
 /* FIXME: this is substantially similar to the ipv4 code.
  * Can some kind of merge be done? -- erics
  */
 static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 {
-	struct tcp6_request_sock *treq;
+	struct inet6_request_sock *treq;
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct tcp_options_received tmp_opt;
 	struct tcp_sock *tp = tcp_sk(sk);
@@ -1158,7 +765,7 @@
 	if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
 		goto drop;
 
-	req = reqsk_alloc(&tcp6_request_sock_ops);
+	req = inet6_reqsk_alloc(&tcp6_request_sock_ops);
 	if (req == NULL)
 		goto drop;
 
@@ -1171,7 +778,7 @@
 	tmp_opt.tstamp_ok = tmp_opt.saw_tstamp;
 	tcp_openreq_init(req, &tmp_opt, skb);
 
-	treq = tcp6_rsk(req);
+	treq = inet6_rsk(req);
 	ipv6_addr_copy(&treq->rmt_addr, &skb->nh.ipv6h->saddr);
 	ipv6_addr_copy(&treq->loc_addr, &skb->nh.ipv6h->daddr);
 	TCP_ECN_create_request(req, skb->h.th);
@@ -1197,8 +804,7 @@
 	if (tcp_v6_send_synack(sk, req, NULL))
 		goto drop;
 
-	tcp_v6_synq_add(sk, req);
-
+	inet6_csk_reqsk_queue_hash_add(sk, req, TCP_TIMEOUT_INIT);
 	return 0;
 
 drop:
@@ -1213,7 +819,7 @@
 					  struct request_sock *req,
 					  struct dst_entry *dst)
 {
-	struct tcp6_request_sock *treq = tcp6_rsk(req);
+	struct inet6_request_sock *treq = inet6_rsk(req);
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct tcp6_sock *newtcp6sk;
 	struct inet_sock *newinet;
@@ -1248,7 +854,7 @@
 
 		ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
 
-		newtp->af_specific = &ipv6_mapped;
+		inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
 		newsk->sk_backlog_rcv = tcp_v4_do_rcv;
 		newnp->pktoptions  = NULL;
 		newnp->opt	   = NULL;
@@ -1262,10 +868,10 @@
 		 */
 
 		/* It is tricky place. Until this moment IPv4 tcp
-		   worked with IPv6 af_tcp.af_specific.
+		   worked with IPv6 icsk.icsk_af_ops.
 		   Sync it now.
 		 */
-		tcp_sync_mss(newsk, newtp->pmtu_cookie);
+		tcp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie);
 
 		return newsk;
 	}
@@ -1372,10 +978,10 @@
 			sock_kfree_s(sk, opt, opt->tot_len);
 	}
 
-	newtp->ext_header_len = 0;
+	inet_csk(newsk)->icsk_ext_hdr_len = 0;
 	if (newnp->opt)
-		newtp->ext_header_len = newnp->opt->opt_nflen +
-					newnp->opt->opt_flen;
+		inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
+						     newnp->opt->opt_flen);
 
 	tcp_sync_mss(newsk, dst_mtu(dst));
 	newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
@@ -1383,7 +989,7 @@
 
 	newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
 
-	__tcp_v6_hash(newsk);
+	__inet6_hash(&tcp_hashinfo, newsk);
 	inet_inherit_port(&tcp_hashinfo, sk, newsk);
 
 	return newsk;
@@ -1547,7 +1153,7 @@
 	return 0;
 }
 
-static int tcp_v6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+static int tcp_v6_rcv(struct sk_buff **pskb)
 {
 	struct sk_buff *skb = *pskb;
 	struct tcphdr *th;	
@@ -1680,139 +1286,16 @@
 	goto discard_it;
 }
 
-static int tcp_v6_rebuild_header(struct sock *sk)
-{
-	int err;
-	struct dst_entry *dst;
-	struct ipv6_pinfo *np = inet6_sk(sk);
-
-	dst = __sk_dst_check(sk, np->dst_cookie);
-
-	if (dst == NULL) {
-		struct inet_sock *inet = inet_sk(sk);
-		struct in6_addr *final_p = NULL, final;
-		struct flowi fl;
-
-		memset(&fl, 0, sizeof(fl));
-		fl.proto = IPPROTO_TCP;
-		ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
-		fl.fl6_flowlabel = np->flow_label;
-		fl.oif = sk->sk_bound_dev_if;
-		fl.fl_ip_dport = inet->dport;
-		fl.fl_ip_sport = inet->sport;
-
-		if (np->opt && np->opt->srcrt) {
-			struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-			ipv6_addr_copy(&final, &fl.fl6_dst);
-			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
-			final_p = &final;
-		}
-
-		err = ip6_dst_lookup(sk, &dst, &fl);
-		if (err) {
-			sk->sk_route_caps = 0;
-			return err;
-		}
-		if (final_p)
-			ipv6_addr_copy(&fl.fl6_dst, final_p);
-
-		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-			sk->sk_err_soft = -err;
-			return err;
-		}
-
-		ip6_dst_store(sk, dst, NULL);
-		sk->sk_route_caps = dst->dev->features &
-			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
-	}
-
-	return 0;
-}
-
-static int tcp_v6_xmit(struct sk_buff *skb, int ipfragok)
-{
-	struct sock *sk = skb->sk;
-	struct inet_sock *inet = inet_sk(sk);
-	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct flowi fl;
-	struct dst_entry *dst;
-	struct in6_addr *final_p = NULL, final;
-
-	memset(&fl, 0, sizeof(fl));
-	fl.proto = IPPROTO_TCP;
-	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-	ipv6_addr_copy(&fl.fl6_src, &np->saddr);
-	fl.fl6_flowlabel = np->flow_label;
-	IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
-	fl.oif = sk->sk_bound_dev_if;
-	fl.fl_ip_sport = inet->sport;
-	fl.fl_ip_dport = inet->dport;
-
-	if (np->opt && np->opt->srcrt) {
-		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-		ipv6_addr_copy(&final, &fl.fl6_dst);
-		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
-		final_p = &final;
-	}
-
-	dst = __sk_dst_check(sk, np->dst_cookie);
-
-	if (dst == NULL) {
-		int err = ip6_dst_lookup(sk, &dst, &fl);
-
-		if (err) {
-			sk->sk_err_soft = -err;
-			return err;
-		}
-
-		if (final_p)
-			ipv6_addr_copy(&fl.fl6_dst, final_p);
-
-		if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) {
-			sk->sk_route_caps = 0;
-			return err;
-		}
-
-		ip6_dst_store(sk, dst, NULL);
-		sk->sk_route_caps = dst->dev->features &
-			~(NETIF_F_IP_CSUM | NETIF_F_TSO);
-	}
-
-	skb->dst = dst_clone(dst);
-
-	/* Restore final destination back after routing done */
-	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
-
-	return ip6_xmit(sk, skb, &fl, np->opt, 0);
-}
-
-static void v6_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
-{
-	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
-
-	sin6->sin6_family = AF_INET6;
-	ipv6_addr_copy(&sin6->sin6_addr, &np->daddr);
-	sin6->sin6_port	= inet_sk(sk)->dport;
-	/* We do not store received flowlabel for TCP */
-	sin6->sin6_flowinfo = 0;
-	sin6->sin6_scope_id = 0;
-	if (sk->sk_bound_dev_if &&
-	    ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)
-		sin6->sin6_scope_id = sk->sk_bound_dev_if;
-}
-
 static int tcp_v6_remember_stamp(struct sock *sk)
 {
 	/* Alas, not yet... */
 	return 0;
 }
 
-static struct tcp_func ipv6_specific = {
-	.queue_xmit	=	tcp_v6_xmit,
+static struct inet_connection_sock_af_ops ipv6_specific = {
+	.queue_xmit	=	inet6_csk_xmit,
 	.send_check	=	tcp_v6_send_check,
-	.rebuild_header	=	tcp_v6_rebuild_header,
+	.rebuild_header	=	inet6_sk_rebuild_header,
 	.conn_request	=	tcp_v6_conn_request,
 	.syn_recv_sock	=	tcp_v6_syn_recv_sock,
 	.remember_stamp	=	tcp_v6_remember_stamp,
@@ -1820,7 +1303,7 @@
 
 	.setsockopt	=	ipv6_setsockopt,
 	.getsockopt	=	ipv6_getsockopt,
-	.addr2sockaddr	=	v6_addr2sockaddr,
+	.addr2sockaddr	=	inet6_csk_addr2sockaddr,
 	.sockaddr_len	=	sizeof(struct sockaddr_in6)
 };
 
@@ -1828,7 +1311,7 @@
  *	TCP over IPv4 via INET6 API
  */
 
-static struct tcp_func ipv6_mapped = {
+static struct inet_connection_sock_af_ops ipv6_mapped = {
 	.queue_xmit	=	ip_queue_xmit,
 	.send_check	=	tcp_v4_send_check,
 	.rebuild_header	=	inet_sk_rebuild_header,
@@ -1839,7 +1322,7 @@
 
 	.setsockopt	=	ipv6_setsockopt,
 	.getsockopt	=	ipv6_getsockopt,
-	.addr2sockaddr	=	v6_addr2sockaddr,
+	.addr2sockaddr	=	inet6_csk_addr2sockaddr,
 	.sockaddr_len	=	sizeof(struct sockaddr_in6)
 };
 
@@ -1878,8 +1361,9 @@
 
 	sk->sk_state = TCP_CLOSE;
 
-	tp->af_specific = &ipv6_specific;
+	icsk->icsk_af_ops = &ipv6_specific;
 	icsk->icsk_ca_ops = &tcp_init_congestion_ops;
+	icsk->icsk_sync_mss = tcp_sync_mss;
 	sk->sk_write_space = sk_stream_write_space;
 	sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
 
@@ -1901,14 +1385,13 @@
 static void get_openreq6(struct seq_file *seq, 
 			 struct sock *sk, struct request_sock *req, int i, int uid)
 {
-	struct in6_addr *dest, *src;
 	int ttd = req->expires - jiffies;
+	struct in6_addr *src = &inet6_rsk(req)->loc_addr;
+	struct in6_addr *dest = &inet6_rsk(req)->rmt_addr;
 
 	if (ttd < 0)
 		ttd = 0;
 
-	src = &tcp6_rsk(req)->loc_addr;
-	dest = &tcp6_rsk(req)->rmt_addr;
 	seq_printf(seq,
 		   "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X "
 		   "%02X %08X:%08X %02X:%08lX %08X %5d %8d %d %d %p\n",
@@ -1989,14 +1472,14 @@
 {
 	struct in6_addr *dest, *src;
 	__u16 destp, srcp;
-	struct tcp6_timewait_sock *tcp6tw = tcp6_twsk((struct sock *)tw);
+	struct inet6_timewait_sock *tw6 = inet6_twsk((struct sock *)tw);
 	int ttd = tw->tw_ttd - jiffies;
 
 	if (ttd < 0)
 		ttd = 0;
 
-	dest = &tcp6tw->tw_v6_daddr;
-	src  = &tcp6tw->tw_v6_rcv_saddr;
+	dest = &tw6->tw_v6_daddr;
+	src  = &tw6->tw_v6_rcv_saddr;
 	destp = ntohs(tw->tw_dport);
 	srcp  = ntohs(tw->tw_sport);
 
@@ -2094,7 +1577,7 @@
 	.sysctl_rmem		= sysctl_tcp_rmem,
 	.max_header		= MAX_TCP_HEADER,
 	.obj_size		= sizeof(struct tcp6_sock),
-	.twsk_obj_size		= sizeof(struct tcp6_timewait_sock),
+	.twsk_prot		= &tcp6_timewait_sock_ops,
 	.rsk_prot		= &tcp6_request_sock_ops,
 };
 
@@ -2111,7 +1594,8 @@
 	.ops		=	&inet6_stream_ops,
 	.capability	=	-1,
 	.no_check	=	0,
-	.flags		=	INET_PROTOSW_PERMANENT,
+	.flags		=	INET_PROTOSW_PERMANENT |
+				INET_PROTOSW_ICSK,
 };
 
 void __init tcpv6_init(void)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 5cc8731..c476488 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -36,6 +36,7 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/init.h>
+#include <linux/skbuff.h>
 #include <asm/uaccess.h>
 
 #include <net/sock.h>
@@ -300,20 +301,7 @@
 	return err;
 
 csum_copy_err:
-	/* Clear queue. */
-	if (flags&MSG_PEEK) {
-		int clear = 0;
-		spin_lock_bh(&sk->sk_receive_queue.lock);
-		if (skb == skb_peek(&sk->sk_receive_queue)) {
-			__skb_unlink(skb, &sk->sk_receive_queue);
-			clear = 1;
-		}
-		spin_unlock_bh(&sk->sk_receive_queue.lock);
-		if (clear)
-			kfree_skb(skb);
-	}
-
-	skb_free_datagram(sk, skb);
+	skb_kill_datagram(sk, skb, flags);
 
 	if (flags & MSG_DONTWAIT) {
 		UDP6_INC_STATS_USER(UDP_MIB_INERRORS);
@@ -447,7 +435,7 @@
 	read_unlock(&udp_hash_lock);
 }
 
-static int udpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+static int udpv6_rcv(struct sk_buff **pskb)
 {
 	struct sk_buff *skb = *pskb;
 	struct sock *sk;
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index 28c29d7..1ca2da6 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -11,6 +11,8 @@
 
 #include <linux/module.h>
 #include <linux/string.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv6.h>
 #include <net/dsfield.h>
 #include <net/inet_ecn.h>
 #include <net/ip.h>
@@ -26,7 +28,7 @@
 		IP6_ECN_set_ce(inner_iph);
 }
 
-int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi)
+int xfrm6_rcv_spi(struct sk_buff **pskb, u32 spi)
 {
 	struct sk_buff *skb = *pskb;
 	int err;
@@ -38,7 +40,7 @@
 	int nexthdr;
 	unsigned int nhoff;
 
-	nhoff = *nhoffp;
+	nhoff = IP6CB(skb)->nhoff;
 	nexthdr = skb->nh.raw[nhoff];
 
 	seq = 0;
@@ -121,6 +123,8 @@
 	skb->sp->len += xfrm_nr;
 	skb->ip_summed = CHECKSUM_NONE;
 
+	nf_reset(skb);
+
 	if (decaps) {
 		if (!(skb->dev->flags&IFF_LOOPBACK)) {
 			dst_release(skb->dst);
@@ -129,7 +133,16 @@
 		netif_rx(skb);
 		return -1;
 	} else {
+#ifdef CONFIG_NETFILTER
+		skb->nh.ipv6h->payload_len = htons(skb->len);
+		__skb_push(skb, skb->data - skb->nh.raw);
+
+		NF_HOOK(PF_INET6, NF_IP6_PRE_ROUTING, skb, skb->dev, NULL,
+		        ip6_rcv_finish);
+		return -1;
+#else
 		return 1;
+#endif
 	}
 
 drop_unlock:
@@ -144,7 +157,7 @@
 
 EXPORT_SYMBOL(xfrm6_rcv_spi);
 
-int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+int xfrm6_rcv(struct sk_buff **pskb)
 {
-	return xfrm6_rcv_spi(pskb, nhoffp, 0);
+	return xfrm6_rcv_spi(pskb, 0);
 }
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 6b98677..8024217 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -9,9 +9,11 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/compiler.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/icmpv6.h>
+#include <linux/netfilter_ipv6.h>
 #include <net/dsfield.h>
 #include <net/inet_ecn.h>
 #include <net/ipv6.h>
@@ -92,7 +94,7 @@
 	return ret;
 }
 
-int xfrm6_output(struct sk_buff *skb)
+static int xfrm6_output_one(struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb->dst;
 	struct xfrm_state *x = dst->xfrm;
@@ -110,29 +112,35 @@
 			goto error_nolock;
 	}
 
-	spin_lock_bh(&x->lock);
-	err = xfrm_state_check(x, skb);
-	if (err)
-		goto error;
+	do {
+		spin_lock_bh(&x->lock);
+		err = xfrm_state_check(x, skb);
+		if (err)
+			goto error;
 
-	xfrm6_encap(skb);
+		xfrm6_encap(skb);
 
-	err = x->type->output(x, skb);
-	if (err)
-		goto error;
+		err = x->type->output(x, skb);
+		if (err)
+			goto error;
 
-	x->curlft.bytes += skb->len;
-	x->curlft.packets++;
+		x->curlft.bytes += skb->len;
+		x->curlft.packets++;
 
-	spin_unlock_bh(&x->lock);
+		spin_unlock_bh(&x->lock);
 
-	skb->nh.raw = skb->data;
-	
-	if (!(skb->dst = dst_pop(dst))) {
-		err = -EHOSTUNREACH;
-		goto error_nolock;
-	}
-	err = NET_XMIT_BYPASS;
+		skb->nh.raw = skb->data;
+		
+		if (!(skb->dst = dst_pop(dst))) {
+			err = -EHOSTUNREACH;
+			goto error_nolock;
+		}
+		dst = skb->dst;
+		x = dst->xfrm;
+	} while (x && !x->props.mode);
+
+	IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
+	err = 0;
 
 out_exit:
 	return err;
@@ -142,3 +150,33 @@
 	kfree_skb(skb);
 	goto out_exit;
 }
+
+static int xfrm6_output_finish(struct sk_buff *skb)
+{
+	int err;
+
+	while (likely((err = xfrm6_output_one(skb)) == 0)) {
+		nf_reset(skb);
+	
+		err = nf_hook(PF_INET6, NF_IP6_LOCAL_OUT, &skb, NULL,
+			      skb->dst->dev, dst_output);
+		if (unlikely(err != 1))
+			break;
+
+		if (!skb->dst->xfrm)
+			return dst_output(skb);
+
+		err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, &skb, NULL,
+			      skb->dst->dev, xfrm6_output_finish);
+		if (unlikely(err != 1))
+			break;
+	}
+
+	return err;
+}
+
+int xfrm6_output(struct sk_buff *skb)
+{
+	return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb->dst->dev,
+		       xfrm6_output_finish);
+}
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index cf1d91e..69bd957 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -214,6 +214,7 @@
 		case IPPROTO_UDP:
 		case IPPROTO_TCP:
 		case IPPROTO_SCTP:
+		case IPPROTO_DCCP:
 			if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) {
 				u16 *ports = (u16 *)exthdr;
 
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index fbef782..da09ff2 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -397,7 +397,7 @@
 
 EXPORT_SYMBOL(xfrm6_tunnel_deregister);
 
-static int xfrm6_tunnel_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+static int xfrm6_tunnel_rcv(struct sk_buff **pskb)
 {
 	struct sk_buff *skb = *pskb;
 	struct xfrm6_tunnel *handler = xfrm6_tunnel_handler;
@@ -405,11 +405,11 @@
 	u32 spi;
 
 	/* device-like_ip6ip6_handler() */
-	if (handler && handler->handler(pskb, nhoffp) == 0)
+	if (handler && handler->handler(pskb) == 0)
 		return 0;
 
 	spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr);
-	return xfrm6_rcv_spi(pskb, nhoffp, spi);
+	return xfrm6_rcv_spi(pskb, spi);
 }
 
 static void xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 34b3bb8..0dc519b 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -75,7 +75,7 @@
 static struct datalink_proto *p8023_datalink;
 static struct datalink_proto *pSNAP_datalink;
 
-static struct proto_ops ipx_dgram_ops;
+static const struct proto_ops ipx_dgram_ops;
 
 LIST_HEAD(ipx_interfaces);
 DEFINE_SPINLOCK(ipx_interfaces_lock);
@@ -1884,7 +1884,7 @@
 		rc = -EINVAL;
 		break;
 	default:
-		rc = dev_ioctl(cmd, argp);
+		rc = -ENOIOCTLCMD;
 		break;
 	}
 
@@ -1901,7 +1901,7 @@
 	.owner		= THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
 	.family		= PF_IPX,
 	.owner		= THIS_MODULE,
 	.release	= ipx_release,
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 6f92f9c..fbfa967 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -62,12 +62,12 @@
 
 static int irda_create(struct socket *sock, int protocol);
 
-static struct proto_ops irda_stream_ops;
-static struct proto_ops irda_seqpacket_ops;
-static struct proto_ops irda_dgram_ops;
+static const struct proto_ops irda_stream_ops;
+static const struct proto_ops irda_seqpacket_ops;
+static const struct proto_ops irda_dgram_ops;
 
 #ifdef CONFIG_IRDA_ULTRA
-static struct proto_ops irda_ultra_ops;
+static const struct proto_ops irda_ultra_ops;
 #define ULTRA_MAX_DATA 382
 #endif /* CONFIG_IRDA_ULTRA */
 
@@ -1438,8 +1438,9 @@
 			/*
 			 *	POSIX 1003.1g mandates this order.
 			 */
-			if (sk->sk_err)
-				ret = sock_error(sk);
+			ret = sock_error(sk);
+			if (ret)
+				break;
 			else if (sk->sk_shutdown & RCV_SHUTDOWN)
 				;
 			else if (noblock)
@@ -1821,7 +1822,7 @@
 		return -EINVAL;
 	default:
 		IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __FUNCTION__);
-		return dev_ioctl(cmd, (void __user *) arg);
+		return -ENOIOCTLCMD;
 	}
 
 	/*NOTREACHED*/
@@ -2463,7 +2464,7 @@
 	.owner	= THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
 	.family =	PF_IRDA,
 	.owner =	THIS_MODULE,
 	.release =	irda_release,
@@ -2484,7 +2485,7 @@
 	.sendpage =	sock_no_sendpage,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
 	.family =	PF_IRDA,
 	.owner =	THIS_MODULE,
 	.release =	irda_release,
@@ -2505,7 +2506,7 @@
 	.sendpage =	sock_no_sendpage,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
 	.family =	PF_IRDA,
 	.owner =	THIS_MODULE,
 	.release =	irda_release,
@@ -2527,7 +2528,7 @@
 };
 
 #ifdef CONFIG_IRDA_ULTRA
-static struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
 	.family =	PF_IRDA,
 	.owner =	THIS_MODULE,
 	.release =	irda_release,
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index b8bb78a..254f907 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -364,7 +364,7 @@
 /*
  * Function iriap_getvaluebyclass (addr, name, attr)
  *
- *    Retreive all values from attribute in all objects with given class
+ *    Retrieve all values from attribute in all objects with given class
  *    name
  */
 int iriap_getvaluebyclass_request(struct iriap_cb *self,
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 3903168..52efd04 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -113,7 +113,7 @@
 }
 
 
-static struct proto_ops pfkey_ops;
+static const struct proto_ops pfkey_ops;
 
 static void pfkey_insert(struct sock *sk)
 {
@@ -336,6 +336,7 @@
 	[SADB_X_EXT_NAT_T_SPORT]	= (u8) sizeof(struct sadb_x_nat_t_port),
 	[SADB_X_EXT_NAT_T_DPORT]	= (u8) sizeof(struct sadb_x_nat_t_port),
 	[SADB_X_EXT_NAT_T_OA]		= (u8) sizeof(struct sadb_address),
+	[SADB_X_EXT_SEC_CTX]		= (u8) sizeof(struct sadb_x_sec_ctx),
 };
 
 /* Verify sadb_address_{len,prefixlen} against sa_family.  */
@@ -383,6 +384,55 @@
 	return 0;
 }
 
+static inline int pfkey_sec_ctx_len(struct sadb_x_sec_ctx *sec_ctx)
+{
+	int len = 0;
+
+	len += sizeof(struct sadb_x_sec_ctx);
+	len += sec_ctx->sadb_x_ctx_len;
+	len += sizeof(uint64_t) - 1;
+	len /= sizeof(uint64_t);
+
+	return len;
+}
+
+static inline int verify_sec_ctx_len(void *p)
+{
+	struct sadb_x_sec_ctx *sec_ctx = (struct sadb_x_sec_ctx *)p;
+	int len;
+
+	if (sec_ctx->sadb_x_ctx_len > PAGE_SIZE)
+		return -EINVAL;
+
+	len = pfkey_sec_ctx_len(sec_ctx);
+
+	if (sec_ctx->sadb_x_sec_len != len)
+		return -EINVAL;
+
+	return 0;
+}
+
+static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(struct sadb_x_sec_ctx *sec_ctx)
+{
+	struct xfrm_user_sec_ctx *uctx = NULL;
+	int ctx_size = sec_ctx->sadb_x_ctx_len;
+
+	uctx = kmalloc((sizeof(*uctx)+ctx_size), GFP_KERNEL);
+
+	if (!uctx)
+		return NULL;
+
+	uctx->len = pfkey_sec_ctx_len(sec_ctx);
+	uctx->exttype = sec_ctx->sadb_x_sec_exttype;
+	uctx->ctx_doi = sec_ctx->sadb_x_ctx_doi;
+	uctx->ctx_alg = sec_ctx->sadb_x_ctx_alg;
+	uctx->ctx_len = sec_ctx->sadb_x_ctx_len;
+	memcpy(uctx + 1, sec_ctx + 1,
+	       uctx->ctx_len);
+
+	return uctx;
+}
+
 static int present_and_same_family(struct sadb_address *src,
 				   struct sadb_address *dst)
 {
@@ -438,6 +488,10 @@
 				if (verify_address_len(p))
 					return -EINVAL;
 			}				
+			if (ext_type == SADB_X_EXT_SEC_CTX) {
+				if (verify_sec_ctx_len(p))
+					return -EINVAL;
+			}
 			ext_hdrs[ext_type-1] = p;
 		}
 		p   += ext_len;
@@ -586,6 +640,9 @@
 	struct sadb_key *key;
 	struct sadb_x_sa2 *sa2;
 	struct sockaddr_in *sin;
+	struct sadb_x_sec_ctx *sec_ctx;
+	struct xfrm_sec_ctx *xfrm_ctx;
+	int ctx_size = 0;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct sockaddr_in6 *sin6;
 #endif
@@ -609,6 +666,12 @@
 			sizeof(struct sadb_address)*2 + 
 				sockaddr_size*2 +
 					sizeof(struct sadb_x_sa2);
+
+	if ((xfrm_ctx = x->security)) {
+		ctx_size = PFKEY_ALIGN8(xfrm_ctx->ctx_len);
+		size += sizeof(struct sadb_x_sec_ctx) + ctx_size;
+	}
+
 	/* identity & sensitivity */
 
 	if ((x->props.family == AF_INET &&
@@ -899,6 +962,20 @@
 		n_port->sadb_x_nat_t_port_reserved = 0;
 	}
 
+	/* security context */
+	if (xfrm_ctx) {
+		sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb,
+				sizeof(struct sadb_x_sec_ctx) + ctx_size);
+		sec_ctx->sadb_x_sec_len =
+		  (sizeof(struct sadb_x_sec_ctx) + ctx_size) / sizeof(uint64_t);
+		sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
+		sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
+		sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
+		sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
+		memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
+		       xfrm_ctx->ctx_len);
+	}
+
 	return skb;
 }
 
@@ -909,6 +986,7 @@
 	struct sadb_lifetime *lifetime;
 	struct sadb_sa *sa;
 	struct sadb_key *key;
+	struct sadb_x_sec_ctx *sec_ctx;
 	uint16_t proto;
 	int err;
 	
@@ -993,6 +1071,21 @@
 		x->lft.soft_add_expires_seconds = lifetime->sadb_lifetime_addtime;
 		x->lft.soft_use_expires_seconds = lifetime->sadb_lifetime_usetime;
 	}
+
+	sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
+	if (sec_ctx != NULL) {
+		struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+
+		if (!uctx)
+			goto out;
+
+		err = security_xfrm_state_alloc(x, uctx);
+		kfree(uctx);
+
+		if (err)
+			goto out;
+	}
+
 	key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_AUTH-1];
 	if (sa->sadb_sa_auth) {
 		int keysize = 0;
@@ -1720,6 +1813,18 @@
 	return 0;
 }
 
+static inline int pfkey_xfrm_policy2sec_ctx_size(struct xfrm_policy *xp)
+{
+  struct xfrm_sec_ctx *xfrm_ctx = xp->security;
+
+	if (xfrm_ctx) {
+		int len = sizeof(struct sadb_x_sec_ctx);
+		len += xfrm_ctx->ctx_len;
+		return PFKEY_ALIGN8(len);
+	}
+	return 0;
+}
+
 static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
 {
 	int sockaddr_size = pfkey_sockaddr_size(xp->family);
@@ -1733,7 +1838,8 @@
 		(sockaddr_size * 2) +
 		sizeof(struct sadb_x_policy) +
 		(xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) +
-				(socklen * 2)));
+				(socklen * 2))) +
+		pfkey_xfrm_policy2sec_ctx_size(xp);
 }
 
 static struct sk_buff * pfkey_xfrm_policy2msg_prep(struct xfrm_policy *xp)
@@ -1757,6 +1863,8 @@
 	struct sadb_lifetime *lifetime;
 	struct sadb_x_policy *pol;
 	struct sockaddr_in   *sin;
+	struct sadb_x_sec_ctx *sec_ctx;
+	struct xfrm_sec_ctx *xfrm_ctx;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	struct sockaddr_in6  *sin6;
 #endif
@@ -1941,6 +2049,21 @@
 			}
 		}
 	}
+
+	/* security context */
+	if ((xfrm_ctx = xp->security)) {
+		int ctx_size = pfkey_xfrm_policy2sec_ctx_size(xp);
+
+		sec_ctx = (struct sadb_x_sec_ctx *) skb_put(skb, ctx_size);
+		sec_ctx->sadb_x_sec_len = ctx_size / sizeof(uint64_t);
+		sec_ctx->sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
+		sec_ctx->sadb_x_ctx_doi = xfrm_ctx->ctx_doi;
+		sec_ctx->sadb_x_ctx_alg = xfrm_ctx->ctx_alg;
+		sec_ctx->sadb_x_ctx_len = xfrm_ctx->ctx_len;
+		memcpy(sec_ctx + 1, xfrm_ctx->ctx_str,
+		       xfrm_ctx->ctx_len);
+	}
+
 	hdr->sadb_msg_len = size / sizeof(uint64_t);
 	hdr->sadb_msg_reserved = atomic_read(&xp->refcnt);
 }
@@ -1976,12 +2099,13 @@
 
 static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
-	int err;
+	int err = 0;
 	struct sadb_lifetime *lifetime;
 	struct sadb_address *sa;
 	struct sadb_x_policy *pol;
 	struct xfrm_policy *xp;
 	struct km_event c;
+	struct sadb_x_sec_ctx *sec_ctx;
 
 	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2028,6 +2152,22 @@
 	if (xp->selector.dport)
 		xp->selector.dport_mask = ~0;
 
+	sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
+	if (sec_ctx != NULL) {
+		struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+
+		if (!uctx) {
+			err = -ENOBUFS;
+			goto out;
+		}
+
+		err = security_xfrm_policy_alloc(xp, uctx);
+		kfree(uctx);
+
+		if (err)
+			goto out;
+	}
+
 	xp->lft.soft_byte_limit = XFRM_INF;
 	xp->lft.hard_byte_limit = XFRM_INF;
 	xp->lft.soft_packet_limit = XFRM_INF;
@@ -2051,10 +2191,9 @@
 
 	err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
 				 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
-	if (err) {
-		kfree(xp);
-		return err;
-	}
+
+	if (err)
+		goto out;
 
 	if (hdr->sadb_msg_type == SADB_X_SPDUPDATE)
 		c.event = XFRM_MSG_UPDPOLICY;
@@ -2069,6 +2208,7 @@
 	return 0;
 
 out:
+	security_xfrm_policy_free(xp);
 	kfree(xp);
 	return err;
 }
@@ -2078,9 +2218,10 @@
 	int err;
 	struct sadb_address *sa;
 	struct sadb_x_policy *pol;
-	struct xfrm_policy *xp;
+	struct xfrm_policy *xp, tmp;
 	struct xfrm_selector sel;
 	struct km_event c;
+	struct sadb_x_sec_ctx *sec_ctx;
 
 	if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1],
 				     ext_hdrs[SADB_EXT_ADDRESS_DST-1]) ||
@@ -2109,7 +2250,24 @@
 	if (sel.dport)
 		sel.dport_mask = ~0;
 
-	xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1);
+	sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
+	memset(&tmp, 0, sizeof(struct xfrm_policy));
+
+	if (sec_ctx != NULL) {
+		struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+
+		if (!uctx)
+			return -ENOMEM;
+
+		err = security_xfrm_policy_alloc(&tmp, uctx);
+		kfree(uctx);
+
+		if (err)
+			return err;
+	}
+
+	xp = xfrm_policy_bysel_ctx(pol->sadb_x_policy_dir-1, &sel, tmp.security, 1);
+	security_xfrm_policy_free(&tmp);
 	if (xp == NULL)
 		return -ENOENT;
 
@@ -2660,6 +2818,7 @@
 {
 	struct xfrm_policy *xp;
 	struct sadb_x_policy *pol = (struct sadb_x_policy*)data;
+	struct sadb_x_sec_ctx *sec_ctx;
 
 	switch (family) {
 	case AF_INET:
@@ -2709,10 +2868,32 @@
 	    (*dir = parse_ipsecrequests(xp, pol)) < 0)
 		goto out;
 
+	/* security context too */
+	if (len >= (pol->sadb_x_policy_len*8 +
+	    sizeof(struct sadb_x_sec_ctx))) {
+		char *p = (char *)pol;
+		struct xfrm_user_sec_ctx *uctx;
+
+		p += pol->sadb_x_policy_len*8;
+		sec_ctx = (struct sadb_x_sec_ctx *)p;
+		if (len < pol->sadb_x_policy_len*8 +
+		    sec_ctx->sadb_x_sec_len)
+			goto out;
+		if ((*dir = verify_sec_ctx_len(p)))
+			goto out;
+		uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx);
+		*dir = security_xfrm_policy_alloc(xp, uctx);
+		kfree(uctx);
+
+		if (*dir)
+			goto out;
+	}
+
 	*dir = pol->sadb_x_policy_dir-1;
 	return xp;
 
 out:
+	security_xfrm_policy_free(xp);
 	kfree(xp);
 	return NULL;
 }
@@ -2946,7 +3127,7 @@
 	return err;
 }
 
-static struct proto_ops pfkey_ops = {
+static const struct proto_ops pfkey_ops = {
 	.family		=	PF_KEY,
 	.owner		=	THIS_MODULE,
 	/* Operations that make no sense on pfkey sockets. */
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index c3f0b07..8171c53 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -36,7 +36,7 @@
 static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
 static u16 llc_ui_sap_link_no_max[256];
 static struct sockaddr_llc llc_ui_addrnull;
-static struct proto_ops llc_ui_ops;
+static const struct proto_ops llc_ui_ops;
 
 static int llc_ui_wait_for_conn(struct sock *sk, long timeout);
 static int llc_ui_wait_for_disc(struct sock *sk, long timeout);
@@ -566,10 +566,9 @@
 		/*
 		 * POSIX 1003.1g mandates this order.
 		 */
-		if (sk->sk_err) {
-			rc = sock_error(sk);
+		rc = sock_error(sk);
+		if (rc)
 			break;
-		}
 		rc = 0;
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
 			break;
@@ -960,7 +959,7 @@
 static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
 			unsigned long arg)
 {
-	return dev_ioctl(cmd, (void __user *)arg);
+	return -ENOIOCTLCMD;
 }
 
 /**
@@ -1099,7 +1098,7 @@
 	.owner	= THIS_MODULE,
 };
 
-static struct proto_ops llc_ui_ops = {
+static const struct proto_ops llc_ui_ops = {
 	.family	     = PF_LLC,
 	.owner       = THIS_MODULE,
 	.release     = llc_ui_release,
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index a84f922..7d55f9c 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -61,8 +61,8 @@
 	  instead of the individual packets.
 
 config NF_CONNTRACK_EVENTS
-	bool "Connection tracking events"
-	depends on NF_CONNTRACK
+	bool "Connection tracking events (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && NF_CONNTRACK
 	help
 	  If this option is enabled, the connection tracking code will
 	  provide a notifier chain that can be used by other kernel code
@@ -95,4 +95,11 @@
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+config NF_CT_NETLINK
+	tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
+	depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK
+	depends on NF_CONNTRACK!=y || NETFILTER_NETLINK!=m
+	help
+	  This option enables support for a netlink-based userspace interface
+
 endmenu
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 55f019a..cb21831 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -13,3 +13,6 @@
 
 # SCTP protocol connection tracking
 obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
+
+# netlink interface for nf_conntrack
+obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 1da6783..62bb509 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -82,6 +82,8 @@
 static LIST_HEAD(unconfirmed);
 static int nf_conntrack_vmalloc;
 
+static unsigned int nf_conntrack_next_id = 1;
+static unsigned int nf_conntrack_expect_next_id = 1;
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
 struct notifier_block *nf_conntrack_chain;
 struct notifier_block *nf_conntrack_expect_chain;
@@ -184,7 +186,7 @@
 
 extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
 struct nf_conntrack_protocol *
-nf_ct_find_proto(u_int16_t l3proto, u_int8_t protocol)
+__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol)
 {
 	if (unlikely(nf_ct_protos[l3proto] == NULL))
 		return &nf_conntrack_generic_protocol;
@@ -192,6 +194,50 @@
 	return nf_ct_protos[l3proto][protocol];
 }
 
+/* this is guaranteed to always return a valid protocol helper, since
+ * it falls back to generic_protocol */
+struct nf_conntrack_protocol *
+nf_ct_proto_find_get(u_int16_t l3proto, u_int8_t protocol)
+{
+	struct nf_conntrack_protocol *p;
+
+	preempt_disable();
+	p = __nf_ct_proto_find(l3proto, protocol);
+	if (p) {
+		if (!try_module_get(p->me))
+			p = &nf_conntrack_generic_protocol;
+	}
+	preempt_enable();
+	
+	return p;
+}
+
+void nf_ct_proto_put(struct nf_conntrack_protocol *p)
+{
+	module_put(p->me);
+}
+
+struct nf_conntrack_l3proto *
+nf_ct_l3proto_find_get(u_int16_t l3proto)
+{
+	struct nf_conntrack_l3proto *p;
+
+	preempt_disable();
+	p = __nf_ct_l3proto_find(l3proto);
+	if (p) {
+		if (!try_module_get(p->me))
+			p = &nf_conntrack_generic_l3proto;
+	}
+	preempt_enable();
+
+	return p;
+}
+
+void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p)
+{
+	module_put(p->me);
+}
+
 static int nf_conntrack_hash_rnd_initted;
 static unsigned int nf_conntrack_hash_rnd;
 
@@ -384,7 +430,7 @@
 }
 
 /* nf_conntrack_expect helper functions */
-static void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
+void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
 {
 	ASSERT_WRITE_LOCK(&nf_conntrack_lock);
 	NF_CT_ASSERT(!timer_pending(&exp->timeout));
@@ -404,6 +450,33 @@
 	nf_conntrack_expect_put(exp);
 }
 
+struct nf_conntrack_expect *
+__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple)
+{
+	struct nf_conntrack_expect *i;
+	
+	list_for_each_entry(i, &nf_conntrack_expect_list, list) {
+		if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) {
+			atomic_inc(&i->use);
+			return i;
+		}
+	}
+	return NULL;
+}
+
+/* Just find a expectation corresponding to a tuple. */
+struct nf_conntrack_expect *
+nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple)
+{
+	struct nf_conntrack_expect *i;
+	
+	read_lock_bh(&nf_conntrack_lock);
+	i = __nf_conntrack_expect_find(tuple);
+	read_unlock_bh(&nf_conntrack_lock);
+
+	return i;
+}
+
 /* If an expectation for this connection is found, it gets delete from
  * global list then returned. */
 static struct nf_conntrack_expect *
@@ -432,7 +505,7 @@
 }
 
 /* delete all expectations for this conntrack */
-static void remove_expectations(struct nf_conn *ct)
+void nf_ct_remove_expectations(struct nf_conn *ct)
 {
 	struct nf_conntrack_expect *i, *tmp;
 
@@ -462,7 +535,7 @@
 	LIST_DELETE(&nf_conntrack_hash[hr], &ct->tuplehash[IP_CT_DIR_REPLY]);
 
 	/* Destroy all pending expectations */
-	remove_expectations(ct);
+	nf_ct_remove_expectations(ct);
 }
 
 static void
@@ -482,12 +555,11 @@
 	/* To make sure we don't get any weird locking issues here:
 	 * destroy_conntrack() MUST NOT be called with a write lock
 	 * to nf_conntrack_lock!!! -HW */
-	l3proto = nf_ct_find_l3proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num);
+	l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num);
 	if (l3proto && l3proto->destroy)
 		l3proto->destroy(ct);
 
-	proto = nf_ct_find_proto(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num,
-				 ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
+	proto = __nf_ct_proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
 	if (proto && proto->destroy)
 		proto->destroy(ct);
 
@@ -499,7 +571,7 @@
 	 * except TFTP can create an expectation on the first packet,
 	 * before connection is in the list, so we need to clean here,
 	 * too. */
-	remove_expectations(ct);
+	nf_ct_remove_expectations(ct);
 
 	/* We overload first tuple to link into unconfirmed list. */
 	if (!nf_ct_is_confirmed(ct)) {
@@ -540,7 +612,7 @@
 		&& nf_ct_tuple_equal(tuple, &i->tuple);
 }
 
-static struct nf_conntrack_tuple_hash *
+struct nf_conntrack_tuple_hash *
 __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
 		    const struct nf_conn *ignored_conntrack)
 {
@@ -575,6 +647,29 @@
 	return h;
 }
 
+static void __nf_conntrack_hash_insert(struct nf_conn *ct,
+				       unsigned int hash,
+				       unsigned int repl_hash) 
+{
+	ct->id = ++nf_conntrack_next_id;
+	list_prepend(&nf_conntrack_hash[hash],
+		     &ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
+	list_prepend(&nf_conntrack_hash[repl_hash],
+		     &ct->tuplehash[IP_CT_DIR_REPLY].list);
+}
+
+void nf_conntrack_hash_insert(struct nf_conn *ct)
+{
+	unsigned int hash, repl_hash;
+
+	hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+	repl_hash = hash_conntrack(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+
+	write_lock_bh(&nf_conntrack_lock);
+	__nf_conntrack_hash_insert(ct, hash, repl_hash);
+	write_unlock_bh(&nf_conntrack_lock);
+}
+
 /* Confirm a connection given skb; places it in hash table */
 int
 __nf_conntrack_confirm(struct sk_buff **pskb)
@@ -621,10 +716,7 @@
 		/* Remove from unconfirmed list */
 		list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
 
-		list_prepend(&nf_conntrack_hash[hash],
-			     &ct->tuplehash[IP_CT_DIR_ORIGINAL]);
-		list_prepend(&nf_conntrack_hash[repl_hash],
-			     &ct->tuplehash[IP_CT_DIR_REPLY]);
+		__nf_conntrack_hash_insert(ct, hash, repl_hash);
 		/* Timer relative to confirmation time, not original
 		   setting time, otherwise we'd get timer wrap in
 		   weird delay cases. */
@@ -708,13 +800,41 @@
 }
 
 static struct nf_conntrack_helper *
-nf_ct_find_helper(const struct nf_conntrack_tuple *tuple)
+__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
 {
 	return LIST_FIND(&helpers, helper_cmp,
 			 struct nf_conntrack_helper *,
 			 tuple);
 }
 
+struct nf_conntrack_helper *
+nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple)
+{
+	struct nf_conntrack_helper *helper;
+
+	/* need nf_conntrack_lock to assure that helper exists until
+	 * try_module_get() is called */
+	read_lock_bh(&nf_conntrack_lock);
+
+	helper = __nf_ct_helper_find(tuple);
+	if (helper) {
+		/* need to increase module usage count to assure helper will
+		 * not go away while the caller is e.g. busy putting a
+		 * conntrack in the hash that uses the helper */
+		if (!try_module_get(helper->me))
+			helper = NULL;
+	}
+
+	read_unlock_bh(&nf_conntrack_lock);
+
+	return helper;
+}
+
+void nf_ct_helper_put(struct nf_conntrack_helper *helper)
+{
+	module_put(helper->me);
+}
+
 static struct nf_conn *
 __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
 		     const struct nf_conntrack_tuple *repl,
@@ -744,7 +864,7 @@
 	/*  find features needed by this conntrack. */
 	features = l3proto->get_features(orig);
 	read_lock_bh(&nf_conntrack_lock);
-	if (nf_ct_find_helper(repl) != NULL)
+	if (__nf_ct_helper_find(repl) != NULL)
 		features |= NF_CT_F_HELP;
 	read_unlock_bh(&nf_conntrack_lock);
 
@@ -794,7 +914,7 @@
 {
 	struct nf_conntrack_l3proto *l3proto;
 
-	l3proto = nf_ct_find_l3proto(orig->src.l3num);
+	l3proto = __nf_ct_l3proto_find(orig->src.l3num);
 	return __nf_conntrack_alloc(orig, repl, l3proto);
 }
 
@@ -853,7 +973,7 @@
 		nf_conntrack_get(&conntrack->master->ct_general);
 		NF_CT_STAT_INC(expect_new);
 	} else {
-		conntrack->helper = nf_ct_find_helper(&repl_tuple);
+		conntrack->helper = __nf_ct_helper_find(&repl_tuple);
 
 		NF_CT_STAT_INC(new);
         }
@@ -947,13 +1067,13 @@
 		return NF_ACCEPT;
 	}
 
-	l3proto = nf_ct_find_l3proto((u_int16_t)pf);
+	l3proto = __nf_ct_l3proto_find((u_int16_t)pf);
 	if ((ret = l3proto->prepare(pskb, hooknum, &dataoff, &protonum)) <= 0) {
 		DEBUGP("not prepared to track yet or error occured\n");
 		return -ret;
 	}
 
-	proto = nf_ct_find_proto((u_int16_t)pf, protonum);
+	proto = __nf_ct_proto_find((u_int16_t)pf, protonum);
 
 	/* It may be an special packet, error, unclean...
 	 * inverse of the return code tells to the netfilter
@@ -1002,9 +1122,9 @@
 			 const struct nf_conntrack_tuple *orig)
 {
 	return nf_ct_invert_tuple(inverse, orig,
-				  nf_ct_find_l3proto(orig->src.l3num),
-				  nf_ct_find_proto(orig->src.l3num,
-						   orig->dst.protonum));
+				  __nf_ct_l3proto_find(orig->src.l3num),
+				  __nf_ct_proto_find(orig->src.l3num,
+						     orig->dst.protonum));
 }
 
 /* Would two expected things clash? */
@@ -1096,6 +1216,7 @@
 	exp->timeout.expires = jiffies + exp->master->helper->timeout * HZ;
 	add_timer(&exp->timeout);
 
+	exp->id = ++nf_conntrack_expect_next_id;
 	atomic_inc(&exp->use);
 	NF_CT_STAT_INC(expect_create);
 }
@@ -1129,6 +1250,7 @@
 int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
 {
 	struct nf_conntrack_expect *i;
+	struct nf_conn *master = expect->master;
 	int ret;
 
 	DEBUGP("nf_conntrack_expect_related %p\n", related_to);
@@ -1149,9 +1271,9 @@
 		}
 	}
 	/* Will be over limit? */
-	if (expect->master->helper->max_expected && 
-	    expect->master->expecting >= expect->master->helper->max_expected)
-		evict_oldest_expect(expect->master);
+	if (master->helper->max_expected && 
+	    master->expecting >= master->helper->max_expected)
+		evict_oldest_expect(master);
 
 	nf_conntrack_expect_insert(expect);
 	nf_conntrack_expect_event(IPEXP_NEW, expect);
@@ -1175,7 +1297,7 @@
 
 	conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
 	if (!conntrack->master && conntrack->expecting == 0)
-		conntrack->helper = nf_ct_find_helper(newreply);
+		conntrack->helper = __nf_ct_helper_find(newreply);
 	write_unlock_bh(&nf_conntrack_lock);
 }
 
@@ -1200,6 +1322,19 @@
 	return 0;
 }
 
+struct nf_conntrack_helper *
+__nf_conntrack_helper_find_byname(const char *name)
+{
+	struct nf_conntrack_helper *h;
+
+	list_for_each_entry(h, &helpers, list) {
+		if (!strcmp(h->name, name))
+			return h;
+	}
+
+	return NULL;
+}
+
 static inline int unhelp(struct nf_conntrack_tuple_hash *i,
 			 const struct nf_conntrack_helper *me)
 {
@@ -1283,6 +1418,51 @@
 		nf_conntrack_event_cache(event, skb);
 }
 
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+/* Generic function for tcp/udp/sctp/dccp and alike. This needs to be
+ * in ip_conntrack_core, since we don't want the protocols to autoload
+ * or depend on ctnetlink */
+int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb,
+			       const struct nf_conntrack_tuple *tuple)
+{
+	NFA_PUT(skb, CTA_PROTO_SRC_PORT, sizeof(u_int16_t),
+		&tuple->src.u.tcp.port);
+	NFA_PUT(skb, CTA_PROTO_DST_PORT, sizeof(u_int16_t),
+		&tuple->dst.u.tcp.port);
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+static const size_t cta_min_proto[CTA_PROTO_MAX] = {
+	[CTA_PROTO_SRC_PORT-1]  = sizeof(u_int16_t),
+	[CTA_PROTO_DST_PORT-1]  = sizeof(u_int16_t)
+};
+
+int nf_ct_port_nfattr_to_tuple(struct nfattr *tb[],
+			       struct nf_conntrack_tuple *t)
+{
+	if (!tb[CTA_PROTO_SRC_PORT-1] || !tb[CTA_PROTO_DST_PORT-1])
+		return -EINVAL;
+
+	if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
+		return -EINVAL;
+
+	t->src.u.tcp.port =
+		*(u_int16_t *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]);
+	t->dst.u.tcp.port =
+		*(u_int16_t *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]);
+
+	return 0;
+}
+#endif
+
 /* Used by ipt_REJECT and ip6t_REJECT. */
 void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
 {
@@ -1365,6 +1545,11 @@
 			   get_order(sizeof(struct list_head) * size));
 }
 
+void nf_conntrack_flush()
+{
+	nf_ct_iterate_cleanup(kill_all, NULL);
+}
+
 /* Mishearing the voices in his head, our hero wonders how he's
    supposed to kill the mall. */
 void nf_conntrack_cleanup(void)
@@ -1378,11 +1563,14 @@
 
 	nf_ct_event_cache_flush();
  i_see_dead_people:
-	nf_ct_iterate_cleanup(kill_all, NULL);
+	nf_conntrack_flush();
 	if (atomic_read(&nf_conntrack_count) != 0) {
 		schedule();
 		goto i_see_dead_people;
 	}
+	/* wait until all references to nf_conntrack_untracked are dropped */
+	while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
+		schedule();
 
 	for (i = 0; i < NF_CT_F_NUM; i++) {
 		if (nf_ct_cache[i].use == 0)
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 65080e2..d5a6eaf 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -44,7 +44,7 @@
 module_param_array(ports, ushort, &ports_c, 0400);
 
 static int loose;
-module_param(loose, int, 0600);
+module_param(loose, bool, 0600);
 
 unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
 				enum ip_conntrack_info ctinfo,
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
new file mode 100644
index 0000000..73ab16b
--- /dev/null
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -0,0 +1,1653 @@
+/* Connection tracking via netlink socket. Allows for user space
+ * protocol helpers and general trouble making from userspace.
+ *
+ * (C) 2001 by Jay Schulist <jschlst@samba.org>
+ * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2003 by Patrick Mchardy <kaber@trash.net>
+ * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
+ *
+ * I've reworked this stuff to use attributes instead of conntrack 
+ * structures. 5.44 am. I need more tea. --pablo 05/07/11.
+ *
+ * Initial connection tracking via netlink development funded and 
+ * generally made possible by Network Robots, Inc. (www.networkrobots.com)
+ *
+ * Further development of this code funded by Astaro AG (http://www.astaro.com)
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * Derived from ip_conntrack_netlink.c: Port by Pablo Neira Ayuso (05/11/14)
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/skbuff.h>
+#include <linux/errno.h>
+#include <linux/netlink.h>
+#include <linux/spinlock.h>
+#include <linux/notifier.h>
+
+#include <linux/netfilter.h>
+#include <net/netfilter/nf_conntrack.h>
+#include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_helper.h>
+#include <net/netfilter/nf_conntrack_l3proto.h>
+#include <net/netfilter/nf_conntrack_protocol.h>
+#include <linux/netfilter_ipv4/ip_nat_protocol.h>
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+MODULE_LICENSE("GPL");
+
+static char __initdata version[] = "0.92";
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+
+static inline int
+ctnetlink_dump_tuples_proto(struct sk_buff *skb, 
+			    const struct nf_conntrack_tuple *tuple)
+{
+	struct nf_conntrack_protocol *proto;
+	int ret = 0;
+
+	NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
+
+	/* If no protocol helper is found, this function will return the
+	 * generic protocol helper, so proto won't *ever* be NULL */
+	proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
+	if (likely(proto->tuple_to_nfattr))
+		ret = proto->tuple_to_nfattr(skb, tuple);
+	
+	nf_ct_proto_put(proto);
+
+	return ret;
+
+nfattr_failure:
+	return -1;
+}
+
+static inline int
+ctnetlink_dump_tuples(struct sk_buff *skb, 
+		      const struct nf_conntrack_tuple *tuple)
+{
+	struct nfattr *nest_parms;
+	struct nf_conntrack_l3proto *l3proto;
+	int ret = 0;
+	
+	l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
+	
+	nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
+	if (likely(l3proto->tuple_to_nfattr))
+		ret = l3proto->tuple_to_nfattr(skb, tuple);
+	NFA_NEST_END(skb, nest_parms);
+
+	nf_ct_l3proto_put(l3proto);
+
+	if (unlikely(ret < 0))
+		return ret;
+
+	nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
+	ret = ctnetlink_dump_tuples_proto(skb, tuple);
+	NFA_NEST_END(skb, nest_parms);
+
+	return ret;
+
+nfattr_failure:
+	return -1;
+}
+
+static inline int
+ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
+{
+	u_int32_t status = htonl((u_int32_t) ct->status);
+	NFA_PUT(skb, CTA_STATUS, sizeof(status), &status);
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+static inline int
+ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct)
+{
+	long timeout_l = ct->timeout.expires - jiffies;
+	u_int32_t timeout;
+
+	if (timeout_l < 0)
+		timeout = 0;
+	else
+		timeout = htonl(timeout_l / HZ);
+	
+	NFA_PUT(skb, CTA_TIMEOUT, sizeof(timeout), &timeout);
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+static inline int
+ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
+{
+	struct nf_conntrack_protocol *proto = nf_ct_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
+	struct nfattr *nest_proto;
+	int ret;
+
+	if (!proto->to_nfattr) {
+		nf_ct_proto_put(proto);
+		return 0;
+	}
+	
+	nest_proto = NFA_NEST(skb, CTA_PROTOINFO);
+
+	ret = proto->to_nfattr(skb, nest_proto, ct);
+
+	nf_ct_proto_put(proto);
+
+	NFA_NEST_END(skb, nest_proto);
+
+	return ret;
+
+nfattr_failure:
+	return -1;
+}
+
+static inline int
+ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
+{
+	struct nfattr *nest_helper;
+
+	if (!ct->helper)
+		return 0;
+		
+	nest_helper = NFA_NEST(skb, CTA_HELP);
+	NFA_PUT(skb, CTA_HELP_NAME, strlen(ct->helper->name), ct->helper->name);
+
+	if (ct->helper->to_nfattr)
+		ct->helper->to_nfattr(skb, ct);
+
+	NFA_NEST_END(skb, nest_helper);
+
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+#ifdef CONFIG_NF_CT_ACCT
+static inline int
+ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
+			enum ip_conntrack_dir dir)
+{
+	enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
+	struct nfattr *nest_count = NFA_NEST(skb, type);
+	u_int32_t tmp;
+
+	tmp = htonl(ct->counters[dir].packets);
+	NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
+
+	tmp = htonl(ct->counters[dir].bytes);
+	NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
+
+	NFA_NEST_END(skb, nest_count);
+
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+#else
+#define ctnetlink_dump_counters(a, b, c) (0)
+#endif
+
+#ifdef CONFIG_NF_CONNTRACK_MARK
+static inline int
+ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
+{
+	u_int32_t mark = htonl(ct->mark);
+
+	NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark);
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+#else
+#define ctnetlink_dump_mark(a, b) (0)
+#endif
+
+static inline int
+ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
+{
+	u_int32_t id = htonl(ct->id);
+	NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id);
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+static inline int
+ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
+{
+	u_int32_t use = htonl(atomic_read(&ct->ct_general.use));
+	
+	NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
+#define tuple(ct, dir) (&(ct)->tuplehash[dir].tuple)
+
+static int
+ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
+		    int event, int nowait, 
+		    const struct nf_conn *ct)
+{
+	struct nlmsghdr *nlh;
+	struct nfgenmsg *nfmsg;
+	struct nfattr *nest_parms;
+	unsigned char *b;
+
+	b = skb->tail;
+
+	event |= NFNL_SUBSYS_CTNETLINK << 8;
+	nlh    = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
+	nfmsg  = NLMSG_DATA(nlh);
+
+	nlh->nlmsg_flags    = (nowait && pid) ? NLM_F_MULTI : 0;
+	nfmsg->nfgen_family = 
+		ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
+	nfmsg->version      = NFNETLINK_V0;
+	nfmsg->res_id	    = 0;
+
+	nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG);
+	if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
+		goto nfattr_failure;
+	NFA_NEST_END(skb, nest_parms);
+	
+	nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY);
+	if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
+		goto nfattr_failure;
+	NFA_NEST_END(skb, nest_parms);
+
+	if (ctnetlink_dump_status(skb, ct) < 0 ||
+	    ctnetlink_dump_timeout(skb, ct) < 0 ||
+	    ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
+	    ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0 ||
+	    ctnetlink_dump_protoinfo(skb, ct) < 0 ||
+	    ctnetlink_dump_helpinfo(skb, ct) < 0 ||
+	    ctnetlink_dump_mark(skb, ct) < 0 ||
+	    ctnetlink_dump_id(skb, ct) < 0 ||
+	    ctnetlink_dump_use(skb, ct) < 0)
+		goto nfattr_failure;
+
+	nlh->nlmsg_len = skb->tail - b;
+	return skb->len;
+
+nlmsg_failure:
+nfattr_failure:
+	skb_trim(skb, b - skb->data);
+	return -1;
+}
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+static int ctnetlink_conntrack_event(struct notifier_block *this,
+                                     unsigned long events, void *ptr)
+{
+	struct nlmsghdr *nlh;
+	struct nfgenmsg *nfmsg;
+	struct nfattr *nest_parms;
+	struct nf_conn *ct = (struct nf_conn *)ptr;
+	struct sk_buff *skb;
+	unsigned int type;
+	unsigned char *b;
+	unsigned int flags = 0, group;
+
+	/* ignore our fake conntrack entry */
+	if (ct == &nf_conntrack_untracked)
+		return NOTIFY_DONE;
+
+	if (events & IPCT_DESTROY) {
+		type = IPCTNL_MSG_CT_DELETE;
+		group = NFNLGRP_CONNTRACK_DESTROY;
+	} else  if (events & (IPCT_NEW | IPCT_RELATED)) {
+		type = IPCTNL_MSG_CT_NEW;
+		flags = NLM_F_CREATE|NLM_F_EXCL;
+		/* dump everything */
+		events = ~0UL;
+		group = NFNLGRP_CONNTRACK_NEW;
+	} else  if (events & (IPCT_STATUS |
+		      IPCT_PROTOINFO |
+		      IPCT_HELPER |
+		      IPCT_HELPINFO |
+		      IPCT_NATINFO)) {
+		type = IPCTNL_MSG_CT_NEW;
+		group = NFNLGRP_CONNTRACK_UPDATE;
+	} else
+		return NOTIFY_DONE;
+	
+  /* FIXME: Check if there are any listeners before, don't hurt performance */
+	
+	skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
+	if (!skb)
+		return NOTIFY_DONE;
+
+	b = skb->tail;
+
+	type |= NFNL_SUBSYS_CTNETLINK << 8;
+	nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
+	nfmsg = NLMSG_DATA(nlh);
+
+	nlh->nlmsg_flags    = flags;
+	nfmsg->nfgen_family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
+	nfmsg->version	= NFNETLINK_V0;
+	nfmsg->res_id	= 0;
+
+	nest_parms = NFA_NEST(skb, CTA_TUPLE_ORIG);
+	if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
+		goto nfattr_failure;
+	NFA_NEST_END(skb, nest_parms);
+	
+	nest_parms = NFA_NEST(skb, CTA_TUPLE_REPLY);
+	if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
+		goto nfattr_failure;
+	NFA_NEST_END(skb, nest_parms);
+	
+	/* NAT stuff is now a status flag */
+	if ((events & IPCT_STATUS || events & IPCT_NATINFO)
+	    && ctnetlink_dump_status(skb, ct) < 0)
+		goto nfattr_failure;
+	if (events & IPCT_REFRESH
+	    && ctnetlink_dump_timeout(skb, ct) < 0)
+		goto nfattr_failure;
+	if (events & IPCT_PROTOINFO
+	    && ctnetlink_dump_protoinfo(skb, ct) < 0)
+		goto nfattr_failure;
+	if (events & IPCT_HELPINFO
+	    && ctnetlink_dump_helpinfo(skb, ct) < 0)
+		goto nfattr_failure;
+
+	if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
+	    ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
+		goto nfattr_failure;
+
+	nlh->nlmsg_len = skb->tail - b;
+	nfnetlink_send(skb, 0, group, 0);
+	return NOTIFY_DONE;
+
+nlmsg_failure:
+nfattr_failure:
+	kfree_skb(skb);
+	return NOTIFY_DONE;
+}
+#endif /* CONFIG_NF_CONNTRACK_EVENTS */
+
+static int ctnetlink_done(struct netlink_callback *cb)
+{
+	DEBUGP("entered %s\n", __FUNCTION__);
+	return 0;
+}
+
+#define L3PROTO(ct) ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num
+
+static int
+ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct nf_conn *ct = NULL;
+	struct nf_conntrack_tuple_hash *h;
+	struct list_head *i;
+	u_int32_t *id = (u_int32_t *) &cb->args[1];
+	struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
+	u_int8_t l3proto = nfmsg->nfgen_family;
+
+	DEBUGP("entered %s, last bucket=%lu id=%u\n", __FUNCTION__, 
+			cb->args[0], *id);
+
+	read_lock_bh(&nf_conntrack_lock);
+	for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++, *id = 0) {
+		list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
+			h = (struct nf_conntrack_tuple_hash *) i;
+			if (DIRECTION(h) != IP_CT_DIR_ORIGINAL)
+				continue;
+			ct = nf_ct_tuplehash_to_ctrack(h);
+			/* Dump entries of a given L3 protocol number.
+			 * If it is not specified, ie. l3proto == 0,
+			 * then dump everything. */
+			if (l3proto && L3PROTO(ct) != l3proto)
+				continue;
+			if (ct->id <= *id)
+				continue;
+			if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
+		                        	cb->nlh->nlmsg_seq,
+						IPCTNL_MSG_CT_NEW,
+						1, ct) < 0)
+				goto out;
+			*id = ct->id;
+		}
+	}
+out:	
+	read_unlock_bh(&nf_conntrack_lock);
+
+	DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
+
+	return skb->len;
+}
+
+#ifdef CONFIG_NF_CT_ACCT
+static int
+ctnetlink_dump_table_w(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct nf_conn *ct = NULL;
+	struct nf_conntrack_tuple_hash *h;
+	struct list_head *i;
+	u_int32_t *id = (u_int32_t *) &cb->args[1];
+	struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
+	u_int8_t l3proto = nfmsg->nfgen_family;	
+
+	DEBUGP("entered %s, last bucket=%u id=%u\n", __FUNCTION__, 
+			cb->args[0], *id);
+
+	write_lock_bh(&nf_conntrack_lock);
+	for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++, *id = 0) {
+		list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
+			h = (struct nf_conntrack_tuple_hash *) i;
+			if (DIRECTION(h) != IP_CT_DIR_ORIGINAL)
+				continue;
+			ct = nf_ct_tuplehash_to_ctrack(h);
+			if (l3proto && L3PROTO(ct) != l3proto)
+				continue;
+			if (ct->id <= *id)
+				continue;
+			if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
+		                        	cb->nlh->nlmsg_seq,
+						IPCTNL_MSG_CT_NEW,
+						1, ct) < 0)
+				goto out;
+			*id = ct->id;
+
+			memset(&ct->counters, 0, sizeof(ct->counters));
+		}
+	}
+out:	
+	write_unlock_bh(&nf_conntrack_lock);
+
+	DEBUGP("leaving, last bucket=%lu id=%u\n", cb->args[0], *id);
+
+	return skb->len;
+}
+#endif
+
+static inline int
+ctnetlink_parse_tuple_ip(struct nfattr *attr, struct nf_conntrack_tuple *tuple)
+{
+	struct nfattr *tb[CTA_IP_MAX];
+	struct nf_conntrack_l3proto *l3proto;
+	int ret = 0;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	nfattr_parse_nested(tb, CTA_IP_MAX, attr);
+
+	l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
+
+	if (likely(l3proto->nfattr_to_tuple))
+		ret = l3proto->nfattr_to_tuple(tb, tuple);
+
+	nf_ct_l3proto_put(l3proto);
+
+	DEBUGP("leaving\n");
+
+	return ret;
+}
+
+static const size_t cta_min_proto[CTA_PROTO_MAX] = {
+	[CTA_PROTO_NUM-1]	= sizeof(u_int8_t),
+};
+
+static inline int
+ctnetlink_parse_tuple_proto(struct nfattr *attr, 
+			    struct nf_conntrack_tuple *tuple)
+{
+	struct nfattr *tb[CTA_PROTO_MAX];
+	struct nf_conntrack_protocol *proto;
+	int ret = 0;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
+
+	if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
+		return -EINVAL;
+
+	if (!tb[CTA_PROTO_NUM-1])
+		return -EINVAL;
+	tuple->dst.protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
+
+	proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum);
+
+	if (likely(proto->nfattr_to_tuple))
+		ret = proto->nfattr_to_tuple(tb, tuple);
+
+	nf_ct_proto_put(proto);
+	
+	return ret;
+}
+
+static inline int
+ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple,
+		      enum ctattr_tuple type, u_int8_t l3num)
+{
+	struct nfattr *tb[CTA_TUPLE_MAX];
+	int err;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	memset(tuple, 0, sizeof(*tuple));
+
+	nfattr_parse_nested(tb, CTA_TUPLE_MAX, cda[type-1]);
+
+	if (!tb[CTA_TUPLE_IP-1])
+		return -EINVAL;
+
+	tuple->src.l3num = l3num;
+
+	err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP-1], tuple);
+	if (err < 0)
+		return err;
+
+	if (!tb[CTA_TUPLE_PROTO-1])
+		return -EINVAL;
+
+	err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO-1], tuple);
+	if (err < 0)
+		return err;
+
+	/* orig and expect tuples get DIR_ORIGINAL */
+	if (type == CTA_TUPLE_REPLY)
+		tuple->dst.dir = IP_CT_DIR_REPLY;
+	else
+		tuple->dst.dir = IP_CT_DIR_ORIGINAL;
+
+	NF_CT_DUMP_TUPLE(tuple);
+
+	DEBUGP("leaving\n");
+
+	return 0;
+}
+
+#ifdef CONFIG_IP_NF_NAT_NEEDED
+static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = {
+	[CTA_PROTONAT_PORT_MIN-1]       = sizeof(u_int16_t),
+	[CTA_PROTONAT_PORT_MAX-1]       = sizeof(u_int16_t),
+};
+
+static int ctnetlink_parse_nat_proto(struct nfattr *attr,
+				     const struct nf_conn *ct,
+				     struct ip_nat_range *range)
+{
+	struct nfattr *tb[CTA_PROTONAT_MAX];
+	struct ip_nat_protocol *npt;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
+
+	if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
+		return -EINVAL;
+
+	npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
+
+	if (!npt->nfattr_to_range) {
+		ip_nat_proto_put(npt);
+		return 0;
+	}
+
+	/* nfattr_to_range returns 1 if it parsed, 0 if not, neg. on error */
+	if (npt->nfattr_to_range(tb, range) > 0)
+		range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+
+	ip_nat_proto_put(npt);
+
+	DEBUGP("leaving\n");
+	return 0;
+}
+
+static const size_t cta_min_nat[CTA_NAT_MAX] = {
+	[CTA_NAT_MINIP-1]       = sizeof(u_int32_t),
+	[CTA_NAT_MAXIP-1]       = sizeof(u_int32_t),
+};
+
+static inline int
+ctnetlink_parse_nat(struct nfattr *cda[],
+		    const struct nf_conn *ct, struct ip_nat_range *range)
+{
+	struct nfattr *tb[CTA_NAT_MAX];
+	int err;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	memset(range, 0, sizeof(*range));
+	
+	nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]);
+
+	if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
+		return -EINVAL;
+
+	if (tb[CTA_NAT_MINIP-1])
+		range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
+
+	if (!tb[CTA_NAT_MAXIP-1])
+		range->max_ip = range->min_ip;
+	else
+		range->max_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MAXIP-1]);
+
+	if (range->min_ip)
+		range->flags |= IP_NAT_RANGE_MAP_IPS;
+
+	if (!tb[CTA_NAT_PROTO-1])
+		return 0;
+
+	err = ctnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range);
+	if (err < 0)
+		return err;
+
+	DEBUGP("leaving\n");
+	return 0;
+}
+#endif
+
+static inline int
+ctnetlink_parse_help(struct nfattr *attr, char **helper_name)
+{
+	struct nfattr *tb[CTA_HELP_MAX];
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	nfattr_parse_nested(tb, CTA_HELP_MAX, attr);
+
+	if (!tb[CTA_HELP_NAME-1])
+		return -EINVAL;
+
+	*helper_name = NFA_DATA(tb[CTA_HELP_NAME-1]);
+
+	return 0;
+}
+
+static const size_t cta_min[CTA_MAX] = {
+	[CTA_STATUS-1] 		= sizeof(u_int32_t),
+	[CTA_TIMEOUT-1] 	= sizeof(u_int32_t),
+	[CTA_MARK-1]		= sizeof(u_int32_t),
+	[CTA_USE-1]		= sizeof(u_int32_t),
+	[CTA_ID-1]		= sizeof(u_int32_t)
+};
+
+static int
+ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, 
+			struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+{
+	struct nf_conntrack_tuple_hash *h;
+	struct nf_conntrack_tuple tuple;
+	struct nf_conn *ct;
+	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+	u_int8_t u3 = nfmsg->nfgen_family;
+	int err = 0;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	if (nfattr_bad_size(cda, CTA_MAX, cta_min))
+		return -EINVAL;
+
+	if (cda[CTA_TUPLE_ORIG-1])
+		err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
+	else if (cda[CTA_TUPLE_REPLY-1])
+		err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
+	else {
+		/* Flush the whole table */
+		nf_conntrack_flush();
+		return 0;
+	}
+
+	if (err < 0)
+		return err;
+
+	h = nf_conntrack_find_get(&tuple, NULL);
+	if (!h) {
+		DEBUGP("tuple not found in conntrack hash\n");
+		return -ENOENT;
+	}
+
+	ct = nf_ct_tuplehash_to_ctrack(h);
+	
+	if (cda[CTA_ID-1]) {
+		u_int32_t id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_ID-1]));
+		if (ct->id != id) {
+			nf_ct_put(ct);
+			return -ENOENT;
+		}
+	}	
+	if (del_timer(&ct->timeout))
+		ct->timeout.function((unsigned long)ct);
+
+	nf_ct_put(ct);
+	DEBUGP("leaving\n");
+
+	return 0;
+}
+
+static int
+ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, 
+			struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+{
+	struct nf_conntrack_tuple_hash *h;
+	struct nf_conntrack_tuple tuple;
+	struct nf_conn *ct;
+	struct sk_buff *skb2 = NULL;
+	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+	u_int8_t u3 = nfmsg->nfgen_family;
+	int err = 0;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	if (nlh->nlmsg_flags & NLM_F_DUMP) {
+		u32 rlen;
+
+		if (NFNL_MSG_TYPE(nlh->nlmsg_type) ==
+					IPCTNL_MSG_CT_GET_CTRZERO) {
+#ifdef CONFIG_NF_CT_ACCT
+			if ((*errp = netlink_dump_start(ctnl, skb, nlh,
+						ctnetlink_dump_table_w,
+						ctnetlink_done)) != 0)
+				return -EINVAL;
+#else
+			return -ENOTSUPP;
+#endif
+		} else {
+			if ((*errp = netlink_dump_start(ctnl, skb, nlh,
+		      		                        ctnetlink_dump_table,
+		                                	ctnetlink_done)) != 0)
+			return -EINVAL;
+		}
+
+		rlen = NLMSG_ALIGN(nlh->nlmsg_len);
+		if (rlen > skb->len)
+			rlen = skb->len;
+		skb_pull(skb, rlen);
+		return 0;
+	}
+
+	if (nfattr_bad_size(cda, CTA_MAX, cta_min))
+		return -EINVAL;
+
+	if (cda[CTA_TUPLE_ORIG-1])
+		err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
+	else if (cda[CTA_TUPLE_REPLY-1])
+		err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
+	else
+		return -EINVAL;
+
+	if (err < 0)
+		return err;
+
+	h = nf_conntrack_find_get(&tuple, NULL);
+	if (!h) {
+		DEBUGP("tuple not found in conntrack hash");
+		return -ENOENT;
+	}
+	DEBUGP("tuple found\n");
+	ct = nf_ct_tuplehash_to_ctrack(h);
+
+	err = -ENOMEM;
+	skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!skb2) {
+		nf_ct_put(ct);
+		return -ENOMEM;
+	}
+	NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid;
+
+	err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 
+				  IPCTNL_MSG_CT_NEW, 1, ct);
+	nf_ct_put(ct);
+	if (err <= 0)
+		goto free;
+
+	err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+	if (err < 0)
+		goto out;
+
+	DEBUGP("leaving\n");
+	return 0;
+
+free:
+	kfree_skb(skb2);
+out:
+	return err;
+}
+
+static inline int
+ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[])
+{
+	unsigned long d;
+	unsigned status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]));
+	d = ct->status ^ status;
+
+	if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
+		/* unchangeable */
+		return -EINVAL;
+	
+	if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
+		/* SEEN_REPLY bit can only be set */
+		return -EINVAL;
+
+	
+	if (d & IPS_ASSURED && !(status & IPS_ASSURED))
+		/* ASSURED bit can only be set */
+		return -EINVAL;
+
+	if (cda[CTA_NAT-1]) {
+#ifndef CONFIG_IP_NF_NAT_NEEDED
+		return -EINVAL;
+#else
+		unsigned int hooknum;
+		struct ip_nat_range range;
+
+		if (ctnetlink_parse_nat(cda, ct, &range) < 0)
+			return -EINVAL;
+
+		DEBUGP("NAT: %u.%u.%u.%u-%u.%u.%u.%u:%u-%u\n", 
+		       NIPQUAD(range.min_ip), NIPQUAD(range.max_ip),
+		       htons(range.min.all), htons(range.max.all));
+		
+		/* This is tricky but it works. ip_nat_setup_info needs the
+		 * hook number as parameter, so let's do the correct 
+		 * conversion and run away */
+		if (status & IPS_SRC_NAT_DONE)
+			hooknum = NF_IP_POST_ROUTING; /* IP_NAT_MANIP_SRC */
+		else if (status & IPS_DST_NAT_DONE)
+			hooknum = NF_IP_PRE_ROUTING;  /* IP_NAT_MANIP_DST */
+		else 
+			return -EINVAL; /* Missing NAT flags */
+
+		DEBUGP("NAT status: %lu\n", 
+		       status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK));
+		
+		if (ip_nat_initialized(ct, HOOK2MANIP(hooknum)))
+			return -EEXIST;
+		ip_nat_setup_info(ct, &range, hooknum);
+
+                DEBUGP("NAT status after setup_info: %lu\n",
+                       ct->status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK));
+#endif
+	}
+
+	/* Be careful here, modifying NAT bits can screw up things,
+	 * so don't let users modify them directly if they don't pass
+	 * ip_nat_range. */
+	ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK);
+	return 0;
+}
+
+
+static inline int
+ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
+{
+	struct nf_conntrack_helper *helper;
+	char *helpname;
+	int err;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	/* don't change helper of sibling connections */
+	if (ct->master)
+		return -EINVAL;
+
+	err = ctnetlink_parse_help(cda[CTA_HELP-1], &helpname);
+	if (err < 0)
+		return err;
+
+	helper = __nf_conntrack_helper_find_byname(helpname);
+	if (!helper) {
+		if (!strcmp(helpname, ""))
+			helper = NULL;
+		else
+			return -EINVAL;
+	}
+
+	if (ct->helper) {
+		if (!helper) {
+			/* we had a helper before ... */
+			nf_ct_remove_expectations(ct);
+			ct->helper = NULL;
+		} else {
+			/* need to zero data of old helper */
+			memset(&ct->help, 0, sizeof(ct->help));
+		}
+	}
+	
+	ct->helper = helper;
+
+	return 0;
+}
+
+static inline int
+ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[])
+{
+	u_int32_t timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
+	
+	if (!del_timer(&ct->timeout))
+		return -ETIME;
+
+	ct->timeout.expires = jiffies + timeout * HZ;
+	add_timer(&ct->timeout);
+
+	return 0;
+}
+
+static inline int
+ctnetlink_change_protoinfo(struct nf_conn *ct, struct nfattr *cda[])
+{
+	struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1];
+	struct nf_conntrack_protocol *proto;
+	u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
+	u_int16_t l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
+	int err = 0;
+
+	nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
+
+	proto = nf_ct_proto_find_get(l3num, npt);
+
+	if (proto->from_nfattr)
+		err = proto->from_nfattr(tb, ct);
+	nf_ct_proto_put(proto); 
+
+	return err;
+}
+
+static int
+ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
+{
+	int err;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	if (cda[CTA_HELP-1]) {
+		err = ctnetlink_change_helper(ct, cda);
+		if (err < 0)
+			return err;
+	}
+
+	if (cda[CTA_TIMEOUT-1]) {
+		err = ctnetlink_change_timeout(ct, cda);
+		if (err < 0)
+			return err;
+	}
+
+	if (cda[CTA_STATUS-1]) {
+		err = ctnetlink_change_status(ct, cda);
+		if (err < 0)
+			return err;
+	}
+
+	if (cda[CTA_PROTOINFO-1]) {
+		err = ctnetlink_change_protoinfo(ct, cda);
+		if (err < 0)
+			return err;
+	}
+
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+	if (cda[CTA_MARK-1])
+		ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+#endif
+
+	DEBUGP("all done\n");
+	return 0;
+}
+
+static int
+ctnetlink_create_conntrack(struct nfattr *cda[], 
+			   struct nf_conntrack_tuple *otuple,
+			   struct nf_conntrack_tuple *rtuple)
+{
+	struct nf_conn *ct;
+	int err = -EINVAL;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	ct = nf_conntrack_alloc(otuple, rtuple);
+	if (ct == NULL || IS_ERR(ct))
+		return -ENOMEM;	
+
+	if (!cda[CTA_TIMEOUT-1])
+		goto err;
+	ct->timeout.expires = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
+
+	ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
+	ct->status |= IPS_CONFIRMED;
+
+	err = ctnetlink_change_status(ct, cda);
+	if (err < 0)
+		goto err;
+
+	if (cda[CTA_PROTOINFO-1]) {
+		err = ctnetlink_change_protoinfo(ct, cda);
+		if (err < 0)
+			return err;
+	}
+
+#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
+	if (cda[CTA_MARK-1])
+		ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+#endif
+
+	ct->helper = nf_ct_helper_find_get(rtuple);
+
+	add_timer(&ct->timeout);
+	nf_conntrack_hash_insert(ct);
+
+	if (ct->helper)
+		nf_ct_helper_put(ct->helper);
+
+	DEBUGP("conntrack with id %u inserted\n", ct->id);
+	return 0;
+
+err:	
+	nf_conntrack_free(ct);
+	return err;
+}
+
+static int 
+ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, 
+			struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+{
+	struct nf_conntrack_tuple otuple, rtuple;
+	struct nf_conntrack_tuple_hash *h = NULL;
+	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+	u_int8_t u3 = nfmsg->nfgen_family;
+	int err = 0;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	if (nfattr_bad_size(cda, CTA_MAX, cta_min))
+		return -EINVAL;
+
+	if (cda[CTA_TUPLE_ORIG-1]) {
+		err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3);
+		if (err < 0)
+			return err;
+	}
+
+	if (cda[CTA_TUPLE_REPLY-1]) {
+		err = ctnetlink_parse_tuple(cda, &rtuple, CTA_TUPLE_REPLY, u3);
+		if (err < 0)
+			return err;
+	}
+
+	write_lock_bh(&nf_conntrack_lock);
+	if (cda[CTA_TUPLE_ORIG-1])
+		h = __nf_conntrack_find(&otuple, NULL);
+	else if (cda[CTA_TUPLE_REPLY-1])
+		h = __nf_conntrack_find(&rtuple, NULL);
+
+	if (h == NULL) {
+		write_unlock_bh(&nf_conntrack_lock);
+		DEBUGP("no such conntrack, create new\n");
+		err = -ENOENT;
+		if (nlh->nlmsg_flags & NLM_F_CREATE)
+			err = ctnetlink_create_conntrack(cda, &otuple, &rtuple);
+		return err;
+	}
+	/* implicit 'else' */
+
+	/* we only allow nat config for new conntracks */
+	if (cda[CTA_NAT-1]) {
+		err = -EINVAL;
+		goto out_unlock;
+	}
+
+	/* We manipulate the conntrack inside the global conntrack table lock,
+	 * so there's no need to increase the refcount */
+	DEBUGP("conntrack found\n");
+	err = -EEXIST;
+	if (!(nlh->nlmsg_flags & NLM_F_EXCL))
+		err = ctnetlink_change_conntrack(nf_ct_tuplehash_to_ctrack(h), cda);
+
+out_unlock:
+	write_unlock_bh(&nf_conntrack_lock);
+	return err;
+}
+
+/*********************************************************************** 
+ * EXPECT 
+ ***********************************************************************/ 
+
+static inline int
+ctnetlink_exp_dump_tuple(struct sk_buff *skb,
+			 const struct nf_conntrack_tuple *tuple,
+			 enum ctattr_expect type)
+{
+	struct nfattr *nest_parms = NFA_NEST(skb, type);
+	
+	if (ctnetlink_dump_tuples(skb, tuple) < 0)
+		goto nfattr_failure;
+
+	NFA_NEST_END(skb, nest_parms);
+
+	return 0;
+
+nfattr_failure:
+	return -1;
+}			
+
+static inline int
+ctnetlink_exp_dump_expect(struct sk_buff *skb,
+                          const struct nf_conntrack_expect *exp)
+{
+	struct nf_conn *master = exp->master;
+	u_int32_t timeout = htonl((exp->timeout.expires - jiffies) / HZ);
+	u_int32_t id = htonl(exp->id);
+
+	if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
+		goto nfattr_failure;
+	if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0)
+		goto nfattr_failure;
+	if (ctnetlink_exp_dump_tuple(skb,
+				 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+				 CTA_EXPECT_MASTER) < 0)
+		goto nfattr_failure;
+	
+	NFA_PUT(skb, CTA_EXPECT_TIMEOUT, sizeof(timeout), &timeout);
+	NFA_PUT(skb, CTA_EXPECT_ID, sizeof(u_int32_t), &id);
+
+	return 0;
+	
+nfattr_failure:
+	return -1;
+}
+
+static int
+ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
+		    int event, 
+		    int nowait, 
+		    const struct nf_conntrack_expect *exp)
+{
+	struct nlmsghdr *nlh;
+	struct nfgenmsg *nfmsg;
+	unsigned char *b;
+
+	b = skb->tail;
+
+	event |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
+	nlh    = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
+	nfmsg  = NLMSG_DATA(nlh);
+
+	nlh->nlmsg_flags    = (nowait && pid) ? NLM_F_MULTI : 0;
+	nfmsg->nfgen_family = exp->tuple.src.l3num;
+	nfmsg->version	    = NFNETLINK_V0;
+	nfmsg->res_id	    = 0;
+
+	if (ctnetlink_exp_dump_expect(skb, exp) < 0)
+		goto nfattr_failure;
+
+	nlh->nlmsg_len = skb->tail - b;
+	return skb->len;
+
+nlmsg_failure:
+nfattr_failure:
+	skb_trim(skb, b - skb->data);
+	return -1;
+}
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+static int ctnetlink_expect_event(struct notifier_block *this,
+				  unsigned long events, void *ptr)
+{
+	struct nlmsghdr *nlh;
+	struct nfgenmsg *nfmsg;
+	struct nf_conntrack_expect *exp = (struct nf_conntrack_expect *)ptr;
+	struct sk_buff *skb;
+	unsigned int type;
+	unsigned char *b;
+	int flags = 0;
+
+	if (events & IPEXP_NEW) {
+		type = IPCTNL_MSG_EXP_NEW;
+		flags = NLM_F_CREATE|NLM_F_EXCL;
+	} else
+		return NOTIFY_DONE;
+
+	skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
+	if (!skb)
+		return NOTIFY_DONE;
+
+	b = skb->tail;
+
+	type |= NFNL_SUBSYS_CTNETLINK << 8;
+	nlh   = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg));
+	nfmsg = NLMSG_DATA(nlh);
+
+	nlh->nlmsg_flags    = flags;
+	nfmsg->nfgen_family = exp->tuple.src.l3num;
+	nfmsg->version	    = NFNETLINK_V0;
+	nfmsg->res_id	    = 0;
+
+	if (ctnetlink_exp_dump_expect(skb, exp) < 0)
+		goto nfattr_failure;
+
+	nlh->nlmsg_len = skb->tail - b;
+	nfnetlink_send(skb, 0, NFNLGRP_CONNTRACK_EXP_NEW, 0);
+	return NOTIFY_DONE;
+
+nlmsg_failure:
+nfattr_failure:
+	kfree_skb(skb);
+	return NOTIFY_DONE;
+}
+#endif
+
+static int
+ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct nf_conntrack_expect *exp = NULL;
+	struct list_head *i;
+	u_int32_t *id = (u_int32_t *) &cb->args[0];
+	struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
+	u_int8_t l3proto = nfmsg->nfgen_family;
+
+	DEBUGP("entered %s, last id=%llu\n", __FUNCTION__, *id);
+
+	read_lock_bh(&nf_conntrack_lock);
+	list_for_each_prev(i, &nf_conntrack_expect_list) {
+		exp = (struct nf_conntrack_expect *) i;
+		if (l3proto && exp->tuple.src.l3num != l3proto)
+			continue;
+		if (exp->id <= *id)
+			continue;
+		if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
+					    cb->nlh->nlmsg_seq,
+					    IPCTNL_MSG_EXP_NEW,
+					    1, exp) < 0)
+			goto out;
+		*id = exp->id;
+	}
+out:	
+	read_unlock_bh(&nf_conntrack_lock);
+
+	DEBUGP("leaving, last id=%llu\n", *id);
+
+	return skb->len;
+}
+
+static const size_t cta_min_exp[CTA_EXPECT_MAX] = {
+	[CTA_EXPECT_TIMEOUT-1]          = sizeof(u_int32_t),
+	[CTA_EXPECT_ID-1]               = sizeof(u_int32_t)
+};
+
+static int
+ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, 
+		     struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+{
+	struct nf_conntrack_tuple tuple;
+	struct nf_conntrack_expect *exp;
+	struct sk_buff *skb2;
+	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+	u_int8_t u3 = nfmsg->nfgen_family;
+	int err = 0;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
+		return -EINVAL;
+
+	if (nlh->nlmsg_flags & NLM_F_DUMP) {
+		u32 rlen;
+
+		if ((*errp = netlink_dump_start(ctnl, skb, nlh,
+		    				ctnetlink_exp_dump_table,
+						ctnetlink_done)) != 0)
+			return -EINVAL;
+		rlen = NLMSG_ALIGN(nlh->nlmsg_len);
+		if (rlen > skb->len)
+			rlen = skb->len;
+		skb_pull(skb, rlen);
+		return 0;
+	}
+
+	if (cda[CTA_EXPECT_MASTER-1])
+		err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3);
+	else
+		return -EINVAL;
+
+	if (err < 0)
+		return err;
+
+	exp = nf_conntrack_expect_find(&tuple);
+	if (!exp)
+		return -ENOENT;
+
+	if (cda[CTA_EXPECT_ID-1]) {
+		u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
+		if (exp->id != ntohl(id)) {
+			nf_conntrack_expect_put(exp);
+			return -ENOENT;
+		}
+	}	
+
+	err = -ENOMEM;
+	skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!skb2)
+		goto out;
+	NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid;
+	
+	err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, 
+				      nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
+				      1, exp);
+	if (err <= 0)
+		goto free;
+
+	nf_conntrack_expect_put(exp);
+
+	return netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
+
+free:
+	kfree_skb(skb2);
+out:
+	nf_conntrack_expect_put(exp);
+	return err;
+}
+
+static int
+ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, 
+		     struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+{
+	struct nf_conntrack_expect *exp, *tmp;
+	struct nf_conntrack_tuple tuple;
+	struct nf_conntrack_helper *h;
+	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+	u_int8_t u3 = nfmsg->nfgen_family;
+	int err;
+
+	if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
+		return -EINVAL;
+
+	if (cda[CTA_EXPECT_TUPLE-1]) {
+		/* delete a single expect by tuple */
+		err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
+		if (err < 0)
+			return err;
+
+		/* bump usage count to 2 */
+		exp = nf_conntrack_expect_find(&tuple);
+		if (!exp)
+			return -ENOENT;
+
+		if (cda[CTA_EXPECT_ID-1]) {
+			u_int32_t id = 
+				*(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
+			if (exp->id != ntohl(id)) {
+				nf_conntrack_expect_put(exp);
+				return -ENOENT;
+			}
+		}
+
+		/* after list removal, usage count == 1 */
+		nf_conntrack_unexpect_related(exp);
+		/* have to put what we 'get' above. 
+		 * after this line usage count == 0 */
+		nf_conntrack_expect_put(exp);
+	} else if (cda[CTA_EXPECT_HELP_NAME-1]) {
+		char *name = NFA_DATA(cda[CTA_EXPECT_HELP_NAME-1]);
+
+		/* delete all expectations for this helper */
+		write_lock_bh(&nf_conntrack_lock);
+		h = __nf_conntrack_helper_find_byname(name);
+		if (!h) {
+			write_unlock_bh(&nf_conntrack_lock);
+			return -EINVAL;
+		}
+		list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
+					 list) {
+			if (exp->master->helper == h 
+			    && del_timer(&exp->timeout)) {
+				nf_ct_unlink_expect(exp);
+				nf_conntrack_expect_put(exp);
+			}
+		}
+		write_unlock_bh(&nf_conntrack_lock);
+	} else {
+		/* This basically means we have to flush everything*/
+		write_lock_bh(&nf_conntrack_lock);
+		list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list,
+					 list) {
+			if (del_timer(&exp->timeout)) {
+				nf_ct_unlink_expect(exp);
+				nf_conntrack_expect_put(exp);
+			}
+		}
+		write_unlock_bh(&nf_conntrack_lock);
+	}
+
+	return 0;
+}
+static int
+ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nfattr *cda[])
+{
+	return -EOPNOTSUPP;
+}
+
+static int
+ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
+{
+	struct nf_conntrack_tuple tuple, mask, master_tuple;
+	struct nf_conntrack_tuple_hash *h = NULL;
+	struct nf_conntrack_expect *exp;
+	struct nf_conn *ct;
+	int err = 0;
+
+	DEBUGP("entered %s\n", __FUNCTION__);
+
+	/* caller guarantees that those three CTA_EXPECT_* exist */
+	err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
+	if (err < 0)
+		return err;
+	err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3);
+	if (err < 0)
+		return err;
+	err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3);
+	if (err < 0)
+		return err;
+
+	/* Look for master conntrack of this expectation */
+	h = nf_conntrack_find_get(&master_tuple, NULL);
+	if (!h)
+		return -ENOENT;
+	ct = nf_ct_tuplehash_to_ctrack(h);
+
+	if (!ct->helper) {
+		/* such conntrack hasn't got any helper, abort */
+		err = -EINVAL;
+		goto out;
+	}
+
+	exp = nf_conntrack_expect_alloc(ct);
+	if (!exp) {
+		err = -ENOMEM;
+		goto out;
+	}
+	
+	exp->expectfn = NULL;
+	exp->flags = 0;
+	exp->master = ct;
+	memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
+	memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));
+
+	err = nf_conntrack_expect_related(exp);
+	nf_conntrack_expect_put(exp);
+
+out:	
+	nf_ct_put(nf_ct_tuplehash_to_ctrack(h));
+	return err;
+}
+
+static int
+ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
+		     struct nlmsghdr *nlh, struct nfattr *cda[], int *errp)
+{
+	struct nf_conntrack_tuple tuple;
+	struct nf_conntrack_expect *exp;
+	struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+	u_int8_t u3 = nfmsg->nfgen_family;
+	int err = 0;
+
+	DEBUGP("entered %s\n", __FUNCTION__);	
+
+	if (nfattr_bad_size(cda, CTA_EXPECT_MAX, cta_min_exp))
+		return -EINVAL;
+
+	if (!cda[CTA_EXPECT_TUPLE-1]
+	    || !cda[CTA_EXPECT_MASK-1]
+	    || !cda[CTA_EXPECT_MASTER-1])
+		return -EINVAL;
+
+	err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
+	if (err < 0)
+		return err;
+
+	write_lock_bh(&nf_conntrack_lock);
+	exp = __nf_conntrack_expect_find(&tuple);
+
+	if (!exp) {
+		write_unlock_bh(&nf_conntrack_lock);
+		err = -ENOENT;
+		if (nlh->nlmsg_flags & NLM_F_CREATE)
+			err = ctnetlink_create_expect(cda, u3);
+		return err;
+	}
+
+	err = -EEXIST;
+	if (!(nlh->nlmsg_flags & NLM_F_EXCL))
+		err = ctnetlink_change_expect(exp, cda);
+	write_unlock_bh(&nf_conntrack_lock);
+
+	DEBUGP("leaving\n");
+	
+	return err;
+}
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+static struct notifier_block ctnl_notifier = {
+	.notifier_call	= ctnetlink_conntrack_event,
+};
+
+static struct notifier_block ctnl_notifier_exp = {
+	.notifier_call	= ctnetlink_expect_event,
+};
+#endif
+
+static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
+	[IPCTNL_MSG_CT_NEW]		= { .call = ctnetlink_new_conntrack,
+					    .attr_count = CTA_MAX, },
+	[IPCTNL_MSG_CT_GET] 		= { .call = ctnetlink_get_conntrack,
+					    .attr_count = CTA_MAX, },
+	[IPCTNL_MSG_CT_DELETE]  	= { .call = ctnetlink_del_conntrack,
+					    .attr_count = CTA_MAX, },
+	[IPCTNL_MSG_CT_GET_CTRZERO] 	= { .call = ctnetlink_get_conntrack,
+					    .attr_count = CTA_MAX, },
+};
+
+static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
+	[IPCTNL_MSG_EXP_GET]		= { .call = ctnetlink_get_expect,
+					    .attr_count = CTA_EXPECT_MAX, },
+	[IPCTNL_MSG_EXP_NEW]		= { .call = ctnetlink_new_expect,
+					    .attr_count = CTA_EXPECT_MAX, },
+	[IPCTNL_MSG_EXP_DELETE]		= { .call = ctnetlink_del_expect,
+					    .attr_count = CTA_EXPECT_MAX, },
+};
+
+static struct nfnetlink_subsystem ctnl_subsys = {
+	.name				= "conntrack",
+	.subsys_id			= NFNL_SUBSYS_CTNETLINK,
+	.cb_count			= IPCTNL_MSG_MAX,
+	.cb				= ctnl_cb,
+};
+
+static struct nfnetlink_subsystem ctnl_exp_subsys = {
+	.name				= "conntrack_expect",
+	.subsys_id			= NFNL_SUBSYS_CTNETLINK_EXP,
+	.cb_count			= IPCTNL_MSG_EXP_MAX,
+	.cb				= ctnl_exp_cb,
+};
+
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
+
+static int __init ctnetlink_init(void)
+{
+	int ret;
+
+	printk("ctnetlink v%s: registering with nfnetlink.\n", version);
+	ret = nfnetlink_subsys_register(&ctnl_subsys);
+	if (ret < 0) {
+		printk("ctnetlink_init: cannot register with nfnetlink.\n");
+		goto err_out;
+	}
+
+	ret = nfnetlink_subsys_register(&ctnl_exp_subsys);
+	if (ret < 0) {
+		printk("ctnetlink_init: cannot register exp with nfnetlink.\n");
+		goto err_unreg_subsys;
+	}
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+	ret = nf_conntrack_register_notifier(&ctnl_notifier);
+	if (ret < 0) {
+		printk("ctnetlink_init: cannot register notifier.\n");
+		goto err_unreg_exp_subsys;
+	}
+
+	ret = nf_conntrack_expect_register_notifier(&ctnl_notifier_exp);
+	if (ret < 0) {
+		printk("ctnetlink_init: cannot expect register notifier.\n");
+		goto err_unreg_notifier;
+	}
+#endif
+
+	return 0;
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+err_unreg_notifier:
+	nf_conntrack_unregister_notifier(&ctnl_notifier);
+err_unreg_exp_subsys:
+	nfnetlink_subsys_unregister(&ctnl_exp_subsys);
+#endif
+err_unreg_subsys:
+	nfnetlink_subsys_unregister(&ctnl_subsys);
+err_out:
+	return ret;
+}
+
+static void __exit ctnetlink_exit(void)
+{
+	printk("ctnetlink: unregistering from nfnetlink.\n");
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+	nf_conntrack_unregister_notifier(&ctnl_notifier_exp);
+	nf_conntrack_unregister_notifier(&ctnl_notifier);
+#endif
+
+	nfnetlink_subsys_unregister(&ctnl_exp_subsys);
+	nfnetlink_subsys_unregister(&ctnl_subsys);
+	return;
+}
+
+module_init(ctnetlink_init);
+module_exit(ctnetlink_exit);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 5a6fcf3..6167137 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -280,9 +280,9 @@
  *	sCL -> sCL
  */
 /* 	     sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI	*/
-/*ack*/	   { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
+/*ack*/	   { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
 /*
- *	sSS -> sIV	Might be a half-open connection.
+ *	sSS -> sIG	Might be a half-open connection.
  *	sSR -> sSR	Might answer late resent SYN.
  *	sES -> sES	:-)
  *	sFW -> sCW	Normal close request answered by ACK.
@@ -912,8 +912,12 @@
 
 	switch (new_state) {
 	case TCP_CONNTRACK_IGNORE:
-		/* Either SYN in ORIGINAL
-		 * or SYN/ACK in REPLY. */
+		/* Ignored packets:
+		 *
+		 * a) SYN in ORIGINAL
+		 * b) SYN/ACK in REPLY
+		 * c) ACK in reply direction after initial SYN in original. 
+		 */
 		if (index == TCP_SYNACK_SET
 		    && conntrack->proto.tcp.last_index == TCP_SYN_SET
 		    && conntrack->proto.tcp.last_dir != dir
@@ -979,13 +983,20 @@
 		}
 	case TCP_CONNTRACK_CLOSE:
 		if (index == TCP_RST_SET
-		    && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
-		    && conntrack->proto.tcp.last_index == TCP_SYN_SET
+		    && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
+		         && conntrack->proto.tcp.last_index == TCP_SYN_SET)
+		        || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
+		            && conntrack->proto.tcp.last_index == TCP_ACK_SET))
 		    && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
-			/* RST sent to invalid SYN we had let trough
-			 * SYN was in window then, tear down connection.
+			/* RST sent to invalid SYN or ACK we had let trough
+			 * at a) and c) above:
+			 *
+			 * a) SYN was in window then
+			 * c) we hold a half-open connection.
+			 *
+			 * Delete our connection entry.
 			 * We skip window checking, because packet might ACK
-			 * segments we ignored in the SYN. */
+			 * segments we ignored. */
 			goto in_window;
 		}
 		/* Just fall trough */
@@ -1136,6 +1147,63 @@
 		receiver->td_scale);
 	return 1;
 }
+
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
+			 const struct nf_conn *ct)
+{
+	struct nfattr *nest_parms;
+	
+	read_lock_bh(&tcp_lock);
+	nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP);
+	NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
+		&ct->proto.tcp.state);
+	read_unlock_bh(&tcp_lock);
+
+	NFA_NEST_END(skb, nest_parms);
+
+	return 0;
+
+nfattr_failure:
+	read_unlock_bh(&tcp_lock);
+	return -1;
+}
+
+static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
+	[CTA_PROTOINFO_TCP_STATE-1]	= sizeof(u_int8_t),
+};
+
+static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct)
+{
+	struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
+	struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
+
+	/* updates could not contain anything about the private
+	 * protocol info, in that case skip the parsing */
+	if (!attr)
+		return 0;
+
+        nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
+
+	if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp))
+		return -EINVAL;
+
+	if (!tb[CTA_PROTOINFO_TCP_STATE-1])
+		return -EINVAL;
+
+	write_lock_bh(&tcp_lock);
+	ct->proto.tcp.state = 
+		*(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
+	write_unlock_bh(&tcp_lock);
+
+	return 0;
+}
+#endif
   
 struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 =
 {
@@ -1149,6 +1217,13 @@
 	.packet 		= tcp_packet,
 	.new 			= tcp_new,
 	.error			= tcp_error4,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.to_nfattr		= tcp_to_nfattr,
+	.from_nfattr		= nfattr_to_tcp,
+	.tuple_to_nfattr	= nf_ct_port_tuple_to_nfattr,
+	.nfattr_to_tuple	= nf_ct_port_nfattr_to_tuple,
+#endif
 };
 
 struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 =
@@ -1163,6 +1238,13 @@
 	.packet 		= tcp_packet,
 	.new 			= tcp_new,
 	.error			= tcp_error6,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.to_nfattr		= tcp_to_nfattr,
+	.from_nfattr		= nfattr_to_tcp,
+	.tuple_to_nfattr	= nf_ct_port_tuple_to_nfattr,
+	.nfattr_to_tuple	= nf_ct_port_nfattr_to_tuple,
+#endif
 };
 
 EXPORT_SYMBOL(nf_conntrack_protocol_tcp4);
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 3cae7ce..1a592a5 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -196,6 +196,11 @@
 	.packet			= udp_packet,
 	.new			= udp_new,
 	.error			= udp_error4,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.tuple_to_nfattr	= nf_ct_port_tuple_to_nfattr,
+	.nfattr_to_tuple	= nf_ct_port_nfattr_to_tuple,
+#endif
 };
 
 struct nf_conntrack_protocol nf_conntrack_protocol_udp6 =
@@ -210,6 +215,11 @@
 	.packet			= udp_packet,
 	.new			= udp_new,
 	.error			= udp_error6,
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+	.tuple_to_nfattr	= nf_ct_port_tuple_to_nfattr,
+	.nfattr_to_tuple	= nf_ct_port_nfattr_to_tuple,
+#endif
 };
 
 EXPORT_SYMBOL(nf_conntrack_protocol_udp4);
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 5af381f..d17e42b 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -161,14 +161,14 @@
 	if (NF_CT_DIRECTION(hash))
 		return 0;
 
-	l3proto = nf_ct_find_l3proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
-				     .tuple.src.l3num);
+	l3proto = __nf_ct_l3proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+				       .tuple.src.l3num);
 
 	NF_CT_ASSERT(l3proto);
-	proto = nf_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
-				 .tuple.src.l3num,
-				 conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
-				 .tuple.dst.protonum);
+	proto = __nf_ct_proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+				   .tuple.src.l3num,
+				   conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
+				   .tuple.dst.protonum);
 	NF_CT_ASSERT(proto);
 
 	if (seq_printf(s, "%-8s %u %-8s %u %ld ",
@@ -307,9 +307,9 @@
 		   expect->tuple.src.l3num,
 		   expect->tuple.dst.protonum);
 	print_tuple(s, &expect->tuple,
-		    nf_ct_find_l3proto(expect->tuple.src.l3num),
-		    nf_ct_find_proto(expect->tuple.src.l3num,
-				     expect->tuple.dst.protonum));
+		    __nf_ct_l3proto_find(expect->tuple.src.l3num),
+		    __nf_ct_proto_find(expect->tuple.src.l3num,
+				       expect->tuple.dst.protonum));
 	return seq_putc(s, '\n');
 }
 
@@ -847,7 +847,11 @@
 EXPORT_SYMBOL(nf_ct_iterate_cleanup);
 EXPORT_SYMBOL(__nf_ct_refresh_acct);
 EXPORT_SYMBOL(nf_ct_protos);
-EXPORT_SYMBOL(nf_ct_find_proto);
+EXPORT_SYMBOL(__nf_ct_proto_find);
+EXPORT_SYMBOL(nf_ct_proto_find_get);
+EXPORT_SYMBOL(nf_ct_proto_put);
+EXPORT_SYMBOL(nf_ct_l3proto_find_get);
+EXPORT_SYMBOL(nf_ct_l3proto_put);
 EXPORT_SYMBOL(nf_ct_l3protos);
 EXPORT_SYMBOL(nf_conntrack_expect_alloc);
 EXPORT_SYMBOL(nf_conntrack_expect_put);
@@ -867,3 +871,21 @@
 EXPORT_SYMBOL(nf_ct_invert_tuple);
 EXPORT_SYMBOL(nf_conntrack_in);
 EXPORT_SYMBOL(__nf_conntrack_attach);
+EXPORT_SYMBOL(nf_conntrack_alloc);
+EXPORT_SYMBOL(nf_conntrack_free);
+EXPORT_SYMBOL(nf_conntrack_flush);
+EXPORT_SYMBOL(nf_ct_remove_expectations);
+EXPORT_SYMBOL(nf_ct_helper_find_get);
+EXPORT_SYMBOL(nf_ct_helper_put);
+EXPORT_SYMBOL(__nf_conntrack_helper_find_byname);
+EXPORT_SYMBOL(__nf_conntrack_find);
+EXPORT_SYMBOL(nf_ct_unlink_expect);
+EXPORT_SYMBOL(nf_conntrack_hash_insert);
+EXPORT_SYMBOL(__nf_conntrack_expect_find);
+EXPORT_SYMBOL(nf_conntrack_expect_find);
+EXPORT_SYMBOL(nf_conntrack_expect_list);
+#if defined(CONFIG_NF_CT_NETLINK) || \
+    defined(CONFIG_NF_CT_NETLINK_MODULE)
+EXPORT_SYMBOL(nf_ct_port_tuple_to_nfattr);
+EXPORT_SYMBOL(nf_ct_port_nfattr_to_tuple);
+#endif
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index a60c59b..95fdf04 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -162,7 +162,7 @@
 		return -EINVAL;
 	}
 
-	min_len = NLMSG_ALIGN(sizeof(struct nfgenmsg));
+	min_len = NLMSG_SPACE(sizeof(struct nfgenmsg));
 	if (unlikely(nlh->nlmsg_len < min_len))
 		return -EINVAL;
 
@@ -236,8 +236,7 @@
 	}
 
 	/* All the messages must at least contain nfgenmsg */
-	if (nlh->nlmsg_len < 
-			NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg)))) {
+	if (nlh->nlmsg_len < NLMSG_SPACE(sizeof(struct nfgenmsg))) {
 		DEBUGP("received message was too short\n");
 		return 0;
 	}
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index cba6372..e10512e 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -151,7 +151,7 @@
 		goto out_unlock;
 
 	INIT_HLIST_NODE(&inst->hlist);
-	inst->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&inst->lock);
 	/* needs to be two, since we _put() after creation */
 	atomic_set(&inst->use, 2);
 
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index f28460b6..18ed9c5 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -148,7 +148,7 @@
 	atomic_set(&inst->id_sequence, 0);
 	/* needs to be two, since we _put() after creation */
 	atomic_set(&inst->use, 2);
-	inst->lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&inst->lock);
 	INIT_LIST_HEAD(&inst->queue_list);
 
 	if (!try_module_get(THIS_MODULE))
@@ -345,6 +345,10 @@
 	struct nfqnl_msg_packet_hdr pmsg;
 	struct nlmsghdr *nlh;
 	struct nfgenmsg *nfmsg;
+	struct nf_info *entinf = entry->info;
+	struct sk_buff *entskb = entry->skb;
+	struct net_device *indev;
+	struct net_device *outdev;
 	unsigned int tmp_uint;
 
 	QDEBUG("entered\n");
@@ -361,6 +365,8 @@
 		+ NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_hw))
 		+ NLMSG_SPACE(sizeof(struct nfqnl_msg_packet_timestamp));
 
+	outdev = entinf->outdev;
+
 	spin_lock_bh(&queue->lock);
 	
 	switch (queue->copy_mode) {
@@ -370,15 +376,15 @@
 		break;
 	
 	case NFQNL_COPY_PACKET:
-		if (entry->skb->ip_summed == CHECKSUM_HW &&
-		    (*errp = skb_checksum_help(entry->skb,
-		                               entry->info->outdev == NULL))) {
+		if (entskb->ip_summed == CHECKSUM_HW &&
+		    (*errp = skb_checksum_help(entskb,
+		                               outdev == NULL))) {
 			spin_unlock_bh(&queue->lock);
 			return NULL;
 		}
 		if (queue->copy_range == 0 
-		    || queue->copy_range > entry->skb->len)
-			data_len = entry->skb->len;
+		    || queue->copy_range > entskb->len)
+			data_len = entskb->len;
 		else
 			data_len = queue->copy_range;
 		
@@ -402,29 +408,30 @@
 			NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET,
 			sizeof(struct nfgenmsg));
 	nfmsg = NLMSG_DATA(nlh);
-	nfmsg->nfgen_family = entry->info->pf;
+	nfmsg->nfgen_family = entinf->pf;
 	nfmsg->version = NFNETLINK_V0;
 	nfmsg->res_id = htons(queue->queue_num);
 
 	pmsg.packet_id 		= htonl(entry->id);
-	pmsg.hw_protocol	= htons(entry->skb->protocol);
-	pmsg.hook		= entry->info->hook;
+	pmsg.hw_protocol	= htons(entskb->protocol);
+	pmsg.hook		= entinf->hook;
 
 	NFA_PUT(skb, NFQA_PACKET_HDR, sizeof(pmsg), &pmsg);
 
-	if (entry->info->indev) {
-		tmp_uint = htonl(entry->info->indev->ifindex);
+	indev = entinf->indev;
+	if (indev) {
+		tmp_uint = htonl(indev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
 		NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint), &tmp_uint);
 #else
-		if (entry->info->pf == PF_BRIDGE) {
+		if (entinf->pf == PF_BRIDGE) {
 			/* Case 1: indev is physical input device, we need to
 			 * look for bridge group (when called from 
 			 * netfilter_bridge) */
 			NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV, sizeof(tmp_uint), 
 				&tmp_uint);
 			/* this is the bridge group "brX" */
-			tmp_uint = htonl(entry->info->indev->br_port->br->dev->ifindex);
+			tmp_uint = htonl(indev->br_port->br->dev->ifindex);
 			NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
 				&tmp_uint);
 		} else {
@@ -432,9 +439,9 @@
 			 * physical device (when called from ipv4) */
 			NFA_PUT(skb, NFQA_IFINDEX_INDEV, sizeof(tmp_uint),
 				&tmp_uint);
-			if (entry->skb->nf_bridge
-			    && entry->skb->nf_bridge->physindev) {
-				tmp_uint = htonl(entry->skb->nf_bridge->physindev->ifindex);
+			if (entskb->nf_bridge
+			    && entskb->nf_bridge->physindev) {
+				tmp_uint = htonl(entskb->nf_bridge->physindev->ifindex);
 				NFA_PUT(skb, NFQA_IFINDEX_PHYSINDEV,
 					sizeof(tmp_uint), &tmp_uint);
 			}
@@ -442,19 +449,19 @@
 #endif
 	}
 
-	if (entry->info->outdev) {
-		tmp_uint = htonl(entry->info->outdev->ifindex);
+	if (outdev) {
+		tmp_uint = htonl(outdev->ifindex);
 #ifndef CONFIG_BRIDGE_NETFILTER
 		NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint), &tmp_uint);
 #else
-		if (entry->info->pf == PF_BRIDGE) {
+		if (entinf->pf == PF_BRIDGE) {
 			/* Case 1: outdev is physical output device, we need to
 			 * look for bridge group (when called from 
 			 * netfilter_bridge) */
 			NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV, sizeof(tmp_uint),
 				&tmp_uint);
 			/* this is the bridge group "brX" */
-			tmp_uint = htonl(entry->info->outdev->br_port->br->dev->ifindex);
+			tmp_uint = htonl(outdev->br_port->br->dev->ifindex);
 			NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
 				&tmp_uint);
 		} else {
@@ -462,9 +469,9 @@
 			 * physical output device (when called from ipv4) */
 			NFA_PUT(skb, NFQA_IFINDEX_OUTDEV, sizeof(tmp_uint),
 				&tmp_uint);
-			if (entry->skb->nf_bridge
-			    && entry->skb->nf_bridge->physoutdev) {
-				tmp_uint = htonl(entry->skb->nf_bridge->physoutdev->ifindex);
+			if (entskb->nf_bridge
+			    && entskb->nf_bridge->physoutdev) {
+				tmp_uint = htonl(entskb->nf_bridge->physoutdev->ifindex);
 				NFA_PUT(skb, NFQA_IFINDEX_PHYSOUTDEV,
 					sizeof(tmp_uint), &tmp_uint);
 			}
@@ -472,27 +479,27 @@
 #endif
 	}
 
-	if (entry->skb->nfmark) {
-		tmp_uint = htonl(entry->skb->nfmark);
+	if (entskb->nfmark) {
+		tmp_uint = htonl(entskb->nfmark);
 		NFA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint);
 	}
 
-	if (entry->info->indev && entry->skb->dev
-	    && entry->skb->dev->hard_header_parse) {
+	if (indev && entskb->dev
+	    && entskb->dev->hard_header_parse) {
 		struct nfqnl_msg_packet_hw phw;
 
 		phw.hw_addrlen =
-			entry->skb->dev->hard_header_parse(entry->skb,
+			entskb->dev->hard_header_parse(entskb,
 			                                   phw.hw_addr);
 		phw.hw_addrlen = htons(phw.hw_addrlen);
 		NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
 	}
 
-	if (entry->skb->tstamp.off_sec) {
+	if (entskb->tstamp.off_sec) {
 		struct nfqnl_msg_packet_timestamp ts;
 
-		ts.sec = cpu_to_be64(entry->skb->tstamp.off_sec);
-		ts.usec = cpu_to_be64(entry->skb->tstamp.off_usec);
+		ts.sec = cpu_to_be64(entskb->tstamp.off_sec);
+		ts.usec = cpu_to_be64(entskb->tstamp.off_usec);
 
 		NFA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
 	}
@@ -510,7 +517,7 @@
 		nfa->nfa_type = NFQA_PAYLOAD;
 		nfa->nfa_len = size;
 
-		if (skb_copy_bits(entry->skb, 0, NFA_DATA(nfa), data_len))
+		if (skb_copy_bits(entskb, 0, NFA_DATA(nfa), data_len))
 			BUG();
 	}
 		
@@ -667,12 +674,14 @@
 static int
 dev_cmp(struct nfqnl_queue_entry *entry, unsigned long ifindex)
 {
-	if (entry->info->indev)
-		if (entry->info->indev->ifindex == ifindex)
+	struct nf_info *entinf = entry->info;
+	
+	if (entinf->indev)
+		if (entinf->indev->ifindex == ifindex)
 			return 1;
 			
-	if (entry->info->outdev)
-		if (entry->info->outdev->ifindex == ifindex)
+	if (entinf->outdev)
+		if (entinf->outdev->ifindex == ifindex)
 			return 1;
 
 	return 0;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 96020d7..7849cac 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -293,7 +293,7 @@
 	return 0;
 }
 
-static struct proto_ops netlink_ops;
+static const struct proto_ops netlink_ops;
 
 static int netlink_insert(struct sock *sk, u32 pid)
 {
@@ -1656,7 +1656,7 @@
 	return notifier_chain_unregister(&netlink_chain, nb);
 }
                 
-static struct proto_ops netlink_ops = {
+static const struct proto_ops netlink_ops = {
 	.family =	PF_NETLINK,
 	.owner =	THIS_MODULE,
 	.release =	netlink_release,
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 287cfcc..3b13784 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -441,7 +441,7 @@
 }
 
 static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
-				      int seq, int cmd)
+				      int seq, u8 cmd)
 {
 	struct sk_buff *skb;
 	int err;
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index e5d82d7..63b0e4a 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -63,7 +63,7 @@
 static HLIST_HEAD(nr_list);
 static DEFINE_SPINLOCK(nr_list_lock);
 
-static struct proto_ops nr_proto_ops;
+static const struct proto_ops nr_proto_ops;
 
 /*
  *	Socket removal during an interrupt is now safe.
@@ -1166,10 +1166,11 @@
 	void __user *argp = (void __user *)arg;
 	int ret;
 
-	lock_sock(sk);
 	switch (cmd) {
 	case TIOCOUTQ: {
 		long amount;
+
+		lock_sock(sk);
 		amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
 		if (amount < 0)
 			amount = 0;
@@ -1180,6 +1181,8 @@
 	case TIOCINQ: {
 		struct sk_buff *skb;
 		long amount = 0L;
+
+		lock_sock(sk);
 		/* These two are safe on a single CPU system as only user tasks fiddle here */
 		if ((skb = skb_peek(&sk->sk_receive_queue)) != NULL)
 			amount = skb->len;
@@ -1188,6 +1191,7 @@
 	}
 
 	case SIOCGSTAMP:
+		lock_sock(sk);
 		ret = sock_get_timestamp(sk, argp);
 		release_sock(sk);
 		return ret;
@@ -1202,21 +1206,17 @@
 	case SIOCSIFNETMASK:
 	case SIOCGIFMETRIC:
 	case SIOCSIFMETRIC:
-		release_sock(sk);
 		return -EINVAL;
 
 	case SIOCADDRT:
 	case SIOCDELRT:
 	case SIOCNRDECOBS:
-		release_sock(sk);
 		if (!capable(CAP_NET_ADMIN)) return -EPERM;
 		return nr_rt_ioctl(cmd, argp);
 
 	default:
-		release_sock(sk);
-		return dev_ioctl(cmd, argp);
+		return -ENOIOCTLCMD;
 	}
-	release_sock(sk);
 
 	return 0;
 }
@@ -1337,7 +1337,7 @@
 	.owner		=	THIS_MODULE,
 };
 
-static struct proto_ops nr_proto_ops = {
+static const struct proto_ops nr_proto_ops = {
 	.family		=	PF_NETROM,
 	.owner		=	THIS_MODULE,
 	.release	=	nr_release,
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
index 004e859..a7d88b5 100644
--- a/net/netrom/nr_in.c
+++ b/net/netrom/nr_in.c
@@ -99,7 +99,7 @@
 		break;
 
 	case NR_RESET:
-		if (sysctl_netrom_reset_circuit);
+		if (sysctl_netrom_reset_circuit)
 			nr_disconnect(sk, ECONNRESET);
 		break;
 
@@ -130,7 +130,7 @@
 		break;
 
 	case NR_RESET:
-		if (sysctl_netrom_reset_circuit);
+		if (sysctl_netrom_reset_circuit)
 			nr_disconnect(sk, ECONNRESET);
 		break;
 
@@ -265,7 +265,7 @@
 		break;
 
 	case NR_RESET:
-		if (sysctl_netrom_reset_circuit);
+		if (sysctl_netrom_reset_circuit)
 			nr_disconnect(sk, ECONNRESET);
 		break;
 
diff --git a/net/nonet.c b/net/nonet.c
index e5241dce..1230f0a 100644
--- a/net/nonet.c
+++ b/net/nonet.c
@@ -14,11 +14,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 
-void __init sock_init(void)
-{
-	printk(KERN_INFO "Linux NoNET1.0 for Linux 2.6\n");
-}
-
 static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
 {
 	return -ENXIO;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 499ae3d..f69e5ed 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -251,10 +251,10 @@
 }
 
 
-static struct proto_ops packet_ops;
+static const struct proto_ops packet_ops;
 
 #ifdef CONFIG_SOCK_PACKET
-static struct proto_ops packet_ops_spkt;
+static const struct proto_ops packet_ops_spkt;
 
 static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct packet_type *pt, struct net_device *orig_dev)
 {
@@ -1521,7 +1521,7 @@
 #endif
 
 		default:
-			return dev_ioctl(cmd, (void __user *)arg);
+			return -ENOIOCTLCMD;
 	}
 	return 0;
 }
@@ -1587,23 +1587,47 @@
 	return virt_to_page(one_pg_vec + (PAGE_SIZE << order) - 1);
 }
 
-static void free_pg_vec(char **pg_vec, unsigned order, unsigned len)
+static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len)
 {
 	int i;
 
-	for (i=0; i<len; i++) {
-		if (pg_vec[i]) {
-			struct page *page, *pend;
-
-			pend = pg_vec_endpage(pg_vec[i], order);
-			for (page = virt_to_page(pg_vec[i]); page <= pend; page++)
-				ClearPageReserved(page);
-			free_pages((unsigned long)pg_vec[i], order);
-		}
+	for (i = 0; i < len; i++) {
+		if (likely(pg_vec[i]))
+			free_pages((unsigned long) pg_vec[i], order);
 	}
 	kfree(pg_vec);
 }
 
+static inline char *alloc_one_pg_vec_page(unsigned long order)
+{
+	return (char *) __get_free_pages(GFP_KERNEL | __GFP_COMP | __GFP_ZERO,
+					 order);
+}
+
+static char **alloc_pg_vec(struct tpacket_req *req, int order)
+{
+	unsigned int block_nr = req->tp_block_nr;
+	char **pg_vec;
+	int i;
+
+	pg_vec = kzalloc(block_nr * sizeof(char *), GFP_KERNEL);
+	if (unlikely(!pg_vec))
+		goto out;
+
+	for (i = 0; i < block_nr; i++) {
+		pg_vec[i] = alloc_one_pg_vec_page(order);
+		if (unlikely(!pg_vec[i]))
+			goto out_free_pgvec;
+	}
+
+out:
+	return pg_vec;
+
+out_free_pgvec:
+	free_pg_vec(pg_vec, order, block_nr);
+	pg_vec = NULL;
+	goto out;
+}
 
 static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing)
 {
@@ -1617,64 +1641,46 @@
 
 		/* Sanity tests and some calculations */
 
-		if (po->pg_vec)
+		if (unlikely(po->pg_vec))
 			return -EBUSY;
 
-		if ((int)req->tp_block_size <= 0)
+		if (unlikely((int)req->tp_block_size <= 0))
 			return -EINVAL;
-		if (req->tp_block_size&(PAGE_SIZE-1))
+		if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
 			return -EINVAL;
-		if (req->tp_frame_size < TPACKET_HDRLEN)
+		if (unlikely(req->tp_frame_size < TPACKET_HDRLEN))
 			return -EINVAL;
-		if (req->tp_frame_size&(TPACKET_ALIGNMENT-1))
+		if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
 			return -EINVAL;
 
 		po->frames_per_block = req->tp_block_size/req->tp_frame_size;
-		if (po->frames_per_block <= 0)
+		if (unlikely(po->frames_per_block <= 0))
 			return -EINVAL;
-		if (po->frames_per_block*req->tp_block_nr != req->tp_frame_nr)
+		if (unlikely((po->frames_per_block * req->tp_block_nr) !=
+			     req->tp_frame_nr))
 			return -EINVAL;
-		/* OK! */
-
-		/* Allocate page vector */
-		while ((PAGE_SIZE<<order) < req->tp_block_size)
-			order++;
 
 		err = -ENOMEM;
-
-		pg_vec = kmalloc(req->tp_block_nr*sizeof(char *), GFP_KERNEL);
-		if (pg_vec == NULL)
+		order = get_order(req->tp_block_size);
+		pg_vec = alloc_pg_vec(req, order);
+		if (unlikely(!pg_vec))
 			goto out;
-		memset(pg_vec, 0, req->tp_block_nr*sizeof(char **));
-
-		for (i=0; i<req->tp_block_nr; i++) {
-			struct page *page, *pend;
-			pg_vec[i] = (char *)__get_free_pages(GFP_KERNEL, order);
-			if (!pg_vec[i])
-				goto out_free_pgvec;
-
-			pend = pg_vec_endpage(pg_vec[i], order);
-			for (page = virt_to_page(pg_vec[i]); page <= pend; page++)
-				SetPageReserved(page);
-		}
-		/* Page vector is allocated */
 
 		l = 0;
-		for (i=0; i<req->tp_block_nr; i++) {
+		for (i = 0; i < req->tp_block_nr; i++) {
 			char *ptr = pg_vec[i];
 			struct tpacket_hdr *header;
 			int k;
 
-			for (k=0; k<po->frames_per_block; k++) {
-				
-				header = (struct tpacket_hdr*)ptr;
+			for (k = 0; k < po->frames_per_block; k++) {
+				header = (struct tpacket_hdr *) ptr;
 				header->tp_status = TP_STATUS_KERNEL;
 				ptr += req->tp_frame_size;
 			}
 		}
 		/* Done */
 	} else {
-		if (req->tp_frame_nr)
+		if (unlikely(req->tp_frame_nr))
 			return -EINVAL;
 	}
 
@@ -1701,7 +1707,7 @@
 
 		spin_lock_bh(&sk->sk_receive_queue.lock);
 		pg_vec = XC(po->pg_vec, pg_vec);
-		po->frame_max = req->tp_frame_nr-1;
+		po->frame_max = (req->tp_frame_nr - 1);
 		po->head = 0;
 		po->frame_size = req->tp_frame_size;
 		spin_unlock_bh(&sk->sk_receive_queue.lock);
@@ -1728,7 +1734,6 @@
 
 	release_sock(sk);
 
-out_free_pgvec:
 	if (pg_vec)
 		free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
@@ -1755,17 +1760,19 @@
 	if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE)
 		goto out;
 
-	atomic_inc(&po->mapped);
 	start = vma->vm_start;
-	err = -EAGAIN;
-	for (i=0; i<po->pg_vec_len; i++) {
-		if (remap_pfn_range(vma, start,
-				     __pa(po->pg_vec[i]) >> PAGE_SHIFT,
-				     po->pg_vec_pages*PAGE_SIZE,
-				     vma->vm_page_prot))
-			goto out;
-		start += po->pg_vec_pages*PAGE_SIZE;
+	for (i = 0; i < po->pg_vec_len; i++) {
+		struct page *page = virt_to_page(po->pg_vec[i]);
+		int pg_num;
+
+		for (pg_num = 0; pg_num < po->pg_vec_pages; pg_num++, page++) {
+			err = vm_insert_page(vma, start, page);
+			if (unlikely(err))
+				goto out;
+			start += PAGE_SIZE;
+		}
 	}
+	atomic_inc(&po->mapped);
 	vma->vm_ops = &packet_mmap_ops;
 	err = 0;
 
@@ -1777,7 +1784,7 @@
 
 
 #ifdef CONFIG_SOCK_PACKET
-static struct proto_ops packet_ops_spkt = {
+static const struct proto_ops packet_ops_spkt = {
 	.family =	PF_PACKET,
 	.owner =	THIS_MODULE,
 	.release =	packet_release,
@@ -1799,7 +1806,7 @@
 };
 #endif
 
-static struct proto_ops packet_ops = {
+static const struct proto_ops packet_ops = {
 	.family =	PF_PACKET,
 	.owner =	THIS_MODULE,
 	.release =	packet_release,
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 829fdbc..63090be 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1320,7 +1320,7 @@
 		return 0;
 
 	default:
-		return dev_ioctl(cmd, argp);
+		return -ENOIOCTLCMD;
 	}
 
 	return 0;
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 8aebe8f..2ce1cb2 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -34,7 +34,7 @@
 #include <net/sch_generic.h>
 #include <net/act_api.h>
 
-#if 1 /* control */
+#if 0 /* control */
 #define DPRINTK(format, args...) printk(KERN_DEBUG format, ##args)
 #else
 #define DPRINTK(format, args...)
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 82fb07a..ba52832 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -25,7 +25,7 @@
 
 #include <net/pkt_sched.h>
 
-#define VERSION "1.1"
+#define VERSION "1.2"
 
 /*	Network Emulation Queuing algorithm.
 	====================================
@@ -65,11 +65,12 @@
 	u32 jitter;
 	u32 duplicate;
 	u32 reorder;
+	u32 corrupt;
 
 	struct crndstate {
 		unsigned long last;
 		unsigned long rho;
-	} delay_cor, loss_cor, dup_cor, reorder_cor;
+	} delay_cor, loss_cor, dup_cor, reorder_cor, corrupt_cor;
 
 	struct disttable {
 		u32  size;
@@ -183,6 +184,23 @@
 		q->duplicate = dupsave;
 	}
 
+	/*
+	 * Randomized packet corruption.
+	 * Make copy if needed since we are modifying
+	 * If packet is going to be hardware checksummed, then
+	 * do it now in software before we mangle it.
+	 */
+	if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) {
+		if (!(skb = skb_unshare(skb, GFP_ATOMIC))
+		    || (skb->ip_summed == CHECKSUM_HW
+			&& skb_checksum_help(skb, 0))) {
+			sch->qstats.drops++;
+			return NET_XMIT_DROP;
+		}
+
+		skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8);
+	}
+
 	if (q->gap == 0 		/* not doing reordering */
 	    || q->counter < q->gap 	/* inside last reordering gap */
 	    || q->reorder < get_crandom(&q->reorder_cor)) {
@@ -382,6 +400,20 @@
 	return 0;
 }
 
+static int get_corrupt(struct Qdisc *sch, const struct rtattr *attr)
+{
+	struct netem_sched_data *q = qdisc_priv(sch);
+	const struct tc_netem_corrupt *r = RTA_DATA(attr);
+
+	if (RTA_PAYLOAD(attr) != sizeof(*r))
+		return -EINVAL;
+
+	q->corrupt = r->probability;
+	init_crandom(&q->corrupt_cor, r->correlation);
+	return 0;
+}
+
+/* Parse netlink message to set options */
 static int netem_change(struct Qdisc *sch, struct rtattr *opt)
 {
 	struct netem_sched_data *q = qdisc_priv(sch);
@@ -432,13 +464,19 @@
 			if (ret)
 				return ret;
 		}
+
 		if (tb[TCA_NETEM_REORDER-1]) {
 			ret = get_reorder(sch, tb[TCA_NETEM_REORDER-1]);
 			if (ret)
 				return ret;
 		}
-	}
 
+		if (tb[TCA_NETEM_CORRUPT-1]) {
+			ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT-1]);
+			if (ret)
+				return ret;
+		}
+	}
 
 	return 0;
 }
@@ -564,6 +602,7 @@
 	struct tc_netem_qopt qopt;
 	struct tc_netem_corr cor;
 	struct tc_netem_reorder reorder;
+	struct tc_netem_corrupt corrupt;
 
 	qopt.latency = q->latency;
 	qopt.jitter = q->jitter;
@@ -582,6 +621,10 @@
 	reorder.correlation = q->reorder_cor.rho;
 	RTA_PUT(skb, TCA_NETEM_REORDER, sizeof(reorder), &reorder);
 
+	corrupt.probability = q->corrupt;
+	corrupt.correlation = q->corrupt_cor.rho;
+	RTA_PUT(skb, TCA_NETEM_CORRUPT, sizeof(corrupt), &corrupt);
+
 	rta->rta_len = skb->tail - b;
 
 	return skb->len;
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 6cf0342..c4a2a8c 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -22,6 +22,7 @@
 #include <linux/in.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
+#include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/inet.h>
 #include <linux/netdevice.h>
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index dec68a6..9d05e13 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -110,7 +110,6 @@
 	asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000;
 	asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000)
 					* 1000;
-	asoc->pmtu = 0;
 	asoc->frag_point = 0;
 
 	/* Set the association max_retrans and RTO values from the
@@ -123,6 +122,25 @@
 
 	asoc->overall_error_count = 0;
 
+	/* Initialize the association's heartbeat interval based on the
+	 * sock configured value.
+	 */
+	asoc->hbinterval = msecs_to_jiffies(sp->hbinterval);
+
+	/* Initialize path max retrans value. */
+	asoc->pathmaxrxt = sp->pathmaxrxt;
+
+	/* Initialize default path MTU. */
+	asoc->pathmtu = sp->pathmtu;
+
+	/* Set association default SACK delay */
+	asoc->sackdelay = msecs_to_jiffies(sp->sackdelay);
+
+	/* Set the association default flags controlling
+	 * Heartbeat, SACK delay, and Path MTU Discovery.
+	 */
+	asoc->param_flags = sp->param_flags;
+
 	/* Initialize the maximum mumber of new data packets that can be sent
 	 * in a burst.
 	 */
@@ -144,8 +162,7 @@
 		= 5 * asoc->rto_max;
 
 	asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
-	asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
-		SCTP_DEFAULT_TIMEOUT_SACK;
+	asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
 	asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
 		sp->autoclose * HZ;
 	
@@ -540,23 +557,46 @@
 
 	sctp_transport_set_owner(peer, asoc);
 
+	/* Initialize the peer's heartbeat interval based on the
+	 * association configured value.
+	 */
+	peer->hbinterval = asoc->hbinterval;
+
+	/* Set the path max_retrans.  */
+	peer->pathmaxrxt = asoc->pathmaxrxt;
+
+	/* Initialize the peer's SACK delay timeout based on the
+	 * association configured value.
+	 */
+	peer->sackdelay = asoc->sackdelay;
+
+	/* Enable/disable heartbeat, SACK delay, and path MTU discovery
+	 * based on association setting.
+	 */
+	peer->param_flags = asoc->param_flags;
+
 	/* Initialize the pmtu of the transport. */
-	sctp_transport_pmtu(peer);
+	if (peer->param_flags & SPP_PMTUD_ENABLE)
+		sctp_transport_pmtu(peer);
+	else if (asoc->pathmtu)
+		peer->pathmtu = asoc->pathmtu;
+	else
+		peer->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 
 	/* If this is the first transport addr on this association,
 	 * initialize the association PMTU to the peer's PMTU.
 	 * If not and the current association PMTU is higher than the new
 	 * peer's PMTU, reset the association PMTU to the new peer's PMTU.
 	 */
-	if (asoc->pmtu)
-		asoc->pmtu = min_t(int, peer->pmtu, asoc->pmtu);
+	if (asoc->pathmtu)
+		asoc->pathmtu = min_t(int, peer->pathmtu, asoc->pathmtu);
 	else
-		asoc->pmtu = peer->pmtu;
+		asoc->pathmtu = peer->pathmtu;
 
 	SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to "
-			  "%d\n", asoc, asoc->pmtu);
+			  "%d\n", asoc, asoc->pathmtu);
 
-	asoc->frag_point = sctp_frag_point(sp, asoc->pmtu);
+	asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);
 
 	/* The asoc->peer.port might not be meaningful yet, but
 	 * initialize the packet structure anyway.
@@ -574,7 +614,7 @@
 	 *   (for example, implementations MAY use the size of the
 	 *   receiver advertised window).
 	 */
-	peer->cwnd = min(4*asoc->pmtu, max_t(__u32, 2*asoc->pmtu, 4380));
+	peer->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
 
 	/* At this point, we may not have the receiver's advertised window,
 	 * so initialize ssthresh to the default value and it will be set
@@ -585,17 +625,6 @@
 	peer->partial_bytes_acked = 0;
 	peer->flight_size = 0;
 
-	/* By default, enable heartbeat for peer address. */
-	peer->hb_allowed = 1;
-
-	/* Initialize the peer's heartbeat interval based on the
-	 * sock configured value.
-	 */
-	peer->hb_interval = msecs_to_jiffies(sp->paddrparam.spp_hbinterval);
-
-	/* Set the path max_retrans.  */
-	peer->max_retrans = sp->paddrparam.spp_pathmaxrxt;
-
 	/* Set the transport's RTO.initial value */
 	peer->rto = asoc->rto_initial;
 
@@ -1155,18 +1184,18 @@
 	/* Get the lowest pmtu of all the transports. */
 	list_for_each(pos, &asoc->peer.transport_addr_list) {
 		t = list_entry(pos, struct sctp_transport, transports);
-		if (!pmtu || (t->pmtu < pmtu))
-			pmtu = t->pmtu;
+		if (!pmtu || (t->pathmtu < pmtu))
+			pmtu = t->pathmtu;
 	}
 
 	if (pmtu) {
 		struct sctp_sock *sp = sctp_sk(asoc->base.sk);
-		asoc->pmtu = pmtu;
+		asoc->pathmtu = pmtu;
 		asoc->frag_point = sctp_frag_point(sp, pmtu);
 	}
 
 	SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n",
-			  __FUNCTION__, asoc, asoc->pmtu, asoc->frag_point);
+			  __FUNCTION__, asoc, asoc->pathmtu, asoc->frag_point);
 }
 
 /* Should we send a SACK to update our peer? */
@@ -1179,7 +1208,7 @@
 	case SCTP_STATE_SHUTDOWN_SENT:
 		if ((asoc->rwnd > asoc->a_rwnd) &&
 		    ((asoc->rwnd - asoc->a_rwnd) >=
-		     min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pmtu)))
+		     min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pathmtu)))
 			return 1;
 		break;
 	default:
diff --git a/net/sctp/input.c b/net/sctp/input.c
index b24ff2c..4aa6fc6 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -225,6 +225,7 @@
 
 	if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb, family))
 		goto discard_release;
+	nf_reset(skb);
 
 	ret = sk_filter(sk, skb, 1);
 	if (ret)
@@ -305,18 +306,36 @@
 void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
 			   struct sctp_transport *t, __u32 pmtu)
 {
-	if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
-		printk(KERN_WARNING "%s: Reported pmtu %d too low, "
-		       "using default minimum of %d\n", __FUNCTION__, pmtu,
-		       SCTP_DEFAULT_MINSEGMENT);
-		pmtu = SCTP_DEFAULT_MINSEGMENT;
+	if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu))
+		return;
+
+	if (t->param_flags & SPP_PMTUD_ENABLE) {
+		if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
+			printk(KERN_WARNING "%s: Reported pmtu %d too low, "
+			       "using default minimum of %d\n",
+			       __FUNCTION__, pmtu,
+			       SCTP_DEFAULT_MINSEGMENT);
+			/* Use default minimum segment size and disable
+			 * pmtu discovery on this transport.
+			 */
+			t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
+			t->param_flags = (t->param_flags & ~SPP_HB) |
+				SPP_PMTUD_DISABLE;
+		} else {
+			t->pathmtu = pmtu;
+		}
+
+		/* Update association pmtu. */
+		sctp_assoc_sync_pmtu(asoc);
 	}
 
-	if (!sock_owned_by_user(sk) && t && (t->pmtu != pmtu)) {
-		t->pmtu = pmtu;
-		sctp_assoc_sync_pmtu(asoc);
-		sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
-	}
+	/* Retransmit with the new pmtu setting.
+	 * Normally, if PMTU discovery is disabled, an ICMP Fragmentation
+	 * Needed will never be sent, but if a message was sent before
+	 * PMTU discovery was disabled that was larger than the PMTU, it
+	 * would not be fragmented, so it must be re-transmitted fragmented.	 
+	 */
+	sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
 }
 
 /*
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index fa3be2b..04c7fab 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -866,7 +866,7 @@
 	return 2;
 }
 
-static struct proto_ops inet6_seqpacket_ops = {
+static const struct proto_ops inet6_seqpacket_ops = {
 	.family     = PF_INET6,
 	.owner      = THIS_MODULE,
 	.release    = inet6_release,
@@ -905,7 +905,7 @@
 	.flags         = SCTP_PROTOSW_FLAG,
 };
 
-static int sctp6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
+static int sctp6_rcv(struct sk_buff **pskb)
 {
 	return sctp_rcv(*pskb) ? -1 : 0;
 }
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 9313716..a40991e 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -234,8 +234,8 @@
 		goto finish;
 
 	pmtu  = ((packet->transport->asoc) ?
-		 (packet->transport->asoc->pmtu) :
-		 (packet->transport->pmtu));
+		 (packet->transport->asoc->pathmtu) :
+		 (packet->transport->pathmtu));
 
 	too_big = (psize + chunk_len > pmtu);
 
@@ -482,7 +482,9 @@
 	if (!dst || (dst->obsolete > 1)) {
 		dst_release(dst);
 		sctp_transport_route(tp, NULL, sctp_sk(sk));
-		sctp_assoc_sync_pmtu(asoc);
+		if (asoc->param_flags & SPP_PMTUD_ENABLE) {
+			sctp_assoc_sync_pmtu(asoc);
+		}
 	}
 
 	nskb->dst = dst_clone(tp->dst);
@@ -492,7 +494,10 @@
 	SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
 			  nskb->len);
 
-	(*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
+	if (tp->param_flags & SPP_PMTUD_ENABLE)
+		(*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
+	else
+		(*tp->af_specific->sctp_xmit)(nskb, tp, 1);
 
 out:
 	packet->size = packet->overhead;
@@ -577,7 +582,7 @@
 	 * 	if ((flightsize + Max.Burst * MTU) < cwnd)
 	 *		cwnd = flightsize + Max.Burst * MTU
 	 */
-	max_burst_bytes = asoc->max_burst * asoc->pmtu;
+	max_burst_bytes = asoc->max_burst * asoc->pathmtu;
 	if ((transport->flight_size + max_burst_bytes) < transport->cwnd) {
 		transport->cwnd = transport->flight_size + max_burst_bytes;
 		SCTP_DEBUG_PRINTK("%s: cwnd limited by max_burst: "
@@ -622,7 +627,7 @@
 		 * data will fit or delay in hopes of bundling a full
 		 * sized packet.
 		 */
-		if (len < asoc->pmtu - packet->overhead) {
+		if (len < asoc->pathmtu - packet->overhead) {
 			retval = SCTP_XMIT_NAGLE_DELAY;
 			goto finish;
 		}
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index f775d78..de693b4 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -54,6 +54,7 @@
 #include <net/protocol.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
+#include <net/route.h>
 #include <net/sctp/sctp.h>
 #include <net/addrconf.h>
 #include <net/inet_common.h>
@@ -829,7 +830,7 @@
 };
 
 /* Socket operations.  */
-static struct proto_ops inet_seqpacket_ops = {
+static const struct proto_ops inet_seqpacket_ops = {
 	.family      = PF_INET,
 	.owner       = THIS_MODULE,
 	.release     = inet_release,       /* Needs to be wrapped... */
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 8239471..2d7d8a5 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -157,9 +157,12 @@
 {
 	__u32 ctsn, max_tsn_seen;
 	struct sctp_chunk *sack;
+	struct sctp_transport *trans = asoc->peer.last_data_from;
 	int error = 0;
 
-	if (force)
+	if (force || 
+	    (!trans && (asoc->param_flags & SPP_SACKDELAY_DISABLE)) ||
+	    (trans && (trans->param_flags & SPP_SACKDELAY_DISABLE)))
 		asoc->peer.sack_needed = 1;
 
 	ctsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map);
@@ -189,7 +192,22 @@
 	if (!asoc->peer.sack_needed) {
 		/* We will need a SACK for the next packet.  */
 		asoc->peer.sack_needed = 1;
-		goto out;
+
+		/* Set the SACK delay timeout based on the
+		 * SACK delay for the last transport
+		 * data was received from, or the default
+		 * for the association.
+		 */
+		if (trans)
+			asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+				trans->sackdelay;
+		else
+			asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = 
+				asoc->sackdelay;
+
+		/* Restart the SACK timer. */
+		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
+				SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
 	} else {
 		if (asoc->a_rwnd > asoc->rwnd)
 			asoc->a_rwnd = asoc->rwnd;
@@ -205,7 +223,7 @@
 		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
 				SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
 	}
-out:
+
 	return error;
 nomem:
 	error = -ENOMEM;
@@ -415,7 +433,7 @@
 	asoc->overall_error_count++;
 
 	if (transport->state != SCTP_INACTIVE &&
-	    (transport->error_count++ >= transport->max_retrans)) {
+	    (transport->error_count++ >= transport->pathmaxrxt)) {
 		SCTP_DEBUG_PRINTK_IPADDR("transport_strike:association %p",
 					 " transport IP: port:%d failed.\n",
 					 asoc,
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 475bfb4..557a7d9 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -900,7 +900,7 @@
 	 * HEARTBEAT is sent (see Section 8.3).
 	 */
 
-	if (transport->hb_allowed) {
+	if (transport->param_flags & SPP_HB_ENABLE) {
 		if (SCTP_DISPOSITION_NOMEM ==
 				sctp_sf_heartbeat(ep, asoc, type, arg,
 						  commands))
@@ -1051,7 +1051,7 @@
 		return SCTP_DISPOSITION_DISCARD;
 	}
 
-	max_interval = link->hb_interval + link->rto;
+	max_interval = link->hbinterval + link->rto;
 
 	/* Check if the timestamp looks valid.  */
 	if (time_after(hbinfo->sent_at, jiffies) ||
@@ -2691,14 +2691,9 @@
 	 * document allow. However, an SCTP transmitter MUST NOT be
 	 * more aggressive than the following algorithms allow.
 	 */
-	if (chunk->end_of_packet) {
+	if (chunk->end_of_packet)
 		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
 
-		/* Start the SACK timer.  */
-		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
-				SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
-	}
-
 	return SCTP_DISPOSITION_CONSUME;
 
 discard_force:
@@ -2721,13 +2716,9 @@
 	return SCTP_DISPOSITION_DISCARD;
 
 discard_noforce:
-	if (chunk->end_of_packet) {
+	if (chunk->end_of_packet)
 		sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
 
-		/* Start the SACK timer.  */
-		sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
-				SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
-	}
 	return SCTP_DISPOSITION_DISCARD;
 consume:
 	return SCTP_DISPOSITION_CONSUME;
@@ -3442,9 +3433,6 @@
 	 * send another. 
 	 */
 	sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, SCTP_NOFORCE());
-	/* Start the SACK timer.  */
-	sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
-			SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
 
 	return SCTP_DISPOSITION_CONSUME;
 
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index abab81f..fc04d18 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -156,10 +156,6 @@
 				sizeof(struct sk_buff) +
 				sizeof(struct sctp_chunk);
 
-	sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk) +
-				sizeof(struct sk_buff) +
-				sizeof(struct sctp_chunk);
-
 	atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
 }
 
@@ -1945,107 +1941,379 @@
  * address's parameters:
  *
  *  struct sctp_paddrparams {
- *      sctp_assoc_t            spp_assoc_id;
- *      struct sockaddr_storage spp_address;
- *      uint32_t                spp_hbinterval;
- *      uint16_t                spp_pathmaxrxt;
- *  };
+ *     sctp_assoc_t            spp_assoc_id;
+ *     struct sockaddr_storage spp_address;
+ *     uint32_t                spp_hbinterval;
+ *     uint16_t                spp_pathmaxrxt;
+ *     uint32_t                spp_pathmtu;
+ *     uint32_t                spp_sackdelay;
+ *     uint32_t                spp_flags;
+ * };
  *
- *   spp_assoc_id    - (UDP style socket) This is filled in the application,
- *                     and identifies the association for this query.
+ *   spp_assoc_id    - (one-to-many style socket) This is filled in the
+ *                     application, and identifies the association for
+ *                     this query.
  *   spp_address     - This specifies which address is of interest.
  *   spp_hbinterval  - This contains the value of the heartbeat interval,
- *                     in milliseconds.  A value of 0, when modifying the
- *                     parameter, specifies that the heartbeat on this
- *                     address should be disabled. A value of UINT32_MAX
- *                     (4294967295), when modifying the parameter,
- *                     specifies that a heartbeat should be sent
- *                     immediately to the peer address, and the current
- *                     interval should remain unchanged.
+ *                     in milliseconds.  If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
  *   spp_pathmaxrxt  - This contains the maximum number of
  *                     retransmissions before this address shall be
- *                     considered unreachable.
+ *                     considered unreachable. If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
+ *   spp_pathmtu     - When Path MTU discovery is disabled the value
+ *                     specified here will be the "fixed" path mtu.
+ *                     Note that if the spp_address field is empty
+ *                     then all associations on this address will
+ *                     have this fixed path mtu set upon them.
+ *
+ *   spp_sackdelay   - When delayed sack is enabled, this value specifies
+ *                     the number of milliseconds that sacks will be delayed
+ *                     for. This value will apply to all addresses of an
+ *                     association if the spp_address field is empty. Note
+ *                     also, that if delayed sack is enabled and this
+ *                     value is set to 0, no change is made to the last
+ *                     recorded delayed sack timer value.
+ *
+ *   spp_flags       - These flags are used to control various features
+ *                     on an association. The flag field may contain
+ *                     zero or more of the following options.
+ *
+ *                     SPP_HB_ENABLE  - Enable heartbeats on the
+ *                     specified address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     have heartbeats enabled upon them.
+ *
+ *                     SPP_HB_DISABLE - Disable heartbeats on the
+ *                     speicifed address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     will have their heartbeats disabled. Note also
+ *                     that SPP_HB_ENABLE and SPP_HB_DISABLE are
+ *                     mutually exclusive, only one of these two should
+ *                     be specified. Enabling both fields will have
+ *                     undetermined results.
+ *
+ *                     SPP_HB_DEMAND - Request a user initiated heartbeat
+ *                     to be made immediately.
+ *
+ *                     SPP_PMTUD_ENABLE - This field will enable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected.
+ *
+ *                     SPP_PMTUD_DISABLE - This field will disable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected. Not also that
+ *                     SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually
+ *                     exclusive. Enabling both will have undetermined
+ *                     results.
+ *
+ *                     SPP_SACKDELAY_ENABLE - Setting this flag turns
+ *                     on delayed sack. The time specified in spp_sackdelay
+ *                     is used to specify the sack delay for this address. Note
+ *                     that if spp_address is empty then all addresses will
+ *                     enable delayed sack and take on the sack delay
+ *                     value specified in spp_sackdelay.
+ *                     SPP_SACKDELAY_DISABLE - Setting this flag turns
+ *                     off delayed sack. If the spp_address field is blank then
+ *                     delayed sack is disabled for the entire association. Note
+ *                     also that this field is mutually exclusive to
+ *                     SPP_SACKDELAY_ENABLE, setting both will have undefined
+ *                     results.
  */
-static int sctp_setsockopt_peer_addr_params(struct sock *sk,
-					    char __user *optval, int optlen)
+int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
+				struct sctp_transport   *trans,
+				struct sctp_association *asoc,
+				struct sctp_sock        *sp,
+				int                      hb_change,
+				int                      pmtud_change,
+				int                      sackdelay_change)
 {
-	struct sctp_paddrparams params;
-	struct sctp_transport *trans;
 	int error;
 
-	if (optlen != sizeof(struct sctp_paddrparams))
-		return -EINVAL;
-	if (copy_from_user(&params, optval, optlen))
-		return -EFAULT;
-
-	/*
-	 * API 7. Socket Options (setting the default value for the endpoint)
-	 * All options that support specific settings on an association by
-	 * filling in either an association id variable or a sockaddr_storage
-	 * SHOULD also support setting of the same value for the entire endpoint
-	 * (i.e. future associations). To accomplish this the following logic is
-	 * used when setting one of these options:
-
-	 * c) If neither the sockaddr_storage or association identification is
-	 *    set i.e. the sockaddr_storage is set to all 0's (INADDR_ANY) and
-	 *    the association identification is 0, the settings are a default
-	 *    and to be applied to the endpoint (all future associations).
-	 */
-
-	/* update default value for endpoint (all future associations) */
-	if (!params.spp_assoc_id && 
-	    sctp_is_any(( union sctp_addr *)&params.spp_address)) {
-		/* Manual heartbeat on an endpoint is invalid. */
-		if (0xffffffff == params.spp_hbinterval)
-			return -EINVAL;
-		else if (params.spp_hbinterval)
-			sctp_sk(sk)->paddrparam.spp_hbinterval =
-						params.spp_hbinterval;
-		if (params.spp_pathmaxrxt)
-			sctp_sk(sk)->paddrparam.spp_pathmaxrxt =
-						params.spp_pathmaxrxt;
-		return 0;
-	}
-
-	trans = sctp_addr_id2transport(sk, &params.spp_address,
-				       params.spp_assoc_id);
-	if (!trans)
-		return -EINVAL;
-
-	/* Applications can enable or disable heartbeats for any peer address
-	 * of an association, modify an address's heartbeat interval, force a
-	 * heartbeat to be sent immediately, and adjust the address's maximum
-	 * number of retransmissions sent before an address is considered
-	 * unreachable.
-	 *
-	 * The value of the heartbeat interval, in milliseconds. A value of
-	 * UINT32_MAX (4294967295), when modifying the parameter, specifies
-	 * that a heartbeat should be sent immediately to the peer address,
-	 * and the current interval should remain unchanged.
-	 */
-	if (0xffffffff == params.spp_hbinterval) {
+	if (params->spp_flags & SPP_HB_DEMAND && trans) {
 		error = sctp_primitive_REQUESTHEARTBEAT (trans->asoc, trans);
 		if (error)
 			return error;
-	} else {
-	/* The value of the heartbeat interval, in milliseconds. A value of 0,
-	 * when modifying the parameter, specifies that the heartbeat on this
-	 * address should be disabled.
-	 */
-		if (params.spp_hbinterval) {
-			trans->hb_allowed = 1;
-			trans->hb_interval = 
-				msecs_to_jiffies(params.spp_hbinterval);
-		} else
-			trans->hb_allowed = 0;
 	}
 
-	/* spp_pathmaxrxt contains the maximum number of retransmissions
-	 * before this address shall be considered unreachable.
-	 */
-	if (params.spp_pathmaxrxt)
-		trans->max_retrans = params.spp_pathmaxrxt;
+	if (params->spp_hbinterval) {
+		if (trans) {
+			trans->hbinterval = msecs_to_jiffies(params->spp_hbinterval);
+		} else if (asoc) {
+			asoc->hbinterval = msecs_to_jiffies(params->spp_hbinterval);
+		} else {
+			sp->hbinterval = params->spp_hbinterval;
+		}
+	}
 
+	if (hb_change) {
+		if (trans) {
+			trans->param_flags =
+				(trans->param_flags & ~SPP_HB) | hb_change;
+		} else if (asoc) {
+			asoc->param_flags =
+				(asoc->param_flags & ~SPP_HB) | hb_change;
+		} else {
+			sp->param_flags =
+				(sp->param_flags & ~SPP_HB) | hb_change;
+		}
+	}
+
+	if (params->spp_pathmtu) {
+		if (trans) {
+			trans->pathmtu = params->spp_pathmtu;
+			sctp_assoc_sync_pmtu(asoc);
+		} else if (asoc) {
+			asoc->pathmtu = params->spp_pathmtu;
+			sctp_frag_point(sp, params->spp_pathmtu);
+		} else {
+			sp->pathmtu = params->spp_pathmtu;
+		}
+	}
+
+	if (pmtud_change) {
+		if (trans) {
+			int update = (trans->param_flags & SPP_PMTUD_DISABLE) &&
+				(params->spp_flags & SPP_PMTUD_ENABLE);
+			trans->param_flags =
+				(trans->param_flags & ~SPP_PMTUD) | pmtud_change;
+			if (update) {
+				sctp_transport_pmtu(trans);
+				sctp_assoc_sync_pmtu(asoc);
+			}
+		} else if (asoc) {
+			asoc->param_flags =
+				(asoc->param_flags & ~SPP_PMTUD) | pmtud_change;
+		} else {
+			sp->param_flags =
+				(sp->param_flags & ~SPP_PMTUD) | pmtud_change;
+		}
+	}
+
+	if (params->spp_sackdelay) {
+		if (trans) {
+			trans->sackdelay =
+				msecs_to_jiffies(params->spp_sackdelay);
+		} else if (asoc) {
+			asoc->sackdelay =
+				msecs_to_jiffies(params->spp_sackdelay);
+		} else {
+			sp->sackdelay = params->spp_sackdelay;
+		}
+	}
+
+	if (sackdelay_change) {
+		if (trans) {
+			trans->param_flags =
+				(trans->param_flags & ~SPP_SACKDELAY) |
+				sackdelay_change;
+		} else if (asoc) {
+			asoc->param_flags =
+				(asoc->param_flags & ~SPP_SACKDELAY) |
+				sackdelay_change;
+		} else {
+			sp->param_flags =
+				(sp->param_flags & ~SPP_SACKDELAY) |
+				sackdelay_change;
+		}
+	}
+
+	if (params->spp_pathmaxrxt) {
+		if (trans) {
+			trans->pathmaxrxt = params->spp_pathmaxrxt;
+		} else if (asoc) {
+			asoc->pathmaxrxt = params->spp_pathmaxrxt;
+		} else {
+			sp->pathmaxrxt = params->spp_pathmaxrxt;
+		}
+	}
+
+	return 0;
+}
+
+static int sctp_setsockopt_peer_addr_params(struct sock *sk,
+					    char __user *optval, int optlen)
+{
+	struct sctp_paddrparams  params;
+	struct sctp_transport   *trans = NULL;
+	struct sctp_association *asoc = NULL;
+	struct sctp_sock        *sp = sctp_sk(sk);
+	int error;
+	int hb_change, pmtud_change, sackdelay_change;
+
+	if (optlen != sizeof(struct sctp_paddrparams))
+		return - EINVAL;
+
+	if (copy_from_user(&params, optval, optlen))
+		return -EFAULT;
+
+	/* Validate flags and value parameters. */
+	hb_change        = params.spp_flags & SPP_HB;
+	pmtud_change     = params.spp_flags & SPP_PMTUD;
+	sackdelay_change = params.spp_flags & SPP_SACKDELAY;
+
+	if (hb_change        == SPP_HB ||
+	    pmtud_change     == SPP_PMTUD ||
+	    sackdelay_change == SPP_SACKDELAY ||
+	    params.spp_sackdelay > 500 ||
+	    (params.spp_pathmtu
+	    && params.spp_pathmtu < SCTP_DEFAULT_MINSEGMENT))
+		return -EINVAL;
+
+	/* If an address other than INADDR_ANY is specified, and
+	 * no transport is found, then the request is invalid.
+	 */
+	if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) {
+		trans = sctp_addr_id2transport(sk, &params.spp_address,
+					       params.spp_assoc_id);
+		if (!trans)
+			return -EINVAL;
+	}
+
+	/* Get association, if assoc_id != 0 and the socket is a one
+	 * to many style socket, and an association was not found, then
+	 * the id was invalid.
+	 */
+	asoc = sctp_id2assoc(sk, params.spp_assoc_id);
+	if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP))
+		return -EINVAL;
+
+	/* Heartbeat demand can only be sent on a transport or
+	 * association, but not a socket.
+	 */
+	if (params.spp_flags & SPP_HB_DEMAND && !trans && !asoc)
+		return -EINVAL;
+
+	/* Process parameters. */
+	error = sctp_apply_peer_addr_params(&params, trans, asoc, sp,
+					    hb_change, pmtud_change,
+					    sackdelay_change);
+
+	if (error)
+		return error;
+
+	/* If changes are for association, also apply parameters to each
+	 * transport.
+	 */
+	if (!trans && asoc) {
+		struct list_head *pos;
+
+		list_for_each(pos, &asoc->peer.transport_addr_list) {
+			trans = list_entry(pos, struct sctp_transport,
+					   transports);
+			sctp_apply_peer_addr_params(&params, trans, asoc, sp,
+						    hb_change, pmtud_change,
+						    sackdelay_change);
+		}
+	}
+
+	return 0;
+}
+
+/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
+ *
+ *   This options will get or set the delayed ack timer.  The time is set
+ *   in milliseconds.  If the assoc_id is 0, then this sets or gets the
+ *   endpoints default delayed ack timer value.  If the assoc_id field is
+ *   non-zero, then the set or get effects the specified association.
+ *
+ *   struct sctp_assoc_value {
+ *       sctp_assoc_t            assoc_id;
+ *       uint32_t                assoc_value;
+ *   };
+ *
+ *     assoc_id    - This parameter, indicates which association the
+ *                   user is preforming an action upon. Note that if
+ *                   this field's value is zero then the endpoints
+ *                   default value is changed (effecting future
+ *                   associations only).
+ *
+ *     assoc_value - This parameter contains the number of milliseconds
+ *                   that the user is requesting the delayed ACK timer
+ *                   be set to. Note that this value is defined in
+ *                   the standard to be between 200 and 500 milliseconds.
+ *
+ *                   Note: a value of zero will leave the value alone,
+ *                   but disable SACK delay. A non-zero value will also
+ *                   enable SACK delay.
+ */
+
+static int sctp_setsockopt_delayed_ack_time(struct sock *sk,
+					    char __user *optval, int optlen)
+{
+	struct sctp_assoc_value  params;
+	struct sctp_transport   *trans = NULL;
+	struct sctp_association *asoc = NULL;
+	struct sctp_sock        *sp = sctp_sk(sk);
+
+	if (optlen != sizeof(struct sctp_assoc_value))
+		return - EINVAL;
+
+	if (copy_from_user(&params, optval, optlen))
+		return -EFAULT;
+
+	/* Validate value parameter. */
+	if (params.assoc_value > 500)
+		return -EINVAL;
+
+	/* Get association, if assoc_id != 0 and the socket is a one
+	 * to many style socket, and an association was not found, then
+	 * the id was invalid.
+ 	 */
+	asoc = sctp_id2assoc(sk, params.assoc_id);
+	if (!asoc && params.assoc_id && sctp_style(sk, UDP))
+		return -EINVAL;
+
+	if (params.assoc_value) {
+		if (asoc) {
+			asoc->sackdelay =
+				msecs_to_jiffies(params.assoc_value);
+			asoc->param_flags = 
+				(asoc->param_flags & ~SPP_SACKDELAY) |
+				SPP_SACKDELAY_ENABLE;
+		} else {
+			sp->sackdelay = params.assoc_value;
+			sp->param_flags = 
+				(sp->param_flags & ~SPP_SACKDELAY) |
+				SPP_SACKDELAY_ENABLE;
+		}
+	} else {
+		if (asoc) {
+			asoc->param_flags = 
+				(asoc->param_flags & ~SPP_SACKDELAY) |
+				SPP_SACKDELAY_DISABLE;
+		} else {
+			sp->param_flags = 
+				(sp->param_flags & ~SPP_SACKDELAY) |
+				SPP_SACKDELAY_DISABLE;
+		}
+	}
+
+	/* If change is for association, also apply to each transport. */
+	if (asoc) {
+		struct list_head *pos;
+
+		list_for_each(pos, &asoc->peer.transport_addr_list) {
+			trans = list_entry(pos, struct sctp_transport,
+					   transports);
+			if (params.assoc_value) {
+				trans->sackdelay =
+					msecs_to_jiffies(params.assoc_value);
+				trans->param_flags = 
+					(trans->param_flags & ~SPP_SACKDELAY) |
+					SPP_SACKDELAY_ENABLE;
+			} else {
+				trans->param_flags = 
+					(trans->param_flags & ~SPP_SACKDELAY) |
+					SPP_SACKDELAY_DISABLE;
+			}
+		}
+	}
+ 
 	return 0;
 }
 
@@ -2338,7 +2606,7 @@
 	/* Update the frag_point of the existing associations. */
 	list_for_each(pos, &(sp->ep->asocs)) {
 		asoc = list_entry(pos, struct sctp_association, asocs);
-		asoc->frag_point = sctp_frag_point(sp, asoc->pmtu); 
+		asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); 
 	}
 
 	return 0;
@@ -2495,6 +2763,10 @@
 		retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen);
 		break;
 
+	case SCTP_DELAYED_ACK_TIME:
+		retval = sctp_setsockopt_delayed_ack_time(sk, optval, optlen);
+		break;
+
 	case SCTP_INITMSG:
 		retval = sctp_setsockopt_initmsg(sk, optval, optlen);
 		break;
@@ -2719,8 +2991,13 @@
 	/* Default Peer Address Parameters.  These defaults can
 	 * be modified via SCTP_PEER_ADDR_PARAMS
 	 */
-	sp->paddrparam.spp_hbinterval = jiffies_to_msecs(sctp_hb_interval);
-	sp->paddrparam.spp_pathmaxrxt = sctp_max_retrans_path;
+	sp->hbinterval  = jiffies_to_msecs(sctp_hb_interval);
+	sp->pathmaxrxt  = sctp_max_retrans_path;
+	sp->pathmtu     = 0; // allow default discovery
+	sp->sackdelay   = sctp_sack_timeout;
+	sp->param_flags = SPP_HB_ENABLE |
+	                  SPP_PMTUD_ENABLE |
+	                  SPP_SACKDELAY_ENABLE;
 
 	/* If enabled no SCTP message fragmentation will be performed.
 	 * Configure through SCTP_DISABLE_FRAGMENTS socket option.
@@ -2869,7 +3146,7 @@
 	status.sstat_primary.spinfo_cwnd = transport->cwnd;
 	status.sstat_primary.spinfo_srtt = transport->srtt;
 	status.sstat_primary.spinfo_rto = jiffies_to_msecs(transport->rto);
-	status.sstat_primary.spinfo_mtu = transport->pmtu;
+	status.sstat_primary.spinfo_mtu = transport->pathmtu;
 
 	if (status.sstat_primary.spinfo_state == SCTP_UNKNOWN)
 		status.sstat_primary.spinfo_state = SCTP_ACTIVE;
@@ -2928,7 +3205,7 @@
 	pinfo.spinfo_cwnd = transport->cwnd;
 	pinfo.spinfo_srtt = transport->srtt;
 	pinfo.spinfo_rto = jiffies_to_msecs(transport->rto);
-	pinfo.spinfo_mtu = transport->pmtu;
+	pinfo.spinfo_mtu = transport->pathmtu;
 
 	if (pinfo.spinfo_state == SCTP_UNKNOWN)
 		pinfo.spinfo_state = SCTP_ACTIVE;
@@ -3090,69 +3367,227 @@
  * address's parameters:
  *
  *  struct sctp_paddrparams {
- *      sctp_assoc_t            spp_assoc_id;
- *      struct sockaddr_storage spp_address;
- *      uint32_t                spp_hbinterval;
- *      uint16_t                spp_pathmaxrxt;
- *  };
+ *     sctp_assoc_t            spp_assoc_id;
+ *     struct sockaddr_storage spp_address;
+ *     uint32_t                spp_hbinterval;
+ *     uint16_t                spp_pathmaxrxt;
+ *     uint32_t                spp_pathmtu;
+ *     uint32_t                spp_sackdelay;
+ *     uint32_t                spp_flags;
+ * };
  *
- *   spp_assoc_id    - (UDP style socket) This is filled in the application,
- *                     and identifies the association for this query.
+ *   spp_assoc_id    - (one-to-many style socket) This is filled in the
+ *                     application, and identifies the association for
+ *                     this query.
  *   spp_address     - This specifies which address is of interest.
  *   spp_hbinterval  - This contains the value of the heartbeat interval,
- *                     in milliseconds.  A value of 0, when modifying the
- *                     parameter, specifies that the heartbeat on this
- *                     address should be disabled. A value of UINT32_MAX
- *                     (4294967295), when modifying the parameter,
- *                     specifies that a heartbeat should be sent
- *                     immediately to the peer address, and the current
- *                     interval should remain unchanged.
+ *                     in milliseconds.  If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
  *   spp_pathmaxrxt  - This contains the maximum number of
  *                     retransmissions before this address shall be
- *                     considered unreachable.
+ *                     considered unreachable. If a  value of zero
+ *                     is present in this field then no changes are to
+ *                     be made to this parameter.
+ *   spp_pathmtu     - When Path MTU discovery is disabled the value
+ *                     specified here will be the "fixed" path mtu.
+ *                     Note that if the spp_address field is empty
+ *                     then all associations on this address will
+ *                     have this fixed path mtu set upon them.
+ *
+ *   spp_sackdelay   - When delayed sack is enabled, this value specifies
+ *                     the number of milliseconds that sacks will be delayed
+ *                     for. This value will apply to all addresses of an
+ *                     association if the spp_address field is empty. Note
+ *                     also, that if delayed sack is enabled and this
+ *                     value is set to 0, no change is made to the last
+ *                     recorded delayed sack timer value.
+ *
+ *   spp_flags       - These flags are used to control various features
+ *                     on an association. The flag field may contain
+ *                     zero or more of the following options.
+ *
+ *                     SPP_HB_ENABLE  - Enable heartbeats on the
+ *                     specified address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     have heartbeats enabled upon them.
+ *
+ *                     SPP_HB_DISABLE - Disable heartbeats on the
+ *                     speicifed address. Note that if the address
+ *                     field is empty all addresses for the association
+ *                     will have their heartbeats disabled. Note also
+ *                     that SPP_HB_ENABLE and SPP_HB_DISABLE are
+ *                     mutually exclusive, only one of these two should
+ *                     be specified. Enabling both fields will have
+ *                     undetermined results.
+ *
+ *                     SPP_HB_DEMAND - Request a user initiated heartbeat
+ *                     to be made immediately.
+ *
+ *                     SPP_PMTUD_ENABLE - This field will enable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected.
+ *
+ *                     SPP_PMTUD_DISABLE - This field will disable PMTU
+ *                     discovery upon the specified address. Note that
+ *                     if the address feild is empty then all addresses
+ *                     on the association are effected. Not also that
+ *                     SPP_PMTUD_ENABLE and SPP_PMTUD_DISABLE are mutually
+ *                     exclusive. Enabling both will have undetermined
+ *                     results.
+ *
+ *                     SPP_SACKDELAY_ENABLE - Setting this flag turns
+ *                     on delayed sack. The time specified in spp_sackdelay
+ *                     is used to specify the sack delay for this address. Note
+ *                     that if spp_address is empty then all addresses will
+ *                     enable delayed sack and take on the sack delay
+ *                     value specified in spp_sackdelay.
+ *                     SPP_SACKDELAY_DISABLE - Setting this flag turns
+ *                     off delayed sack. If the spp_address field is blank then
+ *                     delayed sack is disabled for the entire association. Note
+ *                     also that this field is mutually exclusive to
+ *                     SPP_SACKDELAY_ENABLE, setting both will have undefined
+ *                     results.
  */
 static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
-						char __user *optval, int __user *optlen)
+					    char __user *optval, int __user *optlen)
 {
-	struct sctp_paddrparams params;
-	struct sctp_transport *trans;
+	struct sctp_paddrparams  params;
+	struct sctp_transport   *trans = NULL;
+	struct sctp_association *asoc = NULL;
+	struct sctp_sock        *sp = sctp_sk(sk);
 
 	if (len != sizeof(struct sctp_paddrparams))
 		return -EINVAL;
+
 	if (copy_from_user(&params, optval, len))
 		return -EFAULT;
 
-	/* If no association id is specified retrieve the default value
-	 * for the endpoint that will be used for all future associations
+	/* If an address other than INADDR_ANY is specified, and
+	 * no transport is found, then the request is invalid.
 	 */
-	if (!params.spp_assoc_id &&
-	    sctp_is_any(( union sctp_addr *)&params.spp_address)) {
-		params.spp_hbinterval = sctp_sk(sk)->paddrparam.spp_hbinterval;
-		params.spp_pathmaxrxt = sctp_sk(sk)->paddrparam.spp_pathmaxrxt;
-
-		goto done;
+	if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) {
+		trans = sctp_addr_id2transport(sk, &params.spp_address,
+					       params.spp_assoc_id);
+		if (!trans) {
+			SCTP_DEBUG_PRINTK("Failed no transport\n");
+			return -EINVAL;
+		}
 	}
 
-	trans = sctp_addr_id2transport(sk, &params.spp_address,
-				       params.spp_assoc_id);
-	if (!trans)
+	/* Get association, if assoc_id != 0 and the socket is a one
+	 * to many style socket, and an association was not found, then
+	 * the id was invalid.
+	 */
+	asoc = sctp_id2assoc(sk, params.spp_assoc_id);
+	if (!asoc && params.spp_assoc_id && sctp_style(sk, UDP)) {
+		SCTP_DEBUG_PRINTK("Failed no association\n");
+		return -EINVAL;
+	}
+
+	if (trans) {
+		/* Fetch transport values. */
+		params.spp_hbinterval = jiffies_to_msecs(trans->hbinterval);
+		params.spp_pathmtu    = trans->pathmtu;
+		params.spp_pathmaxrxt = trans->pathmaxrxt;
+		params.spp_sackdelay  = jiffies_to_msecs(trans->sackdelay);
+
+		/*draft-11 doesn't say what to return in spp_flags*/
+		params.spp_flags      = trans->param_flags;
+	} else if (asoc) {
+		/* Fetch association values. */
+		params.spp_hbinterval = jiffies_to_msecs(asoc->hbinterval);
+		params.spp_pathmtu    = asoc->pathmtu;
+		params.spp_pathmaxrxt = asoc->pathmaxrxt;
+		params.spp_sackdelay  = jiffies_to_msecs(asoc->sackdelay);
+
+		/*draft-11 doesn't say what to return in spp_flags*/
+		params.spp_flags      = asoc->param_flags;
+	} else {
+		/* Fetch socket values. */
+		params.spp_hbinterval = sp->hbinterval;
+		params.spp_pathmtu    = sp->pathmtu;
+		params.spp_sackdelay  = sp->sackdelay;
+		params.spp_pathmaxrxt = sp->pathmaxrxt;
+
+		/*draft-11 doesn't say what to return in spp_flags*/
+		params.spp_flags      = sp->param_flags;
+	}
+
+	if (copy_to_user(optval, &params, len))
+		return -EFAULT;
+
+	if (put_user(len, optlen))
+		return -EFAULT;
+
+	return 0;
+}
+
+/* 7.1.24. Delayed Ack Timer (SCTP_DELAYED_ACK_TIME)
+ *
+ *   This options will get or set the delayed ack timer.  The time is set
+ *   in milliseconds.  If the assoc_id is 0, then this sets or gets the
+ *   endpoints default delayed ack timer value.  If the assoc_id field is
+ *   non-zero, then the set or get effects the specified association.
+ *
+ *   struct sctp_assoc_value {
+ *       sctp_assoc_t            assoc_id;
+ *       uint32_t                assoc_value;
+ *   };
+ *
+ *     assoc_id    - This parameter, indicates which association the
+ *                   user is preforming an action upon. Note that if
+ *                   this field's value is zero then the endpoints
+ *                   default value is changed (effecting future
+ *                   associations only).
+ *
+ *     assoc_value - This parameter contains the number of milliseconds
+ *                   that the user is requesting the delayed ACK timer
+ *                   be set to. Note that this value is defined in
+ *                   the standard to be between 200 and 500 milliseconds.
+ *
+ *                   Note: a value of zero will leave the value alone,
+ *                   but disable SACK delay. A non-zero value will also
+ *                   enable SACK delay.
+ */
+static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len,
+					    char __user *optval,
+					    int __user *optlen)
+{
+	struct sctp_assoc_value  params;
+	struct sctp_association *asoc = NULL;
+	struct sctp_sock        *sp = sctp_sk(sk);
+
+	if (len != sizeof(struct sctp_assoc_value))
+		return - EINVAL;
+
+	if (copy_from_user(&params, optval, len))
+		return -EFAULT;
+
+	/* Get association, if assoc_id != 0 and the socket is a one
+	 * to many style socket, and an association was not found, then
+	 * the id was invalid.
+ 	 */
+	asoc = sctp_id2assoc(sk, params.assoc_id);
+	if (!asoc && params.assoc_id && sctp_style(sk, UDP))
 		return -EINVAL;
 
-	/* The value of the heartbeat interval, in milliseconds. A value of 0,
-	 * when modifying the parameter, specifies that the heartbeat on this
-	 * address should be disabled.
-	 */
-	if (!trans->hb_allowed)
-		params.spp_hbinterval = 0;
-	else
-		params.spp_hbinterval = jiffies_to_msecs(trans->hb_interval);
+	if (asoc) {
+		/* Fetch association values. */
+		if (asoc->param_flags & SPP_SACKDELAY_ENABLE)
+			params.assoc_value = jiffies_to_msecs(
+				asoc->sackdelay);
+		else
+			params.assoc_value = 0;
+	} else {
+		/* Fetch socket values. */
+		if (sp->param_flags & SPP_SACKDELAY_ENABLE)
+			params.assoc_value  = sp->sackdelay;
+		else
+			params.assoc_value  = 0;
+	}
 
-	/* spp_pathmaxrxt contains the maximum number of retransmissions
-	 * before this address shall be considered unreachable.
-	 */
-	params.spp_pathmaxrxt = trans->max_retrans;
-
-done:
 	if (copy_to_user(optval, &params, len))
 		return -EFAULT;
 
@@ -3425,7 +3860,7 @@
 }
 
 static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port,
-				    void * __user *to, size_t space_left)
+				    void __user **to, size_t space_left)
 {
 	struct list_head *pos;
 	struct sctp_sockaddr_entry *addr;
@@ -4019,6 +4454,10 @@
 		retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
 							  optlen);
 		break;
+	case SCTP_DELAYED_ACK_TIME:
+		retval = sctp_getsockopt_delayed_ack_time(sk, len, optval,
+							  optlen);
+		break;
 	case SCTP_INITMSG:
 		retval = sctp_getsockopt_initmsg(sk, len, optval, optlen);
 		break;
@@ -4426,7 +4865,7 @@
  * tcp_poll().  Note that, based on these implementations, we don't
  * lock the socket in this function, even though it seems that,
  * ideally, locking or some other mechanisms can be used to ensure
- * the integrity of the counters (sndbuf and wmem_queued) used
+ * the integrity of the counters (sndbuf and wmem_alloc) used
  * in this place.  We assume that we don't need locks either until proven
  * otherwise.
  *
@@ -4743,11 +5182,6 @@
 	struct sk_buff *skb;
 	long timeo;
 
-	/* Caller is allowed not to check sk->sk_err before calling.  */
-	error = sock_error(sk);
-	if (error)
-		goto no_packet;
-
 	timeo = sock_rcvtimeo(sk, noblock);
 
 	SCTP_DEBUG_PRINTK("Timeout: timeo: %ld, MAX: %ld.\n",
@@ -4774,6 +5208,11 @@
 		if (skb)
 			return skb;
 
+		/* Caller is allowed not to check sk->sk_err before calling. */
+		error = sock_error(sk);
+		if (error)
+			goto no_packet;
+
 		if (sk->sk_shutdown & RCV_SHUTDOWN)
 			break;
 
@@ -4833,10 +5272,6 @@
 				sizeof(struct sk_buff) +
 				sizeof(struct sctp_chunk);
 
-	sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk) +
-				sizeof(struct sk_buff) +
-				sizeof(struct sctp_chunk);
-
 	atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
 
 	sock_wfree(skb);
@@ -4920,7 +5355,7 @@
 
 /* Is there any sndbuf space available on the socket?
  *
- * Note that wmem_queued is the sum of the send buffers on all of the
+ * Note that sk_wmem_alloc is the sum of the send buffers on all of the
  * associations on the same socket.  For a UDP-style socket with
  * multiple associations, it is possible for it to be "unwriteable"
  * prematurely.  I assume that this is acceptable because
@@ -4933,7 +5368,7 @@
 {
 	int amt = 0;
 
-	amt = sk->sk_sndbuf - sk->sk_wmem_queued;
+	amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
 	if (amt < 0)
 		amt = 0;
 	return amt;
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 6bc2720..68d73e2 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -86,10 +86,13 @@
 	peer->init_sent_count = 0;
 
 	peer->state = SCTP_ACTIVE;
-	peer->hb_allowed = 0;
+	peer->param_flags = SPP_HB_DISABLE |
+			    SPP_PMTUD_ENABLE |
+			    SPP_SACKDELAY_ENABLE;
+	peer->hbinterval  = 0;
 
 	/* Initialize the default path max_retrans.  */
-	peer->max_retrans = sctp_max_retrans_path;
+	peer->pathmaxrxt  = sctp_max_retrans_path;
 	peer->error_count = 0;
 
 	INIT_LIST_HEAD(&peer->transmitted);
@@ -229,10 +232,10 @@
 	dst = transport->af_specific->get_dst(NULL, &transport->ipaddr, NULL);
 
 	if (dst) {
-		transport->pmtu = dst_mtu(dst);
+		transport->pathmtu = dst_mtu(dst);
 		dst_release(dst);
 	} else
-		transport->pmtu = SCTP_DEFAULT_MAXSEGMENT;
+		transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 }
 
 /* Caches the dst entry and source address for a transport's destination
@@ -254,16 +257,20 @@
 		af->get_saddr(asoc, dst, daddr, &transport->saddr);
 
 	transport->dst = dst;
+	if ((transport->param_flags & SPP_PMTUD_DISABLE) && transport->pathmtu) {
+		return;
+	}
 	if (dst) {
-		transport->pmtu = dst_mtu(dst);
+		transport->pathmtu = dst_mtu(dst);
 
 		/* Initialize sk->sk_rcv_saddr, if the transport is the
 		 * association's active path for getsockname().
 		 */ 
 		if (asoc && (transport == asoc->peer.active_path))
-			af->to_sk_saddr(&transport->saddr, asoc->base.sk);
+			opt->pf->af->to_sk_saddr(&transport->saddr,
+						 asoc->base.sk);
 	} else
-		transport->pmtu = SCTP_DEFAULT_MAXSEGMENT;
+		transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 }
 
 /* Hold a reference to a transport.  */
@@ -368,7 +375,7 @@
 
 	ssthresh = transport->ssthresh;
 	pba = transport->partial_bytes_acked;
-	pmtu = transport->asoc->pmtu;
+	pmtu = transport->asoc->pathmtu;
 
 	if (cwnd <= ssthresh) {
 		/* RFC 2960 7.2.1, sctpimpguide-05 2.14.2 When cwnd is less
@@ -440,8 +447,8 @@
 		 *      partial_bytes_acked = 0
 		 */
 		transport->ssthresh = max(transport->cwnd/2,
-					  4*transport->asoc->pmtu);
-		transport->cwnd = transport->asoc->pmtu;
+					  4*transport->asoc->pathmtu);
+		transport->cwnd = transport->asoc->pathmtu;
 		break;
 
 	case SCTP_LOWER_CWND_FAST_RTX:
@@ -458,7 +465,7 @@
 		 *      partial_bytes_acked = 0
 		 */
 		transport->ssthresh = max(transport->cwnd/2,
-					  4*transport->asoc->pmtu);
+					  4*transport->asoc->pathmtu);
 		transport->cwnd = transport->ssthresh;
 		break;
 
@@ -478,7 +485,7 @@
 		if ((jiffies - transport->last_time_ecne_reduced) >
 		    transport->rtt) {
 			transport->ssthresh = max(transport->cwnd/2,
-					  	  4*transport->asoc->pmtu);
+					  	  4*transport->asoc->pathmtu);
 			transport->cwnd = transport->ssthresh;
 			transport->last_time_ecne_reduced = jiffies;
 		}
@@ -495,7 +502,7 @@
 		 */
 		if ((jiffies - transport->last_time_used) > transport->rto)
 			transport->cwnd = max(transport->cwnd/2,
-						 4*transport->asoc->pmtu);
+						 4*transport->asoc->pathmtu);
 		break;
 	};
 
@@ -510,7 +517,7 @@
 unsigned long sctp_transport_timeout(struct sctp_transport *t)
 {
 	unsigned long timeout;
-	timeout = t->hb_interval + t->rto + sctp_jitter(t->rto);
+	timeout = t->hbinterval + t->rto + sctp_jitter(t->rto);
 	timeout += jiffies;
 	return timeout;
 }
diff --git a/net/socket.c b/net/socket.c
index 3145103..06fa217 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -640,92 +640,6 @@
 	kfree(iocb->private);
 }
 
-/*
- *	Read data from a socket. ubuf is a user mode pointer. We make sure the user
- *	area ubuf...ubuf+size-1 is writable before asking the protocol.
- */
-
-static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
-			 size_t size, loff_t pos)
-{
-	struct sock_iocb *x, siocb;
-	struct socket *sock;
-	int flags;
-
-	if (pos != 0)
-		return -ESPIPE;
-	if (size==0)		/* Match SYS5 behaviour */
-		return 0;
-
-	if (is_sync_kiocb(iocb))
-		x = &siocb;
-	else {
-		x = kmalloc(sizeof(struct sock_iocb), GFP_KERNEL);
-		if (!x)
-			return -ENOMEM;
-		iocb->ki_dtor = sock_aio_dtor;
-	}
-	iocb->private = x;
-	x->kiocb = iocb;
-	sock = iocb->ki_filp->private_data; 
-
-	x->async_msg.msg_name = NULL;
-	x->async_msg.msg_namelen = 0;
-	x->async_msg.msg_iov = &x->async_iov;
-	x->async_msg.msg_iovlen = 1;
-	x->async_msg.msg_control = NULL;
-	x->async_msg.msg_controllen = 0;
-	x->async_iov.iov_base = ubuf;
-	x->async_iov.iov_len = size;
-	flags = !(iocb->ki_filp->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
-
-	return __sock_recvmsg(iocb, sock, &x->async_msg, size, flags);
-}
-
-
-/*
- *	Write data to a socket. We verify that the user area ubuf..ubuf+size-1
- *	is readable by the user process.
- */
-
-static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
-			  size_t size, loff_t pos)
-{
-	struct sock_iocb *x, siocb;
-	struct socket *sock;
-	
-	if (pos != 0)
-		return -ESPIPE;
-	if(size==0)		/* Match SYS5 behaviour */
-		return 0;
-
-	if (is_sync_kiocb(iocb))
-		x = &siocb;
-	else {
-		x = kmalloc(sizeof(struct sock_iocb), GFP_KERNEL);
-		if (!x)
-			return -ENOMEM;
-		iocb->ki_dtor = sock_aio_dtor;
-	}
-	iocb->private = x;
-	x->kiocb = iocb;
-	sock = iocb->ki_filp->private_data; 
-
-	x->async_msg.msg_name = NULL;
-	x->async_msg.msg_namelen = 0;
-	x->async_msg.msg_iov = &x->async_iov;
-	x->async_msg.msg_iovlen = 1;
-	x->async_msg.msg_control = NULL;
-	x->async_msg.msg_controllen = 0;
-	x->async_msg.msg_flags = !(iocb->ki_filp->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
-	if (sock->type == SOCK_SEQPACKET)
-		x->async_msg.msg_flags |= MSG_EOR;
-	x->async_iov.iov_base = (void __user *)ubuf;
-	x->async_iov.iov_len = size;
-	
-	return __sock_sendmsg(iocb, sock, &x->async_msg, size);
-}
-
 static ssize_t sock_sendpage(struct file *file, struct page *page,
 			     int offset, size_t size, loff_t *ppos, int more)
 {
@@ -741,53 +655,135 @@
 	return sock->ops->sendpage(sock, page, offset, size, flags);
 }
 
-static int sock_readv_writev(int type,
-			     struct file * file, const struct iovec * iov,
-			     long count, size_t size)
+static struct sock_iocb *alloc_sock_iocb(struct kiocb *iocb,
+		char __user *ubuf, size_t size, struct sock_iocb *siocb)
+{
+	if (!is_sync_kiocb(iocb)) {
+		siocb = kmalloc(sizeof(*siocb), GFP_KERNEL);
+		if (!siocb)
+			return NULL;
+		iocb->ki_dtor = sock_aio_dtor;
+	}
+
+	siocb->kiocb = iocb;
+	siocb->async_iov.iov_base = ubuf;
+	siocb->async_iov.iov_len = size;
+
+	iocb->private = siocb;
+	return siocb;
+}
+
+static ssize_t do_sock_read(struct msghdr *msg, struct kiocb *iocb,
+		struct file *file, struct iovec *iov, unsigned long nr_segs)
+{
+	struct socket *sock = file->private_data;
+	size_t size = 0;
+	int i;
+
+        for (i = 0 ; i < nr_segs ; i++)
+                size += iov[i].iov_len;
+
+	msg->msg_name = NULL;
+	msg->msg_namelen = 0;
+	msg->msg_control = NULL;
+	msg->msg_controllen = 0;
+	msg->msg_iov = (struct iovec *) iov;
+	msg->msg_iovlen = nr_segs;
+	msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+
+	return __sock_recvmsg(iocb, sock, msg, size, msg->msg_flags);
+}
+
+static ssize_t sock_readv(struct file *file, const struct iovec *iov,
+			  unsigned long nr_segs, loff_t *ppos)
+{
+	struct kiocb iocb;
+	struct sock_iocb siocb;
+	struct msghdr msg;
+	int ret;
+
+        init_sync_kiocb(&iocb, NULL);
+	iocb.private = &siocb;
+
+	ret = do_sock_read(&msg, &iocb, file, (struct iovec *)iov, nr_segs);
+	if (-EIOCBQUEUED == ret)
+		ret = wait_on_sync_kiocb(&iocb);
+	return ret;
+}
+
+static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
+			 size_t count, loff_t pos)
+{
+	struct sock_iocb siocb, *x;
+
+	if (pos != 0)
+		return -ESPIPE;
+	if (count == 0)		/* Match SYS5 behaviour */
+		return 0;
+
+	x = alloc_sock_iocb(iocb, ubuf, count, &siocb);
+	if (!x)
+		return -ENOMEM;
+	return do_sock_read(&x->async_msg, iocb, iocb->ki_filp,
+			&x->async_iov, 1);
+}
+
+static ssize_t do_sock_write(struct msghdr *msg, struct kiocb *iocb,
+		struct file *file, struct iovec *iov, unsigned long nr_segs)
+{
+	struct socket *sock = file->private_data;
+	size_t size = 0;
+	int i;
+
+        for (i = 0 ; i < nr_segs ; i++)
+                size += iov[i].iov_len;
+
+	msg->msg_name = NULL;
+	msg->msg_namelen = 0;
+	msg->msg_control = NULL;
+	msg->msg_controllen = 0;
+	msg->msg_iov = (struct iovec *) iov;
+	msg->msg_iovlen = nr_segs;
+	msg->msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
+	if (sock->type == SOCK_SEQPACKET)
+		msg->msg_flags |= MSG_EOR;
+
+	return __sock_sendmsg(iocb, sock, msg, size);
+}
+
+static ssize_t sock_writev(struct file *file, const struct iovec *iov,
+			   unsigned long nr_segs, loff_t *ppos)
 {
 	struct msghdr msg;
-	struct socket *sock;
+	struct kiocb iocb;
+	struct sock_iocb siocb;
+	int ret;
 
-	sock = file->private_data;
+	init_sync_kiocb(&iocb, NULL);
+	iocb.private = &siocb;
 
-	msg.msg_name = NULL;
-	msg.msg_namelen = 0;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-	msg.msg_iov = (struct iovec *) iov;
-	msg.msg_iovlen = count;
-	msg.msg_flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0;
-
-	/* read() does a VERIFY_WRITE */
-	if (type == VERIFY_WRITE)
-		return sock_recvmsg(sock, &msg, size, msg.msg_flags);
-
-	if (sock->type == SOCK_SEQPACKET)
-		msg.msg_flags |= MSG_EOR;
-
-	return sock_sendmsg(sock, &msg, size);
+	ret = do_sock_write(&msg, &iocb, file, (struct iovec *)iov, nr_segs);
+	if (-EIOCBQUEUED == ret)
+		ret = wait_on_sync_kiocb(&iocb);
+	return ret;
 }
 
-static ssize_t sock_readv(struct file *file, const struct iovec *vector,
-			  unsigned long count, loff_t *ppos)
+static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
+			  size_t count, loff_t pos)
 {
-	size_t tot_len = 0;
-	int i;
-        for (i = 0 ; i < count ; i++)
-                tot_len += vector[i].iov_len;
-	return sock_readv_writev(VERIFY_WRITE,
-				 file, vector, count, tot_len);
-}
-	
-static ssize_t sock_writev(struct file *file, const struct iovec *vector,
-			   unsigned long count, loff_t *ppos)
-{
-	size_t tot_len = 0;
-	int i;
-        for (i = 0 ; i < count ; i++)
-                tot_len += vector[i].iov_len;
-	return sock_readv_writev(VERIFY_READ,
-				 file, vector, count, tot_len);
+	struct sock_iocb siocb, *x;
+
+	if (pos != 0)
+		return -ESPIPE;
+	if (count == 0)		/* Match SYS5 behaviour */
+		return 0;
+
+	x = alloc_sock_iocb(iocb, (void __user *)ubuf, count, &siocb);
+	if (!x)
+		return -ENOMEM;
+
+	return do_sock_write(&x->async_msg, iocb, iocb->ki_filp,
+			&x->async_iov, 1);
 }
 
 
@@ -904,6 +900,13 @@
 			break;
 		default:
 			err = sock->ops->ioctl(sock, cmd, arg);
+
+			/*
+			 * If this ioctl is unknown try to hand it down
+			 * to the NIC driver.
+			 */
+			if (err == -ENOIOCTLCMD)
+				err = dev_ioctl(cmd, argp);
 			break;
 	}
 	return err;
@@ -2036,7 +2039,7 @@
 	return 0;
 }
 
-void __init sock_init(void)
+static int __init sock_init(void)
 {
 	/*
 	 *	Initialize sock SLAB cache.
@@ -2044,12 +2047,10 @@
 	 
 	sk_init();
 
-#ifdef SLAB_SKB
 	/*
 	 *	Initialize skbuff SLAB cache 
 	 */
 	skb_init();
-#endif
 
 	/*
 	 *	Initialize the protocols module. 
@@ -2058,15 +2059,19 @@
 	init_inodecache();
 	register_filesystem(&sock_fs_type);
 	sock_mnt = kern_mount(&sock_fs_type);
-	/* The real protocol initialization is performed when
-	 *  do_initcalls is run.  
+
+	/* The real protocol initialization is performed in later initcalls.
 	 */
 
 #ifdef CONFIG_NETFILTER
 	netfilter_init();
 #endif
+
+	return 0;
 }
 
+core_initcall(sock_init);	/* early initcall */
+
 #ifdef CONFIG_PROC_FS
 void socket_seq_show(struct seq_file *seq)
 {
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index f44f46f..8d78228 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -638,7 +638,7 @@
 				gss_msg);
 		atomic_inc(&gss_msg->count);
 		gss_unhash_msg(gss_msg);
-		if (msg->errno == -ETIMEDOUT || msg->errno == -EPIPE) {
+		if (msg->errno == -ETIMEDOUT) {
 			unsigned long now = jiffies;
 			if (time_after(now, ratelimit)) {
 				printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n"
@@ -786,7 +786,9 @@
 	cred->gc_flags = 0;
 	cred->gc_base.cr_ops = &gss_credops;
 	cred->gc_service = gss_auth->service;
-	err = gss_create_upcall(gss_auth, cred);
+	do {
+		err = gss_create_upcall(gss_auth, cred);
+	} while (err == -EAGAIN);
 	if (err < 0)
 		goto out_err;
 
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 5f1f806..129e2bd 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -97,13 +97,17 @@
 			alg_mode = CRYPTO_TFM_MODE_CBC;
 			break;
 		default:
-			dprintk("RPC:      get_key: unsupported algorithm %d\n", alg);
+			printk("gss_kerberos_mech: unsupported algorithm %d\n", alg);
 			goto out_err_free_key;
 	}
-	if (!(*res = crypto_alloc_tfm(alg_name, alg_mode)))
+	if (!(*res = crypto_alloc_tfm(alg_name, alg_mode))) {
+		printk("gss_kerberos_mech: unable to initialize crypto algorithm %s\n", alg_name);
 		goto out_err_free_key;
-	if (crypto_cipher_setkey(*res, key.data, key.len))
+	}
+	if (crypto_cipher_setkey(*res, key.data, key.len)) {
+		printk("gss_kerberos_mech: error setting key for crypto algorithm %s\n", alg_name);
 		goto out_err_free_tfm;
+	}
 
 	kfree(key.data);
 	return p;
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index 39b3edc..5840080 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -111,14 +111,18 @@
 			setkey = 0;
 			break;
 		default:
-			dprintk("RPC: SPKM3 get_key: unsupported algorithm %d", *resalg);
+			dprintk("gss_spkm3_mech: unsupported algorithm %d\n", *resalg);
 			goto out_err_free_key;
 	}
-	if (!(*res = crypto_alloc_tfm(alg_name, alg_mode)))
+	if (!(*res = crypto_alloc_tfm(alg_name, alg_mode))) {
+		printk("gss_spkm3_mech: unable to initialize crypto algorthm %s\n", alg_name);
 		goto out_err_free_key;
+	}
 	if (setkey) {
-		if (crypto_cipher_setkey(*res, key.data, key.len))
+		if (crypto_cipher_setkey(*res, key.data, key.len)) {
+			printk("gss_spkm3_mech: error setting key for crypto algorthm %s\n", alg_name);
 			goto out_err_free_tfm;
+		}
 	}
 
 	if(key.len > 0)
diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c
index d1e12b2..86fbf7c 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_seal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c
@@ -59,7 +59,7 @@
 	char			tokhdrbuf[25];
 	struct xdr_netobj	md5cksum = {.len = 0, .data = NULL};
 	struct xdr_netobj	mic_hdr = {.len = 0, .data = tokhdrbuf};
-	int			tmsglen, tokenlen = 0;
+	int			tokenlen = 0;
 	unsigned char		*ptr;
 	s32			now;
 	int			ctxelen = 0, ctxzbit = 0;
@@ -92,24 +92,23 @@
 	}
 
 	if (toktype == SPKM_MIC_TOK) {
-		tmsglen = 0;
 		/* Calculate checksum over the mic-header */
 		asn1_bitstring_len(&ctx->ctx_id, &ctxelen, &ctxzbit);
 		spkm3_mic_header(&mic_hdr.data, &mic_hdr.len, ctx->ctx_id.data,
 		                         ctxelen, ctxzbit);
 
 		if (make_checksum(checksum_type, mic_hdr.data, mic_hdr.len, 
-		                             text, &md5cksum))
+		                             text, 0, &md5cksum))
 			goto out_err;
 
 		asn1_bitstring_len(&md5cksum, &md5elen, &md5zbit);
-		tokenlen = 10 + ctxelen + 1 + 2 + md5elen + 1;
+		tokenlen = 10 + ctxelen + 1 + md5elen + 1;
 
 		/* Create token header using generic routines */
-		token->len = g_token_size(&ctx->mech_used, tokenlen + tmsglen);
+		token->len = g_token_size(&ctx->mech_used, tokenlen);
 
 		ptr = token->data;
-		g_make_token_header(&ctx->mech_used, tokenlen + tmsglen, &ptr);
+		g_make_token_header(&ctx->mech_used, tokenlen, &ptr);
 
 		spkm3_make_mic_token(&ptr, tokenlen, &mic_hdr, &md5cksum, md5elen, md5zbit);
 	} else if (toktype == SPKM_WRAP_TOK) { /* Not Supported */
diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c
index 1f82457..af0d7ce 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_token.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_token.c
@@ -182,6 +182,7 @@
  * *tokp points to the beginning of the SPKM_MIC token  described 
  * in rfc 2025, section 3.2.1: 
  *
+ * toklen is the inner token length
  */
 void
 spkm3_make_mic_token(unsigned char **tokp, int toklen, struct xdr_netobj *mic_hdr, struct xdr_netobj *md5cksum, int md5elen, int md5zbit)
@@ -189,7 +190,7 @@
 	unsigned char *ict = *tokp;
 
 	*(u8 *)ict++ = 0xa4;
-	*(u8 *)ict++ = toklen - 2; 
+	*(u8 *)ict++ = toklen;
 	memcpy(ict, mic_hdr->data, mic_hdr->len);
 	ict += mic_hdr->len;
 
diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
index 241d5b3..96851b0 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
@@ -95,7 +95,7 @@
 		ret = GSS_S_DEFECTIVE_TOKEN;
 		code = make_checksum(CKSUMTYPE_RSA_MD5, ptr + 2, 
 					mic_hdrlen + 2, 
-		                        message_buffer, &md5cksum);
+		                        message_buffer, 0, &md5cksum);
 
 		if (code)
 			goto out;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 61c3abe..5530ac8 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -374,19 +374,23 @@
  * Default callback for async RPC calls
  */
 static void
-rpc_default_callback(struct rpc_task *task)
+rpc_default_callback(struct rpc_task *task, void *data)
 {
 }
 
+static const struct rpc_call_ops rpc_default_ops = {
+	.rpc_call_done = rpc_default_callback,
+};
+
 /*
  *	Export the signal mask handling for synchronous code that
  *	sleeps on RPC calls
  */
-#define RPC_INTR_SIGNALS (sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGKILL))
+#define RPC_INTR_SIGNALS (sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGTERM))
  
 static void rpc_save_sigmask(sigset_t *oldset, int intr)
 {
-	unsigned long	sigallow = 0;
+	unsigned long	sigallow = sigmask(SIGKILL);
 	sigset_t sigmask;
 
 	/* Block all signals except those listed in sigallow */
@@ -432,7 +436,7 @@
 	BUG_ON(flags & RPC_TASK_ASYNC);
 
 	status = -ENOMEM;
-	task = rpc_new_task(clnt, NULL, flags);
+	task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL);
 	if (task == NULL)
 		goto out;
 
@@ -442,14 +446,15 @@
 	rpc_call_setup(task, msg, 0);
 
 	/* Set up the call info struct and execute the task */
-	if (task->tk_status == 0) {
+	status = task->tk_status;
+	if (status == 0) {
+		atomic_inc(&task->tk_count);
 		status = rpc_execute(task);
-	} else {
-		status = task->tk_status;
-		rpc_release_task(task);
+		if (status == 0)
+			status = task->tk_status;
 	}
-
 	rpc_restore_sigmask(&oldset);
+	rpc_release_task(task);
 out:
 	return status;
 }
@@ -459,7 +464,7 @@
  */
 int
 rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
-	       rpc_action callback, void *data)
+	       const struct rpc_call_ops *tk_ops, void *data)
 {
 	struct rpc_task	*task;
 	sigset_t	oldset;
@@ -472,12 +477,9 @@
 	flags |= RPC_TASK_ASYNC;
 
 	/* Create/initialize a new RPC task */
-	if (!callback)
-		callback = rpc_default_callback;
 	status = -ENOMEM;
-	if (!(task = rpc_new_task(clnt, callback, flags)))
+	if (!(task = rpc_new_task(clnt, flags, tk_ops, data)))
 		goto out;
-	task->tk_calldata = data;
 
 	/* Mask signals on GSS_AUTH upcalls */
 	rpc_task_sigmask(task, &oldset);		
@@ -511,7 +513,7 @@
 	if (task->tk_status == 0)
 		task->tk_action = call_start;
 	else
-		task->tk_action = NULL;
+		task->tk_action = rpc_exit_task;
 }
 
 void
@@ -536,6 +538,18 @@
 }
 EXPORT_SYMBOL(rpc_max_payload);
 
+/**
+ * rpc_force_rebind - force transport to check that remote port is unchanged
+ * @clnt: client to rebind
+ *
+ */
+void rpc_force_rebind(struct rpc_clnt *clnt)
+{
+	if (clnt->cl_autobind)
+		clnt->cl_port = 0;
+}
+EXPORT_SYMBOL(rpc_force_rebind);
+
 /*
  * Restart an (async) RPC call. Usually called from within the
  * exit handler.
@@ -642,24 +656,26 @@
 
 /*
  * 2.	Allocate the buffer. For details, see sched.c:rpc_malloc.
- *	(Note: buffer memory is freed in rpc_task_release).
+ *	(Note: buffer memory is freed in xprt_release).
  */
 static void
 call_allocate(struct rpc_task *task)
 {
+	struct rpc_rqst *req = task->tk_rqstp;
+	struct rpc_xprt *xprt = task->tk_xprt;
 	unsigned int	bufsiz;
 
 	dprintk("RPC: %4d call_allocate (status %d)\n", 
 				task->tk_pid, task->tk_status);
 	task->tk_action = call_bind;
-	if (task->tk_buffer)
+	if (req->rq_buffer)
 		return;
 
 	/* FIXME: compute buffer requirements more exactly using
 	 * auth->au_wslack */
 	bufsiz = task->tk_msg.rpc_proc->p_bufsiz + RPC_SLACK_SPACE;
 
-	if (rpc_malloc(task, bufsiz << 1) != NULL)
+	if (xprt->ops->buf_alloc(task, bufsiz << 1) != NULL)
 		return;
 	printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); 
 
@@ -702,14 +718,14 @@
 				task->tk_pid, task->tk_status);
 
 	/* Default buffer setup */
-	bufsiz = task->tk_bufsize >> 1;
-	sndbuf->head[0].iov_base = (void *)task->tk_buffer;
+	bufsiz = req->rq_bufsize >> 1;
+	sndbuf->head[0].iov_base = (void *)req->rq_buffer;
 	sndbuf->head[0].iov_len  = bufsiz;
 	sndbuf->tail[0].iov_len  = 0;
 	sndbuf->page_len	 = 0;
 	sndbuf->len		 = 0;
 	sndbuf->buflen		 = bufsiz;
-	rcvbuf->head[0].iov_base = (void *)((char *)task->tk_buffer + bufsiz);
+	rcvbuf->head[0].iov_base = (void *)((char *)req->rq_buffer + bufsiz);
 	rcvbuf->head[0].iov_len  = bufsiz;
 	rcvbuf->tail[0].iov_len  = 0;
 	rcvbuf->page_len	 = 0;
@@ -849,8 +865,7 @@
 	}
 
 	/* Something failed: remote service port may have changed */
-	if (clnt->cl_autobind)
-		clnt->cl_port = 0;
+	rpc_force_rebind(clnt);
 
 	switch (status) {
 	case -ENOTCONN:
@@ -892,7 +907,7 @@
 	if (task->tk_status < 0)
 		return;
 	if (!task->tk_msg.rpc_proc->p_decode) {
-		task->tk_action = NULL;
+		task->tk_action = rpc_exit_task;
 		rpc_wake_up_task(task);
 	}
 	return;
@@ -931,8 +946,7 @@
 		break;
 	case -ECONNREFUSED:
 	case -ENOTCONN:
-		if (clnt->cl_autobind)
-			clnt->cl_port = 0;
+		rpc_force_rebind(clnt);
 		task->tk_action = call_bind;
 		break;
 	case -EAGAIN:
@@ -943,8 +957,7 @@
 		rpc_exit(task, status);
 		break;
 	default:
-		if (clnt->cl_chatty)
-			printk("%s: RPC call returned error %d\n",
+		printk("%s: RPC call returned error %d\n",
 			       clnt->cl_protname, -status);
 		rpc_exit(task, status);
 		break;
@@ -979,20 +992,18 @@
 
 	dprintk("RPC: %4d call_timeout (major)\n", task->tk_pid);
 	if (RPC_IS_SOFT(task)) {
-		if (clnt->cl_chatty)
-			printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
+		printk(KERN_NOTICE "%s: server %s not responding, timed out\n",
 				clnt->cl_protname, clnt->cl_server);
 		rpc_exit(task, -EIO);
 		return;
 	}
 
-	if (clnt->cl_chatty && !(task->tk_flags & RPC_CALL_MAJORSEEN)) {
+	if (!(task->tk_flags & RPC_CALL_MAJORSEEN)) {
 		task->tk_flags |= RPC_CALL_MAJORSEEN;
 		printk(KERN_NOTICE "%s: server %s not responding, still trying\n",
 			clnt->cl_protname, clnt->cl_server);
 	}
-	if (clnt->cl_autobind)
-		clnt->cl_port = 0;
+	rpc_force_rebind(clnt);
 
 retry:
 	clnt->cl_stats->rpcretrans++;
@@ -1014,7 +1025,7 @@
 	dprintk("RPC: %4d call_decode (status %d)\n", 
 				task->tk_pid, task->tk_status);
 
-	if (clnt->cl_chatty && (task->tk_flags & RPC_CALL_MAJORSEEN)) {
+	if (task->tk_flags & RPC_CALL_MAJORSEEN) {
 		printk(KERN_NOTICE "%s: server %s OK\n",
 			clnt->cl_protname, clnt->cl_server);
 		task->tk_flags &= ~RPC_CALL_MAJORSEEN;
@@ -1039,13 +1050,14 @@
 				sizeof(req->rq_rcv_buf)) != 0);
 
 	/* Verify the RPC header */
-	if (!(p = call_verify(task))) {
-		if (task->tk_action == NULL)
-			return;
-		goto out_retry;
+	p = call_verify(task);
+	if (IS_ERR(p)) {
+		if (p == ERR_PTR(-EAGAIN))
+			goto out_retry;
+		return;
 	}
 
-	task->tk_action = NULL;
+	task->tk_action = rpc_exit_task;
 
 	if (decode)
 		task->tk_status = rpcauth_unwrap_resp(task, decode, req, p,
@@ -1138,7 +1150,7 @@
 
 	if ((n = ntohl(*p++)) != RPC_REPLY) {
 		printk(KERN_WARNING "call_verify: not an RPC reply: %x\n", n);
-		goto out_retry;
+		goto out_garbage;
 	}
 	if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
 		if (--len < 0)
@@ -1168,7 +1180,7 @@
 							task->tk_pid);
 			rpcauth_invalcred(task);
 			task->tk_action = call_refresh;
-			return NULL;
+			goto out_retry;
 		case RPC_AUTH_BADCRED:
 		case RPC_AUTH_BADVERF:
 			/* possibly garbled cred/verf? */
@@ -1178,7 +1190,7 @@
 			dprintk("RPC: %4d call_verify: retry garbled creds\n",
 							task->tk_pid);
 			task->tk_action = call_bind;
-			return NULL;
+			goto out_retry;
 		case RPC_AUTH_TOOWEAK:
 			printk(KERN_NOTICE "call_verify: server requires stronger "
 			       "authentication.\n");
@@ -1193,7 +1205,7 @@
 	}
 	if (!(p = rpcauth_checkverf(task, p))) {
 		printk(KERN_WARNING "call_verify: auth check failed\n");
-		goto out_retry;		/* bad verifier, retry */
+		goto out_garbage;		/* bad verifier, retry */
 	}
 	len = p - (u32 *)iov->iov_base - 1;
 	if (len < 0)
@@ -1230,23 +1242,24 @@
 		/* Also retry */
 	}
 
-out_retry:
+out_garbage:
 	task->tk_client->cl_stats->rpcgarbage++;
 	if (task->tk_garb_retry) {
 		task->tk_garb_retry--;
 		dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid);
 		task->tk_action = call_bind;
-		return NULL;
+out_retry:
+		return ERR_PTR(-EAGAIN);
 	}
 	printk(KERN_WARNING "RPC %s: retry failed, exit EIO\n", __FUNCTION__);
 out_eio:
 	error = -EIO;
 out_err:
 	rpc_exit(task, error);
-	return NULL;
+	return ERR_PTR(error);
 out_overflow:
 	printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__);
-	goto out_retry;
+	goto out_garbage;
 }
 
 static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj)
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
index a398575..8139ce6 100644
--- a/net/sunrpc/pmap_clnt.c
+++ b/net/sunrpc/pmap_clnt.c
@@ -90,8 +90,7 @@
 	map->pm_binding = 0;
 	rpc_wake_up(&map->pm_bindwait);
 	spin_unlock(&pmap_lock);
-	task->tk_status = -EIO;
-	task->tk_action = NULL;
+	rpc_exit(task, -EIO);
 }
 
 #ifdef CONFIG_ROOT_NFS
@@ -132,21 +131,22 @@
 pmap_getport_done(struct rpc_task *task)
 {
 	struct rpc_clnt	*clnt = task->tk_client;
+	struct rpc_xprt *xprt = task->tk_xprt;
 	struct rpc_portmap *map = clnt->cl_pmap;
 
 	dprintk("RPC: %4d pmap_getport_done(status %d, port %d)\n",
 			task->tk_pid, task->tk_status, clnt->cl_port);
+
+	xprt->ops->set_port(xprt, 0);
 	if (task->tk_status < 0) {
 		/* Make the calling task exit with an error */
-		task->tk_action = NULL;
+		task->tk_action = rpc_exit_task;
 	} else if (clnt->cl_port == 0) {
 		/* Program not registered */
-		task->tk_status = -EACCES;
-		task->tk_action = NULL;
+		rpc_exit(task, -EACCES);
 	} else {
-		/* byte-swap port number first */
+		xprt->ops->set_port(xprt, clnt->cl_port);
 		clnt->cl_port = htons(clnt->cl_port);
-		clnt->cl_xprt->addr.sin_port = clnt->cl_port;
 	}
 	spin_lock(&pmap_lock);
 	map->pm_binding = 0;
@@ -207,7 +207,7 @@
 	xprt = xprt_create_proto(proto, srvaddr, NULL);
 	if (IS_ERR(xprt))
 		return (struct rpc_clnt *)xprt;
-	xprt->addr.sin_port = htons(RPC_PMAP_PORT);
+	xprt->ops->set_port(xprt, RPC_PMAP_PORT);
 	if (!privileged)
 		xprt->resvport = 0;
 
@@ -217,7 +217,6 @@
 				RPC_AUTH_UNIX);
 	if (!IS_ERR(clnt)) {
 		clnt->cl_softrtry = 1;
-		clnt->cl_chatty   = 1;
 		clnt->cl_oneshot  = 1;
 	}
 	return clnt;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e3b242d..e14c1cae 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -59,7 +59,6 @@
 	struct rpc_inode *rpci = RPC_I(inode);
 
 	__rpc_purge_list(rpci, &rpci->pipe, err);
-	__rpc_purge_list(rpci, &rpci->in_upcall, err);
 	rpci->pipelen = 0;
 	wake_up(&rpci->waitq);
 }
@@ -71,8 +70,11 @@
 	struct inode *inode = &rpci->vfs_inode;
 
 	down(&inode->i_sem);
+	if (rpci->ops == NULL)
+		goto out;
 	if (rpci->nreaders == 0 && !list_empty(&rpci->pipe))
 		__rpc_purge_upcall(inode, -ETIMEDOUT);
+out:
 	up(&inode->i_sem);
 }
 
@@ -114,11 +116,10 @@
 {
 	struct rpc_inode *rpci = RPC_I(inode);
 
-	cancel_delayed_work(&rpci->queue_timeout);
-	flush_scheduled_work();
 	down(&inode->i_sem);
 	if (rpci->ops != NULL) {
 		rpci->nreaders = 0;
+		__rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE);
 		__rpc_purge_upcall(inode, -EPIPE);
 		rpci->nwriters = 0;
 		if (rpci->ops->release_pipe)
@@ -127,6 +128,8 @@
 	}
 	rpc_inode_setowner(inode, NULL);
 	up(&inode->i_sem);
+	cancel_delayed_work(&rpci->queue_timeout);
+	flush_scheduled_work();
 }
 
 static struct inode *
@@ -166,7 +169,7 @@
 static int
 rpc_pipe_release(struct inode *inode, struct file *filp)
 {
-	struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode);
+	struct rpc_inode *rpci = RPC_I(inode);
 	struct rpc_pipe_msg *msg;
 
 	down(&inode->i_sem);
@@ -174,7 +177,7 @@
 		goto out;
 	msg = (struct rpc_pipe_msg *)filp->private_data;
 	if (msg != NULL) {
-		msg->errno = -EPIPE;
+		msg->errno = -EAGAIN;
 		list_del_init(&msg->list);
 		rpci->ops->destroy_msg(msg);
 	}
@@ -183,7 +186,7 @@
 	if (filp->f_mode & FMODE_READ)
 		rpci->nreaders --;
 	if (!rpci->nreaders)
-		__rpc_purge_upcall(inode, -EPIPE);
+		__rpc_purge_upcall(inode, -EAGAIN);
 	if (rpci->ops->release_pipe)
 		rpci->ops->release_pipe(inode);
 out:
@@ -492,7 +495,7 @@
 repeat:
 	spin_lock(&dcache_lock);
 	list_for_each_safe(pos, next, &parent->d_subdirs) {
-		dentry = list_entry(pos, struct dentry, d_child);
+		dentry = list_entry(pos, struct dentry, d_u.d_child);
 		spin_lock(&dentry->d_lock);
 		if (!d_unhashed(dentry)) {
 			dget_locked(dentry);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 54e60a6..7415406 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -41,8 +41,6 @@
 
 static void			__rpc_default_timer(struct rpc_task *task);
 static void			rpciod_killall(void);
-static void			rpc_free(struct rpc_task *task);
-
 static void			rpc_async_schedule(void *);
 
 /*
@@ -264,6 +262,35 @@
 }
 EXPORT_SYMBOL(rpc_init_wait_queue);
 
+static int rpc_wait_bit_interruptible(void *word)
+{
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	schedule();
+	return 0;
+}
+
+/*
+ * Mark an RPC call as having completed by clearing the 'active' bit
+ */
+static inline void rpc_mark_complete_task(struct rpc_task *task)
+{
+	rpc_clear_active(task);
+	wake_up_bit(&task->tk_runstate, RPC_TASK_ACTIVE);
+}
+
+/*
+ * Allow callers to wait for completion of an RPC call
+ */
+int __rpc_wait_for_completion_task(struct rpc_task *task, int (*action)(void *))
+{
+	if (action == NULL)
+		action = rpc_wait_bit_interruptible;
+	return wait_on_bit(&task->tk_runstate, RPC_TASK_ACTIVE,
+			action, TASK_INTERRUPTIBLE);
+}
+EXPORT_SYMBOL(__rpc_wait_for_completion_task);
+
 /*
  * Make an RPC task runnable.
  *
@@ -299,10 +326,7 @@
 static inline void
 rpc_schedule_run(struct rpc_task *task)
 {
-	/* Don't run a child twice! */
-	if (RPC_IS_ACTIVATED(task))
-		return;
-	task->tk_active = 1;
+	rpc_set_active(task);
 	rpc_make_runnable(task);
 }
 
@@ -324,8 +348,7 @@
 	}
 
 	/* Mark the task as being activated if so needed */
-	if (!RPC_IS_ACTIVATED(task))
-		task->tk_active = 1;
+	rpc_set_active(task);
 
 	__rpc_add_wait_queue(q, task);
 
@@ -555,36 +578,29 @@
 }
 
 /*
- * Helper that calls task->tk_exit if it exists and then returns
- * true if we should exit __rpc_execute.
+ * Helper to call task->tk_ops->rpc_call_prepare
  */
-static inline int __rpc_do_exit(struct rpc_task *task)
+static void rpc_prepare_task(struct rpc_task *task)
 {
-	if (task->tk_exit != NULL) {
-		lock_kernel();
-		task->tk_exit(task);
-		unlock_kernel();
-		/* If tk_action is non-null, we should restart the call */
-		if (task->tk_action != NULL) {
-			if (!RPC_ASSASSINATED(task)) {
-				/* Release RPC slot and buffer memory */
-				xprt_release(task);
-				rpc_free(task);
-				return 0;
-			}
-			printk(KERN_ERR "RPC: dead task tried to walk away.\n");
-		}
-	}
-	return 1;
+	task->tk_ops->rpc_call_prepare(task, task->tk_calldata);
 }
 
-static int rpc_wait_bit_interruptible(void *word)
+/*
+ * Helper that calls task->tk_ops->rpc_call_done if it exists
+ */
+void rpc_exit_task(struct rpc_task *task)
 {
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	schedule();
-	return 0;
+	task->tk_action = NULL;
+	if (task->tk_ops->rpc_call_done != NULL) {
+		task->tk_ops->rpc_call_done(task, task->tk_calldata);
+		if (task->tk_action != NULL) {
+			WARN_ON(RPC_ASSASSINATED(task));
+			/* Always release the RPC slot and buffer memory */
+			xprt_release(task);
+		}
+	}
 }
+EXPORT_SYMBOL(rpc_exit_task);
 
 /*
  * This is the RPC `scheduler' (or rather, the finite state machine).
@@ -631,12 +647,11 @@
 		 * by someone else.
 		 */
 		if (!RPC_IS_QUEUED(task)) {
-			if (task->tk_action != NULL) {
-				lock_kernel();
-				task->tk_action(task);
-				unlock_kernel();
-			} else if (__rpc_do_exit(task))
+			if (task->tk_action == NULL)
 				break;
+			lock_kernel();
+			task->tk_action(task);
+			unlock_kernel();
 		}
 
 		/*
@@ -676,9 +691,9 @@
 		dprintk("RPC: %4d sync task resuming\n", task->tk_pid);
 	}
 
-	dprintk("RPC: %4d exit() = %d\n", task->tk_pid, task->tk_status);
-	status = task->tk_status;
-
+	dprintk("RPC: %4d, return %d, status %d\n", task->tk_pid, status, task->tk_status);
+	/* Wake up anyone who is waiting for task completion */
+	rpc_mark_complete_task(task);
 	/* Release all resources associated with the task */
 	rpc_release_task(task);
 	return status;
@@ -696,9 +711,7 @@
 int
 rpc_execute(struct rpc_task *task)
 {
-	BUG_ON(task->tk_active);
-
-	task->tk_active = 1;
+	rpc_set_active(task);
 	rpc_set_running(task);
 	return __rpc_execute(task);
 }
@@ -708,17 +721,19 @@
 	__rpc_execute((struct rpc_task *)arg);
 }
 
-/*
- * Allocate memory for RPC purposes.
+/**
+ * rpc_malloc - allocate an RPC buffer
+ * @task: RPC task that will use this buffer
+ * @size: requested byte size
  *
  * We try to ensure that some NFS reads and writes can always proceed
  * by using a mempool when allocating 'small' buffers.
  * In order to avoid memory starvation triggering more writebacks of
  * NFS requests, we use GFP_NOFS rather than GFP_KERNEL.
  */
-void *
-rpc_malloc(struct rpc_task *task, size_t size)
+void * rpc_malloc(struct rpc_task *task, size_t size)
 {
+	struct rpc_rqst *req = task->tk_rqstp;
 	gfp_t	gfp;
 
 	if (task->tk_flags & RPC_TASK_SWAPPER)
@@ -727,42 +742,52 @@
 		gfp = GFP_NOFS;
 
 	if (size > RPC_BUFFER_MAXSIZE) {
-		task->tk_buffer =  kmalloc(size, gfp);
-		if (task->tk_buffer)
-			task->tk_bufsize = size;
+		req->rq_buffer = kmalloc(size, gfp);
+		if (req->rq_buffer)
+			req->rq_bufsize = size;
 	} else {
-		task->tk_buffer =  mempool_alloc(rpc_buffer_mempool, gfp);
-		if (task->tk_buffer)
-			task->tk_bufsize = RPC_BUFFER_MAXSIZE;
+		req->rq_buffer = mempool_alloc(rpc_buffer_mempool, gfp);
+		if (req->rq_buffer)
+			req->rq_bufsize = RPC_BUFFER_MAXSIZE;
 	}
-	return task->tk_buffer;
+	return req->rq_buffer;
 }
 
-static void
-rpc_free(struct rpc_task *task)
+/**
+ * rpc_free - free buffer allocated via rpc_malloc
+ * @task: RPC task with a buffer to be freed
+ *
+ */
+void rpc_free(struct rpc_task *task)
 {
-	if (task->tk_buffer) {
-		if (task->tk_bufsize == RPC_BUFFER_MAXSIZE)
-			mempool_free(task->tk_buffer, rpc_buffer_mempool);
+	struct rpc_rqst *req = task->tk_rqstp;
+
+	if (req->rq_buffer) {
+		if (req->rq_bufsize == RPC_BUFFER_MAXSIZE)
+			mempool_free(req->rq_buffer, rpc_buffer_mempool);
 		else
-			kfree(task->tk_buffer);
-		task->tk_buffer = NULL;
-		task->tk_bufsize = 0;
+			kfree(req->rq_buffer);
+		req->rq_buffer = NULL;
+		req->rq_bufsize = 0;
 	}
 }
 
 /*
  * Creation and deletion of RPC task structures
  */
-void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action callback, int flags)
+void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata)
 {
 	memset(task, 0, sizeof(*task));
 	init_timer(&task->tk_timer);
 	task->tk_timer.data     = (unsigned long) task;
 	task->tk_timer.function = (void (*)(unsigned long)) rpc_run_timer;
+	atomic_set(&task->tk_count, 1);
 	task->tk_client = clnt;
 	task->tk_flags  = flags;
-	task->tk_exit   = callback;
+	task->tk_ops = tk_ops;
+	if (tk_ops->rpc_call_prepare != NULL)
+		task->tk_action = rpc_prepare_task;
+	task->tk_calldata = calldata;
 
 	/* Initialize retry counters */
 	task->tk_garb_retry = 2;
@@ -791,6 +816,8 @@
 	list_add_tail(&task->tk_task, &all_tasks);
 	spin_unlock(&rpc_sched_lock);
 
+	BUG_ON(task->tk_ops == NULL);
+
 	dprintk("RPC: %4d new task procpid %d\n", task->tk_pid,
 				current->pid);
 }
@@ -801,8 +828,7 @@
 	return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS);
 }
 
-static void
-rpc_default_free_task(struct rpc_task *task)
+static void rpc_free_task(struct rpc_task *task)
 {
 	dprintk("RPC: %4d freeing task\n", task->tk_pid);
 	mempool_free(task, rpc_task_mempool);
@@ -813,8 +839,7 @@
  * clean up after an allocation failure, as the client may
  * have specified "oneshot".
  */
-struct rpc_task *
-rpc_new_task(struct rpc_clnt *clnt, rpc_action callback, int flags)
+struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata)
 {
 	struct rpc_task	*task;
 
@@ -822,10 +847,7 @@
 	if (!task)
 		goto cleanup;
 
-	rpc_init_task(task, clnt, callback, flags);
-
-	/* Replace tk_release */
-	task->tk_release = rpc_default_free_task;
+	rpc_init_task(task, clnt, flags, tk_ops, calldata);
 
 	dprintk("RPC: %4d allocated task\n", task->tk_pid);
 	task->tk_flags |= RPC_TASK_DYNAMIC;
@@ -845,11 +867,15 @@
 
 void rpc_release_task(struct rpc_task *task)
 {
-	dprintk("RPC: %4d release task\n", task->tk_pid);
+	const struct rpc_call_ops *tk_ops = task->tk_ops;
+	void *calldata = task->tk_calldata;
 
 #ifdef RPC_DEBUG
 	BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID);
 #endif
+	if (!atomic_dec_and_test(&task->tk_count))
+		return;
+	dprintk("RPC: %4d release task\n", task->tk_pid);
 
 	/* Remove from global task list */
 	spin_lock(&rpc_sched_lock);
@@ -857,7 +883,6 @@
 	spin_unlock(&rpc_sched_lock);
 
 	BUG_ON (RPC_IS_QUEUED(task));
-	task->tk_active = 0;
 
 	/* Synchronously delete any running timer */
 	rpc_delete_timer(task);
@@ -867,7 +892,6 @@
 		xprt_release(task);
 	if (task->tk_msg.rpc_cred)
 		rpcauth_unbindcred(task);
-	rpc_free(task);
 	if (task->tk_client) {
 		rpc_release_client(task->tk_client);
 		task->tk_client = NULL;
@@ -876,11 +900,34 @@
 #ifdef RPC_DEBUG
 	task->tk_magic = 0;
 #endif
-	if (task->tk_release)
-		task->tk_release(task);
+	if (task->tk_flags & RPC_TASK_DYNAMIC)
+		rpc_free_task(task);
+	if (tk_ops->rpc_release)
+		tk_ops->rpc_release(calldata);
 }
 
 /**
+ * rpc_run_task - Allocate a new RPC task, then run rpc_execute against it
+ * @clnt - pointer to RPC client
+ * @flags - RPC flags
+ * @ops - RPC call ops
+ * @data - user call data
+ */
+struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
+					const struct rpc_call_ops *ops,
+					void *data)
+{
+	struct rpc_task *task;
+	task = rpc_new_task(clnt, flags, ops, data);
+	if (task == NULL)
+		return ERR_PTR(-ENOMEM);
+	atomic_inc(&task->tk_count);
+	rpc_execute(task);
+	return task;
+}
+EXPORT_SYMBOL(rpc_run_task);
+
+/**
  * rpc_find_parent - find the parent of a child task.
  * @child: child task
  *
@@ -890,12 +937,11 @@
  *
  * Caller must hold childq.lock
  */
-static inline struct rpc_task *rpc_find_parent(struct rpc_task *child)
+static inline struct rpc_task *rpc_find_parent(struct rpc_task *child, struct rpc_task *parent)
 {
-	struct rpc_task	*task, *parent;
+	struct rpc_task	*task;
 	struct list_head *le;
 
-	parent = (struct rpc_task *) child->tk_calldata;
 	task_for_each(task, le, &childq.tasks[0])
 		if (task == parent)
 			return parent;
@@ -903,18 +949,22 @@
 	return NULL;
 }
 
-static void rpc_child_exit(struct rpc_task *child)
+static void rpc_child_exit(struct rpc_task *child, void *calldata)
 {
 	struct rpc_task	*parent;
 
 	spin_lock_bh(&childq.lock);
-	if ((parent = rpc_find_parent(child)) != NULL) {
+	if ((parent = rpc_find_parent(child, calldata)) != NULL) {
 		parent->tk_status = child->tk_status;
 		__rpc_wake_up_task(parent);
 	}
 	spin_unlock_bh(&childq.lock);
 }
 
+static const struct rpc_call_ops rpc_child_ops = {
+	.rpc_call_done = rpc_child_exit,
+};
+
 /*
  * Note: rpc_new_task releases the client after a failure.
  */
@@ -923,11 +973,9 @@
 {
 	struct rpc_task	*task;
 
-	task = rpc_new_task(clnt, NULL, RPC_TASK_ASYNC | RPC_TASK_CHILD);
+	task = rpc_new_task(clnt, RPC_TASK_ASYNC | RPC_TASK_CHILD, &rpc_child_ops, parent);
 	if (!task)
 		goto fail;
-	task->tk_exit = rpc_child_exit;
-	task->tk_calldata = parent;
 	return task;
 
 fail:
@@ -1063,7 +1111,7 @@
 		return;
 	}
 	printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout "
-		"-rpcwait -action- --exit--\n");
+		"-rpcwait -action- ---ops--\n");
 	alltask_for_each(t, le, &all_tasks) {
 		const char *rpc_waitq = "none";
 
@@ -1078,7 +1126,7 @@
 			(t->tk_client ? t->tk_client->cl_prog : 0),
 			t->tk_rqstp, t->tk_timeout,
 			rpc_waitq,
-			t->tk_action, t->tk_exit);
+			t->tk_action, t->tk_ops);
 	}
 	spin_unlock(&rpc_sched_lock);
 }
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index a03d4b6..9f73732 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -30,8 +30,6 @@
 EXPORT_SYMBOL(rpc_sleep_on);
 EXPORT_SYMBOL(rpc_wake_up_next);
 EXPORT_SYMBOL(rpc_wake_up_task);
-EXPORT_SYMBOL(rpc_new_child);
-EXPORT_SYMBOL(rpc_run_child);
 EXPORT_SYMBOL(rpciod_down);
 EXPORT_SYMBOL(rpciod_up);
 EXPORT_SYMBOL(rpc_new_task);
@@ -45,7 +43,6 @@
 EXPORT_SYMBOL(rpc_bind_new_program);
 EXPORT_SYMBOL(rpc_destroy_client);
 EXPORT_SYMBOL(rpc_shutdown_client);
-EXPORT_SYMBOL(rpc_release_client);
 EXPORT_SYMBOL(rpc_killall_tasks);
 EXPORT_SYMBOL(rpc_call_sync);
 EXPORT_SYMBOL(rpc_call_async);
@@ -120,7 +117,6 @@
 
 /* Generic XDR */
 EXPORT_SYMBOL(xdr_encode_string);
-EXPORT_SYMBOL(xdr_decode_string);
 EXPORT_SYMBOL(xdr_decode_string_inplace);
 EXPORT_SYMBOL(xdr_decode_netobj);
 EXPORT_SYMBOL(xdr_encode_netobj);
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index cac2e77..3e6c694 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -101,10 +101,22 @@
 	}
 }
 
+#if IP_HASHBITS == 8
+/* hash_long on a 64 bit machine is currently REALLY BAD for
+ * IP addresses in reverse-endian (i.e. on a little-endian machine).
+ * So use a trivial but reliable hash instead
+ */
+static inline int hash_ip(unsigned long ip)
+{
+	int hash = ip ^ (ip>>16);
+	return (hash ^ (hash>>8)) & 0xff;
+}
+#endif
+
 static inline int ip_map_hash(struct ip_map *item)
 {
 	return hash_str(item->m_class, IP_HASHBITS) ^ 
-		hash_long((unsigned long)item->m_addr.s_addr, IP_HASHBITS);
+		hash_ip((unsigned long)item->m_addr.s_addr);
 }
 static inline int ip_map_match(struct ip_map *item, struct ip_map *tmp)
 {
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index c6a5191..e67613e 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -758,7 +758,7 @@
 	struct svc_serv	*serv = svsk->sk_server;
 	struct socket	*sock = svsk->sk_sock;
 	struct socket	*newsock;
-	struct proto_ops *ops;
+	const struct proto_ops *ops;
 	struct svc_sock	*newsvsk;
 	int		err, slen;
 
@@ -1026,7 +1026,7 @@
 	} else {
 		printk(KERN_NOTICE "%s: recvfrom returned errno %d\n",
 					svsk->sk_server->sv_name, -len);
-		svc_sock_received(svsk);
+		goto err_delete;
 	}
 
 	return len;
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index aaf08cdd..ca4bfa5 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -93,27 +93,6 @@
 }
 
 u32 *
-xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen)
-{
-	unsigned int	len;
-	char		*string;
-
-	if ((len = ntohl(*p++)) > maxlen)
-		return NULL;
-	if (lenp)
-		*lenp = len;
-	if ((len % 4) != 0) {
-		string = (char *) p;
-	} else {
-		string = (char *) (p - 1);
-		memmove(string, p, len);
-	}
-	string[len] = '\0';
-	*sp = string;
-	return p + XDR_QUADLEN(len);
-}
-
-u32 *
 xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen)
 {
 	unsigned int	len;
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 6dda386..8ff2c8a 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -119,6 +119,17 @@
 	return 0;
 }
 
+static void xprt_clear_locked(struct rpc_xprt *xprt)
+{
+	xprt->snd_task = NULL;
+	if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state) || xprt->shutdown) {
+		smp_mb__before_clear_bit();
+		clear_bit(XPRT_LOCKED, &xprt->state);
+		smp_mb__after_clear_bit();
+	} else
+		schedule_work(&xprt->task_cleanup);
+}
+
 /*
  * xprt_reserve_xprt_cong - serialize write access to transports
  * @task: task that is requesting access to the transport
@@ -145,9 +156,7 @@
 		}
 		return 1;
 	}
-	smp_mb__before_clear_bit();
-	clear_bit(XPRT_LOCKED, &xprt->state);
-	smp_mb__after_clear_bit();
+	xprt_clear_locked(xprt);
 out_sleep:
 	dprintk("RPC: %4d failed to lock transport %p\n", task->tk_pid, xprt);
 	task->tk_timeout = 0;
@@ -193,9 +202,7 @@
 	return;
 
 out_unlock:
-	smp_mb__before_clear_bit();
-	clear_bit(XPRT_LOCKED, &xprt->state);
-	smp_mb__after_clear_bit();
+	xprt_clear_locked(xprt);
 }
 
 static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt)
@@ -222,9 +229,7 @@
 		return;
 	}
 out_unlock:
-	smp_mb__before_clear_bit();
-	clear_bit(XPRT_LOCKED, &xprt->state);
-	smp_mb__after_clear_bit();
+	xprt_clear_locked(xprt);
 }
 
 /**
@@ -237,10 +242,7 @@
 void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
 {
 	if (xprt->snd_task == task) {
-		xprt->snd_task = NULL;
-		smp_mb__before_clear_bit();
-		clear_bit(XPRT_LOCKED, &xprt->state);
-		smp_mb__after_clear_bit();
+		xprt_clear_locked(xprt);
 		__xprt_lock_write_next(xprt);
 	}
 }
@@ -256,10 +258,7 @@
 void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task)
 {
 	if (xprt->snd_task == task) {
-		xprt->snd_task = NULL;
-		smp_mb__before_clear_bit();
-		clear_bit(XPRT_LOCKED, &xprt->state);
-		smp_mb__after_clear_bit();
+		xprt_clear_locked(xprt);
 		__xprt_lock_write_next_cong(xprt);
 	}
 }
@@ -535,10 +534,6 @@
 	dprintk("RPC: %4d xprt_connect xprt %p %s connected\n", task->tk_pid,
 			xprt, (xprt_connected(xprt) ? "is" : "is not"));
 
-	if (xprt->shutdown) {
-		task->tk_status = -EIO;
-		return;
-	}
 	if (!xprt->addr.sin_port) {
 		task->tk_status = -EIO;
 		return;
@@ -687,9 +682,6 @@
 
 	dprintk("RPC: %4d xprt_prepare_transmit\n", task->tk_pid);
 
-	if (xprt->shutdown)
-		return -EIO;
-
 	spin_lock_bh(&xprt->transport_lock);
 	if (req->rq_received && !req->rq_bytes_sent) {
 		err = req->rq_received;
@@ -814,11 +806,9 @@
 	struct rpc_xprt	*xprt = task->tk_xprt;
 
 	task->tk_status = -EIO;
-	if (!xprt->shutdown) {
-		spin_lock(&xprt->reserve_lock);
-		do_xprt_reserve(task);
-		spin_unlock(&xprt->reserve_lock);
-	}
+	spin_lock(&xprt->reserve_lock);
+	do_xprt_reserve(task);
+	spin_unlock(&xprt->reserve_lock);
 }
 
 static inline u32 xprt_alloc_xid(struct rpc_xprt *xprt)
@@ -838,6 +828,8 @@
 	req->rq_timeout = xprt->timeout.to_initval;
 	req->rq_task	= task;
 	req->rq_xprt    = xprt;
+	req->rq_buffer  = NULL;
+	req->rq_bufsize = 0;
 	req->rq_xid     = xprt_alloc_xid(xprt);
 	req->rq_release_snd_buf = NULL;
 	dprintk("RPC: %4d reserved req %p xid %08x\n", task->tk_pid,
@@ -863,10 +855,11 @@
 	if (!list_empty(&req->rq_list))
 		list_del(&req->rq_list);
 	xprt->last_used = jiffies;
-	if (list_empty(&xprt->recv) && !xprt->shutdown)
+	if (list_empty(&xprt->recv))
 		mod_timer(&xprt->timer,
 				xprt->last_used + xprt->idle_timeout);
 	spin_unlock_bh(&xprt->transport_lock);
+	xprt->ops->buf_free(task);
 	task->tk_rqstp = NULL;
 	if (req->rq_release_snd_buf)
 		req->rq_release_snd_buf(req);
@@ -974,16 +967,6 @@
 	return xprt;
 }
 
-static void xprt_shutdown(struct rpc_xprt *xprt)
-{
-	xprt->shutdown = 1;
-	rpc_wake_up(&xprt->sending);
-	rpc_wake_up(&xprt->resend);
-	xprt_wake_pending_tasks(xprt, -EIO);
-	rpc_wake_up(&xprt->backlog);
-	del_timer_sync(&xprt->timer);
-}
-
 /**
  * xprt_destroy - destroy an RPC transport, killing off all requests.
  * @xprt: transport to destroy
@@ -992,7 +975,8 @@
 int xprt_destroy(struct rpc_xprt *xprt)
 {
 	dprintk("RPC:      destroying transport %p\n", xprt);
-	xprt_shutdown(xprt);
+	xprt->shutdown = 1;
+	del_timer_sync(&xprt->timer);
 	xprt->ops->destroy(xprt);
 	kfree(xprt);
 
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 0a51fd4..c458f8d 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -28,6 +28,7 @@
 #include <linux/udp.h>
 #include <linux/tcp.h>
 #include <linux/sunrpc/clnt.h>
+#include <linux/sunrpc/sched.h>
 #include <linux/file.h>
 
 #include <net/sock.h>
@@ -424,7 +425,7 @@
 	struct sock *sk = xprt->inet;
 
 	if (!sk)
-		return;
+		goto clear_close_wait;
 
 	dprintk("RPC:      xs_close xprt %p\n", xprt);
 
@@ -441,6 +442,10 @@
 	sk->sk_no_check = 0;
 
 	sock_release(sock);
+clear_close_wait:
+	smp_mb__before_clear_bit();
+	clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
+	smp_mb__after_clear_bit();
 }
 
 /**
@@ -800,9 +805,13 @@
 	case TCP_SYN_SENT:
 	case TCP_SYN_RECV:
 		break;
+	case TCP_CLOSE_WAIT:
+		/* Try to schedule an autoclose RPC calls */
+		set_bit(XPRT_CLOSE_WAIT, &xprt->state);
+		if (test_and_set_bit(XPRT_LOCKED, &xprt->state) == 0)
+			schedule_work(&xprt->task_cleanup);
 	default:
 		xprt_disconnect(xprt);
-		break;
 	}
  out:
 	read_unlock(&sk->sk_callback_lock);
@@ -920,6 +929,18 @@
 	xprt_adjust_cwnd(task, -ETIMEDOUT);
 }
 
+/**
+ * xs_set_port - reset the port number in the remote endpoint address
+ * @xprt: generic transport
+ * @port: new port number
+ *
+ */
+static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
+{
+	dprintk("RPC:      setting port for xprt %p to %u\n", xprt, port);
+	xprt->addr.sin_port = htons(port);
+}
+
 static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
 {
 	struct sockaddr_in myaddr = {
@@ -990,6 +1011,7 @@
 		sk->sk_data_ready = xs_udp_data_ready;
 		sk->sk_write_space = xs_udp_write_space;
 		sk->sk_no_check = UDP_CSUM_NORCV;
+		sk->sk_allocation = GFP_ATOMIC;
 
 		xprt_set_connected(xprt);
 
@@ -1074,6 +1096,7 @@
 		sk->sk_data_ready = xs_tcp_data_ready;
 		sk->sk_state_change = xs_tcp_state_change;
 		sk->sk_write_space = xs_tcp_write_space;
+		sk->sk_allocation = GFP_ATOMIC;
 
 		/* socket options */
 		sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
@@ -1158,7 +1181,10 @@
 	.set_buffer_size	= xs_udp_set_buffer_size,
 	.reserve_xprt		= xprt_reserve_xprt_cong,
 	.release_xprt		= xprt_release_xprt_cong,
+	.set_port		= xs_set_port,
 	.connect		= xs_connect,
+	.buf_alloc		= rpc_malloc,
+	.buf_free		= rpc_free,
 	.send_request		= xs_udp_send_request,
 	.set_retrans_timeout	= xprt_set_retrans_timeout_rtt,
 	.timer			= xs_udp_timer,
@@ -1170,7 +1196,10 @@
 static struct rpc_xprt_ops xs_tcp_ops = {
 	.reserve_xprt		= xprt_reserve_xprt,
 	.release_xprt		= xprt_release_xprt,
+	.set_port		= xs_set_port,
 	.connect		= xs_connect,
+	.buf_alloc		= rpc_malloc,
+	.buf_free		= rpc_free,
 	.send_request		= xs_tcp_send_request,
 	.set_retrans_timeout	= xprt_set_retrans_timeout_def,
 	.close			= xs_close,
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index acc73ba..5f6ae79 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -121,7 +121,7 @@
 int sysctl_unix_max_dgram_qlen = 10;
 
 struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
-DEFINE_RWLOCK(unix_table_lock);
+DEFINE_SPINLOCK(unix_table_lock);
 static atomic_t unix_nr_socks = ATOMIC_INIT(0);
 
 #define unix_sockets_unbound	(&unix_socket_table[UNIX_HASH_SIZE])
@@ -130,7 +130,7 @@
 
 /*
  *  SMP locking strategy:
- *    hash table is protected with rwlock unix_table_lock
+ *    hash table is protected with spinlock unix_table_lock
  *    each socket state is protected by separate rwlock.
  */
 
@@ -214,16 +214,16 @@
 
 static inline void unix_remove_socket(struct sock *sk)
 {
-	write_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	__unix_remove_socket(sk);
-	write_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 }
 
 static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
 {
-	write_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	__unix_insert_socket(list, sk);
-	write_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 }
 
 static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
@@ -250,11 +250,11 @@
 {
 	struct sock *s;
 
-	read_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	s = __unix_find_socket_byname(sunname, len, type, hash);
 	if (s)
 		sock_hold(s);
-	read_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 	return s;
 }
 
@@ -263,7 +263,7 @@
 	struct sock *s;
 	struct hlist_node *node;
 
-	read_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	sk_for_each(s, node,
 		    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
 		struct dentry *dentry = unix_sk(s)->dentry;
@@ -276,7 +276,7 @@
 	}
 	s = NULL;
 found:
-	read_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 	return s;
 }
 
@@ -473,7 +473,7 @@
 static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
 				  struct msghdr *, size_t);
 
-static struct proto_ops unix_stream_ops = {
+static const struct proto_ops unix_stream_ops = {
 	.family =	PF_UNIX,
 	.owner =	THIS_MODULE,
 	.release =	unix_release,
@@ -494,7 +494,7 @@
 	.sendpage =	sock_no_sendpage,
 };
 
-static struct proto_ops unix_dgram_ops = {
+static const struct proto_ops unix_dgram_ops = {
 	.family =	PF_UNIX,
 	.owner =	THIS_MODULE,
 	.release =	unix_release,
@@ -515,7 +515,7 @@
 	.sendpage =	sock_no_sendpage,
 };
 
-static struct proto_ops unix_seqpacket_ops = {
+static const struct proto_ops unix_seqpacket_ops = {
 	.family =	PF_UNIX,
 	.owner =	THIS_MODULE,
 	.release =	unix_release,
@@ -564,7 +564,7 @@
 	u	  = unix_sk(sk);
 	u->dentry = NULL;
 	u->mnt	  = NULL;
-	rwlock_init(&u->lock);
+	spin_lock_init(&u->lock);
 	atomic_set(&u->inflight, sock ? 0 : -1);
 	init_MUTEX(&u->readsem); /* single task reading lock */
 	init_waitqueue_head(&u->peer_wait);
@@ -642,12 +642,12 @@
 	addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
 	addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0));
 
-	write_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	ordernum = (ordernum+1)&0xFFFFF;
 
 	if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
 				      addr->hash)) {
-		write_unlock(&unix_table_lock);
+		spin_unlock(&unix_table_lock);
 		/* Sanity yield. It is unusual case, but yet... */
 		if (!(ordernum&0xFF))
 			yield();
@@ -658,7 +658,7 @@
 	__unix_remove_socket(sk);
 	u->addr = addr;
 	__unix_insert_socket(&unix_socket_table[addr->hash], sk);
-	write_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 	err = 0;
 
 out:	up(&u->readsem);
@@ -791,7 +791,7 @@
 		addr->hash = UNIX_HASH_SIZE;
 	}
 
-	write_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 
 	if (!sunaddr->sun_path[0]) {
 		err = -EADDRINUSE;
@@ -814,7 +814,7 @@
 	__unix_insert_socket(list, sk);
 
 out_unlock:
-	write_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 out_up:
 	up(&u->readsem);
 out:
@@ -1063,10 +1063,12 @@
 	/* Set credentials */
 	sk->sk_peercred = other->sk_peercred;
 
-	sock_hold(newsk);
-	unix_peer(sk)	= newsk;
 	sock->state	= SS_CONNECTED;
 	sk->sk_state	= TCP_ESTABLISHED;
+	sock_hold(newsk);
+
+	smp_mb__after_atomic_inc();	/* sock_hold() does an atomic_inc() */
+	unix_peer(sk)	= newsk;
 
 	unix_state_wunlock(sk);
 
@@ -1414,7 +1416,7 @@
 	} else {
 		sunaddr = NULL;
 		err = -ENOTCONN;
-		other = unix_peer_get(sk);
+		other = unix_peer(sk);
 		if (!other)
 			goto out_err;
 	}
@@ -1476,7 +1478,6 @@
 		other->sk_data_ready(other, size);
 		sent+=size;
 	}
-	sock_put(other);
 
 	scm_destroy(siocb->scm);
 	siocb->scm = NULL;
@@ -1491,8 +1492,6 @@
 		send_sig(SIGPIPE,current,0);
 	err = -EPIPE;
 out_err:
-        if (other)
-		sock_put(other);
 	scm_destroy(siocb->scm);
 	siocb->scm = NULL;
 	return sent ? : err;
@@ -1860,7 +1859,7 @@
 		}
 
 		default:
-			err = dev_ioctl(cmd, (void __user *)arg);
+			err = -ENOIOCTLCMD;
 			break;
 	}
 	return err;
@@ -1917,7 +1916,7 @@
 
 static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
 {
-	read_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 	return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
 }
 
@@ -1932,7 +1931,7 @@
 
 static void unix_seq_stop(struct seq_file *seq, void *v)
 {
-	read_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 }
 
 static int unix_seq_show(struct seq_file *seq, void *v)
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 6ffc64e..411802b 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -182,7 +182,7 @@
 	if (down_trylock(&unix_gc_sem))
 		return;
 
-	read_lock(&unix_table_lock);
+	spin_lock(&unix_table_lock);
 
 	forall_unix_sockets(i, s)
 	{
@@ -301,7 +301,7 @@
 		}
 		u->gc_tree = GC_ORPHAN;
 	}
-	read_unlock(&unix_table_lock);
+	spin_unlock(&unix_table_lock);
 
 	/*
 	 *	Here we are. Hitlist is filled. Die.
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
index 59fec59..7a43ae4 100644
--- a/net/wanrouter/af_wanpipe.c
+++ b/net/wanrouter/af_wanpipe.c
@@ -181,7 +181,7 @@
 #endif
 
 static int sk_count;
-extern struct proto_ops wanpipe_ops;
+extern const struct proto_ops wanpipe_ops;
 static unsigned long find_free_critical;
 
 static void wanpipe_unlink_driver(struct sock *sk);
@@ -1839,7 +1839,7 @@
 #endif
 
 		default:
-			return dev_ioctl(cmd,(void __user *) arg);
+			return -ENOIOCTLCMD;
 	}
 	/*NOTREACHED*/
 }
@@ -2546,7 +2546,7 @@
 	return 0;
 }
 
-struct proto_ops wanpipe_ops = {
+const struct proto_ops wanpipe_ops = {
 	.family = 	PF_WANPIPE,
 	.owner =	THIS_MODULE,
 	.release = 	wanpipe_release,
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 020d73c..bfabaf9 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -64,7 +64,7 @@
 HLIST_HEAD(x25_list);
 DEFINE_RWLOCK(x25_list_lock);
 
-static struct proto_ops x25_proto_ops;
+static const struct proto_ops x25_proto_ops;
 
 static struct x25_address null_x25_address = {"               "};
 
@@ -540,12 +540,7 @@
 	sk->sk_state       = TCP_ESTABLISHED;
 	sk->sk_sleep       = osk->sk_sleep;
 	sk->sk_backlog_rcv = osk->sk_backlog_rcv;
-
-	if (sock_flag(osk, SOCK_ZAPPED))
-		sock_set_flag(sk, SOCK_ZAPPED);
-	
-	if (sock_flag(osk, SOCK_DBG))
-		sock_set_flag(sk, SOCK_DBG);
+	sock_copy_flags(sk, osk);
 
 	ox25 = x25_sk(osk);
 	x25->t21        = ox25->t21;
@@ -1378,7 +1373,7 @@
 		}
 
  		default:
-			rc = dev_ioctl(cmd, argp);
+			rc = -ENOIOCTLCMD;
 			break;
 	}
 
@@ -1391,7 +1386,7 @@
 	.owner	=	THIS_MODULE,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
 	.family =	AF_X25,
 	.owner =	THIS_MODULE,
 	.release =	x25_release,
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 0db9e57..59614a9 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -10,7 +10,7 @@
  * 	YOSHIFUJI Hideaki
  * 		Split up af-specific portion
  *	Derek Atkins <derek@ihtfp.com>		Add the post_input processor
- * 	
+ *
  */
 
 #include <asm/bug.h>
@@ -22,6 +22,7 @@
 #include <linux/workqueue.h>
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
+#include <linux/netfilter.h>
 #include <linux/module.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
@@ -256,6 +257,7 @@
 	if (del_timer(&policy->timer))
 		BUG();
 
+	security_xfrm_policy_free(policy);
 	kfree(policy);
 }
 EXPORT_SYMBOL(__xfrm_policy_destroy);
@@ -346,10 +348,12 @@
 	struct xfrm_policy *pol, **p;
 	struct xfrm_policy *delpol = NULL;
 	struct xfrm_policy **newpos = NULL;
+	struct dst_entry *gc_list;
 
 	write_lock_bh(&xfrm_policy_lock);
 	for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL;) {
-		if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0) {
+		if (!delpol && memcmp(&policy->selector, &pol->selector, sizeof(pol->selector)) == 0 &&
+		    xfrm_sec_ctx_match(pol->security, policy->security)) {
 			if (excl) {
 				write_unlock_bh(&xfrm_policy_lock);
 				return -EEXIST;
@@ -381,21 +385,49 @@
 		xfrm_pol_hold(policy);
 	write_unlock_bh(&xfrm_policy_lock);
 
-	if (delpol) {
+	if (delpol)
 		xfrm_policy_kill(delpol);
+
+	read_lock_bh(&xfrm_policy_lock);
+	gc_list = NULL;
+	for (policy = policy->next; policy; policy = policy->next) {
+		struct dst_entry *dst;
+
+		write_lock(&policy->lock);
+		dst = policy->bundles;
+		if (dst) {
+			struct dst_entry *tail = dst;
+			while (tail->next)
+				tail = tail->next;
+			tail->next = gc_list;
+			gc_list = dst;
+
+			policy->bundles = NULL;
+		}
+		write_unlock(&policy->lock);
 	}
+	read_unlock_bh(&xfrm_policy_lock);
+
+	while (gc_list) {
+		struct dst_entry *dst = gc_list;
+
+		gc_list = dst->next;
+		dst_free(dst);
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL(xfrm_policy_insert);
 
-struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,
-				      int delete)
+struct xfrm_policy *xfrm_policy_bysel_ctx(int dir, struct xfrm_selector *sel,
+					  struct xfrm_sec_ctx *ctx, int delete)
 {
 	struct xfrm_policy *pol, **p;
 
 	write_lock_bh(&xfrm_policy_lock);
 	for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
-		if (memcmp(sel, &pol->selector, sizeof(*sel)) == 0) {
+		if ((memcmp(sel, &pol->selector, sizeof(*sel)) == 0) &&
+		    (xfrm_sec_ctx_match(ctx, pol->security))) {
 			xfrm_pol_hold(pol);
 			if (delete)
 				*p = pol->next;
@@ -410,7 +442,7 @@
 	}
 	return pol;
 }
-EXPORT_SYMBOL(xfrm_policy_bysel);
+EXPORT_SYMBOL(xfrm_policy_bysel_ctx);
 
 struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete)
 {
@@ -491,7 +523,7 @@
 
 /* Find policy to apply to this flow. */
 
-static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
+static void xfrm_policy_lookup(struct flowi *fl, u32 sk_sid, u16 family, u8 dir,
 			       void **objp, atomic_t **obj_refp)
 {
 	struct xfrm_policy *pol;
@@ -505,9 +537,12 @@
 			continue;
 
 		match = xfrm_selector_match(sel, fl, family);
+
 		if (match) {
-			xfrm_pol_hold(pol);
-			break;
+ 			if (!security_xfrm_policy_lookup(pol, sk_sid, dir)) {
+				xfrm_pol_hold(pol);
+				break;
+			}
 		}
 	}
 	read_unlock_bh(&xfrm_policy_lock);
@@ -515,15 +550,37 @@
 		*obj_refp = &pol->refcnt;
 }
 
-static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl)
+static inline int policy_to_flow_dir(int dir)
+{
+	if (XFRM_POLICY_IN == FLOW_DIR_IN &&
+ 	    XFRM_POLICY_OUT == FLOW_DIR_OUT &&
+ 	    XFRM_POLICY_FWD == FLOW_DIR_FWD)
+ 		return dir;
+ 	switch (dir) {
+ 	default:
+ 	case XFRM_POLICY_IN:
+ 		return FLOW_DIR_IN;
+ 	case XFRM_POLICY_OUT:
+ 		return FLOW_DIR_OUT;
+ 	case XFRM_POLICY_FWD:
+ 		return FLOW_DIR_FWD;
+	};
+}
+
+static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl, u32 sk_sid)
 {
 	struct xfrm_policy *pol;
 
 	read_lock_bh(&xfrm_policy_lock);
 	if ((pol = sk->sk_policy[dir]) != NULL) {
-		int match = xfrm_selector_match(&pol->selector, fl,
+ 		int match = xfrm_selector_match(&pol->selector, fl,
 						sk->sk_family);
+ 		int err = 0;
+
 		if (match)
+		  err = security_xfrm_policy_lookup(pol, sk_sid, policy_to_flow_dir(dir));
+
+ 		if (match && !err)
 			xfrm_pol_hold(pol);
 		else
 			pol = NULL;
@@ -596,6 +653,10 @@
 
 	if (newp) {
 		newp->selector = old->selector;
+		if (security_xfrm_policy_clone(old, newp)) {
+			kfree(newp);
+			return NULL;  /* ENOMEM */
+		}
 		newp->lft = old->lft;
 		newp->curlft = old->curlft;
 		newp->action = old->action;
@@ -707,22 +768,6 @@
 	return err;
 }
 
-static inline int policy_to_flow_dir(int dir)
-{
-	if (XFRM_POLICY_IN == FLOW_DIR_IN &&
-	    XFRM_POLICY_OUT == FLOW_DIR_OUT &&
-	    XFRM_POLICY_FWD == FLOW_DIR_FWD)
-		return dir;
-	switch (dir) {
-	default:
-	case XFRM_POLICY_IN:
-		return FLOW_DIR_IN;
-	case XFRM_POLICY_OUT:
-		return FLOW_DIR_OUT;
-	case XFRM_POLICY_FWD:
-		return FLOW_DIR_FWD;
-	};
-}
 
 static int stale_bundle(struct dst_entry *dst);
 
@@ -741,19 +786,20 @@
 	int err;
 	u32 genid;
 	u16 family = dst_orig->ops->family;
+	u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT);
+	u32 sk_sid = security_sk_sid(sk, fl, dir);
 restart:
 	genid = atomic_read(&flow_cache_genid);
 	policy = NULL;
 	if (sk && sk->sk_policy[1])
-		policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
+		policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl, sk_sid);
 
 	if (!policy) {
 		/* To accelerate a bit...  */
 		if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT])
 			return 0;
 
-		policy = flow_cache_lookup(fl, family,
-					   policy_to_flow_dir(XFRM_POLICY_OUT),
+		policy = flow_cache_lookup(fl, sk_sid, family, dir,
 					   xfrm_policy_lookup);
 	}
 
@@ -906,8 +952,8 @@
 	return start;
 }
 
-static int
-_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family)
+int
+xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family)
 {
 	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
 
@@ -918,6 +964,7 @@
 	xfrm_policy_put_afinfo(afinfo);
 	return 0;
 }
+EXPORT_SYMBOL(xfrm_decode_session);
 
 static inline int secpath_has_tunnel(struct sec_path *sp, int k)
 {
@@ -934,16 +981,21 @@
 {
 	struct xfrm_policy *pol;
 	struct flowi fl;
+	u8 fl_dir = policy_to_flow_dir(dir);
+	u32 sk_sid;
 
-	if (_decode_session(skb, &fl, family) < 0)
+	if (xfrm_decode_session(skb, &fl, family) < 0)
 		return 0;
+	nf_nat_decode_session(skb, &fl, family);
+
+	sk_sid = security_sk_sid(sk, &fl, fl_dir);
 
 	/* First, check used SA against their selectors. */
 	if (skb->sp) {
 		int i;
 
 		for (i=skb->sp->len-1; i>=0; i--) {
-		  struct sec_decap_state *xvec = &(skb->sp->x[i]);
+			struct sec_decap_state *xvec = &(skb->sp->x[i]);
 			if (!xfrm_selector_match(&xvec->xvec->sel, &fl, family))
 				return 0;
 
@@ -958,11 +1010,10 @@
 
 	pol = NULL;
 	if (sk && sk->sk_policy[dir])
-		pol = xfrm_sk_policy_lookup(sk, dir, &fl);
+		pol = xfrm_sk_policy_lookup(sk, dir, &fl, sk_sid);
 
 	if (!pol)
-		pol = flow_cache_lookup(&fl, family,
-					policy_to_flow_dir(dir),
+		pol = flow_cache_lookup(&fl, sk_sid, family, fl_dir,
 					xfrm_policy_lookup);
 
 	if (!pol)
@@ -1007,20 +1058,19 @@
 {
 	struct flowi fl;
 
-	if (_decode_session(skb, &fl, family) < 0)
+	if (xfrm_decode_session(skb, &fl, family) < 0)
 		return 0;
 
 	return xfrm_lookup(&skb->dst, &fl, NULL, 0) == 0;
 }
 EXPORT_SYMBOL(__xfrm_route_forward);
 
-/* Optimize later using cookies and generation ids. */
-
 static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie)
 {
-	if (!stale_bundle(dst))
-		return dst;
-
+	/* If it is marked obsolete, which is how we even get here,
+	 * then we have purged it from the policy bundle list and we
+	 * did that for a good reason.
+	 */
 	return NULL;
 }
 
@@ -1104,6 +1154,16 @@
 	return 0;
 }
 
+static int always_true(struct dst_entry *dst)
+{
+	return 1;
+}
+
+void xfrm_flush_all_bundles(void)
+{
+	xfrm_prune_bundles(always_true);
+}
+
 void xfrm_init_pmtu(struct dst_entry *dst)
 {
 	do {
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 7cf48aa..e12d0be 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -10,7 +10,7 @@
  * 		Split up af-specific functions
  *	Derek Atkins <derek@ihtfp.com>
  *		Add UDP Encapsulation
- * 	
+ *
  */
 
 #include <linux/workqueue.h>
@@ -70,6 +70,7 @@
 		x->type->destructor(x);
 		xfrm_put_type(x->type);
 	}
+	security_xfrm_state_free(x);
 	kfree(x);
 }
 
@@ -343,7 +344,8 @@
 			      selector.
 			 */
 			if (x->km.state == XFRM_STATE_VALID) {
-				if (!xfrm_selector_match(&x->sel, fl, family))
+				if (!xfrm_selector_match(&x->sel, fl, family) ||
+				    !xfrm_sec_ctx_match(pol->security, x->security))
 					continue;
 				if (!best ||
 				    best->km.dying > x->km.dying ||
@@ -354,7 +356,8 @@
 				acquire_in_progress = 1;
 			} else if (x->km.state == XFRM_STATE_ERROR ||
 				   x->km.state == XFRM_STATE_EXPIRED) {
-				if (xfrm_selector_match(&x->sel, fl, family))
+ 				if (xfrm_selector_match(&x->sel, fl, family) &&
+				    xfrm_sec_ctx_match(pol->security, x->security))
 					error = -ESRCH;
 			}
 		}
@@ -431,6 +434,8 @@
 	spin_lock_bh(&xfrm_state_lock);
 	__xfrm_state_insert(x);
 	spin_unlock_bh(&xfrm_state_lock);
+
+	xfrm_flush_all_bundles();
 }
 EXPORT_SYMBOL(xfrm_state_insert);
 
@@ -478,6 +483,9 @@
 	spin_unlock_bh(&xfrm_state_lock);
 	xfrm_state_put_afinfo(afinfo);
 
+	if (!err)
+		xfrm_flush_all_bundles();
+
 	if (x1) {
 		xfrm_state_delete(x1);
 		xfrm_state_put(x1);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 0cdd9a0..ac87a09 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -7,7 +7,7 @@
  * 	Kazunori MIYAZAWA @USAGI
  * 	Kunihiro Ishiguro <kunihiro@ipinfusion.com>
  * 		IPv6 support
- * 	
+ *
  */
 
 #include <linux/module.h>
@@ -88,6 +88,34 @@
 	return 0;
 }
 
+
+static inline int verify_sec_ctx_len(struct rtattr **xfrma)
+{
+	struct rtattr *rt = xfrma[XFRMA_SEC_CTX - 1];
+	struct xfrm_user_sec_ctx *uctx;
+	int len = 0;
+
+	if (!rt)
+		return 0;
+
+	if (rt->rta_len < sizeof(*uctx))
+		return -EINVAL;
+
+	uctx = RTA_DATA(rt);
+
+	if (uctx->ctx_len > PAGE_SIZE)
+		return -EINVAL;
+
+	len += sizeof(struct xfrm_user_sec_ctx);
+	len += uctx->ctx_len;
+
+	if (uctx->len != len)
+		return -EINVAL;
+
+	return 0;
+}
+
+
 static int verify_newsa_info(struct xfrm_usersa_info *p,
 			     struct rtattr **xfrma)
 {
@@ -145,6 +173,8 @@
 		goto out;
 	if ((err = verify_encap_tmpl(xfrma)))
 		goto out;
+	if ((err = verify_sec_ctx_len(xfrma)))
+		goto out;
 
 	err = -EINVAL;
 	switch (p->mode) {
@@ -209,6 +239,30 @@
 	return 0;
 }
 
+
+static inline int xfrm_user_sec_ctx_size(struct xfrm_policy *xp)
+{
+	struct xfrm_sec_ctx *xfrm_ctx = xp->security;
+	int len = 0;
+
+	if (xfrm_ctx) {
+		len += sizeof(struct xfrm_user_sec_ctx);
+		len += xfrm_ctx->ctx_len;
+	}
+	return len;
+}
+
+static int attach_sec_ctx(struct xfrm_state *x, struct rtattr *u_arg)
+{
+	struct xfrm_user_sec_ctx *uctx;
+
+	if (!u_arg)
+		return 0;
+
+	uctx = RTA_DATA(u_arg);
+	return security_xfrm_state_alloc(x, uctx);
+}
+
 static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *p)
 {
 	memcpy(&x->id, &p->id, sizeof(x->id));
@@ -253,6 +307,9 @@
 	if (err)
 		goto error;
 
+	if ((err = attach_sec_ctx(x, xfrma[XFRMA_SEC_CTX-1])))
+		goto error;
+
 	x->km.seq = p->seq;
 
 	return x;
@@ -272,11 +329,11 @@
 	int err;
 	struct km_event c;
 
-	err = verify_newsa_info(p, (struct rtattr **) xfrma);
+	err = verify_newsa_info(p, (struct rtattr **)xfrma);
 	if (err)
 		return err;
 
-	x = xfrm_state_construct(p, (struct rtattr **) xfrma, &err);
+	x = xfrm_state_construct(p, (struct rtattr **)xfrma, &err);
 	if (!x)
 		return err;
 
@@ -390,6 +447,19 @@
 	if (x->encap)
 		RTA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
 
+	if (x->security) {
+		int ctx_size = sizeof(struct xfrm_sec_ctx) +
+				x->security->ctx_len;
+		struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
+		struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+
+		uctx->exttype = XFRMA_SEC_CTX;
+		uctx->len = ctx_size;
+		uctx->ctx_doi = x->security->ctx_doi;
+		uctx->ctx_alg = x->security->ctx_alg;
+		uctx->ctx_len = x->security->ctx_len;
+		memcpy(uctx + 1, x->security->ctx_str, x->security->ctx_len);
+	}
 	nlh->nlmsg_len = skb->tail - b;
 out:
 	sp->this_idx++;
@@ -603,6 +673,18 @@
 	return verify_policy_dir(p->dir);
 }
 
+static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct rtattr **xfrma)
+{
+	struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
+	struct xfrm_user_sec_ctx *uctx;
+
+	if (!rt)
+		return 0;
+
+	uctx = RTA_DATA(rt);
+	return security_xfrm_policy_alloc(pol, uctx);
+}
+
 static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
 			   int nr)
 {
@@ -681,7 +763,10 @@
 	}
 
 	copy_from_user_policy(xp, p);
-	err = copy_from_user_tmpl(xp, xfrma);
+
+	if (!(err = copy_from_user_tmpl(xp, xfrma)))
+		err = copy_from_user_sec_ctx(xp, xfrma);
+
 	if (err) {
 		*errp = err;
 		kfree(xp);
@@ -702,8 +787,11 @@
 	err = verify_newpolicy_info(p);
 	if (err)
 		return err;
+	err = verify_sec_ctx_len((struct rtattr **)xfrma);
+	if (err)
+		return err;
 
-	xp = xfrm_policy_construct(p, (struct rtattr **) xfrma, &err);
+	xp = xfrm_policy_construct(p, (struct rtattr **)xfrma, &err);
 	if (!xp)
 		return err;
 
@@ -714,6 +802,7 @@
 	excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY;
 	err = xfrm_policy_insert(p->dir, xp, excl);
 	if (err) {
+		security_xfrm_policy_free(xp);
 		kfree(xp);
 		return err;
 	}
@@ -761,6 +850,27 @@
 	return -1;
 }
 
+static int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *skb)
+{
+	if (xp->security) {
+		int ctx_size = sizeof(struct xfrm_sec_ctx) +
+				xp->security->ctx_len;
+		struct rtattr *rt = __RTA_PUT(skb, XFRMA_SEC_CTX, ctx_size);
+		struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+
+		uctx->exttype = XFRMA_SEC_CTX;
+		uctx->len = ctx_size;
+		uctx->ctx_doi = xp->security->ctx_doi;
+		uctx->ctx_alg = xp->security->ctx_alg;
+		uctx->ctx_len = xp->security->ctx_len;
+		memcpy(uctx + 1, xp->security->ctx_str, xp->security->ctx_len);
+	}
+	return 0;
+
+ rtattr_failure:
+	return -1;
+}
+
 static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr)
 {
 	struct xfrm_dump_info *sp = ptr;
@@ -782,6 +892,8 @@
 	copy_to_user_policy(xp, p, dir);
 	if (copy_to_user_tmpl(xp, skb) < 0)
 		goto nlmsg_failure;
+	if (copy_to_user_sec_ctx(xp, skb))
+		goto nlmsg_failure;
 
 	nlh->nlmsg_len = skb->tail - b;
 out:
@@ -852,8 +964,25 @@
 
 	if (p->index)
 		xp = xfrm_policy_byid(p->dir, p->index, delete);
-	else
-		xp = xfrm_policy_bysel(p->dir, &p->sel, delete);
+	else {
+		struct rtattr **rtattrs = (struct rtattr **)xfrma;
+		struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
+		struct xfrm_policy tmp;
+
+		err = verify_sec_ctx_len(rtattrs);
+		if (err)
+			return err;
+
+		memset(&tmp, 0, sizeof(struct xfrm_policy));
+		if (rt) {
+			struct xfrm_user_sec_ctx *uctx = RTA_DATA(rt);
+
+			if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
+				return err;
+		}
+		xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete);
+		security_xfrm_policy_free(&tmp);
+	}
 	if (xp == NULL)
 		return -ENOENT;
 
@@ -1224,6 +1353,8 @@
 
 	if (copy_to_user_tmpl(xp, skb) < 0)
 		goto nlmsg_failure;
+	if (copy_to_user_sec_ctx(xp, skb))
+		goto nlmsg_failure;
 
 	nlh->nlmsg_len = skb->tail - b;
 	return skb->len;
@@ -1241,6 +1372,7 @@
 
 	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	len += NLMSG_SPACE(sizeof(struct xfrm_user_acquire));
+	len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
@@ -1324,6 +1456,8 @@
 	copy_to_user_policy(xp, &upe->pol, dir);
 	if (copy_to_user_tmpl(xp, skb) < 0)
 		goto nlmsg_failure;
+	if (copy_to_user_sec_ctx(xp, skb))
+		goto nlmsg_failure;
 	upe->hard = !!hard;
 
 	nlh->nlmsg_len = skb->tail - b;
@@ -1341,6 +1475,7 @@
 
 	len = RTA_SPACE(sizeof(struct xfrm_user_tmpl) * xp->xfrm_nr);
 	len += NLMSG_SPACE(sizeof(struct xfrm_user_polexpire));
+	len += RTA_SPACE(xfrm_user_sec_ctx_size(xp));
 	skb = alloc_skb(len, GFP_ATOMIC);
 	if (skb == NULL)
 		return -ENOMEM;
diff --git a/scripts/.gitignore b/scripts/.gitignore
index b46d68b..a234e52 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -1,4 +1,7 @@
+#
+# Generated files
+#
 conmakehash
 kallsyms
 pnmtologo
-
+bin2c
diff --git a/scripts/Makefile b/scripts/Makefile
index 67763ee..6f6b48f 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -19,4 +19,4 @@
 subdir-$(CONFIG_MODULES)     += mod
 
 # Let clean descend into subdirs
-subdir-	+= basic lxdialog kconfig package
+subdir-	+= basic kconfig package
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 0f81dcf..550798f 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -81,8 +81,10 @@
 # Note: It's possible that one object gets potentially linked into more
 #       than one module. In that case KBUILD_MODNAME will be set to foo_bar,
 #       where foo and bar are the name of the modules.
-basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
-modname_flags  = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))))
+name-fix = $(subst $(comma),_,$(subst -,_,$1))
+basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(*F)))"
+modname_flags  = $(if $(filter 1,$(words $(modname))),\
+                 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
 
 _c_flags       = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o)
 _a_flags       = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
@@ -113,7 +115,7 @@
 
 c_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
 		 $(__c_flags) $(modkern_cflags) \
-		 $(basename_flags) $(modname_flags)
+		 -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
 
 a_flags        = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(CPPFLAGS) \
 		 $(__a_flags) $(modkern_aflags)
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index 0b61bea..679124b 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -130,9 +130,22 @@
 	exit(1);
 }
 
+/*
+ * Print out the commandline prefixed with cmd_<target filename> :=
+ * If commandline contains '#' escape with '\' so make to not see
+ * the '#' as a start-of-comment symbol
+ **/
 void print_cmdline(void)
 {
-	printf("cmd_%s := %s\n\n", target, cmdline);
+	char *p = cmdline;
+
+	printf("cmd_%s := ", target);
+	for (; *p; p++) {
+		if (*p == '#')
+			printf("\\");
+		printf("%c", *p);
+	}
+	printf("\n\n");
 }
 
 char * str_config  = NULL;
diff --git a/scripts/binoffset.c b/scripts/binoffset.c
index 591309d..1a2e39b 100644
--- a/scripts/binoffset.c
+++ b/scripts/binoffset.c
@@ -1,6 +1,6 @@
 /***************************************************************************
  * binoffset.c
- * (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+ * (C) 2002 Randy Dunlap <rdunlap@xenotime.net>
 
 #   This program is free software; you can redistribute it and/or modify
 #   it under the terms of the GNU General Public License as published by
diff --git a/scripts/bloat-o-meter b/scripts/bloat-o-meter
new file mode 100644
index 0000000..75f21d8
--- /dev/null
+++ b/scripts/bloat-o-meter
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+#
+# Copyright 2004 Matt Mackall <mpm@selenic.com>
+#
+# inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
+#
+# This software may be used and distributed according to the terms
+# of the GNU General Public License, incorporated herein by reference.
+
+import sys, os, re
+
+if len(sys.argv) != 3:
+    sys.stderr.write("usage: %s file1 file2\n" % sys.argv[0])
+    sys.exit(-1)
+
+def getsizes(file):
+    sym = {}
+    for l in os.popen("nm --size-sort " + file).readlines():
+        size, type, name = l[:-1].split()
+        if type in "tTdDbB":
+            sym[name] = int(size, 16)
+    return sym
+
+old = getsizes(sys.argv[1])
+new = getsizes(sys.argv[2])
+grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
+delta, common = [], {}
+
+for a in old:
+    if a in new:
+        common[a] = 1
+
+for name in old:
+    if name not in common:
+        remove += 1
+        down += old[name]
+        delta.append((-old[name], name))
+
+for name in new:
+    if name not in common:
+        add += 1
+        up += new[name]
+        delta.append((new[name], name))
+
+for name in common:
+        d = new.get(name, 0) - old.get(name, 0)
+        if d>0: grow, up = grow+1, up+d
+        if d<0: shrink, down = shrink+1, down-d
+        delta.append((d, name))
+
+delta.sort()
+delta.reverse()
+
+print "add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s (%s)" % \
+      (add, remove, grow, shrink, up, -down, up-down)
+print "%-40s %7s %7s %+7s" % ("function", "old", "new", "delta")
+for d, n in delta:
+    if d: print "%-40s %7s %7s %+7d" % (n, old.get(n,"-"), new.get(n,"-"), d)
diff --git a/scripts/checkversion.pl b/scripts/checkversion.pl
index df10db6..9f84e56 100755
--- a/scripts/checkversion.pl
+++ b/scripts/checkversion.pl
@@ -3,7 +3,7 @@
 # checkversion find uses of LINUX_VERSION_CODE, KERNEL_VERSION, or
 # UTS_RELEASE without including <linux/version.h>, or cases of
 # including <linux/version.h> that don't need it.
-# Copyright (C) 2003, Randy Dunlap <rddunlap@osdl.org>
+# Copyright (C) 2003, Randy Dunlap <rdunlap@xenotime.net>
 
 $| = 1;
 
diff --git a/scripts/genksyms/.gitignore b/scripts/genksyms/.gitignore
new file mode 100644
index 0000000..be5cadb
--- /dev/null
+++ b/scripts/genksyms/.gitignore
@@ -0,0 +1,4 @@
+keywords.c
+lex.c
+parse.[ch]
+genksyms
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
index eabaf74..ee46478 100644
--- a/scripts/genksyms/keywords.c_shipped
+++ b/scripts/genksyms/keywords.c_shipped
@@ -1,7 +1,38 @@
-/* ANSI-C code produced by gperf version 2.7.2 */
+/* ANSI-C code produced by gperf version 3.0.1 */
 /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf  */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646.  */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+#line 1 "scripts/genksyms/keywords.gperf"
+
+#line 3 "scripts/genksyms/keywords.gperf"
 struct resword { const char *name; int token; };
-/* maximum key range = 109, duplicates = 0 */
+/* maximum key range = 68, duplicates = 0 */
 
 #ifdef __GNUC__
 __inline
@@ -15,32 +46,32 @@
 {
   static const unsigned char asso_values[] =
     {
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113,   5,
-      113, 113, 113, 113, 113, 113,   0, 113, 113, 113,
-        0, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113,   0, 113,   0, 113,  20,
-       25,   0,  35,  30, 113,  20, 113, 113,  40,  30,
-       30,   0,   0, 113,   0,  51,   0,  15,   5, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113, 113, 113, 113, 113,
-      113, 113, 113, 113, 113, 113
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 15,
+      71, 71, 71, 71, 71, 71, 15, 71, 71, 71,
+      10, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71,  0, 71,  0, 71,  5,
+       5,  0, 10, 20, 71, 25, 71, 71, 20,  0,
+      20, 30, 25, 71, 10,  5,  0, 20, 15, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+      71, 71, 71, 71, 71, 71
     };
   return len + asso_values[(unsigned char)str[2]] + asso_values[(unsigned char)str[0]] + asso_values[(unsigned char)str[len - 1]];
 }
@@ -56,77 +87,112 @@
       TOTAL_KEYWORDS = 41,
       MIN_WORD_LENGTH = 3,
       MAX_WORD_LENGTH = 17,
-      MIN_HASH_VALUE = 4,
-      MAX_HASH_VALUE = 112
+      MIN_HASH_VALUE = 3,
+      MAX_HASH_VALUE = 70
     };
 
   static const struct resword wordlist[] =
     {
-      {""}, {""}, {""}, {""},
-      {"auto", AUTO_KEYW},
-      {""}, {""},
+      {""}, {""}, {""},
+#line 24 "scripts/genksyms/keywords.gperf"
+      {"asm", ASM_KEYW},
+      {""},
+#line 7 "scripts/genksyms/keywords.gperf"
+      {"__asm", ASM_KEYW},
+      {""},
+#line 8 "scripts/genksyms/keywords.gperf"
       {"__asm__", ASM_KEYW},
       {""},
+#line 21 "scripts/genksyms/keywords.gperf"
       {"_restrict", RESTRICT_KEYW},
+#line 50 "scripts/genksyms/keywords.gperf"
       {"__typeof__", TYPEOF_KEYW},
+#line 9 "scripts/genksyms/keywords.gperf"
       {"__attribute", ATTRIBUTE_KEYW},
-      {"__restrict__", RESTRICT_KEYW},
-      {"__attribute__", ATTRIBUTE_KEYW},
-      {""},
-      {"__volatile", VOLATILE_KEYW},
-      {""},
-      {"__volatile__", VOLATILE_KEYW},
-      {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
-      {""}, {""}, {""},
-      {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
-      {"int", INT_KEYW},
-      {"char", CHAR_KEYW},
-      {""}, {""},
+#line 11 "scripts/genksyms/keywords.gperf"
       {"__const", CONST_KEYW},
-      {"__inline", INLINE_KEYW},
+#line 10 "scripts/genksyms/keywords.gperf"
+      {"__attribute__", ATTRIBUTE_KEYW},
+#line 12 "scripts/genksyms/keywords.gperf"
       {"__const__", CONST_KEYW},
-      {"__inline__", INLINE_KEYW},
-      {""}, {""}, {""}, {""},
-      {"__asm", ASM_KEYW},
-      {"extern", EXTERN_KEYW},
-      {""},
-      {"register", REGISTER_KEYW},
-      {""},
-      {"float", FLOAT_KEYW},
-      {"typeof", TYPEOF_KEYW},
-      {"typedef", TYPEDEF_KEYW},
-      {""}, {""},
-      {"_Bool", BOOL_KEYW},
-      {"double", DOUBLE_KEYW},
-      {""}, {""},
-      {"enum", ENUM_KEYW},
-      {""}, {""}, {""},
-      {"volatile", VOLATILE_KEYW},
-      {"void", VOID_KEYW},
-      {"const", CONST_KEYW},
-      {"short", SHORT_KEYW},
-      {"struct", STRUCT_KEYW},
-      {""},
-      {"restrict", RESTRICT_KEYW},
-      {""},
+#line 16 "scripts/genksyms/keywords.gperf"
       {"__signed__", SIGNED_KEYW},
-      {""},
-      {"asm", ASM_KEYW},
-      {""}, {""},
-      {"inline", INLINE_KEYW},
-      {""}, {""}, {""},
-      {"union", UNION_KEYW},
-      {""}, {""}, {""}, {""}, {""}, {""},
+#line 42 "scripts/genksyms/keywords.gperf"
       {"static", STATIC_KEYW},
-      {""}, {""}, {""}, {""}, {""}, {""},
+      {""},
+#line 15 "scripts/genksyms/keywords.gperf"
       {"__signed", SIGNED_KEYW},
-      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {""}, {""}, {""}, {""}, {""},
+#line 30 "scripts/genksyms/keywords.gperf"
+      {"char", CHAR_KEYW},
+      {""},
+#line 43 "scripts/genksyms/keywords.gperf"
+      {"struct", STRUCT_KEYW},
+#line 22 "scripts/genksyms/keywords.gperf"
+      {"__restrict__", RESTRICT_KEYW},
+#line 23 "scripts/genksyms/keywords.gperf"
+      {"restrict", RESTRICT_KEYW},
+#line 33 "scripts/genksyms/keywords.gperf"
+      {"enum", ENUM_KEYW},
+#line 17 "scripts/genksyms/keywords.gperf"
+      {"__volatile", VOLATILE_KEYW},
+#line 34 "scripts/genksyms/keywords.gperf"
+      {"extern", EXTERN_KEYW},
+#line 18 "scripts/genksyms/keywords.gperf"
+      {"__volatile__", VOLATILE_KEYW},
+#line 37 "scripts/genksyms/keywords.gperf"
+      {"int", INT_KEYW},
+      {""},
+#line 31 "scripts/genksyms/keywords.gperf"
+      {"const", CONST_KEYW},
+#line 32 "scripts/genksyms/keywords.gperf"
+      {"double", DOUBLE_KEYW},
+      {""},
+#line 13 "scripts/genksyms/keywords.gperf"
+      {"__inline", INLINE_KEYW},
+#line 29 "scripts/genksyms/keywords.gperf"
+      {"auto", AUTO_KEYW},
+#line 14 "scripts/genksyms/keywords.gperf"
+      {"__inline__", INLINE_KEYW},
+#line 41 "scripts/genksyms/keywords.gperf"
+      {"signed", SIGNED_KEYW},
+      {""},
+#line 46 "scripts/genksyms/keywords.gperf"
       {"unsigned", UNSIGNED_KEYW},
-      {""}, {""}, {""}, {""},
+      {""},
+#line 40 "scripts/genksyms/keywords.gperf"
+      {"short", SHORT_KEYW},
+#line 49 "scripts/genksyms/keywords.gperf"
+      {"typeof", TYPEOF_KEYW},
+#line 44 "scripts/genksyms/keywords.gperf"
+      {"typedef", TYPEDEF_KEYW},
+#line 48 "scripts/genksyms/keywords.gperf"
+      {"volatile", VOLATILE_KEYW},
+      {""},
+#line 35 "scripts/genksyms/keywords.gperf"
+      {"float", FLOAT_KEYW},
+      {""}, {""},
+#line 39 "scripts/genksyms/keywords.gperf"
+      {"register", REGISTER_KEYW},
+#line 47 "scripts/genksyms/keywords.gperf"
+      {"void", VOID_KEYW},
+      {""},
+#line 36 "scripts/genksyms/keywords.gperf"
+      {"inline", INLINE_KEYW},
+      {""},
+#line 5 "scripts/genksyms/keywords.gperf"
+      {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
+      {""},
+#line 20 "scripts/genksyms/keywords.gperf"
+      {"_Bool", BOOL_KEYW},
+      {""},
+#line 6 "scripts/genksyms/keywords.gperf"
+      {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
+      {""}, {""}, {""}, {""}, {""}, {""},
+#line 38 "scripts/genksyms/keywords.gperf"
       {"long", LONG_KEYW},
-      {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {"signed", SIGNED_KEYW}
+      {""}, {""}, {""}, {""}, {""},
+#line 45 "scripts/genksyms/keywords.gperf"
+      {"union", UNION_KEYW}
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/scripts/genksyms/lex.c_shipped b/scripts/genksyms/lex.c_shipped
index d9bfbb5..1218053 100644
--- a/scripts/genksyms/lex.c_shipped
+++ b/scripts/genksyms/lex.c_shipped
@@ -2036,49 +2036,131 @@
 
   return token;
 }
-#ifndef YYSTYPE
-#define YYSTYPE int
-#endif
-#define	ASM_KEYW	257
-#define	ATTRIBUTE_KEYW	258
-#define	AUTO_KEYW	259
-#define	BOOL_KEYW	260
-#define	CHAR_KEYW	261
-#define	CONST_KEYW	262
-#define	DOUBLE_KEYW	263
-#define	ENUM_KEYW	264
-#define	EXTERN_KEYW	265
-#define	FLOAT_KEYW	266
-#define	INLINE_KEYW	267
-#define	INT_KEYW	268
-#define	LONG_KEYW	269
-#define	REGISTER_KEYW	270
-#define	RESTRICT_KEYW	271
-#define	SHORT_KEYW	272
-#define	SIGNED_KEYW	273
-#define	STATIC_KEYW	274
-#define	STRUCT_KEYW	275
-#define	TYPEDEF_KEYW	276
-#define	UNION_KEYW	277
-#define	UNSIGNED_KEYW	278
-#define	VOID_KEYW	279
-#define	VOLATILE_KEYW	280
-#define	TYPEOF_KEYW	281
-#define	EXPORT_SYMBOL_KEYW	282
-#define	ASM_PHRASE	283
-#define	ATTRIBUTE_PHRASE	284
-#define	BRACE_PHRASE	285
-#define	BRACKET_PHRASE	286
-#define	EXPRESSION_PHRASE	287
-#define	CHAR	288
-#define	DOTS	289
-#define	IDENT	290
-#define	INT	291
-#define	REAL	292
-#define	STRING	293
-#define	TYPE	294
-#define	OTHER	295
-#define	FILENAME	296
+/* A Bison parser, made by GNU Bison 2.0.  */
 
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ASM_KEYW = 258,
+     ATTRIBUTE_KEYW = 259,
+     AUTO_KEYW = 260,
+     BOOL_KEYW = 261,
+     CHAR_KEYW = 262,
+     CONST_KEYW = 263,
+     DOUBLE_KEYW = 264,
+     ENUM_KEYW = 265,
+     EXTERN_KEYW = 266,
+     FLOAT_KEYW = 267,
+     INLINE_KEYW = 268,
+     INT_KEYW = 269,
+     LONG_KEYW = 270,
+     REGISTER_KEYW = 271,
+     RESTRICT_KEYW = 272,
+     SHORT_KEYW = 273,
+     SIGNED_KEYW = 274,
+     STATIC_KEYW = 275,
+     STRUCT_KEYW = 276,
+     TYPEDEF_KEYW = 277,
+     UNION_KEYW = 278,
+     UNSIGNED_KEYW = 279,
+     VOID_KEYW = 280,
+     VOLATILE_KEYW = 281,
+     TYPEOF_KEYW = 282,
+     EXPORT_SYMBOL_KEYW = 283,
+     ASM_PHRASE = 284,
+     ATTRIBUTE_PHRASE = 285,
+     BRACE_PHRASE = 286,
+     BRACKET_PHRASE = 287,
+     EXPRESSION_PHRASE = 288,
+     CHAR = 289,
+     DOTS = 290,
+     IDENT = 291,
+     INT = 292,
+     REAL = 293,
+     STRING = 294,
+     TYPE = 295,
+     OTHER = 296,
+     FILENAME = 297
+   };
+#endif
+#define ASM_KEYW 258
+#define ATTRIBUTE_KEYW 259
+#define AUTO_KEYW 260
+#define BOOL_KEYW 261
+#define CHAR_KEYW 262
+#define CONST_KEYW 263
+#define DOUBLE_KEYW 264
+#define ENUM_KEYW 265
+#define EXTERN_KEYW 266
+#define FLOAT_KEYW 267
+#define INLINE_KEYW 268
+#define INT_KEYW 269
+#define LONG_KEYW 270
+#define REGISTER_KEYW 271
+#define RESTRICT_KEYW 272
+#define SHORT_KEYW 273
+#define SIGNED_KEYW 274
+#define STATIC_KEYW 275
+#define STRUCT_KEYW 276
+#define TYPEDEF_KEYW 277
+#define UNION_KEYW 278
+#define UNSIGNED_KEYW 279
+#define VOID_KEYW 280
+#define VOLATILE_KEYW 281
+#define TYPEOF_KEYW 282
+#define EXPORT_SYMBOL_KEYW 283
+#define ASM_PHRASE 284
+#define ATTRIBUTE_PHRASE 285
+#define BRACE_PHRASE 286
+#define BRACKET_PHRASE 287
+#define EXPRESSION_PHRASE 288
+#define CHAR 289
+#define DOTS 290
+#define IDENT 291
+#define INT 292
+#define REAL 293
+#define STRING 294
+#define TYPE 295
+#define OTHER 296
+#define FILENAME 297
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
 
 extern YYSTYPE yylval;
+
+
+
diff --git a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped
index 2c6b128..99d7c25 100644
--- a/scripts/genksyms/parse.c_shipped
+++ b/scripts/genksyms/parse.c_shipped
@@ -1,50 +1,145 @@
+/* A Bison parser, made by GNU Bison 2.0.  */
 
-/*  A Bison parser, made from scripts/genksyms/parse.y
-    by GNU Bison version 1.28  */
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
-#define YYBISON 1  /* Identify Bison output.  */
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
 
-#define	ASM_KEYW	257
-#define	ATTRIBUTE_KEYW	258
-#define	AUTO_KEYW	259
-#define	BOOL_KEYW	260
-#define	CHAR_KEYW	261
-#define	CONST_KEYW	262
-#define	DOUBLE_KEYW	263
-#define	ENUM_KEYW	264
-#define	EXTERN_KEYW	265
-#define	FLOAT_KEYW	266
-#define	INLINE_KEYW	267
-#define	INT_KEYW	268
-#define	LONG_KEYW	269
-#define	REGISTER_KEYW	270
-#define	RESTRICT_KEYW	271
-#define	SHORT_KEYW	272
-#define	SIGNED_KEYW	273
-#define	STATIC_KEYW	274
-#define	STRUCT_KEYW	275
-#define	TYPEDEF_KEYW	276
-#define	UNION_KEYW	277
-#define	UNSIGNED_KEYW	278
-#define	VOID_KEYW	279
-#define	VOLATILE_KEYW	280
-#define	TYPEOF_KEYW	281
-#define	EXPORT_SYMBOL_KEYW	282
-#define	ASM_PHRASE	283
-#define	ATTRIBUTE_PHRASE	284
-#define	BRACE_PHRASE	285
-#define	BRACKET_PHRASE	286
-#define	EXPRESSION_PHRASE	287
-#define	CHAR	288
-#define	DOTS	289
-#define	IDENT	290
-#define	INT	291
-#define	REAL	292
-#define	STRING	293
-#define	TYPE	294
-#define	OTHER	295
-#define	FILENAME	296
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ASM_KEYW = 258,
+     ATTRIBUTE_KEYW = 259,
+     AUTO_KEYW = 260,
+     BOOL_KEYW = 261,
+     CHAR_KEYW = 262,
+     CONST_KEYW = 263,
+     DOUBLE_KEYW = 264,
+     ENUM_KEYW = 265,
+     EXTERN_KEYW = 266,
+     FLOAT_KEYW = 267,
+     INLINE_KEYW = 268,
+     INT_KEYW = 269,
+     LONG_KEYW = 270,
+     REGISTER_KEYW = 271,
+     RESTRICT_KEYW = 272,
+     SHORT_KEYW = 273,
+     SIGNED_KEYW = 274,
+     STATIC_KEYW = 275,
+     STRUCT_KEYW = 276,
+     TYPEDEF_KEYW = 277,
+     UNION_KEYW = 278,
+     UNSIGNED_KEYW = 279,
+     VOID_KEYW = 280,
+     VOLATILE_KEYW = 281,
+     TYPEOF_KEYW = 282,
+     EXPORT_SYMBOL_KEYW = 283,
+     ASM_PHRASE = 284,
+     ATTRIBUTE_PHRASE = 285,
+     BRACE_PHRASE = 286,
+     BRACKET_PHRASE = 287,
+     EXPRESSION_PHRASE = 288,
+     CHAR = 289,
+     DOTS = 290,
+     IDENT = 291,
+     INT = 292,
+     REAL = 293,
+     STRING = 294,
+     TYPE = 295,
+     OTHER = 296,
+     FILENAME = 297
+   };
+#endif
+#define ASM_KEYW 258
+#define ATTRIBUTE_KEYW 259
+#define AUTO_KEYW 260
+#define BOOL_KEYW 261
+#define CHAR_KEYW 262
+#define CONST_KEYW 263
+#define DOUBLE_KEYW 264
+#define ENUM_KEYW 265
+#define EXTERN_KEYW 266
+#define FLOAT_KEYW 267
+#define INLINE_KEYW 268
+#define INT_KEYW 269
+#define LONG_KEYW 270
+#define REGISTER_KEYW 271
+#define RESTRICT_KEYW 272
+#define SHORT_KEYW 273
+#define SIGNED_KEYW 274
+#define STATIC_KEYW 275
+#define STRUCT_KEYW 276
+#define TYPEDEF_KEYW 277
+#define UNION_KEYW 278
+#define UNSIGNED_KEYW 279
+#define VOID_KEYW 280
+#define VOLATILE_KEYW 281
+#define TYPEOF_KEYW 282
+#define EXPORT_SYMBOL_KEYW 283
+#define ASM_PHRASE 284
+#define ATTRIBUTE_PHRASE 285
+#define BRACE_PHRASE 286
+#define BRACKET_PHRASE 287
+#define EXPRESSION_PHRASE 288
+#define CHAR 289
+#define DOTS 290
+#define IDENT 291
+#define INT 292
+#define REAL 293
+#define STRING 294
+#define TYPE 295
+#define OTHER 296
+#define FILENAME 297
+
+
+
+
+/* Copy the first part of user declarations.  */
 #line 24 "scripts/genksyms/parse.y"
 
 
@@ -75,661 +170,1000 @@
   free_list(b, e);
 }
 
-#ifndef YYSTYPE
-#define YYSTYPE int
-#endif
+
+
+/* Enabling traces.  */
 #ifndef YYDEBUG
-#define YYDEBUG 1
+# define YYDEBUG 1
 #endif
 
-#include <stdio.h>
-
-#ifndef __cplusplus
-#ifndef __STDC__
-#define const
-#endif
-#endif
-
-
-
-#define	YYFINAL		172
-#define	YYFLAG		-32768
-#define	YYNTBASE	52
-
-#define YYTRANSLATE(x) ((unsigned)(x) <= 296 ? yytranslate[x] : 96)
-
-static const char yytranslate[] = {     0,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,    46,
-    47,    48,     2,    45,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,    51,    43,     2,
-    49,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,    50,     2,    44,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
-     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
-    17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
-    27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
-    37,    38,    39,    40,    41,    42
-};
-
-#if YYDEBUG != 0
-static const short yyprhs[] = {     0,
-     0,     2,     5,     6,     9,    10,    14,    16,    18,    20,
-    22,    25,    28,    32,    33,    35,    37,    41,    46,    47,
-    49,    51,    54,    56,    58,    60,    62,    64,    66,    68,
-    70,    72,    77,    80,    83,    86,    90,    94,    98,   101,
-   104,   107,   109,   111,   113,   115,   117,   119,   121,   123,
-   125,   127,   129,   132,   133,   135,   137,   140,   142,   144,
-   146,   148,   151,   153,   155,   160,   165,   168,   172,   176,
-   179,   181,   183,   185,   190,   195,   198,   202,   206,   209,
-   211,   215,   216,   218,   220,   224,   227,   230,   232,   233,
-   235,   237,   242,   247,   250,   254,   258,   262,   263,   265,
-   268,   272,   276,   277,   279,   281,   284,   288,   291,   292,
-   294,   296,   300,   303,   306,   308,   311,   312,   314,   317,
-   318,   320
-};
-
-static const short yyrhs[] = {    53,
-     0,    52,    53,     0,     0,    54,    55,     0,     0,    22,
-    56,    57,     0,    57,     0,    81,     0,    93,     0,    95,
-     0,     1,    43,     0,     1,    44,     0,    61,    58,    43,
-     0,     0,    59,     0,    60,     0,    59,    45,    60,     0,
-    71,    94,    92,    82,     0,     0,    62,     0,    63,     0,
-    62,    63,     0,    64,     0,    65,     0,     5,     0,    16,
-     0,    20,     0,    11,     0,    13,     0,    66,     0,    70,
-     0,    27,    46,    62,    47,     0,    21,    36,     0,    23,
-    36,     0,    10,    36,     0,    21,    36,    84,     0,    23,
-    36,    84,     0,    10,    36,    31,     0,    10,    31,     0,
-    21,    84,     0,    23,    84,     0,     7,     0,    18,     0,
-    14,     0,    15,     0,    19,     0,    24,     0,    12,     0,
-     9,     0,    25,     0,     6,     0,    40,     0,    48,    68,
-     0,     0,    69,     0,    70,     0,    69,    70,     0,     8,
-     0,    26,     0,    30,     0,    17,     0,    67,    71,     0,
-    72,     0,    36,     0,    72,    46,    75,    47,     0,    72,
-    46,     1,    47,     0,    72,    32,     0,    46,    71,    47,
-     0,    46,     1,    47,     0,    67,    73,     0,    74,     0,
-    36,     0,    40,     0,    74,    46,    75,    47,     0,    74,
-    46,     1,    47,     0,    74,    32,     0,    46,    73,    47,
-     0,    46,     1,    47,     0,    76,    35,     0,    76,     0,
-    77,    45,    35,     0,     0,    77,     0,    78,     0,    77,
-    45,    78,     0,    62,    79,     0,    67,    79,     0,    80,
-     0,     0,    36,     0,    40,     0,    80,    46,    75,    47,
-     0,    80,    46,     1,    47,     0,    80,    32,     0,    46,
-    79,    47,     0,    46,     1,    47,     0,    61,    71,    31,
-     0,     0,    83,     0,    49,    33,     0,    50,    85,    44,
-     0,    50,     1,    44,     0,     0,    86,     0,    87,     0,
-    86,    87,     0,    61,    88,    43,     0,     1,    43,     0,
-     0,    89,     0,    90,     0,    89,    45,    90,     0,    73,
-    92,     0,    36,    91,     0,    91,     0,    51,    33,     0,
-     0,    30,     0,    29,    43,     0,     0,    29,     0,    28,
-    46,    36,    47,    43,     0
-};
-
-#endif
-
-#if YYDEBUG != 0
-static const short yyrline[] = { 0,
-   101,   103,   106,   109,   112,   114,   115,   116,   117,   118,
-   119,   120,   123,   137,   139,   142,   151,   163,   169,   171,
-   174,   176,   179,   186,   189,   191,   192,   193,   194,   197,
-   199,   200,   204,   206,   208,   212,   219,   226,   235,   236,
-   237,   240,   242,   243,   244,   245,   246,   247,   248,   249,
-   250,   251,   254,   259,   261,   264,   266,   269,   270,   270,
-   271,   278,   280,   283,   293,   295,   297,   299,   301,   307,
-   309,   312,   314,   315,   317,   319,   321,   323,   327,   329,
-   330,   333,   335,   338,   340,   344,   349,   352,   355,   357,
-   365,   369,   371,   373,   375,   377,   381,   390,   392,   396,
-   401,   403,   406,   408,   411,   413,   416,   419,   423,   425,
-   428,   430,   433,   435,   436,   439,   443,   445,   448,   452,
-   454,   457
-};
-#endif
-
-
-#if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
-
-static const char * const yytname[] = {   "$","error","$undefined.","ASM_KEYW",
-"ATTRIBUTE_KEYW","AUTO_KEYW","BOOL_KEYW","CHAR_KEYW","CONST_KEYW","DOUBLE_KEYW",
-"ENUM_KEYW","EXTERN_KEYW","FLOAT_KEYW","INLINE_KEYW","INT_KEYW","LONG_KEYW",
-"REGISTER_KEYW","RESTRICT_KEYW","SHORT_KEYW","SIGNED_KEYW","STATIC_KEYW","STRUCT_KEYW",
-"TYPEDEF_KEYW","UNION_KEYW","UNSIGNED_KEYW","VOID_KEYW","VOLATILE_KEYW","TYPEOF_KEYW",
-"EXPORT_SYMBOL_KEYW","ASM_PHRASE","ATTRIBUTE_PHRASE","BRACE_PHRASE","BRACKET_PHRASE",
-"EXPRESSION_PHRASE","CHAR","DOTS","IDENT","INT","REAL","STRING","TYPE","OTHER",
-"FILENAME","';'","'}'","','","'('","')'","'*'","'='","'{'","':'","declaration_seq",
-"declaration","@1","declaration1","@2","simple_declaration","init_declarator_list_opt",
-"init_declarator_list","init_declarator","decl_specifier_seq_opt","decl_specifier_seq",
-"decl_specifier","storage_class_specifier","type_specifier","simple_type_specifier",
-"ptr_operator","cvar_qualifier_seq_opt","cvar_qualifier_seq","cvar_qualifier",
-"declarator","direct_declarator","nested_declarator","direct_nested_declarator",
-"parameter_declaration_clause","parameter_declaration_list_opt","parameter_declaration_list",
-"parameter_declaration","m_abstract_declarator","direct_m_abstract_declarator",
-"function_definition","initializer_opt","initializer","class_body","member_specification_opt",
-"member_specification","member_declaration","member_declarator_list_opt","member_declarator_list",
-"member_declarator","member_bitfield_declarator","attribute_opt","asm_definition",
-"asm_phrase_opt","export_definition", NULL
-};
-#endif
-
-static const short yyr1[] = {     0,
-    52,    52,    54,    53,    56,    55,    55,    55,    55,    55,
-    55,    55,    57,    58,    58,    59,    59,    60,    61,    61,
-    62,    62,    63,    63,    64,    64,    64,    64,    64,    65,
-    65,    65,    65,    65,    65,    65,    65,    65,    65,    65,
-    65,    66,    66,    66,    66,    66,    66,    66,    66,    66,
-    66,    66,    67,    68,    68,    69,    69,    70,    70,    70,
-    70,    71,    71,    72,    72,    72,    72,    72,    72,    73,
-    73,    74,    74,    74,    74,    74,    74,    74,    75,    75,
-    75,    76,    76,    77,    77,    78,    79,    79,    80,    80,
-    80,    80,    80,    80,    80,    80,    81,    82,    82,    83,
-    84,    84,    85,    85,    86,    86,    87,    87,    88,    88,
-    89,    89,    90,    90,    90,    91,    92,    92,    93,    94,
-    94,    95
-};
-
-static const short yyr2[] = {     0,
-     1,     2,     0,     2,     0,     3,     1,     1,     1,     1,
-     2,     2,     3,     0,     1,     1,     3,     4,     0,     1,
-     1,     2,     1,     1,     1,     1,     1,     1,     1,     1,
-     1,     4,     2,     2,     2,     3,     3,     3,     2,     2,
-     2,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-     1,     1,     2,     0,     1,     1,     2,     1,     1,     1,
-     1,     2,     1,     1,     4,     4,     2,     3,     3,     2,
-     1,     1,     1,     4,     4,     2,     3,     3,     2,     1,
-     3,     0,     1,     1,     3,     2,     2,     1,     0,     1,
-     1,     4,     4,     2,     3,     3,     3,     0,     1,     2,
-     3,     3,     0,     1,     1,     2,     3,     2,     0,     1,
-     1,     3,     2,     2,     1,     2,     0,     1,     2,     0,
-     1,     5
-};
-
-static const short yydefact[] = {     3,
-     3,     1,     0,     2,     0,    25,    51,    42,    58,    49,
-     0,    28,    48,    29,    44,    45,    26,    61,    43,    46,
-    27,     0,     5,     0,    47,    50,    59,     0,     0,     0,
-    60,    52,     4,     7,    14,    20,    21,    23,    24,    30,
-    31,     8,     9,    10,    11,    12,    39,    35,    33,     0,
-    40,    19,    34,    41,     0,     0,   119,    64,     0,    54,
-     0,    15,    16,     0,   120,    63,    22,    38,    36,     0,
-   109,     0,     0,   105,     6,    14,    37,     0,     0,     0,
-     0,    53,    55,    56,    13,     0,    62,   121,    97,   117,
-    67,     0,   108,   102,    72,    73,     0,     0,     0,   117,
-    71,     0,   110,   111,   115,   101,     0,   106,   120,    32,
-     0,    69,    68,    57,    17,   118,    98,     0,    89,     0,
-    80,    83,    84,   114,     0,    72,     0,   116,    70,   113,
-    76,     0,   107,     0,   122,     0,    18,    99,    66,    90,
-    52,     0,    89,    86,    88,    65,    79,     0,    78,    77,
-     0,     0,   112,   100,     0,    91,     0,    87,    94,     0,
-    81,    85,    75,    74,    96,    95,     0,     0,    93,    92,
-     0,     0
-};
-
-static const short yydefgoto[] = {     1,
-     2,     3,    33,    52,    34,    61,    62,    63,    71,    36,
-    37,    38,    39,    40,    64,    82,    83,    41,   109,    66,
-   100,   101,   120,   121,   122,   123,   144,   145,    42,   137,
-   138,    51,    72,    73,    74,   102,   103,   104,   105,   117,
-    43,    90,    44
-};
-
-static const short yypact[] = {-32768,
-    15,-32768,   197,-32768,    23,-32768,-32768,-32768,-32768,-32768,
-   -18,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,   -28,-32768,   -25,-32768,-32768,-32768,   -26,   -22,   -12,
--32768,-32768,-32768,-32768,    49,   493,-32768,-32768,-32768,-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768,    27,    -8,   101,
--32768,   493,    -8,-32768,   493,    10,-32768,-32768,    11,     9,
-    18,    26,-32768,    49,   -15,   -13,-32768,-32768,-32768,    25,
-    24,    48,   149,-32768,-32768,    49,-32768,   414,    39,    40,
-    47,-32768,     9,-32768,-32768,    49,-32768,-32768,-32768,    66,
--32768,   241,-32768,-32768,    50,-32768,     5,    65,    42,    66,
-    17,    56,    55,-32768,-32768,-32768,    60,-32768,    75,-32768,
-    80,-32768,-32768,-32768,-32768,-32768,    81,    82,   370,    85,
-    98,    89,-32768,-32768,    88,-32768,    91,-32768,-32768,-32768,
--32768,   284,-32768,    24,-32768,   103,-32768,-32768,-32768,-32768,
--32768,     8,    43,-32768,    30,-32768,-32768,   457,-32768,-32768,
-    92,    93,-32768,-32768,    95,-32768,    96,-32768,-32768,   327,
--32768,-32768,-32768,-32768,-32768,-32768,    99,   104,-32768,-32768,
-   148,-32768
-};
-
-static const short yypgoto[] = {-32768,
-   152,-32768,-32768,-32768,   119,-32768,-32768,    94,     0,   -55,
-   -35,-32768,-32768,-32768,   -69,-32768,-32768,   -56,   -30,-32768,
-   -76,-32768,  -122,-32768,-32768,    29,   -62,-32768,-32768,-32768,
--32768,   -17,-32768,-32768,   105,-32768,-32768,    52,    86,    83,
--32768,-32768,-32768
-};
-
-
-#define	YYLAST		533
-
-
-static const short yytable[] = {    78,
-    67,    99,    35,    84,    65,   125,    54,    49,   155,   152,
-    53,    80,    47,    88,   171,    89,     9,    48,    91,    55,
-   127,    50,   129,    56,    50,    18,   114,    99,    81,    99,
-    57,    69,    92,    87,    27,    77,   119,   168,    31,   -89,
-   126,    50,    67,   140,    96,    79,    58,   156,   131,   143,
-    97,    76,    60,   142,   -89,    60,    59,    68,    60,    95,
-    85,   159,   132,    96,    99,    45,    46,    93,    94,    97,
-    86,    60,   143,   143,    98,   160,   119,   126,   140,   157,
-   158,    96,   156,    67,    58,   111,   112,    97,   142,    60,
-    60,   106,   119,   113,    59,   116,    60,   128,   133,   134,
-    98,    70,    93,    88,   119,     6,     7,     8,     9,    10,
-    11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-    21,    22,   135,    24,    25,    26,    27,    28,   139,   136,
-    31,   146,   147,   148,   149,   154,   -19,   150,   163,   164,
-    32,   165,   166,   -19,  -103,   169,   -19,   172,   -19,   107,
-   170,   -19,     4,     6,     7,     8,     9,    10,    11,    12,
-    13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-    75,    24,    25,    26,    27,    28,   162,   108,    31,   115,
-   124,     0,   130,     0,   -19,   153,     0,     0,    32,     0,
-     0,   -19,  -104,     0,   -19,     0,   -19,     5,     0,   -19,
-     0,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-    15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-    25,    26,    27,    28,    29,    30,    31,     0,     0,     0,
-     0,     0,   -19,     0,     0,     0,    32,     0,     0,   -19,
-     0,   118,   -19,     0,   -19,     6,     7,     8,     9,    10,
-    11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-    21,    22,     0,    24,    25,    26,    27,    28,     0,     0,
-    31,     0,     0,     0,     0,   -82,     0,     0,     0,     0,
-    32,     0,     0,     0,   151,     0,     0,   -82,     6,     7,
-     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-    18,    19,    20,    21,    22,     0,    24,    25,    26,    27,
-    28,     0,     0,    31,     0,     0,     0,     0,   -82,     0,
-     0,     0,     0,    32,     0,     0,     0,   167,     0,     0,
-   -82,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-    15,    16,    17,    18,    19,    20,    21,    22,     0,    24,
-    25,    26,    27,    28,     0,     0,    31,     0,     0,     0,
-     0,   -82,     0,     0,     0,     0,    32,     0,     0,     0,
-     0,     0,     0,   -82,     6,     7,     8,     9,    10,    11,
-    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-    22,     0,    24,    25,    26,    27,    28,     0,     0,    31,
-     0,     0,     0,     0,     0,   140,     0,     0,     0,   141,
-     0,     0,     0,     0,     0,   142,     0,    60,     6,     7,
-     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-    18,    19,    20,    21,    22,     0,    24,    25,    26,    27,
-    28,     0,     0,    31,     0,     0,     0,     0,     0,     0,
-     0,     0,     0,    32,     0,     0,     0,     0,     0,     0,
-   110,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-    15,    16,    17,    18,    19,    20,    21,    22,     0,    24,
-    25,    26,    27,    28,     0,     0,    31,     0,     0,     0,
-     0,   161,     0,     0,     0,     0,    32,     6,     7,     8,
-     9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
-    19,    20,    21,    22,     0,    24,    25,    26,    27,    28,
-     0,     0,    31,     0,     0,     0,     0,     0,     0,     0,
-     0,     0,    32
-};
-
-static const short yycheck[] = {    55,
-    36,    71,     3,    60,    35,     1,    24,    36,     1,   132,
-    36,     1,    31,    29,     0,    31,     8,    36,    32,    46,
-    97,    50,    99,    46,    50,    17,    83,    97,    59,    99,
-    43,    49,    46,    64,    26,    53,    92,   160,    30,    32,
-    36,    50,    78,    36,    40,    36,    36,    40,    32,   119,
-    46,    52,    48,    46,    47,    48,    46,    31,    48,    36,
-    43,    32,    46,    40,   134,    43,    44,    43,    44,    46,
-    45,    48,   142,   143,    51,    46,   132,    36,    36,   142,
-   143,    40,    40,   119,    36,    47,    47,    46,    46,    48,
-    48,    44,   148,    47,    46,    30,    48,    33,    43,    45,
-    51,     1,    43,    29,   160,     5,     6,     7,     8,     9,
-    10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-    20,    21,    43,    23,    24,    25,    26,    27,    47,    49,
-    30,    47,    35,    45,    47,    33,    36,    47,    47,    47,
-    40,    47,    47,    43,    44,    47,    46,     0,    48,     1,
-    47,    51,     1,     5,     6,     7,     8,     9,    10,    11,
-    12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-    52,    23,    24,    25,    26,    27,   148,    73,    30,    86,
-    95,    -1,   100,    -1,    36,   134,    -1,    -1,    40,    -1,
-    -1,    43,    44,    -1,    46,    -1,    48,     1,    -1,    51,
-    -1,     5,     6,     7,     8,     9,    10,    11,    12,    13,
-    14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
-    24,    25,    26,    27,    28,    29,    30,    -1,    -1,    -1,
-    -1,    -1,    36,    -1,    -1,    -1,    40,    -1,    -1,    43,
-    -1,     1,    46,    -1,    48,     5,     6,     7,     8,     9,
-    10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-    20,    21,    -1,    23,    24,    25,    26,    27,    -1,    -1,
-    30,    -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,    -1,
-    40,    -1,    -1,    -1,     1,    -1,    -1,    47,     5,     6,
-     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
-    17,    18,    19,    20,    21,    -1,    23,    24,    25,    26,
-    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,    35,    -1,
-    -1,    -1,    -1,    40,    -1,    -1,    -1,     1,    -1,    -1,
-    47,     5,     6,     7,     8,     9,    10,    11,    12,    13,
-    14,    15,    16,    17,    18,    19,    20,    21,    -1,    23,
-    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,
-    -1,    35,    -1,    -1,    -1,    -1,    40,    -1,    -1,    -1,
-    -1,    -1,    -1,    47,     5,     6,     7,     8,     9,    10,
-    11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
-    21,    -1,    23,    24,    25,    26,    27,    -1,    -1,    30,
-    -1,    -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    40,
-    -1,    -1,    -1,    -1,    -1,    46,    -1,    48,     5,     6,
-     7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
-    17,    18,    19,    20,    21,    -1,    23,    24,    25,    26,
-    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,    -1,    -1,
-    -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,
-    47,     5,     6,     7,     8,     9,    10,    11,    12,    13,
-    14,    15,    16,    17,    18,    19,    20,    21,    -1,    23,
-    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,
-    -1,    35,    -1,    -1,    -1,    -1,    40,     5,     6,     7,
-     8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-    18,    19,    20,    21,    -1,    23,    24,    25,    26,    27,
-    -1,    -1,    30,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-    -1,    -1,    40
-};
-/* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
-#line 3 "/usr/lib/bison.simple"
-/* This file comes from bison-1.28.  */
-
-/* Skeleton output parser for bison,
-   Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* As a special exception, when this file is copied by Bison into a
-   Bison output file, you may use that output file without restriction.
-   This special exception was added by the Free Software Foundation
-   in version 1.24 of Bison.  */
-
-/* This is the parser code that is written into each bison parser
-  when the %semantic_parser declaration is not specified in the grammar.
-  It was written by Richard Stallman by simplifying the hairy parser
-  used when %semantic_parser is specified.  */
-
-#ifndef YYSTACK_USE_ALLOCA
-#ifdef alloca
-#define YYSTACK_USE_ALLOCA
-#else /* alloca not defined */
-#ifdef __GNUC__
-#define YYSTACK_USE_ALLOCA
-#define alloca __builtin_alloca
-#else /* not GNU C.  */
-#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
-#define YYSTACK_USE_ALLOCA
-#include <alloca.h>
-#else /* not sparc */
-/* We think this test detects Watcom and Microsoft C.  */
-/* This used to test MSDOS, but that is a bad idea
-   since that symbol is in the user namespace.  */
-#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
-#if 0 /* No need for malloc.h, which pollutes the namespace;
-	 instead, just don't use alloca.  */
-#include <malloc.h>
-#endif
-#else /* not MSDOS, or __TURBOC__ */
-#if defined(_AIX)
-/* I don't know what this was needed for, but it pollutes the namespace.
-   So I turned it off.   rms, 2 May 1997.  */
-/* #include <malloc.h>  */
- #pragma alloca
-#define YYSTACK_USE_ALLOCA
-#else /* not MSDOS, or __TURBOC__, or _AIX */
-#if 0
-#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
-		 and on HPUX 10.  Eventually we can turn this on.  */
-#define YYSTACK_USE_ALLOCA
-#define alloca __builtin_alloca
-#endif /* __hpux */
-#endif
-#endif /* not _AIX */
-#endif /* not MSDOS, or __TURBOC__ */
-#endif /* not sparc */
-#endif /* not GNU C */
-#endif /* alloca not defined */
-#endif /* YYSTACK_USE_ALLOCA not defined */
-
-#ifdef YYSTACK_USE_ALLOCA
-#define YYSTACK_ALLOC alloca
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
 #else
-#define YYSTACK_ALLOC malloc
+# define YYERROR_VERBOSE 0
 #endif
 
-/* Note: there must be only one dollar sign in this file.
-   It is replaced by the list of actions, each action
-   as one case of the switch.  */
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 213 of yacc.c.  */
+#line 202 "scripts/genksyms/parse.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+# ifndef YYFREE
+#  define YYFREE free
+# endif
+# ifndef YYMALLOC
+#  define YYMALLOC malloc
+# endif
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+#  if defined (__STDC__) || defined (__cplusplus)
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   define YYSIZE_T size_t
+#  endif
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+	 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short int yyss;
+  YYSTYPE yyvs;
+  };
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short int) + sizeof (YYSTYPE))			\
+      + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined (__GNUC__) && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  register YYSIZE_T yyi;		\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  4
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   535
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  52
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  45
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  124
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  174
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   297
+
+#define YYTRANSLATE(YYX) 						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+      46,    48,    47,     2,    45,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    51,    43,
+       2,    49,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    50,     2,    44,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned short int yyprhs[] =
+{
+       0,     0,     3,     5,     8,     9,    12,    13,    17,    19,
+      21,    23,    25,    28,    31,    35,    36,    38,    40,    44,
+      49,    50,    52,    54,    57,    59,    61,    63,    65,    67,
+      69,    71,    73,    75,    81,    86,    89,    92,    95,    99,
+     103,   107,   110,   113,   116,   118,   120,   122,   124,   126,
+     128,   130,   132,   134,   136,   138,   141,   142,   144,   146,
+     149,   151,   153,   155,   157,   160,   162,   164,   169,   174,
+     177,   181,   185,   188,   190,   192,   194,   199,   204,   207,
+     211,   215,   218,   220,   224,   225,   227,   229,   233,   236,
+     239,   241,   242,   244,   246,   251,   256,   259,   263,   267,
+     271,   272,   274,   277,   281,   285,   286,   288,   290,   293,
+     297,   300,   301,   303,   305,   309,   312,   315,   317,   320,
+     321,   323,   326,   327,   329
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      53,     0,    -1,    54,    -1,    53,    54,    -1,    -1,    55,
+      56,    -1,    -1,    22,    57,    58,    -1,    58,    -1,    82,
+      -1,    94,    -1,    96,    -1,     1,    43,    -1,     1,    44,
+      -1,    62,    59,    43,    -1,    -1,    60,    -1,    61,    -1,
+      60,    45,    61,    -1,    72,    95,    93,    83,    -1,    -1,
+      63,    -1,    64,    -1,    63,    64,    -1,    65,    -1,    66,
+      -1,     5,    -1,    16,    -1,    20,    -1,    11,    -1,    13,
+      -1,    67,    -1,    71,    -1,    27,    46,    63,    47,    48,
+      -1,    27,    46,    63,    48,    -1,    21,    36,    -1,    23,
+      36,    -1,    10,    36,    -1,    21,    36,    85,    -1,    23,
+      36,    85,    -1,    10,    36,    31,    -1,    10,    31,    -1,
+      21,    85,    -1,    23,    85,    -1,     7,    -1,    18,    -1,
+      14,    -1,    15,    -1,    19,    -1,    24,    -1,    12,    -1,
+       9,    -1,    25,    -1,     6,    -1,    40,    -1,    47,    69,
+      -1,    -1,    70,    -1,    71,    -1,    70,    71,    -1,     8,
+      -1,    26,    -1,    30,    -1,    17,    -1,    68,    72,    -1,
+      73,    -1,    36,    -1,    73,    46,    76,    48,    -1,    73,
+      46,     1,    48,    -1,    73,    32,    -1,    46,    72,    48,
+      -1,    46,     1,    48,    -1,    68,    74,    -1,    75,    -1,
+      36,    -1,    40,    -1,    75,    46,    76,    48,    -1,    75,
+      46,     1,    48,    -1,    75,    32,    -1,    46,    74,    48,
+      -1,    46,     1,    48,    -1,    77,    35,    -1,    77,    -1,
+      78,    45,    35,    -1,    -1,    78,    -1,    79,    -1,    78,
+      45,    79,    -1,    63,    80,    -1,    68,    80,    -1,    81,
+      -1,    -1,    36,    -1,    40,    -1,    81,    46,    76,    48,
+      -1,    81,    46,     1,    48,    -1,    81,    32,    -1,    46,
+      80,    48,    -1,    46,     1,    48,    -1,    62,    72,    31,
+      -1,    -1,    84,    -1,    49,    33,    -1,    50,    86,    44,
+      -1,    50,     1,    44,    -1,    -1,    87,    -1,    88,    -1,
+      87,    88,    -1,    62,    89,    43,    -1,     1,    43,    -1,
+      -1,    90,    -1,    91,    -1,    90,    45,    91,    -1,    74,
+      93,    -1,    36,    92,    -1,    92,    -1,    51,    33,    -1,
+      -1,    30,    -1,    29,    43,    -1,    -1,    29,    -1,    28,
+      46,    36,    48,    43,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned short int yyrline[] =
+{
+       0,   102,   102,   103,   107,   107,   113,   113,   115,   116,
+     117,   118,   119,   120,   124,   138,   139,   143,   151,   164,
+     170,   171,   175,   176,   180,   186,   190,   191,   192,   193,
+     194,   198,   199,   200,   201,   205,   207,   209,   213,   220,
+     227,   236,   237,   238,   242,   243,   244,   245,   246,   247,
+     248,   249,   250,   251,   252,   256,   261,   262,   266,   267,
+     271,   271,   271,   272,   280,   281,   285,   294,   296,   298,
+     300,   302,   309,   310,   314,   315,   316,   318,   320,   322,
+     324,   329,   330,   331,   335,   336,   340,   341,   346,   351,
+     353,   357,   358,   366,   370,   372,   374,   376,   378,   383,
+     392,   393,   398,   403,   404,   408,   409,   413,   414,   418,
+     420,   425,   426,   430,   431,   435,   436,   437,   441,   445,
+     446,   450,   454,   455,   459
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "ASM_KEYW", "ATTRIBUTE_KEYW",
+  "AUTO_KEYW", "BOOL_KEYW", "CHAR_KEYW", "CONST_KEYW", "DOUBLE_KEYW",
+  "ENUM_KEYW", "EXTERN_KEYW", "FLOAT_KEYW", "INLINE_KEYW", "INT_KEYW",
+  "LONG_KEYW", "REGISTER_KEYW", "RESTRICT_KEYW", "SHORT_KEYW",
+  "SIGNED_KEYW", "STATIC_KEYW", "STRUCT_KEYW", "TYPEDEF_KEYW",
+  "UNION_KEYW", "UNSIGNED_KEYW", "VOID_KEYW", "VOLATILE_KEYW",
+  "TYPEOF_KEYW", "EXPORT_SYMBOL_KEYW", "ASM_PHRASE", "ATTRIBUTE_PHRASE",
+  "BRACE_PHRASE", "BRACKET_PHRASE", "EXPRESSION_PHRASE", "CHAR", "DOTS",
+  "IDENT", "INT", "REAL", "STRING", "TYPE", "OTHER", "FILENAME", "';'",
+  "'}'", "','", "'('", "'*'", "')'", "'='", "'{'", "':'", "$accept",
+  "declaration_seq", "declaration", "@1", "declaration1", "@2",
+  "simple_declaration", "init_declarator_list_opt", "init_declarator_list",
+  "init_declarator", "decl_specifier_seq_opt", "decl_specifier_seq",
+  "decl_specifier", "storage_class_specifier", "type_specifier",
+  "simple_type_specifier", "ptr_operator", "cvar_qualifier_seq_opt",
+  "cvar_qualifier_seq", "cvar_qualifier", "declarator",
+  "direct_declarator", "nested_declarator", "direct_nested_declarator",
+  "parameter_declaration_clause", "parameter_declaration_list_opt",
+  "parameter_declaration_list", "parameter_declaration",
+  "m_abstract_declarator", "direct_m_abstract_declarator",
+  "function_definition", "initializer_opt", "initializer", "class_body",
+  "member_specification_opt", "member_specification", "member_declaration",
+  "member_declarator_list_opt", "member_declarator_list",
+  "member_declarator", "member_bitfield_declarator", "attribute_opt",
+  "asm_definition", "asm_phrase_opt", "export_definition", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short int yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,    59,   125,    44,    40,    42,    41,    61,
+     123,    58
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    52,    53,    53,    55,    54,    57,    56,    56,    56,
+      56,    56,    56,    56,    58,    59,    59,    60,    60,    61,
+      62,    62,    63,    63,    64,    64,    65,    65,    65,    65,
+      65,    66,    66,    66,    66,    66,    66,    66,    66,    66,
+      66,    66,    66,    66,    67,    67,    67,    67,    67,    67,
+      67,    67,    67,    67,    67,    68,    69,    69,    70,    70,
+      71,    71,    71,    71,    72,    72,    73,    73,    73,    73,
+      73,    73,    74,    74,    75,    75,    75,    75,    75,    75,
+      75,    76,    76,    76,    77,    77,    78,    78,    79,    80,
+      80,    81,    81,    81,    81,    81,    81,    81,    81,    82,
+      83,    83,    84,    85,    85,    86,    86,    87,    87,    88,
+      88,    89,    89,    90,    90,    91,    91,    91,    92,    93,
+      93,    94,    95,    95,    96
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     1,     2,     0,     2,     0,     3,     1,     1,
+       1,     1,     2,     2,     3,     0,     1,     1,     3,     4,
+       0,     1,     1,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     5,     4,     2,     2,     2,     3,     3,
+       3,     2,     2,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     2,     0,     1,     1,     2,
+       1,     1,     1,     1,     2,     1,     1,     4,     4,     2,
+       3,     3,     2,     1,     1,     1,     4,     4,     2,     3,
+       3,     2,     1,     3,     0,     1,     1,     3,     2,     2,
+       1,     0,     1,     1,     4,     4,     2,     3,     3,     3,
+       0,     1,     2,     3,     3,     0,     1,     1,     2,     3,
+       2,     0,     1,     1,     3,     2,     2,     1,     2,     0,
+       1,     2,     0,     1,     5
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       4,     4,     2,     0,     1,     3,     0,    26,    53,    44,
+      60,    51,     0,    29,    50,    30,    46,    47,    27,    63,
+      45,    48,    28,     0,     6,     0,    49,    52,    61,     0,
+       0,     0,    62,    54,     5,     8,    15,    21,    22,    24,
+      25,    31,    32,     9,    10,    11,    12,    13,    41,    37,
+      35,     0,    42,    20,    36,    43,     0,     0,   121,    66,
+       0,    56,     0,    16,    17,     0,   122,    65,    23,    40,
+      38,     0,   111,     0,     0,   107,     7,    15,    39,     0,
+       0,     0,     0,    55,    57,    58,    14,     0,    64,   123,
+      99,   119,    69,     0,   110,   104,    74,    75,     0,     0,
+       0,   119,    73,     0,   112,   113,   117,   103,     0,   108,
+     122,     0,    34,     0,    71,    70,    59,    18,   120,   100,
+       0,    91,     0,    82,    85,    86,   116,     0,    74,     0,
+     118,    72,   115,    78,     0,   109,     0,    33,   124,     0,
+      19,   101,    68,    92,    54,     0,    91,    88,    90,    67,
+      81,     0,    80,    79,     0,     0,   114,   102,     0,    93,
+       0,    89,    96,     0,    83,    87,    77,    76,    98,    97,
+       0,     0,    95,    94
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+      -1,     1,     2,     3,    34,    53,    35,    62,    63,    64,
+      72,    37,    38,    39,    40,    41,    65,    83,    84,    42,
+     110,    67,   101,   102,   122,   123,   124,   125,   147,   148,
+      43,   140,   141,    52,    73,    74,    75,   103,   104,   105,
+     106,   119,    44,    91,    45
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -128
+static const short int yypact[] =
+{
+    -128,    13,  -128,   329,  -128,  -128,    36,  -128,  -128,  -128,
+    -128,  -128,   -16,  -128,  -128,  -128,  -128,  -128,  -128,  -128,
+    -128,  -128,  -128,   -25,  -128,   -24,  -128,  -128,  -128,   -29,
+      -4,   -22,  -128,  -128,  -128,  -128,   -28,   495,  -128,  -128,
+    -128,  -128,  -128,  -128,  -128,  -128,  -128,  -128,  -128,    16,
+     -23,   103,  -128,   495,   -23,  -128,   495,    35,  -128,  -128,
+       3,    15,     9,    17,  -128,   -28,   -15,    -8,  -128,  -128,
+    -128,    47,    23,    44,   150,  -128,  -128,   -28,  -128,   372,
+      33,    48,    49,  -128,    15,  -128,  -128,   -28,  -128,  -128,
+    -128,    64,  -128,   197,  -128,  -128,    50,  -128,    21,    65,
+      37,    64,    14,    56,    55,  -128,  -128,  -128,    59,  -128,
+      74,    57,  -128,    63,  -128,  -128,  -128,  -128,  -128,    76,
+      83,   416,    84,    99,    90,  -128,  -128,    88,  -128,    89,
+    -128,  -128,  -128,  -128,   241,  -128,    23,  -128,  -128,   105,
+    -128,  -128,  -128,  -128,  -128,     8,    46,  -128,    26,  -128,
+    -128,   459,  -128,  -128,    92,    93,  -128,  -128,    94,  -128,
+      96,  -128,  -128,   285,  -128,  -128,  -128,  -128,  -128,  -128,
+      97,   100,  -128,  -128
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const short int yypgoto[] =
+{
+    -128,  -128,   151,  -128,  -128,  -128,   119,  -128,  -128,    66,
+       0,   -56,   -36,  -128,  -128,  -128,   -70,  -128,  -128,   -51,
+     -31,  -128,   -11,  -128,  -127,  -128,  -128,    27,   -81,  -128,
+    -128,  -128,  -128,   -19,  -128,  -128,   107,  -128,  -128,    43,
+      86,    82,  -128,  -128,  -128
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -107
+static const short int yytable[] =
+{
+      79,    68,   100,    36,    81,    66,    55,   155,    59,   158,
+      85,    50,    54,     4,    89,    48,    90,    56,    60,    61,
+      49,    58,   127,    10,    92,    51,    51,    51,   100,    82,
+     100,    70,    19,   116,    88,    78,   171,   121,    93,    59,
+     -91,    28,    57,    68,   143,    32,   133,    69,   159,    60,
+      61,   146,    86,    77,   145,    61,   -91,   128,   162,    96,
+     134,    97,    87,    97,   160,   161,   100,    98,    61,    98,
+      61,    80,   163,   128,    99,   146,   146,    97,   121,    46,
+      47,   113,   143,    98,    61,    68,   159,   129,   107,   131,
+      94,    95,   145,    61,   118,   121,   114,   115,   130,   135,
+     136,    99,    94,    89,    71,   137,   138,   121,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,   139,    25,    26,    27,    28,
+      29,   142,   149,    32,   150,   151,   152,   153,   157,   -20,
+     166,   167,   168,    33,   169,   172,   -20,  -105,   173,   -20,
+     -20,   108,     5,   117,   -20,     7,     8,     9,    10,    11,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    23,    76,    25,    26,    27,    28,    29,   165,   156,
+      32,   109,   126,   132,     0,     0,   -20,     0,     0,     0,
+      33,     0,     0,   -20,  -106,     0,   -20,   -20,   120,     0,
+       0,   -20,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,     0,
+      25,    26,    27,    28,    29,     0,     0,    32,     0,     0,
+       0,     0,   -84,     0,     0,     0,     0,    33,     0,     0,
+       0,     0,   154,     0,     0,   -84,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,     0,    25,    26,    27,    28,    29,     0,
+       0,    32,     0,     0,     0,     0,   -84,     0,     0,     0,
+       0,    33,     0,     0,     0,     0,   170,     0,     0,   -84,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,     0,    25,    26,
+      27,    28,    29,     0,     0,    32,     0,     0,     0,     0,
+     -84,     0,     0,     0,     0,    33,     0,     0,     0,     0,
+       6,     0,     0,   -84,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+       0,     0,     0,     0,     0,   -20,     0,     0,     0,    33,
+       0,     0,   -20,     0,     0,   -20,   -20,     7,     8,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,    23,     0,    25,    26,    27,    28,    29,
+       0,     0,    32,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    33,     0,     0,     0,     0,     0,     0,   111,
+     112,     7,     8,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,    23,     0,    25,
+      26,    27,    28,    29,     0,     0,    32,     0,     0,     0,
+       0,     0,   143,     0,     0,     0,   144,     0,     0,     0,
+       0,     0,   145,    61,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,     0,    25,    26,    27,    28,    29,     0,     0,    32,
+       0,     0,     0,     0,   164,     0,     0,     0,     0,    33,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,     0,    25,    26,
+      27,    28,    29,     0,     0,    32,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    33
+};
+
+static const short int yycheck[] =
+{
+      56,    37,    72,     3,     1,    36,    25,   134,    36,     1,
+      61,    36,    36,     0,    29,    31,    31,    46,    46,    47,
+      36,    43,     1,     8,    32,    50,    50,    50,    98,    60,
+     100,    50,    17,    84,    65,    54,   163,    93,    46,    36,
+      32,    26,    46,    79,    36,    30,    32,    31,    40,    46,
+      47,   121,    43,    53,    46,    47,    48,    36,    32,    36,
+      46,    40,    45,    40,   145,   146,   136,    46,    47,    46,
+      47,    36,    46,    36,    51,   145,   146,    40,   134,    43,
+      44,    48,    36,    46,    47,   121,    40,    98,    44,   100,
+      43,    44,    46,    47,    30,   151,    48,    48,    33,    43,
+      45,    51,    43,    29,     1,    48,    43,   163,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    49,    23,    24,    25,    26,
+      27,    48,    48,    30,    35,    45,    48,    48,    33,    36,
+      48,    48,    48,    40,    48,    48,    43,    44,    48,    46,
+      47,     1,     1,    87,    51,     5,     6,     7,     8,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    53,    23,    24,    25,    26,    27,   151,   136,
+      30,    74,    96,   101,    -1,    -1,    36,    -1,    -1,    -1,
+      40,    -1,    -1,    43,    44,    -1,    46,    47,     1,    -1,
+      -1,    51,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    -1,
+      23,    24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,
+      -1,    -1,    35,    -1,    -1,    -1,    -1,    40,    -1,    -1,
+      -1,    -1,     1,    -1,    -1,    48,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    -1,    23,    24,    25,    26,    27,    -1,
+      -1,    30,    -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,
+      -1,    40,    -1,    -1,    -1,    -1,     1,    -1,    -1,    48,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    -1,    23,    24,
+      25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,
+      35,    -1,    -1,    -1,    -1,    40,    -1,    -1,    -1,    -1,
+       1,    -1,    -1,    48,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      -1,    -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    40,
+      -1,    -1,    43,    -1,    -1,    46,    47,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    -1,    23,    24,    25,    26,    27,
+      -1,    -1,    30,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,    47,
+      48,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    -1,    23,
+      24,    25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,
+      -1,    -1,    36,    -1,    -1,    -1,    40,    -1,    -1,    -1,
+      -1,    -1,    46,    47,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    -1,    23,    24,    25,    26,    27,    -1,    -1,    30,
+      -1,    -1,    -1,    -1,    35,    -1,    -1,    -1,    -1,    40,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    -1,    23,    24,
+      25,    26,    27,    -1,    -1,    30,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    40
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,    53,    54,    55,     0,    54,     1,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    40,    56,    58,    62,    63,    64,    65,
+      66,    67,    71,    82,    94,    96,    43,    44,    31,    36,
+      36,    50,    85,    57,    36,    85,    46,    46,    43,    36,
+      46,    47,    59,    60,    61,    68,    72,    73,    64,    31,
+      85,     1,    62,    86,    87,    88,    58,    62,    85,    63,
+      36,     1,    72,    69,    70,    71,    43,    45,    72,    29,
+      31,    95,    32,    46,    43,    44,    36,    40,    46,    51,
+      68,    74,    75,    89,    90,    91,    92,    44,     1,    88,
+      72,    47,    48,    48,    48,    48,    71,    61,    30,    93,
+       1,    63,    76,    77,    78,    79,    92,     1,    36,    74,
+      33,    74,    93,    32,    46,    43,    45,    48,    43,    49,
+      83,    84,    48,    36,    40,    46,    68,    80,    81,    48,
+      35,    45,    48,    48,     1,    76,    91,    33,     1,    40,
+      80,    80,    32,    46,    35,    79,    48,    48,    48,    48,
+       1,    76,    48,    48
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
 
 #define yyerrok		(yyerrstatus = 0)
 #define yyclearin	(yychar = YYEMPTY)
-#define YYEMPTY		-2
+#define YYEMPTY		(-2)
 #define YYEOF		0
+
 #define YYACCEPT	goto yyacceptlab
-#define YYABORT 	goto yyabortlab
-#define YYERROR		goto yyerrlab1
-/* Like YYERROR except do call yyerror.
-   This remains here temporarily to ease the
-   transition to the new meaning of YYERROR, for GCC.
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
    Once GCC version 2 has supplanted version 1, this can go.  */
+
 #define YYFAIL		goto yyerrlab
+
 #define YYRECOVERING()  (!!yyerrstatus)
-#define YYBACKUP(token, value) \
+
+#define YYBACKUP(Token, Value)					\
 do								\
   if (yychar == YYEMPTY && yylen == 1)				\
-    { yychar = (token), yylval = (value);			\
-      yychar1 = YYTRANSLATE (yychar);				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
       YYPOPSTACK;						\
       goto yybackup;						\
     }								\
   else								\
-    { yyerror ("syntax error: cannot back up"); YYERROR; }	\
+    { 								\
+      yyerror ("syntax error: cannot back up");\
+      YYERROR;							\
+    }								\
 while (0)
 
+
 #define YYTERROR	1
 #define YYERRCODE	256
 
-#ifndef YYPURE
-#define YYLEX		yylex()
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (N)								\
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (0)
 #endif
 
-#ifdef YYPURE
-#ifdef YYLSP_NEEDED
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+              (Loc).first_line, (Loc).first_column,	\
+              (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
 #ifdef YYLEX_PARAM
-#define YYLEX		yylex(&yylval, &yylloc, YYLEX_PARAM)
+# define YYLEX yylex (YYLEX_PARAM)
 #else
-#define YYLEX		yylex(&yylval, &yylloc)
+# define YYLEX yylex ()
 #endif
-#else /* not YYLSP_NEEDED */
-#ifdef YYLEX_PARAM
-#define YYLEX		yylex(&yylval, YYLEX_PARAM)
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)		\
+do {								\
+  if (yydebug)							\
+    {								\
+      YYFPRINTF (stderr, "%s ", Title);				\
+      yysymprint (stderr, 					\
+                  Type, Value);	\
+      YYFPRINTF (stderr, "\n");					\
+    }								\
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
 #else
-#define YYLEX		yylex(&yylval)
+static void
+yy_stack_print (bottom, top)
+    short int *bottom;
+    short int *top;
 #endif
-#endif /* not YYLSP_NEEDED */
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+    int yyrule;
 #endif
+{
+  int yyi;
+  unsigned int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+             yyrule - 1, yylno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+    YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
 
-/* If nonreentrant, generate the variables here */
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (Rule);		\
+} while (0)
 
-#ifndef YYPURE
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
 
-int	yychar;			/*  the lookahead symbol		*/
-YYSTYPE	yylval;			/*  the semantic value of the		*/
-				/*  lookahead symbol			*/
 
-#ifdef YYLSP_NEEDED
-YYLTYPE yylloc;			/*  location data for the lookahead	*/
-				/*  symbol				*/
-#endif
-
-int yynerrs;			/*  number of parse errors so far       */
-#endif  /* not YYPURE */
-
-#if YYDEBUG != 0
-int yydebug;			/*  nonzero means print parse trace	*/
-/* Since this is uninitialized, it does not stop multiple parsers
-   from coexisting.  */
-#endif
-
-/*  YYINITDEPTH indicates the initial size of the parser's stacks	*/
-
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
 #ifndef	YYINITDEPTH
-#define YYINITDEPTH 200
+# define YYINITDEPTH 200
 #endif
 
-/*  YYMAXDEPTH is the maximum size the stacks can grow to
-    (effective only if the built-in stack extension method is used).  */
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
 
-#if YYMAXDEPTH == 0
-#undef YYMAXDEPTH
-#endif
+   Do not make this value too large; the results are undefined if
+   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
 
 #ifndef YYMAXDEPTH
-#define YYMAXDEPTH 10000
+# define YYMAXDEPTH 10000
 #endif
+
 
-/* Define __yy_memcpy.  Note that the size argument
-   should be passed with type unsigned int, because that is what the non-GCC
-   definitions require.  With GCC, __builtin_memcpy takes an arg
-   of type size_t, but it can handle unsigned int.  */
 
-#if __GNUC__ > 1		/* GNU C and GNU C++ define this.  */
-#define __yy_memcpy(TO,FROM,COUNT)	__builtin_memcpy(TO,FROM,COUNT)
-#else				/* not GNU C or C++ */
-#ifndef __cplusplus
+#if YYERROR_VERBOSE
 
-/* This is the most reliable way to avoid incompatibilities
-   in available built-in functions on various systems.  */
-static void
-__yy_memcpy (to, from, count)
-     char *to;
-     char *from;
-     unsigned int count;
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
 {
-  register char *f = from;
-  register char *t = to;
-  register int i = count;
+  register const char *yys = yystr;
 
-  while (i-- > 0)
-    *t++ = *f++;
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
 }
+#  endif
+# endif
 
-#else /* __cplusplus */
-
-/* This is the most reliable way to avoid incompatibilities
-   in available built-in functions on various systems.  */
-static void
-__yy_memcpy (char *to, char *from, unsigned int count)
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
 {
-  register char *t = to;
-  register char *f = from;
-  register int i = count;
+  register char *yyd = yydest;
+  register const char *yys = yysrc;
 
-  while (i-- > 0)
-    *t++ = *f++;
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
 }
+#  endif
+# endif
 
-#endif
-#endif
+#endif /* !YYERROR_VERBOSE */
+
 
-#line 217 "/usr/lib/bison.simple"
 
-/* The user can define YYPARSE_PARAM as the name of an argument to be passed
-   into yyparse.  The argument should have type void *.
-   It should actually point to an object.
-   Grammar actions can access the variable by casting it
-   to the proper pointer type.  */
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
 
-#ifdef YYPARSE_PARAM
-#ifdef __cplusplus
-#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL
-#else /* not __cplusplus */
-#define YYPARSE_PARAM_ARG YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
-#endif /* not __cplusplus */
-#else /* not YYPARSE_PARAM */
-#define YYPARSE_PARAM_ARG
-#define YYPARSE_PARAM_DECL
-#endif /* not YYPARSE_PARAM */
-
-/* Prevent warning if -Wstrict-prototypes.  */
-#ifdef __GNUC__
-#ifdef YYPARSE_PARAM
-int yyparse (void *);
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
 #else
-int yyparse (void);
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE *yyvaluep;
 #endif
-#endif
-
-int
-yyparse(YYPARSE_PARAM_ARG)
-     YYPARSE_PARAM_DECL
 {
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+        break;
+    }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
   register int yystate;
   register int yyn;
-  register short *yyssp;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short int yyssa[YYINITDEPTH];
+  short int *yyss = yyssa;
+  register short int *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
   register YYSTYPE *yyvsp;
-  int yyerrstatus;	/*  number of tokens to shift before error messages enabled */
-  int yychar1 = 0;		/*  lookahead token as an internal (translated) token number */
 
-  short	yyssa[YYINITDEPTH];	/*  the state stack			*/
-  YYSTYPE yyvsa[YYINITDEPTH];	/*  the semantic value stack		*/
 
-  short *yyss = yyssa;		/*  refer to the stacks thru separate pointers */
-  YYSTYPE *yyvs = yyvsa;	/*  to allow yyoverflow to reallocate them elsewhere */
 
-#ifdef YYLSP_NEEDED
-  YYLTYPE yylsa[YYINITDEPTH];	/*  the location stack			*/
-  YYLTYPE *yyls = yylsa;
-  YYLTYPE *yylsp;
-
-#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
-#else
 #define YYPOPSTACK   (yyvsp--, yyssp--)
-#endif
 
-  int yystacksize = YYINITDEPTH;
-  int yyfree_stacks = 0;
+  YYSIZE_T yystacksize = YYINITDEPTH;
 
-#ifdef YYPURE
-  int yychar;
-  YYSTYPE yylval;
-  int yynerrs;
-#ifdef YYLSP_NEEDED
-  YYLTYPE yylloc;
-#endif
-#endif
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
 
-  YYSTYPE yyval;		/*  the variable used to return		*/
-				/*  semantic values from the action	*/
-				/*  routines				*/
 
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
   int yylen;
 
-#if YYDEBUG != 0
-  if (yydebug)
-    fprintf(stderr, "Starting parse\n");
-#endif
+  YYDPRINTF ((stderr, "Starting parse\n"));
 
   yystate = 0;
   yyerrstatus = 0;
@@ -741,833 +1175,872 @@
      so that they stay on the same level as the state stack.
      The wasted elements are never initialized.  */
 
-  yyssp = yyss - 1;
+  yyssp = yyss;
   yyvsp = yyvs;
-#ifdef YYLSP_NEEDED
-  yylsp = yyls;
-#endif
 
-/* Push a new state, which is found in  yystate  .  */
-/* In all cases, when you get here, the value and location stacks
-   have just been pushed. so pushing a state here evens the stacks.  */
-yynewstate:
 
-  *++yyssp = yystate;
+  yyvsp[0] = yylval;
 
-  if (yyssp >= yyss + yystacksize - 1)
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
     {
-      /* Give user a chance to reallocate the stack */
-      /* Use copies of these so that the &'s don't force the real ones into memory. */
-      YYSTYPE *yyvs1 = yyvs;
-      short *yyss1 = yyss;
-#ifdef YYLSP_NEEDED
-      YYLTYPE *yyls1 = yyls;
-#endif
-
       /* Get the current used size of the three stacks, in elements.  */
-      int size = yyssp - yyss + 1;
+      YYSIZE_T yysize = yyssp - yyss + 1;
 
 #ifdef yyoverflow
-      /* Each stack pointer address is followed by the size of
-	 the data in use in that stack, in bytes.  */
-#ifdef YYLSP_NEEDED
-      /* This used to be a conditional around just the two extra args,
-	 but that might be undefined if yyoverflow is a macro.  */
-      yyoverflow("parser stack overflow",
-		 &yyss1, size * sizeof (*yyssp),
-		 &yyvs1, size * sizeof (*yyvsp),
-		 &yyls1, size * sizeof (*yylsp),
-		 &yystacksize);
-#else
-      yyoverflow("parser stack overflow",
-		 &yyss1, size * sizeof (*yyssp),
-		 &yyvs1, size * sizeof (*yyvsp),
-		 &yystacksize);
-#endif
+      {
+	/* Give user a chance to reallocate the stack. Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	short int *yyss1 = yyss;
 
-      yyss = yyss1; yyvs = yyvs1;
-#ifdef YYLSP_NEEDED
-      yyls = yyls1;
-#endif
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow ("parser stack overflow",
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+
+		    &yystacksize);
+
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
 #else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyoverflowlab;
+# else
       /* Extend the stack our own way.  */
-      if (yystacksize >= YYMAXDEPTH)
-	{
-	  yyerror("parser stack overflow");
-	  if (yyfree_stacks)
-	    {
-	      free (yyss);
-	      free (yyvs);
-#ifdef YYLSP_NEEDED
-	      free (yyls);
-#endif
-	    }
-	  return 2;
-	}
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyoverflowlab;
       yystacksize *= 2;
-      if (yystacksize > YYMAXDEPTH)
+      if (YYMAXDEPTH < yystacksize)
 	yystacksize = YYMAXDEPTH;
-#ifndef YYSTACK_USE_ALLOCA
-      yyfree_stacks = 1;
-#endif
-      yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
-      __yy_memcpy ((char *)yyss, (char *)yyss1,
-		   size * (unsigned int) sizeof (*yyssp));
-      yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
-      __yy_memcpy ((char *)yyvs, (char *)yyvs1,
-		   size * (unsigned int) sizeof (*yyvsp));
-#ifdef YYLSP_NEEDED
-      yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
-      __yy_memcpy ((char *)yyls, (char *)yyls1,
-		   size * (unsigned int) sizeof (*yylsp));
-#endif
+
+      {
+	short int *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyoverflowlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
 #endif /* no yyoverflow */
 
-      yyssp = yyss + size - 1;
-      yyvsp = yyvs + size - 1;
-#ifdef YYLSP_NEEDED
-      yylsp = yyls + size - 1;
-#endif
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
 
-#if YYDEBUG != 0
-      if (yydebug)
-	fprintf(stderr, "Stack size increased to %d\n", yystacksize);
-#endif
 
-      if (yyssp >= yyss + yystacksize - 1)
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
 	YYABORT;
     }
 
-#if YYDEBUG != 0
-  if (yydebug)
-    fprintf(stderr, "Entering state %d\n", yystate);
-#endif
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
   goto yybackup;
- yybackup:
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
 
 /* Do appropriate processing given the current state.  */
-/* Read a lookahead token if we need one and don't already have one.  */
+/* Read a look-ahead token if we need one and don't already have one.  */
 /* yyresume: */
 
-  /* First try to decide what to do without reference to lookahead token.  */
+  /* First try to decide what to do without reference to look-ahead token.  */
 
   yyn = yypact[yystate];
-  if (yyn == YYFLAG)
+  if (yyn == YYPACT_NINF)
     goto yydefault;
 
-  /* Not known => get a lookahead token if don't already have one.  */
+  /* Not known => get a look-ahead token if don't already have one.  */
 
-  /* yychar is either YYEMPTY or YYEOF
-     or a valid token in external form.  */
-
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
   if (yychar == YYEMPTY)
     {
-#if YYDEBUG != 0
-      if (yydebug)
-	fprintf(stderr, "Reading a token: ");
-#endif
+      YYDPRINTF ((stderr, "Reading a token: "));
       yychar = YYLEX;
     }
 
-  /* Convert token to internal form (in yychar1) for indexing tables with */
-
-  if (yychar <= 0)		/* This means end of input. */
+  if (yychar <= YYEOF)
     {
-      yychar1 = 0;
-      yychar = YYEOF;		/* Don't call YYLEX any more */
-
-#if YYDEBUG != 0
-      if (yydebug)
-	fprintf(stderr, "Now at end of input.\n");
-#endif
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
     }
   else
     {
-      yychar1 = YYTRANSLATE(yychar);
-
-#if YYDEBUG != 0
-      if (yydebug)
-	{
-	  fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
-	  /* Give the individual parser a way to print the precise meaning
-	     of a token, for further debugging info.  */
-#ifdef YYPRINT
-	  YYPRINT (stderr, yychar, yylval);
-#endif
-	  fprintf (stderr, ")\n");
-	}
-#endif
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
     }
 
-  yyn += yychar1;
-  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
     goto yydefault;
-
   yyn = yytable[yyn];
-
-  /* yyn is what to do for this token type in this state.
-     Negative => reduce, -yyn is rule number.
-     Positive => shift, yyn is new state.
-       New state is final state => don't bother to shift,
-       just return success.
-     0, or most negative number => error.  */
-
-  if (yyn < 0)
+  if (yyn <= 0)
     {
-      if (yyn == YYFLAG)
+      if (yyn == 0 || yyn == YYTABLE_NINF)
 	goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
-  else if (yyn == 0)
-    goto yyerrlab;
 
   if (yyn == YYFINAL)
     YYACCEPT;
 
-  /* Shift the lookahead token.  */
-
-#if YYDEBUG != 0
-  if (yydebug)
-    fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
-#endif
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
   /* Discard the token being shifted unless it is eof.  */
   if (yychar != YYEOF)
     yychar = YYEMPTY;
 
   *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
-  *++yylsp = yylloc;
-#endif
 
-  /* count tokens shifted since error; after three, turn off error status.  */
-  if (yyerrstatus) yyerrstatus--;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
 
   yystate = yyn;
   goto yynewstate;
 
-/* Do the default action for the current state.  */
-yydefault:
 
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
   yyn = yydefact[yystate];
   if (yyn == 0)
     goto yyerrlab;
+  goto yyreduce;
 
-/* Do a reduction.  yyn is the number of a rule to reduce with.  */
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
 yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
   yylen = yyr2[yyn];
-  if (yylen > 0)
-    yyval = yyvsp[1-yylen]; /* implement default value of the action */
 
-#if YYDEBUG != 0
-  if (yydebug)
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
     {
-      int i;
-
-      fprintf (stderr, "Reducing via rule %d (line %d), ",
-	       yyn, yyrline[yyn]);
-
-      /* Print the symbols being reduced, and their result.  */
-      for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
-	fprintf (stderr, "%s ", yytname[yyrhs[i]]);
-      fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
-    }
-#endif
-
-
-  switch (yyn) {
-
-case 3:
+        case 4:
 #line 107 "scripts/genksyms/parse.y"
-{ is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;
-    break;}
-case 4:
+    { is_typedef = 0; is_extern = 0; current_name = NULL; decl_spec = NULL; ;}
+    break;
+
+  case 5:
 #line 109 "scripts/genksyms/parse.y"
-{ free_list(*yyvsp[0], NULL); *yyvsp[0] = NULL; ;
-    break;}
-case 5:
+    { free_list(*(yyvsp[0]), NULL); *(yyvsp[0]) = NULL; ;}
+    break;
+
+  case 6:
 #line 113 "scripts/genksyms/parse.y"
-{ is_typedef = 1; ;
-    break;}
-case 6:
+    { is_typedef = 1; ;}
+    break;
+
+  case 7:
 #line 114 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 11:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 12:
 #line 119 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 12:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 13:
 #line 120 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 13:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 14:
 #line 125 "scripts/genksyms/parse.y"
-{ if (current_name) {
-		    struct string_list *decl = (*yyvsp[0])->next;
-		    (*yyvsp[0])->next = NULL;
+    { if (current_name) {
+		    struct string_list *decl = (*(yyvsp[0]))->next;
+		    (*(yyvsp[0]))->next = NULL;
 		    add_symbol(current_name,
 			       is_typedef ? SYM_TYPEDEF : SYM_NORMAL,
 			       decl, is_extern);
 		    current_name = NULL;
 		  }
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 14:
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 15:
 #line 138 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 16:
+    { (yyval) = NULL; ;}
+    break;
+
+  case 17:
 #line 144 "scripts/genksyms/parse.y"
-{ struct string_list *decl = *yyvsp[0];
-		  *yyvsp[0] = NULL;
+    { struct string_list *decl = *(yyvsp[0]);
+		  *(yyvsp[0]) = NULL;
 		  add_symbol(current_name,
 			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
 		  current_name = NULL;
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 17:
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 18:
 #line 152 "scripts/genksyms/parse.y"
-{ struct string_list *decl = *yyvsp[0];
-		  *yyvsp[0] = NULL;
-		  free_list(*yyvsp[-1], NULL);
-		  *yyvsp[-1] = decl_spec;
+    { struct string_list *decl = *(yyvsp[0]);
+		  *(yyvsp[0]) = NULL;
+		  free_list(*(yyvsp[-1]), NULL);
+		  *(yyvsp[-1]) = decl_spec;
 		  add_symbol(current_name,
 			     is_typedef ? SYM_TYPEDEF : SYM_NORMAL, decl, is_extern);
 		  current_name = NULL;
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 18:
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 19:
 #line 165 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1] ? yyvsp[-1] : yyvsp[-2] ? yyvsp[-2] : yyvsp[-3]; ;
-    break;}
-case 19:
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]) ? (yyvsp[-1]) : (yyvsp[-2]) ? (yyvsp[-2]) : (yyvsp[-3]); ;}
+    break;
+
+  case 20:
 #line 170 "scripts/genksyms/parse.y"
-{ decl_spec = NULL; ;
-    break;}
-case 21:
+    { decl_spec = NULL; ;}
+    break;
+
+  case 22:
 #line 175 "scripts/genksyms/parse.y"
-{ decl_spec = *yyvsp[0]; ;
-    break;}
-case 22:
+    { decl_spec = *(yyvsp[0]); ;}
+    break;
+
+  case 23:
 #line 176 "scripts/genksyms/parse.y"
-{ decl_spec = *yyvsp[0]; ;
-    break;}
-case 23:
+    { decl_spec = *(yyvsp[0]); ;}
+    break;
+
+  case 24:
 #line 181 "scripts/genksyms/parse.y"
-{ /* Version 2 checksumming ignores storage class, as that
+    { /* Version 2 checksumming ignores storage class, as that
 		     is really irrelevant to the linkage.  */
-		  remove_node(yyvsp[0]);
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 28:
+		  remove_node((yyvsp[0]));
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 29:
 #line 193 "scripts/genksyms/parse.y"
-{ is_extern = 1; yyval = yyvsp[0]; ;
-    break;}
-case 29:
+    { is_extern = 1; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 30:
 #line 194 "scripts/genksyms/parse.y"
-{ is_extern = 0; yyval = yyvsp[0]; ;
-    break;}
-case 33:
-#line 205 "scripts/genksyms/parse.y"
-{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_STRUCT; yyval = yyvsp[0]; ;
-    break;}
-case 34:
-#line 207 "scripts/genksyms/parse.y"
-{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_UNION; yyval = yyvsp[0]; ;
-    break;}
-case 35:
-#line 209 "scripts/genksyms/parse.y"
-{ remove_node(yyvsp[-1]); (*yyvsp[0])->tag = SYM_ENUM; yyval = yyvsp[0]; ;
-    break;}
-case 36:
-#line 213 "scripts/genksyms/parse.y"
-{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+    { is_extern = 0; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 35:
+#line 206 "scripts/genksyms/parse.y"
+    { remove_node((yyvsp[-1])); (*(yyvsp[0]))->tag = SYM_STRUCT; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 36:
+#line 208 "scripts/genksyms/parse.y"
+    { remove_node((yyvsp[-1])); (*(yyvsp[0]))->tag = SYM_UNION; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 37:
+#line 210 "scripts/genksyms/parse.y"
+    { remove_node((yyvsp[-1])); (*(yyvsp[0]))->tag = SYM_ENUM; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 38:
+#line 214 "scripts/genksyms/parse.y"
+    { struct string_list *s = *(yyvsp[0]), *i = *(yyvsp[-1]), *r;
 		  r = copy_node(i); r->tag = SYM_STRUCT;
-		  r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+		  r->next = (*(yyvsp[-2]))->next; *(yyvsp[0]) = r; (*(yyvsp[-2]))->next = NULL;
 		  add_symbol(i->string, SYM_STRUCT, s, is_extern);
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 37:
-#line 220 "scripts/genksyms/parse.y"
-{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 39:
+#line 221 "scripts/genksyms/parse.y"
+    { struct string_list *s = *(yyvsp[0]), *i = *(yyvsp[-1]), *r;
 		  r = copy_node(i); r->tag = SYM_UNION;
-		  r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+		  r->next = (*(yyvsp[-2]))->next; *(yyvsp[0]) = r; (*(yyvsp[-2]))->next = NULL;
 		  add_symbol(i->string, SYM_UNION, s, is_extern);
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 38:
-#line 227 "scripts/genksyms/parse.y"
-{ struct string_list *s = *yyvsp[0], *i = *yyvsp[-1], *r;
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 40:
+#line 228 "scripts/genksyms/parse.y"
+    { struct string_list *s = *(yyvsp[0]), *i = *(yyvsp[-1]), *r;
 		  r = copy_node(i); r->tag = SYM_ENUM;
-		  r->next = (*yyvsp[-2])->next; *yyvsp[0] = r; (*yyvsp[-2])->next = NULL;
+		  r->next = (*(yyvsp[-2]))->next; *(yyvsp[0]) = r; (*(yyvsp[-2]))->next = NULL;
 		  add_symbol(i->string, SYM_ENUM, s, is_extern);
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 39:
-#line 235 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 40:
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 41:
 #line 236 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 41:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 42:
 #line 237 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 52:
-#line 251 "scripts/genksyms/parse.y"
-{ (*yyvsp[0])->tag = SYM_TYPEDEF; yyval = yyvsp[0]; ;
-    break;}
-case 53:
-#line 256 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
-    break;}
-case 54:
-#line 260 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 57:
-#line 266 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 61:
-#line 272 "scripts/genksyms/parse.y"
-{ /* restrict has no effect in prototypes so ignore it */
-		  remove_node(yyvsp[0]);
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 62:
-#line 279 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 64:
-#line 285 "scripts/genksyms/parse.y"
-{ if (current_name != NULL) {
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 43:
+#line 238 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 54:
+#line 252 "scripts/genksyms/parse.y"
+    { (*(yyvsp[0]))->tag = SYM_TYPEDEF; (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 55:
+#line 257 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+    break;
+
+  case 56:
+#line 261 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 59:
+#line 267 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 63:
+#line 273 "scripts/genksyms/parse.y"
+    { /* restrict has no effect in prototypes so ignore it */
+		  remove_node((yyvsp[0]));
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 64:
+#line 280 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 66:
+#line 286 "scripts/genksyms/parse.y"
+    { if (current_name != NULL) {
 		    error_with_pos("unexpected second declaration name");
 		    YYERROR;
 		  } else {
-		    current_name = (*yyvsp[0])->string;
-		    yyval = yyvsp[0];
+		    current_name = (*(yyvsp[0]))->string;
+		    (yyval) = (yyvsp[0]);
 		  }
-		;
-    break;}
-case 65:
-#line 294 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 66:
-#line 296 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 67:
-#line 298 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 68:
-#line 300 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 69:
-#line 302 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 70:
-#line 308 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 74:
-#line 316 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 75:
-#line 318 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 76:
-#line 320 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 77:
-#line 322 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 78:
-#line 324 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 79:
-#line 328 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 81:
-#line 330 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 82:
-#line 334 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 85:
-#line 341 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 86:
-#line 346 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
-    break;}
-case 87:
-#line 351 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
-    break;}
-case 89:
-#line 356 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 90:
-#line 358 "scripts/genksyms/parse.y"
-{ /* For version 2 checksums, we don't want to remember
+		;}
+    break;
+
+  case 67:
+#line 295 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 68:
+#line 297 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 69:
+#line 299 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 70:
+#line 301 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 71:
+#line 303 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 72:
+#line 309 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 76:
+#line 317 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 77:
+#line 319 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 78:
+#line 321 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 79:
+#line 323 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 80:
+#line 325 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 81:
+#line 329 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 83:
+#line 331 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 84:
+#line 335 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 87:
+#line 342 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 88:
+#line 347 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+    break;
+
+  case 89:
+#line 352 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+    break;
+
+  case 91:
+#line 357 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 92:
+#line 359 "scripts/genksyms/parse.y"
+    { /* For version 2 checksums, we don't want to remember
 		     private parameter names.  */
-		  remove_node(yyvsp[0]);
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 91:
-#line 366 "scripts/genksyms/parse.y"
-{ remove_node(yyvsp[0]);
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 92:
-#line 370 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 93:
-#line 372 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 94:
-#line 374 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 95:
-#line 376 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 96:
-#line 378 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 97:
-#line 383 "scripts/genksyms/parse.y"
-{ struct string_list *decl = *yyvsp[-1];
-		  *yyvsp[-1] = NULL;
+		  remove_node((yyvsp[0]));
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 93:
+#line 367 "scripts/genksyms/parse.y"
+    { remove_node((yyvsp[0]));
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 94:
+#line 371 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 95:
+#line 373 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 96:
+#line 375 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 97:
+#line 377 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 98:
+#line 379 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 99:
+#line 384 "scripts/genksyms/parse.y"
+    { struct string_list *decl = *(yyvsp[-1]);
+		  *(yyvsp[-1]) = NULL;
 		  add_symbol(current_name, SYM_NORMAL, decl, is_extern);
-		  yyval = yyvsp[0];
-		;
-    break;}
-case 98:
-#line 391 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 100:
-#line 398 "scripts/genksyms/parse.y"
-{ remove_list(yyvsp[0], &(*yyvsp[-1])->next); yyval = yyvsp[0]; ;
-    break;}
-case 101:
-#line 402 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 102:
+		  (yyval) = (yyvsp[0]);
+		;}
+    break;
+
+  case 100:
+#line 392 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 102:
+#line 399 "scripts/genksyms/parse.y"
+    { remove_list((yyvsp[0]), &(*(yyvsp[-1]))->next); (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 103:
 #line 403 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 103:
-#line 407 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 106:
-#line 413 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 107:
-#line 418 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 108:
-#line 420 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 109:
-#line 424 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 112:
-#line 430 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 113:
-#line 434 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0] ? yyvsp[0] : yyvsp[-1]; ;
-    break;}
-case 114:
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 104:
+#line 404 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 105:
+#line 408 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 108:
+#line 414 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 109:
+#line 419 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 110:
+#line 421 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 111:
+#line 425 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 114:
+#line 431 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 115:
 #line 435 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 116:
-#line 440 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 117:
-#line 444 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 119:
-#line 449 "scripts/genksyms/parse.y"
-{ yyval = yyvsp[0]; ;
-    break;}
-case 120:
-#line 453 "scripts/genksyms/parse.y"
-{ yyval = NULL; ;
-    break;}
-case 122:
-#line 459 "scripts/genksyms/parse.y"
-{ export_symbol((*yyvsp[-2])->string); yyval = yyvsp[0]; ;
-    break;}
-}
-   /* the action file gets copied in in place of this dollarsign */
-#line 543 "/usr/lib/bison.simple"
+    { (yyval) = (yyvsp[0]) ? (yyvsp[0]) : (yyvsp[-1]); ;}
+    break;
+
+  case 116:
+#line 436 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 118:
+#line 441 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 119:
+#line 445 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 121:
+#line 450 "scripts/genksyms/parse.y"
+    { (yyval) = (yyvsp[0]); ;}
+    break;
+
+  case 122:
+#line 454 "scripts/genksyms/parse.y"
+    { (yyval) = NULL; ;}
+    break;
+
+  case 124:
+#line 460 "scripts/genksyms/parse.y"
+    { export_symbol((*(yyvsp[-2]))->string); (yyval) = (yyvsp[0]); ;}
+    break;
+
+
+    }
+
+/* Line 1037 of yacc.c.  */
+#line 1816 "scripts/genksyms/parse.c"
 
   yyvsp -= yylen;
   yyssp -= yylen;
-#ifdef YYLSP_NEEDED
-  yylsp -= yylen;
-#endif
 
-#if YYDEBUG != 0
-  if (yydebug)
-    {
-      short *ssp1 = yyss - 1;
-      fprintf (stderr, "state stack now");
-      while (ssp1 != yyssp)
-	fprintf (stderr, " %d", *++ssp1);
-      fprintf (stderr, "\n");
-    }
-#endif
+
+  YY_STACK_PRINT (yyss, yyssp);
 
   *++yyvsp = yyval;
 
-#ifdef YYLSP_NEEDED
-  yylsp++;
-  if (yylen == 0)
-    {
-      yylsp->first_line = yylloc.first_line;
-      yylsp->first_column = yylloc.first_column;
-      yylsp->last_line = (yylsp-1)->last_line;
-      yylsp->last_column = (yylsp-1)->last_column;
-      yylsp->text = 0;
-    }
-  else
-    {
-      yylsp->last_line = (yylsp+yylen-1)->last_line;
-      yylsp->last_column = (yylsp+yylen-1)->last_column;
-    }
-#endif
 
-  /* Now "shift" the result of the reduction.
-     Determine what state that goes to,
-     based on the state we popped back to
-     and the rule number reduced by.  */
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
 
   yyn = yyr1[yyn];
 
-  yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
-  if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
     yystate = yytable[yystate];
   else
-    yystate = yydefgoto[yyn - YYNTBASE];
+    yystate = yydefgoto[yyn - YYNTOKENS];
 
   goto yynewstate;
 
-yyerrlab:   /* here on detecting error */
 
-  if (! yyerrstatus)
-    /* If not already recovering from an error, report this error.  */
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
     {
       ++yynerrs;
-
-#ifdef YYERROR_VERBOSE
+#if YYERROR_VERBOSE
       yyn = yypact[yystate];
 
-      if (yyn > YYFLAG && yyn < YYLAST)
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
 	{
-	  int size = 0;
-	  char *msg;
-	  int x, count;
+	  YYSIZE_T yysize = 0;
+	  int yytype = YYTRANSLATE (yychar);
+	  const char* yyprefix;
+	  char *yymsg;
+	  int yyx;
 
-	  count = 0;
-	  /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
-	  for (x = (yyn < 0 ? -yyn : 0);
-	       x < (sizeof(yytname) / sizeof(char *)); x++)
-	    if (yycheck[x + yyn] == x)
-	      size += strlen(yytname[x]) + 15, count++;
-	  msg = (char *) malloc(size + 15);
-	  if (msg != 0)
+	  /* Start YYX at -YYN if negative to avoid negative indexes in
+	     YYCHECK.  */
+	  int yyxbegin = yyn < 0 ? -yyn : 0;
+
+	  /* Stay within bounds of both yycheck and yytname.  */
+	  int yychecklim = YYLAST - yyn;
+	  int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+	  int yycount = 0;
+
+	  yyprefix = ", expecting ";
+	  for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	      {
+		yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
+		yycount += 1;
+		if (yycount == 5)
+		  {
+		    yysize = 0;
+		    break;
+		  }
+	      }
+	  yysize += (sizeof ("syntax error, unexpected ")
+		     + yystrlen (yytname[yytype]));
+	  yymsg = (char *) YYSTACK_ALLOC (yysize);
+	  if (yymsg != 0)
 	    {
-	      strcpy(msg, "parse error");
+	      char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+	      yyp = yystpcpy (yyp, yytname[yytype]);
 
-	      if (count < 5)
+	      if (yycount < 5)
 		{
-		  count = 0;
-		  for (x = (yyn < 0 ? -yyn : 0);
-		       x < (sizeof(yytname) / sizeof(char *)); x++)
-		    if (yycheck[x + yyn] == x)
+		  yyprefix = ", expecting ";
+		  for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+		    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
 		      {
-			strcat(msg, count == 0 ? ", expecting `" : " or `");
-			strcat(msg, yytname[x]);
-			strcat(msg, "'");
-			count++;
+			yyp = yystpcpy (yyp, yyprefix);
+			yyp = yystpcpy (yyp, yytname[yyx]);
+			yyprefix = " or ";
 		      }
 		}
-	      yyerror(msg);
-	      free(msg);
+	      yyerror (yymsg);
+	      YYSTACK_FREE (yymsg);
 	    }
 	  else
-	    yyerror ("parse error; also virtual memory exceeded");
+	    yyerror ("syntax error; also virtual memory exhausted");
 	}
       else
 #endif /* YYERROR_VERBOSE */
-	yyerror("parse error");
+	yyerror ("syntax error");
     }
 
-  goto yyerrlab1;
-yyerrlab1:   /* here on error raised explicitly by an action */
+
 
   if (yyerrstatus == 3)
     {
-      /* if just tried and failed to reuse lookahead token after an error, discard it.  */
+      /* If just tried and failed to reuse look-ahead token after an
+	 error, discard it.  */
 
-      /* return failure if at end of input */
-      if (yychar == YYEOF)
+      if (yychar <= YYEOF)
+        {
+          /* If at end of input, pop the error token,
+	     then the rest of the stack, then return failure.  */
+	  if (yychar == YYEOF)
+	     for (;;)
+	       {
+
+		 YYPOPSTACK;
+		 if (yyssp == yyss)
+		   YYABORT;
+		 yydestruct ("Error: popping",
+                             yystos[*yyssp], yyvsp);
+	       }
+        }
+      else
+	{
+	  yydestruct ("Error: discarding", yytoken, &yylval);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+#ifdef __GNUC__
+  /* Pacify GCC when the user code never invokes YYERROR and the label
+     yyerrorlab therefore never appears in user code.  */
+  if (0)
+     goto yyerrorlab;
+#endif
+
+yyvsp -= yylen;
+  yyssp -= yylen;
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
 	YYABORT;
 
-#if YYDEBUG != 0
-      if (yydebug)
-	fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
-#endif
 
-      yychar = YYEMPTY;
+      yydestruct ("Error: popping", yystos[yystate], yyvsp);
+      YYPOPSTACK;
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
     }
 
-  /* Else will try to reuse lookahead token
-     after shifting the error token.  */
-
-  yyerrstatus = 3;		/* Each real token shifted decrements this */
-
-  goto yyerrhandle;
-
-yyerrdefault:  /* current state does not do anything special for the error token. */
-
-#if 0
-  /* This is wrong; only states that explicitly want error tokens
-     should shift them.  */
-  yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
-  if (yyn) goto yydefault;
-#endif
-
-yyerrpop:   /* pop the current state because it cannot handle the error token */
-
-  if (yyssp == yyss) YYABORT;
-  yyvsp--;
-  yystate = *--yyssp;
-#ifdef YYLSP_NEEDED
-  yylsp--;
-#endif
-
-#if YYDEBUG != 0
-  if (yydebug)
-    {
-      short *ssp1 = yyss - 1;
-      fprintf (stderr, "Error: state stack now");
-      while (ssp1 != yyssp)
-	fprintf (stderr, " %d", *++ssp1);
-      fprintf (stderr, "\n");
-    }
-#endif
-
-yyerrhandle:
-
-  yyn = yypact[yystate];
-  if (yyn == YYFLAG)
-    goto yyerrdefault;
-
-  yyn += YYTERROR;
-  if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
-    goto yyerrdefault;
-
-  yyn = yytable[yyn];
-  if (yyn < 0)
-    {
-      if (yyn == YYFLAG)
-	goto yyerrpop;
-      yyn = -yyn;
-      goto yyreduce;
-    }
-  else if (yyn == 0)
-    goto yyerrpop;
-
   if (yyn == YYFINAL)
     YYACCEPT;
 
-#if YYDEBUG != 0
-  if (yydebug)
-    fprintf(stderr, "Shifting error token, ");
-#endif
-
   *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
-  *++yylsp = yylloc;
-#endif
+
+
+  /* Shift the error token. */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
 
   yystate = yyn;
   goto yynewstate;
 
- yyacceptlab:
-  /* YYACCEPT comes here.  */
-  if (yyfree_stacks)
-    {
-      free (yyss);
-      free (yyvs);
-#ifdef YYLSP_NEEDED
-      free (yyls);
-#endif
-    }
-  return 0;
 
- yyabortlab:
-  /* YYABORT comes here.  */
-  if (yyfree_stacks)
-    {
-      free (yyss);
-      free (yyvs);
-#ifdef YYLSP_NEEDED
-      free (yyls);
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yydestruct ("Error: discarding lookahead",
+              yytoken, &yylval);
+  yychar = YYEMPTY;
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here.  |
+`----------------------------------------------*/
+yyoverflowlab:
+  yyerror ("parser stack overflow");
+  yyresult = 2;
+  /* Fall through.  */
 #endif
-    }
-  return 1;
+
+yyreturn:
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
 }
-#line 463 "scripts/genksyms/parse.y"
+
+
+#line 464 "scripts/genksyms/parse.y"
 
 
 static void
@@ -1575,3 +2048,4 @@
 {
   error_with_pos("%s", e);
 }
+
diff --git a/scripts/genksyms/parse.h_shipped b/scripts/genksyms/parse.h_shipped
index d5b27e3..f3fb2bb 100644
--- a/scripts/genksyms/parse.h_shipped
+++ b/scripts/genksyms/parse.h_shipped
@@ -1,46 +1,128 @@
-#ifndef YYSTYPE
-#define YYSTYPE int
-#endif
-#define	ASM_KEYW	257
-#define	ATTRIBUTE_KEYW	258
-#define	AUTO_KEYW	259
-#define	BOOL_KEYW	260
-#define	CHAR_KEYW	261
-#define	CONST_KEYW	262
-#define	DOUBLE_KEYW	263
-#define	ENUM_KEYW	264
-#define	EXTERN_KEYW	265
-#define	FLOAT_KEYW	266
-#define	INLINE_KEYW	267
-#define	INT_KEYW	268
-#define	LONG_KEYW	269
-#define	REGISTER_KEYW	270
-#define	RESTRICT_KEYW	271
-#define	SHORT_KEYW	272
-#define	SIGNED_KEYW	273
-#define	STATIC_KEYW	274
-#define	STRUCT_KEYW	275
-#define	TYPEDEF_KEYW	276
-#define	UNION_KEYW	277
-#define	UNSIGNED_KEYW	278
-#define	VOID_KEYW	279
-#define	VOLATILE_KEYW	280
-#define	TYPEOF_KEYW	281
-#define	EXPORT_SYMBOL_KEYW	282
-#define	ASM_PHRASE	283
-#define	ATTRIBUTE_PHRASE	284
-#define	BRACE_PHRASE	285
-#define	BRACKET_PHRASE	286
-#define	EXPRESSION_PHRASE	287
-#define	CHAR	288
-#define	DOTS	289
-#define	IDENT	290
-#define	INT	291
-#define	REAL	292
-#define	STRING	293
-#define	TYPE	294
-#define	OTHER	295
-#define	FILENAME	296
+/* A Bison parser, made by GNU Bison 2.0.  */
 
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ASM_KEYW = 258,
+     ATTRIBUTE_KEYW = 259,
+     AUTO_KEYW = 260,
+     BOOL_KEYW = 261,
+     CHAR_KEYW = 262,
+     CONST_KEYW = 263,
+     DOUBLE_KEYW = 264,
+     ENUM_KEYW = 265,
+     EXTERN_KEYW = 266,
+     FLOAT_KEYW = 267,
+     INLINE_KEYW = 268,
+     INT_KEYW = 269,
+     LONG_KEYW = 270,
+     REGISTER_KEYW = 271,
+     RESTRICT_KEYW = 272,
+     SHORT_KEYW = 273,
+     SIGNED_KEYW = 274,
+     STATIC_KEYW = 275,
+     STRUCT_KEYW = 276,
+     TYPEDEF_KEYW = 277,
+     UNION_KEYW = 278,
+     UNSIGNED_KEYW = 279,
+     VOID_KEYW = 280,
+     VOLATILE_KEYW = 281,
+     TYPEOF_KEYW = 282,
+     EXPORT_SYMBOL_KEYW = 283,
+     ASM_PHRASE = 284,
+     ATTRIBUTE_PHRASE = 285,
+     BRACE_PHRASE = 286,
+     BRACKET_PHRASE = 287,
+     EXPRESSION_PHRASE = 288,
+     CHAR = 289,
+     DOTS = 290,
+     IDENT = 291,
+     INT = 292,
+     REAL = 293,
+     STRING = 294,
+     TYPE = 295,
+     OTHER = 296,
+     FILENAME = 297
+   };
+#endif
+#define ASM_KEYW 258
+#define ATTRIBUTE_KEYW 259
+#define AUTO_KEYW 260
+#define BOOL_KEYW 261
+#define CHAR_KEYW 262
+#define CONST_KEYW 263
+#define DOUBLE_KEYW 264
+#define ENUM_KEYW 265
+#define EXTERN_KEYW 266
+#define FLOAT_KEYW 267
+#define INLINE_KEYW 268
+#define INT_KEYW 269
+#define LONG_KEYW 270
+#define REGISTER_KEYW 271
+#define RESTRICT_KEYW 272
+#define SHORT_KEYW 273
+#define SIGNED_KEYW 274
+#define STATIC_KEYW 275
+#define STRUCT_KEYW 276
+#define TYPEDEF_KEYW 277
+#define UNION_KEYW 278
+#define UNSIGNED_KEYW 279
+#define VOID_KEYW 280
+#define VOLATILE_KEYW 281
+#define TYPEOF_KEYW 282
+#define EXPORT_SYMBOL_KEYW 283
+#define ASM_PHRASE 284
+#define ATTRIBUTE_PHRASE 285
+#define BRACE_PHRASE 286
+#define BRACKET_PHRASE 287
+#define EXPRESSION_PHRASE 288
+#define CHAR 289
+#define DOTS 290
+#define IDENT 291
+#define INT 292
+#define REAL 293
+#define STRING 294
+#define TYPE 295
+#define OTHER 296
+#define FILENAME 297
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
 
 extern YYSTYPE yylval;
+
+
+
diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y
index 0990437..ca04c944 100644
--- a/scripts/genksyms/parse.y
+++ b/scripts/genksyms/parse.y
@@ -197,6 +197,7 @@
 type_specifier:
 	simple_type_specifier
 	| cvar_qualifier
+	| TYPEOF_KEYW '(' decl_specifier_seq '*' ')'
 	| TYPEOF_KEYW '(' decl_specifier_seq ')'
 
 	/* References to s/u/e's defined elsewhere.  Rearrange things
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index 2dac344..e8ad1f6 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -5,6 +5,7 @@
 lex.*.c
 *.tab.c
 *.tab.h
+zconf.hash.c
 
 #
 # configuration programs
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index a96153f..5760e05 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -11,7 +11,7 @@
 	$< arch/$(ARCH)/Kconfig
 
 menuconfig: $(obj)/mconf
-	$(Q)$(MAKE) $(build)=scripts/lxdialog
+	$(Q)$(MAKE) $(build)=scripts/kconfig/lxdialog
 	$< arch/$(ARCH)/Kconfig
 
 config: $(obj)/conf
@@ -115,6 +115,7 @@
 
 clean-files	:= lkc_defs.h qconf.moc .tmp_qtcheck \
 		   .tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c
+subdir- += lxdialog
 
 # Needed for systems without gettext
 KBUILD_HAVE_NLS := $(shell \
@@ -132,8 +133,8 @@
 HOSTLOADLIBES_qconf	= $(KC_QT_LIBS) -ldl
 HOSTCXXFLAGS_qconf.o	= $(KC_QT_CFLAGS) -D LKC_DIRECT_LINK
 
-HOSTLOADLIBES_gconf	= `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs`
-HOSTCFLAGS_gconf.o	= `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \
+HOSTLOADLIBES_gconf	= `pkg-config --libs gtk+-2.0 gmodule-2.0 libglade-2.0`
+HOSTCFLAGS_gconf.o	= `pkg-config --cflags gtk+-2.0 gmodule-2.0 libglade-2.0` \
                           -D LKC_DIRECT_LINK
 
 $(obj)/qconf.o: $(obj)/.tmp_qtcheck
@@ -192,8 +193,8 @@
 
 # GTK needs some extra effort, too...
 $(obj)/.tmp_gtkcheck:
-	@if `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --exists`; then		\
-		if `pkg-config gtk+-2.0 --atleast-version=2.0.0`; then			\
+	@if `pkg-config --exists gtk+-2.0 gmodule-2.0 libglade-2.0`; then		\
+		if `pkg-config --atleast-version=2.0.0 gtk+-2.0`; then			\
 			touch $@;								\
 		else									\
 			echo "*"; 							\
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 8ba5d29..10eeae5 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -63,6 +63,20 @@
 	}
 }
 
+static char *fgets_check_stream(char *s, int size, FILE *stream)
+{
+	char *ret = fgets(s, size, stream);
+
+	if (ret == NULL && feof(stream)) {
+		printf(_("aborted!\n\n"));
+		printf(_("Console input is closed. "));
+		printf(_("Run 'make oldconfig' to update configuration.\n\n"));
+		exit(1);
+	}
+
+	return ret;
+}
+
 static void conf_askvalue(struct symbol *sym, const char *def)
 {
 	enum symbol_type type = sym_get_type(sym);
@@ -100,7 +114,7 @@
 		check_stdin();
 	case ask_all:
 		fflush(stdout);
-		fgets(line, 128, stdin);
+		fgets_check_stream(line, 128, stdin);
 		return;
 	case set_default:
 		printf("%s\n", def);
@@ -356,7 +370,7 @@
 			check_stdin();
 		case ask_all:
 			fflush(stdout);
-			fgets(line, 128, stdin);
+			fgets_check_stream(line, 128, stdin);
 			strip(line);
 			if (line[0] == '?') {
 				printf("\n%s\n", menu->sym->help ?
diff --git a/scripts/kconfig/lxdialog/.gitignore b/scripts/kconfig/lxdialog/.gitignore
new file mode 100644
index 0000000..90b08ff
--- /dev/null
+++ b/scripts/kconfig/lxdialog/.gitignore
@@ -0,0 +1,4 @@
+#
+# Generated files
+#
+lxdialog
diff --git a/scripts/lxdialog/BIG.FAT.WARNING b/scripts/kconfig/lxdialog/BIG.FAT.WARNING
similarity index 100%
rename from scripts/lxdialog/BIG.FAT.WARNING
rename to scripts/kconfig/lxdialog/BIG.FAT.WARNING
diff --git a/scripts/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile
similarity index 100%
rename from scripts/lxdialog/Makefile
rename to scripts/kconfig/lxdialog/Makefile
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
new file mode 100644
index 0000000..db07ae7
--- /dev/null
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -0,0 +1,334 @@
+/*
+ *  checklist.c -- implements the checklist box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
+ *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static int list_width, check_x, item_x;
+
+/*
+ * Print list item
+ */
+static void print_item(WINDOW * win, const char *item, int status, int choice,
+		       int selected)
+{
+	int i;
+
+	/* Clear 'residue' of last item */
+	wattrset(win, menubox_attr);
+	wmove(win, choice, 0);
+	for (i = 0; i < list_width; i++)
+		waddch(win, ' ');
+
+	wmove(win, choice, check_x);
+	wattrset(win, selected ? check_selected_attr : check_attr);
+	wprintw(win, "(%c)", status ? 'X' : ' ');
+
+	wattrset(win, selected ? tag_selected_attr : tag_attr);
+	mvwaddch(win, choice, item_x, item[0]);
+	wattrset(win, selected ? item_selected_attr : item_attr);
+	waddstr(win, (char *)item + 1);
+	if (selected) {
+		wmove(win, choice, check_x + 1);
+		wrefresh(win);
+	}
+}
+
+/*
+ * Print the scroll indicators.
+ */
+static void print_arrows(WINDOW * win, int choice, int item_no, int scroll,
+	     int y, int x, int height)
+{
+	wmove(win, y, x);
+
+	if (scroll > 0) {
+		wattrset(win, uarrow_attr);
+		waddch(win, ACS_UARROW);
+		waddstr(win, "(-)");
+	} else {
+		wattrset(win, menubox_attr);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+	}
+
+	y = y + height + 1;
+	wmove(win, y, x);
+
+	if ((height < item_no) && (scroll + choice < item_no - 1)) {
+		wattrset(win, darrow_attr);
+		waddch(win, ACS_DARROW);
+		waddstr(win, "(+)");
+	} else {
+		wattrset(win, menubox_border_attr);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+	}
+}
+
+/*
+ *  Display the termination buttons
+ */
+static void print_buttons(WINDOW * dialog, int height, int width, int selected)
+{
+	int x = width / 2 - 11;
+	int y = height - 2;
+
+	print_button(dialog, "Select", y, x, selected == 0);
+	print_button(dialog, " Help ", y, x + 14, selected == 1);
+
+	wmove(dialog, y, x + 1 + 14 * selected);
+	wrefresh(dialog);
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ * in the style of radiolist (only one option turned on at a time).
+ */
+int dialog_checklist(const char *title, const char *prompt, int height,
+		     int width, int list_height, int item_no,
+		     const char *const *items)
+{
+	int i, x, y, box_x, box_y;
+	int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
+	WINDOW *dialog, *list;
+
+	/* Allocate space for storing item on/off status */
+	if ((status = malloc(sizeof(int) * item_no)) == NULL) {
+		endwin();
+		fprintf(stderr,
+			"\nCan't allocate memory in dialog_checklist().\n");
+		exit(-1);
+	}
+
+	/* Initializes status */
+	for (i = 0; i < item_no; i++) {
+		status[i] = !strcasecmp(items[i * 3 + 2], "on");
+		if ((!choice && status[i])
+		    || !strcasecmp(items[i * 3 + 2], "selected"))
+			choice = i + 1;
+	}
+	if (choice)
+		choice--;
+
+	max_choice = MIN(list_height, item_no);
+
+	/* center dialog box on screen */
+	x = (COLS - width) / 2;
+	y = (LINES - height) / 2;
+
+	draw_shadow(stdscr, y, x, height, width);
+
+	dialog = newwin(height, width, y, x);
+	keypad(dialog, TRUE);
+
+	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+	wattrset(dialog, border_attr);
+	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+	for (i = 0; i < width - 2; i++)
+		waddch(dialog, ACS_HLINE);
+	wattrset(dialog, dialog_attr);
+	waddch(dialog, ACS_RTEE);
+
+	print_title(dialog, title, width);
+
+	wattrset(dialog, dialog_attr);
+	print_autowrap(dialog, prompt, width - 2, 1, 3);
+
+	list_width = width - 6;
+	box_y = height - list_height - 5;
+	box_x = (width - list_width) / 2 - 1;
+
+	/* create new window for the list */
+	list = subwin(dialog, list_height, list_width, y + box_y + 1,
+	              x + box_x + 1);
+
+	keypad(list, TRUE);
+
+	/* draw a box around the list items */
+	draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2,
+	         menubox_border_attr, menubox_attr);
+
+	/* Find length of longest item in order to center checklist */
+	check_x = 0;
+	for (i = 0; i < item_no; i++)
+		check_x = MAX(check_x, +strlen(items[i * 3 + 1]) + 4);
+
+	check_x = (list_width - check_x) / 2;
+	item_x = check_x + 4;
+
+	if (choice >= list_height) {
+		scroll = choice - list_height + 1;
+		choice -= scroll;
+	}
+
+	/* Print the list */
+	for (i = 0; i < max_choice; i++) {
+		print_item(list, items[(scroll + i) * 3 + 1],
+			   status[i + scroll], i, i == choice);
+	}
+
+	print_arrows(dialog, choice, item_no, scroll,
+		     box_y, box_x + check_x + 5, list_height);
+
+	print_buttons(dialog, height, width, 0);
+
+	wnoutrefresh(list);
+	wnoutrefresh(dialog);
+	doupdate();
+
+	while (key != ESC) {
+		key = wgetch(dialog);
+
+		for (i = 0; i < max_choice; i++)
+			if (toupper(key) ==
+			    toupper(items[(scroll + i) * 3 + 1][0]))
+				break;
+
+		if (i < max_choice || key == KEY_UP || key == KEY_DOWN ||
+		    key == '+' || key == '-') {
+			if (key == KEY_UP || key == '-') {
+				if (!choice) {
+					if (!scroll)
+						continue;
+					/* Scroll list down */
+					if (list_height > 1) {
+						/* De-highlight current first item */
+						print_item(list, items[scroll * 3 + 1],
+							   status[scroll], 0, FALSE);
+						scrollok(list, TRUE);
+						wscrl(list, -1);
+						scrollok(list, FALSE);
+					}
+					scroll--;
+					print_item(list, items[scroll * 3 + 1], status[scroll], 0, TRUE);
+					wnoutrefresh(list);
+
+					print_arrows(dialog, choice, item_no,
+						     scroll, box_y, box_x + check_x + 5, list_height);
+
+					wrefresh(dialog);
+
+					continue;	/* wait for another key press */
+				} else
+					i = choice - 1;
+			} else if (key == KEY_DOWN || key == '+') {
+				if (choice == max_choice - 1) {
+					if (scroll + choice >= item_no - 1)
+						continue;
+					/* Scroll list up */
+					if (list_height > 1) {
+						/* De-highlight current last item before scrolling up */
+						print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
+							   status[scroll + max_choice - 1],
+							   max_choice - 1, FALSE);
+						scrollok(list, TRUE);
+						wscrl(list, 1);
+						scrollok(list, FALSE);
+					}
+					scroll++;
+					print_item(list, items[(scroll + max_choice - 1) * 3 + 1],
+						   status[scroll + max_choice - 1], max_choice - 1, TRUE);
+					wnoutrefresh(list);
+
+					print_arrows(dialog, choice, item_no,
+						     scroll, box_y, box_x + check_x + 5, list_height);
+
+					wrefresh(dialog);
+
+					continue;	/* wait for another key press */
+				} else
+					i = choice + 1;
+			}
+			if (i != choice) {
+				/* De-highlight current item */
+				print_item(list, items[(scroll + choice) * 3 + 1],
+					   status[scroll + choice], choice, FALSE);
+				/* Highlight new item */
+				choice = i;
+				print_item(list, items[(scroll + choice) * 3 + 1],
+					   status[scroll + choice], choice, TRUE);
+				wnoutrefresh(list);
+				wrefresh(dialog);
+			}
+			continue;	/* wait for another key press */
+		}
+		switch (key) {
+		case 'H':
+		case 'h':
+		case '?':
+			fprintf(stderr, "%s", items[(scroll + choice) * 3]);
+			delwin(dialog);
+			free(status);
+			return 1;
+		case TAB:
+		case KEY_LEFT:
+		case KEY_RIGHT:
+			button = ((key == KEY_LEFT ? --button : ++button) < 0)
+			    ? 1 : (button > 1 ? 0 : button);
+
+			print_buttons(dialog, height, width, button);
+			wrefresh(dialog);
+			break;
+		case 'S':
+		case 's':
+		case ' ':
+		case '\n':
+			if (!button) {
+				if (!status[scroll + choice]) {
+					for (i = 0; i < item_no; i++)
+						status[i] = 0;
+					status[scroll + choice] = 1;
+					for (i = 0; i < max_choice; i++)
+						print_item(list, items[(scroll + i) * 3 + 1],
+							   status[scroll + i], i, i == choice);
+				}
+				wnoutrefresh(list);
+				wrefresh(dialog);
+
+				for (i = 0; i < item_no; i++)
+					if (status[i])
+						fprintf(stderr, "%s", items[i * 3]);
+			} else
+				fprintf(stderr, "%s", items[(scroll + choice) * 3]);
+			delwin(dialog);
+			free(status);
+			return button;
+		case 'X':
+		case 'x':
+			key = ESC;
+		case ESC:
+			break;
+		}
+
+		/* Now, update everything... */
+		doupdate();
+	}
+
+	delwin(dialog);
+	free(status);
+	return -1;		/* ESC pressed */
+}
diff --git a/scripts/lxdialog/colors.h b/scripts/kconfig/lxdialog/colors.h
similarity index 99%
rename from scripts/lxdialog/colors.h
rename to scripts/kconfig/lxdialog/colors.h
index 25c5952..db071df1 100644
--- a/scripts/lxdialog/colors.h
+++ b/scripts/kconfig/lxdialog/colors.h
@@ -18,7 +18,6 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-
 /*
  *   Default color definitions
  *
diff --git a/scripts/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
similarity index 75%
rename from scripts/lxdialog/dialog.h
rename to scripts/kconfig/lxdialog/dialog.h
index eb63e1b..af3cf71 100644
--- a/scripts/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -1,4 +1,3 @@
-
 /*
  *  dialog.h -- common declarations for all dialog modules
  *
@@ -42,7 +41,7 @@
 #if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
 #define OLD_NCURSES 1
 #undef  wbkgdset
-#define wbkgdset(w,p) /*nothing*/
+#define wbkgdset(w,p)		/*nothing */
 #else
 #define OLD_NCURSES 0
 #endif
@@ -56,7 +55,6 @@
 #define MIN(x,y) (x < y ? x : y)
 #define MAX(x,y) (x > y ? x : y)
 
-
 #ifndef ACS_ULCORNER
 #define ACS_ULCORNER '+'
 #endif
@@ -88,7 +86,7 @@
 #define ACS_DARROW 'v'
 #endif
 
-/* 
+/*
  * Attribute names
  */
 #define screen_attr                   attributes[0]
@@ -137,35 +135,35 @@
 /*
  * Function prototypes
  */
-extern void create_rc (const char *filename);
-extern int parse_rc (void);
+extern void create_rc(const char *filename);
+extern int parse_rc(void);
 
+void init_dialog(void);
+void end_dialog(void);
+void attr_clear(WINDOW * win, int height, int width, chtype attr);
+void dialog_clear(void);
+void color_setup(void);
+void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x);
+void print_button(WINDOW * win, const char *label, int y, int x, int selected);
+void print_title(WINDOW *dialog, const char *title, int width);
+void draw_box(WINDOW * win, int y, int x, int height, int width, chtype box,
+	      chtype border);
+void draw_shadow(WINDOW * win, int y, int x, int height, int width);
 
-void init_dialog (void);
-void end_dialog (void);
-void attr_clear (WINDOW * win, int height, int width, chtype attr);
-void dialog_clear (void);
-void color_setup (void);
-void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
-void print_button (WINDOW * win, const char *label, int y, int x, int selected);
-void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
-		chtype border);
-void draw_shadow (WINDOW * win, int y, int x, int height, int width);
-
-int first_alpha (const char *string, const char *exempt);
-int dialog_yesno (const char *title, const char *prompt, int height, int width);
-int dialog_msgbox (const char *title, const char *prompt, int height,
-		int width, int pause);
-int dialog_textbox (const char *title, const char *file, int height, int width);
-int dialog_menu (const char *title, const char *prompt, int height, int width,
-		int menu_height, const char *choice, int item_no, 
-		const char * const * items);
-int dialog_checklist (const char *title, const char *prompt, int height,
-		int width, int list_height, int item_no,
-		const char * const * items, int flag);
+int first_alpha(const char *string, const char *exempt);
+int dialog_yesno(const char *title, const char *prompt, int height, int width);
+int dialog_msgbox(const char *title, const char *prompt, int height,
+		  int width, int pause);
+int dialog_textbox(const char *title, const char *file, int height, int width);
+int dialog_menu(const char *title, const char *prompt, int height, int width,
+		int menu_height, const char *choice, int item_no,
+		const char *const *items);
+int dialog_checklist(const char *title, const char *prompt, int height,
+		     int width, int list_height, int item_no,
+		     const char *const *items);
 extern char dialog_input_result[];
-int dialog_inputbox (const char *title, const char *prompt, int height,
-		int width, const char *init);
+int dialog_inputbox(const char *title, const char *prompt, int height,
+		    int width, const char *init);
 
 /*
  * This is the base for fictitious keys, which activate
@@ -177,11 +175,3 @@
  *   -- uppercase chars are used to invoke the button (M_EVENT + 'O')
  */
 #define M_EVENT (KEY_MAX+1)
-
-
-/*
- * The `flag' parameter in checklist is used to select between
- * radiolist and checklist
- */
-#define FLAG_CHECK 1
-#define FLAG_RADIO 0
diff --git a/scripts/kconfig/lxdialog/inputbox.c b/scripts/kconfig/lxdialog/inputbox.c
new file mode 100644
index 0000000..7795037
--- /dev/null
+++ b/scripts/kconfig/lxdialog/inputbox.c
@@ -0,0 +1,224 @@
+/*
+ *  inputbox.c -- implements the input box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+char dialog_input_result[MAX_LEN + 1];
+
+/*
+ *  Print the termination buttons
+ */
+static void print_buttons(WINDOW * dialog, int height, int width, int selected)
+{
+	int x = width / 2 - 11;
+	int y = height - 2;
+
+	print_button(dialog, "  Ok  ", y, x, selected == 0);
+	print_button(dialog, " Help ", y, x + 14, selected == 1);
+
+	wmove(dialog, y, x + 1 + 14 * selected);
+	wrefresh(dialog);
+}
+
+/*
+ * Display a dialog box for inputing a string
+ */
+int dialog_inputbox(const char *title, const char *prompt, int height, int width,
+                    const char *init)
+{
+	int i, x, y, box_y, box_x, box_width;
+	int input_x = 0, scroll = 0, key = 0, button = -1;
+	char *instr = dialog_input_result;
+	WINDOW *dialog;
+
+	/* center dialog box on screen */
+	x = (COLS - width) / 2;
+	y = (LINES - height) / 2;
+
+	draw_shadow(stdscr, y, x, height, width);
+
+	dialog = newwin(height, width, y, x);
+	keypad(dialog, TRUE);
+
+	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+	wattrset(dialog, border_attr);
+	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+	for (i = 0; i < width - 2; i++)
+		waddch(dialog, ACS_HLINE);
+	wattrset(dialog, dialog_attr);
+	waddch(dialog, ACS_RTEE);
+
+	print_title(dialog, title, width);
+
+	wattrset(dialog, dialog_attr);
+	print_autowrap(dialog, prompt, width - 2, 1, 3);
+
+	/* Draw the input field box */
+	box_width = width - 6;
+	getyx(dialog, y, x);
+	box_y = y + 2;
+	box_x = (width - box_width) / 2;
+	draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, border_attr, dialog_attr);
+
+	print_buttons(dialog, height, width, 0);
+
+	/* Set up the initial value */
+	wmove(dialog, box_y, box_x);
+	wattrset(dialog, inputbox_attr);
+
+	if (!init)
+		instr[0] = '\0';
+	else
+		strcpy(instr, init);
+
+	input_x = strlen(instr);
+
+	if (input_x >= box_width) {
+		scroll = input_x - box_width + 1;
+		input_x = box_width - 1;
+		for (i = 0; i < box_width - 1; i++)
+			waddch(dialog, instr[scroll + i]);
+	} else {
+		waddstr(dialog, instr);
+	}
+
+	wmove(dialog, box_y, box_x + input_x);
+
+	wrefresh(dialog);
+
+	while (key != ESC) {
+		key = wgetch(dialog);
+
+		if (button == -1) {	/* Input box selected */
+			switch (key) {
+			case TAB:
+			case KEY_UP:
+			case KEY_DOWN:
+				break;
+			case KEY_LEFT:
+				continue;
+			case KEY_RIGHT:
+				continue;
+			case KEY_BACKSPACE:
+			case 127:
+				if (input_x || scroll) {
+					wattrset(dialog, inputbox_attr);
+					if (!input_x) {
+						scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
+						wmove(dialog, box_y, box_x);
+						for (i = 0; i < box_width; i++)
+							waddch(dialog,
+							       instr[scroll + input_x + i] ?
+							       instr[scroll + input_x + i] : ' ');
+						input_x = strlen(instr) - scroll;
+					} else
+						input_x--;
+					instr[scroll + input_x] = '\0';
+					mvwaddch(dialog, box_y, input_x + box_x, ' ');
+					wmove(dialog, box_y, input_x + box_x);
+					wrefresh(dialog);
+				}
+				continue;
+			default:
+				if (key < 0x100 && isprint(key)) {
+					if (scroll + input_x < MAX_LEN) {
+						wattrset(dialog, inputbox_attr);
+						instr[scroll + input_x] = key;
+						instr[scroll + input_x + 1] = '\0';
+						if (input_x == box_width - 1) {
+							scroll++;
+							wmove(dialog, box_y, box_x);
+							for (i = 0; i < box_width - 1; i++)
+								waddch(dialog, instr [scroll + i]);
+						} else {
+							wmove(dialog, box_y, input_x++ + box_x);
+							waddch(dialog, key);
+						}
+						wrefresh(dialog);
+					} else
+						flash();	/* Alarm user about overflow */
+					continue;
+				}
+			}
+		}
+		switch (key) {
+		case 'O':
+		case 'o':
+			delwin(dialog);
+			return 0;
+		case 'H':
+		case 'h':
+			delwin(dialog);
+			return 1;
+		case KEY_UP:
+		case KEY_LEFT:
+			switch (button) {
+			case -1:
+				button = 1;	/* Indicates "Cancel" button is selected */
+				print_buttons(dialog, height, width, 1);
+				break;
+			case 0:
+				button = -1;	/* Indicates input box is selected */
+				print_buttons(dialog, height, width, 0);
+				wmove(dialog, box_y, box_x + input_x);
+				wrefresh(dialog);
+				break;
+			case 1:
+				button = 0;	/* Indicates "OK" button is selected */
+				print_buttons(dialog, height, width, 0);
+				break;
+			}
+			break;
+		case TAB:
+		case KEY_DOWN:
+		case KEY_RIGHT:
+			switch (button) {
+			case -1:
+				button = 0;	/* Indicates "OK" button is selected */
+				print_buttons(dialog, height, width, 0);
+				break;
+			case 0:
+				button = 1;	/* Indicates "Cancel" button is selected */
+				print_buttons(dialog, height, width, 1);
+				break;
+			case 1:
+				button = -1;	/* Indicates input box is selected */
+				print_buttons(dialog, height, width, 0);
+				wmove(dialog, box_y, box_x + input_x);
+				wrefresh(dialog);
+				break;
+			}
+			break;
+		case ' ':
+		case '\n':
+			delwin(dialog);
+			return (button == -1 ? 0 : button);
+		case 'X':
+		case 'x':
+			key = ESC;
+		case ESC:
+			break;
+		}
+	}
+
+	delwin(dialog);
+	return -1;		/* ESC pressed */
+}
diff --git a/scripts/kconfig/lxdialog/lxdialog.c b/scripts/kconfig/lxdialog/lxdialog.c
new file mode 100644
index 0000000..79f6c5f
--- /dev/null
+++ b/scripts/kconfig/lxdialog/lxdialog.c
@@ -0,0 +1,204 @@
+/*
+ *  dialog - Display simple dialog boxes from shell scripts
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static void Usage(const char *name);
+
+typedef int (jumperFn) (const char *title, int argc, const char *const *argv);
+
+struct Mode {
+	char *name;
+	int argmin, argmax, argmod;
+	jumperFn *jumper;
+};
+
+jumperFn j_menu, j_radiolist, j_yesno, j_textbox, j_inputbox;
+jumperFn j_msgbox, j_infobox;
+
+static struct Mode modes[] = {
+	{"--menu", 9, 0, 3, j_menu},
+	{"--radiolist", 9, 0, 3, j_radiolist},
+	{"--yesno", 5, 5, 1, j_yesno},
+	{"--textbox", 5, 5, 1, j_textbox},
+	{"--inputbox", 5, 6, 1, j_inputbox},
+	{"--msgbox", 5, 5, 1, j_msgbox},
+	{"--infobox", 5, 5, 1, j_infobox},
+	{NULL, 0, 0, 0, NULL}
+};
+
+static struct Mode *modePtr;
+
+#ifdef LOCALE
+#include <locale.h>
+#endif
+
+int main(int argc, const char *const *argv)
+{
+	int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
+	const char *title = NULL;
+
+#ifdef LOCALE
+	(void)setlocale(LC_ALL, "");
+#endif
+
+#ifdef TRACE
+	trace(TRACE_CALLS | TRACE_UPDATE);
+#endif
+	if (argc < 2) {
+		Usage(argv[0]);
+		exit(-1);
+	}
+
+	while (offset < argc - 1 && !end_common_opts) {	/* Common options */
+		if (!strcmp(argv[offset + 1], "--title")) {
+			if (argc - offset < 3 || title != NULL) {
+				Usage(argv[0]);
+				exit(-1);
+			} else {
+				title = argv[offset + 2];
+				offset += 2;
+			}
+		} else if (!strcmp(argv[offset + 1], "--backtitle")) {
+			if (backtitle != NULL) {
+				Usage(argv[0]);
+				exit(-1);
+			} else {
+				backtitle = argv[offset + 2];
+				offset += 2;
+			}
+		} else if (!strcmp(argv[offset + 1], "--clear")) {
+			if (opt_clear) {	/* Hey, "--clear" can't appear twice! */
+				Usage(argv[0]);
+				exit(-1);
+			} else if (argc == 2) {	/* we only want to clear the screen */
+				init_dialog();
+				refresh();	/* init_dialog() will clear the screen for us */
+				end_dialog();
+				return 0;
+			} else {
+				opt_clear = 1;
+				offset++;
+			}
+		} else		/* no more common options */
+			end_common_opts = 1;
+	}
+
+	if (argc - 1 == offset) {	/* no more options */
+		Usage(argv[0]);
+		exit(-1);
+	}
+	/* use a table to look for the requested mode, to avoid code duplication */
+
+	for (modePtr = modes; modePtr->name; modePtr++)	/* look for the mode */
+		if (!strcmp(argv[offset + 1], modePtr->name))
+			break;
+
+	if (!modePtr->name)
+		Usage(argv[0]);
+	if (argc - offset < modePtr->argmin)
+		Usage(argv[0]);
+	if (modePtr->argmax && argc - offset > modePtr->argmax)
+		Usage(argv[0]);
+
+	init_dialog();
+	retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
+
+	if (opt_clear) {	/* clear screen before exit */
+		attr_clear(stdscr, LINES, COLS, screen_attr);
+		refresh();
+	}
+	end_dialog();
+
+	exit(retval);
+}
+
+/*
+ * Print program usage
+ */
+static void Usage(const char *name)
+{
+	fprintf(stderr, "\
+\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
+\n  patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
+\n  modified/gutted for use as a Linux kernel config tool by \
+\n  William Roadcap (roadcapw@cfw.com)\
+\n\
+\n* Display dialog boxes from shell scripts *\
+\n\
+\nUsage: %s --clear\
+\n       %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
+\n\
+\nBox options:\
+\n\
+\n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
+\n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
+\n  --textbox   <file> <height> <width>\
+\n  --inputbox  <text> <height> <width> [<init>]\
+\n  --yesno     <text> <height> <width>\
+\n", name, name);
+	exit(-1);
+}
+
+/*
+ * These are the program jumpers
+ */
+
+int j_menu(const char *t, int ac, const char *const *av)
+{
+	return dialog_menu(t, av[2], atoi(av[3]), atoi(av[4]),
+			   atoi(av[5]), av[6], (ac - 6) / 2, av + 7);
+}
+
+int j_radiolist(const char *t, int ac, const char *const *av)
+{
+	return dialog_checklist(t, av[2], atoi(av[3]), atoi(av[4]),
+				atoi(av[5]), (ac - 6) / 3, av + 6);
+}
+
+int j_textbox(const char *t, int ac, const char *const *av)
+{
+	return dialog_textbox(t, av[2], atoi(av[3]), atoi(av[4]));
+}
+
+int j_yesno(const char *t, int ac, const char *const *av)
+{
+	return dialog_yesno(t, av[2], atoi(av[3]), atoi(av[4]));
+}
+
+int j_inputbox(const char *t, int ac, const char *const *av)
+{
+	int ret = dialog_inputbox(t, av[2], atoi(av[3]), atoi(av[4]),
+				  ac == 6 ? av[5] : (char *)NULL);
+	if (ret == 0)
+		fprintf(stderr, dialog_input_result);
+	return ret;
+}
+
+int j_msgbox(const char *t, int ac, const char *const *av)
+{
+	return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 1);
+}
+
+int j_infobox(const char *t, int ac, const char *const *av)
+{
+	return dialog_msgbox(t, av[2], atoi(av[3]), atoi(av[4]), 0);
+}
diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c
new file mode 100644
index 0000000..09512b5
--- /dev/null
+++ b/scripts/kconfig/lxdialog/menubox.c
@@ -0,0 +1,425 @@
+/*
+ *  menubox.c -- implements the menu box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *  Changes by Clifford Wolf (god@clifford.at)
+ *
+ *  [ 1998-06-13 ]
+ *
+ *    *)  A bugfix for the Page-Down problem
+ *
+ *    *)  Formerly when I used Page Down and Page Up, the cursor would be set 
+ *        to the first position in the menu box.  Now lxdialog is a bit
+ *        smarter and works more like other menu systems (just have a look at
+ *        it).
+ *
+ *    *)  Formerly if I selected something my scrolling would be broken because
+ *        lxdialog is re-invoked by the Menuconfig shell script, can't
+ *        remember the last scrolling position, and just sets it so that the
+ *        cursor is at the bottom of the box.  Now it writes the temporary file
+ *        lxdialog.scrltmp which contains this information. The file is
+ *        deleted by lxdialog if the user leaves a submenu or enters a new
+ *        one, but it would be nice if Menuconfig could make another "rm -f"
+ *        just to be sure.  Just try it out - you will recognise a difference!
+ *
+ *  [ 1998-06-14 ]
+ *
+ *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
+ *        and menus change their size on the fly.
+ *
+ *    *)  If for some reason the last scrolling position is not saved by
+ *        lxdialog, it sets the scrolling so that the selected item is in the
+ *        middle of the menu box, not at the bottom.
+ *
+ * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
+ * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
+ * This fixes a bug in Menuconfig where using ' ' to descend into menus
+ * would leave mis-synchronized lxdialog.scrltmp files lying around,
+ * fscanf would read in 'scroll', and eventually that value would get used.
+ */
+
+#include "dialog.h"
+
+#define ITEM_IDENT 1   /* Indent of menu entries. Fixed for all menus */
+static int menu_width;
+
+/*
+ * Print menu item
+ */
+static void do_print_item(WINDOW * win, const char *item, int choice,
+                          int selected, int hotkey)
+{
+	int j;
+	char *menu_item = malloc(menu_width + 1);
+
+	strncpy(menu_item, item, menu_width - ITEM_IDENT);
+	menu_item[menu_width] = 0;
+	j = first_alpha(menu_item, "YyNnMmHh");
+
+	/* Clear 'residue' of last item */
+	wattrset(win, menubox_attr);
+	wmove(win, choice, 0);
+#if OLD_NCURSES
+	{
+		int i;
+		for (i = 0; i < menu_width; i++)
+			waddch(win, ' ');
+	}
+#else
+	wclrtoeol(win);
+#endif
+	wattrset(win, selected ? item_selected_attr : item_attr);
+	mvwaddstr(win, choice, ITEM_IDENT, menu_item);
+	if (hotkey) {
+		wattrset(win, selected ? tag_key_selected_attr : tag_key_attr);
+		mvwaddch(win, choice, ITEM_IDENT + j, menu_item[j]);
+	}
+	if (selected) {
+		wmove(win, choice, ITEM_IDENT + 1);
+	}
+	free(menu_item);
+	wrefresh(win);
+}
+
+#define print_item(index, choice, selected) \
+do {\
+	int hotkey = (items[(index) * 2][0] != ':'); \
+	do_print_item(menu, items[(index) * 2 + 1], choice, selected, hotkey); \
+} while (0)
+
+/*
+ * Print the scroll indicators.
+ */
+static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
+			 int height)
+{
+	int cur_y, cur_x;
+
+	getyx(win, cur_y, cur_x);
+
+	wmove(win, y, x);
+
+	if (scroll > 0) {
+		wattrset(win, uarrow_attr);
+		waddch(win, ACS_UARROW);
+		waddstr(win, "(-)");
+	} else {
+		wattrset(win, menubox_attr);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+	}
+
+	y = y + height + 1;
+	wmove(win, y, x);
+	wrefresh(win);
+
+	if ((height < item_no) && (scroll + height < item_no)) {
+		wattrset(win, darrow_attr);
+		waddch(win, ACS_DARROW);
+		waddstr(win, "(+)");
+	} else {
+		wattrset(win, menubox_border_attr);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+		waddch(win, ACS_HLINE);
+	}
+
+	wmove(win, cur_y, cur_x);
+	wrefresh(win);
+}
+
+/*
+ * Display the termination buttons.
+ */
+static void print_buttons(WINDOW * win, int height, int width, int selected)
+{
+	int x = width / 2 - 16;
+	int y = height - 2;
+
+	print_button(win, "Select", y, x, selected == 0);
+	print_button(win, " Exit ", y, x + 12, selected == 1);
+	print_button(win, " Help ", y, x + 24, selected == 2);
+
+	wmove(win, y, x + 1 + 12 * selected);
+	wrefresh(win);
+}
+
+/* scroll up n lines (n may be negative) */
+static void do_scroll(WINDOW *win, int *scroll, int n)
+{
+	/* Scroll menu up */
+	scrollok(win, TRUE);
+	wscrl(win, n);
+	scrollok(win, FALSE);
+	*scroll = *scroll + n;
+	wrefresh(win);
+}
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+int dialog_menu(const char *title, const char *prompt, int height, int width,
+                int menu_height, const char *current, int item_no,
+                const char *const *items)
+{
+	int i, j, x, y, box_x, box_y;
+	int key = 0, button = 0, scroll = 0, choice = 0;
+	int first_item =  0, max_choice;
+	WINDOW *dialog, *menu;
+	FILE *f;
+
+	max_choice = MIN(menu_height, item_no);
+
+	/* center dialog box on screen */
+	x = (COLS - width) / 2;
+	y = (LINES - height) / 2;
+
+	draw_shadow(stdscr, y, x, height, width);
+
+	dialog = newwin(height, width, y, x);
+	keypad(dialog, TRUE);
+
+	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+	wattrset(dialog, border_attr);
+	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+	for (i = 0; i < width - 2; i++)
+		waddch(dialog, ACS_HLINE);
+	wattrset(dialog, dialog_attr);
+	wbkgdset(dialog, dialog_attr & A_COLOR);
+	waddch(dialog, ACS_RTEE);
+
+	print_title(dialog, title, width);
+
+	wattrset(dialog, dialog_attr);
+	print_autowrap(dialog, prompt, width - 2, 1, 3);
+
+	menu_width = width - 6;
+	box_y = height - menu_height - 5;
+	box_x = (width - menu_width) / 2 - 1;
+
+	/* create new window for the menu */
+	menu = subwin(dialog, menu_height, menu_width,
+		      y + box_y + 1, x + box_x + 1);
+	keypad(menu, TRUE);
+
+	/* draw a box around the menu items */
+	draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
+		 menubox_border_attr, menubox_attr);
+
+	/* Set choice to default item */
+	for (i = 0; i < item_no; i++)
+		if (strcmp(current, items[i * 2]) == 0)
+			choice = i;
+
+	/* get the scroll info from the temp file */
+	if ((f = fopen("lxdialog.scrltmp", "r")) != NULL) {
+		if ((fscanf(f, "%d\n", &scroll) == 1) && (scroll <= choice) &&
+		    (scroll + max_choice > choice) && (scroll >= 0) &&
+		    (scroll + max_choice <= item_no)) {
+			first_item = scroll;
+			choice = choice - scroll;
+			fclose(f);
+		} else {
+			scroll = 0;
+			remove("lxdialog.scrltmp");
+			fclose(f);
+			f = NULL;
+		}
+	}
+	if ((choice >= max_choice) || (f == NULL && choice >= max_choice / 2)) {
+		if (choice >= item_no - max_choice / 2)
+			scroll = first_item = item_no - max_choice;
+		else
+			scroll = first_item = choice - max_choice / 2;
+		choice = choice - scroll;
+	}
+
+	/* Print the menu */
+	for (i = 0; i < max_choice; i++) {
+		print_item(first_item + i, i, i == choice);
+	}
+
+	wnoutrefresh(menu);
+
+	print_arrows(dialog, item_no, scroll,
+		     box_y, box_x + ITEM_IDENT + 1, menu_height);
+
+	print_buttons(dialog, height, width, 0);
+	wmove(menu, choice, ITEM_IDENT + 1);
+	wrefresh(menu);
+
+	while (key != ESC) {
+		key = wgetch(menu);
+
+		if (key < 256 && isalpha(key))
+			key = tolower(key);
+
+		if (strchr("ynmh", key))
+			i = max_choice;
+		else {
+			for (i = choice + 1; i < max_choice; i++) {
+				j = first_alpha(items[(scroll + i) * 2 + 1], "YyNnMmHh");
+				if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+					break;
+			}
+			if (i == max_choice)
+				for (i = 0; i < max_choice; i++) {
+					j = first_alpha(items [(scroll + i) * 2 + 1], "YyNnMmHh");
+					if (key == tolower(items[(scroll + i) * 2 + 1][j]))
+						break;
+				}
+		}
+
+		if (i < max_choice ||
+		    key == KEY_UP || key == KEY_DOWN ||
+		    key == '-' || key == '+' ||
+		    key == KEY_PPAGE || key == KEY_NPAGE) {
+			/* Remove highligt of current item */
+			print_item(scroll + choice, choice, FALSE);
+
+			if (key == KEY_UP || key == '-') {
+				if (choice < 2 && scroll) {
+					/* Scroll menu down */
+					do_scroll(menu, &scroll, -1);
+
+					print_item(scroll, 0, FALSE);
+				} else
+					choice = MAX(choice - 1, 0);
+
+			} else if (key == KEY_DOWN || key == '+') {
+				print_item(scroll+choice, choice, FALSE);
+
+				if ((choice > max_choice - 3) &&
+				    (scroll + max_choice < item_no)) {
+					/* Scroll menu up */
+					do_scroll(menu, &scroll, 1);
+
+					print_item(scroll+max_choice - 1,
+						   max_choice - 1, FALSE);
+				} else
+					choice = MIN(choice + 1, max_choice - 1);
+
+			} else if (key == KEY_PPAGE) {
+				scrollok(menu, TRUE);
+				for (i = 0; (i < max_choice); i++) {
+					if (scroll > 0) {
+						do_scroll(menu, &scroll, -1);
+						print_item(scroll, 0, FALSE);
+					} else {
+						if (choice > 0)
+							choice--;
+					}
+				}
+
+			} else if (key == KEY_NPAGE) {
+				for (i = 0; (i < max_choice); i++) {
+					if (scroll + max_choice < item_no) {
+						do_scroll(menu, &scroll, 1);
+						print_item(scroll+max_choice-1,
+							   max_choice - 1, FALSE);
+					} else {
+						if (choice + 1 < max_choice)
+							choice++;
+					}
+				}
+			} else
+				choice = i;
+
+			print_item(scroll + choice, choice, TRUE);
+
+			print_arrows(dialog, item_no, scroll,
+				     box_y, box_x + ITEM_IDENT + 1, menu_height);
+
+			wnoutrefresh(dialog);
+			wrefresh(menu);
+
+			continue;	/* wait for another key press */
+		}
+
+		switch (key) {
+		case KEY_LEFT:
+		case TAB:
+		case KEY_RIGHT:
+			button = ((key == KEY_LEFT ? --button : ++button) < 0)
+			    ? 2 : (button > 2 ? 0 : button);
+
+			print_buttons(dialog, height, width, button);
+			wrefresh(menu);
+			break;
+		case ' ':
+		case 's':
+		case 'y':
+		case 'n':
+		case 'm':
+		case '/':
+			/* save scroll info */
+			if ((f = fopen("lxdialog.scrltmp", "w")) != NULL) {
+				fprintf(f, "%d\n", scroll);
+				fclose(f);
+			}
+			delwin(dialog);
+			fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
+			switch (key) {
+			case 's':
+				return 3;
+			case 'y':
+				return 3;
+			case 'n':
+				return 4;
+			case 'm':
+				return 5;
+			case ' ':
+				return 6;
+			case '/':
+				return 7;
+			}
+			return 0;
+		case 'h':
+		case '?':
+			button = 2;
+		case '\n':
+			delwin(dialog);
+			if (button == 2)
+				fprintf(stderr, "%s \"%s\"\n",
+					items[(scroll + choice) * 2],
+					items[(scroll + choice) * 2 + 1] +
+					first_alpha(items [(scroll + choice) * 2 + 1], ""));
+			else
+				fprintf(stderr, "%s\n",
+					items[(scroll + choice) * 2]);
+
+			remove("lxdialog.scrltmp");
+			return button;
+		case 'e':
+		case 'x':
+			key = ESC;
+		case ESC:
+			break;
+		}
+	}
+
+	delwin(dialog);
+	remove("lxdialog.scrltmp");
+	return -1;		/* ESC pressed */
+}
diff --git a/scripts/kconfig/lxdialog/msgbox.c b/scripts/kconfig/lxdialog/msgbox.c
new file mode 100644
index 0000000..7323f54
--- /dev/null
+++ b/scripts/kconfig/lxdialog/msgbox.c
@@ -0,0 +1,71 @@
+/*
+ *  msgbox.c -- implements the message box and info box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display a message box. Program will pause and display an "OK" button
+ * if the parameter 'pause' is non-zero.
+ */
+int dialog_msgbox(const char *title, const char *prompt, int height, int width,
+                  int pause)
+{
+	int i, x, y, key = 0;
+	WINDOW *dialog;
+
+	/* center dialog box on screen */
+	x = (COLS - width) / 2;
+	y = (LINES - height) / 2;
+
+	draw_shadow(stdscr, y, x, height, width);
+
+	dialog = newwin(height, width, y, x);
+	keypad(dialog, TRUE);
+
+	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+	print_title(dialog, title, width);
+
+	wattrset(dialog, dialog_attr);
+	print_autowrap(dialog, prompt, width - 2, 1, 2);
+
+	if (pause) {
+		wattrset(dialog, border_attr);
+		mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+		for (i = 0; i < width - 2; i++)
+			waddch(dialog, ACS_HLINE);
+		wattrset(dialog, dialog_attr);
+		waddch(dialog, ACS_RTEE);
+
+		print_button(dialog, "  Ok  ", height - 2, width / 2 - 4, TRUE);
+
+		wrefresh(dialog);
+		while (key != ESC && key != '\n' && key != ' ' &&
+		       key != 'O' && key != 'o' && key != 'X' && key != 'x')
+			key = wgetch(dialog);
+	} else {
+		key = '\n';
+		wrefresh(dialog);
+	}
+
+	delwin(dialog);
+	return key == ESC ? -1 : 0;
+}
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
new file mode 100644
index 0000000..77848bb
--- /dev/null
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -0,0 +1,533 @@
+/*
+ *  textbox.c -- implements the text box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+static void back_lines(int n);
+static void print_page(WINDOW * win, int height, int width);
+static void print_line(WINDOW * win, int row, int width);
+static char *get_line(void);
+static void print_position(WINDOW * win, int height, int width);
+
+static int hscroll, fd, file_size, bytes_read;
+static int begin_reached = 1, end_reached, page_length;
+static char *buf, *page;
+
+/*
+ * Display text from a file in a dialog box.
+ */
+int dialog_textbox(const char *title, const char *file, int height, int width)
+{
+	int i, x, y, cur_x, cur_y, fpos, key = 0;
+	int passed_end;
+	char search_term[MAX_LEN + 1];
+	WINDOW *dialog, *text;
+
+	search_term[0] = '\0';	/* no search term entered yet */
+
+	/* Open input file for reading */
+	if ((fd = open(file, O_RDONLY)) == -1) {
+		endwin();
+		fprintf(stderr, "\nCan't open input file in dialog_textbox().\n");
+		exit(-1);
+	}
+	/* Get file size. Actually, 'file_size' is the real file size - 1,
+	   since it's only the last byte offset from the beginning */
+	if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
+		endwin();
+		fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
+		exit(-1);
+	}
+	/* Restore file pointer to beginning of file after getting file size */
+	if (lseek(fd, 0, SEEK_SET) == -1) {
+		endwin();
+		fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+		exit(-1);
+	}
+	/* Allocate space for read buffer */
+	if ((buf = malloc(BUF_SIZE + 1)) == NULL) {
+		endwin();
+		fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
+		exit(-1);
+	}
+	if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
+		endwin();
+		fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+		exit(-1);
+	}
+	buf[bytes_read] = '\0';	/* mark end of valid data */
+	page = buf;		/* page is pointer to start of page to be displayed */
+
+	/* center dialog box on screen */
+	x = (COLS - width) / 2;
+	y = (LINES - height) / 2;
+
+	draw_shadow(stdscr, y, x, height, width);
+
+	dialog = newwin(height, width, y, x);
+	keypad(dialog, TRUE);
+
+	/* Create window for text region, used for scrolling text */
+	text = subwin(dialog, height - 4, width - 2, y + 1, x + 1);
+	wattrset(text, dialog_attr);
+	wbkgdset(text, dialog_attr & A_COLOR);
+
+	keypad(text, TRUE);
+
+	/* register the new window, along with its borders */
+	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+
+	wattrset(dialog, border_attr);
+	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+	for (i = 0; i < width - 2; i++)
+		waddch(dialog, ACS_HLINE);
+	wattrset(dialog, dialog_attr);
+	wbkgdset(dialog, dialog_attr & A_COLOR);
+	waddch(dialog, ACS_RTEE);
+
+	print_title(dialog, title, width);
+
+	print_button(dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
+	wnoutrefresh(dialog);
+	getyx(dialog, cur_y, cur_x);	/* Save cursor position */
+
+	/* Print first page of text */
+	attr_clear(text, height - 4, width - 2, dialog_attr);
+	print_page(text, height - 4, width - 2);
+	print_position(dialog, height, width);
+	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
+	wrefresh(dialog);
+
+	while ((key != ESC) && (key != '\n')) {
+		key = wgetch(dialog);
+		switch (key) {
+		case 'E':	/* Exit */
+		case 'e':
+		case 'X':
+		case 'x':
+			delwin(dialog);
+			free(buf);
+			close(fd);
+			return 0;
+		case 'g':	/* First page */
+		case KEY_HOME:
+			if (!begin_reached) {
+				begin_reached = 1;
+				/* First page not in buffer? */
+				if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+					endwin();
+					fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+					exit(-1);
+				}
+				if (fpos > bytes_read) {	/* Yes, we have to read it in */
+					if (lseek(fd, 0, SEEK_SET) == -1) {
+						endwin();
+						fprintf(stderr, "\nError moving file pointer in "
+							        "dialog_textbox().\n");
+						exit(-1);
+					}
+					if ((bytes_read =
+					     read(fd, buf, BUF_SIZE)) == -1) {
+						endwin();
+						fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+						exit(-1);
+					}
+					buf[bytes_read] = '\0';
+				}
+				page = buf;
+				print_page(text, height - 4, width - 2);
+				print_position(dialog, height, width);
+				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
+				wrefresh(dialog);
+			}
+			break;
+		case 'G':	/* Last page */
+		case KEY_END:
+
+			end_reached = 1;
+			/* Last page not in buffer? */
+			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+				endwin();
+				fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+				exit(-1);
+			}
+			if (fpos < file_size) {	/* Yes, we have to read it in */
+				if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
+					endwin();
+					fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
+					exit(-1);
+				}
+				if ((bytes_read =
+				     read(fd, buf, BUF_SIZE)) == -1) {
+					endwin();
+					fprintf(stderr, "\nError reading file in dialog_textbox().\n");
+					exit(-1);
+				}
+				buf[bytes_read] = '\0';
+			}
+			page = buf + bytes_read;
+			back_lines(height - 4);
+			print_page(text, height - 4, width - 2);
+			print_position(dialog, height, width);
+			wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
+			wrefresh(dialog);
+			break;
+		case 'K':	/* Previous line */
+		case 'k':
+		case KEY_UP:
+			if (!begin_reached) {
+				back_lines(page_length + 1);
+
+				/* We don't call print_page() here but use scrolling to ensure
+				   faster screen update. However, 'end_reached' and
+				   'page_length' should still be updated, and 'page' should
+				   point to start of next page. This is done by calling
+				   get_line() in the following 'for' loop. */
+				scrollok(text, TRUE);
+				wscrl(text, -1);	/* Scroll text region down one line */
+				scrollok(text, FALSE);
+				page_length = 0;
+				passed_end = 0;
+				for (i = 0; i < height - 4; i++) {
+					if (!i) {
+						/* print first line of page */
+						print_line(text, 0, width - 2);
+						wnoutrefresh(text);
+					} else
+						/* Called to update 'end_reached' and 'page' */
+						get_line();
+					if (!passed_end)
+						page_length++;
+					if (end_reached && !passed_end)
+						passed_end = 1;
+				}
+
+				print_position(dialog, height, width);
+				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
+				wrefresh(dialog);
+			}
+			break;
+		case 'B':	/* Previous page */
+		case 'b':
+		case KEY_PPAGE:
+			if (begin_reached)
+				break;
+			back_lines(page_length + height - 4);
+			print_page(text, height - 4, width - 2);
+			print_position(dialog, height, width);
+			wmove(dialog, cur_y, cur_x);
+			wrefresh(dialog);
+			break;
+		case 'J':	/* Next line */
+		case 'j':
+		case KEY_DOWN:
+			if (!end_reached) {
+				begin_reached = 0;
+				scrollok(text, TRUE);
+				scroll(text);	/* Scroll text region up one line */
+				scrollok(text, FALSE);
+				print_line(text, height - 5, width - 2);
+				wnoutrefresh(text);
+				print_position(dialog, height, width);
+				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
+				wrefresh(dialog);
+			}
+			break;
+		case KEY_NPAGE:	/* Next page */
+		case ' ':
+			if (end_reached)
+				break;
+
+			begin_reached = 0;
+			print_page(text, height - 4, width - 2);
+			print_position(dialog, height, width);
+			wmove(dialog, cur_y, cur_x);
+			wrefresh(dialog);
+			break;
+		case '0':	/* Beginning of line */
+		case 'H':	/* Scroll left */
+		case 'h':
+		case KEY_LEFT:
+			if (hscroll <= 0)
+				break;
+
+			if (key == '0')
+				hscroll = 0;
+			else
+				hscroll--;
+			/* Reprint current page to scroll horizontally */
+			back_lines(page_length);
+			print_page(text, height - 4, width - 2);
+			wmove(dialog, cur_y, cur_x);
+			wrefresh(dialog);
+			break;
+		case 'L':	/* Scroll right */
+		case 'l':
+		case KEY_RIGHT:
+			if (hscroll >= MAX_LEN)
+				break;
+			hscroll++;
+			/* Reprint current page to scroll horizontally */
+			back_lines(page_length);
+			print_page(text, height - 4, width - 2);
+			wmove(dialog, cur_y, cur_x);
+			wrefresh(dialog);
+			break;
+		case ESC:
+			break;
+		}
+	}
+
+	delwin(dialog);
+	free(buf);
+	close(fd);
+	return -1;		/* ESC pressed */
+}
+
+/*
+ * Go back 'n' lines in text file. Called by dialog_textbox().
+ * 'page' will be updated to point to the desired line in 'buf'.
+ */
+static void back_lines(int n)
+{
+	int i, fpos;
+
+	begin_reached = 0;
+	/* We have to distinguish between end_reached and !end_reached
+	   since at end of file, the line is not ended by a '\n'.
+	   The code inside 'if' basically does a '--page' to move one
+	   character backward so as to skip '\n' of the previous line */
+	if (!end_reached) {
+		/* Either beginning of buffer or beginning of file reached? */
+		if (page == buf) {
+			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+				endwin();
+				fprintf(stderr, "\nError moving file pointer in "
+					        "back_lines().\n");
+				exit(-1);
+			}
+			if (fpos > bytes_read) {	/* Not beginning of file yet */
+				/* We've reached beginning of buffer, but not beginning of
+				   file yet, so read previous part of file into buffer.
+				   Note that we only move backward for BUF_SIZE/2 bytes,
+				   but not BUF_SIZE bytes to avoid re-reading again in
+				   print_page() later */
+				/* Really possible to move backward BUF_SIZE/2 bytes? */
+				if (fpos < BUF_SIZE / 2 + bytes_read) {
+					/* No, move less then */
+					if (lseek(fd, 0, SEEK_SET) == -1) {
+						endwin();
+						fprintf(stderr, "\nError moving file pointer in "
+						                "back_lines().\n");
+						exit(-1);
+					}
+					page = buf + fpos - bytes_read;
+				} else {	/* Move backward BUF_SIZE/2 bytes */
+					if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
+						endwin();
+						fprintf(stderr, "\nError moving file pointer "
+						                "in back_lines().\n");
+						exit(-1);
+					}
+					page = buf + BUF_SIZE / 2;
+				}
+				if ((bytes_read =
+				     read(fd, buf, BUF_SIZE)) == -1) {
+					endwin();
+					fprintf(stderr, "\nError reading file in back_lines().\n");
+					exit(-1);
+				}
+				buf[bytes_read] = '\0';
+			} else {	/* Beginning of file reached */
+				begin_reached = 1;
+				return;
+			}
+		}
+		if (*(--page) != '\n') {	/* '--page' here */
+			/* Something's wrong... */
+			endwin();
+			fprintf(stderr, "\nInternal error in back_lines().\n");
+			exit(-1);
+		}
+	}
+	/* Go back 'n' lines */
+	for (i = 0; i < n; i++)
+		do {
+			if (page == buf) {
+				if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+					endwin();
+					fprintf(stderr, "\nError moving file pointer in back_lines().\n");
+					exit(-1);
+				}
+				if (fpos > bytes_read) {
+					/* Really possible to move backward BUF_SIZE/2 bytes? */
+					if (fpos < BUF_SIZE / 2 + bytes_read) {
+						/* No, move less then */
+						if (lseek(fd, 0, SEEK_SET) == -1) {
+							endwin();
+							fprintf(stderr, "\nError moving file pointer "
+							                "in back_lines().\n");
+							exit(-1);
+						}
+						page = buf + fpos - bytes_read;
+					} else {	/* Move backward BUF_SIZE/2 bytes */
+						if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) == -1) {
+							endwin();
+							fprintf(stderr, "\nError moving file pointer"
+							                " in back_lines().\n");
+							exit(-1);
+						}
+						page = buf + BUF_SIZE / 2;
+					}
+					if ((bytes_read =
+					     read(fd, buf, BUF_SIZE)) == -1) {
+						endwin();
+						fprintf(stderr, "\nError reading file in "
+						                "back_lines().\n");
+						exit(-1);
+					}
+					buf[bytes_read] = '\0';
+				} else {	/* Beginning of file reached */
+					begin_reached = 1;
+					return;
+				}
+			}
+		} while (*(--page) != '\n');
+	page++;
+}
+
+/*
+ * Print a new page of text. Called by dialog_textbox().
+ */
+static void print_page(WINDOW * win, int height, int width)
+{
+	int i, passed_end = 0;
+
+	page_length = 0;
+	for (i = 0; i < height; i++) {
+		print_line(win, i, width);
+		if (!passed_end)
+			page_length++;
+		if (end_reached && !passed_end)
+			passed_end = 1;
+	}
+	wnoutrefresh(win);
+}
+
+/*
+ * Print a new line of text. Called by dialog_textbox() and print_page().
+ */
+static void print_line(WINDOW * win, int row, int width)
+{
+	int y, x;
+	char *line;
+
+	line = get_line();
+	line += MIN(strlen(line), hscroll);	/* Scroll horizontally */
+	wmove(win, row, 0);	/* move cursor to correct line */
+	waddch(win, ' ');
+	waddnstr(win, line, MIN(strlen(line), width - 2));
+
+	getyx(win, y, x);
+	/* Clear 'residue' of previous line */
+#if OLD_NCURSES
+	{
+		int i;
+		for (i = 0; i < width - x; i++)
+			waddch(win, ' ');
+	}
+#else
+	wclrtoeol(win);
+#endif
+}
+
+/*
+ * Return current line of text. Called by dialog_textbox() and print_line().
+ * 'page' should point to start of current line before calling, and will be
+ * updated to point to start of next line.
+ */
+static char *get_line(void)
+{
+	int i = 0, fpos;
+	static char line[MAX_LEN + 1];
+
+	end_reached = 0;
+	while (*page != '\n') {
+		if (*page == '\0') {
+			/* Either end of file or end of buffer reached */
+			if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+				endwin();
+				fprintf(stderr, "\nError moving file pointer in "
+				                "get_line().\n");
+				exit(-1);
+			}
+			if (fpos < file_size) {	/* Not end of file yet */
+				/* We've reached end of buffer, but not end of file yet,
+				   so read next part of file into buffer */
+				if ((bytes_read =
+				     read(fd, buf, BUF_SIZE)) == -1) {
+					endwin();
+					fprintf(stderr, "\nError reading file in get_line().\n");
+					exit(-1);
+				}
+				buf[bytes_read] = '\0';
+				page = buf;
+			} else {
+				if (!end_reached)
+					end_reached = 1;
+				break;
+			}
+		} else if (i < MAX_LEN)
+			line[i++] = *(page++);
+		else {
+			/* Truncate lines longer than MAX_LEN characters */
+			if (i == MAX_LEN)
+				line[i++] = '\0';
+			page++;
+		}
+	}
+	if (i <= MAX_LEN)
+		line[i] = '\0';
+	if (!end_reached)
+		page++;		/* move pass '\n' */
+
+	return line;
+}
+
+/*
+ * Print current position
+ */
+static void print_position(WINDOW * win, int height, int width)
+{
+	int fpos, percent;
+
+	if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
+		endwin();
+		fprintf(stderr, "\nError moving file pointer in print_position().\n");
+		exit(-1);
+	}
+	wattrset(win, position_indicator_attr);
+	wbkgdset(win, position_indicator_attr & A_COLOR);
+	percent = !file_size ?
+	    100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
+	wmove(win, height - 3, width - 9);
+	wprintw(win, "(%3d%%)", percent);
+}
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
new file mode 100644
index 0000000..f82cebb
--- /dev/null
+++ b/scripts/kconfig/lxdialog/util.c
@@ -0,0 +1,362 @@
+/*
+ *  util.c
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/* use colors by default? */
+bool use_colors = 1;
+
+const char *backtitle = NULL;
+
+/*
+ * Attribute values, default is for mono display
+ */
+chtype attributes[] = {
+	A_NORMAL,		/* screen_attr */
+	A_NORMAL,		/* shadow_attr */
+	A_NORMAL,		/* dialog_attr */
+	A_BOLD,			/* title_attr */
+	A_NORMAL,		/* border_attr */
+	A_REVERSE,		/* button_active_attr */
+	A_DIM,			/* button_inactive_attr */
+	A_REVERSE,		/* button_key_active_attr */
+	A_BOLD,			/* button_key_inactive_attr */
+	A_REVERSE,		/* button_label_active_attr */
+	A_NORMAL,		/* button_label_inactive_attr */
+	A_NORMAL,		/* inputbox_attr */
+	A_NORMAL,		/* inputbox_border_attr */
+	A_NORMAL,		/* searchbox_attr */
+	A_BOLD,			/* searchbox_title_attr */
+	A_NORMAL,		/* searchbox_border_attr */
+	A_BOLD,			/* position_indicator_attr */
+	A_NORMAL,		/* menubox_attr */
+	A_NORMAL,		/* menubox_border_attr */
+	A_NORMAL,		/* item_attr */
+	A_REVERSE,		/* item_selected_attr */
+	A_BOLD,			/* tag_attr */
+	A_REVERSE,		/* tag_selected_attr */
+	A_BOLD,			/* tag_key_attr */
+	A_REVERSE,		/* tag_key_selected_attr */
+	A_BOLD,			/* check_attr */
+	A_REVERSE,		/* check_selected_attr */
+	A_BOLD,			/* uarrow_attr */
+	A_BOLD			/* darrow_attr */
+};
+
+#include "colors.h"
+
+/*
+ * Table of color values
+ */
+int color_table[][3] = {
+	{SCREEN_FG, SCREEN_BG, SCREEN_HL},
+	{SHADOW_FG, SHADOW_BG, SHADOW_HL},
+	{DIALOG_FG, DIALOG_BG, DIALOG_HL},
+	{TITLE_FG, TITLE_BG, TITLE_HL},
+	{BORDER_FG, BORDER_BG, BORDER_HL},
+	{BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
+	{BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
+	{BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
+	{BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG,
+	 BUTTON_KEY_INACTIVE_HL},
+	{BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG,
+	 BUTTON_LABEL_ACTIVE_HL},
+	{BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
+	 BUTTON_LABEL_INACTIVE_HL},
+	{INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
+	{INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
+	{SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
+	{SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
+	{SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
+	{POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
+	{MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
+	{MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
+	{ITEM_FG, ITEM_BG, ITEM_HL},
+	{ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
+	{TAG_FG, TAG_BG, TAG_HL},
+	{TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
+	{TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
+	{TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
+	{CHECK_FG, CHECK_BG, CHECK_HL},
+	{CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
+	{UARROW_FG, UARROW_BG, UARROW_HL},
+	{DARROW_FG, DARROW_BG, DARROW_HL},
+};				/* color_table */
+
+/*
+ * Set window to attribute 'attr'
+ */
+void attr_clear(WINDOW * win, int height, int width, chtype attr)
+{
+	int i, j;
+
+	wattrset(win, attr);
+	for (i = 0; i < height; i++) {
+		wmove(win, i, 0);
+		for (j = 0; j < width; j++)
+			waddch(win, ' ');
+	}
+	touchwin(win);
+}
+
+void dialog_clear(void)
+{
+	attr_clear(stdscr, LINES, COLS, screen_attr);
+	/* Display background title if it exists ... - SLH */
+	if (backtitle != NULL) {
+		int i;
+
+		wattrset(stdscr, screen_attr);
+		mvwaddstr(stdscr, 0, 1, (char *)backtitle);
+		wmove(stdscr, 1, 1);
+		for (i = 1; i < COLS - 1; i++)
+			waddch(stdscr, ACS_HLINE);
+	}
+	wnoutrefresh(stdscr);
+}
+
+/*
+ * Do some initialization for dialog
+ */
+void init_dialog(void)
+{
+	initscr();		/* Init curses */
+	keypad(stdscr, TRUE);
+	cbreak();
+	noecho();
+
+	if (use_colors)		/* Set up colors */
+		color_setup();
+
+	dialog_clear();
+}
+
+/*
+ * Setup for color display
+ */
+void color_setup(void)
+{
+	int i;
+
+	if (has_colors()) {	/* Terminal supports color? */
+		start_color();
+
+		/* Initialize color pairs */
+		for (i = 0; i < ATTRIBUTE_COUNT; i++)
+			init_pair(i + 1, color_table[i][0], color_table[i][1]);
+
+		/* Setup color attributes */
+		for (i = 0; i < ATTRIBUTE_COUNT; i++)
+			attributes[i] = C_ATTR(color_table[i][2], i + 1);
+	}
+}
+
+/*
+ * End using dialog functions.
+ */
+void end_dialog(void)
+{
+	endwin();
+}
+
+/* Print the title of the dialog. Center the title and truncate
+ * tile if wider than dialog (- 2 chars).
+ **/
+void print_title(WINDOW *dialog, const char *title, int width)
+{
+	if (title) {
+		int tlen = MIN(width - 2, strlen(title));
+		wattrset(dialog, title_attr);
+		mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
+		mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
+		waddch(dialog, ' ');
+	}
+}
+
+/*
+ * Print a string of text in a window, automatically wrap around to the
+ * next line if the string is too long to fit on one line. Newline
+ * characters '\n' are replaced by spaces.  We start on a new line
+ * if there is no room for at least 4 nonblanks following a double-space.
+ */
+void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
+{
+	int newl, cur_x, cur_y;
+	int i, prompt_len, room, wlen;
+	char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
+
+	strcpy(tempstr, prompt);
+
+	prompt_len = strlen(tempstr);
+
+	/*
+	 * Remove newlines
+	 */
+	for (i = 0; i < prompt_len; i++) {
+		if (tempstr[i] == '\n')
+			tempstr[i] = ' ';
+	}
+
+	if (prompt_len <= width - x * 2) {	/* If prompt is short */
+		wmove(win, y, (width - prompt_len) / 2);
+		waddstr(win, tempstr);
+	} else {
+		cur_x = x;
+		cur_y = y;
+		newl = 1;
+		word = tempstr;
+		while (word && *word) {
+			sp = index(word, ' ');
+			if (sp)
+				*sp++ = 0;
+
+			/* Wrap to next line if either the word does not fit,
+			   or it is the first word of a new sentence, and it is
+			   short, and the next word does not fit. */
+			room = width - cur_x;
+			wlen = strlen(word);
+			if (wlen > room ||
+			    (newl && wlen < 4 && sp
+			     && wlen + 1 + strlen(sp) > room
+			     && (!(sp2 = index(sp, ' '))
+				 || wlen + 1 + (sp2 - sp) > room))) {
+				cur_y++;
+				cur_x = x;
+			}
+			wmove(win, cur_y, cur_x);
+			waddstr(win, word);
+			getyx(win, cur_y, cur_x);
+			cur_x++;
+			if (sp && *sp == ' ') {
+				cur_x++;	/* double space */
+				while (*++sp == ' ') ;
+				newl = 1;
+			} else
+				newl = 0;
+			word = sp;
+		}
+	}
+}
+
+/*
+ * Print a button
+ */
+void print_button(WINDOW * win, const char *label, int y, int x, int selected)
+{
+	int i, temp;
+
+	wmove(win, y, x);
+	wattrset(win, selected ? button_active_attr : button_inactive_attr);
+	waddstr(win, "<");
+	temp = strspn(label, " ");
+	label += temp;
+	wattrset(win, selected ? button_label_active_attr
+		 : button_label_inactive_attr);
+	for (i = 0; i < temp; i++)
+		waddch(win, ' ');
+	wattrset(win, selected ? button_key_active_attr
+		 : button_key_inactive_attr);
+	waddch(win, label[0]);
+	wattrset(win, selected ? button_label_active_attr
+		 : button_label_inactive_attr);
+	waddstr(win, (char *)label + 1);
+	wattrset(win, selected ? button_active_attr : button_inactive_attr);
+	waddstr(win, ">");
+	wmove(win, y, x + temp + 1);
+}
+
+/*
+ * Draw a rectangular box with line drawing characters
+ */
+void
+draw_box(WINDOW * win, int y, int x, int height, int width,
+	 chtype box, chtype border)
+{
+	int i, j;
+
+	wattrset(win, 0);
+	for (i = 0; i < height; i++) {
+		wmove(win, y + i, x);
+		for (j = 0; j < width; j++)
+			if (!i && !j)
+				waddch(win, border | ACS_ULCORNER);
+			else if (i == height - 1 && !j)
+				waddch(win, border | ACS_LLCORNER);
+			else if (!i && j == width - 1)
+				waddch(win, box | ACS_URCORNER);
+			else if (i == height - 1 && j == width - 1)
+				waddch(win, box | ACS_LRCORNER);
+			else if (!i)
+				waddch(win, border | ACS_HLINE);
+			else if (i == height - 1)
+				waddch(win, box | ACS_HLINE);
+			else if (!j)
+				waddch(win, border | ACS_VLINE);
+			else if (j == width - 1)
+				waddch(win, box | ACS_VLINE);
+			else
+				waddch(win, box | ' ');
+	}
+}
+
+/*
+ * Draw shadows along the right and bottom edge to give a more 3D look
+ * to the boxes
+ */
+void draw_shadow(WINDOW * win, int y, int x, int height, int width)
+{
+	int i;
+
+	if (has_colors()) {	/* Whether terminal supports color? */
+		wattrset(win, shadow_attr);
+		wmove(win, y + height, x + 2);
+		for (i = 0; i < width; i++)
+			waddch(win, winch(win) & A_CHARTEXT);
+		for (i = y + 1; i < y + height + 1; i++) {
+			wmove(win, i, x + width);
+			waddch(win, winch(win) & A_CHARTEXT);
+			waddch(win, winch(win) & A_CHARTEXT);
+		}
+		wnoutrefresh(win);
+	}
+}
+
+/*
+ *  Return the position of the first alphabetic character in a string.
+ */
+int first_alpha(const char *string, const char *exempt)
+{
+	int i, in_paren = 0, c;
+
+	for (i = 0; i < strlen(string); i++) {
+		c = tolower(string[i]);
+
+		if (strchr("<[(", c))
+			++in_paren;
+		if (strchr(">])", c) && in_paren > 0)
+			--in_paren;
+
+		if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)
+			return i;
+	}
+
+	return 0;
+}
diff --git a/scripts/kconfig/lxdialog/yesno.c b/scripts/kconfig/lxdialog/yesno.c
new file mode 100644
index 0000000..cb2568a
--- /dev/null
+++ b/scripts/kconfig/lxdialog/yesno.c
@@ -0,0 +1,102 @@
+/*
+ *  yesno.c -- implements the yes/no box
+ *
+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version 2
+ *  of the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "dialog.h"
+
+/*
+ * Display termination buttons
+ */
+static void print_buttons(WINDOW * dialog, int height, int width, int selected)
+{
+	int x = width / 2 - 10;
+	int y = height - 2;
+
+	print_button(dialog, " Yes ", y, x, selected == 0);
+	print_button(dialog, "  No  ", y, x + 13, selected == 1);
+
+	wmove(dialog, y, x + 1 + 13 * selected);
+	wrefresh(dialog);
+}
+
+/*
+ * Display a dialog box with two buttons - Yes and No
+ */
+int dialog_yesno(const char *title, const char *prompt, int height, int width)
+{
+	int i, x, y, key = 0, button = 0;
+	WINDOW *dialog;
+
+	/* center dialog box on screen */
+	x = (COLS - width) / 2;
+	y = (LINES - height) / 2;
+
+	draw_shadow(stdscr, y, x, height, width);
+
+	dialog = newwin(height, width, y, x);
+	keypad(dialog, TRUE);
+
+	draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
+	wattrset(dialog, border_attr);
+	mvwaddch(dialog, height - 3, 0, ACS_LTEE);
+	for (i = 0; i < width - 2; i++)
+		waddch(dialog, ACS_HLINE);
+	wattrset(dialog, dialog_attr);
+	waddch(dialog, ACS_RTEE);
+
+	print_title(dialog, title, width);
+
+	wattrset(dialog, dialog_attr);
+	print_autowrap(dialog, prompt, width - 2, 1, 3);
+
+	print_buttons(dialog, height, width, 0);
+
+	while (key != ESC) {
+		key = wgetch(dialog);
+		switch (key) {
+		case 'Y':
+		case 'y':
+			delwin(dialog);
+			return 0;
+		case 'N':
+		case 'n':
+			delwin(dialog);
+			return 1;
+
+		case TAB:
+		case KEY_LEFT:
+		case KEY_RIGHT:
+			button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button);
+
+			print_buttons(dialog, height, width, button);
+			wrefresh(dialog);
+			break;
+		case ' ':
+		case '\n':
+			delwin(dialog);
+			return button;
+		case ESC:
+			break;
+		}
+	}
+
+	delwin(dialog);
+	return -1;		/* ESC pressed */
+}
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index d1ad405..d63d7fb 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -325,7 +325,7 @@
 	memset(args, 0, sizeof(args));
 	indent = 0;
 	child_count = 0;
-	cprint("./scripts/lxdialog/lxdialog");
+	cprint("./scripts/kconfig/lxdialog/lxdialog");
 	cprint("--backtitle");
 	cprint(menu_backtitle);
 }
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index 7c03927..e52f3e9 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -22,8 +22,8 @@
 
 #if QT_VERSION >= 300
 	void readListSettings();
-	QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok);
-	bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value);
+	QValueList<int> readSizes(const QString& key, bool *ok);
+	bool writeSizes(const QString& key, const QValueList<int>& value);
 #endif
 
 	bool showAll;
@@ -124,7 +124,7 @@
 	void setParentMenu(void);
 
 	template <class P>
-	void ConfigList::updateMenuList(P*, struct menu*);
+	void updateMenuList(P*, struct menu*);
 
 	bool updateAll;
 
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index 1fa4c0b..656d2c8 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -33,7 +33,7 @@
 	FILE *out;
 
 	if (!name)
-		name = ".config.cmd";
+		name = ".kconfig.d";
 	out = fopen("..config.tmp", "w");
 	if (!out)
 		return 1;
@@ -101,7 +101,7 @@
 	va_end(ap);
 }
 
-/* Retreive value of growable string */
+/* Retrieve value of growable string */
 const char *str_get(struct gstr *gs)
 {
 	return gs->s;
diff --git a/scripts/lxdialog/checklist.c b/scripts/lxdialog/checklist.c
deleted file mode 100644
index 7aba17c..0000000
--- a/scripts/lxdialog/checklist.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- *  checklist.c -- implements the checklist box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
- *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static int list_width, check_x, item_x, checkflag;
-
-/*
- * Print list item
- */
-static void
-print_item (WINDOW * win, const char *item, int status,
-	    int choice, int selected)
-{
-    int i;
-
-    /* Clear 'residue' of last item */
-    wattrset (win, menubox_attr);
-    wmove (win, choice, 0);
-    for (i = 0; i < list_width; i++)
-	waddch (win, ' ');
-
-    wmove (win, choice, check_x);
-    wattrset (win, selected ? check_selected_attr : check_attr);
-    if (checkflag == FLAG_CHECK)
-	wprintw (win, "[%c]", status ? 'X' : ' ');
-    else
-	wprintw (win, "(%c)", status ? 'X' : ' ');
-
-    wattrset (win, selected ? tag_selected_attr : tag_attr);
-    mvwaddch(win, choice, item_x, item[0]);
-    wattrset (win, selected ? item_selected_attr : item_attr);
-    waddstr (win, (char *)item+1);
-    if (selected) {
-    	wmove (win, choice, check_x+1);
-    	wrefresh (win);
-    }
-}
-
-/*
- * Print the scroll indicators.
- */
-static void
-print_arrows (WINDOW * win, int choice, int item_no, int scroll,
-		int y, int x, int height)
-{
-    wmove(win, y, x);
-
-    if (scroll > 0) {
-	wattrset (win, uarrow_attr);
-	waddch (win, ACS_UARROW);
-	waddstr (win, "(-)");
-    }
-    else {
-	wattrset (win, menubox_attr);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-    }
-
-   y = y + height + 1;
-   wmove(win, y, x);
-
-   if ((height < item_no) && (scroll + choice < item_no - 1)) {
-	wattrset (win, darrow_attr);
-	waddch (win, ACS_DARROW);
-	waddstr (win, "(+)");
-    }
-    else {
-	wattrset (win, menubox_border_attr);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-   }
-}
-
-/*
- *  Display the termination buttons
- */
-static void
-print_buttons( WINDOW *dialog, int height, int width, int selected)
-{
-    int x = width / 2 - 11;
-    int y = height - 2;
-
-    print_button (dialog, "Select", y, x, selected == 0);
-    print_button (dialog, " Help ", y, x + 14, selected == 1);
-
-    wmove(dialog, y, x+1 + 14*selected);
-    wrefresh (dialog);
-}
-
-/*
- * Display a dialog box with a list of options that can be turned on or off
- * The `flag' parameter is used to select between radiolist and checklist.
- */
-int
-dialog_checklist (const char *title, const char *prompt, int height, int width,
-	int list_height, int item_no, const char * const * items, int flag)
-	
-{
-    int i, x, y, box_x, box_y;
-    int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
-    WINDOW *dialog, *list;
-
-    checkflag = flag;
-
-    /* Allocate space for storing item on/off status */
-    if ((status = malloc (sizeof (int) * item_no)) == NULL) {
-	endwin ();
-	fprintf (stderr,
-		 "\nCan't allocate memory in dialog_checklist().\n");
-	exit (-1);
-    }
-
-    /* Initializes status */
-    for (i = 0; i < item_no; i++) {
-	status[i] = !strcasecmp (items[i * 3 + 2], "on");
-	if ((!choice && status[i]) || !strcasecmp (items[i * 3 + 2], "selected"))
-            choice = i + 1;
-    }
-    if (choice)
-	    choice--;
-
-    max_choice = MIN (list_height, item_no);
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-	waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-	/* truncate long title -- mec */
-	char * title2 = malloc(width-2+1);
-	memcpy( title2, title, width-2 );
-	title2[width-2] = '\0';
-	title = title2;
-    }
-
-    if (title != NULL) {
-	wattrset (dialog, title_attr);
-	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-	waddstr (dialog, (char *)title);
-	waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    list_width = width - 6;
-    box_y = height - list_height - 5;
-    box_x = (width - list_width) / 2 - 1;
-
-    /* create new window for the list */
-    list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
-
-    keypad (list, TRUE);
-
-    /* draw a box around the list items */
-    draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
-	      menubox_border_attr, menubox_attr);
-
-    /* Find length of longest item in order to center checklist */
-    check_x = 0;
-    for (i = 0; i < item_no; i++) 
-	check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4);
-
-    check_x = (list_width - check_x) / 2;
-    item_x = check_x + 4;
-
-    if (choice >= list_height) {
-	scroll = choice - list_height + 1;
-	choice -= scroll;
-    }
-
-    /* Print the list */
-    for (i = 0; i < max_choice; i++) {
-	print_item (list, items[(scroll+i) * 3 + 1],
-		    status[i+scroll], i, i == choice);
-    }
-
-    print_arrows(dialog, choice, item_no, scroll,
-			box_y, box_x + check_x + 5, list_height);
-
-    print_buttons(dialog, height, width, 0);
-
-    wnoutrefresh (list);
-    wnoutrefresh (dialog);
-    doupdate ();
-
-    while (key != ESC) {
-	key = wgetch (dialog);
-
-    	for (i = 0; i < max_choice; i++)
-            if (toupper(key) == toupper(items[(scroll+i)*3+1][0]))
-                break;
-
-
-	if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || 
-	    key == '+' || key == '-' ) {
-	    if (key == KEY_UP || key == '-') {
-		if (!choice) {
-		    if (!scroll)
-			continue;
-		    /* Scroll list down */
-		    if (list_height > 1) {
-			/* De-highlight current first item */
-			print_item (list, items[scroll * 3 + 1],
-					status[scroll], 0, FALSE);
-			scrollok (list, TRUE);
-			wscrl (list, -1);
-			scrollok (list, FALSE);
-		    }
-		    scroll--;
-		    print_item (list, items[scroll * 3 + 1],
-				status[scroll], 0, TRUE);
-		    wnoutrefresh (list);
-
-    		    print_arrows(dialog, choice, item_no, scroll,
-				box_y, box_x + check_x + 5, list_height);
-
-		    wrefresh (dialog);
-
-		    continue;	/* wait for another key press */
-		} else
-		    i = choice - 1;
-	    } else if (key == KEY_DOWN || key == '+') {
-		if (choice == max_choice - 1) {
-		    if (scroll + choice >= item_no - 1)
-			continue;
-		    /* Scroll list up */
-		    if (list_height > 1) {
-			/* De-highlight current last item before scrolling up */
-			print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
-				    status[scroll + max_choice - 1],
-				    max_choice - 1, FALSE);
-			scrollok (list, TRUE);
-			wscrl (list, 1);
-			scrollok (list, FALSE);
-		    }
-		    scroll++;
-		    print_item (list, items[(scroll + max_choice - 1) * 3 + 1],
-				status[scroll + max_choice - 1],
-				max_choice - 1, TRUE);
-		    wnoutrefresh (list);
-
-    		    print_arrows(dialog, choice, item_no, scroll,
-				box_y, box_x + check_x + 5, list_height);
-
-		    wrefresh (dialog);
-
-		    continue;	/* wait for another key press */
-		} else
-		    i = choice + 1;
-	    }
-	    if (i != choice) {
-		/* De-highlight current item */
-		print_item (list, items[(scroll + choice) * 3 + 1],
-			    status[scroll + choice], choice, FALSE);
-		/* Highlight new item */
-		choice = i;
-		print_item (list, items[(scroll + choice) * 3 + 1],
-			    status[scroll + choice], choice, TRUE);
-		wnoutrefresh (list);
-		wrefresh (dialog);
-	    }
-	    continue;		/* wait for another key press */
-	}
-	switch (key) {
-	case 'H':
-	case 'h':
-	case '?':
-	    fprintf (stderr, "%s", items[(scroll + choice) * 3]);
-	    delwin (dialog);
-	    free (status);
-	    return 1;
-	case TAB:
-	case KEY_LEFT:
-	case KEY_RIGHT:
-	    button = ((key == KEY_LEFT ? --button : ++button) < 0)
-			? 1 : (button > 1 ? 0 : button);
-
-	    print_buttons(dialog, height, width, button);
-	    wrefresh (dialog);
-	    break;
-	case 'S':
-	case 's':
-	case ' ':
-	case '\n':
-	    if (!button) {
-		if (flag == FLAG_CHECK) {
-		    status[scroll + choice] = !status[scroll + choice];
-		    wmove (list, choice, check_x);
-		    wattrset (list, check_selected_attr);
-		    wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
-		} else {
-		    if (!status[scroll + choice]) {
-			for (i = 0; i < item_no; i++)
-			    status[i] = 0;
-			status[scroll + choice] = 1;
-			for (i = 0; i < max_choice; i++)
-			    print_item (list, items[(scroll + i) * 3 + 1],
-					status[scroll + i], i, i == choice);
-		    }
-		}
-		wnoutrefresh (list);
-		wrefresh (dialog);
-            
-		for (i = 0; i < item_no; i++) {
-		    if (status[i]) {
-			if (flag == FLAG_CHECK) {
-			    fprintf (stderr, "\"%s\" ", items[i * 3]);
-			} else {
-			    fprintf (stderr, "%s", items[i * 3]);
-			}
-
-		    }
-		}
-            } else
-		fprintf (stderr, "%s", items[(scroll + choice) * 3]);
-	    delwin (dialog);
-	    free (status);
-	    return button;
-	case 'X':
-	case 'x':
-	    key = ESC;
-	case ESC:
-	    break;
-	}
-
-	/* Now, update everything... */
-	doupdate ();
-    }
-    
-
-    delwin (dialog);
-    free (status);
-    return -1;			/* ESC pressed */
-}
diff --git a/scripts/lxdialog/inputbox.c b/scripts/lxdialog/inputbox.c
deleted file mode 100644
index 074d2d6..0000000
--- a/scripts/lxdialog/inputbox.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- *  inputbox.c -- implements the input box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-char dialog_input_result[MAX_LEN + 1];
-
-/*
- *  Print the termination buttons
- */
-static void
-print_buttons(WINDOW *dialog, int height, int width, int selected)
-{
-    int x = width / 2 - 11;
-    int y = height - 2;
-
-    print_button (dialog, "  Ok  ", y, x, selected==0);
-    print_button (dialog, " Help ", y, x + 14, selected==1);
-
-    wmove(dialog, y, x+1+14*selected);
-    wrefresh(dialog);
-}
-
-/*
- * Display a dialog box for inputing a string
- */
-int
-dialog_inputbox (const char *title, const char *prompt, int height, int width,
-		 const char *init)
-{
-    int i, x, y, box_y, box_x, box_width;
-    int input_x = 0, scroll = 0, key = 0, button = -1;
-    char *instr = dialog_input_result;
-    WINDOW *dialog;
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-	waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-	/* truncate long title -- mec */
-	char * title2 = malloc(width-2+1);
-	memcpy( title2, title, width-2 );
-	title2[width-2] = '\0';
-	title = title2;
-    }
-
-    if (title != NULL) {
-	wattrset (dialog, title_attr);
-	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-	waddstr (dialog, (char *)title);
-	waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    /* Draw the input field box */
-    box_width = width - 6;
-    getyx (dialog, y, x);
-    box_y = y + 2;
-    box_x = (width - box_width) / 2;
-    draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
-	      border_attr, dialog_attr);
-
-    print_buttons(dialog, height, width, 0);
-
-    /* Set up the initial value */
-    wmove (dialog, box_y, box_x);
-    wattrset (dialog, inputbox_attr);
-
-    if (!init)
-	instr[0] = '\0';
-    else
-	strcpy (instr, init);
-
-    input_x = strlen (instr);
-
-    if (input_x >= box_width) {
-	scroll = input_x - box_width + 1;
-	input_x = box_width - 1;
-	for (i = 0; i < box_width - 1; i++)
-	    waddch (dialog, instr[scroll + i]);
-    } else
-	waddstr (dialog, instr);
-
-    wmove (dialog, box_y, box_x + input_x);
-
-    wrefresh (dialog);
-
-    while (key != ESC) {
-	key = wgetch (dialog);
-
-	if (button == -1) {	/* Input box selected */
-	    switch (key) {
-	    case TAB:
-	    case KEY_UP:
-	    case KEY_DOWN:
-		break;
-	    case KEY_LEFT:
-		continue;
-	    case KEY_RIGHT:
-		continue;
-	    case KEY_BACKSPACE:
-	    case 127:
-		if (input_x || scroll) {
-		    wattrset (dialog, inputbox_attr);
-		    if (!input_x) {
-			scroll = scroll < box_width - 1 ?
-			    0 : scroll - (box_width - 1);
-			wmove (dialog, box_y, box_x);
-			for (i = 0; i < box_width; i++)
-			    waddch (dialog, instr[scroll + input_x + i] ?
-				    instr[scroll + input_x + i] : ' ');
-			input_x = strlen (instr) - scroll;
-		    } else
-			input_x--;
-		    instr[scroll + input_x] = '\0';
-		    mvwaddch (dialog, box_y, input_x + box_x, ' ');
-		    wmove (dialog, box_y, input_x + box_x);
-		    wrefresh (dialog);
-		}
-		continue;
-	    default:
-		if (key < 0x100 && isprint (key)) {
-		    if (scroll + input_x < MAX_LEN) {
-			wattrset (dialog, inputbox_attr);
-			instr[scroll + input_x] = key;
-			instr[scroll + input_x + 1] = '\0';
-			if (input_x == box_width - 1) {
-			    scroll++;
-			    wmove (dialog, box_y, box_x);
-			    for (i = 0; i < box_width - 1; i++)
-				waddch (dialog, instr[scroll + i]);
-			} else {
-			    wmove (dialog, box_y, input_x++ + box_x);
-			    waddch (dialog, key);
-			}
-			wrefresh (dialog);
-		    } else
-			flash ();	/* Alarm user about overflow */
-		    continue;
-		}
-	    }
-	}
-	switch (key) {
-	case 'O':
-	case 'o':
-	    delwin (dialog);
-	    return 0;
-	case 'H':
-	case 'h':
-	    delwin (dialog);
-	    return 1;
-	case KEY_UP:
-	case KEY_LEFT:
-	    switch (button) {
-	    case -1:
-		button = 1;	/* Indicates "Cancel" button is selected */
-		print_buttons(dialog, height, width, 1);
-		break;
-	    case 0:
-		button = -1;	/* Indicates input box is selected */
-		print_buttons(dialog, height, width, 0);
-		wmove (dialog, box_y, box_x + input_x);
-		wrefresh (dialog);
-		break;
-	    case 1:
-		button = 0;	/* Indicates "OK" button is selected */
-		print_buttons(dialog, height, width, 0);
-		break;
-	    }
-	    break;
-	case TAB:
-	case KEY_DOWN:
-	case KEY_RIGHT:
-	    switch (button) {
-	    case -1:
-		button = 0;	/* Indicates "OK" button is selected */
-		print_buttons(dialog, height, width, 0);
-		break;
-	    case 0:
-		button = 1;	/* Indicates "Cancel" button is selected */
-		print_buttons(dialog, height, width, 1);
-		break;
-	    case 1:
-		button = -1;	/* Indicates input box is selected */
-		print_buttons(dialog, height, width, 0);
-		wmove (dialog, box_y, box_x + input_x);
-		wrefresh (dialog);
-		break;
-	    }
-	    break;
-	case ' ':
-	case '\n':
-	    delwin (dialog);
-	    return (button == -1 ? 0 : button);
-	case 'X':
-	case 'x':
-	    key = ESC;
-	case ESC:
-	    break;
-	}
-    }
-
-    delwin (dialog);
-    return -1;			/* ESC pressed */
-}
diff --git a/scripts/lxdialog/lxdialog.c b/scripts/lxdialog/lxdialog.c
deleted file mode 100644
index f283a85..0000000
--- a/scripts/lxdialog/lxdialog.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  dialog - Display simple dialog boxes from shell scripts
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static void Usage (const char *name);
-
-typedef int (jumperFn) (const char *title, int argc, const char * const * argv);
-
-struct Mode {
-    char *name;
-    int argmin, argmax, argmod;
-    jumperFn *jumper;
-};
-
-jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox;
-jumperFn j_msgbox, j_infobox;
-
-static struct Mode modes[] =
-{
-    {"--menu", 9, 0, 3, j_menu},
-    {"--checklist", 9, 0, 3, j_checklist},
-    {"--radiolist", 9, 0, 3, j_radiolist},
-    {"--yesno",    5,5,1, j_yesno},
-    {"--textbox",  5,5,1, j_textbox},
-    {"--inputbox", 5, 6, 1, j_inputbox},
-    {"--msgbox", 5, 5, 1, j_msgbox},
-    {"--infobox", 5, 5, 1, j_infobox},
-    {NULL, 0, 0, 0, NULL}
-};
-
-static struct Mode *modePtr;
-
-#ifdef LOCALE
-#include <locale.h>
-#endif
-
-int
-main (int argc, const char * const * argv)
-{
-    int offset = 0, opt_clear = 0, end_common_opts = 0, retval;
-    const char *title = NULL;
-
-#ifdef LOCALE
-    (void) setlocale (LC_ALL, "");
-#endif
-
-#ifdef TRACE
-    trace(TRACE_CALLS|TRACE_UPDATE);
-#endif
-    if (argc < 2) {
-	Usage (argv[0]);
-	exit (-1);
-    }
-
-    while (offset < argc - 1 && !end_common_opts) {	/* Common options */
-	if (!strcmp (argv[offset + 1], "--title")) {
-	    if (argc - offset < 3 || title != NULL) {
-		Usage (argv[0]);
-		exit (-1);
-	    } else {
-		title = argv[offset + 2];
-		offset += 2;
-	    }
-        } else if (!strcmp (argv[offset + 1], "--backtitle")) {
-            if (backtitle != NULL) {
-                Usage (argv[0]);
-                exit (-1);
-            } else {
-                backtitle = argv[offset + 2];
-                offset += 2;
-            }
-	} else if (!strcmp (argv[offset + 1], "--clear")) {
-	    if (opt_clear) {		/* Hey, "--clear" can't appear twice! */
-		Usage (argv[0]);
-		exit (-1);
-	    } else if (argc == 2) {	/* we only want to clear the screen */
-		init_dialog ();
-		refresh ();	/* init_dialog() will clear the screen for us */
-		end_dialog ();
-		return 0;
-	    } else {
-		opt_clear = 1;
-		offset++;
-	    }
-	} else			/* no more common options */
-	    end_common_opts = 1;
-    }
-
-    if (argc - 1 == offset) {	/* no more options */
-	Usage (argv[0]);
-	exit (-1);
-    }
-    /* use a table to look for the requested mode, to avoid code duplication */
-
-    for (modePtr = modes; modePtr->name; modePtr++)	/* look for the mode */
-	if (!strcmp (argv[offset + 1], modePtr->name))
-	    break;
-
-    if (!modePtr->name)
-	Usage (argv[0]);
-    if (argc - offset < modePtr->argmin)
-	Usage (argv[0]);
-    if (modePtr->argmax && argc - offset > modePtr->argmax)
-	Usage (argv[0]);
-
-
-
-    init_dialog ();
-    retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset);
-
-    if (opt_clear) {		/* clear screen before exit */
-	attr_clear (stdscr, LINES, COLS, screen_attr);
-	refresh ();
-    }
-    end_dialog();
-
-    exit (retval);
-}
-
-/*
- * Print program usage
- */
-static void
-Usage (const char *name)
-{
-    fprintf (stderr, "\
-\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\
-\n  patched by Stuart Herbert (S.Herbert@shef.ac.uk)\
-\n  modified/gutted for use as a Linux kernel config tool by \
-\n  William Roadcap (roadcapw@cfw.com)\
-\n\
-\n* Display dialog boxes from shell scripts *\
-\n\
-\nUsage: %s --clear\
-\n       %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\
-\n\
-\nBox options:\
-\n\
-\n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
-\n  --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
-\n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
-\n  --textbox   <file> <height> <width>\
-\n  --inputbox  <text> <height> <width> [<init>]\
-\n  --yesno     <text> <height> <width>\
-\n", name, name);
-    exit (-1);
-}
-
-/*
- * These are the program jumpers
- */
-
-int
-j_menu (const char *t, int ac, const char * const * av)
-{
-    return dialog_menu (t, av[2], atoi (av[3]), atoi (av[4]),
-			atoi (av[5]), av[6], (ac - 6) / 2, av + 7);
-}
-
-int
-j_checklist (const char *t, int ac, const char * const * av)
-{
-    return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
-	atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK);
-}
-
-int
-j_radiolist (const char *t, int ac, const char * const * av)
-{
-    return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]),
-	atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO);
-}
-
-int
-j_textbox (const char *t, int ac, const char * const * av)
-{
-    return dialog_textbox (t, av[2], atoi (av[3]), atoi (av[4]));
-}
-
-int
-j_yesno (const char *t, int ac, const char * const * av)
-{
-    return dialog_yesno (t, av[2], atoi (av[3]), atoi (av[4]));
-}
-
-int
-j_inputbox (const char *t, int ac, const char * const * av)
-{
-    int ret = dialog_inputbox (t, av[2], atoi (av[3]), atoi (av[4]),
-                            ac == 6 ? av[5] : (char *) NULL);
-    if (ret == 0)
-        fprintf(stderr, dialog_input_result);
-    return ret;
-}
-
-int
-j_msgbox (const char *t, int ac, const char * const * av)
-{
-    return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 1);
-}
-
-int
-j_infobox (const char *t, int ac, const char * const * av)
-{
-    return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 0);
-}
-
diff --git a/scripts/lxdialog/menubox.c b/scripts/lxdialog/menubox.c
deleted file mode 100644
index 91d82ba..0000000
--- a/scripts/lxdialog/menubox.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- *  menubox.c -- implements the menu box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- *  Changes by Clifford Wolf (god@clifford.at)
- *
- *  [ 1998-06-13 ]
- *
- *    *)  A bugfix for the Page-Down problem
- *
- *    *)  Formerly when I used Page Down and Page Up, the cursor would be set 
- *        to the first position in the menu box.  Now lxdialog is a bit
- *        smarter and works more like other menu systems (just have a look at
- *        it).
- *
- *    *)  Formerly if I selected something my scrolling would be broken because
- *        lxdialog is re-invoked by the Menuconfig shell script, can't
- *        remember the last scrolling position, and just sets it so that the
- *        cursor is at the bottom of the box.  Now it writes the temporary file
- *        lxdialog.scrltmp which contains this information. The file is
- *        deleted by lxdialog if the user leaves a submenu or enters a new
- *        one, but it would be nice if Menuconfig could make another "rm -f"
- *        just to be sure.  Just try it out - you will recognise a difference!
- *
- *  [ 1998-06-14 ]
- *
- *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
- *        and menus change their size on the fly.
- *
- *    *)  If for some reason the last scrolling position is not saved by
- *        lxdialog, it sets the scrolling so that the selected item is in the
- *        middle of the menu box, not at the bottom.
- *
- * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
- * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
- * This fixes a bug in Menuconfig where using ' ' to descend into menus
- * would leave mis-synchronized lxdialog.scrltmp files lying around,
- * fscanf would read in 'scroll', and eventually that value would get used.
- */
-
-#include "dialog.h"
-
-static int menu_width, item_x;
-
-/*
- * Print menu item
- */
-static void
-print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
-{
-    int j;
-    char menu_item[menu_width+1];
-
-    strncpy(menu_item, item, menu_width);
-    menu_item[menu_width] = 0;
-    j = first_alpha(menu_item, "YyNnMmHh");
-
-    /* Clear 'residue' of last item */
-    wattrset (win, menubox_attr);
-    wmove (win, choice, 0);
-#if OLD_NCURSES
-    {
-        int i;
-        for (i = 0; i < menu_width; i++)
-	    waddch (win, ' ');
-    }
-#else
-    wclrtoeol(win);
-#endif
-    wattrset (win, selected ? item_selected_attr : item_attr);
-    mvwaddstr (win, choice, item_x, menu_item);
-    if (hotkey) {
-    	wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
-    	mvwaddch(win, choice, item_x+j, menu_item[j]);
-    }
-    if (selected) {
-	wmove (win, choice, item_x+1);
-	wrefresh (win);
-    }
-}
-
-/*
- * Print the scroll indicators.
- */
-static void
-print_arrows (WINDOW * win, int item_no, int scroll,
-		int y, int x, int height)
-{
-    int cur_y, cur_x;
-
-    getyx(win, cur_y, cur_x);
-
-    wmove(win, y, x);
-
-    if (scroll > 0) {
-	wattrset (win, uarrow_attr);
-	waddch (win, ACS_UARROW);
-	waddstr (win, "(-)");
-    }
-    else {
-	wattrset (win, menubox_attr);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-    }
-
-   y = y + height + 1;
-   wmove(win, y, x);
-
-   if ((height < item_no) && (scroll + height < item_no)) {
-	wattrset (win, darrow_attr);
-	waddch (win, ACS_DARROW);
-	waddstr (win, "(+)");
-    }
-    else {
-	wattrset (win, menubox_border_attr);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-	waddch (win, ACS_HLINE);
-   }
-
-   wmove(win, cur_y, cur_x);
-}
-
-/*
- * Display the termination buttons.
- */
-static void
-print_buttons (WINDOW *win, int height, int width, int selected)
-{
-    int x = width / 2 - 16;
-    int y = height - 2;
-
-    print_button (win, "Select", y, x, selected == 0);
-    print_button (win, " Exit ", y, x + 12, selected == 1);
-    print_button (win, " Help ", y, x + 24, selected == 2);
-
-    wmove(win, y, x+1+12*selected);
-    wrefresh (win);
-}
-
-/*
- * Display a menu for choosing among a number of options
- */
-int
-dialog_menu (const char *title, const char *prompt, int height, int width,
-		int menu_height, const char *current, int item_no,
-		const char * const * items)
-
-{
-    int i, j, x, y, box_x, box_y;
-    int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
-    WINDOW *dialog, *menu;
-    FILE *f;
-
-    max_choice = MIN (menu_height, item_no);
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height - 3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-	waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    wbkgdset (dialog, dialog_attr & A_COLOR);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-	/* truncate long title -- mec */
-	char * title2 = malloc(width-2+1);
-	memcpy( title2, title, width-2 );
-	title2[width-2] = '\0';
-	title = title2;
-    }
-
-    if (title != NULL) {
-	wattrset (dialog, title_attr);
-	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-	waddstr (dialog, (char *)title);
-	waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    menu_width = width - 6;
-    box_y = height - menu_height - 5;
-    box_x = (width - menu_width) / 2 - 1;
-
-    /* create new window for the menu */
-    menu = subwin (dialog, menu_height, menu_width,
-		y + box_y + 1, x + box_x + 1);
-    keypad (menu, TRUE);
-
-    /* draw a box around the menu items */
-    draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
-	      menubox_border_attr, menubox_attr);
-
-    /*
-     * Find length of longest item in order to center menu.
-     * Set 'choice' to default item. 
-     */
-    item_x = 0;
-    for (i = 0; i < item_no; i++) {
-	item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2));
-	if (strcmp(current, items[i*2]) == 0) choice = i;
-    }
-
-    item_x = (menu_width - item_x) / 2;
-
-    /* get the scroll info from the temp file */
-    if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
-	if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
-	     (scroll+max_choice > choice) && (scroll >= 0) &&
-	     (scroll+max_choice <= item_no) ) {
-	    first_item = scroll;
-	    choice = choice - scroll;
-	    fclose(f);
-	} else {
-	    scroll=0;
-	    remove("lxdialog.scrltmp");
-	    fclose(f);
-	    f=NULL;
-	}
-    }
-    if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
-	if (choice >= item_no-max_choice/2)
-	    scroll = first_item = item_no-max_choice;
-	else
-	    scroll = first_item = choice - max_choice/2;
-	choice = choice - scroll;
-    }
-
-    /* Print the menu */
-    for (i=0; i < max_choice; i++) {
-	print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice,
-                    (items[(first_item + i)*2][0] != ':'));
-    }
-
-    wnoutrefresh (menu);
-
-    print_arrows(dialog, item_no, scroll,
-		 box_y, box_x+item_x+1, menu_height);
-
-    print_buttons (dialog, height, width, 0);
-    wmove (menu, choice, item_x+1);
-    wrefresh (menu);
-
-    while (key != ESC) {
-	key = wgetch(menu);
-
-	if (key < 256 && isalpha(key)) key = tolower(key);
-
-	if (strchr("ynmh", key))
-		i = max_choice;
-	else {
-        for (i = choice+1; i < max_choice; i++) {
-		j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
-		if (key == tolower(items[(scroll+i)*2+1][j]))
-                	break;
-	}
-	if (i == max_choice)
-       		for (i = 0; i < max_choice; i++) {
-			j = first_alpha(items[(scroll+i)*2+1], "YyNnMmHh");
-			if (key == tolower(items[(scroll+i)*2+1][j]))
-                		break;
-		}
-	}
-
-	if (i < max_choice || 
-            key == KEY_UP || key == KEY_DOWN ||
-            key == '-' || key == '+' ||
-            key == KEY_PPAGE || key == KEY_NPAGE) {
-
-            print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
-                       (items[(scroll+choice)*2][0] != ':'));
-
-	    if (key == KEY_UP || key == '-') {
-                if (choice < 2 && scroll) {
-	            /* Scroll menu down */
-                    scrollok (menu, TRUE);
-                    wscrl (menu, -1);
-                    scrollok (menu, FALSE);
-
-                    scroll--;
-
-                    print_item (menu, items[scroll * 2 + 1], 0, FALSE,
-                               (items[scroll*2][0] != ':'));
-		} else
-		    choice = MAX(choice - 1, 0);
-
-	    } else if (key == KEY_DOWN || key == '+')  {
-
-		print_item (menu, items[(scroll+choice)*2+1], choice, FALSE,
-                                (items[(scroll+choice)*2][0] != ':'));
-
-                if ((choice > max_choice-3) &&
-                    (scroll + max_choice < item_no)
-                   ) {
-		    /* Scroll menu up */
-		    scrollok (menu, TRUE);
-		    wscrl (menu, 1);
-                    scrollok (menu, FALSE);
-
-                    scroll++;
-
-                    print_item (menu, items[(scroll+max_choice-1)*2+1],
-                               max_choice-1, FALSE,
-                               (items[(scroll+max_choice-1)*2][0] != ':'));
-                } else
-                    choice = MIN(choice+1, max_choice-1);
-
-	    } else if (key == KEY_PPAGE) {
-	        scrollok (menu, TRUE);
-                for (i=0; (i < max_choice); i++) {
-                    if (scroll > 0) {
-                	wscrl (menu, -1);
-                	scroll--;
-                	print_item (menu, items[scroll * 2 + 1], 0, FALSE,
-                	(items[scroll*2][0] != ':'));
-                    } else {
-                        if (choice > 0)
-                            choice--;
-                    }
-                }
-                scrollok (menu, FALSE);
-
-            } else if (key == KEY_NPAGE) {
-                for (i=0; (i < max_choice); i++) {
-                    if (scroll+max_choice < item_no) {
-			scrollok (menu, TRUE);
-			wscrl (menu, 1);
-			scrollok (menu, FALSE);
-                	scroll++;
-                	print_item (menu, items[(scroll+max_choice-1)*2+1],
-			            max_choice-1, FALSE,
-			            (items[(scroll+max_choice-1)*2][0] != ':'));
-		    } else {
-			if (choice+1 < max_choice)
-			    choice++;
-		    }
-                }
-
-            } else
-                choice = i;
-
-            print_item (menu, items[(scroll+choice)*2+1], choice, TRUE,
-                       (items[(scroll+choice)*2][0] != ':'));
-
-            print_arrows(dialog, item_no, scroll,
-                         box_y, box_x+item_x+1, menu_height);
-
-            wnoutrefresh (dialog);
-            wrefresh (menu);
-
-	    continue;		/* wait for another key press */
-        }
-
-	switch (key) {
-	case KEY_LEFT:
-	case TAB:
-	case KEY_RIGHT:
-	    button = ((key == KEY_LEFT ? --button : ++button) < 0)
-			? 2 : (button > 2 ? 0 : button);
-
-	    print_buttons(dialog, height, width, button);
-	    wrefresh (menu);
-	    break;
-	case ' ':
-	case 's':
-	case 'y':
-	case 'n':
-	case 'm':
-	case '/':
-	    /* save scroll info */
-	    if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
-		fprintf(f,"%d\n",scroll);
-		fclose(f);
-	    }
-	    delwin (dialog);
-            fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
-            switch (key) {
-            case 's': return 3;
-            case 'y': return 3;
-            case 'n': return 4;
-            case 'm': return 5;
-            case ' ': return 6;
-            case '/': return 7;
-            }
-	    return 0;
-	case 'h':
-	case '?':
-	    button = 2;
-	case '\n':
-	    delwin (dialog);
-	    if (button == 2) 
-            	fprintf(stderr, "%s \"%s\"\n", 
-			items[(scroll + choice) * 2],
-			items[(scroll + choice) * 2 + 1] +
-			first_alpha(items[(scroll + choice) * 2 + 1],""));
-	    else
-            	fprintf(stderr, "%s\n", items[(scroll + choice) * 2]);
-
-	    remove("lxdialog.scrltmp");
-	    return button;
-	case 'e':
-	case 'x':
-	    key = ESC;
-	case ESC:
-	    break;
-	}
-    }
-
-    delwin (dialog);
-    remove("lxdialog.scrltmp");
-    return -1;			/* ESC pressed */
-}
diff --git a/scripts/lxdialog/msgbox.c b/scripts/lxdialog/msgbox.c
deleted file mode 100644
index 93692e1..0000000
--- a/scripts/lxdialog/msgbox.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  msgbox.c -- implements the message box and info box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display a message box. Program will pause and display an "OK" button
- * if the parameter 'pause' is non-zero.
- */
-int
-dialog_msgbox (const char *title, const char *prompt, int height, int width,
-		int pause)
-{
-    int i, x, y, key = 0;
-    WINDOW *dialog;
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-	/* truncate long title -- mec */
-	char * title2 = malloc(width-2+1);
-	memcpy( title2, title, width-2 );
-	title2[width-2] = '\0';
-	title = title2;
-    }
-
-    if (title != NULL) {
-	wattrset (dialog, title_attr);
-	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-	waddstr (dialog, (char *)title);
-	waddch (dialog, ' ');
-    }
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 2);
-
-    if (pause) {
-	wattrset (dialog, border_attr);
-	mvwaddch (dialog, height - 3, 0, ACS_LTEE);
-	for (i = 0; i < width - 2; i++)
-	    waddch (dialog, ACS_HLINE);
-	wattrset (dialog, dialog_attr);
-	waddch (dialog, ACS_RTEE);
-
-	print_button (dialog, "  Ok  ",
-		      height - 2, width / 2 - 4, TRUE);
-
-	wrefresh (dialog);
-	while (key != ESC && key != '\n' && key != ' ' &&
-               key != 'O' && key != 'o' && key != 'X' && key != 'x')
-	    key = wgetch (dialog);
-    } else {
-	key = '\n';
-	wrefresh (dialog);
-    }
-
-    delwin (dialog);
-    return key == ESC ? -1 : 0;
-}
diff --git a/scripts/lxdialog/textbox.c b/scripts/lxdialog/textbox.c
deleted file mode 100644
index ed23df2..0000000
--- a/scripts/lxdialog/textbox.c
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- *  textbox.c -- implements the text box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-static void back_lines (int n);
-static void print_page (WINDOW * win, int height, int width);
-static void print_line (WINDOW * win, int row, int width);
-static char *get_line (void);
-static void print_position (WINDOW * win, int height, int width);
-
-static int hscroll, fd, file_size, bytes_read;
-static int begin_reached = 1, end_reached, page_length;
-static char *buf, *page;
-
-/*
- * Display text from a file in a dialog box.
- */
-int
-dialog_textbox (const char *title, const char *file, int height, int width)
-{
-    int i, x, y, cur_x, cur_y, fpos, key = 0;
-    int passed_end;
-    char search_term[MAX_LEN + 1];
-    WINDOW *dialog, *text;
-
-    search_term[0] = '\0';	/* no search term entered yet */
-
-    /* Open input file for reading */
-    if ((fd = open (file, O_RDONLY)) == -1) {
-	endwin ();
-	fprintf (stderr,
-		 "\nCan't open input file in dialog_textbox().\n");
-	exit (-1);
-    }
-    /* Get file size. Actually, 'file_size' is the real file size - 1,
-       since it's only the last byte offset from the beginning */
-    if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
-	endwin ();
-	fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
-	exit (-1);
-    }
-    /* Restore file pointer to beginning of file after getting file size */
-    if (lseek (fd, 0, SEEK_SET) == -1) {
-	endwin ();
-	fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
-	exit (-1);
-    }
-    /* Allocate space for read buffer */
-    if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
-	endwin ();
-	fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
-	exit (-1);
-    }
-    if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-	endwin ();
-	fprintf (stderr, "\nError reading file in dialog_textbox().\n");
-	exit (-1);
-    }
-    buf[bytes_read] = '\0';	/* mark end of valid data */
-    page = buf;			/* page is pointer to start of page to be displayed */
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    /* Create window for text region, used for scrolling text */
-    text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
-    wattrset (text, dialog_attr);
-    wbkgdset (text, dialog_attr & A_COLOR);
-
-    keypad (text, TRUE);
-
-    /* register the new window, along with its borders */
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-	waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    wbkgdset (dialog, dialog_attr & A_COLOR);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-	/* truncate long title -- mec */
-	char * title2 = malloc(width-2+1);
-	memcpy( title2, title, width-2 );
-	title2[width-2] = '\0';
-	title = title2;
-    }
-
-    if (title != NULL) {
-	wattrset (dialog, title_attr);
-	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-	waddstr (dialog, (char *)title);
-	waddch (dialog, ' ');
-    }
-    print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
-    wnoutrefresh (dialog);
-    getyx (dialog, cur_y, cur_x);	/* Save cursor position */
-
-    /* Print first page of text */
-    attr_clear (text, height - 4, width - 2, dialog_attr);
-    print_page (text, height - 4, width - 2);
-    print_position (dialog, height, width);
-    wmove (dialog, cur_y, cur_x);	/* Restore cursor position */
-    wrefresh (dialog);
-
-    while ((key != ESC) && (key != '\n')) {
-	key = wgetch (dialog);
-	switch (key) {
-	case 'E':		/* Exit */
-	case 'e':
-	case 'X':
-	case 'x':
-	    delwin (dialog);
-	    free (buf);
-	    close (fd);
-	    return 0;
-	case 'g':		/* First page */
-	case KEY_HOME:
-	    if (!begin_reached) {
-		begin_reached = 1;
-		/* First page not in buffer? */
-		if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-		    endwin ();
-		    fprintf (stderr,
-		      "\nError moving file pointer in dialog_textbox().\n");
-		    exit (-1);
-		}
-		if (fpos > bytes_read) {	/* Yes, we have to read it in */
-		    if (lseek (fd, 0, SEEK_SET) == -1) {
-			endwin ();
-			fprintf (stderr, "\nError moving file pointer in "
-				 "dialog_textbox().\n");
-			exit (-1);
-		    }
-		    if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-			endwin ();
-			fprintf (stderr,
-			     "\nError reading file in dialog_textbox().\n");
-			exit (-1);
-		    }
-		    buf[bytes_read] = '\0';
-		}
-		page = buf;
-		print_page (text, height - 4, width - 2);
-		print_position (dialog, height, width);
-		wmove (dialog, cur_y, cur_x);	/* Restore cursor position */
-		wrefresh (dialog);
-	    }
-	    break;
-	case 'G':		/* Last page */
-	case KEY_END:
-
-	    end_reached = 1;
-	    /* Last page not in buffer? */
-	    if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-		endwin ();
-		fprintf (stderr,
-		      "\nError moving file pointer in dialog_textbox().\n");
-		exit (-1);
-	    }
-	    if (fpos < file_size) {	/* Yes, we have to read it in */
-		if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
-		    endwin ();
-		    fprintf (stderr,
-		      "\nError moving file pointer in dialog_textbox().\n");
-		    exit (-1);
-		}
-		if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-		    endwin ();
-		    fprintf (stderr,
-			     "\nError reading file in dialog_textbox().\n");
-		    exit (-1);
-		}
-		buf[bytes_read] = '\0';
-	    }
-	    page = buf + bytes_read;
-	    back_lines (height - 4);
-	    print_page (text, height - 4, width - 2);
-	    print_position (dialog, height, width);
-	    wmove (dialog, cur_y, cur_x);	/* Restore cursor position */
-	    wrefresh (dialog);
-	    break;
-	case 'K':		/* Previous line */
-	case 'k':
-	case KEY_UP:
-	    if (!begin_reached) {
-		back_lines (page_length + 1);
-
-		/* We don't call print_page() here but use scrolling to ensure
-		   faster screen update. However, 'end_reached' and
-		   'page_length' should still be updated, and 'page' should
-		   point to start of next page. This is done by calling
-		   get_line() in the following 'for' loop. */
-		scrollok (text, TRUE);
-		wscrl (text, -1);	/* Scroll text region down one line */
-		scrollok (text, FALSE);
-		page_length = 0;
-		passed_end = 0;
-		for (i = 0; i < height - 4; i++) {
-		    if (!i) {
-			/* print first line of page */
-			print_line (text, 0, width - 2);
-			wnoutrefresh (text);
-		    } else
-			/* Called to update 'end_reached' and 'page' */
-			get_line ();
-		    if (!passed_end)
-			page_length++;
-		    if (end_reached && !passed_end)
-			passed_end = 1;
-		}
-
-		print_position (dialog, height, width);
-		wmove (dialog, cur_y, cur_x);	/* Restore cursor position */
-		wrefresh (dialog);
-	    }
-	    break;
-	case 'B':		/* Previous page */
-	case 'b':
-	case KEY_PPAGE:
-	    if (begin_reached)
-		break;
-	    back_lines (page_length + height - 4);
-	    print_page (text, height - 4, width - 2);
-	    print_position (dialog, height, width);
-	    wmove (dialog, cur_y, cur_x);
-	    wrefresh (dialog);
-	    break;
-	case 'J':		/* Next line */
-	case 'j':
-	case KEY_DOWN:
-	    if (!end_reached) {
-		begin_reached = 0;
-		scrollok (text, TRUE);
-		scroll (text);	/* Scroll text region up one line */
-		scrollok (text, FALSE);
-		print_line (text, height - 5, width - 2);
-		wnoutrefresh (text);
-		print_position (dialog, height, width);
-		wmove (dialog, cur_y, cur_x);	/* Restore cursor position */
-		wrefresh (dialog);
-	    }
-	    break;
-	case KEY_NPAGE:		/* Next page */
-	case ' ':
-	    if (end_reached)
-		break;
-
-	    begin_reached = 0;
-	    print_page (text, height - 4, width - 2);
-	    print_position (dialog, height, width);
-	    wmove (dialog, cur_y, cur_x);
-	    wrefresh (dialog);
-	    break;
-	case '0':		/* Beginning of line */
-	case 'H':		/* Scroll left */
-	case 'h':
-	case KEY_LEFT:
-	    if (hscroll <= 0)
-		break;
-
-	    if (key == '0')
-		hscroll = 0;
-	    else
-		hscroll--;
-	    /* Reprint current page to scroll horizontally */
-	    back_lines (page_length);
-	    print_page (text, height - 4, width - 2);
-	    wmove (dialog, cur_y, cur_x);
-	    wrefresh (dialog);
-	    break;
-	case 'L':		/* Scroll right */
-	case 'l':
-	case KEY_RIGHT:
-	    if (hscroll >= MAX_LEN)
-		break;
-	    hscroll++;
-	    /* Reprint current page to scroll horizontally */
-	    back_lines (page_length);
-	    print_page (text, height - 4, width - 2);
-	    wmove (dialog, cur_y, cur_x);
-	    wrefresh (dialog);
-	    break;
-	case ESC:
-	    break;
-	}
-    }
-
-    delwin (dialog);
-    free (buf);
-    close (fd);
-    return -1;			/* ESC pressed */
-}
-
-/*
- * Go back 'n' lines in text file. Called by dialog_textbox().
- * 'page' will be updated to point to the desired line in 'buf'.
- */
-static void
-back_lines (int n)
-{
-    int i, fpos;
-
-    begin_reached = 0;
-    /* We have to distinguish between end_reached and !end_reached
-       since at end of file, the line is not ended by a '\n'.
-       The code inside 'if' basically does a '--page' to move one
-       character backward so as to skip '\n' of the previous line */
-    if (!end_reached) {
-	/* Either beginning of buffer or beginning of file reached? */
-	if (page == buf) {
-	    if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-		endwin ();
-		fprintf (stderr, "\nError moving file pointer in "
-			 "back_lines().\n");
-		exit (-1);
-	    }
-	    if (fpos > bytes_read) {	/* Not beginning of file yet */
-		/* We've reached beginning of buffer, but not beginning of
-		   file yet, so read previous part of file into buffer.
-		   Note that we only move backward for BUF_SIZE/2 bytes,
-		   but not BUF_SIZE bytes to avoid re-reading again in
-		   print_page() later */
-		/* Really possible to move backward BUF_SIZE/2 bytes? */
-		if (fpos < BUF_SIZE / 2 + bytes_read) {
-		    /* No, move less then */
-		    if (lseek (fd, 0, SEEK_SET) == -1) {
-			endwin ();
-			fprintf (stderr, "\nError moving file pointer in "
-				 "back_lines().\n");
-			exit (-1);
-		    }
-		    page = buf + fpos - bytes_read;
-		} else {	/* Move backward BUF_SIZE/2 bytes */
-		    if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
-			== -1) {
-			endwin ();
-			fprintf (stderr, "\nError moving file pointer "
-				 "in back_lines().\n");
-			exit (-1);
-		    }
-		    page = buf + BUF_SIZE / 2;
-		}
-		if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-		    endwin ();
-		    fprintf (stderr, "\nError reading file in back_lines().\n");
-		    exit (-1);
-		}
-		buf[bytes_read] = '\0';
-	    } else {		/* Beginning of file reached */
-		begin_reached = 1;
-		return;
-	    }
-	}
-	if (*(--page) != '\n') {	/* '--page' here */
-	    /* Something's wrong... */
-	    endwin ();
-	    fprintf (stderr, "\nInternal error in back_lines().\n");
-	    exit (-1);
-	}
-    }
-    /* Go back 'n' lines */
-    for (i = 0; i < n; i++)
-	do {
-	    if (page == buf) {
-		if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-		    endwin ();
-		    fprintf (stderr,
-			  "\nError moving file pointer in back_lines().\n");
-		    exit (-1);
-		}
-		if (fpos > bytes_read) {
-		    /* Really possible to move backward BUF_SIZE/2 bytes? */
-		    if (fpos < BUF_SIZE / 2 + bytes_read) {
-			/* No, move less then */
-			if (lseek (fd, 0, SEEK_SET) == -1) {
-			    endwin ();
-			    fprintf (stderr, "\nError moving file pointer "
-				     "in back_lines().\n");
-			    exit (-1);
-			}
-			page = buf + fpos - bytes_read;
-		    } else {	/* Move backward BUF_SIZE/2 bytes */
-			if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
-				   SEEK_CUR) == -1) {
-			    endwin ();
-			    fprintf (stderr, "\nError moving file pointer"
-				     " in back_lines().\n");
-			    exit (-1);
-			}
-			page = buf + BUF_SIZE / 2;
-		    }
-		    if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-			endwin ();
-			fprintf (stderr, "\nError reading file in "
-				 "back_lines().\n");
-			exit (-1);
-		    }
-		    buf[bytes_read] = '\0';
-		} else {	/* Beginning of file reached */
-		    begin_reached = 1;
-		    return;
-		}
-	    }
-	} while (*(--page) != '\n');
-    page++;
-}
-
-/*
- * Print a new page of text. Called by dialog_textbox().
- */
-static void
-print_page (WINDOW * win, int height, int width)
-{
-    int i, passed_end = 0;
-
-    page_length = 0;
-    for (i = 0; i < height; i++) {
-	print_line (win, i, width);
-	if (!passed_end)
-	    page_length++;
-	if (end_reached && !passed_end)
-	    passed_end = 1;
-    }
-    wnoutrefresh (win);
-}
-
-/*
- * Print a new line of text. Called by dialog_textbox() and print_page().
- */
-static void
-print_line (WINDOW * win, int row, int width)
-{
-    int y, x;
-    char *line;
-
-    line = get_line ();
-    line += MIN (strlen (line), hscroll);	/* Scroll horizontally */
-    wmove (win, row, 0);	/* move cursor to correct line */
-    waddch (win, ' ');
-    waddnstr (win, line, MIN (strlen (line), width - 2));
-
-    getyx (win, y, x);
-    /* Clear 'residue' of previous line */
-#if OLD_NCURSES
-    {
-        int i;
-        for (i = 0; i < width - x; i++)
-	    waddch (win, ' ');
-    }
-#else
-    wclrtoeol(win);
-#endif
-}
-
-/*
- * Return current line of text. Called by dialog_textbox() and print_line().
- * 'page' should point to start of current line before calling, and will be
- * updated to point to start of next line.
- */
-static char *
-get_line (void)
-{
-    int i = 0, fpos;
-    static char line[MAX_LEN + 1];
-
-    end_reached = 0;
-    while (*page != '\n') {
-	if (*page == '\0') {
-	    /* Either end of file or end of buffer reached */
-	    if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-		endwin ();
-		fprintf (stderr, "\nError moving file pointer in "
-			 "get_line().\n");
-		exit (-1);
-	    }
-	    if (fpos < file_size) {	/* Not end of file yet */
-		/* We've reached end of buffer, but not end of file yet,
-		   so read next part of file into buffer */
-		if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-		    endwin ();
-		    fprintf (stderr, "\nError reading file in get_line().\n");
-		    exit (-1);
-		}
-		buf[bytes_read] = '\0';
-		page = buf;
-	    } else {
-		if (!end_reached)
-		    end_reached = 1;
-		break;
-	    }
-	} else if (i < MAX_LEN)
-	    line[i++] = *(page++);
-	else {
-	    /* Truncate lines longer than MAX_LEN characters */
-	    if (i == MAX_LEN)
-		line[i++] = '\0';
-	    page++;
-	}
-    }
-    if (i <= MAX_LEN)
-	line[i] = '\0';
-    if (!end_reached)
-	page++;			/* move pass '\n' */
-
-    return line;
-}
-
-/*
- * Print current position
- */
-static void
-print_position (WINDOW * win, int height, int width)
-{
-    int fpos, percent;
-
-    if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-	endwin ();
-	fprintf (stderr, "\nError moving file pointer in print_position().\n");
-	exit (-1);
-    }
-    wattrset (win, position_indicator_attr);
-    wbkgdset (win, position_indicator_attr & A_COLOR);
-    percent = !file_size ?
-	100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
-    wmove (win, height - 3, width - 9);
-    wprintw (win, "(%3d%%)", percent);
-}
diff --git a/scripts/lxdialog/util.c b/scripts/lxdialog/util.c
deleted file mode 100644
index e7bce9b..0000000
--- a/scripts/lxdialog/util.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- *  util.c
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-
-/* use colors by default? */
-bool use_colors = 1;
-
-const char *backtitle = NULL;
-
-const char *dialog_result;
-
-/* 
- * Attribute values, default is for mono display
- */
-chtype attributes[] =
-{
-    A_NORMAL,			/* screen_attr */
-    A_NORMAL,			/* shadow_attr */
-    A_NORMAL,			/* dialog_attr */
-    A_BOLD,			/* title_attr */
-    A_NORMAL,			/* border_attr */
-    A_REVERSE,			/* button_active_attr */
-    A_DIM,			/* button_inactive_attr */
-    A_REVERSE,			/* button_key_active_attr */
-    A_BOLD,			/* button_key_inactive_attr */
-    A_REVERSE,			/* button_label_active_attr */
-    A_NORMAL,			/* button_label_inactive_attr */
-    A_NORMAL,			/* inputbox_attr */
-    A_NORMAL,			/* inputbox_border_attr */
-    A_NORMAL,			/* searchbox_attr */
-    A_BOLD,			/* searchbox_title_attr */
-    A_NORMAL,			/* searchbox_border_attr */
-    A_BOLD,			/* position_indicator_attr */
-    A_NORMAL,			/* menubox_attr */
-    A_NORMAL,			/* menubox_border_attr */
-    A_NORMAL,			/* item_attr */
-    A_REVERSE,			/* item_selected_attr */
-    A_BOLD,			/* tag_attr */
-    A_REVERSE,			/* tag_selected_attr */
-    A_BOLD,			/* tag_key_attr */
-    A_REVERSE,			/* tag_key_selected_attr */
-    A_BOLD,			/* check_attr */
-    A_REVERSE,			/* check_selected_attr */
-    A_BOLD,			/* uarrow_attr */
-    A_BOLD			/* darrow_attr */
-};
-
-
-#include "colors.h"
-
-/*
- * Table of color values
- */
-int color_table[][3] =
-{
-    {SCREEN_FG, SCREEN_BG, SCREEN_HL},
-    {SHADOW_FG, SHADOW_BG, SHADOW_HL},
-    {DIALOG_FG, DIALOG_BG, DIALOG_HL},
-    {TITLE_FG, TITLE_BG, TITLE_HL},
-    {BORDER_FG, BORDER_BG, BORDER_HL},
-    {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
-    {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
-    {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
-    {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
-    {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
-    {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
-     BUTTON_LABEL_INACTIVE_HL},
-    {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
-    {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
-    {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
-    {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
-    {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
-    {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
-    {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
-    {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
-    {ITEM_FG, ITEM_BG, ITEM_HL},
-    {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
-    {TAG_FG, TAG_BG, TAG_HL},
-    {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
-    {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
-    {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
-    {CHECK_FG, CHECK_BG, CHECK_HL},
-    {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
-    {UARROW_FG, UARROW_BG, UARROW_HL},
-    {DARROW_FG, DARROW_BG, DARROW_HL},
-};				/* color_table */
-
-/*
- * Set window to attribute 'attr'
- */
-void
-attr_clear (WINDOW * win, int height, int width, chtype attr)
-{
-    int i, j;
-
-    wattrset (win, attr);
-    for (i = 0; i < height; i++) {
-	wmove (win, i, 0);
-	for (j = 0; j < width; j++)
-	    waddch (win, ' ');
-    }
-    touchwin (win);
-}
-
-void dialog_clear (void)
-{
-    attr_clear (stdscr, LINES, COLS, screen_attr);
-    /* Display background title if it exists ... - SLH */
-    if (backtitle != NULL) {
-        int i;
-
-        wattrset (stdscr, screen_attr);
-        mvwaddstr (stdscr, 0, 1, (char *)backtitle);
-        wmove (stdscr, 1, 1);
-        for (i = 1; i < COLS - 1; i++)
-            waddch (stdscr, ACS_HLINE);
-    }
-    wnoutrefresh (stdscr);
-}
-
-/*
- * Do some initialization for dialog
- */
-void
-init_dialog (void)
-{
-    initscr ();			/* Init curses */
-    keypad (stdscr, TRUE);
-    cbreak ();
-    noecho ();
-
-
-    if (use_colors)	/* Set up colors */
-	color_setup ();
-
-
-    dialog_clear ();
-}
-
-/*
- * Setup for color display
- */
-void
-color_setup (void)
-{
-    int i;
-
-    if (has_colors ()) {	/* Terminal supports color? */
-	start_color ();
-
-	/* Initialize color pairs */
-	for (i = 0; i < ATTRIBUTE_COUNT; i++)
-	    init_pair (i + 1, color_table[i][0], color_table[i][1]);
-
-	/* Setup color attributes */
-	for (i = 0; i < ATTRIBUTE_COUNT; i++)
-	    attributes[i] = C_ATTR (color_table[i][2], i + 1);
-    }
-}
-
-/*
- * End using dialog functions.
- */
-void
-end_dialog (void)
-{
-    endwin ();
-}
-
-
-/*
- * Print a string of text in a window, automatically wrap around to the
- * next line if the string is too long to fit on one line. Newline
- * characters '\n' are replaced by spaces.  We start on a new line
- * if there is no room for at least 4 nonblanks following a double-space.
- */
-void
-print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
-{
-    int newl, cur_x, cur_y;
-    int i, prompt_len, room, wlen;
-    char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
-
-    strcpy (tempstr, prompt);
-
-    prompt_len = strlen(tempstr);
-	
-    /*
-     * Remove newlines
-     */
-    for(i=0; i<prompt_len; i++) {
-	if(tempstr[i] == '\n') tempstr[i] = ' ';
-    }
-
-    if (prompt_len <= width - x * 2) {	/* If prompt is short */
-	wmove (win, y, (width - prompt_len) / 2);
-	waddstr (win, tempstr);
-    } else {
-	cur_x = x;
-	cur_y = y;
-	newl = 1;
-	word = tempstr;
-	while (word && *word) {
-	    sp = index(word, ' ');
-	    if (sp)
-	        *sp++ = 0;
-
-	    /* Wrap to next line if either the word does not fit,
-	       or it is the first word of a new sentence, and it is
-	       short, and the next word does not fit. */
-	    room = width - cur_x;
-	    wlen = strlen(word);
-	    if (wlen > room ||
-	       (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
-		     && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
-		cur_y++;
-		cur_x = x;
-	    }
-	    wmove (win, cur_y, cur_x);
-	    waddstr (win, word);
-	    getyx (win, cur_y, cur_x);
-	    cur_x++;
-	    if (sp && *sp == ' ') {
-	        cur_x++;	/* double space */
-		while (*++sp == ' ');
-		newl = 1;
-	    } else
-	        newl = 0;
-	    word = sp;
-	}
-    }
-}
-
-/*
- * Print a button
- */
-void
-print_button (WINDOW * win, const char *label, int y, int x, int selected)
-{
-    int i, temp;
-
-    wmove (win, y, x);
-    wattrset (win, selected ? button_active_attr : button_inactive_attr);
-    waddstr (win, "<");
-    temp = strspn (label, " ");
-    label += temp;
-    wattrset (win, selected ? button_label_active_attr
-	      : button_label_inactive_attr);
-    for (i = 0; i < temp; i++)
-	waddch (win, ' ');
-    wattrset (win, selected ? button_key_active_attr
-	      : button_key_inactive_attr);
-    waddch (win, label[0]);
-    wattrset (win, selected ? button_label_active_attr
-	      : button_label_inactive_attr);
-    waddstr (win, (char *)label + 1);
-    wattrset (win, selected ? button_active_attr : button_inactive_attr);
-    waddstr (win, ">");
-    wmove (win, y, x + temp + 1);
-}
-
-/*
- * Draw a rectangular box with line drawing characters
- */
-void
-draw_box (WINDOW * win, int y, int x, int height, int width,
-	  chtype box, chtype border)
-{
-    int i, j;
-
-    wattrset (win, 0);
-    for (i = 0; i < height; i++) {
-	wmove (win, y + i, x);
-	for (j = 0; j < width; j++)
-	    if (!i && !j)
-		waddch (win, border | ACS_ULCORNER);
-	    else if (i == height - 1 && !j)
-		waddch (win, border | ACS_LLCORNER);
-	    else if (!i && j == width - 1)
-		waddch (win, box | ACS_URCORNER);
-	    else if (i == height - 1 && j == width - 1)
-		waddch (win, box | ACS_LRCORNER);
-	    else if (!i)
-		waddch (win, border | ACS_HLINE);
-	    else if (i == height - 1)
-		waddch (win, box | ACS_HLINE);
-	    else if (!j)
-		waddch (win, border | ACS_VLINE);
-	    else if (j == width - 1)
-		waddch (win, box | ACS_VLINE);
-	    else
-		waddch (win, box | ' ');
-    }
-}
-
-/*
- * Draw shadows along the right and bottom edge to give a more 3D look
- * to the boxes
- */
-void
-draw_shadow (WINDOW * win, int y, int x, int height, int width)
-{
-    int i;
-
-    if (has_colors ()) {	/* Whether terminal supports color? */
-	wattrset (win, shadow_attr);
-	wmove (win, y + height, x + 2);
-	for (i = 0; i < width; i++)
-	    waddch (win, winch (win) & A_CHARTEXT);
-	for (i = y + 1; i < y + height + 1; i++) {
-	    wmove (win, i, x + width);
-	    waddch (win, winch (win) & A_CHARTEXT);
-	    waddch (win, winch (win) & A_CHARTEXT);
-	}
-	wnoutrefresh (win);
-    }
-}
-
-/*
- *  Return the position of the first alphabetic character in a string.
- */
-int
-first_alpha(const char *string, const char *exempt)
-{
-	int i, in_paren=0, c;
-
-	for (i = 0; i < strlen(string); i++) {
-		c = tolower(string[i]);
-
-		if (strchr("<[(", c)) ++in_paren;
-		if (strchr(">])", c) && in_paren > 0) --in_paren;
-
-		if ((! in_paren) && isalpha(c) && 
-		     strchr(exempt, c) == 0)
-			return i;
-	}
-
-	return 0;
-}
diff --git a/scripts/lxdialog/yesno.c b/scripts/lxdialog/yesno.c
deleted file mode 100644
index 11fcc25..0000000
--- a/scripts/lxdialog/yesno.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *  yesno.c -- implements the yes/no box
- *
- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License
- *  as published by the Free Software Foundation; either version 2
- *  of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "dialog.h"
-
-/*
- * Display termination buttons
- */
-static void
-print_buttons(WINDOW *dialog, int height, int width, int selected)
-{
-    int x = width / 2 - 10;
-    int y = height - 2;
-
-    print_button (dialog, " Yes ", y, x, selected == 0);
-    print_button (dialog, "  No  ", y, x + 13, selected == 1);
-
-    wmove(dialog, y, x+1 + 13*selected );
-    wrefresh (dialog);
-}
-
-/*
- * Display a dialog box with two buttons - Yes and No
- */
-int
-dialog_yesno (const char *title, const char *prompt, int height, int width)
-{
-    int i, x, y, key = 0, button = 0;
-    WINDOW *dialog;
-
-    /* center dialog box on screen */
-    x = (COLS - width) / 2;
-    y = (LINES - height) / 2;
-
-    draw_shadow (stdscr, y, x, height, width);
-
-    dialog = newwin (height, width, y, x);
-    keypad (dialog, TRUE);
-
-    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-    wattrset (dialog, border_attr);
-    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-    for (i = 0; i < width - 2; i++)
-	waddch (dialog, ACS_HLINE);
-    wattrset (dialog, dialog_attr);
-    waddch (dialog, ACS_RTEE);
-
-    if (title != NULL && strlen(title) >= width-2 ) {
-	/* truncate long title -- mec */
-	char * title2 = malloc(width-2+1);
-	memcpy( title2, title, width-2 );
-	title2[width-2] = '\0';
-	title = title2;
-    }
-
-    if (title != NULL) {
-	wattrset (dialog, title_attr);
-	mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-	waddstr (dialog, (char *)title);
-	waddch (dialog, ' ');
-    }
-
-    wattrset (dialog, dialog_attr);
-    print_autowrap (dialog, prompt, width - 2, 1, 3);
-
-    print_buttons(dialog, height, width, 0);
-
-    while (key != ESC) {
-	key = wgetch (dialog);
-	switch (key) {
-	case 'Y':
-	case 'y':
-	    delwin (dialog);
-	    return 0;
-	case 'N':
-	case 'n':
-	    delwin (dialog);
-	    return 1;
-
-	case TAB:
-	case KEY_LEFT:
-	case KEY_RIGHT:
-	    button = ((key == KEY_LEFT ? --button : ++button) < 0)
-			? 1 : (button > 1 ? 0 : button);
-
-	    print_buttons(dialog, height, width, button);
-	    wrefresh (dialog);
-	    break;
-	case ' ':
-	case '\n':
-	    delwin (dialog);
-	    return button;
-	case ESC:
-	    break;
-	}
-    }
-
-    delwin (dialog);
-    return -1;			/* ESC pressed */
-}
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index e3d144a..e0eedff 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -16,8 +16,10 @@
  * use either stdint.h or inttypes.h for the rest. */
 #if KERNEL_ELFCLASS == ELFCLASS32
 typedef Elf32_Addr	kernel_ulong_t;
+#define BITS_PER_LONG 32
 #else
 typedef Elf64_Addr	kernel_ulong_t;
+#define BITS_PER_LONG 64
 #endif
 #ifdef __sun__
 #include <inttypes.h>
@@ -35,6 +37,7 @@
  * even potentially has different endianness and word sizes, since 
  * we handle those differences explicitly below */
 #include "../../include/linux/mod_devicetable.h"
+#include "../../include/linux/input.h"
 
 #define ADD(str, sep, cond, field)                              \
 do {                                                            \
@@ -366,6 +369,61 @@
 	return 1;
 }
 
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+static void do_input(char *alias,
+		     kernel_ulong_t *arr, unsigned int min, unsigned int max)
+{
+	unsigned int i;
+	for (i = min; i < max; i++) {
+		if (arr[i/BITS_PER_LONG] & (1 << (i%BITS_PER_LONG)))
+			sprintf(alias+strlen(alias), "%X,*", i);
+	}
+}
+
+/* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */
+static int do_input_entry(const char *filename, struct input_device_id *id,
+			  char *alias)
+{
+	sprintf(alias, "input:");
+
+	ADD(alias, "b", id->flags&INPUT_DEVICE_ID_MATCH_BUS, id->id.bustype);
+	ADD(alias, "v", id->flags&INPUT_DEVICE_ID_MATCH_VENDOR, id->id.vendor);
+	ADD(alias, "p", id->flags&INPUT_DEVICE_ID_MATCH_PRODUCT,
+	    id->id.product);
+	ADD(alias, "e", id->flags&INPUT_DEVICE_ID_MATCH_VERSION,
+	    id->id.version);
+
+	sprintf(alias + strlen(alias), "-e*");
+	if (id->flags&INPUT_DEVICE_ID_MATCH_EVBIT)
+		do_input(alias, id->evbit, 0, EV_MAX);
+	sprintf(alias + strlen(alias), "k*");
+	if (id->flags&INPUT_DEVICE_ID_MATCH_KEYBIT)
+		do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
+	sprintf(alias + strlen(alias), "r*");
+	if (id->flags&INPUT_DEVICE_ID_MATCH_RELBIT)
+		do_input(alias, id->relbit, 0, REL_MAX);
+	sprintf(alias + strlen(alias), "a*");
+	if (id->flags&INPUT_DEVICE_ID_MATCH_ABSBIT)
+		do_input(alias, id->absbit, 0, ABS_MAX);
+	sprintf(alias + strlen(alias), "m*");
+	if (id->flags&INPUT_DEVICE_ID_MATCH_MSCIT)
+		do_input(alias, id->mscbit, 0, MSC_MAX);
+	sprintf(alias + strlen(alias), "l*");
+	if (id->flags&INPUT_DEVICE_ID_MATCH_LEDBIT)
+		do_input(alias, id->ledbit, 0, LED_MAX);
+	sprintf(alias + strlen(alias), "s*");
+	if (id->flags&INPUT_DEVICE_ID_MATCH_SNDBIT)
+		do_input(alias, id->sndbit, 0, SND_MAX);
+	sprintf(alias + strlen(alias), "f*");
+	if (id->flags&INPUT_DEVICE_ID_MATCH_FFBIT)
+		do_input(alias, id->ffbit, 0, SND_MAX);
+	sprintf(alias + strlen(alias), "w*");
+	if (id->flags&INPUT_DEVICE_ID_MATCH_SWBIT)
+		do_input(alias, id->swbit, 0, SW_MAX);
+	return 1;
+}
+
 /* Ignore any prefix, eg. v850 prepends _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -453,7 +511,9 @@
 	else if (sym_is(symname, "__mod_i2c_device_table"))
 		do_table(symval, sym->st_size, sizeof(struct i2c_device_id),
 			 do_i2c_entry, mod);
-
+	else if (sym_is(symname, "__mod_input_device_table"))
+		do_table(symval, sym->st_size, sizeof(struct input_device_id),
+			 do_input_entry, mod);
 }
 
 /* Now add out buffered information to the generated C source */
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 3bed09e..f70ff13 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -326,8 +326,8 @@
 	release_file(info->hdr, info->size);
 }
 
-#define CRC_PFX     MODULE_SYMBOL_PREFIX "__crc_"
-#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
+#define CRC_PFX     "__crc_"
+#define KSYMTAB_PFX "__ksymtab_"
 
 void
 handle_modversions(struct module *mod, struct elf_info *info,
@@ -539,10 +539,9 @@
 	buf_printf(b, "\n");
 	buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
 	buf_printf(b, "\n");
-	buf_printf(b, "#undef unix\n"); /* We have a module called "unix" */
 	buf_printf(b, "struct module __this_module\n");
 	buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
-	buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n");
+	buf_printf(b, " .name = KBUILD_MODNAME,\n");
 	if (mod->has_init)
 		buf_printf(b, " .init = init_module,\n");
 	if (mod->has_cleanup)
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
index f3e7e8e..c201ef00 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -84,7 +84,7 @@
 # ---------------------------------------------------------------------------
 .PHONY: tar%pkg
 tar%pkg:
-	$(MAKE)
+	$(MAKE) KBUILD_SRC=
 	$(CONFIG_SHELL) $(srctree)/scripts/package/buildtar $@
 
 clean-dirs += $(objtree)/tar-install/
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index d8fffe6..88b5281 100644
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -1,9 +1,9 @@
 #!/bin/sh
 
 #
-# buildtar 0.0.3
+# buildtar 0.0.4
 #
-# (C) 2004-2005 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
+# (C) 2004-2006 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
 #
 # This script is used to compile a tarball from the currently
 # prepared kernel. Based upon the builddeb script from
@@ -15,9 +15,8 @@
 #
 # Some variables and settings used throughout the script
 #
-version="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}${EXTRANAME}"
 tmpdir="${objtree}/tar-install"
-tarball="${objtree}/linux-${version}.tar"
+tarball="${objtree}/linux-${KERNELRELEASE}.tar"
 
 
 #
@@ -53,21 +52,17 @@
 #
 # Try to install modules
 #
-if ! make INSTALL_MOD_PATH="${tmpdir}" modules_install; then
-	echo "" >&2
-	echo "Ignoring error at module_install time, since that could be" >&2
-	echo "a result of missing local modutils/module-init-tools," >&2
-	echo "or you just didn't compile in module support at all..." >&2
-	echo "" >&2
+if grep -q '^CONFIG_MODULES=y' "${objtree}/.config"; then
+	make ARCH="${ARCH}" O="${objtree}" KBUILD_SRC= INSTALL_MOD_PATH="${tmpdir}" modules_install
 fi
 
 
 #
 # Install basic kernel files
 #
-cp -v -- System.map "${tmpdir}/boot/System.map-${version}"
-cp -v -- .config "${tmpdir}/boot/config-${version}"
-cp -v -- vmlinux "${tmpdir}/boot/vmlinux-${version}"
+cp -v -- "${objtree}/System.map" "${tmpdir}/boot/System.map-${KERNELRELEASE}"
+cp -v -- "${objtree}/.config" "${tmpdir}/boot/config-${KERNELRELEASE}"
+cp -v -- "${objtree}/vmlinux" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}"
 
 
 #
@@ -75,17 +70,17 @@
 #
 case "${ARCH}" in
 	i386)
-		[ -f arch/i386/boot/bzImage ] && cp -v -- arch/i386/boot/bzImage "${tmpdir}/boot/vmlinuz-${version}"
+		[ -f "${objtree}/arch/i386/boot/bzImage" ] && cp -v -- "${objtree}/arch/i386/boot/bzImage" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
 		;;
 	alpha)
-		[ -f arch/alpha/boot/vmlinux.gz ] && cp -v -- arch/alpha/boot/vmlinux.gz "${tmpdir}/boot/vmlinuz-${version}"
+		[ -f "${objtree}/arch/alpha/boot/vmlinux.gz" ] && cp -v -- "${objtree}/arch/alpha/boot/vmlinux.gz" "${tmpdir}/boot/vmlinuz-${KERNELRELEASE}"
 		;;
 	vax)
-		[ -f vmlinux.SYS ] && cp -v -- vmlinux.SYS "${tmpdir}/boot/vmlinux-${version}.SYS"
-		[ -f vmlinux.dsk ] && cp -v -- vmlinux.dsk "${tmpdir}/boot/vmlinux-${version}.dsk"
+		[ -f "${objtree}/vmlinux.SYS" ] && cp -v -- "${objtree}/vmlinux.SYS" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.SYS"
+		[ -f "${objtree}/vmlinux.dsk" ] && cp -v -- "${objtree}/vmlinux.dsk" "${tmpdir}/boot/vmlinux-${KERNELRELEASE}.dsk"
 		;;
 	*)
-		[ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${version}"
+		[ -f "${KBUILD_IMAGE}" ] && cp -v -- "${KBUILD_IMAGE}" "${tmpdir}/boot/vmlinux-kbuild-${KERNELRELEASE}"
 		echo "" >&2
 		echo '** ** **  WARNING  ** ** **' >&2
 		echo "" >&2
diff --git a/scripts/patch-kernel b/scripts/patch-kernel
index f2d47ca..67e4b18 100755
--- a/scripts/patch-kernel
+++ b/scripts/patch-kernel
@@ -45,7 +45,7 @@
 # update usage message;
 # fix some whitespace damage;
 # be smarter about stopping when current version is larger than requested;
-#	Randy Dunlap <rddunlap@osdl.org>, 2004-AUG-18.
+#	Randy Dunlap <rdunlap@xenotime.net>, 2004-AUG-18.
 #
 # Add better support for (non-incremental) 2.6.x.y patches;
 # If an ending version number if not specified, the script automatically
@@ -56,7 +56,7 @@
 # patch-kernel does not normally support reverse patching, but does so when
 # applying EXTRAVERSION (x.y) patches, so that moving from 2.6.11.y to 2.6.11.z
 # is easy and handled by the script (reverse 2.6.11.y and apply 2.6.11.z).
-#	Randy Dunlap <rddunlap@osdl.org>, 2005-APR-08.
+#	Randy Dunlap <rdunlap@xenotime.net>, 2005-APR-08.
 
 PNAME=patch-kernel
 
diff --git a/scripts/setlocalversion b/scripts/setlocalversion
index 7c805c8..f54dac8 100644
--- a/scripts/setlocalversion
+++ b/scripts/setlocalversion
@@ -1,56 +1,22 @@
-#!/usr/bin/perl
-# Copyright 2004 - Ryan Anderson <ryan@michonline.com>  GPL v2
+#!/bin/sh
+# Print additional version information for non-release trees.
 
-use strict;
-use warnings;
-use Digest::MD5;
-require 5.006;
-
-if (@ARGV != 1) {
-	print <<EOT;
-Usage: setlocalversion <srctree>
-EOT
-	exit(1);
+usage() {
+	echo "Usage: $0 [srctree]" >&2
+	exit 1
 }
 
-my ($srctree) = @ARGV;
-chdir($srctree);
+cd "${1:-.}" || usage
 
-my @LOCALVERSIONS = ();
+# Check for git and a git repo.
+if head=`git rev-parse --verify HEAD 2>/dev/null`; then
+	# Do we have an untagged version?
+	if  [ "`git name-rev --tags HEAD`" = "HEAD undefined" ]; then
+		printf '%s%s' -g `echo "$head" | cut -c1-8`
+	fi
 
-# We are going to use the following commands to try and determine if this
-# repository is at a Version boundary (i.e, 2.6.10 vs 2.6.10 + some patches) We
-# currently assume that all meaningful version boundaries are marked by a tag.
-# We don't care what the tag is, just that something exists.
-
-# Git/Cogito store the top-of-tree "commit" in .git/HEAD
-# A list of known tags sits in .git/refs/tags/
-#
-# The simple trick here is to just compare the two of these, and if we get a
-# match, return nothing, otherwise, return a subset of the SHA-1 hash in
-# .git/HEAD
-
-sub do_git_checks {
-	open(H,"<.git/HEAD") or return;
-	my $head = <H>;
-	chomp $head;
-	close(H);
-
-	opendir(D,".git/refs/tags") or return;
-	foreach my $tagfile (grep !/^\.{1,2}$/, readdir(D)) {
-		open(F,"<.git/refs/tags/" . $tagfile) or return;
-		my $tag = <F>;
-		chomp $tag;
-		close(F);
-		return if ($tag eq $head);
-	}
-	closedir(D);
-
-	push @LOCALVERSIONS, "g" . substr($head,0,8);
-}
-
-if ( -d ".git") {
-	do_git_checks();
-}
-
-printf "-%s\n", join("-",@LOCALVERSIONS) if (scalar @LOCALVERSIONS > 0);
+	# Are there uncommitted changes?
+	if git diff-files | read dummy; then
+		printf '%s' -git_dirty
+	fi
+fi
diff --git a/security/Kconfig b/security/Kconfig
index 64d3f1e..34f5934 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -54,6 +54,19 @@
 	  implement socket and networking access controls.
 	  If you are unsure how to answer this question, answer N.
 
+config SECURITY_NETWORK_XFRM
+	bool "XFRM (IPSec) Networking Security Hooks"
+	depends on XFRM && SECURITY_NETWORK
+	help
+	  This enables the XFRM (IPSec) networking security hooks.
+	  If enabled, a security module can use these hooks to
+	  implement per-packet access controls based on labels
+	  derived from IPSec policy.  Non-IPSec communications are
+	  designated as unlabelled, and only sockets authorized
+	  to communicate unlabelled data can send without using
+	  IPSec.
+	  If you are unsure how to answer this question, answer N.
+
 config SECURITY_CAPABILITIES
 	tristate "Default Linux Capabilities"
 	depends on SECURITY
diff --git a/security/capability.c b/security/capability.c
index ec18d60..f9b35cc 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -49,8 +49,6 @@
 	.vm_enough_memory =             cap_vm_enough_memory,
 };
 
-#define MY_NAME __stringify(KBUILD_MODNAME)
-
 /* flag to keep track of how we were registered */
 static int secondary;
 
@@ -67,7 +65,7 @@
 	/* register ourselves with the security framework */
 	if (register_security (&capability_ops)) {
 		/* try registering with primary module */
-		if (mod_reg_security (MY_NAME, &capability_ops)) {
+		if (mod_reg_security (KBUILD_MODNAME, &capability_ops)) {
 			printk (KERN_INFO "Failure registering capabilities "
 				"with primary security module.\n");
 			return -EINVAL;
@@ -85,7 +83,7 @@
 		return;
 	/* remove ourselves from the security framework */
 	if (secondary) {
-		if (mod_unreg_security (MY_NAME, &capability_ops))
+		if (mod_unreg_security (KBUILD_MODNAME, &capability_ops))
 			printk (KERN_INFO "Failure unregistering capabilities "
 				"with primary module.\n");
 		return;
diff --git a/security/dummy.c b/security/dummy.c
index 3ca5f2b..a15c547 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -776,8 +776,42 @@
 static inline void dummy_sk_free_security (struct sock *sk)
 {
 }
+
+static unsigned int dummy_sk_getsid(struct sock *sk, struct flowi *fl, u8 dir)
+{
+	return 0;
+}
 #endif	/* CONFIG_SECURITY_NETWORK */
 
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return 0;
+}
+
+static inline int dummy_xfrm_policy_clone_security(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+	return 0;
+}
+
+static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp)
+{
+}
+
+static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
+{
+	return 0;
+}
+
+static void dummy_xfrm_state_free_security(struct xfrm_state *x)
+{
+}
+
+static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+	return 0;
+}
+#endif /* CONFIG_SECURITY_NETWORK_XFRM */
 static int dummy_register_security (const char *name, struct security_operations *ops)
 {
 	return -EINVAL;
@@ -970,7 +1004,16 @@
 	set_to_dummy_if_null(ops, socket_getpeersec);
 	set_to_dummy_if_null(ops, sk_alloc_security);
 	set_to_dummy_if_null(ops, sk_free_security);
-#endif	/* CONFIG_SECURITY_NETWORK */
+	set_to_dummy_if_null(ops, sk_getsid);
+ #endif	/* CONFIG_SECURITY_NETWORK */
+#ifdef  CONFIG_SECURITY_NETWORK_XFRM
+	set_to_dummy_if_null(ops, xfrm_policy_alloc_security);
+	set_to_dummy_if_null(ops, xfrm_policy_clone_security);
+	set_to_dummy_if_null(ops, xfrm_policy_free_security);
+	set_to_dummy_if_null(ops, xfrm_state_alloc_security);
+	set_to_dummy_if_null(ops, xfrm_state_free_security);
+	set_to_dummy_if_null(ops, xfrm_policy_lookup);
+#endif	/* CONFIG_SECURITY_NETWORK_XFRM */
 #ifdef CONFIG_KEYS
 	set_to_dummy_if_null(ops, key_alloc);
 	set_to_dummy_if_null(ops, key_free);
diff --git a/security/keys/compat.c b/security/keys/compat.c
index 3303673..bcdb285 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -74,6 +74,12 @@
 	case KEYCTL_SET_REQKEY_KEYRING:
 		return keyctl_set_reqkey_keyring(arg2);
 
+	case KEYCTL_SET_TIMEOUT:
+		return keyctl_set_timeout(arg2, arg3);
+
+	case KEYCTL_ASSUME_AUTHORITY:
+		return keyctl_assume_authority(arg2);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/keys/internal.h b/security/keys/internal.h
index db99ed4..e066e60 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -25,7 +25,6 @@
 #define kdebug(FMT, a...)	do {} while(0)
 #endif
 
-extern struct key_type key_type_dead;
 extern struct key_type key_type_user;
 
 /*****************************************************************************/
@@ -108,12 +107,13 @@
 struct request_key_auth {
 	struct key		*target_key;
 	struct task_struct	*context;
+	const char		*callout_info;
 	pid_t			pid;
 };
 
 extern struct key_type key_type_request_key_auth;
 extern struct key *request_key_auth_new(struct key *target,
-					struct key **_rkakey);
+					const char *callout_info);
 
 extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
 
@@ -137,6 +137,8 @@
 				   size_t, key_serial_t);
 extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
 extern long keyctl_set_reqkey_keyring(int);
+extern long keyctl_set_timeout(key_serial_t, unsigned);
+extern long keyctl_assume_authority(key_serial_t);
 
 
 /*
diff --git a/security/keys/key.c b/security/keys/key.c
index 01bcfec..99781b7 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -36,7 +36,7 @@
 DECLARE_RWSEM(key_construction_sem);
 
 /* any key who's type gets unegistered will be re-typed to this */
-struct key_type key_type_dead = {
+static struct key_type key_type_dead = {
 	.name		= "dead",
 };
 
@@ -240,9 +240,9 @@
 /*
  * allocate a key of the specified type
  * - update the user's quota to reflect the existence of the key
- * - called from a key-type operation with key_types_sem read-locked by either
- *   key_create_or_update() or by key_duplicate(); this prevents unregistration
- *   of the key type
+ * - called from a key-type operation with key_types_sem read-locked by
+ *   key_create_or_update()
+ *   - this prevents unregistration of the key type
  * - upon return the key is as yet uninstantiated; the caller needs to either
  *   instantiate the key or discard it before returning
  */
@@ -889,56 +889,6 @@
 
 /*****************************************************************************/
 /*
- * duplicate a key, potentially with a revised description
- * - must be supported by the keytype (keyrings for instance can be duplicated)
- */
-struct key *key_duplicate(struct key *source, const char *desc)
-{
-	struct key *key;
-	int ret;
-
-	key_check(source);
-
-	if (!desc)
-		desc = source->description;
-
-	down_read(&key_types_sem);
-
-	ret = -EINVAL;
-	if (!source->type->duplicate)
-		goto error;
-
-	/* allocate and instantiate a key */
-	key = key_alloc(source->type, desc, current->fsuid, current->fsgid,
-			source->perm, 0);
-	if (IS_ERR(key))
-		goto error_k;
-
-	down_read(&source->sem);
-	ret = key->type->duplicate(key, source);
-	up_read(&source->sem);
-	if (ret < 0)
-		goto error2;
-
-	atomic_inc(&key->user->nikeys);
-	set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
-
- error_k:
-	up_read(&key_types_sem);
- out:
-	return key;
-
- error2:
-	key_put(key);
- error:
-	up_read(&key_types_sem);
-	key = ERR_PTR(ret);
-	goto out;
-
-} /* end key_duplicate() */
-
-/*****************************************************************************/
-/*
  * revoke a key
  */
 void key_revoke(struct key *key)
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index b7a468f..3d2ebae 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -834,6 +834,17 @@
 	if (plen > 32767)
 		goto error;
 
+	/* the appropriate instantiation authorisation key must have been
+	 * assumed before calling this */
+	ret = -EPERM;
+	instkey = current->request_key_auth;
+	if (!instkey)
+		goto error;
+
+	rka = instkey->payload.data;
+	if (rka->target_key->serial != id)
+		goto error;
+
 	/* pull the payload in if one was supplied */
 	payload = NULL;
 
@@ -848,15 +859,6 @@
 			goto error2;
 	}
 
-	/* find the instantiation authorisation key */
-	instkey = key_get_instantiation_authkey(id);
-	if (IS_ERR(instkey)) {
-		ret = PTR_ERR(instkey);
-		goto error2;
-	}
-
-	rka = instkey->payload.data;
-
 	/* find the destination keyring amongst those belonging to the
 	 * requesting task */
 	keyring_ref = NULL;
@@ -865,7 +867,7 @@
 					      KEY_WRITE);
 		if (IS_ERR(keyring_ref)) {
 			ret = PTR_ERR(keyring_ref);
-			goto error3;
+			goto error2;
 		}
 	}
 
@@ -874,11 +876,17 @@
 				       key_ref_to_ptr(keyring_ref), instkey);
 
 	key_ref_put(keyring_ref);
- error3:
-	key_put(instkey);
- error2:
+
+	/* discard the assumed authority if it's just been disabled by
+	 * instantiation of the key */
+	if (ret == 0) {
+		key_put(current->request_key_auth);
+		current->request_key_auth = NULL;
+	}
+
+error2:
 	kfree(payload);
- error:
+error:
 	return ret;
 
 } /* end keyctl_instantiate_key() */
@@ -895,14 +903,16 @@
 	key_ref_t keyring_ref;
 	long ret;
 
-	/* find the instantiation authorisation key */
-	instkey = key_get_instantiation_authkey(id);
-	if (IS_ERR(instkey)) {
-		ret = PTR_ERR(instkey);
+	/* the appropriate instantiation authorisation key must have been
+	 * assumed before calling this */
+	ret = -EPERM;
+	instkey = current->request_key_auth;
+	if (!instkey)
 		goto error;
-	}
 
 	rka = instkey->payload.data;
+	if (rka->target_key->serial != id)
+		goto error;
 
 	/* find the destination keyring if present (which must also be
 	 * writable) */
@@ -911,7 +921,7 @@
 		keyring_ref = lookup_user_key(NULL, ringid, 1, 0, KEY_WRITE);
 		if (IS_ERR(keyring_ref)) {
 			ret = PTR_ERR(keyring_ref);
-			goto error2;
+			goto error;
 		}
 	}
 
@@ -920,9 +930,15 @@
 				  key_ref_to_ptr(keyring_ref), instkey);
 
 	key_ref_put(keyring_ref);
- error2:
-	key_put(instkey);
- error:
+
+	/* discard the assumed authority if it's just been disabled by
+	 * instantiation of the key */
+	if (ret == 0) {
+		key_put(current->request_key_auth);
+		current->request_key_auth = NULL;
+	}
+
+error:
 	return ret;
 
 } /* end keyctl_negate_key() */
@@ -967,6 +983,88 @@
 
 /*****************************************************************************/
 /*
+ * set or clear the timeout for a key
+ */
+long keyctl_set_timeout(key_serial_t id, unsigned timeout)
+{
+	struct timespec now;
+	struct key *key;
+	key_ref_t key_ref;
+	time_t expiry;
+	long ret;
+
+	key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
+	if (IS_ERR(key_ref)) {
+		ret = PTR_ERR(key_ref);
+		goto error;
+	}
+
+	key = key_ref_to_ptr(key_ref);
+
+	/* make the changes with the locks held to prevent races */
+	down_write(&key->sem);
+
+	expiry = 0;
+	if (timeout > 0) {
+		now = current_kernel_time();
+		expiry = now.tv_sec + timeout;
+	}
+
+	key->expiry = expiry;
+
+	up_write(&key->sem);
+	key_put(key);
+
+	ret = 0;
+error:
+	return ret;
+
+} /* end keyctl_set_timeout() */
+
+/*****************************************************************************/
+/*
+ * assume the authority to instantiate the specified key
+ */
+long keyctl_assume_authority(key_serial_t id)
+{
+	struct key *authkey;
+	long ret;
+
+	/* special key IDs aren't permitted */
+	ret = -EINVAL;
+	if (id < 0)
+		goto error;
+
+	/* we divest ourselves of authority if given an ID of 0 */
+	if (id == 0) {
+		key_put(current->request_key_auth);
+		current->request_key_auth = NULL;
+		ret = 0;
+		goto error;
+	}
+
+	/* attempt to assume the authority temporarily granted to us whilst we
+	 * instantiate the specified key
+	 * - the authorisation key must be in the current task's keyrings
+	 *   somewhere
+	 */
+	authkey = key_get_instantiation_authkey(id);
+	if (IS_ERR(authkey)) {
+		ret = PTR_ERR(authkey);
+		goto error;
+	}
+
+	key_put(current->request_key_auth);
+	current->request_key_auth = authkey;
+	ret = authkey->serial;
+
+error:
+	return ret;
+
+} /* end keyctl_assume_authority() */
+
+/*****************************************************************************/
+/*
  * the key control system call
  */
 asmlinkage long sys_keyctl(int option, unsigned long arg2, unsigned long arg3,
@@ -1038,6 +1136,13 @@
 	case KEYCTL_SET_REQKEY_KEYRING:
 		return keyctl_set_reqkey_keyring(arg2);
 
+	case KEYCTL_SET_TIMEOUT:
+		return keyctl_set_timeout((key_serial_t) arg2,
+					  (unsigned) arg3);
+
+	case KEYCTL_ASSUME_AUTHORITY:
+		return keyctl_assume_authority((key_serial_t) arg2);
+
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index c7a0ab1..d65a180 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -48,7 +48,6 @@
  */
 static int keyring_instantiate(struct key *keyring,
 			       const void *data, size_t datalen);
-static int keyring_duplicate(struct key *keyring, const struct key *source);
 static int keyring_match(const struct key *keyring, const void *criterion);
 static void keyring_destroy(struct key *keyring);
 static void keyring_describe(const struct key *keyring, struct seq_file *m);
@@ -59,7 +58,6 @@
 	.name		= "keyring",
 	.def_datalen	= sizeof(struct keyring_list),
 	.instantiate	= keyring_instantiate,
-	.duplicate	= keyring_duplicate,
 	.match		= keyring_match,
 	.destroy	= keyring_destroy,
 	.describe	= keyring_describe,
@@ -70,7 +68,7 @@
  * semaphore to serialise link/link calls to prevent two link calls in parallel
  * introducing a cycle
  */
-DECLARE_RWSEM(keyring_serialise_link_sem);
+static DECLARE_RWSEM(keyring_serialise_link_sem);
 
 /*****************************************************************************/
 /*
@@ -120,68 +118,6 @@
 
 /*****************************************************************************/
 /*
- * duplicate the list of subscribed keys from a source keyring into this one
- */
-static int keyring_duplicate(struct key *keyring, const struct key *source)
-{
-	struct keyring_list *sklist, *klist;
-	unsigned max;
-	size_t size;
-	int loop, ret;
-
-	const unsigned limit =
-		(PAGE_SIZE - sizeof(*klist)) / sizeof(struct key *);
-
-	ret = 0;
-
-	/* find out how many keys are currently linked */
-	rcu_read_lock();
-	sklist = rcu_dereference(source->payload.subscriptions);
-	max = 0;
-	if (sklist)
-		max = sklist->nkeys;
-	rcu_read_unlock();
-
-	/* allocate a new payload and stuff load with key links */
-	if (max > 0) {
-		BUG_ON(max > limit);
-
-		max = (max + 3) & ~3;
-		if (max > limit)
-			max = limit;
-
-		ret = -ENOMEM;
-		size = sizeof(*klist) + sizeof(struct key *) * max;
-		klist = kmalloc(size, GFP_KERNEL);
-		if (!klist)
-			goto error;
-
-		/* set links */
-		rcu_read_lock();
-		sklist = rcu_dereference(source->payload.subscriptions);
-
-		klist->maxkeys = max;
-		klist->nkeys = sklist->nkeys;
-		memcpy(klist->keys,
-		       sklist->keys,
-		       sklist->nkeys * sizeof(struct key *));
-
-		for (loop = klist->nkeys - 1; loop >= 0; loop--)
-			atomic_inc(&klist->keys[loop]->usage);
-
-		rcu_read_unlock();
-
-		rcu_assign_pointer(keyring->payload.subscriptions, klist);
-		ret = 0;
-	}
-
- error:
-	return ret;
-
-} /* end keyring_duplicate() */
-
-/*****************************************************************************/
-/*
  * match keyrings on their name
  */
 static int keyring_match(const struct key *keyring, const void *description)
@@ -526,7 +462,7 @@
 			    (!key->type->match ||
 			     key->type->match(key, description)) &&
 			    key_permission(make_key_ref(key, possessed),
-					   perm) < 0 &&
+					   perm) == 0 &&
 			    !test_bit(KEY_FLAG_REVOKED, &key->flags)
 			    )
 				goto found;
@@ -545,51 +481,6 @@
 
 /*****************************************************************************/
 /*
- * search for an instantiation authorisation key matching a target key
- * - the RCU read lock must be held by the caller
- * - a target_id of zero specifies any valid token
- */
-struct key *keyring_search_instkey(struct key *keyring,
-				   key_serial_t target_id)
-{
-	struct request_key_auth *rka;
-	struct keyring_list *klist;
-	struct key *instkey;
-	int loop;
-
-	klist = rcu_dereference(keyring->payload.subscriptions);
-	if (klist) {
-		for (loop = 0; loop < klist->nkeys; loop++) {
-			instkey = klist->keys[loop];
-
-			if (instkey->type != &key_type_request_key_auth)
-				continue;
-
-			rka = instkey->payload.data;
-			if (target_id && rka->target_key->serial != target_id)
-				continue;
-
-			/* the auth key is revoked during instantiation */
-			if (!test_bit(KEY_FLAG_REVOKED, &instkey->flags))
-				goto found;
-
-			instkey = ERR_PTR(-EKEYREVOKED);
-			goto error;
-		}
-	}
-
-	instkey = ERR_PTR(-EACCES);
-	goto error;
-
-found:
-	atomic_inc(&instkey->usage);
-error:
-	return instkey;
-
-} /* end keyring_search_instkey() */
-
-/*****************************************************************************/
-/*
  * find a keyring with the specified name
  * - all named keyrings are searched
  * - only find keyrings with search permission for the process
@@ -748,15 +639,31 @@
 
 /*****************************************************************************/
 /*
+ * dispose of a keyring list after the RCU grace period, freeing the unlinked
+ * key
+ */
+static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
+{
+	struct keyring_list *klist =
+		container_of(rcu, struct keyring_list, rcu);
+
+	key_put(klist->keys[klist->delkey]);
+	kfree(klist);
+
+} /* end keyring_unlink_rcu_disposal() */
+
+/*****************************************************************************/
+/*
  * link a key into to a keyring
  * - must be called with the keyring's semaphore write-locked
+ * - discard already extant link to matching key if there is one
  */
 int __key_link(struct key *keyring, struct key *key)
 {
 	struct keyring_list *klist, *nklist;
 	unsigned max;
 	size_t size;
-	int ret;
+	int loop, ret;
 
 	ret = -EKEYREVOKED;
 	if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
@@ -778,6 +685,48 @@
 			goto error2;
 	}
 
+	/* see if there's a matching key we can displace */
+	klist = keyring->payload.subscriptions;
+
+	if (klist && klist->nkeys > 0) {
+		struct key_type *type = key->type;
+
+		for (loop = klist->nkeys - 1; loop >= 0; loop--) {
+			if (klist->keys[loop]->type == type &&
+			    strcmp(klist->keys[loop]->description,
+				   key->description) == 0
+			    ) {
+				/* found a match - replace with new key */
+				size = sizeof(struct key *) * klist->maxkeys;
+				size += sizeof(*klist);
+				BUG_ON(size > PAGE_SIZE);
+
+				ret = -ENOMEM;
+				nklist = kmalloc(size, GFP_KERNEL);
+				if (!nklist)
+					goto error2;
+
+				memcpy(nklist, klist, size);
+
+				/* replace matched key */
+				atomic_inc(&key->usage);
+				nklist->keys[loop] = key;
+
+				rcu_assign_pointer(
+					keyring->payload.subscriptions,
+					nklist);
+
+				/* dispose of the old keyring list and the
+				 * displaced key */
+				klist->delkey = loop;
+				call_rcu(&klist->rcu,
+					 keyring_unlink_rcu_disposal);
+
+				goto done;
+			}
+		}
+	}
+
 	/* check that we aren't going to overrun the user's quota */
 	ret = key_payload_reserve(keyring,
 				  keyring->datalen + KEYQUOTA_LINK_BYTES);
@@ -794,8 +743,6 @@
 		smp_wmb();
 		klist->nkeys++;
 		smp_wmb();
-
-		ret = 0;
 	}
 	else {
 		/* grow the key list */
@@ -833,16 +780,16 @@
 		/* dispose of the old keyring list */
 		if (klist)
 			call_rcu(&klist->rcu, keyring_link_rcu_disposal);
-
-		ret = 0;
 	}
 
- error2:
+done:
+	ret = 0;
+error2:
 	up_write(&keyring_serialise_link_sem);
- error:
+error:
 	return ret;
 
- error3:
+error3:
 	/* undo the quota changes */
 	key_payload_reserve(keyring,
 			    keyring->datalen - KEYQUOTA_LINK_BYTES);
@@ -873,21 +820,6 @@
 
 /*****************************************************************************/
 /*
- * dispose of a keyring list after the RCU grace period, freeing the unlinked
- * key
- */
-static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
-{
-	struct keyring_list *klist =
-		container_of(rcu, struct keyring_list, rcu);
-
-	key_put(klist->keys[klist->delkey]);
-	kfree(klist);
-
-} /* end keyring_unlink_rcu_disposal() */
-
-/*****************************************************************************/
-/*
  * unlink the first link to a key from a keyring
  */
 int key_unlink(struct key *keyring, struct key *key)
diff --git a/security/keys/permission.c b/security/keys/permission.c
index e7f579c..3b41f9b 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -73,3 +73,35 @@
 } /* end key_task_permission() */
 
 EXPORT_SYMBOL(key_task_permission);
+
+/*****************************************************************************/
+/*
+ * validate a key
+ */
+int key_validate(struct key *key)
+{
+	struct timespec now;
+	int ret = 0;
+
+	if (key) {
+		/* check it's still accessible */
+		ret = -EKEYREVOKED;
+		if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
+		    test_bit(KEY_FLAG_DEAD, &key->flags))
+			goto error;
+
+		/* check it hasn't expired */
+		ret = 0;
+		if (key->expiry) {
+			now = current_kernel_time();
+			if (now.tv_sec >= key->expiry)
+				ret = -EKEYEXPIRED;
+		}
+	}
+
+ error:
+	return ret;
+
+} /* end key_validate() */
+
+EXPORT_SYMBOL(key_validate);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 566b1cc..74cb79e 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -270,9 +270,14 @@
 int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
 {
 	key_check(tsk->thread_keyring);
+	key_check(tsk->request_key_auth);
 
 	/* no thread keyring yet */
 	tsk->thread_keyring = NULL;
+
+	/* copy the request_key() authorisation for this thread */
+	key_get(tsk->request_key_auth);
+
 	return 0;
 
 } /* end copy_keys() */
@@ -290,11 +295,12 @@
 
 /*****************************************************************************/
 /*
- * dispose of keys upon thread exit
+ * dispose of per-thread keys upon thread exit
  */
 void exit_keys(struct task_struct *tsk)
 {
 	key_put(tsk->thread_keyring);
+	key_put(tsk->request_key_auth);
 
 } /* end exit_keys() */
 
@@ -382,7 +388,7 @@
 				  struct task_struct *context)
 {
 	struct request_key_auth *rka;
-	key_ref_t key_ref, ret, err, instkey_ref;
+	key_ref_t key_ref, ret, err;
 
 	/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
 	 * searchable, but we failed to find a key or we found a negative key;
@@ -461,44 +467,6 @@
 			err = key_ref;
 			break;
 		}
-
-		/* if this process has a session keyring and that has an
-		 * instantiation authorisation key in the bottom level, then we
-		 * also search the keyrings of the process mentioned there */
-		if (context != current)
-			goto no_key;
-
-		rcu_read_lock();
-		instkey_ref = __keyring_search_one(
-			make_key_ref(rcu_dereference(
-					     context->signal->session_keyring),
-				     1),
-			&key_type_request_key_auth, NULL, 0);
-		rcu_read_unlock();
-
-		if (IS_ERR(instkey_ref))
-			goto no_key;
-
-		rka = key_ref_to_ptr(instkey_ref)->payload.data;
-
-		key_ref = search_process_keyrings(type, description, match,
-						  rka->context);
-		key_ref_put(instkey_ref);
-
-		if (!IS_ERR(key_ref))
-			goto found;
-
-		switch (PTR_ERR(key_ref)) {
-		case -EAGAIN: /* no key */
-			if (ret)
-				break;
-		case -ENOKEY: /* negative key */
-			ret = key_ref;
-			break;
-		default:
-			err = key_ref;
-			break;
-		}
 	}
 	/* or search the user-session keyring */
 	else {
@@ -521,8 +489,36 @@
 		}
 	}
 
+	/* if this process has an instantiation authorisation key, then we also
+	 * search the keyrings of the process mentioned there
+	 * - we don't permit access to request_key auth keys via this method
+	 */
+	if (context->request_key_auth &&
+	    context == current &&
+	    type != &key_type_request_key_auth &&
+	    key_validate(context->request_key_auth) == 0
+	    ) {
+		rka = context->request_key_auth->payload.data;
 
-no_key:
+		key_ref = search_process_keyrings(type, description, match,
+						  rka->context);
+
+		if (!IS_ERR(key_ref))
+			goto found;
+
+		switch (PTR_ERR(key_ref)) {
+		case -EAGAIN: /* no key */
+			if (ret)
+				break;
+		case -ENOKEY: /* negative key */
+			ret = key_ref;
+			break;
+		default:
+			err = key_ref;
+			break;
+		}
+	}
+
 	/* no key - decide on the error we're going to go for */
 	key_ref = ret ? ret : err;
 
@@ -628,6 +624,15 @@
 		key = ERR_PTR(-EINVAL);
 		goto error;
 
+	case KEY_SPEC_REQKEY_AUTH_KEY:
+		key = context->request_key_auth;
+		if (!key)
+			goto error;
+
+		atomic_inc(&key->usage);
+		key_ref = make_key_ref(key, 1);
+		break;
+
 	default:
 		key_ref = ERR_PTR(-EINVAL);
 		if (id < 1)
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 5cc4bba..f030a0c 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -29,28 +29,36 @@
 /*****************************************************************************/
 /*
  * request userspace finish the construction of a key
- * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring> <info>"
+ * - execute "/sbin/request-key <op> <key> <uid> <gid> <keyring> <keyring> <keyring>"
  */
-static int call_request_key(struct key *key,
-			    const char *op,
-			    const char *callout_info)
+static int call_sbin_request_key(struct key *key,
+				 struct key *authkey,
+				 const char *op)
 {
 	struct task_struct *tsk = current;
 	key_serial_t prkey, sskey;
-	struct key *session_keyring, *rkakey;
-	char *argv[10], *envp[3], uid_str[12], gid_str[12];
+	struct key *keyring;
+	char *argv[9], *envp[3], uid_str[12], gid_str[12];
 	char key_str[12], keyring_str[3][12];
+	char desc[20];
 	int ret, i;
 
-	kenter("{%d},%s,%s", key->serial, op, callout_info);
+	kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
 
-	/* generate a new session keyring with an auth key in it */
-	session_keyring = request_key_auth_new(key, &rkakey);
-	if (IS_ERR(session_keyring)) {
-		ret = PTR_ERR(session_keyring);
-		goto error;
+	/* allocate a new session keyring */
+	sprintf(desc, "_req.%u", key->serial);
+
+	keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
+	if (IS_ERR(keyring)) {
+		ret = PTR_ERR(keyring);
+		goto error_alloc;
 	}
 
+	/* attach the auth key to the session keyring */
+	ret = __key_link(keyring, authkey);
+	if (ret < 0)
+		goto error_link;
+
 	/* record the UID and GID */
 	sprintf(uid_str, "%d", current->fsuid);
 	sprintf(gid_str, "%d", current->fsgid);
@@ -95,22 +103,19 @@
 	argv[i++] = keyring_str[0];
 	argv[i++] = keyring_str[1];
 	argv[i++] = keyring_str[2];
-	argv[i++] = (char *) callout_info;
 	argv[i] = NULL;
 
 	/* do it */
-	ret = call_usermodehelper_keys(argv[0], argv, envp, session_keyring, 1);
+	ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 1);
 
-	/* dispose of the special keys */
-	key_revoke(rkakey);
-	key_put(rkakey);
-	key_put(session_keyring);
+error_link:
+	key_put(keyring);
 
- error:
+error_alloc:
 	kleave(" = %d", ret);
 	return ret;
 
-} /* end call_request_key() */
+} /* end call_sbin_request_key() */
 
 /*****************************************************************************/
 /*
@@ -122,9 +127,10 @@
 					      const char *description,
 					      const char *callout_info)
 {
+	request_key_actor_t actor;
 	struct key_construction cons;
 	struct timespec now;
-	struct key *key;
+	struct key *key, *authkey;
 	int ret, negated;
 
 	kenter("%s,%s,%s", type->name, description, callout_info);
@@ -143,8 +149,19 @@
 	/* we drop the construction sem here on behalf of the caller */
 	up_write(&key_construction_sem);
 
+	/* allocate an authorisation key */
+	authkey = request_key_auth_new(key, callout_info);
+	if (IS_ERR(authkey)) {
+		ret = PTR_ERR(authkey);
+		authkey = NULL;
+		goto alloc_authkey_failed;
+	}
+
 	/* make the call */
-	ret = call_request_key(key, "create", callout_info);
+	actor = call_sbin_request_key;
+	if (type->request_key)
+		actor = type->request_key;
+	ret = actor(key, authkey, "create");
 	if (ret < 0)
 		goto request_failed;
 
@@ -153,22 +170,29 @@
 	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
 		goto request_failed;
 
+	key_revoke(authkey);
+	key_put(authkey);
+
 	down_write(&key_construction_sem);
 	list_del(&cons.link);
 	up_write(&key_construction_sem);
 
 	/* also give an error if the key was negatively instantiated */
- check_not_negative:
+check_not_negative:
 	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
 		key_put(key);
 		key = ERR_PTR(-ENOKEY);
 	}
 
- out:
+out:
 	kleave(" = %p", key);
 	return key;
 
- request_failed:
+request_failed:
+	key_revoke(authkey);
+	key_put(authkey);
+
+alloc_authkey_failed:
 	/* it wasn't instantiated
 	 * - remove from construction queue
 	 * - mark the key as dead
@@ -217,7 +241,7 @@
 	key = ERR_PTR(ret);
 	goto out;
 
- alloc_failed:
+alloc_failed:
 	up_write(&key_construction_sem);
 	goto out;
 
@@ -464,35 +488,3 @@
 } /* end request_key() */
 
 EXPORT_SYMBOL(request_key);
-
-/*****************************************************************************/
-/*
- * validate a key
- */
-int key_validate(struct key *key)
-{
-	struct timespec now;
-	int ret = 0;
-
-	if (key) {
-		/* check it's still accessible */
-		ret = -EKEYREVOKED;
-		if (test_bit(KEY_FLAG_REVOKED, &key->flags) ||
-		    test_bit(KEY_FLAG_DEAD, &key->flags))
-			goto error;
-
-		/* check it hasn't expired */
-		ret = 0;
-		if (key->expiry) {
-			now = current_kernel_time();
-			if (now.tv_sec >= key->expiry)
-				ret = -EKEYEXPIRED;
-		}
-	}
-
- error:
-	return ret;
-
-} /* end key_validate() */
-
-EXPORT_SYMBOL(key_validate);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index a8e4069..cce6ba6 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -15,11 +15,13 @@
 #include <linux/sched.h>
 #include <linux/err.h>
 #include <linux/seq_file.h>
+#include <asm/uaccess.h>
 #include "internal.h"
 
 static int request_key_auth_instantiate(struct key *, const void *, size_t);
 static void request_key_auth_describe(const struct key *, struct seq_file *);
 static void request_key_auth_destroy(struct key *);
+static long request_key_auth_read(const struct key *, char __user *, size_t);
 
 /*
  * the request-key authorisation key type definition
@@ -30,51 +32,25 @@
 	.instantiate	= request_key_auth_instantiate,
 	.describe	= request_key_auth_describe,
 	.destroy	= request_key_auth_destroy,
+	.read		= request_key_auth_read,
 };
 
 /*****************************************************************************/
 /*
- * instantiate a request-key authorisation record
+ * instantiate a request-key authorisation key
  */
 static int request_key_auth_instantiate(struct key *key,
 					const void *data,
 					size_t datalen)
 {
-	struct request_key_auth *rka, *irka;
-	struct key *instkey;
-	int ret;
-
-	ret = -ENOMEM;
-	rka = kmalloc(sizeof(*rka), GFP_KERNEL);
-	if (rka) {
-		/* see if the calling process is already servicing the key
-		 * request of another process */
-		instkey = key_get_instantiation_authkey(0);
-		if (!IS_ERR(instkey)) {
-			/* it is - use that instantiation context here too */
-			irka = instkey->payload.data;
-			rka->context = irka->context;
-			rka->pid = irka->pid;
-			key_put(instkey);
-		}
-		else {
-			/* it isn't - use this process as the context */
-			rka->context = current;
-			rka->pid = current->pid;
-		}
-
-		rka->target_key = key_get((struct key *) data);
-		key->payload.data = rka;
-		ret = 0;
-	}
-
-	return ret;
+	key->payload.data = (struct request_key_auth *) data;
+	return 0;
 
 } /* end request_key_auth_instantiate() */
 
 /*****************************************************************************/
 /*
- *
+ * reading a request-key authorisation key retrieves the callout information
  */
 static void request_key_auth_describe(const struct key *key,
 				      struct seq_file *m)
@@ -83,12 +59,40 @@
 
 	seq_puts(m, "key:");
 	seq_puts(m, key->description);
-	seq_printf(m, " pid:%d", rka->pid);
+	seq_printf(m, " pid:%d ci:%zu", rka->pid, strlen(rka->callout_info));
 
 } /* end request_key_auth_describe() */
 
 /*****************************************************************************/
 /*
+ * read the callout_info data
+ * - the key's semaphore is read-locked
+ */
+static long request_key_auth_read(const struct key *key,
+				  char __user *buffer, size_t buflen)
+{
+	struct request_key_auth *rka = key->payload.data;
+	size_t datalen;
+	long ret;
+
+	datalen = strlen(rka->callout_info);
+	ret = datalen;
+
+	/* we can return the data as is */
+	if (buffer && buflen > 0) {
+		if (buflen > datalen)
+			buflen = datalen;
+
+		if (copy_to_user(buffer, rka->callout_info, buflen) != 0)
+			ret = -EFAULT;
+	}
+
+	return ret;
+
+} /* end request_key_auth_read() */
+
+/*****************************************************************************/
+/*
  * destroy an instantiation authorisation token key
  */
 static void request_key_auth_destroy(struct key *key)
@@ -104,56 +108,89 @@
 
 /*****************************************************************************/
 /*
- * create a session keyring to be for the invokation of /sbin/request-key and
- * stick an authorisation token in it
+ * create an authorisation token for /sbin/request-key or whoever to gain
+ * access to the caller's security data
  */
-struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
+struct key *request_key_auth_new(struct key *target, const char *callout_info)
 {
-	struct key *keyring, *rkakey = NULL;
+	struct request_key_auth *rka, *irka;
+	struct key *authkey = NULL;
 	char desc[20];
 	int ret;
 
 	kenter("%d,", target->serial);
 
-	/* allocate a new session keyring */
-	sprintf(desc, "_req.%u", target->serial);
-
-	keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
-	if (IS_ERR(keyring)) {
-		kleave("= %ld", PTR_ERR(keyring));
-		return keyring;
+	/* allocate a auth record */
+	rka = kmalloc(sizeof(*rka), GFP_KERNEL);
+	if (!rka) {
+		kleave(" = -ENOMEM");
+		return ERR_PTR(-ENOMEM);
 	}
 
+	/* see if the calling process is already servicing the key request of
+	 * another process */
+	if (current->request_key_auth) {
+		/* it is - use that instantiation context here too */
+		irka = current->request_key_auth->payload.data;
+		rka->context = irka->context;
+		rka->pid = irka->pid;
+	}
+	else {
+		/* it isn't - use this process as the context */
+		rka->context = current;
+		rka->pid = current->pid;
+	}
+
+	rka->target_key = key_get(target);
+	rka->callout_info = callout_info;
+
 	/* allocate the auth key */
 	sprintf(desc, "%x", target->serial);
 
-	rkakey = key_alloc(&key_type_request_key_auth, desc,
-			   current->fsuid, current->fsgid,
-			   KEY_POS_VIEW | KEY_USR_VIEW, 1);
-	if (IS_ERR(rkakey)) {
-		key_put(keyring);
-		kleave("= %ld", PTR_ERR(rkakey));
-		return rkakey;
+	authkey = key_alloc(&key_type_request_key_auth, desc,
+			    current->fsuid, current->fsgid,
+			    KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
+			    KEY_USR_VIEW, 1);
+	if (IS_ERR(authkey)) {
+		ret = PTR_ERR(authkey);
+		goto error_alloc;
 	}
 
 	/* construct and attach to the keyring */
-	ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL);
-	if (ret < 0) {
-		key_revoke(rkakey);
-		key_put(rkakey);
-		key_put(keyring);
-		kleave("= %d", ret);
-		return ERR_PTR(ret);
-	}
+	ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL);
+	if (ret < 0)
+		goto error_inst;
 
-	*_rkakey = rkakey;
-	kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial);
-	return keyring;
+	kleave(" = {%d})", authkey->serial);
+	return authkey;
+
+error_inst:
+	key_revoke(authkey);
+	key_put(authkey);
+error_alloc:
+	key_put(rka->target_key);
+	kfree(rka);
+	kleave("= %d", ret);
+	return ERR_PTR(ret);
 
 } /* end request_key_auth_new() */
 
 /*****************************************************************************/
 /*
+ * see if an authorisation key is associated with a particular key
+ */
+static int key_get_instantiation_authkey_match(const struct key *key,
+					       const void *_id)
+{
+	struct request_key_auth *rka = key->payload.data;
+	key_serial_t id = (key_serial_t)(unsigned long) _id;
+
+	return rka->target_key->serial == id;
+
+} /* end key_get_instantiation_authkey_match() */
+
+/*****************************************************************************/
+/*
  * get the authorisation key for instantiation of a specific key if attached to
  * the current process's keyrings
  * - this key is inserted into a keyring and that is set as /sbin/request-key's
@@ -162,22 +199,27 @@
  */
 struct key *key_get_instantiation_authkey(key_serial_t target_id)
 {
-	struct task_struct *tsk = current;
-	struct key *instkey;
+	struct key *authkey;
+	key_ref_t authkey_ref;
 
-	/* we must have our own personal session keyring */
-	if (!tsk->signal->session_keyring)
-		return ERR_PTR(-EACCES);
+	authkey_ref = search_process_keyrings(
+		&key_type_request_key_auth,
+		(void *) (unsigned long) target_id,
+		key_get_instantiation_authkey_match,
+		current);
 
-	/* and it must contain a suitable request authorisation key
-	 * - lock RCU against session keyring changing
-	 */
-	rcu_read_lock();
+	if (IS_ERR(authkey_ref)) {
+		authkey = ERR_PTR(PTR_ERR(authkey_ref));
+		goto error;
+	}
 
-	instkey = keyring_search_instkey(
-		rcu_dereference(tsk->signal->session_keyring), target_id);
+	authkey = key_ref_to_ptr(authkey_ref);
+	if (test_bit(KEY_FLAG_REVOKED, &authkey->flags)) {
+		key_put(authkey);
+		authkey = ERR_PTR(-EKEYREVOKED);
+	}
 
-	rcu_read_unlock();
-	return instkey;
+error:
+	return authkey;
 
 } /* end key_get_instantiation_authkey() */
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index cbda3b2..8e71895 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -26,7 +26,6 @@
 struct key_type key_type_user = {
 	.name		= "user",
 	.instantiate	= user_instantiate,
-	.duplicate	= user_duplicate,
 	.update		= user_update,
 	.match		= user_match,
 	.destroy	= user_destroy,
@@ -68,42 +67,10 @@
 	return ret;
 
 } /* end user_instantiate() */
-
 EXPORT_SYMBOL_GPL(user_instantiate);
 
 /*****************************************************************************/
 /*
- * duplicate a user defined key
- * - both keys' semaphores are locked against further modification
- * - the new key cannot yet be accessed
- */
-int user_duplicate(struct key *key, const struct key *source)
-{
-	struct user_key_payload *upayload, *spayload;
-	int ret;
-
-	/* just copy the payload */
-	ret = -ENOMEM;
-	upayload = kmalloc(sizeof(*upayload) + source->datalen, GFP_KERNEL);
-	if (upayload) {
-		spayload = rcu_dereference(source->payload.data);
-		BUG_ON(source->datalen != spayload->datalen);
-
-		upayload->datalen = key->datalen = spayload->datalen;
-		memcpy(upayload->data, spayload->data, key->datalen);
-
-		key->payload.data = upayload;
-		ret = 0;
-	}
-
-	return ret;
-
-} /* end user_duplicate() */
-
-EXPORT_SYMBOL_GPL(user_duplicate);
-
-/*****************************************************************************/
-/*
  * dispose of the old data from an updated user defined key
  */
 static void user_update_rcu_disposal(struct rcu_head *rcu)
diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index b038cd0..06d54d9 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -8,5 +8,7 @@
 
 selinux-$(CONFIG_SECURITY_NETWORK) += netif.o
 
+selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
+
 EXTRA_CFLAGS += -Isecurity/selinux/include
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index fc77443..6647204 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -73,6 +73,7 @@
 #include "avc.h"
 #include "objsec.h"
 #include "netif.h"
+#include "xfrm.h"
 
 #define XATTR_SELINUX_SUFFIX "selinux"
 #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
@@ -1662,7 +1663,7 @@
 						continue;
 					}
 					if (devnull) {
-						rcuref_inc(&devnull->f_count);
+						get_file(devnull);
 					} else {
 						devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
 						if (!devnull) {
@@ -3349,6 +3350,10 @@
 		err = avc_has_perm(sock_sid, port_sid,
 				   sock_class, recv_perm, &ad);
 	}
+
+	if (!err)
+		err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
+
 out:	
 	return err;
 }
@@ -3401,6 +3406,24 @@
 	sk_free_security(sk);
 }
 
+static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir)
+{
+	struct inode_security_struct *isec;
+	u32 sock_sid = SECINITSID_ANY_SOCKET;
+
+	if (!sk)
+		return selinux_no_sk_sid(fl);
+
+	read_lock_bh(&sk->sk_callback_lock);
+	isec = get_sock_isec(sk);
+
+	if (isec)
+		sock_sid = isec->sid;
+
+	read_unlock_bh(&sk->sk_callback_lock);
+	return sock_sid;
+}
+
 static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
 {
 	int err = 0;
@@ -3536,6 +3559,11 @@
 		                   send_perm, &ad) ? NF_DROP : NF_ACCEPT;
 	}
 
+	if (err != NF_ACCEPT)
+		goto out;
+
+	err = selinux_xfrm_postroute_last(isec->sid, skb);
+
 out:
 	return err;
 }
@@ -4380,6 +4408,16 @@
 	.socket_getpeersec =		selinux_socket_getpeersec,
 	.sk_alloc_security =		selinux_sk_alloc_security,
 	.sk_free_security =		selinux_sk_free_security,
+	.sk_getsid = 			selinux_sk_getsid_security,
+#endif
+
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+	.xfrm_policy_alloc_security =	selinux_xfrm_policy_alloc,
+	.xfrm_policy_clone_security =	selinux_xfrm_policy_clone,
+	.xfrm_policy_free_security =	selinux_xfrm_policy_free,
+	.xfrm_state_alloc_security =	selinux_xfrm_state_alloc,
+	.xfrm_state_free_security =	selinux_xfrm_state_free,
+	.xfrm_policy_lookup = 		selinux_xfrm_policy_lookup,
 #endif
 };
 
@@ -4491,6 +4529,7 @@
 		panic("SELinux: nf_register_hook for IPv6: error %d\n", err);
 
 #endif	/* IPV6 */
+
 out:
 	return err;
 }
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index 1deb59e..591e98d 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -238,3 +238,4 @@
    S_(SECCLASS_NSCD, NSCD__SHMEMHOST, "shmemhost")
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto")
    S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom")
+   S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index a78b5d5..d7f02ed 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -908,6 +908,7 @@
 
 #define ASSOCIATION__SENDTO                       0x00000001UL
 #define ASSOCIATION__RECVFROM                     0x00000002UL
+#define ASSOCIATION__SETCONTEXT                   0x00000004UL
 
 #define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL      0x00000001UL
 #define NETLINK_KOBJECT_UEVENT_SOCKET__READ       0x00000002UL
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
new file mode 100644
index 0000000..8e87996
--- /dev/null
+++ b/security/selinux/include/xfrm.h
@@ -0,0 +1,54 @@
+/*
+ * SELinux support for the XFRM LSM hooks
+ *
+ * Author : Trent Jaeger, <jaegert@us.ibm.com>
+ */
+#ifndef _SELINUX_XFRM_H_
+#define _SELINUX_XFRM_H_
+
+int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
+int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
+void selinux_xfrm_policy_free(struct xfrm_policy *xp);
+int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
+void selinux_xfrm_state_free(struct xfrm_state *x);
+int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir);
+
+/*
+ * Extract the security blob from the sock (it's actually on the socket)
+ */
+static inline struct inode_security_struct *get_sock_isec(struct sock *sk)
+{
+	if (!sk->sk_socket)
+		return NULL;
+
+	return SOCK_INODE(sk->sk_socket)->i_security;
+}
+
+
+static inline u32 selinux_no_sk_sid(struct flowi *fl)
+{
+	/* NOTE: no sock occurs on ICMP reply, forwards, ... */
+	/* icmp_reply: authorize as kernel packet */
+	if (fl && fl->proto == IPPROTO_ICMP) {
+		return SECINITSID_KERNEL;
+	}
+
+	return SECINITSID_ANY_SOCKET;
+}
+
+#ifdef CONFIG_SECURITY_NETWORK_XFRM
+int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb);
+int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb);
+#else
+static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
+{
+	return 0;
+}
+
+static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
+{
+	return NF_ACCEPT;
+}
+#endif
+
+#endif /* _SELINUX_XFRM_H_ */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 0e1352a..b5fa02d 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -376,7 +376,7 @@
 	char *data;
 	ssize_t rv;
 
-	if (ino >= sizeof(write_op)/sizeof(write_op[0]) || !write_op[ino])
+	if (ino >= ARRAY_SIZE(write_op) || !write_op[ino])
 		return -EINVAL;
 
 	data = simple_transaction_get(file, buf, size);
@@ -889,7 +889,7 @@
 	spin_lock(&dcache_lock);
 	node = de->d_subdirs.next;
 	while (node != &de->d_subdirs) {
-		struct dentry *d = list_entry(node, struct dentry, d_child);
+		struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
 		list_del_init(node);
 
 		if (d->d_inode) {
@@ -1161,7 +1161,7 @@
 #endif
 	};
 
-	for (i = 0; i < sizeof (files) / sizeof (files[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(files); i++) {
 		struct inode *inode;
 		struct dentry *dentry;
 
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index dde094f..d049c7a 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -359,7 +359,7 @@
 			return -1;
 		}
 
-		for (i = 0; i < sizeof(spec_order)/sizeof(u16); i++) {
+		for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
 			if (val & spec_order[i]) {
 				key.specified = spec_order[i] | enabled;
 				datum.data = le32_to_cpu(buf32[items++]);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 0ac311d..0111990 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -103,7 +103,7 @@
 	int i;
 	struct policydb_compat_info *info = NULL;
 
-	for (i = 0; i < sizeof(policydb_compat)/sizeof(*info); i++) {
+	for (i = 0; i < ARRAY_SIZE(policydb_compat); i++) {
 		if (policydb_compat[i].version == version) {
 			info = &policydb_compat[i];
 			break;
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
new file mode 100644
index 0000000..b2af7ca
--- /dev/null
+++ b/security/selinux/xfrm.c
@@ -0,0 +1,305 @@
+/*
+ *  NSA Security-Enhanced Linux (SELinux) security module
+ *
+ *  This file contains the SELinux XFRM hook function implementations.
+ *
+ *  Authors:  Serge Hallyn <sergeh@us.ibm.com>
+ *	      Trent Jaeger <jaegert@us.ibm.com>
+ *
+ *  Copyright (C) 2005 International Business Machines Corporation
+ *
+ *	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.
+ */
+
+/*
+ * USAGE:
+ * NOTES:
+ *   1. Make sure to enable the following options in your kernel config:
+ *	CONFIG_SECURITY=y
+ *	CONFIG_SECURITY_NETWORK=y
+ *	CONFIG_SECURITY_NETWORK_XFRM=y
+ *	CONFIG_SECURITY_SELINUX=m/y
+ * ISSUES:
+ *   1. Caching packets, so they are not dropped during negotiation
+ *   2. Emulating a reasonable SO_PEERSEC across machines
+ *   3. Testing addition of sk_policy's with security context via setsockopt
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/security.h>
+#include <linux/types.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/xfrm.h>
+#include <net/xfrm.h>
+#include <net/checksum.h>
+#include <net/udp.h>
+#include <asm/semaphore.h>
+
+#include "avc.h"
+#include "objsec.h"
+#include "xfrm.h"
+
+
+/*
+ * Returns true if an LSM/SELinux context
+ */
+static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
+{
+	return (ctx &&
+		(ctx->ctx_doi == XFRM_SC_DOI_LSM) &&
+		(ctx->ctx_alg == XFRM_SC_ALG_SELINUX));
+}
+
+/*
+ * Returns true if the xfrm contains a security blob for SELinux
+ */
+static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
+{
+	return selinux_authorizable_ctx(x->security);
+}
+
+/*
+ * LSM hook implementation that authorizes that a socket can be used
+ * with the corresponding xfrm_sec_ctx and direction.
+ */
+int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir)
+{
+	int rc = 0;
+	u32 sel_sid = SECINITSID_UNLABELED;
+	struct xfrm_sec_ctx *ctx;
+
+	/* Context sid is either set to label or ANY_ASSOC */
+	if ((ctx = xp->security)) {
+		if (!selinux_authorizable_ctx(ctx))
+			return -EINVAL;
+
+		sel_sid = ctx->ctx_sid;
+	}
+
+	rc = avc_has_perm(sk_sid, sel_sid, SECCLASS_ASSOCIATION,
+			  ((dir == FLOW_DIR_IN) ? ASSOCIATION__RECVFROM :
+			   ((dir == FLOW_DIR_OUT) ?  ASSOCIATION__SENDTO :
+			    (ASSOCIATION__SENDTO | ASSOCIATION__RECVFROM))),
+			  NULL);
+
+	return rc;
+}
+
+/*
+ * Security blob allocation for xfrm_policy and xfrm_state
+ * CTX does not have a meaningful value on input
+ */
+static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx)
+{
+	int rc = 0;
+	struct task_security_struct *tsec = current->security;
+	struct xfrm_sec_ctx *ctx;
+
+	BUG_ON(!uctx);
+	BUG_ON(uctx->ctx_doi != XFRM_SC_ALG_SELINUX);
+
+	if (uctx->ctx_len >= PAGE_SIZE)
+		return -ENOMEM;
+
+	*ctxp = ctx = kmalloc(sizeof(*ctx) +
+			      uctx->ctx_len,
+			      GFP_KERNEL);
+
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->ctx_doi = uctx->ctx_doi;
+	ctx->ctx_len = uctx->ctx_len;
+	ctx->ctx_alg = uctx->ctx_alg;
+
+	memcpy(ctx->ctx_str,
+	       uctx+1,
+	       ctx->ctx_len);
+	rc = security_context_to_sid(ctx->ctx_str,
+				     ctx->ctx_len,
+				     &ctx->ctx_sid);
+
+	if (rc)
+		goto out;
+
+	/*
+	 * Does the subject have permission to set security or permission to
+	 * do the relabel?
+	 * Must be permitted to relabel from default socket type (process type)
+	 * to specified context
+	 */
+	rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
+			  SECCLASS_ASSOCIATION,
+			  ASSOCIATION__SETCONTEXT, NULL);
+	if (rc)
+		goto out;
+
+	return rc;
+
+out:
+	*ctxp = NULL;
+	kfree(ctx);
+	return rc;
+}
+
+/*
+ * LSM hook implementation that allocs and transfers uctx spec to
+ * xfrm_policy.
+ */
+int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *uctx)
+{
+	int err;
+
+	BUG_ON(!xp);
+
+	err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx);
+	return err;
+}
+
+
+/*
+ * LSM hook implementation that copies security data structure from old to
+ * new for policy cloning.
+ */
+int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
+{
+	struct xfrm_sec_ctx *old_ctx, *new_ctx;
+
+	old_ctx = old->security;
+
+	if (old_ctx) {
+		new_ctx = new->security = kmalloc(sizeof(*new_ctx) +
+						  old_ctx->ctx_len,
+						  GFP_KERNEL);
+
+		if (!new_ctx)
+			return -ENOMEM;
+
+		memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
+		memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
+	}
+	return 0;
+}
+
+/*
+ * LSM hook implementation that frees xfrm_policy security information.
+ */
+void selinux_xfrm_policy_free(struct xfrm_policy *xp)
+{
+	struct xfrm_sec_ctx *ctx = xp->security;
+	if (ctx)
+		kfree(ctx);
+}
+
+/*
+ * LSM hook implementation that allocs and transfers sec_ctx spec to
+ * xfrm_state.
+ */
+int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx)
+{
+	int err;
+
+	BUG_ON(!x);
+
+	err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx);
+	return err;
+}
+
+/*
+ * LSM hook implementation that frees xfrm_state security information.
+ */
+void selinux_xfrm_state_free(struct xfrm_state *x)
+{
+	struct xfrm_sec_ctx *ctx = x->security;
+	if (ctx)
+		kfree(ctx);
+}
+
+/*
+ * LSM hook that controls access to unlabelled packets.  If
+ * a xfrm_state is authorizable (defined by macro) then it was
+ * already authorized by the IPSec process.  If not, then
+ * we need to check for unlabelled access since this may not have
+ * gone thru the IPSec process.
+ */
+int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb)
+{
+	int i, rc = 0;
+	struct sec_path *sp;
+
+	sp = skb->sp;
+
+	if (sp) {
+		/*
+		 * __xfrm_policy_check does not approve unless xfrm_policy_ok
+		 * says that spi's match for policy and the socket.
+		 *
+		 *  Only need to verify the existence of an authorizable sp.
+		 */
+		for (i = 0; i < sp->len; i++) {
+			struct xfrm_state *x = sp->x[i].xvec;
+
+			if (x && selinux_authorizable_xfrm(x))
+				goto accept;
+		}
+	}
+
+	/* check SELinux sock for unlabelled access */
+	rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
+			  ASSOCIATION__RECVFROM, NULL);
+	if (rc)
+		goto drop;
+
+accept:
+	return 0;
+
+drop:
+	return rc;
+}
+
+/*
+ * POSTROUTE_LAST hook's XFRM processing:
+ * If we have no security association, then we need to determine
+ * whether the socket is allowed to send to an unlabelled destination.
+ * If we do have a authorizable security association, then it has already been
+ * checked in xfrm_policy_lookup hook.
+ */
+int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb)
+{
+	struct dst_entry *dst;
+	int rc = 0;
+
+	dst = skb->dst;
+
+	if (dst) {
+		struct dst_entry *dst_test;
+
+		for (dst_test = dst; dst_test != 0;
+		     dst_test = dst_test->child) {
+			struct xfrm_state *x = dst_test->xfrm;
+
+			if (x && selinux_authorizable_xfrm(x))
+				goto accept;
+		}
+	}
+
+	rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
+			  ASSOCIATION__SENDTO, NULL);
+	if (rc)
+		goto drop;
+
+accept:
+	return NF_ACCEPT;
+
+drop:
+	return NF_DROP;
+}
diff --git a/sound/Kconfig b/sound/Kconfig
index d8f1140..b65ee47 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -48,14 +48,6 @@
 
 	  For more information, see <http://www.alsa-project.org/>
 
-config SND_AC97_CODEC
-	tristate
-	select SND_PCM
-	select SND_AC97_BUS
-
-config SND_AC97_BUS
-	tristate
-
 source "sound/core/Kconfig"
 
 source "sound/drivers/Kconfig"
diff --git a/sound/arm/Kconfig b/sound/arm/Kconfig
index 0864a7c..2e4a5e0 100644
--- a/sound/arm/Kconfig
+++ b/sound/arm/Kconfig
@@ -7,7 +7,6 @@
 	tristate "SA11xx UDA1341TS driver (iPaq H3600)"
 	depends on ARCH_SA1100 && SND && L3
 	select SND_PCM
-	select SND_GENERIC_DRIVER
 	help
 	  Say Y here if you have a Compaq iPaq H3x00 handheld computer
 	  and want to use its Philips UDA 1341 audio chip.
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 559ead6..54147c1 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -17,11 +17,11 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/err.h>
+#include <linux/amba/bus.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/sizes.h>
-#include <asm/hardware/amba.h>
 
 #include <sound/driver.h>
 #include <sound/core.h>
@@ -40,7 +40,7 @@
  */
 #undef CONFIG_PM
 
-static void aaci_ac97_select_codec(struct aaci *aaci, ac97_t *ac97)
+static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97)
 {
 	u32 v, maincr = aaci->maincr | MAINCR_SCRA(ac97->num);
 
@@ -65,7 +65,7 @@
  *  SI1TxEn, SI2TxEn and SI12TxEn bits are set in the AACI_MAINCR
  *  register.
  */
-static void aaci_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
 	struct aaci *aaci = ac97->private_data;
 	u32 v;
@@ -97,7 +97,7 @@
 /*
  * Read an AC'97 register.
  */
-static unsigned short aaci_ac97_read(ac97_t *ac97, unsigned short reg)
+static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
 	struct aaci *aaci = ac97->private_data;
 	u32 v;
@@ -284,11 +284,11 @@
  *  (unimplemented)
  */
 static int
-aaci_rule_rate_by_channels(snd_pcm_hw_params_t *p, snd_pcm_hw_rule_t *rule)
+aaci_rule_rate_by_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule)
 {
 	struct aaci *aaci = rule->private;
 	unsigned int rate_mask = SNDRV_PCM_RATE_8000_48000|SNDRV_PCM_RATE_5512;
-	snd_interval_t *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *c = hw_param_interval(p, SNDRV_PCM_HW_PARAM_CHANNELS);
 
 	switch (c->max) {
 	case 6:
@@ -304,7 +304,7 @@
 				 rate_mask);
 }
 
-static snd_pcm_hardware_t aaci_hw_info = {
+static struct snd_pcm_hardware aaci_hw_info = {
 	.info			= SNDRV_PCM_INFO_MMAP |
 				  SNDRV_PCM_INFO_MMAP_VALID |
 				  SNDRV_PCM_INFO_INTERLEAVED |
@@ -330,10 +330,10 @@
 	.periods_max		= PAGE_SIZE / 16,
 };
 
-static int aaci_pcm_open(struct aaci *aaci, snd_pcm_substream_t *substream,
+static int aaci_pcm_open(struct aaci *aaci, struct snd_pcm_substream *substream,
 			 struct aaci_runtime *aacirun)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int ret;
 
 	aacirun->substream = substream;
@@ -375,7 +375,7 @@
 /*
  * Common ALSA stuff
  */
-static int aaci_pcm_close(snd_pcm_substream_t *substream)
+static int aaci_pcm_close(struct snd_pcm_substream *substream)
 {
 	struct aaci *aaci = substream->private_data;
 	struct aaci_runtime *aacirun = substream->runtime->private_data;
@@ -388,7 +388,7 @@
 	return 0;
 }
 
-static int aaci_pcm_hw_free(snd_pcm_substream_t *substream)
+static int aaci_pcm_hw_free(struct snd_pcm_substream *substream)
 {
 	struct aaci_runtime *aacirun = substream->runtime->private_data;
 
@@ -409,9 +409,9 @@
 	return 0;
 }
 
-static int aaci_pcm_hw_params(snd_pcm_substream_t *substream,
+static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
 			      struct aaci_runtime *aacirun,
-			      snd_pcm_hw_params_t *params)
+			      struct snd_pcm_hw_params *params)
 {
 	int err;
 
@@ -434,9 +434,9 @@
 	return err;
 }
 
-static int aaci_pcm_prepare(snd_pcm_substream_t *substream)
+static int aaci_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct aaci_runtime *aacirun = runtime->private_data;
 
 	aacirun->start	= (void *)runtime->dma_area;
@@ -448,16 +448,16 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t aaci_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t aaci_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct aaci_runtime *aacirun = runtime->private_data;
 	ssize_t bytes = aacirun->ptr - aacirun->start;
 
 	return bytes_to_frames(runtime, bytes);
 }
 
-static int aaci_pcm_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *vma)
+static int aaci_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
 {
 	return devdma_mmap(NULL, substream, vma);
 }
@@ -484,7 +484,7 @@
 static unsigned int channel_list[] = { 2, 4, 6 };
 
 static int
-aaci_rule_channels(snd_pcm_hw_params_t *p, snd_pcm_hw_rule_t *rule)
+aaci_rule_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule)
 {
 	struct aaci *aaci = rule->private;
 	unsigned int chan_mask = 1 << 0, slots;
@@ -504,7 +504,7 @@
 				 chan_mask);
 }
 
-static int aaci_pcm_playback_open(snd_pcm_substream_t *substream)
+static int aaci_pcm_playback_open(struct snd_pcm_substream *substream)
 {
 	struct aaci *aaci = substream->private_data;
 	int ret;
@@ -522,8 +522,8 @@
 	return aaci_pcm_open(aaci, substream, &aaci->playback);
 }
 
-static int aaci_pcm_playback_hw_params(snd_pcm_substream_t *substream,
-				       snd_pcm_hw_params_t *params)
+static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
+				       struct snd_pcm_hw_params *params)
 {
 	struct aaci *aaci = substream->private_data;
 	struct aaci_runtime *aacirun = substream->runtime->private_data;
@@ -575,7 +575,7 @@
 	writel(aacirun->cr, aacirun->base + AACI_TXCR);
 }
 
-static int aaci_pcm_playback_trigger(snd_pcm_substream_t *substream, int cmd)
+static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct aaci *aaci = substream->private_data;
 	struct aaci_runtime *aacirun = substream->runtime->private_data;
@@ -614,7 +614,7 @@
 	return ret;
 }
 
-static snd_pcm_ops_t aaci_playback_ops = {
+static struct snd_pcm_ops aaci_playback_ops = {
 	.open		= aaci_pcm_playback_open,
 	.close		= aaci_pcm_close,
 	.ioctl		= snd_pcm_lib_ioctl,
@@ -632,34 +632,29 @@
  * Power Management.
  */
 #ifdef CONFIG_PM
-static int aaci_do_suspend(snd_card_t *card, unsigned int state)
+static int aaci_do_suspend(struct snd_card *card, unsigned int state)
 {
 	struct aaci *aaci = card->private_data;
-	if (aaci->card->power_state != SNDRV_CTL_POWER_D3cold) {
-		snd_pcm_suspend_all(aaci->pcm);
-		snd_power_change_state(aaci->card, SNDRV_CTL_POWER_D3cold);
-	}
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
+	snd_pcm_suspend_all(aaci->pcm);
 	return 0;
 }
 
-static int aaci_do_resume(snd_card_t *card, unsigned int state)
+static int aaci_do_resume(struct snd_card *card, unsigned int state)
 {
-	struct aaci *aaci = card->private_data;
-	if (aaci->card->power_state != SNDRV_CTL_POWER_D0) {
-		snd_power_change_state(aaci->card, SNDRV_CTL_POWER_D0);
-	}
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 
 static int aaci_suspend(struct amba_device *dev, pm_message_t state)
 {
-	snd_card_t *card = amba_get_drvdata(dev);
+	struct snd_card *card = amba_get_drvdata(dev);
 	return card ? aaci_do_suspend(card) : 0;
 }
 
 static int aaci_resume(struct amba_device *dev)
 {
-	snd_card_t *card = amba_get_drvdata(dev);
+	struct snd_card *card = amba_get_drvdata(dev);
 	return card ? aaci_do_resume(card) : 0;
 }
 #else
@@ -705,16 +700,16 @@
 	}
 };
 
-static ac97_bus_ops_t aaci_bus_ops = {
+static struct snd_ac97_bus_ops aaci_bus_ops = {
 	.write	= aaci_ac97_write,
 	.read	= aaci_ac97_read,
 };
 
 static int __devinit aaci_probe_ac97(struct aaci *aaci)
 {
-	ac97_template_t ac97_template;
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97;
+	struct snd_ac97_template ac97_template;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97;
 	int ret;
 
 	/*
@@ -737,7 +732,7 @@
 	ac97_bus->clock = 48000;
 	aaci->ac97_bus = ac97_bus;
 
-	memset(&ac97_template, 0, sizeof(ac97_template_t));
+	memset(&ac97_template, 0, sizeof(struct snd_ac97_template));
 	ac97_template.private_data = aaci;
 	ac97_template.num = 0;
 	ac97_template.scaps = AC97_SCAP_SKIP_MODEM;
@@ -762,7 +757,7 @@
 	return ret;
 }
 
-static void aaci_free_card(snd_card_t *card)
+static void aaci_free_card(struct snd_card *card)
 {
 	struct aaci *aaci = card->private_data;
 	if (aaci->base)
@@ -772,7 +767,7 @@
 static struct aaci * __devinit aaci_init_card(struct amba_device *dev)
 {
 	struct aaci *aaci;
-	snd_card_t *card;
+	struct snd_card *card;
 
 	card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
 			    THIS_MODULE, sizeof(struct aaci));
@@ -780,7 +775,6 @@
 		return ERR_PTR(-ENOMEM);
 
 	card->private_free = aaci_free_card;
-	snd_card_set_pm_callback(card, aaci_do_suspend, aaci_do_resume, NULL);
 
 	strlcpy(card->driver, DRIVER_NAME, sizeof(card->driver));
 	strlcpy(card->shortname, "ARM AC'97 Interface", sizeof(card->shortname));
@@ -803,7 +797,7 @@
 
 static int __devinit aaci_init_pcm(struct aaci *aaci)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int ret;
 
 	ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 0, &pcm);
@@ -920,7 +914,7 @@
 
 static int __devexit aaci_remove(struct amba_device *dev)
 {
-	snd_card_t *card = amba_get_drvdata(dev);
+	struct snd_card *card = amba_get_drvdata(dev);
 
 	amba_set_drvdata(dev, NULL);
 
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h
index b2f969b..83f73c2 100644
--- a/sound/arm/aaci.h
+++ b/sound/arm/aaci.h
@@ -207,7 +207,7 @@
 	int			pcm_open;
 
 	u32			cr;
-	snd_pcm_substream_t	*substream;
+	struct snd_pcm_substream	*substream;
 
 	/*
 	 * PIO support
@@ -222,7 +222,7 @@
 
 struct aaci {
 	struct amba_device	*dev;
-	snd_card_t		*card;
+	struct snd_card		*card;
 	void			__iomem *base;
 	unsigned int		fifosize;
 
@@ -236,7 +236,7 @@
 	struct aaci_runtime	playback;
 	struct aaci_runtime	capture;
 
-	snd_pcm_t		*pcm;
+	struct snd_pcm		*pcm;
 };
 
 #define ACSTREAM_FRONT		0
diff --git a/sound/arm/devdma.c b/sound/arm/devdma.c
index 60826a5..ca3bf4e 100644
--- a/sound/arm/devdma.c
+++ b/sound/arm/devdma.c
@@ -18,9 +18,9 @@
 
 #include "devdma.h"
 
-void devdma_hw_free(struct device *dev, snd_pcm_substream_t *substream)
+void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_dma_buffer *buf = runtime->dma_buffer_p;
 
 	if (runtime->dma_area == NULL)
@@ -34,9 +34,9 @@
 	snd_pcm_set_runtime_buffer(substream, NULL);
 }
 
-int devdma_hw_alloc(struct device *dev, snd_pcm_substream_t *substream, size_t size)
+int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_dma_buffer *buf = runtime->dma_buffer_p;
 	int ret = 0;
 
@@ -74,8 +74,8 @@
 	return -ENOMEM;
 }
 
-int devdma_mmap(struct device *dev, snd_pcm_substream_t *substream, struct vm_area_struct *vma)
+int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	return dma_mmap_coherent(dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
 }
diff --git a/sound/arm/devdma.h b/sound/arm/devdma.h
index 5a33b6b..d025329 100644
--- a/sound/arm/devdma.h
+++ b/sound/arm/devdma.h
@@ -1,3 +1,3 @@
-void devdma_hw_free(struct device *dev, snd_pcm_substream_t *substream);
-int devdma_hw_alloc(struct device *dev, snd_pcm_substream_t *substream, size_t size);
-int devdma_mmap(struct device *dev, snd_pcm_substream_t *substream, struct vm_area_struct *vma);
+void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream);
+int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size);
+int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma);
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index c96c8a2..3acbc60 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -37,69 +37,74 @@
 static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
 static volatile long gsr_bits;
 
-static unsigned short pxa2xx_ac97_read(ac97_t *ac97, unsigned short reg)
+/*
+ * Beware PXA27x bugs:
+ *
+ *   o Slot 12 read from modem space will hang controller.
+ *   o CDONE, SDONE interrupt fails after any slot 12 IO.
+ *
+ * We therefore have an hybrid approach for waiting on SDONE (interrupt or
+ * 1 jiffy timeout if interrupt never comes).
+ */ 
+
+static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
 	unsigned short val = -1;
 	volatile u32 *reg_addr;
 
 	down(&car_mutex);
-	if (CAR & CAR_CAIP) {
-		printk(KERN_CRIT"%s: CAR_CAIP already set\n", __FUNCTION__);
-		goto out;
-	}
 
 	/* set up primary or secondary codec space */
 	reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
 	reg_addr += (reg >> 1);
 
 	/* start read access across the ac97 link */
+	GSR = GSR_CDONE | GSR_SDONE;
 	gsr_bits = 0;
 	val = *reg_addr;
 	if (reg == AC97_GPIO_STATUS)
 		goto out;
-	wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1);
-	if (!gsr_bits & GSR_SDONE) {
+	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
+	    !((GSR | gsr_bits) & GSR_SDONE)) {
 		printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
-				__FUNCTION__, reg, gsr_bits);
+				__FUNCTION__, reg, GSR | gsr_bits);
 		val = -1;
 		goto out;
 	}
 
 	/* valid data now */
+	GSR = GSR_CDONE | GSR_SDONE;
 	gsr_bits = 0;
 	val = *reg_addr;			
 	/* but we've just started another cycle... */
-	wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1);
+	wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);
 
 out:	up(&car_mutex);
 	return val;
 }
 
-static void pxa2xx_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
 	volatile u32 *reg_addr;
 
 	down(&car_mutex);
 
-	if (CAR & CAR_CAIP) {
-		printk(KERN_CRIT "%s: CAR_CAIP already set\n", __FUNCTION__);
-		goto out;
-	}
-
 	/* set up primary or secondary codec space */
 	reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
 	reg_addr += (reg >> 1);
+
+	GSR = GSR_CDONE | GSR_SDONE;
 	gsr_bits = 0;
 	*reg_addr = val;
-	wait_event_timeout(gsr_wq, gsr_bits & GSR_CDONE, 1);
-	if (!gsr_bits & GSR_SDONE)
+	if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
+	    !((GSR | gsr_bits) & GSR_CDONE))
 		printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
-				__FUNCTION__, reg, gsr_bits);
+				__FUNCTION__, reg, GSR | gsr_bits);
 
-out:	up(&car_mutex);
+	up(&car_mutex);
 }
 
-static void pxa2xx_ac97_reset(ac97_t *ac97)
+static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)
 {
 	/* First, try cold reset */
 	GCR &=  GCR_COLD_RST;  /* clear everything but nCRST */
@@ -172,13 +177,13 @@
 	return IRQ_NONE;
 }
 
-static ac97_bus_ops_t pxa2xx_ac97_ops = {
+static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
 	.read	= pxa2xx_ac97_read,
 	.write	= pxa2xx_ac97_write,
 	.reset	= pxa2xx_ac97_reset,
 };
 
-static pxa2xx_pcm_dma_params_t pxa2xx_ac97_pcm_out = {
+static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
 	.name			= "AC97 PCM out",
 	.dev_addr		= __PREG(PCDR),
 	.drcmr			= &DRCMRTXPCDR,
@@ -186,7 +191,7 @@
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
 
-static pxa2xx_pcm_dma_params_t pxa2xx_ac97_pcm_in = {
+static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = {
 	.name			= "AC97 PCM in",
 	.dev_addr		= __PREG(PCDR),
 	.drcmr			= &DRCMRRXPCDR,
@@ -194,12 +199,12 @@
 				  DCMD_BURST32 | DCMD_WIDTH4,
 };
 
-static snd_pcm_t *pxa2xx_ac97_pcm;
-static ac97_t *pxa2xx_ac97_ac97;
+static struct snd_pcm *pxa2xx_ac97_pcm;
+static struct snd_ac97 *pxa2xx_ac97_ac97;
 
-static int pxa2xx_ac97_pcm_startup(snd_pcm_substream_t *substream)
+static int pxa2xx_ac97_pcm_startup(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	pxa2xx_audio_ops_t *platform_ops;
 	int r;
 
@@ -218,7 +223,7 @@
 		return 0;
 }
 
-static void pxa2xx_ac97_pcm_shutdown(snd_pcm_substream_t *substream)
+static void pxa2xx_ac97_pcm_shutdown(struct snd_pcm_substream *substream)
 {
 	pxa2xx_audio_ops_t *platform_ops;
 
@@ -227,15 +232,15 @@
 		platform_ops->shutdown(substream, platform_ops->priv);
 }
 
-static int pxa2xx_ac97_pcm_prepare(snd_pcm_substream_t *substream)
+static int pxa2xx_ac97_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int reg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
 		  AC97_PCM_FRONT_DAC_RATE : AC97_PCM_LR_ADC_RATE;
 	return snd_ac97_set_rate(pxa2xx_ac97_ac97, reg, runtime->rate);
 }
 
-static pxa2xx_pcm_client_t pxa2xx_ac97_pcm_client = {
+static struct pxa2xx_pcm_client pxa2xx_ac97_pcm_client = {
 	.playback_params	= &pxa2xx_ac97_pcm_out,
 	.capture_params		= &pxa2xx_ac97_pcm_in,
 	.startup		= pxa2xx_ac97_pcm_startup,
@@ -245,39 +250,37 @@
 
 #ifdef CONFIG_PM
 
-static int pxa2xx_ac97_do_suspend(snd_card_t *card, pm_message_t state)
+static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state)
 {
-	if (card->power_state != SNDRV_CTL_POWER_D3cold) {
-		pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
-		snd_pcm_suspend_all(pxa2xx_ac97_pcm);
-		snd_ac97_suspend(pxa2xx_ac97_ac97);
-		snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
-		if (platform_ops && platform_ops->suspend)
-			platform_ops->suspend(platform_ops->priv);
-		GCR |= GCR_ACLINK_OFF;
-		pxa_set_cken(CKEN2_AC97, 0);
-	}
+	pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
+	snd_pcm_suspend_all(pxa2xx_ac97_pcm);
+	snd_ac97_suspend(pxa2xx_ac97_ac97);
+	if (platform_ops && platform_ops->suspend)
+		platform_ops->suspend(platform_ops->priv);
+	GCR |= GCR_ACLINK_OFF;
+	pxa_set_cken(CKEN2_AC97, 0);
 
 	return 0;
 }
 
-static int pxa2xx_ac97_do_resume(snd_card_t *card)
+static int pxa2xx_ac97_do_resume(struct snd_card *card)
 {
-	if (card->power_state != SNDRV_CTL_POWER_D0) {
-		pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
-		pxa_set_cken(CKEN2_AC97, 1);
-		if (platform_ops && platform_ops->resume)
-			platform_ops->resume(platform_ops->priv);
-		snd_ac97_resume(pxa2xx_ac97_ac97);
-		snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-	}
+	pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
+
+	pxa_set_cken(CKEN2_AC97, 1);
+	if (platform_ops && platform_ops->resume)
+		platform_ops->resume(platform_ops->priv);
+	snd_ac97_resume(pxa2xx_ac97_ac97);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 
 	return 0;
 }
 
 static int pxa2xx_ac97_suspend(struct platform_device *dev, pm_message_t state)
 {
-	snd_card_t *card = platform_get_drvdata(dev);
+	struct snd_card *card = platform_get_drvdata(dev);
 	int ret = 0;
 
 	if (card)
@@ -288,7 +291,7 @@
 
 static int pxa2xx_ac97_resume(struct platform_device *dev)
 {
-	snd_card_t *card = platform_get_drvdata(dev);
+	struct snd_card *card = platform_get_drvdata(dev);
 	int ret = 0;
 
 	if (card)
@@ -304,9 +307,9 @@
 
 static int pxa2xx_ac97_probe(struct platform_device *dev)
 {
-	snd_card_t *card;
-	ac97_bus_t *ac97_bus;
-	ac97_template_t ac97_template;
+	struct snd_card *card;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97_template ac97_template;
 	int ret;
 
 	ret = -ENOMEM;
@@ -349,8 +352,6 @@
 	snprintf(card->longname, sizeof(card->longname),
 		 "%s (%s)", dev->dev.driver->name, card->mixername);
 
-	snd_card_set_pm_callback(card, pxa2xx_ac97_do_suspend,
-				 pxa2xx_ac97_do_resume, NULL);
 	ret = snd_card_register(card);
 	if (ret == 0) {
 		platform_set_drvdata(dev, card);
@@ -370,7 +371,7 @@
 
 static int pxa2xx_ac97_remove(struct platform_device *dev)
 {
-	snd_card_t *card = platform_get_drvdata(dev);
+	struct snd_card *card = platform_get_drvdata(dev);
 
 	if (card) {
 		snd_card_free(card);
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c
index b1eb53b..4938ef1 100644
--- a/sound/arm/pxa2xx-pcm.c
+++ b/sound/arm/pxa2xx-pcm.c
@@ -28,7 +28,7 @@
 #include "pxa2xx-pcm.h"
 
 
-static const snd_pcm_hardware_t pxa2xx_pcm_hardware = {
+static const struct snd_pcm_hardware pxa2xx_pcm_hardware = {
 	.info			= SNDRV_PCM_INFO_MMAP |
 				  SNDRV_PCM_INFO_MMAP_VALID |
 				  SNDRV_PCM_INFO_INTERLEAVED |
@@ -44,15 +44,15 @@
 
 struct pxa2xx_runtime_data {
 	int dma_ch;
-	pxa2xx_pcm_dma_params_t *params;
+	struct pxa2xx_pcm_dma_params *params;
 	pxa_dma_desc *dma_desc_array;
 	dma_addr_t dma_desc_array_phys;
 };
 
-static int pxa2xx_pcm_hw_params(snd_pcm_substream_t *substream,
-				snd_pcm_hw_params_t *params)
+static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct pxa2xx_runtime_data *rtd = runtime->private_data;
 	size_t totsize = params_buffer_bytes(params);
 	size_t period = params_period_bytes(params);
@@ -86,7 +86,7 @@
 	return 0;
 }
 
-static int pxa2xx_pcm_hw_free(snd_pcm_substream_t *substream)
+static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
 {
 	struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
 
@@ -95,10 +95,10 @@
 	return 0;
 }
 
-static int pxa2xx_pcm_prepare(snd_pcm_substream_t *substream)
+static int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	pxa2xx_pcm_client_t *client = substream->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct pxa2xx_pcm_client *client = substream->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct pxa2xx_runtime_data *rtd = runtime->private_data;
 
 	DCSR(rtd->dma_ch) &= ~DCSR_RUN;
@@ -109,7 +109,7 @@
 	return client->prepare(substream);
 }
 
-static int pxa2xx_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
 	int ret = 0;
@@ -139,7 +139,7 @@
 
 static void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id, struct pt_regs *regs)
 {
-	snd_pcm_substream_t *substream = dev_id;
+	struct snd_pcm_substream *substream = dev_id;
 	struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
 	int dcsr;
 
@@ -155,9 +155,9 @@
 	}
 }
 
-static snd_pcm_uframes_t pxa2xx_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct pxa2xx_runtime_data *rtd = runtime->private_data;
 	dma_addr_t ptr = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
 			 DSADR(rtd->dma_ch) : DTADR(rtd->dma_ch);
@@ -168,9 +168,9 @@
 }
 
 static int
-pxa2xx_pcm_hw_rule_mult32(snd_pcm_hw_params_t *params, snd_pcm_hw_rule_t *rule)
+pxa2xx_pcm_hw_rule_mult32(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t *i = hw_param_interval(params, rule->var);
+	struct snd_interval *i = hw_param_interval(params, rule->var);
 	int changed = 0;
 
 	if (i->min & 31) {
@@ -188,10 +188,10 @@
 	return changed;
 }
 
-static int pxa2xx_pcm_open(snd_pcm_substream_t *substream)
+static int pxa2xx_pcm_open(struct snd_pcm_substream *substream)
 {
-	pxa2xx_pcm_client_t *client = substream->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct pxa2xx_pcm_client *client = substream->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct pxa2xx_runtime_data *rtd;
 	int ret;
 
@@ -246,9 +246,9 @@
 	return ret;
 }
 
-static int pxa2xx_pcm_close(snd_pcm_substream_t *substream)
+static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
 {
-	pxa2xx_pcm_client_t *client = substream->private_data;
+	struct pxa2xx_pcm_client *client = substream->private_data;
 	struct pxa2xx_runtime_data *rtd = substream->runtime->private_data;
 
 	pxa_free_dma(rtd->dma_ch);
@@ -260,16 +260,16 @@
 }
 
 static int
-pxa2xx_pcm_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *vma)
+pxa2xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	return dma_mmap_writecombine(substream->pcm->card->dev, vma,
 				     runtime->dma_area,
 				     runtime->dma_addr,
 				     runtime->dma_bytes);
 }
 
-static snd_pcm_ops_t pxa2xx_pcm_ops = {
+static struct snd_pcm_ops pxa2xx_pcm_ops = {
 	.open		= pxa2xx_pcm_open,
 	.close		= pxa2xx_pcm_close,
 	.ioctl		= snd_pcm_lib_ioctl,
@@ -281,9 +281,9 @@
 	.mmap		= pxa2xx_pcm_mmap,
 };
 
-static int pxa2xx_pcm_preallocate_dma_buffer(snd_pcm_t *pcm, int stream)
+static int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
 {
-	snd_pcm_substream_t *substream = pcm->streams[stream].substream;
+	struct snd_pcm_substream *substream = pcm->streams[stream].substream;
 	struct snd_dma_buffer *buf = &substream->dma_buffer;
 	size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
 	buf->dev.type = SNDRV_DMA_TYPE_DEV;
@@ -297,9 +297,9 @@
 	return 0;
 }
 
-static void pxa2xx_pcm_free_dma_buffers(snd_pcm_t *pcm)
+static void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	struct snd_dma_buffer *buf;
 	int stream;
 
@@ -318,9 +318,10 @@
 
 static u64 pxa2xx_pcm_dmamask = 0xffffffff;
 
-int pxa2xx_pcm_new(snd_card_t *card, pxa2xx_pcm_client_t *client, snd_pcm_t **rpcm)
+int pxa2xx_pcm_new(struct snd_card *card, struct pxa2xx_pcm_client *client,
+		   struct snd_pcm **rpcm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int play = client->playback_params ? 1 : 0;
 	int capt = client->capture_params ? 1 : 0;
 	int ret;
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
index 4351759..b79f1e8 100644
--- a/sound/arm/pxa2xx-pcm.h
+++ b/sound/arm/pxa2xx-pcm.h
@@ -10,20 +10,20 @@
  * published by the Free Software Foundation.
  */
 
-typedef struct {
+struct pxa2xx_pcm_dma_params {
 	char *name;			/* stream identifier */
 	u32 dcmd;			/* DMA descriptor dcmd field */
 	volatile u32 *drcmr;		/* the DMA request channel to use */
 	u32 dev_addr;			/* device physical address for DMA */
-} pxa2xx_pcm_dma_params_t;
+};
 	
-typedef struct {
-	pxa2xx_pcm_dma_params_t *playback_params;
-	pxa2xx_pcm_dma_params_t *capture_params;
-	int (*startup)(snd_pcm_substream_t *);
-	void (*shutdown)(snd_pcm_substream_t *);
-	int (*prepare)(snd_pcm_substream_t *);
-} pxa2xx_pcm_client_t;
+struct pxa2xx_pcm_client {
+	struct pxa2xx_pcm_dma_params *playback_params;
+	struct pxa2xx_pcm_dma_params *capture_params;
+	int (*startup)(struct snd_pcm_substream *);
+	void (*shutdown)(struct snd_pcm_substream *);
+	int (*prepare)(struct snd_pcm_substream *);
+};
 
-extern int pxa2xx_pcm_new(snd_card_t *, pxa2xx_pcm_client_t *, snd_pcm_t **);
+extern int pxa2xx_pcm_new(struct snd_card *, struct pxa2xx_pcm_client *, struct snd_pcm **);
 
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
index 6ee9122..13057d9 100644
--- a/sound/arm/sa11xx-uda1341.c
+++ b/sound/arm/sa11xx-uda1341.c
@@ -21,7 +21,7 @@
  *                              merged HAL layer (patches from Brian)
  */
 
-/* $Id: sa11xx-uda1341.c,v 1.23 2005/09/09 13:22:34 tiwai Exp $ */
+/* $Id: sa11xx-uda1341.c,v 1.27 2005/12/07 09:13:42 cladisch Exp $ */
 
 /***************************************************************************************************
 *
@@ -64,6 +64,8 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/errno.h>
 #include <linux/ioctl.h>
 #include <linux/delay.h>
@@ -115,7 +117,7 @@
 module_param(id, charp, 0444);
 MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UDA1341TS soundcard.");
 
-typedef struct audio_stream {
+struct audio_stream {
 	char *id;		/* identification string */
 	int stream_id;		/* numeric identification */	
 	dma_device_t dma_dev;	/* device identifier for DMA */
@@ -130,18 +132,16 @@
 	int tx_spin;		/* are we recoding - flag used to do DMA trans. for sync */
 	unsigned int old_offset;
 	spinlock_t dma_lock;	/* for locking in DMA operations (see dma-sa1100.c in the kernel) */
-	snd_pcm_substream_t *stream;
-}audio_stream_t;
+	struct snd_pcm_substream *stream;
+};
 
-typedef struct snd_card_sa11xx_uda1341 {
-	snd_card_t *card;
+struct sa11xx_uda1341 {
+	struct snd_card *card;
 	struct l3_client *uda1341;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	long samplerate;
-	audio_stream_t s[2];	/* playback & capture */
-} sa11xx_uda1341_t;
-
-static struct snd_card_sa11xx_uda1341 *sa11xx_uda1341 = NULL;
+	struct audio_stream s[2];	/* playback & capture */
+};
 
 static unsigned int rates[] = {
 	8000,  10666, 10985, 14647,
@@ -149,12 +149,14 @@
 	29400, 32000, 44100, 48000,
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 	.count	= ARRAY_SIZE(rates),
 	.list	= rates,
 	.mask	= 0,
 };
 
+static struct platform_device *device;
+
 /* }}} */
 
 /* {{{ Clock and sample rate stuff */
@@ -195,7 +197,7 @@
 	}
 }
 
-static void sa11xx_uda1341_set_samplerate(sa11xx_uda1341_t *sa11xx_uda1341, long rate)
+static void sa11xx_uda1341_set_samplerate(struct sa11xx_uda1341 *sa11xx_uda1341, long rate)
 {
 	int clk_div = 0;
 	int clk=0;
@@ -280,7 +282,7 @@
 
 /* {{{ HW init and shutdown */
 
-static void sa11xx_uda1341_audio_init(sa11xx_uda1341_t *sa11xx_uda1341)
+static void sa11xx_uda1341_audio_init(struct sa11xx_uda1341 *sa11xx_uda1341)
 {
 	unsigned long flags;
 
@@ -337,7 +339,7 @@
 #endif     
 }
 
-static void sa11xx_uda1341_audio_shutdown(sa11xx_uda1341_t *sa11xx_uda1341)
+static void sa11xx_uda1341_audio_shutdown(struct sa11xx_uda1341 *sa11xx_uda1341)
 {
 	/* mute on */
 #ifdef CONFIG_H3600_HAL
@@ -378,7 +380,7 @@
 
 #ifdef HH_VERSION
 
-static int audio_dma_request(audio_stream_t *s, void (*callback)(void *, int))
+static int audio_dma_request(struct audio_stream *s, void (*callback)(void *, int))
 {
 	int ret;
 
@@ -391,7 +393,7 @@
 	return 0;
 }
 
-static inline void audio_dma_free(audio_stream_t *s)
+static inline void audio_dma_free(struct audio_stream *s)
 {
 	sa1100_free_dma(s->dmach);
 	s->dmach = -1;
@@ -399,7 +401,7 @@
 
 #else
 
-static int audio_dma_request(audio_stream_t *s, void (*callback)(void *))
+static int audio_dma_request(struct audio_stream *s, void (*callback)(void *))
 {
 	int ret;
 
@@ -409,18 +411,18 @@
 	return ret;
 }
 
-static void audio_dma_free(audio_stream_t *s)
+static void audio_dma_free(struct audio_stream *s)
 {
-	sa1100_free_dma((s)->dma_regs);
-	(s)->dma_regs = 0;
+	sa1100_free_dma(s->dma_regs);
+	s->dma_regs = 0;
 }
 
 #endif
 
-static u_int audio_get_dma_pos(audio_stream_t *s)
+static u_int audio_get_dma_pos(struct audio_stream *s)
 {
-	snd_pcm_substream_t * substream = s->stream;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_substream *substream = s->stream;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int offset;
 	unsigned long flags;
 	dma_addr_t addr;
@@ -445,7 +447,7 @@
 /*
  * this stops the dma and clears the dma ptrs
  */
-static void audio_stop_dma(audio_stream_t *s)
+static void audio_stop_dma(struct audio_stream *s)
 {
 	unsigned long flags;
 
@@ -461,10 +463,10 @@
 	spin_unlock_irqrestore(&s->dma_lock, flags);
 }
 
-static void audio_process_dma(audio_stream_t *s)
+static void audio_process_dma(struct audio_stream *s)
 {
-	snd_pcm_substream_t *substream = s->stream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream = s->stream;
+	struct snd_pcm_runtime *runtime;
 	unsigned int dma_size;		
 	unsigned int offset;
 	int ret;
@@ -527,7 +529,7 @@
 static void audio_dma_callback(void *data)
 #endif
 {
-	audio_stream_t *s = data;
+	struct audio_stream *s = data;
         
 	/* 
 	 * If we are getting a callback for an active stream then we inform
@@ -549,12 +551,12 @@
 
 /* {{{ trigger & timer */
 
-static int snd_sa11xx_uda1341_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_sa11xx_uda1341_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream);
+	struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
 	int stream_id = substream->pstr->stream;
-	audio_stream_t *s = &chip->s[stream_id];
-	audio_stream_t *s1 = &chip->s[stream_id ^ 1];
+	struct audio_stream *s = &chip->s[stream_id];
+	struct audio_stream *s1 = &chip->s[stream_id ^ 1];
 	int err = 0;
 
 	/* note local interrupts are already disabled in the midlevel code */
@@ -683,11 +685,11 @@
 	return err;
 }
 
-static int snd_sa11xx_uda1341_prepare(snd_pcm_substream_t * substream)
+static int snd_sa11xx_uda1341_prepare(struct snd_pcm_substream *substream)
 {
-	sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	audio_stream_t *s = &chip->s[substream->pstr->stream];
+	struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct audio_stream *s = &chip->s[substream->pstr->stream];
         
 	/* set requested samplerate */
 	sa11xx_uda1341_set_samplerate(chip, runtime->rate);
@@ -701,15 +703,15 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_sa11xx_uda1341_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_sa11xx_uda1341_pointer(struct snd_pcm_substream *substream)
 {
-	sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream);
+	struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
 	return audio_get_dma_pos(&chip->s[substream->pstr->stream]);
 }
 
 /* }}} */
 
-static snd_pcm_hardware_t snd_sa11xx_uda1341_capture =
+static struct snd_pcm_hardware snd_sa11xx_uda1341_capture =
 {
 	.info			= (SNDRV_PCM_INFO_INTERLEAVED |
 				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -732,7 +734,7 @@
 	.fifo_size		= 0,
 };
 
-static snd_pcm_hardware_t snd_sa11xx_uda1341_playback =
+static struct snd_pcm_hardware snd_sa11xx_uda1341_playback =
 {
 	.info			= (SNDRV_PCM_INFO_INTERLEAVED |
 				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -755,10 +757,10 @@
 	.fifo_size		= 0,
 };
 
-static int snd_card_sa11xx_uda1341_open(snd_pcm_substream_t * substream)
+static int snd_card_sa11xx_uda1341_open(struct snd_pcm_substream *substream)
 {
-	sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int stream_id = substream->pstr->stream;
 	int err;
 
@@ -776,9 +778,9 @@
 	return 0;
 }
 
-static int snd_card_sa11xx_uda1341_close(snd_pcm_substream_t * substream)
+static int snd_card_sa11xx_uda1341_close(struct snd_pcm_substream *substream)
 {
-	sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream);
+	struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream);
 
 	chip->s[substream->pstr->stream].stream = NULL;
 	return 0;
@@ -786,21 +788,21 @@
 
 /* {{{ HW params & free */
 
-static int snd_sa11xx_uda1341_hw_params(snd_pcm_substream_t * substream,
-					snd_pcm_hw_params_t * hw_params)
+static int snd_sa11xx_uda1341_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
         
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_sa11xx_uda1341_hw_free(snd_pcm_substream_t * substream)
+static int snd_sa11xx_uda1341_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
 /* }}} */
 
-static snd_pcm_ops_t snd_card_sa11xx_uda1341_playback_ops = {
+static struct snd_pcm_ops snd_card_sa11xx_uda1341_playback_ops = {
 	.open			= snd_card_sa11xx_uda1341_open,
 	.close			= snd_card_sa11xx_uda1341_close,
 	.ioctl			= snd_pcm_lib_ioctl,
@@ -811,7 +813,7 @@
 	.pointer		= snd_sa11xx_uda1341_pointer,
 };
 
-static snd_pcm_ops_t snd_card_sa11xx_uda1341_capture_ops = {
+static struct snd_pcm_ops snd_card_sa11xx_uda1341_capture_ops = {
 	.open			= snd_card_sa11xx_uda1341_open,
 	.close			= snd_card_sa11xx_uda1341_close,
 	.ioctl			= snd_pcm_lib_ioctl,
@@ -822,9 +824,9 @@
 	.pointer		= snd_sa11xx_uda1341_pointer,
 };
 
-static int __init snd_card_sa11xx_uda1341_pcm(sa11xx_uda1341_t *sa11xx_uda1341, int device)
+static int __init snd_card_sa11xx_uda1341_pcm(struct sa11xx_uda1341 *sa11xx_uda1341, int device)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(sa11xx_uda1341->card, "UDA1341 PCM", device, 1, 1, &pcm)) < 0)
@@ -835,8 +837,8 @@
 	 * isa works but I'm not sure why (or if) it's the right choice
 	 * this may be too large, trying it for now
 	 */
-	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_ISA, 
-					      snd_pcm_dma_flags(0),
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 
+					      snd_dma_isa_data(),
 					      64*1024, 64*1024);
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_sa11xx_uda1341_playback_ops);
@@ -862,12 +864,15 @@
 
 #ifdef CONFIG_PM
 
-static int snd_sa11xx_uda1341_suspend(snd_card_t *card, pm_message_t state)
+static int snd_sa11xx_uda1341_suspend(struct platform_device *devptr,
+				      pm_message_t state)
 {
-	sa11xx_uda1341_t *chip = card->pm_private_data;
+	struct snd_card *card = platform_get_drvdata(devptr);
+	struct sa11xx_uda1341 *chip = card->private_data;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
-#ifdef HH_VERSION	
+#ifdef HH_VERSION
 	sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dmach);
 	sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_CAPTURE].dmach);
 #else
@@ -875,12 +880,14 @@
 #endif
 	l3_command(chip->uda1341, CMD_SUSPEND, NULL);
 	sa11xx_uda1341_audio_shutdown(chip);
+
 	return 0;
 }
 
-static int snd_sa11xx_uda1341_resume(snd_card_t *card)
+static int snd_sa11xx_uda1341_resume(struct platform_device *devptr)
 {
-	sa11xx_uda1341_t *chip = card->pm_private_data;
+	struct snd_card *card = platform_get_drvdata(devptr);
+	struct sa11xx_uda1341 *chip = card->private_data;
 
 	sa11xx_uda1341_audio_init(chip);
 	l3_command(chip->uda1341, CMD_RESUME, NULL);
@@ -890,67 +897,55 @@
 #else
 	//FIXME
 #endif
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* COMFIG_PM */
 
-void snd_sa11xx_uda1341_free(snd_card_t *card)
+void snd_sa11xx_uda1341_free(struct snd_card *card)
 {
-	sa11xx_uda1341_t *chip = card->private_data;
+	struct sa11xx_uda1341 *chip = card->private_data;
 
 	audio_dma_free(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]);
 	audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]);
-	sa11xx_uda1341 = NULL;
-	card->private_data = NULL;
-	kfree(chip);
 }
 
-static int __init sa11xx_uda1341_init(void)
+static int __init sa11xx_uda1341_probe(struct platform_device *devptr)
 {
 	int err;
-	snd_card_t *card;
-
-	if (!machine_is_h3xxx())
-		return -ENODEV;
+	struct snd_card *card;
+	struct sa11xx_uda1341 *chip;
 
 	/* register the soundcard */
-	card = snd_card_new(-1, id, THIS_MODULE, sizeof(sa11xx_uda1341_t));
+	card = snd_card_new(-1, id, THIS_MODULE, sizeof(struct sa11xx_uda1341));
 	if (card == NULL)
 		return -ENOMEM;
 
-	sa11xx_uda1341 = kzalloc(sizeof(*sa11xx_uda1341), GFP_KERNEL);
-	if (sa11xx_uda1341 == NULL)
-		return -ENOMEM;	
+	chip = card->private_data;
 	spin_lock_init(&chip->s[0].dma_lock);
 	spin_lock_init(&chip->s[1].dma_lock);
-         
-	card->private_data = (void *)sa11xx_uda1341;
-	card->private_free = snd_sa11xx_uda1341_free;
 
-	sa11xx_uda1341->card = card;
-	sa11xx_uda1341->samplerate = AUDIO_RATE_DEFAULT;
+	card->private_free = snd_sa11xx_uda1341_free;
+	chip->card = card;
+	chip->samplerate = AUDIO_RATE_DEFAULT;
 
 	// mixer
-	if ((err = snd_chip_uda1341_mixer_new(sa11xx_uda1341->card, &sa11xx_uda1341->uda1341)))
+	if ((err = snd_chip_uda1341_mixer_new(card, &chip->uda1341)))
 		goto nodev;
 
 	// PCM
-	if ((err = snd_card_sa11xx_uda1341_pcm(sa11xx_uda1341, 0)) < 0)
+	if ((err = snd_card_sa11xx_uda1341_pcm(chip, 0)) < 0)
 		goto nodev;
         
-	snd_card_set_generic_pm_callback(card,
-				     snd_sa11xx_uda1341_suspend, snd_sa11_uda1341_resume,
-				     sa11xx_uda1341);
-
 	strcpy(card->driver, "UDA1341");
 	strcpy(card->shortname, "H3600 UDA1341TS");
 	sprintf(card->longname, "Compaq iPAQ H3600 with Philips UDA1341TS");
         
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto nodev;
+	snd_card_set_dev(card, &devptr->dev);
 
 	if ((err = snd_card_register(card)) == 0) {
 		printk( KERN_INFO "iPAQ audio support initialized\n" );
+		platform_set_drvdata(devptr, card);
 		return 0;
 	}
         
@@ -959,9 +954,47 @@
 	return err;
 }
 
+static int __devexit sa11xx_uda1341_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#define SA11XX_UDA1341_DRIVER	"sa11xx_uda1341"
+
+static struct platform_driver sa11xx_uda1341_driver = {
+	.probe		= sa11xx_uda1341_probe,
+	.remove		= __devexit_p(sa11xx_uda1341_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_sa11xx_uda1341_suspend,
+	.resume		= snd_sa11xx_uda1341_resume,
+#endif
+	.driver		= {
+		.name	= SA11XX_UDA1341_DRIVER,
+	},
+};
+
+static int __init sa11xx_uda1341_init(void)
+{
+	int err;
+
+	if (!machine_is_h3xxx())
+		return -ENODEV;
+	if ((err = platform_driver_register(&sa11xx_uda1341_driver)) < 0)
+		return err;
+	device = platform_device_register_simple(SA11XX_UDA1341_DRIVER, -1, NULL, 0);
+	if (IS_ERR(device)) {
+		platform_driver_unregister(&sa11xx_uda1341_driver);
+		return PTR_ERR(device);
+	}
+	return 0;
+}
+
 static void __exit sa11xx_uda1341_exit(void)
 {
-	snd_card_free(sa11xx_uda1341->card);
+	platform_device_unregister(device);
+	platform_driver_unregister(&sa11xx_uda1341_driver);
 }
 
 module_init(sa11xx_uda1341_init);
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 8271883..f79755f 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -111,6 +111,25 @@
 
 	  If in doubt, say Y.
 
+config SND_DYNAMIC_MINORS
+	bool "Dynamic device file minor numbers (EXPERIMENTAL)"
+	depends on SND && EXPERIMENTAL
+	help
+	  If you say Y here, the minor numbers of ALSA device files in
+	  /dev/snd/ are allocated dynamically.  This allows you to have
+	  more than 8 sound cards, but requires a dynamic device file
+	  system like udev.
+
+	  If you are unsure about this, say N here.
+
+config SND_SUPPORT_OLD_API
+	bool "Support old ALSA API"
+	depends on SND
+	default y
+	help
+	  Say Y here to support the obsolete ALSA PCM API (ver.0.9.0 rc3
+	  or older).
+
 config SND_VERBOSE_PRINTK
 	bool "Verbose printk"
 	depends on SND
@@ -133,7 +152,3 @@
 	help
 	  Say Y here to enable extra-verbose log messages printed when
 	  detecting devices.
-
-config SND_GENERIC_DRIVER
-	bool
-	depends on SND
diff --git a/sound/core/control.c b/sound/core/control.c
index 212c46a..abd62f9 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -34,12 +34,10 @@
 /* max number of user-defined controls */
 #define MAX_USER_CONTROLS	32
 
-typedef struct _snd_kctl_ioctl {
+struct snd_kctl_ioctl {
 	struct list_head list;		/* list of all ioctls */
 	snd_kctl_ioctl_func_t fioctl;
-} snd_kctl_ioctl_t;
-
-#define snd_kctl_ioctl(n) list_entry(n, snd_kctl_ioctl_t, list)
+};
 
 static DECLARE_RWSEM(snd_ioctl_rwsem);
 static LIST_HEAD(snd_control_ioctls);
@@ -49,13 +47,12 @@
 
 static int snd_ctl_open(struct inode *inode, struct file *file)
 {
-	int cardnum = SNDRV_MINOR_CARD(iminor(inode));
 	unsigned long flags;
-	snd_card_t *card;
-	snd_ctl_file_t *ctl;
+	struct snd_card *card;
+	struct snd_ctl_file *ctl;
 	int err;
 
-	card = snd_cards[cardnum];
+	card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
 	if (!card) {
 		err = -ENODEV;
 		goto __error1;
@@ -93,9 +90,9 @@
       	return err;
 }
 
-static void snd_ctl_empty_read_queue(snd_ctl_file_t * ctl)
+static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl)
 {
-	snd_kctl_event_t *cread;
+	struct snd_kctl_event *cread;
 	
 	spin_lock(&ctl->read_lock);
 	while (!list_empty(&ctl->events)) {
@@ -110,9 +107,9 @@
 {
 	unsigned long flags;
 	struct list_head *list;
-	snd_card_t *card;
-	snd_ctl_file_t *ctl;
-	snd_kcontrol_t *control;
+	struct snd_card *card;
+	struct snd_ctl_file *ctl;
+	struct snd_kcontrol *control;
 	unsigned int idx;
 
 	ctl = file->private_data;
@@ -137,12 +134,13 @@
 	return 0;
 }
 
-void snd_ctl_notify(snd_card_t *card, unsigned int mask, snd_ctl_elem_id_t *id)
+void snd_ctl_notify(struct snd_card *card, unsigned int mask,
+		    struct snd_ctl_elem_id *id)
 {
 	unsigned long flags;
 	struct list_head *flist;
-	snd_ctl_file_t *ctl;
-	snd_kctl_event_t *ev;
+	struct snd_ctl_file *ctl;
+	struct snd_kctl_event *ev;
 	
 	snd_assert(card != NULL && id != NULL, return);
 	read_lock(&card->ctl_files_rwlock);
@@ -183,21 +181,23 @@
  * @control: the control template
  * @access: the default control access
  *
- * Allocates a new snd_kcontrol_t instance and copies the given template 
+ * Allocates a new struct snd_kcontrol instance and copies the given template 
  * to the new instance. It does not copy volatile data (access).
  *
  * Returns the pointer of the new instance, or NULL on failure.
  */
-snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control, unsigned int access)
+struct snd_kcontrol *snd_ctl_new(struct snd_kcontrol *control, unsigned int access)
 {
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 	unsigned int idx;
 	
 	snd_assert(control != NULL, return NULL);
 	snd_assert(control->count > 0, return NULL);
-	kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
-	if (kctl == NULL)
+	kctl = kzalloc(sizeof(*kctl) + sizeof(struct snd_kcontrol_volatile) * control->count, GFP_KERNEL);
+	if (kctl == NULL) {
+		snd_printk(KERN_ERR "Cannot allocate control instance\n");
 		return NULL;
+	}
 	*kctl = *control;
 	for (idx = 0; idx < kctl->count; idx++)
 		kctl->vd[idx].access = access;
@@ -209,15 +209,16 @@
  * @ncontrol: the initialization record
  * @private_data: the private data to set
  *
- * Allocates a new snd_kcontrol_t instance and initialize from the given 
+ * Allocates a new struct snd_kcontrol instance and initialize from the given 
  * template.  When the access field of ncontrol is 0, it's assumed as
  * READWRITE access. When the count field is 0, it's assumes as one.
  *
  * Returns the pointer of the newly generated instance, or NULL on failure.
  */
-snd_kcontrol_t *snd_ctl_new1(const snd_kcontrol_new_t * ncontrol, void *private_data)
+struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
+				  void *private_data)
 {
-	snd_kcontrol_t kctl;
+	struct snd_kcontrol kctl;
 	unsigned int access;
 	
 	snd_assert(ncontrol != NULL, return NULL);
@@ -249,7 +250,7 @@
  * or snd_ctl_new1().
  * Don't call this after the control was added to the card.
  */
-void snd_ctl_free_one(snd_kcontrol_t * kcontrol)
+void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
 {
 	if (kcontrol) {
 		if (kcontrol->private_free)
@@ -258,11 +259,11 @@
 	}
 }
 
-static unsigned int snd_ctl_hole_check(snd_card_t * card,
+static unsigned int snd_ctl_hole_check(struct snd_card *card,
 				       unsigned int count)
 {
 	struct list_head *list;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	list_for_each(list, &card->controls) {
 		kctl = snd_kcontrol(list);
@@ -275,7 +276,7 @@
 	return card->last_numid;
 }
 
-static int snd_ctl_find_hole(snd_card_t * card, unsigned int count)
+static int snd_ctl_find_hole(struct snd_card *card, unsigned int count)
 {
 	unsigned int last_numid, iter = 100000;
 
@@ -304,12 +305,14 @@
  *
  * It frees automatically the control which cannot be added.
  */
-int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol)
+int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
 {
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 	unsigned int idx;
 
-	snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
+	snd_assert(card != NULL, return -EINVAL);
+	if (! kcontrol)
+		return -EINVAL;
 	snd_assert(kcontrol->info != NULL, return -EINVAL);
 	id = kcontrol->id;
 	down_write(&card->controls_rwsem);
@@ -350,9 +353,9 @@
  * 
  * Returns 0 if successful, or a negative error code on failure.
  */
-int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol)
+int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
 {
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 	unsigned int idx;
 
 	snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
@@ -375,9 +378,9 @@
  * 
  * Returns 0 if successful, or a negative error code on failure.
  */
-int snd_ctl_remove_id(snd_card_t * card, snd_ctl_elem_id_t *id)
+int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
 {
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 	int ret;
 
 	down_write(&card->controls_rwsem);
@@ -401,10 +404,11 @@
  * 
  * Returns 0 if successful, or a negative error code on failure.
  */
-static int snd_ctl_remove_unlocked_id(snd_ctl_file_t * file, snd_ctl_elem_id_t *id)
+static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file,
+				      struct snd_ctl_elem_id *id)
 {
-	snd_card_t *card = file->card;
-	snd_kcontrol_t *kctl;
+	struct snd_card *card = file->card;
+	struct snd_kcontrol *kctl;
 	int idx, ret;
 
 	down_write(&card->controls_rwsem);
@@ -434,9 +438,10 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_ctl_rename_id(snd_card_t * card, snd_ctl_elem_id_t *src_id, snd_ctl_elem_id_t *dst_id)
+int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
+		      struct snd_ctl_elem_id *dst_id)
 {
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	down_write(&card->controls_rwsem);
 	kctl = snd_ctl_find_id(card, src_id);
@@ -463,10 +468,10 @@
  * The caller must down card->controls_rwsem before calling this function
  * (if the race condition can happen).
  */
-snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid)
+struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numid)
 {
 	struct list_head *list;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	snd_assert(card != NULL && numid != 0, return NULL);
 	list_for_each(list, &card->controls) {
@@ -489,10 +494,11 @@
  * The caller must down card->controls_rwsem before calling this function
  * (if the race condition can happen).
  */
-snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
+struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
+				     struct snd_ctl_elem_id *id)
 {
 	struct list_head *list;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	snd_assert(card != NULL && id != NULL, return NULL);
 	if (id->numid != 0)
@@ -516,10 +522,10 @@
 	return NULL;
 }
 
-static int snd_ctl_card_info(snd_card_t * card, snd_ctl_file_t * ctl,
+static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
 			     unsigned int cmd, void __user *arg)
 {
-	snd_ctl_card_info_t *info;
+	struct snd_ctl_card_info *info;
 
 	info = kzalloc(sizeof(*info), GFP_KERNEL);
 	if (! info)
@@ -533,7 +539,7 @@
 	strlcpy(info->mixername, card->mixername, sizeof(info->mixername));
 	strlcpy(info->components, card->components, sizeof(info->components));
 	up_read(&snd_ioctl_rwsem);
-	if (copy_to_user(arg, info, sizeof(snd_ctl_card_info_t))) {
+	if (copy_to_user(arg, info, sizeof(struct snd_ctl_card_info))) {
 		kfree(info);
 		return -EFAULT;
 	}
@@ -541,12 +547,13 @@
 	return 0;
 }
 
-static int snd_ctl_elem_list(snd_card_t *card, snd_ctl_elem_list_t __user *_list)
+static int snd_ctl_elem_list(struct snd_card *card,
+			     struct snd_ctl_elem_list __user *_list)
 {
 	struct list_head *plist;
-	snd_ctl_elem_list_t list;
-	snd_kcontrol_t *kctl;
-	snd_ctl_elem_id_t *dst, *id;
+	struct snd_ctl_elem_list list;
+	struct snd_kcontrol *kctl;
+	struct snd_ctl_elem_id *dst, *id;
 	unsigned int offset, space, first, jidx;
 	
 	if (copy_from_user(&list, _list, sizeof(list)))
@@ -559,7 +566,7 @@
 		return -ENOMEM;
 	if (space > 0) {
 		/* allocate temporary buffer for atomic operation */
-		dst = vmalloc(space * sizeof(snd_ctl_elem_id_t));
+		dst = vmalloc(space * sizeof(struct snd_ctl_elem_id));
 		if (dst == NULL)
 			return -ENOMEM;
 		down_read(&card->controls_rwsem);
@@ -588,7 +595,9 @@
 			offset = 0;
 		}
 		up_read(&card->controls_rwsem);
-		if (list.used > 0 && copy_to_user(list.pids, dst, list.used * sizeof(snd_ctl_elem_id_t))) {
+		if (list.used > 0 &&
+		    copy_to_user(list.pids, dst,
+				 list.used * sizeof(struct snd_ctl_elem_id))) {
 			vfree(dst);
 			return -EFAULT;
 		}
@@ -603,11 +612,12 @@
 	return 0;
 }
 
-static int snd_ctl_elem_info(snd_ctl_file_t *ctl, snd_ctl_elem_info_t *info)
+static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
+			     struct snd_ctl_elem_info *info)
 {
-	snd_card_t *card = ctl->card;
-	snd_kcontrol_t *kctl;
-	snd_kcontrol_volatile_t *vd;
+	struct snd_card *card = ctl->card;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_volatile *vd;
 	unsigned int index_offset;
 	int result;
 	
@@ -640,9 +650,10 @@
 	return result;
 }
 
-static int snd_ctl_elem_info_user(snd_ctl_file_t *ctl, snd_ctl_elem_info_t __user *_info)
+static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
+				  struct snd_ctl_elem_info __user *_info)
 {
-	snd_ctl_elem_info_t info;
+	struct snd_ctl_elem_info info;
 	int result;
 
 	if (copy_from_user(&info, _info, sizeof(info)))
@@ -654,10 +665,10 @@
 	return result;
 }
 
-int snd_ctl_elem_read(snd_card_t *card, snd_ctl_elem_value_t *control)
+int snd_ctl_elem_read(struct snd_card *card, struct snd_ctl_elem_value *control)
 {
-	snd_kcontrol_t *kctl;
-	snd_kcontrol_volatile_t *vd;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_volatile *vd;
 	unsigned int index_offset;
 	int result, indirect;
 
@@ -684,9 +695,10 @@
 	return result;
 }
 
-static int snd_ctl_elem_read_user(snd_card_t *card, snd_ctl_elem_value_t __user *_control)
+static int snd_ctl_elem_read_user(struct snd_card *card,
+				  struct snd_ctl_elem_value __user *_control)
 {
-	snd_ctl_elem_value_t *control;
+	struct snd_ctl_elem_value *control;
 	int result;
 	
 	control = kmalloc(sizeof(*control), GFP_KERNEL);
@@ -704,10 +716,11 @@
 	return result;
 }
 
-int snd_ctl_elem_write(snd_card_t *card, snd_ctl_file_t *file, snd_ctl_elem_value_t *control)
+int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
+		       struct snd_ctl_elem_value *control)
 {
-	snd_kcontrol_t *kctl;
-	snd_kcontrol_volatile_t *vd;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_volatile *vd;
 	unsigned int index_offset;
 	int result, indirect;
 
@@ -741,9 +754,10 @@
 	return result;
 }
 
-static int snd_ctl_elem_write_user(snd_ctl_file_t *file, snd_ctl_elem_value_t __user *_control)
+static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
+				   struct snd_ctl_elem_value __user *_control)
 {
-	snd_ctl_elem_value_t *control;
+	struct snd_ctl_elem_value *control;
 	int result;
 
 	control = kmalloc(sizeof(*control), GFP_KERNEL);
@@ -761,12 +775,13 @@
 	return result;
 }
 
-static int snd_ctl_elem_lock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
+static int snd_ctl_elem_lock(struct snd_ctl_file *file,
+			     struct snd_ctl_elem_id __user *_id)
 {
-	snd_card_t *card = file->card;
-	snd_ctl_elem_id_t id;
-	snd_kcontrol_t *kctl;
-	snd_kcontrol_volatile_t *vd;
+	struct snd_card *card = file->card;
+	struct snd_ctl_elem_id id;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_volatile *vd;
 	int result;
 	
 	if (copy_from_user(&id, _id, sizeof(id)))
@@ -789,12 +804,13 @@
 	return result;
 }
 
-static int snd_ctl_elem_unlock(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
+static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
+			       struct snd_ctl_elem_id __user *_id)
 {
-	snd_card_t *card = file->card;
-	snd_ctl_elem_id_t id;
-	snd_kcontrol_t *kctl;
-	snd_kcontrol_volatile_t *vd;
+	struct snd_card *card = file->card;
+	struct snd_ctl_elem_id id;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_volatile *vd;
 	int result;
 	
 	if (copy_from_user(&id, _id, sizeof(id)))
@@ -820,14 +836,15 @@
 }
 
 struct user_element {
-	snd_ctl_elem_info_t info;
+	struct snd_ctl_elem_info info;
 	void *elem_data;		/* element data */
 	unsigned long elem_data_size;	/* size of element data in bytes */
 	void *priv_data;		/* private data (like strings for enumerated type) */
 	unsigned long priv_data_size;	/* size of private data in bytes */
 };
 
-static int snd_ctl_elem_user_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	struct user_element *ue = kcontrol->private_data;
 
@@ -835,7 +852,8 @@
 	return 0;
 }
 
-static int snd_ctl_elem_user_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct user_element *ue = kcontrol->private_data;
 
@@ -843,7 +861,8 @@
 	return 0;
 }
 
-static int snd_ctl_elem_user_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	int change;
 	struct user_element *ue = kcontrol->private_data;
@@ -854,15 +873,16 @@
 	return change;
 }
 
-static void snd_ctl_elem_user_free(snd_kcontrol_t * kcontrol)
+static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol)
 {
 	kfree(kcontrol->private_data);
 }
 
-static int snd_ctl_elem_add(snd_ctl_file_t *file, snd_ctl_elem_info_t *info, int replace)
+static int snd_ctl_elem_add(struct snd_ctl_file *file,
+			    struct snd_ctl_elem_info *info, int replace)
 {
-	snd_card_t *card = file->card;
-	snd_kcontrol_t kctl, *_kctl;
+	struct snd_card *card = file->card;
+	struct snd_kcontrol kctl, *_kctl;
 	unsigned int access;
 	long private_size;
 	struct user_element *ue;
@@ -873,7 +893,8 @@
 	if (info->count > 1024)
 		return -EINVAL;
 	access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
-		(info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|SNDRV_CTL_ELEM_ACCESS_INACTIVE));
+		(info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
+				 SNDRV_CTL_ELEM_ACCESS_INACTIVE));
 	info->id.numid = 0;
 	memset(&kctl, 0, sizeof(kctl));
 	down_write(&card->controls_rwsem);
@@ -921,7 +942,7 @@
 			return -EINVAL;
 		break;
 	case SNDRV_CTL_ELEM_TYPE_IEC958:
-		private_size = sizeof(struct sndrv_aes_iec958);
+		private_size = sizeof(struct snd_aes_iec958);
 		if (info->count != 1)
 			return -EINVAL;
 		break;
@@ -957,24 +978,26 @@
 	return 0;
 }
 
-static int snd_ctl_elem_add_user(snd_ctl_file_t *file, snd_ctl_elem_info_t __user *_info, int replace)
+static int snd_ctl_elem_add_user(struct snd_ctl_file *file,
+				 struct snd_ctl_elem_info __user *_info, int replace)
 {
-	snd_ctl_elem_info_t info;
+	struct snd_ctl_elem_info info;
 	if (copy_from_user(&info, _info, sizeof(info)))
 		return -EFAULT;
 	return snd_ctl_elem_add(file, &info, replace);
 }
 
-static int snd_ctl_elem_remove(snd_ctl_file_t *file, snd_ctl_elem_id_t __user *_id)
+static int snd_ctl_elem_remove(struct snd_ctl_file *file,
+			       struct snd_ctl_elem_id __user *_id)
 {
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 	int err;
 
 	if (copy_from_user(&id, _id, sizeof(id)))
 		return -EFAULT;
 	err = snd_ctl_remove_unlocked_id(file, &id);
 	if (! err) {
-		snd_card_t *card = file->card;
+		struct snd_card *card = file->card;
 		down_write(&card->controls_rwsem);
 		card->user_ctl_count--;
 		up_write(&card->controls_rwsem);
@@ -982,7 +1005,7 @@
 	return err;
 }
 
-static int snd_ctl_subscribe_events(snd_ctl_file_t *file, int __user *ptr)
+static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
 {
 	int subscribe;
 	if (get_user(subscribe, ptr))
@@ -1003,42 +1026,12 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
-/*
- * change the power state
- */
-static int snd_ctl_set_power_state(snd_card_t *card, unsigned int power_state)
-{
-	switch (power_state) {
-	case SNDRV_CTL_POWER_D0:
-		if (card->power_state != power_state) {
-			card->pm_resume(card);
-			snd_power_change_state(card, power_state);
-		}
-		break;
-	case SNDRV_CTL_POWER_D3hot:
-		if (card->power_state != power_state) {
-			card->pm_suspend(card, PMSG_SUSPEND);
-			snd_power_change_state(card, power_state);
-		}
-		break;
-	case SNDRV_CTL_POWER_D1:
-	case SNDRV_CTL_POWER_D2:
-	case SNDRV_CTL_POWER_D3cold:
-		/* not supported yet */
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-#endif
-
 static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	snd_ctl_file_t *ctl;
-	snd_card_t *card;
+	struct snd_ctl_file *ctl;
+	struct snd_card *card;
 	struct list_head *list;
-	snd_kctl_ioctl_t *p;
+	struct snd_kctl_ioctl *p;
 	void __user *argp = (void __user *)arg;
 	int __user *ip = argp;
 	int err;
@@ -1072,19 +1065,7 @@
 	case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
 		return snd_ctl_subscribe_events(ctl, ip);
 	case SNDRV_CTL_IOCTL_POWER:
-		if (get_user(err, ip))
-			return -EFAULT;
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-#ifdef CONFIG_PM
-		if (card->pm_suspend && card->pm_resume) {
-			snd_power_lock(card);
-			err = snd_ctl_set_power_state(card, err);
-			snd_power_unlock(card);
-		} else
-#endif
-			err = -ENOPROTOOPT;
-		return err;
+		return -ENOPROTOOPT;
 	case SNDRV_CTL_IOCTL_POWER_STATE:
 #ifdef CONFIG_PM
 		return put_user(card->power_state, ip) ? -EFAULT : 0;
@@ -1094,7 +1075,7 @@
 	}
 	down_read(&snd_ioctl_rwsem);
 	list_for_each(list, &snd_control_ioctls) {
-		p = list_entry(list, snd_kctl_ioctl_t, list);
+		p = list_entry(list, struct snd_kctl_ioctl, list);
 		err = p->fioctl(card, ctl, cmd, arg);
 		if (err != -ENOIOCTLCMD) {
 			up_read(&snd_ioctl_rwsem);
@@ -1106,9 +1087,10 @@
 	return -ENOTTY;
 }
 
-static ssize_t snd_ctl_read(struct file *file, char __user *buffer, size_t count, loff_t * offset)
+static ssize_t snd_ctl_read(struct file *file, char __user *buffer,
+			    size_t count, loff_t * offset)
 {
-	snd_ctl_file_t *ctl;
+	struct snd_ctl_file *ctl;
 	int err = 0;
 	ssize_t result = 0;
 
@@ -1116,12 +1098,12 @@
 	snd_assert(ctl != NULL && ctl->card != NULL, return -ENXIO);
 	if (!ctl->subscribed)
 		return -EBADFD;
-	if (count < sizeof(snd_ctl_event_t))
+	if (count < sizeof(struct snd_ctl_event))
 		return -EINVAL;
 	spin_lock_irq(&ctl->read_lock);
-	while (count >= sizeof(snd_ctl_event_t)) {
-		snd_ctl_event_t ev;
-		snd_kctl_event_t *kev;
+	while (count >= sizeof(struct snd_ctl_event)) {
+		struct snd_ctl_event ev;
+		struct snd_kctl_event *kev;
 		while (list_empty(&ctl->events)) {
 			wait_queue_t wait;
 			if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
@@ -1145,14 +1127,14 @@
 		list_del(&kev->list);
 		spin_unlock_irq(&ctl->read_lock);
 		kfree(kev);
-		if (copy_to_user(buffer, &ev, sizeof(snd_ctl_event_t))) {
+		if (copy_to_user(buffer, &ev, sizeof(struct snd_ctl_event))) {
 			err = -EFAULT;
 			goto __end;
 		}
 		spin_lock_irq(&ctl->read_lock);
-		buffer += sizeof(snd_ctl_event_t);
-		count -= sizeof(snd_ctl_event_t);
-		result += sizeof(snd_ctl_event_t);
+		buffer += sizeof(struct snd_ctl_event);
+		count -= sizeof(struct snd_ctl_event);
+		result += sizeof(struct snd_ctl_event);
 	}
       __end_lock:
 	spin_unlock_irq(&ctl->read_lock);
@@ -1163,7 +1145,7 @@
 static unsigned int snd_ctl_poll(struct file *file, poll_table * wait)
 {
 	unsigned int mask;
-	snd_ctl_file_t *ctl;
+	struct snd_ctl_file *ctl;
 
 	ctl = file->private_data;
 	if (!ctl->subscribed)
@@ -1183,9 +1165,9 @@
  */
 static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head *lists)
 {
-	snd_kctl_ioctl_t *pn;
+	struct snd_kctl_ioctl *pn;
 
-	pn = kzalloc(sizeof(snd_kctl_ioctl_t), GFP_KERNEL);
+	pn = kzalloc(sizeof(struct snd_kctl_ioctl), GFP_KERNEL);
 	if (pn == NULL)
 		return -ENOMEM;
 	pn->fioctl = fcn;
@@ -1210,15 +1192,16 @@
 /*
  * de-register the device-specific control-ioctls.
  */
-static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head *lists)
+static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn,
+				     struct list_head *lists)
 {
 	struct list_head *list;
-	snd_kctl_ioctl_t *p;
+	struct snd_kctl_ioctl *p;
 
 	snd_assert(fcn != NULL, return -EINVAL);
 	down_write(&snd_ioctl_rwsem);
 	list_for_each(list, lists) {
-		p = list_entry(list, snd_kctl_ioctl_t, list);
+		p = list_entry(list, struct snd_kctl_ioctl, list);
 		if (p->fioctl == fcn) {
 			list_del(&p->list);
 			up_write(&snd_ioctl_rwsem);
@@ -1246,7 +1229,7 @@
 
 static int snd_ctl_fasync(int fd, struct file * file, int on)
 {
-	snd_ctl_file_t *ctl;
+	struct snd_ctl_file *ctl;
 	int err;
 	ctl = file->private_data;
 	err = fasync_helper(fd, file, on, &ctl->fasync);
@@ -1280,18 +1263,12 @@
 	.fasync =	snd_ctl_fasync,
 };
 
-static snd_minor_t snd_ctl_reg =
-{
-	.comment =	"ctl",
-	.f_ops =	&snd_ctl_f_ops,
-};
-
 /*
  * registration of the control device
  */
-static int snd_ctl_dev_register(snd_device_t *device)
+static int snd_ctl_dev_register(struct snd_device *device)
 {
-	snd_card_t *card = device->device_data;
+	struct snd_card *card = device->device_data;
 	int err, cardnum;
 	char name[16];
 
@@ -1299,8 +1276,8 @@
 	cardnum = card->number;
 	snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
 	sprintf(name, "controlC%i", cardnum);
-	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL,
-					card, 0, &snd_ctl_reg, name)) < 0)
+	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
+				       &snd_ctl_f_ops, card, name)) < 0)
 		return err;
 	return 0;
 }
@@ -1308,11 +1285,11 @@
 /*
  * disconnection of the control device
  */
-static int snd_ctl_dev_disconnect(snd_device_t *device)
+static int snd_ctl_dev_disconnect(struct snd_device *device)
 {
-	snd_card_t *card = device->device_data;
+	struct snd_card *card = device->device_data;
 	struct list_head *flist;
-	snd_ctl_file_t *ctl;
+	struct snd_ctl_file *ctl;
 
 	down_read(&card->controls_rwsem);
 	list_for_each(flist, &card->ctl_files) {
@@ -1327,10 +1304,10 @@
 /*
  * free all controls
  */
-static int snd_ctl_dev_free(snd_device_t *device)
+static int snd_ctl_dev_free(struct snd_device *device)
 {
-	snd_card_t *card = device->device_data;
-	snd_kcontrol_t *control;
+	struct snd_card *card = device->device_data;
+	struct snd_kcontrol *control;
 
 	down_write(&card->controls_rwsem);
 	while (!list_empty(&card->controls)) {
@@ -1344,15 +1321,16 @@
 /*
  * de-registration of the control device
  */
-static int snd_ctl_dev_unregister(snd_device_t *device)
+static int snd_ctl_dev_unregister(struct snd_device *device)
 {
-	snd_card_t *card = device->device_data;
+	struct snd_card *card = device->device_data;
 	int err, cardnum;
 
 	snd_assert(card != NULL, return -ENXIO);
 	cardnum = card->number;
 	snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
-	if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL, card, 0)) < 0)
+	if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
+					 card, -1)) < 0)
 		return err;
 	return snd_ctl_dev_free(device);
 }
@@ -1361,9 +1339,9 @@
  * create control core:
  * called from init.c
  */
-int snd_ctl_create(snd_card_t *card)
+int snd_ctl_create(struct snd_card *card)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_ctl_dev_free,
 		.dev_register =	snd_ctl_dev_register,
 		.dev_disconnect = snd_ctl_dev_disconnect,
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index 207c7de..418c6d4 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -22,7 +22,7 @@
 
 #include <linux/compat.h>
 
-struct sndrv_ctl_elem_list32 {
+struct snd_ctl_elem_list32 {
 	u32 offset;
 	u32 space;
 	u32 used;
@@ -31,9 +31,10 @@
 	unsigned char reserved[50];
 } /* don't set packed attribute here */;
 
-static int snd_ctl_elem_list_compat(snd_card_t *card, struct sndrv_ctl_elem_list32 __user *data32)
+static int snd_ctl_elem_list_compat(struct snd_card *card,
+				    struct snd_ctl_elem_list32 __user *data32)
 {
-	struct sndrv_ctl_elem_list __user *data;
+	struct snd_ctl_elem_list __user *data;
 	compat_caddr_t ptr;
 	int err;
 
@@ -60,8 +61,8 @@
  * it uses union, so the things are not easy..
  */
 
-struct sndrv_ctl_elem_info32 {
-	struct sndrv_ctl_elem_id id; // the size of struct is same
+struct snd_ctl_elem_info32 {
+	struct snd_ctl_elem_id id; // the size of struct is same
 	s32 type;
 	u32 access;
 	u32 count;
@@ -87,9 +88,10 @@
 	unsigned char reserved[64];
 } __attribute__((packed));
 
-static int snd_ctl_elem_info_compat(snd_ctl_file_t *ctl, struct sndrv_ctl_elem_info32 __user *data32)
+static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
+				    struct snd_ctl_elem_info32 __user *data32)
 {
-	struct sndrv_ctl_elem_info *data;
+	struct snd_ctl_elem_info *data;
 	int err;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -146,8 +148,8 @@
 }
 
 /* read / write */
-struct sndrv_ctl_elem_value32 {
-	struct sndrv_ctl_elem_id id;
+struct snd_ctl_elem_value32 {
+	struct snd_ctl_elem_id id;
 	unsigned int indirect;	/* bit-field causes misalignment */
         union {
 		s32 integer[128];
@@ -161,10 +163,11 @@
 
 
 /* get the value type and count of the control */
-static int get_ctl_type(snd_card_t *card, snd_ctl_elem_id_t *id, int *countp)
+static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
+			int *countp)
 {
-	snd_kcontrol_t *kctl;
-	snd_ctl_elem_info_t info;
+	struct snd_kcontrol *kctl;
+	struct snd_ctl_elem_info info;
 	int err;
 
 	down_read(&card->controls_rwsem);
@@ -193,15 +196,15 @@
 	case SNDRV_CTL_ELEM_TYPE_BYTES:
 		return 512;
 	case SNDRV_CTL_ELEM_TYPE_IEC958:
-		return sizeof(struct sndrv_aes_iec958);
+		return sizeof(struct snd_aes_iec958);
 	default:
 		return -1;
 	}
 }
 
-static int copy_ctl_value_from_user(snd_card_t *card,
-				    struct sndrv_ctl_elem_value *data,
-				    struct sndrv_ctl_elem_value32 __user *data32,
+static int copy_ctl_value_from_user(struct snd_card *card,
+				    struct snd_ctl_elem_value *data,
+				    struct snd_ctl_elem_value32 __user *data32,
 				    int *typep, int *countp)
 {
 	int i, type, count, size;
@@ -242,8 +245,8 @@
 }
 
 /* restore the value to 32bit */
-static int copy_ctl_value_to_user(struct sndrv_ctl_elem_value32 __user *data32,
-				  struct sndrv_ctl_elem_value *data,
+static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
+				  struct snd_ctl_elem_value *data,
 				  int type, int count)
 {
 	int i, size;
@@ -265,10 +268,10 @@
 	return 0;
 }
 
-static int snd_ctl_elem_read_user_compat(snd_card_t *card, 
-					 struct sndrv_ctl_elem_value32 __user *data32)
+static int snd_ctl_elem_read_user_compat(struct snd_card *card, 
+					 struct snd_ctl_elem_value32 __user *data32)
 {
-	struct sndrv_ctl_elem_value *data;
+	struct snd_ctl_elem_value *data;
 	int err, type, count;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -285,10 +288,10 @@
 	return err;
 }
 
-static int snd_ctl_elem_write_user_compat(snd_ctl_file_t *file,
-					  struct sndrv_ctl_elem_value32 __user *data32)
+static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
+					  struct snd_ctl_elem_value32 __user *data32)
 {
-	struct sndrv_ctl_elem_value *data;
+	struct snd_ctl_elem_value *data;
 	int err, type, count;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -306,11 +309,11 @@
 }
 
 /* add or replace a user control */
-static int snd_ctl_elem_add_compat(snd_ctl_file_t *file,
-				   struct sndrv_ctl_elem_info32 __user *data32,
+static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
+				   struct snd_ctl_elem_info32 __user *data32,
 				   int replace)
 {
-	struct sndrv_ctl_elem_info *data;
+	struct snd_ctl_elem_info *data;
 	int err;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -355,17 +358,17 @@
 }  
 
 enum {
-	SNDRV_CTL_IOCTL_ELEM_LIST32 = _IOWR('U', 0x10, struct sndrv_ctl_elem_list32),
-	SNDRV_CTL_IOCTL_ELEM_INFO32 = _IOWR('U', 0x11, struct sndrv_ctl_elem_info32),
-	SNDRV_CTL_IOCTL_ELEM_READ32 = _IOWR('U', 0x12, struct sndrv_ctl_elem_value32),
-	SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct sndrv_ctl_elem_value32),
-	SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct sndrv_ctl_elem_info32),
-	SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct sndrv_ctl_elem_info32),
+	SNDRV_CTL_IOCTL_ELEM_LIST32 = _IOWR('U', 0x10, struct snd_ctl_elem_list32),
+	SNDRV_CTL_IOCTL_ELEM_INFO32 = _IOWR('U', 0x11, struct snd_ctl_elem_info32),
+	SNDRV_CTL_IOCTL_ELEM_READ32 = _IOWR('U', 0x12, struct snd_ctl_elem_value32),
+	SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
+	SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
+	SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
 };
 
 static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	snd_ctl_file_t *ctl;
+	struct snd_ctl_file *ctl;
 	struct list_head *list;
 	void __user *argp = compat_ptr(arg);
 	int err;
@@ -398,7 +401,7 @@
 
 	down_read(&snd_ioctl_rwsem);
 	list_for_each(list, &snd_control_compat_ioctls) {
-		snd_kctl_ioctl_t *p = list_entry(list, snd_kctl_ioctl_t, list);
+		struct snd_kctl_ioctl *p = list_entry(list, struct snd_kctl_ioctl, list);
 		if (p->fioctl) {
 			err = p->fioctl(ctl->card, ctl, cmd, arg);
 			if (err != -ENOIOCTLCMD) {
diff --git a/sound/core/device.c b/sound/core/device.c
index 1f509f5..b1cf6ec 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -41,17 +41,19 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_device_new(snd_card_t *card, snd_device_type_t type,
-		   void *device_data, snd_device_ops_t *ops)
+int snd_device_new(struct snd_card *card, snd_device_type_t type,
+		   void *device_data, struct snd_device_ops *ops)
 {
-	snd_device_t *dev;
+	struct snd_device *dev;
 
 	snd_assert(card != NULL, return -ENXIO);
 	snd_assert(device_data != NULL, return -ENXIO);
 	snd_assert(ops != NULL, return -ENXIO);
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (dev == NULL)
+	if (dev == NULL) {
+		snd_printk(KERN_ERR "Cannot allocate device\n");
 		return -ENOMEM;
+	}
 	dev->card = card;
 	dev->type = type;
 	dev->state = SNDRV_DEV_BUILD;
@@ -73,10 +75,10 @@
  * Returns zero if successful, or a negative error code on failure or if the
  * device not found.
  */
-int snd_device_free(snd_card_t *card, void *device_data)
+int snd_device_free(struct snd_card *card, void *device_data)
 {
 	struct list_head *list;
-	snd_device_t *dev;
+	struct snd_device *dev;
 	
 	snd_assert(card != NULL, return -ENXIO);
 	snd_assert(device_data != NULL, return -ENXIO);
@@ -86,7 +88,8 @@
 			continue;
 		/* unlink */
 		list_del(&dev->list);
-		if ((dev->state == SNDRV_DEV_REGISTERED || dev->state == SNDRV_DEV_DISCONNECTED) &&
+		if ((dev->state == SNDRV_DEV_REGISTERED ||
+		     dev->state == SNDRV_DEV_DISCONNECTED) &&
 		    dev->ops->dev_unregister) {
 			if (dev->ops->dev_unregister(dev))
 				snd_printk(KERN_ERR "device unregister failure\n");
@@ -99,7 +102,8 @@
 		kfree(dev);
 		return 0;
 	}
-	snd_printd("device free %p (from %p), not found\n", device_data, __builtin_return_address(0));
+	snd_printd("device free %p (from %p), not found\n", device_data,
+		   __builtin_return_address(0));
 	return -ENXIO;
 }
 
@@ -116,10 +120,10 @@
  * Returns zero if successful, or a negative error code on failure or if the
  * device not found.
  */
-int snd_device_disconnect(snd_card_t *card, void *device_data)
+int snd_device_disconnect(struct snd_card *card, void *device_data)
 {
 	struct list_head *list;
-	snd_device_t *dev;
+	struct snd_device *dev;
 
 	snd_assert(card != NULL, return -ENXIO);
 	snd_assert(device_data != NULL, return -ENXIO);
@@ -127,14 +131,16 @@
 		dev = snd_device(list);
 		if (dev->device_data != device_data)
 			continue;
-		if (dev->state == SNDRV_DEV_REGISTERED && dev->ops->dev_disconnect) {
+		if (dev->state == SNDRV_DEV_REGISTERED &&
+		    dev->ops->dev_disconnect) {
 			if (dev->ops->dev_disconnect(dev))
 				snd_printk(KERN_ERR "device disconnect failure\n");
 			dev->state = SNDRV_DEV_DISCONNECTED;
 		}
 		return 0;
 	}
-	snd_printd("device disconnect %p (from %p), not found\n", device_data, __builtin_return_address(0));
+	snd_printd("device disconnect %p (from %p), not found\n", device_data,
+		   __builtin_return_address(0));
 	return -ENXIO;
 }
 
@@ -151,10 +157,10 @@
  * Returns zero if successful, or a negative error code on failure or if the
  * device not found.
  */
-int snd_device_register(snd_card_t *card, void *device_data)
+int snd_device_register(struct snd_card *card, void *device_data)
 {
 	struct list_head *list;
-	snd_device_t *dev;
+	struct snd_device *dev;
 	int err;
 
 	snd_assert(card != NULL, return -ENXIO);
@@ -169,6 +175,7 @@
 			dev->state = SNDRV_DEV_REGISTERED;
 			return 0;
 		}
+		snd_printd("snd_device_register busy\n");
 		return -EBUSY;
 	}
 	snd_BUG();
@@ -179,10 +186,10 @@
  * register all the devices on the card.
  * called from init.c
  */
-int snd_device_register_all(snd_card_t *card)
+int snd_device_register_all(struct snd_card *card)
 {
 	struct list_head *list;
-	snd_device_t *dev;
+	struct snd_device *dev;
 	int err;
 	
 	snd_assert(card != NULL, return -ENXIO);
@@ -201,9 +208,9 @@
  * disconnect all the devices on the card.
  * called from init.c
  */
-int snd_device_disconnect_all(snd_card_t *card)
+int snd_device_disconnect_all(struct snd_card *card)
 {
-	snd_device_t *dev;
+	struct snd_device *dev;
 	struct list_head *list;
 	int err = 0;
 
@@ -220,9 +227,9 @@
  * release all the devices on the card.
  * called from init.c
  */
-int snd_device_free_all(snd_card_t *card, snd_device_cmd_t cmd)
+int snd_device_free_all(struct snd_card *card, snd_device_cmd_t cmd)
 {
-	snd_device_t *dev;
+	struct snd_device *dev;
 	struct list_head *list;
 	int err;
 	unsigned int range_low, range_high;
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index e91cee3..618c43b 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -35,38 +35,49 @@
 MODULE_DESCRIPTION("Hardware dependent layer");
 MODULE_LICENSE("GPL");
 
-static snd_hwdep_t *snd_hwdep_devices[SNDRV_CARDS * SNDRV_MINOR_HWDEPS];
-
+static LIST_HEAD(snd_hwdep_devices);
 static DECLARE_MUTEX(register_mutex);
 
-static int snd_hwdep_free(snd_hwdep_t *hwdep);
-static int snd_hwdep_dev_free(snd_device_t *device);
-static int snd_hwdep_dev_register(snd_device_t *device);
-static int snd_hwdep_dev_unregister(snd_device_t *device);
+static int snd_hwdep_free(struct snd_hwdep *hwdep);
+static int snd_hwdep_dev_free(struct snd_device *device);
+static int snd_hwdep_dev_register(struct snd_device *device);
+static int snd_hwdep_dev_unregister(struct snd_device *device);
 
-/*
 
- */
+static struct snd_hwdep *snd_hwdep_search(struct snd_card *card, int device)
+{
+	struct list_head *p;
+	struct snd_hwdep *hwdep;
+
+	list_for_each(p, &snd_hwdep_devices) {
+		hwdep = list_entry(p, struct snd_hwdep, list);
+		if (hwdep->card == card && hwdep->device == device)
+			return hwdep;
+	}
+	return NULL;
+}
 
 static loff_t snd_hwdep_llseek(struct file * file, loff_t offset, int orig)
 {
-	snd_hwdep_t *hw = file->private_data;
+	struct snd_hwdep *hw = file->private_data;
 	if (hw->ops.llseek)
 		return hw->ops.llseek(hw, file, offset, orig);
 	return -ENXIO;
 }
 
-static ssize_t snd_hwdep_read(struct file * file, char __user *buf, size_t count, loff_t *offset)
+static ssize_t snd_hwdep_read(struct file * file, char __user *buf,
+			      size_t count, loff_t *offset)
 {
-	snd_hwdep_t *hw = file->private_data;
+	struct snd_hwdep *hw = file->private_data;
 	if (hw->ops.read)
 		return hw->ops.read(hw, buf, count, offset);
 	return -ENXIO;	
 }
 
-static ssize_t snd_hwdep_write(struct file * file, const char __user *buf, size_t count, loff_t *offset)
+static ssize_t snd_hwdep_write(struct file * file, const char __user *buf,
+			       size_t count, loff_t *offset)
 {
-	snd_hwdep_t *hw = file->private_data;
+	struct snd_hwdep *hw = file->private_data;
 	if (hw->ops.write)
 		return hw->ops.write(hw, buf, count, offset);
 	return -ENXIO;	
@@ -75,34 +86,25 @@
 static int snd_hwdep_open(struct inode *inode, struct file * file)
 {
 	int major = imajor(inode);
-	int cardnum;
-	int device;
-	snd_hwdep_t *hw;
+	struct snd_hwdep *hw;
 	int err;
 	wait_queue_t wait;
 
 	if (major == snd_major) {
-		cardnum = SNDRV_MINOR_CARD(iminor(inode));
-		device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP;
+		hw = snd_lookup_minor_data(iminor(inode),
+					   SNDRV_DEVICE_TYPE_HWDEP);
 #ifdef CONFIG_SND_OSSEMUL
 	} else if (major == SOUND_MAJOR) {
-		cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
-		device = 0;
+		hw = snd_lookup_oss_minor_data(iminor(inode),
+					       SNDRV_OSS_DEVICE_TYPE_DMFM);
 #endif
 	} else
 		return -ENXIO;
-	cardnum %= SNDRV_CARDS;
-	device %= SNDRV_MINOR_HWDEPS;
-	hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device];
 	if (hw == NULL)
 		return -ENODEV;
 
 	if (!hw->ops.open)
 		return -ENXIO;
-#ifdef CONFIG_SND_OSSEMUL
-	if (major == SOUND_MAJOR && hw->oss_type < 0)
-		return -ENXIO;
-#endif
 
 	if (!try_module_get(hw->card->module))
 		return -EFAULT;
@@ -154,7 +156,7 @@
 static int snd_hwdep_release(struct inode *inode, struct file * file)
 {
 	int err = -ENXIO;
-	snd_hwdep_t *hw = file->private_data;
+	struct snd_hwdep *hw = file->private_data;
 	down(&hw->open_mutex);
 	if (hw->ops.release) {
 		err = hw->ops.release(hw, file);
@@ -170,15 +172,16 @@
 
 static unsigned int snd_hwdep_poll(struct file * file, poll_table * wait)
 {
-	snd_hwdep_t *hw = file->private_data;
+	struct snd_hwdep *hw = file->private_data;
 	if (hw->ops.poll)
 		return hw->ops.poll(hw, file, wait);
 	return 0;
 }
 
-static int snd_hwdep_info(snd_hwdep_t *hw, snd_hwdep_info_t __user *_info)
+static int snd_hwdep_info(struct snd_hwdep *hw,
+			  struct snd_hwdep_info __user *_info)
 {
-	snd_hwdep_info_t info;
+	struct snd_hwdep_info info;
 	
 	memset(&info, 0, sizeof(info));
 	info.card = hw->card->number;
@@ -190,9 +193,10 @@
 	return 0;
 }
 
-static int snd_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t __user *_info)
+static int snd_hwdep_dsp_status(struct snd_hwdep *hw,
+				struct snd_hwdep_dsp_status __user *_info)
 {
-	snd_hwdep_dsp_status_t info;
+	struct snd_hwdep_dsp_status info;
 	int err;
 	
 	if (! hw->ops.dsp_status)
@@ -206,9 +210,10 @@
 	return 0;
 }
 
-static int snd_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t __user *_info)
+static int snd_hwdep_dsp_load(struct snd_hwdep *hw,
+			      struct snd_hwdep_dsp_image __user *_info)
 {
-	snd_hwdep_dsp_image_t info;
+	struct snd_hwdep_dsp_image info;
 	int err;
 	
 	if (! hw->ops.dsp_load)
@@ -228,9 +233,10 @@
 	return 0;
 }
 
-static long snd_hwdep_ioctl(struct file * file, unsigned int cmd, unsigned long arg)
+static long snd_hwdep_ioctl(struct file * file, unsigned int cmd,
+			    unsigned long arg)
 {
-	snd_hwdep_t *hw = file->private_data;
+	struct snd_hwdep *hw = file->private_data;
 	void __user *argp = (void __user *)arg;
 	switch (cmd) {
 	case SNDRV_HWDEP_IOCTL_PVERSION:
@@ -249,18 +255,16 @@
 
 static int snd_hwdep_mmap(struct file * file, struct vm_area_struct * vma)
 {
-	snd_hwdep_t *hw = file->private_data;
+	struct snd_hwdep *hw = file->private_data;
 	if (hw->ops.mmap)
 		return hw->ops.mmap(hw, file, vma);
 	return -ENXIO;
 }
 
-static int snd_hwdep_control_ioctl(snd_card_t * card, snd_ctl_file_t * control,
+static int snd_hwdep_control_ioctl(struct snd_card *card,
+				   struct snd_ctl_file * control,
 				   unsigned int cmd, unsigned long arg)
 {
-	unsigned int tmp;
-	
-	tmp = card->number * SNDRV_MINOR_HWDEPS;
 	switch (cmd) {
 	case SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE:
 		{
@@ -268,32 +272,36 @@
 
 			if (get_user(device, (int __user *)arg))
 				return -EFAULT;
+			down(&register_mutex);
 			device = device < 0 ? 0 : device + 1;
 			while (device < SNDRV_MINOR_HWDEPS) {
-				if (snd_hwdep_devices[tmp + device])
+				if (snd_hwdep_search(card, device))
 					break;
 				device++;
 			}
 			if (device >= SNDRV_MINOR_HWDEPS)
 				device = -1;
+			up(&register_mutex);
 			if (put_user(device, (int __user *)arg))
 				return -EFAULT;
 			return 0;
 		}
 	case SNDRV_CTL_IOCTL_HWDEP_INFO:
 		{
-			snd_hwdep_info_t __user *info = (snd_hwdep_info_t __user *)arg;
-			int device;
-			snd_hwdep_t *hwdep;
+			struct snd_hwdep_info __user *info = (struct snd_hwdep_info __user *)arg;
+			int device, err;
+			struct snd_hwdep *hwdep;
 
 			if (get_user(device, &info->device))
 				return -EFAULT;
-			if (device < 0 || device >= SNDRV_MINOR_HWDEPS)
-				return -ENXIO;
-			hwdep = snd_hwdep_devices[tmp + device];
-			if (hwdep == NULL)
-				return -ENXIO;
-			return snd_hwdep_info(hwdep, info);
+			down(&register_mutex);
+			hwdep = snd_hwdep_search(card, device);
+			if (hwdep)
+				err = snd_hwdep_info(hwdep, info);
+			else
+				err = -ENXIO;
+			up(&register_mutex);
+			return err;
 		}
 	}
 	return -ENOIOCTLCMD;
@@ -323,12 +331,6 @@
 	.mmap =		snd_hwdep_mmap,
 };
 
-static snd_minor_t snd_hwdep_reg =
-{
-	.comment =	"hardware dependent",
-	.f_ops =	&snd_hwdep_f_ops,
-};
-
 /**
  * snd_hwdep_new - create a new hwdep instance
  * @card: the card instance
@@ -342,11 +344,12 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_hwdep_new(snd_card_t * card, char *id, int device, snd_hwdep_t ** rhwdep)
+int snd_hwdep_new(struct snd_card *card, char *id, int device,
+		  struct snd_hwdep **rhwdep)
 {
-	snd_hwdep_t *hwdep;
+	struct snd_hwdep *hwdep;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_hwdep_dev_free,
 		.dev_register = snd_hwdep_dev_register,
 		.dev_unregister = snd_hwdep_dev_unregister
@@ -356,13 +359,14 @@
 	*rhwdep = NULL;
 	snd_assert(card != NULL, return -ENXIO);
 	hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
-	if (hwdep == NULL)
+	if (hwdep == NULL) {
+		snd_printk(KERN_ERR "hwdep: cannot allocate\n");
 		return -ENOMEM;
+	}
 	hwdep->card = card;
 	hwdep->device = device;
-	if (id) {
+	if (id)
 		strlcpy(hwdep->id, id, sizeof(hwdep->id));
-	}
 #ifdef CONFIG_SND_OSSEMUL
 	hwdep->oss_type = -1;
 #endif
@@ -376,7 +380,7 @@
 	return 0;
 }
 
-static int snd_hwdep_free(snd_hwdep_t *hwdep)
+static int snd_hwdep_free(struct snd_hwdep *hwdep)
 {
 	snd_assert(hwdep != NULL, return -ENXIO);
 	if (hwdep->private_free)
@@ -385,32 +389,31 @@
 	return 0;
 }
 
-static int snd_hwdep_dev_free(snd_device_t *device)
+static int snd_hwdep_dev_free(struct snd_device *device)
 {
-	snd_hwdep_t *hwdep = device->device_data;
+	struct snd_hwdep *hwdep = device->device_data;
 	return snd_hwdep_free(hwdep);
 }
 
-static int snd_hwdep_dev_register(snd_device_t *device)
+static int snd_hwdep_dev_register(struct snd_device *device)
 {
-	snd_hwdep_t *hwdep = device->device_data;
-	int idx, err;
+	struct snd_hwdep *hwdep = device->device_data;
+	int err;
 	char name[32];
 
 	down(&register_mutex);
-	idx = (hwdep->card->number * SNDRV_MINOR_HWDEPS) + hwdep->device;
-	if (snd_hwdep_devices[idx]) {
+	if (snd_hwdep_search(hwdep->card, hwdep->device)) {
 		up(&register_mutex);
 		return -EBUSY;
 	}
-	snd_hwdep_devices[idx] = hwdep;
+	list_add_tail(&hwdep->list, &snd_hwdep_devices);
 	sprintf(name, "hwC%iD%i", hwdep->card->number, hwdep->device);
 	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP,
 				       hwdep->card, hwdep->device,
-				       &snd_hwdep_reg, name)) < 0) {
+				       &snd_hwdep_f_ops, hwdep, name)) < 0) {
 		snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n",
 			   hwdep->card->number, hwdep->device);
-		snd_hwdep_devices[idx] = NULL;
+		list_del(&hwdep->list);
 		up(&register_mutex);
 		return err;
 	}
@@ -422,7 +425,8 @@
 		} else {
 			if (snd_register_oss_device(hwdep->oss_type,
 						    hwdep->card, hwdep->device,
-						    &snd_hwdep_reg, hwdep->oss_dev) < 0) {
+						    &snd_hwdep_f_ops, hwdep,
+						    hwdep->oss_dev) < 0) {
 				snd_printk(KERN_ERR "unable to register OSS compatibility device %i:%i\n",
 					   hwdep->card->number, hwdep->device);
 			} else
@@ -434,15 +438,13 @@
 	return 0;
 }
 
-static int snd_hwdep_dev_unregister(snd_device_t *device)
+static int snd_hwdep_dev_unregister(struct snd_device *device)
 {
-	snd_hwdep_t *hwdep = device->device_data;
-	int idx;
+	struct snd_hwdep *hwdep = device->device_data;
 
 	snd_assert(hwdep != NULL, return -ENXIO);
 	down(&register_mutex);
-	idx = (hwdep->card->number * SNDRV_MINOR_HWDEPS) + hwdep->device;
-	if (snd_hwdep_devices[idx] != hwdep) {
+	if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
 		up(&register_mutex);
 		return -EINVAL;
 	}
@@ -451,47 +453,39 @@
 		snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
 #endif
 	snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
-	snd_hwdep_devices[idx] = NULL;
+	list_del(&hwdep->list);
 	up(&register_mutex);
 	return snd_hwdep_free(hwdep);
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *  Info interface
  */
 
-static void snd_hwdep_proc_read(snd_info_entry_t *entry,
-				snd_info_buffer_t * buffer)
+static void snd_hwdep_proc_read(struct snd_info_entry *entry,
+				struct snd_info_buffer *buffer)
 {
-	int idx;
-	snd_hwdep_t *hwdep;
+	struct list_head *p;
+	struct snd_hwdep *hwdep;
 
 	down(&register_mutex);
-	for (idx = 0; idx < SNDRV_CARDS * SNDRV_MINOR_HWDEPS; idx++) {
-		hwdep = snd_hwdep_devices[idx];
-		if (hwdep == NULL)
-			continue;
+	list_for_each(p, &snd_hwdep_devices) {
+		hwdep = list_entry(p, struct snd_hwdep, list);
 		snd_iprintf(buffer, "%02i-%02i: %s\n",
-					idx / SNDRV_MINOR_HWDEPS,
-					idx % SNDRV_MINOR_HWDEPS,
-					hwdep->name);
+			    hwdep->card->number, hwdep->device, hwdep->name);
 	}
 	up(&register_mutex);
 }
 
-/*
- *  ENTRY functions
- */
+static struct snd_info_entry *snd_hwdep_proc_entry;
 
-static snd_info_entry_t *snd_hwdep_proc_entry = NULL;
-
-static int __init alsa_hwdep_init(void)
+static void __init snd_hwdep_proc_init(void)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
-	memset(snd_hwdep_devices, 0, sizeof(snd_hwdep_devices));
 	if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) {
-		entry->c.text.read_size = 512;
+		entry->c.text.read_size = PAGE_SIZE;
 		entry->c.text.read = snd_hwdep_proc_read;
 		if (snd_info_register(entry) < 0) {
 			snd_info_free_entry(entry);
@@ -499,6 +493,25 @@
 		}
 	}
 	snd_hwdep_proc_entry = entry;
+}
+
+static void __exit snd_hwdep_proc_done(void)
+{
+	snd_info_unregister(snd_hwdep_proc_entry);
+}
+#else /* !CONFIG_PROC_FS */
+#define snd_hwdep_proc_init()
+#define snd_hwdep_proc_done()
+#endif /* CONFIG_PROC_FS */
+
+
+/*
+ *  ENTRY functions
+ */
+
+static int __init alsa_hwdep_init(void)
+{
+	snd_hwdep_proc_init();
 	snd_ctl_register_ioctl(snd_hwdep_control_ioctl);
 	snd_ctl_register_ioctl_compat(snd_hwdep_control_ioctl);
 	return 0;
@@ -508,10 +521,7 @@
 {
 	snd_ctl_unregister_ioctl(snd_hwdep_control_ioctl);
 	snd_ctl_unregister_ioctl_compat(snd_hwdep_control_ioctl);
-	if (snd_hwdep_proc_entry) {
-		snd_info_unregister(snd_hwdep_proc_entry);
-		snd_hwdep_proc_entry = NULL;
-	}
+	snd_hwdep_proc_done();
 }
 
 module_init(alsa_hwdep_init)
diff --git a/sound/core/hwdep_compat.c b/sound/core/hwdep_compat.c
index 6866f42..938f775 100644
--- a/sound/core/hwdep_compat.c
+++ b/sound/core/hwdep_compat.c
@@ -22,7 +22,7 @@
 
 #include <linux/compat.h>
 
-struct sndrv_hwdep_dsp_image32 {
+struct snd_hwdep_dsp_image32 {
 	u32 index;
 	unsigned char name[64];
 	u32 image;	/* pointer */
@@ -30,10 +30,10 @@
 	u32 driver_data;
 } /* don't set packed attribute here */;
 
-static int snd_hwdep_dsp_load_compat(snd_hwdep_t *hw,
-				     struct sndrv_hwdep_dsp_image32 __user *src)
+static int snd_hwdep_dsp_load_compat(struct snd_hwdep *hw,
+				     struct snd_hwdep_dsp_image32 __user *src)
 {
-	struct sndrv_hwdep_dsp_image *dst;
+	struct snd_hwdep_dsp_image *dst;
 	compat_caddr_t ptr;
 	u32 val;
 
@@ -56,12 +56,13 @@
 }
 
 enum {
-	SNDRV_HWDEP_IOCTL_DSP_LOAD32   = _IOW('H', 0x03, struct sndrv_hwdep_dsp_image32)
+	SNDRV_HWDEP_IOCTL_DSP_LOAD32   = _IOW('H', 0x03, struct snd_hwdep_dsp_image32)
 };
 
-static long snd_hwdep_ioctl_compat(struct file * file, unsigned int cmd, unsigned long arg)
+static long snd_hwdep_ioctl_compat(struct file * file, unsigned int cmd,
+				   unsigned long arg)
 {
-	snd_hwdep_t *hw = file->private_data;
+	struct snd_hwdep *hw = file->private_data;
 	void __user *argp = compat_ptr(arg);
 	switch (cmd) {
 	case SNDRV_HWDEP_IOCTL_PVERSION:
diff --git a/sound/core/info.c b/sound/core/info.c
index 39f9b97..ae88539 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -37,6 +37,8 @@
  *
  */
 
+#ifdef CONFIG_PROC_FS
+
 int snd_info_check_reserved_words(const char *str)
 {
 	static char *reserved[] =
@@ -66,16 +68,14 @@
 	return 1;
 }
 
-#ifdef CONFIG_PROC_FS
-
 static DECLARE_MUTEX(info_mutex);
 
-typedef struct _snd_info_private_data {
-	snd_info_buffer_t *rbuffer;
-	snd_info_buffer_t *wbuffer;
-	snd_info_entry_t *entry;
+struct snd_info_private_data {
+	struct snd_info_buffer *rbuffer;
+	struct snd_info_buffer *wbuffer;
+	struct snd_info_entry *entry;
 	void *file_private_data;
-} snd_info_private_data_t;
+};
 
 static int snd_info_version_init(void);
 static int snd_info_version_done(void);
@@ -90,7 +90,7 @@
  *
  * Returns the size of output string.
  */
-int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
+int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...)
 {
 	va_list args;
 	int len, res;
@@ -115,9 +115,9 @@
  */
 
 static struct proc_dir_entry *snd_proc_root = NULL;
-snd_info_entry_t *snd_seq_root = NULL;
+struct snd_info_entry *snd_seq_root = NULL;
 #ifdef CONFIG_SND_OSSEMUL
-snd_info_entry_t *snd_oss_root = NULL;
+struct snd_info_entry *snd_oss_root = NULL;
 #endif
 
 static inline void snd_info_entry_prepare(struct proc_dir_entry *de)
@@ -134,7 +134,7 @@
 
 static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
 {
-	snd_info_private_data_t *data;
+	struct snd_info_private_data *data;
 	struct snd_info_entry *entry;
 	loff_t ret;
 
@@ -176,9 +176,9 @@
 static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
 				   size_t count, loff_t * offset)
 {
-	snd_info_private_data_t *data;
+	struct snd_info_private_data *data;
 	struct snd_info_entry *entry;
-	snd_info_buffer_t *buf;
+	struct snd_info_buffer *buf;
 	size_t size = 0;
 	loff_t pos;
 
@@ -217,9 +217,9 @@
 static ssize_t snd_info_entry_write(struct file *file, const char __user *buffer,
 				    size_t count, loff_t * offset)
 {
-	snd_info_private_data_t *data;
+	struct snd_info_private_data *data;
 	struct snd_info_entry *entry;
-	snd_info_buffer_t *buf;
+	struct snd_info_buffer *buf;
 	size_t size = 0;
 	loff_t pos;
 
@@ -259,15 +259,15 @@
 
 static int snd_info_entry_open(struct inode *inode, struct file *file)
 {
-	snd_info_entry_t *entry;
-	snd_info_private_data_t *data;
-	snd_info_buffer_t *buffer;
+	struct snd_info_entry *entry;
+	struct snd_info_private_data *data;
+	struct snd_info_buffer *buffer;
 	struct proc_dir_entry *p;
 	int mode, err;
 
 	down(&info_mutex);
 	p = PDE(inode);
-	entry = p == NULL ? NULL : (snd_info_entry_t *)p->data;
+	entry = p == NULL ? NULL : (struct snd_info_entry *)p->data;
 	if (entry == NULL || entry->disconnected) {
 		up(&info_mutex);
 		return -ENODEV;
@@ -381,8 +381,8 @@
 
 static int snd_info_entry_release(struct inode *inode, struct file *file)
 {
-	snd_info_entry_t *entry;
-	snd_info_private_data_t *data;
+	struct snd_info_entry *entry;
+	struct snd_info_private_data *data;
 	int mode;
 
 	mode = file->f_flags & O_ACCMODE;
@@ -420,7 +420,7 @@
 
 static unsigned int snd_info_entry_poll(struct file *file, poll_table * wait)
 {
-	snd_info_private_data_t *data;
+	struct snd_info_private_data *data;
 	struct snd_info_entry *entry;
 	unsigned int mask;
 
@@ -447,7 +447,7 @@
 static inline int _snd_info_entry_ioctl(struct inode *inode, struct file *file,
 					unsigned int cmd, unsigned long arg)
 {
-	snd_info_private_data_t *data;
+	struct snd_info_private_data *data;
 	struct snd_info_entry *entry;
 
 	data = file->private_data;
@@ -479,7 +479,7 @@
 static int snd_info_entry_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	struct inode *inode = file->f_dentry->d_inode;
-	snd_info_private_data_t *data;
+	struct snd_info_private_data *data;
 	struct snd_info_entry *entry;
 
 	data = file->private_data;
@@ -541,7 +541,7 @@
 	snd_proc_root = p;
 #ifdef CONFIG_SND_OSSEMUL
 	{
-		snd_info_entry_t *entry;
+		struct snd_info_entry *entry;
 		if ((entry = snd_info_create_module_entry(THIS_MODULE, "oss", NULL)) == NULL)
 			return -ENOMEM;
 		entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
@@ -554,7 +554,7 @@
 #endif
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
 	{
-		snd_info_entry_t *entry;
+		struct snd_info_entry *entry;
 		if ((entry = snd_info_create_module_entry(THIS_MODULE, "seq", NULL)) == NULL)
 			return -ENOMEM;
 		entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
@@ -580,12 +580,10 @@
 	snd_info_version_done();
 	if (snd_proc_root) {
 #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
-		if (snd_seq_root)
-			snd_info_unregister(snd_seq_root);
+		snd_info_unregister(snd_seq_root);
 #endif
 #ifdef CONFIG_SND_OSSEMUL
-		if (snd_oss_root)
-			snd_info_unregister(snd_oss_root);
+		snd_info_unregister(snd_oss_root);
 #endif
 		snd_remove_proc_entry(&proc_root, snd_proc_root);
 	}
@@ -601,10 +599,10 @@
  * create a card proc file
  * called from init.c
  */
-int snd_info_card_create(snd_card_t * card)
+int snd_info_card_create(struct snd_card *card)
 {
 	char str[8];
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	snd_assert(card != NULL, return -ENXIO);
 
@@ -624,7 +622,7 @@
  * register the card proc file
  * called from init.c
  */
-int snd_info_card_register(snd_card_t * card)
+int snd_info_card_register(struct snd_card *card)
 {
 	struct proc_dir_entry *p;
 
@@ -644,7 +642,7 @@
  * de-register the card proc file
  * called from init.c
  */
-int snd_info_card_free(snd_card_t * card)
+int snd_info_card_free(struct snd_card *card)
 {
 	snd_assert(card != NULL, return -ENXIO);
 	if (card->proc_root_link) {
@@ -669,7 +667,7 @@
  *
  * Returns zero if successful, or 1 if error or EOF.
  */
-int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len)
+int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len)
 {
 	int c = -1;
 
@@ -747,9 +745,9 @@
  *
  * Returns the pointer of the new instance, or NULL on failure.
  */
-static snd_info_entry_t *snd_info_create_entry(const char *name)
+static struct snd_info_entry *snd_info_create_entry(const char *name)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 	if (entry == NULL)
 		return NULL;
@@ -774,11 +772,11 @@
  *
  * Returns the pointer of the new instance, or NULL on failure.
  */
-snd_info_entry_t *snd_info_create_module_entry(struct module * module,
+struct snd_info_entry *snd_info_create_module_entry(struct module * module,
 					       const char *name,
-					       snd_info_entry_t *parent)
+					       struct snd_info_entry *parent)
 {
-	snd_info_entry_t *entry = snd_info_create_entry(name);
+	struct snd_info_entry *entry = snd_info_create_entry(name);
 	if (entry) {
 		entry->module = module;
 		entry->parent = parent;
@@ -796,11 +794,11 @@
  *
  * Returns the pointer of the new instance, or NULL on failure.
  */
-snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card,
+struct snd_info_entry *snd_info_create_card_entry(struct snd_card *card,
 					     const char *name,
-					     snd_info_entry_t * parent)
+					     struct snd_info_entry * parent)
 {
-	snd_info_entry_t *entry = snd_info_create_entry(name);
+	struct snd_info_entry *entry = snd_info_create_entry(name);
 	if (entry) {
 		entry->module = card->module;
 		entry->card = card;
@@ -809,29 +807,29 @@
 	return entry;
 }
 
-static int snd_info_dev_free_entry(snd_device_t *device)
+static int snd_info_dev_free_entry(struct snd_device *device)
 {
-	snd_info_entry_t *entry = device->device_data;
+	struct snd_info_entry *entry = device->device_data;
 	snd_info_free_entry(entry);
 	return 0;
 }
 
-static int snd_info_dev_register_entry(snd_device_t *device)
+static int snd_info_dev_register_entry(struct snd_device *device)
 {
-	snd_info_entry_t *entry = device->device_data;
+	struct snd_info_entry *entry = device->device_data;
 	return snd_info_register(entry);
 }
 
-static int snd_info_dev_disconnect_entry(snd_device_t *device)
+static int snd_info_dev_disconnect_entry(struct snd_device *device)
 {
-	snd_info_entry_t *entry = device->device_data;
+	struct snd_info_entry *entry = device->device_data;
 	entry->disconnected = 1;
 	return 0;
 }
 
-static int snd_info_dev_unregister_entry(snd_device_t *device)
+static int snd_info_dev_unregister_entry(struct snd_device *device)
 {
-	snd_info_entry_t *entry = device->device_data;
+	struct snd_info_entry *entry = device->device_data;
 	return snd_info_unregister(entry);
 }
 
@@ -855,16 +853,16 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_card_proc_new(snd_card_t *card, const char *name,
-		      snd_info_entry_t **entryp)
+int snd_card_proc_new(struct snd_card *card, const char *name,
+		      struct snd_info_entry **entryp)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_info_dev_free_entry,
 		.dev_register =	snd_info_dev_register_entry,
 		.dev_disconnect = snd_info_dev_disconnect_entry,
 		.dev_unregister = snd_info_dev_unregister_entry
 	};
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	int err;
 
 	entry = snd_info_create_card_entry(card, name, card->proc_root);
@@ -885,7 +883,7 @@
  *
  * Releases the info entry.  Don't call this after registered.
  */
-void snd_info_free_entry(snd_info_entry_t * entry)
+void snd_info_free_entry(struct snd_info_entry * entry)
 {
 	if (entry == NULL)
 		return;
@@ -903,7 +901,7 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_info_register(snd_info_entry_t * entry)
+int snd_info_register(struct snd_info_entry * entry)
 {
 	struct proc_dir_entry *root, *p = NULL;
 
@@ -933,11 +931,12 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_info_unregister(snd_info_entry_t * entry)
+int snd_info_unregister(struct snd_info_entry * entry)
 {
 	struct proc_dir_entry *root;
 
-	snd_assert(entry != NULL, return -ENXIO);
+	if (! entry)
+		return 0;
 	snd_assert(entry->p != NULL, return -ENXIO);
 	root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
 	snd_assert(root, return -ENXIO);
@@ -952,9 +951,9 @@
 
  */
 
-static snd_info_entry_t *snd_info_version_entry = NULL;
+static struct snd_info_entry *snd_info_version_entry = NULL;
 
-static void snd_info_version_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
 	snd_iprintf(buffer,
 		    "Advanced Linux Sound Architecture Driver Version "
@@ -964,7 +963,7 @@
 
 static int __init snd_info_version_init(void)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	entry = snd_info_create_module_entry(THIS_MODULE, "version", NULL);
 	if (entry == NULL)
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index 1210796..820f477 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -37,7 +37,7 @@
 
 static DECLARE_MUTEX(strings);
 static char *snd_sndstat_strings[SNDRV_CARDS][SNDRV_OSS_INFO_DEV_COUNT];
-static snd_info_entry_t *snd_sndstat_proc_entry;
+static struct snd_info_entry *snd_sndstat_proc_entry;
 
 int snd_oss_info_register(int dev, int num, char *string)
 {
@@ -63,9 +63,9 @@
 	return 0;
 }
 
-extern void snd_card_info_read_oss(snd_info_buffer_t * buffer);
+extern void snd_card_info_read_oss(struct snd_info_buffer *buffer);
 
-static int snd_sndstat_show_strings(snd_info_buffer_t * buf, char *id, int dev)
+static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int dev)
 {
 	int idx, ok = -1;
 	char *str;
@@ -88,7 +88,8 @@
 	return ok;
 }
 
-static void snd_sndstat_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void snd_sndstat_proc_read(struct snd_info_entry *entry,
+				  struct snd_info_buffer *buffer)
 {
 	snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA v" CONFIG_SND_VERSION " emulation code)\n");
 	snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n",
@@ -111,7 +112,7 @@
 
 int snd_info_minor_register(void)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	memset(snd_sndstat_strings, 0, sizeof(snd_sndstat_strings));
 	if ((entry = snd_info_create_module_entry(THIS_MODULE, "sndstat", snd_oss_root)) != NULL) {
diff --git a/sound/core/init.c b/sound/core/init.c
index 33813f9..7581668 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -28,7 +28,6 @@
 #include <linux/ctype.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
-#include <linux/platform_device.h>
 
 #include <sound/core.h>
 #include <sound/control.h>
@@ -40,18 +39,46 @@
 };
 
 unsigned int snd_cards_lock = 0;	/* locked for registering/using */
-snd_card_t *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL};
+struct snd_card *snd_cards[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = NULL};
 DEFINE_RWLOCK(snd_card_rwlock);
 
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
-int (*snd_mixer_oss_notify_callback)(snd_card_t *card, int free_flag);
+int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int free_flag);
 #endif
 
-static void snd_card_id_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+#ifdef CONFIG_PROC_FS
+static void snd_card_id_read(struct snd_info_entry *entry,
+			     struct snd_info_buffer *buffer)
 {
 	snd_iprintf(buffer, "%s\n", entry->card->id);
 }
 
+static inline int init_info_for_card(struct snd_card *card)
+{
+	int err;
+	struct snd_info_entry *entry;
+
+	if ((err = snd_info_card_register(card)) < 0) {
+		snd_printd("unable to create card info\n");
+		return err;
+	}
+	if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
+		snd_printd("unable to create card entry\n");
+		return err;
+	}
+	entry->c.text.read_size = PAGE_SIZE;
+	entry->c.text.read = snd_card_id_read;
+	if (snd_info_register(entry) < 0) {
+		snd_info_free_entry(entry);
+		entry = NULL;
+	}
+	card->proc_id = entry;
+	return 0;
+}
+#else /* !CONFIG_PROC_FS */
+#define init_info_for_card(card)
+#endif
+
 static void snd_card_free_thread(void * __card);
 
 /**
@@ -63,13 +90,13 @@
  *
  *  Creates and initializes a soundcard structure.
  *
- *  Returns kmallocated snd_card_t structure. Creates the ALSA control interface
+ *  Returns kmallocated snd_card structure. Creates the ALSA control interface
  *  (which is blocked until snd_card_register function is called).
  */
-snd_card_t *snd_card_new(int idx, const char *xid,
+struct snd_card *snd_card_new(int idx, const char *xid,
 			 struct module *module, int extra_size)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	int err;
 
 	if (extra_size < 0)
@@ -132,7 +159,7 @@
 		goto __error_ctl;
 	}
 	if (extra_size > 0)
-		card->private_data = (char *)card + sizeof(snd_card_t);
+		card->private_data = (char *)card + sizeof(struct snd_card);
 	return card;
 
       __error_ctl:
@@ -158,7 +185,7 @@
  *  Note: The current implementation replaces all active file->f_op with special
  *        dummy file operations (they do nothing except release).
  */
-int snd_card_disconnect(snd_card_t * card)
+int snd_card_disconnect(struct snd_card *card)
 {
 	struct snd_monitor_file *mfile;
 	struct file *file;
@@ -228,12 +255,6 @@
 	return 0;	
 }
 
-#ifdef CONFIG_SND_GENERIC_DRIVER
-static void snd_generic_device_unregister(snd_card_t *card);
-#else
-#define snd_generic_device_unregister(x) /*NOP*/
-#endif
-
 /**
  *  snd_card_free - frees given soundcard structure
  *  @card: soundcard structure
@@ -245,7 +266,7 @@
  *  Returns zero. Frees all associated devices and frees the control
  *  interface associated to given soundcard.
  */
-int snd_card_free(snd_card_t * card)
+int snd_card_free(struct snd_card *card)
 {
 	struct snd_shutdown_f_ops *s_f_ops;
 
@@ -279,13 +300,11 @@
 	}
 	if (card->private_free)
 		card->private_free(card);
-	if (card->proc_id)
-		snd_info_unregister(card->proc_id);
+	snd_info_unregister(card->proc_id);
 	if (snd_info_card_free(card) < 0) {
 		snd_printk(KERN_WARNING "unable to free card info\n");
 		/* Not fatal error */
 	}
-	snd_generic_device_unregister(card);
 	while (card->s_f_ops) {
 		s_f_ops = card->s_f_ops;
 		card->s_f_ops = s_f_ops->next;
@@ -300,7 +319,7 @@
 
 static void snd_card_free_thread(void * __card)
 {
-	snd_card_t *card = __card;
+	struct snd_card *card = __card;
 	struct module * module = card->module;
 
 	if (!try_module_get(module)) {
@@ -327,7 +346,7 @@
  *  
  *  Returns - zero otherwise a negative error code if the start of thread failed.
  */
-int snd_card_free_in_thread(snd_card_t * card)
+int snd_card_free_in_thread(struct snd_card *card)
 {
 	if (card->files == NULL) {
 		snd_card_free(card);
@@ -343,9 +362,9 @@
 	return -EFAULT;
 }
 
-static void choose_default_id(snd_card_t * card)
+static void choose_default_id(struct snd_card *card)
 {
-	int i, len, idx_flag = 0, loops = 8;
+	int i, len, idx_flag = 0, loops = SNDRV_CARDS;
 	char *id, *spos;
 	
 	id = spos = card->shortname;	
@@ -387,9 +406,12 @@
 
 	      __change:
 		len = strlen(id);
-		if (idx_flag)
-			id[len-1]++;
-		else if ((size_t)len <= sizeof(card->id) - 3) {
+		if (idx_flag) {
+			if (id[len-1] != '9')
+				id[len-1]++;
+			else
+				id[len-1] = 'A';
+		} else if ((size_t)len <= sizeof(card->id) - 3) {
 			strcat(id, "_1");
 			idx_flag++;
 		} else {
@@ -415,10 +437,9 @@
  *
  *  Returns zero otherwise a negative error code if the registrain failed.
  */
-int snd_card_register(snd_card_t * card)
+int snd_card_register(struct snd_card *card)
 {
 	int err;
-	snd_info_entry_t *entry;
 
 	snd_assert(card != NULL, return -EINVAL);
 	if ((err = snd_device_register_all(card)) < 0)
@@ -433,22 +454,7 @@
 		choose_default_id(card);
 	snd_cards[card->number] = card;
 	write_unlock(&snd_card_rwlock);
-	if ((err = snd_info_card_register(card)) < 0) {
-		snd_printd("unable to create card info\n");
-		goto __skip_info;
-	}
-	if ((entry = snd_info_create_card_entry(card, "id", card->proc_root)) == NULL) {
-		snd_printd("unable to create card entry\n");
-		goto __skip_info;
-	}
-	entry->c.text.read_size = PAGE_SIZE;
-	entry->c.text.read = snd_card_id_read;
-	if (snd_info_register(entry) < 0) {
-		snd_info_free_entry(entry);
-		entry = NULL;
-	}
-	card->proc_id = entry;
-      __skip_info:
+	init_info_for_card(card);
 #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
 	if (snd_mixer_oss_notify_callback)
 		snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
@@ -456,23 +462,25 @@
 	return 0;
 }
 
-static snd_info_entry_t *snd_card_info_entry = NULL;
+#ifdef CONFIG_PROC_FS
+static struct snd_info_entry *snd_card_info_entry = NULL;
 
-static void snd_card_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void snd_card_info_read(struct snd_info_entry *entry,
+			       struct snd_info_buffer *buffer)
 {
 	int idx, count;
-	snd_card_t *card;
+	struct snd_card *card;
 
 	for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
 		read_lock(&snd_card_rwlock);
 		if ((card = snd_cards[idx]) != NULL) {
 			count++;
-			snd_iprintf(buffer, "%i [%-15s]: %s - %s\n",
+			snd_iprintf(buffer, "%2i [%-15s]: %s - %s\n",
 					idx,
 					card->id,
 					card->driver,
 					card->shortname);
-			snd_iprintf(buffer, "                     %s\n",
+			snd_iprintf(buffer, "                      %s\n",
 					card->longname);
 		}
 		read_unlock(&snd_card_rwlock);
@@ -481,12 +489,12 @@
 		snd_iprintf(buffer, "--- no soundcards ---\n");
 }
 
-#if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_PROC_FS)
+#ifdef CONFIG_SND_OSSEMUL
 
-void snd_card_info_read_oss(snd_info_buffer_t * buffer)
+void snd_card_info_read_oss(struct snd_info_buffer *buffer)
 {
 	int idx, count;
-	snd_card_t *card;
+	struct snd_card *card;
 
 	for (idx = count = 0; idx < SNDRV_CARDS; idx++) {
 		read_lock(&snd_card_rwlock);
@@ -504,16 +512,18 @@
 #endif
 
 #ifdef MODULE
-static snd_info_entry_t *snd_card_module_info_entry;
-static void snd_card_module_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static struct snd_info_entry *snd_card_module_info_entry;
+static void snd_card_module_info_read(struct snd_info_entry *entry,
+				      struct snd_info_buffer *buffer)
 {
 	int idx;
-	snd_card_t *card;
+	struct snd_card *card;
 
 	for (idx = 0; idx < SNDRV_CARDS; idx++) {
 		read_lock(&snd_card_rwlock);
 		if ((card = snd_cards[idx]) != NULL)
-			snd_iprintf(buffer, "%i %s\n", idx, card->module->name);
+			snd_iprintf(buffer, "%2i %s\n",
+				    idx, card->module->name);
 		read_unlock(&snd_card_rwlock);
 	}
 }
@@ -521,7 +531,7 @@
 
 int __init snd_card_info_init(void)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
 	if (! entry)
@@ -551,15 +561,15 @@
 
 int __exit snd_card_info_done(void)
 {
-	if (snd_card_info_entry)
-		snd_info_unregister(snd_card_info_entry);
+	snd_info_unregister(snd_card_info_entry);
 #ifdef MODULE
-	if (snd_card_module_info_entry)
-		snd_info_unregister(snd_card_module_info_entry);
+	snd_info_unregister(snd_card_module_info_entry);
 #endif
 	return 0;
 }
 
+#endif /* CONFIG_PROC_FS */
+
 /**
  *  snd_component_add - add a component string
  *  @card: soundcard structure
@@ -571,7 +581,7 @@
  *  Returns zero otherwise a negative error code.
  */
   
-int snd_component_add(snd_card_t *card, const char *component)
+int snd_component_add(struct snd_card *card, const char *component)
 {
 	char *ptr;
 	int len = strlen(component);
@@ -602,7 +612,7 @@
  *
  *  Returns zero or a negative error code.
  */
-int snd_card_file_add(snd_card_t *card, struct file *file)
+int snd_card_file_add(struct snd_card *card, struct file *file)
 {
 	struct snd_monitor_file *mfile;
 
@@ -636,7 +646,7 @@
  *
  *  Returns zero or a negative error code.
  */
-int snd_card_file_remove(snd_card_t *card, struct file *file)
+int snd_card_file_remove(struct snd_card *card, struct file *file)
 {
 	struct snd_monitor_file *mfile, *pfile = NULL;
 
@@ -664,97 +674,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_SND_GENERIC_DRIVER
-/*
- * generic device without a proper bus using platform_device
- * (e.g. ISA)
- */
-struct snd_generic_device {
-	struct platform_device pdev;
-	snd_card_t *card;
-};
-
-#define get_snd_generic_card(dev)	container_of(dev, struct snd_generic_device, pdev)->card
-
-#define SND_GENERIC_NAME	"snd_generic"
-
-#ifdef CONFIG_PM
-static int snd_generic_suspend(struct platform_device *dev, pm_message_t state);
-static int snd_generic_resume(struct platform_device *dev);
-#endif
-
-/* initialized in sound.c */
-struct platform_driver snd_generic_driver = {
-#ifdef CONFIG_PM
-	.suspend	= snd_generic_suspend,
-	.resume		= snd_generic_resume,
-#endif
-	.driver		= {
-		.name	= SND_GENERIC_NAME,
-	},
-};
-
-void snd_generic_device_release(struct device *dev)
-{
-}
-
-static int snd_generic_device_register(snd_card_t *card)
-{
-	struct snd_generic_device *dev;
-	int err;
-
-	if (card->generic_dev)
-		return 0; /* already registered */
-
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (! dev) {
-		snd_printk(KERN_ERR "can't allocate generic_device\n");
-		return -ENOMEM;
-	}
-
-	dev->pdev.name = SND_GENERIC_NAME;
-	dev->pdev.id = card->number;
-	dev->pdev.dev.release = snd_generic_device_release;
-	dev->card = card;
-	if ((err = platform_device_register(&dev->pdev)) < 0) {
-		kfree(dev);
-		return err;
-	}
-	card->generic_dev = dev;
-	return 0;
-}
-
-static void snd_generic_device_unregister(snd_card_t *card)
-{
-	struct snd_generic_device *dev = card->generic_dev;
-	if (dev) {
-		platform_device_unregister(&dev->pdev);
-		kfree(dev);
-		card->generic_dev = NULL;
-	}
-}
-
-/**
- * snd_card_set_generic_dev - assign the generic device to the card
- * @card: soundcard structure
- *
- * Assigns a generic device to the card.  This function is provided as the
- * last resort, for devices without any proper bus.  Thus this won't override
- * the device already assigned to the card.
- * 
- * Returns zero if successful, or a negative error code.
- */
-int snd_card_set_generic_dev(snd_card_t *card)
-{
-	int err;
-	if ((err = snd_generic_device_register(card)) < 0)
-		return err;
-	if (! card->dev)
-		snd_card_set_dev(card, &card->generic_dev->pdev.dev);
-	return 0;
-}
-#endif /* CONFIG_SND_GENERIC_DRIVER */
-
 #ifdef CONFIG_PM
 /**
  *  snd_power_wait - wait until the power-state is changed.
@@ -766,7 +685,7 @@
  *
  *  Note: the power lock must be active before call.
  */
-int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file)
+int snd_power_wait(struct snd_card *card, unsigned int power_state, struct file *file)
 {
 	wait_queue_t wait;
 	int result = 0;
@@ -798,107 +717,4 @@
 	return result;
 }
 
-/**
- * snd_card_set_pm_callback - set the PCI power-management callbacks
- * @card: soundcard structure
- * @suspend: suspend callback function
- * @resume: resume callback function
- * @private_data: private data to pass to the callback functions
- *
- * Sets the power-management callback functions of the card.
- * These callbacks are called from ALSA's common PCI suspend/resume
- * handler and from the control API.
- */
-int snd_card_set_pm_callback(snd_card_t *card,
-			     int (*suspend)(snd_card_t *, pm_message_t),
-			     int (*resume)(snd_card_t *),
-			     void *private_data)
-{
-	card->pm_suspend = suspend;
-	card->pm_resume = resume;
-	card->pm_private_data = private_data;
-	return 0;
-}
-
-#ifdef CONFIG_SND_GENERIC_DRIVER
-/* suspend/resume callbacks for snd_generic platform device */
-static int snd_generic_suspend(struct platform_device *dev, pm_message_t state)
-{
-	snd_card_t *card;
-
-	card = get_snd_generic_card(dev);
-	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		return 0;
-	if (card->pm_suspend)
-		card->pm_suspend(card, PMSG_SUSPEND);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-	return 0;
-}
-
-static int snd_generic_resume(struct platform_device *dev)
-{
-	snd_card_t *card;
-
-	card = get_snd_generic_card(dev);
-	if (card->power_state == SNDRV_CTL_POWER_D0)
-		return 0;
-	if (card->pm_resume)
-		card->pm_resume(card);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-	return 0;
-}
-
-/**
- * snd_card_set_generic_pm_callback - set the generic power-management callbacks
- * @card: soundcard structure
- * @suspend: suspend callback function
- * @resume: resume callback function
- * @private_data: private data to pass to the callback functions
- *
- * Registers the power-management and sets the lowlevel callbacks for
- * the given card.  These callbacks are called from the ALSA's common
- * PM handler and from the control API.
- */
-int snd_card_set_generic_pm_callback(snd_card_t *card,
-				 int (*suspend)(snd_card_t *, pm_message_t),
-				 int (*resume)(snd_card_t *),
-				 void *private_data)
-{
-	int err;
-	if ((err = snd_generic_device_register(card)) < 0)
-		return err;
-	return snd_card_set_pm_callback(card, suspend, resume, private_data);
-}
-#endif /* CONFIG_SND_GENERIC_DRIVER */
-
-#ifdef CONFIG_PCI
-int snd_card_pci_suspend(struct pci_dev *dev, pm_message_t state)
-{
-	snd_card_t *card = pci_get_drvdata(dev);
-	int err;
-	if (! card || ! card->pm_suspend)
-		return 0;
-	if (card->power_state == SNDRV_CTL_POWER_D3hot)
-		return 0;
-	err = card->pm_suspend(card, PMSG_SUSPEND);
-	pci_save_state(dev);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
-	return err;
-}
-
-int snd_card_pci_resume(struct pci_dev *dev)
-{
-	snd_card_t *card = pci_get_drvdata(dev);
-	if (! card || ! card->pm_resume)
-		return 0;
-	if (card->power_state == SNDRV_CTL_POWER_D0)
-		return 0;
-	/* restore the PCI config space */
-	pci_restore_state(dev);
-	card->pm_resume(card);
-	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
-	return 0;
-}
-#endif
-
 #endif /* CONFIG_PM */
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index e4b8959..19b3dcb 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -43,10 +43,6 @@
 MODULE_LICENSE("GPL");
 
 
-#ifndef SNDRV_CARDS
-#define SNDRV_CARDS	8
-#endif
-
 /*
  */
 
diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c
index edecbe7..d6a04c2 100644
--- a/sound/core/oss/copy.c
+++ b/sound/core/oss/copy.c
@@ -25,9 +25,9 @@
 #include <sound/pcm.h>
 #include "pcm_plugin.h"
 
-static snd_pcm_sframes_t copy_transfer(snd_pcm_plugin_t *plugin,
-			     const snd_pcm_plugin_channel_t *src_channels,
-			     snd_pcm_plugin_channel_t *dst_channels,
+static snd_pcm_sframes_t copy_transfer(struct snd_pcm_plugin *plugin,
+			     const struct snd_pcm_plugin_channel *src_channels,
+			     struct snd_pcm_plugin_channel *dst_channels,
 			     snd_pcm_uframes_t frames)
 {
 	unsigned int channel;
@@ -58,13 +58,13 @@
 	return frames;
 }
 
-int snd_pcm_plugin_build_copy(snd_pcm_plug_t *plug,
-			      snd_pcm_plugin_format_t *src_format,
-			      snd_pcm_plugin_format_t *dst_format,
-			      snd_pcm_plugin_t **r_plugin)
+int snd_pcm_plugin_build_copy(struct snd_pcm_substream *plug,
+			      struct snd_pcm_plugin_format *src_format,
+			      struct snd_pcm_plugin_format *dst_format,
+			      struct snd_pcm_plugin **r_plugin)
 {
 	int err;
-	snd_pcm_plugin_t *plugin;
+	struct snd_pcm_plugin *plugin;
 	int width;
 
 	snd_assert(r_plugin != NULL, return -ENXIO);
diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c
index bb1c99a..322702e 100644
--- a/sound/core/oss/io.c
+++ b/sound/core/oss/io.c
@@ -35,9 +35,9 @@
  *  Basic io plugin
  */
  
-static snd_pcm_sframes_t io_playback_transfer(snd_pcm_plugin_t *plugin,
-				    const snd_pcm_plugin_channel_t *src_channels,
-				    snd_pcm_plugin_channel_t *dst_channels ATTRIBUTE_UNUSED,
+static snd_pcm_sframes_t io_playback_transfer(struct snd_pcm_plugin *plugin,
+				    const struct snd_pcm_plugin_channel *src_channels,
+				    struct snd_pcm_plugin_channel *dst_channels,
 				    snd_pcm_uframes_t frames)
 {
 	snd_assert(plugin != NULL, return -ENXIO);
@@ -58,9 +58,9 @@
 	}
 }
  
-static snd_pcm_sframes_t io_capture_transfer(snd_pcm_plugin_t *plugin,
-				   const snd_pcm_plugin_channel_t *src_channels ATTRIBUTE_UNUSED,
-				   snd_pcm_plugin_channel_t *dst_channels,
+static snd_pcm_sframes_t io_capture_transfer(struct snd_pcm_plugin *plugin,
+				   const struct snd_pcm_plugin_channel *src_channels,
+				   struct snd_pcm_plugin_channel *dst_channels,
 				   snd_pcm_uframes_t frames)
 {
 	snd_assert(plugin != NULL, return -ENXIO);
@@ -82,13 +82,13 @@
 	return 0;
 }
  
-static snd_pcm_sframes_t io_src_channels(snd_pcm_plugin_t *plugin,
+static snd_pcm_sframes_t io_src_channels(struct snd_pcm_plugin *plugin,
 			     snd_pcm_uframes_t frames,
-			     snd_pcm_plugin_channel_t **channels)
+			     struct snd_pcm_plugin_channel **channels)
 {
 	int err;
 	unsigned int channel;
-	snd_pcm_plugin_channel_t *v;
+	struct snd_pcm_plugin_channel *v;
 	err = snd_pcm_plugin_client_channels(plugin, frames, &v);
 	if (err < 0)
 		return err;
@@ -100,13 +100,13 @@
 	return frames;
 }
 
-int snd_pcm_plugin_build_io(snd_pcm_plug_t *plug,
-			    snd_pcm_hw_params_t *params,
-			    snd_pcm_plugin_t **r_plugin)
+int snd_pcm_plugin_build_io(struct snd_pcm_substream *plug,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_pcm_plugin **r_plugin)
 {
 	int err;
-	snd_pcm_plugin_format_t format;
-	snd_pcm_plugin_t *plugin;
+	struct snd_pcm_plugin_format format;
+	struct snd_pcm_plugin *plugin;
 
 	snd_assert(r_plugin != NULL, return -ENXIO);
 	*r_plugin = NULL;
diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c
index 12ed27a..8cbfa41 100644
--- a/sound/core/oss/linear.c
+++ b/sound/core/oss/linear.c
@@ -30,19 +30,19 @@
  *  Basic linear conversion plugin
  */
  
-typedef struct linear_private_data {
+struct linear_priv {
 	int conv;
-} linear_t;
+};
 
-static void convert(snd_pcm_plugin_t *plugin,
-		    const snd_pcm_plugin_channel_t *src_channels,
-		    snd_pcm_plugin_channel_t *dst_channels,
+static void convert(struct snd_pcm_plugin *plugin,
+		    const struct snd_pcm_plugin_channel *src_channels,
+		    struct snd_pcm_plugin_channel *dst_channels,
 		    snd_pcm_uframes_t frames)
 {
 #define CONV_LABELS
 #include "plugin_ops.h"
 #undef CONV_LABELS
-	linear_t *data = (linear_t *)plugin->extra_data;
+	struct linear_priv *data = (struct linear_priv *)plugin->extra_data;
 	void *conv = conv_labels[data->conv];
 	int channel;
 	int nchannels = plugin->src_format.channels;
@@ -75,15 +75,15 @@
 	}
 }
 
-static snd_pcm_sframes_t linear_transfer(snd_pcm_plugin_t *plugin,
-			       const snd_pcm_plugin_channel_t *src_channels,
-			       snd_pcm_plugin_channel_t *dst_channels,
+static snd_pcm_sframes_t linear_transfer(struct snd_pcm_plugin *plugin,
+			       const struct snd_pcm_plugin_channel *src_channels,
+			       struct snd_pcm_plugin_channel *dst_channels,
 			       snd_pcm_uframes_t frames)
 {
-	linear_t *data;
+	struct linear_priv *data;
 
 	snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
-	data = (linear_t *)plugin->extra_data;
+	data = (struct linear_priv *)plugin->extra_data;
 	if (frames == 0)
 		return 0;
 #ifdef CONFIG_SND_DEBUG
@@ -128,14 +128,14 @@
 	return src_width * 32 + src_endian * 16 + sign * 8 + dst_width * 2 + dst_endian;
 }
 
-int snd_pcm_plugin_build_linear(snd_pcm_plug_t *plug,
-				snd_pcm_plugin_format_t *src_format,
-				snd_pcm_plugin_format_t *dst_format,
-				snd_pcm_plugin_t **r_plugin)
+int snd_pcm_plugin_build_linear(struct snd_pcm_substream *plug,
+				struct snd_pcm_plugin_format *src_format,
+				struct snd_pcm_plugin_format *dst_format,
+				struct snd_pcm_plugin **r_plugin)
 {
 	int err;
-	struct linear_private_data *data;
-	snd_pcm_plugin_t *plugin;
+	struct linear_priv *data;
+	struct snd_pcm_plugin *plugin;
 
 	snd_assert(r_plugin != NULL, return -ENXIO);
 	*r_plugin = NULL;
@@ -147,10 +147,10 @@
 
 	err = snd_pcm_plugin_build(plug, "linear format conversion",
 				   src_format, dst_format,
-				   sizeof(linear_t), &plugin);
+				   sizeof(struct linear_priv), &plugin);
 	if (err < 0)
 		return err;
-	data = (linear_t *)plugin->extra_data;
+	data = (struct linear_priv *)plugin->extra_data;
 	data->conv = conv_index(src_format->format, dst_format->format);
 	plugin->transfer = linear_transfer;
 	*r_plugin = plugin;
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 214933c..f08e65a 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -41,12 +41,13 @@
 
 static int snd_mixer_oss_open(struct inode *inode, struct file *file)
 {
-	int cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
-	snd_card_t *card;
-	snd_mixer_oss_file_t *fmixer;
+	struct snd_card *card;
+	struct snd_mixer_oss_file *fmixer;
 	int err;
 
-	if ((card = snd_cards[cardnum]) == NULL)
+	card = snd_lookup_oss_minor_data(iminor(inode),
+					 SNDRV_OSS_DEVICE_TYPE_MIXER);
+	if (card == NULL)
 		return -ENODEV;
 	if (card->mixer_oss == NULL)
 		return -ENODEV;
@@ -71,10 +72,10 @@
 
 static int snd_mixer_oss_release(struct inode *inode, struct file *file)
 {
-	snd_mixer_oss_file_t *fmixer;
+	struct snd_mixer_oss_file *fmixer;
 
 	if (file->private_data) {
-		fmixer = (snd_mixer_oss_file_t *) file->private_data;
+		fmixer = (struct snd_mixer_oss_file *) file->private_data;
 		module_put(fmixer->card->module);
 		snd_card_file_remove(fmixer->card, file);
 		kfree(fmixer);
@@ -82,11 +83,11 @@
 	return 0;
 }
 
-static int snd_mixer_oss_info(snd_mixer_oss_file_t *fmixer,
+static int snd_mixer_oss_info(struct snd_mixer_oss_file *fmixer,
 			      mixer_info __user *_info)
 {
-	snd_card_t *card = fmixer->card;
-	snd_mixer_oss_t *mixer = fmixer->mixer;
+	struct snd_card *card = fmixer->card;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
 	struct mixer_info info;
 	
 	memset(&info, 0, sizeof(info));
@@ -98,11 +99,11 @@
 	return 0;
 }
 
-static int snd_mixer_oss_info_obsolete(snd_mixer_oss_file_t *fmixer,
+static int snd_mixer_oss_info_obsolete(struct snd_mixer_oss_file *fmixer,
 				       _old_mixer_info __user *_info)
 {
-	snd_card_t *card = fmixer->card;
-	snd_mixer_oss_t *mixer = fmixer->mixer;
+	struct snd_card *card = fmixer->card;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
 	_old_mixer_info info;
 	
 	memset(&info, 0, sizeof(info));
@@ -113,9 +114,9 @@
 	return 0;
 }
 
-static int snd_mixer_oss_caps(snd_mixer_oss_file_t *fmixer)
+static int snd_mixer_oss_caps(struct snd_mixer_oss_file *fmixer)
 {
-	snd_mixer_oss_t *mixer = fmixer->mixer;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
 	int result = 0;
 
 	if (mixer == NULL)
@@ -125,10 +126,10 @@
 	return result;
 }
 
-static int snd_mixer_oss_devmask(snd_mixer_oss_file_t *fmixer)
+static int snd_mixer_oss_devmask(struct snd_mixer_oss_file *fmixer)
 {
-	snd_mixer_oss_t *mixer = fmixer->mixer;
-	snd_mixer_oss_slot_t *pslot;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
+	struct snd_mixer_oss_slot *pslot;
 	int result = 0, chn;
 
 	if (mixer == NULL)
@@ -141,10 +142,10 @@
 	return result;
 }
 
-static int snd_mixer_oss_stereodevs(snd_mixer_oss_file_t *fmixer)
+static int snd_mixer_oss_stereodevs(struct snd_mixer_oss_file *fmixer)
 {
-	snd_mixer_oss_t *mixer = fmixer->mixer;
-	snd_mixer_oss_slot_t *pslot;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
+	struct snd_mixer_oss_slot *pslot;
 	int result = 0, chn;
 
 	if (mixer == NULL)
@@ -157,9 +158,9 @@
 	return result;
 }
 
-static int snd_mixer_oss_recmask(snd_mixer_oss_file_t *fmixer)
+static int snd_mixer_oss_recmask(struct snd_mixer_oss_file *fmixer)
 {
-	snd_mixer_oss_t *mixer = fmixer->mixer;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
 	int result = 0;
 
 	if (mixer == NULL)
@@ -167,7 +168,7 @@
 	if (mixer->put_recsrc && mixer->get_recsrc) {	/* exclusive */
 		result = mixer->mask_recsrc;
 	} else {
-		snd_mixer_oss_slot_t *pslot;
+		struct snd_mixer_oss_slot *pslot;
 		int chn;
 		for (chn = 0; chn < 31; chn++) {
 			pslot = &mixer->slots[chn];
@@ -178,9 +179,9 @@
 	return result;
 }
 
-static int snd_mixer_oss_get_recsrc(snd_mixer_oss_file_t *fmixer)
+static int snd_mixer_oss_get_recsrc(struct snd_mixer_oss_file *fmixer)
 {
-	snd_mixer_oss_t *mixer = fmixer->mixer;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
 	int result = 0;
 
 	if (mixer == NULL)
@@ -191,7 +192,7 @@
 			return err;
 		result = 1 << result;
 	} else {
-		snd_mixer_oss_slot_t *pslot;
+		struct snd_mixer_oss_slot *pslot;
 		int chn;
 		for (chn = 0; chn < 31; chn++) {
 			pslot = &mixer->slots[chn];
@@ -206,10 +207,10 @@
 	return mixer->oss_recsrc = result;
 }
 
-static int snd_mixer_oss_set_recsrc(snd_mixer_oss_file_t *fmixer, int recsrc)
+static int snd_mixer_oss_set_recsrc(struct snd_mixer_oss_file *fmixer, int recsrc)
 {
-	snd_mixer_oss_t *mixer = fmixer->mixer;
-	snd_mixer_oss_slot_t *pslot;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
+	struct snd_mixer_oss_slot *pslot;
 	int chn, active;
 	int result = 0;
 
@@ -243,10 +244,10 @@
 	return result;
 }
 
-static int snd_mixer_oss_get_volume(snd_mixer_oss_file_t *fmixer, int slot)
+static int snd_mixer_oss_get_volume(struct snd_mixer_oss_file *fmixer, int slot)
 {
-	snd_mixer_oss_t *mixer = fmixer->mixer;
-	snd_mixer_oss_slot_t *pslot;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
+	struct snd_mixer_oss_slot *pslot;
 	int result = 0, left, right;
 
 	if (mixer == NULL || slot > 30)
@@ -268,11 +269,11 @@
 	return result;
 }
 
-static int snd_mixer_oss_set_volume(snd_mixer_oss_file_t *fmixer,
+static int snd_mixer_oss_set_volume(struct snd_mixer_oss_file *fmixer,
 				    int slot, int volume)
 {
-	snd_mixer_oss_t *mixer = fmixer->mixer;
-	snd_mixer_oss_slot_t *pslot;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
+	struct snd_mixer_oss_slot *pslot;
 	int result = 0, left = volume & 0xff, right = (volume >> 8) & 0xff;
 
 	if (mixer == NULL || slot > 30)
@@ -293,7 +294,7 @@
  	return (left & 0xff) | ((right & 0xff) << 8);
 }
 
-static int snd_mixer_oss_ioctl1(snd_mixer_oss_file_t *fmixer, unsigned int cmd, unsigned long arg)
+static int snd_mixer_oss_ioctl1(struct snd_mixer_oss_file *fmixer, unsigned int cmd, unsigned long arg)
 {
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
@@ -362,12 +363,12 @@
 
 static long snd_mixer_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	return snd_mixer_oss_ioctl1((snd_mixer_oss_file_t *) file->private_data, cmd, arg);
+	return snd_mixer_oss_ioctl1((struct snd_mixer_oss_file *) file->private_data, cmd, arg);
 }
 
-int snd_mixer_oss_ioctl_card(snd_card_t *card, unsigned int cmd, unsigned long arg)
+int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg)
 {
-	snd_mixer_oss_file_t fmixer;
+	struct snd_mixer_oss_file fmixer;
 	
 	snd_assert(card != NULL, return -ENXIO);
 	if (card->mixer_oss == NULL)
@@ -398,12 +399,6 @@
 	.compat_ioctl =	snd_mixer_oss_ioctl_compat,
 };
 
-static snd_minor_t snd_mixer_oss_reg =
-{
-	.comment =	"mixer",
-	.f_ops =	&snd_mixer_oss_f_ops,
-};
-
 /*
  *  utilities
  */
@@ -432,16 +427,16 @@
 }
 
 #if 0
-static void snd_mixer_oss_recsrce_set(snd_card_t *card, int slot)
+static void snd_mixer_oss_recsrce_set(struct snd_card *card, int slot)
 {
-	snd_mixer_oss_t *mixer = card->mixer_oss;
+	struct snd_mixer_oss *mixer = card->mixer_oss;
 	if (mixer)
 		mixer->mask_recsrc |= 1 << slot;
 }
 
-static int snd_mixer_oss_recsrce_get(snd_card_t *card, int slot)
+static int snd_mixer_oss_recsrce_get(struct snd_card *card, int slot)
 {
-	snd_mixer_oss_t *mixer = card->mixer_oss;
+	struct snd_mixer_oss *mixer = card->mixer_oss;
 	if (mixer && (mixer->mask_recsrc & (1 << slot)))
 		return 1;
 	return 0;
@@ -488,10 +483,10 @@
 
 #define ID_UNKNOWN	((unsigned int)-1)
 
-static snd_kcontrol_t *snd_mixer_oss_test_id(snd_mixer_oss_t *mixer, const char *name, int index)
+static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, const char *name, int index)
 {
-	snd_card_t * card = mixer->card;
-	snd_ctl_elem_id_t id;
+	struct snd_card *card = mixer->card;
+	struct snd_ctl_elem_id id;
 	
 	memset(&id, 0, sizeof(id));
 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -500,15 +495,15 @@
 	return snd_ctl_find_id(card, &id);
 }
 
-static void snd_mixer_oss_get_volume1_vol(snd_mixer_oss_file_t *fmixer,
-					  snd_mixer_oss_slot_t *pslot,
+static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer,
+					  struct snd_mixer_oss_slot *pslot,
 					  unsigned int numid,
 					  int *left, int *right)
 {
-	snd_ctl_elem_info_t *uinfo;
-	snd_ctl_elem_value_t *uctl;
-	snd_kcontrol_t *kctl;
-	snd_card_t *card = fmixer->card;
+	struct snd_ctl_elem_info *uinfo;
+	struct snd_ctl_elem_value *uctl;
+	struct snd_kcontrol *kctl;
+	struct snd_card *card = fmixer->card;
 
 	if (numid == ID_UNKNOWN)
 		return;
@@ -537,16 +532,16 @@
       	kfree(uinfo);
 }
 
-static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer,
-					 snd_mixer_oss_slot_t *pslot,
+static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer,
+					 struct snd_mixer_oss_slot *pslot,
 					 unsigned int numid,
 					 int *left, int *right,
 					 int route)
 {
-	snd_ctl_elem_info_t *uinfo;
-	snd_ctl_elem_value_t *uctl;
-	snd_kcontrol_t *kctl;
-	snd_card_t *card = fmixer->card;
+	struct snd_ctl_elem_info *uinfo;
+	struct snd_ctl_elem_value *uctl;
+	struct snd_kcontrol *kctl;
+	struct snd_card *card = fmixer->card;
 
 	if (numid == ID_UNKNOWN)
 		return;
@@ -576,8 +571,8 @@
 	kfree(uinfo);
 }
 
-static int snd_mixer_oss_get_volume1(snd_mixer_oss_file_t *fmixer,
-				     snd_mixer_oss_slot_t *pslot,
+static int snd_mixer_oss_get_volume1(struct snd_mixer_oss_file *fmixer,
+				     struct snd_mixer_oss_slot *pslot,
 				     int *left, int *right)
 {
 	struct slot *slot = (struct slot *)pslot->private_data;
@@ -602,15 +597,15 @@
 	return 0;
 }
 
-static void snd_mixer_oss_put_volume1_vol(snd_mixer_oss_file_t *fmixer,
-					  snd_mixer_oss_slot_t *pslot,
+static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer,
+					  struct snd_mixer_oss_slot *pslot,
 					  unsigned int numid,
 					  int left, int right)
 {
-	snd_ctl_elem_info_t *uinfo;
-	snd_ctl_elem_value_t *uctl;
-	snd_kcontrol_t *kctl;
-	snd_card_t *card = fmixer->card;
+	struct snd_ctl_elem_info *uinfo;
+	struct snd_ctl_elem_value *uctl;
+	struct snd_kcontrol *kctl;
+	struct snd_card *card = fmixer->card;
 	int res;
 
 	if (numid == ID_UNKNOWN)
@@ -640,16 +635,16 @@
 	kfree(uinfo);
 }
 
-static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,
-					 snd_mixer_oss_slot_t *pslot,
+static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer,
+					 struct snd_mixer_oss_slot *pslot,
 					 unsigned int numid,
 					 int left, int right,
 					 int route)
 {
-	snd_ctl_elem_info_t *uinfo;
-	snd_ctl_elem_value_t *uctl;
-	snd_kcontrol_t *kctl;
-	snd_card_t *card = fmixer->card;
+	struct snd_ctl_elem_info *uinfo;
+	struct snd_ctl_elem_value *uctl;
+	struct snd_kcontrol *kctl;
+	struct snd_card *card = fmixer->card;
 	int res;
 
 	if (numid == ID_UNKNOWN)
@@ -685,8 +680,8 @@
 	kfree(uinfo);
 }
 
-static int snd_mixer_oss_put_volume1(snd_mixer_oss_file_t *fmixer,
-				     snd_mixer_oss_slot_t *pslot,
+static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer,
+				     struct snd_mixer_oss_slot *pslot,
 				     int left, int right)
 {
 	struct slot *slot = (struct slot *)pslot->private_data;
@@ -723,8 +718,8 @@
 	return 0;
 }
 
-static int snd_mixer_oss_get_recsrc1_sw(snd_mixer_oss_file_t *fmixer,
-					snd_mixer_oss_slot_t *pslot,
+static int snd_mixer_oss_get_recsrc1_sw(struct snd_mixer_oss_file *fmixer,
+					struct snd_mixer_oss_slot *pslot,
 					int *active)
 {
 	struct slot *slot = (struct slot *)pslot->private_data;
@@ -736,8 +731,8 @@
 	return 0;
 }
 
-static int snd_mixer_oss_get_recsrc1_route(snd_mixer_oss_file_t *fmixer,
-					   snd_mixer_oss_slot_t *pslot,
+static int snd_mixer_oss_get_recsrc1_route(struct snd_mixer_oss_file *fmixer,
+					   struct snd_mixer_oss_slot *pslot,
 					   int *active)
 {
 	struct slot *slot = (struct slot *)pslot->private_data;
@@ -749,8 +744,8 @@
 	return 0;
 }
 
-static int snd_mixer_oss_put_recsrc1_sw(snd_mixer_oss_file_t *fmixer,
-					snd_mixer_oss_slot_t *pslot,
+static int snd_mixer_oss_put_recsrc1_sw(struct snd_mixer_oss_file *fmixer,
+					struct snd_mixer_oss_slot *pslot,
 					int active)
 {
 	struct slot *slot = (struct slot *)pslot->private_data;
@@ -759,8 +754,8 @@
 	return 0;
 }
 
-static int snd_mixer_oss_put_recsrc1_route(snd_mixer_oss_file_t *fmixer,
-					   snd_mixer_oss_slot_t *pslot,
+static int snd_mixer_oss_put_recsrc1_route(struct snd_mixer_oss_file *fmixer,
+					   struct snd_mixer_oss_slot *pslot,
 					   int active)
 {
 	struct slot *slot = (struct slot *)pslot->private_data;
@@ -769,15 +764,15 @@
 	return 0;
 }
 
-static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int *active_index)
+static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned int *active_index)
 {
-	snd_card_t *card = fmixer->card;
-	snd_mixer_oss_t *mixer = fmixer->mixer;
-	snd_kcontrol_t *kctl;
-	snd_mixer_oss_slot_t *pslot;
+	struct snd_card *card = fmixer->card;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
+	struct snd_kcontrol *kctl;
+	struct snd_mixer_oss_slot *pslot;
 	struct slot *slot;
-	snd_ctl_elem_info_t *uinfo;
-	snd_ctl_elem_value_t *uctl;
+	struct snd_ctl_elem_info *uinfo;
+	struct snd_ctl_elem_value *uctl;
 	int err, idx;
 	
 	uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL);
@@ -818,15 +813,15 @@
       	return err;
 }
 
-static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int active_index)
+static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned int active_index)
 {
-	snd_card_t *card = fmixer->card;
-	snd_mixer_oss_t *mixer = fmixer->mixer;
-	snd_kcontrol_t *kctl;
-	snd_mixer_oss_slot_t *pslot;
+	struct snd_card *card = fmixer->card;
+	struct snd_mixer_oss *mixer = fmixer->mixer;
+	struct snd_kcontrol *kctl;
+	struct snd_mixer_oss_slot *pslot;
 	struct slot *slot = NULL;
-	snd_ctl_elem_info_t *uinfo;
-	snd_ctl_elem_value_t *uctl;
+	struct snd_ctl_elem_info *uinfo;
+	struct snd_ctl_elem_value *uctl;
 	int err;
 	unsigned int idx;
 
@@ -878,11 +873,11 @@
 	int index;
 };
 
-static int snd_mixer_oss_build_test(snd_mixer_oss_t *mixer, struct slot *slot, const char *name, int index, int item)
+static int snd_mixer_oss_build_test(struct snd_mixer_oss *mixer, struct slot *slot, const char *name, int index, int item)
 {
-	snd_ctl_elem_info_t *info;
-	snd_kcontrol_t *kcontrol;
-	snd_card_t *card = mixer->card;
+	struct snd_ctl_elem_info *info;
+	struct snd_kcontrol *kcontrol;
+	struct snd_card *card = mixer->card;
 	int err;
 
 	down_read(&card->controls_rwsem);
@@ -910,7 +905,7 @@
 	return 0;
 }
 
-static void snd_mixer_oss_slot_free(snd_mixer_oss_slot_t *chn)
+static void snd_mixer_oss_slot_free(struct snd_mixer_oss_slot *chn)
 {
 	struct slot *p = (struct slot *)chn->private_data;
 	if (p) {
@@ -922,7 +917,7 @@
 	}
 }
 
-static void mixer_slot_clear(snd_mixer_oss_slot_t *rslot)
+static void mixer_slot_clear(struct snd_mixer_oss_slot *rslot)
 {
 	int idx = rslot->number; /* remember this */
 	if (rslot->private_free)
@@ -936,12 +931,12 @@
  * ptr_allocated means the entry is dynamically allocated (change via proc file).
  * when replace_old = 1, the old entry is replaced with the new one.
  */
-static int snd_mixer_oss_build_input(snd_mixer_oss_t *mixer, struct snd_mixer_oss_assign_table *ptr, int ptr_allocated, int replace_old)
+static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer, struct snd_mixer_oss_assign_table *ptr, int ptr_allocated, int replace_old)
 {
 	struct slot slot;
 	struct slot *pslot;
-	snd_kcontrol_t *kctl;
-	snd_mixer_oss_slot_t *rslot;
+	struct snd_kcontrol *kctl;
+	struct snd_mixer_oss_slot *rslot;
 	char str[64];	
 	
 	/* check if already assigned */
@@ -991,7 +986,7 @@
 		return 0;
 	down_read(&mixer->card->controls_rwsem);
 	if (ptr->index == 0 && (kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0)) != NULL) {
-		snd_ctl_elem_info_t *uinfo;
+		struct snd_ctl_elem_info *uinfo;
 
 		uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL);
 		if (! uinfo) {
@@ -1058,6 +1053,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  */
 #define MIXER_VOL(name) [SOUND_MIXER_##name] = #name
@@ -1093,10 +1089,10 @@
  *  /proc interface
  */
 
-static void snd_mixer_oss_proc_read(snd_info_entry_t *entry,
-				    snd_info_buffer_t * buffer)
+static void snd_mixer_oss_proc_read(struct snd_info_entry *entry,
+				    struct snd_info_buffer *buffer)
 {
-	snd_mixer_oss_t *mixer = entry->private_data;
+	struct snd_mixer_oss *mixer = entry->private_data;
 	int i;
 
 	down(&mixer->reg_mutex);
@@ -1117,10 +1113,10 @@
 	up(&mixer->reg_mutex);
 }
 
-static void snd_mixer_oss_proc_write(snd_info_entry_t *entry,
-				     snd_info_buffer_t * buffer)
+static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
+				     struct snd_info_buffer *buffer)
 {
-	snd_mixer_oss_t *mixer = entry->private_data;
+	struct snd_mixer_oss *mixer = entry->private_data;
 	char line[128], str[32], idxstr[16], *cptr;
 	int ch, idx;
 	struct snd_mixer_oss_assign_table *tbl;
@@ -1176,9 +1172,9 @@
 	}
 }
 
-static void snd_mixer_oss_proc_init(snd_mixer_oss_t *mixer)
+static void snd_mixer_oss_proc_init(struct snd_mixer_oss *mixer)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	entry = snd_info_create_card_entry(mixer->card, "oss_mixer",
 					   mixer->card->proc_root);
@@ -1198,15 +1194,19 @@
 	mixer->proc_entry = entry;
 }
 
-static void snd_mixer_oss_proc_done(snd_mixer_oss_t *mixer)
+static void snd_mixer_oss_proc_done(struct snd_mixer_oss *mixer)
 {
 	if (mixer->proc_entry) {
 		snd_info_unregister(mixer->proc_entry);
 		mixer->proc_entry = NULL;
 	}
 }
+#else /* !CONFIG_PROC_FS */
+#define snd_mixer_oss_proc_init(mix)
+#define snd_mixer_oss_proc_done(mix)
+#endif /* CONFIG_PROC_FS */
 
-static void snd_mixer_oss_build(snd_mixer_oss_t *mixer)
+static void snd_mixer_oss_build(struct snd_mixer_oss *mixer)
 {
 	static struct snd_mixer_oss_assign_table table[] = {
 		{ SOUND_MIXER_VOLUME, 	"Master",		0 },
@@ -1260,8 +1260,8 @@
 
 static int snd_mixer_oss_free1(void *private)
 {
-	snd_mixer_oss_t *mixer = private;
-	snd_card_t * card;
+	struct snd_mixer_oss *mixer = private;
+	struct snd_card *card;
 	int idx;
  
 	snd_assert(mixer != NULL, return -ENXIO);
@@ -1269,7 +1269,7 @@
 	snd_assert(mixer == card->mixer_oss, return -ENXIO);
 	card->mixer_oss = NULL;
 	for (idx = 0; idx < SNDRV_OSS_MAX_MIXERS; idx++) {
-		snd_mixer_oss_slot_t *chn = &mixer->slots[idx];
+		struct snd_mixer_oss_slot *chn = &mixer->slots[idx];
 		if (chn->private_free)
 			chn->private_free(chn);
 	}
@@ -1277,9 +1277,9 @@
 	return 0;
 }
 
-static int snd_mixer_oss_notify_handler(snd_card_t * card, int cmd)
+static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd)
 {
-	snd_mixer_oss_t *mixer;
+	struct snd_mixer_oss *mixer;
 
 	if (cmd == SND_MIXER_OSS_NOTIFY_REGISTER) {
 		char name[128];
@@ -1292,7 +1292,7 @@
 		sprintf(name, "mixer%i%i", card->number, 0);
 		if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,
 						   card, 0,
-						   &snd_mixer_oss_reg,
+						   &snd_mixer_oss_f_ops, card,
 						   name)) < 0) {
 			snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n",
 				   card->number, 0);
diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c
index 44ec4c6..14f5578 100644
--- a/sound/core/oss/mulaw.c
+++ b/sound/core/oss/mulaw.c
@@ -139,25 +139,25 @@
  *  Basic Mu-Law plugin
  */
 
-typedef void (*mulaw_f)(snd_pcm_plugin_t *plugin,
-			const snd_pcm_plugin_channel_t *src_channels,
-			snd_pcm_plugin_channel_t *dst_channels,
+typedef void (*mulaw_f)(struct snd_pcm_plugin *plugin,
+			const struct snd_pcm_plugin_channel *src_channels,
+			struct snd_pcm_plugin_channel *dst_channels,
 			snd_pcm_uframes_t frames);
 
-typedef struct mulaw_private_data {
+struct mulaw_priv {
 	mulaw_f func;
 	int conv;
-} mulaw_t;
+};
 
-static void mulaw_decode(snd_pcm_plugin_t *plugin,
-			const snd_pcm_plugin_channel_t *src_channels,
-			snd_pcm_plugin_channel_t *dst_channels,
+static void mulaw_decode(struct snd_pcm_plugin *plugin,
+			const struct snd_pcm_plugin_channel *src_channels,
+			struct snd_pcm_plugin_channel *dst_channels,
 			snd_pcm_uframes_t frames)
 {
 #define PUT_S16_LABELS
 #include "plugin_ops.h"
 #undef PUT_S16_LABELS
-	mulaw_t *data = (mulaw_t *)plugin->extra_data;
+	struct mulaw_priv *data = (struct mulaw_priv *)plugin->extra_data;
 	void *put = put_s16_labels[data->conv];
 	int channel;
 	int nchannels = plugin->src_format.channels;
@@ -191,15 +191,15 @@
 	}
 }
 
-static void mulaw_encode(snd_pcm_plugin_t *plugin,
-			const snd_pcm_plugin_channel_t *src_channels,
-			snd_pcm_plugin_channel_t *dst_channels,
+static void mulaw_encode(struct snd_pcm_plugin *plugin,
+			const struct snd_pcm_plugin_channel *src_channels,
+			struct snd_pcm_plugin_channel *dst_channels,
 			snd_pcm_uframes_t frames)
 {
 #define GET_S16_LABELS
 #include "plugin_ops.h"
 #undef GET_S16_LABELS
-	mulaw_t *data = (mulaw_t *)plugin->extra_data;
+	struct mulaw_priv *data = (struct mulaw_priv *)plugin->extra_data;
 	void *get = get_s16_labels[data->conv];
 	int channel;
 	int nchannels = plugin->src_format.channels;
@@ -234,12 +234,12 @@
 	}
 }
 
-static snd_pcm_sframes_t mulaw_transfer(snd_pcm_plugin_t *plugin,
-			      const snd_pcm_plugin_channel_t *src_channels,
-			      snd_pcm_plugin_channel_t *dst_channels,
+static snd_pcm_sframes_t mulaw_transfer(struct snd_pcm_plugin *plugin,
+			      const struct snd_pcm_plugin_channel *src_channels,
+			      struct snd_pcm_plugin_channel *dst_channels,
 			      snd_pcm_uframes_t frames)
 {
-	mulaw_t *data;
+	struct mulaw_priv *data;
 
 	snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
 	if (frames == 0)
@@ -257,20 +257,20 @@
 		}
 	}
 #endif
-	data = (mulaw_t *)plugin->extra_data;
+	data = (struct mulaw_priv *)plugin->extra_data;
 	data->func(plugin, src_channels, dst_channels, frames);
 	return frames;
 }
 
-int snd_pcm_plugin_build_mulaw(snd_pcm_plug_t *plug,
-			       snd_pcm_plugin_format_t *src_format,
-			       snd_pcm_plugin_format_t *dst_format,
-			       snd_pcm_plugin_t **r_plugin)
+int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *plug,
+			       struct snd_pcm_plugin_format *src_format,
+			       struct snd_pcm_plugin_format *dst_format,
+			       struct snd_pcm_plugin **r_plugin)
 {
 	int err;
-	mulaw_t *data;
-	snd_pcm_plugin_t *plugin;
-	snd_pcm_plugin_format_t *format;
+	struct mulaw_priv *data;
+	struct snd_pcm_plugin *plugin;
+	struct snd_pcm_plugin_format *format;
 	mulaw_f func;
 
 	snd_assert(r_plugin != NULL, return -ENXIO);
@@ -295,10 +295,10 @@
 
 	err = snd_pcm_plugin_build(plug, "Mu-Law<->linear conversion",
 				   src_format, dst_format,
-				   sizeof(mulaw_t), &plugin);
+				   sizeof(struct mulaw_priv), &plugin);
 	if (err < 0)
 		return err;
-	data = (mulaw_t*)plugin->extra_data;
+	data = (struct mulaw_priv *)plugin->extra_data;
 	data->func = func;
 	data->conv = getput_index(format->format);
 	snd_assert(data->conv >= 0 && data->conv < 4*2*2, return -EINVAL);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index bcc9707..16df124 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -61,10 +61,10 @@
 MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM);
 MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM1);
 
-extern int snd_mixer_oss_ioctl_card(snd_card_t *card, unsigned int cmd, unsigned long arg);
-static int snd_pcm_oss_get_rate(snd_pcm_oss_file_t *pcm_oss_file);
-static int snd_pcm_oss_get_channels(snd_pcm_oss_file_t *pcm_oss_file);
-static int snd_pcm_oss_get_format(snd_pcm_oss_file_t *pcm_oss_file);
+extern int snd_mixer_oss_ioctl_card(struct snd_card *card, unsigned int cmd, unsigned long arg);
+static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file);
+static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file);
+static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file);
 
 static inline mm_segment_t snd_enter_user(void)
 {
@@ -78,10 +78,10 @@
 	set_fs(fs);
 }
 
-static int snd_pcm_oss_plugin_clear(snd_pcm_substream_t *substream)
+static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_plugin_t *plugin, *next;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_pcm_plugin *plugin, *next;
 	
 	plugin = runtime->oss.plugin_first;
 	while (plugin) {
@@ -93,9 +93,9 @@
 	return 0;
 }
 
-static int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin)
+static int snd_pcm_plugin_insert(struct snd_pcm_plugin *plugin)
 {
-	snd_pcm_runtime_t *runtime = plugin->plug->runtime;
+	struct snd_pcm_runtime *runtime = plugin->plug->runtime;
 	plugin->next = runtime->oss.plugin_first;
 	plugin->prev = NULL;
 	if (runtime->oss.plugin_first) {
@@ -108,9 +108,9 @@
 	return 0;
 }
 
-int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin)
+int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin)
 {
-	snd_pcm_runtime_t *runtime = plugin->plug->runtime;
+	struct snd_pcm_runtime *runtime = plugin->plug->runtime;
 	plugin->next = NULL;
 	plugin->prev = runtime->oss.plugin_last;
 	if (runtime->oss.plugin_last) {
@@ -123,9 +123,9 @@
 	return 0;
 }
 
-static long snd_pcm_oss_bytes(snd_pcm_substream_t *substream, long frames)
+static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	long buffer_size = snd_pcm_lib_buffer_bytes(substream);
 	long bytes = frames_to_bytes(runtime, frames);
 	if (buffer_size == runtime->oss.buffer_bytes)
@@ -142,9 +142,9 @@
 #endif
 }
 
-static long snd_pcm_alsa_frames(snd_pcm_substream_t *substream, long bytes)
+static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	long buffer_size = snd_pcm_lib_buffer_bytes(substream);
 	if (buffer_size == runtime->oss.buffer_bytes)
 		return bytes_to_frames(runtime, bytes);
@@ -185,14 +185,14 @@
 	}
 }
 
-static int snd_pcm_oss_period_size(snd_pcm_substream_t *substream, 
-				   snd_pcm_hw_params_t *oss_params,
-				   snd_pcm_hw_params_t *slave_params)
+static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, 
+				   struct snd_pcm_hw_params *oss_params,
+				   struct snd_pcm_hw_params *slave_params)
 {
 	size_t s;
 	size_t oss_buffer_size, oss_period_size, oss_periods;
 	size_t min_period_size, max_period_size;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	size_t oss_frame_size;
 
 	oss_frame_size = snd_pcm_format_physical_width(params_format(oss_params)) *
@@ -277,11 +277,11 @@
 	return 0;
 }
 
-static int choose_rate(snd_pcm_substream_t *substream,
-		       snd_pcm_hw_params_t *params, unsigned int best_rate)
+static int choose_rate(struct snd_pcm_substream *substream,
+		       struct snd_pcm_hw_params *params, unsigned int best_rate)
 {
-	snd_interval_t *it;
-	snd_pcm_hw_params_t *save;
+	struct snd_interval *it;
+	struct snd_pcm_hw_params *save;
 	unsigned int rate, prev;
 
 	save = kmalloc(sizeof(*save), GFP_KERNEL);
@@ -317,18 +317,18 @@
 	return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
 }
 
-static int snd_pcm_oss_change_params(snd_pcm_substream_t *substream)
+static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_hw_params_t *params, *sparams;
-	snd_pcm_sw_params_t *sw_params;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_pcm_hw_params *params, *sparams;
+	struct snd_pcm_sw_params *sw_params;
 	ssize_t oss_buffer_size, oss_period_size;
 	size_t oss_frame_size;
 	int err;
 	int direct;
 	int format, sformat, n;
-	snd_mask_t sformat_mask;
-	snd_mask_t mask;
+	struct snd_mask sformat_mask;
+	struct snd_mask mask;
 
 	sw_params = kmalloc(sizeof(*sw_params), GFP_KERNEL);
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
@@ -342,7 +342,7 @@
 	if (atomic_read(&runtime->mmap_count)) {
 		direct = 1;
 	} else {
-		snd_pcm_oss_setup_t *setup = substream->oss.setup;
+		struct snd_pcm_oss_setup *setup = substream->oss.setup;
 		direct = (setup != NULL && setup->direct);
 	}
 
@@ -424,7 +424,7 @@
 			goto failure;
 		}
 		if (runtime->oss.plugin_first) {
-			snd_pcm_plugin_t *plugin;
+			struct snd_pcm_plugin *plugin;
 			if ((err = snd_pcm_plugin_build_io(substream, sparams, &plugin)) < 0) {
 				snd_printd("snd_pcm_plugin_build_io failed: %i\n", err);
 				snd_pcm_oss_plugin_clear(substream);
@@ -540,10 +540,10 @@
 	return err;
 }
 
-static int snd_pcm_oss_get_active_substream(snd_pcm_oss_file_t *pcm_oss_file, snd_pcm_substream_t **r_substream)
+static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_file, struct snd_pcm_substream **r_substream)
 {
 	int idx, err;
-	snd_pcm_substream_t *asubstream = NULL, *substream;
+	struct snd_pcm_substream *asubstream = NULL, *substream;
 
 	for (idx = 0; idx < 2; idx++) {
 		substream = pcm_oss_file->streams[idx];
@@ -563,10 +563,10 @@
 	return 0;
 }
 
-static int snd_pcm_oss_prepare(snd_pcm_substream_t *substream)
+static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
 {
 	int err;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL);
 	if (err < 0) {
@@ -581,9 +581,9 @@
 	return 0;
 }
 
-static int snd_pcm_oss_make_ready(snd_pcm_substream_t *substream)
+static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	int err;
 
 	if (substream == NULL)
@@ -602,9 +602,9 @@
 	return 0;
 }
 
-static int snd_pcm_oss_capture_position_fixup(snd_pcm_substream_t *substream, snd_pcm_sframes_t *delay)
+static int snd_pcm_oss_capture_position_fixup(struct snd_pcm_substream *substream, snd_pcm_sframes_t *delay)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	snd_pcm_uframes_t frames;
 	int err = 0;
 
@@ -627,9 +627,9 @@
 	return err;
 }
 
-snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel)
+snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int ret;
 	while (1) {
 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
@@ -662,9 +662,9 @@
 	return ret;
 }
 
-snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, snd_pcm_uframes_t frames, int in_kernel)
+snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *ptr, snd_pcm_uframes_t frames, int in_kernel)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_sframes_t delay;
 	int ret;
 	while (1) {
@@ -709,9 +709,9 @@
 	return ret;
 }
 
-snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel)
+snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int ret;
 	while (1) {
 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
@@ -745,9 +745,9 @@
 	return ret;
 }
 	
-snd_pcm_sframes_t snd_pcm_oss_readv3(snd_pcm_substream_t *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel)
+snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int ret;
 	while (1) {
 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
@@ -780,12 +780,12 @@
 	return ret;
 }
 
-static ssize_t snd_pcm_oss_write2(snd_pcm_substream_t *substream, const char *buf, size_t bytes, int in_kernel)
+static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_sframes_t frames, frames1;
 	if (runtime->oss.plugin_first) {
-		snd_pcm_plugin_channel_t *channels;
+		struct snd_pcm_plugin_channel *channels;
 		size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8;
 		if (!in_kernel) {
 			if (copy_from_user(runtime->oss.buffer, (const char __user *)buf, bytes))
@@ -810,11 +810,11 @@
 	return bytes;
 }
 
-static ssize_t snd_pcm_oss_write1(snd_pcm_substream_t *substream, const char __user *buf, size_t bytes)
+static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const char __user *buf, size_t bytes)
 {
 	size_t xfer = 0;
 	ssize_t tmp;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (atomic_read(&runtime->mmap_count))
 		return -ENXIO;
@@ -867,13 +867,13 @@
 	return xfer;
 }
 
-static ssize_t snd_pcm_oss_read2(snd_pcm_substream_t *substream, char *buf, size_t bytes, int in_kernel)
+static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, size_t bytes, int in_kernel)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_sframes_t frames, frames1;
 	char __user *final_dst = (char __user *)buf;
 	if (runtime->oss.plugin_first) {
-		snd_pcm_plugin_channel_t *channels;
+		struct snd_pcm_plugin_channel *channels;
 		size_t oss_frame_bytes = (runtime->oss.plugin_last->dst_width * runtime->oss.plugin_last->dst_format.channels) / 8;
 		if (!in_kernel)
 			buf = runtime->oss.buffer;
@@ -897,11 +897,11 @@
 	return bytes;
 }
 
-static ssize_t snd_pcm_oss_read1(snd_pcm_substream_t *substream, char __user *buf, size_t bytes)
+static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __user *buf, size_t bytes)
 {
 	size_t xfer = 0;
 	ssize_t tmp;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (atomic_read(&runtime->mmap_count))
 		return -ENXIO;
@@ -941,9 +941,9 @@
 	return xfer;
 }
 
-static int snd_pcm_oss_reset(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 
 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
 	if (substream != NULL) {
@@ -958,9 +958,9 @@
 	return 0;
 }
 
-static int snd_pcm_oss_post(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_post(struct snd_pcm_oss_file *pcm_oss_file)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	int err;
 
 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
@@ -974,9 +974,9 @@
 	return 0;
 }
 
-static int snd_pcm_oss_sync1(snd_pcm_substream_t *substream, size_t size)
+static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	ssize_t result = 0;
 	long res;
 	wait_queue_t wait;
@@ -1020,12 +1020,12 @@
 	return result;
 }
 
-static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
 {
 	int err = 0;
 	unsigned int saved_f_flags;
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	snd_pcm_format_t format;
 	unsigned long width;
 	size_t size;
@@ -1117,13 +1117,13 @@
 	return 0;
 }
 
-static int snd_pcm_oss_set_rate(snd_pcm_oss_file_t *pcm_oss_file, int rate)
+static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate)
 {
 	int idx;
 
 	for (idx = 1; idx >= 0; --idx) {
-		snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];
-		snd_pcm_runtime_t *runtime;
+		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
+		struct snd_pcm_runtime *runtime;
 		if (substream == NULL)
 			continue;
 		runtime = substream->runtime;
@@ -1139,9 +1139,9 @@
 	return snd_pcm_oss_get_rate(pcm_oss_file);
 }
 
-static int snd_pcm_oss_get_rate(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	int err;
 	
 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
@@ -1149,7 +1149,7 @@
 	return substream->runtime->oss.rate;
 }
 
-static int snd_pcm_oss_set_channels(snd_pcm_oss_file_t *pcm_oss_file, unsigned int channels)
+static int snd_pcm_oss_set_channels(struct snd_pcm_oss_file *pcm_oss_file, unsigned int channels)
 {
 	int idx;
 	if (channels < 1)
@@ -1157,8 +1157,8 @@
 	if (channels > 128)
 		return -EINVAL;
 	for (idx = 1; idx >= 0; --idx) {
-		snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];
-		snd_pcm_runtime_t *runtime;
+		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
+		struct snd_pcm_runtime *runtime;
 		if (substream == NULL)
 			continue;
 		runtime = substream->runtime;
@@ -1170,9 +1170,9 @@
 	return snd_pcm_oss_get_channels(pcm_oss_file);
 }
 
-static int snd_pcm_oss_get_channels(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	int err;
 	
 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
@@ -1180,9 +1180,9 @@
 	return substream->runtime->oss.channels;
 }
 
-static int snd_pcm_oss_get_block_size(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_get_block_size(struct snd_pcm_oss_file *pcm_oss_file)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	int err;
 	
 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
@@ -1190,14 +1190,14 @@
 	return substream->runtime->oss.period_bytes;
 }
 
-static int snd_pcm_oss_get_formats(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	int err;
 	int direct;
-	snd_pcm_hw_params_t *params;
+	struct snd_pcm_hw_params *params;
 	unsigned int formats = 0;
-	snd_mask_t format_mask;
+	struct snd_mask format_mask;
 	int fmt;
 
 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
@@ -1205,7 +1205,7 @@
 	if (atomic_read(&substream->runtime->mmap_count)) {
 		direct = 1;
 	} else {
-		snd_pcm_oss_setup_t *setup = substream->oss.setup;
+		struct snd_pcm_oss_setup *setup = substream->oss.setup;
 		direct = (setup != NULL && setup->direct);
 	}
 	if (!direct)
@@ -1231,7 +1231,7 @@
 	return formats;
 }
 
-static int snd_pcm_oss_set_format(snd_pcm_oss_file_t *pcm_oss_file, int format)
+static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)
 {
 	int formats, idx;
 	
@@ -1240,8 +1240,8 @@
 		if (!(formats & format))
 			format = AFMT_U8;
 		for (idx = 1; idx >= 0; --idx) {
-			snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];
-			snd_pcm_runtime_t *runtime;
+			struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
+			struct snd_pcm_runtime *runtime;
 			if (substream == NULL)
 				continue;
 			runtime = substream->runtime;
@@ -1254,9 +1254,9 @@
 	return snd_pcm_oss_get_format(pcm_oss_file);
 }
 
-static int snd_pcm_oss_get_format(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	int err;
 	
 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
@@ -1264,9 +1264,9 @@
 	return substream->runtime->oss.format;
 }
 
-static int snd_pcm_oss_set_subdivide1(snd_pcm_substream_t *substream, int subdivide)
+static int snd_pcm_oss_set_subdivide1(struct snd_pcm_substream *substream, int subdivide)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 
 	if (substream == NULL)
 		return 0;
@@ -1287,12 +1287,12 @@
 	return subdivide;
 }
 
-static int snd_pcm_oss_set_subdivide(snd_pcm_oss_file_t *pcm_oss_file, int subdivide)
+static int snd_pcm_oss_set_subdivide(struct snd_pcm_oss_file *pcm_oss_file, int subdivide)
 {
 	int err = -EINVAL, idx;
 
 	for (idx = 1; idx >= 0; --idx) {
-		snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];
+		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
 		if (substream == NULL)
 			continue;
 		if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0)
@@ -1301,9 +1301,9 @@
 	return err;
 }
 
-static int snd_pcm_oss_set_fragment1(snd_pcm_substream_t *substream, unsigned int val)
+static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsigned int val)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 
 	if (substream == NULL)
 		return 0;
@@ -1320,12 +1320,12 @@
 	return 0;
 }
 
-static int snd_pcm_oss_set_fragment(snd_pcm_oss_file_t *pcm_oss_file, unsigned int val)
+static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsigned int val)
 {
 	int err = -EINVAL, idx;
 
 	for (idx = 1; idx >= 0; --idx) {
-		snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];
+		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
 		if (substream == NULL)
 			continue;
 		if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0)
@@ -1340,7 +1340,7 @@
 	return 0;
 }
 
-static int snd_pcm_oss_get_caps1(snd_pcm_substream_t *substream, int res)
+static int snd_pcm_oss_get_caps1(struct snd_pcm_substream *substream, int res)
 {
 
 	if (substream == NULL) {
@@ -1356,7 +1356,7 @@
 	/* all ALSA drivers can return actual pointer in ring buffer */
 #if defined(DSP_CAP_REALTIME) && 0
 	{
-		snd_pcm_runtime_t *runtime = substream->runtime;
+		struct snd_pcm_runtime *runtime = substream->runtime;
 		if (runtime->info & (SNDRV_PCM_INFO_BLOCK_TRANSFER|SNDRV_PCM_INFO_BATCH))
 			res &= ~DSP_CAP_REALTIME;
 	}
@@ -1364,32 +1364,32 @@
 	return res;
 }
 
-static int snd_pcm_oss_get_caps(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file)
 {
 	int result, idx;
 	
 	result = DSP_CAP_TRIGGER | DSP_CAP_MMAP	| DSP_CAP_DUPLEX | DSP_CAP_REALTIME;
 	for (idx = 0; idx < 2; idx++) {
-		snd_pcm_substream_t *substream = pcm_oss_file->streams[idx];
+		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
 		result = snd_pcm_oss_get_caps1(substream, result);
 	}
 	result |= 0x0001;	/* revision - same as SB AWE 64 */
 	return result;
 }
 
-static void snd_pcm_oss_simulate_fill(snd_pcm_substream_t *substream, snd_pcm_uframes_t hw_ptr)
+static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream, snd_pcm_uframes_t hw_ptr)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t appl_ptr;
 	appl_ptr = hw_ptr + runtime->buffer_size;
 	appl_ptr %= runtime->boundary;
 	runtime->control->appl_ptr = appl_ptr;
 }
 
-static int snd_pcm_oss_set_trigger(snd_pcm_oss_file_t *pcm_oss_file, int trigger)
+static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int trigger)
 {
-	snd_pcm_runtime_t *runtime;
-	snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL;
+	struct snd_pcm_runtime *runtime;
+	struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
 	int err, cmd;
 
 #ifdef OSS_DEBUG
@@ -1454,9 +1454,9 @@
 	return 0;
 }
 
-static int snd_pcm_oss_get_trigger(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_get_trigger(struct snd_pcm_oss_file *pcm_oss_file)
 {
-	snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL;
+	struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
 	int result = 0;
 
 	psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
@@ -1468,10 +1468,10 @@
 	return result;
 }
 
-static int snd_pcm_oss_get_odelay(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_get_odelay(struct snd_pcm_oss_file *pcm_oss_file)
 {
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	snd_pcm_sframes_t delay;
 	int err;
 
@@ -1491,10 +1491,10 @@
 	return snd_pcm_oss_bytes(substream, delay);
 }
 
-static int snd_pcm_oss_get_ptr(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct count_info __user * _info)
+static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct count_info __user * _info)
 {	
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	snd_pcm_sframes_t delay;
 	int fixup;
 	struct count_info info;
@@ -1543,7 +1543,7 @@
 	} else {
 		delay = snd_pcm_oss_bytes(substream, delay);
 		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			snd_pcm_oss_setup_t *setup = substream->oss.setup;
+			struct snd_pcm_oss_setup *setup = substream->oss.setup;
 			if (setup && setup->buggyptr)
 				info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
 			else
@@ -1560,10 +1560,10 @@
 	return 0;
 }
 
-static int snd_pcm_oss_get_space(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct audio_buf_info __user *_info)
+static int snd_pcm_oss_get_space(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct audio_buf_info __user *_info)
 {
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	snd_pcm_sframes_t avail;
 	int fixup;
 	struct audio_buf_info info;
@@ -1619,17 +1619,17 @@
 	return 0;
 }
 
-static int snd_pcm_oss_get_mapbuf(snd_pcm_oss_file_t *pcm_oss_file, int stream, struct buffmem_desc __user * _info)
+static int snd_pcm_oss_get_mapbuf(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct buffmem_desc __user * _info)
 {
 	// it won't be probably implemented
 	// snd_printd("TODO: snd_pcm_oss_get_mapbuf\n");
 	return -EINVAL;
 }
 
-static snd_pcm_oss_setup_t *snd_pcm_oss_look_for_setup(snd_pcm_t *pcm, int stream, const char *task_name)
+static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream, const char *task_name)
 {
 	const char *ptr, *ptrl;
-	snd_pcm_oss_setup_t *setup;
+	struct snd_pcm_oss_setup *setup;
 
 	down(&pcm->streams[stream].oss.setup_mutex);
 	for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) {
@@ -1659,11 +1659,11 @@
 	return NULL;
 }
 
-static void snd_pcm_oss_init_substream(snd_pcm_substream_t *substream,
-				       snd_pcm_oss_setup_t *setup,
+static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
+				       struct snd_pcm_oss_setup *setup,
 				       int minor)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 
 	substream->oss.oss = 1;
 	substream->oss.setup = setup;
@@ -1687,9 +1687,9 @@
 	runtime->oss.subdivision = 0;
 }
 
-static void snd_pcm_oss_release_substream(snd_pcm_substream_t *substream)
+static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	runtime = substream->runtime;
 	vfree(runtime->oss.buffer);
 	snd_pcm_oss_plugin_clear(substream);
@@ -1697,13 +1697,13 @@
 	substream->oss.oss = 0;
 }
 
-static int snd_pcm_oss_release_file(snd_pcm_oss_file_t *pcm_oss_file)
+static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
 {
 	int cidx;
 	snd_assert(pcm_oss_file != NULL, return -ENXIO);
 	for (cidx = 0; cidx < 2; ++cidx) {
-		snd_pcm_substream_t *substream = pcm_oss_file->streams[cidx];
-		snd_pcm_runtime_t *runtime;
+		struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx];
+		struct snd_pcm_runtime *runtime;
 		if (substream == NULL)
 			continue;
 		runtime = substream->runtime;
@@ -1726,15 +1726,15 @@
 }
 
 static int snd_pcm_oss_open_file(struct file *file,
-				 snd_pcm_t *pcm,
-				 snd_pcm_oss_file_t **rpcm_oss_file,
+				 struct snd_pcm *pcm,
+				 struct snd_pcm_oss_file **rpcm_oss_file,
 				 int minor,
-				 snd_pcm_oss_setup_t *psetup,
-				 snd_pcm_oss_setup_t *csetup)
+				 struct snd_pcm_oss_setup *psetup,
+				 struct snd_pcm_oss_setup *csetup)
 {
 	int err = 0;
-	snd_pcm_oss_file_t *pcm_oss_file;
-	snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL;
+	struct snd_pcm_oss_file *pcm_oss_file;
+	struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
 	unsigned int f_mode = file->f_mode;
 
 	snd_assert(rpcm_oss_file != NULL, return -EINVAL);
@@ -1834,22 +1834,16 @@
 
 static int snd_pcm_oss_open(struct inode *inode, struct file *file)
 {
-	int minor = iminor(inode);
-	int cardnum = SNDRV_MINOR_OSS_CARD(minor);
-	int device;
 	int err;
 	char task_name[32];
-	snd_pcm_t *pcm;
-	snd_pcm_oss_file_t *pcm_oss_file;
-	snd_pcm_oss_setup_t *psetup = NULL, *csetup = NULL;
+	struct snd_pcm *pcm;
+	struct snd_pcm_oss_file *pcm_oss_file;
+	struct snd_pcm_oss_setup *psetup = NULL, *csetup = NULL;
 	int nonblock;
 	wait_queue_t wait;
 
-	snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
-	device = SNDRV_MINOR_OSS_DEVICE(minor) == SNDRV_MINOR_OSS_PCM1 ?
-		adsp_map[cardnum] : dsp_map[cardnum];
-
-	pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + device];
+	pcm = snd_lookup_oss_minor_data(iminor(inode),
+					SNDRV_OSS_DEVICE_TYPE_PCM);
 	if (pcm == NULL) {
 		err = -ENODEV;
 		goto __error1;
@@ -1890,7 +1884,7 @@
 	down(&pcm->open_mutex);
 	while (1) {
 		err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file,
-					    minor, psetup, csetup);
+					    iminor(inode), psetup, csetup);
 		if (err >= 0)
 			break;
 		if (err == -EAGAIN) {
@@ -1925,9 +1919,9 @@
 
 static int snd_pcm_oss_release(struct inode *inode, struct file *file)
 {
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *substream;
-	snd_pcm_oss_file_t *pcm_oss_file;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_oss_file *pcm_oss_file;
 
 	pcm_oss_file = file->private_data;
 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
@@ -1947,7 +1941,7 @@
 
 static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	snd_pcm_oss_file_t *pcm_oss_file;
+	struct snd_pcm_oss_file *pcm_oss_file;
 	int __user *p = (int __user *)arg;
 	int res;
 
@@ -1958,7 +1952,7 @@
 		return put_user(1, p);
 #if defined(CONFIG_SND_MIXER_OSS) || (defined(MODULE) && defined(CONFIG_SND_MIXER_OSS_MODULE))
 	if (((cmd >> 8) & 0xff) == 'M')	{	/* mixer ioctl - for OSS compatibility */
-		snd_pcm_substream_t *substream;
+		struct snd_pcm_substream *substream;
 		int idx;
 		for (idx = 0; idx < 2; ++idx) {
 			substream = pcm_oss_file->streams[idx];
@@ -2113,8 +2107,8 @@
 
 static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
-	snd_pcm_oss_file_t *pcm_oss_file;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_oss_file *pcm_oss_file;
+	struct snd_pcm_substream *substream;
 
 	pcm_oss_file = file->private_data;
 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
@@ -2133,8 +2127,8 @@
 
 static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
 {
-	snd_pcm_oss_file_t *pcm_oss_file;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_oss_file *pcm_oss_file;
+	struct snd_pcm_substream *substream;
 	long result;
 
 	pcm_oss_file = file->private_data;
@@ -2150,18 +2144,18 @@
 	return result;
 }
 
-static int snd_pcm_oss_playback_ready(snd_pcm_substream_t *substream)
+static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (atomic_read(&runtime->mmap_count))
 		return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt;
 	else
 		return snd_pcm_playback_avail(runtime) >= runtime->oss.period_frames;
 }
 
-static int snd_pcm_oss_capture_ready(snd_pcm_substream_t *substream)
+static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (atomic_read(&runtime->mmap_count))
 		return runtime->oss.prev_hw_ptr_interrupt != runtime->hw_ptr_interrupt;
 	else
@@ -2170,9 +2164,9 @@
 
 static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)
 {
-	snd_pcm_oss_file_t *pcm_oss_file;
+	struct snd_pcm_oss_file *pcm_oss_file;
 	unsigned int mask;
-	snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL;
+	struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
 	
 	pcm_oss_file = file->private_data;
 
@@ -2181,7 +2175,7 @@
 
 	mask = 0;
 	if (psubstream != NULL) {
-		snd_pcm_runtime_t *runtime = psubstream->runtime;
+		struct snd_pcm_runtime *runtime = psubstream->runtime;
 		poll_wait(file, &runtime->sleep, wait);
 		snd_pcm_stream_lock_irq(psubstream);
 		if (runtime->status->state != SNDRV_PCM_STATE_DRAINING &&
@@ -2191,8 +2185,8 @@
 		snd_pcm_stream_unlock_irq(psubstream);
 	}
 	if (csubstream != NULL) {
-		snd_pcm_runtime_t *runtime = csubstream->runtime;
-		enum sndrv_pcm_state ostate;
+		struct snd_pcm_runtime *runtime = csubstream->runtime;
+		snd_pcm_state_t ostate;
 		poll_wait(file, &runtime->sleep, wait);
 		snd_pcm_stream_lock_irq(csubstream);
 		if ((ostate = runtime->status->state) != SNDRV_PCM_STATE_RUNNING ||
@@ -2200,7 +2194,7 @@
 			mask |= POLLIN | POLLRDNORM;
 		snd_pcm_stream_unlock_irq(csubstream);
 		if (ostate != SNDRV_PCM_STATE_RUNNING && runtime->oss.trigger) {
-			snd_pcm_oss_file_t ofile;
+			struct snd_pcm_oss_file ofile;
 			memset(&ofile, 0, sizeof(ofile));
 			ofile.streams[SNDRV_PCM_STREAM_CAPTURE] = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
 			runtime->oss.trigger = 0;
@@ -2213,9 +2207,9 @@
 
 static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area)
 {
-	snd_pcm_oss_file_t *pcm_oss_file;
-	snd_pcm_substream_t *substream = NULL;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_oss_file *pcm_oss_file;
+	struct snd_pcm_substream *substream = NULL;
+	struct snd_pcm_runtime *runtime;
 	int err;
 
 #ifdef OSS_DEBUG
@@ -2275,15 +2269,16 @@
 	return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *  /proc interface
  */
 
-static void snd_pcm_oss_proc_read(snd_info_entry_t *entry,
-				  snd_info_buffer_t * buffer)
+static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
+				  struct snd_info_buffer *buffer)
 {
-	snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data;
-	snd_pcm_oss_setup_t *setup = pstr->oss.setup_list;
+	struct snd_pcm_str *pstr = entry->private_data;
+	struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
 	down(&pstr->oss.setup_mutex);
 	while (setup) {
 		snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
@@ -2301,11 +2296,11 @@
 	up(&pstr->oss.setup_mutex);
 }
 
-static void snd_pcm_oss_proc_free_setup_list(snd_pcm_str_t * pstr)
+static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr)
 {
 	unsigned int idx;
-	snd_pcm_substream_t *substream;
-	snd_pcm_oss_setup_t *setup, *setupn;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_oss_setup *setup, *setupn;
 
 	for (idx = 0, substream = pstr->substream;
 	     idx < pstr->substream_count; idx++, substream = substream->next)
@@ -2319,13 +2314,13 @@
 	pstr->oss.setup_list = NULL;
 }
 
-static void snd_pcm_oss_proc_write(snd_info_entry_t *entry,
-				   snd_info_buffer_t * buffer)
+static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
+				   struct snd_info_buffer *buffer)
 {
-	snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data;
+	struct snd_pcm_str *pstr = entry->private_data;
 	char line[128], str[32], task_name[32], *ptr;
 	int idx1;
-	snd_pcm_oss_setup_t *setup, *setup1, template;
+	struct snd_pcm_oss_setup *setup, *setup1, template;
 
 	while (!snd_info_get_line(buffer, line, sizeof(line))) {
 		down(&pstr->oss.setup_mutex);
@@ -2370,7 +2365,7 @@
 			}
 		} while (*str);
 		if (setup == NULL) {
-			setup = (snd_pcm_oss_setup_t *) kmalloc(sizeof(snd_pcm_oss_setup_t), GFP_KERNEL);
+			setup = kmalloc(sizeof(struct snd_pcm_oss_setup), GFP_KERNEL);
 			if (setup) {
 				if (pstr->oss.setup_list == NULL) {
 					pstr->oss.setup_list = setup;
@@ -2389,12 +2384,12 @@
 	}
 }
 
-static void snd_pcm_oss_proc_init(snd_pcm_t *pcm)
+static void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
 {
 	int stream;
 	for (stream = 0; stream < 2; ++stream) {
-		snd_info_entry_t *entry;
-		snd_pcm_str_t *pstr = &pcm->streams[stream];
+		struct snd_info_entry *entry;
+		struct snd_pcm_str *pstr = &pcm->streams[stream];
 		if (pstr->substream_count == 0)
 			continue;
 		if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) {
@@ -2414,11 +2409,11 @@
 	}
 }
 
-static void snd_pcm_oss_proc_done(snd_pcm_t *pcm)
+static void snd_pcm_oss_proc_done(struct snd_pcm *pcm)
 {
 	int stream;
 	for (stream = 0; stream < 2; ++stream) {
-		snd_pcm_str_t *pstr = &pcm->streams[stream];
+		struct snd_pcm_str *pstr = &pcm->streams[stream];
 		if (pstr->oss.proc_entry) {
 			snd_info_unregister(pstr->oss.proc_entry);
 			pstr->oss.proc_entry = NULL;
@@ -2426,6 +2421,10 @@
 		}
 	}
 }
+#else /* !CONFIG_PROC_FS */
+#define snd_pcm_oss_proc_init(pcm)
+#define snd_pcm_oss_proc_done(pcm)
+#endif /* CONFIG_PROC_FS */
 
 /*
  *  ENTRY functions
@@ -2444,25 +2443,19 @@
 	.mmap =		snd_pcm_oss_mmap,
 };
 
-static snd_minor_t snd_pcm_oss_reg =
-{
-	.comment =	"digital audio",
-	.f_ops =	&snd_pcm_oss_f_reg,
-};
-
-static void register_oss_dsp(snd_pcm_t *pcm, int index)
+static void register_oss_dsp(struct snd_pcm *pcm, int index)
 {
 	char name[128];
 	sprintf(name, "dsp%i%i", pcm->card->number, pcm->device);
 	if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
-				    pcm->card, index, &snd_pcm_oss_reg,
-				    name) < 0) {
+				    pcm->card, index, &snd_pcm_oss_f_reg,
+				    pcm, name) < 0) {
 		snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n",
 			   pcm->card->number, pcm->device);
 	}
 }
 
-static int snd_pcm_oss_register_minor(snd_pcm_t * pcm)
+static int snd_pcm_oss_register_minor(struct snd_pcm *pcm)
 {
 	pcm->oss.reg = 0;
 	if (dsp_map[pcm->card->number] == (int)pcm->device) {
@@ -2493,7 +2486,7 @@
 	return 0;
 }
 
-static int snd_pcm_oss_disconnect_minor(snd_pcm_t * pcm)
+static int snd_pcm_oss_disconnect_minor(struct snd_pcm *pcm)
 {
 	if (pcm->oss.reg) {
 		if (pcm->oss.reg_mask & 1) {
@@ -2510,7 +2503,7 @@
 	return 0;
 }
 
-static int snd_pcm_oss_unregister_minor(snd_pcm_t * pcm)
+static int snd_pcm_oss_unregister_minor(struct snd_pcm *pcm)
 {
 	snd_pcm_oss_disconnect_minor(pcm);
 	if (pcm->oss.reg) {
@@ -2525,7 +2518,7 @@
 	return 0;
 }
 
-static snd_pcm_notify_t snd_pcm_oss_notify =
+static struct snd_pcm_notify snd_pcm_oss_notify =
 {
 	.n_register =	snd_pcm_oss_register_minor,
 	.n_disconnect = snd_pcm_oss_disconnect_minor,
diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c
index fc23373..7e86768 100644
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -36,22 +36,22 @@
 #define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first)
 #define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last)
 
-static int snd_pcm_plugin_src_channels_mask(snd_pcm_plugin_t *plugin,
-					    bitset_t *dst_vmask,
-					    bitset_t **src_vmask)
+static int snd_pcm_plugin_src_channels_mask(struct snd_pcm_plugin *plugin,
+					    unsigned long *dst_vmask,
+					    unsigned long **src_vmask)
 {
-	bitset_t *vmask = plugin->src_vmask;
-	bitset_copy(vmask, dst_vmask, plugin->src_format.channels);
+	unsigned long *vmask = plugin->src_vmask;
+	bitmap_copy(vmask, dst_vmask, plugin->src_format.channels);
 	*src_vmask = vmask;
 	return 0;
 }
 
-static int snd_pcm_plugin_dst_channels_mask(snd_pcm_plugin_t *plugin,
-					    bitset_t *src_vmask,
-					    bitset_t **dst_vmask)
+static int snd_pcm_plugin_dst_channels_mask(struct snd_pcm_plugin *plugin,
+					    unsigned long *src_vmask,
+					    unsigned long **dst_vmask)
 {
-	bitset_t *vmask = plugin->dst_vmask;
-	bitset_copy(vmask, src_vmask, plugin->dst_format.channels);
+	unsigned long *vmask = plugin->dst_vmask;
+	bitmap_copy(vmask, src_vmask, plugin->dst_format.channels);
 	*dst_vmask = vmask;
 	return 0;
 }
@@ -67,13 +67,13 @@
 	return dst_rate >= low && dst_rate <= high;
 }
 
-static int snd_pcm_plugin_alloc(snd_pcm_plugin_t *plugin, snd_pcm_uframes_t frames)
+static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
 {
-	snd_pcm_plugin_format_t *format;
+	struct snd_pcm_plugin_format *format;
 	ssize_t width;
 	size_t size;
 	unsigned int channel;
-	snd_pcm_plugin_channel_t *c;
+	struct snd_pcm_plugin_channel *c;
 
 	if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		format = &plugin->src_format;
@@ -120,12 +120,12 @@
 	return 0;
 }
 
-int snd_pcm_plug_alloc(snd_pcm_plug_t *plug, snd_pcm_uframes_t frames)
+int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames)
 {
 	int err;
 	snd_assert(snd_pcm_plug_first(plug) != NULL, return -ENXIO);
 	if (snd_pcm_plug_stream(plug) == SNDRV_PCM_STREAM_PLAYBACK) {
-		snd_pcm_plugin_t *plugin = snd_pcm_plug_first(plug);
+		struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug);
 		while (plugin->next) {
 			if (plugin->dst_frames)
 				frames = plugin->dst_frames(plugin, frames);
@@ -136,7 +136,7 @@
 				return err;
 		}
 	} else {
-		snd_pcm_plugin_t *plugin = snd_pcm_plug_last(plug);
+		struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
 		while (plugin->prev) {
 			if (plugin->src_frames)
 				frames = plugin->src_frames(plugin, frames);
@@ -151,22 +151,22 @@
 }
 
 
-snd_pcm_sframes_t snd_pcm_plugin_client_channels(snd_pcm_plugin_t *plugin,
+snd_pcm_sframes_t snd_pcm_plugin_client_channels(struct snd_pcm_plugin *plugin,
 				       snd_pcm_uframes_t frames,
-				       snd_pcm_plugin_channel_t **channels)
+				       struct snd_pcm_plugin_channel **channels)
 {
 	*channels = plugin->buf_channels;
 	return frames;
 }
 
-int snd_pcm_plugin_build(snd_pcm_plug_t *plug,
+int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
 			 const char *name,
-			 snd_pcm_plugin_format_t *src_format,
-			 snd_pcm_plugin_format_t *dst_format,
+			 struct snd_pcm_plugin_format *src_format,
+			 struct snd_pcm_plugin_format *dst_format,
 			 size_t extra,
-			 snd_pcm_plugin_t **ret)
+			 struct snd_pcm_plugin **ret)
 {
-	snd_pcm_plugin_t *plugin;
+	struct snd_pcm_plugin *plugin;
 	unsigned int channels;
 	
 	snd_assert(plug != NULL, return -ENXIO);
@@ -193,12 +193,12 @@
 		snd_pcm_plugin_free(plugin);
 		return -ENOMEM;
 	}
-	plugin->src_vmask = bitset_alloc(src_format->channels);
+	plugin->src_vmask = bitmap_alloc(src_format->channels);
 	if (plugin->src_vmask == NULL) {
 		snd_pcm_plugin_free(plugin);
 		return -ENOMEM;
 	}
-	plugin->dst_vmask = bitset_alloc(dst_format->channels);
+	plugin->dst_vmask = bitmap_alloc(dst_format->channels);
 	if (plugin->dst_vmask == NULL) {
 		snd_pcm_plugin_free(plugin);
 		return -ENOMEM;
@@ -210,7 +210,7 @@
 	return 0;
 }
 
-int snd_pcm_plugin_free(snd_pcm_plugin_t *plugin)
+int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin)
 {
 	if (! plugin)
 		return 0;
@@ -224,9 +224,9 @@
 	return 0;
 }
 
-snd_pcm_sframes_t snd_pcm_plug_client_size(snd_pcm_plug_t *plug, snd_pcm_uframes_t drv_frames)
+snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t drv_frames)
 {
-	snd_pcm_plugin_t *plugin, *plugin_prev, *plugin_next;
+	struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
 	int stream = snd_pcm_plug_stream(plug);
 
 	snd_assert(plug != NULL, return -ENXIO);
@@ -253,9 +253,9 @@
 	return drv_frames;
 }
 
-snd_pcm_sframes_t snd_pcm_plug_slave_size(snd_pcm_plug_t *plug, snd_pcm_uframes_t clt_frames)
+snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t clt_frames)
 {
-	snd_pcm_plugin_t *plugin, *plugin_prev, *plugin_next;
+	struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
 	snd_pcm_sframes_t frames;
 	int stream = snd_pcm_plug_stream(plug);
 	
@@ -290,9 +290,9 @@
 	return frames;
 }
 
-static int snd_pcm_plug_formats(snd_mask_t *mask, int format)
+static int snd_pcm_plug_formats(struct snd_mask *mask, int format)
 {
-	snd_mask_t formats = *mask;
+	struct snd_mask formats = *mask;
 	u64 linfmts = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
 		       SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
 		       SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
@@ -326,7 +326,7 @@
 	SNDRV_PCM_FORMAT_U8
 };
 
-int snd_pcm_plug_slave_format(int format, snd_mask_t *format_mask)
+int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask)
 {
 	if (snd_mask_test(format_mask, format))
 		return format;
@@ -376,15 +376,15 @@
 	}
 }
 
-int snd_pcm_plug_format_plugins(snd_pcm_plug_t *plug,
-				snd_pcm_hw_params_t *params,
-				snd_pcm_hw_params_t *slave_params)
+int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
+				struct snd_pcm_hw_params *params,
+				struct snd_pcm_hw_params *slave_params)
 {
-	snd_pcm_plugin_format_t tmpformat;
-	snd_pcm_plugin_format_t dstformat;
-	snd_pcm_plugin_format_t srcformat;
+	struct snd_pcm_plugin_format tmpformat;
+	struct snd_pcm_plugin_format dstformat;
+	struct snd_pcm_plugin_format srcformat;
 	int src_access, dst_access;
-	snd_pcm_plugin_t *plugin = NULL;
+	struct snd_pcm_plugin *plugin = NULL;
 	int err;
 	int stream = snd_pcm_plug_stream(plug);
 	int slave_interleaved = (params_channels(slave_params) == 1 ||
@@ -462,7 +462,7 @@
 	if (srcformat.channels > dstformat.channels) {
 		int sv = srcformat.channels;
 		int dv = dstformat.channels;
-		route_ttable_entry_t *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
+		int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
 		if (ttable == NULL)
 			return -ENOMEM;
 #if 1
@@ -525,7 +525,7 @@
 	if (srcformat.channels < dstformat.channels) {
 		int sv = srcformat.channels;
 		int dv = dstformat.channels;
-		route_ttable_entry_t *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
+		int *ttable = kcalloc(dv * sv, sizeof(*ttable), GFP_KERNEL);
 		if (ttable == NULL)
 			return -ENOMEM;
 #if 0
@@ -614,14 +614,14 @@
 	return 0;
 }
 
-snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(snd_pcm_plug_t *plug,
+snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *plug,
 					 char *buf,
 					 snd_pcm_uframes_t count,
-					 snd_pcm_plugin_channel_t **channels)
+					 struct snd_pcm_plugin_channel **channels)
 {
-	snd_pcm_plugin_t *plugin;
-	snd_pcm_plugin_channel_t *v;
-	snd_pcm_plugin_format_t *format;
+	struct snd_pcm_plugin *plugin;
+	struct snd_pcm_plugin_channel *v;
+	struct snd_pcm_plugin_format *format;
 	int width, nchannels, channel;
 	int stream = snd_pcm_plug_stream(plug);
 
@@ -650,19 +650,19 @@
 	return count;
 }
 
-static int snd_pcm_plug_playback_channels_mask(snd_pcm_plug_t *plug,
-					       bitset_t *client_vmask)
+static int snd_pcm_plug_playback_channels_mask(struct snd_pcm_substream *plug,
+					       unsigned long *client_vmask)
 {
-	snd_pcm_plugin_t *plugin = snd_pcm_plug_last(plug);
+	struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
 	if (plugin == NULL) {
 		return 0;
 	} else {
 		int schannels = plugin->dst_format.channels;
-		bitset_t bs[bitset_size(schannels)];
-		bitset_t *srcmask;
-		bitset_t *dstmask = bs;
+		DECLARE_BITMAP(bs, schannels);
+		unsigned long *srcmask;
+		unsigned long *dstmask = bs;
 		int err;
-		bitset_one(dstmask, schannels);
+		bitmap_fill(dstmask, schannels);
 
 		while (1) {
 			err = plugin->src_channels_mask(plugin, dstmask, &srcmask);
@@ -673,52 +673,52 @@
 				break;
 			plugin = plugin->prev;
 		}
-		bitset_and(client_vmask, dstmask, plugin->src_format.channels);
+		bitmap_and(client_vmask, client_vmask, dstmask, plugin->src_format.channels);
 		return 0;
 	}
 }
 
-static int snd_pcm_plug_playback_disable_useless_channels(snd_pcm_plug_t *plug,
-							  snd_pcm_plugin_channel_t *src_channels)
+static int snd_pcm_plug_playback_disable_useless_channels(struct snd_pcm_substream *plug,
+							  struct snd_pcm_plugin_channel *src_channels)
 {
-	snd_pcm_plugin_t *plugin = snd_pcm_plug_first(plug);
+	struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug);
 	unsigned int nchannels = plugin->src_format.channels;
-	bitset_t bs[bitset_size(nchannels)];
-	bitset_t *srcmask = bs;
+	DECLARE_BITMAP(bs, nchannels);
+	unsigned long *srcmask = bs;
 	int err;
 	unsigned int channel;
 	for (channel = 0; channel < nchannels; channel++) {
 		if (src_channels[channel].enabled)
-			bitset_set(srcmask, channel);
+			set_bit(channel, srcmask);
 		else
-			bitset_reset(srcmask, channel);
+			clear_bit(channel, srcmask);
 	}
 	err = snd_pcm_plug_playback_channels_mask(plug, srcmask);
 	if (err < 0)
 		return err;
 	for (channel = 0; channel < nchannels; channel++) {
-		if (!bitset_get(srcmask, channel))
+		if (!test_bit(channel, srcmask))
 			src_channels[channel].enabled = 0;
 	}
 	return 0;
 }
 
-static int snd_pcm_plug_capture_disable_useless_channels(snd_pcm_plug_t *plug,
-							 snd_pcm_plugin_channel_t *src_channels,
-							 snd_pcm_plugin_channel_t *client_channels)
+static int snd_pcm_plug_capture_disable_useless_channels(struct snd_pcm_substream *plug,
+							 struct snd_pcm_plugin_channel *src_channels,
+							 struct snd_pcm_plugin_channel *client_channels)
 {
-	snd_pcm_plugin_t *plugin = snd_pcm_plug_last(plug);
+	struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
 	unsigned int nchannels = plugin->dst_format.channels;
-	bitset_t bs[bitset_size(nchannels)];
-	bitset_t *dstmask = bs;
-	bitset_t *srcmask;
+	DECLARE_BITMAP(bs, nchannels);
+	unsigned long *dstmask = bs;
+	unsigned long *srcmask;
 	int err;
 	unsigned int channel;
 	for (channel = 0; channel < nchannels; channel++) {
 		if (client_channels[channel].enabled)
-			bitset_set(dstmask, channel);
+			set_bit(channel, dstmask);
 		else
-			bitset_reset(dstmask, channel);
+			clear_bit(channel, dstmask);
 	}
 	while (plugin) {
 		err = plugin->src_channels_mask(plugin, dstmask, &srcmask);
@@ -730,16 +730,16 @@
 	plugin = snd_pcm_plug_first(plug);
 	nchannels = plugin->src_format.channels;
 	for (channel = 0; channel < nchannels; channel++) {
-		if (!bitset_get(dstmask, channel))
+		if (!test_bit(channel, dstmask))
 			src_channels[channel].enabled = 0;
 	}
 	return 0;
 }
 
-snd_pcm_sframes_t snd_pcm_plug_write_transfer(snd_pcm_plug_t *plug, snd_pcm_plugin_channel_t *src_channels, snd_pcm_uframes_t size)
+snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *src_channels, snd_pcm_uframes_t size)
 {
-	snd_pcm_plugin_t *plugin, *next;
-	snd_pcm_plugin_channel_t *dst_channels;
+	struct snd_pcm_plugin *plugin, *next;
+	struct snd_pcm_plugin_channel *dst_channels;
 	int err;
 	snd_pcm_sframes_t frames = size;
 
@@ -771,10 +771,10 @@
 	return snd_pcm_plug_client_size(plug, frames);
 }
 
-snd_pcm_sframes_t snd_pcm_plug_read_transfer(snd_pcm_plug_t *plug, snd_pcm_plugin_channel_t *dst_channels_final, snd_pcm_uframes_t size)
+snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *dst_channels_final, snd_pcm_uframes_t size)
 {
-	snd_pcm_plugin_t *plugin, *next;
-	snd_pcm_plugin_channel_t *src_channels, *dst_channels;
+	struct snd_pcm_plugin *plugin, *next;
+	struct snd_pcm_plugin_channel *src_channels, *dst_channels;
 	snd_pcm_sframes_t frames = size;
 	int err;
 
@@ -806,7 +806,7 @@
 	return frames;
 }
 
-int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offset,
+int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_area, size_t dst_offset,
 			 size_t samples, int format)
 {
 	/* FIXME: sub byte resolution and odd dst_offset */
@@ -852,8 +852,8 @@
 	return 0;
 }
 
-int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset,
-		      const snd_pcm_channel_area_t *dst_area, size_t dst_offset,
+int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_offset,
+		      const struct snd_pcm_channel_area *dst_area, size_t dst_offset,
 		      size_t samples, int format)
 {
 	/* FIXME: sub byte resolution and odd dst_offset */
diff --git a/sound/core/oss/pcm_plugin.h b/sound/core/oss/pcm_plugin.h
index 0f86ce4..29198da 100644
--- a/sound/core/oss/pcm_plugin.h
+++ b/sound/core/oss/pcm_plugin.h
@@ -22,214 +22,164 @@
  *
  */
 
-#ifndef ATTRIBUTE_UNUSED
-#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
-#endif
+#include <linux/bitmap.h>
 
-typedef unsigned int bitset_t;
-
-static inline size_t bitset_size(int nbits)
+static inline unsigned long *bitmap_alloc(unsigned int nbits)
 {
-	return (nbits + sizeof(bitset_t) * 8 - 1) / (sizeof(bitset_t) * 8);
+	return kmalloc(BITS_TO_LONGS(nbits), GFP_KERNEL);
 }
 
-static inline bitset_t *bitset_alloc(int nbits)
-{
-	return kcalloc(bitset_size(nbits), sizeof(bitset_t), GFP_KERNEL);
-}
-	
-static inline void bitset_set(bitset_t *bitmap, unsigned int pos)
-{
-	size_t bits = sizeof(*bitmap) * 8;
-	bitmap[pos / bits] |= 1 << (pos % bits);
-}
-
-static inline void bitset_reset(bitset_t *bitmap, unsigned int pos)
-{
-	size_t bits = sizeof(*bitmap) * 8;
-	bitmap[pos / bits] &= ~(1 << (pos % bits));
-}
-
-static inline int bitset_get(bitset_t *bitmap, unsigned int pos)
-{
-	size_t bits = sizeof(*bitmap) * 8;
-	return !!(bitmap[pos / bits] & (1 << (pos % bits)));
-}
-
-static inline void bitset_copy(bitset_t *dst, bitset_t *src, unsigned int nbits)
-{
-	memcpy(dst, src, bitset_size(nbits) * sizeof(bitset_t));
-}
-
-static inline void bitset_and(bitset_t *dst, bitset_t *bs, unsigned int nbits)
-{
-	bitset_t *end = dst + bitset_size(nbits);
-	while (dst < end)
-		*dst++ &= *bs++;
-}
-
-static inline void bitset_or(bitset_t *dst, bitset_t *bs, unsigned int nbits)
-{
-	bitset_t *end = dst + bitset_size(nbits);
-	while (dst < end)
-		*dst++ |= *bs++;
-}
-
-static inline void bitset_zero(bitset_t *dst, unsigned int nbits)
-{
-	bitset_t *end = dst + bitset_size(nbits);
-	while (dst < end)
-		*dst++ = 0;
-}
-
-static inline void bitset_one(bitset_t *dst, unsigned int nbits)
-{
-	bitset_t *end = dst + bitset_size(nbits);
-	while (dst < end)
-		*dst++ = ~(bitset_t)0;
-}
-
-#define snd_pcm_plug_t snd_pcm_substream_t
 #define snd_pcm_plug_stream(plug) ((plug)->stream)
 
-typedef enum {
+enum snd_pcm_plugin_action {
 	INIT = 0,
 	PREPARE = 1,
-} snd_pcm_plugin_action_t;
+};
 
-typedef struct _snd_pcm_channel_area {
+struct snd_pcm_channel_area {
 	void *addr;			/* base address of channel samples */
 	unsigned int first;		/* offset to first sample in bits */
 	unsigned int step;		/* samples distance in bits */
-} snd_pcm_channel_area_t;
+};
 
-typedef struct _snd_pcm_plugin_channel {
+struct snd_pcm_plugin_channel {
 	void *aptr;			/* pointer to the allocated area */
-	snd_pcm_channel_area_t area;
+	struct snd_pcm_channel_area area;
 	snd_pcm_uframes_t frames;	/* allocated frames */
 	unsigned int enabled:1;		/* channel need to be processed */
 	unsigned int wanted:1;		/* channel is wanted */
-} snd_pcm_plugin_channel_t;
+};
 
-typedef struct _snd_pcm_plugin_format {
+struct snd_pcm_plugin_format {
 	int format;
 	unsigned int rate;
 	unsigned int channels;
-} snd_pcm_plugin_format_t;
+};
 
-struct _snd_pcm_plugin {
+struct snd_pcm_plugin {
 	const char *name;		/* plug-in name */
 	int stream;
-	snd_pcm_plugin_format_t src_format;	/* source format */
-	snd_pcm_plugin_format_t dst_format;	/* destination format */
+	struct snd_pcm_plugin_format src_format;	/* source format */
+	struct snd_pcm_plugin_format dst_format;	/* destination format */
 	int src_width;			/* sample width in bits */
 	int dst_width;			/* sample width in bits */
 	int access;
-	snd_pcm_sframes_t (*src_frames)(snd_pcm_plugin_t *plugin, snd_pcm_uframes_t dst_frames);
-	snd_pcm_sframes_t (*dst_frames)(snd_pcm_plugin_t *plugin, snd_pcm_uframes_t src_frames);
-	snd_pcm_sframes_t (*client_channels)(snd_pcm_plugin_t *plugin,
-				 snd_pcm_uframes_t frames,
-				 snd_pcm_plugin_channel_t **channels);
-	int (*src_channels_mask)(snd_pcm_plugin_t *plugin,
-			       bitset_t *dst_vmask,
-			       bitset_t **src_vmask);
-	int (*dst_channels_mask)(snd_pcm_plugin_t *plugin,
-			       bitset_t *src_vmask,
-			       bitset_t **dst_vmask);
-	snd_pcm_sframes_t (*transfer)(snd_pcm_plugin_t *plugin,
-			    const snd_pcm_plugin_channel_t *src_channels,
-			    snd_pcm_plugin_channel_t *dst_channels,
-			    snd_pcm_uframes_t frames);
-	int (*action)(snd_pcm_plugin_t *plugin,
-		      snd_pcm_plugin_action_t action,
+	snd_pcm_sframes_t (*src_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t dst_frames);
+	snd_pcm_sframes_t (*dst_frames)(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t src_frames);
+	snd_pcm_sframes_t (*client_channels)(struct snd_pcm_plugin *plugin,
+					     snd_pcm_uframes_t frames,
+					     struct snd_pcm_plugin_channel **channels);
+	int (*src_channels_mask)(struct snd_pcm_plugin *plugin,
+				 unsigned long *dst_vmask,
+				 unsigned long **src_vmask);
+	int (*dst_channels_mask)(struct snd_pcm_plugin *plugin,
+				 unsigned long *src_vmask,
+				 unsigned long **dst_vmask);
+	snd_pcm_sframes_t (*transfer)(struct snd_pcm_plugin *plugin,
+				      const struct snd_pcm_plugin_channel *src_channels,
+				      struct snd_pcm_plugin_channel *dst_channels,
+				      snd_pcm_uframes_t frames);
+	int (*action)(struct snd_pcm_plugin *plugin,
+		      enum snd_pcm_plugin_action action,
 		      unsigned long data);
-	snd_pcm_plugin_t *prev;
-	snd_pcm_plugin_t *next;
-	snd_pcm_plug_t *plug;
+	struct snd_pcm_plugin *prev;
+	struct snd_pcm_plugin *next;
+	struct snd_pcm_substream *plug;
 	void *private_data;
-	void (*private_free)(snd_pcm_plugin_t *plugin);
+	void (*private_free)(struct snd_pcm_plugin *plugin);
 	char *buf;
 	snd_pcm_uframes_t buf_frames;
-	snd_pcm_plugin_channel_t *buf_channels;
-	bitset_t *src_vmask;
-	bitset_t *dst_vmask;
+	struct snd_pcm_plugin_channel *buf_channels;
+	unsigned long *src_vmask;
+	unsigned long *dst_vmask;
 	char extra_data[0];
 };
 
-int snd_pcm_plugin_build(snd_pcm_plug_t *handle,
+int snd_pcm_plugin_build(struct snd_pcm_substream *handle,
                          const char *name,
-                         snd_pcm_plugin_format_t *src_format,
-                         snd_pcm_plugin_format_t *dst_format,
+                         struct snd_pcm_plugin_format *src_format,
+                         struct snd_pcm_plugin_format *dst_format,
                          size_t extra,
-                         snd_pcm_plugin_t **ret);
-int snd_pcm_plugin_free(snd_pcm_plugin_t *plugin);
-int snd_pcm_plugin_clear(snd_pcm_plugin_t **first);
-int snd_pcm_plug_alloc(snd_pcm_plug_t *plug, snd_pcm_uframes_t frames);
-snd_pcm_sframes_t snd_pcm_plug_client_size(snd_pcm_plug_t *handle, snd_pcm_uframes_t drv_size);
-snd_pcm_sframes_t snd_pcm_plug_slave_size(snd_pcm_plug_t *handle, snd_pcm_uframes_t clt_size);
+                         struct snd_pcm_plugin **ret);
+int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin);
+int snd_pcm_plugin_clear(struct snd_pcm_plugin **first);
+int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames);
+snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t drv_size);
+snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *handle, snd_pcm_uframes_t clt_size);
 
 #define FULL ROUTE_PLUGIN_RESOLUTION
 #define HALF ROUTE_PLUGIN_RESOLUTION / 2
-typedef int route_ttable_entry_t;
 
-int snd_pcm_plugin_build_io(snd_pcm_plug_t *handle,
-			    snd_pcm_hw_params_t *params,
-			    snd_pcm_plugin_t **r_plugin);
-int snd_pcm_plugin_build_linear(snd_pcm_plug_t *handle,
-				snd_pcm_plugin_format_t *src_format,
-				snd_pcm_plugin_format_t *dst_format,
-				snd_pcm_plugin_t **r_plugin);
-int snd_pcm_plugin_build_mulaw(snd_pcm_plug_t *handle,
-			       snd_pcm_plugin_format_t *src_format,
-			       snd_pcm_plugin_format_t *dst_format,
-			       snd_pcm_plugin_t **r_plugin);
-int snd_pcm_plugin_build_rate(snd_pcm_plug_t *handle,
-			      snd_pcm_plugin_format_t *src_format,
-			      snd_pcm_plugin_format_t *dst_format,
-			      snd_pcm_plugin_t **r_plugin);
-int snd_pcm_plugin_build_route(snd_pcm_plug_t *handle,
-			       snd_pcm_plugin_format_t *src_format,
-			       snd_pcm_plugin_format_t *dst_format,
-			       route_ttable_entry_t *ttable,
-		               snd_pcm_plugin_t **r_plugin);
-int snd_pcm_plugin_build_copy(snd_pcm_plug_t *handle,
-			      snd_pcm_plugin_format_t *src_format,
-			      snd_pcm_plugin_format_t *dst_format,
-			      snd_pcm_plugin_t **r_plugin);
+int snd_pcm_plugin_build_io(struct snd_pcm_substream *handle,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_pcm_plugin **r_plugin);
+int snd_pcm_plugin_build_linear(struct snd_pcm_substream *handle,
+				struct snd_pcm_plugin_format *src_format,
+				struct snd_pcm_plugin_format *dst_format,
+				struct snd_pcm_plugin **r_plugin);
+int snd_pcm_plugin_build_mulaw(struct snd_pcm_substream *handle,
+			       struct snd_pcm_plugin_format *src_format,
+			       struct snd_pcm_plugin_format *dst_format,
+			       struct snd_pcm_plugin **r_plugin);
+int snd_pcm_plugin_build_rate(struct snd_pcm_substream *handle,
+			      struct snd_pcm_plugin_format *src_format,
+			      struct snd_pcm_plugin_format *dst_format,
+			      struct snd_pcm_plugin **r_plugin);
+int snd_pcm_plugin_build_route(struct snd_pcm_substream *handle,
+			       struct snd_pcm_plugin_format *src_format,
+			       struct snd_pcm_plugin_format *dst_format,
+			       int *ttable,
+		               struct snd_pcm_plugin **r_plugin);
+int snd_pcm_plugin_build_copy(struct snd_pcm_substream *handle,
+			      struct snd_pcm_plugin_format *src_format,
+			      struct snd_pcm_plugin_format *dst_format,
+			      struct snd_pcm_plugin **r_plugin);
 
-int snd_pcm_plug_format_plugins(snd_pcm_plug_t *substream,
-				snd_pcm_hw_params_t *params,
-				snd_pcm_hw_params_t *slave_params);
+int snd_pcm_plug_format_plugins(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params,
+				struct snd_pcm_hw_params *slave_params);
 
-int snd_pcm_plug_slave_format(int format, snd_mask_t *format_mask);
+int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask);
 
-int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin);
+int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin);
 
-snd_pcm_sframes_t snd_pcm_plug_write_transfer(snd_pcm_plug_t *handle, snd_pcm_plugin_channel_t *src_channels, snd_pcm_uframes_t size);
-snd_pcm_sframes_t snd_pcm_plug_read_transfer(snd_pcm_plug_t *handle, snd_pcm_plugin_channel_t *dst_channels_final, snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *handle,
+					      struct snd_pcm_plugin_channel *src_channels,
+					      snd_pcm_uframes_t size);
+snd_pcm_sframes_t snd_pcm_plug_read_transfer(struct snd_pcm_substream *handle,
+					     struct snd_pcm_plugin_channel *dst_channels_final,
+					     snd_pcm_uframes_t size);
 
-snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(snd_pcm_plug_t *handle,
-					 char *buf, snd_pcm_uframes_t count,
-					 snd_pcm_plugin_channel_t **channels);
+snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(struct snd_pcm_substream *handle,
+						   char *buf, snd_pcm_uframes_t count,
+						   struct snd_pcm_plugin_channel **channels);
 
-snd_pcm_sframes_t snd_pcm_plugin_client_channels(snd_pcm_plugin_t *plugin,
-				       snd_pcm_uframes_t frames,
-				       snd_pcm_plugin_channel_t **channels);
+snd_pcm_sframes_t snd_pcm_plugin_client_channels(struct snd_pcm_plugin *plugin,
+						 snd_pcm_uframes_t frames,
+						 struct snd_pcm_plugin_channel **channels);
 
-int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
+int snd_pcm_area_silence(const struct snd_pcm_channel_area *dst_channel,
+			 size_t dst_offset,
 			 size_t samples, int format);
-int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_channel, size_t src_offset,
-		      const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
+int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_channel,
+		      size_t src_offset,
+		      const struct snd_pcm_channel_area *dst_channel,
+		      size_t dst_offset,
 		      size_t samples, int format);
 
-void *snd_pcm_plug_buf_alloc(snd_pcm_plug_t *plug, snd_pcm_uframes_t size);
-void snd_pcm_plug_buf_unlock(snd_pcm_plug_t *plug, void *ptr);
-snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char *ptr, snd_pcm_uframes_t size, int in_kernel);
-snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, snd_pcm_uframes_t size, int in_kernel);
-snd_pcm_sframes_t snd_pcm_oss_writev3(snd_pcm_substream_t *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel);
-snd_pcm_sframes_t snd_pcm_oss_readv3(snd_pcm_substream_t *substream, void **bufs, snd_pcm_uframes_t frames, int in_kernel);
-
-
+void *snd_pcm_plug_buf_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t size);
+void snd_pcm_plug_buf_unlock(struct snd_pcm_substream *plug, void *ptr);
+snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream,
+				     const char *ptr, snd_pcm_uframes_t size,
+				     int in_kernel);
+snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream,
+				    char *ptr, snd_pcm_uframes_t size, int in_kernel);
+snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream,
+				      void **bufs, snd_pcm_uframes_t frames,
+				      int in_kernel);
+snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream,
+				     void **bufs, snd_pcm_uframes_t frames,
+				     int in_kernel);
 
 #define ROUTE_PLUGIN_RESOLUTION 16
 
@@ -237,8 +187,8 @@
 int copy_index(int format);
 int conv_index(int src_format, int dst_format);
 
-void zero_channel(snd_pcm_plugin_t *plugin,
-		  const snd_pcm_plugin_channel_t *dst_channel,
+void zero_channel(struct snd_pcm_plugin *plugin,
+		  const struct snd_pcm_plugin_channel *dst_channel,
 		  size_t samples);
 
 #ifdef PLUGIN_DEBUG
diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c
index 1096ec1..4854cef 100644
--- a/sound/core/oss/rate.c
+++ b/sound/core/oss/rate.c
@@ -33,29 +33,29 @@
  *  Basic rate conversion plugin
  */
 
-typedef struct {
+struct rate_channel {
 	signed short last_S1;
 	signed short last_S2;
-} rate_channel_t;
+};
  
-typedef void (*rate_f)(snd_pcm_plugin_t *plugin,
-		       const snd_pcm_plugin_channel_t *src_channels,
-		       snd_pcm_plugin_channel_t *dst_channels,
+typedef void (*rate_f)(struct snd_pcm_plugin *plugin,
+		       const struct snd_pcm_plugin_channel *src_channels,
+		       struct snd_pcm_plugin_channel *dst_channels,
 		       int src_frames, int dst_frames);
 
-typedef struct rate_private_data {
+struct rate_priv {
 	unsigned int pitch;
 	unsigned int pos;
 	rate_f func;
 	int get, put;
 	snd_pcm_sframes_t old_src_frames, old_dst_frames;
-	rate_channel_t channels[0];
-} rate_t;
+	struct rate_channel channels[0];
+};
 
-static void rate_init(snd_pcm_plugin_t *plugin)
+static void rate_init(struct snd_pcm_plugin *plugin)
 {
 	unsigned int channel;
-	rate_t *data = (rate_t *)plugin->extra_data;
+	struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
 	data->pos = 0;
 	for (channel = 0; channel < plugin->src_format.channels; channel++) {
 		data->channels[channel].last_S1 = 0;
@@ -63,9 +63,9 @@
 	}
 }
 
-static void resample_expand(snd_pcm_plugin_t *plugin,
-			    const snd_pcm_plugin_channel_t *src_channels,
-			    snd_pcm_plugin_channel_t *dst_channels,
+static void resample_expand(struct snd_pcm_plugin *plugin,
+			    const struct snd_pcm_plugin_channel *src_channels,
+			    struct snd_pcm_plugin_channel *dst_channels,
 			    int src_frames, int dst_frames)
 {
 	unsigned int pos = 0;
@@ -75,8 +75,8 @@
 	unsigned int channel;
 	int src_step, dst_step;
 	int src_frames1, dst_frames1;
-	rate_t *data = (rate_t *)plugin->extra_data;
-	rate_channel_t *rchannels = data->channels;
+	struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
+	struct rate_channel *rchannels = data->channels;
 
 #define GET_S16_LABELS
 #define PUT_S16_LABELS
@@ -139,9 +139,9 @@
 	data->pos = pos;
 }
 
-static void resample_shrink(snd_pcm_plugin_t *plugin,
-			    const snd_pcm_plugin_channel_t *src_channels,
-			    snd_pcm_plugin_channel_t *dst_channels,
+static void resample_shrink(struct snd_pcm_plugin *plugin,
+			    const struct snd_pcm_plugin_channel *src_channels,
+			    struct snd_pcm_plugin_channel *dst_channels,
 			    int src_frames, int dst_frames)
 {
 	unsigned int pos = 0;
@@ -151,8 +151,8 @@
 	unsigned int channel;
 	int src_step, dst_step;
 	int src_frames1, dst_frames1;
-	rate_t *data = (rate_t *)plugin->extra_data;
-	rate_channel_t *rchannels = data->channels;
+	struct rate_priv *data = (struct rate_priv *)plugin->extra_data;
+	struct rate_channel *rchannels = data->channels;
 	
 #define GET_S16_LABELS
 #define PUT_S16_LABELS
@@ -216,15 +216,15 @@
 	data->pos = pos;
 }
 
-static snd_pcm_sframes_t rate_src_frames(snd_pcm_plugin_t *plugin, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t rate_src_frames(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
 {
-	rate_t *data;
+	struct rate_priv *data;
 	snd_pcm_sframes_t res;
 
 	snd_assert(plugin != NULL, return -ENXIO);
 	if (frames == 0)
 		return 0;
-	data = (rate_t *)plugin->extra_data;
+	data = (struct rate_priv *)plugin->extra_data;
 	if (plugin->src_format.rate < plugin->dst_format.rate) {
 		res = (((frames * data->pitch) + (BITS/2)) >> SHIFT);
 	} else {
@@ -248,15 +248,15 @@
 	return res;
 }
 
-static snd_pcm_sframes_t rate_dst_frames(snd_pcm_plugin_t *plugin, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t rate_dst_frames(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
 {
-	rate_t *data;
+	struct rate_priv *data;
 	snd_pcm_sframes_t res;
 
 	snd_assert(plugin != NULL, return -ENXIO);
 	if (frames == 0)
 		return 0;
-	data = (rate_t *)plugin->extra_data;
+	data = (struct rate_priv *)plugin->extra_data;
 	if (plugin->src_format.rate < plugin->dst_format.rate) {
 		res = (((frames << SHIFT) + (data->pitch / 2)) / data->pitch);
 	} else {
@@ -280,13 +280,13 @@
 	return res;
 }
 
-static snd_pcm_sframes_t rate_transfer(snd_pcm_plugin_t *plugin,
-			     const snd_pcm_plugin_channel_t *src_channels,
-			     snd_pcm_plugin_channel_t *dst_channels,
+static snd_pcm_sframes_t rate_transfer(struct snd_pcm_plugin *plugin,
+			     const struct snd_pcm_plugin_channel *src_channels,
+			     struct snd_pcm_plugin_channel *dst_channels,
 			     snd_pcm_uframes_t frames)
 {
 	snd_pcm_uframes_t dst_frames;
-	rate_t *data;
+	struct rate_priv *data;
 
 	snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
 	if (frames == 0)
@@ -308,14 +308,14 @@
 	dst_frames = rate_dst_frames(plugin, frames);
 	if (dst_frames > dst_channels[0].frames)
 		dst_frames = dst_channels[0].frames;
-	data = (rate_t *)plugin->extra_data;
+	data = (struct rate_priv *)plugin->extra_data;
 	data->func(plugin, src_channels, dst_channels, frames, dst_frames);
 	return dst_frames;
 }
 
-static int rate_action(snd_pcm_plugin_t *plugin,
-		       snd_pcm_plugin_action_t action,
-		       unsigned long udata ATTRIBUTE_UNUSED)
+static int rate_action(struct snd_pcm_plugin *plugin,
+		       enum snd_pcm_plugin_action action,
+		       unsigned long udata)
 {
 	snd_assert(plugin != NULL, return -ENXIO);
 	switch (action) {
@@ -329,14 +329,14 @@
 	return 0;	/* silenty ignore other actions */
 }
 
-int snd_pcm_plugin_build_rate(snd_pcm_plug_t *plug,
-			      snd_pcm_plugin_format_t *src_format,
-			      snd_pcm_plugin_format_t *dst_format,
-			      snd_pcm_plugin_t **r_plugin)
+int snd_pcm_plugin_build_rate(struct snd_pcm_substream *plug,
+			      struct snd_pcm_plugin_format *src_format,
+			      struct snd_pcm_plugin_format *dst_format,
+			      struct snd_pcm_plugin **r_plugin)
 {
 	int err;
-	rate_t *data;
-	snd_pcm_plugin_t *plugin;
+	struct rate_priv *data;
+	struct snd_pcm_plugin *plugin;
 
 	snd_assert(r_plugin != NULL, return -ENXIO);
 	*r_plugin = NULL;
@@ -349,11 +349,12 @@
 
 	err = snd_pcm_plugin_build(plug, "rate conversion",
 				   src_format, dst_format,
-				   sizeof(rate_t) + src_format->channels * sizeof(rate_channel_t),
+				   sizeof(struct rate_priv) +
+				   src_format->channels * sizeof(struct rate_channel),
 				   &plugin);
 	if (err < 0)
 		return err;
-	data = (rate_t *)plugin->extra_data;
+	data = (struct rate_priv *)plugin->extra_data;
 	data->get = getput_index(src_format->format);
 	snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
 	data->put = getput_index(dst_format->format);
diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c
index c955b7d..726c5ca 100644
--- a/sound/core/oss/route.c
+++ b/sound/core/oss/route.c
@@ -35,61 +35,62 @@
 #error "Add some code here"
 #endif
 
-typedef struct ttable_dst ttable_dst_t;
-typedef struct route_private_data route_t;
+struct ttable_dst;
 
-typedef void (*route_channel_f)(snd_pcm_plugin_t *plugin,
-			      const snd_pcm_plugin_channel_t *src_channels,
-			      snd_pcm_plugin_channel_t *dst_channel,
-			      ttable_dst_t* ttable, snd_pcm_uframes_t frames);
+typedef void (*route_channel_f)(struct snd_pcm_plugin *plugin,
+				const struct snd_pcm_plugin_channel *src_channels,
+				struct snd_pcm_plugin_channel *dst_channel,
+				struct ttable_dst *ttable, snd_pcm_uframes_t frames);
 
-typedef struct {
+struct ttable_src {
 	int channel;
 	int as_int;
-} ttable_src_t;
+};
 
 struct ttable_dst {
 	int att;	/* Attenuated */
 	unsigned int nsrcs;
-	ttable_src_t* srcs;
+	struct ttable_src *srcs;
 	route_channel_f func;
 };
 
-struct route_private_data {
+struct route_priv {
 	enum {R_UINT32=0, R_UINT64=1} sum_type;
 	int get, put;
 	int conv;
 	int src_sample_size;
-	ttable_dst_t ttable[0];
+	struct ttable_dst ttable[0];
 };
 
-typedef union {
+union sum {
 	u_int32_t as_uint32;
 	u_int64_t as_uint64;
-} sum_t;
+};
 
 
-static void route_to_channel_from_zero(snd_pcm_plugin_t *plugin,
-				     const snd_pcm_plugin_channel_t *src_channels ATTRIBUTE_UNUSED,
-				     snd_pcm_plugin_channel_t *dst_channel,
-				     ttable_dst_t* ttable ATTRIBUTE_UNUSED, snd_pcm_uframes_t frames)
+static void route_to_channel_from_zero(struct snd_pcm_plugin *plugin,
+				       const struct snd_pcm_plugin_channel *src_channels,
+				       struct snd_pcm_plugin_channel *dst_channel,
+				       struct ttable_dst *ttable,
+				       snd_pcm_uframes_t frames)
 {
 	if (dst_channel->wanted)
 		snd_pcm_area_silence(&dst_channel->area, 0, frames, plugin->dst_format.format);
 	dst_channel->enabled = 0;
 }
 
-static void route_to_channel_from_one(snd_pcm_plugin_t *plugin,
-				    const snd_pcm_plugin_channel_t *src_channels,
-				    snd_pcm_plugin_channel_t *dst_channel,
-				    ttable_dst_t* ttable, snd_pcm_uframes_t frames)
+static void route_to_channel_from_one(struct snd_pcm_plugin *plugin,
+				      const struct snd_pcm_plugin_channel *src_channels,
+				      struct snd_pcm_plugin_channel *dst_channel,
+				      struct ttable_dst *ttable,
+				      snd_pcm_uframes_t frames)
 {
 #define CONV_LABELS
 #include "plugin_ops.h"
 #undef CONV_LABELS
-	route_t *data = (route_t *)plugin->extra_data;
+	struct route_priv *data = (struct route_priv *)plugin->extra_data;
 	void *conv;
-	const snd_pcm_plugin_channel_t *src_channel = NULL;
+	const struct snd_pcm_plugin_channel *src_channel = NULL;
 	unsigned int srcidx;
 	char *src, *dst;
 	int src_step, dst_step;
@@ -120,10 +121,10 @@
 	}
 }
 
-static void route_to_channel(snd_pcm_plugin_t *plugin,
-			   const snd_pcm_plugin_channel_t *src_channels,
-			   snd_pcm_plugin_channel_t *dst_channel,
-			   ttable_dst_t* ttable, snd_pcm_uframes_t frames)
+static void route_to_channel(struct snd_pcm_plugin *plugin,
+			     const struct snd_pcm_plugin_channel *src_channels,
+			     struct snd_pcm_plugin_channel *dst_channel,
+			     struct ttable_dst *ttable, snd_pcm_uframes_t frames)
 {
 #define GET_U_LABELS
 #define PUT_U32_LABELS
@@ -153,18 +154,18 @@
 					 &&norm_int64_16_att,
 					 &&norm_int64_24_att,
 	};
-	route_t *data = (route_t *)plugin->extra_data;
+	struct route_priv *data = (struct route_priv *)plugin->extra_data;
 	void *zero, *get, *add, *norm, *put_u32;
 	int nsrcs = ttable->nsrcs;
 	char *dst;
 	int dst_step;
 	char *srcs[nsrcs];
 	int src_steps[nsrcs];
-	ttable_src_t src_tt[nsrcs];
+	struct ttable_src src_tt[nsrcs];
 	u_int32_t sample = 0;
 	int srcidx, srcidx1 = 0;
 	for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
-		const snd_pcm_plugin_channel_t *src_channel = &src_channels[ttable->srcs[srcidx].channel];
+		const struct snd_pcm_plugin_channel *src_channel = &src_channels[ttable->srcs[srcidx].channel];
 		if (!src_channel->enabled)
 			continue;
 		srcs[srcidx1] = src_channel->area.addr + src_channel->area.first / 8;
@@ -191,8 +192,8 @@
 	dst_step = dst_channel->area.step / 8;
 
 	while (frames-- > 0) {
-		ttable_src_t *ttp = src_tt;
-		sum_t sum;
+		struct ttable_src *ttp = src_tt;
+		union sum sum;
 
 		/* Zero sum */
 		goto *zero;
@@ -297,47 +298,47 @@
 	}
 }
 
-static int route_src_channels_mask(snd_pcm_plugin_t *plugin,
-				   bitset_t *dst_vmask,
-				   bitset_t **src_vmask)
+static int route_src_channels_mask(struct snd_pcm_plugin *plugin,
+				   unsigned long *dst_vmask,
+				   unsigned long **src_vmask)
 {
-	route_t *data = (route_t *)plugin->extra_data;
+	struct route_priv *data = (struct route_priv *)plugin->extra_data;
 	int schannels = plugin->src_format.channels;
 	int dchannels = plugin->dst_format.channels;
-	bitset_t *vmask = plugin->src_vmask;
+	unsigned long *vmask = plugin->src_vmask;
 	int channel;
-	ttable_dst_t *dp = data->ttable;
-	bitset_zero(vmask, schannels);
+	struct ttable_dst *dp = data->ttable;
+	bitmap_zero(vmask, schannels);
 	for (channel = 0; channel < dchannels; channel++, dp++) {
 		unsigned int src;
-		ttable_src_t *sp;
-		if (!bitset_get(dst_vmask, channel))
+		struct ttable_src *sp;
+		if (!test_bit(channel, dst_vmask))
 			continue;
 		sp = dp->srcs;
 		for (src = 0; src < dp->nsrcs; src++, sp++)
-			bitset_set(vmask, sp->channel);
+			set_bit(sp->channel, vmask);
 	}
 	*src_vmask = vmask;
 	return 0;
 }
 
-static int route_dst_channels_mask(snd_pcm_plugin_t *plugin,
-				   bitset_t *src_vmask,
-				   bitset_t **dst_vmask)
+static int route_dst_channels_mask(struct snd_pcm_plugin *plugin,
+				   unsigned long *src_vmask,
+				   unsigned long **dst_vmask)
 {
-	route_t *data = (route_t *)plugin->extra_data;
+	struct route_priv *data = (struct route_priv *)plugin->extra_data;
 	int dchannels = plugin->dst_format.channels;
-	bitset_t *vmask = plugin->dst_vmask;
+	unsigned long *vmask = plugin->dst_vmask;
 	int channel;
-	ttable_dst_t *dp = data->ttable;
-	bitset_zero(vmask, dchannels);
+	struct ttable_dst *dp = data->ttable;
+	bitmap_zero(vmask, dchannels);
 	for (channel = 0; channel < dchannels; channel++, dp++) {
 		unsigned int src;
-		ttable_src_t *sp;
+		struct ttable_src *sp;
 		sp = dp->srcs;
 		for (src = 0; src < dp->nsrcs; src++, sp++) {
-			if (bitset_get(src_vmask, sp->channel)) {
-				bitset_set(vmask, channel);
+			if (test_bit(sp->channel, src_vmask)) {
+				set_bit(channel, vmask);
 				break;
 			}
 		}
@@ -346,33 +347,33 @@
 	return 0;
 }
 
-static void route_free(snd_pcm_plugin_t *plugin)
+static void route_free(struct snd_pcm_plugin *plugin)
 {
-	route_t *data = (route_t *)plugin->extra_data;
+	struct route_priv *data = (struct route_priv *)plugin->extra_data;
 	unsigned int dst_channel;
 	for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
 		kfree(data->ttable[dst_channel].srcs);
 	}
 }
 
-static int route_load_ttable(snd_pcm_plugin_t *plugin, 
-			     const route_ttable_entry_t* src_ttable)
+static int route_load_ttable(struct snd_pcm_plugin *plugin, 
+			     const int *src_ttable)
 {
-	route_t *data;
+	struct route_priv *data;
 	unsigned int src_channel, dst_channel;
-	const route_ttable_entry_t *sptr;
-	ttable_dst_t *dptr;
+	const int *sptr;
+	struct ttable_dst *dptr;
 	if (src_ttable == NULL)
 		return 0;
-	data = (route_t *)plugin->extra_data;
+	data = (struct route_priv *)plugin->extra_data;
 	dptr = data->ttable;
 	sptr = src_ttable;
 	plugin->private_free = route_free;
 	for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
-		route_ttable_entry_t t = 0;
+		int t = 0;
 		int att = 0;
 		int nsrcs = 0;
-		ttable_src_t srcs[plugin->src_format.channels];
+		struct ttable_src srcs[plugin->src_format.channels];
 		for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) {
 			snd_assert(*sptr >= 0 || *sptr <= FULL, return -ENXIO);
 			if (*sptr != 0) {
@@ -405,21 +406,21 @@
 	return 0;
 }
 
-static snd_pcm_sframes_t route_transfer(snd_pcm_plugin_t *plugin,
-			      const snd_pcm_plugin_channel_t *src_channels,
-			      snd_pcm_plugin_channel_t *dst_channels,
+static snd_pcm_sframes_t route_transfer(struct snd_pcm_plugin *plugin,
+			      const struct snd_pcm_plugin_channel *src_channels,
+			      struct snd_pcm_plugin_channel *dst_channels,
 			      snd_pcm_uframes_t frames)
 {
-	route_t *data;
+	struct route_priv *data;
 	int src_nchannels, dst_nchannels;
 	int dst_channel;
-	ttable_dst_t *ttp;
-	snd_pcm_plugin_channel_t *dvp;
+	struct ttable_dst *ttp;
+	struct snd_pcm_plugin_channel *dvp;
 
 	snd_assert(plugin != NULL && src_channels != NULL && dst_channels != NULL, return -ENXIO);
 	if (frames == 0)
 		return 0;
-	data = (route_t *)plugin->extra_data;
+	data = (struct route_priv *)plugin->extra_data;
 
 	src_nchannels = plugin->src_format.channels;
 	dst_nchannels = plugin->dst_format.channels;
@@ -469,14 +470,14 @@
 	return width * 4 + endian * 2 + sign;
 }
 
-int snd_pcm_plugin_build_route(snd_pcm_plug_t *plug,
-			       snd_pcm_plugin_format_t *src_format,
-			       snd_pcm_plugin_format_t *dst_format,
-			       route_ttable_entry_t *ttable,
-			       snd_pcm_plugin_t **r_plugin)
+int snd_pcm_plugin_build_route(struct snd_pcm_substream *plug,
+			       struct snd_pcm_plugin_format *src_format,
+			       struct snd_pcm_plugin_format *dst_format,
+			       int *ttable,
+			       struct snd_pcm_plugin **r_plugin)
 {
-	route_t *data;
-	snd_pcm_plugin_t *plugin;
+	struct route_priv *data;
+	struct snd_pcm_plugin *plugin;
 	int err;
 
 	snd_assert(r_plugin != NULL, return -ENXIO);
@@ -488,12 +489,13 @@
 
 	err = snd_pcm_plugin_build(plug, "attenuated route conversion",
 				   src_format, dst_format,
-				   sizeof(route_t) + sizeof(data->ttable[0]) * dst_format->channels,
+				   sizeof(struct route_priv) +
+				   sizeof(data->ttable[0]) * dst_format->channels,
 				   &plugin);
 	if (err < 0)
 		return err;
 
-	data = (route_t *) plugin->extra_data;
+	data = (struct route_priv *)plugin->extra_data;
 
 	data->get = getput_index(src_format->format);
 	snd_assert(data->get >= 0 && data->get < 4*2*2, return -EINVAL);
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 184e74b..28ca61e 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -33,23 +33,33 @@
 MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");
 MODULE_LICENSE("GPL");
 
-snd_pcm_t *snd_pcm_devices[SNDRV_CARDS * SNDRV_PCM_DEVICES];
+static LIST_HEAD(snd_pcm_devices);
 static LIST_HEAD(snd_pcm_notify_list);
 static DECLARE_MUTEX(register_mutex);
 
-static int snd_pcm_free(snd_pcm_t *pcm);
-static int snd_pcm_dev_free(snd_device_t *device);
-static int snd_pcm_dev_register(snd_device_t *device);
-static int snd_pcm_dev_disconnect(snd_device_t *device);
-static int snd_pcm_dev_unregister(snd_device_t *device);
+static int snd_pcm_free(struct snd_pcm *pcm);
+static int snd_pcm_dev_free(struct snd_device *device);
+static int snd_pcm_dev_register(struct snd_device *device);
+static int snd_pcm_dev_disconnect(struct snd_device *device);
+static int snd_pcm_dev_unregister(struct snd_device *device);
 
-static int snd_pcm_control_ioctl(snd_card_t * card,
-				 snd_ctl_file_t * control,
+static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device)
+{
+	struct list_head *p;
+	struct snd_pcm *pcm;
+
+	list_for_each(p, &snd_pcm_devices) {
+		pcm = list_entry(p, struct snd_pcm, list);
+		if (pcm->card == card && pcm->device == device)
+			return pcm;
+	}
+	return NULL;
+}
+
+static int snd_pcm_control_ioctl(struct snd_card *card,
+				 struct snd_ctl_file *control,
 				 unsigned int cmd, unsigned long arg)
 {
-	unsigned int tmp;
-
-	tmp = card->number * SNDRV_PCM_DEVICES;
 	switch (cmd) {
 	case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE:
 		{
@@ -57,51 +67,66 @@
 
 			if (get_user(device, (int __user *)arg))
 				return -EFAULT;
+			down(&register_mutex);
 			device = device < 0 ? 0 : device + 1;
 			while (device < SNDRV_PCM_DEVICES) {
-				if (snd_pcm_devices[tmp + device])
+				if (snd_pcm_search(card, device))
 					break;
 				device++;
 			}
 			if (device == SNDRV_PCM_DEVICES)
 				device = -1;
+			up(&register_mutex);
 			if (put_user(device, (int __user *)arg))
 				return -EFAULT;
 			return 0;
 		}
 	case SNDRV_CTL_IOCTL_PCM_INFO:
 		{
-			snd_pcm_info_t __user *info;
+			struct snd_pcm_info __user *info;
 			unsigned int device, subdevice;
-			snd_pcm_stream_t stream;
-			snd_pcm_t *pcm;
-			snd_pcm_str_t *pstr;
-			snd_pcm_substream_t *substream;
-			info = (snd_pcm_info_t __user *)arg;
+			int stream;
+			struct snd_pcm *pcm;
+			struct snd_pcm_str *pstr;
+			struct snd_pcm_substream *substream;
+			int err;
+
+			info = (struct snd_pcm_info __user *)arg;
 			if (get_user(device, &info->device))
 				return -EFAULT;
-			if (device >= SNDRV_PCM_DEVICES)
-				return -ENXIO;
-			pcm = snd_pcm_devices[tmp + device];
-			if (pcm == NULL)
-				return -ENXIO;
 			if (get_user(stream, &info->stream))
 				return -EFAULT;
 			if (stream < 0 || stream > 1)
 				return -EINVAL;
-			pstr = &pcm->streams[stream];
-			if (pstr->substream_count == 0)
-				return -ENOENT;
 			if (get_user(subdevice, &info->subdevice))
 				return -EFAULT;
-			if (subdevice >= pstr->substream_count)
-				return -ENXIO;
-			for (substream = pstr->substream; substream; substream = substream->next)
+			down(&register_mutex);
+			pcm = snd_pcm_search(card, device);
+			if (pcm == NULL) {
+				err = -ENXIO;
+				goto _error;
+			}
+			pstr = &pcm->streams[stream];
+			if (pstr->substream_count == 0) {
+				err = -ENOENT;
+				goto _error;
+			}
+			if (subdevice >= pstr->substream_count) {
+				err = -ENXIO;
+				goto _error;
+			}
+			for (substream = pstr->substream; substream;
+			     substream = substream->next)
 				if (substream->number == (int)subdevice)
 					break;
-			if (substream == NULL)
-				return -ENXIO;
-			return snd_pcm_info_user(substream, info);
+			if (substream == NULL) {
+				err = -ENXIO;
+				goto _error;
+			}
+			err = snd_pcm_info_user(substream, info);
+		_error:
+			up(&register_mutex);
+			return err;
 		}
 	case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
 		{
@@ -126,30 +151,6 @@
 #define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
 #define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v 
 
-static char *snd_pcm_stream_names[] = {
-	STREAM(PLAYBACK),
-	STREAM(CAPTURE),
-};
-
-static char *snd_pcm_state_names[] = {
-	STATE(OPEN),
-	STATE(SETUP),
-	STATE(PREPARED),
-	STATE(RUNNING),
-	STATE(XRUN),
-	STATE(DRAINING),
-	STATE(PAUSED),
-	STATE(SUSPENDED),
-};
-
-static char *snd_pcm_access_names[] = {
-	ACCESS(MMAP_INTERLEAVED), 
-	ACCESS(MMAP_NONINTERLEAVED),
-	ACCESS(MMAP_COMPLEX),
-	ACCESS(RW_INTERLEAVED),
-	ACCESS(RW_NONINTERLEAVED),
-};
-
 static char *snd_pcm_format_names[] = {
 	FORMAT(S8),
 	FORMAT(U8),
@@ -191,6 +192,36 @@
 	FORMAT(U18_3BE),
 };
 
+const char *snd_pcm_format_name(snd_pcm_format_t format)
+{
+	return snd_pcm_format_names[format];
+}
+
+#ifdef CONFIG_PROC_FS
+static char *snd_pcm_stream_names[] = {
+	STREAM(PLAYBACK),
+	STREAM(CAPTURE),
+};
+
+static char *snd_pcm_state_names[] = {
+	STATE(OPEN),
+	STATE(SETUP),
+	STATE(PREPARED),
+	STATE(RUNNING),
+	STATE(XRUN),
+	STATE(DRAINING),
+	STATE(PAUSED),
+	STATE(SUSPENDED),
+};
+
+static char *snd_pcm_access_names[] = {
+	ACCESS(MMAP_INTERLEAVED), 
+	ACCESS(MMAP_NONINTERLEAVED),
+	ACCESS(MMAP_COMPLEX),
+	ACCESS(RW_INTERLEAVED),
+	ACCESS(RW_NONINTERLEAVED),
+};
+
 static char *snd_pcm_subformat_names[] = {
 	SUBFORMAT(STD), 
 };
@@ -200,7 +231,7 @@
 	TSTAMP(MMAP),
 };
 
-static const char *snd_pcm_stream_name(snd_pcm_stream_t stream)
+static const char *snd_pcm_stream_name(int stream)
 {
 	snd_assert(stream <= SNDRV_PCM_STREAM_LAST, return NULL);
 	return snd_pcm_stream_names[stream];
@@ -208,23 +239,15 @@
 
 static const char *snd_pcm_access_name(snd_pcm_access_t access)
 {
-	snd_assert(access <= SNDRV_PCM_ACCESS_LAST, return NULL);
 	return snd_pcm_access_names[access];
 }
 
-const char *snd_pcm_format_name(snd_pcm_format_t format)
-{
-	snd_assert(format <= SNDRV_PCM_FORMAT_LAST, return NULL);
-	return snd_pcm_format_names[format];
-}
-
 static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
 {
-	snd_assert(subformat <= SNDRV_PCM_SUBFORMAT_LAST, return NULL);
 	return snd_pcm_subformat_names[subformat];
 }
 
-static const char *snd_pcm_tstamp_mode_name(snd_pcm_tstamp_t mode)
+static const char *snd_pcm_tstamp_mode_name(int mode)
 {
 	snd_assert(mode <= SNDRV_PCM_TSTAMP_LAST, return NULL);
 	return snd_pcm_tstamp_mode_names[mode];
@@ -232,7 +255,6 @@
 
 static const char *snd_pcm_state_name(snd_pcm_state_t state)
 {
-	snd_assert(state <= SNDRV_PCM_STATE_LAST, return NULL);
 	return snd_pcm_state_names[state];
 }
 
@@ -267,10 +289,10 @@
 }
 #endif
 
-#ifdef CONFIG_PROC_FS
-static void snd_pcm_proc_info_read(snd_pcm_substream_t *substream, snd_info_buffer_t *buffer)
+static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
+				   struct snd_info_buffer *buffer)
 {
-	snd_pcm_info_t *info;
+	struct snd_pcm_info *info;
 	int err;
 
 	if (! substream)
@@ -302,20 +324,25 @@
 	kfree(info);
 }
 
-static void snd_pcm_stream_proc_info_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,
+					  struct snd_info_buffer *buffer)
 {
-	snd_pcm_proc_info_read(((snd_pcm_str_t *)entry->private_data)->substream, buffer);
+	snd_pcm_proc_info_read(((struct snd_pcm_str *)entry->private_data)->substream,
+			       buffer);
 }
 
-static void snd_pcm_substream_proc_info_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry,
+					     struct snd_info_buffer *buffer)
 {
-	snd_pcm_proc_info_read((snd_pcm_substream_t *)entry->private_data, buffer);
+	snd_pcm_proc_info_read((struct snd_pcm_substream *)entry->private_data,
+			       buffer);
 }
 
-static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
+						  struct snd_info_buffer *buffer)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_substream *substream = entry->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (!runtime) {
 		snd_iprintf(buffer, "closed\n");
 		return;
@@ -347,10 +374,11 @@
 	snd_pcm_stream_unlock_irq(substream);
 }
 
-static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
+						  struct snd_info_buffer *buffer)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_substream *substream = entry->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (!runtime) {
 		snd_iprintf(buffer, "closed\n");
 		return;
@@ -374,11 +402,12 @@
 	snd_pcm_stream_unlock_irq(substream);
 }
 
-static void snd_pcm_substream_proc_status_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
+					       struct snd_info_buffer *buffer)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_status_t status;
+	struct snd_pcm_substream *substream = entry->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_pcm_status status;
 	int err;
 	if (!runtime) {
 		snd_iprintf(buffer, "closed\n");
@@ -402,28 +431,29 @@
 	snd_iprintf(buffer, "hw_ptr      : %ld\n", runtime->status->hw_ptr);
 	snd_iprintf(buffer, "appl_ptr    : %ld\n", runtime->control->appl_ptr);
 }
-#endif
 
 #ifdef CONFIG_SND_DEBUG
-static void snd_pcm_xrun_debug_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
+				    struct snd_info_buffer *buffer)
 {
-	snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data;
+	struct snd_pcm_str *pstr = entry->private_data;
 	snd_iprintf(buffer, "%d\n", pstr->xrun_debug);
 }
 
-static void snd_pcm_xrun_debug_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_pcm_xrun_debug_write(struct snd_info_entry *entry,
+				     struct snd_info_buffer *buffer)
 {
-	snd_pcm_str_t *pstr = (snd_pcm_str_t *)entry->private_data;
+	struct snd_pcm_str *pstr = entry->private_data;
 	char line[64];
 	if (!snd_info_get_line(buffer, line, sizeof(line)))
 		pstr->xrun_debug = simple_strtoul(line, NULL, 10);
 }
 #endif
 
-static int snd_pcm_stream_proc_init(snd_pcm_str_t *pstr)
+static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
 {
-	snd_pcm_t *pcm = pstr->pcm;
-	snd_info_entry_t *entry;
+	struct snd_pcm *pcm = pstr->pcm;
+	struct snd_info_entry *entry;
 	char name[16];
 
 	sprintf(name, "pcm%i%c", pcm->device, 
@@ -447,7 +477,8 @@
 	pstr->proc_info_entry = entry;
 
 #ifdef CONFIG_SND_DEBUG
-	if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug", pstr->proc_root)) != NULL) {
+	if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
+						pstr->proc_root)) != NULL) {
 		entry->c.text.read_size = 64;
 		entry->c.text.read = snd_pcm_xrun_debug_read;
 		entry->c.text.write_size = 64;
@@ -464,7 +495,7 @@
 	return 0;
 }
 
-static int snd_pcm_stream_proc_done(snd_pcm_str_t *pstr)
+static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr)
 {
 #ifdef CONFIG_SND_DEBUG
 	if (pstr->proc_xrun_debug_entry) {
@@ -483,10 +514,10 @@
 	return 0;
 }
 
-static int snd_pcm_substream_proc_init(snd_pcm_substream_t *substream)
+static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
 {
-	snd_info_entry_t *entry;
-	snd_card_t *card;
+	struct snd_info_entry *entry;
+	struct snd_card *card;
 	char name[16];
 
 	card = substream->pcm->card;
@@ -540,7 +571,7 @@
 	return 0;
 }
 		
-static int snd_pcm_substream_proc_done(snd_pcm_substream_t *substream)
+static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream)
 {
 	if (substream->proc_info_entry) {
 		snd_info_unregister(substream->proc_info_entry);
@@ -564,6 +595,12 @@
 	}
 	return 0;
 }
+#else /* !CONFIG_PROC_FS */
+static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }
+static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }
+static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }
+static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }
+#endif /* CONFIG_PROC_FS */
 
 /**
  * snd_pcm_new_stream - create a new PCM stream
@@ -578,11 +615,11 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
+int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
 {
 	int idx, err;
-	snd_pcm_str_t *pstr = &pcm->streams[stream];
-	snd_pcm_substream_t *substream, *prev;
+	struct snd_pcm_str *pstr = &pcm->streams[stream];
+	struct snd_pcm_substream *substream, *prev;
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	init_MUTEX(&pstr->oss.setup_mutex);
@@ -590,17 +627,20 @@
 	pstr->stream = stream;
 	pstr->pcm = pcm;
 	pstr->substream_count = substream_count;
-	pstr->reg = &snd_pcm_reg[stream];
 	if (substream_count > 0) {
 		err = snd_pcm_stream_proc_init(pstr);
-		if (err < 0)
+		if (err < 0) {
+			snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
 			return err;
+		}
 	}
 	prev = NULL;
 	for (idx = 0, prev = NULL; idx < substream_count; idx++) {
 		substream = kzalloc(sizeof(*substream), GFP_KERNEL);
-		if (substream == NULL)
+		if (substream == NULL) {
+			snd_printk(KERN_ERR "Cannot allocate PCM substream\n");
 			return -ENOMEM;
+		}
 		substream->pcm = pcm;
 		substream->pstr = pstr;
 		substream->number = idx;
@@ -613,6 +653,7 @@
 			prev->next = substream;
 		err = snd_pcm_substream_proc_init(substream);
 		if (err < 0) {
+			snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n");
 			kfree(substream);
 			return err;
 		}
@@ -642,13 +683,13 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_new(snd_card_t * card, char *id, int device,
+int snd_pcm_new(struct snd_card *card, char *id, int device,
 		int playback_count, int capture_count,
-	        snd_pcm_t ** rpcm)
+	        struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_pcm_dev_free,
 		.dev_register =	snd_pcm_dev_register,
 		.dev_disconnect = snd_pcm_dev_disconnect,
@@ -659,13 +700,14 @@
 	*rpcm = NULL;
 	snd_assert(card != NULL, return -ENXIO);
 	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
-	if (pcm == NULL)
+	if (pcm == NULL) {
+		snd_printk(KERN_ERR "Cannot allocate PCM\n");
 		return -ENOMEM;
+	}
 	pcm->card = card;
 	pcm->device = device;
-	if (id) {
+	if (id)
 		strlcpy(pcm->id, id, sizeof(pcm->id));
-	}
 	if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
 		snd_pcm_free(pcm);
 		return err;
@@ -684,11 +726,11 @@
 	return 0;
 }
 
-static void snd_pcm_free_stream(snd_pcm_str_t * pstr)
+static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
 {
-	snd_pcm_substream_t *substream, *substream_next;
+	struct snd_pcm_substream *substream, *substream_next;
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
-	snd_pcm_oss_setup_t *setup, *setupn;
+	struct snd_pcm_oss_setup *setup, *setupn;
 #endif
 	substream = pstr->substream;
 	while (substream) {
@@ -707,7 +749,7 @@
 #endif
 }
 
-static int snd_pcm_free(snd_pcm_t *pcm)
+static int snd_pcm_free(struct snd_pcm *pcm)
 {
 	snd_assert(pcm != NULL, return -ENXIO);
 	if (pcm->private_free)
@@ -719,26 +761,26 @@
 	return 0;
 }
 
-static int snd_pcm_dev_free(snd_device_t *device)
+static int snd_pcm_dev_free(struct snd_device *device)
 {
-	snd_pcm_t *pcm = device->device_data;
+	struct snd_pcm *pcm = device->device_data;
 	return snd_pcm_free(pcm);
 }
 
 static void snd_pcm_tick_timer_func(unsigned long data)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t*) data;
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *) data;
 	snd_pcm_tick_elapsed(substream);
 }
 
-int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
-			   snd_pcm_substream_t **rsubstream)
+int snd_pcm_open_substream(struct snd_pcm *pcm, int stream,
+			   struct snd_pcm_substream **rsubstream)
 {
-	snd_pcm_str_t * pstr;
-	snd_pcm_substream_t * substream;
-	snd_pcm_runtime_t * runtime;
-	snd_ctl_file_t *kctl;
-	snd_card_t *card;
+	struct snd_pcm_str * pstr;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
+	struct snd_ctl_file *kctl;
+	struct snd_card *card;
 	struct list_head *list;
 	int prefer_subdevice = -1;
 	size_t size;
@@ -800,7 +842,7 @@
 	if (runtime == NULL)
 		return -ENOMEM;
 
-	size = PAGE_ALIGN(sizeof(snd_pcm_mmap_status_t));
+	size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status));
 	runtime->status = snd_malloc_pages(size, GFP_KERNEL);
 	if (runtime->status == NULL) {
 		kfree(runtime);
@@ -808,10 +850,11 @@
 	}
 	memset((void*)runtime->status, 0, size);
 
-	size = PAGE_ALIGN(sizeof(snd_pcm_mmap_control_t));
+	size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control));
 	runtime->control = snd_malloc_pages(size, GFP_KERNEL);
 	if (runtime->control == NULL) {
-		snd_free_pages((void*)runtime->status, PAGE_ALIGN(sizeof(snd_pcm_mmap_status_t)));
+		snd_free_pages((void*)runtime->status,
+			       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
 		kfree(runtime);
 		return -ENOMEM;
 	}
@@ -832,39 +875,39 @@
 	return 0;
 }
 
-void snd_pcm_release_substream(snd_pcm_substream_t *substream)
+void snd_pcm_release_substream(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t * runtime;
+	struct snd_pcm_runtime *runtime;
 	substream->file = NULL;
 	runtime = substream->runtime;
 	snd_assert(runtime != NULL, return);
 	if (runtime->private_free != NULL)
 		runtime->private_free(runtime);
-	snd_free_pages((void*)runtime->status, PAGE_ALIGN(sizeof(snd_pcm_mmap_status_t)));
-	snd_free_pages((void*)runtime->control, PAGE_ALIGN(sizeof(snd_pcm_mmap_control_t)));
+	snd_free_pages((void*)runtime->status,
+		       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
+	snd_free_pages((void*)runtime->control,
+		       PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
 	kfree(runtime->hw_constraints.rules);
 	kfree(runtime);
 	substream->runtime = NULL;
 	substream->pstr->substream_opened--;
 }
 
-static int snd_pcm_dev_register(snd_device_t *device)
+static int snd_pcm_dev_register(struct snd_device *device)
 {
-	int idx, cidx, err;
-	unsigned short minor;
-	snd_pcm_substream_t *substream;
+	int cidx, err;
+	struct snd_pcm_substream *substream;
 	struct list_head *list;
 	char str[16];
-	snd_pcm_t *pcm = device->device_data;
+	struct snd_pcm *pcm = device->device_data;
 
 	snd_assert(pcm != NULL && device != NULL, return -ENXIO);
 	down(&register_mutex);
-	idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
-	if (snd_pcm_devices[idx]) {
+	if (snd_pcm_search(pcm->card, pcm->device)) {
 		up(&register_mutex);
 		return -EBUSY;
 	}
-	snd_pcm_devices[idx] = pcm;
+	list_add_tail(&pcm->list, &snd_pcm_devices);
 	for (cidx = 0; cidx < 2; cidx++) {
 		int devtype = -1;
 		if (pcm->streams[cidx].substream == NULL)
@@ -872,17 +915,19 @@
 		switch (cidx) {
 		case SNDRV_PCM_STREAM_PLAYBACK:
 			sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device);
-			minor = SNDRV_MINOR_PCM_PLAYBACK + idx;
 			devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
 			break;
 		case SNDRV_PCM_STREAM_CAPTURE:
 			sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device);
-			minor = SNDRV_MINOR_PCM_CAPTURE + idx;
 			devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
 			break;
 		}
-		if ((err = snd_register_device(devtype, pcm->card, pcm->device, pcm->streams[cidx].reg, str)) < 0) {
-			snd_pcm_devices[idx] = NULL;
+		if ((err = snd_register_device(devtype, pcm->card,
+					       pcm->device,
+					       &snd_pcm_f_ops[cidx],
+					       pcm, str)) < 0)
+		{
+			list_del(&pcm->list);
 			up(&register_mutex);
 			return err;
 		}
@@ -890,48 +935,46 @@
 			snd_pcm_timer_init(substream);
 	}
 	list_for_each(list, &snd_pcm_notify_list) {
-		snd_pcm_notify_t *notify;
-		notify = list_entry(list, snd_pcm_notify_t, list);
+		struct snd_pcm_notify *notify;
+		notify = list_entry(list, struct snd_pcm_notify, list);
 		notify->n_register(pcm);
 	}
 	up(&register_mutex);
 	return 0;
 }
 
-static int snd_pcm_dev_disconnect(snd_device_t *device)
+static int snd_pcm_dev_disconnect(struct snd_device *device)
 {
-	snd_pcm_t *pcm = device->device_data;
+	struct snd_pcm *pcm = device->device_data;
 	struct list_head *list;
-	snd_pcm_substream_t *substream;
-	int idx, cidx;
+	struct snd_pcm_substream *substream;
+	int cidx;
 
 	down(&register_mutex);
-	idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
-	snd_pcm_devices[idx] = NULL;
+	list_del_init(&pcm->list);
 	for (cidx = 0; cidx < 2; cidx++)
 		for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
 			if (substream->runtime)
 				substream->runtime->status->state = SNDRV_PCM_STATE_DISCONNECTED;
 	list_for_each(list, &snd_pcm_notify_list) {
-		snd_pcm_notify_t *notify;
-		notify = list_entry(list, snd_pcm_notify_t, list);
+		struct snd_pcm_notify *notify;
+		notify = list_entry(list, struct snd_pcm_notify, list);
 		notify->n_disconnect(pcm);
 	}
 	up(&register_mutex);
 	return 0;
 }
 
-static int snd_pcm_dev_unregister(snd_device_t *device)
+static int snd_pcm_dev_unregister(struct snd_device *device)
 {
-	int idx, cidx, devtype;
-	snd_pcm_substream_t *substream;
+	int cidx, devtype;
+	struct snd_pcm_substream *substream;
 	struct list_head *list;
-	snd_pcm_t *pcm = device->device_data;
+	struct snd_pcm *pcm = device->device_data;
 
 	snd_assert(pcm != NULL, return -ENXIO);
 	down(&register_mutex);
-	idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
-	snd_pcm_devices[idx] = NULL;
+	list_del(&pcm->list);
 	for (cidx = 0; cidx < 2; cidx++) {
 		devtype = -1;
 		switch (cidx) {
@@ -947,84 +990,99 @@
 			snd_pcm_timer_done(substream);
 	}
 	list_for_each(list, &snd_pcm_notify_list) {
-		snd_pcm_notify_t *notify;
-		notify = list_entry(list, snd_pcm_notify_t, list);
+		struct snd_pcm_notify *notify;
+		notify = list_entry(list, struct snd_pcm_notify, list);
 		notify->n_unregister(pcm);
 	}
 	up(&register_mutex);
 	return snd_pcm_free(pcm);
 }
 
-int snd_pcm_notify(snd_pcm_notify_t *notify, int nfree)
+int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
 {
-	int idx;
+	struct list_head *p;
 
 	snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL);
 	down(&register_mutex);
 	if (nfree) {
 		list_del(&notify->list);
-		for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
-			if (snd_pcm_devices[idx] == NULL)
-				continue;
-			notify->n_unregister(snd_pcm_devices[idx]);
-		}
+		list_for_each(p, &snd_pcm_devices)
+			notify->n_unregister(list_entry(p,
+							struct snd_pcm, list));
 	} else {
 		list_add_tail(&notify->list, &snd_pcm_notify_list);
-		for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
-			if (snd_pcm_devices[idx] == NULL)
-				continue;
-			notify->n_register(snd_pcm_devices[idx]);
-		}
+		list_for_each(p, &snd_pcm_devices)
+			notify->n_register(list_entry(p, struct snd_pcm, list));
 	}
 	up(&register_mutex);
 	return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *  Info interface
  */
 
-static void snd_pcm_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void snd_pcm_proc_read(struct snd_info_entry *entry,
+			      struct snd_info_buffer *buffer)
 {
-	int idx;
-	snd_pcm_t *pcm;
+	struct list_head *p;
+	struct snd_pcm *pcm;
 
 	down(&register_mutex);
-	for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
-		pcm = snd_pcm_devices[idx];
-		if (pcm == NULL)
-			continue;
-		snd_iprintf(buffer, "%02i-%02i: %s : %s", idx / SNDRV_PCM_DEVICES,
-			    idx % SNDRV_PCM_DEVICES, pcm->id, pcm->name);
+	list_for_each(p, &snd_pcm_devices) {
+		pcm = list_entry(p, struct snd_pcm, list);
+		snd_iprintf(buffer, "%02i-%02i: %s : %s",
+			    pcm->card->number, pcm->device, pcm->id, pcm->name);
 		if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
-			snd_iprintf(buffer, " : playback %i", pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);
+			snd_iprintf(buffer, " : playback %i",
+				    pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);
 		if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
-			snd_iprintf(buffer, " : capture %i", pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
+			snd_iprintf(buffer, " : capture %i",
+				    pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
 		snd_iprintf(buffer, "\n");
 	}
 	up(&register_mutex);
 }
 
-/*
- *  ENTRY functions
- */
+static struct snd_info_entry *snd_pcm_proc_entry = NULL;
 
-static snd_info_entry_t *snd_pcm_proc_entry = NULL;
-
-static int __init alsa_pcm_init(void)
+static void snd_pcm_proc_init(void)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
-	snd_ctl_register_ioctl(snd_pcm_control_ioctl);
-	snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
 	if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
-		snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128, snd_pcm_proc_read);
+		snd_info_set_text_ops(entry, NULL, SNDRV_CARDS * SNDRV_PCM_DEVICES * 128,
+				      snd_pcm_proc_read);
 		if (snd_info_register(entry) < 0) {
 			snd_info_free_entry(entry);
 			entry = NULL;
 		}
 	}
 	snd_pcm_proc_entry = entry;
+}
+
+static void snd_pcm_proc_done(void)
+{
+	if (snd_pcm_proc_entry)
+		snd_info_unregister(snd_pcm_proc_entry);
+}
+
+#else /* !CONFIG_PROC_FS */
+#define snd_pcm_proc_init()
+#define snd_pcm_proc_done()
+#endif /* CONFIG_PROC_FS */
+
+
+/*
+ *  ENTRY functions
+ */
+
+static int __init alsa_pcm_init(void)
+{
+	snd_ctl_register_ioctl(snd_pcm_control_ioctl);
+	snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
+	snd_pcm_proc_init();
 	return 0;
 }
 
@@ -1032,16 +1090,12 @@
 {
 	snd_ctl_unregister_ioctl(snd_pcm_control_ioctl);
 	snd_ctl_unregister_ioctl_compat(snd_pcm_control_ioctl);
-	if (snd_pcm_proc_entry) {
-		snd_info_unregister(snd_pcm_proc_entry);
-		snd_pcm_proc_entry = NULL;
-	}
+	snd_pcm_proc_done();
 }
 
 module_init(alsa_pcm_init)
 module_exit(alsa_pcm_exit)
 
-EXPORT_SYMBOL(snd_pcm_devices);
 EXPORT_SYMBOL(snd_pcm_new);
 EXPORT_SYMBOL(snd_pcm_new_stream);
 EXPORT_SYMBOL(snd_pcm_notify);
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 4b6307d..e513303 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -22,7 +22,7 @@
 
 #include <linux/compat.h>
 
-static int snd_pcm_ioctl_delay_compat(snd_pcm_substream_t *substream,
+static int snd_pcm_ioctl_delay_compat(struct snd_pcm_substream *substream,
 				      s32 __user *src)
 {
 	snd_pcm_sframes_t delay;
@@ -39,7 +39,7 @@
 	return err;
 }
 
-static int snd_pcm_ioctl_rewind_compat(snd_pcm_substream_t *substream,
+static int snd_pcm_ioctl_rewind_compat(struct snd_pcm_substream *substream,
 				       u32 __user *src)
 {
 	snd_pcm_uframes_t frames;
@@ -56,7 +56,7 @@
 	return err < 0 ? err : 0;
 }
 
-static int snd_pcm_ioctl_forward_compat(snd_pcm_substream_t *substream,
+static int snd_pcm_ioctl_forward_compat(struct snd_pcm_substream *substream,
 				       u32 __user *src)
 {
 	snd_pcm_uframes_t frames;
@@ -73,12 +73,12 @@
 	return err < 0 ? err : 0;
 }
 
-struct sndrv_pcm_hw_params32 {
+struct snd_pcm_hw_params32 {
 	u32 flags;
-	struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */
-	struct sndrv_mask mres[5];	/* reserved masks */
-	struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
-	struct sndrv_interval ires[9];	/* reserved intervals */
+	struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */
+	struct snd_mask mres[5];	/* reserved masks */
+	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
+	struct snd_interval ires[9];	/* reserved intervals */
 	u32 rmask;
 	u32 cmask;
 	u32 info;
@@ -89,7 +89,7 @@
 	unsigned char reserved[64];
 };
 
-struct sndrv_pcm_sw_params32 {
+struct snd_pcm_sw_params32 {
 	s32 tstamp_mode;
 	u32 period_step;
 	u32 sleep_min;
@@ -104,7 +104,7 @@
 };
 
 /* recalcuate the boundary within 32bit */
-static snd_pcm_uframes_t recalculate_boundary(snd_pcm_runtime_t *runtime)
+static snd_pcm_uframes_t recalculate_boundary(struct snd_pcm_runtime *runtime)
 {
 	snd_pcm_uframes_t boundary;
 
@@ -116,10 +116,10 @@
 	return boundary;
 }
 
-static int snd_pcm_ioctl_sw_params_compat(snd_pcm_substream_t *substream,
-					  struct sndrv_pcm_sw_params32 __user *src)
+static int snd_pcm_ioctl_sw_params_compat(struct snd_pcm_substream *substream,
+					  struct snd_pcm_sw_params32 __user *src)
 {
-	snd_pcm_sw_params_t params;
+	struct snd_pcm_sw_params params;
 	snd_pcm_uframes_t boundary;
 	int err;
 
@@ -149,17 +149,17 @@
 	return err;
 }
 
-struct sndrv_pcm_channel_info32 {
+struct snd_pcm_channel_info32 {
 	u32 channel;
 	u32 offset;
 	u32 first;
 	u32 step;
 };
 
-static int snd_pcm_ioctl_channel_info_compat(snd_pcm_substream_t *substream,
-					     struct sndrv_pcm_channel_info32 __user *src)
+static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream,
+					     struct snd_pcm_channel_info32 __user *src)
 {
-	snd_pcm_channel_info_t info;
+	struct snd_pcm_channel_info info;
 	int err;
 
 	if (get_user(info.channel, &src->channel) ||
@@ -178,7 +178,7 @@
 	return err;
 }
 
-struct sndrv_pcm_status32 {
+struct snd_pcm_status32 {
 	s32 state;
 	struct compat_timespec trigger_tstamp;
 	struct compat_timespec tstamp;
@@ -193,10 +193,10 @@
 } __attribute__((packed));
 
 
-static int snd_pcm_status_user_compat(snd_pcm_substream_t *substream,
-				      struct sndrv_pcm_status32 __user *src)
+static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
+				      struct snd_pcm_status32 __user *src)
 {
-	snd_pcm_status_t status;
+	struct snd_pcm_status status;
 	int err;
 
 	err = snd_pcm_status(substream, &status);
@@ -221,12 +221,12 @@
 }
 
 /* both for HW_PARAMS and HW_REFINE */
-static int snd_pcm_ioctl_hw_params_compat(snd_pcm_substream_t *substream,
+static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
 					  int refine, 
-					  struct sndrv_pcm_hw_params32 __user *data32)
+					  struct snd_pcm_hw_params32 __user *data32)
 {
-	struct sndrv_pcm_hw_params *data;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_hw_params *data;
+	struct snd_pcm_runtime *runtime;
 	int err;
 
 	if (! (runtime = substream->runtime))
@@ -265,14 +265,14 @@
 
 /*
  */
-struct sndrv_xferi32 {
+struct snd_xferi32 {
 	s32 result;
 	u32 buf;
 	u32 frames;
 };
 
-static int snd_pcm_ioctl_xferi_compat(snd_pcm_substream_t *substream,
-				      int dir, struct sndrv_xferi32 __user *data32)
+static int snd_pcm_ioctl_xferi_compat(struct snd_pcm_substream *substream,
+				      int dir, struct snd_xferi32 __user *data32)
 {
 	compat_caddr_t buf;
 	u32 frames;
@@ -303,7 +303,7 @@
 
 
 /* snd_xfern needs remapping of bufs */
-struct sndrv_xfern32 {
+struct snd_xfern32 {
 	s32 result;
 	u32 bufs;  /* this is void **; */
 	u32 frames;
@@ -315,8 +315,8 @@
  * handler there expands again the same 128 pointers on stack, so it is better
  * to handle the function (calling pcm_readv/writev) directly in this handler.
  */
-static int snd_pcm_ioctl_xfern_compat(snd_pcm_substream_t *substream,
-				      int dir, struct sndrv_xfern32 __user *data32)
+static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
+				      int dir, struct snd_xfern32 __user *data32)
 {
 	compat_caddr_t buf;
 	compat_caddr_t __user *bufptr;
@@ -360,7 +360,7 @@
 }
 
 
-struct sndrv_pcm_mmap_status32 {
+struct snd_pcm_mmap_status32 {
 	s32 state;
 	s32 pad1;
 	u32 hw_ptr;
@@ -368,32 +368,32 @@
 	s32 suspended_state;
 } __attribute__((packed));
 
-struct sndrv_pcm_mmap_control32 {
+struct snd_pcm_mmap_control32 {
 	u32 appl_ptr;
 	u32 avail_min;
 };
 
-struct sndrv_pcm_sync_ptr32 {
+struct snd_pcm_sync_ptr32 {
 	u32 flags;
 	union {
-		struct sndrv_pcm_mmap_status32 status;
+		struct snd_pcm_mmap_status32 status;
 		unsigned char reserved[64];
 	} s;
 	union {
-		struct sndrv_pcm_mmap_control32 control;
+		struct snd_pcm_mmap_control32 control;
 		unsigned char reserved[64];
 	} c;
 } __attribute__((packed));
 
-static int snd_pcm_ioctl_sync_ptr_compat(snd_pcm_substream_t *substream,
-					 struct sndrv_pcm_sync_ptr32 __user *src)
+static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
+					 struct snd_pcm_sync_ptr32 __user *src)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	volatile struct sndrv_pcm_mmap_status *status;
-	volatile struct sndrv_pcm_mmap_control *control;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	volatile struct snd_pcm_mmap_status *status;
+	volatile struct snd_pcm_mmap_control *control;
 	u32 sflags;
-	struct sndrv_pcm_mmap_control scontrol;
-	struct sndrv_pcm_mmap_status sstatus;
+	struct snd_pcm_mmap_control scontrol;
+	struct snd_pcm_mmap_status sstatus;
 	snd_pcm_uframes_t boundary;
 	int err;
 
@@ -444,26 +444,26 @@
 /*
  */
 enum {
-	SNDRV_PCM_IOCTL_HW_REFINE32 = _IOWR('A', 0x10, struct sndrv_pcm_hw_params32),
-	SNDRV_PCM_IOCTL_HW_PARAMS32 = _IOWR('A', 0x11, struct sndrv_pcm_hw_params32),
-	SNDRV_PCM_IOCTL_SW_PARAMS32 = _IOWR('A', 0x13, struct sndrv_pcm_sw_params32),
-	SNDRV_PCM_IOCTL_STATUS32 = _IOR('A', 0x20, struct sndrv_pcm_status32),
+	SNDRV_PCM_IOCTL_HW_REFINE32 = _IOWR('A', 0x10, struct snd_pcm_hw_params32),
+	SNDRV_PCM_IOCTL_HW_PARAMS32 = _IOWR('A', 0x11, struct snd_pcm_hw_params32),
+	SNDRV_PCM_IOCTL_SW_PARAMS32 = _IOWR('A', 0x13, struct snd_pcm_sw_params32),
+	SNDRV_PCM_IOCTL_STATUS32 = _IOR('A', 0x20, struct snd_pcm_status32),
 	SNDRV_PCM_IOCTL_DELAY32 = _IOR('A', 0x21, s32),
-	SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct sndrv_pcm_channel_info32),
+	SNDRV_PCM_IOCTL_CHANNEL_INFO32 = _IOR('A', 0x32, struct snd_pcm_channel_info32),
 	SNDRV_PCM_IOCTL_REWIND32 = _IOW('A', 0x46, u32),
 	SNDRV_PCM_IOCTL_FORWARD32 = _IOW('A', 0x49, u32),
-	SNDRV_PCM_IOCTL_WRITEI_FRAMES32 = _IOW('A', 0x50, struct sndrv_xferi32),
-	SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct sndrv_xferi32),
-	SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct sndrv_xfern32),
-	SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct sndrv_xfern32),
-	SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr32),
+	SNDRV_PCM_IOCTL_WRITEI_FRAMES32 = _IOW('A', 0x50, struct snd_xferi32),
+	SNDRV_PCM_IOCTL_READI_FRAMES32 = _IOR('A', 0x51, struct snd_xferi32),
+	SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32),
+	SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
+	SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32),
 
 };
 
 static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_file *pcm_file;
+	struct snd_pcm_substream *substream;
 	void __user *argp = compat_ptr(arg);
 
 	pcm_file = file->private_data;
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 3dbf9bf..eeba2f0 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -39,9 +39,9 @@
  *
  * when runtime->silence_size >= runtime->boundary - fill processed area with silence immediately
  */
-void snd_pcm_playback_silence(snd_pcm_substream_t *substream, snd_pcm_uframes_t new_hw_ptr)
+void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_uframes_t new_hw_ptr)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t frames, ofs, transfer;
 
 	if (runtime->silence_size < runtime->boundary) {
@@ -56,9 +56,8 @@
 				runtime->silence_filled = 0;
 			runtime->silence_start = runtime->control->appl_ptr;
 		}
-		if (runtime->silence_filled == runtime->buffer_size)
+		if (runtime->silence_filled >= runtime->buffer_size)
 			return;
-		snd_assert(runtime->silence_filled <= runtime->buffer_size, return);
 		noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;
 		if (noise_dist >= (snd_pcm_sframes_t) runtime->silence_threshold)
 			return;
@@ -128,7 +127,7 @@
 	}
 }
 
-static void xrun(snd_pcm_substream_t *substream)
+static void xrun(struct snd_pcm_substream *substream)
 {
 	snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
 #ifdef CONFIG_SND_DEBUG
@@ -143,8 +142,8 @@
 #endif
 }
 
-static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(snd_pcm_substream_t *substream,
-							  snd_pcm_runtime_t *runtime)
+static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(struct snd_pcm_substream *substream,
+							  struct snd_pcm_runtime *runtime)
 {
 	snd_pcm_uframes_t pos;
 
@@ -162,8 +161,8 @@
 	return pos;
 }
 
-static inline int snd_pcm_update_hw_ptr_post(snd_pcm_substream_t *substream,
-					     snd_pcm_runtime_t *runtime)
+static inline int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
+					     struct snd_pcm_runtime *runtime)
 {
 	snd_pcm_uframes_t avail;
 
@@ -185,9 +184,9 @@
 	return 0;
 }
 
-static inline int snd_pcm_update_hw_ptr_interrupt(snd_pcm_substream_t *substream)
+static inline int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t pos;
 	snd_pcm_uframes_t new_hw_ptr, hw_ptr_interrupt;
 	snd_pcm_sframes_t delta;
@@ -232,9 +231,9 @@
 }
 
 /* CAUTION: call it with irq disabled */
-int snd_pcm_update_hw_ptr(snd_pcm_substream_t *substream)
+int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t pos;
 	snd_pcm_uframes_t old_hw_ptr, new_hw_ptr;
 	snd_pcm_sframes_t delta;
@@ -281,10 +280,10 @@
  *
  * Sets the given PCM operators to the pcm instance.
  */
-void snd_pcm_set_ops(snd_pcm_t *pcm, int direction, snd_pcm_ops_t *ops)
+void snd_pcm_set_ops(struct snd_pcm *pcm, int direction, struct snd_pcm_ops *ops)
 {
-	snd_pcm_str_t *stream = &pcm->streams[direction];
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_str *stream = &pcm->streams[direction];
+	struct snd_pcm_substream *substream;
 	
 	for (substream = stream->substream; substream != NULL; substream = substream->next)
 		substream->ops = ops;
@@ -297,9 +296,9 @@
  *
  * Sets the PCM sync identifier for the card.
  */
-void snd_pcm_set_sync(snd_pcm_substream_t * substream)
+void snd_pcm_set_sync(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	
 	runtime->sync.id32[0] = substream->pcm->card->number;
 	runtime->sync.id32[1] = -1;
@@ -370,7 +369,7 @@
 	return n;
 }
 
-static int snd_interval_refine_min(snd_interval_t *i, unsigned int min, int openmin)
+static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
 {
 	int changed = 0;
 	assert(!snd_interval_empty(i));
@@ -395,7 +394,7 @@
 	return changed;
 }
 
-static int snd_interval_refine_max(snd_interval_t *i, unsigned int max, int openmax)
+static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
 {
 	int changed = 0;
 	assert(!snd_interval_empty(i));
@@ -431,7 +430,7 @@
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
-int snd_interval_refine(snd_interval_t *i, const snd_interval_t *v)
+int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v)
 {
 	int changed = 0;
 	assert(!snd_interval_empty(i));
@@ -473,7 +472,7 @@
 	return changed;
 }
 
-static int snd_interval_refine_first(snd_interval_t *i)
+static int snd_interval_refine_first(struct snd_interval *i)
 {
 	assert(!snd_interval_empty(i));
 	if (snd_interval_single(i))
@@ -485,7 +484,7 @@
 	return 1;
 }
 
-static int snd_interval_refine_last(snd_interval_t *i)
+static int snd_interval_refine_last(struct snd_interval *i)
 {
 	assert(!snd_interval_empty(i));
 	if (snd_interval_single(i))
@@ -497,9 +496,9 @@
 	return 1;
 }
 
-static int snd_interval_refine_set(snd_interval_t *i, unsigned int val)
+static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
 {
-	snd_interval_t t;
+	struct snd_interval t;
 	t.empty = 0;
 	t.min = t.max = val;
 	t.openmin = t.openmax = 0;
@@ -507,7 +506,7 @@
 	return snd_interval_refine(i, &t);
 }
 
-void snd_interval_mul(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c)
+void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
 {
 	if (a->empty || b->empty) {
 		snd_interval_none(c);
@@ -531,7 +530,7 @@
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
-void snd_interval_div(const snd_interval_t *a, const snd_interval_t *b, snd_interval_t *c)
+void snd_interval_div(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c)
 {
 	unsigned int r;
 	if (a->empty || b->empty) {
@@ -566,8 +565,8 @@
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
-void snd_interval_muldivk(const snd_interval_t *a, const snd_interval_t *b,
-		      unsigned int k, snd_interval_t *c)
+void snd_interval_muldivk(const struct snd_interval *a, const struct snd_interval *b,
+		      unsigned int k, struct snd_interval *c)
 {
 	unsigned int r;
 	if (a->empty || b->empty) {
@@ -597,8 +596,8 @@
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
-void snd_interval_mulkdiv(const snd_interval_t *a, unsigned int k,
-		      const snd_interval_t *b, snd_interval_t *c)
+void snd_interval_mulkdiv(const struct snd_interval *a, unsigned int k,
+		      const struct snd_interval *b, struct snd_interval *c)
 {
 	unsigned int r;
 	if (a->empty || b->empty) {
@@ -636,13 +635,13 @@
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
-int snd_interval_ratnum(snd_interval_t *i,
-		    unsigned int rats_count, ratnum_t *rats,
-		    unsigned int *nump, unsigned int *denp)
+int snd_interval_ratnum(struct snd_interval *i,
+			unsigned int rats_count, struct snd_ratnum *rats,
+			unsigned int *nump, unsigned int *denp)
 {
 	unsigned int best_num, best_diff, best_den;
 	unsigned int k;
-	snd_interval_t t;
+	struct snd_interval t;
 	int err;
 
 	best_num = best_den = best_diff = 0;
@@ -731,20 +730,20 @@
 /**
  * snd_interval_ratden - refine the interval value
  * @i: interval to refine
- * @rats_count: number of ratden_t
- * @rats: ratden_t array
+ * @rats_count: number of struct ratden
+ * @rats: struct ratden array
  * @nump: pointer to store the resultant numerator
  * @denp: pointer to store the resultant denominator
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
-static int snd_interval_ratden(snd_interval_t *i,
-			       unsigned int rats_count, ratden_t *rats,
+static int snd_interval_ratden(struct snd_interval *i,
+			       unsigned int rats_count, struct snd_ratden *rats,
 			       unsigned int *nump, unsigned int *denp)
 {
 	unsigned int best_num, best_diff, best_den;
 	unsigned int k;
-	snd_interval_t t;
+	struct snd_interval t;
 	int err;
 
 	best_num = best_den = best_diff = 0;
@@ -837,7 +836,7 @@
  *
  * Returns non-zero if the value is changed, zero if not changed.
  */
-int snd_interval_list(snd_interval_t *i, unsigned int count, unsigned int *list, unsigned int mask)
+int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask)
 {
         unsigned int k;
 	int changed = 0;
@@ -878,7 +877,7 @@
         return changed;
 }
 
-static int snd_interval_step(snd_interval_t *i, unsigned int min, unsigned int step)
+static int snd_interval_step(struct snd_interval *i, unsigned int min, unsigned int step)
 {
 	unsigned int n;
 	int changed = 0;
@@ -912,18 +911,18 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_hw_rule_add(snd_pcm_runtime_t *runtime, unsigned int cond,
+int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
 			int var,
 			snd_pcm_hw_rule_func_t func, void *private,
 			int dep, ...)
 {
-	snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints;
-	snd_pcm_hw_rule_t *c;
+	struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
+	struct snd_pcm_hw_rule *c;
 	unsigned int k;
 	va_list args;
 	va_start(args, dep);
 	if (constrs->rules_num >= constrs->rules_all) {
-		snd_pcm_hw_rule_t *new;
+		struct snd_pcm_hw_rule *new;
 		unsigned int new_rules = constrs->rules_all + 16;
 		new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
 		if (!new)
@@ -962,11 +961,11 @@
  *
  * Apply the constraint of the given bitmap mask to a mask parameter.
  */
-int snd_pcm_hw_constraint_mask(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
 			       u_int32_t mask)
 {
-	snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints;
-	snd_mask_t *maskp = constrs_mask(constrs, var);
+	struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
+	struct snd_mask *maskp = constrs_mask(constrs, var);
 	*maskp->bits &= mask;
 	memset(maskp->bits + 1, 0, (SNDRV_MASK_MAX-32) / 8); /* clear rest */
 	if (*maskp->bits == 0)
@@ -982,11 +981,11 @@
  *
  * Apply the constraint of the given bitmap mask to a mask parameter.
  */
-int snd_pcm_hw_constraint_mask64(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
 				 u_int64_t mask)
 {
-	snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints;
-	snd_mask_t *maskp = constrs_mask(constrs, var);
+	struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
+	struct snd_mask *maskp = constrs_mask(constrs, var);
 	maskp->bits[0] &= (u_int32_t)mask;
 	maskp->bits[1] &= (u_int32_t)(mask >> 32);
 	memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
@@ -1002,9 +1001,9 @@
  *
  * Apply the constraint of integer to an interval parameter.
  */
-int snd_pcm_hw_constraint_integer(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var)
+int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var)
 {
-	snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints;
+	struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
 	return snd_interval_setinteger(constrs_interval(constrs, var));
 }
 
@@ -1017,11 +1016,11 @@
  * 
  * Apply the min/max range constraint to an interval parameter.
  */
-int snd_pcm_hw_constraint_minmax(snd_pcm_runtime_t *runtime, snd_pcm_hw_param_t var,
+int snd_pcm_hw_constraint_minmax(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
 				 unsigned int min, unsigned int max)
 {
-	snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints;
-	snd_interval_t t;
+	struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
+	struct snd_interval t;
 	t.min = min;
 	t.max = max;
 	t.openmin = t.openmax = 0;
@@ -1029,10 +1028,10 @@
 	return snd_interval_refine(constrs_interval(constrs, var), &t);
 }
 
-static int snd_pcm_hw_rule_list(snd_pcm_hw_params_t *params,
-				snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
+				struct snd_pcm_hw_rule *rule)
 {
-	snd_pcm_hw_constraint_list_t *list = rule->private;
+	struct snd_pcm_hw_constraint_list *list = rule->private;
 	return snd_interval_list(hw_param_interval(params, rule->var), list->count, list->list, list->mask);
 }		
 
@@ -1046,20 +1045,20 @@
  * 
  * Apply the list of constraints to an interval parameter.
  */
-int snd_pcm_hw_constraint_list(snd_pcm_runtime_t *runtime,
+int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
 			       unsigned int cond,
 			       snd_pcm_hw_param_t var,
-			       snd_pcm_hw_constraint_list_t *l)
+			       struct snd_pcm_hw_constraint_list *l)
 {
 	return snd_pcm_hw_rule_add(runtime, cond, var,
 				   snd_pcm_hw_rule_list, l,
 				   var, -1);
 }
 
-static int snd_pcm_hw_rule_ratnums(snd_pcm_hw_params_t *params,
-				   snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
+				   struct snd_pcm_hw_rule *rule)
 {
-	snd_pcm_hw_constraint_ratnums_t *r = rule->private;
+	struct snd_pcm_hw_constraint_ratnums *r = rule->private;
 	unsigned int num = 0, den = 0;
 	int err;
 	err = snd_interval_ratnum(hw_param_interval(params, rule->var),
@@ -1076,22 +1075,22 @@
  * @runtime: PCM runtime instance
  * @cond: condition bits
  * @var: hw_params variable to apply the ratnums constraint
- * @r: ratnums_t constriants
+ * @r: struct snd_ratnums constriants
  */
-int snd_pcm_hw_constraint_ratnums(snd_pcm_runtime_t *runtime, 
+int snd_pcm_hw_constraint_ratnums(struct snd_pcm_runtime *runtime, 
 				  unsigned int cond,
 				  snd_pcm_hw_param_t var,
-				  snd_pcm_hw_constraint_ratnums_t *r)
+				  struct snd_pcm_hw_constraint_ratnums *r)
 {
 	return snd_pcm_hw_rule_add(runtime, cond, var,
 				   snd_pcm_hw_rule_ratnums, r,
 				   var, -1);
 }
 
-static int snd_pcm_hw_rule_ratdens(snd_pcm_hw_params_t *params,
-				   snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
+				   struct snd_pcm_hw_rule *rule)
 {
-	snd_pcm_hw_constraint_ratdens_t *r = rule->private;
+	struct snd_pcm_hw_constraint_ratdens *r = rule->private;
 	unsigned int num = 0, den = 0;
 	int err = snd_interval_ratden(hw_param_interval(params, rule->var),
 				  r->nrats, r->rats, &num, &den);
@@ -1107,25 +1106,25 @@
  * @runtime: PCM runtime instance
  * @cond: condition bits
  * @var: hw_params variable to apply the ratdens constraint
- * @r: ratdens_t constriants
+ * @r: struct snd_ratdens constriants
  */
-int snd_pcm_hw_constraint_ratdens(snd_pcm_runtime_t *runtime, 
+int snd_pcm_hw_constraint_ratdens(struct snd_pcm_runtime *runtime, 
 				  unsigned int cond,
 				  snd_pcm_hw_param_t var,
-				  snd_pcm_hw_constraint_ratdens_t *r)
+				  struct snd_pcm_hw_constraint_ratdens *r)
 {
 	return snd_pcm_hw_rule_add(runtime, cond, var,
 				   snd_pcm_hw_rule_ratdens, r,
 				   var, -1);
 }
 
-static int snd_pcm_hw_rule_msbits(snd_pcm_hw_params_t *params,
-				  snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
+				  struct snd_pcm_hw_rule *rule)
 {
 	unsigned int l = (unsigned long) rule->private;
 	int width = l & 0xffff;
 	unsigned int msbits = l >> 16;
-	snd_interval_t *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
+	struct snd_interval *i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
 	if (snd_interval_single(i) && snd_interval_value(i) == width)
 		params->msbits = msbits;
 	return 0;
@@ -1138,7 +1137,7 @@
  * @width: sample bits width
  * @msbits: msbits width
  */
-int snd_pcm_hw_constraint_msbits(snd_pcm_runtime_t *runtime, 
+int snd_pcm_hw_constraint_msbits(struct snd_pcm_runtime *runtime, 
 				 unsigned int cond,
 				 unsigned int width,
 				 unsigned int msbits)
@@ -1150,8 +1149,8 @@
 				    SNDRV_PCM_HW_PARAM_SAMPLE_BITS, -1);
 }
 
-static int snd_pcm_hw_rule_step(snd_pcm_hw_params_t *params,
-				snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params,
+				struct snd_pcm_hw_rule *rule)
 {
 	unsigned long step = (unsigned long) rule->private;
 	return snd_interval_step(hw_param_interval(params, rule->var), 0, step);
@@ -1164,7 +1163,7 @@
  * @var: hw_params variable to apply the step constraint
  * @step: step size
  */
-int snd_pcm_hw_constraint_step(snd_pcm_runtime_t *runtime,
+int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime,
 			       unsigned int cond,
 			       snd_pcm_hw_param_t var,
 			       unsigned long step)
@@ -1174,7 +1173,7 @@
 				   var, -1);
 }
 
-static int snd_pcm_hw_rule_pow2(snd_pcm_hw_params_t *params, snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
 {
 	static int pow2_sizes[] = {
 		1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7,
@@ -1192,7 +1191,7 @@
  * @cond: condition bits
  * @var: hw_params variable to apply the power-of-2 constraint
  */
-int snd_pcm_hw_constraint_pow2(snd_pcm_runtime_t *runtime,
+int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime,
 			       unsigned int cond,
 			       snd_pcm_hw_param_t var)
 {
@@ -1202,13 +1201,12 @@
 }
 
 /* To use the same code we have in alsa-lib */
-#define snd_pcm_t snd_pcm_substream_t
 #define assert(i) snd_assert((i), return -EINVAL)
 #ifndef INT_MIN
 #define INT_MIN ((int)((unsigned int)INT_MAX+1))
 #endif
 
-static void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params,
+static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params,
 				  snd_pcm_hw_param_t var)
 {
 	if (hw_is_mask(var)) {
@@ -1230,7 +1228,7 @@
 /*
  * snd_pcm_hw_param_any
  */
-int snd_pcm_hw_param_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
 			 snd_pcm_hw_param_t var)
 {
 	_snd_pcm_hw_param_any(params, var);
@@ -1238,7 +1236,7 @@
 }
 #endif  /*  0  */
 
-void _snd_pcm_hw_params_any(snd_pcm_hw_params_t *params)
+void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
 {
 	unsigned int k;
 	memset(params, 0, sizeof(*params));
@@ -1255,7 +1253,7 @@
  *
  * Fill PARAMS with full configuration space boundaries
  */
-int snd_pcm_hw_params_any(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+int snd_pcm_hw_params_any(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params)
 {
 	_snd_pcm_hw_params_any(params);
 	return snd_pcm_hw_refine(pcm, params);
@@ -1271,11 +1269,11 @@
  * Return the value for field PAR if it's fixed in configuration space 
  *  defined by PARAMS. Return -EINVAL otherwise
  */
-static int snd_pcm_hw_param_value(const snd_pcm_hw_params_t *params,
+static int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
 				  snd_pcm_hw_param_t var, int *dir)
 {
 	if (hw_is_mask(var)) {
-		const snd_mask_t *mask = hw_param_mask_c(params, var);
+		const struct snd_mask *mask = hw_param_mask_c(params, var);
 		if (!snd_mask_single(mask))
 			return -EINVAL;
 		if (dir)
@@ -1283,7 +1281,7 @@
 		return snd_mask_value(mask);
 	}
 	if (hw_is_interval(var)) {
-		const snd_interval_t *i = hw_param_interval_c(params, var);
+		const struct snd_interval *i = hw_param_interval_c(params, var);
 		if (!snd_interval_single(i))
 			return -EINVAL;
 		if (dir)
@@ -1302,7 +1300,7 @@
  *
  * Return the minimum value for field PAR.
  */
-unsigned int snd_pcm_hw_param_value_min(const snd_pcm_hw_params_t *params,
+unsigned int snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
 					snd_pcm_hw_param_t var, int *dir)
 {
 	if (hw_is_mask(var)) {
@@ -1311,7 +1309,7 @@
 		return snd_mask_min(hw_param_mask_c(params, var));
 	}
 	if (hw_is_interval(var)) {
-		const snd_interval_t *i = hw_param_interval_c(params, var);
+		const struct snd_interval *i = hw_param_interval_c(params, var);
 		if (dir)
 			*dir = i->openmin;
 		return snd_interval_min(i);
@@ -1328,7 +1326,7 @@
  *
  * Return the maximum value for field PAR.
  */
-unsigned int snd_pcm_hw_param_value_max(const snd_pcm_hw_params_t *params,
+unsigned int snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
 					snd_pcm_hw_param_t var, int *dir)
 {
 	if (hw_is_mask(var)) {
@@ -1337,7 +1335,7 @@
 		return snd_mask_max(hw_param_mask_c(params, var));
 	}
 	if (hw_is_interval(var)) {
-		const snd_interval_t *i = hw_param_interval_c(params, var);
+		const struct snd_interval *i = hw_param_interval_c(params, var);
 		if (dir)
 			*dir = - (int) i->openmax;
 		return snd_interval_max(i);
@@ -1346,7 +1344,7 @@
 	return -EINVAL;
 }
 
-void _snd_pcm_hw_param_setempty(snd_pcm_hw_params_t *params,
+void _snd_pcm_hw_param_setempty(struct snd_pcm_hw_params *params,
 				snd_pcm_hw_param_t var)
 {
 	if (hw_is_mask(var)) {
@@ -1362,7 +1360,7 @@
 	}
 }
 
-int _snd_pcm_hw_param_setinteger(snd_pcm_hw_params_t *params,
+int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
 				 snd_pcm_hw_param_t var)
 {
 	int changed;
@@ -1383,8 +1381,8 @@
  * non integer values. Reduce configuration space accordingly.
  * Return -EINVAL if the configuration space is empty
  */
-int snd_pcm_hw_param_setinteger(snd_pcm_t *pcm, 
-				snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_setinteger(struct snd_pcm_substream *pcm, 
+				struct snd_pcm_hw_params *params,
 				snd_pcm_hw_param_t var)
 {
 	int changed = _snd_pcm_hw_param_setinteger(params, var);
@@ -1399,7 +1397,7 @@
 }
 #endif  /*  0  */
 
-static int _snd_pcm_hw_param_first(snd_pcm_hw_params_t *params,
+static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
 				   snd_pcm_hw_param_t var)
 {
 	int changed;
@@ -1430,8 +1428,8 @@
  * values > minimum. Reduce configuration space accordingly.
  * Return the minimum.
  */
-static int snd_pcm_hw_param_first(snd_pcm_t *pcm, 
-				  snd_pcm_hw_params_t *params, 
+static int snd_pcm_hw_param_first(struct snd_pcm_substream *pcm, 
+				  struct snd_pcm_hw_params *params, 
 				  snd_pcm_hw_param_t var, int *dir)
 {
 	int changed = _snd_pcm_hw_param_first(params, var);
@@ -1444,7 +1442,7 @@
 	return snd_pcm_hw_param_value(params, var, dir);
 }
 
-static int _snd_pcm_hw_param_last(snd_pcm_hw_params_t *params,
+static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
 				  snd_pcm_hw_param_t var)
 {
 	int changed;
@@ -1475,8 +1473,8 @@
  * values < maximum. Reduce configuration space accordingly.
  * Return the maximum.
  */
-static int snd_pcm_hw_param_last(snd_pcm_t *pcm, 
-				 snd_pcm_hw_params_t *params,
+static int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm, 
+				 struct snd_pcm_hw_params *params,
 				 snd_pcm_hw_param_t var, int *dir)
 {
 	int changed = _snd_pcm_hw_param_last(params, var);
@@ -1489,7 +1487,7 @@
 	return snd_pcm_hw_param_value(params, var, dir);
 }
 
-int _snd_pcm_hw_param_min(snd_pcm_hw_params_t *params,
+int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params,
 			  snd_pcm_hw_param_t var, unsigned int val, int dir)
 {
 	int changed;
@@ -1531,7 +1529,7 @@
  * values < VAL. Reduce configuration space accordingly.
  * Return new minimum or -EINVAL if the configuration space is empty
  */
-static int snd_pcm_hw_param_min(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
 				snd_pcm_hw_param_t var, unsigned int val,
 				int *dir)
 {
@@ -1546,7 +1544,7 @@
 	return snd_pcm_hw_param_value_min(params, var, dir);
 }
 
-static int _snd_pcm_hw_param_max(snd_pcm_hw_params_t *params,
+static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
 				 snd_pcm_hw_param_t var, unsigned int val,
 				 int dir)
 {
@@ -1591,7 +1589,7 @@
  *  values >= VAL + 1. Reduce configuration space accordingly.
  *  Return new maximum or -EINVAL if the configuration space is empty
  */
-static int snd_pcm_hw_param_max(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
 				snd_pcm_hw_param_t var, unsigned int val,
 				int *dir)
 {
@@ -1606,12 +1604,12 @@
 	return snd_pcm_hw_param_value_max(params, var, dir);
 }
 
-int _snd_pcm_hw_param_set(snd_pcm_hw_params_t *params,
+int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
 			  snd_pcm_hw_param_t var, unsigned int val, int dir)
 {
 	int changed;
 	if (hw_is_mask(var)) {
-		snd_mask_t *m = hw_param_mask(params, var);
+		struct snd_mask *m = hw_param_mask(params, var);
 		if (val == 0 && dir < 0) {
 			changed = -EINVAL;
 			snd_mask_none(m);
@@ -1623,14 +1621,14 @@
 			changed = snd_mask_refine_set(hw_param_mask(params, var), val);
 		}
 	} else if (hw_is_interval(var)) {
-		snd_interval_t *i = hw_param_interval(params, var);
+		struct snd_interval *i = hw_param_interval(params, var);
 		if (val == 0 && dir < 0) {
 			changed = -EINVAL;
 			snd_interval_none(i);
 		} else if (dir == 0)
 			changed = snd_interval_refine_set(i, val);
 		else {
-			snd_interval_t t;
+			struct snd_interval t;
 			t.openmin = 1;
 			t.openmax = 1;
 			t.empty = 0;
@@ -1667,7 +1665,7 @@
  * values != VAL. Reduce configuration space accordingly.
  *  Return VAL or -EINVAL if the configuration space is empty
  */
-int snd_pcm_hw_param_set(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
 			 snd_pcm_hw_param_t var, unsigned int val, int dir)
 {
 	int changed = _snd_pcm_hw_param_set(params, var, val, dir);
@@ -1681,8 +1679,8 @@
 	return snd_pcm_hw_param_value(params, var, NULL);
 }
 
-static int _snd_pcm_hw_param_mask(snd_pcm_hw_params_t *params,
-				  snd_pcm_hw_param_t var, const snd_mask_t *val)
+static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
+				  snd_pcm_hw_param_t var, const struct snd_mask *val)
 {
 	int changed;
 	assert(hw_is_mask(var));
@@ -1708,8 +1706,8 @@
  * Return 0 on success or -EINVAL
  * if the configuration space is empty
  */
-int snd_pcm_hw_param_mask(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
-			  snd_pcm_hw_param_t var, const snd_mask_t *val)
+int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
+			  snd_pcm_hw_param_t var, const struct snd_mask *val)
 {
 	int changed = _snd_pcm_hw_param_mask(params, var, val);
 	if (changed < 0)
@@ -1784,10 +1782,10 @@
  * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
  * Return the value found.
   */
-int snd_pcm_hw_param_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
+int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params,
 			  snd_pcm_hw_param_t var, unsigned int best, int *dir)
 {
-	snd_pcm_hw_params_t *save = NULL;
+	struct snd_pcm_hw_params *save = NULL;
 	int v;
 	unsigned int saved_min;
 	int last = 0;
@@ -1814,7 +1812,7 @@
 	saved_min = min;
 	min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
 	if (min >= 0) {
-		snd_pcm_hw_params_t *params1;
+		struct snd_pcm_hw_params *params1;
 		if (max < 0)
 			goto _end;
 		if ((unsigned int)min == saved_min && mindir == valdir)
@@ -1861,7 +1859,7 @@
  * first access, first format, first subformat, min channels,
  * min rate, min period time, max buffer size, min tick time
  */
-int snd_pcm_hw_params_choose(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
+int snd_pcm_hw_params_choose(struct snd_pcm_substream *pcm, struct snd_pcm_hw_params *params)
 {
 	int err;
 
@@ -1892,13 +1890,12 @@
 	return 0;
 }
 
-#undef snd_pcm_t
 #undef assert
 
-static int snd_pcm_lib_ioctl_reset(snd_pcm_substream_t *substream,
+static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
 				   void *arg)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 	snd_pcm_stream_lock_irqsave(substream, flags);
 	if (snd_pcm_running(substream) &&
@@ -1910,11 +1907,11 @@
 	return 0;
 }
 
-static int snd_pcm_lib_ioctl_channel_info(snd_pcm_substream_t *substream,
+static int snd_pcm_lib_ioctl_channel_info(struct snd_pcm_substream *substream,
 					  void *arg)
 {
-	snd_pcm_channel_info_t *info = arg;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_channel_info *info = arg;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int width;
 	if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) {
 		info->offset = -1;
@@ -1956,7 +1953,7 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_lib_ioctl(snd_pcm_substream_t *substream,
+int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
 		      unsigned int cmd, void *arg)
 {
 	switch (cmd) {
@@ -1974,10 +1971,10 @@
  *  Conditions
  */
 
-static void snd_pcm_system_tick_set(snd_pcm_substream_t *substream, 
+static void snd_pcm_system_tick_set(struct snd_pcm_substream *substream, 
 				    unsigned long ticks)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (ticks == 0)
 		del_timer(&runtime->tick_timer);
 	else {
@@ -1988,14 +1985,14 @@
 }
 
 /* Temporary alias */
-void snd_pcm_tick_set(snd_pcm_substream_t *substream, unsigned long ticks)
+void snd_pcm_tick_set(struct snd_pcm_substream *substream, unsigned long ticks)
 {
 	snd_pcm_system_tick_set(substream, ticks);
 }
 
-void snd_pcm_tick_prepare(snd_pcm_substream_t *substream)
+void snd_pcm_tick_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t frames = ULONG_MAX;
 	snd_pcm_uframes_t avail, dist;
 	unsigned int ticks;
@@ -2008,8 +2005,8 @@
 			   runtime->silence_filled < runtime->buffer_size) {
 			snd_pcm_sframes_t noise_dist;
 			noise_dist = snd_pcm_playback_hw_avail(runtime) + runtime->silence_filled;
-			snd_assert(noise_dist <= (snd_pcm_sframes_t)runtime->silence_threshold, );
-			frames = noise_dist - runtime->silence_threshold;
+			if (noise_dist > (snd_pcm_sframes_t)runtime->silence_threshold)
+				frames = noise_dist - runtime->silence_threshold;
 		}
 		avail = snd_pcm_playback_avail(runtime);
 	} else {
@@ -2046,9 +2043,9 @@
 	snd_pcm_tick_set(substream, (unsigned long) ticks);
 }
 
-void snd_pcm_tick_elapsed(snd_pcm_substream_t *substream)
+void snd_pcm_tick_elapsed(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	unsigned long flags;
 	
 	snd_assert(substream != NULL, return);
@@ -2076,9 +2073,9 @@
  * Even if more than one periods have elapsed since the last call, you
  * have to call this only once.
  */
-void snd_pcm_period_elapsed(snd_pcm_substream_t *substream)
+void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	unsigned long flags;
 
 	snd_assert(substream != NULL, return);
@@ -2104,12 +2101,12 @@
 	kill_fasync(&runtime->fasync, SIGIO, POLL_IN);
 }
 
-static int snd_pcm_lib_write_transfer(snd_pcm_substream_t *substream,
+static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream,
 				      unsigned int hwoff,
 				      unsigned long data, unsigned int off,
 				      snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
 	if (substream->ops->copy) {
@@ -2124,17 +2121,17 @@
 	return 0;
 }
  
-typedef int (*transfer_f)(snd_pcm_substream_t *substream, unsigned int hwoff,
+typedef int (*transfer_f)(struct snd_pcm_substream *substream, unsigned int hwoff,
 			  unsigned long data, unsigned int off,
 			  snd_pcm_uframes_t size);
 
-static snd_pcm_sframes_t snd_pcm_lib_write1(snd_pcm_substream_t *substream, 
+static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, 
 					    unsigned long data,
 					    snd_pcm_uframes_t size,
 					    int nonblock,
 					    transfer_f transfer)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t xfer = 0;
 	snd_pcm_uframes_t offset = 0;
 	int err = 0;
@@ -2290,9 +2287,9 @@
 	return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
 }
 
-snd_pcm_sframes_t snd_pcm_lib_write(snd_pcm_substream_t *substream, const void __user *buf, snd_pcm_uframes_t size)
+snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	int nonblock;
 
 	snd_assert(substream != NULL, return -ENXIO);
@@ -2306,7 +2303,7 @@
 	nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	if (substream->oss.oss) {
-		snd_pcm_oss_setup_t *setup = substream->oss.setup;
+		struct snd_pcm_oss_setup *setup = substream->oss.setup;
 		if (setup != NULL) {
 			if (setup->nonblock)
 				nonblock = 1;
@@ -2323,12 +2320,12 @@
 				  snd_pcm_lib_write_transfer);
 }
 
-static int snd_pcm_lib_writev_transfer(snd_pcm_substream_t *substream,
+static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream,
 				       unsigned int hwoff,
 				       unsigned long data, unsigned int off,
 				       snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	void __user **bufs = (void __user **)data;
 	int channels = runtime->channels;
@@ -2363,11 +2360,11 @@
 	return 0;
 }
  
-snd_pcm_sframes_t snd_pcm_lib_writev(snd_pcm_substream_t *substream,
+snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream,
 				     void __user **bufs,
 				     snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	int nonblock;
 
 	snd_assert(substream != NULL, return -ENXIO);
@@ -2381,7 +2378,7 @@
 	nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	if (substream->oss.oss) {
-		snd_pcm_oss_setup_t *setup = substream->oss.setup;
+		struct snd_pcm_oss_setup *setup = substream->oss.setup;
 		if (setup != NULL) {
 			if (setup->nonblock)
 				nonblock = 1;
@@ -2397,12 +2394,12 @@
 				  nonblock, snd_pcm_lib_writev_transfer);
 }
 
-static int snd_pcm_lib_read_transfer(snd_pcm_substream_t *substream, 
+static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, 
 				     unsigned int hwoff,
 				     unsigned long data, unsigned int off,
 				     snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	char __user *buf = (char __user *) data + frames_to_bytes(runtime, off);
 	if (substream->ops->copy) {
@@ -2417,13 +2414,13 @@
 	return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_lib_read1(snd_pcm_substream_t *substream,
+static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
 					   unsigned long data,
 					   snd_pcm_uframes_t size,
 					   int nonblock,
 					   transfer_f transfer)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_uframes_t xfer = 0;
 	snd_pcm_uframes_t offset = 0;
 	int err = 0;
@@ -2587,9 +2584,9 @@
 	return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
 }
 
-snd_pcm_sframes_t snd_pcm_lib_read(snd_pcm_substream_t *substream, void __user *buf, snd_pcm_uframes_t size)
+snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __user *buf, snd_pcm_uframes_t size)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	int nonblock;
 	
 	snd_assert(substream != NULL, return -ENXIO);
@@ -2603,7 +2600,7 @@
 	nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	if (substream->oss.oss) {
-		snd_pcm_oss_setup_t *setup = substream->oss.setup;
+		struct snd_pcm_oss_setup *setup = substream->oss.setup;
 		if (setup != NULL) {
 			if (setup->nonblock)
 				nonblock = 1;
@@ -2617,12 +2614,12 @@
 	return snd_pcm_lib_read1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_read_transfer);
 }
 
-static int snd_pcm_lib_readv_transfer(snd_pcm_substream_t *substream,
+static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream,
 				      unsigned int hwoff,
 				      unsigned long data, unsigned int off,
 				      snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	void __user **bufs = (void __user **)data;
 	int channels = runtime->channels;
@@ -2654,11 +2651,11 @@
 	return 0;
 }
  
-snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream,
+snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream,
 				    void __user **bufs,
 				    snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	int nonblock;
 
 	snd_assert(substream != NULL, return -ENXIO);
@@ -2672,7 +2669,7 @@
 	nonblock = !!(substream->ffile->f_flags & O_NONBLOCK);
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
 	if (substream->oss.oss) {
-		snd_pcm_oss_setup_t *setup = substream->oss.setup;
+		struct snd_pcm_oss_setup *setup = substream->oss.setup;
 		if (setup != NULL) {
 			if (setup->nonblock)
 				nonblock = 1;
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index b3f5344..a0119ae 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -46,7 +46,7 @@
  *
  * the minimum size is snd_minimum_buffer.  it should be power of 2.
  */
-static int preallocate_pcm_pages(snd_pcm_substream_t *substream, size_t size)
+static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t size)
 {
 	struct snd_dma_buffer *dmab = &substream->dma_buffer;
 	int err;
@@ -78,7 +78,7 @@
 /*
  * release the preallocated buffer if not yet done.
  */
-static void snd_pcm_lib_preallocate_dma_free(snd_pcm_substream_t *substream)
+static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream)
 {
 	if (substream->dma_buffer.area == NULL)
 		return;
@@ -97,13 +97,11 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_lib_preallocate_free(snd_pcm_substream_t *substream)
+int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream)
 {
 	snd_pcm_lib_preallocate_dma_free(substream);
-	if (substream->proc_prealloc_entry) {
-		snd_info_unregister(substream->proc_prealloc_entry);
-		substream->proc_prealloc_entry = NULL;
-	}
+	snd_info_unregister(substream->proc_prealloc_entry);
+	substream->proc_prealloc_entry = NULL;
 	return 0;
 }
 
@@ -115,9 +113,9 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_lib_preallocate_free_for_all(snd_pcm_t *pcm)
+int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	int stream;
 
 	for (stream = 0; stream < 2; stream++)
@@ -126,15 +124,16 @@
 	return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  * read callback for prealloc proc file
  *
  * prints the current allocated size in kB.
  */
-static void snd_pcm_lib_preallocate_proc_read(snd_info_entry_t *entry,
-					      snd_info_buffer_t *buffer)
+static void snd_pcm_lib_preallocate_proc_read(struct snd_info_entry *entry,
+					      struct snd_info_buffer *buffer)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;
+	struct snd_pcm_substream *substream = entry->private_data;
 	snd_iprintf(buffer, "%lu\n", (unsigned long) substream->dma_buffer.bytes / 1024);
 }
 
@@ -143,10 +142,10 @@
  *
  * accepts the preallocation size in kB.
  */
-static void snd_pcm_lib_preallocate_proc_write(snd_info_entry_t *entry,
-					       snd_info_buffer_t *buffer)
+static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
+					       struct snd_info_buffer *buffer)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)entry->private_data;
+	struct snd_pcm_substream *substream = entry->private_data;
 	char line[64], str[64];
 	size_t size;
 	struct snd_dma_buffer new_dmab;
@@ -185,20 +184,10 @@
 	}
 }
 
-/*
- * pre-allocate the buffer and create a proc file for the substream
- */
-static int snd_pcm_lib_preallocate_pages1(snd_pcm_substream_t *substream,
-					  size_t size, size_t max)
+static inline void preallocate_info_init(struct snd_pcm_substream *substream)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
-	if (size > 0 && preallocate_dma && substream->number < maximum_substreams)
-		preallocate_pcm_pages(substream, size);
-
-	if (substream->dma_buffer.bytes > 0)
-		substream->buffer_bytes_max = substream->dma_buffer.bytes;
-	substream->dma_max = max;
 	if ((entry = snd_info_create_card_entry(substream->pcm->card, "prealloc", substream->proc_root)) != NULL) {
 		entry->c.text.read_size = 64;
 		entry->c.text.read = snd_pcm_lib_preallocate_proc_read;
@@ -212,6 +201,26 @@
 		}
 	}
 	substream->proc_prealloc_entry = entry;
+}
+
+#else /* !CONFIG_PROC_FS */
+#define preallocate_info_init(s)
+#endif
+
+/*
+ * pre-allocate the buffer and create a proc file for the substream
+ */
+static int snd_pcm_lib_preallocate_pages1(struct snd_pcm_substream *substream,
+					  size_t size, size_t max)
+{
+
+	if (size > 0 && preallocate_dma && substream->number < maximum_substreams)
+		preallocate_pcm_pages(substream, size);
+
+	if (substream->dma_buffer.bytes > 0)
+		substream->buffer_bytes_max = substream->dma_buffer.bytes;
+	substream->dma_max = max;
+	preallocate_info_init(substream);
 	return 0;
 }
 
@@ -233,7 +242,7 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_lib_preallocate_pages(snd_pcm_substream_t *substream,
+int snd_pcm_lib_preallocate_pages(struct snd_pcm_substream *substream,
 				  int type, struct device *data,
 				  size_t size, size_t max)
 {
@@ -255,11 +264,11 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_lib_preallocate_pages_for_all(snd_pcm_t *pcm,
+int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
 					  int type, void *data,
 					  size_t size, size_t max)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	int stream, err;
 
 	for (stream = 0; stream < 2; stream++)
@@ -277,7 +286,7 @@
  * Returns the page struct at the given buffer offset.
  * Used as the page callback of PCM ops.
  */
-struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset)
+struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset)
 {
 	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
 
@@ -298,9 +307,9 @@
  * Returns 1 if the buffer is changed, 0 if not changed, or a negative
  * code on failure.
  */
-int snd_pcm_lib_malloc_pages(snd_pcm_substream_t *substream, size_t size)
+int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	struct snd_dma_buffer *dmab = NULL;
 
 	snd_assert(substream->dma_buffer.dev.type != SNDRV_DMA_TYPE_UNKNOWN, return -EINVAL);
@@ -318,7 +327,8 @@
 		}
 		snd_pcm_lib_free_pages(substream);
 	}
-	if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) {
+	if (substream->dma_buffer.area != NULL &&
+	    substream->dma_buffer.bytes >= size) {
 		dmab = &substream->dma_buffer; /* use the pre-allocated buffer */
 	} else {
 		dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
@@ -345,9 +355,9 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_pcm_lib_free_pages(snd_pcm_substream_t *substream)
+int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 
 	snd_assert(substream != NULL, return -EINVAL);
 	runtime = substream->runtime;
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 1453743..593c77f 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -441,7 +441,7 @@
  *
  * Returns zero if successful.
  */
-int snd_pcm_limit_hw_rates(snd_pcm_runtime_t *runtime)
+int snd_pcm_limit_hw_rates(struct snd_pcm_runtime *runtime)
 {
 	static unsigned rates[] = {
 		/* ATTENTION: these values depend on the definition in pcm.h! */
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 16e252f..f3d5de7 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -39,11 +39,11 @@
  *  Compatibility
  */
 
-struct sndrv_pcm_hw_params_old {
+struct snd_pcm_hw_params_old {
 	unsigned int flags;
 	unsigned int masks[SNDRV_PCM_HW_PARAM_SUBFORMAT -
 			   SNDRV_PCM_HW_PARAM_ACCESS + 1];
-	struct sndrv_interval intervals[SNDRV_PCM_HW_PARAM_TICK_TIME -
+	struct snd_interval intervals[SNDRV_PCM_HW_PARAM_TICK_TIME -
 					SNDRV_PCM_HW_PARAM_SAMPLE_BITS + 1];
 	unsigned int rmask;
 	unsigned int cmask;
@@ -51,15 +51,20 @@
 	unsigned int msbits;
 	unsigned int rate_num;
 	unsigned int rate_den;
-	sndrv_pcm_uframes_t fifo_size;
+	snd_pcm_uframes_t fifo_size;
 	unsigned char reserved[64];
 };
 
-#define SNDRV_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct sndrv_pcm_hw_params_old)
-#define SNDRV_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct sndrv_pcm_hw_params_old)
+#ifdef CONFIG_SND_SUPPORT_OLD_API
+#define SNDRV_PCM_IOCTL_HW_REFINE_OLD _IOWR('A', 0x10, struct snd_pcm_hw_params_old)
+#define SNDRV_PCM_IOCTL_HW_PARAMS_OLD _IOWR('A', 0x11, struct snd_pcm_hw_params_old)
 
-static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams);
-static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams);
+static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params_old __user * _oparams);
+static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params_old __user * _oparams);
+#endif
+static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
 
 /*
  *
@@ -83,11 +88,11 @@
 
 
 
-int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info)
+int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
 {
-	snd_pcm_runtime_t * runtime;
-	snd_pcm_t *pcm = substream->pcm;
-	snd_pcm_str_t *pstr = substream->pstr;
+	struct snd_pcm_runtime *runtime;
+	struct snd_pcm *pcm = substream->pcm;
+	struct snd_pcm_str *pstr = substream->pstr;
 
 	snd_assert(substream != NULL, return -ENXIO);
 	memset(info, 0, sizeof(*info));
@@ -111,9 +116,10 @@
 	return 0;
 }
 
-int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t __user * _info)
+int snd_pcm_info_user(struct snd_pcm_substream *substream,
+		      struct snd_pcm_info __user * _info)
 {
-	snd_pcm_info_t *info;
+	struct snd_pcm_info *info;
 	int err;
 
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
@@ -151,14 +157,14 @@
 };
 #endif
 
-int snd_pcm_hw_refine(snd_pcm_substream_t *substream, 
-		      snd_pcm_hw_params_t *params)
+int snd_pcm_hw_refine(struct snd_pcm_substream *substream, 
+		      struct snd_pcm_hw_params *params)
 {
 	unsigned int k;
-	snd_pcm_hardware_t *hw;
-	snd_interval_t *i = NULL;
-	snd_mask_t *m = NULL;
-	snd_pcm_hw_constraints_t *constrs = &substream->runtime->hw_constraints;
+	struct snd_pcm_hardware *hw;
+	struct snd_interval *i = NULL;
+	struct snd_mask *m = NULL;
+	struct snd_pcm_hw_constraints *constrs = &substream->runtime->hw_constraints;
 	unsigned int rstamps[constrs->rules_num];
 	unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1];
 	unsigned int stamp = 2;
@@ -231,7 +237,7 @@
 	do {
 		again = 0;
 		for (k = 0; k < constrs->rules_num; k++) {
-			snd_pcm_hw_rule_t *r = &constrs->rules[k];
+			struct snd_pcm_hw_rule *r = &constrs->rules[k];
 			unsigned int d;
 			int doit = 0;
 			if (r->cond && !(r->cond & params->flags))
@@ -313,9 +319,10 @@
 	return 0;
 }
 
-static int snd_pcm_hw_refine_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t __user * _params)
+static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params __user * _params)
 {
-	snd_pcm_hw_params_t *params;
+	struct snd_pcm_hw_params *params;
 	int err;
 
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
@@ -337,10 +344,10 @@
 	return err;
 }
 
-static int snd_pcm_hw_params(snd_pcm_substream_t *substream,
-			     snd_pcm_hw_params_t *params)
+static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	int err;
 	unsigned int bits;
 	snd_pcm_uframes_t frames;
@@ -432,9 +439,10 @@
 	return err;
 }
 
-static int snd_pcm_hw_params_user(snd_pcm_substream_t * substream, snd_pcm_hw_params_t __user * _params)
+static int snd_pcm_hw_params_user(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params __user * _params)
 {
-	snd_pcm_hw_params_t *params;
+	struct snd_pcm_hw_params *params;
 	int err;
 
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
@@ -456,9 +464,9 @@
 	return err;
 }
 
-static int snd_pcm_hw_free(snd_pcm_substream_t * substream)
+static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	int result = 0;
 
 	snd_assert(substream != NULL, return -ENXIO);
@@ -482,9 +490,10 @@
 	return result;
 }
 
-static int snd_pcm_sw_params(snd_pcm_substream_t * substream, snd_pcm_sw_params_t *params)
+static int snd_pcm_sw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_sw_params *params)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 
 	snd_assert(substream != NULL, return -ENXIO);
 	runtime = substream->runtime;
@@ -537,9 +546,10 @@
 	return 0;
 }
 
-static int snd_pcm_sw_params_user(snd_pcm_substream_t * substream, snd_pcm_sw_params_t __user * _params)
+static int snd_pcm_sw_params_user(struct snd_pcm_substream *substream,
+				  struct snd_pcm_sw_params __user * _params)
 {
-	snd_pcm_sw_params_t params;
+	struct snd_pcm_sw_params params;
 	int err;
 	if (copy_from_user(&params, _params, sizeof(params)))
 		return -EFAULT;
@@ -549,10 +559,10 @@
 	return err;
 }
 
-int snd_pcm_status(snd_pcm_substream_t *substream,
-		   snd_pcm_status_t *status)
+int snd_pcm_status(struct snd_pcm_substream *substream,
+		   struct snd_pcm_status *status)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_pcm_stream_lock_irq(substream);
 	status->state = runtime->status->state;
@@ -593,10 +603,11 @@
 	return 0;
 }
 
-static int snd_pcm_status_user(snd_pcm_substream_t * substream, snd_pcm_status_t __user * _status)
+static int snd_pcm_status_user(struct snd_pcm_substream *substream,
+			       struct snd_pcm_status __user * _status)
 {
-	snd_pcm_status_t status;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_status status;
+	struct snd_pcm_runtime *runtime;
 	int res;
 	
 	snd_assert(substream != NULL, return -ENXIO);
@@ -610,9 +621,10 @@
 	return 0;
 }
 
-static int snd_pcm_channel_info(snd_pcm_substream_t * substream, snd_pcm_channel_info_t * info)
+static int snd_pcm_channel_info(struct snd_pcm_substream *substream,
+				struct snd_pcm_channel_info * info)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	unsigned int channel;
 	
 	snd_assert(substream != NULL, return -ENXIO);
@@ -631,9 +643,10 @@
 	return substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_CHANNEL_INFO, info);
 }
 
-static int snd_pcm_channel_info_user(snd_pcm_substream_t * substream, snd_pcm_channel_info_t __user * _info)
+static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
+				     struct snd_pcm_channel_info __user * _info)
 {
-	snd_pcm_channel_info_t info;
+	struct snd_pcm_channel_info info;
 	int res;
 	
 	if (copy_from_user(&info, _info, sizeof(info)))
@@ -646,9 +659,9 @@
 	return 0;
 }
 
-static void snd_pcm_trigger_tstamp(snd_pcm_substream_t *substream)
+static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->trigger_master == NULL)
 		return;
 	if (runtime->trigger_master == substream) {
@@ -661,10 +674,10 @@
 }
 
 struct action_ops {
-	int (*pre_action)(snd_pcm_substream_t *substream, int state);
-	int (*do_action)(snd_pcm_substream_t *substream, int state);
-	void (*undo_action)(snd_pcm_substream_t *substream, int state);
-	void (*post_action)(snd_pcm_substream_t *substream, int state);
+	int (*pre_action)(struct snd_pcm_substream *substream, int state);
+	int (*do_action)(struct snd_pcm_substream *substream, int state);
+	void (*undo_action)(struct snd_pcm_substream *substream, int state);
+	void (*post_action)(struct snd_pcm_substream *substream, int state);
 };
 
 /*
@@ -673,12 +686,12 @@
  *  Note2: call with calling stream lock + link lock
  */
 static int snd_pcm_action_group(struct action_ops *ops,
-				snd_pcm_substream_t *substream,
+				struct snd_pcm_substream *substream,
 				int state, int do_lock)
 {
 	struct list_head *pos;
-	snd_pcm_substream_t *s = NULL;
-	snd_pcm_substream_t *s1;
+	struct snd_pcm_substream *s = NULL;
+	struct snd_pcm_substream *s1;
 	int res = 0;
 
 	snd_pcm_group_for_each(pos, substream) {
@@ -727,7 +740,7 @@
  *  Note: call with stream lock
  */
 static int snd_pcm_action_single(struct action_ops *ops,
-				 snd_pcm_substream_t *substream,
+				 struct snd_pcm_substream *substream,
 				 int state)
 {
 	int res;
@@ -747,7 +760,7 @@
  *  Note: call with stream lock
  */
 static int snd_pcm_action(struct action_ops *ops,
-			  snd_pcm_substream_t *substream,
+			  struct snd_pcm_substream *substream,
 			  int state)
 {
 	int res;
@@ -770,7 +783,7 @@
  *  Note: don't use any locks before
  */
 static int snd_pcm_action_lock_irq(struct action_ops *ops,
-				   snd_pcm_substream_t *substream,
+				   struct snd_pcm_substream *substream,
 				   int state)
 {
 	int res;
@@ -794,7 +807,7 @@
 /*
  */
 static int snd_pcm_action_nonatomic(struct action_ops *ops,
-				    snd_pcm_substream_t *substream,
+				    struct snd_pcm_substream *substream,
 				    int state)
 {
 	int res;
@@ -811,9 +824,9 @@
 /*
  * start callbacks
  */
-static int snd_pcm_pre_start(snd_pcm_substream_t *substream, int state)
+static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->status->state != SNDRV_PCM_STATE_PREPARED)
 		return -EBADFD;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
@@ -823,22 +836,22 @@
 	return 0;
 }
 
-static int snd_pcm_do_start(snd_pcm_substream_t *substream, int state)
+static int snd_pcm_do_start(struct snd_pcm_substream *substream, int state)
 {
 	if (substream->runtime->trigger_master != substream)
 		return 0;
 	return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
 }
 
-static void snd_pcm_undo_start(snd_pcm_substream_t *substream, int state)
+static void snd_pcm_undo_start(struct snd_pcm_substream *substream, int state)
 {
 	if (substream->runtime->trigger_master == substream)
 		substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
 }
 
-static void snd_pcm_post_start(snd_pcm_substream_t *substream, int state)
+static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_trigger_tstamp(substream);
 	runtime->status->state = state;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
@@ -847,7 +860,8 @@
 	if (runtime->sleep_min)
 		snd_pcm_tick_prepare(substream);
 	if (substream->timer)
-		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART, &runtime->trigger_tstamp);
+		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTART,
+				 &runtime->trigger_tstamp);
 }
 
 static struct action_ops snd_pcm_action_start = {
@@ -863,24 +877,25 @@
  *
  * Start all linked streams.
  */
-int snd_pcm_start(snd_pcm_substream_t *substream)
+int snd_pcm_start(struct snd_pcm_substream *substream)
 {
-	return snd_pcm_action(&snd_pcm_action_start, substream, SNDRV_PCM_STATE_RUNNING);
+	return snd_pcm_action(&snd_pcm_action_start, substream,
+			      SNDRV_PCM_STATE_RUNNING);
 }
 
 /*
  * stop callbacks
  */
-static int snd_pcm_pre_stop(snd_pcm_substream_t *substream, int state)
+static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 		return -EBADFD;
 	runtime->trigger_master = substream;
 	return 0;
 }
 
-static int snd_pcm_do_stop(snd_pcm_substream_t *substream, int state)
+static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state)
 {
 	if (substream->runtime->trigger_master == substream &&
 	    snd_pcm_running(substream))
@@ -888,13 +903,14 @@
 	return 0; /* unconditonally stop all substreams */
 }
 
-static void snd_pcm_post_stop(snd_pcm_substream_t *substream, int state)
+static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->status->state != state) {
 		snd_pcm_trigger_tstamp(substream);
 		if (substream->timer)
-			snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP, &runtime->trigger_tstamp);
+			snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSTOP,
+					 &runtime->trigger_tstamp);
 		runtime->status->state = state;
 		snd_pcm_tick_set(substream, 0);
 	}
@@ -915,7 +931,7 @@
  * Try to stop all running streams in the substream group.
  * The state of each stream is changed to the given value after that unconditionally.
  */
-int snd_pcm_stop(snd_pcm_substream_t *substream, int state)
+int snd_pcm_stop(struct snd_pcm_substream *substream, int state)
 {
 	return snd_pcm_action(&snd_pcm_action_stop, substream, state);
 }
@@ -928,17 +944,18 @@
  * The state is changed to SETUP.
  * Unlike snd_pcm_stop(), this affects only the given stream.
  */
-int snd_pcm_drain_done(snd_pcm_substream_t *substream)
+int snd_pcm_drain_done(struct snd_pcm_substream *substream)
 {
-	return snd_pcm_action_single(&snd_pcm_action_stop, substream, SNDRV_PCM_STATE_SETUP);
+	return snd_pcm_action_single(&snd_pcm_action_stop, substream,
+				     SNDRV_PCM_STATE_SETUP);
 }
 
 /*
  * pause callbacks
  */
-static int snd_pcm_pre_pause(snd_pcm_substream_t *substream, int push)
+static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (!(runtime->info & SNDRV_PCM_INFO_PAUSE))
 		return -ENOSYS;
 	if (push) {
@@ -950,7 +967,7 @@
 	return 0;
 }
 
-static int snd_pcm_do_pause(snd_pcm_substream_t *substream, int push)
+static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
 {
 	if (substream->runtime->trigger_master != substream)
 		return 0;
@@ -959,7 +976,7 @@
 					      SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
 }
 
-static void snd_pcm_undo_pause(snd_pcm_substream_t *substream, int push)
+static void snd_pcm_undo_pause(struct snd_pcm_substream *substream, int push)
 {
 	if (substream->runtime->trigger_master == substream)
 		substream->ops->trigger(substream,
@@ -967,14 +984,16 @@
 					SNDRV_PCM_TRIGGER_PAUSE_PUSH);
 }
 
-static void snd_pcm_post_pause(snd_pcm_substream_t *substream, int push)
+static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_trigger_tstamp(substream);
 	if (push) {
 		runtime->status->state = SNDRV_PCM_STATE_PAUSED;
 		if (substream->timer)
-			snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MPAUSE, &runtime->trigger_tstamp);
+			snd_timer_notify(substream->timer,
+					 SNDRV_TIMER_EVENT_MPAUSE,
+					 &runtime->trigger_tstamp);
 		snd_pcm_tick_set(substream, 0);
 		wake_up(&runtime->sleep);
 	} else {
@@ -982,7 +1001,9 @@
 		if (runtime->sleep_min)
 			snd_pcm_tick_prepare(substream);
 		if (substream->timer)
-			snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MCONTINUE, &runtime->trigger_tstamp);
+			snd_timer_notify(substream->timer,
+					 SNDRV_TIMER_EVENT_MCONTINUE,
+					 &runtime->trigger_tstamp);
 	}
 }
 
@@ -996,7 +1017,7 @@
 /*
  * Push/release the pause for all linked streams.
  */
-static int snd_pcm_pause(snd_pcm_substream_t *substream, int push)
+static int snd_pcm_pause(struct snd_pcm_substream *substream, int push)
 {
 	return snd_pcm_action(&snd_pcm_action_pause, substream, push);
 }
@@ -1004,18 +1025,18 @@
 #ifdef CONFIG_PM
 /* suspend */
 
-static int snd_pcm_pre_suspend(snd_pcm_substream_t *substream, int state)
+static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
 		return -EBUSY;
 	runtime->trigger_master = substream;
 	return 0;
 }
 
-static int snd_pcm_do_suspend(snd_pcm_substream_t *substream, int state)
+static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->trigger_master != substream)
 		return 0;
 	if (! snd_pcm_running(substream))
@@ -1024,12 +1045,13 @@
 	return 0; /* suspend unconditionally */
 }
 
-static void snd_pcm_post_suspend(snd_pcm_substream_t *substream, int state)
+static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_trigger_tstamp(substream);
 	if (substream->timer)
-		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND, &runtime->trigger_tstamp);
+		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MSUSPEND,
+				 &runtime->trigger_tstamp);
 	runtime->status->suspended_state = runtime->status->state;
 	runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
 	snd_pcm_tick_set(substream, 0);
@@ -1049,11 +1071,14 @@
  * Trigger SUSPEND to all linked streams.
  * After this call, all streams are changed to SUSPENDED state.
  */
-int snd_pcm_suspend(snd_pcm_substream_t *substream)
+int snd_pcm_suspend(struct snd_pcm_substream *substream)
 {
 	int err;
 	unsigned long flags;
 
+	if (! substream)
+		return 0;
+
 	snd_pcm_stream_lock_irqsave(substream, flags);
 	err = snd_pcm_action(&snd_pcm_action_suspend, substream, 0);
 	snd_pcm_stream_unlock_irqrestore(substream, flags);
@@ -1067,13 +1092,17 @@
  * Trigger SUSPEND to all substreams in the given pcm.
  * After this call, all streams are changed to SUSPENDED state.
  */
-int snd_pcm_suspend_all(snd_pcm_t *pcm)
+int snd_pcm_suspend_all(struct snd_pcm *pcm)
 {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	int stream, err = 0;
 
+	if (! pcm)
+		return 0;
+
 	for (stream = 0; stream < 2; stream++) {
-		for (substream = pcm->streams[stream].substream; substream; substream = substream->next) {
+		for (substream = pcm->streams[stream].substream;
+		     substream; substream = substream->next) {
 			/* FIXME: the open/close code should lock this as well */
 			if (substream->runtime == NULL)
 				continue;
@@ -1087,18 +1116,18 @@
 
 /* resume */
 
-static int snd_pcm_pre_resume(snd_pcm_substream_t *substream, int state)
+static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (!(runtime->info & SNDRV_PCM_INFO_RESUME))
 		return -ENOSYS;
 	runtime->trigger_master = substream;
 	return 0;
 }
 
-static int snd_pcm_do_resume(snd_pcm_substream_t *substream, int state)
+static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->trigger_master != substream)
 		return 0;
 	/* DMA not running previously? */
@@ -1109,19 +1138,20 @@
 	return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
 }
 
-static void snd_pcm_undo_resume(snd_pcm_substream_t *substream, int state)
+static void snd_pcm_undo_resume(struct snd_pcm_substream *substream, int state)
 {
 	if (substream->runtime->trigger_master == substream &&
 	    snd_pcm_running(substream))
 		substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
 }
 
-static void snd_pcm_post_resume(snd_pcm_substream_t *substream, int state)
+static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_trigger_tstamp(substream);
 	if (substream->timer)
-		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME, &runtime->trigger_tstamp);
+		snd_timer_notify(substream->timer, SNDRV_TIMER_EVENT_MRESUME,
+				 &runtime->trigger_tstamp);
 	runtime->status->state = runtime->status->suspended_state;
 	if (runtime->sleep_min)
 		snd_pcm_tick_prepare(substream);
@@ -1134,9 +1164,9 @@
 	.post_action = snd_pcm_post_resume
 };
 
-static int snd_pcm_resume(snd_pcm_substream_t *substream)
+static int snd_pcm_resume(struct snd_pcm_substream *substream)
 {
-	snd_card_t *card = substream->pcm->card;
+	struct snd_card *card = substream->pcm->card;
 	int res;
 
 	snd_power_lock(card);
@@ -1148,7 +1178,7 @@
 
 #else
 
-static int snd_pcm_resume(snd_pcm_substream_t *substream)
+static int snd_pcm_resume(struct snd_pcm_substream *substream)
 {
 	return -ENOSYS;
 }
@@ -1160,10 +1190,10 @@
  *
  * Change the RUNNING stream(s) to XRUN state.
  */
-static int snd_pcm_xrun(snd_pcm_substream_t *substream)
+static int snd_pcm_xrun(struct snd_pcm_substream *substream)
 {
-	snd_card_t *card = substream->pcm->card;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_card *card = substream->pcm->card;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int result;
 
 	snd_power_lock(card);
@@ -1193,9 +1223,9 @@
 /*
  * reset ioctl
  */
-static int snd_pcm_pre_reset(snd_pcm_substream_t * substream, int state)
+static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	switch (runtime->status->state) {
 	case SNDRV_PCM_STATE_RUNNING:
 	case SNDRV_PCM_STATE_PREPARED:
@@ -1207,23 +1237,24 @@
 	}
 }
 
-static int snd_pcm_do_reset(snd_pcm_substream_t * substream, int state)
+static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err = substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
 	if (err < 0)
 		return err;
 	// snd_assert(runtime->status->hw_ptr < runtime->buffer_size, );
 	runtime->hw_ptr_base = 0;
-	runtime->hw_ptr_interrupt = runtime->status->hw_ptr - runtime->status->hw_ptr % runtime->period_size;
+	runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
+		runtime->status->hw_ptr % runtime->period_size;
 	runtime->silence_start = runtime->status->hw_ptr;
 	runtime->silence_filled = 0;
 	return 0;
 }
 
-static void snd_pcm_post_reset(snd_pcm_substream_t * substream, int state)
+static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	runtime->control->appl_ptr = runtime->status->hw_ptr;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
 	    runtime->silence_size > 0)
@@ -1236,7 +1267,7 @@
 	.post_action = snd_pcm_post_reset
 };
 
-static int snd_pcm_reset(snd_pcm_substream_t *substream)
+static int snd_pcm_reset(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream, 0);
 }
@@ -1244,9 +1275,9 @@
 /*
  * prepare ioctl
  */
-static int snd_pcm_pre_prepare(snd_pcm_substream_t * substream, int state)
+static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 		return -EBADFD;
 	if (snd_pcm_running(substream))
@@ -1254,7 +1285,7 @@
 	return 0;
 }
 
-static int snd_pcm_do_prepare(snd_pcm_substream_t * substream, int state)
+static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, int state)
 {
 	int err;
 	err = substream->ops->prepare(substream);
@@ -1263,9 +1294,9 @@
 	return snd_pcm_do_reset(substream, 0);
 }
 
-static void snd_pcm_post_prepare(snd_pcm_substream_t * substream, int state)
+static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	runtime->control->appl_ptr = runtime->status->hw_ptr;
 	runtime->status->state = SNDRV_PCM_STATE_PREPARED;
 }
@@ -1282,10 +1313,10 @@
  *
  * Prepare the PCM substream to be triggerable.
  */
-int snd_pcm_prepare(snd_pcm_substream_t *substream)
+int snd_pcm_prepare(struct snd_pcm_substream *substream)
 {
 	int res;
-	snd_card_t *card = substream->pcm->card;
+	struct snd_card *card = substream->pcm->card;
 
 	snd_power_lock(card);
 	if ((res = snd_power_wait(card, SNDRV_CTL_POWER_D0, substream->ffile)) >= 0)
@@ -1298,7 +1329,7 @@
  * drain ioctl
  */
 
-static int snd_pcm_pre_drain_init(snd_pcm_substream_t * substream, int state)
+static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
 {
 	if (substream->ffile->f_flags & O_NONBLOCK)
 		return -EAGAIN;
@@ -1306,9 +1337,9 @@
 	return 0;
 }
 
-static int snd_pcm_do_drain_init(snd_pcm_substream_t * substream, int state)
+static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		switch (runtime->status->state) {
 		case SNDRV_PCM_STATE_PREPARED:
@@ -1336,7 +1367,7 @@
 	return 0;
 }
 
-static void snd_pcm_post_drain_init(snd_pcm_substream_t * substream, int state)
+static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int state)
 {
 }
 
@@ -1347,12 +1378,12 @@
 };
 
 struct drain_rec {
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	wait_queue_t wait;
 	snd_pcm_uframes_t stop_threshold;
 };
 
-static int snd_pcm_drop(snd_pcm_substream_t *substream);
+static int snd_pcm_drop(struct snd_pcm_substream *substream);
 
 /*
  * Drain the stream(s).
@@ -1361,10 +1392,10 @@
  * After this call, all streams are supposed to be either SETUP or DRAINING
  * (capture only) state.
  */
-static int snd_pcm_drain(snd_pcm_substream_t *substream)
+static int snd_pcm_drain(struct snd_pcm_substream *substream)
 {
-	snd_card_t *card;
-	snd_pcm_runtime_t *runtime;
+	struct snd_card *card;
+	struct snd_pcm_runtime *runtime;
 	struct list_head *pos;
 	int result = 0;
 	int i, num_drecs;
@@ -1401,7 +1432,7 @@
 	/* count only playback streams */
 	num_drecs = 0;
 	snd_pcm_group_for_each(pos, substream) {
-		snd_pcm_substream_t *s = snd_pcm_group_substream_entry(pos);
+		struct snd_pcm_substream *s = snd_pcm_group_substream_entry(pos);
 		runtime = s->runtime;
 		if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 			d = &drec[num_drecs++];
@@ -1487,10 +1518,10 @@
  *
  * Immediately put all linked substreams into SETUP state.
  */
-static int snd_pcm_drop(snd_pcm_substream_t *substream)
+static int snd_pcm_drop(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime;
-	snd_card_t *card;
+	struct snd_pcm_runtime *runtime;
+	struct snd_card *card;
 	int result = 0;
 	
 	snd_assert(substream != NULL, return -ENXIO);
@@ -1526,7 +1557,8 @@
 {
 	struct file *file;
 	struct inode *inode;
-	unsigned short minor;
+	unsigned int minor;
+
 	file = fget(fd);
 	if (!file)
 		return NULL;
@@ -1537,8 +1569,8 @@
 		return NULL;
 	}
 	minor = iminor(inode);
-	if (minor >= 256 || 
-	    minor % SNDRV_MINOR_DEVICES < SNDRV_MINOR_PCM_PLAYBACK) {
+	if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) &&
+	    !snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) {
 		fput(file);
 		return NULL;
 	}
@@ -1548,12 +1580,12 @@
 /*
  * PCM link handling
  */
-static int snd_pcm_link(snd_pcm_substream_t *substream, int fd)
+static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
 {
 	int res = 0;
 	struct file *file;
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream1;
+	struct snd_pcm_file *pcm_file;
+	struct snd_pcm_substream *substream1;
 
 	file = snd_pcm_file_fd(fd);
 	if (!file)
@@ -1572,7 +1604,7 @@
 		goto _end;
 	}
 	if (!snd_pcm_stream_linked(substream)) {
-		substream->group = kmalloc(sizeof(snd_pcm_group_t), GFP_ATOMIC);
+		substream->group = kmalloc(sizeof(struct snd_pcm_group), GFP_ATOMIC);
 		if (substream->group == NULL) {
 			res = -ENOMEM;
 			goto _end;
@@ -1592,14 +1624,14 @@
 	return res;
 }
 
-static void relink_to_local(snd_pcm_substream_t *substream)
+static void relink_to_local(struct snd_pcm_substream *substream)
 {
 	substream->group = &substream->self_group;
 	INIT_LIST_HEAD(&substream->self_group.substreams);
 	list_add_tail(&substream->link_list, &substream->self_group.substreams);
 }
 
-static int snd_pcm_unlink(snd_pcm_substream_t *substream)
+static int snd_pcm_unlink(struct snd_pcm_substream *substream)
 {
 	struct list_head *pos;
 	int res = 0;
@@ -1629,51 +1661,51 @@
 /*
  * hw configurator
  */
-static int snd_pcm_hw_rule_mul(snd_pcm_hw_params_t *params,
-			       snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_mul(struct snd_pcm_hw_params *params,
+			       struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t t;
+	struct snd_interval t;
 	snd_interval_mul(hw_param_interval_c(params, rule->deps[0]),
 		     hw_param_interval_c(params, rule->deps[1]), &t);
 	return snd_interval_refine(hw_param_interval(params, rule->var), &t);
 }
 
-static int snd_pcm_hw_rule_div(snd_pcm_hw_params_t *params,
-			       snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_div(struct snd_pcm_hw_params *params,
+			       struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t t;
+	struct snd_interval t;
 	snd_interval_div(hw_param_interval_c(params, rule->deps[0]),
 		     hw_param_interval_c(params, rule->deps[1]), &t);
 	return snd_interval_refine(hw_param_interval(params, rule->var), &t);
 }
 
-static int snd_pcm_hw_rule_muldivk(snd_pcm_hw_params_t *params,
-				   snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_muldivk(struct snd_pcm_hw_params *params,
+				   struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t t;
+	struct snd_interval t;
 	snd_interval_muldivk(hw_param_interval_c(params, rule->deps[0]),
 			 hw_param_interval_c(params, rule->deps[1]),
 			 (unsigned long) rule->private, &t);
 	return snd_interval_refine(hw_param_interval(params, rule->var), &t);
 }
 
-static int snd_pcm_hw_rule_mulkdiv(snd_pcm_hw_params_t *params,
-				   snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_mulkdiv(struct snd_pcm_hw_params *params,
+				   struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t t;
+	struct snd_interval t;
 	snd_interval_mulkdiv(hw_param_interval_c(params, rule->deps[0]),
 			 (unsigned long) rule->private,
 			 hw_param_interval_c(params, rule->deps[1]), &t);
 	return snd_interval_refine(hw_param_interval(params, rule->var), &t);
 }
 
-static int snd_pcm_hw_rule_format(snd_pcm_hw_params_t *params,
-				  snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_format(struct snd_pcm_hw_params *params,
+				  struct snd_pcm_hw_rule *rule)
 {
 	unsigned int k;
-	snd_interval_t *i = hw_param_interval(params, rule->deps[0]);
-	snd_mask_t m;
-	snd_mask_t *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	struct snd_interval *i = hw_param_interval(params, rule->deps[0]);
+	struct snd_mask m;
+	struct snd_mask *mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 	snd_mask_any(&m);
 	for (k = 0; k <= SNDRV_PCM_FORMAT_LAST; ++k) {
 		int bits;
@@ -1688,10 +1720,10 @@
 	return snd_mask_refine(mask, &m);
 }
 
-static int snd_pcm_hw_rule_sample_bits(snd_pcm_hw_params_t *params,
-				       snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_sample_bits(struct snd_pcm_hw_params *params,
+				       struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t t;
+	struct snd_interval t;
 	unsigned int k;
 	t.min = UINT_MAX;
 	t.max = 0;
@@ -1720,19 +1752,19 @@
 static unsigned int rates[] = { 5512, 8000, 11025, 16000, 22050, 32000, 44100,
                                  48000, 64000, 88200, 96000, 176400, 192000 };
 
-static int snd_pcm_hw_rule_rate(snd_pcm_hw_params_t *params,
-				snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_rate(struct snd_pcm_hw_params *params,
+				struct snd_pcm_hw_rule *rule)
 {
-	snd_pcm_hardware_t *hw = rule->private;
+	struct snd_pcm_hardware *hw = rule->private;
 	return snd_interval_list(hw_param_interval(params, rule->var),
 				 ARRAY_SIZE(rates), rates, hw->rates);
 }		
 
-static int snd_pcm_hw_rule_buffer_bytes_max(snd_pcm_hw_params_t *params,
-					    snd_pcm_hw_rule_t *rule)
+static int snd_pcm_hw_rule_buffer_bytes_max(struct snd_pcm_hw_params *params,
+					    struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t t;
-	snd_pcm_substream_t *substream = rule->private;
+	struct snd_interval t;
+	struct snd_pcm_substream *substream = rule->private;
 	t.min = 0;
 	t.max = substream->buffer_bytes_max;
 	t.openmin = 0;
@@ -1741,10 +1773,10 @@
 	return snd_interval_refine(hw_param_interval(params, rule->var), &t);
 }		
 
-int snd_pcm_hw_constraints_init(snd_pcm_substream_t *substream)
+int snd_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_hw_constraints_t *constrs = &runtime->hw_constraints;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_pcm_hw_constraints *constrs = &runtime->hw_constraints;
 	int k, err;
 
 	for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK; k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) {
@@ -1865,10 +1897,10 @@
 	return 0;
 }
 
-int snd_pcm_hw_constraints_complete(snd_pcm_substream_t *substream)
+int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_hardware_t *hw = &runtime->hw;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_pcm_hardware *hw = &runtime->hw;
 	int err;
 	unsigned int mask = 0;
 
@@ -1941,17 +1973,17 @@
 	return 0;
 }
 
-static void snd_pcm_add_file(snd_pcm_str_t *str,
-			     snd_pcm_file_t *pcm_file)
+static void snd_pcm_add_file(struct snd_pcm_str *str,
+			     struct snd_pcm_file *pcm_file)
 {
 	pcm_file->next = str->files;
 	str->files = pcm_file;
 }
 
-static void snd_pcm_remove_file(snd_pcm_str_t *str,
-				snd_pcm_file_t *pcm_file)
+static void snd_pcm_remove_file(struct snd_pcm_str *str,
+				struct snd_pcm_file *pcm_file)
 {
-	snd_pcm_file_t * pcm_file1;
+	struct snd_pcm_file * pcm_file1;
 	if (str->files == pcm_file) {
 		str->files = pcm_file->next;
 	} else {
@@ -1963,11 +1995,11 @@
 	}
 }
 
-static int snd_pcm_release_file(snd_pcm_file_t * pcm_file)
+static int snd_pcm_release_file(struct snd_pcm_file * pcm_file)
 {
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
-	snd_pcm_str_t * str;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
+	struct snd_pcm_str * str;
 
 	snd_assert(pcm_file != NULL, return -ENXIO);
 	substream = pcm_file->substream;
@@ -1988,14 +2020,14 @@
 }
 
 static int snd_pcm_open_file(struct file *file,
-			     snd_pcm_t *pcm,
+			     struct snd_pcm *pcm,
 			     int stream,
-			     snd_pcm_file_t **rpcm_file)
+			     struct snd_pcm_file **rpcm_file)
 {
 	int err = 0;
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream;
-	snd_pcm_str_t *str;
+	struct snd_pcm_file *pcm_file;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_str *str;
 
 	snd_assert(rpcm_file != NULL, return -EINVAL);
 	*rpcm_file = NULL;
@@ -2043,18 +2075,30 @@
 	return 0;
 }
 
-static int snd_pcm_open(struct inode *inode, struct file *file)
+static int snd_pcm_playback_open(struct inode *inode, struct file *file)
 {
-	int cardnum = SNDRV_MINOR_CARD(iminor(inode));
-	int device = SNDRV_MINOR_DEVICE(iminor(inode));
+	struct snd_pcm *pcm;
+
+	pcm = snd_lookup_minor_data(iminor(inode),
+				    SNDRV_DEVICE_TYPE_PCM_PLAYBACK);
+	return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK);
+}
+
+static int snd_pcm_capture_open(struct inode *inode, struct file *file)
+{
+	struct snd_pcm *pcm;
+
+	pcm = snd_lookup_minor_data(iminor(inode),
+				    SNDRV_DEVICE_TYPE_PCM_CAPTURE);
+	return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE);
+}
+
+static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream)
+{
 	int err;
-	snd_pcm_t *pcm;
-	snd_pcm_file_t *pcm_file;
+	struct snd_pcm_file *pcm_file;
 	wait_queue_t wait;
 
-	if (device < SNDRV_MINOR_PCM_PLAYBACK || device >= SNDRV_MINOR_DEVICES)
-		return -ENXIO;
-	pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)];
 	if (pcm == NULL) {
 		err = -ENODEV;
 		goto __error1;
@@ -2070,7 +2114,7 @@
 	add_wait_queue(&pcm->open_wait, &wait);
 	down(&pcm->open_mutex);
 	while (1) {
-		err = snd_pcm_open_file(file, pcm, device >= SNDRV_MINOR_PCM_CAPTURE ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK, &pcm_file);
+		err = snd_pcm_open_file(file, pcm, stream, &pcm_file);
 		if (err >= 0)
 			break;
 		if (err == -EAGAIN) {
@@ -2105,9 +2149,9 @@
 
 static int snd_pcm_release(struct inode *inode, struct file *file)
 {
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *substream;
-	snd_pcm_file_t *pcm_file;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_file *pcm_file;
 
 	pcm_file = file->private_data;
 	substream = pcm_file->substream;
@@ -2125,9 +2169,10 @@
 	return 0;
 }
 
-static snd_pcm_sframes_t snd_pcm_playback_rewind(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_playback_rewind(struct snd_pcm_substream *substream,
+						 snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_sframes_t appl_ptr;
 	snd_pcm_sframes_t ret;
 	snd_pcm_sframes_t hw_avail;
@@ -2174,9 +2219,10 @@
 	return ret;
 }
 
-static snd_pcm_sframes_t snd_pcm_capture_rewind(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_capture_rewind(struct snd_pcm_substream *substream,
+						snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_sframes_t appl_ptr;
 	snd_pcm_sframes_t ret;
 	snd_pcm_sframes_t hw_avail;
@@ -2223,9 +2269,10 @@
 	return ret;
 }
 
-static snd_pcm_sframes_t snd_pcm_playback_forward(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_playback_forward(struct snd_pcm_substream *substream,
+						  snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_sframes_t appl_ptr;
 	snd_pcm_sframes_t ret;
 	snd_pcm_sframes_t avail;
@@ -2273,9 +2320,10 @@
 	return ret;
 }
 
-static snd_pcm_sframes_t snd_pcm_capture_forward(snd_pcm_substream_t *substream, snd_pcm_uframes_t frames)
+static snd_pcm_sframes_t snd_pcm_capture_forward(struct snd_pcm_substream *substream,
+						 snd_pcm_uframes_t frames)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	snd_pcm_sframes_t appl_ptr;
 	snd_pcm_sframes_t ret;
 	snd_pcm_sframes_t avail;
@@ -2323,9 +2371,9 @@
 	return ret;
 }
 
-static int snd_pcm_hwsync(snd_pcm_substream_t *substream)
+static int snd_pcm_hwsync(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	snd_pcm_stream_lock_irq(substream);
@@ -2353,9 +2401,10 @@
 	return err;
 }
 		
-static int snd_pcm_delay(snd_pcm_substream_t *substream, snd_pcm_sframes_t __user *res)
+static int snd_pcm_delay(struct snd_pcm_substream *substream,
+			 snd_pcm_sframes_t __user *res)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	snd_pcm_sframes_t n = 0;
 
@@ -2391,18 +2440,19 @@
 	return err;
 }
 		
-static int snd_pcm_sync_ptr(snd_pcm_substream_t *substream, struct sndrv_pcm_sync_ptr __user *_sync_ptr)
+static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
+			    struct snd_pcm_sync_ptr __user *_sync_ptr)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	struct sndrv_pcm_sync_ptr sync_ptr;
-	volatile struct sndrv_pcm_mmap_status *status;
-	volatile struct sndrv_pcm_mmap_control *control;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_pcm_sync_ptr sync_ptr;
+	volatile struct snd_pcm_mmap_status *status;
+	volatile struct snd_pcm_mmap_control *control;
 	int err;
 
 	memset(&sync_ptr, 0, sizeof(sync_ptr));
 	if (get_user(sync_ptr.flags, (unsigned __user *)&(_sync_ptr->flags)))
 		return -EFAULT;
-	if (copy_from_user(&sync_ptr.c.control, &(_sync_ptr->c.control), sizeof(struct sndrv_pcm_mmap_control)))
+	if (copy_from_user(&sync_ptr.c.control, &(_sync_ptr->c.control), sizeof(struct snd_pcm_mmap_control)))
 		return -EFAULT;	
 	status = runtime->status;
 	control = runtime->control;
@@ -2430,12 +2480,12 @@
 	return 0;
 }
 		
-static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
+static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
 				   unsigned int cmd, void __user *arg);
-static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
+static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
 				  unsigned int cmd, void __user *arg);
 
-static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream,
+static int snd_pcm_common_ioctl1(struct snd_pcm_substream *substream,
 				 unsigned int cmd, void __user *arg)
 {
 	snd_assert(substream != NULL, return -ENXIO);
@@ -2479,10 +2529,12 @@
 		return snd_pcm_delay(substream, arg);
 	case SNDRV_PCM_IOCTL_SYNC_PTR:
 		return snd_pcm_sync_ptr(substream, arg);
+#ifdef CONFIG_SND_SUPPORT_OLD_API
 	case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
 		return snd_pcm_hw_refine_old_user(substream, arg);
 	case SNDRV_PCM_IOCTL_HW_PARAMS_OLD:
 		return snd_pcm_hw_params_old_user(substream, arg);
+#endif
 	case SNDRV_PCM_IOCTL_DRAIN:
 		return snd_pcm_drain(substream);
 	case SNDRV_PCM_IOCTL_DROP:
@@ -2492,7 +2544,7 @@
 	return -ENOTTY;
 }
 
-static int snd_pcm_playback_ioctl1(snd_pcm_substream_t *substream,
+static int snd_pcm_playback_ioctl1(struct snd_pcm_substream *substream,
 				   unsigned int cmd, void __user *arg)
 {
 	snd_assert(substream != NULL, return -ENXIO);
@@ -2500,9 +2552,9 @@
 	switch (cmd) {
 	case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
 	{
-		snd_xferi_t xferi;
-		snd_xferi_t __user *_xferi = arg;
-		snd_pcm_runtime_t *runtime = substream->runtime;
+		struct snd_xferi xferi;
+		struct snd_xferi __user *_xferi = arg;
+		struct snd_pcm_runtime *runtime = substream->runtime;
 		snd_pcm_sframes_t result;
 		if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 			return -EBADFD;
@@ -2516,9 +2568,9 @@
 	}
 	case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
 	{
-		snd_xfern_t xfern;
-		snd_xfern_t __user *_xfern = arg;
-		snd_pcm_runtime_t *runtime = substream->runtime;
+		struct snd_xfern xfern;
+		struct snd_xfern __user *_xfern = arg;
+		struct snd_pcm_runtime *runtime = substream->runtime;
 		void __user **bufs;
 		snd_pcm_sframes_t result;
 		if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
@@ -2579,7 +2631,7 @@
 	return snd_pcm_common_ioctl1(substream, cmd, arg);
 }
 
-static int snd_pcm_capture_ioctl1(snd_pcm_substream_t *substream,
+static int snd_pcm_capture_ioctl1(struct snd_pcm_substream *substream,
 				  unsigned int cmd, void __user *arg)
 {
 	snd_assert(substream != NULL, return -ENXIO);
@@ -2587,9 +2639,9 @@
 	switch (cmd) {
 	case SNDRV_PCM_IOCTL_READI_FRAMES:
 	{
-		snd_xferi_t xferi;
-		snd_xferi_t __user *_xferi = arg;
-		snd_pcm_runtime_t *runtime = substream->runtime;
+		struct snd_xferi xferi;
+		struct snd_xferi __user *_xferi = arg;
+		struct snd_pcm_runtime *runtime = substream->runtime;
 		snd_pcm_sframes_t result;
 		if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
 			return -EBADFD;
@@ -2603,9 +2655,9 @@
 	}
 	case SNDRV_PCM_IOCTL_READN_FRAMES:
 	{
-		snd_xfern_t xfern;
-		snd_xfern_t __user *_xfern = arg;
-		snd_pcm_runtime_t *runtime = substream->runtime;
+		struct snd_xfern xfern;
+		struct snd_xfern __user *_xfern = arg;
+		struct snd_pcm_runtime *runtime = substream->runtime;
 		void *bufs;
 		snd_pcm_sframes_t result;
 		if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
@@ -2658,9 +2710,10 @@
 	return snd_pcm_common_ioctl1(substream, cmd, arg);
 }
 
-static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
+				   unsigned long arg)
 {
-	snd_pcm_file_t *pcm_file;
+	struct snd_pcm_file *pcm_file;
 
 	pcm_file = file->private_data;
 
@@ -2670,9 +2723,10 @@
 	return snd_pcm_playback_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
 }
 
-static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
+				  unsigned long arg)
 {
-	snd_pcm_file_t *pcm_file;
+	struct snd_pcm_file *pcm_file;
 
 	pcm_file = file->private_data;
 
@@ -2682,7 +2736,7 @@
 	return snd_pcm_capture_ioctl1(pcm_file->substream, cmd, (void __user *)arg);
 }
 
-int snd_pcm_kernel_playback_ioctl(snd_pcm_substream_t *substream,
+int snd_pcm_kernel_playback_ioctl(struct snd_pcm_substream *substream,
 				  unsigned int cmd, void *arg)
 {
 	mm_segment_t fs;
@@ -2694,7 +2748,7 @@
 	return result;
 }
 
-int snd_pcm_kernel_capture_ioctl(snd_pcm_substream_t *substream,
+int snd_pcm_kernel_capture_ioctl(struct snd_pcm_substream *substream,
 				 unsigned int cmd, void *arg)
 {
 	mm_segment_t fs;
@@ -2706,7 +2760,7 @@
 	return result;
 }
 
-int snd_pcm_kernel_ioctl(snd_pcm_substream_t *substream,
+int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
 			 unsigned int cmd, void *arg)
 {
 	switch (substream->stream) {
@@ -2719,11 +2773,12 @@
 	}
 }
 
-static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count, loff_t * offset)
+static ssize_t snd_pcm_read(struct file *file, char __user *buf, size_t count,
+			    loff_t * offset)
 {
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_file *pcm_file;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	snd_pcm_sframes_t result;
 
 	pcm_file = file->private_data;
@@ -2741,11 +2796,12 @@
 	return result;
 }
 
-static ssize_t snd_pcm_write(struct file *file, const char __user *buf, size_t count, loff_t * offset)
+static ssize_t snd_pcm_write(struct file *file, const char __user *buf,
+			     size_t count, loff_t * offset)
 {
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_file *pcm_file;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	snd_pcm_sframes_t result;
 
 	pcm_file = file->private_data;
@@ -2772,9 +2828,9 @@
 			     unsigned long count, loff_t * offset)
 
 {
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_file *pcm_file;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	snd_pcm_sframes_t result;
 	unsigned long i;
 	void __user **bufs;
@@ -2806,9 +2862,9 @@
 static ssize_t snd_pcm_writev(struct file *file, const struct iovec *_vector,
 			      unsigned long count, loff_t * offset)
 {
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_file *pcm_file;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	snd_pcm_sframes_t result;
 	unsigned long i;
 	void __user **bufs;
@@ -2843,9 +2899,9 @@
 
 static unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
 {
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_file *pcm_file;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
         unsigned int mask;
 	snd_pcm_uframes_t avail;
 
@@ -2881,9 +2937,9 @@
 
 static unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
 {
-	snd_pcm_file_t *pcm_file;
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_file *pcm_file;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
         unsigned int mask;
 	snd_pcm_uframes_t avail;
 
@@ -2933,10 +2989,11 @@
 /*
  * mmap status record
  */
-static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, unsigned long address, int *type)
+static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area,
+						unsigned long address, int *type)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream = area->vm_private_data;
+	struct snd_pcm_runtime *runtime;
 	struct page * page;
 	
 	if (substream == NULL)
@@ -2954,17 +3011,17 @@
 	.nopage =	snd_pcm_mmap_status_nopage,
 };
 
-static int snd_pcm_mmap_status(snd_pcm_substream_t *substream, struct file *file,
+static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
 			       struct vm_area_struct *area)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	long size;
 	if (!(area->vm_flags & VM_READ))
 		return -EINVAL;
 	runtime = substream->runtime;
 	snd_assert(runtime != NULL, return -EAGAIN);
 	size = area->vm_end - area->vm_start;
-	if (size != PAGE_ALIGN(sizeof(snd_pcm_mmap_status_t)))
+	if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)))
 		return -EINVAL;
 	area->vm_ops = &snd_pcm_vm_ops_status;
 	area->vm_private_data = substream;
@@ -2975,10 +3032,11 @@
 /*
  * mmap control record
  */
-static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, unsigned long address, int *type)
+static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area,
+						 unsigned long address, int *type)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream = area->vm_private_data;
+	struct snd_pcm_runtime *runtime;
 	struct page * page;
 	
 	if (substream == NULL)
@@ -2996,17 +3054,17 @@
 	.nopage =	snd_pcm_mmap_control_nopage,
 };
 
-static int snd_pcm_mmap_control(snd_pcm_substream_t *substream, struct file *file,
+static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
 				struct vm_area_struct *area)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	long size;
 	if (!(area->vm_flags & VM_READ))
 		return -EINVAL;
 	runtime = substream->runtime;
 	snd_assert(runtime != NULL, return -EAGAIN);
 	size = area->vm_end - area->vm_start;
-	if (size != PAGE_ALIGN(sizeof(snd_pcm_mmap_control_t)))
+	if (size != PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)))
 		return -EINVAL;
 	area->vm_ops = &snd_pcm_vm_ops_control;
 	area->vm_private_data = substream;
@@ -3017,12 +3075,12 @@
 /*
  * don't support mmap for status and control records.
  */
-static int snd_pcm_mmap_status(snd_pcm_substream_t *substream, struct file *file,
+static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
 			       struct vm_area_struct *area)
 {
 	return -ENXIO;
 }
-static int snd_pcm_mmap_control(snd_pcm_substream_t *substream, struct file *file,
+static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
 				struct vm_area_struct *area)
 {
 	return -ENXIO;
@@ -3032,10 +3090,11 @@
 /*
  * nopage callback for mmapping a RAM page
  */
-static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsigned long address, int *type)
+static struct page *snd_pcm_mmap_data_nopage(struct vm_area_struct *area,
+					     unsigned long address, int *type)
 {
-	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream = area->vm_private_data;
+	struct snd_pcm_runtime *runtime;
 	unsigned long offset;
 	struct page * page;
 	void *vaddr;
@@ -3074,7 +3133,8 @@
 /*
  * mmap the DMA buffer on RAM
  */
-static int snd_pcm_default_mmap(snd_pcm_substream_t *substream, struct vm_area_struct *area)
+static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
+				struct vm_area_struct *area)
 {
 	area->vm_ops = &snd_pcm_vm_ops_data;
 	area->vm_private_data = substream;
@@ -3093,7 +3153,8 @@
 	.close =	snd_pcm_mmap_data_close,
 };
 
-int snd_pcm_lib_mmap_iomem(snd_pcm_substream_t *substream, struct vm_area_struct *area)
+int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
+			   struct vm_area_struct *area)
 {
 	long size;
 	unsigned long offset;
@@ -3118,10 +3179,10 @@
 /*
  * mmap DMA buffer
  */
-int snd_pcm_mmap_data(snd_pcm_substream_t *substream, struct file *file,
+int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
 		      struct vm_area_struct *area)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	long size;
 	unsigned long offset;
 	size_t dma_bytes;
@@ -3158,8 +3219,8 @@
 
 static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
 {
-	snd_pcm_file_t * pcm_file;
-	snd_pcm_substream_t *substream;	
+	struct snd_pcm_file * pcm_file;
+	struct snd_pcm_substream *substream;	
 	unsigned long offset;
 	
 	pcm_file = file->private_data;
@@ -3184,9 +3245,9 @@
 
 static int snd_pcm_fasync(int fd, struct file * file, int on)
 {
-	snd_pcm_file_t * pcm_file;
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_file * pcm_file;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	int err;
 
 	pcm_file = file->private_data;
@@ -3213,10 +3274,12 @@
  *  To be removed helpers to keep binary compatibility
  */
 
+#ifdef CONFIG_SND_SUPPORT_OLD_API
 #define __OLD_TO_NEW_MASK(x) ((x&7)|((x&0x07fffff8)<<5))
 #define __NEW_TO_OLD_MASK(x) ((x&7)|((x&0xffffff00)>>5))
 
-static void snd_pcm_hw_convert_from_old_params(snd_pcm_hw_params_t *params, struct sndrv_pcm_hw_params_old *oparams)
+static void snd_pcm_hw_convert_from_old_params(struct snd_pcm_hw_params *params,
+					       struct snd_pcm_hw_params_old *oparams)
 {
 	unsigned int i;
 
@@ -3234,7 +3297,8 @@
 	params->fifo_size = oparams->fifo_size;
 }
 
-static void snd_pcm_hw_convert_to_old_params(struct sndrv_pcm_hw_params_old *oparams, snd_pcm_hw_params_t *params)
+static void snd_pcm_hw_convert_to_old_params(struct snd_pcm_hw_params_old *oparams,
+					     struct snd_pcm_hw_params *params)
 {
 	unsigned int i;
 
@@ -3252,10 +3316,11 @@
 	oparams->fifo_size = params->fifo_size;
 }
 
-static int snd_pcm_hw_refine_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams)
+static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params_old __user * _oparams)
 {
-	snd_pcm_hw_params_t *params;
-	struct sndrv_pcm_hw_params_old *oparams = NULL;
+	struct snd_pcm_hw_params *params;
+	struct snd_pcm_hw_params_old *oparams = NULL;
 	int err;
 
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
@@ -3286,10 +3351,11 @@
 	return err;
 }
 
-static int snd_pcm_hw_params_old_user(snd_pcm_substream_t * substream, struct sndrv_pcm_hw_params_old __user * _oparams)
+static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params_old __user * _oparams)
 {
-	snd_pcm_hw_params_t *params;
-	struct sndrv_pcm_hw_params_old *oparams = NULL;
+	struct snd_pcm_hw_params *params;
+	struct snd_pcm_hw_params_old *oparams = NULL;
 	int err;
 
 	params = kmalloc(sizeof(*params), GFP_KERNEL);
@@ -3318,45 +3384,35 @@
 	kfree(oparams);
 	return err;
 }
+#endif /* CONFIG_SND_SUPPORT_OLD_API */
 
 /*
  *  Register section
  */
 
-static struct file_operations snd_pcm_f_ops_playback = {
-	.owner =	THIS_MODULE,
-	.write =	snd_pcm_write,
-	.writev =	snd_pcm_writev,
-	.open =		snd_pcm_open,
-	.release =	snd_pcm_release,
-	.poll =		snd_pcm_playback_poll,
-	.unlocked_ioctl =	snd_pcm_playback_ioctl,
-	.compat_ioctl = snd_pcm_ioctl_compat,
-	.mmap =		snd_pcm_mmap,
-	.fasync =	snd_pcm_fasync,
-};
-
-static struct file_operations snd_pcm_f_ops_capture = {
-	.owner =	THIS_MODULE,
-	.read =		snd_pcm_read,
-	.readv =	snd_pcm_readv,
-	.open =		snd_pcm_open,
-	.release =	snd_pcm_release,
-	.poll =		snd_pcm_capture_poll,
-	.unlocked_ioctl =	snd_pcm_capture_ioctl,
-	.compat_ioctl = snd_pcm_ioctl_compat,
-	.mmap =		snd_pcm_mmap,
-	.fasync =	snd_pcm_fasync,
-};
-
-snd_minor_t snd_pcm_reg[2] =
-{
+struct file_operations snd_pcm_f_ops[2] = {
 	{
-		.comment =	"digital audio playback",
-		.f_ops =	&snd_pcm_f_ops_playback,
+		.owner =		THIS_MODULE,
+		.write =		snd_pcm_write,
+		.writev =		snd_pcm_writev,
+		.open =			snd_pcm_playback_open,
+		.release =		snd_pcm_release,
+		.poll =			snd_pcm_playback_poll,
+		.unlocked_ioctl =	snd_pcm_playback_ioctl,
+		.compat_ioctl = 	snd_pcm_ioctl_compat,
+		.mmap =			snd_pcm_mmap,
+		.fasync =		snd_pcm_fasync,
 	},
 	{
-		.comment =	"digital audio capture",
-		.f_ops =	&snd_pcm_f_ops_capture,
+		.owner =		THIS_MODULE,
+		.read =			snd_pcm_read,
+		.readv =		snd_pcm_readv,
+		.open =			snd_pcm_capture_open,
+		.release =		snd_pcm_release,
+		.poll =			snd_pcm_capture_poll,
+		.unlocked_ioctl =	snd_pcm_capture_ioctl,
+		.compat_ioctl = 	snd_pcm_ioctl_compat,
+		.mmap =			snd_pcm_mmap,
+		.fasync =		snd_pcm_fasync,
 	}
 };
diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index 884eaea..d94ed16 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -45,10 +45,10 @@
 	return b;
 }
 
-void snd_pcm_timer_resolution_change(snd_pcm_substream_t *substream)
+void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream)
 {
 	unsigned long rate, mult, fsize, l, post;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	
         mult = 1000000000;
 	rate = runtime->rate;
@@ -74,18 +74,18 @@
 	runtime->timer_resolution = (mult * fsize / rate) * post;
 }
 
-static unsigned long snd_pcm_timer_resolution(snd_timer_t * timer)
+static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer)
 {
-	snd_pcm_substream_t * substream;
+	struct snd_pcm_substream *substream;
 	
 	substream = timer->private_data;
 	return substream->runtime ? substream->runtime->timer_resolution : 0;
 }
 
-static int snd_pcm_timer_start(snd_timer_t * timer)
+static int snd_pcm_timer_start(struct snd_timer * timer)
 {
 	unsigned long flags;
-	snd_pcm_substream_t * substream;
+	struct snd_pcm_substream *substream;
 	
 	substream = snd_timer_chip(timer);
 	spin_lock_irqsave(&substream->timer_lock, flags);
@@ -94,10 +94,10 @@
 	return 0;
 }
 
-static int snd_pcm_timer_stop(snd_timer_t * timer)
+static int snd_pcm_timer_stop(struct snd_timer * timer)
 {
 	unsigned long flags;
-	snd_pcm_substream_t * substream;
+	struct snd_pcm_substream *substream;
 	
 	substream = snd_timer_chip(timer);
 	spin_lock_irqsave(&substream->timer_lock, flags);
@@ -106,7 +106,7 @@
 	return 0;
 }
 
-static struct _snd_timer_hardware snd_pcm_timer =
+static struct snd_timer_hardware snd_pcm_timer =
 {
 	.flags =	SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_SLAVE,
 	.resolution =	0,
@@ -120,16 +120,16 @@
  *  Init functions
  */
 
-static void snd_pcm_timer_free(snd_timer_t *timer)
+static void snd_pcm_timer_free(struct snd_timer *timer)
 {
-	snd_pcm_substream_t *substream = timer->private_data;
+	struct snd_pcm_substream *substream = timer->private_data;
 	substream->timer = NULL;
 }
 
-void snd_pcm_timer_init(snd_pcm_substream_t *substream)
+void snd_pcm_timer_init(struct snd_pcm_substream *substream)
 {
-	snd_timer_id_t tid;
-	snd_timer_t *timer;
+	struct snd_timer_id tid;
+	struct snd_timer *timer;
 	
 	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
 	tid.dev_class = SNDRV_TIMER_CLASS_PCM;
@@ -152,7 +152,7 @@
 	substream->timer = timer;
 }
 
-void snd_pcm_timer_done(snd_pcm_substream_t *substream)
+void snd_pcm_timer_done(struct snd_pcm_substream *substream)
 {
 	if (substream->timer) {
 		snd_device_free(substream->pcm->card, substream->timer);
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index d033e61..d4d124e 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -50,16 +50,28 @@
 MODULE_PARM_DESC(amidi_map, "Raw MIDI device number assigned to 2nd OSS device.");
 #endif /* CONFIG_SND_OSSEMUL */
 
-static int snd_rawmidi_free(snd_rawmidi_t *rawmidi);
-static int snd_rawmidi_dev_free(snd_device_t *device);
-static int snd_rawmidi_dev_register(snd_device_t *device);
-static int snd_rawmidi_dev_disconnect(snd_device_t *device);
-static int snd_rawmidi_dev_unregister(snd_device_t *device);
+static int snd_rawmidi_free(struct snd_rawmidi *rawmidi);
+static int snd_rawmidi_dev_free(struct snd_device *device);
+static int snd_rawmidi_dev_register(struct snd_device *device);
+static int snd_rawmidi_dev_disconnect(struct snd_device *device);
+static int snd_rawmidi_dev_unregister(struct snd_device *device);
 
-static snd_rawmidi_t *snd_rawmidi_devices[SNDRV_CARDS * SNDRV_RAWMIDI_DEVICES];
-
+static LIST_HEAD(snd_rawmidi_devices);
 static DECLARE_MUTEX(register_mutex);
 
+static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device)
+{
+	struct list_head *p;
+	struct snd_rawmidi *rawmidi;
+
+	list_for_each(p, &snd_rawmidi_devices) {
+		rawmidi = list_entry(p, struct snd_rawmidi, list);
+		if (rawmidi->card == card && rawmidi->device == device)
+			return rawmidi;
+	}
+	return NULL;
+}
+
 static inline unsigned short snd_rawmidi_file_flags(struct file *file)
 {
 	switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
@@ -72,34 +84,35 @@
 	}
 }
 
-static inline int snd_rawmidi_ready(snd_rawmidi_substream_t * substream)
+static inline int snd_rawmidi_ready(struct snd_rawmidi_substream *substream)
 {
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 	return runtime->avail >= runtime->avail_min;
 }
 
-static inline int snd_rawmidi_ready_append(snd_rawmidi_substream_t * substream, size_t count)
+static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substream,
+					   size_t count)
 {
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 	return runtime->avail >= runtime->avail_min &&
 	       (!substream->append || runtime->avail >= count);
 }
 
 static void snd_rawmidi_input_event_tasklet(unsigned long data)
 {
-	snd_rawmidi_substream_t *substream = (snd_rawmidi_substream_t *)data;
+	struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
 	substream->runtime->event(substream);
 }
 
 static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
 {
-	snd_rawmidi_substream_t *substream = (snd_rawmidi_substream_t *)data;
+	struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
 	substream->ops->trigger(substream, 1);
 }
 
-static int snd_rawmidi_runtime_create(snd_rawmidi_substream_t * substream)
+static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
 {
-	snd_rawmidi_runtime_t *runtime;
+	struct snd_rawmidi_runtime *runtime;
 
 	if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
@@ -129,9 +142,9 @@
 	return 0;
 }
 
-static int snd_rawmidi_runtime_free(snd_rawmidi_substream_t * substream)
+static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream)
 {
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	kfree(runtime->buffer);
 	kfree(runtime);
@@ -139,7 +152,7 @@
 	return 0;
 }
 
-static inline void snd_rawmidi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,int up)
 {
 	if (up) {
 		tasklet_hi_schedule(&substream->runtime->tasklet);
@@ -149,17 +162,17 @@
 	}
 }
 
-static void snd_rawmidi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	substream->ops->trigger(substream, up);
 	if (!up && substream->runtime->event)
 		tasklet_kill(&substream->runtime->tasklet);
 }
 
-int snd_rawmidi_drop_output(snd_rawmidi_substream_t * substream)
+int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	snd_rawmidi_output_trigger(substream, 0);
 	runtime->drain = 0;
@@ -170,11 +183,11 @@
 	return 0;
 }
 
-int snd_rawmidi_drain_output(snd_rawmidi_substream_t * substream)
+int snd_rawmidi_drain_output(struct snd_rawmidi_substream *substream)
 {
 	int err;
 	long timeout;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	err = 0;
 	runtime->drain = 1;
@@ -199,10 +212,10 @@
 	return err;
 }
 
-int snd_rawmidi_drain_input(snd_rawmidi_substream_t * substream)
+int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	snd_rawmidi_input_trigger(substream, 0);
 	runtime->drain = 0;
@@ -213,18 +226,20 @@
 	return 0;
 }
 
-int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice,
-			    int mode, snd_rawmidi_file_t * rfile)
+int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
+			    int mode, struct snd_rawmidi_file * rfile)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	struct list_head *list1, *list2;
-	snd_rawmidi_substream_t *sinput = NULL, *soutput = NULL;
-	snd_rawmidi_runtime_t *input = NULL, *output = NULL;
+	struct snd_rawmidi_substream *sinput = NULL, *soutput = NULL;
+	struct snd_rawmidi_runtime *input = NULL, *output = NULL;
 	int err;
 
 	if (rfile)
 		rfile->input = rfile->output = NULL;
-	rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
+	down(&register_mutex);
+	rmidi = snd_rawmidi_search(card, device);
+	up(&register_mutex);
 	if (rmidi == NULL) {
 		err = -ENODEV;
 		goto __error1;
@@ -275,7 +290,7 @@
 			}
 			break;
 		}
-		sinput = list_entry(list1, snd_rawmidi_substream_t, list);
+		sinput = list_entry(list1, struct snd_rawmidi_substream, list);
 		if ((mode & SNDRV_RAWMIDI_LFLG_INPUT) && sinput->opened)
 			goto __nexti;
 		if (subdevice < 0 || (subdevice >= 0 && subdevice == sinput->number))
@@ -293,7 +308,7 @@
 			}
 			break;
 		}
-		soutput = list_entry(list2, snd_rawmidi_substream_t, list);
+		soutput = list_entry(list2, struct snd_rawmidi_substream, list);
 		if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
 			if (mode & SNDRV_RAWMIDI_LFLG_APPEND) {
 				if (soutput->opened && !soutput->append)
@@ -367,39 +382,29 @@
 static int snd_rawmidi_open(struct inode *inode, struct file *file)
 {
 	int maj = imajor(inode);
-	int cardnum;
-	snd_card_t *card;
-	int device, subdevice;
+	struct snd_card *card;
+	int subdevice;
 	unsigned short fflags;
 	int err;
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_file_t *rawmidi_file;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_file *rawmidi_file;
 	wait_queue_t wait;
 	struct list_head *list;
-	snd_ctl_file_t *kctl;
+	struct snd_ctl_file *kctl;
 
 	if (maj == snd_major) {
-		cardnum = SNDRV_MINOR_CARD(iminor(inode));
-		cardnum %= SNDRV_CARDS;
-		device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI;
-		device %= SNDRV_MINOR_RAWMIDIS;
+		rmidi = snd_lookup_minor_data(iminor(inode),
+					      SNDRV_DEVICE_TYPE_RAWMIDI);
 #ifdef CONFIG_SND_OSSEMUL
 	} else if (maj == SOUND_MAJOR) {
-		cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
-		cardnum %= SNDRV_CARDS;
-		device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ?
-			midi_map[cardnum] : amidi_map[cardnum];
+		rmidi = snd_lookup_oss_minor_data(iminor(inode),
+						  SNDRV_OSS_DEVICE_TYPE_MIDI);
 #endif
 	} else
 		return -ENXIO;
 
-	rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
 	if (rmidi == NULL)
 		return -ENODEV;
-#ifdef CONFIG_SND_OSSEMUL
-	if (maj == SOUND_MAJOR && !rmidi->ossreg)
-		return -ENXIO;
-#endif
 	if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) 
 		return -EINVAL;		/* invalid combination */
 	card = rmidi->card;
@@ -429,7 +434,8 @@
 			}
 		}
 		up_read(&card->controls_rwsem);
-		err = snd_rawmidi_kernel_open(cardnum, device, subdevice, fflags, rawmidi_file);
+		err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device,
+					      subdevice, fflags, rawmidi_file);
 		if (err >= 0)
 			break;
 		if (err == -EAGAIN) {
@@ -465,11 +471,11 @@
 	return err;
 }
 
-int snd_rawmidi_kernel_release(snd_rawmidi_file_t * rfile)
+int snd_rawmidi_kernel_release(struct snd_rawmidi_file * rfile)
 {
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *substream;
-	snd_rawmidi_runtime_t *runtime;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *substream;
+	struct snd_rawmidi_runtime *runtime;
 
 	snd_assert(rfile != NULL, return -ENXIO);
 	snd_assert(rfile->input != NULL || rfile->output != NULL, return -ENXIO);
@@ -515,8 +521,8 @@
 
 static int snd_rawmidi_release(struct inode *inode, struct file *file)
 {
-	snd_rawmidi_file_t *rfile;
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi_file *rfile;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	rfile = file->private_data;
@@ -528,9 +534,10 @@
 	return err;
 }
 
-int snd_rawmidi_info(snd_rawmidi_substream_t *substream, snd_rawmidi_info_t *info)
+static int snd_rawmidi_info(struct snd_rawmidi_substream *substream,
+			    struct snd_rawmidi_info *info)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	
 	if (substream == NULL)
 		return -ENODEV;
@@ -550,26 +557,30 @@
 	return 0;
 }
 
-static int snd_rawmidi_info_user(snd_rawmidi_substream_t *substream, snd_rawmidi_info_t __user * _info)
+static int snd_rawmidi_info_user(struct snd_rawmidi_substream *substream,
+				 struct snd_rawmidi_info __user * _info)
 {
-	snd_rawmidi_info_t info;
+	struct snd_rawmidi_info info;
 	int err;
 	if ((err = snd_rawmidi_info(substream, &info)) < 0)
 		return err;
-	if (copy_to_user(_info, &info, sizeof(snd_rawmidi_info_t)))
+	if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
 		return -EFAULT;
 	return 0;
 }
 
-int snd_rawmidi_info_select(snd_card_t *card, snd_rawmidi_info_t *info)
+int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info)
 {
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_str_t *pstr;
-	snd_rawmidi_substream_t *substream;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_str *pstr;
+	struct snd_rawmidi_substream *substream;
 	struct list_head *list;
-	if (info->device >= SNDRV_RAWMIDI_DEVICES)
+
+	down(&register_mutex);
+	rmidi = snd_rawmidi_search(card, info->device);
+	up(&register_mutex);
+	if (!rmidi)
 		return -ENXIO;
-	rmidi = snd_rawmidi_devices[card->number * SNDRV_RAWMIDI_DEVICES + info->device];
 	if (info->stream < 0 || info->stream > 1)
 		return -EINVAL;
 	pstr = &rmidi->streams[info->stream];
@@ -578,18 +589,18 @@
 	if (info->subdevice >= pstr->substream_count)
 		return -ENXIO;
 	list_for_each(list, &pstr->substreams) {
-		substream = list_entry(list, snd_rawmidi_substream_t, list);
+		substream = list_entry(list, struct snd_rawmidi_substream, list);
 		if ((unsigned int)substream->number == info->subdevice)
 			return snd_rawmidi_info(substream, info);
 	}
 	return -ENXIO;
 }
 
-static int snd_rawmidi_info_select_user(snd_card_t *card,
-					snd_rawmidi_info_t __user *_info)
+static int snd_rawmidi_info_select_user(struct snd_card *card,
+					struct snd_rawmidi_info __user *_info)
 {
 	int err;
-	snd_rawmidi_info_t info;
+	struct snd_rawmidi_info info;
 	if (get_user(info.device, &_info->device))
 		return -EFAULT;
 	if (get_user(info.stream, &_info->stream))
@@ -598,16 +609,16 @@
 		return -EFAULT;
 	if ((err = snd_rawmidi_info_select(card, &info)) < 0)
 		return err;
-	if (copy_to_user(_info, &info, sizeof(snd_rawmidi_info_t)))
+	if (copy_to_user(_info, &info, sizeof(struct snd_rawmidi_info)))
 		return -EFAULT;
 	return 0;
 }
 
-int snd_rawmidi_output_params(snd_rawmidi_substream_t * substream,
-			      snd_rawmidi_params_t * params)
+int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
+			      struct snd_rawmidi_params * params)
 {
 	char *newbuf;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 	
 	if (substream->append && substream->use_count > 1)
 		return -EBUSY;
@@ -624,17 +635,18 @@
 		kfree(runtime->buffer);
 		runtime->buffer = newbuf;
 		runtime->buffer_size = params->buffer_size;
+		runtime->avail = runtime->buffer_size;
 	}
 	runtime->avail_min = params->avail_min;
 	substream->active_sensing = !params->no_active_sensing;
 	return 0;
 }
 
-int snd_rawmidi_input_params(snd_rawmidi_substream_t * substream,
-			     snd_rawmidi_params_t * params)
+int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
+			     struct snd_rawmidi_params * params)
 {
 	char *newbuf;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	snd_rawmidi_drain_input(substream);
 	if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
@@ -654,10 +666,10 @@
 	return 0;
 }
 
-static int snd_rawmidi_output_status(snd_rawmidi_substream_t * substream,
-				     snd_rawmidi_status_t * status)
+static int snd_rawmidi_output_status(struct snd_rawmidi_substream *substream,
+				     struct snd_rawmidi_status * status)
 {
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	memset(status, 0, sizeof(*status));
 	status->stream = SNDRV_RAWMIDI_STREAM_OUTPUT;
@@ -667,10 +679,10 @@
 	return 0;
 }
 
-static int snd_rawmidi_input_status(snd_rawmidi_substream_t * substream,
-				    snd_rawmidi_status_t * status)
+static int snd_rawmidi_input_status(struct snd_rawmidi_substream *substream,
+				    struct snd_rawmidi_status * status)
 {
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	memset(status, 0, sizeof(*status));
 	status->stream = SNDRV_RAWMIDI_STREAM_INPUT;
@@ -684,7 +696,7 @@
 
 static long snd_rawmidi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	snd_rawmidi_file_t *rfile;
+	struct snd_rawmidi_file *rfile;
 	void __user *argp = (void __user *)arg;
 
 	rfile = file->private_data;
@@ -695,8 +707,8 @@
 		return put_user(SNDRV_RAWMIDI_VERSION, (int __user *)argp) ? -EFAULT : 0;
 	case SNDRV_RAWMIDI_IOCTL_INFO:
 	{
-		snd_rawmidi_stream_t stream;
-		snd_rawmidi_info_t __user *info = argp;
+		int stream;
+		struct snd_rawmidi_info __user *info = argp;
 		if (get_user(stream, &info->stream))
 			return -EFAULT;
 		switch (stream) {
@@ -710,8 +722,8 @@
 	}
 	case SNDRV_RAWMIDI_IOCTL_PARAMS:
 	{
-		snd_rawmidi_params_t params;
-		if (copy_from_user(&params, argp, sizeof(snd_rawmidi_params_t)))
+		struct snd_rawmidi_params params;
+		if (copy_from_user(&params, argp, sizeof(struct snd_rawmidi_params)))
 			return -EFAULT;
 		switch (params.stream) {
 		case SNDRV_RAWMIDI_STREAM_OUTPUT:
@@ -729,8 +741,8 @@
 	case SNDRV_RAWMIDI_IOCTL_STATUS:
 	{
 		int err = 0;
-		snd_rawmidi_status_t status;
-		if (copy_from_user(&status, argp, sizeof(snd_rawmidi_status_t)))
+		struct snd_rawmidi_status status;
+		if (copy_from_user(&status, argp, sizeof(struct snd_rawmidi_status)))
 			return -EFAULT;
 		switch (status.stream) {
 		case SNDRV_RAWMIDI_STREAM_OUTPUT:
@@ -748,7 +760,7 @@
 		}
 		if (err < 0)
 			return err;
-		if (copy_to_user(argp, &status, sizeof(snd_rawmidi_status_t)))
+		if (copy_to_user(argp, &status, sizeof(struct snd_rawmidi_status)))
 			return -EFAULT;
 		return 0;
 	}
@@ -792,15 +804,13 @@
 	return -ENOTTY;
 }
 
-static int snd_rawmidi_control_ioctl(snd_card_t * card,
-				     snd_ctl_file_t * control,
+static int snd_rawmidi_control_ioctl(struct snd_card *card,
+				     struct snd_ctl_file *control,
 				     unsigned int cmd,
 				     unsigned long arg)
 {
 	void __user *argp = (void __user *)arg;
-	unsigned int tmp;
 
-	tmp = card->number * SNDRV_RAWMIDI_DEVICES;
 	switch (cmd) {
 	case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE:
 	{
@@ -808,14 +818,16 @@
 		
 		if (get_user(device, (int __user *)argp))
 			return -EFAULT;
+		down(&register_mutex);
 		device = device < 0 ? 0 : device + 1;
 		while (device < SNDRV_RAWMIDI_DEVICES) {
-			if (snd_rawmidi_devices[tmp + device])
+			if (snd_rawmidi_search(card, device))
 				break;
 			device++;
 		}
 		if (device == SNDRV_RAWMIDI_DEVICES)
 			device = -1;
+		up(&register_mutex);
 		if (put_user(device, (int __user *)argp))
 			return -EFAULT;
 		return 0;
@@ -845,11 +857,12 @@
  *
  * Returns the size of read data, or a negative error code on failure.
  */
-int snd_rawmidi_receive(snd_rawmidi_substream_t * substream, const unsigned char *buffer, int count)
+int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
+			const unsigned char *buffer, int count)
 {
 	unsigned long flags;
 	int result = 0, count1;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	if (runtime->buffer == NULL) {
 		snd_printd("snd_rawmidi_receive: input is not active!!!\n");
@@ -904,12 +917,12 @@
 	return result;
 }
 
-static long snd_rawmidi_kernel_read1(snd_rawmidi_substream_t *substream,
+static long snd_rawmidi_kernel_read1(struct snd_rawmidi_substream *substream,
 				     unsigned char *buf, long count, int kernel)
 {
 	unsigned long flags;
 	long result = 0, count1;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	while (count > 0 && runtime->avail) {
 		count1 = runtime->buffer_size - runtime->appl_ptr;
@@ -938,19 +951,21 @@
 	return result;
 }
 
-long snd_rawmidi_kernel_read(snd_rawmidi_substream_t *substream, unsigned char *buf, long count)
+long snd_rawmidi_kernel_read(struct snd_rawmidi_substream *substream,
+			     unsigned char *buf, long count)
 {
 	snd_rawmidi_input_trigger(substream, 1);
 	return snd_rawmidi_kernel_read1(substream, buf, count, 1);
 }
 
-static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
+static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t count,
+				loff_t *offset)
 {
 	long result;
 	int count1;
-	snd_rawmidi_file_t *rfile;
-	snd_rawmidi_substream_t *substream;
-	snd_rawmidi_runtime_t *runtime;
+	struct snd_rawmidi_file *rfile;
+	struct snd_rawmidi_substream *substream;
+	struct snd_rawmidi_runtime *runtime;
 
 	rfile = file->private_data;
 	substream = rfile->input;
@@ -998,9 +1013,9 @@
  * 
  * Returns 1 if the internal output buffer is empty, 0 if not.
  */
-int snd_rawmidi_transmit_empty(snd_rawmidi_substream_t * substream)
+int snd_rawmidi_transmit_empty(struct snd_rawmidi_substream *substream)
 {
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 	int result;
 	unsigned long flags;
 
@@ -1028,11 +1043,12 @@
  *
  * Returns the size of copied data, or a negative error code on failure.
  */
-int snd_rawmidi_transmit_peek(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count)
+int snd_rawmidi_transmit_peek(struct snd_rawmidi_substream *substream,
+			      unsigned char *buffer, int count)
 {
 	unsigned long flags;
 	int result, count1;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	if (runtime->buffer == NULL) {
 		snd_printd("snd_rawmidi_transmit_peek: output is not active!!!\n");
@@ -1079,10 +1095,10 @@
  *
  * Returns the advanced size if successful, or a negative error code on failure.
  */
-int snd_rawmidi_transmit_ack(snd_rawmidi_substream_t * substream, int count)
+int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
 {
 	unsigned long flags;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	if (runtime->buffer == NULL) {
 		snd_printd("snd_rawmidi_transmit_ack: output is not active!!!\n");
@@ -1112,7 +1128,8 @@
  *
  * Returns the copied size if successful, or a negative error code on failure.
  */
-int snd_rawmidi_transmit(snd_rawmidi_substream_t * substream, unsigned char *buffer, int count)
+int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
+			 unsigned char *buffer, int count)
 {
 	count = snd_rawmidi_transmit_peek(substream, buffer, count);
 	if (count < 0)
@@ -1120,11 +1137,12 @@
 	return snd_rawmidi_transmit_ack(substream, count);
 }
 
-static long snd_rawmidi_kernel_write1(snd_rawmidi_substream_t * substream, const unsigned char *buf, long count, int kernel)
+static long snd_rawmidi_kernel_write1(struct snd_rawmidi_substream *substream,
+				      const unsigned char *buf, long count, int kernel)
 {
 	unsigned long flags;
 	long count1, result;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
 
 	snd_assert(buf != NULL, return -EINVAL);
 	snd_assert(runtime->buffer != NULL, return -EINVAL);
@@ -1170,18 +1188,20 @@
 	return result;
 }
 
-long snd_rawmidi_kernel_write(snd_rawmidi_substream_t * substream, const unsigned char *buf, long count)
+long snd_rawmidi_kernel_write(struct snd_rawmidi_substream *substream,
+			      const unsigned char *buf, long count)
 {
 	return snd_rawmidi_kernel_write1(substream, buf, count, 1);
 }
 
-static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
+static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
+				 size_t count, loff_t *offset)
 {
 	long result, timeout;
 	int count1;
-	snd_rawmidi_file_t *rfile;
-	snd_rawmidi_runtime_t *runtime;
-	snd_rawmidi_substream_t *substream;
+	struct snd_rawmidi_file *rfile;
+	struct snd_rawmidi_runtime *runtime;
+	struct snd_rawmidi_substream *substream;
 
 	rfile = file->private_data;
 	substream = rfile->output;
@@ -1246,8 +1266,8 @@
 
 static unsigned int snd_rawmidi_poll(struct file *file, poll_table * wait)
 {
-	snd_rawmidi_file_t *rfile;
-	snd_rawmidi_runtime_t *runtime;
+	struct snd_rawmidi_file *rfile;
+	struct snd_rawmidi_runtime *runtime;
 	unsigned int mask;
 
 	rfile = file->private_data;
@@ -1284,12 +1304,12 @@
 
  */
 
-static void snd_rawmidi_proc_info_read(snd_info_entry_t *entry,
-				       snd_info_buffer_t * buffer)
+static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
+				       struct snd_info_buffer *buffer)
 {
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *substream;
-	snd_rawmidi_runtime_t *runtime;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *substream;
+	struct snd_rawmidi_runtime *runtime;
 	struct list_head *list;
 
 	rmidi = entry->private_data;
@@ -1297,7 +1317,7 @@
 	down(&rmidi->open_mutex);
 	if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_OUTPUT) {
 		list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
-			substream = list_entry(list, snd_rawmidi_substream_t, list);
+			substream = list_entry(list, struct snd_rawmidi_substream, list);
 			snd_iprintf(buffer,
 				    "Output %d\n"
 				    "  Tx bytes     : %lu\n",
@@ -1317,7 +1337,7 @@
 	}
 	if (rmidi->info_flags & SNDRV_RAWMIDI_INFO_INPUT) {
 		list_for_each(list, &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
-			substream = list_entry(list, snd_rawmidi_substream_t, list);
+			substream = list_entry(list, struct snd_rawmidi_substream, list);
 			snd_iprintf(buffer,
 				    "Input %d\n"
 				    "  Rx bytes     : %lu\n",
@@ -1354,25 +1374,21 @@
 	.compat_ioctl =	snd_rawmidi_ioctl_compat,
 };
 
-static snd_minor_t snd_rawmidi_reg =
-{
-	.comment =	"raw midi",
-	.f_ops =	&snd_rawmidi_f_ops,
-};
-
-static int snd_rawmidi_alloc_substreams(snd_rawmidi_t *rmidi,
-					snd_rawmidi_str_t *stream,
+static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi,
+					struct snd_rawmidi_str *stream,
 					int direction,
 					int count)
 {
-	snd_rawmidi_substream_t *substream;
+	struct snd_rawmidi_substream *substream;
 	int idx;
 
 	INIT_LIST_HEAD(&stream->substreams);
 	for (idx = 0; idx < count; idx++) {
 		substream = kzalloc(sizeof(*substream), GFP_KERNEL);
-		if (substream == NULL)
+		if (substream == NULL) {
+			snd_printk(KERN_ERR "rawmidi: cannot allocate substream\n");
 			return -ENOMEM;
+		}
 		substream->stream = direction;
 		substream->number = idx;
 		substream->rmidi = rmidi;
@@ -1397,13 +1413,13 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_rawmidi_new(snd_card_t * card, char *id, int device,
+int snd_rawmidi_new(struct snd_card *card, char *id, int device,
 		    int output_count, int input_count,
-		    snd_rawmidi_t ** rrawmidi)
+		    struct snd_rawmidi ** rrawmidi)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_rawmidi_dev_free,
 		.dev_register = snd_rawmidi_dev_register,
 		.dev_disconnect = snd_rawmidi_dev_disconnect,
@@ -1414,19 +1430,27 @@
 	*rrawmidi = NULL;
 	snd_assert(card != NULL, return -ENXIO);
 	rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL);
-	if (rmidi == NULL)
+	if (rmidi == NULL) {
+		snd_printk(KERN_ERR "rawmidi: cannot allocate\n");
 		return -ENOMEM;
+	}
 	rmidi->card = card;
 	rmidi->device = device;
 	init_MUTEX(&rmidi->open_mutex);
 	init_waitqueue_head(&rmidi->open_wait);
 	if (id != NULL)
 		strlcpy(rmidi->id, id, sizeof(rmidi->id));
-	if ((err = snd_rawmidi_alloc_substreams(rmidi, &rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT], SNDRV_RAWMIDI_STREAM_INPUT, input_count)) < 0) {
+	if ((err = snd_rawmidi_alloc_substreams(rmidi,
+						&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT],
+						SNDRV_RAWMIDI_STREAM_INPUT,
+						input_count)) < 0) {
 		snd_rawmidi_free(rmidi);
 		return err;
 	}
-	if ((err = snd_rawmidi_alloc_substreams(rmidi, &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT], SNDRV_RAWMIDI_STREAM_OUTPUT, output_count)) < 0) {
+	if ((err = snd_rawmidi_alloc_substreams(rmidi,
+						&rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT],
+						SNDRV_RAWMIDI_STREAM_OUTPUT,
+						output_count)) < 0) {
 		snd_rawmidi_free(rmidi);
 		return err;
 	}
@@ -1438,18 +1462,18 @@
 	return 0;
 }
 
-static void snd_rawmidi_free_substreams(snd_rawmidi_str_t *stream)
+static void snd_rawmidi_free_substreams(struct snd_rawmidi_str *stream)
 {
-	snd_rawmidi_substream_t *substream;
+	struct snd_rawmidi_substream *substream;
 
 	while (!list_empty(&stream->substreams)) {
-		substream = list_entry(stream->substreams.next, snd_rawmidi_substream_t, list);
+		substream = list_entry(stream->substreams.next, struct snd_rawmidi_substream, list);
 		list_del(&substream->list);
 		kfree(substream);
 	}
 }
 
-static int snd_rawmidi_free(snd_rawmidi_t *rmidi)
+static int snd_rawmidi_free(struct snd_rawmidi *rmidi)
 {
 	snd_assert(rmidi != NULL, return -ENXIO);	
 	snd_rawmidi_free_substreams(&rmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT]);
@@ -1460,49 +1484,48 @@
 	return 0;
 }
 
-static int snd_rawmidi_dev_free(snd_device_t *device)
+static int snd_rawmidi_dev_free(struct snd_device *device)
 {
-	snd_rawmidi_t *rmidi = device->device_data;
+	struct snd_rawmidi *rmidi = device->device_data;
 	return snd_rawmidi_free(rmidi);
 }
 
 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
-static void snd_rawmidi_dev_seq_free(snd_seq_device_t *device)
+static void snd_rawmidi_dev_seq_free(struct snd_seq_device *device)
 {
-	snd_rawmidi_t *rmidi = device->private_data;
+	struct snd_rawmidi *rmidi = device->private_data;
 	rmidi->seq_dev = NULL;
 }
 #endif
 
-static int snd_rawmidi_dev_register(snd_device_t *device)
+static int snd_rawmidi_dev_register(struct snd_device *device)
 {
-	int idx, err;
-	snd_info_entry_t *entry;
+	int err;
+	struct snd_info_entry *entry;
 	char name[16];
-	snd_rawmidi_t *rmidi = device->device_data;
+	struct snd_rawmidi *rmidi = device->device_data;
 
 	if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
 		return -ENOMEM;
 	down(&register_mutex);
-	idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device;
-	if (snd_rawmidi_devices[idx] != NULL) {
+	if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
 		up(&register_mutex);
 		return -EBUSY;
 	}
-	snd_rawmidi_devices[idx] = rmidi;
+	list_add_tail(&rmidi->list, &snd_rawmidi_devices);
 	sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device);
 	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
 				       rmidi->card, rmidi->device,
-				       &snd_rawmidi_reg, name)) < 0) {
+				       &snd_rawmidi_f_ops, rmidi, name)) < 0) {
 		snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
-		snd_rawmidi_devices[idx] = NULL;
+		list_del(&rmidi->list);
 		up(&register_mutex);
 		return err;
 	}
 	if (rmidi->ops && rmidi->ops->dev_register &&
 	    (err = rmidi->ops->dev_register(rmidi)) < 0) {
 		snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
-		snd_rawmidi_devices[idx] = NULL;
+		list_del(&rmidi->list);
 		up(&register_mutex);
 		return err;
 	}
@@ -1510,7 +1533,8 @@
 	rmidi->ossreg = 0;
 	if ((int)rmidi->device == midi_map[rmidi->card->number]) {
 		if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
-					    rmidi->card, 0, &snd_rawmidi_reg, name) < 0) {
+					    rmidi->card, 0, &snd_rawmidi_f_ops,
+					    rmidi, name) < 0) {
 			snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0);
 		} else {
 			rmidi->ossreg++;
@@ -1521,7 +1545,8 @@
 	}
 	if ((int)rmidi->device == amidi_map[rmidi->card->number]) {
 		if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
-					    rmidi->card, 1, &snd_rawmidi_reg, name) < 0) {
+					    rmidi->card, 1, &snd_rawmidi_f_ops,
+					    rmidi, name) < 0) {
 			snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1);
 		} else {
 			rmidi->ossreg++;
@@ -1554,27 +1579,23 @@
 	return 0;
 }
 
-static int snd_rawmidi_dev_disconnect(snd_device_t *device)
+static int snd_rawmidi_dev_disconnect(struct snd_device *device)
 {
-	snd_rawmidi_t *rmidi = device->device_data;
-	int idx;
+	struct snd_rawmidi *rmidi = device->device_data;
 
 	down(&register_mutex);
-	idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device;
-	snd_rawmidi_devices[idx] = NULL;
+	list_del_init(&rmidi->list);
 	up(&register_mutex);
 	return 0;
 }
 
-static int snd_rawmidi_dev_unregister(snd_device_t *device)
+static int snd_rawmidi_dev_unregister(struct snd_device *device)
 {
-	int idx;
-	snd_rawmidi_t *rmidi = device->device_data;
+	struct snd_rawmidi *rmidi = device->device_data;
 
 	snd_assert(rmidi != NULL, return -ENXIO);
 	down(&register_mutex);
-	idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device;
-	snd_rawmidi_devices[idx] = NULL;
+	list_del(&rmidi->list);
 	if (rmidi->proc_entry) {
 		snd_info_unregister(rmidi->proc_entry);
 		rmidi->proc_entry = NULL;
@@ -1613,13 +1634,14 @@
  *
  * Sets the rawmidi operators for the given stream direction.
  */
-void snd_rawmidi_set_ops(snd_rawmidi_t *rmidi, int stream, snd_rawmidi_ops_t *ops)
+void snd_rawmidi_set_ops(struct snd_rawmidi *rmidi, int stream,
+			 struct snd_rawmidi_ops *ops)
 {
 	struct list_head *list;
-	snd_rawmidi_substream_t *substream;
+	struct snd_rawmidi_substream *substream;
 	
 	list_for_each(list, &rmidi->streams[stream].substreams) {
-		substream = list_entry(list, snd_rawmidi_substream_t, list);
+		substream = list_entry(list, struct snd_rawmidi_substream, list);
 		substream->ops = ops;
 	}
 }
@@ -1672,7 +1694,6 @@
 EXPORT_SYMBOL(snd_rawmidi_transmit);
 EXPORT_SYMBOL(snd_rawmidi_new);
 EXPORT_SYMBOL(snd_rawmidi_set_ops);
-EXPORT_SYMBOL(snd_rawmidi_info);
 EXPORT_SYMBOL(snd_rawmidi_info_select);
 EXPORT_SYMBOL(snd_rawmidi_kernel_open);
 EXPORT_SYMBOL(snd_rawmidi_kernel_release);
diff --git a/sound/core/rawmidi_compat.c b/sound/core/rawmidi_compat.c
index d97631c..5268c1f 100644
--- a/sound/core/rawmidi_compat.c
+++ b/sound/core/rawmidi_compat.c
@@ -22,7 +22,7 @@
 
 #include <linux/compat.h>
 
-struct sndrv_rawmidi_params32 {
+struct snd_rawmidi_params32 {
 	s32 stream;
 	u32 buffer_size;
 	u32 avail_min;
@@ -30,10 +30,10 @@
 	unsigned char reserved[16];
 } __attribute__((packed));
 
-static int snd_rawmidi_ioctl_params_compat(snd_rawmidi_file_t *rfile,
-					   struct sndrv_rawmidi_params32 __user *src)
+static int snd_rawmidi_ioctl_params_compat(struct snd_rawmidi_file *rfile,
+					   struct snd_rawmidi_params32 __user *src)
 {
-	snd_rawmidi_params_t params;
+	struct snd_rawmidi_params params;
 	unsigned int val;
 
 	if (rfile->output == NULL)
@@ -53,7 +53,7 @@
 	return -EINVAL;
 }
 
-struct sndrv_rawmidi_status32 {
+struct snd_rawmidi_status32 {
 	s32 stream;
 	struct compat_timespec tstamp;
 	u32 avail;
@@ -61,11 +61,11 @@
 	unsigned char reserved[16];
 } __attribute__((packed));
 
-static int snd_rawmidi_ioctl_status_compat(snd_rawmidi_file_t *rfile,
-					   struct sndrv_rawmidi_status32 __user *src)
+static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
+					   struct snd_rawmidi_status32 __user *src)
 {
 	int err;
-	snd_rawmidi_status_t status;
+	struct snd_rawmidi_status status;
 
 	if (rfile->output == NULL)
 		return -EINVAL;
@@ -95,13 +95,13 @@
 }
 
 enum {
-	SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct sndrv_rawmidi_params32),
-	SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct sndrv_rawmidi_status32),
+	SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32),
+	SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32),
 };
 
 static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	snd_rawmidi_file_t *rfile;
+	struct snd_rawmidi_file *rfile;
 	void __user *argp = compat_ptr(arg);
 
 	rfile = file->private_data;
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index c3c1856..84704cc 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -40,16 +40,16 @@
 /*
  * prototypes
  */
-static int rtctimer_open(snd_timer_t *t);
-static int rtctimer_close(snd_timer_t *t);
-static int rtctimer_start(snd_timer_t *t);
-static int rtctimer_stop(snd_timer_t *t);
+static int rtctimer_open(struct snd_timer *t);
+static int rtctimer_close(struct snd_timer *t);
+static int rtctimer_start(struct snd_timer *t);
+static int rtctimer_stop(struct snd_timer *t);
 
 
 /*
  * The hardware dependent description for this timer.
  */
-static struct _snd_timer_hardware rtc_hw = {
+static struct snd_timer_hardware rtc_hw = {
 	.flags =	SNDRV_TIMER_HW_FIRST|SNDRV_TIMER_HW_AUTO,
 	.ticks =	100000000L,		/* FIXME: XXX */
 	.open =		rtctimer_open,
@@ -59,12 +59,12 @@
 };
 
 static int rtctimer_freq = RTC_FREQ;		/* frequency */
-static snd_timer_t *rtctimer;
+static struct snd_timer *rtctimer;
 static rtc_task_t rtc_task;
 
 
 static int
-rtctimer_open(snd_timer_t *t)
+rtctimer_open(struct snd_timer *t)
 {
 	int err;
 
@@ -76,7 +76,7 @@
 }
 
 static int
-rtctimer_close(snd_timer_t *t)
+rtctimer_close(struct snd_timer *t)
 {
 	rtc_task_t *rtc = t->private_data;
 	if (rtc) {
@@ -87,7 +87,7 @@
 }
 
 static int
-rtctimer_start(snd_timer_t *timer)
+rtctimer_start(struct snd_timer *timer)
 {
 	rtc_task_t *rtc = timer->private_data;
 	snd_assert(rtc != NULL, return -EINVAL);
@@ -97,7 +97,7 @@
 }
 
 static int
-rtctimer_stop(snd_timer_t *timer)
+rtctimer_stop(struct snd_timer *timer)
 {
 	rtc_task_t *rtc = timer->private_data;
 	snd_assert(rtc != NULL, return -EINVAL);
@@ -120,7 +120,7 @@
 static int __init rtctimer_init(void)
 {
 	int err;
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 
 	if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
 	    (rtctimer_freq & (rtctimer_freq - 1)) != 0) {
diff --git a/sound/core/seq/instr/ainstr_fm.c b/sound/core/seq/instr/ainstr_fm.c
index 5c671e6..b09babf 100644
--- a/sound/core/seq/instr/ainstr_fm.c
+++ b/sound/core/seq/instr/ainstr_fm.c
@@ -30,11 +30,11 @@
 MODULE_DESCRIPTION("Advanced Linux Sound Architecture FM Instrument support.");
 MODULE_LICENSE("GPL");
 
-static int snd_seq_fm_put(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_fm_put(void *private_data, struct snd_seq_kinstr *instr,
 			  char __user *instr_data, long len, int atomic, int cmd)
 {
-	fm_instrument_t *ip;
-	fm_xinstrument_t ix;
+	struct fm_instrument *ip;
+	struct fm_xinstrument ix;
 	int idx;
 
 	if (cmd != SNDRV_SEQ_INSTR_PUT_CMD_CREATE)
@@ -46,7 +46,7 @@
 		return -EFAULT;
 	if (ix.stype != FM_STRU_INSTR)
 		return -EINVAL;
-	ip = (fm_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct fm_instrument *)KINSTR_DATA(instr);
 	ip->share_id[0] = le32_to_cpu(ix.share_id[0]);
 	ip->share_id[1] = le32_to_cpu(ix.share_id[1]);
 	ip->share_id[2] = le32_to_cpu(ix.share_id[2]);
@@ -72,12 +72,12 @@
 	return 0;
 }
 
-static int snd_seq_fm_get(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_fm_get(void *private_data, struct snd_seq_kinstr *instr,
 			  char __user *instr_data, long len, int atomic,
 			  int cmd)
 {
-	fm_instrument_t *ip;
-	fm_xinstrument_t ix;
+	struct fm_instrument *ip;
+	struct fm_xinstrument ix;
 	int idx;
 	
 	if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
@@ -85,7 +85,7 @@
 	if (len < (long)sizeof(ix))
 		return -ENOMEM;
 	memset(&ix, 0, sizeof(ix));
-	ip = (fm_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct fm_instrument *)KINSTR_DATA(instr);
 	ix.stype = FM_STRU_INSTR;
 	ix.share_id[0] = cpu_to_le32(ip->share_id[0]);
 	ix.share_id[1] = cpu_to_le32(ip->share_id[1]);
@@ -114,19 +114,19 @@
 	return 0;
 }
 
-static int snd_seq_fm_get_size(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_fm_get_size(void *private_data, struct snd_seq_kinstr *instr,
 			       long *size)
 {
-	*size = sizeof(fm_xinstrument_t);
+	*size = sizeof(struct fm_xinstrument);
 	return 0;
 }
 
-int snd_seq_fm_init(snd_seq_kinstr_ops_t *ops,
-		    snd_seq_kinstr_ops_t *next)
+int snd_seq_fm_init(struct snd_seq_kinstr_ops *ops,
+		    struct snd_seq_kinstr_ops *next)
 {
 	memset(ops, 0, sizeof(*ops));
 	// ops->private_data = private_data;
-	ops->add_len = sizeof(fm_instrument_t);
+	ops->add_len = sizeof(struct fm_instrument);
 	ops->instr_type = SNDRV_SEQ_INSTR_ID_OPL2_3;
 	ops->put = snd_seq_fm_put;
 	ops->get = snd_seq_fm_get;
diff --git a/sound/core/seq/instr/ainstr_gf1.c b/sound/core/seq/instr/ainstr_gf1.c
index 0e4df88..3c31038 100644
--- a/sound/core/seq/instr/ainstr_gf1.c
+++ b/sound/core/seq/instr/ainstr_gf1.c
@@ -42,14 +42,14 @@
 	return format;
 }
 
-static int snd_seq_gf1_copy_wave_from_stream(snd_gf1_ops_t *ops,
-					     gf1_instrument_t *ip,
+static int snd_seq_gf1_copy_wave_from_stream(struct snd_gf1_ops *ops,
+					     struct gf1_instrument *ip,
 					     char __user **data,
 					     long *len,
 					     int atomic)
 {
-	gf1_wave_t *wp, *prev;
-	gf1_xwave_t xp;
+	struct gf1_wave *wp, *prev;
+	struct gf1_xwave xp;
 	int err;
 	gfp_t gfp_mask;
 	unsigned int real_size;
@@ -116,8 +116,8 @@
 	return 0;
 }
 
-static void snd_seq_gf1_wave_free(snd_gf1_ops_t *ops,
-				  gf1_wave_t *wave,
+static void snd_seq_gf1_wave_free(struct snd_gf1_ops *ops,
+				  struct gf1_wave *wave,
 				  int atomic)
 {
 	if (ops->remove_sample)
@@ -125,11 +125,11 @@
 	kfree(wave);
 }
 
-static void snd_seq_gf1_instr_free(snd_gf1_ops_t *ops,
-				   gf1_instrument_t *ip,
+static void snd_seq_gf1_instr_free(struct snd_gf1_ops *ops,
+				   struct gf1_instrument *ip,
 				   int atomic)
 {
-	gf1_wave_t *wave;
+	struct gf1_wave *wave;
 	
 	while ((wave = ip->wave) != NULL) {
 		ip->wave = wave->next;
@@ -137,13 +137,13 @@
 	}
 }
 
-static int snd_seq_gf1_put(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_gf1_put(void *private_data, struct snd_seq_kinstr *instr,
 			   char __user *instr_data, long len, int atomic,
 			   int cmd)
 {
-	snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
-	gf1_instrument_t *ip;
-	gf1_xinstrument_t ix;
+	struct snd_gf1_ops *ops = private_data;
+	struct gf1_instrument *ip;
+	struct gf1_xinstrument ix;
 	int err;
 	gfp_t gfp_mask;
 
@@ -159,7 +159,7 @@
 		return -EINVAL;
 	instr_data += sizeof(ix);
 	len -= sizeof(ix);
-	ip = (gf1_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct gf1_instrument *)KINSTR_DATA(instr);
 	ip->exclusion = le16_to_cpu(ix.exclusion);
 	ip->exclusion_group = le16_to_cpu(ix.exclusion_group);
 	ip->effect1 = ix.effect1;
@@ -189,14 +189,14 @@
 	return 0;
 }
 
-static int snd_seq_gf1_copy_wave_to_stream(snd_gf1_ops_t *ops,
-					   gf1_instrument_t *ip,
+static int snd_seq_gf1_copy_wave_to_stream(struct snd_gf1_ops *ops,
+					   struct gf1_instrument *ip,
 					   char __user **data,
 					   long *len,
 					   int atomic)
 {
-	gf1_wave_t *wp;
-	gf1_xwave_t xp;
+	struct gf1_wave *wp;
+	struct gf1_xwave xp;
 	int err;
 	unsigned int real_size;
 	
@@ -251,20 +251,20 @@
 	return 0;
 }
 
-static int snd_seq_gf1_get(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_gf1_get(void *private_data, struct snd_seq_kinstr *instr,
 			   char __user *instr_data, long len, int atomic,
 			   int cmd)
 {
-	snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
-	gf1_instrument_t *ip;
-	gf1_xinstrument_t ix;
+	struct snd_gf1_ops *ops = private_data;
+	struct gf1_instrument *ip;
+	struct gf1_xinstrument ix;
 	
 	if (cmd != SNDRV_SEQ_INSTR_GET_CMD_FULL)
 		return -EINVAL;
 	if (len < (long)sizeof(ix))
 		return -ENOMEM;
 	memset(&ix, 0, sizeof(ix));
-	ip = (gf1_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct gf1_instrument *)KINSTR_DATA(instr);
 	ix.stype = GF1_STRU_INSTR;
 	ix.exclusion = cpu_to_le16(ip->exclusion);
 	ix.exclusion_group = cpu_to_le16(ip->exclusion_group);
@@ -283,18 +283,18 @@
 					       atomic);
 }
 
-static int snd_seq_gf1_get_size(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_gf1_get_size(void *private_data, struct snd_seq_kinstr *instr,
 				long *size)
 {
 	long result;
-	gf1_instrument_t *ip;
-	gf1_wave_t *wp;
+	struct gf1_instrument *ip;
+	struct gf1_wave *wp;
 
 	*size = 0;
-	ip = (gf1_instrument_t *)KINSTR_DATA(instr);
-	result = sizeof(gf1_xinstrument_t);
+	ip = (struct gf1_instrument *)KINSTR_DATA(instr);
+	result = sizeof(struct gf1_xinstrument);
 	for (wp = ip->wave; wp; wp = wp->next) {
-		result += sizeof(gf1_xwave_t);
+		result += sizeof(struct gf1_xwave);
 		result += wp->size;
 	}
 	*size = result;
@@ -302,35 +302,35 @@
 }
 
 static int snd_seq_gf1_remove(void *private_data,
-			      snd_seq_kinstr_t *instr,
+			      struct snd_seq_kinstr *instr,
                               int atomic)
 {
-	snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
-	gf1_instrument_t *ip;
+	struct snd_gf1_ops *ops = private_data;
+	struct gf1_instrument *ip;
 
-	ip = (gf1_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct gf1_instrument *)KINSTR_DATA(instr);
 	snd_seq_gf1_instr_free(ops, ip, atomic);
 	return 0;
 }
 
 static void snd_seq_gf1_notify(void *private_data,
-			       snd_seq_kinstr_t *instr,
+			       struct snd_seq_kinstr *instr,
 			       int what)
 {
-	snd_gf1_ops_t *ops = (snd_gf1_ops_t *)private_data;
+	struct snd_gf1_ops *ops = private_data;
 
 	if (ops->notify)
 		ops->notify(ops->private_data, instr, what);
 }
 
-int snd_seq_gf1_init(snd_gf1_ops_t *ops,
+int snd_seq_gf1_init(struct snd_gf1_ops *ops,
 		     void *private_data,
-		     snd_seq_kinstr_ops_t *next)
+		     struct snd_seq_kinstr_ops *next)
 {
 	memset(ops, 0, sizeof(*ops));
 	ops->private_data = private_data;
 	ops->kops.private_data = ops;
-	ops->kops.add_len = sizeof(gf1_instrument_t);
+	ops->kops.add_len = sizeof(struct gf1_instrument);
 	ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_GUS_PATCH;
 	ops->kops.put = snd_seq_gf1_put;
 	ops->kops.get = snd_seq_gf1_get;
diff --git a/sound/core/seq/instr/ainstr_iw.c b/sound/core/seq/instr/ainstr_iw.c
index 7c19fbb..7f8df19 100644
--- a/sound/core/seq/instr/ainstr_iw.c
+++ b/sound/core/seq/instr/ainstr_iw.c
@@ -42,8 +42,8 @@
 	return result;
 }
 
-static void snd_seq_iwffff_copy_lfo_from_stream(iwffff_lfo_t *fp,
-						iwffff_xlfo_t *fx)
+static void snd_seq_iwffff_copy_lfo_from_stream(struct iwffff_lfo *fp,
+						struct iwffff_xlfo *fx)
 {
 	fp->freq = le16_to_cpu(fx->freq);
 	fp->depth = le16_to_cpu(fx->depth);
@@ -53,18 +53,18 @@
 }
 
 static int snd_seq_iwffff_copy_env_from_stream(__u32 req_stype,
-					       iwffff_layer_t *lp,
-					       iwffff_env_t *ep,
-					       iwffff_xenv_t *ex,
+					       struct iwffff_layer *lp,
+					       struct iwffff_env *ep,
+					       struct iwffff_xenv *ex,
 					       char __user **data,
 					       long *len,
 					       gfp_t gfp_mask)
 {
 	__u32 stype;
-	iwffff_env_record_t *rp, *rp_last;
-	iwffff_xenv_record_t rx;
-	iwffff_env_point_t *pp;
-	iwffff_xenv_point_t px;
+	struct iwffff_env_record *rp, *rp_last;
+	struct iwffff_xenv_record rx;
+	struct iwffff_env_point *pp;
+	struct iwffff_xenv_point px;
 	int points_size, idx;
 
 	ep->flags = ex->flags;
@@ -101,7 +101,7 @@
 		rp->sustain_rate = le16_to_cpu(rx.sustain_rate);
 		rp->release_rate = le16_to_cpu(rx.release_rate);
 		rp->hirange = rx.hirange;
-		pp = (iwffff_env_point_t *)(rp + 1);
+		pp = (struct iwffff_env_point *)(rp + 1);
 		for (idx = 0; idx < rp->nattack + rp->nrelease; idx++) {
 			if (copy_from_user(&px, *data, sizeof(px)))
 				return -EFAULT;
@@ -120,14 +120,14 @@
 	return 0;
 }
 
-static int snd_seq_iwffff_copy_wave_from_stream(snd_iwffff_ops_t *ops,
-						iwffff_layer_t *lp,
+static int snd_seq_iwffff_copy_wave_from_stream(struct snd_iwffff_ops *ops,
+						struct iwffff_layer *lp,
 					        char __user **data,
 					        long *len,
 					        int atomic)
 {
-	iwffff_wave_t *wp, *prev;
-	iwffff_xwave_t xp;
+	struct iwffff_wave *wp, *prev;
+	struct iwffff_xwave xp;
 	int err;
 	gfp_t gfp_mask;
 	unsigned int real_size;
@@ -186,11 +186,11 @@
 	return 0;
 }
 
-static void snd_seq_iwffff_env_free(snd_iwffff_ops_t *ops,
-				    iwffff_env_t *env,
+static void snd_seq_iwffff_env_free(struct snd_iwffff_ops *ops,
+				    struct iwffff_env *env,
 				    int atomic)
 {
-	iwffff_env_record_t *rec;
+	struct iwffff_env_record *rec;
 	
 	while ((rec = env->record) != NULL) {
 		env->record = rec->next;
@@ -198,8 +198,8 @@
 	}
 }
 				    
-static void snd_seq_iwffff_wave_free(snd_iwffff_ops_t *ops,
-				     iwffff_wave_t *wave,
+static void snd_seq_iwffff_wave_free(struct snd_iwffff_ops *ops,
+				     struct iwffff_wave *wave,
 				     int atomic)
 {
 	if (ops->remove_sample)
@@ -207,12 +207,12 @@
 	kfree(wave);
 }
 
-static void snd_seq_iwffff_instr_free(snd_iwffff_ops_t *ops,
-                                      iwffff_instrument_t *ip,
+static void snd_seq_iwffff_instr_free(struct snd_iwffff_ops *ops,
+                                      struct iwffff_instrument *ip,
                                       int atomic)
 {
-	iwffff_layer_t *layer;
-	iwffff_wave_t *wave;
+	struct iwffff_layer *layer;
+	struct iwffff_wave *wave;
 	
 	while ((layer = ip->layer) != NULL) {
 		ip->layer = layer->next;
@@ -226,15 +226,15 @@
 	}
 }
 
-static int snd_seq_iwffff_put(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_iwffff_put(void *private_data, struct snd_seq_kinstr *instr,
 			      char __user *instr_data, long len, int atomic,
 			      int cmd)
 {
-	snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data;
-	iwffff_instrument_t *ip;
-	iwffff_xinstrument_t ix;
-	iwffff_layer_t *lp, *prev_lp;
-	iwffff_xlayer_t lx;
+	struct snd_iwffff_ops *ops = private_data;
+	struct iwffff_instrument *ip;
+	struct iwffff_xinstrument ix;
+	struct iwffff_layer *lp, *prev_lp;
+	struct iwffff_xlayer lx;
 	int err;
 	gfp_t gfp_mask;
 
@@ -250,7 +250,7 @@
 		return -EINVAL;
 	instr_data += sizeof(ix);
 	len -= sizeof(ix);
-	ip = (iwffff_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct iwffff_instrument *)KINSTR_DATA(instr);
 	ip->exclusion = le16_to_cpu(ix.exclusion);
 	ip->layer_type = le16_to_cpu(ix.layer_type);
 	ip->exclusion_group = le16_to_cpu(ix.exclusion_group);
@@ -261,7 +261,7 @@
 	/* copy layers */
 	prev_lp = NULL;
 	while (len > 0) {
-		if (len < (long)sizeof(iwffff_xlayer_t)) {
+		if (len < (long)sizeof(struct iwffff_xlayer)) {
 			snd_seq_iwffff_instr_free(ops, ip, atomic);
 			return -EINVAL;
 		}
@@ -335,8 +335,8 @@
 	return 0;
 }
 
-static void snd_seq_iwffff_copy_lfo_to_stream(iwffff_xlfo_t *fx,
-					      iwffff_lfo_t *fp)
+static void snd_seq_iwffff_copy_lfo_to_stream(struct iwffff_xlfo *fx,
+					      struct iwffff_lfo *fp)
 {
 	fx->freq = cpu_to_le16(fp->freq);
 	fx->depth = cpu_to_le16(fp->depth);
@@ -346,16 +346,16 @@
 }
 
 static int snd_seq_iwffff_copy_env_to_stream(__u32 req_stype,
-					     iwffff_layer_t *lp,
-					     iwffff_xenv_t *ex,
-					     iwffff_env_t *ep,
+					     struct iwffff_layer *lp,
+					     struct iwffff_xenv *ex,
+					     struct iwffff_env *ep,
 					     char __user **data,
 					     long *len)
 {
-	iwffff_env_record_t *rp;
-	iwffff_xenv_record_t rx;
-	iwffff_env_point_t *pp;
-	iwffff_xenv_point_t px;
+	struct iwffff_env_record *rp;
+	struct iwffff_xenv_record rx;
+	struct iwffff_env_point *pp;
+	struct iwffff_xenv_point px;
 	int points_size, idx;
 
 	ex->flags = ep->flags;
@@ -379,7 +379,7 @@
 		points_size = (rp->nattack + rp->nrelease) * 2 * sizeof(__u16);
 		if (*len < points_size)
 			return -ENOMEM;
-		pp = (iwffff_env_point_t *)(rp + 1);
+		pp = (struct iwffff_env_point *)(rp + 1);
 		for (idx = 0; idx < rp->nattack + rp->nrelease; idx++) {
 			px.offset = cpu_to_le16(pp->offset);
 			px.rate = cpu_to_le16(pp->rate);
@@ -392,14 +392,14 @@
 	return 0;
 }
 
-static int snd_seq_iwffff_copy_wave_to_stream(snd_iwffff_ops_t *ops,
-					      iwffff_layer_t *lp,
+static int snd_seq_iwffff_copy_wave_to_stream(struct snd_iwffff_ops *ops,
+					      struct iwffff_layer *lp,
 					      char __user **data,
 					      long *len,
 					      int atomic)
 {
-	iwffff_wave_t *wp;
-	iwffff_xwave_t xp;
+	struct iwffff_wave *wp;
+	struct iwffff_xwave xp;
 	int err;
 	unsigned int real_size;
 	
@@ -447,14 +447,14 @@
 	return 0;
 }
 
-static int snd_seq_iwffff_get(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_iwffff_get(void *private_data, struct snd_seq_kinstr *instr,
 			      char __user *instr_data, long len, int atomic, int cmd)
 {
-	snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data;
-	iwffff_instrument_t *ip;
-	iwffff_xinstrument_t ix;
-	iwffff_layer_t *lp;
-	iwffff_xlayer_t lx;
+	struct snd_iwffff_ops *ops = private_data;
+	struct iwffff_instrument *ip;
+	struct iwffff_xinstrument ix;
+	struct iwffff_layer *lp;
+	struct iwffff_xlayer lx;
 	char __user *layer_instr_data;
 	int err;
 	
@@ -463,7 +463,7 @@
 	if (len < (long)sizeof(ix))
 		return -ENOMEM;
 	memset(&ix, 0, sizeof(ix));
-	ip = (iwffff_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct iwffff_instrument *)KINSTR_DATA(instr);
 	ix.stype = IWFFFF_STRU_INSTR;
 	ix.exclusion = cpu_to_le16(ip->exclusion);
 	ix.layer_type = cpu_to_le16(ip->layer_type);
@@ -520,43 +520,43 @@
 	return 0;
 }
 
-static long snd_seq_iwffff_env_size_in_stream(iwffff_env_t *ep)
+static long snd_seq_iwffff_env_size_in_stream(struct iwffff_env *ep)
 {
 	long result = 0;
-	iwffff_env_record_t *rp;
+	struct iwffff_env_record *rp;
 
 	for (rp = ep->record; rp; rp = rp->next) {
-		result += sizeof(iwffff_xenv_record_t);
+		result += sizeof(struct iwffff_xenv_record);
 		result += (rp->nattack + rp->nrelease) * 2 * sizeof(__u16);
 	}
 	return 0;
 }
 
-static long snd_seq_iwffff_wave_size_in_stream(iwffff_layer_t *lp)
+static long snd_seq_iwffff_wave_size_in_stream(struct iwffff_layer *lp)
 {
 	long result = 0;
-	iwffff_wave_t *wp;
+	struct iwffff_wave *wp;
 	
 	for (wp = lp->wave; wp; wp = wp->next) {
-		result += sizeof(iwffff_xwave_t);
+		result += sizeof(struct iwffff_xwave);
 		if (!(wp->format & IWFFFF_WAVE_ROM))
 			result += wp->size;
 	}
 	return result;
 }
 
-static int snd_seq_iwffff_get_size(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_iwffff_get_size(void *private_data, struct snd_seq_kinstr *instr,
 				   long *size)
 {
 	long result;
-	iwffff_instrument_t *ip;
-	iwffff_layer_t *lp;
+	struct iwffff_instrument *ip;
+	struct iwffff_layer *lp;
 
 	*size = 0;
-	ip = (iwffff_instrument_t *)KINSTR_DATA(instr);
-	result = sizeof(iwffff_xinstrument_t);
+	ip = (struct iwffff_instrument *)KINSTR_DATA(instr);
+	result = sizeof(struct iwffff_xinstrument);
 	for (lp = ip->layer; lp; lp = lp->next) {
-		result += sizeof(iwffff_xlayer_t);
+		result += sizeof(struct iwffff_xlayer);
 		result += snd_seq_iwffff_env_size_in_stream(&lp->penv);
 		result += snd_seq_iwffff_env_size_in_stream(&lp->venv);
 		result += snd_seq_iwffff_wave_size_in_stream(lp);
@@ -566,35 +566,35 @@
 }
 
 static int snd_seq_iwffff_remove(void *private_data,
-				 snd_seq_kinstr_t *instr,
+				 struct snd_seq_kinstr *instr,
                                  int atomic)
 {
-	snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data;
-	iwffff_instrument_t *ip;
+	struct snd_iwffff_ops *ops = private_data;
+	struct iwffff_instrument *ip;
 
-	ip = (iwffff_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct iwffff_instrument *)KINSTR_DATA(instr);
 	snd_seq_iwffff_instr_free(ops, ip, atomic);
 	return 0;
 }
 
 static void snd_seq_iwffff_notify(void *private_data,
-				  snd_seq_kinstr_t *instr,
+				  struct snd_seq_kinstr *instr,
                                   int what)
 {
-	snd_iwffff_ops_t *ops = (snd_iwffff_ops_t *)private_data;
+	struct snd_iwffff_ops *ops = private_data;
 
 	if (ops->notify)
 		ops->notify(ops->private_data, instr, what);
 }
 
-int snd_seq_iwffff_init(snd_iwffff_ops_t *ops,
+int snd_seq_iwffff_init(struct snd_iwffff_ops *ops,
 			void *private_data,
-			snd_seq_kinstr_ops_t *next)
+			struct snd_seq_kinstr_ops *next)
 {
 	memset(ops, 0, sizeof(*ops));
 	ops->private_data = private_data;
 	ops->kops.private_data = ops;
-	ops->kops.add_len = sizeof(iwffff_instrument_t);
+	ops->kops.add_len = sizeof(struct iwffff_instrument);
 	ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_INTERWAVE;
 	ops->kops.put = snd_seq_iwffff_put;
 	ops->kops.get = snd_seq_iwffff_get;
diff --git a/sound/core/seq/instr/ainstr_simple.c b/sound/core/seq/instr/ainstr_simple.c
index 17ab94e..6d6ffec 100644
--- a/sound/core/seq/instr/ainstr_simple.c
+++ b/sound/core/seq/instr/ainstr_simple.c
@@ -42,21 +42,21 @@
 	return result;
 }
 
-static void snd_seq_simple_instr_free(snd_simple_ops_t *ops,
-				      simple_instrument_t *ip,
+static void snd_seq_simple_instr_free(struct snd_simple_ops *ops,
+				      struct simple_instrument *ip,
 				      int atomic)
 {
 	if (ops->remove_sample)
 		ops->remove_sample(ops->private_data, ip, atomic);
 }
 
-static int snd_seq_simple_put(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_simple_put(void *private_data, struct snd_seq_kinstr *instr,
 			      char __user *instr_data, long len,
 			      int atomic, int cmd)
 {
-	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
-	simple_instrument_t *ip;
-	simple_xinstrument_t ix;
+	struct snd_simple_ops *ops = private_data;
+	struct simple_instrument *ip;
+	struct simple_xinstrument ix;
 	int err;
 	gfp_t gfp_mask;
 	unsigned int real_size;
@@ -73,7 +73,7 @@
 		return -EINVAL;
 	instr_data += sizeof(ix);
 	len -= sizeof(ix);
-	ip = (simple_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct simple_instrument *)KINSTR_DATA(instr);
 	ip->share_id[0] = le32_to_cpu(ix.share_id[0]);
 	ip->share_id[1] = le32_to_cpu(ix.share_id[1]);
 	ip->share_id[2] = le32_to_cpu(ix.share_id[2]);
@@ -100,13 +100,13 @@
 	return 0;
 }
 
-static int snd_seq_simple_get(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_simple_get(void *private_data, struct snd_seq_kinstr *instr,
 			      char __user *instr_data, long len,
 			      int atomic, int cmd)
 {
-	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
-	simple_instrument_t *ip;
-	simple_xinstrument_t ix;
+	struct snd_simple_ops *ops = private_data;
+	struct simple_instrument *ip;
+	struct simple_xinstrument ix;
 	int err;
 	unsigned int real_size;
 	
@@ -115,7 +115,7 @@
 	if (len < (long)sizeof(ix))
 		return -ENOMEM;
 	memset(&ix, 0, sizeof(ix));
-	ip = (simple_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct simple_instrument *)KINSTR_DATA(instr);
 	ix.stype = SIMPLE_STRU_INSTR;
 	ix.share_id[0] = cpu_to_le32(ip->share_id[0]);
 	ix.share_id[1] = cpu_to_le32(ip->share_id[1]);
@@ -147,46 +147,46 @@
 	return 0;
 }
 
-static int snd_seq_simple_get_size(void *private_data, snd_seq_kinstr_t *instr,
+static int snd_seq_simple_get_size(void *private_data, struct snd_seq_kinstr *instr,
 				   long *size)
 {
-	simple_instrument_t *ip;
+	struct simple_instrument *ip;
 
-	ip = (simple_instrument_t *)KINSTR_DATA(instr);
-	*size = sizeof(simple_xinstrument_t) + snd_seq_simple_size(ip->size, ip->format);
+	ip = (struct simple_instrument *)KINSTR_DATA(instr);
+	*size = sizeof(struct simple_xinstrument) + snd_seq_simple_size(ip->size, ip->format);
 	return 0;
 }
 
 static int snd_seq_simple_remove(void *private_data,
-			         snd_seq_kinstr_t *instr,
+			         struct snd_seq_kinstr *instr,
                                  int atomic)
 {
-	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
-	simple_instrument_t *ip;
+	struct snd_simple_ops *ops = private_data;
+	struct simple_instrument *ip;
 
-	ip = (simple_instrument_t *)KINSTR_DATA(instr);
+	ip = (struct simple_instrument *)KINSTR_DATA(instr);
 	snd_seq_simple_instr_free(ops, ip, atomic);
 	return 0;
 }
 
 static void snd_seq_simple_notify(void *private_data,
-			          snd_seq_kinstr_t *instr,
+			          struct snd_seq_kinstr *instr,
                                   int what)
 {
-	snd_simple_ops_t *ops = (snd_simple_ops_t *)private_data;
+	struct snd_simple_ops *ops = private_data;
 
 	if (ops->notify)
 		ops->notify(ops->private_data, instr, what);
 }
 
-int snd_seq_simple_init(snd_simple_ops_t *ops,
+int snd_seq_simple_init(struct snd_simple_ops *ops,
 		        void *private_data,
-		        snd_seq_kinstr_ops_t *next)
+		        struct snd_seq_kinstr_ops *next)
 {
 	memset(ops, 0, sizeof(*ops));
 	ops->private_data = private_data;
 	ops->kops.private_data = ops;
-	ops->kops.add_len = sizeof(simple_instrument_t);
+	ops->kops.add_len = sizeof(struct simple_instrument);
 	ops->kops.instr_type = SNDRV_SEQ_INSTR_ID_SIMPLE;
 	ops->kops.put = snd_seq_simple_put;
 	ops->kops.get = snd_seq_simple_get;
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 4c0558c..c98f0ba 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -52,8 +52,13 @@
  */
 static int register_device(void);
 static void unregister_device(void);
+#ifdef CONFIG_PROC_FS
 static int register_proc(void);
 static void unregister_proc(void);
+#else
+static inline int register_proc(void) { return 0; }
+static inline void unregister_proc(void) {}
+#endif
 
 static int odev_open(struct inode *inode, struct file *file);
 static int odev_release(struct inode *inode, struct file *file);
@@ -61,9 +66,6 @@
 static ssize_t odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset);
 static long odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
 static unsigned int odev_poll(struct file *file, poll_table * wait);
-#ifdef CONFIG_PROC_FS
-static void info_read(snd_info_entry_t *entry, snd_info_buffer_t *buf);
-#endif
 
 
 /*
@@ -73,7 +75,7 @@
 static int __init alsa_seq_oss_init(void)
 {
 	int rc;
-	static snd_seq_dev_ops_t ops = {
+	static struct snd_seq_dev_ops ops = {
 		snd_seq_oss_synth_register,
 		snd_seq_oss_synth_unregister,
 	};
@@ -92,7 +94,7 @@
 	}
 
 	if ((rc = snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OSS, &ops,
-						 sizeof(snd_seq_oss_reg_t))) < 0) {
+						 sizeof(struct snd_seq_oss_reg))) < 0) {
 		snd_seq_oss_delete_client();
 		unregister_proc();
 		unregister_device();
@@ -144,7 +146,7 @@
 static int
 odev_release(struct inode *inode, struct file *file)
 {
-	seq_oss_devinfo_t *dp;
+	struct seq_oss_devinfo *dp;
 
 	if ((dp = file->private_data) == NULL)
 		return 0;
@@ -161,7 +163,7 @@
 static ssize_t
 odev_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
 {
-	seq_oss_devinfo_t *dp;
+	struct seq_oss_devinfo *dp;
 	dp = file->private_data;
 	snd_assert(dp != NULL, return -EIO);
 	return snd_seq_oss_read(dp, buf, count);
@@ -171,7 +173,7 @@
 static ssize_t
 odev_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
 {
-	seq_oss_devinfo_t *dp;
+	struct seq_oss_devinfo *dp;
 	dp = file->private_data;
 	snd_assert(dp != NULL, return -EIO);
 	return snd_seq_oss_write(dp, buf, count, file);
@@ -180,7 +182,7 @@
 static long
 odev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	seq_oss_devinfo_t *dp;
+	struct seq_oss_devinfo *dp;
 	dp = file->private_data;
 	snd_assert(dp != NULL, return -EIO);
 	return snd_seq_oss_ioctl(dp, cmd, arg);
@@ -195,7 +197,7 @@
 static unsigned int
 odev_poll(struct file *file, poll_table * wait)
 {
-	seq_oss_devinfo_t *dp;
+	struct seq_oss_devinfo *dp;
 	dp = file->private_data;
 	snd_assert(dp != NULL, return 0);
 	return snd_seq_oss_poll(dp, file, wait);
@@ -217,11 +219,6 @@
 	.compat_ioctl =	odev_ioctl_compat,
 };
 
-static snd_minor_t seq_oss_reg = {
-	.comment =	"sequencer",
-	.f_ops =	&seq_oss_f_ops,
-};
-
 static int __init
 register_device(void)
 {
@@ -230,7 +227,7 @@
 	down(&register_mutex);
 	if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
 					  NULL, 0,
-					  &seq_oss_reg,
+					  &seq_oss_f_ops, NULL,
 					  SNDRV_SEQ_OSS_DEVNAME)) < 0) {
 		snd_printk(KERN_ERR "can't register device seq\n");
 		up(&register_mutex);
@@ -238,7 +235,7 @@
 	}
 	if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
 					  NULL, 0,
-					  &seq_oss_reg,
+					  &seq_oss_f_ops, NULL,
 					  SNDRV_SEQ_OSS_DEVNAME)) < 0) {
 		snd_printk(KERN_ERR "can't register device music\n");
 		snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0);
@@ -268,10 +265,10 @@
 
 #ifdef CONFIG_PROC_FS
 
-static snd_info_entry_t *info_entry;
+static struct snd_info_entry *info_entry;
 
 static void
-info_read(snd_info_entry_t *entry, snd_info_buffer_t *buf)
+info_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
 {
 	down(&register_mutex);
 	snd_iprintf(buf, "OSS sequencer emulation version %s\n", SNDRV_SEQ_OSS_VERSION_STR);
@@ -281,13 +278,11 @@
 	up(&register_mutex);
 }
 
-#endif /* CONFIG_PROC_FS */
 
 static int __init
 register_proc(void)
 {
-#ifdef CONFIG_PROC_FS
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	entry = snd_info_create_module_entry(THIS_MODULE, SNDRV_SEQ_OSS_PROCNAME, snd_seq_root);
 	if (entry == NULL)
@@ -302,16 +297,14 @@
 		return -ENOMEM;
 	}
 	info_entry = entry;
-#endif
 	return 0;
 }
 
 static void
 unregister_proc(void)
 {
-#ifdef CONFIG_PROC_FS
 	if (info_entry)
 		snd_info_unregister(info_entry);
 	info_entry = NULL;
-#endif
 }
+#endif /* CONFIG_PROC_FS */
diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h
index 9737867..9a8567c 100644
--- a/sound/core/seq/oss/seq_oss_device.h
+++ b/sound/core/seq/oss/seq_oss_device.h
@@ -55,32 +55,24 @@
  * type definitions
  */
 
-typedef struct seq_oss_devinfo_t seq_oss_devinfo_t;
-typedef struct seq_oss_writeq_t seq_oss_writeq_t;
-typedef struct seq_oss_readq_t seq_oss_readq_t;
-typedef struct seq_oss_timer_t seq_oss_timer_t;
-typedef struct seq_oss_synthinfo_t seq_oss_synthinfo_t;
-typedef struct seq_oss_synth_sysex_t seq_oss_synth_sysex_t;
-typedef struct seq_oss_chinfo_t seq_oss_chinfo_t;
 typedef unsigned int reltime_t;
 typedef unsigned int abstime_t;
-typedef union evrec_t evrec_t;
 
 
 /*
  * synthesizer channel information
  */
-struct seq_oss_chinfo_t {
+struct seq_oss_chinfo {
 	int note, vel;
 };
 
 /*
  * synthesizer information
  */
-struct seq_oss_synthinfo_t {
-	snd_seq_oss_arg_t arg;
-	seq_oss_chinfo_t *ch;
-	seq_oss_synth_sysex_t *sysex;
+struct seq_oss_synthinfo {
+	struct snd_seq_oss_arg arg;
+	struct seq_oss_chinfo *ch;
+	struct seq_oss_synth_sysex *sysex;
 	int nr_voices;
 	int opened;
 	int is_midi;
@@ -92,14 +84,14 @@
  * sequencer client information
  */
 
-struct seq_oss_devinfo_t {
+struct seq_oss_devinfo {
 
 	int index;	/* application index */
 	int cseq;	/* sequencer client number */
 	int port;	/* sequencer port number */
 	int queue;	/* sequencer queue number */
 
-	snd_seq_addr_t addr;	/* address of this device */
+	struct snd_seq_addr addr;	/* address of this device */
 
 	int seq_mode;	/* sequencer mode */
 	int file_mode;	/* file access */
@@ -109,17 +101,17 @@
 
 	/* synth device table */
 	int max_synthdev;
-	seq_oss_synthinfo_t synths[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
+	struct seq_oss_synthinfo synths[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
 	int synth_opened;
 
 	/* output queue */
-	seq_oss_writeq_t *writeq;
+	struct seq_oss_writeq *writeq;
 
 	/* midi input queue */
-	seq_oss_readq_t *readq;
+	struct seq_oss_readq *readq;
 
 	/* timer */
-	seq_oss_timer_t *timer;
+	struct seq_oss_timer *timer;
 };
 
 
@@ -133,24 +125,24 @@
 
 /* device file interface */
 int snd_seq_oss_open(struct file *file, int level);
-void snd_seq_oss_release(seq_oss_devinfo_t *dp);
-int snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long arg);
-int snd_seq_oss_read(seq_oss_devinfo_t *dev, char __user *buf, int count);
-int snd_seq_oss_write(seq_oss_devinfo_t *dp, const char __user *buf, int count, struct file *opt);
-unsigned int snd_seq_oss_poll(seq_oss_devinfo_t *dp, struct file *file, poll_table * wait);
+void snd_seq_oss_release(struct seq_oss_devinfo *dp);
+int snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long arg);
+int snd_seq_oss_read(struct seq_oss_devinfo *dev, char __user *buf, int count);
+int snd_seq_oss_write(struct seq_oss_devinfo *dp, const char __user *buf, int count, struct file *opt);
+unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait);
 
-void snd_seq_oss_reset(seq_oss_devinfo_t *dp);
-void snd_seq_oss_drain_write(seq_oss_devinfo_t *dp);
+void snd_seq_oss_reset(struct seq_oss_devinfo *dp);
+void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp);
 
 /* */
-void snd_seq_oss_process_queue(seq_oss_devinfo_t *dp, abstime_t time);
+void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time);
 
 
 /* proc interface */
-void snd_seq_oss_system_info_read(snd_info_buffer_t *buf);
-void snd_seq_oss_midi_info_read(snd_info_buffer_t *buf);
-void snd_seq_oss_synth_info_read(snd_info_buffer_t *buf);
-void snd_seq_oss_readq_info_read(seq_oss_readq_t *q, snd_info_buffer_t *buf);
+void snd_seq_oss_system_info_read(struct snd_info_buffer *buf);
+void snd_seq_oss_midi_info_read(struct snd_info_buffer *buf);
+void snd_seq_oss_synth_info_read(struct snd_info_buffer *buf);
+void snd_seq_oss_readq_info_read(struct seq_oss_readq *q, struct snd_info_buffer *buf);
 
 /* file mode macros */
 #define is_read_mode(mode)	((mode) & SNDRV_SEQ_OSS_FILE_READ)
@@ -159,21 +151,21 @@
 
 /* dispatch event */
 static inline int
-snd_seq_oss_dispatch(seq_oss_devinfo_t *dp, snd_seq_event_t *ev, int atomic, int hop)
+snd_seq_oss_dispatch(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int atomic, int hop)
 {
 	return snd_seq_kernel_client_dispatch(dp->cseq, ev, atomic, hop);
 }
 
 /* ioctl */
 static inline int
-snd_seq_oss_control(seq_oss_devinfo_t *dp, unsigned int type, void *arg)
+snd_seq_oss_control(struct seq_oss_devinfo *dp, unsigned int type, void *arg)
 {
 	return snd_seq_kernel_client_ctl(dp->cseq, type, arg);
 }
 
 /* fill the addresses in header */
 static inline void
-snd_seq_oss_fill_addr(seq_oss_devinfo_t *dp, snd_seq_event_t *ev,
+snd_seq_oss_fill_addr(struct seq_oss_devinfo *dp, struct snd_seq_event *ev,
 		     int dest_client, int dest_port)
 {
 	ev->queue = dp->queue;
diff --git a/sound/core/seq/oss/seq_oss_event.c b/sound/core/seq/oss/seq_oss_event.c
index 58e52dd..066f5f3 100644
--- a/sound/core/seq/oss/seq_oss_event.c
+++ b/sound/core/seq/oss/seq_oss_event.c
@@ -31,17 +31,17 @@
 /*
  * prototypes
  */
-static int extended_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev);
-static int chn_voice_event(seq_oss_devinfo_t *dp, evrec_t *event_rec, snd_seq_event_t *ev);
-static int chn_common_event(seq_oss_devinfo_t *dp, evrec_t *event_rec, snd_seq_event_t *ev);
-static int timing_event(seq_oss_devinfo_t *dp, evrec_t *event_rec, snd_seq_event_t *ev);
-static int local_event(seq_oss_devinfo_t *dp, evrec_t *event_rec, snd_seq_event_t *ev);
-static int old_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev);
-static int note_on_event(seq_oss_devinfo_t *dp, int dev, int ch, int note, int vel, snd_seq_event_t *ev);
-static int note_off_event(seq_oss_devinfo_t *dp, int dev, int ch, int note, int vel, snd_seq_event_t *ev);
-static int set_note_event(seq_oss_devinfo_t *dp, int dev, int type, int ch, int note, int vel, snd_seq_event_t *ev);
-static int set_control_event(seq_oss_devinfo_t *dp, int dev, int type, int ch, int param, int val, snd_seq_event_t *ev);
-static int set_echo_event(seq_oss_devinfo_t *dp, evrec_t *rec, snd_seq_event_t *ev);
+static int extended_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev);
+static int chn_voice_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev);
+static int chn_common_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev);
+static int timing_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev);
+static int local_event(struct seq_oss_devinfo *dp, union evrec *event_rec, struct snd_seq_event *ev);
+static int old_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev);
+static int note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev);
+static int note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev);
+static int set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev);
+static int set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev);
+static int set_echo_event(struct seq_oss_devinfo *dp, union evrec *rec, struct snd_seq_event *ev);
 
 
 /*
@@ -51,7 +51,7 @@
  */
 
 int
-snd_seq_oss_process_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
+snd_seq_oss_process_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
 {
 	switch (q->s.code) {
 	case SEQ_EXTENDED:
@@ -104,7 +104,7 @@
 
 /* old type events: mode1 only */
 static int
-old_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
+old_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
 {
 	switch (q->s.code) {
 	case SEQ_NOTEOFF:
@@ -130,7 +130,7 @@
 
 /* 8bytes extended event: mode1 only */
 static int
-extended_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
+extended_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
 {
 	int val;
 
@@ -184,7 +184,7 @@
 
 /* channel voice events: mode1 and 2 */
 static int
-chn_voice_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
+chn_voice_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
 {
 	if (q->v.chn >= 32)
 		return -EINVAL;
@@ -205,7 +205,7 @@
 
 /* channel common events: mode1 and 2 */
 static int
-chn_common_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
+chn_common_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
 {
 	if (q->l.chn >= 32)
 		return -EINVAL;
@@ -232,14 +232,14 @@
 
 /* timer events: mode1 and mode2 */
 static int
-timing_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
+timing_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
 {
 	switch (q->t.cmd) {
 	case TMR_ECHO:
 		if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC)
 			return set_echo_event(dp, q, ev);
 		else {
-			evrec_t tmp;
+			union evrec tmp;
 			memset(&tmp, 0, sizeof(tmp));
 			/* XXX: only for little-endian! */
 			tmp.echo = (q->t.time << 8) | SEQ_ECHO;
@@ -267,7 +267,7 @@
 
 /* local events: mode1 and 2 */
 static int
-local_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev)
+local_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev)
 {
 	return -EINVAL;
 }
@@ -283,9 +283,9 @@
  *	Use key-pressure if note >= 128
  */
 static int
-note_on_event(seq_oss_devinfo_t *dp, int dev, int ch, int note, int vel, snd_seq_event_t *ev)
+note_on_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev)
 {
-	seq_oss_synthinfo_t *info = &dp->synths[dev];
+	struct seq_oss_synthinfo *info = &dp->synths[dev];
 	switch (info->arg.event_passing) {
 	case SNDRV_SEQ_OSS_PROCESS_EVENTS:
 		if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -338,9 +338,9 @@
  * process note-off event for OSS synth
  */
 static int
-note_off_event(seq_oss_devinfo_t *dp, int dev, int ch, int note, int vel, snd_seq_event_t *ev)
+note_off_event(struct seq_oss_devinfo *dp, int dev, int ch, int note, int vel, struct snd_seq_event *ev)
 {
-	seq_oss_synthinfo_t *info = &dp->synths[dev];
+	struct seq_oss_synthinfo *info = &dp->synths[dev];
 	switch (info->arg.event_passing) {
 	case SNDRV_SEQ_OSS_PROCESS_EVENTS:
 		if (! info->ch || ch < 0 || ch >= info->nr_voices) {
@@ -369,7 +369,7 @@
  * create a note event
  */
 static int
-set_note_event(seq_oss_devinfo_t *dp, int dev, int type, int ch, int note, int vel, snd_seq_event_t *ev)
+set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev)
 {
 	if (! snd_seq_oss_synth_is_valid(dp, dev))
 		return -ENXIO;
@@ -387,7 +387,7 @@
  * create a control event
  */
 static int
-set_control_event(seq_oss_devinfo_t *dp, int dev, int type, int ch, int param, int val, snd_seq_event_t *ev)
+set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev)
 {
 	if (! snd_seq_oss_synth_is_valid(dp, dev))
 		return -ENXIO;
@@ -405,7 +405,7 @@
  * create an echo event
  */
 static int
-set_echo_event(seq_oss_devinfo_t *dp, evrec_t *rec, snd_seq_event_t *ev)
+set_echo_event(struct seq_oss_devinfo *dp, union evrec *rec, struct snd_seq_event *ev)
 {
 	ev->type = SNDRV_SEQ_EVENT_ECHO;
 	/* echo back to itself */
@@ -419,11 +419,11 @@
  * the echo event is processed here.
  */
 int
-snd_seq_oss_event_input(snd_seq_event_t *ev, int direct, void *private_data,
+snd_seq_oss_event_input(struct snd_seq_event *ev, int direct, void *private_data,
 			int atomic, int hop)
 {
-	seq_oss_devinfo_t *dp = (seq_oss_devinfo_t *)private_data;
-	evrec_t *rec;
+	struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data;
+	union evrec *rec;
 
 	if (ev->type != SNDRV_SEQ_EVENT_ECHO)
 		return snd_seq_oss_midi_input(ev, direct, private_data);
@@ -431,7 +431,7 @@
 	if (ev->source.client != dp->cseq)
 		return 0; /* ignored */
 
-	rec = (evrec_t*)&ev->data;
+	rec = (union evrec*)&ev->data;
 	if (rec->s.code == SEQ_SYNCTIMER) {
 		/* sync echo back */
 		snd_seq_oss_writeq_wakeup(dp->writeq, rec->t.time);
diff --git a/sound/core/seq/oss/seq_oss_event.h b/sound/core/seq/oss/seq_oss_event.h
index bf1d4d3..9a4d9ad 100644
--- a/sound/core/seq/oss/seq_oss_event.h
+++ b/sound/core/seq/oss/seq_oss_event.h
@@ -29,74 +29,74 @@
 #define LONG_EVENT_SIZE		8
 
 /* short event (4bytes) */
-typedef struct evrec_short_t {
+struct evrec_short {
 	unsigned char code;
 	unsigned char parm1;
 	unsigned char dev;
 	unsigned char parm2;
-} evrec_short_t;
+};
 	
 /* short note events (4bytes) */
-typedef struct evrec_note_t {
+struct evrec_note {
 	unsigned char code;
 	unsigned char chn;
 	unsigned char note;
 	unsigned char vel;
-} evrec_note_t;
+};
 	
 /* long timer events (8bytes) */
-typedef struct evrec_timer_t {
+struct evrec_timer {
 	unsigned char code;
 	unsigned char cmd;
 	unsigned char dummy1, dummy2;
 	unsigned int time;
-} evrec_timer_t;
+};
 
 /* long extended events (8bytes) */
-typedef struct evrec_extended_t {
+struct evrec_extended {
 	unsigned char code;
 	unsigned char cmd;
 	unsigned char dev;
 	unsigned char chn;
 	unsigned char p1, p2, p3, p4;
-} evrec_extended_t;
+};
 
 /* long channel events (8bytes) */
-typedef struct evrec_long_t {
+struct evrec_long {
 	unsigned char code;
 	unsigned char dev;
 	unsigned char cmd;
 	unsigned char chn;
 	unsigned char p1, p2;
 	unsigned short val;
-} evrec_long_t;
+};
 	
 /* channel voice events (8bytes) */
-typedef struct evrec_voice_t {
+struct evrec_voice {
 	unsigned char code;
 	unsigned char dev;
 	unsigned char cmd;
 	unsigned char chn;
 	unsigned char note, parm;
 	unsigned short dummy;
-} evrec_voice_t;
+};
 
 /* sysex events (8bytes) */
-typedef struct evrec_sysex_t {
+struct evrec_sysex {
 	unsigned char code;
 	unsigned char dev;
 	unsigned char buf[6];
-} evrec_sysex_t;
+};
 
 /* event record */
-union evrec_t {
-	evrec_short_t s;
-	evrec_note_t n;
-	evrec_long_t l;
-	evrec_voice_t v;
-	evrec_timer_t t;
-	evrec_extended_t e;
-	evrec_sysex_t x;
+union evrec {
+	struct evrec_short s;
+	struct evrec_note n;
+	struct evrec_long l;
+	struct evrec_voice v;
+	struct evrec_timer t;
+	struct evrec_extended e;
+	struct evrec_sysex x;
 	unsigned int echo;
 	unsigned char c[LONG_EVENT_SIZE];
 };
@@ -104,9 +104,9 @@
 #define ev_is_long(ev) ((ev)->s.code >= 128)
 #define ev_length(ev) ((ev)->s.code >= 128 ? LONG_EVENT_SIZE : SHORT_EVENT_SIZE)
 
-int snd_seq_oss_process_event(seq_oss_devinfo_t *dp, evrec_t *q, snd_seq_event_t *ev);
-int snd_seq_oss_process_timer_event(seq_oss_timer_t *rec, evrec_t *q);
-int snd_seq_oss_event_input(snd_seq_event_t *ev, int direct, void *private_data, int atomic, int hop);
+int snd_seq_oss_process_event(struct seq_oss_devinfo *dp, union evrec *q, struct snd_seq_event *ev);
+int snd_seq_oss_process_timer_event(struct seq_oss_timer *rec, union evrec *q);
+int snd_seq_oss_event_input(struct snd_seq_event *ev, int direct, void *private_data, int atomic, int hop);
 
 
 #endif /* __SEQ_OSS_EVENT_H */
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index 1ab1cf8..ca5a2ed 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -41,17 +41,17 @@
 static int system_port = -1;
 
 static int num_clients;
-static seq_oss_devinfo_t *client_table[SNDRV_SEQ_OSS_MAX_CLIENTS];
+static struct seq_oss_devinfo *client_table[SNDRV_SEQ_OSS_MAX_CLIENTS];
 
 
 /*
  * prototypes
  */
-static int receive_announce(snd_seq_event_t *ev, int direct, void *private, int atomic, int hop);
+static int receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic, int hop);
 static int translate_mode(struct file *file);
-static int create_port(seq_oss_devinfo_t *dp);
-static int delete_port(seq_oss_devinfo_t *dp);
-static int alloc_seq_queue(seq_oss_devinfo_t *dp);
+static int create_port(struct seq_oss_devinfo *dp);
+static int delete_port(struct seq_oss_devinfo *dp);
+static int alloc_seq_queue(struct seq_oss_devinfo *dp);
 static int delete_seq_queue(int queue);
 static void free_devinfo(void *private);
 
@@ -65,40 +65,24 @@
 snd_seq_oss_create_client(void)
 {
 	int rc;
-	snd_seq_client_callback_t callback;
-	snd_seq_client_info_t *info;
-	snd_seq_port_info_t *port;
-	snd_seq_port_callback_t port_callback;
+	struct snd_seq_port_info *port;
+	struct snd_seq_port_callback port_callback;
 
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	port = kmalloc(sizeof(*port), GFP_KERNEL);
-	if (!info || !port) {
+	if (!port) {
 		rc = -ENOMEM;
 		goto __error;
 	}
 
 	/* create ALSA client */
-	memset(&callback, 0, sizeof(callback));
-
-	callback.private_data = NULL;
-	callback.allow_input = 1;
-	callback.allow_output = 1;
-
-	rc = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_OSS, &callback);
+	rc = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_OSS,
+					  "OSS sequencer");
 	if (rc < 0)
 		goto __error;
 
 	system_client = rc;
 	debug_printk(("new client = %d\n", rc));
 
-	/* set client information */
-	memset(info, 0, sizeof(*info));
-	info->client = system_client;
-	info->type = KERNEL_CLIENT;
-	strcpy(info->name, "OSS sequencer");
-
-	rc = call_ctl(SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, info);
-
 	/* look up midi devices */
 	snd_seq_oss_midi_lookup_ports(system_client);
 
@@ -118,7 +102,7 @@
 	
 	call_ctl(SNDRV_SEQ_IOCTL_CREATE_PORT, port);
 	if ((system_port = port->addr.port) >= 0) {
-		snd_seq_port_subscribe_t subs;
+		struct snd_seq_port_subscribe subs;
 
 		memset(&subs, 0, sizeof(subs));
 		subs.sender.client = SNDRV_SEQ_CLIENT_SYSTEM;
@@ -131,7 +115,6 @@
 
  __error:
 	kfree(port);
-	kfree(info);
 	return rc;
 }
 
@@ -140,9 +123,9 @@
  * receive annoucement from system port, and check the midi device
  */
 static int
-receive_announce(snd_seq_event_t *ev, int direct, void *private, int atomic, int hop)
+receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic, int hop)
 {
-	snd_seq_port_info_t pinfo;
+	struct snd_seq_port_info pinfo;
 
 	if (atomic)
 		return 0; /* it must not happen */
@@ -191,7 +174,7 @@
 snd_seq_oss_open(struct file *file, int level)
 {
 	int i, rc;
-	seq_oss_devinfo_t *dp;
+	struct seq_oss_devinfo *dp;
 
 	if ((dp = kzalloc(sizeof(*dp), GFP_KERNEL)) == NULL) {
 		snd_printk(KERN_ERR "can't malloc device info\n");
@@ -323,11 +306,11 @@
  * create sequencer port
  */
 static int
-create_port(seq_oss_devinfo_t *dp)
+create_port(struct seq_oss_devinfo *dp)
 {
 	int rc;
-	snd_seq_port_info_t port;
-	snd_seq_port_callback_t callback;
+	struct snd_seq_port_info port;
+	struct snd_seq_port_callback callback;
 
 	memset(&port, 0, sizeof(port));
 	port.addr.client = dp->cseq;
@@ -358,7 +341,7 @@
  * delete ALSA port
  */
 static int
-delete_port(seq_oss_devinfo_t *dp)
+delete_port(struct seq_oss_devinfo *dp)
 {
 	if (dp->port < 0)
 		return 0;
@@ -371,9 +354,9 @@
  * allocate a queue
  */
 static int
-alloc_seq_queue(seq_oss_devinfo_t *dp)
+alloc_seq_queue(struct seq_oss_devinfo *dp)
 {
-	snd_seq_queue_info_t qinfo;
+	struct snd_seq_queue_info qinfo;
 	int rc;
 
 	memset(&qinfo, 0, sizeof(qinfo));
@@ -392,7 +375,7 @@
 static int
 delete_seq_queue(int queue)
 {
-	snd_seq_queue_info_t qinfo;
+	struct snd_seq_queue_info qinfo;
 	int rc;
 
 	if (queue < 0)
@@ -412,7 +395,7 @@
 static void
 free_devinfo(void *private)
 {
-	seq_oss_devinfo_t *dp = (seq_oss_devinfo_t *)private;
+	struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private;
 
 	if (dp->timer)
 		snd_seq_oss_timer_delete(dp->timer);
@@ -431,7 +414,7 @@
  * close sequencer device
  */
 void
-snd_seq_oss_release(seq_oss_devinfo_t *dp)
+snd_seq_oss_release(struct seq_oss_devinfo *dp)
 {
 	int queue;
 
@@ -460,7 +443,7 @@
  * Wait until the queue is empty (if we don't have nonblock)
  */
 void
-snd_seq_oss_drain_write(seq_oss_devinfo_t *dp)
+snd_seq_oss_drain_write(struct seq_oss_devinfo *dp)
 {
 	if (! dp->timer->running)
 		return;
@@ -477,7 +460,7 @@
  * reset sequencer devices
  */
 void
-snd_seq_oss_reset(seq_oss_devinfo_t *dp)
+snd_seq_oss_reset(struct seq_oss_devinfo *dp)
 {
 	int i;
 
@@ -502,6 +485,7 @@
 }
 
 
+#ifdef CONFIG_PROC_FS
 /*
  * misc. functions for proc interface
  */
@@ -525,10 +509,10 @@
  * proc interface
  */
 void
-snd_seq_oss_system_info_read(snd_info_buffer_t *buf)
+snd_seq_oss_system_info_read(struct snd_info_buffer *buf)
 {
 	int i;
-	seq_oss_devinfo_t *dp;
+	struct seq_oss_devinfo *dp;
 
 	snd_iprintf(buf, "ALSA client number %d\n", system_client);
 	snd_iprintf(buf, "ALSA receiver port %d\n", system_port);
@@ -552,4 +536,4 @@
 			snd_seq_oss_readq_info_read(dp->readq, buf);
 	}
 }
-
+#endif /* CONFIG_PROC_FS */
diff --git a/sound/core/seq/oss/seq_oss_ioctl.c b/sound/core/seq/oss/seq_oss_ioctl.c
index e86f18d..5ac701c 100644
--- a/sound/core/seq/oss/seq_oss_ioctl.c
+++ b/sound/core/seq/oss/seq_oss_ioctl.c
@@ -28,7 +28,7 @@
 #include "seq_oss_midi.h"
 #include "seq_oss_event.h"
 
-static int snd_seq_oss_synth_info_user(seq_oss_devinfo_t *dp, void __user *arg)
+static int snd_seq_oss_synth_info_user(struct seq_oss_devinfo *dp, void __user *arg)
 {
 	struct synth_info info;
 
@@ -41,7 +41,7 @@
 	return 0;
 }
 
-static int snd_seq_oss_midi_info_user(seq_oss_devinfo_t *dp, void __user *arg)
+static int snd_seq_oss_midi_info_user(struct seq_oss_devinfo *dp, void __user *arg)
 {
 	struct midi_info info;
 
@@ -54,24 +54,24 @@
 	return 0;
 }
 
-static int snd_seq_oss_oob_user(seq_oss_devinfo_t *dp, void __user *arg)
+static int snd_seq_oss_oob_user(struct seq_oss_devinfo *dp, void __user *arg)
 {
 	unsigned char ev[8];
-	snd_seq_event_t tmpev;
+	struct snd_seq_event tmpev;
 
 	if (copy_from_user(ev, arg, 8))
 		return -EFAULT;
 	memset(&tmpev, 0, sizeof(tmpev));
 	snd_seq_oss_fill_addr(dp, &tmpev, dp->addr.port, dp->addr.client);
 	tmpev.time.tick = 0;
-	if (! snd_seq_oss_process_event(dp, (evrec_t*)ev, &tmpev)) {
+	if (! snd_seq_oss_process_event(dp, (union evrec *)ev, &tmpev)) {
 		snd_seq_oss_dispatch(dp, &tmpev, 0, 0);
 	}
 	return 0;
 }
 
 int
-snd_seq_oss_ioctl(seq_oss_devinfo_t *dp, unsigned int cmd, unsigned long carg)
+snd_seq_oss_ioctl(struct seq_oss_devinfo *dp, unsigned int cmd, unsigned long carg)
 {
 	int dev, val;
 	void __user *arg = (void __user *)carg;
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index f0e95c8..0a711d2 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -37,15 +37,15 @@
 /*
  * definition of midi device record
  */
-struct seq_oss_midi_t {
+struct seq_oss_midi {
 	int seq_device;		/* device number */
 	int client;		/* sequencer client number */
 	int port;		/* sequencer port number */
 	unsigned int flags;	/* port capability */
 	int opened;		/* flag for opening */
 	unsigned char name[SNDRV_SEQ_OSS_MAX_MIDI_NAME];
-	snd_midi_event_t *coder;	/* MIDI event coder */
-	seq_oss_devinfo_t *devinfo;	/* assigned OSSseq device */
+	struct snd_midi_event *coder;	/* MIDI event coder */
+	struct seq_oss_devinfo *devinfo;	/* assigned OSSseq device */
 	snd_use_lock_t use_lock;
 };
 
@@ -54,17 +54,17 @@
  * midi device table
  */
 static int max_midi_devs;
-static seq_oss_midi_t *midi_devs[SNDRV_SEQ_OSS_MAX_MIDI_DEVS];
+static struct seq_oss_midi *midi_devs[SNDRV_SEQ_OSS_MAX_MIDI_DEVS];
 
 static DEFINE_SPINLOCK(register_lock);
 
 /*
  * prototypes
  */
-static seq_oss_midi_t *get_mdev(int dev);
-static seq_oss_midi_t *get_mididev(seq_oss_devinfo_t *dp, int dev);
-static int send_synth_event(seq_oss_devinfo_t *dp, snd_seq_event_t *ev, int dev);
-static int send_midi_event(seq_oss_devinfo_t *dp, snd_seq_event_t *ev, seq_oss_midi_t *mdev);
+static struct seq_oss_midi *get_mdev(int dev);
+static struct seq_oss_midi *get_mididev(struct seq_oss_devinfo *dp, int dev);
+static int send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev);
+static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev);
 
 /*
  * look up the existing ports
@@ -73,8 +73,8 @@
 int __init
 snd_seq_oss_midi_lookup_ports(int client)
 {
-	snd_seq_client_info_t *clinfo;
-	snd_seq_port_info_t *pinfo;
+	struct snd_seq_client_info *clinfo;
+	struct snd_seq_port_info *pinfo;
 
 	clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL);
 	pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
@@ -100,10 +100,10 @@
 
 /*
  */
-static seq_oss_midi_t *
+static struct seq_oss_midi *
 get_mdev(int dev)
 {
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 	unsigned long flags;
 
 	spin_lock_irqsave(&register_lock, flags);
@@ -117,11 +117,11 @@
 /*
  * look for the identical slot
  */
-static seq_oss_midi_t *
+static struct seq_oss_midi *
 find_slot(int client, int port)
 {
 	int i;
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 	unsigned long flags;
 
 	spin_lock_irqsave(&register_lock, flags);
@@ -145,10 +145,10 @@
  * register a new port if it doesn't exist yet
  */
 int
-snd_seq_oss_midi_check_new_port(snd_seq_port_info_t *pinfo)
+snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo)
 {
 	int i;
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 	unsigned long flags;
 
 	debug_printk(("check for MIDI client %d port %d\n", pinfo->addr.client, pinfo->addr.port));
@@ -226,7 +226,7 @@
 int
 snd_seq_oss_midi_check_exit_port(int client, int port)
 {
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 	unsigned long flags;
 	int index;
 
@@ -258,7 +258,7 @@
 snd_seq_oss_midi_clear_all(void)
 {
 	int i;
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 	unsigned long flags;
 
 	spin_lock_irqsave(&register_lock, flags);
@@ -279,7 +279,7 @@
  * set up midi tables
  */
 void
-snd_seq_oss_midi_setup(seq_oss_devinfo_t *dp)
+snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp)
 {
 	dp->max_mididev = max_midi_devs;
 }
@@ -288,7 +288,7 @@
  * clean up midi tables
  */
 void
-snd_seq_oss_midi_cleanup(seq_oss_devinfo_t *dp)
+snd_seq_oss_midi_cleanup(struct seq_oss_devinfo *dp)
 {
 	int i;
 	for (i = 0; i < dp->max_mididev; i++)
@@ -301,7 +301,7 @@
  * open all midi devices.  ignore errors.
  */
 void
-snd_seq_oss_midi_open_all(seq_oss_devinfo_t *dp, int file_mode)
+snd_seq_oss_midi_open_all(struct seq_oss_devinfo *dp, int file_mode)
 {
 	int i;
 	for (i = 0; i < dp->max_mididev; i++)
@@ -312,8 +312,8 @@
 /*
  * get the midi device information
  */
-static seq_oss_midi_t *
-get_mididev(seq_oss_devinfo_t *dp, int dev)
+static struct seq_oss_midi *
+get_mididev(struct seq_oss_devinfo *dp, int dev)
 {
 	if (dev < 0 || dev >= dp->max_mididev)
 		return NULL;
@@ -325,11 +325,11 @@
  * open the midi device if not opened yet
  */
 int
-snd_seq_oss_midi_open(seq_oss_devinfo_t *dp, int dev, int fmode)
+snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int fmode)
 {
 	int perm;
-	seq_oss_midi_t *mdev;
-	snd_seq_port_subscribe_t subs;
+	struct seq_oss_midi *mdev;
+	struct snd_seq_port_subscribe subs;
 
 	if ((mdev = get_mididev(dp, dev)) == NULL)
 		return -ENODEV;
@@ -392,10 +392,10 @@
  * close the midi device if already opened
  */
 int
-snd_seq_oss_midi_close(seq_oss_devinfo_t *dp, int dev)
+snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev)
 {
-	seq_oss_midi_t *mdev;
-	snd_seq_port_subscribe_t subs;
+	struct seq_oss_midi *mdev;
+	struct snd_seq_port_subscribe subs;
 
 	if ((mdev = get_mididev(dp, dev)) == NULL)
 		return -ENODEV;
@@ -430,9 +430,9 @@
  * change seq capability flags to file mode flags
  */
 int
-snd_seq_oss_midi_filemode(seq_oss_devinfo_t *dp, int dev)
+snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev)
 {
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 	int mode;
 
 	if ((mdev = get_mididev(dp, dev)) == NULL)
@@ -453,9 +453,9 @@
  * so far, only close the device.
  */
 void
-snd_seq_oss_midi_reset(seq_oss_devinfo_t *dp, int dev)
+snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
 {
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 
 	if ((mdev = get_mididev(dp, dev)) == NULL)
 		return;
@@ -465,7 +465,7 @@
 	}
 
 	if (mdev->opened & PERM_WRITE) {
-		snd_seq_event_t ev;
+		struct snd_seq_event ev;
 		int c;
 
 		debug_printk(("resetting client %d port %d\n", mdev->client, mdev->port));
@@ -501,9 +501,9 @@
  * get client/port of the specified MIDI device
  */
 void
-snd_seq_oss_midi_get_addr(seq_oss_devinfo_t *dp, int dev, snd_seq_addr_t *addr)
+snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_addr *addr)
 {
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 
 	if ((mdev = get_mididev(dp, dev)) == NULL)
 		return;
@@ -517,10 +517,10 @@
  * input callback - this can be atomic
  */
 int
-snd_seq_oss_midi_input(snd_seq_event_t *ev, int direct, void *private_data)
+snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private_data)
 {
-	seq_oss_devinfo_t *dp = (seq_oss_devinfo_t *)private_data;
-	seq_oss_midi_t *mdev;
+	struct seq_oss_devinfo *dp = (struct seq_oss_devinfo *)private_data;
+	struct seq_oss_midi *mdev;
 	int rc;
 
 	if (dp->readq == NULL)
@@ -545,9 +545,9 @@
  * convert ALSA sequencer event to OSS synth event
  */
 static int
-send_synth_event(seq_oss_devinfo_t *dp, snd_seq_event_t *ev, int dev)
+send_synth_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, int dev)
 {
-	evrec_t ossev;
+	union evrec ossev;
 
 	memset(&ossev, 0, sizeof(ossev));
 
@@ -606,7 +606,7 @@
  * decode event and send MIDI bytes to read queue
  */
 static int
-send_midi_event(seq_oss_devinfo_t *dp, snd_seq_event_t *ev, seq_oss_midi_t *mdev)
+send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq_oss_midi *mdev)
 {
 	char msg[32];
 	int len;
@@ -634,9 +634,9 @@
  *        non-zero : invalid - ignored
  */
 int
-snd_seq_oss_midi_putc(seq_oss_devinfo_t *dp, int dev, unsigned char c, snd_seq_event_t *ev)
+snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c, struct snd_seq_event *ev)
 {
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 
 	if ((mdev = get_mididev(dp, dev)) == NULL)
 		return -ENODEV;
@@ -653,9 +653,9 @@
  * create OSS compatible midi_info record
  */
 int
-snd_seq_oss_midi_make_info(seq_oss_devinfo_t *dp, int dev, struct midi_info *inf)
+snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info *inf)
 {
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 
 	if ((mdev = get_mididev(dp, dev)) == NULL)
 		return -ENXIO;
@@ -668,6 +668,7 @@
 }
 
 
+#ifdef CONFIG_PROC_FS
 /*
  * proc interface
  */
@@ -686,10 +687,10 @@
 }
 
 void
-snd_seq_oss_midi_info_read(snd_info_buffer_t *buf)
+snd_seq_oss_midi_info_read(struct snd_info_buffer *buf)
 {
 	int i;
-	seq_oss_midi_t *mdev;
+	struct seq_oss_midi *mdev;
 
 	snd_iprintf(buf, "\nNumber of MIDI devices: %d\n", max_midi_devs);
 	for (i = 0; i < max_midi_devs; i++) {
@@ -707,4 +708,4 @@
 		snd_use_lock_free(&mdev->use_lock);
 	}
 }
-
+#endif /* CONFIG_PROC_FS */
diff --git a/sound/core/seq/oss/seq_oss_midi.h b/sound/core/seq/oss/seq_oss_midi.h
index 462484b..84eb866 100644
--- a/sound/core/seq/oss/seq_oss_midi.h
+++ b/sound/core/seq/oss/seq_oss_midi.h
@@ -26,24 +26,23 @@
 #include "seq_oss_device.h"
 #include <sound/seq_oss_legacy.h>
 
-typedef struct seq_oss_midi_t seq_oss_midi_t;
-
 int snd_seq_oss_midi_lookup_ports(int client);
-int snd_seq_oss_midi_check_new_port(snd_seq_port_info_t *pinfo);
+int snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo);
 int snd_seq_oss_midi_check_exit_port(int client, int port);
 void snd_seq_oss_midi_clear_all(void);
 
-void snd_seq_oss_midi_setup(seq_oss_devinfo_t *dp);
-void snd_seq_oss_midi_cleanup(seq_oss_devinfo_t *dp);
+void snd_seq_oss_midi_setup(struct seq_oss_devinfo *dp);
+void snd_seq_oss_midi_cleanup(struct seq_oss_devinfo *dp);
 
-int snd_seq_oss_midi_open(seq_oss_devinfo_t *dp, int dev, int file_mode);
-void snd_seq_oss_midi_open_all(seq_oss_devinfo_t *dp, int file_mode);
-int snd_seq_oss_midi_close(seq_oss_devinfo_t *dp, int dev);
-void snd_seq_oss_midi_reset(seq_oss_devinfo_t *dp, int dev);
-int snd_seq_oss_midi_putc(seq_oss_devinfo_t *dp, int dev, unsigned char c, snd_seq_event_t *ev);
-int snd_seq_oss_midi_input(snd_seq_event_t *ev, int direct, void *private);
-int snd_seq_oss_midi_filemode(seq_oss_devinfo_t *dp, int dev);
-int snd_seq_oss_midi_make_info(seq_oss_devinfo_t *dp, int dev, struct midi_info *inf);
-void snd_seq_oss_midi_get_addr(seq_oss_devinfo_t *dp, int dev, snd_seq_addr_t *addr);
+int snd_seq_oss_midi_open(struct seq_oss_devinfo *dp, int dev, int file_mode);
+void snd_seq_oss_midi_open_all(struct seq_oss_devinfo *dp, int file_mode);
+int snd_seq_oss_midi_close(struct seq_oss_devinfo *dp, int dev);
+void snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev);
+int snd_seq_oss_midi_putc(struct seq_oss_devinfo *dp, int dev, unsigned char c,
+			  struct snd_seq_event *ev);
+int snd_seq_oss_midi_input(struct snd_seq_event *ev, int direct, void *private);
+int snd_seq_oss_midi_filemode(struct seq_oss_devinfo *dp, int dev);
+int snd_seq_oss_midi_make_info(struct seq_oss_devinfo *dp, int dev, struct midi_info *inf);
+void snd_seq_oss_midi_get_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_addr *addr);
 
 #endif
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index 55571e1..f5de79f 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -41,17 +41,17 @@
 /*
  * create a read queue
  */
-seq_oss_readq_t *
-snd_seq_oss_readq_new(seq_oss_devinfo_t *dp, int maxlen)
+struct seq_oss_readq *
+snd_seq_oss_readq_new(struct seq_oss_devinfo *dp, int maxlen)
 {
-	seq_oss_readq_t *q;
+	struct seq_oss_readq *q;
 
 	if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL) {
 		snd_printk(KERN_ERR "can't malloc read queue\n");
 		return NULL;
 	}
 
-	if ((q->q = kcalloc(maxlen, sizeof(evrec_t), GFP_KERNEL)) == NULL) {
+	if ((q->q = kcalloc(maxlen, sizeof(union evrec), GFP_KERNEL)) == NULL) {
 		snd_printk(KERN_ERR "can't malloc read queue buffer\n");
 		kfree(q);
 		return NULL;
@@ -72,7 +72,7 @@
  * delete the read queue
  */
 void
-snd_seq_oss_readq_delete(seq_oss_readq_t *q)
+snd_seq_oss_readq_delete(struct seq_oss_readq *q)
 {
 	if (q) {
 		kfree(q->q);
@@ -84,7 +84,7 @@
  * reset the read queue
  */
 void
-snd_seq_oss_readq_clear(seq_oss_readq_t *q)
+snd_seq_oss_readq_clear(struct seq_oss_readq *q)
 {
 	if (q->qlen) {
 		q->qlen = 0;
@@ -100,9 +100,9 @@
  * put a midi byte
  */
 int
-snd_seq_oss_readq_puts(seq_oss_readq_t *q, int dev, unsigned char *data, int len)
+snd_seq_oss_readq_puts(struct seq_oss_readq *q, int dev, unsigned char *data, int len)
 {
-	evrec_t rec;
+	union evrec rec;
 	int result;
 
 	memset(&rec, 0, sizeof(rec));
@@ -123,7 +123,7 @@
  * return zero if enqueued
  */
 int
-snd_seq_oss_readq_put_event(seq_oss_readq_t *q, evrec_t *ev)
+snd_seq_oss_readq_put_event(struct seq_oss_readq *q, union evrec *ev)
 {
 	unsigned long flags;
 
@@ -152,7 +152,7 @@
  * caller must hold lock
  */
 int
-snd_seq_oss_readq_pick(seq_oss_readq_t *q, evrec_t *rec)
+snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec)
 {
 	if (q->qlen == 0)
 		return -EAGAIN;
@@ -164,7 +164,7 @@
  * sleep until ready
  */
 void
-snd_seq_oss_readq_wait(seq_oss_readq_t *q)
+snd_seq_oss_readq_wait(struct seq_oss_readq *q)
 {
 	wait_event_interruptible_timeout(q->midi_sleep,
 					 (q->qlen > 0 || q->head == q->tail),
@@ -176,7 +176,7 @@
  * caller must hold lock
  */
 void
-snd_seq_oss_readq_free(seq_oss_readq_t *q)
+snd_seq_oss_readq_free(struct seq_oss_readq *q)
 {
 	if (q->qlen > 0) {
 		q->head = (q->head + 1) % q->maxlen;
@@ -189,7 +189,7 @@
  * return non-zero if readq is not empty.
  */
 unsigned int
-snd_seq_oss_readq_poll(seq_oss_readq_t *q, struct file *file, poll_table *wait)
+snd_seq_oss_readq_poll(struct seq_oss_readq *q, struct file *file, poll_table *wait)
 {
 	poll_wait(file, &q->midi_sleep, wait);
 	return q->qlen;
@@ -199,10 +199,10 @@
  * put a timestamp
  */
 int
-snd_seq_oss_readq_put_timestamp(seq_oss_readq_t *q, unsigned long curt, int seq_mode)
+snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *q, unsigned long curt, int seq_mode)
 {
 	if (curt != q->input_time) {
-		evrec_t rec;
+		union evrec rec;
 		memset(&rec, 0, sizeof(rec));
 		switch (seq_mode) {
 		case SNDRV_SEQ_OSS_MODE_SYNTH:
@@ -222,13 +222,15 @@
 }
 
 
+#ifdef CONFIG_PROC_FS
 /*
  * proc interface
  */
 void
-snd_seq_oss_readq_info_read(seq_oss_readq_t *q, snd_info_buffer_t *buf)
+snd_seq_oss_readq_info_read(struct seq_oss_readq *q, struct snd_info_buffer *buf)
 {
 	snd_iprintf(buf, "  read queue [%s] length = %d : tick = %ld\n",
 		    (waitqueue_active(&q->midi_sleep) ? "sleeping":"running"),
 		    q->qlen, q->input_time);
 }
+#endif /* CONFIG_PROC_FS */
diff --git a/sound/core/seq/oss/seq_oss_readq.h b/sound/core/seq/oss/seq_oss_readq.h
index 303b929..f1463f1 100644
--- a/sound/core/seq/oss/seq_oss_readq.h
+++ b/sound/core/seq/oss/seq_oss_readq.h
@@ -28,8 +28,8 @@
 /*
  * definition of read queue
  */
-struct seq_oss_readq_t {
-	evrec_t *q;
+struct seq_oss_readq {
+	union evrec *q;
 	int qlen;
 	int maxlen;
 	int head, tail;
@@ -39,16 +39,16 @@
 	spinlock_t lock;
 };
 
-seq_oss_readq_t *snd_seq_oss_readq_new(seq_oss_devinfo_t *dp, int maxlen);
-void snd_seq_oss_readq_delete(seq_oss_readq_t *q);
-void snd_seq_oss_readq_clear(seq_oss_readq_t *readq);
-unsigned int snd_seq_oss_readq_poll(seq_oss_readq_t *readq, struct file *file, poll_table *wait);
-int snd_seq_oss_readq_puts(seq_oss_readq_t *readq, int dev, unsigned char *data, int len);
-int snd_seq_oss_readq_put_event(seq_oss_readq_t *readq, evrec_t *ev);
-int snd_seq_oss_readq_put_timestamp(seq_oss_readq_t *readq, unsigned long curt, int seq_mode);
-int snd_seq_oss_readq_pick(seq_oss_readq_t *q, evrec_t *rec);
-void snd_seq_oss_readq_wait(seq_oss_readq_t *q);
-void snd_seq_oss_readq_free(seq_oss_readq_t *q);
+struct seq_oss_readq *snd_seq_oss_readq_new(struct seq_oss_devinfo *dp, int maxlen);
+void snd_seq_oss_readq_delete(struct seq_oss_readq *q);
+void snd_seq_oss_readq_clear(struct seq_oss_readq *readq);
+unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait);
+int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len);
+int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev);
+int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode);
+int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec);
+void snd_seq_oss_readq_wait(struct seq_oss_readq *q);
+void snd_seq_oss_readq_free(struct seq_oss_readq *q);
 
 #define snd_seq_oss_readq_lock(q, flags) spin_lock_irqsave(&(q)->lock, flags)
 #define snd_seq_oss_readq_unlock(q, flags) spin_unlock_irqrestore(&(q)->lock, flags)
diff --git a/sound/core/seq/oss/seq_oss_rw.c b/sound/core/seq/oss/seq_oss_rw.c
index 1d8fbd2..6a7b6ac 100644
--- a/sound/core/seq/oss/seq_oss_rw.c
+++ b/sound/core/seq/oss/seq_oss_rw.c
@@ -33,7 +33,7 @@
 /*
  * protoypes
  */
-static int insert_queue(seq_oss_devinfo_t *dp, evrec_t *rec, struct file *opt);
+static int insert_queue(struct seq_oss_devinfo *dp, union evrec *rec, struct file *opt);
 
 
 /*
@@ -41,12 +41,12 @@
  */
 
 int
-snd_seq_oss_read(seq_oss_devinfo_t *dp, char __user *buf, int count)
+snd_seq_oss_read(struct seq_oss_devinfo *dp, char __user *buf, int count)
 {
-	seq_oss_readq_t *readq = dp->readq;
+	struct seq_oss_readq *readq = dp->readq;
 	int result = 0, err = 0;
 	int ev_len;
-	evrec_t rec;
+	union evrec rec;
 	unsigned long flags;
 
 	if (readq == NULL || ! is_read_mode(dp->file_mode))
@@ -93,11 +93,11 @@
  */
 
 int
-snd_seq_oss_write(seq_oss_devinfo_t *dp, const char __user *buf, int count, struct file *opt)
+snd_seq_oss_write(struct seq_oss_devinfo *dp, const char __user *buf, int count, struct file *opt)
 {
 	int result = 0, err = 0;
 	int ev_size, fmt;
-	evrec_t rec;
+	union evrec rec;
 
 	if (! is_write_mode(dp->file_mode) || dp->writeq == NULL)
 		return -ENXIO;
@@ -161,10 +161,10 @@
  * return: 0 = OK, non-zero = NG
  */
 static int
-insert_queue(seq_oss_devinfo_t *dp, evrec_t *rec, struct file *opt)
+insert_queue(struct seq_oss_devinfo *dp, union evrec *rec, struct file *opt)
 {
 	int rc = 0;
-	snd_seq_event_t event;
+	struct snd_seq_event event;
 
 	/* if this is a timing event, process the current time */
 	if (snd_seq_oss_process_timer_event(dp->timer, rec))
@@ -197,7 +197,7 @@
  */
   
 unsigned int
-snd_seq_oss_poll(seq_oss_devinfo_t *dp, struct file *file, poll_table * wait)
+snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait)
 {
 	unsigned int mask = 0;
 
diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c
index 8257fce..ab570a0 100644
--- a/sound/core/seq/oss/seq_oss_synth.c
+++ b/sound/core/seq/oss/seq_oss_synth.c
@@ -37,14 +37,14 @@
  */
 
 /* sysex buffer */
-struct seq_oss_synth_sysex_t {
+struct seq_oss_synth_sysex {
 	int len;
 	int skip;
 	unsigned char buf[MAX_SYSEX_BUFLEN];
 };
 
 /* synth info */
-struct seq_oss_synth_t {
+struct seq_oss_synth {
 	int seq_device;
 
 	/* for synth_info */
@@ -53,7 +53,7 @@
 	int nr_voices;
 
 	char name[SNDRV_SEQ_OSS_MAX_SYNTH_NAME];
-	snd_seq_oss_callback_t oper;
+	struct snd_seq_oss_callback oper;
 
 	int opened;
 
@@ -66,8 +66,8 @@
  * device table
  */
 static int max_synth_devs;
-static seq_oss_synth_t *synth_devs[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
-static seq_oss_synth_t midi_synth_dev = {
+static struct seq_oss_synth *synth_devs[SNDRV_SEQ_OSS_MAX_SYNTH_DEVS];
+static struct seq_oss_synth midi_synth_dev = {
 	-1, /* seq_device */
 	SYNTH_TYPE_MIDI, /* synth_type */
 	0, /* synth_subtype */
@@ -80,8 +80,8 @@
 /*
  * prototypes
  */
-static seq_oss_synth_t *get_synthdev(seq_oss_devinfo_t *dp, int dev);
-static void reset_channels(seq_oss_synthinfo_t *info);
+static struct seq_oss_synth *get_synthdev(struct seq_oss_devinfo *dp, int dev);
+static void reset_channels(struct seq_oss_synthinfo *info);
 
 /*
  * global initialization
@@ -96,11 +96,11 @@
  * registration of the synth device
  */
 int
-snd_seq_oss_synth_register(snd_seq_device_t *dev)
+snd_seq_oss_synth_register(struct snd_seq_device *dev)
 {
 	int i;
-	seq_oss_synth_t *rec;
-	snd_seq_oss_reg_t *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	struct seq_oss_synth *rec;
+	struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	unsigned long flags;
 
 	if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) {
@@ -148,10 +148,10 @@
 
 
 int
-snd_seq_oss_synth_unregister(snd_seq_device_t *dev)
+snd_seq_oss_synth_unregister(struct snd_seq_device *dev)
 {
 	int index;
-	seq_oss_synth_t *rec = dev->driver_data;
+	struct seq_oss_synth *rec = dev->driver_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&register_lock, flags);
@@ -187,10 +187,10 @@
 
 /*
  */
-static seq_oss_synth_t *
+static struct seq_oss_synth *
 get_sdev(int dev)
 {
-	seq_oss_synth_t *rec;
+	struct seq_oss_synth *rec;
 	unsigned long flags;
 
 	spin_lock_irqsave(&register_lock, flags);
@@ -207,11 +207,11 @@
  */
 
 void
-snd_seq_oss_synth_setup(seq_oss_devinfo_t *dp)
+snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp)
 {
 	int i;
-	seq_oss_synth_t *rec;
-	seq_oss_synthinfo_t *info;
+	struct seq_oss_synth *rec;
+	struct seq_oss_synthinfo *info;
 
 	dp->max_synthdev = max_synth_devs;
 	dp->synth_opened = 0;
@@ -244,7 +244,7 @@
 		}
 		info->nr_voices = rec->nr_voices;
 		if (info->nr_voices > 0) {
-			info->ch = kcalloc(info->nr_voices, sizeof(seq_oss_chinfo_t), GFP_KERNEL);
+			info->ch = kcalloc(info->nr_voices, sizeof(struct seq_oss_chinfo), GFP_KERNEL);
 			if (!info->ch)
 				BUG();
 			reset_channels(info);
@@ -263,7 +263,7 @@
  */
 
 void
-snd_seq_oss_synth_setup_midi(seq_oss_devinfo_t *dp)
+snd_seq_oss_synth_setup_midi(struct seq_oss_devinfo *dp)
 {
 	int i;
 
@@ -271,7 +271,7 @@
 		return;
 
 	for (i = 0; i < dp->max_mididev; i++) {
-		seq_oss_synthinfo_t *info;
+		struct seq_oss_synthinfo *info;
 		info = &dp->synths[dp->max_synthdev];
 		if (snd_seq_oss_midi_open(dp, i, dp->file_mode) < 0)
 			continue;
@@ -297,11 +297,11 @@
  */
 
 void
-snd_seq_oss_synth_cleanup(seq_oss_devinfo_t *dp)
+snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp)
 {
 	int i;
-	seq_oss_synth_t *rec;
-	seq_oss_synthinfo_t *info;
+	struct seq_oss_synth *rec;
+	struct seq_oss_synthinfo *info;
 
 	snd_assert(dp->max_synthdev <= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS, return);
 	for (i = 0; i < dp->max_synthdev; i++) {
@@ -338,7 +338,7 @@
  * check if the specified device is MIDI mapped device
  */
 static int
-is_midi_dev(seq_oss_devinfo_t *dp, int dev)
+is_midi_dev(struct seq_oss_devinfo *dp, int dev)
 {
 	if (dev < 0 || dev >= dp->max_synthdev)
 		return 0;
@@ -350,10 +350,10 @@
 /*
  * return synth device information pointer
  */
-static seq_oss_synth_t *
-get_synthdev(seq_oss_devinfo_t *dp, int dev)
+static struct seq_oss_synth *
+get_synthdev(struct seq_oss_devinfo *dp, int dev)
 {
-	seq_oss_synth_t *rec;
+	struct seq_oss_synth *rec;
 	if (dev < 0 || dev >= dp->max_synthdev)
 		return NULL;
 	if (! dp->synths[dev].opened)
@@ -374,7 +374,7 @@
  * reset note and velocity on each channel.
  */
 static void
-reset_channels(seq_oss_synthinfo_t *info)
+reset_channels(struct seq_oss_synthinfo *info)
 {
 	int i;
 	if (info->ch == NULL || ! info->nr_voices)
@@ -392,10 +392,10 @@
  * event to the corresponding port.
  */
 void
-snd_seq_oss_synth_reset(seq_oss_devinfo_t *dp, int dev)
+snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev)
 {
-	seq_oss_synth_t *rec;
-	seq_oss_synthinfo_t *info;
+	struct seq_oss_synth *rec;
+	struct seq_oss_synthinfo *info;
 
 	snd_assert(dev >= 0 && dev < dp->max_synthdev, return);
 	info = &dp->synths[dev];
@@ -428,7 +428,7 @@
 	if (rec->oper.reset) {
 		rec->oper.reset(&info->arg);
 	} else {
-		snd_seq_event_t ev;
+		struct snd_seq_event ev;
 		memset(&ev, 0, sizeof(ev));
 		snd_seq_oss_fill_addr(dp, &ev, info->arg.addr.client,
 				      info->arg.addr.port);
@@ -444,10 +444,10 @@
  * call load_patch callback function
  */
 int
-snd_seq_oss_synth_load_patch(seq_oss_devinfo_t *dp, int dev, int fmt,
+snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
 			    const char __user *buf, int p, int c)
 {
-	seq_oss_synth_t *rec;
+	struct seq_oss_synth *rec;
 	int rc;
 
 	if (dev < 0 || dev >= dp->max_synthdev)
@@ -470,9 +470,9 @@
  * check if the device is valid synth device
  */
 int
-snd_seq_oss_synth_is_valid(seq_oss_devinfo_t *dp, int dev)
+snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev)
 {
-	seq_oss_synth_t *rec;
+	struct seq_oss_synth *rec;
 	rec = get_synthdev(dp, dev);
 	if (rec) {
 		snd_use_lock_free(&rec->use_lock);
@@ -488,11 +488,11 @@
  * (0xff).
  */
 int
-snd_seq_oss_synth_sysex(seq_oss_devinfo_t *dp, int dev, unsigned char *buf, snd_seq_event_t *ev)
+snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf, struct snd_seq_event *ev)
 {
 	int i, send;
 	unsigned char *dest;
-	seq_oss_synth_sysex_t *sysex;
+	struct seq_oss_synth_sysex *sysex;
 
 	if (! snd_seq_oss_synth_is_valid(dp, dev))
 		return -ENXIO;
@@ -545,7 +545,7 @@
  * fill the event source/destination addresses
  */
 int
-snd_seq_oss_synth_addr(seq_oss_devinfo_t *dp, int dev, snd_seq_event_t *ev)
+snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
 {
 	if (! snd_seq_oss_synth_is_valid(dp, dev))
 		return -EINVAL;
@@ -559,9 +559,9 @@
  * OSS compatible ioctl
  */
 int
-snd_seq_oss_synth_ioctl(seq_oss_devinfo_t *dp, int dev, unsigned int cmd, unsigned long addr)
+snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
 {
-	seq_oss_synth_t *rec;
+	struct seq_oss_synth *rec;
 	int rc;
 
 	if (is_midi_dev(dp, dev))
@@ -581,7 +581,7 @@
  * send OSS raw events - SEQ_PRIVATE and SEQ_VOLUME
  */
 int
-snd_seq_oss_synth_raw_event(seq_oss_devinfo_t *dp, int dev, unsigned char *data, snd_seq_event_t *ev)
+snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
 {
 	if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev))
 		return -ENXIO;
@@ -595,9 +595,9 @@
  * create OSS compatible synth_info record
  */
 int
-snd_seq_oss_synth_make_info(seq_oss_devinfo_t *dp, int dev, struct synth_info *inf)
+snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_info *inf)
 {
-	seq_oss_synth_t *rec;
+	struct seq_oss_synth *rec;
 
 	if (dp->synths[dev].is_midi) {
 		struct midi_info minf;
@@ -621,14 +621,15 @@
 }
 
 
+#ifdef CONFIG_PROC_FS
 /*
  * proc interface
  */
 void
-snd_seq_oss_synth_info_read(snd_info_buffer_t *buf)
+snd_seq_oss_synth_info_read(struct snd_info_buffer *buf)
 {
 	int i;
-	seq_oss_synth_t *rec;
+	struct seq_oss_synth *rec;
 
 	snd_iprintf(buf, "\nNumber of synth devices: %d\n", max_synth_devs);
 	for (i = 0; i < max_synth_devs; i++) {
@@ -648,4 +649,4 @@
 		snd_use_lock_free(&rec->use_lock);
 	}
 }
-
+#endif /* CONFIG_PROC_FS */
diff --git a/sound/core/seq/oss/seq_oss_synth.h b/sound/core/seq/oss/seq_oss_synth.h
index 07bc0e2..dbdfcbb 100644
--- a/sound/core/seq/oss/seq_oss_synth.h
+++ b/sound/core/seq/oss/seq_oss_synth.h
@@ -27,23 +27,25 @@
 #include <sound/seq_oss_legacy.h>
 #include <sound/seq_device.h>
 
-typedef struct seq_oss_synth_t seq_oss_synth_t;
-
 void snd_seq_oss_synth_init(void);
-int snd_seq_oss_synth_register(snd_seq_device_t *dev);
-int snd_seq_oss_synth_unregister(snd_seq_device_t *dev);
-void snd_seq_oss_synth_setup(seq_oss_devinfo_t *dp);
-void snd_seq_oss_synth_setup_midi(seq_oss_devinfo_t *dp);
-void snd_seq_oss_synth_cleanup(seq_oss_devinfo_t *dp);
+int snd_seq_oss_synth_register(struct snd_seq_device *dev);
+int snd_seq_oss_synth_unregister(struct snd_seq_device *dev);
+void snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp);
+void snd_seq_oss_synth_setup_midi(struct seq_oss_devinfo *dp);
+void snd_seq_oss_synth_cleanup(struct seq_oss_devinfo *dp);
 
-void snd_seq_oss_synth_reset(seq_oss_devinfo_t *dp, int dev);
-int snd_seq_oss_synth_load_patch(seq_oss_devinfo_t *dp, int dev, int fmt, const char __user *buf, int p, int c);
-int snd_seq_oss_synth_is_valid(seq_oss_devinfo_t *dp, int dev);
-int snd_seq_oss_synth_sysex(seq_oss_devinfo_t *dp, int dev, unsigned char *buf, snd_seq_event_t *ev);
-int snd_seq_oss_synth_addr(seq_oss_devinfo_t *dp, int dev, snd_seq_event_t *ev);
-int snd_seq_oss_synth_ioctl(seq_oss_devinfo_t *dp, int dev, unsigned int cmd, unsigned long addr);
-int snd_seq_oss_synth_raw_event(seq_oss_devinfo_t *dp, int dev, unsigned char *data, snd_seq_event_t *ev);
+void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev);
+int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
+				 const char __user *buf, int p, int c);
+int snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev);
+int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
+			    struct snd_seq_event *ev);
+int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev);
+int snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd,
+			    unsigned long addr);
+int snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev,
+				unsigned char *data, struct snd_seq_event *ev);
 
-int snd_seq_oss_synth_make_info(seq_oss_devinfo_t *dp, int dev, struct synth_info *inf);
+int snd_seq_oss_synth_make_info(struct seq_oss_devinfo *dp, int dev, struct synth_info *inf);
 
 #endif
diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c
index 64d594b..c440fda 100644
--- a/sound/core/seq/oss/seq_oss_timer.c
+++ b/sound/core/seq/oss/seq_oss_timer.c
@@ -33,18 +33,18 @@
 
 /*
  */
-static void calc_alsa_tempo(seq_oss_timer_t *timer);
-static int send_timer_event(seq_oss_devinfo_t *dp, int type, int value);
+static void calc_alsa_tempo(struct seq_oss_timer *timer);
+static int send_timer_event(struct seq_oss_devinfo *dp, int type, int value);
 
 
 /*
  * create and register a new timer.
  * if queue is not started yet, start it.
  */
-seq_oss_timer_t *
-snd_seq_oss_timer_new(seq_oss_devinfo_t *dp)
+struct seq_oss_timer *
+snd_seq_oss_timer_new(struct seq_oss_devinfo *dp)
 {
-	seq_oss_timer_t *rec;
+	struct seq_oss_timer *rec;
 
 	rec = kzalloc(sizeof(*rec), GFP_KERNEL);
 	if (rec == NULL)
@@ -67,7 +67,7 @@
  * if no more timer exists, stop the queue.
  */
 void
-snd_seq_oss_timer_delete(seq_oss_timer_t *rec)
+snd_seq_oss_timer_delete(struct seq_oss_timer *rec)
 {
 	if (rec) {
 		snd_seq_oss_timer_stop(rec);
@@ -82,7 +82,7 @@
  *        0 : not a timer event -- enqueue this event
  */
 int
-snd_seq_oss_process_timer_event(seq_oss_timer_t *rec, evrec_t *ev)
+snd_seq_oss_process_timer_event(struct seq_oss_timer *rec, union evrec *ev)
 {
 	abstime_t parm = ev->t.time;
 
@@ -125,7 +125,7 @@
  * convert tempo units
  */
 static void
-calc_alsa_tempo(seq_oss_timer_t *timer)
+calc_alsa_tempo(struct seq_oss_timer *timer)
 {
 	timer->tempo = (60 * 1000000) / timer->oss_tempo;
 	timer->ppq = timer->oss_timebase;
@@ -136,9 +136,9 @@
  * dispatch a timer event
  */
 static int
-send_timer_event(seq_oss_devinfo_t *dp, int type, int value)
+send_timer_event(struct seq_oss_devinfo *dp, int type, int value)
 {
-	snd_seq_event_t ev;
+	struct snd_seq_event ev;
 
 	memset(&ev, 0, sizeof(ev));
 	ev.type = type;
@@ -156,10 +156,10 @@
  * set queue tempo and start queue
  */
 int
-snd_seq_oss_timer_start(seq_oss_timer_t *timer)
+snd_seq_oss_timer_start(struct seq_oss_timer *timer)
 {
-	seq_oss_devinfo_t *dp = timer->dp;
-	snd_seq_queue_tempo_t tmprec;
+	struct seq_oss_devinfo *dp = timer->dp;
+	struct snd_seq_queue_tempo tmprec;
 
 	if (timer->running)
 		snd_seq_oss_timer_stop(timer);
@@ -181,7 +181,7 @@
  * stop queue
  */
 int
-snd_seq_oss_timer_stop(seq_oss_timer_t *timer)
+snd_seq_oss_timer_stop(struct seq_oss_timer *timer)
 {
 	if (! timer->running)
 		return 0;
@@ -195,7 +195,7 @@
  * continue queue
  */
 int
-snd_seq_oss_timer_continue(seq_oss_timer_t *timer)
+snd_seq_oss_timer_continue(struct seq_oss_timer *timer)
 {
 	if (timer->running)
 		return 0;
@@ -209,7 +209,7 @@
  * change queue tempo
  */
 int
-snd_seq_oss_timer_tempo(seq_oss_timer_t *timer, int value)
+snd_seq_oss_timer_tempo(struct seq_oss_timer *timer, int value)
 {
 	if (value < MIN_OSS_TEMPO)
 		value = MIN_OSS_TEMPO;
@@ -227,7 +227,7 @@
  * ioctls
  */
 int
-snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, int __user *arg)
+snd_seq_oss_timer_ioctl(struct seq_oss_timer *timer, unsigned int cmd, int __user *arg)
 {
 	int value;
 
diff --git a/sound/core/seq/oss/seq_oss_timer.h b/sound/core/seq/oss/seq_oss_timer.h
index 6e4dbd8..b995bd6 100644
--- a/sound/core/seq/oss/seq_oss_timer.h
+++ b/sound/core/seq/oss/seq_oss_timer.h
@@ -27,8 +27,8 @@
 /*
  * timer information definition
  */
-struct seq_oss_timer_t {
-	seq_oss_devinfo_t *dp;
+struct seq_oss_timer {
+	struct seq_oss_devinfo *dp;
 	reltime_t cur_tick;
 	int realtime;
 	int running;
@@ -37,22 +37,22 @@
 };	
 
 
-seq_oss_timer_t *snd_seq_oss_timer_new(seq_oss_devinfo_t *dp);
-void snd_seq_oss_timer_delete(seq_oss_timer_t *dp);
+struct seq_oss_timer *snd_seq_oss_timer_new(struct seq_oss_devinfo *dp);
+void snd_seq_oss_timer_delete(struct seq_oss_timer *dp);
 
-int snd_seq_oss_timer_start(seq_oss_timer_t *timer);
-int snd_seq_oss_timer_stop(seq_oss_timer_t *timer);
-int snd_seq_oss_timer_continue(seq_oss_timer_t *timer);
-int snd_seq_oss_timer_tempo(seq_oss_timer_t *timer, int value);
+int snd_seq_oss_timer_start(struct seq_oss_timer *timer);
+int snd_seq_oss_timer_stop(struct seq_oss_timer *timer);
+int snd_seq_oss_timer_continue(struct seq_oss_timer *timer);
+int snd_seq_oss_timer_tempo(struct seq_oss_timer *timer, int value);
 #define snd_seq_oss_timer_reset  snd_seq_oss_timer_start
 
-int snd_seq_oss_timer_ioctl(seq_oss_timer_t *timer, unsigned int cmd, int __user *arg);
+int snd_seq_oss_timer_ioctl(struct seq_oss_timer *timer, unsigned int cmd, int __user *arg);
 
 /*
  * get current processed time
  */
 static inline abstime_t
-snd_seq_oss_timer_cur_tick(seq_oss_timer_t *timer)
+snd_seq_oss_timer_cur_tick(struct seq_oss_timer *timer)
 {
 	return timer->cur_tick;
 }
@@ -62,7 +62,7 @@
  * is realtime event?
  */
 static inline int
-snd_seq_oss_timer_is_realtime(seq_oss_timer_t *timer)
+snd_seq_oss_timer_is_realtime(struct seq_oss_timer *timer)
 {
 	return timer->realtime;
 }
diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c
index b203780..5c84956 100644
--- a/sound/core/seq/oss/seq_oss_writeq.c
+++ b/sound/core/seq/oss/seq_oss_writeq.c
@@ -32,11 +32,11 @@
 /*
  * create a write queue record
  */
-seq_oss_writeq_t *
-snd_seq_oss_writeq_new(seq_oss_devinfo_t *dp, int maxlen)
+struct seq_oss_writeq *
+snd_seq_oss_writeq_new(struct seq_oss_devinfo *dp, int maxlen)
 {
-	seq_oss_writeq_t *q;
-	snd_seq_client_pool_t pool;
+	struct seq_oss_writeq *q;
+	struct snd_seq_client_pool pool;
 
 	if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL)
 		return NULL;
@@ -61,7 +61,7 @@
  * delete the write queue
  */
 void
-snd_seq_oss_writeq_delete(seq_oss_writeq_t *q)
+snd_seq_oss_writeq_delete(struct seq_oss_writeq *q)
 {
 	snd_seq_oss_writeq_clear(q);	/* to be sure */
 	kfree(q);
@@ -72,9 +72,9 @@
  * reset the write queue
  */
 void
-snd_seq_oss_writeq_clear(seq_oss_writeq_t *q)
+snd_seq_oss_writeq_clear(struct seq_oss_writeq *q)
 {
-	snd_seq_remove_events_t reset;
+	struct snd_seq_remove_events reset;
 
 	memset(&reset, 0, sizeof(reset));
 	reset.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT; /* remove all */
@@ -88,9 +88,9 @@
  * wait until the write buffer has enough room
  */
 int
-snd_seq_oss_writeq_sync(seq_oss_writeq_t *q)
+snd_seq_oss_writeq_sync(struct seq_oss_writeq *q)
 {
-	seq_oss_devinfo_t *dp = q->dp;
+	struct seq_oss_devinfo *dp = q->dp;
 	abstime_t time;
 
 	time = snd_seq_oss_timer_cur_tick(dp->timer);
@@ -98,8 +98,8 @@
 		return 0; /* already finished */
 
 	if (! q->sync_event_put) {
-		snd_seq_event_t ev;
-		evrec_t *rec;
+		struct snd_seq_event ev;
+		union evrec *rec;
 
 		/* put echoback event */
 		memset(&ev, 0, sizeof(ev));
@@ -108,7 +108,7 @@
 		ev.time.tick = time;
 		/* echo back to itself */
 		snd_seq_oss_fill_addr(dp, &ev, dp->addr.client, dp->addr.port);
-		rec = (evrec_t*)&ev.data;
+		rec = (union evrec *)&ev.data;
 		rec->t.code = SEQ_SYNCTIMER;
 		rec->t.time = time;
 		q->sync_event_put = 1;
@@ -128,7 +128,7 @@
  * wake up sync - echo event was catched
  */
 void
-snd_seq_oss_writeq_wakeup(seq_oss_writeq_t *q, abstime_t time)
+snd_seq_oss_writeq_wakeup(struct seq_oss_writeq *q, abstime_t time)
 {
 	unsigned long flags;
 
@@ -146,9 +146,9 @@
  * return the unused pool size
  */
 int
-snd_seq_oss_writeq_get_free_size(seq_oss_writeq_t *q)
+snd_seq_oss_writeq_get_free_size(struct seq_oss_writeq *q)
 {
-	snd_seq_client_pool_t pool;
+	struct snd_seq_client_pool pool;
 	pool.client = q->dp->cseq;
 	snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, &pool);
 	return pool.output_free;
@@ -159,9 +159,9 @@
  * set output threshold size from ioctl
  */
 void
-snd_seq_oss_writeq_set_output(seq_oss_writeq_t *q, int val)
+snd_seq_oss_writeq_set_output(struct seq_oss_writeq *q, int val)
 {
-	snd_seq_client_pool_t pool;
+	struct snd_seq_client_pool pool;
 	pool.client = q->dp->cseq;
 	snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, &pool);
 	pool.output_room = val;
diff --git a/sound/core/seq/oss/seq_oss_writeq.h b/sound/core/seq/oss/seq_oss_writeq.h
index 6a13c85..c469d29 100644
--- a/sound/core/seq/oss/seq_oss_writeq.h
+++ b/sound/core/seq/oss/seq_oss_writeq.h
@@ -25,8 +25,8 @@
 #include "seq_oss_device.h"
 
 
-struct seq_oss_writeq_t {
-	seq_oss_devinfo_t *dp;
+struct seq_oss_writeq {
+	struct seq_oss_devinfo *dp;
 	int maxlen;
 	abstime_t sync_time;
 	int sync_event_put;
@@ -38,13 +38,13 @@
 /*
  * seq_oss_writeq.c
  */
-seq_oss_writeq_t *snd_seq_oss_writeq_new(seq_oss_devinfo_t *dp, int maxlen);
-void snd_seq_oss_writeq_delete(seq_oss_writeq_t *q);
-void snd_seq_oss_writeq_clear(seq_oss_writeq_t *q);
-int snd_seq_oss_writeq_sync(seq_oss_writeq_t *q);
-void snd_seq_oss_writeq_wakeup(seq_oss_writeq_t *q, abstime_t time);
-int snd_seq_oss_writeq_get_free_size(seq_oss_writeq_t *q);
-void snd_seq_oss_writeq_set_output(seq_oss_writeq_t *q, int size);
+struct seq_oss_writeq *snd_seq_oss_writeq_new(struct seq_oss_devinfo *dp, int maxlen);
+void snd_seq_oss_writeq_delete(struct seq_oss_writeq *q);
+void snd_seq_oss_writeq_clear(struct seq_oss_writeq *q);
+int snd_seq_oss_writeq_sync(struct seq_oss_writeq *q);
+void snd_seq_oss_writeq_wakeup(struct seq_oss_writeq *q, abstime_t time);
+int snd_seq_oss_writeq_get_free_size(struct seq_oss_writeq *q);
+void snd_seq_oss_writeq_set_output(struct seq_oss_writeq *q, int size);
 
 
 #endif
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index 24644150..20f954b 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -36,9 +36,9 @@
 #include <sound/seq_device.h>
 
 #if defined(CONFIG_SND_SEQ_DUMMY_MODULE)
-int seq_client_load[64] = {[0] = SNDRV_SEQ_CLIENT_DUMMY, [1 ... 63] = -1};
+int seq_client_load[15] = {[0] = SNDRV_SEQ_CLIENT_DUMMY, [1 ... 14] = -1};
 #else
-int seq_client_load[64] = {[0 ... 63] = -1};
+int seq_client_load[15] = {[0 ... 14] = -1};
 #endif
 int seq_default_timer_class = SNDRV_TIMER_CLASS_GLOBAL;
 int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE;
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index a886db9..fd2032e 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -47,6 +47,21 @@
  * 
  */
 
+/*
+ * There are four ranges of client numbers (last two shared):
+ * 0..15: global clients
+ * 16..127: statically allocated client numbers for cards 0..27
+ * 128..191: dynamically allocated client numbers for cards 28..31
+ * 128..191: dynamically allocated client numbers for applications
+ */
+
+/* number of kernel non-card clients */
+#define SNDRV_SEQ_GLOBAL_CLIENTS	16
+/* clients per cards, for static clients */
+#define SNDRV_SEQ_CLIENTS_PER_CARD	4
+/* dynamically allocated client numbers (both kernel drivers and user space) */
+#define SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN	128
+
 #define SNDRV_SEQ_LFLG_INPUT	0x0001
 #define SNDRV_SEQ_LFLG_OUTPUT	0x0002
 #define SNDRV_SEQ_LFLG_OPEN	(SNDRV_SEQ_LFLG_INPUT|SNDRV_SEQ_LFLG_OUTPUT)
@@ -58,14 +73,18 @@
  * client table
  */
 static char clienttablock[SNDRV_SEQ_MAX_CLIENTS];
-static client_t *clienttab[SNDRV_SEQ_MAX_CLIENTS];
-static usage_t client_usage;
+static struct snd_seq_client *clienttab[SNDRV_SEQ_MAX_CLIENTS];
+static struct snd_seq_usage client_usage;
 
 /*
  * prototypes
  */
-static int bounce_error_event(client_t *client, snd_seq_event_t *event, int err, int atomic, int hop);
-static int snd_seq_deliver_single_event(client_t *client, snd_seq_event_t *event, int filter, int atomic, int hop);
+static int bounce_error_event(struct snd_seq_client *client,
+			      struct snd_seq_event *event,
+			      int err, int atomic, int hop);
+static int snd_seq_deliver_single_event(struct snd_seq_client *client,
+					struct snd_seq_event *event,
+					int filter, int atomic, int hop);
 
 /*
  */
@@ -96,16 +115,17 @@
         }
 }
 
-static inline int snd_seq_write_pool_allocated(client_t *client)
+static inline int snd_seq_write_pool_allocated(struct snd_seq_client *client)
 {
 	return snd_seq_total_cells(client->pool) > 0;
 }
 
 /* return pointer to client structure for specified id */
-static client_t *clientptr(int clientid)
+static struct snd_seq_client *clientptr(int clientid)
 {
 	if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
-		snd_printd("Seq: oops. Trying to get pointer to client %d\n", clientid);
+		snd_printd("Seq: oops. Trying to get pointer to client %d\n",
+			   clientid);
 		return NULL;
 	}
 	return clienttab[clientid];
@@ -113,13 +133,14 @@
 
 extern int seq_client_load[];
 
-client_t *snd_seq_client_use_ptr(int clientid)
+struct snd_seq_client *snd_seq_client_use_ptr(int clientid)
 {
 	unsigned long flags;
-	client_t *client;
+	struct snd_seq_client *client;
 
 	if (clientid < 0 || clientid >= SNDRV_SEQ_MAX_CLIENTS) {
-		snd_printd("Seq: oops. Trying to get pointer to client %d\n", clientid);
+		snd_printd("Seq: oops. Trying to get pointer to client %d\n",
+			   clientid);
 		return NULL;
 	}
 	spin_lock_irqsave(&clients_lock, flags);
@@ -133,24 +154,26 @@
 	spin_unlock_irqrestore(&clients_lock, flags);
 #ifdef CONFIG_KMOD
 	if (!in_interrupt() && current->fs->root) {
-		static char client_requested[64];
+		static char client_requested[SNDRV_SEQ_GLOBAL_CLIENTS];
 		static char card_requested[SNDRV_CARDS];
-		if (clientid < 64) {
+		if (clientid < SNDRV_SEQ_GLOBAL_CLIENTS) {
 			int idx;
 			
 			if (! client_requested[clientid] && current->fs->root) {
 				client_requested[clientid] = 1;
-				for (idx = 0; idx < 64; idx++) {
+				for (idx = 0; idx < 15; idx++) {
 					if (seq_client_load[idx] < 0)
 						break;
 					if (seq_client_load[idx] == clientid) {
-						request_module("snd-seq-client-%i", clientid);
+						request_module("snd-seq-client-%i",
+							       clientid);
 						break;
 					}
 				}
 			}
-		} else if (clientid >= 64 && clientid < 128) {
-			int card = (clientid - 64) / 8;
+		} else if (clientid < SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN) {
+			int card = (clientid - SNDRV_SEQ_GLOBAL_CLIENTS) /
+				SNDRV_SEQ_CLIENTS_PER_CARD;
 			if (card < snd_ecards_limit) {
 				if (! card_requested[card]) {
 					card_requested[card] = 1;
@@ -174,14 +197,14 @@
 	return client;
 }
 
-static void usage_alloc(usage_t * res, int num)
+static void usage_alloc(struct snd_seq_usage *res, int num)
 {
 	res->cur += num;
 	if (res->cur > res->peak)
 		res->peak = res->cur;
 }
 
-static void usage_free(usage_t * res, int num)
+static void usage_free(struct snd_seq_usage *res, int num)
 {
 	res->cur -= num;
 }
@@ -196,11 +219,11 @@
 }
 
 
-static client_t *seq_create_client1(int client_index, int poolsize)
+static struct snd_seq_client *seq_create_client1(int client_index, int poolsize)
 {
 	unsigned long flags;
 	int c;
-	client_t *client;
+	struct snd_seq_client *client;
 
 	/* init client data */
 	client = kzalloc(sizeof(*client), GFP_KERNEL);
@@ -220,7 +243,9 @@
 	/* find free slot in the client table */
 	spin_lock_irqsave(&clients_lock, flags);
 	if (client_index < 0) {
-		for (c = 128; c < SNDRV_SEQ_MAX_CLIENTS; c++) {
+		for (c = SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN;
+		     c < SNDRV_SEQ_MAX_CLIENTS;
+		     c++) {
 			if (clienttab[c] || clienttablock[c])
 				continue;
 			clienttab[client->number = c] = client;
@@ -241,7 +266,7 @@
 }
 
 
-static int seq_free_client1(client_t *client)
+static int seq_free_client1(struct snd_seq_client *client)
 {
 	unsigned long flags;
 
@@ -263,12 +288,13 @@
 }
 
 
-static void seq_free_client(client_t * client)
+static void seq_free_client(struct snd_seq_client * client)
 {
 	down(&register_mutex);
 	switch (client->type) {
 	case NO_CLIENT:
-		snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n", client->number);
+		snd_printk(KERN_WARNING "Seq: Trying to free unused client %d\n",
+			   client->number);
 		break;
 	case USER_CLIENT:
 	case KERNEL_CLIENT:
@@ -277,7 +303,8 @@
 		break;
 
 	default:
-		snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n", client->number, client->type);
+		snd_printk(KERN_ERR "Seq: Trying to free client %d with undefined type = %d\n",
+			   client->number, client->type);
 	}
 	up(&register_mutex);
 
@@ -292,8 +319,8 @@
 static int snd_seq_open(struct inode *inode, struct file *file)
 {
 	int c, mode;			/* client id */
-	client_t *client;
-	user_client_t *user;
+	struct snd_seq_client *client;
+	struct snd_seq_user_client *user;
 
 	if (down_interruptible(&register_mutex))
 		return -ERESTARTSYS;
@@ -344,7 +371,7 @@
 /* delete a user client */
 static int snd_seq_release(struct inode *inode, struct file *file)
 {
-	client_t *client = (client_t *) file->private_data;
+	struct snd_seq_client *client = file->private_data;
 
 	if (client) {
 		seq_free_client(client);
@@ -364,13 +391,14 @@
  *	-EINVAL	no enough user-space buffer to write the whole event
  *	-EFAULT	seg. fault during copy to user space
  */
-static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
+static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
+			    loff_t *offset)
 {
-	client_t *client = (client_t *) file->private_data;
-	fifo_t *fifo;
+	struct snd_seq_client *client = file->private_data;
+	struct snd_seq_fifo *fifo;
 	int err;
 	long result = 0;
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 
 	if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_INPUT))
 		return -ENXIO;
@@ -396,7 +424,7 @@
 	snd_seq_fifo_lock(fifo);
 
 	/* while data available in queue */
-	while (count >= sizeof(snd_seq_event_t)) {
+	while (count >= sizeof(struct snd_seq_event)) {
 		int nonblock;
 
 		nonblock = (file->f_flags & O_NONBLOCK) || result > 0;
@@ -404,34 +432,34 @@
 			break;
 		}
 		if (snd_seq_ev_is_variable(&cell->event)) {
-			snd_seq_event_t tmpev;
+			struct snd_seq_event tmpev;
 			tmpev = cell->event;
 			tmpev.data.ext.len &= ~SNDRV_SEQ_EXT_MASK;
-			if (copy_to_user(buf, &tmpev, sizeof(snd_seq_event_t))) {
+			if (copy_to_user(buf, &tmpev, sizeof(struct snd_seq_event))) {
 				err = -EFAULT;
 				break;
 			}
-			count -= sizeof(snd_seq_event_t);
-			buf += sizeof(snd_seq_event_t);
+			count -= sizeof(struct snd_seq_event);
+			buf += sizeof(struct snd_seq_event);
 			err = snd_seq_expand_var_event(&cell->event, count,
 						       (char __force *)buf, 0,
-						       sizeof(snd_seq_event_t));
+						       sizeof(struct snd_seq_event));
 			if (err < 0)
 				break;
 			result += err;
 			count -= err;
 			buf += err;
 		} else {
-			if (copy_to_user(buf, &cell->event, sizeof(snd_seq_event_t))) {
+			if (copy_to_user(buf, &cell->event, sizeof(struct snd_seq_event))) {
 				err = -EFAULT;
 				break;
 			}
-			count -= sizeof(snd_seq_event_t);
-			buf += sizeof(snd_seq_event_t);
+			count -= sizeof(struct snd_seq_event);
+			buf += sizeof(struct snd_seq_event);
 		}
 		snd_seq_cell_free(cell);
 		cell = NULL; /* to be sure */
-		result += sizeof(snd_seq_event_t);
+		result += sizeof(struct snd_seq_event);
 	}
 
 	if (err < 0) {
@@ -449,7 +477,7 @@
 /*
  * check access permission to the port
  */
-static int check_port_perm(client_port_t *port, unsigned int flags)
+static int check_port_perm(struct snd_seq_client_port *port, unsigned int flags)
 {
 	if ((port->capability & flags) != flags)
 		return 0;
@@ -460,9 +488,10 @@
  * check if the destination client is available, and return the pointer
  * if filter is non-zero, client filter bitmap is tested.
  */
-static client_t *get_event_dest_client(snd_seq_event_t *event, int filter)
+static struct snd_seq_client *get_event_dest_client(struct snd_seq_event *event,
+						    int filter)
 {
-	client_t *dest;
+	struct snd_seq_client *dest;
 
 	dest = snd_seq_client_use_ptr(event->dest.client);
 	if (dest == NULL)
@@ -493,10 +522,11 @@
  * quoted in SNDRV_SEQ_EVENT_KERNEL_ERROR, since this requires no extra
  * kmalloc.
  */
-static int bounce_error_event(client_t *client, snd_seq_event_t *event,
+static int bounce_error_event(struct snd_seq_client *client,
+			      struct snd_seq_event *event,
 			      int err, int atomic, int hop)
 {
-	snd_seq_event_t bounce_ev;
+	struct snd_seq_event bounce_ev;
 	int result;
 
 	if (client == NULL ||
@@ -531,9 +561,10 @@
  * of the given queue.
  * return non-zero if updated.
  */
-static int update_timestamp_of_queue(snd_seq_event_t *event, int queue, int real_time)
+static int update_timestamp_of_queue(struct snd_seq_event *event,
+				     int queue, int real_time)
 {
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	q = queueptr(queue);
 	if (! q)
@@ -559,12 +590,12 @@
  *  RETURN VALUE: 0 : if succeeded
  *		 <0 : error
  */
-static int snd_seq_deliver_single_event(client_t *client,
-					snd_seq_event_t *event,
+static int snd_seq_deliver_single_event(struct snd_seq_client *client,
+					struct snd_seq_event *event,
 					int filter, int atomic, int hop)
 {
-	client_t *dest = NULL;
-	client_port_t *dest_port = NULL;
+	struct snd_seq_client *dest = NULL;
+	struct snd_seq_client_port *dest_port = NULL;
 	int result = -ENOENT;
 	int direct;
 
@@ -596,7 +627,9 @@
 	case KERNEL_CLIENT:
 		if (dest_port->event_input == NULL)
 			break;
-		result = dest_port->event_input(event, direct, dest_port->private_data, atomic, hop);
+		result = dest_port->event_input(event, direct,
+						dest_port->private_data,
+						atomic, hop);
 		break;
 	default:
 		break;
@@ -618,16 +651,16 @@
 /*
  * send the event to all subscribers:
  */
-static int deliver_to_subscribers(client_t *client,
-				  snd_seq_event_t *event,
+static int deliver_to_subscribers(struct snd_seq_client *client,
+				  struct snd_seq_event *event,
 				  int atomic, int hop)
 {
-	subscribers_t *subs;
+	struct snd_seq_subscribers *subs;
 	int err = 0, num_ev = 0;
-	snd_seq_event_t event_saved;
-	client_port_t *src_port;
+	struct snd_seq_event event_saved;
+	struct snd_seq_client_port *src_port;
 	struct list_head *p;
-	port_subs_info_t *grp;
+	struct snd_seq_port_subs_info *grp;
 
 	src_port = snd_seq_port_use_ptr(client, event->source.port);
 	if (src_port == NULL)
@@ -642,7 +675,7 @@
 	else
 		down_read(&grp->list_mutex);
 	list_for_each(p, &grp->list_head) {
-		subs = list_entry(p, subscribers_t, src_list);
+		subs = list_entry(p, struct snd_seq_subscribers, src_list);
 		event->dest = subs->info.dest;
 		if (subs->info.flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP)
 			/* convert time according to flag with subscription */
@@ -670,12 +703,12 @@
 /*
  * broadcast to all ports:
  */
-static int port_broadcast_event(client_t *client,
-				snd_seq_event_t *event,
+static int port_broadcast_event(struct snd_seq_client *client,
+				struct snd_seq_event *event,
 				int atomic, int hop)
 {
 	int num_ev = 0, err = 0;
-	client_t *dest_client;
+	struct snd_seq_client *dest_client;
 	struct list_head *p;
 
 	dest_client = get_event_dest_client(event, SNDRV_SEQ_FILTER_BROADCAST);
@@ -684,7 +717,7 @@
 
 	read_lock(&dest_client->ports_lock);
 	list_for_each(p, &dest_client->ports_list_head) {
-		client_port_t *port = list_entry(p, client_port_t, list);
+		struct snd_seq_client_port *port = list_entry(p, struct snd_seq_client_port, list);
 		event->dest.port = port->addr.port;
 		/* pass NULL as source client to avoid error bounce */
 		err = snd_seq_deliver_single_event(NULL, event,
@@ -704,12 +737,12 @@
  * send the event to all clients:
  * if destination port is also ADDRESS_BROADCAST, deliver to all ports.
  */
-static int broadcast_event(client_t *client,
-			   snd_seq_event_t *event, int atomic, int hop)
+static int broadcast_event(struct snd_seq_client *client,
+			   struct snd_seq_event *event, int atomic, int hop)
 {
 	int err = 0, num_ev = 0;
 	int dest;
-	snd_seq_addr_t addr;
+	struct snd_seq_addr addr;
 
 	addr = event->dest; /* save */
 
@@ -736,7 +769,7 @@
 
 
 /* multicast - not supported yet */
-static int multicast_event(client_t *client, snd_seq_event_t *event,
+static int multicast_event(struct snd_seq_client *client, struct snd_seq_event *event,
 			   int atomic, int hop)
 {
 	snd_printd("seq: multicast not supported yet.\n");
@@ -753,7 +786,7 @@
  *               n == 0 : the event was not passed to any client.
  *               n < 0  : error - event was not processed.
  */
-static int snd_seq_deliver_event(client_t *client, snd_seq_event_t *event,
+static int snd_seq_deliver_event(struct snd_seq_client *client, struct snd_seq_event *event,
 				 int atomic, int hop)
 {
 	int result;
@@ -794,9 +827,9 @@
  *		 n == 0 : the event was not passed to any client.
  *		 n < 0  : error - event was not processed.
  */
-int snd_seq_dispatch_event(snd_seq_event_cell_t *cell, int atomic, int hop)
+int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
 {
-	client_t *client;
+	struct snd_seq_client *client;
 	int result;
 
 	snd_assert(cell != NULL, return -EINVAL);
@@ -812,7 +845,7 @@
 		 * the event cell is re-used as a NOTE-OFF event and
 		 * enqueued again.
 		 */
-		snd_seq_event_t tmpev, *ev;
+		struct snd_seq_event tmpev, *ev;
 
 		/* reserve this event to enqueue note-off later */
 		tmpev = cell->event;
@@ -865,12 +898,12 @@
  * if pool is empty and blocking is TRUE, sleep until a new cell is
  * available.
  */
-static int snd_seq_client_enqueue_event(client_t *client,
-					snd_seq_event_t *event,
+static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
+					struct snd_seq_event *event,
 					struct file *file, int blocking,
 					int atomic, int hop)
 {
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 	int err;
 
 	/* special queue values - force direct passing */
@@ -886,7 +919,7 @@
 #endif
 	if (event->dest.client == SNDRV_SEQ_ADDRESS_SUBSCRIBERS) {
 		/* check presence of source port */
-		client_port_t *src_port = snd_seq_port_use_ptr(client, event->source.port);
+		struct snd_seq_client_port *src_port = snd_seq_port_use_ptr(client, event->source.port);
 		if (src_port == NULL)
 			return -EINVAL;
 		snd_seq_port_unlock(src_port);
@@ -924,7 +957,7 @@
  * check validity of event type and data length.
  * return non-zero if invalid.
  */
-static int check_event_type_and_length(snd_seq_event_t *ev)
+static int check_event_type_and_length(struct snd_seq_event *ev)
 {
 	switch (snd_seq_ev_length_type(ev)) {
 	case SNDRV_SEQ_EVENT_LENGTH_FIXED:
@@ -957,12 +990,13 @@
  *	-EMLINK	too many hops
  *	others	depends on return value from driver callback
  */
-static ssize_t snd_seq_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
+static ssize_t snd_seq_write(struct file *file, const char __user *buf,
+			     size_t count, loff_t *offset)
 {
-	client_t *client = (client_t *) file->private_data;
+	struct snd_seq_client *client = file->private_data;
 	int written = 0, len;
 	int err = -EINVAL;
-	snd_seq_event_t event;
+	struct snd_seq_event event;
 
 	if (!(snd_seq_file_flags(file) & SNDRV_SEQ_LFLG_OUTPUT))
 		return -ENXIO;
@@ -980,7 +1014,7 @@
 	}
 
 	/* only process whole events */
-	while (count >= sizeof(snd_seq_event_t)) {
+	while (count >= sizeof(struct snd_seq_event)) {
 		/* Read in the event header from the user */
 		len = sizeof(event);
 		if (copy_from_user(&event, buf, len)) {
@@ -1012,7 +1046,7 @@
 			/* set user space pointer */
 			event.data.ext.len = extlen | SNDRV_SEQ_EXT_USRPTR;
 			event.data.ext.ptr = (char __force *)buf
-						+ sizeof(snd_seq_event_t);
+						+ sizeof(struct snd_seq_event);
 			len += extlen; /* increment data length */
 		} else {
 #ifdef CONFIG_COMPAT
@@ -1046,7 +1080,7 @@
  */
 static unsigned int snd_seq_poll(struct file *file, poll_table * wait)
 {
-	client_t *client = (client_t *) file->private_data;
+	struct snd_seq_client *client = file->private_data;
 	unsigned int mask = 0;
 
 	/* check client structures are in place */
@@ -1076,9 +1110,9 @@
 
 
 /* SYSTEM_INFO ioctl() */
-static int snd_seq_ioctl_system_info(client_t *client, void __user *arg)
+static int snd_seq_ioctl_system_info(struct snd_seq_client *client, void __user *arg)
 {
-	snd_seq_system_info_t info;
+	struct snd_seq_system_info info;
 
 	memset(&info, 0, sizeof(info));
 	/* fill the info fields */
@@ -1096,10 +1130,10 @@
 
 
 /* RUNNING_MODE ioctl() */
-static int snd_seq_ioctl_running_mode(client_t *client, void __user *arg)
+static int snd_seq_ioctl_running_mode(struct snd_seq_client *client, void __user *arg)
 {
-	struct sndrv_seq_running_info info;
-	client_t *cptr;
+	struct snd_seq_running_info info;
+	struct snd_seq_client *cptr;
 	int err = 0;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
@@ -1133,7 +1167,8 @@
 }
 
 /* CLIENT_INFO ioctl() */
-static void get_client_info(client_t *cptr, snd_seq_client_info_t *info)
+static void get_client_info(struct snd_seq_client *cptr,
+			    struct snd_seq_client_info *info)
 {
 	info->client = cptr->number;
 
@@ -1147,10 +1182,11 @@
 	memset(info->reserved, 0, sizeof(info->reserved));
 }
 
-static int snd_seq_ioctl_get_client_info(client_t * client, void __user *arg)
+static int snd_seq_ioctl_get_client_info(struct snd_seq_client *client,
+					 void __user *arg)
 {
-	client_t *cptr;
-	snd_seq_client_info_t client_info;
+	struct snd_seq_client *cptr;
+	struct snd_seq_client_info client_info;
 
 	if (copy_from_user(&client_info, arg, sizeof(client_info)))
 		return -EFAULT;
@@ -1170,9 +1206,10 @@
 
 
 /* CLIENT_INFO ioctl() */
-static int snd_seq_ioctl_set_client_info(client_t * client, void __user *arg)
+static int snd_seq_ioctl_set_client_info(struct snd_seq_client *client,
+					 void __user *arg)
 {
-	snd_seq_client_info_t client_info;
+	struct snd_seq_client_info client_info;
 
 	if (copy_from_user(&client_info, arg, sizeof(client_info)))
 		return -EFAULT;
@@ -1199,11 +1236,12 @@
 /* 
  * CREATE PORT ioctl() 
  */
-static int snd_seq_ioctl_create_port(client_t * client, void __user *arg)
+static int snd_seq_ioctl_create_port(struct snd_seq_client *client,
+				     void __user *arg)
 {
-	client_port_t *port;
-	snd_seq_port_info_t info;
-	snd_seq_port_callback_t *callback;
+	struct snd_seq_client_port *port;
+	struct snd_seq_port_info info;
+	struct snd_seq_port_callback *callback;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1249,9 +1287,10 @@
 /* 
  * DELETE PORT ioctl() 
  */
-static int snd_seq_ioctl_delete_port(client_t * client, void __user *arg)
+static int snd_seq_ioctl_delete_port(struct snd_seq_client *client,
+				     void __user *arg)
 {
-	snd_seq_port_info_t info;
+	struct snd_seq_port_info info;
 	int err;
 
 	/* set passed parameters */
@@ -1272,11 +1311,12 @@
 /* 
  * GET_PORT_INFO ioctl() (on any client) 
  */
-static int snd_seq_ioctl_get_port_info(client_t *client, void __user *arg)
+static int snd_seq_ioctl_get_port_info(struct snd_seq_client *client,
+				       void __user *arg)
 {
-	client_t *cptr;
-	client_port_t *port;
-	snd_seq_port_info_t info;
+	struct snd_seq_client *cptr;
+	struct snd_seq_client_port *port;
+	struct snd_seq_port_info info;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1304,10 +1344,11 @@
 /* 
  * SET_PORT_INFO ioctl() (only ports on this/own client) 
  */
-static int snd_seq_ioctl_set_port_info(client_t * client, void __user *arg)
+static int snd_seq_ioctl_set_port_info(struct snd_seq_client *client,
+				       void __user *arg)
 {
-	client_port_t *port;
-	snd_seq_port_info_t info;
+	struct snd_seq_client_port *port;
+	struct snd_seq_port_info info;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1329,9 +1370,10 @@
 #define PERM_RD		(SNDRV_SEQ_PORT_CAP_READ|SNDRV_SEQ_PORT_CAP_SUBS_READ)
 #define PERM_WR		(SNDRV_SEQ_PORT_CAP_WRITE|SNDRV_SEQ_PORT_CAP_SUBS_WRITE)
 
-static int check_subscription_permission(client_t *client, client_port_t *sport,
-					 client_port_t *dport,
-					 snd_seq_port_subscribe_t *subs)
+static int check_subscription_permission(struct snd_seq_client *client,
+					 struct snd_seq_client_port *sport,
+					 struct snd_seq_client_port *dport,
+					 struct snd_seq_port_subscribe *subs)
 {
 	if (client->number != subs->sender.client &&
 	    client->number != subs->dest.client) {
@@ -1363,9 +1405,10 @@
  * client must be user client.
  */
 int snd_seq_client_notify_subscription(int client, int port,
-				       snd_seq_port_subscribe_t *info, int evtype)
+				       struct snd_seq_port_subscribe *info,
+				       int evtype)
 {
-	snd_seq_event_t event;
+	struct snd_seq_event event;
 
 	memset(&event, 0, sizeof(event));
 	event.type = evtype;
@@ -1379,12 +1422,13 @@
 /* 
  * add to port's subscription list IOCTL interface 
  */
-static int snd_seq_ioctl_subscribe_port(client_t * client, void __user *arg)
+static int snd_seq_ioctl_subscribe_port(struct snd_seq_client *client,
+					void __user *arg)
 {
 	int result = -EINVAL;
-	client_t *receiver = NULL, *sender = NULL;
-	client_port_t *sport = NULL, *dport = NULL;
-	snd_seq_port_subscribe_t subs;
+	struct snd_seq_client *receiver = NULL, *sender = NULL;
+	struct snd_seq_client_port *sport = NULL, *dport = NULL;
+	struct snd_seq_port_subscribe subs;
 
 	if (copy_from_user(&subs, arg, sizeof(subs)))
 		return -EFAULT;
@@ -1423,12 +1467,13 @@
 /* 
  * remove from port's subscription list 
  */
-static int snd_seq_ioctl_unsubscribe_port(client_t * client, void __user *arg)
+static int snd_seq_ioctl_unsubscribe_port(struct snd_seq_client *client,
+					  void __user *arg)
 {
 	int result = -ENXIO;
-	client_t *receiver = NULL, *sender = NULL;
-	client_port_t *sport = NULL, *dport = NULL;
-	snd_seq_port_subscribe_t subs;
+	struct snd_seq_client *receiver = NULL, *sender = NULL;
+	struct snd_seq_client_port *sport = NULL, *dport = NULL;
+	struct snd_seq_port_subscribe subs;
 
 	if (copy_from_user(&subs, arg, sizeof(subs)))
 		return -EFAULT;
@@ -1464,11 +1509,12 @@
 
 
 /* CREATE_QUEUE ioctl() */
-static int snd_seq_ioctl_create_queue(client_t *client, void __user *arg)
+static int snd_seq_ioctl_create_queue(struct snd_seq_client *client,
+				      void __user *arg)
 {
-	snd_seq_queue_info_t info;
+	struct snd_seq_queue_info info;
 	int result;
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1498,9 +1544,10 @@
 }
 
 /* DELETE_QUEUE ioctl() */
-static int snd_seq_ioctl_delete_queue(client_t *client, void __user *arg)
+static int snd_seq_ioctl_delete_queue(struct snd_seq_client *client,
+				      void __user *arg)
 {
-	snd_seq_queue_info_t info;
+	struct snd_seq_queue_info info;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1509,10 +1556,11 @@
 }
 
 /* GET_QUEUE_INFO ioctl() */
-static int snd_seq_ioctl_get_queue_info(client_t *client, void __user *arg)
+static int snd_seq_ioctl_get_queue_info(struct snd_seq_client *client,
+					void __user *arg)
 {
-	snd_seq_queue_info_t info;
-	queue_t *q;
+	struct snd_seq_queue_info info;
+	struct snd_seq_queue *q;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1535,10 +1583,11 @@
 }
 
 /* SET_QUEUE_INFO ioctl() */
-static int snd_seq_ioctl_set_queue_info(client_t *client, void __user *arg)
+static int snd_seq_ioctl_set_queue_info(struct snd_seq_client *client,
+					void __user *arg)
 {
-	snd_seq_queue_info_t info;
-	queue_t *q;
+	struct snd_seq_queue_info info;
+	struct snd_seq_queue *q;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1570,10 +1619,10 @@
 }
 
 /* GET_NAMED_QUEUE ioctl() */
-static int snd_seq_ioctl_get_named_queue(client_t *client, void __user *arg)
+static int snd_seq_ioctl_get_named_queue(struct snd_seq_client *client, void __user *arg)
 {
-	snd_seq_queue_info_t info;
-	queue_t *q;
+	struct snd_seq_queue_info info;
+	struct snd_seq_queue *q;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1593,11 +1642,12 @@
 }
 
 /* GET_QUEUE_STATUS ioctl() */
-static int snd_seq_ioctl_get_queue_status(client_t * client, void __user *arg)
+static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client,
+					  void __user *arg)
 {
-	snd_seq_queue_status_t status;
-	queue_t *queue;
-	seq_timer_t *tmr;
+	struct snd_seq_queue_status status;
+	struct snd_seq_queue *queue;
+	struct snd_seq_timer *tmr;
 
 	if (copy_from_user(&status, arg, sizeof(status)))
 		return -EFAULT;
@@ -1626,11 +1676,12 @@
 
 
 /* GET_QUEUE_TEMPO ioctl() */
-static int snd_seq_ioctl_get_queue_tempo(client_t * client, void __user *arg)
+static int snd_seq_ioctl_get_queue_tempo(struct snd_seq_client *client,
+					 void __user *arg)
 {
-	snd_seq_queue_tempo_t tempo;
-	queue_t *queue;
-	seq_timer_t *tmr;
+	struct snd_seq_queue_tempo tempo;
+	struct snd_seq_queue *queue;
+	struct snd_seq_timer *tmr;
 
 	if (copy_from_user(&tempo, arg, sizeof(tempo)))
 		return -EFAULT;
@@ -1656,17 +1707,18 @@
 
 
 /* SET_QUEUE_TEMPO ioctl() */
-int snd_seq_set_queue_tempo(int client, snd_seq_queue_tempo_t *tempo)
+int snd_seq_set_queue_tempo(int client, struct snd_seq_queue_tempo *tempo)
 {
 	if (!snd_seq_queue_check_access(tempo->queue, client))
 		return -EPERM;
 	return snd_seq_queue_timer_set_tempo(tempo->queue, client, tempo);
 }
 
-static int snd_seq_ioctl_set_queue_tempo(client_t * client, void __user *arg)
+static int snd_seq_ioctl_set_queue_tempo(struct snd_seq_client *client,
+					 void __user *arg)
 {
 	int result;
-	snd_seq_queue_tempo_t tempo;
+	struct snd_seq_queue_tempo tempo;
 
 	if (copy_from_user(&tempo, arg, sizeof(tempo)))
 		return -EFAULT;
@@ -1677,11 +1729,12 @@
 
 
 /* GET_QUEUE_TIMER ioctl() */
-static int snd_seq_ioctl_get_queue_timer(client_t * client, void __user *arg)
+static int snd_seq_ioctl_get_queue_timer(struct snd_seq_client *client,
+					 void __user *arg)
 {
-	snd_seq_queue_timer_t timer;
-	queue_t *queue;
-	seq_timer_t *tmr;
+	struct snd_seq_queue_timer timer;
+	struct snd_seq_queue *queue;
+	struct snd_seq_timer *tmr;
 
 	if (copy_from_user(&timer, arg, sizeof(timer)))
 		return -EFAULT;
@@ -1713,10 +1766,11 @@
 
 
 /* SET_QUEUE_TIMER ioctl() */
-static int snd_seq_ioctl_set_queue_timer(client_t * client, void __user *arg)
+static int snd_seq_ioctl_set_queue_timer(struct snd_seq_client *client,
+					 void __user *arg)
 {
 	int result = 0;
-	snd_seq_queue_timer_t timer;
+	struct snd_seq_queue_timer timer;
 
 	if (copy_from_user(&timer, arg, sizeof(timer)))
 		return -EFAULT;
@@ -1725,8 +1779,8 @@
 		return -EINVAL;
 
 	if (snd_seq_queue_check_access(timer.queue, client->number)) {
-		queue_t *q;
-		seq_timer_t *tmr;
+		struct snd_seq_queue *q;
+		struct snd_seq_timer *tmr;
 
 		q = queueptr(timer.queue);
 		if (q == NULL)
@@ -1754,9 +1808,10 @@
 
 
 /* GET_QUEUE_CLIENT ioctl() */
-static int snd_seq_ioctl_get_queue_client(client_t * client, void __user *arg)
+static int snd_seq_ioctl_get_queue_client(struct snd_seq_client *client,
+					  void __user *arg)
 {
-	snd_seq_queue_client_t info;
+	struct snd_seq_queue_client info;
 	int used;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
@@ -1775,10 +1830,11 @@
 
 
 /* SET_QUEUE_CLIENT ioctl() */
-static int snd_seq_ioctl_set_queue_client(client_t * client, void __user *arg)
+static int snd_seq_ioctl_set_queue_client(struct snd_seq_client *client,
+					  void __user *arg)
 {
 	int err;
-	snd_seq_queue_client_t info;
+	struct snd_seq_queue_client info;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1794,10 +1850,11 @@
 
 
 /* GET_CLIENT_POOL ioctl() */
-static int snd_seq_ioctl_get_client_pool(client_t * client, void __user *arg)
+static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
+					 void __user *arg)
 {
-	snd_seq_client_pool_t info;
-	client_t *cptr;
+	struct snd_seq_client_pool info;
+	struct snd_seq_client *cptr;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1828,9 +1885,10 @@
 }
 
 /* SET_CLIENT_POOL ioctl() */
-static int snd_seq_ioctl_set_client_pool(client_t * client, void __user *arg)
+static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
+					 void __user *arg)
 {
-	snd_seq_client_pool_t info;
+	struct snd_seq_client_pool info;
 	int rc;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
@@ -1872,9 +1930,10 @@
 
 
 /* REMOVE_EVENTS ioctl() */
-static int snd_seq_ioctl_remove_events(client_t * client, void __user *arg)
+static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
+				       void __user *arg)
 {
-	snd_seq_remove_events_t info;
+	struct snd_seq_remove_events info;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -1901,13 +1960,14 @@
 /*
  * get subscription info
  */
-static int snd_seq_ioctl_get_subscription(client_t *client, void __user *arg)
+static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
+					  void __user *arg)
 {
 	int result;
-	client_t *sender = NULL;
-	client_port_t *sport = NULL;
-	snd_seq_port_subscribe_t subs;
-	subscribers_t *p;
+	struct snd_seq_client *sender = NULL;
+	struct snd_seq_client_port *sport = NULL;
+	struct snd_seq_port_subscribe subs;
+	struct snd_seq_subscribers *p;
 
 	if (copy_from_user(&subs, arg, sizeof(subs)))
 		return -EFAULT;
@@ -1940,13 +2000,14 @@
 /*
  * get subscription info - check only its presence
  */
-static int snd_seq_ioctl_query_subs(client_t *client, void __user *arg)
+static int snd_seq_ioctl_query_subs(struct snd_seq_client *client,
+				    void __user *arg)
 {
 	int result = -ENXIO;
-	client_t *cptr = NULL;
-	client_port_t *port = NULL;
-	snd_seq_query_subs_t subs;
-	port_subs_info_t *group;
+	struct snd_seq_client *cptr = NULL;
+	struct snd_seq_client_port *port = NULL;
+	struct snd_seq_query_subs subs;
+	struct snd_seq_port_subs_info *group;
 	struct list_head *p;
 	int i;
 
@@ -1977,12 +2038,12 @@
 	list_for_each(p, &group->list_head) {
 		if (i++ == subs.index) {
 			/* found! */
-			subscribers_t *s;
+			struct snd_seq_subscribers *s;
 			if (subs.type == SNDRV_SEQ_QUERY_SUBS_READ) {
-				s = list_entry(p, subscribers_t, src_list);
+				s = list_entry(p, struct snd_seq_subscribers, src_list);
 				subs.addr = s->info.dest;
 			} else {
-				s = list_entry(p, subscribers_t, dest_list);
+				s = list_entry(p, struct snd_seq_subscribers, dest_list);
 				subs.addr = s->info.sender;
 			}
 			subs.flags = s->info.flags;
@@ -2009,10 +2070,11 @@
 /*
  * query next client
  */
-static int snd_seq_ioctl_query_next_client(client_t *client, void __user *arg)
+static int snd_seq_ioctl_query_next_client(struct snd_seq_client *client,
+					   void __user *arg)
 {
-	client_t *cptr = NULL;
-	snd_seq_client_info_t info;
+	struct snd_seq_client *cptr = NULL;
+	struct snd_seq_client_info info;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -2040,11 +2102,12 @@
 /* 
  * query next port
  */
-static int snd_seq_ioctl_query_next_port(client_t *client, void __user *arg)
+static int snd_seq_ioctl_query_next_port(struct snd_seq_client *client,
+					 void __user *arg)
 {
-	client_t *cptr;
-	client_port_t *port = NULL;
-	snd_seq_port_info_t info;
+	struct snd_seq_client *cptr;
+	struct snd_seq_client_port *port = NULL;
+	struct snd_seq_port_info info;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
 		return -EFAULT;
@@ -2075,7 +2138,7 @@
 
 static struct seq_ioctl_table {
 	unsigned int cmd;
-	int (*func)(client_t *client, void __user * arg);
+	int (*func)(struct snd_seq_client *client, void __user * arg);
 } ioctl_tables[] = {
 	{ SNDRV_SEQ_IOCTL_SYSTEM_INFO, snd_seq_ioctl_system_info },
 	{ SNDRV_SEQ_IOCTL_RUNNING_MODE, snd_seq_ioctl_running_mode },
@@ -2109,7 +2172,8 @@
 	{ 0, NULL },
 };
 
-static int snd_seq_do_ioctl(client_t *client, unsigned int cmd, void __user *arg)
+static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd,
+			    void __user *arg)
 {
 	struct seq_ioctl_table *p;
 
@@ -2136,7 +2200,7 @@
 
 static long snd_seq_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	client_t *client = (client_t *) file->private_data;
+	struct snd_seq_client *client = file->private_data;
 
 	snd_assert(client != NULL, return -ENXIO);
 		
@@ -2153,23 +2217,29 @@
 
 
 /* exported to kernel modules */
-int snd_seq_create_kernel_client(snd_card_t *card, int client_index, snd_seq_client_callback_t * callback)
+int snd_seq_create_kernel_client(struct snd_card *card, int client_index,
+				 const char *name_fmt, ...)
 {
-	client_t *client;
+	struct snd_seq_client *client;
+	va_list args;
 
 	snd_assert(! in_interrupt(), return -EBUSY);
 
-	if (callback == NULL)
+	if (card && client_index >= SNDRV_SEQ_CLIENTS_PER_CARD)
 		return -EINVAL;
-	if (card && client_index > 7)
+	if (card == NULL && client_index >= SNDRV_SEQ_GLOBAL_CLIENTS)
 		return -EINVAL;
-	if (card == NULL && client_index > 63)
-		return -EINVAL;
-	if (card)
-		client_index += 64 + (card->number << 3);
 
 	if (down_interruptible(&register_mutex))
 		return -ERESTARTSYS;
+
+	if (card) {
+		client_index += SNDRV_SEQ_GLOBAL_CLIENTS
+			+ card->number * SNDRV_SEQ_CLIENTS_PER_CARD;
+		if (client_index >= SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN)
+			client_index = -1;
+	}
+
 	/* empty write queue as default */
 	client = seq_create_client1(client_index, 0);
 	if (client == NULL) {
@@ -2178,13 +2248,12 @@
 	}
 	usage_alloc(&client_usage, 1);
 
-	client->accept_input = callback->allow_output;
-	client->accept_output = callback->allow_input;
+	client->accept_input = 1;
+	client->accept_output = 1;
 		
-	/* fill client data */
-	client->data.kernel.card = card;
-	client->data.kernel.private_data = callback->private_data;
-	sprintf(client->name, "Client-%d", client->number);
+	va_start(args, name_fmt);
+	vsnprintf(client->name, sizeof(client->name), name_fmt, args);
+	va_end(args);
 
 	client->type = KERNEL_CLIENT;
 	up(&register_mutex);
@@ -2199,7 +2268,7 @@
 /* exported to kernel modules */
 int snd_seq_delete_kernel_client(int client)
 {
-	client_t *ptr;
+	struct snd_seq_client *ptr;
 
 	snd_assert(! in_interrupt(), return -EBUSY);
 
@@ -2216,11 +2285,11 @@
 /* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue
  * and snd_seq_kernel_client_enqueue_blocking
  */
-static int kernel_client_enqueue(int client, snd_seq_event_t *ev,
+static int kernel_client_enqueue(int client, struct snd_seq_event *ev,
 				 struct file *file, int blocking,
 				 int atomic, int hop)
 {
-	client_t *cptr;
+	struct snd_seq_client *cptr;
 	int result;
 
 	snd_assert(ev != NULL, return -EINVAL);
@@ -2254,7 +2323,7 @@
  *
  * RETURN VALUE: zero if succeed, negative if error
  */
-int snd_seq_kernel_client_enqueue(int client, snd_seq_event_t * ev,
+int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event * ev,
 				  int atomic, int hop)
 {
 	return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop);
@@ -2265,7 +2334,7 @@
  *
  * RETURN VALUE: zero if succeed, negative if error
  */
-int snd_seq_kernel_client_enqueue_blocking(int client, snd_seq_event_t * ev,
+int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev,
 					   struct file *file,
 					   int atomic, int hop)
 {
@@ -2280,10 +2349,10 @@
  * RETURN VALUE: negative = delivery failed,
  *		 zero, or positive: the number of delivered events
  */
-int snd_seq_kernel_client_dispatch(int client, snd_seq_event_t * ev,
+int snd_seq_kernel_client_dispatch(int client, struct snd_seq_event * ev,
 				   int atomic, int hop)
 {
-	client_t *cptr;
+	struct snd_seq_client *cptr;
 	int result;
 
 	snd_assert(ev != NULL, return -EINVAL);
@@ -2315,7 +2384,7 @@
  */
 int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
 {
-	client_t *client;
+	struct snd_seq_client *client;
 	mm_segment_t fs;
 	int result;
 
@@ -2332,7 +2401,7 @@
 /* exported (for OSS emulator) */
 int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait)
 {
-	client_t *client;
+	struct snd_seq_client *client;
 
 	client = clientptr(clientid);
 	if (client == NULL)
@@ -2347,13 +2416,16 @@
 
 /*---------------------------------------------------------------------------*/
 
+#ifdef CONFIG_PROC_FS
 /*
  *  /proc interface
  */
-static void snd_seq_info_dump_subscribers(snd_info_buffer_t *buffer, port_subs_info_t *group, int is_src, char *msg)
+static void snd_seq_info_dump_subscribers(struct snd_info_buffer *buffer,
+					  struct snd_seq_port_subs_info *group,
+					  int is_src, char *msg)
 {
 	struct list_head *p;
-	subscribers_t *s;
+	struct snd_seq_subscribers *s;
 	int count = 0;
 
 	down_read(&group->list_mutex);
@@ -2364,9 +2436,9 @@
 	snd_iprintf(buffer, msg);
 	list_for_each(p, &group->list_head) {
 		if (is_src)
-			s = list_entry(p, subscribers_t, src_list);
+			s = list_entry(p, struct snd_seq_subscribers, src_list);
 		else
-			s = list_entry(p, subscribers_t, dest_list);
+			s = list_entry(p, struct snd_seq_subscribers, dest_list);
 		if (count++)
 			snd_iprintf(buffer, ", ");
 		snd_iprintf(buffer, "%d:%d",
@@ -2387,13 +2459,14 @@
 
 #define FLAG_PERM_DUPLEX(perm) ((perm) & SNDRV_SEQ_PORT_CAP_DUPLEX ? 'X' : '-')
 
-static void snd_seq_info_dump_ports(snd_info_buffer_t *buffer, client_t *client)
+static void snd_seq_info_dump_ports(struct snd_info_buffer *buffer,
+				    struct snd_seq_client *client)
 {
 	struct list_head *l;
 
 	down(&client->ports_mutex);
 	list_for_each(l, &client->ports_list_head) {
-		client_port_t *p = list_entry(l, client_port_t, list);
+		struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
 		snd_iprintf(buffer, "  Port %3d : \"%s\" (%c%c%c%c)\n",
 			    p->addr.port, p->name,
 			    FLAG_PERM_RD(p->capability),
@@ -2407,13 +2480,15 @@
 }
 
 
+void snd_seq_info_pool(struct snd_info_buffer *buffer,
+		       struct snd_seq_pool *pool, char *space);
+
 /* exported to seq_info.c */
-void snd_seq_info_clients_read(snd_info_entry_t *entry, 
-			       snd_info_buffer_t * buffer)
+void snd_seq_info_clients_read(struct snd_info_entry *entry, 
+			       struct snd_info_buffer *buffer)
 {
-	extern void snd_seq_info_pool(snd_info_buffer_t * buffer, pool_t * pool, char *space);
 	int c;
-	client_t *client;
+	struct snd_seq_client *client;
 
 	snd_iprintf(buffer, "Client info\n");
 	snd_iprintf(buffer, "  cur  clients : %d\n", client_usage.cur);
@@ -2447,7 +2522,7 @@
 		snd_seq_client_unlock(client);
 	}
 }
-
+#endif /* CONFIG_PROC_FS */
 
 /*---------------------------------------------------------------------------*/
 
@@ -2468,13 +2543,6 @@
 	.compat_ioctl =	snd_seq_ioctl_compat,
 };
 
-static snd_minor_t snd_seq_reg =
-{
-	.comment =	"sequencer",
-	.f_ops =	&snd_seq_f_ops,
-};
-
-
 /* 
  * register sequencer device 
  */
@@ -2485,7 +2553,8 @@
 	if (down_interruptible(&register_mutex))
 		return -ERESTARTSYS;
 
-	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0, &snd_seq_reg, "seq")) < 0) {
+	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
+				       &snd_seq_f_ops, NULL, "seq")) < 0) {
 		up(&register_mutex);
 		return err;
 	}
diff --git a/sound/core/seq/seq_clientmgr.h b/sound/core/seq/seq_clientmgr.h
index 3715c36..450091c 100644
--- a/sound/core/seq/seq_clientmgr.h
+++ b/sound/core/seq/seq_clientmgr.h
@@ -30,24 +30,21 @@
 
 /* client manager */
 
-struct _snd_seq_user_client {
+struct snd_seq_user_client {
 	struct file *file;	/* file struct of client */
 	/* ... */
 	
 	/* fifo */
-	fifo_t *fifo;	/* queue for incoming events */
+	struct snd_seq_fifo *fifo;	/* queue for incoming events */
 	int fifo_pool_size;
 };
 
-struct _snd_seq_kernel_client {
-	snd_card_t *card;
-	/* pointer to client functions */
-	void *private_data;			/* private data for client */
+struct snd_seq_kernel_client {
 	/* ... */
 };
 
 
-struct _snd_seq_client {
+struct snd_seq_client {
 	snd_seq_client_type_t type;
 	unsigned int accept_input: 1,
 		accept_output: 1;
@@ -65,40 +62,40 @@
 	int convert32;		/* convert 32->64bit */
 
 	/* output pool */
-	pool_t *pool;		/* memory pool for this client */
+	struct snd_seq_pool *pool;		/* memory pool for this client */
 
 	union {
-		user_client_t user;
-		kernel_client_t kernel;
+		struct snd_seq_user_client user;
+		struct snd_seq_kernel_client kernel;
 	} data;
 };
 
 /* usage statistics */
-typedef struct {
+struct snd_seq_usage {
 	int cur;
 	int peak;
-} usage_t;
+};
 
 
-extern int client_init_data(void);
-extern int snd_sequencer_device_init(void);
-extern void snd_sequencer_device_done(void);
+int client_init_data(void);
+int snd_sequencer_device_init(void);
+void snd_sequencer_device_done(void);
 
 /* get locked pointer to client */
-extern client_t *snd_seq_client_use_ptr(int clientid);
+struct snd_seq_client *snd_seq_client_use_ptr(int clientid);
 
 /* unlock pointer to client */
 #define snd_seq_client_unlock(client) snd_use_lock_free(&(client)->use_lock)
 
 /* dispatch event to client(s) */
-extern int snd_seq_dispatch_event(snd_seq_event_cell_t *cell, int atomic, int hop);
+int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop);
 
 /* exported to other modules */
-extern int snd_seq_register_kernel_client(snd_seq_client_callback_t *callback, void *private_data);
-extern int snd_seq_unregister_kernel_client(int client);
-extern int snd_seq_kernel_client_enqueue(int client, snd_seq_event_t *ev, int atomic, int hop);
-int snd_seq_kernel_client_enqueue_blocking(int client, snd_seq_event_t * ev, struct file *file, int atomic, int hop);
+int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev, int atomic, int hop);
+int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev,
+					   struct file *file, int atomic, int hop);
 int snd_seq_kernel_client_write_poll(int clientid, struct file *file, poll_table *wait);
-int snd_seq_client_notify_subscription(int client, int port, snd_seq_port_subscribe_t *info, int evtype);
+int snd_seq_client_notify_subscription(int client, int port,
+				       struct snd_seq_port_subscribe *info, int evtype);
 
 #endif
diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c
index 902ad8b..9628c06 100644
--- a/sound/core/seq/seq_compat.c
+++ b/sound/core/seq/seq_compat.c
@@ -22,8 +22,8 @@
 
 #include <linux/compat.h>
 
-struct sndrv_seq_port_info32 {
-	struct sndrv_seq_addr addr;	/* client/port numbers */
+struct snd_seq_port_info32 {
+	struct snd_seq_addr addr;	/* client/port numbers */
 	char name[64];			/* port name */
 
 	u32 capability;	/* port capability bits */
@@ -41,11 +41,11 @@
 	char reserved[59];		/* for future use */
 };
 
-static int snd_seq_call_port_info_ioctl(client_t *client, unsigned int cmd,
-					struct sndrv_seq_port_info32 __user *data32)
+static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned int cmd,
+					struct snd_seq_port_info32 __user *data32)
 {
 	int err = -EFAULT;
-	snd_seq_port_info_t *data;
+	struct snd_seq_port_info *data;
 	mm_segment_t fs;
 
 	data = kmalloc(sizeof(*data), GFP_KERNEL);
@@ -80,16 +80,16 @@
  */
 
 enum {
-	SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct sndrv_seq_port_info32),
-	SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct sndrv_seq_port_info32),
-	SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct sndrv_seq_port_info32),
-	SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct sndrv_seq_port_info32),
-	SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct sndrv_seq_port_info32),
+	SNDRV_SEQ_IOCTL_CREATE_PORT32 = _IOWR('S', 0x20, struct snd_seq_port_info32),
+	SNDRV_SEQ_IOCTL_DELETE_PORT32 = _IOW ('S', 0x21, struct snd_seq_port_info32),
+	SNDRV_SEQ_IOCTL_GET_PORT_INFO32 = _IOWR('S', 0x22, struct snd_seq_port_info32),
+	SNDRV_SEQ_IOCTL_SET_PORT_INFO32 = _IOW ('S', 0x23, struct snd_seq_port_info32),
+	SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT32 = _IOWR('S', 0x52, struct snd_seq_port_info32),
 };
 
 static long snd_seq_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
 {
-	client_t *client = (client_t *) file->private_data;
+	struct snd_seq_client *client = file->private_data;
 	void __user *argp = compat_ptr(arg);
 
 	snd_assert(client != NULL, return -ENXIO);
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 252b527..9ece443 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -50,11 +50,6 @@
 MODULE_DESCRIPTION("ALSA sequencer device management");
 MODULE_LICENSE("GPL");
 
-/*
- * driver list
- */
-typedef struct ops_list ops_list_t;
-
 /* driver state */
 #define DRIVER_EMPTY		0
 #define DRIVER_LOADED		(1<<0)
@@ -68,7 +63,7 @@
 	int argsize;		/* argument size */
 
 	/* operators */
-	snd_seq_dev_ops_t ops;
+	struct snd_seq_dev_ops ops;
 
 	/* registred devices */
 	struct list_head dev_list;	/* list of devices */
@@ -83,35 +78,39 @@
 static LIST_HEAD(opslist);
 static int num_ops;
 static DECLARE_MUTEX(ops_mutex);
-static snd_info_entry_t *info_entry = NULL;
+#ifdef CONFIG_PROC_FS
+static struct snd_info_entry *info_entry = NULL;
+#endif
 
 /*
  * prototypes
  */
-static int snd_seq_device_free(snd_seq_device_t *dev);
-static int snd_seq_device_dev_free(snd_device_t *device);
-static int snd_seq_device_dev_register(snd_device_t *device);
-static int snd_seq_device_dev_disconnect(snd_device_t *device);
-static int snd_seq_device_dev_unregister(snd_device_t *device);
+static int snd_seq_device_free(struct snd_seq_device *dev);
+static int snd_seq_device_dev_free(struct snd_device *device);
+static int snd_seq_device_dev_register(struct snd_device *device);
+static int snd_seq_device_dev_disconnect(struct snd_device *device);
+static int snd_seq_device_dev_unregister(struct snd_device *device);
 
-static int init_device(snd_seq_device_t *dev, ops_list_t *ops);
-static int free_device(snd_seq_device_t *dev, ops_list_t *ops);
-static ops_list_t *find_driver(char *id, int create_if_empty);
-static ops_list_t *create_driver(char *id);
-static void unlock_driver(ops_list_t *ops);
+static int init_device(struct snd_seq_device *dev, struct ops_list *ops);
+static int free_device(struct snd_seq_device *dev, struct ops_list *ops);
+static struct ops_list *find_driver(char *id, int create_if_empty);
+static struct ops_list *create_driver(char *id);
+static void unlock_driver(struct ops_list *ops);
 static void remove_drivers(void);
 
 /*
  * show all drivers and their status
  */
 
-static void snd_seq_device_info(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+#ifdef CONFIG_PROC_FS
+static void snd_seq_device_info(struct snd_info_entry *entry,
+				struct snd_info_buffer *buffer)
 {
 	struct list_head *head;
 
 	down(&ops_mutex);
 	list_for_each(head, &opslist) {
-		ops_list_t *ops = list_entry(head, ops_list_t, list);
+		struct ops_list *ops = list_entry(head, struct ops_list, list);
 		snd_iprintf(buffer, "snd-%s%s%s%s,%d\n",
 				ops->id,
 				ops->driver & DRIVER_LOADED ? ",loaded" : (ops->driver == DRIVER_EMPTY ? ",empty" : ""),
@@ -121,6 +120,7 @@
 	}
 	up(&ops_mutex);	
 }
+#endif
  
 /*
  * load all registered drivers (called from seq_clientmgr.c)
@@ -156,7 +156,7 @@
 
 	down(&ops_mutex);
 	list_for_each(head, &opslist) {
-		ops_list_t *ops = list_entry(head, ops_list_t, list);
+		struct ops_list *ops = list_entry(head, struct ops_list, list);
 		if (! (ops->driver & DRIVER_LOADED) &&
 		    ! (ops->driver & DRIVER_REQUESTED)) {
 			ops->used++;
@@ -178,13 +178,13 @@
  * id = id of driver
  * result = return pointer (NULL allowed if unnecessary)
  */
-int snd_seq_device_new(snd_card_t *card, int device, char *id, int argsize,
-		       snd_seq_device_t **result)
+int snd_seq_device_new(struct snd_card *card, int device, char *id, int argsize,
+		       struct snd_seq_device **result)
 {
-	snd_seq_device_t *dev;
-	ops_list_t *ops;
+	struct snd_seq_device *dev;
+	struct ops_list *ops;
 	int err;
-	static snd_device_ops_t dops = {
+	static struct snd_device_ops dops = {
 		.dev_free = snd_seq_device_dev_free,
 		.dev_register = snd_seq_device_dev_register,
 		.dev_disconnect = snd_seq_device_dev_disconnect,
@@ -235,9 +235,9 @@
 /*
  * free the existing device
  */
-static int snd_seq_device_free(snd_seq_device_t *dev)
+static int snd_seq_device_free(struct snd_seq_device *dev)
 {
-	ops_list_t *ops;
+	struct ops_list *ops;
 
 	snd_assert(dev != NULL, return -EINVAL);
 
@@ -261,19 +261,19 @@
 	return 0;
 }
 
-static int snd_seq_device_dev_free(snd_device_t *device)
+static int snd_seq_device_dev_free(struct snd_device *device)
 {
-	snd_seq_device_t *dev = device->device_data;
+	struct snd_seq_device *dev = device->device_data;
 	return snd_seq_device_free(dev);
 }
 
 /*
  * register the device
  */
-static int snd_seq_device_dev_register(snd_device_t *device)
+static int snd_seq_device_dev_register(struct snd_device *device)
 {
-	snd_seq_device_t *dev = device->device_data;
-	ops_list_t *ops;
+	struct snd_seq_device *dev = device->device_data;
+	struct ops_list *ops;
 
 	ops = find_driver(dev->id, 0);
 	if (ops == NULL)
@@ -292,10 +292,10 @@
 /*
  * disconnect the device
  */
-static int snd_seq_device_dev_disconnect(snd_device_t *device)
+static int snd_seq_device_dev_disconnect(struct snd_device *device)
 {
-	snd_seq_device_t *dev = device->device_data;
-	ops_list_t *ops;
+	struct snd_seq_device *dev = device->device_data;
+	struct ops_list *ops;
 
 	ops = find_driver(dev->id, 0);
 	if (ops == NULL)
@@ -310,9 +310,9 @@
 /*
  * unregister the existing device
  */
-static int snd_seq_device_dev_unregister(snd_device_t *device)
+static int snd_seq_device_dev_unregister(struct snd_device *device)
 {
-	snd_seq_device_t *dev = device->device_data;
+	struct snd_seq_device *dev = device->device_data;
 	return snd_seq_device_free(dev);
 }
 
@@ -321,10 +321,11 @@
  * id = driver id
  * entry = driver operators - duplicated to each instance
  */
-int snd_seq_device_register_driver(char *id, snd_seq_dev_ops_t *entry, int argsize)
+int snd_seq_device_register_driver(char *id, struct snd_seq_dev_ops *entry,
+				   int argsize)
 {
 	struct list_head *head;
-	ops_list_t *ops;
+	struct ops_list *ops;
 
 	if (id == NULL || entry == NULL ||
 	    entry->init_device == NULL || entry->free_device == NULL)
@@ -351,7 +352,7 @@
 
 	/* initialize existing devices if necessary */
 	list_for_each(head, &ops->dev_list) {
-		snd_seq_device_t *dev = list_entry(head, snd_seq_device_t, list);
+		struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
 		init_device(dev, ops);
 	}
 	up(&ops->reg_mutex);
@@ -366,9 +367,9 @@
 /*
  * create driver record
  */
-static ops_list_t * create_driver(char *id)
+static struct ops_list * create_driver(char *id)
 {
-	ops_list_t *ops;
+	struct ops_list *ops;
 
 	ops = kmalloc(sizeof(*ops), GFP_KERNEL);
 	if (ops == NULL)
@@ -399,14 +400,15 @@
 int snd_seq_device_unregister_driver(char *id)
 {
 	struct list_head *head;
-	ops_list_t *ops;
+	struct ops_list *ops;
 
 	ops = find_driver(id, 0);
 	if (ops == NULL)
 		return -ENXIO;
 	if (! (ops->driver & DRIVER_LOADED) ||
 	    (ops->driver & DRIVER_LOCKED)) {
-		snd_printk(KERN_ERR "driver_unregister: cannot unload driver '%s': status=%x\n", id, ops->driver);
+		snd_printk(KERN_ERR "driver_unregister: cannot unload driver '%s': status=%x\n",
+			   id, ops->driver);
 		unlock_driver(ops);
 		return -EBUSY;
 	}
@@ -415,13 +417,14 @@
 	down(&ops->reg_mutex);
 	ops->driver |= DRIVER_LOCKED; /* do not remove this driver recursively */
 	list_for_each(head, &ops->dev_list) {
-		snd_seq_device_t *dev = list_entry(head, snd_seq_device_t, list);
+		struct snd_seq_device *dev = list_entry(head, struct snd_seq_device, list);
 		free_device(dev, ops);
 	}
 
 	ops->driver = 0;
 	if (ops->num_init_devices > 0)
-		snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n", ops->num_init_devices);
+		snd_printk(KERN_ERR "free_driver: init_devices > 0!! (%d)\n",
+			   ops->num_init_devices);
 	up(&ops->reg_mutex);
 
 	unlock_driver(ops);
@@ -443,7 +446,7 @@
 	down(&ops_mutex);
 	head = opslist.next;
 	while (head != &opslist) {
-		ops_list_t *ops = list_entry(head, ops_list_t, list);
+		struct ops_list *ops = list_entry(head, struct ops_list, list);
 		if (! (ops->driver & DRIVER_LOADED) &&
 		    ops->used == 0 && ops->num_devices == 0) {
 			head = head->next;
@@ -459,21 +462,23 @@
 /*
  * initialize the device - call init_device operator
  */
-static int init_device(snd_seq_device_t *dev, ops_list_t *ops)
+static int init_device(struct snd_seq_device *dev, struct ops_list *ops)
 {
 	if (! (ops->driver & DRIVER_LOADED))
 		return 0; /* driver is not loaded yet */
 	if (dev->status != SNDRV_SEQ_DEVICE_FREE)
 		return 0; /* already initialized */
 	if (ops->argsize != dev->argsize) {
-		snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n", dev->name, ops->id, ops->argsize, dev->argsize);
+		snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
+			   dev->name, ops->id, ops->argsize, dev->argsize);
 		return -EINVAL;
 	}
 	if (ops->ops.init_device(dev) >= 0) {
 		dev->status = SNDRV_SEQ_DEVICE_REGISTERED;
 		ops->num_init_devices++;
 	} else {
-		snd_printk(KERN_ERR "init_device failed: %s: %s\n", dev->name, dev->id);
+		snd_printk(KERN_ERR "init_device failed: %s: %s\n",
+			   dev->name, dev->id);
 	}
 
 	return 0;
@@ -482,7 +487,7 @@
 /*
  * release the device - call free_device operator
  */
-static int free_device(snd_seq_device_t *dev, ops_list_t *ops)
+static int free_device(struct snd_seq_device *dev, struct ops_list *ops)
 {
 	int result;
 
@@ -491,7 +496,8 @@
 	if (dev->status != SNDRV_SEQ_DEVICE_REGISTERED)
 		return 0; /* not registered */
 	if (ops->argsize != dev->argsize) {
-		snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n", dev->name, ops->id, ops->argsize, dev->argsize);
+		snd_printk(KERN_ERR "incompatible device '%s' for plug-in '%s' (%d %d)\n",
+			   dev->name, ops->id, ops->argsize, dev->argsize);
 		return -EINVAL;
 	}
 	if ((result = ops->ops.free_device(dev)) >= 0 || result == -ENXIO) {
@@ -499,7 +505,8 @@
 		dev->driver_data = NULL;
 		ops->num_init_devices--;
 	} else {
-		snd_printk(KERN_ERR "free_device failed: %s: %s\n", dev->name, dev->id);
+		snd_printk(KERN_ERR "free_device failed: %s: %s\n",
+			   dev->name, dev->id);
 	}
 
 	return 0;
@@ -508,13 +515,13 @@
 /*
  * find the matching driver with given id
  */
-static ops_list_t * find_driver(char *id, int create_if_empty)
+static struct ops_list * find_driver(char *id, int create_if_empty)
 {
 	struct list_head *head;
 
 	down(&ops_mutex);
 	list_for_each(head, &opslist) {
-		ops_list_t *ops = list_entry(head, ops_list_t, list);
+		struct ops_list *ops = list_entry(head, struct ops_list, list);
 		if (strcmp(ops->id, id) == 0) {
 			ops->used++;
 			up(&ops_mutex);
@@ -527,7 +534,7 @@
 	return NULL;
 }
 
-static void unlock_driver(ops_list_t *ops)
+static void unlock_driver(struct ops_list *ops)
 {
 	down(&ops_mutex);
 	ops->used--;
@@ -541,7 +548,9 @@
 
 static int __init alsa_seq_device_init(void)
 {
-	info_entry = snd_info_create_module_entry(THIS_MODULE, "drivers", snd_seq_root);
+#ifdef CONFIG_PROC_FS
+	info_entry = snd_info_create_module_entry(THIS_MODULE, "drivers",
+						  snd_seq_root);
 	if (info_entry == NULL)
 		return -ENOMEM;
 	info_entry->content = SNDRV_INFO_CONTENT_TEXT;
@@ -551,13 +560,16 @@
 		snd_info_free_entry(info_entry);
 		return -ENOMEM;
 	}
+#endif
 	return 0;
 }
 
 static void __exit alsa_seq_device_exit(void)
 {
 	remove_drivers();
+#ifdef CONFIG_PROC_FS
 	snd_info_unregister(info_entry);
+#endif
 	if (num_ops)
 		snd_printk(KERN_ERR "drivers not released (%d)\n", num_ops);
 }
diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c
index 5dd0e6a..2a283a5 100644
--- a/sound/core/seq/seq_dummy.c
+++ b/sound/core/seq/seq_dummy.c
@@ -73,12 +73,12 @@
 module_param(duplex, bool, 0444);
 MODULE_PARM_DESC(duplex, "create DUPLEX ports");
 
-typedef struct snd_seq_dummy_port {
+struct snd_seq_dummy_port {
 	int client;
 	int port;
 	int duplex;
 	int connect;
-} snd_seq_dummy_port_t;
+};
 
 static int my_client = -1;
 
@@ -88,11 +88,11 @@
  * Note: this callback is called only after all subscribers are removed.
  */
 static int
-dummy_unuse(void *private_data, snd_seq_port_subscribe_t *info)
+dummy_unuse(void *private_data, struct snd_seq_port_subscribe *info)
 {
-	snd_seq_dummy_port_t *p;
+	struct snd_seq_dummy_port *p;
 	int i;
-	snd_seq_event_t ev;
+	struct snd_seq_event ev;
 
 	p = private_data;
 	memset(&ev, 0, sizeof(ev));
@@ -116,10 +116,11 @@
  * event input callback - just redirect events to subscribers
  */
 static int
-dummy_input(snd_seq_event_t *ev, int direct, void *private_data, int atomic, int hop)
+dummy_input(struct snd_seq_event *ev, int direct, void *private_data,
+	    int atomic, int hop)
 {
-	snd_seq_dummy_port_t *p;
-	snd_seq_event_t tmpev;
+	struct snd_seq_dummy_port *p;
+	struct snd_seq_event tmpev;
 
 	p = private_data;
 	if (ev->source.client == SNDRV_SEQ_CLIENT_SYSTEM ||
@@ -146,12 +147,12 @@
 /*
  * create a port
  */
-static snd_seq_dummy_port_t __init *
+static struct snd_seq_dummy_port __init *
 create_port(int idx, int type)
 {
-	snd_seq_port_info_t pinfo;
-	snd_seq_port_callback_t pcb;
-	snd_seq_dummy_port_t *rec;
+	struct snd_seq_port_info pinfo;
+	struct snd_seq_port_callback pcb;
+	struct snd_seq_dummy_port *rec;
 
 	if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL)
 		return NULL;
@@ -192,9 +193,7 @@
 static int __init
 register_client(void)
 {
-	snd_seq_client_callback_t cb;
-	snd_seq_client_info_t cinfo;
-	snd_seq_dummy_port_t *rec1, *rec2;
+	struct snd_seq_dummy_port *rec1, *rec2;
 	int i;
 
 	if (ports < 1) {
@@ -203,20 +202,11 @@
 	}
 
 	/* create client */
-	memset(&cb, 0, sizeof(cb));
-	cb.allow_input = 1;
-	cb.allow_output = 1;
-	my_client = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_DUMMY, &cb);
+	my_client = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_DUMMY,
+						 "Midi Through");
 	if (my_client < 0)
 		return my_client;
 
-	/* set client name */
-	memset(&cinfo, 0, sizeof(cinfo));
-	cinfo.client = my_client;
-	cinfo.type = KERNEL_CLIENT;
-	strcpy(cinfo.name, "Midi Through");
-	snd_seq_kernel_client_ctl(my_client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
-
 	/* create ports */
 	for (i = 0; i < ports; i++) {
 		rec1 = create_port(i, 0);
diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c
index 4767cfd..6b055ae 100644
--- a/sound/core/seq/seq_fifo.c
+++ b/sound/core/seq/seq_fifo.c
@@ -29,9 +29,9 @@
 /* FIFO */
 
 /* create new fifo */
-fifo_t *snd_seq_fifo_new(int poolsize)
+struct snd_seq_fifo *snd_seq_fifo_new(int poolsize)
 {
-	fifo_t *f;
+	struct snd_seq_fifo *f;
 
 	f = kzalloc(sizeof(*f), GFP_KERNEL);
 	if (f == NULL) {
@@ -62,9 +62,9 @@
 	return f;
 }
 
-void snd_seq_fifo_delete(fifo_t **fifo)
+void snd_seq_fifo_delete(struct snd_seq_fifo **fifo)
 {
-	fifo_t *f;
+	struct snd_seq_fifo *f;
 
 	snd_assert(fifo != NULL, return);
 	f = *fifo;
@@ -88,12 +88,12 @@
 	kfree(f);
 }
 
-static snd_seq_event_cell_t *fifo_cell_out(fifo_t *f);
+static struct snd_seq_event_cell *fifo_cell_out(struct snd_seq_fifo *f);
 
 /* clear queue */
-void snd_seq_fifo_clear(fifo_t *f)
+void snd_seq_fifo_clear(struct snd_seq_fifo *f)
 {
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 	unsigned long flags;
 
 	/* clear overflow flag */
@@ -110,9 +110,10 @@
 
 
 /* enqueue event to fifo */
-int snd_seq_fifo_event_in(fifo_t *f, snd_seq_event_t *event)
+int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
+			  struct snd_seq_event *event)
 {
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 	unsigned long flags;
 	int err;
 
@@ -148,9 +149,9 @@
 }
 
 /* dequeue cell from fifo */
-static snd_seq_event_cell_t *fifo_cell_out(fifo_t *f)
+static struct snd_seq_event_cell *fifo_cell_out(struct snd_seq_fifo *f)
 {
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 
 	if ((cell = f->head) != NULL) {
 		f->head = cell->next;
@@ -167,9 +168,10 @@
 }
 
 /* dequeue cell from fifo and copy on user space */
-int snd_seq_fifo_cell_out(fifo_t *f, snd_seq_event_cell_t **cellp, int nonblock)
+int snd_seq_fifo_cell_out(struct snd_seq_fifo *f,
+			  struct snd_seq_event_cell **cellp, int nonblock)
 {
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 	unsigned long flags;
 	wait_queue_t wait;
 
@@ -202,7 +204,8 @@
 }
 
 
-void snd_seq_fifo_cell_putback(fifo_t *f, snd_seq_event_cell_t *cell)
+void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f,
+			       struct snd_seq_event_cell *cell)
 {
 	unsigned long flags;
 
@@ -217,18 +220,19 @@
 
 
 /* polling; return non-zero if queue is available */
-int snd_seq_fifo_poll_wait(fifo_t *f, struct file *file, poll_table *wait)
+int snd_seq_fifo_poll_wait(struct snd_seq_fifo *f, struct file *file,
+			   poll_table *wait)
 {
 	poll_wait(file, &f->input_sleep, wait);
 	return (f->cells > 0);
 }
 
 /* change the size of pool; all old events are removed */
-int snd_seq_fifo_resize(fifo_t *f, int poolsize)
+int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)
 {
 	unsigned long flags;
-	pool_t *newpool, *oldpool;
-	snd_seq_event_cell_t *cell, *next, *oldhead;
+	struct snd_seq_pool *newpool, *oldpool;
+	struct snd_seq_event_cell *cell, *next, *oldhead;
 
 	snd_assert(f != NULL && f->pool != NULL, return -EINVAL);
 
diff --git a/sound/core/seq/seq_fifo.h b/sound/core/seq/seq_fifo.h
index d677c26..062c446 100644
--- a/sound/core/seq/seq_fifo.h
+++ b/sound/core/seq/seq_fifo.h
@@ -27,46 +27,46 @@
 
 /* === FIFO === */
 
-typedef struct {
-	pool_t *pool;			/* FIFO pool */
-	snd_seq_event_cell_t* head;    	/* pointer to head of fifo */
-	snd_seq_event_cell_t* tail;    	/* pointer to tail of fifo */
+struct snd_seq_fifo {
+	struct snd_seq_pool *pool;		/* FIFO pool */
+	struct snd_seq_event_cell *head;    	/* pointer to head of fifo */
+	struct snd_seq_event_cell *tail;    	/* pointer to tail of fifo */
 	int cells;
 	spinlock_t lock;
 	snd_use_lock_t use_lock;
 	wait_queue_head_t input_sleep;
 	atomic_t overflow;
 
-} fifo_t;
+};
 
 /* create new fifo (constructor) */
-extern fifo_t *snd_seq_fifo_new(int poolsize);
+struct snd_seq_fifo *snd_seq_fifo_new(int poolsize);
 
 /* delete fifo (destructor) */
-extern void snd_seq_fifo_delete(fifo_t **f);
+void snd_seq_fifo_delete(struct snd_seq_fifo **f);
 
 
 /* enqueue event to fifo */
-extern int snd_seq_fifo_event_in(fifo_t *f, snd_seq_event_t *event);
+int snd_seq_fifo_event_in(struct snd_seq_fifo *f, struct snd_seq_event *event);
 
 /* lock fifo from release */
 #define snd_seq_fifo_lock(fifo)		snd_use_lock_use(&(fifo)->use_lock)
 #define snd_seq_fifo_unlock(fifo)	snd_use_lock_free(&(fifo)->use_lock)
 
 /* get a cell from fifo - fifo should be locked */
-int snd_seq_fifo_cell_out(fifo_t *f, snd_seq_event_cell_t **cellp, int nonblock);
+int snd_seq_fifo_cell_out(struct snd_seq_fifo *f, struct snd_seq_event_cell **cellp, int nonblock);
 
 /* free dequeued cell - fifo should be locked */
-extern void snd_seq_fifo_cell_putback(fifo_t *f, snd_seq_event_cell_t *cell);
+void snd_seq_fifo_cell_putback(struct snd_seq_fifo *f, struct snd_seq_event_cell *cell);
 
 /* clean up queue */
-extern void snd_seq_fifo_clear(fifo_t *f);
+void snd_seq_fifo_clear(struct snd_seq_fifo *f);
 
 /* polling */
-extern int snd_seq_fifo_poll_wait(fifo_t *f, struct file *file, poll_table *wait);
+int snd_seq_fifo_poll_wait(struct snd_seq_fifo *f, struct file *file, poll_table *wait);
 
 /* resize pool in fifo */
-int snd_seq_fifo_resize(fifo_t *f, int poolsize);
+int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize);
 
 
 #endif
diff --git a/sound/core/seq/seq_info.c b/sound/core/seq/seq_info.c
index b50b695..acce21a 100644
--- a/sound/core/seq/seq_info.c
+++ b/sound/core/seq/seq_info.c
@@ -27,16 +27,17 @@
 #include "seq_clientmgr.h"
 #include "seq_timer.h"
 
-
-static snd_info_entry_t *queues_entry;
-static snd_info_entry_t *clients_entry;
-static snd_info_entry_t *timer_entry;
+#ifdef CONFIG_PROC_FS
+static struct snd_info_entry *queues_entry;
+static struct snd_info_entry *clients_entry;
+static struct snd_info_entry *timer_entry;
 
 
-static snd_info_entry_t * __init
-create_info_entry(char *name, int size, void (*read)(snd_info_entry_t *, snd_info_buffer_t *))
+static struct snd_info_entry * __init
+create_info_entry(char *name, int size, void (*read)(struct snd_info_entry *,
+						     struct snd_info_buffer *))
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	entry = snd_info_create_module_entry(THIS_MODULE, name, snd_seq_root);
 	if (entry == NULL)
@@ -51,7 +52,6 @@
 	return entry;
 }
 
-
 /* create all our /proc entries */
 int __init snd_seq_info_init(void)
 {
@@ -65,11 +65,9 @@
 
 int __exit snd_seq_info_done(void)
 {
-	if (queues_entry)
-		snd_info_unregister(queues_entry);
-	if (clients_entry)
-		snd_info_unregister(clients_entry);
-	if (timer_entry)
-		snd_info_unregister(timer_entry);
+	snd_info_unregister(queues_entry);
+	snd_info_unregister(clients_entry);
+	snd_info_unregister(timer_entry);
 	return 0;
 }
+#endif
diff --git a/sound/core/seq/seq_info.h b/sound/core/seq/seq_info.h
index efd099a..4892a7f 100644
--- a/sound/core/seq/seq_info.h
+++ b/sound/core/seq/seq_info.h
@@ -24,13 +24,17 @@
 #include <sound/info.h>
 #include <sound/seq_kernel.h>
 
-void snd_seq_info_clients_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer);
-void snd_seq_info_timer_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer);
-void snd_seq_info_queues_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer);
+void snd_seq_info_clients_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
+void snd_seq_info_timer_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
+void snd_seq_info_queues_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
 
 
+#ifdef CONFIG_PROC_FS
 int snd_seq_info_init( void );
 int snd_seq_info_done( void );
-
+#else
+static inline int snd_seq_info_init(void) { return 0; }
+static inline int snd_seq_info_done(void) { return 0; }
+#endif
 
 #endif
diff --git a/sound/core/seq/seq_instr.c b/sound/core/seq/seq_instr.c
index 1d525b1..4874520 100644
--- a/sound/core/seq/seq_instr.c
+++ b/sound/core/seq/seq_instr.c
@@ -31,7 +31,7 @@
 MODULE_LICENSE("GPL");
 
 
-static void snd_instr_lock_ops(snd_seq_kinstr_list_t *list)
+static void snd_instr_lock_ops(struct snd_seq_kinstr_list *list)
 {
 	if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
 		spin_lock_irqsave(&list->ops_lock, list->ops_flags);
@@ -40,7 +40,7 @@
 	}
 }
 
-static void snd_instr_unlock_ops(snd_seq_kinstr_list_t *list)
+static void snd_instr_unlock_ops(struct snd_seq_kinstr_list *list)
 {
 	if (!(list->flags & SNDRV_SEQ_INSTR_FLG_DIRECT)) {
 		spin_unlock_irqrestore(&list->ops_lock, list->ops_flags);
@@ -49,18 +49,18 @@
 	}
 }
 
-static snd_seq_kinstr_t *snd_seq_instr_new(int add_len, int atomic)
+static struct snd_seq_kinstr *snd_seq_instr_new(int add_len, int atomic)
 {
-	snd_seq_kinstr_t *instr;
+	struct snd_seq_kinstr *instr;
 	
-	instr = kzalloc(sizeof(snd_seq_kinstr_t) + add_len, atomic ? GFP_ATOMIC : GFP_KERNEL);
+	instr = kzalloc(sizeof(struct snd_seq_kinstr) + add_len, atomic ? GFP_ATOMIC : GFP_KERNEL);
 	if (instr == NULL)
 		return NULL;
 	instr->add_len = add_len;
 	return instr;
 }
 
-static int snd_seq_instr_free(snd_seq_kinstr_t *instr, int atomic)
+static int snd_seq_instr_free(struct snd_seq_kinstr *instr, int atomic)
 {
 	int result = 0;
 
@@ -73,11 +73,11 @@
 	return result;
 }
 
-snd_seq_kinstr_list_t *snd_seq_instr_list_new(void)
+struct snd_seq_kinstr_list *snd_seq_instr_list_new(void)
 {
-	snd_seq_kinstr_list_t *list;
+	struct snd_seq_kinstr_list *list;
 
-	list = kzalloc(sizeof(snd_seq_kinstr_list_t), GFP_KERNEL);
+	list = kzalloc(sizeof(struct snd_seq_kinstr_list), GFP_KERNEL);
 	if (list == NULL)
 		return NULL;
 	spin_lock_init(&list->lock);
@@ -87,11 +87,11 @@
 	return list;
 }
 
-void snd_seq_instr_list_free(snd_seq_kinstr_list_t **list_ptr)
+void snd_seq_instr_list_free(struct snd_seq_kinstr_list **list_ptr)
 {
-	snd_seq_kinstr_list_t *list;
-	snd_seq_kinstr_t *instr;
-	snd_seq_kcluster_t *cluster;
+	struct snd_seq_kinstr_list *list;
+	struct snd_seq_kinstr *instr;
+	struct snd_seq_kcluster *cluster;
 	int idx;
 	unsigned long flags;
 
@@ -125,8 +125,8 @@
 	kfree(list);
 }
 
-static int instr_free_compare(snd_seq_kinstr_t *instr,
-			      snd_seq_instr_header_t *ifree,
+static int instr_free_compare(struct snd_seq_kinstr *instr,
+			      struct snd_seq_instr_header *ifree,
 			      unsigned int client)
 {
 	switch (ifree->cmd) {
@@ -160,12 +160,12 @@
 	return 1;
 }
 
-int snd_seq_instr_list_free_cond(snd_seq_kinstr_list_t *list,
-			         snd_seq_instr_header_t *ifree,
+int snd_seq_instr_list_free_cond(struct snd_seq_kinstr_list *list,
+			         struct snd_seq_instr_header *ifree,
 			         int client,
 			         int atomic)
 {
-	snd_seq_kinstr_t *instr, *prev, *next, *flist;
+	struct snd_seq_kinstr *instr, *prev, *next, *flist;
 	int idx;
 	unsigned long flags;
 
@@ -209,7 +209,7 @@
 	return 0;	
 }
 
-static int compute_hash_instr_key(snd_seq_instr_t *instr)
+static int compute_hash_instr_key(struct snd_seq_instr *instr)
 {
 	int result;
 	
@@ -233,7 +233,7 @@
 }
 #endif
 
-static int compare_instr(snd_seq_instr_t *i1, snd_seq_instr_t *i2, int exact)
+static int compare_instr(struct snd_seq_instr *i1, struct snd_seq_instr *i2, int exact)
 {
 	if (exact) {
 		if (i1->cluster != i2->cluster ||
@@ -262,14 +262,14 @@
 	}
 }
 
-snd_seq_kinstr_t *snd_seq_instr_find(snd_seq_kinstr_list_t *list,
-				     snd_seq_instr_t *instr,
-				     int exact,
-				     int follow_alias)
+struct snd_seq_kinstr *snd_seq_instr_find(struct snd_seq_kinstr_list *list,
+					  struct snd_seq_instr *instr,
+					  int exact,
+					  int follow_alias)
 {
 	unsigned long flags;
 	int depth = 0;
-	snd_seq_kinstr_t *result;
+	struct snd_seq_kinstr *result;
 
 	if (list == NULL || instr == NULL)
 		return NULL;
@@ -279,7 +279,7 @@
 	while (result) {
 		if (!compare_instr(&result->instr, instr, exact)) {
 			if (follow_alias && (result->type == SNDRV_SEQ_INSTR_ATYPE_ALIAS)) {
-				instr = (snd_seq_instr_t *)KINSTR_DATA(result);
+				instr = (struct snd_seq_instr *)KINSTR_DATA(result);
 				if (++depth > 10)
 					goto __not_found;
 				goto __again;
@@ -295,8 +295,8 @@
 	return NULL;
 }
 
-void snd_seq_instr_free_use(snd_seq_kinstr_list_t *list,
-			    snd_seq_kinstr_t *instr)
+void snd_seq_instr_free_use(struct snd_seq_kinstr_list *list,
+			    struct snd_seq_kinstr *instr)
 {
 	unsigned long flags;
 
@@ -311,7 +311,8 @@
 	spin_unlock_irqrestore(&list->lock, flags);
 }
 
-static snd_seq_kinstr_ops_t *instr_ops(snd_seq_kinstr_ops_t *ops, char *instr_type)
+static struct snd_seq_kinstr_ops *instr_ops(struct snd_seq_kinstr_ops *ops,
+					    char *instr_type)
 {
 	while (ops) {
 		if (!strcmp(ops->instr_type, instr_type))
@@ -321,11 +322,11 @@
 	return NULL;
 }
 
-static int instr_result(snd_seq_event_t *ev,
+static int instr_result(struct snd_seq_event *ev,
 			int type, int result,
 			int atomic)
 {
-	snd_seq_event_t sev;
+	struct snd_seq_event sev;
 	
 	memset(&sev, 0, sizeof(sev));
 	sev.type = SNDRV_SEQ_EVENT_RESULT;
@@ -345,9 +346,9 @@
 	return snd_seq_kernel_client_dispatch(sev.source.client, &sev, atomic, 0);
 }
 
-static int instr_begin(snd_seq_kinstr_ops_t *ops,
-		       snd_seq_kinstr_list_t *list,
-		       snd_seq_event_t *ev,
+static int instr_begin(struct snd_seq_kinstr_ops *ops,
+		       struct snd_seq_kinstr_list *list,
+		       struct snd_seq_event *ev,
 		       int atomic, int hop)
 {
 	unsigned long flags;
@@ -362,9 +363,9 @@
 	return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_BEGIN, 0, atomic);
 }
 
-static int instr_end(snd_seq_kinstr_ops_t *ops,
-		     snd_seq_kinstr_list_t *list,
-		     snd_seq_event_t *ev,
+static int instr_end(struct snd_seq_kinstr_ops *ops,
+		     struct snd_seq_kinstr_list *list,
+		     struct snd_seq_event *ev,
 		     int atomic, int hop)
 {
 	unsigned long flags;
@@ -380,54 +381,55 @@
 	return instr_result(ev, SNDRV_SEQ_EVENT_INSTR_END, -EINVAL, atomic);
 }
 
-static int instr_info(snd_seq_kinstr_ops_t *ops,
-		      snd_seq_kinstr_list_t *list,
-		      snd_seq_event_t *ev,
+static int instr_info(struct snd_seq_kinstr_ops *ops,
+		      struct snd_seq_kinstr_list *list,
+		      struct snd_seq_event *ev,
 		      int atomic, int hop)
 {
 	return -ENXIO;
 }
 
-static int instr_format_info(snd_seq_kinstr_ops_t *ops,
-			     snd_seq_kinstr_list_t *list,
-			     snd_seq_event_t *ev,
+static int instr_format_info(struct snd_seq_kinstr_ops *ops,
+			     struct snd_seq_kinstr_list *list,
+			     struct snd_seq_event *ev,
 			     int atomic, int hop)
 {
 	return -ENXIO;
 }
 
-static int instr_reset(snd_seq_kinstr_ops_t *ops,
-		       snd_seq_kinstr_list_t *list,
-		       snd_seq_event_t *ev,
+static int instr_reset(struct snd_seq_kinstr_ops *ops,
+		       struct snd_seq_kinstr_list *list,
+		       struct snd_seq_event *ev,
 		       int atomic, int hop)
 {
 	return -ENXIO;
 }
 
-static int instr_status(snd_seq_kinstr_ops_t *ops,
-			snd_seq_kinstr_list_t *list,
-			snd_seq_event_t *ev,
+static int instr_status(struct snd_seq_kinstr_ops *ops,
+			struct snd_seq_kinstr_list *list,
+			struct snd_seq_event *ev,
 			int atomic, int hop)
 {
 	return -ENXIO;
 }
 
-static int instr_put(snd_seq_kinstr_ops_t *ops,
-		     snd_seq_kinstr_list_t *list,
-		     snd_seq_event_t *ev,
+static int instr_put(struct snd_seq_kinstr_ops *ops,
+		     struct snd_seq_kinstr_list *list,
+		     struct snd_seq_event *ev,
 		     int atomic, int hop)
 {
 	unsigned long flags;
-	snd_seq_instr_header_t put;
-	snd_seq_kinstr_t *instr;
+	struct snd_seq_instr_header put;
+	struct snd_seq_kinstr *instr;
 	int result = -EINVAL, len, key;
 
 	if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARUSR)
 		goto __return;
 
-	if (ev->data.ext.len < sizeof(snd_seq_instr_header_t))
+	if (ev->data.ext.len < sizeof(struct snd_seq_instr_header))
 		goto __return;
-	if (copy_from_user(&put, (void __user *)ev->data.ext.ptr, sizeof(snd_seq_instr_header_t))) {
+	if (copy_from_user(&put, (void __user *)ev->data.ext.ptr,
+			   sizeof(struct snd_seq_instr_header))) {
 		result = -EFAULT;
 		goto __return;
 	}
@@ -449,7 +451,7 @@
 	}
 	len = ops->add_len;
 	if (put.data.type == SNDRV_SEQ_INSTR_ATYPE_ALIAS)
-		len = sizeof(snd_seq_instr_t);
+		len = sizeof(struct snd_seq_instr);
 	instr = snd_seq_instr_new(len, atomic);
 	if (instr == NULL) {
 		snd_instr_unlock_ops(list);
@@ -463,8 +465,8 @@
 	if (instr->type == SNDRV_SEQ_INSTR_ATYPE_DATA) {
 		result = ops->put(ops->private_data,
 				  instr,
-				  (void __user *)ev->data.ext.ptr + sizeof(snd_seq_instr_header_t),
-				  ev->data.ext.len - sizeof(snd_seq_instr_header_t),
+				  (void __user *)ev->data.ext.ptr + sizeof(struct snd_seq_instr_header),
+				  ev->data.ext.len - sizeof(struct snd_seq_instr_header),
 				  atomic,
 				  put.cmd);
 		if (result < 0) {
@@ -486,21 +488,21 @@
 	return result;
 }
 
-static int instr_get(snd_seq_kinstr_ops_t *ops,
-		     snd_seq_kinstr_list_t *list,
-		     snd_seq_event_t *ev,
+static int instr_get(struct snd_seq_kinstr_ops *ops,
+		     struct snd_seq_kinstr_list *list,
+		     struct snd_seq_event *ev,
 		     int atomic, int hop)
 {
 	return -ENXIO;
 }
 
-static int instr_free(snd_seq_kinstr_ops_t *ops,
-		      snd_seq_kinstr_list_t *list,
-		      snd_seq_event_t *ev,
+static int instr_free(struct snd_seq_kinstr_ops *ops,
+		      struct snd_seq_kinstr_list *list,
+		      struct snd_seq_event *ev,
 		      int atomic, int hop)
 {
-	snd_seq_instr_header_t ifree;
-	snd_seq_kinstr_t *instr, *prev;
+	struct snd_seq_instr_header ifree;
+	struct snd_seq_kinstr *instr, *prev;
 	int result = -EINVAL;
 	unsigned long flags;
 	unsigned int hash;
@@ -508,9 +510,10 @@
 	if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARUSR)
 		goto __return;
 
-	if (ev->data.ext.len < sizeof(snd_seq_instr_header_t))
+	if (ev->data.ext.len < sizeof(struct snd_seq_instr_header))
 		goto __return;
-	if (copy_from_user(&ifree, (void __user *)ev->data.ext.ptr, sizeof(snd_seq_instr_header_t))) {
+	if (copy_from_user(&ifree, (void __user *)ev->data.ext.ptr,
+			   sizeof(struct snd_seq_instr_header))) {
 		result = -EFAULT;
 		goto __return;
 	}
@@ -548,7 +551,8 @@
 			list->hash[hash] = instr->next;
 		}
 		if (instr->ops && instr->ops->notify)
-			instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
+			instr->ops->notify(instr->ops->private_data, instr,
+					   SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
 		while (instr->use) {
 			spin_unlock_irqrestore(&list->lock, flags);
 			schedule_timeout_interruptible(1);
@@ -565,25 +569,25 @@
 	return result;
 }
 
-static int instr_list(snd_seq_kinstr_ops_t *ops,
-		      snd_seq_kinstr_list_t *list,
-		      snd_seq_event_t *ev,
+static int instr_list(struct snd_seq_kinstr_ops *ops,
+		      struct snd_seq_kinstr_list *list,
+		      struct snd_seq_event *ev,
 		      int atomic, int hop)
 {
 	return -ENXIO;
 }
 
-static int instr_cluster(snd_seq_kinstr_ops_t *ops,
-			 snd_seq_kinstr_list_t *list,
-			 snd_seq_event_t *ev,
+static int instr_cluster(struct snd_seq_kinstr_ops *ops,
+			 struct snd_seq_kinstr_list *list,
+			 struct snd_seq_event *ev,
 			 int atomic, int hop)
 {
 	return -ENXIO;
 }
 
-int snd_seq_instr_event(snd_seq_kinstr_ops_t *ops,
-			snd_seq_kinstr_list_t *list,
-			snd_seq_event_t *ev,
+int snd_seq_instr_event(struct snd_seq_kinstr_ops *ops,
+			struct snd_seq_kinstr_list *list,
+			struct snd_seq_event *ev,
 			int client,
 			int atomic,
 			int hop)
diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
index 8416bcf..9ee6c17 100644
--- a/sound/core/seq/seq_memory.c
+++ b/sound/core/seq/seq_memory.c
@@ -36,12 +36,12 @@
 #define semaphore_of(fp)	((fp)->f_dentry->d_inode->i_sem)
 
 
-static inline int snd_seq_pool_available(pool_t *pool)
+static inline int snd_seq_pool_available(struct snd_seq_pool *pool)
 {
 	return pool->total_elements - atomic_read(&pool->counter);
 }
 
-static inline int snd_seq_output_ok(pool_t *pool)
+static inline int snd_seq_output_ok(struct snd_seq_pool *pool)
 {
 	return snd_seq_pool_available(pool) >= pool->room;
 }
@@ -72,7 +72,7 @@
  * call dump function to expand external data.
  */
 
-static int get_var_len(const snd_seq_event_t *event)
+static int get_var_len(const struct snd_seq_event *event)
 {
 	if ((event->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
 		return -EINVAL;
@@ -80,10 +80,11 @@
 	return event->data.ext.len & ~SNDRV_SEQ_EXT_MASK;
 }
 
-int snd_seq_dump_var_event(const snd_seq_event_t *event, snd_seq_dump_func_t func, void *private_data)
+int snd_seq_dump_var_event(const struct snd_seq_event *event,
+			   snd_seq_dump_func_t func, void *private_data)
 {
 	int len, err;
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 
 	if ((len = get_var_len(event)) <= 0)
 		return len;
@@ -108,9 +109,9 @@
 		return func(private_data, event->data.ext.ptr, len);
 	}
 
-	cell = (snd_seq_event_cell_t*)event->data.ext.ptr;
+	cell = (struct snd_seq_event_cell *)event->data.ext.ptr;
 	for (; len > 0 && cell; cell = cell->next) {
-		int size = sizeof(snd_seq_event_t);
+		int size = sizeof(struct snd_seq_event);
 		if (len < size)
 			size = len;
 		err = func(private_data, &cell->event, size);
@@ -142,7 +143,8 @@
 	return 0;
 }
 
-int snd_seq_expand_var_event(const snd_seq_event_t *event, int count, char *buf, int in_kernel, int size_aligned)
+int snd_seq_expand_var_event(const struct snd_seq_event *event, int count, char *buf,
+			     int in_kernel, int size_aligned)
 {
 	int len, newlen;
 	int err;
@@ -174,17 +176,18 @@
  * release this cell, free extended data if available
  */
 
-static inline void free_cell(pool_t *pool, snd_seq_event_cell_t *cell)
+static inline void free_cell(struct snd_seq_pool *pool,
+			     struct snd_seq_event_cell *cell)
 {
 	cell->next = pool->free;
 	pool->free = cell;
 	atomic_dec(&pool->counter);
 }
 
-void snd_seq_cell_free(snd_seq_event_cell_t * cell)
+void snd_seq_cell_free(struct snd_seq_event_cell * cell)
 {
 	unsigned long flags;
-	pool_t *pool;
+	struct snd_seq_pool *pool;
 
 	snd_assert(cell != NULL, return);
 	pool = cell->pool;
@@ -194,7 +197,7 @@
 	free_cell(pool, cell);
 	if (snd_seq_ev_is_variable(&cell->event)) {
 		if (cell->event.data.ext.len & SNDRV_SEQ_EXT_CHAINED) {
-			snd_seq_event_cell_t *curp, *nextptr;
+			struct snd_seq_event_cell *curp, *nextptr;
 			curp = cell->event.data.ext.ptr;
 			for (; curp; curp = nextptr) {
 				nextptr = curp->next;
@@ -215,9 +218,11 @@
 /*
  * allocate an event cell.
  */
-static int snd_seq_cell_alloc(pool_t *pool, snd_seq_event_cell_t **cellp, int nonblock, struct file *file)
+static int snd_seq_cell_alloc(struct snd_seq_pool *pool,
+			      struct snd_seq_event_cell **cellp,
+			      int nonblock, struct file *file)
 {
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 	unsigned long flags;
 	int err = -EAGAIN;
 	wait_queue_t wait;
@@ -280,11 +285,13 @@
  * if the event has external data, the data is decomposed to additional
  * cells.
  */
-int snd_seq_event_dup(pool_t *pool, snd_seq_event_t *event, snd_seq_event_cell_t **cellp, int nonblock, struct file *file)
+int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
+		      struct snd_seq_event_cell **cellp, int nonblock,
+		      struct file *file)
 {
 	int ncells, err;
 	unsigned int extlen;
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 
 	*cellp = NULL;
 
@@ -292,7 +299,7 @@
 	extlen = 0;
 	if (snd_seq_ev_is_variable(event)) {
 		extlen = event->data.ext.len & ~SNDRV_SEQ_EXT_MASK;
-		ncells = (extlen + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
+		ncells = (extlen + sizeof(struct snd_seq_event) - 1) / sizeof(struct snd_seq_event);
 	}
 	if (ncells >= pool->total_elements)
 		return -ENOMEM;
@@ -309,18 +316,18 @@
 		int len = extlen;
 		int is_chained = event->data.ext.len & SNDRV_SEQ_EXT_CHAINED;
 		int is_usrptr = event->data.ext.len & SNDRV_SEQ_EXT_USRPTR;
-		snd_seq_event_cell_t *src, *tmp, *tail;
+		struct snd_seq_event_cell *src, *tmp, *tail;
 		char *buf;
 
 		cell->event.data.ext.len = extlen | SNDRV_SEQ_EXT_CHAINED;
 		cell->event.data.ext.ptr = NULL;
 
-		src = (snd_seq_event_cell_t*)event->data.ext.ptr;
+		src = (struct snd_seq_event_cell *)event->data.ext.ptr;
 		buf = (char *)event->data.ext.ptr;
 		tail = NULL;
 
 		while (ncells-- > 0) {
-			int size = sizeof(snd_seq_event_t);
+			int size = sizeof(struct snd_seq_event);
 			if (len < size)
 				size = len;
 			err = snd_seq_cell_alloc(pool, &tmp, nonblock, file);
@@ -358,7 +365,8 @@
   
 
 /* poll wait */
-int snd_seq_pool_poll_wait(pool_t *pool, struct file *file, poll_table *wait)
+int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file,
+			   poll_table *wait)
 {
 	poll_wait(file, &pool->output_sleep, wait);
 	return snd_seq_output_ok(pool);
@@ -366,17 +374,17 @@
 
 
 /* allocate room specified number of events */
-int snd_seq_pool_init(pool_t *pool)
+int snd_seq_pool_init(struct snd_seq_pool *pool)
 {
 	int cell;
-	snd_seq_event_cell_t *cellptr;
+	struct snd_seq_event_cell *cellptr;
 	unsigned long flags;
 
 	snd_assert(pool != NULL, return -EINVAL);
 	if (pool->ptr)			/* should be atomic? */
 		return 0;
 
-	pool->ptr = vmalloc(sizeof(snd_seq_event_cell_t) * pool->size);
+	pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
 	if (pool->ptr == NULL) {
 		snd_printd("seq: malloc for sequencer events failed\n");
 		return -ENOMEM;
@@ -402,10 +410,10 @@
 }
 
 /* remove events */
-int snd_seq_pool_done(pool_t *pool)
+int snd_seq_pool_done(struct snd_seq_pool *pool)
 {
 	unsigned long flags;
-	snd_seq_event_cell_t *ptr;
+	struct snd_seq_event_cell *ptr;
 	int max_count = 5 * HZ;
 
 	snd_assert(pool != NULL, return -EINVAL);
@@ -446,9 +454,9 @@
 
 
 /* init new memory pool */
-pool_t *snd_seq_pool_new(int poolsize)
+struct snd_seq_pool *snd_seq_pool_new(int poolsize)
 {
-	pool_t *pool;
+	struct snd_seq_pool *pool;
 
 	/* create pool block */
 	pool = kzalloc(sizeof(*pool), GFP_KERNEL);
@@ -472,9 +480,9 @@
 }
 
 /* remove memory pool */
-int snd_seq_pool_delete(pool_t **ppool)
+int snd_seq_pool_delete(struct snd_seq_pool **ppool)
 {
-	pool_t *pool = *ppool;
+	struct snd_seq_pool *pool = *ppool;
 
 	*ppool = NULL;
 	if (pool == NULL)
@@ -497,7 +505,8 @@
 
 
 /* exported to seq_clientmgr.c */
-void snd_seq_info_pool(snd_info_buffer_t * buffer, pool_t *pool, char *space)
+void snd_seq_info_pool(struct snd_info_buffer *buffer,
+		       struct snd_seq_pool *pool, char *space)
 {
 	if (pool == NULL)
 		return;
diff --git a/sound/core/seq/seq_memory.h b/sound/core/seq/seq_memory.h
index 6c4dde5..39c60d9 100644
--- a/sound/core/seq/seq_memory.h
+++ b/sound/core/seq/seq_memory.h
@@ -24,23 +24,21 @@
 #include <sound/seq_kernel.h>
 #include <linux/poll.h>
 
-typedef struct pool pool_t;
-
 /* container for sequencer event (internal use) */
-typedef struct snd_seq_event_cell_t {
-	snd_seq_event_t event;
-	pool_t *pool;				/* used pool */
-	struct snd_seq_event_cell_t *next;	/* next cell */
-} snd_seq_event_cell_t;
+struct snd_seq_event_cell {
+	struct snd_seq_event event;
+	struct snd_seq_pool *pool;				/* used pool */
+	struct snd_seq_event_cell *next;	/* next cell */
+};
 
 /* design note: the pool is a contigious block of memory, if we dynamicly
    want to add additional cells to the pool be better store this in another
    pool as we need to know the base address of the pool when releasing
    memory. */
 
-struct pool {
-	snd_seq_event_cell_t *ptr;	/* pointer to first event chunk */
-	snd_seq_event_cell_t *free;	/* pointer to the head of the free list */
+struct snd_seq_pool {
+	struct snd_seq_event_cell *ptr;	/* pointer to first event chunk */
+	struct snd_seq_event_cell *free;	/* pointer to the head of the free list */
 
 	int total_elements;	/* pool size actually allocated */
 	atomic_t counter;	/* cells free */
@@ -63,33 +61,34 @@
 	spinlock_t lock;
 };
 
-extern void snd_seq_cell_free(snd_seq_event_cell_t* cell);
+void snd_seq_cell_free(struct snd_seq_event_cell *cell);
 
-int snd_seq_event_dup(pool_t *pool, snd_seq_event_t *event, snd_seq_event_cell_t **cellp, int nonblock, struct file *file);
+int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
+		      struct snd_seq_event_cell **cellp, int nonblock, struct file *file);
 
 /* return number of unused (free) cells */
-static inline int snd_seq_unused_cells(pool_t *pool)
+static inline int snd_seq_unused_cells(struct snd_seq_pool *pool)
 {
 	return pool ? pool->total_elements - atomic_read(&pool->counter) : 0;
 }
 
 /* return total number of allocated cells */
-static inline int snd_seq_total_cells(pool_t *pool)
+static inline int snd_seq_total_cells(struct snd_seq_pool *pool)
 {
 	return pool ? pool->total_elements : 0;
 }
 
 /* init pool - allocate events */
-int snd_seq_pool_init(pool_t *pool);
+int snd_seq_pool_init(struct snd_seq_pool *pool);
 
 /* done pool - free events */
-int snd_seq_pool_done(pool_t *pool);
+int snd_seq_pool_done(struct snd_seq_pool *pool);
 
 /* create pool */
-pool_t *snd_seq_pool_new(int poolsize);
+struct snd_seq_pool *snd_seq_pool_new(int poolsize);
 
 /* remove pool */
-int snd_seq_pool_delete(pool_t **pool);
+int snd_seq_pool_delete(struct snd_seq_pool **pool);
 
 /* init memory */
 int snd_sequencer_memory_init(void);
@@ -98,7 +97,7 @@
 void snd_sequencer_memory_done(void);
 
 /* polling */
-int snd_seq_pool_poll_wait(pool_t *pool, struct file *file, poll_table *wait);
+int snd_seq_pool_poll_wait(struct snd_seq_pool *pool, struct file *file, poll_table *wait);
 
 
 #endif
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index f89f40f..ce0df86 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -51,40 +51,40 @@
 MODULE_PARM_DESC(input_buffer_size, "Input buffer size in bytes.");
 
 /* data for this midi synth driver */
-typedef struct {
-	snd_card_t *card;
+struct seq_midisynth {
+	struct snd_card *card;
 	int device;
 	int subdevice;
-	snd_rawmidi_file_t input_rfile;
-	snd_rawmidi_file_t output_rfile;
+	struct snd_rawmidi_file input_rfile;
+	struct snd_rawmidi_file output_rfile;
 	int seq_client;
 	int seq_port;
-	snd_midi_event_t *parser;
-} seq_midisynth_t;
+	struct snd_midi_event *parser;
+};
 
-typedef struct {
+struct seq_midisynth_client {
 	int seq_client;
 	int num_ports;
 	int ports_per_device[SNDRV_RAWMIDI_DEVICES];
- 	seq_midisynth_t *ports[SNDRV_RAWMIDI_DEVICES];
-} seq_midisynth_client_t;
+ 	struct seq_midisynth *ports[SNDRV_RAWMIDI_DEVICES];
+};
 
-static seq_midisynth_client_t *synths[SNDRV_CARDS];
+static struct seq_midisynth_client *synths[SNDRV_CARDS];
 static DECLARE_MUTEX(register_mutex);
 
 /* handle rawmidi input event (MIDI v1.0 stream) */
-static void snd_midi_input_event(snd_rawmidi_substream_t * substream)
+static void snd_midi_input_event(struct snd_rawmidi_substream *substream)
 {
-	snd_rawmidi_runtime_t *runtime;
-	seq_midisynth_t *msynth;
-	snd_seq_event_t ev;
+	struct snd_rawmidi_runtime *runtime;
+	struct seq_midisynth *msynth;
+	struct snd_seq_event ev;
 	char buf[16], *pbuf;
 	long res, count;
 
 	if (substream == NULL)
 		return;
 	runtime = substream->runtime;
-	msynth = (seq_midisynth_t *) runtime->private_data;
+	msynth = runtime->private_data;
 	if (msynth == NULL)
 		return;
 	memset(&ev, 0, sizeof(ev));
@@ -112,9 +112,9 @@
 	}
 }
 
-static int dump_midi(snd_rawmidi_substream_t *substream, const char *buf, int count)
+static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, int count)
 {
-	snd_rawmidi_runtime_t *runtime;
+	struct snd_rawmidi_runtime *runtime;
 	int tmp;
 
 	snd_assert(substream != NULL || buf != NULL, return -EINVAL);
@@ -128,12 +128,12 @@
 	return 0;
 }
 
-static int event_process_midi(snd_seq_event_t * ev, int direct,
+static int event_process_midi(struct snd_seq_event *ev, int direct,
 			      void *private_data, int atomic, int hop)
 {
-	seq_midisynth_t *msynth = (seq_midisynth_t *) private_data;
+	struct seq_midisynth *msynth = private_data;
 	unsigned char msg[10];	/* buffer for constructing midi messages */
-	snd_rawmidi_substream_t *substream;
+	struct snd_rawmidi_substream *substream;
 	int len;
 
 	snd_assert(msynth != NULL, return -EINVAL);
@@ -161,8 +161,8 @@
 }
 
 
-static int snd_seq_midisynth_new(seq_midisynth_t *msynth,
-				 snd_card_t *card,
+static int snd_seq_midisynth_new(struct seq_midisynth *msynth,
+				 struct snd_card *card,
 				 int device,
 				 int subdevice)
 {
@@ -175,15 +175,18 @@
 }
 
 /* open associated midi device for input */
-static int midisynth_subscribe(void *private_data, snd_seq_port_subscribe_t *info)
+static int midisynth_subscribe(void *private_data, struct snd_seq_port_subscribe *info)
 {
 	int err;
-	seq_midisynth_t *msynth = (seq_midisynth_t *)private_data;
-	snd_rawmidi_runtime_t *runtime;
-	snd_rawmidi_params_t params;
+	struct seq_midisynth *msynth = private_data;
+	struct snd_rawmidi_runtime *runtime;
+	struct snd_rawmidi_params params;
 
 	/* open midi port */
-	if ((err = snd_rawmidi_kernel_open(msynth->card->number, msynth->device, msynth->subdevice, SNDRV_RAWMIDI_LFLG_INPUT, &msynth->input_rfile)) < 0) {
+	if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
+					   msynth->subdevice,
+					   SNDRV_RAWMIDI_LFLG_INPUT,
+					   &msynth->input_rfile)) < 0) {
 		snd_printd("midi input open failed!!!\n");
 		return err;
 	}
@@ -203,10 +206,10 @@
 }
 
 /* close associated midi device for input */
-static int midisynth_unsubscribe(void *private_data, snd_seq_port_subscribe_t *info)
+static int midisynth_unsubscribe(void *private_data, struct snd_seq_port_subscribe *info)
 {
 	int err;
-	seq_midisynth_t *msynth = (seq_midisynth_t *)private_data;
+	struct seq_midisynth *msynth = private_data;
 
 	snd_assert(msynth->input_rfile.input != NULL, return -EINVAL);
 	err = snd_rawmidi_kernel_release(&msynth->input_rfile);
@@ -214,14 +217,17 @@
 }
 
 /* open associated midi device for output */
-static int midisynth_use(void *private_data, snd_seq_port_subscribe_t *info)
+static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info)
 {
 	int err;
-	seq_midisynth_t *msynth = (seq_midisynth_t *)private_data;
-	snd_rawmidi_params_t params;
+	struct seq_midisynth *msynth = private_data;
+	struct snd_rawmidi_params params;
 
 	/* open midi port */
-	if ((err = snd_rawmidi_kernel_open(msynth->card->number, msynth->device, msynth->subdevice, SNDRV_RAWMIDI_LFLG_OUTPUT, &msynth->output_rfile)) < 0) {
+	if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
+					   msynth->subdevice,
+					   SNDRV_RAWMIDI_LFLG_OUTPUT,
+					   &msynth->output_rfile)) < 0) {
 		snd_printd("midi output open failed!!!\n");
 		return err;
 	}
@@ -237,9 +243,9 @@
 }
 
 /* close associated midi device for output */
-static int midisynth_unuse(void *private_data, snd_seq_port_subscribe_t *info)
+static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info)
 {
-	seq_midisynth_t *msynth = (seq_midisynth_t *)private_data;
+	struct seq_midisynth *msynth = private_data;
 	unsigned char buf = 0xff; /* MIDI reset */
 
 	snd_assert(msynth->output_rfile.output != NULL, return -EINVAL);
@@ -250,7 +256,7 @@
 }
 
 /* delete given midi synth port */
-static void snd_seq_midisynth_delete(seq_midisynth_t *msynth)
+static void snd_seq_midisynth_delete(struct seq_midisynth *msynth)
 {
 	if (msynth == NULL)
 		return;
@@ -264,34 +270,18 @@
 		snd_midi_event_free(msynth->parser);
 }
 
-/* set our client name */
-static int set_client_name(seq_midisynth_client_t *client, snd_card_t *card,
-			   snd_rawmidi_info_t *rmidi)
-{
-	snd_seq_client_info_t cinfo;
-	const char *name;
-
-	memset(&cinfo, 0, sizeof(cinfo));
-	cinfo.client = client->seq_client;
-	cinfo.type = KERNEL_CLIENT;
-	name = rmidi->name[0] ? (const char *)rmidi->name : "External MIDI";
-	strlcpy(cinfo.name, name, sizeof(cinfo.name));
-	return snd_seq_kernel_client_ctl(client->seq_client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
-}
-
 /* register new midi synth port */
 static int
-snd_seq_midisynth_register_port(snd_seq_device_t *dev)
+snd_seq_midisynth_register_port(struct snd_seq_device *dev)
 {
-	seq_midisynth_client_t *client;
-	seq_midisynth_t *msynth, *ms;
-	snd_seq_port_info_t *port;
-	snd_rawmidi_info_t *info;
+	struct seq_midisynth_client *client;
+	struct seq_midisynth *msynth, *ms;
+	struct snd_seq_port_info *port;
+	struct snd_rawmidi_info *info;
 	int newclient = 0;
 	unsigned int p, ports;
-	snd_seq_client_callback_t callbacks;
-	snd_seq_port_callback_t pcallbacks;
-	snd_card_t *card = dev->card;
+	struct snd_seq_port_callback pcallbacks;
+	struct snd_card *card = dev->card;
 	int device = dev->device;
 	unsigned int input_count = 0, output_count = 0;
 
@@ -328,21 +318,19 @@
 			kfree(info);
 			return -ENOMEM;
 		}
-		memset(&callbacks, 0, sizeof(callbacks));
-		callbacks.private_data = client;
-		callbacks.allow_input = callbacks.allow_output = 1;
-		client->seq_client = snd_seq_create_kernel_client(card, 0, &callbacks);
+		client->seq_client =
+			snd_seq_create_kernel_client(
+				card, 0, "%s", info->name[0] ?
+				(const char *)info->name : "External MIDI");
 		if (client->seq_client < 0) {
 			kfree(client);
 			up(&register_mutex);
 			kfree(info);
 			return -ENOMEM;
 		}
-		set_client_name(client, card, info);
-	} else if (device == 0)
-		set_client_name(client, card, info); /* use the first device's name */
+	}
 
-	msynth = kcalloc(ports, sizeof(seq_midisynth_t), GFP_KERNEL);
+	msynth = kcalloc(ports, sizeof(struct seq_midisynth), GFP_KERNEL);
 	port = kmalloc(sizeof(*port), GFP_KERNEL);
 	if (msynth == NULL || port == NULL)
 		goto __nomem;
@@ -432,11 +420,11 @@
 
 /* release midi synth port */
 static int
-snd_seq_midisynth_unregister_port(snd_seq_device_t *dev)
+snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
 {
-	seq_midisynth_client_t *client;
-	seq_midisynth_t *msynth;
-	snd_card_t *card = dev->card;
+	struct seq_midisynth_client *client;
+	struct seq_midisynth *msynth;
+	struct snd_card *card = dev->card;
 	int device = dev->device, p, ports;
 	
 	down(&register_mutex);
@@ -465,7 +453,7 @@
 
 static int __init alsa_seq_midi_init(void)
 {
-	static snd_seq_dev_ops_t ops = {
+	static struct snd_seq_dev_ops ops = {
 		snd_seq_midisynth_register_port,
 		snd_seq_midisynth_unregister_port,
 	};
diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
index 35fe8a7..d7c4fb8 100644
--- a/sound/core/seq/seq_midi_emul.c
+++ b/sound/core/seq/seq_midi_emul.c
@@ -44,17 +44,25 @@
 MODULE_LICENSE("GPL");
 
 /* Prototypes for static functions */
-static void note_off(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan, int note, int vel);
-static void do_control(snd_midi_op_t *ops, void *private,
-		       snd_midi_channel_set_t *chset, snd_midi_channel_t *chan,
+static void note_off(struct snd_midi_op *ops, void *drv,
+		     struct snd_midi_channel *chan,
+		     int note, int vel);
+static void do_control(struct snd_midi_op *ops, void *private,
+		       struct snd_midi_channel_set *chset,
+		       struct snd_midi_channel *chan,
 		       int control, int value);
-static void rpn(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);
-static void nrpn(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);
-static void sysex(snd_midi_op_t *ops, void *private, unsigned char *sysex, int len, snd_midi_channel_set_t *chset);
-static void all_sounds_off(snd_midi_op_t *ops, void *private, snd_midi_channel_t *chan);
-static void all_notes_off(snd_midi_op_t *ops, void *private, snd_midi_channel_t *chan);
-static void snd_midi_reset_controllers(snd_midi_channel_t *chan);
-static void reset_all_channels(snd_midi_channel_set_t *chset);
+static void rpn(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
+		struct snd_midi_channel_set *chset);
+static void nrpn(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
+		 struct snd_midi_channel_set *chset);
+static void sysex(struct snd_midi_op *ops, void *private, unsigned char *sysex,
+		  int len, struct snd_midi_channel_set *chset);
+static void all_sounds_off(struct snd_midi_op *ops, void *private,
+			   struct snd_midi_channel *chan);
+static void all_notes_off(struct snd_midi_op *ops, void *private,
+			  struct snd_midi_channel *chan);
+static void snd_midi_reset_controllers(struct snd_midi_channel *chan);
+static void reset_all_channels(struct snd_midi_channel_set *chset);
 
 
 /*
@@ -72,10 +80,11 @@
  *        be interpreted.
  */
 void
-snd_midi_process_event(snd_midi_op_t *ops,
-		       snd_seq_event_t *ev, snd_midi_channel_set_t *chanset)
+snd_midi_process_event(struct snd_midi_op *ops,
+		       struct snd_seq_event *ev,
+		       struct snd_midi_channel_set *chanset)
 {
-	snd_midi_channel_t *chan;
+	struct snd_midi_channel *chan;
 	void *drv;
 	int dest_channel = 0;
 
@@ -89,7 +98,8 @@
 	if (snd_seq_ev_is_channel_type(ev)) {
 		dest_channel = ev->data.note.channel;
 		if (dest_channel >= chanset->max_channels) {
-			snd_printd("dest channel is %d, max is %d\n", dest_channel, chanset->max_channels);
+			snd_printd("dest channel is %d, max is %d\n",
+				   dest_channel, chanset->max_channels);
 			return;
 		}
 	}
@@ -239,7 +249,8 @@
  * release note
  */
 static void
-note_off(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan, int note, int vel)
+note_off(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
+	 int note, int vel)
 {
 	if (chan->gm_hold) {
 		/* Hold this note until pedal is turned off */
@@ -260,8 +271,8 @@
  * events that need to take place immediately to the driver.
  */
 static void
-do_control(snd_midi_op_t *ops, void *drv, snd_midi_channel_set_t *chset,
-	   snd_midi_channel_t *chan, int control, int value)
+do_control(struct snd_midi_op *ops, void *drv, struct snd_midi_channel_set *chset,
+	   struct snd_midi_channel *chan, int control, int value)
 {
 	int  i;
 
@@ -376,7 +387,7 @@
  * initialize the MIDI status
  */
 void
-snd_midi_channel_set_clear(snd_midi_channel_set_t *chset)
+snd_midi_channel_set_clear(struct snd_midi_channel_set *chset)
 {
 	int i;
 
@@ -384,7 +395,7 @@
 	chset->gs_master_volume = 127;
 
 	for (i = 0; i < chset->max_channels; i++) {
-		snd_midi_channel_t *chan = chset->channels + i;
+		struct snd_midi_channel *chan = chset->channels + i;
 		memset(chan->note, 0, sizeof(chan->note));
 
 		chan->midi_aftertouch = 0;
@@ -407,8 +418,8 @@
  * Process a rpn message.
  */
 static void
-rpn(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan,
-    snd_midi_channel_set_t *chset)
+rpn(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
+    struct snd_midi_channel_set *chset)
 {
 	int type;
 	int val;
@@ -447,8 +458,8 @@
  * Process an nrpn message.
  */
 static void
-nrpn(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan,
-     snd_midi_channel_set_t *chset)
+nrpn(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
+     struct snd_midi_channel_set *chset)
 {
 	/* parse XG NRPNs here if possible */
 	if (ops->nrpn)
@@ -475,7 +486,8 @@
  * Process a sysex message.
  */
 static void
-sysex(snd_midi_op_t *ops, void *private, unsigned char *buf, int len, snd_midi_channel_set_t *chset)
+sysex(struct snd_midi_op *ops, void *private, unsigned char *buf, int len,
+      struct snd_midi_channel_set *chset)
 {
 	/* GM on */
 	static unsigned char gm_on_macro[] = {
@@ -588,7 +600,7 @@
  * all sound off
  */
 static void
-all_sounds_off(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan)
+all_sounds_off(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan)
 {
 	int n;
 
@@ -606,7 +618,7 @@
  * all notes off
  */
 static void
-all_notes_off(snd_midi_op_t *ops, void *drv, snd_midi_channel_t *chan)
+all_notes_off(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan)
 {
 	int n;
 
@@ -621,12 +633,12 @@
 /*
  * Initialise a single midi channel control block.
  */
-static void snd_midi_channel_init(snd_midi_channel_t *p, int n)
+static void snd_midi_channel_init(struct snd_midi_channel *p, int n)
 {
 	if (p == NULL)
 		return;
 
-	memset(p, 0, sizeof(snd_midi_channel_t));
+	memset(p, 0, sizeof(struct snd_midi_channel));
 	p->private = NULL;
 	p->number = n;
 
@@ -642,12 +654,12 @@
 /*
  * Allocate and initialise a set of midi channel control blocks.
  */
-static snd_midi_channel_t *snd_midi_channel_init_set(int n)
+static struct snd_midi_channel *snd_midi_channel_init_set(int n)
 {
-	snd_midi_channel_t *chan;
+	struct snd_midi_channel *chan;
 	int  i;
 
-	chan = kmalloc(n * sizeof(snd_midi_channel_t), GFP_KERNEL);
+	chan = kmalloc(n * sizeof(struct snd_midi_channel), GFP_KERNEL);
 	if (chan) {
 		for (i = 0; i < n; i++)
 			snd_midi_channel_init(chan+i, i);
@@ -660,11 +672,11 @@
  * reset all midi channels
  */
 static void
-reset_all_channels(snd_midi_channel_set_t *chset)
+reset_all_channels(struct snd_midi_channel_set *chset)
 {
 	int ch;
 	for (ch = 0; ch < chset->max_channels; ch++) {
-		snd_midi_channel_t *chan = chset->channels + ch;
+		struct snd_midi_channel *chan = chset->channels + ch;
 		snd_midi_reset_controllers(chan);
 		chan->gm_rpn_pitch_bend_range = 256; /* 2 semitones */
 		chan->gm_rpn_fine_tuning = 0;
@@ -681,9 +693,9 @@
 /*
  * Allocate and initialise a midi channel set.
  */
-snd_midi_channel_set_t *snd_midi_channel_alloc_set(int n)
+struct snd_midi_channel_set *snd_midi_channel_alloc_set(int n)
 {
-	snd_midi_channel_set_t *chset;
+	struct snd_midi_channel_set *chset;
 
 	chset = kmalloc(sizeof(*chset), GFP_KERNEL);
 	if (chset) {
@@ -697,7 +709,7 @@
 /*
  * Reset the midi controllers on a particular channel to default values.
  */
-static void snd_midi_reset_controllers(snd_midi_channel_t *chan)
+static void snd_midi_reset_controllers(struct snd_midi_channel *chan)
 {
 	memset(chan->control, 0, sizeof(chan->control));
 	chan->gm_volume = 127;
@@ -709,7 +721,7 @@
 /*
  * Free a midi channel set.
  */
-void snd_midi_channel_free_set(snd_midi_channel_set_t *chset)
+void snd_midi_channel_free_set(struct snd_midi_channel_set *chset)
 {
 	if (chset == NULL)
 		return;
diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c
index 2dc1aec..5ff80b7 100644
--- a/sound/core/seq/seq_midi_event.c
+++ b/sound/core/seq/seq_midi_event.c
@@ -41,33 +41,29 @@
 /* from 8 to 15 are events for 0xf0-0xf7 */
 
 
-/* status event types */
-typedef void (*event_encode_t)(snd_midi_event_t *dev, snd_seq_event_t *ev);
-typedef void (*event_decode_t)(snd_seq_event_t *ev, unsigned char *buf);
-
 /*
  * prototypes
  */
-static void note_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
-static void one_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
-static void pitchbend_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
-static void two_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
-static void one_param_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
-static void songpos_event(snd_midi_event_t *dev, snd_seq_event_t *ev);
-static void note_decode(snd_seq_event_t *ev, unsigned char *buf);
-static void one_param_decode(snd_seq_event_t *ev, unsigned char *buf);
-static void pitchbend_decode(snd_seq_event_t *ev, unsigned char *buf);
-static void two_param_decode(snd_seq_event_t *ev, unsigned char *buf);
-static void songpos_decode(snd_seq_event_t *ev, unsigned char *buf);
+static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
+static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
+static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
+static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
+static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
+static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev);
+static void note_decode(struct snd_seq_event *ev, unsigned char *buf);
+static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf);
+static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf);
+static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf);
+static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf);
 
 /*
  * event list
  */
-static struct status_event_list_t {
+static struct status_event_list {
 	int event;
 	int qlen;
-	event_encode_t encode;
-	event_decode_t decode;
+	void (*encode)(struct snd_midi_event *dev, struct snd_seq_event *ev);
+	void (*decode)(struct snd_seq_event *ev, unsigned char *buf);
 } status_event[] = {
 	/* 0x80 - 0xf0 */
 	{SNDRV_SEQ_EVENT_NOTEOFF,	2, note_event, note_decode},
@@ -97,12 +93,15 @@
 	{SNDRV_SEQ_EVENT_RESET, 	0, NULL, NULL}, /* 0xff */
 };
 
-static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int len, snd_seq_event_t *ev);
-static int extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int count, snd_seq_event_t *ev);
+static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf, int len,
+			       struct snd_seq_event *ev);
+static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf, int count,
+			     struct snd_seq_event *ev);
 
-static struct extra_event_list_t {
+static struct extra_event_list {
 	int event;
-	int (*decode)(snd_midi_event_t *dev, unsigned char *buf, int len, snd_seq_event_t *ev);
+	int (*decode)(struct snd_midi_event *dev, unsigned char *buf, int len,
+		      struct snd_seq_event *ev);
 } extra_event[] = {
 	{SNDRV_SEQ_EVENT_CONTROL14, extra_decode_ctrl14},
 	{SNDRV_SEQ_EVENT_NONREGPARAM, extra_decode_xrpn},
@@ -113,9 +112,9 @@
  *  new/delete record
  */
 
-int snd_midi_event_new(int bufsize, snd_midi_event_t **rdev)
+int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev)
 {
-	snd_midi_event_t *dev;
+	struct snd_midi_event *dev;
 
 	*rdev = NULL;
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -135,7 +134,7 @@
 	return 0;
 }
 
-void snd_midi_event_free(snd_midi_event_t *dev)
+void snd_midi_event_free(struct snd_midi_event *dev)
 {
 	if (dev != NULL) {
 		kfree(dev->buf);
@@ -146,14 +145,14 @@
 /*
  * initialize record
  */
-static inline void reset_encode(snd_midi_event_t *dev)
+static inline void reset_encode(struct snd_midi_event *dev)
 {
 	dev->read = 0;
 	dev->qlen = 0;
 	dev->type = 0;
 }
 
-void snd_midi_event_reset_encode(snd_midi_event_t *dev)
+void snd_midi_event_reset_encode(struct snd_midi_event *dev)
 {
 	unsigned long flags;
 
@@ -162,7 +161,7 @@
 	spin_unlock_irqrestore(&dev->lock, flags);
 }
 
-void snd_midi_event_reset_decode(snd_midi_event_t *dev)
+void snd_midi_event_reset_decode(struct snd_midi_event *dev)
 {
 	unsigned long flags;
 
@@ -172,14 +171,14 @@
 }
 
 #if 0
-void snd_midi_event_init(snd_midi_event_t *dev)
+void snd_midi_event_init(struct snd_midi_event *dev)
 {
 	snd_midi_event_reset_encode(dev);
 	snd_midi_event_reset_decode(dev);
 }
 #endif  /*  0  */
 
-void snd_midi_event_no_status(snd_midi_event_t *dev, int on)
+void snd_midi_event_no_status(struct snd_midi_event *dev, int on)
 {
 	dev->nostat = on ? 1 : 0;
 }
@@ -188,7 +187,7 @@
  * resize buffer
  */
 #if 0
-int snd_midi_event_resize_buffer(snd_midi_event_t *dev, int bufsize)
+int snd_midi_event_resize_buffer(struct snd_midi_event *dev, int bufsize)
 {
 	unsigned char *new_buf, *old_buf;
 	unsigned long flags;
@@ -213,7 +212,8 @@
  *  read bytes and encode to sequencer event if finished
  *  return the size of encoded bytes
  */
-long snd_midi_event_encode(snd_midi_event_t *dev, unsigned char *buf, long count, snd_seq_event_t *ev)
+long snd_midi_event_encode(struct snd_midi_event *dev, unsigned char *buf, long count,
+			   struct snd_seq_event *ev)
 {
 	long result = 0;
 	int rc;
@@ -238,7 +238,8 @@
  *         0 data is not finished
  *         negative for error
  */
-int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev)
+int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
+			       struct snd_seq_event *ev)
 {
 	int rc = 0;
 	unsigned long flags;
@@ -303,7 +304,7 @@
 }
 
 /* encode note event */
-static void note_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
+static void note_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 {
 	ev->data.note.channel = dev->buf[0] & 0x0f;
 	ev->data.note.note = dev->buf[1];
@@ -311,21 +312,21 @@
 }
 
 /* encode one parameter controls */
-static void one_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
+static void one_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 {
 	ev->data.control.channel = dev->buf[0] & 0x0f;
 	ev->data.control.value = dev->buf[1];
 }
 
 /* encode pitch wheel change */
-static void pitchbend_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
+static void pitchbend_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 {
 	ev->data.control.channel = dev->buf[0] & 0x0f;
 	ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1] - 8192;
 }
 
 /* encode midi control change */
-static void two_param_ctrl_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
+static void two_param_ctrl_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 {
 	ev->data.control.channel = dev->buf[0] & 0x0f;
 	ev->data.control.param = dev->buf[1];
@@ -333,13 +334,13 @@
 }
 
 /* encode one parameter value*/
-static void one_param_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
+static void one_param_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 {
 	ev->data.control.value = dev->buf[1];
 }
 
 /* encode song position */
-static void songpos_event(snd_midi_event_t *dev, snd_seq_event_t *ev)
+static void songpos_event(struct snd_midi_event *dev, struct snd_seq_event *ev)
 {
 	ev->data.control.value = (int)dev->buf[2] * 128 + (int)dev->buf[1];
 }
@@ -348,7 +349,8 @@
  * decode from a sequencer event to midi bytes
  * return the size of decoded midi events
  */
-long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count, snd_seq_event_t *ev)
+long snd_midi_event_decode(struct snd_midi_event *dev, unsigned char *buf, long count,
+			   struct snd_seq_event *ev)
 {
 	unsigned int cmd, type;
 
@@ -404,20 +406,20 @@
 
 
 /* decode note event */
-static void note_decode(snd_seq_event_t *ev, unsigned char *buf)
+static void note_decode(struct snd_seq_event *ev, unsigned char *buf)
 {
 	buf[0] = ev->data.note.note & 0x7f;
 	buf[1] = ev->data.note.velocity & 0x7f;
 }
 
 /* decode one parameter controls */
-static void one_param_decode(snd_seq_event_t *ev, unsigned char *buf)
+static void one_param_decode(struct snd_seq_event *ev, unsigned char *buf)
 {
 	buf[0] = ev->data.control.value & 0x7f;
 }
 
 /* decode pitch wheel change */
-static void pitchbend_decode(snd_seq_event_t *ev, unsigned char *buf)
+static void pitchbend_decode(struct snd_seq_event *ev, unsigned char *buf)
 {
 	int value = ev->data.control.value + 8192;
 	buf[0] = value & 0x7f;
@@ -425,21 +427,22 @@
 }
 
 /* decode midi control change */
-static void two_param_decode(snd_seq_event_t *ev, unsigned char *buf)
+static void two_param_decode(struct snd_seq_event *ev, unsigned char *buf)
 {
 	buf[0] = ev->data.control.param & 0x7f;
 	buf[1] = ev->data.control.value & 0x7f;
 }
 
 /* decode song position */
-static void songpos_decode(snd_seq_event_t *ev, unsigned char *buf)
+static void songpos_decode(struct snd_seq_event *ev, unsigned char *buf)
 {
 	buf[0] = ev->data.control.value & 0x7f;
 	buf[1] = (ev->data.control.value >> 7) & 0x7f;
 }
 
 /* decode 14bit control */
-static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int count, snd_seq_event_t *ev)
+static int extra_decode_ctrl14(struct snd_midi_event *dev, unsigned char *buf,
+			       int count, struct snd_seq_event *ev)
 {
 	unsigned char cmd;
 	int idx = 0;
@@ -476,7 +479,8 @@
 }
 
 /* decode reg/nonreg param */
-static int extra_decode_xrpn(snd_midi_event_t *dev, unsigned char *buf, int count, snd_seq_event_t *ev)
+static int extra_decode_xrpn(struct snd_midi_event *dev, unsigned char *buf,
+			     int count, struct snd_seq_event *ev)
 {
 	unsigned char cmd;
 	char *cbytes;
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index 57ec31d..2b384fd 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -56,16 +56,17 @@
 */
 
 /* return pointer to port structure - port is locked if found */
-client_port_t *snd_seq_port_use_ptr(client_t *client, int num)
+struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client,
+						 int num)
 {
 	struct list_head *p;
-	client_port_t *port;
+	struct snd_seq_client_port *port;
 
 	if (client == NULL)
 		return NULL;
 	read_lock(&client->ports_lock);
 	list_for_each(p, &client->ports_list_head) {
-		port = list_entry(p, client_port_t, list);
+		port = list_entry(p, struct snd_seq_client_port, list);
 		if (port->addr.port == num) {
 			if (port->closing)
 				break; /* deleting now */
@@ -80,17 +81,18 @@
 
 
 /* search for the next port - port is locked if found */
-client_port_t *snd_seq_port_query_nearest(client_t *client, snd_seq_port_info_t *pinfo)
+struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *client,
+						       struct snd_seq_port_info *pinfo)
 {
 	int num;
 	struct list_head *p;
-	client_port_t *port, *found;
+	struct snd_seq_client_port *port, *found;
 
 	num = pinfo->addr.port;
 	found = NULL;
 	read_lock(&client->ports_lock);
 	list_for_each(p, &client->ports_list_head) {
-		port = list_entry(p, client_port_t, list);
+		port = list_entry(p, struct snd_seq_client_port, list);
 		if (port->addr.port < num)
 			continue;
 		if (port->addr.port == num) {
@@ -111,8 +113,8 @@
 }
 
 
-/* initialize port_subs_info_t */
-static void port_subs_info_init(port_subs_info_t *grp)
+/* initialize snd_seq_port_subs_info */
+static void port_subs_info_init(struct snd_seq_port_subs_info *grp)
 {
 	INIT_LIST_HEAD(&grp->list_head);
 	grp->count = 0;
@@ -125,10 +127,11 @@
 
 
 /* create a port, port number is returned (-1 on failure) */
-client_port_t *snd_seq_create_port(client_t *client, int port)
+struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
+						int port)
 {
 	unsigned long flags;
-	client_port_t *new_port;
+	struct snd_seq_client_port *new_port;
 	struct list_head *l;
 	int num = -1;
 	
@@ -159,7 +162,7 @@
 	down(&client->ports_mutex);
 	write_lock_irqsave(&client->ports_lock, flags);
 	list_for_each(l, &client->ports_list_head) {
-		client_port_t *p = list_entry(l, client_port_t, list);
+		struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
 		if (p->addr.port > num)
 			break;
 		if (port < 0) /* auto-probe mode */
@@ -177,17 +180,24 @@
 }
 
 /* */
-enum group_type_t {
+enum group_type {
 	SRC_LIST, DEST_LIST
 };
 
-static int subscribe_port(client_t *client, client_port_t *port, port_subs_info_t *grp, snd_seq_port_subscribe_t *info, int send_ack);
-static int unsubscribe_port(client_t *client, client_port_t *port, port_subs_info_t *grp, snd_seq_port_subscribe_t *info, int send_ack);
+static int subscribe_port(struct snd_seq_client *client,
+			  struct snd_seq_client_port *port,
+			  struct snd_seq_port_subs_info *grp,
+			  struct snd_seq_port_subscribe *info, int send_ack);
+static int unsubscribe_port(struct snd_seq_client *client,
+			    struct snd_seq_client_port *port,
+			    struct snd_seq_port_subs_info *grp,
+			    struct snd_seq_port_subscribe *info, int send_ack);
 
 
-static client_port_t *get_client_port(snd_seq_addr_t *addr, client_t **cp)
+static struct snd_seq_client_port *get_client_port(struct snd_seq_addr *addr,
+						   struct snd_seq_client **cp)
 {
-	client_port_t *p;
+	struct snd_seq_client_port *p;
 	*cp = snd_seq_client_use_ptr(addr->client);
 	if (*cp) {
 		p = snd_seq_port_use_ptr(*cp, addr->port);
@@ -204,22 +214,24 @@
  * remove all subscribers on the list
  * this is called from port_delete, for each src and dest list.
  */
-static void clear_subscriber_list(client_t *client, client_port_t *port,
-				  port_subs_info_t *grp, int grptype)
+static void clear_subscriber_list(struct snd_seq_client *client,
+				  struct snd_seq_client_port *port,
+				  struct snd_seq_port_subs_info *grp,
+				  int grptype)
 {
 	struct list_head *p, *n;
 
 	down_write(&grp->list_mutex);
 	list_for_each_safe(p, n, &grp->list_head) {
-		subscribers_t *subs;
-		client_t *c;
-		client_port_t *aport;
+		struct snd_seq_subscribers *subs;
+		struct snd_seq_client *c;
+		struct snd_seq_client_port *aport;
 
 		if (grptype == SRC_LIST) {
-			subs = list_entry(p, subscribers_t, src_list);
+			subs = list_entry(p, struct snd_seq_subscribers, src_list);
 			aport = get_client_port(&subs->info.dest, &c);
 		} else {
-			subs = list_entry(p, subscribers_t, dest_list);
+			subs = list_entry(p, struct snd_seq_subscribers, dest_list);
 			aport = get_client_port(&subs->info.sender, &c);
 		}
 		list_del(p);
@@ -233,7 +245,7 @@
 				kfree(subs);
 		} else {
 			/* ok we got the connected port */
-			port_subs_info_t *agrp;
+			struct snd_seq_port_subs_info *agrp;
 			agrp = (grptype == SRC_LIST) ? &aport->c_dest : &aport->c_src;
 			down_write(&agrp->list_mutex);
 			if (grptype == SRC_LIST)
@@ -251,7 +263,8 @@
 }
 
 /* delete port data */
-static int port_delete(client_t *client, client_port_t *port)
+static int port_delete(struct snd_seq_client *client,
+		       struct snd_seq_client_port *port)
 {
 	/* set closing flag and wait for all port access are gone */
 	port->closing = 1;
@@ -273,16 +286,16 @@
 
 
 /* delete a port with the given port id */
-int snd_seq_delete_port(client_t *client, int port)
+int snd_seq_delete_port(struct snd_seq_client *client, int port)
 {
 	unsigned long flags;
 	struct list_head *l;
-	client_port_t *found = NULL;
+	struct snd_seq_client_port *found = NULL;
 
 	down(&client->ports_mutex);
 	write_lock_irqsave(&client->ports_lock, flags);
 	list_for_each(l, &client->ports_list_head) {
-		client_port_t *p = list_entry(l, client_port_t, list);
+		struct snd_seq_client_port *p = list_entry(l, struct snd_seq_client_port, list);
 		if (p->addr.port == port) {
 			/* ok found.  delete from the list at first */
 			list_del(l);
@@ -300,7 +313,7 @@
 }
 
 /* delete the all ports belonging to the given client */
-int snd_seq_delete_all_ports(client_t *client)
+int snd_seq_delete_all_ports(struct snd_seq_client *client)
 {
 	unsigned long flags;
 	struct list_head deleted_list, *p, *n;
@@ -323,7 +336,7 @@
 
 	/* remove each port in deleted_list */
 	list_for_each_safe(p, n, &deleted_list) {
-		client_port_t *port = list_entry(p, client_port_t, list);
+		struct snd_seq_client_port *port = list_entry(p, struct snd_seq_client_port, list);
 		list_del(p);
 		snd_seq_system_client_ev_port_exit(port->addr.client, port->addr.port);
 		port_delete(client, port);
@@ -333,7 +346,8 @@
 }
 
 /* set port info fields */
-int snd_seq_set_port_info(client_port_t * port, snd_seq_port_info_t * info)
+int snd_seq_set_port_info(struct snd_seq_client_port * port,
+			  struct snd_seq_port_info * info)
 {
 	snd_assert(port && info, return -EINVAL);
 
@@ -361,7 +375,8 @@
 }
 
 /* get port info fields */
-int snd_seq_get_port_info(client_port_t * port, snd_seq_port_info_t * info)
+int snd_seq_get_port_info(struct snd_seq_client_port * port,
+			  struct snd_seq_port_info * info)
 {
 	snd_assert(port && info, return -EINVAL);
 
@@ -410,8 +425,11 @@
  * at each connnection/disconnection. 
  */
 
-static int subscribe_port(client_t *client, client_port_t *port, port_subs_info_t *grp,
-			  snd_seq_port_subscribe_t *info, int send_ack)
+static int subscribe_port(struct snd_seq_client *client,
+			  struct snd_seq_client_port *port,
+			  struct snd_seq_port_subs_info *grp,
+			  struct snd_seq_port_subscribe *info,
+			  int send_ack)
 {
 	int err = 0;
 
@@ -432,9 +450,11 @@
 	return err;
 }
 
-static int unsubscribe_port(client_t *client, client_port_t *port,
-			    port_subs_info_t *grp,
-			    snd_seq_port_subscribe_t *info, int send_ack)
+static int unsubscribe_port(struct snd_seq_client *client,
+			    struct snd_seq_client_port *port,
+			    struct snd_seq_port_subs_info *grp,
+			    struct snd_seq_port_subscribe *info,
+			    int send_ack)
 {
 	int err = 0;
 
@@ -453,15 +473,15 @@
 
 
 /* check if both addresses are identical */
-static inline int addr_match(snd_seq_addr_t *r, snd_seq_addr_t *s)
+static inline int addr_match(struct snd_seq_addr *r, struct snd_seq_addr *s)
 {
 	return (r->client == s->client) && (r->port == s->port);
 }
 
 /* check the two subscribe info match */
 /* if flags is zero, checks only sender and destination addresses */
-static int match_subs_info(snd_seq_port_subscribe_t *r,
-			   snd_seq_port_subscribe_t *s)
+static int match_subs_info(struct snd_seq_port_subscribe *r,
+			   struct snd_seq_port_subscribe *s)
 {
 	if (addr_match(&r->sender, &s->sender) &&
 	    addr_match(&r->dest, &s->dest)) {
@@ -475,14 +495,16 @@
 
 
 /* connect two ports */
-int snd_seq_port_connect(client_t *connector,
-			 client_t *src_client, client_port_t *src_port,
-			 client_t *dest_client, client_port_t *dest_port,
-			 snd_seq_port_subscribe_t *info)
+int snd_seq_port_connect(struct snd_seq_client *connector,
+			 struct snd_seq_client *src_client,
+			 struct snd_seq_client_port *src_port,
+			 struct snd_seq_client *dest_client,
+			 struct snd_seq_client_port *dest_port,
+			 struct snd_seq_port_subscribe *info)
 {
-	port_subs_info_t *src = &src_port->c_src;
-	port_subs_info_t *dest = &dest_port->c_dest;
-	subscribers_t *subs;
+	struct snd_seq_port_subs_info *src = &src_port->c_src;
+	struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
+	struct snd_seq_subscribers *subs;
 	struct list_head *p;
 	int err, src_called = 0;
 	unsigned long flags;
@@ -508,12 +530,12 @@
 			goto __error;
 		/* check whether already exists */
 		list_for_each(p, &src->list_head) {
-			subscribers_t *s = list_entry(p, subscribers_t, src_list);
+			struct snd_seq_subscribers *s = list_entry(p, struct snd_seq_subscribers, src_list);
 			if (match_subs_info(info, &s->info))
 				goto __error;
 		}
 		list_for_each(p, &dest->list_head) {
-			subscribers_t *s = list_entry(p, subscribers_t, dest_list);
+			struct snd_seq_subscribers *s = list_entry(p, struct snd_seq_subscribers, dest_list);
 			if (match_subs_info(info, &s->info))
 				goto __error;
 		}
@@ -554,14 +576,16 @@
 
 
 /* remove the connection */
-int snd_seq_port_disconnect(client_t *connector,
-			    client_t *src_client, client_port_t *src_port,
-			    client_t *dest_client, client_port_t *dest_port,
-			    snd_seq_port_subscribe_t *info)
+int snd_seq_port_disconnect(struct snd_seq_client *connector,
+			    struct snd_seq_client *src_client,
+			    struct snd_seq_client_port *src_port,
+			    struct snd_seq_client *dest_client,
+			    struct snd_seq_client_port *dest_port,
+			    struct snd_seq_port_subscribe *info)
 {
-	port_subs_info_t *src = &src_port->c_src;
-	port_subs_info_t *dest = &dest_port->c_dest;
-	subscribers_t *subs;
+	struct snd_seq_port_subs_info *src = &src_port->c_src;
+	struct snd_seq_port_subs_info *dest = &dest_port->c_dest;
+	struct snd_seq_subscribers *subs;
 	struct list_head *p;
 	int err = -ENOENT;
 	unsigned long flags;
@@ -571,7 +595,7 @@
 
 	/* look for the connection */
 	list_for_each(p, &src->list_head) {
-		subs = list_entry(p, subscribers_t, src_list);
+		subs = list_entry(p, struct snd_seq_subscribers, src_list);
 		if (match_subs_info(info, &subs->info)) {
 			write_lock_irqsave(&src->list_lock, flags);
 			// write_lock(&dest->list_lock);  // no lock yet
@@ -597,15 +621,15 @@
 
 
 /* get matched subscriber */
-subscribers_t *snd_seq_port_get_subscription(port_subs_info_t *src_grp,
-					     snd_seq_addr_t *dest_addr)
+struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
+							  struct snd_seq_addr *dest_addr)
 {
 	struct list_head *p;
-	subscribers_t *s, *found = NULL;
+	struct snd_seq_subscribers *s, *found = NULL;
 
 	down_read(&src_grp->list_mutex);
 	list_for_each(p, &src_grp->list_head) {
-		s = list_entry(p, subscribers_t, src_list);
+		s = list_entry(p, struct snd_seq_subscribers, src_list);
 		if (addr_match(dest_addr, &s->info.dest)) {
 			found = s;
 			break;
@@ -623,11 +647,11 @@
  */
 /* exported */
 int snd_seq_event_port_attach(int client,
-			      snd_seq_port_callback_t *pcbp,
+			      struct snd_seq_port_callback *pcbp,
 			      int cap, int type, int midi_channels,
 			      int midi_voices, char *portname)
 {
-	snd_seq_port_info_t portinfo;
+	struct snd_seq_port_info portinfo;
 	int  ret;
 
 	/* Set up the port */
@@ -660,7 +684,7 @@
 /* exported */
 int snd_seq_event_port_detach(int client, int port)
 {
-	snd_seq_port_info_t portinfo;
+	struct snd_seq_port_info portinfo;
 	int  err;
 
 	memset(&portinfo, 0, sizeof(portinfo));
diff --git a/sound/core/seq/seq_ports.h b/sound/core/seq/seq_ports.h
index 89fd4416..9d71171 100644
--- a/sound/core/seq/seq_ports.h
+++ b/sound/core/seq/seq_ports.h
@@ -40,37 +40,38 @@
  
 */
 
-typedef struct subscribers_t {
-	snd_seq_port_subscribe_t info;	/* additional info */
+struct snd_seq_subscribers {
+	struct snd_seq_port_subscribe info;	/* additional info */
 	struct list_head src_list;	/* link of sources */
 	struct list_head dest_list;	/* link of destinations */
 	atomic_t ref_count;
-} subscribers_t;
+};
 
-typedef struct port_subs_info_t {
+struct snd_seq_port_subs_info {
 	struct list_head list_head;	/* list of subscribed ports */
 	unsigned int count;		/* count of subscribers */
 	unsigned int exclusive: 1;	/* exclusive mode */
 	struct rw_semaphore list_mutex;
 	rwlock_t list_lock;
-	snd_seq_kernel_port_open_t *open;
-	snd_seq_kernel_port_close_t *close;
-} port_subs_info_t;
+	int (*open)(void *private_data, struct snd_seq_port_subscribe *info);
+	int (*close)(void *private_data, struct snd_seq_port_subscribe *info);
+};
 
-typedef struct client_port_t {
+struct snd_seq_client_port {
 
-	snd_seq_addr_t addr;		/* client/port number */
+	struct snd_seq_addr addr;	/* client/port number */
 	struct module *owner;		/* owner of this port */
 	char name[64];			/* port name */	
 	struct list_head list;		/* port list */
 	snd_use_lock_t use_lock;
 
 	/* subscribers */
-	port_subs_info_t c_src;		/* read (sender) list */
-	port_subs_info_t c_dest;	/* write (dest) list */
+	struct snd_seq_port_subs_info c_src;	/* read (sender) list */
+	struct snd_seq_port_subs_info c_dest;	/* write (dest) list */
 
-	snd_seq_kernel_port_input_t *event_input;
-	snd_seq_kernel_port_private_free_t *private_free;
+	int (*event_input)(struct snd_seq_event *ev, int direct, void *private_data,
+			   int atomic, int hop);
+	void (*private_free)(void *private_data);
 	void *private_data;
 	unsigned int callback_all : 1;
 	unsigned int closing : 1;
@@ -87,42 +88,55 @@
 	int midi_voices;
 	int synth_voices;
 		
-} client_port_t;
+};
+
+struct snd_seq_client;
 
 /* return pointer to port structure and lock port */
-client_port_t *snd_seq_port_use_ptr(client_t *client, int num);
+struct snd_seq_client_port *snd_seq_port_use_ptr(struct snd_seq_client *client, int num);
 
 /* search for next port - port is locked if found */
-client_port_t *snd_seq_port_query_nearest(client_t *client, snd_seq_port_info_t *pinfo);
+struct snd_seq_client_port *snd_seq_port_query_nearest(struct snd_seq_client *client,
+						       struct snd_seq_port_info *pinfo);
 
 /* unlock the port */
 #define snd_seq_port_unlock(port) snd_use_lock_free(&(port)->use_lock)
 
 /* create a port, port number is returned (-1 on failure) */
-client_port_t *snd_seq_create_port(client_t *client, int port_index);
+struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client, int port_index);
 
 /* delete a port */
-int snd_seq_delete_port(client_t *client, int port);
+int snd_seq_delete_port(struct snd_seq_client *client, int port);
 
 /* delete all ports */
-int snd_seq_delete_all_ports(client_t *client);
+int snd_seq_delete_all_ports(struct snd_seq_client *client);
 
 /* set port info fields */
-int snd_seq_set_port_info(client_port_t *port, snd_seq_port_info_t *info);
+int snd_seq_set_port_info(struct snd_seq_client_port *port,
+			  struct snd_seq_port_info *info);
 
 /* get port info fields */
-int snd_seq_get_port_info(client_port_t *port, snd_seq_port_info_t *info);
+int snd_seq_get_port_info(struct snd_seq_client_port *port,
+			  struct snd_seq_port_info *info);
 
 /* add subscriber to subscription list */
-int snd_seq_port_connect(client_t *caller, client_t *s, client_port_t *sp, client_t *d, client_port_t *dp, snd_seq_port_subscribe_t *info);
+int snd_seq_port_connect(struct snd_seq_client *caller,
+			 struct snd_seq_client *s, struct snd_seq_client_port *sp,
+			 struct snd_seq_client *d, struct snd_seq_client_port *dp,
+			 struct snd_seq_port_subscribe *info);
 
 /* remove subscriber from subscription list */ 
-int snd_seq_port_disconnect(client_t *caller, client_t *s, client_port_t *sp, client_t *d, client_port_t *dp, snd_seq_port_subscribe_t *info);
+int snd_seq_port_disconnect(struct snd_seq_client *caller,
+			    struct snd_seq_client *s, struct snd_seq_client_port *sp,
+			    struct snd_seq_client *d, struct snd_seq_client_port *dp,
+			    struct snd_seq_port_subscribe *info);
 
 /* subscribe port */
-int snd_seq_port_subscribe(client_port_t *port, snd_seq_port_subscribe_t *info);
+int snd_seq_port_subscribe(struct snd_seq_client_port *port,
+			   struct snd_seq_port_subscribe *info);
 
 /* get matched subscriber */
-subscribers_t *snd_seq_port_get_subscription(port_subs_info_t *src_grp, snd_seq_addr_t *dest_addr);
+struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
+							  struct snd_seq_addr *dest_addr);
 
 #endif
diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c
index cd641bc..0744186 100644
--- a/sound/core/seq/seq_prioq.c
+++ b/sound/core/seq/seq_prioq.c
@@ -55,9 +55,9 @@
 
 
 /* create new prioq (constructor) */
-prioq_t *snd_seq_prioq_new(void)
+struct snd_seq_prioq *snd_seq_prioq_new(void)
 {
-	prioq_t *f;
+	struct snd_seq_prioq *f;
 
 	f = kzalloc(sizeof(*f), GFP_KERNEL);
 	if (f == NULL) {
@@ -74,9 +74,9 @@
 }
 
 /* delete prioq (destructor) */
-void snd_seq_prioq_delete(prioq_t **fifo)
+void snd_seq_prioq_delete(struct snd_seq_prioq **fifo)
 {
-	prioq_t *f = *fifo;
+	struct snd_seq_prioq *f = *fifo;
 	*fifo = NULL;
 
 	if (f == NULL) {
@@ -101,7 +101,8 @@
 
 /* compare timestamp between events */
 /* return 1 if a >= b; 0 */
-static inline int compare_timestamp(snd_seq_event_t * a, snd_seq_event_t * b)
+static inline int compare_timestamp(struct snd_seq_event *a,
+				    struct snd_seq_event *b)
 {
 	if ((a->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK) {
 		/* compare ticks */
@@ -117,7 +118,8 @@
  *        zero     if a = b;
  *        positive if a > b;
  */
-static inline int compare_timestamp_rel(snd_seq_event_t *a, snd_seq_event_t *b)
+static inline int compare_timestamp_rel(struct snd_seq_event *a,
+					struct snd_seq_event *b)
 {
 	if ((a->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK) {
 		/* compare ticks */
@@ -144,9 +146,10 @@
 }
 
 /* enqueue cell to prioq */
-int snd_seq_prioq_cell_in(prioq_t * f, snd_seq_event_cell_t * cell)
+int snd_seq_prioq_cell_in(struct snd_seq_prioq * f,
+			  struct snd_seq_event_cell * cell)
 {
-	snd_seq_event_cell_t *cur, *prev;
+	struct snd_seq_event_cell *cur, *prev;
 	unsigned long flags;
 	int count;
 	int prior;
@@ -215,9 +218,9 @@
 }
 
 /* dequeue cell from prioq */
-snd_seq_event_cell_t *snd_seq_prioq_cell_out(prioq_t * f)
+struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f)
 {
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 	unsigned long flags;
 
 	if (f == NULL) {
@@ -243,7 +246,7 @@
 }
 
 /* return number of events available in prioq */
-int snd_seq_prioq_avail(prioq_t * f)
+int snd_seq_prioq_avail(struct snd_seq_prioq * f)
 {
 	if (f == NULL) {
 		snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
@@ -254,7 +257,7 @@
 
 
 /* peek at cell at the head of the prioq */
-snd_seq_event_cell_t *snd_seq_prioq_cell_peek(prioq_t * f)
+struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f)
 {
 	if (f == NULL) {
 		snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
@@ -264,7 +267,8 @@
 }
 
 
-static inline int prioq_match(snd_seq_event_cell_t *cell, int client, int timestamp)
+static inline int prioq_match(struct snd_seq_event_cell *cell,
+			      int client, int timestamp)
 {
 	if (cell->event.source.client == client ||
 	    cell->event.dest.client == client)
@@ -286,12 +290,12 @@
 }
 
 /* remove cells for left client */
-void snd_seq_prioq_leave(prioq_t * f, int client, int timestamp)
+void snd_seq_prioq_leave(struct snd_seq_prioq * f, int client, int timestamp)
 {
-	register snd_seq_event_cell_t *cell, *next;
+	register struct snd_seq_event_cell *cell, *next;
 	unsigned long flags;
-	snd_seq_event_cell_t *prev = NULL;
-	snd_seq_event_cell_t *freefirst = NULL, *freeprev = NULL, *freenext;
+	struct snd_seq_event_cell *prev = NULL;
+	struct snd_seq_event_cell *freefirst = NULL, *freeprev = NULL, *freenext;
 
 	/* collect all removed cells */
 	spin_lock_irqsave(&f->lock, flags);
@@ -338,8 +342,8 @@
 	}
 }
 
-static int prioq_remove_match(snd_seq_remove_events_t *info,
-	snd_seq_event_t *ev)
+static int prioq_remove_match(struct snd_seq_remove_events *info,
+			      struct snd_seq_event *ev)
 {
 	int res;
 
@@ -394,13 +398,13 @@
 }
 
 /* remove cells matching remove criteria */
-void snd_seq_prioq_remove_events(prioq_t * f, int client,
-	snd_seq_remove_events_t *info)
+void snd_seq_prioq_remove_events(struct snd_seq_prioq * f, int client,
+				 struct snd_seq_remove_events *info)
 {
-	register snd_seq_event_cell_t *cell, *next;
+	struct snd_seq_event_cell *cell, *next;
 	unsigned long flags;
-	snd_seq_event_cell_t *prev = NULL;
-	snd_seq_event_cell_t *freefirst = NULL, *freeprev = NULL, *freenext;
+	struct snd_seq_event_cell *prev = NULL;
+	struct snd_seq_event_cell *freefirst = NULL, *freeprev = NULL, *freenext;
 
 	/* collect all removed cells */
 	spin_lock_irqsave(&f->lock, flags);
diff --git a/sound/core/seq/seq_prioq.h b/sound/core/seq/seq_prioq.h
index f12af79..d38bb78 100644
--- a/sound/core/seq/seq_prioq.h
+++ b/sound/core/seq/seq_prioq.h
@@ -26,37 +26,37 @@
 
 /* === PRIOQ === */
 
-typedef struct {
-	snd_seq_event_cell_t* head;      /* pointer to head of prioq */
-	snd_seq_event_cell_t* tail;      /* pointer to tail of prioq */
+struct snd_seq_prioq {
+	struct snd_seq_event_cell *head;      /* pointer to head of prioq */
+	struct snd_seq_event_cell *tail;      /* pointer to tail of prioq */
 	int cells;
 	spinlock_t lock;
-} prioq_t;
+};
 
 
 /* create new prioq (constructor) */
-extern prioq_t *snd_seq_prioq_new(void);
+struct snd_seq_prioq *snd_seq_prioq_new(void);
 
 /* delete prioq (destructor) */
-extern void snd_seq_prioq_delete(prioq_t **fifo);
+void snd_seq_prioq_delete(struct snd_seq_prioq **fifo);
 
 /* enqueue cell to prioq */
-extern int snd_seq_prioq_cell_in(prioq_t *f, snd_seq_event_cell_t *cell);
+int snd_seq_prioq_cell_in(struct snd_seq_prioq *f, struct snd_seq_event_cell *cell);
 
 /* dequeue cell from prioq */ 
-extern snd_seq_event_cell_t *snd_seq_prioq_cell_out(prioq_t *f);
+struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f);
 
 /* return number of events available in prioq */
-extern int snd_seq_prioq_avail(prioq_t *f);
+int snd_seq_prioq_avail(struct snd_seq_prioq *f);
 
 /* peek at cell at the head of the prioq */
-extern snd_seq_event_cell_t *snd_seq_prioq_cell_peek(prioq_t *f);
+struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq *f);
 
 /* client left queue */
-extern void snd_seq_prioq_leave(prioq_t *f, int client, int timestamp);        
+void snd_seq_prioq_leave(struct snd_seq_prioq *f, int client, int timestamp);        
 
 /* Remove events */
-void snd_seq_prioq_remove_events(prioq_t * f, int client,
-	snd_seq_remove_events_t *info);
+void snd_seq_prioq_remove_events(struct snd_seq_prioq *f, int client,
+				 struct snd_seq_remove_events *info);
 
 #endif
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 5f5c3cb..9cf20f0 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -29,7 +29,7 @@
  *  Aug. 30, 2000	Takashi Iwai
  *     - Queues are managed in static array again, but with better way.
  *       The API itself is identical.
- *     - The queue is locked when queue_t pinter is returned via
+ *     - The queue is locked when struct snd_seq_queue pointer is returned via
  *       queueptr().  This pointer *MUST* be released afterward by
  *       queuefree(ptr).
  *     - Addition of experimental sync support.
@@ -48,7 +48,7 @@
 #include "seq_info.h"
 
 /* list of allocated queues */
-static queue_t *queue_list[SNDRV_SEQ_MAX_QUEUES];
+static struct snd_seq_queue *queue_list[SNDRV_SEQ_MAX_QUEUES];
 static DEFINE_SPINLOCK(queue_list_lock);
 /* number of queues allocated */
 static int num_queues;
@@ -61,7 +61,7 @@
 /*----------------------------------------------------------------*/
 
 /* assign queue id and insert to list */
-static int queue_list_add(queue_t *q)
+static int queue_list_add(struct snd_seq_queue *q)
 {
 	int i;
 	unsigned long flags;
@@ -80,9 +80,9 @@
 	return -1;
 }
 
-static queue_t *queue_list_remove(int id, int client)
+static struct snd_seq_queue *queue_list_remove(int id, int client)
 {
-	queue_t *q;
+	struct snd_seq_queue *q;
 	unsigned long flags;
 
 	spin_lock_irqsave(&queue_list_lock, flags);
@@ -107,9 +107,9 @@
 /*----------------------------------------------------------------*/
 
 /* create new queue (constructor) */
-static queue_t *queue_new(int owner, int locked)
+static struct snd_seq_queue *queue_new(int owner, int locked)
 {
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	q = kzalloc(sizeof(*q), GFP_KERNEL);
 	if (q == NULL) {
@@ -142,7 +142,7 @@
 }
 
 /* delete queue (destructor) */
-static void queue_delete(queue_t *q)
+static void queue_delete(struct snd_seq_queue *q)
 {
 	/* stop and release the timer */
 	snd_seq_timer_stop(q->timer);
@@ -187,7 +187,7 @@
  */
 int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
 {
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	q = queue_new(client, locked);
 	if (q == NULL)
@@ -204,7 +204,7 @@
 /* delete a queue - queue must be owned by the client */
 int snd_seq_queue_delete(int client, int queueid)
 {
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	if (queueid < 0 || queueid >= SNDRV_SEQ_MAX_QUEUES)
 		return -EINVAL;
@@ -218,9 +218,9 @@
 
 
 /* return pointer to queue structure for specified id */
-queue_t *queueptr(int queueid)
+struct snd_seq_queue *queueptr(int queueid)
 {
-	queue_t *q;
+	struct snd_seq_queue *q;
 	unsigned long flags;
 
 	if (queueid < 0 || queueid >= SNDRV_SEQ_MAX_QUEUES)
@@ -234,10 +234,10 @@
 }
 
 /* return the (first) queue matching with the specified name */
-queue_t *snd_seq_queue_find_name(char *name)
+struct snd_seq_queue *snd_seq_queue_find_name(char *name)
 {
 	int i;
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
 		if ((q = queueptr(i)) != NULL) {
@@ -252,10 +252,10 @@
 
 /* -------------------------------------------------------- */
 
-void snd_seq_check_queue(queue_t *q, int atomic, int hop)
+void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop)
 {
 	unsigned long flags;
-	snd_seq_event_cell_t *cell;
+	struct snd_seq_event_cell *cell;
 
 	if (q == NULL)
 		return;
@@ -273,7 +273,8 @@
       __again:
 	/* Process tick queue... */
 	while ((cell = snd_seq_prioq_cell_peek(q->tickq)) != NULL) {
-		if (snd_seq_compare_tick_time(&q->timer->tick.cur_tick, &cell->event.time.tick)) {
+		if (snd_seq_compare_tick_time(&q->timer->tick.cur_tick,
+					      &cell->event.time.tick)) {
 			cell = snd_seq_prioq_cell_out(q->tickq);
 			if (cell)
 				snd_seq_dispatch_event(cell, atomic, hop);
@@ -286,7 +287,8 @@
 
 	/* Process time queue... */
 	while ((cell = snd_seq_prioq_cell_peek(q->timeq)) != NULL) {
-		if (snd_seq_compare_real_time(&q->timer->cur_time, &cell->event.time.time)) {
+		if (snd_seq_compare_real_time(&q->timer->cur_time,
+					      &cell->event.time.time)) {
 			cell = snd_seq_prioq_cell_out(q->timeq);
 			if (cell)
 				snd_seq_dispatch_event(cell, atomic, hop);
@@ -309,10 +311,10 @@
 
 
 /* enqueue a event to singe queue */
-int snd_seq_enqueue_event(snd_seq_event_cell_t *cell, int atomic, int hop)
+int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop)
 {
 	int dest, err;
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	snd_assert(cell != NULL, return -EINVAL);
 	dest = cell->event.queue;	/* destination queue */
@@ -327,7 +329,8 @@
 			break;
 
 		case SNDRV_SEQ_TIME_STAMP_REAL:
-			snd_seq_inc_real_time(&cell->event.time.time, &q->timer->cur_time);
+			snd_seq_inc_real_time(&cell->event.time.time,
+					      &q->timer->cur_time);
 			break;
 		}
 		cell->event.flags &= ~SNDRV_SEQ_TIME_MODE_MASK;
@@ -361,7 +364,7 @@
 
 /*----------------------------------------------------------------*/
 
-static inline int check_access(queue_t *q, int client)
+static inline int check_access(struct snd_seq_queue *q, int client)
 {
 	return (q->owner == client) || (!q->locked && !q->klocked);
 }
@@ -369,7 +372,7 @@
 /* check if the client has permission to modify queue parameters.
  * if it does, lock the queue
  */
-static int queue_access_lock(queue_t *q, int client)
+static int queue_access_lock(struct snd_seq_queue *q, int client)
 {
 	unsigned long flags;
 	int access_ok;
@@ -383,7 +386,7 @@
 }
 
 /* unlock the queue */
-static inline void queue_access_unlock(queue_t *q)
+static inline void queue_access_unlock(struct snd_seq_queue *q)
 {
 	unsigned long flags;
 
@@ -395,7 +398,7 @@
 /* exported - only checking permission */
 int snd_seq_queue_check_access(int queueid, int client)
 {
-	queue_t *q = queueptr(queueid);
+	struct snd_seq_queue *q = queueptr(queueid);
 	int access_ok;
 	unsigned long flags;
 
@@ -415,7 +418,7 @@
  */
 int snd_seq_queue_set_owner(int queueid, int client, int locked)
 {
-	queue_t *q = queueptr(queueid);
+	struct snd_seq_queue *q = queueptr(queueid);
 
 	if (q == NULL)
 		return -EINVAL;
@@ -443,8 +446,8 @@
 int snd_seq_queue_timer_open(int queueid)
 {
 	int result = 0;
-	queue_t *queue;
-	seq_timer_t *tmr;
+	struct snd_seq_queue *queue;
+	struct snd_seq_timer *tmr;
 
 	queue = queueptr(queueid);
 	if (queue == NULL)
@@ -463,8 +466,8 @@
  */
 int snd_seq_queue_timer_close(int queueid)
 {
-	queue_t *queue;
-	seq_timer_t *tmr;
+	struct snd_seq_queue *queue;
+	struct snd_seq_timer *tmr;
 	int result = 0;
 
 	queue = queueptr(queueid);
@@ -477,9 +480,10 @@
 }
 
 /* change queue tempo and ppq */
-int snd_seq_queue_timer_set_tempo(int queueid, int client, snd_seq_queue_tempo_t *info)
+int snd_seq_queue_timer_set_tempo(int queueid, int client,
+				  struct snd_seq_queue_tempo *info)
 {
-	queue_t *q = queueptr(queueid);
+	struct snd_seq_queue *q = queueptr(queueid);
 	int result;
 
 	if (q == NULL)
@@ -493,7 +497,8 @@
 	if (result >= 0)
 		result = snd_seq_timer_set_ppq(q->timer, info->ppq);
 	if (result >= 0 && info->skew_base > 0)
-		result = snd_seq_timer_set_skew(q->timer, info->skew_value, info->skew_base);
+		result = snd_seq_timer_set_skew(q->timer, info->skew_value,
+						info->skew_base);
 	queue_access_unlock(q);
 	queuefree(q);
 	return result;
@@ -506,7 +511,7 @@
  */
 int snd_seq_queue_use(int queueid, int client, int use)
 {
-	queue_t *queue;
+	struct snd_seq_queue *queue;
 
 	queue = queueptr(queueid);
 	if (queue == NULL)
@@ -538,7 +543,7 @@
  */
 int snd_seq_queue_is_used(int queueid, int client)
 {
-	queue_t *q;
+	struct snd_seq_queue *q;
 	int result;
 
 	q = queueptr(queueid);
@@ -559,7 +564,7 @@
 {
 	unsigned long flags;
 	int i;
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
 		if ((q = queueptr(i)) == NULL)
@@ -584,7 +589,7 @@
 void snd_seq_queue_client_leave(int client)
 {
 	int i;
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	/* delete own queues from queue list */
 	for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
@@ -615,7 +620,7 @@
 void snd_seq_queue_client_leave_cells(int client)
 {
 	int i;
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
 		if ((q = queueptr(i)) == NULL)
@@ -627,10 +632,10 @@
 }
 
 /* remove cells based on flush criteria */
-void snd_seq_queue_remove_cells(int client, snd_seq_remove_events_t *info)
+void snd_seq_queue_remove_cells(int client, struct snd_seq_remove_events *info)
 {
 	int i;
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
 		if ((q = queueptr(i)) == NULL)
@@ -650,9 +655,10 @@
 /*
  * send events to all subscribed ports
  */
-static void queue_broadcast_event(queue_t *q, snd_seq_event_t *ev, int atomic, int hop)
+static void queue_broadcast_event(struct snd_seq_queue *q, struct snd_seq_event *ev,
+				  int atomic, int hop)
 {
-	snd_seq_event_t sev;
+	struct snd_seq_event sev;
 
 	sev = *ev;
 	
@@ -672,7 +678,8 @@
  * process a received queue-control event.
  * this function is exported for seq_sync.c.
  */
-static void snd_seq_queue_process_event(queue_t *q, snd_seq_event_t *ev,
+static void snd_seq_queue_process_event(struct snd_seq_queue *q,
+					struct snd_seq_event *ev,
 					int atomic, int hop)
 {
 	switch (ev->type) {
@@ -724,9 +731,9 @@
  * Queue control via timer control port:
  * this function is exported as a callback of timer port.
  */
-int snd_seq_control_queue(snd_seq_event_t *ev, int atomic, int hop)
+int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop)
 {
-	queue_t *q;
+	struct snd_seq_queue *q;
 
 	snd_assert(ev != NULL, return -EINVAL);
 	q = queueptr(ev->data.queue.queue);
@@ -749,13 +756,14 @@
 
 /*----------------------------------------------------------------*/
 
+#ifdef CONFIG_PROC_FS
 /* exported to seq_info.c */
-void snd_seq_info_queues_read(snd_info_entry_t *entry, 
-			      snd_info_buffer_t * buffer)
+void snd_seq_info_queues_read(struct snd_info_entry *entry, 
+			      struct snd_info_buffer *buffer)
 {
 	int i, bpm;
-	queue_t *q;
-	seq_timer_t *tmr;
+	struct snd_seq_queue *q;
+	struct snd_seq_timer *tmr;
 
 	for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
 		if ((q = queueptr(i)) == NULL)
@@ -782,3 +790,5 @@
 		queuefree(q);
 	}
 }
+#endif /* CONFIG_PROC_FS */
+
diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h
index ea3c542..8884385 100644
--- a/sound/core/seq/seq_queue.h
+++ b/sound/core/seq/seq_queue.h
@@ -30,15 +30,15 @@
 
 #define SEQ_QUEUE_NO_OWNER (-1)
 
-struct _snd_seq_queue {
+struct snd_seq_queue {
 	int queue;		/* queue number */
 
 	char name[64];		/* name of this queue */
 
-	prioq_t	*tickq;		/* midi tick event queue */
-	prioq_t	*timeq;		/* real-time event queue */	
+	struct snd_seq_prioq	*tickq;		/* midi tick event queue */
+	struct snd_seq_prioq	*timeq;		/* real-time event queue */	
 	
-	seq_timer_t *timer;	/* time keeper for this queue */
+	struct snd_seq_timer *timer;	/* time keeper for this queue */
 	int	owner;		/* client that 'owns' the timer */
 	unsigned int	locked:1,	/* timer is only accesibble by owner if set */
 		klocked:1,	/* kernel lock (after START) */	
@@ -83,26 +83,26 @@
 void snd_seq_queue_client_leave(int client);
 
 /* enqueue a event received from one the clients */
-int snd_seq_enqueue_event(snd_seq_event_cell_t *cell, int atomic, int hop);
+int snd_seq_enqueue_event(struct snd_seq_event_cell *cell, int atomic, int hop);
 
 /* Remove events */
 void snd_seq_queue_client_leave_cells(int client);
-void snd_seq_queue_remove_cells(int client, snd_seq_remove_events_t *info);
+void snd_seq_queue_remove_cells(int client, struct snd_seq_remove_events *info);
 
 /* return pointer to queue structure for specified id */
-queue_t *queueptr(int queueid);
+struct snd_seq_queue *queueptr(int queueid);
 /* unlock */
 #define queuefree(q) snd_use_lock_free(&(q)->use_lock)
 
 /* return the (first) queue matching with the specified name */
-queue_t *snd_seq_queue_find_name(char *name);
+struct snd_seq_queue *snd_seq_queue_find_name(char *name);
 
 /* check single queue and dispatch events */
-void snd_seq_check_queue(queue_t *q, int atomic, int hop);
+void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop);
 
 /* access to queue's parameters */
 int snd_seq_queue_check_access(int queueid, int client);
-int snd_seq_queue_timer_set_tempo(int queueid, int client, snd_seq_queue_tempo_t *info);
+int snd_seq_queue_timer_set_tempo(int queueid, int client, struct snd_seq_queue_tempo *info);
 int snd_seq_queue_set_owner(int queueid, int client, int locked);
 int snd_seq_queue_set_locked(int queueid, int client, int locked);
 int snd_seq_queue_timer_open(int queueid);
@@ -110,7 +110,7 @@
 int snd_seq_queue_use(int queueid, int client, int use);
 int snd_seq_queue_is_used(int queueid, int client);
 
-int snd_seq_control_queue(snd_seq_event_t *ev, int atomic, int hop);
+int snd_seq_control_queue(struct snd_seq_event *ev, int atomic, int hop);
 
 /*
  * 64bit division - for sync stuff..
diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c
index 0d9eff8..b201b76 100644
--- a/sound/core/seq/seq_system.c
+++ b/sound/core/seq/seq_system.c
@@ -66,12 +66,12 @@
 
 
 /* fill standard header data, source port & channel are filled in */
-static int setheader(snd_seq_event_t * ev, int client, int port)
+static int setheader(struct snd_seq_event * ev, int client, int port)
 {
 	if (announce_port < 0)
 		return -ENODEV;
 
-	memset(ev, 0, sizeof(snd_seq_event_t));
+	memset(ev, 0, sizeof(struct snd_seq_event));
 
 	ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
 	ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
@@ -92,7 +92,7 @@
 /* entry points for broadcasting system events */
 void snd_seq_system_broadcast(int client, int port, int type)
 {
-	snd_seq_event_t ev;
+	struct snd_seq_event ev;
 	
 	if (setheader(&ev, client, port) < 0)
 		return;
@@ -101,7 +101,7 @@
 }
 
 /* entry points for broadcasting system events */
-int snd_seq_system_notify(int client, int port, snd_seq_event_t *ev)
+int snd_seq_system_notify(int client, int port, struct snd_seq_event *ev)
 {
 	ev->flags = SNDRV_SEQ_EVENT_LENGTH_FIXED;
 	ev->source.client = sysclient;
@@ -112,7 +112,7 @@
 }
 
 /* call-back handler for timer events */
-static int event_input_timer(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop)
+static int event_input_timer(struct snd_seq_event * ev, int direct, void *private_data, int atomic, int hop)
 {
 	return snd_seq_control_queue(ev, atomic, hop);
 }
@@ -120,34 +120,19 @@
 /* register our internal client */
 int __init snd_seq_system_client_init(void)
 {
+	struct snd_seq_port_callback pcallbacks;
+	struct snd_seq_port_info *port;
 
-	snd_seq_client_callback_t callbacks;
-	snd_seq_port_callback_t pcallbacks;
-	snd_seq_client_info_t *inf;
-	snd_seq_port_info_t *port;
-
-	inf = kzalloc(sizeof(*inf), GFP_KERNEL);
 	port = kzalloc(sizeof(*port), GFP_KERNEL);
-	if (! inf || ! port) {
-		kfree(inf);
-		kfree(port);
+	if (!port)
 		return -ENOMEM;
-	}
 
-	memset(&callbacks, 0, sizeof(callbacks));
 	memset(&pcallbacks, 0, sizeof(pcallbacks));
 	pcallbacks.owner = THIS_MODULE;
 	pcallbacks.event_input = event_input_timer;
 
 	/* register client */
-	callbacks.allow_input = callbacks.allow_output = 1;
-	sysclient = snd_seq_create_kernel_client(NULL, 0, &callbacks);
-
-	/* set our name */
-	inf->client = 0;
-	inf->type = KERNEL_CLIENT;
-	strcpy(inf->name, "System");
-	snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, inf);
+	sysclient = snd_seq_create_kernel_client(NULL, 0, "System");
 
 	/* register timer */
 	strcpy(port->name, "Timer");
@@ -171,7 +156,6 @@
 	snd_seq_kernel_client_ctl(sysclient, SNDRV_SEQ_IOCTL_CREATE_PORT, port);
 	announce_port = port->addr.port;
 
-	kfree(inf);
 	kfree(port);
 	return 0;
 }
diff --git a/sound/core/seq/seq_system.h b/sound/core/seq/seq_system.h
index 9000072..cf2cfa2 100644
--- a/sound/core/seq/seq_system.h
+++ b/sound/core/seq/seq_system.h
@@ -34,7 +34,7 @@
 #define snd_seq_system_client_ev_port_exit(client, port) snd_seq_system_broadcast(client, port, SNDRV_SEQ_EVENT_PORT_EXIT)
 #define snd_seq_system_client_ev_port_change(client, port) snd_seq_system_broadcast(client, port, SNDRV_SEQ_EVENT_PORT_CHANGE)
 
-int snd_seq_system_notify(int client, int port, snd_seq_event_t *ev);
+int snd_seq_system_notify(int client, int port, struct snd_seq_event *ev);
 
 /* register our internal client */
 int snd_seq_system_client_init(void);
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index 65b64a7..b4b9a13 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -41,7 +41,7 @@
 
 #define SKEW_BASE	0x10000	/* 16bit shift */
 
-static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick,
+static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer_tick *tick,
 					      int tempo, int ppq)
 {
 	if (tempo < 1000000)
@@ -60,9 +60,9 @@
 }
 
 /* create new timer (constructor) */
-seq_timer_t *snd_seq_timer_new(void)
+struct snd_seq_timer *snd_seq_timer_new(void)
 {
-	seq_timer_t *tmr;
+	struct snd_seq_timer *tmr;
 	
 	tmr = kzalloc(sizeof(*tmr), GFP_KERNEL);
 	if (tmr == NULL) {
@@ -81,9 +81,9 @@
 }
 
 /* delete timer (destructor) */
-void snd_seq_timer_delete(seq_timer_t **tmr)
+void snd_seq_timer_delete(struct snd_seq_timer **tmr)
 {
-	seq_timer_t *t = *tmr;
+	struct snd_seq_timer *t = *tmr;
 	*tmr = NULL;
 
 	if (t == NULL) {
@@ -99,7 +99,7 @@
 	kfree(t);
 }
 
-void snd_seq_timer_defaults(seq_timer_t * tmr)
+void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
 {
 	/* setup defaults */
 	tmr->ppq = 96;		/* 96 PPQ */
@@ -118,7 +118,7 @@
 	tmr->skew = tmr->skew_base = SKEW_BASE;
 }
 
-void snd_seq_timer_reset(seq_timer_t * tmr)
+void snd_seq_timer_reset(struct snd_seq_timer * tmr)
 {
 	unsigned long flags;
 
@@ -136,13 +136,13 @@
 
 
 /* called by timer interrupt routine. the period time since previous invocation is passed */
-static void snd_seq_timer_interrupt(snd_timer_instance_t *timeri,
+static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri,
 				    unsigned long resolution,
 				    unsigned long ticks)
 {
 	unsigned long flags;
-	queue_t *q = (queue_t *)timeri->callback_data;
-	seq_timer_t *tmr;
+	struct snd_seq_queue *q = timeri->callback_data;
+	struct snd_seq_timer *tmr;
 
 	if (q == NULL)
 		return;
@@ -177,7 +177,7 @@
 }
 
 /* set current tempo */
-int snd_seq_timer_set_tempo(seq_timer_t * tmr, int tempo)
+int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo)
 {
 	unsigned long flags;
 
@@ -194,7 +194,7 @@
 }
 
 /* set current ppq */
-int snd_seq_timer_set_ppq(seq_timer_t * tmr, int ppq)
+int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq)
 {
 	unsigned long flags;
 
@@ -217,7 +217,8 @@
 }
 
 /* set current tick position */
-int snd_seq_timer_set_position_tick(seq_timer_t *tmr, snd_seq_tick_time_t position)
+int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr,
+				    snd_seq_tick_time_t position)
 {
 	unsigned long flags;
 
@@ -231,7 +232,8 @@
 }
 
 /* set current real-time position */
-int snd_seq_timer_set_position_time(seq_timer_t *tmr, snd_seq_real_time_t position)
+int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr,
+				    snd_seq_real_time_t position)
 {
 	unsigned long flags;
 
@@ -245,7 +247,8 @@
 }
 
 /* set timer skew */
-int snd_seq_timer_set_skew(seq_timer_t *tmr, unsigned int skew, unsigned int base)
+int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew,
+			   unsigned int base)
 {
 	unsigned long flags;
 
@@ -262,10 +265,10 @@
 	return 0;
 }
 
-int snd_seq_timer_open(queue_t *q)
+int snd_seq_timer_open(struct snd_seq_queue *q)
 {
-	snd_timer_instance_t *t;
-	seq_timer_t *tmr;
+	struct snd_timer_instance *t;
+	struct snd_seq_timer *tmr;
 	char str[32];
 	int err;
 
@@ -282,7 +285,7 @@
 	if (err < 0 && tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) {
 		if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_GLOBAL ||
 		    tmr->alsa_id.device != SNDRV_TIMER_GLOBAL_SYSTEM) {
-			snd_timer_id_t tid;
+			struct snd_timer_id tid;
 			memset(&tid, 0, sizeof(tid));
 			tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
 			tid.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
@@ -302,9 +305,9 @@
 	return 0;
 }
 
-int snd_seq_timer_close(queue_t *q)
+int snd_seq_timer_close(struct snd_seq_queue *q)
 {
-	seq_timer_t *tmr;
+	struct snd_seq_timer *tmr;
 	
 	tmr = q->timer;
 	snd_assert(tmr != NULL, return -EINVAL);
@@ -316,7 +319,7 @@
 	return 0;
 }
 
-int snd_seq_timer_stop(seq_timer_t * tmr)
+int snd_seq_timer_stop(struct snd_seq_timer * tmr)
 {
 	if (! tmr->timeri)
 		return -EINVAL;
@@ -327,9 +330,9 @@
 	return 0;
 }
 
-static int initialize_timer(seq_timer_t *tmr)
+static int initialize_timer(struct snd_seq_timer *tmr)
 {
-	snd_timer_t *t;
+	struct snd_timer *t;
 	unsigned long freq;
 
 	t = tmr->timeri->timer;
@@ -358,7 +361,7 @@
 	return 0;
 }
 
-int snd_seq_timer_start(seq_timer_t * tmr)
+int snd_seq_timer_start(struct snd_seq_timer * tmr)
 {
 	if (! tmr->timeri)
 		return -EINVAL;
@@ -373,7 +376,7 @@
 	return 0;
 }
 
-int snd_seq_timer_continue(seq_timer_t * tmr)
+int snd_seq_timer_continue(struct snd_seq_timer * tmr)
 {
 	if (! tmr->timeri)
 		return -EINVAL;
@@ -391,7 +394,7 @@
 }
 
 /* return current 'real' time. use timeofday() to get better granularity. */
-snd_seq_real_time_t snd_seq_timer_get_cur_time(seq_timer_t *tmr)
+snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
 {
 	snd_seq_real_time_t cur_time;
 
@@ -416,19 +419,21 @@
 
 /* TODO: use interpolation on tick queue (will only be useful for very
  high PPQ values) */
-snd_seq_tick_time_t snd_seq_timer_get_cur_tick(seq_timer_t *tmr)
+snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr)
 {
 	return tmr->tick.cur_tick;
 }
 
 
+#ifdef CONFIG_PROC_FS
 /* exported to seq_info.c */
-void snd_seq_info_timer_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+void snd_seq_info_timer_read(struct snd_info_entry *entry,
+			     struct snd_info_buffer *buffer)
 {
 	int idx;
-	queue_t *q;
-	seq_timer_t *tmr;
-	snd_timer_instance_t *ti;
+	struct snd_seq_queue *q;
+	struct snd_seq_timer *tmr;
+	struct snd_timer_instance *ti;
 	unsigned long resolution;
 	
 	for (idx = 0; idx < SNDRV_SEQ_MAX_QUEUES; idx++) {
@@ -447,3 +452,5 @@
 		queuefree(q);
  	}
 }
+#endif /* CONFIG_PROC_FS */
+
diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h
index 287ed68..e9ee154 100644
--- a/sound/core/seq/seq_timer.h
+++ b/sound/core/seq/seq_timer.h
@@ -24,13 +24,13 @@
 #include <sound/timer.h>
 #include <sound/seq_kernel.h>
 
-typedef struct {
+struct snd_seq_timer_tick {
 	snd_seq_tick_time_t	cur_tick;	/* current tick */
 	unsigned long		resolution;	/* time per tick in nsec */
 	unsigned long		fraction;	/* current time per tick in nsec */
-} seq_timer_tick_t;
+};
 
-typedef struct {
+struct snd_seq_timer {
 	/* ... tempo / offset / running state */
 
 	unsigned int		running:1,	/* running state of queue */	
@@ -40,12 +40,12 @@
 	int			ppq;		/* time resolution, ticks/quarter */
 
 	snd_seq_real_time_t	cur_time;	/* current time */
-	seq_timer_tick_t	tick;		/* current tick */
+	struct snd_seq_timer_tick	tick;	/* current tick */
 	int tick_updated;
 	
 	int			type;		/* timer type */
-	snd_timer_id_t		alsa_id;	/* ALSA's timer ID */
-	snd_timer_instance_t	*timeri;	/* timer instance */
+	struct snd_timer_id	alsa_id;	/* ALSA's timer ID */
+	struct snd_timer_instance	*timeri;	/* timer instance */
 	unsigned int		ticks;
 	unsigned long		preferred_resolution; /* timer resolution, ticks/sec */
 
@@ -55,17 +55,18 @@
 	struct timeval 		last_update;	 /* time of last clock update, used for interpolation */
 
 	spinlock_t lock;
-} seq_timer_t;
+};
 
 
 /* create new timer (constructor) */
-extern seq_timer_t *snd_seq_timer_new(void);
+struct snd_seq_timer *snd_seq_timer_new(void);
 
 /* delete timer (destructor) */
-extern void snd_seq_timer_delete(seq_timer_t **tmr);
+void snd_seq_timer_delete(struct snd_seq_timer **tmr);
 
 /* */
-static inline void snd_seq_timer_update_tick(seq_timer_tick_t *tick, unsigned long resolution)
+static inline void snd_seq_timer_update_tick(struct snd_seq_timer_tick *tick,
+					     unsigned long resolution)
 {
 	if (tick->resolution > 0) {
 		tick->fraction += resolution;
@@ -119,21 +120,22 @@
 }
 
 /* called by timer isr */
-int snd_seq_timer_open(queue_t *q);
-int snd_seq_timer_close(queue_t *q);
-int snd_seq_timer_midi_open(queue_t *q);
-int snd_seq_timer_midi_close(queue_t *q);
-void snd_seq_timer_defaults(seq_timer_t *tmr);
-void snd_seq_timer_reset(seq_timer_t *tmr);
-int snd_seq_timer_stop(seq_timer_t *tmr);
-int snd_seq_timer_start(seq_timer_t *tmr);
-int snd_seq_timer_continue(seq_timer_t *tmr);
-int snd_seq_timer_set_tempo(seq_timer_t *tmr, int tempo);
-int snd_seq_timer_set_ppq(seq_timer_t *tmr, int ppq);
-int snd_seq_timer_set_position_tick(seq_timer_t *tmr, snd_seq_tick_time_t position);
-int snd_seq_timer_set_position_time(seq_timer_t *tmr, snd_seq_real_time_t position);
-int snd_seq_timer_set_skew(seq_timer_t *tmr, unsigned int skew, unsigned int base);
-snd_seq_real_time_t snd_seq_timer_get_cur_time(seq_timer_t *tmr);
-snd_seq_tick_time_t snd_seq_timer_get_cur_tick(seq_timer_t *tmr);
+struct snd_seq_queue;
+int snd_seq_timer_open(struct snd_seq_queue *q);
+int snd_seq_timer_close(struct snd_seq_queue *q);
+int snd_seq_timer_midi_open(struct snd_seq_queue *q);
+int snd_seq_timer_midi_close(struct snd_seq_queue *q);
+void snd_seq_timer_defaults(struct snd_seq_timer *tmr);
+void snd_seq_timer_reset(struct snd_seq_timer *tmr);
+int snd_seq_timer_stop(struct snd_seq_timer *tmr);
+int snd_seq_timer_start(struct snd_seq_timer *tmr);
+int snd_seq_timer_continue(struct snd_seq_timer *tmr);
+int snd_seq_timer_set_tempo(struct snd_seq_timer *tmr, int tempo);
+int snd_seq_timer_set_ppq(struct snd_seq_timer *tmr, int ppq);
+int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position);
+int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position);
+int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base);
+snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr);
+snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr);
 
 #endif
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index e4f512a..14fd1a6 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -56,7 +56,8 @@
 /*
  * initialize an event record
  */
-static void snd_virmidi_init_event(snd_virmidi_t *vmidi, snd_seq_event_t *ev)
+static void snd_virmidi_init_event(struct snd_virmidi *vmidi,
+				   struct snd_seq_event *ev)
 {
 	memset(ev, 0, sizeof(*ev));
 	ev->source.port = vmidi->port;
@@ -76,16 +77,17 @@
 /*
  * decode input event and put to read buffer of each opened file
  */
-static int snd_virmidi_dev_receive_event(snd_virmidi_dev_t *rdev, snd_seq_event_t *ev)
+static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
+					 struct snd_seq_event *ev)
 {
-	snd_virmidi_t *vmidi;
+	struct snd_virmidi *vmidi;
 	struct list_head *list;
 	unsigned char msg[4];
 	int len;
 
 	read_lock(&rdev->filelist_lock);
 	list_for_each(list, &rdev->filelist) {
-		vmidi = list_entry(list, snd_virmidi_t, list);
+		vmidi = list_entry(list, struct snd_virmidi, list);
 		if (!vmidi->trigger)
 			continue;
 		if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
@@ -111,9 +113,9 @@
  * SNDRV_VIRMIDI_SEQ_ATTACH.
  */
 #if 0
-int snd_virmidi_receive(snd_rawmidi_t *rmidi, snd_seq_event_t *ev)
+int snd_virmidi_receive(struct snd_rawmidi *rmidi, struct snd_seq_event *ev)
 {
-	snd_virmidi_dev_t *rdev;
+	struct snd_virmidi_dev *rdev;
 
 	rdev = rmidi->private_data;
 	return snd_virmidi_dev_receive_event(rdev, ev);
@@ -123,10 +125,10 @@
 /*
  * event handler of virmidi port
  */
-static int snd_virmidi_event_input(snd_seq_event_t *ev, int direct,
+static int snd_virmidi_event_input(struct snd_seq_event *ev, int direct,
 				   void *private_data, int atomic, int hop)
 {
-	snd_virmidi_dev_t *rdev;
+	struct snd_virmidi_dev *rdev;
 
 	rdev = private_data;
 	if (!(rdev->flags & SNDRV_VIRMIDI_USE))
@@ -137,9 +139,9 @@
 /*
  * trigger rawmidi stream for input
  */
-static void snd_virmidi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_virmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	snd_virmidi_t *vmidi = substream->runtime->private_data;
+	struct snd_virmidi *vmidi = substream->runtime->private_data;
 
 	if (up) {
 		vmidi->trigger = 1;
@@ -151,9 +153,9 @@
 /*
  * trigger rawmidi stream for output
  */
-static void snd_virmidi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	snd_virmidi_t *vmidi = substream->runtime->private_data;
+	struct snd_virmidi *vmidi = substream->runtime->private_data;
 	int count, res;
 	unsigned char buf[32], *pbuf;
 
@@ -198,11 +200,11 @@
 /*
  * open rawmidi handle for input
  */
-static int snd_virmidi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_virmidi_input_open(struct snd_rawmidi_substream *substream)
 {
-	snd_virmidi_dev_t *rdev = substream->rmidi->private_data;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
-	snd_virmidi_t *vmidi;
+	struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	struct snd_virmidi *vmidi;
 	unsigned long flags;
 
 	vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
@@ -227,11 +229,11 @@
 /*
  * open rawmidi handle for output
  */
-static int snd_virmidi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_virmidi_output_open(struct snd_rawmidi_substream *substream)
 {
-	snd_virmidi_dev_t *rdev = substream->rmidi->private_data;
-	snd_rawmidi_runtime_t *runtime = substream->runtime;
-	snd_virmidi_t *vmidi;
+	struct snd_virmidi_dev *rdev = substream->rmidi->private_data;
+	struct snd_rawmidi_runtime *runtime = substream->runtime;
+	struct snd_virmidi *vmidi;
 
 	vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL);
 	if (vmidi == NULL)
@@ -253,9 +255,9 @@
 /*
  * close rawmidi handle for input
  */
-static int snd_virmidi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_virmidi_input_close(struct snd_rawmidi_substream *substream)
 {
-	snd_virmidi_t *vmidi = substream->runtime->private_data;
+	struct snd_virmidi *vmidi = substream->runtime->private_data;
 	snd_midi_event_free(vmidi->parser);
 	list_del(&vmidi->list);
 	substream->runtime->private_data = NULL;
@@ -266,9 +268,9 @@
 /*
  * close rawmidi handle for output
  */
-static int snd_virmidi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_virmidi_output_close(struct snd_rawmidi_substream *substream)
 {
-	snd_virmidi_t *vmidi = substream->runtime->private_data;
+	struct snd_virmidi *vmidi = substream->runtime->private_data;
 	snd_midi_event_free(vmidi->parser);
 	substream->runtime->private_data = NULL;
 	kfree(vmidi);
@@ -278,9 +280,10 @@
 /*
  * subscribe callback - allow output to rawmidi device
  */
-static int snd_virmidi_subscribe(void *private_data, snd_seq_port_subscribe_t *info)
+static int snd_virmidi_subscribe(void *private_data,
+				 struct snd_seq_port_subscribe *info)
 {
-	snd_virmidi_dev_t *rdev;
+	struct snd_virmidi_dev *rdev;
 
 	rdev = private_data;
 	if (!try_module_get(rdev->card->module))
@@ -292,9 +295,10 @@
 /*
  * unsubscribe callback - disallow output to rawmidi device
  */
-static int snd_virmidi_unsubscribe(void *private_data, snd_seq_port_subscribe_t *info)
+static int snd_virmidi_unsubscribe(void *private_data,
+				   struct snd_seq_port_subscribe *info)
 {
-	snd_virmidi_dev_t *rdev;
+	struct snd_virmidi_dev *rdev;
 
 	rdev = private_data;
 	rdev->flags &= ~SNDRV_VIRMIDI_SUBSCRIBE;
@@ -306,9 +310,10 @@
 /*
  * use callback - allow input to rawmidi device
  */
-static int snd_virmidi_use(void *private_data, snd_seq_port_subscribe_t *info)
+static int snd_virmidi_use(void *private_data,
+			   struct snd_seq_port_subscribe *info)
 {
-	snd_virmidi_dev_t *rdev;
+	struct snd_virmidi_dev *rdev;
 
 	rdev = private_data;
 	if (!try_module_get(rdev->card->module))
@@ -320,9 +325,10 @@
 /*
  * unuse callback - disallow input to rawmidi device
  */
-static int snd_virmidi_unuse(void *private_data, snd_seq_port_subscribe_t *info)
+static int snd_virmidi_unuse(void *private_data,
+			     struct snd_seq_port_subscribe *info)
 {
-	snd_virmidi_dev_t *rdev;
+	struct snd_virmidi_dev *rdev;
 
 	rdev = private_data;
 	rdev->flags &= ~SNDRV_VIRMIDI_USE;
@@ -335,13 +341,13 @@
  *  Register functions
  */
 
-static snd_rawmidi_ops_t snd_virmidi_input_ops = {
+static struct snd_rawmidi_ops snd_virmidi_input_ops = {
 	.open = snd_virmidi_input_open,
 	.close = snd_virmidi_input_close,
 	.trigger = snd_virmidi_input_trigger,
 };
 
-static snd_rawmidi_ops_t snd_virmidi_output_ops = {
+static struct snd_rawmidi_ops snd_virmidi_output_ops = {
 	.open = snd_virmidi_output_open,
 	.close = snd_virmidi_output_close,
 	.trigger = snd_virmidi_output_trigger,
@@ -350,43 +356,32 @@
 /*
  * create a sequencer client and a port
  */
-static int snd_virmidi_dev_attach_seq(snd_virmidi_dev_t *rdev)
+static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev)
 {
 	int client;
-	snd_seq_client_callback_t callbacks;
-	snd_seq_port_callback_t pcallbacks;
-	snd_seq_client_info_t *info;
-	snd_seq_port_info_t *pinfo;
+	struct snd_seq_port_callback pcallbacks;
+	struct snd_seq_port_info *pinfo;
 	int err;
 
 	if (rdev->client >= 0)
 		return 0;
 
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	pinfo = kmalloc(sizeof(*pinfo), GFP_KERNEL);
-	if (! info || ! pinfo) {
+	if (!pinfo) {
 		err = -ENOMEM;
 		goto __error;
 	}
 
-	memset(&callbacks, 0, sizeof(callbacks));
-	callbacks.private_data = rdev;
-	callbacks.allow_input = 1;
-	callbacks.allow_output = 1;
-	client = snd_seq_create_kernel_client(rdev->card, rdev->device, &callbacks);
+	client = snd_seq_create_kernel_client(rdev->card, rdev->device,
+					      "%s %d-%d", rdev->rmidi->name,
+					      rdev->card->number,
+					      rdev->device);
 	if (client < 0) {
 		err = client;
 		goto __error;
 	}
 	rdev->client = client;
 
-	/* set client name */
-	memset(info, 0, sizeof(*info));
-	info->client = client;
-	info->type = KERNEL_CLIENT;
-	sprintf(info->name, "%s %d-%d", rdev->rmidi->name, rdev->card->number, rdev->device);
-	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, info);
-
 	/* create a port */
 	memset(pinfo, 0, sizeof(*pinfo));
 	pinfo->addr.client = client;
@@ -417,7 +412,6 @@
 	err = 0; /* success */
 
  __error:
-	kfree(info);
 	kfree(pinfo);
 	return err;
 }
@@ -426,7 +420,7 @@
 /*
  * release the sequencer client
  */
-static void snd_virmidi_dev_detach_seq(snd_virmidi_dev_t *rdev)
+static void snd_virmidi_dev_detach_seq(struct snd_virmidi_dev *rdev)
 {
 	if (rdev->client >= 0) {
 		snd_seq_delete_kernel_client(rdev->client);
@@ -437,9 +431,9 @@
 /*
  * register the device
  */
-static int snd_virmidi_dev_register(snd_rawmidi_t *rmidi)
+static int snd_virmidi_dev_register(struct snd_rawmidi *rmidi)
 {
-	snd_virmidi_dev_t *rdev = rmidi->private_data;
+	struct snd_virmidi_dev *rdev = rmidi->private_data;
 	int err;
 
 	switch (rdev->seq_mode) {
@@ -464,9 +458,9 @@
 /*
  * unregister the device
  */
-static int snd_virmidi_dev_unregister(snd_rawmidi_t *rmidi)
+static int snd_virmidi_dev_unregister(struct snd_rawmidi *rmidi)
 {
-	snd_virmidi_dev_t *rdev = rmidi->private_data;
+	struct snd_virmidi_dev *rdev = rmidi->private_data;
 
 	if (rdev->seq_mode == SNDRV_VIRMIDI_SEQ_DISPATCH)
 		snd_virmidi_dev_detach_seq(rdev);
@@ -476,7 +470,7 @@
 /*
  *
  */
-static snd_rawmidi_global_ops_t snd_virmidi_global_ops = {
+static struct snd_rawmidi_global_ops snd_virmidi_global_ops = {
 	.dev_register = snd_virmidi_dev_register,
 	.dev_unregister = snd_virmidi_dev_unregister,
 };
@@ -484,9 +478,9 @@
 /*
  * free device
  */
-static void snd_virmidi_free(snd_rawmidi_t *rmidi)
+static void snd_virmidi_free(struct snd_rawmidi *rmidi)
 {
-	snd_virmidi_dev_t *rdev = rmidi->private_data;
+	struct snd_virmidi_dev *rdev = rmidi->private_data;
 	kfree(rdev);
 }
 
@@ -495,10 +489,10 @@
  *
  */
 /* exported */
-int snd_virmidi_new(snd_card_t *card, int device, snd_rawmidi_t **rrmidi)
+int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmidi)
 {
-	snd_rawmidi_t *rmidi;
-	snd_virmidi_dev_t *rdev;
+	struct snd_rawmidi *rmidi;
+	struct snd_virmidi_dev *rdev;
 	int err;
 	
 	*rrmidi = NULL;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 6e7cad1e..a8eda02 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/device.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/minors.h>
@@ -32,7 +33,6 @@
 #include <sound/initval.h>
 #include <linux/kmod.h>
 #include <linux/devfs_fs_kernel.h>
-#include <linux/platform_device.h>
 
 #define SNDRV_OS_MINORS 256
 
@@ -60,8 +60,7 @@
  */
 int snd_ecards_limit;
 
-static struct list_head snd_minors_hash[SNDRV_CARDS];
-
+static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
 static DECLARE_MUTEX(sound_mutex);
 
 extern struct class *sound_class;
@@ -108,44 +107,61 @@
 
 #endif				/* request_module support */
 
-static snd_minor_t *snd_minor_search(int minor)
+/**
+ * snd_lookup_minor_data - get user data of a registered device
+ * @minor: the minor number
+ * @type: device type (SNDRV_DEVICE_TYPE_XXX)
+ *
+ * Checks that a minor device with the specified type is registered, and returns
+ * its user data pointer.
+ */
+void *snd_lookup_minor_data(unsigned int minor, int type)
 {
-	struct list_head *list;
-	snd_minor_t *mptr;
+	struct snd_minor *mreg;
+	void *private_data;
 
-	list_for_each(list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]) {
-		mptr = list_entry(list, snd_minor_t, list);
-		if (mptr->number == minor)
-			return mptr;
-	}
-	return NULL;
+	if (minor > ARRAY_SIZE(snd_minors))
+		return NULL;
+	down(&sound_mutex);
+	mreg = snd_minors[minor];
+	if (mreg && mreg->type == type)
+		private_data = mreg->private_data;
+	else
+		private_data = NULL;
+	up(&sound_mutex);
+	return private_data;
 }
 
 static int snd_open(struct inode *inode, struct file *file)
 {
-	int minor = iminor(inode);
-	int card = SNDRV_MINOR_CARD(minor);
-	int dev = SNDRV_MINOR_DEVICE(minor);
-	snd_minor_t *mptr = NULL;
+	unsigned int minor = iminor(inode);
+	struct snd_minor *mptr = NULL;
 	struct file_operations *old_fops;
 	int err = 0;
 
-	if (dev != SNDRV_MINOR_GLOBAL) {
-		if (snd_cards[card] == NULL) {
-#ifdef CONFIG_KMOD
-			snd_request_card(card);
-			if (snd_cards[card] == NULL)
-#endif
-				return -ENODEV;
-		}
-	} else {
-#ifdef CONFIG_KMOD
-		if ((mptr = snd_minor_search(minor)) == NULL)
-			snd_request_other(minor);
-#endif
-	}
-	if (mptr == NULL && (mptr = snd_minor_search(minor)) == NULL)
+	if (minor > ARRAY_SIZE(snd_minors))
 		return -ENODEV;
+	mptr = snd_minors[minor];
+	if (mptr == NULL) {
+#ifdef CONFIG_KMOD
+		int dev = SNDRV_MINOR_DEVICE(minor);
+		if (dev == SNDRV_MINOR_CONTROL) {
+			/* /dev/aloadC? */
+			int card = SNDRV_MINOR_CARD(minor);
+			if (snd_cards[card] == NULL)
+				snd_request_card(card);
+		} else if (dev == SNDRV_MINOR_GLOBAL) {
+			/* /dev/aloadSEQ */
+			snd_request_other(minor);
+		}
+#ifndef CONFIG_SND_DYNAMIC_MINORS
+		/* /dev/snd/{controlC?,seq} */
+		mptr = snd_minors[minor];
+		if (mptr == NULL)
+#endif
+#endif
+			return -ENODEV;
+	}
 	old_fops = file->f_op;
 	file->f_op = fops_get(mptr->f_ops);
 	if (file->f_op->open)
@@ -164,7 +180,23 @@
 	.open =		snd_open
 };
 
-static int snd_kernel_minor(int type, snd_card_t * card, int dev)
+#ifdef CONFIG_SND_DYNAMIC_MINORS
+static int snd_find_free_minor(void)
+{
+	int minor;
+
+	for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) {
+		/* skip minors still used statically for autoloading devices */
+		if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL ||
+		    minor == SNDRV_MINOR_SEQUENCER)
+			continue;
+		if (!snd_minors[minor])
+			return minor;
+	}
+	return -EBUSY;
+}
+#else
+static int snd_kernel_minor(int type, struct snd_card *card, int dev)
 {
 	int minor;
 
@@ -190,13 +222,15 @@
 	snd_assert(minor >= 0 && minor < SNDRV_OS_MINORS, return -EINVAL);
 	return minor;
 }
+#endif
 
 /**
  * snd_register_device - Register the ALSA device file for the card
  * @type: the device type, SNDRV_DEVICE_TYPE_XXX
  * @card: the card instance
  * @dev: the device index
- * @reg: the snd_minor_t record
+ * @f_ops: the file operations
+ * @private_data: user pointer for f_ops->open()
  * @name: the device file name
  *
  * Registers an ALSA device file for the given card.
@@ -204,30 +238,39 @@
  *
  * Retrurns zero if successful, or a negative error code on failure.
  */
-int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg, const char *name)
+int snd_register_device(int type, struct snd_card *card, int dev,
+			struct file_operations *f_ops, void *private_data,
+			const char *name)
 {
-	int minor = snd_kernel_minor(type, card, dev);
-	snd_minor_t *preg;
+	int minor;
+	struct snd_minor *preg;
 	struct device *device = NULL;
 
-	if (minor < 0)
-		return minor;
 	snd_assert(name, return -EINVAL);
-	preg = (snd_minor_t *)kmalloc(sizeof(snd_minor_t) + strlen(name) + 1, GFP_KERNEL);
+	preg = kmalloc(sizeof(struct snd_minor) + strlen(name) + 1, GFP_KERNEL);
 	if (preg == NULL)
 		return -ENOMEM;
-	*preg = *reg;
-	preg->number = minor;
+	preg->type = type;
+	preg->card = card ? card->number : -1;
 	preg->device = dev;
+	preg->f_ops = f_ops;
+	preg->private_data = private_data;
 	strcpy(preg->name, name);
 	down(&sound_mutex);
-	if (snd_minor_search(minor)) {
+#ifdef CONFIG_SND_DYNAMIC_MINORS
+	minor = snd_find_free_minor();
+#else
+	minor = snd_kernel_minor(type, card, dev);
+	if (minor >= 0 && snd_minors[minor])
+		minor = -EBUSY;
+#endif
+	if (minor < 0) {
 		up(&sound_mutex);
 		kfree(preg);
-		return -EBUSY;
+		return minor;
 	}
-	list_add_tail(&preg->list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]);
-	if (strncmp(name, "controlC", 8) || card->number >= cards_limit)
+	snd_minors[minor] = preg;
+	if (type != SNDRV_DEVICE_TYPE_CONTROL || preg->card >= cards_limit)
 		devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
 	if (card)
 		device = card->dev;
@@ -248,61 +291,92 @@
  *
  * Returns zero if sucecessful, or a negative error code on failure
  */
-int snd_unregister_device(int type, snd_card_t * card, int dev)
+int snd_unregister_device(int type, struct snd_card *card, int dev)
 {
-	int minor = snd_kernel_minor(type, card, dev);
-	snd_minor_t *mptr;
+	int cardnum, minor;
+	struct snd_minor *mptr;
 
-	if (minor < 0)
-		return minor;
+	cardnum = card ? card->number : -1;
 	down(&sound_mutex);
-	if ((mptr = snd_minor_search(minor)) == NULL) {
+	for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor)
+		if ((mptr = snd_minors[minor]) != NULL &&
+		    mptr->type == type &&
+		    mptr->card == cardnum &&
+		    mptr->device == dev)
+			break;
+	if (minor == ARRAY_SIZE(snd_minors)) {
 		up(&sound_mutex);
 		return -EINVAL;
 	}
 
-	if (strncmp(mptr->name, "controlC", 8) || card->number >= cards_limit) /* created in sound.c */
+	if (mptr->type != SNDRV_DEVICE_TYPE_CONTROL ||
+	    mptr->card >= cards_limit)			/* created in sound.c */
 		devfs_remove("snd/%s", mptr->name);
 	class_device_destroy(sound_class, MKDEV(major, minor));
 
-	list_del(&mptr->list);
+	snd_minors[minor] = NULL;
 	up(&sound_mutex);
 	kfree(mptr);
 	return 0;
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *  INFO PART
  */
 
-static snd_info_entry_t *snd_minor_info_entry = NULL;
+static struct snd_info_entry *snd_minor_info_entry = NULL;
 
-static void snd_minor_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static const char *snd_device_type_name(int type)
 {
-	int card, device;
-	struct list_head *list;
-	snd_minor_t *mptr;
+	switch (type) {
+	case SNDRV_DEVICE_TYPE_CONTROL:
+		return "control";
+	case SNDRV_DEVICE_TYPE_HWDEP:
+		return "hardware dependent";
+	case SNDRV_DEVICE_TYPE_RAWMIDI:
+		return "raw midi";
+	case SNDRV_DEVICE_TYPE_PCM_PLAYBACK:
+		return "digital audio playback";
+	case SNDRV_DEVICE_TYPE_PCM_CAPTURE:
+		return "digital audio capture";
+	case SNDRV_DEVICE_TYPE_SEQUENCER:
+		return "sequencer";
+	case SNDRV_DEVICE_TYPE_TIMER:
+		return "timer";
+	default:
+		return "?";
+	}
+}
+
+static void snd_minor_info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
+{
+	int minor;
+	struct snd_minor *mptr;
 
 	down(&sound_mutex);
-	for (card = 0; card < SNDRV_CARDS; card++) {
-		list_for_each(list, &snd_minors_hash[card]) {
-			mptr = list_entry(list, snd_minor_t, list);
-			if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_GLOBAL) {
-				if ((device = mptr->device) >= 0)
-					snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, mptr->comment);
-				else
-					snd_iprintf(buffer, "%3i: [%i]   : %s\n", mptr->number, card, mptr->comment);
-			} else {
-				snd_iprintf(buffer, "%3i:       : %s\n", mptr->number, mptr->comment);
-			}
-		}
+	for (minor = 0; minor < SNDRV_OS_MINORS; ++minor) {
+		if (!(mptr = snd_minors[minor]))
+			continue;
+		if (mptr->card >= 0) {
+			if (mptr->device >= 0)
+				snd_iprintf(buffer, "%3i: [%2i-%2i]: %s\n",
+					    minor, mptr->card, mptr->device,
+					    snd_device_type_name(mptr->type));
+			else
+				snd_iprintf(buffer, "%3i: [%2i]   : %s\n",
+					    minor, mptr->card,
+					    snd_device_type_name(mptr->type));
+		} else
+			snd_iprintf(buffer, "%3i:        : %s\n", minor,
+				    snd_device_type_name(mptr->type));
 	}
 	up(&sound_mutex);
 }
 
 int __init snd_minor_info_init(void)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	entry = snd_info_create_module_entry(THIS_MODULE, "devices", NULL);
 	if (entry) {
@@ -323,27 +397,18 @@
 		snd_info_unregister(snd_minor_info_entry);
 	return 0;
 }
+#endif /* CONFIG_PROC_FS */
 
 /*
  *  INIT PART
  */
 
-#ifdef CONFIG_SND_GENERIC_DRIVER
-extern struct platform_driver snd_generic_driver;
-#endif
-
 static int __init alsa_sound_init(void)
 {
 	short controlnum;
-	int err;
-	int card;
 
 	snd_major = major;
 	snd_ecards_limit = cards_limit;
-	for (card = 0; card < SNDRV_CARDS; card++)
-		INIT_LIST_HEAD(&snd_minors_hash[card]);
-	if ((err = snd_oss_init_module()) < 0)
-		return err;
 	devfs_mk_dir("snd");
 	if (register_chrdev(major, "alsa", &snd_fops)) {
 		snd_printk(KERN_ERR "unable to register native major device number %d\n", major);
@@ -356,9 +421,6 @@
 		return -ENOMEM;
 	}
 	snd_info_minor_register();
-#ifdef CONFIG_SND_GENERIC_DRIVER
-	platform_driver_register(&snd_generic_driver);
-#endif
 	for (controlnum = 0; controlnum < cards_limit; controlnum++)
 		devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
 #ifndef MODULE
@@ -374,9 +436,6 @@
 	for (controlnum = 0; controlnum < cards_limit; controlnum++)
 		devfs_remove("snd/controlC%d", controlnum);
 
-#ifdef CONFIG_SND_GENERIC_DRIVER
-	platform_driver_unregister(&snd_generic_driver);
-#endif
 	snd_info_minor_unregister();
 	snd_info_done();
 	if (unregister_chrdev(major, "alsa") != 0)
@@ -395,9 +454,11 @@
 #endif
 EXPORT_SYMBOL(snd_register_device);
 EXPORT_SYMBOL(snd_unregister_device);
+EXPORT_SYMBOL(snd_lookup_minor_data);
 #if defined(CONFIG_SND_OSSEMUL)
 EXPORT_SYMBOL(snd_register_oss_device);
 EXPORT_SYMBOL(snd_unregister_oss_device);
+EXPORT_SYMBOL(snd_lookup_oss_minor_data);
 #endif
   /* memory.c */
 EXPORT_SYMBOL(copy_to_user_fromio);
@@ -415,19 +476,8 @@
 EXPORT_SYMBOL(snd_component_add);
 EXPORT_SYMBOL(snd_card_file_add);
 EXPORT_SYMBOL(snd_card_file_remove);
-#ifdef CONFIG_SND_GENERIC_DRIVER
-EXPORT_SYMBOL(snd_card_set_generic_dev);
-#endif
 #ifdef CONFIG_PM
 EXPORT_SYMBOL(snd_power_wait);
-EXPORT_SYMBOL(snd_card_set_pm_callback);
-#ifdef CONFIG_SND_GENERIC_DRIVER
-EXPORT_SYMBOL(snd_card_set_generic_pm_callback);
-#endif
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL(snd_card_pci_suspend);
-EXPORT_SYMBOL(snd_card_pci_resume);
-#endif
 #endif
   /* device.c */
 EXPORT_SYMBOL(snd_device_new);
diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c
index e401c67..d0be32b 100644
--- a/sound/core/sound_oss.c
+++ b/sound/core/sound_oss.c
@@ -35,26 +35,29 @@
 #include <sound/info.h>
 #include <linux/sound.h>
 
-#define SNDRV_OS_MINORS		256
+#define SNDRV_OSS_MINORS 128
 
-static struct list_head snd_oss_minors_hash[SNDRV_CARDS];
-
+static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
 static DECLARE_MUTEX(sound_oss_mutex);
 
-static snd_minor_t *snd_oss_minor_search(int minor)
+void *snd_lookup_oss_minor_data(unsigned int minor, int type)
 {
-	struct list_head *list;
-	snd_minor_t *mptr;
+	struct snd_minor *mreg;
+	void *private_data;
 
-	list_for_each(list, &snd_oss_minors_hash[SNDRV_MINOR_OSS_CARD(minor)]) {
-		mptr = list_entry(list, snd_minor_t, list);
-		if (mptr->number == minor)
-			return mptr;
-	}
-	return NULL;
+	if (minor > ARRAY_SIZE(snd_oss_minors))
+		return NULL;
+	down(&sound_oss_mutex);
+	mreg = snd_oss_minors[minor];
+	if (mreg && mreg->type == type)
+		private_data = mreg->private_data;
+	else
+		private_data = NULL;
+	up(&sound_oss_mutex);
+	return private_data;
 }
 
-static int snd_oss_kernel_minor(int type, snd_card_t * card, int dev)
+static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
 {
 	int minor;
 
@@ -86,30 +89,36 @@
 	default:
 		return -EINVAL;
 	}
-	snd_assert(minor >= 0 && minor < SNDRV_OS_MINORS, return -EINVAL);
+	snd_assert(minor >= 0 && minor < SNDRV_OSS_MINORS, return -EINVAL);
 	return minor;
 }
 
-int snd_register_oss_device(int type, snd_card_t * card, int dev, snd_minor_t * reg, const char *name)
+int snd_register_oss_device(int type, struct snd_card *card, int dev,
+			    struct file_operations *f_ops, void *private_data,
+			    const char *name)
 {
 	int minor = snd_oss_kernel_minor(type, card, dev);
 	int minor_unit;
-	snd_minor_t *preg;
+	struct snd_minor *preg;
 	int cidx = SNDRV_MINOR_OSS_CARD(minor);
 	int track2 = -1;
 	int register1 = -1, register2 = -1;
 	struct device *carddev = NULL;
 
+	if (card && card->number >= 8)
+		return 0; /* ignore silently */
 	if (minor < 0)
 		return minor;
-	preg = (snd_minor_t *)kmalloc(sizeof(snd_minor_t), GFP_KERNEL);
+	preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL);
 	if (preg == NULL)
 		return -ENOMEM;
-	*preg = *reg;
-	preg->number = minor;
+	preg->type = type;
+	preg->card = card ? card->number : -1;
 	preg->device = dev;
+	preg->f_ops = f_ops;
+	preg->private_data = private_data;
 	down(&sound_oss_mutex);
-	list_add_tail(&preg->list, &snd_oss_minors_hash[cidx]);
+	snd_oss_minors[minor] = preg;
 	minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
 	switch (minor_unit) {
 	case SNDRV_MINOR_OSS_PCM:
@@ -124,13 +133,15 @@
 	}
 	if (card)
 		carddev = card->dev;
-	register1 = register_sound_special_device(reg->f_ops, minor, carddev);
+	register1 = register_sound_special_device(f_ops, minor, carddev);
 	if (register1 != minor)
 		goto __end;
 	if (track2 >= 0) {
-		register2 = register_sound_special_device(reg->f_ops, track2, carddev);
+		register2 = register_sound_special_device(f_ops, track2,
+							  carddev);
 		if (register2 != track2)
 			goto __end;
+		snd_oss_minors[track2] = preg;
 	}
 	up(&sound_oss_mutex);
 	return 0;
@@ -140,23 +151,25 @@
       		unregister_sound_special(register2);
       	if (register1 >= 0)
       		unregister_sound_special(register1);
-      	list_del(&preg->list);
+	snd_oss_minors[minor] = NULL;
 	up(&sound_oss_mutex);
 	kfree(preg);
       	return -EBUSY;
 }
 
-int snd_unregister_oss_device(int type, snd_card_t * card, int dev)
+int snd_unregister_oss_device(int type, struct snd_card *card, int dev)
 {
 	int minor = snd_oss_kernel_minor(type, card, dev);
 	int cidx = SNDRV_MINOR_OSS_CARD(minor);
 	int track2 = -1;
-	snd_minor_t *mptr;
+	struct snd_minor *mptr;
 
+	if (card && card->number >= 8)
+		return 0;
 	if (minor < 0)
 		return minor;
 	down(&sound_oss_mutex);
-	mptr = snd_oss_minor_search(minor);
+	mptr = snd_oss_minors[minor];
 	if (mptr == NULL) {
 		up(&sound_oss_mutex);
 		return -ENOENT;
@@ -173,9 +186,11 @@
 		track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1);
 		break;
 	}
-	if (track2 >= 0)
+	if (track2 >= 0) {
 		unregister_sound_special(track2);
-	list_del(&mptr->list);
+		snd_oss_minors[track2] = NULL;
+	}
+	snd_oss_minors[minor] = NULL;
 	up(&sound_oss_mutex);
 	kfree(mptr);
 	return 0;
@@ -187,36 +202,52 @@
 
 #ifdef CONFIG_PROC_FS
 
-static snd_info_entry_t *snd_minor_info_oss_entry = NULL;
+static struct snd_info_entry *snd_minor_info_oss_entry = NULL;
 
-static void snd_minor_info_oss_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static const char *snd_oss_device_type_name(int type)
 {
-	int card, dev;
-	struct list_head *list;
-	snd_minor_t *mptr;
+	switch (type) {
+	case SNDRV_OSS_DEVICE_TYPE_MIXER:
+		return "mixer";
+	case SNDRV_OSS_DEVICE_TYPE_SEQUENCER:
+	case SNDRV_OSS_DEVICE_TYPE_MUSIC:
+		return "sequencer";
+	case SNDRV_OSS_DEVICE_TYPE_PCM:
+		return "digital audio";
+	case SNDRV_OSS_DEVICE_TYPE_MIDI:
+		return "raw midi";
+	case SNDRV_OSS_DEVICE_TYPE_DMFM:
+		return "hardware dependent";
+	default:
+		return "?";
+	}
+}
+
+static void snd_minor_info_oss_read(struct snd_info_entry *entry,
+				    struct snd_info_buffer *buffer)
+{
+	int minor;
+	struct snd_minor *mptr;
 
 	down(&sound_oss_mutex);
-	for (card = 0; card < SNDRV_CARDS; card++) {
-		list_for_each(list, &snd_oss_minors_hash[card]) {
-			mptr = list_entry(list, snd_minor_t, list);
-			dev = SNDRV_MINOR_OSS_DEVICE(mptr->number);
-		        if (dev != SNDRV_MINOR_OSS_SNDSTAT &&
-			    dev != SNDRV_MINOR_OSS_SEQUENCER &&
-			    dev != SNDRV_MINOR_OSS_MUSIC)
-				snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, dev, mptr->comment);
-			else
-				snd_iprintf(buffer, "%3i:       : %s\n", mptr->number, mptr->comment);
-		}
+	for (minor = 0; minor < SNDRV_OSS_MINORS; ++minor) {
+		if (!(mptr = snd_oss_minors[minor]))
+			continue;
+		if (mptr->card >= 0)
+			snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", minor,
+				    mptr->card, mptr->device,
+				    snd_oss_device_type_name(mptr->type));
+		else
+			snd_iprintf(buffer, "%3i:       : %s\n", minor,
+				    snd_oss_device_type_name(mptr->type));
 	}
 	up(&sound_oss_mutex);
 }
 
-#endif /* CONFIG_PROC_FS */
 
 int __init snd_minor_info_oss_init(void)
 {
-#ifdef CONFIG_PROC_FS
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	entry = snd_info_create_module_entry(THIS_MODULE, "devices", snd_oss_root);
 	if (entry) {
@@ -228,26 +259,15 @@
 		}
 	}
 	snd_minor_info_oss_entry = entry;
-#endif
 	return 0;
 }
 
 int __exit snd_minor_info_oss_done(void)
 {
-#ifdef CONFIG_PROC_FS
 	if (snd_minor_info_oss_entry)
 		snd_info_unregister(snd_minor_info_oss_entry);
-#endif
 	return 0;
 }
-
-int __init snd_oss_init_module(void)
-{
-	int card;
-	
-	for (card = 0; card < SNDRV_CARDS; card++)
-		INIT_LIST_HEAD(&snd_oss_minors_hash[card]);
-	return 0;
-}
+#endif /* CONFIG_PROC_FS */
 
 #endif /* CONFIG_SND_OSSEMUL */
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 1b90a38..2425b97 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -53,8 +53,8 @@
 module_param(timer_limit, int, 0444);
 MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
 
-typedef struct {
-	snd_timer_instance_t *timeri;
+struct snd_timer_user {
+	struct snd_timer_instance *timeri;
 	int tread;		/* enhanced read with timestamps and events */
 	unsigned long ticks;
 	unsigned long overrun;
@@ -62,8 +62,8 @@
 	int qtail;
 	int qused;
 	int queue_size;
-	snd_timer_read_t *queue;
-	snd_timer_tread_t *tqueue;
+	struct snd_timer_read *queue;
+	struct snd_timer_tread *tqueue;
 	spinlock_t qlock;
 	unsigned long last_resolution;
 	unsigned int filter;
@@ -71,7 +71,7 @@
 	wait_queue_head_t qchange_sleep;
 	struct fasync_struct *fasync;
 	struct semaphore tread_sem;
-} snd_timer_user_t;
+};
 
 /* list of timers */
 static LIST_HEAD(snd_timer_list);
@@ -84,21 +84,21 @@
 
 static DECLARE_MUTEX(register_mutex);
 
-static int snd_timer_free(snd_timer_t *timer);
-static int snd_timer_dev_free(snd_device_t *device);
-static int snd_timer_dev_register(snd_device_t *device);
-static int snd_timer_dev_unregister(snd_device_t *device);
+static int snd_timer_free(struct snd_timer *timer);
+static int snd_timer_dev_free(struct snd_device *device);
+static int snd_timer_dev_register(struct snd_device *device);
+static int snd_timer_dev_unregister(struct snd_device *device);
 
-static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left);
+static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left);
 
 /*
  * create a timer instance with the given owner string.
  * when timer is not NULL, increments the module counter
  */
-static snd_timer_instance_t *snd_timer_instance_new(char *owner,
-						    snd_timer_t *timer)
+static struct snd_timer_instance *snd_timer_instance_new(char *owner,
+							 struct snd_timer *timer)
 {
-	snd_timer_instance_t *timeri;
+	struct snd_timer_instance *timeri;
 	timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
 	if (timeri == NULL)
 		return NULL;
@@ -126,13 +126,13 @@
 /*
  * find a timer instance from the given timer id
  */
-static snd_timer_t *snd_timer_find(snd_timer_id_t *tid)
+static struct snd_timer *snd_timer_find(struct snd_timer_id *tid)
 {
-	snd_timer_t *timer = NULL;
+	struct snd_timer *timer = NULL;
 	struct list_head *p;
 
 	list_for_each(p, &snd_timer_list) {
-		timer = list_entry(p, snd_timer_t, device_list);
+		timer = list_entry(p, struct snd_timer, device_list);
 
 		if (timer->tmr_class != tid->dev_class)
 			continue;
@@ -152,7 +152,7 @@
 
 #ifdef CONFIG_KMOD
 
-static void snd_timer_request(snd_timer_id_t *tid)
+static void snd_timer_request(struct snd_timer_id *tid)
 {
 	if (! current->fs->root)
 		return;
@@ -179,17 +179,17 @@
  *
  * call this with register_mutex down.
  */
-static void snd_timer_check_slave(snd_timer_instance_t *slave)
+static void snd_timer_check_slave(struct snd_timer_instance *slave)
 {
-	snd_timer_t *timer;
-	snd_timer_instance_t *master;
+	struct snd_timer *timer;
+	struct snd_timer_instance *master;
 	struct list_head *p, *q;
 
 	/* FIXME: it's really dumb to look up all entries.. */
 	list_for_each(p, &snd_timer_list) {
-		timer = list_entry(p, snd_timer_t, device_list);
+		timer = list_entry(p, struct snd_timer, device_list);
 		list_for_each(q, &timer->open_list_head) {
-			master = list_entry(q, snd_timer_instance_t, open_list);
+			master = list_entry(q, struct snd_timer_instance, open_list);
 			if (slave->slave_class == master->slave_class &&
 			    slave->slave_id == master->slave_id) {
 				list_del(&slave->open_list);
@@ -211,14 +211,14 @@
  *
  * call this with register_mutex down.
  */
-static void snd_timer_check_master(snd_timer_instance_t *master)
+static void snd_timer_check_master(struct snd_timer_instance *master)
 {
-	snd_timer_instance_t *slave;
+	struct snd_timer_instance *slave;
 	struct list_head *p, *n;
 
 	/* check all pending slaves */
 	list_for_each_safe(p, n, &snd_timer_slave_list) {
-		slave = list_entry(p, snd_timer_instance_t, open_list);
+		slave = list_entry(p, struct snd_timer_instance, open_list);
 		if (slave->slave_class == master->slave_class &&
 		    slave->slave_id == master->slave_id) {
 			list_del(p);
@@ -238,12 +238,12 @@
  * open a timer instance
  * when opening a master, the slave id must be here given.
  */
-int snd_timer_open(snd_timer_instance_t **ti,
-		   char *owner, snd_timer_id_t *tid,
+int snd_timer_open(struct snd_timer_instance **ti,
+		   char *owner, struct snd_timer_id *tid,
 		   unsigned int slave_id)
 {
-	snd_timer_t *timer;
-	snd_timer_instance_t *timeri = NULL;
+	struct snd_timer *timer;
+	struct snd_timer_instance *timeri = NULL;
 
 	if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
 		/* open a slave instance */
@@ -285,7 +285,7 @@
 	}
 	if (!list_empty(&timer->open_list_head)) {
 		timeri = list_entry(timer->open_list_head.next,
-				    snd_timer_instance_t, open_list);
+				    struct snd_timer_instance, open_list);
 		if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
 			up(&register_mutex);
 			return -EBUSY;
@@ -307,17 +307,17 @@
 	return 0;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri,
-			   int keep_flag, enum sndrv_timer_event event);
+static int _snd_timer_stop(struct snd_timer_instance *timeri,
+			   int keep_flag, int event);
 
 /*
  * close a timer instance
  */
-int snd_timer_close(snd_timer_instance_t * timeri)
+int snd_timer_close(struct snd_timer_instance *timeri)
 {
-	snd_timer_t *timer = NULL;
+	struct snd_timer *timer = NULL;
 	struct list_head *p, *n;
-	snd_timer_instance_t *slave;
+	struct snd_timer_instance *slave;
 
 	snd_assert(timeri != NULL, return -ENXIO);
 
@@ -353,7 +353,7 @@
 			timer->hw.close(timer);
 		/* remove slave links */
 		list_for_each_safe(p, n, &timeri->slave_list_head) {
-			slave = list_entry(p, snd_timer_instance_t, open_list);
+			slave = list_entry(p, struct snd_timer_instance, open_list);
 			spin_lock_irq(&slave_active_lock);
 			_snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
 			list_del(p);
@@ -373,9 +373,9 @@
 	return 0;
 }
 
-unsigned long snd_timer_resolution(snd_timer_instance_t * timeri)
+unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
 {
-	snd_timer_t * timer;
+	struct snd_timer * timer;
 
 	if (timeri == NULL)
 		return 0;
@@ -387,13 +387,12 @@
 	return 0;
 }
 
-static void snd_timer_notify1(snd_timer_instance_t *ti,
-			      enum sndrv_timer_event event)
+static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
 {
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 	unsigned long flags;
 	unsigned long resolution = 0;
-	snd_timer_instance_t *ts;
+	struct snd_timer_instance *ts;
 	struct list_head *n;
 	struct timespec tstamp;
 
@@ -414,14 +413,14 @@
 		return;
 	spin_lock_irqsave(&timer->lock, flags);
 	list_for_each(n, &ti->slave_active_head) {
-		ts = list_entry(n, snd_timer_instance_t, active_list);
+		ts = list_entry(n, struct snd_timer_instance, active_list);
 		if (ts->ccallback)
 			ts->ccallback(ti, event + 100, &tstamp, resolution);
 	}
 	spin_unlock_irqrestore(&timer->lock, flags);
 }
 
-static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri,
+static int snd_timer_start1(struct snd_timer *timer, struct snd_timer_instance *timeri,
 			    unsigned long sticks)
 {
 	list_del(&timeri->active_list);
@@ -442,7 +441,7 @@
 	}
 }
 
-static int snd_timer_start_slave(snd_timer_instance_t *timeri)
+static int snd_timer_start_slave(struct snd_timer_instance *timeri)
 {
 	unsigned long flags;
 
@@ -458,9 +457,9 @@
 /*
  *  start the timer instance
  */
-int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks)
+int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks)
 {
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 	int result = -EINVAL;
 	unsigned long flags;
 
@@ -483,10 +482,10 @@
 	return result;
 }
 
-static int _snd_timer_stop(snd_timer_instance_t * timeri,
-			   int keep_flag, enum sndrv_timer_event event)
+static int _snd_timer_stop(struct snd_timer_instance * timeri,
+			   int keep_flag, int event)
 {
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 	unsigned long flags;
 
 	snd_assert(timeri != NULL, return -ENXIO);
@@ -532,9 +531,9 @@
  *
  * do not call this from the timer callback!
  */
-int snd_timer_stop(snd_timer_instance_t * timeri)
+int snd_timer_stop(struct snd_timer_instance *timeri)
 {
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 	unsigned long flags;
 	int err;
 
@@ -552,9 +551,9 @@
 /*
  * start again..  the tick is kept.
  */
-int snd_timer_continue(snd_timer_instance_t * timeri)
+int snd_timer_continue(struct snd_timer_instance *timeri)
 {
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 	int result = -EINVAL;
 	unsigned long flags;
 
@@ -578,7 +577,7 @@
 /*
  * pause.. remember the ticks left
  */
-int snd_timer_pause(snd_timer_instance_t * timeri)
+int snd_timer_pause(struct snd_timer_instance * timeri)
 {
 	return _snd_timer_stop(timeri, 0, SNDRV_TIMER_EVENT_PAUSE);
 }
@@ -589,14 +588,14 @@
  * start pending instances and check the scheduling ticks.
  * when the scheduling ticks is changed set CHANGE flag to reprogram the timer.
  */
-static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left)
+static void snd_timer_reschedule(struct snd_timer * timer, unsigned long ticks_left)
 {
-	snd_timer_instance_t *ti;
+	struct snd_timer_instance *ti;
 	unsigned long ticks = ~0UL;
 	struct list_head *p;
 
 	list_for_each(p, &timer->active_list_head) {
-		ti = list_entry(p, snd_timer_instance_t, active_list);
+		ti = list_entry(p, struct snd_timer_instance, active_list);
 		if (ti->flags & SNDRV_TIMER_IFLG_START) {
 			ti->flags &= ~SNDRV_TIMER_IFLG_START;
 			ti->flags |= SNDRV_TIMER_IFLG_RUNNING;
@@ -624,8 +623,8 @@
  */
 static void snd_timer_tasklet(unsigned long arg)
 {
-	snd_timer_t *timer = (snd_timer_t *) arg;
-	snd_timer_instance_t *ti;
+	struct snd_timer *timer = (struct snd_timer *) arg;
+	struct snd_timer_instance *ti;
 	struct list_head *p;
 	unsigned long resolution, ticks;
 
@@ -633,7 +632,7 @@
 	/* now process all callbacks */
 	while (!list_empty(&timer->sack_list_head)) {
 		p = timer->sack_list_head.next;		/* get first item */
-		ti = list_entry(p, snd_timer_instance_t, ack_list);
+		ti = list_entry(p, struct snd_timer_instance, ack_list);
 
 		/* remove from ack_list and make empty */
 		list_del_init(p);
@@ -658,17 +657,18 @@
  * ticks_left is usually equal to timer->sticks.
  *
  */
-void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
+void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
 {
-	snd_timer_instance_t *ti, *ts;
+	struct snd_timer_instance *ti, *ts;
 	unsigned long resolution, ticks;
 	struct list_head *p, *q, *n, *ack_list_head;
+	unsigned long flags;
 	int use_tasklet = 0;
 
 	if (timer == NULL)
 		return;
 
-	spin_lock(&timer->lock);
+	spin_lock_irqsave(&timer->lock, flags);
 
 	/* remember the current resolution */
 	if (timer->hw.c_resolution)
@@ -682,7 +682,7 @@
 	 * is called.
 	 */
 	list_for_each_safe(p, n, &timer->active_list_head) {
-		ti = list_entry(p, snd_timer_instance_t, active_list);
+		ti = list_entry(p, struct snd_timer_instance, active_list);
 		if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
 			continue;
 		ti->pticks += ticks_left;
@@ -708,7 +708,7 @@
 		if (list_empty(&ti->ack_list))
 			list_add_tail(&ti->ack_list, ack_list_head);
 		list_for_each(q, &ti->slave_active_head) {
-			ts = list_entry(q, snd_timer_instance_t, active_list);
+			ts = list_entry(q, struct snd_timer_instance, active_list);
 			ts->pticks = ti->pticks;
 			ts->resolution = resolution;
 			if (list_empty(&ts->ack_list))
@@ -735,7 +735,7 @@
 	/* now process all fast callbacks */
 	while (!list_empty(&timer->ack_list_head)) {
 		p = timer->ack_list_head.next;		/* get first item */
-		ti = list_entry(p, snd_timer_instance_t, ack_list);
+		ti = list_entry(p, struct snd_timer_instance, ack_list);
 
 		/* remove from ack_list and make empty */
 		list_del_init(p);
@@ -753,7 +753,7 @@
 
 	/* do we have any slow callbacks? */
 	use_tasklet = !list_empty(&timer->sack_list_head);
-	spin_unlock(&timer->lock);
+	spin_unlock_irqrestore(&timer->lock, flags);
 
 	if (use_tasklet)
 		tasklet_hi_schedule(&timer->task_queue);
@@ -763,12 +763,12 @@
 
  */
 
-int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid,
-		  snd_timer_t **rtimer)
+int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
+		  struct snd_timer **rtimer)
 {
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_timer_dev_free,
 		.dev_register = snd_timer_dev_register,
 		.dev_unregister = snd_timer_dev_unregister
@@ -778,8 +778,10 @@
 	snd_assert(rtimer != NULL, return -EINVAL);
 	*rtimer = NULL;
 	timer = kzalloc(sizeof(*timer), GFP_KERNEL);
-	if (timer == NULL)
+	if (timer == NULL) {
+		snd_printk(KERN_ERR "timer: cannot allocate\n");
 		return -ENOMEM;
+	}
 	timer->tmr_class = tid->dev_class;
 	timer->card = card;
 	timer->tmr_device = tid->device;
@@ -806,7 +808,7 @@
 	return 0;
 }
 
-static int snd_timer_free(snd_timer_t *timer)
+static int snd_timer_free(struct snd_timer *timer)
 {
 	snd_assert(timer != NULL, return -ENXIO);
 	if (timer->private_free)
@@ -815,16 +817,16 @@
 	return 0;
 }
 
-static int snd_timer_dev_free(snd_device_t *device)
+static int snd_timer_dev_free(struct snd_device *device)
 {
-	snd_timer_t *timer = device->device_data;
+	struct snd_timer *timer = device->device_data;
 	return snd_timer_free(timer);
 }
 
-static int snd_timer_dev_register(snd_device_t *dev)
+static int snd_timer_dev_register(struct snd_device *dev)
 {
-	snd_timer_t *timer = dev->device_data;
-	snd_timer_t *timer1;
+	struct snd_timer *timer = dev->device_data;
+	struct snd_timer *timer1;
 	struct list_head *p;
 
 	snd_assert(timer != NULL && timer->hw.start != NULL &&
@@ -835,7 +837,7 @@
 
 	down(&register_mutex);
 	list_for_each(p, &snd_timer_list) {
-		timer1 = list_entry(p, snd_timer_t, device_list);
+		timer1 = list_entry(p, struct snd_timer, device_list);
 		if (timer1->tmr_class > timer->tmr_class)
 			break;
 		if (timer1->tmr_class < timer->tmr_class)
@@ -863,10 +865,10 @@
 	return 0;
 }
 
-static int snd_timer_unregister(snd_timer_t *timer)
+static int snd_timer_unregister(struct snd_timer *timer)
 {
 	struct list_head *p, *n;
-	snd_timer_instance_t *ti;
+	struct snd_timer_instance *ti;
 
 	snd_assert(timer != NULL, return -ENXIO);
 	down(&register_mutex);
@@ -874,7 +876,7 @@
 		snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
 		list_for_each_safe(p, n, &timer->open_list_head) {
 			list_del_init(p);
-			ti = list_entry(p, snd_timer_instance_t, open_list);
+			ti = list_entry(p, struct snd_timer_instance, open_list);
 			ti->timer = NULL;
 		}
 	}
@@ -883,18 +885,17 @@
 	return snd_timer_free(timer);
 }
 
-static int snd_timer_dev_unregister(snd_device_t *device)
+static int snd_timer_dev_unregister(struct snd_device *device)
 {
-	snd_timer_t *timer = device->device_data;
+	struct snd_timer *timer = device->device_data;
 	return snd_timer_unregister(timer);
 }
 
-void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event,
-		      struct timespec *tstamp)
+void snd_timer_notify(struct snd_timer *timer, int event, struct timespec *tstamp)
 {
 	unsigned long flags;
 	unsigned long resolution = 0;
-	snd_timer_instance_t *ti, *ts;
+	struct snd_timer_instance *ti, *ts;
 	struct list_head *p, *n;
 
 	if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
@@ -911,11 +912,11 @@
 			resolution = timer->hw.resolution;
 	}
 	list_for_each(p, &timer->active_list_head) {
-		ti = list_entry(p, snd_timer_instance_t, active_list);
+		ti = list_entry(p, struct snd_timer_instance, active_list);
 		if (ti->ccallback)
 			ti->ccallback(ti, event, tstamp, resolution);
 		list_for_each(n, &ti->slave_active_head) {
-			ts = list_entry(n, snd_timer_instance_t, active_list);
+			ts = list_entry(n, struct snd_timer_instance, active_list);
 			if (ts->ccallback)
 				ts->ccallback(ts, event, tstamp, resolution);
 		}
@@ -926,9 +927,9 @@
 /*
  * exported functions for global timers
  */
-int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer)
+int snd_timer_global_new(char *id, int device, struct snd_timer **rtimer)
 {
-	snd_timer_id_t tid;
+	struct snd_timer_id tid;
 
 	tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
 	tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
@@ -938,21 +939,21 @@
 	return snd_timer_new(NULL, id, &tid, rtimer);
 }
 
-int snd_timer_global_free(snd_timer_t *timer)
+int snd_timer_global_free(struct snd_timer *timer)
 {
 	return snd_timer_free(timer);
 }
 
-int snd_timer_global_register(snd_timer_t *timer)
+int snd_timer_global_register(struct snd_timer *timer)
 {
-	snd_device_t dev;
+	struct snd_device dev;
 
 	memset(&dev, 0, sizeof(dev));
 	dev.device_data = timer;
 	return snd_timer_dev_register(&dev);
 }
 
-int snd_timer_global_unregister(snd_timer_t *timer)
+int snd_timer_global_unregister(struct snd_timer *timer)
 {
 	return snd_timer_unregister(timer);
 }
@@ -971,7 +972,7 @@
 
 static void snd_timer_s_function(unsigned long data)
 {
-	snd_timer_t *timer = (snd_timer_t *)data;
+	struct snd_timer *timer = (struct snd_timer *)data;
 	struct snd_timer_system_private *priv = timer->private_data;
 	unsigned long jiff = jiffies;
 	if (time_after(jiff, priv->last_expires))
@@ -979,7 +980,7 @@
 	snd_timer_interrupt(timer, (long)jiff - (long)priv->last_jiffies);
 }
 
-static int snd_timer_s_start(snd_timer_t * timer)
+static int snd_timer_s_start(struct snd_timer * timer)
 {
 	struct snd_timer_system_private *priv;
 	unsigned long njiff;
@@ -998,7 +999,7 @@
 	return 0;
 }
 
-static int snd_timer_s_stop(snd_timer_t * timer)
+static int snd_timer_s_stop(struct snd_timer * timer)
 {
 	struct snd_timer_system_private *priv;
 	unsigned long jiff;
@@ -1013,7 +1014,7 @@
 	return 0;
 }
 
-static struct _snd_timer_hardware snd_timer_system =
+static struct snd_timer_hardware snd_timer_system =
 {
 	.flags =	SNDRV_TIMER_HW_FIRST | SNDRV_TIMER_HW_TASKLET,
 	.resolution =	1000000000L / HZ,
@@ -1022,14 +1023,14 @@
 	.stop =		snd_timer_s_stop
 };
 
-static void snd_timer_free_system(snd_timer_t *timer)
+static void snd_timer_free_system(struct snd_timer *timer)
 {
 	kfree(timer->private_data);
 }
 
 static int snd_timer_register_system(void)
 {
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 	struct snd_timer_system_private *priv;
 	int err;
 
@@ -1051,21 +1052,22 @@
 	return snd_timer_global_register(timer);
 }
 
+#ifdef CONFIG_PROC_FS
 /*
  *  Info interface
  */
 
-static void snd_timer_proc_read(snd_info_entry_t *entry,
-				snd_info_buffer_t * buffer)
+static void snd_timer_proc_read(struct snd_info_entry *entry,
+				struct snd_info_buffer *buffer)
 {
 	unsigned long flags;
-	snd_timer_t *timer;
-	snd_timer_instance_t *ti;
+	struct snd_timer *timer;
+	struct snd_timer_instance *ti;
 	struct list_head *p, *q;
 
 	down(&register_mutex);
 	list_for_each(p, &snd_timer_list) {
-		timer = list_entry(p, snd_timer_t, device_list);
+		timer = list_entry(p, struct snd_timer, device_list);
 		switch (timer->tmr_class) {
 		case SNDRV_TIMER_CLASS_GLOBAL:
 			snd_iprintf(buffer, "G%i: ", timer->tmr_device);
@@ -1094,7 +1096,7 @@
 		snd_iprintf(buffer, "\n");
 		spin_lock_irqsave(&timer->lock, flags);
 		list_for_each(q, &timer->open_list_head) {
-			ti = list_entry(q, snd_timer_instance_t, open_list);
+			ti = list_entry(q, struct snd_timer_instance, open_list);
 			snd_iprintf(buffer, "  Client %s : %s\n",
 				    ti->owner ? ti->owner : "unknown",
 				    ti->flags & (SNDRV_TIMER_IFLG_START |
@@ -1106,16 +1108,43 @@
 	up(&register_mutex);
 }
 
+static struct snd_info_entry *snd_timer_proc_entry = NULL;
+
+static void __init snd_timer_proc_init(void)
+{
+	struct snd_info_entry *entry;
+
+	entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
+	if (entry != NULL) {
+		entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
+		entry->c.text.read = snd_timer_proc_read;
+		if (snd_info_register(entry) < 0) {
+			snd_info_free_entry(entry);
+			entry = NULL;
+		}
+	}
+	snd_timer_proc_entry = entry;
+}
+
+static void __exit snd_timer_proc_done(void)
+{
+	snd_info_unregister(snd_timer_proc_entry);
+}
+#else /* !CONFIG_PROC_FS */
+#define snd_timer_proc_init()
+#define snd_timer_proc_done()
+#endif
+
 /*
  *  USER SPACE interface
  */
 
-static void snd_timer_user_interrupt(snd_timer_instance_t *timeri,
+static void snd_timer_user_interrupt(struct snd_timer_instance *timeri,
 				     unsigned long resolution,
 				     unsigned long ticks)
 {
-	snd_timer_user_t *tu = timeri->callback_data;
-	snd_timer_read_t *r;
+	struct snd_timer_user *tu = timeri->callback_data;
+	struct snd_timer_read *r;
 	int prev;
 
 	spin_lock(&tu->qlock);
@@ -1142,8 +1171,8 @@
 	wake_up(&tu->qchange_sleep);
 }
 
-static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu,
-					    snd_timer_tread_t *tread)
+static void snd_timer_user_append_to_tqueue(struct snd_timer_user *tu,
+					    struct snd_timer_tread *tread)
 {
 	if (tu->qused >= tu->queue_size) {
 		tu->overrun++;
@@ -1154,13 +1183,13 @@
 	}
 }
 
-static void snd_timer_user_ccallback(snd_timer_instance_t *timeri,
-				     enum sndrv_timer_event event,
+static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
+				     int event,
 				     struct timespec *tstamp,
 				     unsigned long resolution)
 {
-	snd_timer_user_t *tu = timeri->callback_data;
-	snd_timer_tread_t r1;
+	struct snd_timer_user *tu = timeri->callback_data;
+	struct snd_timer_tread r1;
 
 	if (event >= SNDRV_TIMER_EVENT_START &&
 	    event <= SNDRV_TIMER_EVENT_PAUSE)
@@ -1177,12 +1206,12 @@
 	wake_up(&tu->qchange_sleep);
 }
 
-static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri,
+static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
 				      unsigned long resolution,
 				      unsigned long ticks)
 {
-	snd_timer_user_t *tu = timeri->callback_data;
-	snd_timer_tread_t *r, r1;
+	struct snd_timer_user *tu = timeri->callback_data;
+	struct snd_timer_tread *r, r1;
 	struct timespec tstamp;
 	int prev, append = 0;
 
@@ -1233,7 +1262,7 @@
 
 static int snd_timer_user_open(struct inode *inode, struct file *file)
 {
-	snd_timer_user_t *tu;
+	struct snd_timer_user *tu;
 
 	tu = kzalloc(sizeof(*tu), GFP_KERNEL);
 	if (tu == NULL)
@@ -1243,7 +1272,7 @@
 	init_MUTEX(&tu->tread_sem);
 	tu->ticks = 1;
 	tu->queue_size = 128;
-	tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
+	tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
 			    GFP_KERNEL);
 	if (tu->queue == NULL) {
 		kfree(tu);
@@ -1255,7 +1284,7 @@
 
 static int snd_timer_user_release(struct inode *inode, struct file *file)
 {
-	snd_timer_user_t *tu;
+	struct snd_timer_user *tu;
 
 	if (file->private_data) {
 		tu = file->private_data;
@@ -1270,7 +1299,7 @@
 	return 0;
 }
 
-static void snd_timer_user_zero_id(snd_timer_id_t *id)
+static void snd_timer_user_zero_id(struct snd_timer_id *id)
 {
 	id->dev_class = SNDRV_TIMER_CLASS_NONE;
 	id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
@@ -1279,7 +1308,7 @@
 	id->subdevice = -1;
 }
 
-static void snd_timer_user_copy_id(snd_timer_id_t *id, snd_timer_t *timer)
+static void snd_timer_user_copy_id(struct snd_timer_id *id, struct snd_timer *timer)
 {
 	id->dev_class = timer->tmr_class;
 	id->dev_sclass = SNDRV_TIMER_SCLASS_NONE;
@@ -1288,10 +1317,10 @@
 	id->subdevice = timer->tmr_subdevice;
 }
 
-static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
+static int snd_timer_user_next_device(struct snd_timer_id __user *_tid)
 {
-	snd_timer_id_t id;
-	snd_timer_t *timer;
+	struct snd_timer_id id;
+	struct snd_timer *timer;
 	struct list_head *p;
 
 	if (copy_from_user(&id, _tid, sizeof(id)))
@@ -1302,7 +1331,7 @@
 			snd_timer_user_zero_id(&id);
 		else {
 			timer = list_entry(snd_timer_list.next,
-					   snd_timer_t, device_list);
+					   struct snd_timer, device_list);
 			snd_timer_user_copy_id(&id, timer);
 		}
 	} else {
@@ -1310,7 +1339,7 @@
 		case SNDRV_TIMER_CLASS_GLOBAL:
 			id.device = id.device < 0 ? 0 : id.device + 1;
 			list_for_each(p, &snd_timer_list) {
-				timer = list_entry(p, snd_timer_t, device_list);
+				timer = list_entry(p, struct snd_timer, device_list);
 				if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
 					snd_timer_user_copy_id(&id, timer);
 					break;
@@ -1343,7 +1372,7 @@
 				}
 			}
 			list_for_each(p, &snd_timer_list) {
-				timer = list_entry(p, snd_timer_t, device_list);
+				timer = list_entry(p, struct snd_timer, device_list);
 				if (timer->tmr_class > id.dev_class) {
 					snd_timer_user_copy_id(&id, timer);
 					break;
@@ -1385,11 +1414,11 @@
 }
 
 static int snd_timer_user_ginfo(struct file *file,
-				snd_timer_ginfo_t __user *_ginfo)
+				struct snd_timer_ginfo __user *_ginfo)
 {
-	snd_timer_ginfo_t *ginfo;
-	snd_timer_id_t tid;
-	snd_timer_t *t;
+	struct snd_timer_ginfo *ginfo;
+	struct snd_timer_id tid;
+	struct snd_timer *t;
 	struct list_head *p;
 	int err = 0;
 
@@ -1430,10 +1459,10 @@
 }
 
 static int snd_timer_user_gparams(struct file *file,
-				  snd_timer_gparams_t __user *_gparams)
+				  struct snd_timer_gparams __user *_gparams)
 {
-	snd_timer_gparams_t gparams;
-	snd_timer_t *t;
+	struct snd_timer_gparams gparams;
+	struct snd_timer *t;
 	int err;
 
 	if (copy_from_user(&gparams, _gparams, sizeof(gparams)))
@@ -1459,11 +1488,11 @@
 }
 
 static int snd_timer_user_gstatus(struct file *file,
-				  snd_timer_gstatus_t __user *_gstatus)
+				  struct snd_timer_gstatus __user *_gstatus)
 {
-	snd_timer_gstatus_t gstatus;
-	snd_timer_id_t tid;
-	snd_timer_t *t;
+	struct snd_timer_gstatus gstatus;
+	struct snd_timer_id tid;
+	struct snd_timer *t;
 	int err = 0;
 
 	if (copy_from_user(&gstatus, _gstatus, sizeof(gstatus)))
@@ -1495,10 +1524,10 @@
 }
 
 static int snd_timer_user_tselect(struct file *file,
-				  snd_timer_select_t __user *_tselect)
+				  struct snd_timer_select __user *_tselect)
 {
-	snd_timer_user_t *tu;
-	snd_timer_select_t tselect;
+	struct snd_timer_user *tu;
+	struct snd_timer_select tselect;
 	char str[32];
 	int err = 0;
 
@@ -1524,12 +1553,12 @@
 	kfree(tu->tqueue);
 	tu->tqueue = NULL;
 	if (tu->tread) {
-		tu->tqueue = kmalloc(tu->queue_size * sizeof(snd_timer_tread_t),
+		tu->tqueue = kmalloc(tu->queue_size * sizeof(struct snd_timer_tread),
 				     GFP_KERNEL);
 		if (tu->tqueue == NULL)
 			err = -ENOMEM;
 	} else {
-		tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
+		tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
 				    GFP_KERNEL);
 		if (tu->queue == NULL)
 			err = -ENOMEM;
@@ -1552,11 +1581,11 @@
 }
 
 static int snd_timer_user_info(struct file *file,
-			       snd_timer_info_t __user *_info)
+			       struct snd_timer_info __user *_info)
 {
-	snd_timer_user_t *tu;
-	snd_timer_info_t *info;
-	snd_timer_t *t;
+	struct snd_timer_user *tu;
+	struct snd_timer_info *info;
+	struct snd_timer *t;
 	int err = 0;
 
 	tu = file->private_data;
@@ -1580,13 +1609,13 @@
 }
 
 static int snd_timer_user_params(struct file *file,
-				 snd_timer_params_t __user *_params)
+				 struct snd_timer_params __user *_params)
 {
-	snd_timer_user_t *tu;
-	snd_timer_params_t params;
-	snd_timer_t *t;
-	snd_timer_read_t *tr;
-	snd_timer_tread_t *ttr;
+	struct snd_timer_user *tu;
+	struct snd_timer_params params;
+	struct snd_timer *t;
+	struct snd_timer_read *tr;
+	struct snd_timer_tread *ttr;
 	int err;
 
 	tu = file->private_data;
@@ -1656,14 +1685,14 @@
 	tu->qhead = tu->qtail = tu->qused = 0;
 	if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
 		if (tu->tread) {
-			snd_timer_tread_t tread;
+			struct snd_timer_tread tread;
 			tread.event = SNDRV_TIMER_EVENT_EARLY;
 			tread.tstamp.tv_sec = 0;
 			tread.tstamp.tv_nsec = 0;
 			tread.val = 0;
 			snd_timer_user_append_to_tqueue(tu, &tread);
 		} else {
-			snd_timer_read_t *r = &tu->queue[0];
+			struct snd_timer_read *r = &tu->queue[0];
 			r->resolution = 0;
 			r->ticks = 0;
 			tu->qused++;
@@ -1680,10 +1709,10 @@
 }
 
 static int snd_timer_user_status(struct file *file,
-				 snd_timer_status_t __user *_status)
+				 struct snd_timer_status __user *_status)
 {
-	snd_timer_user_t *tu;
-	snd_timer_status_t status;
+	struct snd_timer_user *tu;
+	struct snd_timer_status status;
 
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
@@ -1703,7 +1732,7 @@
 static int snd_timer_user_start(struct file *file)
 {
 	int err;
-	snd_timer_user_t *tu;
+	struct snd_timer_user *tu;
 
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
@@ -1716,7 +1745,7 @@
 static int snd_timer_user_stop(struct file *file)
 {
 	int err;
-	snd_timer_user_t *tu;
+	struct snd_timer_user *tu;
 
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
@@ -1726,7 +1755,7 @@
 static int snd_timer_user_continue(struct file *file)
 {
 	int err;
-	snd_timer_user_t *tu;
+	struct snd_timer_user *tu;
 
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
@@ -1737,7 +1766,7 @@
 static int snd_timer_user_pause(struct file *file)
 {
 	int err;
-	snd_timer_user_t *tu;
+	struct snd_timer_user *tu;
 
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
@@ -1754,7 +1783,7 @@
 static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
 				 unsigned long arg)
 {
-	snd_timer_user_t *tu;
+	struct snd_timer_user *tu;
 	void __user *argp = (void __user *)arg;
 	int __user *p = argp;
 
@@ -1813,7 +1842,7 @@
 
 static int snd_timer_user_fasync(int fd, struct file * file, int on)
 {
-	snd_timer_user_t *tu;
+	struct snd_timer_user *tu;
 	int err;
 
 	tu = file->private_data;
@@ -1826,12 +1855,12 @@
 static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
 				   size_t count, loff_t *offset)
 {
-	snd_timer_user_t *tu;
+	struct snd_timer_user *tu;
 	long result = 0, unit;
 	int err = 0;
 
 	tu = file->private_data;
-	unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t);
+	unit = tu->tread ? sizeof(struct snd_timer_tread) : sizeof(struct snd_timer_read);
 	spin_lock_irq(&tu->qlock);
 	while ((long)count - result >= unit) {
 		while (!tu->qused) {
@@ -1864,13 +1893,13 @@
 
 		if (tu->tread) {
 			if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
-					 sizeof(snd_timer_tread_t))) {
+					 sizeof(struct snd_timer_tread))) {
 				err = -EFAULT;
 				goto _error;
 			}
 		} else {
 			if (copy_to_user(buffer, &tu->queue[tu->qhead++],
-					 sizeof(snd_timer_read_t))) {
+					 sizeof(struct snd_timer_read))) {
 				err = -EFAULT;
 				goto _error;
 			}
@@ -1892,7 +1921,7 @@
 static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
 {
         unsigned int mask;
-        snd_timer_user_t *tu;
+        struct snd_timer_user *tu;
 
         tu = file->private_data;
 
@@ -1923,44 +1952,27 @@
 	.fasync = 	snd_timer_user_fasync,
 };
 
-static snd_minor_t snd_timer_reg =
-{
-	.comment =	"timer",
-	.f_ops =	&snd_timer_f_ops,
-};
-
 /*
  *  ENTRY functions
  */
 
-static snd_info_entry_t *snd_timer_proc_entry = NULL;
-
 static int __init alsa_timer_init(void)
 {
 	int err;
-	snd_info_entry_t *entry;
 
 #ifdef SNDRV_OSS_INFO_DEV_TIMERS
 	snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
 			      "system timer");
 #endif
-	entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
-	if (entry != NULL) {
-		entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
-		entry->c.text.read = snd_timer_proc_read;
-		if (snd_info_register(entry) < 0) {
-			snd_info_free_entry(entry);
-			entry = NULL;
-		}
-	}
-	snd_timer_proc_entry = entry;
+
 	if ((err = snd_timer_register_system()) < 0)
 		snd_printk(KERN_ERR "unable to register system timer (%i)\n",
 			   err);
-	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER,
-					NULL, 0, &snd_timer_reg, "timer"))<0)
+	if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,
+				       &snd_timer_f_ops, NULL, "timer")) < 0)
 		snd_printk(KERN_ERR "unable to register timer device (%i)\n",
 			   err);
+	snd_timer_proc_init();
 	return 0;
 }
 
@@ -1971,13 +1983,10 @@
 	snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0);
 	/* unregister the system timer */
 	list_for_each_safe(p, n, &snd_timer_list) {
-		snd_timer_t *timer = list_entry(p, snd_timer_t, device_list);
+		struct snd_timer *timer = list_entry(p, struct snd_timer, device_list);
 		snd_timer_unregister(timer);
 	}
-	if (snd_timer_proc_entry) {
-		snd_info_unregister(snd_timer_proc_entry);
-		snd_timer_proc_entry = NULL;
-	}
+	snd_timer_proc_done();
 #ifdef SNDRV_OSS_INFO_DEV_TIMERS
 	snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1);
 #endif
diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
index 3de552d..5512f53 100644
--- a/sound/core/timer_compat.c
+++ b/sound/core/timer_compat.c
@@ -22,7 +22,7 @@
 
 #include <linux/compat.h>
 
-struct sndrv_timer_info32 {
+struct snd_timer_info32 {
 	u32 flags;
 	s32 card;
 	unsigned char id[64];
@@ -33,11 +33,11 @@
 };
 
 static int snd_timer_user_info_compat(struct file *file,
-				      struct sndrv_timer_info32 __user *_info)
+				      struct snd_timer_info32 __user *_info)
 {
-	snd_timer_user_t *tu;
-	struct sndrv_timer_info32 info;
-	snd_timer_t *t;
+	struct snd_timer_user *tu;
+	struct snd_timer_info32 info;
+	struct snd_timer *t;
 
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
@@ -55,7 +55,7 @@
 	return 0;
 }
 
-struct sndrv_timer_status32 {
+struct snd_timer_status32 {
 	struct compat_timespec tstamp;
 	u32 resolution;
 	u32 lost;
@@ -65,10 +65,10 @@
 };
 
 static int snd_timer_user_status_compat(struct file *file,
-					struct sndrv_timer_status32 __user *_status)
+					struct snd_timer_status32 __user *_status)
 {
-	snd_timer_user_t *tu;
-	snd_timer_status_t status;
+	struct snd_timer_user *tu;
+	struct snd_timer_status status;
 	
 	tu = file->private_data;
 	snd_assert(tu->timeri != NULL, return -ENXIO);
@@ -89,8 +89,8 @@
  */
 
 enum {
-	SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct sndrv_timer_info32),
-	SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct sndrv_timer_status32),
+	SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32),
+	SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32),
 };
 
 static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index efcb4eb..395c4ef 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -6,7 +6,6 @@
 
 config SND_MPU401_UART
         tristate
-	select SND_TIMER
         select SND_RAWMIDI
 
 config SND_OPL3_LIB
@@ -24,12 +23,19 @@
 	select SND_HWDEP
 	select SND_PCM
 
+config SND_AC97_CODEC
+	tristate
+	select SND_PCM
+	select SND_AC97_BUS
+
+config SND_AC97_BUS
+	tristate
+
 
 config SND_DUMMY
 	tristate "Dummy (/dev/null) soundcard"
 	depends on SND
 	select SND_PCM
-	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include the dummy driver.  This driver does
 	  nothing, but emulates various mixer controls and PCM devices.
@@ -45,7 +51,6 @@
 	depends on SND_SEQUENCER
 	select SND_TIMER
 	select SND_RAWMIDI
-	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include the virtual MIDI driver.  This driver
 	  allows to connect applications using raw MIDI devices to
@@ -59,9 +64,7 @@
 config SND_MTPAV
 	tristate "MOTU MidiTimePiece AV multiport MIDI"
 	depends on SND
-	select SND_TIMER
 	select SND_RAWMIDI
-	select SND_GENERIC_DRIVER
 	help
 	  To use a MOTU MidiTimePiece AV multiport MIDI adapter
 	  connected to the parallel port, say Y here and make sure that
@@ -73,9 +76,7 @@
 config SND_SERIAL_U16550
 	tristate "UART16550 serial MIDI driver"
 	depends on SND
-	select SND_TIMER
 	select SND_RAWMIDI
-	select SND_GENERIC_DRIVER
 	help
 	  To include support for MIDI serial port interfaces, say Y here
 	  and read <file:Documentation/sound/alsa/serial-u16550.txt>.
@@ -92,7 +93,6 @@
 	tristate "Generic MPU-401 UART driver"
 	depends on SND
 	select SND_MPU401_UART
-	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for MIDI ports compatible with
 	  the Roland MPU-401 interface in UART mode.
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 64ef7f6..14e1a67 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -20,6 +20,8 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/jiffies.h>
 #include <linux/slab.h>
 #include <linux/time.h>
@@ -42,7 +44,7 @@
 
 #if 0 /* emu10k1 emulation */
 #define MAX_BUFFER_SIZE		(128 * 1024)
-static int emu10k1_playback_constraints(snd_pcm_runtime_t *runtime)
+static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
 {
 	int err;
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
@@ -90,11 +92,27 @@
 #define USE_RATE_MAX		48000
 #endif
 
+#if 0 /* CA0106 */
+#define USE_FORMATS		SNDRV_PCM_FMTBIT_S16_LE
+#define USE_CHANNELS_MIN	2
+#define USE_CHANNELS_MAX	2
+#define USE_RATE		(SNDRV_PCM_RATE_48000|SNDRV_PCM_RATE_96000|SNDRV_PCM_RATE_192000) 
+#define USE_RATE_MIN		48000 
+#define USE_RATE_MAX		192000
+#define MAX_BUFFER_SIZE		((65536-64)*8)
+#define MAX_PERIOD_SIZE		(65536-64)
+#define USE_PERIODS_MIN		2
+#define USE_PERIODS_MAX		8
+#endif
+
 
 /* defaults */
 #ifndef MAX_BUFFER_SIZE
 #define MAX_BUFFER_SIZE		(64*1024)
 #endif
+#ifndef MAX_PERIOD_SIZE
+#define MAX_PERIOD_SIZE		MAX_BUFFER_SIZE
+#endif
 #ifndef USE_FORMATS
 #define USE_FORMATS 		(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE)
 #endif
@@ -142,6 +160,8 @@
 //module_param_array(midi_devs, int, NULL, 0444);
 //MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 #define MIXER_ADDR_MASTER	0
 #define MIXER_ADDR_LINE		1
 #define MIXER_ADDR_MIC		2
@@ -149,15 +169,16 @@
 #define MIXER_ADDR_CD		4
 #define MIXER_ADDR_LAST		4
 
-typedef struct snd_card_dummy {
-	snd_card_t *card;
+struct snd_dummy {
+	struct snd_card *card;
+	struct snd_pcm *pcm;
 	spinlock_t mixer_lock;
 	int mixer_volume[MIXER_ADDR_LAST+1][2];
 	int capture_source[MIXER_ADDR_LAST+1][2];
-} snd_card_dummy_t;
+};
 
-typedef struct snd_card_dummy_pcm {
-	snd_card_dummy_t *dummy;
+struct snd_dummy_pcm {
+	struct snd_dummy *dummy;
 	spinlock_t lock;
 	struct timer_list timer;
 	unsigned int pcm_size;
@@ -166,59 +187,49 @@
 	unsigned int pcm_jiffie;	/* bytes per one jiffie */
 	unsigned int pcm_irq_pos;	/* IRQ position */
 	unsigned int pcm_buf_pos;	/* position in buffer */
-	snd_pcm_substream_t *substream;
-} snd_card_dummy_pcm_t;
-
-static snd_card_t *snd_dummy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+	struct snd_pcm_substream *substream;
+};
 
 
-static void snd_card_dummy_pcm_timer_start(snd_pcm_substream_t * substream)
+static inline void snd_card_dummy_pcm_timer_start(struct snd_dummy_pcm *dpcm)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_dummy_pcm_t *dpcm = runtime->private_data;
-
 	dpcm->timer.expires = 1 + jiffies;
 	add_timer(&dpcm->timer);
 }
 
-static void snd_card_dummy_pcm_timer_stop(snd_pcm_substream_t * substream)
+static inline void snd_card_dummy_pcm_timer_stop(struct snd_dummy_pcm *dpcm)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_dummy_pcm_t *dpcm = runtime->private_data;
-
 	del_timer(&dpcm->timer);
 }
 
-static int snd_card_dummy_playback_trigger(snd_pcm_substream_t * substream,
-					   int cmd)
+static int snd_card_dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	if (cmd == SNDRV_PCM_TRIGGER_START) {
-		snd_card_dummy_pcm_timer_start(substream);
-	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-		snd_card_dummy_pcm_timer_stop(substream);
-	} else {
-		return -EINVAL;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dummy_pcm *dpcm = runtime->private_data;
+	int err = 0;
+
+	spin_lock(&dpcm->lock);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+		snd_card_dummy_pcm_timer_start(dpcm);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+		snd_card_dummy_pcm_timer_stop(dpcm);
+		break;
+	default:
+		err = -EINVAL;
+		break;
 	}
+	spin_unlock(&dpcm->lock);
 	return 0;
 }
 
-static int snd_card_dummy_capture_trigger(snd_pcm_substream_t * substream,
-					  int cmd)
+static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	if (cmd == SNDRV_PCM_TRIGGER_START) {
-		snd_card_dummy_pcm_timer_start(substream);
-	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
-		snd_card_dummy_pcm_timer_stop(substream);
-	} else {
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int snd_card_dummy_pcm_prepare(snd_pcm_substream_t * substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_dummy_pcm_t *dpcm = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dummy_pcm *dpcm = runtime->private_data;
 	unsigned int bps;
 
 	bps = runtime->rate * runtime->channels;
@@ -235,53 +246,37 @@
 	return 0;
 }
 
-static int snd_card_dummy_playback_prepare(snd_pcm_substream_t * substream)
-{
-	return snd_card_dummy_pcm_prepare(substream);
-}
-
-static int snd_card_dummy_capture_prepare(snd_pcm_substream_t * substream)
-{
-	return snd_card_dummy_pcm_prepare(substream);
-}
-
 static void snd_card_dummy_pcm_timer_function(unsigned long data)
 {
-	snd_card_dummy_pcm_t *dpcm = (snd_card_dummy_pcm_t *)data;
+	struct snd_dummy_pcm *dpcm = (struct snd_dummy_pcm *)data;
+	unsigned long flags;
 	
+	spin_lock_irqsave(&dpcm->lock, flags);
 	dpcm->timer.expires = 1 + jiffies;
 	add_timer(&dpcm->timer);
-	spin_lock_irq(&dpcm->lock);
 	dpcm->pcm_irq_pos += dpcm->pcm_jiffie;
 	dpcm->pcm_buf_pos += dpcm->pcm_jiffie;
 	dpcm->pcm_buf_pos %= dpcm->pcm_size;
 	if (dpcm->pcm_irq_pos >= dpcm->pcm_count) {
 		dpcm->pcm_irq_pos %= dpcm->pcm_count;
+		spin_unlock_irqrestore(&dpcm->lock, flags);
 		snd_pcm_period_elapsed(dpcm->substream);
-	}
-	spin_unlock_irq(&dpcm->lock);	
+	} else
+		spin_unlock_irqrestore(&dpcm->lock, flags);
 }
 
-static snd_pcm_uframes_t snd_card_dummy_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_dummy_pcm_t *dpcm = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dummy_pcm *dpcm = runtime->private_data;
 
 	return bytes_to_frames(runtime, dpcm->pcm_buf_pos);
 }
 
-static snd_pcm_uframes_t snd_card_dummy_capture_pointer(snd_pcm_substream_t * substream)
-{
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_dummy_pcm_t *dpcm = runtime->private_data;
-
-	return bytes_to_frames(runtime, dpcm->pcm_buf_pos);
-}
-
-static snd_pcm_hardware_t snd_card_dummy_playback =
+static struct snd_pcm_hardware snd_card_dummy_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		USE_FORMATS,
 	.rates =		USE_RATE,
 	.rate_min =		USE_RATE_MIN,
@@ -296,10 +291,10 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_card_dummy_capture =
+static struct snd_pcm_hardware snd_card_dummy_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		USE_FORMATS,
 	.rates =		USE_RATE,
 	.rate_min =		USE_RATE_MIN,
@@ -308,43 +303,51 @@
 	.channels_max =		USE_CHANNELS_MAX,
 	.buffer_bytes_max =	MAX_BUFFER_SIZE,
 	.period_bytes_min =	64,
-	.period_bytes_max =	MAX_BUFFER_SIZE,
+	.period_bytes_max =	MAX_PERIOD_SIZE,
 	.periods_min =		USE_PERIODS_MIN,
 	.periods_max =		USE_PERIODS_MAX,
 	.fifo_size =		0,
 };
 
-static void snd_card_dummy_runtime_free(snd_pcm_runtime_t *runtime)
+static void snd_card_dummy_runtime_free(struct snd_pcm_runtime *runtime)
 {
-	snd_card_dummy_pcm_t *dpcm = runtime->private_data;
-	kfree(dpcm);
+	kfree(runtime->private_data);
 }
 
-static int snd_card_dummy_hw_params(snd_pcm_substream_t * substream,
-				    snd_pcm_hw_params_t * hw_params)
+static int snd_card_dummy_hw_params(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_card_dummy_hw_free(snd_pcm_substream_t * substream)
+static int snd_card_dummy_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream)
+static struct snd_dummy_pcm *new_pcm_stream(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_dummy_pcm_t *dpcm;
-	int err;
+	struct snd_dummy_pcm *dpcm;
 
 	dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
-	if (dpcm == NULL)
-		return -ENOMEM;
+	if (! dpcm)
+		return dpcm;
 	init_timer(&dpcm->timer);
 	dpcm->timer.data = (unsigned long) dpcm;
 	dpcm->timer.function = snd_card_dummy_pcm_timer_function;
 	spin_lock_init(&dpcm->lock);
 	dpcm->substream = substream;
+	return dpcm;
+}
+
+static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dummy_pcm *dpcm;
+	int err;
+
+	if ((dpcm = new_pcm_stream(substream)) == NULL)
+		return -ENOMEM;
 	runtime->private_data = dpcm;
 	runtime->private_free = snd_card_dummy_runtime_free;
 	runtime->hw = snd_card_dummy_playback;
@@ -362,20 +365,14 @@
 	return 0;
 }
 
-static int snd_card_dummy_capture_open(snd_pcm_substream_t * substream)
+static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_card_dummy_pcm_t *dpcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dummy_pcm *dpcm;
 	int err;
 
-	dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
-	if (dpcm == NULL)
+	if ((dpcm = new_pcm_stream(substream)) == NULL)
 		return -ENOMEM;
-	init_timer(&dpcm->timer);
-	dpcm->timer.data = (unsigned long) dpcm;
-	dpcm->timer.function = snd_card_dummy_pcm_timer_function;
-	spin_lock_init(&dpcm->lock);
-	dpcm->substream = substream;
 	runtime->private_data = dpcm;
 	runtime->private_free = snd_card_dummy_runtime_free;
 	runtime->hw = snd_card_dummy_capture;
@@ -393,45 +390,47 @@
 	return 0;
 }
 
-static int snd_card_dummy_playback_close(snd_pcm_substream_t * substream)
+static int snd_card_dummy_playback_close(struct snd_pcm_substream *substream)
 {
 	return 0;
 }
 
-static int snd_card_dummy_capture_close(snd_pcm_substream_t * substream)
+static int snd_card_dummy_capture_close(struct snd_pcm_substream *substream)
 {
 	return 0;
 }
 
-static snd_pcm_ops_t snd_card_dummy_playback_ops = {
+static struct snd_pcm_ops snd_card_dummy_playback_ops = {
 	.open =			snd_card_dummy_playback_open,
 	.close =		snd_card_dummy_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
 	.hw_params =		snd_card_dummy_hw_params,
 	.hw_free =		snd_card_dummy_hw_free,
-	.prepare =		snd_card_dummy_playback_prepare,
-	.trigger =		snd_card_dummy_playback_trigger,
-	.pointer =		snd_card_dummy_playback_pointer,
+	.prepare =		snd_card_dummy_pcm_prepare,
+	.trigger =		snd_card_dummy_pcm_trigger,
+	.pointer =		snd_card_dummy_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_card_dummy_capture_ops = {
+static struct snd_pcm_ops snd_card_dummy_capture_ops = {
 	.open =			snd_card_dummy_capture_open,
 	.close =		snd_card_dummy_capture_close,
 	.ioctl =		snd_pcm_lib_ioctl,
 	.hw_params =		snd_card_dummy_hw_params,
 	.hw_free =		snd_card_dummy_hw_free,
-	.prepare =		snd_card_dummy_capture_prepare,
-	.trigger =		snd_card_dummy_capture_trigger,
-	.pointer =		snd_card_dummy_capture_pointer,
+	.prepare =		snd_card_dummy_pcm_prepare,
+	.trigger =		snd_card_dummy_pcm_trigger,
+	.pointer =		snd_card_dummy_pcm_pointer,
 };
 
-static int __init snd_card_dummy_pcm(snd_card_dummy_t *dummy, int device, int substreams)
+static int __init snd_card_dummy_pcm(struct snd_dummy *dummy, int device, int substreams)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
-	if ((err = snd_pcm_new(dummy->card, "Dummy PCM", device, substreams, substreams, &pcm)) < 0)
+	if ((err = snd_pcm_new(dummy->card, "Dummy PCM", device,
+			       substreams, substreams, &pcm)) < 0)
 		return err;
+	dummy->pcm = pcm;
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_dummy_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_dummy_capture_ops);
 	pcm->private_data = dummy;
@@ -449,7 +448,8 @@
   .get = snd_dummy_volume_get, .put = snd_dummy_volume_put, \
   .private_value = addr }
 
-static int snd_dummy_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_dummy_volume_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -458,23 +458,23 @@
 	return 0;
 }
  
-static int snd_dummy_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_dummy_volume_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
+	struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
 	int addr = kcontrol->private_value;
 
-	spin_lock_irqsave(&dummy->mixer_lock, flags);
+	spin_lock_irq(&dummy->mixer_lock);
 	ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0];
 	ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1];
-	spin_unlock_irqrestore(&dummy->mixer_lock, flags);
+	spin_unlock_irq(&dummy->mixer_lock);
 	return 0;
 }
 
-static int snd_dummy_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_dummy_volume_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
+	struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
 	int change, addr = kcontrol->private_value;
 	int left, right;
 
@@ -488,12 +488,12 @@
 		right = -50;
 	if (right > 100)
 		right = 100;
-	spin_lock_irqsave(&dummy->mixer_lock, flags);
+	spin_lock_irq(&dummy->mixer_lock);
 	change = dummy->mixer_volume[addr][0] != left ||
 	         dummy->mixer_volume[addr][1] != right;
 	dummy->mixer_volume[addr][0] = left;
 	dummy->mixer_volume[addr][1] = right;
-	spin_unlock_irqrestore(&dummy->mixer_lock, flags);
+	spin_unlock_irq(&dummy->mixer_lock);
 	return change;
 }
 
@@ -503,7 +503,8 @@
   .get = snd_dummy_capsrc_get, .put = snd_dummy_capsrc_put, \
   .private_value = addr }
 
-static int snd_dummy_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_dummy_capsrc_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -512,38 +513,37 @@
 	return 0;
 }
  
-static int snd_dummy_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_dummy_capsrc_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
+	struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
 	int addr = kcontrol->private_value;
 
-	spin_lock_irqsave(&dummy->mixer_lock, flags);
+	spin_lock_irq(&dummy->mixer_lock);
 	ucontrol->value.integer.value[0] = dummy->capture_source[addr][0];
 	ucontrol->value.integer.value[1] = dummy->capture_source[addr][1];
-	spin_unlock_irqrestore(&dummy->mixer_lock, flags);
+	spin_unlock_irq(&dummy->mixer_lock);
 	return 0;
 }
 
-static int snd_dummy_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
-	unsigned long flags;
+	struct snd_dummy *dummy = snd_kcontrol_chip(kcontrol);
 	int change, addr = kcontrol->private_value;
 	int left, right;
 
 	left = ucontrol->value.integer.value[0] & 1;
 	right = ucontrol->value.integer.value[1] & 1;
-	spin_lock_irqsave(&dummy->mixer_lock, flags);
+	spin_lock_irq(&dummy->mixer_lock);
 	change = dummy->capture_source[addr][0] != left &&
 	         dummy->capture_source[addr][1] != right;
 	dummy->capture_source[addr][0] = left;
 	dummy->capture_source[addr][1] = right;
-	spin_unlock_irqrestore(&dummy->mixer_lock, flags);
+	spin_unlock_irq(&dummy->mixer_lock);
 	return change;
 }
 
-static snd_kcontrol_new_t snd_dummy_controls[] = {
+static struct snd_kcontrol_new snd_dummy_controls[] = {
 DUMMY_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER),
 DUMMY_CAPSRC("Master Capture Switch", 0, MIXER_ADDR_MASTER),
 DUMMY_VOLUME("Synth Volume", 0, MIXER_ADDR_SYNTH),
@@ -556,9 +556,9 @@
 DUMMY_CAPSRC("CD Capture Switch", 0, MIXER_ADDR_MASTER)
 };
 
-static int __init snd_card_dummy_new_mixer(snd_card_dummy_t * dummy)
+static int __init snd_card_dummy_new_mixer(struct snd_dummy *dummy)
 {
-	snd_card_t *card = dummy->card;
+	struct snd_card *card = dummy->card;
 	unsigned int idx;
 	int err;
 
@@ -573,19 +573,18 @@
 	return 0;
 }
 
-static int __init snd_card_dummy_probe(int dev)
+static int __init snd_dummy_probe(struct platform_device *devptr)
 {
-	snd_card_t *card;
-	struct snd_card_dummy *dummy;
+	struct snd_card *card;
+	struct snd_dummy *dummy;
 	int idx, err;
+	int dev = devptr->id;
 
-	if (!enable[dev])
-		return -ENODEV;
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
-			    sizeof(struct snd_card_dummy));
+			    sizeof(struct snd_dummy));
 	if (card == NULL)
 		return -ENOMEM;
-	dummy = (struct snd_card_dummy *)card->private_data;
+	dummy = card->private_data;
 	dummy->card = card;
 	for (idx = 0; idx < MAX_PCM_DEVICES && idx < pcm_devs[dev]; idx++) {
 		if (pcm_substreams[dev] < 1)
@@ -601,11 +600,10 @@
 	strcpy(card->shortname, "Dummy");
 	sprintf(card->longname, "Dummy %i", dev + 1);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto __nodev;
+	snd_card_set_dev(card, &devptr->dev);
 
 	if ((err = snd_card_register(card)) == 0) {
-		snd_dummy_cards[dev] = card;
+		platform_set_drvdata(devptr, card);
 		return 0;
 	}
       __nodev:
@@ -613,34 +611,92 @@
 	return err;
 }
 
+static int snd_dummy_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct snd_card *card = platform_get_drvdata(pdev);
+	struct snd_dummy *dummy = card->private_data;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(dummy->pcm);
+	return 0;
+}
+	
+static int snd_dummy_resume(struct platform_device *pdev)
+{
+	struct snd_card *card = platform_get_drvdata(pdev);
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
+#define SND_DUMMY_DRIVER	"snd_dummy"
+
+static struct platform_driver snd_dummy_driver = {
+	.probe		= snd_dummy_probe,
+	.remove		= snd_dummy_remove,
+#ifdef CONFIG_PM
+	.suspend	= snd_dummy_suspend,
+	.resume		= snd_dummy_resume,
+#endif
+	.driver		= {
+		.name	= SND_DUMMY_DRIVER
+	},
+};
+
+static void __init_or_module snd_dummy_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_dummy_driver);
+}
+
 static int __init alsa_card_dummy_init(void)
 {
-	int dev, cards;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) {
-		if (snd_card_dummy_probe(dev) < 0) {
-#ifdef MODULE
-			printk(KERN_ERR "Dummy soundcard #%i not found or device busy\n", dev + 1);
-#endif
-			break;
+	if ((err = platform_driver_register(&snd_dummy_driver)) < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(SND_DUMMY_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
 #ifdef MODULE
 		printk(KERN_ERR "Dummy soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_dummy_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_dummy_exit(void)
 {
-	int idx;
-
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_dummy_cards[idx]);
+	snd_dummy_unregister_all();
 }
 
 module_init(alsa_card_dummy_init)
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 54e2ff9..915589a 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -23,6 +23,8 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/pnp.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/mpu401.h>
@@ -56,12 +58,12 @@
 module_param_array(irq, int, NULL, 0444);
 MODULE_PARM_DESC(irq, "IRQ # for MPU-401 device.");
 
-static snd_card_t *snd_mpu401_legacy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct platform_device *platform_devices[SNDRV_CARDS];
 static int pnp_registered = 0;
 
-static int snd_mpu401_create(int dev, snd_card_t **rcard)
+static int snd_mpu401_create(int dev, struct snd_card **rcard)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	int err;
 
 	*rcard = NULL;
@@ -85,12 +87,6 @@
 		goto _err;
 	}
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
-
-	if ((err = snd_card_register(card)) < 0)
-		goto _err;
-
 	*rcard = card;
 	return 0;
 
@@ -99,8 +95,12 @@
 	return err;
 }
 
-static int __devinit snd_mpu401_probe(int dev)
+static int __devinit snd_mpu401_probe(struct platform_device *devptr)
 {
+	int dev = devptr->id;
+	int err;
+	struct snd_card *card;
+
 	if (port[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR "specify port\n");
 		return -EINVAL;
@@ -109,9 +109,36 @@
 		snd_printk(KERN_ERR "specify or disable IRQ\n");
 		return -EINVAL;
 	}
-	return snd_mpu401_create(dev, &snd_mpu401_legacy_cards[dev]);
+	err = snd_mpu401_create(dev, &card);
+	if (err < 0)
+		return err;
+	snd_card_set_dev(card, &devptr->dev);
+	if ((err = snd_card_register(card)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	platform_set_drvdata(devptr, card);
+	return 0;
 }
 
+static int __devexit snd_mpu401_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#define SND_MPU401_DRIVER	"snd_mpu401"
+
+static struct platform_driver snd_mpu401_driver = {
+	.probe		= snd_mpu401_probe,
+	.remove		= __devexit_p(snd_mpu401_remove),
+	.driver		= {
+		.name	= SND_MPU401_DRIVER
+	},
+};
+
+
 #ifdef CONFIG_PNP
 
 #define IO_EXTENT 2
@@ -152,7 +179,7 @@
 					  const struct pnp_device_id *id)
 {
 	static int dev;
-	snd_card_t *card;
+	struct snd_card *card;
 	int err;
 
 	for ( ; dev < SNDRV_CARDS; ++dev) {
@@ -164,6 +191,10 @@
 		err = snd_mpu401_create(dev, &card);
 		if (err < 0)
 			return err;
+		if ((err = snd_card_register(card)) < 0) {
+			snd_card_free(card);
+			return err;
+		}
 		snd_card_set_dev(card, &pnp_dev->dev);
 		pnp_set_drvdata(pnp_dev, card);
 		++dev;
@@ -174,7 +205,7 @@
 
 static void __devexit snd_mpu401_pnp_remove(struct pnp_dev *dev)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_drvdata(dev);
+	struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev);
 
 	snd_card_disconnect(card);
 	snd_card_free_in_thread(card);
@@ -190,20 +221,39 @@
 static struct pnp_driver snd_mpu401_pnp_driver;
 #endif
 
+static void __init_or_module snd_mpu401_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_driver(&snd_mpu401_pnp_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_mpu401_driver);
+}
+
 static int __init alsa_card_mpu401_init(void)
 {
-	int dev, devices = 0;
-	int err;
+	int i, err, devices;
 
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev])
-			continue;
+	if ((err = platform_driver_register(&snd_mpu401_driver)) < 0)
+		return err;
+
+	devices = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
 #ifdef CONFIG_PNP
-		if (pnp[dev])
+		if (pnp[i])
 			continue;
 #endif
-		if (snd_mpu401_probe(dev) >= 0)
-			devices++;
+		device = platform_device_register_simple(SND_MPU401_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		platform_devices[i] = device;
+		devices++;
 	}
 	if ((err = pnp_register_driver(&snd_mpu401_pnp_driver)) >= 0) {
 		pnp_registered = 1;
@@ -214,21 +264,19 @@
 #ifdef MODULE
 		printk(KERN_ERR "MPU-401 device not found or device busy\n");
 #endif
-		if (pnp_registered)
-			pnp_unregister_driver(&snd_mpu401_pnp_driver);
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_mpu401_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_mpu401_exit(void)
 {
-	int idx;
-
-	if (pnp_registered)
-		pnp_unregister_driver(&snd_mpu401_pnp_driver);
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_mpu401_legacy_cards[idx]);
+	snd_mpu401_unregister_all();
 }
 
 module_init(alsa_card_mpu401_init)
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c
index bdeb2c0..8687ae3 100644
--- a/sound/drivers/mpu401/mpu401_uart.c
+++ b/sound/drivers/mpu401/mpu401_uart.c
@@ -43,8 +43,8 @@
 MODULE_DESCRIPTION("Routines for control of MPU-401 in UART mode");
 MODULE_LICENSE("GPL");
 
-static void snd_mpu401_uart_input_read(mpu401_t * mpu);
-static void snd_mpu401_uart_output_write(mpu401_t * mpu);
+static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu);
+static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu);
 
 /*
 
@@ -58,28 +58,28 @@
 #define MPU401_ACK		0xfe
 
 /* Build in lowlevel io */
-static void mpu401_write_port(mpu401_t *mpu, unsigned char data, unsigned long addr)
+static void mpu401_write_port(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr)
 {
 	outb(data, addr);
 }
 
-static unsigned char mpu401_read_port(mpu401_t *mpu, unsigned long addr)
+static unsigned char mpu401_read_port(struct snd_mpu401 *mpu, unsigned long addr)
 {
 	return inb(addr);
 }
 
-static void mpu401_write_mmio(mpu401_t *mpu, unsigned char data, unsigned long addr)
+static void mpu401_write_mmio(struct snd_mpu401 *mpu, unsigned char data, unsigned long addr)
 {
 	writeb(data, (void __iomem *)addr);
 }
 
-static unsigned char mpu401_read_mmio(mpu401_t *mpu, unsigned long addr)
+static unsigned char mpu401_read_mmio(struct snd_mpu401 *mpu, unsigned long addr)
 {
 	return readb((void __iomem *)addr);
 }
 /*  */
 
-static void snd_mpu401_uart_clear_rx(mpu401_t *mpu)
+static void snd_mpu401_uart_clear_rx(struct snd_mpu401 *mpu)
 {
 	int timeout = 100000;
 	for (; timeout > 0 && snd_mpu401_input_avail(mpu); timeout--)
@@ -90,7 +90,7 @@
 #endif
 }
 
-static void _snd_mpu401_uart_interrupt(mpu401_t *mpu)
+static void _snd_mpu401_uart_interrupt(struct snd_mpu401 *mpu)
 {
 	spin_lock(&mpu->input_lock);
 	if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
@@ -118,7 +118,7 @@
  */
 irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	mpu401_t *mpu = dev_id;
+	struct snd_mpu401 *mpu = dev_id;
 	
 	if (mpu == NULL)
 		return IRQ_NONE;
@@ -132,13 +132,14 @@
  */
 static void snd_mpu401_uart_timer(unsigned long data)
 {
-	mpu401_t *mpu = (mpu401_t *)data;
+	struct snd_mpu401 *mpu = (struct snd_mpu401 *)data;
+	unsigned long flags;
 
-	spin_lock(&mpu->timer_lock);
+	spin_lock_irqsave(&mpu->timer_lock, flags);
 	/*mpu->mode |= MPU401_MODE_TIMER;*/
 	mpu->timer.expires = 1 + jiffies;
 	add_timer(&mpu->timer);
-	spin_unlock(&mpu->timer_lock);
+	spin_unlock_irqrestore(&mpu->timer_lock, flags);
 	if (mpu->rmidi)
 		_snd_mpu401_uart_interrupt(mpu);
 }
@@ -146,7 +147,7 @@
 /*
  * initialize the timer callback if not programmed yet
  */
-static void snd_mpu401_uart_add_timer (mpu401_t *mpu, int input)
+static void snd_mpu401_uart_add_timer (struct snd_mpu401 *mpu, int input)
 {
 	unsigned long flags;
 
@@ -165,7 +166,7 @@
 /*
  * remove the timer callback if still active
  */
-static void snd_mpu401_uart_remove_timer (mpu401_t *mpu, int input)
+static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
 {
 	unsigned long flags;
 
@@ -182,7 +183,7 @@
 
  */
 
-static void snd_mpu401_uart_cmd(mpu401_t * mpu, unsigned char cmd, int ack)
+static void snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int ack)
 {
 	unsigned long flags;
 	int timeout, ok;
@@ -225,9 +226,9 @@
 /*
  * input/output open/close - protected by open_mutex in rawmidi.c
  */
-static int snd_mpu401_uart_input_open(snd_rawmidi_substream_t * substream)
+static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
 {
-	mpu401_t *mpu;
+	struct snd_mpu401 *mpu;
 	int err;
 
 	mpu = substream->rmidi->private_data;
@@ -242,9 +243,9 @@
 	return 0;
 }
 
-static int snd_mpu401_uart_output_open(snd_rawmidi_substream_t * substream)
+static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
 {
-	mpu401_t *mpu;
+	struct snd_mpu401 *mpu;
 	int err;
 
 	mpu = substream->rmidi->private_data;
@@ -259,9 +260,9 @@
 	return 0;
 }
 
-static int snd_mpu401_uart_input_close(snd_rawmidi_substream_t * substream)
+static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream)
 {
-	mpu401_t *mpu;
+	struct snd_mpu401 *mpu;
 
 	mpu = substream->rmidi->private_data;
 	clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
@@ -273,9 +274,9 @@
 	return 0;
 }
 
-static int snd_mpu401_uart_output_close(snd_rawmidi_substream_t * substream)
+static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream)
 {
-	mpu401_t *mpu;
+	struct snd_mpu401 *mpu;
 
 	mpu = substream->rmidi->private_data;
 	clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
@@ -290,10 +291,10 @@
 /*
  * trigger input callback
  */
-static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	mpu401_t *mpu;
+	struct snd_mpu401 *mpu;
 	int max = 64;
 
 	mpu = substream->rmidi->private_data;
@@ -321,7 +322,7 @@
  * transfer input pending data
  * call with input_lock spinlock held
  */
-static void snd_mpu401_uart_input_read(mpu401_t * mpu)
+static void snd_mpu401_uart_input_read(struct snd_mpu401 * mpu)
 {
 	int max = 128;
 	unsigned char byte;
@@ -349,7 +350,7 @@
  * write output pending bytes
  * call with output_lock spinlock held
  */
-static void snd_mpu401_uart_output_write(mpu401_t * mpu)
+static void snd_mpu401_uart_output_write(struct snd_mpu401 * mpu)
 {
 	unsigned char byte;
 	int max = 256, timeout;
@@ -375,10 +376,10 @@
 /*
  * output trigger callback
  */
-static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_mpu401_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	mpu401_t *mpu;
+	struct snd_mpu401 *mpu;
 
 	mpu = substream->rmidi->private_data;
 	if (up) {
@@ -404,23 +405,23 @@
 
  */
 
-static snd_rawmidi_ops_t snd_mpu401_uart_output =
+static struct snd_rawmidi_ops snd_mpu401_uart_output =
 {
 	.open =		snd_mpu401_uart_output_open,
 	.close =	snd_mpu401_uart_output_close,
 	.trigger =	snd_mpu401_uart_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_mpu401_uart_input =
+static struct snd_rawmidi_ops snd_mpu401_uart_input =
 {
 	.open =		snd_mpu401_uart_input_open,
 	.close =	snd_mpu401_uart_input_close,
 	.trigger =	snd_mpu401_uart_input_trigger,
 };
 
-static void snd_mpu401_uart_free(snd_rawmidi_t *rmidi)
+static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi)
 {
-	mpu401_t *mpu = rmidi->private_data;
+	struct snd_mpu401 *mpu = rmidi->private_data;
 	if (mpu->irq_flags && mpu->irq >= 0)
 		free_irq(mpu->irq, (void *) mpu);
 	release_and_free_resource(mpu->res);
@@ -442,18 +443,18 @@
  *
  * Note that the rawmidi instance is returned on the rrawmidi argument,
  * not the mpu401 instance itself.  To access to the mpu401 instance,
- * cast from rawmidi->private_data (with mpu401_t magic-cast).
+ * cast from rawmidi->private_data (with struct snd_mpu401 magic-cast).
  *
  * Returns zero if successful, or a negative error code.
  */
-int snd_mpu401_uart_new(snd_card_t * card, int device,
+int snd_mpu401_uart_new(struct snd_card *card, int device,
 			unsigned short hardware,
 			unsigned long port, int integrated,
 			int irq, int irq_flags,
-			snd_rawmidi_t ** rrawmidi)
+			struct snd_rawmidi ** rrawmidi)
 {
-	mpu401_t *mpu;
-	snd_rawmidi_t *rmidi;
+	struct snd_mpu401 *mpu;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	if (rrawmidi)
@@ -462,6 +463,7 @@
 		return err;
 	mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
 	if (mpu == NULL) {
+		snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n");
 		snd_device_free(card, rmidi);
 		return -ENOMEM;
 	}
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index e9d52c6..b7a0b42 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -53,6 +53,8 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/moduleparam.h>
@@ -93,6 +95,8 @@
 module_param(hwports, int, 0444);
 MODULE_PARM_DESC(hwports, "Hardware ports # for MotuMTPAV MIDI.");
 
+static struct platform_device *device;
+
 /*
  *      defines
  */
@@ -125,17 +129,17 @@
 /*
  */
 
-typedef struct mtpav_port {
+struct mtpav_port {
 	u8 number;
 	u8 hwport;
 	u8 mode;
 	u8 running_status;
-	snd_rawmidi_substream_t *input;
-	snd_rawmidi_substream_t *output;
-} mtpav_port_t;
+	struct snd_rawmidi_substream *input;
+	struct snd_rawmidi_substream *output;
+};
 
-typedef struct mtpav {
-	snd_card_t *card;
+struct mtpav {
+	struct snd_card *card;
 	unsigned long port;
 	struct resource *res_port;
 	int irq;			/* interrupt (for inputs) */
@@ -143,24 +147,18 @@
 	int share_irq;			/* number of accesses to input interrupts */
 	int istimer;			/* number of accesses to timer interrupts */
 	struct timer_list timer;	/* timer interrupts for outputs */
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int num_ports;		/* number of hw ports (1-8) */
-	mtpav_port_t ports[NUMPORTS];	/* all ports including computer, adat and bc */
+	struct mtpav_port ports[NUMPORTS];	/* all ports including computer, adat and bc */
 
 	u32 inmidiport;		/* selected input midi port */
 	u32 inmidistate;	/* during midi command 0xf5 */
 
 	u32 outmidihwport;	/* selected output midi hw port */
-} mtpav_t;
+};
 
 
 /*
- * global instance
- * hey, we handle at most only one card..
- */
-static mtpav_t *mtp_card;
-
-/*
  * possible hardware ports (selected by 0xf5 port message)
  *      0x00		all ports
  *      0x01 .. 0x08    this MTP's ports 1..8
@@ -183,7 +181,7 @@
 #define MTPAV_PIDX_BROADCAST	2
 
 
-static int translate_subdevice_to_hwport(mtpav_t *chip, int subdev)
+static int translate_subdevice_to_hwport(struct mtpav *chip, int subdev)
 {
 	if (subdev < 0)
 		return 0x01; /* invalid - use port 0 as default */
@@ -198,7 +196,7 @@
 	return 0; /* all ports */
 }
 
-static int translate_hwport_to_subdevice(mtpav_t *chip, int hwport)
+static int translate_hwport_to_subdevice(struct mtpav *chip, int hwport)
 {
 	int p;
 	if (hwport <= 0x00) /* all ports */
@@ -223,7 +221,7 @@
 /*
  */
 
-static u8 snd_mtpav_getreg(mtpav_t *chip, u16 reg)
+static u8 snd_mtpav_getreg(struct mtpav *chip, u16 reg)
 {
 	u8 rval = 0;
 
@@ -241,19 +239,16 @@
 /*
  */
 
-static void snd_mtpav_mputreg(mtpav_t *chip, u16 reg, u8 val)
+static inline void snd_mtpav_mputreg(struct mtpav *chip, u16 reg, u8 val)
 {
-	if (reg == DREG) {
-		outb(val, chip->port + DREG);
-	} else if (reg == CREG) {
-		outb(val, chip->port + CREG);
-	}
+	if (reg == DREG || reg == CREG)
+		outb(val, chip->port + reg);
 }
 
 /*
  */
 
-static void snd_mtpav_wait_rfdhi(mtpav_t *chip)
+static void snd_mtpav_wait_rfdhi(struct mtpav *chip)
 {
 	int counts = 10000;
 	u8 sbyte;
@@ -265,7 +260,7 @@
 	}
 }
 
-static void snd_mtpav_send_byte(mtpav_t *chip, u8 byte)
+static void snd_mtpav_send_byte(struct mtpav *chip, u8 byte)
 {
 	u8 tcbyt;
 	u8 clrwrite;
@@ -291,8 +286,9 @@
  */
 
 /* call this with spin lock held */
-static void snd_mtpav_output_port_write(mtpav_port_t *port,
-					snd_rawmidi_substream_t *substream)
+static void snd_mtpav_output_port_write(struct mtpav *mtp_card,
+					struct mtpav_port *portp,
+					struct snd_rawmidi_substream *substream)
 {
 	u8 outbyte;
 
@@ -303,34 +299,35 @@
 
 	// send port change command if necessary
 
-	if (port->hwport != mtp_card->outmidihwport) {
-		mtp_card->outmidihwport = port->hwport;
+	if (portp->hwport != mtp_card->outmidihwport) {
+		mtp_card->outmidihwport = portp->hwport;
 
 		snd_mtpav_send_byte(mtp_card, 0xf5);
-		snd_mtpav_send_byte(mtp_card, port->hwport);
-		//snd_printk("new outport: 0x%x\n", (unsigned int) port->hwport);
+		snd_mtpav_send_byte(mtp_card, portp->hwport);
+		//snd_printk("new outport: 0x%x\n", (unsigned int) portp->hwport);
 
-		if (!(outbyte & 0x80) && port->running_status)
-			snd_mtpav_send_byte(mtp_card, port->running_status);
+		if (!(outbyte & 0x80) && portp->running_status)
+			snd_mtpav_send_byte(mtp_card, portp->running_status);
 	}
 
 	// send data
 
 	do {
 		if (outbyte & 0x80)
-			port->running_status = outbyte;
+			portp->running_status = outbyte;
 		
 		snd_mtpav_send_byte(mtp_card, outbyte);
 	} while (snd_rawmidi_transmit(substream, &outbyte, 1) == 1);
 }
 
-static void snd_mtpav_output_write(snd_rawmidi_substream_t * substream)
+static void snd_mtpav_output_write(struct snd_rawmidi_substream *substream)
 {
-	mtpav_port_t *port = &mtp_card->ports[substream->number];
+	struct mtpav *mtp_card = substream->rmidi->private_data;
+	struct mtpav_port *portp = &mtp_card->ports[substream->number];
 	unsigned long flags;
 
 	spin_lock_irqsave(&mtp_card->spinlock, flags);
-	snd_mtpav_output_port_write(port, substream);
+	snd_mtpav_output_port_write(mtp_card, portp, substream);
 	spin_unlock_irqrestore(&mtp_card->spinlock, flags);
 }
 
@@ -339,7 +336,7 @@
  *      mtpav control
  */
 
-static void snd_mtpav_portscan(mtpav_t *chip)	// put mtp into smart routing mode
+static void snd_mtpav_portscan(struct mtpav *chip)	// put mtp into smart routing mode
 {
 	u8 p;
 
@@ -353,12 +350,12 @@
 /*
  */
 
-static int snd_mtpav_input_open(snd_rawmidi_substream_t * substream)
+static int snd_mtpav_input_open(struct snd_rawmidi_substream *substream)
 {
+	struct mtpav *mtp_card = substream->rmidi->private_data;
+	struct mtpav_port *portp = &mtp_card->ports[substream->number];
 	unsigned long flags;
-	mtpav_port_t *portp = &mtp_card->ports[substream->number];
 
-	//printk("mtpav port: %d opened\n", (int) substream->number);
 	spin_lock_irqsave(&mtp_card->spinlock, flags);
 	portp->mode |= MTPAV_MODE_INPUT_OPENED;
 	portp->input = substream;
@@ -371,20 +368,17 @@
 /*
  */
 
-static int snd_mtpav_input_close(snd_rawmidi_substream_t *substream)
+static int snd_mtpav_input_close(struct snd_rawmidi_substream *substream)
 {
+	struct mtpav *mtp_card = substream->rmidi->private_data;
+	struct mtpav_port *portp = &mtp_card->ports[substream->number];
 	unsigned long flags;
-	mtpav_port_t *portp = &mtp_card->ports[substream->number];
-
-	//printk("mtpav port: %d closed\n", (int) portp);
 
 	spin_lock_irqsave(&mtp_card->spinlock, flags);
-
-	portp->mode &= (~MTPAV_MODE_INPUT_OPENED);
+	portp->mode &= ~MTPAV_MODE_INPUT_OPENED;
 	portp->input = NULL;
 	if (--mtp_card->share_irq == 0)
 		snd_mtpav_mputreg(mtp_card, CREG, 0);	// disable pport interrupts
-
 	spin_unlock_irqrestore(&mtp_card->spinlock, flags);
 	return 0;
 }
@@ -392,10 +386,11 @@
 /*
  */
 
-static void snd_mtpav_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_mtpav_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
+	struct mtpav *mtp_card = substream->rmidi->private_data;
+	struct mtpav_port *portp = &mtp_card->ports[substream->number];
 	unsigned long flags;
-	mtpav_port_t *portp = &mtp_card->ports[substream->number];
 
 	spin_lock_irqsave(&mtp_card->spinlock, flags);
 	if (up)
@@ -414,7 +409,7 @@
 static void snd_mtpav_output_timer(unsigned long data)
 {
 	unsigned long flags;
-	mtpav_t *chip = (mtpav_t *)data;
+	struct mtpav *chip = (struct mtpav *)data;
 	int p;
 
 	spin_lock_irqsave(&chip->spinlock, flags);
@@ -423,25 +418,22 @@
 	add_timer(&chip->timer);
 	/* process each port */
 	for (p = 0; p <= chip->num_ports * 2 + MTPAV_PIDX_BROADCAST; p++) {
-		mtpav_port_t *portp = &mtp_card->ports[p];
+		struct mtpav_port *portp = &chip->ports[p];
 		if ((portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED) && portp->output)
-			snd_mtpav_output_port_write(portp, portp->output);
+			snd_mtpav_output_port_write(chip, portp, portp->output);
 	}
 	spin_unlock_irqrestore(&chip->spinlock, flags);
 }
 
 /* spinlock held! */
-static void snd_mtpav_add_output_timer(mtpav_t *chip)
+static void snd_mtpav_add_output_timer(struct mtpav *chip)
 {
-	init_timer(&chip->timer);
-	chip->timer.function = snd_mtpav_output_timer;
-	chip->timer.data = (unsigned long) mtp_card;
 	chip->timer.expires = 1 + jiffies;
 	add_timer(&chip->timer);
 }
 
 /* spinlock held! */
-static void snd_mtpav_remove_output_timer(mtpav_t *chip)
+static void snd_mtpav_remove_output_timer(struct mtpav *chip)
 {
 	del_timer(&chip->timer);
 }
@@ -449,10 +441,11 @@
 /*
  */
 
-static int snd_mtpav_output_open(snd_rawmidi_substream_t * substream)
+static int snd_mtpav_output_open(struct snd_rawmidi_substream *substream)
 {
+	struct mtpav *mtp_card = substream->rmidi->private_data;
+	struct mtpav_port *portp = &mtp_card->ports[substream->number];
 	unsigned long flags;
-	mtpav_port_t *portp = &mtp_card->ports[substream->number];
 
 	spin_lock_irqsave(&mtp_card->spinlock, flags);
 	portp->mode |= MTPAV_MODE_OUTPUT_OPENED;
@@ -464,13 +457,14 @@
 /*
  */
 
-static int snd_mtpav_output_close(snd_rawmidi_substream_t * substream)
+static int snd_mtpav_output_close(struct snd_rawmidi_substream *substream)
 {
+	struct mtpav *mtp_card = substream->rmidi->private_data;
+	struct mtpav_port *portp = &mtp_card->ports[substream->number];
 	unsigned long flags;
-	mtpav_port_t *portp = &mtp_card->ports[substream->number];
 
 	spin_lock_irqsave(&mtp_card->spinlock, flags);
-	portp->mode &= (~MTPAV_MODE_OUTPUT_OPENED);
+	portp->mode &= ~MTPAV_MODE_OUTPUT_OPENED;
 	portp->output = NULL;
 	spin_unlock_irqrestore(&mtp_card->spinlock, flags);
 	return 0;
@@ -479,14 +473,15 @@
 /*
  */
 
-static void snd_mtpav_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_mtpav_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
+	struct mtpav *mtp_card = substream->rmidi->private_data;
+	struct mtpav_port *portp = &mtp_card->ports[substream->number];
 	unsigned long flags;
-	mtpav_port_t *portp = &mtp_card->ports[substream->number];
 
 	spin_lock_irqsave(&mtp_card->spinlock, flags);
 	if (up) {
-		if (! (portp->mode  & MTPAV_MODE_OUTPUT_TRIGGERED)) {
+		if (! (portp->mode & MTPAV_MODE_OUTPUT_TRIGGERED)) {
 			if (mtp_card->istimer++ == 0)
 				snd_mtpav_add_output_timer(mtp_card);
 			portp->mode |= MTPAV_MODE_OUTPUT_TRIGGERED;
@@ -506,23 +501,20 @@
  * midi interrupt for inputs
  */
 
-static void snd_mtpav_inmidi_process(mtpav_t *mcrd, u8 inbyte)
+static void snd_mtpav_inmidi_process(struct mtpav *mcrd, u8 inbyte)
 {
-	mtpav_port_t *portp;
+	struct mtpav_port *portp;
 
 	if ((int)mcrd->inmidiport > mcrd->num_ports * 2 + MTPAV_PIDX_BROADCAST)
 		return;
 
 	portp = &mcrd->ports[mcrd->inmidiport];
-	if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED) {
+	if (portp->mode & MTPAV_MODE_INPUT_TRIGGERED)
 		snd_rawmidi_receive(portp->input, &inbyte, 1);
-	}
 }
 
-static void snd_mtpav_inmidi_h(mtpav_t * mcrd, u8 inbyte)
+static void snd_mtpav_inmidi_h(struct mtpav *mcrd, u8 inbyte)
 {
-	snd_assert(mcrd, return);
-
 	if (inbyte >= 0xf8) {
 		/* real-time midi code */
 		snd_mtpav_inmidi_process(mcrd, inbyte);
@@ -540,7 +532,7 @@
 	}
 }
 
-static void snd_mtpav_read_bytes(mtpav_t * mcrd)
+static void snd_mtpav_read_bytes(struct mtpav *mcrd)
 {
 	u8 clrread, setread;
 	u8 mtp_read_byte;
@@ -580,9 +572,8 @@
 
 static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id, struct pt_regs *regs)
 {
-	mtpav_t *mcard = dev_id;
+	struct mtpav *mcard = dev_id;
 
-	//printk("irqh()\n");
 	spin_lock(&mcard->spinlock);
 	snd_mtpav_read_bytes(mcard);
 	spin_unlock(&mcard->spinlock);
@@ -592,14 +583,14 @@
 /*
  * get ISA resources
  */
-static int snd_mtpav_get_ISA(mtpav_t * mcard)
+static int __init snd_mtpav_get_ISA(struct mtpav * mcard)
 {
 	if ((mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI")) == NULL) {
 		snd_printk("MTVAP port 0x%lx is busy\n", port);
 		return -EBUSY;
 	}
 	mcard->port = port;
-	if (request_irq(irq, snd_mtpav_irqh, SA_INTERRUPT, "MOTU MTPAV", (void *)mcard)) {
+	if (request_irq(irq, snd_mtpav_irqh, SA_INTERRUPT, "MOTU MTPAV", mcard)) {
 		snd_printk("MTVAP IRQ %d busy\n", irq);
 		return -EBUSY;
 	}
@@ -611,13 +602,13 @@
 /*
  */
 
-static snd_rawmidi_ops_t snd_mtpav_output = {
+static struct snd_rawmidi_ops snd_mtpav_output = {
 	.open =		snd_mtpav_output_open,
 	.close =	snd_mtpav_output_close,
 	.trigger =	snd_mtpav_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_mtpav_input = {
+static struct snd_rawmidi_ops snd_mtpav_input = {
 	.open =		snd_mtpav_input_open,
 	.close =	snd_mtpav_input_close,
 	.trigger =	snd_mtpav_input_trigger,
@@ -628,7 +619,8 @@
  * get RAWMIDI resources
  */
 
-static void snd_mtpav_set_name(mtpav_t *chip, snd_rawmidi_substream_t *substream)
+static void __init snd_mtpav_set_name(struct mtpav *chip,
+				      struct snd_rawmidi_substream *substream)
 {
 	if (substream->number >= 0 && substream->number < chip->num_ports)
 		sprintf(substream->name, "MTP direct %d", (substream->number % chip->num_ports) + 1);
@@ -642,21 +634,18 @@
 		strcpy(substream->name, "MTP broadcast");
 }
 
-static int snd_mtpav_get_RAWMIDI(mtpav_t * mcard)
+static int __init snd_mtpav_get_RAWMIDI(struct mtpav *mcard)
 {
-	int rval = 0;
-	snd_rawmidi_t *rawmidi;
-	snd_rawmidi_substream_t *substream;
+	int rval;
+	struct snd_rawmidi *rawmidi;
+	struct snd_rawmidi_substream *substream;
 	struct list_head *list;
 
-	//printk("entering snd_mtpav_get_RAWMIDI\n");
-
 	if (hwports < 1)
-		mcard->num_ports = 1;
+		hwports = 1;
 	else if (hwports > 8)
-		mcard->num_ports = 8;
-	else
-		mcard->num_ports = hwports;
+		hwports = 8;
+	mcard->num_ports = hwports;
 
 	if ((rval = snd_rawmidi_new(mcard->card, "MotuMIDI", 0,
 				    mcard->num_ports * 2 + MTPAV_PIDX_BROADCAST + 1,
@@ -664,14 +653,15 @@
 				    &mcard->rmidi)) < 0)
 		return rval;
 	rawmidi = mcard->rmidi;
+	rawmidi->private_data = mcard;
 
 	list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_INPUT].substreams) {
-		substream = list_entry(list, snd_rawmidi_substream_t, list);
+		substream = list_entry(list, struct snd_rawmidi_substream, list);
 		snd_mtpav_set_name(mcard, substream);
 		substream->ops = &snd_mtpav_input;
 	}
 	list_for_each(list, &rawmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT].substreams) {
-		substream = list_entry(list, snd_rawmidi_substream_t, list);
+		substream = list_entry(list, struct snd_rawmidi_substream, list);
 		snd_mtpav_set_name(mcard, substream);
 		substream->ops = &snd_mtpav_output;
 		mcard->ports[substream->number].hwport = translate_subdevice_to_hwport(mcard, substream->number);
@@ -679,36 +669,15 @@
 	rawmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
 			       SNDRV_RAWMIDI_INFO_DUPLEX;
 	sprintf(rawmidi->name, "MTP AV MIDI");
-	//printk("exiting snd_mtpav_get_RAWMIDI() \n");
 	return 0;
 }
 
 /*
  */
 
-static mtpav_t *new_mtpav(void)
+static void snd_mtpav_free(struct snd_card *card)
 {
-	mtpav_t *ncrd = kzalloc(sizeof(*ncrd), GFP_KERNEL);
-	if (ncrd != NULL) {
-		spin_lock_init(&ncrd->spinlock);
-
-		init_timer(&ncrd->timer);
-		ncrd->card = NULL;
-		ncrd->irq = -1;
-		ncrd->share_irq = 0;
-
-		ncrd->inmidiport = 0xffffffff;
-		ncrd->inmidistate = 0;
-		ncrd->outmidihwport = 0xffffffff;
-	}
-	return ncrd;
-}
-
-/*
- */
-
-static void free_mtpav(mtpav_t * crd)
-{
+	struct mtpav *crd = card->private_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&crd->spinlock, flags);
@@ -718,78 +687,101 @@
 	if (crd->irq >= 0)
 		free_irq(crd->irq, (void *)crd);
 	release_and_free_resource(crd->res_port);
-	kfree(crd);
 }
 
 /*
  */
-
-static int __init alsa_card_mtpav_init(void)
+static int __init snd_mtpav_probe(struct platform_device *dev)
 {
-	int err = 0;
-	char longname_buffer[80];
+	struct snd_card *card;
+	int err;
+	struct mtpav *mtp_card;
 
-	mtp_card = new_mtpav();
-	if (mtp_card == NULL)
+	card = snd_card_new(index, id, THIS_MODULE, sizeof(*mtp_card));
+	if (! card)
 		return -ENOMEM;
 
-	mtp_card->card = snd_card_new(index, id, THIS_MODULE, 0);
-	if (mtp_card->card == NULL) {
-		free_mtpav(mtp_card);
-		return -ENOMEM;
-	}
+	mtp_card = card->private_data;
+	spin_lock_init(&mtp_card->spinlock);
+	init_timer(&mtp_card->timer);
+	mtp_card->card = card;
+	mtp_card->irq = -1;
+	mtp_card->share_irq = 0;
+	mtp_card->inmidiport = 0xffffffff;
+	mtp_card->inmidistate = 0;
+	mtp_card->outmidihwport = 0xffffffff;
+	init_timer(&mtp_card->timer);
+	mtp_card->timer.function = snd_mtpav_output_timer;
+	mtp_card->timer.data = (unsigned long) mtp_card;
+
+	card->private_free = snd_mtpav_free;
 
 	err = snd_mtpav_get_ISA(mtp_card);
-	//printk("snd_mtpav_get_ISA returned: %d\n", err);
 	if (err < 0)
 		goto __error;
 
-	strcpy(mtp_card->card->driver, "MTPAV");
-	strcpy(mtp_card->card->shortname, "MTPAV on parallel port");
-	memset(longname_buffer, 0, sizeof(longname_buffer));
-	sprintf(longname_buffer, "MTPAV on parallel port at");
+	strcpy(card->driver, "MTPAV");
+	strcpy(card->shortname, "MTPAV on parallel port");
+	snprintf(card->longname, sizeof(card->longname),
+		 "MTPAV on parallel port at 0x%lx", port);
 
 	err = snd_mtpav_get_RAWMIDI(mtp_card);
-	//snd_printk("snd_mtapv_get_RAWMIDI returned: %d\n", err);
 	if (err < 0)
 		goto __error;
 
-	if ((err = snd_card_set_generic_dev(mtp_card->card)) < 0)
-		goto __error;
-
-	err = snd_card_register(mtp_card->card);	// don't snd_card_register until AFTER all cards reources done!
-
-	//printk("snd_card_register returned %d\n", err);
-	if (err < 0)
-		goto __error;
-
-
 	snd_mtpav_portscan(mtp_card);
 
-	printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port);
+	snd_card_set_dev(card, &dev->dev);
+	err = snd_card_register(mtp_card->card);
+	if (err < 0)
+		goto __error;
 
+	platform_set_drvdata(dev, card);
+	printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port);
 	return 0;
 
-      __error:
-	snd_card_free(mtp_card->card);
-	free_mtpav(mtp_card);
+ __error:
+	snd_card_free(card);
 	return err;
 }
 
-/*
- */
+static int snd_mtpav_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#define SND_MTPAV_DRIVER	"snd_mtpav"
+
+static struct platform_driver snd_mtpav_driver = {
+	.probe		= snd_mtpav_probe,
+	.remove		= snd_mtpav_remove,
+	.driver		= {
+		.name	= SND_MTPAV_DRIVER
+	},
+};
+
+static int __init alsa_card_mtpav_init(void)
+{
+	int err;
+
+	if ((err = platform_driver_register(&snd_mtpav_driver)) < 0)
+		return err;
+
+	device = platform_device_register_simple(SND_MTPAV_DRIVER, -1, NULL, 0);
+	if (IS_ERR(device)) {
+		platform_driver_unregister(&snd_mtpav_driver);
+		return PTR_ERR(device);
+	}
+	return 0;
+}
 
 static void __exit alsa_card_mtpav_exit(void)
 {
-	if (mtp_card == NULL)
-		return;
-	if (mtp_card->card)
-		snd_card_free(mtp_card->card);
-	free_mtpav(mtp_card);
+	platform_device_unregister(device);
+	platform_driver_unregister(&snd_mtpav_driver);
 }
 
-/*
- */
-
 module_init(alsa_card_mtpav_init)
 module_exit(alsa_card_mtpav_exit)
diff --git a/sound/drivers/opl3/opl3_drums.c b/sound/drivers/opl3/opl3_drums.c
index f263326..7369438 100644
--- a/sound/drivers/opl3/opl3_drums.c
+++ b/sound/drivers/opl3/opl3_drums.c
@@ -45,7 +45,7 @@
 	OPL3_CYMBAL_ON,    OPL3_CYMBAL_ON			/* 80 - 81 */
 };
 
-typedef struct snd_opl3_drum_voice {
+struct snd_opl3_drum_voice {
 	int voice;
 	int op;
 	unsigned char am_vib;
@@ -54,33 +54,34 @@
 	unsigned char sustain_release;
 	unsigned char feedback_connection;
 	unsigned char wave_select;
-} snd_opl3_drum_voice_t;
+};
 
-typedef struct snd_opl3_drum_note {
+struct snd_opl3_drum_note {
 	int voice;
 	unsigned char fnum;
 	unsigned char octave_f;
 	unsigned char feedback_connection;
-} snd_opl3_drum_note_t;
+};
 
-static snd_opl3_drum_voice_t bass_op0 = {6, 0, 0x00, 0x32, 0xf8, 0x66, 0x30, 0x00};
-static snd_opl3_drum_voice_t bass_op1 = {6, 1, 0x00, 0x03, 0xf6, 0x57, 0x30, 0x00};
-static snd_opl3_drum_note_t bass_note = {6, 0x90, 0x09};
+static struct snd_opl3_drum_voice bass_op0 = {6, 0, 0x00, 0x32, 0xf8, 0x66, 0x30, 0x00};
+static struct snd_opl3_drum_voice bass_op1 = {6, 1, 0x00, 0x03, 0xf6, 0x57, 0x30, 0x00};
+static struct snd_opl3_drum_note bass_note = {6, 0x90, 0x09};
 
-static snd_opl3_drum_voice_t hihat = {7, 0, 0x00, 0x03, 0xf0, 0x06, 0x20, 0x00};
+static struct snd_opl3_drum_voice hihat = {7, 0, 0x00, 0x03, 0xf0, 0x06, 0x20, 0x00};
 
-static snd_opl3_drum_voice_t snare = {7, 1, 0x00, 0x03, 0xf0, 0x07, 0x20, 0x02};
-static snd_opl3_drum_note_t snare_note = {7, 0xf4, 0x0d};
+static struct snd_opl3_drum_voice snare = {7, 1, 0x00, 0x03, 0xf0, 0x07, 0x20, 0x02};
+static struct snd_opl3_drum_note snare_note = {7, 0xf4, 0x0d};
 
-static snd_opl3_drum_voice_t tomtom = {8, 0, 0x02, 0x03, 0xf0, 0x06, 0x10, 0x00};
-static snd_opl3_drum_note_t tomtom_note = {8, 0xf4, 0x09};
+static struct snd_opl3_drum_voice tomtom = {8, 0, 0x02, 0x03, 0xf0, 0x06, 0x10, 0x00};
+static struct snd_opl3_drum_note tomtom_note = {8, 0xf4, 0x09};
 
-static snd_opl3_drum_voice_t cymbal = {8, 1, 0x04, 0x03, 0xf0, 0x06, 0x10, 0x00};
+static struct snd_opl3_drum_voice cymbal = {8, 1, 0x04, 0x03, 0xf0, 0x06, 0x10, 0x00};
 
 /*
  * set drum voice characteristics
  */
-static void snd_opl3_drum_voice_set(opl3_t *opl3, snd_opl3_drum_voice_t *data)
+static void snd_opl3_drum_voice_set(struct snd_opl3 *opl3,
+				    struct snd_opl3_drum_voice *data)
 {
 	unsigned char op_offset = snd_opl3_regmap[data->voice][data->op];
 	unsigned char voice_offset = data->voice;
@@ -114,7 +115,8 @@
 /*
  * Set drum voice pitch
  */
-static void snd_opl3_drum_note_set(opl3_t *opl3, snd_opl3_drum_note_t *data)
+static void snd_opl3_drum_note_set(struct snd_opl3 *opl3,
+				   struct snd_opl3_drum_note *data)
 {
 	unsigned char voice_offset = data->voice;
 	unsigned short opl3_reg;
@@ -131,8 +133,9 @@
 /*
  * Set drum voice volume and position
  */
-static void snd_opl3_drum_vol_set(opl3_t *opl3, snd_opl3_drum_voice_t *data,
-				  int vel, snd_midi_channel_t *chan)
+static void snd_opl3_drum_vol_set(struct snd_opl3 *opl3,
+				  struct snd_opl3_drum_voice *data,
+				  int vel, struct snd_midi_channel *chan)
 {
 	unsigned char op_offset = snd_opl3_regmap[data->voice][data->op];
 	unsigned char voice_offset = data->voice;
@@ -159,7 +162,7 @@
 /*
  * Loads drum voices at init time
  */
-void snd_opl3_load_drums(opl3_t *opl3)
+void snd_opl3_load_drums(struct snd_opl3 *opl3)
 {
 	snd_opl3_drum_voice_set(opl3, &bass_op0);
 	snd_opl3_drum_voice_set(opl3, &bass_op1);
@@ -179,11 +182,11 @@
 /*
  * Switch drum voice on or off
  */
-void snd_opl3_drum_switch(opl3_t *opl3, int note, int vel, int on_off,
-			  snd_midi_channel_t *chan)
+void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int vel, int on_off,
+			  struct snd_midi_channel *chan)
 {
 	unsigned char drum_mask;
-	snd_opl3_drum_voice_t *drum_voice;
+	struct snd_opl3_drum_voice *drum_voice;
 
 	if (!(opl3->drum_reg & OPL3_PERCUSSION_ENABLE))
 		return;
diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c
index 0624650..1e0c76b 100644
--- a/sound/drivers/opl3/opl3_lib.c
+++ b/sound/drivers/opl3/opl3_lib.c
@@ -37,7 +37,7 @@
 
 extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
 
-static void snd_opl2_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
+static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
 {
 	unsigned long flags;
 	unsigned long port;
@@ -60,7 +60,7 @@
 	spin_unlock_irqrestore(&opl3->reg_lock, flags);
 }
 
-static void snd_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
+static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
 {
 	unsigned long flags;
 	unsigned long port;
@@ -85,7 +85,7 @@
 	spin_unlock_irqrestore(&opl3->reg_lock, flags);
 }
 
-static int snd_opl3_detect(opl3_t * opl3)
+static int snd_opl3_detect(struct snd_opl3 * opl3)
 {
 	/*
 	 * This function returns 1 if the FM chip is present at the given I/O port
@@ -153,12 +153,12 @@
  *  Timer 1 - 80us
  */
 
-static int snd_opl3_timer1_start(snd_timer_t * timer)
+static int snd_opl3_timer1_start(struct snd_timer * timer)
 {
 	unsigned long flags;
 	unsigned char tmp;
 	unsigned int ticks;
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
 	opl3 = snd_timer_chip(timer);
 	spin_lock_irqsave(&opl3->timer_lock, flags);
@@ -171,11 +171,11 @@
 	return 0;
 }
 
-static int snd_opl3_timer1_stop(snd_timer_t * timer)
+static int snd_opl3_timer1_stop(struct snd_timer * timer)
 {
 	unsigned long flags;
 	unsigned char tmp;
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
 	opl3 = snd_timer_chip(timer);
 	spin_lock_irqsave(&opl3->timer_lock, flags);
@@ -190,12 +190,12 @@
  *  Timer 2 - 320us
  */
 
-static int snd_opl3_timer2_start(snd_timer_t * timer)
+static int snd_opl3_timer2_start(struct snd_timer * timer)
 {
 	unsigned long flags;
 	unsigned char tmp;
 	unsigned int ticks;
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
 	opl3 = snd_timer_chip(timer);
 	spin_lock_irqsave(&opl3->timer_lock, flags);
@@ -208,11 +208,11 @@
 	return 0;
 }
 
-static int snd_opl3_timer2_stop(snd_timer_t * timer)
+static int snd_opl3_timer2_stop(struct snd_timer * timer)
 {
 	unsigned long flags;
 	unsigned char tmp;
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
 	opl3 = snd_timer_chip(timer);
 	spin_lock_irqsave(&opl3->timer_lock, flags);
@@ -227,7 +227,7 @@
 
  */
 
-static struct _snd_timer_hardware snd_opl3_timer1 =
+static struct snd_timer_hardware snd_opl3_timer1 =
 {
 	.flags =	SNDRV_TIMER_HW_STOP,
 	.resolution =	80000,
@@ -236,7 +236,7 @@
 	.stop =		snd_opl3_timer1_stop,
 };
 
-static struct _snd_timer_hardware snd_opl3_timer2 =
+static struct snd_timer_hardware snd_opl3_timer2 =
 {
 	.flags =	SNDRV_TIMER_HW_STOP,
 	.resolution =	320000,
@@ -245,10 +245,10 @@
 	.stop =		snd_opl3_timer2_stop,
 };
 
-static int snd_opl3_timer1_init(opl3_t * opl3, int timer_no)
+static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
 {
-	snd_timer_t *timer = NULL;
-	snd_timer_id_t tid;
+	struct snd_timer *timer = NULL;
+	struct snd_timer_id tid;
 	int err;
 
 	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
@@ -265,10 +265,10 @@
 	return err;
 }
 
-static int snd_opl3_timer2_init(opl3_t * opl3, int timer_no)
+static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
 {
-	snd_timer_t *timer = NULL;
-	snd_timer_id_t tid;
+	struct snd_timer *timer = NULL;
+	struct snd_timer_id tid;
 	int err;
 
 	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
@@ -289,11 +289,11 @@
 
  */
 
-void snd_opl3_interrupt(snd_hwdep_t * hw)
+void snd_opl3_interrupt(struct snd_hwdep * hw)
 {
 	unsigned char status;
-	opl3_t *opl3;
-	snd_timer_t *timer;
+	struct snd_opl3 *opl3;
+	struct snd_timer *timer;
 
 	if (hw == NULL)
 		return;
@@ -320,7 +320,7 @@
 
  */
 
-static int snd_opl3_free(opl3_t *opl3)
+static int snd_opl3_free(struct snd_opl3 *opl3)
 {
 	snd_assert(opl3 != NULL, return -ENXIO);
 	if (opl3->private_free)
@@ -331,26 +331,28 @@
 	return 0;
 }
 
-static int snd_opl3_dev_free(snd_device_t *device)
+static int snd_opl3_dev_free(struct snd_device *device)
 {
-	opl3_t *opl3 = device->device_data;
+	struct snd_opl3 *opl3 = device->device_data;
 	return snd_opl3_free(opl3);
 }
 
-int snd_opl3_new(snd_card_t *card,
+int snd_opl3_new(struct snd_card *card,
 		 unsigned short hardware,
-		 opl3_t **ropl3)
+		 struct snd_opl3 **ropl3)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_opl3_dev_free,
 	};
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 	int err;
 
 	*ropl3 = NULL;
 	opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
-	if (opl3 == NULL)
+	if (opl3 == NULL) {
+		snd_printk(KERN_ERR "opl3: cannot allocate\n");
 		return -ENOMEM;
+	}
 
 	opl3->card = card;
 	opl3->hardware = hardware;
@@ -367,7 +369,7 @@
 	return 0;
 }
 
-int snd_opl3_init(opl3_t *opl3)
+int snd_opl3_init(struct snd_opl3 *opl3)
 {
 	if (! opl3->command) {
 		printk(KERN_ERR "snd_opl3_init: command not defined!\n");
@@ -391,14 +393,14 @@
 	return 0;
 }
 
-int snd_opl3_create(snd_card_t * card,
+int snd_opl3_create(struct snd_card *card,
 		    unsigned long l_port,
 		    unsigned long r_port,
 		    unsigned short hardware,
 		    int integrated,
-		    opl3_t ** ropl3)
+		    struct snd_opl3 ** ropl3)
 {
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 	int err;
 
 	*ropl3 = NULL;
@@ -407,13 +409,13 @@
 	if (! integrated) {
 		if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
 			snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
-			snd_opl3_free(opl3);
+			snd_device_free(card, opl3);
 			return -EBUSY;
 		}
 		if (r_port != 0 &&
 		    (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
 			snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
-			snd_opl3_free(opl3);
+			snd_device_free(card, opl3);
 			return -EBUSY;
 		}
 	}
@@ -432,7 +434,7 @@
 		if ((err = snd_opl3_detect(opl3)) < 0) {
 			snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
 				   opl3->l_port, opl3->r_port);
-			snd_opl3_free(opl3);
+			snd_device_free(card, opl3);
 			return err;
 		}
 		/* detect routine returns correct hardware type */
@@ -449,7 +451,7 @@
 	return 0;
 }
 
-int snd_opl3_timer_new(opl3_t * opl3, int timer1_dev, int timer2_dev)
+int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
 {
 	int err;
 
@@ -466,12 +468,12 @@
 	return 0;
 }
 
-int snd_opl3_hwdep_new(opl3_t * opl3,
+int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
 		       int device, int seq_device,
-		       snd_hwdep_t ** rhwdep)
+		       struct snd_hwdep ** rhwdep)
 {
-	snd_hwdep_t *hw;
-	snd_card_t *card = opl3->card;
+	struct snd_hwdep *hw;
+	struct snd_card *card = opl3->card;
 	int err;
 
 	if (rhwdep)
@@ -514,9 +516,9 @@
 	opl3->seq_dev_num = seq_device;
 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
 	if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
-			       sizeof(opl3_t*), &opl3->seq_dev) >= 0) {
+			       sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
 		strcpy(opl3->seq_dev->name, hw->name);
-		*(opl3_t**)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
+		*(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
 	}
 #endif
 	if (rhwdep)
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 93d6740..1b6f227 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -60,7 +60,7 @@
 };
 
 void snd_opl3_calc_volume(unsigned char *volbyte, int vel,
-			  snd_midi_channel_t *chan)
+			  struct snd_midi_channel *chan)
 {
 	int oldvol, newvol, n;
 	int volume;
@@ -93,7 +93,7 @@
 };
 
 static void snd_opl3_calc_pitch(unsigned char *fnum, unsigned char *blocknum,
-				int note, snd_midi_channel_t *chan)
+				int note, struct snd_midi_channel *chan)
 {
 	int block = ((note / 12) & 0x07) - 1;
 	int idx = (note % 12) + 2;
@@ -121,7 +121,7 @@
 
 
 #ifdef DEBUG_ALLOC
-static void debug_alloc(opl3_t *opl3, char *s, int voice) {
+static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) {
 	int i;
 	char *str = "x.24";
 
@@ -135,12 +135,12 @@
 /*
  * Get a FM voice (channel) to play a note on.
  */
-static int opl3_get_voice(opl3_t *opl3, int instr_4op,
-			  snd_midi_channel_t *chan) {
+static int opl3_get_voice(struct snd_opl3 *opl3, int instr_4op,
+			  struct snd_midi_channel *chan) {
 	int chan_4op_1;		/* first voice for 4op instrument */
 	int chan_4op_2;		/* second voice for 4op instrument */
 
-	snd_opl3_voice_t *vp, *vp2;
+	struct snd_opl3_voice *vp, *vp2;
 	unsigned int voice_time;
 	int i;
 
@@ -237,13 +237,14 @@
 void snd_opl3_timer_func(unsigned long data)
 {
 
-	opl3_t *opl3 = (opl3_t *)data;
+	struct snd_opl3 *opl3 = (struct snd_opl3 *)data;
+	unsigned long flags;
 	int again = 0;
 	int i;
 
-	spin_lock(&opl3->sys_timer_lock);
+	spin_lock_irqsave(&opl3->sys_timer_lock, flags);
 	for (i = 0; i < opl3->max_voices; i++) {
-		snd_opl3_voice_t *vp = &opl3->voices[i];
+		struct snd_opl3_voice *vp = &opl3->voices[i];
 		if (vp->state > 0 && vp->note_off_check) {
 			if (vp->note_off == jiffies)
 				snd_opl3_note_off(opl3, vp->note, 0, vp->chan);
@@ -257,13 +258,13 @@
 	} else {
 		opl3->sys_timer_status = 0;
 	}
-	spin_unlock(&opl3->sys_timer_lock);
+	spin_unlock_irqrestore(&opl3->sys_timer_lock, flags);
 }
 
 /*
  * Start system timer
  */
-static void snd_opl3_start_timer(opl3_t *opl3)
+static void snd_opl3_start_timer(struct snd_opl3 *opl3)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&opl3->sys_timer_lock, flags);
@@ -285,15 +286,15 @@
 /*
  * Start a note.
  */
-void snd_opl3_note_on(void *p, int note, int vel, snd_midi_channel_t *chan)
+void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
 {
-	opl3_t *opl3;
-	snd_seq_instr_t wanted;
-	snd_seq_kinstr_t *kinstr;
+	struct snd_opl3 *opl3;
+	struct snd_seq_instr wanted;
+	struct snd_seq_kinstr *kinstr;
 	int instr_4op;
 
 	int voice;
-	snd_opl3_voice_t *vp, *vp2;
+	struct snd_opl3_voice *vp, *vp2;
 	unsigned short connect_mask;
 	unsigned char connection;
 	unsigned char vol_op[4];
@@ -310,7 +311,7 @@
 	unsigned char fnum, blocknum;
 	int i;
 
-	fm_instrument_t *fm;
+	struct fm_instrument *fm;
 	unsigned long flags;
 
 	opl3 = p;
@@ -615,13 +616,13 @@
 	spin_unlock_irqrestore(&opl3->voice_lock, flags);
 }
 
-static void snd_opl3_kill_voice(opl3_t *opl3, int voice)
+static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
 {
 	unsigned short reg_side;
 	unsigned char voice_offset;
 	unsigned short opl3_reg;
 
-	snd_opl3_voice_t *vp, *vp2;
+	struct snd_opl3_voice *vp, *vp2;
 
 	snd_assert(voice < MAX_OPL3_VOICES, return);
 
@@ -663,12 +664,12 @@
 /*
  * Release a note in response to a midi note off.
  */
-void snd_opl3_note_off(void *p, int note, int vel, snd_midi_channel_t *chan)
+void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
 {
-  	opl3_t *opl3;
+  	struct snd_opl3 *opl3;
 
 	int voice;
-	snd_opl3_voice_t *vp;
+	struct snd_opl3_voice *vp;
 
 	unsigned long flags;
 
@@ -708,9 +709,9 @@
 /*
  * key pressure change
  */
-void snd_opl3_key_press(void *p, int note, int vel, snd_midi_channel_t *chan)
+void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
 {
-  	opl3_t *opl3;
+  	struct snd_opl3 *opl3;
 
 	opl3 = p;
 #ifdef DEBUG_MIDI
@@ -722,9 +723,9 @@
 /*
  * terminate note
  */
-void snd_opl3_terminate_note(void *p, int note, snd_midi_channel_t *chan)
+void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan)
 {
-  	opl3_t *opl3;
+  	struct snd_opl3 *opl3;
 
 	opl3 = p;
 #ifdef DEBUG_MIDI
@@ -733,7 +734,7 @@
 #endif
 }
 
-static void snd_opl3_update_pitch(opl3_t *opl3, int voice)
+static void snd_opl3_update_pitch(struct snd_opl3 *opl3, int voice)
 {
 	unsigned short reg_side;
 	unsigned char voice_offset;
@@ -741,7 +742,7 @@
 
 	unsigned char fnum, blocknum;
 
-	snd_opl3_voice_t *vp;
+	struct snd_opl3_voice *vp;
 
 	snd_assert(voice < MAX_OPL3_VOICES, return);
 
@@ -780,10 +781,10 @@
 /*
  * Update voice pitch controller
  */
-static void snd_opl3_pitch_ctrl(opl3_t *opl3, snd_midi_channel_t *chan)
+static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *chan)
 {
 	int voice;
-	snd_opl3_voice_t *vp;
+	struct snd_opl3_voice *vp;
 
 	unsigned long flags;
 
@@ -810,9 +811,9 @@
  * Deal with a controler type event.  This includes all types of
  * control events, not just the midi controllers
  */
-void snd_opl3_control(void *p, int type, snd_midi_channel_t *chan)
+void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
 {
-  	opl3_t *opl3;
+  	struct snd_opl3 *opl3;
 
 	opl3 = p;
 #ifdef DEBUG_MIDI
@@ -846,10 +847,10 @@
 /*
  * NRPN events
  */
-void snd_opl3_nrpn(void *p, snd_midi_channel_t *chan,
-		   snd_midi_channel_set_t *chset)
+void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan,
+		   struct snd_midi_channel_set *chset)
 {
-  	opl3_t *opl3;
+  	struct snd_opl3 *opl3;
 
 	opl3 = p;
 #ifdef DEBUG_MIDI
@@ -862,9 +863,9 @@
  * receive sysex
  */
 void snd_opl3_sysex(void *p, unsigned char *buf, int len,
-		    int parsed, snd_midi_channel_set_t *chset)
+		    int parsed, struct snd_midi_channel_set *chset)
 {
-  	opl3_t *opl3;
+  	struct snd_opl3 *opl3;
 
 	opl3 = p;
 #ifdef DEBUG_MIDI
diff --git a/sound/drivers/opl3/opl3_oss.c b/sound/drivers/opl3/opl3_oss.c
index 21a2b40..31f1f2e 100644
--- a/sound/drivers/opl3/opl3_oss.c
+++ b/sound/drivers/opl3/opl3_oss.c
@@ -21,11 +21,11 @@
 #include "opl3_voice.h"
 #include <linux/slab.h>
 
-static int snd_opl3_open_seq_oss(snd_seq_oss_arg_t *arg, void *closure);
-static int snd_opl3_close_seq_oss(snd_seq_oss_arg_t *arg);
-static int snd_opl3_ioctl_seq_oss(snd_seq_oss_arg_t *arg, unsigned int cmd, unsigned long ioarg);
-static int snd_opl3_load_patch_seq_oss(snd_seq_oss_arg_t *arg, int format, const char __user *buf, int offs, int count);
-static int snd_opl3_reset_seq_oss(snd_seq_oss_arg_t *arg);
+static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
+static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg);
+static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned long ioarg);
+static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format, const char __user *buf, int offs, int count);
+static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg);
 
 /* */
 
@@ -43,9 +43,9 @@
 
 /* operators */
 
-extern snd_midi_op_t opl3_ops;
+extern struct snd_midi_op opl3_ops;
 
-static snd_seq_oss_callback_t oss_callback = {
+static struct snd_seq_oss_callback oss_callback = {
 	.owner = 	THIS_MODULE,
 	.open =		snd_opl3_open_seq_oss,
 	.close =	snd_opl3_close_seq_oss,
@@ -54,10 +54,10 @@
 	.reset =	snd_opl3_reset_seq_oss,
 };
 
-static int snd_opl3_oss_event_input(snd_seq_event_t *ev, int direct,
+static int snd_opl3_oss_event_input(struct snd_seq_event *ev, int direct,
 				    void *private_data, int atomic, int hop)
 {
-	opl3_t *opl3 = private_data;
+	struct snd_opl3 *opl3 = private_data;
 
 	if (ev->type != SNDRV_SEQ_EVENT_OSS)
 		snd_midi_process_event(&opl3_ops, ev, opl3->oss_chset);
@@ -68,14 +68,14 @@
 
 static void snd_opl3_oss_free_port(void *private_data)
 {
-	opl3_t *opl3 = private_data;
+	struct snd_opl3 *opl3 = private_data;
 
 	snd_midi_channel_free_set(opl3->oss_chset);
 }
 
-static int snd_opl3_oss_create_port(opl3_t * opl3)
+static int snd_opl3_oss_create_port(struct snd_opl3 * opl3)
 {
-	snd_seq_port_callback_t callbacks;
+	struct snd_seq_port_callback callbacks;
 	char name[32];
 	int voices, opl_ver;
 
@@ -113,13 +113,13 @@
 /* ------------------------------ */
 
 /* register OSS synth */
-void snd_opl3_init_seq_oss(opl3_t *opl3, char *name)
+void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name)
 {
-	snd_seq_oss_reg_t *arg;
-	snd_seq_device_t *dev;
+	struct snd_seq_oss_reg *arg;
+	struct snd_seq_device *dev;
 
 	if (snd_seq_device_new(opl3->card, 0, SNDRV_SEQ_DEV_ID_OSS,
-			       sizeof(snd_seq_oss_reg_t), &dev) < 0)
+			       sizeof(struct snd_seq_oss_reg), &dev) < 0)
 		return;
 
 	opl3->oss_seq_dev = dev;
@@ -143,7 +143,7 @@
 }
 
 /* unregister */
-void snd_opl3_free_seq_oss(opl3_t *opl3)
+void snd_opl3_free_seq_oss(struct snd_opl3 *opl3)
 {
 	if (opl3->oss_seq_dev) {
 		snd_device_free(opl3->card, opl3->oss_seq_dev);
@@ -154,9 +154,9 @@
 /* ------------------------------ */
 
 /* open OSS sequencer */
-static int snd_opl3_open_seq_oss(snd_seq_oss_arg_t *arg, void *closure)
+static int snd_opl3_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
 {
-	opl3_t *opl3 = closure;
+	struct snd_opl3 *opl3 = closure;
 	int err;
 
 	snd_assert(arg != NULL, return -ENXIO);
@@ -177,9 +177,9 @@
 }
 
 /* close OSS sequencer */
-static int snd_opl3_close_seq_oss(snd_seq_oss_arg_t *arg)
+static int snd_opl3_close_seq_oss(struct snd_seq_oss_arg *arg)
 {
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
 	snd_assert(arg != NULL, return -ENXIO);
 	opl3 = arg->private_data;
@@ -206,10 +206,10 @@
 /* from sound_config.h */
 #define SBFM_MAXINSTR	256
 
-static int snd_opl3_load_patch_seq_oss(snd_seq_oss_arg_t *arg, int format,
+static int snd_opl3_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
 				       const char __user *buf, int offs, int count)
 {
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 	int err = -EINVAL;
 
 	snd_assert(arg != NULL, return -ENXIO);
@@ -219,11 +219,11 @@
 		struct sbi_instrument sbi;
 
 		size_t size;
-		snd_seq_instr_header_t *put;
-		snd_seq_instr_data_t *data;
-		fm_xinstrument_t *xinstr;
+		struct snd_seq_instr_header *put;
+		struct snd_seq_instr_data *data;
+		struct fm_xinstrument *xinstr;
 
-		snd_seq_event_t ev;
+		struct snd_seq_event ev;
 		int i;
 
 		mm_segment_t fs;
@@ -240,7 +240,7 @@
 			return -EINVAL;
 		}
 
-		size = sizeof(*put) + sizeof(fm_xinstrument_t);
+		size = sizeof(*put) + sizeof(struct fm_xinstrument);
 		put = kzalloc(size, GFP_KERNEL);
 		if (put == NULL)
 			return -ENOMEM;
@@ -249,7 +249,7 @@
 		data->type = SNDRV_SEQ_INSTR_ATYPE_DATA;
 		strcpy(data->data.format, SNDRV_SEQ_INSTR_ID_OPL2_3);
 		/* build data section */
-		xinstr = (fm_xinstrument_t *)(data + 1);
+		xinstr = (struct fm_xinstrument *)(data + 1);
 		xinstr->stype = FM_STRU_INSTR;
         
 		for (i = 0; i < 2; i++) {
@@ -296,7 +296,7 @@
 		err = snd_seq_instr_event(&opl3->fm_ops, opl3->ilist, &ev,
 				    opl3->seq_client, 0, 0);
 		if (err == -EBUSY) {
-			snd_seq_instr_header_t remove;
+			struct snd_seq_instr_header remove;
 
 			memset (&remove, 0, sizeof(remove));
 			remove.cmd = SNDRV_SEQ_INSTR_FREE_CMD_SINGLE;
@@ -319,10 +319,10 @@
 }
 
 /* ioctl */
-static int snd_opl3_ioctl_seq_oss(snd_seq_oss_arg_t *arg, unsigned int cmd,
+static int snd_opl3_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
 				  unsigned long ioarg)
 {
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
 	snd_assert(arg != NULL, return -ENXIO);
 	opl3 = arg->private_data;
@@ -345,9 +345,9 @@
 }
 
 /* reset device */
-static int snd_opl3_reset_seq_oss(snd_seq_oss_arg_t *arg)
+static int snd_opl3_reset_seq_oss(struct snd_seq_oss_arg *arg)
 {
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
 	snd_assert(arg != NULL, return -ENXIO);
 	opl3 = arg->private_data;
diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c
index 136964b..c4ead79 100644
--- a/sound/drivers/opl3/opl3_seq.c
+++ b/sound/drivers/opl3/opl3_seq.c
@@ -35,7 +35,7 @@
 module_param(use_internal_drums, bool, 0444);
 MODULE_PARM_DESC(use_internal_drums, "Enable internal OPL2/3 drums.");
 
-int snd_opl3_synth_use_inc(opl3_t * opl3)
+int snd_opl3_synth_use_inc(struct snd_opl3 * opl3)
 {
 	if (!try_module_get(opl3->card->module))
 		return -EFAULT;
@@ -43,12 +43,12 @@
 
 }
 
-void snd_opl3_synth_use_dec(opl3_t * opl3)
+void snd_opl3_synth_use_dec(struct snd_opl3 * opl3)
 {
 	module_put(opl3->card->module);
 }
 
-int snd_opl3_synth_setup(opl3_t * opl3)
+int snd_opl3_synth_setup(struct snd_opl3 * opl3)
 {
 	int idx;
 
@@ -78,7 +78,7 @@
 	return 0;
 }
 
-void snd_opl3_synth_cleanup(opl3_t * opl3)
+void snd_opl3_synth_cleanup(struct snd_opl3 * opl3)
 {
 	unsigned long flags;
 
@@ -96,9 +96,9 @@
 	up(&opl3->access_mutex);
 }
 
-static int snd_opl3_synth_use(void *private_data, snd_seq_port_subscribe_t * info)
+static int snd_opl3_synth_use(void *private_data, struct snd_seq_port_subscribe * info)
 {
-	opl3_t *opl3 = private_data;
+	struct snd_opl3 *opl3 = private_data;
 	int err;
 
 	if ((err = snd_opl3_synth_setup(opl3)) < 0)
@@ -123,9 +123,9 @@
 	return 0;
 }
 
-static int snd_opl3_synth_unuse(void *private_data, snd_seq_port_subscribe_t * info)
+static int snd_opl3_synth_unuse(void *private_data, struct snd_seq_port_subscribe * info)
 {
-	opl3_t *opl3 = private_data;
+	struct snd_opl3 *opl3 = private_data;
 
 	snd_opl3_synth_cleanup(opl3);
 
@@ -137,7 +137,7 @@
 /*
  * MIDI emulation operators
  */
-snd_midi_op_t opl3_ops = {
+struct snd_midi_op opl3_ops = {
 	.note_on =		snd_opl3_note_on,
 	.note_off =		snd_opl3_note_off,
 	.key_press =		snd_opl3_key_press,
@@ -147,10 +147,10 @@
 	.sysex =		snd_opl3_sysex,
 };
 
-static int snd_opl3_synth_event_input(snd_seq_event_t * ev, int direct,
+static int snd_opl3_synth_event_input(struct snd_seq_event * ev, int direct,
 				      void *private_data, int atomic, int hop)
 {
-	opl3_t *opl3 = private_data;
+	struct snd_opl3 *opl3 = private_data;
 
 	if (ev->type >= SNDRV_SEQ_EVENT_INSTR_BEGIN &&
 	    ev->type <= SNDRV_SEQ_EVENT_INSTR_CHANGE) {
@@ -168,14 +168,14 @@
 
 static void snd_opl3_synth_free_port(void *private_data)
 {
-	opl3_t *opl3 = private_data;
+	struct snd_opl3 *opl3 = private_data;
 
 	snd_midi_channel_free_set(opl3->chset);
 }
 
-static int snd_opl3_synth_create_port(opl3_t * opl3)
+static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
 {
-	snd_seq_port_callback_t callbacks;
+	struct snd_seq_port_callback callbacks;
 	char name[32];
 	int voices, opl_ver;
 
@@ -215,15 +215,14 @@
 
 /* ------------------------------ */
 
-static int snd_opl3_seq_new_device(snd_seq_device_t *dev)
+static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
 {
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 	int client;
-	snd_seq_client_callback_t callbacks;
-	snd_seq_client_info_t cinfo;
+	char name[32];
 	int opl_ver;
 
-	opl3 = *(opl3_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	if (opl3 == NULL)
 		return -EINVAL;
 
@@ -232,22 +231,14 @@
 	opl3->seq_client = -1;
 
 	/* allocate new client */
-	memset(&callbacks, 0, sizeof(callbacks));
-	callbacks.private_data = opl3;
-	callbacks.allow_output = callbacks.allow_input = 1;
+	opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
+	sprintf(name, "OPL%i FM synth", opl_ver);
 	client = opl3->seq_client =
-	    snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num, &callbacks);
+		snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num,
+					     name);
 	if (client < 0)
 		return client;
 
-	/* change name of client */
-	memset(&cinfo, 0, sizeof(cinfo));
-	cinfo.client = client;
-	cinfo.type = KERNEL_CLIENT;
-	opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
-	sprintf(cinfo.name, "OPL%i FM synth", opl_ver);
-	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
-
 	snd_opl3_synth_create_port(opl3);
 
 	/* initialize instrument list */
@@ -268,16 +259,16 @@
 	opl3->sys_timer_status = 0;
 
 #ifdef CONFIG_SND_SEQUENCER_OSS
-	snd_opl3_init_seq_oss(opl3, cinfo.name);
+	snd_opl3_init_seq_oss(opl3, name);
 #endif
 	return 0;
 }
 
-static int snd_opl3_seq_delete_device(snd_seq_device_t *dev)
+static int snd_opl3_seq_delete_device(struct snd_seq_device *dev)
 {
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
-	opl3 = *(opl3_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	if (opl3 == NULL)
 		return -EINVAL;
 
@@ -295,14 +286,14 @@
 
 static int __init alsa_opl3_seq_init(void)
 {
-	static snd_seq_dev_ops_t ops =
+	static struct snd_seq_dev_ops ops =
 	{
 		snd_opl3_seq_new_device,
 		snd_opl3_seq_delete_device
 	};
 
 	return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL3, &ops,
-					      sizeof(opl3_t*));
+					      sizeof(struct snd_opl3 *));
 }
 
 static void __exit alsa_opl3_seq_exit(void)
diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c
index 04f9f95..3534a0e 100644
--- a/sound/drivers/opl3/opl3_synth.c
+++ b/sound/drivers/opl3/opl3_synth.c
@@ -61,20 +61,20 @@
 /*
  * prototypes
  */
-static int snd_opl3_play_note(opl3_t * opl3, snd_dm_fm_note_t * note);
-static int snd_opl3_set_voice(opl3_t * opl3, snd_dm_fm_voice_t * voice);
-static int snd_opl3_set_params(opl3_t * opl3, snd_dm_fm_params_t * params);
-static int snd_opl3_set_mode(opl3_t * opl3, int mode);
-static int snd_opl3_set_connection(opl3_t * opl3, int connection);
+static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note);
+static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice);
+static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params);
+static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode);
+static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection);
 
 /* ------------------------------ */
 
 /*
  * open the device exclusively
  */
-int snd_opl3_open(snd_hwdep_t * hw, struct file *file)
+int snd_opl3_open(struct snd_hwdep * hw, struct file *file)
 {
-	opl3_t *opl3 = hw->private_data;
+	struct snd_opl3 *opl3 = hw->private_data;
 
 	down(&opl3->access_mutex);
 	if (opl3->used) {
@@ -90,10 +90,10 @@
 /*
  * ioctl for hwdep device:
  */
-int snd_opl3_ioctl(snd_hwdep_t * hw, struct file *file,
+int snd_opl3_ioctl(struct snd_hwdep * hw, struct file *file,
 		   unsigned int cmd, unsigned long arg)
 {
-	opl3_t *opl3 = hw->private_data;
+	struct snd_opl3 *opl3 = hw->private_data;
 	void __user *argp = (void __user *)arg;
 
 	snd_assert(opl3 != NULL, return -EINVAL);
@@ -102,11 +102,11 @@
 		/* get information */
 	case SNDRV_DM_FM_IOCTL_INFO:
 		{
-			snd_dm_fm_info_t info;
+			struct snd_dm_fm_info info;
 
 			info.fm_mode = opl3->fm_mode;
 			info.rhythm = opl3->rhythm;
-			if (copy_to_user(argp, &info, sizeof(snd_dm_fm_info_t)))
+			if (copy_to_user(argp, &info, sizeof(struct snd_dm_fm_info)))
 				return -EFAULT;
 			return 0;
 		}
@@ -123,8 +123,8 @@
 	case SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE:
 #endif
 		{
-			snd_dm_fm_note_t note;
-			if (copy_from_user(&note, argp, sizeof(snd_dm_fm_note_t)))
+			struct snd_dm_fm_note note;
+			if (copy_from_user(&note, argp, sizeof(struct snd_dm_fm_note)))
 				return -EFAULT;
 			return snd_opl3_play_note(opl3, &note);
 		}
@@ -134,8 +134,8 @@
 	case SNDRV_DM_FM_OSS_IOCTL_SET_VOICE:
 #endif
 		{
-			snd_dm_fm_voice_t voice;
-			if (copy_from_user(&voice, argp, sizeof(snd_dm_fm_voice_t)))
+			struct snd_dm_fm_voice voice;
+			if (copy_from_user(&voice, argp, sizeof(struct snd_dm_fm_voice)))
 				return -EFAULT;
 			return snd_opl3_set_voice(opl3, &voice);
 		}
@@ -145,8 +145,8 @@
 	case SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS:
 #endif
 		{
-			snd_dm_fm_params_t params;
-			if (copy_from_user(&params, argp, sizeof(snd_dm_fm_params_t)))
+			struct snd_dm_fm_params params;
+			if (copy_from_user(&params, argp, sizeof(struct snd_dm_fm_params)))
 				return -EFAULT;
 			return snd_opl3_set_params(opl3, &params);
 		}
@@ -174,9 +174,9 @@
 /*
  * close the device
  */
-int snd_opl3_release(snd_hwdep_t * hw, struct file *file)
+int snd_opl3_release(struct snd_hwdep * hw, struct file *file)
 {
-	opl3_t *opl3 = hw->private_data;
+	struct snd_opl3 *opl3 = hw->private_data;
 
 	snd_opl3_reset(opl3);
 	down(&opl3->access_mutex);
@@ -188,7 +188,7 @@
 
 /* ------------------------------ */
 
-void snd_opl3_reset(opl3_t * opl3)
+void snd_opl3_reset(struct snd_opl3 * opl3)
 {
 	unsigned short opl3_reg;
 
@@ -229,7 +229,7 @@
 }
 
 
-static int snd_opl3_play_note(opl3_t * opl3, snd_dm_fm_note_t * note)
+static int snd_opl3_play_note(struct snd_opl3 * opl3, struct snd_dm_fm_note * note)
 {
 	unsigned short reg_side;
 	unsigned char voice_offset;
@@ -276,7 +276,7 @@
 }
 
 
-static int snd_opl3_set_voice(opl3_t * opl3, snd_dm_fm_voice_t * voice)
+static int snd_opl3_set_voice(struct snd_opl3 * opl3, struct snd_dm_fm_voice * voice)
 {
 	unsigned short reg_side;
 	unsigned char op_offset;
@@ -378,7 +378,7 @@
 	return 0;
 }
 
-static int snd_opl3_set_params(opl3_t * opl3, snd_dm_fm_params_t * params)
+static int snd_opl3_set_params(struct snd_opl3 * opl3, struct snd_dm_fm_params * params)
 {
 	unsigned char reg_val;
 
@@ -418,7 +418,7 @@
 	return 0;
 }
 
-static int snd_opl3_set_mode(opl3_t * opl3, int mode)
+static int snd_opl3_set_mode(struct snd_opl3 * opl3, int mode)
 {
 	if ((mode == SNDRV_DM_FM_MODE_OPL3) && (opl3->hardware < OPL3_HW_OPL3))
 		return -EINVAL;
@@ -430,7 +430,7 @@
 	return 0;
 }
 
-static int snd_opl3_set_connection(opl3_t * opl3, int connection)
+static int snd_opl3_set_connection(struct snd_opl3 * opl3, int connection)
 {
 	unsigned char reg_val;
 
diff --git a/sound/drivers/opl3/opl3_voice.h b/sound/drivers/opl3/opl3_voice.h
index 63346a5..a371c07 100644
--- a/sound/drivers/opl3/opl3_voice.h
+++ b/sound/drivers/opl3/opl3_voice.h
@@ -22,31 +22,31 @@
 #include <sound/opl3.h>
 
 /* Prototypes for opl3_seq.c */
-int snd_opl3_synth_use_inc(opl3_t * opl3);
-void snd_opl3_synth_use_dec(opl3_t * opl3);
-int snd_opl3_synth_setup(opl3_t * opl3);
-void snd_opl3_synth_cleanup(opl3_t * opl3);
+int snd_opl3_synth_use_inc(struct snd_opl3 * opl3);
+void snd_opl3_synth_use_dec(struct snd_opl3 * opl3);
+int snd_opl3_synth_setup(struct snd_opl3 * opl3);
+void snd_opl3_synth_cleanup(struct snd_opl3 * opl3);
 
 /* Prototypes for opl3_midi.c */
 void snd_opl3_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
 void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
 void snd_opl3_key_press(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_opl3_terminate_note(void *p, int note, snd_midi_channel_t *chan);
+void snd_opl3_terminate_note(void *p, int note, struct snd_midi_channel *chan);
 void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan);
-void snd_opl3_nrpn(void *p, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);
-void snd_opl3_sysex(void *p, unsigned char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
+void snd_opl3_nrpn(void *p, struct snd_midi_channel *chan, struct snd_midi_channel_set *chset);
+void snd_opl3_sysex(void *p, unsigned char *buf, int len, int parsed, struct snd_midi_channel_set *chset);
 
-void snd_opl3_calc_volume(unsigned char *reg, int vel, snd_midi_channel_t *chan);
+void snd_opl3_calc_volume(unsigned char *reg, int vel, struct snd_midi_channel *chan);
 void snd_opl3_timer_func(unsigned long data);
 
 /* Prototypes for opl3_drums.c */
-void snd_opl3_load_drums(opl3_t *opl3);
-void snd_opl3_drum_switch(opl3_t *opl3, int note, int on_off, int vel, snd_midi_channel_t *chan);
+void snd_opl3_load_drums(struct snd_opl3 *opl3);
+void snd_opl3_drum_switch(struct snd_opl3 *opl3, int note, int on_off, int vel, struct snd_midi_channel *chan);
 
 /* Prototypes for opl3_oss.c */
 #ifdef CONFIG_SND_SEQUENCER_OSS
-void snd_opl3_init_seq_oss(opl3_t *opl3, char *name);
-void snd_opl3_free_seq_oss(opl3_t *opl3);
+void snd_opl3_init_seq_oss(struct snd_opl3 *opl3, char *name);
+void snd_opl3_free_seq_oss(struct snd_opl3 *opl3);
 #endif
 
 #endif
diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c
index 4ae5dd8..ddfc10d 100644
--- a/sound/drivers/opl4/opl4_lib.c
+++ b/sound/drivers/opl4/opl4_lib.c
@@ -27,14 +27,14 @@
 MODULE_DESCRIPTION("OPL4 driver");
 MODULE_LICENSE("GPL");
 
-static void inline snd_opl4_wait(opl4_t *opl4)
+static void inline snd_opl4_wait(struct snd_opl4 *opl4)
 {
 	int timeout = 10;
 	while ((inb(opl4->fm_port) & OPL4_STATUS_BUSY) && --timeout > 0)
 		;
 }
 
-void snd_opl4_write(opl4_t *opl4, u8 reg, u8 value)
+void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value)
 {
 	snd_opl4_wait(opl4);
 	outb(reg, opl4->pcm_port);
@@ -43,7 +43,7 @@
 	outb(value, opl4->pcm_port + 1);
 }
 
-u8 snd_opl4_read(opl4_t *opl4, u8 reg)
+u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg)
 {
 	snd_opl4_wait(opl4);
 	outb(reg, opl4->pcm_port);
@@ -52,7 +52,7 @@
 	return inb(opl4->pcm_port + 1);
 }
 
-void snd_opl4_read_memory(opl4_t *opl4, char *buf, int offset, int size)
+void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size)
 {
 	unsigned long flags;
 	u8 memcfg;
@@ -76,7 +76,7 @@
 	spin_unlock_irqrestore(&opl4->reg_lock, flags);
 }
 
-void snd_opl4_write_memory(opl4_t *opl4, const char *buf, int offset, int size)
+void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size)
 {
 	unsigned long flags;
 	u8 memcfg;
@@ -100,7 +100,7 @@
 	spin_unlock_irqrestore(&opl4->reg_lock, flags);
 }
 
-static void snd_opl4_enable_opl4(opl4_t *opl4)
+static void snd_opl4_enable_opl4(struct snd_opl4 *opl4)
 {
 	outb(OPL3_REG_MODE, opl4->fm_port + 2);
 	inb(opl4->fm_port);
@@ -110,7 +110,7 @@
 	inb(opl4->fm_port);
 }
 
-static int snd_opl4_detect(opl4_t *opl4)
+static int snd_opl4_detect(struct snd_opl4 *opl4)
 {
 	u8 id1, id2;
 
@@ -144,19 +144,19 @@
 }
 
 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
-static void snd_opl4_seq_dev_free(snd_seq_device_t *seq_dev)
+static void snd_opl4_seq_dev_free(struct snd_seq_device *seq_dev)
 {
-	opl4_t *opl4 = seq_dev->private_data;
+	struct snd_opl4 *opl4 = seq_dev->private_data;
 	opl4->seq_dev = NULL;
 }
 
-static int snd_opl4_create_seq_dev(opl4_t *opl4, int seq_device)
+static int snd_opl4_create_seq_dev(struct snd_opl4 *opl4, int seq_device)
 {
 	opl4->seq_dev_num = seq_device;
 	if (snd_seq_device_new(opl4->card, seq_device, SNDRV_SEQ_DEV_ID_OPL4,
-			       sizeof(opl4_t *), &opl4->seq_dev) >= 0) {
+			       sizeof(struct snd_opl4 *), &opl4->seq_dev) >= 0) {
 		strcpy(opl4->seq_dev->name, "OPL4 Wavetable");
-		*(opl4_t **)SNDRV_SEQ_DEVICE_ARGPTR(opl4->seq_dev) = opl4;
+		*(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(opl4->seq_dev) = opl4;
 		opl4->seq_dev->private_data = opl4;
 		opl4->seq_dev->private_free = snd_opl4_seq_dev_free;
 	}
@@ -164,7 +164,7 @@
 }
 #endif
 
-static void snd_opl4_free(opl4_t *opl4)
+static void snd_opl4_free(struct snd_opl4 *opl4)
 {
 #ifdef CONFIG_PROC_FS
 	snd_opl4_free_proc(opl4);
@@ -174,22 +174,22 @@
 	kfree(opl4);
 }
 
-static int snd_opl4_dev_free(snd_device_t *device)
+static int snd_opl4_dev_free(struct snd_device *device)
 {
-	opl4_t *opl4 = device->device_data;
+	struct snd_opl4 *opl4 = device->device_data;
 	snd_opl4_free(opl4);
 	return 0;
 }
 
-int snd_opl4_create(snd_card_t *card,
+int snd_opl4_create(struct snd_card *card,
 		    unsigned long fm_port, unsigned long pcm_port,
 		    int seq_device,
-		    opl3_t **ropl3, opl4_t **ropl4)
+		    struct snd_opl3 **ropl3, struct snd_opl4 **ropl4)
 {
-	opl4_t *opl4;
-	opl3_t *opl3;
+	struct snd_opl4 *opl4;
+	struct snd_opl3 *opl3;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_opl4_dev_free
 	};
 
diff --git a/sound/drivers/opl4/opl4_local.h b/sound/drivers/opl4/opl4_local.h
index c455680..7e088a4 100644
--- a/sound/drivers/opl4/opl4_local.h
+++ b/sound/drivers/opl4/opl4_local.h
@@ -131,7 +131,7 @@
 #define SNDRV_SEQ_DEV_ID_OPL4 "opl4-synth"
 
 
-typedef struct opl4_sound {
+struct opl4_sound {
 	u16 tone;
 	s16 pitch_offset;
 	u8 key_scaling;
@@ -144,42 +144,42 @@
 	u8 reg_level_decay2;
 	u8 reg_release_correction;
 	u8 reg_tremolo;
-} opl4_sound_t;
+};
 
-typedef struct opl4_region {
+struct opl4_region {
 	u8 key_min, key_max;
-	opl4_sound_t sound;
-} opl4_region_t;
+	struct opl4_sound sound;
+};
 
-typedef struct opl4_region_ptr {
+struct opl4_region_ptr {
 	int count;
-	const opl4_region_t *regions;
-} opl4_region_ptr_t;
+	const struct opl4_region *regions;
+};
 
-typedef struct opl4_voice {
+struct opl4_voice {
 	struct list_head list;
 	int number;
-	snd_midi_channel_t *chan;
+	struct snd_midi_channel *chan;
 	int note;
 	int velocity;
-	const opl4_sound_t *sound;
+	const struct opl4_sound *sound;
 	u8 level_direct;
 	u8 reg_f_number;
 	u8 reg_misc;
 	u8 reg_lfo_vibrato;
-} opl4_voice_t;
+};
 
-struct opl4 {
+struct snd_opl4 {
 	unsigned long fm_port;
 	unsigned long pcm_port;
 	struct resource *res_fm_port;
 	struct resource *res_pcm_port;
 	unsigned short hardware;
 	spinlock_t reg_lock;
-	snd_card_t *card;
+	struct snd_card *card;
 
 #ifdef CONFIG_PROC_FS
-	snd_info_entry_t *proc_entry;
+	struct snd_info_entry *proc_entry;
 	int memory_access;
 #endif
 	struct semaphore access_mutex;
@@ -189,44 +189,44 @@
 
 	int seq_dev_num;
 	int seq_client;
-	snd_seq_device_t *seq_dev;
+	struct snd_seq_device *seq_dev;
 
-	snd_midi_channel_set_t *chset;
-	opl4_voice_t voices[OPL4_MAX_VOICES];
+	struct snd_midi_channel_set *chset;
+	struct opl4_voice voices[OPL4_MAX_VOICES];
 	struct list_head off_voices;
 	struct list_head on_voices;
 #endif
 };
 
 /* opl4_lib.c */
-void snd_opl4_write(opl4_t *opl4, u8 reg, u8 value);
-u8 snd_opl4_read(opl4_t *opl4, u8 reg);
-void snd_opl4_read_memory(opl4_t *opl4, char *buf, int offset, int size);
-void snd_opl4_write_memory(opl4_t *opl4, const char *buf, int offset, int size);
+void snd_opl4_write(struct snd_opl4 *opl4, u8 reg, u8 value);
+u8 snd_opl4_read(struct snd_opl4 *opl4, u8 reg);
+void snd_opl4_read_memory(struct snd_opl4 *opl4, char *buf, int offset, int size);
+void snd_opl4_write_memory(struct snd_opl4 *opl4, const char *buf, int offset, int size);
 
 /* opl4_mixer.c */
-int snd_opl4_create_mixer(opl4_t *opl4);
+int snd_opl4_create_mixer(struct snd_opl4 *opl4);
 
 #ifdef CONFIG_PROC_FS
 /* opl4_proc.c */
-int snd_opl4_create_proc(opl4_t *opl4);
-void snd_opl4_free_proc(opl4_t *opl4);
+int snd_opl4_create_proc(struct snd_opl4 *opl4);
+void snd_opl4_free_proc(struct snd_opl4 *opl4);
 #endif
 
 /* opl4_seq.c */
 extern int volume_boost;
 
 /* opl4_synth.c */
-void snd_opl4_synth_reset(opl4_t *opl4);
-void snd_opl4_synth_shutdown(opl4_t *opl4);
-void snd_opl4_note_on(void *p, int note, int vel, snd_midi_channel_t *chan);
-void snd_opl4_note_off(void *p, int note, int vel, snd_midi_channel_t *chan);
-void snd_opl4_terminate_note(void *p, int note, snd_midi_channel_t *chan);
-void snd_opl4_control(void *p, int type, snd_midi_channel_t *chan);
-void snd_opl4_sysex(void *p, unsigned char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
+void snd_opl4_synth_reset(struct snd_opl4 *opl4);
+void snd_opl4_synth_shutdown(struct snd_opl4 *opl4);
+void snd_opl4_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
+void snd_opl4_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
+void snd_opl4_terminate_note(void *p, int note, struct snd_midi_channel *chan);
+void snd_opl4_control(void *p, int type, struct snd_midi_channel *chan);
+void snd_opl4_sysex(void *p, unsigned char *buf, int len, int parsed, struct snd_midi_channel_set *chset);
 
 /* yrw801.c */
-int snd_yrw801_detect(opl4_t *opl4);
-extern const opl4_region_ptr_t snd_yrw801_regions[];
+int snd_yrw801_detect(struct snd_opl4 *opl4);
+extern const struct opl4_region_ptr snd_yrw801_regions[];
 
 #endif /* __OPL4_LOCAL_H */
diff --git a/sound/drivers/opl4/opl4_mixer.c b/sound/drivers/opl4/opl4_mixer.c
index ec7a228..04079de4 100644
--- a/sound/drivers/opl4/opl4_mixer.c
+++ b/sound/drivers/opl4/opl4_mixer.c
@@ -20,7 +20,7 @@
 #include "opl4_local.h"
 #include <sound/control.h>
 
-static int snd_opl4_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_opl4_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -29,9 +29,9 @@
 	return 0;
 }
 
-static int snd_opl4_ctl_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_opl4_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opl4_t *opl4 = snd_kcontrol_chip(kcontrol);
+	struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	u8 reg = kcontrol->private_value;
 	u8 value;
@@ -44,9 +44,9 @@
 	return 0;
 }
 
-static int snd_opl4_ctl_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_opl4_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opl4_t *opl4 = snd_kcontrol_chip(kcontrol);
+	struct snd_opl4 *opl4 = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	u8 reg = kcontrol->private_value;
 	u8 value, old_value;
@@ -60,7 +60,7 @@
 	return value != old_value;
 }
 
-static snd_kcontrol_new_t snd_opl4_controls[] = {
+static struct snd_kcontrol_new snd_opl4_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "FM Playback Volume",
@@ -79,9 +79,9 @@
 	}
 };
 
-int snd_opl4_create_mixer(opl4_t *opl4)
+int snd_opl4_create_mixer(struct snd_opl4 *opl4)
 {
-	snd_card_t *card = opl4->card;
+	struct snd_card *card = opl4->card;
 	int i, err;
 
 	strcat(card->mixername, ",OPL4");
diff --git a/sound/drivers/opl4/opl4_proc.c b/sound/drivers/opl4/opl4_proc.c
index 6a14862..f4b4e74 100644
--- a/sound/drivers/opl4/opl4_proc.c
+++ b/sound/drivers/opl4/opl4_proc.c
@@ -23,10 +23,10 @@
 
 #ifdef CONFIG_PROC_FS
 
-static int snd_opl4_mem_proc_open(snd_info_entry_t *entry,
+static int snd_opl4_mem_proc_open(struct snd_info_entry *entry,
 				  unsigned short mode, void **file_private_data)
 {
-	opl4_t *opl4 = entry->private_data;
+	struct snd_opl4 *opl4 = entry->private_data;
 
 	down(&opl4->access_mutex);
 	if (opl4->memory_access) {
@@ -38,10 +38,10 @@
 	return 0;
 }
 
-static int snd_opl4_mem_proc_release(snd_info_entry_t *entry,
+static int snd_opl4_mem_proc_release(struct snd_info_entry *entry,
 				     unsigned short mode, void *file_private_data)
 {
-	opl4_t *opl4 = entry->private_data;
+	struct snd_opl4 *opl4 = entry->private_data;
 
 	down(&opl4->access_mutex);
 	opl4->memory_access--;
@@ -49,11 +49,11 @@
 	return 0;
 }
 
-static long snd_opl4_mem_proc_read(snd_info_entry_t *entry, void *file_private_data,
+static long snd_opl4_mem_proc_read(struct snd_info_entry *entry, void *file_private_data,
 				   struct file *file, char __user *_buf,
 				   unsigned long count, unsigned long pos)
 {
-	opl4_t *opl4 = entry->private_data;
+	struct snd_opl4 *opl4 = entry->private_data;
 	long size;
 	char* buf;
 
@@ -75,11 +75,11 @@
 	return 0;
 }
 
-static long snd_opl4_mem_proc_write(snd_info_entry_t *entry, void *file_private_data,
+static long snd_opl4_mem_proc_write(struct snd_info_entry *entry, void *file_private_data,
 				    struct file *file, const char __user *_buf,
 				    unsigned long count, unsigned long pos)
 {
-	opl4_t *opl4 = entry->private_data;
+	struct snd_opl4 *opl4 = entry->private_data;
 	long size;
 	char *buf;
 
@@ -101,7 +101,7 @@
 	return 0;
 }
 
-static long long snd_opl4_mem_proc_llseek(snd_info_entry_t *entry, void *file_private_data,
+static long long snd_opl4_mem_proc_llseek(struct snd_info_entry *entry, void *file_private_data,
 					  struct file *file, long long offset, int orig)
 {
 	switch (orig) {
@@ -130,9 +130,9 @@
 	.llseek = snd_opl4_mem_proc_llseek,
 };
 
-int snd_opl4_create_proc(opl4_t *opl4)
+int snd_opl4_create_proc(struct snd_opl4 *opl4)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	entry = snd_info_create_card_entry(opl4->card, "opl4-mem", opl4->card->proc_root);
 	if (entry) {
@@ -157,7 +157,7 @@
 	return 0;
 }
 
-void snd_opl4_free_proc(opl4_t *opl4)
+void snd_opl4_free_proc(struct snd_opl4 *opl4)
 {
 	if (opl4->proc_entry)
 		snd_info_unregister(opl4->proc_entry);
diff --git a/sound/drivers/opl4/opl4_seq.c b/sound/drivers/opl4/opl4_seq.c
index 958dfe8..e348032 100644
--- a/sound/drivers/opl4/opl4_seq.c
+++ b/sound/drivers/opl4/opl4_seq.c
@@ -45,21 +45,21 @@
 module_param(volume_boost, int, 0644);
 MODULE_PARM_DESC(volume_boost, "Additional volume for OPL4 wavetable sounds.");
 
-static int snd_opl4_seq_use_inc(opl4_t *opl4)
+static int snd_opl4_seq_use_inc(struct snd_opl4 *opl4)
 {
 	if (!try_module_get(opl4->card->module))
 		return -EFAULT;
 	return 0;
 }
 
-static void snd_opl4_seq_use_dec(opl4_t *opl4)
+static void snd_opl4_seq_use_dec(struct snd_opl4 *opl4)
 {
 	module_put(opl4->card->module);
 }
 
-static int snd_opl4_seq_use(void *private_data, snd_seq_port_subscribe_t *info)
+static int snd_opl4_seq_use(void *private_data, struct snd_seq_port_subscribe *info)
 {
-	opl4_t *opl4 = private_data;
+	struct snd_opl4 *opl4 = private_data;
 	int err;
 
 	down(&opl4->access_mutex);
@@ -84,9 +84,9 @@
 	return 0;
 }
 
-static int snd_opl4_seq_unuse(void *private_data, snd_seq_port_subscribe_t *info)
+static int snd_opl4_seq_unuse(void *private_data, struct snd_seq_port_subscribe *info)
 {
-	opl4_t *opl4 = private_data;
+	struct snd_opl4 *opl4 = private_data;
 
 	snd_opl4_synth_shutdown(opl4);
 
@@ -99,7 +99,7 @@
 	return 0;
 }
 
-static snd_midi_op_t opl4_ops = {
+static struct snd_midi_op opl4_ops = {
 	.note_on =		snd_opl4_note_on,
 	.note_off =		snd_opl4_note_off,
 	.note_terminate =	snd_opl4_terminate_note,
@@ -107,10 +107,10 @@
 	.sysex =		snd_opl4_sysex,
 };
 
-static int snd_opl4_seq_event_input(snd_seq_event_t *ev, int direct,
+static int snd_opl4_seq_event_input(struct snd_seq_event *ev, int direct,
 				    void *private_data, int atomic, int hop)
 {
-	opl4_t *opl4 = private_data;
+	struct snd_opl4 *opl4 = private_data;
 
 	snd_midi_process_event(&opl4_ops, ev, opl4->chset);
 	return 0;
@@ -118,20 +118,18 @@
 
 static void snd_opl4_seq_free_port(void *private_data)
 {
-	opl4_t *opl4 = private_data;
+	struct snd_opl4 *opl4 = private_data;
 
 	snd_midi_channel_free_set(opl4->chset);
 }
 
-static int snd_opl4_seq_new_device(snd_seq_device_t *dev)
+static int snd_opl4_seq_new_device(struct snd_seq_device *dev)
 {
-	opl4_t *opl4;
+	struct snd_opl4 *opl4;
 	int client;
-	snd_seq_client_callback_t callbacks;
-	snd_seq_client_info_t cinfo;
-	snd_seq_port_callback_t pcallbacks;
+	struct snd_seq_port_callback pcallbacks;
 
-	opl4 = *(opl4_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	opl4 = *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	if (!opl4)
 		return -EINVAL;
 
@@ -144,10 +142,8 @@
 	opl4->chset->private_data = opl4;
 
 	/* allocate new client */
-	memset(&callbacks, 0, sizeof(callbacks));
-	callbacks.private_data = opl4;
-	callbacks.allow_output = callbacks.allow_input = 1;
-	client = snd_seq_create_kernel_client(opl4->card, opl4->seq_dev_num, &callbacks);
+	client = snd_seq_create_kernel_client(opl4->card, opl4->seq_dev_num,
+					      "OPL4 Wavetable");
 	if (client < 0) {
 		snd_midi_channel_free_set(opl4->chset);
 		return client;
@@ -155,13 +151,6 @@
 	opl4->seq_client = client;
 	opl4->chset->client = client;
 
-	/* change name of client */
-	memset(&cinfo, 0, sizeof(cinfo));
-	cinfo.client = client;
-	cinfo.type = KERNEL_CLIENT;
-	strcpy(cinfo.name, "OPL4 Wavetable");
-	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
-
 	/* create new port */
 	memset(&pcallbacks, 0, sizeof(pcallbacks));
 	pcallbacks.owner = THIS_MODULE;
@@ -188,11 +177,11 @@
 	return 0;
 }
 
-static int snd_opl4_seq_delete_device(snd_seq_device_t *dev)
+static int snd_opl4_seq_delete_device(struct snd_seq_device *dev)
 {
-	opl4_t *opl4;
+	struct snd_opl4 *opl4;
 
-	opl4 = *(opl4_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	opl4 = *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	if (!opl4)
 		return -EINVAL;
 
@@ -205,13 +194,13 @@
 
 static int __init alsa_opl4_synth_init(void)
 {
-	static snd_seq_dev_ops_t ops = {
+	static struct snd_seq_dev_ops ops = {
 		snd_opl4_seq_new_device,
 		snd_opl4_seq_delete_device
 	};
 
 	return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_OPL4, &ops,
-					      sizeof(opl4_t*));
+					      sizeof(struct snd_opl4 *));
 }
 
 static void __exit alsa_opl4_synth_exit(void)
diff --git a/sound/drivers/opl4/opl4_synth.c b/sound/drivers/opl4/opl4_synth.c
index b146a1c99..74f6e53 100644
--- a/sound/drivers/opl4/opl4_synth.c
+++ b/sound/drivers/opl4/opl4_synth.c
@@ -270,7 +270,7 @@
 /*
  * Initializes all voices.
  */
-void snd_opl4_synth_reset(opl4_t *opl4)
+void snd_opl4_synth_reset(struct snd_opl4 *opl4)
 {
 	unsigned long flags;
 	int i;
@@ -294,7 +294,7 @@
 /*
  * Shuts down all voices.
  */
-void snd_opl4_synth_shutdown(opl4_t *opl4)
+void snd_opl4_synth_shutdown(struct snd_opl4 *opl4)
 {
 	unsigned long flags;
 	int i;
@@ -309,12 +309,12 @@
 /*
  * Executes the callback for all voices playing the specified note.
  */
-static void snd_opl4_do_for_note(opl4_t *opl4, int note, snd_midi_channel_t *chan,
-				 void (*func)(opl4_t *opl4, opl4_voice_t *voice))
+static void snd_opl4_do_for_note(struct snd_opl4 *opl4, int note, struct snd_midi_channel *chan,
+				 void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
 {
 	int i;
 	unsigned long flags;
-	opl4_voice_t *voice;
+	struct opl4_voice *voice;
 
 	spin_lock_irqsave(&opl4->reg_lock, flags);
 	for (i = 0; i < OPL4_MAX_VOICES; i++) {
@@ -329,12 +329,13 @@
 /*
  * Executes the callback for all voices of to the specified channel.
  */
-static void snd_opl4_do_for_channel(opl4_t *opl4, snd_midi_channel_t *chan,
-				    void (*func)(opl4_t *opl4, opl4_voice_t *voice))
+static void snd_opl4_do_for_channel(struct snd_opl4 *opl4,
+				    struct snd_midi_channel *chan,
+				    void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
 {
 	int i;
 	unsigned long flags;
-	opl4_voice_t *voice;
+	struct opl4_voice *voice;
 
 	spin_lock_irqsave(&opl4->reg_lock, flags);
 	for (i = 0; i < OPL4_MAX_VOICES; i++) {
@@ -349,12 +350,12 @@
 /*
  * Executes the callback for all active voices.
  */
-static void snd_opl4_do_for_all(opl4_t *opl4,
-				void (*func)(opl4_t *opl4, opl4_voice_t *voice))
+static void snd_opl4_do_for_all(struct snd_opl4 *opl4,
+				void (*func)(struct snd_opl4 *opl4, struct opl4_voice *voice))
 {
 	int i;
 	unsigned long flags;
-	opl4_voice_t *voice;
+	struct opl4_voice *voice;
 
 	spin_lock_irqsave(&opl4->reg_lock, flags);
 	for (i = 0; i < OPL4_MAX_VOICES; i++) {
@@ -365,7 +366,7 @@
 	spin_unlock_irqrestore(&opl4->reg_lock, flags);
 }
 
-static void snd_opl4_update_volume(opl4_t *opl4, opl4_voice_t *voice)
+static void snd_opl4_update_volume(struct snd_opl4 *opl4, struct opl4_voice *voice)
 {
 	int att;
 
@@ -384,7 +385,7 @@
 	voice->level_direct = 0;
 }
 
-static void snd_opl4_update_pan(opl4_t *opl4, opl4_voice_t *voice)
+static void snd_opl4_update_pan(struct snd_opl4 *opl4, struct opl4_voice *voice)
 {
 	int pan = voice->sound->panpot;
 
@@ -399,7 +400,8 @@
 	snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
 }
 
-static void snd_opl4_update_vibrato_depth(opl4_t *opl4, opl4_voice_t *voice)
+static void snd_opl4_update_vibrato_depth(struct snd_opl4 *opl4,
+					  struct opl4_voice *voice)
 {
 	int depth;
 
@@ -414,9 +416,10 @@
 		       voice->reg_lfo_vibrato);
 }
 
-static void snd_opl4_update_pitch(opl4_t *opl4, opl4_voice_t *voice)
+static void snd_opl4_update_pitch(struct snd_opl4 *opl4,
+				  struct opl4_voice *voice)
 {
-	snd_midi_channel_t *chan = voice->chan;
+	struct snd_midi_channel *chan = voice->chan;
 	int note, pitch, octave;
 
 	note = chan->drum_channel ? 60 : voice->note;
@@ -444,7 +447,8 @@
 	snd_opl4_write(opl4, OPL4_REG_F_NUMBER + voice->number, voice->reg_f_number);
 }
 
-static void snd_opl4_update_tone_parameters(opl4_t *opl4, opl4_voice_t *voice)
+static void snd_opl4_update_tone_parameters(struct snd_opl4 *opl4,
+					    struct opl4_voice *voice)
 {
 	snd_opl4_write(opl4, OPL4_REG_ATTACK_DECAY1 + voice->number,
 		       voice->sound->reg_attack_decay1);
@@ -457,17 +461,17 @@
 }
 
 /* allocate one voice */
-static opl4_voice_t *snd_opl4_get_voice(opl4_t *opl4)
+static struct opl4_voice *snd_opl4_get_voice(struct snd_opl4 *opl4)
 {
 	/* first, try to get the oldest key-off voice */
 	if (!list_empty(&opl4->off_voices))
-		return list_entry(opl4->off_voices.next, opl4_voice_t, list);
+		return list_entry(opl4->off_voices.next, struct opl4_voice, list);
 	/* then get the oldest key-on voice */
 	snd_assert(!list_empty(&opl4->on_voices), );
-	return list_entry(opl4->on_voices.next, opl4_voice_t, list);
+	return list_entry(opl4->on_voices.next, struct opl4_voice, list);
 }
 
-static void snd_opl4_wait_for_wave_headers(opl4_t *opl4)
+static void snd_opl4_wait_for_wave_headers(struct snd_opl4 *opl4)
 {
 	int timeout = 200;
 
@@ -475,12 +479,12 @@
 		udelay(10);
 }
 
-void snd_opl4_note_on(void *private_data, int note, int vel, snd_midi_channel_t *chan)
+void snd_opl4_note_on(void *private_data, int note, int vel, struct snd_midi_channel *chan)
 {
-	opl4_t *opl4 = private_data;
-	const opl4_region_ptr_t *regions;
-	opl4_voice_t *voice[2];
-	const opl4_sound_t *sound[2];
+	struct snd_opl4 *opl4 = private_data;
+	const struct opl4_region_ptr *regions;
+	struct opl4_voice *voice[2];
+	const struct opl4_sound *sound[2];
 	int voices = 0, i;
 	unsigned long flags;
 
@@ -549,7 +553,7 @@
 	spin_unlock_irqrestore(&opl4->reg_lock, flags);
 }
 
-static void snd_opl4_voice_off(opl4_t *opl4, opl4_voice_t *voice)
+static void snd_opl4_voice_off(struct snd_opl4 *opl4, struct opl4_voice *voice)
 {
 	list_del(&voice->list);
 	list_add_tail(&voice->list, &opl4->off_voices);
@@ -558,14 +562,14 @@
 	snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
 }
 
-void snd_opl4_note_off(void *private_data, int note, int vel, snd_midi_channel_t *chan)
+void snd_opl4_note_off(void *private_data, int note, int vel, struct snd_midi_channel *chan)
 {
-	opl4_t *opl4 = private_data;
+	struct snd_opl4 *opl4 = private_data;
 
 	snd_opl4_do_for_note(opl4, note, chan, snd_opl4_voice_off);
 }
 
-static void snd_opl4_terminate_voice(opl4_t *opl4, opl4_voice_t *voice)
+static void snd_opl4_terminate_voice(struct snd_opl4 *opl4, struct opl4_voice *voice)
 {
 	list_del(&voice->list);
 	list_add_tail(&voice->list, &opl4->off_voices);
@@ -574,16 +578,16 @@
 	snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
 }
 
-void snd_opl4_terminate_note(void *private_data, int note, snd_midi_channel_t *chan)
+void snd_opl4_terminate_note(void *private_data, int note, struct snd_midi_channel *chan)
 {
-	opl4_t *opl4 = private_data;
+	struct snd_opl4 *opl4 = private_data;
 
 	snd_opl4_do_for_note(opl4, note, chan, snd_opl4_terminate_voice);
 }
 
-void snd_opl4_control(void *private_data, int type, snd_midi_channel_t *chan)
+void snd_opl4_control(void *private_data, int type, struct snd_midi_channel *chan)
 {
-	opl4_t *opl4 = private_data;
+	struct snd_opl4 *opl4 = private_data;
 
 	switch (type) {
 	case MIDI_CTL_MSB_MODWHEEL:
@@ -621,9 +625,9 @@
 }
 
 void snd_opl4_sysex(void *private_data, unsigned char *buf, int len,
-		    int parsed, snd_midi_channel_set_t *chset)
+		    int parsed, struct snd_midi_channel_set *chset)
 {
-	opl4_t *opl4 = private_data;
+	struct snd_opl4 *opl4 = private_data;
 
 	if (parsed == SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME)
 		snd_opl4_do_for_all(opl4, snd_opl4_update_volume);
diff --git a/sound/drivers/opl4/yrw801.c b/sound/drivers/opl4/yrw801.c
index a51174d..6c33549 100644
--- a/sound/drivers/opl4/yrw801.c
+++ b/sound/drivers/opl4/yrw801.c
@@ -33,7 +33,7 @@
 
 #include "opl4_local.h"
 
-int snd_yrw801_detect(opl4_t *opl4)
+int snd_yrw801_detect(struct snd_opl4 *opl4)
 {
 	char buf[15];
 
@@ -54,7 +54,7 @@
  * by this driver.
  */
 
-static const opl4_region_t regions_00[] = { /* Acoustic Grand Piano */
+static const struct opl4_region regions_00[] = { /* Acoustic Grand Piano */
 	{0x14, 0x27, {0x12c,7474,100, 0,0,0x00,0xc8,0x20,0xf2,0x13,0x08,0x0}},
 	{0x28, 0x2d, {0x12d,6816,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
 	{0x2e, 0x33, {0x12e,5899,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
@@ -66,7 +66,7 @@
 	{0x53, 0x58, {0x134,1444,100, 0,0,0x07,0xc8,0x20,0xf3,0x14,0x18,0x0}},
 	{0x59, 0x6d, {0x135,1915,100, 0,0,0x00,0xc8,0x20,0xf4,0x15,0x08,0x0}}
 };
-static const opl4_region_t regions_01[] = { /* Bright Acoustic Piano */
+static const struct opl4_region regions_01[] = { /* Bright Acoustic Piano */
 	{0x14, 0x2d, {0x12c,7474,100, 0,0,0x00,0xc8,0x20,0xf2,0x13,0x08,0x0}},
 	{0x2e, 0x33, {0x12d,6816,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
 	{0x34, 0x39, {0x12e,5899,100, 0,0,0x00,0xc8,0x20,0xf2,0x14,0x08,0x0}},
@@ -78,7 +78,7 @@
 	{0x59, 0x5e, {0x134,1444,100, 0,0,0x0a,0xc8,0x20,0xf3,0x14,0x18,0x0}},
 	{0x5f, 0x6d, {0x135,1915,100, 0,0,0x00,0xc8,0x20,0xf4,0x15,0x08,0x0}}
 };
-static const opl4_region_t regions_02[] = { /* Electric Grand Piano */
+static const struct opl4_region regions_02[] = { /* Electric Grand Piano */
 	{0x14, 0x2d, {0x12c,7476,100, 1,0,0x00,0xae,0x20,0xf2,0x13,0x07,0x0}},
 	{0x2e, 0x33, {0x12d,6818,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
 	{0x34, 0x39, {0x12e,5901,100, 1,0,0x00,0xae,0x20,0xf2,0x14,0x07,0x0}},
@@ -91,7 +91,7 @@
 	{0x5f, 0x6d, {0x135,1917,100, 1,0,0x00,0xae,0x20,0xf4,0x15,0x07,0x0}},
 	{0x00, 0x7f, {0x06c,6375,100,-1,0,0x00,0xc2,0x28,0xf4,0x23,0x18,0x0}}
 };
-static const opl4_region_t regions_03[] = { /* Honky-Tonk Piano */
+static const struct opl4_region regions_03[] = { /* Honky-Tonk Piano */
 	{0x14, 0x27, {0x12c,7474,100, 0,0,0x00,0xb4,0x20,0xf2,0x13,0x08,0x0}},
 	{0x28, 0x2d, {0x12d,6816,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
 	{0x2e, 0x33, {0x12e,5899,100, 0,0,0x00,0xb4,0x20,0xf2,0x14,0x08,0x0}},
@@ -113,11 +113,11 @@
 	{0x53, 0x58, {0x134,1457,100, 0,0,0x01,0xb4,0x20,0xf3,0x14,0x18,0x0}},
 	{0x59, 0x6d, {0x135,1903,100, 0,0,0x00,0xb4,0x20,0xf4,0x15,0x08,0x0}}
 };
-static const opl4_region_t regions_04[] = { /* Electric Piano 1 */
+static const struct opl4_region regions_04[] = { /* Electric Piano 1 */
 	{0x15, 0x6c, {0x00b,6570,100, 0,0,0x00,0x28,0x38,0xf0,0x00,0x0c,0x0}},
 	{0x00, 0x7f, {0x06c,6375,100, 0,2,0x00,0xb0,0x22,0xf4,0x23,0x19,0x0}}
 };
-static const opl4_region_t regions_05[] = { /* Electric Piano 2 */
+static const struct opl4_region regions_05[] = { /* Electric Piano 2 */
 	{0x14, 0x27, {0x12c,7476,100, 0,3,0x00,0xa2,0x1b,0xf2,0x13,0x08,0x0}},
 	{0x28, 0x2d, {0x12d,6818,100, 0,3,0x00,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
 	{0x2e, 0x33, {0x12e,5901,100, 0,3,0x00,0xa2,0x1b,0xf2,0x14,0x08,0x0}},
@@ -139,103 +139,103 @@
 	{0x59, 0x5e, {0x134,1442,100, 0,0,0x0a,0xa2,0x18,0xf3,0x14,0x18,0x0}},
 	{0x5f, 0x6d, {0x135,1913,100, 0,0,0x00,0xa2,0x18,0xf4,0x15,0x08,0x0}}
 };
-static const opl4_region_t regions_06[] = { /* Harpsichord */
+static const struct opl4_region regions_06[] = { /* Harpsichord */
 	{0x15, 0x39, {0x080,5158,100, 0,0,0x00,0xb2,0x20,0xf5,0x24,0x19,0x0}},
 	{0x3a, 0x3f, {0x081,4408,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x09,0x0}},
 	{0x40, 0x45, {0x082,3622,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x09,0x0}},
 	{0x46, 0x4d, {0x083,2843,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x19,0x0}},
 	{0x4e, 0x6c, {0x084,1307,100, 0,0,0x00,0xb2,0x20,0xf5,0x25,0x29,0x0}}
 };
-static const opl4_region_t regions_07[] = { /* Clavinet */
+static const struct opl4_region regions_07[] = { /* Clavinet */
 	{0x15, 0x51, {0x027,5009,100, 0,0,0x00,0xd2,0x28,0xf5,0x13,0x2b,0x0}},
 	{0x52, 0x6c, {0x028,3495,100, 0,0,0x00,0xd2,0x28,0xf5,0x13,0x3b,0x0}}
 };
-static const opl4_region_t regions_08[] = { /* Celesta */
+static const struct opl4_region regions_08[] = { /* Celesta */
 	{0x15, 0x6c, {0x02b,3267,100, 0,0,0x00,0xdc,0x20,0xf4,0x15,0x07,0x3}}
 };
-static const opl4_region_t regions_09[] = { /* Glockenspiel */
+static const struct opl4_region regions_09[] = { /* Glockenspiel */
 	{0x15, 0x78, {0x0f3, 285,100, 0,0,0x00,0xc2,0x28,0xf6,0x25,0x25,0x0}}
 };
-static const opl4_region_t regions_0a[] = { /* Music Box */
+static const struct opl4_region regions_0a[] = { /* Music Box */
 	{0x15, 0x6c, {0x0f3,3362,100, 0,0,0x00,0xb6,0x20,0xa6,0x25,0x25,0x0}},
 	{0x15, 0x6c, {0x101,4773,100, 0,0,0x00,0xaa,0x20,0xd4,0x14,0x16,0x0}}
 };
-static const opl4_region_t regions_0b[] = { /* Vibraphone */
+static const struct opl4_region regions_0b[] = { /* Vibraphone */
 	{0x15, 0x6c, {0x101,4778,100, 0,0,0x00,0xc0,0x28,0xf4,0x14,0x16,0x4}}
 };
-static const opl4_region_t regions_0c[] = { /* Marimba */
+static const struct opl4_region regions_0c[] = { /* Marimba */
 	{0x15, 0x3f, {0x0f4,4778,100, 0,0,0x00,0xc4,0x38,0xf7,0x47,0x08,0x0}},
 	{0x40, 0x4c, {0x0f5,3217,100, 0,0,0x00,0xc4,0x38,0xf7,0x47,0x08,0x0}},
 	{0x4d, 0x5a, {0x0f5,3217,100, 0,0,0x00,0xc4,0x38,0xf7,0x48,0x08,0x0}},
 	{0x5b, 0x7f, {0x0f5,3218,100, 0,0,0x00,0xc4,0x38,0xf7,0x48,0x18,0x0}}
 };
-static const opl4_region_t regions_0d[] = { /* Xylophone */
+static const struct opl4_region regions_0d[] = { /* Xylophone */
 	{0x00, 0x7f, {0x136,1729,100, 0,0,0x00,0xd2,0x38,0xf0,0x06,0x36,0x0}}
 };
-static const opl4_region_t regions_0e[] = { /* Tubular Bell */
+static const struct opl4_region regions_0e[] = { /* Tubular Bell */
 	{0x01, 0x7f, {0x0ff,3999,100, 0,1,0x00,0x90,0x21,0xf4,0xa3,0x25,0x1}}
 };
-static const opl4_region_t regions_0f[] = { /* Dulcimer */
+static const struct opl4_region regions_0f[] = { /* Dulcimer */
 	{0x00, 0x7f, {0x03f,4236,100, 0,1,0x00,0xbc,0x29,0xf5,0x16,0x07,0x0}},
 	{0x00, 0x7f, {0x040,4236,100, 0,2,0x0e,0x94,0x2a,0xf5,0x16,0x07,0x0}}
 };
-static const opl4_region_t regions_10[] = { /* Drawbar Organ */
+static const struct opl4_region regions_10[] = { /* Drawbar Organ */
 	{0x01, 0x7f, {0x08e,4394,100, 0,2,0x14,0xc2,0x3a,0xf0,0x00,0x0a,0x0}}
 };
-static const opl4_region_t regions_11[] = { /* Percussive Organ */
+static const struct opl4_region regions_11[] = { /* Percussive Organ */
 	{0x15, 0x3b, {0x08c,6062,100, 0,3,0x00,0xbe,0x3b,0xf0,0x00,0x09,0x0}},
 	{0x3c, 0x6c, {0x08d,2984,100, 0,3,0x00,0xbe,0x3b,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_12[] = { /* Rock Organ */
+static const struct opl4_region regions_12[] = { /* Rock Organ */
 	{0x15, 0x30, {0x128,6574,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
 	{0x31, 0x3c, {0x129,5040,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
 	{0x3d, 0x48, {0x12a,3498,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
 	{0x49, 0x54, {0x12b,1957,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}},
 	{0x55, 0x6c, {0x127, 423,100, 0,1,0x00,0xcc,0x39,0xf0,0x00,0x0a,0x0}}
 };
-static const opl4_region_t regions_13[] = { /* Church Organ */
+static const struct opl4_region regions_13[] = { /* Church Organ */
 	{0x15, 0x29, {0x087,7466,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
 	{0x2a, 0x30, {0x088,6456,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
 	{0x31, 0x38, {0x089,5428,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
 	{0x39, 0x41, {0x08a,4408,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}},
 	{0x42, 0x6c, {0x08b,3406,100, 0,1,0x00,0xc4,0x11,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_14[] = { /* Reed Organ */
+static const struct opl4_region regions_14[] = { /* Reed Organ */
 	{0x00, 0x53, {0x0ac,5570,100, 0,0,0x06,0xc0,0x38,0xf0,0x00,0x09,0x1}},
 	{0x54, 0x7f, {0x0ad,2497,100, 0,0,0x00,0xc0,0x38,0xf0,0x00,0x09,0x1}}
 };
-static const opl4_region_t regions_15[] = { /* Accordion */
+static const struct opl4_region regions_15[] = { /* Accordion */
 	{0x15, 0x4c, {0x006,4261,100, 0,2,0x00,0xa4,0x22,0x90,0x00,0x09,0x0}},
 	{0x4d, 0x6c, {0x007,1530,100, 0,2,0x00,0xa4,0x22,0x90,0x00,0x09,0x0}},
 	{0x15, 0x6c, {0x070,4391,100, 0,3,0x00,0x8a,0x23,0xa0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_16[] = { /* Harmonica */
+static const struct opl4_region regions_16[] = { /* Harmonica */
 	{0x15, 0x6c, {0x070,4408,100, 0,0,0x00,0xae,0x30,0xa0,0x00,0x09,0x2}}
 };
-static const opl4_region_t regions_17[] = { /* Tango Accordion */
+static const struct opl4_region regions_17[] = { /* Tango Accordion */
 	{0x00, 0x53, {0x0ac,5573,100, 0,0,0x00,0xae,0x38,0xf0,0x00,0x09,0x0}},
 	{0x54, 0x7f, {0x0ad,2500,100, 0,0,0x00,0xae,0x38,0xf0,0x00,0x09,0x0}},
 	{0x15, 0x6c, {0x041,8479,100, 0,2,0x00,0x6a,0x3a,0x75,0x20,0x0a,0x0}}
 };
-static const opl4_region_t regions_18[] = { /* Nylon Guitar */
+static const struct opl4_region regions_18[] = { /* Nylon Guitar */
 	{0x15, 0x2f, {0x0b3,6964,100, 0,0,0x05,0xca,0x28,0xf5,0x34,0x09,0x0}},
 	{0x30, 0x36, {0x0b7,5567,100, 0,0,0x0c,0xca,0x28,0xf5,0x34,0x09,0x0}},
 	{0x37, 0x3c, {0x0b5,4653,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}},
 	{0x3d, 0x43, {0x0b4,3892,100, 0,0,0x00,0xca,0x28,0xf6,0x35,0x09,0x0}},
 	{0x44, 0x60, {0x0b6,2723,100, 0,0,0x00,0xca,0x28,0xf6,0x35,0x19,0x0}}
 };
-static const opl4_region_t regions_19[] = { /* Steel Guitar */
+static const struct opl4_region regions_19[] = { /* Steel Guitar */
 	{0x15, 0x31, {0x00c,6937,100, 0,0,0x00,0xbc,0x28,0xf0,0x04,0x19,0x0}},
 	{0x32, 0x38, {0x00d,5410,100, 0,0,0x00,0xbc,0x28,0xf0,0x05,0x09,0x0}},
 	{0x39, 0x47, {0x00e,4379,100, 0,0,0x00,0xbc,0x28,0xf5,0x94,0x09,0x0}},
 	{0x48, 0x6c, {0x00f,2843,100, 0,0,0x00,0xbc,0x28,0xf6,0x95,0x09,0x0}}
 };
-static const opl4_region_t regions_1a[] = { /* Jazz Guitar */
+static const struct opl4_region regions_1a[] = { /* Jazz Guitar */
 	{0x15, 0x31, {0x05a,6832,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}},
 	{0x32, 0x3f, {0x05b,4897,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}},
 	{0x40, 0x6c, {0x05c,3218,100, 0,0,0x00,0xca,0x28,0xf6,0x34,0x09,0x0}}
 };
-static const opl4_region_t regions_1b[] = { /* Clean Guitar */
+static const struct opl4_region regions_1b[] = { /* Clean Guitar */
 	{0x15, 0x2c, {0x061,7053,100, 0,1,0x00,0xb4,0x29,0xf5,0x54,0x0a,0x0}},
 	{0x2d, 0x31, {0x060,6434,100, 0,1,0x00,0xb4,0x29,0xf5,0x54,0x0a,0x0}},
 	{0x32, 0x38, {0x063,5764,100, 0,1,0x00,0xbe,0x29,0xf5,0x55,0x0a,0x0}},
@@ -245,14 +245,14 @@
 	{0x4c, 0x54, {0x066,2462,100, 0,1,0x00,0xb4,0x29,0xf5,0x55,0x2a,0x0}},
 	{0x55, 0x6c, {0x067,1307,100, 0,1,0x00,0xb4,0x29,0xf6,0x56,0x0a,0x0}}
 };
-static const opl4_region_t regions_1c[] = { /* Muted Guitar */
+static const struct opl4_region regions_1c[] = { /* Muted Guitar */
 	{0x01, 0x7f, {0x068,4408,100, 0,0,0x00,0xcc,0x28,0xf6,0x15,0x09,0x0}}
 };
-static const opl4_region_t regions_1d[] = { /* Overdriven Guitar */
+static const struct opl4_region regions_1d[] = { /* Overdriven Guitar */
 	{0x00, 0x40, {0x0a5,6589,100, 0,1,0x00,0xc0,0x29,0xf2,0x11,0x09,0x0}},
 	{0x41, 0x7f, {0x0a6,5428,100, 0,1,0x00,0xc0,0x29,0xf2,0x11,0x09,0x0}}
 };
-static const opl4_region_t regions_1e[] = { /* Distortion Guitar */
+static const struct opl4_region regions_1e[] = { /* Distortion Guitar */
 	{0x15, 0x2a, {0x051,6928,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
 	{0x2b, 0x2e, {0x052,6433,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
 	{0x2f, 0x32, {0x053,5944,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
@@ -263,44 +263,44 @@
 	{0x43, 0x46, {0x058,3361,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}},
 	{0x47, 0x6c, {0x059,2784,100, 0,1,0x00,0xbc,0x21,0xa2,0x12,0x0a,0x0}}
 };
-static const opl4_region_t regions_1f[] = { /* Guitar Harmonics */
+static const struct opl4_region regions_1f[] = { /* Guitar Harmonics */
 	{0x15, 0x44, {0x05e,5499,100, 0,0,0x00,0xce,0x28,0xf4,0x24,0x09,0x0}},
 	{0x45, 0x49, {0x05d,4850,100, 0,0,0x00,0xe2,0x28,0xf4,0x24,0x09,0x0}},
 	{0x4a, 0x6c, {0x05f,4259,100, 0,0,0x00,0xce,0x28,0xf4,0x24,0x09,0x0}}
 };
-static const opl4_region_t regions_20[] = { /* Acoustic Bass */
+static const struct opl4_region regions_20[] = { /* Acoustic Bass */
 	{0x15, 0x30, {0x004,8053,100, 0,0,0x00,0xe2,0x18,0xf5,0x15,0x09,0x0}},
 	{0x31, 0x6c, {0x005,4754,100, 0,0,0x00,0xe2,0x18,0xf5,0x15,0x09,0x0}}
 };
-static const opl4_region_t regions_21[] = { /* Fingered Bass */
+static const struct opl4_region regions_21[] = { /* Fingered Bass */
 	{0x01, 0x20, {0x04a,8762,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}},
 	{0x21, 0x25, {0x04b,8114,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}},
 	{0x26, 0x2a, {0x04c,7475,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}},
 	{0x2b, 0x7f, {0x04d,6841,100, 0,0,0x00,0xde,0x18,0xf6,0x14,0x09,0x0}}
 };
-static const opl4_region_t regions_22[] = { /* Picked Bass */
+static const struct opl4_region regions_22[] = { /* Picked Bass */
 	{0x15, 0x23, {0x04f,7954,100, 0,0,0x00,0xcc,0x18,0xf3,0x90,0x0a,0x0}},
 	{0x24, 0x2a, {0x050,7318,100, 0,0,0x05,0xcc,0x18,0xf3,0x90,0x1a,0x0}},
 	{0x2b, 0x2f, {0x06b,6654,100, 0,0,0x00,0xcc,0x18,0xf3,0x90,0x2a,0x0}},
 	{0x30, 0x47, {0x069,6031,100, 0,0,0x00,0xcc,0x18,0xf5,0xb0,0x0a,0x0}},
 	{0x48, 0x6c, {0x06a,5393,100, 0,0,0x00,0xcc,0x18,0xf5,0xb0,0x0a,0x0}}
 };
-static const opl4_region_t regions_23[] = { /* Fretless Bass */
+static const struct opl4_region regions_23[] = { /* Fretless Bass */
 	{0x01, 0x7f, {0x04e,5297,100, 0,0,0x00,0xd2,0x10,0xf3,0x63,0x19,0x0}}
 };
-static const opl4_region_t regions_24[] = { /* Slap Bass 1 */
+static const struct opl4_region regions_24[] = { /* Slap Bass 1 */
 	{0x15, 0x6c, {0x0a3,7606,100, 0,1,0x00,0xde,0x19,0xf5,0x32,0x1a,0x0}}
 };
-static const opl4_region_t regions_25[] = { /* Slap Bass 2 */
+static const struct opl4_region regions_25[] = { /* Slap Bass 2 */
 	{0x01, 0x7f, {0x0a2,6694,100, 0,0,0x00,0xda,0x20,0xb0,0x02,0x09,0x0}}
 };
-static const opl4_region_t regions_26[] = { /* Synth Bass 1 */
+static const struct opl4_region regions_26[] = { /* Synth Bass 1 */
 	{0x15, 0x6c, {0x0be,7466,100, 0,1,0x00,0xb8,0x39,0xf4,0x14,0x09,0x0}}
 };
-static const opl4_region_t regions_27[] = { /* Synth Bass 2 */
+static const struct opl4_region regions_27[] = { /* Synth Bass 2 */
 	{0x00, 0x7f, {0x117,8103,100, 0,1,0x00,0xca,0x39,0xf3,0x50,0x08,0x0}}
 };
-static const opl4_region_t regions_28[] = { /* Violin */
+static const struct opl4_region regions_28[] = { /* Violin */
 	{0x15, 0x3a, {0x105,5158,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
 	{0x3b, 0x3f, {0x102,4754,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
 	{0x40, 0x41, {0x106,4132,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
@@ -312,7 +312,7 @@
 	{0x4f, 0x51, {0x10d,2166,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}},
 	{0x52, 0x6c, {0x109,1825,100, 0,3,0x00,0xcc,0x3b,0xf3,0x20,0x09,0x0}}
 };
-static const opl4_region_t regions_29[] = { /* Viola */
+static const struct opl4_region regions_29[] = { /* Viola */
 	{0x15, 0x32, {0x103,5780,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
 	{0x33, 0x35, {0x104,5534,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
 	{0x36, 0x38, {0x105,5158,100, 0,3,0x00,0xc4,0x3b,0xa3,0x20,0x09,0x0}},
@@ -326,76 +326,76 @@
 	{0x4d, 0x4f, {0x10d,2166,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}},
 	{0x50, 0x6c, {0x109,1825,100, 0,3,0x00,0xd0,0x3b,0xa3,0x20,0x09,0x0}}
 };
-static const opl4_region_t regions_2a[] = { /* Cello */
+static const struct opl4_region regions_2a[] = { /* Cello */
 	{0x15, 0x2d, {0x112,6545,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x08,0x0}},
 	{0x2e, 0x37, {0x113,5764,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x08,0x0}},
 	{0x38, 0x3e, {0x115,4378,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x18,0x0}},
 	{0x3f, 0x44, {0x116,3998,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x18,0x0}},
 	{0x45, 0x6c, {0x114,3218,100, 0,3,0x00,0xc0,0x33,0xa0,0x00,0x18,0x0}}
 };
-static const opl4_region_t regions_2b[] = { /* Contrabass */
+static const struct opl4_region regions_2b[] = { /* Contrabass */
 	{0x15, 0x29, {0x110,7713,100, 0,1,0x00,0xc2,0x19,0x90,0x00,0x09,0x0}},
 	{0x2a, 0x6c, {0x111,6162,100, 0,1,0x00,0xc2,0x19,0x90,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_2c[] = { /* Tremolo Strings */
+static const struct opl4_region regions_2c[] = { /* Tremolo Strings */
 	{0x15, 0x3b, {0x0b0,4810,100, 0,0,0x0a,0xde,0x38,0xf0,0x00,0x07,0x6}},
 	{0x3c, 0x41, {0x035,4035,100, 0,0,0x05,0xde,0x38,0xf0,0x00,0x07,0x6}},
 	{0x42, 0x47, {0x033,3129,100, 0,0,0x05,0xde,0x38,0xf0,0x00,0x07,0x6}},
 	{0x48, 0x52, {0x034,2625,100, 0,0,0x05,0xde,0x38,0xf0,0x00,0x07,0x6}},
 	{0x53, 0x6c, {0x0af, 936,100, 0,0,0x00,0xde,0x38,0xf0,0x00,0x07,0x6}}
 };
-static const opl4_region_t regions_2d[] = { /* Pizzicato Strings */
+static const struct opl4_region regions_2d[] = { /* Pizzicato Strings */
 	{0x15, 0x32, {0x0b8,6186,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}},
 	{0x33, 0x3b, {0x0b9,5031,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}},
 	{0x3c, 0x42, {0x0bb,4146,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}},
 	{0x43, 0x48, {0x0ba,3245,100, 0,0,0x00,0xc2,0x28,0xf0,0x00,0x05,0x0}},
 	{0x49, 0x6c, {0x0bc,2352,100, 0,0,0x00,0xbc,0x28,0xf0,0x00,0x05,0x0}}
 };
-static const opl4_region_t regions_2e[] = { /* Harp */
+static const struct opl4_region regions_2e[] = { /* Harp */
 	{0x15, 0x46, {0x07e,3740,100, 0,1,0x00,0xd2,0x29,0xf5,0x25,0x07,0x0}},
 	{0x47, 0x6c, {0x07f,2319,100, 0,1,0x00,0xd2,0x29,0xf5,0x25,0x07,0x0}}
 };
-static const opl4_region_t regions_2f[] = { /* Timpani */
+static const struct opl4_region regions_2f[] = { /* Timpani */
 	{0x15, 0x6c, {0x100,6570,100, 0,0,0x00,0xf8,0x28,0xf0,0x05,0x16,0x0}}
 };
-static const opl4_region_t regions_30[] = { /* Strings */
+static const struct opl4_region regions_30[] = { /* Strings */
 	{0x15, 0x3b, {0x13c,4806,100, 0,0,0x00,0xc8,0x20,0x80,0x00,0x07,0x0}},
 	{0x3c, 0x41, {0x13e,4035,100, 0,0,0x00,0xc8,0x20,0x80,0x00,0x07,0x0}},
 	{0x42, 0x47, {0x13d,3122,100, 0,0,0x00,0xc8,0x20,0x80,0x00,0x07,0x0}},
 	{0x48, 0x52, {0x13f,2629,100, 0,0,0x00,0xbe,0x20,0x80,0x00,0x07,0x0}},
 	{0x53, 0x6c, {0x140, 950,100, 0,0,0x00,0xbe,0x20,0x80,0x00,0x07,0x0}}
 };
-static const opl4_region_t regions_31[] = { /* Slow Strings */
+static const struct opl4_region regions_31[] = { /* Slow Strings */
 	{0x15, 0x3b, {0x0b0,4810,100, 0,1,0x0a,0xbe,0x19,0xf0,0x00,0x07,0x0}},
 	{0x3c, 0x41, {0x035,4035,100, 0,1,0x05,0xbe,0x19,0xf0,0x00,0x07,0x0}},
 	{0x42, 0x47, {0x033,3129,100, 0,1,0x05,0xbe,0x19,0xf0,0x00,0x07,0x0}},
 	{0x48, 0x52, {0x034,2625,100, 0,1,0x05,0xbe,0x19,0xf0,0x00,0x07,0x0}},
 	{0x53, 0x6c, {0x0af, 936,100, 0,1,0x00,0xbe,0x19,0xf0,0x00,0x07,0x0}}
 };
-static const opl4_region_t regions_32[] = { /* Synth Strings 1 */
+static const struct opl4_region regions_32[] = { /* Synth Strings 1 */
 	{0x05, 0x71, {0x002,6045,100,-2,0,0x00,0xa6,0x20,0x93,0x22,0x06,0x0}},
 	{0x15, 0x6c, {0x0ae,3261,100, 2,0,0x00,0xc6,0x20,0x70,0x01,0x06,0x0}}
 };
-static const opl4_region_t regions_33[] = { /* Synth Strings 2 */
+static const struct opl4_region regions_33[] = { /* Synth Strings 2 */
 	{0x15, 0x6c, {0x002,4513,100, 5,1,0x00,0xb4,0x19,0x70,0x00,0x06,0x0}},
 	{0x15, 0x6c, {0x002,4501,100,-5,1,0x00,0xb4,0x19,0x70,0x00,0x06,0x0}}
 };
-static const opl4_region_t regions_34[] = { /* Choir Aahs */
+static const struct opl4_region regions_34[] = { /* Choir Aahs */
 	{0x15, 0x3a, {0x018,5010,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}},
 	{0x3b, 0x40, {0x019,4370,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}},
 	{0x41, 0x47, {0x01a,3478,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}},
 	{0x48, 0x6c, {0x01b,2197,100, 0,2,0x00,0xc2,0x1a,0x70,0x00,0x08,0x0}}
 };
-static const opl4_region_t regions_35[] = { /* Voice Oohs */
+static const struct opl4_region regions_35[] = { /* Voice Oohs */
 	{0x15, 0x6c, {0x029,3596,100, 0,0,0x00,0xe6,0x20,0xf7,0x20,0x08,0x0}}
 };
-static const opl4_region_t regions_36[] = { /* Synth Voice */
+static const struct opl4_region regions_36[] = { /* Synth Voice */
 	{0x15, 0x6c, {0x02a,3482,100, 0,1,0x00,0xc2,0x19,0x85,0x21,0x07,0x0}}
 };
-static const opl4_region_t regions_37[] = { /* Orchestra Hit */
+static const struct opl4_region regions_37[] = { /* Orchestra Hit */
 	{0x15, 0x6c, {0x049,4394,100, 0,0,0x00,0xfe,0x30,0x80,0x05,0x05,0x0}}
 };
-static const opl4_region_t regions_38[] = { /* Trumpet */
+static const struct opl4_region regions_38[] = { /* Trumpet */
 	{0x15, 0x3c, {0x0f6,4706,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
 	{0x3d, 0x43, {0x0f8,3894,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
 	{0x44, 0x48, {0x0f7,3118,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
@@ -403,28 +403,28 @@
 	{0x4f, 0x55, {0x0f9,1634,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}},
 	{0x56, 0x6c, {0x0fb, 786,100, 0,2,0x00,0xd6,0x32,0xf3,0x20,0x0a,0x0}}
 };
-static const opl4_region_t regions_39[] = { /* Trombone */
+static const struct opl4_region regions_39[] = { /* Trombone */
 	{0x15, 0x3a, {0x0f0,5053,100, 0,1,0x00,0xd6,0x21,0xf0,0x00,0x09,0x0}},
 	{0x3b, 0x3f, {0x0f1,4290,100, 0,1,0x00,0xd6,0x21,0xf0,0x00,0x09,0x0}},
 	{0x40, 0x6c, {0x0f2,3580,100, 0,1,0x00,0xd6,0x21,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_3a[] = { /* Tuba */
+static const struct opl4_region regions_3a[] = { /* Tuba */
 	{0x15, 0x2d, {0x085,7096,100, 0,1,0x00,0xde,0x21,0xf5,0x10,0x09,0x0}},
 	{0x2e, 0x6c, {0x086,6014,100, 0,1,0x00,0xde,0x21,0xf5,0x10,0x09,0x0}}
 };
-static const opl4_region_t regions_3b[] = { /* Muted Trumpet */
+static const struct opl4_region regions_3b[] = { /* Muted Trumpet */
 	{0x15, 0x45, {0x0b1,4135,100, 0,0,0x00,0xcc,0x28,0xf3,0x10,0x0a,0x1}},
 	{0x46, 0x6c, {0x0b2,2599,100, 0,0,0x00,0xcc,0x28,0x83,0x10,0x0a,0x1}}
 };
-static const opl4_region_t regions_3c[] = { /* French Horns */
+static const struct opl4_region regions_3c[] = { /* French Horns */
 	{0x15, 0x49, {0x07c,3624,100, 0,2,0x00,0xd0,0x1a,0xf0,0x00,0x09,0x0}},
 	{0x4a, 0x6c, {0x07d,2664,100, 0,2,0x00,0xd0,0x1a,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_3d[] = { /* Brass Section */
+static const struct opl4_region regions_3d[] = { /* Brass Section */
 	{0x15, 0x42, {0x0fc,4375,100, 0,0,0x00,0xd6,0x28,0xf0,0x00,0x0a,0x0}},
 	{0x43, 0x6c, {0x0fd,2854,100, 0,0,0x00,0xd6,0x28,0xf0,0x00,0x0a,0x0}}
 };
-static const opl4_region_t regions_3e[] = { /* Synth Brass 1 */
+static const struct opl4_region regions_3e[] = { /* Synth Brass 1 */
 	{0x01, 0x27, {0x0d3,9094,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
 	{0x28, 0x2d, {0x0da,8335,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
 	{0x2e, 0x33, {0x0d4,7558,100,-1,0,0x00,0xbe,0x18,0xa5,0x11,0x08,0x0}},
@@ -450,7 +450,7 @@
 	{0x5e, 0x64, {0x122,1421,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}},
 	{0x65, 0x7f, {0x123,-115,100, 1,1,0x00,0xbe,0x19,0x85,0x23,0x08,0x0}}
 };
-static const opl4_region_t regions_3f[] = { /* Synth Brass 2 */
+static const struct opl4_region regions_3f[] = { /* Synth Brass 2 */
 	{0x01, 0x27, {0x118,9113,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
 	{0x28, 0x2d, {0x119,8350,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
 	{0x2e, 0x33, {0x11a,7575,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
@@ -465,7 +465,7 @@
 	{0x65, 0x7f, {0x123,-105,100, 3,6,0x00,0xae,0x26,0x85,0x23,0x08,0x0}},
 	{0x00, 0x7f, {0x124,4034,100,-3,2,0x00,0xea,0x22,0x85,0x23,0x08,0x0}}
 };
-static const opl4_region_t regions_40[] = { /* Soprano Sax */
+static const struct opl4_region regions_40[] = { /* Soprano Sax */
 	{0x15, 0x3f, {0x0e3,4228,100, 0,1,0x00,0xc8,0x21,0xf5,0x20,0x0a,0x0}},
 	{0x40, 0x45, {0x0e4,3495,100, 0,1,0x00,0xc8,0x21,0xf5,0x20,0x0a,0x0}},
 	{0x46, 0x4b, {0x0e5,2660,100, 0,1,0x00,0xd6,0x21,0xf5,0x20,0x0a,0x0}},
@@ -473,7 +473,7 @@
 	{0x52, 0x59, {0x0e7,1186,100, 0,1,0x00,0xd6,0x21,0xf5,0x20,0x0a,0x0}},
 	{0x59, 0x6c, {0x0e8,1730,100, 0,1,0x00,0xc8,0x21,0xf5,0x20,0x0a,0x0}}
 };
-static const opl4_region_t regions_41[] = { /* Alto Sax */
+static const struct opl4_region regions_41[] = { /* Alto Sax */
 	{0x15, 0x32, {0x092,6204,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
 	{0x33, 0x35, {0x096,5812,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
 	{0x36, 0x3a, {0x099,5318,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
@@ -488,7 +488,7 @@
 	{0x51, 0x53, {0x091,2088,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}},
 	{0x54, 0x6c, {0x095,1732,100, 0,1,0x00,0xbe,0x19,0xf5,0x20,0x0b,0x0}}
 };
-static const opl4_region_t regions_42[] = { /* Tenor Sax */
+static const struct opl4_region regions_42[] = { /* Tenor Sax */
 	{0x24, 0x30, {0x0e9,6301,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
 	{0x31, 0x34, {0x0ea,5781,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
 	{0x35, 0x3a, {0x0eb,5053,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
@@ -497,13 +497,13 @@
 	{0x48, 0x51, {0x0ee,2462,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}},
 	{0x52, 0x6c, {0x0ef,1421,100, 0,1,0x00,0xbc,0x19,0xf4,0x10,0x0b,0x0}}
 };
-static const opl4_region_t regions_43[] = { /* Baritone Sax */
+static const struct opl4_region regions_43[] = { /* Baritone Sax */
 	{0x15, 0x2d, {0x0df,6714,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}},
 	{0x2e, 0x34, {0x0e1,5552,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}},
 	{0x35, 0x39, {0x0e2,5178,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}},
 	{0x3a, 0x6c, {0x0e0,4437,100, 0,1,0x00,0xce,0x19,0xf0,0x00,0x0a,0x0}}
 };
-static const opl4_region_t regions_44[] = { /* Oboe */
+static const struct opl4_region regions_44[] = { /* Oboe */
 	{0x15, 0x3c, {0x042,4493,100, 0,1,0x00,0xe6,0x39,0xf4,0x10,0x0a,0x0}},
 	{0x3d, 0x43, {0x044,3702,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
 	{0x44, 0x49, {0x043,2956,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
@@ -511,55 +511,55 @@
 	{0x50, 0x55, {0x045,1420,100, 0,1,0x00,0xdc,0x39,0xf4,0x10,0x0a,0x0}},
 	{0x56, 0x6c, {0x047, 630,100, 0,1,0x00,0xe6,0x39,0xf4,0x10,0x0a,0x0}}
 };
-static const opl4_region_t regions_45[] = { /* English Horn */
+static const struct opl4_region regions_45[] = { /* English Horn */
 	{0x15, 0x38, {0x03c,5098,100, 0,1,0x00,0xc4,0x31,0xf0,0x00,0x09,0x0}},
 	{0x39, 0x3e, {0x03b,4291,100, 0,1,0x00,0xc4,0x31,0xf0,0x00,0x09,0x0}},
 	{0x3f, 0x6c, {0x03d,3540,100, 0,1,0x00,0xc4,0x31,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_46[] = { /* Bassoon */
+static const struct opl4_region regions_46[] = { /* Bassoon */
 	{0x15, 0x22, {0x038,7833,100, 0,1,0x00,0xc6,0x31,0xf0,0x00,0x0b,0x0}},
 	{0x23, 0x2e, {0x03a,7070,100, 0,1,0x00,0xc6,0x31,0xf0,0x00,0x0b,0x0}},
 	{0x2f, 0x6c, {0x039,6302,100, 0,1,0x00,0xc6,0x31,0xf0,0x00,0x0b,0x0}}
 };
-static const opl4_region_t regions_47[] = { /* Clarinet */
+static const struct opl4_region regions_47[] = { /* Clarinet */
 	{0x15, 0x3b, {0x09e,5900,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}},
 	{0x3c, 0x41, {0x0a0,5158,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}},
 	{0x42, 0x4a, {0x09f,4260,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}},
 	{0x4b, 0x6c, {0x0a1,2957,100, 0,1,0x00,0xc8,0x29,0xf3,0x20,0x0a,0x0}}
 };
-static const opl4_region_t regions_48[] = { /* Piccolo */
+static const struct opl4_region regions_48[] = { /* Piccolo */
 	{0x15, 0x40, {0x071,4803,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
 	{0x41, 0x4d, {0x072,3314,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
 	{0x4e, 0x53, {0x073,1731,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
 	{0x54, 0x5f, {0x074,2085,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}},
 	{0x60, 0x6c, {0x075,1421,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}}
 };
-static const opl4_region_t regions_49[] = { /* Flute */
+static const struct opl4_region regions_49[] = { /* Flute */
 	{0x15, 0x40, {0x071,4803,100, 0,0,0x00,0xdc,0x38,0xf0,0x00,0x0a,0x2}},
 	{0x41, 0x4d, {0x072,3314,100, 0,0,0x00,0xdc,0x38,0xf0,0x00,0x0a,0x2}},
 	{0x4e, 0x6c, {0x073,1731,100, 0,0,0x00,0xe6,0x38,0xf0,0x00,0x0a,0x2}}
 };
-static const opl4_region_t regions_4a[] = { /* Recorder */
+static const struct opl4_region regions_4a[] = { /* Recorder */
 	{0x15, 0x6f, {0x0bd,4897,100, 0,0,0x00,0xec,0x30,0x70,0x00,0x09,0x1}}
 };
-static const opl4_region_t regions_4b[] = { /* Pan Flute */
+static const struct opl4_region regions_4b[] = { /* Pan Flute */
 	{0x15, 0x6c, {0x077,2359,100, 0,0,0x00,0xde,0x38,0xf0,0x00,0x09,0x3}}
 };
-static const opl4_region_t regions_4c[] = { /* Bottle Blow */
+static const struct opl4_region regions_4c[] = { /* Bottle Blow */
 	{0x15, 0x6c, {0x077,2359,100, 0,0,0x00,0xc8,0x38,0xf0,0x00,0x09,0x1}},
 	{0x01, 0x7f, {0x125,7372,100, 0,0,0x1e,0x80,0x00,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_4d[] = { /* Shakuhachi */
+static const struct opl4_region regions_4d[] = { /* Shakuhachi */
 	{0x00, 0x7f, {0x0ab,4548,100, 0,0,0x00,0xd6,0x30,0xf0,0x00,0x0a,0x3}},
 	{0x15, 0x6c, {0x076,3716,100, 0,0,0x00,0xa2,0x28,0x70,0x00,0x09,0x2}}
 };
-static const opl4_region_t regions_4e[] = { /* Whistle */
+static const struct opl4_region regions_4e[] = { /* Whistle */
 	{0x00, 0x7f, {0x0aa,1731,100, 0,4,0x00,0xd2,0x2c,0x70,0x00,0x0a,0x0}}
 };
-static const opl4_region_t regions_4f[] = { /* Ocarina */
+static const struct opl4_region regions_4f[] = { /* Ocarina */
 	{0x00, 0x7f, {0x0aa,1731,100, 0,1,0x00,0xce,0x29,0x90,0x00,0x0a,0x1}}
 };
-static const opl4_region_t regions_50[] = { /* Square Lead */
+static const struct opl4_region regions_50[] = { /* Square Lead */
 	{0x01, 0x2a, {0x0cc,9853,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
 	{0x2b, 0x36, {0x0cd,6785,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
 	{0x37, 0x42, {0x0ca,5248,100, 3,0,0x00,0xac,0x38,0xc6,0x21,0x09,0x0}},
@@ -573,7 +573,7 @@
 	{0x4f, 0x5a, {0x0ce,2167,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}},
 	{0x5b, 0x7f, {0x0cb, 631,100,-3,0,0x00,0xac,0x08,0xc6,0x21,0x09,0x0}}
 };
-static const opl4_region_t regions_51[] = { /* Sawtooth Lead */
+static const struct opl4_region regions_51[] = { /* Sawtooth Lead */
 	{0x01, 0x27, {0x118,9108,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
 	{0x28, 0x2d, {0x119,8345,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
 	{0x2e, 0x33, {0x11a,7570,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
@@ -599,15 +599,15 @@
 	{0x5e, 0x66, {0x122,1416,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}},
 	{0x67, 0x7f, {0x123,-120,100, 0,0,0x00,0xc8,0x30,0xf2,0x22,0x0a,0x0}}
 };
-static const opl4_region_t regions_52[] = { /* Calliope Lead */
+static const struct opl4_region regions_52[] = { /* Calliope Lead */
 	{0x00, 0x7f, {0x0aa,1731,100, 0,0,0x00,0xc2,0x28,0x90,0x00,0x0a,0x2}},
 	{0x15, 0x6c, {0x076,3716,100, 0,0,0x00,0xb6,0x28,0xb0,0x00,0x09,0x2}}
 };
-static const opl4_region_t regions_53[] = { /* Chiffer Lead */
+static const struct opl4_region regions_53[] = { /* Chiffer Lead */
 	{0x00, 0x7f, {0x13a,3665,100, 0,2,0x00,0xcc,0x2a,0xf0,0x10,0x09,0x1}},
 	{0x01, 0x7f, {0x0fe,3660,100, 0,0,0x00,0xbe,0x28,0xf3,0x10,0x17,0x0}}
 };
-static const opl4_region_t regions_54[] = { /* Charang Lead */
+static const struct opl4_region regions_54[] = { /* Charang Lead */
 	{0x00, 0x40, {0x0a5,6594,100, 0,3,0x00,0xba,0x33,0xf2,0x11,0x09,0x0}},
 	{0x41, 0x7f, {0x0a6,5433,100, 0,3,0x00,0xba,0x33,0xf2,0x11,0x09,0x0}},
 	{0x01, 0x27, {0x118,9098,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
@@ -623,11 +623,11 @@
 	{0x5e, 0x66, {0x122,1416,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}},
 	{0x67, 0x7f, {0x123,-120,100, 0,2,0x00,0xa4,0x2a,0xf2,0x22,0x0e,0x0}}
 };
-static const opl4_region_t regions_55[] = { /* Voice Lead */
+static const struct opl4_region regions_55[] = { /* Voice Lead */
 	{0x00, 0x7f, {0x0aa,1739,100, 0,6,0x00,0x8c,0x2e,0x90,0x00,0x0a,0x0}},
 	{0x15, 0x6c, {0x02a,3474,100, 0,1,0x00,0xd8,0x29,0xf0,0x05,0x0a,0x0}}
 };
-static const opl4_region_t regions_56[] = { /* 5ths Lead */
+static const struct opl4_region regions_56[] = { /* 5ths Lead */
 	{0x01, 0x27, {0x118,8468,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
 	{0x28, 0x2d, {0x119,7705,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
 	{0x2e, 0x33, {0x11a,6930,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
@@ -642,7 +642,7 @@
 	{0x65, 0x7f, {0x123,-750,100, 0,2,0x00,0xd0,0x32,0xf5,0x20,0x08,0x0}},
 	{0x05, 0x71, {0x002,4503,100, 0,1,0x00,0xb8,0x31,0xb3,0x20,0x0b,0x0}}
 };
-static const opl4_region_t regions_57[] = { /* Bass & Lead */
+static const struct opl4_region regions_57[] = { /* Bass & Lead */
 	{0x00, 0x7f, {0x117,8109,100, 0,1,0x00,0xbc,0x29,0xf3,0x50,0x08,0x0}},
 	{0x01, 0x27, {0x118,9097,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
 	{0x28, 0x2d, {0x119,8334,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
@@ -657,15 +657,15 @@
 	{0x5e, 0x66, {0x122,1415,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}},
 	{0x67, 0x7f, {0x123,-121,100, 0,2,0x00,0xbc,0x2a,0xf2,0x20,0x0a,0x0}}
 };
-static const opl4_region_t regions_58[] = { /* New Age Pad */
+static const struct opl4_region regions_58[] = { /* New Age Pad */
 	{0x15, 0x6c, {0x002,4501,100, 0,4,0x00,0xa4,0x24,0x80,0x01,0x05,0x0}},
 	{0x15, 0x6c, {0x0f3,4253,100, 0,3,0x00,0x8c,0x23,0xa2,0x14,0x06,0x1}}
 };
-static const opl4_region_t regions_59[] = { /* Warm Pad */
+static const struct opl4_region regions_59[] = { /* Warm Pad */
 	{0x15, 0x6c, {0x04e,5306,100, 2,2,0x00,0x92,0x2a,0x34,0x23,0x05,0x2}},
 	{0x15, 0x6c, {0x029,3575,100,-2,2,0x00,0xbe,0x22,0x31,0x23,0x06,0x0}}
 };
-static const opl4_region_t regions_5a[] = { /* Polysynth Pad */
+static const struct opl4_region regions_5a[] = { /* Polysynth Pad */
 	{0x01, 0x27, {0x118,9111,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
 	{0x28, 0x2d, {0x119,8348,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
 	{0x2e, 0x33, {0x11a,7573,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
@@ -680,29 +680,29 @@
 	{0x67, 0x7f, {0x123,-107,100, 0,3,0x00,0xae,0x23,0xf2,0x20,0x07,0x1}},
 	{0x00, 0x7f, {0x124,4024,100, 0,2,0x00,0xae,0x22,0xe5,0x20,0x08,0x0}}
 };
-static const opl4_region_t regions_5b[] = { /* Choir Pad */
+static const struct opl4_region regions_5b[] = { /* Choir Pad */
 	{0x15, 0x3a, {0x018,5010,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
 	{0x3b, 0x40, {0x019,4370,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
 	{0x41, 0x47, {0x01a,3478,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
 	{0x48, 0x6c, {0x01b,2197,100, 0,5,0x00,0xb0,0x25,0x70,0x00,0x06,0x0}},
 	{0x15, 0x6c, {0x02a,3482,100, 0,4,0x00,0x98,0x24,0x65,0x21,0x06,0x0}}
 };
-static const opl4_region_t regions_5c[] = { /* Bowed Pad */
+static const struct opl4_region regions_5c[] = { /* Bowed Pad */
 	{0x15, 0x6c, {0x101,4790,100,-1,1,0x00,0xbe,0x19,0x44,0x14,0x16,0x0}},
 	{0x00, 0x7f, {0x0aa,1720,100, 1,1,0x00,0x94,0x19,0x40,0x00,0x06,0x0}}
 };
-static const opl4_region_t regions_5d[] = { /* Metallic Pad */
+static const struct opl4_region regions_5d[] = { /* Metallic Pad */
 	{0x15, 0x31, {0x00c,6943,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
 	{0x32, 0x38, {0x00d,5416,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
 	{0x39, 0x47, {0x00e,4385,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
 	{0x48, 0x6c, {0x00f,2849,100, 0,2,0x00,0xa0,0x0a,0x60,0x03,0x06,0x0}},
 	{0x00, 0x7f, {0x03f,4224,100, 0,1,0x00,0x9c,0x31,0x65,0x16,0x07,0x0}}
 };
-static const opl4_region_t regions_5e[] = { /* Halo Pad */
+static const struct opl4_region regions_5e[] = { /* Halo Pad */
 	{0x00, 0x7f, {0x124,4038,100, 0,2,0x00,0xa6,0x1a,0x85,0x23,0x08,0x0}},
 	{0x15, 0x6c, {0x02a,3471,100, 0,3,0x00,0xc0,0x1b,0xc0,0x05,0x06,0x0}}
 };
-static const opl4_region_t regions_5f[] = { /* Sweep Pad */
+static const struct opl4_region regions_5f[] = { /* Sweep Pad */
 	{0x01, 0x27, {0x0d3,9100,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
 	{0x28, 0x2d, {0x0da,8341,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
 	{0x2e, 0x33, {0x0d4,7564,100, 0,1,0x00,0xce,0x19,0x13,0x11,0x06,0x0}},
@@ -728,21 +728,21 @@
 	{0x5e, 0x63, {0x0d8,1415,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}},
 	{0x64, 0x7f, {0x0d9,-121,100, 0,0,0x00,0xce,0x18,0x13,0x11,0x06,0x0}}
 };
-static const opl4_region_t regions_60[] = { /* Ice Rain */
+static const struct opl4_region regions_60[] = { /* Ice Rain */
 	{0x01, 0x7f, {0x04e,9345,100, 0,2,0x00,0xcc,0x22,0xa3,0x63,0x17,0x0}},
 	{0x00, 0x7f, {0x143,5586, 20, 0,2,0x00,0x6e,0x2a,0xf0,0x05,0x05,0x0}}
 };
-static const opl4_region_t regions_61[] = { /* Soundtrack */
+static const struct opl4_region regions_61[] = { /* Soundtrack */
 	{0x15, 0x6c, {0x002,4501,100, 0,2,0x00,0xb6,0x2a,0x60,0x01,0x05,0x0}},
 	{0x15, 0x6c, {0x0f3,1160,100, 0,5,0x00,0xa8,0x2d,0x52,0x14,0x06,0x2}}
 };
-static const opl4_region_t regions_62[] = { /* Crystal */
+static const struct opl4_region regions_62[] = { /* Crystal */
 	{0x15, 0x6c, {0x0f3,1826,100, 0,3,0x00,0xb8,0x33,0xf6,0x25,0x25,0x0}},
 	{0x15, 0x2c, {0x06d,7454,100, 0,3,0x00,0xac,0x3b,0x85,0x24,0x06,0x0}},
 	{0x2d, 0x36, {0x06e,5925,100, 0,3,0x00,0xac,0x3b,0x85,0x24,0x06,0x0}},
 	{0x37, 0x6c, {0x06f,4403,100, 0,3,0x09,0xac,0x3b,0x85,0x24,0x06,0x0}}
 };
-static const opl4_region_t regions_63[] = { /* Atmosphere */
+static const struct opl4_region regions_63[] = { /* Atmosphere */
 	{0x05, 0x71, {0x002,4509,100, 0,2,0x00,0xc8,0x32,0x73,0x22,0x06,0x1}},
 	{0x15, 0x2f, {0x0b3,6964,100, 0,2,0x05,0xc2,0x32,0xf5,0x34,0x07,0x2}},
 	{0x30, 0x36, {0x0b7,5567,100, 0,2,0x0c,0xc2,0x32,0xf5,0x34,0x07,0x2}},
@@ -750,29 +750,29 @@
 	{0x3d, 0x43, {0x0b4,3892,100, 0,2,0x00,0xc2,0x32,0xf6,0x35,0x07,0x2}},
 	{0x44, 0x60, {0x0b6,2723,100, 0,2,0x00,0xc2,0x32,0xf6,0x35,0x17,0x2}}
 };
-static const opl4_region_t regions_64[] = { /* Brightness */
+static const struct opl4_region regions_64[] = { /* Brightness */
 	{0x00, 0x7f, {0x137,5285,100, 0,2,0x00,0xbe,0x2a,0xa5,0x18,0x08,0x0}},
 	{0x15, 0x6c, {0x02a,3481,100, 0,1,0x00,0xc8,0x29,0x80,0x05,0x05,0x0}}
 };
-static const opl4_region_t regions_65[] = { /* Goblins */
+static const struct opl4_region regions_65[] = { /* Goblins */
 	{0x15, 0x6c, {0x002,4501,100,-1,2,0x00,0xca,0x2a,0x40,0x01,0x05,0x0}},
 	{0x15, 0x6c, {0x009,9679, 20, 1,4,0x00,0x3c,0x0c,0x22,0x11,0x06,0x0}}
 };
-static const opl4_region_t regions_66[] = { /* Echoes */
+static const struct opl4_region regions_66[] = { /* Echoes */
 	{0x15, 0x6c, {0x02a,3487,100, 0,3,0x00,0xae,0x2b,0xf5,0x21,0x06,0x0}},
 	{0x00, 0x7f, {0x124,4027,100, 0,3,0x00,0xae,0x2b,0x85,0x23,0x07,0x0}}
 };
-static const opl4_region_t regions_67[] = { /* Sci-Fi */
+static const struct opl4_region regions_67[] = { /* Sci-Fi */
 	{0x15, 0x31, {0x00c,6940,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
 	{0x32, 0x38, {0x00d,5413,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
 	{0x39, 0x47, {0x00e,4382,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
 	{0x48, 0x6c, {0x00f,2846,100, 0,3,0x00,0xc8,0x2b,0x90,0x05,0x06,0x3}},
 	{0x15, 0x6c, {0x002,4498,100, 0,2,0x00,0xd4,0x22,0x80,0x01,0x05,0x0}}
 };
-static const opl4_region_t regions_68[] = { /* Sitar */
+static const struct opl4_region regions_68[] = { /* Sitar */
 	{0x00, 0x7f, {0x10f,4408,100, 0,2,0x00,0xc4,0x32,0xf4,0x15,0x16,0x1}}
 };
-static const opl4_region_t regions_69[] = { /* Banjo */
+static const struct opl4_region regions_69[] = { /* Banjo */
 	{0x15, 0x34, {0x013,5685,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
 	{0x35, 0x38, {0x014,5009,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
 	{0x39, 0x3c, {0x012,4520,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
@@ -780,21 +780,21 @@
 	{0x45, 0x4c, {0x017,2661,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}},
 	{0x4d, 0x6d, {0x016,1632,100, 0,0,0x00,0xdc,0x38,0xf6,0x15,0x09,0x0}}
 };
-static const opl4_region_t regions_6a[] = { /* Shamisen */
+static const struct opl4_region regions_6a[] = { /* Shamisen */
 	{0x15, 0x6c, {0x10e,3273,100, 0,0,0x00,0xc0,0x28,0xf7,0x76,0x08,0x0}}
 };
-static const opl4_region_t regions_6b[] = { /* Koto */
+static const struct opl4_region regions_6b[] = { /* Koto */
 	{0x00, 0x7f, {0x0a9,4033,100, 0,0,0x00,0xc6,0x20,0xf0,0x06,0x07,0x0}}
 };
-static const opl4_region_t regions_6c[] = { /* Kalimba */
+static const struct opl4_region regions_6c[] = { /* Kalimba */
 	{0x00, 0x7f, {0x137,3749,100, 0,0,0x00,0xce,0x38,0xf5,0x18,0x08,0x0}}
 };
-static const opl4_region_t regions_6d[] = { /* Bagpipe */
+static const struct opl4_region regions_6d[] = { /* Bagpipe */
 	{0x15, 0x39, {0x0a4,7683,100, 0,4,0x00,0xc0,0x1c,0xf0,0x00,0x09,0x0}},
 	{0x15, 0x39, {0x0a7,7680,100, 0,1,0x00,0xaa,0x19,0xf0,0x00,0x09,0x0}},
 	{0x3a, 0x6c, {0x0a8,3697,100, 0,1,0x00,0xaa,0x19,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_6e[] = { /* Fiddle */
+static const struct opl4_region regions_6e[] = { /* Fiddle */
 	{0x15, 0x3a, {0x105,5158,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
 	{0x3b, 0x3f, {0x102,4754,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
 	{0x40, 0x41, {0x106,4132,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
@@ -806,64 +806,64 @@
 	{0x4f, 0x51, {0x10d,2166,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}},
 	{0x52, 0x6c, {0x109,1825,100, 0,1,0x00,0xca,0x31,0xf3,0x20,0x09,0x0}}
 };
-static const opl4_region_t regions_6f[] = { /* Shanai */
+static const struct opl4_region regions_6f[] = { /* Shanai */
 	{0x15, 0x6c, {0x041,6946,100, 0,1,0x00,0xc4,0x31,0x95,0x20,0x09,0x0}}
 };
-static const opl4_region_t regions_70[] = { /* Tinkle Bell */
+static const struct opl4_region regions_70[] = { /* Tinkle Bell */
 	{0x15, 0x73, {0x0f3,1821,100, 0,3,0x00,0xc8,0x3b,0xd6,0x25,0x25,0x0}},
 	{0x00, 0x7f, {0x137,5669,100, 0,3,0x00,0x66,0x3b,0xf5,0x18,0x08,0x0}}
 };
-static const opl4_region_t regions_71[] = { /* Agogo */
+static const struct opl4_region regions_71[] = { /* Agogo */
 	{0x15, 0x74, {0x00b,2474,100, 0,0,0x00,0xd2,0x38,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_72[] = { /* Steel Drums */
+static const struct opl4_region regions_72[] = { /* Steel Drums */
 	{0x01, 0x7f, {0x0fe,3670,100, 0,0,0x00,0xca,0x38,0xf3,0x06,0x17,0x1}},
 	{0x15, 0x6c, {0x100,9602,100, 0,0,0x00,0x54,0x38,0xb0,0x05,0x16,0x1}}
 };
-static const opl4_region_t regions_73[] = { /* Woodblock */
+static const struct opl4_region regions_73[] = { /* Woodblock */
 	{0x15, 0x6c, {0x02c,2963, 50, 0,0,0x07,0xd4,0x00,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_74[] = { /* Taiko Drum */
+static const struct opl4_region regions_74[] = { /* Taiko Drum */
 	{0x13, 0x6c, {0x03e,1194, 50, 0,0,0x00,0xaa,0x38,0xf0,0x04,0x04,0x0}}
 };
-static const opl4_region_t regions_75[] = { /* Melodic Tom */
+static const struct opl4_region regions_75[] = { /* Melodic Tom */
 	{0x15, 0x6c, {0x0c7,6418, 50, 0,0,0x00,0xe4,0x38,0xf0,0x05,0x01,0x0}}
 };
-static const opl4_region_t regions_76[] = { /* Synth Drum */
+static const struct opl4_region regions_76[] = { /* Synth Drum */
 	{0x15, 0x6c, {0x026,3898, 50, 0,0,0x00,0xd0,0x38,0xf0,0x04,0x04,0x0}}
 };
-static const opl4_region_t regions_77[] = { /* Reverse Cymbal */
+static const struct opl4_region regions_77[] = { /* Reverse Cymbal */
 	{0x15, 0x6c, {0x031,4138, 50, 0,0,0x00,0xfe,0x38,0x3a,0xf0,0x09,0x0}}
 };
-static const opl4_region_t regions_78[] = { /* Guitar Fret Noise */
+static const struct opl4_region regions_78[] = { /* Guitar Fret Noise */
 	{0x15, 0x6c, {0x138,5266,100, 0,0,0x00,0xa0,0x38,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_79[] = { /* Breath Noise */
+static const struct opl4_region regions_79[] = { /* Breath Noise */
 	{0x01, 0x7f, {0x125,4269,100, 0,0,0x1e,0xd0,0x38,0xf0,0x00,0x09,0x0}}
 };
-static const opl4_region_t regions_7a[] = { /* Seashore */
+static const struct opl4_region regions_7a[] = { /* Seashore */
 	{0x15, 0x6c, {0x008,2965, 20,-2,0,0x00,0xfe,0x00,0x20,0x03,0x04,0x0}},
 	{0x01, 0x7f, {0x037,4394, 20, 2,0,0x14,0xfe,0x00,0x20,0x04,0x05,0x0}}
 };
-static const opl4_region_t regions_7b[] = { /* Bird Tweet */
+static const struct opl4_region regions_7b[] = { /* Bird Tweet */
 	{0x15, 0x6c, {0x009,8078,  5,-4,7,0x00,0xc2,0x0f,0x22,0x12,0x07,0x0}},
 	{0x15, 0x6c, {0x009,3583,  5, 4,5,0x00,0xae,0x15,0x72,0x12,0x07,0x0}}
 };
-static const opl4_region_t regions_7c[] = { /* Telephone Ring */
+static const struct opl4_region regions_7c[] = { /* Telephone Ring */
 	{0x15, 0x6c, {0x003,3602, 10, 0,0,0x00,0xce,0x00,0xf0,0x00,0x0f,0x0}}
 };
-static const opl4_region_t regions_7d[] = { /* Helicopter */
+static const struct opl4_region regions_7d[] = { /* Helicopter */
 	{0x0c, 0x7f, {0x001,2965, 10,-2,0,0x00,0xe0,0x08,0x30,0x01,0x07,0x0}},
 	{0x01, 0x7f, {0x037,4394, 10, 2,0,0x44,0x76,0x00,0x30,0x01,0x07,0x0}}
 };
-static const opl4_region_t regions_7e[] = { /* Applause */
+static const struct opl4_region regions_7e[] = { /* Applause */
 	{0x15, 0x6c, {0x036,8273, 20,-6,7,0x00,0xc4,0x0f,0x70,0x01,0x05,0x0}},
 	{0x15, 0x6c, {0x036,8115,  5, 6,7,0x00,0xc6,0x07,0x70,0x01,0x05,0x0}}
 };
-static const opl4_region_t regions_7f[] = { /* Gun Shot */
+static const struct opl4_region regions_7f[] = { /* Gun Shot */
 	{0x15, 0x6c, {0x139,2858, 20, 0,0,0x00,0xbe,0x38,0xf0,0x03,0x00,0x0}}
 };
-static const opl4_region_t regions_drums[] = {
+static const struct opl4_region regions_drums[] = {
 	{0x18, 0x18, {0x0cb,6397,100, 3,0,0x00,0xf4,0x38,0xc9,0x1c,0x0c,0x0}},
 	{0x19, 0x19, {0x0c4,3714,100, 0,0,0x00,0xe0,0x00,0x97,0x19,0x09,0x0}},
 	{0x1a, 0x1a, {0x0c4,3519,100, 0,0,0x00,0xea,0x00,0x61,0x01,0x07,0x0}},
@@ -924,7 +924,7 @@
 };
 
 #define REGION(num) { ARRAY_SIZE(regions ## num), regions ## num }
-const opl4_region_ptr_t snd_yrw801_regions[0x81] = {
+const struct opl4_region_ptr snd_yrw801_regions[0x81] = {
 	REGION(_00), REGION(_01), REGION(_02), REGION(_03),
 	REGION(_04), REGION(_05), REGION(_06), REGION(_07),
 	REGION(_08), REGION(_09), REGION(_0a), REGION(_0b),
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 1ed58df..29676d8 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -33,6 +33,8 @@
 #include <sound/driver.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/moduleparam.h>
@@ -116,10 +118,10 @@
 #define SERIAL_MODE_OUTPUT_TRIGGERED	(1 << 3)
 
 typedef struct _snd_uart16550 {
-	snd_card_t *card;
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *midi_output[SNDRV_SERIAL_MAX_OUTS];
-	snd_rawmidi_substream_t *midi_input[SNDRV_SERIAL_MAX_INS];
+	struct snd_card *card;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *midi_output[SNDRV_SERIAL_MAX_OUTS];
+	struct snd_rawmidi_substream *midi_input[SNDRV_SERIAL_MAX_INS];
 
 	int filemode;		//open status of file
 
@@ -166,7 +168,7 @@
 
 } snd_uart16550_t;
 
-static snd_card_t *snd_serial_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct platform_device *devices[SNDRV_CARDS];
 
 static inline void snd_uart16550_add_timer(snd_uart16550_t *uart)
 {
@@ -509,7 +511,7 @@
 	}
 }
 
-static int snd_uart16550_input_open(snd_rawmidi_substream_t * substream)
+static int snd_uart16550_input_open(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
 	snd_uart16550_t *uart = substream->rmidi->private_data;
@@ -523,7 +525,7 @@
 	return 0;
 }
 
-static int snd_uart16550_input_close(snd_rawmidi_substream_t * substream)
+static int snd_uart16550_input_close(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
 	snd_uart16550_t *uart = substream->rmidi->private_data;
@@ -537,7 +539,7 @@
 	return 0;
 }
 
-static void snd_uart16550_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_uart16550_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
 	snd_uart16550_t *uart = substream->rmidi->private_data;
@@ -551,7 +553,7 @@
 	spin_unlock_irqrestore(&uart->open_lock, flags);
 }
 
-static int snd_uart16550_output_open(snd_rawmidi_substream_t * substream)
+static int snd_uart16550_output_open(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
 	snd_uart16550_t *uart = substream->rmidi->private_data;
@@ -565,7 +567,7 @@
 	return 0;
 };
 
-static int snd_uart16550_output_close(snd_rawmidi_substream_t * substream)
+static int snd_uart16550_output_close(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
 	snd_uart16550_t *uart = substream->rmidi->private_data;
@@ -603,7 +605,7 @@
 		return 0;
 }
 
-static int snd_uart16550_output_byte(snd_uart16550_t *uart, snd_rawmidi_substream_t * substream, unsigned char midi_byte)
+static int snd_uart16550_output_byte(snd_uart16550_t *uart, struct snd_rawmidi_substream *substream, unsigned char midi_byte)
 {
 	if (uart->buff_in_count == 0                            /* Buffer empty? */
 	    && ((uart->adaptor != SNDRV_SERIAL_MS124W_SA &&
@@ -636,7 +638,7 @@
 	return 1;
 }
 
-static void snd_uart16550_output_write(snd_rawmidi_substream_t * substream)
+static void snd_uart16550_output_write(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
 	unsigned char midi_byte, addr_byte;
@@ -715,7 +717,7 @@
 	spin_unlock_irqrestore(&uart->open_lock, flags);
 }
 
-static void snd_uart16550_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_uart16550_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
 	snd_uart16550_t *uart = substream->rmidi->private_data;
@@ -731,14 +733,14 @@
 		snd_uart16550_output_write(substream);
 }
 
-static snd_rawmidi_ops_t snd_uart16550_output =
+static struct snd_rawmidi_ops snd_uart16550_output =
 {
 	.open =		snd_uart16550_output_open,
 	.close =	snd_uart16550_output_close,
 	.trigger =	snd_uart16550_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_uart16550_input =
+static struct snd_rawmidi_ops snd_uart16550_input =
 {
 	.open =		snd_uart16550_input_open,
 	.close =	snd_uart16550_input_close,
@@ -754,13 +756,13 @@
 	return 0;
 };
 
-static int snd_uart16550_dev_free(snd_device_t *device)
+static int snd_uart16550_dev_free(struct snd_device *device)
 {
 	snd_uart16550_t *uart = device->device_data;
 	return snd_uart16550_free(uart);
 }
 
-static int __init snd_uart16550_create(snd_card_t * card,
+static int __init snd_uart16550_create(struct snd_card *card,
 				       unsigned long iobase,
 				       int irq,
 				       unsigned int speed,
@@ -769,7 +771,7 @@
 				       int droponfull,
 				       snd_uart16550_t **ruart)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_uart16550_dev_free,
 	};
 	snd_uart16550_t *uart;
@@ -838,19 +840,19 @@
 	return 0;
 }
 
-static void __init snd_uart16550_substreams(snd_rawmidi_str_t *stream)
+static void __init snd_uart16550_substreams(struct snd_rawmidi_str *stream)
 {
 	struct list_head *list;
 
 	list_for_each(list, &stream->substreams) {
-		snd_rawmidi_substream_t *substream = list_entry(list, snd_rawmidi_substream_t, list);
+		struct snd_rawmidi_substream *substream = list_entry(list, struct snd_rawmidi_substream, list);
 		sprintf(substream->name, "Serial MIDI %d", substream->number + 1);
 	}
 }
 
-static int __init snd_uart16550_rmidi(snd_uart16550_t *uart, int device, int outs, int ins, snd_rawmidi_t **rmidi)
+static int __init snd_uart16550_rmidi(snd_uart16550_t *uart, int device, int outs, int ins, struct snd_rawmidi **rmidi)
 {
-	snd_rawmidi_t *rrawmidi;
+	struct snd_rawmidi *rrawmidi;
 	int err;
 
 	if ((err = snd_rawmidi_new(uart->card, "UART Serial MIDI", device, outs, ins, &rrawmidi)) < 0)
@@ -869,14 +871,12 @@
 	return 0;
 }
 
-static int __init snd_serial_probe(int dev)
+static int __init snd_serial_probe(struct platform_device *devptr)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	snd_uart16550_t *uart;
 	int err;
-
-	if (!enable[dev])
-		return -ENOENT;
+	int dev = devptr->id;
 
 	switch (adaptor[dev]) {
 	case SNDRV_SERIAL_SOUNDCANVAS:
@@ -942,13 +942,12 @@
 		adaptor_names[uart->adaptor],
 		uart->drop_on_full);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
+	snd_card_set_dev(card, &devptr->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
-	snd_serial_cards[dev] = card;
+	platform_set_drvdata(devptr, card);
 	return 0;
 
  _err:
@@ -956,33 +955,68 @@
 	return err;
 }
 
+static int snd_serial_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#define SND_SERIAL_DRIVER	"snd_serial_u16550"
+
+static struct platform_driver snd_serial_driver = {
+	.probe		= snd_serial_probe,
+	.remove		= snd_serial_remove,
+	.driver		= {
+		.name	= SND_SERIAL_DRIVER
+	},
+};
+
+static void __init_or_module snd_serial_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_serial_driver);
+}
+
 static int __init alsa_card_serial_init(void)
 {
-	int dev = 0;
-	int cards = 0;
+	int i, cards, err;
 
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (snd_serial_probe(dev) == 0)
-			cards++;
+	if ((err = platform_driver_register(&snd_serial_driver)) < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(SND_SERIAL_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		devices[i] = device;
+		cards++;
 	}
-
-	if (cards == 0) {
+	if (! cards) {
 #ifdef MODULE
 		printk(KERN_ERR "serial midi soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_serial_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_serial_exit(void)
 {
-	int dev;
-
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (snd_serial_cards[dev] != NULL)
-			snd_card_free(snd_serial_cards[dev]);
-	}
+	snd_serial_unregister_all();
 }
 
 module_init(alsa_card_serial_init)
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index af12185..4258723 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -45,6 +45,8 @@
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/seq_kernel.h>
@@ -59,7 +61,7 @@
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{ALSA,Virtual rawmidi device}}");
 
-#define MAX_MIDI_DEVICES	8
+#define MAX_MIDI_DEVICES	4
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
@@ -73,24 +75,23 @@
 module_param_array(enable, bool, NULL, 0444);
 MODULE_PARM_DESC(enable, "Enable this soundcard.");
 module_param_array(midi_devs, int, NULL, 0444);
-MODULE_PARM_DESC(midi_devs, "MIDI devices # (1-8)");
+MODULE_PARM_DESC(midi_devs, "MIDI devices # (1-4)");
 
-typedef struct snd_card_virmidi {
-	snd_card_t *card;
-	snd_rawmidi_t *midi[MAX_MIDI_DEVICES];
-} snd_card_virmidi_t;
+struct snd_card_virmidi {
+	struct snd_card *card;
+	struct snd_rawmidi *midi[MAX_MIDI_DEVICES];
+};
 
-static snd_card_t *snd_virmidi_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct platform_device *devices[SNDRV_CARDS];
 
 
-static int __init snd_card_virmidi_probe(int dev)
+static int __init snd_virmidi_probe(struct platform_device *devptr)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_card_virmidi *vmidi;
 	int idx, err;
+	int dev = devptr->id;
 
-	if (!enable[dev])
-		return -ENODEV;
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(struct snd_card_virmidi));
 	if (card == NULL)
@@ -103,8 +104,8 @@
 		midi_devs[dev] = MAX_MIDI_DEVICES;
 	}
 	for (idx = 0; idx < midi_devs[dev]; idx++) {
-		snd_rawmidi_t *rmidi;
-		snd_virmidi_dev_t *rdev;
+		struct snd_rawmidi *rmidi;
+		struct snd_virmidi_dev *rdev;
 		if ((err = snd_virmidi_new(card, idx, &rmidi)) < 0)
 			goto __nodev;
 		rdev = rmidi->private_data;
@@ -117,11 +118,10 @@
 	strcpy(card->shortname, "VirMIDI");
 	sprintf(card->longname, "Virtual MIDI Card %i", dev + 1);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto __nodev;
+	snd_card_set_dev(card, &devptr->dev);
 
 	if ((err = snd_card_register(card)) == 0) {
-		snd_virmidi_cards[dev] = card;
+		platform_set_drvdata(devptr, card);
 		return 0;
 	}
       __nodev:
@@ -129,34 +129,68 @@
 	return err;
 }
 
+static int snd_virmidi_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#define SND_VIRMIDI_DRIVER	"snd_virmidi"
+
+static struct platform_driver snd_virmidi_driver = {
+	.probe		= snd_virmidi_probe,
+	.remove		= snd_virmidi_remove,
+	.driver		= {
+		.name	= SND_VIRMIDI_DRIVER
+	},
+};
+
+static void __init_or_module snd_virmidi_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_virmidi_driver);
+}
+
 static int __init alsa_card_virmidi_init(void)
 {
-	int dev, cards;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) {
-		if (snd_card_virmidi_probe(dev) < 0) {
-#ifdef MODULE
-			printk(KERN_ERR "Card-VirMIDI #%i not found or device busy\n", dev + 1);
-#endif
-			break;
+	if ((err = platform_driver_register(&snd_virmidi_driver)) < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(SND_VIRMIDI_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
 		}
+		devices[i] = device;
 		cards++;
 	}
 	if (!cards) {
 #ifdef MODULE
 		printk(KERN_ERR "Card-VirMIDI soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_virmidi_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_virmidi_exit(void)
 {
-	int dev;
-
-	for (dev = 0; dev < SNDRV_CARDS; dev++)
-		snd_card_free(snd_virmidi_cards[dev]);
+	snd_virmidi_unregister_all();
 }
 
 module_init(alsa_card_virmidi_init)
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 4697b1d..43f615d 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -41,18 +41,6 @@
 
 
 /*
- * snd_vx_delay - delay for the specified time
- * @xmsec: the time to delay in msec
- */
-void snd_vx_delay(vx_core_t *chip, int xmsec)
-{
-	if (! in_interrupt() && xmsec >= 1000 / HZ)
-		msleep(xmsec);
-	else
-		mdelay(xmsec);
-}
-
-/*
  * vx_check_reg_bit - wait for the specified bit is set/reset on a register
  * @reg: register to check
  * @mask: bit mask
@@ -61,7 +49,7 @@
  *
  * returns zero if a bit matches, or a negative error code.
  */
-int snd_vx_check_reg_bit(vx_core_t *chip, int reg, int mask, int bit, int time)
+int snd_vx_check_reg_bit(struct vx_core *chip, int reg, int mask, int bit, int time)
 {
 	unsigned long end_time = jiffies + (time * HZ + 999) / 1000;
 #ifdef CONFIG_SND_DEBUG
@@ -76,7 +64,7 @@
 	do {
 		if ((snd_vx_inb(chip, reg) & mask) == bit)
 			return 0;
-		//snd_vx_delay(chip, 10);
+		//msleep(10);
 	} while (time_after_eq(end_time, jiffies));
 	snd_printd(KERN_DEBUG "vx_check_reg_bit: timeout, reg=%s, mask=0x%x, val=0x%x\n", reg_names[reg], mask, snd_vx_inb(chip, reg));
 	return -EIO;
@@ -90,7 +78,7 @@
  * returns 0 if successful, or a negative error code.
  * 
  */
-static int vx_send_irq_dsp(vx_core_t *chip, int num)
+static int vx_send_irq_dsp(struct vx_core *chip, int num)
 {
 	int nirq;
 
@@ -111,7 +99,7 @@
  *
  * returns 0 if successful, or a negative error code.
  */
-static int vx_reset_chk(vx_core_t *chip)
+static int vx_reset_chk(struct vx_core *chip)
 {
 	/* Reset irq CHK */
 	if (vx_send_irq_dsp(chip, IRQ_RESET_CHK) < 0)
@@ -130,7 +118,7 @@
  * the error code can be VX-specific, retrieved via vx_get_error().
  * NB: call with spinlock held!
  */
-static int vx_transfer_end(vx_core_t *chip, int cmd)
+static int vx_transfer_end(struct vx_core *chip, int cmd)
 {
 	int err;
 
@@ -168,7 +156,7 @@
  * the error code can be VX-specific, retrieved via vx_get_error().
  * NB: call with spinlock held!
  */
-static int vx_read_status(vx_core_t *chip, struct vx_rmh *rmh)
+static int vx_read_status(struct vx_core *chip, struct vx_rmh *rmh)
 {
 	int i, err, val, size;
 
@@ -248,7 +236,7 @@
  * 
  * this function doesn't call spinlock at all.
  */
-int vx_send_msg_nolock(vx_core_t *chip, struct vx_rmh *rmh)
+int vx_send_msg_nolock(struct vx_core *chip, struct vx_rmh *rmh)
 {
 	int i, err;
 	
@@ -353,7 +341,7 @@
  * returns 0 if successful, or a negative error code.
  * see vx_send_msg_nolock().
  */
-int vx_send_msg(vx_core_t *chip, struct vx_rmh *rmh)
+int vx_send_msg(struct vx_core *chip, struct vx_rmh *rmh)
 {
 	unsigned long flags;
 	int err;
@@ -376,7 +364,7 @@
  *
  * unlike RMH, no command is sent to DSP.
  */
-int vx_send_rih_nolock(vx_core_t *chip, int cmd)
+int vx_send_rih_nolock(struct vx_core *chip, int cmd)
 {
 	int err;
 
@@ -413,7 +401,7 @@
  *
  * see vx_send_rih_nolock().
  */
-int vx_send_rih(vx_core_t *chip, int cmd)
+int vx_send_rih(struct vx_core *chip, int cmd)
 {
 	unsigned long flags;
 	int err;
@@ -430,7 +418,7 @@
  * snd_vx_boot_xilinx - boot up the xilinx interface
  * @boot: the boot record to load
  */
-int snd_vx_load_boot_image(vx_core_t *chip, const struct firmware *boot)
+int snd_vx_load_boot_image(struct vx_core *chip, const struct firmware *boot)
 {
 	unsigned int i;
 	int no_fillup = vx_has_new_dsp(chip);
@@ -482,7 +470,7 @@
  *
  * called from irq handler only
  */
-static int vx_test_irq_src(vx_core_t *chip, unsigned int *ret)
+static int vx_test_irq_src(struct vx_core *chip, unsigned int *ret)
 {
 	int err;
 
@@ -503,7 +491,7 @@
  */
 static void vx_interrupt(unsigned long private_data)
 {
-	vx_core_t *chip = (vx_core_t *) private_data;
+	struct vx_core *chip = (struct vx_core *) private_data;
 	unsigned int events;
 		
 	if (chip->chip_status & VX_STAT_IS_STALE)
@@ -547,7 +535,7 @@
  */
 irqreturn_t snd_vx_irq_handler(int irq, void *dev, struct pt_regs *regs)
 {
-	vx_core_t *chip = dev;
+	struct vx_core *chip = dev;
 
 	if (! (chip->chip_status & VX_STAT_CHIP_INIT) ||
 	    (chip->chip_status & VX_STAT_IS_STALE))
@@ -560,7 +548,7 @@
 
 /*
  */
-static void vx_reset_board(vx_core_t *chip, int cold_reset)
+static void vx_reset_board(struct vx_core *chip, int cold_reset)
 {
 	snd_assert(chip->ops->reset_board, return);
 
@@ -599,9 +587,9 @@
  * proc interface
  */
 
-static void vx_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void vx_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	vx_core_t *chip = entry->private_data;
+	struct vx_core *chip = entry->private_data;
 	static char *audio_src_vxp[] = { "Line", "Mic", "Digital" };
 	static char *audio_src_vx2[] = { "Analog", "Analog", "Digital" };
 	static char *clock_mode[] = { "Auto", "Internal", "External" };
@@ -642,9 +630,9 @@
 		    chip->ibl.granularity);
 }
 
-static void vx_proc_init(vx_core_t *chip)
+static void vx_proc_init(struct vx_core *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(chip->card, "vx-status", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, vx_proc_read);
@@ -654,7 +642,7 @@
 /**
  * snd_vx_dsp_boot - load the DSP boot
  */
-int snd_vx_dsp_boot(vx_core_t *chip, const struct firmware *boot)
+int snd_vx_dsp_boot(struct vx_core *chip, const struct firmware *boot)
 {
 	int err;
 	int cold_reset = !(chip->chip_status & VX_STAT_DEVICE_INIT);
@@ -664,7 +652,7 @@
 
 	if ((err = snd_vx_load_boot_image(chip, boot)) < 0)
 		return err;
-	snd_vx_delay(chip, 10);
+	msleep(10);
 
 	return 0;
 }
@@ -672,7 +660,7 @@
 /**
  * snd_vx_dsp_load - load the DSP image
  */
-int snd_vx_dsp_load(vx_core_t *chip, const struct firmware *dsp)
+int snd_vx_dsp_load(struct vx_core *chip, const struct firmware *dsp)
 {
 	unsigned int i;
 	int err;
@@ -704,7 +692,7 @@
 	}
 	snd_printdd(KERN_DEBUG "checksum = 0x%08x\n", csum);
 
-	snd_vx_delay(chip, 200);
+	msleep(200);
 
 	if ((err = vx_wait_isr_bit(chip, ISR_CHK)) < 0)
 		return err;
@@ -721,13 +709,11 @@
 /*
  * suspend
  */
-static int snd_vx_suspend(snd_card_t *card, pm_message_t state)
+int snd_vx_suspend(struct vx_core *chip, pm_message_t state)
 {
-	vx_core_t *chip = card->pm_private_data;
 	unsigned int i;
 
-	snd_assert(chip, return -EINVAL);
-
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
 	chip->chip_status |= VX_STAT_IN_SUSPEND;
 	for (i = 0; i < chip->hw->num_codecs; i++)
 		snd_pcm_suspend_all(chip->pcm[i]);
@@ -738,13 +724,10 @@
 /*
  * resume
  */
-static int snd_vx_resume(snd_card_t *card)
+int snd_vx_resume(struct vx_core *chip)
 {
-	vx_core_t *chip = card->pm_private_data;
 	int i, err;
 
-	snd_assert(chip, return -EINVAL);
-
 	chip->chip_status &= ~VX_STAT_CHIP_INIT;
 
 	for (i = 0; i < 4; i++) {
@@ -760,13 +743,14 @@
 	chip->chip_status |= VX_STAT_CHIP_INIT;
 	chip->chip_status &= ~VX_STAT_IN_SUSPEND;
 
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 
 #endif
 
 /**
- * snd_vx_create - constructor for vx_core_t
+ * snd_vx_create - constructor for struct vx_core
  * @hw: hardware specific record
  *
  * this function allocates the instance and prepare for the hardware
@@ -774,11 +758,11 @@
  *
  * return the instance pointer if successful, NULL in error.
  */
-vx_core_t *snd_vx_create(snd_card_t *card, struct snd_vx_hardware *hw,
-			 struct snd_vx_ops *ops,
-			 int extra_size)
+struct vx_core *snd_vx_create(struct snd_card *card, struct snd_vx_hardware *hw,
+			      struct snd_vx_ops *ops,
+			      int extra_size)
 {
-	vx_core_t *chip;
+	struct vx_core *chip;
 
 	snd_assert(card && hw && ops, return NULL);
 
@@ -801,8 +785,6 @@
 	strcpy(card->driver, hw->name);
 	sprintf(card->shortname, "Digigram %s", hw->name);
 
-	snd_card_set_pm_callback(card, snd_vx_suspend, snd_vx_resume, chip);
-
 	vx_proc_init(chip);
 
 	return chip;
@@ -831,7 +813,10 @@
 EXPORT_SYMBOL(snd_vx_setup_firmware);
 EXPORT_SYMBOL(snd_vx_free_firmware);
 EXPORT_SYMBOL(snd_vx_irq_handler);
-EXPORT_SYMBOL(snd_vx_delay);
 EXPORT_SYMBOL(snd_vx_dsp_boot);
 EXPORT_SYMBOL(snd_vx_dsp_load);
 EXPORT_SYMBOL(snd_vx_load_boot_image);
+#ifdef CONFIG_PM
+EXPORT_SYMBOL(snd_vx_suspend);
+EXPORT_SYMBOL(snd_vx_resume);
+#endif
diff --git a/sound/drivers/vx/vx_hwdep.c b/sound/drivers/vx/vx_hwdep.c
index c4993b0..d837783 100644
--- a/sound/drivers/vx/vx_hwdep.c
+++ b/sound/drivers/vx/vx_hwdep.c
@@ -30,7 +30,7 @@
 
 #ifdef SND_VX_FW_LOADER
 
-int snd_vx_setup_firmware(vx_core_t *chip)
+int snd_vx_setup_firmware(struct vx_core *chip)
 {
 	static char *fw_files[VX_TYPE_NUMS][4] = {
 		[VX_TYPE_BOARD] = {
@@ -95,7 +95,7 @@
 }
 
 /* exported */
-void snd_vx_free_firmware(vx_core_t *chip)
+void snd_vx_free_firmware(struct vx_core *chip)
 {
 #ifdef CONFIG_PM
 	int i;
@@ -106,17 +106,18 @@
 
 #else /* old style firmware loading */
 
-static int vx_hwdep_open(snd_hwdep_t *hw, struct file *file)
+static int vx_hwdep_open(struct snd_hwdep *hw, struct file *file)
 {
 	return 0;
 }
 
-static int vx_hwdep_release(snd_hwdep_t *hw, struct file *file)
+static int vx_hwdep_release(struct snd_hwdep *hw, struct file *file)
 {
 	return 0;
 }
 
-static int vx_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *info)
+static int vx_hwdep_dsp_status(struct snd_hwdep *hw,
+			       struct snd_hwdep_dsp_status *info)
 {
 	static char *type_ids[VX_TYPE_NUMS] = {
 		[VX_TYPE_BOARD] = "vxboard",
@@ -125,7 +126,7 @@
 		[VX_TYPE_VXPOCKET] = "vxpocket",
 		[VX_TYPE_VXP440] = "vxp440",
 	};
-	vx_core_t *vx = hw->private_data;
+	struct vx_core *vx = hw->private_data;
 
 	snd_assert(type_ids[vx->type], return -EINVAL);
 	strcpy(info->id, type_ids[vx->type]);
@@ -147,9 +148,10 @@
 	}
 }
 
-static int vx_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp)
+static int vx_hwdep_dsp_load(struct snd_hwdep *hw,
+			     struct snd_hwdep_dsp_image *dsp)
 {
-	vx_core_t *vx = hw->private_data;
+	struct vx_core *vx = hw->private_data;
 	int index, err;
 	struct firmware *fw;
 
@@ -216,10 +218,10 @@
 
 
 /* exported */
-int snd_vx_setup_firmware(vx_core_t *chip)
+int snd_vx_setup_firmware(struct vx_core *chip)
 {
 	int err;
-	snd_hwdep_t *hw;
+	struct snd_hwdep *hw;
 
 	if ((err = snd_hwdep_new(chip->card, SND_VX_HWDEP_ID, 0, &hw)) < 0)
 		return err;
@@ -238,7 +240,7 @@
 }
 
 /* exported */
-void snd_vx_free_firmware(vx_core_t *chip)
+void snd_vx_free_firmware(struct vx_core *chip)
 {
 #ifdef CONFIG_PM
 	int i;
diff --git a/sound/drivers/vx/vx_mixer.c b/sound/drivers/vx/vx_mixer.c
index 19fc68c..8ec2c60 100644
--- a/sound/drivers/vx/vx_mixer.c
+++ b/sound/drivers/vx/vx_mixer.c
@@ -30,7 +30,7 @@
 /*
  * write a codec data (24bit)
  */
-static void vx_write_codec_reg(vx_core_t *chip, int codec, unsigned int data)
+static void vx_write_codec_reg(struct vx_core *chip, int codec, unsigned int data)
 {
 	unsigned long flags;
 
@@ -47,7 +47,7 @@
 /*
  * Data type used to access the Codec
  */
-typedef union {
+union vx_codec_data {
 	u32 l;
 #ifdef SNDRV_BIG_ENDIAN
 	struct w {
@@ -72,7 +72,7 @@
 		u8 hh;
 	} b;
 #endif
-} vx_codec_data_t;
+};
 
 #define SET_CDC_DATA_SEL(di,s)          ((di).b.mh = (u8) (s))
 #define SET_CDC_DATA_REG(di,r)          ((di).b.ml = (u8) (r))
@@ -85,9 +85,9 @@
  * @reg: register index
  * @val: data value
  */
-static void vx_set_codec_reg(vx_core_t *chip, int codec, int reg, int val)
+static void vx_set_codec_reg(struct vx_core *chip, int codec, int reg, int val)
 {
-	vx_codec_data_t data;
+	union vx_codec_data data;
 	/* DAC control register */
 	SET_CDC_DATA_INIT(data);
 	SET_CDC_DATA_REG(data, reg);
@@ -102,7 +102,7 @@
  * @left: left output level, 0 = mute
  * @right: right output level
  */
-static void vx_set_analog_output_level(vx_core_t *chip, int codec, int left, int right)
+static void vx_set_analog_output_level(struct vx_core *chip, int codec, int left, int right)
 {
 	left  = chip->hw->output_level_max - left;
 	right = chip->hw->output_level_max - right;
@@ -126,7 +126,7 @@
 #define DAC_ATTEN_MIN	0x08
 #define DAC_ATTEN_MAX	0x38
 
-void vx_toggle_dac_mute(vx_core_t *chip, int mute)
+void vx_toggle_dac_mute(struct vx_core *chip, int mute)
 {
 	unsigned int i;
 	for (i = 0; i < chip->hw->num_codecs; i++) {
@@ -141,7 +141,7 @@
 /*
  * vx_reset_codec - reset and initialize the codecs
  */
-void vx_reset_codec(vx_core_t *chip, int cold_reset)
+void vx_reset_codec(struct vx_core *chip, int cold_reset)
 {
 	unsigned int i;
 	int port = chip->type >= VX_TYPE_VXPOCKET ? 0x75 : 0x65;
@@ -175,7 +175,7 @@
  * change the audio input source
  * @src: the target source (VX_AUDIO_SRC_XXX)
  */
-static void vx_change_audio_source(vx_core_t *chip, int src)
+static void vx_change_audio_source(struct vx_core *chip, int src)
 {
 	unsigned long flags;
 
@@ -192,7 +192,7 @@
  * change the audio source if necessary and possible
  * returns 1 if the source is actually changed.
  */
-int vx_sync_audio_source(vx_core_t *chip)
+int vx_sync_audio_source(struct vx_core *chip)
 {
 	if (chip->audio_source_target == chip->audio_source ||
 	    chip->pcm_running)
@@ -217,7 +217,7 @@
 	short monitor_level;
 };
 
-static int vx_adjust_audio_level(vx_core_t *chip, int audio, int capture,
+static int vx_adjust_audio_level(struct vx_core *chip, int audio, int capture,
 				 struct vx_audio_level *info)
 {
 	struct vx_rmh rmh;
@@ -256,7 +256,7 @@
 
     
 #if 0 // not used
-static int vx_read_audio_level(vx_core_t *chip, int audio, int capture,
+static int vx_read_audio_level(struct vx_core *chip, int audio, int capture,
 			       struct vx_audio_level *info)
 {
 	int err;
@@ -283,7 +283,7 @@
  * set the monitoring level and mute state of the given audio
  * no more static, because must be called from vx_pcm to demute monitoring
  */
-int vx_set_monitor_level(vx_core_t *chip, int audio, int level, int active)
+int vx_set_monitor_level(struct vx_core *chip, int audio, int level, int active)
 {
 	struct vx_audio_level info;
 
@@ -301,7 +301,7 @@
 /*
  * set the mute status of the given audio
  */
-static int vx_set_audio_switch(vx_core_t *chip, int audio, int active)
+static int vx_set_audio_switch(struct vx_core *chip, int audio, int active)
 {
 	struct vx_audio_level info;
 
@@ -315,7 +315,7 @@
 /*
  * set the mute status of the given audio
  */
-static int vx_set_audio_gain(vx_core_t *chip, int audio, int capture, int level)
+static int vx_set_audio_gain(struct vx_core *chip, int audio, int capture, int level)
 {
 	struct vx_audio_level info;
 
@@ -329,7 +329,7 @@
 /*
  * reset all audio levels
  */
-static void vx_reset_audio_levels(vx_core_t *chip)
+static void vx_reset_audio_levels(struct vx_core *chip)
 {
 	unsigned int i, c;
 	struct vx_audio_level info;
@@ -375,7 +375,7 @@
  * @capture: 0 = playback, 1 = capture operation
  * @info: the array of vx_vu_meter records (size = 2).
  */
-static int vx_get_audio_vu_meter(vx_core_t *chip, int audio, int capture, struct vx_vu_meter *info)
+static int vx_get_audio_vu_meter(struct vx_core *chip, int audio, int capture, struct vx_vu_meter *info)
 {
 	struct vx_rmh rmh;
 	int i, err;
@@ -413,9 +413,9 @@
 /*
  * output level control
  */
-static int vx_output_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_output_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
 	uinfo->value.integer.min = 0;
@@ -423,9 +423,9 @@
 	return 0;
 }
 
-static int vx_output_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_output_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int codec = kcontrol->id.index;
 	down(&chip->mixer_mutex);
 	ucontrol->value.integer.value[0] = chip->output_level[codec][0];
@@ -434,9 +434,9 @@
 	return 0;
 }
 
-static int vx_output_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_output_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int codec = kcontrol->id.index;
 	down(&chip->mixer_mutex);
 	if (ucontrol->value.integer.value[0] != chip->output_level[codec][0] ||
@@ -453,7 +453,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vx_control_output_level = {
+static struct snd_kcontrol_new vx_control_output_level = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Master Playback Volume",
 	.info =		vx_output_level_info,
@@ -464,7 +464,7 @@
 /*
  * audio source select
  */
-static int vx_audio_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_audio_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts_mic[3] = {
 		"Digital", "Line", "Mic"
@@ -472,7 +472,7 @@
 	static char *texts_vx2[2] = {
 		"Digital", "Analog"
 	};
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -492,16 +492,16 @@
 	return 0;
 }
 
-static int vx_audio_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_audio_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.enumerated.item[0] = chip->audio_source_target;
 	return 0;
 }
 
-static int vx_audio_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_audio_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	down(&chip->mixer_mutex);
 	if (chip->audio_source_target != ucontrol->value.enumerated.item[0]) {
 		chip->audio_source_target = ucontrol->value.enumerated.item[0];
@@ -513,7 +513,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vx_control_audio_src = {
+static struct snd_kcontrol_new vx_control_audio_src = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Capture Source",
 	.info =		vx_audio_src_info,
@@ -524,7 +524,7 @@
 /*
  * clock mode selection
  */
-static int vx_clock_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_clock_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = {
 		"Auto", "Internal", "External"
@@ -540,16 +540,16 @@
 	return 0;
 }
 
-static int vx_clock_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_clock_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.enumerated.item[0] = chip->clock_mode;
 	return 0;
 }
 
-static int vx_clock_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_clock_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	down(&chip->mixer_mutex);
 	if (chip->clock_mode != ucontrol->value.enumerated.item[0]) {
 		chip->clock_mode = ucontrol->value.enumerated.item[0];
@@ -561,7 +561,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vx_control_clock_mode = {
+static struct snd_kcontrol_new vx_control_clock_mode = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Clock Mode",
 	.info =		vx_clock_mode_info,
@@ -572,7 +572,7 @@
 /*
  * Audio Gain
  */
-static int vx_audio_gain_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_audio_gain_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -581,9 +581,9 @@
 	return 0;
 }
 
-static int vx_audio_gain_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_audio_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int audio = kcontrol->private_value & 0xff;
 	int capture = (kcontrol->private_value >> 8) & 1;
 
@@ -594,9 +594,9 @@
 	return 0;
 }
 
-static int vx_audio_gain_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_audio_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int audio = kcontrol->private_value & 0xff;
 	int capture = (kcontrol->private_value >> 8) & 1;
 
@@ -612,9 +612,9 @@
 	return 0;
 }
 
-static int vx_audio_monitor_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_audio_monitor_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int audio = kcontrol->private_value & 0xff;
 
 	down(&chip->mixer_mutex);
@@ -624,9 +624,9 @@
 	return 0;
 }
 
-static int vx_audio_monitor_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_audio_monitor_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int audio = kcontrol->private_value & 0xff;
 
 	down(&chip->mixer_mutex);
@@ -643,7 +643,7 @@
 	return 0;
 }
 
-static int vx_audio_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_audio_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -652,9 +652,9 @@
 	return 0;
 }
 
-static int vx_audio_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int audio = kcontrol->private_value & 0xff;
 
 	down(&chip->mixer_mutex);
@@ -664,9 +664,9 @@
 	return 0;
 }
 
-static int vx_audio_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int audio = kcontrol->private_value & 0xff;
 
 	down(&chip->mixer_mutex);
@@ -681,9 +681,9 @@
 	return 0;
 }
 
-static int vx_monitor_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int audio = kcontrol->private_value & 0xff;
 
 	down(&chip->mixer_mutex);
@@ -693,9 +693,9 @@
 	return 0;
 }
 
-static int vx_monitor_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	int audio = kcontrol->private_value & 0xff;
 
 	down(&chip->mixer_mutex);
@@ -712,28 +712,28 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vx_control_audio_gain = {
+static struct snd_kcontrol_new vx_control_audio_gain = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	/* name will be filled later */
 	.info =         vx_audio_gain_info,
 	.get =          vx_audio_gain_get,
 	.put =          vx_audio_gain_put
 };
-static snd_kcontrol_new_t vx_control_output_switch = {
+static struct snd_kcontrol_new vx_control_output_switch = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "PCM Playback Switch",
 	.info =         vx_audio_sw_info,
 	.get =          vx_audio_sw_get,
 	.put =          vx_audio_sw_put
 };
-static snd_kcontrol_new_t vx_control_monitor_gain = {
+static struct snd_kcontrol_new vx_control_monitor_gain = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Monitoring Volume",
 	.info =         vx_audio_gain_info,	/* shared */
 	.get =          vx_audio_monitor_get,
 	.put =          vx_audio_monitor_put
 };
-static snd_kcontrol_new_t vx_control_monitor_switch = {
+static struct snd_kcontrol_new vx_control_monitor_switch = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Monitoring Switch",
 	.info =         vx_audio_sw_info,	/* shared */
@@ -745,16 +745,16 @@
 /*
  * IEC958 status bits
  */
-static int vx_iec958_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int vx_iec958_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 
 	down(&chip->mixer_mutex);
 	ucontrol->value.iec958.status[0] = (chip->uer_bits >> 0) & 0xff;
@@ -765,7 +765,7 @@
         return 0;
 }
 
-static int vx_iec958_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_iec958_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = 0xff;
 	ucontrol->value.iec958.status[1] = 0xff;
@@ -774,9 +774,9 @@
         return 0;
 }
 
-static int vx_iec958_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 
 	val = (ucontrol->value.iec958.status[0] << 0) |
@@ -794,7 +794,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vx_control_iec958_mask = {
+static struct snd_kcontrol_new vx_control_iec958_mask = {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
@@ -802,7 +802,7 @@
 	.get =		vx_iec958_mask_get,
 };
 
-static snd_kcontrol_new_t vx_control_iec958 = {
+static struct snd_kcontrol_new vx_control_iec958 = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
 	.info =         vx_iec958_info,
@@ -818,7 +818,7 @@
 #define METER_MAX	0xff
 #define METER_SHIFT	16
 
-static int vx_vu_meter_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_vu_meter_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -827,9 +827,9 @@
 	return 0;
 }
 
-static int vx_vu_meter_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_vu_meter_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	struct vx_vu_meter meter[2];
 	int audio = kcontrol->private_value & 0xff;
 	int capture = (kcontrol->private_value >> 8) & 1;
@@ -840,9 +840,9 @@
 	return 0;
 }
 
-static int vx_peak_meter_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_peak_meter_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	struct vx_vu_meter meter[2];
 	int audio = kcontrol->private_value & 0xff;
 	int capture = (kcontrol->private_value >> 8) & 1;
@@ -853,7 +853,7 @@
 	return 0;
 }
 
-static int vx_saturation_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_saturation_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -862,9 +862,9 @@
 	return 0;
 }
 
-static int vx_saturation_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_saturation_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *chip = snd_kcontrol_chip(kcontrol);
 	struct vx_vu_meter meter[2];
 	int audio = kcontrol->private_value & 0xff;
 
@@ -874,7 +874,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vx_control_vu_meter = {
+static struct snd_kcontrol_new vx_control_vu_meter = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	/* name will be filled later */
@@ -882,7 +882,7 @@
 	.get =		vx_vu_meter_get,
 };
 
-static snd_kcontrol_new_t vx_control_peak_meter = {
+static struct snd_kcontrol_new vx_control_peak_meter = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	/* name will be filled later */
@@ -890,7 +890,7 @@
 	.get =		vx_peak_meter_get,
 };
 
-static snd_kcontrol_new_t vx_control_saturation = {
+static struct snd_kcontrol_new vx_control_saturation = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Input Saturation",
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -904,12 +904,12 @@
  *
  */
 
-int snd_vx_mixer_new(vx_core_t *chip)
+int snd_vx_mixer_new(struct vx_core *chip)
 {
 	unsigned int i, c;
 	int err;
-	snd_kcontrol_new_t temp;
-	snd_card_t *card = chip->card;
+	struct snd_kcontrol_new temp;
+	struct snd_card *card = chip->card;
 	char name[32];
 
 	strcpy(card->mixername, card->driver);
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index 2b46758..464109e 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -61,7 +61,8 @@
  */
 
 /* get the physical page pointer on the given offset */
-static struct page *snd_pcm_get_vmalloc_page(snd_pcm_substream_t *subs, unsigned long offset)
+static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
+					     unsigned long offset)
 {
 	void *pageptr = subs->runtime->dma_area + offset;
 	return vmalloc_to_page(pageptr);
@@ -72,9 +73,9 @@
  * called from hw_params
  * NOTE: this may be called not only once per pcm open!
  */
-static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size)
+static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	if (runtime->dma_area) {
 		/* already allocated */
 		if (runtime->dma_bytes >= size)
@@ -94,9 +95,9 @@
  * called from hw_free callback
  * NOTE: this may be called not only once per pcm open!
  */
-static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs)
+static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	if (runtime->dma_area) {
 		vfree(runtime->dma_area);
 		runtime->dma_area = NULL;
@@ -108,7 +109,8 @@
 /*
  * read three pending pcm bytes via inb()
  */
-static void vx_pcm_read_per_bytes(vx_core_t *chip, snd_pcm_runtime_t *runtime, vx_pipe_t *pipe)
+static void vx_pcm_read_per_bytes(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+				  struct vx_pipe *pipe)
 {
 	int offset = pipe->hw_ptr;
 	unsigned char *buf = (unsigned char *)(runtime->dma_area + offset);
@@ -135,7 +137,8 @@
  * @pc_time: the pointer for the PC-time to set
  * @dsp_time: the pointer for RMH status time array
  */
-static void vx_set_pcx_time(vx_core_t *chip, pcx_time_t *pc_time, unsigned int *dsp_time)
+static void vx_set_pcx_time(struct vx_core *chip, pcx_time_t *pc_time,
+			    unsigned int *dsp_time)
 {
 	dsp_time[0] = (unsigned int)((*pc_time) >> 24) & PCX_TIME_HI_MASK;
 	dsp_time[1] = (unsigned int)(*pc_time) &  MASK_DSP_WORD;
@@ -151,7 +154,8 @@
  *
  * returns the increase of the command length.
  */
-static int vx_set_differed_time(vx_core_t *chip, struct vx_rmh *rmh, vx_pipe_t *pipe)
+static int vx_set_differed_time(struct vx_core *chip, struct vx_rmh *rmh,
+				struct vx_pipe *pipe)
 {
 	/* Update The length added to the RMH command by the timestamp */
 	if (! (pipe->differed_type & DC_DIFFERED_DELAY))
@@ -184,7 +188,8 @@
  * @pipe: the affected pipe
  * @data: format bitmask
  */
-static int vx_set_stream_format(vx_core_t *chip, vx_pipe_t *pipe, unsigned int data)
+static int vx_set_stream_format(struct vx_core *chip, struct vx_pipe *pipe,
+				unsigned int data)
 {
 	struct vx_rmh rmh;
 
@@ -210,8 +215,8 @@
  *
  * returns 0 if successful, or a negative error code.
  */
-static int vx_set_format(vx_core_t *chip, vx_pipe_t *pipe,
-			 snd_pcm_runtime_t *runtime)
+static int vx_set_format(struct vx_core *chip, struct vx_pipe *pipe,
+			 struct snd_pcm_runtime *runtime)
 {
 	unsigned int header = HEADER_FMT_BASE;
 
@@ -239,7 +244,7 @@
 /*
  * set / query the IBL size
  */
-static int vx_set_ibl(vx_core_t *chip, struct vx_ibl_info *info)
+static int vx_set_ibl(struct vx_core *chip, struct vx_ibl_info *info)
 {
 	int err;
 	struct vx_rmh rmh;
@@ -269,7 +274,7 @@
  *
  * called from trigger callback only
  */
-static int vx_get_pipe_state(vx_core_t *chip, vx_pipe_t *pipe, int *state)
+static int vx_get_pipe_state(struct vx_core *chip, struct vx_pipe *pipe, int *state)
 {
 	int err;
 	struct vx_rmh rmh;
@@ -294,7 +299,7 @@
  *       you'll need to disconnect the host to get back to the
  *       normal mode.
  */
-static int vx_query_hbuffer_size(vx_core_t *chip, vx_pipe_t *pipe)
+static int vx_query_hbuffer_size(struct vx_core *chip, struct vx_pipe *pipe)
 {
 	int result;
 	struct vx_rmh rmh;
@@ -318,7 +323,7 @@
  *
  * called from trigger callback only
  */
-static int vx_pipe_can_start(vx_core_t *chip, vx_pipe_t *pipe)
+static int vx_pipe_can_start(struct vx_core *chip, struct vx_pipe *pipe)
 {
 	int err;
 	struct vx_rmh rmh;
@@ -339,7 +344,7 @@
  * vx_conf_pipe - tell the pipe to stand by and wait for IRQA.
  * @pipe: the pipe to be configured
  */
-static int vx_conf_pipe(vx_core_t *chip, vx_pipe_t *pipe)
+static int vx_conf_pipe(struct vx_core *chip, struct vx_pipe *pipe)
 {
 	struct vx_rmh rmh;
 
@@ -353,7 +358,7 @@
 /*
  * vx_send_irqa - trigger IRQA
  */
-static int vx_send_irqa(vx_core_t *chip)
+static int vx_send_irqa(struct vx_core *chip)
 {
 	struct vx_rmh rmh;
 
@@ -378,7 +383,7 @@
  * called from trigger callback only
  *
  */
-static int vx_toggle_pipe(vx_core_t *chip, vx_pipe_t *pipe, int state)
+static int vx_toggle_pipe(struct vx_core *chip, struct vx_pipe *pipe, int state)
 {
 	int err, i, cur_state;
 
@@ -431,7 +436,7 @@
  *
  * called from trigger callback only
  */
-static int vx_stop_pipe(vx_core_t *chip, vx_pipe_t *pipe)
+static int vx_stop_pipe(struct vx_core *chip, struct vx_pipe *pipe)
 {
 	struct vx_rmh rmh;
 	vx_init_rmh(&rmh, CMD_STOP_PIPE);
@@ -449,12 +454,12 @@
  *
  * return 0 on success, or a negative error code.
  */
-static int vx_alloc_pipe(vx_core_t *chip, int capture,
+static int vx_alloc_pipe(struct vx_core *chip, int capture,
 			 int audioid, int num_audio,
-			 vx_pipe_t **pipep)
+			 struct vx_pipe **pipep)
 {
 	int err;
-	vx_pipe_t *pipe;
+	struct vx_pipe *pipe;
 	struct vx_rmh rmh;
 	int data_mode;
 
@@ -499,7 +504,7 @@
  * vx_free_pipe - release a pipe
  * @pipe: pipe to be released
  */
-static int vx_free_pipe(vx_core_t *chip, vx_pipe_t *pipe)
+static int vx_free_pipe(struct vx_core *chip, struct vx_pipe *pipe)
 {
 	struct vx_rmh rmh;
 
@@ -517,7 +522,7 @@
  *
  * called from trigger callback only
  */
-static int vx_start_stream(vx_core_t *chip, vx_pipe_t *pipe)
+static int vx_start_stream(struct vx_core *chip, struct vx_pipe *pipe)
 {
 	struct vx_rmh rmh;
 
@@ -533,7 +538,7 @@
  *
  * called from trigger callback only
  */
-static int vx_stop_stream(vx_core_t *chip, vx_pipe_t *pipe)
+static int vx_stop_stream(struct vx_core *chip, struct vx_pipe *pipe)
 {
 	struct vx_rmh rmh;
 
@@ -547,11 +552,12 @@
  * playback hw information
  */
 
-static snd_pcm_hardware_t vx_pcm_playback_hw = {
+static struct snd_pcm_hardware vx_pcm_playback_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
 				 /*SNDRV_PCM_INFO_RESUME*/),
-	.formats =		/*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
+	.formats =		(/*SNDRV_PCM_FMTBIT_U8 |*/
+				 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		5000,
 	.rate_max =		48000,
@@ -571,11 +577,11 @@
 /*
  * vx_pcm_playback_open - open callback for playback
  */
-static int vx_pcm_playback_open(snd_pcm_substream_t *subs)
+static int vx_pcm_playback_open(struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
-	vx_core_t *chip = snd_pcm_substream_chip(subs);
-	vx_pipe_t *pipe = NULL;
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct vx_core *chip = snd_pcm_substream_chip(subs);
+	struct vx_pipe *pipe = NULL;
 	unsigned int audio;
 	int err;
 
@@ -615,10 +621,10 @@
 /*
  * vx_pcm_playback_close - close callback for playback
  */
-static int vx_pcm_playback_close(snd_pcm_substream_t *subs)
+static int vx_pcm_playback_close(struct snd_pcm_substream *subs)
 {
-	vx_core_t *chip = snd_pcm_substream_chip(subs);
-	vx_pipe_t *pipe;
+	struct vx_core *chip = snd_pcm_substream_chip(subs);
+	struct vx_pipe *pipe;
 
 	if (! subs->runtime->private_data)
 		return -EINVAL;
@@ -641,7 +647,7 @@
  *
  * NB: call with a certain lock.
  */
-static int vx_notify_end_of_buffer(vx_core_t *chip, vx_pipe_t *pipe)
+static int vx_notify_end_of_buffer(struct vx_core *chip, struct vx_pipe *pipe)
 {
 	int err;
 	struct vx_rmh rmh;  /* use a temporary rmh here */
@@ -669,7 +675,9 @@
  *
  * return 0 if ok.
  */
-static int vx_pcm_playback_transfer_chunk(vx_core_t *chip, snd_pcm_runtime_t *runtime, vx_pipe_t *pipe, int size)
+static int vx_pcm_playback_transfer_chunk(struct vx_core *chip,
+					  struct snd_pcm_runtime *runtime,
+					  struct vx_pipe *pipe, int size)
 {
 	int space, err = 0;
 
@@ -705,7 +713,9 @@
  * so that the caller can check the total transferred size later
  * (to call snd_pcm_period_elapsed).
  */
-static int vx_update_pipe_position(vx_core_t *chip, snd_pcm_runtime_t *runtime, vx_pipe_t *pipe)
+static int vx_update_pipe_position(struct vx_core *chip,
+				   struct snd_pcm_runtime *runtime,
+				   struct vx_pipe *pipe)
 {
 	struct vx_rmh rmh;
 	int err, update;
@@ -731,10 +741,12 @@
  * transfer the pending playback buffer data to DSP
  * called from interrupt handler
  */
-static void vx_pcm_playback_transfer(vx_core_t *chip, snd_pcm_substream_t *subs, vx_pipe_t *pipe, int nchunks)
+static void vx_pcm_playback_transfer(struct vx_core *chip,
+				     struct snd_pcm_substream *subs,
+				     struct vx_pipe *pipe, int nchunks)
 {
 	int i, err;
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 
 	if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
 		return;
@@ -749,10 +761,12 @@
  * update the playback position and call snd_pcm_period_elapsed() if necessary
  * called from interrupt handler
  */
-static void vx_pcm_playback_update(vx_core_t *chip, snd_pcm_substream_t *subs, vx_pipe_t *pipe)
+static void vx_pcm_playback_update(struct vx_core *chip,
+				   struct snd_pcm_substream *subs,
+				   struct vx_pipe *pipe)
 {
 	int err;
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 
 	if (pipe->running && ! (chip->chip_status & VX_STAT_IS_STALE)) {
 		if ((err = vx_update_pipe_position(chip, runtime, pipe)) < 0)
@@ -771,9 +785,9 @@
  */
 static void vx_pcm_delayed_start(unsigned long arg)
 {
-	snd_pcm_substream_t *subs = (snd_pcm_substream_t *)arg;
-	vx_core_t *chip = subs->pcm->private_data;
-	vx_pipe_t *pipe = subs->runtime->private_data;
+	struct snd_pcm_substream *subs = (struct snd_pcm_substream *)arg;
+	struct vx_core *chip = subs->pcm->private_data;
+	struct vx_pipe *pipe = subs->runtime->private_data;
 	int err;
 
 	/*  printk( KERN_DEBUG "DDDD tasklet delayed start jiffies = %ld\n", jiffies);*/
@@ -792,10 +806,10 @@
 /*
  * vx_pcm_playback_trigger - trigger callback for playback
  */
-static int vx_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
+static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
 {
-	vx_core_t *chip = snd_pcm_substream_chip(subs);
-	vx_pipe_t *pipe = subs->runtime->private_data;
+	struct vx_core *chip = snd_pcm_substream_chip(subs);
+	struct vx_pipe *pipe = subs->runtime->private_data;
 	int err;
 
 	if (chip->chip_status & VX_STAT_IS_STALE)
@@ -839,18 +853,18 @@
 /*
  * vx_pcm_playback_pointer - pointer callback for playback
  */
-static snd_pcm_uframes_t vx_pcm_playback_pointer(snd_pcm_substream_t *subs)
+static snd_pcm_uframes_t vx_pcm_playback_pointer(struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
-	vx_pipe_t *pipe = runtime->private_data;
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct vx_pipe *pipe = runtime->private_data;
 	return pipe->position;
 }
 
 /*
  * vx_pcm_hw_params - hw_params callback for playback and capture
  */
-static int vx_pcm_hw_params(snd_pcm_substream_t *subs,
-				     snd_pcm_hw_params_t *hw_params)
+static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
+				     struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params));
 }
@@ -858,7 +872,7 @@
 /*
  * vx_pcm_hw_free - hw_free callback for playback and capture
  */
-static int vx_pcm_hw_free(snd_pcm_substream_t *subs)
+static int vx_pcm_hw_free(struct snd_pcm_substream *subs)
 {
 	return snd_pcm_free_vmalloc_buffer(subs);
 }
@@ -866,11 +880,11 @@
 /*
  * vx_pcm_prepare - prepare callback for playback and capture
  */
-static int vx_pcm_prepare(snd_pcm_substream_t *subs)
+static int vx_pcm_prepare(struct snd_pcm_substream *subs)
 {
-	vx_core_t *chip = snd_pcm_substream_chip(subs);
-	snd_pcm_runtime_t *runtime = subs->runtime;
-	vx_pipe_t *pipe = runtime->private_data;
+	struct vx_core *chip = snd_pcm_substream_chip(subs);
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct vx_pipe *pipe = runtime->private_data;
 	int err, data_mode;
 	// int max_size, nchunks;
 
@@ -897,7 +911,8 @@
 	}
 
 	if (chip->pcm_running && chip->freq != runtime->rate) {
-		snd_printk(KERN_ERR "vx: cannot set different clock %d from the current %d\n", runtime->rate, chip->freq);
+		snd_printk(KERN_ERR "vx: cannot set different clock %d "
+			   "from the current %d\n", runtime->rate, chip->freq);
 		return -EINVAL;
 	}
 	vx_set_clock(chip, runtime->rate);
@@ -930,7 +945,7 @@
 /*
  * operators for PCM playback
  */
-static snd_pcm_ops_t vx_pcm_playback_ops = {
+static struct snd_pcm_ops vx_pcm_playback_ops = {
 	.open =		vx_pcm_playback_open,
 	.close =	vx_pcm_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -947,11 +962,12 @@
  * playback hw information
  */
 
-static snd_pcm_hardware_t vx_pcm_capture_hw = {
+static struct snd_pcm_hardware vx_pcm_capture_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID /*|*/
 				 /*SNDRV_PCM_INFO_RESUME*/),
-	.formats =		/*SNDRV_PCM_FMTBIT_U8 |*/ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE,
+	.formats =		(/*SNDRV_PCM_FMTBIT_U8 |*/
+				 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_3LE),
 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		5000,
 	.rate_max =		48000,
@@ -969,12 +985,12 @@
 /*
  * vx_pcm_capture_open - open callback for capture
  */
-static int vx_pcm_capture_open(snd_pcm_substream_t *subs)
+static int vx_pcm_capture_open(struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
-	vx_core_t *chip = snd_pcm_substream_chip(subs);
-	vx_pipe_t *pipe;
-	vx_pipe_t *pipe_out_monitoring = NULL;
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct vx_core *chip = snd_pcm_substream_chip(subs);
+	struct vx_pipe *pipe;
+	struct vx_pipe *pipe_out_monitoring = NULL;
 	unsigned int audio;
 	int err;
 
@@ -1005,9 +1021,11 @@
 		   if an output pipe is available, it's audios still may need to be 
 		   unmuted. hence we'll have to call a mixer entry point.
 		*/
-		vx_set_monitor_level(chip, audio, chip->audio_monitor[audio], chip->audio_monitor_active[audio]);
+		vx_set_monitor_level(chip, audio, chip->audio_monitor[audio],
+				     chip->audio_monitor_active[audio]);
 		/* assuming stereo */
-		vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1], chip->audio_monitor_active[audio+1]); 
+		vx_set_monitor_level(chip, audio+1, chip->audio_monitor[audio+1],
+				     chip->audio_monitor_active[audio+1]); 
 	}
 
 	pipe->monitoring_pipe = pipe_out_monitoring; /* default value NULL */
@@ -1026,11 +1044,11 @@
 /*
  * vx_pcm_capture_close - close callback for capture
  */
-static int vx_pcm_capture_close(snd_pcm_substream_t *subs)
+static int vx_pcm_capture_close(struct snd_pcm_substream *subs)
 {
-	vx_core_t *chip = snd_pcm_substream_chip(subs);
-	vx_pipe_t *pipe;
-	vx_pipe_t *pipe_out_monitoring;
+	struct vx_core *chip = snd_pcm_substream_chip(subs);
+	struct vx_pipe *pipe;
+	struct vx_pipe *pipe_out_monitoring;
 	
 	if (! subs->runtime->private_data)
 		return -EINVAL;
@@ -1062,10 +1080,11 @@
 /*
  * vx_pcm_capture_update - update the capture buffer
  */
-static void vx_pcm_capture_update(vx_core_t *chip, snd_pcm_substream_t *subs, vx_pipe_t *pipe)
+static void vx_pcm_capture_update(struct vx_core *chip, struct snd_pcm_substream *subs,
+				  struct vx_pipe *pipe)
 {
 	int size, space, count;
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 
 	if (! pipe->prepared || (chip->chip_status & VX_STAT_IS_STALE))
 		return;
@@ -1135,17 +1154,17 @@
 /*
  * vx_pcm_capture_pointer - pointer callback for capture
  */
-static snd_pcm_uframes_t vx_pcm_capture_pointer(snd_pcm_substream_t *subs)
+static snd_pcm_uframes_t vx_pcm_capture_pointer(struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
-	vx_pipe_t *pipe = runtime->private_data;
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct vx_pipe *pipe = runtime->private_data;
 	return bytes_to_frames(runtime, pipe->hw_ptr);
 }
 
 /*
  * operators for PCM capture
  */
-static snd_pcm_ops_t vx_pcm_capture_ops = {
+static struct snd_pcm_ops vx_pcm_capture_ops = {
 	.open =		vx_pcm_capture_open,
 	.close =	vx_pcm_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1161,10 +1180,10 @@
 /*
  * interrupt handler for pcm streams
  */
-void vx_pcm_update_intr(vx_core_t *chip, unsigned int events)
+void vx_pcm_update_intr(struct vx_core *chip, unsigned int events)
 {
 	unsigned int i;
-	vx_pipe_t *pipe;
+	struct vx_pipe *pipe;
 
 #define EVENT_MASK	(END_OF_BUFFER_EVENTS_PENDING|ASYNC_EVENTS_PENDING)
 
@@ -1218,7 +1237,7 @@
 /*
  * vx_init_audio_io - check the availabe audio i/o and allocate pipe arrays
  */
-static int vx_init_audio_io(vx_core_t *chip)
+static int vx_init_audio_io(struct vx_core *chip)
 {
 	struct vx_rmh rmh;
 	int preferred;
@@ -1234,19 +1253,20 @@
 	chip->audio_info = rmh.Stat[1];
 
 	/* allocate pipes */
-	chip->playback_pipes = kmalloc(sizeof(vx_pipe_t *) * chip->audio_outs, GFP_KERNEL);
-	chip->capture_pipes = kmalloc(sizeof(vx_pipe_t *) * chip->audio_ins, GFP_KERNEL);
+	chip->playback_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_outs, GFP_KERNEL);
+	chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL);
 	if (! chip->playback_pipes || ! chip->capture_pipes)
 		return -ENOMEM;
 
-	memset(chip->playback_pipes, 0, sizeof(vx_pipe_t *) * chip->audio_outs);
-	memset(chip->capture_pipes, 0, sizeof(vx_pipe_t *) * chip->audio_ins);
+	memset(chip->playback_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_outs);
+	memset(chip->capture_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_ins);
 
 	preferred = chip->ibl.size;
 	chip->ibl.size = 0;
 	vx_set_ibl(chip, &chip->ibl); /* query the info */
 	if (preferred > 0) {
-		chip->ibl.size = ((preferred + chip->ibl.granularity - 1) / chip->ibl.granularity) * chip->ibl.granularity;
+		chip->ibl.size = ((preferred + chip->ibl.granularity - 1) /
+				  chip->ibl.granularity) * chip->ibl.granularity;
 		if (chip->ibl.size > chip->ibl.max_size)
 			chip->ibl.size = chip->ibl.max_size;
 	} else
@@ -1260,9 +1280,9 @@
 /*
  * free callback for pcm
  */
-static void snd_vx_pcm_free(snd_pcm_t *pcm)
+static void snd_vx_pcm_free(struct snd_pcm *pcm)
 {
-	vx_core_t *chip = pcm->private_data;
+	struct vx_core *chip = pcm->private_data;
 	chip->pcm[pcm->device] = NULL;
 	kfree(chip->playback_pipes);
 	chip->playback_pipes = NULL;
@@ -1273,9 +1293,9 @@
 /*
  * snd_vx_pcm_new - create and initialize a pcm
  */
-int snd_vx_pcm_new(vx_core_t *chip)
+int snd_vx_pcm_new(struct vx_core *chip)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	unsigned int i;
 	int err;
 
diff --git a/sound/drivers/vx/vx_uer.c b/sound/drivers/vx/vx_uer.c
index 4fc38bd..7400306 100644
--- a/sound/drivers/vx/vx_uer.c
+++ b/sound/drivers/vx/vx_uer.c
@@ -31,7 +31,7 @@
  * vx_modify_board_clock - tell the board that its clock has been modified
  * @sync: DSP needs to resynchronize its FIFO
  */
-static int vx_modify_board_clock(vx_core_t *chip, int sync)
+static int vx_modify_board_clock(struct vx_core *chip, int sync)
 {
 	struct vx_rmh rmh;
 
@@ -45,7 +45,7 @@
 /*
  * vx_modify_board_inputs - resync audio inputs
  */
-static int vx_modify_board_inputs(vx_core_t *chip)
+static int vx_modify_board_inputs(struct vx_core *chip)
 {
 	struct vx_rmh rmh;
 
@@ -59,7 +59,7 @@
  * @index: the bit index
  * returns 0 or 1.
  */
-static int vx_read_one_cbit(vx_core_t *chip, int index)
+static int vx_read_one_cbit(struct vx_core *chip, int index)
 {
 	unsigned long flags;
 	int val;
@@ -82,7 +82,7 @@
  * @index: the bit index
  * @val: bit value, 0 or 1
  */
-static void vx_write_one_cbit(vx_core_t *chip, int index, int val)
+static void vx_write_one_cbit(struct vx_core *chip, int index, int val)
 {
 	unsigned long flags;
 	val = !!val;	/* 0 or 1 */
@@ -104,7 +104,7 @@
  * returns the frequency of UER, or 0 if not sync,
  * or a negative error code.
  */
-static int vx_read_uer_status(vx_core_t *chip, int *mode)
+static int vx_read_uer_status(struct vx_core *chip, int *mode)
 {
 	int val, freq;
 
@@ -160,7 +160,7 @@
  *    default        : HexFreq = (dword) ((double) 28224000 / (double) (Frequency*4)) - 0x000001FF
  */
 
-static int vx_calc_clock_from_freq(vx_core_t *chip, int freq)
+static int vx_calc_clock_from_freq(struct vx_core *chip, int freq)
 {
 	int hexfreq;
 
@@ -187,7 +187,7 @@
  * vx_change_clock_source - change the clock source
  * @source: the new source
  */
-static void vx_change_clock_source(vx_core_t *chip, int source)
+static void vx_change_clock_source(struct vx_core *chip, int source)
 {
 	unsigned long flags;
 
@@ -205,7 +205,7 @@
 /*
  * set the internal clock
  */
-void vx_set_internal_clock(vx_core_t *chip, unsigned int freq)
+void vx_set_internal_clock(struct vx_core *chip, unsigned int freq)
 {
 	int clock;
 	unsigned long flags;
@@ -228,7 +228,7 @@
  * set the iec958 status bits
  * @bits: 32-bit status bits
  */
-void vx_set_iec958_status(vx_core_t *chip, unsigned int bits)
+void vx_set_iec958_status(struct vx_core *chip, unsigned int bits)
 {
 	int i;
 
@@ -243,7 +243,7 @@
 /*
  * vx_set_clock - change the clock and audio source if necessary
  */
-int vx_set_clock(vx_core_t *chip, unsigned int freq)
+int vx_set_clock(struct vx_core *chip, unsigned int freq)
 {
 	int src_changed = 0;
 
@@ -285,7 +285,7 @@
 /*
  * vx_change_frequency - called from interrupt handler
  */
-int vx_change_frequency(vx_core_t *chip)
+int vx_change_frequency(struct vx_core *chip)
 {
 	int freq;
 
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index 1a05cfb..9deba80 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -30,7 +30,7 @@
 #include <sound/cs8427.h>
 #include <sound/asoundef.h>
 
-static void snd_cs8427_reset(snd_i2c_device_t *cs8427);
+static void snd_cs8427_reset(struct snd_i2c_device *cs8427);
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
 MODULE_DESCRIPTION("IEC958 (S/PDIF) receiver & transmitter by Cirrus Logic");
@@ -38,22 +38,22 @@
 
 #define CS8427_ADDR			(0x20>>1) /* fixed address */
 
-typedef struct {
-	snd_pcm_substream_t *substream;
+struct cs8427_stream {
+	struct snd_pcm_substream *substream;
 	char hw_status[24];		/* hardware status */
 	char def_status[24];		/* default status */
 	char pcm_status[24];		/* PCM private status */
 	char hw_udata[32];
-	snd_kcontrol_t *pcm_ctl;
-} cs8427_stream_t;
+	struct snd_kcontrol *pcm_ctl;
+};
 
-typedef struct {
+struct cs8427 {
 	unsigned char regmap[0x14];	/* map of first 1 + 13 registers */
 	unsigned int rate;
 	unsigned int reset_timeout;
-	cs8427_stream_t playback;
-	cs8427_stream_t capture;
-} cs8427_t;
+	struct cs8427_stream playback;
+	struct cs8427_stream capture;
+};
 
 static unsigned char swapbits(unsigned char val)
 {
@@ -67,7 +67,8 @@
 	return res;
 }
 
-int snd_cs8427_reg_write(snd_i2c_device_t *device, unsigned char reg, unsigned char val)
+int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
+			 unsigned char val)
 {
 	int err;
 	unsigned char buf[2];
@@ -81,7 +82,7 @@
 	return 0;
 }
 
-static int snd_cs8427_reg_read(snd_i2c_device_t *device, unsigned char reg)
+static int snd_cs8427_reg_read(struct snd_i2c_device *device, unsigned char reg)
 {
 	int err;
 	unsigned char buf;
@@ -97,28 +98,29 @@
 	return buf;
 }
 
-static int snd_cs8427_select_corudata(snd_i2c_device_t *device, int udata)
+static int snd_cs8427_select_corudata(struct snd_i2c_device *device, int udata)
 {
-	cs8427_t *chip = device->private_data;
+	struct cs8427 *chip = device->private_data;
 	int err;
 
 	udata = udata ? CS8427_BSEL : 0;
 	if (udata != (chip->regmap[CS8427_REG_CSDATABUF] & udata)) {
 		chip->regmap[CS8427_REG_CSDATABUF] &= ~CS8427_BSEL;
 		chip->regmap[CS8427_REG_CSDATABUF] |= udata;
-		err = snd_cs8427_reg_write(device, CS8427_REG_CSDATABUF, chip->regmap[CS8427_REG_CSDATABUF]);
+		err = snd_cs8427_reg_write(device, CS8427_REG_CSDATABUF,
+					   chip->regmap[CS8427_REG_CSDATABUF]);
 		if (err < 0)
 			return err;
 	}
 	return 0;
 }
 
-static int snd_cs8427_send_corudata(snd_i2c_device_t *device,
+static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
 				    int udata,
 				    unsigned char *ndata,
 				    int count)
 {
-	cs8427_t *chip = device->private_data;
+	struct cs8427 *chip = device->private_data;
 	char *hw_data = udata ? chip->playback.hw_udata : chip->playback.hw_status;
 	char data[32];
 	int err, idx;
@@ -133,7 +135,8 @@
 		if (memcmp(hw_data, data, count) == 0) {
 			chip->regmap[CS8427_REG_UDATABUF] &= ~CS8427_UBMMASK;
 			chip->regmap[CS8427_REG_UDATABUF] |= CS8427_UBMZEROS | CS8427_EFTUI;
-			if ((err = snd_cs8427_reg_write(device, CS8427_REG_UDATABUF, chip->regmap[CS8427_REG_UDATABUF])) < 0)
+			if ((err = snd_cs8427_reg_write(device, CS8427_REG_UDATABUF,
+							chip->regmap[CS8427_REG_UDATABUF])) < 0)
 				return err;
 			return 0;
 		}
@@ -146,15 +149,15 @@
 	return 1;
 }
 
-static void snd_cs8427_free(snd_i2c_device_t *device)
+static void snd_cs8427_free(struct snd_i2c_device *device)
 {
 	kfree(device->private_data);
 }
 
-int snd_cs8427_create(snd_i2c_bus_t *bus,
+int snd_cs8427_create(struct snd_i2c_bus *bus,
 		      unsigned char addr,
 		      unsigned int reset_timeout,
-		      snd_i2c_device_t **r_cs8427)
+		      struct snd_i2c_device **r_cs8427)
 {
 	static unsigned char initvals1[] = {
 	  CS8427_REG_CONTROL1 | CS8427_REG_AUTOINC,
@@ -194,11 +197,12 @@
 	  CS8427_UD | CS8427_EFTUI | CS8427_DETUI,
 	};
 	int err;
-	cs8427_t *chip;
-	snd_i2c_device_t *device;
+	struct cs8427 *chip;
+	struct snd_i2c_device *device;
 	unsigned char buf[24];
 
-	if ((err = snd_i2c_device_create(bus, "CS8427", CS8427_ADDR | (addr & 7), &device)) < 0)
+	if ((err = snd_i2c_device_create(bus, "CS8427", CS8427_ADDR | (addr & 7),
+					 &device)) < 0)
 		return err;
 	chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL) {
@@ -208,9 +212,13 @@
 	device->private_free = snd_cs8427_free;
 	
 	snd_i2c_lock(bus);
-	if ((err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER)) != CS8427_VER8427A) {
+	if ((err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER)) !=
+	    CS8427_VER8427A) {
 		snd_i2c_unlock(bus);
-		snd_printk(KERN_ERR "unable to find CS8427 signature (expected 0x%x, read 0x%x), initialization is not completed\n", CS8427_VER8427A, err);
+		snd_printk(KERN_ERR "unable to find CS8427 signature "
+			   "(expected 0x%x, read 0x%x),\n",
+			   CS8427_VER8427A, err);
+		snd_printk(KERN_ERR "   initialization is not completed\n");
 		return -EFAULT;
 	}
 	/* turn off run bit while making changes to configuration */
@@ -279,9 +287,9 @@
  * put back AES3INPUT. This workaround is described in latest
  * CS8427 datasheet, otherwise TXDSERIAL will not work.
  */
-static void snd_cs8427_reset(snd_i2c_device_t *cs8427)
+static void snd_cs8427_reset(struct snd_i2c_device *cs8427)
 {
-	cs8427_t *chip;
+	struct cs8427 *chip;
 	unsigned long end_time;
 	int data;
 
@@ -289,10 +297,12 @@
 	chip = cs8427->private_data;
 	snd_i2c_lock(cs8427->bus);
 	chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~(CS8427_RUN | CS8427_RXDMASK);
-	snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, chip->regmap[CS8427_REG_CLOCKSOURCE]);
+	snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
+			     chip->regmap[CS8427_REG_CLOCKSOURCE]);
 	udelay(200);
 	chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RUN | CS8427_RXDILRCK;
-	snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, chip->regmap[CS8427_REG_CLOCKSOURCE]);
+	snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
+			     chip->regmap[CS8427_REG_CLOCKSOURCE]);
 	udelay(200);
 	snd_i2c_unlock(cs8427->bus);
 	end_time = jiffies + chip->reset_timeout;
@@ -307,12 +317,13 @@
 	snd_i2c_lock(cs8427->bus);
 	chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
 	chip->regmap[CS8427_REG_CLOCKSOURCE] |= CS8427_RXDAES3INPUT;
-	snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE, chip->regmap[CS8427_REG_CLOCKSOURCE]);
+	snd_cs8427_reg_write(cs8427, CS8427_REG_CLOCKSOURCE,
+			     chip->regmap[CS8427_REG_CLOCKSOURCE]);
 	snd_i2c_unlock(cs8427->bus);
 }
 
-static int snd_cs8427_in_status_info(snd_kcontrol_t *kcontrol,
-				     snd_ctl_elem_info_t *uinfo)
+static int snd_cs8427_in_status_info(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -321,10 +332,10 @@
 	return 0;
 }
 
-static int snd_cs8427_in_status_get(snd_kcontrol_t *kcontrol,
-				    snd_ctl_elem_value_t *ucontrol)
+static int snd_cs8427_in_status_get(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
 {
-	snd_i2c_device_t *device = snd_kcontrol_chip(kcontrol);
+	struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
 	int data;
 
 	snd_i2c_lock(device->bus);
@@ -336,18 +347,18 @@
 	return 0;
 }
 
-static int snd_cs8427_qsubcode_info(snd_kcontrol_t *kcontrol,
-				    snd_ctl_elem_info_t *uinfo)
+static int snd_cs8427_qsubcode_info(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
 	uinfo->count = 10;
 	return 0;
 }
 
-static int snd_cs8427_qsubcode_get(snd_kcontrol_t *kcontrol,
-				   snd_ctl_elem_value_t *ucontrol)
+static int snd_cs8427_qsubcode_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	snd_i2c_device_t *device = snd_kcontrol_chip(kcontrol);
+	struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
 	unsigned char reg = CS8427_REG_QSUBCODE;
 	int err;
 
@@ -366,18 +377,18 @@
 	return 0;
 }
 
-static int snd_cs8427_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_cs8427_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_cs8427_spdif_get(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+static int snd_cs8427_spdif_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	snd_i2c_device_t *device = snd_kcontrol_chip(kcontrol);
-	cs8427_t *chip = device->private_data;
+	struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
+	struct cs8427 *chip = device->private_data;
 	
 	snd_i2c_lock(device->bus);
 	memcpy(ucontrol->value.iec958.status, chip->playback.def_status, 24);
@@ -385,13 +396,15 @@
 	return 0;
 }
 
-static int snd_cs8427_spdif_put(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+static int snd_cs8427_spdif_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	snd_i2c_device_t *device = snd_kcontrol_chip(kcontrol);
-	cs8427_t *chip = device->private_data;
-	unsigned char *status = kcontrol->private_value ? chip->playback.pcm_status : chip->playback.def_status;
-	snd_pcm_runtime_t *runtime = chip->playback.substream ? chip->playback.substream->runtime : NULL;
+	struct snd_i2c_device *device = snd_kcontrol_chip(kcontrol);
+	struct cs8427 *chip = device->private_data;
+	unsigned char *status = kcontrol->private_value ?
+		chip->playback.pcm_status : chip->playback.def_status;
+	struct snd_pcm_runtime *runtime = chip->playback.substream ?
+		chip->playback.substream->runtime : NULL;
 	int err, change;
 
 	snd_i2c_lock(device->bus);
@@ -406,21 +419,22 @@
 	return change;
 }
 
-static int snd_cs8427_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_cs8427_spdif_mask_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_cs8427_spdif_mask_get(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_cs8427_spdif_mask_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
 	memset(ucontrol->value.iec958.status, 0xff, 24);
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_cs8427_iec958_controls[] = {
+static struct snd_kcontrol_new snd_cs8427_iec958_controls[] = {
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.info =		snd_cs8427_in_status_info,
@@ -469,12 +483,12 @@
 	.get =		snd_cs8427_qsubcode_get
 }};
 
-int snd_cs8427_iec958_build(snd_i2c_device_t *cs8427,
-			    snd_pcm_substream_t *play_substream,
-			    snd_pcm_substream_t *cap_substream)
+int snd_cs8427_iec958_build(struct snd_i2c_device *cs8427,
+			    struct snd_pcm_substream *play_substream,
+			    struct snd_pcm_substream *cap_substream)
 {
-	cs8427_t *chip = cs8427->private_data;
-	snd_kcontrol_t *kctl;
+	struct cs8427 *chip = cs8427->private_data;
+	struct snd_kcontrol *kctl;
 	unsigned int idx;
 	int err;
 
@@ -498,9 +512,9 @@
 	return 0;
 }
 
-int snd_cs8427_iec958_active(snd_i2c_device_t *cs8427, int active)
+int snd_cs8427_iec958_active(struct snd_i2c_device *cs8427, int active)
 {
-	cs8427_t *chip;
+	struct cs8427 *chip;
 
 	snd_assert(cs8427, return -ENXIO);
 	chip = cs8427->private_data;
@@ -512,9 +526,9 @@
 	return 0;
 }
 
-int snd_cs8427_iec958_pcm(snd_i2c_device_t *cs8427, unsigned int rate)
+int snd_cs8427_iec958_pcm(struct snd_i2c_device *cs8427, unsigned int rate)
 {
-	cs8427_t *chip;
+	struct cs8427 *chip;
 	char *status;
 	int err, reset;
 
diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c
index e4e505b..c4e1f2c 100644
--- a/sound/i2c/i2c.c
+++ b/sound/i2c/i2c.c
@@ -32,20 +32,23 @@
 MODULE_DESCRIPTION("Generic i2c interface for ALSA");
 MODULE_LICENSE("GPL");
 
-static int snd_i2c_bit_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count);
-static int snd_i2c_bit_readbytes(snd_i2c_device_t *device, unsigned char *bytes, int count);
-static int snd_i2c_bit_probeaddr(snd_i2c_bus_t *bus, unsigned short addr);
+static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
+				 unsigned char *bytes, int count);
+static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
+				 unsigned char *bytes, int count);
+static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus,
+				 unsigned short addr);
 
-static snd_i2c_ops_t snd_i2c_bit_ops = {
+static struct snd_i2c_ops snd_i2c_bit_ops = {
 	.sendbytes = snd_i2c_bit_sendbytes,
 	.readbytes = snd_i2c_bit_readbytes,
 	.probeaddr = snd_i2c_bit_probeaddr,
 };
 
-static int snd_i2c_bus_free(snd_i2c_bus_t *bus)
+static int snd_i2c_bus_free(struct snd_i2c_bus *bus)
 {
-	snd_i2c_bus_t *slave;
-	snd_i2c_device_t *device;
+	struct snd_i2c_bus *slave;
+	struct snd_i2c_device *device;
 
 	snd_assert(bus != NULL, return -EINVAL);
 	while (!list_empty(&bus->devices)) {
@@ -66,17 +69,18 @@
 	return 0;
 }
 
-static int snd_i2c_bus_dev_free(snd_device_t *device)
+static int snd_i2c_bus_dev_free(struct snd_device *device)
 {
-	snd_i2c_bus_t *bus = device->device_data;
+	struct snd_i2c_bus *bus = device->device_data;
 	return snd_i2c_bus_free(bus);
 }
 
-int snd_i2c_bus_create(snd_card_t *card, const char *name, snd_i2c_bus_t *master, snd_i2c_bus_t **ri2c)
+int snd_i2c_bus_create(struct snd_card *card, const char *name,
+		       struct snd_i2c_bus *master, struct snd_i2c_bus **ri2c)
 {
-	snd_i2c_bus_t *bus;
+	struct snd_i2c_bus *bus;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_i2c_bus_dev_free,
 	};
 
@@ -102,9 +106,10 @@
 	return 0;
 }
 
-int snd_i2c_device_create(snd_i2c_bus_t *bus, const char *name, unsigned char addr, snd_i2c_device_t **rdevice)
+int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
+			  unsigned char addr, struct snd_i2c_device **rdevice)
 {
-	snd_i2c_device_t *device;
+	struct snd_i2c_device *device;
 
 	*rdevice = NULL;
 	snd_assert(bus != NULL, return -EINVAL);
@@ -119,7 +124,7 @@
 	return 0;
 }
 
-int snd_i2c_device_free(snd_i2c_device_t *device)
+int snd_i2c_device_free(struct snd_i2c_device *device)
 {
 	if (device->bus)
 		list_del(&device->list);
@@ -129,18 +134,18 @@
 	return 0;
 }
 
-int snd_i2c_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
+int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
 {
 	return device->bus->ops->sendbytes(device, bytes, count);
 }
 
 
-int snd_i2c_readbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
+int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
 {
 	return device->bus->ops->readbytes(device, bytes, count);
 }
 
-int snd_i2c_probeaddr(snd_i2c_bus_t *bus, unsigned short addr)
+int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
 {
 	return bus->ops->probeaddr(bus, addr);
 }
@@ -149,31 +154,31 @@
  *  bit-operations
  */
 
-static inline void snd_i2c_bit_hw_start(snd_i2c_bus_t *bus)
+static inline void snd_i2c_bit_hw_start(struct snd_i2c_bus *bus)
 {
 	if (bus->hw_ops.bit->start)
 		bus->hw_ops.bit->start(bus);
 }
 
-static inline void snd_i2c_bit_hw_stop(snd_i2c_bus_t *bus)
+static inline void snd_i2c_bit_hw_stop(struct snd_i2c_bus *bus)
 {
 	if (bus->hw_ops.bit->stop)
 		bus->hw_ops.bit->stop(bus);
 }
 
-static void snd_i2c_bit_direction(snd_i2c_bus_t *bus, int clock, int data)
+static void snd_i2c_bit_direction(struct snd_i2c_bus *bus, int clock, int data)
 {
 	if (bus->hw_ops.bit->direction)
 		bus->hw_ops.bit->direction(bus, clock, data);
 }
 
-static void snd_i2c_bit_set(snd_i2c_bus_t *bus, int clock, int data)
+static void snd_i2c_bit_set(struct snd_i2c_bus *bus, int clock, int data)
 {
 	bus->hw_ops.bit->setlines(bus, clock, data);
 }
 
 #if 0
-static int snd_i2c_bit_clock(snd_i2c_bus_t *bus)
+static int snd_i2c_bit_clock(struct snd_i2c_bus *bus)
 {
 	if (bus->hw_ops.bit->getclock)
 		return bus->hw_ops.bit->getclock(bus);
@@ -181,12 +186,12 @@
 }
 #endif
 
-static int snd_i2c_bit_data(snd_i2c_bus_t *bus, int ack)
+static int snd_i2c_bit_data(struct snd_i2c_bus *bus, int ack)
 {
 	return bus->hw_ops.bit->getdata(bus, ack);
 }
 
-static void snd_i2c_bit_start(snd_i2c_bus_t *bus)
+static void snd_i2c_bit_start(struct snd_i2c_bus *bus)
 {
 	snd_i2c_bit_hw_start(bus);
 	snd_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
@@ -195,7 +200,7 @@
 	snd_i2c_bit_set(bus, 0, 0);
 }
 
-static void snd_i2c_bit_stop(snd_i2c_bus_t *bus)
+static void snd_i2c_bit_stop(struct snd_i2c_bus *bus)
 {
 	snd_i2c_bit_set(bus, 0, 0);
 	snd_i2c_bit_set(bus, 1, 0);
@@ -203,14 +208,14 @@
 	snd_i2c_bit_hw_stop(bus);
 }
 
-static void snd_i2c_bit_send(snd_i2c_bus_t *bus, int data)
+static void snd_i2c_bit_send(struct snd_i2c_bus *bus, int data)
 {
 	snd_i2c_bit_set(bus, 0, data);
 	snd_i2c_bit_set(bus, 1, data);
 	snd_i2c_bit_set(bus, 0, data);
 }
 
-static int snd_i2c_bit_ack(snd_i2c_bus_t *bus)
+static int snd_i2c_bit_ack(struct snd_i2c_bus *bus)
 {
 	int ack;
 
@@ -223,7 +228,7 @@
 	return ack ? -EIO : 0;
 }
 
-static int snd_i2c_bit_sendbyte(snd_i2c_bus_t *bus, unsigned char data)
+static int snd_i2c_bit_sendbyte(struct snd_i2c_bus *bus, unsigned char data)
 {
 	int i, err;
 
@@ -234,7 +239,7 @@
 	return 0;
 }
 
-static int snd_i2c_bit_readbyte(snd_i2c_bus_t *bus, int last)
+static int snd_i2c_bit_readbyte(struct snd_i2c_bus *bus, int last)
 {
 	int i;
 	unsigned char data = 0;
@@ -252,9 +257,10 @@
 	return data;
 }
 
-static int snd_i2c_bit_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
+static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
+				 unsigned char *bytes, int count)
 {
-	snd_i2c_bus_t *bus = device->bus;
+	struct snd_i2c_bus *bus = device->bus;
 	int err, res = 0;
 
 	if (device->flags & SND_I2C_DEVICE_ADDRTEN)
@@ -275,9 +281,10 @@
 	return res;
 }
 
-static int snd_i2c_bit_readbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
+static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
+				 unsigned char *bytes, int count)
 {
-	snd_i2c_bus_t *bus = device->bus;
+	struct snd_i2c_bus *bus = device->bus;
 	int err, res = 0;
 
 	if (device->flags & SND_I2C_DEVICE_ADDRTEN)
@@ -299,7 +306,7 @@
 	return res;
 }
 
-static int snd_i2c_bit_probeaddr(snd_i2c_bus_t *bus, unsigned short addr)
+static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
 {
 	int err;
 
diff --git a/sound/i2c/l3/uda1341.c b/sound/i2c/l3/uda1341.c
index 103a7dc..746500e 100644
--- a/sound/i2c/l3/uda1341.c
+++ b/sound/i2c/l3/uda1341.c
@@ -17,7 +17,7 @@
  * 2002-05-12   Tomas Kasparek  another code cleanup
  */
 
-/* $Id: uda1341.c,v 1.16 2005/09/09 13:22:34 tiwai Exp $ */
+/* $Id: uda1341.c,v 1.18 2005/11/17 14:17:21 tiwai Exp $ */
 
 #include <sound/driver.h>
 #include <linux/module.h>
@@ -56,6 +56,33 @@
 
 /* }}} */
 
+
+static const char *peak_names[] = {
+	"before",
+	"after",
+};
+
+static const char *filter_names[] = {
+	"flat",
+	"min",
+	"min",
+	"max",
+};
+
+static const char *mixer_names[] = {
+	"double differential",
+	"input channel 1 (line in)",
+	"input channel 2 (microphone)",
+	"digital mixer",
+};
+
+static const char *deemp_names[] = {
+	"none",
+	"32 kHz",
+	"44.1 kHz",
+	"48 kHz",        
+};
+
 enum uda1341_regs_names {
 	stat0,
 	stat1,
@@ -73,7 +100,7 @@
 	uda1341_reg_last,
 };
 
-const char *uda1341_reg_names[] = {
+static const char *uda1341_reg_names[] = {
 	"stat 0 ",
 	"stat 1 ",
 	"data 00",
@@ -89,7 +116,7 @@
 	"ext 6",
 };
 
-const int uda1341_enum_items[] = {
+static const int uda1341_enum_items[] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	2, //peak - before/after
 	4, //deemp - none/32/44.1/48
@@ -100,7 +127,7 @@
 	0, 0, 0, 0, 0,
 };
 
-const char ** uda1341_enum_names[] = {
+static const char ** uda1341_enum_names[] = {
 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 	peak_names, //peak - before/after
 	deemp_names, //deemp - none/32/44.1/48
@@ -113,15 +140,13 @@
 
 typedef int uda1341_cfg[CMD_LAST];
 
-typedef struct uda1341 uda1341_t;
-
 struct uda1341 {
 	int (*write) (struct l3_client *uda1341, unsigned short reg, unsigned short val);
 	int (*read) (struct l3_client *uda1341, unsigned short reg);        
 	unsigned char regs[uda1341_reg_last];
 	int active;
 	spinlock_t reg_lock;
-	snd_card_t *card;
+	struct snd_card *card;
 	uda1341_cfg cfg;
 #ifdef CONFIG_PM
 	unsigned char suspend_regs[uda1341_reg_last];
@@ -129,11 +154,9 @@
 #endif
 };
 
-//hack for ALSA magic casting
-typedef struct l3_client l3_client_t;
-
 /* transfer 8bit integer into string with binary representation */
-void int2str_bin8(uint8_t val, char *buf){
+static void int2str_bin8(uint8_t val, char *buf)
+{
 	const int size = sizeof(val) * 8;
 	int i;
 
@@ -146,7 +169,7 @@
 
 /* {{{ HW manipulation routines */
 
-int snd_uda1341_codec_write(struct l3_client *clnt, unsigned short reg, unsigned short val)
+static int snd_uda1341_codec_write(struct l3_client *clnt, unsigned short reg, unsigned short val)
 {
 	struct uda1341 *uda = clnt->driver_data;
 	unsigned char buf[2] = { 0xc0, 0xe0 }; // for EXT addressing
@@ -171,7 +194,7 @@
 	return err;
 }
 
-int snd_uda1341_codec_read(struct l3_client *clnt, unsigned short reg)
+static int snd_uda1341_codec_read(struct l3_client *clnt, unsigned short reg)
 {
 	unsigned char val;
 	int err;
@@ -188,8 +211,9 @@
 	return reg < uda1341_reg_last;
 }
 
-int snd_uda1341_update_bits(struct l3_client *clnt, unsigned short reg, unsigned short mask,
-                            unsigned short shift, unsigned short value, int flush)
+static int snd_uda1341_update_bits(struct l3_client *clnt, unsigned short reg,
+				   unsigned short mask, unsigned short shift,
+				   unsigned short value, int flush)
 {
 	int change;
 	unsigned short old, new;
@@ -214,8 +238,8 @@
 	return change;
 }
 
-int snd_uda1341_cfg_write(struct l3_client *clnt, unsigned short what,
-                          unsigned short value, int flush)
+static int snd_uda1341_cfg_write(struct l3_client *clnt, unsigned short what,
+				 unsigned short value, int flush)
 {
 	struct uda1341 *uda = clnt->driver_data;
 	int ret = 0;
@@ -327,9 +351,84 @@
 /* }}} */
 
 /* {{{ Proc interface */
+#ifdef CONFIG_PROC_FS
 
-static void snd_uda1341_proc_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static const char *format_names[] = {
+	"I2S-bus",
+	"LSB 16bits",
+	"LSB 18bits",
+	"LSB 20bits",
+	"MSB",
+	"in LSB 16bits/out MSB",
+	"in LSB 18bits/out MSB",
+	"in LSB 20bits/out MSB",        
+};
+
+static const char *fs_names[] = {
+	"512*fs",
+	"384*fs",
+	"256*fs",
+	"Unused - bad value!",
+};
+
+static const char* bass_values[][16] = {
+	{"0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB", "0 dB",
+	 "0 dB", "0 dB", "0 dB", "0 dB", "undefined", }, //flat
+	{"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB",
+	 "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min
+	{"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "18 dB",
+	 "18 dB", "18 dB", "18 dB", "18 dB", "undefined",}, // min
+	{"0 dB", "2 dB", "4 dB", "6 dB", "8 dB", "10 dB", "12 dB", "14 dB", "16 dB", "18 dB", "20 dB",
+	 "22 dB", "24 dB", "24 dB", "24 dB", "undefined",}, // max
+};
+
+static const char *mic_sens_value[] = {
+	"-3 dB", "0 dB", "3 dB", "9 dB", "15 dB", "21 dB", "27 dB", "not used",
+};
+
+static const unsigned short AGC_atime[] = {
+	11, 16, 11, 16, 21, 11, 16, 21,
+};
+
+static const unsigned short AGC_dtime[] = {
+	100, 100, 200, 200, 200, 400, 400, 400,
+};
+
+static const char *AGC_level[] = {
+	"-9.0", "-11.5", "-15.0", "-17.5",
+};
+
+static const char *ig_small_value[] = {
+	"-3.0", "-2.5", "-2.0", "-1.5", "-1.0", "-0.5",
+};
+
+/*
+ * this was computed as peak_value[i] = pow((63-i)*1.42,1.013)
+ *
+ * UDA1341 datasheet on page 21: Peak value (dB) = (Peak level - 63.5)*5*log2
+ * There is an table with these values [level]=value: [3]=-90.31, [7]=-84.29
+ * [61]=-2.78, [62] = -1.48, [63] = 0.0
+ * I tried to compute it, but using but even using logarithm with base either 10 or 2
+ * i was'n able to get values in the table from the formula. So I constructed another
+ * formula (see above) to interpolate the values as good as possible. If there is some
+ * mistake, please contact me on tomas.kasparek@seznam.cz. Thanks.
+ * UDA1341TS datasheet is available at:
+ *   http://www-us9.semiconductors.com/acrobat/datasheets/UDA1341TS_3.pdf 
+ */
+static const char *peak_value[] = {
+	"-INF dB", "N.A.", "N.A", "90.31 dB", "N.A.", "N.A.", "N.A.", "-84.29 dB",
+	"-82.65 dB", "-81.13 dB", "-79.61 dB", "-78.09 dB", "-76.57 dB", "-75.05 dB", "-73.53 dB",
+	"-72.01 dB", "-70.49 dB", "-68.97 dB", "-67.45 dB", "-65.93 dB", "-64.41 dB", "-62.90 dB",
+	"-61.38 dB", "-59.86 dB", "-58.35 dB", "-56.83 dB", "-55.32 dB", "-53.80 dB", "-52.29 dB",
+	"-50.78 dB", "-49.26 dB", "-47.75 dB", "-46.24 dB", "-44.73 dB", "-43.22 dB", "-41.71 dB",
+	"-40.20 dB", "-38.69 dB", "-37.19 dB", "-35.68 dB", "-34.17 dB", "-32.67 dB", "-31.17 dB",
+	"-29.66 dB", "-28.16 dB", "-26.66 dB", "-25.16 dB", "-23.66 dB", "-22.16 dB", "-20.67 dB",
+	"-19.17 dB", "-17.68 dB", "-16.19 dB", "-14.70 dB", "-13.21 dB", "-11.72 dB", "-10.24 dB",
+	"-8.76 dB", "-7.28 dB", "-5.81 dB", "-4.34 dB", "-2.88 dB", "-1.43 dB", "0.00 dB",
+};
+
+static void snd_uda1341_proc_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
 	struct l3_client *clnt = entry->private_data;
 	struct uda1341 *uda = clnt->driver_data;
@@ -393,15 +492,14 @@
 		snd_iprintf(buffer, "Input Amp. Gain ch 2: %s dB\n",  ig_small_value[uda->cfg[CMD_IG]]);
 }
 
-static void snd_uda1341_proc_regs_read(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_uda1341_proc_regs_read(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
 	struct l3_client *clnt = entry->private_data;
 	struct uda1341 *uda = clnt->driver_data;		
 	int reg;
 	char buf[12];
 
-	spin_lock(&uda->reg_lock);
 	for (reg = 0; reg < uda1341_reg_last; reg ++) {
 		if (reg == empty)
 			continue;
@@ -411,13 +509,12 @@
 
 	int2str_bin8(snd_uda1341_codec_read(clnt, UDA1341_DATA1), buf);
 	snd_iprintf(buffer, "DATA1 = %s\n", buf);
-	
-	spin_unlock(&uda->reg_lock);       
 }
+#endif /* CONFIG_PROC_FS */
 
-static void __devinit snd_uda1341_proc_init(snd_card_t *card, struct l3_client *clnt)
+static void __devinit snd_uda1341_proc_init(struct snd_card *card, struct l3_client *clnt)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(card, "uda1341", &entry))
 		snd_info_set_text_ops(entry, clnt, 1024, snd_uda1341_proc_read);
@@ -437,7 +534,8 @@
   .private_value = where | (reg << 5) | (shift << 9) | (mask << 12) | (invert << 18) \
 }
 
-static int snd_uda1341_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_uda1341_info_single(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 12) & 63;
 
@@ -448,10 +546,11 @@
 	return 0;
 }
 
-static int snd_uda1341_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_uda1341_get_single(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
 	struct l3_client *clnt = snd_kcontrol_chip(kcontrol);
-	uda1341_t *uda = clnt->driver_data;
+	struct uda1341 *uda = clnt->driver_data;
 	int where = kcontrol->private_value & 31;        
 	int mask = (kcontrol->private_value >> 12) & 63;
 	int invert = (kcontrol->private_value >> 18) & 1;
@@ -463,10 +562,11 @@
 	return 0;
 }
 
-static int snd_uda1341_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_uda1341_put_single(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
 	struct l3_client *clnt = snd_kcontrol_chip(kcontrol);
-	uda1341_t *uda = clnt->driver_data;
+	struct uda1341 *uda = clnt->driver_data;
 	int where = kcontrol->private_value & 31;        
 	int reg = (kcontrol->private_value >> 5) & 15;
 	int shift = (kcontrol->private_value >> 9) & 7;
@@ -492,7 +592,8 @@
   .private_value = where | (reg << 5) | (shift << 9) | (mask << 12) | (invert << 18) \
 }
 
-static int snd_uda1341_info_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_uda1341_info_enum(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
 	int where = kcontrol->private_value & 31;
 	const char **texts;
@@ -513,20 +614,22 @@
 	return 0;
 }
 
-static int snd_uda1341_get_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_uda1341_get_enum(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
 	struct l3_client *clnt = snd_kcontrol_chip(kcontrol);
-	uda1341_t *uda = clnt->driver_data;
+	struct uda1341 *uda = clnt->driver_data;
 	int where = kcontrol->private_value & 31;        
         
 	ucontrol->value.enumerated.item[0] = uda->cfg[where];	
 	return 0;
 }
 
-static int snd_uda1341_put_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_uda1341_put_enum(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
 	struct l3_client *clnt = snd_kcontrol_chip(kcontrol);
-	uda1341_t *uda = clnt->driver_data;
+	struct uda1341 *uda = clnt->driver_data;
 	int where = kcontrol->private_value & 31;        
 	int reg = (kcontrol->private_value >> 5) & 15;
 	int shift = (kcontrol->private_value >> 9) & 7;
@@ -549,7 +652,8 @@
 }
 
 
-static int snd_uda1341_info_2regs(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_uda1341_info_2regs(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	int mask_1 = (kcontrol->private_value >> 19) & 63;
 	int mask_2 = (kcontrol->private_value >> 25) & 63;
@@ -563,10 +667,11 @@
 	return 0;
 }
 
-static int snd_uda1341_get_2regs(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_uda1341_get_2regs(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct l3_client *clnt = snd_kcontrol_chip(kcontrol);
-	uda1341_t *uda = clnt->driver_data;
+	struct uda1341 *uda = clnt->driver_data;
 	int where = kcontrol->private_value & 31;
 	int mask_1 = (kcontrol->private_value >> 19) & 63;
 	int mask_2 = (kcontrol->private_value >> 25) & 63;        
@@ -581,10 +686,11 @@
 	return 0;
 }
 
-static int snd_uda1341_put_2regs(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_uda1341_put_2regs(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
 	struct l3_client *clnt = snd_kcontrol_chip(kcontrol);
-	uda1341_t *uda = clnt->driver_data;        
+	struct uda1341 *uda = clnt->driver_data;        
 	int where = kcontrol->private_value & 31;        
 	int reg_1 = (kcontrol->private_value >> 5) & 15;
 	int reg_2 = (kcontrol->private_value >> 9) & 15;        
@@ -617,7 +723,7 @@
 
 /* }}} */
   
-static snd_kcontrol_new_t snd_uda1341_controls[] = {
+static struct snd_kcontrol_new snd_uda1341_controls[] = {
 	UDA1341_SINGLE("Master Playback Switch", CMD_MUTE, data0_2, 2, 1, 1),
 	UDA1341_SINGLE("Master Playback Volume", CMD_VOLUME, data0_0, 0, 63, 1),
 
@@ -647,54 +753,55 @@
 	UDA1341_2REGS("Gain Input Amplifier Gain (channel 2)", CMD_IG, ext4, ext5, 0, 0, 3, 31, 0),
 };
 
-static void uda1341_free(struct l3_client *uda1341)
+static void uda1341_free(struct l3_client *clnt)
 {
-	l3_detach_client(uda1341); // calls kfree for driver_data (uda1341_t)
-	kfree(uda1341);
+	l3_detach_client(clnt); // calls kfree for driver_data (struct uda1341)
+	kfree(clnt);
 }
 
-static int uda1341_dev_free(snd_device_t *device)
+static int uda1341_dev_free(struct snd_device *device)
 {
 	struct l3_client *clnt = device->device_data;
 	uda1341_free(clnt);
 	return 0;
 }
 
-int __init snd_chip_uda1341_mixer_new(snd_card_t *card, struct l3_client **clnt)
+int __init snd_chip_uda1341_mixer_new(struct snd_card *card, struct l3_client **clntp)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =     uda1341_dev_free,
 	};
-	struct l3_client *uda1341;
+	struct l3_client *clnt;
 	int idx, err;
 
 	snd_assert(card != NULL, return -EINVAL);
 
-	uda1341 = kzalloc(sizeof(*uda1341), GFP_KERNEL);
-	if (uda1341 == NULL)
+	clnt = kzalloc(sizeof(*clnt), GFP_KERNEL);
+	if (clnt == NULL)
 		return -ENOMEM;
          
-	if ((err = l3_attach_client(uda1341, "l3-bit-sa1100-gpio", "snd-uda1341"))) {
-		kfree(uda1341);
-		return err;
-	}
-
-	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, uda1341, &ops)) < 0) {
-		l3_detach_client(uda1341);
-		kfree(uda1341);
+	if ((err = l3_attach_client(clnt, "l3-bit-sa1100-gpio", UDA1341_ALSA_NAME))) {
+		kfree(clnt);
 		return err;
 	}
 
 	for (idx = 0; idx < ARRAY_SIZE(snd_uda1341_controls); idx++) {
-		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_uda1341_controls[idx], uda1341))) < 0)
+		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_uda1341_controls[idx], clnt))) < 0) {
+			uda1341_free(clnt);
 			return err;
+		}
 	}
 
-	*clnt = uda1341;
+	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, clnt, &ops)) < 0) {
+		uda1341_free(clnt);
+		return err;
+	}
+
+	*clntp = clnt;
 	strcpy(card->mixername, "UDA1341TS Mixer");
-	((uda1341_t *)uda1341->driver_data)->card = card;
+	((struct uda1341 *)clnt->driver_data)->card = card;
         
-	snd_uda1341_proc_init(card, uda1341);
+	snd_uda1341_proc_init(card, clnt);
         
 	return 0;
 }
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index d351b3a..12ffffc 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -37,7 +37,7 @@
 
 static void ak4114_stats(void *);
 
-static void reg_write(ak4114_t *ak4114, unsigned char reg, unsigned char val)
+static void reg_write(struct ak4114 *ak4114, unsigned char reg, unsigned char val)
 {
 	ak4114->write(ak4114->private_data, reg, val);
 	if (reg <= AK4114_REG_INT1_MASK)
@@ -46,13 +46,13 @@
 		ak4114->txcsb[reg-AK4114_REG_RXCSB0] = val;
 }
 
-static inline unsigned char reg_read(ak4114_t *ak4114, unsigned char reg)
+static inline unsigned char reg_read(struct ak4114 *ak4114, unsigned char reg)
 {
 	return ak4114->read(ak4114->private_data, reg);
 }
 
 #if 0
-static void reg_dump(ak4114_t *ak4114)
+static void reg_dump(struct ak4114 *ak4114)
 {
 	int i;
 
@@ -62,7 +62,7 @@
 }
 #endif
 
-static void snd_ak4114_free(ak4114_t *chip)
+static void snd_ak4114_free(struct ak4114 *chip)
 {
 	chip->init = 1;	/* don't schedule new work */
 	mb();
@@ -73,22 +73,22 @@
 	kfree(chip);
 }
 
-static int snd_ak4114_dev_free(snd_device_t *device)
+static int snd_ak4114_dev_free(struct snd_device *device)
 {
-	ak4114_t *chip = device->device_data;
+	struct ak4114 *chip = device->device_data;
 	snd_ak4114_free(chip);
 	return 0;
 }
 
-int snd_ak4114_create(snd_card_t *card,
+int snd_ak4114_create(struct snd_card *card,
 		      ak4114_read_t *read, ak4114_write_t *write,
 		      unsigned char pgm[7], unsigned char txcsb[5],
-		      void *private_data, ak4114_t **r_ak4114)
+		      void *private_data, struct ak4114 **r_ak4114)
 {
-	ak4114_t *chip;
+	struct ak4114 *chip;
 	int err = 0;
 	unsigned char reg;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =     snd_ak4114_dev_free,
 	};
 
@@ -129,7 +129,7 @@
 	return err < 0 ? err : -EIO;
 }
 
-void snd_ak4114_reg_write(ak4114_t *chip, unsigned char reg, unsigned char mask, unsigned char val)
+void snd_ak4114_reg_write(struct ak4114 *chip, unsigned char reg, unsigned char mask, unsigned char val)
 {
 	if (reg <= AK4114_REG_INT1_MASK)
 		reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val);
@@ -137,7 +137,7 @@
 		reg_write(chip, reg, (chip->txcsb[reg] & ~mask) | val);
 }
 
-void snd_ak4114_reinit(ak4114_t *chip)
+void snd_ak4114_reinit(struct ak4114 *chip)
 {
 	unsigned char old = chip->regmap[AK4114_REG_PWRDN], reg;
 
@@ -176,8 +176,8 @@
 	}
 }
 
-static int snd_ak4114_in_error_info(snd_kcontrol_t *kcontrol,
-				    snd_ctl_elem_info_t *uinfo)
+static int snd_ak4114_in_error_info(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -186,10 +186,10 @@
 	return 0;
 }
 
-static int snd_ak4114_in_error_get(snd_kcontrol_t *kcontrol,
-				   snd_ctl_elem_value_t *ucontrol)
+static int snd_ak4114_in_error_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	ak4114_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
 	long *ptr;
 
 	spin_lock_irq(&chip->lock);
@@ -200,8 +200,8 @@
 	return 0;
 }
 
-static int snd_ak4114_in_bit_info(snd_kcontrol_t *kcontrol,
-				  snd_ctl_elem_info_t *uinfo)
+static int snd_ak4114_in_bit_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -210,10 +210,10 @@
 	return 0;
 }
 
-static int snd_ak4114_in_bit_get(snd_kcontrol_t *kcontrol,
-				 snd_ctl_elem_value_t *ucontrol)
+static int snd_ak4114_in_bit_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	ak4114_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned char reg = kcontrol->private_value & 0xff;
 	unsigned char bit = (kcontrol->private_value >> 8) & 0xff;
 	unsigned char inv = (kcontrol->private_value >> 31) & 1;
@@ -222,8 +222,8 @@
 	return 0;
 }
 
-static int snd_ak4114_rate_info(snd_kcontrol_t *kcontrol,
-				snd_ctl_elem_info_t *uinfo)
+static int snd_ak4114_rate_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -232,26 +232,26 @@
 	return 0;
 }
 
-static int snd_ak4114_rate_get(snd_kcontrol_t *kcontrol,
-			       snd_ctl_elem_value_t *ucontrol)
+static int snd_ak4114_rate_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	ak4114_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.integer.value[0] = external_rate(reg_read(chip, AK4114_REG_RCS1));
 	return 0;
 }
 
-static int snd_ak4114_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4114_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ak4114_spdif_get(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4114_spdif_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	ak4114_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned i;
 
 	for (i = 0; i < AK4114_REG_RXCSB_SIZE; i++)
@@ -259,10 +259,10 @@
 	return 0;
 }
 
-static int snd_ak4114_spdif_playback_get(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4114_spdif_playback_get(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	ak4114_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned i;
 
 	for (i = 0; i < AK4114_REG_TXCSB_SIZE; i++)
@@ -270,10 +270,10 @@
 	return 0;
 }
 
-static int snd_ak4114_spdif_playback_put(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4114_spdif_playback_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	ak4114_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned i;
 
 	for (i = 0; i < AK4114_REG_TXCSB_SIZE; i++)
@@ -281,21 +281,21 @@
 	return 0;
 }
 
-static int snd_ak4114_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4114_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ak4114_spdif_mask_get(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4114_spdif_mask_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
 	memset(ucontrol->value.iec958.status, 0xff, AK4114_REG_RXCSB_SIZE);
 	return 0;
 }
 
-static int snd_ak4114_spdif_pinfo(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4114_spdif_pinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->value.integer.min = 0;
@@ -304,10 +304,10 @@
 	return 0;
 }
 
-static int snd_ak4114_spdif_pget(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4114_spdif_pget(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	ak4114_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned short tmp;
 
 	ucontrol->value.integer.value[0] = 0xf8f2;
@@ -319,17 +319,17 @@
 	return 0;
 }
 
-static int snd_ak4114_spdif_qinfo(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4114_spdif_qinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
 	uinfo->count = AK4114_REG_QSUB_SIZE;
 	return 0;
 }
 
-static int snd_ak4114_spdif_qget(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4114_spdif_qget(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	ak4114_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4114 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned i;
 
 	for (i = 0; i < AK4114_REG_QSUB_SIZE; i++)
@@ -338,14 +338,14 @@
 }
 
 /* Don't forget to change AK4114_CONTROLS define!!! */
-static snd_kcontrol_new_t snd_ak4114_iec958_controls[] = {
+static struct snd_kcontrol_new snd_ak4114_iec958_controls[] = {
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =		"IEC958 Parity Errors",
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4114_in_error_info,
 	.get =		snd_ak4114_in_error_get,
-	.private_value = offsetof(ak4114_t, parity_errors),
+	.private_value = offsetof(struct ak4114, parity_errors),
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -353,7 +353,7 @@
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4114_in_error_info,
 	.get =		snd_ak4114_in_error_get,
-	.private_value = offsetof(ak4114_t, v_bit_errors),
+	.private_value = offsetof(struct ak4114, v_bit_errors),
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -361,7 +361,7 @@
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4114_in_error_info,
 	.get =		snd_ak4114_in_error_get,
-	.private_value = offsetof(ak4114_t, ccrc_errors),
+	.private_value = offsetof(struct ak4114, ccrc_errors),
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -369,7 +369,7 @@
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4114_in_error_info,
 	.get =		snd_ak4114_in_error_get,
-	.private_value = offsetof(ak4114_t, qcrc_errors),
+	.private_value = offsetof(struct ak4114, qcrc_errors),
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -447,11 +447,11 @@
 }
 };
 
-int snd_ak4114_build(ak4114_t *ak4114,
-		     snd_pcm_substream_t *ply_substream,
-		     snd_pcm_substream_t *cap_substream)
+int snd_ak4114_build(struct ak4114 *ak4114,
+		     struct snd_pcm_substream *ply_substream,
+		     struct snd_pcm_substream *cap_substream)
 {
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 	unsigned int idx;
 	int err;
 
@@ -482,7 +482,7 @@
 	return 0;
 }
 
-int snd_ak4114_external_rate(ak4114_t *ak4114)
+int snd_ak4114_external_rate(struct ak4114 *ak4114)
 {
 	unsigned char rcs1;
 
@@ -490,9 +490,9 @@
 	return external_rate(rcs1);
 }
 
-int snd_ak4114_check_rate_and_errors(ak4114_t *ak4114, unsigned int flags)
+int snd_ak4114_check_rate_and_errors(struct ak4114 *ak4114, unsigned int flags)
 {
-	snd_pcm_runtime_t *runtime = ak4114->capture_substream ? ak4114->capture_substream->runtime : NULL;
+	struct snd_pcm_runtime *runtime = ak4114->capture_substream ? ak4114->capture_substream->runtime : NULL;
 	unsigned long _flags;
 	int res = 0;
 	unsigned char rcs0, rcs1;
@@ -563,7 +563,7 @@
 
 static void ak4114_stats(void *data)
 {
-	ak4114_t *chip = (ak4114_t *)data;
+	struct ak4114 *chip = (struct ak4114 *)data;
 
 	if (chip->init)
 		return;
diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c
index 35b4584..4e45952 100644
--- a/sound/i2c/other/ak4117.c
+++ b/sound/i2c/other/ak4117.c
@@ -37,20 +37,20 @@
 
 static void snd_ak4117_timer(unsigned long data);
 
-static void reg_write(ak4117_t *ak4117, unsigned char reg, unsigned char val)
+static void reg_write(struct ak4117 *ak4117, unsigned char reg, unsigned char val)
 {
 	ak4117->write(ak4117->private_data, reg, val);
 	if (reg < sizeof(ak4117->regmap))
 		ak4117->regmap[reg] = val;
 }
 
-static inline unsigned char reg_read(ak4117_t *ak4117, unsigned char reg)
+static inline unsigned char reg_read(struct ak4117 *ak4117, unsigned char reg)
 {
 	return ak4117->read(ak4117->private_data, reg);
 }
 
 #if 0
-static void reg_dump(ak4117_t *ak4117)
+static void reg_dump(struct ak4117 *ak4117)
 {
 	int i;
 
@@ -60,26 +60,26 @@
 }
 #endif
 
-static void snd_ak4117_free(ak4117_t *chip)
+static void snd_ak4117_free(struct ak4117 *chip)
 {
 	del_timer(&chip->timer);
 	kfree(chip);
 }
 
-static int snd_ak4117_dev_free(snd_device_t *device)
+static int snd_ak4117_dev_free(struct snd_device *device)
 {
-	ak4117_t *chip = device->device_data;
+	struct ak4117 *chip = device->device_data;
 	snd_ak4117_free(chip);
 	return 0;
 }
 
-int snd_ak4117_create(snd_card_t *card, ak4117_read_t *read, ak4117_write_t *write,
-		      unsigned char pgm[5], void *private_data, ak4117_t **r_ak4117)
+int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t *write,
+		      unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117)
 {
-	ak4117_t *chip;
+	struct ak4117 *chip;
 	int err = 0;
 	unsigned char reg;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =     snd_ak4117_dev_free,
 	};
 
@@ -115,14 +115,14 @@
 	return err < 0 ? err : -EIO;
 }
 
-void snd_ak4117_reg_write(ak4117_t *chip, unsigned char reg, unsigned char mask, unsigned char val)
+void snd_ak4117_reg_write(struct ak4117 *chip, unsigned char reg, unsigned char mask, unsigned char val)
 {
 	if (reg >= 5)
 		return;
 	reg_write(chip, reg, (chip->regmap[reg] & ~mask) | val);
 }
 
-void snd_ak4117_reinit(ak4117_t *chip)
+void snd_ak4117_reinit(struct ak4117 *chip)
 {
 	unsigned char old = chip->regmap[AK4117_REG_PWRDN], reg;
 
@@ -157,8 +157,8 @@
 	}
 }
 
-static int snd_ak4117_in_error_info(snd_kcontrol_t *kcontrol,
-				    snd_ctl_elem_info_t *uinfo)
+static int snd_ak4117_in_error_info(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -167,10 +167,10 @@
 	return 0;
 }
 
-static int snd_ak4117_in_error_get(snd_kcontrol_t *kcontrol,
-				   snd_ctl_elem_value_t *ucontrol)
+static int snd_ak4117_in_error_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	ak4117_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
 	long *ptr;
 
 	spin_lock_irq(&chip->lock);
@@ -181,8 +181,8 @@
 	return 0;
 }
 
-static int snd_ak4117_in_bit_info(snd_kcontrol_t *kcontrol,
-				  snd_ctl_elem_info_t *uinfo)
+static int snd_ak4117_in_bit_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -191,10 +191,10 @@
 	return 0;
 }
 
-static int snd_ak4117_in_bit_get(snd_kcontrol_t *kcontrol,
-				 snd_ctl_elem_value_t *ucontrol)
+static int snd_ak4117_in_bit_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	ak4117_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned char reg = kcontrol->private_value & 0xff;
 	unsigned char bit = (kcontrol->private_value >> 8) & 0xff;
 	unsigned char inv = (kcontrol->private_value >> 31) & 1;
@@ -203,8 +203,8 @@
 	return 0;
 }
 
-static int snd_ak4117_rx_info(snd_kcontrol_t *kcontrol,
-			      snd_ctl_elem_info_t *uinfo)
+static int snd_ak4117_rx_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -213,19 +213,19 @@
 	return 0;
 }
 
-static int snd_ak4117_rx_get(snd_kcontrol_t *kcontrol,
-			     snd_ctl_elem_value_t *ucontrol)
+static int snd_ak4117_rx_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
 {
-	ak4117_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.integer.value[0] = (chip->regmap[AK4117_REG_IO] & AK4117_IPS) ? 1 : 0;
 	return 0;
 }
 
-static int snd_ak4117_rx_put(snd_kcontrol_t *kcontrol,
-			     snd_ctl_elem_value_t *ucontrol)
+static int snd_ak4117_rx_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
 {
-	ak4117_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
 	int change;
 	u8 old_val;
 	
@@ -238,8 +238,8 @@
 	return change;
 }
 
-static int snd_ak4117_rate_info(snd_kcontrol_t *kcontrol,
-				snd_ctl_elem_info_t *uinfo)
+static int snd_ak4117_rate_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -248,26 +248,26 @@
 	return 0;
 }
 
-static int snd_ak4117_rate_get(snd_kcontrol_t *kcontrol,
-			       snd_ctl_elem_value_t *ucontrol)
+static int snd_ak4117_rate_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	ak4117_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.integer.value[0] = external_rate(reg_read(chip, AK4117_REG_RCS1));
 	return 0;
 }
 
-static int snd_ak4117_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4117_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ak4117_spdif_get(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4117_spdif_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	ak4117_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned i;
 
 	for (i = 0; i < AK4117_REG_RXCSB_SIZE; i++)
@@ -275,21 +275,21 @@
 	return 0;
 }
 
-static int snd_ak4117_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4117_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ak4117_spdif_mask_get(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4117_spdif_mask_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
 	memset(ucontrol->value.iec958.status, 0xff, AK4117_REG_RXCSB_SIZE);
 	return 0;
 }
 
-static int snd_ak4117_spdif_pinfo(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4117_spdif_pinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->value.integer.min = 0;
@@ -298,10 +298,10 @@
 	return 0;
 }
 
-static int snd_ak4117_spdif_pget(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4117_spdif_pget(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	ak4117_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned short tmp;
 
 	ucontrol->value.integer.value[0] = 0xf8f2;
@@ -313,17 +313,17 @@
 	return 0;
 }
 
-static int snd_ak4117_spdif_qinfo(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4117_spdif_qinfo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
 	uinfo->count = AK4117_REG_QSUB_SIZE;
 	return 0;
 }
 
-static int snd_ak4117_spdif_qget(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4117_spdif_qget(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	ak4117_t *chip = snd_kcontrol_chip(kcontrol);
+	struct ak4117 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned i;
 
 	for (i = 0; i < AK4117_REG_QSUB_SIZE; i++)
@@ -332,14 +332,14 @@
 }
 
 /* Don't forget to change AK4117_CONTROLS define!!! */
-static snd_kcontrol_new_t snd_ak4117_iec958_controls[] = {
+static struct snd_kcontrol_new snd_ak4117_iec958_controls[] = {
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =		"IEC958 Parity Errors",
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4117_in_error_info,
 	.get =		snd_ak4117_in_error_get,
-	.private_value = offsetof(ak4117_t, parity_errors),
+	.private_value = offsetof(struct ak4117, parity_errors),
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -347,7 +347,7 @@
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4117_in_error_info,
 	.get =		snd_ak4117_in_error_get,
-	.private_value = offsetof(ak4117_t, v_bit_errors),
+	.private_value = offsetof(struct ak4117, v_bit_errors),
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -355,7 +355,7 @@
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4117_in_error_info,
 	.get =		snd_ak4117_in_error_get,
-	.private_value = offsetof(ak4117_t, ccrc_errors),
+	.private_value = offsetof(struct ak4117, ccrc_errors),
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -363,7 +363,7 @@
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
 	.info =		snd_ak4117_in_error_info,
 	.get =		snd_ak4117_in_error_get,
-	.private_value = offsetof(ak4117_t, qcrc_errors),
+	.private_value = offsetof(struct ak4117, qcrc_errors),
 },
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -434,9 +434,9 @@
 }
 };
 
-int snd_ak4117_build(ak4117_t *ak4117, snd_pcm_substream_t *cap_substream)
+int snd_ak4117_build(struct ak4117 *ak4117, struct snd_pcm_substream *cap_substream)
 {
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 	unsigned int idx;
 	int err;
 
@@ -456,7 +456,7 @@
 	return 0;
 }
 
-int snd_ak4117_external_rate(ak4117_t *ak4117)
+int snd_ak4117_external_rate(struct ak4117 *ak4117)
 {
 	unsigned char rcs1;
 
@@ -464,9 +464,9 @@
 	return external_rate(rcs1);
 }
 
-int snd_ak4117_check_rate_and_errors(ak4117_t *ak4117, unsigned int flags)
+int snd_ak4117_check_rate_and_errors(struct ak4117 *ak4117, unsigned int flags)
 {
-	snd_pcm_runtime_t *runtime = ak4117->substream ? ak4117->substream->runtime : NULL;
+	struct snd_pcm_runtime *runtime = ak4117->substream ? ak4117->substream->runtime : NULL;
 	unsigned long _flags;
 	int res = 0;
 	unsigned char rcs0, rcs1, rcs2;
@@ -542,7 +542,7 @@
 
 static void snd_ak4117_timer(unsigned long data)
 {
-	ak4117_t *chip = (ak4117_t *)data;
+	struct ak4117 *chip = (struct ak4117 *)data;
 
 	if (chip->init)
 		return;
diff --git a/sound/i2c/other/ak4xxx-adda.c b/sound/i2c/other/ak4xxx-adda.c
index db2b727..045e32a 100644
--- a/sound/i2c/other/ak4xxx-adda.c
+++ b/sound/i2c/other/ak4xxx-adda.c
@@ -34,7 +34,7 @@
 MODULE_DESCRIPTION("Routines for control of AK452x / AK43xx  AD/DA converters");
 MODULE_LICENSE("GPL");
 
-void snd_akm4xxx_write(akm4xxx_t *ak, int chip, unsigned char reg, unsigned char val)
+void snd_akm4xxx_write(struct snd_akm4xxx *ak, int chip, unsigned char reg, unsigned char val)
 {
 	ak->ops.lock(ak, chip);
 	ak->ops.write(ak, chip, reg, val);
@@ -58,7 +58,7 @@
  *
  * assert the reset operation and restores the register values to the chips.
  */
-void snd_akm4xxx_reset(akm4xxx_t *ak, int state)
+void snd_akm4xxx_reset(struct snd_akm4xxx *ak, int state)
 {
 	unsigned int chip;
 	unsigned char reg;
@@ -109,7 +109,7 @@
 /*
  * initialize all the ak4xxx chips
  */
-void snd_akm4xxx_init(akm4xxx_t *ak)
+void snd_akm4xxx_init(struct snd_akm4xxx *ak)
 {
 	static unsigned char inits_ak4524[] = {
 		0x00, 0x07, /* 0: all power up */
@@ -247,7 +247,8 @@
 #define AK_COMPOSE(chip,addr,shift,mask) (((chip) << 8) | (addr) | ((shift) << 16) | ((mask) << 24))
 #define AK_INVERT 			(1<<23)
 
-static int snd_akm4xxx_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_akm4xxx_volume_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
 {
 	unsigned int mask = AK_GET_MASK(kcontrol->private_value);
 
@@ -258,9 +259,10 @@
 	return 0;
 }
 
-static int snd_akm4xxx_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_akm4xxx_volume_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	akm4xxx_t *ak = snd_kcontrol_chip(kcontrol);
+	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	int invert = AK_GET_INVERT(kcontrol->private_value);
@@ -271,9 +273,10 @@
 	return 0;
 }
 
-static int snd_akm4xxx_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_akm4xxx_volume_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	akm4xxx_t *ak = snd_kcontrol_chip(kcontrol);
+	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	int invert = AK_GET_INVERT(kcontrol->private_value);
@@ -289,7 +292,8 @@
 	return change;
 }
 
-static int snd_akm4xxx_ipga_gain_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_akm4xxx_ipga_gain_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -298,18 +302,20 @@
 	return 0;
 }
 
-static int snd_akm4xxx_ipga_gain_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_akm4xxx_ipga_gain_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	akm4xxx_t *ak = snd_kcontrol_chip(kcontrol);
+	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	ucontrol->value.integer.value[0] = snd_akm4xxx_get_ipga(ak, chip, addr) & 0x7f;
 	return 0;
 }
 
-static int snd_akm4xxx_ipga_gain_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_akm4xxx_ipga_gain_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	akm4xxx_t *ak = snd_kcontrol_chip(kcontrol);
+	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	unsigned char nval = (ucontrol->value.integer.value[0] % 37) | 0x80;
@@ -319,7 +325,8 @@
 	return change;
 }
 
-static int snd_akm4xxx_deemphasis_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_akm4xxx_deemphasis_info(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = {
 		"44.1kHz", "Off", "48kHz", "32kHz",
@@ -333,9 +340,10 @@
 	return 0;
 }
 
-static int snd_akm4xxx_deemphasis_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_akm4xxx_deemphasis_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	akm4xxx_t *ak = snd_kcontrol_chip(kcontrol);
+	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	int shift = AK_GET_SHIFT(kcontrol->private_value);
@@ -343,9 +351,10 @@
 	return 0;
 }
 
-static int snd_akm4xxx_deemphasis_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_akm4xxx_deemphasis_put(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	akm4xxx_t *ak = snd_kcontrol_chip(kcontrol);
+	struct snd_akm4xxx *ak = snd_kcontrol_chip(kcontrol);
 	int chip = AK_GET_CHIP(kcontrol->private_value);
 	int addr = AK_GET_ADDR(kcontrol->private_value);
 	int shift = AK_GET_SHIFT(kcontrol->private_value);
@@ -363,10 +372,10 @@
  * build AK4xxx controls
  */
 
-int snd_akm4xxx_build_controls(akm4xxx_t *ak)
+int snd_akm4xxx_build_controls(struct snd_akm4xxx *ak)
 {
 	unsigned int idx, num_emphs;
-	snd_kcontrol_t *ctl;
+	struct snd_kcontrol *ctl;
 	int err;
 
 	ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 0f05a2b..4c2fd14 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -58,7 +58,7 @@
  * lowlevel part
  */
 
-static void snd_tea575x_set_freq(tea575x_t *tea)
+static void snd_tea575x_set_freq(struct snd_tea575x *tea)
 {
 	unsigned long freq;
 
@@ -89,7 +89,7 @@
 			     unsigned int cmd, unsigned long data)
 {
 	struct video_device *dev = video_devdata(file);
-	tea575x_t *tea = video_get_drvdata(dev);
+	struct snd_tea575x *tea = video_get_drvdata(dev);
 	void __user *arg = (void __user *)data;
 	
 	switch(cmd) {
@@ -175,7 +175,7 @@
 /*
  * initialize all the tea575x chips
  */
-void snd_tea575x_init(tea575x_t *tea)
+void snd_tea575x_init(struct snd_tea575x *tea)
 {
 	unsigned int val;
 
@@ -209,7 +209,7 @@
 	snd_tea575x_set_freq(tea);
 }
 
-void snd_tea575x_exit(tea575x_t *tea)
+void snd_tea575x_exit(struct snd_tea575x *tea)
 {
 	if (tea->vd_registered) {
 		video_unregister_device(&tea->vd);
diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c
index 4fdd1fb..ae5b1e3 100644
--- a/sound/i2c/tea6330t.c
+++ b/sound/i2c/tea6330t.c
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <sound/core.h>
+#include <sound/control.h>
 #include <sound/tea6330t.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
@@ -43,7 +44,20 @@
 #define   TEA6330T_GMU			0x80	/* mute control, general mute */
 #define   TEA6330T_EQN			0x40	/* equalizer switchover (0=equalizer-on) */
 
-int snd_tea6330t_detect(snd_i2c_bus_t *bus, int equalizer)
+
+struct tea6330t {
+	struct snd_i2c_device *device;
+	struct snd_i2c_bus *bus;
+	int equalizer;
+	int fader;
+	unsigned char regs[8];
+	unsigned char mleft, mright;
+	unsigned char bass, treble;
+	unsigned char max_bass, max_treble;
+};
+
+
+int snd_tea6330t_detect(struct snd_i2c_bus *bus, int equalizer)
 {
 	int res;
 
@@ -54,7 +68,7 @@
 }
 
 #if 0
-static void snd_tea6330t_set(tea6330t_t *tea,
+static void snd_tea6330t_set(struct tea6330t *tea,
 			     unsigned char addr, unsigned char value)
 {
 #if 0
@@ -69,7 +83,8 @@
   .info = snd_tea6330t_info_master_volume, \
   .get = snd_tea6330t_get_master_volume, .put = snd_tea6330t_put_master_volume }
 
-static int snd_tea6330t_info_master_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_tea6330t_info_master_volume(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -78,9 +93,10 @@
 	return 0;
 }
 
-static int snd_tea6330t_get_master_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_tea6330t_get_master_volume(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 	
 	snd_i2c_lock(tea->bus);
 	ucontrol->value.integer.value[0] = tea->mleft - 0x14;
@@ -89,9 +105,10 @@
 	return 0;
 }
 
-static int snd_tea6330t_put_master_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_tea6330t_put_master_volume(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 	int change, count, err;
 	unsigned char bytes[3];
 	unsigned char val1, val2;
@@ -125,7 +142,8 @@
   .info = snd_tea6330t_info_master_switch, \
   .get = snd_tea6330t_get_master_switch, .put = snd_tea6330t_put_master_switch }
 
-static int snd_tea6330t_info_master_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_tea6330t_info_master_switch(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -134,9 +152,10 @@
 	return 0;
 }
 
-static int snd_tea6330t_get_master_switch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_tea6330t_get_master_switch(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 	
 	snd_i2c_lock(tea->bus);
 	ucontrol->value.integer.value[0] = tea->regs[TEA6330T_SADDR_VOLUME_LEFT] == 0 ? 0 : 1;
@@ -145,9 +164,10 @@
 	return 0;
 }
 
-static int snd_tea6330t_put_master_switch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_tea6330t_put_master_switch(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 	int change, err;
 	unsigned char bytes[3];
 	unsigned char oval1, oval2, val1, val2;
@@ -174,9 +194,10 @@
   .info = snd_tea6330t_info_bass, \
   .get = snd_tea6330t_get_bass, .put = snd_tea6330t_put_bass }
 
-static int snd_tea6330t_info_bass(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_tea6330t_info_bass(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -185,17 +206,19 @@
 	return 0;
 }
 
-static int snd_tea6330t_get_bass(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_tea6330t_get_bass(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = tea->bass;
 	return 0;
 }
 
-static int snd_tea6330t_put_bass(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_tea6330t_put_bass(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 	int change, err;
 	unsigned char bytes[2];
 	unsigned char val1;
@@ -218,9 +241,10 @@
   .info = snd_tea6330t_info_treble, \
   .get = snd_tea6330t_get_treble, .put = snd_tea6330t_put_treble }
 
-static int snd_tea6330t_info_treble(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_tea6330t_info_treble(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -229,17 +253,19 @@
 	return 0;
 }
 
-static int snd_tea6330t_get_treble(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_tea6330t_get_treble(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = tea->treble;
 	return 0;
 }
 
-static int snd_tea6330t_put_treble(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_tea6330t_put_treble(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	tea6330t_t *tea = snd_kcontrol_chip(kcontrol);
+	struct tea6330t *tea = snd_kcontrol_chip(kcontrol);
 	int change, err;
 	unsigned char bytes[2];
 	unsigned char val1;
@@ -257,25 +283,25 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_tea6330t_controls[] = {
+static struct snd_kcontrol_new snd_tea6330t_controls[] = {
 TEA6330T_MASTER_SWITCH("Master Playback Switch", 0),
 TEA6330T_MASTER_VOLUME("Master Playback Volume", 0),
 TEA6330T_BASS("Tone Control - Bass", 0),
 TEA6330T_TREBLE("Tone Control - Treble", 0)
 };
 
-static void snd_tea6330_free(snd_i2c_device_t *device)
+static void snd_tea6330_free(struct snd_i2c_device *device)
 {
 	kfree(device->private_data);
 }
                                         
-int snd_tea6330t_update_mixer(snd_card_t * card,
-			      snd_i2c_bus_t *bus,
+int snd_tea6330t_update_mixer(struct snd_card *card,
+			      struct snd_i2c_bus *bus,
 			      int equalizer, int fader)
 {
-	snd_i2c_device_t *device;
-	tea6330t_t *tea;
-	snd_kcontrol_new_t *knew;
+	struct snd_i2c_device *device;
+	struct tea6330t *tea;
+	struct snd_kcontrol_new *knew;
 	unsigned int idx;
 	int err = -ENOMEM;
 	u8 default_treble, default_bass;
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 5d6c300a..ff8fef9 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -6,12 +6,10 @@
 config SND_AD1848_LIB
         tristate
         select SND_PCM
-	select SND_GENERIC_DRIVER
 
 config SND_CS4231_LIB
         tristate
         select SND_PCM
-	select SND_GENERIC_DRIVER
 
 config SND_AD1816A
 	tristate "Analog Devices SoundPort AD1816A"
@@ -41,264 +39,6 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-ad1848.
 
-config SND_CS4231
-	tristate "Generic Cirrus Logic CS4231 driver"
-	depends on SND
-	select SND_MPU401_UART
-	select SND_CS4231_LIB
-	help
-	  Say Y here to include support for CS4231 chips from Cirrus
-	  Logic - Crystal Semiconductors.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-cs4231.
-
-config SND_CS4232
-	tristate "Generic Cirrus Logic CS4232 driver"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_CS4231_LIB
-	help
-	  Say Y here to include support for CS4232 chips from Cirrus
-	  Logic - Crystal Semiconductors.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-cs4232.
-
-config SND_CS4236
-	tristate "Generic Cirrus Logic CS4236+ driver"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_CS4231_LIB
-	help
-	  Say Y to include support for CS4235,CS4236,CS4237B,CS4238B,
-	  CS4239 chips from Cirrus Logic - Crystal Semiconductors.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-cs4236.
-
-config SND_ES968
-	tristate "Generic ESS ES968 driver"
-	depends on SND && PNP && ISA
-	select ISAPNP
-	select SND_MPU401_UART
-	select SND_PCM
-	help
-	  Say Y here to include support for ESS AudioDrive ES968 chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-es968.
-
-config SND_ES1688
-	tristate "Generic ESS ES688/ES1688 driver"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for ESS AudioDrive ES688 or
-	  ES1688 chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-es1688.
-
-config SND_ES18XX
-	tristate "Generic ESS ES18xx driver"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for ESS AudioDrive ES18xx chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-es18xx.
-
-config SND_GUS_SYNTH
-	tristate
-
-config SND_GUSCLASSIC
-	tristate "Gravis UltraSound Classic"
-	depends on SND
-	select SND_RAWMIDI
-	select SND_PCM
-	select SND_GUS_SYNTH
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for Gravis UltraSound Classic
-	  soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-gusclassic.
-
-config SND_GUSEXTREME
-	tristate "Gravis UltraSound Extreme"
-	depends on SND
-	select SND_HWDEP
-	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GUS_SYNTH
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for Gravis UltraSound Extreme
-	  soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-gusextreme.
-
-config SND_GUSMAX
-	tristate "Gravis UltraSound MAX"
-	depends on SND
-	select SND_RAWMIDI
-	select SND_CS4231_LIB
-	select SND_GUS_SYNTH
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for Gravis UltraSound MAX
-	  soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-gusmax.
-
-config SND_INTERWAVE
-	tristate "AMD InterWave, Gravis UltraSound PnP"
-	depends on SND && PNP && ISA
-	select SND_RAWMIDI
-	select SND_CS4231_LIB
-	select SND_GUS_SYNTH
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for AMD InterWave based
-	  soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
-	  MED3210, Dynasonic Pro, Panasonic PCA761AW).
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-interwave.
-
-config SND_INTERWAVE_STB
-	tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)"
-	depends on SND && PNP && ISA
-	select SND_RAWMIDI
-	select SND_CS4231_LIB
-	select SND_GUS_SYNTH
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for AMD InterWave based
-	  soundcards with a TEA6330T bass and treble regulator
-	  (UltraSound 32-Pro).
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-interwave-stb.
-
-config SND_OPTI92X_AD1848
-	tristate "OPTi 82C92x - AD1848"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_OPL4_LIB
-	select SND_MPU401_UART
-	select SND_AD1848_LIB
-	help
-	  Say Y here to include support for soundcards based on Opti
-	  82C92x or OTI-601 chips and using an AD1848 codec.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-opti92x-ad1848.
-
-config SND_OPTI92X_CS4231
-	tristate "OPTi 82C92x - CS4231"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_OPL4_LIB
-	select SND_MPU401_UART
-	select SND_CS4231_LIB
-	help
-	  Say Y here to include support for soundcards based on Opti
-	  82C92x chips and using a CS4231 codec.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-opti92x-cs4231.
-
-config SND_OPTI93X
-	tristate "OPTi 82C93x"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for soundcards based on Opti
-	  82C93x chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-opti93x.
-
-config SND_SB8
-	tristate "Sound Blaster 1.0/2.0/Pro (8-bit)"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_RAWMIDI
-	select SND_PCM
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for Creative Sound Blaster 1.0/
-	  2.0/Pro (8-bit) or 100% compatible soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-sb8.
-
-config SND_SB16
-	tristate "Sound Blaster 16 (PnP)"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for Sound Blaster 16 soundcards
-	  (including the Plug and Play version).
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-sb16.
-
-config SND_SBAWE
-	tristate "Sound Blaster AWE (32,64) (PnP)"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_PCM
-	select SND_GENERIC_DRIVER
-	help
-	  Say Y here to include support for Sound Blaster AWE soundcards
-	  (including the Plug and Play version).
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-sbawe.
-
-config SND_SB16_CSP
-	bool "Sound Blaster 16/AWE CSP support"
-	depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
-	help
-	  Say Y here to include support for the CSP core.  This special
-	  coprocessor can do variable tasks like various compression and
-	  decompression algorithms.
-
-config SND_WAVEFRONT
-	tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_CS4231_LIB
-	help
-	  Say Y here to include support for Turtle Beach Maui, Tropez
-	  and Tropez+ soundcards based on the Wavefront chip.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-wavefront.
-
 config SND_ALS100
 	tristate "Avance Logic ALS100/ALS120"
 	depends on SND && PNP && ISA
@@ -338,6 +78,44 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-cmi8330.
 
+config SND_CS4231
+	tristate "Generic Cirrus Logic CS4231 driver"
+	depends on SND
+	select SND_MPU401_UART
+	select SND_CS4231_LIB
+	help
+	  Say Y here to include support for CS4231 chips from Cirrus
+	  Logic - Crystal Semiconductors.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cs4231.
+
+config SND_CS4232
+	tristate "Generic Cirrus Logic CS4232 driver"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_CS4231_LIB
+	help
+	  Say Y here to include support for CS4232 chips from Cirrus
+	  Logic - Crystal Semiconductors.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cs4232.
+
+config SND_CS4236
+	tristate "Generic Cirrus Logic CS4236+ driver"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_CS4231_LIB
+	help
+	  Say Y to include support for CS4235,CS4236,CS4237B,CS4238B,
+	  CS4239 chips from Cirrus Logic - Crystal Semiconductors.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cs4236.
+
 config SND_DT019X
 	tristate "Diamond Technologies DT-019X, Avance Logic ALS-007"
 	depends on SND && PNP && ISA
@@ -352,6 +130,114 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-dt019x.
 
+config SND_ES968
+	tristate "Generic ESS ES968 driver"
+	depends on SND && PNP && ISA
+	select ISAPNP
+	select SND_MPU401_UART
+	select SND_PCM
+	help
+	  Say Y here to include support for ESS AudioDrive ES968 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-es968.
+
+config SND_ES1688
+	tristate "Generic ESS ES688/ES1688 driver"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_PCM
+	help
+	  Say Y here to include support for ESS AudioDrive ES688 or
+	  ES1688 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-es1688.
+
+config SND_ES18XX
+	tristate "Generic ESS ES18xx driver"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_PCM
+	help
+	  Say Y here to include support for ESS AudioDrive ES18xx chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-es18xx.
+
+config SND_GUS_SYNTH
+	tristate
+
+config SND_GUSCLASSIC
+	tristate "Gravis UltraSound Classic"
+	depends on SND
+	select SND_RAWMIDI
+	select SND_PCM
+	select SND_GUS_SYNTH
+	help
+	  Say Y here to include support for Gravis UltraSound Classic
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-gusclassic.
+
+config SND_GUSEXTREME
+	tristate "Gravis UltraSound Extreme"
+	depends on SND
+	select SND_HWDEP
+	select SND_MPU401_UART
+	select SND_PCM
+	select SND_GUS_SYNTH
+	help
+	  Say Y here to include support for Gravis UltraSound Extreme
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-gusextreme.
+
+config SND_GUSMAX
+	tristate "Gravis UltraSound MAX"
+	depends on SND
+	select SND_RAWMIDI
+	select SND_CS4231_LIB
+	select SND_GUS_SYNTH
+	help
+	  Say Y here to include support for Gravis UltraSound MAX
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-gusmax.
+
+config SND_INTERWAVE
+	tristate "AMD InterWave, Gravis UltraSound PnP"
+	depends on SND && PNP && ISA
+	select SND_RAWMIDI
+	select SND_CS4231_LIB
+	select SND_GUS_SYNTH
+	help
+	  Say Y here to include support for AMD InterWave based
+	  soundcards (Gravis UltraSound Plug & Play, STB SoundRage32,
+	  MED3210, Dynasonic Pro, Panasonic PCA761AW).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-interwave.
+
+config SND_INTERWAVE_STB
+	tristate "AMD InterWave + TEA6330T (UltraSound 32-Pro)"
+	depends on SND && PNP && ISA
+	select SND_RAWMIDI
+	select SND_CS4231_LIB
+	select SND_GUS_SYNTH
+	help
+	  Say Y here to include support for AMD InterWave based
+	  soundcards with a TEA6330T bass and treble regulator
+	  (UltraSound 32-Pro).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-interwave-stb.
+
 config SND_OPL3SA2
 	tristate "Yamaha OPL3-SA2/SA3"
 	depends on SND
@@ -365,6 +251,94 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-opl3sa2.
 
+config SND_OPTI92X_AD1848
+	tristate "OPTi 82C92x - AD1848"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_OPL4_LIB
+	select SND_MPU401_UART
+	select SND_AD1848_LIB
+	help
+	  Say Y here to include support for soundcards based on Opti
+	  82C92x or OTI-601 chips and using an AD1848 codec.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-opti92x-ad1848.
+
+config SND_OPTI92X_CS4231
+	tristate "OPTi 82C92x - CS4231"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_OPL4_LIB
+	select SND_MPU401_UART
+	select SND_CS4231_LIB
+	help
+	  Say Y here to include support for soundcards based on Opti
+	  82C92x chips and using a CS4231 codec.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-opti92x-cs4231.
+
+config SND_OPTI93X
+	tristate "OPTi 82C93x"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_PCM
+	help
+	  Say Y here to include support for soundcards based on Opti
+	  82C93x chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-opti93x.
+
+config SND_SB8
+	tristate "Sound Blaster 1.0/2.0/Pro (8-bit)"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_RAWMIDI
+	select SND_PCM
+	help
+	  Say Y here to include support for Creative Sound Blaster 1.0/
+	  2.0/Pro (8-bit) or 100% compatible soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sb8.
+
+config SND_SB16
+	tristate "Sound Blaster 16 (PnP)"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_PCM
+	help
+	  Say Y here to include support for Sound Blaster 16 soundcards
+	  (including the Plug and Play version).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sb16.
+
+config SND_SBAWE
+	tristate "Sound Blaster AWE (32,64) (PnP)"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_PCM
+	help
+	  Say Y here to include support for Sound Blaster AWE soundcards
+	  (including the Plug and Play version).
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-sbawe.
+
+config SND_SB16_CSP
+	bool "Sound Blaster 16/AWE CSP support"
+	depends on (SND_SB16 || SND_SBAWE) && (BROKEN || !PPC)
+	help
+	  Say Y here to include support for the CSP core.  This special
+	  coprocessor can do variable tasks like various compression and
+	  decompression algorithms.
+
 config SND_SGALAXY
 	tristate "Aztech Sound Galaxy"
 	depends on SND
@@ -389,4 +363,17 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-sscape.
 
+config SND_WAVEFRONT
+	tristate "Turtle Beach Maui,Tropez,Tropez+ (Wavefront)"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_CS4231_LIB
+	help
+	  Say Y here to include support for Turtle Beach Maui, Tropez
+	  and Tropez+ soundcards based on the Wavefront chip.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-wavefront.
+
 endmenu
diff --git a/sound/isa/ad1816a/Makefile b/sound/isa/ad1816a/Makefile
index a42b29c..90e00e8 100644
--- a/sound/isa/ad1816a/Makefile
+++ b/sound/isa/ad1816a/Makefile
@@ -3,8 +3,7 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-ad1816a-lib-objs := ad1816a_lib.o
-snd-ad1816a-objs := ad1816a.o
+snd-ad1816a-objs := ad1816a.o ad1816a_lib.o
 
 # Toplevel Module Dependency
-obj-$(CONFIG_SND_AD1816A) += snd-ad1816a.o snd-ad1816a-lib.o
+obj-$(CONFIG_SND_AD1816A) += snd-ad1816a.o
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 0eb442c..7051f77 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -188,10 +188,10 @@
 					    const struct pnp_card_device_id *pid)
 {
 	int error;
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_card_ad1816a *acard;
-	ad1816a_t *chip;
-	opl3_t *opl3;
+	struct snd_ad1816a *chip;
+	struct snd_opl3 *opl3;
 
 	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 				 sizeof(struct snd_card_ad1816a))) == NULL)
@@ -282,10 +282,8 @@
 
 static void __devexit snd_ad1816a_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
 static struct pnp_card_driver ad1816a_pnpc_driver = {
@@ -294,20 +292,22 @@
 	.id_table	= snd_ad1816a_pnpids,
 	.probe		= snd_ad1816a_pnp_detect,
 	.remove		= __devexit_p(snd_ad1816a_pnp_remove),
+	/* FIXME: suspend/resume */
 };
 
 static int __init alsa_card_ad1816a_init(void)
 {
-	int cards = 0;
+	int cards;
 
-	cards += pnp_register_card_driver(&ad1816a_pnpc_driver);
-#ifdef MODULE
-	if (!cards) {
+	cards = pnp_register_card_driver(&ad1816a_pnpc_driver);
+	if (cards <= 0) {
 		pnp_unregister_card_driver(&ad1816a_pnpc_driver);
+#ifdef MODULE
 		printk(KERN_ERR "no AD1816A based soundcards found.\n");
-	}
 #endif	/* MODULE */
-	return cards ? 0 : -ENODEV;
+		return -ENODEV;
+	}
+	return 0;
 }
 
 static void __exit alsa_card_ad1816a_exit(void)
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 7ae0239..ac0d808 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -30,11 +30,7 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 
-MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
-MODULE_DESCRIPTION("lowlevel code for Analog Devices AD1816A chip");
-MODULE_LICENSE("GPL");
-
-static inline int snd_ad1816a_busy_wait(ad1816a_t *chip)
+static inline int snd_ad1816a_busy_wait(struct snd_ad1816a *chip)
 {
 	int timeout;
 
@@ -46,34 +42,34 @@
 	return -EBUSY;
 }
 
-static inline unsigned char snd_ad1816a_in(ad1816a_t *chip, unsigned char reg)
+static inline unsigned char snd_ad1816a_in(struct snd_ad1816a *chip, unsigned char reg)
 {
 	snd_ad1816a_busy_wait(chip);
 	return inb(AD1816A_REG(reg));
 }
 
-static inline void snd_ad1816a_out(ad1816a_t *chip, unsigned char reg,
+static inline void snd_ad1816a_out(struct snd_ad1816a *chip, unsigned char reg,
 			    unsigned char value)
 {
 	snd_ad1816a_busy_wait(chip);
 	outb(value, AD1816A_REG(reg));
 }
 
-static inline void snd_ad1816a_out_mask(ad1816a_t *chip, unsigned char reg,
+static inline void snd_ad1816a_out_mask(struct snd_ad1816a *chip, unsigned char reg,
 				 unsigned char mask, unsigned char value)
 {
 	snd_ad1816a_out(chip, reg,
 		(value & mask) | (snd_ad1816a_in(chip, reg) & ~mask));
 }
 
-static unsigned short snd_ad1816a_read(ad1816a_t *chip, unsigned char reg)
+static unsigned short snd_ad1816a_read(struct snd_ad1816a *chip, unsigned char reg)
 {
 	snd_ad1816a_out(chip, AD1816A_INDIR_ADDR, reg & 0x3f);
 	return snd_ad1816a_in(chip, AD1816A_INDIR_DATA_LOW) |
 		(snd_ad1816a_in(chip, AD1816A_INDIR_DATA_HIGH) << 8);
 }
 
-static void snd_ad1816a_write(ad1816a_t *chip, unsigned char reg,
+static void snd_ad1816a_write(struct snd_ad1816a *chip, unsigned char reg,
 			      unsigned short value)
 {
 	snd_ad1816a_out(chip, AD1816A_INDIR_ADDR, reg & 0x3f);
@@ -81,7 +77,7 @@
 	snd_ad1816a_out(chip, AD1816A_INDIR_DATA_HIGH, (value >> 8) & 0xff);
 }
 
-static void snd_ad1816a_write_mask(ad1816a_t *chip, unsigned char reg,
+static void snd_ad1816a_write_mask(struct snd_ad1816a *chip, unsigned char reg,
 				   unsigned short mask, unsigned short value)
 {
 	snd_ad1816a_write(chip, reg,
@@ -89,7 +85,7 @@
 }
 
 
-static unsigned char snd_ad1816a_get_format(ad1816a_t *chip,
+static unsigned char snd_ad1816a_get_format(struct snd_ad1816a *chip,
 					    unsigned int format, int channels)
 {
 	unsigned char retval = AD1816A_FMT_LINEAR_8;
@@ -110,7 +106,7 @@
 	return (channels > 1) ? (retval | AD1816A_FMT_STEREO) : retval;
 }
 
-static int snd_ad1816a_open(ad1816a_t *chip, unsigned int mode)
+static int snd_ad1816a_open(struct snd_ad1816a *chip, unsigned int mode)
 {
 	unsigned long flags;
 
@@ -146,7 +142,7 @@
 	return 0;
 }
 
-static void snd_ad1816a_close(ad1816a_t *chip, unsigned int mode)
+static void snd_ad1816a_close(struct snd_ad1816a *chip, unsigned int mode)
 {
 	unsigned long flags;
 
@@ -178,7 +174,7 @@
 }
 
 
-static int snd_ad1816a_trigger(ad1816a_t *chip, unsigned char what,
+static int snd_ad1816a_trigger(struct snd_ad1816a *chip, unsigned char what,
 			       int channel, int cmd)
 {
 	int error = 0;
@@ -204,36 +200,36 @@
 	return error;
 }
 
-static int snd_ad1816a_playback_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_ad1816a_playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
 	return snd_ad1816a_trigger(chip, AD1816A_PLAYBACK_ENABLE,
 		SNDRV_PCM_STREAM_PLAYBACK, cmd);
 }
 
-static int snd_ad1816a_capture_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_ad1816a_capture_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
 	return snd_ad1816a_trigger(chip, AD1816A_CAPTURE_ENABLE,
 		SNDRV_PCM_STREAM_CAPTURE, cmd);
 }
 
-static int snd_ad1816a_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_ad1816a_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_ad1816a_hw_free(snd_pcm_substream_t * substream)
+static int snd_ad1816a_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_ad1816a_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_ad1816a_playback_prepare(struct snd_pcm_substream *substream)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
 	unsigned long flags;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int size, rate;
 
 	spin_lock_irqsave(&chip->lock, flags);
@@ -261,11 +257,11 @@
 	return 0;
 }
 
-static int snd_ad1816a_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_ad1816a_capture_prepare(struct snd_pcm_substream *substream)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
 	unsigned long flags;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int size, rate;
 
 	spin_lock_irqsave(&chip->lock, flags);
@@ -294,9 +290,9 @@
 }
 
 
-static snd_pcm_uframes_t snd_ad1816a_playback_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_ad1816a_playback_pointer(struct snd_pcm_substream *substream)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	if (!(chip->mode & AD1816A_MODE_PLAYBACK))
 		return 0;
@@ -304,9 +300,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_ad1816a_capture_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_ad1816a_capture_pointer(struct snd_pcm_substream *substream)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	if (!(chip->mode & AD1816A_MODE_CAPTURE))
 		return 0;
@@ -317,7 +313,7 @@
 
 static irqreturn_t snd_ad1816a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	ad1816a_t *chip = dev_id;
+	struct snd_ad1816a *chip = dev_id;
 	unsigned char status;
 
 	spin_lock(&chip->lock);
@@ -340,7 +336,7 @@
 }
 
 
-static snd_pcm_hardware_t snd_ad1816a_playback = {
+static struct snd_pcm_hardware snd_ad1816a_playback = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
@@ -359,7 +355,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ad1816a_capture = {
+static struct snd_pcm_hardware snd_ad1816a_capture = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW |
@@ -379,32 +375,32 @@
 };
 
 #if 0 /* not used now */
-static int snd_ad1816a_timer_close(snd_timer_t *timer)
+static int snd_ad1816a_timer_close(struct snd_timer *timer)
 {
-	ad1816a_t *chip = snd_timer_chip(timer);
+	struct snd_ad1816a *chip = snd_timer_chip(timer);
 	snd_ad1816a_close(chip, AD1816A_MODE_TIMER);
 	return 0;
 }
 
-static int snd_ad1816a_timer_open(snd_timer_t *timer)
+static int snd_ad1816a_timer_open(struct snd_timer *timer)
 {
-	ad1816a_t *chip = snd_timer_chip(timer);
+	struct snd_ad1816a *chip = snd_timer_chip(timer);
 	snd_ad1816a_open(chip, AD1816A_MODE_TIMER);
 	return 0;
 }
 
-static unsigned long snd_ad1816a_timer_resolution(snd_timer_t *timer)
+static unsigned long snd_ad1816a_timer_resolution(struct snd_timer *timer)
 {
 	snd_assert(timer != NULL, return 0);
 
 	return 10000;
 }
 
-static int snd_ad1816a_timer_start(snd_timer_t *timer)
+static int snd_ad1816a_timer_start(struct snd_timer *timer)
 {
 	unsigned short bits;
 	unsigned long flags;
-	ad1816a_t *chip = snd_timer_chip(timer);
+	struct snd_ad1816a *chip = snd_timer_chip(timer);
 	spin_lock_irqsave(&chip->lock, flags);
 	bits = snd_ad1816a_read(chip, AD1816A_INTERRUPT_ENABLE);
 
@@ -419,10 +415,10 @@
 	return 0;
 }
 
-static int snd_ad1816a_timer_stop(snd_timer_t *timer)
+static int snd_ad1816a_timer_stop(struct snd_timer *timer)
 {
 	unsigned long flags;
-	ad1816a_t *chip = snd_timer_chip(timer);
+	struct snd_ad1816a *chip = snd_timer_chip(timer);
 	spin_lock_irqsave(&chip->lock, flags);
 
 	snd_ad1816a_write_mask(chip, AD1816A_INTERRUPT_ENABLE,
@@ -432,7 +428,7 @@
 	return 0;
 }
 
-static struct _snd_timer_hardware snd_ad1816a_timer_table = {
+static struct snd_timer_hardware snd_ad1816a_timer_table = {
 	.flags =	SNDRV_TIMER_HW_AUTO,
 	.resolution =	10000,
 	.ticks =	65535,
@@ -445,10 +441,10 @@
 #endif /* not used now */
 
 
-static int snd_ad1816a_playback_open(snd_pcm_substream_t *substream)
+static int snd_ad1816a_playback_open(struct snd_pcm_substream *substream)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int error;
 
 	if ((error = snd_ad1816a_open(chip, AD1816A_MODE_PLAYBACK)) < 0)
@@ -461,10 +457,10 @@
 	return 0;
 }
 
-static int snd_ad1816a_capture_open(snd_pcm_substream_t *substream)
+static int snd_ad1816a_capture_open(struct snd_pcm_substream *substream)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int error;
 
 	if ((error = snd_ad1816a_open(chip, AD1816A_MODE_CAPTURE)) < 0)
@@ -477,18 +473,18 @@
 	return 0;
 }
 
-static int snd_ad1816a_playback_close(snd_pcm_substream_t *substream)
+static int snd_ad1816a_playback_close(struct snd_pcm_substream *substream)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
 
 	chip->playback_substream = NULL;
 	snd_ad1816a_close(chip, AD1816A_MODE_PLAYBACK);
 	return 0;
 }
 
-static int snd_ad1816a_capture_close(snd_pcm_substream_t *substream)
+static int snd_ad1816a_capture_close(struct snd_pcm_substream *substream)
 {
-	ad1816a_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1816a *chip = snd_pcm_substream_chip(substream);
 
 	chip->capture_substream = NULL;
 	snd_ad1816a_close(chip, AD1816A_MODE_CAPTURE);
@@ -496,7 +492,7 @@
 }
 
 
-static void snd_ad1816a_init(ad1816a_t *chip)
+static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip)
 {
 	unsigned long flags;
 
@@ -516,7 +512,7 @@
 	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
-static int snd_ad1816a_probe(ad1816a_t *chip)
+static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip)
 {
 	unsigned long flags;
 
@@ -540,7 +536,7 @@
 	return 0;
 }
 
-static int snd_ad1816a_free(ad1816a_t *chip)
+static int snd_ad1816a_free(struct snd_ad1816a *chip)
 {
 	release_and_free_resource(chip->res_port);
 	if (chip->irq >= 0)
@@ -557,13 +553,13 @@
 	return 0;
 }
 
-static int snd_ad1816a_dev_free(snd_device_t *device)
+static int snd_ad1816a_dev_free(struct snd_device *device)
 {
-	ad1816a_t *chip = device->device_data;
+	struct snd_ad1816a *chip = device->device_data;
 	return snd_ad1816a_free(chip);
 }
 
-static const char *snd_ad1816a_chip_id(ad1816a_t *chip)
+static const char __devinit *snd_ad1816a_chip_id(struct snd_ad1816a *chip)
 {
 	switch (chip->hardware) {
 	case AD1816A_HW_AD1816A: return "AD1816A";
@@ -576,15 +572,15 @@
 	}
 }
 
-int snd_ad1816a_create(snd_card_t *card,
-		       unsigned long port, int irq, int dma1, int dma2,
-		       ad1816a_t **rchip)
+int __devinit snd_ad1816a_create(struct snd_card *card,
+				 unsigned long port, int irq, int dma1, int dma2,
+				 struct snd_ad1816a **rchip)
 {
-        static snd_device_ops_t ops = {
+        static struct snd_device_ops ops = {
 		.dev_free =	snd_ad1816a_dev_free,
 	};
 	int error;
-	ad1816a_t *chip;
+	struct snd_ad1816a *chip;
 
 	*rchip = NULL;
 
@@ -640,7 +636,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_ad1816a_playback_ops = {
+static struct snd_pcm_ops snd_ad1816a_playback_ops = {
 	.open =		snd_ad1816a_playback_open,
 	.close =	snd_ad1816a_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -651,7 +647,7 @@
 	.pointer =	snd_ad1816a_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_ad1816a_capture_ops = {
+static struct snd_pcm_ops snd_ad1816a_capture_ops = {
 	.open =		snd_ad1816a_capture_open,
 	.close =	snd_ad1816a_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -662,17 +658,10 @@
 	.pointer =	snd_ad1816a_capture_pointer,
 };
 
-static void snd_ad1816a_pcm_free(snd_pcm_t *pcm)
-{
-	ad1816a_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int snd_ad1816a_pcm(ad1816a_t *chip, int device, snd_pcm_t **rpcm)
+int __devinit snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm)
 {
 	int error;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 
 	if ((error = snd_pcm_new(chip->card, "AD1816A", device, 1, 1, &pcm)))
 		return error;
@@ -681,7 +670,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1816a_capture_ops);
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_ad1816a_pcm_free;
 	pcm->info_flags = (chip->dma1 == chip->dma2 ) ? SNDRV_PCM_INFO_JOINT_DUPLEX : 0;
 
 	strcpy(pcm->name, snd_ad1816a_chip_id(chip));
@@ -698,16 +686,10 @@
 }
 
 #if 0 /* not used now */
-static void snd_ad1816a_timer_free(snd_timer_t *timer)
+int __devinit snd_ad1816a_timer(struct snd_ad1816a *chip, int device, struct snd_timer **rtimer)
 {
-	ad1816a_t *chip = timer->private_data;
-	chip->timer = NULL;
-}
-
-int snd_ad1816a_timer(ad1816a_t *chip, int device, snd_timer_t **rtimer)
-{
-	snd_timer_t *timer;
-	snd_timer_id_t tid;
+	struct snd_timer *timer;
+	struct snd_timer_id tid;
 	int error;
 
 	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
@@ -719,7 +701,6 @@
 		return error;
 	strcpy(timer->name, snd_ad1816a_chip_id(chip));
 	timer->private_data = chip;
-	timer->private_free = snd_ad1816a_timer_free;
 	chip->timer = timer;
 	timer->hw = snd_ad1816a_timer_table;
 	if (rtimer)
@@ -732,7 +713,7 @@
  *
  */
 
-static int snd_ad1816a_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ad1816a_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[8] = {
 		"Line", "Mix", "CD", "Synth", "Video",
@@ -748,9 +729,9 @@
 	return 0;
 }
 
-static int snd_ad1816a_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1816a_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1816a_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned short val;
 	
@@ -762,9 +743,9 @@
 	return 0;
 }
 
-static int snd_ad1816a_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1816a_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1816a_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned short val;
 	int change;
@@ -786,7 +767,7 @@
   .get = snd_ad1816a_get_single, .put = snd_ad1816a_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_ad1816a_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ad1816a_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -797,9 +778,9 @@
 	return 0;
 }
 
-static int snd_ad1816a_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1816a_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1816a_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -814,9 +795,9 @@
 	return 0;
 }
 
-static int snd_ad1816a_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1816a_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1816a_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -843,7 +824,7 @@
   .get = snd_ad1816a_get_double, .put = snd_ad1816a_put_double, \
   .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24) }
 
-static int snd_ad1816a_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ad1816a_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -854,9 +835,9 @@
 	return 0;
 }
 
-static int snd_ad1816a_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1816a_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1816a_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift_left = (kcontrol->private_value >> 8) & 0x0f;
@@ -877,9 +858,9 @@
 	return 0;
 }
 
-static int snd_ad1816a_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1816a_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1816a_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1816a *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift_left = (kcontrol->private_value >> 8) & 0x0f;
@@ -906,7 +887,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ad1816a_controls[] = {
+static struct snd_kcontrol_new snd_ad1816a_controls[] __devinitdata = {
 AD1816A_DOUBLE("Master Playback Switch", AD1816A_MASTER_ATT, 15, 7, 1, 1),
 AD1816A_DOUBLE("Master Playback Volume", AD1816A_MASTER_ATT, 8, 0, 31, 1),
 AD1816A_DOUBLE("PCM Playback Switch", AD1816A_VOICE_ATT, 15, 7, 1, 1),
@@ -941,9 +922,9 @@
 AD1816A_SINGLE("3D Control - Level", AD1816A_3D_PHAT_CTRL, 0, 15, 0),
 };
                                         
-int snd_ad1816a_mixer(ad1816a_t *chip)
+int __devinit snd_ad1816a_mixer(struct snd_ad1816a *chip)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned int idx;
 	int err;
 
@@ -959,19 +940,3 @@
 	}
 	return 0;
 }
-
-EXPORT_SYMBOL(snd_ad1816a_create);
-EXPORT_SYMBOL(snd_ad1816a_pcm);
-EXPORT_SYMBOL(snd_ad1816a_mixer);
-
-static int __init alsa_ad1816a_init(void)
-{
-	return 0;
-}
-
-static void __exit alsa_ad1816a_exit(void)
-{
-}
-
-module_init(alsa_ad1816a_init)
-module_exit(alsa_ad1816a_exit)
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index 3ebcc48..e091bbe 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -23,6 +23,8 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
@@ -60,14 +62,15 @@
 module_param_array(thinkpad, bool, NULL, 0444);
 MODULE_PARM_DESC(thinkpad, "Enable only for the onboard CS4248 of IBM Thinkpad 360/750/755 series.");
 
-static snd_card_t *snd_ad1848_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct platform_device *devices[SNDRV_CARDS];
 
 
-static int __init snd_card_ad1848_probe(int dev)
+static int __init snd_ad1848_probe(struct platform_device *pdev)
 {
-	snd_card_t *card;
-	ad1848_t *chip;
-	snd_pcm_t *pcm;
+	int dev = pdev->id;
+	struct snd_card *card;
+	struct snd_ad1848 *chip;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (port[dev] == SNDRV_AUTO_PORT) {
@@ -93,6 +96,7 @@
 				     thinkpad[dev] ? AD1848_HW_THINKPAD : AD1848_HW_DETECT,
 				     &chip)) < 0)
 		goto _err;
+	card->private_data = chip;
 
 	if ((err = snd_ad1848_pcm(chip, 0, &pcm)) < 0)
 		goto _err;
@@ -109,13 +113,12 @@
 	if (thinkpad[dev])
 		strcat(card->longname, " [Thinkpad]");
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
+	snd_card_set_dev(card, &pdev->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
-	snd_ad1848_cards[dev] = card;
+	platform_set_drvdata(pdev, card);
 	return 0;
 
  _err:
@@ -123,29 +126,95 @@
 	return err;
 }
 
+static int __devexit snd_ad1848_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_ad1848_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct snd_card *card = platform_get_drvdata(pdev);
+	struct snd_ad1848 *chip = card->private_data;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	chip->suspend(chip);
+	return 0;
+}
+
+static int snd_ad1848_resume(struct platform_device *pdev)
+{
+	struct snd_card *card = platform_get_drvdata(pdev);
+	struct snd_ad1848 *chip = card->private_data;
+
+	chip->resume(chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
+#define SND_AD1848_DRIVER	"snd_ad1848"
+
+static struct platform_driver snd_ad1848_driver = {
+	.probe		= snd_ad1848_probe,
+	.remove		= __devexit_p(snd_ad1848_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_ad1848_suspend,
+	.resume		= snd_ad1848_resume,
+#endif
+	.driver		= {
+		.name	= SND_AD1848_DRIVER
+	},
+};
+
+static void __init_or_module snd_ad1848_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_ad1848_driver);
+}
+
 static int __init alsa_card_ad1848_init(void)
 {
-	int dev, cards;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++)
-		if (snd_card_ad1848_probe(dev) >= 0)
-			cards++;
+	err = platform_driver_register(&snd_ad1848_driver);
+	if (err < 0)
+		return err;
 
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(SND_AD1848_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		devices[i] = device;
+		cards++;
+	}
 	if (!cards) {
 #ifdef MODULE
 		printk(KERN_ERR "AD1848 soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_ad1848_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_ad1848_exit(void)
 {
-	int idx;
-
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_ad1848_cards[idx]);
+	snd_ad1848_unregister_all();
 }
 
 module_init(alsa_card_ad1848_init)
diff --git a/sound/isa/ad1848/ad1848_lib.c b/sound/isa/ad1848/ad1848_lib.c
index 891bacc..b78530d 100644
--- a/sound/isa/ad1848/ad1848_lib.c
+++ b/sound/isa/ad1848/ad1848_lib.c
@@ -24,7 +24,6 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/pm.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <sound/core.h>
@@ -69,7 +68,7 @@
 	27042, 32000, 33075, 37800, 44100, 48000
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 	.count = 14,
 	.list = rates,
 	.mask = 0,
@@ -99,7 +98,7 @@
  *  Basic I/O functions
  */
 
-void snd_ad1848_out(ad1848_t *chip,
+void snd_ad1848_out(struct snd_ad1848 *chip,
 			   unsigned char reg,
 			   unsigned char value)
 {
@@ -119,7 +118,7 @@
 #endif
 }
 
-static void snd_ad1848_dout(ad1848_t *chip,
+static void snd_ad1848_dout(struct snd_ad1848 *chip,
 			    unsigned char reg, unsigned char value)
 {
 	int timeout;
@@ -131,7 +130,7 @@
 	mb();
 }
 
-static unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg)
+static unsigned char snd_ad1848_in(struct snd_ad1848 *chip, unsigned char reg)
 {
 	int timeout;
 
@@ -148,7 +147,7 @@
 
 #if 0
 
-static void snd_ad1848_debug(ad1848_t *chip)
+static void snd_ad1848_debug(struct snd_ad1848 *chip)
 {
 	printk("AD1848 REGS:      INDEX = 0x%02x  ", inb(AD1848P(chip, REGSEL)));
 	printk("                 STATUS = 0x%02x\n", inb(AD1848P(chip, STATUS)));
@@ -176,7 +175,7 @@
  *  AD1848 detection / MCE routines
  */
 
-static void snd_ad1848_mce_up(ad1848_t *chip)
+static void snd_ad1848_mce_up(struct snd_ad1848 *chip)
 {
 	unsigned long flags;
 	int timeout;
@@ -197,7 +196,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static void snd_ad1848_mce_down(ad1848_t *chip)
+static void snd_ad1848_mce_down(struct snd_ad1848 *chip)
 {
 	unsigned long flags;
 	int timeout;
@@ -279,7 +278,7 @@
 	return size;
 }
 
-static int snd_ad1848_trigger(ad1848_t *chip, unsigned char what,
+static int snd_ad1848_trigger(struct snd_ad1848 *chip, unsigned char what,
 			      int channel, int cmd)
 {
 	int result = 0;
@@ -324,7 +323,7 @@
 	return freq_bits[13];
 }
 
-static int snd_ad1848_ioctl(snd_pcm_substream_t * substream,
+static int snd_ad1848_ioctl(struct snd_pcm_substream *substream,
 			    unsigned int cmd, void *arg)
 {
 	return snd_pcm_lib_ioctl(substream, cmd, arg);
@@ -348,7 +347,7 @@
 	return rformat;
 }
 
-static void snd_ad1848_calibrate_mute(ad1848_t *chip, int mute)
+static void snd_ad1848_calibrate_mute(struct snd_ad1848 *chip, int mute)
 {
 	unsigned long flags;
 	
@@ -372,7 +371,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static void snd_ad1848_set_data_format(ad1848_t *chip, snd_pcm_hw_params_t *hw_params)
+static void snd_ad1848_set_data_format(struct snd_ad1848 *chip, struct snd_pcm_hw_params *hw_params)
 {
 	if (hw_params == NULL) {
 		chip->image[AD1848_DATA_FORMAT] = 0x20;
@@ -384,7 +383,7 @@
 	// snd_printk(">>> pmode = 0x%x, dfr = 0x%x\n", pstr->mode, chip->image[AD1848_DATA_FORMAT]);
 }
 
-static int snd_ad1848_open(ad1848_t *chip, unsigned int mode)
+static int snd_ad1848_open(struct snd_ad1848 *chip, unsigned int mode)
 {
 	unsigned long flags;
 
@@ -438,7 +437,7 @@
 	return 0;
 }
 
-static void snd_ad1848_close(ad1848_t *chip)
+static void snd_ad1848_close(struct snd_ad1848 *chip)
 {
 	unsigned long flags;
 
@@ -479,24 +478,24 @@
  *  ok.. exported functions..
  */
 
-static int snd_ad1848_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_ad1848_playback_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
 	return snd_ad1848_trigger(chip, AD1848_PLAYBACK_ENABLE, SNDRV_PCM_STREAM_PLAYBACK, cmd);
 }
 
-static int snd_ad1848_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_ad1848_capture_trigger(struct snd_pcm_substream *substream,
 				      int cmd)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
 	return snd_ad1848_trigger(chip, AD1848_CAPTURE_ENABLE, SNDRV_PCM_STREAM_CAPTURE, cmd);
 }
 
-static int snd_ad1848_playback_hw_params(snd_pcm_substream_t * substream,
-					 snd_pcm_hw_params_t * hw_params)
+static int snd_ad1848_playback_hw_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
 	unsigned long flags;
 	int err;
 
@@ -513,15 +512,15 @@
 	return 0;
 }
 
-static int snd_ad1848_playback_hw_free(snd_pcm_substream_t * substream)
+static int snd_ad1848_playback_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_ad1848_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_ad1848_playback_prepare(struct snd_pcm_substream *substream)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -537,10 +536,10 @@
 	return 0;
 }
 
-static int snd_ad1848_capture_hw_params(snd_pcm_substream_t * substream,
-					snd_pcm_hw_params_t * hw_params)
+static int snd_ad1848_capture_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
 	unsigned long flags;
 	int err;
 
@@ -557,15 +556,15 @@
 	return 0;
 }
 
-static int snd_ad1848_capture_hw_free(snd_pcm_substream_t * substream)
+static int snd_ad1848_capture_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_ad1848_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_ad1848_capture_prepare(struct snd_pcm_substream *substream)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -583,7 +582,7 @@
 
 static irqreturn_t snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	ad1848_t *chip = dev_id;
+	struct snd_ad1848 *chip = dev_id;
 
 	if ((chip->mode & AD1848_MODE_PLAY) && chip->playback_substream &&
 	    (chip->mode & AD1848_MODE_RUNNING))
@@ -595,9 +594,9 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_uframes_t snd_ad1848_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ad1848_playback_pointer(struct snd_pcm_substream *substream)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	
 	if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_PLAYBACK_ENABLE))
@@ -606,9 +605,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_ad1848_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ad1848_capture_pointer(struct snd_pcm_substream *substream)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(chip->image[AD1848_IFACE_CTRL] & AD1848_CAPTURE_ENABLE))
@@ -621,7 +620,7 @@
 
  */
 
-static void snd_ad1848_thinkpad_twiddle(ad1848_t *chip, int on) {
+static void snd_ad1848_thinkpad_twiddle(struct snd_ad1848 *chip, int on) {
 
 	int tmp;
 
@@ -642,33 +641,34 @@
 }
 
 #ifdef CONFIG_PM
-static int snd_ad1848_suspend(snd_card_t *card, pm_message_t state)
+static void snd_ad1848_suspend(struct snd_ad1848 *chip)
 {
-	ad1848_t *chip = card->pm_private_data;
-
 	snd_pcm_suspend_all(chip->pcm);
-	/* FIXME: save registers? */
-
 	if (chip->thinkpad_flag)
 		snd_ad1848_thinkpad_twiddle(chip, 0);
-
-	return 0;
 }
 
-static int snd_ad1848_resume(snd_card_t *card)
+static void snd_ad1848_resume(struct snd_ad1848 *chip)
 {
-	ad1848_t *chip = card->pm_private_data;
+	int i;
 
 	if (chip->thinkpad_flag)
 		snd_ad1848_thinkpad_twiddle(chip, 1);
 
-	/* FIXME: restore registers? */
+	/* clear any pendings IRQ */
+	inb(AD1848P(chip, STATUS));
+	outb(0, AD1848P(chip, STATUS));
+	mb();
 
-	return 0;
+	snd_ad1848_mce_down(chip);
+	for (i = 0; i < 16; i++)
+		snd_ad1848_out(chip, i, chip->image[i]);
+	snd_ad1848_mce_up(chip);
+	snd_ad1848_mce_down(chip);
 }
 #endif /* CONFIG_PM */
 
-static int snd_ad1848_probe(ad1848_t * chip)
+static int snd_ad1848_probe(struct snd_ad1848 * chip)
 {
 	unsigned long flags;
 	int i, id, rev, ad1847;
@@ -748,7 +748,7 @@
 
  */
 
-static snd_pcm_hardware_t snd_ad1848_playback =
+static struct snd_pcm_hardware snd_ad1848_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -767,7 +767,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ad1848_capture =
+static struct snd_pcm_hardware snd_ad1848_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -790,10 +790,10 @@
 
  */
 
-static int snd_ad1848_playback_open(snd_pcm_substream_t * substream)
+static int snd_ad1848_playback_open(struct snd_pcm_substream *substream)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if ((err = snd_ad1848_open(chip, AD1848_MODE_PLAY)) < 0)
@@ -806,10 +806,10 @@
 	return 0;
 }
 
-static int snd_ad1848_capture_open(snd_pcm_substream_t * substream)
+static int snd_ad1848_capture_open(struct snd_pcm_substream *substream)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if ((err = snd_ad1848_open(chip, AD1848_MODE_CAPTURE)) < 0)
@@ -822,9 +822,9 @@
 	return 0;
 }
 
-static int snd_ad1848_playback_close(snd_pcm_substream_t * substream)
+static int snd_ad1848_playback_close(struct snd_pcm_substream *substream)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
 
 	chip->mode &= ~AD1848_MODE_PLAY;
 	chip->playback_substream = NULL;
@@ -832,9 +832,9 @@
 	return 0;
 }
 
-static int snd_ad1848_capture_close(snd_pcm_substream_t * substream)
+static int snd_ad1848_capture_close(struct snd_pcm_substream *substream)
 {
-	ad1848_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ad1848 *chip = snd_pcm_substream_chip(substream);
 
 	chip->mode &= ~AD1848_MODE_CAPTURE;
 	chip->capture_substream = NULL;
@@ -842,7 +842,7 @@
 	return 0;
 }
 
-static int snd_ad1848_free(ad1848_t *chip)
+static int snd_ad1848_free(struct snd_ad1848 *chip)
 {
 	release_and_free_resource(chip->res_port);
 	if (chip->irq >= 0)
@@ -855,13 +855,13 @@
 	return 0;
 }
 
-static int snd_ad1848_dev_free(snd_device_t *device)
+static int snd_ad1848_dev_free(struct snd_device *device)
 {
-	ad1848_t *chip = device->device_data;
+	struct snd_ad1848 *chip = device->device_data;
 	return snd_ad1848_free(chip);
 }
 
-static const char *snd_ad1848_chip_id(ad1848_t *chip)
+static const char *snd_ad1848_chip_id(struct snd_ad1848 *chip)
 {
 	switch (chip->hardware) {
 	case AD1848_HW_AD1847:	return "AD1847";
@@ -872,16 +872,16 @@
 	}
 }
 
-int snd_ad1848_create(snd_card_t * card,
+int snd_ad1848_create(struct snd_card *card,
 		      unsigned long port,
 		      int irq, int dma,
 		      unsigned short hardware,
-		      ad1848_t ** rchip)
+		      struct snd_ad1848 ** rchip)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_ad1848_dev_free,
 	};
-	ad1848_t *chip;
+	struct snd_ad1848 *chip;
 	int err;
 
 	*rchip = NULL;
@@ -919,7 +919,6 @@
 		chip->thinkpad_flag = 1;
 		chip->hardware = AD1848_HW_DETECT; /* reset */
 		snd_ad1848_thinkpad_twiddle(chip, 1);
-		snd_card_set_isa_pm_callback(card, snd_ad1848_suspend, snd_ad1848_resume, chip);
 	}
 
 	if (snd_ad1848_probe(chip) < 0) {
@@ -933,11 +932,16 @@
 		return err;
 	}
 
+#ifdef CONFIG_PM
+	chip->suspend = snd_ad1848_suspend;
+	chip->resume = snd_ad1848_resume;
+#endif
+
 	*rchip = chip;
 	return 0;
 }
 
-static snd_pcm_ops_t snd_ad1848_playback_ops = {
+static struct snd_pcm_ops snd_ad1848_playback_ops = {
 	.open =		snd_ad1848_playback_open,
 	.close =	snd_ad1848_playback_close,
 	.ioctl =	snd_ad1848_ioctl,
@@ -948,7 +952,7 @@
 	.pointer =	snd_ad1848_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_ad1848_capture_ops = {
+static struct snd_pcm_ops snd_ad1848_capture_ops = {
 	.open =		snd_ad1848_capture_open,
 	.close =	snd_ad1848_capture_close,
 	.ioctl =	snd_ad1848_ioctl,
@@ -959,16 +963,9 @@
 	.pointer =	snd_ad1848_capture_pointer,
 };
 
-static void snd_ad1848_pcm_free(snd_pcm_t *pcm)
+int snd_ad1848_pcm(struct snd_ad1848 *chip, int device, struct snd_pcm **rpcm)
 {
-	ad1848_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int snd_ad1848_pcm(ad1848_t *chip, int device, snd_pcm_t **rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(chip->card, "AD1848", device, 1, 1, &pcm)) < 0)
@@ -977,7 +974,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ad1848_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ad1848_capture_ops);
 
-	pcm->private_free = snd_ad1848_pcm_free;
 	pcm->private_data = chip;
 	pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
 	strcpy(pcm->name, snd_ad1848_chip_id(chip));
@@ -992,7 +988,7 @@
 	return 0;
 }
 
-const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction)
+const struct snd_pcm_ops *snd_ad1848_get_pcm_ops(int direction)
 {
 	return direction == SNDRV_PCM_STREAM_PLAYBACK ?
 		&snd_ad1848_playback_ops : &snd_ad1848_capture_ops;
@@ -1002,7 +998,7 @@
  *  MIXER part
  */
 
-static int snd_ad1848_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ad1848_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = {
 		"Line", "Aux", "Mic", "Mix"
@@ -1017,9 +1013,9 @@
 	return 0;
 }
 
-static int snd_ad1848_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1029,9 +1025,9 @@
 	return 0;
 }
 
-static int snd_ad1848_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned short left, right;
 	int change;
@@ -1052,7 +1048,7 @@
 	return change;
 }
 
-static int snd_ad1848_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ad1848_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -1063,9 +1059,9 @@
 	return 0;
 }
 
-static int snd_ad1848_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -1080,9 +1076,9 @@
 	return 0;
 }
 
-static int snd_ad1848_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -1103,7 +1099,7 @@
 	return change;
 }
 
-static int snd_ad1848_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ad1848_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -1114,9 +1110,9 @@
 	return 0;
 }
 
-static int snd_ad1848_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -1136,9 +1132,9 @@
 	return 0;
 }
 
-static int snd_ad1848_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ad1848_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ad1848_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ad1848 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -1175,9 +1171,9 @@
 
 /*
  */
-int snd_ad1848_add_ctl(ad1848_t *chip, const char *name, int index, int type, unsigned long value)
+int snd_ad1848_add_ctl(struct snd_ad1848 *chip, const char *name, int index, int type, unsigned long value)
 {
-	static snd_kcontrol_new_t newctls[] = {
+	static struct snd_kcontrol_new newctls[] = {
 		[AD1848_MIX_SINGLE] = {
 			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 			.info = snd_ad1848_info_single,
@@ -1197,7 +1193,7 @@
 			.put = snd_ad1848_put_mux,
 		},
 	};
-	snd_kcontrol_t *ctl;
+	struct snd_kcontrol *ctl;
 	int err;
 
 	ctl = snd_ctl_new1(&newctls[type], chip);
@@ -1230,10 +1226,10 @@
 AD1848_SINGLE("Loopback Capture Volume", 0, AD1848_LOOPBACK, 1, 63, 0)
 };
                                         
-int snd_ad1848_mixer(ad1848_t *chip)
+int snd_ad1848_mixer(struct snd_ad1848 *chip)
 {
-	snd_card_t *card;
-	snd_pcm_t *pcm;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
 	unsigned int idx;
 	int err;
 
diff --git a/sound/isa/als100.c b/sound/isa/als100.c
index ac8f136..9b77c17 100644
--- a/sound/isa/als100.c
+++ b/sound/isa/als100.c
@@ -83,6 +83,7 @@
 	struct pnp_dev *dev;
 	struct pnp_dev *devmpu;
 	struct pnp_dev *devopl;
+	struct snd_sb *chip;
 };
 
 static struct pnp_card_device_id snd_als100_pnpids[] = {
@@ -203,15 +204,15 @@
 					const struct pnp_card_device_id *pid)
 {
 	int error;
-	sb_t *chip;
-	snd_card_t *card;
+	struct snd_sb *chip;
+	struct snd_card *card;
 	struct snd_card_als100 *acard;
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
 	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 				 sizeof(struct snd_card_als100))) == NULL)
 		return -ENOMEM;
-	acard = (struct snd_card_als100 *)card->private_data;
+	acard = card->private_data;
 
 	if ((error = snd_card_als100_pnp(dev, acard, pcard, pid))) {
 		snd_card_free(card);
@@ -228,6 +229,7 @@
 		snd_card_free(card);
 		return error;
 	}
+	acard->chip = chip;
 
 	strcpy(card->driver, "ALS100");
 	strcpy(card->shortname, "Avance Logic ALS100");
@@ -299,32 +301,61 @@
 
 static void __devexit snd_als100_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_als100_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+	struct snd_card_als100 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(chip->pcm);
+	snd_sbmixer_suspend(chip);
+	return 0;
+}
+
+static int snd_als100_pnp_resume(struct pnp_card_link *pcard)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+	struct snd_card_als100 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_sbdsp_reset(chip);
+	snd_sbmixer_resume(chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
 static struct pnp_card_driver als100_pnpc_driver = {
 	.flags          = PNP_DRIVER_RES_DISABLE,
         .name           = "als100",
         .id_table       = snd_als100_pnpids,
         .probe          = snd_als100_pnp_detect,
         .remove         = __devexit_p(snd_als100_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_als100_pnp_suspend,
+	.resume		= snd_als100_pnp_resume,
+#endif
 };
 
 static int __init alsa_card_als100_init(void)
 {
-	int cards = 0;
+	int cards;
 
-	cards += pnp_register_card_driver(&als100_pnpc_driver);
-#ifdef MODULE
-	if (!cards) {
+	cards = pnp_register_card_driver(&als100_pnpc_driver);
+	if (cards <= 0) {
 		pnp_unregister_card_driver(&als100_pnpc_driver);
+#ifdef MODULE
 		snd_printk(KERN_ERR "no ALS100 based soundcards found\n");
-	}
 #endif
-	return cards ? 0 : -ENODEV;
+		return -ENODEV;
+	}
+	return 0;
 }
 
 static void __exit alsa_card_als100_exit(void)
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c
index bb41c6ec..a530691 100644
--- a/sound/isa/azt2320.c
+++ b/sound/isa/azt2320.c
@@ -93,6 +93,7 @@
 	int dev_no;
 	struct pnp_dev *dev;
 	struct pnp_dev *devmpu;
+	struct snd_cs4231 *chip;
 };
 
 static struct pnp_card_device_id snd_azt2320_pnpids[] = {
@@ -227,10 +228,10 @@
 					    const struct pnp_card_device_id *pid)
 {
 	int error;
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_card_azt2320 *acard;
-	cs4231_t *chip;
-	opl3_t *opl3;
+	struct snd_cs4231 *chip;
+	struct snd_opl3 *opl3;
 
 	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 				 sizeof(struct snd_card_azt2320))) == NULL)
@@ -329,32 +330,59 @@
 
 static void __devexit snd_azt2320_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_azt2320_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+	struct snd_card_azt2320 *acard = card->private_data;
+	struct snd_cs4231 *chip = acard->chip;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	chip->suspend(chip);
+	return 0;
+}
+
+static int snd_azt2320_pnp_resume(struct pnp_card_link *pcard)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+	struct snd_card_azt2320 *acard = card->private_data;
+	struct snd_cs4231 *chip = acard->chip;
+
+	chip->resume(chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
 static struct pnp_card_driver azt2320_pnpc_driver = {
 	.flags          = PNP_DRIVER_RES_DISABLE,
 	.name           = "azt2320",
 	.id_table       = snd_azt2320_pnpids,
 	.probe          = snd_azt2320_pnp_detect,
 	.remove         = __devexit_p(snd_azt2320_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_azt2320_pnp_suspend,
+	.resume		= snd_azt2320_pnp_resume,
+#endif
 };
 
 static int __init alsa_card_azt2320_init(void)
 {
-	int cards = 0;
+	int cards;
 
-	cards += pnp_register_card_driver(&azt2320_pnpc_driver);
-#ifdef MODULE
-	if (!cards) {
+	cards = pnp_register_card_driver(&azt2320_pnpc_driver);
+	if (cards <= 0) {
 		pnp_unregister_card_driver(&azt2320_pnpc_driver);
+#ifdef MODULE
 		snd_printk(KERN_ERR "no AZT2320 based soundcards found\n");
-	}
 #endif
-	return cards ? 0 : -ENODEV;
+		return -ENODEV;
+	}
+	return 0;
 }
 
 static void __exit alsa_card_azt2320_exit(void)
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 5252206..bd8e238 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -45,6 +45,8 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
@@ -106,6 +108,9 @@
 module_param_array(wssdma, int, NULL, 0444);
 MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
+
 #define CMI8330_RMUX3D    16
 #define CMI8330_MUTEMUX   17
 #define CMI8330_OUTPUTVOL 18
@@ -137,27 +142,25 @@
 	0x0			/* 26 - cd-in rec gain */
 };
 
-typedef int (*snd_pcm_open_callback_t)(snd_pcm_substream_t *);
+typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *);
 
 struct snd_cmi8330 {
 #ifdef CONFIG_PNP
 	struct pnp_dev *cap;
 	struct pnp_dev *play;
 #endif
-	snd_card_t *card;
-	ad1848_t *wss;
-	sb_t *sb;
+	struct snd_card *card;
+	struct snd_ad1848 *wss;
+	struct snd_sb *sb;
 
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	struct snd_cmi8330_stream {
-		snd_pcm_ops_t ops;
+		struct snd_pcm_ops ops;
 		snd_pcm_open_callback_t open;
 		void *private_data; /* sb or wss */
 	} streams[2];
 };
 
-static snd_card_t *snd_cmi8330_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
 #ifdef CONFIG_PNP
 
 static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
@@ -231,7 +234,7 @@
 };
 
 
-static int __devinit cmi8330_add_sb_mixers(sb_t *chip)
+static int __devinit cmi8330_add_sb_mixers(struct snd_sb *chip)
 {
 	int idx, err;
 	unsigned long flags;
@@ -256,7 +259,7 @@
 }
 #endif
 
-static int __devinit snd_cmi8330_mixer(snd_card_t *card, struct snd_cmi8330 *acard)
+static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330 *acard)
 {
 	unsigned int idx;
 	int err;
@@ -370,7 +373,7 @@
 #define CMI_AD_STREAM	SNDRV_PCM_STREAM_PLAYBACK
 #endif
 
-static int snd_cmi8330_playback_open(snd_pcm_substream_t * substream)
+static int snd_cmi8330_playback_open(struct snd_pcm_substream *substream)
 {
 	struct snd_cmi8330 *chip = snd_pcm_substream_chip(substream);
 
@@ -379,7 +382,7 @@
 	return chip->streams[SNDRV_PCM_STREAM_PLAYBACK].open(substream);
 }
 
-static int snd_cmi8330_capture_open(snd_pcm_substream_t * substream)
+static int snd_cmi8330_capture_open(struct snd_pcm_substream *substream)
 {
 	struct snd_cmi8330 *chip = snd_pcm_substream_chip(substream);
 
@@ -388,15 +391,10 @@
 	return chip->streams[SNDRV_PCM_STREAM_CAPTURE].open(substream);
 }
 
-static void snd_cmi8330_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *chip)
 {
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_cmi8330_pcm(snd_card_t *card, struct snd_cmi8330 *chip)
-{
-	snd_pcm_t *pcm;
-	const snd_pcm_ops_t *ops;
+	struct snd_pcm *pcm;
+	const struct snd_pcm_ops *ops;
 	int err;
 	static snd_pcm_open_callback_t cmi_open_callbacks[2] = {
 		snd_cmi8330_playback_open,
@@ -407,7 +405,6 @@
 		return err;
 	strcpy(pcm->name, "CMI8330");
 	pcm->private_data = chip;
-	pcm->private_free = snd_cmi8330_pcm_free;
 	
 	/* SB16 */
 	ops = snd_sb16dsp_get_pcm_ops(CMI_SB_STREAM);
@@ -435,6 +432,31 @@
 }
 
 
+#ifdef CONFIG_PM
+static int snd_cmi8330_suspend(struct snd_card *card)
+{
+	struct snd_cmi8330 *acard = card->private_data;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(acard->pcm);
+	acard->wss->suspend(acard->wss);
+	snd_sbmixer_suspend(acard->sb);
+	return 0;
+}
+
+static int snd_cmi8330_resume(struct snd_card *card)
+{
+	struct snd_cmi8330 *acard = card->private_data;
+
+	snd_sbdsp_reset(acard->sb);
+	snd_sbmixer_suspend(acard->sb);
+	acard->wss->resume(acard->wss);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
+
 /*
  */
 
@@ -446,44 +468,28 @@
 
 #define PFX	"cmi8330: "
 
-static int __devinit snd_cmi8330_probe(int dev,
-				       struct pnp_card_link *pcard,
-				       const struct pnp_card_device_id *pid)
+static struct snd_card *snd_cmi8330_card_new(int dev)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_cmi8330 *acard;
-	int i, err;
-
-	if (! is_isapnp_selected(dev)) {
-		if (wssport[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR PFX "specify wssport\n");
-			return -EINVAL;
-		}
-		if (sbport[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR PFX "specify sbport\n");
-			return -EINVAL;
-		}
-	}
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(struct snd_cmi8330));
 	if (card == NULL) {
 		snd_printk(KERN_ERR PFX "could not get a new card\n");
-		return -ENOMEM;
+		return NULL;
 	}
-	acard = (struct snd_cmi8330 *)card->private_data;
+	acard = card->private_data;
 	acard->card = card;
+	return card;
+}
 
-#ifdef CONFIG_PNP
-	if (isapnp[dev]) {
-		if ((err = snd_cmi8330_pnp(dev, acard, pcard, pid)) < 0) {
-			snd_printk(KERN_ERR PFX "PnP detection failed\n");
-			goto _err;
-		}
-		snd_card_set_dev(card, &pcard->card->dev);
-	}
-#endif
+static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
+{
+	struct snd_cmi8330 *acard;
+	int i, err;
 
+	acard = card->private_data;
 	if ((err = snd_ad1848_create(card,
 				     wssport[dev] + 4,
 				     wssirq[dev],
@@ -491,12 +497,11 @@
 				     AD1848_HW_DETECT,
 				     &acard->wss)) < 0) {
 		snd_printk(KERN_ERR PFX "(AD1848) device busy??\n");
-		goto _err;
+		return err;
 	}
 	if (acard->wss->hardware != AD1848_HW_CMI8330) {
 		snd_printk(KERN_ERR PFX "(AD1848) not found during probe\n");
-		err = -ENODEV;
-		goto _err;
+		return -ENODEV;
 	}
 
 	if ((err = snd_sbdsp_create(card, sbport[dev],
@@ -506,11 +511,11 @@
 				    sbdma16[dev],
 				    SB_HW_AUTO, &acard->sb)) < 0) {
 		snd_printk(KERN_ERR PFX "(SB16) device busy??\n");
-		goto _err;
+		return err;
 	}
 	if (acard->sb->hardware != SB_HW_16) {
 		snd_printk(KERN_ERR PFX "(SB16) not found during probe\n");
-		goto _err;
+		return err;
 	}
 
 	snd_ad1848_out(acard->wss, AD1848_MISC_INFO, 0x40); /* switch on MODE2 */
@@ -519,12 +524,12 @@
 
 	if ((err = snd_cmi8330_mixer(card, acard)) < 0) {
 		snd_printk(KERN_ERR PFX "failed to create mixers\n");
-		goto _err;
+		return err;
 	}
 
 	if ((err = snd_cmi8330_pcm(card, acard)) < 0) {
 		snd_printk(KERN_ERR PFX "failed to create pcms\n");
-		goto _err;
+		return err;
 	}
 
 	strcpy(card->driver, "CMI8330/C3D");
@@ -535,97 +540,189 @@
 		wssirq[dev],
 		wssdma[dev]);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
-
-	if ((err = snd_card_register(card)) < 0)
-		goto _err;
-
-	if (pcard)
-		pnp_set_card_drvdata(pcard, card);
-	else
-		snd_cmi8330_legacy[dev] = card;
-	return 0;
-
- _err:
-	snd_card_free(card);
-	return err;
+	return snd_card_register(card);
 }
 
+static int __init snd_cmi8330_nonpnp_probe(struct platform_device *pdev)
+{
+	struct snd_card *card;
+	int err;
+	int dev = pdev->id;
+
+	if (wssport[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR PFX "specify wssport\n");
+		return -EINVAL;
+	}
+	if (sbport[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR PFX "specify sbport\n");
+		return -EINVAL;
+	}
+
+	card = snd_cmi8330_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	snd_card_set_dev(card, &pdev->dev);
+	if ((err = snd_cmi8330_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	platform_set_drvdata(pdev, card);
+	return 0;
+}
+
+static int snd_cmi8330_nonpnp_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_cmi8330_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+{
+	return snd_cmi8330_suspend(platform_get_drvdata(dev));
+}
+
+static int snd_cmi8330_nonpnp_resume(struct platform_device *dev)
+{
+	return snd_cmi8330_resume(platform_get_drvdata(dev));
+}
+#endif
+
+#define CMI8330_DRIVER	"snd_cmi8330"
+
+static struct platform_driver snd_cmi8330_driver = {
+	.probe		= snd_cmi8330_nonpnp_probe,
+	.remove		= snd_cmi8330_nonpnp_remove,
+#ifdef CONFIG_PM
+	.suspend	= snd_cmi8330_nonpnp_suspend,
+	.resume		= snd_cmi8330_nonpnp_resume,
+#endif
+	.driver		= {
+		.name	= CMI8330_DRIVER
+	},
+};
+
+
 #ifdef CONFIG_PNP
-static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *card,
-					    const struct pnp_card_device_id *id)
+static int __devinit snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
+					    const struct pnp_card_device_id *pid)
 {
 	static int dev;
+	struct snd_card *card;
 	int res;
 
 	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || !isapnp[dev])
-			continue;
-		res = snd_cmi8330_probe(dev, card, id);
-		if (res < 0)
-			return res;
-		dev++;
-		return 0;
+		if (enable[dev] && isapnp[dev])
+			break;
 	}
-	return -ENODEV;
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+			       
+	card = snd_cmi8330_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	if ((res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid)) < 0) {
+		snd_printk(KERN_ERR PFX "PnP detection failed\n");
+		snd_card_free(card);
+		return res;
+	}
+	snd_card_set_dev(card, &pcard->card->dev);
+	if ((res = snd_cmi8330_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return res;
+	}
+	pnp_set_card_drvdata(pcard, card);
+	dev++;
+	return 0;
 }
 
 static void __devexit snd_cmi8330_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_cmi8330_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	return snd_cmi8330_suspend(pnp_get_card_drvdata(pcard));
+}
+
+static int snd_cmi8330_pnp_resume(struct pnp_card_link *pcard)
+{
+	return snd_cmi8330_resume(pnp_get_card_drvdata(pcard));
+}
+#endif
+
 static struct pnp_card_driver cmi8330_pnpc_driver = {
 	.flags = PNP_DRIVER_RES_DISABLE,
 	.name = "cmi8330",
 	.id_table = snd_cmi8330_pnpids,
 	.probe = snd_cmi8330_pnp_detect,
 	.remove = __devexit_p(snd_cmi8330_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_cmi8330_pnp_suspend,
+	.resume		= snd_cmi8330_pnp_resume,
+#endif
 };
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_cmi8330_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&cmi8330_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_cmi8330_driver);
+}
+
 static int __init alsa_card_cmi8330_init(void)
 {
-	int dev, cards = 0;
+	int i, err, cards = 0;
 
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev])
+	if ((err = platform_driver_register(&snd_cmi8330_driver)) < 0)
+		return err;
+
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		if (is_isapnp_selected(i))
 			continue;
-		if (is_isapnp_selected(dev))
-			continue;
-		if (snd_cmi8330_probe(dev, NULL, NULL) >= 0)
-			cards++;
+		device = platform_device_register_simple(CMI8330_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		platform_devices[i] = device;
+		cards++;
 	}
-#ifdef CONFIG_PNP
-	cards += pnp_register_card_driver(&cmi8330_pnpc_driver);
-#endif
+
+	err = pnp_register_card_driver(&cmi8330_pnpc_driver);
+	if (err >= 0) {
+		pnp_registered = 1;
+		cards += err;
+	}
 
 	if (!cards) {
-#ifdef CONFIG_PNP
-		pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-#endif
 #ifdef MODULE
 		snd_printk(KERN_ERR "CMI8330 not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_cmi8330_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_cmi8330_exit(void)
 {
-	int i;
-
-#ifdef CONFIG_PNP
-	/* PnP cards first */
-	pnp_unregister_card_driver(&cmi8330_pnpc_driver);
-#endif
-	for (i = 0; i < SNDRV_CARDS; i++)
-		snd_card_free(snd_cmi8330_legacy[i]);
+	snd_cmi8330_unregister_all();
 }
 
 module_init(alsa_card_cmi8330_init)
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index 9be5416..ab67b5c 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -22,6 +22,8 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
@@ -64,15 +66,15 @@
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for CS4231 driver.");
 
-static snd_card_t *snd_cs4231_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct platform_device *devices[SNDRV_CARDS];
 
 
-static int __init snd_card_cs4231_probe(int dev)
+static int __init snd_cs4231_probe(struct platform_device *pdev)
 {
-	snd_card_t *card;
-	struct snd_card_cs4231 *acard;
-	snd_pcm_t *pcm = NULL;
-	cs4231_t *chip;
+	int dev = pdev->id;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_cs4231 *chip;
 	int err;
 
 	if (port[dev] == SNDRV_AUTO_PORT) {
@@ -90,7 +92,6 @@
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
-	acard = (struct snd_card_cs4231 *)card->private_data;
 	if ((err = snd_cs4231_create(card, port[dev], -1,
 				     irq[dev],
 				     dma1[dev],
@@ -98,6 +99,7 @@
 				     CS4231_HW_DETECT,
 				     0, &chip)) < 0)
 		goto _err;
+	card->private_data = chip;
 
 	if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
 		goto _err;
@@ -125,12 +127,12 @@
 			printk(KERN_WARNING "cs4231: MPU401 not detected\n");
 	}
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
+	snd_card_set_dev(card, &pdev->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
-	snd_cs4231_cards[dev] = card;
+
+	platform_set_drvdata(pdev, card);
 	return 0;
 
  _err:
@@ -138,29 +140,97 @@
 	return err;
 }
 
+static int __devexit snd_cs4231_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_cs4231_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct snd_card *card;
+	struct snd_cs4231 *chip;
+	card = platform_get_drvdata(dev);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	chip = card->private_data;
+	chip->suspend(chip);
+	return 0;
+}
+
+static int snd_cs4231_resume(struct platform_device *dev)
+{
+	struct snd_card *card;
+	struct snd_cs4231 *chip;
+	card = platform_get_drvdata(dev);
+	chip = card->private_data;
+	chip->resume(chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
+#define SND_CS4231_DRIVER	"snd_cs4231"
+
+static struct platform_driver snd_cs4231_driver = {
+	.probe		= snd_cs4231_probe,
+	.remove		= __devexit_p(snd_cs4231_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_cs4231_suspend,
+	.resume		= snd_cs4231_resume,
+#endif
+	.driver		= {
+		.name	= SND_CS4231_DRIVER
+	},
+};
+
+static void __init_or_module snd_cs4231_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_cs4231_driver);
+}
+
 static int __init alsa_card_cs4231_init(void)
 {
-	int dev, cards;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) {
-		if (snd_card_cs4231_probe(dev) >= 0)
-			cards++;
+	err = platform_driver_register(&snd_cs4231_driver);
+	if (err < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(SND_CS4231_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		devices[i] = device;
+		cards++;
 	}
 	if (!cards) {
 #ifdef MODULE
 		printk(KERN_ERR "CS4231 soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_cs4231_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_cs4231_exit(void)
 {
-	int idx;
-
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_cs4231_cards[idx]);
+	snd_cs4231_unregister_all();
 }
 
 module_init(alsa_card_cs4231_init)
diff --git a/sound/isa/cs423x/cs4231_lib.c b/sound/isa/cs423x/cs4231_lib.c
index 4af7690..eab7eb5 100644
--- a/sound/isa/cs423x/cs4231_lib.c
+++ b/sound/isa/cs423x/cs4231_lib.c
@@ -73,13 +73,13 @@
 	27042, 32000, 33075, 37800, 44100, 48000
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 	.count = 14,
 	.list = rates,
 	.mask = 0,
 };
 
-static int snd_cs4231_xrate(snd_pcm_runtime_t *runtime)
+static int snd_cs4231_xrate(struct snd_pcm_runtime *runtime)
 {
 	return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
 }
@@ -124,49 +124,17 @@
  *  Basic I/O functions
  */
 
-#if !defined(EBUS_SUPPORT) && !defined(SBUS_SUPPORT)
-#define __CS4231_INLINE__ inline
-#else
-#define __CS4231_INLINE__ /* nothing */
-#endif
-
-static __CS4231_INLINE__ void cs4231_outb(cs4231_t *chip, u8 offset, u8 val)
+static inline void cs4231_outb(struct snd_cs4231 *chip, u8 offset, u8 val)
 {
-#ifdef EBUS_SUPPORT
-	if (chip->ebus->flag) {
-		writeb(val, chip->port + (offset << 2));
-	} else {
-#endif
-#ifdef SBUS_SUPPORT
-		sbus_writeb(val, chip->port + (offset << 2));
-#endif
-#ifdef EBUS_SUPPORT
-	}
-#endif
-#ifdef LEGACY_SUPPORT
 	outb(val, chip->port + offset);
-#endif
 }
 
-static __CS4231_INLINE__ u8 cs4231_inb(cs4231_t *chip, u8 offset)
+static inline u8 cs4231_inb(struct snd_cs4231 *chip, u8 offset)
 {
-#ifdef EBUS_SUPPORT
-	if (chip->ebus_flag) {
-		return readb(chip->port + (offset << 2));
-	} else {
-#endif
-#ifdef SBUS_SUPPORT
-		return sbus_readb(chip->port + (offset << 2));
-#endif
-#ifdef EBUS_SUPPORT
-	}
-#endif
-#ifdef LEGACY_SUPPORT
 	return inb(chip->port + offset);
-#endif
 }
 
-static void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
+static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg,
 			    unsigned char mask, unsigned char value)
 {
 	int timeout;
@@ -193,7 +161,7 @@
 	}
 }
 
-static void snd_cs4231_dout(cs4231_t *chip, unsigned char reg, unsigned char value)
+static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
 {
 	int timeout;
 
@@ -206,7 +174,7 @@
 	mb();
 }
 
-void snd_cs4231_out(cs4231_t *chip, unsigned char reg, unsigned char value)
+void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
 {
 	int timeout;
 
@@ -227,7 +195,7 @@
 #endif
 }
 
-unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg)
+unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg)
 {
 	int timeout;
 
@@ -244,7 +212,7 @@
 	return cs4231_inb(chip, CS4231P(REG));
 }
 
-void snd_cs4236_ext_out(cs4231_t *chip, unsigned char reg, unsigned char val)
+void snd_cs4236_ext_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val)
 {
 	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
 	cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01));
@@ -255,7 +223,7 @@
 #endif
 }
 
-unsigned char snd_cs4236_ext_in(cs4231_t *chip, unsigned char reg)
+unsigned char snd_cs4236_ext_in(struct snd_cs4231 *chip, unsigned char reg)
 {
 	cs4231_outb(chip, CS4231P(REGSEL), chip->mce_bit | 0x17);
 	cs4231_outb(chip, CS4231P(REG), reg | (chip->image[CS4236_EXT_REG] & 0x01));
@@ -273,7 +241,7 @@
 
 #if 0
 
-static void snd_cs4231_debug(cs4231_t *chip)
+static void snd_cs4231_debug(struct snd_cs4231 *chip)
 {
 	printk("CS4231 REGS:      INDEX = 0x%02x  ", cs4231_inb(chip, CS4231P(REGSEL)));
 	printk("                 STATUS = 0x%02x\n", cs4231_inb(chip, CS4231P(STATUS)));
@@ -317,7 +285,7 @@
  *  CS4231 detection / MCE routines
  */
 
-static void snd_cs4231_busy_wait(cs4231_t *chip)
+static void snd_cs4231_busy_wait(struct snd_cs4231 *chip)
 {
 	int timeout;
 
@@ -331,7 +299,7 @@
 	     	udelay(10);
 }
 
-void snd_cs4231_mce_up(cs4231_t *chip)
+void snd_cs4231_mce_up(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 	int timeout;
@@ -352,7 +320,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-void snd_cs4231_mce_down(cs4231_t *chip)
+void snd_cs4231_mce_down(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 	int timeout;
@@ -431,14 +399,14 @@
 	return size;
 }
 
-static int snd_cs4231_trigger(snd_pcm_substream_t *substream,
+static int snd_cs4231_trigger(struct snd_pcm_substream *substream,
 			      int cmd)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	int result = 0;
 	unsigned int what;
 	struct list_head *pos;
-	snd_pcm_substream_t *s;
+	struct snd_pcm_substream *s;
 	int do_start;
 
 #if 0
@@ -500,7 +468,7 @@
 	return freq_bits[13];
 }
 
-static unsigned char snd_cs4231_get_format(cs4231_t *chip,
+static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip,
 				           int format,
                                            int channels)
 {
@@ -522,7 +490,7 @@
 	return rformat;
 }
 
-static void snd_cs4231_calibrate_mute(cs4231_t *chip, int mute)
+static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute)
 {
 	unsigned long flags;
 
@@ -556,8 +524,8 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static void snd_cs4231_playback_format(cs4231_t *chip,
-				       snd_pcm_hw_params_t *params,
+static void snd_cs4231_playback_format(struct snd_cs4231 *chip,
+				       struct snd_pcm_hw_params *params,
 				       unsigned char pdfr)
 {
 	unsigned long flags;
@@ -595,8 +563,8 @@
 	up(&chip->mce_mutex);
 }
 
-static void snd_cs4231_capture_format(cs4231_t *chip,
-				      snd_pcm_hw_params_t *params,
+static void snd_cs4231_capture_format(struct snd_cs4231 *chip,
+				      struct snd_pcm_hw_params *params,
                                       unsigned char cdfr)
 {
 	unsigned long flags;
@@ -642,20 +610,20 @@
  *  Timer interface
  */
 
-static unsigned long snd_cs4231_timer_resolution(snd_timer_t * timer)
+static unsigned long snd_cs4231_timer_resolution(struct snd_timer * timer)
 {
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 	if (chip->hardware & CS4231_HW_CS4236B_MASK)
 		return 14467;
 	else
 		return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920;
 }
 
-static int snd_cs4231_timer_start(snd_timer_t * timer)
+static int snd_cs4231_timer_start(struct snd_timer * timer)
 {
 	unsigned long flags;
 	unsigned int ticks;
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	ticks = timer->sticks;
 	if ((chip->image[CS4231_ALT_FEATURE_1] & CS4231_TIMER_ENABLE) == 0 ||
@@ -669,17 +637,17 @@
 	return 0;
 }
 
-static int snd_cs4231_timer_stop(snd_timer_t * timer)
+static int snd_cs4231_timer_stop(struct snd_timer * timer)
 {
 	unsigned long flags;
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	snd_cs4231_out(chip, CS4231_ALT_FEATURE_1, chip->image[CS4231_ALT_FEATURE_1] &= ~CS4231_TIMER_ENABLE);
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	return 0;
 }
 
-static void snd_cs4231_init(cs4231_t *chip)
+static void snd_cs4231_init(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 
@@ -737,7 +705,7 @@
 #endif
 }
 
-static int snd_cs4231_open(cs4231_t *chip, unsigned int mode)
+static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
 {
 	unsigned long flags;
 
@@ -773,7 +741,7 @@
 	return 0;
 }
 
-static void snd_cs4231_close(cs4231_t *chip, unsigned int mode)
+static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
 {
 	unsigned long flags;
 
@@ -824,21 +792,21 @@
  *  timer open/close
  */
 
-static int snd_cs4231_timer_open(snd_timer_t * timer)
+static int snd_cs4231_timer_open(struct snd_timer * timer)
 {
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 	snd_cs4231_open(chip, CS4231_MODE_TIMER);
 	return 0;
 }
 
-static int snd_cs4231_timer_close(snd_timer_t * timer)
+static int snd_cs4231_timer_close(struct snd_timer * timer)
 {
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 	snd_cs4231_close(chip, CS4231_MODE_TIMER);
 	return 0;
 }
 
-static struct _snd_timer_hardware snd_cs4231_timer_table =
+static struct snd_timer_hardware snd_cs4231_timer_table =
 {
 	.flags =	SNDRV_TIMER_HW_AUTO,
 	.resolution =	9945,
@@ -854,10 +822,10 @@
  *  ok.. exported functions..
  */
 
-static int snd_cs4231_playback_hw_params(snd_pcm_substream_t * substream,
-					 snd_pcm_hw_params_t * hw_params)
+static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	unsigned char new_pdfr;
 	int err;
 
@@ -869,16 +837,15 @@
 	return 0;
 }
 
-static int snd_cs4231_playback_hw_free(snd_pcm_substream_t * substream)
+static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-#ifdef LEGACY_SUPPORT
-static int snd_cs4231_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -896,12 +863,11 @@
 #endif
 	return 0;
 }
-#endif /* LEGACY_SUPPORT */
 
-static int snd_cs4231_capture_hw_params(snd_pcm_substream_t * substream,
-					snd_pcm_hw_params_t * hw_params)
+static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	unsigned char new_cdfr;
 	int err;
 
@@ -913,16 +879,15 @@
 	return 0;
 }
 
-static int snd_cs4231_capture_hw_free(snd_pcm_substream_t * substream)
+static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-#ifdef LEGACY_SUPPORT
-static int snd_cs4231_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -942,9 +907,8 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 	return 0;
 }
-#endif
 
-static void snd_cs4231_overrange(cs4231_t *chip)
+static void snd_cs4231_overrange(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 	unsigned char res;
@@ -958,7 +922,7 @@
 
 irqreturn_t snd_cs4231_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	cs4231_t *chip = dev_id;
+	struct snd_cs4231 *chip = dev_id;
 	unsigned char status;
 
 	status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
@@ -998,10 +962,9 @@
 	return IRQ_HANDLED;
 }
 
-#ifdef LEGACY_SUPPORT
-static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
@@ -1010,9 +973,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	
 	if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
@@ -1020,13 +983,12 @@
 	ptr = snd_dma_pointer(chip->dma2, chip->c_dma_size);
 	return bytes_to_frames(substream->runtime, ptr);
 }
-#endif /* LEGACY_SUPPORT */
 
 /*
 
  */
 
-static int snd_cs4231_probe(cs4231_t *chip)
+static int snd_cs4231_probe(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 	int i, id, rev;
@@ -1190,7 +1152,7 @@
 
  */
 
-static snd_pcm_hardware_t snd_cs4231_playback =
+static struct snd_pcm_hardware snd_cs4231_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID |
@@ -1211,7 +1173,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_cs4231_capture =
+static struct snd_pcm_hardware snd_cs4231_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID |
@@ -1236,10 +1198,10 @@
 
  */
 
-static int snd_cs4231_playback_open(snd_pcm_substream_t * substream)
+static int snd_cs4231_playback_open(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	runtime->hw = snd_cs4231_playback;
@@ -1253,7 +1215,6 @@
 	    chip->hardware == CS4231_HW_CS4239)
 		runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
 
-#ifdef LEGACY_SUPPORT
 	snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.buffer_bytes_max);
 	snd_pcm_limit_isa_dma_size(chip->dma1, &runtime->hw.period_bytes_max);
 
@@ -1261,29 +1222,23 @@
 		if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma1)) < 0)
 			return err;
 	}
-#endif
 
 	if ((err = snd_cs4231_open(chip, CS4231_MODE_PLAY)) < 0) {
-#ifdef LEGACY_SUPPORT
 		if (chip->release_dma)
 			chip->release_dma(chip, chip->dma_private_data, chip->dma1);
-#endif
 		snd_free_pages(runtime->dma_area, runtime->dma_bytes);
 		return err;
 	}
 	chip->playback_substream = substream;
-#if defined(SBUS_SUPPORT) || defined(EBUS_SUPPORT)
-	chip->p_periods_sent = 0;
-#endif
 	snd_pcm_set_sync(substream);
 	chip->rate_constraint(runtime);
 	return 0;
 }
 
-static int snd_cs4231_capture_open(snd_pcm_substream_t * substream)
+static int snd_cs4231_capture_open(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	runtime->hw = snd_cs4231_capture;
@@ -1293,7 +1248,6 @@
 	    chip->hardware == CS4231_HW_CS4239)
 		runtime->hw.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE;
 
-#ifdef LEGACY_SUPPORT
 	snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.buffer_bytes_max);
 	snd_pcm_limit_isa_dma_size(chip->dma2, &runtime->hw.period_bytes_max);
 
@@ -1301,37 +1255,31 @@
 		if ((err = chip->claim_dma(chip, chip->dma_private_data, chip->dma2)) < 0)
 			return err;
 	}
-#endif
 
 	if ((err = snd_cs4231_open(chip, CS4231_MODE_RECORD)) < 0) {
-#ifdef LEGACY_SUPPORT
 		if (chip->release_dma)
 			chip->release_dma(chip, chip->dma_private_data, chip->dma2);
-#endif
 		snd_free_pages(runtime->dma_area, runtime->dma_bytes);
 		return err;
 	}
 	chip->capture_substream = substream;
-#if defined(SBUS_SUPPORT) || defined(EBUS_SUPPORT)
-	chip->c_periods_sent = 0;
-#endif
 	snd_pcm_set_sync(substream);
 	chip->rate_constraint(runtime);
 	return 0;
 }
 
-static int snd_cs4231_playback_close(snd_pcm_substream_t * substream)
+static int snd_cs4231_playback_close(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 
 	chip->playback_substream = NULL;
 	snd_cs4231_close(chip, CS4231_MODE_PLAY);
 	return 0;
 }
 
-static int snd_cs4231_capture_close(snd_pcm_substream_t * substream)
+static int snd_cs4231_capture_close(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 
 	chip->capture_substream = NULL;
 	snd_cs4231_close(chip, CS4231_MODE_RECORD);
@@ -1341,13 +1289,12 @@
 #ifdef CONFIG_PM
 
 /* lowlevel suspend callback for CS4231 */
-static void snd_cs4231_suspend(cs4231_t *chip)
+static void snd_cs4231_suspend(struct snd_cs4231 *chip)
 {
 	int reg;
 	unsigned long flags;
 	
-	if (chip->pcm)
-		snd_pcm_suspend_all(chip->pcm);
+	snd_pcm_suspend_all(chip->pcm);
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	for (reg = 0; reg < 32; reg++)
 		chip->image[reg] = snd_cs4231_in(chip, reg);
@@ -1355,11 +1302,11 @@
 }
 
 /* lowlevel resume callback for CS4231 */
-static void snd_cs4231_resume(cs4231_t *chip)
+static void snd_cs4231_resume(struct snd_cs4231 *chip)
 {
 	int reg;
 	unsigned long flags;
-	int timeout;
+	/* int timeout; */
 	
 	snd_cs4231_mce_up(chip);
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1373,7 +1320,7 @@
 		}
 	}
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
-#if 0
+#if 1
 	snd_cs4231_mce_down(chip);
 #else
 	/* The following is a workaround to avoid freeze after resume on TP600E.
@@ -1395,27 +1342,9 @@
 	snd_cs4231_busy_wait(chip);
 #endif
 }
-
-static int snd_cs4231_pm_suspend(snd_card_t *card, pm_message_t state)
-{
-	cs4231_t *chip = card->pm_private_data;
-	if (chip->suspend)
-		chip->suspend(chip);
-	return 0;
-}
-
-static int snd_cs4231_pm_resume(snd_card_t *card)
-{
-	cs4231_t *chip = card->pm_private_data;
-	if (chip->resume)
-		chip->resume(chip);
-	return 0;
-}
 #endif /* CONFIG_PM */
 
-#ifdef LEGACY_SUPPORT
-
-static int snd_cs4231_free(cs4231_t *chip)
+static int snd_cs4231_free(struct snd_cs4231 *chip)
 {
 	release_and_free_resource(chip->res_port);
 	release_and_free_resource(chip->res_cport);
@@ -1438,15 +1367,13 @@
 	return 0;
 }
 
-static int snd_cs4231_dev_free(snd_device_t *device)
+static int snd_cs4231_dev_free(struct snd_device *device)
 {
-	cs4231_t *chip = device->device_data;
+	struct snd_cs4231 *chip = device->device_data;
 	return snd_cs4231_free(chip);	
 }
 
-#endif /* LEGACY_SUPPORT */
-
-const char *snd_cs4231_chip_id(cs4231_t *chip)
+const char *snd_cs4231_chip_id(struct snd_cs4231 *chip)
 {
 	switch (chip->hardware) {
 	case CS4231_HW_CS4231:	return "CS4231";
@@ -1466,12 +1393,12 @@
 	}
 }
 
-static int snd_cs4231_new(snd_card_t * card,
+static int snd_cs4231_new(struct snd_card *card,
 			  unsigned short hardware,
 			  unsigned short hwshare,
-			  cs4231_t ** rchip)
+			  struct snd_cs4231 ** rchip)
 {
-	cs4231_t *chip;
+	struct snd_cs4231 *chip;
 
 	*rchip = NULL;
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -1493,20 +1420,18 @@
         return 0;
 }
 
-#ifdef LEGACY_SUPPORT
-
-int snd_cs4231_create(snd_card_t * card,
+int snd_cs4231_create(struct snd_card *card,
 	              unsigned long port,
 	              unsigned long cport,
 		      int irq, int dma1, int dma2,
 		      unsigned short hardware,
 		      unsigned short hwshare,
-		      cs4231_t ** rchip)
+		      struct snd_cs4231 ** rchip)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_cs4231_dev_free,
 	};
-	cs4231_t *chip;
+	struct snd_cs4231 *chip;
 	int err;
 
 	err = snd_cs4231_new(card, hardware, hwshare, &chip);
@@ -1559,10 +1484,12 @@
 	}
 	snd_cs4231_init(chip);
 
+#if 0
 	if (chip->hardware & CS4231_HW_CS4232_MASK) {
 		if (chip->res_cport == NULL)
 			snd_printk("CS4232 control port features are not accessible\n");
 	}
+#endif
 
 	/* Register device */
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
@@ -1574,16 +1501,13 @@
 	/* Power Management */
 	chip->suspend = snd_cs4231_suspend;
 	chip->resume = snd_cs4231_resume;
-	snd_card_set_isa_pm_callback(card, snd_cs4231_pm_suspend, snd_cs4231_pm_resume, chip);
 #endif
 
 	*rchip = chip;
 	return 0;
 }
 
-#endif /* LEGACY_SUPPORT */
-
-static snd_pcm_ops_t snd_cs4231_playback_ops = {
+static struct snd_pcm_ops snd_cs4231_playback_ops = {
 	.open =		snd_cs4231_playback_open,
 	.close =	snd_cs4231_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1594,7 +1518,7 @@
 	.pointer =	snd_cs4231_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_cs4231_capture_ops = {
+static struct snd_pcm_ops snd_cs4231_capture_ops = {
 	.open =		snd_cs4231_capture_open,
 	.close =	snd_cs4231_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1605,16 +1529,9 @@
 	.pointer =	snd_cs4231_capture_pointer,
 };
 
-static void snd_cs4231_pcm_free(snd_pcm_t *pcm)
+int snd_cs4231_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm)
 {
-	cs4231_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int snd_cs4231_pcm(cs4231_t *chip, int device, snd_pcm_t **rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(chip->card, "CS4231", device, 1, 1, &pcm)) < 0)
@@ -1629,7 +1546,6 @@
 	
 	/* global setup */
 	pcm->private_data = chip;
-	pcm->private_free = snd_cs4231_pcm_free;
 	pcm->info_flags = 0;
 	if (chip->single_dma)
 		pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX;
@@ -1637,27 +1553,9 @@
 		pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
 	strcpy(pcm->name, snd_cs4231_chip_id(chip));
 
-#ifdef LEGACY_SUPPORT
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 					      snd_dma_isa_data(),
 					      64*1024, chip->dma1 > 3 || chip->dma2 > 3 ? 128*1024 : 64*1024);
-#else
-#  ifdef EBUS_SUPPORT
-        if (chip->ebus_flag) {
-                snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-                				      chip->dev_u.pdev,
-						      64*1024, 128*1024);
-        } else {
-#  endif
-#  ifdef SBUS_SUPPORT
-                snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
-                				      chip->dev_u.sdev,
-						      64*1024, 128*1024);
-#  endif
-#  ifdef EBUS_SUPPORT
-        }
-#  endif
-#endif
 
 	chip->pcm = pcm;
 	if (rpcm)
@@ -1665,16 +1563,16 @@
 	return 0;
 }
 
-static void snd_cs4231_timer_free(snd_timer_t *timer)
+static void snd_cs4231_timer_free(struct snd_timer *timer)
 {
-	cs4231_t *chip = timer->private_data;
+	struct snd_cs4231 *chip = timer->private_data;
 	chip->timer = NULL;
 }
 
-int snd_cs4231_timer(cs4231_t *chip, int device, snd_timer_t **rtimer)
+int snd_cs4231_timer(struct snd_cs4231 *chip, int device, struct snd_timer **rtimer)
 {
-	snd_timer_t *timer;
-	snd_timer_id_t tid;
+	struct snd_timer *timer;
+	struct snd_timer_id tid;
 	int err;
 
 	/* Timer initialization */
@@ -1699,7 +1597,7 @@
  *  MIXER part
  */
 
-static int snd_cs4231_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = {
 		"Line", "Aux", "Mic", "Mix"
@@ -1711,7 +1609,7 @@
 		"Line", "Synth", "Mic", "Mix"
 	};
 	char **ptexts = texts;
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 
 	snd_assert(chip->card != NULL, return -EINVAL);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -1729,9 +1627,9 @@
 	return 0;
 }
 
-static int snd_cs4231_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1741,9 +1639,9 @@
 	return 0;
 }
 
-static int snd_cs4231_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned short left, right;
 	int change;
@@ -1764,7 +1662,7 @@
 	return change;
 }
 
-int snd_cs4231_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+int snd_cs4231_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -1775,9 +1673,9 @@
 	return 0;
 }
 
-int snd_cs4231_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_cs4231_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -1792,9 +1690,9 @@
 	return 0;
 }
 
-int snd_cs4231_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_cs4231_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -1815,7 +1713,7 @@
 	return change;
 }
 
-int snd_cs4231_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+int snd_cs4231_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -1826,9 +1724,9 @@
 	return 0;
 }
 
-int snd_cs4231_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_cs4231_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -1848,9 +1746,9 @@
 	return 0;
 }
 
-int snd_cs4231_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_cs4231_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -1879,7 +1777,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_cs4231_controls[] = {
+static struct snd_kcontrol_new snd_cs4231_controls[] = {
 CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
 CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
 CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
@@ -1905,9 +1803,9 @@
 CS4231_SINGLE("Loopback Capture Volume", 0, CS4231_LOOPBACK, 2, 63, 1)
 };
                                         
-int snd_cs4231_mixer(cs4231_t *chip)
+int snd_cs4231_mixer(struct snd_cs4231 *chip)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned int idx;
 	int err;
 
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index d60a55e..e168333 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -21,6 +21,8 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
@@ -122,7 +124,14 @@
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnpc_registered;
+#ifdef CS4232
+static int pnp_registered;
+#endif
+
 struct snd_card_cs4236 {
+	struct snd_cs4231 *chip;
 	struct resource *res_sb_port;
 #ifdef CONFIG_PNP
 	struct pnp_dev *wss;
@@ -131,33 +140,26 @@
 #endif
 };
 
-static snd_card_t *snd_cs4236_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
 #ifdef CONFIG_PNP
 
-#define ISAPNP_CS4232(_va, _vb, _vc, _device, _wss, _ctrl, _mpu401) \
-	{ \
-		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
-                          ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl), \
-			  ISAPNP_DEVICE_ID(_va, _vb, _vc, _mpu401) } \
-        }
-#define ISAPNP_CS4232_1(_va, _vb, _vc, _device, _wss, _ctrl, _mpu401) \
-	{ \
-		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
-                          ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl), \
-		 	  ISAPNP_DEVICE_ID('P', 'N', 'P', _mpu401) } \
-        }
-#define ISAPNP_CS4232_WOMPU(_va, _vb, _vc, _device, _wss, _ctrl) \
-	{ \
-		ISAPNP_CARD_ID(_va, _vb, _vc, _device), \
-		.devs = { ISAPNP_DEVICE_ID(_va, _vb, _vc, _wss), \
-                          ISAPNP_DEVICE_ID(_va, _vb, _vc, _ctrl) } \
-        }
-
+#ifdef CS4232
+/*
+ * PNP BIOS
+ */
+static const struct pnp_device_id snd_cs4232_pnpbiosids[] = {
+	{ .id = "CSC0100" },
+	{ .id = "CSC0000" },
+	/* Guillemot Turtlebeach something appears to be cs4232 compatible
+	 * (untested) */
+	{ .id = "GIM0100" },
+	{ .id = "" }
+};
+MODULE_DEVICE_TABLE(pnp, snd_cs4232_pnpbiosids);
+#endif /* CS4232 */
 
 #ifdef CS4232
+#define CS423X_DRIVER		"snd_cs4232"
+#define CS423X_ISAPNP_DRIVER	"cs4232_isapnp"
 static struct pnp_card_device_id snd_cs423x_pnpids[] = {
 	/* Philips PCA70PS */
 	{ .id = "CSC0d32", .devs = { { "CSC0000" }, { "CSC0010" }, { "PNPb006" } } },
@@ -177,6 +179,8 @@
 	{ .id = "" }	/* end */
 };
 #else /* CS4236 */
+#define CS423X_DRIVER		"snd_cs4236"
+#define CS423X_ISAPNP_DRIVER	"cs4236_isapnp"
 static struct pnp_card_device_id snd_cs423x_pnpids[] = {
 	/* Intel Marlin Spike Motherboard - CS4235 */
 	{ .id = "CSC0225", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
@@ -261,37 +265,12 @@
 
 MODULE_DEVICE_TABLE(pnp_card, snd_cs423x_pnpids);
 
-static int __devinit snd_card_cs4236_pnp(int dev, struct snd_card_cs4236 *acard,
-					 struct pnp_card_link *card,
-					 const struct pnp_card_device_id *id)
+/* WSS initialization */
+static int __devinit snd_cs423x_pnp_init_wss(int dev, struct pnp_dev *pdev,
+					     struct pnp_resource_table *cfg)
 {
-	struct pnp_dev *pdev;
-	struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
 	int err;
 
-	if (!cfg)
-		return -ENOMEM;
-
-	acard->wss = pnp_request_card_device(card, id->devs[0].id, NULL);
-	if (acard->wss == NULL) {
-		kfree(cfg);
-		return -EBUSY;
-	}
-	acard->ctrl = pnp_request_card_device(card, id->devs[1].id, NULL);
-	if (acard->ctrl == NULL) {
-		kfree(cfg);
-		return -EBUSY;
-	}
-	if (id->devs[2].id[0]) {
-		acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
-		if (acard->mpu == NULL) {
-			kfree(cfg);
-			return -EBUSY;
-		}
-	}
-
-	/* WSS initialization */
-	pdev = acard->wss;
 	pnp_init_resource_table(cfg);
 	if (port[dev] != SNDRV_AUTO_PORT)
 		pnp_resource_change(&cfg->port_resource[0], port[dev], 4);
@@ -310,7 +289,6 @@
 		snd_printk(KERN_ERR IDENT " WSS PnP manual resources are invalid, using auto config\n");
 	err = pnp_activate_dev(pdev);
 	if (err < 0) {
-		kfree(cfg);
 		printk(KERN_ERR IDENT " WSS PnP configure failed for WSS (out of resources?)\n");
 		return -EBUSY;
 	}
@@ -325,110 +303,163 @@
 			port[dev], fm_port[dev], sb_port[dev]);
 	snd_printdd("isapnp WSS: irq=%i, dma1=%i, dma2=%i\n",
 			irq[dev], dma1[dev], dma2[dev]);
+	return 0;
+}
+
+/* CTRL initialization */
+static int __devinit snd_cs423x_pnp_init_ctrl(int dev, struct pnp_dev *pdev,
+					      struct pnp_resource_table *cfg)
+{
+	int err;
+
+	pnp_init_resource_table(cfg);
+	if (cport[dev] != SNDRV_AUTO_PORT)
+		pnp_resource_change(&cfg->port_resource[0], cport[dev], 8);
+	err = pnp_manual_config_dev(pdev, cfg, 0);
+	if (err < 0)
+		snd_printk(KERN_ERR IDENT " CTRL PnP manual resources are invalid, using auto config\n");
+	err = pnp_activate_dev(pdev);
+	if (err < 0) {
+		printk(KERN_ERR IDENT " CTRL PnP configure failed for WSS (out of resources?)\n");
+		return -EBUSY;
+	}
+	cport[dev] = pnp_port_start(pdev, 0);
+	snd_printdd("isapnp CTRL: control port=0x%lx\n", cport[dev]);
+	return 0;
+}
+
+/* MPU initialization */
+static int __devinit snd_cs423x_pnp_init_mpu(int dev, struct pnp_dev *pdev,
+					     struct pnp_resource_table *cfg)
+{
+	int err;
+
+	pnp_init_resource_table(cfg);
+	if (mpu_port[dev] != SNDRV_AUTO_PORT)
+		pnp_resource_change(&cfg->port_resource[0], mpu_port[dev], 2);
+	if (mpu_irq[dev] != SNDRV_AUTO_IRQ && mpu_irq[dev] >= 0)
+		pnp_resource_change(&cfg->irq_resource[0], mpu_irq[dev], 1);
+	err = pnp_manual_config_dev(pdev, cfg, 0);
+	if (err < 0)
+		snd_printk(KERN_ERR IDENT " MPU401 PnP manual resources are invalid, using auto config\n");
+	err = pnp_activate_dev(pdev);
+	if (err < 0) {
+		printk(KERN_ERR IDENT " MPU401 PnP configure failed for WSS (out of resources?)\n");
+		mpu_port[dev] = SNDRV_AUTO_PORT;
+		mpu_irq[dev] = SNDRV_AUTO_IRQ;
+	} else {
+		mpu_port[dev] = pnp_port_start(pdev, 0);
+		if (mpu_irq[dev] >= 0 &&
+		    pnp_irq_valid(pdev, 0) && pnp_irq(pdev, 0) >= 0) {
+			mpu_irq[dev] = pnp_irq(pdev, 0);
+		} else {
+			mpu_irq[dev] = -1;	/* disable interrupt */
+		}
+	}
+	snd_printdd("isapnp MPU: port=0x%lx, irq=%i\n", mpu_port[dev], mpu_irq[dev]);
+	return 0;
+}
+
+#ifdef CS4232
+static int __devinit snd_card_cs4232_pnp(int dev, struct snd_card_cs4236 *acard,
+					 struct pnp_dev *pdev)
+{
+	struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
+
+	if (!cfg)
+		return -ENOMEM;
+	if (snd_cs423x_pnp_init_wss(dev, acard->wss, cfg) < 0) {
+		kfree(cfg);
+		return -EBUSY;
+	}
+	kfree(cfg);
+	cport[dev] = -1;
+	return 0;
+}
+#endif
+
+static int __devinit snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard,
+					  struct pnp_card_link *card,
+					  const struct pnp_card_device_id *id)
+{
+	struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
+
+	if (!cfg)
+		return -ENOMEM;
+
+	acard->wss = pnp_request_card_device(card, id->devs[0].id, NULL);
+	if (acard->wss == NULL)
+		goto error;
+	acard->ctrl = pnp_request_card_device(card, id->devs[1].id, NULL);
+	if (acard->ctrl == NULL)
+		goto error;
+	if (id->devs[2].id[0]) {
+		acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
+		if (acard->mpu == NULL)
+			goto error;
+	}
+
+	/* WSS initialization */
+	if (snd_cs423x_pnp_init_wss(dev, acard->wss, cfg) < 0)
+		goto error;
+
 	/* CTRL initialization */
 	if (acard->ctrl && cport[dev] > 0) {
-		pdev = acard->ctrl;
-		pnp_init_resource_table(cfg);
-		if (cport[dev] != SNDRV_AUTO_PORT)
-			pnp_resource_change(&cfg->port_resource[0], cport[dev], 8);
-		err = pnp_manual_config_dev(pdev, cfg, 0);
-		if (err < 0)
-			snd_printk(KERN_ERR IDENT " CTRL PnP manual resources are invalid, using auto config\n");
-		err = pnp_activate_dev(pdev);
-		if (err < 0) {
-			kfree(cfg);
-			printk(KERN_ERR IDENT " CTRL PnP configure failed for WSS (out of resources?)\n");
-			return -EBUSY;
-		}
-		cport[dev] = pnp_port_start(pdev, 0);
-		snd_printdd("isapnp CTRL: control port=0x%lx\n", cport[dev]);
+		if (snd_cs423x_pnp_init_ctrl(dev, acard->ctrl, cfg) < 0)
+			goto error;
 	}
 	/* MPU initialization */
 	if (acard->mpu && mpu_port[dev] > 0) {
-		pdev = acard->mpu;
-		pnp_init_resource_table(cfg);
-		if (mpu_port[dev] != SNDRV_AUTO_PORT)
-			pnp_resource_change(&cfg->port_resource[0], mpu_port[dev], 2);
-		if (mpu_irq[dev] != SNDRV_AUTO_IRQ && mpu_irq[dev] >= 0)
-			pnp_resource_change(&cfg->irq_resource[0], mpu_irq[dev], 1);
-		err = pnp_manual_config_dev(pdev, cfg, 0);
-		if (err < 0)
-			snd_printk(KERN_ERR IDENT " MPU401 PnP manual resources are invalid, using auto config\n");
-		err = pnp_activate_dev(pdev);
-		if (err < 0) {
-			printk(KERN_ERR IDENT " MPU401 PnP configure failed for WSS (out of resources?)\n");
-			mpu_port[dev] = SNDRV_AUTO_PORT;
-			mpu_irq[dev] = SNDRV_AUTO_IRQ;
-		} else {
-			mpu_port[dev] = pnp_port_start(pdev, 0);
-			if (mpu_irq[dev] >= 0 &&
-			    pnp_irq_valid(pdev, 0) && pnp_irq(pdev, 0) >= 0) {
-				mpu_irq[dev] = pnp_irq(pdev, 0);
-			} else {
-				mpu_irq[dev] = -1;	/* disable interrupt */
-			}
-		}
-		snd_printdd("isapnp MPU: port=0x%lx, irq=%i\n", mpu_port[dev], mpu_irq[dev]);
+		if (snd_cs423x_pnp_init_mpu(dev, acard->ctrl, cfg) < 0)
+			goto error;
 	}
 	kfree(cfg);
 	return 0;
+
+ error:
+	kfree(cfg);
+	return -EBUSY;
 }
 #endif /* CONFIG_PNP */
 
-static void snd_card_cs4236_free(snd_card_t *card)
-{
-	struct snd_card_cs4236 *acard = (struct snd_card_cs4236 *)card->private_data;
-
-	if (acard)
-		release_and_free_resource(acard->res_sb_port);
-}
-
 #ifdef CONFIG_PNP
 #define is_isapnp_selected(dev)		isapnp[dev]
 #else
 #define is_isapnp_selected(dev)		0
 #endif
 
-static int __devinit snd_card_cs423x_probe(int dev, struct pnp_card_link *pcard,
-					   const struct pnp_card_device_id *pid)
+static void snd_card_cs4236_free(struct snd_card *card)
 {
-	snd_card_t *card;
-	struct snd_card_cs4236 *acard;
-	snd_pcm_t *pcm = NULL;
-	cs4231_t *chip;
-	opl3_t *opl3;
-	int err;
+	struct snd_card_cs4236 *acard = card->private_data;
 
-	if (! is_isapnp_selected(dev)) {
-		if (port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR "specify port\n");
-			return -EINVAL;
-		}
-		if (cport[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR "specify cport\n");
-			return -EINVAL;
-		}
-	}
+	release_and_free_resource(acard->res_sb_port);
+}
+
+static struct snd_card *snd_cs423x_card_new(int dev)
+{
+	struct snd_card *card;
+
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(struct snd_card_cs4236));
 	if (card == NULL)
-		return -ENOMEM;
-	acard = (struct snd_card_cs4236 *)card->private_data;
+		return NULL;
 	card->private_free = snd_card_cs4236_free;
-#ifdef CONFIG_PNP
-	if (isapnp[dev]) {
-		if ((err = snd_card_cs4236_pnp(dev, acard, pcard, pid))<0) {
-			printk(KERN_ERR "isapnp detection failed and probing for " IDENT " is not supported\n");
-			goto _err;
-		}
-		snd_card_set_dev(card, &pcard->card->dev);
-	}
-#endif
+	return card;
+}
+
+static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
+{
+	struct snd_card_cs4236 *acard;
+	struct snd_pcm *pcm;
+	struct snd_cs4231 *chip;
+	struct snd_opl3 *opl3;
+	int err;
+
+	acard = card->private_data;
 	if (sb_port[dev] > 0 && sb_port[dev] != SNDRV_AUTO_PORT)
 		if ((acard->res_sb_port = request_region(sb_port[dev], 16, IDENT " SB")) == NULL) {
 			printk(KERN_ERR IDENT ": unable to register SB port at 0x%lx\n", sb_port[dev]);
-			err = -EBUSY;
-			goto _err;
+			return -EBUSY;
 		}
 
 #ifdef CS4232
@@ -441,13 +472,14 @@
 				     CS4231_HW_DETECT,
 				     0,
 				     &chip)) < 0)
-		goto _err;
+		return err;
+	acard->chip = chip;
 
 	if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0)
-		goto _err;
+		return err;
 
 	if ((err = snd_cs4231_mixer(chip)) < 0)
-		goto _err;
+		return err;
 
 #else /* CS4236 */
 	if ((err = snd_cs4236_create(card,
@@ -459,13 +491,14 @@
 				     CS4231_HW_DETECT,
 				     0,
 				     &chip)) < 0)
-		goto _err;
+		return err;
+	acard->chip = chip;
 
 	if ((err = snd_cs4236_pcm(chip, 0, &pcm)) < 0)
-		goto _err;
+		return err;
 
 	if ((err = snd_cs4236_mixer(chip)) < 0)
-		goto _err;
+		return err;
 #endif
 	strcpy(card->driver, pcm->name);
 	strcpy(card->shortname, pcm->name);
@@ -478,7 +511,7 @@
 		sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
 
 	if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0)
-		goto _err;
+		return err;
 
 	if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
 		if (snd_opl3_create(card,
@@ -487,7 +520,7 @@
 			printk(KERN_WARNING IDENT ": OPL3 not detected\n");
 		} else {
 			if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
-				goto _err;
+				return err;
 		}
 	}
 
@@ -501,95 +534,279 @@
 			printk(KERN_WARNING IDENT ": MPU401 not detected\n");
 	}
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
-
-	if ((err = snd_card_register(card)) < 0)
-		goto _err;
-	if (pcard)
-		pnp_set_card_drvdata(pcard, card);
-	else
-		snd_cs4236_legacy[dev] = card;
-	return 0;
-
- _err:
-	snd_card_free(card);
-	return err;
+	return snd_card_register(card);
 }
 
+static int __init snd_cs423x_nonpnp_probe(struct platform_device *pdev)
+{
+	int dev = pdev->id;
+	struct snd_card *card;
+	int err;
+
+	if (port[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR "specify port\n");
+		return -EINVAL;
+	}
+	if (cport[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR "specify cport\n");
+		return -EINVAL;
+	}
+
+	card = snd_cs423x_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	snd_card_set_dev(card, &pdev->dev);
+	if ((err = snd_cs423x_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	
+	platform_set_drvdata(pdev, card);
+	return 0;
+}
+
+static int __devexit snd_cs423x_nonpnp_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_cs423x_suspend(struct snd_card *card)
+{
+	struct snd_card_cs4236 *acard = card->private_data;
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	acard->chip->suspend(acard->chip);
+	return 0;
+}
+
+static int snd_cs423x_resume(struct snd_card *card)
+{
+	struct snd_card_cs4236 *acard = card->private_data;
+	acard->chip->resume(acard->chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+
+static int snd_cs423x_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+{
+	return snd_cs423x_suspend(platform_get_drvdata(dev));
+}
+
+static int snd_cs423x_nonpnp_resume(struct platform_device *dev)
+{
+	return snd_cs423x_resume(platform_get_drvdata(dev));
+}
+#endif
+
+static struct platform_driver cs423x_nonpnp_driver = {
+	.probe		= snd_cs423x_nonpnp_probe,
+	.remove		= __devexit_p(snd_cs423x_nonpnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_cs423x_nonpnp_suspend,
+	.resume		= snd_cs423x_nonpnp_resume,
+#endif
+	.driver		= {
+		.name	= CS423X_DRIVER
+	},
+};
+
+
 #ifdef CONFIG_PNP
-static int __devinit snd_cs423x_pnp_detect(struct pnp_card_link *card,
-					   const struct pnp_card_device_id *id)
+#ifdef CS4232
+static int __devinit snd_cs4232_pnpbios_detect(struct pnp_dev *pdev,
+					       const struct pnp_device_id *id)
 {
 	static int dev;
+	int err;
+	struct snd_card *card;
+
+	if (pnp_device_is_isapnp(pdev))
+		return -ENOENT;	/* we have another procedure - card */
+	for (; dev < SNDRV_CARDS; dev++) {
+		if (enable[dev] && isapnp[dev])
+			break;
+	}
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+
+	card = snd_cs423x_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	if ((err = snd_card_cs4232_pnp(dev, card->private_data, pdev)) < 0) {
+		printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n");
+		snd_card_free(card);
+		return err;
+	}
+	snd_card_set_dev(card, &pdev->dev);
+	if ((err = snd_cs423x_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	pnp_set_drvdata(pdev, card);
+	dev++;
+	return 0;
+}
+
+static void __devexit snd_cs4232_pnp_remove(struct pnp_dev * pdev)
+{
+	snd_card_free(pnp_get_drvdata(pdev));
+	pnp_set_drvdata(pdev, NULL);
+}
+
+#ifdef CONFIG_PM
+static int snd_cs4232_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
+{
+	return snd_cs423x_suspend(pnp_get_drvdata(pdev));
+}
+
+static int snd_cs4232_pnp_resume(struct pnp_dev *pdev)
+{
+	return snd_cs423x_resume(pnp_get_drvdata(pdev));
+}
+#endif
+
+static struct pnp_driver cs4232_pnp_driver = {
+	.name = "cs4232-pnpbios",
+	.id_table = snd_cs4232_pnpbiosids,
+	.probe = snd_cs4232_pnpbios_detect,
+	.remove = __devexit_p(snd_cs4232_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_cs4232_pnp_suspend,
+	.resume		= snd_cs4232_pnp_resume,
+#endif
+};
+#endif /* CS4232 */
+
+static int __devinit snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
+					    const struct pnp_card_device_id *pid)
+{
+	static int dev;
+	struct snd_card *card;
 	int res;
 
 	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || !isapnp[dev])
-			continue;
-		res = snd_card_cs423x_probe(dev, card, id);
-		if (res < 0)
-			return res;
-		dev++;
-		return 0;
+		if (enable[dev] && isapnp[dev])
+			break;
 	}
-	return -ENODEV;
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+
+	card = snd_cs423x_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	if ((res = snd_card_cs423x_pnpc(dev, card->private_data, pcard, pid)) < 0) {
+		printk(KERN_ERR "isapnp detection failed and probing for " IDENT
+		       " is not supported\n");
+		snd_card_free(card);
+		return res;
+	}
+	snd_card_set_dev(card, &pcard->card->dev);
+	if ((res = snd_cs423x_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return res;
+	}
+	pnp_set_card_drvdata(pcard, card);
+	dev++;
+	return 0;
 }
 
-static void __devexit snd_cs423x_pnp_remove(struct pnp_card_link * pcard)
+static void __devexit snd_cs423x_pnpc_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-        
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
                         
+#ifdef CONFIG_PM
+static int snd_cs423x_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	return snd_cs423x_suspend(pnp_get_card_drvdata(pcard));
+}
+
+static int snd_cs423x_pnpc_resume(struct pnp_card_link *pcard)
+{
+	return snd_cs423x_resume(pnp_get_card_drvdata(pcard));
+}
+#endif
+
 static struct pnp_card_driver cs423x_pnpc_driver = {
 	.flags = PNP_DRIVER_RES_DISABLE,
-	.name = "cs423x",
+	.name = CS423X_ISAPNP_DRIVER,
 	.id_table = snd_cs423x_pnpids,
-	.probe = snd_cs423x_pnp_detect,
-	.remove = __devexit_p(snd_cs423x_pnp_remove),
+	.probe = snd_cs423x_pnpc_detect,
+	.remove = __devexit_p(snd_cs423x_pnpc_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_cs423x_pnpc_suspend,
+	.resume		= snd_cs423x_pnpc_resume,
+#endif
 };
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_cs423x_unregister_all(void)
+{
+	int i;
+
+	if (pnpc_registered)
+		pnp_unregister_card_driver(&cs423x_pnpc_driver);
+#ifdef CS4232
+	if (pnp_registered)
+		pnp_unregister_driver(&cs4232_pnp_driver);
+#endif
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&cs423x_nonpnp_driver);
+}
+
 static int __init alsa_card_cs423x_init(void)
 {
-	int dev, cards = 0;
+	int i, err, cards = 0;
 
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev])
+	if ((err = platform_driver_register(&cs423x_nonpnp_driver)) < 0)
+		return err;
+
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		if (is_isapnp_selected(i))
 			continue;
-		if (is_isapnp_selected(dev))
-			continue;
-		if (snd_card_cs423x_probe(dev, NULL, NULL) >= 0)
-			cards++;
+		device = platform_device_register_simple(CS423X_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		platform_devices[i] = device;
+		cards++;
 	}
-#ifdef CONFIG_PNP
-	cards += pnp_register_card_driver(&cs423x_pnpc_driver);
+#ifdef CS4232
+	i = pnp_register_driver(&cs4232_pnp_driver);
+	if (i >= 0) {
+		pnp_registered = 1;
+		cards += i;
+	}
 #endif
+	i = pnp_register_card_driver(&cs423x_pnpc_driver);
+	if (i >= 0) {
+		pnpc_registered = 1;
+		cards += i;
+	}
 	if (!cards) {
-#ifdef CONFIG_PNP
-		pnp_unregister_card_driver(&cs423x_pnpc_driver);
-#endif
 #ifdef MODULE
 		printk(KERN_ERR IDENT " soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_cs423x_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_cs423x_exit(void)
 {
-	int idx;
-
-#ifdef CONFIG_PNP
-	/* PnP cards first */
-	pnp_unregister_card_driver(&cs423x_pnpc_driver);
-#endif
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_cs4236_legacy[idx]);
+	snd_cs423x_unregister_all();
 }
 
 module_init(alsa_card_cs423x_init)
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index 1adb88d..e36981d 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -122,13 +122,13 @@
  *
  */
 
-static void snd_cs4236_ctrl_out(cs4231_t *chip, unsigned char reg, unsigned char val)
+static void snd_cs4236_ctrl_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char val)
 {
 	outb(reg, chip->cport + 3);
 	outb(chip->cimage[reg] = val, chip->cport + 4);
 }
 
-static unsigned char snd_cs4236_ctrl_in(cs4231_t *chip, unsigned char reg)
+static unsigned char snd_cs4236_ctrl_in(struct snd_cs4231 *chip, unsigned char reg)
 {
 	outb(reg, chip->cport + 3);
 	return inb(chip->cport + 4);
@@ -140,7 +140,7 @@
 
 #define CLOCKS 8
 
-static ratnum_t clocks[CLOCKS] = {
+static struct snd_ratnum clocks[CLOCKS] = {
 	{ .num = 16934400, .den_min = 353, .den_max = 353, .den_step = 1 },
 	{ .num = 16934400, .den_min = 529, .den_max = 529, .den_step = 1 },
 	{ .num = 16934400, .den_min = 617, .den_max = 617, .den_step = 1 },
@@ -151,12 +151,12 @@
 	{ .num = 16934400/16, .den_min = 21, .den_max = 192, .den_step = 1 }
 };
 
-static snd_pcm_hw_constraint_ratnums_t hw_constraints_clocks = {
+static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = {
 	.nrats = CLOCKS,
 	.rats = clocks,
 };
 
-static int snd_cs4236_xrate(snd_pcm_runtime_t *runtime)
+static int snd_cs4236_xrate(struct snd_pcm_runtime *runtime)
 {
 	return snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
 					     &hw_constraints_clocks);
@@ -181,7 +181,7 @@
 	}
 }
 
-static void snd_cs4236_playback_format(cs4231_t *chip, snd_pcm_hw_params_t *params, unsigned char pdfr)
+static void snd_cs4236_playback_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, unsigned char pdfr)
 {
 	unsigned long flags;
 	unsigned char rate = divisor_to_rate_register(params->rate_den);
@@ -195,7 +195,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static void snd_cs4236_capture_format(cs4231_t *chip, snd_pcm_hw_params_t *params, unsigned char cdfr)
+static void snd_cs4236_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params, unsigned char cdfr)
 {
 	unsigned long flags;
 	unsigned char rate = divisor_to_rate_register(params->rate_den);
@@ -211,7 +211,7 @@
 
 #ifdef CONFIG_PM
 
-static void snd_cs4236_suspend(cs4231_t *chip)
+static void snd_cs4236_suspend(struct snd_cs4231 *chip)
 {
 	int reg;
 	unsigned long flags;
@@ -226,7 +226,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static void snd_cs4236_resume(cs4231_t *chip)
+static void snd_cs4236_resume(struct snd_cs4231 *chip)
 {
 	int reg;
 	unsigned long flags;
@@ -261,15 +261,15 @@
 
 #endif /* CONFIG_PM */
 
-int snd_cs4236_create(snd_card_t * card,
+int snd_cs4236_create(struct snd_card *card,
 		      unsigned long port,
 		      unsigned long cport,
 		      int irq, int dma1, int dma2,
 		      unsigned short hardware,
 		      unsigned short hwshare,
-		      cs4231_t ** rchip)
+		      struct snd_cs4231 ** rchip)
 {
-	cs4231_t *chip;
+	struct snd_cs4231 *chip;
 	unsigned char ver1, ver2;
 	unsigned int reg;
 	int err;
@@ -352,9 +352,9 @@
 	return 0;
 }
 
-int snd_cs4236_pcm(cs4231_t *chip, int device, snd_pcm_t **rpcm)
+int snd_cs4236_pcm(struct snd_cs4231 *chip, int device, struct snd_pcm **rpcm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 	
 	if ((err = snd_cs4231_pcm(chip, device, &pcm)) < 0)
@@ -375,7 +375,7 @@
   .get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_cs4236_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -386,9 +386,9 @@
 	return 0;
 }
 
-static int snd_cs4236_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -403,9 +403,9 @@
 	return 0;
 }
 
-static int snd_cs4236_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -432,9 +432,9 @@
   .get = snd_cs4236_get_singlec, .put = snd_cs4236_put_singlec, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_cs4236_get_singlec(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_get_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -449,9 +449,9 @@
 	return 0;
 }
 
-static int snd_cs4236_put_singlec(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -478,7 +478,7 @@
   .get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-static int snd_cs4236_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -489,9 +489,9 @@
 	return 0;
 }
 
-static int snd_cs4236_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -511,9 +511,9 @@
 	return 0;
 }
 
-static int snd_cs4236_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -554,9 +554,9 @@
   .get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-static int snd_cs4236_get_double1(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -576,9 +576,9 @@
 	return 0;
 }
 
-static int snd_cs4236_put_double1(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -618,9 +618,9 @@
 	return (vol < 64) ? 63 - vol : 64 + (71 - vol);
 }        
 
-static int snd_cs4236_get_master_digital(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -630,9 +630,9 @@
 	return 0;
 }
 
-static int snd_cs4236_put_master_digital(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned short val1, val2;
@@ -677,9 +677,9 @@
 	return 1 << 5;
 }
 
-static int snd_cs4235_get_output_accu(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4235_get_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -689,9 +689,9 @@
 	return 0;
 }
 
-static int snd_cs4235_put_output_accu(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned short val1, val2;
@@ -708,7 +708,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_cs4236_controls[] = {
+static struct snd_kcontrol_new snd_cs4236_controls[] = {
 
 CS4236_DOUBLE("Master Digital Playback Switch", 0, CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
 CS4236_DOUBLE("Master Digital Capture Switch", 0, CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
@@ -759,7 +759,7 @@
 CS4236_DOUBLE1("Digital Loopback Playback Volume", 0, CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1)
 };
 
-static snd_kcontrol_new_t snd_cs4235_controls[] = {
+static struct snd_kcontrol_new snd_cs4235_controls[] = {
 
 CS4231_DOUBLE("Master Switch", 0, CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1),
 CS4231_DOUBLE("Master Volume", 0, CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1),
@@ -812,9 +812,9 @@
   .get = snd_cs4236_get_iec958_switch, .put = snd_cs4236_put_iec958_switch, \
   .private_value = 1 << 16 }
 
-static int snd_cs4236_get_iec958_switch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_get_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -832,9 +832,9 @@
 	return 0;
 }
 
-static int snd_cs4236_put_iec958_switch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4236_put_iec958_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned short enable, val;
@@ -868,7 +868,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_cs4236_iec958_controls[] = {
+static struct snd_kcontrol_new snd_cs4236_iec958_controls[] = {
 CS4236_IEC958_ENABLE("IEC958 Output Enable", 0),
 CS4236_SINGLEC("IEC958 Output Validity", 0, 4, 4, 1, 0),
 CS4236_SINGLEC("IEC958 Output User", 0, 4, 5, 1, 0),
@@ -877,12 +877,12 @@
 CS4236_SINGLEC("IEC958 Output Channel Status High", 0, 6, 0, 255, 0)
 };
 
-static snd_kcontrol_new_t snd_cs4236_3d_controls_cs4235[] = {
+static struct snd_kcontrol_new snd_cs4236_3d_controls_cs4235[] = {
 CS4236_SINGLEC("3D Control - Switch", 0, 3, 4, 1, 0),
 CS4236_SINGLEC("3D Control - Space", 0, 2, 4, 15, 1)
 };
 
-static snd_kcontrol_new_t snd_cs4236_3d_controls_cs4237[] = {
+static struct snd_kcontrol_new snd_cs4236_3d_controls_cs4237[] = {
 CS4236_SINGLEC("3D Control - Switch", 0, 3, 7, 1, 0),
 CS4236_SINGLEC("3D Control - Space", 0, 2, 4, 15, 1),
 CS4236_SINGLEC("3D Control - Center", 0, 2, 0, 15, 1),
@@ -890,19 +890,19 @@
 CS4236_SINGLEC("3D Control - IEC958", 0, 3, 5, 1, 0)
 };
 
-static snd_kcontrol_new_t snd_cs4236_3d_controls_cs4238[] = {
+static struct snd_kcontrol_new snd_cs4236_3d_controls_cs4238[] = {
 CS4236_SINGLEC("3D Control - Switch", 0, 3, 4, 1, 0),
 CS4236_SINGLEC("3D Control - Space", 0, 2, 4, 15, 1),
 CS4236_SINGLEC("3D Control - Volume", 0, 2, 0, 15, 1),
 CS4236_SINGLEC("3D Control - IEC958", 0, 3, 5, 1, 0)
 };
 
-int snd_cs4236_mixer(cs4231_t *chip)
+int snd_cs4236_mixer(struct snd_cs4231 *chip)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned int idx, count;
 	int err;
-	snd_kcontrol_new_t *kcontrol;
+	struct snd_kcontrol_new *kcontrol;
 
 	snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
 	card = chip->card;
diff --git a/sound/isa/dt019x.c b/sound/isa/dt019x.c
index db7c339..50e7bc5 100644
--- a/sound/isa/dt019x.c
+++ b/sound/isa/dt019x.c
@@ -74,6 +74,7 @@
 	struct pnp_dev *dev;
 	struct pnp_dev *devmpu;
 	struct pnp_dev *devopl;
+	struct snd_sb *chip;
 };
 
 static struct pnp_card_device_id snd_dt019x_pnpids[] = {
@@ -188,15 +189,15 @@
 static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, const struct pnp_card_device_id *pid)
 {
 	int error;
-	sb_t *chip;
-	snd_card_t *card;
+	struct snd_sb *chip;
+	struct snd_card *card;
 	struct snd_card_dt019x *acard;
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 
 	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 				 sizeof(struct snd_card_dt019x))) == NULL)
 		return -ENOMEM;
-	acard = (struct snd_card_dt019x *)card->private_data;
+	acard = card->private_data;
 
 	snd_card_set_dev(card, &pcard->card->dev);
 	if ((error = snd_card_dt019x_pnp(dev, acard, pcard, pid))) {
@@ -214,6 +215,7 @@
 		snd_card_free(card);
 		return error;
 	}
+	acard->chip = chip;
 
 	strcpy(card->driver, "DT-019X");
 	strcpy(card->shortname, "Diamond Tech. DT-019X");
@@ -290,32 +292,61 @@
 
 static void __devexit snd_dt019x_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_dt019x_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+	struct snd_card_dt019x *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(chip->pcm);
+	snd_sbmixer_suspend(chip);
+	return 0;
+}
+
+static int snd_dt019x_pnp_resume(struct pnp_card_link *pcard)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+	struct snd_card_dt019x *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_sbdsp_reset(chip);
+	snd_sbmixer_resume(chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
 static struct pnp_card_driver dt019x_pnpc_driver = {
 	.flags          = PNP_DRIVER_RES_DISABLE,
 	.name           = "dt019x",
 	.id_table       = snd_dt019x_pnpids,
 	.probe          = snd_dt019x_pnp_probe,
 	.remove         = __devexit_p(snd_dt019x_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_dt019x_pnp_suspend,
+	.resume		= snd_dt019x_pnp_resume,
+#endif
 };
 
 static int __init alsa_card_dt019x_init(void)
 {
 	int cards = 0;
 
-	cards += pnp_register_card_driver(&dt019x_pnpc_driver);
-
-#ifdef MODULE
-	if (!cards) {
+	cards = pnp_register_card_driver(&dt019x_pnpc_driver);
+	if (cards <= 0) {
 		pnp_unregister_card_driver(&dt019x_pnpc_driver);
+#ifdef MODULE
 		snd_printk(KERN_ERR "no DT-019X / ALS-007 based soundcards found\n");
-	}
 #endif
-	return cards ? 0 : -ENODEV;
+		return -ENODEV;
+	}
+	return 0;
 }
 
 static void __exit alsa_card_dt019x_exit(void)
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index 26a7d33..50d23cf 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -20,16 +20,17 @@
  */
 
 #include <sound/driver.h>
-#include <asm/dma.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/moduleparam.h>
+#include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/es1688.h>
 #include <sound/mpu401.h>
 #include <sound/opl3.h>
-#define SNDRV_LEGACY_AUTO_PROBE
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
@@ -68,19 +69,20 @@
 module_param_array(dma8, int, NULL, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for ESx688 driver.");
 
-static snd_card_t *snd_audiodrive_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct platform_device *devices[SNDRV_CARDS];
 
 #define PFX	"es1688: "
 
-static int __init snd_audiodrive_probe(int dev)
+static int __init snd_es1688_probe(struct platform_device *pdev)
 {
+	int dev = pdev->id;
 	static int possible_irqs[] = {5, 9, 10, 7, -1};
 	static int possible_dmas[] = {1, 3, 0, -1};
 	int xirq, xdma, xmpu_irq;
-	snd_card_t *card;
-	es1688_t *chip;
-	opl3_t *opl3;
-	snd_pcm_t *pcm;
+	struct snd_card *card;
+	struct snd_es1688 *chip;
+	struct snd_opl3 *opl3;
+	struct snd_pcm *pcm;
 	int err;
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
@@ -105,10 +107,30 @@
 		}
 	}
 
-	if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
-				     xirq, xmpu_irq, xdma,
-				     ES1688_HW_AUTO, &chip)) < 0)
-		goto _err;
+	if (port[dev] != SNDRV_AUTO_PORT) {
+		if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
+					     xirq, xmpu_irq, xdma,
+					     ES1688_HW_AUTO, &chip)) < 0)
+			goto _err;
+	} else {
+		/* auto-probe legacy ports */
+		static unsigned long possible_ports[] = {
+			0x220, 0x240, 0x260,
+		};
+		int i;
+		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
+			err = snd_es1688_create(card, possible_ports[i],
+						mpu_port[dev],
+						xirq, xmpu_irq, xdma,
+						ES1688_HW_AUTO, &chip);
+			if (err >= 0) {
+				port[dev] = possible_ports[i];
+				break;
+			}
+		}
+		if (i >= ARRAY_SIZE(possible_ports))
+			goto _err;
+	}
 
 	if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
 		goto _err;
@@ -136,13 +158,12 @@
 			goto _err;
 	}
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
+	snd_card_set_dev(card, &pdev->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
-	snd_audiodrive_cards[dev] = card;
+	platform_set_drvdata(pdev, card);
 	return 0;
 
  _err:
@@ -150,53 +171,70 @@
 	return err;
 }
 
-static int __init snd_audiodrive_legacy_auto_probe(unsigned long xport)
+static int snd_es1688_remove(struct platform_device *devptr)
 {
-	static int dev;
-	int res;
-	
-	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
-			continue;
-		port[dev] = xport;
-		res = snd_audiodrive_probe(dev);
-		if (res < 0)
-			port[dev] = SNDRV_AUTO_PORT;
-		return res;
-	}
-	return -ENODEV;
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#define ES1688_DRIVER	"snd_es1688"
+
+static struct platform_driver snd_es1688_driver = {
+	.probe		= snd_es1688_probe,
+	.remove		= snd_es1688_remove,
+	/* FIXME: suspend/resume */
+	.driver		= {
+		.name	= ES1688_DRIVER
+	},
+};
+
+static void __init_or_module snd_es1688_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_es1688_driver);
 }
 
 static int __init alsa_card_es1688_init(void)
 {
-	static unsigned long possible_ports[] = {0x220, 0x240, 0x260, -1};
-	int dev, cards = 0, i;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) {
-		if (port[dev] == SNDRV_AUTO_PORT)
-			continue;
-		if (snd_audiodrive_probe(dev) >= 0)
-			cards++;
+	err = platform_driver_register(&snd_es1688_driver);
+	if (err < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(ES1688_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		devices[i] = device;
+		cards++;
 	}
-	i = snd_legacy_auto_probe(possible_ports, snd_audiodrive_legacy_auto_probe);
-	if (i > 0)
-		cards += i;
-
 	if (!cards) {
 #ifdef MODULE
 		printk(KERN_ERR "ESS AudioDrive ES1688 soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_es1688_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_es1688_exit(void)
 {
-	int idx;
-
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_audiodrive_cards[idx]);
+	snd_es1688_unregister_all();
 }
 
 module_init(alsa_card_es1688_init)
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c
index 2edc9c9..702ad51 100644
--- a/sound/isa/es1688/es1688_lib.c
+++ b/sound/isa/es1688/es1688_lib.c
@@ -36,7 +36,7 @@
 MODULE_DESCRIPTION("ESS ESx688 lowlevel module");
 MODULE_LICENSE("GPL");
 
-static int snd_es1688_dsp_command(es1688_t *chip, unsigned char val)
+static int snd_es1688_dsp_command(struct snd_es1688 *chip, unsigned char val)
 {
 	int i;
 
@@ -51,7 +51,7 @@
 	return 0;
 }
 
-static int snd_es1688_dsp_get_byte(es1688_t *chip)
+static int snd_es1688_dsp_get_byte(struct snd_es1688 *chip)
 {
 	int i;
 
@@ -62,7 +62,7 @@
 	return -ENODEV;
 }
 
-static int snd_es1688_write(es1688_t *chip,
+static int snd_es1688_write(struct snd_es1688 *chip,
 			    unsigned char reg, unsigned char data)
 {
 	if (!snd_es1688_dsp_command(chip, reg))
@@ -70,7 +70,7 @@
 	return snd_es1688_dsp_command(chip, data);
 }
 
-static int snd_es1688_read(es1688_t *chip, unsigned char reg)
+static int snd_es1688_read(struct snd_es1688 *chip, unsigned char reg)
 {
 	/* Read a byte from an extended mode register of ES1688 */
 	if (!snd_es1688_dsp_command(chip, 0xc0))
@@ -80,7 +80,7 @@
 	return snd_es1688_dsp_get_byte(chip);
 }
 
-void snd_es1688_mixer_write(es1688_t *chip,
+void snd_es1688_mixer_write(struct snd_es1688 *chip,
 			    unsigned char reg, unsigned char data)
 {
 	outb(reg, ES1688P(chip, MIXER_ADDR));
@@ -89,7 +89,7 @@
 	udelay(10);
 }
 
-static unsigned char snd_es1688_mixer_read(es1688_t *chip, unsigned char reg)
+static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned char reg)
 {
 	unsigned char result;
 
@@ -100,7 +100,7 @@
 	return result;
 }
 
-static int snd_es1688_reset(es1688_t *chip)
+static int snd_es1688_reset(struct snd_es1688 *chip)
 {
 	int i;
 
@@ -117,7 +117,7 @@
 	return 0;
 }
 
-static int snd_es1688_probe(es1688_t *chip)
+static int snd_es1688_probe(struct snd_es1688 *chip)
 {
 	unsigned long flags;
 	unsigned short major, minor, hw;
@@ -191,7 +191,7 @@
 	return 0;
 }
 
-static int snd_es1688_init(es1688_t * chip, int enable)
+static int snd_es1688_init(struct snd_es1688 * chip, int enable)
 {
 	static int irqs[16] = {-1, -1, 0, -1, -1, 1, -1, 2, -1, 0, 3, -1, -1, -1, -1, -1};
 	unsigned long flags;
@@ -283,7 +283,7 @@
 
  */
 
-static ratnum_t clocks[2] = {
+static struct snd_ratnum clocks[2] = {
 	{
 		.num = 795444,
 		.den_min = 1,
@@ -298,14 +298,14 @@
 	}
 };
 
-static snd_pcm_hw_constraint_ratnums_t hw_constraints_clocks  = {
+static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks  = {
 	.nrats = 2,
 	.rats = clocks,
 };
 
-static void snd_es1688_set_rate(es1688_t *chip, snd_pcm_substream_t *substream)
+static void snd_es1688_set_rate(struct snd_es1688 *chip, struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int bits, divider;
 
 	if (runtime->rate_num == clocks[0].num)
@@ -319,13 +319,13 @@
 	snd_es1688_write(chip, 0xa2, divider);
 }
 
-static int snd_es1688_ioctl(snd_pcm_substream_t * substream,
+static int snd_es1688_ioctl(struct snd_pcm_substream *substream,
 			    unsigned int cmd, void *arg)
 {
 	return snd_pcm_lib_ioctl(substream, cmd, arg);
 }
 
-static int snd_es1688_trigger(es1688_t *chip, int cmd, unsigned char value)
+static int snd_es1688_trigger(struct snd_es1688 *chip, int cmd, unsigned char value)
 {
 	int val;
 
@@ -350,22 +350,22 @@
 	return 0;
 }
 
-static int snd_es1688_hw_params(snd_pcm_substream_t * substream,
-				snd_pcm_hw_params_t * hw_params)
+static int snd_es1688_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_es1688_hw_free(snd_pcm_substream_t * substream)
+static int snd_es1688_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_es1688_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_es1688_playback_prepare(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	es1688_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
 
@@ -415,18 +415,18 @@
 	return 0;
 }
 
-static int snd_es1688_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_es1688_playback_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	es1688_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
 	return snd_es1688_trigger(chip, cmd, 0x05);
 }
 
-static int snd_es1688_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_es1688_capture_prepare(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	es1688_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
 
@@ -472,16 +472,16 @@
 	return 0;
 }
 
-static int snd_es1688_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_es1688_capture_trigger(struct snd_pcm_substream *substream,
 				      int cmd)
 {
-	es1688_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
 	return snd_es1688_trigger(chip, cmd, 0x0f);
 }
 
 static irqreturn_t snd_es1688_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	es1688_t *chip = dev_id;
+	struct snd_es1688 *chip = dev_id;
 
 	if (chip->trigger_value == 0x05)	/* ok.. playback is active */
 		snd_pcm_period_elapsed(chip->playback_substream);
@@ -492,9 +492,9 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_uframes_t snd_es1688_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_es1688_playback_pointer(struct snd_pcm_substream *substream)
 {
-	es1688_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	
 	if (chip->trigger_value != 0x05)
@@ -503,9 +503,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_es1688_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_es1688_capture_pointer(struct snd_pcm_substream *substream)
 {
-	es1688_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	
 	if (chip->trigger_value != 0x0f)
@@ -518,7 +518,7 @@
 
  */
 
-static snd_pcm_hardware_t snd_es1688_playback =
+static struct snd_pcm_hardware snd_es1688_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -536,7 +536,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_es1688_capture =
+static struct snd_pcm_hardware snd_es1688_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -558,10 +558,10 @@
 
  */
 
-static int snd_es1688_playback_open(snd_pcm_substream_t * substream)
+static int snd_es1688_playback_open(struct snd_pcm_substream *substream)
 {
-	es1688_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (chip->capture_substream != NULL)
 		return -EAGAIN;
@@ -572,10 +572,10 @@
 	return 0;
 }
 
-static int snd_es1688_capture_open(snd_pcm_substream_t * substream)
+static int snd_es1688_capture_open(struct snd_pcm_substream *substream)
 {
-	es1688_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (chip->playback_substream != NULL)
 		return -EAGAIN;
@@ -586,23 +586,23 @@
 	return 0;
 }
 
-static int snd_es1688_playback_close(snd_pcm_substream_t * substream)
+static int snd_es1688_playback_close(struct snd_pcm_substream *substream)
 {
-	es1688_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
 
 	chip->playback_substream = NULL;
 	return 0;
 }
 
-static int snd_es1688_capture_close(snd_pcm_substream_t * substream)
+static int snd_es1688_capture_close(struct snd_pcm_substream *substream)
 {
-	es1688_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_es1688 *chip = snd_pcm_substream_chip(substream);
 
 	chip->capture_substream = NULL;
 	return 0;
 }
 
-static int snd_es1688_free(es1688_t *chip)
+static int snd_es1688_free(struct snd_es1688 *chip)
 {
 	if (chip->res_port) {
 		snd_es1688_init(chip, 0);
@@ -618,33 +618,33 @@
 	return 0;
 }
 
-static int snd_es1688_dev_free(snd_device_t *device)
+static int snd_es1688_dev_free(struct snd_device *device)
 {
-	es1688_t *chip = device->device_data;
+	struct snd_es1688 *chip = device->device_data;
 	return snd_es1688_free(chip);
 }
 
-static const char *snd_es1688_chip_id(es1688_t *chip)
+static const char *snd_es1688_chip_id(struct snd_es1688 *chip)
 {
 	static char tmp[16];
 	sprintf(tmp, "ES%s688 rev %i", chip->hardware == ES1688_HW_688 ? "" : "1", chip->version & 0x0f);
 	return tmp;
 }
 
-int snd_es1688_create(snd_card_t * card,
+int snd_es1688_create(struct snd_card *card,
 		      unsigned long port,
 		      unsigned long mpu_port,
 		      int irq,
 		      int mpu_irq,
 		      int dma8,
 		      unsigned short hardware,
-		      es1688_t **rchip)
+		      struct snd_es1688 **rchip)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_es1688_dev_free,
 	};
                                 
-	es1688_t *chip;
+	struct snd_es1688 *chip;
 	int err;
 
 	*rchip = NULL;
@@ -702,7 +702,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_es1688_playback_ops = {
+static struct snd_pcm_ops snd_es1688_playback_ops = {
 	.open =			snd_es1688_playback_open,
 	.close =		snd_es1688_playback_close,
 	.ioctl =		snd_es1688_ioctl,
@@ -713,7 +713,7 @@
 	.pointer =		snd_es1688_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_es1688_capture_ops = {
+static struct snd_pcm_ops snd_es1688_capture_ops = {
 	.open =			snd_es1688_capture_open,
 	.close =		snd_es1688_capture_close,
 	.ioctl =		snd_es1688_ioctl,
@@ -724,16 +724,9 @@
 	.pointer =		snd_es1688_capture_pointer,
 };
 
-static void snd_es1688_pcm_free(snd_pcm_t *pcm)
+int snd_es1688_pcm(struct snd_es1688 * chip, int device, struct snd_pcm ** rpcm)
 {
-	es1688_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int snd_es1688_pcm(es1688_t * chip, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(chip->card, "ESx688", device, 1, 1, &pcm)) < 0)
@@ -743,7 +736,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1688_capture_ops);
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_es1688_pcm_free;
 	pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
 	sprintf(pcm->name, snd_es1688_chip_id(chip));
 	chip->pcm = pcm;
@@ -761,7 +753,7 @@
  *  MIXER part
  */
 
-static int snd_es1688_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es1688_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[9] = {
 		"Mic", "Mic Master", "CD", "AOUT",
@@ -777,16 +769,16 @@
 	return 0;
 }
 
-static int snd_es1688_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1688_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es1688_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.enumerated.item[0] = snd_es1688_mixer_read(chip, ES1688_REC_DEV) & 7;
 	return 0;
 }
 
-static int snd_es1688_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1688_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es1688_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned char oval, nval;
 	int change;
@@ -809,7 +801,7 @@
   .get = snd_es1688_get_single, .put = snd_es1688_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_es1688_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es1688_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -820,9 +812,9 @@
 	return 0;
 }
 
-static int snd_es1688_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1688_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es1688_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -837,9 +829,9 @@
 	return 0;
 }
 
-static int snd_es1688_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1688_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es1688_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -868,7 +860,7 @@
   .get = snd_es1688_get_double, .put = snd_es1688_put_double, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-static int snd_es1688_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es1688_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -879,9 +871,9 @@
 	return 0;
 }
 
-static int snd_es1688_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1688_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es1688_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -913,9 +905,9 @@
 	return 0;
 }
 
-static int snd_es1688_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1688_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es1688_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es1688 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -976,7 +968,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_es1688_controls[] = {
+static struct snd_kcontrol_new snd_es1688_controls[] = {
 ES1688_DOUBLE("Master Playback Volume", 0, ES1688_MASTER_DEV, ES1688_MASTER_DEV, 4, 0, 15, 0),
 ES1688_DOUBLE("PCM Playback Volume", 0, ES1688_PCM_DEV, ES1688_PCM_DEV, 4, 0, 15, 0),
 ES1688_DOUBLE("Line Playback Volume", 0, ES1688_LINE_DEV, ES1688_LINE_DEV, 4, 0, 15, 0),
@@ -1011,9 +1003,9 @@
 	{ ES1688_REC_DEV, 0x17 }
 };
                                         
-int snd_es1688_mixer(es1688_t *chip)
+int snd_es1688_mixer(struct snd_es1688 *chip)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned int idx;
 	int err;
 	unsigned char reg, val;
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 970e2aa..bf5de07 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -65,28 +65,28 @@
 
 
 #include <sound/driver.h>
-#include <asm/io.h>
-#include <asm/dma.h>
 #include <linux/init.h>
-#include <linux/pm.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/isapnp.h>
 #include <linux/moduleparam.h>
+#include <asm/io.h>
+#include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/mpu401.h>
 #include <sound/opl3.h>
-#define SNDRV_LEGACY_AUTO_PROBE
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
 
 #define PFX "es18xx: "
 
-struct _snd_es18xx {
+struct snd_es18xx {
 	unsigned long port;		/* port of ESS chip */
 	unsigned long mpu_port;		/* MPU-401 port of ESS chip */
 	unsigned long fm_port;		/* FM port */
@@ -107,18 +107,18 @@
 	unsigned int dma1_shift;
 	unsigned int dma2_shift;
 
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *playback_a_substream;
-	snd_pcm_substream_t *capture_a_substream;
-	snd_pcm_substream_t *playback_b_substream;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_a_substream;
+	struct snd_pcm_substream *capture_a_substream;
+	struct snd_pcm_substream *playback_b_substream;
 
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 
-	snd_kcontrol_t *hw_volume;
-	snd_kcontrol_t *hw_switch;
-	snd_kcontrol_t *master_volume;
-	snd_kcontrol_t *master_switch;
+	struct snd_kcontrol *hw_volume;
+	struct snd_kcontrol *hw_switch;
+	struct snd_kcontrol *master_volume;
+	struct snd_kcontrol *master_switch;
 
 	spinlock_t reg_lock;
 	spinlock_t mixer_lock;
@@ -128,6 +128,14 @@
 #endif
 };
 
+struct snd_audiodrive {
+	struct snd_es18xx *chip;
+#ifdef CONFIG_PNP
+	struct pnp_dev *dev;
+	struct pnp_dev *devc;
+#endif
+};
+
 #define AUDIO1_IRQ	0x01
 #define AUDIO2_IRQ	0x02
 #define HWV_IRQ		0x04
@@ -155,8 +163,6 @@
 #define ES18XX_PM_FM	0x020
 #define ES18XX_PM_SUS	0x080
 
-typedef struct _snd_es18xx es18xx_t;
-
 /* Lowlevel */
 
 #define DAC1 0x01
@@ -164,7 +170,7 @@
 #define DAC2 0x04
 #define MILLISECOND 10000
 
-static int snd_es18xx_dsp_command(es18xx_t *chip, unsigned char val)
+static int snd_es18xx_dsp_command(struct snd_es18xx *chip, unsigned char val)
 {
         int i;
 
@@ -177,7 +183,7 @@
         return -EINVAL;
 }
 
-static int snd_es18xx_dsp_get_byte(es18xx_t *chip)
+static int snd_es18xx_dsp_get_byte(struct snd_es18xx *chip)
 {
         int i;
 
@@ -191,7 +197,7 @@
 
 #undef REG_DEBUG
 
-static int snd_es18xx_write(es18xx_t *chip,
+static int snd_es18xx_write(struct snd_es18xx *chip,
 			    unsigned char reg, unsigned char data)
 {
 	unsigned long flags;
@@ -210,7 +216,7 @@
 	return ret;
 }
 
-static int snd_es18xx_read(es18xx_t *chip, unsigned char reg)
+static int snd_es18xx_read(struct snd_es18xx *chip, unsigned char reg)
 {
 	unsigned long flags;
 	int ret, data;
@@ -232,7 +238,7 @@
 }
 
 /* Return old value */
-static int snd_es18xx_bits(es18xx_t *chip, unsigned char reg,
+static int snd_es18xx_bits(struct snd_es18xx *chip, unsigned char reg,
 			   unsigned char mask, unsigned char val)
 {
         int ret;
@@ -270,7 +276,7 @@
 	return ret;
 }
 
-static inline void snd_es18xx_mixer_write(es18xx_t *chip,
+static inline void snd_es18xx_mixer_write(struct snd_es18xx *chip,
 			    unsigned char reg, unsigned char data)
 {
 	unsigned long flags;
@@ -283,7 +289,7 @@
 #endif
 }
 
-static inline int snd_es18xx_mixer_read(es18xx_t *chip, unsigned char reg)
+static inline int snd_es18xx_mixer_read(struct snd_es18xx *chip, unsigned char reg)
 {
 	unsigned long flags;
 	int data;
@@ -298,7 +304,7 @@
 }
 
 /* Return old value */
-static inline int snd_es18xx_mixer_bits(es18xx_t *chip, unsigned char reg,
+static inline int snd_es18xx_mixer_bits(struct snd_es18xx *chip, unsigned char reg,
 					unsigned char mask, unsigned char val)
 {
 	unsigned char old, new, oval;
@@ -319,7 +325,7 @@
 	return oval;
 }
 
-static inline int snd_es18xx_mixer_writable(es18xx_t *chip, unsigned char reg,
+static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned char reg,
 					    unsigned char mask)
 {
 	int old, expected, new;
@@ -339,7 +345,7 @@
 }
 
 
-static int snd_es18xx_reset(es18xx_t *chip)
+static int snd_es18xx_reset(struct snd_es18xx *chip)
 {
 	int i;
         outb(0x03, chip->port + 0x06);
@@ -351,7 +357,7 @@
 	return 0;
 }
 
-static int snd_es18xx_reset_fifo(es18xx_t *chip)
+static int snd_es18xx_reset_fifo(struct snd_es18xx *chip)
 {
         outb(0x02, chip->port + 0x06);
         inb(chip->port + 0x06);
@@ -359,7 +365,7 @@
 	return 0;
 }
 
-static ratnum_t new_clocks[2] = {
+static struct snd_ratnum new_clocks[2] = {
 	{
 		.num = 793800,
 		.den_min = 1,
@@ -374,12 +380,12 @@
 	}
 };
 
-static snd_pcm_hw_constraint_ratnums_t new_hw_constraints_clocks = {
+static struct snd_pcm_hw_constraint_ratnums new_hw_constraints_clocks = {
 	.nrats = 2,
 	.rats = new_clocks,
 };
 
-static ratnum_t old_clocks[2] = {
+static struct snd_ratnum old_clocks[2] = {
 	{
 		.num = 795444,
 		.den_min = 1,
@@ -394,18 +400,18 @@
 	}
 };
 
-static snd_pcm_hw_constraint_ratnums_t old_hw_constraints_clocks  = {
+static struct snd_pcm_hw_constraint_ratnums old_hw_constraints_clocks  = {
 	.nrats = 2,
 	.rats = old_clocks,
 };
 
 
-static void snd_es18xx_rate_set(es18xx_t *chip, 
-				snd_pcm_substream_t *substream,
+static void snd_es18xx_rate_set(struct snd_es18xx *chip, 
+				struct snd_pcm_substream *substream,
 				int mode)
 {
 	unsigned int bits, div0;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (chip->caps & ES18XX_NEW_RATE) {
 		if (runtime->rate_num == new_clocks[0].num)
 			bits = 128 - runtime->rate_den;
@@ -435,10 +441,10 @@
 	}
 }
 
-static int snd_es18xx_playback_hw_params(snd_pcm_substream_t * substream,
-					 snd_pcm_hw_params_t * hw_params)
+static int snd_es18xx_playback_hw_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
 {
-	es18xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 	int shift, err;
 
 	shift = 0;
@@ -463,15 +469,15 @@
 	return 0;
 }
 
-static int snd_es18xx_pcm_hw_free(snd_pcm_substream_t * substream)
+static int snd_es18xx_pcm_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_es18xx_playback1_prepare(es18xx_t *chip,
-					snd_pcm_substream_t *substream)
+static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip,
+					struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
 
@@ -496,8 +502,8 @@
 	return 0;
 }
 
-static int snd_es18xx_playback1_trigger(es18xx_t *chip,
-					snd_pcm_substream_t * substream,
+static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip,
+					struct snd_pcm_substream *substream,
 					int cmd)
 {
 	switch (cmd) {
@@ -546,10 +552,10 @@
 	return 0;
 }
 
-static int snd_es18xx_capture_hw_params(snd_pcm_substream_t * substream,
-					snd_pcm_hw_params_t * hw_params)
+static int snd_es18xx_capture_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
-	es18xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 	int shift, err;
 
 	shift = 0;
@@ -569,10 +575,10 @@
 	return 0;
 }
 
-static int snd_es18xx_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
 {
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
 
@@ -608,10 +614,10 @@
 	return 0;
 }
 
-static int snd_es18xx_capture_trigger(snd_pcm_substream_t *substream,
+static int snd_es18xx_capture_trigger(struct snd_pcm_substream *substream,
 				      int cmd)
 {
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -637,10 +643,10 @@
 	return 0;
 }
 
-static int snd_es18xx_playback2_prepare(es18xx_t *chip,
-					snd_pcm_substream_t *substream)
+static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip,
+					struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
 
@@ -674,8 +680,8 @@
 	return 0;
 }
 
-static int snd_es18xx_playback2_trigger(es18xx_t *chip,
-					snd_pcm_substream_t *substream,
+static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip,
+					struct snd_pcm_substream *substream,
 					int cmd)
 {
 	switch (cmd) {
@@ -714,19 +720,19 @@
 	return 0;
 }
 
-static int snd_es18xx_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_es18xx_playback_prepare(struct snd_pcm_substream *substream)
 {
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 	if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
 		return snd_es18xx_playback1_prepare(chip, substream);
 	else
 		return snd_es18xx_playback2_prepare(chip, substream);
 }
 
-static int snd_es18xx_playback_trigger(snd_pcm_substream_t *substream,
+static int snd_es18xx_playback_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 	if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
 		return snd_es18xx_playback1_trigger(chip, substream, cmd);
 	else
@@ -735,7 +741,7 @@
 
 static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	es18xx_t *chip = dev_id;
+	struct snd_es18xx *chip = dev_id;
 	unsigned char status;
 
 	if (chip->caps & ES18XX_CONTROL) {
@@ -795,9 +801,9 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_uframes_t snd_es18xx_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream)
 {
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 	int pos;
 
 	if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
@@ -813,9 +819,9 @@
 	}
 }
 
-static snd_pcm_uframes_t snd_es18xx_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream)
 {
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 	int pos;
 
         if (!(chip->active & ADC1))
@@ -824,7 +830,7 @@
 	return pos >> chip->dma1_shift;
 }
 
-static snd_pcm_hardware_t snd_es18xx_playback =
+static struct snd_pcm_hardware snd_es18xx_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_RESUME |
@@ -844,7 +850,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_es18xx_capture =
+static struct snd_pcm_hardware snd_es18xx_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_RESUME |
@@ -864,10 +870,10 @@
 	.fifo_size =		0,
 };
 
-static int snd_es18xx_playback_open(snd_pcm_substream_t * substream)
+static int snd_es18xx_playback_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 
 	if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
 		if ((chip->caps & ES18XX_DUPLEX_MONO) &&
@@ -889,10 +895,10 @@
         return 0;
 }
 
-static int snd_es18xx_capture_open(snd_pcm_substream_t * substream)
+static int snd_es18xx_capture_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 
         if (chip->playback_b_substream)
                 return -EAGAIN;
@@ -907,9 +913,9 @@
         return 0;
 }
 
-static int snd_es18xx_playback_close(snd_pcm_substream_t * substream)
+static int snd_es18xx_playback_close(struct snd_pcm_substream *substream)
 {
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 
 	if (substream->number == 0 && (chip->caps & ES18XX_PCM2))
 		chip->playback_a_substream = NULL;
@@ -920,9 +926,9 @@
 	return 0;
 }
 
-static int snd_es18xx_capture_close(snd_pcm_substream_t * substream)
+static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
 {
-        es18xx_t *chip = snd_pcm_substream_chip(substream);
+        struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
 
         chip->capture_a_substream = NULL;
 	snd_pcm_lib_free_pages(substream);
@@ -933,7 +939,7 @@
  *  MIXER part
  */
 
-static int snd_es18xx_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[8] = {
 		"Mic", "Mic Master", "CD", "AOUT",
@@ -949,16 +955,16 @@
 	return 0;
 }
 
-static int snd_es18xx_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.enumerated.item[0] = snd_es18xx_mixer_read(chip, 0x1c) & 0x07;
 	return 0;
 }
 
-static int snd_es18xx_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	unsigned char val = ucontrol->value.enumerated.item[0];
 	
 	if (val > 7)
@@ -966,7 +972,7 @@
 	return snd_es18xx_mixer_bits(chip, 0x1c, 0x07, val) != val;
 }
 
-static int snd_es18xx_info_spatializer_enable(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es18xx_info_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -975,17 +981,17 @@
 	return 0;
 }
 
-static int snd_es18xx_get_spatializer_enable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_get_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	unsigned char val = snd_es18xx_mixer_read(chip, 0x50);
 	ucontrol->value.integer.value[0] = !!(val & 8);
 	return 0;
 }
 
-static int snd_es18xx_put_spatializer_enable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_put_spatializer_enable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	unsigned char oval, nval;
 	int change;
 	nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04;
@@ -998,7 +1004,7 @@
 	return change;
 }
 
-static int snd_es18xx_info_hw_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es18xx_info_hw_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -1007,15 +1013,15 @@
 	return 0;
 }
 
-static int snd_es18xx_get_hw_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_get_hw_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = snd_es18xx_mixer_read(chip, 0x61) & 0x3f;
 	ucontrol->value.integer.value[1] = snd_es18xx_mixer_read(chip, 0x63) & 0x3f;
 	return 0;
 }
 
-static int snd_es18xx_info_hw_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es18xx_info_hw_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -1024,24 +1030,24 @@
 	return 0;
 }
 
-static int snd_es18xx_get_hw_switch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_get_hw_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = !(snd_es18xx_mixer_read(chip, 0x61) & 0x40);
 	ucontrol->value.integer.value[1] = !(snd_es18xx_mixer_read(chip, 0x63) & 0x40);
 	return 0;
 }
 
-static void snd_es18xx_hwv_free(snd_kcontrol_t *kcontrol)
+static void snd_es18xx_hwv_free(struct snd_kcontrol *kcontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	chip->master_volume = NULL;
 	chip->master_switch = NULL;
 	chip->hw_volume = NULL;
 	chip->hw_switch = NULL;
 }
 
-static int snd_es18xx_reg_bits(es18xx_t *chip, unsigned char reg,
+static int snd_es18xx_reg_bits(struct snd_es18xx *chip, unsigned char reg,
 			       unsigned char mask, unsigned char val)
 {
 	if (reg < 0xa0)
@@ -1050,7 +1056,7 @@
 		return snd_es18xx_bits(chip, reg, mask, val);
 }
 
-static int snd_es18xx_reg_read(es18xx_t *chip, unsigned char reg)
+static int snd_es18xx_reg_read(struct snd_es18xx *chip, unsigned char reg)
 {
 	if (reg < 0xa0)
 		return snd_es18xx_mixer_read(chip, reg);
@@ -1064,7 +1070,7 @@
   .get = snd_es18xx_get_single, .put = snd_es18xx_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_es18xx_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es18xx_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -1075,9 +1081,9 @@
 	return 0;
 }
 
-static int snd_es18xx_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -1091,9 +1097,9 @@
 	return 0;
 }
 
-static int snd_es18xx_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -1114,7 +1120,7 @@
   .get = snd_es18xx_get_double, .put = snd_es18xx_put_double, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-static int snd_es18xx_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es18xx_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -1125,9 +1131,9 @@
 	return 0;
 }
 
-static int snd_es18xx_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1150,9 +1156,9 @@
 	return 0;
 }
 
-static int snd_es18xx_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es18xx_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	es18xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_es18xx *chip = snd_kcontrol_chip(kcontrol);
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1185,7 +1191,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_es18xx_base_controls[] = {
+static struct snd_kcontrol_new snd_es18xx_base_controls[] = {
 ES18XX_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0),
 ES18XX_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
 ES18XX_DOUBLE("Line Playback Volume", 0, 0x3e, 0x3e, 4, 0, 15, 0),
@@ -1207,10 +1213,10 @@
 }
 };
 
-static snd_kcontrol_new_t snd_es18xx_mono_in_control = 
+static struct snd_kcontrol_new snd_es18xx_mono_in_control = 
 ES18XX_DOUBLE("Mono Input Playback Volume", 0, 0x6d, 0x6d, 4, 0, 15, 0);
 
-static snd_kcontrol_new_t snd_es18xx_recmix_controls[] = {
+static struct snd_kcontrol_new snd_es18xx_recmix_controls[] = {
 ES18XX_DOUBLE("PCM Capture Volume", 0, 0x69, 0x69, 4, 0, 15, 0),
 ES18XX_DOUBLE("Mic Capture Volume", 0, 0x68, 0x68, 4, 0, 15, 0),
 ES18XX_DOUBLE("Line Capture Volume", 0, 0x6e, 0x6e, 4, 0, 15, 0),
@@ -1220,16 +1226,16 @@
 ES18XX_DOUBLE("Aux Capture Volume", 0, 0x6c, 0x6c, 4, 0, 15, 0)
 };
 
-static snd_kcontrol_new_t snd_es18xx_pcm1_controls[] = {
+static struct snd_kcontrol_new snd_es18xx_pcm1_controls[] = {
 ES18XX_DOUBLE("PCM Playback Volume", 0, 0x14, 0x14, 4, 0, 15, 0),
 };
 
-static snd_kcontrol_new_t snd_es18xx_pcm2_controls[] = {
+static struct snd_kcontrol_new snd_es18xx_pcm2_controls[] = {
 ES18XX_DOUBLE("PCM Playback Volume", 0, 0x7c, 0x7c, 4, 0, 15, 0),
 ES18XX_DOUBLE("PCM Playback Volume", 1, 0x14, 0x14, 4, 0, 15, 0)
 };
 
-static snd_kcontrol_new_t snd_es18xx_spatializer_controls[] = {
+static struct snd_kcontrol_new snd_es18xx_spatializer_controls[] = {
 ES18XX_SINGLE("3D Control - Level", 0, 0x52, 0, 63, 0),
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1240,13 +1246,13 @@
 }
 };
 
-static snd_kcontrol_new_t snd_es18xx_micpre1_control = 
+static struct snd_kcontrol_new snd_es18xx_micpre1_control = 
 ES18XX_SINGLE("Mic Boost (+26dB)", 0, 0xa9, 2, 1, 0);
 
-static snd_kcontrol_new_t snd_es18xx_micpre2_control =
+static struct snd_kcontrol_new snd_es18xx_micpre2_control =
 ES18XX_SINGLE("Mic Boost (+26dB)", 0, 0x7d, 3, 1, 0);
 
-static snd_kcontrol_new_t snd_es18xx_hw_volume_controls[] = {
+static struct snd_kcontrol_new snd_es18xx_hw_volume_controls[] = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Hardware Master Playback Volume",
@@ -1265,7 +1271,7 @@
 };
 
 #if 0
-static int __devinit snd_es18xx_config_read(es18xx_t *chip, unsigned char reg)
+static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
 {
 	int data;
 	unsigned long flags;
@@ -1277,7 +1283,7 @@
 }
 #endif
 
-static void __devinit snd_es18xx_config_write(es18xx_t *chip, 
+static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip, 
 					      unsigned char reg, unsigned char data)
 {
 	/* No need for spinlocks, this function is used only in
@@ -1289,7 +1295,7 @@
 #endif
 }
 
-static int __devinit snd_es18xx_initialize(es18xx_t *chip)
+static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
 {
 	int mask = 0;
 
@@ -1438,7 +1444,7 @@
         return 0;
 }
 
-static int __devinit snd_es18xx_identify(es18xx_t *chip)
+static int __devinit snd_es18xx_identify(struct snd_es18xx *chip)
 {
 	int hi,lo;
 
@@ -1504,7 +1510,7 @@
 	return 0;
 }
 
-static int __devinit snd_es18xx_probe(es18xx_t *chip)
+static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
 {
 	if (snd_es18xx_identify(chip) < 0) {
 		snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port);
@@ -1544,7 +1550,7 @@
         return snd_es18xx_initialize(chip);
 }
 
-static snd_pcm_ops_t snd_es18xx_playback_ops = {
+static struct snd_pcm_ops snd_es18xx_playback_ops = {
 	.open =		snd_es18xx_playback_open,
 	.close =	snd_es18xx_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1555,7 +1561,7 @@
 	.pointer =	snd_es18xx_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_es18xx_capture_ops = {
+static struct snd_pcm_ops snd_es18xx_capture_ops = {
 	.open =		snd_es18xx_capture_open,
 	.close =	snd_es18xx_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1566,27 +1572,19 @@
 	.pointer =	snd_es18xx_capture_pointer,
 };
 
-static void snd_es18xx_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_es18xx_pcm(struct snd_es18xx *chip, int device, struct snd_pcm ** rpcm)
 {
-	es18xx_t *codec = pcm->private_data;
-	codec->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_es18xx_pcm(es18xx_t *chip, int device, snd_pcm_t ** rpcm)
-{
-        snd_pcm_t *pcm;
+        struct snd_pcm *pcm;
 	char str[16];
 	int err;
 
 	if (rpcm)
 		*rpcm = NULL;
 	sprintf(str, "ES%x", chip->version);
-	if (chip->caps & ES18XX_PCM2) {
+	if (chip->caps & ES18XX_PCM2)
 		err = snd_pcm_new(chip->card, str, device, 2, 1, &pcm);
-	} else {
+	else
 		err = snd_pcm_new(chip->card, str, device, 1, 1, &pcm);
-	}
         if (err < 0)
                 return err;
 
@@ -1595,7 +1593,6 @@
 
 	/* global setup */
         pcm->private_data = chip;
-	pcm->private_free = snd_es18xx_pcm_free;
         pcm->info_flags = 0;
 	if (chip->caps & ES18XX_DUPLEX_SAME)
 		pcm->info_flags |= SNDRV_PCM_INFO_JOINT_DUPLEX;
@@ -1616,9 +1613,12 @@
 
 /* Power Management support functions */
 #ifdef CONFIG_PM
-static int snd_es18xx_suspend(snd_card_t *card, pm_message_t state)
+static int snd_es18xx_suspend(struct snd_card *card, pm_message_t state)
 {
-	es18xx_t *chip = card->pm_private_data;
+	struct snd_audiodrive *acard = card->private_data;
+	struct snd_es18xx *chip = acard->chip;
+
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
 
 	snd_pcm_suspend_all(chip->pcm);
 
@@ -1631,18 +1631,20 @@
 	return 0;
 }
 
-static int snd_es18xx_resume(snd_card_t *card)
+static int snd_es18xx_resume(struct snd_card *card)
 {
-	es18xx_t *chip = card->pm_private_data;
+	struct snd_audiodrive *acard = card->private_data;
+	struct snd_es18xx *chip = acard->chip;
 
 	/* restore PM register, we won't wake till (not 0x07) i/o activity though */
 	snd_es18xx_write(chip, ES18XX_PM, chip->pm_reg ^= ES18XX_PM_FM);
 
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
-static int snd_es18xx_free(es18xx_t *chip)
+static int snd_es18xx_free(struct snd_es18xx *chip)
 {
 	release_and_free_resource(chip->res_port);
 	release_and_free_resource(chip->res_ctrl_port);
@@ -1661,21 +1663,21 @@
 	return 0;
 }
 
-static int snd_es18xx_dev_free(snd_device_t *device)
+static int snd_es18xx_dev_free(struct snd_device *device)
 {
-	es18xx_t *chip = device->device_data;
+	struct snd_es18xx *chip = device->device_data;
 	return snd_es18xx_free(chip);
 }
 
-static int __devinit snd_es18xx_new_device(snd_card_t * card,
+static int __devinit snd_es18xx_new_device(struct snd_card *card,
 					   unsigned long port,
 					   unsigned long mpu_port,
 					   unsigned long fm_port,
 					   int irq, int dma1, int dma2,
-					   es18xx_t ** rchip)
+					   struct snd_es18xx ** rchip)
 {
-        es18xx_t *chip;
-	static snd_device_ops_t ops = {
+        struct snd_es18xx *chip;
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_es18xx_dev_free,
         };
 	int err;
@@ -1736,9 +1738,9 @@
         return 0;
 }
 
-static int __devinit snd_es18xx_mixer(es18xx_t *chip)
+static int __devinit snd_es18xx_mixer(struct snd_es18xx *chip)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	int err;
 	unsigned int idx;
 
@@ -1747,7 +1749,7 @@
 	strcpy(card->mixername, chip->pcm->name);
 
 	for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_base_controls); idx++) {
-		snd_kcontrol_t *kctl;
+		struct snd_kcontrol *kctl;
 		kctl = snd_ctl_new1(&snd_es18xx_base_controls[idx], chip);
 		if (chip->caps & ES18XX_HWV) {
 			switch (idx) {
@@ -1805,7 +1807,7 @@
 	}
 	if (chip->caps & ES18XX_HWV) {
 		for (idx = 0; idx < ARRAY_SIZE(snd_es18xx_hw_volume_controls); idx++) {
-			snd_kcontrol_t *kctl;
+			struct snd_kcontrol *kctl;
 			kctl = snd_ctl_new1(&snd_es18xx_hw_volume_controls[idx], chip);
 			if (idx == 0)
 				chip->hw_volume = kctl;
@@ -1875,14 +1877,8 @@
 module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
 
-struct snd_audiodrive {
-#ifdef CONFIG_PNP
-	struct pnp_dev *dev;
-	struct pnp_dev *devc;
-#endif
-};
-
-static snd_card_t *snd_audiodrive_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
 
 #ifdef CONFIG_PNP
 
@@ -1989,227 +1985,281 @@
 #define is_isapnp_selected(dev)		0
 #endif
 
-static int __devinit snd_audiodrive_probe(int dev, struct pnp_card_link *pcard,
-					  const struct pnp_card_device_id *pid)
+static struct snd_card *snd_es18xx_card_new(int dev)
 {
-	static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1};
-	static int possible_dmas[] = {1, 0, 3, 5, -1};
-	int xirq, xdma1, xdma2;
-	snd_card_t *card;
-	struct snd_audiodrive *acard;
-	es18xx_t *chip;
-	opl3_t *opl3;
-	int err;
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
+	return snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(struct snd_audiodrive));
-	if (card == NULL)
-		return -ENOMEM;
-	acard = (struct snd_audiodrive *)card->private_data;
-#ifdef CONFIG_PNP
-	if (isapnp[dev]) {
-		if ((err = snd_audiodrive_pnp(dev, acard, pcard, pid)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
-		snd_card_set_dev(card, &pcard->card->dev);
-	}
-#endif
+}
 
-	xirq = irq[dev];
-	if (xirq == SNDRV_AUTO_IRQ) {
-		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
-			err = -EBUSY;
-			goto _err;
-		}
-	}
-	xdma1 = dma1[dev];
-        if (xdma1 == SNDRV_AUTO_DMA) {
-                if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
-			err = -EBUSY;
-			goto _err;
-                }
-        }
-	xdma2 = dma2[dev];
-        if (xdma2 == SNDRV_AUTO_DMA) {
-                if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
-			err = -EBUSY;
-			goto _err;
-                }
-        }
+static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
+{
+	struct snd_audiodrive *acard = card->private_data;
+	struct snd_es18xx *chip;
+	struct snd_opl3 *opl3;
+	int err;
 
 	if ((err = snd_es18xx_new_device(card,
 					 port[dev],
 					 mpu_port[dev],
 					 fm_port[dev],
-					 xirq, xdma1, xdma2,
+					 irq[dev], dma1[dev], dma2[dev],
 					 &chip)) < 0)
-		goto _err;
+		return err;
+	acard->chip = chip;
 
 	sprintf(card->driver, "ES%x", chip->version);
+	
 	sprintf(card->shortname, "ESS AudioDrive ES%x", chip->version);
-	if (xdma1 != xdma2)
+	if (dma1[dev] != dma2[dev])
 		sprintf(card->longname, "%s at 0x%lx, irq %d, dma1 %d, dma2 %d",
 			card->shortname,
 			chip->port,
-			xirq, xdma1, xdma2);
+			irq[dev], dma1[dev], dma2[dev]);
 	else
 		sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
 			card->shortname,
 			chip->port,
-			xirq, xdma1);
+			irq[dev], dma1[dev]);
 
 	if ((err = snd_es18xx_pcm(chip, 0, NULL)) < 0)
-		goto _err;
+		return err;
 
 	if ((err = snd_es18xx_mixer(chip)) < 0)
-		goto _err;
+		return err;
 
 	if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
 		if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) {
 			snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port);
 		} else {
 			if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
-				goto _err;
+				return err;
 		}
 	}
 
 	if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
 		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
 					       chip->mpu_port, 0,
-					       xirq, 0,
+					       irq[dev], 0,
 					       &chip->rmidi)) < 0)
-			goto _err;
+			return err;
 	}
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
-
-	/* Power Management */
-	snd_card_set_isa_pm_callback(card, snd_es18xx_suspend, snd_es18xx_resume, chip);
-
-	if ((err = snd_card_register(card)) < 0)
-		goto _err;
-
-	if (pcard)
-		pnp_set_card_drvdata(pcard, card);
-	else
-		snd_audiodrive_legacy[dev] = card;
-	return 0;
-
- _err:
-	snd_card_free(card);
-	return err;
+	return snd_card_register(card);
 }
 
-static int __devinit snd_audiodrive_probe_legacy_port(unsigned long xport)
+static int __init snd_es18xx_nonpnp_probe1(int dev, struct platform_device *devptr)
 {
-	static int dev;
-	int res;
+	struct snd_card *card;
+	int err;
 
-	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
-			continue;
-		if (is_isapnp_selected(dev))
-			continue;
-		port[dev] = xport;
-		res = snd_audiodrive_probe(dev, NULL, NULL);
-		if (res < 0)
-			port[dev] = SNDRV_AUTO_PORT;
-		return res;
+	card = snd_es18xx_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	snd_card_set_dev(card, &devptr->dev);
+	if ((err = snd_audiodrive_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
 	}
-	return -ENODEV;
+	platform_set_drvdata(devptr, card);
+	return 0;
 }
 
+static int __init snd_es18xx_nonpnp_probe(struct platform_device *pdev)
+{
+	int dev = pdev->id;
+	int err;
+	static int possible_irqs[] = {5, 9, 10, 7, 11, 12, -1};
+	static int possible_dmas[] = {1, 0, 3, 5, -1};
+
+	if (irq[dev] == SNDRV_AUTO_IRQ) {
+		if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+			return -EBUSY;
+		}
+	}
+	if (dma1[dev] == SNDRV_AUTO_DMA) {
+		if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+			return -EBUSY;
+		}
+	}
+	if (dma2[dev] == SNDRV_AUTO_DMA) {
+		if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+			return -EBUSY;
+		}
+	}
+
+	if (port[dev] != SNDRV_AUTO_PORT) {
+		return snd_es18xx_nonpnp_probe1(dev, pdev);
+	} else {
+		static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280};
+		int i;
+		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
+			port[dev] = possible_ports[i];
+			err = snd_es18xx_nonpnp_probe1(dev, pdev);
+			if (! err)
+				return 0;
+		}
+		return err;
+	}
+}
+
+static int __devexit snd_es18xx_nonpnp_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_es18xx_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+{
+	return snd_es18xx_suspend(platform_get_drvdata(dev), state);
+}
+
+static int snd_es18xx_nonpnp_resume(struct platform_device *dev)
+{
+	return snd_es18xx_resume(platform_get_drvdata(dev));
+}
+#endif
+
+#define ES18XX_DRIVER	"snd_es18xx"
+
+static struct platform_driver snd_es18xx_nonpnp_driver = {
+	.probe		= snd_es18xx_nonpnp_probe,
+	.remove		= __devexit_p(snd_es18xx_nonpnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_es18xx_nonpnp_suspend,
+	.resume		= snd_es18xx_nonpnp_resume,
+#endif
+	.driver		= {
+		.name	= ES18XX_DRIVER
+	},
+};
+
 
 #ifdef CONFIG_PNP
-static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *card,
-					       const struct pnp_card_device_id *id)
+static int __devinit snd_audiodrive_pnp_detect(struct pnp_card_link *pcard,
+					       const struct pnp_card_device_id *pid)
 {
 	static int dev;
+	struct snd_card *card;
 	int res;
 
 	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || !isapnp[dev])
-			continue;
-                res = snd_audiodrive_probe(dev, card, id);
-		if (res < 0)
-			return res;
-		dev++;
-		return 0;
-        }
+		if (enable[dev] && isapnp[dev])
+			break;
+	}
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
 
-        return -ENODEV;
+	card = snd_es18xx_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+
+	if ((res = snd_audiodrive_pnp(dev, card->private_data, pcard, pid)) < 0) {
+		snd_card_free(card);
+		return res;
+	}
+	snd_card_set_dev(card, &pcard->card->dev);
+	if ((res = snd_audiodrive_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return res;
+	}
+
+	pnp_set_card_drvdata(pcard, card);
+	dev++;
+	return 0;
 }
 
 static void __devexit snd_audiodrive_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_audiodrive_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	return snd_es18xx_suspend(pnp_get_card_drvdata(pcard), state);
+}
+
+static int snd_audiodrive_pnp_resume(struct pnp_card_link *pcard)
+{
+	return snd_es18xx_resume(pnp_get_card_drvdata(pcard));
+}
+
+#endif
+
 static struct pnp_card_driver es18xx_pnpc_driver = {
 	.flags = PNP_DRIVER_RES_DISABLE,
 	.name = "es18xx",
 	.id_table = snd_audiodrive_pnpids,
 	.probe = snd_audiodrive_pnp_detect,
 	.remove = __devexit_p(snd_audiodrive_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_audiodrive_pnp_suspend,
+	.resume		= snd_audiodrive_pnp_resume,
+#endif
 };
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_es18xx_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&es18xx_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_es18xx_nonpnp_driver);
+}
+
 static int __init alsa_card_es18xx_init(void)
 {
-	static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280, -1};
-	int dev, cards = 0, i;
+	int i, err, cards = 0;
 
-	/* legacy non-auto cards at first */
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT)
+	if ((err = platform_driver_register(&snd_es18xx_nonpnp_driver)) < 0)
+		return err;
+
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		if (is_isapnp_selected(i))
 			continue;
-		if (is_isapnp_selected(dev))
-			continue;
-		if (snd_audiodrive_probe(dev, NULL, NULL) >= 0)
-			cards++;
+		device = platform_device_register_simple(ES18XX_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		platform_devices[i] = device;
+		cards++;
 	}
-	/* legacy auto configured cards */
-	i = snd_legacy_auto_probe(possible_ports, snd_audiodrive_probe_legacy_port);
-	if (i > 0)
-		cards += i;
 
-#ifdef CONFIG_PNP
-	/* ISA PnP cards at last */
 	i = pnp_register_card_driver(&es18xx_pnpc_driver);
-	if (i > 0)
+	if (i >= 0) {
+		pnp_registered = 1;
 		cards += i;
+	}
 
-#endif
 	if(!cards) {
-#ifdef CONFIG_PNP
-		pnp_unregister_card_driver(&es18xx_pnpc_driver);
-#endif
 #ifdef MODULE
 		snd_printk(KERN_ERR "ESS AudioDrive ES18xx soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_es18xx_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_es18xx_exit(void)
 {
-	int idx;
-
-#ifdef CONFIG_PNP
-	/* PnP cards first */
-	pnp_unregister_card_driver(&es18xx_pnpc_driver);
-#endif
-	for(idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_audiodrive_legacy[idx]);
+	snd_es18xx_unregister_all();
 }
 
 module_init(alsa_card_es18xx_init)
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c
index ef1b2e9..930f4bc 100644
--- a/sound/isa/gus/gus_dma.c
+++ b/sound/isa/gus/gus_dma.c
@@ -25,7 +25,7 @@
 #include <sound/core.h>
 #include <sound/gus.h>
 
-static void snd_gf1_dma_ack(snd_gus_card_t * gus)
+static void snd_gf1_dma_ack(struct snd_gus_card * gus)
 {
 	unsigned long flags;
 
@@ -35,7 +35,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-static void snd_gf1_dma_program(snd_gus_card_t * gus,
+static void snd_gf1_dma_program(struct snd_gus_card * gus,
 				unsigned int addr,
 				unsigned long buf_addr,
 				unsigned int count,
@@ -91,9 +91,9 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-static snd_gf1_dma_block_t *snd_gf1_dma_next_block(snd_gus_card_t * gus)
+static struct snd_gf1_dma_block *snd_gf1_dma_next_block(struct snd_gus_card * gus)
 {
-	snd_gf1_dma_block_t *block;
+	struct snd_gf1_dma_block *block;
 
 	/* PCM block have bigger priority than synthesizer one */
 	if (gus->gf1.dma_data_pcm) {
@@ -123,9 +123,9 @@
 }
 
 
-static void snd_gf1_dma_interrupt(snd_gus_card_t * gus)
+static void snd_gf1_dma_interrupt(struct snd_gus_card * gus)
 {
-	snd_gf1_dma_block_t *block;
+	struct snd_gf1_dma_block *block;
 
 	snd_gf1_dma_ack(gus);
 	if (gus->gf1.dma_ack)
@@ -147,7 +147,7 @@
 #endif
 }
 
-int snd_gf1_dma_init(snd_gus_card_t * gus)
+int snd_gf1_dma_init(struct snd_gus_card * gus)
 {
 	down(&gus->dma_mutex);
 	gus->gf1.dma_shared++;
@@ -164,9 +164,9 @@
 	return 0;
 }
 
-int snd_gf1_dma_done(snd_gus_card_t * gus)
+int snd_gf1_dma_done(struct snd_gus_card * gus)
 {
-	snd_gf1_dma_block_t *block;
+	struct snd_gf1_dma_block *block;
 
 	down(&gus->dma_mutex);
 	gus->gf1.dma_shared--;
@@ -189,13 +189,13 @@
 	return 0;
 }
 
-int snd_gf1_dma_transfer_block(snd_gus_card_t * gus,
-			       snd_gf1_dma_block_t * __block,
+int snd_gf1_dma_transfer_block(struct snd_gus_card * gus,
+			       struct snd_gf1_dma_block * __block,
 			       int atomic,
 			       int synth)
 {
 	unsigned long flags;
-	snd_gf1_dma_block_t *block;
+	struct snd_gf1_dma_block *block;
 
 	block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL);
 	if (block == NULL) {
diff --git a/sound/isa/gus/gus_dram.c b/sound/isa/gus/gus_dram.c
index 22120b8..f22fe79 100644
--- a/sound/isa/gus/gus_dram.c
+++ b/sound/isa/gus/gus_dram.c
@@ -26,7 +26,7 @@
 #include <sound/info.h>
 
 
-static int snd_gus_dram_poke(snd_gus_card_t *gus, char __user *_buffer,
+static int snd_gus_dram_poke(struct snd_gus_card *gus, char __user *_buffer,
 			     unsigned int address, unsigned int size)
 {
 	unsigned long flags;
@@ -57,13 +57,13 @@
 }
 
 
-int snd_gus_dram_write(snd_gus_card_t *gus, char __user *buffer,
+int snd_gus_dram_write(struct snd_gus_card *gus, char __user *buffer,
 		       unsigned int address, unsigned int size)
 {
 	return snd_gus_dram_poke(gus, buffer, address, size);
 }
 
-static int snd_gus_dram_peek(snd_gus_card_t *gus, char __user *_buffer,
+static int snd_gus_dram_peek(struct snd_gus_card *gus, char __user *_buffer,
 			     unsigned int address, unsigned int size,
 			     int rom)
 {
@@ -95,7 +95,7 @@
 	return 0;
 }
 
-int snd_gus_dram_read(snd_gus_card_t *gus, char __user *buffer,
+int snd_gus_dram_read(struct snd_gus_card *gus, char __user *buffer,
 		      unsigned int address, unsigned int size,
 		      int rom)
 {
diff --git a/sound/isa/gus/gus_instr.c b/sound/isa/gus/gus_instr.c
index 591a9a1..d0c38e1 100644
--- a/sound/isa/gus/gus_instr.c
+++ b/sound/isa/gus/gus_instr.c
@@ -28,11 +28,11 @@
  *
  */
 
-int snd_gus_iwffff_put_sample(void *private_data, iwffff_wave_t *wave,
+int snd_gus_iwffff_put_sample(void *private_data, struct iwffff_wave *wave,
 			      char __user *data, long len, int atomic)
 {
-	snd_gus_card_t *gus = private_data;
-	snd_gf1_mem_block_t *block;
+	struct snd_gus_card *gus = private_data;
+	struct snd_gf1_mem_block *block;
 	int err;
 
 	if (wave->format & IWFFFF_WAVE_ROM)
@@ -58,19 +58,19 @@
 	return 0;
 }
 
-int snd_gus_iwffff_get_sample(void *private_data, iwffff_wave_t *wave,
+int snd_gus_iwffff_get_sample(void *private_data, struct iwffff_wave *wave,
 			      char __user *data, long len, int atomic)
 {
-	snd_gus_card_t *gus = private_data;
+	struct snd_gus_card *gus = private_data;
 
 	return snd_gus_dram_read(gus, data, wave->address.memory, wave->size,
 				 wave->format & IWFFFF_WAVE_ROM ? 1 : 0);
 }
 
-int snd_gus_iwffff_remove_sample(void *private_data, iwffff_wave_t *wave,
+int snd_gus_iwffff_remove_sample(void *private_data, struct iwffff_wave *wave,
 				 int atomic)
 {
-	snd_gus_card_t *gus = private_data;
+	struct snd_gus_card *gus = private_data;
 
 	if (wave->format & IWFFFF_WAVE_ROM)
 		return 0;	/* it's probably ok - verify the address? */	
@@ -81,11 +81,11 @@
  *
  */
 
-int snd_gus_gf1_put_sample(void *private_data, gf1_wave_t *wave,
+int snd_gus_gf1_put_sample(void *private_data, struct gf1_wave *wave,
 			   char __user *data, long len, int atomic)
 {
-	snd_gus_card_t *gus = private_data;
-	snd_gf1_mem_block_t *block;
+	struct snd_gus_card *gus = private_data;
+	struct snd_gf1_mem_block *block;
 	int err;
 
 	if (wave->format & GF1_WAVE_STEREO)
@@ -109,18 +109,18 @@
 	return 0;
 }
 
-int snd_gus_gf1_get_sample(void *private_data, gf1_wave_t *wave,
+int snd_gus_gf1_get_sample(void *private_data, struct gf1_wave *wave,
 			   char __user *data, long len, int atomic)
 {
-	snd_gus_card_t *gus = private_data;
+	struct snd_gus_card *gus = private_data;
 
 	return snd_gus_dram_read(gus, data, wave->address.memory, wave->size, 0);
 }
 
-int snd_gus_gf1_remove_sample(void *private_data, gf1_wave_t *wave,
+int snd_gus_gf1_remove_sample(void *private_data, struct gf1_wave *wave,
 			      int atomic)
 {
-	snd_gus_card_t *gus = private_data;
+	struct snd_gus_card *gus = private_data;
 
 	return snd_gf1_mem_free(&gus->gf1.mem_alloc, wave->address.memory);
 }
@@ -129,11 +129,11 @@
  *
  */
 
-int snd_gus_simple_put_sample(void *private_data, simple_instrument_t *instr,
+int snd_gus_simple_put_sample(void *private_data, struct simple_instrument *instr,
 			      char __user *data, long len, int atomic)
 {
-	snd_gus_card_t *gus = private_data;
-	snd_gf1_mem_block_t *block;
+	struct snd_gus_card *gus = private_data;
+	struct snd_gf1_mem_block *block;
 	int err;
 
 	if (instr->format & SIMPLE_WAVE_STEREO)
@@ -156,18 +156,18 @@
 	return 0;
 }
 
-int snd_gus_simple_get_sample(void *private_data, simple_instrument_t *instr,
+int snd_gus_simple_get_sample(void *private_data, struct simple_instrument *instr,
 			      char __user *data, long len, int atomic)
 {
-	snd_gus_card_t *gus = private_data;
+	struct snd_gus_card *gus = private_data;
 
 	return snd_gus_dram_read(gus, data, instr->address.memory, instr->size, 0);
 }
 
-int snd_gus_simple_remove_sample(void *private_data, simple_instrument_t *instr,
+int snd_gus_simple_remove_sample(void *private_data, struct simple_instrument *instr,
 			         int atomic)
 {
-	snd_gus_card_t *gus = private_data;
+	struct snd_gus_card *gus = private_data;
 
 	return snd_gf1_mem_free(&gus->gf1.mem_alloc, instr->address.memory);
 }
diff --git a/sound/isa/gus/gus_io.c b/sound/isa/gus/gus_io.c
index 8d5752b..9b1fe29 100644
--- a/sound/isa/gus/gus_io.c
+++ b/sound/isa/gus/gus_io.c
@@ -25,7 +25,7 @@
 #include <sound/core.h>
 #include <sound/gus.h>
 
-void snd_gf1_delay(snd_gus_card_t * gus)
+void snd_gf1_delay(struct snd_gus_card * gus)
 {
 	int i;
 
@@ -44,7 +44,7 @@
  *       big UltraClick (tm) elimination...
  */
 
-static inline void __snd_gf1_ctrl_stop(snd_gus_card_t * gus, unsigned char reg)
+static inline void __snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
 {
 	unsigned char value;
 
@@ -58,7 +58,7 @@
 	mb();
 }
 
-static inline void __snd_gf1_write8(snd_gus_card_t * gus,
+static inline void __snd_gf1_write8(struct snd_gus_card * gus,
 				    unsigned char reg,
 				    unsigned char data)
 {
@@ -68,7 +68,7 @@
 	mb();
 }
 
-static inline unsigned char __snd_gf1_look8(snd_gus_card_t * gus,
+static inline unsigned char __snd_gf1_look8(struct snd_gus_card * gus,
 					    unsigned char reg)
 {
 	outb(reg, gus->gf1.reg_regsel);
@@ -76,7 +76,7 @@
 	return inb(gus->gf1.reg_data8);
 }
 
-static inline void __snd_gf1_write16(snd_gus_card_t * gus,
+static inline void __snd_gf1_write16(struct snd_gus_card * gus,
 				     unsigned char reg, unsigned int data)
 {
 	outb(reg, gus->gf1.reg_regsel);
@@ -85,7 +85,7 @@
 	mb();
 }
 
-static inline unsigned short __snd_gf1_look16(snd_gus_card_t * gus,
+static inline unsigned short __snd_gf1_look16(struct snd_gus_card * gus,
 					      unsigned char reg)
 {
 	outb(reg, gus->gf1.reg_regsel);
@@ -93,7 +93,7 @@
 	return inw(gus->gf1.reg_data16);
 }
 
-static inline void __snd_gf1_adlib_write(snd_gus_card_t * gus,
+static inline void __snd_gf1_adlib_write(struct snd_gus_card * gus,
 					 unsigned char reg, unsigned char data)
 {
 	outb(reg, gus->gf1.reg_timerctrl);
@@ -104,7 +104,7 @@
 	inb(gus->gf1.reg_timerctrl);
 }
 
-static inline void __snd_gf1_write_addr(snd_gus_card_t * gus, unsigned char reg,
+static inline void __snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg,
                                         unsigned int addr, int w_16bit)
 {
 	if (gus->gf1.enh_mode) {
@@ -117,7 +117,7 @@
 	__snd_gf1_write16(gus, reg + 1, (unsigned short) (addr << 5));
 }
 
-static inline unsigned int __snd_gf1_read_addr(snd_gus_card_t * gus,
+static inline unsigned int __snd_gf1_read_addr(struct snd_gus_card * gus,
 					       unsigned char reg, short w_16bit)
 {
 	unsigned int res;
@@ -138,49 +138,49 @@
  *  =======================================================================
  */
 
-void snd_gf1_ctrl_stop(snd_gus_card_t * gus, unsigned char reg)
+void snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
 {
 	__snd_gf1_ctrl_stop(gus, reg);
 }
 
-void snd_gf1_write8(snd_gus_card_t * gus,
+void snd_gf1_write8(struct snd_gus_card * gus,
 		    unsigned char reg,
 		    unsigned char data)
 {
 	__snd_gf1_write8(gus, reg, data);
 }
 
-unsigned char snd_gf1_look8(snd_gus_card_t * gus, unsigned char reg)
+unsigned char snd_gf1_look8(struct snd_gus_card * gus, unsigned char reg)
 {
 	return __snd_gf1_look8(gus, reg);
 }
 
-void snd_gf1_write16(snd_gus_card_t * gus,
+void snd_gf1_write16(struct snd_gus_card * gus,
 		     unsigned char reg,
 		     unsigned int data)
 {
 	__snd_gf1_write16(gus, reg, data);
 }
 
-unsigned short snd_gf1_look16(snd_gus_card_t * gus, unsigned char reg)
+unsigned short snd_gf1_look16(struct snd_gus_card * gus, unsigned char reg)
 {
 	return __snd_gf1_look16(gus, reg);
 }
 
-void snd_gf1_adlib_write(snd_gus_card_t * gus,
+void snd_gf1_adlib_write(struct snd_gus_card * gus,
                          unsigned char reg,
                          unsigned char data)
 {
 	__snd_gf1_adlib_write(gus, reg, data);
 }
 
-void snd_gf1_write_addr(snd_gus_card_t * gus, unsigned char reg,
+void snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg,
                         unsigned int addr, short w_16bit)
 {
 	__snd_gf1_write_addr(gus, reg, addr, w_16bit);
 }
 
-unsigned int snd_gf1_read_addr(snd_gus_card_t * gus,
+unsigned int snd_gf1_read_addr(struct snd_gus_card * gus,
                                unsigned char reg,
                                short w_16bit)
 {
@@ -191,7 +191,7 @@
 
  */
 
-void snd_gf1_i_ctrl_stop(snd_gus_card_t * gus, unsigned char reg)
+void snd_gf1_i_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
 {
 	unsigned long flags;
 
@@ -200,7 +200,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-void snd_gf1_i_write8(snd_gus_card_t * gus,
+void snd_gf1_i_write8(struct snd_gus_card * gus,
 		      unsigned char reg,
                       unsigned char data)
 {
@@ -211,7 +211,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-unsigned char snd_gf1_i_look8(snd_gus_card_t * gus, unsigned char reg)
+unsigned char snd_gf1_i_look8(struct snd_gus_card * gus, unsigned char reg)
 {
 	unsigned long flags;
 	unsigned char res;
@@ -222,7 +222,7 @@
 	return res;
 }
 
-void snd_gf1_i_write16(snd_gus_card_t * gus,
+void snd_gf1_i_write16(struct snd_gus_card * gus,
 		       unsigned char reg,
 		       unsigned int data)
 {
@@ -233,7 +233,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-unsigned short snd_gf1_i_look16(snd_gus_card_t * gus, unsigned char reg)
+unsigned short snd_gf1_i_look16(struct snd_gus_card * gus, unsigned char reg)
 {
 	unsigned long flags;
 	unsigned short res;
@@ -246,7 +246,7 @@
 
 #if 0
 
-void snd_gf1_i_adlib_write(snd_gus_card_t * gus,
+void snd_gf1_i_adlib_write(struct snd_gus_card * gus,
 		           unsigned char reg,
 		           unsigned char data)
 {
@@ -257,7 +257,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-void snd_gf1_i_write_addr(snd_gus_card_t * gus, unsigned char reg,
+void snd_gf1_i_write_addr(struct snd_gus_card * gus, unsigned char reg,
 			  unsigned int addr, short w_16bit)
 {
 	unsigned long flags;
@@ -270,7 +270,7 @@
 #endif  /*  0  */
 
 #ifdef CONFIG_SND_DEBUG
-static unsigned int snd_gf1_i_read_addr(snd_gus_card_t * gus,
+static unsigned int snd_gf1_i_read_addr(struct snd_gus_card * gus,
 					unsigned char reg, short w_16bit)
 {
 	unsigned int res;
@@ -287,7 +287,7 @@
 
  */
 
-void snd_gf1_dram_addr(snd_gus_card_t * gus, unsigned int addr)
+void snd_gf1_dram_addr(struct snd_gus_card * gus, unsigned int addr)
 {
 	outb(0x43, gus->gf1.reg_regsel);
 	mb();
@@ -299,7 +299,7 @@
 	mb();
 }
 
-void snd_gf1_poke(snd_gus_card_t * gus, unsigned int addr, unsigned char data)
+void snd_gf1_poke(struct snd_gus_card * gus, unsigned int addr, unsigned char data)
 {
 	unsigned long flags;
 
@@ -316,7 +316,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-unsigned char snd_gf1_peek(snd_gus_card_t * gus, unsigned int addr)
+unsigned char snd_gf1_peek(struct snd_gus_card * gus, unsigned int addr)
 {
 	unsigned long flags;
 	unsigned char res;
@@ -337,7 +337,7 @@
 
 #if 0
 
-void snd_gf1_pokew(snd_gus_card_t * gus, unsigned int addr, unsigned short data)
+void snd_gf1_pokew(struct snd_gus_card * gus, unsigned int addr, unsigned short data)
 {
 	unsigned long flags;
 
@@ -360,7 +360,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-unsigned short snd_gf1_peekw(snd_gus_card_t * gus, unsigned int addr)
+unsigned short snd_gf1_peekw(struct snd_gus_card * gus, unsigned int addr)
 {
 	unsigned long flags;
 	unsigned short res;
@@ -385,7 +385,7 @@
 	return res;
 }
 
-void snd_gf1_dram_setmem(snd_gus_card_t * gus, unsigned int addr,
+void snd_gf1_dram_setmem(struct snd_gus_card * gus, unsigned int addr,
 			 unsigned short value, unsigned int count)
 {
 	unsigned long port;
@@ -415,7 +415,7 @@
 
 #endif  /*  0  */
 
-void snd_gf1_select_active_voices(snd_gus_card_t * gus)
+void snd_gf1_select_active_voices(struct snd_gus_card * gus)
 {
 	unsigned short voices;
 
@@ -443,7 +443,7 @@
 
 #ifdef CONFIG_SND_DEBUG
 
-void snd_gf1_print_voice_registers(snd_gus_card_t * gus)
+void snd_gf1_print_voice_registers(struct snd_gus_card * gus)
 {
 	unsigned char mode;
 	int voice, ctrl;
@@ -477,7 +477,7 @@
 
 #if 0
 
-void snd_gf1_print_global_registers(snd_gus_card_t * gus)
+void snd_gf1_print_global_registers(struct snd_gus_card * gus)
 {
 	unsigned char global_mode = 0x00;
 
@@ -504,7 +504,7 @@
 	}
 }
 
-void snd_gf1_print_setup_registers(snd_gus_card_t * gus)
+void snd_gf1_print_setup_registers(struct snd_gus_card * gus)
 {
 	printk(KERN_INFO " -S- mix control                  = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
 	printk(KERN_INFO " -S- IRQ status                   = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
@@ -523,7 +523,7 @@
 	}
 }
 
-void snd_gf1_peek_print_block(snd_gus_card_t * gus, unsigned int addr, int count, int w_16bit)
+void snd_gf1_peek_print_block(struct snd_gus_card * gus, unsigned int addr, int count, int w_16bit)
 {
 	if (!w_16bit) {
 		while (count-- > 0)
diff --git a/sound/isa/gus/gus_irq.c b/sound/isa/gus/gus_irq.c
index 1e2a15e..c19ba29 100644
--- a/sound/isa/gus/gus_irq.c
+++ b/sound/isa/gus/gus_irq.c
@@ -32,7 +32,7 @@
 
 irqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	snd_gus_card_t * gus = dev_id;
+	struct snd_gus_card * gus = dev_id;
 	unsigned char status;
 	int loop = 100;
 	int handled = 0;
@@ -54,7 +54,7 @@
 	if (status & (0x20 | 0x40)) {
 		unsigned int already, _current_;
 		unsigned char voice_status, voice;
-		snd_gus_voice_t *pvoice;
+		struct snd_gus_voice *pvoice;
 
 		already = 0;
 		while (((voice_status = snd_gf1_i_read8(gus, SNDRV_GF1_GB_VOICES_IRQ)) & 0xc0) != 0xc0) {
@@ -107,11 +107,11 @@
 }
 
 #ifdef CONFIG_SND_DEBUG
-static void snd_gus_irq_info_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_gus_irq_info_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
-	snd_gus_card_t *gus;
-	snd_gus_voice_t *pvoice;
+	struct snd_gus_card *gus;
+	struct snd_gus_voice *pvoice;
 	int idx;
 
 	gus = entry->private_data;
@@ -131,9 +131,9 @@
 	}
 }
 
-void snd_gus_irq_profile_init(snd_gus_card_t *gus)
+void snd_gus_irq_profile_init(struct snd_gus_card *gus)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(gus->card, "gusirq", &entry))
 		snd_info_set_text_ops(entry, gus, 1024, snd_gus_irq_info_read);
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c
index 4f57ff4..6d15b3d 100644
--- a/sound/isa/gus/gus_main.c
+++ b/sound/isa/gus/gus_main.c
@@ -35,21 +35,21 @@
 MODULE_DESCRIPTION("Routines for Gravis UltraSound soundcards");
 MODULE_LICENSE("GPL");
 
-static int snd_gus_init_dma_irq(snd_gus_card_t * gus, int latches);
+static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches);
 
-int snd_gus_use_inc(snd_gus_card_t * gus)
+int snd_gus_use_inc(struct snd_gus_card * gus)
 {
 	if (!try_module_get(gus->card->module))
 		return 0;
 	return 1;
 }
 
-void snd_gus_use_dec(snd_gus_card_t * gus)
+void snd_gus_use_dec(struct snd_gus_card * gus)
 {
 	module_put(gus->card->module);
 }
 
-static int snd_gus_joystick_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_gus_joystick_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -58,17 +58,17 @@
 	return 0;
 }
 
-static int snd_gus_joystick_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_gus_joystick_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol);
+	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = gus->joystick_dac & 31;
 	return 0;
 }
 
-static int snd_gus_joystick_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_gus_joystick_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol);
+	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned char nval;
@@ -82,7 +82,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_gus_joystick_control = {
+static struct snd_kcontrol_new snd_gus_joystick_control = {
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.name = "Joystick Speed",
 	.info = snd_gus_joystick_info,
@@ -90,7 +90,7 @@
 	.put = snd_gus_joystick_put
 };
 
-static void snd_gus_init_control(snd_gus_card_t *gus)
+static void snd_gus_init_control(struct snd_gus_card *gus)
 {
 	if (!gus->ace_flag)
 		snd_ctl_add(gus->card, snd_ctl_new1(&snd_gus_joystick_control, gus));
@@ -100,7 +100,7 @@
  *
  */
 
-static int snd_gus_free(snd_gus_card_t *gus)
+static int snd_gus_free(struct snd_gus_card *gus)
 {
 	if (gus->gf1.res_port2 == NULL)
 		goto __hw_end;
@@ -129,24 +129,24 @@
 	return 0;
 }
 
-static int snd_gus_dev_free(snd_device_t *device)
+static int snd_gus_dev_free(struct snd_device *device)
 {
-	snd_gus_card_t *gus = device->device_data;
+	struct snd_gus_card *gus = device->device_data;
 	return snd_gus_free(gus);
 }
 
-int snd_gus_create(snd_card_t * card,
+int snd_gus_create(struct snd_card *card,
 		   unsigned long port,
 		   int irq, int dma1, int dma2,
 		   int timer_dev,
 		   int voices,
 		   int pcm_channels,
 		   int effect,
-		   snd_gus_card_t **rgus)
+		   struct snd_gus_card **rgus)
 {
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_gus_dev_free,
 	};
 
@@ -238,7 +238,7 @@
  *  Memory detection routine for plain GF1 soundcards
  */
 
-static int snd_gus_detect_memory(snd_gus_card_t * gus)
+static int snd_gus_detect_memory(struct snd_gus_card * gus)
 {
 	int l, idx, local;
 	unsigned char d;
@@ -273,9 +273,9 @@
 	return 0;		/* some memory were detected */
 }
 
-static int snd_gus_init_dma_irq(snd_gus_card_t * gus, int latches)
+static int snd_gus_init_dma_irq(struct snd_gus_card * gus, int latches)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned long flags;
 	int irq, dma1, dma2;
 	static unsigned char irqs[16] =
@@ -360,11 +360,11 @@
 	return 0;
 }
 
-static int snd_gus_check_version(snd_gus_card_t * gus)
+static int snd_gus_check_version(struct snd_gus_card * gus)
 {
 	unsigned long flags;
 	unsigned char val, rev;
-	snd_card_t *card;
+	struct snd_card *card;
 
 	card = gus->card;
 	spin_lock_irqsave(&gus->reg_lock, flags);
@@ -409,14 +409,14 @@
 }
 
 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
-static void snd_gus_seq_dev_free(snd_seq_device_t *seq_dev)
+static void snd_gus_seq_dev_free(struct snd_seq_device *seq_dev)
 {
-	snd_gus_card_t *gus = seq_dev->private_data;
+	struct snd_gus_card *gus = seq_dev->private_data;
 	gus->seq_dev = NULL;
 }
 #endif
 
-int snd_gus_initialize(snd_gus_card_t *gus)
+int snd_gus_initialize(struct snd_gus_card *gus)
 {
 	int err;
 
@@ -432,9 +432,9 @@
 		return err;
 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
 	if (snd_seq_device_new(gus->card, 1, SNDRV_SEQ_DEV_ID_GUS,
-			       sizeof(snd_gus_card_t*), &gus->seq_dev) >= 0) {
+			       sizeof(struct snd_gus_card *), &gus->seq_dev) >= 0) {
 		strcpy(gus->seq_dev->name, "GUS");
-		*(snd_gus_card_t**)SNDRV_SEQ_DEVICE_ARGPTR(gus->seq_dev) = gus;
+		*(struct snd_gus_card **)SNDRV_SEQ_DEVICE_ARGPTR(gus->seq_dev) = gus;
 		gus->seq_dev->private_data = gus;
 		gus->seq_dev->private_free = snd_gus_seq_dev_free;
 	}
diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c
index 2e23f2a..e8bdb86 100644
--- a/sound/isa/gus/gus_mem.c
+++ b/sound/isa/gus/gus_mem.c
@@ -27,11 +27,11 @@
 #include <sound/info.h>
 
 #ifdef CONFIG_SND_DEBUG
-static void snd_gf1_mem_info_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer);
+static void snd_gf1_mem_info_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer);
 #endif
 
-void snd_gf1_mem_lock(snd_gf1_mem_t * alloc, int xup)
+void snd_gf1_mem_lock(struct snd_gf1_mem * alloc, int xup)
 {
 	if (!xup) {
 		down(&alloc->memory_mutex);
@@ -40,12 +40,12 @@
 	}
 }
 
-static snd_gf1_mem_block_t *snd_gf1_mem_xalloc(snd_gf1_mem_t * alloc,
-					       snd_gf1_mem_block_t * block)
+static struct snd_gf1_mem_block *snd_gf1_mem_xalloc(struct snd_gf1_mem * alloc,
+					       struct snd_gf1_mem_block * block)
 {
-	snd_gf1_mem_block_t *pblock, *nblock;
+	struct snd_gf1_mem_block *pblock, *nblock;
 
-	nblock = (snd_gf1_mem_block_t *) kmalloc(sizeof(snd_gf1_mem_block_t), GFP_KERNEL);
+	nblock = kmalloc(sizeof(struct snd_gf1_mem_block), GFP_KERNEL);
 	if (nblock == NULL)
 		return NULL;
 	*nblock = *block;
@@ -76,7 +76,7 @@
 	return nblock;
 }
 
-int snd_gf1_mem_xfree(snd_gf1_mem_t * alloc, snd_gf1_mem_block_t * block)
+int snd_gf1_mem_xfree(struct snd_gf1_mem * alloc, struct snd_gf1_mem_block * block)
 {
 	if (block->share) {	/* ok.. shared block */
 		block->share--;
@@ -106,10 +106,10 @@
 	return 0;
 }
 
-static snd_gf1_mem_block_t *snd_gf1_mem_look(snd_gf1_mem_t * alloc,
+static struct snd_gf1_mem_block *snd_gf1_mem_look(struct snd_gf1_mem * alloc,
 					     unsigned int address)
 {
-	snd_gf1_mem_block_t *block;
+	struct snd_gf1_mem_block *block;
 
 	for (block = alloc->first; block; block = block->next) {
 		if (block->ptr == address) {
@@ -119,10 +119,10 @@
 	return NULL;
 }
 
-static snd_gf1_mem_block_t *snd_gf1_mem_share(snd_gf1_mem_t * alloc,
+static struct snd_gf1_mem_block *snd_gf1_mem_share(struct snd_gf1_mem * alloc,
 					      unsigned int *share_id)
 {
-	snd_gf1_mem_block_t *block;
+	struct snd_gf1_mem_block *block;
 
 	if (!share_id[0] && !share_id[1] &&
 	    !share_id[2] && !share_id[3])
@@ -133,14 +133,14 @@
 	return NULL;
 }
 
-static int snd_gf1_mem_find(snd_gf1_mem_t * alloc,
-			    snd_gf1_mem_block_t * block,
+static int snd_gf1_mem_find(struct snd_gf1_mem * alloc,
+			    struct snd_gf1_mem_block * block,
 			    unsigned int size, int w_16, int align)
 {
-	snd_gf1_bank_info_t *info = w_16 ? alloc->banks_16 : alloc->banks_8;
+	struct snd_gf1_bank_info *info = w_16 ? alloc->banks_16 : alloc->banks_8;
 	unsigned int idx, boundary;
 	int size1;
-	snd_gf1_mem_block_t *pblock;
+	struct snd_gf1_mem_block *pblock;
 	unsigned int ptr1, ptr2;
 
 	align--;
@@ -186,11 +186,11 @@
 	return -ENOMEM;
 }
 
-snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner,
+struct snd_gf1_mem_block *snd_gf1_mem_alloc(struct snd_gf1_mem * alloc, int owner,
 				       char *name, int size, int w_16, int align,
 				       unsigned int *share_id)
 {
-	snd_gf1_mem_block_t block, *nblock;
+	struct snd_gf1_mem_block block, *nblock;
 
 	snd_gf1_mem_lock(alloc, 0);
 	if (share_id != NULL) {
@@ -220,10 +220,10 @@
 	return nblock;
 }
 
-int snd_gf1_mem_free(snd_gf1_mem_t * alloc, unsigned int address)
+int snd_gf1_mem_free(struct snd_gf1_mem * alloc, unsigned int address)
 {
 	int result;
-	snd_gf1_mem_block_t *block;
+	struct snd_gf1_mem_block *block;
 
 	snd_gf1_mem_lock(alloc, 0);
 	if ((block = snd_gf1_mem_look(alloc, address)) != NULL) {
@@ -235,12 +235,12 @@
 	return -EINVAL;
 }
 
-int snd_gf1_mem_init(snd_gus_card_t * gus)
+int snd_gf1_mem_init(struct snd_gus_card * gus)
 {
-	snd_gf1_mem_t *alloc;
-	snd_gf1_mem_block_t block;
+	struct snd_gf1_mem *alloc;
+	struct snd_gf1_mem_block block;
 #ifdef CONFIG_SND_DEBUG
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 #endif
 
 	alloc = &gus->gf1.mem_alloc;
@@ -272,10 +272,10 @@
 	return 0;
 }
 
-int snd_gf1_mem_done(snd_gus_card_t * gus)
+int snd_gf1_mem_done(struct snd_gus_card * gus)
 {
-	snd_gf1_mem_t *alloc;
-	snd_gf1_mem_block_t *block, *nblock;
+	struct snd_gf1_mem *alloc;
+	struct snd_gf1_mem_block *block, *nblock;
 
 	alloc = &gus->gf1.mem_alloc;
 	block = alloc->first;
@@ -288,12 +288,12 @@
 }
 
 #ifdef CONFIG_SND_DEBUG
-static void snd_gf1_mem_info_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_gf1_mem_info_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
-	snd_gus_card_t *gus;
-	snd_gf1_mem_t *alloc;
-	snd_gf1_mem_block_t *block;
+	struct snd_gus_card *gus;
+	struct snd_gf1_mem *alloc;
+	struct snd_gf1_mem_block *block;
 	unsigned int total, used;
 	int i;
 
diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c
index 7f96ac2..4080255 100644
--- a/sound/isa/gus/gus_mem_proc.c
+++ b/sound/isa/gus/gus_mem_proc.c
@@ -25,20 +25,20 @@
 #include <sound/gus.h>
 #include <sound/info.h>
 
-typedef struct gus_proc_private {
+struct gus_proc_private {
 	int rom;		/* data are in ROM */
 	unsigned int address;
 	unsigned int size;
-	snd_gus_card_t * gus;
-} gus_proc_private_t;
+	struct snd_gus_card * gus;
+};
 
-static long snd_gf1_mem_proc_dump(snd_info_entry_t *entry, void *file_private_data,
+static long snd_gf1_mem_proc_dump(struct snd_info_entry *entry, void *file_private_data,
 			          struct file *file, char __user *buf,
 			          unsigned long count, unsigned long pos)
 {
 	long size;
-	gus_proc_private_t *priv = entry->private_data;
-	snd_gus_card_t *gus = priv->gus;
+	struct gus_proc_private *priv = entry->private_data;
+	struct snd_gus_card *gus = priv->gus;
 	int err;
 
 	size = count;
@@ -52,13 +52,13 @@
 	return 0;
 }			
 
-static long long snd_gf1_mem_proc_llseek(snd_info_entry_t *entry,
+static long long snd_gf1_mem_proc_llseek(struct snd_info_entry *entry,
 					void *private_file_data,
 					struct file *file,
 					long long offset,
 					int orig)
 {
-	gus_proc_private_t *priv = entry->private_data;
+	struct gus_proc_private *priv = entry->private_data;
 
 	switch (orig) {
 	case 0:	/* SEEK_SET */
@@ -78,9 +78,9 @@
 	return file->f_pos;
 }
 
-static void snd_gf1_mem_proc_free(snd_info_entry_t *entry)
+static void snd_gf1_mem_proc_free(struct snd_info_entry *entry)
 {
-	gus_proc_private_t *priv = entry->private_data;
+	struct gus_proc_private *priv = entry->private_data;
 	kfree(priv);
 }
 
@@ -89,12 +89,12 @@
 	.llseek = snd_gf1_mem_proc_llseek,
 };
 
-int snd_gf1_mem_proc_init(snd_gus_card_t * gus)
+int snd_gf1_mem_proc_init(struct snd_gus_card * gus)
 {
 	int idx;
 	char name[16];
-	gus_proc_private_t *priv;
-	snd_info_entry_t *entry;
+	struct gus_proc_private *priv;
+	struct snd_info_entry *entry;
 
 	for (idx = 0; idx < 4; idx++) {
 		if (gus->gf1.mem_alloc.banks_8[idx].size > 0) {
diff --git a/sound/isa/gus/gus_mixer.c b/sound/isa/gus/gus_mixer.c
index a051094..acc25a2 100644
--- a/sound/isa/gus/gus_mixer.c
+++ b/sound/isa/gus/gus_mixer.c
@@ -36,7 +36,7 @@
   .get = snd_gf1_get_single, .put = snd_gf1_put_single, \
   .private_value = shift | (invert << 8) }
 
-static int snd_gf1_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_gf1_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -45,9 +45,9 @@
 	return 0;
 }
 
-static int snd_gf1_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_gf1_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol);
+	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value >> 8) & 1;
 	
@@ -57,9 +57,9 @@
 	return 0;
 }
 
-static int snd_gf1_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_gf1_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol);
+	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value >> 8) & 1;
@@ -86,7 +86,7 @@
   .get = snd_ics_get_double, .put = snd_ics_put_double, \
   .private_value = addr }
 
-static int snd_ics_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ics_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -95,9 +95,9 @@
 	return 0;
 }
 
-static int snd_ics_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ics_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol);
+	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int addr = kcontrol->private_value & 0xff;
 	unsigned char left, right;
@@ -111,9 +111,9 @@
 	return 0;
 }
 
-static int snd_ics_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ics_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol);
+	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int addr = kcontrol->private_value & 0xff;
 	int change;
@@ -146,13 +146,13 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_gf1_controls[] = {
+static struct snd_kcontrol_new snd_gf1_controls[] = {
 GF1_SINGLE("Master Playback Switch", 0, 1, 1),
 GF1_SINGLE("Line Switch", 0, 0, 1),
 GF1_SINGLE("Mic Switch", 0, 2, 0)
 };
 
-static snd_kcontrol_new_t snd_ics_controls[] = {
+static struct snd_kcontrol_new snd_ics_controls[] = {
 GF1_SINGLE("Master Playback Switch", 0, 1, 1),
 ICS_DOUBLE("Master Playback Volume", 0, SNDRV_ICS_MASTER_DEV),
 ICS_DOUBLE("Synth Playback Volume", 0, SNDRV_ICS_GF1_DEV),
@@ -163,9 +163,9 @@
 ICS_DOUBLE("CD Playback Volume", 0, SNDRV_ICS_CD_DEV)
 };
 
-int snd_gf1_new_mixer(snd_gus_card_t * gus)
+int snd_gf1_new_mixer(struct snd_gus_card * gus)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned int idx, max;
 	int err;
 
diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c
index 1cc89fb..d082939 100644
--- a/sound/isa/gus/gus_pcm.c
+++ b/sound/isa/gus/gus_pcm.c
@@ -42,12 +42,12 @@
 #define SNDRV_GF1_PCM_PFLG_ACTIVE	(1<<0)
 #define SNDRV_GF1_PCM_PFLG_NEUTRAL	(2<<0)
 
-typedef struct {
-	snd_gus_card_t * gus;
-	snd_pcm_substream_t * substream;
+struct gus_pcm_private {
+	struct snd_gus_card * gus;
+	struct snd_pcm_substream *substream;
 	spinlock_t lock;
 	unsigned int voices;
-	snd_gus_voice_t *pvoices[2];
+	struct snd_gus_voice *pvoices[2];
 	unsigned int memory;
 	unsigned short flags;
 	unsigned char voice_ctrl, ramp_ctrl;
@@ -58,13 +58,13 @@
 	wait_queue_head_t sleep;
 	atomic_t dma_count;
 	int final_volume;
-} gus_pcm_private_t;
+};
 
 static int snd_gf1_pcm_use_dma = 1;
 
-static void snd_gf1_pcm_block_change_ack(snd_gus_card_t * gus, void *private_data)
+static void snd_gf1_pcm_block_change_ack(struct snd_gus_card * gus, void *private_data)
 {
-	gus_pcm_private_t *pcmp = private_data;
+	struct gus_pcm_private *pcmp = private_data;
 
 	if (pcmp) {
 		atomic_dec(&pcmp->dma_count);
@@ -72,14 +72,14 @@
 	}
 }
 
-static int snd_gf1_pcm_block_change(snd_pcm_substream_t * substream,
+static int snd_gf1_pcm_block_change(struct snd_pcm_substream *substream,
 				    unsigned int offset,
 				    unsigned int addr,
 				    unsigned int count)
 {
-	snd_gf1_dma_block_t block;
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
+	struct snd_gf1_dma_block block;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
 
 	count += offset & 31;
 	offset &= ~31;
@@ -101,11 +101,11 @@
 	return 0;
 }
 
-static void snd_gf1_pcm_trigger_up(snd_pcm_substream_t * substream)
+static void snd_gf1_pcm_trigger_up(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
-	snd_gus_card_t * gus = pcmp->gus;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
+	struct snd_gus_card * gus = pcmp->gus;
 	unsigned long flags;
 	unsigned char voice_ctrl, ramp_ctrl;
 	unsigned short rate;
@@ -179,10 +179,11 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-static void snd_gf1_pcm_interrupt_wave(snd_gus_card_t * gus, snd_gus_voice_t *pvoice)
+static void snd_gf1_pcm_interrupt_wave(struct snd_gus_card * gus,
+				       struct snd_gus_voice *pvoice)
 {
-	gus_pcm_private_t * pcmp;
-	snd_pcm_runtime_t * runtime;
+	struct gus_pcm_private * pcmp;
+	struct snd_pcm_runtime *runtime;
 	unsigned char voice_ctrl, ramp_ctrl;
 	unsigned int idx;
 	unsigned int end, step;
@@ -261,11 +262,12 @@
 #endif
 }
 
-static void snd_gf1_pcm_interrupt_volume(snd_gus_card_t * gus, snd_gus_voice_t * pvoice)
+static void snd_gf1_pcm_interrupt_volume(struct snd_gus_card * gus,
+					 struct snd_gus_voice * pvoice)
 {
 	unsigned short vol;
 	int cvoice;
-	gus_pcm_private_t *pcmp = pvoice->private_data;
+	struct gus_pcm_private *pcmp = pvoice->private_data;
 
 	/* stop ramp, but leave rollover bit untouched */
 	spin_lock(&gus->reg_lock);
@@ -289,11 +291,11 @@
 	spin_unlock(&gus->reg_lock);
 }
 
-static void snd_gf1_pcm_volume_change(snd_gus_card_t * gus)
+static void snd_gf1_pcm_volume_change(struct snd_gus_card * gus)
 {
 }
 
-static int snd_gf1_pcm_poke_block(snd_gus_card_t *gus, unsigned char *buf,
+static int snd_gf1_pcm_poke_block(struct snd_gus_card *gus, unsigned char *buf,
 				  unsigned int pos, unsigned int count,
 				  int w16, int invert)
 {
@@ -341,14 +343,14 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_playback_copy(snd_pcm_substream_t *substream,
+static int snd_gf1_pcm_playback_copy(struct snd_pcm_substream *substream,
 				     int voice,
 				     snd_pcm_uframes_t pos,
 				     void __user *src,
 				     snd_pcm_uframes_t count)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
 	unsigned int bpos, len;
 	
 	bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2));
@@ -360,7 +362,7 @@
 	if (snd_gf1_pcm_use_dma && len > 32) {
 		return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len);
 	} else {
-		snd_gus_card_t *gus = pcmp->gus;
+		struct snd_gus_card *gus = pcmp->gus;
 		int err, w16, invert;
 
 		w16 = (snd_pcm_format_width(runtime->format) == 16);
@@ -371,13 +373,13 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_playback_silence(snd_pcm_substream_t *substream,
+static int snd_gf1_pcm_playback_silence(struct snd_pcm_substream *substream,
 					int voice,
 					snd_pcm_uframes_t pos,
 					snd_pcm_uframes_t count)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
 	unsigned int bpos, len;
 	
 	bpos = samples_to_bytes(runtime, pos) + (voice * (pcmp->dma_size / 2));
@@ -388,7 +390,7 @@
 	if (snd_gf1_pcm_use_dma && len > 32) {
 		return snd_gf1_pcm_block_change(substream, bpos, pcmp->memory + bpos, len);
 	} else {
-		snd_gus_card_t *gus = pcmp->gus;
+		struct snd_gus_card *gus = pcmp->gus;
 		int err, w16, invert;
 
 		w16 = (snd_pcm_format_width(runtime->format) == 16);
@@ -399,18 +401,18 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_playback_hw_params(snd_pcm_substream_t * substream,
-					  snd_pcm_hw_params_t * hw_params)
+static int snd_gf1_pcm_playback_hw_params(struct snd_pcm_substream *substream,
+					  struct snd_pcm_hw_params *hw_params)
 {
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
 	int err;
 	
 	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
 		return err;
 	if (err > 0) {	/* change */
-		snd_gf1_mem_block_t *block;
+		struct snd_gf1_mem_block *block;
 		if (pcmp->memory > 0) {
 			snd_gf1_mem_free(&gus->gf1.mem_alloc, pcmp->memory);
 			pcmp->memory = 0;
@@ -448,10 +450,10 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_playback_hw_free(snd_pcm_substream_t * substream)
+static int snd_gf1_pcm_playback_hw_free(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
 
 	snd_pcm_lib_free_pages(substream);
 	if (pcmp->pvoices[0]) {
@@ -469,10 +471,10 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_gf1_pcm_playback_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
 
 	pcmp->bpos = 0;
 	pcmp->dma_size = snd_pcm_lib_buffer_bytes(substream);
@@ -481,12 +483,12 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_gf1_pcm_playback_trigger(struct snd_pcm_substream *substream,
 					int cmd)
 {
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
 	int voice;
 
 	if (cmd == SNDRV_PCM_TRIGGER_START) {
@@ -507,11 +509,11 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_gf1_pcm_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_gf1_pcm_playback_pointer(struct snd_pcm_substream *substream)
 {
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
 	unsigned int pos;
 	unsigned char voice_ctrl;
 
@@ -529,22 +531,22 @@
 	return pos;
 }
 
-static ratnum_t clock = {
+static struct snd_ratnum clock = {
 	.num = 9878400/16,
 	.den_min = 2,
 	.den_max = 257,
 	.den_step = 1,
 };
 
-static snd_pcm_hw_constraint_ratnums_t hw_constraints_clocks  = {
+static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks  = {
 	.nrats = 1,
 	.rats = &clock,
 };
 
-static int snd_gf1_pcm_capture_hw_params(snd_pcm_substream_t * substream,
-					 snd_pcm_hw_params_t * hw_params)
+static int snd_gf1_pcm_capture_hw_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
 {
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
 
 	gus->c_dma_size = params_buffer_bytes(hw_params);
 	gus->c_period_size = params_period_bytes(hw_params);
@@ -559,15 +561,15 @@
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_gf1_pcm_capture_hw_free(snd_pcm_substream_t * substream)
+static int snd_gf1_pcm_capture_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_gf1_pcm_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_gf1_pcm_capture_prepare(struct snd_pcm_substream *substream)
 {
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_RECORD_RATE, runtime->rate_den - 2);
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL, 0);	/* disable sampling */
@@ -576,10 +578,10 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_gf1_pcm_capture_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
 	int val;
 	
 	if (cmd == SNDRV_PCM_TRIGGER_START) {
@@ -597,15 +599,15 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_gf1_pcm_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_gf1_pcm_capture_pointer(struct snd_pcm_substream *substream)
 {
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
 	int pos = snd_dma_pointer(gus->gf1.dma2, gus->c_period_size);
 	pos = bytes_to_frames(substream->runtime, (gus->c_pos + pos) % gus->c_dma_size);
 	return pos;
 }
 
-static void snd_gf1_pcm_interrupt_dma_read(snd_gus_card_t * gus)
+static void snd_gf1_pcm_interrupt_dma_read(struct snd_gus_card * gus)
 {
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL, 0);	/* disable sampling */
 	snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL);	/* Sampling Control Register */
@@ -617,7 +619,7 @@
 	}
 }
 
-static snd_pcm_hardware_t snd_gf1_pcm_playback =
+static struct snd_pcm_hardware snd_gf1_pcm_playback =
 {
 	.info =			SNDRV_PCM_INFO_NONINTERLEAVED,
 	.formats		= (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
@@ -635,7 +637,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_gf1_pcm_capture =
+static struct snd_pcm_hardware snd_gf1_pcm_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -653,16 +655,16 @@
 	.fifo_size =		0,
 };
 
-static void snd_gf1_pcm_playback_free(snd_pcm_runtime_t *runtime)
+static void snd_gf1_pcm_playback_free(struct snd_pcm_runtime *runtime)
 {
 	kfree(runtime->private_data);
 }
 
-static int snd_gf1_pcm_playback_open(snd_pcm_substream_t *substream)
+static int snd_gf1_pcm_playback_open(struct snd_pcm_substream *substream)
 {
-	gus_pcm_private_t *pcmp;
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp;
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	pcmp = kzalloc(sizeof(*pcmp), GFP_KERNEL);
@@ -690,11 +692,11 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_playback_close(snd_pcm_substream_t * substream)
+static int snd_gf1_pcm_playback_close(struct snd_pcm_substream *substream)
 {
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	gus_pcm_private_t *pcmp = runtime->private_data;
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct gus_pcm_private *pcmp = runtime->private_data;
 	
 	if (!wait_event_timeout(pcmp->sleep, (atomic_read(&pcmp->dma_count) <= 0), 2*HZ))
 		snd_printk(KERN_ERR "gf1 pcm - serious DMA problem\n");
@@ -703,10 +705,10 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_capture_open(snd_pcm_substream_t * substream)
+static int snd_gf1_pcm_capture_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
 
 	gus->gf1.interrupt_handler_dma_read = snd_gf1_pcm_interrupt_dma_read;
 	gus->pcm_cap_substream = substream;
@@ -718,23 +720,16 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_capture_close(snd_pcm_substream_t * substream)
+static int snd_gf1_pcm_capture_close(struct snd_pcm_substream *substream)
 {
-	snd_gus_card_t *gus = snd_pcm_substream_chip(substream);
+	struct snd_gus_card *gus = snd_pcm_substream_chip(substream);
 
 	gus->pcm_cap_substream = NULL;
 	snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_DMA_READ);
 	return 0;
 }
 
-static void snd_gf1_pcm_free(snd_pcm_t *pcm)
-{
-	snd_gus_card_t *gus = pcm->private_data;
-	gus->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int snd_gf1_pcm_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_gf1_pcm_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -743,9 +738,9 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_gf1_pcm_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol);
+	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&gus->pcm_volume_level_lock, flags);
@@ -755,15 +750,15 @@
 	return 0;
 }
 
-static int snd_gf1_pcm_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_gf1_pcm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_gus_card_t *gus = snd_kcontrol_chip(kcontrol);
+	struct snd_gus_card *gus = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned int idx;
 	unsigned short val1, val2, vol;
-	gus_pcm_private_t *pcmp;
-	snd_gus_voice_t *pvoice;
+	struct gus_pcm_private *pcmp;
+	struct snd_gus_voice *pvoice;
 	
 	val1 = ucontrol->value.integer.value[0] & 127;
 	val2 = ucontrol->value.integer.value[1] & 127;
@@ -797,7 +792,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_gf1_pcm_volume_control =
+static struct snd_kcontrol_new snd_gf1_pcm_volume_control =
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PCM Playback Volume",
@@ -806,7 +801,7 @@
 	.put = snd_gf1_pcm_volume_put
 };
 
-static snd_kcontrol_new_t snd_gf1_pcm_volume_control1 =
+static struct snd_kcontrol_new snd_gf1_pcm_volume_control1 =
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "GPCM Playback Volume",
@@ -815,7 +810,7 @@
 	.put = snd_gf1_pcm_volume_put
 };
 
-static snd_pcm_ops_t snd_gf1_pcm_playback_ops = {
+static struct snd_pcm_ops snd_gf1_pcm_playback_ops = {
 	.open =		snd_gf1_pcm_playback_open,
 	.close =	snd_gf1_pcm_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -828,7 +823,7 @@
 	.silence =	snd_gf1_pcm_playback_silence,
 };
 
-static snd_pcm_ops_t snd_gf1_pcm_capture_ops = {
+static struct snd_pcm_ops snd_gf1_pcm_capture_ops = {
 	.open =		snd_gf1_pcm_capture_open,
 	.close =	snd_gf1_pcm_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -839,12 +834,12 @@
 	.pointer =	snd_gf1_pcm_capture_pointer,
 };
 
-int snd_gf1_pcm_new(snd_gus_card_t * gus, int pcm_dev, int control_index, snd_pcm_t ** rpcm)
+int snd_gf1_pcm_new(struct snd_gus_card * gus, int pcm_dev, int control_index, struct snd_pcm ** rpcm)
 {
-	snd_card_t *card;
-	snd_kcontrol_t *kctl;
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *substream;
+	struct snd_card *card;
+	struct snd_kcontrol *kctl;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *substream;
 	int capture, err;
 
 	if (rpcm)
@@ -860,7 +855,6 @@
 	if (err < 0)
 		return err;
 	pcm->private_data = gus;
-	pcm->private_free = snd_gf1_pcm_free;
 	/* playback setup */
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_gf1_pcm_playback_ops);
 
diff --git a/sound/isa/gus/gus_reset.c b/sound/isa/gus/gus_reset.c
index 9071096..b263655 100644
--- a/sound/isa/gus/gus_reset.c
+++ b/sound/isa/gus/gus_reset.c
@@ -25,52 +25,52 @@
 #include <sound/core.h>
 #include <sound/gus.h>
 
-extern void snd_gf1_timers_init(snd_gus_card_t * gus);
-extern void snd_gf1_timers_done(snd_gus_card_t * gus);
-extern int snd_gf1_synth_init(snd_gus_card_t * gus);
-extern void snd_gf1_synth_done(snd_gus_card_t * gus);
+extern void snd_gf1_timers_init(struct snd_gus_card * gus);
+extern void snd_gf1_timers_done(struct snd_gus_card * gus);
+extern int snd_gf1_synth_init(struct snd_gus_card * gus);
+extern void snd_gf1_synth_done(struct snd_gus_card * gus);
 
 /*
  *  ok.. default interrupt handlers...
  */
 
-static void snd_gf1_default_interrupt_handler_midi_out(snd_gus_card_t * gus)
+static void snd_gf1_default_interrupt_handler_midi_out(struct snd_gus_card * gus)
 {
 	snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd &= ~0x20);
 }
 
-static void snd_gf1_default_interrupt_handler_midi_in(snd_gus_card_t * gus)
+static void snd_gf1_default_interrupt_handler_midi_in(struct snd_gus_card * gus)
 {
 	snd_gf1_uart_cmd(gus, gus->gf1.uart_cmd &= ~0x80);
 }
 
-static void snd_gf1_default_interrupt_handler_timer1(snd_gus_card_t * gus)
+static void snd_gf1_default_interrupt_handler_timer1(struct snd_gus_card * gus)
 {
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, gus->gf1.timer_enabled &= ~4);
 }
 
-static void snd_gf1_default_interrupt_handler_timer2(snd_gus_card_t * gus)
+static void snd_gf1_default_interrupt_handler_timer2(struct snd_gus_card * gus)
 {
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, gus->gf1.timer_enabled &= ~8);
 }
 
-static void snd_gf1_default_interrupt_handler_wave_and_volume(snd_gus_card_t * gus, snd_gus_voice_t * voice)
+static void snd_gf1_default_interrupt_handler_wave_and_volume(struct snd_gus_card * gus, struct snd_gus_voice * voice)
 {
 	snd_gf1_i_ctrl_stop(gus, 0x00);
 	snd_gf1_i_ctrl_stop(gus, 0x0d);
 }
 
-static void snd_gf1_default_interrupt_handler_dma_write(snd_gus_card_t * gus)
+static void snd_gf1_default_interrupt_handler_dma_write(struct snd_gus_card * gus)
 {
 	snd_gf1_i_write8(gus, 0x41, 0x00);
 }
 
-static void snd_gf1_default_interrupt_handler_dma_read(snd_gus_card_t * gus)
+static void snd_gf1_default_interrupt_handler_dma_read(struct snd_gus_card * gus)
 {
 	snd_gf1_i_write8(gus, 0x49, 0x00);
 }
 
-void snd_gf1_set_default_handlers(snd_gus_card_t * gus, unsigned int what)
+void snd_gf1_set_default_handlers(struct snd_gus_card * gus, unsigned int what)
 {
 	if (what & SNDRV_GF1_HANDLER_MIDI_OUT)
 		gus->gf1.interrupt_handler_midi_out = snd_gf1_default_interrupt_handler_midi_out;
@@ -81,7 +81,7 @@
 	if (what & SNDRV_GF1_HANDLER_TIMER2)
 		gus->gf1.interrupt_handler_timer2 = snd_gf1_default_interrupt_handler_timer2;
 	if (what & SNDRV_GF1_HANDLER_VOICE) {
-		snd_gus_voice_t *voice;
+		struct snd_gus_voice *voice;
 		
 		voice = &gus->gf1.voices[what & 0xffff];
 		voice->handler_wave =
@@ -99,7 +99,7 @@
 
  */
 
-static void snd_gf1_clear_regs(snd_gus_card_t * gus)
+static void snd_gf1_clear_regs(struct snd_gus_card * gus)
 {
 	unsigned long flags;
 
@@ -111,7 +111,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-static void snd_gf1_look_regs(snd_gus_card_t * gus)
+static void snd_gf1_look_regs(struct snd_gus_card * gus)
 {
 	unsigned long flags;
 
@@ -127,7 +127,7 @@
  *  put selected GF1 voices to initial stage...
  */
 
-void snd_gf1_smart_stop_voice(snd_gus_card_t * gus, unsigned short voice)
+void snd_gf1_smart_stop_voice(struct snd_gus_card * gus, unsigned short voice)
 {
 	unsigned long flags;
 
@@ -141,7 +141,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-void snd_gf1_stop_voice(snd_gus_card_t * gus, unsigned short voice)
+void snd_gf1_stop_voice(struct snd_gus_card * gus, unsigned short voice)
 {
 	unsigned long flags;
 
@@ -161,7 +161,7 @@
 #endif
 }
 
-static void snd_gf1_clear_voices(snd_gus_card_t * gus, unsigned short v_min,
+static void snd_gf1_clear_voices(struct snd_gus_card * gus, unsigned short v_min,
 				 unsigned short v_max)
 {
 	unsigned long flags;
@@ -203,7 +203,7 @@
 	}
 }
 
-void snd_gf1_stop_voices(snd_gus_card_t * gus, unsigned short v_min, unsigned short v_max)
+void snd_gf1_stop_voices(struct snd_gus_card * gus, unsigned short v_min, unsigned short v_max)
 {
 	unsigned long flags;
 	short i, ramp_ok;
@@ -232,8 +232,8 @@
 	snd_gf1_clear_voices(gus, v_min, v_max);
 }
 
-static void snd_gf1_alloc_voice_use(snd_gus_card_t * gus, 
-				    snd_gus_voice_t * pvoice,
+static void snd_gf1_alloc_voice_use(struct snd_gus_card * gus, 
+				    struct snd_gus_voice * pvoice,
 				    int type, int client, int port)
 {
 	pvoice->use = 1;
@@ -255,9 +255,9 @@
 	}
 }
 
-snd_gus_voice_t *snd_gf1_alloc_voice(snd_gus_card_t * gus, int type, int client, int port)
+struct snd_gus_voice *snd_gf1_alloc_voice(struct snd_gus_card * gus, int type, int client, int port)
 {
-	snd_gus_voice_t *pvoice;
+	struct snd_gus_voice *pvoice;
 	unsigned long flags;
 	int idx;
 
@@ -289,10 +289,10 @@
 	return NULL;
 }
 
-void snd_gf1_free_voice(snd_gus_card_t * gus, snd_gus_voice_t *voice)
+void snd_gf1_free_voice(struct snd_gus_card * gus, struct snd_gus_voice *voice)
 {
 	unsigned long flags;
-	void (*private_free)(snd_gus_voice_t *voice);
+	void (*private_free)(struct snd_gus_voice *voice);
 	void *private_data;
 
 	if (voice == NULL || !voice->use)
@@ -317,7 +317,7 @@
  *  call this function only by start of driver
  */
 
-int snd_gf1_start(snd_gus_card_t * gus)
+int snd_gf1_start(struct snd_gus_card * gus)
 {
 	unsigned long flags;
 	unsigned int i;
@@ -400,7 +400,7 @@
  *  call this function only by shutdown of driver
  */
 
-int snd_gf1_stop(snd_gus_card_t * gus)
+int snd_gf1_stop(struct snd_gus_card * gus)
 {
 	snd_gf1_i_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, 0); /* stop all timers */
 	snd_gf1_stop_voices(gus, 0, 31);		/* stop all voices */
diff --git a/sound/isa/gus/gus_sample.c b/sound/isa/gus/gus_sample.c
index 4290e03..9e0c55a 100644
--- a/sound/isa/gus/gus_sample.c
+++ b/sound/isa/gus/gus_sample.c
@@ -28,9 +28,9 @@
  *
  */
 
-static void select_instrument(snd_gus_card_t * gus, snd_gus_voice_t * v)
+static void select_instrument(struct snd_gus_card * gus, struct snd_gus_voice * v)
 {
-	snd_seq_kinstr_t *instr;
+	struct snd_seq_kinstr *instr;
 
 #if 0
 	printk("select instrument: cluster = %li, std = 0x%x, bank = %i, prg = %i\n",
@@ -53,7 +53,8 @@
  *
  */
 
-static void event_sample(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v)
+static void event_sample(struct snd_seq_event *ev, struct snd_gus_port *p,
+			 struct snd_gus_voice *v)
 {
 	if (v->sample_ops && v->sample_ops->sample_stop)
 		v->sample_ops->sample_stop(p->gus, v, SAMPLE_STOP_IMMEDIATELY);
@@ -67,7 +68,8 @@
 	select_instrument(p->gus, v);
 }
 
-static void event_cluster(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v)
+static void event_cluster(struct snd_seq_event *ev, struct snd_gus_port *p,
+			  struct snd_gus_voice *v)
 {
 	if (v->sample_ops && v->sample_ops->sample_stop)
 		v->sample_ops->sample_stop(p->gus, v, SAMPLE_STOP_IMMEDIATELY);
@@ -75,50 +77,58 @@
 	select_instrument(p->gus, v);
 }
 
-static void event_start(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v)
+static void event_start(struct snd_seq_event *ev, struct snd_gus_port *p,
+			struct snd_gus_voice *v)
 {
 	if (v->sample_ops && v->sample_ops->sample_start)
 		v->sample_ops->sample_start(p->gus, v, ev->data.sample.param.position);
 }
 
-static void event_stop(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v)
+static void event_stop(struct snd_seq_event *ev, struct snd_gus_port *p,
+		       struct snd_gus_voice *v)
 {
 	if (v->sample_ops && v->sample_ops->sample_stop)
 		v->sample_ops->sample_stop(p->gus, v, ev->data.sample.param.stop_mode);
 }
 
-static void event_freq(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v)
+static void event_freq(struct snd_seq_event *ev, struct snd_gus_port *p,
+		       struct snd_gus_voice *v)
 {
 	if (v->sample_ops && v->sample_ops->sample_freq)
 		v->sample_ops->sample_freq(p->gus, v, ev->data.sample.param.frequency);
 }
 
-static void event_volume(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v)
+static void event_volume(struct snd_seq_event *ev, struct snd_gus_port *p,
+			 struct snd_gus_voice *v)
 {
 	if (v->sample_ops && v->sample_ops->sample_volume)
 		v->sample_ops->sample_volume(p->gus, v, &ev->data.sample.param.volume);
 }
 
-static void event_loop(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v)
+static void event_loop(struct snd_seq_event *ev, struct snd_gus_port *p,
+		       struct snd_gus_voice *v)
 {
 	if (v->sample_ops && v->sample_ops->sample_loop)
 		v->sample_ops->sample_loop(p->gus, v, &ev->data.sample.param.loop);
 }
 
-static void event_position(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v)
+static void event_position(struct snd_seq_event *ev, struct snd_gus_port *p,
+			   struct snd_gus_voice *v)
 {
 	if (v->sample_ops && v->sample_ops->sample_pos)
 		v->sample_ops->sample_pos(p->gus, v, ev->data.sample.param.position);
 }
 
-static void event_private1(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v)
+static void event_private1(struct snd_seq_event *ev, struct snd_gus_port *p,
+			   struct snd_gus_voice *v)
 {
 	if (v->sample_ops && v->sample_ops->sample_private1)
 		v->sample_ops->sample_private1(p->gus, v, (unsigned char *)&ev->data.sample.param.raw8);
 }
 
-typedef void (gus_sample_event_handler_t)(snd_seq_event_t *ev, snd_gus_port_t *p, snd_gus_voice_t *v);
-
+typedef void (gus_sample_event_handler_t)(struct snd_seq_event *ev,
+					  struct snd_gus_port *p,
+					  struct snd_gus_voice *v);
 static gus_sample_event_handler_t *gus_sample_event_handlers[9] = {
 	event_sample,
 	event_cluster,
@@ -131,11 +141,11 @@
 	event_private1
 };
 
-void snd_gus_sample_event(snd_seq_event_t *ev, snd_gus_port_t *p)
+void snd_gus_sample_event(struct snd_seq_event *ev, struct snd_gus_port *p)
 {
 	int idx, voice;
-	snd_gus_card_t *gus = p->gus;
-	snd_gus_voice_t *v;
+	struct snd_gus_card *gus = p->gus;
+	struct snd_gus_voice *v;
 	unsigned long flags;
 	
 	idx = ev->type - SNDRV_SEQ_EVENT_SAMPLE;
diff --git a/sound/isa/gus/gus_simple.c b/sound/isa/gus/gus_simple.c
index dfed85b..dcad6ed 100644
--- a/sound/isa/gus/gus_simple.c
+++ b/sound/isa/gus/gus_simple.c
@@ -29,19 +29,19 @@
  *
  */
 
-static void interrupt_wave(snd_gus_card_t *gus, snd_gus_voice_t *voice);
-static void interrupt_volume(snd_gus_card_t *gus, snd_gus_voice_t *voice);
-static void interrupt_effect(snd_gus_card_t *gus, snd_gus_voice_t *voice);
+static void interrupt_wave(struct snd_gus_card *gus, struct snd_gus_voice *voice);
+static void interrupt_volume(struct snd_gus_card *gus, struct snd_gus_voice *voice);
+static void interrupt_effect(struct snd_gus_card *gus, struct snd_gus_voice *voice);
 
-static void sample_start(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_position_t position);
-static void sample_stop(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_stop_mode_t mode);
-static void sample_freq(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_frequency_t freq);
-static void sample_volume(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_ev_volume_t *volume);
-static void sample_loop(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_ev_loop_t *loop);
-static void sample_pos(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_position_t position);
-static void sample_private1(snd_gus_card_t *card, snd_gus_voice_t *voice, unsigned char *data);
+static void sample_start(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_position_t position);
+static void sample_stop(struct snd_gus_card *gus, struct snd_gus_voice *voice, int mode);
+static void sample_freq(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_frequency_t freq);
+static void sample_volume(struct snd_gus_card *card, struct snd_gus_voice *voice, struct snd_seq_ev_volume *volume);
+static void sample_loop(struct snd_gus_card *card, struct snd_gus_voice *voice, struct snd_seq_ev_loop *loop);
+static void sample_pos(struct snd_gus_card *card, struct snd_gus_voice *voice, snd_seq_position_t position);
+static void sample_private1(struct snd_gus_card *card, struct snd_gus_voice *voice, unsigned char *data);
 
-static snd_gus_sample_ops_t sample_ops = {
+static struct snd_gus_sample_ops sample_ops = {
 	sample_start,
 	sample_stop,
 	sample_freq,
@@ -53,13 +53,13 @@
 
 #if 0
 
-static void note_stop(snd_gus_card_t *gus, snd_gus_voice_t *voice, int wait);
-static void note_wait(snd_gus_card_t *gus, snd_gus_voice_t *voice);
-static void note_off(snd_gus_card_t *gus, snd_gus_voice_t *voice);
-static void note_volume(snd_gus_card_t *card, snd_gus_voice_t *voice);
-static void note_pitchbend(snd_gus_card_t *card, snd_gus_voice_t *voice);
-static void note_vibrato(snd_gus_card_t *card, snd_gus_voice_t *voice);
-static void note_tremolo(snd_gus_card_t *card, snd_gus_voice_t *voice);
+static void note_stop(struct snd_gus_card *gus, struct snd_gus_voice *voice, int wait);
+static void note_wait(struct snd_gus_card *gus, struct snd_gus_voice *voice);
+static void note_off(struct snd_gus_card *gus, struct snd_gus_voice *voice);
+static void note_volume(struct snd_gus_card *card, struct snd_gus_voice *voice);
+static void note_pitchbend(struct snd_gus_card *card, struct snd_gus_voice *voice);
+static void note_vibrato(struct snd_gus_card *card, struct snd_gus_voice *voice);
+static void note_tremolo(struct snd_gus_card *card, struct snd_gus_voice *voice);
 
 static struct snd_gus_note_handlers note_commands = {
 	note_stop,
@@ -71,7 +71,7 @@
 	note_tremolo
 };
 
-static void chn_trigger_down(snd_gus_card_t *card, ultra_channel_t *channel, ultra_instrument_t *instrument, unsigned char note, unsigned char velocity, unsigned char priority );
+static void chn_trigger_down(struct snd_gus_card *card, ultra_channel_t *channel, ultra_instrument_t *instrument, unsigned char note, unsigned char velocity, unsigned char priority );
 static void chn_trigger_up( ultra_card_t *card, ultra_note_t *note );
 static void chn_control( ultra_card_t *card, ultra_channel_t *channel, unsigned short p1, unsigned short p2 );
 
@@ -83,14 +83,14 @@
 
 #endif
 
-static void do_volume_envelope(snd_gus_card_t *card, snd_gus_voice_t *voice);
-static void do_pan_envelope(snd_gus_card_t *card, snd_gus_voice_t *voice);
+static void do_volume_envelope(struct snd_gus_card *card, struct snd_gus_voice *voice);
+static void do_pan_envelope(struct snd_gus_card *card, struct snd_gus_voice *voice);
 
 /*
  *
  */
 
-static void interrupt_wave(snd_gus_card_t *gus, snd_gus_voice_t *voice)
+static void interrupt_wave(struct snd_gus_card *gus, struct snd_gus_voice *voice)
 {
 	spin_lock(&gus->event_lock);
 	snd_gf1_stop_voice(gus, voice->number);
@@ -102,7 +102,7 @@
 	spin_unlock(&gus->event_lock);
 }
 
-static void interrupt_volume(snd_gus_card_t *gus, snd_gus_voice_t *voice)
+static void interrupt_volume(struct snd_gus_card *gus, struct snd_gus_voice *voice)
 {
 	spin_lock(&gus->event_lock);
 	if (voice->flags & SNDRV_GF1_VFLG_RUNNING)
@@ -112,7 +112,7 @@
 	spin_unlock(&gus->event_lock);
 }
 
-static void interrupt_effect(snd_gus_card_t *gus, snd_gus_voice_t *voice)
+static void interrupt_effect(struct snd_gus_card *gus, struct snd_gus_voice *voice)
 {
 	spin_lock(&gus->event_lock);
 	if ((voice->flags & (SNDRV_GF1_VFLG_RUNNING|SNDRV_GF1_VFLG_EFFECT_TIMER1)) ==
@@ -125,7 +125,7 @@
  *
  */
 
-static void do_volume_envelope(snd_gus_card_t *gus, snd_gus_voice_t *voice)
+static void do_volume_envelope(struct snd_gus_card *gus, struct snd_gus_voice *voice)
 {
 	unsigned short next, rate, old_volume;
 	int program_next_ramp;
@@ -229,7 +229,7 @@
 	}
 }
 
-static void do_pan_envelope(snd_gus_card_t *gus, snd_gus_voice_t *voice)
+static void do_pan_envelope(struct snd_gus_card *gus, struct snd_gus_voice *voice)
 {
 	unsigned long flags;
 	unsigned char old_pan;
@@ -276,7 +276,7 @@
 #endif
 }
 
-static void set_enhanced_pan(snd_gus_card_t *gus, snd_gus_voice_t *voice, unsigned short pan)
+static void set_enhanced_pan(struct snd_gus_card *gus, struct snd_gus_voice *voice, unsigned short pan)
 {
 	unsigned long flags;
 	unsigned short vlo, vro;
@@ -307,13 +307,13 @@
  *
  */
 
-static void sample_start(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_position_t position)
+static void sample_start(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_position_t position)
 {
 	unsigned long flags;
 	unsigned int begin, addr, addr_end, addr_start;
 	int w_16;
-	simple_instrument_t *simple;
-	snd_seq_kinstr_t *instr;
+	struct simple_instrument *simple;
+	struct snd_seq_kinstr *instr;
 
 	instr = snd_seq_instr_find(gus->gf1.ilist, &voice->instr, 0, 1);
 	if (instr == NULL)
@@ -397,7 +397,7 @@
 	snd_seq_instr_free_use(gus->gf1.ilist, instr);
 }
 
-static void sample_stop(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_stop_mode_t mode)
+static void sample_stop(struct snd_gus_card *gus, struct snd_gus_voice *voice, int mode)
 {
 	unsigned char control;
 	unsigned long flags;
@@ -433,7 +433,7 @@
 	}
 }
 
-static void sample_freq(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_frequency_t freq)
+static void sample_freq(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_frequency_t freq)
 {
 	unsigned long flags;
 
@@ -444,7 +444,7 @@
 	spin_unlock_irqrestore(&gus->reg_lock, flags);
 }
 
-static void sample_volume(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_ev_volume_t *volume)
+static void sample_volume(struct snd_gus_card *gus, struct snd_gus_voice *voice, struct snd_seq_ev_volume *volume)
 {
 	if (volume->volume >= 0) {
 		volume->volume &= 0x3fff;
@@ -471,13 +471,13 @@
 	}
 }
 
-static void sample_loop(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_ev_loop_t *loop)
+static void sample_loop(struct snd_gus_card *gus, struct snd_gus_voice *voice, struct snd_seq_ev_loop *loop)
 {
 	unsigned long flags;
 	int w_16 = voice->control & 0x04;
 	unsigned int begin, addr_start, addr_end;
-	simple_instrument_t *simple;
-	snd_seq_kinstr_t *instr;
+	struct simple_instrument *simple;
+	struct snd_seq_kinstr *instr;
 
 #if 0
 	printk("voice_loop: start = 0x%x, end = 0x%x\n", loop->start, loop->end);
@@ -500,13 +500,13 @@
 	snd_seq_instr_free_use(gus->gf1.ilist, instr);
 }
 
-static void sample_pos(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_position_t position)
+static void sample_pos(struct snd_gus_card *gus, struct snd_gus_voice *voice, snd_seq_position_t position)
 {
 	unsigned long flags;
 	int w_16 = voice->control & 0x04;
 	unsigned int begin, addr;
-	simple_instrument_t *simple;
-	snd_seq_kinstr_t *instr;
+	struct simple_instrument *simple;
+	struct snd_seq_kinstr *instr;
 
 #if 0
 	printk("voice_loop: start = 0x%x, end = 0x%x\n", loop->start, loop->end);
@@ -537,7 +537,7 @@
 
 #endif
 
-static void sample_private1(snd_gus_card_t *card, snd_gus_voice_t *voice, unsigned char *data)
+static void sample_private1(struct snd_gus_card *card, struct snd_gus_voice *voice, unsigned char *data)
 {
 #if 0
   unsigned long flags;
@@ -624,7 +624,7 @@
  
 #endif
 
-void snd_gf1_simple_init(snd_gus_voice_t *voice)
+void snd_gf1_simple_init(struct snd_gus_voice *voice)
 {
 	voice->handler_wave = interrupt_wave;
 	voice->handler_volume = interrupt_volume;
diff --git a/sound/isa/gus/gus_synth.c b/sound/isa/gus/gus_synth.c
index f51c386..85a1b05 100644
--- a/sound/isa/gus/gus_synth.c
+++ b/sound/isa/gus/gus_synth.c
@@ -34,10 +34,10 @@
  *
  */
 
-static void snd_gus_synth_free_voices(snd_gus_card_t * gus, int client, int port)
+static void snd_gus_synth_free_voices(struct snd_gus_card * gus, int client, int port)
 {
 	int idx;
-	snd_gus_voice_t * voice;
+	struct snd_gus_voice * voice;
 	
 	for (idx = 0; idx < 32; idx++) {
 		voice = &gus->gf1.voices[idx];
@@ -46,11 +46,11 @@
 	}
 }
 
-static int snd_gus_synth_use(void *private_data, snd_seq_port_subscribe_t *info)
+static int snd_gus_synth_use(void *private_data, struct snd_seq_port_subscribe *info)
 {
-	snd_gus_port_t * port = (snd_gus_port_t *)private_data;
-	snd_gus_card_t * gus = port->gus;
-	snd_gus_voice_t * voice;
+	struct snd_gus_port * port = private_data;
+	struct snd_gus_card * gus = port->gus;
+	struct snd_gus_voice * voice;
 	unsigned int idx;
 
 	if (info->voices > 32)
@@ -74,10 +74,10 @@
 	return 0;
 }
 
-static int snd_gus_synth_unuse(void *private_data, snd_seq_port_subscribe_t *info)
+static int snd_gus_synth_unuse(void *private_data, struct snd_seq_port_subscribe *info)
 {
-	snd_gus_port_t * port = (snd_gus_port_t *)private_data;
-	snd_gus_card_t * gus = port->gus;
+	struct snd_gus_port * port = private_data;
+	struct snd_gus_card * gus = port->gus;
 
 	down(&gus->register_mutex);
 	snd_gus_synth_free_voices(gus, info->sender.client, info->sender.port);
@@ -90,19 +90,19 @@
  *
  */
 
-static void snd_gus_synth_free_private_instruments(snd_gus_port_t *p, int client)
+static void snd_gus_synth_free_private_instruments(struct snd_gus_port *p, int client)
 {
-	snd_seq_instr_header_t ifree;
+	struct snd_seq_instr_header ifree;
 
 	memset(&ifree, 0, sizeof(ifree));
 	ifree.cmd = SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE;
 	snd_seq_instr_list_free_cond(p->gus->gf1.ilist, &ifree, client, 0);
 }
  
-static int snd_gus_synth_event_input(snd_seq_event_t *ev, int direct,
+static int snd_gus_synth_event_input(struct snd_seq_event *ev, int direct,
 				     void *private_data, int atomic, int hop)
 {
-	snd_gus_port_t * p = (snd_gus_port_t *) private_data;
+	struct snd_gus_port * p = private_data;
 	
 	snd_assert(p != NULL, return -EINVAL);
 	if (ev->type >= SNDRV_SEQ_EVENT_SAMPLE &&
@@ -131,12 +131,12 @@
 }
 
 static void snd_gus_synth_instr_notify(void *private_data,
-				       snd_seq_kinstr_t *instr,
+				       struct snd_seq_kinstr *instr,
 				       int what)
 {
 	unsigned int idx;
-	snd_gus_card_t *gus = private_data;
-	snd_gus_voice_t *pvoice;
+	struct snd_gus_card *gus = private_data;
+	struct snd_gus_voice *pvoice;
 	unsigned long flags;
 	
 	spin_lock_irqsave(&gus->event_lock, flags);
@@ -160,16 +160,16 @@
 
 static void snd_gus_synth_free_port(void *private_data)
 {
-	snd_gus_port_t * p = (snd_gus_port_t *)private_data;
+	struct snd_gus_port * p = private_data;
 	
 	if (p)
 		snd_midi_channel_free_set(p->chset);
 }
 
-static int snd_gus_synth_create_port(snd_gus_card_t * gus, int idx)
+static int snd_gus_synth_create_port(struct snd_gus_card * gus, int idx)
 {
-	snd_gus_port_t * p;
-	snd_seq_port_callback_t callbacks;
+	struct snd_gus_port * p;
+	struct snd_seq_port_callback callbacks;
 	char name[32];
 	int result;
 	
@@ -210,46 +210,28 @@
  *
  */
 
-static int snd_gus_synth_new_device(snd_seq_device_t *dev)
+static int snd_gus_synth_new_device(struct snd_seq_device *dev)
 {
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 	int client, i;
-	snd_seq_client_callback_t callbacks;
-	snd_seq_client_info_t *cinfo;
-	snd_seq_port_subscribe_t sub;
-	snd_iwffff_ops_t *iwops;
-	snd_gf1_ops_t *gf1ops;
-	snd_simple_ops_t *simpleops;
+	struct snd_seq_port_subscribe sub;
+	struct snd_iwffff_ops *iwops;
+	struct snd_gf1_ops *gf1ops;
+	struct snd_simple_ops *simpleops;
 
-	gus = *(snd_gus_card_t**)SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	gus = *(struct snd_gus_card **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	if (gus == NULL)
 		return -EINVAL;
 
 	init_MUTEX(&gus->register_mutex);
 	gus->gf1.seq_client = -1;
 	
-	cinfo = kmalloc(sizeof(*cinfo), GFP_KERNEL);
-	if (! cinfo)
-		return -ENOMEM;
-
 	/* allocate new client */
-	memset(&callbacks, 0, sizeof(callbacks));
-	callbacks.private_data = gus;
-	callbacks.allow_output = callbacks.allow_input = 1;
 	client = gus->gf1.seq_client =
-			snd_seq_create_kernel_client(gus->card, 1, &callbacks);
-	if (client < 0) {
-		kfree(cinfo);
+		snd_seq_create_kernel_client(gus->card, 1, gus->interwave ?
+					     "AMD InterWave" : "GF1");
+	if (client < 0)
 		return client;
-	}
-
-	/* change name of client */
-	memset(cinfo, 0, sizeof(*cinfo));
-	cinfo->client = client;
-	cinfo->type = KERNEL_CLIENT;
-	sprintf(cinfo->name, gus->interwave ? "AMD InterWave" : "GF1");
-	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, cinfo);
-	kfree(cinfo);
 
 	for (i = 0; i < 4; i++)
 		snd_gus_synth_create_port(gus, i);
@@ -293,11 +275,11 @@
 	return 0;
 }
 
-static int snd_gus_synth_delete_device(snd_seq_device_t *dev)
+static int snd_gus_synth_delete_device(struct snd_seq_device *dev)
 {
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 
-	gus = *(snd_gus_card_t**)SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	gus = *(struct snd_gus_card **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	if (gus == NULL)
 		return -EINVAL;
 
@@ -312,13 +294,13 @@
 
 static int __init alsa_gus_synth_init(void)
 {
-	static snd_seq_dev_ops_t ops = {
+	static struct snd_seq_dev_ops ops = {
 		snd_gus_synth_new_device,
 		snd_gus_synth_delete_device
 	};
 
 	return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_GUS, &ops,
-					      sizeof(snd_gus_card_t*));
+					      sizeof(struct snd_gus_card *));
 }
 
 static void __exit alsa_gus_synth_exit(void)
diff --git a/sound/isa/gus/gus_timer.c b/sound/isa/gus/gus_timer.c
index 9876603..a43b662 100644
--- a/sound/isa/gus/gus_timer.c
+++ b/sound/isa/gus/gus_timer.c
@@ -30,12 +30,12 @@
  *  Timer 1 - 80us
  */
 
-static int snd_gf1_timer1_start(snd_timer_t * timer)
+static int snd_gf1_timer1_start(struct snd_timer * timer)
 {
 	unsigned long flags;
 	unsigned char tmp;
 	unsigned int ticks;
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 
 	gus = snd_timer_chip(timer);
 	spin_lock_irqsave(&gus->reg_lock, flags);
@@ -48,11 +48,11 @@
 	return 0;
 }
 
-static int snd_gf1_timer1_stop(snd_timer_t * timer)
+static int snd_gf1_timer1_stop(struct snd_timer * timer)
 {
 	unsigned long flags;
 	unsigned char tmp;
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 
 	gus = snd_timer_chip(timer);
 	spin_lock_irqsave(&gus->reg_lock, flags);
@@ -66,12 +66,12 @@
  *  Timer 2 - 320us
  */
 
-static int snd_gf1_timer2_start(snd_timer_t * timer)
+static int snd_gf1_timer2_start(struct snd_timer * timer)
 {
 	unsigned long flags;
 	unsigned char tmp;
 	unsigned int ticks;
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 
 	gus = snd_timer_chip(timer);
 	spin_lock_irqsave(&gus->reg_lock, flags);
@@ -84,11 +84,11 @@
 	return 0;
 }
 
-static int snd_gf1_timer2_stop(snd_timer_t * timer)
+static int snd_gf1_timer2_stop(struct snd_timer * timer)
 {
 	unsigned long flags;
 	unsigned char tmp;
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 
 	gus = snd_timer_chip(timer);
 	spin_lock_irqsave(&gus->reg_lock, flags);
@@ -102,18 +102,18 @@
 
  */
 
-static void snd_gf1_interrupt_timer1(snd_gus_card_t * gus)
+static void snd_gf1_interrupt_timer1(struct snd_gus_card * gus)
 {
-	snd_timer_t *timer = gus->gf1.timer1;
+	struct snd_timer *timer = gus->gf1.timer1;
 
 	if (timer == NULL)
 		return;
 	snd_timer_interrupt(timer, timer->sticks);
 }
 
-static void snd_gf1_interrupt_timer2(snd_gus_card_t * gus)
+static void snd_gf1_interrupt_timer2(struct snd_gus_card * gus)
 {
-	snd_timer_t *timer = gus->gf1.timer2;
+	struct snd_timer *timer = gus->gf1.timer2;
 
 	if (timer == NULL)
 		return;
@@ -124,7 +124,7 @@
 
  */
 
-static struct _snd_timer_hardware snd_gf1_timer1 =
+static struct snd_timer_hardware snd_gf1_timer1 =
 {
 	.flags =	SNDRV_TIMER_HW_STOP,
 	.resolution =	80000,
@@ -133,7 +133,7 @@
 	.stop =		snd_gf1_timer1_stop,
 };
 
-static struct _snd_timer_hardware snd_gf1_timer2 =
+static struct snd_timer_hardware snd_gf1_timer2 =
 {
 	.flags =	SNDRV_TIMER_HW_STOP,
 	.resolution =	320000,
@@ -142,22 +142,22 @@
 	.stop =		snd_gf1_timer2_stop,
 };
 
-static void snd_gf1_timer1_free(snd_timer_t *timer)
+static void snd_gf1_timer1_free(struct snd_timer *timer)
 {
-	snd_gus_card_t *gus = timer->private_data;
+	struct snd_gus_card *gus = timer->private_data;
 	gus->gf1.timer1 = NULL;
 }
 
-static void snd_gf1_timer2_free(snd_timer_t *timer)
+static void snd_gf1_timer2_free(struct snd_timer *timer)
 {
-	snd_gus_card_t *gus = timer->private_data;
+	struct snd_gus_card *gus = timer->private_data;
 	gus->gf1.timer2 = NULL;
 }
 
-void snd_gf1_timers_init(snd_gus_card_t * gus)
+void snd_gf1_timers_init(struct snd_gus_card * gus)
 {
-	snd_timer_t *timer;
-	snd_timer_id_t tid;
+	struct snd_timer *timer;
+	struct snd_timer_id tid;
 
 	if (gus->gf1.timer1 != NULL || gus->gf1.timer2 != NULL)
 		return;
@@ -190,7 +190,7 @@
 	gus->gf1.timer2 = timer;
 }
 
-void snd_gf1_timers_done(snd_gus_card_t * gus)
+void snd_gf1_timers_done(struct snd_gus_card * gus)
 {
 	snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_TIMER1 | SNDRV_GF1_HANDLER_TIMER2);
 	if (gus->gf1.timer1) {
diff --git a/sound/isa/gus/gus_uart.c b/sound/isa/gus/gus_uart.c
index fbc95e9..654290a 100644
--- a/sound/isa/gus/gus_uart.c
+++ b/sound/isa/gus/gus_uart.c
@@ -26,7 +26,7 @@
 #include <sound/core.h>
 #include <sound/gus.h>
 
-static void snd_gf1_interrupt_midi_in(snd_gus_card_t * gus)
+static void snd_gf1_interrupt_midi_in(struct snd_gus_card * gus)
 {
 	int count;
 	unsigned char stat, data, byte;
@@ -61,7 +61,7 @@
 	}
 }
 
-static void snd_gf1_interrupt_midi_out(snd_gus_card_t * gus)
+static void snd_gf1_interrupt_midi_out(struct snd_gus_card * gus)
 {
 	char byte;
 	unsigned long flags;
@@ -81,7 +81,7 @@
 	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
 }
 
-static void snd_gf1_uart_reset(snd_gus_card_t * gus, int close)
+static void snd_gf1_uart_reset(struct snd_gus_card * gus, int close)
 {
 	snd_gf1_uart_cmd(gus, 0x03);	/* reset */
 	if (!close && gus->uart_enable) {
@@ -90,10 +90,10 @@
 	}
 }
 
-static int snd_gf1_uart_output_open(snd_rawmidi_substream_t * substream)
+static int snd_gf1_uart_output_open(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 
 	gus = substream->rmidi->private_data;
 	spin_lock_irqsave(&gus->uart_cmd_lock, flags);
@@ -109,10 +109,10 @@
 	return 0;
 }
 
-static int snd_gf1_uart_input_open(snd_rawmidi_substream_t * substream)
+static int snd_gf1_uart_input_open(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 	int i;
 
 	gus = substream->rmidi->private_data;
@@ -136,10 +136,10 @@
 	return 0;
 }
 
-static int snd_gf1_uart_output_close(snd_rawmidi_substream_t * substream)
+static int snd_gf1_uart_output_close(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 
 	gus = substream->rmidi->private_data;
 	spin_lock_irqsave(&gus->uart_cmd_lock, flags);
@@ -151,10 +151,10 @@
 	return 0;
 }
 
-static int snd_gf1_uart_input_close(snd_rawmidi_substream_t * substream)
+static int snd_gf1_uart_input_close(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 
 	gus = substream->rmidi->private_data;
 	spin_lock_irqsave(&gus->uart_cmd_lock, flags);
@@ -166,9 +166,9 @@
 	return 0;
 }
 
-static void snd_gf1_uart_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_gf1_uart_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 	unsigned long flags;
 
 	gus = substream->rmidi->private_data;
@@ -184,10 +184,10 @@
 	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
 }
 
-static void snd_gf1_uart_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_gf1_uart_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	snd_gus_card_t *gus;
+	struct snd_gus_card *gus;
 	char byte;
 	int timeout;
 
@@ -222,23 +222,23 @@
 	spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
 }
 
-static snd_rawmidi_ops_t snd_gf1_uart_output =
+static struct snd_rawmidi_ops snd_gf1_uart_output =
 {
 	.open =		snd_gf1_uart_output_open,
 	.close =	snd_gf1_uart_output_close,
 	.trigger =	snd_gf1_uart_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_gf1_uart_input =
+static struct snd_rawmidi_ops snd_gf1_uart_input =
 {
 	.open =		snd_gf1_uart_input_open,
 	.close =	snd_gf1_uart_input_close,
 	.trigger =	snd_gf1_uart_input_trigger,
 };
 
-int snd_gf1_rawmidi_new(snd_gus_card_t * gus, int device, snd_rawmidi_t ** rrawmidi)
+int snd_gf1_rawmidi_new(struct snd_gus_card * gus, int device, struct snd_rawmidi ** rrawmidi)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	if (rrawmidi)
diff --git a/sound/isa/gus/gus_volume.c b/sound/isa/gus/gus_volume.c
index b3382fe..dbbc0a6 100644
--- a/sound/isa/gus/gus_volume.c
+++ b/sound/isa/gus/gus_volume.c
@@ -72,7 +72,7 @@
 	return rvol | (m >> (8 - e));
 }
 
-unsigned int snd_gf1_calc_ramp_rate(snd_gus_card_t * gus,
+unsigned int snd_gf1_calc_ramp_rate(struct snd_gus_card * gus,
 				    unsigned short start,
 				    unsigned short end,
 				    unsigned int us)
@@ -112,7 +112,7 @@
 
 #endif  /*  0  */
 
-unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq16)
+unsigned short snd_gf1_translate_freq(struct snd_gus_card * gus, unsigned int freq16)
 {
 	freq16 >>= 3;
 	if (freq16 < 50)
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index 39cef38..d1165b9 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -20,14 +20,15 @@
  */
 
 #include <sound/driver.h>
-#include <asm/dma.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
+#include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/gus.h>
-#define SNDRV_LEGACY_AUTO_PROBE
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
@@ -70,11 +71,12 @@
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Classic driver.");
 
-static snd_card_t *snd_gusclassic_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct platform_device *devices[SNDRV_CARDS];
+
 
 #define PFX	"gusclassic: "
 
-static int __init snd_gusclassic_detect(snd_gus_card_t * gus)
+static int __init snd_gusclassic_detect(struct snd_gus_card * gus)
 {
 	unsigned char d;
 
@@ -93,7 +95,7 @@
 	return 0;
 }
 
-static void __init snd_gusclassic_init(int dev, snd_gus_card_t * gus)
+static void __init snd_gusclassic_init(int dev, struct snd_gus_card * gus)
 {
 	gus->equal_irq = 0;
 	gus->codec_flag = 0;
@@ -101,20 +103,19 @@
 	gus->joystick_dac = joystick_dac[dev];
 }
 
-static int __init snd_gusclassic_probe(int dev)
+static int __init snd_gusclassic_probe(struct platform_device *pdev)
 {
+	int dev = pdev->id;
 	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, 4, -1};
 	static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
 	int xirq, xdma1, xdma2;
-	snd_card_t *card;
-	struct snd_gusclassic *guscard;
-	snd_gus_card_t *gus = NULL;
+	struct snd_card *card;
+	struct snd_gus_card *gus = NULL;
 	int err;
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
-	guscard = (struct snd_gusclassic *)card->private_data;
 	if (pcm_channels[dev] < 2)
 		pcm_channels[dev] = 2;
 
@@ -143,12 +144,31 @@
 		}
 	}
 
-
-	if ((err = snd_gus_create(card,
-				  port[dev],
-				  xirq, xdma1, xdma2,
-			          0, channels[dev], pcm_channels[dev],
-			          0, &gus)) < 0)
+	if (port[dev] != SNDRV_AUTO_PORT) {
+		err = snd_gus_create(card,
+				     port[dev],
+				     xirq, xdma1, xdma2,
+				     0, channels[dev], pcm_channels[dev],
+				     0, &gus);
+	} else {
+		/* auto-probe legacy ports */
+		static unsigned long possible_ports[] = {
+			0x220, 0x230, 0x240, 0x250, 0x260,
+		};
+		int i;
+		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
+			err = snd_gus_create(card,
+					     possible_ports[i],
+					     xirq, xdma1, xdma2,
+					     0, channels[dev], pcm_channels[dev],
+					     0, &gus);
+			if (err >= 0) {
+				port[dev] = possible_ports[i];
+				break;
+			}
+		}
+	}
+	if (err < 0)
 		goto _err;
 
 	if ((err = snd_gusclassic_detect(gus)) < 0)
@@ -178,13 +198,12 @@
 	if (dma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
+	snd_card_set_dev(card, &pdev->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
-	snd_gusclassic_cards[dev] = card;
+	platform_set_drvdata(pdev, card);
 	return 0;
 
  _err:
@@ -192,53 +211,70 @@
 	return err;
 }
 
-static int __init snd_gusclassic_legacy_auto_probe(unsigned long xport)
+static int snd_gusclassic_remove(struct platform_device *devptr)
 {
-	static int dev;
-	int res;
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
 
-	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
-			continue;
-		port[dev] = xport;
-		res = snd_gusclassic_probe(dev);
-		if (res < 0)
-			port[dev] = SNDRV_AUTO_PORT;
-		return res;
-	}
-	return -ENODEV;
+#define GUSCLASSIC_DRIVER	"snd_gusclassic"
+
+static struct platform_driver snd_gusclassic_driver = {
+	.probe		= snd_gusclassic_probe,
+	.remove		= snd_gusclassic_remove,
+	/* FIXME: suspend/resume */
+	.driver		= {
+		.name	= GUSCLASSIC_DRIVER
+	},
+};
+
+static void __init_or_module snd_gusclassic_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_gusclassic_driver);
 }
 
 static int __init alsa_card_gusclassic_init(void)
 {
-	static unsigned long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260, -1};
-	int dev, cards, i;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) {
-		if (port[dev] == SNDRV_AUTO_PORT)
-			continue;
-		if (snd_gusclassic_probe(dev) >= 0)
-			cards++;
+	err = platform_driver_register(&snd_gusclassic_driver);
+	if (err < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(GUSCLASSIC_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		devices[i] = device;
+		cards++;
 	}
-	i = snd_legacy_auto_probe(possible_ports, snd_gusclassic_legacy_auto_probe);
-	if (i > 0)
-		cards += i;
-
 	if (!cards) {
 #ifdef MODULE
 		printk(KERN_ERR "GUS Classic soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_gusclassic_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_gusclassic_exit(void)
 {
-	int idx;
-	
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_gusclassic_cards[idx]);
+	snd_gusclassic_unregister_all();
 }
 
 module_init(alsa_card_gusclassic_init)
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index d2e7cb1..239f16e 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -20,11 +20,13 @@
  */
 
 #include <sound/driver.h>
-#include <asm/dma.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
+#include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/gus.h>
 #include <sound/es1688.h>
@@ -85,14 +87,15 @@
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS Extreme driver.");
 
-static snd_card_t *snd_gusextreme_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+struct platform_device *devices[SNDRV_CARDS];
+
 
 #define PFX	"gusextreme: "
 
 static int __init snd_gusextreme_detect(int dev,
-					snd_card_t * card,
-					snd_gus_card_t * gus,
-					es1688_t *es1688)
+					struct snd_card *card,
+					struct snd_gus_card * gus,
+					struct snd_es1688 *es1688)
 {
 	unsigned long flags;
 	unsigned char d;
@@ -139,15 +142,15 @@
 	return 0;
 }
 
-static void __init snd_gusextreme_init(int dev, snd_gus_card_t * gus)
+static void __init snd_gusextreme_init(int dev, struct snd_gus_card * gus)
 {
 	gus->joystick_dac = joystick_dac[dev];
 }
 
-static int __init snd_gusextreme_mixer(es1688_t *chip)
+static int __init snd_gusextreme_mixer(struct snd_es1688 *chip)
 {
-	snd_card_t *card = chip->card;
-	snd_ctl_elem_id_t id1, id2;
+	struct snd_card *card = chip->card;
+	struct snd_ctl_elem_id id1, id2;
 	int err;
 
 	memset(&id1, 0, sizeof(id1));
@@ -166,24 +169,23 @@
 	return 0;
 }
 
-static int __init snd_gusextreme_probe(int dev)
+static int __init snd_gusextreme_probe(struct platform_device *pdev)
 {
+	int dev = pdev->id;
 	static int possible_ess_irqs[] = {5, 9, 10, 7, -1};
 	static int possible_ess_dmas[] = {1, 3, 0, -1};
 	static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
 	static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1};
 	int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma;
-	snd_card_t *card;
-	struct snd_gusextreme *acard;
-	snd_gus_card_t *gus;
-	es1688_t *es1688;
-	opl3_t *opl3;
+	struct snd_card *card;
+	struct snd_gus_card *gus;
+	struct snd_es1688 *es1688;
+	struct snd_opl3 *opl3;
 	int err;
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
-	acard = (struct snd_gusextreme *)card->private_data;
 
 	xgf1_irq = gf1_irq[dev];
 	if (xgf1_irq == SNDRV_AUTO_IRQ) {
@@ -223,10 +225,29 @@
 		}
 	}
 
-	if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
-				     xess_irq, xmpu_irq, xess_dma,
-				     ES1688_HW_1688, &es1688)) < 0)
+	if (port[dev] != SNDRV_AUTO_PORT) {
+		err = snd_es1688_create(card, port[dev], mpu_port[dev],
+					xess_irq, xmpu_irq, xess_dma,
+					ES1688_HW_1688, &es1688);
+	} else {
+		/* auto-probe legacy ports */
+		static unsigned long possible_ports[] = {0x220, 0x240, 0x260};
+		int i;
+		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
+			err = snd_es1688_create(card,
+						possible_ports[i],
+						mpu_port[dev],
+						xess_irq, xmpu_irq, xess_dma,
+						ES1688_HW_1688, &es1688);
+			if (err >= 0) {
+				port[dev] = possible_ports[i];
+				break;
+			}
+		}
+	}
+	if (err < 0)
 		goto out;
+
 	if (gf1_port[dev] < 0)
 		gf1_port[dev] = port[dev] + 0x20;
 	if ((err = snd_gus_create(card,
@@ -287,13 +308,12 @@
 	sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
 		es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto out;
+	snd_card_set_dev(card, &pdev->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto out;
 
-	snd_gusextreme_cards[dev] = card;
+	platform_set_drvdata(pdev, card);
 	return 0;
 
       out:
@@ -301,60 +321,70 @@
 	return err;
 }
 
-static int __init snd_gusextreme_legacy_auto_probe(unsigned long xport)
+static int snd_gusextreme_remove(struct platform_device *devptr)
 {
-        static int dev;
-        int res;
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
 
-        for ( ; dev < SNDRV_CARDS; dev++) {
-                if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
-                        continue;
-                port[dev] = xport;
-                res = snd_gusextreme_probe(dev);
-                if (res < 0)
-                        port[dev] = SNDRV_AUTO_PORT;
-                return res;
-        }
-        return -ENODEV;
+#define GUSEXTREME_DRIVER	"snd_gusextreme"
+
+static struct platform_driver snd_gusextreme_driver = {
+	.probe		= snd_gusextreme_probe,
+	.remove		= snd_gusextreme_remove,
+	/* FIXME: suspend/resume */
+	.driver		= {
+		.name	= GUSEXTREME_DRIVER
+	},
+};
+
+static void __init_or_module snd_gusextreme_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_gusextreme_driver);
 }
 
 static int __init alsa_card_gusextreme_init(void)
 {
-	static unsigned long possible_ports[] = {0x220, 0x240, 0x260, -1};
-	int dev, cards, i;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev] > 0; dev++) {
-		if (port[dev] == SNDRV_AUTO_PORT)
-			continue;
-		if (snd_gusextreme_probe(dev) >= 0)
-			cards++;
+	err = platform_driver_register(&snd_gusextreme_driver);
+	if (err < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(GUSEXTREME_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		devices[i] = device;
+		cards++;
 	}
-	i = snd_legacy_auto_probe(possible_ports, snd_gusextreme_legacy_auto_probe);
-	if (i > 0)
-		cards += i;
-
 	if (!cards) {
 #ifdef MODULE
 		printk(KERN_ERR "GUS Extreme soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_gusextreme_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_gusextreme_exit(void)
 {
-	int idx;
-	snd_card_t *card;
-	struct snd_gusextreme *acard;
-
-	for (idx = 0; idx < SNDRV_CARDS; idx++) {
-		card = snd_gusextreme_cards[idx];
-		if (card == NULL)
-			continue;
-		acard = (struct snd_gusextreme *)card->private_data;
-		snd_card_free(snd_gusextreme_cards[idx]);
-	}
+	snd_gusextreme_unregister_all();
 }
 
 module_init(alsa_card_gusextreme_init)
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c
index 0bb44b5..d4d2b2a 100644
--- a/sound/isa/gus/gusmax.c
+++ b/sound/isa/gus/gusmax.c
@@ -20,15 +20,16 @@
  */
 
 #include <sound/driver.h>
-#include <asm/dma.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/moduleparam.h>
+#include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/gus.h>
 #include <sound/cs4231.h>
-#define SNDRV_LEGACY_AUTO_PROBE
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
@@ -71,20 +72,20 @@
 module_param_array(pcm_channels, int, NULL, 0444);
 MODULE_PARM_DESC(pcm_channels, "Reserved PCM channels for GUS MAX driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 struct snd_gusmax {
 	int irq;
-	snd_card_t *card;
-	snd_gus_card_t *gus;
-	cs4231_t *cs4231;
+	struct snd_card *card;
+	struct snd_gus_card *gus;
+	struct snd_cs4231 *cs4231;
 	unsigned short gus_status_reg;
 	unsigned short pcm_status_reg;
 };
 
-static snd_card_t *snd_gusmax_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
 #define PFX	"gusmax: "
 
-static int __init snd_gusmax_detect(snd_gus_card_t * gus)
+static int __init snd_gusmax_detect(struct snd_gus_card * gus)
 {
 	unsigned char d;
 
@@ -126,7 +127,7 @@
 	return IRQ_RETVAL(handled);
 }
 
-static void __init snd_gusmax_init(int dev, snd_card_t * card, snd_gus_card_t * gus)
+static void __init snd_gusmax_init(int dev, struct snd_card *card, struct snd_gus_card * gus)
 {
 	gus->equal_irq = 1;
 	gus->codec_flag = 1;
@@ -144,10 +145,10 @@
 #define CS4231_PRIVATE( left, right, shift, mute ) \
 			((left << 24)|(right << 16)|(shift<<8)|mute)
 
-static int __init snd_gusmax_mixer(cs4231_t *chip)
+static int __init snd_gusmax_mixer(struct snd_cs4231 *chip)
 {
-	snd_card_t *card = chip->card;
-	snd_ctl_elem_id_t id1, id2;
+	struct snd_card *card = chip->card;
+	struct snd_ctl_elem_id id1, id2;
 	int err;
 	
 	memset(&id1, 0, sizeof(id1));
@@ -193,7 +194,7 @@
 	return 0;
 }
 
-static void snd_gusmax_free(snd_card_t *card)
+static void snd_gusmax_free(struct snd_card *card)
 {
 	struct snd_gusmax *maxcard = (struct snd_gusmax *)card->private_data;
 	
@@ -203,14 +204,15 @@
 		free_irq(maxcard->irq, (void *)maxcard);
 }
 
-static int __init snd_gusmax_probe(int dev)
+static int __init snd_gusmax_probe(struct platform_device *pdev)
 {
+	int dev = pdev->id;
 	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
 	static int possible_dmas[] = {5, 6, 7, 1, 3, -1};
 	int xirq, xdma1, xdma2, err;
-	snd_card_t *card;
-	snd_gus_card_t *gus = NULL;
-	cs4231_t *cs4231;
+	struct snd_card *card;
+	struct snd_gus_card *gus = NULL;
+	struct snd_cs4231 *cs4231;
 	struct snd_gusmax *maxcard;
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
@@ -247,12 +249,32 @@
 		}
 	}
 
-	if ((err = snd_gus_create(card,
-				  port[dev],
-				  -xirq, xdma1, xdma2,
-				  0, channels[dev],
-				  pcm_channels[dev],
-				  0, &gus)) < 0)
+	if (port[dev] != SNDRV_AUTO_PORT) {
+		err = snd_gus_create(card,
+				     port[dev],
+				     -xirq, xdma1, xdma2,
+				     0, channels[dev],
+				     pcm_channels[dev],
+				     0, &gus);
+	} else {
+		static unsigned long possible_ports[] = {
+			0x220, 0x230, 0x240, 0x250, 0x260
+		};
+		int i;
+		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
+			err = snd_gus_create(card,
+					     possible_ports[i],
+					     -xirq, xdma1, xdma2,
+					     0, channels[dev],
+					     pcm_channels[dev],
+					     0, &gus);
+			if (err >= 0) {
+				port[dev] = possible_ports[i];
+				break;
+			}
+		}
+	}
+	if (err < 0)
 		goto _err;
 
 	if ((err = snd_gusmax_detect(gus)) < 0)
@@ -310,15 +332,15 @@
 	if (xdma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%i", xdma2);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
+	snd_card_set_dev(card, &pdev->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 		
 	maxcard->gus = gus;
 	maxcard->cs4231 = cs4231;
-	snd_gusmax_cards[dev] = card;
+
+	platform_set_drvdata(pdev, card);
 	return 0;
 
  _err:
@@ -326,53 +348,70 @@
 	return err;
 }
 
-static int __init snd_gusmax_legacy_auto_probe(unsigned long xport)
+static int snd_gusmax_remove(struct platform_device *devptr)
 {
-	static int dev;
-	int res;
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
 
-	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
-			continue;
-		port[dev] = xport;
-		res = snd_gusmax_probe(dev);
-		if (res < 0)
-			port[dev] = SNDRV_AUTO_PORT;
-		return res;
-	}
-	return -ENODEV;
+#define GUSMAX_DRIVER	"snd_gusmax"
+
+static struct platform_driver snd_gusmax_driver = {
+	.probe		= snd_gusmax_probe,
+	.remove		= snd_gusmax_remove,
+	/* FIXME: suspend/resume */
+	.driver		= {
+		.name	= GUSMAX_DRIVER
+	},
+};
+
+static void __init_or_module snd_gusmax_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_gusmax_driver);
 }
 
 static int __init alsa_card_gusmax_init(void)
 {
-	static unsigned long possible_ports[] = {0x220, 0x230, 0x240, 0x250, 0x260, -1};
-	int dev, cards, i;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev] > 0; dev++) {
-		if (port[dev] == SNDRV_AUTO_PORT)
-			continue;
-		if (snd_gusmax_probe(dev) >= 0)
-			cards++;
+	err = platform_driver_register(&snd_gusmax_driver);
+	if (err < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(GUSMAX_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		devices[i] = device;
+		cards++;
 	}
-	i = snd_legacy_auto_probe(possible_ports, snd_gusmax_legacy_auto_probe);
-	if (i > 0)
-		cards += i;
-
 	if (!cards) {
 #ifdef MODULE
 		printk(KERN_ERR "GUS MAX soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_gusmax_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_gusmax_exit(void)
 {
-	int idx;
-
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_gusmax_cards[idx]);
+	snd_gusmax_unregister_all();
 }
 
 module_init(alsa_card_gusmax_init)
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index f703a9f..9838d992b 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -23,19 +23,20 @@
  */
 
 #include <sound/driver.h>
-#include <asm/dma.h>
-#include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
+#include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/gus.h>
 #include <sound/cs4231.h>
 #ifdef SNDRV_STB
 #include <sound/tea6330t.h>
 #endif
-#define SNDRV_LEGACY_AUTO_PROBE
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
@@ -75,8 +76,12 @@
 
 #ifdef SNDRV_STB
 #define PFX "interwave-stb: "
+#define INTERWAVE_DRIVER	"snd_interwave_stb"
+#define INTERWAVE_PNP_DRIVER	"interwave-stb"
 #else
 #define PFX "interwave: "
+#define INTERWAVE_DRIVER	"snd_interwave"
+#define INTERWAVE_PNP_DRIVER	"interwave"
 #endif
 
 module_param_array(index, int, NULL, 0444);
@@ -110,11 +115,14 @@
 module_param_array(effect, int, NULL, 0444);
 MODULE_PARM_DESC(effect, "Effects enable for InterWave driver.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
+
 struct snd_interwave {
 	int irq;
-	snd_card_t *card;
-	snd_gus_card_t *gus;
-	cs4231_t *cs4231;
+	struct snd_card *card;
+	struct snd_gus_card *gus;
+	struct snd_cs4231 *cs4231;
 #ifdef SNDRV_STB
 	struct resource *i2c_res;
 #endif
@@ -128,7 +136,6 @@
 #endif
 };
 
-static snd_card_t *snd_interwave_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
 
 #ifdef CONFIG_PNP
 
@@ -160,7 +167,7 @@
 
 
 #ifdef SNDRV_STB
-static void snd_interwave_i2c_setlines(snd_i2c_bus_t *bus, int ctrl, int data)
+static void snd_interwave_i2c_setlines(struct snd_i2c_bus *bus, int ctrl, int data)
 {
 	unsigned long port = bus->private_value;
 
@@ -171,7 +178,7 @@
 	udelay(10);
 }
 
-static int snd_interwave_i2c_getclockline(snd_i2c_bus_t *bus)
+static int snd_interwave_i2c_getclockline(struct snd_i2c_bus *bus)
 {
 	unsigned long port = bus->private_value;
 	unsigned char res;
@@ -183,7 +190,7 @@
 	return res;
 }
 
-static int snd_interwave_i2c_getdataline(snd_i2c_bus_t *bus, int ack)
+static int snd_interwave_i2c_getdataline(struct snd_i2c_bus *bus, int ack)
 {
 	unsigned long port = bus->private_value;
 	unsigned char res;
@@ -197,19 +204,19 @@
 	return res;
 }
 
-static snd_i2c_bit_ops_t snd_interwave_i2c_bit_ops = {
+static struct snd_i2c_bit_ops snd_interwave_i2c_bit_ops = {
 	.setlines = snd_interwave_i2c_setlines,
 	.getclock = snd_interwave_i2c_getclockline,
 	.getdata  = snd_interwave_i2c_getdataline,
 };
 
 static int __devinit snd_interwave_detect_stb(struct snd_interwave *iwcard,
-					      snd_gus_card_t * gus, int dev,
-					      snd_i2c_bus_t **rbus)
+					      struct snd_gus_card * gus, int dev,
+					      struct snd_i2c_bus **rbus)
 {
 	unsigned long port;
-	snd_i2c_bus_t *bus;
-	snd_card_t *card = iwcard->card;
+	struct snd_i2c_bus *bus;
+	struct snd_card *card = iwcard->card;
 	char name[32];
 	int err;
 
@@ -246,10 +253,10 @@
 #endif
 
 static int __devinit snd_interwave_detect(struct snd_interwave *iwcard,
-				          snd_gus_card_t * gus,
+				          struct snd_gus_card * gus,
 				          int dev
 #ifdef SNDRV_STB
-				          , snd_i2c_bus_t **rbus
+				          , struct snd_i2c_bus **rbus
 #endif
 				          )
 {
@@ -314,7 +321,7 @@
 	return IRQ_RETVAL(handled);
 }
 
-static void __devinit snd_interwave_reset(snd_gus_card_t * gus)
+static void __devinit snd_interwave_reset(struct snd_gus_card * gus)
 {
 	snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x00);
 	udelay(160);
@@ -322,7 +329,7 @@
 	udelay(160);
 }
 
-static void __devinit snd_interwave_bank_sizes(snd_gus_card_t * gus, int *sizes)
+static void __devinit snd_interwave_bank_sizes(struct snd_gus_card * gus, int *sizes)
 {
 	unsigned int idx;
 	unsigned int local;
@@ -371,7 +378,7 @@
 	/* 511 */ unsigned char csum;
 };
 
-static void __devinit snd_interwave_detect_memory(snd_gus_card_t * gus)
+static void __devinit snd_interwave_detect_memory(struct snd_gus_card * gus)
 {
 	static unsigned int lmc[13] =
 	{
@@ -470,7 +477,7 @@
 		snd_interwave_reset(gus);
 }
 
-static void __devinit snd_interwave_init(int dev, snd_gus_card_t * gus)
+static void __devinit snd_interwave_init(int dev, struct snd_gus_card * gus)
 {
 	unsigned long flags;
 
@@ -492,17 +499,17 @@
 
 }
 
-static snd_kcontrol_new_t snd_interwave_controls[] = {
+static struct snd_kcontrol_new snd_interwave_controls[] = {
 CS4231_DOUBLE("Master Playback Switch", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1),
 CS4231_DOUBLE("Master Playback Volume", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1),
 CS4231_DOUBLE("Mic Playback Switch", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1),
 CS4231_DOUBLE("Mic Playback Volume", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1)
 };
 
-static int __devinit snd_interwave_mixer(cs4231_t *chip)
+static int __devinit snd_interwave_mixer(struct snd_cs4231 *chip)
 {
-	snd_card_t *card = chip->card;
-	snd_ctl_elem_id_t id1, id2;
+	struct snd_card *card = chip->card;
+	struct snd_ctl_elem_id id1, id2;
 	unsigned int idx;
 	int err;
 
@@ -631,9 +638,9 @@
 }
 #endif /* CONFIG_PNP */
 
-static void snd_interwave_free(snd_card_t *card)
+static void snd_interwave_free(struct snd_card *card)
 {
-	struct snd_interwave *iwcard = (struct snd_interwave *)card->private_data;
+	struct snd_interwave *iwcard = card->private_data;
 
 	if (iwcard == NULL)
 		return;
@@ -644,76 +651,52 @@
 		free_irq(iwcard->irq, (void *)iwcard);
 }
 
-static int __devinit snd_interwave_probe(int dev, struct pnp_card_link *pcard,
-				         const struct pnp_card_device_id *pid)
+static struct snd_card *snd_interwave_card_new(int dev)
 {
-	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
-	static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
-	int xirq, xdma1, xdma2;
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_interwave *iwcard;
-	cs4231_t *cs4231;
-	snd_gus_card_t *gus;
-#ifdef SNDRV_STB
-	snd_i2c_bus_t *i2c_bus;
-#endif
-	snd_pcm_t *pcm;
-	char *str;
-	int err;
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(struct snd_interwave));
 	if (card == NULL)
-		return -ENOMEM;
-	iwcard = (struct snd_interwave *)card->private_data;
+		return NULL;
+	iwcard = card->private_data;
 	iwcard->card = card;
 	iwcard->irq = -1;
 	card->private_free = snd_interwave_free;
-#ifdef CONFIG_PNP
-	if (isapnp[dev]) {
-		if ((err = snd_interwave_pnp(dev, iwcard, pcard, pid)) < 0)
-			goto _err;
-		snd_card_set_dev(card, &pcard->card->dev);
-	}
+	return card;
+}
+
+static int __devinit snd_interwave_probe(struct snd_card *card, int dev)
+{
+	int xirq, xdma1, xdma2;
+	struct snd_interwave *iwcard = card->private_data;
+	struct snd_cs4231 *cs4231;
+	struct snd_gus_card *gus;
+#ifdef SNDRV_STB
+	struct snd_i2c_bus *i2c_bus;
 #endif
+	struct snd_pcm *pcm;
+	char *str;
+	int err;
+
 	xirq = irq[dev];
-	if (xirq == SNDRV_AUTO_IRQ) {
-		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
-			err = -EBUSY;
-			goto _err;
-		}
-	}
 	xdma1 = dma1[dev];
-	if (xdma1 == SNDRV_AUTO_DMA) {
-		if ((xdma1 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
-			err = -EBUSY;
-			goto _err;
-		}
-	}
 	xdma2 = dma2[dev];
-	if (xdma2 == SNDRV_AUTO_DMA) {
-		if ((xdma2 = snd_legacy_find_free_dma(possible_dmas)) < 0) {
-			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
-			err = -EBUSY;
-			goto _err;
-		}
-	}
 
 	if ((err = snd_gus_create(card,
 				  port[dev],
 				  -xirq, xdma1, xdma2,
 				  0, 32,
 				  pcm_channels[dev], effect[dev], &gus)) < 0)
-		goto _err;
+		return err;
 
 	if ((err = snd_interwave_detect(iwcard, gus, dev
 #ifdef SNDRV_STB
             , &i2c_bus
 #endif
 	    )) < 0)
-		goto _err;
+		return err;
 
 	iwcard->gus_status_reg = gus->gf1.reg_irqstat;
 	iwcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
@@ -721,12 +704,12 @@
 	snd_interwave_init(dev, gus);
 	snd_interwave_detect_memory(gus);
 	if ((err = snd_gus_initialize(gus)) < 0)
-		goto _err;
+		return err;
 
-	if (request_irq(xirq, snd_interwave_interrupt, SA_INTERRUPT, "InterWave", (void *)iwcard)) {
+	if (request_irq(xirq, snd_interwave_interrupt, SA_INTERRUPT,
+			"InterWave", iwcard)) {
 		snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
-		err = -EBUSY;
-		goto _err;
+		return -EBUSY;
 	}
 	iwcard->irq = xirq;
 
@@ -738,30 +721,30 @@
 				     CS4231_HWSHARE_DMA1 |
 				     CS4231_HWSHARE_DMA2,
 				     &cs4231)) < 0)
-		goto _err;
+		return err;
 
 	if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0)
-		goto _err;
+		return err;
 
 	sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');
 	strcat(pcm->name, " (codec)");
 
 	if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0)
-		goto _err;
+		return err;
 
 	if ((err = snd_cs4231_mixer(cs4231)) < 0)
-		goto _err;
+		return err;
 
 	if (pcm_channels[dev] > 0) {
 		if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
-			goto _err;
+			return err;
 	}
 	if ((err = snd_interwave_mixer(cs4231)) < 0)
-		goto _err;
+		return err;
 
 #ifdef SNDRV_STB
 	{
-		snd_ctl_elem_id_t id1, id2;
+		struct snd_ctl_elem_id id1, id2;
 		memset(&id1, 0, sizeof(id1));
 		memset(&id2, 0, sizeof(id2));
 		id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -769,19 +752,19 @@
 		strcpy(id2.name, id1.name);
 		id2.index = 1;
 		if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
-			goto _err;
+			return err;
 		strcpy(id1.name, "Master Playback Volume");
 		strcpy(id2.name, id1.name);
 		if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
-			goto _err;
+			return err;
 		if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0)
-			goto _err;
+			return err;
 	}
 #endif
 
 	gus->uart_enable = midi[dev];
 	if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)
-		goto _err;
+		return err;
 
 #ifndef SNDRV_STB
 	str = "AMD InterWave";
@@ -800,139 +783,198 @@
 	if (xdma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
-
 	if ((err = snd_card_register(card)) < 0)
-		goto _err;
+		return err;
 	
 	iwcard->cs4231 = cs4231;
 	iwcard->gus = gus;
-	if (pcard)
-		pnp_set_card_drvdata(pcard, card);
-	else
-		snd_interwave_legacy[dev++] = card;
 	return 0;
-
- _err:
-	snd_card_free(card);
-	return err;
 }
 
-static int __devinit snd_interwave_probe_legacy_port(unsigned long xport)
+static int __init snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr)
+{
+	struct snd_card *card;
+	int err;
+
+	card = snd_interwave_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+
+	snd_card_set_dev(card, &devptr->dev);
+	if ((err = snd_interwave_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	platform_set_drvdata(devptr, card);
+	return 0;
+}
+
+static int __init snd_interwave_nonpnp_probe(struct platform_device *pdev)
+{
+	int dev = pdev->id;
+	int err;
+	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
+	static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};
+
+	if (irq[dev] == SNDRV_AUTO_IRQ) {
+		if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+			return -EBUSY;
+		}
+	}
+	if (dma1[dev] == SNDRV_AUTO_DMA) {
+		if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
+			return -EBUSY;
+		}
+	}
+	if (dma2[dev] == SNDRV_AUTO_DMA) {
+		if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {
+			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
+			return -EBUSY;
+		}
+	}
+
+	if (port[dev] != SNDRV_AUTO_PORT)
+		return snd_interwave_nonpnp_probe1(dev, pdev);
+	else {
+		static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260};
+		int i;
+		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
+			port[dev] = possible_ports[i];
+			err = snd_interwave_nonpnp_probe1(dev, pdev);
+			if (! err)
+				return 0;
+		}
+		return err;
+	}
+}
+
+static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+static struct platform_driver snd_interwave_driver = {
+	.probe		= snd_interwave_nonpnp_probe,
+	.remove		= __devexit_p(snd_interwave_nonpnp_remove),
+	/* FIXME: suspend,resume */
+	.driver		= {
+		.name	= INTERWAVE_DRIVER
+	},
+};
+
+#ifdef CONFIG_PNP
+
+static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,
+					      const struct pnp_card_device_id *pid)
 {
 	static int dev;
+	struct snd_card *card;
 	int res;
 
 	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
-                        continue;
-#ifdef CONFIG_PNP
-		if (isapnp[dev])
-			continue;
-#endif
-		port[dev] = xport;
-		res = snd_interwave_probe(dev, NULL, NULL);
-		if (res < 0)
-			port[dev] = SNDRV_AUTO_PORT;
+		if (enable[dev] && isapnp[dev])
+			break;
+	}
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+				
+	card = snd_interwave_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+
+	if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) {
+		snd_card_free(card);
 		return res;
 	}
-	return -ENODEV;
-}
-
-#ifdef CONFIG_PNP
-
-static int __devinit snd_interwave_pnp_detect(struct pnp_card_link *card,
-					   const struct pnp_card_device_id *id)
-{
-	static int dev;
-	int res;
-
-	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || !isapnp[dev])
-			continue;
-		res = snd_interwave_probe(dev, card, id);
-		if (res < 0)
-			return res;
-		dev++;
-		return 0;
-        }
-
-        return -ENODEV;
+	snd_card_set_dev(card, &pcard->card->dev);
+	if ((res = snd_interwave_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return res;
+	}
+	pnp_set_card_drvdata(pcard, card);
+	dev++;
+	return 0;
 }
 
 static void __devexit snd_interwave_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
 static struct pnp_card_driver interwave_pnpc_driver = {
 	.flags = PNP_DRIVER_RES_DISABLE,
-	.name = "interwave",
+	.name = INTERWAVE_PNP_DRIVER,
 	.id_table = snd_interwave_pnpids,
 	.probe = snd_interwave_pnp_detect,
 	.remove = __devexit_p(snd_interwave_pnp_remove),
+	/* FIXME: suspend,resume */
 };
 
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_interwave_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&interwave_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_interwave_driver);
+}
+
 static int __init alsa_card_interwave_init(void)
 {
-	int cards = 0, i;
-	static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260, -1};
-	int dev;
+	int i, err, cards = 0;
 
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT)
-			continue;
+	if ((err = platform_driver_register(&snd_interwave_driver)) < 0)
+		return err;
+
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
 #ifdef CONFIG_PNP
-		if (isapnp[dev])
+		if (isapnp[i])
 			continue;
 #endif
-		if (!snd_interwave_probe(dev, NULL, NULL)) {
-			cards++;
-			continue;
+		device = platform_device_register_simple(INTERWAVE_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
 		}
-#ifdef MODULE
-		printk(KERN_ERR "InterWave soundcard #%i not found at 0x%lx or device busy\n", dev, port[dev]);
-#endif
+		platform_devices[i] = device;
+		cards++;
 	}
-	/* legacy auto configured cards */
-	i = snd_legacy_auto_probe(possible_ports, snd_interwave_probe_legacy_port);
-	if (i > 0)
-		cards += i;
-#ifdef CONFIG_PNP
+
 	/* ISA PnP cards */
 	i = pnp_register_card_driver(&interwave_pnpc_driver);
-	if (i > 0)
+	if (i >= 0) {
+		pnp_registered = 1;
 		cards += i;
-#endif
+	}
 
 	if (!cards) {
-#ifdef CONFIG_PNP
-		pnp_unregister_card_driver(&interwave_pnpc_driver);
-#endif
 #ifdef MODULE
 		printk(KERN_ERR "InterWave soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_interwave_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_interwave_exit(void)
 {
-	int dev;
-
-#ifdef CONFIG_PNP
-	/* PnP cards first */
-	pnp_unregister_card_driver(&interwave_pnpc_driver);
-#endif
-	for (dev = 0; dev < SNDRV_CARDS; dev++)
-		snd_card_free(snd_interwave_legacy[dev]);
+	snd_interwave_unregister_all();
 }
 
 module_init(alsa_card_interwave_init)
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 47cabda..ca359e0 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -21,6 +21,8 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
@@ -88,6 +90,10 @@
 module_param_array(opl3sa3_ymode, int, NULL, 0444);
 MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
+static int pnpc_registered;
+
 /* control ports */
 #define OPL3SA2_PM_CTRL		0x01
 #define OPL3SA2_SYS_CTRL		0x02
@@ -115,34 +121,23 @@
 #define OPL3SA2_PM_D0	0x00
 #define OPL3SA2_PM_D3	(OPL3SA2_PM_ADOWN|OPL3SA2_PM_PSV|OPL3SA2_PM_PDN|OPL3SA2_PM_PDX)
 
-typedef struct snd_opl3sa2 opl3sa2_t;
-
 struct snd_opl3sa2 {
-	snd_card_t *card;
+	struct snd_card *card;
 	int version;		/* 2 or 3 */
 	unsigned long port;	/* control port */
 	struct resource *res_port; /* control port resource */
 	int irq;
 	int single_dma;
 	spinlock_t reg_lock;
-	snd_hwdep_t *synth;
-	snd_rawmidi_t *rmidi;
-	cs4231_t *cs4231;
-#ifdef CONFIG_PNP
-	struct pnp_dev *dev;
-#endif
+	struct snd_hwdep *synth;
+	struct snd_rawmidi *rmidi;
+	struct snd_cs4231 *cs4231;
 	unsigned char ctlregs[0x20];
 	int ymode;		/* SL added */
-	snd_kcontrol_t *master_switch;
-	snd_kcontrol_t *master_volume;
-#ifdef CONFIG_PM
-	void (*cs4231_suspend)(cs4231_t *);
-	void (*cs4231_resume)(cs4231_t *);
-#endif
+	struct snd_kcontrol *master_switch;
+	struct snd_kcontrol *master_volume;
 };
 
-static snd_card_t *snd_opl3sa2_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
 #define PFX	"opl3sa2: "
 
 #ifdef CONFIG_PNP
@@ -176,7 +171,7 @@
 
 
 /* read control port (w/o spinlock) */
-static unsigned char __snd_opl3sa2_read(opl3sa2_t *chip, unsigned char reg)
+static unsigned char __snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char reg)
 {
 	unsigned char result;
 #if 0
@@ -192,7 +187,7 @@
 }
 
 /* read control port (with spinlock) */
-static unsigned char snd_opl3sa2_read(opl3sa2_t *chip, unsigned char reg)
+static unsigned char snd_opl3sa2_read(struct snd_opl3sa2 *chip, unsigned char reg)
 {
 	unsigned long flags;
 	unsigned char result;
@@ -204,7 +199,7 @@
 }
 
 /* write control port (w/o spinlock) */
-static void __snd_opl3sa2_write(opl3sa2_t *chip, unsigned char reg, unsigned char value)
+static void __snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsigned char value)
 {
 #if 0
 	outb(0x1d, port);	/* password */
@@ -215,7 +210,7 @@
 }
 
 /* write control port (with spinlock) */
-static void snd_opl3sa2_write(opl3sa2_t *chip, unsigned char reg, unsigned char value)
+static void snd_opl3sa2_write(struct snd_opl3sa2 *chip, unsigned char reg, unsigned char value)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -223,9 +218,9 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static int __init snd_opl3sa2_detect(opl3sa2_t *chip)
+static int __init snd_opl3sa2_detect(struct snd_opl3sa2 *chip)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned long port;
 	unsigned char tmp, tmp1;
 	char str[2];
@@ -298,7 +293,7 @@
 static irqreturn_t snd_opl3sa2_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned short status;
-	opl3sa2_t *chip = dev_id;
+	struct snd_opl3sa2 *chip = dev_id;
 	int handled = 0;
 
 	if (chip == NULL || chip->card == NULL)
@@ -340,7 +335,7 @@
   .get = snd_opl3sa2_get_single, .put = snd_opl3sa2_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_opl3sa2_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_opl3sa2_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -351,9 +346,9 @@
 	return 0;
 }
 
-static int snd_opl3sa2_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -368,9 +363,9 @@
 	return 0;
 }
 
-static int snd_opl3sa2_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -398,7 +393,7 @@
   .get = snd_opl3sa2_get_double, .put = snd_opl3sa2_put_double, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-static int snd_opl3sa2_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_opl3sa2_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -409,9 +404,9 @@
 	return 0;
 }
 
-static int snd_opl3sa2_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -431,9 +426,9 @@
 	return 0;
 }
 
-static int snd_opl3sa2_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opl3sa2_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -471,31 +466,31 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_opl3sa2_controls[] = {
+static struct snd_kcontrol_new snd_opl3sa2_controls[] = {
 OPL3SA2_DOUBLE("Master Playback Switch", 0, 0x07, 0x08, 7, 7, 1, 1),
 OPL3SA2_DOUBLE("Master Playback Volume", 0, 0x07, 0x08, 0, 0, 15, 1),
 OPL3SA2_SINGLE("Mic Playback Switch", 0, 0x09, 7, 1, 1),
 OPL3SA2_SINGLE("Mic Playback Volume", 0, 0x09, 0, 31, 1)
 };
 
-static snd_kcontrol_new_t snd_opl3sa2_tone_controls[] = {
+static struct snd_kcontrol_new snd_opl3sa2_tone_controls[] = {
 OPL3SA2_DOUBLE("3D Control - Wide", 0, 0x14, 0x14, 4, 0, 7, 0),
 OPL3SA2_DOUBLE("Tone Control - Bass", 0, 0x15, 0x15, 4, 0, 7, 0),
 OPL3SA2_DOUBLE("Tone Control - Treble", 0, 0x16, 0x16, 4, 0, 7, 0)
 };
 
-static void snd_opl3sa2_master_free(snd_kcontrol_t *kcontrol)
+static void snd_opl3sa2_master_free(struct snd_kcontrol *kcontrol)
 {
-	opl3sa2_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opl3sa2 *chip = snd_kcontrol_chip(kcontrol);
 	chip->master_switch = NULL;
 	chip->master_volume = NULL;
 }
 
-static int __init snd_opl3sa2_mixer(opl3sa2_t *chip)
+static int __init snd_opl3sa2_mixer(struct snd_opl3sa2 *chip)
 {
-	snd_card_t *card = chip->card;
-	snd_ctl_elem_id_t id1, id2;
-	snd_kcontrol_t *kctl;
+	struct snd_card *card = chip->card;
+	struct snd_ctl_elem_id id1, id2;
+	struct snd_kcontrol *kctl;
 	unsigned int idx;
 	int err;
 
@@ -505,21 +500,29 @@
 	/* reassign AUX0 to CD */
         strcpy(id1.name, "Aux Playback Switch");
         strcpy(id2.name, "CD Playback Switch");
-        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+		snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
                 return err;
+	}
         strcpy(id1.name, "Aux Playback Volume");
         strcpy(id2.name, "CD Playback Volume");
-        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+		snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
                 return err;
+	}
 	/* reassign AUX1 to FM */
         strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
         strcpy(id2.name, "FM Playback Switch");
-        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+		snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
                 return err;
+	}
         strcpy(id1.name, "Aux Playback Volume");
         strcpy(id2.name, "FM Playback Volume");
-        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)
+        if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0) {
+		snd_printk(KERN_ERR "Cannot rename opl3sa2 control\n");
                 return err;
+	}
 	/* add OPL3SA2 controls */
 	for (idx = 0; idx < ARRAY_SIZE(snd_opl3sa2_controls); idx++) {
 		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_opl3sa2_controls[idx], chip))) < 0)
@@ -539,22 +542,21 @@
 
 /* Power Management support functions */
 #ifdef CONFIG_PM
-static int snd_opl3sa2_suspend(snd_card_t *card, pm_message_t state)
+static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state)
 {
-	opl3sa2_t *chip = card->pm_private_data;
+	struct snd_opl3sa2 *chip = card->private_data;
 
-	snd_pcm_suspend_all(chip->cs4231->pcm); /* stop before saving regs */
-	chip->cs4231_suspend(chip->cs4231);
-
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	chip->cs4231->suspend(chip->cs4231);
 	/* power down */
 	snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3);
 
 	return 0;
 }
 
-static int snd_opl3sa2_resume(snd_card_t *card)
+static int snd_opl3sa2_resume(struct snd_card *card)
 {
-	opl3sa2_t *chip = card->pm_private_data;
+	struct snd_opl3sa2 *chip = card->private_data;
 	int i;
 
 	/* power up */
@@ -570,26 +572,25 @@
 			snd_opl3sa2_write(chip, i, chip->ctlregs[i]);
 	}
 	/* restore cs4231 */
-	chip->cs4231_resume(chip->cs4231);
+	chip->cs4231->resume(chip->cs4231);
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
 #ifdef CONFIG_PNP
-static int __init snd_opl3sa2_pnp(int dev, opl3sa2_t *chip,
-				  struct pnp_dev *pdev,
-				  int isapnp)
+static int __init snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
+				  struct pnp_dev *pdev)
 {
 	struct pnp_resource_table * cfg;
 	int err;
 
-	if (!isapnp && pnp_device_is_isapnp(pdev))
-		return -ENOENT;	/* we have another procedure - card */
-
 	cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
-	if (!cfg)
+	if (!cfg) {
+		snd_printk(KERN_ERR PFX "cannot allocate pnp cfg\n");
 		return -ENOMEM;
+	}
 	/* PnP initialization */
 	pnp_init_resource_table(cfg);
 	if (sb_port[dev] != SNDRV_AUTO_PORT)
@@ -609,8 +610,8 @@
 	if (irq[dev] != SNDRV_AUTO_IRQ)
 		pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1);
 	err = pnp_manual_config_dev(pdev, cfg, 0);
-	if (err < 0 && isapnp)
-		snd_printk(KERN_ERR "PnP manual resources are invalid, using auto config\n");
+	if (err < 0)
+		snd_printk(KERN_WARNING "PnP manual resources are invalid, using auto config\n");
 	err = pnp_activate_dev(pdev);
 	if (err < 0) {
 		kfree(cfg);
@@ -630,111 +631,47 @@
 	snd_printdd("%sPnP OPL3-SA: control port=0x%lx, dma1=%i, dma2=%i, irq=%i\n",
 		pnp_device_is_pnpbios(pdev) ? "BIOS" : "ISA", port[dev], dma1[dev], dma2[dev], irq[dev]);
 	kfree(cfg);
-	chip->dev = pdev;
 	return 0;
 }
-
-static int __init snd_opl3sa2_cpnp(int dev, opl3sa2_t *chip,
-				   struct pnp_card_link *card,
-				   const struct pnp_card_device_id *id)
-{
-	struct pnp_dev *pdev;
-	struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);
-
-	if (!cfg)
-		return -ENOMEM;
-	pdev = pnp_request_card_device(card, id->devs[0].id, NULL);
-	if (pdev == NULL) {
-		kfree(cfg);
-		return -EBUSY;
-	}
-	return snd_opl3sa2_pnp(dev, chip, pdev, 1);
-}
 #endif /* CONFIG_PNP */
 
-static int snd_opl3sa2_free(opl3sa2_t *chip)
+static void snd_opl3sa2_free(struct snd_card *card)
 {
+	struct snd_opl3sa2 *chip = card->private_data;
 	if (chip->irq >= 0)
 		free_irq(chip->irq, (void *)chip);
 	release_and_free_resource(chip->res_port);
-	kfree(chip);
-	return 0;
 }
 
-static int snd_opl3sa2_dev_free(snd_device_t *device)
+static struct snd_card *snd_opl3sa2_card_new(int dev)
 {
-	opl3sa2_t *chip = device->device_data;
-	return snd_opl3sa2_free(chip);
-}
-
-#ifdef CONFIG_PNP
-#define is_isapnp_selected(dev)		isapnp[dev]
-#else
-#define is_isapnp_selected(dev)		0
-#endif
-
-static int __devinit snd_opl3sa2_probe(int dev,
-				       struct pnp_dev *pdev,
-				       struct pnp_card_link *pcard,
-				       const struct pnp_card_device_id *pid)
-{
-	int xirq, xdma1, xdma2;
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_opl3sa2 *chip;
-	cs4231_t *cs4231;
-	opl3_t *opl3;
-	static snd_device_ops_t ops = {
-		.dev_free =	snd_opl3sa2_dev_free,
-	};
-	int err;
 
-	if (! is_isapnp_selected(dev)) {
-		if (port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR PFX "specify port\n");
-			return -EINVAL;
-		}
-		if (wss_port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR PFX "specify wss_port\n");
-			return -EINVAL;
-		}
-		if (fm_port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR PFX "specify fm_port\n");
-			return -EINVAL;
-		}
-		if (midi_port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk(KERN_ERR PFX "specify midi_port\n");
-			return -EINVAL;
-		}
-	}
-
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct snd_opl3sa2));
 	if (card == NULL)
-		return -ENOMEM;
+		return NULL;
 	strcpy(card->driver, "OPL3SA2");
 	strcpy(card->shortname, "Yamaha OPL3-SA2");
-	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-	if (chip == NULL) {
-		err = -ENOMEM;
-		goto __error;
-	}
+	chip = card->private_data;
 	spin_lock_init(&chip->reg_lock);
 	chip->irq = -1;
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
-		goto __error;
-#ifdef CONFIG_PNP
-	if (pdev) {
-		if ((err = snd_opl3sa2_pnp(dev, chip, pdev, 0)) < 0)
-			goto __error;
-		snd_card_set_dev(card, &pdev->dev);
-	}
-	if (pcard) {
-		if ((err = snd_opl3sa2_cpnp(dev, chip, pcard, pid)) < 0)
-			goto __error;
-		snd_card_set_dev(card, &pcard->card->dev);
-	}
-#endif
-	chip->ymode = opl3sa3_ymode[dev] & 0x03 ; /* initialise this card from supplied (or default) parameter*/ 
 	chip->card = card;
+	card->private_free = snd_opl3sa2_free;
+	return card;
+}
+
+static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev)
+{
+	int xirq, xdma1, xdma2;
+	struct snd_opl3sa2 *chip;
+	struct snd_cs4231 *cs4231;
+	struct snd_opl3 *opl3;
+	int err;
+
+	/* initialise this card from supplied (or default) parameter*/ 
+	chip = card->private_data;
+	chip->ymode = opl3sa3_ymode[dev] & 0x03 ;
 	chip->port = port[dev];
 	xirq = irq[dev];
 	xdma1 = dma1[dev];
@@ -742,11 +679,10 @@
 	if (xdma2 < 0)
 		chip->single_dma = 1;
 	if ((err = snd_opl3sa2_detect(chip)) < 0)
-		goto __error;
-	if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2", (void *)chip)) {
+		return err;
+	if (request_irq(xirq, snd_opl3sa2_interrupt, SA_INTERRUPT, "OPL3-SA2", chip)) {
 		snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
-		err = -ENODEV;
-		goto __error;
+		return -ENODEV;
 	}
 	chip->irq = xirq;
 	if ((err = snd_cs4231_create(card,
@@ -756,179 +692,303 @@
 				     CS4231_HWSHARE_IRQ,
 				     &cs4231)) < 0) {
 		snd_printd("Oops, WSS not detected at 0x%lx\n", wss_port[dev] + 4);
-		goto __error;
+		return err;
 	}
 	chip->cs4231 = cs4231;
 	if ((err = snd_cs4231_pcm(cs4231, 0, NULL)) < 0)
-		goto __error;
+		return err;
 	if ((err = snd_cs4231_mixer(cs4231)) < 0)
-		goto __error;
+		return err;
 	if ((err = snd_opl3sa2_mixer(chip)) < 0)
-		goto __error;
+		return err;
 	if ((err = snd_cs4231_timer(cs4231, 0, NULL)) < 0)
-		goto __error;
+		return err;
 	if (fm_port[dev] >= 0x340 && fm_port[dev] < 0x400) {
 		if ((err = snd_opl3_create(card, fm_port[dev],
 					   fm_port[dev] + 2,
 					   OPL3_HW_OPL3, 0, &opl3)) < 0)
-			goto __error;
+			return err;
 		if ((err = snd_opl3_timer_new(opl3, 1, 2)) < 0)
-			goto __error;
+			return err;
 		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, &chip->synth)) < 0)
-			goto __error;
+			return err;
 	}
 	if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) {
 		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2,
 					       midi_port[dev], 0,
 					       xirq, 0, &chip->rmidi)) < 0)
-			goto __error;
+			return err;
 	}
-#ifdef CONFIG_PM
-	chip->cs4231_suspend = chip->cs4231->suspend;
-	chip->cs4231_resume = chip->cs4231->resume;
-	/* now clear callbacks for cs4231 */
-	chip->cs4231->suspend = NULL;
-	chip->cs4231->resume = NULL;
-	snd_card_set_isa_pm_callback(card, snd_opl3sa2_suspend, snd_opl3sa2_resume, chip);
-#endif
-
 	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
 		card->shortname, chip->port, xirq, xdma1);
 	if (dma2 >= 0)
 		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto __error;
-
-	if ((err = snd_card_register(card)) < 0)
-		goto __error;
-
-	if (pdev)
-		pnp_set_drvdata(pdev, card);
-	else if (pcard)
-		pnp_set_card_drvdata(pcard, card);
-	else
-		snd_opl3sa2_legacy[dev] = card;
-	return 0;
-
- __error:
-	snd_card_free(card);
-	return err;
+	return snd_card_register(card);
 }
 
 #ifdef CONFIG_PNP
 static int __devinit snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
 					    const struct pnp_device_id *id)
 {
-        static int dev;
-        int res;
+	static int dev;
+	int err;
+	struct snd_card *card;
 
-        for ( ; dev < SNDRV_CARDS; dev++) {
-                if (!enable[dev] || !isapnp[dev])
-                        continue;
-                res = snd_opl3sa2_probe(dev, pdev, NULL, NULL);
-                if (res < 0)
-                        return res;
-                dev++;
-                return 0;
-        }
-        return -ENODEV;
+	if (pnp_device_is_isapnp(pdev))
+		return -ENOENT;	/* we have another procedure - card */
+	for (; dev < SNDRV_CARDS; dev++) {
+		if (enable[dev] && isapnp[dev])
+			break;
+	}
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+
+	card = snd_opl3sa2_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	snd_card_set_dev(card, &pdev->dev);
+	if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	pnp_set_drvdata(pdev, card);
+	dev++;
+	return 0;
 }
 
 static void __devexit snd_opl3sa2_pnp_remove(struct pnp_dev * pdev)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_drvdata(pdev);
-        
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_drvdata(pdev));
+	pnp_set_drvdata(pdev, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_opl3sa2_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
+{
+	return snd_opl3sa2_suspend(pnp_get_drvdata(pdev), state);
+}
+static int snd_opl3sa2_pnp_resume(struct pnp_dev *pdev)
+{
+	return snd_opl3sa2_resume(pnp_get_drvdata(pdev));
+}
+#endif
+
 static struct pnp_driver opl3sa2_pnp_driver = {
 	.name = "opl3sa2-pnpbios",
 	.id_table = snd_opl3sa2_pnpbiosids,
 	.probe = snd_opl3sa2_pnp_detect,
 	.remove = __devexit_p(snd_opl3sa2_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend = snd_opl3sa2_pnp_suspend,
+	.resume = snd_opl3sa2_pnp_resume,
+#endif
 };
 
-static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *card,
+static int __devinit snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
 					     const struct pnp_card_device_id *id)
 {
-        static int dev;
-        int res;
+	static int dev;
+	struct pnp_dev *pdev;
+	int err;
+	struct snd_card *card;
 
-        for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev])
-			continue;
-		if (is_isapnp_selected(dev))
-			continue;
-                res = snd_opl3sa2_probe(dev, NULL, card, id);
-                if (res < 0)
-                        return res;
-                dev++;
-                return 0;
-        }
-        return -ENODEV;
+	pdev = pnp_request_card_device(pcard, id->devs[0].id, NULL);
+	if (pdev == NULL) {
+		snd_printk(KERN_ERR PFX "can't get pnp device from id '%s'\n",
+			   id->devs[0].id);
+		return -EBUSY;
+	}
+	for (; dev < SNDRV_CARDS; dev++) {
+		if (enable[dev] && isapnp[dev])
+			break;
+	}
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+
+	card = snd_opl3sa2_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	if ((err = snd_opl3sa2_pnp(dev, card->private_data, pdev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	snd_card_set_dev(card, &pdev->dev);
+	if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	pnp_set_card_drvdata(pcard, card);
+	dev++;
+	return 0;
 }
 
 static void __devexit snd_opl3sa2_pnp_cremove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-        
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_opl3sa2_pnp_csuspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	return snd_opl3sa2_suspend(pnp_get_card_drvdata(pcard), state);
+}
+static int snd_opl3sa2_pnp_cresume(struct pnp_card_link *pcard)
+{
+	return snd_opl3sa2_resume(pnp_get_card_drvdata(pcard));
+}
+#endif
+
 static struct pnp_card_driver opl3sa2_pnpc_driver = {
 	.flags = PNP_DRIVER_RES_DISABLE,
 	.name = "opl3sa2",
 	.id_table = snd_opl3sa2_pnpids,
 	.probe = snd_opl3sa2_pnp_cdetect,
 	.remove = __devexit_p(snd_opl3sa2_pnp_cremove),
+#ifdef CONFIG_PM
+	.suspend = snd_opl3sa2_pnp_csuspend,
+	.resume = snd_opl3sa2_pnp_cresume,
+#endif
 };
 #endif /* CONFIG_PNP */
 
+static int __init snd_opl3sa2_nonpnp_probe(struct platform_device *pdev)
+{
+	struct snd_card *card;
+	int err;
+	int dev = pdev->id;
+
+	if (port[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR PFX "specify port\n");
+		return -EINVAL;
+	}
+	if (wss_port[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR PFX "specify wss_port\n");
+		return -EINVAL;
+	}
+	if (fm_port[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR PFX "specify fm_port\n");
+		return -EINVAL;
+	}
+	if (midi_port[dev] == SNDRV_AUTO_PORT) {
+		snd_printk(KERN_ERR PFX "specify midi_port\n");
+		return -EINVAL;
+	}
+
+	card = snd_opl3sa2_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	snd_card_set_dev(card, &pdev->dev);
+	if ((err = snd_opl3sa2_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	platform_set_drvdata(pdev, card);
+	return 0;
+}
+
+static int snd_opl3sa2_nonpnp_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_opl3sa2_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+{
+	return snd_opl3sa2_suspend(platform_get_drvdata(dev), state);
+}
+
+static int snd_opl3sa2_nonpnp_resume(struct platform_device *dev)
+{
+	return snd_opl3sa2_resume(platform_get_drvdata(dev));
+}
+#endif
+
+#define OPL3SA2_DRIVER	"snd_opl3sa2"
+
+static struct platform_driver snd_opl3sa2_nonpnp_driver = {
+	.probe		= snd_opl3sa2_nonpnp_probe,
+	.remove		= snd_opl3sa2_nonpnp_remove,
+#ifdef CONFIG_PM
+	.suspend	= snd_opl3sa2_nonpnp_suspend,
+	.resume		= snd_opl3sa2_nonpnp_resume,
+#endif
+	.driver		= {
+		.name	= OPL3SA2_DRIVER
+	},
+};
+
+static void __init_or_module snd_opl3sa2_unregister_all(void)
+{
+	int i;
+
+	if (pnpc_registered)
+		pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
+	if (pnp_registered)
+		pnp_unregister_driver(&opl3sa2_pnp_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_opl3sa2_nonpnp_driver);
+}
+
 static int __init alsa_card_opl3sa2_init(void)
 {
-	int dev, cards = 0;
+	int i, err, cards = 0;
 
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev])
-			continue;
+	if ((err = platform_driver_register(&snd_opl3sa2_nonpnp_driver)) < 0)
+		return err;
+
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
 #ifdef CONFIG_PNP
-		if (isapnp[dev])
+		if (isapnp[i])
 			continue;
 #endif
-		if (snd_opl3sa2_probe(dev, NULL, NULL, NULL) >= 0)
-			cards++;
+		device = platform_device_register_simple(OPL3SA2_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		platform_devices[i] = device;
+		cards++;
 	}
-#ifdef CONFIG_PNP
-	cards += pnp_register_driver(&opl3sa2_pnp_driver);
-	cards += pnp_register_card_driver(&opl3sa2_pnpc_driver);
-#endif
+
+	err = pnp_register_driver(&opl3sa2_pnp_driver);
+	if (err >= 0) {
+		pnp_registered = 1;
+		cards += err;
+	}
+	err = pnp_register_card_driver(&opl3sa2_pnpc_driver);
+	if (err >= 0) {
+		pnpc_registered = 1;
+		cards += err;
+	}
+
 	if (!cards) {
 #ifdef MODULE
 		snd_printk(KERN_ERR "Yamaha OPL3-SA soundcard not found or device busy\n");
 #endif
-#ifdef CONFIG_PNP
-		pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
-		pnp_unregister_driver(&opl3sa2_pnp_driver);
-#endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_opl3sa2_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_opl3sa2_exit(void)
 {
-	int idx;
-
-#ifdef CONFIG_PNP
-	/* PnP cards first */
-	pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
-	pnp_unregister_driver(&opl3sa2_pnp_driver);
-#endif
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_opl3sa2_legacy[idx]);
+	snd_opl3sa2_unregister_all();
 }
 
 module_init(alsa_card_opl3sa2_init)
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index b94339f..1ea3944 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -24,13 +24,15 @@
 
 
 #include <sound/driver.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
+#include <asm/io.h>
+#include <asm/dma.h>
 #include <sound/core.h>
 #ifdef CS4231
 #include <sound/cs4231.h>
@@ -120,8 +122,6 @@
 
 #define OPTi9XX_MC_REG(n)	n
 
-typedef struct _snd_opti9xx opti9xx_t;
-
 #ifdef OPTi93X
 
 #define OPTi93X_INDEX			0x00
@@ -193,16 +193,14 @@
 #define OPTi93X_IRQ_CAPTURE		0x08
 
 
-typedef struct _snd_opti93x opti93x_t;
-
-struct _snd_opti93x {
+struct snd_opti93x {
 	unsigned long port;
 	struct resource *res_port;
 	int irq;
 	int dma1;
 	int dma2;
 
-	opti9xx_t *chip;
+	struct snd_opti9xx *chip;
 	unsigned short hardware;
 	unsigned char image[32];
 
@@ -212,10 +210,10 @@
 
 	spinlock_t lock;
 
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
 	unsigned int p_dma_size;
 	unsigned int c_dma_size;
 };
@@ -227,7 +225,7 @@
 
 #endif /* OPTi93X */
 
-struct _snd_opti9xx {
+struct snd_opti9xx {
 	unsigned short hardware;
 	unsigned char password;
 	char name[7];
@@ -260,8 +258,8 @@
 #endif	/* CONFIG_PNP */
 };
 
-static int snd_opti9xx_first_hit = 1;
-static snd_card_t *snd_opti9xx_legacy = SNDRV_DEFAULT_PTR1;
+static int snd_opti9xx_pnp_is_probed;
+static struct platform_device *snd_opti9xx_platform_device;
 
 #ifdef CONFIG_PNP
 
@@ -296,7 +294,7 @@
 };
 
 
-static long snd_legacy_find_free_ioport(long *port_table, long size)
+static long __init snd_legacy_find_free_ioport(long *port_table, long size)
 {
 	while (*port_table != -1) {
 		if (request_region(*port_table, size, "ALSA test")) {
@@ -308,7 +306,7 @@
 	return -1;
 }
 
-static int __devinit snd_opti9xx_init(opti9xx_t *chip, unsigned short hardware)
+static int __init snd_opti9xx_init(struct snd_opti9xx *chip, unsigned short hardware)
 {
 	static int opti9xx_mc_size[] = {7, 7, 10, 10, 2, 2, 2};
 
@@ -363,7 +361,7 @@
 	return 0;
 }
 
-static unsigned char snd_opti9xx_read(opti9xx_t *chip,
+static unsigned char snd_opti9xx_read(struct snd_opti9xx *chip,
 				      unsigned char reg)
 {
 	unsigned long flags;
@@ -406,7 +404,7 @@
 	return retval;
 }
 	
-static void snd_opti9xx_write(opti9xx_t *chip, unsigned char reg,
+static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
 			      unsigned char value)
 {
 	unsigned long flags;
@@ -453,7 +451,7 @@
 		(snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
 
 
-static int __devinit snd_opti9xx_configure(opti9xx_t *chip)
+static int __init snd_opti9xx_configure(struct snd_opti9xx *chip)
 {
 	unsigned char wss_base_bits;
 	unsigned char irq_bits;
@@ -684,7 +682,7 @@
 };
 
 
-static int snd_opti93x_busy_wait(opti93x_t *chip)
+static int snd_opti93x_busy_wait(struct snd_opti93x *chip)
 {
 	int timeout;
 
@@ -696,14 +694,14 @@
 	return -EBUSY;
 }
 
-static unsigned char snd_opti93x_in(opti93x_t *chip, unsigned char reg)
+static unsigned char snd_opti93x_in(struct snd_opti93x *chip, unsigned char reg)
 {
 	snd_opti93x_busy_wait(chip);
 	outb(chip->mce_bit | (reg & 0x1f), OPTi93X_PORT(chip, INDEX));
 	return inb(OPTi93X_PORT(chip, DATA));
 }
 
-static void snd_opti93x_out(opti93x_t *chip, unsigned char reg,
+static void snd_opti93x_out(struct snd_opti93x *chip, unsigned char reg,
 			    unsigned char value)
 {
 	snd_opti93x_busy_wait(chip);
@@ -711,13 +709,13 @@
 	outb(value, OPTi93X_PORT(chip, DATA));
 }
 
-static void snd_opti93x_out_image(opti93x_t *chip, unsigned char reg,
+static void snd_opti93x_out_image(struct snd_opti93x *chip, unsigned char reg,
 				  unsigned char value)
 {
 	snd_opti93x_out(chip, reg, chip->image[reg] = value);
 }
 
-static void snd_opti93x_out_mask(opti93x_t *chip, unsigned char reg,
+static void snd_opti93x_out_mask(struct snd_opti93x *chip, unsigned char reg,
 				 unsigned char mask, unsigned char value)
 {
 	snd_opti93x_out_image(chip, reg,
@@ -725,7 +723,7 @@
 }
 
 
-static void snd_opti93x_mce_up(opti93x_t *chip)
+static void snd_opti93x_mce_up(struct snd_opti93x *chip)
 {
 	snd_opti93x_busy_wait(chip);
 
@@ -734,7 +732,7 @@
 		outb(chip->mce_bit, OPTi93X_PORT(chip, INDEX));
 }
 
-static void snd_opti93x_mce_down(opti93x_t *chip)
+static void snd_opti93x_mce_down(struct snd_opti93x *chip)
 {
 	snd_opti93x_busy_wait(chip);
 
@@ -746,7 +744,7 @@
 #define snd_opti93x_mute_reg(chip, reg, mute)	\
 	snd_opti93x_out(chip, reg, mute ? 0x80 : chip->image[reg]);
 
-static void snd_opti93x_mute(opti93x_t *chip, int mute)
+static void snd_opti93x_mute(struct snd_opti93x *chip, int mute)
 {
 	mute = mute ? 1 : 0;
 	if (chip->mute == mute)
@@ -798,7 +796,7 @@
 				44100, 48000 };
 #define RATES ARRAY_SIZE(rates)
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 	.count = RATES,
 	.list = rates,
 	.mask = 0,
@@ -820,7 +818,7 @@
 	return bits[RATES-1];
 }
 
-static unsigned char snd_opti93x_get_format(opti93x_t *chip,
+static unsigned char snd_opti93x_get_format(struct snd_opti93x *chip,
 					    unsigned int format, int channels)
 {
 	unsigned char retval = OPTi93X_LINEAR_8;
@@ -845,7 +843,7 @@
 }
 
 
-static void snd_opti93x_playback_format(opti93x_t *chip, unsigned char fmt)
+static void snd_opti93x_playback_format(struct snd_opti93x *chip, unsigned char fmt)
 {
 	unsigned char mask;
 
@@ -859,7 +857,7 @@
 	snd_opti93x_mute(chip, 0);
 }
 
-static void snd_opti93x_capture_format(opti93x_t *chip, unsigned char fmt)
+static void snd_opti93x_capture_format(struct snd_opti93x *chip, unsigned char fmt)
 {
 	snd_opti93x_mute(chip, 1);
 
@@ -875,7 +873,7 @@
 }
 
 
-static int snd_opti93x_open(opti93x_t *chip, unsigned int mode)
+static int snd_opti93x_open(struct snd_opti93x *chip, unsigned int mode)
 {
 	unsigned long flags;
 
@@ -899,7 +897,7 @@
 	return 0;
 }
 
-static void snd_opti93x_close(opti93x_t *chip, unsigned int mode)
+static void snd_opti93x_close(struct snd_opti93x *chip, unsigned int mode)
 {
 	unsigned long flags;
 
@@ -926,10 +924,10 @@
 	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
-static int snd_opti93x_trigger(snd_pcm_substream_t *substream, 
+static int snd_opti93x_trigger(struct snd_pcm_substream *substream, 
 			       unsigned char what, int cmd)
 {
-	opti93x_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -937,7 +935,7 @@
 	{
 		unsigned int what = 0;
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
+		struct snd_pcm_substream *s;
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == chip->playback_substream) {
@@ -964,36 +962,36 @@
 	return 0;
 }
 
-static int snd_opti93x_playback_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_opti93x_playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	return snd_opti93x_trigger(substream,
 				   OPTi93X_PLAYBACK_ENABLE, cmd);
 }
 
-static int snd_opti93x_capture_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_opti93x_capture_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	return snd_opti93x_trigger(substream,
 				   OPTi93X_CAPTURE_ENABLE, cmd);
 }
 
-static int snd_opti93x_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_opti93x_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
 
-static int snd_opti93x_hw_free(snd_pcm_substream_t * substream)
+static int snd_opti93x_hw_free(struct snd_pcm_substream *substream)
 {
 	snd_pcm_lib_free_pages(substream);
 	return 0;
 }
 
 
-static int snd_opti93x_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_opti93x_playback_prepare(struct snd_pcm_substream *substream)
 {
-	opti93x_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 	unsigned char format;
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -1023,10 +1021,10 @@
 	return 0;
 }
 
-static int snd_opti93x_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_opti93x_capture_prepare(struct snd_pcm_substream *substream)
 {
-	opti93x_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 	unsigned char format;
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -1055,9 +1053,9 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_opti93x_playback_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_opti93x_playback_pointer(struct snd_pcm_substream *substream)
 {
-	opti93x_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_PLAYBACK_ENABLE))
@@ -1067,9 +1065,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_opti93x_capture_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_opti93x_capture_pointer(struct snd_pcm_substream *substream)
 {
-	opti93x_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	
 	if (!(chip->image[OPTi93X_IFACE_CONF] & OPTi93X_CAPTURE_ENABLE))
@@ -1080,7 +1078,7 @@
 }
 
 
-static void snd_opti93x_overrange(opti93x_t *chip)
+static void snd_opti93x_overrange(struct snd_opti93x *chip)
 {
 	unsigned long flags;
 
@@ -1094,7 +1092,7 @@
 
 static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	opti93x_t *codec = dev_id;
+	struct snd_opti93x *codec = dev_id;
 	unsigned char status;
 
 	status = snd_opti9xx_read(codec->chip, OPTi9XX_MC_REG(11));
@@ -1109,7 +1107,7 @@
 }
 
 
-static snd_pcm_hardware_t snd_opti93x_playback = {
+static struct snd_pcm_hardware snd_opti93x_playback = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
 	.formats =		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
@@ -1127,7 +1125,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_opti93x_capture = {
+static struct snd_pcm_hardware snd_opti93x_capture = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
 	.formats =		(SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
@@ -1145,11 +1143,11 @@
 	.fifo_size =		0,
 };
 
-static int snd_opti93x_playback_open(snd_pcm_substream_t *substream)
+static int snd_opti93x_playback_open(struct snd_pcm_substream *substream)
 {
 	int error;
-	opti93x_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if ((error = snd_opti93x_open(chip, OPTi93X_MODE_PLAY)) < 0)
 		return error;
@@ -1161,11 +1159,11 @@
 	return error;
 }
 
-static int snd_opti93x_capture_open(snd_pcm_substream_t *substream)
+static int snd_opti93x_capture_open(struct snd_pcm_substream *substream)
 {
 	int error;
-	opti93x_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if ((error = snd_opti93x_open(chip, OPTi93X_MODE_CAPTURE)) < 0)
 		return error;
@@ -1177,18 +1175,18 @@
 	return error;
 }
 
-static int snd_opti93x_playback_close(snd_pcm_substream_t *substream)
+static int snd_opti93x_playback_close(struct snd_pcm_substream *substream)
 {
-	opti93x_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
 
 	chip->playback_substream = NULL;
 	snd_opti93x_close(chip, OPTi93X_MODE_PLAY);
 	return 0;
 }
 
-static int snd_opti93x_capture_close(snd_pcm_substream_t *substream)
+static int snd_opti93x_capture_close(struct snd_pcm_substream *substream)
 {
-	opti93x_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_opti93x *chip = snd_pcm_substream_chip(substream);
 
 	chip->capture_substream = NULL;
 	snd_opti93x_close(chip, OPTi93X_MODE_CAPTURE);
@@ -1196,7 +1194,7 @@
 }
 
 
-static void snd_opti93x_init(opti93x_t *chip)
+static void snd_opti93x_init(struct snd_opti93x *chip)
 {
 	unsigned long flags;
 	int i;
@@ -1211,7 +1209,7 @@
 	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
-static int snd_opti93x_probe(opti93x_t *chip)
+static int snd_opti93x_probe(struct snd_opti93x *chip)
 {
 	unsigned long flags;
 	unsigned char val;
@@ -1223,7 +1221,7 @@
 	return (val == 0x0a) ? 0 : -ENODEV;
 }
 
-static int snd_opti93x_free(opti93x_t *chip)
+static int snd_opti93x_free(struct snd_opti93x *chip)
 {
 	release_and_free_resource(chip->res_port);
 	if (chip->dma1 >= 0) {
@@ -1241,13 +1239,13 @@
 	return 0;
 }
 
-static int snd_opti93x_dev_free(snd_device_t *device)
+static int snd_opti93x_dev_free(struct snd_device *device)
 {
-	opti93x_t *chip = device->device_data;
+	struct snd_opti93x *chip = device->device_data;
 	return snd_opti93x_free(chip);
 }
 
-static const char *snd_opti93x_chip_id(opti93x_t *codec)
+static const char *snd_opti93x_chip_id(struct snd_opti93x *codec)
 {
 	switch (codec->hardware) {
 	case OPTi9XX_HW_82C930: return "82C930";
@@ -1257,15 +1255,15 @@
 	}
 }
 
-static int snd_opti93x_create(snd_card_t *card, opti9xx_t *chip,
+static int snd_opti93x_create(struct snd_card *card, struct snd_opti9xx *chip,
 			      int dma1, int dma2,
-			      opti93x_t **rcodec)
+			      struct snd_opti93x **rcodec)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_opti93x_dev_free,
 	};
 	int error;
-	opti93x_t *codec;
+	struct snd_opti93x *codec;
 
 	*rcodec = NULL;
 	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
@@ -1324,7 +1322,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_opti93x_playback_ops = {
+static struct snd_pcm_ops snd_opti93x_playback_ops = {
 	.open =		snd_opti93x_playback_open,
 	.close =	snd_opti93x_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1335,7 +1333,7 @@
 	.pointer =	snd_opti93x_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_opti93x_capture_ops = {
+static struct snd_pcm_ops snd_opti93x_capture_ops = {
 	.open =		snd_opti93x_capture_open,
 	.close =	snd_opti93x_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1346,17 +1344,10 @@
 	.pointer =	snd_opti93x_capture_pointer,
 };
 
-static void snd_opti93x_pcm_free(snd_pcm_t *pcm)
-{
-	opti93x_t *codec = pcm->private_data;
-	codec->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int snd_opti93x_pcm(opti93x_t *codec, int device, snd_pcm_t **rpcm)
+static int snd_opti93x_pcm(struct snd_opti93x *codec, int device, struct snd_pcm **rpcm)
 {
 	int error;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 
 	if ((error = snd_pcm_new(codec->card, "OPTi 82C93X", device, 1, 1, &pcm)))
 		return error;
@@ -1365,7 +1356,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_opti93x_capture_ops);
 
 	pcm->private_data = codec;
-	pcm->private_free = snd_opti93x_pcm_free;
 	pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
 
 	strcpy(pcm->name, snd_opti93x_chip_id(codec));
@@ -1384,7 +1374,7 @@
  *  MIXER part
  */
 
-static int snd_opti93x_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_opti93x_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = {
 		"Line1", "Aux", "Mic", "Mix"
@@ -1399,9 +1389,9 @@
 	return 0;
 }
 
-static int snd_opti93x_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opti93x_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opti93x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&chip->lock, flags);
@@ -1411,9 +1401,9 @@
 	return 0;
 }
 
-static int snd_opti93x_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opti93x_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opti93x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned short left, right;
 	int change;
@@ -1442,7 +1432,7 @@
   .get = snd_opti93x_get_single, .put = snd_opti93x_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_opti93x_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_opti93x_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -1453,9 +1443,9 @@
 	return 0;
 }
 
-static int snd_opti93x_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opti93x_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opti93x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -1470,9 +1460,9 @@
 	return 0;
 }
 
-static int snd_opti93x_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opti93x_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opti93x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -1507,7 +1497,7 @@
 	do { xctl.private_value &= ~0x0000ffff; \
 	     xctl.private_value |= left_reg | (right_reg << 8); } while (0)
 
-static int snd_opti93x_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_opti93x_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -1518,9 +1508,9 @@
 	return 0;
 }
 
-static int snd_opti93x_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opti93x_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opti93x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -1540,9 +1530,9 @@
 	return 0;
 }
 
-static int snd_opti93x_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_opti93x_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	opti93x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_opti93x *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -1571,7 +1561,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_opti93x_controls[] = {
+static struct snd_kcontrol_new snd_opti93x_controls[] = {
 OPTi93X_DOUBLE("Master Playback Switch", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
 OPTi93X_DOUBLE("Master Playback Volume", 0, OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1), 
 OPTi93X_DOUBLE("PCM Playback Switch", 0, OPTi93X_DAC_LEFT, OPTi93X_DAC_RIGHT, 7, 7, 1, 1),
@@ -1597,10 +1587,10 @@
 }
 };
                                         
-static int snd_opti93x_mixer(opti93x_t *chip)
+static int snd_opti93x_mixer(struct snd_opti93x *chip)
 {
-	snd_card_t *card;
-	snd_kcontrol_new_t knew;
+	struct snd_card *card;
+	struct snd_kcontrol_new knew;
 	int err;
 	unsigned int idx;
 
@@ -1632,7 +1622,7 @@
 
 #endif /* OPTi93X */
 
-static int __devinit snd_card_opti9xx_detect(snd_card_t *card, opti9xx_t *chip)
+static int __init snd_card_opti9xx_detect(struct snd_card *card, struct snd_opti9xx *chip)
 {
 	int i, err;
 
@@ -1686,8 +1676,8 @@
 }
 
 #ifdef CONFIG_PNP
-static int __devinit snd_card_opti9xx_pnp(opti9xx_t *chip, struct pnp_card_link *card,
-					  const struct pnp_card_device_id *pid)
+static int __init snd_card_opti9xx_pnp(struct snd_opti9xx *chip, struct pnp_card_link *card,
+				       const struct pnp_card_device_id *pid)
 {
 	struct pnp_dev *pdev;
 	struct pnp_resource_table *cfg = kmalloc(sizeof(*cfg), GFP_KERNEL);
@@ -1778,195 +1768,35 @@
 }
 #endif	/* CONFIG_PNP */
 
-#if 0
-static int __devinit snd_card_opti9xx_resources(struct snd_card_opti9xx *chip,
-						snd_card_t *card)
+static void snd_card_opti9xx_free(struct snd_card *card)
 {
-	int error, i, pnp = 0;
-
-#ifdef CONFIG_PNP
-	pnp = chip->dev != NULL;
-#endif	/* CONFIG_PNP */
-
-#ifndef OPTi93X
-	if (chip->chip->hardware == OPTi9XX_HW_82C928)
-		mpu_port = -1;
-#endif	/* OPTi93X */
-	error = 0;
-	if (!pnp && (mpu_port == SNDRV_DEFAULT_PORT1)) {
-		for (i = 0; possible_mpu_ports[i] != -1; i++)
-			if (!snd_register_ioport(card, possible_mpu_ports[i], 2,
-					DRIVER_NAME" - MPU-401", NULL)) {
-				mpu_port = possible_mpu_ports[i];
-				break;
-			}
-		if (mpu_port == SNDRV_DEFAULT_PORT1)
-			error = -EBUSY;
-	}
-	else
-		error = (mpu_port == -1) ? -ENODEV :
-			snd_register_ioport(card, mpu_port, 2,
-			DRIVER_NAME" - MPU-401", NULL);
-	if (error)
-		chip->chip->mpu_port = -1;
-	else if (pnp && (irq == mpu_irq))
-		chip->chip->mpu_irq = mpu_irq;
-	else if (!snd_register_interrupt(card,
-			DRIVER_NAME" - MPU-401",
-			mpu_irq, SNDRV_IRQ_TYPE_ISA,
-			snd_card_opti9xx_mpu_interrupt, chip,
-			pnp ? no_alternatives : possible_mpu_irqs,
-			&chip->mpuirqptr)) {
-		chip->chip->mpu_port = mpu_port;
-		chip->chip->mpu_irq = chip->mpuirqptr->irq;
-	}
-	else
-		chip->chip->mpu_port = -1;
-
-	if (!pnp && (port == SNDRV_DEFAULT_PORT1)) {
-		for (i = 0; possible_ports[i] != -1; i++)
-			if (!snd_register_ioport(card, possible_ports[i], 8,
-					DRIVER_NAME" - WSS", NULL)) {
-				port = possible_ports[i];
-				break;
-			}
-		if (port == SNDRV_DEFAULT_PORT1)
-			return -EBUSY;
-	}
-	else if ((error = snd_register_ioport(card, port, 8,
-			DRIVER_NAME" - WSS", NULL)) < 0)
-		return error;
-	chip->chip->wss_base = port;
-	if ((error = snd_register_interrupt(card, DRIVER_NAME" - WSS",
-			irq, SNDRV_IRQ_TYPE_ISA,
-			snd_card_opti9xx_interrupt, chip,
-			pnp ? no_alternatives : possible_irqs,
-			&chip->irqptr)) < 0)
-		return error;
-	chip->chip->irq = chip->irqptr->irq;
-	if ((error = snd_register_dma_channel(card,
-#if defined(CS4231) || defined(OPTi93X)
-			DRIVER_NAME" - WSS playback",
-#else
-			DRIVER_NAME" - WSS",
-#endif	/* CS4231 || OPTi93X */
-			dma1, SNDRV_DMA_TYPE_ISA, dma1_size,
-			pnp ? no_alternatives : possible_dma1s,
-			&chip->dma1ptr)) < 0)
-		return error;
-	chip->chip->dma1 = chip->dma1ptr->dma;
-#if defined(CS4231) || defined(OPTi93X)
-	if ((error = snd_register_dma_channel(card, DRIVER_NAME" - WSS capture",
-			dma2, SNDRV_DMA_TYPE_ISA, dma2_size,
-			pnp ? no_alternatives :
-				possible_dma2s[chip->dma1ptr->dma],
-			&chip->dma2ptr)) < 0)
-		return error;
-	chip->chip->dma2 = chip->dma2ptr->dma;
-#endif	/* CS4231 || OPTi93X */
-
-	if (snd_register_ioport(card,
-			pnp ? fm_port : fm_port = 0x388, 4,
-			DRIVER_NAME" - OPL", NULL) < 0)
-		fm_port = -1;
-	chip->chip->fm_port = fm_port;
-
-	return 0;
-}
-#endif
-
-static void snd_card_opti9xx_free(snd_card_t *card)
-{
-	opti9xx_t *chip = (opti9xx_t *)card->private_data;
+	struct snd_opti9xx *chip = card->private_data;
         
 	if (chip)
 		release_and_free_resource(chip->res_mc_base);
 }
 
-static int snd_card_opti9xx_probe(struct pnp_card_link *pcard,
-				  const struct pnp_card_device_id *pid)
+static int __init snd_opti9xx_probe(struct snd_card *card)
 {
 	static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
-	static long possible_mpu_ports[] = {0x300, 0x310, 0x320, 0x330, -1};
-#ifdef OPTi93X
-	static int possible_irqs[] = {5, 9, 10, 11, 7, -1};
-#else
-	static int possible_irqs[] = {9, 10, 11, 7, -1};
-#endif	/* OPTi93X */
-	static int possible_mpu_irqs[] = {5, 9, 10, 7, -1};
-	static int possible_dma1s[] = {3, 1, 0, -1};
-#if defined(CS4231) || defined(OPTi93X)
-	static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
-#endif	/* CS4231 || OPTi93X */
 	int error;
-	opti9xx_t *chip;
+	struct snd_opti9xx *chip = card->private_data;
 #if defined(OPTi93X)
-	opti93x_t *codec;
+	struct snd_opti93x *codec;
 #elif defined(CS4231)
-	cs4231_t *codec;
-	snd_timer_t *timer;
+	struct snd_cs4231 *codec;
+	struct snd_timer *timer;
 #else
-	ad1848_t *codec;
+	struct snd_ad1848 *codec;
 #endif
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_rawmidi_t *rmidi;
-	snd_hwdep_t *synth;
-#ifdef CONFIG_PNP
-	int hw;
-#endif	/* CONFIG_PNP */
-
-	if (pcard && !snd_opti9xx_first_hit)
-		return -EBUSY;
-	if (!(card = snd_card_new(index, id, THIS_MODULE,
-				  sizeof(opti9xx_t))))
-		return -ENOMEM;
-	card->private_free = snd_card_opti9xx_free;
-	chip = (opti9xx_t *)card->private_data;
-
-#ifdef CONFIG_PNP
-	if (isapnp && pcard && (hw = snd_card_opti9xx_pnp(chip, pcard, pid)) > 0) {
-		switch (hw) {
-		case 0x0924:
-			hw = OPTi9XX_HW_82C924;
-			break;
-		case 0x0925:
-			hw = OPTi9XX_HW_82C925;
-			break;
-		case 0x0931:
-			hw = OPTi9XX_HW_82C931;
-			break;
-		default:
-			snd_card_free(card);
-			return -ENODEV;
-		}
-
-		if ((error = snd_opti9xx_init(chip, hw))) {
-			snd_card_free(card);
-			return error;
-		}
-		if (hw <= OPTi9XX_HW_82C930)
-			chip->mc_base -= 0x80;
-		snd_card_set_dev(card, &pcard->card->dev);
-	} else {
-#endif	/* CONFIG_PNP */
-		if ((error = snd_card_opti9xx_detect(card, chip)) < 0) {
-			snd_card_free(card);
-			return error;
-		}
-		if ((error = snd_card_set_generic_dev(card)) < 0) {
-			snd_card_free(card);
-			return error;
-		}
-#ifdef CONFIG_PNP
-	}
-#endif	/* CONFIG_PNP */
+	struct snd_pcm *pcm;
+	struct snd_rawmidi *rmidi;
+	struct snd_hwdep *synth;
 
 	if (! chip->res_mc_base &&
-	    (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) {
-		snd_card_free(card);
+	    (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
+						"OPTi9xx MC")) == NULL)
 		return -ENOMEM;
-	}
 
 	chip->wss_base = port;
 	chip->fm_port = fm_port;
@@ -1980,110 +1810,42 @@
 
 	if (chip->wss_base == SNDRV_AUTO_PORT) {
 		if ((chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) {
-			snd_card_free(card);
 			snd_printk("unable to find a free WSS port\n");
 			return -EBUSY;
 		}
 	}
-#ifdef CONFIG_PNP
-	if (!isapnp) {
-#endif
-	if (chip->mpu_port == SNDRV_AUTO_PORT) {
-		if ((chip->mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free MPU401 port\n");
-			return -EBUSY;
-		}
-	}
-	if (chip->irq == SNDRV_AUTO_IRQ) {
-		if ((chip->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free IRQ\n");
-			return -EBUSY;
-		}
-	}
-	if (chip->mpu_irq == SNDRV_AUTO_IRQ) {
-		if ((chip->mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) {
-			snd_card_free(card);
-			snd_printk("unable to find a free MPU401 IRQ\n");
-			return -EBUSY;
-		}
-	}
-	if (chip->dma1 == SNDRV_AUTO_DMA) {
-                if ((chip->dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) {
-                        snd_card_free(card);
-			snd_printk("unable to find a free DMA1\n");
-			return -EBUSY;
-		}
-        }
-#if defined(CS4231) || defined(OPTi93X)
-	if (chip->dma2 == SNDRV_AUTO_DMA) {
-                if ((chip->dma2 = snd_legacy_find_free_dma(possible_dma2s[chip->dma1 % 4])) < 0) {
-                        snd_card_free(card);
-			snd_printk("unable to find a free DMA2\n");
-			return -EBUSY;
-		}
-        }
-#endif
-
-#ifdef CONFIG_PNP
-	}
-#endif
-
-	if ((error = snd_opti9xx_configure(chip))) {
-		snd_card_free(card);
+	if ((error = snd_opti9xx_configure(chip)))
 		return error;
-	}
 
 #if defined(OPTi93X)
-	if ((error = snd_opti93x_create(card, chip, chip->dma1, chip->dma2, &codec))) {
-		snd_card_free(card);
+	if ((error = snd_opti93x_create(card, chip, chip->dma1, chip->dma2, &codec)))
 		return error;
-	}
-	if ((error = snd_opti93x_pcm(codec, 0, &pcm)) < 0) {
-		snd_card_free(card);
+	if ((error = snd_opti93x_pcm(codec, 0, &pcm)) < 0)
 		return error;
-	}
-	if ((error = snd_opti93x_mixer(codec)) < 0) {
-		snd_card_free(card);
+	if ((error = snd_opti93x_mixer(codec)) < 0)
 		return error;
-	}
 #elif defined(CS4231)
 	if ((error = snd_cs4231_create(card, chip->wss_base + 4, -1,
 				       chip->irq, chip->dma1, chip->dma2,
 				       CS4231_HW_DETECT,
 				       0,
-				       &codec)) < 0) {
-		snd_card_free(card);
+				       &codec)) < 0)
 		return error;
-	}
-	if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0) {
-		snd_card_free(card);
+	if ((error = snd_cs4231_pcm(codec, 0, &pcm)) < 0)
 		return error;
-	}
-	if ((error = snd_cs4231_mixer(codec)) < 0) {
-		snd_card_free(card);
+	if ((error = snd_cs4231_mixer(codec)) < 0)
 		return error;
-	}
-	if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0) {
-		snd_card_free(card);
+	if ((error = snd_cs4231_timer(codec, 0, &timer)) < 0)
 		return error;
-	}
 #else
 	if ((error = snd_ad1848_create(card, chip->wss_base + 4,
 				       chip->irq, chip->dma1,
-				       AD1848_HW_DETECT, &codec)) < 0) {
-		snd_card_free(card);
+				       AD1848_HW_DETECT, &codec)) < 0)
 		return error;
-	}
-	if ((error = snd_ad1848_pcm(codec, 0, &pcm)) < 0) {
-		snd_card_free(card);
+	if ((error = snd_ad1848_pcm(codec, 0, &pcm)) < 0)
 		return error;
-	}
-	if ((error = snd_ad1848_mixer(codec)) < 0) {
-		snd_card_free(card);
+	if ((error = snd_ad1848_mixer(codec)) < 0)
 		return error;
-	}
 #endif
 	strcpy(card->driver, chip->name);
 	sprintf(card->shortname, "OPTi %s", card->driver);
@@ -2103,15 +1865,16 @@
 		if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
 				chip->mpu_port, 0, chip->mpu_irq, SA_INTERRUPT,
 				&rmidi)))
-			snd_printk("no MPU-401 device at 0x%lx?\n", chip->mpu_port);
+			snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
+				   chip->mpu_port);
 
 	if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) {
-		opl3_t *opl3 = NULL;
+		struct snd_opl3 *opl3 = NULL;
 #ifndef OPTi93X
 		if (chip->hardware == OPTi9XX_HW_82C928 ||
 		    chip->hardware == OPTi9XX_HW_82C929 ||
 		    chip->hardware == OPTi9XX_HW_82C924) {
-			opl4_t *opl4;
+			struct snd_opl4 *opl4;
 			/* assume we have an OPL4 */
 			snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
 					       0x20, 0x20);
@@ -2129,89 +1892,230 @@
 					     chip->fm_port,
 					     chip->fm_port + 2,
 					     OPL3_HW_AUTO, 0, &opl3) < 0) {
-			snd_printk("no OPL device at 0x%lx-0x%lx\n",
+			snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
 				   chip->fm_port, chip->fm_port + 4 - 1);
 		}
 		if (opl3) {
-			if ((error = snd_opl3_timer_new(opl3,
 #ifdef CS4231
-							1, 2)) < 0) {
+			const int t1dev = 1;
 #else
-							0, 1)) < 0) {
-#endif	/* CS4231 */
-				snd_card_free(card);
+			const int t1dev = 0;
+#endif
+			if ((error = snd_opl3_timer_new(opl3, t1dev, t1dev+1)) < 0)
 				return error;
-			}
-			if ((error = snd_opl3_hwdep_new(opl3, 0, 1, &synth)) < 0) {
-				snd_card_free(card);
+			if ((error = snd_opl3_hwdep_new(opl3, 0, 1, &synth)) < 0)
 				return error;
-			}
 		}
 	}
 
-	if ((error = snd_card_register(card))) {
+	return snd_card_register(card);
+}
+
+static struct snd_card *snd_opti9xx_card_new(void)
+{
+	struct snd_card *card;
+
+	card = snd_card_new(index, id, THIS_MODULE, sizeof(struct snd_opti9xx));
+	if (! card)
+		return NULL;
+	card->private_free = snd_card_opti9xx_free;
+	return card;
+}
+
+static int __init snd_opti9xx_nonpnp_probe(struct platform_device *devptr)
+{
+	struct snd_card *card;
+	int error;
+	static long possible_mpu_ports[] = {0x300, 0x310, 0x320, 0x330, -1};
+#ifdef OPTi93X
+	static int possible_irqs[] = {5, 9, 10, 11, 7, -1};
+#else
+	static int possible_irqs[] = {9, 10, 11, 7, -1};
+#endif	/* OPTi93X */
+	static int possible_mpu_irqs[] = {5, 9, 10, 7, -1};
+	static int possible_dma1s[] = {3, 1, 0, -1};
+#if defined(CS4231) || defined(OPTi93X)
+	static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
+#endif	/* CS4231 || OPTi93X */
+
+	if (snd_opti9xx_pnp_is_probed)
+		return -EBUSY;
+
+	if (mpu_port == SNDRV_AUTO_PORT) {
+		if ((mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
+			snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
+			return -EBUSY;
+		}
+	}
+	if (irq == SNDRV_AUTO_IRQ) {
+		if ((irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+			snd_printk(KERN_ERR "unable to find a free IRQ\n");
+			return -EBUSY;
+		}
+	}
+	if (mpu_irq == SNDRV_AUTO_IRQ) {
+		if ((mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) {
+			snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
+			return -EBUSY;
+		}
+	}
+	if (dma1 == SNDRV_AUTO_DMA) {
+		if ((dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) {
+			snd_printk(KERN_ERR "unable to find a free DMA1\n");
+			return -EBUSY;
+		}
+	}
+#if defined(CS4231) || defined(OPTi93X)
+	if (dma2 == SNDRV_AUTO_DMA) {
+		if ((dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4])) < 0) {
+			snd_printk("unable to find a free DMA2\n");
+			return -EBUSY;
+		}
+	}
+#endif
+
+	card = snd_opti9xx_card_new();
+	if (! card)
+		return -ENOMEM;
+
+	if ((error = snd_card_opti9xx_detect(card, card->private_data)) < 0) {
 		snd_card_free(card);
 		return error;
 	}
-	snd_opti9xx_first_hit = 0;
-	if (pcard)
-		pnp_set_card_drvdata(pcard, card);
-	else
-		snd_opti9xx_legacy = card;
+	snd_card_set_dev(card, &devptr->dev);
+	if ((error = snd_opti9xx_probe(card)) < 0) {
+		snd_card_free(card);
+		return error;
+	}
+	platform_set_drvdata(devptr, card);
 	return 0;
 }
 
+static int __devexit snd_opti9xx_nonpnp_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+static struct platform_driver snd_opti9xx_driver = {
+	.probe		= snd_opti9xx_nonpnp_probe,
+	.remove		= __devexit_p(snd_opti9xx_nonpnp_remove),
+	/* FIXME: suspend/resume */
+	.driver		= {
+		.name	= DRIVER_NAME
+	},
+};
+
 #ifdef CONFIG_PNP
+static int __init snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
+					const struct pnp_card_device_id *pid)
+{
+	struct snd_card *card;
+	int error, hw;
+	struct snd_opti9xx *chip;
+
+	if (snd_opti9xx_pnp_is_probed)
+		return -EBUSY;
+	if (! isapnp)
+		return -ENODEV;
+	card = snd_opti9xx_card_new();
+	if (! card)
+		return -ENOMEM;
+	chip = card->private_data;
+
+	hw = snd_card_opti9xx_pnp(chip, pcard, pid);
+	switch (hw) {
+	case 0x0924:
+		hw = OPTi9XX_HW_82C924;
+		break;
+	case 0x0925:
+		hw = OPTi9XX_HW_82C925;
+		break;
+	case 0x0931:
+		hw = OPTi9XX_HW_82C931;
+		break;
+	default:
+		snd_card_free(card);
+		return -ENODEV;
+	}
+
+	if ((error = snd_opti9xx_init(chip, hw))) {
+		snd_card_free(card);
+		return error;
+	}
+	if (hw <= OPTi9XX_HW_82C930)
+		chip->mc_base -= 0x80;
+	snd_card_set_dev(card, &pcard->card->dev);
+	if ((error = snd_opti9xx_probe(card)) < 0) {
+		snd_card_free(card);
+		return error;
+	}
+	pnp_set_card_drvdata(pcard, card);
+	snd_opti9xx_pnp_is_probed = 1;
+	return 0;
+}
+
 static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
-	snd_opti9xx_first_hit = 0;
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
+	snd_opti9xx_pnp_is_probed = 0;
 }
 
 static struct pnp_card_driver opti9xx_pnpc_driver = {
 	.flags		= PNP_DRIVER_RES_DISABLE,
 	.name		= "opti9xx",
 	.id_table	= snd_opti9xx_pnpids,
-	.probe		= snd_card_opti9xx_probe,
+	.probe		= snd_opti9xx_pnp_probe,
 	.remove		= __devexit_p(snd_opti9xx_pnp_remove),
 };
 #endif
 
+#ifdef CONFIG_PNP
+#define is_isapnp_selected()	isapnp
+#else
+#define is_isapnp_selected()	0
+#endif
+#ifdef OPTi93X
+#define CHIP_NAME	"82C93x"
+#else
+#define CHIP_NAME	"82C92x"
+#endif
+
 static int __init alsa_card_opti9xx_init(void)
 {
-	int cards, error;
+	int error;
+	struct platform_device *device;
 
-#ifdef CONFIG_PNP
-	cards = pnp_register_card_driver(&opti9xx_pnpc_driver);
-#else
-	cards = 0;
-#endif
-	if (cards == 0 && (error = snd_card_opti9xx_probe(NULL, NULL)) < 0) {
-#ifdef CONFIG_PNP
-		pnp_unregister_card_driver(&opti9xx_pnpc_driver);
-#endif
-#ifdef MODULE
-#ifdef OPTi93X
-		printk(KERN_ERR "no OPTi 82C93x soundcard found\n");
-#else
-		printk(KERN_ERR "no OPTi 82C92x soundcard found\n");
-#endif	/* OPTi93X */
-#endif
-		return error;
+	pnp_register_card_driver(&opti9xx_pnpc_driver);
+	if (snd_opti9xx_pnp_is_probed)
+		return 0;
+	if (! is_isapnp_selected()) {
+		error = platform_driver_register(&snd_opti9xx_driver);
+		if (error < 0)
+			return error;
+		device = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+		if (!IS_ERR(device)) {
+			snd_opti9xx_platform_device = device;
+			return 0;
+		}
+		platform_driver_unregister(&snd_opti9xx_driver);
 	}
-	return 0;
+	pnp_unregister_card_driver(&opti9xx_pnpc_driver);
+#ifdef MODULE
+	printk(KERN_ERR "no OPTi " CHIP_NAME " soundcard found\n");
+#endif
+	return -ENODEV;
 }
 
 static void __exit alsa_card_opti9xx_exit(void)
 {
-#ifdef CONFIG_PNP
+	if (!snd_opti9xx_pnp_is_probed) {
+		platform_device_unregister(snd_opti9xx_platform_device);
+		platform_driver_unregister(&snd_opti9xx_driver);
+	}
 	pnp_unregister_card_driver(&opti9xx_pnpc_driver);
-#endif
-	if (snd_opti9xx_legacy)
-		snd_card_free(snd_opti9xx_legacy);
 }
 
 module_init(alsa_card_opti9xx_init)
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index b09c657..c0b8d61 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -45,7 +45,7 @@
  * directly.  The macros handle the port number and command word.
  */
 /* Write a word */
-void snd_emu8000_poke(emu8000_t *emu, unsigned int port, unsigned int reg, unsigned int val)
+void snd_emu8000_poke(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&emu->reg_lock, flags);
@@ -58,7 +58,7 @@
 }
 
 /* Read a word */
-unsigned short snd_emu8000_peek(emu8000_t *emu, unsigned int port, unsigned int reg)
+unsigned short snd_emu8000_peek(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
 {
 	unsigned short res;
 	unsigned long flags;
@@ -73,7 +73,7 @@
 }
 
 /* Write a double word */
-void snd_emu8000_poke_dw(emu8000_t *emu, unsigned int port, unsigned int reg, unsigned int val)
+void snd_emu8000_poke_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&emu->reg_lock, flags);
@@ -87,7 +87,7 @@
 }
 
 /* Read a double word */
-unsigned int snd_emu8000_peek_dw(emu8000_t *emu, unsigned int port, unsigned int reg)
+unsigned int snd_emu8000_peek_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
 {
 	unsigned short low;
 	unsigned int res;
@@ -107,7 +107,7 @@
  * Set up / close a channel to be used for DMA.
  */
 /*exported*/ void
-snd_emu8000_dma_chan(emu8000_t *emu, int ch, int mode)
+snd_emu8000_dma_chan(struct snd_emu8000 *emu, int ch, int mode)
 {
 	unsigned right_bit = (mode & EMU8000_RAM_RIGHT) ? 0x01000000 : 0;
 	mode &= EMU8000_RAM_MODE_MASK;
@@ -132,7 +132,7 @@
 /*
  */
 static void __init
-snd_emu8000_read_wait(emu8000_t *emu)
+snd_emu8000_read_wait(struct snd_emu8000 *emu)
 {
 	while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
 		schedule_timeout_interruptible(1);
@@ -144,7 +144,7 @@
 /*
  */
 static void __init
-snd_emu8000_write_wait(emu8000_t *emu)
+snd_emu8000_write_wait(struct snd_emu8000 *emu)
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
 		schedule_timeout_interruptible(1);
@@ -157,7 +157,7 @@
  * detect a card at the given port
  */
 static int __init
-snd_emu8000_detect(emu8000_t *emu)
+snd_emu8000_detect(struct snd_emu8000 *emu)
 {
 	/* Initialise */
 	EMU8000_HWCF1_WRITE(emu, 0x0059);
@@ -183,7 +183,7 @@
  * intiailize audio channels
  */
 static void __init
-init_audio(emu8000_t *emu)
+init_audio(struct snd_emu8000 *emu)
 {
 	int ch;
 
@@ -224,7 +224,7 @@
  * initialize DMA address
  */
 static void __init
-init_dma(emu8000_t *emu)
+init_dma(struct snd_emu8000 *emu)
 {
 	EMU8000_SMALR_WRITE(emu, 0);
 	EMU8000_SMARR_WRITE(emu, 0);
@@ -328,7 +328,7 @@
  * is meant to work
  */
 static void __init
-send_array(emu8000_t *emu, unsigned short *data, int size)
+send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
 {
 	int i;
 	unsigned short *p;
@@ -350,7 +350,7 @@
  * initialisation sequence in the adip.
  */
 static void __init
-init_arrays(emu8000_t *emu)
+init_arrays(struct snd_emu8000 *emu)
 {
 	send_array(emu, init1, ARRAY_SIZE(init1)/4);
 
@@ -376,7 +376,7 @@
  * reallocating between read and write.
  */
 static void __init
-size_dram(emu8000_t *emu)
+size_dram(struct snd_emu8000 *emu)
 {
 	int i, size;
 
@@ -455,7 +455,7 @@
  * and therefore lose 2 voices.
  */
 /*exported*/ void
-snd_emu8000_init_fm(emu8000_t *emu)
+snd_emu8000_init_fm(struct snd_emu8000 *emu)
 {
 	unsigned long flags;
 
@@ -501,7 +501,7 @@
  * The main initialization routine.
  */
 static void __init
-snd_emu8000_init_hw(emu8000_t *emu)
+snd_emu8000_init_hw(struct snd_emu8000 *emu)
 {
 	int i;
 
@@ -585,7 +585,7 @@
  * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
  */
 /*exported*/ void
-snd_emu8000_update_equalizer(emu8000_t *emu)
+snd_emu8000_update_equalizer(struct snd_emu8000 *emu)
 {
 	unsigned short w;
 	int bass = emu->bass_level;
@@ -628,17 +628,17 @@
 /* user can define chorus modes up to 32 */
 #define SNDRV_EMU8000_CHORUS_NUMBERS	32
 
-typedef struct soundfont_chorus_fx_t {
+struct soundfont_chorus_fx {
 	unsigned short feedback;	/* feedback level (0xE600-0xE6FF) */
 	unsigned short delay_offset;	/* delay (0-0x0DA3) [1/44100 sec] */
 	unsigned short lfo_depth;	/* LFO depth (0xBC00-0xBCFF) */
 	unsigned int delay;	/* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */
 	unsigned int lfo_freq;		/* LFO freq LFO freq (0-0xFFFFFFFF) */
-} soundfont_chorus_fx_t;
+};
 
 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
 static char chorus_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
-static soundfont_chorus_fx_t chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = {
+static struct soundfont_chorus_fx chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = {
 	{0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
 	{0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
 	{0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
@@ -650,9 +650,9 @@
 };
 
 /*exported*/ int
-snd_emu8000_load_chorus_fx(emu8000_t *emu, int mode, const void __user *buf, long len)
+snd_emu8000_load_chorus_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
 {
-	soundfont_chorus_fx_t rec;
+	struct soundfont_chorus_fx rec;
 	if (mode < SNDRV_EMU8000_CHORUS_PREDEFINED || mode >= SNDRV_EMU8000_CHORUS_NUMBERS) {
 		snd_printk(KERN_WARNING "invalid chorus mode %d for uploading\n", mode);
 		return -EINVAL;
@@ -665,7 +665,7 @@
 }
 
 /*exported*/ void
-snd_emu8000_update_chorus_mode(emu8000_t *emu)
+snd_emu8000_update_chorus_mode(struct snd_emu8000 *emu)
 {
 	int effect = emu->chorus_mode;
 	if (effect < 0 || effect >= SNDRV_EMU8000_CHORUS_NUMBERS ||
@@ -699,15 +699,15 @@
 /* user can define reverb modes up to 32 */
 #define SNDRV_EMU8000_REVERB_NUMBERS	32
 
-typedef struct soundfont_reverb_fx_t {
+struct soundfont_reverb_fx {
 	unsigned short parms[28];
-} soundfont_reverb_fx_t;
+};
 
 /* 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[SNDRV_EMU8000_CHORUS_NUMBERS];
-static soundfont_reverb_fx_t reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = {
+static struct soundfont_reverb_fx reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = {
 {{  /* room 1 */
 	0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
 	0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
@@ -777,9 +777,9 @@
 };
 
 /*exported*/ int
-snd_emu8000_load_reverb_fx(emu8000_t *emu, int mode, const void __user *buf, long len)
+snd_emu8000_load_reverb_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
 {
-	soundfont_reverb_fx_t rec;
+	struct soundfont_reverb_fx rec;
 
 	if (mode < SNDRV_EMU8000_REVERB_PREDEFINED || mode >= SNDRV_EMU8000_REVERB_NUMBERS) {
 		snd_printk(KERN_WARNING "invalid reverb mode %d for uploading\n", mode);
@@ -793,7 +793,7 @@
 }
 
 /*exported*/ void
-snd_emu8000_update_reverb_mode(emu8000_t *emu)
+snd_emu8000_update_reverb_mode(struct snd_emu8000 *emu)
 {
 	int effect = emu->reverb_mode;
 	int i;
@@ -819,7 +819,7 @@
 /*
  * bass/treble
  */
-static int mixer_bass_treble_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int mixer_bass_treble_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -828,17 +828,17 @@
 	return 0;
 }
 
-static int mixer_bass_treble_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int mixer_bass_treble_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu8000_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->treble_level : emu->bass_level;
 	return 0;
 }
 
-static int mixer_bass_treble_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int mixer_bass_treble_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu8000_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned short val1;
@@ -857,7 +857,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t mixer_bass_control =
+static struct snd_kcontrol_new mixer_bass_control =
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Synth Tone Control - Bass",
@@ -867,7 +867,7 @@
 	.private_value = 0,
 };
 
-static snd_kcontrol_new_t mixer_treble_control =
+static struct snd_kcontrol_new mixer_treble_control =
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Synth Tone Control - Treble",
@@ -880,7 +880,7 @@
 /*
  * chorus/reverb mode
  */
-static int mixer_chorus_reverb_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int mixer_chorus_reverb_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -889,17 +889,17 @@
 	return 0;
 }
 
-static int mixer_chorus_reverb_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int mixer_chorus_reverb_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu8000_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->chorus_mode : emu->reverb_mode;
 	return 0;
 }
 
-static int mixer_chorus_reverb_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int mixer_chorus_reverb_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu8000_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned short val1;
@@ -924,7 +924,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t mixer_chorus_mode_control =
+static struct snd_kcontrol_new mixer_chorus_mode_control =
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Chorus Mode",
@@ -934,7 +934,7 @@
 	.private_value = 1,
 };
 
-static snd_kcontrol_new_t mixer_reverb_mode_control =
+static struct snd_kcontrol_new mixer_reverb_mode_control =
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Reverb Mode",
@@ -947,7 +947,7 @@
 /*
  * FM OPL3 chorus/reverb depth
  */
-static int mixer_fm_depth_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int mixer_fm_depth_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -956,17 +956,17 @@
 	return 0;
 }
 
-static int mixer_fm_depth_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int mixer_fm_depth_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu8000_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->fm_chorus_depth : emu->fm_reverb_depth;
 	return 0;
 }
 
-static int mixer_fm_depth_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int mixer_fm_depth_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu8000_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned short val1;
@@ -986,7 +986,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t mixer_fm_chorus_depth_control =
+static struct snd_kcontrol_new mixer_fm_chorus_depth_control =
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "FM Chorus Depth",
@@ -996,7 +996,7 @@
 	.private_value = 1,
 };
 
-static snd_kcontrol_new_t mixer_fm_reverb_depth_control =
+static struct snd_kcontrol_new mixer_fm_reverb_depth_control =
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "FM Reverb Depth",
@@ -1007,7 +1007,7 @@
 };
 
 
-static snd_kcontrol_new_t *mixer_defs[EMU8000_NUM_CONTROLS] = {
+static struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = {
 	&mixer_bass_control,
 	&mixer_treble_control,
 	&mixer_chorus_mode_control,
@@ -1020,7 +1020,7 @@
  * create and attach mixer elements for WaveTable treble/bass controls
  */
 static int __init
-snd_emu8000_create_mixer(snd_card_t *card, emu8000_t *emu)
+snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
 {
 	int i, err = 0;
 
@@ -1049,7 +1049,7 @@
 /*
  * free resources
  */
-static int snd_emu8000_free(emu8000_t *hw)
+static int snd_emu8000_free(struct snd_emu8000 *hw)
 {
 	release_and_free_resource(hw->res_port1);
 	release_and_free_resource(hw->res_port2);
@@ -1060,9 +1060,9 @@
 
 /*
  */
-static int snd_emu8000_dev_free(snd_device_t *device)
+static int snd_emu8000_dev_free(struct snd_device *device)
 {
-	emu8000_t *hw = device->device_data;
+	struct snd_emu8000 *hw = device->device_data;
 	return snd_emu8000_free(hw);
 }
 
@@ -1070,12 +1070,13 @@
  * initialize and register emu8000 synth device.
  */
 int __init
-snd_emu8000_new(snd_card_t *card, int index, long port, int seq_ports, snd_seq_device_t **awe_ret)
+snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
+		struct snd_seq_device **awe_ret)
 {
-	snd_seq_device_t *awe;
-	emu8000_t *hw;
+	struct snd_seq_device *awe;
+	struct snd_emu8000 *hw;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_emu8000_dev_free,
 	};
 
@@ -1127,9 +1128,9 @@
 	}
 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
 	if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000,
-			       sizeof(emu8000_t*), &awe) >= 0) {
+			       sizeof(struct snd_emu8000*), &awe) >= 0) {
 		strcpy(awe->name, "EMU-8000");
-		*(emu8000_t**)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw;
+		*(struct snd_emu8000 **)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw;
 	}
 #else
 	awe = NULL;
diff --git a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c
index 1cc4101..9a3c71cc 100644
--- a/sound/isa/sb/emu8000_callback.c
+++ b/sound/isa/sb/emu8000_callback.c
@@ -25,27 +25,30 @@
 /*
  * prototypes
  */
-static snd_emux_voice_t *get_voice(snd_emux_t *emu, snd_emux_port_t *port);
-static int start_voice(snd_emux_voice_t *vp);
-static void trigger_voice(snd_emux_voice_t *vp);
-static void release_voice(snd_emux_voice_t *vp);
-static void update_voice(snd_emux_voice_t *vp, int update);
-static void reset_voice(snd_emux_t *emu, int ch);
-static void terminate_voice(snd_emux_voice_t *vp);
-static void sysex(snd_emux_t *emu, char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
+static struct snd_emux_voice *get_voice(struct snd_emux *emu,
+					struct snd_emux_port *port);
+static int start_voice(struct snd_emux_voice *vp);
+static void trigger_voice(struct snd_emux_voice *vp);
+static void release_voice(struct snd_emux_voice *vp);
+static void update_voice(struct snd_emux_voice *vp, int update);
+static void reset_voice(struct snd_emux *emu, int ch);
+static void terminate_voice(struct snd_emux_voice *vp);
+static void sysex(struct snd_emux *emu, char *buf, int len, int parsed,
+		  struct snd_midi_channel_set *chset);
 #ifdef CONFIG_SND_SEQUENCER_OSS
-static int oss_ioctl(snd_emux_t *emu, int cmd, int p1, int p2);
+static int oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2);
 #endif
-static int load_fx(snd_emux_t *emu, int type, int mode, const void __user *buf, long len);
+static int load_fx(struct snd_emux *emu, int type, int mode,
+		   const void __user *buf, long len);
 
-static void set_pitch(emu8000_t *hw, snd_emux_voice_t *vp);
-static void set_volume(emu8000_t *hw, snd_emux_voice_t *vp);
-static void set_pan(emu8000_t *hw, snd_emux_voice_t *vp);
-static void set_fmmod(emu8000_t *hw, snd_emux_voice_t *vp);
-static void set_tremfreq(emu8000_t *hw, snd_emux_voice_t *vp);
-static void set_fm2frq2(emu8000_t *hw, snd_emux_voice_t *vp);
-static void set_filterQ(emu8000_t *hw, snd_emux_voice_t *vp);
-static void snd_emu8000_tweak_voice(emu8000_t *emu, int ch);
+static void set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
+static void set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
+static void set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
+static void set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
+static void set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
+static void set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
+static void set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp);
+static void snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int ch);
 
 /*
  * Ensure a value is between two points
@@ -58,7 +61,7 @@
 /*
  * set up operators
  */
-static snd_emux_operators_t emu8000_ops = {
+static struct snd_emux_operators emu8000_ops = {
 	.owner =	THIS_MODULE,
 	.get_voice =	get_voice,
 	.prepare =	start_voice,
@@ -78,7 +81,7 @@
 };
 
 void
-snd_emu8000_ops_setup(emu8000_t *hw)
+snd_emu8000_ops_setup(struct snd_emu8000 *hw)
 {
 	hw->emu->ops = emu8000_ops;
 }
@@ -89,10 +92,10 @@
  * Terminate a voice
  */
 static void
-release_voice(snd_emux_voice_t *vp)
+release_voice(struct snd_emux_voice *vp)
 {
 	int dcysusv;
-	emu8000_t *hw;
+	struct snd_emu8000 *hw;
 
 	hw = vp->hw;
 	dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
@@ -105,9 +108,9 @@
 /*
  */
 static void
-terminate_voice(snd_emux_voice_t *vp)
+terminate_voice(struct snd_emux_voice *vp)
 {
-	emu8000_t *hw; 
+	struct snd_emu8000 *hw; 
 
 	hw = vp->hw;
 	EMU8000_DCYSUSV_WRITE(hw, vp->ch, 0x807F);
@@ -117,9 +120,9 @@
 /*
  */
 static void
-update_voice(snd_emux_voice_t *vp, int update)
+update_voice(struct snd_emux_voice *vp, int update)
 {
-	emu8000_t *hw;
+	struct snd_emu8000 *hw;
 
 	hw = vp->hw;
 	if (update & SNDRV_EMUX_UPDATE_VOLUME)
@@ -149,12 +152,12 @@
  * The channel index (vp->ch) must be initialized in this routine.
  * In Emu8k, it is identical with the array index.
  */
-static snd_emux_voice_t *
-get_voice(snd_emux_t *emu, snd_emux_port_t *port)
+static struct snd_emux_voice *
+get_voice(struct snd_emux *emu, struct snd_emux_port *port)
 {
 	int  i;
-	snd_emux_voice_t *vp;
-	emu8000_t *hw;
+	struct snd_emux_voice *vp;
+	struct snd_emu8000 *hw;
 
 	/* what we are looking for, in order of preference */
 	enum {
@@ -227,13 +230,13 @@
 /*
  */
 static int
-start_voice(snd_emux_voice_t *vp)
+start_voice(struct snd_emux_voice *vp)
 {
 	unsigned int temp;
 	int ch;
 	int addr;
-	snd_midi_channel_t *chan;
-	emu8000_t *hw;
+	struct snd_midi_channel *chan;
+	struct snd_emu8000 *hw;
 
 	hw = vp->hw;
 	ch = vp->ch;
@@ -307,11 +310,11 @@
  * Start envelope
  */
 static void
-trigger_voice(snd_emux_voice_t *vp)
+trigger_voice(struct snd_emux_voice *vp)
 {
 	int ch = vp->ch;
 	unsigned int temp;
-	emu8000_t *hw;
+	struct snd_emu8000 *hw;
 
 	hw = vp->hw;
 
@@ -329,9 +332,9 @@
  * reset voice parameters
  */
 static void
-reset_voice(snd_emux_t *emu, int ch)
+reset_voice(struct snd_emux *emu, int ch)
 {
-	emu8000_t *hw;
+	struct snd_emu8000 *hw;
 
 	hw = emu->hw;
 	EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F);
@@ -342,7 +345,7 @@
  * Set the pitch of a possibly playing note.
  */
 static void
-set_pitch(emu8000_t *hw, snd_emux_voice_t *vp)
+set_pitch(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 {
 	EMU8000_IP_WRITE(hw, vp->ch, vp->apitch);
 }
@@ -351,7 +354,7 @@
  * Set the volume of a possibly already playing note
  */
 static void
-set_volume(emu8000_t *hw, snd_emux_voice_t *vp)
+set_volume(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 {
 	int  ifatn;
 
@@ -365,7 +368,7 @@
  * Set pan and loop start address.
  */
 static void
-set_pan(emu8000_t *hw, snd_emux_voice_t *vp)
+set_pan(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 {
 	unsigned int temp;
 
@@ -376,7 +379,7 @@
 #define MOD_SENSE 18
 
 static void
-set_fmmod(emu8000_t *hw, snd_emux_voice_t *vp)
+set_fmmod(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 {
 	unsigned short fmmod;
 	short pitch;
@@ -394,14 +397,14 @@
 
 /* set tremolo (lfo1) volume & frequency */
 static void
-set_tremfreq(emu8000_t *hw, snd_emux_voice_t *vp)
+set_tremfreq(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 {
 	EMU8000_TREMFRQ_WRITE(hw, vp->ch, vp->reg.parm.tremfrq);
 }
 
 /* set lfo2 pitch & frequency */
 static void
-set_fm2frq2(emu8000_t *hw, snd_emux_voice_t *vp)
+set_fm2frq2(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 {
 	unsigned short fm2frq2;
 	short pitch;
@@ -419,7 +422,7 @@
 
 /* set filterQ */
 static void
-set_filterQ(emu8000_t *hw, snd_emux_voice_t *vp)
+set_filterQ(struct snd_emu8000 *hw, struct snd_emux_voice *vp)
 {
 	unsigned int addr;
 	addr = EMU8000_CCCA_READ(hw, vp->ch) & 0xffffff;
@@ -431,7 +434,7 @@
  * set the envelope & LFO parameters to the default values
  */
 static void
-snd_emu8000_tweak_voice(emu8000_t *emu, int i)
+snd_emu8000_tweak_voice(struct snd_emu8000 *emu, int i)
 {
 	/* set all mod/vol envelope shape to minimum */
 	EMU8000_ENVVOL_WRITE(emu, i, 0x8000);
@@ -453,9 +456,9 @@
  * sysex callback
  */
 static void
-sysex(snd_emux_t *emu, char *buf, int len, int parsed, snd_midi_channel_set_t *chset)
+sysex(struct snd_emux *emu, char *buf, int len, int parsed, struct snd_midi_channel_set *chset)
 {
-	emu8000_t *hw;
+	struct snd_emu8000 *hw;
 
 	hw = emu->hw;
 
@@ -478,9 +481,9 @@
  * OSS ioctl callback
  */
 static int
-oss_ioctl(snd_emux_t *emu, int cmd, int p1, int p2)
+oss_ioctl(struct snd_emux *emu, int cmd, int p1, int p2)
 {
-	emu8000_t *hw;
+	struct snd_emu8000 *hw;
 
 	hw = emu->hw;
 
@@ -523,9 +526,9 @@
  */
 
 static int
-load_fx(snd_emux_t *emu, int type, int mode, const void __user *buf, long len)
+load_fx(struct snd_emux *emu, int type, int mode, const void __user *buf, long len)
 {
-	emu8000_t *hw;
+	struct snd_emu8000 *hw;
 	hw = emu->hw;
 
 	/* skip header */
diff --git a/sound/isa/sb/emu8000_local.h b/sound/isa/sb/emu8000_local.h
index ea4996a..2ac77f1 100644
--- a/sound/isa/sb/emu8000_local.h
+++ b/sound/isa/sb/emu8000_local.h
@@ -30,14 +30,17 @@
 #include <sound/emu8000_reg.h>
 
 /* emu8000_patch.c */
-int snd_emu8000_sample_new(snd_emux_t *rec, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void __user *data, long count);
-int snd_emu8000_sample_free(snd_emux_t *rec, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr);
-void snd_emu8000_sample_reset(snd_emux_t *rec);
+int snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
+			   struct snd_util_memhdr *hdr,
+			   const void __user *data, long count);
+int snd_emu8000_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
+			    struct snd_util_memhdr *hdr);
+void snd_emu8000_sample_reset(struct snd_emux *rec);
 
 /* emu8000_callback.c */
-void snd_emu8000_ops_setup(emu8000_t *emu);
+void snd_emu8000_ops_setup(struct snd_emu8000 *emu);
 
 /* emu8000_pcm.c */
-int snd_emu8000_pcm_new(snd_card_t *card, emu8000_t *emu, int index);
+int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index);
 
 #endif	/* __EMU8000_LOCAL_H */
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c
index 2fea67e..80b1cf8 100644
--- a/sound/isa/sb/emu8000_patch.c
+++ b/sound/isa/sb/emu8000_patch.c
@@ -32,7 +32,7 @@
  * Open up channels.
  */
 static int
-snd_emu8000_open_dma(emu8000_t *emu, int write)
+snd_emu8000_open_dma(struct snd_emu8000 *emu, int write)
 {
 	int i;
 
@@ -59,7 +59,7 @@
  * Close all dram channels.
  */
 static void
-snd_emu8000_close_dma(emu8000_t *emu)
+snd_emu8000_close_dma(struct snd_emu8000 *emu)
 {
 	int i;
 
@@ -106,7 +106,7 @@
 /*
  */
 static void
-snd_emu8000_write_wait(emu8000_t *emu)
+snd_emu8000_write_wait(struct snd_emu8000 *emu)
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
 		schedule_timeout_interruptible(1);
@@ -128,7 +128,7 @@
  * working.
  */
 static inline void
-write_word(emu8000_t *emu, int *offset, unsigned short data)
+write_word(struct snd_emu8000 *emu, int *offset, unsigned short data)
 {
 	if (emu8000_reset_addr) {
 		if (emu8000_reset_addr > 1)
@@ -144,15 +144,16 @@
  * the generic soundfont routines as a callback.
  */
 int
-snd_emu8000_sample_new(snd_emux_t *rec, snd_sf_sample_t *sp,
-		       snd_util_memhdr_t *hdr, const void __user *data, long count)
+snd_emu8000_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
+		       struct snd_util_memhdr *hdr,
+		       const void __user *data, long count)
 {
 	int  i;
 	int  rc;
 	int  offset;
 	int  truesize;
 	int  dram_offset, dram_start;
-	emu8000_t *emu;
+	struct snd_emu8000 *emu;
 
 	emu = rec->hw;
 	snd_assert(sp != NULL, return -EINVAL);
@@ -282,7 +283,8 @@
  * free a sample block
  */
 int
-snd_emu8000_sample_free(snd_emux_t *rec, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr)
+snd_emu8000_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
+			struct snd_util_memhdr *hdr)
 {
 	if (sp->block) {
 		snd_util_mem_free(hdr, sp->block);
@@ -296,7 +298,7 @@
  * sample_reset callback - terminate voices
  */
 void
-snd_emu8000_sample_reset(snd_emux_t *rec)
+snd_emu8000_sample_reset(struct snd_emux *rec)
 {
 	snd_emux_terminate_all(rec);
 }
diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c
index b323bee..91dc3d8 100644
--- a/sound/isa/sb/emu8000_pcm.c
+++ b/sound/isa/sb/emu8000_pcm.c
@@ -46,14 +46,12 @@
  */
 
 
-typedef struct snd_emu8k_pcm emu8k_pcm_t;
-
 struct snd_emu8k_pcm {
-	emu8000_t *emu;
-	snd_pcm_substream_t *substream;
+	struct snd_emu8000 *emu;
+	struct snd_pcm_substream *substream;
 
 	unsigned int allocated_bytes;
-	snd_util_memblk_t *block;
+	struct snd_util_memblk *block;
 	unsigned int offset;
 	unsigned int buf_size;
 	unsigned int period_size;
@@ -77,7 +75,7 @@
  * open up channels for the simultaneous data transfer and playback
  */
 static int
-emu8k_open_dram_for_pcm(emu8000_t *emu, int channels)
+emu8k_open_dram_for_pcm(struct snd_emu8000 *emu, int channels)
 {
 	int i;
 
@@ -113,7 +111,7 @@
 /*
  */
 static void
-snd_emu8000_write_wait(emu8000_t *emu, int can_schedule)
+snd_emu8000_write_wait(struct snd_emu8000 *emu, int can_schedule)
 {
 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
 		if (can_schedule) {
@@ -128,7 +126,7 @@
  * close all channels
  */
 static void
-emu8k_close_dram(emu8000_t *emu)
+emu8k_close_dram(struct snd_emu8000 *emu)
 {
 	int i;
 
@@ -156,7 +154,7 @@
 /*
  */
 
-static snd_pcm_hardware_t emu8k_pcm_hw = {
+static struct snd_pcm_hardware emu8k_pcm_hw = {
 #ifdef USE_NONINTERLEAVE
 	.info =			SNDRV_PCM_INFO_NONINTERLEAVED,
 #else
@@ -180,7 +178,7 @@
 /*
  * get the current position at the given channel from CCCA register
  */
-static inline int emu8k_get_curpos(emu8k_pcm_t *rec, int ch)
+static inline int emu8k_get_curpos(struct snd_emu8k_pcm *rec, int ch)
 {
 	int val = EMU8000_CCCA_READ(rec->emu, ch) & 0xfffffff;
 	val -= rec->loop_start[ch] - 1;
@@ -194,7 +192,7 @@
  */
 static void emu8k_pcm_timer_func(unsigned long data)
 {
-	emu8k_pcm_t *rec = (emu8k_pcm_t *)data;
+	struct snd_emu8k_pcm *rec = (struct snd_emu8k_pcm *)data;
 	int ptr, delta;
 
 	spin_lock(&rec->timer_lock);
@@ -226,11 +224,11 @@
  * open pcm
  * creating an instance here
  */
-static int emu8k_pcm_open(snd_pcm_substream_t *subs)
+static int emu8k_pcm_open(struct snd_pcm_substream *subs)
 {
-	emu8000_t *emu = snd_pcm_substream_chip(subs);
-	emu8k_pcm_t *rec;
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_emu8000 *emu = snd_pcm_substream_chip(subs);
+	struct snd_emu8k_pcm *rec;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 
 	rec = kzalloc(sizeof(*rec), GFP_KERNEL);
 	if (! rec)
@@ -256,9 +254,9 @@
 	return 0;
 }
 
-static int emu8k_pcm_close(snd_pcm_substream_t *subs)
+static int emu8k_pcm_close(struct snd_pcm_substream *subs)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
 	kfree(rec);
 	subs->runtime->private_data = NULL;
 	return 0;
@@ -281,9 +279,9 @@
 /*
  * set up the voice
  */
-static void setup_voice(emu8k_pcm_t *rec, int ch)
+static void setup_voice(struct snd_emu8k_pcm *rec, int ch)
 {
-	emu8000_t *hw = rec->emu;
+	struct snd_emu8000 *hw = rec->emu;
 	unsigned int temp;
 
 	/* channel to be silent and idle */
@@ -334,10 +332,10 @@
 /*
  * trigger the voice
  */
-static void start_voice(emu8k_pcm_t *rec, int ch)
+static void start_voice(struct snd_emu8k_pcm *rec, int ch)
 {
 	unsigned long flags;
-	emu8000_t *hw = rec->emu;
+	struct snd_emu8000 *hw = rec->emu;
 	unsigned int temp, aux;
 	int pt = calc_pitch_target(rec->pitch);
 
@@ -370,10 +368,10 @@
 /*
  * stop the voice immediately
  */
-static void stop_voice(emu8k_pcm_t *rec, int ch)
+static void stop_voice(struct snd_emu8k_pcm *rec, int ch)
 {
 	unsigned long flags;
-	emu8000_t *hw = rec->emu;
+	struct snd_emu8000 *hw = rec->emu;
 
 	EMU8000_DCYSUSV_WRITE(hw, ch, 0x807F);
 
@@ -386,9 +384,9 @@
 	spin_unlock_irqrestore(&rec->timer_lock, flags);
 }
 
-static int emu8k_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
+static int emu8k_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
 	int ch;
 
 	switch (cmd) {
@@ -428,7 +426,7 @@
 
 #ifdef USE_NONINTERLEAVE
 /* copy one channel block */
-static int emu8k_transfer_block(emu8000_t *emu, int offset, unsigned short *buf, int count)
+static int emu8k_transfer_block(struct snd_emu8000 *emu, int offset, unsigned short *buf, int count)
 {
 	EMU8000_SMALW_WRITE(emu, offset);
 	while (count > 0) {
@@ -442,14 +440,14 @@
 	return 0;
 }
 
-static int emu8k_pcm_copy(snd_pcm_substream_t *subs,
+static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
 			  int voice,
 			  snd_pcm_uframes_t pos,
 			  void *src,
 			  snd_pcm_uframes_t count)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
-	emu8000_t *emu = rec->emu;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
+	struct snd_emu8000 *emu = rec->emu;
 
 	snd_emu8000_write_wait(emu, 1);
 	if (voice == -1) {
@@ -469,7 +467,7 @@
 }
 
 /* make a channel block silence */
-static int emu8k_silence_block(emu8000_t *emu, int offset, int count)
+static int emu8k_silence_block(struct snd_emu8000 *emu, int offset, int count)
 {
 	EMU8000_SMALW_WRITE(emu, offset);
 	while (count > 0) {
@@ -480,13 +478,13 @@
 	return 0;
 }
 
-static int emu8k_pcm_silence(snd_pcm_substream_t *subs,
+static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
 			     int voice,
 			     snd_pcm_uframes_t pos,
 			     snd_pcm_uframes_t count)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
-	emu8000_t *emu = rec->emu;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
+	struct snd_emu8000 *emu = rec->emu;
 
 	snd_emu8000_write_wait(emu, 1);
 	if (voice == -1 && rec->voices == 1)
@@ -508,14 +506,14 @@
  * copy the interleaved data can be done easily by using
  * DMA "left" and "right" channels on emu8k engine.
  */
-static int emu8k_pcm_copy(snd_pcm_substream_t *subs,
+static int emu8k_pcm_copy(struct snd_pcm_substream *subs,
 			  int voice,
 			  snd_pcm_uframes_t pos,
 			  void __user *src,
 			  snd_pcm_uframes_t count)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
-	emu8000_t *emu = rec->emu;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
+	struct snd_emu8000 *emu = rec->emu;
 	unsigned short __user *buf = src;
 
 	snd_emu8000_write_wait(emu, 1);
@@ -539,13 +537,13 @@
 	return 0;
 }
 
-static int emu8k_pcm_silence(snd_pcm_substream_t *subs,
+static int emu8k_pcm_silence(struct snd_pcm_substream *subs,
 			     int voice,
 			     snd_pcm_uframes_t pos,
 			     snd_pcm_uframes_t count)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
-	emu8000_t *emu = rec->emu;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
+	struct snd_emu8000 *emu = rec->emu;
 
 	snd_emu8000_write_wait(emu, 1);
 	EMU8000_SMALW_WRITE(emu, rec->loop_start[0] + pos);
@@ -567,10 +565,10 @@
 /*
  * allocate a memory block
  */
-static int emu8k_pcm_hw_params(snd_pcm_substream_t *subs,
-			       snd_pcm_hw_params_t *hw_params)
+static int emu8k_pcm_hw_params(struct snd_pcm_substream *subs,
+			       struct snd_pcm_hw_params *hw_params)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
 
 	if (rec->block) {
 		/* reallocation - release the old block */
@@ -592,9 +590,9 @@
 /*
  * free the memory block
  */
-static int emu8k_pcm_hw_free(snd_pcm_substream_t *subs)
+static int emu8k_pcm_hw_free(struct snd_pcm_substream *subs)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
 
 	if (rec->block) {
 		int ch;
@@ -610,9 +608,9 @@
 
 /*
  */
-static int emu8k_pcm_prepare(snd_pcm_substream_t *subs)
+static int emu8k_pcm_prepare(struct snd_pcm_substream *subs)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
 
 	rec->pitch = 0xe000 + calc_rate_offset(subs->runtime->rate);
 	rec->last_ptr = 0;
@@ -656,16 +654,16 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t emu8k_pcm_pointer(snd_pcm_substream_t *subs)
+static snd_pcm_uframes_t emu8k_pcm_pointer(struct snd_pcm_substream *subs)
 {
-	emu8k_pcm_t *rec = subs->runtime->private_data;
+	struct snd_emu8k_pcm *rec = subs->runtime->private_data;
 	if (rec->running)
 		return emu8k_get_curpos(rec, 0);
 	return 0;
 }
 
 
-static snd_pcm_ops_t emu8k_pcm_ops = {
+static struct snd_pcm_ops emu8k_pcm_ops = {
 	.open =		emu8k_pcm_open,
 	.close =	emu8k_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -679,15 +677,15 @@
 };
 
 
-static void snd_emu8000_pcm_free(snd_pcm_t *pcm)
+static void snd_emu8000_pcm_free(struct snd_pcm *pcm)
 {
-	emu8000_t *emu = pcm->private_data;
+	struct snd_emu8000 *emu = pcm->private_data;
 	emu->pcm = NULL;
 }
 
-int snd_emu8000_pcm_new(snd_card_t *card, emu8000_t *emu, int index)
+int snd_emu8000_pcm_new(struct snd_card *card, struct snd_emu8000 *emu, int index)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(card, "Emu8000 PCM", index, 1, 0, &pcm)) < 0)
diff --git a/sound/isa/sb/emu8000_synth.c b/sound/isa/sb/emu8000_synth.c
index f68e2174..3d72742 100644
--- a/sound/isa/sb/emu8000_synth.c
+++ b/sound/isa/sb/emu8000_synth.c
@@ -33,12 +33,12 @@
 /*
  * create a new hardware dependent device for Emu8000
  */
-static int snd_emu8000_new_device(snd_seq_device_t *dev)
+static int snd_emu8000_new_device(struct snd_seq_device *dev)
 {
-	emu8000_t *hw;
-	snd_emux_t *emu;
+	struct snd_emu8000 *hw;
+	struct snd_emux *emu;
 
-	hw = *(emu8000_t**)SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	hw = *(struct snd_emu8000**)SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	if (hw == NULL)
 		return -EINVAL;
 
@@ -92,9 +92,9 @@
 /*
  * free all resources
  */
-static int snd_emu8000_delete_device(snd_seq_device_t *dev)
+static int snd_emu8000_delete_device(struct snd_seq_device *dev)
 {
-	emu8000_t *hw;
+	struct snd_emu8000 *hw;
 
 	if (dev->driver_data == NULL)
 		return 0; /* no synth was allocated actually */
@@ -118,11 +118,12 @@
 static int __init alsa_emu8000_init(void)
 {
 	
-	static snd_seq_dev_ops_t ops = {
+	static struct snd_seq_dev_ops ops = {
 		snd_emu8000_new_device,
 		snd_emu8000_delete_device,
 	};
-	return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU8000, &ops, sizeof(emu8000_t*));
+	return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU8000, &ops,
+					      sizeof(struct snd_emu8000*));
 }
 
 static void __exit alsa_emu8000_exit(void)
diff --git a/sound/isa/sb/es968.c b/sound/isa/sb/es968.c
index c859917..9da80bf 100644
--- a/sound/isa/sb/es968.c
+++ b/sound/isa/sb/es968.c
@@ -58,6 +58,7 @@
 
 struct snd_card_es968 {
 	struct pnp_dev *dev;
+	struct snd_sb *chip;
 };
 
 static struct pnp_card_device_id snd_es968_pnpids[] = {
@@ -72,7 +73,7 @@
 static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id,
 					    struct pt_regs *regs)
 {
-	sb_t *chip = dev_id;
+	struct snd_sb *chip = dev_id;
 
 	if (chip->open & SB_OPEN_PCM) {
 		return snd_sb8dsp_interrupt(chip);
@@ -128,14 +129,14 @@
 					const struct pnp_card_device_id *pid)
 {
 	int error;
-	sb_t *chip;
-	snd_card_t *card;
+	struct snd_sb *chip;
+	struct snd_card *card;
 	struct snd_card_es968 *acard;
 
 	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 				 sizeof(struct snd_card_es968))) == NULL)
 		return -ENOMEM;
-	acard = (struct snd_card_es968 *)card->private_data;
+	acard = card->private_data;
 	if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) {
 		snd_card_free(card);
 		return error;
@@ -151,6 +152,7 @@
 		snd_card_free(card);
 		return error;
 	}
+	acard->chip = chip;
 
 	if ((error = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) {
 		snd_card_free(card);
@@ -200,30 +202,59 @@
 
 static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+	struct snd_card_es968 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(chip->pcm);
+	snd_sbmixer_suspend(chip);
+	return 0;
+}
+
+static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+	struct snd_card_es968 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_sbdsp_reset(chip);
+	snd_sbmixer_resume(chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
 static struct pnp_card_driver es968_pnpc_driver = {
 	.flags		= PNP_DRIVER_RES_DISABLE,
 	.name		= "es968",
 	.id_table	= snd_es968_pnpids,
 	.probe		= snd_es968_pnp_detect,
 	.remove		= __devexit_p(snd_es968_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_es968_pnp_suspend,
+	.resume		= snd_es968_pnp_resume,
+#endif
 };
 
 static int __init alsa_card_es968_init(void)
 {
 	int cards = pnp_register_card_driver(&es968_pnpc_driver);
-#ifdef MODULE
-	if (cards == 0) {
+	if (cards <= 0) {
 		pnp_unregister_card_driver(&es968_pnpc_driver);
+#ifdef MODULE
 		snd_printk(KERN_ERR "no ES968 based soundcards found\n");
-	}
 #endif
-	return cards ? 0 : -ENODEV;
+		return -ENODEV;
+	}
+	return 0;
 }
 
 static void __exit alsa_card_es968_exit(void)
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c
index c2fa451..c0be7a5 100644
--- a/sound/isa/sb/sb16.c
+++ b/sound/isa/sb/sb16.c
@@ -24,6 +24,8 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/pnp.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/sb.h>
@@ -32,7 +34,6 @@
 #include <sound/opl3.h>
 #include <sound/emu8000.h>
 #include <sound/seq_device.h>
-#define SNDRV_LEGACY_AUTO_PROBE
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
@@ -127,8 +128,14 @@
 MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
 #endif
 
+static struct platform_device *platform_devices[SNDRV_CARDS];
+#ifdef CONFIG_PNP
+static int pnp_registered;
+#endif
+
 struct snd_card_sb16 {
 	struct resource *fm_res;	/* used to block FM i/o region for legacy cards */
+	struct snd_sb *chip;
 #ifdef CONFIG_PNP
 	int dev_no;
 	struct pnp_dev *dev;
@@ -138,8 +145,6 @@
 #endif
 };
 
-static snd_card_t *snd_sb16_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
 #ifdef CONFIG_PNP
 
 static struct pnp_card_device_id snd_sb16_pnpids[] = {
@@ -339,9 +344,9 @@
 
 #endif /* CONFIG_PNP */
 
-static void snd_sb16_free(snd_card_t *card)
+static void snd_sb16_free(struct snd_card *card)
 {
-	struct snd_card_sb16 *acard = (struct snd_card_sb16 *)card->private_data;
+	struct snd_card_sb16 *acard = card->private_data;
         
 	if (acard == NULL)
 		return;
@@ -354,73 +359,32 @@
 #define is_isapnp_selected(dev)		0
 #endif
 
-static int __init snd_sb16_probe(int dev,
-				 struct pnp_card_link *pcard,
-				 const struct pnp_card_device_id *pid)
+static struct snd_card *snd_sb16_card_new(int dev)
 {
-	static int possible_irqs[] = {5, 9, 10, 7, -1};
-	static int possible_dmas8[] = {1, 3, 0, -1};
-	static int possible_dmas16[] = {5, 6, 7, -1};
+	struct snd_card *card = snd_card_new(index[dev], id[dev], THIS_MODULE,
+					sizeof(struct snd_card_sb16));
+	if (card == NULL)
+		return NULL;
+	card->private_free = snd_sb16_free;
+	return card;
+}
+
+static int __init snd_sb16_probe(struct snd_card *card, int dev)
+{
 	int xirq, xdma8, xdma16;
-	sb_t *chip;
-	snd_card_t *card;
-	struct snd_card_sb16 *acard;
-	opl3_t *opl3;
-	snd_hwdep_t *synth = NULL;
+	struct snd_sb *chip;
+	struct snd_card_sb16 *acard = card->private_data;
+	struct snd_opl3 *opl3;
+	struct snd_hwdep *synth = NULL;
 #ifdef CONFIG_SND_SB16_CSP
-	snd_hwdep_t *xcsp = NULL;
+	struct snd_hwdep *xcsp = NULL;
 #endif
 	unsigned long flags;
 	int err;
 
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
-			    sizeof(struct snd_card_sb16));
-	if (card == NULL)
-		return -ENOMEM;
-	acard = (struct snd_card_sb16 *) card->private_data;
-	card->private_free = snd_sb16_free;
-#ifdef CONFIG_PNP
-	if (isapnp[dev]) {
-		if ((err = snd_card_sb16_pnp(dev, acard, pcard, pid)))
-			goto _err;
-		snd_card_set_dev(card, &pcard->card->dev);
-	}
-#endif
-
 	xirq = irq[dev];
 	xdma8 = dma8[dev];
 	xdma16 = dma16[dev];
-	if (! is_isapnp_selected(dev)) {
-		if (xirq == SNDRV_AUTO_IRQ) {
-			if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
-				snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
-				err = -EBUSY;
-				goto _err;
-			}
-		}
-		if (xdma8 == SNDRV_AUTO_DMA) {
-			if ((xdma8 = snd_legacy_find_free_dma(possible_dmas8)) < 0) {
-				snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n");
-				err = -EBUSY;
-				goto _err;
-			}
-		}
-		if (xdma16 == SNDRV_AUTO_DMA) {
-			if ((xdma16 = snd_legacy_find_free_dma(possible_dmas16)) < 0) {
-				snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n");
-				err = -EBUSY;
-				goto _err;
-			}
-		}
-		/* non-PnP FM port address is hardwired with base port address */
-		fm_port[dev] = port[dev];
-		/* block the 0x388 port to avoid PnP conflicts */
-		acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
-#ifdef SNDRV_SBAWE_EMU8000
-		/* non-PnP AWE port address is hardwired with base port address */
-		awe_port[dev] = port[dev] + 0x400;
-#endif
-	}
 
 	if ((err = snd_sbdsp_create(card,
 				    port[dev],
@@ -430,19 +394,19 @@
 				    xdma16,
 				    SB_HW_AUTO,
 				    &chip)) < 0)
-		goto _err;
+		return err;
 
+	acard->chip = chip;
 	if (chip->hardware != SB_HW_16) {
 		snd_printk(KERN_ERR PFX "SB 16 chip was not detected at 0x%lx\n", port[dev]);
-		err = -ENODEV;
-		goto _err;
+		return -ENODEV;
 	}
 	chip->mpu_port = mpu_port[dev];
 	if (! is_isapnp_selected(dev) && (err = snd_sb16dsp_configure(chip)) < 0)
-		goto _err;
+		return err;
 
-	if ((err = snd_sb16dsp_pcm(chip, 0, NULL)) < 0)
-		goto _err;
+	if ((err = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0)
+		return err;
 
 	strcpy(card->driver,
 #ifdef SNDRV_SBAWE_EMU8000
@@ -464,7 +428,7 @@
 		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB,
 					       chip->mpu_port, 0,
 					       xirq, 0, &chip->rmidi)) < 0)
-			goto _err;
+			return err;
 		chip->rmidi_callback = snd_mpu401_uart_interrupt;
 	}
 
@@ -487,12 +451,12 @@
 			int seqdev = 1;
 #endif
 			if ((err = snd_opl3_hwdep_new(opl3, 0, seqdev, &synth)) < 0)
-				goto _err;
+				return err;
 		}
 	}
 
 	if ((err = snd_sbmixer_new(chip)) < 0)
-		goto _err;
+		return err;
 
 #ifdef CONFIG_SND_SB16_CSP
 	/* CSP chip on SB16ASP/AWE32 */
@@ -512,7 +476,7 @@
 					   seq_ports[dev], NULL)) < 0) {
 			snd_printk(KERN_ERR PFX "fatal error - EMU-8000 synthesizer not detected at 0x%lx\n", awe_port[dev]);
 
-			goto _err;
+			return err;
 		}
 	}
 #endif
@@ -524,56 +488,168 @@
 		(mic_agc[dev] ? 0x00 : 0x01));
 	spin_unlock_irqrestore(&chip->mixer_lock, flags);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
-
 	if ((err = snd_card_register(card)) < 0)
-		goto _err;
+		return err;
 
-	if (pcard)
-		pnp_set_card_drvdata(pcard, card);
-	else
-		snd_sb16_legacy[dev] = card;
 	return 0;
-
- _err:
-	snd_card_free(card);
-	return err;
 }
 
-static int __init snd_sb16_probe_legacy_port(unsigned long xport)
+#ifdef CONFIG_PM
+static int snd_sb16_suspend(struct snd_card *card, pm_message_t state)
 {
-	static int dev;
-	int res;
+	struct snd_card_sb16 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
 
-	for ( ; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
-			continue;
-		if (is_isapnp_selected(dev))
-			continue;
-		port[dev] = xport;
-		res = snd_sb16_probe(dev, NULL, NULL);
-		if (res < 0)
-			port[dev] = SNDRV_AUTO_PORT;
-		return res;
-	}
-	return -ENODEV;
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(chip->pcm);
+	snd_sbmixer_suspend(chip);
+	return 0;
 }
 
+static int snd_sb16_resume(struct snd_card *card)
+{
+	struct snd_card_sb16 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_sbdsp_reset(chip);
+	snd_sbmixer_resume(chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
+static int __init snd_sb16_nonpnp_probe1(int dev, struct platform_device *devptr)
+{
+	struct snd_card_sb16 *acard;
+	struct snd_card *card;
+	int err;
+
+	card = snd_sb16_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+
+	acard = card->private_data;
+	/* non-PnP FM port address is hardwired with base port address */
+	fm_port[dev] = port[dev];
+	/* block the 0x388 port to avoid PnP conflicts */
+	acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
+#ifdef SNDRV_SBAWE_EMU8000
+	/* non-PnP AWE port address is hardwired with base port address */
+	awe_port[dev] = port[dev] + 0x400;
+#endif
+
+	snd_card_set_dev(card, &devptr->dev);
+	if ((err = snd_sb16_probe(card, dev)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	platform_set_drvdata(devptr, card);
+	return 0;
+}
+
+
+static int __init snd_sb16_nonpnp_probe(struct platform_device *pdev)
+{
+	int dev = pdev->id;
+	int err;
+	static int possible_irqs[] = {5, 9, 10, 7, -1};
+	static int possible_dmas8[] = {1, 3, 0, -1};
+	static int possible_dmas16[] = {5, 6, 7, -1};
+
+	if (irq[dev] == SNDRV_AUTO_IRQ) {
+		if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {
+			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
+			return -EBUSY;
+		}
+	}
+	if (dma8[dev] == SNDRV_AUTO_DMA) {
+		if ((dma8[dev] = snd_legacy_find_free_dma(possible_dmas8)) < 0) {
+			snd_printk(KERN_ERR PFX "unable to find a free 8-bit DMA\n");
+			return -EBUSY;
+		}
+	}
+	if (dma16[dev] == SNDRV_AUTO_DMA) {
+		if ((dma16[dev] = snd_legacy_find_free_dma(possible_dmas16)) < 0) {
+			snd_printk(KERN_ERR PFX "unable to find a free 16-bit DMA\n");
+			return -EBUSY;
+		}
+	}
+
+	if (port[dev] != SNDRV_AUTO_PORT)
+		return snd_sb16_nonpnp_probe1(dev, pdev);
+	else {
+		static int possible_ports[] = {0x220, 0x240, 0x260, 0x280};
+		int i;
+		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
+			port[dev] = possible_ports[i];
+			err = snd_sb16_nonpnp_probe1(dev, pdev);
+			if (! err)
+				return 0;
+		}
+		return err;
+	}
+}
+
+static int __devexit snd_sb16_nonpnp_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_sb16_nonpnp_suspend(struct platform_device *dev, pm_message_t state)
+{
+	return snd_sb16_suspend(platform_get_drvdata(dev), state);
+}
+
+static int snd_sb16_nonpnp_resume(struct platform_device *dev)
+{
+	return snd_sb16_resume(platform_get_drvdata(dev));
+}
+#endif
+
+#ifdef SNDRV_SBAWE
+#define SND_SB16_DRIVER	"snd_sbawe"
+#else
+#define SND_SB16_DRIVER	"snd_sb16"
+#endif
+
+static struct platform_driver snd_sb16_nonpnp_driver = {
+	.probe		= snd_sb16_nonpnp_probe,
+	.remove		= __devexit_p(snd_sb16_nonpnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_sb16_nonpnp_suspend,
+	.resume		= snd_sb16_nonpnp_resume,
+#endif
+	.driver		= {
+		.name	= SND_SB16_DRIVER
+	},
+};
+
+
 #ifdef CONFIG_PNP
 
-static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *card,
-					 const struct pnp_card_device_id *id)
+static int __devinit snd_sb16_pnp_detect(struct pnp_card_link *pcard,
+					 const struct pnp_card_device_id *pid)
 {
 	static int dev;
+	struct snd_card *card;
 	int res;
 
 	for ( ; dev < SNDRV_CARDS; dev++) {
 		if (!enable[dev] || !isapnp[dev])
 			continue;
-		res = snd_sb16_probe(dev, card, id);
-		if (res < 0)
+		card = snd_sb16_card_new(dev);
+		if (! card)
+			return -ENOMEM;
+		snd_card_set_dev(card, &pcard->card->dev);
+		if ((res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid)) < 0 ||
+		    (res = snd_sb16_probe(card, dev)) < 0) {
+			snd_card_free(card);
 			return res;
+		}
+		pnp_set_card_drvdata(pcard, card);
 		dev++;
 		return 0;
 	}
@@ -583,57 +659,82 @@
 
 static void __devexit snd_sb16_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_sb16_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
+{
+	return snd_sb16_suspend(pnp_get_card_drvdata(pcard), state);
+}
+static int snd_sb16_pnp_resume(struct pnp_card_link *pcard)
+{
+	return snd_sb16_resume(pnp_get_card_drvdata(pcard));
+}
+#endif
+
 static struct pnp_card_driver sb16_pnpc_driver = {
 	.flags = PNP_DRIVER_RES_DISABLE,
+#ifdef SNDRV_SBAWE
+	.name = "sbawe",
+#else
 	.name = "sb16",
+#endif
 	.id_table = snd_sb16_pnpids,
 	.probe = snd_sb16_pnp_detect,
 	.remove = __devexit_p(snd_sb16_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend = snd_sb16_pnp_suspend,
+	.resume = snd_sb16_pnp_resume,
+#endif
 };
 
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_sb16_unregister_all(void)
+{
+	int i;
+
+#ifdef CONFIG_PNP
+	if (pnp_registered)
+		pnp_unregister_card_driver(&sb16_pnpc_driver);
+#endif
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_sb16_nonpnp_driver);
+}
+
 static int __init alsa_card_sb16_init(void)
 {
-	int dev, cards = 0, i;
-	static unsigned long possible_ports[] = {0x220, 0x240, 0x260, 0x280, -1};
+	int i, err, cards = 0;
 
-	/* legacy non-auto cards at first */
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev] || port[dev] == SNDRV_AUTO_PORT)
+	if ((err = platform_driver_register(&snd_sb16_nonpnp_driver)) < 0)
+		return err;
+
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		if (is_isapnp_selected(i))
 			continue;
-		if (is_isapnp_selected(dev))
-			continue;
-		if (!snd_sb16_probe(dev, NULL, NULL)) {
-			cards++;
-			continue;
+		device = platform_device_register_simple(SND_SB16_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
 		}
-#ifdef MODULE
-		snd_printk(KERN_ERR "Sound Blaster 16+ soundcard #%i not found at 0x%lx or device busy\n", dev, port[dev]);
-#endif
+		platform_devices[i] = device;
+		cards++;
 	}
-	/* legacy auto configured cards */
-	i = snd_legacy_auto_probe(possible_ports, snd_sb16_probe_legacy_port);
-	if (i > 0)
-		cards += i;
-
 #ifdef CONFIG_PNP
 	/* PnP cards at last */
 	i = pnp_register_card_driver(&sb16_pnpc_driver);
-	if (i >0)
+	if (i >= 0) {
+		pnp_registered = 1;
 		cards += i;
+	}
 #endif
 
 	if (!cards) {
-#ifdef CONFIG_PNP
-		pnp_unregister_card_driver(&sb16_pnpc_driver);
-#endif
 #ifdef MODULE
 		snd_printk(KERN_ERR "Sound Blaster 16 soundcard not found or device busy\n");
 #ifdef SNDRV_SBAWE_EMU8000
@@ -642,21 +743,19 @@
 		snd_printk(KERN_ERR "In case, if you have AWE card, try snd-sbawe module\n");
 #endif
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_sb16_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_sb16_exit(void)
 {
-	int dev;
-
-#ifdef CONFIG_PNP
-	/* PnP cards first */
-	pnp_unregister_card_driver(&sb16_pnpc_driver);
-#endif
-	for (dev = 0; dev < SNDRV_CARDS; dev++)
-		snd_card_free(snd_sb16_legacy[dev]);
+	snd_sb16_unregister_all();
 }
 
 module_init(alsa_card_sb16_init)
diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c
index 7192d4c..9c2b5ef 100644
--- a/sound/isa/sb/sb16_csp.c
+++ b/sound/isa/sb/sb16_csp.c
@@ -72,46 +72,47 @@
 /*
  * prototypes
  */
-static void snd_sb_csp_free(snd_hwdep_t *hw);
-static int snd_sb_csp_open(snd_hwdep_t * hw, struct file *file);
-static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg);
-static int snd_sb_csp_release(snd_hwdep_t * hw, struct file *file);
+static void snd_sb_csp_free(struct snd_hwdep *hw);
+static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file);
+static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg);
+static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file);
 
-static int csp_detect(sb_t *chip, int *version);
-static int set_codec_parameter(sb_t *chip, unsigned char par, unsigned char val);
-static int set_register(sb_t *chip, unsigned char reg, unsigned char val);
-static int read_register(sb_t *chip, unsigned char reg);
-static int set_mode_register(sb_t *chip, unsigned char mode);
-static int get_version(sb_t *chip);
+static int csp_detect(struct snd_sb *chip, int *version);
+static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val);
+static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val);
+static int read_register(struct snd_sb *chip, unsigned char reg);
+static int set_mode_register(struct snd_sb *chip, unsigned char mode);
+static int get_version(struct snd_sb *chip);
 
-static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user * code);
-static int snd_sb_csp_unload(snd_sb_csp_t * p);
-static int snd_sb_csp_load_user(snd_sb_csp_t * p, const unsigned char __user *buf, int size, int load_flags);
-static int snd_sb_csp_autoload(snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode);
-static int snd_sb_csp_check_version(snd_sb_csp_t * p);
+static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
+				struct snd_sb_csp_microcode __user * code);
+static int snd_sb_csp_unload(struct snd_sb_csp * p);
+static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags);
+static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode);
+static int snd_sb_csp_check_version(struct snd_sb_csp * p);
 
-static int snd_sb_csp_use(snd_sb_csp_t * p);
-static int snd_sb_csp_unuse(snd_sb_csp_t * p);
-static int snd_sb_csp_start(snd_sb_csp_t * p, int sample_width, int channels);
-static int snd_sb_csp_stop(snd_sb_csp_t * p);
-static int snd_sb_csp_pause(snd_sb_csp_t * p);
-static int snd_sb_csp_restart(snd_sb_csp_t * p);
+static int snd_sb_csp_use(struct snd_sb_csp * p);
+static int snd_sb_csp_unuse(struct snd_sb_csp * p);
+static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels);
+static int snd_sb_csp_stop(struct snd_sb_csp * p);
+static int snd_sb_csp_pause(struct snd_sb_csp * p);
+static int snd_sb_csp_restart(struct snd_sb_csp * p);
 
-static int snd_sb_qsound_build(snd_sb_csp_t * p);
-static void snd_sb_qsound_destroy(snd_sb_csp_t * p);
-static int snd_sb_csp_qsound_transfer(snd_sb_csp_t * p);
+static int snd_sb_qsound_build(struct snd_sb_csp * p);
+static void snd_sb_qsound_destroy(struct snd_sb_csp * p);
+static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p);
 
-static int init_proc_entry(snd_sb_csp_t * p, int device);
-static void info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer);
+static int init_proc_entry(struct snd_sb_csp * p, int device);
+static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer);
 
 /*
  * Detect CSP chip and create a new instance
  */
-int snd_sb_csp_new(sb_t *chip, int device, snd_hwdep_t ** rhwdep)
+int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep)
 {
-	snd_sb_csp_t *p;
+	struct snd_sb_csp *p;
 	int version, err;
-	snd_hwdep_t *hw;
+	struct snd_hwdep *hw;
 
 	if (rhwdep)
 		*rhwdep = NULL;
@@ -158,9 +159,9 @@
 /*
  * free_private for hwdep instance
  */
-static void snd_sb_csp_free(snd_hwdep_t *hwdep)
+static void snd_sb_csp_free(struct snd_hwdep *hwdep)
 {
-	snd_sb_csp_t *p = hwdep->private_data;
+	struct snd_sb_csp *p = hwdep->private_data;
 	if (p) {
 		if (p->running & SNDRV_SB_CSP_ST_RUNNING)
 			snd_sb_csp_stop(p);
@@ -173,20 +174,20 @@
 /*
  * open the device exclusively
  */
-static int snd_sb_csp_open(snd_hwdep_t * hw, struct file *file)
+static int snd_sb_csp_open(struct snd_hwdep * hw, struct file *file)
 {
-	snd_sb_csp_t *p = hw->private_data;
+	struct snd_sb_csp *p = hw->private_data;
 	return (snd_sb_csp_use(p));
 }
 
 /*
  * ioctl for hwdep device:
  */
-static int snd_sb_csp_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
+static int snd_sb_csp_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
 {
-	snd_sb_csp_t *p = hw->private_data;
-	snd_sb_csp_info_t info;
-	snd_sb_csp_start_t start_info;
+	struct snd_sb_csp *p = hw->private_data;
+	struct snd_sb_csp_info info;
+	struct snd_sb_csp_start start_info;
 	int err;
 
 	snd_assert(p != NULL, return -EINVAL);
@@ -217,7 +218,7 @@
 		/* load CSP microcode */
 	case SNDRV_SB_CSP_IOCTL_LOAD_CODE:
 		err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
-		       -EBUSY : snd_sb_csp_riff_load(p, (snd_sb_csp_microcode_t __user *) arg));
+		       -EBUSY : snd_sb_csp_riff_load(p, (struct snd_sb_csp_microcode __user *) arg));
 		break;
 	case SNDRV_SB_CSP_IOCTL_UNLOAD_CODE:
 		err = (p->running & SNDRV_SB_CSP_ST_RUNNING ?
@@ -251,9 +252,9 @@
 /*
  * close the device
  */
-static int snd_sb_csp_release(snd_hwdep_t * hw, struct file *file)
+static int snd_sb_csp_release(struct snd_hwdep * hw, struct file *file)
 {
-	snd_sb_csp_t *p = hw->private_data;
+	struct snd_sb_csp *p = hw->private_data;
 	return (snd_sb_csp_unuse(p));
 }
 
@@ -262,7 +263,7 @@
 /*
  * acquire device
  */
-static int snd_sb_csp_use(snd_sb_csp_t * p)
+static int snd_sb_csp_use(struct snd_sb_csp * p)
 {
 	down(&p->access_mutex);
 	if (p->used) {
@@ -279,7 +280,7 @@
 /*
  * release device
  */
-static int snd_sb_csp_unuse(snd_sb_csp_t * p)
+static int snd_sb_csp_unuse(struct snd_sb_csp * p)
 {
 	down(&p->access_mutex);
 	p->used--;
@@ -292,9 +293,10 @@
  * load microcode via ioctl: 
  * code is user-space pointer
  */
-static int snd_sb_csp_riff_load(snd_sb_csp_t * p, snd_sb_csp_microcode_t __user * mcode)
+static int snd_sb_csp_riff_load(struct snd_sb_csp * p,
+				struct snd_sb_csp_microcode __user * mcode)
 {
-	snd_sb_csp_mc_header_t info;
+	struct snd_sb_csp_mc_header info;
 
 	unsigned char __user *data_ptr;
 	unsigned char __user *data_end;
@@ -449,7 +451,7 @@
 /*
  * unload CSP microcode
  */
-static int snd_sb_csp_unload(snd_sb_csp_t * p)
+static int snd_sb_csp_unload(struct snd_sb_csp * p)
 {
 	if (p->running & SNDRV_SB_CSP_ST_RUNNING)
 		return -EBUSY;
@@ -472,7 +474,7 @@
 /*
  * send command sequence to DSP
  */
-static inline int command_seq(sb_t *chip, const unsigned char *seq, int size)
+static inline int command_seq(struct snd_sb *chip, const unsigned char *seq, int size)
 {
 	int i;
 	for (i = 0; i < size; i++) {
@@ -485,7 +487,7 @@
 /*
  * set CSP codec parameter
  */
-static int set_codec_parameter(sb_t *chip, unsigned char par, unsigned char val)
+static int set_codec_parameter(struct snd_sb *chip, unsigned char par, unsigned char val)
 {
 	unsigned char dsp_cmd[3];
 
@@ -502,7 +504,7 @@
 /*
  * set CSP register
  */
-static int set_register(sb_t *chip, unsigned char reg, unsigned char val)
+static int set_register(struct snd_sb *chip, unsigned char reg, unsigned char val)
 {
 	unsigned char dsp_cmd[3];
 
@@ -516,7 +518,7 @@
  * read CSP register
  * return < 0 -> error
  */
-static int read_register(sb_t *chip, unsigned char reg)
+static int read_register(struct snd_sb *chip, unsigned char reg)
 {
 	unsigned char dsp_cmd[2];
 
@@ -529,7 +531,7 @@
 /*
  * set CSP mode register
  */
-static int set_mode_register(sb_t *chip, unsigned char mode)
+static int set_mode_register(struct snd_sb *chip, unsigned char mode)
 {
 	unsigned char dsp_cmd[2];
 
@@ -542,7 +544,7 @@
  * Detect CSP
  * return 0 if CSP exists.
  */
-static int csp_detect(sb_t *chip, int *version)
+static int csp_detect(struct snd_sb *chip, int *version)
 {
 	unsigned char csp_test1, csp_test2;
 	unsigned long flags;
@@ -579,7 +581,7 @@
 /*
  * get CSP version number
  */
-static int get_version(sb_t *chip)
+static int get_version(struct snd_sb *chip)
 {
 	unsigned char dsp_cmd[2];
 
@@ -593,7 +595,7 @@
 /*
  * check if the CSP version is valid
  */
-static int snd_sb_csp_check_version(snd_sb_csp_t * p)
+static int snd_sb_csp_check_version(struct snd_sb_csp * p)
 {
 	if (p->version < 0x10 || p->version > 0x1f) {
 		snd_printd("%s: Invalid CSP version: 0x%x\n", __FUNCTION__, p->version);
@@ -605,7 +607,7 @@
 /*
  * download microcode to CSP (microcode should have one "main" block).
  */
-static int snd_sb_csp_load(snd_sb_csp_t * p, const unsigned char *buf, int size, int load_flags)
+static int snd_sb_csp_load(struct snd_sb_csp * p, const unsigned char *buf, int size, int load_flags)
 {
 	int status, i;
 	int err;
@@ -671,7 +673,7 @@
 	return result;
 }
  
-static int snd_sb_csp_load_user(snd_sb_csp_t * p, const unsigned char __user *buf, int size, int load_flags)
+static int snd_sb_csp_load_user(struct snd_sb_csp * p, const unsigned char __user *buf, int size, int load_flags)
 {
 	int err = -ENOMEM;
 	unsigned char *kbuf = kmalloc(size, GFP_KERNEL);
@@ -691,7 +693,7 @@
  * autoload hardware codec if necessary
  * return 0 if CSP is loaded and ready to run (p->running != 0)
  */
-static int snd_sb_csp_autoload(snd_sb_csp_t * p, int pcm_sfmt, int play_rec_mode)
+static int snd_sb_csp_autoload(struct snd_sb_csp * p, int pcm_sfmt, int play_rec_mode)
 {
 	unsigned long flags;
 	int err = 0;
@@ -763,7 +765,7 @@
 /*
  * start CSP
  */
-static int snd_sb_csp_start(snd_sb_csp_t * p, int sample_width, int channels)
+static int snd_sb_csp_start(struct snd_sb_csp * p, int sample_width, int channels)
 {
 	unsigned char s_type;	/* sample type */
 	unsigned char mixL, mixR;
@@ -842,7 +844,7 @@
 /*
  * stop CSP
  */
-static int snd_sb_csp_stop(snd_sb_csp_t * p)
+static int snd_sb_csp_stop(struct snd_sb_csp * p)
 {
 	int result;
 	unsigned char mixL, mixR;
@@ -883,7 +885,7 @@
 /*
  * pause CSP codec and hold DMA transfer
  */
-static int snd_sb_csp_pause(snd_sb_csp_t * p)
+static int snd_sb_csp_pause(struct snd_sb_csp * p)
 {
 	int result;
 	unsigned long flags;
@@ -903,7 +905,7 @@
 /*
  * restart CSP codec and resume DMA transfer
  */
-static int snd_sb_csp_restart(snd_sb_csp_t * p)
+static int snd_sb_csp_restart(struct snd_sb_csp * p)
 {
 	int result;
 	unsigned long flags;
@@ -926,7 +928,7 @@
  * QSound mixer control for PCM
  */
 
-static int snd_sb_qsound_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sb_qsound_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -935,17 +937,17 @@
 	return 0;
 }
 
-static int snd_sb_qsound_switch_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb_qsound_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_sb_csp_t *p = snd_kcontrol_chip(kcontrol);
+	struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = p->q_enabled ? 1 : 0;
 	return 0;
 }
 
-static int snd_sb_qsound_switch_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb_qsound_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_sb_csp_t *p = snd_kcontrol_chip(kcontrol);
+	struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned char nval;
@@ -958,7 +960,7 @@
 	return change;
 }
 
-static int snd_sb_qsound_space_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sb_qsound_space_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -967,9 +969,9 @@
 	return 0;
 }
 
-static int snd_sb_qsound_space_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb_qsound_space_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_sb_csp_t *p = snd_kcontrol_chip(kcontrol);
+	struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&p->q_lock, flags);
@@ -979,9 +981,9 @@
 	return 0;
 }
 
-static int snd_sb_qsound_space_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb_qsound_space_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	snd_sb_csp_t *p = snd_kcontrol_chip(kcontrol);
+	struct snd_sb_csp *p = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned char nval1, nval2;
@@ -1001,7 +1003,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_sb_qsound_switch = {
+static struct snd_kcontrol_new snd_sb_qsound_switch = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "3D Control - Switch",
 	.info = snd_sb_qsound_switch_info,
@@ -1009,7 +1011,7 @@
 	.put = snd_sb_qsound_switch_put
 };
 
-static snd_kcontrol_new_t snd_sb_qsound_space = {
+static struct snd_kcontrol_new snd_sb_qsound_space = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "3D Control - Space",
 	.info = snd_sb_qsound_space_info,
@@ -1017,9 +1019,9 @@
 	.put = snd_sb_qsound_space_put
 };
 
-static int snd_sb_qsound_build(snd_sb_csp_t * p)
+static int snd_sb_qsound_build(struct snd_sb_csp * p)
 {
-	snd_card_t * card;
+	struct snd_card *card;
 	int err;
 
 	snd_assert(p != NULL, return -EINVAL);
@@ -1042,9 +1044,9 @@
 	return err;
 }
 
-static void snd_sb_qsound_destroy(snd_sb_csp_t * p)
+static void snd_sb_qsound_destroy(struct snd_sb_csp * p)
 {
-	snd_card_t * card;
+	struct snd_card *card;
 	unsigned long flags;
 
 	snd_assert(p != NULL, return);
@@ -1068,7 +1070,7 @@
  * Transfer qsound parameters to CSP,
  * function should be called from interrupt routine
  */
-static int snd_sb_csp_qsound_transfer(snd_sb_csp_t * p)
+static int snd_sb_csp_qsound_transfer(struct snd_sb_csp * p)
 {
 	int err = -ENXIO;
 
@@ -1093,19 +1095,19 @@
 /*
  * proc interface
  */
-static int init_proc_entry(snd_sb_csp_t * p, int device)
+static int init_proc_entry(struct snd_sb_csp * p, int device)
 {
 	char name[16];
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	sprintf(name, "cspD%d", device);
 	if (! snd_card_proc_new(p->chip->card, name, &entry))
 		snd_info_set_text_ops(entry, p, 1024, info_read);
 	return 0;
 }
 
-static void info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void info_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	snd_sb_csp_t *p = entry->private_data;
+	struct snd_sb_csp *p = entry->private_data;
 
 	snd_iprintf(buffer, "Creative Signal Processor [v%d.%d]\n", (p->version >> 4), (p->version & 0x0f));
 	snd_iprintf(buffer, "State: %cx%c%c%c\n", ((p->running & SNDRV_SB_CSP_ST_QSOUND) ? 'Q' : '-'),
diff --git a/sound/isa/sb/sb16_main.c b/sound/isa/sb/sb16_main.c
index 556b95e..f183f18 100644
--- a/sound/isa/sb/sb16_main.c
+++ b/sound/isa/sb/sb16_main.c
@@ -50,10 +50,10 @@
 MODULE_LICENSE("GPL");
 
 #ifdef CONFIG_SND_SB16_CSP
-static void snd_sb16_csp_playback_prepare(sb_t *chip, snd_pcm_runtime_t *runtime)
+static void snd_sb16_csp_playback_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
 {
 	if (chip->hardware == SB_HW_16CSP) {
-		snd_sb_csp_t *csp = chip->csp;
+		struct snd_sb_csp *csp = chip->csp;
 
 		if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 			/* manually loaded codec */
@@ -98,10 +98,10 @@
 	}
 }
 
-static void snd_sb16_csp_capture_prepare(sb_t *chip, snd_pcm_runtime_t *runtime)
+static void snd_sb16_csp_capture_prepare(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
 {
 	if (chip->hardware == SB_HW_16CSP) {
-		snd_sb_csp_t *csp = chip->csp;
+		struct snd_sb_csp *csp = chip->csp;
 
 		if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 			/* manually loaded codec */
@@ -136,10 +136,10 @@
 	}
 }
 
-static void snd_sb16_csp_update(sb_t *chip)
+static void snd_sb16_csp_update(struct snd_sb *chip)
 {
 	if (chip->hardware == SB_HW_16CSP) {
-		snd_sb_csp_t *csp = chip->csp;
+		struct snd_sb_csp *csp = chip->csp;
 
 		if (csp->qpos_changed) {
 			spin_lock(&chip->reg_lock);
@@ -149,11 +149,11 @@
 	}
 }
 
-static void snd_sb16_csp_playback_open(sb_t *chip, snd_pcm_runtime_t *runtime)
+static void snd_sb16_csp_playback_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
 {
 	/* CSP decoders (QSound excluded) support only 16bit transfers */
 	if (chip->hardware == SB_HW_16CSP) {
-		snd_sb_csp_t *csp = chip->csp;
+		struct snd_sb_csp *csp = chip->csp;
 
 		if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 			/* manually loaded codec */
@@ -168,10 +168,10 @@
 	}
 }
 
-static void snd_sb16_csp_playback_close(sb_t *chip)
+static void snd_sb16_csp_playback_close(struct snd_sb *chip)
 {
 	if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_WRITE)) {
-		snd_sb_csp_t *csp = chip->csp;
+		struct snd_sb_csp *csp = chip->csp;
 
 		if (csp->ops.csp_stop(csp) == 0) {
 			csp->ops.csp_unuse(csp);
@@ -180,11 +180,11 @@
 	}
 }
 
-static void snd_sb16_csp_capture_open(sb_t *chip, snd_pcm_runtime_t *runtime)
+static void snd_sb16_csp_capture_open(struct snd_sb *chip, struct snd_pcm_runtime *runtime)
 {
 	/* CSP coders support only 16bit transfers */
 	if (chip->hardware == SB_HW_16CSP) {
-		snd_sb_csp_t *csp = chip->csp;
+		struct snd_sb_csp *csp = chip->csp;
 
 		if (csp->running & SNDRV_SB_CSP_ST_LOADED) {
 			/* manually loaded codec */
@@ -199,10 +199,10 @@
 	}
 }
 
-static void snd_sb16_csp_capture_close(sb_t *chip)
+static void snd_sb16_csp_capture_close(struct snd_sb *chip)
 {
 	if ((chip->hardware == SB_HW_16CSP) && (chip->open == SNDRV_SB_CSP_MODE_DSP_READ)) {
-		snd_sb_csp_t *csp = chip->csp;
+		struct snd_sb_csp *csp = chip->csp;
 
 		if (csp->ops.csp_stop(csp) == 0) {
 			csp->ops.csp_unuse(csp);
@@ -221,7 +221,7 @@
 #endif
 
 
-static void snd_sb16_setup_rate(sb_t *chip,
+static void snd_sb16_setup_rate(struct snd_sb *chip,
 				unsigned short rate,
 				int channel)
 {
@@ -244,23 +244,23 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static int snd_sb16_hw_params(snd_pcm_substream_t * substream,
-			      snd_pcm_hw_params_t * hw_params)
+static int snd_sb16_hw_params(struct snd_pcm_substream *substream,
+			      struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_sb16_hw_free(snd_pcm_substream_t * substream)
+static int snd_sb16_hw_free(struct snd_pcm_substream *substream)
 {
 	snd_pcm_lib_free_pages(substream);
 	return 0;
 }
 
-static int snd_sb16_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_prepare(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned char format;
 	unsigned int size, count, dma;
 
@@ -298,19 +298,21 @@
 	return 0;
 }
 
-static int snd_sb16_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_sb16_playback_trigger(struct snd_pcm_substream *substream,
 				     int cmd)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	int result = 0;
 
 	spin_lock(&chip->reg_lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		chip->mode |= SB_RATE_LOCK_PLAYBACK;
 		snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		snd_sbdsp_command(chip, chip->mode & SB_MODE_PLAYBACK_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
 		/* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
 		if (chip->mode & SB_RATE_LOCK_CAPTURE)
@@ -324,11 +326,11 @@
 	return result;
 }
 
-static int snd_sb16_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_prepare(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned char format;
 	unsigned int size, count, dma;
 
@@ -365,19 +367,21 @@
 	return 0;
 }
 
-static int snd_sb16_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_sb16_capture_trigger(struct snd_pcm_substream *substream,
 				    int cmd)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	int result = 0;
 
 	spin_lock(&chip->reg_lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		chip->mode |= SB_RATE_LOCK_CAPTURE;
 		snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_ON : SB_DSP_DMA8_ON);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		snd_sbdsp_command(chip, chip->mode & SB_MODE_CAPTURE_16 ? SB_DSP_DMA16_OFF : SB_DSP_DMA8_OFF);
 		/* next two lines are needed for some types of DSP4 (SB AWE 32 - 4.13) */
 		if (chip->mode & SB_RATE_LOCK_PLAYBACK)
@@ -393,7 +397,7 @@
 
 irqreturn_t snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	sb_t *chip = dev_id;
+	struct snd_sb *chip = dev_id;
 	unsigned char status;
 	int ok;
 
@@ -443,9 +447,9 @@
 
  */
 
-static snd_pcm_uframes_t snd_sb16_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_sb16_playback_pointer(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	unsigned int dma;
 	size_t ptr;
 
@@ -454,9 +458,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_sb16_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_sb16_capture_pointer(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	unsigned int dma;
 	size_t ptr;
 
@@ -469,7 +473,7 @@
 
  */
 
-static snd_pcm_hardware_t snd_sb16_playback =
+static struct snd_pcm_hardware snd_sb16_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -487,7 +491,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_sb16_capture =
+static struct snd_pcm_hardware snd_sb16_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -509,11 +513,11 @@
  *  open/close
  */
 
-static int snd_sb16_playback_open(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_open(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	spin_lock_irqsave(&chip->open_lock, flags);
 	if (chip->mode & SB_MODE_PLAYBACK) {
@@ -566,10 +570,10 @@
 	return 0;
 }
 
-static int snd_sb16_playback_close(snd_pcm_substream_t * substream)
+static int snd_sb16_playback_close(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 
 	snd_sb16_csp_playback_close(chip);
 	spin_lock_irqsave(&chip->open_lock, flags);
@@ -579,11 +583,11 @@
 	return 0;
 }
 
-static int snd_sb16_capture_open(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_open(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	spin_lock_irqsave(&chip->open_lock, flags);
 	if (chip->mode & SB_MODE_CAPTURE) {
@@ -636,10 +640,10 @@
 	return 0;
 }
 
-static int snd_sb16_capture_close(snd_pcm_substream_t * substream)
+static int snd_sb16_capture_close(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 
 	snd_sb16_csp_capture_close(chip);
 	spin_lock_irqsave(&chip->open_lock, flags);
@@ -653,7 +657,7 @@
  *  DMA control interface
  */
 
-static int snd_sb16_set_dma_mode(sb_t *chip, int what)
+static int snd_sb16_set_dma_mode(struct snd_sb *chip, int what)
 {
 	if (chip->dma8 < 0 || chip->dma16 < 0) {
 		snd_assert(what == 0, return -EINVAL);
@@ -671,7 +675,7 @@
 	return 0;
 }
 
-static int snd_sb16_get_dma_mode(sb_t *chip)
+static int snd_sb16_get_dma_mode(struct snd_sb *chip)
 {
 	if (chip->dma8 < 0 || chip->dma16 < 0)
 		return 0;
@@ -685,7 +689,7 @@
 	}
 }
 
-static int snd_sb16_dma_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sb16_dma_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = {
 		"Auto", "Playback", "Capture"
@@ -700,9 +704,9 @@
 	return 0;
 }
 
-static int snd_sb16_dma_control_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb16_dma_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -711,9 +715,9 @@
 	return 0;
 }
 
-static int snd_sb16_dma_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb16_dma_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned char nval, oval;
 	int change;
@@ -728,7 +732,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_sb16_dma_control = {
+static struct snd_kcontrol_new snd_sb16_dma_control = {
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.name = "16-bit DMA Allocation",
 	.info = snd_sb16_dma_control_info,
@@ -740,7 +744,7 @@
  *  Initialization part
  */
  
-int snd_sb16dsp_configure(sb_t * chip)
+int snd_sb16dsp_configure(struct snd_sb * chip)
 {
 	unsigned long flags;
 	unsigned char irqreg = 0, dmareg = 0, mpureg;
@@ -829,7 +833,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_sb16_playback_ops = {
+static struct snd_pcm_ops snd_sb16_playback_ops = {
 	.open =		snd_sb16_playback_open,
 	.close =	snd_sb16_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -840,7 +844,7 @@
 	.pointer =	snd_sb16_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_sb16_capture_ops = {
+static struct snd_pcm_ops snd_sb16_capture_ops = {
 	.open =		snd_sb16_capture_open,
 	.close =	snd_sb16_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -851,15 +855,10 @@
 	.pointer =	snd_sb16_capture_pointer,
 };
 
-static void snd_sb16dsp_pcm_free(snd_pcm_t *pcm)
+int snd_sb16dsp_pcm(struct snd_sb * chip, int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int snd_sb16dsp_pcm(sb_t * chip, int device, snd_pcm_t ** rpcm)
-{
-	snd_card_t *card = chip->card;
-	snd_pcm_t *pcm;
+	struct snd_card *card = chip->card;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -869,7 +868,6 @@
 	sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
 	pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
 	pcm->private_data = chip;
-	pcm->private_free = snd_sb16dsp_pcm_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb16_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb16_capture_ops);
@@ -888,7 +886,7 @@
 	return 0;
 }
 
-const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction)
+const struct snd_pcm_ops *snd_sb16dsp_get_pcm_ops(int direction)
 {
 	return direction == SNDRV_PCM_STREAM_PLAYBACK ?
 		&snd_sb16_playback_ops : &snd_sb16_capture_ops;
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 0bc0a3a..60ee79c 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -21,13 +21,14 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/opl3.h>
-#define SNDRV_LEGACY_AUTO_PROBE
 #include <sound/initval.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
@@ -55,15 +56,16 @@
 module_param_array(dma8, int, NULL, 0444);
 MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 struct snd_sb8 {
 	struct resource *fm_res;	/* used to block FM i/o region for legacy cards */
+	struct snd_sb *chip;
 };
 
-static snd_card_t *snd_sb8_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
 static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	sb_t *chip = dev_id;
+	struct snd_sb *chip = dev_id;
 
 	if (chip->open & SB_OPEN_PCM) {
 		return snd_sb8dsp_interrupt(chip);
@@ -72,7 +74,7 @@
 	}
 }
 
-static void snd_sb8_free(snd_card_t *card)
+static void snd_sb8_free(struct snd_card *card)
 {
 	struct snd_sb8 *acard = (struct snd_sb8 *)card->private_data;
 
@@ -81,32 +83,57 @@
 	release_and_free_resource(acard->fm_res);
 }
 
-static int __init snd_sb8_probe(int dev)
+static int __init snd_sb8_probe(struct platform_device *pdev)
 {
-	sb_t *chip;
-	snd_card_t *card;
+	int dev = pdev->id;
+	struct snd_sb *chip;
+	struct snd_card *card;
 	struct snd_sb8 *acard;
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 	int err;
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
 			    sizeof(struct snd_sb8));
 	if (card == NULL)
 		return -ENOMEM;
-	acard = (struct snd_sb8 *)card->private_data;
+	acard = card->private_data;
 	card->private_free = snd_sb8_free;
 
 	/* block the 0x388 port to avoid PnP conflicts */
 	acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
 
-	if ((err = snd_sbdsp_create(card, port[dev], irq[dev],
-				    snd_sb8_interrupt,
-				    dma8[dev],
-				    -1,
-				    SB_HW_AUTO,
-				    &chip)) < 0)
-		goto _err;
-
+	if (port[dev] != SNDRV_AUTO_PORT) {
+		if ((err = snd_sbdsp_create(card, port[dev], irq[dev],
+					    snd_sb8_interrupt,
+					    dma8[dev],
+					    -1,
+					    SB_HW_AUTO,
+					    &chip)) < 0)
+			goto _err;
+	} else {
+		/* auto-probe legacy ports */
+		static unsigned long possible_ports[] = {
+			0x220, 0x240, 0x260,
+		};
+		int i;
+		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
+			err = snd_sbdsp_create(card, possible_ports[i],
+					       irq[dev],
+					       snd_sb8_interrupt,
+					       dma8[dev],
+					       -1,
+					       SB_HW_AUTO,
+					       &chip);
+			if (err >= 0) {
+				port[dev] = possible_ports[i];
+				break;
+			}
+		}
+		if (i >= ARRAY_SIZE(possible_ports))
+			goto _err;
+	}
+	acard->chip = chip;
+			
 	if (chip->hardware >= SB_HW_16) {
 		if (chip->hardware == SB_HW_ALS100)
 			snd_printk(KERN_WARNING "ALS100 chip detected at 0x%lx, try snd-als100 module\n",
@@ -153,13 +180,12 @@
 		chip->port,
 		irq[dev], dma8[dev]);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
+	snd_card_set_dev(card, &pdev->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
-	snd_sb8_cards[dev] = card;
+	platform_set_drvdata(pdev, card);
 	return 0;
 
  _err:
@@ -167,53 +193,99 @@
 	return err;
 }
 
-static int __init snd_card_sb8_legacy_auto_probe(unsigned long xport)
+static int snd_sb8_remove(struct platform_device *pdev)
 {
-        static int dev;
-        int res;
+	snd_card_free(platform_get_drvdata(pdev));
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
 
-        for ( ; dev < SNDRV_CARDS; dev++) {
-                if (!enable[dev] || port[dev] != SNDRV_AUTO_PORT)
-                        continue;
-                port[dev] = xport;
-                res = snd_sb8_probe(dev);
-                if (res < 0)
-                        port[dev] = SNDRV_AUTO_PORT;
-                return res;
-        }
-        return -ENODEV;
+#ifdef CONFIG_PM
+static int snd_sb8_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct snd_card *card = platform_get_drvdata(dev);
+	struct snd_sb8 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(chip->pcm);
+	snd_sbmixer_suspend(chip);
+	return 0;
+}
+
+static int snd_sb8_resume(struct platform_device *dev)
+{
+	struct snd_card *card = platform_get_drvdata(dev);
+	struct snd_sb8 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_sbdsp_reset(chip);
+	snd_sbmixer_resume(chip);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
+#define SND_SB8_DRIVER	"snd_sb8"
+
+static struct platform_driver snd_sb8_driver = {
+	.probe		= snd_sb8_probe,
+	.remove		= snd_sb8_remove,
+#ifdef CONFIG_PM
+	.suspend	= snd_sb8_suspend,
+	.resume		= snd_sb8_resume,
+#endif
+	.driver		= {
+		.name	= SND_SB8_DRIVER
+	},
+};
+
+static void __init_or_module snd_sb8_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_sb8_driver);
 }
 
 static int __init alsa_card_sb8_init(void)
 {
-	static unsigned long possible_ports[] = {0x220, 0x240, 0x260, -1};
-	int dev, cards, i;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) {
-		if (port[dev] == SNDRV_AUTO_PORT)
-			continue;
-		if (snd_sb8_probe(dev) >= 0)
-			cards++;
+	err = platform_driver_register(&snd_sb8_driver);
+	if (err < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(SND_SB8_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		devices[i] = device;
+		cards++;
 	}
-	i = snd_legacy_auto_probe(possible_ports, snd_card_sb8_legacy_auto_probe);
-	if (i > 0)
-		cards += i;
-
 	if (!cards) {
 #ifdef MODULE
 		snd_printk(KERN_ERR "Sound Blaster soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_sb8_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_sb8_exit(void)
 {
-	int idx;
-
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_sb8_cards[idx]);
+	snd_sb8_unregister_all();
 }
 
 module_init(alsa_card_sb8_init)
diff --git a/sound/isa/sb/sb8_main.c b/sound/isa/sb/sb8_main.c
index 5ddc6e4..aea9e5e 100644
--- a/sound/isa/sb/sb8_main.c
+++ b/sound/isa/sb/sb8_main.c
@@ -46,19 +46,19 @@
 #define SB8_DEN(v)	((SB8_CLOCK + (v) / 2) / (v))
 #define SB8_RATE(v)	(SB8_CLOCK / SB8_DEN(v))
 
-static ratnum_t clock = {
+static struct snd_ratnum clock = {
 	.num = SB8_CLOCK,
 	.den_min = 1,
 	.den_max = 256,
 	.den_step = 1,
 };
 
-static snd_pcm_hw_constraint_ratnums_t hw_constraints_clock = {
+static struct snd_pcm_hw_constraint_ratnums hw_constraints_clock = {
 	.nrats = 1,
 	.rats = &clock,
 };
 
-static ratnum_t stereo_clocks[] = {
+static struct snd_ratnum stereo_clocks[] = {
 	{
 		.num = SB8_CLOCK,
 		.den_min = SB8_DEN(22050),
@@ -73,10 +73,10 @@
 	}
 };
 
-static int snd_sb8_hw_constraint_rate_channels(snd_pcm_hw_params_t *params,
-					       snd_pcm_hw_rule_t *rule)
+static int snd_sb8_hw_constraint_rate_channels(struct snd_pcm_hw_params *params,
+					       struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 	if (c->min > 1) {
 	  	unsigned int num = 0, den = 0;
 		int err = snd_interval_ratnum(hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE),
@@ -90,22 +90,22 @@
 	return 0;
 }
 
-static int snd_sb8_hw_constraint_channels_rate(snd_pcm_hw_params_t *params,
-					       snd_pcm_hw_rule_t *rule)
+static int snd_sb8_hw_constraint_channels_rate(struct snd_pcm_hw_params *params,
+					       struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (r->min > SB8_RATE(22050) || r->max <= SB8_RATE(11025)) {
-		snd_interval_t t = { .min = 1, .max = 1 };
+		struct snd_interval t = { .min = 1, .max = 1 };
 		return snd_interval_refine(hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS), &t);
 	}
 	return 0;
 }
 
-static int snd_sb8_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int mixreg, rate, size, count;
 
 	rate = runtime->rate;
@@ -178,11 +178,11 @@
 	return 0;
 }
 
-static int snd_sb8_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream,
 				    int cmd)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	unsigned int count;
 
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -197,7 +197,7 @@
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 		if (chip->playback_format == SB_DSP_HI_OUTPUT_AUTO) {
-			snd_pcm_runtime_t *runtime = substream->runtime;
+			struct snd_pcm_runtime *runtime = substream->runtime;
 			snd_sbdsp_reset(chip);
 			if (runtime->channels > 1) {
 				spin_lock(&chip->mixer_lock);
@@ -215,23 +215,23 @@
 	return 0;
 }
 
-static int snd_sb8_hw_params(snd_pcm_substream_t * substream,
-			     snd_pcm_hw_params_t * hw_params)
+static int snd_sb8_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_sb8_hw_free(snd_pcm_substream_t * substream)
+static int snd_sb8_hw_free(struct snd_pcm_substream *substream)
 {
 	snd_pcm_lib_free_pages(substream);
 	return 0;
 }
 
-static int snd_sb8_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int mixreg, rate, size, count;
 
 	rate = runtime->rate;
@@ -290,11 +290,11 @@
 	return 0;
 }
 
-static int snd_sb8_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
 				   int cmd)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	unsigned int count;
 
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -309,7 +309,7 @@
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 		if (chip->capture_format == SB_DSP_HI_INPUT_AUTO) {
-			snd_pcm_runtime_t *runtime = substream->runtime;
+			struct snd_pcm_runtime *runtime = substream->runtime;
 			snd_sbdsp_reset(chip);
 			if (runtime->channels > 1) {
 				/* restore input filter status */
@@ -329,10 +329,10 @@
 	return 0;
 }
 
-irqreturn_t snd_sb8dsp_interrupt(sb_t *chip)
+irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip)
 {
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 
 	snd_sb_ack_8bit(chip);
 	switch (chip->mode) {
@@ -354,9 +354,9 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_uframes_t snd_sb8_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (chip->mode != SB_MODE_PLAYBACK_8)
@@ -365,9 +365,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_sb8_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (chip->mode != SB_MODE_CAPTURE_8)
@@ -380,7 +380,7 @@
 
  */
 
-static snd_pcm_hardware_t snd_sb8_playback =
+static struct snd_pcm_hardware snd_sb8_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -399,7 +399,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_sb8_capture =
+static struct snd_pcm_hardware snd_sb8_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -422,10 +422,10 @@
  *
  */
  
-static int snd_sb8_open(snd_pcm_substream_t *substream)
+static int snd_sb8_open(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 
 	spin_lock_irqsave(&chip->open_lock, flags);
@@ -468,10 +468,10 @@
 	return 0;	
 }
 
-static int snd_sb8_close(snd_pcm_substream_t *substream)
+static int snd_sb8_close(struct snd_pcm_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 
 	chip->playback_substream = NULL;
 	chip->capture_substream = NULL;
@@ -485,7 +485,7 @@
  *  Initialization part
  */
  
-static snd_pcm_ops_t snd_sb8_playback_ops = {
+static struct snd_pcm_ops snd_sb8_playback_ops = {
 	.open =			snd_sb8_open,
 	.close =		snd_sb8_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -496,7 +496,7 @@
 	.pointer =		snd_sb8_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_sb8_capture_ops = {
+static struct snd_pcm_ops snd_sb8_capture_ops = {
 	.open =			snd_sb8_open,
 	.close =		snd_sb8_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -507,15 +507,10 @@
 	.pointer =		snd_sb8_capture_pointer,
 };
 
-static void snd_sb8dsp_pcm_free(snd_pcm_t *pcm)
+int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int snd_sb8dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm)
-{
-	snd_card_t *card = chip->card;
-	snd_pcm_t *pcm;
+	struct snd_card *card = chip->card;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -525,7 +520,6 @@
 	sprintf(pcm->name, "DSP v%i.%i", chip->version >> 8, chip->version & 0xff);
 	pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
 	pcm->private_data = chip;
-	pcm->private_free = snd_sb8dsp_pcm_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops);
diff --git a/sound/isa/sb/sb8_midi.c b/sound/isa/sb/sb8_midi.c
index d2c633a..c549ace 100644
--- a/sound/isa/sb/sb8_midi.c
+++ b/sound/isa/sb/sb8_midi.c
@@ -36,9 +36,9 @@
 
  */
 
-irqreturn_t snd_sb8dsp_midi_interrupt(sb_t * chip)
+irqreturn_t snd_sb8dsp_midi_interrupt(struct snd_sb * chip)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int max = 64;
 	char byte;
 
@@ -63,10 +63,10 @@
 
  */
 
-static int snd_sb8dsp_midi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_sb8dsp_midi_input_open(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip;
+	struct snd_sb *chip;
 	unsigned int valid_open_flags;
 
 	chip = substream->rmidi->private_data;
@@ -90,10 +90,10 @@
 	return 0;
 }
 
-static int snd_sb8dsp_midi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_sb8dsp_midi_output_open(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip;
+	struct snd_sb *chip;
 	unsigned int valid_open_flags;
 
 	chip = substream->rmidi->private_data;
@@ -117,10 +117,10 @@
 	return 0;
 }
 
-static int snd_sb8dsp_midi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_sb8dsp_midi_input_close(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip;
+	struct snd_sb *chip;
 
 	chip = substream->rmidi->private_data;
 	spin_lock_irqsave(&chip->open_lock, flags);
@@ -135,10 +135,10 @@
 	return 0;
 }
 
-static int snd_sb8dsp_midi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_sb8dsp_midi_output_close(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip;
+	struct snd_sb *chip;
 
 	chip = substream->rmidi->private_data;
 	spin_lock_irqsave(&chip->open_lock, flags);
@@ -153,10 +153,10 @@
 	return 0;
 }
 
-static void snd_sb8dsp_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_sb8dsp_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	sb_t *chip;
+	struct snd_sb *chip;
 
 	chip = substream->rmidi->private_data;
 	spin_lock_irqsave(&chip->open_lock, flags);
@@ -176,10 +176,10 @@
 	spin_unlock_irqrestore(&chip->open_lock, flags);
 }
 
-static void snd_sb8dsp_midi_output_write(snd_rawmidi_substream_t * substream)
+static void snd_sb8dsp_midi_output_write(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
-	sb_t *chip;
+	struct snd_sb *chip;
 	char byte;
 	int max = 32;
 
@@ -214,8 +214,8 @@
 
 static void snd_sb8dsp_midi_output_timer(unsigned long data)
 {
-	snd_rawmidi_substream_t * substream = (snd_rawmidi_substream_t *) data;
-	sb_t * chip = substream->rmidi->private_data;
+	struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *) data;
+	struct snd_sb * chip = substream->rmidi->private_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&chip->open_lock, flags);
@@ -225,10 +225,10 @@
 	snd_sb8dsp_midi_output_write(substream);
 }
 
-static void snd_sb8dsp_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_sb8dsp_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	sb_t *chip;
+	struct snd_sb *chip;
 
 	chip = substream->rmidi->private_data;
 	spin_lock_irqsave(&chip->open_lock, flags);
@@ -256,23 +256,23 @@
 
  */
 
-static snd_rawmidi_ops_t snd_sb8dsp_midi_output =
+static struct snd_rawmidi_ops snd_sb8dsp_midi_output =
 {
 	.open =		snd_sb8dsp_midi_output_open,
 	.close =	snd_sb8dsp_midi_output_close,
 	.trigger =	snd_sb8dsp_midi_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_sb8dsp_midi_input =
+static struct snd_rawmidi_ops snd_sb8dsp_midi_input =
 {
 	.open =		snd_sb8dsp_midi_input_open,
 	.close =	snd_sb8dsp_midi_input_close,
 	.trigger =	snd_sb8dsp_midi_input_trigger,
 };
 
-int snd_sb8dsp_midi(sb_t *chip, int device, snd_rawmidi_t ** rrawmidi)
+int snd_sb8dsp_midi(struct snd_sb *chip, int device, struct snd_rawmidi ** rrawmidi)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	if (rrawmidi)
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c
index 603e923..f343a82 100644
--- a/sound/isa/sb/sb_common.c
+++ b/sound/isa/sb/sb_common.c
@@ -41,7 +41,7 @@
 
 #undef IO_DEBUG
 
-int snd_sbdsp_command(sb_t *chip, unsigned char val)
+int snd_sbdsp_command(struct snd_sb *chip, unsigned char val)
 {
 	int i;
 #ifdef IO_DEBUG
@@ -56,7 +56,7 @@
 	return 0;
 }
 
-int snd_sbdsp_get_byte(sb_t *chip)
+int snd_sbdsp_get_byte(struct snd_sb *chip)
 {
 	int val;
 	int i;
@@ -73,7 +73,7 @@
 	return -ENODEV;
 }
 
-int snd_sbdsp_reset(sb_t *chip)
+int snd_sbdsp_reset(struct snd_sb *chip)
 {
 	int i;
 
@@ -92,7 +92,7 @@
 	return -ENODEV;
 }
 
-static int snd_sbdsp_version(sb_t * chip)
+static int snd_sbdsp_version(struct snd_sb * chip)
 {
 	unsigned int result = -ENODEV;
 
@@ -102,7 +102,7 @@
 	return result;
 }
 
-static int snd_sbdsp_probe(sb_t * chip)
+static int snd_sbdsp_probe(struct snd_sb * chip)
 {
 	int version;
 	int major, minor;
@@ -176,7 +176,7 @@
 	return 0;
 }
 
-static int snd_sbdsp_free(sb_t *chip)
+static int snd_sbdsp_free(struct snd_sb *chip)
 {
 	if (chip->res_port)
 		release_and_free_resource(chip->res_port);
@@ -196,24 +196,24 @@
 	return 0;
 }
 
-static int snd_sbdsp_dev_free(snd_device_t *device)
+static int snd_sbdsp_dev_free(struct snd_device *device)
 {
-	sb_t *chip = device->device_data;
+	struct snd_sb *chip = device->device_data;
 	return snd_sbdsp_free(chip);
 }
 
-int snd_sbdsp_create(snd_card_t *card,
+int snd_sbdsp_create(struct snd_card *card,
 		     unsigned long port,
 		     int irq,
 		     irqreturn_t (*irq_handler)(int, void *, struct pt_regs *),
 		     int dma8,
 		     int dma16,
 		     unsigned short hardware,
-		     sb_t **r_chip)
+		     struct snd_sb **r_chip)
 {
-	sb_t *chip;
+	struct snd_sb *chip;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_sbdsp_dev_free,
 	};
 
@@ -293,6 +293,10 @@
 EXPORT_SYMBOL(snd_sbmixer_read);
 EXPORT_SYMBOL(snd_sbmixer_new);
 EXPORT_SYMBOL(snd_sbmixer_add_ctl);
+#ifdef CONFIG_PM
+EXPORT_SYMBOL(snd_sbmixer_suspend);
+EXPORT_SYMBOL(snd_sbmixer_resume);
+#endif
 
 /*
  *  INIT part
diff --git a/sound/isa/sb/sb_mixer.c b/sound/isa/sb/sb_mixer.c
index 5a926a4..1a6ee34 100644
--- a/sound/isa/sb/sb_mixer.c
+++ b/sound/isa/sb/sb_mixer.c
@@ -29,7 +29,7 @@
 
 #undef IO_DEBUG
 
-void snd_sbmixer_write(sb_t *chip, unsigned char reg, unsigned char data)
+void snd_sbmixer_write(struct snd_sb *chip, unsigned char reg, unsigned char data)
 {
 	outb(reg, SBP(chip, MIXER_ADDR));
 	udelay(10);
@@ -40,7 +40,7 @@
 #endif
 }
 
-unsigned char snd_sbmixer_read(sb_t *chip, unsigned char reg)
+unsigned char snd_sbmixer_read(struct snd_sb *chip, unsigned char reg)
 {
 	unsigned char result;
 
@@ -58,7 +58,7 @@
  * Single channel mixer element
  */
 
-static int snd_sbmixer_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sbmixer_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -69,9 +69,9 @@
 	return 0;
 }
 
-static int snd_sbmixer_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sbmixer_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 16) & 0xff;
@@ -85,9 +85,9 @@
 	return 0;
 }
 
-static int snd_sbmixer_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sbmixer_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 16) & 0x07;
@@ -110,7 +110,7 @@
  * Double channel mixer element
  */
 
-static int snd_sbmixer_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sbmixer_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -121,9 +121,9 @@
 	return 0;
 }
 
-static int snd_sbmixer_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sbmixer_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -141,9 +141,9 @@
 	return 0;
 }
 
-static int snd_sbmixer_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sbmixer_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -181,7 +181,7 @@
  * DT-019x / ALS-007 capture/input switch
  */
 
-static int snd_dt019x_input_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_dt019x_input_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[5] = {
 		"CD", "Mic", "Line", "Synth", "Master"
@@ -196,9 +196,9 @@
 	return 0;
 }
 
-static int snd_dt019x_input_sw_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_dt019x_input_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned char oval;
 	
@@ -232,9 +232,9 @@
 	return 0;
 }
 
-static int snd_dt019x_input_sw_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_dt019x_input_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned char nval, oval;
@@ -273,7 +273,7 @@
  * SBPRO input multiplexer
  */
 
-static int snd_sb8mixer_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sb8mixer_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = {
 		"Mic", "CD", "Line"
@@ -289,9 +289,9 @@
 }
 
 
-static int snd_sb8mixer_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb8mixer_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned char oval;
 	
@@ -312,9 +312,9 @@
 	return 0;
 }
 
-static int snd_sb8mixer_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb8mixer_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int change;
 	unsigned char nval, oval;
@@ -346,7 +346,7 @@
  * SB16 input switch
  */
 
-static int snd_sb16mixer_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sb16mixer_info_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 4;
@@ -355,9 +355,9 @@
 	return 0;
 }
 
-static int snd_sb16mixer_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb16mixer_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg1 = kcontrol->private_value & 0xff;
 	int reg2 = (kcontrol->private_value >> 8) & 0xff;
@@ -376,9 +376,9 @@
 	return 0;
 }                                                                                                                   
 
-static int snd_sb16mixer_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sb16mixer_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sb_t *sb = snd_kcontrol_chip(kcontrol);
+	struct snd_sb *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg1 = kcontrol->private_value & 0xff;
 	int reg2 = (kcontrol->private_value >> 8) & 0xff;
@@ -410,9 +410,9 @@
  */
 /*
  */
-int snd_sbmixer_add_ctl(sb_t *chip, const char *name, int index, int type, unsigned long value)
+int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int type, unsigned long value)
 {
-	static snd_kcontrol_new_t newctls[] = {
+	static struct snd_kcontrol_new newctls[] = {
 		[SB_MIX_SINGLE] = {
 			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 			.info = snd_sbmixer_info_single,
@@ -444,7 +444,7 @@
 			.put = snd_dt019x_input_sw_put,
 		},
 	};
-	snd_kcontrol_t *ctl;
+	struct snd_kcontrol *ctl;
 	int err;
 
 	ctl = snd_ctl_new1(&newctls[type], chip);
@@ -669,25 +669,34 @@
 /*
  * ALS4000 specific mixer elements
  */
-/* FIXME: SB_ALS4000_MONO_IO_CTRL needs output select ctrl ! */
-static struct sbmix_elem snd_als4000_ctl_mono_output_switch =
-	SB_SINGLE("Mono Output Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1);
-/* FIXME: mono input switch also available on DT019X ? */
-static struct sbmix_elem snd_als4000_ctl_mono_input_switch =
-	SB_SINGLE("Mono Input Switch", SB_DT019X_OUTPUT_SW2, 0, 1);
+/* FIXME: SB_ALS4000_MONO_IO_CTRL needs output select ctrl! */
+static struct sbmix_elem snd_als4000_ctl_master_mono_playback_switch =
+	SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1);
+static struct sbmix_elem snd_als4000_ctl_master_mono_capture_route =
+	SB_SINGLE("Master Mono Capture Route", SB_ALS4000_MONO_IO_CTRL, 6, 0x03);
+/* FIXME: mono playback switch also available on DT019X? */
+static struct sbmix_elem snd_als4000_ctl_mono_playback_switch =
+	SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1);
 static struct sbmix_elem snd_als4000_ctl_mic_20db_boost =
 	SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03);
-static struct sbmix_elem snd_als4000_ctl_mixer_out_to_in =
-	SB_SINGLE("Mixer Out To In", SB_ALS4000_MIC_IN_GAIN, 7, 0x01);
-/* FIXME: 3D needs much more sophisticated controls, many more features ! */
-static struct sbmix_elem snd_als4000_ctl_3d_output_switch =
-	SB_SINGLE("3D Output Switch", SB_ALS4000_3D_SND_FX, 6, 0x01);
-static struct sbmix_elem snd_als4000_ctl_3d_output_ratio =
-	SB_SINGLE("3D Output Ratio", SB_ALS4000_3D_SND_FX, 0, 0x07);
-static struct sbmix_elem snd_als4000_ctl_3d_poweroff_switch =
+static struct sbmix_elem snd_als4000_ctl_mixer_loopback =
+	SB_SINGLE("Analog Loopback", SB_ALS4000_MIC_IN_GAIN, 7, 0x01);
+/* FIXME: functionality of 3D controls might be swapped, I didn't find
+ * a description of how to identify what is supposed to be what */
+static struct sbmix_elem snd_als4000_3d_control_switch =
+	SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01);
+static struct sbmix_elem snd_als4000_3d_control_ratio =
+	SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07);
+static struct sbmix_elem snd_als4000_3d_control_freq =
+	/* FIXME: maybe there's actually some standard 3D ctrl name for it?? */
+	SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03);
+static struct sbmix_elem snd_als4000_3d_control_delay =
+	/* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay,
+	 * but what ALSA 3D attribute is that actually? "Center", "Depth",
+	 * "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */
+	SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f);
+static struct sbmix_elem snd_als4000_3d_control_poweroff_switch =
 	SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01);
-static struct sbmix_elem snd_als4000_ctl_3d_delay =
-	SB_SINGLE("3D Delay", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f);
 #ifdef NOT_AVAILABLE
 static struct sbmix_elem snd_als4000_ctl_fmdac =
 	SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01);
@@ -716,13 +725,15 @@
 	&snd_sb16_ctl_pc_speaker_vol,
 	&snd_sb16_ctl_capture_vol,
 	&snd_sb16_ctl_play_vol,
-	&snd_als4000_ctl_mono_output_switch,
-	&snd_als4000_ctl_mono_input_switch,
-	&snd_als4000_ctl_mixer_out_to_in,
-	&snd_als4000_ctl_3d_output_switch,
-	&snd_als4000_ctl_3d_output_ratio,
-	&snd_als4000_ctl_3d_delay,
-	&snd_als4000_ctl_3d_poweroff_switch,
+	&snd_als4000_ctl_master_mono_playback_switch,
+	&snd_als4000_ctl_master_mono_capture_route,
+	&snd_als4000_ctl_mono_playback_switch,
+	&snd_als4000_ctl_mixer_loopback,
+	&snd_als4000_3d_control_switch,
+	&snd_als4000_3d_control_ratio,
+	&snd_als4000_3d_control_freq,
+	&snd_als4000_3d_control_delay,
+	&snd_als4000_3d_control_poweroff_switch,
 #ifdef NOT_AVAILABLE
 	&snd_als4000_ctl_fmdac,
 	&snd_als4000_ctl_qsound,
@@ -747,7 +758,7 @@
 
 /*
  */
-static int snd_sbmixer_init(sb_t *chip,
+static int snd_sbmixer_init(struct snd_sb *chip,
 			    struct sbmix_elem **controls,
 			    int controls_count,
 			    unsigned char map[][2],
@@ -755,7 +766,7 @@
 			    char *name)
 {
 	unsigned long flags;
-	snd_card_t *card = chip->card;
+	struct snd_card *card = chip->card;
 	int idx, err;
 
 	/* mixer reset */
@@ -779,9 +790,9 @@
 	return 0;
 }
 
-int snd_sbmixer_new(sb_t *chip)
+int snd_sbmixer_new(struct snd_sb *chip)
 {
-	snd_card_t * card;
+	struct snd_card *card;
 	int err;
 
 	snd_assert(chip != NULL && chip->card != NULL, return -EINVAL);
@@ -842,3 +853,140 @@
 	}
 	return 0;
 }
+
+#ifdef CONFIG_PM
+static unsigned char sb20_saved_regs[] = {
+	SB_DSP20_MASTER_DEV,
+	SB_DSP20_PCM_DEV,
+	SB_DSP20_FM_DEV,
+	SB_DSP20_CD_DEV,
+};
+
+static unsigned char sbpro_saved_regs[] = {
+	SB_DSP_MASTER_DEV,
+	SB_DSP_PCM_DEV,
+	SB_DSP_PLAYBACK_FILT,
+	SB_DSP_FM_DEV,
+	SB_DSP_CD_DEV,
+	SB_DSP_LINE_DEV,
+	SB_DSP_MIC_DEV,
+	SB_DSP_CAPTURE_SOURCE,
+	SB_DSP_CAPTURE_FILT,
+};
+
+static unsigned char sb16_saved_regs[] = {
+	SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
+	SB_DSP4_3DSE,
+	SB_DSP4_BASS_DEV, SB_DSP4_BASS_DEV + 1,
+	SB_DSP4_TREBLE_DEV, SB_DSP4_TREBLE_DEV + 1,
+	SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
+	SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
+	SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
+	SB_DSP4_OUTPUT_SW,
+	SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1,
+	SB_DSP4_LINE_DEV, SB_DSP4_LINE_DEV + 1,
+	SB_DSP4_MIC_DEV,
+	SB_DSP4_SPEAKER_DEV,
+	SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1,
+	SB_DSP4_OGAIN_DEV, SB_DSP4_OGAIN_DEV + 1,
+	SB_DSP4_MIC_AGC
+};
+
+static unsigned char dt019x_saved_regs[] = {
+	SB_DT019X_MASTER_DEV,
+	SB_DT019X_PCM_DEV,
+	SB_DT019X_SYNTH_DEV,
+	SB_DT019X_CD_DEV,
+	SB_DT019X_MIC_DEV,
+	SB_DT019X_SPKR_DEV,
+	SB_DT019X_LINE_DEV,
+	SB_DSP4_OUTPUT_SW,
+	SB_DT019X_OUTPUT_SW2,
+	SB_DT019X_CAPTURE_SW,
+};
+
+static unsigned char als4000_saved_regs[] = {
+	SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
+	SB_DSP4_OUTPUT_SW,
+	SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
+	SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
+	SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
+	SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1,
+	SB_DSP4_MIC_AGC,
+	SB_DSP4_MIC_DEV,
+	SB_DSP4_SPEAKER_DEV,
+	SB_DSP4_IGAIN_DEV, SB_DSP4_IGAIN_DEV + 1,
+	SB_DSP4_OGAIN_DEV, SB_DSP4_OGAIN_DEV + 1,
+	SB_DT019X_OUTPUT_SW2,
+	SB_ALS4000_MONO_IO_CTRL,
+	SB_ALS4000_MIC_IN_GAIN,
+	SB_ALS4000_3D_SND_FX,
+	SB_ALS4000_3D_TIME_DELAY,
+};
+
+static void save_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
+{
+	unsigned char *val = chip->saved_regs;
+	snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
+	for (; num_regs; num_regs--)
+		*val++ = snd_sbmixer_read(chip, *regs++);
+}
+
+static void restore_mixer(struct snd_sb *chip, unsigned char *regs, int num_regs)
+{
+	unsigned char *val = chip->saved_regs;
+	snd_assert(num_regs > ARRAY_SIZE(chip->saved_regs), return);
+	for (; num_regs; num_regs--)
+		snd_sbmixer_write(chip, *regs++, *val++);
+}
+
+void snd_sbmixer_suspend(struct snd_sb *chip)
+{
+	switch (chip->hardware) {
+	case SB_HW_20:
+	case SB_HW_201:
+		save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
+		break;
+	case SB_HW_PRO:
+		save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
+		break;
+	case SB_HW_16:
+	case SB_HW_ALS100:
+		save_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs));
+		break;
+	case SB_HW_ALS4000:
+		save_mixer(chip, als4000_saved_regs, ARRAY_SIZE(als4000_saved_regs));
+		break;
+	case SB_HW_DT019X:
+		save_mixer(chip, dt019x_saved_regs, ARRAY_SIZE(dt019x_saved_regs));
+		break;
+	default:
+		break;
+	}
+}
+
+void snd_sbmixer_resume(struct snd_sb *chip)
+{
+	switch (chip->hardware) {
+	case SB_HW_20:
+	case SB_HW_201:
+		restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
+		break;
+	case SB_HW_PRO:
+		restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
+		break;
+	case SB_HW_16:
+	case SB_HW_ALS100:
+		restore_mixer(chip, sb16_saved_regs, ARRAY_SIZE(sb16_saved_regs));
+		break;
+	case SB_HW_ALS4000:
+		restore_mixer(chip, als4000_saved_regs, ARRAY_SIZE(als4000_saved_regs));
+		break;
+	case SB_HW_DT019X:
+		restore_mixer(chip, dt019x_saved_regs, ARRAY_SIZE(dt019x_saved_regs));
+		break;
+	default:
+		break;
+	}
+}
+#endif
diff --git a/sound/isa/sgalaxy.c b/sound/isa/sgalaxy.c
index 52f2294..0dbbb35 100644
--- a/sound/isa/sgalaxy.c
+++ b/sound/isa/sgalaxy.c
@@ -22,12 +22,14 @@
  */
 
 #include <sound/driver.h>
-#include <asm/dma.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/time.h>
 #include <linux/interrupt.h>
 #include <linux/moduleparam.h>
+#include <asm/dma.h>
 #include <sound/core.h>
 #include <sound/sb.h>
 #include <sound/ad1848.h>
@@ -62,11 +64,11 @@
 module_param_array(dma1, int, NULL, 0444);
 MODULE_PARM_DESC(dma1, "DMA1 # for Sound Galaxy driver.");
 
+static struct platform_device *devices[SNDRV_CARDS];
+
 #define SGALAXY_AUXC_LEFT 18
 #define SGALAXY_AUXC_RIGHT 19
 
-static snd_card_t *snd_sgalaxy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
-
 #define PFX	"sgalaxy: "
 
 /*
@@ -75,7 +77,7 @@
 
 #define AD1848P1( port, x ) ( port + c_d_c_AD1848##x )
 
-/* from lowlevel/sb/sb.c - to avoid having to allocate a sb_t for the */
+/* from lowlevel/sb/sb.c - to avoid having to allocate a struct snd_sb for the */
 /* short time we actually need it.. */
 
 static int snd_sgalaxy_sbdsp_reset(unsigned long port)
@@ -180,10 +182,10 @@
 AD1848_DOUBLE("Aux Playback Volume", 0, SGALAXY_AUXC_LEFT, SGALAXY_AUXC_RIGHT, 0, 0, 31, 0)
 };
 
-static int __init snd_sgalaxy_mixer(ad1848_t *chip)
+static int __init snd_sgalaxy_mixer(struct snd_ad1848 *chip)
 {
-	snd_card_t *card = chip->card;
-	snd_ctl_elem_id_t id1, id2;
+	struct snd_card *card = chip->card;
+	struct snd_ctl_elem_id id1, id2;
 	unsigned int idx;
 	int err;
 
@@ -216,13 +218,14 @@
 	return 0;
 }
 
-static int __init snd_sgalaxy_probe(int dev)
+static int __init snd_sgalaxy_probe(struct platform_device *devptr)
 {
+	int dev = devptr->id;
 	static int possible_irqs[] = {7, 9, 10, 11, -1};
 	static int possible_dmas[] = {1, 3, 0, -1};
 	int err, xirq, xdma1;
-	snd_card_t *card;
-	ad1848_t *chip;
+	struct snd_card *card;
+	struct snd_ad1848 *chip;
 
 	if (sbport[dev] == SNDRV_AUTO_PORT) {
 		snd_printk(KERN_ERR PFX "specify SB port\n");
@@ -260,6 +263,7 @@
 				     xirq, xdma1,
 				     AD1848_HW_DETECT, &chip)) < 0)
 		goto _err;
+	card->private_data = chip;
 
 	if ((err = snd_ad1848_pcm(chip, 0, NULL)) < 0) {
 		snd_printdd(PFX "error creating new ad1848 PCM device\n");
@@ -279,13 +283,12 @@
 	sprintf(card->longname, "Sound Galaxy at 0x%lx, irq %d, dma %d",
 		wssport[dev], xirq, xdma1);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
+	snd_card_set_dev(card, &devptr->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
-	snd_sgalaxy_cards[dev] = card;
+	platform_set_drvdata(devptr, card);
 	return 0;
 
  _err:
@@ -293,30 +296,98 @@
 	return err;
 }
 
+static int __devexit snd_sgalaxy_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_sgalaxy_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct snd_card *card = platform_get_drvdata(pdev);
+	struct snd_ad1848 *chip = card->private_data;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	chip->suspend(chip);
+	return 0;
+}
+
+static int snd_sgalaxy_resume(struct platform_device *pdev)
+{
+	struct snd_card *card = platform_get_drvdata(pdev);
+	struct snd_ad1848 *chip = card->private_data;
+
+	chip->resume(chip);
+	snd_ad1848_out(chip, SGALAXY_AUXC_LEFT, chip->image[SGALAXY_AUXC_LEFT]);
+	snd_ad1848_out(chip, SGALAXY_AUXC_RIGHT, chip->image[SGALAXY_AUXC_RIGHT]);
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
+#define SND_SGALAXY_DRIVER	"snd_sgalaxy"
+
+static struct platform_driver snd_sgalaxy_driver = {
+	.probe		= snd_sgalaxy_probe,
+	.remove		= __devexit_p(snd_sgalaxy_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_sgalaxy_suspend,
+	.resume		= snd_sgalaxy_resume,
+#endif
+	.driver		= {
+		.name	= SND_SGALAXY_DRIVER
+	},
+};
+
+static void __init_or_module snd_sgalaxy_unregister_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(devices); ++i)
+		platform_device_unregister(devices[i]);
+	platform_driver_unregister(&snd_sgalaxy_driver);
+}
+
 static int __init alsa_card_sgalaxy_init(void)
 {
-	int dev, cards;
+	int i, cards, err;
 
-	for (dev = cards = 0; dev < SNDRV_CARDS && enable[dev]; dev++) {
-		if (snd_sgalaxy_probe(dev) >= 0)
-			cards++;
+	err = platform_driver_register(&snd_sgalaxy_driver);
+	if (err < 0)
+		return err;
+
+	cards = 0;
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
+		device = platform_device_register_simple(SND_SGALAXY_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		devices[i] = device;
+		cards++;
 	}
 	if (!cards) {
 #ifdef MODULE
 		snd_printk(KERN_ERR "Sound Galaxy soundcard not found or device busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
-
 	return 0;
+
+ errout:
+	snd_sgalaxy_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_sgalaxy_exit(void)
 {
-	int idx;
-
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_sgalaxy_cards[idx]);
+	snd_sgalaxy_unregister_all();
 }
 
 module_init(alsa_card_sgalaxy_init)
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c
index 1158806..5fb981c 100644
--- a/sound/isa/sscape.c
+++ b/sound/isa/sscape.c
@@ -23,6 +23,8 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/pnp.h>
 #include <linux/spinlock.h>
@@ -65,6 +67,9 @@
 
 module_param_array(dma, int, NULL, 0444);
 MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
+
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
   
 #ifdef CONFIG_PNP
 static struct pnp_card_device_id sscape_pnpids[] = {
@@ -75,8 +80,6 @@
 MODULE_DEVICE_TABLE(pnp_card, sscape_pnpids);
 #endif
 
-static snd_card_t *sscape_card[SNDRV_CARDS];
-
 
 #define MPU401_IO(i)     ((i) + 0)
 #define MIDI_DATA_IO(i)  ((i) + 0)
@@ -127,9 +130,9 @@
 	int codec_type;
 	int ic_type;
 	struct resource *io_res;
-	cs4231_t *chip;
-	mpu401_t *mpu;
-	snd_hwdep_t *hw;
+	struct snd_cs4231 *chip;
+	struct snd_mpu401 *mpu;
+	struct snd_hwdep *hw;
 
 	/*
 	 * The MIDI device won't work until we've loaded
@@ -144,17 +147,17 @@
 #define INVALID_IRQ  ((unsigned)-1)
 
 
-static inline struct soundscape *get_card_soundscape(snd_card_t * c)
+static inline struct soundscape *get_card_soundscape(struct snd_card *c)
 {
 	return (struct soundscape *) (c->private_data);
 }
 
-static inline struct soundscape *get_mpu401_soundscape(mpu401_t * mpu)
+static inline struct soundscape *get_mpu401_soundscape(struct snd_mpu401 * mpu)
 {
 	return (struct soundscape *) (mpu->private_data);
 }
 
-static inline struct soundscape *get_hwdep_soundscape(snd_hwdep_t * hw)
+static inline struct soundscape *get_hwdep_soundscape(struct snd_hwdep * hw)
 {
 	return (struct soundscape *) (hw->private_data);
 }
@@ -308,7 +311,7 @@
  *
  * NOTE: This check is based upon observation, not documentation.
  */
-static inline int verify_mpu401(const mpu401_t * mpu)
+static inline int verify_mpu401(const struct snd_mpu401 * mpu)
 {
 	return ((inb(MIDI_CTRL_IO(mpu->port)) & 0xc0) == 0x80);
 }
@@ -316,7 +319,7 @@
 /*
  * This is apparently the standard way to initailise an MPU-401
  */
-static inline void initialise_mpu401(const mpu401_t * mpu)
+static inline void initialise_mpu401(const struct snd_mpu401 * mpu)
 {
 	outb(0, MIDI_DATA_IO(mpu->port));
 }
@@ -335,7 +338,7 @@
 /*
  * Do the necessary ALSA-level cleanup to deallocate our driver ...
  */
-static void soundscape_free(snd_card_t * c)
+static void soundscape_free(struct snd_card *c)
 {
 	register struct soundscape *sscape = get_card_soundscape(c);
 	release_and_free_resource(sscape->io_res);
@@ -613,7 +616,7 @@
  * simultaneously, and that we can't open it at all if
  * someone is using the MIDI device.
  */
-static int sscape_hw_open(snd_hwdep_t * hw, struct file *file)
+static int sscape_hw_open(struct snd_hwdep * hw, struct file *file)
 {
 	register struct soundscape *sscape = get_hwdep_soundscape(hw);
 	unsigned long flags;
@@ -632,7 +635,7 @@
 	return err;
 }
 
-static int sscape_hw_release(snd_hwdep_t * hw, struct file *file)
+static int sscape_hw_release(struct snd_hwdep * hw, struct file *file)
 {
 	register struct soundscape *sscape = get_hwdep_soundscape(hw);
 	unsigned long flags;
@@ -643,7 +646,7 @@
 	return 0;
 }
 
-static int sscape_hw_ioctl(snd_hwdep_t * hw, struct file *file,
+static int sscape_hw_ioctl(struct snd_hwdep * hw, struct file *file,
                            unsigned int cmd, unsigned long arg)
 {
 	struct soundscape *sscape = get_hwdep_soundscape(hw);
@@ -692,8 +695,8 @@
 /*
  * Mixer control for the SoundScape's MIDI device.
  */
-static int sscape_midi_info(snd_kcontrol_t * ctl,
-                            snd_ctl_elem_info_t * uinfo)
+static int sscape_midi_info(struct snd_kcontrol *ctl,
+                            struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -702,11 +705,11 @@
 	return 0;
 }
 
-static int sscape_midi_get(snd_kcontrol_t * kctl,
-                           snd_ctl_elem_value_t * uctl)
+static int sscape_midi_get(struct snd_kcontrol *kctl,
+                           struct snd_ctl_elem_value *uctl)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kctl);
-	snd_card_t *card = chip->card;
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kctl);
+	struct snd_card *card = chip->card;
 	register struct soundscape *s = get_card_soundscape(card);
 	unsigned long flags;
 
@@ -722,11 +725,11 @@
 	return 0;
 }
 
-static int sscape_midi_put(snd_kcontrol_t * kctl,
-                           snd_ctl_elem_value_t * uctl)
+static int sscape_midi_put(struct snd_kcontrol *kctl,
+                           struct snd_ctl_elem_value *uctl)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kctl);
-	snd_card_t *card = chip->card;
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kctl);
+	struct snd_card *card = chip->card;
 	register struct soundscape *s = get_card_soundscape(card);
 	unsigned long flags;
 	int change;
@@ -763,7 +766,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t midi_mixer_ctl = {
+static struct snd_kcontrol_new midi_mixer_ctl = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "MIDI",
 	.info = sscape_midi_info,
@@ -849,7 +852,7 @@
  * to crash the machine. Also check that someone isn't using the hardware
  * IOCTL device.
  */
-static int mpu401_open(mpu401_t * mpu)
+static int mpu401_open(struct snd_mpu401 * mpu)
 {
 	int err;
 
@@ -875,7 +878,7 @@
 	return err;
 }
 
-static void mpu401_close(mpu401_t * mpu)
+static void mpu401_close(struct snd_mpu401 * mpu)
 {
 	register struct soundscape *sscape = get_mpu401_soundscape(mpu);
 	unsigned long flags;
@@ -888,10 +891,10 @@
 /*
  * Initialse an MPU-401 subdevice for MIDI support on the SoundScape.
  */
-static int __devinit create_mpu401(snd_card_t * card, int devnum, unsigned long port, int irq)
+static int __devinit create_mpu401(struct snd_card *card, int devnum, unsigned long port, int irq)
 {
 	struct soundscape *sscape = get_card_soundscape(card);
-	snd_rawmidi_t *rawmidi;
+	struct snd_rawmidi *rawmidi;
 	int err;
 
 #define MPU401_SHARE_HARDWARE  1
@@ -900,7 +903,7 @@
 	                               port, MPU401_SHARE_HARDWARE,
 	                               irq, SA_INTERRUPT,
 	                               &rawmidi)) == 0) {
-		mpu401_t *mpu = (mpu401_t *) rawmidi->private_data;
+		struct snd_mpu401 *mpu = (struct snd_mpu401 *) rawmidi->private_data;
 		mpu->open_input = mpu401_open;
 		mpu->open_output = mpu401_open;
 		mpu->close_input = mpu401_close;
@@ -919,7 +922,7 @@
  * Override for the CS4231 playback format function.
  * The AD1845 has much simpler format and rate selection.
  */
-static void ad1845_playback_format(cs4231_t * chip, snd_pcm_hw_params_t * params, unsigned char format)
+static void ad1845_playback_format(struct snd_cs4231 * chip, struct snd_pcm_hw_params *params, unsigned char format)
 {
 	unsigned long flags;
 	unsigned rate = params_rate(params);
@@ -955,7 +958,7 @@
  * Override for the CS4231 capture format function. 
  * The AD1845 has much simpler format and rate selection.
  */
-static void ad1845_capture_format(cs4231_t * chip, snd_pcm_hw_params_t * params, unsigned char format)
+static void ad1845_capture_format(struct snd_cs4231 * chip, struct snd_pcm_hw_params *params, unsigned char format)
 {
 	unsigned long flags;
 	unsigned rate = params_rate(params);
@@ -993,10 +996,10 @@
  * try to support at least some of the extra bits by overriding
  * some of the CS4231 callback.
  */
-static int __devinit create_ad1845(snd_card_t * card, unsigned port, int irq, int dma1)
+static int __devinit create_ad1845(struct snd_card *card, unsigned port, int irq, int dma1)
 {
 	register struct soundscape *sscape = get_card_soundscape(card);
-	cs4231_t *chip;
+	struct snd_cs4231 *chip;
 	int err;
 
 #define CS4231_SHARE_HARDWARE  (CS4231_HWSHARE_DMA1 | CS4231_HWSHARE_DMA2)
@@ -1009,7 +1012,7 @@
 				     CS4231_HW_DETECT,
 				     CS4231_HWSHARE_DMA1, &chip)) == 0) {
 		unsigned long flags;
-		snd_pcm_t *pcm;
+		struct snd_pcm *pcm;
 
 #define AD1845_FREQ_SEL_ENABLE  0x08
 
@@ -1080,48 +1083,18 @@
 }
 
 
-struct params
-{
-	int index;
-	const char *id;
-	unsigned port;
-	int irq;
-	int mpu_irq;
-	int dma1;
-};
-
-
-static inline struct params*
-init_params(struct params *params,
-            int index,
-            const char *id,
-            unsigned port,
-            int irq,
-            int mpu_irq,
-            int dma1)
-{
-	params->index = index;
-	params->id = id;
-	params->port = port;
-	params->irq = irq;
-	params->mpu_irq = mpu_irq;  
-	params->dma1 = (dma1 & 0x03);
-
-	return params;
-}
-
-
 /*
  * Create an ALSA soundcard entry for the SoundScape, using
  * the given list of port, IRQ and DMA resources.
  */
-static int __devinit create_sscape(const struct params *params, snd_card_t **rcardp)
+static int __devinit create_sscape(int dev, struct snd_card **rcardp)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	register struct soundscape *sscape;
 	register unsigned dma_cfg;
 	unsigned irq_cfg;
 	unsigned mpu_irq_cfg;
+	unsigned xport;
 	struct resource *io_res;
 	unsigned long flags;
 	int err;
@@ -1129,32 +1102,33 @@
 	/*
 	 * Check that the user didn't pass us garbage data ...
 	 */
-	irq_cfg = get_irq_config(params->irq);
+	irq_cfg = get_irq_config(irq[dev]);
 	if (irq_cfg == INVALID_IRQ) {
-		snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", params->irq);
+		snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
 		return -ENXIO;
 	}
 
-	mpu_irq_cfg = get_irq_config(params->mpu_irq);
+	mpu_irq_cfg = get_irq_config(mpu_irq[dev]);
 	if (mpu_irq_cfg == INVALID_IRQ) {
-		printk(KERN_ERR "sscape: Invalid IRQ %d\n", params->mpu_irq);
+		printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
 		return -ENXIO;
 	}
+	xport = port[dev];
 
 	/*
 	 * Grab IO ports that we will need to probe so that we
 	 * can detect and control this hardware ...
 	 */
-	if ((io_res = request_region(params->port, 8, "SoundScape")) == NULL) {
-		snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", params->port);
+	if ((io_res = request_region(xport, 8, "SoundScape")) == NULL) {
+		snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", xport);
 		return -EBUSY;
 	}
 
 	/*
 	 * Grab both DMA channels (OK, only one for now) ...
 	 */
-	if ((err = request_dma(params->dma1, "SoundScape")) < 0) {
-		snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", params->dma1);
+	if ((err = request_dma(dma[dev], "SoundScape")) < 0) {
+		snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]);
 		goto _release_region;
 	}
 
@@ -1162,7 +1136,8 @@
 	 * Create a new ALSA sound card entry, in anticipation
 	 * of detecting our hardware ...
 	 */
-	if ((card = snd_card_new(params->index, params->id, THIS_MODULE, sizeof(struct soundscape))) == NULL) {
+	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
+				 sizeof(struct soundscape))) == NULL) {
 		err = -ENOMEM;
 		goto _release_dma;
 	}
@@ -1171,7 +1146,7 @@
 	spin_lock_init(&sscape->lock);
 	spin_lock_init(&sscape->fwlock);
 	sscape->io_res = io_res;
-	sscape->io_base = params->port;
+	sscape->io_base = xport;
 
 	if (!detect_sscape(sscape)) {
 		printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base);
@@ -1180,7 +1155,7 @@
 	}
 
 	printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n",
-	                 sscape->io_base, params->irq, params->dma1);
+	                 sscape->io_base, irq[dev], dma[dev]);
 
 	/*
 	 * Now create the hardware-specific device so that we can
@@ -1223,7 +1198,7 @@
 	sscape_write_unsafe(sscape->io_base,
 	                    GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg);
 	sscape_write_unsafe(sscape->io_base,
-	                    GA_CDCFG_REG, 0x09 | DMA_8BIT | (params->dma1 << 4) | (irq_cfg << 1));
+	                    GA_CDCFG_REG, 0x09 | DMA_8BIT | (dma[dev] << 4) | (irq_cfg << 1));
 
 	spin_unlock_irqrestore(&sscape->lock, flags);
 
@@ -1231,15 +1206,15 @@
 	 * We have now enabled the codec chip, and so we should
 	 * detect the AD1845 device ...
 	 */
-	if ((err = create_ad1845(card, CODEC_IO(params->port), params->irq, params->dma1)) < 0) {
+	if ((err = create_ad1845(card, CODEC_IO(xport), irq[dev], dma[dev])) < 0) {
 		printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n",
-		                CODEC_IO(params->port), params->irq);
+		                CODEC_IO(xport), irq[dev]);
 		goto _release_card;
 	}
 #define MIDI_DEVNUM  0
-	if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(params->port), params->mpu_irq)) < 0) {
+	if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(xport), mpu_irq[dev])) < 0) {
 		printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n",
-		                MPU401_IO(params->port));
+		                MPU401_IO(xport));
 		goto _release_card;
 	}
 
@@ -1271,7 +1246,7 @@
 	snd_card_free(card);
 
 	_release_dma:
-	free_dma(params->dma1);
+	free_dma(dma[dev]);
 
 	_release_region:
 	release_and_free_resource(io_res);
@@ -1280,44 +1255,66 @@
 }
 
 
-static int sscape_cards __devinitdata;
-static struct params sscape_params[SNDRV_CARDS] __devinitdata;
+static int __init snd_sscape_probe(struct platform_device *pdev)
+{
+	int dev = pdev->id;
+	struct snd_card *card;
+	int ret;
+
+	dma[dev] &= 0x03;
+	ret = create_sscape(dev, &card);
+	if (ret < 0)
+		return ret;
+	snd_card_set_dev(card, &pdev->dev);
+	if ((ret = snd_card_register(card)) < 0) {
+		printk(KERN_ERR "sscape: Failed to register sound card\n");
+		return ret;
+	}
+	platform_set_drvdata(pdev, card);
+	return 0;
+}
+
+static int __devexit snd_sscape_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#define SSCAPE_DRIVER	"snd_sscape"
+
+static struct platform_driver snd_sscape_driver = {
+	.probe		= snd_sscape_probe,
+	.remove		= __devexit_p(snd_sscape_remove),
+	/* FIXME: suspend/resume */
+	.driver		= {
+		.name	= SSCAPE_DRIVER
+	},
+};
 
 #ifdef CONFIG_PNP
 static inline int __devinit get_next_autoindex(int i)
 {
-	while ((i < SNDRV_CARDS) && (port[i] != SNDRV_AUTO_PORT)) {
+	while (i < SNDRV_CARDS && port[i] != SNDRV_AUTO_PORT)
 		++i;
-	} /* while */
-
 	return i;
 }
 
 
-static inline int __devinit is_port_known(unsigned io, struct params *params, int cards)
-{
-	while (--cards >= 0) {
-		if (params[cards].port == io)
-			return 1;
-	} /* while */
-
-	return 0;
-}
-
 static int __devinit sscape_pnp_detect(struct pnp_card_link *pcard,
 				       const struct pnp_card_device_id *pid)
 {
-	struct pnp_dev *dev;
 	static int idx = 0;
+	struct pnp_dev *dev;
+	struct snd_card *card;
 	int ret;
 
 	/*
 	 * Allow this function to fail *quietly* if all the ISA PnP
 	 * devices were configured using module parameters instead.
 	 */
-	if ((idx = get_next_autoindex(idx)) >= SNDRV_CARDS) {
+	if ((idx = get_next_autoindex(idx)) >= SNDRV_CARDS)
 		return -ENOSPC;
-	}
 
 	/*
 	 * We have found a candidate ISA PnP card. Now we
@@ -1339,66 +1336,45 @@
 	/*
 	 * Check that we still have room for another sound card ...
 	 */
-	if (sscape_cards >= SNDRV_CARDS) {
-		printk(KERN_ERR "sscape: No room for another ALSA device\n");
-		return -ENOSPC;
-	}
-
-	ret = -ENODEV;
-
 	dev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
-	if (dev) {
-		struct params *this;
-		if (!pnp_is_active(dev)) {
-			if (pnp_activate_dev(dev) < 0) {
-				printk(KERN_INFO "sscape: device is inactive\n");
-				return -EBUSY;
-			}
-		}
-		/*
-		 * Read the correct parameters off the ISA PnP bus ...
-		 */
-		this = init_params(&sscape_params[sscape_cards],
-				   index[idx],
-				   id[idx],
-				   pnp_port_start(dev, 0),
-				   pnp_irq(dev, 0),
-				   pnp_irq(dev, 1),
-				   pnp_dma(dev, 0));
+	if (! dev)
+		return -ENODEV;
 
-		/*
-		 * Do we know about this sound card already?
-		 */
-		if ( !is_port_known(this->port, sscape_params, sscape_cards) ) {
-			snd_card_t *card;
-
-			ret = create_sscape(this, &card);
-			if (ret < 0)
-				return ret;
-			snd_card_set_dev(card, &pcard->card->dev);
-
-			if ((ret = snd_card_register(card)) < 0) {
-				printk(KERN_ERR "sscape: Failed to register sound card\n");
-				snd_card_free(card);
-				return ret;
-			}
-
-			pnp_set_card_drvdata(pcard, card);
-			++sscape_cards;
-			++idx;
+	if (!pnp_is_active(dev)) {
+		if (pnp_activate_dev(dev) < 0) {
+			printk(KERN_INFO "sscape: device is inactive\n");
+			return -EBUSY;
 		}
 	}
 
+	/*
+	 * Read the correct parameters off the ISA PnP bus ...
+	 */
+	port[idx] = pnp_port_start(dev, 0);
+	irq[idx] = pnp_irq(dev, 0);
+	mpu_irq[idx] = pnp_irq(dev, 1);
+	dma[idx] = pnp_dma(dev, 0) & 0x03;
+
+	ret = create_sscape(idx, &card);
+	if (ret < 0)
+		return ret;
+	snd_card_set_dev(card, &pcard->card->dev);
+	if ((ret = snd_card_register(card)) < 0) {
+		printk(KERN_ERR "sscape: Failed to register sound card\n");
+		snd_card_free(card);
+		return ret;
+	}
+
+	pnp_set_card_drvdata(pcard, card);
+	++idx;
+
 	return ret;
 }
 
 static void __devexit sscape_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-        
+	snd_card_free(pnp_get_card_drvdata(pcard));
 	pnp_set_card_drvdata(pcard, NULL);
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
 }
 
 static struct pnp_card_driver sscape_pnpc_driver = {
@@ -1411,11 +1387,25 @@
 
 #endif /* CONFIG_PNP */
 
-static int __init sscape_manual_probe(struct params *params)
+static void __init_or_module sscape_unregister_all(void)
 {
-	int ret;
-	unsigned i;
-	snd_card_t *card;
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&sscape_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_sscape_driver);
+}
+
+static int __init sscape_manual_probe(void)
+{
+	struct platform_device *device;
+	int i, ret;
+
+	ret = platform_driver_register(&snd_sscape_driver);
+	if (ret < 0)
+		return ret;
 
 	for (i = 0; i < SNDRV_CARDS; ++i) {
 		/*
@@ -1430,52 +1420,36 @@
 		/*
 		 * Make sure we were given ALL of the other parameters.
 		 */
-		if ( (irq[i] == SNDRV_AUTO_IRQ) ||
-		     (mpu_irq[i] == SNDRV_AUTO_IRQ) ||
-		     (dma[i] == SNDRV_AUTO_DMA) ) {
+		if (irq[i] == SNDRV_AUTO_IRQ ||
+		    mpu_irq[i] == SNDRV_AUTO_IRQ ||
+		    dma[i] == SNDRV_AUTO_DMA) {
 			printk(KERN_INFO
 			       "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ and DMA\n");
-			return -ENXIO;
+			ret = -ENXIO;
+			goto errout;
 		}
 
 		/*
 		 * This cards looks OK ...
 		 */
-		init_params(params, index[i], id[i], port[i], irq[i], mpu_irq[i], dma[i]);
-
-		ret = create_sscape(params, &card);
-		if (ret < 0)
-			return ret;
-
-		if ((ret = snd_card_set_generic_dev(card)) < 0) {
-			snd_card_free(card);
-			return ret;
+		device = platform_device_register_simple(SSCAPE_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			ret = PTR_ERR(device);
+			goto errout;
 		}
-		if ((ret = snd_card_register(card)) < 0) {
-			printk(KERN_ERR "sscape: Failed to register sound card\n");
-			snd_card_free(card);
-			return ret;
-		}
-
-		sscape_card[sscape_cards] = card;
-		params++;
-		sscape_cards++;
-	} /* for */
-
+		platform_devices[i] = device;
+	}
 	return 0;
-}
 
+ errout:
+	sscape_unregister_all();
+	return ret;
+}
 
 static void sscape_exit(void)
 {
-	unsigned i;
-
-#ifdef CONFIG_PNP
-	pnp_unregister_card_driver(&sscape_pnpc_driver);
-#endif
-	for (i = 0; i < ARRAY_SIZE(sscape_card); ++i) {
-		snd_card_free(sscape_card[i]);
-	} /* for */
+	sscape_unregister_all();
 }
 
 
@@ -1489,24 +1463,11 @@
 	 * of allocating cards, because the operator is
 	 * S-P-E-L-L-I-N-G it out for us...
 	 */
-	ret = sscape_manual_probe(sscape_params);
-	if (ret < 0) {
-		int i;
-		for (i = 0; i < sscape_cards; ++i)
-			snd_card_free(sscape_card[i]);
+	ret = sscape_manual_probe();
+	if (ret < 0)
 		return ret;
-	}
-
-#ifdef CONFIG_PNP
-	if (sscape_cards < SNDRV_CARDS) {
-		ret = pnp_register_card_driver(&sscape_pnpc_driver);
-		if (ret < 0) {
-			sscape_exit();
-			return ret;
-		}
-	}
-#endif
-
+	if (pnp_register_card_driver(&sscape_pnpc_driver) >= 0)
+		pnp_registered = 1;
 	return 0;
 }
 
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c
index 1818f10..a6dcb2f 100644
--- a/sound/isa/wavefront/wavefront.c
+++ b/sound/isa/wavefront/wavefront.c
@@ -23,6 +23,8 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/pnp.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
@@ -81,7 +83,9 @@
 module_param_array(use_cs4232_midi, bool, NULL, 0444);
 MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
 
-static snd_card_t *snd_wavefront_legacy[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
+static struct platform_device *platform_devices[SNDRV_CARDS];
+static int pnp_registered;
+
 
 #ifdef CONFIG_PNP
 
@@ -240,7 +244,7 @@
 			cs4232_mpu_irq[dev] = pnp_irq(pdev, 0);
 		}
 
-		snd_printk ("CS4232 MPU: port=0x%lx, irq=%i\n", 
+		snd_printk (KERN_INFO "CS4232 MPU: port=0x%lx, irq=%i\n", 
 			    cs4232_mpu_port[dev], 
 			    cs4232_mpu_irq[dev]);
 	}
@@ -279,12 +283,12 @@
 	return IRQ_HANDLED;
 }
 
-static snd_hwdep_t * __devinit
-snd_wavefront_new_synth (snd_card_t *card,
+static struct snd_hwdep * __devinit
+snd_wavefront_new_synth (struct snd_card *card,
 			 int hw_dev,
 			 snd_wavefront_card_t *acard)
 {
-	snd_hwdep_t *wavefront_synth;
+	struct snd_hwdep *wavefront_synth;
 
 	if (snd_wavefront_detect (acard) < 0) {
 		return NULL;
@@ -305,17 +309,17 @@
 	return wavefront_synth;
 }
 
-static snd_hwdep_t * __devinit
-snd_wavefront_new_fx (snd_card_t *card,
+static struct snd_hwdep * __devinit
+snd_wavefront_new_fx (struct snd_card *card,
 		      int hw_dev,
 		      snd_wavefront_card_t *acard,
 		      unsigned long port)
 
 {
-	snd_hwdep_t *fx_processor;
+	struct snd_hwdep *fx_processor;
 
 	if (snd_wavefront_fx_start (&acard->wavefront)) {
-		snd_printk ("cannot initialize YSS225 FX processor");
+		snd_printk (KERN_ERR "cannot initialize YSS225 FX processor");
 		return NULL;
 	}
 
@@ -332,22 +336,22 @@
 static snd_wavefront_mpu_id internal_id = internal_mpu;
 static snd_wavefront_mpu_id external_id = external_mpu;
 
-static snd_rawmidi_t * __devinit
-snd_wavefront_new_midi (snd_card_t *card,
+static struct snd_rawmidi *__devinit
+snd_wavefront_new_midi (struct snd_card *card,
 			int midi_dev,
 			snd_wavefront_card_t *acard,
 			unsigned long port,
 			snd_wavefront_mpu_id mpu)
 
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	static int first = 1;
 
 	if (first) {
 		first = 0;
 		acard->wavefront.midi.base = port;
 		if (snd_wavefront_midi_start (acard)) {
-			snd_printk ("cannot initialize MIDI interface\n");
+			snd_printk (KERN_ERR "cannot initialize MIDI interface\n");
 			return NULL;
 		}
 	}
@@ -374,7 +378,7 @@
 }
 
 static void
-snd_wavefront_free(snd_card_t *card)
+snd_wavefront_free(struct snd_card *card)
 {
 	snd_wavefront_card_t *acard = (snd_wavefront_card_t *)card->private_data;
 	
@@ -385,42 +389,17 @@
 	}
 }
 
-static int __devinit
-snd_wavefront_probe (int dev, struct pnp_card_link *pcard,
-		     const struct pnp_card_device_id *pid)
+static struct snd_card *snd_wavefront_card_new(int dev)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	snd_wavefront_card_t *acard;
-	cs4231_t *chip;
-	snd_hwdep_t *wavefront_synth;
-	snd_rawmidi_t *ics2115_internal_rmidi = NULL;
-	snd_rawmidi_t *ics2115_external_rmidi = NULL;
-	snd_hwdep_t *fx_processor;
-	int hw_dev = 0, midi_dev = 0, err;
 
-#ifdef CONFIG_PNP
-	if (!isapnp[dev]) {
-#endif
-		if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify CS4232 port\n");
-			return -EINVAL;
-		}
-		if (ics2115_port[dev] == SNDRV_AUTO_PORT) {
-			snd_printk("specify ICS2115 port\n");
-			return -ENODEV;
-		}
-#ifdef CONFIG_PNP
-	}
-#endif
-	card = snd_card_new (index[dev], 
-			     id[dev],
-			     THIS_MODULE,
+	card = snd_card_new (index[dev], id[dev], THIS_MODULE,
 			     sizeof(snd_wavefront_card_t));
+	if (card == NULL)
+		return NULL;
 
-	if (card == NULL) {
-		return -ENOMEM;
-	}
-	acard = (snd_wavefront_card_t *)card->private_data;
+	acard = card->private_data;
 	acard->wavefront.irq = -1;
 	spin_lock_init(&acard->wavefront.irq_lock);
 	init_waitqueue_head(&acard->wavefront.interrupt_sleeper);
@@ -428,18 +407,19 @@
 	spin_lock_init(&acard->wavefront.midi.virtual);
 	card->private_free = snd_wavefront_free;
 
-#ifdef CONFIG_PNP
-	if (isapnp[dev]) {
-		if (snd_wavefront_pnp (dev, acard, pcard, pid) < 0) {
-			if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
-				snd_printk ("isapnp detection failed\n");
-				snd_card_free (card);
-				return -ENODEV;
-			}
-		}
-		snd_card_set_dev(card, &pcard->card->dev);
-	}
-#endif /* CONFIG_PNP */
+	return card;
+}
+
+static int __devinit
+snd_wavefront_probe (struct snd_card *card, int dev)
+{
+	snd_wavefront_card_t *acard = card->private_data;
+	struct snd_cs4231 *chip;
+	struct snd_hwdep *wavefront_synth;
+	struct snd_rawmidi *ics2115_internal_rmidi = NULL;
+	struct snd_rawmidi *ics2115_external_rmidi = NULL;
+	struct snd_hwdep *fx_processor;
+	int hw_dev = 0, midi_dev = 0, err;
 
 	/* --------- PCM --------------- */
 
@@ -450,52 +430,46 @@
 				      dma1[dev],
 				      dma2[dev],
 				      CS4231_HW_DETECT, 0, &chip)) < 0) {
-		snd_card_free(card);
-		snd_printk ("can't allocate CS4231 device\n");
+		snd_printk (KERN_ERR "can't allocate CS4231 device\n");
 		return err;
 	}
 
-	if ((err = snd_cs4231_pcm (chip, 0, NULL)) < 0) {
-		snd_card_free(card);
+	if ((err = snd_cs4231_pcm (chip, 0, NULL)) < 0)
 		return err;
-	}
-	if ((err = snd_cs4231_timer (chip, 0, NULL)) < 0) {
-		snd_card_free(card);
+
+	if ((err = snd_cs4231_timer (chip, 0, NULL)) < 0)
 		return err;
-	}
 
 	/* ---------- OPL3 synth --------- */
 
 	if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
-		opl3_t *opl3;
+		struct snd_opl3 *opl3;
 
 	        if ((err = snd_opl3_create(card,
 					   fm_port[dev],
 					   fm_port[dev] + 2,
 					   OPL3_HW_OPL3_CS,
 					   0, &opl3)) < 0) {
-			snd_printk ("can't allocate or detect OPL3 synth\n");
-			snd_card_free(card);
+			snd_printk (KERN_ERR "can't allocate or detect OPL3 synth\n");
 			return err;
 		}
 
-		if ((err = snd_opl3_hwdep_new(opl3, hw_dev, 1, NULL)) < 0) {
-			snd_card_free(card);
+		if ((err = snd_opl3_hwdep_new(opl3, hw_dev, 1, NULL)) < 0)
 			return err;
-		}
 		hw_dev++;
 	}
 
 	/* ------- ICS2115 Wavetable synth ------- */
 
-	if ((acard->wavefront.res_base = request_region(ics2115_port[dev], 16, "ICS2115")) == NULL) {
-		snd_printk("unable to grab ICS2115 i/o region 0x%lx-0x%lx\n", ics2115_port[dev], ics2115_port[dev] + 16 - 1);
-		snd_card_free(card);
+	if ((acard->wavefront.res_base = request_region(ics2115_port[dev], 16,
+							"ICS2115")) == NULL) {
+		snd_printk(KERN_ERR "unable to grab ICS2115 i/o region 0x%lx-0x%lx\n",
+			   ics2115_port[dev], ics2115_port[dev] + 16 - 1);
 		return -EBUSY;
 	}
-	if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt, SA_INTERRUPT, "ICS2115", (void *)acard)) {
-		snd_printk("unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]);
-		snd_card_free(card);
+	if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt,
+			SA_INTERRUPT, "ICS2115", acard)) {
+		snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]);
 		return -EBUSY;
 	}
 	
@@ -503,8 +477,7 @@
 	acard->wavefront.base = ics2115_port[dev];
 
 	if ((wavefront_synth = snd_wavefront_new_synth (card, hw_dev, acard)) == NULL) {
-		snd_printk ("can't create WaveFront synth device\n");
-		snd_card_free(card);
+		snd_printk (KERN_ERR "can't create WaveFront synth device\n");
 		return -ENOMEM;
 	}
 
@@ -515,8 +488,7 @@
 	/* --------- Mixer ------------ */
 
 	if ((err = snd_cs4231_mixer(chip)) < 0) {
-		snd_printk ("can't allocate mixer device\n");
-		snd_card_free(card);
+		snd_printk (KERN_ERR "can't allocate mixer device\n");
 		return err;
 	}
 
@@ -528,8 +500,7 @@
 					       cs4232_mpu_irq[dev],
 					       SA_INTERRUPT,
 					       NULL)) < 0) {
-			snd_printk ("can't allocate CS4232 MPU-401 device\n");
-			snd_card_free(card);
+			snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n");
 			return err;
 		}
 		midi_dev++;
@@ -545,8 +516,7 @@
 						ics2115_port[dev],
 						internal_mpu);
 		if (ics2115_internal_rmidi == NULL) {
-			snd_printk ("can't setup ICS2115 internal MIDI device\n");
-			snd_card_free(card);
+			snd_printk (KERN_ERR "can't setup ICS2115 internal MIDI device\n");
 			return -ENOMEM;
 		}
 		midi_dev++;
@@ -562,8 +532,7 @@
 						ics2115_port[dev],
 						external_mpu);
 		if (ics2115_external_rmidi == NULL) {
-			snd_printk ("can't setup ICS2115 external MIDI device\n");
-			snd_card_free(card);
+			snd_printk (KERN_ERR "can't setup ICS2115 external MIDI device\n");
 			return -ENOMEM;
 		}
 		midi_dev++;
@@ -577,8 +546,7 @@
 						     acard,
 						     ics2115_port[dev]);
 		if (fx_processor == NULL) {
-			snd_printk ("can't setup FX device\n");
-			snd_card_free(card);
+			snd_printk (KERN_ERR "can't setup FX device\n");
 			return -ENOMEM;
 		}
 
@@ -619,49 +587,97 @@
 		 ics2115_port[dev],
 		 ics2115_irq[dev]);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0) {
-		snd_card_free(card);
-		return err;
+	return snd_card_register(card);
+}	
+
+static int __init snd_wavefront_nonpnp_probe(struct platform_device *pdev)
+{
+	int dev = pdev->id;
+	struct snd_card *card;
+	int err;
+
+	if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
+		snd_printk("specify CS4232 port\n");
+		return -EINVAL;
+	}
+	if (ics2115_port[dev] == SNDRV_AUTO_PORT) {
+		snd_printk("specify ICS2115 port\n");
+		return -ENODEV;
 	}
 
-	if ((err = snd_card_register(card)) < 0) {
+	card = snd_wavefront_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+	snd_card_set_dev(card, &pdev->dev);
+	if ((err = snd_wavefront_probe(card, dev)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
-	if (pcard)
-		pnp_set_card_drvdata(pcard, card);
-	else
-		snd_wavefront_legacy[dev] = card;
+	
+	platform_set_drvdata(pdev, card);
 	return 0;
-}	
+}
+
+static int __devexit snd_wavefront_nonpnp_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#define WAVEFRONT_DRIVER	"snd_wavefront"
+
+static struct platform_driver snd_wavefront_driver = {
+	.probe		= snd_wavefront_nonpnp_probe,
+	.remove		= __devexit_p(snd_wavefront_nonpnp_remove),
+	/* FIXME: suspend, resume */
+	.driver		= {
+		.name	= WAVEFRONT_DRIVER
+	},
+};
+
 
 #ifdef CONFIG_PNP
 
-static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *card,
-                                              const struct pnp_card_device_id *id)
+static int __devinit snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
+                                              const struct pnp_card_device_id *pid)
 {
-        static int dev;
-        int res;
+	static int dev;
+	struct snd_card *card;
+	int res;
 
-        for ( ; dev < SNDRV_CARDS; dev++) {
-                if (!enable[dev] || !isapnp[dev])
-                        continue;
-                res = snd_wavefront_probe(dev, card, id);
-                if (res < 0)
-                        return res;
-                dev++;
-                return 0;
-        }
+	for ( ; dev < SNDRV_CARDS; dev++) {
+		if (enable[dev] && isapnp[dev])
+			break;
+	}
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
 
-        return -ENODEV;
+	card = snd_wavefront_card_new(dev);
+	if (! card)
+		return -ENOMEM;
+
+	if (snd_wavefront_pnp (dev, card->private_data, pcard, pid) < 0) {
+		if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
+			snd_printk (KERN_ERR "isapnp detection failed\n");
+			snd_card_free (card);
+			return -ENODEV;
+		}
+	}
+	snd_card_set_dev(card, &pcard->card->dev);
+
+	if ((res = snd_wavefront_probe(card, dev)) < 0)
+		return res;
+
+	pnp_set_card_drvdata(pcard, card);
+	dev++;
+	return 0;
 }
 
 static void __devexit snd_wavefront_pnp_remove(struct pnp_card_link * pcard)
 {
-	snd_card_t *card = (snd_card_t *) pnp_get_card_drvdata(pcard);
-
-	snd_card_disconnect(card);
-	snd_card_free_in_thread(card);
+	snd_card_free(pnp_get_card_drvdata(pcard));
+	pnp_set_card_drvdata(pcard, NULL);
 }
 
 static struct pnp_card_driver wavefront_pnpc_driver = {
@@ -670,48 +686,68 @@
 	.id_table	= snd_wavefront_pnpids,
 	.probe		= snd_wavefront_pnp_detect,
 	.remove		= __devexit_p(snd_wavefront_pnp_remove),
+	/* FIXME: suspend,resume */
 };
 
 #endif /* CONFIG_PNP */
 
+static void __init_or_module snd_wavefront_unregister_all(void)
+{
+	int i;
+
+	if (pnp_registered)
+		pnp_unregister_card_driver(&wavefront_pnpc_driver);
+	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)
+		platform_device_unregister(platform_devices[i]);
+	platform_driver_unregister(&snd_wavefront_driver);
+}
+
 static int __init alsa_card_wavefront_init(void)
 {
-	int cards = 0;
-	int dev;
-	for (dev = 0; dev < SNDRV_CARDS; dev++) {
-		if (!enable[dev])
-			continue;
+	int i, err, cards = 0;
+
+	if ((err = platform_driver_register(&snd_wavefront_driver)) < 0)
+		return err;
+
+	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {
+		struct platform_device *device;
 #ifdef CONFIG_PNP
-		if (isapnp[dev])
+		if (isapnp[i])
 			continue;
 #endif
-		if (snd_wavefront_probe(dev, NULL, NULL) >= 0)
-			cards++;
+		device = platform_device_register_simple(WAVEFRONT_DRIVER,
+							 i, NULL, 0);
+		if (IS_ERR(device)) {
+			err = PTR_ERR(device);
+			goto errout;
+		}
+		platform_devices[i] = device;
+		cards++;
 	}
-#ifdef CONFIG_PNP
-	cards += pnp_register_card_driver(&wavefront_pnpc_driver);
-#endif
+
+	i = pnp_register_card_driver(&wavefront_pnpc_driver);
+	if (i >= 0) {
+		pnp_registered = 1;
+		cards += i;
+	}
+
 	if (!cards) {
-#ifdef CONFIG_PNP
-		pnp_unregister_card_driver(&wavefront_pnpc_driver);
-#endif
 #ifdef MODULE
 		printk (KERN_ERR "No WaveFront cards found or devices busy\n");
 #endif
-		return -ENODEV;
+		err = -ENODEV;
+		goto errout;
 	}
 	return 0;
+
+ errout:
+	snd_wavefront_unregister_all();
+	return err;
 }
 
 static void __exit alsa_card_wavefront_exit(void)
 {
-	int idx;
-
-#ifdef CONFIG_PNP
-	pnp_unregister_card_driver(&wavefront_pnpc_driver);
-#endif
-	for (idx = 0; idx < SNDRV_CARDS; idx++)
-		snd_card_free(snd_wavefront_legacy[idx]);
+	snd_wavefront_unregister_all();
 }
 
 module_init(alsa_card_wavefront_init)
diff --git a/sound/isa/wavefront/wavefront_fx.c b/sound/isa/wavefront/wavefront_fx.c
index 3237968..180661c 100644
--- a/sound/isa/wavefront/wavefront_fx.c
+++ b/sound/isa/wavefront/wavefront_fx.c
@@ -460,7 +460,7 @@
 }
 
 int
-snd_wavefront_fx_open (snd_hwdep_t *hw, struct file *file)
+snd_wavefront_fx_open (struct snd_hwdep *hw, struct file *file)
 
 {
 	if (!try_module_get(hw->card->module))
@@ -470,7 +470,7 @@
 }
 
 int 
-snd_wavefront_fx_release (snd_hwdep_t *hw, struct file *file)
+snd_wavefront_fx_release (struct snd_hwdep *hw, struct file *file)
 
 {
 	module_put(hw->card->module);
@@ -478,11 +478,11 @@
 }
 
 int
-snd_wavefront_fx_ioctl (snd_hwdep_t *sdev, struct file *file,
+snd_wavefront_fx_ioctl (struct snd_hwdep *sdev, struct file *file,
 			unsigned int cmd, unsigned long arg)
 
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	snd_wavefront_card_t *acard;
 	snd_wavefront_t *dev;
 	wavefront_fx_info r;
diff --git a/sound/isa/wavefront/wavefront_midi.c b/sound/isa/wavefront/wavefront_midi.c
index 6f51d64..15888ba 100644
--- a/sound/isa/wavefront/wavefront_midi.c
+++ b/sound/isa/wavefront/wavefront_midi.c
@@ -91,10 +91,10 @@
 }
 
 static snd_wavefront_midi_t *
-get_wavefront_midi (snd_rawmidi_substream_t *substream)
+get_wavefront_midi (struct snd_rawmidi_substream *substream)
 
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	snd_wavefront_card_t *acard;
 
 	if (substream == NULL || substream->rmidi == NULL) 
@@ -230,7 +230,7 @@
 	}
 }
 
-static int snd_wavefront_midi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_wavefront_midi_input_open(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
 	snd_wavefront_midi_t *midi;
@@ -252,7 +252,7 @@
 	return 0;
 }
 
-static int snd_wavefront_midi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_wavefront_midi_output_open(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
 	snd_wavefront_midi_t *midi;
@@ -274,7 +274,7 @@
 	return 0;
 }
 
-static int snd_wavefront_midi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_wavefront_midi_input_close(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
 	snd_wavefront_midi_t *midi;
@@ -295,7 +295,7 @@
 	return 0;
 }
 
-static int snd_wavefront_midi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_wavefront_midi_output_close(struct snd_rawmidi_substream *substream)
 {
 	unsigned long flags;
 	snd_wavefront_midi_t *midi;
@@ -315,7 +315,7 @@
 	return 0;
 }
 
-static void snd_wavefront_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_wavefront_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
 	snd_wavefront_midi_t *midi;
@@ -355,7 +355,7 @@
 	snd_wavefront_midi_output_write(card);
 }
 
-static void snd_wavefront_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_wavefront_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
 	snd_wavefront_midi_t *midi;
@@ -401,7 +401,7 @@
 {
 	unsigned long flags;
 	snd_wavefront_midi_t *midi;
-	static snd_rawmidi_substream_t *substream = NULL;
+	static struct snd_rawmidi_substream *substream = NULL;
 	static int mpu = external_mpu; 
 	int max = 128;
 	unsigned char byte;
@@ -554,14 +554,14 @@
 	return 0;
 }
 
-snd_rawmidi_ops_t snd_wavefront_midi_output =
+struct snd_rawmidi_ops snd_wavefront_midi_output =
 {
 	.open =		snd_wavefront_midi_output_open,
 	.close =	snd_wavefront_midi_output_close,
 	.trigger =	snd_wavefront_midi_output_trigger,
 };
 
-snd_rawmidi_ops_t snd_wavefront_midi_input =
+struct snd_rawmidi_ops snd_wavefront_midi_input =
 {
 	.open =		snd_wavefront_midi_input_open,
 	.close =	snd_wavefront_midi_input_close,
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index abd79b7..ed81eec 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -115,18 +115,11 @@
 
 #ifdef WF_DEBUG
 
-#if defined(NEW_MACRO_VARARGS) || __GNUC__ >= 3
 #define DPRINT(cond, ...) \
        if ((dev->debug & (cond)) == (cond)) { \
 	     snd_printk (__VA_ARGS__); \
        }
 #else
-#define DPRINT(cond, args...) \
-       if ((dev->debug & (cond)) == (cond)) { \
-	     snd_printk (args); \
-       }
-#endif
-#else
 #define DPRINT(cond, args...)
 #endif /* WF_DEBUG */
 
@@ -144,13 +137,13 @@
 static int wavefront_delete_sample (snd_wavefront_t *, int sampnum);
 static int wavefront_find_free_sample (snd_wavefront_t *);
 
-typedef struct {
+struct wavefront_command {
 	int cmd;
 	char *action;
 	unsigned int read_cnt;
 	unsigned int write_cnt;
 	int need_ack;
-} wavefront_command;
+};
 
 static struct {
 	int errno;
@@ -170,7 +163,7 @@
 
 #define NEEDS_ACK 1
 
-static wavefront_command wavefront_commands[] = {
+static struct 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 },
@@ -249,7 +242,7 @@
 	return "Unknown WaveFront error";
 }
 
-static wavefront_command *
+static struct wavefront_command *
 wavefront_get_command (int cmd) 
 
 {
@@ -261,7 +254,7 @@
 		}
 	}
 
-	return (wavefront_command *) 0;
+	return NULL;
 }
 
 static inline int
@@ -345,9 +338,9 @@
 	int ack;
 	unsigned int i;
 	int c;
-	wavefront_command *wfcmd;
+	struct wavefront_command *wfcmd;
 
-	if ((wfcmd = wavefront_get_command (cmd)) == (wavefront_command *) 0) {
+	if ((wfcmd = wavefront_get_command (cmd)) == NULL) {
 		snd_printk ("command 0x%x not supported.\n",
 			cmd);
 		return 1;
@@ -1625,7 +1618,7 @@
 }
 
 int 
-snd_wavefront_synth_open (snd_hwdep_t *hw, struct file *file)
+snd_wavefront_synth_open (struct snd_hwdep *hw, struct file *file)
 
 {
 	if (!try_module_get(hw->card->module))
@@ -1635,7 +1628,7 @@
 }
 
 int 
-snd_wavefront_synth_release (snd_hwdep_t *hw, struct file *file)
+snd_wavefront_synth_release (struct snd_hwdep *hw, struct file *file)
 
 {
 	module_put(hw->card->module);
@@ -1643,18 +1636,18 @@
 }
 
 int
-snd_wavefront_synth_ioctl (snd_hwdep_t *hw, struct file *file,
+snd_wavefront_synth_ioctl (struct snd_hwdep *hw, struct file *file,
 			   unsigned int cmd, unsigned long arg)
 
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	snd_wavefront_t *dev;
 	snd_wavefront_card_t *acard;
 	wavefront_control *wc;
 	void __user *argp = (void __user *)arg;
 	int err;
 
-	card = (snd_card_t *) hw->card;
+	card = (struct snd_card *) hw->card;
 
 	snd_assert(card != NULL, return -ENODEV);
 
diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig
index 2433b77..531f8ba 100644
--- a/sound/mips/Kconfig
+++ b/sound/mips/Kconfig
@@ -8,7 +8,6 @@
 	depends on (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && SND
 	select SND_PCM
 	select SND_AC97_CODEC
-	select SND_GENERIC_DRIVER
 	help
 	  ALSA Sound driver for the Au1x00's AC97 port.
 
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index d08a42b..6d8f8b3e 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -50,12 +50,7 @@
 MODULE_AUTHOR("Charles Eidsness <charles@cooper-street.com>");
 MODULE_DESCRIPTION("Au1000 AC'97 ALSA Driver");
 MODULE_LICENSE("GPL");
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 MODULE_SUPPORTED_DEVICE("{{AMD,Au1000 AC'97}}");
-#else
-MODULE_CLASSES("{sound}");
-MODULE_DEVICES("{{AMD,Au1000 AC'97}}");
-#endif
 
 #define PLAYBACK 0
 #define CAPTURE 1
@@ -68,18 +63,14 @@
 #define READ_WAIT 2
 #define RW_DONE 3
 
-DECLARE_WAIT_QUEUE_HEAD(ac97_command_wq);
-
-typedef struct au1000_period au1000_period_t;
 struct au1000_period
 {
 	u32 start;
 	u32 relative_end;	/*realtive to start of buffer*/
-	au1000_period_t * next;
+	struct au1000_period * next;
 };
 
 /*Au1000 AC97 Port Control Reisters*/
-typedef struct au1000_ac97_reg au1000_ac97_reg_t;
 struct au1000_ac97_reg {
 	u32 volatile config;
 	u32 volatile status;
@@ -88,32 +79,30 @@
 	u32 volatile cntrl;
 };
 
-typedef struct audio_stream audio_stream_t;
 struct audio_stream {
-	snd_pcm_substream_t * substream;
+	struct snd_pcm_substream *substream;
 	int dma;
 	spinlock_t dma_lock;
-	au1000_period_t * buffer;
-	unsigned long period_size;
+	struct au1000_period * buffer;
+	unsigned int period_size;
+	unsigned int periods;
 };
 
-typedef struct snd_card_au1000 {
-	snd_card_t *card;
-	au1000_ac97_reg_t volatile *ac97_ioport;
+struct snd_au1000 {
+	struct snd_card *card;
+	struct au1000_ac97_reg volatile *ac97_ioport;
 
 	struct resource *ac97_res_port;
 	spinlock_t ac97_lock;
-	ac97_t *ac97;
+	struct snd_ac97 *ac97;
 
-	snd_pcm_t *pcm;
-	audio_stream_t *stream[2];	/* playback & capture */
-} au1000_t;
-
-static au1000_t *au1000 = NULL;
+	struct snd_pcm *pcm;
+	struct audio_stream *stream[2];	/* playback & capture */
+};
 
 /*--------------------------- Local Functions --------------------------------*/
 static void
-au1000_set_ac97_xmit_slots(long xmit_slots)
+au1000_set_ac97_xmit_slots(struct snd_au1000 *au1000, long xmit_slots)
 {
 	u32 volatile ac97_config;
 
@@ -126,7 +115,7 @@
 }
 
 static void
-au1000_set_ac97_recv_slots(long recv_slots)
+au1000_set_ac97_recv_slots(struct snd_au1000 *au1000, long recv_slots)
 {
 	u32 volatile ac97_config;
 
@@ -140,86 +129,99 @@
 
 
 static void
-au1000_dma_stop(audio_stream_t *stream)
+au1000_release_dma_link(struct audio_stream *stream)
 {
-	unsigned long   flags;
-	au1000_period_t * pointer;
-	au1000_period_t * pointer_next;
+	struct au1000_period * pointer;
+	struct au1000_period * pointer_next;
 
-	if (stream->buffer != NULL) {
-		spin_lock_irqsave(&stream->dma_lock, flags);
-		disable_dma(stream->dma);
-		spin_unlock_irqrestore(&stream->dma_lock, flags);
+	stream->period_size = 0;
+	stream->periods = 0;
+	pointer = stream->buffer;
+	if (! pointer)
+		return;
+	do {
+		pointer_next = pointer->next;
+		kfree(pointer);
+		pointer = pointer_next;
+	} while (pointer != stream->buffer);
+	stream->buffer = NULL;
+}
 
-		pointer = stream->buffer;
-		pointer_next = stream->buffer->next;
+static int
+au1000_setup_dma_link(struct audio_stream *stream, unsigned int period_bytes,
+		      unsigned int periods)
+{
+	struct snd_pcm_substream *substream = stream->substream;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	unsigned long dma_start;
+	int i;
 
-		do {
-			kfree(pointer);
-			pointer = pointer_next;
-			pointer_next = pointer->next;
-		} while (pointer != stream->buffer);
+	dma_start = virt_to_phys(runtime->dma_area);
 
-		stream->buffer = NULL;
+	if (stream->period_size == period_bytes &&
+	    stream->periods == periods)
+		return 0; /* not changed */
+
+	au1000_release_dma_link(stream);
+
+	stream->period_size = period_bytes;
+	stream->periods = periods;
+
+	stream->buffer = kmalloc(sizeof(struct au1000_period), GFP_KERNEL);
+	if (! stream->buffer)
+		return -ENOMEM;
+	pointer = stream->buffer;
+	for (i = 0; i < periods; i++) {
+		pointer->start = (u32)(dma_start + (i * period_bytes));
+		pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1);
+		if (i < periods - 1) {
+			pointer->next = kmalloc(sizeof(struct au1000_period), GFP_KERNEL);
+			if (! pointer->next) {
+				au1000_release_dma_link(stream);
+				return -ENOMEM;
+			}
+			pointer = pointer->next;
+		}
 	}
+	pointer->next = stream->buffer;
+	return 0;
 }
 
 static void
-au1000_dma_start(audio_stream_t *stream)
+au1000_dma_stop(struct audio_stream *stream)
 {
-	snd_pcm_substream_t *substream = stream->substream;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	snd_assert(stream->buffer, return);
+	disable_dma(stream->dma);
+}
 
-	unsigned long flags, dma_start;
-	int i;
-	au1000_period_t * pointer;
+static void
+au1000_dma_start(struct audio_stream *stream)
+{
+	snd_assert(stream->buffer, return);
 
-	if (stream->buffer == NULL) {
-		dma_start = virt_to_phys(runtime->dma_area);
-
-		stream->period_size = frames_to_bytes(runtime,
-			runtime->period_size);
-		stream->buffer = kmalloc(sizeof(au1000_period_t), GFP_KERNEL);
-		pointer = stream->buffer;
-		for (i = 0 ; i < runtime->periods ; i++) {
-			pointer->start = (u32)(dma_start +
-				(i * stream->period_size));
-			pointer->relative_end = (u32)
-				(((i+1) * stream->period_size) - 0x1);
-			if ( i < runtime->periods - 1) {
-				pointer->next = kmalloc(sizeof(au1000_period_t)
-					, GFP_KERNEL);
-				pointer = pointer->next;
-			}
-		}
-		pointer->next = stream->buffer;
-
-		spin_lock_irqsave(&stream->dma_lock, flags);
-		init_dma(stream->dma);
-		if (get_dma_active_buffer(stream->dma) == 0) {
-			clear_dma_done0(stream->dma);
-			set_dma_addr0(stream->dma, stream->buffer->start);
-			set_dma_count0(stream->dma, stream->period_size >> 1);
-			set_dma_addr1(stream->dma, stream->buffer->next->start);
-			set_dma_count1(stream->dma, stream->period_size >> 1);
-		} else {
-			clear_dma_done1(stream->dma);
-			set_dma_addr1(stream->dma, stream->buffer->start);
-			set_dma_count1(stream->dma, stream->period_size >> 1);
-			set_dma_addr0(stream->dma, stream->buffer->next->start);
-			set_dma_count0(stream->dma, stream->period_size >> 1);
-		}
-		enable_dma_buffers(stream->dma);
-		start_dma(stream->dma);
-		spin_unlock_irqrestore(&stream->dma_lock, flags);
+	init_dma(stream->dma);
+	if (get_dma_active_buffer(stream->dma) == 0) {
+		clear_dma_done0(stream->dma);
+		set_dma_addr0(stream->dma, stream->buffer->start);
+		set_dma_count0(stream->dma, stream->period_size >> 1);
+		set_dma_addr1(stream->dma, stream->buffer->next->start);
+		set_dma_count1(stream->dma, stream->period_size >> 1);
+	} else {
+		clear_dma_done1(stream->dma);
+		set_dma_addr1(stream->dma, stream->buffer->start);
+		set_dma_count1(stream->dma, stream->period_size >> 1);
+		set_dma_addr0(stream->dma, stream->buffer->next->start);
+		set_dma_count0(stream->dma, stream->period_size >> 1);
 	}
+	enable_dma_buffers(stream->dma);
+	start_dma(stream->dma);
 }
 
 static irqreturn_t
 au1000_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	audio_stream_t *stream = (audio_stream_t *) dev_id;
-	snd_pcm_substream_t *substream = stream->substream;
+	struct audio_stream *stream = (struct audio_stream *) dev_id;
+	struct snd_pcm_substream *substream = stream->substream;
 
 	spin_lock(&stream->dma_lock);
 	switch (get_dma_buffer_done(stream->dma)) {
@@ -238,11 +240,9 @@
 		enable_dma_buffer1(stream->dma);
 		break;
 	case (DMA_D0 | DMA_D1):
-		spin_unlock(&stream->dma_lock);
 		printk(KERN_ERR "DMA %d missed interrupt.\n",stream->dma);
 		au1000_dma_stop(stream);
 		au1000_dma_start(stream);
-		spin_lock(&stream->dma_lock);
 		break;
 	case (~DMA_D0 & ~DMA_D1):
 		printk(KERN_ERR "DMA %d empty irq.\n",stream->dma);
@@ -255,13 +255,13 @@
 /*-------------------------- PCM Audio Streams -------------------------------*/
 
 static unsigned int rates[] = {8000, 11025, 16000, 22050};
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 	.count	=  sizeof(rates) / sizeof(rates[0]),
 	.list	= rates,
 	.mask	= 0,
 };
 
-static snd_pcm_hardware_t snd_au1000 =
+static struct snd_pcm_hardware snd_au1000_hw =
 {
 	.info			= (SNDRV_PCM_INFO_INTERLEAVED | \
 				SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
@@ -281,88 +281,108 @@
 };
 
 static int
-snd_au1000_playback_open(snd_pcm_substream_t * substream)
+snd_au1000_playback_open(struct snd_pcm_substream *substream)
 {
+	struct snd_au1000 *au1000 = substream->pcm->private_data;
+
 	au1000->stream[PLAYBACK]->substream = substream;
 	au1000->stream[PLAYBACK]->buffer = NULL;
 	substream->private_data = au1000->stream[PLAYBACK];
-	substream->runtime->hw = snd_au1000;
+	substream->runtime->hw = snd_au1000_hw;
 	return (snd_pcm_hw_constraint_list(substream->runtime, 0,
 		SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
 }
 
 static int
-snd_au1000_capture_open(snd_pcm_substream_t * substream)
+snd_au1000_capture_open(struct snd_pcm_substream *substream)
 {
+	struct snd_au1000 *au1000 = substream->pcm->private_data;
+
 	au1000->stream[CAPTURE]->substream = substream;
 	au1000->stream[CAPTURE]->buffer = NULL;
 	substream->private_data = au1000->stream[CAPTURE];
-	substream->runtime->hw = snd_au1000;
+	substream->runtime->hw = snd_au1000_hw;
 	return (snd_pcm_hw_constraint_list(substream->runtime, 0,
 		SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates) < 0);
-
 }
 
 static int
-snd_au1000_playback_close(snd_pcm_substream_t * substream)
+snd_au1000_playback_close(struct snd_pcm_substream *substream)
 {
+	struct snd_au1000 *au1000 = substream->pcm->private_data;
+
 	au1000->stream[PLAYBACK]->substream = NULL;
 	return 0;
 }
 
 static int
-snd_au1000_capture_close(snd_pcm_substream_t * substream)
+snd_au1000_capture_close(struct snd_pcm_substream *substream)
 {
+	struct snd_au1000 *au1000 = substream->pcm->private_data;
+
 	au1000->stream[CAPTURE]->substream = NULL;
 	return 0;
 }
 
 static int
-snd_au1000_hw_params(snd_pcm_substream_t * substream,
-					snd_pcm_hw_params_t * hw_params)
+snd_au1000_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
-	return snd_pcm_lib_malloc_pages(substream,
-					params_buffer_bytes(hw_params));
+	struct audio_stream *stream = substream->private_data;
+	int err;
+
+	err = snd_pcm_lib_malloc_pages(substream,
+				       params_buffer_bytes(hw_params));
+	if (err < 0)
+		return err;
+	return au1000_setup_dma_link(stream,
+				     params_period_bytes(hw_params),
+				     params_periods(hw_params));
 }
 
 static int
-snd_au1000_hw_free(snd_pcm_substream_t * substream)
+snd_au1000_hw_free(struct snd_pcm_substream *substream)
 {
+	struct audio_stream *stream = substream->private_data;
+	au1000_release_dma_link(stream);
 	return snd_pcm_lib_free_pages(substream);
 }
 
 static int
-snd_au1000_playback_prepare(snd_pcm_substream_t * substream)
+snd_au1000_playback_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_au1000 *au1000 = substream->pcm->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
-	if (runtime->channels == 1 )
-		au1000_set_ac97_xmit_slots(AC97_SLOT_4);
+	if (runtime->channels == 1)
+		au1000_set_ac97_xmit_slots(au1000, AC97_SLOT_4);
 	else
-		au1000_set_ac97_xmit_slots(AC97_SLOT_3 | AC97_SLOT_4);
+		au1000_set_ac97_xmit_slots(au1000, AC97_SLOT_3 | AC97_SLOT_4);
 	snd_ac97_set_rate(au1000->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
 	return 0;
 }
 
 static int
-snd_au1000_capture_prepare(snd_pcm_substream_t * substream)
+snd_au1000_capture_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_au1000 *au1000 = substream->pcm->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
-	if (runtime->channels == 1 )
-		au1000_set_ac97_recv_slots(AC97_SLOT_4);
+	if (runtime->channels == 1)
+		au1000_set_ac97_recv_slots(au1000, AC97_SLOT_4);
 	else
-		au1000_set_ac97_recv_slots(AC97_SLOT_3 | AC97_SLOT_4);
+		au1000_set_ac97_recv_slots(au1000, AC97_SLOT_3 | AC97_SLOT_4);
 	snd_ac97_set_rate(au1000->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
 	return 0;
 }
 
 static int
-snd_au1000_trigger(snd_pcm_substream_t * substream, int cmd)
+snd_au1000_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	audio_stream_t *stream = substream->private_data;
+	struct audio_stream *stream = substream->private_data;
 	int err = 0;
 
+	spin_lock(&stream->dma_lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		au1000_dma_start(stream);
@@ -374,27 +394,27 @@
 		err = -EINVAL;
 		break;
 	}
+	spin_unlock(&stream->dma_lock);
 	return err;
 }
 
 static snd_pcm_uframes_t
-snd_au1000_pointer(snd_pcm_substream_t * substream)
+snd_au1000_pointer(struct snd_pcm_substream *substream)
 {
-	audio_stream_t *stream = substream->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	unsigned long flags;
+	struct audio_stream *stream = substream->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	long location;
 
-	spin_lock_irqsave(&stream->dma_lock, flags);
+	spin_lock(&stream->dma_lock);
 	location = get_dma_residue(stream->dma);
-	spin_unlock_irqrestore(&stream->dma_lock, flags);
+	spin_unlock(&stream->dma_lock);
 	location = stream->buffer->relative_end - location;
 	if (location == -1)
 		location = 0;
 	return bytes_to_frames(runtime,location);
 }
 
-static snd_pcm_ops_t snd_card_au1000_playback_ops = {
+static struct snd_pcm_ops snd_card_au1000_playback_ops = {
 	.open			= snd_au1000_playback_open,
 	.close			= snd_au1000_playback_close,
 	.ioctl			= snd_pcm_lib_ioctl,
@@ -405,7 +425,7 @@
 	.pointer		= snd_au1000_pointer,
 };
 
-static snd_pcm_ops_t snd_card_au1000_capture_ops = {
+static struct snd_pcm_ops snd_card_au1000_capture_ops = {
 	.open			= snd_au1000_capture_open,
 	.close			= snd_au1000_capture_close,
 	.ioctl			= snd_pcm_lib_ioctl,
@@ -417,9 +437,9 @@
 };
 
 static int __devinit
-snd_au1000_pcm_new(void)
+snd_au1000_pcm_new(struct snd_au1000 *au1000)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 	unsigned long flags;
 
@@ -438,6 +458,9 @@
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "Au1000 AC97 PCM");
 
+	spin_lock_init(&au1000->stream[PLAYBACK]->dma_lock);
+	spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
+
 	flags = claim_dma_lock();
 	if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX,
 			"AC97 TX", au1000_dma_interrupt, SA_INTERRUPT,
@@ -457,8 +480,6 @@
 	set_dma_mode(au1000->stream[CAPTURE]->dma,
 		     get_dma_mode(au1000->stream[CAPTURE]->dma) & ~DMA_NC);
 	release_dma_lock(flags);
-	spin_lock_init(&au1000->stream[PLAYBACK]->dma_lock);
-	spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
 	au1000->pcm = pcm;
 	return 0;
 }
@@ -467,11 +488,13 @@
 /*-------------------------- AC97 CODEC Control ------------------------------*/
 
 static unsigned short
-snd_au1000_ac97_read(ac97_t *ac97, unsigned short reg)
+snd_au1000_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
+	struct snd_au1000 *au1000 = ac97->private_data;
 	u32 volatile cmd;
 	u16 volatile data;
 	int             i;
+
 	spin_lock(&au1000->ac97_lock);
 /* would rather use the interupt than this polling but it works and I can't
 get the interupt driven case to work efficiently */
@@ -503,10 +526,12 @@
 
 
 static void
-snd_au1000_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+snd_au1000_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
+	struct snd_au1000 *au1000 = ac97->private_data;
 	u32 cmd;
 	int i;
+
 	spin_lock(&au1000->ac97_lock);
 /* would rather use the interupt than this polling but it works and I can't
 get the interupt driven case to work efficiently */
@@ -522,40 +547,27 @@
 	au1000->ac97_ioport->cmd = cmd;
 	spin_unlock(&au1000->ac97_lock);
 }
-static void
-snd_au1000_ac97_free(ac97_t *ac97)
-{
-	au1000->ac97 = NULL;
-}
 
 static int __devinit
-snd_au1000_ac97_new(void)
+snd_au1000_ac97_new(struct snd_au1000 *au1000)
 {
 	int err;
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
- 	static ac97_bus_ops_t ops = {
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
+ 	static struct snd_ac97_bus_ops ops = {
 		.write = snd_au1000_ac97_write,
 		.read = snd_au1000_ac97_read,
 	};
-#else
-	ac97_bus_t bus, *pbus;
-	ac97_t ac97;
-#endif
 
 	if ((au1000->ac97_res_port = request_region(AC97C_CONFIG,
-	       		sizeof(au1000_ac97_reg_t), "Au1x00 AC97")) == NULL) {
+	       		sizeof(struct au1000_ac97_reg), "Au1x00 AC97")) == NULL) {
 		snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n");
 		return -EBUSY;
 	}
-	au1000->ac97_ioport = (au1000_ac97_reg_t *) au1000->ac97_res_port->start;
+	au1000->ac97_ioport = (struct au1000_ac97_reg *) au1000->ac97_res_port->start;
 
 	spin_lock_init(&au1000->ac97_lock);
 
-	spin_lock(&au1000->ac97_lock);
-
 	/* configure pins for AC'97
 	TODO: move to board_setup.c */
 	au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
@@ -572,33 +584,24 @@
 	au1000->ac97_ioport->config = 0x0;
 	mdelay(5);
 
-	spin_unlock(&au1000->ac97_lock);
-
 	/* Initialise AC97 middle-layer */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
 	if ((err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus)) < 0)
  		return err;
-#else
-	memset(&bus, 0, sizeof(bus));
-	bus.write = snd_au1000_ac97_write;
-	bus.read = snd_au1000_ac97_read;
-	if ((err = snd_ac97_bus(au1000->card, &bus, &pbus)) < 0)
-		return err;
-#endif
+
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = au1000;
-	ac97.private_free = snd_au1000_ac97_free;
 	if ((err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97)) < 0)
 		return err;
-	return 0;
 
+	return 0;
 }
 
 /*------------------------------ Setup / Destroy ----------------------------*/
 
 void
-snd_au1000_free(snd_card_t *card)
+snd_au1000_free(struct snd_card *card)
 {
+	struct snd_au1000 *au1000 = card->private_data;
 
 	if (au1000->ac97_res_port) {
 		/* put internal AC97 block into reset */
@@ -614,73 +617,65 @@
 		free_au1000_dma(au1000->stream[CAPTURE]->dma);
 
 	kfree(au1000->stream[PLAYBACK]);
-	au1000->stream[PLAYBACK] = NULL;
 	kfree(au1000->stream[CAPTURE]);
-	au1000->stream[CAPTURE] = NULL;
-	kfree(au1000);
-	au1000 = NULL;
-
 }
 
+
+static struct snd_card *au1000_card;
+
 static int __init
 au1000_init(void)
 {
 	int err;
+	struct snd_card *card;
+	struct snd_au1000 *au1000;
 
-	au1000 = kmalloc(sizeof(au1000_t), GFP_KERNEL);
-	if (au1000 == NULL)
+	card = snd_card_new(-1, "AC97", THIS_MODULE, sizeof(struct snd_au1000));
+	if (card == NULL)
 		return -ENOMEM;
-	au1000->stream[PLAYBACK] = kmalloc(sizeof(audio_stream_t), GFP_KERNEL);
-	if (au1000->stream[PLAYBACK] == NULL)
-		return -ENOMEM;
-	au1000->stream[CAPTURE] = kmalloc(sizeof(audio_stream_t), GFP_KERNEL);
-	if (au1000->stream[CAPTURE] == NULL)
-		return -ENOMEM;
+
+	card->private_free = snd_au1000_free;
+	au1000 = card->private_data;
 	/* so that snd_au1000_free will work as intended */
+	au1000->card = card;
 	au1000->stream[PLAYBACK]->dma = -1;
 	au1000->stream[CAPTURE]->dma = -1;
  	au1000->ac97_res_port = NULL;
-
-	au1000->card = snd_card_new(-1, "AC97", THIS_MODULE, sizeof(au1000_t));
-	if (au1000->card == NULL) {
-		snd_au1000_free(au1000->card);
+	au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
+	au1000->stream[CAPTURE] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
+	if (au1000->stream[PLAYBACK] == NULL ||
+	    au1000->stream[CAPTURE] == NULL) {
+		snd_card_free(card);
 		return -ENOMEM;
 	}
 
-	au1000->card->private_data = (au1000_t *)au1000;
-	au1000->card->private_free = snd_au1000_free;
-
-	if ((err = snd_au1000_ac97_new()) < 0 ) {
-		snd_card_free(au1000->card);
+	if ((err = snd_au1000_ac97_new(au1000)) < 0 ) {
+		snd_card_free(card);
 		return err;
 	}
 
-	if ((err = snd_au1000_pcm_new()) < 0) {
-		snd_card_free(au1000->card);
+	if ((err = snd_au1000_pcm_new(au1000)) < 0) {
+		snd_card_free(card);
 		return err;
 	}
 
-	strcpy(au1000->card->driver, "AMD-Au1000-AC97");
-	strcpy(au1000->card->shortname, "Au1000-AC97");
-	sprintf(au1000->card->longname, "AMD Au1000--AC97 ALSA Driver");
+	strcpy(card->driver, "Au1000-AC97");
+	strcpy(card->shortname, "AMD Au1000-AC97");
+	sprintf(card->longname, "AMD Au1000--AC97 ALSA Driver");
 
-	if ((err = snd_card_set_generic_dev(au1000->card)) < 0) {
-		snd_card_free(au1000->card);
-		return err;
-	}
-
-	if ((err = snd_card_register(au1000->card)) < 0) {
-		snd_card_free(au1000->card);
+	if ((err = snd_card_register(card)) < 0) {
+		snd_card_free(card);
 		return err;
 	}
 
 	printk( KERN_INFO "ALSA AC97: Driver Initialized\n" );
+	au1000_card = card;
 	return 0;
 }
 
 static void __exit au1000_exit(void)
 {
-	snd_card_free(au1000->card);
+	snd_card_free(au1000_card);
 }
 
 module_init(au1000_init);
diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c
index 3f30c57..49796be 100644
--- a/sound/oss/ad1848.c
+++ b/sound/oss/ad1848.c
@@ -46,8 +46,6 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/stddef.h>
-#include <linux/pm.h>
-#include <linux/pm_legacy.h>
 #include <linux/isapnp.h>
 #include <linux/pnp.h>
 #include <linux/spinlock.h>
@@ -105,9 +103,6 @@
 	int             irq_ok;
 	mixer_ents     *mix_devices;
 	int             mixer_output_port;
-
-	/* Power management */
-	struct		pm_dev *pmdev;
 } ad1848_info;
 
 typedef struct ad1848_port_info
@@ -201,7 +196,6 @@
 static void     ad1848_halt_input(int dev);
 static void     ad1848_halt_output(int dev);
 static void     ad1848_trigger(int dev, int bits);
-static int	ad1848_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data);
 
 #ifndef EXCLUDE_TIMERS
 static int ad1848_tmr_install(int dev);
@@ -2027,10 +2021,6 @@
 
 	nr_ad1848_devs++;
 
-	devc->pmdev = pm_register(PM_ISA_DEV, my_dev, ad1848_pm_callback);
-	if (devc->pmdev)
-		devc->pmdev->data = devc;
-
 	ad1848_init_hw(devc);
 
 	if (irq > 0)
@@ -2197,9 +2187,6 @@
 		if(mixer>=0)
 			sound_unload_mixerdev(mixer);
 
-		if (devc->pmdev)
-			pm_unregister(devc->pmdev);
-
 		nr_ad1848_devs--;
 		for ( ; i < nr_ad1848_devs ; i++)
 			adev_info[i] = adev_info[i+1];
@@ -2811,85 +2798,6 @@
 }
 #endif /* EXCLUDE_TIMERS */
 
-static int ad1848_suspend(ad1848_info *devc)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&devc->lock,flags);
-
-	ad_mute(devc);
-	
-	spin_unlock_irqrestore(&devc->lock,flags);
-	return 0;
-}
-
-static int ad1848_resume(ad1848_info *devc)
-{
-	int mixer_levels[32], i;
-
-	/* Thinkpad is a bit more of PITA than normal. The BIOS tends to
-	   restore it in a different config to the one we use.  Need to
-	   fix this somehow */
-
-	/* store old mixer levels */
-	memcpy(mixer_levels, devc->levels, sizeof (mixer_levels));  
-	ad1848_init_hw(devc);
-
-	/* restore mixer levels */
-	for (i = 0; i < 32; i++)
-		ad1848_mixer_set(devc, devc->dev_no, mixer_levels[i]);
-
-	if (!devc->subtype) {
-		static signed char interrupt_bits[12] = { -1, -1, -1, -1, -1, 0x00, -1, 0x08, -1, 0x10, 0x18, 0x20 };
-		static char dma_bits[4] = { 1, 2, 0, 3 };
-		unsigned long flags;
-		signed char bits;
-		char dma2_bit = 0;
-
-		int config_port = devc->base + 0;
-
-		bits = interrupt_bits[devc->irq];
-		if (bits == -1) {
-			printk(KERN_ERR "MSS: Bad IRQ %d\n", devc->irq);
-			return -1;
-		}
-
-		spin_lock_irqsave(&devc->lock,flags);
-	
-		outb((bits | 0x40), config_port); 
-
-		if (devc->dma2 != -1 && devc->dma2 != devc->dma1)
-			if ( (devc->dma1 == 0 && devc->dma2 == 1) ||
-			     (devc->dma1 == 1 && devc->dma2 == 0) ||
-			     (devc->dma1 == 3 && devc->dma2 == 0))
-				dma2_bit = 0x04;
-
-		outb((bits | dma_bits[devc->dma1] | dma2_bit), config_port);
-		spin_unlock_irqrestore(&devc->lock,flags);
-	}
-
-	return 0;
-}
-
-static int ad1848_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) 
-{
-	ad1848_info *devc = dev->data;
-	if (devc) {
-		DEB(printk("ad1848: pm event received: 0x%x\n", rqst));
-
-		switch (rqst) {
-		case PM_SUSPEND:
-			ad1848_suspend(devc);
-			break;
-		case PM_RESUME:
-			ad1848_resume(devc);
-			break;
-		}
-	}
-	return 0;
-}
-
-
 EXPORT_SYMBOL(ad1848_detect);
 EXPORT_SYMBOL(ad1848_init);
 EXPORT_SYMBOL(ad1848_unload);
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index 6b46a8a..b963c55 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -578,17 +578,15 @@
 	} while ((stat & PSC_AC97STAT_DR) == 0);
 }
 
+/* Hold spinlock for both start_dac() and start_adc() calls */
 static void
 start_dac(struct au1550_state *s)
 {
 	struct dmabuf  *db = &s->dma_dac;
-	unsigned long   flags;
 
 	if (!db->stopped)
 		return;
 
-	spin_lock_irqsave(&s->lock, flags);
-
 	set_xmit_slots(db->num_channels);
 	au_writel(PSC_AC97PCR_TC, PSC_AC97PCR);
 	au_sync();
@@ -598,8 +596,6 @@
 	au1xxx_dbdma_start(db->dmanr);
 
 	db->stopped = 0;
-
-	spin_unlock_irqrestore(&s->lock, flags);
 }
 
 static void
@@ -718,7 +714,6 @@
 }
 
 
-/* hold spinlock for the following */
 static void
 dac_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -726,6 +721,8 @@
 	struct dmabuf  *db = &s->dma_dac;
 	u32	ac97c_stat;
 
+	spin_lock(&s->lock);
+
 	ac97c_stat = au_readl(PSC_AC97STAT);
 	if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE))
 		pr_debug("AC97C status = 0x%08x\n", ac97c_stat);
@@ -747,6 +744,8 @@
 	/* wake up anybody listening */
 	if (waitqueue_active(&db->wait))
 		wake_up(&db->wait);
+
+	spin_unlock(&s->lock);
 }
 
 
@@ -758,6 +757,8 @@
 	u32	obytes;
 	char	*obuf;
 
+	spin_lock(&s->lock);
+
 	/* Pull the buffer from the dma queue.
 	*/
 	au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes);
@@ -765,6 +766,7 @@
 	if ((dp->count + obytes) > dp->dmasize) {
 		/* Overrun. Stop ADC and log the error
 		*/
+		spin_unlock(&s->lock);
 		stop_adc(s);
 		dp->error++;
 		err("adc overrun");
@@ -787,6 +789,7 @@
 	if (waitqueue_active(&dp->wait))
 		wake_up(&dp->wait);
 
+	spin_unlock(&s->lock);
 }
 
 static loff_t
@@ -1048,9 +1051,9 @@
 		/* wait for samples in ADC dma buffer
 		*/
 		do {
+			spin_lock_irqsave(&s->lock, flags);
 			if (db->stopped)
 				start_adc(s);
-			spin_lock_irqsave(&s->lock, flags);
 			avail = db->count;
 			if (avail <= 0)
 				__set_current_state(TASK_INTERRUPTIBLE);
@@ -1570,15 +1573,19 @@
 		if (get_user(val, (int *) arg))
 			return -EFAULT;
 		if (file->f_mode & FMODE_READ) {
-			if (val & PCM_ENABLE_INPUT)
+			if (val & PCM_ENABLE_INPUT) {
+				spin_lock_irqsave(&s->lock, flags);
 				start_adc(s);
-			else
+				spin_unlock_irqrestore(&s->lock, flags);
+			} else
 				stop_adc(s);
 		}
 		if (file->f_mode & FMODE_WRITE) {
-			if (val & PCM_ENABLE_OUTPUT)
+			if (val & PCM_ENABLE_OUTPUT) {
+				spin_lock_irqsave(&s->lock, flags);
 				start_dac(s);
-			else
+				spin_unlock_irqrestore(&s->lock, flags);
+			} else
 				stop_dac(s);
 		}
 		return 0;
diff --git a/sound/oss/cs4281/cs4281m.c b/sound/oss/cs4281/cs4281m.c
index adc6896..46dd41d 100644
--- a/sound/oss/cs4281/cs4281m.c
+++ b/sound/oss/cs4281/cs4281m.c
@@ -298,7 +298,6 @@
 	struct cs4281_pipeline pl[CS4281_NUMBER_OF_PIPELINES];
 };
 
-#include <linux/pm_legacy.h>
 #include "cs4281pm-24.c"
 
 #if CSDEBUG
@@ -4256,9 +4255,6 @@
 static int __devinit cs4281_probe(struct pci_dev *pcidev,
 				  const struct pci_device_id *pciid)
 {
-#ifndef NOT_CS4281_PM
-	struct pm_dev *pmdev;
-#endif
 	struct cs4281_state *s;
 	dma_addr_t dma_mask;
 	mm_segment_t fs;
@@ -4374,19 +4370,7 @@
 	}
 #ifndef NOT_CS4281_PM
 	cs4281_InitPM(s);
-	pmdev = cs_pm_register(PM_PCI_DEV, PM_PCI_ID(pcidev), cs4281_pm_callback);
-	if (pmdev)
-	{
-		CS_DBGOUT(CS_INIT | CS_PM, 4, printk(KERN_INFO
-			 "cs4281: probe() pm_register() succeeded (%p).\n", pmdev));
-		pmdev->data = s;
-	}
-	else
-	{
-		CS_DBGOUT(CS_INIT | CS_PM | CS_ERROR, 0, printk(KERN_INFO
-			 "cs4281: probe() pm_register() failed (%p).\n", pmdev));
-		s->pm.flags |= CS4281_PM_NOT_REGISTERED;
-	}
+	s->pm.flags |= CS4281_PM_NOT_REGISTERED;
 #endif
 
 	pci_set_master(pcidev);	// enable bus mastering 
@@ -4487,9 +4471,6 @@
 static void __exit cs4281_cleanup_module(void)
 {
 	pci_unregister_driver(&cs4281_pci_driver);
-#ifndef NOT_CS4281_PM
-	cs_pm_unregister_all(cs4281_pm_callback);
-#endif
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
 		  printk(KERN_INFO "cs4281: cleanup_cs4281() finished\n"));
 }
diff --git a/sound/oss/cs4281/cs4281pm-24.c b/sound/oss/cs4281/cs4281pm-24.c
index d2a453a..90cbd76 100644
--- a/sound/oss/cs4281/cs4281pm-24.c
+++ b/sound/oss/cs4281/cs4281pm-24.c
@@ -27,9 +27,6 @@
 #ifndef NOT_CS4281_PM
 #include <linux/pm.h>
 
-#define cs_pm_register(a, b, c) pm_register((a), (b), (c));
-#define cs_pm_unregister_all(a) pm_unregister_all((a));
-
 static int cs4281_suspend(struct cs4281_state *s);
 static int cs4281_resume(struct cs4281_state *s);
 /* 
@@ -41,42 +38,6 @@
 #define CS4281_SUSPEND_TBL cs4281_suspend_null
 #define CS4281_RESUME_TBL cs4281_resume_null
 
-static int cs4281_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
-{
-	struct cs4281_state *state;
-
-	CS_DBGOUT(CS_PM, 2, printk(KERN_INFO 
-		"cs4281: cs4281_pm_callback dev=%p rqst=0x%x state=%p\n",
-			dev,(unsigned)rqst,data));
-	state = (struct cs4281_state *) dev->data;
-	if (state) {
-		switch(rqst) {
-			case PM_SUSPEND:
-				CS_DBGOUT(CS_PM, 2, printk(KERN_INFO
-					"cs4281: PM suspend request\n"));
-				if(cs4281_suspend(state))
-				{
-				    CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
-					"cs4281: PM suspend request refused\n"));
-					return 1; 
-				}
-				break;
-			case PM_RESUME:
-				CS_DBGOUT(CS_PM, 2, printk(KERN_INFO
-					"cs4281: PM resume request\n"));
-				if(cs4281_resume(state))
-				{
-				    CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
-					"cs4281: PM resume request refused\n"));
-					return 1;
-				}
-				break;
-		}
-	}
-
-	return 0;
-}
-
 #else /* CS4281_PM */
 #define CS4281_SUSPEND_TBL cs4281_suspend_null
 #define CS4281_RESUME_TBL cs4281_resume_null
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
index cb998e8..0da4d93 100644
--- a/sound/oss/cs46xx.c
+++ b/sound/oss/cs46xx.c
@@ -391,10 +391,6 @@
 static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state);
 static int cs46xx_resume_tbl(struct pci_dev *pcidev);
 
-#ifndef CS46XX_ACPI_SUPPORT
-static int cs46xx_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data);
-#endif
-
 #if CSDEBUG
 
 /* DEBUG ROUTINES */
@@ -5320,7 +5316,6 @@
 static int __devinit cs46xx_probe(struct pci_dev *pci_dev,
 				  const struct pci_device_id *pciid)
 {
-	struct pm_dev *pmdev;
 	int i,j;
 	u16 ss_card, ss_vendor;
 	struct cs_card *card;
@@ -5530,22 +5525,6 @@
 	PCI_SET_DMA_MASK(pci_dev, dma_mask);
 	list_add(&card->list, &cs46xx_devs);
 
-	pmdev = cs_pm_register(PM_PCI_DEV, PM_PCI_ID(pci_dev), cs46xx_pm_callback);
-	if (pmdev)
-	{
-		CS_DBGOUT(CS_INIT | CS_PM, 4, printk(KERN_INFO
-			 "cs46xx: probe() pm_register() succeeded (%p).\n",
-				pmdev));
-		pmdev->data = card;
-	}
-	else
-	{
-		CS_DBGOUT(CS_INIT | CS_PM | CS_ERROR, 2, printk(KERN_INFO
-			 "cs46xx: probe() pm_register() failed (%p).\n",
-				pmdev));
-		card->pm.flags |= CS46XX_PM_NOT_REGISTERED;
-	}
-
 	CS_DBGOUT(CS_PM, 9, printk(KERN_INFO "cs46xx: pm.flags=0x%x card=%p\n",
 		(unsigned)card->pm.flags,card));
 
@@ -5727,7 +5706,6 @@
 static void __exit cs46xx_cleanup_module(void)
 {
 	pci_unregister_driver(&cs46xx_pci_driver);
-	cs_pm_unregister_all(cs46xx_pm_callback);
 	CS_DBGOUT(CS_INIT | CS_FUNCTION, 2,
 		  printk(KERN_INFO "cs46xx: cleanup_cs46xx() finished\n"));
 }
@@ -5735,44 +5713,6 @@
 module_init(cs46xx_init_module);
 module_exit(cs46xx_cleanup_module);
 
-#ifndef CS46XX_ACPI_SUPPORT
-static int cs46xx_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
-{
-	struct cs_card *card;
-
-	CS_DBGOUT(CS_PM, 2, printk(KERN_INFO 
-		"cs46xx: cs46xx_pm_callback dev=%p rqst=0x%x card=%p\n",
-			dev,(unsigned)rqst,data));
-	card = (struct cs_card *) dev->data;
-	if (card) {
-		switch(rqst) {
-			case PM_SUSPEND:
-				CS_DBGOUT(CS_PM, 2, printk(KERN_INFO
-					"cs46xx: PM suspend request\n"));
-				if(cs46xx_suspend(card, PMSG_SUSPEND))
-				{
-				    CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
-					"cs46xx: PM suspend request refused\n"));
-					return 1; 
-				}
-				break;
-			case PM_RESUME:
-				CS_DBGOUT(CS_PM, 2, printk(KERN_INFO
-					"cs46xx: PM resume request\n"));
-				if(cs46xx_resume(card))
-				{
-				    CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO
-					"cs46xx: PM resume request refused\n"));
-					return 1;
-				}
-				break;
-		}
-	}
-
-	return 0;
-}
-#endif
-
 #if CS46XX_ACPI_SUPPORT
 static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state)
 {
diff --git a/sound/oss/cs46xxpm-24.h b/sound/oss/cs46xxpm-24.h
index e220bd7..ad82db8 100644
--- a/sound/oss/cs46xxpm-24.h
+++ b/sound/oss/cs46xxpm-24.h
@@ -38,13 +38,9 @@
 */
 static int cs46xx_suspend_tbl(struct pci_dev *pcidev, pm_message_t state);
 static int cs46xx_resume_tbl(struct pci_dev *pcidev);
-#define cs_pm_register(a, b, c)  NULL
-#define cs_pm_unregister_all(a) 
 #define CS46XX_SUSPEND_TBL cs46xx_suspend_tbl
 #define CS46XX_RESUME_TBL cs46xx_resume_tbl
 #else
-#define cs_pm_register(a, b, c) pm_register((a), (b), (c));
-#define cs_pm_unregister_all(a) pm_unregister_all((a));
 #define CS46XX_SUSPEND_TBL cs46xx_null
 #define CS46XX_RESUME_TBL cs46xx_null
 #endif
diff --git a/sound/oss/dmasound/dac3550a.c b/sound/oss/dmasound/dac3550a.c
index 533895e..7360d89 100644
--- a/sound/oss/dmasound/dac3550a.c
+++ b/sound/oss/dmasound/dac3550a.c
@@ -41,10 +41,10 @@
 static int daca_detach_client(struct i2c_client *client);
 
 struct i2c_driver daca_driver = {  
-	.owner			= THIS_MODULE,
-	.name			= "DAC3550A driver  V " DACA_VERSION,
+	.driver = {
+		.name		= "DAC3550A driver  V " DACA_VERSION,
+	},
 	.id			= I2C_DRIVERID_DACA,
-	.flags			= I2C_DF_NOTIFY,
 	.attach_adapter		= daca_attach_adapter,
 	.detach_client		= daca_detach_client,
 };
diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c
index d36a1fe..8131599 100644
--- a/sound/oss/dmasound/tas_common.c
+++ b/sound/oss/dmasound/tas_common.c
@@ -47,9 +47,9 @@
 static int tas_detach_client(struct i2c_client *);
 
 struct i2c_driver tas_driver = {
-	.owner		= THIS_MODULE,
-	.name		= "tas",
-	.flags		= I2C_DF_NOTIFY,
+	.driver = {
+		.name	= "tas",
+	},
 	.attach_adapter	= tas_attach_adapter,
 	.detach_client	= tas_detach_client,
 };
diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
index b9a640f..4600cd6 100644
--- a/sound/oss/i810_audio.c
+++ b/sound/oss/i810_audio.c
@@ -3359,12 +3359,6 @@
 		goto out_region2;
 	}
 
-	if (request_irq(card->irq, &i810_interrupt, SA_SHIRQ,
-			card_names[pci_id->driver_data], card)) {
-		printk(KERN_ERR "i810_audio: unable to allocate irq %d\n", card->irq);
-		goto out_pio;
-	}
-
 	if (card->use_mmio) {
 		if (request_mem_region(card->ac97base_mmio_phys, 512, "ich_audio MMBAR")) {
 			if ((card->ac97base_mmio = ioremap(card->ac97base_mmio_phys, 512))) { /*@FIXME can ioremap fail? don't know (jsaw) */
@@ -3395,10 +3389,8 @@
 	}
 
 	/* initialize AC97 codec and register /dev/mixer */
-	if (i810_ac97_init(card) <= 0) {
-		free_irq(card->irq, card);
+	if (i810_ac97_init(card) <= 0)
 		goto out_iospace;
-	}
 	pci_set_drvdata(pci_dev, card);
 
 	if(clocking == 0) {
@@ -3410,7 +3402,6 @@
 	if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) {
 		int i;
 		printk(KERN_ERR "i810_audio: couldn't register DSP device!\n");
-		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);
@@ -3419,6 +3410,13 @@
 		goto out_iospace;
 	}
 
+	if (request_irq(card->irq, &i810_interrupt, SA_SHIRQ,
+			card_names[pci_id->driver_data], card)) {
+		printk(KERN_ERR "i810_audio: unable to allocate irq %d\n", card->irq);
+		goto out_iospace;
+	}
+
+
  	card->initializing = 0;
 	return 0;
 
diff --git a/sound/oss/maestro.c b/sound/oss/maestro.c
index 3abd354..f9ac5b1 100644
--- a/sound/oss/maestro.c
+++ b/sound/oss/maestro.c
@@ -230,10 +230,6 @@
 #include <asm/page.h>
 #include <asm/uaccess.h>
 
-#include <linux/pm.h>
-#include <linux/pm_legacy.h>
-static int maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *d);
-
 #include "maestro.h"
 
 static struct pci_driver maestro_pci_driver;
@@ -3404,7 +3400,6 @@
 	int i, ret;
 	struct ess_card *card;
 	struct ess_state *ess;
-	struct pm_dev *pmdev;
 	int num = 0;
 
 /* when built into the kernel, we only print version if device is found */
@@ -3450,11 +3445,6 @@
 	memset(card, 0, sizeof(*card));
 	card->pcidev = pcidev;
 
-	pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(pcidev),
-			maestro_pm_callback);
-	if (pmdev)
-		pmdev->data = card;
-
 	card->iobase = iobase;
 	card->card_type = card_type;
 	card->irq = pcidev->irq;
@@ -3670,7 +3660,6 @@
 static void cleanup_maestro(void) {
 	M_printk("maestro: unloading\n");
 	pci_unregister_driver(&maestro_pci_driver);
-	pm_unregister_all(maestro_pm_callback);
 	unregister_reboot_notifier(&maestro_nb);
 }
 
@@ -3691,143 +3680,5 @@
 	current->state = TASK_RUNNING;
 }
 
-static int 
-maestro_suspend(struct ess_card *card)
-{
-	unsigned long flags;
-	int i,j;
-
-	spin_lock_irqsave(&card->lock,flags); /* over-kill */
-
-	M_printk("maestro: apm in dev %p\n",card);
-
-	/* we have to read from the apu regs, need
-		to power it up */
-	maestro_power(card,ACPI_D0);
-
-	for(i=0;i<NR_DSPS;i++) {
-		struct ess_state *s = &card->channels[i];
-
-		if(s->dev_audio == -1)
-			continue;
-
-		M_printk("maestro: stopping apus for device %d\n",i);
-		stop_dac(s);
-		stop_adc(s);
-		for(j=0;j<6;j++) 
-			card->apu_map[s->apu[j]][5]=apu_get_register(s,j,5);
-
-	}
-
-	/* get rid of interrupts? */
-	if( card->dsps_open > 0)
-		stop_bob(&card->channels[0]);
-
-	card->in_suspend++;
-
-	spin_unlock_irqrestore(&card->lock,flags);
-
-	/* we trust in the bios to power down the chip on suspend.
-	 * XXX I'm also not sure that in_suspend will protect
-	 * against all reg accesses from here on out. 
-	 */
-	return 0;
-}
-static int 
-maestro_resume(struct ess_card *card)
-{
-	unsigned long flags;
-	int i;
-
-	spin_lock_irqsave(&card->lock,flags); /* over-kill */
-
-	card->in_suspend = 0;
-
-	M_printk("maestro: resuming card at %p\n",card);
-
-	/* restore all our config */
-	maestro_config(card);
-	/* need to restore the base pointers.. */ 
-	if(card->dmapages) 
-		set_base_registers(&card->channels[0],card->dmapages);
-
-	mixer_push_state(card);
-
-	/* set each channels' apu control registers before
-	 * restoring audio 
-	 */
-	for(i=0;i<NR_DSPS;i++) {
-		struct ess_state *s = &card->channels[i];
-		int chan,reg;
-
-		if(s->dev_audio == -1)
-			continue;
-
-		for(chan = 0 ; chan < 6 ; chan++) {
-			wave_set_register(s,s->apu[chan]<<3,s->apu_base[chan]);
-			for(reg = 1 ; reg < NR_APU_REGS ; reg++)  
-				apu_set_register(s,chan,reg,s->card->apu_map[s->apu[chan]][reg]);
-		}
-		for(chan = 0 ; chan < 6 ; chan++)  
-			apu_set_register(s,chan,0,s->card->apu_map[s->apu[chan]][0] & 0xFF0F);
-	}
-
-	/* now we flip on the music */
-
-	if( card->dsps_open <= 0) {
-		/* this card's idle */
-		maestro_power(card,ACPI_D2);
-	} else {
-		/* ok, we're actually playing things on
-			this card */
-		maestro_power(card,ACPI_D0);
-		start_bob(&card->channels[0]);
-		for(i=0;i<NR_DSPS;i++) {
-			struct ess_state *s = &card->channels[i];
-
-			/* these use the apu_mode, and can handle
-				spurious calls */
-			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;
-}
-
-int 
-maestro_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) 
-{
-	struct ess_card *card = (struct ess_card*) dev->data;
-
-	if ( ! card ) goto out;
-
-	M_printk("maestro: pm event 0x%x received for card %p\n", rqst, card);
-	
-	switch (rqst) {
-		case PM_SUSPEND: 
-			maestro_suspend(card);
-		break;
-		case PM_RESUME: 
-			maestro_resume(card);
-		break;
-		/*
-		 * we'd also like to find out about
-		 * power level changes because some biosen
-		 * do mean things to the maestro when they
-		 * change their power state.
-		 */
-        }
-out:
-	return 0;
-}
-
 module_init(init_maestro);
 module_exit(cleanup_maestro);
diff --git a/sound/oss/nm256_audio.c b/sound/oss/nm256_audio.c
index 0ce2c404..42d8f05 100644
--- a/sound/oss/nm256_audio.c
+++ b/sound/oss/nm256_audio.c
@@ -24,8 +24,6 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/pm.h>
-#include <linux/pm_legacy.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include "sound_config.h"
@@ -49,7 +47,6 @@
 static int nm256_releaseInterrupt (struct nm256_info *card);
 static irqreturn_t nm256_interrupt (int irq, void *dev_id, struct pt_regs *dummy);
 static irqreturn_t nm256_interrupt_zx (int irq, void *dev_id, struct pt_regs *dummy);
-static int handle_pm_event (struct pm_dev *dev, pm_request_t rqst, void *data);
 
 /* These belong in linux/pci.h. */
 #define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
@@ -992,15 +989,6 @@
     return 0;
 }
 
-/* Perform a full reset on the hardware; this is invoked when an APM
-   resume event occurs.  */
-static void
-nm256_full_reset (struct nm256_info *card)
-{
-    nm256_initHw (card);
-    ac97_reset (&(card->mdev));
-}
-
 /* 
  * See if the signature left by the NM256 BIOS is intact; if so, we use
  * the associated address as the end of our audio buffer in the video
@@ -1053,7 +1041,6 @@
 nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr)
 {
     struct nm256_info *card;
-    struct pm_dev *pmdev;
     int x;
 
     if (pci_enable_device(pcidev))
@@ -1234,43 +1221,10 @@
 
     nm256_install_mixer (card);
 
-    pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(pcidev), handle_pm_event);
-    if (pmdev)
-        pmdev->data = card;
-
     return 1;
 }
 
 
-/*
- * PM event handler, so the card is properly reinitialized after a power
- * event.
- */
-static int
-handle_pm_event (struct pm_dev *dev, pm_request_t rqst, void *data)
-{
-    struct nm256_info *crd = (struct nm256_info*) dev->data;
-    if (crd) {
-        switch (rqst) {
-	case PM_SUSPEND:
-	    break;
-	case PM_RESUME:
-            {
-                int playing = crd->playing;
-                nm256_full_reset (crd);
-                /*
-                 * A little ugly, but that's ok; pretend the
-                 * block we were playing is done. 
-                 */
-                if (playing)
-                    DMAbuf_outputintr (crd->dev_for_play, 1);
-            }
-	    break;
-	}
-    }
-    return 0;
-}
-
 static int __devinit
 nm256_probe(struct pci_dev *pcidev,const struct pci_device_id *pciid)
 {
@@ -1696,7 +1650,6 @@
 static void __exit cleanup_nm256 (void)
 {
     pci_unregister_driver(&nm256_pci_driver);
-    pm_unregister_all (&handle_pm_event);
 }
 
 module_init(do_init_nm256);
diff --git a/sound/oss/opl3sa2.c b/sound/oss/opl3sa2.c
index cd41d0e..5cecdbc 100644
--- a/sound/oss/opl3sa2.c
+++ b/sound/oss/opl3sa2.c
@@ -69,8 +69,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/pm.h>
-#include <linux/pm_legacy.h>
 #include "sound_config.h"
 
 #include "ad1848.h"
@@ -139,10 +137,6 @@
 	struct pnp_dev* pdev;
 	int activated;			/* Whether said devices have been activated */
 #endif
-#ifdef CONFIG_PM_LEGACY
-	unsigned int	in_suspend;
-	struct pm_dev	*pmdev;
-#endif
 	unsigned int	card;
 	int		chipset;	/* What's my version(s)? */
 	char		*chipset_name;
@@ -341,22 +335,6 @@
 	}
 }
 
-/* Currently only used for power management */
-#ifdef CONFIG_PM_LEGACY
-static void opl3sa2_mixer_restore(opl3sa2_state_t* devc)
-{
-	if (devc) {
-		opl3sa2_set_volume(devc, devc->volume_l, devc->volume_r);
-		opl3sa2_set_mic(devc, devc->mic);
-
-		if (devc->chipset == CHIPSET_OPL3SA3) {
-			opl3sa3_set_bass(devc, devc->bass_l, devc->bass_r);
-			opl3sa3_set_treble(devc, devc->treble_l, devc->treble_r);
-		}
-	}
-}
-#endif /* CONFIG_PM_LEGACY */
-
 static inline void arg_to_vol_mono(unsigned int vol, int* value)
 {
 	int left;
@@ -832,84 +810,6 @@
 
 /* End of component functions */
 
-#ifdef CONFIG_PM_LEGACY
-
-static DEFINE_SPINLOCK(opl3sa2_lock);
-
-/* Power Management support functions */
-static int opl3sa2_suspend(struct pm_dev *pdev, unsigned int pm_mode)
-{
-	unsigned long flags;
-	opl3sa2_state_t *p;
-
-	if (!pdev)
-		return -EINVAL;
-
-	spin_lock_irqsave(&opl3sa2_lock,flags);
-
-	p = (opl3sa2_state_t *) pdev->data;
-	switch (pm_mode) {
-	case 1:
-		pm_mode = OPL3SA2_PM_MODE1;
-		break;
-	case 2:
-		pm_mode = OPL3SA2_PM_MODE2;
-		break;
-	case 3:
-		pm_mode = OPL3SA2_PM_MODE3;
-		break;
-	default:
-		/* we don't know howto handle this... */
-		spin_unlock_irqrestore(&opl3sa2_lock, flags);
-		return -EBUSY;
-	}
-
-	p->in_suspend = 1;
-
-	/* its supposed to automute before suspending, so we won't bother */
-	opl3sa2_write(p->cfg_port, OPL3SA2_PM, pm_mode);
-	/* wait a while for the clock oscillator to stabilise */
-	mdelay(10);
-
-	spin_unlock_irqrestore(&opl3sa2_lock,flags);
-	return 0;
-}
-
-static int opl3sa2_resume(struct pm_dev *pdev)
-{
-	unsigned long flags;
-	opl3sa2_state_t *p;
-
- 	if (!pdev)
- 		return -EINVAL;
-
-	p = (opl3sa2_state_t *) pdev->data;
-	spin_lock_irqsave(&opl3sa2_lock,flags);
-
- 	/* I don't think this is necessary */
-	opl3sa2_write(p->cfg_port, OPL3SA2_PM, OPL3SA2_PM_MODE0);
-	opl3sa2_mixer_restore(p);
- 	p->in_suspend = 0;
-
-	spin_unlock_irqrestore(&opl3sa2_lock,flags);
-	return 0;
-}
-
-static int opl3sa2_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
-{
-	unsigned long mode = (unsigned  long)data;
-
-	switch (rqst) {
-		case PM_SUSPEND:
-			return opl3sa2_suspend(pdev, mode);
-
-		case PM_RESUME:
-			return opl3sa2_resume(pdev);
-	}
-	return 0;
-}
-#endif /* CONFIG_PM_LEGACY */
-
 /*
  * Install OPL3-SA2 based card(s).
  *
@@ -1021,12 +921,6 @@
 
 		/* ewww =) */
 		opl3sa2_state[card].card = card;
-#ifdef CONFIG_PM_LEGACY
-		/* register our power management capabilities */
-		opl3sa2_state[card].pmdev = pm_register(PM_ISA_DEV, card, opl3sa2_pm_callback);
-		if (opl3sa2_state[card].pmdev)
-			opl3sa2_state[card].pmdev->data = &opl3sa2_state[card];
-#endif /* CONFIG_PM_LEGACY */
 
 		/*
 		 * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and
@@ -1083,10 +977,6 @@
 	int card;
 
 	for(card = 0; card < opl3sa2_cards_num; card++) {
-#ifdef CONFIG_PM_LEGACY
-		if (opl3sa2_state[card].pmdev)
-			pm_unregister(opl3sa2_state[card].pmdev);
-#endif
 	        if (opl3sa2_state[card].cfg_mpu.slots[1] != -1) {
 			unload_opl3sa2_mpu(&opl3sa2_state[card].cfg_mpu);
  		}
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index d833349..ce73f3ea 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -59,6 +59,14 @@
 
 #include "harmony.h"
 
+static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
+static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
+module_param(index, int, 0444);
+MODULE_PARM_DESC(index, "Index value for Harmony driver.");
+module_param(id, charp, 0444);
+MODULE_PARM_DESC(id, "ID string for Harmony driver.");
+
+
 static struct parisc_device_id snd_harmony_devtable[] = {
 	/* bushmaster / flounder */
 	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x0007A }, 
@@ -91,32 +99,32 @@
 	HARMONY_SR_44KHZ, HARMONY_SR_48KHZ
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraint_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraint_rates = {
 	.count = ARRAY_SIZE(snd_harmony_rates),
 	.list = snd_harmony_rates,
 	.mask = 0,
 };
 
-inline unsigned long
-harmony_read(harmony_t *h, unsigned r)
+static inline unsigned long
+harmony_read(struct snd_harmony *h, unsigned r)
 {
 	return __raw_readl(h->iobase + r);
 }
 
-inline void
-harmony_write(harmony_t *h, unsigned r, unsigned long v)
+static inline void
+harmony_write(struct snd_harmony *h, unsigned r, unsigned long v)
 {
 	__raw_writel(v, h->iobase + r);
 }
 
-static void
-harmony_wait_for_control(harmony_t *h)
+static inline void
+harmony_wait_for_control(struct snd_harmony *h)
 {
 	while (harmony_read(h, HARMONY_CNTL) & HARMONY_CNTL_C) ;
 }
 
-inline void
-harmony_reset(harmony_t *h)
+static inline void
+harmony_reset(struct snd_harmony *h)
 {
 	harmony_write(h, HARMONY_RESET, 1);
 	mdelay(50);
@@ -124,7 +132,7 @@
 }
 
 static void
-harmony_disable_interrupts(harmony_t *h)
+harmony_disable_interrupts(struct snd_harmony *h)
 {
 	u32 dstatus;
 	harmony_wait_for_control(h);
@@ -134,7 +142,7 @@
 }
 
 static void
-harmony_enable_interrupts(harmony_t *h)
+harmony_enable_interrupts(struct snd_harmony *h)
 {
 	u32 dstatus;
 	harmony_wait_for_control(h);
@@ -144,7 +152,7 @@
 }
 
 static void
-harmony_mute(harmony_t *h)
+harmony_mute(struct snd_harmony *h)
 {
 	unsigned long flags;
 
@@ -155,7 +163,7 @@
 }
 
 static void
-harmony_unmute(harmony_t *h)
+harmony_unmute(struct snd_harmony *h)
 {
 	unsigned long flags;
 
@@ -166,7 +174,7 @@
 }
 
 static void
-harmony_set_control(harmony_t *h)
+harmony_set_control(struct snd_harmony *h)
 {
 	u32 ctrl;
 	unsigned long flags;
@@ -188,7 +196,7 @@
 snd_harmony_interrupt(int irq, void *dev, struct pt_regs *regs)
 {
 	u32 dstatus;
-	harmony_t *h = dev;
+	struct snd_harmony *h = dev;
 
 	spin_lock(&h->lock);
 	harmony_disable_interrupts(h);
@@ -253,7 +261,7 @@
 	return HARMONY_SR_44KHZ;
 }
 
-static snd_pcm_hardware_t snd_harmony_playback =
+static struct snd_pcm_hardware snd_harmony_playback =
 {
 	.info =	(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 
 		 SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
@@ -274,7 +282,7 @@
 	.fifo_size = 0,
 };
 
-static snd_pcm_hardware_t snd_harmony_capture =
+static struct snd_pcm_hardware snd_harmony_capture =
 {
         .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
                  SNDRV_PCM_INFO_JOINT_DUPLEX | SNDRV_PCM_INFO_MMAP_VALID |
@@ -296,15 +304,14 @@
 };
 
 static int
-snd_harmony_playback_trigger(snd_pcm_substream_t *ss, int cmd)
+snd_harmony_playback_trigger(struct snd_pcm_substream *ss, int cmd)
 {
-	harmony_t *h = snd_pcm_substream_chip(ss);
-	unsigned long flags;
+	struct snd_harmony *h = snd_pcm_substream_chip(ss);
 
 	if (h->st.capturing)
 		return -EBUSY;
 
-	spin_lock_irqsave(&h->lock, flags);
+	spin_lock(&h->lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		h->st.playing = 1;
@@ -323,25 +330,24 @@
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	default:
-		spin_unlock_irqrestore(&h->lock, flags);
+		spin_unlock(&h->lock);
 		snd_BUG();
 		return -EINVAL;
 	}
-	spin_unlock_irqrestore(&h->lock, flags);
+	spin_unlock(&h->lock);
 	
 	return 0;
 }
 
 static int
-snd_harmony_capture_trigger(snd_pcm_substream_t *ss, int cmd)
+snd_harmony_capture_trigger(struct snd_pcm_substream *ss, int cmd)
 {
-        harmony_t *h = snd_pcm_substream_chip(ss);
-	unsigned long flags;
+        struct snd_harmony *h = snd_pcm_substream_chip(ss);
 
 	if (h->st.playing)
 		return -EBUSY;
 
-	spin_lock_irqsave(&h->lock, flags);
+	spin_lock(&h->lock);
         switch (cmd) {
         case SNDRV_PCM_TRIGGER_START:
 		h->st.capturing = 1;
@@ -360,17 +366,17 @@
         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
         case SNDRV_PCM_TRIGGER_SUSPEND:
 	default:
-		spin_unlock_irqrestore(&h->lock, flags);
+		spin_unlock(&h->lock);
 		snd_BUG();
                 return -EINVAL;
         }
-	spin_unlock_irqrestore(&h->lock, flags);
+	spin_unlock(&h->lock);
 		
         return 0;
 }
 
 static int
-snd_harmony_set_data_format(harmony_t *h, int fmt, int force)
+snd_harmony_set_data_format(struct snd_harmony *h, int fmt, int force)
 {
 	int o = h->st.format;
 	int n;
@@ -400,10 +406,10 @@
 }
 
 static int
-snd_harmony_playback_prepare(snd_pcm_substream_t *ss)
+snd_harmony_playback_prepare(struct snd_pcm_substream *ss)
 {
-	harmony_t *h = snd_pcm_substream_chip(ss);
-	snd_pcm_runtime_t *rt = ss->runtime;
+	struct snd_harmony *h = snd_pcm_substream_chip(ss);
+	struct snd_pcm_runtime *rt = ss->runtime;
 	
 	if (h->st.capturing)
 		return -EBUSY;
@@ -430,10 +436,10 @@
 }
 
 static int
-snd_harmony_capture_prepare(snd_pcm_substream_t *ss)
+snd_harmony_capture_prepare(struct snd_pcm_substream *ss)
 {
-        harmony_t *h = snd_pcm_substream_chip(ss);
-        snd_pcm_runtime_t *rt = ss->runtime;
+        struct snd_harmony *h = snd_pcm_substream_chip(ss);
+        struct snd_pcm_runtime *rt = ss->runtime;
 
 	if (h->st.playing)
 		return -EBUSY;
@@ -460,10 +466,10 @@
 }
 
 static snd_pcm_uframes_t 
-snd_harmony_playback_pointer(snd_pcm_substream_t *ss)
+snd_harmony_playback_pointer(struct snd_pcm_substream *ss)
 {
-	snd_pcm_runtime_t *rt = ss->runtime;
-	harmony_t *h = snd_pcm_substream_chip(ss);
+	struct snd_pcm_runtime *rt = ss->runtime;
+	struct snd_harmony *h = snd_pcm_substream_chip(ss);
 	unsigned long pcuradd;
 	unsigned long played;
 
@@ -489,10 +495,10 @@
 }
 
 static snd_pcm_uframes_t
-snd_harmony_capture_pointer(snd_pcm_substream_t *ss)
+snd_harmony_capture_pointer(struct snd_pcm_substream *ss)
 {
-        snd_pcm_runtime_t *rt = ss->runtime;
-        harmony_t *h = snd_pcm_substream_chip(ss);
+        struct snd_pcm_runtime *rt = ss->runtime;
+        struct snd_harmony *h = snd_pcm_substream_chip(ss);
         unsigned long rcuradd;
         unsigned long caught;
 
@@ -518,10 +524,10 @@
 }
 
 static int 
-snd_harmony_playback_open(snd_pcm_substream_t *ss)
+snd_harmony_playback_open(struct snd_pcm_substream *ss)
 {
-	harmony_t *h = snd_pcm_substream_chip(ss);
-	snd_pcm_runtime_t *rt = ss->runtime;
+	struct snd_harmony *h = snd_pcm_substream_chip(ss);
+	struct snd_pcm_runtime *rt = ss->runtime;
 	int err;
 	
 	h->psubs = ss;
@@ -537,10 +543,10 @@
 }
 
 static int
-snd_harmony_capture_open(snd_pcm_substream_t *ss)
+snd_harmony_capture_open(struct snd_pcm_substream *ss)
 {
-        harmony_t *h = snd_pcm_substream_chip(ss);
-        snd_pcm_runtime_t *rt = ss->runtime;
+        struct snd_harmony *h = snd_pcm_substream_chip(ss);
+        struct snd_pcm_runtime *rt = ss->runtime;
         int err;
 
         h->csubs = ss;
@@ -556,27 +562,27 @@
 }
 
 static int 
-snd_harmony_playback_close(snd_pcm_substream_t *ss)
+snd_harmony_playback_close(struct snd_pcm_substream *ss)
 {
-	harmony_t *h = snd_pcm_substream_chip(ss);
+	struct snd_harmony *h = snd_pcm_substream_chip(ss);
 	h->psubs = NULL;
 	return 0;
 }
 
 static int
-snd_harmony_capture_close(snd_pcm_substream_t *ss)
+snd_harmony_capture_close(struct snd_pcm_substream *ss)
 {
-        harmony_t *h = snd_pcm_substream_chip(ss);
+        struct snd_harmony *h = snd_pcm_substream_chip(ss);
         h->csubs = NULL;
         return 0;
 }
 
 static int 
-snd_harmony_hw_params(snd_pcm_substream_t *ss,
-		      snd_pcm_hw_params_t *hw)
+snd_harmony_hw_params(struct snd_pcm_substream *ss,
+		      struct snd_pcm_hw_params *hw)
 {
 	int err;
-	harmony_t *h = snd_pcm_substream_chip(ss);
+	struct snd_harmony *h = snd_pcm_substream_chip(ss);
 	
 	err = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw));
 	if (err > 0 && h->dma.type == SNDRV_DMA_TYPE_CONTINUOUS)
@@ -586,12 +592,12 @@
 }
 
 static int 
-snd_harmony_hw_free(snd_pcm_substream_t *ss) 
+snd_harmony_hw_free(struct snd_pcm_substream *ss) 
 {
 	return snd_pcm_lib_free_pages(ss);
 }
 
-static snd_pcm_ops_t snd_harmony_playback_ops = {
+static struct snd_pcm_ops snd_harmony_playback_ops = {
 	.open =	snd_harmony_playback_open,
 	.close = snd_harmony_playback_close,
 	.ioctl = snd_pcm_lib_ioctl,
@@ -602,7 +608,7 @@
  	.pointer = snd_harmony_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_harmony_capture_ops = {
+static struct snd_pcm_ops snd_harmony_capture_ops = {
         .open = snd_harmony_capture_open,
         .close = snd_harmony_capture_close,
         .ioctl = snd_pcm_lib_ioctl,
@@ -614,9 +620,9 @@
 };
 
 static int 
-snd_harmony_pcm_init(harmony_t *h)
+snd_harmony_pcm_init(struct snd_harmony *h)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	harmony_disable_interrupts(h);
@@ -677,15 +683,15 @@
 }
 
 static void 
-snd_harmony_set_new_gain(harmony_t *h)
+snd_harmony_set_new_gain(struct snd_harmony *h)
 {
  	harmony_wait_for_control(h);
 	harmony_write(h, HARMONY_GAINCTL, h->st.gain);
 }
 
 static int 
-snd_harmony_mixercontrol_info(snd_kcontrol_t *kc, 
-			      snd_ctl_elem_info_t *uinfo)
+snd_harmony_mixercontrol_info(struct snd_kcontrol *kc, 
+			      struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kc->private_value >> 16) & 0xff;
 	int left_shift = (kc->private_value) & 0xff;
@@ -701,18 +707,17 @@
 }
 
 static int 
-snd_harmony_volume_get(snd_kcontrol_t *kc, 
-		       snd_ctl_elem_value_t *ucontrol)
+snd_harmony_volume_get(struct snd_kcontrol *kc, 
+		       struct snd_ctl_elem_value *ucontrol)
 {
-	harmony_t *h = snd_kcontrol_chip(kc);
+	struct snd_harmony *h = snd_kcontrol_chip(kc);
 	int shift_left = (kc->private_value) & 0xff;
 	int shift_right = (kc->private_value >> 8) & 0xff;
 	int mask = (kc->private_value >> 16) & 0xff;
 	int invert = (kc->private_value >> 24) & 0xff;
 	int left, right;
-	unsigned long flags;
 	
-	spin_lock_irqsave(&h->mixer_lock, flags);
+	spin_lock_irq(&h->mixer_lock);
 
 	left = (h->st.gain >> shift_left) & mask;
 	right = (h->st.gain >> shift_right) & mask;
@@ -725,25 +730,24 @@
 	if (shift_left != shift_right)
 		ucontrol->value.integer.value[1] = right;
 
-	spin_unlock_irqrestore(&h->mixer_lock, flags);
+	spin_unlock_irq(&h->mixer_lock);
 
 	return 0;
 }  
 
 static int 
-snd_harmony_volume_put(snd_kcontrol_t *kc, 
-		       snd_ctl_elem_value_t *ucontrol)
+snd_harmony_volume_put(struct snd_kcontrol *kc, 
+		       struct snd_ctl_elem_value *ucontrol)
 {
-	harmony_t *h = snd_kcontrol_chip(kc);
+	struct snd_harmony *h = snd_kcontrol_chip(kc);
 	int shift_left = (kc->private_value) & 0xff;
 	int shift_right = (kc->private_value >> 8) & 0xff;
 	int mask = (kc->private_value >> 16) & 0xff;
 	int invert = (kc->private_value >> 24) & 0xff;
 	int left, right;
 	int old_gain = h->st.gain;
-	unsigned long flags;
 	
-	spin_lock_irqsave(&h->mixer_lock, flags);
+	spin_lock_irq(&h->mixer_lock);
 
 	left = ucontrol->value.integer.value[0] & mask;
 	if (invert)
@@ -761,14 +765,14 @@
 
 	snd_harmony_set_new_gain(h);
 
-	spin_unlock_irqrestore(&h->mixer_lock, flags);
+	spin_unlock_irq(&h->mixer_lock);
 	
 	return h->st.gain != old_gain;
 }
 
 static int 
-snd_harmony_captureroute_info(snd_kcontrol_t *kc, 
-			      snd_ctl_elem_info_t *uinfo)
+snd_harmony_captureroute_info(struct snd_kcontrol *kc, 
+			      struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = { "Line", "Mic" };
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -782,33 +786,31 @@
 }
 
 static int 
-snd_harmony_captureroute_get(snd_kcontrol_t *kc, 
-			     snd_ctl_elem_value_t *ucontrol)
+snd_harmony_captureroute_get(struct snd_kcontrol *kc, 
+			     struct snd_ctl_elem_value *ucontrol)
 {
-	harmony_t *h = snd_kcontrol_chip(kc);
+	struct snd_harmony *h = snd_kcontrol_chip(kc);
 	int value;
-	unsigned long flags;
 	
-	spin_lock_irqsave(&h->mixer_lock, flags);
+	spin_lock_irq(&h->mixer_lock);
 
 	value = (h->st.gain >> HARMONY_GAIN_IS_SHIFT) & 1;
 	ucontrol->value.enumerated.item[0] = value;
 
-	spin_unlock_irqrestore(&h->mixer_lock, flags);
+	spin_unlock_irq(&h->mixer_lock);
 
 	return 0;
 }  
 
 static int 
-snd_harmony_captureroute_put(snd_kcontrol_t *kc, 
-			     snd_ctl_elem_value_t *ucontrol)
+snd_harmony_captureroute_put(struct snd_kcontrol *kc, 
+			     struct snd_ctl_elem_value *ucontrol)
 {
-	harmony_t *h = snd_kcontrol_chip(kc);
+	struct snd_harmony *h = snd_kcontrol_chip(kc);
 	int value;
 	int old_gain = h->st.gain;
-	unsigned long flags;
 	
-	spin_lock_irqsave(&h->mixer_lock, flags);
+	spin_lock_irq(&h->mixer_lock);
 
 	value = ucontrol->value.enumerated.item[0] & 1;
 	h->st.gain &= ~HARMONY_GAIN_IS_MASK;
@@ -816,13 +818,12 @@
 
 	snd_harmony_set_new_gain(h);
 
-	spin_unlock_irqrestore(&h->mixer_lock, flags);
+	spin_unlock_irq(&h->mixer_lock);
 	
 	return h->st.gain != old_gain;
 }
 
-#define HARMONY_CONTROLS (sizeof(snd_harmony_controls)/ \
-                          sizeof(snd_kcontrol_new_t))
+#define HARMONY_CONTROLS	ARRAY_SIZE(snd_harmony_controls)
 
 #define HARMONY_VOLUME(xname, left_shift, right_shift, mask, invert) \
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,                \
@@ -831,7 +832,7 @@
   .private_value = ((left_shift) | ((right_shift) << 8) |            \
                    ((mask) << 16) | ((invert) << 24)) }
 
-static snd_kcontrol_new_t snd_harmony_controls[] = {
+static struct snd_kcontrol_new snd_harmony_controls[] = {
 	HARMONY_VOLUME("Master Playback Volume", HARMONY_GAIN_LO_SHIFT, 
 		       HARMONY_GAIN_RO_SHIFT, HARMONY_GAIN_OUT, 1),
 	HARMONY_VOLUME("Capture Volume", HARMONY_GAIN_LI_SHIFT,
@@ -854,7 +855,7 @@
 };
 
 static void __init 
-snd_harmony_mixer_reset(harmony_t *h)
+snd_harmony_mixer_reset(struct snd_harmony *h)
 {
 	harmony_mute(h);
 	harmony_reset(h);
@@ -863,9 +864,9 @@
 }
 
 static int __init 
-snd_harmony_mixer_init(harmony_t *h)
+snd_harmony_mixer_init(struct snd_harmony *h)
 {
-	snd_card_t *card = h->card;
+	struct snd_card *card = h->card;
 	int idx, err;
 
 	snd_assert(h != NULL, return -EINVAL);
@@ -884,7 +885,7 @@
 }
 
 static int
-snd_harmony_free(harmony_t *h)
+snd_harmony_free(struct snd_harmony *h)
 {
         if (h->gdma.addr)
                 snd_dma_free_pages(&h->gdma);
@@ -904,38 +905,33 @@
 }
 
 static int
-snd_harmony_dev_free(snd_device_t *dev)
+snd_harmony_dev_free(struct snd_device *dev)
 {
-	harmony_t *h = dev->device_data;
+	struct snd_harmony *h = dev->device_data;
 	return snd_harmony_free(h);
 }
 
 static int __devinit
-snd_harmony_create(snd_card_t *card, 
+snd_harmony_create(struct snd_card *card, 
 		   struct parisc_device *padev, 
-		   harmony_t **rchip)
+		   struct snd_harmony **rchip)
 {
 	int err;
-	harmony_t *h;
-	static snd_device_ops_t ops = {
+	struct snd_harmony *h;
+	static struct snd_device_ops ops = {
 		.dev_free = snd_harmony_dev_free,
 	};
 
 	*rchip = NULL;
 
-	h = kmalloc(sizeof(*h), GFP_KERNEL);
+	h = kzalloc(sizeof(*h), GFP_KERNEL);
 	if (h == NULL)
 		return -ENOMEM;
 
-	memset(&h->st, 0, sizeof(h->st));
-	memset(&h->stats, 0, sizeof(h->stats));
-	memset(&h->pbuf, 0, sizeof(h->pbuf));
-	memset(&h->cbuf, 0, sizeof(h->cbuf));
-
 	h->hpa = padev->hpa.start;
 	h->card = card;
 	h->dev = padev;
-	h->irq = padev->irq;
+	h->irq = -1;
 	h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE);
 	if (h->iobase == NULL) {
 		printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
@@ -944,13 +940,14 @@
 		goto free_and_ret;
 	}
 		
-	err = request_irq(h->irq, snd_harmony_interrupt, 0,
+	err = request_irq(padev->irq, snd_harmony_interrupt, 0,
 			  "harmony", h);
 	if (err) {
 		printk(KERN_ERR PFX "could not obtain interrupt %d",
-		       h->irq);
+		       padev->irq);
 		goto free_and_ret;
 	}
+	h->irq = padev->irq;
 
 	spin_lock_init(&h->mixer_lock);
 	spin_lock_init(&h->lock);
@@ -975,35 +972,24 @@
 snd_harmony_probe(struct parisc_device *padev)
 {
 	int err;
-	static int dev;
-	snd_card_t *card;
-	harmony_t *h;
-	static int index = SNDRV_DEFAULT_IDX1;
-	static char *id = SNDRV_DEFAULT_STR1;
-
-	h = parisc_get_drvdata(padev);
-	if (h != NULL) {
-		return -ENODEV;
-	}
+	struct snd_card *card;
+	struct snd_harmony *h;
 
 	card = snd_card_new(index, id, THIS_MODULE, 0);
 	if (card == NULL)
 		return -ENOMEM;
 
 	err = snd_harmony_create(card, padev, &h);
-	if (err < 0) {
+	if (err < 0)
 		goto free_and_ret;
-	}
 
 	err = snd_harmony_pcm_init(h);
-	if (err < 0) {
+	if (err < 0)
 		goto free_and_ret;
-	}
 
 	err = snd_harmony_mixer_init(h);
-	if (err < 0) {
+	if (err < 0)
 		goto free_and_ret;
-	}
 
 	strcpy(card->driver, "harmony");
 	strcpy(card->shortname, "Harmony");
@@ -1011,13 +997,10 @@
 		card->shortname, h->hpa, h->irq);
 
 	err = snd_card_register(card);
-	if (err < 0) {
+	if (err < 0)
 		goto free_and_ret;
-	}
 
-	dev++;
-	parisc_set_drvdata(padev, h);
-
+	parisc_set_drvdata(padev, card);
 	return 0;
 
 free_and_ret:
@@ -1028,8 +1011,8 @@
 static int __devexit
 snd_harmony_remove(struct parisc_device *padev)
 {
-	harmony_t *h = parisc_get_drvdata(padev);
-	snd_card_free(h->card);
+	snd_card_free(parisc_get_drvdata(padev));
+	parisc_set_drvdata(padev, NULL);
 	return 0;
 }
 
@@ -1043,28 +1026,13 @@
 static int __init 
 alsa_harmony_init(void)
 {
-	int err;
-
-	err = register_parisc_driver(&snd_harmony_driver);
-	if (err < 0) {
-		printk(KERN_ERR PFX "device not found\n");
-		return err;
-	}
-
-	return 0;
+	return register_parisc_driver(&snd_harmony_driver);
 }
 
 static void __exit
 alsa_harmony_fini(void)
 {
-	int err;
-
-	err = unregister_parisc_driver(&snd_harmony_driver);
-	if (err < 0) {
-		printk(KERN_ERR PFX "failed to unregister\n");
-	}
-	
-	return;
+	unregister_parisc_driver(&snd_harmony_driver);
 }
 
 MODULE_LICENSE("GPL");
diff --git a/sound/parisc/harmony.h b/sound/parisc/harmony.h
index 526c523..2e43452 100644
--- a/sound/parisc/harmony.h
+++ b/sound/parisc/harmony.h
@@ -13,7 +13,7 @@
         int coherent;
 };
 
-typedef struct snd_card_harmony {
+struct snd_harmony {
         int irq;
 
         unsigned long hpa; /* hard physical address */
@@ -44,15 +44,15 @@
                 unsigned long silence_intr;
         } stats;
 
-        snd_pcm_t *pcm;
-        snd_card_t *card;
-        snd_pcm_substream_t *psubs;
-	snd_pcm_substream_t *csubs;
-        snd_info_entry_t *proc;
+        struct snd_pcm *pcm;
+        struct snd_card *card;
+        struct snd_pcm_substream *psubs;
+	struct snd_pcm_substream *csubs;
+        struct snd_info_entry *proc;
 
         spinlock_t lock;
         spinlock_t mixer_lock;
-} harmony_t;
+};
 
 #define MAX_PCM_DEVICES     1
 #define MAX_PCM_SUBSTREAMS  4
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 0fb16cf..1e2e193 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -3,6 +3,31 @@
 menu "PCI devices"
 	depends on SND!=n && PCI
 
+config SND_AD1889
+	tristate "Analog Devices AD1889"
+	depends on SND
+	select SND_AC97_CODEC
+	help
+	  Say Y here to include support for the integrated AC97 sound
+	  device found in particular on the Hewlett-Packard [BCJ]-xxx0
+	  class PA-RISC workstations, using the AD1819 codec.
+
+	  To compile this as a module, choose M here: the module
+	  will be called snd-ad1889.
+
+config SND_ALS4000
+	tristate "Avance Logic ALS4000"
+	depends on SND && ISA_DMA_API
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_PCM
+	help
+	  Say Y here to include support for soundcards based on Avance Logic
+	  ALS4000 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-als4000.
+
 config SND_ALI5451
 	tristate "ALi M5451 PCI Audio Controller"
 	depends on SND
@@ -119,6 +144,44 @@
 	  Higher sample rates won't hurt your hardware, but audio
 	  quality may suffer.
 
+config SND_CA0106
+	tristate "SB Audigy LS / Live 24bit"
+	depends on SND
+	select SND_AC97_CODEC
+	select SND_RAWMIDI
+	help
+	  Say Y here to include support for the Sound Blaster Audigy LS
+	  and Live 24bit.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-ca0106.
+
+config SND_CMIPCI
+	tristate "C-Media 8738, 8338"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_PCM
+	help
+	  If you want to use soundcards based on C-Media CMI8338 or CMI8738
+	  chips, say Y here and read
+	  <file:Documentation/sound/alsa/CMIPCI.txt>.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cmipci.
+
+config SND_CS4281
+	tristate "Cirrus Logic (Sound Fusion) CS4281"
+	depends on SND
+	select SND_OPL3_LIB
+	select SND_RAWMIDI
+	select SND_AC97_CODEC
+	help
+	  Say Y here to include support for Cirrus Logic CS4281 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cs4281.
+
 config SND_CS46XX
 	tristate "Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x"
 	depends on SND
@@ -139,17 +202,18 @@
 
 	  This works better than the old code, so say Y.
 
-config SND_CS4281
-	tristate "Cirrus Logic (Sound Fusion) CS4281"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_RAWMIDI
+config SND_CS5535AUDIO
+	tristate "CS5535 Audio"
+	depends on SND && X86 && !X86_64
+	select SND_PCM
 	select SND_AC97_CODEC
 	help
-	  Say Y here to include support for Cirrus Logic CS4281 chips.
+	  Say Y here to include support for audio on CS5535 chips. It is
+	  referred to as NS CS5535 IO or AMD CS5535 IO companion in
+	  various literature.
 
 	  To compile this driver as a module, choose M here: the module
-	  will be called snd-cs4281.
+	  will be called snd-cs5535audio.
 
 config SND_EMU10K1
 	tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)"
@@ -180,174 +244,6 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-emu10k1x.
 
-config SND_CA0106
-	tristate "SB Audigy LS / Live 24bit"
-	depends on SND
-	select SND_AC97_CODEC
-	select SND_RAWMIDI
-	help
-	  Say Y here to include support for the Sound Blaster Audigy LS
-	  and Live 24bit.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-ca0106.
-
-config SND_KORG1212
-	tristate "Korg 1212 IO"
-	depends on SND
-	select SND_PCM
-	help
-	  Say Y here to include support for Korg 1212IO soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-korg1212.
-
-config SND_MIXART
-	tristate "Digigram miXart"
-	depends on SND
-	select SND_HWDEP
-	select SND_PCM
-	help
-	  If you want to use Digigram miXart soundcards, say Y here and
-	  read <file:Documentation/sound/alsa/MIXART.txt>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-mixart.
-
-config SND_NM256
-	tristate "NeoMagic NM256AV/ZX"
-	depends on SND
-	select SND_AC97_CODEC
-	help
-	  Say Y here to include support for NeoMagic NM256AV/ZX chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-nm256.
-
-config SND_RME32
-	tristate "RME Digi32, 32/8, 32 PRO"
-	depends on SND
-	select SND_PCM
-	help
-	  Say Y to include support for RME Digi32, Digi32 PRO and
-	  Digi32/8 (Sek'd Prodif32, Prodif96 and Prodif Gold) audio
-	  devices.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-rme32.
-
-config SND_RME96
-	tristate "RME Digi96, 96/8, 96/8 PRO"
-	depends on SND
-	select SND_PCM
-	help
-	  Say Y here to include support for RME Digi96, Digi96/8 and
-	  Digi96/8 PRO/PAD/PST soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-rme96.
-
-config SND_RME9652
-	tristate "RME Digi9652 (Hammerfall)"
-	depends on SND
-	select SND_PCM
-	help
-	  Say Y here to include support for RME Hammerfall (RME
-	  Digi9652/Digi9636) soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-rme9652.
-
-config SND_HDSP
-	tristate "RME Hammerfall DSP Audio"
-	depends on SND
-	select SND_HWDEP
-	select SND_RAWMIDI
-	select SND_PCM
-	help
-	  Say Y here to include support for RME Hammerfall DSP Audio
-	  soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-hdsp.
-
-config SND_HDSPM
-	tristate "RME Hammerfall DSP MADI"
-	depends on SND
-	select SND_HWDEP
-	select SND_RAWMIDI
-	select SND_PCM
-	help
-	  Say Y here to include support for RME Hammerfall DSP MADI
-	  soundcards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-hdspm.
-
-config SND_TRIDENT
-	tristate "Trident 4D-Wave DX/NX; SiS 7018"
-	depends on SND
-	select SND_MPU401_UART
-	select SND_AC97_CODEC
-	help
-	  Say Y here to include support for soundcards based on Trident
-	  4D-Wave DX/NX or SiS 7018 chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-trident.
-
-config SND_YMFPCI
-	tristate "Yamaha YMF724/740/744/754"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_AC97_CODEC
-	help
-	  Say Y here to include support for Yamaha PCI audio chips -
-	  YMF724, YMF724F, YMF740, YMF740C, YMF744, YMF754.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-ymfpci.
-
-config SND_AD1889
-	tristate "Analog Devices AD1889"
-	depends on SND
-	select SND_AC97_CODEC
-	help
-	  Say Y here to include support for the integrated AC97 sound
-	  device found in particular on the Hewlett-Packard [BCJ]-xxx0
-	  class PA-RISC workstations, using the AD1819 codec.
-
-	  To compile this as a module, choose M here: the module
-	  will be called snd-ad1889.
-
-config SND_ALS4000
-	tristate "Avance Logic ALS4000"
-	depends on SND && ISA_DMA_API
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_PCM
-	help
-	  Say Y here to include support for soundcards based on Avance Logic
-	  ALS4000 chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-als4000.
-
-config SND_CMIPCI
-	tristate "C-Media 8738, 8338"
-	depends on SND
-	select SND_OPL3_LIB
-	select SND_MPU401_UART
-	select SND_PCM
-	help
-	  If you want to use soundcards based on C-Media CMI8338 or CMI8738
-	  chips, say Y here and read
-	  <file:Documentation/sound/alsa/CMIPCI.txt>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-cmipci.
-
 config SND_ENS1370
 	tristate "(Creative) Ensoniq AudioPCI 1370"
 	depends on SND
@@ -396,17 +292,6 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-es1968.
 
-config SND_MAESTRO3
-	tristate "ESS Allegro/Maestro3"
-	depends on SND
-	select SND_AC97_CODEC
-	help
-	  Say Y here to include support for soundcards based on ESS Maestro 3
-	  (Allegro) chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called snd-maestro3.
-
 config SND_FM801
 	tristate "ForteMedia FM801"
 	depends on SND
@@ -432,6 +317,43 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-fm801-tea575x.
 
+config SND_HDA_INTEL
+	tristate "Intel HD Audio"
+	depends on SND
+	select SND_PCM
+	help
+	  Say Y here to include support for Intel "High Definition
+	  Audio" (Azalia) motherboard devices.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-hda-intel.
+
+config SND_HDSP
+	tristate "RME Hammerfall DSP Audio"
+	depends on SND
+	select SND_HWDEP
+	select SND_RAWMIDI
+	select SND_PCM
+	help
+	  Say Y here to include support for RME Hammerfall DSP Audio
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-hdsp.
+
+config SND_HDSPM
+	tristate "RME Hammerfall DSP MADI"
+	depends on SND
+	select SND_HWDEP
+	select SND_RAWMIDI
+	select SND_PCM
+	help
+	  Say Y here to include support for RME Hammerfall DSP MADI
+	  soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-hdspm.
+
 config SND_ICE1712
 	tristate "ICEnsemble ICE1712 (Envy24)"
 	depends on SND
@@ -490,6 +412,94 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-intel8x0m.
 
+config SND_KORG1212
+	tristate "Korg 1212 IO"
+	depends on SND
+	select SND_PCM
+	help
+	  Say Y here to include support for Korg 1212IO soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-korg1212.
+
+config SND_MAESTRO3
+	tristate "ESS Allegro/Maestro3"
+	depends on SND
+	select SND_AC97_CODEC
+	help
+	  Say Y here to include support for soundcards based on ESS Maestro 3
+	  (Allegro) chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-maestro3.
+
+config SND_MIXART
+	tristate "Digigram miXart"
+	depends on SND
+	select SND_HWDEP
+	select SND_PCM
+	help
+	  If you want to use Digigram miXart soundcards, say Y here and
+	  read <file:Documentation/sound/alsa/MIXART.txt>.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-mixart.
+
+config SND_NM256
+	tristate "NeoMagic NM256AV/ZX"
+	depends on SND
+	select SND_AC97_CODEC
+	help
+	  Say Y here to include support for NeoMagic NM256AV/ZX chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-nm256.
+
+config SND_PCXHR
+	tristate "Digigram PCXHR"
+	depends on SND
+	select SND_PCM
+	select SND_HWDEP
+	help
+	  Say Y here to include support for Digigram PCXHR boards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-pcxhr.
+
+config SND_RME32
+	tristate "RME Digi32, 32/8, 32 PRO"
+	depends on SND
+	select SND_PCM
+	help
+	  Say Y to include support for RME Digi32, Digi32 PRO and
+	  Digi32/8 (Sek'd Prodif32, Prodif96 and Prodif Gold) audio
+	  devices.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-rme32.
+
+config SND_RME96
+	tristate "RME Digi96, 96/8, 96/8 PRO"
+	depends on SND
+	select SND_PCM
+	help
+	  Say Y here to include support for RME Digi96, Digi96/8 and
+	  Digi96/8 PRO/PAD/PST soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-rme96.
+
+config SND_RME9652
+	tristate "RME Digi9652 (Hammerfall)"
+	depends on SND
+	select SND_PCM
+	help
+	  Say Y here to include support for RME Hammerfall (RME
+	  Digi9652/Digi9636) soundcards.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-rme9652.
+
 config SND_SONICVIBES
 	tristate "S3 SonicVibes"
 	depends on SND
@@ -503,6 +513,18 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-sonicvibes.
 
+config SND_TRIDENT
+	tristate "Trident 4D-Wave DX/NX; SiS 7018"
+	depends on SND
+	select SND_MPU401_UART
+	select SND_AC97_CODEC
+	help
+	  Say Y here to include support for soundcards based on Trident
+	  4D-Wave DX/NX or SiS 7018 chips.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-trident.
+
 config SND_VIA82XX
 	tristate "VIA 82C686A/B, 8233/8235 AC97 Controller"
 	depends on SND
@@ -536,15 +558,17 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-vx222.
 
-config SND_HDA_INTEL
-	tristate "Intel HD Audio"
+config SND_YMFPCI
+	tristate "Yamaha YMF724/740/744/754"
 	depends on SND
-	select SND_PCM
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	select SND_AC97_CODEC
 	help
-	  Say Y here to include support for Intel "High Definition
-	  Audio" (Azalia) motherboard devices.
+	  Say Y here to include support for Yamaha PCI audio chips -
+	  YMF724, YMF724F, YMF740, YMF740C, YMF744, YMF754.
 
 	  To compile this driver as a module, choose M here: the module
-	  will be called snd-hda-intel.
+	  will be called snd-ymfpci.
 
 endmenu
diff --git a/sound/pci/Makefile b/sound/pci/Makefile
index 42fabfc..a6c3cd5 100644
--- a/sound/pci/Makefile
+++ b/sound/pci/Makefile
@@ -54,12 +54,14 @@
 	au88x0/ \
 	ca0106/ \
 	cs46xx/ \
+	cs5535audio/ \
 	emu10k1/ \
 	hda/ \
 	ice1712/ \
 	korg1212/ \
 	mixart/ \
 	nm256/ \
+	pcxhr/ \
 	rme9652/ \
 	trident/ \
 	ymfpci/ \
diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c
index ec70fad..66de2c2 100644
--- a/sound/pci/ac97/ac97_bus.c
+++ b/sound/pci/ac97/ac97_bus.c
@@ -18,7 +18,7 @@
 
 /*
  * Let drivers decide whether they want to support given codec from their
- * probe method.  Drivers have direct access to the ac97_t structure and may
+ * probe method.  Drivers have direct access to the struct snd_ac97 structure and may
  * decide based on the id field amongst other things.
  */
 static int ac97_bus_match(struct device *dev, struct device_driver *drv)
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 9bde76c..3020ca2 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -50,16 +50,16 @@
 
  */
 
-typedef struct {
+struct ac97_codec_id {
 	unsigned int id;
 	unsigned int mask;
 	const char *name;
-	int (*patch)(ac97_t *ac97);
-	int (*mpatch)(ac97_t *ac97);
+	int (*patch)(struct snd_ac97 *ac97);
+	int (*mpatch)(struct snd_ac97 *ac97);
 	unsigned int flags;
-} ac97_codec_id_t;
+};
 
-static const ac97_codec_id_t snd_ac97_codec_id_vendors[] = {
+static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
 { 0x414b4d00, 0xffffff00, "Asahi Kasei",	NULL,	NULL },
 { 0x41445300, 0xffffff00, "Analog Devices",	NULL,	NULL },
 { 0x414c4300, 0xffffff00, "Realtek",		NULL,	NULL },
@@ -86,7 +86,7 @@
 { 0,	      0, 	  NULL,			NULL,	NULL }
 };
 
-static const ac97_codec_id_t snd_ac97_codec_ids[] = {
+static const struct ac97_codec_id snd_ac97_codec_ids[] = {
 { 0x414b4d00, 0xffffffff, "AK4540",		NULL,		NULL },
 { 0x414b4d01, 0xffffffff, "AK4542",		NULL,		NULL },
 { 0x414b4d02, 0xffffffff, "AK4543",		NULL,		NULL },
@@ -137,7 +137,7 @@
 { 0x43585421, 0xffffffff, "HSD11246",		NULL,		NULL },	// SmartMC II
 { 0x43585428, 0xfffffff8, "Cx20468",		patch_conexant,	NULL }, // SmartAMC fixme: the mask might be different
 { 0x44543031, 0xfffffff0, "DT0398",		NULL,		NULL },
-{ 0x454d4328, 0xffffffff, "28028",		NULL,		NULL },  // same as TR28028?
+{ 0x454d4328, 0xffffffff, "EM28028",		NULL,		NULL },  // same as TR28028?
 { 0x45838308, 0xffffffff, "ESS1988",		NULL,		NULL },
 { 0x48525300, 0xffffff00, "HMP9701",		NULL,		NULL },
 { 0x49434501, 0xffffffff, "ICE1230",		NULL,		NULL },
@@ -184,48 +184,12 @@
 { 0, 	      0,	  NULL,			NULL,		NULL }
 };
 
-const char *snd_ac97_stereo_enhancements[] =
-{
-  /*   0 */ "No 3D Stereo Enhancement",
-  /*   1 */ "Analog Devices Phat Stereo",
-  /*   2 */ "Creative Stereo Enhancement",
-  /*   3 */ "National Semi 3D Stereo Enhancement",
-  /*   4 */ "YAMAHA Ymersion",
-  /*   5 */ "BBE 3D Stereo Enhancement",
-  /*   6 */ "Crystal Semi 3D Stereo Enhancement",
-  /*   7 */ "Qsound QXpander",
-  /*   8 */ "Spatializer 3D Stereo Enhancement",
-  /*   9 */ "SRS 3D Stereo Enhancement",
-  /*  10 */ "Platform Tech 3D Stereo Enhancement",
-  /*  11 */ "AKM 3D Audio",
-  /*  12 */ "Aureal Stereo Enhancement",
-  /*  13 */ "Aztech 3D Enhancement",
-  /*  14 */ "Binaura 3D Audio Enhancement",
-  /*  15 */ "ESS Technology Stereo Enhancement",
-  /*  16 */ "Harman International VMAx",
-  /*  17 */ "Nvidea/IC Ensemble/KS Waves 3D Stereo Enhancement",
-  /*  18 */ "Philips Incredible Sound",
-  /*  19 */ "Texas Instruments 3D Stereo Enhancement",
-  /*  20 */ "VLSI Technology 3D Stereo Enhancement",
-  /*  21 */ "TriTech 3D Stereo Enhancement",
-  /*  22 */ "Realtek 3D Stereo Enhancement",
-  /*  23 */ "Samsung 3D Stereo Enhancement",
-  /*  24 */ "Wolfson Microelectronics 3D Enhancement",
-  /*  25 */ "Delta Integration 3D Enhancement",
-  /*  26 */ "SigmaTel 3D Enhancement",
-  /*  27 */ "IC Ensemble/KS Waves",
-  /*  28 */ "Rockwell 3D Stereo Enhancement",
-  /*  29 */ "Reserved 29",
-  /*  30 */ "Reserved 30",
-  /*  31 */ "Reserved 31"
-};
-
 
 /*
  *  I/O routines
  */
 
-static int snd_ac97_valid_reg(ac97_t *ac97, unsigned short reg)
+static int snd_ac97_valid_reg(struct snd_ac97 *ac97, unsigned short reg)
 {
 	if (ac97->limited_regs && ! test_bit(reg, ac97->reg_accessed))
   		return 0;
@@ -278,7 +242,7 @@
  * #snd_ca97_write_cache(), so use this only when you don't want to
  * reflect the change to the suspend/resume state.
  */
-void snd_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short value)
+void snd_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short value)
 {
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return;
@@ -301,7 +265,7 @@
  *
  * Returns the read value.
  */
-unsigned short snd_ac97_read(ac97_t *ac97, unsigned short reg)
+unsigned short snd_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return 0;
@@ -309,7 +273,7 @@
 }
 
 /* read a register - return the cached value if already read */
-static inline unsigned short snd_ac97_read_cache(ac97_t *ac97, unsigned short reg)
+static inline unsigned short snd_ac97_read_cache(struct snd_ac97 *ac97, unsigned short reg)
 {
 	if (! test_bit(reg, ac97->reg_accessed)) {
 		ac97->regs[reg] = ac97->bus->ops->read(ac97, reg);
@@ -328,7 +292,7 @@
  * cache.  The cached values are used for the cached-read and the
  * suspend/resume.
  */
-void snd_ac97_write_cache(ac97_t *ac97, unsigned short reg, unsigned short value)
+void snd_ac97_write_cache(struct snd_ac97 *ac97, unsigned short reg, unsigned short value)
 {
 	if (!snd_ac97_valid_reg(ac97, reg))
 		return;
@@ -351,7 +315,7 @@
  * Returns 1 if the value is changed, 0 if no change, or a negative
  * code on failure.
  */
-int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value)
+int snd_ac97_update(struct snd_ac97 *ac97, unsigned short reg, unsigned short value)
 {
 	int change;
 
@@ -381,7 +345,7 @@
  * Returns 1 if the bits are changed, 0 if no change, or a negative
  * code on failure.
  */
-int snd_ac97_update_bits(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value)
+int snd_ac97_update_bits(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value)
 {
 	int change;
 
@@ -394,7 +358,7 @@
 }
 
 /* no lock version - see snd_ac97_updat_bits() */
-int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg,
+int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
 				unsigned short mask, unsigned short value)
 {
 	int change;
@@ -411,7 +375,7 @@
 	return change;
 }
 
-static int snd_ac97_ad18xx_update_pcm_bits(ac97_t *ac97, int codec, unsigned short mask, unsigned short value)
+static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, unsigned short mask, unsigned short value)
 {
 	int change;
 	unsigned short old, new, cfg;
@@ -443,7 +407,7 @@
  * Controls
  */
 
-int snd_ac97_info_enum_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
 	
@@ -457,9 +421,9 @@
 	return 0;
 }
 
-int snd_ac97_get_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
 	unsigned short val, bitmask;
 	
@@ -473,9 +437,9 @@
 	return 0;
 }
 
-int snd_ac97_put_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value;
 	unsigned short val;
 	unsigned short mask, bitmask;
@@ -496,7 +460,7 @@
 }
 
 /* save/restore ac97 v2.3 paging */
-static int snd_ac97_page_save(ac97_t *ac97, int reg, snd_kcontrol_t *kcontrol)
+static int snd_ac97_page_save(struct snd_ac97 *ac97, int reg, struct snd_kcontrol *kcontrol)
 {
 	int page_save = -1;
 	if ((kcontrol->private_value & (1<<25)) &&
@@ -510,7 +474,7 @@
 	return page_save;
 }
 
-static void snd_ac97_page_restore(ac97_t *ac97, int page_save)
+static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save)
 {
 	if (page_save >= 0) {
 		snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, page_save);
@@ -519,7 +483,7 @@
 }
 
 /* volume and switch controls */
-int snd_ac97_info_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0x0f;
@@ -532,9 +496,9 @@
 	return 0;
 }
 
-int snd_ac97_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0x0f;
 	int rshift = (kcontrol->private_value >> 12) & 0x0f;
@@ -555,9 +519,9 @@
 	return 0;
 }
 
-int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0x0f;
 	int rshift = (kcontrol->private_value >> 12) & 0x0f;
@@ -584,22 +548,22 @@
 	return err;
 }
 
-static const snd_kcontrol_new_t snd_ac97_controls_master_mono[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_master_mono[2] = {
 AC97_SINGLE("Master Mono Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
 AC97_SINGLE("Master Mono Playback Volume", AC97_MASTER_MONO, 0, 31, 1)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_tone[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_tone[2] = {
 AC97_SINGLE("Tone Control - Bass", AC97_MASTER_TONE, 8, 15, 1),
 AC97_SINGLE("Tone Control - Treble", AC97_MASTER_TONE, 0, 15, 1)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_pc_beep[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_pc_beep[2] = {
 AC97_SINGLE("PC Speaker Playback Switch", AC97_PC_BEEP, 15, 1, 1),
 AC97_SINGLE("PC Speaker Playback Volume", AC97_PC_BEEP, 1, 15, 1)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_mic_boost =
+static const struct snd_kcontrol_new snd_ac97_controls_mic_boost =
 	AC97_SINGLE("Mic Boost (+20dB)", AC97_MIC, 6, 1, 0);
 
 
@@ -615,18 +579,18 @@
 AC97_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, std_mic),
 };
 
-static const snd_kcontrol_new_t snd_ac97_control_capture_src = 
+static const struct snd_kcontrol_new snd_ac97_control_capture_src = 
 AC97_ENUM("Capture Source", std_enum[0]); 
 
-static const snd_kcontrol_new_t snd_ac97_control_capture_vol =
+static const struct snd_kcontrol_new snd_ac97_control_capture_vol =
 AC97_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 15, 0);
 
-static const snd_kcontrol_new_t snd_ac97_controls_mic_capture[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_mic_capture[2] = {
 AC97_SINGLE("Mic Capture Switch", AC97_REC_GAIN_MIC, 15, 1, 1),
 AC97_SINGLE("Mic Capture Volume", AC97_REC_GAIN_MIC, 0, 15, 0)
 };
 
-typedef enum {
+enum {
 	AC97_GENERAL_PCM_OUT = 0,
 	AC97_GENERAL_STEREO_ENHANCEMENT,
 	AC97_GENERAL_3D,
@@ -634,9 +598,9 @@
 	AC97_GENERAL_MONO,
 	AC97_GENERAL_MIC,
 	AC97_GENERAL_LOOPBACK
-} ac97_general_index_t;
+};
 
-static const snd_kcontrol_new_t snd_ac97_controls_general[7] = {
+static const struct snd_kcontrol_new snd_ac97_controls_general[7] = {
 AC97_ENUM("PCM Out Path & Mute", std_enum[1]),
 AC97_SINGLE("Simulated Stereo Enhancement", AC97_GENERAL_PURPOSE, 14, 1, 0),
 AC97_SINGLE("3D Control - Switch", AC97_GENERAL_PURPOSE, 13, 1, 0),
@@ -646,45 +610,45 @@
 AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0)
 };
 
-const snd_kcontrol_new_t snd_ac97_controls_3d[2] = {
+const struct snd_kcontrol_new snd_ac97_controls_3d[2] = {
 AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0),
 AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_center[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_center[2] = {
 AC97_SINGLE("Center Playback Switch", AC97_CENTER_LFE_MASTER, 7, 1, 1),
 AC97_SINGLE("Center Playback Volume", AC97_CENTER_LFE_MASTER, 0, 31, 1)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_lfe[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_lfe[2] = {
 AC97_SINGLE("LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 1, 1),
 AC97_SINGLE("LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 31, 1)
 };
 
-static const snd_kcontrol_new_t snd_ac97_control_eapd =
+static const struct snd_kcontrol_new snd_ac97_control_eapd =
 AC97_SINGLE("External Amplifier", AC97_POWERDOWN, 15, 1, 1);
 
-static const snd_kcontrol_new_t snd_ac97_controls_modem_switches[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_modem_switches[2] = {
 AC97_SINGLE("Off-hook Switch", AC97_GPIO_STATUS, 0, 1, 0),
 AC97_SINGLE("Caller ID Switch", AC97_GPIO_STATUS, 2, 1, 0)
 };
 
 /* change the existing EAPD control as inverted */
-static void set_inv_eapd(ac97_t *ac97, snd_kcontrol_t *kctl)
+static void set_inv_eapd(struct snd_ac97 *ac97, struct snd_kcontrol *kctl)
 {
 	kctl->private_value = AC97_SINGLE_VALUE(AC97_POWERDOWN, 15, 1, 0);
 	snd_ac97_update_bits(ac97, AC97_POWERDOWN, (1<<15), (1<<15)); /* EAPD up */
 	ac97->scaps |= AC97_SCAP_INV_EAPD;
 }
 
-static int snd_ac97_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ac97_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
                         
-static int snd_ac97_spdif_cmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
 					   IEC958_AES0_NONAUDIO |
@@ -696,7 +660,7 @@
 	return 0;
 }
                         
-static int snd_ac97_spdif_pmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	/* FIXME: AC'97 spec doesn't say which bits are used for what */
 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
@@ -706,9 +670,9 @@
 	return 0;
 }
 
-static int snd_ac97_spdif_default_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	down(&ac97->reg_mutex);
 	ucontrol->value.iec958.status[0] = ac97->spdif_status & 0xff;
@@ -719,9 +683,9 @@
 	return 0;
 }
                         
-static int snd_ac97_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned int new = 0;
 	unsigned short val = 0;
 	int change;
@@ -787,9 +751,9 @@
 	return change;
 }
 
-static int snd_ac97_put_spsa(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -817,7 +781,7 @@
 	return change;
 }
 
-const snd_kcontrol_new_t snd_ac97_controls_spdif[5] = {
+const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = {
 	{
 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -856,9 +820,9 @@
   .get = snd_ac97_ad18xx_pcm_get_bits, .put = snd_ac97_ad18xx_pcm_put_bits, \
   .private_value = (codec) | ((lshift) << 8) | ((rshift) << 12) | ((mask) << 16) }
 
-static int snd_ac97_ad18xx_pcm_info_bits(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ac97_ad18xx_pcm_info_bits(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int mask = (kcontrol->private_value >> 16) & 0x0f;
 	int lshift = (kcontrol->private_value >> 8) & 0x0f;
 	int rshift = (kcontrol->private_value >> 12) & 0x0f;
@@ -873,9 +837,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad18xx_pcm_get_bits(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ad18xx_pcm_get_bits(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int codec = kcontrol->private_value & 3;
 	int lshift = (kcontrol->private_value >> 8) & 0x0f;
 	int rshift = (kcontrol->private_value >> 12) & 0x0f;
@@ -887,9 +851,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad18xx_pcm_put_bits(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ad18xx_pcm_put_bits(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int codec = kcontrol->private_value & 3;
 	int lshift = (kcontrol->private_value >> 8) & 0x0f;
 	int rshift = (kcontrol->private_value >> 12) & 0x0f;
@@ -910,7 +874,7 @@
   .get = snd_ac97_ad18xx_pcm_get_volume, .put = snd_ac97_ad18xx_pcm_put_volume, \
   .private_value = codec }
 
-static int snd_ac97_ad18xx_pcm_info_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ac97_ad18xx_pcm_info_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -919,9 +883,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad18xx_pcm_get_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ad18xx_pcm_get_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int codec = kcontrol->private_value & 3;
 	
 	down(&ac97->page_mutex);
@@ -931,9 +895,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad18xx_pcm_put_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ad18xx_pcm_put_volume(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int codec = kcontrol->private_value & 3;
 	unsigned short val1, val2;
 	
@@ -942,22 +906,22 @@
 	return snd_ac97_ad18xx_update_pcm_bits(ac97, codec, 0x1f1f, (val1 << 8) | val2);
 }
 
-static const snd_kcontrol_new_t snd_ac97_controls_ad18xx_pcm[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_ad18xx_pcm[2] = {
 AD18XX_PCM_BITS("PCM Playback Switch", 0, 15, 7, 1),
 AD18XX_PCM_VOLUME("PCM Playback Volume", 0)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_ad18xx_surround[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_ad18xx_surround[2] = {
 AD18XX_PCM_BITS("Surround Playback Switch", 1, 15, 7, 1),
 AD18XX_PCM_VOLUME("Surround Playback Volume", 1)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_ad18xx_center[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_ad18xx_center[2] = {
 AD18XX_PCM_BITS("Center Playback Switch", 2, 15, 15, 1),
 AD18XX_PCM_BITS("Center Playback Volume", 2, 8, 8, 31)
 };
 
-static const snd_kcontrol_new_t snd_ac97_controls_ad18xx_lfe[2] = {
+static const struct snd_kcontrol_new snd_ac97_controls_ad18xx_lfe[2] = {
 AD18XX_PCM_BITS("LFE Playback Switch", 2, 7, 7, 1),
 AD18XX_PCM_BITS("LFE Playback Volume", 2, 0, 0, 31)
 };
@@ -966,9 +930,9 @@
  *
  */
 
-static void snd_ac97_powerdown(ac97_t *ac97);
+static void snd_ac97_powerdown(struct snd_ac97 *ac97);
 
-static int snd_ac97_bus_free(ac97_bus_t *bus)
+static int snd_ac97_bus_free(struct snd_ac97_bus *bus)
 {
 	if (bus) {
 		snd_ac97_bus_proc_done(bus);
@@ -980,13 +944,13 @@
 	return 0;
 }
 
-static int snd_ac97_bus_dev_free(snd_device_t *device)
+static int snd_ac97_bus_dev_free(struct snd_device *device)
 {
-	ac97_bus_t *bus = device->device_data;
+	struct snd_ac97_bus *bus = device->device_data;
 	return snd_ac97_bus_free(bus);
 }
 
-static int snd_ac97_free(ac97_t *ac97)
+static int snd_ac97_free(struct snd_ac97 *ac97)
 {
 	if (ac97) {
 		snd_ac97_proc_done(ac97);
@@ -999,14 +963,14 @@
 	return 0;
 }
 
-static int snd_ac97_dev_free(snd_device_t *device)
+static int snd_ac97_dev_free(struct snd_device *device)
 {
-	ac97_t *ac97 = device->device_data;
+	struct snd_ac97 *ac97 = device->device_data;
 	snd_ac97_powerdown(ac97); /* for avoiding click noises during shut down */
 	return snd_ac97_free(ac97);
 }
 
-static int snd_ac97_try_volume_mix(ac97_t * ac97, int reg)
+static int snd_ac97_try_volume_mix(struct snd_ac97 * ac97, int reg)
 {
 	unsigned short val, mask = 0x8000;
 
@@ -1052,13 +1016,14 @@
 		/* try another test */
 		snd_ac97_write_cache(ac97, reg, val | mask);
 		val = snd_ac97_read(ac97, reg);
+		val = snd_ac97_read(ac97, reg);
 		if (!(val & mask))
 			return 0;	/* nothing here */
 	}
 	return 1;		/* success, useable */
 }
 
-static void check_volume_resolution(ac97_t *ac97, int reg, unsigned char *lo_max, unsigned char *hi_max)
+static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned char *lo_max, unsigned char *hi_max)
 {
 	unsigned short cbit[3] = { 0x20, 0x10, 0x01 };
 	unsigned char max[3] = { 63, 31, 15 };
@@ -1083,7 +1048,7 @@
 	}
 }
 
-int snd_ac97_try_bit(ac97_t * ac97, int reg, int bit)
+int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit)
 {
 	unsigned short mask, val, orig, res;
 
@@ -1097,7 +1062,7 @@
 }
 
 /* check the volume resolution of center/lfe */
-static void snd_ac97_change_volume_params2(ac97_t * ac97, int reg, int shift, unsigned char *max)
+static void snd_ac97_change_volume_params2(struct snd_ac97 * ac97, int reg, int shift, unsigned char *max)
 {
 	unsigned short val, val1;
 
@@ -1123,9 +1088,9 @@
 	return x;
 }
 
-snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97)
+struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97)
 {
-	snd_kcontrol_new_t template;
+	struct snd_kcontrol_new template;
 	memcpy(&template, _template, sizeof(template));
 	template.index = ac97->num;
 	return snd_ctl_new1(&template, ac97);
@@ -1134,9 +1099,9 @@
 /*
  * create mute switch(es) for normal stereo controls
  */
-static int snd_ac97_cmute_new_stereo(snd_card_t *card, char *name, int reg, int check_stereo, ac97_t *ac97)
+static int snd_ac97_cmute_new_stereo(struct snd_card *card, char *name, int reg, int check_stereo, struct snd_ac97 *ac97)
 {
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 	int err;
 	unsigned short val, val1, mute_mask;
 
@@ -1153,11 +1118,11 @@
 			mute_mask = 0x8080;
 	}
 	if (mute_mask == 0x8080) {
-		snd_kcontrol_new_t tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1);
+		struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1);
 		tmp.index = ac97->num;
 		kctl = snd_ctl_new1(&tmp, ac97);
 	} else {
-		snd_kcontrol_new_t tmp = AC97_SINGLE(name, reg, 15, 1, 1);
+		struct snd_kcontrol_new tmp = AC97_SINGLE(name, reg, 15, 1, 1);
 		tmp.index = ac97->num;
 		kctl = snd_ctl_new1(&tmp, ac97);
 	}
@@ -1172,22 +1137,22 @@
 /*
  * create a volume for normal stereo/mono controls
  */
-static int snd_ac97_cvol_new(snd_card_t *card, char *name, int reg, unsigned int lo_max,
-			     unsigned int hi_max, ac97_t *ac97)
+static int snd_ac97_cvol_new(struct snd_card *card, char *name, int reg, unsigned int lo_max,
+			     unsigned int hi_max, struct snd_ac97 *ac97)
 {
 	int err;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	if (! snd_ac97_valid_reg(ac97, reg))
 		return 0;
 	if (hi_max) {
 		/* invert */
-		snd_kcontrol_new_t tmp = AC97_DOUBLE(name, reg, 8, 0, lo_max, 1);
+		struct snd_kcontrol_new tmp = AC97_DOUBLE(name, reg, 8, 0, lo_max, 1);
 		tmp.index = ac97->num;
 		kctl = snd_ctl_new1(&tmp, ac97);
 	} else {
 		/* invert */
-		snd_kcontrol_new_t tmp = AC97_SINGLE(name, reg, 0, lo_max, 1);
+		struct snd_kcontrol_new tmp = AC97_SINGLE(name, reg, 0, lo_max, 1);
 		tmp.index = ac97->num;
 		kctl = snd_ctl_new1(&tmp, ac97);
 	}
@@ -1203,7 +1168,7 @@
 /*
  * create a mute-switch and a volume for normal stereo/mono controls
  */
-static int snd_ac97_cmix_new_stereo(snd_card_t *card, const char *pfx, int reg, int check_stereo, ac97_t *ac97)
+static int snd_ac97_cmix_new_stereo(struct snd_card *card, const char *pfx, int reg, int check_stereo, struct snd_ac97 *ac97)
 {
 	int err;
 	char name[44];
@@ -1229,12 +1194,12 @@
 #define snd_ac97_cmix_new(card, pfx, reg, ac97)	snd_ac97_cmix_new_stereo(card, pfx, reg, 0, ac97)
 #define snd_ac97_cmute_new(card, name, reg, ac97)	snd_ac97_cmute_new_stereo(card, name, reg, 0, ac97)
 
-static unsigned int snd_ac97_determine_spdif_rates(ac97_t *ac97);
+static unsigned int snd_ac97_determine_spdif_rates(struct snd_ac97 *ac97);
 
-static int snd_ac97_mixer_build(ac97_t * ac97)
+static int snd_ac97_mixer_build(struct snd_ac97 * ac97)
 {
-	snd_card_t *card = ac97->bus->card;
-	snd_kcontrol_t *kctl;
+	struct snd_card *card = ac97->bus->card;
+	struct snd_kcontrol *kctl;
 	int err;
 	unsigned int idx;
 	unsigned char max;
@@ -1531,7 +1496,7 @@
 	return 0;
 }
 
-static int snd_ac97_modem_build(snd_card_t * card, ac97_t * ac97)
+static int snd_ac97_modem_build(struct snd_card *card, struct snd_ac97 * ac97)
 {
 	int err, idx;
 
@@ -1555,7 +1520,7 @@
 	return 0;
 }
 
-static int snd_ac97_test_rate(ac97_t *ac97, int reg, int shadow_reg, int rate)
+static int snd_ac97_test_rate(struct snd_ac97 *ac97, int reg, int shadow_reg, int rate)
 {
 	unsigned short val;
 	unsigned int tmp;
@@ -1568,7 +1533,7 @@
 	return val == (tmp & 0xffff);
 }
 
-static void snd_ac97_determine_rates(ac97_t *ac97, int reg, int shadow_reg, unsigned int *r_result)
+static void snd_ac97_determine_rates(struct snd_ac97 *ac97, int reg, int shadow_reg, unsigned int *r_result)
 {
 	unsigned int result = 0;
 	unsigned short saved;
@@ -1628,7 +1593,7 @@
 }
 
 /* check AC97_SPDIF register to accept which sample rates */
-static unsigned int snd_ac97_determine_spdif_rates(ac97_t *ac97)
+static unsigned int snd_ac97_determine_spdif_rates(struct snd_ac97 *ac97)
 {
 	unsigned int result = 0;
 	int i;
@@ -1648,10 +1613,10 @@
 }
 
 /* look for the codec id table matching with the given id */
-static const ac97_codec_id_t *look_for_codec_id(const ac97_codec_id_t *table,
-						unsigned int id)
+static const struct ac97_codec_id *look_for_codec_id(const struct ac97_codec_id *table,
+						     unsigned int id)
 {
-	const ac97_codec_id_t *pid;
+	const struct ac97_codec_id *pid;
 
 	for (pid = table; pid->id; pid++)
 		if (pid->id == (id & pid->mask))
@@ -1659,9 +1624,9 @@
 	return NULL;
 }
 
-void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem)
+void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem)
 {
-	const ac97_codec_id_t *pid;
+	const struct ac97_codec_id *pid;
 
 	sprintf(name, "0x%x %c%c%c", id,
 		printable(id >> 24),
@@ -1699,9 +1664,9 @@
  *
  * Returns the short identifying name of the codec.
  */
-const char *snd_ac97_get_short_name(ac97_t *ac97)
+const char *snd_ac97_get_short_name(struct snd_ac97 *ac97)
 {
-	const ac97_codec_id_t *pid;
+	const struct ac97_codec_id *pid;
 
 	for (pid = snd_ac97_codec_ids; pid->id; pid++)
 		if (pid->id == (ac97->id & pid->mask))
@@ -1713,7 +1678,7 @@
 /* wait for a while until registers are accessible after RESET
  * return 0 if ok, negative not ready
  */
-static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem)
+static int ac97_reset_wait(struct snd_ac97 *ac97, int timeout, int with_modem)
 {
 	unsigned long end_time;
 	unsigned short val;
@@ -1758,7 +1723,7 @@
  * @private_data: private data pointer for the new instance
  * @rbus: the pointer to store the new AC97 bus instance.
  *
- * Creates an AC97 bus component.  An ac97_bus_t instance is newly
+ * Creates an AC97 bus component.  An struct snd_ac97_bus instance is newly
  * allocated and initialized.
  *
  * The ops table must include valid callbacks (at least read and
@@ -1772,12 +1737,12 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_ac97_bus(snd_card_t *card, int num, ac97_bus_ops_t *ops,
-		 void *private_data, ac97_bus_t **rbus)
+int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops,
+		 void *private_data, struct snd_ac97_bus **rbus)
 {
 	int err;
-	ac97_bus_t *bus;
-	static snd_device_ops_t dev_ops = {
+	struct snd_ac97_bus *bus;
+	static struct snd_device_ops dev_ops = {
 		.dev_free =	snd_ac97_bus_dev_free,
 	};
 
@@ -1807,15 +1772,17 @@
 }
 
 /* register ac97 codec to bus */
-static int snd_ac97_dev_register(snd_device_t *device)
+static int snd_ac97_dev_register(struct snd_device *device)
 {
-	ac97_t *ac97 = device->device_data;
+	struct snd_ac97 *ac97 = device->device_data;
 	int err;
 
 	ac97->dev.bus = &ac97_bus_type;
 	ac97->dev.parent = ac97->bus->card->dev;
 	ac97->dev.release = ac97_device_release;
-	snprintf(ac97->dev.bus_id, BUS_ID_SIZE, "card%d-%d", ac97->bus->card->number, ac97->num);
+	snprintf(ac97->dev.bus_id, BUS_ID_SIZE, "%d-%d:%s",
+		 ac97->bus->card->number, ac97->num,
+		 snd_ac97_get_short_name(ac97));
 	if ((err = device_register(&ac97->dev)) < 0) {
 		snd_printk(KERN_ERR "Can't register ac97 bus\n");
 		ac97->dev.bus = NULL;
@@ -1825,9 +1792,9 @@
 }
 
 /* unregister ac97 codec */
-static int snd_ac97_dev_unregister(snd_device_t *device)
+static int snd_ac97_dev_unregister(struct snd_device *device)
 {
-	ac97_t *ac97 = device->device_data;
+	struct snd_ac97 *ac97 = device->device_data;
 	if (ac97->dev.bus)
 		device_unregister(&ac97->dev);
 	return snd_ac97_free(ac97);
@@ -1843,7 +1810,7 @@
  *         the private data.
  * @rac97: the pointer to store the new ac97 instance.
  *
- * Creates an Codec97 component.  An ac97_t instance is newly
+ * Creates an Codec97 component.  An struct snd_ac97 instance is newly
  * allocated and initialized from the template.  The codec
  * is then initialized by the standard procedure.
  *
@@ -1855,16 +1822,16 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
+int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, struct snd_ac97 **rac97)
 {
 	int err;
-	ac97_t *ac97;
-	snd_card_t *card;
+	struct snd_ac97 *ac97;
+	struct snd_card *card;
 	char name[64];
 	unsigned long end_time;
 	unsigned int reg;
-	const ac97_codec_id_t *pid;
-	static snd_device_ops_t ops = {
+	const struct ac97_codec_id *pid;
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_ac97_dev_free,
 		.dev_register =	snd_ac97_dev_register,
 		.dev_unregister =	snd_ac97_dev_unregister,
@@ -1892,10 +1859,12 @@
 	init_MUTEX(&ac97->reg_mutex);
 	init_MUTEX(&ac97->page_mutex);
 
+#ifdef CONFIG_PCI
 	if (ac97->pci) {
 		pci_read_config_word(ac97->pci, PCI_SUBSYSTEM_VENDOR_ID, &ac97->subsystem_vendor);
 		pci_read_config_word(ac97->pci, PCI_SUBSYSTEM_ID, &ac97->subsystem_device);
 	}
+#endif
 	if (bus->ops->reset) {
 		bus->ops->reset(ac97);
 		goto __access_ok;
@@ -2148,7 +2117,7 @@
  * MASTER and HEADPHONE registers are muted but the register cache values
  * are not changed, so that the values can be restored in snd_ac97_resume().
  */
-static void snd_ac97_powerdown(ac97_t *ac97)
+static void snd_ac97_powerdown(struct snd_ac97 *ac97)
 {
 	unsigned short power;
 
@@ -2181,8 +2150,10 @@
  *
  * Suspends the codec, power down the chip.
  */
-void snd_ac97_suspend(ac97_t *ac97)
+void snd_ac97_suspend(struct snd_ac97 *ac97)
 {
+	if (! ac97)
+		return;
 	if (ac97->build_ops->suspend)
 		ac97->build_ops->suspend(ac97);
 	snd_ac97_powerdown(ac97);
@@ -2191,7 +2162,7 @@
 /*
  * restore ac97 status
  */
-void snd_ac97_restore_status(ac97_t *ac97)
+void snd_ac97_restore_status(struct snd_ac97 *ac97)
 {
 	int i;
 
@@ -2212,7 +2183,7 @@
 /*
  * restore IEC958 status
  */
-void snd_ac97_restore_iec958(ac97_t *ac97)
+void snd_ac97_restore_iec958(struct snd_ac97 *ac97)
 {
 	if (ac97->ext_id & AC97_EI_SPDIF) {
 		if (ac97->regs[AC97_EXTENDED_STATUS] & AC97_EA_SPDIF) {
@@ -2235,10 +2206,13 @@
  * Do the standard resume procedure, power up and restoring the
  * old register values.
  */
-void snd_ac97_resume(ac97_t *ac97)
+void snd_ac97_resume(struct snd_ac97 *ac97)
 {
 	unsigned long end_time;
 
+	if (! ac97)
+		return;
+
 	if (ac97->bus->ops->reset) {
 		ac97->bus->ops->reset(ac97);
 		goto  __reset_ready;
@@ -2301,18 +2275,18 @@
 }	
 
 /* remove the control with the given name and optional suffix */
-int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix)
+int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix)
 {
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 	memset(&id, 0, sizeof(id));
 	set_ctl_name(id.name, name, suffix);
 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_remove_id(ac97->bus->card, &id);
 }
 
-static snd_kcontrol_t *ctl_find(ac97_t *ac97, const char *name, const char *suffix)
+static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, const char *suffix)
 {
-	snd_ctl_elem_id_t sid;
+	struct snd_ctl_elem_id sid;
 	memset(&sid, 0, sizeof(sid));
 	set_ctl_name(sid.name, name, suffix);
 	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -2320,9 +2294,9 @@
 }
 
 /* rename the control with the given name and optional suffix */
-int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix)
+int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix)
 {
-	snd_kcontrol_t *kctl = ctl_find(ac97, src, suffix);
+	struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix);
 	if (kctl) {
 		set_ctl_name(kctl->id.name, dst, suffix);
 		return 0;
@@ -2331,16 +2305,16 @@
 }
 
 /* rename both Volume and Switch controls - don't check the return value */
-void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst)
+void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst)
 {
 	snd_ac97_rename_ctl(ac97, src, dst, "Switch");
 	snd_ac97_rename_ctl(ac97, src, dst, "Volume");
 }
 
 /* swap controls */
-int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *suffix)
+int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix)
 {
-	snd_kcontrol_t *kctl1, *kctl2;
+	struct snd_kcontrol *kctl1, *kctl2;
 	kctl1 = ctl_find(ac97, s1, suffix);
 	kctl2 = ctl_find(ac97, s2, suffix);
 	if (kctl1 && kctl2) {
@@ -2353,7 +2327,7 @@
 
 #if 1
 /* bind hp and master controls instead of using only hp control */
-static int bind_hp_volsw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int bind_hp_volsw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	int err = snd_ac97_put_volsw(kcontrol, ucontrol);
 	if (err > 0) {
@@ -2366,10 +2340,10 @@
 }
 
 /* ac97 tune: bind Master and Headphone controls */
-static int tune_hp_only(ac97_t *ac97)
+static int tune_hp_only(struct snd_ac97 *ac97)
 {
-	snd_kcontrol_t *msw = ctl_find(ac97, "Master Playback Switch", NULL);
-	snd_kcontrol_t *mvol = ctl_find(ac97, "Master Playback Volume", NULL);
+	struct snd_kcontrol *msw = ctl_find(ac97, "Master Playback Switch", NULL);
+	struct snd_kcontrol *mvol = ctl_find(ac97, "Master Playback Volume", NULL);
 	if (! msw || ! mvol)
 		return -ENOENT;
 	msw->put = bind_hp_volsw_put;
@@ -2381,7 +2355,7 @@
 
 #else
 /* ac97 tune: use Headphone control as master */
-static int tune_hp_only(ac97_t *ac97)
+static int tune_hp_only(struct snd_ac97 *ac97)
 {
 	if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
 		return -ENOENT;
@@ -2393,7 +2367,7 @@
 #endif
 
 /* ac97 tune: swap Headphone and Master controls */
-static int tune_swap_hp(ac97_t *ac97)
+static int tune_swap_hp(struct snd_ac97 *ac97)
 {
 	if (ctl_find(ac97, "Headphone Playback Switch", NULL) == NULL)
 		return -ENOENT;
@@ -2403,7 +2377,7 @@
 }
 
 /* ac97 tune: swap Surround and Master controls */
-static int tune_swap_surround(ac97_t *ac97)
+static int tune_swap_surround(struct snd_ac97 *ac97)
 {
 	if (snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Switch") ||
 	    snd_ac97_swap_ctl(ac97, "Master Playback", "Surround Playback", "Volume"))
@@ -2412,7 +2386,7 @@
 }
 
 /* ac97 tune: set up mic sharing for AD codecs */
-static int tune_ad_sharing(ac97_t *ac97)
+static int tune_ad_sharing(struct snd_ac97 *ac97)
 {
 	unsigned short scfg;
 	if ((ac97->id & 0xffffff00) != 0x41445300) {
@@ -2425,11 +2399,11 @@
 	return 0;
 }
 
-static const snd_kcontrol_new_t snd_ac97_alc_jack_detect = 
+static const struct snd_kcontrol_new snd_ac97_alc_jack_detect = 
 AC97_SINGLE("Jack Detect", AC97_ALC650_CLOCK, 5, 1, 0);
 
 /* ac97 tune: set up ALC jack-select */
-static int tune_alc_jack(ac97_t *ac97)
+static int tune_alc_jack(struct snd_ac97 *ac97)
 {
 	if ((ac97->id & 0xffffff00) != 0x414c4700) {
 		snd_printk(KERN_ERR "ac97_quirk ALC_JACK is only for Realtek codecs\n");
@@ -2437,24 +2411,26 @@
 	}
 	snd_ac97_update_bits(ac97, 0x7a, 0x20, 0x20); /* select jack detect function */
 	snd_ac97_update_bits(ac97, 0x7a, 0x01, 0x01); /* Line-out auto mute */
+	if (ac97->id == AC97_ID_ALC658D)
+		snd_ac97_update_bits(ac97, 0x74, 0x0800, 0x0800);
 	return snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&snd_ac97_alc_jack_detect, ac97));
 }
 
 /* ac97 tune: inversed EAPD bit */
-static int tune_inv_eapd(ac97_t *ac97)
+static int tune_inv_eapd(struct snd_ac97 *ac97)
 {
-	snd_kcontrol_t *kctl = ctl_find(ac97, "External Amplifier", NULL);
+	struct snd_kcontrol *kctl = ctl_find(ac97, "External Amplifier", NULL);
 	if (! kctl)
 		return -ENOENT;
 	set_inv_eapd(ac97, kctl);
 	return 0;
 }
 
-static int master_mute_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int master_mute_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	int err = snd_ac97_put_volsw(kcontrol, ucontrol);
 	if (err > 0) {
-		ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+		struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 		int shift = (kcontrol->private_value >> 8) & 0x0f;
 		int rshift = (kcontrol->private_value >> 12) & 0x0f;
 		unsigned short mask;
@@ -2470,9 +2446,9 @@
 }
 
 /* ac97 tune: EAPD controls mute LED bound with the master mute */
-static int tune_mute_led(ac97_t *ac97)
+static int tune_mute_led(struct snd_ac97 *ac97)
 {
-	snd_kcontrol_t *msw = ctl_find(ac97, "Master Playback Switch", NULL);
+	struct snd_kcontrol *msw = ctl_find(ac97, "Master Playback Switch", NULL);
 	if (! msw)
 		return -ENOENT;
 	msw->put = master_mute_sw_put;
@@ -2481,9 +2457,44 @@
 	return 0;
 }
 
+static int hp_master_mute_sw_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	int err = bind_hp_volsw_put(kcontrol, ucontrol);
+	if (err > 0) {
+		struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
+		int shift = (kcontrol->private_value >> 8) & 0x0f;
+		int rshift = (kcontrol->private_value >> 12) & 0x0f;
+		unsigned short mask;
+		if (shift != rshift)
+			mask = 0x8080;
+		else
+			mask = 0x8000;
+		snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000,
+				     (ac97->regs[AC97_MASTER] & mask) == mask ?
+				     0x8000 : 0);
+	}
+	return err;
+}
+
+static int tune_hp_mute_led(struct snd_ac97 *ac97)
+{
+	struct snd_kcontrol *msw = ctl_find(ac97, "Master Playback Switch", NULL);
+	struct snd_kcontrol *mvol = ctl_find(ac97, "Master Playback Volume", NULL);
+	if (! msw || ! mvol)
+		return -ENOENT;
+	msw->put = hp_master_mute_sw_put;
+	mvol->put = bind_hp_volsw_put;
+	snd_ac97_remove_ctl(ac97, "External Amplifier", NULL);
+	snd_ac97_remove_ctl(ac97, "Headphone Playback", "Switch");
+	snd_ac97_remove_ctl(ac97, "Headphone Playback", "Volume");
+	snd_ac97_update_bits(ac97, AC97_POWERDOWN, 0x8000, 0x8000); /* mute LED on */
+	return 0;
+}
+
 struct quirk_table {
 	const char *name;
-	int (*func)(ac97_t *);
+	int (*func)(struct snd_ac97 *);
 };
 
 static struct quirk_table applicable_quirks[] = {
@@ -2495,10 +2506,11 @@
 	{ "alc_jack", tune_alc_jack },
 	{ "inv_eapd", tune_inv_eapd },
 	{ "mute_led", tune_mute_led },
+	{ "hp_mute_led", tune_hp_mute_led },
 };
 
 /* apply the quirk with the given type */
-static int apply_quirk(ac97_t *ac97, int type)
+static int apply_quirk(struct snd_ac97 *ac97, int type)
 {
 	if (type <= 0)
 		return 0;
@@ -2510,7 +2522,7 @@
 }
 
 /* apply the quirk with the given name */
-static int apply_quirk_str(ac97_t *ac97, const char *typestr)
+static int apply_quirk_str(struct snd_ac97 *ac97, const char *typestr)
 {
 	int i;
 	struct quirk_table *q;
@@ -2539,7 +2551,7 @@
  * Returns zero if successful, or a negative error code on failure.
  */
 
-int snd_ac97_tune_hardware(ac97_t *ac97, struct ac97_quirk *quirk, const char *override)
+int snd_ac97_tune_hardware(struct snd_ac97 *ac97, struct ac97_quirk *quirk, const char *override)
 {
 	int result;
 
diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h
index 536a4d4..a6244c7 100644
--- a/sound/pci/ac97/ac97_local.h
+++ b/sound/pci/ac97/ac97_local.h
@@ -36,6 +36,16 @@
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \
   .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \
   .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) }
+
+/* enum control */
+struct ac97_enum {
+	unsigned char reg;
+	unsigned char shift_l;
+	unsigned char shift_r;
+	unsigned short mask;
+	const char **texts;
+};
+
 #define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \
 { .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
   .mask = xmask, .texts = xtexts }
@@ -47,34 +57,33 @@
   .private_value = (unsigned long)&xenum }
 
 /* ac97_codec.c */
-extern const char *snd_ac97_stereo_enhancements[];
-extern const snd_kcontrol_new_t snd_ac97_controls_3d[];
-extern const snd_kcontrol_new_t snd_ac97_controls_spdif[];
-snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97);
-void snd_ac97_get_name(ac97_t *ac97, unsigned int id, char *name, int modem);
-int snd_ac97_info_volsw(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
-int snd_ac97_get_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_ac97_put_volsw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_ac97_try_bit(ac97_t * ac97, int reg, int bit);
-int snd_ac97_remove_ctl(ac97_t *ac97, const char *name, const char *suffix);
-int snd_ac97_rename_ctl(ac97_t *ac97, const char *src, const char *dst, const char *suffix);
-int snd_ac97_swap_ctl(ac97_t *ac97, const char *s1, const char *s2, const char *suffix);
-void snd_ac97_rename_vol_ctl(ac97_t *ac97, const char *src, const char *dst);
-void snd_ac97_restore_status(ac97_t *ac97);
-void snd_ac97_restore_iec958(ac97_t *ac97);
-int snd_ac97_info_enum_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
-int snd_ac97_get_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_ac97_put_enum_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+extern const struct snd_kcontrol_new snd_ac97_controls_3d[];
+extern const struct snd_kcontrol_new snd_ac97_controls_spdif[];
+struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97);
+void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem);
+int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
+int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit);
+int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix);
+int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix);
+int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix);
+void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst);
+void snd_ac97_restore_status(struct snd_ac97 *ac97);
+void snd_ac97_restore_iec958(struct snd_ac97 *ac97);
+int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
+int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
 
-int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg,
+int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg,
 				unsigned short mask, unsigned short value);
 
 /* ac97_proc.c */
 #ifdef CONFIG_PROC_FS
-void snd_ac97_bus_proc_init(ac97_bus_t * ac97);
-void snd_ac97_bus_proc_done(ac97_bus_t * ac97);
-void snd_ac97_proc_init(ac97_t * ac97);
-void snd_ac97_proc_done(ac97_t * ac97);
+void snd_ac97_bus_proc_init(struct snd_ac97_bus * ac97);
+void snd_ac97_bus_proc_done(struct snd_ac97_bus * ac97);
+void snd_ac97_proc_init(struct snd_ac97 * ac97);
+void snd_ac97_proc_done(struct snd_ac97 * ac97);
 #else
 #define snd_ac97_bus_proc_init(ac97_bus_t) do { } while (0)
 #define snd_ac97_bus_proc_done(ac97_bus_t) do { } while (0)
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index de1c72a..4aa5fdc 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -39,7 +39,7 @@
  *  Chip specific initialization
  */
 
-static int patch_build_controls(ac97_t * ac97, const snd_kcontrol_new_t *controls, int count)
+static int patch_build_controls(struct snd_ac97 * ac97, const struct snd_kcontrol_new *controls, int count)
 {
 	int idx, err;
 
@@ -50,7 +50,7 @@
 }
 
 /* set to the page, update bits and restore the page */
-static int ac97_update_bits_page(ac97_t *ac97, unsigned short reg, unsigned short mask, unsigned short value, unsigned short page)
+static int ac97_update_bits_page(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value, unsigned short page)
 {
 	unsigned short page_save;
 	int ret;
@@ -67,7 +67,7 @@
 /*
  * shared line-in/mic controls
  */
-static int ac97_enum_text_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo,
+static int ac97_enum_text_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo,
 			       const char **texts, unsigned int nums)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -79,23 +79,23 @@
 	return 0;
 }
 
-static int ac97_surround_jack_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int ac97_surround_jack_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static const char *texts[] = { "Shared", "Independent" };
 	return ac97_enum_text_info(kcontrol, uinfo, texts, 2);
 }
 
-static int ac97_surround_jack_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ac97_surround_jack_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = ac97->indep_surround;
 	return 0;
 }
 
-static int ac97_surround_jack_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ac97_surround_jack_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned char indep = !!ucontrol->value.enumerated.item[0];
 
 	if (indep != ac97->indep_surround) {
@@ -107,7 +107,7 @@
 	return 0;
 }
 
-static int ac97_channel_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static const char *texts[] = { "2ch", "4ch", "6ch" };
 	if (kcontrol->private_value)
@@ -115,17 +115,17 @@
 	return ac97_enum_text_info(kcontrol, uinfo, texts, 3);
 }
 
-static int ac97_channel_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = ac97->channel_mode;
 	return 0;
 }
 
-static int ac97_channel_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ac97_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned char mode = ucontrol->value.enumerated.item[0];
 
 	if (mode != ac97->channel_mode) {
@@ -163,22 +163,22 @@
 		.private_value = 1, \
 	}
 
-static inline int is_surround_on(ac97_t *ac97)
+static inline int is_surround_on(struct snd_ac97 *ac97)
 {
 	return ac97->channel_mode >= 1;
 }
 
-static inline int is_clfe_on(ac97_t *ac97)
+static inline int is_clfe_on(struct snd_ac97 *ac97)
 {
 	return ac97->channel_mode >= 2;
 }
 
-static inline int is_shared_linein(ac97_t *ac97)
+static inline int is_shared_linein(struct snd_ac97 *ac97)
 {
 	return ! ac97->indep_surround && is_surround_on(ac97);
 }
 
-static inline int is_shared_micin(ac97_t *ac97)
+static inline int is_shared_micin(struct snd_ac97 *ac97)
 {
 	return ! ac97->indep_surround && is_clfe_on(ac97);
 }
@@ -187,7 +187,7 @@
 /* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
 
 /* It is possible to indicate to the Yamaha YMF753 the type of speakers being used. */
-static int snd_ac97_ymf753_info_speaker(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ac97_ymf753_info_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = {
 		"Standard", "Small", "Smaller"
@@ -202,9 +202,9 @@
 	return 0;
 }
 
-static int snd_ac97_ymf753_get_speaker(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ymf753_get_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	val = ac97->regs[AC97_YMF753_3D_MODE_SEL];
@@ -215,9 +215,9 @@
 	return 0;
 }
 
-static int snd_ac97_ymf753_put_speaker(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ymf753_put_speaker(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	if (ucontrol->value.enumerated.item[0] > 2)
@@ -226,7 +226,7 @@
 	return snd_ac97_update(ac97, AC97_YMF753_3D_MODE_SEL, val);
 }
 
-static const snd_kcontrol_new_t snd_ac97_ymf753_controls_speaker =
+static const struct snd_kcontrol_new snd_ac97_ymf753_controls_speaker =
 {
 	.iface  = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name   = "3D Control - Speaker",
@@ -236,7 +236,7 @@
 };
 
 /* It is possible to indicate to the Yamaha YMF753 the source to direct to the S/PDIF output. */
-static int snd_ac97_ymf753_spdif_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ac97_ymf753_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = { "AC-Link", "A/D Converter" };
 
@@ -249,9 +249,9 @@
 	return 0;
 }
 
-static int snd_ac97_ymf753_spdif_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ymf753_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	val = ac97->regs[AC97_YMF753_DIT_CTRL2];
@@ -259,9 +259,9 @@
 	return 0;
 }
 
-static int snd_ac97_ymf753_spdif_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ymf753_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	if (ucontrol->value.enumerated.item[0] > 1)
@@ -274,7 +274,7 @@
    The YMF753 will output the S/PDIF signal to pin 43, 47 (EAPD), or 48.
    By default, no output pin is selected, and the S/PDIF signal is not output.
    There is also a bit to mute S/PDIF output in a vendor-specific register. */
-static int snd_ac97_ymf753_spdif_output_pin_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ac97_ymf753_spdif_output_pin_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = { "Disabled", "Pin 43", "Pin 48" };
 
@@ -287,9 +287,9 @@
 	return 0;
 }
 
-static int snd_ac97_ymf753_spdif_output_pin_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ymf753_spdif_output_pin_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	val = ac97->regs[AC97_YMF753_DIT_CTRL2];
@@ -297,9 +297,9 @@
 	return 0;
 }
 
-static int snd_ac97_ymf753_spdif_output_pin_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ymf753_spdif_output_pin_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	if (ucontrol->value.enumerated.item[0] > 2)
@@ -311,7 +311,7 @@
 	   snd_ac97_write_cache(ac97, 0x62, snd_ac97_read(ac97, 0x62) | 0x0008); */
 }
 
-static const snd_kcontrol_new_t snd_ac97_ymf753_controls_spdif[3] = {
+static const struct snd_kcontrol_new snd_ac97_ymf753_controls_spdif[3] = {
 	{
 		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name	= SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
@@ -329,9 +329,9 @@
 	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",NONE,NONE) "Mute", AC97_YMF753_DIT_CTRL2, 2, 1, 1)
 };
 
-static int patch_yamaha_ymf753_3d(ac97_t * ac97)
+static int patch_yamaha_ymf753_3d(struct snd_ac97 * ac97)
 {
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 	int err;
 
 	if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
@@ -345,7 +345,7 @@
 	return 0;
 }
 
-static int patch_yamaha_ymf753_post_spdif(ac97_t * ac97)
+static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
 {
 	int err;
 
@@ -359,7 +359,7 @@
 	.build_post_spdif = patch_yamaha_ymf753_post_spdif
 };
 
-int patch_yamaha_ymf753(ac97_t * ac97)
+int patch_yamaha_ymf753(struct snd_ac97 * ac97)
 {
 	/* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com.
 	   This chip has nonstandard and extended behaviour with regard to its S/PDIF output.
@@ -380,12 +380,12 @@
  *  added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
  */
 
-static const snd_kcontrol_new_t wm97xx_snd_ac97_controls[] = {
+static const struct snd_kcontrol_new wm97xx_snd_ac97_controls[] = {
 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
 };
 
-static int patch_wolfson_wm9703_specific(ac97_t * ac97)
+static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97)
 {
 	/* This is known to work for the ViewSonic ViewPad 1000
 	 * Randolph Bentson <bentson@holmsjoen.com>
@@ -405,13 +405,13 @@
 	.build_specific = patch_wolfson_wm9703_specific,
 };
 
-int patch_wolfson03(ac97_t * ac97)
+int patch_wolfson03(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_wolfson_wm9703_ops;
 	return 0;
 }
 
-static const snd_kcontrol_new_t wm9704_snd_ac97_controls[] = {
+static const struct snd_kcontrol_new wm9704_snd_ac97_controls[] = {
 AC97_DOUBLE("Front Playback Volume", AC97_WM97XX_FMIXER_VOL, 8, 0, 31, 1),
 AC97_SINGLE("Front Playback Switch", AC97_WM97XX_FMIXER_VOL, 15, 1, 1),
 AC97_DOUBLE("Rear Playback Volume", AC97_WM9704_RMIXER_VOL, 8, 0, 31, 1),
@@ -420,7 +420,7 @@
 AC97_DOUBLE("Surround Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
 };
 
-static int patch_wolfson_wm9704_specific(ac97_t * ac97)
+static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97)
 {
 	int err, i;
 	for (i = 0; i < ARRAY_SIZE(wm9704_snd_ac97_controls); i++) {
@@ -436,14 +436,14 @@
 	.build_specific = patch_wolfson_wm9704_specific,
 };
 
-int patch_wolfson04(ac97_t * ac97)
+int patch_wolfson04(struct snd_ac97 * ac97)
 {
 	/* WM9704M/9704Q */
 	ac97->build_ops = &patch_wolfson_wm9704_ops;
 	return 0;
 }
 
-static int patch_wolfson_wm9705_specific(ac97_t * ac97)
+static int patch_wolfson_wm9705_specific(struct snd_ac97 * ac97)
 {
 	int err, i;
 	for (i = 0; i < ARRAY_SIZE(wm97xx_snd_ac97_controls); i++) {
@@ -458,7 +458,7 @@
 	.build_specific = patch_wolfson_wm9705_specific,
 };
 
-int patch_wolfson05(ac97_t * ac97)
+int patch_wolfson05(struct snd_ac97 * ac97)
 {
 	/* WM9705, WM9710 */
 	ac97->build_ops = &patch_wolfson_wm9705_ops;
@@ -490,7 +490,7 @@
 AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9711_ng_type),
 };
 
-static const snd_kcontrol_new_t wm9711_snd_ac97_controls[] = {
+static const struct snd_kcontrol_new wm9711_snd_ac97_controls[] = {
 AC97_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
 AC97_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
 AC97_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
@@ -568,7 +568,7 @@
 AC97_SINGLE("Mono ZC Switch", AC97_MASTER_MONO, 7, 1, 0),
 };
 
-static int patch_wolfson_wm9711_specific(ac97_t * ac97)
+static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97)
 {
 	int err, i;
 	
@@ -589,7 +589,7 @@
 	.build_specific = patch_wolfson_wm9711_specific,
 };
 
-int patch_wolfson11(ac97_t * ac97)
+int patch_wolfson11(struct snd_ac97 * ac97)
 {
 	/* WM9711, WM9712 */
 	ac97->build_ops = &patch_wolfson_wm9711_ops;
@@ -636,7 +636,7 @@
 AC97_ENUM_SINGLE(AC97_PCI_SVID, 5, 2, wm9713_ng_type),
 };
 
-static const snd_kcontrol_new_t wm13_snd_ac97_controls[] = {
+static const struct snd_kcontrol_new wm13_snd_ac97_controls[] = {
 AC97_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1),
 AC97_SINGLE("Line In to Headphone Switch", AC97_PC_BEEP, 15, 1, 1),
 AC97_SINGLE("Line In to Master Switch", AC97_PC_BEEP, 14, 1, 1),
@@ -728,14 +728,14 @@
 AC97_SINGLE("Tone Volume", AC97_GENERAL_PURPOSE, 0, 15, 1),
 };
 
-static const snd_kcontrol_new_t wm13_snd_ac97_controls_3d[] = {
+static const struct snd_kcontrol_new wm13_snd_ac97_controls_3d[] = {
 AC97_ENUM("Inv Input Mux", wm9713_enum[11]),
 AC97_SINGLE("3D Upper Cut-off Switch", AC97_REC_GAIN_MIC, 5, 1, 0),
 AC97_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0),
 AC97_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1),
 };
 
-static int patch_wolfson_wm9713_3d (ac97_t * ac97)
+static int patch_wolfson_wm9713_3d (struct snd_ac97 * ac97)
 {
 	int err, i;
     
@@ -746,7 +746,7 @@
 	return 0;
 }
 
-static int patch_wolfson_wm9713_specific(ac97_t * ac97)
+static int patch_wolfson_wm9713_specific(struct snd_ac97 * ac97)
 {
 	int err, i;
 	
@@ -765,13 +765,13 @@
 }
 
 #ifdef CONFIG_PM
-static void patch_wolfson_wm9713_suspend (ac97_t * ac97)
+static void patch_wolfson_wm9713_suspend (struct snd_ac97 * ac97)
 {
 	snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xfeff);
 	snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0xffff);
 }
 
-static void patch_wolfson_wm9713_resume (ac97_t * ac97)
+static void patch_wolfson_wm9713_resume (struct snd_ac97 * ac97)
 {
 	snd_ac97_write_cache(ac97, AC97_EXTENDED_MID, 0xda00);
 	snd_ac97_write_cache(ac97, AC97_EXTENDED_MSTATUS, 0x3810);
@@ -788,7 +788,7 @@
 #endif
 };
 
-int patch_wolfson13(ac97_t * ac97)
+int patch_wolfson13(struct snd_ac97 * ac97)
 {
 	/* WM9713, WM9714 */
 	ac97->build_ops = &patch_wolfson_wm9713_ops;
@@ -808,7 +808,7 @@
 /*
  * Tritech codec
  */
-int patch_tritech_tr28028(ac97_t * ac97)
+int patch_tritech_tr28028(struct snd_ac97 * ac97)
 {
 	snd_ac97_write_cache(ac97, 0x26, 0x0300);
 	snd_ac97_write_cache(ac97, 0x26, 0x0000);
@@ -820,9 +820,9 @@
 /*
  * Sigmatel STAC97xx codecs
  */
-static int patch_sigmatel_stac9700_3d(ac97_t * ac97)
+static int patch_sigmatel_stac9700_3d(struct snd_ac97 * ac97)
 {
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 	int err;
 
 	if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
@@ -833,9 +833,9 @@
 	return 0;
 }
 
-static int patch_sigmatel_stac9708_3d(ac97_t * ac97)
+static int patch_sigmatel_stac9708_3d(struct snd_ac97 * ac97)
 {
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 	int err;
 
 	if ((err = snd_ctl_add(ac97->bus->card, kctl = snd_ac97_cnew(&snd_ac97_controls_3d[0], ac97))) < 0)
@@ -850,18 +850,18 @@
 	return 0;
 }
 
-static const snd_kcontrol_new_t snd_ac97_sigmatel_4speaker =
+static const struct snd_kcontrol_new snd_ac97_sigmatel_4speaker =
 AC97_SINGLE("Sigmatel 4-Speaker Stereo Playback Switch", AC97_SIGMATEL_DAC2INVERT, 2, 1, 0);
 
-static const snd_kcontrol_new_t snd_ac97_sigmatel_phaseinvert =
+static const struct snd_kcontrol_new snd_ac97_sigmatel_phaseinvert =
 AC97_SINGLE("Sigmatel Surround Phase Inversion Playback Switch", AC97_SIGMATEL_DAC2INVERT, 3, 1, 0);
 
-static const snd_kcontrol_new_t snd_ac97_sigmatel_controls[] = {
+static const struct snd_kcontrol_new snd_ac97_sigmatel_controls[] = {
 AC97_SINGLE("Sigmatel DAC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 1, 1, 0),
 AC97_SINGLE("Sigmatel ADC 6dB Attenuate", AC97_SIGMATEL_ANALOG, 0, 1, 0)
 };
 
-static int patch_sigmatel_stac97xx_specific(ac97_t * ac97)
+static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97)
 {
 	int err;
 
@@ -886,15 +886,15 @@
 	.build_specific	= patch_sigmatel_stac97xx_specific
 };
 
-int patch_sigmatel_stac9700(ac97_t * ac97)
+int patch_sigmatel_stac9700(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_sigmatel_stac9700_ops;
 	return 0;
 }
 
-static int snd_ac97_stac9708_put_bias(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ac97_stac9708_put_bias(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int err;
 
 	down(&ac97->page_mutex);
@@ -906,7 +906,7 @@
 	return err;
 }
 
-static const snd_kcontrol_new_t snd_ac97_stac9708_bias_control = {
+static const struct snd_kcontrol_new snd_ac97_stac9708_bias_control = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Sigmatel Output Bias Switch",
 	.info = snd_ac97_info_volsw,
@@ -915,7 +915,7 @@
 	.private_value = AC97_SINGLE_VALUE(AC97_SIGMATEL_BIAS2, 4, 1, 0),
 };
 
-static int patch_sigmatel_stac9708_specific(ac97_t *ac97)
+static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97)
 {
 	int err;
 
@@ -930,7 +930,7 @@
 	.build_specific	= patch_sigmatel_stac9708_specific
 };
 
-int patch_sigmatel_stac9708(ac97_t * ac97)
+int patch_sigmatel_stac9708(struct snd_ac97 * ac97)
 {
 	unsigned int codec72, codec6c;
 
@@ -956,7 +956,7 @@
 	return 0;
 }
 
-int patch_sigmatel_stac9721(ac97_t * ac97)
+int patch_sigmatel_stac9721(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_sigmatel_stac9700_ops;
 	if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) {
@@ -970,7 +970,7 @@
 	return 0;
 }
 
-int patch_sigmatel_stac9744(ac97_t * ac97)
+int patch_sigmatel_stac9744(struct snd_ac97 * ac97)
 {
 	// patch for SigmaTel
 	ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -982,7 +982,7 @@
 	return 0;
 }
 
-int patch_sigmatel_stac9756(ac97_t * ac97)
+int patch_sigmatel_stac9756(struct snd_ac97 * ac97)
 {
 	// patch for SigmaTel
 	ac97->build_ops = &patch_sigmatel_stac9700_ops;
@@ -994,7 +994,7 @@
 	return 0;
 }
 
-static int snd_ac97_stac9758_output_jack_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ac97_stac9758_output_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[5] = { "Input/Disabled", "Front Output",
 		"Rear Output", "Center/LFE Output", "Mixer Output" };
@@ -1008,9 +1008,9 @@
 	return 0;
 }
 
-static int snd_ac97_stac9758_output_jack_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
+static int snd_ac97_stac9758_output_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value;
 	unsigned short val;
 
@@ -1022,9 +1022,9 @@
 	return 0;
 }
 
-static int snd_ac97_stac9758_output_jack_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ac97_stac9758_output_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value;
 	unsigned short val;
 
@@ -1038,7 +1038,7 @@
 				     7 << shift, val << shift, 0);
 }
 
-static int snd_ac97_stac9758_input_jack_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ac97_stac9758_input_jack_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[7] = { "Mic2 Jack", "Mic1 Jack", "Line In Jack",
 		"Front Jack", "Rear Jack", "Center/LFE Jack", "Mute" };
@@ -1052,9 +1052,9 @@
 	return 0;
 }
 
-static int snd_ac97_stac9758_input_jack_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
+static int snd_ac97_stac9758_input_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value;
 	unsigned short val;
 
@@ -1063,16 +1063,16 @@
 	return 0;
 }
 
-static int snd_ac97_stac9758_input_jack_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ac97_stac9758_input_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value;
 
 	return ac97_update_bits_page(ac97, AC97_SIGMATEL_INSEL, 7 << shift,
 				     ucontrol->value.enumerated.item[0] << shift, 0);
 }
 
-static int snd_ac97_stac9758_phonesel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ac97_stac9758_phonesel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = { "None", "Front Jack", "Rear Jack" };
 
@@ -1085,17 +1085,17 @@
 	return 0;
 }
 
-static int snd_ac97_stac9758_phonesel_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
+static int snd_ac97_stac9758_phonesel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = ac97->regs[AC97_SIGMATEL_IOMISC] & 3;
 	return 0;
 }
 
-static int snd_ac97_stac9758_phonesel_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ac97_stac9758_phonesel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	return ac97_update_bits_page(ac97, AC97_SIGMATEL_IOMISC, 3,
 				     ucontrol->value.enumerated.item[0], 0);
@@ -1113,7 +1113,7 @@
 	.get = snd_ac97_stac9758_input_jack_get, \
 	.put = snd_ac97_stac9758_input_jack_put, \
 	.private_value = shift }
-static const snd_kcontrol_new_t snd_ac97_sigmatel_stac9758_controls[] = {
+static const struct snd_kcontrol_new snd_ac97_sigmatel_stac9758_controls[] = {
 	STAC9758_OUTPUT_JACK("Mic1 Jack", 1),
 	STAC9758_OUTPUT_JACK("LineIn Jack", 4),
 	STAC9758_OUTPUT_JACK("Front Jack", 7),
@@ -1132,7 +1132,7 @@
 	AC97_SINGLE("Headphone +3dB Boost", AC97_SIGMATEL_IOMISC, 8, 1, 0)
 };
 
-static int patch_sigmatel_stac9758_specific(ac97_t *ac97)
+static int patch_sigmatel_stac9758_specific(struct snd_ac97 *ac97)
 {
 	int err;
 
@@ -1159,7 +1159,7 @@
 	.build_specific	= patch_sigmatel_stac9758_specific
 };
 
-int patch_sigmatel_stac9758(ac97_t * ac97)
+int patch_sigmatel_stac9758(struct snd_ac97 * ac97)
 {
 	static unsigned short regs[4] = {
 		AC97_SIGMATEL_OUTSEL,
@@ -1202,12 +1202,12 @@
 /*
  * Cirrus Logic CS42xx codecs
  */
-static const snd_kcontrol_new_t snd_ac97_cirrus_controls_spdif[2] = {
+static const struct snd_kcontrol_new snd_ac97_cirrus_controls_spdif[2] = {
 	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CSR_SPDIF, 15, 1, 0),
 	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", AC97_CSR_ACMODE, 0, 3, 0)
 };
 
-static int patch_cirrus_build_spdif(ac97_t * ac97)
+static int patch_cirrus_build_spdif(struct snd_ac97 * ac97)
 {
 	int err;
 
@@ -1233,7 +1233,7 @@
 	.build_spdif = patch_cirrus_build_spdif
 };
 
-int patch_cirrus_spdif(ac97_t * ac97)
+int patch_cirrus_spdif(struct snd_ac97 * ac97)
 {
 	/* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers.
 	   WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC?  *sigh*
@@ -1254,7 +1254,7 @@
 	return 0;
 }
 
-int patch_cirrus_cs4299(ac97_t * ac97)
+int patch_cirrus_cs4299(struct snd_ac97 * ac97)
 {
 	/* force the detection of PC Beep */
 	ac97->flags |= AC97_HAS_PC_BEEP;
@@ -1265,11 +1265,11 @@
 /*
  * Conexant codecs
  */
-static const snd_kcontrol_new_t snd_ac97_conexant_controls_spdif[1] = {
+static const struct snd_kcontrol_new snd_ac97_conexant_controls_spdif[1] = {
 	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CXR_AUDIO_MISC, 3, 1, 0),
 };
 
-static int patch_conexant_build_spdif(ac97_t * ac97)
+static int patch_conexant_build_spdif(struct snd_ac97 * ac97)
 {
 	int err;
 
@@ -1290,7 +1290,7 @@
 	.build_spdif = patch_conexant_build_spdif
 };
 
-int patch_conexant(ac97_t * ac97)
+int patch_conexant(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_conexant_ops;
 	ac97->flags |= AC97_CX_SPDIF;
@@ -1303,7 +1303,7 @@
  * Analog Device AD18xx, AD19xx codecs
  */
 #ifdef CONFIG_PM
-static void ad18xx_resume(ac97_t *ac97)
+static void ad18xx_resume(struct snd_ac97 *ac97)
 {
 	static unsigned short setup_regs[] = {
 		AC97_AD_MISC, AC97_AD_SERIAL_CFG, AC97_AD_JACK_SPDIF,
@@ -1367,7 +1367,7 @@
 }
 #endif
 
-int patch_ad1819(ac97_t * ac97)
+int patch_ad1819(struct snd_ac97 * ac97)
 {
 	unsigned short scfg;
 
@@ -1377,7 +1377,7 @@
 	return 0;
 }
 
-static unsigned short patch_ad1881_unchained(ac97_t * ac97, int idx, unsigned short mask)
+static unsigned short patch_ad1881_unchained(struct snd_ac97 * ac97, int idx, unsigned short mask)
 {
 	unsigned short val;
 
@@ -1393,7 +1393,7 @@
 	return mask;
 }
 
-static int patch_ad1881_chained1(ac97_t * ac97, int idx, unsigned short codec_bits)
+static int patch_ad1881_chained1(struct snd_ac97 * ac97, int idx, unsigned short codec_bits)
 {
 	static int cfg_bits[3] = { 1<<12, 1<<14, 1<<13 };
 	unsigned short val;
@@ -1411,7 +1411,7 @@
 	return 1;
 }
 
-static void patch_ad1881_chained(ac97_t * ac97, int unchained_idx, int cidx1, int cidx2)
+static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int cidx1, int cidx2)
 {
 	// already detected?
 	if (ac97->spec.ad18xx.unchained[cidx1] || ac97->spec.ad18xx.chained[cidx1])
@@ -1441,7 +1441,7 @@
 #endif
 };
 
-int patch_ad1881(ac97_t * ac97)
+int patch_ad1881(struct snd_ac97 * ac97)
 {
 	static const char cfg_idxs[3][2] = {
 		{2, 1},
@@ -1500,7 +1500,7 @@
 	return 0;
 }
 
-static const snd_kcontrol_new_t snd_ac97_controls_ad1885[] = {
+static const struct snd_kcontrol_new snd_ac97_controls_ad1885[] = {
 	AC97_SINGLE("Digital Mono Direct", AC97_AD_MISC, 11, 1, 0),
 	/* AC97_SINGLE("Digital Audio Mode", AC97_AD_MISC, 12, 1, 0), */ /* seems problematic */
 	AC97_SINGLE("Low Power Mixer", AC97_AD_MISC, 14, 1, 0),
@@ -1509,7 +1509,7 @@
 	AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1), /* inverted */
 };
 
-static int patch_ad1885_specific(ac97_t * ac97)
+static int patch_ad1885_specific(struct snd_ac97 * ac97)
 {
 	int err;
 
@@ -1525,7 +1525,7 @@
 #endif
 };
 
-int patch_ad1885(ac97_t * ac97)
+int patch_ad1885(struct snd_ac97 * ac97)
 {
 	patch_ad1881(ac97);
 	/* This is required to deal with the Intel D815EEAL2 */
@@ -1538,7 +1538,7 @@
 	return 0;
 }
 
-int patch_ad1886(ac97_t * ac97)
+int patch_ad1886(struct snd_ac97 * ac97)
 {
 	patch_ad1881(ac97);
 	/* Presario700 workaround */
@@ -1569,7 +1569,7 @@
 #define AC97_AD198X_DACZ	0x8000	/* DAC zero-fill mode */
 
 
-static int snd_ac97_ad198x_spdif_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = { "AC-Link", "A/D Converter" };
 
@@ -1582,9 +1582,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad198x_spdif_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ad198x_spdif_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	val = ac97->regs[AC97_AD_SERIAL_CFG];
@@ -1592,9 +1592,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad198x_spdif_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_ad198x_spdif_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	if (ucontrol->value.enumerated.item[0] > 1)
@@ -1603,7 +1603,7 @@
 	return snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 0x0004, val);
 }
 
-static const snd_kcontrol_new_t snd_ac97_ad198x_spdif_source = {
+static const struct snd_kcontrol_new snd_ac97_ad198x_spdif_source = {
 	.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name	= SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
 	.info	= snd_ac97_ad198x_spdif_source_info,
@@ -1611,17 +1611,17 @@
 	.put	= snd_ac97_ad198x_spdif_source_put,
 };
 
-static int patch_ad198x_post_spdif(ac97_t * ac97)
+static int patch_ad198x_post_spdif(struct snd_ac97 * ac97)
 {
  	return patch_build_controls(ac97, &snd_ac97_ad198x_spdif_source, 1);
 }
 
-static const snd_kcontrol_new_t snd_ac97_ad1981x_jack_sense[] = {
+static const struct snd_kcontrol_new snd_ac97_ad1981x_jack_sense[] = {
 	AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 11, 1, 0),
 	AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
 };
 
-static int patch_ad1981a_specific(ac97_t * ac97)
+static int patch_ad1981a_specific(struct snd_ac97 * ac97)
 {
 	return patch_build_controls(ac97, snd_ac97_ad1981x_jack_sense,
 				    ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
@@ -1635,12 +1635,16 @@
 #endif
 };
 
-static void check_ad1981_hp_jack_sense(ac97_t *ac97)
+static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97)
 {
 	u32 subid = ((u32)ac97->subsystem_vendor << 16) | ac97->subsystem_device;
 	switch (subid) {
+	case 0x0e11005a: /* HP nc4000/4010 */
 	case 0x103c0890: /* HP nc6000 */
+	case 0x103c0938: /* HP nc4220 */
 	case 0x103c099c: /* HP nx6110 */
+	case 0x103c0944: /* HP nc6220 */
+	case 0x103c0934: /* HP nc8220 */
 	case 0x103c006d: /* HP nx9105 */
 	case 0x17340088: /* FSC Scenic-W */
 		/* enable headphone jack sense */
@@ -1649,7 +1653,7 @@
 	}
 }
 
-int patch_ad1981a(ac97_t *ac97)
+int patch_ad1981a(struct snd_ac97 *ac97)
 {
 	patch_ad1881(ac97);
 	ac97->build_ops = &patch_ad1981a_build_ops;
@@ -1659,10 +1663,10 @@
 	return 0;
 }
 
-static const snd_kcontrol_new_t snd_ac97_ad198x_2cmic =
+static const struct snd_kcontrol_new snd_ac97_ad198x_2cmic =
 AC97_SINGLE("Stereo Mic", AC97_AD_MISC, 6, 1, 0);
 
-static int patch_ad1981b_specific(ac97_t *ac97)
+static int patch_ad1981b_specific(struct snd_ac97 *ac97)
 {
 	int err;
 
@@ -1680,7 +1684,7 @@
 #endif
 };
 
-int patch_ad1981b(ac97_t *ac97)
+int patch_ad1981b(struct snd_ac97 *ac97)
 {
 	patch_ad1881(ac97);
 	ac97->build_ops = &patch_ad1981b_build_ops;
@@ -1690,7 +1694,7 @@
 	return 0;
 }
 
-static int snd_ac97_ad1888_lohpsel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ac97_ad1888_lohpsel_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1699,9 +1703,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad1888_lohpsel_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
+static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	val = ac97->regs[AC97_AD_MISC];
@@ -1709,9 +1713,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad1888_lohpsel_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	val = !ucontrol->value.integer.value[0]
@@ -1720,7 +1724,7 @@
 				    AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val);
 }
 
-static int snd_ac97_ad1888_downmix_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ac97_ad1888_downmix_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = {"Off", "6 -> 4", "6 -> 2"};
 
@@ -1733,9 +1737,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad1888_downmix_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t* ucontrol)
+static int snd_ac97_ad1888_downmix_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	val = ac97->regs[AC97_AD_MISC];
@@ -1746,9 +1750,9 @@
 	return 0;
 }
 
-static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ac97_ad1888_downmix_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	if (ucontrol->value.enumerated.item[0] > 2)
@@ -1762,7 +1766,7 @@
 				    AC97_AD198X_DMIX0 | AC97_AD198X_DMIX1, val);
 }
 
-static void ad1888_update_jacks(ac97_t *ac97)
+static void ad1888_update_jacks(struct snd_ac97 *ac97)
 {
 	unsigned short val = 0;
 	if (! is_shared_linein(ac97))
@@ -1773,7 +1777,7 @@
 	snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
 }
 
-static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
+static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Exchange Front/Surround",
@@ -1796,7 +1800,7 @@
 	AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
 };
 
-static int patch_ad1888_specific(ac97_t *ac97)
+static int patch_ad1888_specific(struct snd_ac97 *ac97)
 {
 	/* rename 0x04 as "Master" and 0x02 as "Master Surround" */
 	snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Master Surround Playback");
@@ -1813,7 +1817,7 @@
 	.update_jacks = ad1888_update_jacks,
 };
 
-int patch_ad1888(ac97_t * ac97)
+int patch_ad1888(struct snd_ac97 * ac97)
 {
 	unsigned short misc;
 	
@@ -1833,7 +1837,7 @@
 	return 0;
 }
 
-static int patch_ad1980_specific(ac97_t *ac97)
+static int patch_ad1980_specific(struct snd_ac97 *ac97)
 {
 	int err;
 
@@ -1851,25 +1855,25 @@
 	.update_jacks = ad1888_update_jacks,
 };
 
-int patch_ad1980(ac97_t * ac97)
+int patch_ad1980(struct snd_ac97 * ac97)
 {
 	patch_ad1888(ac97);
 	ac97->build_ops = &patch_ad1980_build_ops;
 	return 0;
 }
 
-static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = {
+static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = {
 	AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0)
 };
 
-static void ad1985_update_jacks(ac97_t *ac97)
+static void ad1985_update_jacks(struct snd_ac97 *ac97)
 {
 	ad1888_update_jacks(ac97);
 	snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
 			     is_shared_micin(ac97) ? 0 : 1 << 9);
 }
 
-static int patch_ad1985_specific(ac97_t *ac97)
+static int patch_ad1985_specific(struct snd_ac97 *ac97)
 {
 	int err;
 
@@ -1887,7 +1891,7 @@
 	.update_jacks = ad1985_update_jacks,
 };
 
-int patch_ad1985(ac97_t * ac97)
+int patch_ad1985(struct snd_ac97 * ac97)
 {
 	unsigned short misc;
 	
@@ -1916,7 +1920,7 @@
 /*
  * realtek ALC65x/850 codecs
  */
-static void alc650_update_jacks(ac97_t *ac97)
+static void alc650_update_jacks(struct snd_ac97 *ac97)
 {
 	int shared;
 	
@@ -1937,7 +1941,7 @@
 			     shared ? 0 : 0x100);
 }
 
-static const snd_kcontrol_new_t snd_ac97_controls_alc650[] = {
+static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
 	AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
 	AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
 	AC97_SINGLE("Center/LFE Down Mix", AC97_ALC650_MULTICH, 2, 1, 0),
@@ -1963,14 +1967,14 @@
 	AC97_CHANNEL_MODE_CTL,
 };
 
-static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc650[] = {
+static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650[] = {
         AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0),
         AC97_SINGLE("Analog to IEC958 Output", AC97_ALC650_MULTICH, 12, 1, 0),
 	/* disable this controls since it doesn't work as expected */
 	/* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */
 };
 
-static int patch_alc650_specific(ac97_t * ac97)
+static int patch_alc650_specific(struct snd_ac97 * ac97)
 {
 	int err;
 
@@ -1988,7 +1992,7 @@
 	.update_jacks = alc650_update_jacks
 };
 
-int patch_alc650(ac97_t * ac97)
+int patch_alc650(struct snd_ac97 * ac97)
 {
 	unsigned short val;
 
@@ -2043,7 +2047,7 @@
 	return 0;
 }
 
-static void alc655_update_jacks(ac97_t *ac97)
+static void alc655_update_jacks(struct snd_ac97 *ac97)
 {
 	int shared;
 	
@@ -2060,17 +2064,17 @@
 			      shared ? (1 << 10) : 0, 0);
 }
 
-static const snd_kcontrol_new_t snd_ac97_controls_alc655[] = {
+static const struct snd_kcontrol_new snd_ac97_controls_alc655[] = {
 	AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
 	AC97_SURROUND_JACK_MODE_CTL,
 	AC97_CHANNEL_MODE_CTL,
 };
 
-static int alc655_iec958_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc655_iec958_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts_655[3] = { "PCM", "Analog In", "IEC958 In" };
 	static char *texts_658[4] = { "PCM", "Analog1 In", "Analog2 In", "IEC958 In" };
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -2084,9 +2088,9 @@
 	return 0;
 }
 
-static int alc655_iec958_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc655_iec958_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	val = ac97->regs[AC97_ALC650_MULTICH];
@@ -2097,29 +2101,29 @@
 	return 0;
 }
 
-static int alc655_iec958_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc655_iec958_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	return ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 3 << 12,
 				     (unsigned short)ucontrol->value.enumerated.item[0] << 12,
 				     0);
 }
 
-static const snd_kcontrol_new_t snd_ac97_spdif_controls_alc655[] = {
+static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc655[] = {
         AC97_PAGE_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), AC97_ALC650_MULTICH, 11, 1, 0, 0),
 	/* disable this controls since it doesn't work as expected */
         /* AC97_PAGE_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 14, 1, 0, 0), */
 	{
 		.iface  = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name   = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
+		.name   = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
 		.info   = alc655_iec958_route_info,
 		.get    = alc655_iec958_route_get,
 		.put    = alc655_iec958_route_put,
 	},
 };
 
-static int patch_alc655_specific(ac97_t * ac97)
+static int patch_alc655_specific(struct snd_ac97 * ac97)
 {
 	int err;
 
@@ -2137,7 +2141,7 @@
 	.update_jacks = alc655_update_jacks
 };
 
-int patch_alc655(ac97_t * ac97)
+int patch_alc655(struct snd_ac97 * ac97)
 {
 	unsigned int val;
 
@@ -2189,7 +2193,7 @@
 #define AC97_ALC850_JACK_SELECT	0x76
 #define AC97_ALC850_MISC1	0x7a
 
-static void alc850_update_jacks(ac97_t *ac97)
+static void alc850_update_jacks(struct snd_ac97 *ac97)
 {
 	int shared;
 	
@@ -2211,14 +2215,14 @@
 			     shared ? (2<<4) : (1<<4));
 }
 
-static const snd_kcontrol_new_t snd_ac97_controls_alc850[] = {
+static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = {
 	AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
 	AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1),
 	AC97_SURROUND_JACK_MODE_CTL,
 	AC97_CHANNEL_MODE_CTL,
 };
 
-static int patch_alc850_specific(ac97_t *ac97)
+static int patch_alc850_specific(struct snd_ac97 *ac97)
 {
 	int err;
 
@@ -2236,7 +2240,7 @@
 	.update_jacks = alc850_update_jacks
 };
 
-int patch_alc850(ac97_t *ac97)
+int patch_alc850(struct snd_ac97 *ac97)
 {
 	ac97->build_ops = &patch_alc850_ops;
 
@@ -2273,20 +2277,20 @@
 /*
  * C-Media CM97xx codecs
  */
-static void cm9738_update_jacks(ac97_t *ac97)
+static void cm9738_update_jacks(struct snd_ac97 *ac97)
 {
 	/* shared Line-In */
 	snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10,
 			     is_shared_linein(ac97) ? (1 << 10) : 0);
 }
 
-static const snd_kcontrol_new_t snd_ac97_cm9738_controls[] = {
+static const struct snd_kcontrol_new snd_ac97_cm9738_controls[] = {
 	AC97_SINGLE("Duplicate Front", AC97_CM9738_VENDOR_CTRL, 13, 1, 0),
 	AC97_SURROUND_JACK_MODE_CTL,
 	AC97_CHANNEL_MODE_4CH_CTL,
 };
 
-static int patch_cm9738_specific(ac97_t * ac97)
+static int patch_cm9738_specific(struct snd_ac97 * ac97)
 {
 	return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls));
 }
@@ -2296,7 +2300,7 @@
 	.update_jacks = cm9738_update_jacks
 };
 
-int patch_cm9738(ac97_t * ac97)
+int patch_cm9738(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_cm9738_ops;
 	/* FIXME: can anyone confirm below? */
@@ -2307,7 +2311,7 @@
 	return 0;
 }
 
-static int snd_ac97_cmedia_spdif_playback_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ac97_cmedia_spdif_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "Analog", "Digital" };
 
@@ -2320,9 +2324,9 @@
 	return 0;
 }
 
-static int snd_ac97_cmedia_spdif_playback_source_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_cmedia_spdif_playback_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	val = ac97->regs[AC97_CM9739_SPDIF_CTRL];
@@ -2330,16 +2334,16 @@
 	return 0;
 }
 
-static int snd_ac97_cmedia_spdif_playback_source_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ac97_cmedia_spdif_playback_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	return snd_ac97_update_bits(ac97, AC97_CM9739_SPDIF_CTRL,
 				    0x01 << 1, 
 				    (ucontrol->value.enumerated.item[0] & 0x01) << 1);
 }
 
-static const snd_kcontrol_new_t snd_ac97_cm9739_controls_spdif[] = {
+static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif[] = {
 	/* BIT 0: SPDI_EN - always true */
 	{ /* BIT 1: SPDIFS */
 		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2357,7 +2361,7 @@
 	/* BIT 8: SPD32 - 32bit SPDIF - not supported yet */
 };
 
-static void cm9739_update_jacks(ac97_t *ac97)
+static void cm9739_update_jacks(struct snd_ac97 *ac97)
 {
 	/* shared Line-In */
 	snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10,
@@ -2367,17 +2371,17 @@
 			     is_shared_micin(ac97) ? 0x1000 : 0x2000);
 }
 
-static const snd_kcontrol_new_t snd_ac97_cm9739_controls[] = {
+static const struct snd_kcontrol_new snd_ac97_cm9739_controls[] = {
 	AC97_SURROUND_JACK_MODE_CTL,
 	AC97_CHANNEL_MODE_CTL,
 };
 
-static int patch_cm9739_specific(ac97_t * ac97)
+static int patch_cm9739_specific(struct snd_ac97 * ac97)
 {
 	return patch_build_controls(ac97, snd_ac97_cm9739_controls, ARRAY_SIZE(snd_ac97_cm9739_controls));
 }
 
-static int patch_cm9739_post_spdif(ac97_t * ac97)
+static int patch_cm9739_post_spdif(struct snd_ac97 * ac97)
 {
 	return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif));
 }
@@ -2388,7 +2392,7 @@
 	.update_jacks = cm9739_update_jacks
 };
 
-int patch_cm9739(ac97_t * ac97)
+int patch_cm9739(struct snd_ac97 * ac97)
 {
 	unsigned short val;
 
@@ -2447,7 +2451,7 @@
 #define AC97_CM9761_FUNC	0x66
 #define AC97_CM9761_SPDIF_CTRL	0x6c
 
-static void cm9761_update_jacks(ac97_t *ac97)
+static void cm9761_update_jacks(struct snd_ac97 *ac97)
 {
 	/* FIXME: check the bits for each model
 	 *        model 83 is confirmed to work
@@ -2482,12 +2486,12 @@
 	snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
 }
 
-static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
+static const struct snd_kcontrol_new snd_ac97_cm9761_controls[] = {
 	AC97_SURROUND_JACK_MODE_CTL,
 	AC97_CHANNEL_MODE_CTL,
 };
 
-static int cm9761_spdif_out_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int cm9761_spdif_out_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "AC-Link", "ADC", "SPDIF-In" };
 
@@ -2500,9 +2504,9 @@
 	return 0;
 }
 
-static int cm9761_spdif_out_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int cm9761_spdif_out_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	if (ac97->regs[AC97_CM9761_FUNC] & 0x1)
 		ucontrol->value.enumerated.item[0] = 2; /* SPDIF-loopback */
@@ -2513,9 +2517,9 @@
 	return 0;
 }
 
-static int cm9761_spdif_out_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int cm9761_spdif_out_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ac97_t *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
 
 	if (ucontrol->value.enumerated.item[0] == 2)
 		return snd_ac97_update_bits(ac97, AC97_CM9761_FUNC, 0x1, 0x1);
@@ -2528,7 +2532,7 @@
 static const struct ac97_enum cm9761_dac_clock_enum =
 	AC97_ENUM_SINGLE(AC97_CM9761_SPDIF_CTRL, 9, 3, cm9761_dac_clock);
 
-static const snd_kcontrol_new_t snd_ac97_cm9761_controls_spdif[] = {
+static const struct snd_kcontrol_new snd_ac97_cm9761_controls_spdif[] = {
 	{ /* BIT 1: SPDIFS */
 		.iface	= SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name	= SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
@@ -2546,12 +2550,12 @@
 	AC97_ENUM("DAC Clock Source", cm9761_dac_clock_enum),
 };
 
-static int patch_cm9761_post_spdif(ac97_t * ac97)
+static int patch_cm9761_post_spdif(struct snd_ac97 * ac97)
 {
 	return patch_build_controls(ac97, snd_ac97_cm9761_controls_spdif, ARRAY_SIZE(snd_ac97_cm9761_controls_spdif));
 }
 
-static int patch_cm9761_specific(ac97_t * ac97)
+static int patch_cm9761_specific(struct snd_ac97 * ac97)
 {
 	return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
 }
@@ -2562,7 +2566,7 @@
 	.update_jacks = cm9761_update_jacks
 };
 
-int patch_cm9761(ac97_t *ac97)
+int patch_cm9761(struct snd_ac97 *ac97)
 {
 	unsigned short val;
 
@@ -2641,13 +2645,13 @@
 static const char *cm9780_ch_select[] = { "Front", "Side", "Center/LFE", "Rear" };
 static const struct ac97_enum cm9780_ch_select_enum =
 	AC97_ENUM_SINGLE(AC97_CM9780_MULTI_CHAN, 6, 4, cm9780_ch_select);
-static const snd_kcontrol_new_t cm9780_controls[] = {
+static const struct snd_kcontrol_new cm9780_controls[] = {
 	AC97_DOUBLE("Side Playback Switch", AC97_CM9780_SIDE, 15, 7, 1, 1),
 	AC97_DOUBLE("Side Playback Volume", AC97_CM9780_SIDE, 8, 0, 31, 0),
 	AC97_ENUM("Side Playback Route", cm9780_ch_select_enum),
 };
 
-static int patch_cm9780_specific(ac97_t *ac97)
+static int patch_cm9780_specific(struct snd_ac97 *ac97)
 {
 	return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls));
 }
@@ -2657,7 +2661,7 @@
 	.build_post_spdif = patch_cm9761_post_spdif	/* identical with CM9761 */
 };
 
-int patch_cm9780(ac97_t *ac97)
+int patch_cm9780(struct snd_ac97 *ac97)
 {
 	unsigned short val;
 
@@ -2677,14 +2681,14 @@
 /*
  * VIA VT1616 codec
  */
-static const snd_kcontrol_new_t snd_ac97_controls_vt1616[] = {
+static const struct snd_kcontrol_new snd_ac97_controls_vt1616[] = {
 AC97_SINGLE("DC Offset removal", 0x5a, 10, 1, 0),
 AC97_SINGLE("Alternate Level to Surround Out", 0x5a, 15, 1, 0),
 AC97_SINGLE("Downmix LFE and Center to Front", 0x5a, 12, 1, 0),
 AC97_SINGLE("Downmix Surround to Front", 0x5a, 11, 1, 0),
 };
 
-static int patch_vt1616_specific(ac97_t * ac97)
+static int patch_vt1616_specific(struct snd_ac97 * ac97)
 {
 	int err;
 
@@ -2700,7 +2704,7 @@
 	.build_specific	= patch_vt1616_specific
 };
 
-int patch_vt1616(ac97_t * ac97)
+int patch_vt1616(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_vt1616_ops;
 	return 0;
@@ -2709,7 +2713,7 @@
 /*
  * VT1617A codec
  */
-int patch_vt1617a(ac97_t * ac97)
+int patch_vt1617a(struct snd_ac97 * ac97)
 {
 	ac97->ext_id |= AC97_EI_SPDIF;	/* force the detection of spdif */
 	ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
@@ -2718,7 +2722,7 @@
 
 /*
  */
-static void it2646_update_jacks(ac97_t *ac97)
+static void it2646_update_jacks(struct snd_ac97 *ac97)
 {
 	/* shared Line-In */
 	snd_ac97_update_bits(ac97, 0x76, 1 << 9,
@@ -2728,18 +2732,18 @@
 			     is_shared_micin(ac97) ? (1<<10) : 0);
 }
 
-static const snd_kcontrol_new_t snd_ac97_controls_it2646[] = {
+static const struct snd_kcontrol_new snd_ac97_controls_it2646[] = {
 	AC97_SURROUND_JACK_MODE_CTL,
 	AC97_CHANNEL_MODE_CTL,
 };
 
-static const snd_kcontrol_new_t snd_ac97_spdif_controls_it2646[] = {
+static const struct snd_kcontrol_new snd_ac97_spdif_controls_it2646[] = {
 	AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0x76, 11, 1, 0),
 	AC97_SINGLE("Analog to IEC958 Output", 0x76, 12, 1, 0),
 	AC97_SINGLE("IEC958 Input Monitor", 0x76, 13, 1, 0),
 };
 
-static int patch_it2646_specific(ac97_t * ac97)
+static int patch_it2646_specific(struct snd_ac97 * ac97)
 {
 	int err;
 	if ((err = patch_build_controls(ac97, snd_ac97_controls_it2646, ARRAY_SIZE(snd_ac97_controls_it2646))) < 0)
@@ -2754,7 +2758,7 @@
 	.update_jacks = it2646_update_jacks
 };
 
-int patch_it2646(ac97_t * ac97)
+int patch_it2646(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_it2646_ops;
 	/* full DAC volume */
@@ -2770,11 +2774,11 @@
 #define AC97_SI3036_CHIP_ID     0x5a
 #define AC97_SI3036_LINE_CFG    0x5c
 
-static const snd_kcontrol_new_t snd_ac97_controls_si3036[] = {
+static const struct snd_kcontrol_new snd_ac97_controls_si3036[] = {
 AC97_DOUBLE("Modem Speaker Volume", 0x5c, 14, 12, 3, 1)
 };
 
-static int patch_si3036_specific(ac97_t * ac97)
+static int patch_si3036_specific(struct snd_ac97 * ac97)
 {
 	int idx, err;
 	for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_si3036); idx++)
@@ -2787,7 +2791,7 @@
 	.build_specific	= patch_si3036_specific,
 };
 
-int mpatch_si3036(ac97_t * ac97)
+int mpatch_si3036(struct snd_ac97 * ac97)
 {
 	ac97->build_ops = &patch_si3036_ops;
 	snd_ac97_write_cache(ac97, 0x5c, 0xf210 );
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h
index ec18113..5060cb6 100644
--- a/sound/pci/ac97/ac97_patch.h
+++ b/sound/pci/ac97/ac97_patch.h
@@ -22,40 +22,40 @@
  *
  */
 
-int patch_yamaha_ymf753(ac97_t * ac97);
-int patch_wolfson00(ac97_t * ac97);
-int patch_wolfson03(ac97_t * ac97);
-int patch_wolfson04(ac97_t * ac97);
-int patch_wolfson05(ac97_t * ac97);
-int patch_wolfson11(ac97_t * ac97);
-int patch_wolfson13(ac97_t * ac97);
-int patch_tritech_tr28028(ac97_t * ac97);
-int patch_sigmatel_stac9700(ac97_t * ac97);
-int patch_sigmatel_stac9708(ac97_t * ac97);
-int patch_sigmatel_stac9721(ac97_t * ac97);
-int patch_sigmatel_stac9744(ac97_t * ac97);
-int patch_sigmatel_stac9756(ac97_t * ac97);
-int patch_sigmatel_stac9758(ac97_t * ac97);
-int patch_cirrus_cs4299(ac97_t * ac97);
-int patch_cirrus_spdif(ac97_t * ac97);
-int patch_conexant(ac97_t * ac97);
-int patch_ad1819(ac97_t * ac97);
-int patch_ad1881(ac97_t * ac97);
-int patch_ad1885(ac97_t * ac97);
-int patch_ad1886(ac97_t * ac97);
-int patch_ad1888(ac97_t * ac97);
-int patch_ad1980(ac97_t * ac97);
-int patch_ad1981a(ac97_t * ac97);
-int patch_ad1981b(ac97_t * ac97);
-int patch_ad1985(ac97_t * ac97);
-int patch_alc650(ac97_t * ac97);
-int patch_alc655(ac97_t * ac97);
-int patch_alc850(ac97_t * ac97);
-int patch_cm9738(ac97_t * ac97);
-int patch_cm9739(ac97_t * ac97);
-int patch_cm9761(ac97_t * ac97);
-int patch_cm9780(ac97_t * ac97);
-int patch_vt1616(ac97_t * ac97);
-int patch_vt1617a(ac97_t * ac97);
-int patch_it2646(ac97_t * ac97);
-int mpatch_si3036(ac97_t * ac97);
+int patch_yamaha_ymf753(struct snd_ac97 * ac97);
+int patch_wolfson00(struct snd_ac97 * ac97);
+int patch_wolfson03(struct snd_ac97 * ac97);
+int patch_wolfson04(struct snd_ac97 * ac97);
+int patch_wolfson05(struct snd_ac97 * ac97);
+int patch_wolfson11(struct snd_ac97 * ac97);
+int patch_wolfson13(struct snd_ac97 * ac97);
+int patch_tritech_tr28028(struct snd_ac97 * ac97);
+int patch_sigmatel_stac9700(struct snd_ac97 * ac97);
+int patch_sigmatel_stac9708(struct snd_ac97 * ac97);
+int patch_sigmatel_stac9721(struct snd_ac97 * ac97);
+int patch_sigmatel_stac9744(struct snd_ac97 * ac97);
+int patch_sigmatel_stac9756(struct snd_ac97 * ac97);
+int patch_sigmatel_stac9758(struct snd_ac97 * ac97);
+int patch_cirrus_cs4299(struct snd_ac97 * ac97);
+int patch_cirrus_spdif(struct snd_ac97 * ac97);
+int patch_conexant(struct snd_ac97 * ac97);
+int patch_ad1819(struct snd_ac97 * ac97);
+int patch_ad1881(struct snd_ac97 * ac97);
+int patch_ad1885(struct snd_ac97 * ac97);
+int patch_ad1886(struct snd_ac97 * ac97);
+int patch_ad1888(struct snd_ac97 * ac97);
+int patch_ad1980(struct snd_ac97 * ac97);
+int patch_ad1981a(struct snd_ac97 * ac97);
+int patch_ad1981b(struct snd_ac97 * ac97);
+int patch_ad1985(struct snd_ac97 * ac97);
+int patch_alc650(struct snd_ac97 * ac97);
+int patch_alc655(struct snd_ac97 * ac97);
+int patch_alc850(struct snd_ac97 * ac97);
+int patch_cm9738(struct snd_ac97 * ac97);
+int patch_cm9739(struct snd_ac97 * ac97);
+int patch_cm9761(struct snd_ac97 * ac97);
+int patch_cm9780(struct snd_ac97 * ac97);
+int patch_vt1616(struct snd_ac97 * ac97);
+int patch_vt1617a(struct snd_ac97 * ac97);
+int patch_it2646(struct snd_ac97 * ac97);
+int mpatch_si3036(struct snd_ac97 * ac97);
diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c
index ded1316..c3e590b 100644
--- a/sound/pci/ac97/ac97_pcm.c
+++ b/sound/pci/ac97/ac97_pcm.c
@@ -170,7 +170,7 @@
 		return rate_cregs[slot - 3];
 }
 
-static int set_spdif_rate(ac97_t *ac97, unsigned short rate)
+static int set_spdif_rate(struct snd_ac97 *ac97, unsigned short rate)
 {
 	unsigned short old, bits, reg, mask;
 	unsigned int sbits;
@@ -254,7 +254,7 @@
  *
  * Returns zero if successful, or a negative error code on failure.
  */
-int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate)
+int snd_ac97_set_rate(struct snd_ac97 *ac97, int reg, unsigned int rate)
 {
 	int dbl;
 	unsigned int tmp;
@@ -315,7 +315,7 @@
 	return 0;
 }
 
-static unsigned short get_pslots(ac97_t *ac97, unsigned char *rate_table, unsigned short *spdif_slots)
+static unsigned short get_pslots(struct snd_ac97 *ac97, unsigned char *rate_table, unsigned short *spdif_slots)
 {
 	if (!ac97_is_audio(ac97))
 		return 0;
@@ -390,7 +390,7 @@
 	}
 }
 
-static unsigned short get_cslots(ac97_t *ac97)
+static unsigned short get_cslots(struct snd_ac97 *ac97)
 {
 	unsigned short slots;
 
@@ -437,7 +437,7 @@
  * some slots are available, pcm->xxx.slots and pcm->xxx.rslots[] members
  * are reduced and might be zero.
  */
-int snd_ac97_pcm_assign(ac97_bus_t *bus,
+int snd_ac97_pcm_assign(struct snd_ac97_bus *bus,
 			unsigned short pcms_count,
 			const struct ac97_pcm *pcms)
 {
@@ -449,7 +449,7 @@
 	unsigned short tmp, slots;
 	unsigned short spdif_slots[4];
 	unsigned int rates;
-	ac97_t *codec;
+	struct snd_ac97 *codec;
 
 	rpcms = kcalloc(pcms_count, sizeof(struct ac97_pcm), GFP_KERNEL);
 	if (rpcms == NULL)
@@ -560,7 +560,7 @@
 int snd_ac97_pcm_open(struct ac97_pcm *pcm, unsigned int rate,
 		      enum ac97_pcm_cfg cfg, unsigned short slots)
 {
-	ac97_bus_t *bus;
+	struct snd_ac97_bus *bus;
 	int i, cidx, r, ok_flag;
 	unsigned int reg_ok[4] = {0,0,0,0};
 	unsigned char reg;
@@ -639,7 +639,7 @@
  */
 int snd_ac97_pcm_close(struct ac97_pcm *pcm)
 {
-	ac97_bus_t *bus;
+	struct snd_ac97_bus *bus;
 	unsigned short slots = pcm->aslots;
 	int i, cidx;
 
@@ -656,31 +656,31 @@
 	return 0;
 }
 
-static int double_rate_hw_constraint_rate(snd_pcm_hw_params_t *params,
-					  snd_pcm_hw_rule_t *rule)
+static int double_rate_hw_constraint_rate(struct snd_pcm_hw_params *params,
+					  struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 	if (channels->min > 2) {
-		static const snd_interval_t single_rates = {
+		static const struct snd_interval single_rates = {
 			.min = 1,
 			.max = 48000,
 		};
-		snd_interval_t *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+		struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 		return snd_interval_refine(rate, &single_rates);
 	}
 	return 0;
 }
 
-static int double_rate_hw_constraint_channels(snd_pcm_hw_params_t *params,
-					      snd_pcm_hw_rule_t *rule)
+static int double_rate_hw_constraint_channels(struct snd_pcm_hw_params *params,
+					      struct snd_pcm_hw_rule *rule)
 {
-	snd_interval_t *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (rate->min > 48000) {
-		static const snd_interval_t double_rate_channels = {
+		static const struct snd_interval double_rate_channels = {
 			.min = 2,
 			.max = 2,
 		};
-		snd_interval_t *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+		struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 		return snd_interval_refine(channels, &double_rate_channels);
 	}
 	return 0;
@@ -693,7 +693,7 @@
  * Installs the hardware constraint rules to prevent using double rates and
  * more than two channels at the same time.
  */
-int snd_ac97_pcm_double_rate_rules(snd_pcm_runtime_t *runtime)
+int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime)
 {
 	int err;
 
diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c
index a040b26..7134b3f 100644
--- a/sound/pci/ac97/ac97_proc.c
+++ b/sound/pci/ac97/ac97_proc.c
@@ -34,7 +34,7 @@
  * proc interface
  */
 
-static void snd_ac97_proc_read_functions(ac97_t *ac97, snd_info_buffer_t *buffer)
+static void snd_ac97_proc_read_functions(struct snd_ac97 *ac97, struct snd_info_buffer *buffer)
 {
 	int header = 0, function;
 	unsigned short info, sense_info;
@@ -68,7 +68,43 @@
 	}
 }
 
-static void snd_ac97_proc_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, int subidx)
+static const char *snd_ac97_stereo_enhancements[] =
+{
+  /*   0 */ "No 3D Stereo Enhancement",
+  /*   1 */ "Analog Devices Phat Stereo",
+  /*   2 */ "Creative Stereo Enhancement",
+  /*   3 */ "National Semi 3D Stereo Enhancement",
+  /*   4 */ "YAMAHA Ymersion",
+  /*   5 */ "BBE 3D Stereo Enhancement",
+  /*   6 */ "Crystal Semi 3D Stereo Enhancement",
+  /*   7 */ "Qsound QXpander",
+  /*   8 */ "Spatializer 3D Stereo Enhancement",
+  /*   9 */ "SRS 3D Stereo Enhancement",
+  /*  10 */ "Platform Tech 3D Stereo Enhancement",
+  /*  11 */ "AKM 3D Audio",
+  /*  12 */ "Aureal Stereo Enhancement",
+  /*  13 */ "Aztech 3D Enhancement",
+  /*  14 */ "Binaura 3D Audio Enhancement",
+  /*  15 */ "ESS Technology Stereo Enhancement",
+  /*  16 */ "Harman International VMAx",
+  /*  17 */ "Nvidea/IC Ensemble/KS Waves 3D Stereo Enhancement",
+  /*  18 */ "Philips Incredible Sound",
+  /*  19 */ "Texas Instruments 3D Stereo Enhancement",
+  /*  20 */ "VLSI Technology 3D Stereo Enhancement",
+  /*  21 */ "TriTech 3D Stereo Enhancement",
+  /*  22 */ "Realtek 3D Stereo Enhancement",
+  /*  23 */ "Samsung 3D Stereo Enhancement",
+  /*  24 */ "Wolfson Microelectronics 3D Enhancement",
+  /*  25 */ "Delta Integration 3D Enhancement",
+  /*  26 */ "SigmaTel 3D Enhancement",
+  /*  27 */ "IC Ensemble/KS Waves",
+  /*  28 */ "Rockwell 3D Stereo Enhancement",
+  /*  29 */ "Reserved 29",
+  /*  30 */ "Reserved 30",
+  /*  31 */ "Reserved 31"
+};
+
+static void snd_ac97_proc_read_main(struct snd_ac97 *ac97, struct snd_info_buffer *buffer, int subidx)
 {
 	char name[64];
 	unsigned short val, tmp, ext, mext;
@@ -79,9 +115,15 @@
 
 	snd_ac97_get_name(NULL, ac97->id, name, 0);
 	snd_iprintf(buffer, "%d-%d/%d: %s\n\n", ac97->addr, ac97->num, subidx, name);
+
 	if ((ac97->scaps & AC97_SCAP_AUDIO) == 0)
 		goto __modem;
 
+        snd_iprintf(buffer, "PCI Subsys Vendor: 0x%04x\n",
+	            ac97->subsystem_vendor);
+        snd_iprintf(buffer, "PCI Subsys Device: 0x%04x\n\n",
+                    ac97->subsystem_device);
+
 	if ((ac97->ext_id & AC97_EI_REV_MASK) >= AC97_EI_REV_23) {
 		val = snd_ac97_read(ac97, AC97_INT_PAGING);
 		snd_ac97_update_bits(ac97, AC97_INT_PAGING,
@@ -292,9 +334,9 @@
 	}
 }
 
-static void snd_ac97_proc_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void snd_ac97_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	ac97_t *ac97 = entry->private_data;
+	struct snd_ac97 *ac97 = entry->private_data;
 	
 	down(&ac97->page_mutex);
 	if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {	// Analog Devices AD1881/85/86
@@ -327,9 +369,9 @@
 
 #ifdef CONFIG_SND_DEBUG
 /* direct register write for debugging */
-static void snd_ac97_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_ac97_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	ac97_t *ac97 = entry->private_data;
+	struct snd_ac97 *ac97 = entry->private_data;
 	char line[64];
 	unsigned int reg, val;
 	down(&ac97->page_mutex);
@@ -344,7 +386,7 @@
 }
 #endif
 
-static void snd_ac97_proc_regs_read_main(ac97_t *ac97, snd_info_buffer_t * buffer, int subidx)
+static void snd_ac97_proc_regs_read_main(struct snd_ac97 *ac97, struct snd_info_buffer *buffer, int subidx)
 {
 	int reg, val;
 
@@ -354,10 +396,10 @@
 	}
 }
 
-static void snd_ac97_proc_regs_read(snd_info_entry_t *entry, 
-				    snd_info_buffer_t * buffer)
+static void snd_ac97_proc_regs_read(struct snd_info_entry *entry, 
+				    struct snd_info_buffer *buffer)
 {
-	ac97_t *ac97 = entry->private_data;
+	struct snd_ac97 *ac97 = entry->private_data;
 
 	down(&ac97->page_mutex);
 	if ((ac97->id & 0xffffff40) == AC97_ID_AD1881) {	// Analog Devices AD1881/85/86
@@ -378,9 +420,9 @@
 	up(&ac97->page_mutex);
 }
 
-void snd_ac97_proc_init(ac97_t * ac97)
+void snd_ac97_proc_init(struct snd_ac97 * ac97)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	char name[32];
 	const char *prefix;
 
@@ -412,7 +454,7 @@
 	ac97->proc_regs = entry;
 }
 
-void snd_ac97_proc_done(ac97_t * ac97)
+void snd_ac97_proc_done(struct snd_ac97 * ac97)
 {
 	if (ac97->proc_regs) {
 		snd_info_unregister(ac97->proc_regs);
@@ -424,9 +466,9 @@
 	}
 }
 
-void snd_ac97_bus_proc_init(ac97_bus_t * bus)
+void snd_ac97_bus_proc_init(struct snd_ac97_bus * bus)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	char name[32];
 
 	sprintf(name, "codec97#%d", bus->num);
@@ -440,7 +482,7 @@
 	bus->proc = entry;
 }
 
-void snd_ac97_bus_proc_done(ac97_bus_t * bus)
+void snd_ac97_bus_proc_done(struct snd_ac97_bus * bus)
 {
 	if (bus->proc) {
 		snd_info_unregister(bus->proc);
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
index 4032c57..dcfb503 100644
--- a/sound/pci/ac97/ak4531_codec.c
+++ b/sound/pci/ac97/ak4531_codec.c
@@ -30,7 +30,11 @@
 MODULE_DESCRIPTION("Universal routines for AK4531 codec");
 MODULE_LICENSE("GPL");
 
-static void snd_ak4531_proc_init(snd_card_t * card, ak4531_t * ak4531);
+#ifdef CONFIG_PROC_FS
+static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531);
+#else
+#define snd_ak4531_proc_init(card,ak)
+#endif
 
 /*
  *
@@ -38,7 +42,7 @@
  
 #if 0
 
-static void snd_ak4531_dump(ak4531_t *ak4531)
+static void snd_ak4531_dump(struct snd_ak4531 *ak4531)
 {
 	int idx;
 	
@@ -58,7 +62,7 @@
   .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \
   .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22) }
 
-static int snd_ak4531_info_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4531_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -69,9 +73,9 @@
 	return 0;
 }
  
-static int snd_ak4531_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4531_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
+	struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 16) & 0x07;
 	int mask = (kcontrol->private_value >> 24) & 0xff;
@@ -88,9 +92,9 @@
 	return 0;
 }
 
-static int snd_ak4531_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4531_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
+	struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 16) & 0x07;
 	int mask = (kcontrol->private_value >> 24) & 0xff;
@@ -117,7 +121,7 @@
   .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \
   .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22) }
 
-static int snd_ak4531_info_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4531_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -128,9 +132,9 @@
 	return 0;
 }
  
-static int snd_ak4531_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4531_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
+	struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int left_shift = (kcontrol->private_value >> 16) & 0x07;
@@ -152,9 +156,9 @@
 	return 0;
 }
 
-static int snd_ak4531_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
+	struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int left_shift = (kcontrol->private_value >> 16) & 0x07;
@@ -194,7 +198,7 @@
   .get = snd_ak4531_get_input_sw, .put = snd_ak4531_put_input_sw, \
   .private_value = reg1 | (reg2 << 8) | (left_shift << 16) | (right_shift << 24) }
 
-static int snd_ak4531_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ak4531_info_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 4;
@@ -203,9 +207,9 @@
 	return 0;
 }
  
-static int snd_ak4531_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4531_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
+	struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
 	int reg1 = kcontrol->private_value & 0xff;
 	int reg2 = (kcontrol->private_value >> 8) & 0xff;
 	int left_shift = (kcontrol->private_value >> 16) & 0x0f;
@@ -220,9 +224,9 @@
 	return 0;
 }
 
-static int snd_ak4531_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ak4531_t *ak4531 = snd_kcontrol_chip(kcontrol);
+	struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
 	int reg1 = kcontrol->private_value & 0xff;
 	int reg2 = (kcontrol->private_value >> 8) & 0xff;
 	int left_shift = (kcontrol->private_value >> 16) & 0x0f;
@@ -244,7 +248,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ak4531_controls[] = {
+static struct snd_kcontrol_new snd_ak4531_controls[] = {
 
 AK4531_DOUBLE("Master Playback Switch", 0, AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1),
 AK4531_DOUBLE("Master Playback Volume", 0, AK4531_LMASTER, AK4531_RMASTER, 0, 0, 0x1f, 1),
@@ -300,7 +304,7 @@
 AK4531_SINGLE("Mic Boost (+30dB)", 0, AK4531_MIC_GAIN, 0, 1, 0)
 };
 
-static int snd_ak4531_free(ak4531_t *ak4531)
+static int snd_ak4531_free(struct snd_ak4531 *ak4531)
 {
 	if (ak4531) {
 		if (ak4531->private_free)
@@ -310,9 +314,9 @@
 	return 0;
 }
 
-static int snd_ak4531_dev_free(snd_device_t *device)
+static int snd_ak4531_dev_free(struct snd_device *device)
 {
-	ak4531_t *ak4531 = device->device_data;
+	struct snd_ak4531 *ak4531 = device->device_data;
 	return snd_ak4531_free(ak4531);
 }
 
@@ -345,12 +349,13 @@
 	0x01		/* 19: Mic Amp Setup */
 };
 
-int snd_ak4531_mixer(snd_card_t * card, ak4531_t * _ak4531, ak4531_t ** rak4531)
+int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531,
+		     struct snd_ak4531 **rak4531)
 {
 	unsigned int idx;
 	int err;
-	ak4531_t * ak4531;
-	static snd_device_ops_t ops = {
+	struct snd_ak4531 *ak4531;
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_ak4531_dev_free,
 	};
 
@@ -370,7 +375,7 @@
 	ak4531->write(ak4531, AK4531_RESET, 0x03);	/* no RST, PD */
 	udelay(100);
 	ak4531->write(ak4531, AK4531_CLOCK, 0x00);	/* CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off LRCLK2 PLL */
-	for (idx = 0; idx < 0x19; idx++) {
+	for (idx = 0; idx <= 0x19; idx++) {
 		if (idx == AK4531_RESET || idx == AK4531_CLOCK)
 			continue;
 		ak4531->write(ak4531, idx, ak4531->regs[idx] = snd_ak4531_initial_map[idx]);	/* recording source is mixer */
@@ -395,13 +400,44 @@
 }
 
 /*
+ * power management
+ */
+#ifdef CONFIG_PM
+void snd_ak4531_suspend(struct snd_ak4531 *ak4531)
+{
+	/* mute */
+	ak4531->write(ak4531, AK4531_LMASTER, 0x9f);
+	ak4531->write(ak4531, AK4531_RMASTER, 0x9f);
+	/* powerdown */
+	ak4531->write(ak4531, AK4531_RESET, 0x01);
+}
 
+void snd_ak4531_resume(struct snd_ak4531 *ak4531)
+{
+	int idx;
+
+	/* initialize */
+	ak4531->write(ak4531, AK4531_RESET, 0x03);
+	udelay(100);
+	ak4531->write(ak4531, AK4531_CLOCK, 0x00);
+	/* restore mixer registers */
+	for (idx = 0; idx <= 0x19; idx++) {
+		if (idx == AK4531_RESET || idx == AK4531_CLOCK)
+			continue;
+		ak4531->write(ak4531, idx, ak4531->regs[idx]);
+	}
+}
+#endif
+
+#ifdef CONFIG_PROC_FS
+/*
+ * /proc interface
  */
 
-static void snd_ak4531_proc_read(snd_info_entry_t *entry, 
-				 snd_info_buffer_t * buffer)
+static void snd_ak4531_proc_read(struct snd_info_entry *entry, 
+				 struct snd_info_buffer *buffer)
 {
-	ak4531_t *ak4531 = entry->private_data;
+	struct snd_ak4531 *ak4531 = entry->private_data;
 
 	snd_iprintf(buffer, "Asahi Kasei AK4531\n\n");
 	snd_iprintf(buffer, "Recording source   : %s\n"
@@ -410,15 +446,20 @@
 		    ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB");
 }
 
-static void snd_ak4531_proc_init(snd_card_t * card, ak4531_t * ak4531)
+static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(card, "ak4531", &entry))
 		snd_info_set_text_ops(entry, ak4531, 1024, snd_ak4531_proc_read);
 }
+#endif
 
 EXPORT_SYMBOL(snd_ak4531_mixer);
+#ifdef CONFIG_PM
+EXPORT_SYMBOL(snd_ak4531_suspend);
+EXPORT_SYMBOL(snd_ak4531_resume);
+#endif
 
 /*
  *  INIT part
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 1fdae67..a208075 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -50,7 +50,7 @@
 #include "ad1889.h"
 #include "ac97/ac97_id.h"
 
-#define	AD1889_DRVVER	"$Revision: 1.4 $"
+#define	AD1889_DRVVER	"Version: 1.7"
 
 MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
 MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
@@ -87,20 +87,20 @@
 };
 
 struct snd_ad1889 {
-	snd_card_t *card;
+	struct snd_card *card;
 	struct pci_dev *pci;
 
 	int irq;
 	unsigned long bar;
 	void __iomem *iobase;
 
-	ac97_t *ac97;
-	ac97_bus_t *ac97_bus;
-	snd_pcm_t *pcm;
-	snd_info_entry_t *proc;
+	struct snd_ac97 *ac97;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_pcm *pcm;
+	struct snd_info_entry *proc;
 
-	snd_pcm_substream_t *psubs;
-	snd_pcm_substream_t *csubs;
+	struct snd_pcm_substream *psubs;
+	struct snd_pcm_substream *csubs;
 
 	/* playback register state */
 	struct ad1889_register_state wave;
@@ -241,14 +241,14 @@
 }
 
 static inline u16
-snd_ad1889_ac97_read(ac97_t *ac97, unsigned short reg)
+snd_ad1889_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
 	struct snd_ad1889 *chip = ac97->private_data;
 	return ad1889_readw(chip, AD_AC97_BASE + reg);
 }
 
 static inline void
-snd_ad1889_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+snd_ad1889_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
 	struct snd_ad1889 *chip = ac97->private_data;
 	ad1889_writew(chip, AD_AC97_BASE + reg, val);
@@ -273,20 +273,20 @@
 }
 
 static int 
-snd_ad1889_hw_params(snd_pcm_substream_t *substream,
-			snd_pcm_hw_params_t *hw_params)
+snd_ad1889_hw_params(struct snd_pcm_substream *substream,
+			struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, 
 					params_buffer_bytes(hw_params));
 }
 
 static int
-snd_ad1889_hw_free(snd_pcm_substream_t *substream)
+snd_ad1889_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static snd_pcm_hardware_t snd_ad1889_playback_hw = {
+static struct snd_pcm_hardware snd_ad1889_playback_hw = {
 	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 		SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
@@ -303,7 +303,7 @@
 	/*.fifo_size = 0,*/
 };
 
-static snd_pcm_hardware_t snd_ad1889_capture_hw = {
+static struct snd_pcm_hardware snd_ad1889_capture_hw = {
 	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 		SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_BLOCK_TRANSFER,
 	.formats = SNDRV_PCM_FMTBIT_S16_LE,
@@ -321,10 +321,10 @@
 };
 
 static int
-snd_ad1889_playback_open(snd_pcm_substream_t *ss)
+snd_ad1889_playback_open(struct snd_pcm_substream *ss)
 {
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
-	snd_pcm_runtime_t *rt = ss->runtime;
+	struct snd_pcm_runtime *rt = ss->runtime;
 
 	chip->psubs = ss;
 	rt->hw = snd_ad1889_playback_hw;
@@ -333,10 +333,10 @@
 }
 
 static int
-snd_ad1889_capture_open(snd_pcm_substream_t *ss)
+snd_ad1889_capture_open(struct snd_pcm_substream *ss)
 {
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
-	snd_pcm_runtime_t *rt = ss->runtime;
+	struct snd_pcm_runtime *rt = ss->runtime;
 
 	chip->csubs = ss;
 	rt->hw = snd_ad1889_capture_hw;
@@ -345,7 +345,7 @@
 }
 
 static int
-snd_ad1889_playback_close(snd_pcm_substream_t *ss)
+snd_ad1889_playback_close(struct snd_pcm_substream *ss)
 {
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
 	chip->psubs = NULL;
@@ -353,7 +353,7 @@
 }
 
 static int
-snd_ad1889_capture_close(snd_pcm_substream_t *ss)
+snd_ad1889_capture_close(struct snd_pcm_substream *ss)
 {
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
 	chip->csubs = NULL;
@@ -361,10 +361,10 @@
 }
 
 static int
-snd_ad1889_playback_prepare(snd_pcm_substream_t *ss)
+snd_ad1889_playback_prepare(struct snd_pcm_substream *ss)
 {
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
-	snd_pcm_runtime_t *rt = ss->runtime;
+	struct snd_pcm_runtime *rt = ss->runtime;
 	unsigned int size = snd_pcm_lib_buffer_bytes(ss);
 	unsigned int count = snd_pcm_lib_period_bytes(ss);
 	u16 reg;
@@ -411,10 +411,10 @@
 }
 
 static int
-snd_ad1889_capture_prepare(snd_pcm_substream_t *ss)
+snd_ad1889_capture_prepare(struct snd_pcm_substream *ss)
 {
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
-	snd_pcm_runtime_t *rt = ss->runtime;
+	struct snd_pcm_runtime *rt = ss->runtime;
 	unsigned int size = snd_pcm_lib_buffer_bytes(ss);
 	unsigned int count = snd_pcm_lib_period_bytes(ss);
 	u16 reg;
@@ -462,7 +462,7 @@
    DMA should be *triggered* by this call.
    The WSMC "WAEN" bit triggers DMA Wave On/Off */
 static int
-snd_ad1889_playback_trigger(snd_pcm_substream_t *ss, int cmd)
+snd_ad1889_playback_trigger(struct snd_pcm_substream *ss, int cmd)
 {
 	u16 wsmc;
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
@@ -503,7 +503,7 @@
    DMA should be *triggered* by this call.
    The RAMC "ADEN" bit triggers DMA ADC On/Off */
 static int
-snd_ad1889_capture_trigger(snd_pcm_substream_t *ss, int cmd)
+snd_ad1889_capture_trigger(struct snd_pcm_substream *ss, int cmd)
 {
 	u16 ramc;
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
@@ -538,7 +538,7 @@
 
 /* Called in atomic context with IRQ disabled */
 static snd_pcm_uframes_t
-snd_ad1889_playback_pointer(snd_pcm_substream_t *ss)
+snd_ad1889_playback_pointer(struct snd_pcm_substream *ss)
 {
 	size_t ptr = 0;
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
@@ -556,7 +556,7 @@
 
 /* Called in atomic context with IRQ disabled */
 static snd_pcm_uframes_t
-snd_ad1889_capture_pointer(snd_pcm_substream_t *ss)
+snd_ad1889_capture_pointer(struct snd_pcm_substream *ss)
 {
 	size_t ptr = 0;
 	struct snd_ad1889 *chip = snd_pcm_substream_chip(ss);
@@ -572,7 +572,7 @@
 	return bytes_to_frames(ss->runtime, ptr);
 }
 
-static snd_pcm_ops_t snd_ad1889_playback_ops = {
+static struct snd_pcm_ops snd_ad1889_playback_ops = {
 	.open = snd_ad1889_playback_open,
 	.close = snd_ad1889_playback_close,
 	.ioctl = snd_pcm_lib_ioctl,
@@ -583,7 +583,7 @@
 	.pointer = snd_ad1889_playback_pointer, 
 };
 
-static snd_pcm_ops_t snd_ad1889_capture_ops = {
+static struct snd_pcm_ops snd_ad1889_capture_ops = {
 	.open = snd_ad1889_capture_open,
 	.close = snd_ad1889_capture_close,
 	.ioctl = snd_pcm_lib_ioctl,
@@ -623,19 +623,11 @@
 	return IRQ_HANDLED;
 }
 
-static void 
-snd_ad1889_pcm_free(snd_pcm_t *pcm)
-{
-	struct snd_ad1889 *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
 static int __devinit
-snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, snd_pcm_t **rpcm)
+snd_ad1889_pcm_init(struct snd_ad1889 *chip, int device, struct snd_pcm **rpcm)
 {
 	int err;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 
 	if (rpcm)
 		*rpcm = NULL;
@@ -650,7 +642,6 @@
 			&snd_ad1889_capture_ops);
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_ad1889_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, chip->card->shortname);
 	
@@ -675,7 +666,7 @@
 }
 
 static void
-snd_ad1889_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+snd_ad1889_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
 	struct snd_ad1889 *chip = entry->private_data;
 	u16 reg;
@@ -758,7 +749,7 @@
 static void __devinit
 snd_ad1889_proc_init(struct snd_ad1889 *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (!snd_card_proc_new(chip->card, chip->card->driver, &entry))
 		snd_info_set_text_ops(entry, chip, 1024, snd_ad1889_proc_read);
@@ -800,14 +791,14 @@
 }
 
 static void
-snd_ad1889_ac97_bus_free(ac97_bus_t *bus)
+snd_ad1889_ac97_bus_free(struct snd_ac97_bus *bus)
 {
 	struct snd_ad1889 *chip = bus->private_data;
 	chip->ac97_bus = NULL;
 }
 
 static void
-snd_ad1889_ac97_free(ac97_t *ac97)
+snd_ad1889_ac97_free(struct snd_ac97 *ac97)
 {
 	struct snd_ad1889 *chip = ac97->private_data;
 	chip->ac97 = NULL;
@@ -817,8 +808,8 @@
 snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override)
 {
 	int err;
-	ac97_template_t ac97;
-	static ac97_bus_ops_t ops = {
+	struct snd_ac97_template ac97;
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_ad1889_ac97_write,
 		.read = snd_ad1889_ac97_read,
 	};
@@ -882,7 +873,7 @@
 }
 
 static inline int
-snd_ad1889_dev_free(snd_device_t *device) 
+snd_ad1889_dev_free(struct snd_device *device) 
 {
 	struct snd_ad1889 *chip = device->device_data;
 	return snd_ad1889_free(chip);
@@ -903,14 +894,14 @@
 }
 
 static int __devinit
-snd_ad1889_create(snd_card_t *card,
+snd_ad1889_create(struct snd_card *card,
 		  struct pci_dev *pci,
 		  struct snd_ad1889 **rchip)
 {
 	int err;
 
 	struct snd_ad1889 *chip;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_ad1889_dev_free,
 	};
 
@@ -994,7 +985,7 @@
 {
 	int err;
 	static int devno;
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_ad1889 *chip;
 
 	/* (1) */
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index feffbe7..bc4d1ef 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -170,10 +170,10 @@
 #define MAX_CODECS 2
 
 
-typedef struct snd_stru_ali ali_t;
-typedef struct snd_ali_stru_voice snd_ali_voice_t;
+struct snd_ali;
+struct snd_ali_voice;
 
-typedef struct snd_ali_channel_control {
+struct snd_ali_channel_control {
 	// register data
 	struct REGDATA {
 		unsigned int start;
@@ -192,9 +192,9 @@
 		unsigned int ac97write;
 	} regs;
 
-} snd_ali_channel_control_t;
+};
 
-struct snd_ali_stru_voice {
+struct snd_ali_voice {
 	unsigned int number;
 	unsigned int use: 1,
 	    pcm: 1,
@@ -203,9 +203,9 @@
 	    synth: 1;
 
 	/* PCM data */
-	ali_t *codec;
-	snd_pcm_substream_t *substream;
-	snd_ali_voice_t *extra;
+	struct snd_ali *codec;
+	struct snd_pcm_substream *substream;
+	struct snd_ali_voice *extra;
 	
 	unsigned int running: 1;
 
@@ -219,28 +219,28 @@
 };
 
 
-typedef struct snd_stru_alidev {
+struct snd_alidev {
 
-	snd_ali_voice_t voices[ALI_CHANNELS];	
+	struct snd_ali_voice voices[ALI_CHANNELS];	
 
 	unsigned int	chcnt;			/* num of opened channels */
 	unsigned int	chmap;			/* bitmap for opened channels */
 	unsigned int synthcount;
 
-} alidev_t;
+};
 
 
 #ifdef CONFIG_PM
 #define ALI_GLOBAL_REGS		56
 #define ALI_CHANNEL_REGS	8
-typedef struct snd_ali_image {
+struct snd_ali_image {
 	unsigned long regs[ALI_GLOBAL_REGS];
 	unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
-} ali_image_t;
+};
 #endif
 
 
-struct snd_stru_ali {
+struct snd_ali {
 	unsigned long	irq;
 	unsigned long	port;
 	unsigned char	revision;
@@ -252,10 +252,10 @@
 	struct pci_dev	*pci_m1533;
 	struct pci_dev	*pci_m7101;
 
-	snd_card_t	*card;
-	snd_pcm_t	*pcm[MAX_CODECS];
-	alidev_t	synth;
-	snd_ali_channel_control_t chregs;
+	struct snd_card	*card;
+	struct snd_pcm	*pcm[MAX_CODECS];
+	struct snd_alidev	synth;
+	struct snd_ali_channel_control chregs;
 
 	/* S/PDIF Mask */
 	unsigned int	spdif_mask;
@@ -265,8 +265,8 @@
 
 	unsigned int num_of_codecs;
 
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97[MAX_CODECS];
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97[MAX_CODECS];
 	unsigned short	ac97_ext_id;
 	unsigned short	ac97_ext_status;
 
@@ -274,7 +274,7 @@
 	spinlock_t	voice_alloc;
 
 #ifdef CONFIG_PM
-	ali_image_t *image;
+	struct snd_ali_image *image;
 #endif
 };
 
@@ -284,9 +284,9 @@
 };
 MODULE_DEVICE_TABLE(pci, snd_ali_ids);
 
-static void snd_ali_clear_voices(ali_t *, unsigned int, unsigned int);
-static unsigned short snd_ali_codec_peek(ali_t *, int, unsigned short);
-static void snd_ali_codec_poke(ali_t *, int, unsigned short, unsigned short);
+static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int);
+static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short);
+static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, unsigned short);
 
 /*
  *  Debug Part
@@ -294,7 +294,7 @@
 
 #ifdef ALI_DEBUG
 
-static void ali_read_regs(ali_t *codec, int channel)
+static void ali_read_regs(struct snd_ali *codec, int channel)
 {
 	int i,j;
 	unsigned int dwVal;
@@ -344,7 +344,7 @@
 	}
 	pci_dev_put(pci_dev);
  }
-static void ali_read_ac97regs(ali_t *codec, int secondary)
+static void ali_read_ac97regs(struct snd_ali *codec, int secondary)
 {
 	unsigned short i,j;
 	unsigned short wVal;
@@ -373,40 +373,38 @@
  *  AC97 ACCESS
  */
 
-static inline unsigned int snd_ali_5451_peek(ali_t *codec,
+static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec,
 						unsigned int port )
 {
 	return (unsigned int)inl(ALI_REG(codec, port)); 
 }
 
-static inline void snd_ali_5451_poke(	ali_t *codec,
+static inline void snd_ali_5451_poke(	struct snd_ali *codec,
 					unsigned int port,
 					unsigned int val )
 {
 	outl((unsigned int)val, ALI_REG(codec, port));
 }
 
-static int snd_ali_codec_ready(	ali_t *codec,
-				unsigned int port,
-				int sched )
+static int snd_ali_codec_ready(	struct snd_ali *codec,
+				unsigned int port )
 {
 	unsigned long end_time;
 	unsigned int res;
 	
-	end_time = jiffies + 10 * msecs_to_jiffies(250);
+	end_time = jiffies + msecs_to_jiffies(250);
 	do {
 		res = snd_ali_5451_peek(codec,port);
 		if (! (res & 0x8000))
 			return 0;
-		if (sched)
-			schedule_timeout_uninterruptible(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
 	snd_ali_5451_poke(codec, port, res & ~0x8000);
 	snd_printdd("ali_codec_ready: codec is not ready.\n ");
 	return -EIO;
 }
 
-static int snd_ali_stimer_ready(ali_t *codec, int sched)
+static int snd_ali_stimer_ready(struct snd_ali *codec)
 {
 	unsigned long end_time;
 	unsigned long dwChk1,dwChk2;
@@ -414,19 +412,18 @@
 	dwChk1 = snd_ali_5451_peek(codec, ALI_STIMER);
 	dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
 
-	end_time = jiffies + 10 * msecs_to_jiffies(250);
+	end_time = jiffies + msecs_to_jiffies(250);
 	do {
 		dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
 		if (dwChk2 != dwChk1)
 			return 0;
-		if (sched)
-			schedule_timeout_uninterruptible(1);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
 	snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n");
 	return -EIO;
 }
 
-static void snd_ali_codec_poke(ali_t *codec,int secondary,
+static void snd_ali_codec_poke(struct snd_ali *codec,int secondary,
 				     unsigned short reg,
 				     unsigned short val)
 {
@@ -440,9 +437,9 @@
 
 	port = codec->chregs.regs.ac97write;
 
-	if (snd_ali_codec_ready(codec, port, 0) < 0)
+	if (snd_ali_codec_ready(codec, port) < 0)
 		return;
-	if (snd_ali_stimer_ready(codec, 0) < 0)
+	if (snd_ali_stimer_ready(codec) < 0)
 		return;
 
 	dwVal  = (unsigned int) (reg & 0xff);
@@ -455,7 +452,7 @@
 	return ;
 }
 
-static unsigned short snd_ali_codec_peek( ali_t *codec,
+static unsigned short snd_ali_codec_peek( struct snd_ali *codec,
 					  int secondary,
 					  unsigned short reg)
 {
@@ -469,9 +466,9 @@
 
 	port = codec->chregs.regs.ac97read;
 
-	if (snd_ali_codec_ready(codec, port, 0) < 0)
+	if (snd_ali_codec_ready(codec, port) < 0)
 		return ~0;
-	if (snd_ali_stimer_ready(codec, 0) < 0)
+	if (snd_ali_stimer_ready(codec) < 0)
 		return ~0;
 
 	dwVal  = (unsigned int) (reg & 0xff);
@@ -480,19 +477,19 @@
 
 	snd_ali_5451_poke(codec, port, dwVal);
 
-	if (snd_ali_stimer_ready(codec, 0) < 0)
+	if (snd_ali_stimer_ready(codec) < 0)
 		return ~0;
-	if (snd_ali_codec_ready(codec, port, 0) < 0)
+	if (snd_ali_codec_ready(codec, port) < 0)
 		return ~0;
 	
 	return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16;
 }
 
-static void snd_ali_codec_write(ac97_t *ac97,
+static void snd_ali_codec_write(struct snd_ac97 *ac97,
 				unsigned short reg,
 				unsigned short val )
 {
-	ali_t *codec = ac97->private_data;
+	struct snd_ali *codec = ac97->private_data;
 
 	snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val);
 	if(reg == AC97_GPIO_STATUS) {
@@ -505,9 +502,9 @@
 }
 
 
-static unsigned short snd_ali_codec_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg)
 {
-	ali_t *codec = ac97->private_data;
+	struct snd_ali *codec = ac97->private_data;
 
 	snd_ali_printk("codec_read reg=%xh.\n", reg);
 	return (snd_ali_codec_peek(codec, ac97->num, reg));
@@ -517,7 +514,7 @@
  *	AC97 Reset
  */
 
-static int snd_ali_reset_5451(ali_t *codec)
+static int snd_ali_reset_5451(struct snd_ali *codec)
 {
 	struct pci_dev *pci_dev = NULL;
 	unsigned short wCount, wReg;
@@ -555,7 +552,7 @@
 
 #ifdef CODEC_RESET
 
-static int snd_ali_reset_codec(ali_t *codec)
+static int snd_ali_reset_codec(struct snd_ali *codec)
 {
 	struct pci_dev *pci_dev = NULL;
 	unsigned char bVal = 0;
@@ -596,7 +593,7 @@
  *  ALI 5451 Controller
  */
 
-static void snd_ali_enable_special_channel(ali_t *codec, unsigned int channel)
+static void snd_ali_enable_special_channel(struct snd_ali *codec, unsigned int channel)
 {
 	unsigned long dwVal = 0;
 
@@ -605,7 +602,7 @@
 	outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
 }
 
-static void snd_ali_disable_special_channel(ali_t *codec, unsigned int channel)
+static void snd_ali_disable_special_channel(struct snd_ali *codec, unsigned int channel)
 {
 	unsigned long dwVal = 0;
 
@@ -614,7 +611,7 @@
 	outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL));
 }
 
-static void snd_ali_enable_address_interrupt(ali_t * codec)
+static void snd_ali_enable_address_interrupt(struct snd_ali * codec)
 {
 	unsigned int gc;
 
@@ -624,7 +621,7 @@
 	outl( gc, ALI_REG(codec, ALI_GC_CIR));
 }
 
-static void snd_ali_disable_address_interrupt(ali_t * codec)
+static void snd_ali_disable_address_interrupt(struct snd_ali * codec)
 {
 	unsigned int gc;
 
@@ -635,10 +632,10 @@
 }
 
 #if 0 // not used
-static void snd_ali_enable_voice_irq(ali_t *codec, unsigned int channel)
+static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel)
 {
 	unsigned int mask;
-	snd_ali_channel_control_t *pchregs = &(codec->chregs);
+	struct snd_ali_channel_control *pchregs = &(codec->chregs);
 
 	snd_ali_printk("enable_voice_irq channel=%d\n",channel);
 	
@@ -649,10 +646,10 @@
 }
 #endif
 
-static void snd_ali_disable_voice_irq(ali_t *codec, unsigned int channel)
+static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channel)
 {
 	unsigned int mask;
-	snd_ali_channel_control_t *pchregs = &(codec->chregs);
+	struct snd_ali_channel_control *pchregs = &(codec->chregs);
 
 	snd_ali_printk("disable_voice_irq channel=%d\n",channel);
 
@@ -662,7 +659,7 @@
 	outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten));
 }
 
-static int snd_ali_alloc_pcm_channel(ali_t *codec, int channel)
+static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel)
 {
 	unsigned int idx =  channel & 0x1f;
 
@@ -680,7 +677,7 @@
 	return -1;
 }
 
-static int snd_ali_find_free_channel(ali_t * codec, int rec)
+static int snd_ali_find_free_channel(struct snd_ali * codec, int rec)
 {
 	int idx;
 	int result = -1;
@@ -722,7 +719,7 @@
 	return -1;
 }
 
-static void snd_ali_free_channel_pcm(ali_t *codec, int channel)
+static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
 {
 	unsigned int idx = channel & 0x0000001f;
 
@@ -741,7 +738,7 @@
 }
 
 #if 0 // not used
-static void snd_ali_start_voice(ali_t * codec, unsigned int channel)
+static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel)
 {
 	unsigned int mask = 1 << (channel & 0x1f);
 	
@@ -750,7 +747,7 @@
 }
 #endif
 
-static void snd_ali_stop_voice(ali_t * codec, unsigned int channel)
+static void snd_ali_stop_voice(struct snd_ali * codec, unsigned int channel)
 {
 	unsigned int mask = 1 << (channel & 0x1f);
 
@@ -762,7 +759,7 @@
  *    S/PDIF Part
  */
 
-static void snd_ali_delay(ali_t *codec,int interval)
+static void snd_ali_delay(struct snd_ali *codec,int interval)
 {
 	unsigned long  begintimer,currenttimer;
 
@@ -770,13 +767,13 @@
 	currenttimer = inl(ALI_REG(codec, ALI_STIMER));
 
 	while (currenttimer < begintimer + interval) {
-		if(snd_ali_stimer_ready(codec, 1) < 0)
+		if(snd_ali_stimer_ready(codec) < 0)
 			break;
 		currenttimer = inl(ALI_REG(codec,  ALI_STIMER));
 	}
 }
 
-static void snd_ali_detect_spdif_rate(ali_t *codec)
+static void snd_ali_detect_spdif_rate(struct snd_ali *codec)
 {
 	u16 wval  = 0;
 	u16 count = 0;
@@ -830,7 +827,7 @@
 	}
 }
 
-static unsigned int snd_ali_get_spdif_in_rate(ali_t *codec)
+static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec)
 {
 	u32	dwRate = 0;
 	u8	bval = 0;
@@ -852,7 +849,7 @@
 	return dwRate;
 }
 
-static void snd_ali_enable_spdif_in(ali_t *codec)
+static void snd_ali_enable_spdif_in(struct snd_ali *codec)
 {	
 	unsigned int dwVal;
 
@@ -867,7 +864,7 @@
 	snd_ali_enable_special_channel(codec, ALI_SPDIF_IN_CHANNEL);
 }
 
-static void snd_ali_disable_spdif_in(ali_t *codec)
+static void snd_ali_disable_spdif_in(struct snd_ali *codec)
 {
 	unsigned int dwVal;
 	
@@ -879,7 +876,7 @@
 }
 
 
-static void snd_ali_set_spdif_out_rate(ali_t *codec, unsigned int rate)
+static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate)
 {
 	unsigned char  bVal;
 	unsigned int  dwRate = 0;
@@ -900,7 +897,7 @@
 	outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2));
 }
 
-static void snd_ali_enable_spdif_out(ali_t *codec)
+static void snd_ali_enable_spdif_out(struct snd_ali *codec)
 {
 	unsigned short wVal;
 	unsigned char bVal;
@@ -936,7 +933,7 @@
    	}
 }
 
-static void snd_ali_enable_spdif_chnout(ali_t *codec)
+static void snd_ali_enable_spdif_chnout(struct snd_ali *codec)
 {
 	unsigned short wVal = 0;
 
@@ -954,7 +951,7 @@
 	snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL);
 }
 
-static void snd_ali_disable_spdif_chnout(ali_t *codec)
+static void snd_ali_disable_spdif_chnout(struct snd_ali *codec)
 {
 	unsigned short wVal = 0;
   	wVal  = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL));
@@ -964,7 +961,7 @@
 	snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL);
 }
 
-static void snd_ali_disable_spdif_out(ali_t *codec)
+static void snd_ali_disable_spdif_out(struct snd_ali *codec)
 {
 	unsigned char  bVal;
 
@@ -974,11 +971,11 @@
 	snd_ali_disable_spdif_chnout(codec);
 }
 
-static void snd_ali_update_ptr(ali_t *codec,int channel)
+static void snd_ali_update_ptr(struct snd_ali *codec,int channel)
 {
-	snd_ali_voice_t *pvoice = NULL;
-	snd_pcm_runtime_t *runtime;
-	snd_ali_channel_control_t *pchregs = NULL;
+	struct snd_ali_voice *pvoice = NULL;
+	struct snd_pcm_runtime *runtime;
+	struct snd_ali_channel_control *pchregs = NULL;
 	unsigned int old, mask;
 #ifdef ALI_DEBUG
 	unsigned int temp, cspf;
@@ -1029,11 +1026,11 @@
 	pchregs->data.aint = old & (~mask);
 }
 
-static void snd_ali_interrupt(ali_t * codec)
+static void snd_ali_interrupt(struct snd_ali * codec)
 {
 	int channel;
 	unsigned int audio_int;
-	snd_ali_channel_control_t *pchregs = NULL;
+	struct snd_ali_channel_control *pchregs = NULL;
 	pchregs = &(codec->chregs);
 
 	audio_int = inl(ALI_REG(codec, ALI_MISCINT));
@@ -1053,7 +1050,7 @@
 				   void *dev_id,
 				   struct pt_regs *regs)
 {
-	ali_t 	*codec = dev_id;
+	struct snd_ali 	*codec = dev_id;
 
 	if (codec == NULL)
 		return IRQ_NONE;
@@ -1062,38 +1059,37 @@
 }
 
 
-static snd_ali_voice_t *snd_ali_alloc_voice(ali_t * codec, int type, int rec, int channel)
+static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int type, int rec, int channel)
 {
-	snd_ali_voice_t *pvoice = NULL;
-	unsigned long flags;
+	struct snd_ali_voice *pvoice = NULL;
 	int idx;
 
 	snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec);
 
-	spin_lock_irqsave(&codec->voice_alloc, flags);
+	spin_lock_irq(&codec->voice_alloc);
 	if (type == SNDRV_ALI_VOICE_TYPE_PCM) {
 		idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
 			snd_ali_find_free_channel(codec,rec);
 		if(idx < 0) {
 			snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
-			spin_unlock_irqrestore(&codec->voice_alloc, flags);
+			spin_unlock_irq(&codec->voice_alloc);
 			return NULL;
 		}
 		pvoice = &(codec->synth.voices[idx]);
+		pvoice->codec = codec;
 		pvoice->use = 1;
 		pvoice->pcm = 1;
 		pvoice->mode = rec;
-		spin_unlock_irqrestore(&codec->voice_alloc, flags);
+		spin_unlock_irq(&codec->voice_alloc);
 		return pvoice;
 	}
-	spin_unlock_irqrestore(&codec->voice_alloc, flags);
+	spin_unlock_irq(&codec->voice_alloc);
 	return NULL;
 }
 
 
-static void snd_ali_free_voice(ali_t * codec, snd_ali_voice_t *pvoice)
+static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvoice)
 {
-	unsigned long flags;
 	void (*private_free)(void *);
 	void *private_data;
 
@@ -1101,7 +1097,7 @@
 	if (pvoice == NULL || !pvoice->use)
 		return;
 	snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
-	spin_lock_irqsave(&codec->voice_alloc, flags);
+	spin_lock_irq(&codec->voice_alloc);
 	private_free = pvoice->private_free;
 	private_data = pvoice->private_data;
 	pvoice->private_free = NULL;
@@ -1111,13 +1107,13 @@
 	}
 	pvoice->use = pvoice->pcm = pvoice->synth = 0;
 	pvoice->substream = NULL;
-	spin_unlock_irqrestore(&codec->voice_alloc, flags);
+	spin_unlock_irq(&codec->voice_alloc);
 	if (private_free)
 		private_free(private_data);
 }
 
 
-static void snd_ali_clear_voices(ali_t * codec,
+static void snd_ali_clear_voices(struct snd_ali * codec,
 			  unsigned int v_min,
 			  unsigned int v_max)
 {
@@ -1129,7 +1125,7 @@
 	}
 }
 
-static void snd_ali_write_voice_regs(ali_t * codec,
+static void snd_ali_write_voice_regs(struct snd_ali * codec,
 			 unsigned int Channel,
 			 unsigned int LBA,
 			 unsigned int CSO,
@@ -1196,10 +1192,10 @@
 	return delta;
 }
 
-static unsigned int snd_ali_control_mode(snd_pcm_substream_t *substream)
+static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream)
 {
 	unsigned int CTRL;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	/* set ctrl mode
 	   CTRL default: 8-bit (unsigned) mono, loop mode enabled
@@ -1218,21 +1214,21 @@
  *  PCM part
  */
 
-static int snd_ali_ioctl(snd_pcm_substream_t * substream,
+static int snd_ali_ioctl(struct snd_pcm_substream *substream,
 				  unsigned int cmd, void *arg)
 {
 	return snd_pcm_lib_ioctl(substream, cmd, arg);
 }
 
-static int snd_ali_trigger(snd_pcm_substream_t *substream,
+static int snd_ali_trigger(struct snd_pcm_substream *substream,
 			       int cmd)
 				    
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
+	struct snd_ali *codec = snd_pcm_substream_chip(substream);
 	struct list_head *pos;
-	snd_pcm_substream_t *s;
+	struct snd_pcm_substream *s;
 	unsigned int what, whati, capture_flag;
-	snd_ali_voice_t *pvoice = NULL, *evoice = NULL;
+	struct snd_ali_voice *pvoice = NULL, *evoice = NULL;
 	unsigned int val;
 	int do_start;
 
@@ -1250,8 +1246,8 @@
 	what = whati = capture_flag = 0;
 	snd_pcm_group_for_each(pos, substream) {
 		s = snd_pcm_group_substream_entry(pos);
-		if ((ali_t *) snd_pcm_substream_chip(s) == codec) {
-			pvoice = (snd_ali_voice_t *) s->runtime->private_data;
+		if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) {
+			pvoice = s->runtime->private_data;
 			evoice = pvoice->extra;
 			what |= 1 << (pvoice->number & 0x1f);
 			if (evoice == NULL) {
@@ -1294,13 +1290,13 @@
 	return 0;
 }
 
-static int snd_ali_playback_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
-	snd_ali_voice_t *evoice = pvoice->extra;
+	struct snd_ali *codec = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ali_voice *pvoice = runtime->private_data;
+	struct snd_ali_voice *evoice = pvoice->extra;
 	int err;
 	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 	if (err < 0) return err;
@@ -1325,12 +1321,12 @@
 	return 0;
 }
 
-static int snd_ali_playback_hw_free(snd_pcm_substream_t * substream)
+static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream)
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
-	snd_ali_voice_t *evoice = pvoice ? pvoice->extra : NULL;
+	struct snd_ali *codec = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ali_voice *pvoice = runtime->private_data;
+	struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL;
 
 	snd_pcm_lib_free_pages(substream);
 	if (evoice != NULL) {
@@ -1340,24 +1336,23 @@
 	return 0;
 }
 
-static int snd_ali_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_ali_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_ali_hw_free(snd_pcm_substream_t * substream)
+static int snd_ali_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_ali_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_ali_playback_prepare(struct snd_pcm_substream *substream)
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
-	snd_ali_voice_t *evoice = pvoice->extra;
-	unsigned long flags;
+	struct snd_ali *codec = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ali_voice *pvoice = runtime->private_data;
+	struct snd_ali_voice *evoice = pvoice->extra;
 
 	unsigned int LBA;
 	unsigned int Delta;
@@ -1370,7 +1365,7 @@
 	
 	snd_ali_printk("playback_prepare ...\n");
 
-	spin_lock_irqsave(&codec->reg_lock, flags);	
+	spin_lock_irq(&codec->reg_lock);	
 	
 	/* set Delta (rate) value */
 	Delta = snd_ali_convert_rate(runtime->rate, 0);
@@ -1435,17 +1430,16 @@
 				     CTRL,
 				     EC);
 	}
-	spin_unlock_irqrestore(&codec->reg_lock, flags);
+	spin_unlock_irq(&codec->reg_lock);
 	return 0;
 }
 
 
-static int snd_ali_prepare(snd_pcm_substream_t * substream)
+static int snd_ali_prepare(struct snd_pcm_substream *substream)
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
-	unsigned long flags;
+	struct snd_ali *codec = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ali_voice *pvoice = runtime->private_data;
 	unsigned int LBA;
 	unsigned int Delta;
 	unsigned int ESO;
@@ -1456,7 +1450,7 @@
 	unsigned int EC;
 	u8	 bValue;
 
-	spin_lock_irqsave(&codec->reg_lock, flags);
+	spin_lock_irq(&codec->reg_lock);
 
 	snd_ali_printk("ali_prepare...\n");
 
@@ -1471,15 +1465,16 @@
 
 		unsigned int rate;
 		
-		if (codec->revision != ALI_5451_V02) {
-			spin_unlock_irqrestore(&codec->reg_lock, flags);			
+		spin_unlock_irq(&codec->reg_lock);
+		if (codec->revision != ALI_5451_V02)
 			return -1;
-		}
+
 		rate = snd_ali_get_spdif_in_rate(codec);
 		if (rate == 0) {
 			snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n");
 			rate = 48000;
 		}
+		spin_lock_irq(&codec->reg_lock);
 		bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
 		if (bValue & 0x10) {
 			outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL));
@@ -1521,17 +1516,17 @@
 				     EC);
 
 
-	spin_unlock_irqrestore(&codec->reg_lock, flags);
+	spin_unlock_irq(&codec->reg_lock);
 
 	return 0;
 }
 
 
-static snd_pcm_uframes_t snd_ali_playback_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_ali_playback_pointer(struct snd_pcm_substream *substream)
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
+	struct snd_ali *codec = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ali_voice *pvoice = runtime->private_data;
 	unsigned int cso;
 
 	spin_lock(&codec->reg_lock);
@@ -1548,27 +1543,26 @@
 }
 
 
-static snd_pcm_uframes_t snd_ali_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream)
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
+	struct snd_ali *codec = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ali_voice *pvoice = runtime->private_data;
 	unsigned int cso;
-	unsigned long flags;
 
-	spin_lock_irqsave(&codec->reg_lock, flags);
+	spin_lock(&codec->reg_lock);
 	if (!pvoice->running) {
-		spin_unlock_irqrestore(&codec->reg_lock, flags);
+		spin_unlock_irq(&codec->reg_lock);
 		return 0;
 	}
 	outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR));
 	cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
-	spin_unlock_irqrestore(&codec->reg_lock, flags);
+	spin_unlock(&codec->reg_lock);
 
 	return cso;
 }
 
-static snd_pcm_hardware_t snd_ali_playback =
+static struct snd_pcm_hardware snd_ali_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1594,7 +1588,7 @@
  *  Capture support device description
  */
 
-static snd_pcm_hardware_t snd_ali_capture =
+static struct snd_pcm_hardware snd_ali_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1616,36 +1610,27 @@
 	.fifo_size =		0,
 };
 
-static void snd_ali_pcm_free_substream(snd_pcm_runtime_t *runtime)
+static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime)
 {
-	unsigned long flags;
-	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) runtime->private_data;
-	ali_t *codec;
+	struct snd_ali_voice *pvoice = runtime->private_data;
+	struct snd_ali *codec;
 
 	if (pvoice) {
 		codec = pvoice->codec;
-		spin_lock_irqsave(&codec->reg_lock, flags);
 		snd_ali_free_voice(pvoice->codec, pvoice);
-		spin_unlock_irqrestore(&codec->reg_lock, flags);
 	}
 }
 
-static int snd_ali_open(snd_pcm_substream_t * substream, int rec, int channel,
-		snd_pcm_hardware_t *phw)
+static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channel,
+		struct snd_pcm_hardware *phw)
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_ali_voice_t *pvoice;
-	unsigned long flags = 0;
+	struct snd_ali *codec = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ali_voice *pvoice;
 
-	spin_lock_irqsave(&codec->reg_lock, flags);
 	pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel);
-	if (pvoice == NULL) {
-		spin_unlock_irqrestore(&codec->reg_lock, flags);
+	if (pvoice == NULL)
 		return -EAGAIN;
-	}
-	pvoice->codec = codec;
-	spin_unlock_irqrestore(&codec->reg_lock, flags);
 
 	pvoice->substream = substream;
 	runtime->private_data = pvoice;
@@ -1657,32 +1642,32 @@
 	return 0;
 }
 
-static int snd_ali_playback_open(snd_pcm_substream_t * substream)
+static int snd_ali_playback_open(struct snd_pcm_substream *substream)
 {
 	return snd_ali_open(substream, 0, -1, &snd_ali_playback);
 }
 
-static int snd_ali_capture_open(snd_pcm_substream_t * substream)
+static int snd_ali_capture_open(struct snd_pcm_substream *substream)
 {
 	return snd_ali_open(substream, 1, -1, &snd_ali_capture);
 }
 
-static int snd_ali_playback_close(snd_pcm_substream_t * substream)
+static int snd_ali_playback_close(struct snd_pcm_substream *substream)
 {
 	return 0;
 }
 
-static int snd_ali_close(snd_pcm_substream_t * substream)
+static int snd_ali_close(struct snd_pcm_substream *substream)
 {
-	ali_t *codec = snd_pcm_substream_chip(substream);
-	snd_ali_voice_t *pvoice = (snd_ali_voice_t *) substream->runtime->private_data;
+	struct snd_ali *codec = snd_pcm_substream_chip(substream);
+	struct snd_ali_voice *pvoice = substream->runtime->private_data;
 
 	snd_ali_disable_special_channel(codec,pvoice->number);
 
 	return 0;
 }
 
-static snd_pcm_ops_t snd_ali_playback_ops = {
+static struct snd_pcm_ops snd_ali_playback_ops = {
 	.open =		snd_ali_playback_open,
 	.close =	snd_ali_playback_close,
 	.ioctl =	snd_ali_ioctl,
@@ -1693,7 +1678,7 @@
 	.pointer =	snd_ali_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_ali_capture_ops = {
+static struct snd_pcm_ops snd_ali_capture_ops = {
 	.open =		snd_ali_capture_open,
 	.close =	snd_ali_close,
 	.ioctl =	snd_ali_ioctl,
@@ -1708,17 +1693,17 @@
  * Modem PCM
  */
 
-static int snd_ali_modem_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
-	ali_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ali *chip = snd_pcm_substream_chip(substream);
 	unsigned int modem_num = chip->num_of_codecs - 1;
 	snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params));
 	snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0);
 	return snd_ali_hw_params(substream, hw_params);
 }
 
-static snd_pcm_hardware_t snd_ali_modem =
+static struct snd_pcm_hardware snd_ali_modem =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1739,10 +1724,10 @@
 	.fifo_size =		0,
 };
 
-static int snd_ali_modem_open(snd_pcm_substream_t * substream, int rec, int channel)
+static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, int channel)
 {
 	static unsigned int rates [] = {8000,9600,12000,16000};
-	static snd_pcm_hw_constraint_list_t hw_constraint_rates = {
+	static struct snd_pcm_hw_constraint_list hw_constraint_rates = {
 		.count = ARRAY_SIZE(rates),
 		.list = rates,
 		.mask = 0,
@@ -1754,17 +1739,17 @@
 			SNDRV_PCM_HW_PARAM_RATE, &hw_constraint_rates);
 }
 
-static int snd_ali_modem_playback_open(snd_pcm_substream_t * substream)
+static int snd_ali_modem_playback_open(struct snd_pcm_substream *substream)
 {
 	return snd_ali_modem_open(substream, 0, ALI_MODEM_OUT_CHANNEL);
 }
 
-static int snd_ali_modem_capture_open(snd_pcm_substream_t * substream)
+static int snd_ali_modem_capture_open(struct snd_pcm_substream *substream)
 {
 	return snd_ali_modem_open(substream, 1, ALI_MODEM_IN_CHANNEL);
 }
 
-static snd_pcm_ops_t snd_ali_modem_playback_ops = {
+static struct snd_pcm_ops snd_ali_modem_playback_ops = {
 	.open =		snd_ali_modem_playback_open,
 	.close =	snd_ali_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1775,7 +1760,7 @@
 	.pointer =	snd_ali_pointer,
 };
 
-static snd_pcm_ops_t snd_ali_modem_capture_ops = {
+static struct snd_pcm_ops snd_ali_modem_capture_ops = {
 	.open =		snd_ali_modem_capture_open,
 	.close =	snd_ali_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1791,22 +1776,22 @@
 	char *name;
 	unsigned int playback_num;
 	unsigned int capture_num;
-	snd_pcm_ops_t *playback_ops;
-	snd_pcm_ops_t *capture_ops;
+	struct snd_pcm_ops *playback_ops;
+	struct snd_pcm_ops *capture_ops;
 	unsigned short class;
 };
 
 
-static void snd_ali_pcm_free(snd_pcm_t *pcm)
+static void snd_ali_pcm_free(struct snd_pcm *pcm)
 {
-	ali_t *codec = pcm->private_data;
+	struct snd_ali *codec = pcm->private_data;
 	codec->pcm[pcm->device] = NULL;
 }
 
 
-static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_description *desc)
+static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_pcm_description *desc)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	err = snd_pcm_new(codec->card, desc->name, device,
@@ -1838,7 +1823,7 @@
 	{ "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM }
 };
 
-static int __devinit snd_ali_build_pcms(ali_t *codec)
+static int __devinit snd_ali_build_pcms(struct snd_ali *codec)
 {
 	int i, err;
 	for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++)
@@ -1853,7 +1838,7 @@
 .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \
 .put = snd_ali5451_spdif_put, .private_value = value}
 
-static int snd_ali5451_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
         uinfo->count = 1;
@@ -1862,15 +1847,14 @@
         return 0;
 }
 
-static int snd_ali5451_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	unsigned long flags;
-	ali_t *codec = kcontrol->private_data;
+	struct snd_ali *codec = kcontrol->private_data;
 	unsigned int enable;
 
 	enable = ucontrol->value.integer.value[0] ? 1 : 0;
 
-	spin_lock_irqsave(&codec->reg_lock, flags);
+	spin_lock_irq(&codec->reg_lock);
 	switch(kcontrol->private_value) {
 	case 0:
 		enable = (codec->spdif_mask & 0x02) ? 1 : 0;
@@ -1885,19 +1869,18 @@
 		break;
 	}
 	ucontrol->value.integer.value[0] = enable;
-	spin_unlock_irqrestore(&codec->reg_lock, flags);
+	spin_unlock_irq(&codec->reg_lock);
 	return 0;
 }
 
-static int snd_ali5451_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	unsigned long flags;
-	ali_t *codec = kcontrol->private_data;
+	struct snd_ali *codec = kcontrol->private_data;
 	unsigned int change = 0, enable = 0;
 
 	enable = ucontrol->value.integer.value[0] ? 1 : 0;
 
-	spin_lock_irqsave(&codec->reg_lock, flags);
+	spin_lock_irq(&codec->reg_lock);
 	switch (kcontrol->private_value) {
 	case 0:
 		change = (codec->spdif_mask & 0x02) ? 1 : 0;
@@ -1942,12 +1925,12 @@
 	default:
 		break;
 	}
-	spin_unlock_irqrestore(&codec->reg_lock, flags);
+	spin_unlock_irq(&codec->reg_lock);
 	
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ali5451_mixer_spdif[] __devinitdata = {
+static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = {
 	/* spdif aplayback switch */
 	/* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */
 	ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 0, 0),
@@ -1957,24 +1940,24 @@
 	ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2)
 };
 
-static void snd_ali_mixer_free_ac97_bus(ac97_bus_t *bus)
+static void snd_ali_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
 {
-	ali_t *codec = bus->private_data;
+	struct snd_ali *codec = bus->private_data;
 	codec->ac97_bus = NULL;
 }
 
-static void snd_ali_mixer_free_ac97(ac97_t *ac97)
+static void snd_ali_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	ali_t *codec = ac97->private_data;
+	struct snd_ali *codec = ac97->private_data;
 	codec->ac97[ac97->num] = NULL;
 }
 
-static int __devinit snd_ali_mixer(ali_t * codec)
+static int __devinit snd_ali_mixer(struct snd_ali * codec)
 {
-	ac97_template_t ac97;
+	struct snd_ac97_template ac97;
 	unsigned int idx;
 	int i, err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_ali_codec_write,
 		.read = snd_ali_codec_read,
 	};
@@ -2008,21 +1991,21 @@
 }
 
 #ifdef CONFIG_PM
-static int ali_suspend(snd_card_t *card, pm_message_t state)
+static int ali_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	ali_t *chip = card->pm_private_data;
-	ali_image_t *im;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_ali *chip = card->private_data;
+	struct snd_ali_image *im;
 	int i, j;
 
 	im = chip->image;
 	if (! im)
 		return 0;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	for(i = 0 ; i < chip->num_of_codecs ; i++) {
-		if (chip->pcm[i])
-			snd_pcm_suspend_all(chip->pcm[i]);
-		if(chip->ac97[i])
-			snd_ac97_suspend(chip->ac97[i]);
+		snd_pcm_suspend_all(chip->pcm[i]);
+		snd_ac97_suspend(chip->ac97[i]);
 	}
 
 	spin_lock_irq(&chip->reg_lock);
@@ -2050,21 +2033,24 @@
 	outl(0xffffffff, ALI_REG(chip, ALI_STOP));
 
 	spin_unlock_irq(&chip->reg_lock);
-	pci_disable_device(chip->pci);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int ali_resume(snd_card_t *card)
+static int ali_resume(struct pci_dev *pci)
 {
-	ali_t *chip = card->pm_private_data;
-	ali_image_t *im;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_ali *chip = card->private_data;
+	struct snd_ali_image *im;
 	int i, j;
 
 	im = chip->image;
 	if (! im)
 		return 0;
 
-	pci_enable_device(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
 
 	spin_lock_irq(&chip->reg_lock);
 	
@@ -2088,14 +2074,14 @@
 	spin_unlock_irq(&chip->reg_lock);
 
 	for(i = 0 ; i < chip->num_of_codecs ; i++)
-		if(chip->ac97[i])
-			snd_ac97_resume(chip->ac97[i]);
+		snd_ac97_resume(chip->ac97[i]);
 	
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
-static int snd_ali_free(ali_t * codec)
+static int snd_ali_free(struct snd_ali * codec)
 {
 	if (codec->hw_initialized)
 		snd_ali_disable_address_interrupt(codec);
@@ -2115,7 +2101,7 @@
 	return 0;
 }
 
-static int snd_ali_chip_init(ali_t *codec)
+static int snd_ali_chip_init(struct snd_ali *codec)
 {
 	unsigned int legacy;
 	unsigned char temp;
@@ -2174,22 +2160,22 @@
 }
 
 /* proc for register dump */
-static void snd_ali_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buf)
+static void snd_ali_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buf)
 {
-	ali_t *codec = entry->private_data;
+	struct snd_ali *codec = entry->private_data;
 	int i;
 	for(i = 0 ; i < 256 ; i+= 4)
 		snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i)));
 }
 
-static void __devinit snd_ali_proc_init(ali_t *codec)
+static void __devinit snd_ali_proc_init(struct snd_ali *codec)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	if(!snd_card_proc_new(codec->card, "ali5451", &entry))
 		snd_info_set_text_ops(entry, codec, 1024, snd_ali_proc_read);
 }
 
-static int __devinit snd_ali_resources(ali_t *codec)
+static int __devinit snd_ali_resources(struct snd_ali *codec)
 {
 	int err;
 
@@ -2206,27 +2192,24 @@
 	snd_ali_printk("resouces allocated.\n");
 	return 0;
 }
-static int snd_ali_dev_free(snd_device_t *device) 
+static int snd_ali_dev_free(struct snd_device *device) 
 {
-	ali_t *codec=device->device_data;
+	struct snd_ali *codec=device->device_data;
 	snd_ali_free(codec);
 	return 0;
 }
 
-static int __devinit snd_ali_create(snd_card_t * card,
+static int __devinit snd_ali_create(struct snd_card *card,
 				    struct pci_dev *pci,
 				    int pcm_streams,
 				    int spdif_support,
-				    ali_t ** r_ali)
+				    struct snd_ali ** r_ali)
 {
-	ali_t *codec;
+	struct snd_ali *codec;
 	int i, err;
-	unsigned short cmdw = 0;
-	struct pci_dev *pci_dev = NULL;
-        static snd_device_ops_t ops = {
-		(snd_dev_free_t *)snd_ali_dev_free,
-		NULL,
-		NULL
+	unsigned short cmdw;
+	static struct snd_device_ops ops = {
+		.dev_free = snd_ali_dev_free,
         };
 
 	*r_ali = NULL;
@@ -2300,16 +2283,14 @@
 	codec->chregs.data.ainten = 0x00;
 
 	/* M1533: southbridge */
-	pci_dev = pci_get_device(0x10b9, 0x1533, NULL);
-	codec->pci_m1533 = pci_dev;
+	codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL);
 	if (! codec->pci_m1533) {
 		snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n");
 		snd_ali_free(codec);
 		return -ENODEV;
 	}
 	/* M7101: power management */
-	pci_dev = pci_get_device(0x10b9, 0x7101, NULL);
-	codec->pci_m7101 = pci_dev;
+	codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL);
 	if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) {
 		snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n");
 		snd_ali_free(codec);
@@ -2336,8 +2317,6 @@
 	codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
 	if (! codec->image)
 		snd_printk(KERN_WARNING "can't allocate apm buffer\n");
-	else
-		snd_card_set_pm_callback(card, ali_suspend, ali_resume, codec);
 #endif
 
 	snd_ali_enable_address_interrupt(codec);
@@ -2351,8 +2330,8 @@
 static int __devinit snd_ali_probe(struct pci_dev *pci,
 				   const struct pci_device_id *pci_id)
 {
-	snd_card_t *card;
-	ali_t *codec;
+	struct snd_card *card;
+	struct snd_ali *codec;
 	int err;
 
 	snd_ali_printk("probe ...\n");
@@ -2365,6 +2344,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = codec;
 
 	snd_ali_printk("mixer building ...\n");
 	if ((err = snd_ali_mixer(codec)) < 0) {
@@ -2406,7 +2386,10 @@
 	.id_table = snd_ali_ids,
 	.probe = snd_ali_probe,
 	.remove = __devexit_p(snd_ali_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = ali_suspend,
+	.resume = ali_resume,
+#endif
 };                                
 
 static int __init alsa_card_ali_init(void)
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 1904df6..7b2ff5f 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -6,6 +6,21 @@
  *
  *  Framework borrowed from Massimo Piccioni's card-als100.c.
  *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
  * NOTES
  *
  *  Since Avance does not provide any meaningful documentation, and I
@@ -43,19 +58,9 @@
  * Set KSound:
  * - value -> some port 0x0c0d
  *
- *  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
+ * ToDo:
+ * - Proper shared IRQ handling?
+ * - power management? (card can do voice wakeup according to datasheet!!)
  */
 
 #include <sound/driver.h>
@@ -100,13 +105,15 @@
 MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0 = disabled)");
 #endif
 
-typedef struct {
-	struct pci_dev *pci;
+struct snd_card_als4000 {
+	/* most frequent access first */
 	unsigned long gcr;
+	struct pci_dev *pci;
+	struct snd_sb *chip;
 #ifdef SUPPORT_JOYSTICK
 	struct gameport *gameport;
 #endif
-} snd_card_als4000_t;
+};
 
 static struct pci_device_id snd_als4000_ids[] = {
 	{ 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* ALS4000 */
@@ -121,7 +128,7 @@
 	outl(val, port+0x08);
 }
 
-static inline void snd_als4000_gcr_write(sb_t *sb, u32 reg, u32 val)
+static inline void snd_als4000_gcr_write(struct snd_sb *sb, u32 reg, u32 val)
 {
 	snd_als4000_gcr_write_addr(sb->alt_port, reg, val);
 }	
@@ -132,12 +139,12 @@
 	return inl(port+0x08);
 }
 
-static inline u32 snd_als4000_gcr_read(sb_t *sb, u32 reg)
+static inline u32 snd_als4000_gcr_read(struct snd_sb *sb, u32 reg)
 {
 	return snd_als4000_gcr_read_addr(sb->alt_port, reg);
 }
 
-static void snd_als4000_set_rate(sb_t *chip, unsigned int rate)
+static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate)
 {
 	if (!(chip->mode & SB_RATE_LOCK)) {
 		snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE_OUT);
@@ -146,13 +153,15 @@
 	}
 }
 
-static void snd_als4000_set_capture_dma(sb_t *chip, dma_addr_t addr, unsigned size)
+static inline void snd_als4000_set_capture_dma(struct snd_sb *chip,
+					       dma_addr_t addr, unsigned size)
 {
 	snd_als4000_gcr_write(chip, 0xa2, addr);
 	snd_als4000_gcr_write(chip, 0xa3, (size-1));
 }
 
-static void snd_als4000_set_playback_dma(sb_t *chip, dma_addr_t addr, unsigned size)
+static inline void snd_als4000_set_playback_dma(struct snd_sb *chip,
+						dma_addr_t addr, unsigned size)
 {
 	snd_als4000_gcr_write(chip, 0x91, addr);
 	snd_als4000_gcr_write(chip, 0x92, (size-1)|0x180000);
@@ -162,7 +171,7 @@
 #define ALS4000_FORMAT_16BIT	(1<<1)
 #define ALS4000_FORMAT_STEREO	(1<<2)
 
-static int snd_als4000_get_format(snd_pcm_runtime_t *runtime)
+static int snd_als4000_get_format(struct snd_pcm_runtime *runtime)
 {
 	int result;
 
@@ -177,7 +186,7 @@
 }
 
 /* structure for setting up playback */
-static struct {
+static const struct {
 	unsigned char dsp_cmd, dma_on, dma_off, format;
 } playback_cmd_vals[]={
 /* ALS4000_FORMAT_U8_MONO */
@@ -201,7 +210,7 @@
 
 /* structure for setting up capture */
 enum { CMD_WIDTH8=0x04, CMD_SIGNED=0x10, CMD_MONO=0x80, CMD_STEREO=0xA0 };
-static unsigned char capture_cmd_vals[]=
+static const unsigned char capture_cmd_vals[]=
 {
 CMD_WIDTH8|CMD_MONO,			/* ALS4000_FORMAT_U8_MONO */
 CMD_WIDTH8|CMD_SIGNED|CMD_MONO,		/* ALS4000_FORMAT_S8_MONO */	
@@ -214,23 +223,22 @@
 };	
 #define capture_cmd(chip) (capture_cmd_vals[(chip)->capture_format])
 
-static int snd_als4000_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_als4000_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_als4000_hw_free(snd_pcm_substream_t * substream)
+static int snd_als4000_hw_free(struct snd_pcm_substream *substream)
 {
 	snd_pcm_lib_free_pages(substream);
 	return 0;
 }
 
-static int snd_als4000_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream)
 {
-	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long size;
 	unsigned count;
 
@@ -243,22 +251,21 @@
 		count >>=1;
 	count--;
 
-	spin_lock_irqsave(&chip->reg_lock, flags);
+	spin_lock_irq(&chip->reg_lock);
 	snd_als4000_set_rate(chip, runtime->rate);
 	snd_als4000_set_capture_dma(chip, runtime->dma_addr, size);
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
-	spin_lock_irqsave(&chip->mixer_lock, flags );
+	spin_unlock_irq(&chip->reg_lock);
+	spin_lock_irq(&chip->mixer_lock);
 	snd_sbmixer_write(chip, 0xdc, count);
 	snd_sbmixer_write(chip, 0xdd, count>>8);
-	spin_unlock_irqrestore(&chip->mixer_lock, flags );
+	spin_unlock_irq(&chip->mixer_lock);
 	return 0;
 }
 
-static int snd_als4000_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream)
 {
-	unsigned long flags;
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long size;
 	unsigned count;
 
@@ -277,7 +284,7 @@
 	 * reordering, ...). Something seems to get enabled on playback
 	 * that I haven't found out how to disable again, which then causes
 	 * the switching pops to reach the speakers the next time here. */
-	spin_lock_irqsave(&chip->reg_lock, flags);
+	spin_lock_irq(&chip->reg_lock);
 	snd_als4000_set_rate(chip, runtime->rate);
 	snd_als4000_set_playback_dma(chip, runtime->dma_addr, size);
 	
@@ -288,52 +295,64 @@
 	snd_sbdsp_command(chip, count);
 	snd_sbdsp_command(chip, count>>8);
 	snd_sbdsp_command(chip, playback_cmd(chip).dma_off);	
-	spin_unlock_irqrestore(&chip->reg_lock, flags);
+	spin_unlock_irq(&chip->reg_lock);
 	
 	return 0;
 }
 
-static int snd_als4000_capture_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	int result = 0;
 	
 	spin_lock(&chip->mixer_lock);
-	if (cmd == SNDRV_PCM_TRIGGER_START) {
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		chip->mode |= SB_RATE_LOCK_CAPTURE;
 		snd_sbmixer_write(chip, 0xde, capture_cmd(chip));
-	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		chip->mode &= ~SB_RATE_LOCK_CAPTURE;
 		snd_sbmixer_write(chip, 0xde, 0);
-	} else {
+		break;
+	default:
 		result = -EINVAL;
+		break;
 	}
 	spin_unlock(&chip->mixer_lock);
 	return result;
 }
 
-static int snd_als4000_playback_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_als4000_playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	int result = 0;
 
 	spin_lock(&chip->reg_lock);
-	if (cmd == SNDRV_PCM_TRIGGER_START) {
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		chip->mode |= SB_RATE_LOCK_PLAYBACK;
 		snd_sbdsp_command(chip, playback_cmd(chip).dma_on);
-	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		snd_sbdsp_command(chip, playback_cmd(chip).dma_off);
 		chip->mode &= ~SB_RATE_LOCK_PLAYBACK;
-	} else {
+		break;
+	default:
 		result = -EINVAL;
+		break;
 	}
 	spin_unlock(&chip->reg_lock);
 	return result;
 }
 
-static snd_pcm_uframes_t snd_als4000_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_als4000_capture_pointer(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	unsigned int result;
 
 	spin_lock(&chip->reg_lock);	
@@ -342,9 +361,9 @@
 	return bytes_to_frames( substream->runtime, result );
 }
 
-static snd_pcm_uframes_t snd_als4000_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 	unsigned result;
 
 	spin_lock(&chip->reg_lock);	
@@ -353,9 +372,21 @@
 	return bytes_to_frames( substream->runtime, result );
 }
 
+/* FIXME: this IRQ routine doesn't really support IRQ sharing (we always
+ * return IRQ_HANDLED no matter whether we actually had an IRQ flag or not).
+ * ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK
+ * the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ
+ * register (alt_port + 0x0e). Probably something could be optimized here to
+ * query/write one register only...
+ * And even if both registers need to be queried, then there's still the
+ * question of whether it's actually correct to ACK PCI IRQ before reading
+ * SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear*
+ * SB IRQ status.
+ * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS??
+ * */
 static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	sb_t *chip = dev_id;
+	struct snd_sb *chip = dev_id;
 	unsigned gcr_status;
 	unsigned sb_status;
 
@@ -388,7 +419,7 @@
 
 /*****************************************************************/
 
-static snd_pcm_hardware_t snd_als4000_playback =
+static struct snd_pcm_hardware snd_als4000_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -407,7 +438,7 @@
 	.fifo_size =		0
 };
 
-static snd_pcm_hardware_t snd_als4000_capture =
+static struct snd_pcm_hardware snd_als4000_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -428,38 +459,38 @@
 
 /*****************************************************************/
 
-static int snd_als4000_playback_open(snd_pcm_substream_t * substream)
+static int snd_als4000_playback_open(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	chip->playback_substream = substream;
 	runtime->hw = snd_als4000_playback;
 	return 0;
 }
 
-static int snd_als4000_playback_close(snd_pcm_substream_t * substream)
+static int snd_als4000_playback_close(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 
 	chip->playback_substream = NULL;
 	snd_pcm_lib_free_pages(substream);
 	return 0;
 }
 
-static int snd_als4000_capture_open(snd_pcm_substream_t * substream)
+static int snd_als4000_capture_open(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	chip->capture_substream = substream;
 	runtime->hw = snd_als4000_capture;
 	return 0;
 }
 
-static int snd_als4000_capture_close(snd_pcm_substream_t * substream)
+static int snd_als4000_capture_close(struct snd_pcm_substream *substream)
 {
-	sb_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_sb *chip = snd_pcm_substream_chip(substream);
 
 	chip->capture_substream = NULL;
 	snd_pcm_lib_free_pages(substream);
@@ -468,7 +499,7 @@
 
 /******************************************************************/
 
-static snd_pcm_ops_t snd_als4000_playback_ops = {
+static struct snd_pcm_ops snd_als4000_playback_ops = {
 	.open =		snd_als4000_playback_open,
 	.close =	snd_als4000_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -479,7 +510,7 @@
 	.pointer =	snd_als4000_playback_pointer
 };
 
-static snd_pcm_ops_t snd_als4000_capture_ops = {
+static struct snd_pcm_ops snd_als4000_capture_ops = {
 	.open =		snd_als4000_capture_open,
 	.close =	snd_als4000_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -490,21 +521,13 @@
 	.pointer =	snd_als4000_capture_pointer
 };
 
-static void snd_als4000_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device)
 {
-	sb_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_als4000_pcm(sb_t *chip, int device)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm)) < 0)
 		return err;
-	pcm->private_free = snd_als4000_pcm_free;
 	pcm->private_data = chip;
 	pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_als4000_playback_ops);
@@ -541,7 +564,7 @@
 	snd_als4000_gcr_write_addr(gcr, 0xa9, confB);
 }
 
-static void __devinit snd_als4000_configure(sb_t *chip)
+static void snd_als4000_configure(struct snd_sb *chip)
 {
 	unsigned tmp;
 	int i;
@@ -566,7 +589,7 @@
 }
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_als4000_create_gameport(snd_card_als4000_t *acard, int dev)
+static int __devinit snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev)
 {
 	struct gameport *gp;
 	struct resource *r;
@@ -612,7 +635,7 @@
 	return 0;
 }
 
-static void snd_als4000_free_gameport(snd_card_als4000_t *acard)
+static void snd_als4000_free_gameport(struct snd_card_als4000 *acard)
 {
 	if (acard->gameport) {
 		struct resource *r = gameport_get_port_data(acard->gameport);
@@ -625,13 +648,13 @@
 	}
 }
 #else
-static inline int snd_als4000_create_gameport(snd_card_als4000_t *acard, int dev) { return -ENOSYS; }
-static inline void snd_als4000_free_gameport(snd_card_als4000_t *acard) { }
+static inline int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev) { return -ENOSYS; }
+static inline void snd_als4000_free_gameport(struct snd_card_als4000 *acard) { }
 #endif
 
-static void snd_card_als4000_free( snd_card_t *card )
+static void snd_card_als4000_free( struct snd_card *card )
 {
-	snd_card_als4000_t * acard = (snd_card_als4000_t *)card->private_data;
+	struct snd_card_als4000 * acard = (struct snd_card_als4000 *)card->private_data;
 
 	/* make sure that interrupts are disabled */
 	snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0);
@@ -645,11 +668,11 @@
 					  const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	snd_card_als4000_t *acard;
+	struct snd_card *card;
+	struct snd_card_als4000 *acard;
 	unsigned long gcr;
-	sb_t *chip;
-	opl3_t *opl3;
+	struct snd_sb *chip;
+	struct snd_opl3 *opl3;
 	unsigned short word;
 	int err;
 
@@ -683,14 +706,14 @@
 	pci_set_master(pci);
 	
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 
-			    sizeof( snd_card_als4000_t ) );
+			    sizeof( struct snd_card_als4000 ) );
 	if (card == NULL) {
 		pci_release_regions(pci);
 		pci_disable_device(pci);
 		return -ENOMEM;
 	}
 
-	acard = (snd_card_als4000_t *)card->private_data;
+	acard = (struct snd_card_als4000 *)card->private_data;
 	acard->pci = pci;
 	acard->gcr = gcr;
 	card->private_free = snd_card_als4000_free;
@@ -706,9 +729,9 @@
 				    -1,
 				    SB_HW_ALS4000,
 				    &chip)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}
+	acard->chip = chip;
 
 	chip->pci = pci;
 	chip->alt_port = gcr;
@@ -724,40 +747,42 @@
 	if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000,
 				        gcr+0x30, 1, pci->irq, 0,
 				        &chip->rmidi)) < 0) {
-		snd_card_free(card);
-		printk(KERN_ERR "als4000: no MPU-401device at 0x%lx ?\n", gcr+0x30);
-		return err;
+		printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30);
+		goto out_err;
 	}
 
 	if ((err = snd_als4000_pcm(chip, 0)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}
 	if ((err = snd_sbmixer_new(chip)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}	    
 
 	if (snd_opl3_create(card, gcr+0x10, gcr+0x12,
 			    OPL3_HW_AUTO, 1, &opl3) < 0) {
-		printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx ?\n",
+		printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx?\n",
 			   gcr+0x10, gcr+0x12 );
 	} else {
 		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
+			goto out_err;
 		}
 	}
 
 	snd_als4000_create_gameport(acard, dev);
 
 	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
+		goto out_err;
 	}
 	pci_set_drvdata(pci, card);
 	dev++;
-	return 0;
+	err = 0;
+	goto out;
+
+out_err:
+	snd_card_free(card);
+	
+out:
+	return err;
 }
 
 static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
@@ -766,11 +791,59 @@
 	pci_set_drvdata(pci, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_card_als4000 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	
+	snd_pcm_suspend_all(chip->pcm);
+	snd_sbmixer_suspend(chip);
+
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
+	return 0;
+}
+
+static int snd_als4000_resume(struct pci_dev *pci)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_card_als4000 *acard = card->private_data;
+	struct snd_sb *chip = acard->chip;
+
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
+	pci_set_master(pci);
+
+	snd_als4000_configure(chip);
+	snd_sbdsp_reset(chip);
+	snd_sbmixer_resume(chip);
+
+#ifdef SUPPORT_JOYSTICK
+	if (acard->gameport)
+		snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1);
+#endif
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
+
 static struct pci_driver driver = {
 	.name = "ALS4000",
 	.id_table = snd_als4000_ids,
 	.probe = snd_card_als4000_probe,
 	.remove = __devexit_p(snd_card_als4000_remove),
+#ifdef CONFIG_PM
+	.suspend = snd_als4000_suspend,
+	.resume = snd_als4000_resume,
+#endif
 };
 
 static int __init alsa_card_als4000_init(void)
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 8bae10d..b7217ad 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -197,24 +197,18 @@
 #define ATI_MAX_DESCRIPTORS	256	/* max number of descriptor packets */
 
 
-/*
- */
-
-typedef struct snd_atiixp atiixp_t;
-typedef struct snd_atiixp_dma atiixp_dma_t;
-typedef struct snd_atiixp_dma_ops atiixp_dma_ops_t;
-
+struct atiixp;
 
 /*
  * DMA packate descriptor
  */
 
-typedef struct atiixp_dma_desc {
+struct atiixp_dma_desc {
 	u32 addr;	/* DMA buffer address */
 	u16 status;	/* status bits */
 	u16 size;	/* size of the packet in dwords */
 	u32 next;	/* address of the next packet descriptor */
-} atiixp_dma_desc_t;
+};
 
 /*
  * stream enum
@@ -229,22 +223,25 @@
 /*
  * constants and callbacks for each DMA type
  */
-struct snd_atiixp_dma_ops {
+struct atiixp_dma_ops {
 	int type;			/* ATI_DMA_XXX */
 	unsigned int llp_offset;	/* LINKPTR offset */
 	unsigned int dt_cur;		/* DT_CUR offset */
-	void (*enable_dma)(atiixp_t *chip, int on);	/* called from open callback */
-	void (*enable_transfer)(atiixp_t *chip, int on); /* called from trigger (START/STOP) */
-	void (*flush_dma)(atiixp_t *chip);		/* called from trigger (STOP only) */
+	/* called from open callback */
+	void (*enable_dma)(struct atiixp *chip, int on);
+	/* called from trigger (START/STOP) */
+	void (*enable_transfer)(struct atiixp *chip, int on);
+ 	/* called from trigger (STOP only) */
+	void (*flush_dma)(struct atiixp *chip);
 };
 
 /*
  * DMA stream
  */
-struct snd_atiixp_dma {
-	const atiixp_dma_ops_t *ops;
+struct atiixp_dma {
+	const struct atiixp_dma_ops *ops;
 	struct snd_dma_buffer desc_buf;
-	snd_pcm_substream_t *substream;	/* assigned PCM substream */
+	struct snd_pcm_substream *substream;	/* assigned PCM substream */
 	unsigned int buf_addr, buf_bytes;	/* DMA buffer address, bytes */
 	unsigned int period_bytes, periods;
 	int opened;
@@ -258,22 +255,22 @@
 /*
  * ATI IXP chip
  */
-struct snd_atiixp {
-	snd_card_t *card;
+struct atiixp {
+	struct snd_card *card;
 	struct pci_dev *pci;
 
 	unsigned long addr;
 	void __iomem *remap_addr;
 	int irq;
 	
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97[NUM_ATI_CODECS];
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97[NUM_ATI_CODECS];
 
 	spinlock_t reg_lock;
 
-	atiixp_dma_t dmas[NUM_ATI_DMAS];
+	struct atiixp_dma dmas[NUM_ATI_DMAS];
 	struct ac97_pcm *pcms[NUM_ATI_PCMS];
-	snd_pcm_t *pcmdevs[NUM_ATI_PCMDEVS];
+	struct snd_pcm *pcmdevs[NUM_ATI_PCMDEVS];
 
 	int max_channels;		/* max. channels for PCM out */
 
@@ -304,7 +301,7 @@
  * update the bits of the given register.
  * return 1 if the bits changed.
  */
-static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
+static int snd_atiixp_update_bits(struct atiixp *chip, unsigned int reg,
 				 unsigned int mask, unsigned int value)
 {
 	void __iomem *addr = chip->remap_addr + reg;
@@ -328,12 +325,6 @@
 #define atiixp_update(chip,reg,mask,val) \
 	snd_atiixp_update_bits(chip, ATI_REG_##reg, mask, val)
 
-/* delay for one tick */
-#define do_delay() do { \
-	schedule_timeout_uninterruptible(1); \
-} while (0)
-
-
 /*
  * handling DMA packets
  *
@@ -342,7 +333,7 @@
  */
 
 #define ATI_DESC_LIST_SIZE \
-	PAGE_ALIGN(ATI_MAX_DESCRIPTORS * sizeof(atiixp_dma_desc_t))
+	PAGE_ALIGN(ATI_MAX_DESCRIPTORS * sizeof(struct atiixp_dma_desc))
 
 /*
  * build packets ring for the given buffer size.
@@ -353,10 +344,10 @@
  *
  * the ring is built in this function, and is set up to the hardware. 
  */
-static int atiixp_build_dma_packets(atiixp_t *chip, atiixp_dma_t *dma,
-				   snd_pcm_substream_t *substream,
-				   unsigned int periods,
-				   unsigned int period_bytes)
+static int atiixp_build_dma_packets(struct atiixp *chip, struct atiixp_dma *dma,
+				    struct snd_pcm_substream *substream,
+				    unsigned int periods,
+				    unsigned int period_bytes)
 {
 	unsigned int i;
 	u32 addr, desc_addr;
@@ -366,8 +357,10 @@
 		return -ENOMEM;
 
 	if (dma->desc_buf.area == NULL) {
-		if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
-					ATI_DESC_LIST_SIZE, &dma->desc_buf) < 0)
+		if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+					snd_dma_pci_data(chip->pci),
+					ATI_DESC_LIST_SIZE,
+					&dma->desc_buf) < 0)
 			return -ENOMEM;
 		dma->period_bytes = dma->periods = 0; /* clear */
 	}
@@ -386,11 +379,12 @@
 	addr = (u32)substream->runtime->dma_addr;
 	desc_addr = (u32)dma->desc_buf.addr;
 	for (i = 0; i < periods; i++) {
-		atiixp_dma_desc_t *desc = &((atiixp_dma_desc_t *)dma->desc_buf.area)[i];
+		struct atiixp_dma_desc *desc;
+		desc = &((struct atiixp_dma_desc *)dma->desc_buf.area)[i];
 		desc->addr = cpu_to_le32(addr);
 		desc->status = 0;
 		desc->size = period_bytes >> 2; /* in dwords */
-		desc_addr += sizeof(atiixp_dma_desc_t);
+		desc_addr += sizeof(struct atiixp_dma_desc);
 		if (i == periods - 1)
 			desc->next = cpu_to_le32((u32)dma->desc_buf.addr);
 		else
@@ -410,7 +404,8 @@
 /*
  * remove the ring buffer and release it if assigned
  */
-static void atiixp_clear_dma_packets(atiixp_t *chip, atiixp_dma_t *dma, snd_pcm_substream_t *substream)
+static void atiixp_clear_dma_packets(struct atiixp *chip, struct atiixp_dma *dma,
+				     struct snd_pcm_substream *substream)
 {
 	if (dma->desc_buf.area) {
 		writel(0, chip->remap_addr + dma->ops->llp_offset);
@@ -422,7 +417,7 @@
 /*
  * AC97 interface
  */
-static int snd_atiixp_acquire_codec(atiixp_t *chip)
+static int snd_atiixp_acquire_codec(struct atiixp *chip)
 {
 	int timeout = 1000;
 
@@ -436,7 +431,7 @@
 	return 0;
 }
 
-static unsigned short snd_atiixp_codec_read(atiixp_t *chip, unsigned short codec, unsigned short reg)
+static unsigned short snd_atiixp_codec_read(struct atiixp *chip, unsigned short codec, unsigned short reg)
 {
 	unsigned int data;
 	int timeout;
@@ -464,7 +459,8 @@
 }
 
 
-static void snd_atiixp_codec_write(atiixp_t *chip, unsigned short codec, unsigned short reg, unsigned short val)
+static void snd_atiixp_codec_write(struct atiixp *chip, unsigned short codec,
+				   unsigned short reg, unsigned short val)
 {
 	unsigned int data;
     
@@ -477,23 +473,25 @@
 }
 
 
-static unsigned short snd_atiixp_ac97_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_atiixp_ac97_read(struct snd_ac97 *ac97,
+					   unsigned short reg)
 {
-	atiixp_t *chip = ac97->private_data;
+	struct atiixp *chip = ac97->private_data;
 	return snd_atiixp_codec_read(chip, ac97->num, reg);
     
 }
 
-static void snd_atiixp_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+static void snd_atiixp_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+				  unsigned short val)
 {
-	atiixp_t *chip = ac97->private_data;
+	struct atiixp *chip = ac97->private_data;
 	snd_atiixp_codec_write(chip, ac97->num, reg, val);
 }
 
 /*
  * reset AC link
  */
-static int snd_atiixp_aclink_reset(atiixp_t *chip)
+static int snd_atiixp_aclink_reset(struct atiixp *chip)
 {
 	int timeout;
 
@@ -513,7 +511,7 @@
 		atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
 			      ATI_REG_CMD_AC_SYNC);
 		atiixp_read(chip, CMD);
-		do_delay();
+		mdelay(1);
 		atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
 		if (--timeout) {
 			snd_printk(KERN_ERR "atiixp: codec reset timeout\n");
@@ -529,7 +527,7 @@
 }
 
 #ifdef CONFIG_PM
-static int snd_atiixp_aclink_down(atiixp_t *chip)
+static int snd_atiixp_aclink_down(struct atiixp *chip)
 {
 	// if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
 	//	return -EBUSY;
@@ -554,16 +552,16 @@
 	     ATI_REG_ISR_CODEC2_NOT_READY)
 #define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)
 
-static int snd_atiixp_codec_detect(atiixp_t *chip)
+static int snd_atiixp_codec_detect(struct atiixp *chip)
 {
 	int timeout;
 
 	chip->codec_not_ready_bits = 0;
 	atiixp_write(chip, IER, CODEC_CHECK_BITS);
 	/* wait for the interrupts */
-	timeout = HZ / 10;
+	timeout = 50;
 	while (timeout-- > 0) {
-		do_delay();
+		mdelay(1);
 		if (chip->codec_not_ready_bits)
 			break;
 	}
@@ -580,7 +578,7 @@
 /*
  * enable DMA and irqs
  */
-static int snd_atiixp_chip_start(atiixp_t *chip)
+static int snd_atiixp_chip_start(struct atiixp *chip)
 {
 	unsigned int reg;
 
@@ -610,7 +608,7 @@
 /*
  * disable DMA and IRQs
  */
-static int snd_atiixp_chip_stop(atiixp_t *chip)
+static int snd_atiixp_chip_stop(struct atiixp *chip)
 {
 	/* clear interrupt source */
 	atiixp_write(chip, ISR, atiixp_read(chip, ISR));
@@ -629,11 +627,11 @@
  * position.  when SG-buffer is implemented, the offset must be calculated
  * correctly...
  */
-static snd_pcm_uframes_t snd_atiixp_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_atiixp_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data;
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct atiixp_dma *dma = runtime->private_data;
 	unsigned int curptr;
 	int timeout = 1000;
 
@@ -654,7 +652,7 @@
 /*
  * XRUN detected, and stop the PCM substream
  */
-static void snd_atiixp_xrun_dma(atiixp_t *chip, atiixp_dma_t *dma)
+static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma)
 {
 	if (! dma->substream || ! dma->running)
 		return;
@@ -665,7 +663,7 @@
 /*
  * the period ack.  update the substream.
  */
-static void snd_atiixp_update_dma(atiixp_t *chip, atiixp_dma_t *dma)
+static void snd_atiixp_update_dma(struct atiixp *chip, struct atiixp_dma *dma)
 {
 	if (! dma->substream || ! dma->running)
 		return;
@@ -674,7 +672,7 @@
 
 /* set BUS_BUSY interrupt bit if any DMA is running */
 /* call with spinlock held */
-static void snd_atiixp_check_bus_busy(atiixp_t *chip)
+static void snd_atiixp_check_bus_busy(struct atiixp *chip)
 {
 	unsigned int bus_busy;
 	if (atiixp_read(chip, CMD) & (ATI_REG_CMD_SEND_EN |
@@ -689,10 +687,10 @@
 /* common trigger callback
  * calling the lowlevel callbacks in it
  */
-static int snd_atiixp_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_dma *dma = substream->runtime->private_data;
 	int err = 0;
 
 	snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL);
@@ -736,13 +734,13 @@
  */
 
 /* flush FIFO of analog OUT DMA */
-static void atiixp_out_flush_dma(atiixp_t *chip)
+static void atiixp_out_flush_dma(struct atiixp *chip)
 {
 	atiixp_write(chip, FIFO_FLUSH, ATI_REG_FIFO_OUT_FLUSH);
 }
 
 /* enable/disable analog OUT DMA */
-static void atiixp_out_enable_dma(atiixp_t *chip, int on)
+static void atiixp_out_enable_dma(struct atiixp *chip, int on)
 {
 	unsigned int data;
 	data = atiixp_read(chip, CMD);
@@ -757,21 +755,21 @@
 }
 
 /* start/stop transfer over OUT DMA */
-static void atiixp_out_enable_transfer(atiixp_t *chip, int on)
+static void atiixp_out_enable_transfer(struct atiixp *chip, int on)
 {
 	atiixp_update(chip, CMD, ATI_REG_CMD_SEND_EN,
 		      on ? ATI_REG_CMD_SEND_EN : 0);
 }
 
 /* enable/disable analog IN DMA */
-static void atiixp_in_enable_dma(atiixp_t *chip, int on)
+static void atiixp_in_enable_dma(struct atiixp *chip, int on)
 {
 	atiixp_update(chip, CMD, ATI_REG_CMD_IN_DMA_EN,
 		      on ? ATI_REG_CMD_IN_DMA_EN : 0);
 }
 
 /* start/stop analog IN DMA */
-static void atiixp_in_enable_transfer(atiixp_t *chip, int on)
+static void atiixp_in_enable_transfer(struct atiixp *chip, int on)
 {
 	if (on) {
 		unsigned int data = atiixp_read(chip, CMD);
@@ -790,20 +788,20 @@
 }
 
 /* flush FIFO of analog IN DMA */
-static void atiixp_in_flush_dma(atiixp_t *chip)
+static void atiixp_in_flush_dma(struct atiixp *chip)
 {
 	atiixp_write(chip, FIFO_FLUSH, ATI_REG_FIFO_IN_FLUSH);
 }
 
 /* enable/disable SPDIF OUT DMA */
-static void atiixp_spdif_enable_dma(atiixp_t *chip, int on)
+static void atiixp_spdif_enable_dma(struct atiixp *chip, int on)
 {
 	atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_DMA_EN,
 		      on ? ATI_REG_CMD_SPDF_DMA_EN : 0);
 }
 
 /* start/stop SPDIF OUT DMA */
-static void atiixp_spdif_enable_transfer(atiixp_t *chip, int on)
+static void atiixp_spdif_enable_transfer(struct atiixp *chip, int on)
 {
 	unsigned int data;
 	data = atiixp_read(chip, CMD);
@@ -815,7 +813,7 @@
 }
 
 /* flush FIFO of SPDIF OUT DMA */
-static void atiixp_spdif_flush_dma(atiixp_t *chip)
+static void atiixp_spdif_flush_dma(struct atiixp *chip)
 {
 	int timeout;
 
@@ -834,9 +832,9 @@
 }
 
 /* set up slots and formats for SPDIF OUT */
-static int snd_atiixp_spdif_prepare(snd_pcm_substream_t *substream)
+static int snd_atiixp_spdif_prepare(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&chip->reg_lock);
 	if (chip->spdif_over_aclink) {
@@ -861,9 +859,9 @@
 }
 
 /* set up slots and formats for analog OUT */
-static int snd_atiixp_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 	unsigned int data;
 
 	spin_lock_irq(&chip->reg_lock);
@@ -906,9 +904,9 @@
 }
 
 /* set up slots and formats for analog IN */
-static int snd_atiixp_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_atiixp_capture_prepare(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&chip->reg_lock);
 	atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_IN,
@@ -921,11 +919,11 @@
 /*
  * hw_params - allocate the buffer and set up buffer descriptors
  */
-static int snd_atiixp_pcm_hw_params(snd_pcm_substream_t *substream,
-				   snd_pcm_hw_params_t *hw_params)
+static int snd_atiixp_pcm_hw_params(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *hw_params)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_dma *dma = substream->runtime->private_data;
 	int err;
 
 	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
@@ -959,10 +957,10 @@
 	return err;
 }
 
-static int snd_atiixp_pcm_hw_free(snd_pcm_substream_t * substream)
+static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_dma *dma = substream->runtime->private_data;
 
 	if (dma->pcm_open_flag) {
 		struct ac97_pcm *pcm = chip->pcms[dma->ac97_pcm_type];
@@ -978,7 +976,7 @@
 /*
  * pcm hardware definition, identical for all DMA types
  */
-static snd_pcm_hardware_t snd_atiixp_pcm_hw =
+static struct snd_pcm_hardware snd_atiixp_pcm_hw =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -998,10 +996,11 @@
 	.periods_max =		ATI_MAX_DESCRIPTORS,
 };
 
-static int snd_atiixp_pcm_open(snd_pcm_substream_t *substream, atiixp_dma_t *dma, int pcm_type)
+static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
+			       struct atiixp_dma *dma, int pcm_type)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
@@ -1031,9 +1030,10 @@
 	return 0;
 }
 
-static int snd_atiixp_pcm_close(snd_pcm_substream_t *substream, atiixp_dma_t *dma)
+static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
+				struct atiixp_dma *dma)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 	/* disable DMA bits */
 	snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
 	spin_lock_irq(&chip->reg_lock);
@@ -1046,9 +1046,9 @@
 
 /*
  */
-static int snd_atiixp_playback_open(snd_pcm_substream_t *substream)
+static int snd_atiixp_playback_open(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 	int err;
 
 	down(&chip->open_mutex);
@@ -1064,9 +1064,9 @@
 	return 0;
 }
 
-static int snd_atiixp_playback_close(snd_pcm_substream_t *substream)
+static int snd_atiixp_playback_close(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 	int err;
 	down(&chip->open_mutex);
 	err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
@@ -1074,21 +1074,21 @@
 	return err;
 }
 
-static int snd_atiixp_capture_open(snd_pcm_substream_t *substream)
+static int snd_atiixp_capture_open(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 	return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_CAPTURE], 1);
 }
 
-static int snd_atiixp_capture_close(snd_pcm_substream_t *substream)
+static int snd_atiixp_capture_close(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 	return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_CAPTURE]);
 }
 
-static int snd_atiixp_spdif_open(snd_pcm_substream_t *substream)
+static int snd_atiixp_spdif_open(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 	int err;
 	down(&chip->open_mutex);
 	if (chip->spdif_over_aclink) /* share DMA_PLAYBACK */
@@ -1099,9 +1099,9 @@
 	return err;
 }
 
-static int snd_atiixp_spdif_close(snd_pcm_substream_t *substream)
+static int snd_atiixp_spdif_close(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp *chip = snd_pcm_substream_chip(substream);
 	int err;
 	down(&chip->open_mutex);
 	if (chip->spdif_over_aclink)
@@ -1113,7 +1113,7 @@
 }
 
 /* AC97 playback */
-static snd_pcm_ops_t snd_atiixp_playback_ops = {
+static struct snd_pcm_ops snd_atiixp_playback_ops = {
 	.open =		snd_atiixp_playback_open,
 	.close =	snd_atiixp_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1125,7 +1125,7 @@
 };
 
 /* AC97 capture */
-static snd_pcm_ops_t snd_atiixp_capture_ops = {
+static struct snd_pcm_ops snd_atiixp_capture_ops = {
 	.open =		snd_atiixp_capture_open,
 	.close =	snd_atiixp_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1137,7 +1137,7 @@
 };
 
 /* SPDIF playback */
-static snd_pcm_ops_t snd_atiixp_spdif_ops = {
+static struct snd_pcm_ops snd_atiixp_spdif_ops = {
 	.open =		snd_atiixp_spdif_open,
 	.close =	snd_atiixp_spdif_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1184,7 +1184,7 @@
 	},
 };
 
-static atiixp_dma_ops_t snd_atiixp_playback_dma_ops = {
+static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = {
 	.type = ATI_DMA_PLAYBACK,
 	.llp_offset = ATI_REG_OUT_DMA_LINKPTR,
 	.dt_cur = ATI_REG_OUT_DMA_DT_CUR,
@@ -1193,7 +1193,7 @@
 	.flush_dma = atiixp_out_flush_dma,
 };
 	
-static atiixp_dma_ops_t snd_atiixp_capture_dma_ops = {
+static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = {
 	.type = ATI_DMA_CAPTURE,
 	.llp_offset = ATI_REG_IN_DMA_LINKPTR,
 	.dt_cur = ATI_REG_IN_DMA_DT_CUR,
@@ -1202,7 +1202,7 @@
 	.flush_dma = atiixp_in_flush_dma,
 };
 	
-static atiixp_dma_ops_t snd_atiixp_spdif_dma_ops = {
+static struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = {
 	.type = ATI_DMA_SPDIF,
 	.llp_offset = ATI_REG_SPDF_DMA_LINKPTR,
 	.dt_cur = ATI_REG_SPDF_DMA_DT_CUR,
@@ -1212,10 +1212,10 @@
 };
 	
 
-static int __devinit snd_atiixp_pcm_new(atiixp_t *chip)
+static int __devinit snd_atiixp_pcm_new(struct atiixp *chip)
 {
-	snd_pcm_t *pcm;
-	ac97_bus_t *pbus = chip->ac97_bus;
+	struct snd_pcm *pcm;
+	struct snd_ac97_bus *pbus = chip->ac97_bus;
 	int err, i, num_pcms;
 
 	/* initialize constants */
@@ -1244,7 +1244,8 @@
 	}
 
 	/* PCM #0: analog I/O */
-	err = snd_pcm_new(chip->card, "ATI IXP AC97", ATI_PCMDEV_ANALOG, 1, 1, &pcm);
+	err = snd_pcm_new(chip->card, "ATI IXP AC97",
+			  ATI_PCMDEV_ANALOG, 1, 1, &pcm);
 	if (err < 0)
 		return err;
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
@@ -1254,7 +1255,8 @@
 	chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-					      snd_dma_pci_data(chip->pci), 64*1024, 128*1024);
+					      snd_dma_pci_data(chip->pci),
+					      64*1024, 128*1024);
 
 	/* no SPDIF support on codec? */
 	if (chip->pcms[ATI_PCM_SPDIF] && ! chip->pcms[ATI_PCM_SPDIF]->rates)
@@ -1265,7 +1267,8 @@
 		chip->pcms[ATI_PCM_SPDIF]->rates = SNDRV_PCM_RATE_48000;
 
 	/* PCM #1: spdif playback */
-	err = snd_pcm_new(chip->card, "ATI IXP IEC958", ATI_PCMDEV_DIGITAL, 1, 0, &pcm);
+	err = snd_pcm_new(chip->card, "ATI IXP IEC958",
+			  ATI_PCMDEV_DIGITAL, 1, 0, &pcm);
 	if (err < 0)
 		return err;
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_spdif_ops);
@@ -1277,12 +1280,15 @@
 	chip->pcmdevs[ATI_PCMDEV_DIGITAL] = pcm;
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-					      snd_dma_pci_data(chip->pci), 64*1024, 128*1024);
+					      snd_dma_pci_data(chip->pci),
+					      64*1024, 128*1024);
 
 	/* pre-select AC97 SPDIF slots 10/11 */
 	for (i = 0; i < NUM_ATI_CODECS; i++) {
 		if (chip->ac97[i])
-			snd_ac97_update_bits(chip->ac97[i], AC97_EXTENDED_STATUS, 0x03 << 4, 0x03 << 4);
+			snd_ac97_update_bits(chip->ac97[i],
+					     AC97_EXTENDED_STATUS,
+					     0x03 << 4, 0x03 << 4);
 	}
 
 	return 0;
@@ -1295,7 +1301,7 @@
  */
 static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	atiixp_t *chip = dev_id;
+	struct atiixp *chip = dev_id;
 	unsigned int status;
 
 	status = atiixp_read(chip, ISR);
@@ -1347,16 +1353,23 @@
 		.name = "HP Pavilion ZV5030US",
 		.type = AC97_TUNE_MUTE_LED
 	},
+	{
+		.subvendor = 0x103c,
+		.subdevice = 0x308b,
+		.name = "HP nx6125",
+		.type = AC97_TUNE_MUTE_LED
+	},
 	{ } /* terminator */
 };
 
-static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock, const char *quirk_override)
+static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock,
+					  const char *quirk_override)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
 	int i, err;
 	int codec_count;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_atiixp_ac97_write,
 		.read = snd_atiixp_ac97_read,
 	};
@@ -1408,90 +1421,100 @@
 /*
  * power management
  */
-static int snd_atiixp_suspend(snd_card_t *card, pm_message_t state)
+static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	atiixp_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct atiixp *chip = card->private_data;
 	int i;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	for (i = 0; i < NUM_ATI_PCMDEVS; i++)
 		if (chip->pcmdevs[i]) {
-			atiixp_dma_t *dma = &chip->dmas[i];
+			struct atiixp_dma *dma = &chip->dmas[i];
 			if (dma->substream && dma->running)
-				dma->saved_curptr = readl(chip->remap_addr + dma->ops->dt_cur);
+				dma->saved_curptr = readl(chip->remap_addr +
+							  dma->ops->dt_cur);
 			snd_pcm_suspend_all(chip->pcmdevs[i]);
 		}
 	for (i = 0; i < NUM_ATI_CODECS; i++)
-		if (chip->ac97[i])
-			snd_ac97_suspend(chip->ac97[i]);
+		snd_ac97_suspend(chip->ac97[i]);
 	snd_atiixp_aclink_down(chip);
 	snd_atiixp_chip_stop(chip);
 
-	pci_set_power_state(chip->pci, PCI_D3hot);
-	pci_disable_device(chip->pci);
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int snd_atiixp_resume(snd_card_t *card)
+static int snd_atiixp_resume(struct pci_dev *pci)
 {
-	atiixp_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct atiixp *chip = card->private_data;
 	int i;
 
-	pci_enable_device(chip->pci);
-	pci_set_power_state(chip->pci, PCI_D0);
-	pci_set_master(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
+	pci_set_master(pci);
 
 	snd_atiixp_aclink_reset(chip);
 	snd_atiixp_chip_start(chip);
 
 	for (i = 0; i < NUM_ATI_CODECS; i++)
-		if (chip->ac97[i])
-			snd_ac97_resume(chip->ac97[i]);
+		snd_ac97_resume(chip->ac97[i]);
 
 	for (i = 0; i < NUM_ATI_PCMDEVS; i++)
 		if (chip->pcmdevs[i]) {
-			atiixp_dma_t *dma = &chip->dmas[i];
+			struct atiixp_dma *dma = &chip->dmas[i];
 			if (dma->substream && dma->suspended) {
 				dma->ops->enable_dma(chip, 1);
 				dma->substream->ops->prepare(dma->substream);
 				writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
 				       chip->remap_addr + dma->ops->llp_offset);
-				writel(dma->saved_curptr, chip->remap_addr + dma->ops->dt_cur);
+				writel(dma->saved_curptr, chip->remap_addr +
+				       dma->ops->dt_cur);
 			}
 		}
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
 
+#ifdef CONFIG_PROC_FS
 /*
  * proc interface for register dump
  */
 
-static void snd_atiixp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_atiixp_proc_read(struct snd_info_entry *entry,
+				 struct snd_info_buffer *buffer)
 {
-	atiixp_t *chip = entry->private_data;
+	struct atiixp *chip = entry->private_data;
 	int i;
 
 	for (i = 0; i < 256; i += 4)
 		snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i));
 }
 
-static void __devinit snd_atiixp_proc_init(atiixp_t *chip)
+static void __devinit snd_atiixp_proc_init(struct atiixp *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(chip->card, "atiixp", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read);
 }
-
+#else /* !CONFIG_PROC_FS */
+#define snd_atiixp_proc_init(chip)
+#endif
 
 
 /*
  * destructor
  */
 
-static int snd_atiixp_free(atiixp_t *chip)
+static int snd_atiixp_free(struct atiixp *chip)
 {
 	if (chip->irq < 0)
 		goto __hw_end;
@@ -1499,7 +1522,7 @@
 	synchronize_irq(chip->irq);
       __hw_end:
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	if (chip->remap_addr)
 		iounmap(chip->remap_addr);
 	pci_release_regions(chip->pci);
@@ -1508,23 +1531,23 @@
 	return 0;
 }
 
-static int snd_atiixp_dev_free(snd_device_t *device)
+static int snd_atiixp_dev_free(struct snd_device *device)
 {
-	atiixp_t *chip = device->device_data;
+	struct atiixp *chip = device->device_data;
 	return snd_atiixp_free(chip);
 }
 
 /*
  * constructor for chip instance
  */
-static int __devinit snd_atiixp_create(snd_card_t *card,
+static int __devinit snd_atiixp_create(struct snd_card *card,
 				      struct pci_dev *pci,
-				      atiixp_t **r_chip)
+				      struct atiixp **r_chip)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_atiixp_dev_free,
 	};
-	atiixp_t *chip;
+	struct atiixp *chip;
 	int err;
 
 	if ((err = pci_enable_device(pci)) < 0)
@@ -1554,7 +1577,8 @@
 		return -EIO;
 	}
 
-	if (request_irq(pci->irq, snd_atiixp_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
+	if (request_irq(pci->irq, snd_atiixp_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_atiixp_free(chip);
 		return -EBUSY;
@@ -1578,8 +1602,8 @@
 static int __devinit snd_atiixp_probe(struct pci_dev *pci,
 				     const struct pci_device_id *pci_id)
 {
-	snd_card_t *card;
-	atiixp_t *chip;
+	struct snd_card *card;
+	struct atiixp *chip;
 	unsigned char revision;
 	int err;
 
@@ -1593,6 +1617,7 @@
 	strcpy(card->shortname, "ATI IXP");
 	if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
 		goto __error;
+	card->private_data = chip;
 
 	if ((err = snd_atiixp_aclink_reset(chip)) < 0)
 		goto __error;
@@ -1614,8 +1639,6 @@
 		 chip->ac97[0] ? snd_ac97_get_short_name(chip->ac97[0]) : "?",
 		 chip->addr, chip->irq);
 
-	snd_card_set_pm_callback(card, snd_atiixp_suspend, snd_atiixp_resume, chip);
-
 	if ((err = snd_card_register(card)) < 0)
 		goto __error;
 
@@ -1638,7 +1661,10 @@
 	.id_table = snd_atiixp_ids,
 	.probe = snd_atiixp_probe,
 	.remove = __devexit_p(snd_atiixp_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = snd_atiixp_suspend,
+	.resume = snd_atiixp_resume,
+#endif
 };
 
 
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 3174b66..8d8fd5a 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -176,24 +176,18 @@
 #define ATI_MAX_DESCRIPTORS	256	/* max number of descriptor packets */
 
 
-/*
- */
-
-typedef struct snd_atiixp atiixp_t;
-typedef struct snd_atiixp_dma atiixp_dma_t;
-typedef struct snd_atiixp_dma_ops atiixp_dma_ops_t;
-
+struct atiixp_modem;
 
 /*
  * DMA packate descriptor
  */
 
-typedef struct atiixp_dma_desc {
+struct atiixp_dma_desc {
 	u32 addr;	/* DMA buffer address */
 	u16 status;	/* status bits */
 	u16 size;	/* size of the packet in dwords */
 	u32 next;	/* address of the next packet descriptor */
-} atiixp_dma_desc_t;
+};
 
 /*
  * stream enum
@@ -208,22 +202,25 @@
 /*
  * constants and callbacks for each DMA type
  */
-struct snd_atiixp_dma_ops {
+struct atiixp_dma_ops {
 	int type;			/* ATI_DMA_XXX */
 	unsigned int llp_offset;	/* LINKPTR offset */
 	unsigned int dt_cur;		/* DT_CUR offset */
-	void (*enable_dma)(atiixp_t *chip, int on);	/* called from open callback */
-	void (*enable_transfer)(atiixp_t *chip, int on); /* called from trigger (START/STOP) */
-	void (*flush_dma)(atiixp_t *chip);		/* called from trigger (STOP only) */
+	/* called from open callback */
+	void (*enable_dma)(struct atiixp_modem *chip, int on);
+	/* called from trigger (START/STOP) */
+	void (*enable_transfer)(struct atiixp_modem *chip, int on);
+ 	/* called from trigger (STOP only) */
+	void (*flush_dma)(struct atiixp_modem *chip);
 };
 
 /*
  * DMA stream
  */
-struct snd_atiixp_dma {
-	const atiixp_dma_ops_t *ops;
+struct atiixp_dma {
+	const struct atiixp_dma_ops *ops;
 	struct snd_dma_buffer desc_buf;
-	snd_pcm_substream_t *substream;	/* assigned PCM substream */
+	struct snd_pcm_substream *substream;	/* assigned PCM substream */
 	unsigned int buf_addr, buf_bytes;	/* DMA buffer address, bytes */
 	unsigned int period_bytes, periods;
 	int opened;
@@ -235,8 +232,8 @@
 /*
  * ATI IXP chip
  */
-struct snd_atiixp {
-	snd_card_t *card;
+struct atiixp_modem {
+	struct snd_card *card;
 	struct pci_dev *pci;
 
 	struct resource *res;		/* memory i/o */
@@ -244,14 +241,14 @@
 	void __iomem *remap_addr;
 	int irq;
 	
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97[NUM_ATI_CODECS];
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97[NUM_ATI_CODECS];
 
 	spinlock_t reg_lock;
 
-	atiixp_dma_t dmas[NUM_ATI_DMAS];
+	struct atiixp_dma dmas[NUM_ATI_DMAS];
 	struct ac97_pcm *pcms[NUM_ATI_PCMS];
-	snd_pcm_t *pcmdevs[NUM_ATI_PCMDEVS];
+	struct snd_pcm *pcmdevs[NUM_ATI_PCMDEVS];
 
 	int max_channels;		/* max. channels for PCM out */
 
@@ -281,8 +278,8 @@
  * update the bits of the given register.
  * return 1 if the bits changed.
  */
-static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
-				 unsigned int mask, unsigned int value)
+static int snd_atiixp_update_bits(struct atiixp_modem *chip, unsigned int reg,
+				  unsigned int mask, unsigned int value)
 {
 	void __iomem *addr = chip->remap_addr + reg;
 	unsigned int data, old_data;
@@ -305,12 +302,6 @@
 #define atiixp_update(chip,reg,mask,val) \
 	snd_atiixp_update_bits(chip, ATI_REG_##reg, mask, val)
 
-/* delay for one tick */
-#define do_delay() do { \
-	schedule_timeout_uninterruptible(1); \
-} while (0)
-
-
 /*
  * handling DMA packets
  *
@@ -319,7 +310,7 @@
  */
 
 #define ATI_DESC_LIST_SIZE \
-	PAGE_ALIGN(ATI_MAX_DESCRIPTORS * sizeof(atiixp_dma_desc_t))
+	PAGE_ALIGN(ATI_MAX_DESCRIPTORS * sizeof(struct atiixp_dma_desc))
 
 /*
  * build packets ring for the given buffer size.
@@ -330,10 +321,11 @@
  *
  * the ring is built in this function, and is set up to the hardware. 
  */
-static int atiixp_build_dma_packets(atiixp_t *chip, atiixp_dma_t *dma,
-				   snd_pcm_substream_t *substream,
-				   unsigned int periods,
-				   unsigned int period_bytes)
+static int atiixp_build_dma_packets(struct atiixp_modem *chip,
+				    struct atiixp_dma *dma,
+				    struct snd_pcm_substream *substream,
+				    unsigned int periods,
+				    unsigned int period_bytes)
 {
 	unsigned int i;
 	u32 addr, desc_addr;
@@ -363,11 +355,12 @@
 	addr = (u32)substream->runtime->dma_addr;
 	desc_addr = (u32)dma->desc_buf.addr;
 	for (i = 0; i < periods; i++) {
-		atiixp_dma_desc_t *desc = &((atiixp_dma_desc_t *)dma->desc_buf.area)[i];
+		struct atiixp_dma_desc *desc;
+		desc = &((struct atiixp_dma_desc *)dma->desc_buf.area)[i];
 		desc->addr = cpu_to_le32(addr);
 		desc->status = 0;
 		desc->size = period_bytes >> 2; /* in dwords */
-		desc_addr += sizeof(atiixp_dma_desc_t);
+		desc_addr += sizeof(struct atiixp_dma_desc);
 		if (i == periods - 1)
 			desc->next = cpu_to_le32((u32)dma->desc_buf.addr);
 		else
@@ -387,7 +380,9 @@
 /*
  * remove the ring buffer and release it if assigned
  */
-static void atiixp_clear_dma_packets(atiixp_t *chip, atiixp_dma_t *dma, snd_pcm_substream_t *substream)
+static void atiixp_clear_dma_packets(struct atiixp_modem *chip,
+				     struct atiixp_dma *dma,
+				     struct snd_pcm_substream *substream)
 {
 	if (dma->desc_buf.area) {
 		writel(0, chip->remap_addr + dma->ops->llp_offset);
@@ -399,7 +394,7 @@
 /*
  * AC97 interface
  */
-static int snd_atiixp_acquire_codec(atiixp_t *chip)
+static int snd_atiixp_acquire_codec(struct atiixp_modem *chip)
 {
 	int timeout = 1000;
 
@@ -413,7 +408,9 @@
 	return 0;
 }
 
-static unsigned short snd_atiixp_codec_read(atiixp_t *chip, unsigned short codec, unsigned short reg)
+static unsigned short snd_atiixp_codec_read(struct atiixp_modem *chip,
+					    unsigned short codec,
+					    unsigned short reg)
 {
 	unsigned int data;
 	int timeout;
@@ -441,7 +438,9 @@
 }
 
 
-static void snd_atiixp_codec_write(atiixp_t *chip, unsigned short codec, unsigned short reg, unsigned short val)
+static void snd_atiixp_codec_write(struct atiixp_modem *chip,
+				   unsigned short codec,
+				   unsigned short reg, unsigned short val)
 {
 	unsigned int data;
     
@@ -454,16 +453,18 @@
 }
 
 
-static unsigned short snd_atiixp_ac97_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_atiixp_ac97_read(struct snd_ac97 *ac97,
+					   unsigned short reg)
 {
-	atiixp_t *chip = ac97->private_data;
+	struct atiixp_modem *chip = ac97->private_data;
 	return snd_atiixp_codec_read(chip, ac97->num, reg);
     
 }
 
-static void snd_atiixp_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+static void snd_atiixp_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+				  unsigned short val)
 {
-	atiixp_t *chip = ac97->private_data;
+	struct atiixp_modem *chip = ac97->private_data;
 	if (reg == AC97_GPIO_STATUS) {
 		atiixp_write(chip, MODEM_OUT_GPIO,
 			(val << ATI_REG_MODEM_OUT_GPIO_DATA_SHIFT) | ATI_REG_MODEM_OUT_GPIO_EN);
@@ -475,7 +476,7 @@
 /*
  * reset AC link
  */
-static int snd_atiixp_aclink_reset(atiixp_t *chip)
+static int snd_atiixp_aclink_reset(struct atiixp_modem *chip)
 {
 	int timeout;
 
@@ -495,7 +496,7 @@
 		atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
 			      ATI_REG_CMD_AC_SYNC);
 		atiixp_read(chip, CMD);
-		do_delay();
+		msleep(1);
 		atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
 		if (--timeout) {
 			snd_printk(KERN_ERR "atiixp-modem: codec reset timeout\n");
@@ -511,7 +512,7 @@
 }
 
 #ifdef CONFIG_PM
-static int snd_atiixp_aclink_down(atiixp_t *chip)
+static int snd_atiixp_aclink_down(struct atiixp_modem *chip)
 {
 	// if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
 	//	return -EBUSY;
@@ -536,16 +537,16 @@
 	     ATI_REG_ISR_CODEC2_NOT_READY)
 #define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)
 
-static int snd_atiixp_codec_detect(atiixp_t *chip)
+static int snd_atiixp_codec_detect(struct atiixp_modem *chip)
 {
 	int timeout;
 
 	chip->codec_not_ready_bits = 0;
 	atiixp_write(chip, IER, CODEC_CHECK_BITS);
 	/* wait for the interrupts */
-	timeout = HZ / 10;
+	timeout = 50;
 	while (timeout-- > 0) {
-		do_delay();
+		msleep(1);
 		if (chip->codec_not_ready_bits)
 			break;
 	}
@@ -562,7 +563,7 @@
 /*
  * enable DMA and irqs
  */
-static int snd_atiixp_chip_start(atiixp_t *chip)
+static int snd_atiixp_chip_start(struct atiixp_modem *chip)
 {
 	unsigned int reg;
 
@@ -587,7 +588,7 @@
 /*
  * disable DMA and IRQs
  */
-static int snd_atiixp_chip_stop(atiixp_t *chip)
+static int snd_atiixp_chip_stop(struct atiixp_modem *chip)
 {
 	/* clear interrupt source */
 	atiixp_write(chip, ISR, atiixp_read(chip, ISR));
@@ -606,11 +607,11 @@
  * position.  when SG-buffer is implemented, the offset must be calculated
  * correctly...
  */
-static snd_pcm_uframes_t snd_atiixp_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_atiixp_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	atiixp_dma_t *dma = (atiixp_dma_t *)runtime->private_data;
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct atiixp_dma *dma = runtime->private_data;
 	unsigned int curptr;
 	int timeout = 1000;
 
@@ -631,7 +632,8 @@
 /*
  * XRUN detected, and stop the PCM substream
  */
-static void snd_atiixp_xrun_dma(atiixp_t *chip, atiixp_dma_t *dma)
+static void snd_atiixp_xrun_dma(struct atiixp_modem *chip,
+				struct atiixp_dma *dma)
 {
 	if (! dma->substream || ! dma->running)
 		return;
@@ -642,7 +644,8 @@
 /*
  * the period ack.  update the substream.
  */
-static void snd_atiixp_update_dma(atiixp_t *chip, atiixp_dma_t *dma)
+static void snd_atiixp_update_dma(struct atiixp_modem *chip,
+				  struct atiixp_dma *dma)
 {
 	if (! dma->substream || ! dma->running)
 		return;
@@ -651,7 +654,7 @@
 
 /* set BUS_BUSY interrupt bit if any DMA is running */
 /* call with spinlock held */
-static void snd_atiixp_check_bus_busy(atiixp_t *chip)
+static void snd_atiixp_check_bus_busy(struct atiixp_modem *chip)
 {
 	unsigned int bus_busy;
 	if (atiixp_read(chip, CMD) & (ATI_REG_CMD_MODEM_SEND1_EN |
@@ -665,10 +668,10 @@
 /* common trigger callback
  * calling the lowlevel callbacks in it
  */
-static int snd_atiixp_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_dma *dma = substream->runtime->private_data;
 	int err = 0;
 
 	snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL);
@@ -706,13 +709,13 @@
  */
 
 /* flush FIFO of analog OUT DMA */
-static void atiixp_out_flush_dma(atiixp_t *chip)
+static void atiixp_out_flush_dma(struct atiixp_modem *chip)
 {
 	atiixp_write(chip, MODEM_FIFO_FLUSH, ATI_REG_MODEM_FIFO_OUT1_FLUSH);
 }
 
 /* enable/disable analog OUT DMA */
-static void atiixp_out_enable_dma(atiixp_t *chip, int on)
+static void atiixp_out_enable_dma(struct atiixp_modem *chip, int on)
 {
 	unsigned int data;
 	data = atiixp_read(chip, CMD);
@@ -727,21 +730,21 @@
 }
 
 /* start/stop transfer over OUT DMA */
-static void atiixp_out_enable_transfer(atiixp_t *chip, int on)
+static void atiixp_out_enable_transfer(struct atiixp_modem *chip, int on)
 {
 	atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_SEND1_EN,
 		      on ? ATI_REG_CMD_MODEM_SEND1_EN : 0);
 }
 
 /* enable/disable analog IN DMA */
-static void atiixp_in_enable_dma(atiixp_t *chip, int on)
+static void atiixp_in_enable_dma(struct atiixp_modem *chip, int on)
 {
 	atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_IN_DMA_EN,
 		      on ? ATI_REG_CMD_MODEM_IN_DMA_EN : 0);
 }
 
 /* start/stop analog IN DMA */
-static void atiixp_in_enable_transfer(atiixp_t *chip, int on)
+static void atiixp_in_enable_transfer(struct atiixp_modem *chip, int on)
 {
 	if (on) {
 		unsigned int data = atiixp_read(chip, CMD);
@@ -754,15 +757,15 @@
 }
 
 /* flush FIFO of analog IN DMA */
-static void atiixp_in_flush_dma(atiixp_t *chip)
+static void atiixp_in_flush_dma(struct atiixp_modem *chip)
 {
 	atiixp_write(chip, MODEM_FIFO_FLUSH, ATI_REG_MODEM_FIFO_IN_FLUSH);
 }
 
 /* set up slots and formats for analog OUT */
-static int snd_atiixp_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
 	unsigned int data;
 
 	spin_lock_irq(&chip->reg_lock);
@@ -776,7 +779,7 @@
 }
 
 /* set up slots and formats for analog IN */
-static int snd_atiixp_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_atiixp_capture_prepare(struct snd_pcm_substream *substream)
 {
 	return 0;
 }
@@ -784,11 +787,11 @@
 /*
  * hw_params - allocate the buffer and set up buffer descriptors
  */
-static int snd_atiixp_pcm_hw_params(snd_pcm_substream_t *substream,
-				   snd_pcm_hw_params_t *hw_params)
+static int snd_atiixp_pcm_hw_params(struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *hw_params)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_dma *dma = substream->runtime->private_data;
 	int err;
 	int i;
 
@@ -815,10 +818,10 @@
 	return err;
 }
 
-static int snd_atiixp_pcm_hw_free(snd_pcm_substream_t * substream)
+static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	atiixp_dma_t *dma = (atiixp_dma_t *)substream->runtime->private_data;
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_dma *dma = substream->runtime->private_data;
 
 	atiixp_clear_dma_packets(chip, dma, substream);
 	snd_pcm_lib_free_pages(substream);
@@ -829,13 +832,15 @@
 /*
  * pcm hardware definition, identical for all DMA types
  */
-static snd_pcm_hardware_t snd_atiixp_pcm_hw =
+static struct snd_pcm_hardware snd_atiixp_pcm_hw =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
-	.rates =		SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_KNOT,
+	.rates =		(SNDRV_PCM_RATE_8000 |
+				 SNDRV_PCM_RATE_16000 |
+				 SNDRV_PCM_RATE_KNOT),
 	.rate_min =		8000,
 	.rate_max =		16000,
 	.channels_min =		2,
@@ -847,13 +852,14 @@
 	.periods_max =		ATI_MAX_DESCRIPTORS,
 };
 
-static int snd_atiixp_pcm_open(snd_pcm_substream_t *substream, atiixp_dma_t *dma, int pcm_type)
+static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
+			       struct atiixp_dma *dma, int pcm_type)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	static unsigned int rates[] = { 8000,  9600, 12000, 16000 };
-	static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+	static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 		.count = ARRAY_SIZE(rates),
 		.list = rates,
 		.mask = 0,
@@ -866,9 +872,12 @@
 	dma->substream = substream;
 	runtime->hw = snd_atiixp_pcm_hw;
 	dma->ac97_pcm_type = pcm_type;
-	if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates)) < 0)
+	if ((err = snd_pcm_hw_constraint_list(runtime, 0,
+					      SNDRV_PCM_HW_PARAM_RATE,
+					      &hw_constraints_rates)) < 0)
 		return err;
-	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+	if ((err = snd_pcm_hw_constraint_integer(runtime,
+						 SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
 		return err;
 	runtime->private_data = dma;
 
@@ -881,9 +890,10 @@
 	return 0;
 }
 
-static int snd_atiixp_pcm_close(snd_pcm_substream_t *substream, atiixp_dma_t *dma)
+static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
+				struct atiixp_dma *dma)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
 	/* disable DMA bits */
 	snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL);
 	spin_lock_irq(&chip->reg_lock);
@@ -896,9 +906,9 @@
 
 /*
  */
-static int snd_atiixp_playback_open(snd_pcm_substream_t *substream)
+static int snd_atiixp_playback_open(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
 	int err;
 
 	down(&chip->open_mutex);
@@ -909,9 +919,9 @@
 	return 0;
 }
 
-static int snd_atiixp_playback_close(snd_pcm_substream_t *substream)
+static int snd_atiixp_playback_close(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
 	int err;
 	down(&chip->open_mutex);
 	err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
@@ -919,21 +929,21 @@
 	return err;
 }
 
-static int snd_atiixp_capture_open(snd_pcm_substream_t *substream)
+static int snd_atiixp_capture_open(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
 	return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_CAPTURE], 1);
 }
 
-static int snd_atiixp_capture_close(snd_pcm_substream_t *substream)
+static int snd_atiixp_capture_close(struct snd_pcm_substream *substream)
 {
-	atiixp_t *chip = snd_pcm_substream_chip(substream);
+	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
 	return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_CAPTURE]);
 }
 
 
 /* AC97 playback */
-static snd_pcm_ops_t snd_atiixp_playback_ops = {
+static struct snd_pcm_ops snd_atiixp_playback_ops = {
 	.open =		snd_atiixp_playback_open,
 	.close =	snd_atiixp_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -945,7 +955,7 @@
 };
 
 /* AC97 capture */
-static snd_pcm_ops_t snd_atiixp_capture_ops = {
+static struct snd_pcm_ops snd_atiixp_capture_ops = {
 	.open =		snd_atiixp_capture_open,
 	.close =	snd_atiixp_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -956,7 +966,7 @@
 	.pointer =	snd_atiixp_pcm_pointer,
 };
 
-static atiixp_dma_ops_t snd_atiixp_playback_dma_ops = {
+static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = {
 	.type = ATI_DMA_PLAYBACK,
 	.llp_offset = ATI_REG_MODEM_OUT_DMA1_LINKPTR,
 	.dt_cur = ATI_REG_MODEM_OUT_DMA1_DT_CUR,
@@ -965,7 +975,7 @@
 	.flush_dma = atiixp_out_flush_dma,
 };
 	
-static atiixp_dma_ops_t snd_atiixp_capture_dma_ops = {
+static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = {
 	.type = ATI_DMA_CAPTURE,
 	.llp_offset = ATI_REG_MODEM_IN_DMA_LINKPTR,
 	.dt_cur = ATI_REG_MODEM_IN_DMA_DT_CUR,
@@ -974,9 +984,9 @@
 	.flush_dma = atiixp_in_flush_dma,
 };
 
-static int __devinit snd_atiixp_pcm_new(atiixp_t *chip)
+static int __devinit snd_atiixp_pcm_new(struct atiixp_modem *chip)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	/* initialize constants */
@@ -995,7 +1005,8 @@
 	chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-					      snd_dma_pci_data(chip->pci), 64*1024, 128*1024);
+					      snd_dma_pci_data(chip->pci),
+					      64*1024, 128*1024);
 
 	return 0;
 }
@@ -1007,7 +1018,7 @@
  */
 static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	atiixp_t *chip = dev_id;
+	struct atiixp_modem *chip = dev_id;
 	unsigned int status;
 
 	status = atiixp_read(chip, ISR);
@@ -1046,13 +1057,13 @@
  * ac97 mixer section
  */
 
-static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock)
+static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
 	int i, err;
 	int codec_count;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_atiixp_ac97_write,
 		.read = snd_atiixp_ac97_read,
 	};
@@ -1102,74 +1113,81 @@
 /*
  * power management
  */
-static int snd_atiixp_suspend(snd_card_t *card, pm_message_t state)
+static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	atiixp_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct atiixp_modem *chip = card->private_data;
 	int i;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	for (i = 0; i < NUM_ATI_PCMDEVS; i++)
-		if (chip->pcmdevs[i])
-			snd_pcm_suspend_all(chip->pcmdevs[i]);
+		snd_pcm_suspend_all(chip->pcmdevs[i]);
 	for (i = 0; i < NUM_ATI_CODECS; i++)
-		if (chip->ac97[i])
-			snd_ac97_suspend(chip->ac97[i]);
+		snd_ac97_suspend(chip->ac97[i]);
 	snd_atiixp_aclink_down(chip);
 	snd_atiixp_chip_stop(chip);
 
-	pci_set_power_state(chip->pci, PCI_D3hot);
-	pci_disable_device(chip->pci);
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int snd_atiixp_resume(snd_card_t *card)
+static int snd_atiixp_resume(struct pci_dev *pci)
 {
-	atiixp_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct atiixp_modem *chip = card->private_data;
 	int i;
 
-	pci_enable_device(chip->pci);
-	pci_set_power_state(chip->pci, PCI_D0);
-	pci_set_master(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
+	pci_set_master(pci);
 
 	snd_atiixp_aclink_reset(chip);
 	snd_atiixp_chip_start(chip);
 
 	for (i = 0; i < NUM_ATI_CODECS; i++)
-		if (chip->ac97[i])
-			snd_ac97_resume(chip->ac97[i]);
+		snd_ac97_resume(chip->ac97[i]);
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
 
+#ifdef CONFIG_PROC_FS
 /*
  * proc interface for register dump
  */
 
-static void snd_atiixp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_atiixp_proc_read(struct snd_info_entry *entry,
+				 struct snd_info_buffer *buffer)
 {
-	atiixp_t *chip = entry->private_data;
+	struct atiixp_modem *chip = entry->private_data;
 	int i;
 
 	for (i = 0; i < 256; i += 4)
 		snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i));
 }
 
-static void __devinit snd_atiixp_proc_init(atiixp_t *chip)
+static void __devinit snd_atiixp_proc_init(struct atiixp_modem *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(chip->card, "atiixp-modem", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, snd_atiixp_proc_read);
 }
-
+#else
+#define snd_atiixp_proc_init(chip)
+#endif
 
 
 /*
  * destructor
  */
 
-static int snd_atiixp_free(atiixp_t *chip)
+static int snd_atiixp_free(struct atiixp_modem *chip)
 {
 	if (chip->irq < 0)
 		goto __hw_end;
@@ -1177,7 +1195,7 @@
 	synchronize_irq(chip->irq);
       __hw_end:
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	if (chip->remap_addr)
 		iounmap(chip->remap_addr);
 	pci_release_regions(chip->pci);
@@ -1186,23 +1204,23 @@
 	return 0;
 }
 
-static int snd_atiixp_dev_free(snd_device_t *device)
+static int snd_atiixp_dev_free(struct snd_device *device)
 {
-	atiixp_t *chip = device->device_data;
+	struct atiixp_modem *chip = device->device_data;
 	return snd_atiixp_free(chip);
 }
 
 /*
  * constructor for chip instance
  */
-static int __devinit snd_atiixp_create(snd_card_t *card,
-				      struct pci_dev *pci,
-				      atiixp_t **r_chip)
+static int __devinit snd_atiixp_create(struct snd_card *card,
+				       struct pci_dev *pci,
+				       struct atiixp_modem **r_chip)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_atiixp_dev_free,
 	};
-	atiixp_t *chip;
+	struct atiixp_modem *chip;
 	int err;
 
 	if ((err = pci_enable_device(pci)) < 0)
@@ -1232,7 +1250,8 @@
 		return -EIO;
 	}
 
-	if (request_irq(pci->irq, snd_atiixp_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
+	if (request_irq(pci->irq, snd_atiixp_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_atiixp_free(chip);
 		return -EBUSY;
@@ -1256,8 +1275,8 @@
 static int __devinit snd_atiixp_probe(struct pci_dev *pci,
 				      const struct pci_device_id *pci_id)
 {
-	snd_card_t *card;
-	atiixp_t *chip;
+	struct snd_card *card;
+	struct atiixp_modem *chip;
 	unsigned char revision;
 	int err;
 
@@ -1271,6 +1290,7 @@
 	strcpy(card->shortname, "ATI IXP Modem");
 	if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
 		goto __error;
+	card->private_data = chip;
 
 	if ((err = snd_atiixp_aclink_reset(chip)) < 0)
 		goto __error;
@@ -1288,8 +1308,6 @@
 	sprintf(card->longname, "%s rev %x at 0x%lx, irq %i",
 		card->shortname, revision, chip->addr, chip->irq);
 
-	snd_card_set_pm_callback(card, snd_atiixp_suspend, snd_atiixp_resume, chip);
-
 	if ((err = snd_card_register(card)) < 0)
 		goto __error;
 
@@ -1312,7 +1330,10 @@
 	.id_table = snd_atiixp_ids,
 	.probe = snd_atiixp_probe,
 	.remove = __devexit_p(snd_atiixp_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = snd_atiixp_suspend,
+	.resume = snd_atiixp_resume,
+#endif
 };
 
 
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index d965609..7d9184f 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/moduleparam.h>
+#include <linux/dma-mapping.h>
 #include <sound/initval.h>
 
 // module parameters (see "Module Parameters")
@@ -118,7 +119,7 @@
 
 // component-destructor
 // (see "Management of Cards and Components")
-static int snd_vortex_dev_free(snd_device_t * device)
+static int snd_vortex_dev_free(struct snd_device *device)
 {
 	vortex_t *vortex = device->device_data;
 
@@ -137,11 +138,11 @@
 // chip-specific constructor
 // (see "Management of Cards and Components")
 static int __devinit
-snd_vortex_create(snd_card_t * card, struct pci_dev *pci, vortex_t ** rchip)
+snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
 {
 	vortex_t *chip;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_vortex_dev_free,
 	};
 
@@ -150,11 +151,10 @@
 	// check PCI availability (DMA).
 	if ((err = pci_enable_device(pci)) < 0)
 		return err;
-	if (!pci_dma_supported(pci, VORTEX_DMA_MASK)) {
+	if (pci_set_dma_mask(pci, DMA_32BIT_MASK)) {
 		printk(KERN_ERR "error to set DMA mask\n");
 		return -ENXIO;
 	}
-	pci_set_dma_mask(pci, VORTEX_DMA_MASK);
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
@@ -233,7 +233,7 @@
 snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
+	struct snd_card *card;
 	vortex_t *chip;
 	int err;
 
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h
index b1197cf..c2ad267 100644
--- a/sound/pci/au88x0/au88x0.h
+++ b/sound/pci/au88x0/au88x0.h
@@ -39,8 +39,6 @@
 #include "au88x0_wt.h"
 #endif
 
-#define	VORTEX_DMA_MASK	0xffffffff
-
 #define	hwread(x,y) readl((x)+((y)>>2))
 #define	hwwrite(x,y,z) writel((z),(x)+((y)>>2))
 
@@ -129,21 +127,21 @@
 	/* Virtual page extender stuff */
 	int nr_periods;
 	int period_bytes;
-	snd_pcm_sgbuf_t *sgbuf;	/* DMA Scatter Gather struct */
+	struct snd_sg_buf *sgbuf;	/* DMA Scatter Gather struct */
 	int period_real;
 	int period_virt;
 
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 } stream_t;
 
 typedef struct snd_vortex vortex_t;
 struct snd_vortex {
 	/* ALSA structs. */
-	snd_card_t *card;
-	snd_pcm_t *pcm[VORTEX_PCM_LAST];
+	struct snd_card *card;
+	struct snd_pcm *pcm[VORTEX_PCM_LAST];
 
-	snd_rawmidi_t *rmidi;	/* Legacy Midi interface. */
-	ac97_t *codec;
+	struct snd_rawmidi *rmidi;	/* Legacy Midi interface. */
+	struct snd_ac97 *codec;
 
 	/* Stream structs. */
 	stream_t dma_adb[NR_ADB];
@@ -199,7 +197,7 @@
 
 /* DMA Engines. */
 static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
-				     snd_pcm_sgbuf_t * sgbuf, int size,
+				     struct snd_sg_buf * sgbuf, int size,
 				     int count);
 static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie,
 				  int dir, int fmt, int d,
@@ -207,7 +205,7 @@
 static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb);
 #ifndef CHIP_AU8810
 static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
-				    snd_pcm_sgbuf_t * sgbuf, int size,
+				    struct snd_sg_buf * sgbuf, int size,
 				    int count);
 static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d,	/*int e, */
 				 unsigned long offset);
@@ -231,9 +229,9 @@
 
 /* global stuff. */
 static void vortex_codec_init(vortex_t * vortex);
-static void vortex_codec_write(ac97_t * codec, unsigned short addr,
+static void vortex_codec_write(struct snd_ac97 * codec, unsigned short addr,
 			       unsigned short data);
-static unsigned short vortex_codec_read(ac97_t * codec, unsigned short addr);
+static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short addr);
 static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode);
 
 static int vortex_core_init(vortex_t * card);
diff --git a/sound/pci/au88x0/au88x0_a3d.c b/sound/pci/au88x0/au88x0_a3d.c
index d5755db..d215f39 100644
--- a/sound/pci/au88x0/au88x0_a3d.c
+++ b/sound/pci/au88x0/au88x0_a3d.c
@@ -725,7 +725,7 @@
 /* ALSA control interface.  */
 
 static int
-snd_vortex_a3d_hrtf_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_vortex_a3d_hrtf_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 6;
@@ -734,7 +734,7 @@
 	return 0;
 }
 static int
-snd_vortex_a3d_itd_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_vortex_a3d_itd_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -743,7 +743,7 @@
 	return 0;
 }
 static int
-snd_vortex_a3d_ild_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_vortex_a3d_ild_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -752,8 +752,8 @@
 	return 0;
 }
 static int
-snd_vortex_a3d_filter_info(snd_kcontrol_t *
-			   kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_vortex_a3d_filter_info(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 4;
@@ -763,7 +763,7 @@
 }
 
 static int
-snd_vortex_a3d_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_vortex_a3d_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	//a3dsrc_t *a = kcontrol->private_data;
 	/* No read yet. Would this be really useable/needed ? */
@@ -772,8 +772,8 @@
 }
 
 static int
-snd_vortex_a3d_hrtf_put(snd_kcontrol_t *
-			kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_vortex_a3d_hrtf_put(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
 {
 	a3dsrc_t *a = kcontrol->private_data;
 	int changed = 1, i;
@@ -789,8 +789,8 @@
 }
 
 static int
-snd_vortex_a3d_itd_put(snd_kcontrol_t *
-		       kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_vortex_a3d_itd_put(struct snd_kcontrol *kcontrol,
+		       struct snd_ctl_elem_value *ucontrol)
 {
 	a3dsrc_t *a = kcontrol->private_data;
 	int coord[6];
@@ -808,8 +808,8 @@
 }
 
 static int
-snd_vortex_a3d_ild_put(snd_kcontrol_t *
-		       kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_vortex_a3d_ild_put(struct snd_kcontrol *kcontrol,
+		       struct snd_ctl_elem_value *ucontrol)
 {
 	a3dsrc_t *a = kcontrol->private_data;
 	int changed = 1;
@@ -825,8 +825,8 @@
 }
 
 static int
-snd_vortex_a3d_filter_put(snd_kcontrol_t
-			  * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_vortex_a3d_filter_put(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_value *ucontrol)
 {
 	a3dsrc_t *a = kcontrol->private_data;
 	int i, changed = 1;
@@ -845,7 +845,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t vortex_a3d_kcontrol __devinitdata = {
+static struct snd_kcontrol_new vortex_a3d_kcontrol __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.name = "Playback PCM advanced processing",
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
@@ -857,7 +857,7 @@
 /* Control (un)registration. */
 static int vortex_a3d_register_controls(vortex_t * vortex)
 {
-	snd_kcontrol_t *kcontrol;
+	struct snd_kcontrol *kcontrol;
 	int err, i;
 	/* HRTF controls. */
 	for (i = 0; i < NR_A3D; i++) {
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
index 5905188..e3394fe 100644
--- a/sound/pci/au88x0/au88x0_core.c
+++ b/sound/pci/au88x0/au88x0_core.c
@@ -1097,7 +1097,7 @@
 
 static void
 vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
-			 snd_pcm_sgbuf_t * sgbuf, int psize, int count)
+			 struct snd_sg_buf * sgbuf, int psize, int count)
 {
 	stream_t *dma = &vortex->dma_adb[adbdma];
 
@@ -1367,7 +1367,7 @@
 
 static void
 vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
-			snd_pcm_sgbuf_t * sgbuf, int psize, int count)
+			struct snd_sg_buf * sgbuf, int psize, int count)
 {
 	stream_t *dma = &vortex->dma_wt[wtdma];
 
@@ -2514,7 +2514,7 @@
 }
 
 static void
-vortex_codec_write(ac97_t * codec, unsigned short addr, unsigned short data)
+vortex_codec_write(struct snd_ac97 * codec, unsigned short addr, unsigned short data)
 {
 
 	vortex_t *card = (vortex_t *) codec->private_data;
@@ -2539,7 +2539,7 @@
 	hwread(card->mmio, VORTEX_CODEC_IO);
 }
 
-static unsigned short vortex_codec_read(ac97_t * codec, unsigned short addr)
+static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short addr)
 {
 
 	vortex_t *card = (vortex_t *) codec->private_data;
diff --git a/sound/pci/au88x0/au88x0_eq.c b/sound/pci/au88x0/au88x0_eq.c
index 9d933cc..13bc8ed 100644
--- a/sound/pci/au88x0/au88x0_eq.c
+++ b/sound/pci/au88x0/au88x0_eq.c
@@ -730,7 +730,7 @@
 
 /* Control interface */
 static int
-snd_vortex_eqtoggle_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_vortex_eqtoggle_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -740,8 +740,8 @@
 }
 
 static int
-snd_vortex_eqtoggle_get(snd_kcontrol_t * kcontrol,
-			snd_ctl_elem_value_t * ucontrol)
+snd_vortex_eqtoggle_get(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
 {
 	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
 	eqlzr_t *eq = &(vortex->eq);
@@ -753,8 +753,8 @@
 }
 
 static int
-snd_vortex_eqtoggle_put(snd_kcontrol_t * kcontrol,
-			snd_ctl_elem_value_t * ucontrol)
+snd_vortex_eqtoggle_put(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
 {
 	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
 	eqlzr_t *eq = &(vortex->eq);
@@ -766,7 +766,7 @@
 	return 1;		/* Allways changes */
 }
 
-static snd_kcontrol_new_t vortex_eqtoggle_kcontrol __devinitdata = {
+static struct snd_kcontrol_new vortex_eqtoggle_kcontrol __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "EQ Enable",
 	.index = 0,
@@ -778,7 +778,7 @@
 };
 
 static int
-snd_vortex_eq_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_vortex_eq_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -788,7 +788,7 @@
 }
 
 static int
-snd_vortex_eq_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_vortex_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
 	int i = kcontrol->private_value;
@@ -802,7 +802,7 @@
 }
 
 static int
-snd_vortex_eq_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_vortex_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
 	int changed = 0, i = kcontrol->private_value;
@@ -824,7 +824,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t vortex_eq_kcontrol __devinitdata = {
+static struct snd_kcontrol_new vortex_eq_kcontrol __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "                        .",
 	.index = 0,
@@ -836,7 +836,7 @@
 };
 
 static int
-snd_vortex_peaks_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_vortex_peaks_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 20;
@@ -846,7 +846,7 @@
 }
 
 static int
-snd_vortex_peaks_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_vortex_peaks_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
 	int i, count;
@@ -863,7 +863,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vortex_levels_kcontrol __devinitdata = {
+static struct snd_kcontrol_new vortex_levels_kcontrol __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "EQ Peaks",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -888,7 +888,7 @@
 /* ALSA driver entry points. Init and exit. */
 static int vortex_eq_init(vortex_t * vortex)
 {
-	snd_kcontrol_t *kcontrol;
+	struct snd_kcontrol *kcontrol;
 	int err, i;
 
 	vortex_Eqlzr_init(vortex);
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
index 86e27d69..c96da1d 100644
--- a/sound/pci/au88x0/au88x0_mixer.c
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -13,10 +13,10 @@
 
 static int __devinit snd_vortex_mixer(vortex_t * vortex)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = vortex_codec_write,
 		.read = vortex_codec_read,
 	};
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c
index c0c2346..8ba6dd3 100644
--- a/sound/pci/au88x0/au88x0_mpu401.c
+++ b/sound/pci/au88x0/au88x0_mpu401.c
@@ -44,9 +44,9 @@
 
 static int __devinit snd_vortex_midi(vortex_t * vortex)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int temp, mode;
-	mpu401_t *mpu;
+	struct snd_mpu401 *mpu;
 	int port;
 
 #ifdef VORTEX_MPU401_LEGACY
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index 38bd2b5d..6a13ca1 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -31,7 +31,7 @@
 #define VORTEX_PCM_TYPE(x) (x->name[40])
 
 /* hardware definition */
-static snd_pcm_hardware_t snd_vortex_playback_hw_adb = {
+static struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
 	.info =
 	    (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
 	     SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
@@ -56,7 +56,7 @@
 };
 
 #ifndef CHIP_AU8820
-static snd_pcm_hardware_t snd_vortex_playback_hw_a3d = {
+static struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
 	.info =
 	    (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
 	     SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
@@ -76,7 +76,7 @@
 	.periods_max = 64,
 };
 #endif
-static snd_pcm_hardware_t snd_vortex_playback_hw_spdif = {
+static struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
 	.info =
 	    (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
 	     SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
@@ -99,7 +99,7 @@
 };
 
 #ifndef CHIP_AU8810
-static snd_pcm_hardware_t snd_vortex_playback_hw_wt = {
+static struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
 	.info = (SNDRV_PCM_INFO_MMAP |
 		 SNDRV_PCM_INFO_INTERLEAVED |
 		 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
@@ -117,10 +117,10 @@
 };
 #endif
 /* open callback */
-static int snd_vortex_pcm_open(snd_pcm_substream_t * substream)
+static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
 {
 	vortex_t *vortex = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	
 	/* Force equal size periods */
@@ -169,7 +169,7 @@
 }
 
 /* close callback */
-static int snd_vortex_pcm_close(snd_pcm_substream_t * substream)
+static int snd_vortex_pcm_close(struct snd_pcm_substream *substream)
 {
 	//vortex_t *chip = snd_pcm_substream_chip(substream);
 	stream_t *stream = (stream_t *) substream->runtime->private_data;
@@ -185,12 +185,12 @@
 
 /* hw_params callback */
 static int
-snd_vortex_pcm_hw_params(snd_pcm_substream_t * substream,
-			 snd_pcm_hw_params_t * hw_params)
+snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
+			 struct snd_pcm_hw_params *hw_params)
 {
 	vortex_t *chip = snd_pcm_substream_chip(substream);
 	stream_t *stream = (stream_t *) (substream->runtime->private_data);
-	snd_pcm_sgbuf_t *sgbuf;
+	struct snd_sg_buf *sgbuf;
 	int err;
 
 	// Alloc buffer memory.
@@ -200,7 +200,7 @@
 		printk(KERN_ERR "Vortex: pcm page alloc failed!\n");
 		return err;
 	}
-	//sgbuf = (snd_pcm_sgbuf_t *) substream->runtime->dma_private;
+	//sgbuf = (struct snd_sg_buf *) substream->runtime->dma_private;
 	sgbuf = snd_pcm_substream_sgbuf(substream);
 	/*
 	   printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
@@ -251,7 +251,7 @@
 }
 
 /* hw_free callback */
-static int snd_vortex_pcm_hw_free(snd_pcm_substream_t * substream)
+static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
 {
 	vortex_t *chip = snd_pcm_substream_chip(substream);
 	stream_t *stream = (stream_t *) (substream->runtime->private_data);
@@ -277,10 +277,10 @@
 }
 
 /* prepare callback */
-static int snd_vortex_pcm_prepare(snd_pcm_substream_t * substream)
+static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream)
 {
 	vortex_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	stream_t *stream = (stream_t *) substream->runtime->private_data;
 	int dma = stream->dma, fmt, dir;
 
@@ -310,7 +310,7 @@
 }
 
 /* trigger callback */
-static int snd_vortex_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	vortex_t *chip = snd_pcm_substream_chip(substream);
 	stream_t *stream = (stream_t *) substream->runtime->private_data;
@@ -374,7 +374,7 @@
 }
 
 /* pointer callback */
-static snd_pcm_uframes_t snd_vortex_pcm_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substream)
 {
 	vortex_t *chip = snd_pcm_substream_chip(substream);
 	stream_t *stream = (stream_t *) substream->runtime->private_data;
@@ -395,13 +395,13 @@
 
 /* Page callback. */
 /*
-static struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset) {
+static struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset) {
 	
 	
 }
 */
 /* operators */
-static snd_pcm_ops_t snd_vortex_playback_ops = {
+static struct snd_pcm_ops snd_vortex_playback_ops = {
 	.open = snd_vortex_pcm_open,
 	.close = snd_vortex_pcm_close,
 	.ioctl = snd_pcm_lib_ioctl,
@@ -434,14 +434,14 @@
 
 /* SPDIF kcontrol */
 
-static int snd_vortex_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_vortex_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_vortex_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vortex_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = 0xff;
 	ucontrol->value.iec958.status[1] = 0xff;
@@ -450,7 +450,7 @@
 	return 0;
 }
 
-static int snd_vortex_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vortex_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.iec958.status[0] = 0x00;
@@ -464,7 +464,7 @@
 	return 0;
 }
 
-static int snd_vortex_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vortex_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
 	int spdif_sr = 48000;
@@ -481,7 +481,7 @@
 }
 
 /* spdif controls */
-static snd_kcontrol_new_t snd_vortex_mixer_spdif[] __devinitdata = {
+static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = {
 	{
 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 		.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -501,8 +501,8 @@
 /* create a pcm device */
 static int __devinit snd_vortex_new_pcm(vortex_t * chip, int idx, int nr)
 {
-	snd_pcm_t *pcm;
-	snd_kcontrol_t *kctl;
+	struct snd_pcm *pcm;
+	struct snd_kcontrol *kctl;
 	int i;
 	int err, nr_capt;
 
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index ab737d6..e077eb3 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -186,7 +186,7 @@
 module_param(seqtimer_scaling, int, 0444);
 MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
 
-typedef struct _snd_azf3328 {
+struct snd_azf3328 {
 	/* often-used fields towards beginning, then grouped */
 	unsigned long codec_port;
 	unsigned long io2_port;
@@ -196,16 +196,16 @@
 
 	spinlock_t reg_lock;
 
-	snd_timer_t *timer;
+	struct snd_timer *timer;
 	
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
 	unsigned int is_playing;
 	unsigned int is_recording;
 
-	snd_card_t *card;
-	snd_rawmidi_t *rmidi;
+	struct snd_card *card;
+	struct snd_rawmidi *rmidi;
 
 #ifdef SUPPORT_JOYSTICK
 	struct gameport *gameport;
@@ -213,7 +213,7 @@
 
 	struct pci_dev *pci;
 	int irq;
-} azf3328_t;
+};
 
 static const struct pci_device_id snd_azf3328_ids[] = {
 	{ 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },   /* PCI168/3328 */
@@ -224,61 +224,61 @@
 MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
 
 static inline void
-snd_azf3328_codec_outb(const azf3328_t *chip, int reg, u8 value)
+snd_azf3328_codec_outb(const struct snd_azf3328 *chip, int reg, u8 value)
 {
 	outb(value, chip->codec_port + reg);
 }
 
 static inline u8
-snd_azf3328_codec_inb(const azf3328_t *chip, int reg)
+snd_azf3328_codec_inb(const struct snd_azf3328 *chip, int reg)
 {
 	return inb(chip->codec_port + reg);
 }
 
 static inline void
-snd_azf3328_codec_outw(const azf3328_t *chip, int reg, u16 value)
+snd_azf3328_codec_outw(const struct snd_azf3328 *chip, int reg, u16 value)
 {
 	outw(value, chip->codec_port + reg);
 }
 
 static inline u16
-snd_azf3328_codec_inw(const azf3328_t *chip, int reg)
+snd_azf3328_codec_inw(const struct snd_azf3328 *chip, int reg)
 {
 	return inw(chip->codec_port + reg);
 }
 
 static inline void
-snd_azf3328_codec_outl(const azf3328_t *chip, int reg, u32 value)
+snd_azf3328_codec_outl(const struct snd_azf3328 *chip, int reg, u32 value)
 {
 	outl(value, chip->codec_port + reg);
 }
 
 static inline void
-snd_azf3328_io2_outb(const azf3328_t *chip, int reg, u8 value)
+snd_azf3328_io2_outb(const struct snd_azf3328 *chip, int reg, u8 value)
 {
 	outb(value, chip->io2_port + reg);
 }
 
 static inline u8
-snd_azf3328_io2_inb(const azf3328_t *chip, int reg)
+snd_azf3328_io2_inb(const struct snd_azf3328 *chip, int reg)
 {
 	return inb(chip->io2_port + reg);
 }
 
 static inline void
-snd_azf3328_mixer_outw(const azf3328_t *chip, int reg, u16 value)
+snd_azf3328_mixer_outw(const struct snd_azf3328 *chip, int reg, u16 value)
 {
 	outw(value, chip->mixer_port + reg);
 }
 
 static inline u16
-snd_azf3328_mixer_inw(const azf3328_t *chip, int reg)
+snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, int reg)
 {
 	return inw(chip->mixer_port + reg);
 }
 
 static void
-snd_azf3328_mixer_set_mute(const azf3328_t *chip, int reg, int do_mute)
+snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, int reg, int do_mute)
 {
 	unsigned long portbase = chip->mixer_port + reg + 1;
 	unsigned char oldval;
@@ -294,7 +294,7 @@
 }
 
 static void
-snd_azf3328_mixer_write_volume_gradually(const azf3328_t *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
+snd_azf3328_mixer_write_volume_gradually(const struct snd_azf3328 *chip, int reg, unsigned char dst_vol_left, unsigned char dst_vol_right, int chan_sel, int delay)
 {
 	unsigned long portbase = chip->mixer_port + reg;
 	unsigned char curr_vol_left = 0, curr_vol_right = 0;
@@ -353,14 +353,14 @@
 /*
  * general mixer element
  */
-typedef struct azf3328_mixer_reg {
+struct azf3328_mixer_reg {
 	unsigned int reg;
 	unsigned int lchan_shift, rchan_shift;
 	unsigned int mask;
 	unsigned int invert: 1;
 	unsigned int stereo: 1;
 	unsigned int enum_c: 4;
-} azf3328_mixer_reg_t;
+};
 
 #define COMPOSE_MIXER_REG(reg,lchan_shift,rchan_shift,mask,invert,stereo,enum_c) \
  ((reg) | (lchan_shift << 8) | (rchan_shift << 12) | \
@@ -369,7 +369,7 @@
   (stereo << 25) | \
   (enum_c << 26))
 
-static void snd_azf3328_mixer_reg_decode(azf3328_mixer_reg_t *r, unsigned long val)
+static void snd_azf3328_mixer_reg_decode(struct azf3328_mixer_reg *r, unsigned long val)
 {
 	r->reg = val & 0xff;
 	r->lchan_shift = (val >> 8) & 0x0f;
@@ -420,9 +420,10 @@
 }
 
 static int
-snd_azf3328_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+snd_azf3328_info_mixer(struct snd_kcontrol *kcontrol,
+		       struct snd_ctl_elem_info *uinfo)
 {
-	azf3328_mixer_reg_t reg;
+	struct azf3328_mixer_reg reg;
 
 	snd_azf3328_dbgcallenter();
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
@@ -436,10 +437,11 @@
 }
 
 static int
-snd_azf3328_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_azf3328_get_mixer(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol)
 {
-	azf3328_t *chip = snd_kcontrol_chip(kcontrol);
-	azf3328_mixer_reg_t reg;
+	struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
+	struct azf3328_mixer_reg reg;
 	unsigned int oreg, val;
 
 	snd_azf3328_dbgcallenter();
@@ -466,10 +468,11 @@
 }
 
 static int
-snd_azf3328_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_azf3328_put_mixer(struct snd_kcontrol *kcontrol,
+		      struct snd_ctl_elem_value *ucontrol)
 {
-	azf3328_t *chip = snd_kcontrol_chip(kcontrol);
-	azf3328_mixer_reg_t reg;
+	struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
+	struct azf3328_mixer_reg reg;
 	unsigned int oreg, nreg, val;
 
 	snd_azf3328_dbgcallenter();
@@ -506,7 +509,8 @@
 }
 
 static int
-snd_azf3328_info_mixer_enum(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_azf3328_info_mixer_enum(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_info *uinfo)
 {
 	static const char * const texts1[] = {
 		"ModemOut1", "ModemOut2"
@@ -518,7 +522,7 @@
                 "Mic", "CD", "Video", "Aux",
 		"Line", "Mix", "Mix Mono", "Phone"
         };
-	azf3328_mixer_reg_t reg;
+	struct azf3328_mixer_reg reg;
 
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -540,10 +544,11 @@
 }
 
 static int
-snd_azf3328_get_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_azf3328_get_mixer_enum(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
 {
-        azf3328_t *chip = snd_kcontrol_chip(kcontrol);
-	azf3328_mixer_reg_t reg;
+        struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
+	struct azf3328_mixer_reg reg;
         unsigned short val;
         
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
@@ -563,10 +568,11 @@
 }
 
 static int
-snd_azf3328_put_mixer_enum(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
 {
-        azf3328_t *chip = snd_kcontrol_chip(kcontrol);
-	azf3328_mixer_reg_t reg;
+        struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
+	struct azf3328_mixer_reg reg;
 	unsigned int oreg, nreg, val;
         
 	snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
@@ -594,7 +600,7 @@
 	return (nreg != oreg);
 }
 
-static const snd_kcontrol_new_t snd_azf3328_mixer_controls[] __devinitdata = {
+static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = {
 	AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1),
 	AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1),
 	AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1),
@@ -666,10 +672,10 @@
 };
 
 static int __devinit
-snd_azf3328_mixer_new(azf3328_t *chip)
+snd_azf3328_mixer_new(struct snd_azf3328 *chip)
 {
-	snd_card_t *card;
-	const snd_kcontrol_new_t *sw;
+	struct snd_card *card;
+	const struct snd_kcontrol_new *sw;
 	unsigned int idx;
 	int err;
 
@@ -702,8 +708,8 @@
 }
 
 static int
-snd_azf3328_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+snd_azf3328_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
 	int res;
 	snd_azf3328_dbgcallenter();
@@ -713,7 +719,7 @@
 }
 
 static int
-snd_azf3328_hw_free(snd_pcm_substream_t * substream)
+snd_azf3328_hw_free(struct snd_pcm_substream *substream)
 {
 	snd_azf3328_dbgcallenter();
 	snd_pcm_lib_free_pages(substream);
@@ -722,7 +728,7 @@
 }
 
 static void
-snd_azf3328_setfmt(azf3328_t *chip,
+snd_azf3328_setfmt(struct snd_azf3328 *chip,
 			       unsigned int reg,
 			       unsigned int bitrate,
 			       unsigned int format_width,
@@ -796,7 +802,7 @@
 }
 
 static void
-snd_azf3328_setdmaa(azf3328_t *chip,
+snd_azf3328_setdmaa(struct snd_azf3328 *chip,
 				long unsigned int addr,
                                 unsigned int count,
                                 unsigned int size,
@@ -842,11 +848,11 @@
 }
 
 static int
-snd_azf3328_playback_prepare(snd_pcm_substream_t *substream)
+snd_azf3328_playback_prepare(struct snd_pcm_substream *substream)
 {
 #if 0
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
         unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
 #endif
@@ -864,11 +870,11 @@
 }
 
 static int
-snd_azf3328_capture_prepare(snd_pcm_substream_t * substream)
+snd_azf3328_capture_prepare(struct snd_pcm_substream *substream)
 {
 #if 0
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
         unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
 #endif
@@ -886,10 +892,10 @@
 }
 
 static int
-snd_azf3328_playback_trigger(snd_pcm_substream_t * substream, int cmd)
+snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int result = 0;
 	unsigned int status1;
 
@@ -998,10 +1004,10 @@
 /* this is just analogous to playback; I'm not quite sure whether recording
  * should actually be triggered like that */
 static int
-snd_azf3328_capture_trigger(snd_pcm_substream_t * substream, int cmd)
+snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int result = 0;
 	unsigned int status1;
 
@@ -1096,9 +1102,9 @@
 }
 
 static snd_pcm_uframes_t
-snd_azf3328_playback_pointer(snd_pcm_substream_t * substream)
+snd_azf3328_playback_pointer(struct snd_pcm_substream *substream)
 {
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
 	unsigned long bufptr, result;
 	snd_pcm_uframes_t frmres;
 
@@ -1117,9 +1123,9 @@
 }
 
 static snd_pcm_uframes_t
-snd_azf3328_capture_pointer(snd_pcm_substream_t * substream)
+snd_azf3328_capture_pointer(struct snd_pcm_substream *substream)
 {
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
 	unsigned long bufptr, result;
 	snd_pcm_uframes_t frmres;
 
@@ -1140,7 +1146,7 @@
 static irqreturn_t
 snd_azf3328_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	azf3328_t *chip = dev_id;
+	struct snd_azf3328 *chip = dev_id;
 	u8 status, which;
 	static unsigned long irq_count;
 
@@ -1223,7 +1229,7 @@
 
 /*****************************************************************/
 
-static const snd_pcm_hardware_t snd_azf3328_playback =
+static const struct snd_pcm_hardware snd_azf3328_playback =
 {
 	/* FIXME!! Correct? */
 	.info =			SNDRV_PCM_INFO_MMAP |
@@ -1251,7 +1257,7 @@
 	.fifo_size =		0,
 };
 
-static const snd_pcm_hardware_t snd_azf3328_capture =
+static const struct snd_pcm_hardware snd_azf3328_capture =
 {
 	/* FIXME */
 	.info =			SNDRV_PCM_INFO_MMAP |
@@ -1280,7 +1286,7 @@
 static unsigned int snd_azf3328_fixed_rates[] = {
 	4000, 4800, 5512, 6620, 8000, 9600, 11025, 13240, 16000, 22050, 32000,
 	44100, 48000, 66200 };
-static snd_pcm_hw_constraint_list_t snd_azf3328_hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
 	.count = ARRAY_SIZE(snd_azf3328_fixed_rates), 
 	.list = snd_azf3328_fixed_rates,
 	.mask = 0,
@@ -1289,10 +1295,10 @@
 /*****************************************************************/
 
 static int
-snd_azf3328_playback_open(snd_pcm_substream_t * substream)
+snd_azf3328_playback_open(struct snd_pcm_substream *substream)
 {
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_azf3328_dbgcallenter();
 	chip->playback_substream = substream;
@@ -1304,10 +1310,10 @@
 }
 
 static int
-snd_azf3328_capture_open(snd_pcm_substream_t * substream)
+snd_azf3328_capture_open(struct snd_pcm_substream *substream)
 {
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_azf3328_dbgcallenter();
 	chip->capture_substream = substream;
@@ -1319,9 +1325,9 @@
 }
 
 static int
-snd_azf3328_playback_close(snd_pcm_substream_t * substream)
+snd_azf3328_playback_close(struct snd_pcm_substream *substream)
 {
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
 
 	snd_azf3328_dbgcallenter();
 
@@ -1331,9 +1337,9 @@
 }
 
 static int
-snd_azf3328_capture_close(snd_pcm_substream_t * substream)
+snd_azf3328_capture_close(struct snd_pcm_substream *substream)
 {
-	azf3328_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
 
 	snd_azf3328_dbgcallenter();
 	chip->capture_substream = NULL;
@@ -1343,7 +1349,7 @@
 
 /******************************************************************/
 
-static snd_pcm_ops_t snd_azf3328_playback_ops = {
+static struct snd_pcm_ops snd_azf3328_playback_ops = {
 	.open =		snd_azf3328_playback_open,
 	.close =	snd_azf3328_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1354,7 +1360,7 @@
 	.pointer =	snd_azf3328_playback_pointer
 };
 
-static snd_pcm_ops_t snd_azf3328_capture_ops = {
+static struct snd_pcm_ops snd_azf3328_capture_ops = {
 	.open =		snd_azf3328_capture_open,
 	.close =	snd_azf3328_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1365,18 +1371,10 @@
 	.pointer =	snd_azf3328_capture_pointer
 };
 
-static void
-snd_azf3328_pcm_free(snd_pcm_t *pcm)
-{
-	azf3328_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
 static int __devinit
-snd_azf3328_pcm(azf3328_t *chip, int device)
+snd_azf3328_pcm(struct snd_azf3328 *chip, int device)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	snd_azf3328_dbgcallenter();
@@ -1386,7 +1384,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_azf3328_capture_ops);
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_azf3328_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcm = pcm;
@@ -1402,7 +1399,7 @@
 
 #ifdef SUPPORT_JOYSTICK
 static int __devinit
-snd_azf3328_config_joystick(azf3328_t *chip, int dev)
+snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev)
 {
 	struct gameport *gp;
 	struct resource *r;
@@ -1437,7 +1434,7 @@
 }
 
 static void
-snd_azf3328_free_joystick(azf3328_t *chip)
+snd_azf3328_free_joystick(struct snd_azf3328 *chip)
 {
 	if (chip->gameport) {
 		struct resource *r = gameport_get_port_data(chip->gameport);
@@ -1452,15 +1449,15 @@
 }
 #else
 static inline int
-snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; }
+snd_azf3328_config_joystick(struct snd_azf3328 *chip, int dev) { return -ENOSYS; }
 static inline void
-snd_azf3328_free_joystick(azf3328_t *chip) { }
+snd_azf3328_free_joystick(struct snd_azf3328 *chip) { }
 #endif
 
 /******************************************************************/
 
 static int
-snd_azf3328_free(azf3328_t *chip)
+snd_azf3328_free(struct snd_azf3328 *chip)
 {
         if (chip->irq < 0)
                 goto __end_hw;
@@ -1486,9 +1483,9 @@
 }
 
 static int
-snd_azf3328_dev_free(snd_device_t *device)
+snd_azf3328_dev_free(struct snd_device *device)
 {
-	azf3328_t *chip = device->device_data;
+	struct snd_azf3328 *chip = device->device_data;
 	return snd_azf3328_free(chip);
 }
 
@@ -1504,9 +1501,9 @@
  ***/
 
 static int
-snd_azf3328_timer_start(snd_timer_t *timer)
+snd_azf3328_timer_start(struct snd_timer *timer)
 {
-	azf3328_t *chip;
+	struct snd_azf3328 *chip;
 	unsigned long flags;
 	unsigned int delay;
 
@@ -1532,9 +1529,9 @@
 }
 
 static int
-snd_azf3328_timer_stop(snd_timer_t *timer)
+snd_azf3328_timer_stop(struct snd_timer *timer)
 {
-	azf3328_t *chip;
+	struct snd_azf3328 *chip;
 	unsigned long flags;
 
 	snd_azf3328_dbgcallenter();
@@ -1550,7 +1547,7 @@
 
 
 static int
-snd_azf3328_timer_precise_resolution(snd_timer_t *timer,
+snd_azf3328_timer_precise_resolution(struct snd_timer *timer,
 					       unsigned long *num, unsigned long *den)
 {
 	snd_azf3328_dbgcallenter();
@@ -1560,7 +1557,7 @@
 	return 0;
 }
 
-static struct _snd_timer_hardware snd_azf3328_timer_hw = {
+static struct snd_timer_hardware snd_azf3328_timer_hw = {
 	.flags = SNDRV_TIMER_HW_AUTO,
 	.resolution = 977, /* 1000000/1024000 = 0.9765625us */
 	.ticks = 1024000, /* max tick count, defined by the value register; actually it's not 1024000, but 1048576, but we don't care */
@@ -1570,10 +1567,10 @@
 };
 
 static int __devinit
-snd_azf3328_timer(azf3328_t *chip, int device)
+snd_azf3328_timer(struct snd_azf3328 *chip, int device)
 {
-	snd_timer_t *timer = NULL;
-	snd_timer_id_t tid;
+	struct snd_timer *timer = NULL;
+	struct snd_timer_id tid;
 	int err;
 
 	snd_azf3328_dbgcallenter();
@@ -1626,7 +1623,7 @@
 #endif
 
 static void
-snd_azf3328_debug_show_ports(const azf3328_t *chip)
+snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
 {
 #if DEBUG_MISC
 	u16 tmp;
@@ -1644,14 +1641,14 @@
 }
 
 static int __devinit
-snd_azf3328_create(snd_card_t * card,
+snd_azf3328_create(struct snd_card *card,
                                          struct pci_dev *pci,
                                          unsigned long device_type,
-                                         azf3328_t ** rchip)
+                                         struct snd_azf3328 ** rchip)
 {
-	azf3328_t *chip;
+	struct snd_azf3328 *chip;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =     snd_azf3328_dev_free,
 	};
 	u16 tmp;
@@ -1744,9 +1741,9 @@
 snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	azf3328_t *chip;
-	opl3_t *opl3;
+	struct snd_card *card;
+	struct snd_azf3328 *chip;
+	struct snd_opl3 *opl3;
 	int err;
 
 	snd_azf3328_dbgcallenter();
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 8feca22..dc9cd30 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -147,9 +147,8 @@
 /* SYNC, one WRITE per line, one extra WRITE per page boundary, SYNC, JUMP */
 #define MAX_RISC_SIZE ((1 + 255 + (PAGE_ALIGN(255 * 4092) / PAGE_SIZE - 1) + 1 + 1) * 8)
 
-typedef struct snd_bt87x bt87x_t;
 struct snd_bt87x {
-	snd_card_t *card;
+	struct snd_card *card;
 	struct pci_dev *pci;
 
 	void __iomem *mmio;
@@ -159,7 +158,7 @@
 
 	spinlock_t reg_lock;
 	long opened;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 
 	struct snd_dma_buffer dma_risc;
 	unsigned int line_bytes;
@@ -175,17 +174,17 @@
 
 enum { DEVICE_DIGITAL, DEVICE_ANALOG };
 
-static inline u32 snd_bt87x_readl(bt87x_t *chip, u32 reg)
+static inline u32 snd_bt87x_readl(struct snd_bt87x *chip, u32 reg)
 {
 	return readl(chip->mmio + reg);
 }
 
-static inline void snd_bt87x_writel(bt87x_t *chip, u32 reg, u32 value)
+static inline void snd_bt87x_writel(struct snd_bt87x *chip, u32 reg, u32 value)
 {
 	writel(value, chip->mmio + reg);
 }
 
-static int snd_bt87x_create_risc(bt87x_t *chip, snd_pcm_substream_t *substream,
+static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substream *substream,
 			       	 unsigned int periods, unsigned int period_bytes)
 {
 	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
@@ -235,7 +234,7 @@
 	return 0;
 }
 
-static void snd_bt87x_free_risc(bt87x_t *chip)
+static void snd_bt87x_free_risc(struct snd_bt87x *chip)
 {
 	if (chip->dma_risc.area) {
 		snd_dma_free_pages(&chip->dma_risc);
@@ -243,7 +242,7 @@
 	}
 }
 
-static void snd_bt87x_pci_error(bt87x_t *chip, unsigned int status)
+static void snd_bt87x_pci_error(struct snd_bt87x *chip, unsigned int status)
 {
 	u16 pci_status;
 
@@ -272,7 +271,7 @@
 
 static irqreturn_t snd_bt87x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	bt87x_t *chip = dev_id;
+	struct snd_bt87x *chip = dev_id;
 	unsigned int status, irq_status;
 
 	status = snd_bt87x_readl(chip, REG_INT_STAT);
@@ -305,7 +304,7 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_hardware_t snd_bt87x_digital_hw = {
+static struct snd_pcm_hardware snd_bt87x_digital_hw = {
 	.info = SNDRV_PCM_INFO_MMAP |
 		SNDRV_PCM_INFO_INTERLEAVED |
 		SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -321,7 +320,7 @@
 	.periods_max = 255,
 };
 
-static snd_pcm_hardware_t snd_bt87x_analog_hw = {
+static struct snd_pcm_hardware snd_bt87x_analog_hw = {
 	.info = SNDRV_PCM_INFO_MMAP |
 		SNDRV_PCM_INFO_INTERLEAVED |
 		SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -339,7 +338,7 @@
 	.periods_max = 255,
 };
 
-static int snd_bt87x_set_digital_hw(bt87x_t *chip, snd_pcm_runtime_t *runtime)
+static int snd_bt87x_set_digital_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime)
 {
 	static struct {
 		int rate;
@@ -368,15 +367,15 @@
 	return 0;
 }
 
-static int snd_bt87x_set_analog_hw(bt87x_t *chip, snd_pcm_runtime_t *runtime)
+static int snd_bt87x_set_analog_hw(struct snd_bt87x *chip, struct snd_pcm_runtime *runtime)
 {
-	static ratnum_t analog_clock = {
+	static struct snd_ratnum analog_clock = {
 		.num = ANALOG_CLOCK,
 		.den_min = CLOCK_DIV_MIN,
 		.den_max = CLOCK_DIV_MAX,
 		.den_step = 1
 	};
-	static snd_pcm_hw_constraint_ratnums_t constraint_rates = {
+	static struct snd_pcm_hw_constraint_ratnums constraint_rates = {
 		.nrats = 1,
 		.rats = &analog_clock
 	};
@@ -387,10 +386,10 @@
 					     &constraint_rates);
 }
 
-static int snd_bt87x_pcm_open(snd_pcm_substream_t *substream)
+static int snd_bt87x_pcm_open(struct snd_pcm_substream *substream)
 {
-	bt87x_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if (test_and_set_bit(0, &chip->opened))
@@ -416,9 +415,9 @@
 	return err;
 }
 
-static int snd_bt87x_close(snd_pcm_substream_t *substream)
+static int snd_bt87x_close(struct snd_pcm_substream *substream)
 {
-	bt87x_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
 
 	chip->substream = NULL;
 	clear_bit(0, &chip->opened);
@@ -426,10 +425,10 @@
 	return 0;
 }
 
-static int snd_bt87x_hw_params(snd_pcm_substream_t *substream,
-			       snd_pcm_hw_params_t *hw_params)
+static int snd_bt87x_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *hw_params)
 {
-	bt87x_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
 	int err;
 
 	err = snd_pcm_lib_malloc_pages(substream,
@@ -441,19 +440,19 @@
 				     params_period_bytes(hw_params));
 }
 
-static int snd_bt87x_hw_free(snd_pcm_substream_t *substream)
+static int snd_bt87x_hw_free(struct snd_pcm_substream *substream)
 {
-	bt87x_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
 
 	snd_bt87x_free_risc(chip);
 	snd_pcm_lib_free_pages(substream);
 	return 0;
 }
 
-static int snd_bt87x_prepare(snd_pcm_substream_t *substream)
+static int snd_bt87x_prepare(struct snd_pcm_substream *substream)
 {
-	bt87x_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int decimation;
 
 	spin_lock_irq(&chip->reg_lock);
@@ -467,7 +466,7 @@
 	return 0;
 }
 
-static int snd_bt87x_start(bt87x_t *chip)
+static int snd_bt87x_start(struct snd_bt87x *chip)
 {
 	spin_lock(&chip->reg_lock);
 	chip->current_line = 0;
@@ -481,7 +480,7 @@
 	return 0;
 }
 
-static int snd_bt87x_stop(bt87x_t *chip)
+static int snd_bt87x_stop(struct snd_bt87x *chip)
 {
 	spin_lock(&chip->reg_lock);
 	chip->reg_control &= ~(CTL_FIFO_ENABLE | CTL_RISC_ENABLE | CTL_ACAP_EN);
@@ -492,9 +491,9 @@
 	return 0;
 }
 
-static int snd_bt87x_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_bt87x_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	bt87x_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -506,15 +505,15 @@
 	}
 }
 
-static snd_pcm_uframes_t snd_bt87x_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_bt87x_pointer(struct snd_pcm_substream *substream)
 {
-	bt87x_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_bt87x *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	return (snd_pcm_uframes_t)bytes_to_frames(runtime, chip->current_line * chip->line_bytes);
 }
 
-static snd_pcm_ops_t snd_bt87x_pcm_ops = {
+static struct snd_pcm_ops snd_bt87x_pcm_ops = {
 	.open = snd_bt87x_pcm_open,
 	.close = snd_bt87x_close,
 	.ioctl = snd_pcm_lib_ioctl,
@@ -526,7 +525,8 @@
 	.page = snd_pcm_sgbuf_ops_page,
 };
 
-static int snd_bt87x_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
+static int snd_bt87x_capture_volume_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *info)
 {
 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	info->count = 1;
@@ -535,17 +535,19 @@
 	return 0;
 }
 
-static int snd_bt87x_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+static int snd_bt87x_capture_volume_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *value)
 {
-	bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
 
 	value->value.integer.value[0] = (chip->reg_control & CTL_A_GAIN_MASK) >> CTL_A_GAIN_SHIFT;
 	return 0;
 }
 
-static int snd_bt87x_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+static int snd_bt87x_capture_volume_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *value)
 {
-	bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
 	u32 old_control;
 	int changed;
 
@@ -559,7 +561,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t snd_bt87x_capture_volume = {
+static struct snd_kcontrol_new snd_bt87x_capture_volume = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Capture Volume",
 	.info = snd_bt87x_capture_volume_info,
@@ -567,7 +569,8 @@
 	.put = snd_bt87x_capture_volume_put,
 };
 
-static int snd_bt87x_capture_boost_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
+static int snd_bt87x_capture_boost_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *info)
 {
 	info->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	info->count = 1;
@@ -576,17 +579,19 @@
 	return 0;
 }
 
-static int snd_bt87x_capture_boost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+static int snd_bt87x_capture_boost_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *value)
 {
-	bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
 
 	value->value.integer.value[0] = !! (chip->reg_control & CTL_A_G2X);
 	return 0;
 }
 
-static int snd_bt87x_capture_boost_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+static int snd_bt87x_capture_boost_put(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *value)
 {
-	bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
 	u32 old_control;
 	int changed;
 
@@ -600,7 +605,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t snd_bt87x_capture_boost = {
+static struct snd_kcontrol_new snd_bt87x_capture_boost = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Capture Boost",
 	.info = snd_bt87x_capture_boost_info,
@@ -608,7 +613,8 @@
 	.put = snd_bt87x_capture_boost_put,
 };
 
-static int snd_bt87x_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
+static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *info)
 {
 	static char *texts[3] = {"TV Tuner", "FM", "Mic/Line"};
 
@@ -621,17 +627,19 @@
 	return 0;
 }
 
-static int snd_bt87x_capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *value)
 {
-	bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
 
 	value->value.enumerated.item[0] = (chip->reg_control & CTL_A_SEL_MASK) >> CTL_A_SEL_SHIFT;
 	return 0;
 }
 
-static int snd_bt87x_capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+static int snd_bt87x_capture_source_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *value)
 {
-	bt87x_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_bt87x *chip = snd_kcontrol_chip(kcontrol);
 	u32 old_control;
 	int changed;
 
@@ -645,7 +653,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t snd_bt87x_capture_source = {
+static struct snd_kcontrol_new snd_bt87x_capture_source = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Capture Source",
 	.info = snd_bt87x_capture_source_info,
@@ -653,7 +661,7 @@
 	.put = snd_bt87x_capture_source_put,
 };
 
-static int snd_bt87x_free(bt87x_t *chip)
+static int snd_bt87x_free(struct snd_bt87x *chip)
 {
 	if (chip->mmio) {
 		snd_bt87x_stop(chip);
@@ -670,16 +678,16 @@
 	return 0;
 }
 
-static int snd_bt87x_dev_free(snd_device_t *device)
+static int snd_bt87x_dev_free(struct snd_device *device)
 {
-	bt87x_t *chip = device->device_data;
+	struct snd_bt87x *chip = device->device_data;
 	return snd_bt87x_free(chip);
 }
 
-static int __devinit snd_bt87x_pcm(bt87x_t *chip, int device, char *name)
+static int __devinit snd_bt87x_pcm(struct snd_bt87x *chip, int device, char *name)
 {
 	int err;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 
 	err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
 	if (err < 0)
@@ -694,13 +702,13 @@
 							(255 * 4092 + 1023) & ~1023);
 }
 
-static int __devinit snd_bt87x_create(snd_card_t *card,
+static int __devinit snd_bt87x_create(struct snd_card *card,
 				      struct pci_dev *pci,
-				      bt87x_t **rchip)
+				      struct snd_bt87x **rchip)
 {
-	bt87x_t *chip;
+	struct snd_bt87x *chip;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_bt87x_dev_free
 	};
 
@@ -823,8 +831,8 @@
 				     const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	bt87x_t *chip;
+	struct snd_card *card;
+	struct snd_bt87x *chip;
 	int err, rate;
 
 	rate = pci_id->driver_data;
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index 9a4b640..c8131ea 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -554,37 +554,36 @@
 
 #include "ca_midi.h"
 
-typedef struct snd_ca0106_channel ca0106_channel_t;
-typedef struct snd_ca0106 ca0106_t;
-typedef struct snd_ca0106_pcm ca0106_pcm_t;
+struct snd_ca0106;
 
 struct snd_ca0106_channel {
-	ca0106_t *emu;
+	struct snd_ca0106 *emu;
 	int number;
 	int use;
-	void (*interrupt)(ca0106_t *emu, ca0106_channel_t *channel);
-	ca0106_pcm_t *epcm;
+	void (*interrupt)(struct snd_ca0106 *emu, struct snd_ca0106_channel *channel);
+	struct snd_ca0106_pcm *epcm;
 };
 
 struct snd_ca0106_pcm {
-	ca0106_t *emu;
-	snd_pcm_substream_t *substream;
+	struct snd_ca0106 *emu;
+	struct snd_pcm_substream *substream;
         int channel_id;
 	unsigned short running;
 };
 
-typedef struct {
+struct snd_ca0106_details {
         u32 serial;
         char * name;
         int ac97;
 	int gpio_type;
 	int i2c_adc;
-} ca0106_details_t;
+	int spi_dac;
+};
 
 // definition of the chip-specific record
 struct snd_ca0106 {
-	snd_card_t *card;
-	ca0106_details_t *details;
+	struct snd_card *card;
+	struct snd_ca0106_details *details;
 	struct pci_dev *pci;
 
 	unsigned long port;
@@ -597,11 +596,11 @@
 
 	spinlock_t emu_lock;
 
-	ac97_t *ac97;
-	snd_pcm_t *pcm;
+	struct snd_ac97 *ac97;
+	struct snd_pcm *pcm;
 
-	ca0106_channel_t playback_channels[4];
-	ca0106_channel_t capture_channels[4];
+	struct snd_ca0106_channel playback_channels[4];
+	struct snd_ca0106_channel capture_channels[4];
 	u32 spdif_bits[4];             /* s/pdif out setup */
 	int spdif_enable;
 	int capture_source;
@@ -609,22 +608,22 @@
 
 	struct snd_dma_buffer buffer;
 
-	ca_midi_t midi;
-	ca_midi_t midi2;
+	struct snd_ca_midi midi;
+	struct snd_ca_midi midi2;
 };
 
-int __devinit snd_ca0106_mixer(ca0106_t *emu);
-int __devinit snd_ca0106_proc_init(ca0106_t * emu);
+int snd_ca0106_mixer(struct snd_ca0106 *emu);
+int snd_ca0106_proc_init(struct snd_ca0106 * emu);
 
-unsigned int snd_ca0106_ptr_read(ca0106_t * emu, 
-					  unsigned int reg, 
-					  unsigned int chn);
+unsigned int snd_ca0106_ptr_read(struct snd_ca0106 * emu, 
+				 unsigned int reg, 
+				 unsigned int chn);
 
-void snd_ca0106_ptr_write(ca0106_t *emu, 
-				   unsigned int reg, 
-				   unsigned int chn, 
-				   unsigned int data);
+void snd_ca0106_ptr_write(struct snd_ca0106 *emu, 
+			  unsigned int reg, 
+			  unsigned int chn, 
+			  unsigned int data);
 
-int snd_ca0106_i2c_write(ca0106_t *emu, u32 reg, u32 value);
+int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
 
 
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 389d967..6ed7c0b 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -164,7 +164,7 @@
 
 #include "ca0106.h"
 
-static ca0106_details_t ca0106_chip_details[] = {
+static struct snd_ca0106_details ca0106_chip_details[] = {
 	 /* AudigyLS[SB0310] */
 	 { .serial = 0x10021102,
 	   .name   = "AudigyLS [SB0310]",
@@ -183,6 +183,17 @@
 	   .name   = "Live! 7.1 24bit [SB0413]",
 	   .gpio_type = 1,
 	   .i2c_adc = 1 } ,
+	 /* New Audigy SE. Has a different DAC. */
+	 /* SB0570:
+	  * CTRL:CA0106-DAT
+	  * ADC: WM8768GEDS
+	  * DAC: WM8775EDS
+	  */
+	 { .serial = 0x100a1102,
+	   .name   = "Audigy SE [SB0570]",
+	   .gpio_type = 1,
+	   .i2c_adc = 1,
+	   .spi_dac = 1 } ,
 	 /* MSI K8N Diamond Motherboard with onboard SB Live 24bit without AC97 */
 	 { .serial = 0x10091462,
 	   .name   = "MSI K8N Diamond MB [SB0438]",
@@ -201,13 +212,14 @@
 };
 
 /* hardware definition */
-static snd_pcm_hardware_t snd_ca0106_playback_hw = {
+static struct snd_pcm_hardware snd_ca0106_playback_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | 
 				 SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
-	.rates =		SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
+	.rates =		(SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
+				 SNDRV_PCM_RATE_192000),
 	.rate_min =		48000,
 	.rate_max =		192000,
 	.channels_min =		2,  //1,
@@ -220,13 +232,14 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ca0106_capture_hw = {
+static struct snd_pcm_hardware snd_ca0106_capture_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | 
 				 SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
-	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000,
+	.rates =		(SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
+				 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
 	.rate_min =		44100,
 	.rate_max =		192000,
 	.channels_min =		2,
@@ -239,7 +252,7 @@
 	.fifo_size =		0,
 };
 
-unsigned int snd_ca0106_ptr_read(ca0106_t * emu, 
+unsigned int snd_ca0106_ptr_read(struct snd_ca0106 * emu, 
 					  unsigned int reg, 
 					  unsigned int chn)
 {
@@ -255,7 +268,7 @@
 	return val;
 }
 
-void snd_ca0106_ptr_write(ca0106_t *emu, 
+void snd_ca0106_ptr_write(struct snd_ca0106 *emu, 
 				   unsigned int reg, 
 				   unsigned int chn, 
 				   unsigned int data)
@@ -271,16 +284,47 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-int snd_ca0106_i2c_write(ca0106_t *emu,
+int snd_ca0106_spi_write(struct snd_ca0106 * emu,
+				   unsigned int data)
+{
+	unsigned int reset, set;
+	unsigned int reg, tmp;
+	int n, result;
+	reg = SPI;
+	if (data > 0xffff) /* Only 16bit values allowed */
+		return 1;
+	tmp = snd_ca0106_ptr_read(emu, reg, 0);
+	reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */
+	set = reset | 0x10000; /* Set xxx1xxxx */
+	snd_ca0106_ptr_write(emu, reg, 0, reset | data);
+	tmp = snd_ca0106_ptr_read(emu, reg, 0); /* write post */
+	snd_ca0106_ptr_write(emu, reg, 0, set | data);
+	result = 1;
+	/* Wait for status bit to return to 0 */
+	for (n = 0; n < 100; n++) {
+		udelay(10);
+		tmp = snd_ca0106_ptr_read(emu, reg, 0);
+		if (!(tmp & 0x10000)) {
+			result = 0;
+			break;
+		}
+	}
+	if (result) /* Timed out */
+		return 1;
+	snd_ca0106_ptr_write(emu, reg, 0, reset | data);
+	tmp = snd_ca0106_ptr_read(emu, reg, 0); /* Write post */
+	return 0;
+}
+
+int snd_ca0106_i2c_write(struct snd_ca0106 *emu,
 				u32 reg,
 				u32 value)
 {
 	u32 tmp;
-	int timeout=0;
+	int timeout = 0;
 	int status;
 	int retry;
-	if ((reg > 0x7f) || (value > 0x1ff))
-	{
+	if ((reg > 0x7f) || (value > 0x1ff)) {
 		snd_printk(KERN_ERR "i2c_write: invalid values.\n");
 		return -EINVAL;
 	}
@@ -292,8 +336,7 @@
 	/* This controls the I2C connected to the WM8775 ADC Codec */
 	snd_ca0106_ptr_write(emu, I2C_D1, 0, tmp);
 
-	for(retry=0;retry<10;retry++)
-	{
+	for (retry = 0; retry < 10; retry++) {
 		/* Send the data to i2c */
 		tmp = snd_ca0106_ptr_read(emu, I2C_A, 0);
 		tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK);
@@ -301,24 +344,22 @@
 		snd_ca0106_ptr_write(emu, I2C_A, 0, tmp);
 
 		/* Wait till the transaction ends */
-		while(1)
-		{
+		while (1) {
 			status = snd_ca0106_ptr_read(emu, I2C_A, 0);
                 	//snd_printk("I2C:status=0x%x\n", status);
 			timeout++;
-			if((status & I2C_A_ADC_START)==0)
+			if ((status & I2C_A_ADC_START) == 0)
 				break;
 
-			if(timeout>1000)
+			if (timeout > 1000)
 				break;
 		}
 		//Read back and see if the transaction is successful
-		if((status & I2C_A_ADC_ABORT)==0)
+		if ((status & I2C_A_ADC_ABORT) == 0)
 			break;
 	}
 
-	if(retry==10)
-	{
+	if (retry == 10) {
 		snd_printk(KERN_ERR "Writing to ADC failed!\n");
 		return -EINVAL;
 	}
@@ -327,7 +368,7 @@
 }
 
 
-static void snd_ca0106_intr_enable(ca0106_t *emu, unsigned int intrenb)
+static void snd_ca0106_intr_enable(struct snd_ca0106 *emu, unsigned int intrenb)
 {
 	unsigned long flags;
 	unsigned int enable;
@@ -338,7 +379,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-static void snd_ca0106_intr_disable(ca0106_t *emu, unsigned int intrenb)
+static void snd_ca0106_intr_disable(struct snd_ca0106 *emu, unsigned int intrenb)
 {
 	unsigned long flags;
 	unsigned int enable;
@@ -350,18 +391,19 @@
 }
 
 
-static void snd_ca0106_pcm_free_substream(snd_pcm_runtime_t *runtime)
+static void snd_ca0106_pcm_free_substream(struct snd_pcm_runtime *runtime)
 {
 	kfree(runtime->private_data);
 }
 
 /* open_playback callback */
-static int snd_ca0106_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
+static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
+						int channel_id)
 {
-	ca0106_t *chip = snd_pcm_substream_chip(substream);
-        ca0106_channel_t *channel = &(chip->playback_channels[channel_id]);
-	ca0106_pcm_t *epcm;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ca0106 *chip = snd_pcm_substream_chip(substream);
+        struct snd_ca0106_channel *channel = &(chip->playback_channels[channel_id]);
+	struct snd_ca0106_pcm *epcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
@@ -380,10 +422,10 @@
         channel->emu = chip;
         channel->number = channel_id;
 
-        channel->use=1;
+	channel->use = 1;
         //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
         //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
-        channel->epcm=epcm;
+	channel->epcm = epcm;
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
                 return err;
 	if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0)
@@ -392,43 +434,44 @@
 }
 
 /* close callback */
-static int snd_ca0106_pcm_close_playback(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
 {
-	ca0106_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-        ca0106_pcm_t *epcm = runtime->private_data;
-        chip->playback_channels[epcm->channel_id].use=0;
-/* FIXME: maybe zero others */
+	struct snd_ca0106 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+        struct snd_ca0106_pcm *epcm = runtime->private_data;
+	chip->playback_channels[epcm->channel_id].use = 0;
+	/* FIXME: maybe zero others */
 	return 0;
 }
 
-static int snd_ca0106_pcm_open_playback_front(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_open_playback_front(struct snd_pcm_substream *substream)
 {
 	return snd_ca0106_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
 }
 
-static int snd_ca0106_pcm_open_playback_center_lfe(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_open_playback_center_lfe(struct snd_pcm_substream *substream)
 {
 	return snd_ca0106_pcm_open_playback_channel(substream, PCM_CENTER_LFE_CHANNEL);
 }
 
-static int snd_ca0106_pcm_open_playback_unknown(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_open_playback_unknown(struct snd_pcm_substream *substream)
 {
 	return snd_ca0106_pcm_open_playback_channel(substream, PCM_UNKNOWN_CHANNEL);
 }
 
-static int snd_ca0106_pcm_open_playback_rear(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_open_playback_rear(struct snd_pcm_substream *substream)
 {
 	return snd_ca0106_pcm_open_playback_channel(substream, PCM_REAR_CHANNEL);
 }
 
 /* open_capture callback */
-static int snd_ca0106_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id)
+static int snd_ca0106_pcm_open_capture_channel(struct snd_pcm_substream *substream,
+					       int channel_id)
 {
-	ca0106_t *chip = snd_pcm_substream_chip(substream);
-        ca0106_channel_t *channel = &(chip->capture_channels[channel_id]);
-	ca0106_pcm_t *epcm;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ca0106 *chip = snd_pcm_substream_chip(substream);
+        struct snd_ca0106_channel *channel = &(chip->capture_channels[channel_id]);
+	struct snd_ca0106_pcm *epcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
@@ -448,10 +491,10 @@
         channel->emu = chip;
         channel->number = channel_id;
 
-        channel->use=1;
+	channel->use = 1;
         //printk("open:channel_id=%d, chip=%p, channel=%p\n",channel_id, chip, channel);
         //channel->interrupt = snd_ca0106_pcm_channel_interrupt;
-        channel->epcm=epcm;
+        channel->epcm = epcm;
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
                 return err;
 	//snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_capture_period_sizes);
@@ -461,70 +504,70 @@
 }
 
 /* close callback */
-static int snd_ca0106_pcm_close_capture(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_close_capture(struct snd_pcm_substream *substream)
 {
-	ca0106_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-        ca0106_pcm_t *epcm = runtime->private_data;
-        chip->capture_channels[epcm->channel_id].use=0;
-/* FIXME: maybe zero others */
+	struct snd_ca0106 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+        struct snd_ca0106_pcm *epcm = runtime->private_data;
+	chip->capture_channels[epcm->channel_id].use = 0;
+	/* FIXME: maybe zero others */
 	return 0;
 }
 
-static int snd_ca0106_pcm_open_0_capture(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_open_0_capture(struct snd_pcm_substream *substream)
 {
 	return snd_ca0106_pcm_open_capture_channel(substream, 0);
 }
 
-static int snd_ca0106_pcm_open_1_capture(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_open_1_capture(struct snd_pcm_substream *substream)
 {
 	return snd_ca0106_pcm_open_capture_channel(substream, 1);
 }
 
-static int snd_ca0106_pcm_open_2_capture(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_open_2_capture(struct snd_pcm_substream *substream)
 {
 	return snd_ca0106_pcm_open_capture_channel(substream, 2);
 }
 
-static int snd_ca0106_pcm_open_3_capture(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_open_3_capture(struct snd_pcm_substream *substream)
 {
 	return snd_ca0106_pcm_open_capture_channel(substream, 3);
 }
 
 /* hw_params callback */
-static int snd_ca0106_pcm_hw_params_playback(snd_pcm_substream_t *substream,
-				      snd_pcm_hw_params_t * hw_params)
+static int snd_ca0106_pcm_hw_params_playback(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream,
 					params_buffer_bytes(hw_params));
 }
 
 /* hw_free callback */
-static int snd_ca0106_pcm_hw_free_playback(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_hw_free_playback(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
 /* hw_params callback */
-static int snd_ca0106_pcm_hw_params_capture(snd_pcm_substream_t *substream,
-				      snd_pcm_hw_params_t * hw_params)
+static int snd_ca0106_pcm_hw_params_capture(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream,
 					params_buffer_bytes(hw_params));
 }
 
 /* hw_free callback */
-static int snd_ca0106_pcm_hw_free_capture(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_hw_free_capture(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
 /* prepare playback callback */
-static int snd_ca0106_pcm_prepare_playback(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_prepare_playback(struct snd_pcm_substream *substream)
 {
-	ca0106_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ca0106_pcm_t *epcm = runtime->private_data;
+	struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ca0106_pcm *epcm = runtime->private_data;
 	int channel = epcm->channel_id;
 	u32 *table_base = (u32 *)(emu->buffer.area+(8*16*channel));
 	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
@@ -593,8 +636,8 @@
 
 	/* FIXME: Check emu->buffer.size before actually writing to it. */
         for(i=0; i < runtime->periods; i++) {
-		table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
-		table_base[(i*2)+1]=period_size_bytes<<16;
+		table_base[i*2] = runtime->dma_addr + (i * period_size_bytes);
+		table_base[i*2+1] = period_size_bytes << 16;
 	}
  
 	snd_ca0106_ptr_write(emu, PLAYBACK_LIST_ADDR, channel, emu->buffer.addr+(8*16*channel));
@@ -621,11 +664,11 @@
 }
 
 /* prepare capture callback */
-static int snd_ca0106_pcm_prepare_capture(snd_pcm_substream_t *substream)
+static int snd_ca0106_pcm_prepare_capture(struct snd_pcm_substream *substream)
 {
-	ca0106_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ca0106_pcm_t *epcm = runtime->private_data;
+	struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ca0106_pcm *epcm = runtime->private_data;
 	int channel = epcm->channel_id;
 	u32 hcfg_mask = HCFG_CAPTURE_S32_LE;
 	u32 hcfg_set = 0x00000000;
@@ -692,16 +735,16 @@
 }
 
 /* trigger_playback callback */
-static int snd_ca0106_pcm_trigger_playback(snd_pcm_substream_t *substream,
+static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
 				    int cmd)
 {
-	ca0106_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime;
-	ca0106_pcm_t *epcm;
+	struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime;
+	struct snd_ca0106_pcm *epcm;
 	int channel;
 	int result = 0;
 	struct list_head *pos;
-        snd_pcm_substream_t *s;
+        struct snd_pcm_substream *s;
 	u32 basic = 0;
 	u32 extended = 0;
 	int running=0;
@@ -745,12 +788,12 @@
 }
 
 /* trigger_capture callback */
-static int snd_ca0106_pcm_trigger_capture(snd_pcm_substream_t *substream,
+static int snd_ca0106_pcm_trigger_capture(struct snd_pcm_substream *substream,
 				    int cmd)
 {
-	ca0106_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ca0106_pcm_t *epcm = runtime->private_data;
+	struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ca0106_pcm *epcm = runtime->private_data;
 	int channel = epcm->channel_id;
 	int result = 0;
 
@@ -774,11 +817,11 @@
 
 /* pointer_playback callback */
 static snd_pcm_uframes_t
-snd_ca0106_pcm_pointer_playback(snd_pcm_substream_t *substream)
+snd_ca0106_pcm_pointer_playback(struct snd_pcm_substream *substream)
 {
-	ca0106_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ca0106_pcm_t *epcm = runtime->private_data;
+	struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ca0106_pcm *epcm = runtime->private_data;
 	snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
 	int channel = epcm->channel_id;
 
@@ -801,11 +844,11 @@
 
 /* pointer_capture callback */
 static snd_pcm_uframes_t
-snd_ca0106_pcm_pointer_capture(snd_pcm_substream_t *substream)
+snd_ca0106_pcm_pointer_capture(struct snd_pcm_substream *substream)
 {
-	ca0106_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ca0106_pcm_t *epcm = runtime->private_data;
+	struct snd_ca0106 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ca0106_pcm *epcm = runtime->private_data;
 	snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
 	int channel = channel=epcm->channel_id;
 
@@ -823,7 +866,7 @@
 }
 
 /* operators */
-static snd_pcm_ops_t snd_ca0106_playback_front_ops = {
+static struct snd_pcm_ops snd_ca0106_playback_front_ops = {
 	.open =        snd_ca0106_pcm_open_playback_front,
 	.close =       snd_ca0106_pcm_close_playback,
 	.ioctl =       snd_pcm_lib_ioctl,
@@ -834,7 +877,7 @@
 	.pointer =     snd_ca0106_pcm_pointer_playback,
 };
 
-static snd_pcm_ops_t snd_ca0106_capture_0_ops = {
+static struct snd_pcm_ops snd_ca0106_capture_0_ops = {
 	.open =        snd_ca0106_pcm_open_0_capture,
 	.close =       snd_ca0106_pcm_close_capture,
 	.ioctl =       snd_pcm_lib_ioctl,
@@ -845,7 +888,7 @@
 	.pointer =     snd_ca0106_pcm_pointer_capture,
 };
 
-static snd_pcm_ops_t snd_ca0106_capture_1_ops = {
+static struct snd_pcm_ops snd_ca0106_capture_1_ops = {
 	.open =        snd_ca0106_pcm_open_1_capture,
 	.close =       snd_ca0106_pcm_close_capture,
 	.ioctl =       snd_pcm_lib_ioctl,
@@ -856,7 +899,7 @@
 	.pointer =     snd_ca0106_pcm_pointer_capture,
 };
 
-static snd_pcm_ops_t snd_ca0106_capture_2_ops = {
+static struct snd_pcm_ops snd_ca0106_capture_2_ops = {
 	.open =        snd_ca0106_pcm_open_2_capture,
 	.close =       snd_ca0106_pcm_close_capture,
 	.ioctl =       snd_pcm_lib_ioctl,
@@ -867,7 +910,7 @@
 	.pointer =     snd_ca0106_pcm_pointer_capture,
 };
 
-static snd_pcm_ops_t snd_ca0106_capture_3_ops = {
+static struct snd_pcm_ops snd_ca0106_capture_3_ops = {
 	.open =        snd_ca0106_pcm_open_3_capture,
 	.close =       snd_ca0106_pcm_close_capture,
 	.ioctl =       snd_pcm_lib_ioctl,
@@ -878,7 +921,7 @@
 	.pointer =     snd_ca0106_pcm_pointer_capture,
 };
 
-static snd_pcm_ops_t snd_ca0106_playback_center_lfe_ops = {
+static struct snd_pcm_ops snd_ca0106_playback_center_lfe_ops = {
         .open =         snd_ca0106_pcm_open_playback_center_lfe,
         .close =        snd_ca0106_pcm_close_playback,
         .ioctl =        snd_pcm_lib_ioctl,
@@ -889,7 +932,7 @@
         .pointer =      snd_ca0106_pcm_pointer_playback, 
 };
 
-static snd_pcm_ops_t snd_ca0106_playback_unknown_ops = {
+static struct snd_pcm_ops snd_ca0106_playback_unknown_ops = {
         .open =         snd_ca0106_pcm_open_playback_unknown,
         .close =        snd_ca0106_pcm_close_playback,
         .ioctl =        snd_pcm_lib_ioctl,
@@ -900,7 +943,7 @@
         .pointer =      snd_ca0106_pcm_pointer_playback, 
 };
 
-static snd_pcm_ops_t snd_ca0106_playback_rear_ops = {
+static struct snd_pcm_ops snd_ca0106_playback_rear_ops = {
         .open =         snd_ca0106_pcm_open_playback_rear,
         .close =        snd_ca0106_pcm_close_playback,
         .ioctl =        snd_pcm_lib_ioctl,
@@ -912,10 +955,10 @@
 };
 
 
-static unsigned short snd_ca0106_ac97_read(ac97_t *ac97,
+static unsigned short snd_ca0106_ac97_read(struct snd_ac97 *ac97,
 					     unsigned short reg)
 {
-	ca0106_t *emu = ac97->private_data;
+	struct snd_ca0106 *emu = ac97->private_data;
 	unsigned long flags;
 	unsigned short val;
 
@@ -926,10 +969,10 @@
 	return val;
 }
 
-static void snd_ca0106_ac97_write(ac97_t *ac97,
+static void snd_ca0106_ac97_write(struct snd_ac97 *ac97,
 				    unsigned short reg, unsigned short val)
 {
-	ca0106_t *emu = ac97->private_data;
+	struct snd_ca0106 *emu = ac97->private_data;
 	unsigned long flags;
   
 	spin_lock_irqsave(&emu->emu_lock, flags);
@@ -938,12 +981,12 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-static int snd_ca0106_ac97(ca0106_t *chip)
+static int snd_ca0106_ac97(struct snd_ca0106 *chip)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_ca0106_ac97_write,
 		.read = snd_ca0106_ac97_read,
 	};
@@ -958,7 +1001,7 @@
 	return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
 }
 
-static int snd_ca0106_free(ca0106_t *chip)
+static int snd_ca0106_free(struct snd_ca0106 *chip)
 {
 	if (chip->res_port != NULL) {    /* avoid access to already used hardware */
 		// disable interrupts
@@ -991,9 +1034,9 @@
 	return 0;
 }
 
-static int snd_ca0106_dev_free(snd_device_t *device)
+static int snd_ca0106_dev_free(struct snd_device *device)
 {
-	ca0106_t *chip = device->device_data;
+	struct snd_ca0106 *chip = device->device_data;
 	return snd_ca0106_free(chip);
 }
 
@@ -1002,19 +1045,13 @@
 {
 	unsigned int status;
 
-	ca0106_t *chip = dev_id;
+	struct snd_ca0106 *chip = dev_id;
 	int i;
 	int mask;
         unsigned int stat76;
-	ca0106_channel_t *pchannel;
-
-	spin_lock(&chip->emu_lock);
+	struct snd_ca0106_channel *pchannel;
 
 	status = inl(chip->port + IPR);
-
-	// call updater, unlock before it
-	spin_unlock(&chip->emu_lock);
-  
 	if (! status)
 		return IRQ_NONE;
 
@@ -1024,11 +1061,11 @@
         mask = 0x11; /* 0x1 for one half, 0x10 for the other half period. */
 	for(i = 0; i < 4; i++) {
 		pchannel = &(chip->playback_channels[i]);
-		if(stat76 & mask) {
+		if (stat76 & mask) {
 /* FIXME: Select the correct substream for period elapsed */
 			if(pchannel->use) {
-                          snd_pcm_period_elapsed(pchannel->epcm->substream);
-	                //printk(KERN_INFO "interrupt [%d] used\n", i);
+				snd_pcm_period_elapsed(pchannel->epcm->substream);
+				//printk(KERN_INFO "interrupt [%d] used\n", i);
                         }
 		}
 	        //printk(KERN_INFO "channel=%p\n",pchannel);
@@ -1038,11 +1075,11 @@
         mask = 0x110000; /* 0x1 for one half, 0x10 for the other half period. */
 	for(i = 0; i < 4; i++) {
 		pchannel = &(chip->capture_channels[i]);
-		if(stat76 & mask) {
+		if (stat76 & mask) {
 /* FIXME: Select the correct substream for period elapsed */
 			if(pchannel->use) {
-                          snd_pcm_period_elapsed(pchannel->epcm->substream);
-	                //printk(KERN_INFO "interrupt [%d] used\n", i);
+				snd_pcm_period_elapsed(pchannel->epcm->substream);
+				//printk(KERN_INFO "interrupt [%d] used\n", i);
                         }
 		}
 	        //printk(KERN_INFO "channel=%p\n",pchannel);
@@ -1051,10 +1088,9 @@
 	}
 
         snd_ca0106_ptr_write(chip, EXTENDED_INT, 0, stat76);
-	spin_lock(&chip->emu_lock);
 
 	if (chip->midi.dev_id &&
-	  (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) {
+	    (status & (chip->midi.ipr_tx|chip->midi.ipr_rx))) {
 		if (chip->midi.interrupt)
 			chip->midi.interrupt(&chip->midi, status);
 		else
@@ -1064,22 +1100,13 @@
 	// acknowledge the interrupt if necessary
 	outl(status, chip->port+IPR);
 
-	spin_unlock(&chip->emu_lock);
-
 	return IRQ_HANDLED;
 }
 
-static void snd_ca0106_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct snd_pcm **rpcm)
 {
-	ca0106_t *emu = pcm->private_data;
-	emu->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_ca0106_pcm(ca0106_t *emu, int device, snd_pcm_t **rpcm)
-{
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *substream;
 	int err;
   
 	if (rpcm)
@@ -1088,7 +1115,6 @@
 		return err;
   
 	pcm->private_data = emu;
-	pcm->private_free = snd_ca0106_pcm_free;
 
 	switch (device) {
 	case 0:
@@ -1140,15 +1166,39 @@
 	return 0;
 }
 
-static int __devinit snd_ca0106_create(snd_card_t *card,
+static unsigned int spi_dac_init[] = {
+	0x00ff,
+	0x02ff,
+	0x0400,
+	0x0520,
+	0x0600,
+	0x08ff,
+	0x0aff,
+	0x0cff,
+	0x0eff,
+	0x10ff,
+	0x1200,
+	0x1400,
+	0x1480,
+	0x1800,
+	0x1aff,
+	0x1cff,
+	0x1e00,
+	0x0530,
+	0x0602,
+	0x0622,
+	0x1400,
+};
+
+static int __devinit snd_ca0106_create(struct snd_card *card,
 					 struct pci_dev *pci,
-					 ca0106_t **rchip)
+					 struct snd_ca0106 **rchip)
 {
-	ca0106_t *chip;
-	ca0106_details_t *c;
+	struct snd_ca0106 *chip;
+	struct snd_ca0106_details *c;
 	int err;
 	int ch;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_ca0106_dev_free,
 	};
   
@@ -1210,8 +1260,9 @@
 	strcpy(card->driver, "CA0106");
 	strcpy(card->shortname, "CA0106");
 
-	for (c=ca0106_chip_details; c->serial; c++) {
-		if (c->serial == chip->serial) break;
+	for (c = ca0106_chip_details; c->serial; c++) {
+		if (c->serial == chip->serial)
+			break;
 	}
 	chip->details = c;
 	sprintf(card->longname, "%s at 0x%lx irq %i",
@@ -1320,6 +1371,13 @@
         if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */
 	        snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */
 	}
+        if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */
+		int size, n;
+
+		size = ARRAY_SIZE(spi_dac_init);
+		for (n=0; n < size; n++)
+			snd_ca0106_spi_write(chip, spi_dac_init[n]);
+	}
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
 				  chip, &ops)) < 0) {
@@ -1331,43 +1389,44 @@
 }
 
 
-static void ca0106_midi_interrupt_enable(ca_midi_t *midi, int intr)
+static void ca0106_midi_interrupt_enable(struct snd_ca_midi *midi, int intr)
 {
-	snd_ca0106_intr_enable((ca0106_t *)(midi->dev_id), intr);
+	snd_ca0106_intr_enable((struct snd_ca0106 *)(midi->dev_id), intr);
 }
 
-static void ca0106_midi_interrupt_disable(ca_midi_t *midi, int intr)
+static void ca0106_midi_interrupt_disable(struct snd_ca_midi *midi, int intr)
 {
-	snd_ca0106_intr_disable((ca0106_t *)(midi->dev_id), intr);
+	snd_ca0106_intr_disable((struct snd_ca0106 *)(midi->dev_id), intr);
 }
 
-static unsigned char ca0106_midi_read(ca_midi_t *midi, int idx)
+static unsigned char ca0106_midi_read(struct snd_ca_midi *midi, int idx)
 {
-	return (unsigned char)snd_ca0106_ptr_read((ca0106_t *)(midi->dev_id), midi->port + idx, 0);
+	return (unsigned char)snd_ca0106_ptr_read((struct snd_ca0106 *)(midi->dev_id),
+						  midi->port + idx, 0);
 }
 
-static void ca0106_midi_write(ca_midi_t *midi, int data, int idx)
+static void ca0106_midi_write(struct snd_ca_midi *midi, int data, int idx)
 {
-	snd_ca0106_ptr_write((ca0106_t *)(midi->dev_id), midi->port + idx, 0, data);
+	snd_ca0106_ptr_write((struct snd_ca0106 *)(midi->dev_id), midi->port + idx, 0, data);
 }
 
-static snd_card_t *ca0106_dev_id_card(void *dev_id)
+static struct snd_card *ca0106_dev_id_card(void *dev_id)
 {
-	return ((ca0106_t *)dev_id)->card;
+	return ((struct snd_ca0106 *)dev_id)->card;
 }
 
 static int ca0106_dev_id_port(void *dev_id)
 {
-	return ((ca0106_t *)dev_id)->port;
+	return ((struct snd_ca0106 *)dev_id)->port;
 }
 
-static int __devinit snd_ca0106_midi(ca0106_t *chip, unsigned int channel)
+static int __devinit snd_ca0106_midi(struct snd_ca0106 *chip, unsigned int channel)
 {
-	ca_midi_t *midi;
+	struct snd_ca_midi *midi;
 	char *name;
 	int err;
 
-        if(channel==CA0106_MIDI_CHAN_B) {
+	if (channel == CA0106_MIDI_CHAN_B) {
 		name = "CA0106 MPU-401 (UART) B";
 		midi =  &chip->midi2;
 		midi->tx_enable = INTE_MIDI_TX_B;
@@ -1416,8 +1475,8 @@
 					const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	ca0106_t *chip;
+	struct snd_card *card;
+	struct snd_ca0106 *chip;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -1471,7 +1530,9 @@
 	}
 	snd_printdd(" done.\n");
 
+#ifdef CONFIG_PROC_FS
 	snd_ca0106_proc_init(chip);
+#endif
 
 	if ((err = snd_card_register(card)) < 0) {
 		snd_card_free(card);
@@ -1507,12 +1568,7 @@
 // initialization of the module
 static int __init alsa_card_ca0106_init(void)
 {
-	int err;
-
-	if ((err = pci_register_driver(&driver)) > 0)
-		return err;
-
-	return 0;
+	return pci_register_driver(&driver);
 }
 
 // clean up the module
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index c10e4a5..06fe055 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -73,7 +73,8 @@
 
 #include "ca0106.h"
 
-static int snd_ca0106_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ca0106_shared_spdif_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -82,19 +83,19 @@
 	return 0;
 }
 
-static int snd_ca0106_shared_spdif_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_shared_spdif_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = emu->spdif_enable;
 	return 0;
 }
 
-static int snd_ca0106_shared_spdif_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change = 0;
 	u32 mask;
@@ -125,18 +126,12 @@
         return change;
 }
 
-static snd_kcontrol_new_t snd_ca0106_shared_spdif __devinitdata =
+static int snd_ca0106_capture_source_info(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_info *uinfo)
 {
-	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name =		"SPDIF Out",
-	.info =		snd_ca0106_shared_spdif_info,
-	.get =		snd_ca0106_shared_spdif_get,
-	.put =		snd_ca0106_shared_spdif_put
-};
-
-static int snd_ca0106_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	static char *texts[6] = { "SPDIF out", "i2s mixer out", "SPDIF in", "i2s in", "AC97 in", "SRC out" };
+	static char *texts[6] = {
+		"IEC958 out", "i2s mixer out", "IEC958 in", "i2s in", "AC97 in", "SRC out"
+	};
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -147,19 +142,19 @@
 	return 0;
 }
 
-static int snd_ca0106_capture_source_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_capture_source_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = emu->capture_source;
 	return 0;
 }
 
-static int snd_ca0106_capture_source_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change = 0;
 	u32 mask;
@@ -176,16 +171,8 @@
         return change;
 }
 
-static snd_kcontrol_new_t snd_ca0106_capture_source __devinitdata =
-{
-	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name =		"Capture Source",
-	.info =		snd_ca0106_capture_source_info,
-	.get =		snd_ca0106_capture_source_get,
-	.put =		snd_ca0106_capture_source_put
-};
-
-static int snd_ca0106_capture_mic_line_in_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ca0106_capture_mic_line_in_info(struct snd_kcontrol *kcontrol,
+					       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = { "Line in", "Mic in" };
 
@@ -198,19 +185,19 @@
 	return 0;
 }
 
-static int snd_ca0106_capture_mic_line_in_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_capture_mic_line_in_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = emu->capture_mic_line_in;
 	return 0;
 }
 
-static int snd_ca0106_capture_mic_line_in_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change = 0;
 	u32 tmp;
@@ -235,7 +222,7 @@
         return change;
 }
 
-static snd_kcontrol_new_t snd_ca0106_capture_mic_line_in __devinitdata =
+static struct snd_kcontrol_new snd_ca0106_capture_mic_line_in __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Mic/Line in Capture",
@@ -244,17 +231,18 @@
 	.put =		snd_ca0106_capture_mic_line_in_put
 };
 
-static int snd_ca0106_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ca0106_spdif_get(snd_kcontrol_t * kcontrol,
-                                 snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_spdif_get(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
 {
-	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 
 	ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
@@ -264,8 +252,8 @@
         return 0;
 }
 
-static int snd_ca0106_spdif_get_mask(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = 0xff;
 	ucontrol->value.iec958.status[1] = 0xff;
@@ -274,10 +262,10 @@
         return 0;
 }
 
-static int snd_ca0106_spdif_put(snd_kcontrol_t * kcontrol,
-                                 snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_spdif_put(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
 {
-	ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	int change;
 	unsigned int val;
@@ -294,27 +282,8 @@
         return change;
 }
 
-static snd_kcontrol_new_t snd_ca0106_spdif_mask_control =
-{
-	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
-        .iface =        SNDRV_CTL_ELEM_IFACE_PCM,
-        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
-	.count =	4,
-        .info =         snd_ca0106_spdif_info,
-        .get =          snd_ca0106_spdif_get_mask
-};
-
-static snd_kcontrol_new_t snd_ca0106_spdif_control =
-{
-        .iface =	SNDRV_CTL_ELEM_IFACE_PCM,
-        .name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
-	.count =	4,
-        .info =         snd_ca0106_spdif_info,
-        .get =          snd_ca0106_spdif_get,
-        .put =          snd_ca0106_spdif_put
-};
-
-static int snd_ca0106_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
         uinfo->count = 2;
@@ -323,11 +292,15 @@
         return 0;
 }
 
-static int snd_ca0106_volume_get(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol, int reg, int channel_id)
+static int snd_ca0106_volume_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-        ca0106_t *emu = snd_kcontrol_chip(kcontrol);
+        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
         unsigned int value;
+	int channel_id, reg;
+
+	channel_id = (kcontrol->private_value >> 8) & 0xff;
+	reg = kcontrol->private_value & 0xff;
 
         value = snd_ca0106_ptr_read(emu, reg, channel_id);
         ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
@@ -335,237 +308,103 @@
         return 0;
 }
 
-static int snd_ca0106_volume_get_spdif_front(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
+static int snd_ca0106_volume_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	int channel_id = CONTROL_FRONT_CHANNEL;
-	int reg = PLAYBACK_VOLUME1;
-        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+        struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
+        unsigned int oval, nval;
+	int channel_id, reg;
+
+	channel_id = (kcontrol->private_value >> 8) & 0xff;
+	reg = kcontrol->private_value & 0xff;
+
+	oval = snd_ca0106_ptr_read(emu, reg, channel_id);
+	nval = ((0xff - ucontrol->value.integer.value[0]) << 24) |
+		((0xff - ucontrol->value.integer.value[1]) << 16);
+        nval |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
+		((0xff - ucontrol->value.integer.value[1]) );
+	if (oval == nval)
+		return 0;
+	snd_ca0106_ptr_write(emu, reg, channel_id, nval);
+	return 1;
 }
 
-static int snd_ca0106_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_CENTER_LFE_CHANNEL;
-	int reg = PLAYBACK_VOLUME1;
-        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_UNKNOWN_CHANNEL;
-	int reg = PLAYBACK_VOLUME1;
-        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_get_spdif_rear(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_REAR_CHANNEL;
-	int reg = PLAYBACK_VOLUME1;
-        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_get_analog_front(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_FRONT_CHANNEL;
-	int reg = PLAYBACK_VOLUME2;
-        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
+#define CA_VOLUME(xname,chid,reg) \
+{								\
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,	\
+	.info = snd_ca0106_volume_info,				\
+	.get =          snd_ca0106_volume_get,			\
+	.put =          snd_ca0106_volume_put,			\
+	.private_value = ((chid) << 8) | (reg)			\
 }
 
-static int snd_ca0106_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_CENTER_LFE_CHANNEL;
-	int reg = PLAYBACK_VOLUME2;
-        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_get_analog_unknown(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_UNKNOWN_CHANNEL;
-	int reg = PLAYBACK_VOLUME2;
-        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_get_analog_rear(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_REAR_CHANNEL;
-	int reg = PLAYBACK_VOLUME2;
-        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
 
-static int snd_ca0106_volume_get_feedback(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = 1;
-	int reg = CAPTURE_CONTROL;
-        return snd_ca0106_volume_get(kcontrol, ucontrol, reg, channel_id);
-}
-                                                                                                                           
-static int snd_ca0106_volume_put(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol, int reg, int channel_id)
-{
-        ca0106_t *emu = snd_kcontrol_chip(kcontrol);
-        unsigned int value;
-        //value = snd_ca0106_ptr_read(emu, reg, channel_id);
-        //value = value & 0xffff;
-        value = ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16);
-        value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) );
-        snd_ca0106_ptr_write(emu, reg, channel_id, value);
-        return 1;
-}
-static int snd_ca0106_volume_put_spdif_front(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_FRONT_CHANNEL;
-	int reg = PLAYBACK_VOLUME1;
-        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_CENTER_LFE_CHANNEL;
-	int reg = PLAYBACK_VOLUME1;
-        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_UNKNOWN_CHANNEL;
-	int reg = PLAYBACK_VOLUME1;
-        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_spdif_rear(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_REAR_CHANNEL;
-	int reg = PLAYBACK_VOLUME1;
-        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_analog_front(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_FRONT_CHANNEL;
-	int reg = PLAYBACK_VOLUME2;
-        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_CENTER_LFE_CHANNEL;
-	int reg = PLAYBACK_VOLUME2;
-        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_analog_unknown(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_UNKNOWN_CHANNEL;
-	int reg = PLAYBACK_VOLUME2;
-        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
-static int snd_ca0106_volume_put_analog_rear(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = CONTROL_REAR_CHANNEL;
-	int reg = PLAYBACK_VOLUME2;
-        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
+static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
+	CA_VOLUME("Analog Front Playback Volume",
+		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
+        CA_VOLUME("Analog Rear Playback Volume",
+		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2),
+	CA_VOLUME("Analog Center/LFE Playback Volume",
+		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2),
+        CA_VOLUME("Analog Side Playback Volume",
+		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2),
 
-static int snd_ca0106_volume_put_feedback(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int channel_id = 1;
-	int reg = CAPTURE_CONTROL;
-        return snd_ca0106_volume_put(kcontrol, ucontrol, reg, channel_id);
-}
+        CA_VOLUME("IEC958 Front Playback Volume",
+		  CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1),
+	CA_VOLUME("IEC958 Rear Playback Volume",
+		  CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1),
+	CA_VOLUME("IEC958 Center/LFE Playback Volume",
+		  CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1),
+	CA_VOLUME("IEC958 Unknown Playback Volume",
+		  CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1),
 
-static snd_kcontrol_new_t snd_ca0106_volume_control_analog_front =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "Analog Front Playback Volume",
-        .info =         snd_ca0106_volume_info,
-        .get =          snd_ca0106_volume_get_analog_front,
-        .put =          snd_ca0106_volume_put_analog_front
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_analog_center_lfe =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "Analog Center/LFE Playback Volume",
-        .info =         snd_ca0106_volume_info,
-        .get =          snd_ca0106_volume_get_analog_center_lfe,
-        .put =          snd_ca0106_volume_put_analog_center_lfe
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_analog_unknown =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "Analog Side Playback Volume",
-        .info =         snd_ca0106_volume_info,
-        .get =          snd_ca0106_volume_get_analog_unknown,
-        .put =          snd_ca0106_volume_put_analog_unknown
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_analog_rear =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "Analog Rear Playback Volume",
-        .info =         snd_ca0106_volume_info,
-        .get =          snd_ca0106_volume_get_analog_rear,
-        .put =          snd_ca0106_volume_put_analog_rear
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_front =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "SPDIF Front Playback Volume",
-        .info =         snd_ca0106_volume_info,
-        .get =          snd_ca0106_volume_get_spdif_front,
-        .put =          snd_ca0106_volume_put_spdif_front
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_center_lfe =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "SPDIF Center/LFE Playback Volume",
-        .info =         snd_ca0106_volume_info,
-        .get =          snd_ca0106_volume_get_spdif_center_lfe,
-        .put =          snd_ca0106_volume_put_spdif_center_lfe
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_unknown =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "SPDIF Unknown Playback Volume",
-        .info =         snd_ca0106_volume_info,
-        .get =          snd_ca0106_volume_get_spdif_unknown,
-        .put =          snd_ca0106_volume_put_spdif_unknown
-};
-static snd_kcontrol_new_t snd_ca0106_volume_control_spdif_rear =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "SPDIF Rear Playback Volume",
-        .info =         snd_ca0106_volume_info,
-        .get =          snd_ca0106_volume_get_spdif_rear,
-        .put =          snd_ca0106_volume_put_spdif_rear
+        CA_VOLUME("CAPTURE feedback Playback Volume",
+		  1, CAPTURE_CONTROL),
+
+	{
+		.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+		.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
+		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
+		.count =	4,
+		.info =         snd_ca0106_spdif_info,
+		.get =          snd_ca0106_spdif_get_mask
+	},
+	{
+		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name =		"IEC958 Playback Switch",
+		.info =		snd_ca0106_shared_spdif_info,
+		.get =		snd_ca0106_shared_spdif_get,
+		.put =		snd_ca0106_shared_spdif_put
+	},
+	{
+		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name =		"Capture Source",
+		.info =		snd_ca0106_capture_source_info,
+		.get =		snd_ca0106_capture_source_get,
+		.put =		snd_ca0106_capture_source_put
+	},
+	{
+		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+		.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+		.count =	4,
+		.info =         snd_ca0106_spdif_info,
+		.get =          snd_ca0106_spdif_get,
+		.put =          snd_ca0106_spdif_put
+	},
 };
 
-static snd_kcontrol_new_t snd_ca0106_volume_control_feedback =
+static int __devinit remove_ctl(struct snd_card *card, const char *name)
 {
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "CAPTURE feedback Playback Volume",
-        .info =         snd_ca0106_volume_info,
-        .get =          snd_ca0106_volume_get_feedback,
-        .put =          snd_ca0106_volume_put_feedback
-};
-
-
-static int remove_ctl(snd_card_t *card, const char *name)
-{
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 	memset(&id, 0, sizeof(id));
 	strcpy(id.name, name);
 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_remove_id(card, &id);
 }
 
-static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name)
+static struct snd_kcontrol __devinit *ctl_find(struct snd_card *card, const char *name)
 {
-	snd_ctl_elem_id_t sid;
+	struct snd_ctl_elem_id sid;
 	memset(&sid, 0, sizeof(sid));
 	/* FIXME: strcpy is bad. */
 	strcpy(sid.name, name);
@@ -573,9 +412,9 @@
 	return snd_ctl_find_id(card, &sid);
 }
 
-static int rename_ctl(snd_card_t *card, const char *src, const char *dst)
+static int __devinit rename_ctl(struct snd_card *card, const char *src, const char *dst)
 {
-	snd_kcontrol_t *kctl = ctl_find(card, src);
+	struct snd_kcontrol *kctl = ctl_find(card, src);
 	if (kctl) {
 		strcpy(kctl->id.name, dst);
 		return 0;
@@ -583,11 +422,10 @@
 	return -ENOENT;
 }
 
-int __devinit snd_ca0106_mixer(ca0106_t *emu)
+int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
 {
-        int err;
-        snd_kcontrol_t *kctl;
-        snd_card_t *card = emu->card;
+	int i, err;
+        struct snd_card *card = emu->card;
 	char **c;
 	static char *ca0106_remove_ctls[] = {
 		"Master Mono Playback Switch",
@@ -627,70 +465,22 @@
 		NULL
 	};
 #if 1
-	for (c=ca0106_remove_ctls; *c; c++)
+	for (c = ca0106_remove_ctls; *c; c++)
 		remove_ctl(card, *c);
-	for (c=ca0106_rename_ctls; *c; c += 2)
+	for (c = ca0106_rename_ctls; *c; c += 2)
 		rename_ctl(card, c[0], c[1]);
 #endif
 
-        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_front, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_rear, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_center_lfe, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_analog_unknown, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_front, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_rear, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_center_lfe, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_spdif_unknown, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_ca0106_volume_control_feedback, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-	if ((kctl = snd_ctl_new1(&snd_ca0106_spdif_mask_control, emu)) == NULL)
-		return -ENOMEM;
-	if ((err = snd_ctl_add(card, kctl)))
-		return err;
-	if ((kctl = snd_ctl_new1(&snd_ca0106_shared_spdif, emu)) == NULL)
-		return -ENOMEM;
-	if ((err = snd_ctl_add(card, kctl)))
-		return err;
-	if ((kctl = snd_ctl_new1(&snd_ca0106_capture_source, emu)) == NULL)
-		return -ENOMEM;
-	if ((err = snd_ctl_add(card, kctl)))
-		return err;
-	if (emu->details->i2c_adc == 1) {
-		if ((kctl = snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)) == NULL)
-			return -ENOMEM;
-		if ((err = snd_ctl_add(card, kctl)))
+	for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_ctls); i++) {
+		err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_ctls[i], emu));
+		if (err < 0)
 			return err;
 	}
-	if ((kctl = snd_ctl_new1(&snd_ca0106_spdif_control, emu)) == NULL)
-		return -ENOMEM;
-	if ((err = snd_ctl_add(card, kctl)))
-		return err;
+	if (emu->details->i2c_adc == 1) {
+		err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
+		if (err < 0)
+			return err;
+	}
         return 0;
 }
 
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index 1c9cc82..6375727 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -77,6 +77,8 @@
 #include "ca0106.h"
 
 
+#ifdef CONFIG_PROC_FS
+
 struct snd_ca0106_category_str {
 	int val;
 	const char *name;
@@ -97,7 +99,7 @@
 };
 
 
-static void snd_ca0106_proc_dump_iec958( snd_info_buffer_t *buffer, u32 value)
+static void snd_ca0106_proc_dump_iec958( struct snd_info_buffer *buffer, u32 value)
 {
 	int i;
 	u32 status[4];
@@ -271,10 +273,10 @@
 	}
 }
 
-static void snd_ca0106_proc_iec958(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_ca0106_proc_iec958(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	ca0106_t *emu = entry->private_data;
+	struct snd_ca0106 *emu = entry->private_data;
 	u32 value;
 
         value = snd_ca0106_ptr_read(emu, SAMPLE_RATE_TRACKER_STATUS, 0);
@@ -293,10 +295,10 @@
 	snd_iprintf(buffer, "\n");
 }
 
-static void snd_ca0106_proc_reg_write32(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_ca0106_proc_reg_write32(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	ca0106_t *emu = entry->private_data;
+	struct snd_ca0106 *emu = entry->private_data;
 	unsigned long flags;
         char line[64];
         u32 reg, val;
@@ -311,10 +313,10 @@
         }
 }
 
-static void snd_ca0106_proc_reg_read32(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_ca0106_proc_reg_read32(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	ca0106_t *emu = entry->private_data;
+	struct snd_ca0106 *emu = entry->private_data;
 	unsigned long value;
 	unsigned long flags;
 	int i;
@@ -327,10 +329,10 @@
 	}
 }
 
-static void snd_ca0106_proc_reg_read16(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_ca0106_proc_reg_read16(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	ca0106_t *emu = entry->private_data;
+	struct snd_ca0106 *emu = entry->private_data;
         unsigned int value;
 	unsigned long flags;
 	int i;
@@ -343,10 +345,10 @@
 	}
 }
 
-static void snd_ca0106_proc_reg_read8(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_ca0106_proc_reg_read8(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	ca0106_t *emu = entry->private_data;
+	struct snd_ca0106 *emu = entry->private_data;
 	unsigned int value;
 	unsigned long flags;
 	int i;
@@ -359,10 +361,10 @@
 	}
 }
 
-static void snd_ca0106_proc_reg_read1(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_ca0106_proc_reg_read1(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	ca0106_t *emu = entry->private_data;
+	struct snd_ca0106 *emu = entry->private_data;
 	unsigned long value;
 	int i,j;
 
@@ -377,10 +379,10 @@
 	}
 }
 
-static void snd_ca0106_proc_reg_read2(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_ca0106_proc_reg_read2(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	ca0106_t *emu = entry->private_data;
+	struct snd_ca0106 *emu = entry->private_data;
 	unsigned long value;
 	int i,j;
 
@@ -395,10 +397,10 @@
 	}
 }
 
-static void snd_ca0106_proc_reg_write(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_ca0106_proc_reg_write(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	ca0106_t *emu = entry->private_data;
+	struct snd_ca0106 *emu = entry->private_data;
         char line[64];
         unsigned int reg, channel_id , val;
         while (!snd_info_get_line(buffer, line, sizeof(line))) {
@@ -409,10 +411,10 @@
         }
 }
 
-static void snd_ca0106_proc_i2c_write(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_ca0106_proc_i2c_write(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	ca0106_t *emu = entry->private_data;
+	struct snd_ca0106 *emu = entry->private_data;
         char line[64];
         unsigned int reg, val;
         while (!snd_info_get_line(buffer, line, sizeof(line))) {
@@ -424,9 +426,9 @@
         }
 }
 
-int __devinit snd_ca0106_proc_init(ca0106_t * emu)
+int __devinit snd_ca0106_proc_init(struct snd_ca0106 * emu)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	
 	if(! snd_card_proc_new(emu->card, "iec958", &entry))
 		snd_info_set_text_ops(entry, emu, 1024, snd_ca0106_proc_iec958);
@@ -459,3 +461,4 @@
 	return 0;
 }
 
+#endif /* CONFIG_PROC_FS */
diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c
index 2e08b27..2e6eab1 100644
--- a/sound/pci/ca0106/ca_midi.c
+++ b/sound/pci/ca0106/ca_midi.c
@@ -40,18 +40,20 @@
 #define ca_midi_input_avail(midi)	(!(ca_midi_read_stat(midi) & midi->input_avail))
 #define ca_midi_output_ready(midi)	(!(ca_midi_read_stat(midi) & midi->output_ready))
 
-static void ca_midi_clear_rx(ca_midi_t *midi)
+static void ca_midi_clear_rx(struct snd_ca_midi *midi)
 {
 	int timeout = 100000;
 	for (; timeout > 0 && ca_midi_input_avail(midi); timeout--)
 		ca_midi_read_data(midi);
 #ifdef CONFIG_SND_DEBUG
 	if (timeout <= 0)
-		snd_printk(KERN_ERR "ca_midi_clear_rx: timeout (status = 0x%x)\n", ca_midi_read_stat(midi));
+		snd_printk(KERN_ERR "ca_midi_clear_rx: timeout (status = 0x%x)\n",
+			   ca_midi_read_stat(midi));
 #endif
 }
 
-static void ca_midi_interrupt(ca_midi_t *midi, unsigned int status) {
+static void ca_midi_interrupt(struct snd_ca_midi *midi, unsigned int status)
+{
 	unsigned char byte;
 
 	if (midi->rmidi == NULL) {
@@ -86,7 +88,7 @@
 
 }
 
-static void ca_midi_cmd(ca_midi_t *midi, unsigned char cmd, int ack)
+static void ca_midi_cmd(struct snd_ca_midi *midi, unsigned char cmd, int ack)
 {
 	unsigned long flags;
 	int timeout, ok;
@@ -119,9 +121,9 @@
 			   ca_midi_read_data(midi));
 }
 
-static int ca_midi_input_open(snd_rawmidi_substream_t * substream)
+static int ca_midi_input_open(struct snd_rawmidi_substream *substream)
 {
-	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	struct snd_ca_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 	
 	snd_assert(midi->dev_id, return -ENXIO);
@@ -138,9 +140,9 @@
 	return 0;
 }
 
-static int ca_midi_output_open(snd_rawmidi_substream_t * substream)
+static int ca_midi_output_open(struct snd_rawmidi_substream *substream)
 {
-	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	struct snd_ca_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 
 	snd_assert(midi->dev_id, return -ENXIO);
@@ -157,9 +159,9 @@
 	return 0;
 }
 
-static int ca_midi_input_close(snd_rawmidi_substream_t * substream)
+static int ca_midi_input_close(struct snd_rawmidi_substream *substream)
 {
-	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	struct snd_ca_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 
 	snd_assert(midi->dev_id, return -ENXIO);
@@ -176,9 +178,9 @@
 	return 0;
 }
 
-static int ca_midi_output_close(snd_rawmidi_substream_t * substream)
+static int ca_midi_output_close(struct snd_rawmidi_substream *substream)
 {
-	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	struct snd_ca_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 	snd_assert(midi->dev_id, return -ENXIO);
 	
@@ -197,9 +199,9 @@
 	return 0;
 }
 
-static void ca_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void ca_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	struct snd_ca_midi *midi = substream->rmidi->private_data;
 	snd_assert(midi->dev_id, return);
 
 	if (up) {
@@ -209,9 +211,9 @@
 	}
 }
 
-static void ca_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void ca_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	ca_midi_t *midi = (ca_midi_t *)substream->rmidi->private_data;
+	struct snd_ca_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 
 	snd_assert(midi->dev_id, return);
@@ -246,21 +248,22 @@
 	}
 }
 
-static snd_rawmidi_ops_t ca_midi_output =
+static struct snd_rawmidi_ops ca_midi_output =
 {
 	.open =		ca_midi_output_open,
 	.close =	ca_midi_output_close,
 	.trigger =	ca_midi_output_trigger,
 };
 
-static snd_rawmidi_ops_t ca_midi_input =
+static struct snd_rawmidi_ops ca_midi_input =
 {
 	.open =		ca_midi_input_open,
 	.close =	ca_midi_input_close,
 	.trigger =	ca_midi_input_trigger,
 };
 
-static void ca_midi_free(ca_midi_t *midi) {
+static void ca_midi_free(struct snd_ca_midi *midi)
+{
 	midi->interrupt = NULL;
 	midi->interrupt_enable = NULL;
 	midi->interrupt_disable = NULL;
@@ -271,14 +274,14 @@
 	midi->rmidi = NULL;
 }
 
-static void ca_rmidi_free(snd_rawmidi_t *rmidi)
+static void ca_rmidi_free(struct snd_rawmidi *rmidi)
 {
-	ca_midi_free((ca_midi_t *)rmidi->private_data);
+	ca_midi_free(rmidi->private_data);
 }
 
-int __devinit ca_midi_init(void *dev_id, ca_midi_t *midi, int device, char *name)
+int __devinit ca_midi_init(void *dev_id, struct snd_ca_midi *midi, int device, char *name)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	if ((err = snd_rawmidi_new(midi->get_dev_id_card(midi->dev_id), name, device, 1, 1, &rmidi)) < 0)
diff --git a/sound/pci/ca0106/ca_midi.h b/sound/pci/ca0106/ca_midi.h
index b452cec..b72c093 100644
--- a/sound/pci/ca0106/ca_midi.h
+++ b/sound/pci/ca0106/ca_midi.h
@@ -29,12 +29,11 @@
 #define CA_MIDI_MODE_INPUT	MPU401_MODE_INPUT
 #define CA_MIDI_MODE_OUTPUT	MPU401_MODE_OUTPUT
 
-typedef struct ca_midi ca_midi_t;
-struct ca_midi {
+struct snd_ca_midi {
 
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *substream_input;
-	snd_rawmidi_substream_t *substream_output;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *substream_input;
+	struct snd_rawmidi_substream *substream_output;
 
 	void *dev_id;
 
@@ -52,18 +51,16 @@
 	int input_avail, output_ready;
 	int ack, reset, enter_uart;
 
-	void (*interrupt)(ca_midi_t *midi, unsigned int status);
-	void (*interrupt_enable)(ca_midi_t *midi, int intr);
-	void (*interrupt_disable)(ca_midi_t *midi, int intr);
+	void (*interrupt)(struct snd_ca_midi *midi, unsigned int status);
+	void (*interrupt_enable)(struct snd_ca_midi *midi, int intr);
+	void (*interrupt_disable)(struct snd_ca_midi *midi, int intr);
 
-	unsigned char (*read)(ca_midi_t *midi, int idx);
-	void (*write)(ca_midi_t *midi, int data, int idx);
+	unsigned char (*read)(struct snd_ca_midi *midi, int idx);
+	void (*write)(struct snd_ca_midi *midi, int data, int idx);
 
 	/* get info from dev_id */
-	snd_card_t *(*get_dev_id_card)(void *dev_id);
+	struct snd_card *(*get_dev_id_card)(void *dev_id);
 	int (*get_dev_id_port)(void *dev_id);
 };
 
-int __devinit ca_midi_init(void *card, ca_midi_t *midi, int device, char *name);
-
-
+int ca_midi_init(void *card, struct snd_ca_midi *midi, int device, char *name);
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index db60537..c03b0a0 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -269,6 +269,7 @@
 #define CM_MICGAINZ		0x01	/* mic boost */
 #define CM_MICGAINZ_SHIFT	0
 
+#define CM_REG_MIXER3		0x24
 #define CM_REG_AUX_VOL		0x26
 #define CM_VAUXL_MASK		0xf0
 #define CM_VAUXR_MASK		0x0f
@@ -324,6 +325,7 @@
 #define CM_REG_CH0_FRAME2	0x84
 #define CM_REG_CH1_FRAME1	0x88	/* 0-15: count of samples at bus master; buffer size */
 #define CM_REG_CH1_FRAME2	0x8C	/* 16-31: count of samples at codec; fragment size */
+#define CM_REG_EXT_MISC		0x90
 #define CM_REG_MISC_CTRL_8768	0x92	/* reg. name the same as 0x18 */
 #define CM_CHB3D8C		0x20	/* 7.1 channels support */
 #define CM_SPD32FMT		0x10	/* SPDIF/IN 32k */
@@ -378,11 +380,8 @@
  * driver data
  */
 
-typedef struct snd_stru_cmipci cmipci_t;
-typedef struct snd_stru_cmipci_pcm cmipci_pcm_t;
-
-struct snd_stru_cmipci_pcm {
-	snd_pcm_substream_t *substream;
+struct cmipci_pcm {
+	struct snd_pcm_substream *substream;
 	int running;		/* dac/adc running? */
 	unsigned int dma_size;	/* in frames */
 	unsigned int period_size;	/* in frames */
@@ -408,8 +407,8 @@
 };
 #define CM_SAVED_MIXERS		ARRAY_SIZE(cm_saved_mixer)
 
-struct snd_stru_cmipci {
-	snd_card_t *card;
+struct cmipci {
+	struct snd_card *card;
 
 	struct pci_dev *pci;
 	unsigned int device;	/* device ID */
@@ -418,9 +417,9 @@
 	unsigned long iobase;
 	unsigned int ctrl;	/* FUNCTRL0 current value */
 
-	snd_pcm_t *pcm;		/* DAC/ADC PCM */
-	snd_pcm_t *pcm2;	/* 2nd DAC */
-	snd_pcm_t *pcm_spdif;	/* SPDIF */
+	struct snd_pcm *pcm;		/* DAC/ADC PCM */
+	struct snd_pcm *pcm2;	/* 2nd DAC */
+	struct snd_pcm *pcm_spdif;	/* SPDIF */
 
 	int chip_version;
 	int max_channels;
@@ -437,63 +436,68 @@
 	unsigned int dig_status;
 	unsigned int dig_pcm_status;
 
-	snd_pcm_hardware_t *hw_info[3]; /* for playbacks */
+	struct snd_pcm_hardware *hw_info[3]; /* for playbacks */
 
 	int opened[2];	/* open mode */
 	struct semaphore open_mutex;
 
 	unsigned int mixer_insensitive: 1;
-	snd_kcontrol_t *mixer_res_ctl[CM_SAVED_MIXERS];
+	struct snd_kcontrol *mixer_res_ctl[CM_SAVED_MIXERS];
 	int mixer_res_status[CM_SAVED_MIXERS];
 
-	cmipci_pcm_t channel[2];	/* ch0 - DAC, ch1 - ADC or 2nd DAC */
+	struct cmipci_pcm channel[2];	/* ch0 - DAC, ch1 - ADC or 2nd DAC */
 
 	/* external MIDI */
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 
 #ifdef SUPPORT_JOYSTICK
 	struct gameport *gameport;
 #endif
 
 	spinlock_t reg_lock;
+
+#ifdef CONFIG_PM
+	unsigned int saved_regs[0x20];
+	unsigned char saved_mixers[0x20];
+#endif
 };
 
 
 /* read/write operations for dword register */
-static inline void snd_cmipci_write(cmipci_t *cm, unsigned int cmd, unsigned int data)
+static inline void snd_cmipci_write(struct cmipci *cm, unsigned int cmd, unsigned int data)
 {
 	outl(data, cm->iobase + cmd);
 }
 
-static inline unsigned int snd_cmipci_read(cmipci_t *cm, unsigned int cmd)
+static inline unsigned int snd_cmipci_read(struct cmipci *cm, unsigned int cmd)
 {
 	return inl(cm->iobase + cmd);
 }
 
 /* read/write operations for word register */
-static inline void snd_cmipci_write_w(cmipci_t *cm, unsigned int cmd, unsigned short data)
+static inline void snd_cmipci_write_w(struct cmipci *cm, unsigned int cmd, unsigned short data)
 {
 	outw(data, cm->iobase + cmd);
 }
 
-static inline unsigned short snd_cmipci_read_w(cmipci_t *cm, unsigned int cmd)
+static inline unsigned short snd_cmipci_read_w(struct cmipci *cm, unsigned int cmd)
 {
 	return inw(cm->iobase + cmd);
 }
 
 /* read/write operations for byte register */
-static inline void snd_cmipci_write_b(cmipci_t *cm, unsigned int cmd, unsigned char data)
+static inline void snd_cmipci_write_b(struct cmipci *cm, unsigned int cmd, unsigned char data)
 {
 	outb(data, cm->iobase + cmd);
 }
 
-static inline unsigned char snd_cmipci_read_b(cmipci_t *cm, unsigned int cmd)
+static inline unsigned char snd_cmipci_read_b(struct cmipci *cm, unsigned int cmd)
 {
 	return inb(cm->iobase + cmd);
 }
 
 /* bit operations for dword register */
-static int snd_cmipci_set_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag)
+static int snd_cmipci_set_bit(struct cmipci *cm, unsigned int cmd, unsigned int flag)
 {
 	unsigned int val, oval;
 	val = oval = inl(cm->iobase + cmd);
@@ -504,7 +508,7 @@
 	return 1;
 }
 
-static int snd_cmipci_clear_bit(cmipci_t *cm, unsigned int cmd, unsigned int flag)
+static int snd_cmipci_clear_bit(struct cmipci *cm, unsigned int cmd, unsigned int flag)
 {
 	unsigned int val, oval;
 	val = oval = inl(cm->iobase + cmd);
@@ -516,7 +520,7 @@
 }
 
 /* bit operations for byte register */
-static int snd_cmipci_set_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag)
+static int snd_cmipci_set_bit_b(struct cmipci *cm, unsigned int cmd, unsigned char flag)
 {
 	unsigned char val, oval;
 	val = oval = inb(cm->iobase + cmd);
@@ -527,7 +531,7 @@
 	return 1;
 }
 
-static int snd_cmipci_clear_bit_b(cmipci_t *cm, unsigned int cmd, unsigned char flag)
+static int snd_cmipci_clear_bit_b(struct cmipci *cm, unsigned int cmd, unsigned char flag)
 {
 	unsigned char val, oval;
 	val = oval = inb(cm->iobase + cmd);
@@ -608,7 +612,7 @@
  * at the register CM_REG_FUNCTRL1 (0x04).
  * Problem: other ways are also possible (any information about that?)
  */
-static void snd_cmipci_set_pll(cmipci_t *cm, unsigned int rate, unsigned int slot)
+static void snd_cmipci_set_pll(struct cmipci *cm, unsigned int rate, unsigned int slot)
 {
 	unsigned int reg = CM_REG_PLL + slot;
 	/*
@@ -626,16 +630,16 @@
 }
 #endif /* USE_VAR48KRATE */
 
-static int snd_cmipci_hw_params(snd_pcm_substream_t * substream,
-				snd_pcm_hw_params_t * hw_params)
+static int snd_cmipci_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_cmipci_playback2_hw_params(snd_pcm_substream_t * substream,
-					  snd_pcm_hw_params_t * hw_params)
+static int snd_cmipci_playback2_hw_params(struct snd_pcm_substream *substream,
+					  struct snd_pcm_hw_params *hw_params)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	if (params_channels(hw_params) > 2) {
 		down(&cm->open_mutex);
 		if (cm->opened[CM_CH_PLAY]) {
@@ -649,7 +653,7 @@
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static void snd_cmipci_ch_reset(cmipci_t *cm, int ch)
+static void snd_cmipci_ch_reset(struct cmipci *cm, int ch)
 {
 	int reset = CM_RST_CH0 << (cm->channel[ch].ch);
 	snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | reset);
@@ -657,7 +661,7 @@
 	udelay(10);
 }
 
-static int snd_cmipci_hw_free(snd_pcm_substream_t * substream)
+static int snd_cmipci_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
@@ -667,23 +671,23 @@
  */
 
 static unsigned int hw_channels[] = {1, 2, 4, 5, 6, 8};
-static snd_pcm_hw_constraint_list_t hw_constraints_channels_4 = {
+static struct snd_pcm_hw_constraint_list hw_constraints_channels_4 = {
 	.count = 3,
 	.list = hw_channels,
 	.mask = 0,
 };
-static snd_pcm_hw_constraint_list_t hw_constraints_channels_6 = {
+static struct snd_pcm_hw_constraint_list hw_constraints_channels_6 = {
 	.count = 5,
 	.list = hw_channels,
 	.mask = 0,
 };
-static snd_pcm_hw_constraint_list_t hw_constraints_channels_8 = {
+static struct snd_pcm_hw_constraint_list hw_constraints_channels_8 = {
 	.count = 6,
 	.list = hw_channels,
 	.mask = 0,
 };
 
-static int set_dac_channels(cmipci_t *cm, cmipci_pcm_t *rec, int channels)
+static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int channels)
 {
 	if (channels > 2) {
 		if (! cm->can_multi_ch)
@@ -737,11 +741,11 @@
  * prepare playback/capture channel
  * channel to be used must have been set in rec->ch.
  */
-static int snd_cmipci_pcm_prepare(cmipci_t *cm, cmipci_pcm_t *rec,
-				 snd_pcm_substream_t *substream)
+static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
+				 struct snd_pcm_substream *substream)
 {
 	unsigned int reg, freq, val;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	rec->fmt = 0;
 	rec->shift = 0;
@@ -820,8 +824,8 @@
 /*
  * PCM trigger/stop
  */
-static int snd_cmipci_pcm_trigger(cmipci_t *cm, cmipci_pcm_t *rec,
-				 snd_pcm_substream_t *substream, int cmd)
+static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec,
+				  struct snd_pcm_substream *substream, int cmd)
 {
 	unsigned int inthld, chen, reset, pause;
 	int result = 0;
@@ -852,10 +856,12 @@
 		snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~reset);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		cm->ctrl |= pause;
 		snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		cm->ctrl &= ~pause;
 		snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
 		break;
@@ -870,8 +876,8 @@
 /*
  * return the current pointer
  */
-static snd_pcm_uframes_t snd_cmipci_pcm_pointer(cmipci_t *cm, cmipci_pcm_t *rec,
-					  snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci_pcm *rec,
+						struct snd_pcm_substream *substream)
 {
 	size_t ptr;
 	unsigned int reg;
@@ -895,16 +901,16 @@
  * playback
  */
 
-static int snd_cmipci_playback_trigger(snd_pcm_substream_t *substream,
+static int snd_cmipci_playback_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_PLAY], substream, cmd);
 }
 
-static snd_pcm_uframes_t snd_cmipci_playback_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_cmipci_playback_pointer(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	return snd_cmipci_pcm_pointer(cm, &cm->channel[CM_CH_PLAY], substream);
 }
 
@@ -914,16 +920,16 @@
  * capture
  */
 
-static int snd_cmipci_capture_trigger(snd_pcm_substream_t *substream,
+static int snd_cmipci_capture_trigger(struct snd_pcm_substream *substream,
 				     int cmd)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	return snd_cmipci_pcm_trigger(cm, &cm->channel[CM_CH_CAPT], substream, cmd);
 }
 
-static snd_pcm_uframes_t snd_cmipci_capture_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_cmipci_capture_pointer(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	return snd_cmipci_pcm_pointer(cm, &cm->channel[CM_CH_CAPT], substream);
 }
 
@@ -932,18 +938,18 @@
  * hw preparation for spdif
  */
 
-static int snd_cmipci_spdif_default_info(snd_kcontrol_t *kcontrol,
-					 snd_ctl_elem_info_t *uinfo)
+static int snd_cmipci_spdif_default_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_cmipci_spdif_default_get(snd_kcontrol_t *kcontrol,
-					snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_spdif_default_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cmipci *chip = snd_kcontrol_chip(kcontrol);
 	int i;
 
 	spin_lock_irq(&chip->reg_lock);
@@ -953,10 +959,10 @@
 	return 0;
 }
 
-static int snd_cmipci_spdif_default_put(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_cmipci_spdif_default_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cmipci *chip = snd_kcontrol_chip(kcontrol);
 	int i, change;
 	unsigned int val;
 
@@ -970,7 +976,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_cmipci_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_cmipci_spdif_default __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -979,16 +985,16 @@
 	.put =		snd_cmipci_spdif_default_put
 };
 
-static int snd_cmipci_spdif_mask_info(snd_kcontrol_t *kcontrol,
-				      snd_ctl_elem_info_t *uinfo)
+static int snd_cmipci_spdif_mask_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_cmipci_spdif_mask_get(snd_kcontrol_t * kcontrol,
-				     snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_spdif_mask_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = 0xff;
 	ucontrol->value.iec958.status[1] = 0xff;
@@ -997,7 +1003,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_cmipci_spdif_mask __devinitdata =
+static struct snd_kcontrol_new snd_cmipci_spdif_mask __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1006,18 +1012,18 @@
 	.get =		snd_cmipci_spdif_mask_get,
 };
 
-static int snd_cmipci_spdif_stream_info(snd_kcontrol_t *kcontrol,
-					snd_ctl_elem_info_t *uinfo)
+static int snd_cmipci_spdif_stream_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_cmipci_spdif_stream_get(snd_kcontrol_t *kcontrol,
-				       snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_spdif_stream_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cmipci *chip = snd_kcontrol_chip(kcontrol);
 	int i;
 
 	spin_lock_irq(&chip->reg_lock);
@@ -1027,10 +1033,10 @@
 	return 0;
 }
 
-static int snd_cmipci_spdif_stream_put(snd_kcontrol_t *kcontrol,
-				       snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_spdif_stream_put(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cmipci *chip = snd_kcontrol_chip(kcontrol);
 	int i, change;
 	unsigned int val;
 
@@ -1044,7 +1050,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_cmipci_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_cmipci_spdif_stream __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1058,17 +1064,17 @@
  */
 
 /* save mixer setting and mute for AC3 playback */
-static int save_mixer_state(cmipci_t *cm)
+static int save_mixer_state(struct cmipci *cm)
 {
 	if (! cm->mixer_insensitive) {
-		snd_ctl_elem_value_t *val;
+		struct snd_ctl_elem_value *val;
 		unsigned int i;
 
 		val = kmalloc(sizeof(*val), GFP_ATOMIC);
 		if (!val)
 			return -ENOMEM;
 		for (i = 0; i < CM_SAVED_MIXERS; i++) {
-			snd_kcontrol_t *ctl = cm->mixer_res_ctl[i];
+			struct snd_kcontrol *ctl = cm->mixer_res_ctl[i];
 			if (ctl) {
 				int event;
 				memset(val, 0, sizeof(*val));
@@ -1092,10 +1098,10 @@
 
 
 /* restore the previously saved mixer status */
-static void restore_mixer_state(cmipci_t *cm)
+static void restore_mixer_state(struct cmipci *cm)
 {
 	if (cm->mixer_insensitive) {
-		snd_ctl_elem_value_t *val;
+		struct snd_ctl_elem_value *val;
 		unsigned int i;
 
 		val = kmalloc(sizeof(*val), GFP_KERNEL);
@@ -1104,7 +1110,7 @@
 		cm->mixer_insensitive = 0; /* at first clear this;
 					      otherwise the changes will be ignored */
 		for (i = 0; i < CM_SAVED_MIXERS; i++) {
-			snd_kcontrol_t *ctl = cm->mixer_res_ctl[i];
+			struct snd_kcontrol *ctl = cm->mixer_res_ctl[i];
 			if (ctl) {
 				int event;
 
@@ -1125,7 +1131,7 @@
 }
 
 /* spinlock held! */
-static void setup_ac3(cmipci_t *cm, snd_pcm_substream_t *subs, int do_ac3, int rate)
+static void setup_ac3(struct cmipci *cm, struct snd_pcm_substream *subs, int do_ac3, int rate)
 {
 	if (do_ac3) {
 		/* AC3EN for 037 */
@@ -1172,7 +1178,7 @@
 	}
 }
 
-static int setup_spdif_playback(cmipci_t *cm, snd_pcm_substream_t *subs, int up, int do_ac3)
+static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *subs, int up, int do_ac3)
 {
 	int rate, err;
 
@@ -1214,9 +1220,9 @@
  */
 
 /* playback - enable spdif only on the certain condition */
-static int snd_cmipci_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_cmipci_playback_prepare(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	int rate = substream->runtime->rate;
 	int err, do_spdif, do_ac3 = 0;
 
@@ -1231,9 +1237,9 @@
 }
 
 /* playback  (via device #2) - enable spdif always */
-static int snd_cmipci_playback_spdif_prepare(snd_pcm_substream_t *substream)
+static int snd_cmipci_playback_spdif_prepare(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	int err, do_ac3;
 
 	if (cm->can_ac3_hw) 
@@ -1245,25 +1251,25 @@
 	return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
 }
 
-static int snd_cmipci_playback_hw_free(snd_pcm_substream_t *substream)
+static int snd_cmipci_playback_hw_free(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	setup_spdif_playback(cm, substream, 0, 0);
 	restore_mixer_state(cm);
 	return snd_cmipci_hw_free(substream);
 }
 
 /* capture */
-static int snd_cmipci_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_cmipci_capture_prepare(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream);
 }
 
 /* capture with spdif (via device #2) */
-static int snd_cmipci_capture_spdif_prepare(snd_pcm_substream_t *substream)
+static int snd_cmipci_capture_spdif_prepare(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&cm->reg_lock);
 	snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
@@ -1272,9 +1278,9 @@
 	return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream);
 }
 
-static int snd_cmipci_capture_spdif_hw_free(snd_pcm_substream_t *subs)
+static int snd_cmipci_capture_spdif_hw_free(struct snd_pcm_substream *subs)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(subs);
+	struct cmipci *cm = snd_pcm_substream_chip(subs);
 
 	spin_lock_irq(&cm->reg_lock);
 	snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
@@ -1289,7 +1295,7 @@
  */
 static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	cmipci_t *cm = dev_id;
+	struct cmipci *cm = dev_id;
 	unsigned int status, mask = 0;
 	
 	/* fastpath out, to ease interrupt sharing */
@@ -1324,11 +1330,11 @@
  */
 
 /* playback on channel A */
-static snd_pcm_hardware_t snd_cmipci_playback =
+static struct snd_pcm_hardware snd_cmipci_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		5512,
@@ -1344,11 +1350,11 @@
 };
 
 /* capture on channel B */
-static snd_pcm_hardware_t snd_cmipci_capture =
+static struct snd_pcm_hardware snd_cmipci_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		5512,
@@ -1364,11 +1370,11 @@
 };
 
 /* playback on channel B - stereo 16bit only? */
-static snd_pcm_hardware_t snd_cmipci_playback2 =
+static struct snd_pcm_hardware snd_cmipci_playback2 =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		5512,
@@ -1384,11 +1390,11 @@
 };
 
 /* spdif playback on channel A */
-static snd_pcm_hardware_t snd_cmipci_playback_spdif =
+static struct snd_pcm_hardware snd_cmipci_playback_spdif =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
 	.rate_min =		44100,
@@ -1404,11 +1410,11 @@
 };
 
 /* spdif playback on channel A (32bit, IEC958 subframes) */
-static snd_pcm_hardware_t snd_cmipci_playback_iec958_subframe =
+static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
 	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
 	.rate_min =		44100,
@@ -1424,11 +1430,11 @@
 };
 
 /* spdif capture on channel B */
-static snd_pcm_hardware_t snd_cmipci_capture_spdif =
+static struct snd_pcm_hardware snd_cmipci_capture_spdif =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
-				 SNDRV_PCM_INFO_MMAP_VALID),
+				 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =	        SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
 	.rate_min =		44100,
@@ -1446,7 +1452,7 @@
 /*
  * check device open/close
  */
-static int open_device_check(cmipci_t *cm, int mode, snd_pcm_substream_t *subs)
+static int open_device_check(struct cmipci *cm, int mode, struct snd_pcm_substream *subs)
 {
 	int ch = mode & CM_OPEN_CH_MASK;
 
@@ -1473,7 +1479,7 @@
 	return 0;
 }
 
-static void close_device_check(cmipci_t *cm, int mode)
+static void close_device_check(struct cmipci *cm, int mode)
 {
 	int ch = mode & CM_OPEN_CH_MASK;
 
@@ -1499,10 +1505,10 @@
 /*
  */
 
-static int snd_cmipci_playback_open(snd_pcm_substream_t *substream)
+static int snd_cmipci_playback_open(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0)
@@ -1514,10 +1520,10 @@
 	return 0;
 }
 
-static int snd_cmipci_capture_open(snd_pcm_substream_t *substream)
+static int snd_cmipci_capture_open(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if ((err = open_device_check(cm, CM_OPEN_CAPTURE, substream)) < 0)
@@ -1531,10 +1537,10 @@
 	return 0;
 }
 
-static int snd_cmipci_playback2_open(snd_pcm_substream_t *substream)
+static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */
@@ -1557,10 +1563,10 @@
 	return 0;
 }
 
-static int snd_cmipci_playback_spdif_open(snd_pcm_substream_t *substream)
+static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if ((err = open_device_check(cm, CM_OPEN_SPDIF_PLAYBACK, substream)) < 0) /* use channel A */
@@ -1577,10 +1583,10 @@
 	return 0;
 }
 
-static int snd_cmipci_capture_spdif_open(snd_pcm_substream_t * substream)
+static int snd_cmipci_capture_spdif_open(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if ((err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream)) < 0) /* use channel B */
@@ -1594,38 +1600,38 @@
 /*
  */
 
-static int snd_cmipci_playback_close(snd_pcm_substream_t * substream)
+static int snd_cmipci_playback_close(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	close_device_check(cm, CM_OPEN_PLAYBACK);
 	return 0;
 }
 
-static int snd_cmipci_capture_close(snd_pcm_substream_t * substream)
+static int snd_cmipci_capture_close(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	close_device_check(cm, CM_OPEN_CAPTURE);
 	return 0;
 }
 
-static int snd_cmipci_playback2_close(snd_pcm_substream_t * substream)
+static int snd_cmipci_playback2_close(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	close_device_check(cm, CM_OPEN_PLAYBACK2);
 	close_device_check(cm, CM_OPEN_PLAYBACK_MULTI);
 	return 0;
 }
 
-static int snd_cmipci_playback_spdif_close(snd_pcm_substream_t * substream)
+static int snd_cmipci_playback_spdif_close(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	close_device_check(cm, CM_OPEN_SPDIF_PLAYBACK);
 	return 0;
 }
 
-static int snd_cmipci_capture_spdif_close(snd_pcm_substream_t * substream)
+static int snd_cmipci_capture_spdif_close(struct snd_pcm_substream *substream)
 {
-	cmipci_t *cm = snd_pcm_substream_chip(substream);
+	struct cmipci *cm = snd_pcm_substream_chip(substream);
 	close_device_check(cm, CM_OPEN_SPDIF_CAPTURE);
 	return 0;
 }
@@ -1634,7 +1640,7 @@
 /*
  */
 
-static snd_pcm_ops_t snd_cmipci_playback_ops = {
+static struct snd_pcm_ops snd_cmipci_playback_ops = {
 	.open =		snd_cmipci_playback_open,
 	.close =	snd_cmipci_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1645,7 +1651,7 @@
 	.pointer =	snd_cmipci_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_cmipci_capture_ops = {
+static struct snd_pcm_ops snd_cmipci_capture_ops = {
 	.open =		snd_cmipci_capture_open,
 	.close =	snd_cmipci_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1656,7 +1662,7 @@
 	.pointer =	snd_cmipci_capture_pointer,
 };
 
-static snd_pcm_ops_t snd_cmipci_playback2_ops = {
+static struct snd_pcm_ops snd_cmipci_playback2_ops = {
 	.open =		snd_cmipci_playback2_open,
 	.close =	snd_cmipci_playback2_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1667,7 +1673,7 @@
 	.pointer =	snd_cmipci_capture_pointer,	/* channel B */
 };
 
-static snd_pcm_ops_t snd_cmipci_playback_spdif_ops = {
+static struct snd_pcm_ops snd_cmipci_playback_spdif_ops = {
 	.open =		snd_cmipci_playback_spdif_open,
 	.close =	snd_cmipci_playback_spdif_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1678,7 +1684,7 @@
 	.pointer =	snd_cmipci_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_cmipci_capture_spdif_ops = {
+static struct snd_pcm_ops snd_cmipci_capture_spdif_ops = {
 	.open =		snd_cmipci_capture_spdif_open,
 	.close =	snd_cmipci_capture_spdif_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1693,14 +1699,9 @@
 /*
  */
 
-static void snd_cmipci_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_cmipci_pcm_new(struct cmipci *cm, int device)
 {
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_cmipci_pcm_new(cmipci_t *cm, int device)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 1, &pcm);
@@ -1711,7 +1712,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cmipci_capture_ops);
 
 	pcm->private_data = cm;
-	pcm->private_free = snd_cmipci_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "C-Media PCI DAC/ADC");
 	cm->pcm = pcm;
@@ -1722,9 +1722,9 @@
 	return 0;
 }
 
-static int __devinit snd_cmipci_pcm2_new(cmipci_t *cm, int device)
+static int __devinit snd_cmipci_pcm2_new(struct cmipci *cm, int device)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 0, &pcm);
@@ -1734,7 +1734,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cmipci_playback2_ops);
 
 	pcm->private_data = cm;
-	pcm->private_free = snd_cmipci_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "C-Media PCI 2nd DAC");
 	cm->pcm2 = pcm;
@@ -1745,9 +1744,9 @@
 	return 0;
 }
 
-static int __devinit snd_cmipci_pcm_spdif_new(cmipci_t *cm, int device)
+static int __devinit snd_cmipci_pcm_spdif_new(struct cmipci *cm, int device)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	err = snd_pcm_new(cm->card, cm->card->driver, device, 1, 1, &pcm);
@@ -1758,7 +1757,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cmipci_capture_spdif_ops);
 
 	pcm->private_data = cm;
-	pcm->private_free = snd_cmipci_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "C-Media PCI IEC958");
 	cm->pcm_spdif = pcm;
@@ -1778,13 +1776,13 @@
  *   - Output mute switches
  */
 
-static void snd_cmipci_mixer_write(cmipci_t *s, unsigned char idx, unsigned char data)
+static void snd_cmipci_mixer_write(struct cmipci *s, unsigned char idx, unsigned char data)
 {
 	outb(idx, s->iobase + CM_REG_SB16_ADDR);
 	outb(data, s->iobase + CM_REG_SB16_DATA);
 }
 
-static unsigned char snd_cmipci_mixer_read(cmipci_t *s, unsigned char idx)
+static unsigned char snd_cmipci_mixer_read(struct cmipci *s, unsigned char idx)
 {
 	unsigned char v;
 
@@ -1796,13 +1794,13 @@
 /*
  * general mixer element
  */
-typedef struct cmipci_sb_reg {
+struct cmipci_sb_reg {
 	unsigned int left_reg, right_reg;
 	unsigned int left_shift, right_shift;
 	unsigned int mask;
 	unsigned int invert: 1;
 	unsigned int stereo: 1;
-} cmipci_sb_reg_t;
+};
 
 #define COMPOSE_SB_REG(lreg,rreg,lshift,rshift,mask,invert,stereo) \
  ((lreg) | ((rreg) << 8) | (lshift << 16) | (rshift << 19) | (mask << 24) | (invert << 22) | (stereo << 23))
@@ -1819,7 +1817,7 @@
 #define CMIPCI_SB_SW_STEREO(xname,lshift,rshift) CMIPCI_DOUBLE(xname, SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, lshift, rshift, 1, 0, 1)
 #define CMIPCI_SB_SW_MONO(xname,shift) CMIPCI_DOUBLE(xname, SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, shift, shift, 1, 0, 0)
 
-static void cmipci_sb_reg_decode(cmipci_sb_reg_t *r, unsigned long val)
+static void cmipci_sb_reg_decode(struct cmipci_sb_reg *r, unsigned long val)
 {
 	r->left_reg = val & 0xff;
 	r->right_reg = (val >> 8) & 0xff;
@@ -1830,9 +1828,10 @@
 	r->mask = (val >> 24) & 0xff;
 }
 
-static int snd_cmipci_info_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_cmipci_info_volume(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
-	cmipci_sb_reg_t reg;
+	struct cmipci_sb_reg reg;
 
 	cmipci_sb_reg_decode(&reg, kcontrol->private_value);
 	uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -1842,10 +1841,11 @@
 	return 0;
 }
  
-static int snd_cmipci_get_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cmipci_get_volume(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
-	cmipci_sb_reg_t reg;
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci_sb_reg reg;
 	int val;
 
 	cmipci_sb_reg_decode(&reg, kcontrol->private_value);
@@ -1864,10 +1864,11 @@
 	return 0;
 }
 
-static int snd_cmipci_put_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cmipci_put_volume(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
-	cmipci_sb_reg_t reg;
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci_sb_reg reg;
 	int change;
 	int left, right, oleft, oright;
 
@@ -1912,7 +1913,8 @@
   .private_value = COMPOSE_SB_REG(SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, left_shift, right_shift, 1, 0, 1), \
 }
 
-static int snd_cmipci_info_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_cmipci_info_input_sw(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 4;
@@ -1921,10 +1923,11 @@
 	return 0;
 }
  
-static int snd_cmipci_get_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cmipci_get_input_sw(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
-	cmipci_sb_reg_t reg;
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci_sb_reg reg;
 	int val1, val2;
 
 	cmipci_sb_reg_decode(&reg, kcontrol->private_value);
@@ -1939,10 +1942,11 @@
 	return 0;
 }
 
-static int snd_cmipci_put_input_sw(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cmipci_put_input_sw(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
-	cmipci_sb_reg_t reg;
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci_sb_reg reg;
 	int change;
 	int val1, val2, oval1, oval2;
 
@@ -1995,9 +1999,10 @@
   .private_value = COMPOSE_SB_REG(reg, reg, shift, shift, mask, 0, 0), \
 }
 
-static int snd_cmipci_info_native_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_cmipci_info_native_mixer(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
 {
-	cmipci_sb_reg_t reg;
+	struct cmipci_sb_reg reg;
 
 	cmipci_sb_reg_decode(&reg, kcontrol->private_value);
 	uinfo->type = reg.mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -2008,10 +2013,11 @@
 
 }
 
-static int snd_cmipci_get_native_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cmipci_get_native_mixer(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
-	cmipci_sb_reg_t reg;
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci_sb_reg reg;
 	unsigned char oreg, val;
 
 	cmipci_sb_reg_decode(&reg, kcontrol->private_value);
@@ -2031,10 +2037,11 @@
 	return 0;
 }
 
-static int snd_cmipci_put_native_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cmipci_put_native_mixer(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
-	cmipci_sb_reg_t reg;
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci_sb_reg reg;
 	unsigned char oreg, nreg, val;
 
 	cmipci_sb_reg_decode(&reg, kcontrol->private_value);
@@ -2060,15 +2067,17 @@
 /*
  * special case - check mixer sensitivity
  */
-static int snd_cmipci_get_native_mixer_sensitive(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_get_native_mixer_sensitive(struct snd_kcontrol *kcontrol,
+						 struct snd_ctl_elem_value *ucontrol)
 {
-	//cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	//struct cmipci *cm = snd_kcontrol_chip(kcontrol);
 	return snd_cmipci_get_native_mixer(kcontrol, ucontrol);
 }
 
-static int snd_cmipci_put_native_mixer_sensitive(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_put_native_mixer_sensitive(struct snd_kcontrol *kcontrol,
+						 struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
 	if (cm->mixer_insensitive) {
 		/* ignored */
 		return 0;
@@ -2077,7 +2086,7 @@
 }
 
 
-static snd_kcontrol_new_t snd_cmipci_mixers[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_mixers[] __devinitdata = {
 	CMIPCI_SB_VOL_STEREO("Master Playback Volume", SB_DSP4_MASTER_DEV, 3, 31),
 	CMIPCI_MIXER_SW_MONO("3D Control - Switch", CM_REG_MIXER1, CM_X3DEN_SHIFT, 0),
 	CMIPCI_SB_VOL_STEREO("PCM Playback Volume", SB_DSP4_PCM_DEV, 3, 31),
@@ -2119,15 +2128,18 @@
  * other switches
  */
 
-typedef struct snd_cmipci_switch_args {
+struct cmipci_switch_args {
 	int reg;		/* register index */
 	unsigned int mask;	/* mask bits */
 	unsigned int mask_on;	/* mask bits to turn on */
 	unsigned int is_byte: 1;		/* byte access? */
-	unsigned int ac3_sensitive: 1;	/* access forbidden during non-audio operation? */
-} snd_cmipci_switch_args_t;
+	unsigned int ac3_sensitive: 1;	/* access forbidden during
+					 * non-audio operation?
+					 */
+};
 
-static int snd_cmipci_uswitch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_cmipci_uswitch_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2136,10 +2148,12 @@
 	return 0;
 }
 
-static int _snd_cmipci_uswitch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol, snd_cmipci_switch_args_t *args)
+static int _snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol,
+				   struct cmipci_switch_args *args)
 {
 	unsigned int val;
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&cm->reg_lock);
 	if (args->ac3_sensitive && cm->mixer_insensitive) {
@@ -2156,18 +2170,22 @@
 	return 0;
 }
 
-static int snd_cmipci_uswitch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	snd_cmipci_switch_args_t *args = (snd_cmipci_switch_args_t*)kcontrol->private_value;
+	struct cmipci_switch_args *args;
+	args = (struct cmipci_switch_args *)kcontrol->private_value;
 	snd_assert(args != NULL, return -EINVAL);
 	return _snd_cmipci_uswitch_get(kcontrol, ucontrol, args);
 }
 
-static int _snd_cmipci_uswitch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol, snd_cmipci_switch_args_t *args)
+static int _snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol,
+				   struct cmipci_switch_args *args)
 {
 	unsigned int val;
 	int change;
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&cm->reg_lock);
 	if (args->ac3_sensitive && cm->mixer_insensitive) {
@@ -2195,15 +2213,17 @@
 	return change;
 }
 
-static int snd_cmipci_uswitch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	snd_cmipci_switch_args_t *args = (snd_cmipci_switch_args_t*)kcontrol->private_value;
+	struct cmipci_switch_args *args;
+	args = (struct cmipci_switch_args *)kcontrol->private_value;
 	snd_assert(args != NULL, return -EINVAL);
 	return _snd_cmipci_uswitch_put(kcontrol, ucontrol, args);
 }
 
 #define DEFINE_SWITCH_ARG(sname, xreg, xmask, xmask_on, xis_byte, xac3) \
-static snd_cmipci_switch_args_t cmipci_switch_arg_##sname = { \
+static struct cmipci_switch_args cmipci_switch_arg_##sname = { \
   .reg = xreg, \
   .mask = xmask, \
   .mask_on = xmask_on, \
@@ -2260,7 +2280,8 @@
  * callbacks for spdif output switch
  * needs toggle two registers..
  */
-static int snd_cmipci_spdout_enable_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_spdout_enable_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
 	int changed;
 	changed = _snd_cmipci_uswitch_get(kcontrol, ucontrol, &cmipci_switch_arg_spdif_enable);
@@ -2268,9 +2289,10 @@
 	return changed;
 }
 
-static int snd_cmipci_spdout_enable_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_spdout_enable_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cmipci *chip = snd_kcontrol_chip(kcontrol);
 	int changed;
 	changed = _snd_cmipci_uswitch_put(kcontrol, ucontrol, &cmipci_switch_arg_spdif_enable);
 	changed |= _snd_cmipci_uswitch_put(kcontrol, ucontrol, &cmipci_switch_arg_spdo2dac);
@@ -2288,10 +2310,10 @@
 }
 
 
-static int snd_cmipci_line_in_mode_info(snd_kcontrol_t *kcontrol,
-					snd_ctl_elem_info_t *uinfo)
+static int snd_cmipci_line_in_mode_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
 	static char *texts[3] = { "Line-In", "Rear Output", "Bass Output" };
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -2302,7 +2324,7 @@
 	return 0;
 }
 
-static inline unsigned int get_line_in_mode(cmipci_t *cm)
+static inline unsigned int get_line_in_mode(struct cmipci *cm)
 {
 	unsigned int val;
 	if (cm->chip_version >= 39) {
@@ -2316,10 +2338,10 @@
 	return 0;
 }
 
-static int snd_cmipci_line_in_mode_get(snd_kcontrol_t *kcontrol,
-				       snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_line_in_mode_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&cm->reg_lock);
 	ucontrol->value.enumerated.item[0] = get_line_in_mode(cm);
@@ -2327,10 +2349,10 @@
 	return 0;
 }
 
-static int snd_cmipci_line_in_mode_put(snd_kcontrol_t *kcontrol,
-				       snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
 	int change;
 
 	spin_lock_irq(&cm->reg_lock);
@@ -2346,8 +2368,8 @@
 	return change;
 }
 
-static int snd_cmipci_mic_in_mode_info(snd_kcontrol_t *kcontrol,
-				       snd_ctl_elem_info_t *uinfo)
+static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = { "Mic-In", "Center/LFE Output" };
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -2359,10 +2381,10 @@
 	return 0;
 }
 
-static int snd_cmipci_mic_in_mode_get(snd_kcontrol_t *kcontrol,
-				      snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
 	/* same bit as spdi_phase */
 	spin_lock_irq(&cm->reg_lock);
 	ucontrol->value.enumerated.item[0] = 
@@ -2371,10 +2393,10 @@
 	return 0;
 }
 
-static int snd_cmipci_mic_in_mode_put(snd_kcontrol_t *kcontrol,
-				      snd_ctl_elem_value_t *ucontrol)
+static int snd_cmipci_mic_in_mode_put(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	cmipci_t *cm = snd_kcontrol_chip(kcontrol);
+	struct cmipci *cm = snd_kcontrol_chip(kcontrol);
 	int change;
 
 	spin_lock_irq(&cm->reg_lock);
@@ -2387,7 +2409,7 @@
 }
 
 /* both for CM8338/8738 */
-static snd_kcontrol_new_t snd_cmipci_mixer_switches[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_mixer_switches[] __devinitdata = {
 	DEFINE_MIXER_SWITCH("Four Channel Mode", fourch),
 	{
 		.name = "Line-In Mode",
@@ -2399,11 +2421,11 @@
 };
 
 /* for non-multichannel chips */
-static snd_kcontrol_new_t snd_cmipci_nomulti_switch __devinitdata =
+static struct snd_kcontrol_new snd_cmipci_nomulti_switch __devinitdata =
 DEFINE_MIXER_SWITCH("Exchange DAC", exchange_dac);
 
 /* only for CM8738 */
-static snd_kcontrol_new_t snd_cmipci_8738_mixer_switches[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] __devinitdata = {
 #if 0 /* controlled in pcm device */
 	DEFINE_MIXER_SWITCH("IEC958 In Record", spdif_in),
 	DEFINE_MIXER_SWITCH("IEC958 Out", spdif_out),
@@ -2425,14 +2447,14 @@
 };
 
 /* only for model 033/037 */
-static snd_kcontrol_new_t snd_cmipci_old_mixer_switches[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_old_mixer_switches[] __devinitdata = {
 	DEFINE_MIXER_SWITCH("IEC958 Mix Analog", spdif_dac_out),
 	DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase),
 	DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel1),
 };
 
 /* only for model 039 or later */
-static snd_kcontrol_new_t snd_cmipci_extra_mixer_switches[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] __devinitdata = {
 	DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel2),
 	DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase2),
 	{
@@ -2445,17 +2467,17 @@
 };
 
 /* card control switches */
-static snd_kcontrol_new_t snd_cmipci_control_switches[] __devinitdata = {
+static struct snd_kcontrol_new snd_cmipci_control_switches[] __devinitdata = {
 	// DEFINE_CARD_SWITCH("Joystick", joystick), /* now module option */
 	DEFINE_CARD_SWITCH("Modem", modem),
 };
 
 
-static int __devinit snd_cmipci_mixer_new(cmipci_t *cm, int pcm_spdif_device)
+static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
 {
-	snd_card_t *card;
-	snd_kcontrol_new_t *sw;
-	snd_kcontrol_t *kctl;
+	struct snd_card *card;
+	struct snd_kcontrol_new *sw;
+	struct snd_kcontrol *kctl;
 	unsigned int idx;
 	int err;
 
@@ -2537,8 +2559,8 @@
 	}
 
 	for (idx = 0; idx < CM_SAVED_MIXERS; idx++) {
-		snd_ctl_elem_id_t id;
-		snd_kcontrol_t *ctl;
+		struct snd_ctl_elem_id id;
+		struct snd_kcontrol *ctl;
 		memset(&id, 0, sizeof(id));
 		id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 		strcpy(id.name, cm_saved_mixer[idx].name);
@@ -2555,10 +2577,10 @@
  */
 
 #ifdef CONFIG_PROC_FS
-static void snd_cmipci_proc_read(snd_info_entry_t *entry, 
-				 snd_info_buffer_t *buffer)
+static void snd_cmipci_proc_read(struct snd_info_entry *entry, 
+				 struct snd_info_buffer *buffer)
 {
-	cmipci_t *cm = entry->private_data;
+	struct cmipci *cm = entry->private_data;
 	int i;
 	
 	snd_iprintf(buffer, "%s\n\n", cm->card->longname);
@@ -2574,15 +2596,15 @@
 	}
 }
 
-static void __devinit snd_cmipci_proc_init(cmipci_t *cm)
+static void __devinit snd_cmipci_proc_init(struct cmipci *cm)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(cm->card, "cmipci", &entry))
 		snd_info_set_text_ops(entry, cm, 1024, snd_cmipci_proc_read);
 }
 #else /* !CONFIG_PROC_FS */
-static inline void snd_cmipci_proc_init(cmipci_t *cm) {}
+static inline void snd_cmipci_proc_init(struct cmipci *cm) {}
 #endif
 
 
@@ -2600,7 +2622,7 @@
  * check chip version and capabilities
  * driver name is modified according to the chip model
  */
-static void __devinit query_chip(cmipci_t *cm)
+static void __devinit query_chip(struct cmipci *cm)
 {
 	unsigned int detect;
 
@@ -2653,7 +2675,7 @@
 }
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_cmipci_create_gameport(cmipci_t *cm, int dev)
+static int __devinit snd_cmipci_create_gameport(struct cmipci *cm, int dev)
 {
 	static int ports[] = { 0x201, 0x200, 0 }; /* FIXME: majority is 0x201? */
 	struct gameport *gp;
@@ -2699,7 +2721,7 @@
 	return 0;
 }
 
-static void snd_cmipci_free_gameport(cmipci_t *cm)
+static void snd_cmipci_free_gameport(struct cmipci *cm)
 {
 	if (cm->gameport) {
 		struct resource *r = gameport_get_port_data(cm->gameport);
@@ -2712,11 +2734,11 @@
 	}
 }
 #else
-static inline int snd_cmipci_create_gameport(cmipci_t *cm, int dev) { return -ENOSYS; }
-static inline void snd_cmipci_free_gameport(cmipci_t *cm) { }
+static inline int snd_cmipci_create_gameport(struct cmipci *cm, int dev) { return -ENOSYS; }
+static inline void snd_cmipci_free_gameport(struct cmipci *cm) { }
 #endif
 
-static int snd_cmipci_free(cmipci_t *cm)
+static int snd_cmipci_free(struct cmipci *cm)
 {
 	if (cm->irq >= 0) {
 		snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
@@ -2732,7 +2754,7 @@
 
 		synchronize_irq(cm->irq);
 
-		free_irq(cm->irq, (void *)cm);
+		free_irq(cm->irq, cm);
 	}
 
 	snd_cmipci_free_gameport(cm);
@@ -2742,17 +2764,17 @@
 	return 0;
 }
 
-static int snd_cmipci_dev_free(snd_device_t *device)
+static int snd_cmipci_dev_free(struct snd_device *device)
 {
-	cmipci_t *cm = device->device_data;
+	struct cmipci *cm = device->device_data;
 	return snd_cmipci_free(cm);
 }
 
-static int __devinit snd_cmipci_create_fm(cmipci_t *cm, long fm_port)
+static int __devinit snd_cmipci_create_fm(struct cmipci *cm, long fm_port)
 {
 	long iosynth;
 	unsigned int val;
-	opl3_t *opl3;
+	struct snd_opl3 *opl3;
 	int err;
 
 	/* first try FM regs in PCI port range */
@@ -2793,12 +2815,12 @@
 	return 0;
 }
 
-static int __devinit snd_cmipci_create(snd_card_t *card, struct pci_dev *pci,
-				       int dev, cmipci_t **rcmipci)
+static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
+				       int dev, struct cmipci **rcmipci)
 {
-	cmipci_t *cm;
+	struct cmipci *cm;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_cmipci_dev_free,
 	};
 	unsigned int val = 0;
@@ -2838,7 +2860,8 @@
 	}
 	cm->iobase = pci_resource_start(pci, 0);
 
-	if (request_irq(pci->irq, snd_cmipci_interrupt, SA_INTERRUPT|SA_SHIRQ, card->driver, (void *)cm)) {
+	if (request_irq(pci->irq, snd_cmipci_interrupt,
+			SA_INTERRUPT|SA_SHIRQ, card->driver, cm)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cmipci_free(cm);
 		return -EBUSY;
@@ -2991,8 +3014,8 @@
 				      const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	cmipci_t *cm;
+	struct snd_card *card;
+	struct cmipci *cm;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -3024,6 +3047,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = cm;
 
 	sprintf(card->shortname, "C-Media PCI %s", card->driver);
 	sprintf(card->longname, "%s (model %d) at 0x%lx, irq %i",
@@ -3051,11 +3075,93 @@
 }
 
 
+#ifdef CONFIG_PM
+/*
+ * power management
+ */
+static unsigned char saved_regs[] = {
+	CM_REG_FUNCTRL1, CM_REG_CHFORMAT, CM_REG_LEGACY_CTRL, CM_REG_MISC_CTRL,
+	CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_MIXER3, CM_REG_PLL,
+	CM_REG_CH0_FRAME1, CM_REG_CH0_FRAME2,
+	CM_REG_CH1_FRAME1, CM_REG_CH1_FRAME2, CM_REG_EXT_MISC,
+	CM_REG_INT_STATUS, CM_REG_INT_HLDCLR, CM_REG_FUNCTRL0,
+};
+
+static unsigned char saved_mixers[] = {
+	SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
+	SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
+	SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
+	SB_DSP4_CD_DEV, SB_DSP4_CD_DEV + 1,
+	SB_DSP4_LINE_DEV, SB_DSP4_LINE_DEV + 1,
+	SB_DSP4_MIC_DEV, SB_DSP4_SPEAKER_DEV,
+	CM_REG_EXTENT_IND, SB_DSP4_OUTPUT_SW,
+	SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
+};
+
+static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct cmipci *cm = card->private_data;
+	int i;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	
+	snd_pcm_suspend_all(cm->pcm);
+	snd_pcm_suspend_all(cm->pcm2);
+	snd_pcm_suspend_all(cm->pcm_spdif);
+
+	/* save registers */
+	for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
+		cm->saved_regs[i] = snd_cmipci_read(cm, saved_regs[i]);
+	for (i = 0; i < ARRAY_SIZE(saved_mixers); i++)
+		cm->saved_mixers[i] = snd_cmipci_mixer_read(cm, saved_mixers[i]);
+
+	/* disable ints */
+	snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);
+
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
+	return 0;
+}
+
+static int snd_cmipci_resume(struct pci_dev *pci)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct cmipci *cm = card->private_data;
+	int i;
+
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
+	pci_set_master(pci);
+
+	/* reset / initialize to a sane state */
+	snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0);
+	snd_cmipci_ch_reset(cm, CM_CH_PLAY);
+	snd_cmipci_ch_reset(cm, CM_CH_CAPT);
+	snd_cmipci_mixer_write(cm, 0, 0);
+
+	/* restore registers */
+	for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
+		snd_cmipci_write(cm, saved_regs[i], cm->saved_regs[i]);
+	for (i = 0; i < ARRAY_SIZE(saved_mixers); i++)
+		snd_cmipci_mixer_write(cm, saved_mixers[i], cm->saved_mixers[i]);
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif /* CONFIG_PM */
+
 static struct pci_driver driver = {
 	.name = "C-Media PCI",
 	.id_table = snd_cmipci_ids,
 	.probe = snd_cmipci_probe,
 	.remove = __devexit_p(snd_cmipci_remove),
+#ifdef CONFIG_PM
+	.suspend = snd_cmipci_suspend,
+	.resume = snd_cmipci_resume,
+#endif
 };
 	
 static int __init alsa_card_cmipci_init(void)
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 034ff37..4f65ec5 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -427,11 +427,8 @@
  *
  */
 
-typedef struct snd_cs4281 cs4281_t;
-typedef struct snd_cs4281_dma cs4281_dma_t;
-
-struct snd_cs4281_dma {
-	snd_pcm_substream_t *substream;
+struct cs4281_dma {
+	struct snd_pcm_substream *substream;
 	unsigned int regDBA;		/* offset to DBA register */
 	unsigned int regDCA;		/* offset to DCA register */
 	unsigned int regDBC;		/* offset to DBC register */
@@ -452,7 +449,7 @@
 
 #define SUSPEND_REGISTERS	20
 
-struct snd_cs4281 {
+struct cs4281 {
 	int irq;
 
 	void __iomem *ba0;		/* virtual (accessible) address */
@@ -462,18 +459,18 @@
 
 	int dual_codec;
 
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97;
-	ac97_t *ac97_secondary;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97;
+	struct snd_ac97 *ac97_secondary;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *midi_input;
-	snd_rawmidi_substream_t *midi_output;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *midi_input;
+	struct snd_rawmidi_substream *midi_output;
 
-	cs4281_dma_t dma[4];
+	struct cs4281_dma dma[4];
 
 	unsigned char src_left_play_slot;
 	unsigned char src_right_play_slot;
@@ -514,38 +511,18 @@
  *  common I/O routines
  */
 
-static void snd_cs4281_delay(unsigned int delay)
-{
-	if (delay > 999) {
-		unsigned long end_time;
-		delay = (delay * HZ) / 1000000;
-		if (delay < 1)
-			delay = 1;
-		end_time = jiffies + delay;
-		do {
-			schedule_timeout_uninterruptible(1);
-		} while (time_after_eq(end_time, jiffies));
-	} else {
-		udelay(delay);
-	}
-}
-
-static inline void snd_cs4281_delay_long(void)
-{
-	schedule_timeout_uninterruptible(1);
-}
-
-static inline void snd_cs4281_pokeBA0(cs4281_t *chip, unsigned long offset, unsigned int val)
+static inline void snd_cs4281_pokeBA0(struct cs4281 *chip, unsigned long offset,
+				      unsigned int val)
 {
         writel(val, chip->ba0 + offset);
 }
 
-static inline unsigned int snd_cs4281_peekBA0(cs4281_t *chip, unsigned long offset)
+static inline unsigned int snd_cs4281_peekBA0(struct cs4281 *chip, unsigned long offset)
 {
         return readl(chip->ba0 + offset);
 }
 
-static void snd_cs4281_ac97_write(ac97_t *ac97,
+static void snd_cs4281_ac97_write(struct snd_ac97 *ac97,
 				  unsigned short reg, unsigned short val)
 {
 	/*
@@ -555,7 +532,7 @@
 	 *  4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
 	 *  5. if DCV not cleared, break and return error
 	 */
-	cs4281_t *chip = ac97->private_data;
+	struct cs4281 *chip = ac97->private_data;
 	int count;
 
 	/*
@@ -590,15 +567,15 @@
 	snd_printk(KERN_ERR "AC'97 write problem, reg = 0x%x, val = 0x%x\n", reg, val);
 }
 
-static unsigned short snd_cs4281_ac97_read(ac97_t *ac97,
+static unsigned short snd_cs4281_ac97_read(struct snd_ac97 *ac97,
 					   unsigned short reg)
 {
-	cs4281_t *chip = ac97->private_data;
+	struct cs4281 *chip = ac97->private_data;
 	int count;
 	unsigned short result;
 	// FIXME: volatile is necessary in the following due to a bug of
 	// some gcc versions
-	volatile int ac97_num = ((volatile ac97_t *)ac97)->num;
+	volatile int ac97_num = ((volatile struct snd_ac97 *)ac97)->num;
 
 	/*
 	 *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
@@ -685,10 +662,10 @@
  *  PCM part
  */
 
-static int snd_cs4281_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_cs4281_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	cs4281_dma_t *dma = (cs4281_dma_t *)substream->runtime->private_data;
-	cs4281_t *chip = snd_pcm_substream_chip(substream);
+	struct cs4281_dma *dma = substream->runtime->private_data;
+	struct cs4281 *chip = snd_pcm_substream_chip(substream);
 
 	spin_lock(&chip->reg_lock);
 	switch (cmd) {
@@ -751,7 +728,9 @@
 	return val;
 }
 
-static void snd_cs4281_mode(cs4281_t *chip, cs4281_dma_t *dma, snd_pcm_runtime_t *runtime, int capture, int src)
+static void snd_cs4281_mode(struct cs4281 *chip, struct cs4281_dma *dma,
+			    struct snd_pcm_runtime *runtime,
+			    int capture, int src)
 {
 	int rec_mono;
 
@@ -814,22 +793,22 @@
 	snd_cs4281_pokeBA0(chip, dma->regFSIC, 0);
 }
 
-static int snd_cs4281_hw_params(snd_pcm_substream_t * substream,
-				snd_pcm_hw_params_t * hw_params)
+static int snd_cs4281_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_cs4281_hw_free(snd_pcm_substream_t * substream)
+static int snd_cs4281_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_cs4281_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_cs4281_playback_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs4281_dma_t *dma = (cs4281_dma_t *)runtime->private_data;
-	cs4281_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct cs4281_dma *dma = runtime->private_data;
+	struct cs4281 *chip = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&chip->reg_lock);
 	snd_cs4281_mode(chip, dma, runtime, 0, 1);
@@ -837,11 +816,11 @@
 	return 0;
 }
 
-static int snd_cs4281_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_cs4281_capture_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs4281_dma_t *dma = (cs4281_dma_t *)runtime->private_data;
-	cs4281_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct cs4281_dma *dma = runtime->private_data;
+	struct cs4281 *chip = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&chip->reg_lock);
 	snd_cs4281_mode(chip, dma, runtime, 1, 1);
@@ -849,18 +828,18 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_cs4281_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_cs4281_pointer(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs4281_dma_t *dma = (cs4281_dma_t *)runtime->private_data;
-	cs4281_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct cs4281_dma *dma = runtime->private_data;
+	struct cs4281 *chip = snd_pcm_substream_chip(substream);
 
 	// printk("DCC = 0x%x, buffer_size = 0x%x, jiffies = %li\n", snd_cs4281_peekBA0(chip, dma->regDCC), runtime->buffer_size, jiffies);
 	return runtime->buffer_size -
 	       snd_cs4281_peekBA0(chip, dma->regDCC) - 1;
 }
 
-static snd_pcm_hardware_t snd_cs4281_playback =
+static struct snd_pcm_hardware snd_cs4281_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_INTERLEAVED |
@@ -886,7 +865,7 @@
 	.fifo_size =		CS4281_FIFO_SIZE,
 };
 
-static snd_pcm_hardware_t snd_cs4281_capture =
+static struct snd_pcm_hardware snd_cs4281_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_INTERLEAVED |
@@ -912,11 +891,11 @@
 	.fifo_size =		CS4281_FIFO_SIZE,
 };
 
-static int snd_cs4281_playback_open(snd_pcm_substream_t * substream)
+static int snd_cs4281_playback_open(struct snd_pcm_substream *substream)
 {
-	cs4281_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs4281_dma_t *dma;
+	struct cs4281 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct cs4281_dma *dma;
 
 	dma = &chip->dma[0];
 	dma->substream = substream;
@@ -932,11 +911,11 @@
 	return 0;
 }
 
-static int snd_cs4281_capture_open(snd_pcm_substream_t * substream)
+static int snd_cs4281_capture_open(struct snd_pcm_substream *substream)
 {
-	cs4281_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs4281_dma_t *dma;
+	struct cs4281 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct cs4281_dma *dma;
 
 	dma = &chip->dma[1];
 	dma->substream = substream;
@@ -952,23 +931,23 @@
 	return 0;
 }
 
-static int snd_cs4281_playback_close(snd_pcm_substream_t * substream)
+static int snd_cs4281_playback_close(struct snd_pcm_substream *substream)
 {
-	cs4281_dma_t *dma = (cs4281_dma_t *)substream->runtime->private_data;
+	struct cs4281_dma *dma = substream->runtime->private_data;
 
 	dma->substream = NULL;
 	return 0;
 }
 
-static int snd_cs4281_capture_close(snd_pcm_substream_t * substream)
+static int snd_cs4281_capture_close(struct snd_pcm_substream *substream)
 {
-	cs4281_dma_t *dma = (cs4281_dma_t *)substream->runtime->private_data;
+	struct cs4281_dma *dma = substream->runtime->private_data;
 
 	dma->substream = NULL;
 	return 0;
 }
 
-static snd_pcm_ops_t snd_cs4281_playback_ops = {
+static struct snd_pcm_ops snd_cs4281_playback_ops = {
 	.open =		snd_cs4281_playback_open,
 	.close =	snd_cs4281_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -979,7 +958,7 @@
 	.pointer =	snd_cs4281_pointer,
 };
 
-static snd_pcm_ops_t snd_cs4281_capture_ops = {
+static struct snd_pcm_ops snd_cs4281_capture_ops = {
 	.open =		snd_cs4281_capture_open,
 	.close =	snd_cs4281_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -990,16 +969,10 @@
 	.pointer =	snd_cs4281_pointer,
 };
 
-static void snd_cs4281_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_cs4281_pcm(struct cs4281 * chip, int device,
+				    struct snd_pcm ** rpcm)
 {
-	cs4281_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_cs4281_pcm(cs4281_t * chip, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1012,7 +985,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs4281_capture_ops);
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_cs4281_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "CS4281");
 	chip->pcm = pcm;
@@ -1031,7 +1003,8 @@
 
 #define CS_VOL_MASK	0x1f
 
-static int snd_cs4281_info_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_cs4281_info_volume(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type              = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count             = 2;
@@ -1040,9 +1013,10 @@
 	return 0;
 }
  
-static int snd_cs4281_get_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4281_get_volume(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	cs4281_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cs4281 *chip = snd_kcontrol_chip(kcontrol);
 	int regL = (kcontrol->private_value >> 16) & 0xffff;
 	int regR = kcontrol->private_value & 0xffff;
 	int volL, volR;
@@ -1055,9 +1029,10 @@
 	return 0;
 }
 
-static int snd_cs4281_put_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	cs4281_t *chip = snd_kcontrol_chip(kcontrol);
+	struct cs4281 *chip = snd_kcontrol_chip(kcontrol);
 	int change = 0;
 	int regL = (kcontrol->private_value >> 16) & 0xffff;
 	int regR = kcontrol->private_value & 0xffff;
@@ -1079,7 +1054,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_cs4281_fm_vol = 
+static struct snd_kcontrol_new snd_cs4281_fm_vol = 
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Synth Playback Volume",
@@ -1089,7 +1064,7 @@
 	.private_value = ((BA0_FMLVC << 16) | BA0_FMRVC),
 };
 
-static snd_kcontrol_new_t snd_cs4281_pcm_vol = 
+static struct snd_kcontrol_new snd_cs4281_pcm_vol = 
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PCM Stream Playback Volume",
@@ -1099,27 +1074,27 @@
 	.private_value = ((BA0_PPLVC << 16) | BA0_PPRVC),
 };
 
-static void snd_cs4281_mixer_free_ac97_bus(ac97_bus_t *bus)
+static void snd_cs4281_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
 {
-	cs4281_t *chip = bus->private_data;
+	struct cs4281 *chip = bus->private_data;
 	chip->ac97_bus = NULL;
 }
 
-static void snd_cs4281_mixer_free_ac97(ac97_t *ac97)
+static void snd_cs4281_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	cs4281_t *chip = ac97->private_data;
+	struct cs4281 *chip = ac97->private_data;
 	if (ac97->num)
 		chip->ac97_secondary = NULL;
 	else
 		chip->ac97 = NULL;
 }
 
-static int __devinit snd_cs4281_mixer(cs4281_t * chip)
+static int __devinit snd_cs4281_mixer(struct cs4281 * chip)
 {
-	snd_card_t *card = chip->card;
-	ac97_template_t ac97;
+	struct snd_card *card = chip->card;
+	struct snd_ac97_template ac97;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_cs4281_ac97_write,
 		.read = snd_cs4281_ac97_read,
 	};
@@ -1150,22 +1125,23 @@
  * proc interface
  */
 
-static void snd_cs4281_proc_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_cs4281_proc_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
-	cs4281_t *chip = entry->private_data;
+	struct cs4281 *chip = entry->private_data;
 
 	snd_iprintf(buffer, "Cirrus Logic CS4281\n\n");
 	snd_iprintf(buffer, "Spurious half IRQs   : %u\n", chip->spurious_dhtc_irq);
 	snd_iprintf(buffer, "Spurious end IRQs    : %u\n", chip->spurious_dtc_irq);
 }
 
-static long snd_cs4281_BA0_read(snd_info_entry_t *entry, void *file_private_data,
+static long snd_cs4281_BA0_read(struct snd_info_entry *entry,
+				void *file_private_data,
 				struct file *file, char __user *buf,
 				unsigned long count, unsigned long pos)
 {
 	long size;
-	cs4281_t *chip = entry->private_data;
+	struct cs4281 *chip = entry->private_data;
 	
 	size = count;
 	if (pos + size > CS4281_BA0_SIZE)
@@ -1177,12 +1153,13 @@
 	return size;
 }
 
-static long snd_cs4281_BA1_read(snd_info_entry_t *entry, void *file_private_data,
+static long snd_cs4281_BA1_read(struct snd_info_entry *entry,
+				void *file_private_data,
 				struct file *file, char __user *buf,
 				unsigned long count, unsigned long pos)
 {
 	long size;
-	cs4281_t *chip = entry->private_data;
+	struct cs4281 *chip = entry->private_data;
 	
 	size = count;
 	if (pos + size > CS4281_BA1_SIZE)
@@ -1202,9 +1179,9 @@
 	.read = snd_cs4281_BA1_read,
 };
 
-static void __devinit snd_cs4281_proc_init(cs4281_t * chip)
+static void __devinit snd_cs4281_proc_init(struct cs4281 * chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(chip->card, "cs4281", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, snd_cs4281_proc_read);
@@ -1230,7 +1207,7 @@
 
 static void snd_cs4281_gameport_trigger(struct gameport *gameport)
 {
-	cs4281_t *chip = gameport_get_port_data(gameport);
+	struct cs4281 *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return);
 	snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff);
@@ -1238,16 +1215,17 @@
 
 static unsigned char snd_cs4281_gameport_read(struct gameport *gameport)
 {
-	cs4281_t *chip = gameport_get_port_data(gameport);
+	struct cs4281 *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return 0);
 	return snd_cs4281_peekBA0(chip, BA0_JSPT);
 }
 
 #ifdef COOKED_MODE
-static int snd_cs4281_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
+static int snd_cs4281_gameport_cooked_read(struct gameport *gameport,
+					   int *axes, int *buttons)
 {
-	cs4281_t *chip = gameport_get_port_data(gameport);
+	struct cs4281 *chip = gameport_get_port_data(gameport);
 	unsigned js1, js2, jst;
 	
 	snd_assert(chip, return 0);
@@ -1286,7 +1264,7 @@
 	return 0;
 }
 
-static int __devinit snd_cs4281_create_gameport(cs4281_t *chip)
+static int __devinit snd_cs4281_create_gameport(struct cs4281 *chip)
 {
 	struct gameport *gp;
 
@@ -1313,7 +1291,7 @@
 	return 0;
 }
 
-static void snd_cs4281_free_gameport(cs4281_t *chip)
+static void snd_cs4281_free_gameport(struct cs4281 *chip)
 {
 	if (chip->gameport) {
 		gameport_unregister_port(chip->gameport);
@@ -1321,11 +1299,11 @@
 	}
 }
 #else
-static inline int snd_cs4281_create_gameport(cs4281_t *chip) { return -ENOSYS; }
-static inline void snd_cs4281_free_gameport(cs4281_t *chip) { }
+static inline int snd_cs4281_create_gameport(struct cs4281 *chip) { return -ENOSYS; }
+static inline void snd_cs4281_free_gameport(struct cs4281 *chip) { }
 #endif /* CONFIG_GAMEPORT || (MODULE && CONFIG_GAMEPORT_MODULE) */
 
-static int snd_cs4281_free(cs4281_t *chip)
+static int snd_cs4281_free(struct cs4281 *chip)
 {
 	snd_cs4281_free_gameport(chip);
 
@@ -1342,7 +1320,7 @@
 	pci_set_power_state(chip->pci, 3);
 
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	if (chip->ba0)
 		iounmap(chip->ba0);
 	if (chip->ba1)
@@ -1354,27 +1332,23 @@
 	return 0;
 }
 
-static int snd_cs4281_dev_free(snd_device_t *device)
+static int snd_cs4281_dev_free(struct snd_device *device)
 {
-	cs4281_t *chip = device->device_data;
+	struct cs4281 *chip = device->device_data;
 	return snd_cs4281_free(chip);
 }
 
-static int snd_cs4281_chip_init(cs4281_t *chip); /* defined below */
-#ifdef CONFIG_PM
-static int cs4281_suspend(snd_card_t *card, pm_message_t state);
-static int cs4281_resume(snd_card_t *card);
-#endif
+static int snd_cs4281_chip_init(struct cs4281 *chip); /* defined below */
 
-static int __devinit snd_cs4281_create(snd_card_t * card,
+static int __devinit snd_cs4281_create(struct snd_card *card,
 				       struct pci_dev *pci,
-				       cs4281_t ** rchip,
+				       struct cs4281 ** rchip,
 				       int dual_codec)
 {
-	cs4281_t *chip;
+	struct cs4281 *chip;
 	unsigned int tmp;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_cs4281_dev_free,
 	};
 
@@ -1405,7 +1379,8 @@
 	chip->ba0_addr = pci_resource_start(pci, 0);
 	chip->ba1_addr = pci_resource_start(pci, 1);
 
-	if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS4281", (void *)chip)) {
+	if (request_irq(pci->irq, snd_cs4281_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			"CS4281", chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cs4281_free(chip);
 		return -ENOMEM;
@@ -1432,15 +1407,13 @@
 
 	snd_cs4281_proc_init(chip);
 
-	snd_card_set_pm_callback(card, cs4281_suspend, cs4281_resume, chip);
-
 	snd_card_set_dev(card, &pci->dev);
 
 	*rchip = chip;
 	return 0;
 }
 
-static int snd_cs4281_chip_init(cs4281_t *chip)
+static int snd_cs4281_chip_init(struct cs4281 *chip)
 {
 	unsigned int tmp;
 	int timeout;
@@ -1501,7 +1474,7 @@
 	snd_cs4281_pokeBA0(chip, BA0_SPMC, 0);
 	udelay(50);
 	snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN);
-	snd_cs4281_delay(50000);
+	msleep(50);
 
 	if (chip->dual_codec)
 		snd_cs4281_pokeBA0(chip, BA0_SPMC, BA0_SPMC_RSTN | BA0_SPMC_ASDI2E);
@@ -1517,13 +1490,13 @@
 	 *  Start the DLL Clock logic.
 	 */
 	snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_DLLP);
-	snd_cs4281_delay(50000);
+	msleep(50);
 	snd_cs4281_pokeBA0(chip, BA0_CLKCR1, BA0_CLKCR1_SWCE | BA0_CLKCR1_DLLP);
 
 	/*
 	 * Wait for the DLL ready signal from the clock logic.
 	 */
-	timeout = HZ;
+	timeout = 100;
 	do {
 		/*
 		 *  Read the AC97 status register to see if we've seen a CODEC
@@ -1531,7 +1504,7 @@
 		 */
 		if (snd_cs4281_peekBA0(chip, BA0_CLKCR1) & BA0_CLKCR1_DLLRDY)
 			goto __ok0;
-		snd_cs4281_delay_long();
+		msleep(1);
 	} while (timeout-- > 0);
 
 	snd_printk(KERN_ERR "DLLRDY not seen\n");
@@ -1549,7 +1522,7 @@
 	/*
 	 * Wait for the codec ready signal from the AC97 codec.
 	 */
-	timeout = HZ;
+	timeout = 100;
 	do {
 		/*
 		 *  Read the AC97 status register to see if we've seen a CODEC
@@ -1557,7 +1530,7 @@
 		 */
 		if (snd_cs4281_peekBA0(chip, BA0_ACSTS) & BA0_ACSTS_CRDY)
 			goto __ok1;
-		snd_cs4281_delay_long();
+		msleep(1);
 	} while (timeout-- > 0);
 
 	snd_printk(KERN_ERR "never read codec ready from AC'97 (0x%x)\n", snd_cs4281_peekBA0(chip, BA0_ACSTS));
@@ -1565,11 +1538,11 @@
 
       __ok1:
 	if (chip->dual_codec) {
-		timeout = HZ;
+		timeout = 100;
 		do {
 			if (snd_cs4281_peekBA0(chip, BA0_ACSTS2) & BA0_ACSTS_CRDY)
 				goto __codec2_ok;
-			snd_cs4281_delay_long();
+			msleep(1);
 		} while (timeout-- > 0);
 		snd_printk(KERN_INFO "secondary codec doesn't respond. disable it...\n");
 		chip->dual_codec = 0;
@@ -1588,7 +1561,7 @@
 	 *  the codec is pumping ADC data across the AC-link.
 	 */
 
-	timeout = HZ;
+	timeout = 100;
 	do {
 		/*
 		 *  Read the input slot valid register and see if input slots 3
@@ -1596,7 +1569,7 @@
 		 */
                 if ((snd_cs4281_peekBA0(chip, BA0_ACISV) & (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4))) == (BA0_ACISV_SLV(3) | BA0_ACISV_SLV(4)))
                         goto __ok2;
-		snd_cs4281_delay_long();
+		msleep(1);
 	} while (timeout-- > 0);
 
 	if (--retry_count > 0)
@@ -1616,7 +1589,7 @@
 	 *  Initialize DMA structures
 	 */
 	for (tmp = 0; tmp < 4; tmp++) {
-		cs4281_dma_t *dma = &chip->dma[tmp];
+		struct cs4281_dma *dma = &chip->dma[tmp];
 		dma->regDBA = BA0_DBA0 + (tmp * 0x10);
 		dma->regDCA = BA0_DCA0 + (tmp * 0x10);
 		dma->regDBC = BA0_DBC0 + (tmp * 0x10);
@@ -1673,16 +1646,16 @@
  *  MIDI section
  */
 
-static void snd_cs4281_midi_reset(cs4281_t *chip)
+static void snd_cs4281_midi_reset(struct cs4281 *chip)
 {
 	snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr | BA0_MIDCR_MRST);
 	udelay(100);
 	snd_cs4281_pokeBA0(chip, BA0_MIDCR, chip->midcr);
 }
 
-static int snd_cs4281_midi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_cs4281_midi_input_open(struct snd_rawmidi_substream *substream)
 {
-	cs4281_t *chip = substream->rmidi->private_data;
+	struct cs4281 *chip = substream->rmidi->private_data;
 
 	spin_lock_irq(&chip->reg_lock);
  	chip->midcr |= BA0_MIDCR_RXE;
@@ -1696,9 +1669,9 @@
 	return 0;
 }
 
-static int snd_cs4281_midi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_cs4281_midi_input_close(struct snd_rawmidi_substream *substream)
 {
-	cs4281_t *chip = substream->rmidi->private_data;
+	struct cs4281 *chip = substream->rmidi->private_data;
 
 	spin_lock_irq(&chip->reg_lock);
 	chip->midcr &= ~(BA0_MIDCR_RXE | BA0_MIDCR_RIE);
@@ -1713,9 +1686,9 @@
 	return 0;
 }
 
-static int snd_cs4281_midi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_cs4281_midi_output_open(struct snd_rawmidi_substream *substream)
 {
-	cs4281_t *chip = substream->rmidi->private_data;
+	struct cs4281 *chip = substream->rmidi->private_data;
 
 	spin_lock_irq(&chip->reg_lock);
 	chip->uartm |= CS4281_MODE_OUTPUT;
@@ -1730,9 +1703,9 @@
 	return 0;
 }
 
-static int snd_cs4281_midi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_cs4281_midi_output_close(struct snd_rawmidi_substream *substream)
 {
-	cs4281_t *chip = substream->rmidi->private_data;
+	struct cs4281 *chip = substream->rmidi->private_data;
 
 	spin_lock_irq(&chip->reg_lock);
 	chip->midcr &= ~(BA0_MIDCR_TXE | BA0_MIDCR_TIE);
@@ -1747,10 +1720,10 @@
 	return 0;
 }
 
-static void snd_cs4281_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_cs4281_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	cs4281_t *chip = substream->rmidi->private_data;
+	struct cs4281 *chip = substream->rmidi->private_data;
 
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	if (up) {
@@ -1767,10 +1740,10 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static void snd_cs4281_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_cs4281_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	cs4281_t *chip = substream->rmidi->private_data;
+	struct cs4281 *chip = substream->rmidi->private_data;
 	unsigned char byte;
 
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -1797,23 +1770,24 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static snd_rawmidi_ops_t snd_cs4281_midi_output =
+static struct snd_rawmidi_ops snd_cs4281_midi_output =
 {
 	.open =		snd_cs4281_midi_output_open,
 	.close =	snd_cs4281_midi_output_close,
 	.trigger =	snd_cs4281_midi_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_cs4281_midi_input =
+static struct snd_rawmidi_ops snd_cs4281_midi_input =
 {
 	.open = 	snd_cs4281_midi_input_open,
 	.close =	snd_cs4281_midi_input_close,
 	.trigger =	snd_cs4281_midi_input_trigger,
 };
 
-static int __devinit snd_cs4281_midi(cs4281_t * chip, int device, snd_rawmidi_t **rrawmidi)
+static int __devinit snd_cs4281_midi(struct cs4281 * chip, int device,
+				     struct snd_rawmidi **rrawmidi)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	if (rrawmidi)
@@ -1837,9 +1811,9 @@
 
 static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	cs4281_t *chip = dev_id;
+	struct cs4281 *chip = dev_id;
 	unsigned int status, dma, val;
-	cs4281_dma_t *cdma;
+	struct cs4281_dma *cdma;
 
 	if (chip == NULL)
 		return IRQ_NONE;
@@ -1909,10 +1883,11 @@
 /*
  * OPL3 command
  */
-static void snd_cs4281_opl3_command(opl3_t * opl3, unsigned short cmd, unsigned char val)
+static void snd_cs4281_opl3_command(struct snd_opl3 *opl3, unsigned short cmd,
+				    unsigned char val)
 {
 	unsigned long flags;
-	cs4281_t *chip = opl3->private_data;
+	struct cs4281 *chip = opl3->private_data;
 	void __iomem *port;
 
 	if (cmd & OPL3_RIGHT)
@@ -1935,9 +1910,9 @@
 				      const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	cs4281_t *chip;
-	opl3_t *opl3;
+	struct snd_card *card;
+	struct cs4281 *chip;
+	struct snd_opl3 *opl3;
 	int err;
 
         if (dev >= SNDRV_CARDS)
@@ -1955,6 +1930,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 
 	if ((err = snd_cs4281_mixer(chip)) < 0) {
 		snd_card_free(card);
@@ -2026,18 +2002,18 @@
 
 #define CLKCR1_CKRA                             0x00010000L
 
-static int cs4281_suspend(snd_card_t *card, pm_message_t state)
+static int cs4281_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	cs4281_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct cs4281 *chip = card->private_data;
 	u32 ulCLK;
 	unsigned int i;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 
-	if (chip->ac97)
-		snd_ac97_suspend(chip->ac97);
-	if (chip->ac97_secondary)
-		snd_ac97_suspend(chip->ac97_secondary);
+	snd_ac97_suspend(chip->ac97);
+	snd_ac97_suspend(chip->ac97_secondary);
 
 	ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
 	ulCLK |= CLKCR1_CKRA;
@@ -2067,18 +2043,21 @@
 	ulCLK &= ~CLKCR1_CKRA;
 	snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
 
-	pci_disable_device(chip->pci);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int cs4281_resume(snd_card_t *card)
+static int cs4281_resume(struct pci_dev *pci)
 {
-	cs4281_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct cs4281 *chip = card->private_data;
 	unsigned int i;
 	u32 ulCLK;
 
-	pci_enable_device(chip->pci);
-	pci_set_master(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci);
 
 	ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
 	ulCLK |= CLKCR1_CKRA;
@@ -2091,15 +2070,14 @@
 		if (saved_regs[i])
 			snd_cs4281_pokeBA0(chip, saved_regs[i], chip->suspend_regs[i]);
 
-	if (chip->ac97)
-		snd_ac97_resume(chip->ac97);
-	if (chip->ac97_secondary)
-		snd_ac97_resume(chip->ac97_secondary);
+	snd_ac97_resume(chip->ac97);
+	snd_ac97_resume(chip->ac97_secondary);
 
 	ulCLK = snd_cs4281_peekBA0(chip, BA0_CLKCR1);
 	ulCLK &= ~CLKCR1_CKRA;
 	snd_cs4281_pokeBA0(chip, BA0_CLKCR1, ulCLK);
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -2109,7 +2087,10 @@
 	.id_table = snd_cs4281_ids,
 	.probe = snd_cs4281_probe,
 	.remove = __devexit_p(snd_cs4281_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = cs4281_suspend,
+	.resume = cs4281_resume,
+#endif
 };
 	
 static int __init alsa_card_cs4281_init(void)
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index b9fff4e..c590602 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -78,8 +78,8 @@
 					   const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	cs46xx_t *chip;
+	struct snd_card *card;
+	struct snd_cs46xx *chip;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -98,6 +98,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 	chip->accept_valid = mmap_valid[dev];
 	if ((err = snd_cs46xx_pcm(chip, 0, NULL)) < 0) {
 		snd_card_free(card);
@@ -166,7 +167,10 @@
 	.id_table = snd_cs46xx_ids,
 	.probe = snd_card_cs46xx_probe,
 	.remove = __devexit_p(snd_card_cs46xx_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = snd_cs46xx_suspend,
+	.resume = snd_cs46xx_resume,
+#endif
 };
 
 static int __init alsa_card_cs46xx_init(void)
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 9b8af5b..8fb275d 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -66,23 +66,23 @@
 #include "cs46xx_lib.h"
 #include "dsp_spos.h"
 
-static void amp_voyetra(cs46xx_t *chip, int change);
+static void amp_voyetra(struct snd_cs46xx *chip, int change);
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-static snd_pcm_ops_t snd_cs46xx_playback_rear_ops;
-static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops;
-static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops;
-static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops;
-static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops;
-static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops;
+static struct snd_pcm_ops snd_cs46xx_playback_rear_ops;
+static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops;
+static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops;
+static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops;
+static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops;
+static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops;
 #endif
 
-static snd_pcm_ops_t snd_cs46xx_playback_ops;
-static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops;
-static snd_pcm_ops_t snd_cs46xx_capture_ops;
-static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops;
+static struct snd_pcm_ops snd_cs46xx_playback_ops;
+static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops;
+static struct snd_pcm_ops snd_cs46xx_capture_ops;
+static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops;
 
-static unsigned short snd_cs46xx_codec_read(cs46xx_t *chip,
+static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip,
 					    unsigned short reg,
 					    int codec_index)
 {
@@ -204,10 +204,10 @@
 	return result;
 }
 
-static unsigned short snd_cs46xx_ac97_read(ac97_t * ac97,
+static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97,
 					    unsigned short reg)
 {
-	cs46xx_t *chip = ac97->private_data;
+	struct snd_cs46xx *chip = ac97->private_data;
 	unsigned short val;
 	int codec_index = ac97->num;
 
@@ -221,7 +221,7 @@
 }
 
 
-static void snd_cs46xx_codec_write(cs46xx_t *chip,
+static void snd_cs46xx_codec_write(struct snd_cs46xx *chip,
 				   unsigned short reg,
 				   unsigned short val,
 				   int codec_index)
@@ -286,11 +286,11 @@
 	chip->active_ctrl(chip, -1);
 }
 
-static void snd_cs46xx_ac97_write(ac97_t *ac97,
+static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97,
 				   unsigned short reg,
 				   unsigned short val)
 {
-	cs46xx_t *chip = ac97->private_data;
+	struct snd_cs46xx *chip = ac97->private_data;
 	int codec_index = ac97->num;
 
 	snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX ||
@@ -305,7 +305,7 @@
  *  Chip initialization
  */
 
-int snd_cs46xx_download(cs46xx_t *chip,
+int snd_cs46xx_download(struct snd_cs46xx *chip,
 			u32 *src,
                         unsigned long offset,
                         unsigned long len)
@@ -334,7 +334,7 @@
 #include "imgs/cwcbinhack.h"
 #include "imgs/cwcdma.h"
 
-int snd_cs46xx_clear_BA1(cs46xx_t *chip,
+int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip,
                          unsigned long offset,
                          unsigned long len) 
 {
@@ -358,7 +358,7 @@
 
 #include "cs46xx_image.h"
 
-int snd_cs46xx_download_image(cs46xx_t *chip)
+int snd_cs46xx_download_image(struct snd_cs46xx *chip)
 {
 	int idx, err;
 	unsigned long offset = 0;
@@ -379,7 +379,7 @@
  *  Chip reset
  */
 
-static void snd_cs46xx_reset(cs46xx_t *chip)
+static void snd_cs46xx_reset(struct snd_cs46xx *chip)
 {
 	int idx;
 
@@ -408,7 +408,7 @@
 	snd_cs46xx_poke(chip, BA1_FRMT, 0xadf);
 }
 
-static int cs46xx_wait_for_fifo(cs46xx_t * chip,int retry_timeout) 
+static int cs46xx_wait_for_fifo(struct snd_cs46xx * chip,int retry_timeout) 
 {
 	u32 i, status = 0;
 	/*
@@ -432,7 +432,7 @@
 	return 0;
 }
 
-static void snd_cs46xx_clear_serial_FIFOs(cs46xx_t *chip)
+static void snd_cs46xx_clear_serial_FIFOs(struct snd_cs46xx *chip)
 {
 	int idx, powerdown = 0;
 	unsigned int tmp;
@@ -486,7 +486,7 @@
 		snd_cs46xx_pokeBA0(chip, BA0_CLKCR1, tmp);
 }
 
-static void snd_cs46xx_proc_start(cs46xx_t *chip)
+static void snd_cs46xx_proc_start(struct snd_cs46xx *chip)
 {
 	int cnt;
 
@@ -513,7 +513,7 @@
 		snd_printk(KERN_ERR "SPCR_RUNFR never reset\n");
 }
 
-static void snd_cs46xx_proc_stop(cs46xx_t *chip)
+static void snd_cs46xx_proc_stop(struct snd_cs46xx *chip)
 {
 	/*
 	 *  Turn off the run, run at frame, and DMA enable bits in the local copy of
@@ -528,7 +528,7 @@
 
 #define GOF_PER_SEC 200
 
-static void snd_cs46xx_set_play_sample_rate(cs46xx_t *chip, unsigned int rate)
+static void snd_cs46xx_set_play_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
 {
 	unsigned long flags;
 	unsigned int tmp1, tmp2;
@@ -574,7 +574,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static void snd_cs46xx_set_capture_sample_rate(cs46xx_t *chip, unsigned int rate)
+static void snd_cs46xx_set_capture_sample_rate(struct snd_cs46xx *chip, unsigned int rate)
 {
 	unsigned long flags;
 	unsigned int phiIncr, coeffIncr, tmp1, tmp2;
@@ -684,43 +684,43 @@
  *  PCM part
  */
 
-static void snd_cs46xx_pb_trans_copy(snd_pcm_substream_t *substream,
-				     snd_pcm_indirect_t *rec, size_t bytes)
+static void snd_cs46xx_pb_trans_copy(struct snd_pcm_substream *substream,
+				     struct snd_pcm_indirect *rec, size_t bytes)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs46xx_pcm_t * cpcm = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_cs46xx_pcm * cpcm = runtime->private_data;
 	memcpy(cpcm->hw_buf.area + rec->hw_data, runtime->dma_area + rec->sw_data, bytes);
 }
 
-static int snd_cs46xx_playback_transfer(snd_pcm_substream_t *substream)
+static int snd_cs46xx_playback_transfer(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs46xx_pcm_t * cpcm = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_cs46xx_pcm * cpcm = runtime->private_data;
 	snd_pcm_indirect_playback_transfer(substream, &cpcm->pcm_rec, snd_cs46xx_pb_trans_copy);
 	return 0;
 }
 
-static void snd_cs46xx_cp_trans_copy(snd_pcm_substream_t *substream,
-				     snd_pcm_indirect_t *rec, size_t bytes)
+static void snd_cs46xx_cp_trans_copy(struct snd_pcm_substream *substream,
+				     struct snd_pcm_indirect *rec, size_t bytes)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	memcpy(runtime->dma_area + rec->sw_data,
 	       chip->capt.hw_buf.area + rec->hw_data, bytes);
 }
 
-static int snd_cs46xx_capture_transfer(snd_pcm_substream_t *substream)
+static int snd_cs46xx_capture_transfer(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 	snd_pcm_indirect_capture_transfer(substream, &chip->capt.pcm_rec, snd_cs46xx_cp_trans_copy);
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
-	cs46xx_pcm_t *cpcm = substream->runtime->private_data;
+	struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
 	snd_assert (cpcm->pcm_channel,return -ENXIO);
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -732,11 +732,11 @@
 	return ptr >> cpcm->shift;
 }
 
-static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
-	cs46xx_pcm_t *cpcm = substream->runtime->private_data;
+	struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	snd_assert (cpcm->pcm_channel,return -ENXIO);
@@ -748,29 +748,29 @@
 	return snd_pcm_indirect_playback_pointer(substream, &cpcm->pcm_rec, ptr);
 }
 
-static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_cs46xx_capture_direct_pointer(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 	size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
 	return ptr >> chip->capt.shift;
 }
 
-static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_cs46xx_capture_indirect_pointer(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 	size_t ptr = snd_cs46xx_peek(chip, BA1_CBA) - chip->capt.hw_buf.addr;
 	return snd_pcm_indirect_capture_pointer(substream, &chip->capt.pcm_rec, ptr);
 }
 
-static int snd_cs46xx_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_cs46xx_playback_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
-	/*snd_pcm_runtime_t *runtime = substream->runtime;*/
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
+	/*struct snd_pcm_runtime *runtime = substream->runtime;*/
 	int result = 0;
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-	cs46xx_pcm_t *cpcm = substream->runtime->private_data;
+	struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data;
 	if (! cpcm->pcm_channel) {
 		return -ENXIO;
 	}
@@ -827,10 +827,10 @@
 	return result;
 }
 
-static int snd_cs46xx_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_cs46xx_capture_trigger(struct snd_pcm_substream *substream,
 				      int cmd)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 	unsigned int tmp;
 	int result = 0;
 
@@ -858,7 +858,7 @@
 }
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-static int _cs46xx_adjust_sample_rate (cs46xx_t *chip, cs46xx_pcm_t *cpcm,
+static int _cs46xx_adjust_sample_rate (struct snd_cs46xx *chip, struct snd_cs46xx_pcm *cpcm,
 				       int sample_rate) 
 {
 
@@ -893,14 +893,14 @@
 #endif
 
 
-static int snd_cs46xx_playback_hw_params(snd_pcm_substream_t * substream,
-					 snd_pcm_hw_params_t * hw_params)
+static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs46xx_pcm_t *cpcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_cs46xx_pcm *cpcm;
 	int err;
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 	int sample_rate = params_rate(hw_params);
 	int period_size = params_period_bytes(hw_params);
 #endif
@@ -995,11 +995,11 @@
 	return 0;
 }
 
-static int snd_cs46xx_playback_hw_free(snd_pcm_substream_t * substream)
+static int snd_cs46xx_playback_hw_free(struct snd_pcm_substream *substream)
 {
-	/*cs46xx_t *chip = snd_pcm_substream_chip(substream);*/
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs46xx_pcm_t *cpcm;
+	/*struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);*/
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_cs46xx_pcm *cpcm;
 
 	cpcm = runtime->private_data;
 
@@ -1017,13 +1017,13 @@
 	return 0;
 }
 
-static int snd_cs46xx_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream)
 {
 	unsigned int tmp;
 	unsigned int pfie;
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs46xx_pcm_t *cpcm;
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_cs46xx_pcm *cpcm;
 
 	cpcm = runtime->private_data;
 
@@ -1087,11 +1087,11 @@
 	return 0;
 }
 
-static int snd_cs46xx_capture_hw_params(snd_pcm_substream_t * substream,
-					snd_pcm_hw_params_t * hw_params)
+static int snd_cs46xx_capture_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -1118,10 +1118,10 @@
 	return 0;
 }
 
-static int snd_cs46xx_capture_hw_free(snd_pcm_substream_t * substream)
+static int snd_cs46xx_capture_hw_free(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (runtime->dma_area != chip->capt.hw_buf.area)
 		snd_pcm_lib_free_pages(substream);
@@ -1132,10 +1132,10 @@
 	return 0;
 }
 
-static int snd_cs46xx_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_cs46xx_capture_prepare(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_cs46xx_poke(chip, BA1_CBA, chip->capt.hw_buf.addr);
 	chip->capt.shift = 2;
@@ -1149,13 +1149,13 @@
 
 static irqreturn_t snd_cs46xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	cs46xx_t *chip = dev_id;
+	struct snd_cs46xx *chip = dev_id;
 	u32 status1;
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	u32 status2;
 	int i;
-	cs46xx_pcm_t *cpcm = NULL;
+	struct snd_cs46xx_pcm *cpcm = NULL;
 #endif
 
 	/*
@@ -1239,7 +1239,7 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_hardware_t snd_cs46xx_playback =
+static struct snd_pcm_hardware snd_cs46xx_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_INTERLEAVED | 
@@ -1261,7 +1261,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_cs46xx_capture =
+static struct snd_pcm_hardware snd_cs46xx_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_INTERLEAVED |
@@ -1285,7 +1285,7 @@
 
 static unsigned int period_sizes[] = { 32, 64, 128, 256, 512, 1024, 2048 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {
+static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
 	.count = ARRAY_SIZE(period_sizes),
 	.list = period_sizes,
 	.mask = 0
@@ -1293,16 +1293,16 @@
 
 #endif
 
-static void snd_cs46xx_pcm_free_substream(snd_pcm_runtime_t *runtime)
+static void snd_cs46xx_pcm_free_substream(struct snd_pcm_runtime *runtime)
 {
 	kfree(runtime->private_data);
 }
 
-static int _cs46xx_playback_open_channel (snd_pcm_substream_t * substream,int pcm_channel_id)
+static int _cs46xx_playback_open_channel (struct snd_pcm_substream *substream,int pcm_channel_id)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
-	cs46xx_pcm_t * cpcm;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx_pcm * cpcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	cpcm = kzalloc(sizeof(*cpcm), GFP_KERNEL);
 	if (cpcm == NULL)
@@ -1340,30 +1340,30 @@
 	return 0;
 }
 
-static int snd_cs46xx_playback_open(snd_pcm_substream_t * substream)
+static int snd_cs46xx_playback_open(struct snd_pcm_substream *substream)
 {
 	snd_printdd("open front channel\n");
 	return _cs46xx_playback_open_channel(substream,DSP_PCM_MAIN_CHANNEL);
 }
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-static int snd_cs46xx_playback_open_rear(snd_pcm_substream_t * substream)
+static int snd_cs46xx_playback_open_rear(struct snd_pcm_substream *substream)
 {
 	snd_printdd("open rear channel\n");
 
 	return _cs46xx_playback_open_channel(substream,DSP_PCM_REAR_CHANNEL);
 }
 
-static int snd_cs46xx_playback_open_clfe(snd_pcm_substream_t * substream)
+static int snd_cs46xx_playback_open_clfe(struct snd_pcm_substream *substream)
 {
 	snd_printdd("open center - LFE channel\n");
 
 	return _cs46xx_playback_open_channel(substream,DSP_PCM_CENTER_LFE_CHANNEL);
 }
 
-static int snd_cs46xx_playback_open_iec958(snd_pcm_substream_t * substream)
+static int snd_cs46xx_playback_open_iec958(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 
 	snd_printdd("open raw iec958 channel\n");
 
@@ -1374,12 +1374,12 @@
 	return _cs46xx_playback_open_channel(substream,DSP_IEC958_CHANNEL);
 }
 
-static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream);
+static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream);
 
-static int snd_cs46xx_playback_close_iec958(snd_pcm_substream_t * substream)
+static int snd_cs46xx_playback_close_iec958(struct snd_pcm_substream *substream)
 {
 	int err;
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
   
 	snd_printdd("close raw iec958 channel\n");
 
@@ -1393,9 +1393,9 @@
 }
 #endif
 
-static int snd_cs46xx_capture_open(snd_pcm_substream_t * substream)
+static int snd_cs46xx_capture_open(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
 				PAGE_SIZE, &chip->capt.hw_buf) < 0)
@@ -1416,11 +1416,11 @@
 	return 0;
 }
 
-static int snd_cs46xx_playback_close(snd_pcm_substream_t * substream)
+static int snd_cs46xx_playback_close(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	cs46xx_pcm_t * cpcm;
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_cs46xx_pcm * cpcm;
 
 	cpcm = runtime->private_data;
 
@@ -1445,9 +1445,9 @@
 	return 0;
 }
 
-static int snd_cs46xx_capture_close(snd_pcm_substream_t * substream)
+static int snd_cs46xx_capture_close(struct snd_pcm_substream *substream)
 {
-	cs46xx_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs46xx *chip = snd_pcm_substream_chip(substream);
 
 	chip->capt.substream = NULL;
 	snd_dma_free_pages(&chip->capt.hw_buf);
@@ -1457,7 +1457,7 @@
 }
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-static snd_pcm_ops_t snd_cs46xx_playback_rear_ops = {
+static struct snd_pcm_ops snd_cs46xx_playback_rear_ops = {
 	.open =			snd_cs46xx_playback_open_rear,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1468,7 +1468,7 @@
 	.pointer =		snd_cs46xx_playback_direct_pointer,
 };
 
-static snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops = {
+static struct snd_pcm_ops snd_cs46xx_playback_indirect_rear_ops = {
 	.open =			snd_cs46xx_playback_open_rear,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1480,7 +1480,7 @@
 	.ack =			snd_cs46xx_playback_transfer,
 };
 
-static snd_pcm_ops_t snd_cs46xx_playback_clfe_ops = {
+static struct snd_pcm_ops snd_cs46xx_playback_clfe_ops = {
 	.open =			snd_cs46xx_playback_open_clfe,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1491,7 +1491,7 @@
 	.pointer =		snd_cs46xx_playback_direct_pointer,
 };
 
-static snd_pcm_ops_t snd_cs46xx_playback_indirect_clfe_ops = {
+static struct snd_pcm_ops snd_cs46xx_playback_indirect_clfe_ops = {
 	.open =			snd_cs46xx_playback_open_clfe,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1503,7 +1503,7 @@
 	.ack =			snd_cs46xx_playback_transfer,
 };
 
-static snd_pcm_ops_t snd_cs46xx_playback_iec958_ops = {
+static struct snd_pcm_ops snd_cs46xx_playback_iec958_ops = {
 	.open =			snd_cs46xx_playback_open_iec958,
 	.close =		snd_cs46xx_playback_close_iec958,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1514,7 +1514,7 @@
 	.pointer =		snd_cs46xx_playback_direct_pointer,
 };
 
-static snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops = {
+static struct snd_pcm_ops snd_cs46xx_playback_indirect_iec958_ops = {
 	.open =			snd_cs46xx_playback_open_iec958,
 	.close =		snd_cs46xx_playback_close_iec958,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1528,7 +1528,7 @@
 
 #endif
 
-static snd_pcm_ops_t snd_cs46xx_playback_ops = {
+static struct snd_pcm_ops snd_cs46xx_playback_ops = {
 	.open =			snd_cs46xx_playback_open,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1539,7 +1539,7 @@
 	.pointer =		snd_cs46xx_playback_direct_pointer,
 };
 
-static snd_pcm_ops_t snd_cs46xx_playback_indirect_ops = {
+static struct snd_pcm_ops snd_cs46xx_playback_indirect_ops = {
 	.open =			snd_cs46xx_playback_open,
 	.close =		snd_cs46xx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1551,7 +1551,7 @@
 	.ack =			snd_cs46xx_playback_transfer,
 };
 
-static snd_pcm_ops_t snd_cs46xx_capture_ops = {
+static struct snd_pcm_ops snd_cs46xx_capture_ops = {
 	.open =			snd_cs46xx_capture_open,
 	.close =		snd_cs46xx_capture_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1562,7 +1562,7 @@
 	.pointer =		snd_cs46xx_capture_direct_pointer,
 };
 
-static snd_pcm_ops_t snd_cs46xx_capture_indirect_ops = {
+static struct snd_pcm_ops snd_cs46xx_capture_indirect_ops = {
 	.open =			snd_cs46xx_capture_open,
 	.close =		snd_cs46xx_capture_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1574,43 +1574,15 @@
 	.ack =			snd_cs46xx_capture_transfer,
 };
 
-static void snd_cs46xx_pcm_free(snd_pcm_t *pcm)
-{
-	cs46xx_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-static void snd_cs46xx_pcm_rear_free(snd_pcm_t *pcm)
-{
-	cs46xx_t *chip = pcm->private_data;
-	chip->pcm_rear = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static void snd_cs46xx_pcm_center_lfe_free(snd_pcm_t *pcm)
-{
-	cs46xx_t *chip = pcm->private_data;
-	chip->pcm_center_lfe = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static void snd_cs46xx_pcm_iec958_free(snd_pcm_t *pcm)
-{
-	cs46xx_t *chip = pcm->private_data;
-	chip->pcm_iec958 = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
 #define MAX_PLAYBACK_CHANNELS	(DSP_MAX_PCM_CHANNELS - 1)
 #else
 #define MAX_PLAYBACK_CHANNELS	1
 #endif
 
-int __devinit snd_cs46xx_pcm(cs46xx_t *chip, int device, snd_pcm_t ** rpcm)
+int __devinit snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1619,7 +1591,6 @@
 		return err;
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_cs46xx_pcm_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cs46xx_capture_ops);
@@ -1640,9 +1611,9 @@
 
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-int __devinit snd_cs46xx_pcm_rear(cs46xx_t *chip, int device, snd_pcm_t ** rpcm)
+int __devinit snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1652,7 +1623,6 @@
 		return err;
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_cs46xx_pcm_rear_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_rear_ops);
 
@@ -1670,9 +1640,9 @@
 	return 0;
 }
 
-int __devinit snd_cs46xx_pcm_center_lfe(cs46xx_t *chip, int device, snd_pcm_t ** rpcm)
+int __devinit snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1682,7 +1652,6 @@
 		return err;
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_cs46xx_pcm_center_lfe_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_clfe_ops);
 
@@ -1700,9 +1669,9 @@
 	return 0;
 }
 
-int __devinit snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t ** rpcm)
+int __devinit snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1712,7 +1681,6 @@
 		return err;
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_cs46xx_pcm_iec958_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_cs46xx_playback_iec958_ops);
 
@@ -1734,16 +1702,16 @@
 /*
  *  Mixer routines
  */
-static void snd_cs46xx_mixer_free_ac97_bus(ac97_bus_t *bus)
+static void snd_cs46xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
 {
-	cs46xx_t *chip = bus->private_data;
+	struct snd_cs46xx *chip = bus->private_data;
 
 	chip->ac97_bus = NULL;
 }
 
-static void snd_cs46xx_mixer_free_ac97(ac97_t *ac97)
+static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	cs46xx_t *chip = ac97->private_data;
+	struct snd_cs46xx *chip = ac97->private_data;
 
 	snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) ||
 		    (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]),
@@ -1757,8 +1725,8 @@
 		chip->ac97[CS46XX_SECONDARY_CODEC_INDEX] = NULL;
 }
 
-static int snd_cs46xx_vol_info(snd_kcontrol_t *kcontrol, 
-			       snd_ctl_elem_info_t *uinfo)
+static int snd_cs46xx_vol_info(struct snd_kcontrol *kcontrol, 
+			       struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -1767,9 +1735,9 @@
 	return 0;
 }
 
-static int snd_cs46xx_vol_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value;
 	unsigned int val = snd_cs46xx_peek(chip, reg);
 	ucontrol->value.integer.value[0] = 0xffff - (val >> 16);
@@ -1777,9 +1745,9 @@
 	return 0;
 }
 
-static int snd_cs46xx_vol_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value;
 	unsigned int val = ((0xffff - ucontrol->value.integer.value[0]) << 16 | 
 			    (0xffff - ucontrol->value.integer.value[1]));
@@ -1795,9 +1763,9 @@
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 
-static int snd_cs46xx_vol_dac_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_vol_dac_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.integer.value[0] = chip->dsp_spos_instance->dac_volume_left;
 	ucontrol->value.integer.value[1] = chip->dsp_spos_instance->dac_volume_right;
@@ -1805,9 +1773,9 @@
 	return 0;
 }
 
-static int snd_cs46xx_vol_dac_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_vol_dac_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int change = 0;
 
 	if (chip->dsp_spos_instance->dac_volume_right != ucontrol->value.integer.value[0] ||
@@ -1822,18 +1790,18 @@
 }
 
 #if 0
-static int snd_cs46xx_vol_iec958_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_vol_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.integer.value[0] = chip->dsp_spos_instance->spdif_input_volume_left;
 	ucontrol->value.integer.value[1] = chip->dsp_spos_instance->spdif_input_volume_right;
 	return 0;
 }
 
-static int snd_cs46xx_vol_iec958_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_vol_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int change = 0;
 
 	if (chip->dsp_spos_instance->spdif_input_volume_left  != ucontrol->value.integer.value[0] ||
@@ -1848,8 +1816,8 @@
 }
 #endif
 
-static int snd_mixer_boolean_info(snd_kcontrol_t *kcontrol, 
-				  snd_ctl_elem_info_t *uinfo)
+static int snd_mixer_boolean_info(struct snd_kcontrol *kcontrol, 
+				  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1858,10 +1826,10 @@
 	return 0;
 }
 
-static int snd_cs46xx_iec958_get(snd_kcontrol_t *kcontrol, 
-                                 snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_iec958_get(struct snd_kcontrol *kcontrol, 
+                                 struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value;
 
 	if (reg == CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT)
@@ -1872,10 +1840,10 @@
 	return 0;
 }
 
-static int snd_cs46xx_iec958_put(snd_kcontrol_t *kcontrol, 
-                                  snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, 
+                                  struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int change, res;
 
 	switch (kcontrol->private_value) {
@@ -1909,11 +1877,11 @@
 	return res;
 }
 
-static int snd_cs46xx_adc_capture_get(snd_kcontrol_t *kcontrol, 
-                                      snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_adc_capture_get(struct snd_kcontrol *kcontrol, 
+                                      struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	if (ins->adc_input != NULL) 
 		ucontrol->value.integer.value[0] = 1;
@@ -1923,11 +1891,11 @@
 	return 0;
 }
 
-static int snd_cs46xx_adc_capture_put(snd_kcontrol_t *kcontrol, 
-                                      snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_adc_capture_put(struct snd_kcontrol *kcontrol, 
+                                      struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	int change = 0;
 
 	if (ucontrol->value.integer.value[0] && !ins->adc_input) {
@@ -1940,11 +1908,11 @@
 	return change;
 }
 
-static int snd_cs46xx_pcm_capture_get(snd_kcontrol_t *kcontrol, 
-                                      snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_pcm_capture_get(struct snd_kcontrol *kcontrol, 
+                                      struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	if (ins->pcm_input != NULL) 
 		ucontrol->value.integer.value[0] = 1;
@@ -1955,11 +1923,11 @@
 }
 
 
-static int snd_cs46xx_pcm_capture_put(snd_kcontrol_t *kcontrol, 
-                                      snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_pcm_capture_put(struct snd_kcontrol *kcontrol, 
+                                      struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	int change = 0;
 
 	if (ucontrol->value.integer.value[0] && !ins->pcm_input) {
@@ -1973,10 +1941,10 @@
 	return change;
 }
 
-static int snd_herc_spdif_select_get(snd_kcontrol_t *kcontrol, 
-                                     snd_ctl_elem_value_t *ucontrol)
+static int snd_herc_spdif_select_get(struct snd_kcontrol *kcontrol, 
+                                     struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 
 	int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
 
@@ -1991,10 +1959,10 @@
 /*
  *	Game Theatre XP card - EGPIO[0] is used to select SPDIF input optical or coaxial.
  */ 
-static int snd_herc_spdif_select_put(snd_kcontrol_t *kcontrol, 
-                                       snd_ctl_elem_value_t *ucontrol)
+static int snd_herc_spdif_select_put(struct snd_kcontrol *kcontrol, 
+                                       struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
 	int val2 = snd_cs46xx_peekBA0(chip, BA0_EGPIOPTR);
 
@@ -2016,18 +1984,18 @@
 }
 
 
-static int snd_cs46xx_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_cs46xx_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_cs46xx_spdif_default_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_spdif_default_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	down (&chip->spos_mutex);
 	ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_default >> 24) & 0xff);
@@ -2039,11 +2007,11 @@
 	return 0;
 }
 
-static int snd_cs46xx_spdif_default_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_spdif_default_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t * chip = snd_kcontrol_chip(kcontrol);
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	unsigned int val;
 	int change;
 
@@ -2066,8 +2034,8 @@
 	return change;
 }
 
-static int snd_cs46xx_spdif_mask_get(snd_kcontrol_t * kcontrol,
-				     snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_spdif_mask_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = 0xff;
 	ucontrol->value.iec958.status[1] = 0xff;
@@ -2076,11 +2044,11 @@
 	return 0;
 }
 
-static int snd_cs46xx_spdif_stream_get(snd_kcontrol_t * kcontrol,
-                                         snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_spdif_stream_get(struct snd_kcontrol *kcontrol,
+                                         struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	down (&chip->spos_mutex);
 	ucontrol->value.iec958.status[0] = _wrap_all_bits((ins->spdif_csuv_stream >> 24) & 0xff);
@@ -2092,11 +2060,11 @@
 	return 0;
 }
 
-static int snd_cs46xx_spdif_stream_put(snd_kcontrol_t * kcontrol,
-                                        snd_ctl_elem_value_t * ucontrol)
+static int snd_cs46xx_spdif_stream_put(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t * chip = snd_kcontrol_chip(kcontrol);
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx * chip = snd_kcontrol_chip(kcontrol);
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	unsigned int val;
 	int change;
 
@@ -2123,8 +2091,8 @@
 
 
 #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
-static int snd_cs46xx_egpio_select_info(snd_kcontrol_t *kcontrol, 
-                                        snd_ctl_elem_info_t *uinfo)
+static int snd_cs46xx_egpio_select_info(struct snd_kcontrol *kcontrol, 
+                                        struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -2133,19 +2101,19 @@
 	return 0;
 }
 
-static int snd_cs46xx_egpio_select_get(snd_kcontrol_t *kcontrol, 
-                                       snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_egpio_select_get(struct snd_kcontrol *kcontrol, 
+                                       struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = chip->current_gpio;
 
 	return 0;
 }
 
-static int snd_cs46xx_egpio_select_put(snd_kcontrol_t *kcontrol, 
-                                       snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_egpio_select_put(struct snd_kcontrol *kcontrol, 
+                                       struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int change = (chip->current_gpio != ucontrol->value.integer.value[0]);
 	chip->current_gpio = ucontrol->value.integer.value[0];
 
@@ -2153,10 +2121,10 @@
 }
 
 
-static int snd_cs46xx_egpio_get(snd_kcontrol_t *kcontrol, 
-                                       snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_egpio_get(struct snd_kcontrol *kcontrol, 
+                                       struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value;
 
 	snd_printdd ("put: reg = %04x, gpio %02x\n",reg,chip->current_gpio);
@@ -2166,10 +2134,10 @@
 	return 0;
 }
 
-static int snd_cs46xx_egpio_put(snd_kcontrol_t *kcontrol, 
-                                       snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_egpio_put(struct snd_kcontrol *kcontrol, 
+                                       struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value;
 	int val = snd_cs46xx_peekBA0(chip, reg);
 	int oldval = val;
@@ -2187,7 +2155,7 @@
 }
 #endif /* CONFIG_SND_CS46XX_DEBUG_GPIO */
 
-static snd_kcontrol_new_t snd_cs46xx_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_cs46xx_controls[] __devinitdata = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "DAC Volume",
@@ -2317,26 +2285,26 @@
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 /* set primary cs4294 codec into Extended Audio Mode */
-static int snd_cs46xx_front_dup_get(snd_kcontrol_t *kcontrol, 
-				    snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_front_dup_get(struct snd_kcontrol *kcontrol, 
+				    struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 	val = snd_ac97_read(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX], AC97_CSR_ACMODE);
 	ucontrol->value.integer.value[0] = (val & 0x200) ? 0 : 1;
 	return 0;
 }
 
-static int snd_cs46xx_front_dup_put(snd_kcontrol_t *kcontrol, 
-				    snd_ctl_elem_value_t *ucontrol)
+static int snd_cs46xx_front_dup_put(struct snd_kcontrol *kcontrol, 
+				    struct snd_ctl_elem_value *ucontrol)
 {
-	cs46xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs46xx *chip = snd_kcontrol_chip(kcontrol);
 	return snd_ac97_update_bits(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX],
 				    AC97_CSR_ACMODE, 0x200,
 				    ucontrol->value.integer.value[0] ? 0 : 0x200);
 }
 
-static snd_kcontrol_new_t snd_cs46xx_front_dup_ctl = {
+static struct snd_kcontrol_new snd_cs46xx_front_dup_ctl = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Duplicate Front",
 	.info = snd_mixer_boolean_info,
@@ -2347,7 +2315,7 @@
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 /* Only available on the Hercules Game Theater XP soundcard */
-static snd_kcontrol_new_t snd_hercules_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_hercules_controls[] __devinitdata = {
 {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Optical/Coaxial SPDIF Input Switch",
@@ -2358,7 +2326,7 @@
 };
 
 
-static void snd_cs46xx_codec_reset (ac97_t * ac97)
+static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97)
 {
 	unsigned long end_time;
 	int err;
@@ -2407,10 +2375,10 @@
 }
 #endif
 
-static int __devinit cs46xx_detect_codec(cs46xx_t *chip, int codec)
+static int __devinit cs46xx_detect_codec(struct snd_cs46xx *chip, int codec)
 {
 	int idx, err;
-	ac97_template_t ac97;
+	struct snd_ac97_template ac97;
 
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
@@ -2440,13 +2408,13 @@
 	return -ENXIO;
 }
 
-int __devinit snd_cs46xx_mixer(cs46xx_t *chip, int spdif_device)
+int __devinit snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device)
 {
-	snd_card_t *card = chip->card;
-	snd_ctl_elem_id_t id;
+	struct snd_card *card = chip->card;
+	struct snd_ctl_elem_id id;
 	int err;
 	unsigned int idx;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 		.reset = snd_cs46xx_codec_reset,
 #endif
@@ -2474,7 +2442,7 @@
 
 	/* add cs4630 mixer controls */
 	for (idx = 0; idx < ARRAY_SIZE(snd_cs46xx_controls); idx++) {
-		snd_kcontrol_t *kctl;
+		struct snd_kcontrol *kctl;
 		kctl = snd_ctl_new1(&snd_cs46xx_controls[idx], chip);
 		if (kctl && kctl->id.iface == SNDRV_CTL_ELEM_IFACE_PCM)
 			kctl->id.device = spdif_device;
@@ -2516,16 +2484,16 @@
  *  RawMIDI interface
  */
 
-static void snd_cs46xx_midi_reset(cs46xx_t *chip)
+static void snd_cs46xx_midi_reset(struct snd_cs46xx *chip)
 {
 	snd_cs46xx_pokeBA0(chip, BA0_MIDCR, MIDCR_MRST);
 	udelay(100);
 	snd_cs46xx_pokeBA0(chip, BA0_MIDCR, chip->midcr);
 }
 
-static int snd_cs46xx_midi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_cs46xx_midi_input_open(struct snd_rawmidi_substream *substream)
 {
-	cs46xx_t *chip = substream->rmidi->private_data;
+	struct snd_cs46xx *chip = substream->rmidi->private_data;
 
 	chip->active_ctrl(chip, 1);
 	spin_lock_irq(&chip->reg_lock);
@@ -2541,9 +2509,9 @@
 	return 0;
 }
 
-static int snd_cs46xx_midi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_cs46xx_midi_input_close(struct snd_rawmidi_substream *substream)
 {
-	cs46xx_t *chip = substream->rmidi->private_data;
+	struct snd_cs46xx *chip = substream->rmidi->private_data;
 
 	spin_lock_irq(&chip->reg_lock);
 	chip->midcr &= ~(MIDCR_RXE | MIDCR_RIE);
@@ -2559,9 +2527,9 @@
 	return 0;
 }
 
-static int snd_cs46xx_midi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_cs46xx_midi_output_open(struct snd_rawmidi_substream *substream)
 {
-	cs46xx_t *chip = substream->rmidi->private_data;
+	struct snd_cs46xx *chip = substream->rmidi->private_data;
 
 	chip->active_ctrl(chip, 1);
 
@@ -2578,9 +2546,9 @@
 	return 0;
 }
 
-static int snd_cs46xx_midi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_cs46xx_midi_output_close(struct snd_rawmidi_substream *substream)
 {
-	cs46xx_t *chip = substream->rmidi->private_data;
+	struct snd_cs46xx *chip = substream->rmidi->private_data;
 
 	spin_lock_irq(&chip->reg_lock);
 	chip->midcr &= ~(MIDCR_TXE | MIDCR_TIE);
@@ -2596,10 +2564,10 @@
 	return 0;
 }
 
-static void snd_cs46xx_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_cs46xx_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	cs46xx_t *chip = substream->rmidi->private_data;
+	struct snd_cs46xx *chip = substream->rmidi->private_data;
 
 	spin_lock_irqsave(&chip->reg_lock, flags);
 	if (up) {
@@ -2616,10 +2584,10 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static void snd_cs46xx_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_cs46xx_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	cs46xx_t *chip = substream->rmidi->private_data;
+	struct snd_cs46xx *chip = substream->rmidi->private_data;
 	unsigned char byte;
 
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -2646,23 +2614,23 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static snd_rawmidi_ops_t snd_cs46xx_midi_output =
+static struct snd_rawmidi_ops snd_cs46xx_midi_output =
 {
 	.open =		snd_cs46xx_midi_output_open,
 	.close =	snd_cs46xx_midi_output_close,
 	.trigger =	snd_cs46xx_midi_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_cs46xx_midi_input =
+static struct snd_rawmidi_ops snd_cs46xx_midi_input =
 {
 	.open =		snd_cs46xx_midi_input_open,
 	.close =	snd_cs46xx_midi_input_close,
 	.trigger =	snd_cs46xx_midi_input_trigger,
 };
 
-int __devinit snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rrawmidi)
+int __devinit snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rrawmidi)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	if (rrawmidi)
@@ -2689,7 +2657,7 @@
 
 static void snd_cs46xx_gameport_trigger(struct gameport *gameport)
 {
-	cs46xx_t *chip = gameport_get_port_data(gameport);
+	struct snd_cs46xx *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return);
 	snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF);  //outb(gameport->io, 0xFF);
@@ -2697,7 +2665,7 @@
 
 static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport)
 {
-	cs46xx_t *chip = gameport_get_port_data(gameport);
+	struct snd_cs46xx *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return 0);
 	return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io);
@@ -2705,7 +2673,7 @@
 
 static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-	cs46xx_t *chip = gameport_get_port_data(gameport);
+	struct snd_cs46xx *chip = gameport_get_port_data(gameport);
 	unsigned js1, js2, jst;
 
 	snd_assert(chip, return 0);
@@ -2739,7 +2707,7 @@
 	return 0;
 }
 
-int __devinit snd_cs46xx_gameport(cs46xx_t *chip)
+int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip)
 {
 	struct gameport *gp;
 
@@ -2767,7 +2735,7 @@
 	return 0;
 }
 
-static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip)
+static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip)
 {
 	if (chip->gameport) {
 		gameport_unregister_port(chip->gameport);
@@ -2775,20 +2743,21 @@
 	}
 }
 #else
-int __devinit snd_cs46xx_gameport(cs46xx_t *chip) { return -ENOSYS; }
-static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip) { }
+int __devinit snd_cs46xx_gameport(struct snd_cs46xx *chip) { return -ENOSYS; }
+static inline void snd_cs46xx_remove_gameport(struct snd_cs46xx *chip) { }
 #endif /* CONFIG_GAMEPORT */
 
+#ifdef CONFIG_PROC_FS
 /*
  *  proc interface
  */
 
-static long snd_cs46xx_io_read(snd_info_entry_t *entry, void *file_private_data,
+static long snd_cs46xx_io_read(struct snd_info_entry *entry, void *file_private_data,
 			       struct file *file, char __user *buf,
 			       unsigned long count, unsigned long pos)
 {
 	long size;
-	snd_cs46xx_region_t *region = (snd_cs46xx_region_t *)entry->private_data;
+	struct snd_cs46xx_region *region = entry->private_data;
 	
 	size = count;
 	if (pos + (size_t)size > region->size)
@@ -2804,13 +2773,13 @@
 	.read = snd_cs46xx_io_read,
 };
 
-static int __devinit snd_cs46xx_proc_init(snd_card_t * card, cs46xx_t *chip)
+static int __devinit snd_cs46xx_proc_init(struct snd_card *card, struct snd_cs46xx *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	int idx;
 	
 	for (idx = 0; idx < 5; idx++) {
-		snd_cs46xx_region_t *region = &chip->region.idx[idx];
+		struct snd_cs46xx_region *region = &chip->region.idx[idx];
 		if (! snd_card_proc_new(card, region->name, &entry)) {
 			entry->content = SNDRV_INFO_CONTENT_DATA;
 			entry->private_data = chip;
@@ -2825,18 +2794,22 @@
 	return 0;
 }
 
-static int snd_cs46xx_proc_done(cs46xx_t *chip)
+static int snd_cs46xx_proc_done(struct snd_cs46xx *chip)
 {
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	cs46xx_dsp_proc_done(chip);
 #endif
 	return 0;
 }
+#else /* !CONFIG_PROC_FS */
+#define snd_cs46xx_proc_init(card, chip)
+#define snd_cs46xx_proc_done(chip)
+#endif
 
 /*
  * stop the h/w
  */
-static void snd_cs46xx_hw_stop(cs46xx_t *chip)
+static void snd_cs46xx_hw_stop(struct snd_cs46xx *chip)
 {
 	unsigned int tmp;
 
@@ -2883,7 +2856,7 @@
 }
 
 
-static int snd_cs46xx_free(cs46xx_t *chip)
+static int snd_cs46xx_free(struct snd_cs46xx *chip)
 {
 	int idx;
 
@@ -2903,13 +2876,13 @@
 		snd_cs46xx_hw_stop(chip);
 
 	for (idx = 0; idx < 5; idx++) {
-		snd_cs46xx_region_t *region = &chip->region.idx[idx];
+		struct snd_cs46xx_region *region = &chip->region.idx[idx];
 		if (region->remap_addr)
 			iounmap(region->remap_addr);
 		release_and_free_resource(region->resource);
 	}
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 
 	if (chip->active_ctrl)
 		chip->active_ctrl(chip, -chip->amplifier);
@@ -2926,16 +2899,16 @@
 	return 0;
 }
 
-static int snd_cs46xx_dev_free(snd_device_t *device)
+static int snd_cs46xx_dev_free(struct snd_device *device)
 {
-	cs46xx_t *chip = device->device_data;
+	struct snd_cs46xx *chip = device->device_data;
 	return snd_cs46xx_free(chip);
 }
 
 /*
  *  initialize chip
  */
-static int snd_cs46xx_chip_init(cs46xx_t *chip)
+static int snd_cs46xx_chip_init(struct snd_cs46xx *chip)
 {
 	int timeout;
 
@@ -3164,7 +3137,7 @@
 /*
  *  start and load DSP 
  */
-int __devinit snd_cs46xx_start_dsp(cs46xx_t *chip)
+int __devinit snd_cs46xx_start_dsp(struct snd_cs46xx *chip)
 {	
 	unsigned int tmp;
 	/*
@@ -3266,12 +3239,12 @@
  *	AMP control - null AMP
  */
  
-static void amp_none(cs46xx_t *chip, int change)
+static void amp_none(struct snd_cs46xx *chip, int change)
 {	
 }
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-static int voyetra_setup_eapd_slot(cs46xx_t *chip)
+static int voyetra_setup_eapd_slot(struct snd_cs46xx *chip)
 {
 	
 	u32 idx, valid_slots,tmp,powerdown = 0;
@@ -3391,7 +3364,7 @@
  *	Crystal EAPD mode
  */
  
-static void amp_voyetra(cs46xx_t *chip, int change)
+static void amp_voyetra(struct snd_cs46xx *chip, int change)
 {
 	/* Manage the EAPD bit on the Crystal 4297 
 	   and the Analog AD1885 */
@@ -3427,7 +3400,7 @@
 #endif
 }
 
-static void hercules_init(cs46xx_t *chip) 
+static void hercules_init(struct snd_cs46xx *chip) 
 {
 	/* default: AMP off, and SPDIF input optical */
 	snd_cs46xx_pokeBA0(chip, BA0_EGPIODR, EGPIODR_GPOE0);
@@ -3438,7 +3411,7 @@
 /*
  *	Game Theatre XP card - EGPIO[2] is used to enable the external amp.
  */ 
-static void amp_hercules(cs46xx_t *chip, int change)
+static void amp_hercules(struct snd_cs46xx *chip, int change)
 {
 	int old = chip->amplifier;
 	int val1 = snd_cs46xx_peekBA0(chip, BA0_EGPIODR);
@@ -3459,7 +3432,7 @@
 	}
 }
 
-static void voyetra_mixer_init (cs46xx_t *chip)
+static void voyetra_mixer_init (struct snd_cs46xx *chip)
 {
 	snd_printdd ("initializing Voyetra mixer\n");
 
@@ -3468,12 +3441,12 @@
 	snd_cs46xx_pokeBA0(chip, BA0_EGPIOPTR, EGPIODR_GPOE0);
 }
 
-static void hercules_mixer_init (cs46xx_t *chip)
+static void hercules_mixer_init (struct snd_cs46xx *chip)
 {
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	unsigned int idx;
 	int err;
-	snd_card_t *card = chip->card;
+	struct snd_card *card = chip->card;
 #endif
 
 	/* set EGPIO to default */
@@ -3483,7 +3456,7 @@
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	for (idx = 0 ; idx < ARRAY_SIZE(snd_hercules_controls); idx++) {
-		snd_kcontrol_t *kctl;
+		struct snd_kcontrol *kctl;
 
 		kctl = snd_ctl_new1(&snd_hercules_controls[idx], chip);
 		if ((err = snd_ctl_add(card, kctl)) < 0) {
@@ -3500,7 +3473,7 @@
  *	Untested
  */
  
-static void amp_voyetra_4294(cs46xx_t *chip, int change)
+static void amp_voyetra_4294(struct snd_cs46xx *chip, int change)
 {
 	chip->amplifier += change;
 
@@ -3530,7 +3503,7 @@
  *	enough to make them useful.
  */
  
-static void clkrun_hack(cs46xx_t *chip, int change)
+static void clkrun_hack(struct snd_cs46xx *chip, int change)
 {
 	u16 control, nval;
 	
@@ -3555,7 +3528,7 @@
 /*
  * detect intel piix4
  */
-static void clkrun_init(cs46xx_t *chip)
+static void clkrun_init(struct snd_cs46xx *chip)
 {
 	struct pci_dev *pdev;
 	u8 pp;
@@ -3583,10 +3556,10 @@
 	u16 vendor;
 	u16 id;
 	char *name;
-	void (*init)(cs46xx_t *);
-	void (*amp)(cs46xx_t *, int);
-	void (*active)(cs46xx_t *, int);
-	void (*mixer_init)(cs46xx_t *);
+	void (*init)(struct snd_cs46xx *);
+	void (*amp)(struct snd_cs46xx *, int);
+	void (*active)(struct snd_cs46xx *, int);
+	void (*mixer_init)(struct snd_cs46xx *);
 };
 
 static struct cs_card_type __devinitdata cards[] = {
@@ -3686,18 +3659,19 @@
  * APM support
  */
 #ifdef CONFIG_PM
-static int snd_cs46xx_suspend(snd_card_t *card, pm_message_t state)
+int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	cs46xx_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_cs46xx *chip = card->private_data;
 	int amp_saved;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 	// chip->ac97_powerdown = snd_cs46xx_codec_read(chip, AC97_POWER_CONTROL);
 	// chip->ac97_general_purpose = snd_cs46xx_codec_read(chip, BA0_AC97_GENERAL_PURPOSE);
 
 	snd_ac97_suspend(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
-	if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])
-		snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
+	snd_ac97_suspend(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
 
 	amp_saved = chip->amplifier;
 	/* turn off amp */
@@ -3706,17 +3680,20 @@
 	/* disable CLKRUN */
 	chip->active_ctrl(chip, -chip->amplifier);
 	chip->amplifier = amp_saved; /* restore the status */
-	pci_disable_device(chip->pci);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int snd_cs46xx_resume(snd_card_t *card)
+int snd_cs46xx_resume(struct pci_dev *pci)
 {
-	cs46xx_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_cs46xx *chip = card->private_data;
 	int amp_saved;
 
-	pci_enable_device(chip->pci);
-	pci_set_master(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci);
 	amp_saved = chip->amplifier;
 	chip->amplifier = 0;
 	chip->active_ctrl(chip, 1); /* force to on */
@@ -3735,14 +3712,14 @@
 #endif
 
 	snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
-	if (chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])
-		snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
+	snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
 
 	if (amp_saved)
 		chip->amplifier_ctrl(chip, 1); /* turn amp on */
 	else
 		chip->active_ctrl(chip, -1); /* disable CLKRUN */
 	chip->amplifier = amp_saved;
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -3751,17 +3728,17 @@
 /*
  */
 
-int __devinit snd_cs46xx_create(snd_card_t * card,
+int __devinit snd_cs46xx_create(struct snd_card *card,
 		      struct pci_dev * pci,
 		      int external_amp, int thinkpad,
-		      cs46xx_t ** rchip)
+		      struct snd_cs46xx ** rchip)
 {
-	cs46xx_t *chip;
+	struct snd_cs46xx *chip;
 	int err, idx;
-	snd_cs46xx_region_t *region;
+	struct snd_cs46xx_region *region;
 	struct cs_card_type *cp;
 	u16 ss_card, ss_vendor;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_cs46xx_dev_free,
 	};
 	
@@ -3787,7 +3764,8 @@
 	chip->ba1_addr = pci_resource_start(pci, 1);
 	if (chip->ba0_addr == 0 || chip->ba0_addr == (unsigned long)~0 ||
 	    chip->ba1_addr == 0 || chip->ba1_addr == (unsigned long)~0) {
-	    	snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n", chip->ba0_addr, chip->ba1_addr);
+	    	snd_printk(KERN_ERR "wrong address(es) - ba0 = 0x%lx, ba1 = 0x%lx\n",
+			   chip->ba0_addr, chip->ba1_addr);
 	    	snd_cs46xx_free(chip);
 	    	return -ENOMEM;
 	}
@@ -3857,8 +3835,10 @@
 
 	for (idx = 0; idx < 5; idx++) {
 		region = &chip->region.idx[idx];
-		if ((region->resource = request_mem_region(region->base, region->size, region->name)) == NULL) {
-			snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n", region->base, region->base + region->size - 1);
+		if ((region->resource = request_mem_region(region->base, region->size,
+							   region->name)) == NULL) {
+			snd_printk(KERN_ERR "unable to request memory region 0x%lx-0x%lx\n",
+				   region->base, region->base + region->size - 1);
 			snd_cs46xx_free(chip);
 			return -EBUSY;
 		}
@@ -3870,7 +3850,8 @@
 		}
 	}
 
-	if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ, "CS46XX", (void *) chip)) {
+	if (request_irq(pci->irq, snd_cs46xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			"CS46XX", chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_cs46xx_free(chip);
 		return -EBUSY;
@@ -3898,8 +3879,6 @@
 	
 	snd_cs46xx_proc_init(card, chip);
 
-	snd_card_set_pm_callback(card, snd_cs46xx_suspend, snd_cs46xx_resume, chip);
-
 	chip->active_ctrl(chip, -1); /* disable CLKRUN */
 
 	snd_card_set_dev(card, &pci->dev);
diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
index d7bec09..f75750c 100644
--- a/sound/pci/cs46xx/cs46xx_lib.h
+++ b/sound/pci/cs46xx/cs46xx_lib.h
@@ -57,7 +57,7 @@
  *  common I/O routines
  */
 
-static inline void snd_cs46xx_poke(cs46xx_t *chip, unsigned long reg, unsigned int val)
+static inline void snd_cs46xx_poke(struct snd_cs46xx *chip, unsigned long reg, unsigned int val)
 {
 	unsigned int bank = reg >> 16;
 	unsigned int offset = reg & 0xffff;
@@ -66,117 +66,138 @@
 	writel(val, chip->region.idx[bank+1].remap_addr + offset);
 }
 
-static inline unsigned int snd_cs46xx_peek(cs46xx_t *chip, unsigned long reg)
+static inline unsigned int snd_cs46xx_peek(struct snd_cs46xx *chip, unsigned long reg)
 {
 	unsigned int bank = reg >> 16;
 	unsigned int offset = reg & 0xffff;
 	return readl(chip->region.idx[bank+1].remap_addr + offset);
 }
 
-static inline void snd_cs46xx_pokeBA0(cs46xx_t *chip, unsigned long offset, unsigned int val)
+static inline void snd_cs46xx_pokeBA0(struct snd_cs46xx *chip, unsigned long offset, unsigned int val)
 {
 	writel(val, chip->region.name.ba0.remap_addr + offset);
 }
 
-static inline unsigned int snd_cs46xx_peekBA0(cs46xx_t *chip, unsigned long offset)
+static inline unsigned int snd_cs46xx_peekBA0(struct snd_cs46xx *chip, unsigned long offset)
 {
 	return readl(chip->region.name.ba0.remap_addr + offset);
 }
 
-dsp_spos_instance_t *  cs46xx_dsp_spos_create (cs46xx_t * chip);
-void                   cs46xx_dsp_spos_destroy (cs46xx_t * chip);
-int                    cs46xx_dsp_load_module (cs46xx_t * chip,dsp_module_desc_t * module);
-symbol_entry_t *       cs46xx_dsp_lookup_symbol (cs46xx_t * chip,char * symbol_name,int symbol_type);
-int                    cs46xx_dsp_proc_init (snd_card_t * card, cs46xx_t *chip);
-int                    cs46xx_dsp_proc_done (cs46xx_t *chip);
-int                    cs46xx_dsp_scb_and_task_init (cs46xx_t *chip);
-int                    snd_cs46xx_download (cs46xx_t *chip,u32 *src,unsigned long offset,
-                                            unsigned long len);
-int                    snd_cs46xx_clear_BA1(cs46xx_t *chip,unsigned long offset,unsigned long len);
-int                    cs46xx_dsp_enable_spdif_out (cs46xx_t *chip);
-int                    cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip);
-int                    cs46xx_dsp_disable_spdif_out (cs46xx_t *chip);
-int                    cs46xx_dsp_enable_spdif_in (cs46xx_t *chip);
-int                    cs46xx_dsp_disable_spdif_in (cs46xx_t *chip);
-int                    cs46xx_dsp_enable_pcm_capture (cs46xx_t *chip);
-int                    cs46xx_dsp_disable_pcm_capture (cs46xx_t *chip);
-int                    cs46xx_dsp_enable_adc_capture (cs46xx_t *chip);
-int                    cs46xx_dsp_disable_adc_capture (cs46xx_t *chip);
-int                    cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data);
-dsp_scb_descriptor_t * cs46xx_dsp_create_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest);
-void                   cs46xx_dsp_proc_free_scb_desc (dsp_scb_descriptor_t * scb);
-void                   cs46xx_dsp_proc_register_scb_desc (cs46xx_t *chip,dsp_scb_descriptor_t * scb);
-dsp_scb_descriptor_t * cs46xx_dsp_create_timing_master_scb (cs46xx_t *chip);
-dsp_scb_descriptor_t * cs46xx_dsp_create_codec_out_scb(cs46xx_t * chip,char * codec_name,
-                                                       u16 channel_disp,u16 fifo_addr,
-                                                       u16 child_scb_addr,
-                                                       u32 dest,
-                                                       dsp_scb_descriptor_t * parent_scb,
-                                                       int scb_child_type);
-dsp_scb_descriptor_t * cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * codec_name,
-                                                      u16 channel_disp,u16 fifo_addr,
-                                                      u16 sample_buffer_addr,
-                                                      u32 dest,
-                                                      dsp_scb_descriptor_t * parent_scb,
-                                                      int scb_child_type);
-void                   cs46xx_dsp_remove_scb (cs46xx_t *chip,dsp_scb_descriptor_t * scb);
-dsp_scb_descriptor_t *  cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * codec_name,
-                                                       u16 channel_disp,u16 fifo_addr,
-                                                       u16 sample_buffer_addr,
-                                                       u32 dest,dsp_scb_descriptor_t * parent_scb,
-                                                       int scb_child_type);
-dsp_scb_descriptor_t *  cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
-						       int sample_rate,
-                                                       u16 src_buffer_addr,
-                                                       u16 src_delay_buffer_addr,u32 dest,
-                                                       dsp_scb_descriptor_t * parent_scb,
-                                                       int scb_child_type,
-						       int pass_through);
-dsp_scb_descriptor_t *  cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name,
-                                                       u16 mix_buffer_addr,u32 dest,
-                                                       dsp_scb_descriptor_t * parent_scb,
-                                                       int scb_child_type);
+struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip);
+void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip);
+int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module);
+struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name,
+						   int symbol_type);
+#ifdef CONFIG_PROC_FS
+int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip);
+int cs46xx_dsp_proc_done (struct snd_cs46xx *chip);
+#else
+#define cs46xx_dsp_proc_init(card, chip)
+#define cs46xx_dsp_proc_done(chip)
+#endif
+int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip);
+int snd_cs46xx_download (struct snd_cs46xx *chip, u32 *src, unsigned long offset,
+			 unsigned long len);
+int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, unsigned long offset, unsigned long len);
+int cs46xx_dsp_enable_spdif_out (struct snd_cs46xx *chip);
+int cs46xx_dsp_enable_spdif_hw (struct snd_cs46xx *chip);
+int cs46xx_dsp_disable_spdif_out (struct snd_cs46xx *chip);
+int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip);
+int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip);
+int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip);
+int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip);
+int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip);
+int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip);
+int cs46xx_poke_via_dsp (struct snd_cs46xx *chip, u32 address, u32 data);
+struct dsp_scb_descriptor * cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name,
+						   u32 * scb_data, u32 dest);
+#ifdef CONFIG_PROC_FS
+void cs46xx_dsp_proc_free_scb_desc (struct dsp_scb_descriptor * scb);
+void cs46xx_dsp_proc_register_scb_desc (struct snd_cs46xx *chip,
+					struct dsp_scb_descriptor * scb);
+#else
+#define cs46xx_dsp_proc_free_scb_desc(scb)
+#define cs46xx_dsp_proc_register_scb_desc(chip, scb)
+#endif
+struct dsp_scb_descriptor * cs46xx_dsp_create_timing_master_scb (struct snd_cs46xx *chip);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_codec_out_scb(struct snd_cs46xx * chip,
+				char * codec_name, u16 channel_disp, u16 fifo_addr,
+				u16 child_scb_addr, u32 dest,
+				struct dsp_scb_descriptor * parent_scb,
+				int scb_child_type);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_codec_in_scb(struct snd_cs46xx * chip, char * codec_name,
+			       u16 channel_disp, u16 fifo_addr,
+			       u16 sample_buffer_addr, u32 dest,
+			       struct dsp_scb_descriptor * parent_scb,
+			       int scb_child_type);
+void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip,
+			    struct dsp_scb_descriptor * scb);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_codec_in_scb(struct snd_cs46xx * chip, char * codec_name,
+			       u16 channel_disp, u16 fifo_addr,
+			       u16 sample_buffer_addr, u32 dest,
+			       struct dsp_scb_descriptor * parent_scb,
+			       int scb_child_type);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_src_task_scb(struct snd_cs46xx * chip, char * scb_name,
+			       int sample_rate, u16 src_buffer_addr,
+			       u16 src_delay_buffer_addr, u32 dest,
+			       struct dsp_scb_descriptor * parent_scb,
+			       int scb_child_type, int pass_through);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_mix_only_scb(struct snd_cs46xx * chip, char * scb_name,
+			       u16 mix_buffer_addr, u32 dest,
+			       struct dsp_scb_descriptor * parent_scb,
+			       int scb_child_type);
 
-dsp_scb_descriptor_t *  cs46xx_dsp_create_vari_decimate_scb(cs46xx_t * chip,char * scb_name,
-                                                            u16 vari_buffer_addr0,
-                                                            u16 vari_buffer_addr1,
-                                                            u32 dest,
-                                                            dsp_scb_descriptor_t * parent_scb,
-                                                            int scb_child_type);
-dsp_scb_descriptor_t * cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
-                                                          u16 hfg_scb_address,
-                                                          u16 asynch_buffer_address,
-                                                          dsp_scb_descriptor_t * parent_scb,
-                                                          int scb_child_type);
-dsp_scb_descriptor_t *  cs46xx_dsp_create_spio_write_scb(cs46xx_t * chip,char * scb_name,u32 dest,
-                                                         dsp_scb_descriptor_t * parent_scb,
-                                                         int scb_child_type);
-dsp_scb_descriptor_t *  cs46xx_dsp_create_mix_to_ostream_scb(cs46xx_t * chip,char * scb_name,
-                                                             u16 mix_buffer_addr,u16 writeback_spb,u32 dest,
-                                                             dsp_scb_descriptor_t * parent_scb,
-                                                             int scb_child_type);
-dsp_scb_descriptor_t *  cs46xx_dsp_create_magic_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
-                                                          u16 snoop_buffer_address,
-                                                          dsp_scb_descriptor_t * snoop_scb,
-                                                          dsp_scb_descriptor_t * parent_scb,
-                                                          int scb_child_type);
-pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sample_rate, void * private_data, u32 hw_dma_addr,
-                                                          int pcm_channel_id);
-void                       cs46xx_dsp_destroy_pcm_channel (cs46xx_t * chip,
-                                                           pcm_channel_descriptor_t * pcm_channel);
-int                        cs46xx_dsp_pcm_unlink (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel);
-int                        cs46xx_dsp_pcm_link (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel);
-dsp_scb_descriptor_t *     cs46xx_add_record_source (cs46xx_t *chip,dsp_scb_descriptor_t * source,
-                                                     u16 addr,char * scb_name);
-int                        cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t * src);
-int                        cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src);
-int                        cs46xx_iec958_pre_open (cs46xx_t *chip);
-int                        cs46xx_iec958_post_close (cs46xx_t *chip);
-int                        cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
-							       pcm_channel_descriptor_t * pcm_channel,
-							       int period_size);
-int                        cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
-							      int period_size);
-int                        cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 left,u16 right);
-int                        cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 left,u16 right);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_vari_decimate_scb(struct snd_cs46xx * chip, char * scb_name,
+				    u16 vari_buffer_addr0, u16 vari_buffer_addr1, u32 dest,
+				    struct dsp_scb_descriptor * parent_scb,
+				    int scb_child_type);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_asynch_fg_rx_scb(struct snd_cs46xx * chip, char * scb_name,
+				   u32 dest, u16 hfg_scb_address, u16 asynch_buffer_address,
+				   struct dsp_scb_descriptor * parent_scb,
+				   int scb_child_type);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_spio_write_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
+				 struct dsp_scb_descriptor * parent_scb,
+				 int scb_child_type);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_mix_to_ostream_scb(struct snd_cs46xx * chip, char * scb_name,
+				     u16 mix_buffer_addr, u16 writeback_spb, u32 dest,
+				     struct dsp_scb_descriptor * parent_scb,
+				     int scb_child_type);
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_magic_snoop_scb(struct snd_cs46xx * chip, char * scb_name,
+				  u32 dest, u16 snoop_buffer_address,
+				  struct dsp_scb_descriptor * snoop_scb,
+				  struct dsp_scb_descriptor * parent_scb,
+				  int scb_child_type);
+struct dsp_pcm_channel_descriptor *
+cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip, u32 sample_rate,
+			       void * private_data, u32 hw_dma_addr,
+			       int pcm_channel_id);
+void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
+				     struct dsp_pcm_channel_descriptor * pcm_channel);
+int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
+			   struct dsp_pcm_channel_descriptor * pcm_channel);
+int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
+			 struct dsp_pcm_channel_descriptor * pcm_channel);
+struct dsp_scb_descriptor *
+cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * source,
+			  u16 addr, char * scb_name);
+int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src);
+int cs46xx_src_link(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src);
+int cs46xx_iec958_pre_open (struct snd_cs46xx *chip);
+int cs46xx_iec958_post_close (struct snd_cs46xx *chip);
+int cs46xx_dsp_pcm_channel_set_period (struct snd_cs46xx * chip,
+				       struct dsp_pcm_channel_descriptor * pcm_channel,
+				       int period_size);
+int cs46xx_dsp_pcm_ostream_set_period (struct snd_cs46xx * chip, int period_size);
+int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right);
+int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right);
 #endif /* __CS46XX_LIB_H__ */
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index b66304f..445a448 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -37,9 +37,10 @@
 #include "cs46xx_lib.h"
 #include "dsp_spos.h"
 
-static int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry);
+static int cs46xx_dsp_async_init (struct snd_cs46xx *chip,
+				  struct dsp_scb_descriptor * fg_entry);
 
-static wide_opcode_t wide_opcodes[] = { 
+static enum wide_opcode wide_opcodes[] = { 
 	WIDE_FOR_BEGIN_LOOP,
 	WIDE_FOR_BEGIN_LOOP2,
 	WIDE_COND_GOTO_ADDR,
@@ -54,12 +55,13 @@
 	WIDE_TBEQ_NCOND_CALL1_ADDR
 };
 
-static int shadow_and_reallocate_code (cs46xx_t * chip,u32 * data,u32 size, u32 overlay_begin_address)
+static int shadow_and_reallocate_code (struct snd_cs46xx * chip, u32 * data, u32 size,
+				       u32 overlay_begin_address)
 {
 	unsigned int i = 0, j, nreallocated = 0;
 	u32 hival,loval,address;
 	u32 mop_operands,mop_type,wide_op;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	snd_assert( ((size % 2) == 0), return -EINVAL);
   
@@ -114,7 +116,7 @@
 	return nreallocated;
 }
 
-static segment_desc_t * get_segment_desc (dsp_module_desc_t * module, int seg_type)
+static struct dsp_segment_desc * get_segment_desc (struct dsp_module_desc * module, int seg_type)
 {
 	int i;
 	for (i = 0;i < module->nsegments; ++i) {
@@ -126,7 +128,7 @@
 	return NULL;
 };
 
-static int find_free_symbol_index (dsp_spos_instance_t * ins)
+static int find_free_symbol_index (struct dsp_spos_instance * ins)
 {
 	int index = ins->symbol_table.nsymbols,i;
 
@@ -140,10 +142,10 @@
 	return index;
 }
 
-static int add_symbols (cs46xx_t * chip, dsp_module_desc_t * module)
+static int add_symbols (struct snd_cs46xx * chip, struct dsp_module_desc * module)
 {
 	int i;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	if (module->symbol_table.nsymbols > 0) {
 		if (!strcmp(module->symbol_table.symbols[0].symbol_name, "OVERLAYBEGINADDRESS") &&
@@ -181,10 +183,11 @@
 	return 0;
 }
 
-static symbol_entry_t * add_symbol (cs46xx_t * chip, char * symbol_name, u32 address, int type)
+static struct dsp_symbol_entry *
+add_symbol (struct snd_cs46xx * chip, char * symbol_name, u32 address, int type)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	symbol_entry_t * symbol = NULL;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_symbol_entry * symbol = NULL;
 	int index;
 
 	if (ins->symbol_table.nsymbols == (DSP_MAX_SYMBOLS - 1)) {
@@ -217,17 +220,17 @@
 	return symbol;
 }
 
-dsp_spos_instance_t *  cs46xx_dsp_spos_create (cs46xx_t * chip)
+struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip)
 {
-	dsp_spos_instance_t * ins = kmalloc(sizeof(dsp_spos_instance_t), GFP_KERNEL);
+	struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL);
 
 	if (ins == NULL) 
 		return NULL;
-	memset(ins, 0, sizeof(*ins));
 
 	/* better to use vmalloc for this big table */
 	ins->symbol_table.nsymbols = 0;
-	ins->symbol_table.symbols = vmalloc(sizeof(symbol_entry_t) * DSP_MAX_SYMBOLS);
+	ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) *
+					    DSP_MAX_SYMBOLS);
 	ins->symbol_table.highest_frag_index = 0;
 
 	if (ins->symbol_table.symbols == NULL) {
@@ -248,7 +251,7 @@
 	ins->ntask = 0;
 
 	ins->nmodules = 0;
-	ins->modules = kmalloc(sizeof(dsp_module_desc_t) * DSP_MAX_MODULES, GFP_KERNEL);
+	ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL);
 
 	if (ins->modules == NULL) {
 		cs46xx_dsp_spos_destroy(chip);
@@ -277,10 +280,10 @@
 	return ins;
 }
 
-void  cs46xx_dsp_spos_destroy (cs46xx_t * chip)
+void  cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
 {
 	int i;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	snd_assert(ins != NULL, return);
 
@@ -298,12 +301,12 @@
 	up(&chip->spos_mutex);
 }
 
-int cs46xx_dsp_load_module (cs46xx_t * chip, dsp_module_desc_t * module)
+int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	segment_desc_t * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM);
-	segment_desc_t * parameter = get_segment_desc (module,SEGTYPE_SP_PARAMETER);
-	segment_desc_t * sample = get_segment_desc (module,SEGTYPE_SP_SAMPLE);
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_segment_desc * code = get_segment_desc (module,SEGTYPE_SP_PROGRAM);
+	struct dsp_segment_desc * parameter = get_segment_desc (module,SEGTYPE_SP_PARAMETER);
+	struct dsp_segment_desc * sample = get_segment_desc (module,SEGTYPE_SP_SAMPLE);
 	u32 doffset, dsize;
 
 	if (ins->nmodules == DSP_MAX_MODULES - 1) {
@@ -410,10 +413,11 @@
 	return 0;
 }
 
-symbol_entry_t * cs46xx_dsp_lookup_symbol (cs46xx_t * chip, char * symbol_name, int symbol_type)
+struct dsp_symbol_entry *
+cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name, int symbol_type)
 {
 	int i;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	for ( i = 0; i < ins->symbol_table.nsymbols; ++i ) {
 
@@ -435,10 +439,12 @@
 }
 
 
-static symbol_entry_t * cs46xx_dsp_lookup_symbol_addr (cs46xx_t * chip, u32 address, int symbol_type)
+#ifdef CONFIG_PROC_FS
+static struct dsp_symbol_entry *
+cs46xx_dsp_lookup_symbol_addr (struct snd_cs46xx * chip, u32 address, int symbol_type)
 {
 	int i;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	for ( i = 0; i < ins->symbol_table.nsymbols; ++i ) {
 
@@ -456,10 +462,11 @@
 }
 
 
-static void cs46xx_dsp_proc_symbol_table_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void cs46xx_dsp_proc_symbol_table_read (struct snd_info_entry *entry,
+					       struct snd_info_buffer *buffer)
 {
-	cs46xx_t *chip = entry->private_data;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx *chip = entry->private_data;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	int i;
 
 	snd_iprintf(buffer, "SYMBOLS:\n");
@@ -483,10 +490,11 @@
 }
 
 
-static void cs46xx_dsp_proc_modules_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void cs46xx_dsp_proc_modules_read (struct snd_info_entry *entry,
+					  struct snd_info_buffer *buffer)
 {
-	cs46xx_t *chip = entry->private_data;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx *chip = entry->private_data;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	int i,j;
 
 	down(&chip->spos_mutex);
@@ -497,7 +505,7 @@
 		snd_iprintf(buffer, "   %d fixups\n", ins->modules[i].nfixups);
 
 		for (j = 0; j < ins->modules[i].nsegments; ++ j) {
-			segment_desc_t * desc = (ins->modules[i].segments + j);
+			struct dsp_segment_desc * desc = (ins->modules[i].segments + j);
 			snd_iprintf(buffer, "   segment %02x offset %08x size %08x\n",
 				    desc->segment_type,desc->offset, desc->size);
 		}
@@ -505,11 +513,12 @@
 	up(&chip->spos_mutex);
 }
 
-static void cs46xx_dsp_proc_task_tree_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void cs46xx_dsp_proc_task_tree_read (struct snd_info_entry *entry,
+					    struct snd_info_buffer *buffer)
 {
-	cs46xx_t *chip = entry->private_data;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	int i,j,col;
+	struct snd_cs46xx *chip = entry->private_data;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	int i, j, col;
 	void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
 
 	down(&chip->spos_mutex);
@@ -532,10 +541,11 @@
 	up(&chip->spos_mutex);
 }
 
-static void cs46xx_dsp_proc_scb_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void cs46xx_dsp_proc_scb_read (struct snd_info_entry *entry,
+				      struct snd_info_buffer *buffer)
 {
-	cs46xx_t *chip = entry->private_data;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_cs46xx *chip = entry->private_data;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	int i;
 
 	down(&chip->spos_mutex);
@@ -564,13 +574,14 @@
 	up(&chip->spos_mutex);
 }
 
-static void cs46xx_dsp_proc_parameter_dump_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void cs46xx_dsp_proc_parameter_dump_read (struct snd_info_entry *entry,
+						 struct snd_info_buffer *buffer)
 {
-	cs46xx_t *chip = entry->private_data;
-	/*dsp_spos_instance_t * ins = chip->dsp_spos_instance; */
-	unsigned int i,col = 0;
+	struct snd_cs46xx *chip = entry->private_data;
+	/*struct dsp_spos_instance * ins = chip->dsp_spos_instance; */
+	unsigned int i, col = 0;
 	void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
-	symbol_entry_t * symbol; 
+	struct dsp_symbol_entry * symbol; 
 
 	for (i = 0;i < DSP_PARAMETER_BYTE_SIZE; i += sizeof(u32),col ++) {
 		if (col == 4) {
@@ -591,9 +602,10 @@
 	}
 }
 
-static void cs46xx_dsp_proc_sample_dump_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+static void cs46xx_dsp_proc_sample_dump_read (struct snd_info_entry *entry,
+					      struct snd_info_buffer *buffer)
 {
-	cs46xx_t *chip = entry->private_data;
+	struct snd_cs46xx *chip = entry->private_data;
 	int i,col = 0;
 	void __iomem *dst = chip->region.idx[2].remap_addr;
 
@@ -738,10 +750,10 @@
 	snd_iprintf(buffer,"\n");
 }
 
-int cs46xx_dsp_proc_init (snd_card_t * card, cs46xx_t *chip)
+int cs46xx_dsp_proc_init (struct snd_card *card, struct snd_cs46xx *chip)
 {
-	snd_info_entry_t *entry;
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct snd_info_entry *entry;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	int i;
 
 	ins->snd_card = card;
@@ -852,9 +864,9 @@
 	return 0;
 }
 
-int cs46xx_dsp_proc_done (cs46xx_t *chip)
+int cs46xx_dsp_proc_done (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	int i;
 
 	if (ins->proc_sym_info_entry) {
@@ -901,9 +913,11 @@
 
 	return 0;
 }
+#endif /* CONFIG_PROC_FS */
 
 static int debug_tree;
-static void _dsp_create_task_tree (cs46xx_t *chip,u32 * task_data, u32  dest, int size)
+static void _dsp_create_task_tree (struct snd_cs46xx *chip, u32 * task_data,
+				   u32  dest, int size)
 {
 	void __iomem *spdst = chip->region.idx[1].remap_addr + 
 		DSP_PARAMETER_BYTE_OFFSET + dest * sizeof(u32);
@@ -917,7 +931,7 @@
 }
 
 static int debug_scb;
-static void _dsp_create_scb (cs46xx_t *chip,u32 * scb_data, u32  dest)
+static void _dsp_create_scb (struct snd_cs46xx *chip, u32 * scb_data, u32 dest)
 {
 	void __iomem *spdst = chip->region.idx[1].remap_addr + 
 		DSP_PARAMETER_BYTE_OFFSET + dest * sizeof(u32);
@@ -930,7 +944,7 @@
 	}
 }
 
-static int find_free_scb_index (dsp_spos_instance_t * ins)
+static int find_free_scb_index (struct dsp_spos_instance * ins)
 {
 	int index = ins->nscb, i;
 
@@ -944,10 +958,10 @@
 	return index;
 }
 
-static dsp_scb_descriptor_t * _map_scb (cs46xx_t *chip,char * name,u32 dest)
+static struct dsp_scb_descriptor * _map_scb (struct snd_cs46xx *chip, char * name, u32 dest)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * desc = NULL;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * desc = NULL;
 	int index;
 
 	if (ins->nscb == DSP_MAX_SCB_DESC - 1) {
@@ -977,10 +991,11 @@
 	return desc;
 }
 
-static dsp_task_descriptor_t * _map_task_tree (cs46xx_t *chip,char * name,u32 dest,u32 size)
+static struct dsp_task_descriptor *
+_map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_task_descriptor_t * desc = NULL;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_task_descriptor * desc = NULL;
 
 	if (ins->ntask == DSP_MAX_TASK_DESC - 1) {
 		snd_printk(KERN_ERR "dsp_spos: got no place for other TASK\n");
@@ -1000,9 +1015,10 @@
 	return desc;
 }
 
-dsp_scb_descriptor_t * cs46xx_dsp_create_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest)
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest)
 {
-	dsp_scb_descriptor_t * desc;
+	struct dsp_scb_descriptor * desc;
 
 	desc = _map_scb (chip,name,dest);
 	if (desc) {
@@ -1015,9 +1031,11 @@
 }
 
 
-static dsp_task_descriptor_t *  cs46xx_dsp_create_task_tree (cs46xx_t *chip,char * name, u32 * task_data,u32 dest,int size)
+static struct dsp_task_descriptor *
+cs46xx_dsp_create_task_tree (struct snd_cs46xx *chip, char * name, u32 * task_data,
+			     u32 dest, int size)
 {
-	dsp_task_descriptor_t * desc;
+	struct dsp_task_descriptor * desc;
 
 	desc = _map_task_tree (chip,name,dest,size);
 	if (desc) {
@@ -1029,31 +1047,31 @@
 	return desc;
 }
 
-int cs46xx_dsp_scb_and_task_init (cs46xx_t *chip)
+int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	symbol_entry_t * fg_task_tree_header_code;
-	symbol_entry_t * task_tree_header_code;
-	symbol_entry_t * task_tree_thread;
-	symbol_entry_t * null_algorithm;
-	symbol_entry_t * magic_snoop_task;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_symbol_entry * fg_task_tree_header_code;
+	struct dsp_symbol_entry * task_tree_header_code;
+	struct dsp_symbol_entry * task_tree_thread;
+	struct dsp_symbol_entry * null_algorithm;
+	struct dsp_symbol_entry * magic_snoop_task;
 
-	dsp_scb_descriptor_t * timing_master_scb;
-	dsp_scb_descriptor_t * codec_out_scb;
-	dsp_scb_descriptor_t * codec_in_scb;
-	dsp_scb_descriptor_t * src_task_scb;
-	dsp_scb_descriptor_t * master_mix_scb;
-	dsp_scb_descriptor_t * rear_mix_scb;
-	dsp_scb_descriptor_t * record_mix_scb;
-	dsp_scb_descriptor_t * write_back_scb;
-	dsp_scb_descriptor_t * vari_decimate_scb;
-	dsp_scb_descriptor_t * rear_codec_out_scb;
-	dsp_scb_descriptor_t * clfe_codec_out_scb;
-	dsp_scb_descriptor_t * magic_snoop_scb;
+	struct dsp_scb_descriptor * timing_master_scb;
+	struct dsp_scb_descriptor * codec_out_scb;
+	struct dsp_scb_descriptor * codec_in_scb;
+	struct dsp_scb_descriptor * src_task_scb;
+	struct dsp_scb_descriptor * master_mix_scb;
+	struct dsp_scb_descriptor * rear_mix_scb;
+	struct dsp_scb_descriptor * record_mix_scb;
+	struct dsp_scb_descriptor * write_back_scb;
+	struct dsp_scb_descriptor * vari_decimate_scb;
+	struct dsp_scb_descriptor * rear_codec_out_scb;
+	struct dsp_scb_descriptor * clfe_codec_out_scb;
+	struct dsp_scb_descriptor * magic_snoop_scb;
 	
-	int fifo_addr,fifo_span,valid_slots;
+	int fifo_addr, fifo_span, valid_slots;
 
-	static spos_control_block_t sposcb = {
+	static struct dsp_spos_control_block sposcb = {
 		/* 0 */ HFG_TREE_SCB,HFG_STACK,
 		/* 1 */ SPOSCB_ADDR,BG_TREE_SCB_ADDR,
 		/* 2 */ DSP_SPOS_DC,0,
@@ -1106,7 +1124,7 @@
   
 	{
 		/* create the null SCB */
-		static generic_scb_t null_scb = {
+		static struct dsp_generic_scb null_scb = {
 			{ 0, 0, 0, 0 },
 			{ 0, 0, 0, 0, 0 },
 			NULL_SCB_ADDR, NULL_SCB_ADDR,
@@ -1128,7 +1146,7 @@
 
 	{
 		/* setup foreground task tree */
-		static task_tree_control_block_t fg_task_tree_hdr =  {
+		static struct dsp_task_tree_control_block fg_task_tree_hdr =  {
 			{ FG_TASK_HEADER_ADDR | (DSP_SPOS_DC << 0x10),
 			  DSP_SPOS_DC_DC,
 			  DSP_SPOS_DC_DC,
@@ -1204,7 +1222,7 @@
 
 	{
 		/* setup foreground task tree */
-		static task_tree_control_block_t bg_task_tree_hdr =  {
+		static struct dsp_task_tree_control_block bg_task_tree_hdr =  {
 			{ DSP_SPOS_DC_DC,
 			  DSP_SPOS_DC_DC,
 			  DSP_SPOS_DC_DC,
@@ -1313,7 +1331,7 @@
 	if (!write_back_scb) goto _fail_end;
 
 	{
-		static mix2_ostream_spb_t mix2_ostream_spb = {
+		static struct dsp_mix2_ostream_spb mix2_ostream_spb = {
 			0x00020000,
 			0x0000ffff
 		};
@@ -1448,13 +1466,14 @@
 	return -EINVAL;
 }
 
-static int cs46xx_dsp_async_init (cs46xx_t *chip, dsp_scb_descriptor_t * fg_entry)
+static int cs46xx_dsp_async_init (struct snd_cs46xx *chip,
+				  struct dsp_scb_descriptor * fg_entry)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	symbol_entry_t * s16_async_codec_input_task;
-	symbol_entry_t * spdifo_task;
-	symbol_entry_t * spdifi_task;
-	dsp_scb_descriptor_t * spdifi_scb_desc,* spdifo_scb_desc,* async_codec_scb_desc;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_symbol_entry * s16_async_codec_input_task;
+	struct dsp_symbol_entry * spdifo_task;
+	struct dsp_symbol_entry * spdifi_task;
+	struct dsp_scb_descriptor * spdifi_scb_desc, * spdifo_scb_desc, * async_codec_scb_desc;
 
 	s16_async_codec_input_task = cs46xx_dsp_lookup_symbol(chip, "S16_ASYNCCODECINPUTTASK", SYMBOL_CODE);
 	if (s16_async_codec_input_task == NULL) {
@@ -1475,7 +1494,7 @@
 
 	{
 		/* 0xBC0 */
-		spdifoscb_t spdifo_scb = {
+		struct dsp_spdifoscb spdifo_scb = {
 			/* 0 */ DSP_SPOS_UUUU,
 			{
 				/* 1 */ 0xb0, 
@@ -1504,7 +1523,7 @@
 		};
 
 		/* 0xBB0 */
-		spdifiscb_t spdifi_scb = {
+		struct dsp_spdifiscb spdifi_scb = {
 			/* 0 */ DSP_SPOS_UULO,DSP_SPOS_UUHI,
 			/* 1 */ 0,
 			/* 2 */ 0,
@@ -1529,7 +1548,7 @@
 		};
 
 		/* 0xBA0 */
-		async_codec_input_scb_t async_codec_input_scb = {
+		struct dsp_async_codec_input_scb async_codec_input_scb = {
 			/* 0 */ DSP_SPOS_UUUU,
 			/* 1 */ 0,
 			/* 2 */ 0,
@@ -1620,9 +1639,9 @@
 }
 
 
-static void cs46xx_dsp_disable_spdif_hw (cs46xx_t *chip)
+static void cs46xx_dsp_disable_spdif_hw (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	/* set SPDIF output FIFO slot */
 	snd_cs46xx_pokeBA0(chip, BA0_ASER_FADDR, 0);
@@ -1641,9 +1660,9 @@
 	ins->spdif_status_out &= ~DSP_SPDIF_STATUS_HW_ENABLED;
 }
 
-int cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip)
+int cs46xx_dsp_enable_spdif_hw (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	/* if hw-ctrl already enabled, turn off to reset logic ... */
 	cs46xx_dsp_disable_spdif_hw (chip);
@@ -1664,9 +1683,9 @@
 	return 0;
 }
 
-int cs46xx_dsp_enable_spdif_in (cs46xx_t *chip)
+int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	/* turn on amplifier */
 	chip->active_ctrl(chip, 1);
@@ -1724,9 +1743,9 @@
 	return 0;
 }
 
-int cs46xx_dsp_disable_spdif_in (cs46xx_t *chip)
+int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL);
 	snd_assert (ins->spdif_in_src != NULL,return -EINVAL);	
@@ -1750,9 +1769,9 @@
 	return 0;
 }
 
-int cs46xx_dsp_enable_pcm_capture (cs46xx_t *chip)
+int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	snd_assert (ins->pcm_input == NULL,return -EINVAL);
 	snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL);
@@ -1765,9 +1784,9 @@
 	return 0;
 }
 
-int cs46xx_dsp_disable_pcm_capture (cs46xx_t *chip)
+int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	snd_assert (ins->pcm_input != NULL,return -EINVAL);
 
@@ -1779,9 +1798,9 @@
 	return 0;
 }
 
-int cs46xx_dsp_enable_adc_capture (cs46xx_t *chip)
+int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	snd_assert (ins->adc_input == NULL,return -EINVAL);
 	snd_assert (ins->codec_in_scb != NULL,return -EINVAL);
@@ -1794,9 +1813,9 @@
 	return 0;
 }
 
-int cs46xx_dsp_disable_adc_capture (cs46xx_t *chip)
+int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	snd_assert (ins->adc_input != NULL,return -EINVAL);
 
@@ -1808,7 +1827,7 @@
 	return 0;
 }
 
-int cs46xx_poke_via_dsp (cs46xx_t *chip,u32 address,u32 data)
+int cs46xx_poke_via_dsp (struct snd_cs46xx *chip, u32 address, u32 data)
 {
 	u32 temp;
 	int  i;
@@ -1845,10 +1864,10 @@
 	return 0;
 }
 
-int cs46xx_dsp_set_dac_volume (cs46xx_t * chip,u16 left,u16 right)
+int cs46xx_dsp_set_dac_volume (struct snd_cs46xx * chip, u16 left, u16 right)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * scb; 
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * scb; 
 
 	down(&chip->spos_mutex);
 	
@@ -1874,8 +1893,9 @@
 	return 0;
 }
 
-int cs46xx_dsp_set_iec958_volume (cs46xx_t * chip,u16 left,u16 right) {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+int cs46xx_dsp_set_iec958_volume (struct snd_cs46xx * chip, u16 left, u16 right)
+{
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	down(&chip->spos_mutex);
 
diff --git a/sound/pci/cs46xx/dsp_spos.h b/sound/pci/cs46xx/dsp_spos.h
index 90871bf..0d246bc 100644
--- a/sound/pci/cs46xx/dsp_spos.h
+++ b/sound/pci/cs46xx/dsp_spos.h
@@ -43,7 +43,7 @@
 /* this instruction types
    needs to be reallocated when load
    code into DSP */
-typedef enum  {
+enum wide_opcode {
 	WIDE_FOR_BEGIN_LOOP = 0x20,
 	WIDE_FOR_BEGIN_LOOP2,
 
@@ -58,7 +58,7 @@
 	WIDE_TBEQ_COND_CALL1_ADDR,
 	WIDE_TBEQ_NCOND_GOTOI_ADDR,
 	WIDE_TBEQ_NCOND_CALL1_ADDR,
-} wide_opcode_t;
+};
 
 /* SAMPLE segment */
 #define VARI_DECIMATE_BUF1       0x0000
@@ -186,7 +186,8 @@
 #define SP_SPDOUT_CONTROL 0x804D
 #define SP_SPDOUT_CSUV    0x808E
 
-static inline u8 _wrap_all_bits (u8 val) {
+static inline u8 _wrap_all_bits (u8 val)
+{
 	u8 wrapped;
 	
 	/* wrap all 8 bits */
@@ -201,11 +202,10 @@
 		((val & 0x80) >> 7);
 
 	return wrapped;
-
 }
 
-
-static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descriptor_t * scb) 
+static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip,
+					       struct dsp_scb_descriptor * scb) 
 {
 	/* update nextSCB and subListPtr in SCB */
 	snd_cs46xx_poke(chip,
@@ -214,8 +214,10 @@
 			(scb->next_scb_ptr->address));	
 }
 
-static inline void cs46xx_dsp_scb_set_volume (cs46xx_t * chip,dsp_scb_descriptor_t * scb,
-					      u16 left,u16 right) {
+static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,
+					      struct dsp_scb_descriptor * scb,
+					      u16 left, u16 right)
+{
 	unsigned int val = ((0xffff - left) << 16 | (0xffff - right));
 
 	snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 92849e1..509aa2b 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -36,14 +36,14 @@
 #include "cs46xx_lib.h"
 #include "dsp_spos.h"
 
-typedef struct _proc_scb_info_t {
-	dsp_scb_descriptor_t * scb_desc;
-	cs46xx_t *chip;
-} proc_scb_info_t;
+struct proc_scb_info {
+	struct dsp_scb_descriptor * scb_desc;
+	struct snd_cs46xx *chip;
+};
 
-static void remove_symbol (cs46xx_t * chip,symbol_entry_t * symbol)
+static void remove_symbol (struct snd_cs46xx * chip, struct dsp_symbol_entry * symbol)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	int symbol_index = (int)(symbol - ins->symbol_table.symbols);
 
 	snd_assert(ins->symbol_table.nsymbols > 0,return);
@@ -64,12 +64,14 @@
 
 }
 
-static void cs46xx_dsp_proc_scb_info_read (snd_info_entry_t *entry, snd_info_buffer_t * buffer)
+#ifdef CONFIG_PROC_FS
+static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
+					   struct snd_info_buffer *buffer)
 {
-	proc_scb_info_t * scb_info  = (proc_scb_info_t *)entry->private_data;
-	dsp_scb_descriptor_t * scb = scb_info->scb_desc;
-	dsp_spos_instance_t * ins;
-	cs46xx_t *chip = scb_info->chip;
+	struct proc_scb_info * scb_info  = entry->private_data;
+	struct dsp_scb_descriptor * scb = scb_info->scb_desc;
+	struct dsp_spos_instance * ins;
+	struct snd_cs46xx *chip = scb_info->chip;
 	int j,col;
 	void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
 
@@ -105,10 +107,11 @@
 	snd_iprintf(buffer,"index [%d] ref_count [%d]\n",scb->index,scb->ref_count);  
 	up(&chip->spos_mutex);
 }
+#endif
 
-static void _dsp_unlink_scb (cs46xx_t *chip,dsp_scb_descriptor_t * scb)
+static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	unsigned long flags;
 
 	if ( scb->parent_scb_ptr ) {
@@ -160,7 +163,8 @@
 	}
 }
 
-static void _dsp_clear_sample_buffer (cs46xx_t *chip, u32 sample_buffer_addr, int dword_count) 
+static void _dsp_clear_sample_buffer (struct snd_cs46xx *chip, u32 sample_buffer_addr,
+				      int dword_count) 
 {
 	void __iomem *dst = chip->region.idx[2].remap_addr + sample_buffer_addr;
 	int i;
@@ -171,9 +175,9 @@
 	}  
 }
 
-void cs46xx_dsp_remove_scb (cs46xx_t *chip, dsp_scb_descriptor_t * scb)
+void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	/* check integrety */
 	snd_assert ( (scb->index >= 0 && 
@@ -218,10 +222,11 @@
 }
 
 
-void cs46xx_dsp_proc_free_scb_desc (dsp_scb_descriptor_t * scb)
+#ifdef CONFIG_PROC_FS
+void cs46xx_dsp_proc_free_scb_desc (struct dsp_scb_descriptor * scb)
 {
 	if (scb->proc_info) {
-		proc_scb_info_t * scb_info  = (proc_scb_info_t *)scb->proc_info->private_data;
+		struct proc_scb_info * scb_info = scb->proc_info->private_data;
 
 		snd_printdd("cs46xx_dsp_proc_free_scb_desc: freeing %s\n",scb->scb_name);
 
@@ -233,11 +238,12 @@
 	}
 }
 
-void cs46xx_dsp_proc_register_scb_desc (cs46xx_t *chip,dsp_scb_descriptor_t * scb)
+void cs46xx_dsp_proc_register_scb_desc (struct snd_cs46xx *chip,
+					struct dsp_scb_descriptor * scb)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	snd_info_entry_t * entry;
-	proc_scb_info_t * scb_info;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct snd_info_entry * entry;
+	struct proc_scb_info * scb_info;
 
 	/* register to proc */
 	if (ins->snd_card != NULL && ins->proc_dsp_dir != NULL &&
@@ -245,7 +251,7 @@
   
 		if ((entry = snd_info_create_card_entry(ins->snd_card, scb->scb_name, 
 							ins->proc_dsp_dir)) != NULL) {
-			scb_info = kmalloc(sizeof(proc_scb_info_t), GFP_KERNEL);
+			scb_info = kmalloc(sizeof(struct proc_scb_info), GFP_KERNEL);
 			if (!scb_info) {
 				snd_info_free_entry(entry);
 				entry = NULL;
@@ -272,15 +278,16 @@
 		scb->proc_info = entry;
 	}
 }
+#endif /* CONFIG_PROC_FS */
 
-static dsp_scb_descriptor_t * 
-_dsp_create_generic_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest,
-                         symbol_entry_t * task_entry,
-                         dsp_scb_descriptor_t * parent_scb,
+static struct dsp_scb_descriptor * 
+_dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest,
+                         struct dsp_symbol_entry * task_entry,
+                         struct dsp_scb_descriptor * parent_scb,
                          int scb_child_type)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * scb;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * scb;
   
 	unsigned long flags;
 
@@ -342,13 +349,13 @@
 	return scb;
 }
 
-static dsp_scb_descriptor_t * 
-cs46xx_dsp_create_generic_scb (cs46xx_t *chip,char * name, u32 * scb_data,u32 dest,
-                               char * task_entry_name,
-                               dsp_scb_descriptor_t * parent_scb,
+static struct dsp_scb_descriptor * 
+cs46xx_dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data,
+			       u32 dest, char * task_entry_name,
+                               struct dsp_scb_descriptor * parent_scb,
                                int scb_child_type)
 {
-	symbol_entry_t * task_entry;
+	struct dsp_symbol_entry * task_entry;
 
 	task_entry = cs46xx_dsp_lookup_symbol (chip,task_entry_name,
 					       SYMBOL_CODE);
@@ -362,12 +369,12 @@
 					parent_scb,scb_child_type);
 }
 
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_timing_master_scb (cs46xx_t *chip)
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_timing_master_scb (struct snd_cs46xx *chip)
 {
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
   
-	timing_master_scb_t timing_master_scb = {
+	struct dsp_timing_master_scb timing_master_scb = {
 		{ 0,
 		  0,
 		  0,
@@ -396,16 +403,15 @@
 }
 
 
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_codec_out_scb(cs46xx_t * chip,char * codec_name,
-                                u16 channel_disp,u16 fifo_addr,
-                                u16 child_scb_addr,
-                                u32 dest,dsp_scb_descriptor_t * parent_scb,
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_codec_out_scb(struct snd_cs46xx * chip, char * codec_name,
+                                u16 channel_disp, u16 fifo_addr, u16 child_scb_addr,
+                                u32 dest, struct dsp_scb_descriptor * parent_scb,
                                 int scb_child_type)
 {
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
   
-	codec_output_scb_t codec_out_scb = {
+	struct dsp_codec_output_scb codec_out_scb = {
 		{ 0,
 		  0,
 		  0,
@@ -435,16 +441,15 @@
 	return scb;
 }
 
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_codec_in_scb(cs46xx_t * chip,char * codec_name,
-                                u16 channel_disp,u16 fifo_addr,
-                                u16 sample_buffer_addr,
-                                u32 dest,dsp_scb_descriptor_t * parent_scb,
-                                int scb_child_type)
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_codec_in_scb(struct snd_cs46xx * chip, char * codec_name,
+			       u16 channel_disp, u16 fifo_addr, u16 sample_buffer_addr,
+			       u32 dest, struct dsp_scb_descriptor * parent_scb,
+			       int scb_child_type)
 {
 
-	dsp_scb_descriptor_t * scb;
-	codec_input_scb_t codec_input_scb = {
+	struct dsp_scb_descriptor * scb;
+	struct dsp_codec_input_scb codec_input_scb = {
 		{ 0,
 		  0,
 		  0,
@@ -481,17 +486,17 @@
 }
 
 
-static dsp_scb_descriptor_t * 
-cs46xx_dsp_create_pcm_reader_scb(cs46xx_t * chip,char * scb_name,
-                                 u16 sample_buffer_addr,u32 dest,
+static struct dsp_scb_descriptor * 
+cs46xx_dsp_create_pcm_reader_scb(struct snd_cs46xx * chip, char * scb_name,
+                                 u16 sample_buffer_addr, u32 dest,
                                  int virtual_channel, u32 playback_hw_addr,
-                                 dsp_scb_descriptor_t * parent_scb,
+                                 struct dsp_scb_descriptor * parent_scb,
                                  int scb_child_type)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * scb;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * scb;
   
-	generic_scb_t pcm_reader_scb = {
+	struct dsp_generic_scb pcm_reader_scb = {
     
 		/*
 		  Play DMA Task xfers data from host buffer to SP buffer
@@ -584,18 +589,18 @@
 
 #define GOF_PER_SEC 200
 
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_src_task_scb(cs46xx_t * chip,char * scb_name,
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_src_task_scb(struct snd_cs46xx * chip, char * scb_name,
 			       int rate,
                                u16 src_buffer_addr,
-                               u16 src_delay_buffer_addr,u32 dest,
-                               dsp_scb_descriptor_t * parent_scb,
+                               u16 src_delay_buffer_addr, u32 dest,
+                               struct dsp_scb_descriptor * parent_scb,
                                int scb_child_type,
 	                       int pass_through)
 {
 
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * scb;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * scb;
 	unsigned int tmp1, tmp2;
 	unsigned int phiIncr;
 	unsigned int correctionPerGOF, correctionPerSec;
@@ -632,7 +637,7 @@
 	correctionPerSec = tmp1;
 
 	{
-		src_task_scb_t src_task_scb = {
+		struct dsp_src_task_scb src_task_scb = {
 			0x0028,0x00c8,
 			0x5555,0x0000,
 			0x0000,0x0000,
@@ -688,14 +693,14 @@
 }
 
 #if 0 /* not used */
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_filter_scb(cs46xx_t * chip,char * scb_name,
-			     u16 buffer_addr,u32 dest,
-			     dsp_scb_descriptor_t * parent_scb,
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_filter_scb(struct snd_cs46xx * chip, char * scb_name,
+			     u16 buffer_addr, u32 dest,
+			     struct dsp_scb_descriptor * parent_scb,
 			     int scb_child_type) {
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
 	
-	filter_scb_t filter_scb = {
+	struct dsp_filter_scb filter_scb = {
 		.a0_right            = 0x41a9,
 		.a0_left             = 0x41a9,
 		.a1_right            = 0xb8e4,
@@ -738,15 +743,15 @@
 }
 #endif /* not used */
 
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_mix_only_scb(cs46xx_t * chip,char * scb_name,
-                               u16 mix_buffer_addr,u32 dest,
-                               dsp_scb_descriptor_t * parent_scb,
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_mix_only_scb(struct snd_cs46xx * chip, char * scb_name,
+                               u16 mix_buffer_addr, u32 dest,
+                               struct dsp_scb_descriptor * parent_scb,
                                int scb_child_type)
 {
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
   
-	mix_only_scb_t master_mix_scb = {
+	struct dsp_mix_only_scb master_mix_scb = {
 		/* 0 */ { 0,
 			  /* 1 */   0,
 			  /* 2 */  mix_buffer_addr,
@@ -778,15 +783,15 @@
 }
 
 
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_mix_to_ostream_scb(cs46xx_t * chip,char * scb_name,
-                                     u16 mix_buffer_addr,u16 writeback_spb,u32 dest,
-                                     dsp_scb_descriptor_t * parent_scb,
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_mix_to_ostream_scb(struct snd_cs46xx * chip, char * scb_name,
+                                     u16 mix_buffer_addr, u16 writeback_spb, u32 dest,
+                                     struct dsp_scb_descriptor * parent_scb,
                                      int scb_child_type)
 {
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
 
-	mix2_ostream_scb_t mix2_ostream_scb = {
+	struct dsp_mix2_ostream_scb mix2_ostream_scb = {
 		/* Basic (non scatter/gather) DMA requestor (4 ints) */
 		{ 
 			DMA_RQ_C1_SOURCE_MOD64 +
@@ -832,18 +837,18 @@
 }
 
 
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_vari_decimate_scb(cs46xx_t * chip,char * scb_name,
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_vari_decimate_scb(struct snd_cs46xx * chip,char * scb_name,
                                     u16 vari_buffer_addr0,
                                     u16 vari_buffer_addr1,
                                     u32 dest,
-                                    dsp_scb_descriptor_t * parent_scb,
+                                    struct dsp_scb_descriptor * parent_scb,
                                     int scb_child_type)
 {
 
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
   
-	vari_decimate_scb_t vari_decimate_scb = {
+	struct dsp_vari_decimate_scb vari_decimate_scb = {
 		0x0028,0x00c8,
 		0x5555,0x0000,
 		0x0000,0x0000,
@@ -876,17 +881,17 @@
 }
 
 
-static dsp_scb_descriptor_t * 
-cs46xx_dsp_create_pcm_serial_input_scb(cs46xx_t * chip,char * scb_name,u32 dest,
-                                       dsp_scb_descriptor_t * input_scb,
-                                       dsp_scb_descriptor_t * parent_scb,
+static struct dsp_scb_descriptor * 
+cs46xx_dsp_create_pcm_serial_input_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
+                                       struct dsp_scb_descriptor * input_scb,
+                                       struct dsp_scb_descriptor * parent_scb,
                                        int scb_child_type)
 {
 
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
 
 
-	pcm_serial_input_scb_t pcm_serial_input_scb = {
+	struct dsp_pcm_serial_input_scb pcm_serial_input_scb = {
 		{ 0,
 		  0,
 		  0,
@@ -919,17 +924,17 @@
 }
 
 
-static dsp_scb_descriptor_t * 
-cs46xx_dsp_create_asynch_fg_tx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
+static struct dsp_scb_descriptor * 
+cs46xx_dsp_create_asynch_fg_tx_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
                                    u16 hfg_scb_address,
                                    u16 asynch_buffer_address,
-                                   dsp_scb_descriptor_t * parent_scb,
+                                   struct dsp_scb_descriptor * parent_scb,
                                    int scb_child_type)
 {
 
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
 
-	asynch_fg_tx_scb_t asynch_fg_tx_scb = {
+	struct dsp_asynch_fg_tx_scb asynch_fg_tx_scb = {
 		0xfc00,0x03ff,      /*  Prototype sample buffer size of 256 dwords */
 		0x0058,0x0028,      /* Min Delta 7 dwords == 28 bytes */
 		/* : Max delta 25 dwords == 100 bytes */
@@ -966,17 +971,17 @@
 }
 
 
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_asynch_fg_rx_scb(cs46xx_t * chip,char * scb_name,u32 dest,
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_asynch_fg_rx_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
                                    u16 hfg_scb_address,
                                    u16 asynch_buffer_address,
-                                   dsp_scb_descriptor_t * parent_scb,
+                                   struct dsp_scb_descriptor * parent_scb,
                                    int scb_child_type)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * scb;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * scb;
 
-	asynch_fg_rx_scb_t asynch_fg_rx_scb = {
+	struct dsp_asynch_fg_rx_scb asynch_fg_rx_scb = {
 		0xfe00,0x01ff,      /*  Prototype sample buffer size of 128 dwords */
 		0x0064,0x001c,      /* Min Delta 7 dwords == 28 bytes */
 		                    /* : Max delta 25 dwords == 100 bytes */
@@ -1016,17 +1021,17 @@
 
 
 #if 0 /* not used */
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_output_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_output_snoop_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
                                    u16 snoop_buffer_address,
-                                   dsp_scb_descriptor_t * snoop_scb,
-                                   dsp_scb_descriptor_t * parent_scb,
+                                   struct dsp_scb_descriptor * snoop_scb,
+                                   struct dsp_scb_descriptor * parent_scb,
                                    int scb_child_type)
 {
 
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
   
-	output_snoop_scb_t output_snoop_scb = {
+	struct dsp_output_snoop_scb output_snoop_scb = {
 		{ 0,	/*  not used.  Zero */
 		  0,
 		  0,
@@ -1058,14 +1063,14 @@
 #endif /* not used */
 
 
-dsp_scb_descriptor_t * 
-cs46xx_dsp_create_spio_write_scb(cs46xx_t * chip,char * scb_name,u32 dest,
-                                 dsp_scb_descriptor_t * parent_scb,
+struct dsp_scb_descriptor * 
+cs46xx_dsp_create_spio_write_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
+                                 struct dsp_scb_descriptor * parent_scb,
                                  int scb_child_type)
 {
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
   
-	spio_write_scb_t spio_write_scb = {
+	struct dsp_spio_write_scb spio_write_scb = {
 		0,0,         /*   SPIOWAddress2:SPIOWAddress1; */
 		0,           /*   SPIOWData1; */
 		0,           /*   SPIOWData2; */
@@ -1094,15 +1099,16 @@
 	return scb;
 }
 
-dsp_scb_descriptor_t *  cs46xx_dsp_create_magic_snoop_scb(cs46xx_t * chip,char * scb_name,u32 dest,
-                                                          u16 snoop_buffer_address,
-                                                          dsp_scb_descriptor_t * snoop_scb,
-                                                          dsp_scb_descriptor_t * parent_scb,
-                                                          int scb_child_type)
+struct dsp_scb_descriptor *
+cs46xx_dsp_create_magic_snoop_scb(struct snd_cs46xx * chip, char * scb_name, u32 dest,
+				  u16 snoop_buffer_address,
+				  struct dsp_scb_descriptor * snoop_scb,
+				  struct dsp_scb_descriptor * parent_scb,
+				  int scb_child_type)
 {
-	dsp_scb_descriptor_t * scb;
+	struct dsp_scb_descriptor * scb;
   
-	magic_snoop_task_t magic_snoop_scb = {
+	struct dsp_magic_snoop_task magic_snoop_scb = {
 		/* 0 */ 0, /* i0 */
 		/* 1 */ 0, /* i1 */
 		/* 2 */ snoop_buffer_address << 0x10,
@@ -1129,10 +1135,11 @@
 	return scb;
 }
 
-static dsp_scb_descriptor_t * find_next_free_scb (cs46xx_t * chip,dsp_scb_descriptor_t * from)
+static struct dsp_scb_descriptor *
+find_next_free_scb (struct snd_cs46xx * chip, struct dsp_scb_descriptor * from)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * scb = from;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * scb = from;
 
 	while (scb->next_scb_ptr != ins->the_null_scb) {
 		snd_assert (scb->next_scb_ptr != NULL, return NULL);
@@ -1212,18 +1219,19 @@
 	0x2B00
 };
 
-pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,
-                                                          u32 sample_rate, void * private_data, 
-                                                          u32 hw_dma_addr,
-                                                          int pcm_channel_id)
+struct dsp_pcm_channel_descriptor *
+cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip,
+			       u32 sample_rate, void * private_data, 
+			       u32 hw_dma_addr,
+			       int pcm_channel_id)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * src_scb = NULL,* pcm_scb, * mixer_scb = NULL;
-	dsp_scb_descriptor_t * src_parent_scb = NULL;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * src_scb = NULL, * pcm_scb, * mixer_scb = NULL;
+	struct dsp_scb_descriptor * src_parent_scb = NULL;
 
-	/* dsp_scb_descriptor_t * pcm_parent_scb; */
+	/* struct dsp_scb_descriptor * pcm_parent_scb; */
 	char scb_name[DSP_MAX_SCB_NAME];
-	int i,pcm_index = -1, insert_point, src_index = -1,pass_through = 0;
+	int i, pcm_index = -1, insert_point, src_index = -1, pass_through = 0;
 	unsigned long flags;
 
 	switch (pcm_channel_id) {
@@ -1371,8 +1379,8 @@
 	return (ins->pcm_channels + pcm_index);
 }
 
-int cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
-				       pcm_channel_descriptor_t * pcm_channel,
+int cs46xx_dsp_pcm_channel_set_period (struct snd_cs46xx * chip,
+				       struct dsp_pcm_channel_descriptor * pcm_channel,
 				       int period_size)
 {
 	u32 temp = snd_cs46xx_peek (chip,pcm_channel->pcm_reader_scb->address << 2);
@@ -1410,7 +1418,7 @@
 	return 0;
 }
 
-int cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
+int cs46xx_dsp_pcm_ostream_set_period (struct snd_cs46xx * chip,
 				       int period_size)
 {
 	u32 temp = snd_cs46xx_peek (chip,WRITEBACK_SCB_ADDR << 2);
@@ -1448,9 +1456,10 @@
 	return 0;
 }
 
-void cs46xx_dsp_destroy_pcm_channel (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel)
+void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip,
+				     struct dsp_pcm_channel_descriptor * pcm_channel)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	unsigned long flags;
 
 	snd_assert(pcm_channel->active, return );
@@ -1478,9 +1487,10 @@
 	}
 }
 
-int cs46xx_dsp_pcm_unlink (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel)
+int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
+			   struct dsp_pcm_channel_descriptor * pcm_channel)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 	unsigned long flags;
 
 	snd_assert(pcm_channel->active,return -EIO);
@@ -1503,11 +1513,12 @@
 	return 0;
 }
 
-int cs46xx_dsp_pcm_link (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel)
+int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
+			 struct dsp_pcm_channel_descriptor * pcm_channel)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * parent_scb;
-	dsp_scb_descriptor_t * src_scb = pcm_channel->src_scb;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * parent_scb;
+	struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb;
 	unsigned long flags;
 
 	spin_lock(&pcm_channel->src_scb->lock);
@@ -1544,12 +1555,13 @@
 	return 0;
 }
 
-dsp_scb_descriptor_t * cs46xx_add_record_source (cs46xx_t *chip,dsp_scb_descriptor_t * source,
-                                                 u16 addr,char * scb_name)
+struct dsp_scb_descriptor *
+cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * source,
+			  u16 addr, char * scb_name)
 {
-  	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * parent;
-	dsp_scb_descriptor_t * pcm_input;
+  	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * parent;
+	struct dsp_scb_descriptor * pcm_input;
 	int insert_point;
 
 	snd_assert (ins->record_mixer_scb != NULL,return NULL);
@@ -1569,7 +1581,7 @@
 	return pcm_input;
 }
 
-int cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t * src)
+int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
 {
 	snd_assert (src->parent_scb_ptr != NULL,  return -EINVAL );
 
@@ -1581,10 +1593,10 @@
 	return 0;
 }
 
-int cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src)
+int cs46xx_src_link(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
-	dsp_scb_descriptor_t * parent_scb;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
+	struct dsp_scb_descriptor * parent_scb;
 
 	snd_assert (src->parent_scb_ptr == NULL,   return -EINVAL );
 	snd_assert(ins->master_mix_scb !=NULL,   return -EINVAL );
@@ -1605,9 +1617,9 @@
 	return 0;
 }
 
-int cs46xx_dsp_enable_spdif_out (cs46xx_t *chip)
+int cs46xx_dsp_enable_spdif_out (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	if ( ! (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) ) {
 		cs46xx_dsp_enable_spdif_hw (chip);
@@ -1653,9 +1665,9 @@
 	return 0;
 }
 
-int  cs46xx_dsp_disable_spdif_out (cs46xx_t *chip)
+int  cs46xx_dsp_disable_spdif_out (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	/* dont touch anything if SPDIF is open */
 	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN) {
@@ -1685,9 +1697,9 @@
 	return 0;
 }
 
-int cs46xx_iec958_pre_open (cs46xx_t *chip)
+int cs46xx_iec958_pre_open (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	if ( ins->spdif_status_out & DSP_SPDIF_STATUS_OUTPUT_ENABLED ) {
 		/* remove AsynchFGTxSCB and and PCMSerialInput_II */
@@ -1718,9 +1730,9 @@
 	return 0;
 }
 
-int cs46xx_iec958_post_close (cs46xx_t *chip)
+int cs46xx_iec958_post_close (struct snd_cs46xx *chip)
 {
-	dsp_spos_instance_t * ins = chip->dsp_spos_instance;
+	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
 
 	snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL);
 
diff --git a/sound/pci/cs46xx/imgs/cwc4630.h b/sound/pci/cs46xx/imgs/cwc4630.h
index 8bed07f..37c4f13 100644
--- a/sound/pci/cs46xx/imgs/cwc4630.h
+++ b/sound/pci/cs46xx/imgs/cwc4630.h
@@ -3,7 +3,7 @@
 #ifndef __HEADER_cwc4630_H__
 #define __HEADER_cwc4630_H__
 
-static symbol_entry_t cwc4630_symbols[] = {
+static struct dsp_symbol_entry cwc4630_symbols[] = {
   { 0x0000, "BEGINADDRESS",0x00 },
   { 0x8000, "EXECCHILD",0x03 },
   { 0x8001, "EXECCHILD_98",0x03 },
@@ -302,12 +302,12 @@
 }; /* #PARAMETER_END */
 
 
-static segment_desc_t cwc4630_segments[] = {
+static struct dsp_segment_desc cwc4630_segments[] = {
   { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000328, cwc4630_code },
   { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000080, cwc4630_parameter },
 };
 
-static dsp_module_desc_t cwc4630_module = {
+static struct dsp_module_desc cwc4630_module = {
   "cwc4630",
   {
     38,
diff --git a/sound/pci/cs46xx/imgs/cwcasync.h b/sound/pci/cs46xx/imgs/cwcasync.h
index e01a7b6..70e63e1 100644
--- a/sound/pci/cs46xx/imgs/cwcasync.h
+++ b/sound/pci/cs46xx/imgs/cwcasync.h
@@ -3,7 +3,7 @@
 #ifndef __HEADER_cwcasync_H__
 #define __HEADER_cwcasync_H__
 
-static symbol_entry_t cwcasync_symbols[] = {
+static struct dsp_symbol_entry cwcasync_symbols[] = {
   { 0x8000, "EXECCHILD",0x03 },
   { 0x8001, "EXECCHILD_98",0x03 },
   { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
@@ -159,11 +159,11 @@
 };
 /* #CODE_END */
 
-static segment_desc_t cwcasync_segments[] = {
+static struct dsp_segment_desc cwcasync_segments[] = {
   { SEGTYPE_SP_PROGRAM, 0x00000000, 0x000001b6, cwcasync_code },
 };
 
-static dsp_module_desc_t cwcasync_module = {
+static struct dsp_module_desc cwcasync_module = {
   "cwcasync",
   {
     32,
diff --git a/sound/pci/cs46xx/imgs/cwcbinhack.h b/sound/pci/cs46xx/imgs/cwcbinhack.h
index 436b38b..f4d9368 100644
--- a/sound/pci/cs46xx/imgs/cwcbinhack.h
+++ b/sound/pci/cs46xx/imgs/cwcbinhack.h
@@ -4,7 +4,7 @@
 #ifndef __HEADER_cwcbinhack_H__
 #define __HEADER_cwcbinhack_H__
 
-static symbol_entry_t cwcbinhack_symbols[] = {
+static struct dsp_symbol_entry cwcbinhack_symbols[] = {
   { 0x02c8, "OVERLAYBEGINADDRESS",0x00 },
   { 0x02c8, "MAGICSNOOPTASK",0x03 },
   { 0x0308, "#CODE_END",0x00 },
@@ -31,11 +31,11 @@
 };
 /* #CODE_END */
 
-static segment_desc_t cwcbinhack_segments[] = {
+static struct dsp_segment_desc cwcbinhack_segments[] = {
   { SEGTYPE_SP_PROGRAM, 0x00000000, 64, cwcbinhack_code },
 };
 
-static dsp_module_desc_t cwcbinhack_module = {
+static struct dsp_module_desc cwcbinhack_module = {
   "cwcbinhack",
   {
     3,
diff --git a/sound/pci/cs46xx/imgs/cwcdma.h b/sound/pci/cs46xx/imgs/cwcdma.h
index 9286043..7ff0d45 100644
--- a/sound/pci/cs46xx/imgs/cwcdma.h
+++ b/sound/pci/cs46xx/imgs/cwcdma.h
@@ -3,7 +3,7 @@
 #ifndef __HEADER_cwcdma_H__
 #define __HEADER_cwcdma_H__
 
-static symbol_entry_t cwcdma_symbols[] = {
+static struct dsp_symbol_entry cwcdma_symbols[] = {
   { 0x8000, "EXECCHILD",0x03 },
   { 0x8001, "EXECCHILD_98",0x03 },
   { 0x8003, "EXECCHILD_PUSH1IND",0x03 },
@@ -51,11 +51,11 @@
 
 /* #CODE_END */
 
-static segment_desc_t cwcdma_segments[] = {
+static struct dsp_segment_desc cwcdma_segments[] = {
   { SEGTYPE_SP_PROGRAM, 0x00000000, 0x00000030, cwcdma_code },
 };
 
-static dsp_module_desc_t cwcdma_module = {
+static struct dsp_module_desc cwcdma_module = {
   "cwcdma",
   {
     27,
diff --git a/sound/pci/cs46xx/imgs/cwcemb80.h b/sound/pci/cs46xx/imgs/cwcemb80.h
index 4b13551..a64c6ff 100644
--- a/sound/pci/cs46xx/imgs/cwcemb80.h
+++ b/sound/pci/cs46xx/imgs/cwcemb80.h
@@ -3,7 +3,7 @@
 #ifndef __HEADER_cwcemb80_H__
 #define __HEADER_cwcemb80_H__
 
-static symbol_entry_t cwcemb80_symbols[] = {
+static struct dsp_symbol_entry cwcemb80_symbols[] = {
   { 0x0000, "BEGINADDRESS",0x00 },
   { 0x8000, "EXECCHILD",0x03 },
   { 0x8001, "EXECCHILD_98",0x03 },
@@ -1588,13 +1588,13 @@
 }; /* #SAMPLE_END */
 
 
-static segment_desc_t cwcemb80_segments[] = {
+static struct dsp_segment_desc cwcemb80_segments[] = {
   { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000031c, cwcemb80_code },
   { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000697, cwcemb80_parameter },
   { SEGTYPE_SP_SAMPLE, 0x00000000, 0x00000e00, cwcemb80_sample },
 };
 
-static dsp_module_desc_t cwcemb80_module = {
+static struct dsp_module_desc cwcemb80_module = {
   "cwcemb80",
   {
     38,
diff --git a/sound/pci/cs46xx/imgs/cwcsnoop.h b/sound/pci/cs46xx/imgs/cwcsnoop.h
index be1162b..6929d0a 100644
--- a/sound/pci/cs46xx/imgs/cwcsnoop.h
+++ b/sound/pci/cs46xx/imgs/cwcsnoop.h
@@ -3,7 +3,7 @@
 #ifndef __HEADER_cwcsnoop_H__
 #define __HEADER_cwcsnoop_H__
 
-static symbol_entry_t cwcsnoop_symbols[] = {
+static struct dsp_symbol_entry cwcsnoop_symbols[] = {
   { 0x0500, "OVERLAYBEGINADDRESS",0x00 },
   { 0x0500, "OUTPUTSNOOP",0x03 },
   { 0x051f, "#CODE_END",0x00 },
@@ -29,11 +29,11 @@
 };
 /* #CODE_END */
 
-static segment_desc_t cwcsnoop_segments[] = {
+static struct dsp_segment_desc cwcsnoop_segments[] = {
   { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000003e, cwcsnoop_code },
 };
 
-static dsp_module_desc_t cwcsnoop_module = {
+static struct dsp_module_desc cwcsnoop_module = {
   "cwcsnoop",
   {
     3,
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
new file mode 100644
index 0000000..08d8ee6
--- /dev/null
+++ b/sound/pci/cs5535audio/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for cs5535audio
+#
+
+snd-cs5535audio-objs := cs5535audio.o cs5535audio_pcm.o
+
+# Toplevel Module Dependency
+obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
new file mode 100644
index 0000000..202c7cf
--- /dev/null
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -0,0 +1,402 @@
+/*
+ * Driver for audio on multifunction CS5535 companion device
+ * Copyright (C) Jaya Kumar
+ *
+ * Based on Jaroslav Kysela and Takashi Iwai's examples.
+ * This work was sponsored by CIS(M) Sdn Bhd.
+ *
+ * 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 <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/moduleparam.h>
+#include <asm/io.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/rawmidi.h>
+#include <sound/ac97_codec.h>
+#include <sound/initval.h>
+#include <sound/asoundef.h>
+#include "cs5535audio.h"
+
+#define DRIVER_NAME "cs5535audio"
+
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+static struct pci_device_id snd_cs5535audio_ids[] = {
+	{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO, PCI_ANY_ID,
+		PCI_ANY_ID, 0, 0, 0, },
+	{}
+};
+
+MODULE_DEVICE_TABLE(pci, snd_cs5535audio_ids);
+
+static void wait_till_cmd_acked(struct cs5535audio *cs5535au, unsigned long timeout)
+{
+	unsigned int tmp;
+	do {
+		tmp = cs_readl(cs5535au, ACC_CODEC_CNTL);
+		if (!(tmp & CMD_NEW))
+			break;
+		msleep(10);
+	} while (--timeout);
+	if (!timeout)
+		snd_printk(KERN_ERR "Failure writing to cs5535 codec\n");
+}
+
+static unsigned short snd_cs5535audio_codec_read(struct cs5535audio *cs5535au,
+						 unsigned short reg)
+{
+	unsigned int regdata;
+	unsigned int timeout;
+	unsigned int val;
+
+	regdata = ((unsigned int) reg) << 24;
+	regdata |= ACC_CODEC_CNTL_RD_CMD;
+	regdata |= CMD_NEW;
+
+	cs_writel(cs5535au, ACC_CODEC_CNTL, regdata);
+	wait_till_cmd_acked(cs5535au, 500);
+
+	timeout = 50;
+	do {
+		val = cs_readl(cs5535au, ACC_CODEC_STATUS);
+		if ((val & STS_NEW) && reg == (val >> 24))
+			break;
+		msleep(10);
+	} while (--timeout);
+	if (!timeout)
+		snd_printk(KERN_ERR "Failure reading cs5535 codec\n");
+
+	return (unsigned short) val;
+}
+
+static void snd_cs5535audio_codec_write(struct cs5535audio *cs5535au,
+					unsigned short reg, unsigned short val)
+{
+	unsigned int regdata;
+
+	regdata = ((unsigned int) reg) << 24;
+	regdata |= val;
+	regdata &= CMD_MASK;
+	regdata |= CMD_NEW;
+	regdata &= ACC_CODEC_CNTL_WR_CMD;
+
+	cs_writel(cs5535au, ACC_CODEC_CNTL, regdata);
+	wait_till_cmd_acked(cs5535au, 50);
+}
+
+static void snd_cs5535audio_ac97_codec_write(struct snd_ac97 *ac97,
+					     unsigned short reg, unsigned short val)
+{
+	struct cs5535audio *cs5535au = ac97->private_data;
+	snd_cs5535audio_codec_write(cs5535au, reg, val);
+}
+
+static unsigned short snd_cs5535audio_ac97_codec_read(struct snd_ac97 *ac97,
+						      unsigned short reg)
+{
+	struct cs5535audio *cs5535au = ac97->private_data;
+	return snd_cs5535audio_codec_read(cs5535au, reg);
+}
+
+static int snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
+{
+	struct snd_card *card = cs5535au->card;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
+	int err;
+	static struct snd_ac97_bus_ops ops = {
+		.write = snd_cs5535audio_ac97_codec_write,
+		.read = snd_cs5535audio_ac97_codec_read,
+	};
+
+	if ((err = snd_ac97_bus(card, 0, &ops, NULL, &pbus)) < 0)
+		return err;
+
+	memset(&ac97, 0, sizeof(ac97));
+	ac97.scaps = AC97_SCAP_AUDIO|AC97_SCAP_SKIP_MODEM;
+	ac97.private_data = cs5535au;
+	ac97.pci = cs5535au->pci;
+
+	if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) {
+		snd_printk(KERN_ERR "mixer failed\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static void process_bm0_irq(struct cs5535audio *cs5535au)
+{
+	u8 bm_stat;
+	spin_lock(&cs5535au->reg_lock);
+	bm_stat = cs_readb(cs5535au, ACC_BM0_STATUS);
+	spin_unlock(&cs5535au->reg_lock);
+	if (bm_stat & EOP) {
+		struct cs5535audio_dma *dma;
+		dma = cs5535au->playback_substream->runtime->private_data;
+		snd_pcm_period_elapsed(cs5535au->playback_substream);
+	} else {
+		snd_printk(KERN_ERR "unexpected bm0 irq src, bm_stat=%x\n",
+					bm_stat);
+	}
+}
+
+static void process_bm1_irq(struct cs5535audio *cs5535au)
+{
+	u8 bm_stat;
+	spin_lock(&cs5535au->reg_lock);
+	bm_stat = cs_readb(cs5535au, ACC_BM1_STATUS);
+	spin_unlock(&cs5535au->reg_lock);
+	if (bm_stat & EOP) {
+		struct cs5535audio_dma *dma;
+		dma = cs5535au->capture_substream->runtime->private_data;
+		snd_pcm_period_elapsed(cs5535au->capture_substream);
+	}
+}
+
+static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id,
+					     struct pt_regs *regs)
+{
+	u16 acc_irq_stat;
+	u8 bm_stat;
+	unsigned char count;
+	struct cs5535audio *cs5535au = dev_id;
+
+	if (cs5535au == NULL)
+		return IRQ_NONE;
+
+	acc_irq_stat = cs_readw(cs5535au, ACC_IRQ_STATUS);
+
+	if (!acc_irq_stat)
+		return IRQ_NONE;
+	for (count = 0; count < 10; count++) {
+		if (acc_irq_stat & (1 << count)) {
+			switch (count) {
+			case IRQ_STS:
+				cs_readl(cs5535au, ACC_GPIO_STATUS);
+				break;
+			case WU_IRQ_STS:
+				cs_readl(cs5535au, ACC_GPIO_STATUS);
+				break;
+			case BM0_IRQ_STS:
+				process_bm0_irq(cs5535au);
+				break;
+			case BM1_IRQ_STS:
+				process_bm1_irq(cs5535au);
+				break;
+			case BM2_IRQ_STS:
+				bm_stat = cs_readb(cs5535au, ACC_BM2_STATUS);
+				break;
+			case BM3_IRQ_STS:
+				bm_stat = cs_readb(cs5535au, ACC_BM3_STATUS);
+				break;
+			case BM4_IRQ_STS:
+				bm_stat = cs_readb(cs5535au, ACC_BM4_STATUS);
+				break;
+			case BM5_IRQ_STS:
+				bm_stat = cs_readb(cs5535au, ACC_BM5_STATUS);
+				break;
+			case BM6_IRQ_STS:
+				bm_stat = cs_readb(cs5535au, ACC_BM6_STATUS);
+				break;
+			case BM7_IRQ_STS:
+				bm_stat = cs_readb(cs5535au, ACC_BM7_STATUS);
+				break;
+			default:
+				snd_printk(KERN_ERR "Unexpected irq src\n");
+				break;
+			}
+		}
+	}
+	return IRQ_HANDLED;
+}
+
+static int snd_cs5535audio_free(struct cs5535audio *cs5535au)
+{
+	synchronize_irq(cs5535au->irq);
+	pci_set_power_state(cs5535au->pci, 3);
+
+	if (cs5535au->irq >= 0)
+		free_irq(cs5535au->irq, cs5535au);
+
+	pci_release_regions(cs5535au->pci);
+	pci_disable_device(cs5535au->pci);
+	kfree(cs5535au);
+	return 0;
+}
+
+static int snd_cs5535audio_dev_free(struct snd_device *device)
+{
+	struct cs5535audio *cs5535au = device->device_data;
+	return snd_cs5535audio_free(cs5535au);
+}
+
+static int __devinit snd_cs5535audio_create(struct snd_card *card,
+					    struct pci_dev *pci,
+					    struct cs5535audio **rcs5535au)
+{
+	struct cs5535audio *cs5535au;
+
+	int err;
+	static struct snd_device_ops ops = {
+		.dev_free =	snd_cs5535audio_dev_free,
+	};
+
+	*rcs5535au = NULL;
+	if ((err = pci_enable_device(pci)) < 0)
+		return err;
+
+	if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
+	    pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
+		printk(KERN_WARNING "unable to get 32bit dma\n");
+		err = -ENXIO;
+		goto pcifail;
+	}
+
+	cs5535au = kzalloc(sizeof(*cs5535au), GFP_KERNEL);
+	if (cs5535au == NULL) {
+		err = -ENOMEM;
+		goto pcifail;
+	}
+
+	spin_lock_init(&cs5535au->reg_lock);
+	cs5535au->card = card;
+	cs5535au->pci = pci;
+	cs5535au->irq = -1;
+
+	if ((err = pci_request_regions(pci, "CS5535 Audio")) < 0) {
+		kfree(cs5535au);
+		goto pcifail;
+	}
+
+	cs5535au->port = pci_resource_start(pci, 0);
+
+	if (request_irq(pci->irq, snd_cs5535audio_interrupt,
+			SA_INTERRUPT|SA_SHIRQ, "CS5535 Audio", cs5535au)) {
+		snd_printk("unable to grab IRQ %d\n", pci->irq);
+		err = -EBUSY;
+		goto sndfail;
+	}
+
+	cs5535au->irq = pci->irq;
+	pci_set_master(pci);
+
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
+				  cs5535au, &ops)) < 0)
+		goto sndfail;
+
+	snd_card_set_dev(card, &pci->dev);
+
+	*rcs5535au = cs5535au;
+	return 0;
+
+sndfail: /* leave the device alive, just kill the snd */
+	snd_cs5535audio_free(cs5535au);
+	return err;
+
+pcifail:
+	pci_disable_device(pci);
+	return err;
+}
+
+static int __devinit snd_cs5535audio_probe(struct pci_dev *pci,
+					   const struct pci_device_id *pci_id)
+{
+	static int dev;
+	struct snd_card *card;
+	struct cs5535audio *cs5535au;
+	int err;
+
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+	if (card == NULL)
+		return -ENOMEM;
+
+	if ((err = snd_cs5535audio_create(card, pci, &cs5535au)) < 0)
+		goto probefail_out;
+
+	if ((err = snd_cs5535audio_mixer(cs5535au)) < 0)
+		goto probefail_out;
+
+	if ((err = snd_cs5535audio_pcm(cs5535au)) < 0)
+		goto probefail_out;
+
+	strcpy(card->driver, DRIVER_NAME);
+
+	strcpy(card->shortname, "CS5535 Audio");
+	sprintf(card->longname, "%s %s at 0x%lx, irq %i",
+		card->shortname, card->driver,
+		cs5535au->port, cs5535au->irq);
+
+	if ((err = snd_card_register(card)) < 0)
+		goto probefail_out;
+
+	pci_set_drvdata(pci, card);
+	dev++;
+	return 0;
+
+probefail_out:
+	snd_card_free(card);
+	return err;
+}
+
+static void __devexit snd_cs5535audio_remove(struct pci_dev *pci)
+{
+	snd_card_free(pci_get_drvdata(pci));
+	pci_set_drvdata(pci, NULL);
+}
+
+static struct pci_driver driver = {
+	.name = DRIVER_NAME,
+	.id_table = snd_cs5535audio_ids,
+	.probe = snd_cs5535audio_probe,
+	.remove = __devexit_p(snd_cs5535audio_remove),
+};
+
+static int __init alsa_card_cs5535audio_init(void)
+{
+	return pci_module_init(&driver);
+}
+
+static void __exit alsa_card_cs5535audio_exit(void)
+{
+	pci_unregister_driver(&driver);
+}
+
+module_init(alsa_card_cs5535audio_init)
+module_exit(alsa_card_cs5535audio_exit)
+
+MODULE_AUTHOR("Jaya Kumar");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CS5535 Audio");
+MODULE_SUPPORTED_DEVICE("CS5535 Audio");
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
new file mode 100644
index 0000000..5e55a1a
--- /dev/null
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -0,0 +1,123 @@
+#ifndef __SOUND_CS5535AUDIO_H
+#define __SOUND_CS5535AUDIO_H
+
+#define cs_writel(cs5535au, reg, val)	outl(val, (cs5535au)->port + reg)
+#define cs_writeb(cs5535au, reg, val)	outb(val, (cs5535au)->port + reg)
+#define cs_readl(cs5535au, reg)		inl((cs5535au)->port + reg)
+#define cs_readw(cs5535au, reg)		inw((cs5535au)->port + reg)
+#define cs_readb(cs5535au, reg)		inb((cs5535au)->port + reg)
+
+#define CS5535AUDIO_MAX_DESCRIPTORS	128
+
+/* acc_codec bar0 reg addrs */
+#define ACC_GPIO_STATUS			0x00
+#define ACC_CODEC_STATUS		0x08
+#define ACC_CODEC_CNTL			0x0C
+#define ACC_IRQ_STATUS			0x12
+#define ACC_BM0_CMD			0x20
+#define ACC_BM1_CMD			0x28
+#define ACC_BM2_CMD			0x30
+#define ACC_BM3_CMD			0x38
+#define ACC_BM4_CMD			0x40
+#define ACC_BM5_CMD			0x48
+#define ACC_BM6_CMD			0x50
+#define ACC_BM7_CMD			0x58
+#define ACC_BM0_PRD			0x24
+#define ACC_BM1_PRD			0x2C
+#define ACC_BM2_PRD			0x34
+#define ACC_BM3_PRD			0x3C
+#define ACC_BM4_PRD			0x44
+#define ACC_BM5_PRD			0x4C
+#define ACC_BM6_PRD			0x54
+#define ACC_BM7_PRD			0x5C
+#define ACC_BM0_STATUS			0x21
+#define ACC_BM1_STATUS			0x29
+#define ACC_BM2_STATUS			0x31
+#define ACC_BM3_STATUS			0x39
+#define ACC_BM4_STATUS			0x41
+#define ACC_BM5_STATUS			0x49
+#define ACC_BM6_STATUS			0x51
+#define ACC_BM7_STATUS			0x59
+#define ACC_BM0_PNTR			0x60
+#define ACC_BM1_PNTR			0x64
+#define ACC_BM2_PNTR			0x68
+#define ACC_BM3_PNTR			0x6C
+#define ACC_BM4_PNTR			0x70
+#define ACC_BM5_PNTR			0x74
+#define ACC_BM6_PNTR			0x78
+#define ACC_BM7_PNTR			0x7C
+/* acc_codec bar0 reg bits */
+/* ACC_IRQ_STATUS */
+#define IRQ_STS 			0
+#define WU_IRQ_STS 			1
+#define BM0_IRQ_STS 			2
+#define BM1_IRQ_STS 			3
+#define BM2_IRQ_STS 			4
+#define BM3_IRQ_STS 			5
+#define BM4_IRQ_STS 			6
+#define BM5_IRQ_STS		 	7
+#define BM6_IRQ_STS 			8
+#define BM7_IRQ_STS 			9
+/* ACC_BMX_STATUS */
+#define EOP				(1<<0)
+#define BM_EOP_ERR			(1<<1)
+/* ACC_BMX_CTL */
+#define BM_CTL_EN			0x00000001
+#define BM_CTL_PAUSE			0x00000011
+#define BM_CTL_DIS			0x00000000
+#define BM_CTL_BYTE_ORD_LE		0x00000000
+#define BM_CTL_BYTE_ORD_BE		0x00000100
+/* cs5535 specific ac97 codec register defines */
+#define CMD_MASK			0xFF00FFFF
+#define CMD_NEW				0x00010000
+#define STS_NEW				0x00020000
+#define PRM_RDY_STS			0x00800000
+#define ACC_CODEC_CNTL_WR_CMD		(~0x80000000)
+#define ACC_CODEC_CNTL_RD_CMD		0x80000000
+#define PRD_JMP				0x2000
+#define PRD_EOP				0x4000
+#define PRD_EOT				0x8000
+
+enum { CS5535AUDIO_DMA_PLAYBACK, CS5535AUDIO_DMA_CAPTURE, NUM_CS5535AUDIO_DMAS };
+
+struct cs5535audio;
+
+struct cs5535audio_dma_ops {
+	int type;
+	void (*enable_dma)(struct cs5535audio *cs5535au);
+	void (*disable_dma)(struct cs5535audio *cs5535au);
+	void (*pause_dma)(struct cs5535audio *cs5535au);
+	void (*setup_prd)(struct cs5535audio *cs5535au, u32 prd_addr);
+	u32 (*read_dma_pntr)(struct cs5535audio *cs5535au);
+};
+
+struct cs5535audio_dma_desc {
+	u32 addr;
+	u16 size;
+	u16 ctlreserved;
+};
+
+struct cs5535audio_dma {
+	const struct cs5535audio_dma_ops *ops;
+	struct snd_dma_buffer desc_buf;
+	struct snd_pcm_substream *substream;
+	unsigned int buf_addr, buf_bytes;
+	unsigned int period_bytes, periods;
+};
+
+struct cs5535audio {
+	struct snd_card *card;
+	struct snd_ac97 *ac97;
+	int irq;
+	struct pci_dev *pci;
+	unsigned long port;
+	spinlock_t reg_lock;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+	struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
+};
+
+int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
+
+#endif /* __SOUND_CS5535AUDIO_H */
+
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
new file mode 100644
index 0000000..60bb82b
--- /dev/null
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -0,0 +1,419 @@
+/*
+ * Driver for audio on multifunction CS5535 companion device
+ * Copyright (C) Jaya Kumar
+ *
+ * Based on Jaroslav Kysela and Takashi Iwai's examples.
+ * This work was sponsored by CIS(M) Sdn Bhd.
+ *
+ * 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
+ *
+ * todo: add be fmt support, spdif, pm
+ */
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/initval.h>
+#include <sound/asoundef.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/ac97_codec.h>
+#include "cs5535audio.h"
+
+static struct snd_pcm_hardware snd_cs5535audio_playback =
+{
+	.info =			(
+				SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_INTERLEAVED |
+		 		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		 		SNDRV_PCM_INFO_MMAP_VALID |
+		 		SNDRV_PCM_INFO_PAUSE |
+				SNDRV_PCM_INFO_SYNC_START
+				),
+	.formats =		(
+				SNDRV_PCM_FMTBIT_S16_LE
+				),
+	.rates =		(
+				SNDRV_PCM_RATE_CONTINUOUS |
+				SNDRV_PCM_RATE_8000_48000
+				),
+	.rate_min =		4000,
+	.rate_max =		48000,
+	.channels_min =		2,
+	.channels_max =		2,
+	.buffer_bytes_max =	(128*1024),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(64*1024 - 16),
+	.periods_min =		1,
+	.periods_max =		CS5535AUDIO_MAX_DESCRIPTORS,
+	.fifo_size =		0,
+};
+
+static struct snd_pcm_hardware snd_cs5535audio_capture =
+{
+	.info =			(
+				SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_INTERLEAVED |
+		 		SNDRV_PCM_INFO_BLOCK_TRANSFER |
+		 		SNDRV_PCM_INFO_MMAP_VALID |
+				SNDRV_PCM_INFO_SYNC_START
+				),
+	.formats =		(
+				SNDRV_PCM_FMTBIT_S16_LE
+				),
+	.rates =		(
+				SNDRV_PCM_RATE_CONTINUOUS |
+				SNDRV_PCM_RATE_8000_48000
+				),
+	.rate_min =		4000,
+	.rate_max =		48000,
+	.channels_min =		2,
+	.channels_max =		2,
+	.buffer_bytes_max =	(128*1024),
+	.period_bytes_min =	64,
+	.period_bytes_max =	(64*1024 - 16),
+	.periods_min =		1,
+	.periods_max =		CS5535AUDIO_MAX_DESCRIPTORS,
+	.fifo_size =		0,
+};
+
+static int snd_cs5535audio_playback_open(struct snd_pcm_substream *substream)
+{
+	int err;
+	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	runtime->hw = snd_cs5535audio_playback;
+	cs5535au->playback_substream = substream;
+	runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK]);
+	snd_pcm_set_sync(substream);
+	if ((err = snd_pcm_hw_constraint_integer(runtime,
+				SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+		return err;
+
+	return 0;
+}
+
+static int snd_cs5535audio_playback_close(struct snd_pcm_substream *substream)
+{
+	return 0;
+}
+
+#define CS5535AUDIO_DESC_LIST_SIZE \
+	PAGE_ALIGN(CS5535AUDIO_MAX_DESCRIPTORS * sizeof(struct cs5535audio_dma_desc))
+
+static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
+					 struct cs5535audio_dma *dma,
+					 struct snd_pcm_substream *substream,
+					 unsigned int periods,
+					 unsigned int period_bytes)
+{
+	unsigned int i;
+	u32 addr, desc_addr, jmpprd_addr;
+	struct cs5535audio_dma_desc *lastdesc;
+
+	if (periods > CS5535AUDIO_MAX_DESCRIPTORS)
+		return -ENOMEM;
+
+	if (dma->desc_buf.area == NULL) {
+		if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+					snd_dma_pci_data(cs5535au->pci),
+					CS5535AUDIO_DESC_LIST_SIZE+1,
+					&dma->desc_buf) < 0)
+			return -ENOMEM;
+		dma->period_bytes = dma->periods = 0;
+	}
+
+	if (dma->periods == periods && dma->period_bytes == period_bytes)
+		return 0;
+
+	/* the u32 cast is okay because in snd*create we succesfully told
+   	   pci alloc that we're only 32 bit capable so the uppper will be 0 */
+	addr = (u32) substream->runtime->dma_addr;
+	desc_addr = (u32) dma->desc_buf.addr;
+	for (i = 0; i < periods; i++) {
+		struct cs5535audio_dma_desc *desc =
+			&((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i];
+		desc->addr = cpu_to_le32(addr);
+		desc->size = cpu_to_le32(period_bytes);
+		desc->ctlreserved = cpu_to_le32(PRD_EOP);
+		desc_addr += sizeof(struct cs5535audio_dma_desc);
+		addr += period_bytes;
+	}
+	/* we reserved one dummy descriptor at the end to do the PRD jump */
+	lastdesc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[periods];
+	lastdesc->addr = cpu_to_le32((u32) dma->desc_buf.addr);
+	lastdesc->size = 0;
+	lastdesc->ctlreserved = cpu_to_le32(PRD_JMP);
+	jmpprd_addr = cpu_to_le32(lastdesc->addr +
+				  (sizeof(struct cs5535audio_dma_desc)*periods));
+
+	dma->period_bytes = period_bytes;
+	dma->periods = periods;
+	spin_lock_irq(&cs5535au->reg_lock);
+	dma->ops->disable_dma(cs5535au);
+	dma->ops->setup_prd(cs5535au, jmpprd_addr);
+	spin_unlock_irq(&cs5535au->reg_lock);
+	return 0;
+}
+
+static void cs5535audio_playback_enable_dma(struct cs5535audio *cs5535au)
+{
+	cs_writeb(cs5535au, ACC_BM0_CMD, BM_CTL_EN);
+}
+
+static void cs5535audio_playback_disable_dma(struct cs5535audio *cs5535au)
+{
+	cs_writeb(cs5535au, ACC_BM0_CMD, 0);
+}
+
+static void cs5535audio_playback_pause_dma(struct cs5535audio *cs5535au)
+{
+	cs_writeb(cs5535au, ACC_BM0_CMD, BM_CTL_PAUSE);
+}
+
+static void cs5535audio_playback_setup_prd(struct cs5535audio *cs5535au,
+					   u32 prd_addr)
+{
+	cs_writel(cs5535au, ACC_BM0_PRD, prd_addr);
+}
+
+static u32 cs5535audio_playback_read_dma_pntr(struct cs5535audio *cs5535au)
+{
+	return cs_readl(cs5535au, ACC_BM0_PNTR);
+}
+
+static void cs5535audio_capture_enable_dma(struct cs5535audio *cs5535au)
+{
+	cs_writeb(cs5535au, ACC_BM1_CMD, BM_CTL_EN);
+}
+
+static void cs5535audio_capture_disable_dma(struct cs5535audio *cs5535au)
+{
+	cs_writeb(cs5535au, ACC_BM1_CMD, 0);
+}
+
+static void cs5535audio_capture_pause_dma(struct cs5535audio *cs5535au)
+{
+	cs_writeb(cs5535au, ACC_BM1_CMD, BM_CTL_PAUSE);
+}
+
+static void cs5535audio_capture_setup_prd(struct cs5535audio *cs5535au,
+					  u32 prd_addr)
+{
+	cs_writel(cs5535au, ACC_BM1_PRD, prd_addr);
+}
+
+static u32 cs5535audio_capture_read_dma_pntr(struct cs5535audio *cs5535au)
+{
+	return cs_readl(cs5535au, ACC_BM1_PNTR);
+}
+
+static void cs5535audio_clear_dma_packets(struct cs5535audio *cs5535au,
+					  struct cs5535audio_dma *dma,
+					  struct snd_pcm_substream *substream)
+{
+	snd_dma_free_pages(&dma->desc_buf);
+	dma->desc_buf.area = NULL;
+}
+
+static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
+				     struct snd_pcm_hw_params *hw_params)
+{
+	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+	struct cs5535audio_dma *dma = substream->runtime->private_data;
+	int err;
+
+	err = snd_pcm_lib_malloc_pages(substream,
+					params_buffer_bytes(hw_params));
+	if (err < 0)
+		return err;
+	dma->buf_addr = substream->runtime->dma_addr;
+	dma->buf_bytes = params_buffer_bytes(hw_params);
+
+	err = cs5535audio_build_dma_packets(cs5535au, dma, substream,
+					    params_periods(hw_params),
+					    params_period_bytes(hw_params));
+	return err;
+}
+
+static int snd_cs5535audio_hw_free(struct snd_pcm_substream *substream)
+{
+	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+	struct cs5535audio_dma *dma = substream->runtime->private_data;
+
+	cs5535audio_clear_dma_packets(cs5535au, dma, substream);
+	return snd_pcm_lib_free_pages(substream);
+}
+
+static int snd_cs5535audio_playback_prepare(struct snd_pcm_substream *substream)
+{
+	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+	return snd_ac97_set_rate(cs5535au->ac97, AC97_PCM_FRONT_DAC_RATE,
+				 substream->runtime->rate);
+}
+
+static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+	struct cs5535audio_dma *dma = substream->runtime->private_data;
+	int err = 0;
+
+	spin_lock(&cs5535au->reg_lock);
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		dma->ops->pause_dma(cs5535au);
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		dma->ops->enable_dma(cs5535au);
+		break;
+	case SNDRV_PCM_TRIGGER_START:
+		dma->ops->enable_dma(cs5535au);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		dma->ops->disable_dma(cs5535au);
+		break;
+	default:
+		snd_printk(KERN_ERR "unhandled trigger\n");
+		err = -EINVAL;
+		break;
+	}
+	spin_unlock(&cs5535au->reg_lock);
+	return err;
+}
+
+static snd_pcm_uframes_t snd_cs5535audio_pcm_pointer(struct snd_pcm_substream
+							*substream)
+{
+	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+	u32 curdma;
+	struct cs5535audio_dma *dma;
+
+	dma = substream->runtime->private_data;
+	curdma = dma->ops->read_dma_pntr(cs5535au);
+	if (curdma < dma->buf_addr) {
+		snd_printk(KERN_ERR "curdma=%x < %x bufaddr.\n",
+					curdma, dma->buf_addr);
+		return 0;
+	}
+	curdma -= dma->buf_addr;
+	if (curdma >= dma->buf_bytes) {
+		snd_printk(KERN_ERR "diff=%x >= %x buf_bytes.\n",
+					curdma, dma->buf_bytes);
+		return 0;
+	}
+	return bytes_to_frames(substream->runtime, curdma);
+}
+
+static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
+{
+	int err;
+	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	runtime->hw = snd_cs5535audio_capture;
+	cs5535au->capture_substream = substream;
+	runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE]);
+	snd_pcm_set_sync(substream);
+	if ((err = snd_pcm_hw_constraint_integer(runtime,
+					 SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
+		return err;
+	return 0;
+}
+
+static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream)
+{
+	return 0;
+}
+
+static int snd_cs5535audio_capture_prepare(struct snd_pcm_substream *substream)
+{
+	struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
+	return snd_ac97_set_rate(cs5535au->ac97, AC97_PCM_LR_ADC_RATE,
+				 substream->runtime->rate);
+}
+
+static struct snd_pcm_ops snd_cs5535audio_playback_ops = {
+	.open =		snd_cs5535audio_playback_open,
+	.close =	snd_cs5535audio_playback_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_cs5535audio_hw_params,
+	.hw_free =	snd_cs5535audio_hw_free,
+	.prepare =	snd_cs5535audio_playback_prepare,
+	.trigger =	snd_cs5535audio_trigger,
+	.pointer =	snd_cs5535audio_pcm_pointer,
+};
+
+static struct snd_pcm_ops snd_cs5535audio_capture_ops = {
+	.open =		snd_cs5535audio_capture_open,
+	.close =	snd_cs5535audio_capture_close,
+	.ioctl =	snd_pcm_lib_ioctl,
+	.hw_params =	snd_cs5535audio_hw_params,
+	.hw_free =	snd_cs5535audio_hw_free,
+	.prepare =	snd_cs5535audio_capture_prepare,
+	.trigger =	snd_cs5535audio_trigger,
+	.pointer =	snd_cs5535audio_pcm_pointer,
+};
+
+static struct cs5535audio_dma_ops snd_cs5535audio_playback_dma_ops = {
+        .type = CS5535AUDIO_DMA_PLAYBACK,
+        .enable_dma = cs5535audio_playback_enable_dma,
+        .disable_dma = cs5535audio_playback_disable_dma,
+        .setup_prd = cs5535audio_playback_setup_prd,
+        .pause_dma = cs5535audio_playback_pause_dma,
+        .read_dma_pntr = cs5535audio_playback_read_dma_pntr,
+};
+
+static struct cs5535audio_dma_ops snd_cs5535audio_capture_dma_ops = {
+        .type = CS5535AUDIO_DMA_CAPTURE,
+        .enable_dma = cs5535audio_capture_enable_dma,
+        .disable_dma = cs5535audio_capture_disable_dma,
+        .setup_prd = cs5535audio_capture_setup_prd,
+        .pause_dma = cs5535audio_capture_pause_dma,
+        .read_dma_pntr = cs5535audio_capture_read_dma_pntr,
+};
+
+int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535au)
+{
+	struct snd_pcm *pcm;
+	int err;
+
+	err = snd_pcm_new(cs5535au->card, "CS5535 Audio", 0, 1, 1, &pcm);
+	if (err < 0)
+		return err;
+
+	cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK].ops =
+					&snd_cs5535audio_playback_dma_ops;
+	cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE].ops =
+					&snd_cs5535audio_capture_dma_ops;
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+					&snd_cs5535audio_playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
+					&snd_cs5535audio_capture_ops);
+
+	pcm->private_data = cs5535au;
+	pcm->info_flags = 0;
+	strcpy(pcm->name, "CS5535 Audio");
+
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+					snd_dma_pci_data(cs5535au->pci),
+					64*1024, 128*1024);
+
+	return 0;
+}
+
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 78270f8..2dfa932 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -101,10 +101,10 @@
 					    const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	emu10k1_t *emu;
+	struct snd_card *card;
+	struct snd_emu10k1 *emu;
 #ifdef ENABLE_SYNTH
-	snd_seq_device_t *wave = NULL;
+	struct snd_seq_device *wave = NULL;
 #endif
 	int err;
 
@@ -125,72 +125,50 @@
 	if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev],
 				      (long)max_buffer_size[dev] * 1024 * 1024,
 				      enable_ir[dev], subsystem[dev],
-				      &emu)) < 0) {
-		snd_card_free(card);
-		return err;
-	}		
-	if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}		
-	if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}		
-	if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+				      &emu)) < 0)
+		goto error;
+	card->private_data = emu;
+	if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
+		goto error;
+	if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
+		goto error;
+	if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0)
+		goto error;
 	/* This stores the periods table. */
 	if (emu->card_capabilities->ca0151_chip) { /* P16V */	
-		if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &emu->p16v_buffer) < 0) {
-			snd_p16v_free(emu);
-			return -ENOMEM;
-		}
+		if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+					       1024, &emu->p16v_buffer)) < 0)
+			goto error;
 	}
 
-	if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0)
+		goto error;
 	
-	if ((err = snd_emu10k1_timer(emu, 0)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_emu10k1_timer(emu, 0)) < 0)
+		goto error;
 
-	if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
-	if (emu->card_capabilities->ca0151_chip) { /* P16V */	
-		if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+	if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0)
+		goto error;
+	if (emu->card_capabilities->ca0151_chip) { /* P16V */
+		if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0)
+			goto error;
 	}
 	if (emu->audigy) {
-		if ((err = snd_emu10k1_audigy_midi(emu)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+		if ((err = snd_emu10k1_audigy_midi(emu)) < 0)
+			goto error;
 	} else {
-		if ((err = snd_emu10k1_midi(emu)) < 0) {
-			snd_card_free(card);
-			return err;
-		}
+		if ((err = snd_emu10k1_midi(emu)) < 0)
+			goto error;
 	}
-	if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0)
+		goto error;
 #ifdef ENABLE_SYNTH
 	if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
-			       sizeof(snd_emu10k1_synth_arg_t), &wave) < 0 ||
+			       sizeof(struct snd_emu10k1_synth_arg), &wave) < 0 ||
 	    wave == NULL) {
 		snd_printk(KERN_WARNING "can't initialize Emu10k1 wavetable synth\n");
 	} else {
-		snd_emu10k1_synth_arg_t *arg;
+		struct snd_emu10k1_synth_arg *arg;
 		arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
 		strcpy(wave->name, "Emu-10k1 Synth");
 		arg->hwptr = emu;
@@ -206,13 +184,16 @@
 		 "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i",
 		 card->shortname, emu->revision, emu->serial, emu->port, emu->irq);
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	if ((err = snd_card_register(card)) < 0)
+		goto error;
+
 	pci_set_drvdata(pci, card);
 	dev++;
 	return 0;
+
+ error:
+	snd_card_free(card);
+	return err;
 }
 
 static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
@@ -221,11 +202,68 @@
 	pci_set_drvdata(pci, NULL);
 }
 
+
+#ifdef CONFIG_PM
+static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_emu10k1 *emu = card->private_data;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+
+	snd_pcm_suspend_all(emu->pcm);
+	snd_pcm_suspend_all(emu->pcm_mic);
+	snd_pcm_suspend_all(emu->pcm_efx);
+	snd_pcm_suspend_all(emu->pcm_multi);
+	snd_pcm_suspend_all(emu->pcm_p16v);
+
+	snd_ac97_suspend(emu->ac97);
+
+	snd_emu10k1_efx_suspend(emu);
+	snd_emu10k1_suspend_regs(emu);
+	if (emu->card_capabilities->ca0151_chip)
+		snd_p16v_suspend(emu);
+
+	snd_emu10k1_done(emu);
+
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
+	return 0;
+}
+
+int snd_emu10k1_resume(struct pci_dev *pci)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_emu10k1 *emu = card->private_data;
+
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
+	pci_set_master(pci);
+	
+	snd_emu10k1_resume_init(emu);
+	snd_emu10k1_efx_resume(emu);
+	snd_ac97_resume(emu->ac97);
+	snd_emu10k1_resume_regs(emu);
+
+	if (emu->card_capabilities->ca0151_chip)
+		snd_p16v_resume(emu);
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
 static struct pci_driver driver = {
 	.name = "EMU10K1_Audigy",
 	.id_table = snd_emu10k1_ids,
 	.probe = snd_card_emu10k1_probe,
 	.remove = __devexit_p(snd_card_emu10k1_remove),
+#ifdef CONFIG_PM
+	.suspend = snd_emu10k1_suspend,
+	.resume = snd_emu10k1_resume,
+#endif
 };
 
 static int __init alsa_card_emu10k1_init(void)
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index 6589bf2..01965bd 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -27,26 +27,28 @@
 };
 
 /* Keeps track of what we are finding */
-typedef struct best_voice {
+struct best_voice {
 	unsigned int time;
 	int voice;
-} best_voice_t;
+};
 
 /*
  * prototypes
  */
-static void lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only);
-static snd_emux_voice_t *get_voice(snd_emux_t *emu, snd_emux_port_t *port);
-static int start_voice(snd_emux_voice_t *vp);
-static void trigger_voice(snd_emux_voice_t *vp);
-static void release_voice(snd_emux_voice_t *vp);
-static void update_voice(snd_emux_voice_t *vp, int update);
-static void terminate_voice(snd_emux_voice_t *vp);
-static void free_voice(snd_emux_voice_t *vp);
+static void lookup_voices(struct snd_emux *emu, struct snd_emu10k1 *hw,
+			  struct best_voice *best, int active_only);
+static struct snd_emux_voice *get_voice(struct snd_emux *emu,
+					struct snd_emux_port *port);
+static int start_voice(struct snd_emux_voice *vp);
+static void trigger_voice(struct snd_emux_voice *vp);
+static void release_voice(struct snd_emux_voice *vp);
+static void update_voice(struct snd_emux_voice *vp, int update);
+static void terminate_voice(struct snd_emux_voice *vp);
+static void free_voice(struct snd_emux_voice *vp);
 
-static void set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp);
-static void set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp);
-static void set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp);
+static void set_fmmod(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
+static void set_fm2frq2(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
+static void set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp);
 
 /*
  * Ensure a value is between two points
@@ -59,7 +61,7 @@
 /*
  * set up operators
  */
-static snd_emux_operators_t emu10k1_ops = {
+static struct snd_emux_operators emu10k1_ops = {
 	.owner =	THIS_MODULE,
 	.get_voice =	get_voice,
 	.prepare =	start_voice,
@@ -73,7 +75,7 @@
 };
 
 void
-snd_emu10k1_ops_setup(snd_emux_t *emu)
+snd_emu10k1_ops_setup(struct snd_emux *emu)
 {
 	emu->ops = emu10k1_ops;
 }
@@ -85,11 +87,11 @@
  * terminate most inactive voice and give it as a pcm voice.
  */
 int
-snd_emu10k1_synth_get_voice(emu10k1_t *hw)
+snd_emu10k1_synth_get_voice(struct snd_emu10k1 *hw)
 {
-	snd_emux_t *emu;
-	snd_emux_voice_t *vp;
-	best_voice_t best[V_END];
+	struct snd_emux *emu;
+	struct snd_emux_voice *vp;
+	struct best_voice best[V_END];
 	unsigned long flags;
 	int i;
 
@@ -123,10 +125,10 @@
  * turn off the voice (not terminated)
  */
 static void
-release_voice(snd_emux_voice_t *vp)
+release_voice(struct snd_emux_voice *vp)
 {
 	int dcysusv;
-	emu10k1_t *hw;
+	struct snd_emu10k1 *hw;
 	
 	hw = vp->hw;
 	dcysusv = 0x8000 | (unsigned char)vp->reg.parm.modrelease;
@@ -140,16 +142,16 @@
  * terminate the voice
  */
 static void
-terminate_voice(snd_emux_voice_t *vp)
+terminate_voice(struct snd_emux_voice *vp)
 {
-	emu10k1_t *hw;
+	struct snd_emu10k1 *hw;
 	
 	snd_assert(vp, return);
 	hw = vp->hw;
 	snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK);
 	if (vp->block) {
-		emu10k1_memblk_t *emem;
-		emem = (emu10k1_memblk_t *)vp->block;
+		struct snd_emu10k1_memblk *emem;
+		emem = (struct snd_emu10k1_memblk *)vp->block;
 		if (emem->map_locked > 0)
 			emem->map_locked--;
 	}
@@ -159,9 +161,9 @@
  * release the voice to system
  */
 static void
-free_voice(snd_emux_voice_t *vp)
+free_voice(struct snd_emux_voice *vp)
 {
-	emu10k1_t *hw;
+	struct snd_emu10k1 *hw;
 	
 	hw = vp->hw;
 	if (vp->ch >= 0) {
@@ -181,9 +183,9 @@
  * update registers
  */
 static void
-update_voice(snd_emux_voice_t *vp, int update)
+update_voice(struct snd_emux_voice *vp, int update)
 {
-	emu10k1_t *hw;
+	struct snd_emu10k1 *hw;
 	
 	hw = vp->hw;
 	if (update & SNDRV_EMUX_UPDATE_VOLUME)
@@ -210,10 +212,11 @@
  */
 /* spinlock held! */
 static void
-lookup_voices(snd_emux_t *emu, emu10k1_t *hw, best_voice_t *best, int active_only)
+lookup_voices(struct snd_emux *emu, struct snd_emu10k1 *hw,
+	      struct best_voice *best, int active_only)
 {
-	snd_emux_voice_t *vp;
-	best_voice_t *bp;
+	struct snd_emux_voice *vp;
+	struct best_voice *bp;
 	int  i;
 
 	for (i = 0; i < V_END; i++) {
@@ -274,12 +277,12 @@
  *
  * emu->voice_lock is already held.
  */
-static snd_emux_voice_t *
-get_voice(snd_emux_t *emu, snd_emux_port_t *port)
+static struct snd_emux_voice *
+get_voice(struct snd_emux *emu, struct snd_emux_port *port)
 {
-	emu10k1_t *hw;
-	snd_emux_voice_t *vp;
-	best_voice_t best[V_END];
+	struct snd_emu10k1 *hw;
+	struct snd_emux_voice *vp;
+	struct best_voice best[V_END];
 	int i;
 
 	hw = emu->hw;
@@ -290,7 +293,7 @@
 			vp = &emu->voices[best[i].voice];
 			if (vp->ch < 0) {
 				/* allocate a voice */
-				emu10k1_voice_t *hwvoice;
+				struct snd_emu10k1_voice *hwvoice;
 				if (snd_emu10k1_voice_alloc(hw, EMU10K1_SYNTH, 1, &hwvoice) < 0 || hwvoice == NULL)
 					continue;
 				vp->ch = hwvoice->number;
@@ -308,21 +311,21 @@
  * prepare envelopes and LFOs
  */
 static int
-start_voice(snd_emux_voice_t *vp)
+start_voice(struct snd_emux_voice *vp)
 {
 	unsigned int temp;
 	int ch;
 	unsigned int addr, mapped_offset;
-	snd_midi_channel_t *chan;
-	emu10k1_t *hw;
-	emu10k1_memblk_t *emem;
+	struct snd_midi_channel *chan;
+	struct snd_emu10k1 *hw;
+	struct snd_emu10k1_memblk *emem;
 	
 	hw = vp->hw;
 	ch = vp->ch;
 	snd_assert(ch >= 0, return -EINVAL);
 	chan = vp->chan;
 
-	emem = (emu10k1_memblk_t *)vp->block;
+	emem = (struct snd_emu10k1_memblk *)vp->block;
 	if (emem == NULL)
 		return -EINVAL;
 	emem->map_locked++;
@@ -463,15 +466,15 @@
  * Start envelope
  */
 static void
-trigger_voice(snd_emux_voice_t *vp)
+trigger_voice(struct snd_emux_voice *vp)
 {
 	unsigned int temp, ptarget;
-	emu10k1_t *hw;
-	emu10k1_memblk_t *emem;
+	struct snd_emu10k1 *hw;
+	struct snd_emu10k1_memblk *emem;
 	
 	hw = vp->hw;
 
-	emem = (emu10k1_memblk_t *)vp->block;
+	emem = (struct snd_emu10k1_memblk *)vp->block;
 	if (! emem || emem->mapped_page < 0)
 		return; /* not mapped */
 
@@ -495,7 +498,7 @@
 
 /* set lfo1 modulation height and cutoff */
 static void
-set_fmmod(emu10k1_t *hw, snd_emux_voice_t *vp)
+set_fmmod(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
 {
 	unsigned short fmmod;
 	short pitch;
@@ -513,7 +516,7 @@
 
 /* set lfo2 pitch & frequency */
 static void
-set_fm2frq2(emu10k1_t *hw, snd_emux_voice_t *vp)
+set_fm2frq2(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
 {
 	unsigned short fm2frq2;
 	short pitch;
@@ -531,7 +534,7 @@
 
 /* set filterQ */
 static void
-set_filterQ(emu10k1_t *hw, snd_emux_voice_t *vp)
+set_filterQ(struct snd_emu10k1 *hw, struct snd_emux_voice *vp)
 {
 	unsigned int val;
 	val = snd_emu10k1_ptr_read(hw, CCCA, vp->ch) & ~CCCA_RESONANCE;
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 53aeff0..3c7043b 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -40,18 +40,14 @@
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 #include "p16v.h"
+#include "tina2.h"
 
-#if 0
-MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>, Creative Labs, Inc.");
-MODULE_DESCRIPTION("Routines for control of EMU10K1 chips");
-MODULE_LICENSE("GPL");
-#endif
 
 /*************************************************************************
  * EMU10K1 init / done
  *************************************************************************/
 
-void snd_emu10k1_voice_init(emu10k1_t * emu, int ch)
+void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int ch)
 {
 	snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
 	snd_emu10k1_ptr_write(emu, IP, ch, 0);
@@ -96,17 +92,38 @@
 	}
 }
 
-static int __devinit snd_emu10k1_init(emu10k1_t * emu, int enable_ir)
+static unsigned int spi_dac_init[] = {
+		0x00ff,
+		0x02ff,
+		0x0400,
+		0x0520,
+		0x0600,
+		0x08ff,
+		0x0aff,
+		0x0cff,
+		0x0eff,
+		0x10ff,
+		0x1200,
+		0x1400,
+		0x1480,
+		0x1800,
+		0x1aff,
+		0x1cff,
+		0x1e00,
+		0x0530,
+		0x0602,
+		0x0622,
+		0x1400,
+};
+	
+static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
 {
-	int ch, idx, err;
 	unsigned int silent_page;
-
-	emu->fx8010.itram_size = (16 * 1024)/2;
-	emu->fx8010.etram_pages.area = NULL;
-	emu->fx8010.etram_pages.bytes = 0;
+	int ch;
 
 	/* disable audio and lock cache */
-	outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
+	outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE,
+	     emu->port + HCFG);
 
 	/* reset recording buffers */
 	snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
@@ -127,48 +144,17 @@
 		/* set SPDIF bypass mode */
 		snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
 		/* enable rear left + rear right AC97 slots */
-		snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT | AC97SLOT_REAR_LEFT);
+		snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_REAR_RIGHT |
+				      AC97SLOT_REAR_LEFT);
 	}
 
 	/* init envelope engine */
-	for (ch = 0; ch < NUM_G; ch++) {
-		emu->voices[ch].emu = emu;
-		emu->voices[ch].number = ch;
+	for (ch = 0; ch < NUM_G; ch++)
 		snd_emu10k1_voice_init(emu, ch);
-	}
 
-	/*
-	 *  Init to 0x02109204 :
-	 *  Clock accuracy    = 0     (1000ppm)
-	 *  Sample Rate       = 2     (48kHz)
-	 *  Audio Channel     = 1     (Left of 2)
-	 *  Source Number     = 0     (Unspecified)
-	 *  Generation Status = 1     (Original for Cat Code 12)
-	 *  Cat Code          = 12    (Digital Signal Mixer)
-	 *  Mode              = 0     (Mode 0)
-	 *  Emphasis          = 0     (None)
-	 *  CP                = 1     (Copyright unasserted)
-	 *  AN                = 0     (Audio data)
-	 *  P                 = 0     (Consumer)
-	 */
-	snd_emu10k1_ptr_write(emu, SPCS0, 0,
-			emu->spdif_bits[0] =
-			SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
-			SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
-			SPCS_GENERATIONSTATUS | 0x00001200 |
-			0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
-	snd_emu10k1_ptr_write(emu, SPCS1, 0,
-			emu->spdif_bits[1] =
-			SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
-			SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
-			SPCS_GENERATIONSTATUS | 0x00001200 |
-			0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
-	snd_emu10k1_ptr_write(emu, SPCS2, 0,
-			emu->spdif_bits[2] =
-			SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
-			SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
-			SPCS_GENERATIONSTATUS | 0x00001200 |
-			0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
+	snd_emu10k1_ptr_write(emu, SPCS0, 0, emu->spdif_bits[0]);
+	snd_emu10k1_ptr_write(emu, SPCS1, 0, emu->spdif_bits[1]);
+	snd_emu10k1_ptr_write(emu, SPCS2, 0, emu->spdif_bits[2]);
 
 	if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
 		/* Hacks for Alice3 to work independent of haP16V driver */
@@ -195,7 +181,7 @@
 		/* Hacks for Alice3 to work independent of haP16V driver */
 		u32 tmp;
 
-		snd_printk(KERN_ERR "Audigy2 value:Special config.\n");
+		snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
 		//Setup SRCMulti_I2S SamplingRate
 		tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
 		tmp &= 0xfffff1ff;
@@ -219,15 +205,28 @@
 		tmp = inl(emu->port + A_IOCFG) & ~0x8; /* Clear bit 3 */
 		outl(tmp, emu->port + A_IOCFG);
 	}
+	if (emu->card_capabilities->spi_dac) { /* Audigy 2 ZS Notebook with DAC Wolfson WM8768/WM8568 */
+		int size, n;
 
+		size = ARRAY_SIZE(spi_dac_init);
+		for (n=0; n < size; n++)
+			snd_emu10k1_spi_write(emu, spi_dac_init[n]);
 
-	/*
-	 *  Clear page with silence & setup all pointers to this page
-	 */
-	memset(emu->silent_page.area, 0, PAGE_SIZE);
-	silent_page = emu->silent_page.addr << 1;
-	for (idx = 0; idx < MAXPAGES; idx++)
-		((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
+		snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
+		/* Enable GPIOs
+		 * GPIO0: Unknown
+		 * GPIO1: Speakers-enabled.
+		 * GPIO2: Unknown
+		 * GPIO3: Unknown
+		 * GPIO4: IEC958 Output on.
+		 * GPIO5: Unknown
+		 * GPIO6: Unknown
+		 * GPIO7: Unknown
+		 */
+		outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
+
+	}
+	
 	snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
 	snd_emu10k1_ptr_write(emu, TCB, 0, 0);	/* taken from original driver */
 	snd_emu10k1_ptr_write(emu, TCBS, 0, 4);	/* taken from original driver */
@@ -264,7 +263,9 @@
 		outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
 
 	if (enable_ir) {	/* enable IR for SB Live */
-		if (emu->audigy) {
+		if ( emu->card_capabilities->emu1212m) {
+			;  /* Disable all access to A_IOCFG for the emu1212m */
+		} else if (emu->audigy) {
 			unsigned int reg = inl(emu->port + A_IOCFG);
 			outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
 			udelay(500);
@@ -281,24 +282,27 @@
  		}
 	}
 	
-	if (emu->audigy) {	/* enable analog output */
+	if ( emu->card_capabilities->emu1212m) {
+		;  /* Disable all access to A_IOCFG for the emu1212m */
+	} else if (emu->audigy) {	/* enable analog output */
 		unsigned int reg = inl(emu->port + A_IOCFG);
 		outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
 	}
 
-	/*
-	 *  Initialize the effect engine
-	 */
-	if ((err = snd_emu10k1_init_efx(emu)) < 0)
-		return err;
+	return 0;
+}
 
+static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
+{
 	/*
 	 *  Enable the audio bit
 	 */
 	outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
 
 	/* Enable analog/digital outs on audigy */
-	if (emu->audigy) {
+	if ( emu->card_capabilities->emu1212m) {
+		;  /* Disable all access to A_IOCFG for the emu1212m */
+	} else if (emu->audigy) {
 		outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
  
 		if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
@@ -334,15 +338,9 @@
 #endif
 
 	snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
-
-	emu->reserved_page = (emu10k1_memblk_t *)snd_emu10k1_synth_alloc(emu, 4096);
-	if (emu->reserved_page)
-		emu->reserved_page->map_locked = 1;
-	
-	return 0;
 }
 
-static int snd_emu10k1_done(emu10k1_t * emu)
+int snd_emu10k1_done(struct snd_emu10k1 * emu)
 {
 	int ch;
 
@@ -381,18 +379,10 @@
 	snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
 	snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
 
-	/* remove reserved page */
-	if (emu->reserved_page != NULL) {
-		snd_emu10k1_synth_free(emu, (snd_util_memblk_t *)emu->reserved_page);
-		emu->reserved_page = NULL;
-	}
-
 	/* disable audio and lock cache */
 	outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
 	snd_emu10k1_ptr_write(emu, PTB, 0, 0);
 
-	snd_emu10k1_free_efx(emu);
-
 	return 0;
 }
 
@@ -473,7 +463,7 @@
  *  register.
  */
 
-static void snd_emu10k1_ecard_write(emu10k1_t * emu, unsigned int value)
+static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value)
 {
 	unsigned short count;
 	unsigned int data;
@@ -511,7 +501,7 @@
  * channel.
  */
 
-static void snd_emu10k1_ecard_setadcgain(emu10k1_t * emu,
+static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
 					 unsigned short gain)
 {
 	unsigned int bit;
@@ -539,7 +529,7 @@
 	snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
 }
 
-static int __devinit snd_emu10k1_ecard_init(emu10k1_t * emu)
+static int __devinit snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
 {
 	unsigned int hc_value;
 
@@ -579,7 +569,7 @@
 	return 0;
 }
 
-static int __devinit snd_emu10k1_cardbus_init(emu10k1_t * emu)
+static int __devinit snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
 {
 	unsigned long special_port;
 	unsigned int value;
@@ -600,18 +590,160 @@
 	outl(0x0090007f, special_port);
 	value = inl(special_port);
 
+	snd_emu10k1_ptr20_write(emu, TINA2_VOLUME, 0, 0xfefefefe); /* Defaults to 0x30303030 */
 	return 0;
 }
 
+static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
+{
+	if (reg<0 || reg>0x3f)
+		return 1;
+	reg+=0x40; /* 0x40 upwards are registers. */
+	if (value<0 || value>0x3f) /* 0 to 0x3f are values */
+		return 1;
+	outl(reg, emu->port + A_IOCFG);
+	outl(reg | 0x80, emu->port + A_IOCFG);  /* High bit clocks the value into the fpga. */
+	outl(value, emu->port + A_IOCFG);
+	outl(value | 0x80 , emu->port + A_IOCFG);  /* High bit clocks the value into the fpga. */
+
+	return 0;
+}
+
+static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
+{
+	if (reg<0 || reg>0x3f)
+		return 1;
+	reg+=0x40; /* 0x40 upwards are registers. */
+	outl(reg, emu->port + A_IOCFG);
+	outl(reg | 0x80, emu->port + A_IOCFG);  /* High bit clocks the value into the fpga. */
+	*value = inl(emu->port + A_IOCFG);
+
+	return 0;
+}
+
+static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value)
+{
+	snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) );
+	snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) );
+	snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) );
+	snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) );
+
+	return 0;
+}
+
+static int __devinit snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu)
+{
+	unsigned int i;
+	int tmp;
+
+	snd_printk(KERN_ERR "emu1212m: Special config.\n");
+	outl(0x0005a00c, emu->port + HCFG);
+	outl(0x0005a004, emu->port + HCFG);
+	outl(0x0005a000, emu->port + HCFG);
+	outl(0x0005a000, emu->port + HCFG);
+
+	snd_emu1212m_fpga_read(emu, 0x22, &tmp );
+	snd_emu1212m_fpga_read(emu, 0x23, &tmp );
+	snd_emu1212m_fpga_read(emu, 0x24, &tmp );
+	snd_emu1212m_fpga_write(emu, 0x04, 0x01 );
+	snd_emu1212m_fpga_read(emu, 0x0b, &tmp );
+	snd_emu1212m_fpga_write(emu, 0x0b, 0x01 );
+	snd_emu1212m_fpga_read(emu, 0x10, &tmp );
+	snd_emu1212m_fpga_write(emu, 0x10, 0x00 );
+	snd_emu1212m_fpga_read(emu, 0x11, &tmp );
+	snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
+	snd_emu1212m_fpga_read(emu, 0x13, &tmp );
+	snd_emu1212m_fpga_write(emu, 0x13, 0x0f );
+	snd_emu1212m_fpga_read(emu, 0x11, &tmp );
+	snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
+	snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
+	snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
+	snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
+	snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
+	snd_emu1212m_fpga_write(emu, 0x09, 0x0f );
+	snd_emu1212m_fpga_write(emu, 0x06, 0x00 );
+	snd_emu1212m_fpga_write(emu, 0x05, 0x00 );
+	snd_emu1212m_fpga_write(emu, 0x0e, 0x12 );
+	snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405);
+	snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406);
+	snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407);
+	snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100);
+	snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104);
+	snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200);
+	snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201);
+	for (i=0;i < 0x20;i++) {
+		snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000);
+	}
+	for (i=0;i < 4;i++) {
+		snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000);
+	}
+	for (i=0;i < 7;i++) {
+		snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000);
+	}
+	for (i=0;i < 7;i++) {
+		snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000);
+	}
+	snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c);
+	snd_emu1212m_fpga_write(emu, 0x07, 0x01 );
+
+	snd_emu1212m_fpga_read(emu, 0x21, &tmp );
+
+	outl(0x0000a000, emu->port + HCFG);
+	outl(0x0000a001, emu->port + HCFG);
+	/* Initial boot complete. Now patches */
+
+	snd_emu1212m_fpga_read(emu, 0x21, &tmp );
+	snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
+	snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
+	snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
+	snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
+	snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
+	snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
+
+	snd_emu1212m_fpga_read(emu, 0x20, &tmp );
+	snd_emu1212m_fpga_read(emu, 0x21, &tmp );
+
+	snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302);
+	snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303);
+
+	return 0;
+}
 /*
  *  Create the EMU10K1 instance
  */
 
-static int snd_emu10k1_free(emu10k1_t *emu)
+#ifdef CONFIG_PM
+static int alloc_pm_buffer(struct snd_emu10k1 *emu);
+static void free_pm_buffer(struct snd_emu10k1 *emu);
+#endif
+
+static int snd_emu10k1_free(struct snd_emu10k1 *emu)
 {
 	if (emu->port) {	/* avoid access to already used hardware */
 	       	snd_emu10k1_fx8010_tram_setup(emu, 0);
 		snd_emu10k1_done(emu);
+		/* remove reserved page */
+		if (emu->reserved_page) {
+			snd_emu10k1_synth_free(emu, (struct snd_util_memblk *)emu->reserved_page);
+			emu->reserved_page = NULL;
+		}
+		snd_emu10k1_free_efx(emu);
        	}
 	if (emu->memhdr)
 		snd_util_memhdr_free(emu->memhdr);
@@ -621,26 +753,35 @@
 		snd_dma_free_pages(&emu->ptb_pages);
 	vfree(emu->page_ptr_table);
 	vfree(emu->page_addr_table);
+#ifdef CONFIG_PM
+	free_pm_buffer(emu);
+#endif
 	if (emu->irq >= 0)
 		free_irq(emu->irq, (void *)emu);
 	if (emu->port)
 		pci_release_regions(emu->pci);
-	pci_disable_device(emu->pci);
 	if (emu->card_capabilities->ca0151_chip) /* P16V */	
 		snd_p16v_free(emu);
+	pci_disable_device(emu->pci);
 	kfree(emu);
 	return 0;
 }
 
-static int snd_emu10k1_dev_free(snd_device_t *device)
+static int snd_emu10k1_dev_free(struct snd_device *device)
 {
-	emu10k1_t *emu = device->device_data;
+	struct snd_emu10k1 *emu = device->device_data;
 	return snd_emu10k1_free(emu);
 }
 
-static emu_chip_details_t emu_chip_details[] = {
+static struct snd_emu_chip_details emu_chip_details[] = {
 	/* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
 	/* Tested by James@superbug.co.uk 3rd July 2005 */
+	/* DSP: CA0108-IAT
+	 * DAC: CS4382-KQ
+	 * ADC: Philips 1361T
+	 * AC97: STAC9750
+	 * CA0151: None
+	 */
 	{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
 	 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]", 
 	 .id = "Audigy2",
@@ -649,14 +790,24 @@
 	 .spk71 = 1,
 	 .ac97_chip = 1} ,
 	/* Audigy 2 ZS Notebook Cardbus card.*/
-	/* Tested by James@superbug.co.uk 30th October 2005 */
-	/* Not working yet, but progressing. */
+	/* Tested by James@superbug.co.uk 22th December 2005 */
+	/* Audio output 7.1/Headphones working.
+	 * Digital output working. (AC3 not checked, only PCM)
+	 * Audio inputs not tested.
+	 */ 
+	/* DSP: Tiny2
+	 * DAC: Wolfson WM8768/WM8568
+	 * ADC: Wolfson WM8775
+	 * AC97: None
+	 * CA0151: None
+	 */
 	{.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
 	 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", 
 	 .id = "Audigy2",
 	 .emu10k2_chip = 1,
 	 .ca0108_chip = 1,
 	 .ca_cardbus_chip = 1,
+	 .spi_dac = 1,
 	 .spk71 = 1} ,
 	{.vendor = 0x1102, .device = 0x0008, 
 	 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 
@@ -670,7 +821,7 @@
 	 .id = "EMU1212m",
 	 .emu10k2_chip = 1,
 	 .ca0102_chip = 1,
-	 .ecard = 1} ,
+	 .emu1212m = 1} ,
 	/* Tested by James@superbug.co.uk 3rd July 2005 */
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
 	 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", 
@@ -681,6 +832,16 @@
 	 .spk71 = 1,
 	 .spdif_bug = 1,
 	 .ac97_chip = 1} ,
+	/* Tested by shane-alsa@cm.nu 5th Nov 2005 */
+	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
+	 .driver = "Audigy2", .name = "Audigy 2 [2006]", 
+	 .id = "Audigy2",
+	 .emu10k2_chip = 1,
+	 .ca0102_chip = 1,
+	 .ca0151_chip = 1,
+	 .spk71 = 1,
+	 .spdif_bug = 1,
+	 .ac97_chip = 1} ,
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
 	 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]", 
 	 .id = "Audigy2",
@@ -699,6 +860,14 @@
 	 .spk71 = 1,
 	 .spdif_bug = 1,
 	 .ac97_chip = 1} ,
+	/* Audigy 2 */
+	/* Tested by James@superbug.co.uk 3rd July 2005 */
+	/* DSP: CA0102-IAT
+	 * DAC: CS4382-KQ
+	 * ADC: Philips 1361T
+	 * AC97: STAC9721
+	 * CA0151: Yes
+	 */
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
 	 .driver = "Audigy2", .name = "Audigy 2 [SB0240]", 
 	 .id = "Audigy2",
@@ -714,6 +883,7 @@
 	 .emu10k2_chip = 1,
 	 .ca0102_chip = 1,
 	 .ca0151_chip = 1,
+	 .spk71 = 1,
 	 .spdif_bug = 1} ,
 	{.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
 	 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", 
@@ -775,6 +945,14 @@
 	 .emu10k1_chip = 1,
 	 .ac97_chip = 1,
 	 .sblive51 = 1} ,
+	/* Tested by ALSA bug#1680 26th December 2005 */
+	/* note: It really has SB0220 written on the card. */
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102,
+	 .driver = "EMU10K1", .name = "SB Live 5.1 Dell OEM [SB0220]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
 	/* Tested by Thomas Zehetbauer 27th Aug 2005 */
 	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
 	 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]", 
@@ -782,6 +960,12 @@
 	 .emu10k1_chip = 1,
 	 .ac97_chip = 1,
 	 .sblive51 = 1} ,
+	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
+	 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]", 
+	 .id = "Live",
+	 .emu10k1_chip = 1,
+	 .ac97_chip = 1,
+	 .sblive51 = 1} ,
 	{.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
 	 .driver = "EMU10K1", .name = "SB Live 5.1", 
 	 .id = "Live",
@@ -877,21 +1061,22 @@
 	{ } /* terminator */
 };
 
-int __devinit snd_emu10k1_create(snd_card_t * card,
+int __devinit snd_emu10k1_create(struct snd_card *card,
 		       struct pci_dev * pci,
 		       unsigned short extin_mask,
 		       unsigned short extout_mask,
 		       long max_cache_bytes,
 		       int enable_ir,
 		       uint subsystem,
-		       emu10k1_t ** remu)
+		       struct snd_emu10k1 ** remu)
 {
-	emu10k1_t *emu;
-	int err;
+	struct snd_emu10k1 *emu;
+	int idx, err;
 	int is_audigy;
 	unsigned char revision;
-	const emu_chip_details_t *c;
-	static snd_device_ops_t ops = {
+	unsigned int silent_page;
+	const struct snd_emu_chip_details *c;
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_emu10k1_dev_free,
 	};
 	
@@ -999,36 +1184,37 @@
 	emu->port = pci_resource_start(pci, 0);
 
 	if (request_irq(pci->irq, snd_emu10k1_interrupt, SA_INTERRUPT|SA_SHIRQ, "EMU10K1", (void *)emu)) {
-		snd_emu10k1_free(emu);
-		return -EBUSY;
+		err = -EBUSY;
+		goto error;
 	}
 	emu->irq = pci->irq;
 
 	emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT;
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				32 * 1024, &emu->ptb_pages) < 0) {
-		snd_emu10k1_free(emu);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto error;
 	}
 
 	emu->page_ptr_table = (void **)vmalloc(emu->max_cache_pages * sizeof(void*));
 	emu->page_addr_table = (unsigned long*)vmalloc(emu->max_cache_pages * sizeof(unsigned long));
 	if (emu->page_ptr_table == NULL || emu->page_addr_table == NULL) {
-		snd_emu10k1_free(emu);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto error;
 	}
 
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				EMUPAGESIZE, &emu->silent_page) < 0) {
-		snd_emu10k1_free(emu);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto error;
 	}
 	emu->memhdr = snd_util_memhdr_new(emu->max_cache_pages * PAGE_SIZE);
 	if (emu->memhdr == NULL) {
-		snd_emu10k1_free(emu);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto error;
 	}
-	emu->memhdr->block_extra_size = sizeof(emu10k1_memblk_t) - sizeof(snd_util_memblk_t);
+	emu->memhdr->block_extra_size = sizeof(struct snd_emu10k1_memblk) -
+		sizeof(struct snd_util_memblk);
 
 	pci_set_master(pci);
 
@@ -1039,40 +1225,191 @@
 		extout_mask = 0x7fff;
 	emu->fx8010.extin_mask = extin_mask;
 	emu->fx8010.extout_mask = extout_mask;
+	emu->enable_ir = enable_ir;
 
 	if (emu->card_capabilities->ecard) {
-		if ((err = snd_emu10k1_ecard_init(emu)) < 0) {
-			snd_emu10k1_free(emu);
-			return err;
-		}
+		if ((err = snd_emu10k1_ecard_init(emu)) < 0)
+			goto error;
 	} else if (emu->card_capabilities->ca_cardbus_chip) {
-		if ((err = snd_emu10k1_cardbus_init(emu)) < 0) {
-			snd_emu10k1_free(emu);
-			return err;
-		}
+		if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
+			goto error;
+ 	} else if (emu->card_capabilities->emu1212m) {
+ 		if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) {
+ 			snd_emu10k1_free(emu);
+ 			return err;
+ 		}
 	} else {
 		/* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
 			does not support this, it shouldn't do any harm */
 		snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
 	}
 
-	if ((err = snd_emu10k1_init(emu, enable_ir)) < 0) {
-		snd_emu10k1_free(emu);
-		return err;
+	/* initialize TRAM setup */
+	emu->fx8010.itram_size = (16 * 1024)/2;
+	emu->fx8010.etram_pages.area = NULL;
+	emu->fx8010.etram_pages.bytes = 0;
+
+	/*
+	 *  Init to 0x02109204 :
+	 *  Clock accuracy    = 0     (1000ppm)
+	 *  Sample Rate       = 2     (48kHz)
+	 *  Audio Channel     = 1     (Left of 2)
+	 *  Source Number     = 0     (Unspecified)
+	 *  Generation Status = 1     (Original for Cat Code 12)
+	 *  Cat Code          = 12    (Digital Signal Mixer)
+	 *  Mode              = 0     (Mode 0)
+	 *  Emphasis          = 0     (None)
+	 *  CP                = 1     (Copyright unasserted)
+	 *  AN                = 0     (Audio data)
+	 *  P                 = 0     (Consumer)
+	 */
+	emu->spdif_bits[0] = emu->spdif_bits[1] =
+		emu->spdif_bits[2] = SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
+		SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
+		SPCS_GENERATIONSTATUS | 0x00001200 |
+		0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
+
+	emu->reserved_page = (struct snd_emu10k1_memblk *)
+		snd_emu10k1_synth_alloc(emu, 4096);
+	if (emu->reserved_page)
+		emu->reserved_page->map_locked = 1;
+	
+	/* Clear silent pages and set up pointers */
+	memset(emu->silent_page.area, 0, PAGE_SIZE);
+	silent_page = emu->silent_page.addr << 1;
+	for (idx = 0; idx < MAXPAGES; idx++)
+		((u32 *)emu->ptb_pages.area)[idx] = cpu_to_le32(silent_page | idx);
+
+	/* set up voice indices */
+	for (idx = 0; idx < NUM_G; idx++) {
+		emu->voices[idx].emu = emu;
+		emu->voices[idx].number = idx;
 	}
 
-	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0) {
-		snd_emu10k1_free(emu);
-		return err;
-	}
+	if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0)
+		goto error;
+#ifdef CONFIG_PM
+	if ((err = alloc_pm_buffer(emu)) < 0)
+		goto error;
+#endif
 
+	/*  Initialize the effect engine */
+	if ((err = snd_emu10k1_init_efx(emu)) < 0)
+		goto error;
+	snd_emu10k1_audio_enable(emu);
+
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0)
+		goto error;
+
+#ifdef CONFIG_PROC_FS
 	snd_emu10k1_proc_init(emu);
+#endif
 
 	snd_card_set_dev(card, &pci->dev);
 	*remu = emu;
 	return 0;
+
+ error:
+	snd_emu10k1_free(emu);
+	return err;
 }
 
+#ifdef CONFIG_PM
+static unsigned char saved_regs[] = {
+	CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
+	FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
+	ATKHLDM, DCYSUSM, LFOVAL2, IP, IFATN, PEFE, FMMOD, TREMFRQ, FM2FRQ2,
+	TEMPENV, ADCCR, FXWC, MICBA, ADCBA, FXBA,
+	MICBS, ADCBS, FXBS, CDCS, GPSCS, SPCS0, SPCS1, SPCS2,
+	SPBYPASS, AC97SLOT, CDSRCS, GPSRCS, ZVSRCS, MICIDX, ADCIDX, FXIDX,
+	0xff /* end */
+};
+static unsigned char saved_regs_audigy[] = {
+	A_ADCIDX, A_MICIDX, A_FXWC1, A_FXWC2, A_SAMPLE_RATE,
+	A_FXRT2, A_SENDAMOUNTS, A_FXRT1,
+	0xff /* end */
+};
+
+static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
+{
+	int size;
+
+	size = ARRAY_SIZE(saved_regs);
+	if (emu->audigy)
+		size += ARRAY_SIZE(saved_regs_audigy);
+	emu->saved_ptr = vmalloc(4 * NUM_G * size);
+	if (! emu->saved_ptr)
+		return -ENOMEM;
+	if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
+		return -ENOMEM;
+	if (emu->card_capabilities->ca0151_chip &&
+	    snd_p16v_alloc_pm_buffer(emu) < 0)
+		return -ENOMEM;
+	return 0;
+}
+
+static void free_pm_buffer(struct snd_emu10k1 *emu)
+{
+	vfree(emu->saved_ptr);
+	snd_emu10k1_efx_free_pm_buffer(emu);
+	if (emu->card_capabilities->ca0151_chip)
+		snd_p16v_free_pm_buffer(emu);
+}
+
+void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu)
+{
+	int i;
+	unsigned char *reg;
+	unsigned int *val;
+
+	val = emu->saved_ptr;
+	for (reg = saved_regs; *reg != 0xff; reg++)
+		for (i = 0; i < NUM_G; i++, val++)
+			*val = snd_emu10k1_ptr_read(emu, *reg, i);
+	if (emu->audigy) {
+		for (reg = saved_regs_audigy; *reg != 0xff; reg++)
+			for (i = 0; i < NUM_G; i++, val++)
+				*val = snd_emu10k1_ptr_read(emu, *reg, i);
+	}
+	if (emu->audigy)
+		emu->saved_a_iocfg = inl(emu->port + A_IOCFG);
+	emu->saved_hcfg = inl(emu->port + HCFG);
+}
+
+void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
+{
+	if (emu->card_capabilities->ecard)
+		snd_emu10k1_ecard_init(emu);
+	else
+		snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
+	snd_emu10k1_init(emu, emu->enable_ir, 1);
+}
+
+void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu)
+{
+	int i;
+	unsigned char *reg;
+	unsigned int *val;
+
+	snd_emu10k1_audio_enable(emu);
+
+	/* resore for spdif */
+	if (emu->audigy)
+		outl(emu->port + A_IOCFG, emu->saved_a_iocfg);
+	outl(emu->port + HCFG, emu->saved_hcfg);
+
+	val = emu->saved_ptr;
+	for (reg = saved_regs; *reg != 0xff; reg++)
+		for (i = 0; i < NUM_G; i++, val++)
+			snd_emu10k1_ptr_write(emu, *reg, i, *val);
+	if (emu->audigy) {
+		for (reg = saved_regs_audigy; *reg != 0xff; reg++)
+			for (i = 0; i < NUM_G; i++, val++)
+				snd_emu10k1_ptr_write(emu, *reg, i, *val);
+	}
+}
+#endif
+
 /* memory.c */
 EXPORT_SYMBOL(snd_emu10k1_synth_alloc);
 EXPORT_SYMBOL(snd_emu10k1_synth_free);
diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c
index 4df668eb3..42bae6f 100644
--- a/sound/pci/emu10k1/emu10k1_patch.c
+++ b/sound/pci/emu10k1/emu10k1_patch.c
@@ -35,14 +35,15 @@
  * allocate a sample block and copy data from userspace
  */
 int
-snd_emu10k1_sample_new(snd_emux_t *rec, snd_sf_sample_t *sp,
-		       snd_util_memhdr_t *hdr, const void __user *data, long count)
+snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
+		       struct snd_util_memhdr *hdr,
+		       const void __user *data, long count)
 {
 	int offset;
 	int truesize, size, loopsize, blocksize;
 	int loopend, sampleend;
 	unsigned int start_addr;
-	emu10k1_t *emu;
+	struct snd_emu10k1 *emu;
 
 	emu = rec->hw;
 	snd_assert(sp != NULL, return -EINVAL);
@@ -205,10 +206,10 @@
  * free a sample block
  */
 int
-snd_emu10k1_sample_free(snd_emux_t *rec, snd_sf_sample_t *sp,
-			snd_util_memhdr_t *hdr)
+snd_emu10k1_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
+			struct snd_util_memhdr *hdr)
 {
-	emu10k1_t *emu;
+	struct snd_emu10k1 *emu;
 
 	emu = rec->hw;
 	snd_assert(sp != NULL, return -EINVAL);
diff --git a/sound/pci/emu10k1/emu10k1_synth.c b/sound/pci/emu10k1/emu10k1_synth.c
index 8bd58d1..1fa393f 100644
--- a/sound/pci/emu10k1/emu10k1_synth.c
+++ b/sound/pci/emu10k1/emu10k1_synth.c
@@ -28,11 +28,11 @@
 /*
  * create a new hardware dependent device for Emu10k1
  */
-static int snd_emu10k1_synth_new_device(snd_seq_device_t *dev)
+static int snd_emu10k1_synth_new_device(struct snd_seq_device *dev)
 {
-	snd_emux_t *emu;
-	emu10k1_t *hw;
-	snd_emu10k1_synth_arg_t *arg;
+	struct snd_emux *emu;
+	struct snd_emu10k1 *hw;
+	struct snd_emu10k1_synth_arg *arg;
 	unsigned long flags;
 
 	arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
@@ -76,10 +76,10 @@
 	return 0;
 }
 
-static int snd_emu10k1_synth_delete_device(snd_seq_device_t *dev)
+static int snd_emu10k1_synth_delete_device(struct snd_seq_device *dev)
 {
-	snd_emux_t *emu;
-	emu10k1_t *hw;
+	struct snd_emux *emu;
+	struct snd_emu10k1 *hw;
 	unsigned long flags;
 
 	if (dev->driver_data == NULL)
@@ -104,11 +104,12 @@
 static int __init alsa_emu10k1_synth_init(void)
 {
 	
-	static snd_seq_dev_ops_t ops = {
+	static struct snd_seq_dev_ops ops = {
 		snd_emu10k1_synth_new_device,
 		snd_emu10k1_synth_delete_device,
 	};
-	return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, &ops, sizeof(snd_emu10k1_synth_arg_t));
+	return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, &ops,
+					      sizeof(struct snd_emu10k1_synth_arg));
 }
 
 static void __exit alsa_emu10k1_synth_exit(void)
diff --git a/sound/pci/emu10k1/emu10k1_synth_local.h b/sound/pci/emu10k1/emu10k1_synth_local.h
index 7f50b01..308ddc8 100644
--- a/sound/pci/emu10k1/emu10k1_synth_local.h
+++ b/sound/pci/emu10k1/emu10k1_synth_local.h
@@ -26,13 +26,18 @@
 #include <sound/emu10k1_synth.h>
 
 /* emu10k1_patch.c */
-int snd_emu10k1_sample_new(snd_emux_t *private_data, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr, const void __user *_data, long count);
-int snd_emu10k1_sample_free(snd_emux_t *private_data, snd_sf_sample_t *sp, snd_util_memhdr_t *hdr);
-int snd_emu10k1_memhdr_init(snd_emux_t *emu);
+int snd_emu10k1_sample_new(struct snd_emux *private_data,
+			   struct snd_sf_sample *sp,
+			   struct snd_util_memhdr *hdr,
+			   const void __user *_data, long count);
+int snd_emu10k1_sample_free(struct snd_emux *private_data,
+			    struct snd_sf_sample *sp,
+			    struct snd_util_memhdr *hdr);
+int snd_emu10k1_memhdr_init(struct snd_emux *emu);
 
 /* emu10k1_callback.c */
-void snd_emu10k1_ops_setup(snd_emux_t *emu);
-int snd_emu10k1_synth_get_voice(emu10k1_t *hw);
+void snd_emu10k1_ops_setup(struct snd_emux *emu);
+int snd_emu10k1_synth_get_voice(struct snd_emu10k1 *hw);
 
 
 #endif	/* __EMU10K1_SYNTH_LOCAL_H */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 7955777..1107c8e 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -195,30 +195,26 @@
  * playback.
  */
 
-typedef struct snd_emu10k1x_voice emu10k1x_voice_t;
-typedef struct snd_emu10k1x emu10k1x_t;
-typedef struct snd_emu10k1x_pcm emu10k1x_pcm_t;
-
-struct snd_emu10k1x_voice {
-	emu10k1x_t *emu;
+struct emu10k1x_voice {
+	struct emu10k1x *emu;
 	int number;
 	int use;
   
-	emu10k1x_pcm_t *epcm;
+	struct emu10k1x_pcm *epcm;
 };
 
-struct snd_emu10k1x_pcm {
-	emu10k1x_t *emu;
-	snd_pcm_substream_t *substream;
-	emu10k1x_voice_t *voice;
+struct emu10k1x_pcm {
+	struct emu10k1x *emu;
+	struct snd_pcm_substream *substream;
+	struct emu10k1x_voice *voice;
 	unsigned short running;
 };
 
-typedef struct {
-	struct snd_emu10k1x *emu;
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *substream_input;
-	snd_rawmidi_substream_t *substream_output;
+struct emu10k1x_midi {
+	struct emu10k1x *emu;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *substream_input;
+	struct snd_rawmidi_substream *substream_output;
 	unsigned int midi_mode;
 	spinlock_t input_lock;
 	spinlock_t output_lock;
@@ -226,12 +222,12 @@
 	int tx_enable, rx_enable;
 	int port;
 	int ipr_tx, ipr_rx;
-	void (*interrupt)(emu10k1x_t *emu, unsigned int status);
-} emu10k1x_midi_t;
+	void (*interrupt)(struct emu10k1x *emu, unsigned int status);
+};
 
 // definition of the chip-specific record
-struct snd_emu10k1x {
-	snd_card_t *card;
+struct emu10k1x {
+	struct snd_card *card;
 	struct pci_dev *pci;
 
 	unsigned long port;
@@ -245,20 +241,20 @@
 	spinlock_t emu_lock;
 	spinlock_t voice_lock;
 
-	ac97_t *ac97;
-	snd_pcm_t *pcm;
+	struct snd_ac97 *ac97;
+	struct snd_pcm *pcm;
 
-	emu10k1x_voice_t voices[3];
-	emu10k1x_voice_t capture_voice;
+	struct emu10k1x_voice voices[3];
+	struct emu10k1x_voice capture_voice;
 	u32 spdif_bits[3]; // SPDIF out setup
 
 	struct snd_dma_buffer dma_buffer;
 
-	emu10k1x_midi_t midi;
+	struct emu10k1x_midi midi;
 };
 
 /* hardware definition */
-static snd_pcm_hardware_t snd_emu10k1x_playback_hw = {
+static struct snd_pcm_hardware snd_emu10k1x_playback_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | 
 				 SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -277,7 +273,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_emu10k1x_capture_hw = {
+static struct snd_pcm_hardware snd_emu10k1x_capture_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | 
 				 SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -296,7 +292,7 @@
 	.fifo_size =		0,
 };
 
-static unsigned int snd_emu10k1x_ptr_read(emu10k1x_t * emu, 
+static unsigned int snd_emu10k1x_ptr_read(struct emu10k1x * emu, 
 					  unsigned int reg, 
 					  unsigned int chn)
 {
@@ -312,7 +308,7 @@
 	return val;
 }
 
-static void snd_emu10k1x_ptr_write(emu10k1x_t *emu, 
+static void snd_emu10k1x_ptr_write(struct emu10k1x *emu, 
 				   unsigned int reg, 
 				   unsigned int chn, 
 				   unsigned int data)
@@ -328,7 +324,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-static void snd_emu10k1x_intr_enable(emu10k1x_t *emu, unsigned int intrenb)
+static void snd_emu10k1x_intr_enable(struct emu10k1x *emu, unsigned int intrenb)
 {
 	unsigned long flags;
 	unsigned int enable;
@@ -339,7 +335,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-static void snd_emu10k1x_intr_disable(emu10k1x_t *emu, unsigned int intrenb)
+static void snd_emu10k1x_intr_disable(struct emu10k1x *emu, unsigned int intrenb)
 {
 	unsigned long flags;
 	unsigned int enable;
@@ -350,7 +346,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-static void snd_emu10k1x_gpio_write(emu10k1x_t *emu, unsigned int value)
+static void snd_emu10k1x_gpio_write(struct emu10k1x *emu, unsigned int value)
 {
 	unsigned long flags;
 
@@ -359,14 +355,14 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-static void snd_emu10k1x_pcm_free_substream(snd_pcm_runtime_t *runtime)
+static void snd_emu10k1x_pcm_free_substream(struct snd_pcm_runtime *runtime)
 {
 	kfree(runtime->private_data);
 }
 
-static void snd_emu10k1x_pcm_interrupt(emu10k1x_t *emu, emu10k1x_voice_t *voice)
+static void snd_emu10k1x_pcm_interrupt(struct emu10k1x *emu, struct emu10k1x_voice *voice)
 {
-	emu10k1x_pcm_t *epcm;
+	struct emu10k1x_pcm *epcm;
 
 	if ((epcm = voice->epcm) == NULL)
 		return;
@@ -382,11 +378,11 @@
 }
 
 /* open callback */
-static int snd_emu10k1x_playback_open(snd_pcm_substream_t *substream)
+static int snd_emu10k1x_playback_open(struct snd_pcm_substream *substream)
 {
-	emu10k1x_t *chip = snd_pcm_substream_chip(substream);
-	emu10k1x_pcm_t *epcm;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct emu10k1x *chip = snd_pcm_substream_chip(substream);
+	struct emu10k1x_pcm *epcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) {
@@ -410,17 +406,17 @@
 }
 
 /* close callback */
-static int snd_emu10k1x_playback_close(snd_pcm_substream_t *substream)
+static int snd_emu10k1x_playback_close(struct snd_pcm_substream *substream)
 {
 	return 0;
 }
 
 /* hw_params callback */
-static int snd_emu10k1x_pcm_hw_params(snd_pcm_substream_t *substream,
-				      snd_pcm_hw_params_t * hw_params)
+static int snd_emu10k1x_pcm_hw_params(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *hw_params)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1x_pcm_t *epcm = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct emu10k1x_pcm *epcm = runtime->private_data;
 
 	if (! epcm->voice) {
 		epcm->voice = &epcm->emu->voices[substream->pcm->device];
@@ -433,10 +429,10 @@
 }
 
 /* hw_free callback */
-static int snd_emu10k1x_pcm_hw_free(snd_pcm_substream_t *substream)
+static int snd_emu10k1x_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1x_pcm_t *epcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct emu10k1x_pcm *epcm;
 
 	if (runtime->private_data == NULL)
 		return 0;
@@ -453,11 +449,11 @@
 }
 
 /* prepare callback */
-static int snd_emu10k1x_pcm_prepare(snd_pcm_substream_t *substream)
+static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1x_pcm_t *epcm = runtime->private_data;
+	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct emu10k1x_pcm *epcm = runtime->private_data;
 	int voice = epcm->voice->number;
 	u32 *table_base = (u32 *)(emu->dma_buffer.area+1024*voice);
 	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
@@ -482,12 +478,12 @@
 }
 
 /* trigger callback */
-static int snd_emu10k1x_pcm_trigger(snd_pcm_substream_t *substream,
+static int snd_emu10k1x_pcm_trigger(struct snd_pcm_substream *substream,
 				    int cmd)
 {
-	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1x_pcm_t *epcm = runtime->private_data;
+	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct emu10k1x_pcm *epcm = runtime->private_data;
 	int channel = epcm->voice->number;
 	int result = 0;
 
@@ -516,11 +512,11 @@
 
 /* pointer callback */
 static snd_pcm_uframes_t
-snd_emu10k1x_pcm_pointer(snd_pcm_substream_t *substream)
+snd_emu10k1x_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1x_pcm_t *epcm = runtime->private_data;
+	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct emu10k1x_pcm *epcm = runtime->private_data;
 	int channel = epcm->voice->number;
 	snd_pcm_uframes_t ptr = 0, ptr1 = 0, ptr2= 0,ptr3 = 0,ptr4 = 0;
 
@@ -547,7 +543,7 @@
 }
 
 /* operators */
-static snd_pcm_ops_t snd_emu10k1x_playback_ops = {
+static struct snd_pcm_ops snd_emu10k1x_playback_ops = {
 	.open =        snd_emu10k1x_playback_open,
 	.close =       snd_emu10k1x_playback_close,
 	.ioctl =       snd_pcm_lib_ioctl,
@@ -559,11 +555,11 @@
 };
 
 /* open_capture callback */
-static int snd_emu10k1x_pcm_open_capture(snd_pcm_substream_t *substream)
+static int snd_emu10k1x_pcm_open_capture(struct snd_pcm_substream *substream)
 {
-	emu10k1x_t *chip = snd_pcm_substream_chip(substream);
-	emu10k1x_pcm_t *epcm;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct emu10k1x *chip = snd_pcm_substream_chip(substream);
+	struct emu10k1x_pcm *epcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
@@ -587,17 +583,17 @@
 }
 
 /* close callback */
-static int snd_emu10k1x_pcm_close_capture(snd_pcm_substream_t *substream)
+static int snd_emu10k1x_pcm_close_capture(struct snd_pcm_substream *substream)
 {
 	return 0;
 }
 
 /* hw_params callback */
-static int snd_emu10k1x_pcm_hw_params_capture(snd_pcm_substream_t *substream,
-					      snd_pcm_hw_params_t * hw_params)
+static int snd_emu10k1x_pcm_hw_params_capture(struct snd_pcm_substream *substream,
+					      struct snd_pcm_hw_params *hw_params)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1x_pcm_t *epcm = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct emu10k1x_pcm *epcm = runtime->private_data;
 
 	if (! epcm->voice) {
 		if (epcm->emu->capture_voice.use)
@@ -612,11 +608,11 @@
 }
 
 /* hw_free callback */
-static int snd_emu10k1x_pcm_hw_free_capture(snd_pcm_substream_t *substream)
+static int snd_emu10k1x_pcm_hw_free_capture(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
-	emu10k1x_pcm_t *epcm;
+	struct emu10k1x_pcm *epcm;
 
 	if (runtime->private_data == NULL)
 		return 0;
@@ -632,10 +628,10 @@
 }
 
 /* prepare capture callback */
-static int snd_emu10k1x_pcm_prepare_capture(snd_pcm_substream_t *substream)
+static int snd_emu10k1x_pcm_prepare_capture(struct snd_pcm_substream *substream)
 {
-	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_emu10k1x_ptr_write(emu, CAPTURE_DMA_ADDR, 0, runtime->dma_addr);
 	snd_emu10k1x_ptr_write(emu, CAPTURE_BUFFER_SIZE, 0, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes
@@ -646,12 +642,12 @@
 }
 
 /* trigger_capture callback */
-static int snd_emu10k1x_pcm_trigger_capture(snd_pcm_substream_t *substream,
+static int snd_emu10k1x_pcm_trigger_capture(struct snd_pcm_substream *substream,
 					    int cmd)
 {
-	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1x_pcm_t *epcm = runtime->private_data;
+	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct emu10k1x_pcm *epcm = runtime->private_data;
 	int result = 0;
 
 	switch (cmd) {
@@ -676,11 +672,11 @@
 
 /* pointer_capture callback */
 static snd_pcm_uframes_t
-snd_emu10k1x_pcm_pointer_capture(snd_pcm_substream_t *substream)
+snd_emu10k1x_pcm_pointer_capture(struct snd_pcm_substream *substream)
 {
-	emu10k1x_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1x_pcm_t *epcm = runtime->private_data;
+	struct emu10k1x *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct emu10k1x_pcm *epcm = runtime->private_data;
 	snd_pcm_uframes_t ptr;
 
 	if (!epcm->running)
@@ -693,7 +689,7 @@
 	return ptr;
 }
 
-static snd_pcm_ops_t snd_emu10k1x_capture_ops = {
+static struct snd_pcm_ops snd_emu10k1x_capture_ops = {
 	.open =        snd_emu10k1x_pcm_open_capture,
 	.close =       snd_emu10k1x_pcm_close_capture,
 	.ioctl =       snd_pcm_lib_ioctl,
@@ -704,10 +700,10 @@
 	.pointer =     snd_emu10k1x_pcm_pointer_capture,
 };
 
-static unsigned short snd_emu10k1x_ac97_read(ac97_t *ac97,
+static unsigned short snd_emu10k1x_ac97_read(struct snd_ac97 *ac97,
 					     unsigned short reg)
 {
-	emu10k1x_t *emu = ac97->private_data;
+	struct emu10k1x *emu = ac97->private_data;
 	unsigned long flags;
 	unsigned short val;
   
@@ -718,10 +714,10 @@
 	return val;
 }
 
-static void snd_emu10k1x_ac97_write(ac97_t *ac97,
+static void snd_emu10k1x_ac97_write(struct snd_ac97 *ac97,
 				    unsigned short reg, unsigned short val)
 {
-	emu10k1x_t *emu = ac97->private_data;
+	struct emu10k1x *emu = ac97->private_data;
 	unsigned long flags;
   
 	spin_lock_irqsave(&emu->emu_lock, flags);
@@ -730,12 +726,12 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-static int snd_emu10k1x_ac97(emu10k1x_t *chip)
+static int snd_emu10k1x_ac97(struct emu10k1x *chip)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_emu10k1x_ac97_write,
 		.read = snd_emu10k1x_ac97_read,
 	};
@@ -750,7 +746,7 @@
 	return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
 }
 
-static int snd_emu10k1x_free(emu10k1x_t *chip)
+static int snd_emu10k1x_free(struct emu10k1x *chip)
 {
 	snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0);
 	// disable interrupts
@@ -777,9 +773,9 @@
 	return 0;
 }
 
-static int snd_emu10k1x_dev_free(snd_device_t *device)
+static int snd_emu10k1x_dev_free(struct snd_device *device)
 {
-	emu10k1x_t *chip = device->device_data;
+	struct emu10k1x *chip = device->device_data;
 	return snd_emu10k1x_free(chip);
 }
 
@@ -788,64 +784,56 @@
 {
 	unsigned int status;
 
-	emu10k1x_t *chip = dev_id;
-	emu10k1x_voice_t *pvoice = chip->voices;
+	struct emu10k1x *chip = dev_id;
+	struct emu10k1x_voice *pvoice = chip->voices;
 	int i;
 	int mask;
 
 	status = inl(chip->port + IPR);
 
-	if(status) {
-		// capture interrupt
-		if(status & (IPR_CAP_0_LOOP | IPR_CAP_0_HALF_LOOP)) {
-			emu10k1x_voice_t *pvoice = &chip->capture_voice;
-			if(pvoice->use)
-				snd_emu10k1x_pcm_interrupt(chip, pvoice);
-			else
-				snd_emu10k1x_intr_disable(chip, 
-							  INTE_CAP_0_LOOP |
-							  INTE_CAP_0_HALF_LOOP);
-		}
-		
-		mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP;
-		for(i = 0; i < 3; i++) {
-			if(status & mask) {
-				if(pvoice->use)
-					snd_emu10k1x_pcm_interrupt(chip, pvoice);
-				else 
-					snd_emu10k1x_intr_disable(chip, mask);
-			}
-			pvoice++;
-			mask <<= 1;
-		}
-		
-		if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
-			if (chip->midi.interrupt)
-				chip->midi.interrupt(chip, status);
-			else
-				snd_emu10k1x_intr_disable(chip, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
-		}
-		
-		// acknowledge the interrupt if necessary
-		if(status)
-			outl(status, chip->port+IPR);
+	if (! status)
+		return IRQ_NONE;
 
-//		snd_printk(KERN_INFO "interrupt %08x\n", status);
+	// capture interrupt
+	if (status & (IPR_CAP_0_LOOP | IPR_CAP_0_HALF_LOOP)) {
+		struct emu10k1x_voice *pvoice = &chip->capture_voice;
+		if (pvoice->use)
+			snd_emu10k1x_pcm_interrupt(chip, pvoice);
+		else
+			snd_emu10k1x_intr_disable(chip, 
+						  INTE_CAP_0_LOOP |
+						  INTE_CAP_0_HALF_LOOP);
 	}
+		
+	mask = IPR_CH_0_LOOP|IPR_CH_0_HALF_LOOP;
+	for (i = 0; i < 3; i++) {
+		if (status & mask) {
+			if (pvoice->use)
+				snd_emu10k1x_pcm_interrupt(chip, pvoice);
+			else 
+				snd_emu10k1x_intr_disable(chip, mask);
+		}
+		pvoice++;
+		mask <<= 1;
+	}
+		
+	if (status & (IPR_MIDITRANSBUFEMPTY|IPR_MIDIRECVBUFEMPTY)) {
+		if (chip->midi.interrupt)
+			chip->midi.interrupt(chip, status);
+		else
+			snd_emu10k1x_intr_disable(chip, INTE_MIDITXENABLE|INTE_MIDIRXENABLE);
+	}
+		
+	// acknowledge the interrupt if necessary
+	outl(status, chip->port + IPR);
 
+	// snd_printk(KERN_INFO "interrupt %08x\n", status);
 	return IRQ_HANDLED;
 }
 
-static void snd_emu10k1x_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **rpcm)
 {
-	emu10k1x_t *emu = pcm->private_data;
-	emu->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_emu10k1x_pcm(emu10k1x_t *emu, int device, snd_pcm_t **rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 	int capture = 0;
   
@@ -858,7 +846,6 @@
 		return err;
   
 	pcm->private_data = emu;
-	pcm->private_free = snd_emu10k1x_pcm_free;
 	
 	switch(device) {
 	case 0:
@@ -896,14 +883,14 @@
 	return 0;
 }
 
-static int __devinit snd_emu10k1x_create(snd_card_t *card,
+static int __devinit snd_emu10k1x_create(struct snd_card *card,
 					 struct pci_dev *pci,
-					 emu10k1x_t **rchip)
+					 struct emu10k1x **rchip)
 {
-	emu10k1x_t *chip;
+	struct emu10k1x *chip;
 	int err;
 	int ch;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = snd_emu10k1x_dev_free,
 	};
   
@@ -1017,10 +1004,10 @@
 	return 0;
 }
 
-static void snd_emu10k1x_proc_reg_read(snd_info_entry_t *entry, 
-				       snd_info_buffer_t * buffer)
+static void snd_emu10k1x_proc_reg_read(struct snd_info_entry *entry, 
+				       struct snd_info_buffer *buffer)
 {
-	emu10k1x_t *emu = entry->private_data;
+	struct emu10k1x *emu = entry->private_data;
 	unsigned long value,value1,value2;
 	unsigned long flags;
 	int i;
@@ -1045,10 +1032,10 @@
 	}
 }
 
-static void snd_emu10k1x_proc_reg_write(snd_info_entry_t *entry, 
-					snd_info_buffer_t *buffer)
+static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry, 
+					struct snd_info_buffer *buffer)
 {
-	emu10k1x_t *emu = entry->private_data;
+	struct emu10k1x *emu = entry->private_data;
 	char line[64];
 	unsigned int reg, channel_id , val;
 
@@ -1062,9 +1049,9 @@
 	}
 }
 
-static int __devinit snd_emu10k1x_proc_init(emu10k1x_t * emu)
+static int __devinit snd_emu10k1x_proc_init(struct emu10k1x * emu)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	
 	if(! snd_card_proc_new(emu->card, "emu10k1x_regs", &entry)) {
 		snd_info_set_text_ops(entry, emu, 1024, snd_emu10k1x_proc_reg_read);
@@ -1077,7 +1064,7 @@
 	return 0;
 }
 
-static int snd_emu10k1x_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1x_shared_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1086,20 +1073,20 @@
 	return 0;
 }
 
-static int snd_emu10k1x_shared_spdif_get(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1x_shared_spdif_get(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
+	struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.integer.value[0] = (snd_emu10k1x_ptr_read(emu, SPDIF_SELECT, 0) == 0x700) ? 0 : 1;
 
 	return 0;
 }
 
-static int snd_emu10k1x_shared_spdif_put(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1x_shared_spdif_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
+	struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change = 0;
 
@@ -1119,7 +1106,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1x_shared_spdif __devinitdata =
+static struct snd_kcontrol_new snd_emu10k1x_shared_spdif __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Analog/Digital Output Jack",
@@ -1128,17 +1115,17 @@
 	.put =		snd_emu10k1x_shared_spdif_put
 };
 
-static int snd_emu10k1x_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1x_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_emu10k1x_spdif_get(snd_kcontrol_t * kcontrol,
-				  snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1x_spdif_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
+	struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 
 	ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff;
@@ -1148,8 +1135,8 @@
 	return 0;
 }
 
-static int snd_emu10k1x_spdif_get_mask(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1x_spdif_get_mask(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = 0xff;
 	ucontrol->value.iec958.status[1] = 0xff;
@@ -1158,10 +1145,10 @@
 	return 0;
 }
 
-static int snd_emu10k1x_spdif_put(snd_kcontrol_t * kcontrol,
-				  snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1x_spdif_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1x_t *emu = snd_kcontrol_chip(kcontrol);
+	struct emu10k1x *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	int change;
 	unsigned int val;
@@ -1178,7 +1165,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1x_spdif_mask_control =
+static struct snd_kcontrol_new snd_emu10k1x_spdif_mask_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1188,7 +1175,7 @@
 	.get =          snd_emu10k1x_spdif_get_mask
 };
 
-static snd_kcontrol_new_t snd_emu10k1x_spdif_control =
+static struct snd_kcontrol_new snd_emu10k1x_spdif_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1198,11 +1185,11 @@
 	.put =          snd_emu10k1x_spdif_put
 };
 
-static int __devinit snd_emu10k1x_mixer(emu10k1x_t *emu)
+static int __devinit snd_emu10k1x_mixer(struct emu10k1x *emu)
 {
 	int err;
-	snd_kcontrol_t *kctl;
-	snd_card_t *card = emu->card;
+	struct snd_kcontrol *kctl;
+	struct snd_card *card = emu->card;
 
 	if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu)) == NULL)
 		return -ENOMEM;
@@ -1223,12 +1210,12 @@
 #define EMU10K1X_MIDI_MODE_INPUT	(1<<0)
 #define EMU10K1X_MIDI_MODE_OUTPUT	(1<<1)
 
-static inline unsigned char mpu401_read(emu10k1x_t *emu, emu10k1x_midi_t *mpu, int idx)
+static inline unsigned char mpu401_read(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int idx)
 {
 	return (unsigned char)snd_emu10k1x_ptr_read(emu, mpu->port + idx, 0);
 }
 
-static inline void mpu401_write(emu10k1x_t *emu, emu10k1x_midi_t *mpu, int data, int idx)
+static inline void mpu401_write(struct emu10k1x *emu, struct emu10k1x_midi *mpu, int data, int idx)
 {
 	snd_emu10k1x_ptr_write(emu, mpu->port + idx, 0, data);
 }
@@ -1245,7 +1232,7 @@
 #define MPU401_ENTER_UART	0x3f
 #define MPU401_ACK		0xfe
 
-static void mpu401_clear_rx(emu10k1x_t *emu, emu10k1x_midi_t *mpu)
+static void mpu401_clear_rx(struct emu10k1x *emu, struct emu10k1x_midi *mpu)
 {
 	int timeout = 100000;
 	for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
@@ -1260,7 +1247,8 @@
 
  */
 
-static void do_emu10k1x_midi_interrupt(emu10k1x_t *emu, emu10k1x_midi_t *midi, unsigned int status)
+static void do_emu10k1x_midi_interrupt(struct emu10k1x *emu,
+				       struct emu10k1x_midi *midi, unsigned int status)
 {
 	unsigned char byte;
 
@@ -1293,12 +1281,13 @@
 	spin_unlock(&midi->output_lock);
 }
 
-static void snd_emu10k1x_midi_interrupt(emu10k1x_t *emu, unsigned int status)
+static void snd_emu10k1x_midi_interrupt(struct emu10k1x *emu, unsigned int status)
 {
 	do_emu10k1x_midi_interrupt(emu, &emu->midi, status);
 }
 
-static void snd_emu10k1x_midi_cmd(emu10k1x_t * emu, emu10k1x_midi_t *midi, unsigned char cmd, int ack)
+static void snd_emu10k1x_midi_cmd(struct emu10k1x * emu,
+				  struct emu10k1x_midi *midi, unsigned char cmd, int ack)
 {
 	unsigned long flags;
 	int timeout, ok;
@@ -1330,10 +1319,10 @@
 			   mpu401_read_data(emu, midi));
 }
 
-static int snd_emu10k1x_midi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream)
 {
-	emu10k1x_t *emu;
-	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	struct emu10k1x *emu;
+	struct emu10k1x_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 	
 	emu = midi->emu;
@@ -1351,10 +1340,10 @@
 	return 0;
 }
 
-static int snd_emu10k1x_midi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream)
 {
-	emu10k1x_t *emu;
-	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	struct emu10k1x *emu;
+	struct emu10k1x_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 
 	emu = midi->emu;
@@ -1372,10 +1361,10 @@
 	return 0;
 }
 
-static int snd_emu10k1x_midi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream)
 {
-	emu10k1x_t *emu;
-	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	struct emu10k1x *emu;
+	struct emu10k1x_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 
 	emu = midi->emu;
@@ -1393,10 +1382,10 @@
 	return 0;
 }
 
-static int snd_emu10k1x_midi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substream)
 {
-	emu10k1x_t *emu;
-	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	struct emu10k1x *emu;
+	struct emu10k1x_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 
 	emu = midi->emu;
@@ -1414,10 +1403,10 @@
 	return 0;
 }
 
-static void snd_emu10k1x_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	emu10k1x_t *emu;
-	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	struct emu10k1x *emu;
+	struct emu10k1x_midi *midi = substream->rmidi->private_data;
 	emu = midi->emu;
 	snd_assert(emu, return);
 
@@ -1427,10 +1416,10 @@
 		snd_emu10k1x_intr_disable(emu, midi->rx_enable);
 }
 
-static void snd_emu10k1x_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	emu10k1x_t *emu;
-	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)substream->rmidi->private_data;
+	struct emu10k1x *emu;
+	struct emu10k1x_midi *midi = substream->rmidi->private_data;
 	unsigned long flags;
 
 	emu = midi->emu;
@@ -1467,30 +1456,31 @@
 
  */
 
-static snd_rawmidi_ops_t snd_emu10k1x_midi_output =
+static struct snd_rawmidi_ops snd_emu10k1x_midi_output =
 {
 	.open =		snd_emu10k1x_midi_output_open,
 	.close =	snd_emu10k1x_midi_output_close,
 	.trigger =	snd_emu10k1x_midi_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_emu10k1x_midi_input =
+static struct snd_rawmidi_ops snd_emu10k1x_midi_input =
 {
 	.open =		snd_emu10k1x_midi_input_open,
 	.close =	snd_emu10k1x_midi_input_close,
 	.trigger =	snd_emu10k1x_midi_input_trigger,
 };
 
-static void snd_emu10k1x_midi_free(snd_rawmidi_t *rmidi)
+static void snd_emu10k1x_midi_free(struct snd_rawmidi *rmidi)
 {
-	emu10k1x_midi_t *midi = (emu10k1x_midi_t *)rmidi->private_data;
+	struct emu10k1x_midi *midi = rmidi->private_data;
 	midi->interrupt = NULL;
 	midi->rmidi = NULL;
 }
 
-static int __devinit emu10k1x_midi_init(emu10k1x_t *emu, emu10k1x_midi_t *midi, int device, char *name)
+static int __devinit emu10k1x_midi_init(struct emu10k1x *emu,
+					struct emu10k1x_midi *midi, int device, char *name)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
@@ -1511,9 +1501,9 @@
 	return 0;
 }
 
-static int __devinit snd_emu10k1x_midi(emu10k1x_t *emu)
+static int __devinit snd_emu10k1x_midi(struct emu10k1x *emu)
 {
-	emu10k1x_midi_t *midi = &emu->midi;
+	struct emu10k1x_midi *midi = &emu->midi;
 	int err;
 
 	if ((err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)")) < 0)
@@ -1532,8 +1522,8 @@
 					const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	emu10k1x_t *chip;
+	struct snd_card *card;
+	struct emu10k1x *chip;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 03e8c16..1a90339 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -29,6 +29,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/init.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
@@ -309,9 +310,10 @@
  *   controls
  */
 
-static int snd_emu10k1_gpr_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_gpr_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
+	struct snd_emu10k1_fx8010_ctl *ctl =
+		(struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
 
 	if (ctl->min == 0 && ctl->max == 1)
 		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -323,10 +325,11 @@
 	return 0;
 }
 
-static int snd_emu10k1_gpr_ctl_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_gpr_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_fx8010_ctl *ctl =
+		(struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
 	unsigned long flags;
 	unsigned int i;
 	
@@ -337,10 +340,11 @@
 	return 0;
 }
 
-static int snd_emu10k1_gpr_ctl_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_gpr_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	snd_emu10k1_fx8010_ctl_t *ctl = (snd_emu10k1_fx8010_ctl_t *)kcontrol->private_value;
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_fx8010_ctl *ctl =
+		(struct snd_emu10k1_fx8010_ctl *) kcontrol->private_value;
 	unsigned long flags;
 	unsigned int nval, val;
 	unsigned int i, j;
@@ -393,9 +397,9 @@
  *   Interrupt handler
  */
 
-static void snd_emu10k1_fx8010_interrupt(emu10k1_t *emu)
+static void snd_emu10k1_fx8010_interrupt(struct snd_emu10k1 *emu)
 {
-	snd_emu10k1_fx8010_irq_t *irq, *nirq;
+	struct snd_emu10k1_fx8010_irq *irq, *nirq;
 
 	irq = emu->fx8010.irq_handlers;
 	while (irq) {
@@ -409,13 +413,13 @@
 	}
 }
 
-int snd_emu10k1_fx8010_register_irq_handler(emu10k1_t *emu,
-						   snd_fx8010_irq_handler_t *handler,
-						   unsigned char gpr_running,
-						   void *private_data,
-						   snd_emu10k1_fx8010_irq_t **r_irq)
+int snd_emu10k1_fx8010_register_irq_handler(struct snd_emu10k1 *emu,
+					    snd_fx8010_irq_handler_t *handler,
+					    unsigned char gpr_running,
+					    void *private_data,
+					    struct snd_emu10k1_fx8010_irq **r_irq)
 {
-	snd_emu10k1_fx8010_irq_t *irq;
+	struct snd_emu10k1_fx8010_irq *irq;
 	unsigned long flags;
 	
 	irq = kmalloc(sizeof(*irq), GFP_ATOMIC);
@@ -440,10 +444,10 @@
 	return 0;
 }
 
-int snd_emu10k1_fx8010_unregister_irq_handler(emu10k1_t *emu,
-					      snd_emu10k1_fx8010_irq_t *irq)
+int snd_emu10k1_fx8010_unregister_irq_handler(struct snd_emu10k1 *emu,
+					      struct snd_emu10k1_fx8010_irq *irq)
 {
-	snd_emu10k1_fx8010_irq_t *tmp;
+	struct snd_emu10k1_fx8010_irq *tmp;
 	unsigned long flags;
 	
 	spin_lock_irqsave(&emu->fx8010.irq_lock, flags);
@@ -468,7 +472,8 @@
  * EMU10K1 effect manager
  *************************************************************************/
 
-static void snd_emu10k1_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
+static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
+				 unsigned int *ptr,
 				 u32 op, u32 r, u32 a, u32 x, u32 y)
 {
 	u_int32_t *code;
@@ -483,7 +488,8 @@
 #define OP(icode, ptr, op, r, a, x, y) \
 	snd_emu10k1_write_op(icode, ptr, op, r, a, x, y)
 
-static void snd_emu10k1_audigy_write_op(emu10k1_fx8010_code_t *icode, unsigned int *ptr,
+static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
+					unsigned int *ptr,
 					u32 op, u32 r, u32 a, u32 x, u32 y)
 {
 	u_int32_t *code;
@@ -498,19 +504,20 @@
 #define A_OP(icode, ptr, op, r, a, x, y) \
 	snd_emu10k1_audigy_write_op(icode, ptr, op, r, a, x, y)
 
-static void snd_emu10k1_efx_write(emu10k1_t *emu, unsigned int pc, unsigned int data)
+static void snd_emu10k1_efx_write(struct snd_emu10k1 *emu, unsigned int pc, unsigned int data)
 {
 	pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
 	snd_emu10k1_ptr_write(emu, pc, 0, data);
 }
 
-unsigned int snd_emu10k1_efx_read(emu10k1_t *emu, unsigned int pc)
+unsigned int snd_emu10k1_efx_read(struct snd_emu10k1 *emu, unsigned int pc)
 {
 	pc += emu->audigy ? A_MICROCODEBASE : MICROCODEBASE;
 	return snd_emu10k1_ptr_read(emu, pc, 0);
 }
 
-static int snd_emu10k1_gpr_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
+				struct snd_emu10k1_fx8010_code *icode)
 {
 	int gpr;
 	u32 val;
@@ -525,7 +532,8 @@
 	return 0;
 }
 
-static int snd_emu10k1_gpr_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
+				struct snd_emu10k1_fx8010_code *icode)
 {
 	int gpr;
 	u32 val;
@@ -539,7 +547,8 @@
 	return 0;
 }
 
-static int snd_emu10k1_tram_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
+				 struct snd_emu10k1_fx8010_code *icode)
 {
 	int tram;
 	u32 addr, val;
@@ -561,7 +570,8 @@
 	return 0;
 }
 
-static int snd_emu10k1_tram_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
+				 struct snd_emu10k1_fx8010_code *icode)
 {
 	int tram;
 	u32 val, addr;
@@ -583,7 +593,8 @@
 	return 0;
 }
 
-static int snd_emu10k1_code_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
+				 struct snd_emu10k1_fx8010_code *icode)
 {
 	u32 pc, lo, hi;
 
@@ -599,7 +610,8 @@
 	return 0;
 }
 
-static int snd_emu10k1_code_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
+				 struct snd_emu10k1_fx8010_code *icode)
 {
 	u32 pc;
 
@@ -614,10 +626,11 @@
 	return 0;
 }
 
-static snd_emu10k1_fx8010_ctl_t *snd_emu10k1_look_for_ctl(emu10k1_t *emu, snd_ctl_elem_id_t *id)
+static struct snd_emu10k1_fx8010_ctl *
+snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
 {
-	snd_emu10k1_fx8010_ctl_t *ctl;
-	snd_kcontrol_t *kcontrol;
+	struct snd_emu10k1_fx8010_ctl *ctl;
+	struct snd_kcontrol *kcontrol;
 	struct list_head *list;
 	
 	list_for_each(list, &emu->fx8010.gpr_ctl) {
@@ -631,13 +644,14 @@
 	return NULL;
 }
 
-static int snd_emu10k1_verify_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
+				       struct snd_emu10k1_fx8010_code *icode)
 {
 	unsigned int i;
-	snd_ctl_elem_id_t __user *_id;
-	snd_ctl_elem_id_t id;
-	emu10k1_fx8010_control_gpr_t __user *_gctl;
-	emu10k1_fx8010_control_gpr_t *gctl;
+	struct snd_ctl_elem_id __user *_id;
+	struct snd_ctl_elem_id id;
+	struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
+	struct snd_emu10k1_fx8010_control_gpr *gctl;
 	int err;
 	
 	for (i = 0, _id = icode->gpr_del_controls;
@@ -685,28 +699,29 @@
 	return err;
 }
 
-static void snd_emu10k1_ctl_private_free(snd_kcontrol_t *kctl)
+static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
 {
-	snd_emu10k1_fx8010_ctl_t *ctl;
+	struct snd_emu10k1_fx8010_ctl *ctl;
 	
-	ctl = (snd_emu10k1_fx8010_ctl_t *)kctl->private_value;
+	ctl = (struct snd_emu10k1_fx8010_ctl *) kctl->private_value;
 	kctl->private_value = 0;
 	list_del(&ctl->list);
 	kfree(ctl);
 }
 
-static int snd_emu10k1_add_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
+				    struct snd_emu10k1_fx8010_code *icode)
 {
 	unsigned int i, j;
-	emu10k1_fx8010_control_gpr_t __user *_gctl;
-	emu10k1_fx8010_control_gpr_t *gctl;
-	snd_emu10k1_fx8010_ctl_t *ctl, *nctl;
-	snd_kcontrol_new_t knew;
-	snd_kcontrol_t *kctl;
-	snd_ctl_elem_value_t *val;
+	struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
+	struct snd_emu10k1_fx8010_control_gpr *gctl;
+	struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
+	struct snd_kcontrol_new knew;
+	struct snd_kcontrol *kctl;
+	struct snd_ctl_elem_value *val;
 	int err = 0;
 
-	val = (snd_ctl_elem_value_t *)kmalloc(sizeof(*val), GFP_KERNEL);
+	val = kmalloc(sizeof(*val), GFP_KERNEL);
 	gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
 	nctl = kmalloc(sizeof(*nctl), GFP_KERNEL);
 	if (!val || !gctl || !nctl) {
@@ -751,7 +766,7 @@
 		nctl->max = gctl->max;
 		nctl->translation = gctl->translation;
 		if (ctl == NULL) {
-			ctl = (snd_emu10k1_fx8010_ctl_t *)kmalloc(sizeof(*ctl), GFP_KERNEL);
+			ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
 			if (ctl == NULL) {
 				err = -ENOMEM;
 				goto __error;
@@ -782,13 +797,14 @@
 	return err;
 }
 
-static int snd_emu10k1_del_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
+				    struct snd_emu10k1_fx8010_code *icode)
 {
 	unsigned int i;
-	snd_ctl_elem_id_t id;
-	snd_ctl_elem_id_t __user *_id;
-	snd_emu10k1_fx8010_ctl_t *ctl;
-	snd_card_t *card = emu->card;
+	struct snd_ctl_elem_id id;
+	struct snd_ctl_elem_id __user *_id;
+	struct snd_emu10k1_fx8010_ctl *ctl;
+	struct snd_card *card = emu->card;
 	
 	for (i = 0, _id = icode->gpr_del_controls;
 	     i < icode->gpr_del_control_count; i++, _id++) {
@@ -803,14 +819,15 @@
 	return 0;
 }
 
-static int snd_emu10k1_list_controls(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
+				     struct snd_emu10k1_fx8010_code *icode)
 {
 	unsigned int i = 0, j;
 	unsigned int total = 0;
-	emu10k1_fx8010_control_gpr_t *gctl;
-	emu10k1_fx8010_control_gpr_t __user *_gctl;
-	snd_emu10k1_fx8010_ctl_t *ctl;
-	snd_ctl_elem_id_t *id;
+	struct snd_emu10k1_fx8010_control_gpr *gctl;
+	struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
+	struct snd_emu10k1_fx8010_ctl *ctl;
+	struct snd_ctl_elem_id *id;
 	struct list_head *list;
 
 	gctl = kmalloc(sizeof(*gctl), GFP_KERNEL);
@@ -851,7 +868,8 @@
 	return 0;
 }
 
-static int snd_emu10k1_icode_poke(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_icode_poke(struct snd_emu10k1 *emu,
+				  struct snd_emu10k1_fx8010_code *icode)
 {
 	int err = 0;
 
@@ -882,7 +900,8 @@
 	return err;
 }
 
-static int snd_emu10k1_icode_peek(emu10k1_t *emu, emu10k1_fx8010_code_t *icode)
+static int snd_emu10k1_icode_peek(struct snd_emu10k1 *emu,
+				  struct snd_emu10k1_fx8010_code *icode)
 {
 	int err;
 
@@ -900,11 +919,12 @@
 	return err;
 }
 
-static int snd_emu10k1_ipcm_poke(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
+static int snd_emu10k1_ipcm_poke(struct snd_emu10k1 *emu,
+				 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
 {
 	unsigned int i;
 	int err = 0;
-	snd_emu10k1_fx8010_pcm_t *pcm;
+	struct snd_emu10k1_fx8010_pcm *pcm;
 
 	if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
 		return -EINVAL;
@@ -945,11 +965,12 @@
 	return err;
 }
 
-static int snd_emu10k1_ipcm_peek(emu10k1_t *emu, emu10k1_fx8010_pcm_t *ipcm)
+static int snd_emu10k1_ipcm_peek(struct snd_emu10k1 *emu,
+				 struct snd_emu10k1_fx8010_pcm_rec *ipcm)
 {
 	unsigned int i;
 	int err = 0;
-	snd_emu10k1_fx8010_pcm_t *pcm;
+	struct snd_emu10k1_fx8010_pcm *pcm;
 
 	if (ipcm->substream >= EMU10K1_FX8010_PCM_COUNT)
 		return -EINVAL;
@@ -979,7 +1000,9 @@
 #define SND_EMU10K1_PLAYBACK_CHANNELS	8
 #define SND_EMU10K1_CAPTURE_CHANNELS	4
 
-static void __devinit snd_emu10k1_init_mono_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
+static void __devinit
+snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
+			      const char *name, int gpr, int defval)
 {
 	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	strcpy(ctl->id.name, name);
@@ -990,7 +1013,9 @@
 	ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;	
 }
 
-static void __devinit snd_emu10k1_init_stereo_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
+static void __devinit
+snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
+				const char *name, int gpr, int defval)
 {
 	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	strcpy(ctl->id.name, name);
@@ -1002,7 +1027,9 @@
 	ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
 }
 
-static void __devinit snd_emu10k1_init_mono_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
+static void __devinit
+snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
+				    const char *name, int gpr, int defval)
 {
 	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	strcpy(ctl->id.name, name);
@@ -1013,7 +1040,9 @@
 	ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
 }
 
-static void __devinit snd_emu10k1_init_stereo_onoff_control(emu10k1_fx8010_control_gpr_t *ctl, const char *name, int gpr, int defval)
+static void __devinit
+snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
+				      const char *name, int gpr, int defval)
 {
 	ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	strcpy(ctl->id.name, name);
@@ -1030,7 +1059,7 @@
  * initial DSP configuration for Audigy
  */
 
-static int __devinit _snd_emu10k1_audigy_init_efx(emu10k1_t *emu)
+static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
 {
 	int err, i, z, gpr, nctl;
 	const int playback = 10;
@@ -1038,17 +1067,17 @@
 	const int stereo_mix = capture + 2;
 	const int tmp = 0x88;
 	u32 ptr;
-	emu10k1_fx8010_code_t *icode = NULL;
-	emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
+	struct snd_emu10k1_fx8010_code *icode = NULL;
+	struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
 	u32 *gpr_map;
 	mm_segment_t seg;
 
-	spin_lock_init(&emu->fx8010.irq_lock);
-	INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
-
 	if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL ||
-	    (icode->gpr_map = (u_int32_t __user *)kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
-	    (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(*controls), GFP_KERNEL)) == NULL) {
+	    (icode->gpr_map = (u_int32_t __user *)
+	     kcalloc(512 + 256 + 256 + 2 * 1024, sizeof(u_int32_t),
+		     GFP_KERNEL)) == NULL ||
+	    (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
+				sizeof(*controls), GFP_KERNEL)) == NULL) {
 		err = -ENOMEM;
 		goto __err;
 	}
@@ -1074,6 +1103,14 @@
 	/* stop FX processor */
 	snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
 
+#if 0
+	/* FIX: jcd test */
+	for (z = 0; z < 80; z=z+2) {
+		A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */
+		A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */
+	}
+#endif /* jcd test */
+#if 1
 	/* PCM front Playback Volume (independent from stereo mix) */
 	A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
 	A_OP(icode, &ptr, iMAC0, A_GPR(playback+1), A_C_00000000, A_GPR(gpr+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT));
@@ -1419,6 +1456,7 @@
 		A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
 	}
 	
+#endif /* JCD test */
 	/*
 	 * ok, set up done..
 	 */
@@ -1434,7 +1472,7 @@
 
 	seg = snd_enter_user();
 	icode->gpr_add_control_count = nctl;
-	icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
+	icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
 	err = snd_emu10k1_icode_poke(emu, icode);
 	snd_leave_user(seg);
 
@@ -1454,14 +1492,14 @@
 
 /* when volume = max, then copy only to avoid volume modification */
 /* with iMAC0 (negative values) */
-static void __devinit _volume(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
+static void __devinit _volume(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
 {
 	OP(icode, ptr, iMAC0, dst, C_00000000, src, vol);
 	OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
 	OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000001);
 	OP(icode, ptr, iACC3, dst, src, C_00000000, C_00000000);
 }
-static void __devinit _volume_add(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
+static void __devinit _volume_add(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
 {
 	OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
 	OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
@@ -1469,7 +1507,7 @@
 	OP(icode, ptr, iSKIP, C_00000000, C_7fffffff, C_7fffffff, C_00000001);
 	OP(icode, ptr, iMAC0, dst, dst, src, vol);
 }
-static void __devinit _volume_out(emu10k1_fx8010_code_t *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
+static void __devinit _volume_out(struct snd_emu10k1_fx8010_code *icode, u32 *ptr, u32 dst, u32 src, u32 vol)
 {
 	OP(icode, ptr, iANDXOR, C_00000000, vol, C_ffffffff, C_7fffffff);
 	OP(icode, ptr, iSKIP, GPR_COND, GPR_COND, CC_REG_NONZERO, C_00000002);
@@ -1500,23 +1538,24 @@
 		_SWITCH_NEG(icode, ptr, GPR(dst), GPR(src))
 
 
-static int __devinit _snd_emu10k1_init_efx(emu10k1_t *emu)
+static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
 {
 	int err, i, z, gpr, tmp, playback, capture;
 	u32 ptr;
-	emu10k1_fx8010_code_t *icode;
-	emu10k1_fx8010_pcm_t *ipcm = NULL;
-	emu10k1_fx8010_control_gpr_t *controls = NULL, *ctl;
+	struct snd_emu10k1_fx8010_code *icode;
+	struct snd_emu10k1_fx8010_pcm_rec *ipcm = NULL;
+	struct snd_emu10k1_fx8010_control_gpr *controls = NULL, *ctl;
 	u32 *gpr_map;
 	mm_segment_t seg;
 
-	spin_lock_init(&emu->fx8010.irq_lock);
-	INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
-
 	if ((icode = kzalloc(sizeof(*icode), GFP_KERNEL)) == NULL)
 		return -ENOMEM;
-	if ((icode->gpr_map = (u_int32_t __user *)kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t), GFP_KERNEL)) == NULL ||
-            (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, sizeof(emu10k1_fx8010_control_gpr_t), GFP_KERNEL)) == NULL ||
+	if ((icode->gpr_map = (u_int32_t __user *)
+	     kcalloc(256 + 160 + 160 + 2 * 512, sizeof(u_int32_t),
+		     GFP_KERNEL)) == NULL ||
+            (controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
+				sizeof(struct snd_emu10k1_fx8010_control_gpr),
+				GFP_KERNEL)) == NULL ||
 	    (ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL)) == NULL) {
 		err = -ENOMEM;
 		goto __err;
@@ -2050,7 +2089,7 @@
 		goto __err;
 	seg = snd_enter_user();
 	icode->gpr_add_control_count = i;
-	icode->gpr_add_controls = (emu10k1_fx8010_control_gpr_t __user *)controls;
+	icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
 	err = snd_emu10k1_icode_poke(emu, icode);
 	snd_leave_user(seg);
 	if (err >= 0)
@@ -2065,15 +2104,17 @@
 	return err;
 }
 
-int __devinit snd_emu10k1_init_efx(emu10k1_t *emu)
+int __devinit snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
 {
+	spin_lock_init(&emu->fx8010.irq_lock);
+	INIT_LIST_HEAD(&emu->fx8010.gpr_ctl);
 	if (emu->audigy)
 		return _snd_emu10k1_audigy_init_efx(emu);
 	else
 		return _snd_emu10k1_init_efx(emu);
 }
 
-void snd_emu10k1_free_efx(emu10k1_t *emu)
+void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
 {
 	/* stop processor */
 	if (emu->audigy)
@@ -2083,7 +2124,7 @@
 }
 
 #if 0 // FIXME: who use them?
-int snd_emu10k1_fx8010_tone_control_activate(emu10k1_t *emu, int output)
+int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
 {
 	if (output < 0 || output >= 6)
 		return -EINVAL;
@@ -2091,7 +2132,7 @@
 	return 0;
 }
 
-int snd_emu10k1_fx8010_tone_control_deactivate(emu10k1_t *emu, int output)
+int snd_emu10k1_fx8010_tone_control_deactivate(struct snd_emu10k1 *emu, int output)
 {
 	if (output < 0 || output >= 6)
 		return -EINVAL;
@@ -2100,7 +2141,7 @@
 }
 #endif
 
-int snd_emu10k1_fx8010_tram_setup(emu10k1_t *emu, u32 size)
+int snd_emu10k1_fx8010_tram_setup(struct snd_emu10k1 *emu, u32 size)
 {
 	u8 size_reg = 0;
 
@@ -2136,13 +2177,13 @@
 		snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
 		spin_lock_irq(&emu->emu_lock);
 		outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
-		spin_unlock_irq(&emu->emu_lock);	
+		spin_unlock_irq(&emu->emu_lock);
 	}
 
 	return 0;
 }
 
-static int snd_emu10k1_fx8010_open(snd_hwdep_t * hw, struct file *file)
+static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
 {
 	return 0;
 }
@@ -2155,7 +2196,8 @@
 		strcpy(dst, src);
 }
 
-static int snd_emu10k1_fx8010_info(emu10k1_t *emu, emu10k1_fx8010_info_t *info)
+static int snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
+				   struct snd_emu10k1_fx8010_info *info)
 {
 	char **fxbus, **extin, **extout;
 	unsigned short fxbus_mask, extin_mask, extout_mask;
@@ -2181,19 +2223,19 @@
 	return 0;
 }
 
-static int snd_emu10k1_fx8010_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
+static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, unsigned int cmd, unsigned long arg)
 {
-	emu10k1_t *emu = hw->private_data;
-	emu10k1_fx8010_info_t *info;
-	emu10k1_fx8010_code_t *icode;
-	emu10k1_fx8010_pcm_t *ipcm;
+	struct snd_emu10k1 *emu = hw->private_data;
+	struct snd_emu10k1_fx8010_info *info;
+	struct snd_emu10k1_fx8010_code *icode;
+	struct snd_emu10k1_fx8010_pcm_rec *ipcm;
 	unsigned int addr;
 	void __user *argp = (void __user *)arg;
 	int res;
 	
 	switch (cmd) {
 	case SNDRV_EMU10K1_IOCTL_INFO:
-		info = (emu10k1_fx8010_info_t *)kmalloc(sizeof(*info), GFP_KERNEL);
+		info = kmalloc(sizeof(*info), GFP_KERNEL);
 		if (!info)
 			return -ENOMEM;
 		if ((res = snd_emu10k1_fx8010_info(emu, info)) < 0) {
@@ -2209,7 +2251,7 @@
 	case SNDRV_EMU10K1_IOCTL_CODE_POKE:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
+		icode = kmalloc(sizeof(*icode), GFP_KERNEL);
 		if (icode == NULL)
 			return -ENOMEM;
 		if (copy_from_user(icode, argp, sizeof(*icode))) {
@@ -2220,7 +2262,7 @@
 		kfree(icode);
 		return res;
 	case SNDRV_EMU10K1_IOCTL_CODE_PEEK:
-		icode = (emu10k1_fx8010_code_t *)kmalloc(sizeof(*icode), GFP_KERNEL);
+		icode = kmalloc(sizeof(*icode), GFP_KERNEL);
 		if (icode == NULL)
 			return -ENOMEM;
 		if (copy_from_user(icode, argp, sizeof(*icode))) {
@@ -2235,7 +2277,7 @@
 		kfree(icode);
 		return res;
 	case SNDRV_EMU10K1_IOCTL_PCM_POKE:
-		ipcm = (emu10k1_fx8010_pcm_t *)kmalloc(sizeof(*ipcm), GFP_KERNEL);
+		ipcm = kmalloc(sizeof(*ipcm), GFP_KERNEL);
 		if (ipcm == NULL)
 			return -ENOMEM;
 		if (copy_from_user(ipcm, argp, sizeof(*ipcm))) {
@@ -2327,14 +2369,14 @@
 	return -ENOTTY;
 }
 
-static int snd_emu10k1_fx8010_release(snd_hwdep_t * hw, struct file *file)
+static int snd_emu10k1_fx8010_release(struct snd_hwdep * hw, struct file *file)
 {
 	return 0;
 }
 
-int __devinit snd_emu10k1_fx8010_new(emu10k1_t *emu, int device, snd_hwdep_t ** rhwdep)
+int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct snd_hwdep ** rhwdep)
 {
-	snd_hwdep_t *hw;
+	struct snd_hwdep *hw;
 	int err;
 	
 	if (rhwdep)
@@ -2351,3 +2393,114 @@
 		*rhwdep = hw;
 	return 0;
 }
+
+#ifdef CONFIG_PM
+int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
+{
+	int len;
+
+	len = emu->audigy ? 0x200 : 0x100;
+	emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL);
+	if (! emu->saved_gpr)
+		return -ENOMEM;
+	len = emu->audigy ? 0x100 : 0xa0;
+	emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL);
+	emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL);
+	if (! emu->tram_val_saved || ! emu->tram_addr_saved)
+		return -ENOMEM;
+	len = emu->audigy ? 2 * 1024 : 2 * 512;
+	emu->saved_icode = vmalloc(len * 4);
+	if (! emu->saved_icode)
+		return -ENOMEM;
+	return 0;
+}
+
+void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu)
+{
+	kfree(emu->saved_gpr);
+	kfree(emu->tram_val_saved);
+	kfree(emu->tram_addr_saved);
+	vfree(emu->saved_icode);
+}
+
+/*
+ * save/restore GPR, TRAM and codes
+ */
+void snd_emu10k1_efx_suspend(struct snd_emu10k1 *emu)
+{
+	int i, len;
+
+	len = emu->audigy ? 0x200 : 0x100;
+	for (i = 0; i < len; i++)
+		emu->saved_gpr[i] = snd_emu10k1_ptr_read(emu, emu->gpr_base + i, 0);
+
+	len = emu->audigy ? 0x100 : 0xa0;
+	for (i = 0; i < len; i++) {
+		emu->tram_val_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMDATAREGBASE + i, 0);
+		emu->tram_addr_saved[i] = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + i, 0);
+		if (emu->audigy) {
+			emu->tram_addr_saved[i] >>= 12;
+			emu->tram_addr_saved[i] |=
+				snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + i, 0) << 20;
+		}
+	}
+
+	len = emu->audigy ? 2 * 1024 : 2 * 512;
+	for (i = 0; i < len; i++)
+		emu->saved_icode[i] = snd_emu10k1_efx_read(emu, i);
+}
+
+void snd_emu10k1_efx_resume(struct snd_emu10k1 *emu)
+{
+	int i, len;
+
+	/* set up TRAM */
+	if (emu->fx8010.etram_pages.bytes > 0) {
+		unsigned size, size_reg = 0;
+		size = emu->fx8010.etram_pages.bytes / 2;
+		size = (size - 1) >> 13;
+		while (size) {
+			size >>= 1;
+			size_reg++;
+		}
+		outl(HCFG_LOCKTANKCACHE_MASK | inl(emu->port + HCFG), emu->port + HCFG);
+		snd_emu10k1_ptr_write(emu, TCB, 0, emu->fx8010.etram_pages.addr);
+		snd_emu10k1_ptr_write(emu, TCBS, 0, size_reg);
+		outl(inl(emu->port + HCFG) & ~HCFG_LOCKTANKCACHE_MASK, emu->port + HCFG);
+	}
+
+	if (emu->audigy)
+		snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg | A_DBG_SINGLE_STEP);
+	else
+		snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg | EMU10K1_DBG_SINGLE_STEP);
+
+	len = emu->audigy ? 0x200 : 0x100;
+	for (i = 0; i < len; i++)
+		snd_emu10k1_ptr_write(emu, emu->gpr_base + i, 0, emu->saved_gpr[i]);
+
+	len = emu->audigy ? 0x100 : 0xa0;
+	for (i = 0; i < len; i++) {
+		snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + i, 0,
+				      emu->tram_val_saved[i]);
+		if (! emu->audigy)
+			snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
+					      emu->tram_addr_saved[i]);
+		else {
+			snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
+					      emu->tram_addr_saved[i] << 12);
+			snd_emu10k1_ptr_write(emu, TANKMEMADDRREGBASE + i, 0,
+					      emu->tram_addr_saved[i] >> 20);
+		}
+	}
+
+	len = emu->audigy ? 2 * 1024 : 2 * 512;
+	for (i = 0; i < len; i++)
+		snd_emu10k1_efx_write(emu, i, emu->saved_icode[i]);
+
+	/* start FX processor when the DSP code is updated */
+	if (emu->audigy)
+		snd_emu10k1_ptr_write(emu, A_DBG, 0, emu->fx8010.dbg);
+	else
+		snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg);
+}
+#endif
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index 7cc831c..2e86a90 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -35,17 +35,17 @@
 
 #define AC97_ID_STAC9758	0x83847658
 
-static int snd_emu10k1_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_emu10k1_spdif_get(snd_kcontrol_t * kcontrol,
-                                 snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_spdif_get(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	unsigned long flags;
 
@@ -58,8 +58,8 @@
 	return 0;
 }
 
-static int snd_emu10k1_spdif_get_mask(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = 0xff;
 	ucontrol->value.iec958.status[1] = 0xff;
@@ -69,7 +69,7 @@
 }
 
 #if 0
-static int snd_audigy_spdif_output_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"44100", "48000", "96000"};
 
@@ -82,10 +82,10 @@
 	return 0;
 }
 
-static int snd_audigy_spdif_output_rate_get(snd_kcontrol_t * kcontrol,
-                                 snd_ctl_elem_value_t * ucontrol)
+static int snd_audigy_spdif_output_rate_get(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int tmp;
 	unsigned long flags;
 	
@@ -109,10 +109,10 @@
 	return 0;
 }
 
-static int snd_audigy_spdif_output_rate_put(snd_kcontrol_t * kcontrol,
-                                 snd_ctl_elem_value_t * ucontrol)
+static int snd_audigy_spdif_output_rate_put(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int reg, val, tmp;
 	unsigned long flags;
@@ -143,7 +143,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_audigy_spdif_output_rate =
+static struct snd_kcontrol_new snd_audigy_spdif_output_rate =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,
 	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -155,10 +155,10 @@
 };
 #endif
 
-static int snd_emu10k1_spdif_put(snd_kcontrol_t * kcontrol,
-                                 snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_spdif_put(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	int change;
 	unsigned int val;
@@ -178,7 +178,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1_spdif_mask_control =
+static struct snd_kcontrol_new snd_emu10k1_spdif_mask_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -188,7 +188,7 @@
 	.get =          snd_emu10k1_spdif_get_mask
 };
 
-static snd_kcontrol_new_t snd_emu10k1_spdif_control =
+static struct snd_kcontrol_new snd_emu10k1_spdif_control =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -199,7 +199,7 @@
 };
 
 
-static void update_emu10k1_fxrt(emu10k1_t *emu, int voice, unsigned char *route)
+static void update_emu10k1_fxrt(struct snd_emu10k1 *emu, int voice, unsigned char *route)
 {
 	if (emu->audigy) {
 		snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
@@ -212,7 +212,7 @@
 	}
 }
 
-static void update_emu10k1_send_volume(emu10k1_t *emu, int voice, unsigned char *volume)
+static void update_emu10k1_send_volume(struct snd_emu10k1 *emu, int voice, unsigned char *volume)
 {
 	snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_A, voice, volume[0]);
 	snd_emu10k1_ptr_write(emu, PTRX_FXSENDAMOUNT_B, voice, volume[1]);
@@ -229,9 +229,9 @@
 
 /* PCM stream controls */
 
-static int snd_emu10k1_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = emu->audigy ? 3*8 : 3*4;
 	uinfo->value.integer.min = 0;
@@ -239,12 +239,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_send_routing_get(snd_kcontrol_t * kcontrol,
-                                        snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_send_routing_get(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_pcm_mixer *mix =
+		&emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
 	int voice, idx;
 	int num_efx = emu->audigy ? 8 : 4;
 	int mask = emu->audigy ? 0x3f : 0x0f;
@@ -258,12 +259,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_send_routing_put(snd_kcontrol_t * kcontrol,
-                                        snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_send_routing_put(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_pcm_mixer *mix =
+		&emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
 	int change = 0, voice, idx, val;
 	int num_efx = emu->audigy ? 8 : 4;
 	int mask = emu->audigy ? 0x3f : 0x0f;
@@ -292,7 +294,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1_send_routing_control =
+static struct snd_kcontrol_new snd_emu10k1_send_routing_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -303,9 +305,9 @@
 	.put =          snd_emu10k1_send_routing_put
 };
 
-static int snd_emu10k1_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = emu->audigy ? 3*8 : 3*4;
 	uinfo->value.integer.min = 0;
@@ -313,12 +315,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_send_volume_get(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_send_volume_get(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_pcm_mixer *mix =
+		&emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
 	int idx;
 	int num_efx = emu->audigy ? 8 : 4;
 
@@ -329,12 +332,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_send_volume_put(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_send_volume_put(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_pcm_mixer *mix =
+		&emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
 	int change = 0, idx, val;
 	int num_efx = emu->audigy ? 8 : 4;
 
@@ -361,7 +365,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1_send_volume_control =
+static struct snd_kcontrol_new snd_emu10k1_send_volume_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -372,7 +376,7 @@
 	.put =          snd_emu10k1_send_volume_put
 };
 
-static int snd_emu10k1_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 3;
@@ -381,11 +385,12 @@
 	return 0;
 }
 
-static int snd_emu10k1_attn_get(snd_kcontrol_t * kcontrol,
-                                snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_attn_get(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_pcm_mixer *mix =
+		&emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
 	unsigned long flags;
 	int idx;
 
@@ -396,12 +401,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_attn_put(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_attn_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_pcm_mixer *mix =
+		&emu->pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
 	int change = 0, idx, val;
 
 	spin_lock_irqsave(&emu->reg_lock, flags);
@@ -424,7 +430,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1_attn_control =
+static struct snd_kcontrol_new snd_emu10k1_attn_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -437,9 +443,9 @@
 
 /* Mutichannel PCM stream controls */
 
-static int snd_emu10k1_efx_send_routing_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_efx_send_routing_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = emu->audigy ? 8 : 4;
 	uinfo->value.integer.min = 0;
@@ -447,12 +453,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_efx_send_routing_get(snd_kcontrol_t * kcontrol,
-                                        snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_efx_send_routing_get(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_pcm_mixer *mix =
+		&emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
 	int idx;
 	int num_efx = emu->audigy ? 8 : 4;
 	int mask = emu->audigy ? 0x3f : 0x0f;
@@ -465,13 +472,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_efx_send_routing_put(snd_kcontrol_t * kcontrol,
-                                        snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_efx_send_routing_put(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-	emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
+	struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
 	int change = 0, idx, val;
 	int num_efx = emu->audigy ? 8 : 4;
 	int mask = emu->audigy ? 0x3f : 0x0f;
@@ -495,7 +502,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1_efx_send_routing_control =
+static struct snd_kcontrol_new snd_emu10k1_efx_send_routing_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -506,9 +513,9 @@
 	.put =          snd_emu10k1_efx_send_routing_put
 };
 
-static int snd_emu10k1_efx_send_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_efx_send_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = emu->audigy ? 8 : 4;
 	uinfo->value.integer.min = 0;
@@ -516,12 +523,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_efx_send_volume_get(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_efx_send_volume_get(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_pcm_mixer *mix =
+		&emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
 	int idx;
 	int num_efx = emu->audigy ? 8 : 4;
 
@@ -532,13 +540,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_efx_send_volume_put(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_efx_send_volume_put(struct snd_kcontrol *kcontrol,
+                                       struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-	emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
+	struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
 	int change = 0, idx, val;
 	int num_efx = emu->audigy ? 8 : 4;
 
@@ -561,7 +569,7 @@
 }
 
 
-static snd_kcontrol_new_t snd_emu10k1_efx_send_volume_control =
+static struct snd_kcontrol_new snd_emu10k1_efx_send_volume_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -572,7 +580,7 @@
 	.put =          snd_emu10k1_efx_send_volume_put
 };
 
-static int snd_emu10k1_efx_attn_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_efx_attn_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -581,11 +589,12 @@
 	return 0;
 }
 
-static int snd_emu10k1_efx_attn_get(snd_kcontrol_t * kcontrol,
-                                snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_efx_attn_get(struct snd_kcontrol *kcontrol,
+                                struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-	emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1_pcm_mixer *mix =
+		&emu->efx_pcm_mixer[snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)];
 	unsigned long flags;
 
 	spin_lock_irqsave(&emu->reg_lock, flags);
@@ -594,13 +603,13 @@
 	return 0;
 }
 
-static int snd_emu10k1_efx_attn_put(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_efx_attn_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	int ch = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-	emu10k1_pcm_mixer_t *mix = &emu->efx_pcm_mixer[ch];
+	struct snd_emu10k1_pcm_mixer *mix = &emu->efx_pcm_mixer[ch];
 	int change = 0, val;
 
 	spin_lock_irqsave(&emu->reg_lock, flags);
@@ -618,7 +627,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1_efx_attn_control =
+static struct snd_kcontrol_new snd_emu10k1_efx_attn_control =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =        SNDRV_CTL_ELEM_IFACE_PCM,
@@ -629,7 +638,7 @@
 	.put =          snd_emu10k1_efx_attn_put
 };
 
-static int snd_emu10k1_shared_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_shared_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -638,10 +647,10 @@
 	return 0;
 }
 
-static int snd_emu10k1_shared_spdif_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_shared_spdif_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 
 	if (emu->audigy)
 		ucontrol->value.integer.value[0] = inl(emu->port + A_IOCFG) & A_IOCFG_GPOUT0 ? 1 : 0;
@@ -650,11 +659,11 @@
 	return 0;
 }
 
-static int snd_emu10k1_shared_spdif_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned long flags;
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int reg, val;
 	int change = 0;
 
@@ -681,7 +690,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1_shared_spdif __devinitdata =
+static struct snd_kcontrol_new snd_emu10k1_shared_spdif __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"SB Live Analog/Digital Output Jack",
@@ -690,7 +699,7 @@
 	.put =		snd_emu10k1_shared_spdif_put
 };
 
-static snd_kcontrol_new_t snd_audigy_shared_spdif __devinitdata =
+static struct snd_kcontrol_new snd_audigy_shared_spdif __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Audigy Analog/Digital Output Jack",
@@ -701,35 +710,35 @@
 
 /*
  */
-static void snd_emu10k1_mixer_free_ac97(ac97_t *ac97)
+static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	emu10k1_t *emu = ac97->private_data;
+	struct snd_emu10k1 *emu = ac97->private_data;
 	emu->ac97 = NULL;
 }
 
 /*
  */
-static int remove_ctl(snd_card_t *card, const char *name)
+static int remove_ctl(struct snd_card *card, const char *name)
 {
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 	memset(&id, 0, sizeof(id));
 	strcpy(id.name, name);
 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_remove_id(card, &id);
 }
 
-static snd_kcontrol_t *ctl_find(snd_card_t *card, const char *name)
+static struct snd_kcontrol *ctl_find(struct snd_card *card, const char *name)
 {
-	snd_ctl_elem_id_t sid;
+	struct snd_ctl_elem_id sid;
 	memset(&sid, 0, sizeof(sid));
 	strcpy(sid.name, name);
 	sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
 	return snd_ctl_find_id(card, &sid);
 }
 
-static int rename_ctl(snd_card_t *card, const char *src, const char *dst)
+static int rename_ctl(struct snd_card *card, const char *src, const char *dst)
 {
-	snd_kcontrol_t *kctl = ctl_find(card, src);
+	struct snd_kcontrol *kctl = ctl_find(card, src);
 	if (kctl) {
 		strcpy(kctl->id.name, dst);
 		return 0;
@@ -737,12 +746,12 @@
 	return -ENOENT;
 }
 
-int __devinit snd_emu10k1_mixer(emu10k1_t *emu,
+int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
 				int pcm_device, int multi_device)
 {
 	int err, pcm;
-	snd_kcontrol_t *kctl;
-	snd_card_t *card = emu->card;
+	struct snd_kcontrol *kctl;
+	struct snd_card *card = emu->card;
 	char **c;
 	static char *emu10k1_remove_ctls[] = {
 		/* no AC97 mono, surround, center/lfe */
@@ -795,9 +804,9 @@
 	};
 
 	if (emu->card_capabilities->ac97_chip) {
-		ac97_bus_t *pbus;
-		ac97_template_t ac97;
-		static ac97_bus_ops_t ops = {
+		struct snd_ac97_bus *pbus;
+		struct snd_ac97_template ac97;
+		static struct snd_ac97_bus_ops ops = {
 			.write = snd_emu10k1_ac97_write,
 			.read = snd_emu10k1_ac97_read,
 		};
@@ -857,7 +866,17 @@
 		c = emu10k1_rename_ctls;
 	for (; *c; c += 2)
 		rename_ctl(card, c[0], c[1]);
-
+	if (emu->card_capabilities->subsystem == 0x20071102) {  /* Audigy 4 Pro */
+		rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume");
+		rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume");
+		rename_ctl(card, "Aux2 Capture Volume", "Line3 Capture Volume");
+		rename_ctl(card, "Mic Capture Volume", "Unknown1 Capture Volume");
+		remove_ctl(card, "Headphone Playback Switch");
+		remove_ctl(card, "Headphone Playback Volume");
+		remove_ctl(card, "3D Control - Center");
+		remove_ctl(card, "3D Control - Depth");
+		remove_ctl(card, "3D Control - Switch");
+	}
 	if ((kctl = emu->ctl_send_routing = snd_ctl_new1(&snd_emu10k1_send_routing_control, emu)) == NULL)
 		return -ENOMEM;
 	kctl->id.device = pcm_device;
@@ -894,7 +913,7 @@
 
 	/* initialize the routing and volume table for each pcm playback stream */
 	for (pcm = 0; pcm < 32; pcm++) {
-		emu10k1_pcm_mixer_t *mix;
+		struct snd_emu10k1_pcm_mixer *mix;
 		int v;
 		
 		mix = &emu->pcm_mixer[pcm];
@@ -914,7 +933,7 @@
 	
 	/* initialize the routing and volume table for the multichannel playback stream */
 	for (pcm = 0; pcm < NUM_EFX_PLAYBACK; pcm++) {
-		emu10k1_pcm_mixer_t *mix;
+		struct snd_emu10k1_pcm_mixer *mix;
 		int v;
 		
 		mix = &emu->efx_pcm_mixer[pcm];
@@ -950,7 +969,9 @@
 			return err;
 	}
 
-	if (emu->audigy) {
+	if ( emu->card_capabilities->emu1212m) {
+		;  /* Disable the snd_audigy_spdif_shared_spdif */
+	} else if (emu->audigy) {
 		if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
 			return -ENOMEM;
 		if ((err = snd_ctl_add(card, kctl)))
diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c
index eb57458..d96eb45 100644
--- a/sound/pci/emu10k1/emumpu401.c
+++ b/sound/pci/emu10k1/emumpu401.c
@@ -28,7 +28,8 @@
 #define EMU10K1_MIDI_MODE_INPUT		(1<<0)
 #define EMU10K1_MIDI_MODE_OUTPUT	(1<<1)
 
-static inline unsigned char mpu401_read(emu10k1_t *emu, emu10k1_midi_t *mpu, int idx)
+static inline unsigned char mpu401_read(struct snd_emu10k1 *emu,
+					struct snd_emu10k1_midi *mpu, int idx)
 {
 	if (emu->audigy)
 		return (unsigned char)snd_emu10k1_ptr_read(emu, mpu->port + idx, 0);
@@ -36,7 +37,8 @@
 		return inb(emu->port + mpu->port + idx);
 }
 
-static inline void mpu401_write(emu10k1_t *emu, emu10k1_midi_t *mpu, int data, int idx)
+static inline void mpu401_write(struct snd_emu10k1 *emu,
+				struct snd_emu10k1_midi *mpu, int data, int idx)
 {
 	if (emu->audigy)
 		snd_emu10k1_ptr_write(emu, mpu->port + idx, 0, data);
@@ -56,7 +58,7 @@
 #define MPU401_ENTER_UART	0x3f
 #define MPU401_ACK		0xfe
 
-static void mpu401_clear_rx(emu10k1_t *emu, emu10k1_midi_t *mpu)
+static void mpu401_clear_rx(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *mpu)
 {
 	int timeout = 100000;
 	for (; timeout > 0 && mpu401_input_avail(emu, mpu); timeout--)
@@ -71,7 +73,7 @@
 
  */
 
-static void do_emu10k1_midi_interrupt(emu10k1_t *emu, emu10k1_midi_t *midi, unsigned int status)
+static void do_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, unsigned int status)
 {
 	unsigned char byte;
 
@@ -104,17 +106,17 @@
 	spin_unlock(&midi->output_lock);
 }
 
-static void snd_emu10k1_midi_interrupt(emu10k1_t *emu, unsigned int status)
+static void snd_emu10k1_midi_interrupt(struct snd_emu10k1 *emu, unsigned int status)
 {
 	do_emu10k1_midi_interrupt(emu, &emu->midi, status);
 }
 
-static void snd_emu10k1_midi_interrupt2(emu10k1_t *emu, unsigned int status)
+static void snd_emu10k1_midi_interrupt2(struct snd_emu10k1 *emu, unsigned int status)
 {
 	do_emu10k1_midi_interrupt(emu, &emu->midi2, status);
 }
 
-static void snd_emu10k1_midi_cmd(emu10k1_t * emu, emu10k1_midi_t *midi, unsigned char cmd, int ack)
+static void snd_emu10k1_midi_cmd(struct snd_emu10k1 * emu, struct snd_emu10k1_midi *midi, unsigned char cmd, int ack)
 {
 	unsigned long flags;
 	int timeout, ok;
@@ -146,10 +148,10 @@
 			   mpu401_read_data(emu, midi));
 }
 
-static int snd_emu10k1_midi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream)
 {
-	emu10k1_t *emu;
-	emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
+	struct snd_emu10k1 *emu;
+	struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
 	unsigned long flags;
 
 	emu = midi->emu;
@@ -167,10 +169,10 @@
 	return 0;
 }
 
-static int snd_emu10k1_midi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream)
 {
-	emu10k1_t *emu;
-	emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
+	struct snd_emu10k1 *emu;
+	struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
 	unsigned long flags;
 
 	emu = midi->emu;
@@ -188,10 +190,10 @@
 	return 0;
 }
 
-static int snd_emu10k1_midi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream)
 {
-	emu10k1_t *emu;
-	emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
+	struct snd_emu10k1 *emu;
+	struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
 	unsigned long flags;
 
 	emu = midi->emu;
@@ -209,10 +211,10 @@
 	return 0;
 }
 
-static int snd_emu10k1_midi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream)
 {
-	emu10k1_t *emu;
-	emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
+	struct snd_emu10k1 *emu;
+	struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
 	unsigned long flags;
 
 	emu = midi->emu;
@@ -230,10 +232,10 @@
 	return 0;
 }
 
-static void snd_emu10k1_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	emu10k1_t *emu;
-	emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
+	struct snd_emu10k1 *emu;
+	struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
 	emu = midi->emu;
 	snd_assert(emu, return);
 
@@ -243,10 +245,10 @@
 		snd_emu10k1_intr_disable(emu, midi->rx_enable);
 }
 
-static void snd_emu10k1_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	emu10k1_t *emu;
-	emu10k1_midi_t *midi = (emu10k1_midi_t *)substream->rmidi->private_data;
+	struct snd_emu10k1 *emu;
+	struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data;
 	unsigned long flags;
 
 	emu = midi->emu;
@@ -283,30 +285,30 @@
 
  */
 
-static snd_rawmidi_ops_t snd_emu10k1_midi_output =
+static struct snd_rawmidi_ops snd_emu10k1_midi_output =
 {
 	.open =		snd_emu10k1_midi_output_open,
 	.close =	snd_emu10k1_midi_output_close,
 	.trigger =	snd_emu10k1_midi_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_emu10k1_midi_input =
+static struct snd_rawmidi_ops snd_emu10k1_midi_input =
 {
 	.open =		snd_emu10k1_midi_input_open,
 	.close =	snd_emu10k1_midi_input_close,
 	.trigger =	snd_emu10k1_midi_input_trigger,
 };
 
-static void snd_emu10k1_midi_free(snd_rawmidi_t *rmidi)
+static void snd_emu10k1_midi_free(struct snd_rawmidi *rmidi)
 {
-	emu10k1_midi_t *midi = (emu10k1_midi_t *)rmidi->private_data;
+	struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)rmidi->private_data;
 	midi->interrupt = NULL;
 	midi->rmidi = NULL;
 }
 
-static int __devinit emu10k1_midi_init(emu10k1_t *emu, emu10k1_midi_t *midi, int device, char *name)
+static int __devinit emu10k1_midi_init(struct snd_emu10k1 *emu, struct snd_emu10k1_midi *midi, int device, char *name)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0)
@@ -327,9 +329,9 @@
 	return 0;
 }
 
-int __devinit snd_emu10k1_midi(emu10k1_t *emu)
+int __devinit snd_emu10k1_midi(struct snd_emu10k1 *emu)
 {
-	emu10k1_midi_t *midi = &emu->midi;
+	struct snd_emu10k1_midi *midi = &emu->midi;
 	int err;
 
 	if ((err = emu10k1_midi_init(emu, midi, 0, "EMU10K1 MPU-401 (UART)")) < 0)
@@ -344,9 +346,9 @@
 	return 0;
 }
 
-int __devinit snd_emu10k1_audigy_midi(emu10k1_t *emu)
+int __devinit snd_emu10k1_audigy_midi(struct snd_emu10k1 *emu)
 {
-	emu10k1_midi_t *midi;
+	struct snd_emu10k1_midi *midi;
 	int err;
 
 	midi = &emu->midi;
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index bf7490d..717e92e 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -35,9 +35,10 @@
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 
-static void snd_emu10k1_pcm_interrupt(emu10k1_t *emu, emu10k1_voice_t *voice)
+static void snd_emu10k1_pcm_interrupt(struct snd_emu10k1 *emu,
+				      struct snd_emu10k1_voice *voice)
 {
-	emu10k1_pcm_t *epcm;
+	struct snd_emu10k1_pcm *epcm;
 
 	if ((epcm = voice->epcm) == NULL)
 		return;
@@ -52,7 +53,8 @@
 	snd_pcm_period_elapsed(epcm->substream);
 }
 
-static void snd_emu10k1_pcm_ac97adc_interrupt(emu10k1_t *emu, unsigned int status)
+static void snd_emu10k1_pcm_ac97adc_interrupt(struct snd_emu10k1 *emu,
+					      unsigned int status)
 {
 #if 0
 	if (status & IPR_ADCBUFHALFFULL) {
@@ -63,7 +65,8 @@
 	snd_pcm_period_elapsed(emu->pcm_capture_substream);
 }
 
-static void snd_emu10k1_pcm_ac97mic_interrupt(emu10k1_t *emu, unsigned int status)
+static void snd_emu10k1_pcm_ac97mic_interrupt(struct snd_emu10k1 *emu,
+					      unsigned int status)
 {
 #if 0
 	if (status & IPR_MICBUFHALFFULL) {
@@ -74,7 +77,8 @@
 	snd_pcm_period_elapsed(emu->pcm_capture_mic_substream);
 }
 
-static void snd_emu10k1_pcm_efx_interrupt(emu10k1_t *emu, unsigned int status)
+static void snd_emu10k1_pcm_efx_interrupt(struct snd_emu10k1 *emu,
+					  unsigned int status)
 {
 #if 0
 	if (status & IPR_EFXBUFHALFFULL) {
@@ -85,11 +89,11 @@
 	snd_pcm_period_elapsed(emu->pcm_capture_efx_substream);
 }	 
 
-static snd_pcm_uframes_t snd_emu10k1_efx_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_emu10k1_efx_playback_pointer(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	unsigned int ptr;
 
 	if (!epcm->running)
@@ -102,7 +106,7 @@
 	return ptr;
 }
 
-static int snd_emu10k1_pcm_channel_alloc(emu10k1_pcm_t * epcm, int voices)
+static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voices)
 {
 	int err, i;
 
@@ -167,7 +171,7 @@
 	384*128,448*128,512*128
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_capture_period_sizes = {
+static struct snd_pcm_hw_constraint_list hw_constraints_capture_period_sizes = {
 	.count = 31,
 	.list = capture_period_sizes,
 	.mask = 0
@@ -177,7 +181,7 @@
 	8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_capture_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraints_capture_rates = {
 	.count = 8,
 	.list = capture_rates,
 	.mask = 0
@@ -271,15 +275,15 @@
 	}
 }
 
-static void snd_emu10k1_pcm_init_voice(emu10k1_t *emu,
+static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
 				       int master, int extra,
-				       emu10k1_voice_t *evoice,
+				       struct snd_emu10k1_voice *evoice,
 				       unsigned int start_addr,
 				       unsigned int end_addr,
-				       emu10k1_pcm_mixer_t *mix)
+				       struct snd_emu10k1_pcm_mixer *mix)
 {
-	snd_pcm_substream_t *substream = evoice->epcm->substream;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_substream *substream = evoice->epcm->substream;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int silent_page, tmp;
 	int voice, stereo, w_16;
 	unsigned char attn, send_amount[8];
@@ -392,12 +396,12 @@
 	spin_unlock_irqrestore(&emu->reg_lock, flags);
 }
 
-static int snd_emu10k1_playback_hw_params(snd_pcm_substream_t * substream,
-					  snd_pcm_hw_params_t * hw_params)
+static int snd_emu10k1_playback_hw_params(struct snd_pcm_substream *substream,
+					  struct snd_pcm_hw_params *hw_params)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	int err;
 
 	if ((err = snd_emu10k1_pcm_channel_alloc(epcm, params_channels(hw_params))) < 0)
@@ -405,24 +409,26 @@
 	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
 		return err;
 	if (err > 0) {	/* change */
-		snd_util_memblk_t *memblk;
+		int mapped;
 		if (epcm->memblk != NULL)
 			snd_emu10k1_free_pages(emu, epcm->memblk);
-		memblk = snd_emu10k1_alloc_pages(emu, substream);
-		if ((epcm->memblk = memblk) == NULL || ((emu10k1_memblk_t *)memblk)->mapped_page < 0) {
-			epcm->start_addr = 0;
+		epcm->memblk = snd_emu10k1_alloc_pages(emu, substream);
+		epcm->start_addr = 0;
+		if (! epcm->memblk)
 			return -ENOMEM;
-		}
-		epcm->start_addr = ((emu10k1_memblk_t *)memblk)->mapped_page << PAGE_SHIFT;
+		mapped = ((struct snd_emu10k1_memblk *)epcm->memblk)->mapped_page;
+		if (mapped < 0)
+			return -ENOMEM;
+		epcm->start_addr = mapped << PAGE_SHIFT;
 	}
 	return 0;
 }
 
-static int snd_emu10k1_playback_hw_free(snd_pcm_substream_t * substream)
+static int snd_emu10k1_playback_hw_free(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm;
 
 	if (runtime->private_data == NULL)
 		return 0;
@@ -448,11 +454,11 @@
 	return 0;
 }
 
-static int snd_emu10k1_efx_playback_hw_free(snd_pcm_substream_t * substream)
+static int snd_emu10k1_efx_playback_hw_free(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm;
 	int i;
 
 	if (runtime->private_data == NULL)
@@ -477,11 +483,11 @@
 	return 0;
 }
 
-static int snd_emu10k1_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_emu10k1_playback_prepare(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	unsigned int start_addr, end_addr;
 
 	start_addr = epcm->start_addr;
@@ -505,11 +511,11 @@
 	return 0;
 }
 
-static int snd_emu10k1_efx_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_emu10k1_efx_playback_prepare(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	unsigned int start_addr, end_addr;
 	unsigned int channel_size;
 	int i;
@@ -541,10 +547,11 @@
 	return 0;
 }
 
-static snd_pcm_hardware_t snd_emu10k1_efx_playback =
+static struct snd_pcm_hardware snd_emu10k1_efx_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_NONINTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_RESUME |
 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_48000,
@@ -560,22 +567,22 @@
 	.fifo_size =		0,
 };
 
-static int snd_emu10k1_capture_hw_params(snd_pcm_substream_t * substream,
-					 snd_pcm_hw_params_t * hw_params)
+static int snd_emu10k1_capture_hw_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_emu10k1_capture_hw_free(snd_pcm_substream_t * substream)
+static int snd_emu10k1_capture_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_emu10k1_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_emu10k1_capture_prepare(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	int idx;
 
 	/* zeroing the buffer size will stop capture */
@@ -618,9 +625,9 @@
 	return 0;
 }
 
-static void snd_emu10k1_playback_invalidate_cache(emu10k1_t *emu, int extra, emu10k1_voice_t *evoice)
+static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int extra, struct snd_emu10k1_voice *evoice)
 {
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_runtime *runtime;
 	unsigned int voice, stereo, i, ccis, cra = 64, cs, sample;
 
 	if (evoice == NULL)
@@ -653,12 +660,12 @@
 	}
 }
 
-static void snd_emu10k1_playback_prepare_voice(emu10k1_t *emu, emu10k1_voice_t *evoice,
+static void snd_emu10k1_playback_prepare_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice,
 					       int master, int extra,
-					       emu10k1_pcm_mixer_t *mix)
+					       struct snd_emu10k1_pcm_mixer *mix)
 {
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	unsigned int attn, vattn;
 	unsigned int voice, tmp;
 
@@ -678,10 +685,10 @@
 	snd_emu10k1_voice_clear_loop_stop(emu, voice);
 }	
 
-static void snd_emu10k1_playback_trigger_voice(emu10k1_t *emu, emu10k1_voice_t *evoice, int master, int extra)
+static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice, int master, int extra)
 {
-	snd_pcm_substream_t *substream;
-	snd_pcm_runtime_t *runtime;
+	struct snd_pcm_substream *substream;
+	struct snd_pcm_runtime *runtime;
 	unsigned int voice, pitch, pitch_target;
 
 	if (evoice == NULL)	/* skip second voice for mono */
@@ -700,7 +707,7 @@
 		snd_emu10k1_voice_intr_enable(emu, voice);
 }
 
-static void snd_emu10k1_playback_stop_voice(emu10k1_t *emu, emu10k1_voice_t *evoice)
+static void snd_emu10k1_playback_stop_voice(struct snd_emu10k1 *emu, struct snd_emu10k1_voice *evoice)
 {
 	unsigned int voice;
 
@@ -716,13 +723,13 @@
 	snd_emu10k1_ptr_write(emu, IP, voice, 0);
 }
 
-static int snd_emu10k1_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
 				        int cmd)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
-	emu10k1_pcm_mixer_t *mix;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
+	struct snd_emu10k1_pcm_mixer *mix;
 	int result = 0;
 
 	// printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream));
@@ -733,6 +740,7 @@
 		snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]);
 		/* follow thru */
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		mix = &emu->pcm_mixer[substream->number];
 		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix);
 		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix);
@@ -744,6 +752,7 @@
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		epcm->running = 0;
 		snd_emu10k1_playback_stop_voice(emu, epcm->voices[0]);
 		snd_emu10k1_playback_stop_voice(emu, epcm->voices[1]);
@@ -757,17 +766,18 @@
 	return result;
 }
 
-static int snd_emu10k1_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	int result = 0;
 
 	spin_lock(&emu->reg_lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		// hmm this should cause full and half full interrupt to be raised?  
 		outl(epcm->capture_ipr, emu->port + IPR);
 		snd_emu10k1_intr_enable(emu, epcm->capture_inte);
@@ -791,6 +801,7 @@
 		epcm->first_ptr = 1;
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		epcm->running = 0;
 		snd_emu10k1_intr_disable(emu, epcm->capture_inte);
 		outl(epcm->capture_ipr, emu->port + IPR);
@@ -817,11 +828,11 @@
 	return result;
 }
 
-static snd_pcm_uframes_t snd_emu10k1_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	unsigned int ptr;
 
 	if (!epcm->running)
@@ -845,12 +856,12 @@
 }
 
 
-static int snd_emu10k1_efx_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
 				        int cmd)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	int i;
 	int result = 0;
 
@@ -865,6 +876,7 @@
 
 		/* follow thru */
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
 		snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0,
 						   &emu->efx_pcm_mixer[0]);
@@ -877,6 +889,7 @@
 			snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0, 0);
 		epcm->running = 1;
 		break;
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		epcm->running = 0;
@@ -894,11 +907,11 @@
 }
 
 
-static snd_pcm_uframes_t snd_emu10k1_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_emu10k1_capture_pointer(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	unsigned int ptr;
 
 	if (!epcm->running)
@@ -915,10 +928,11 @@
  *  Playback support device description
  */
 
-static snd_pcm_hardware_t snd_emu10k1_playback =
+static struct snd_pcm_hardware snd_emu10k1_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_RESUME |
 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_96000,
@@ -938,10 +952,11 @@
  *  Capture support device description
  */
 
-static snd_pcm_hardware_t snd_emu10k1_capture =
+static struct snd_pcm_hardware snd_emu10k1_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_RESUME |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_8000_48000,
@@ -961,9 +976,9 @@
  *
  */
 
-static void snd_emu10k1_pcm_mixer_notify1(emu10k1_t *emu, snd_kcontrol_t *kctl, int idx, int activate)
+static void snd_emu10k1_pcm_mixer_notify1(struct snd_emu10k1 *emu, struct snd_kcontrol *kctl, int idx, int activate)
 {
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 
 	if (! kctl)
 		return;
@@ -976,29 +991,29 @@
 		       snd_ctl_build_ioff(&id, kctl, idx));
 }
 
-static void snd_emu10k1_pcm_mixer_notify(emu10k1_t *emu, int idx, int activate)
+static void snd_emu10k1_pcm_mixer_notify(struct snd_emu10k1 *emu, int idx, int activate)
 {
 	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_routing, idx, activate);
 	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_send_volume, idx, activate);
 	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_attn, idx, activate);
 }
 
-static void snd_emu10k1_pcm_efx_mixer_notify(emu10k1_t *emu, int idx, int activate)
+static void snd_emu10k1_pcm_efx_mixer_notify(struct snd_emu10k1 *emu, int idx, int activate)
 {
 	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_routing, idx, activate);
 	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_send_volume, idx, activate);
 	snd_emu10k1_pcm_mixer_notify1(emu, emu->ctl_efx_attn, idx, activate);
 }
 
-static void snd_emu10k1_pcm_free_substream(snd_pcm_runtime_t *runtime)
+static void snd_emu10k1_pcm_free_substream(struct snd_pcm_runtime *runtime)
 {
 	kfree(runtime->private_data);
 }
 
-static int snd_emu10k1_efx_playback_close(snd_pcm_substream_t * substream)
+static int snd_emu10k1_efx_playback_close(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	emu10k1_pcm_mixer_t *mix;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_pcm_mixer *mix;
 	int i;
 
 	for (i=0; i < NUM_EFX_PLAYBACK; i++) {
@@ -1009,12 +1024,12 @@
 	return 0;
 }
 
-static int snd_emu10k1_efx_playback_open(snd_pcm_substream_t * substream)
+static int snd_emu10k1_efx_playback_open(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	emu10k1_pcm_t *epcm;
-	emu10k1_pcm_mixer_t *mix;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_pcm *epcm;
+	struct snd_emu10k1_pcm_mixer *mix;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int i;
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
@@ -1042,12 +1057,12 @@
 	return 0;
 }
 
-static int snd_emu10k1_playback_open(snd_pcm_substream_t * substream)
+static int snd_emu10k1_playback_open(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	emu10k1_pcm_t *epcm;
-	emu10k1_pcm_mixer_t *mix;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_pcm *epcm;
+	struct snd_emu10k1_pcm_mixer *mix;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int i, err;
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
@@ -1079,21 +1094,21 @@
 	return 0;
 }
 
-static int snd_emu10k1_playback_close(snd_pcm_substream_t * substream)
+static int snd_emu10k1_playback_close(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	emu10k1_pcm_mixer_t *mix = &emu->pcm_mixer[substream->number];
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_pcm_mixer *mix = &emu->pcm_mixer[substream->number];
 
 	mix->epcm = NULL;
 	snd_emu10k1_pcm_mixer_notify(emu, substream->number, 0);
 	return 0;
 }
 
-static int snd_emu10k1_capture_open(snd_pcm_substream_t * substream)
+static int snd_emu10k1_capture_open(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm;
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL)
@@ -1116,20 +1131,20 @@
 	return 0;
 }
 
-static int snd_emu10k1_capture_close(snd_pcm_substream_t * substream)
+static int snd_emu10k1_capture_close(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 
 	emu->capture_interrupt = NULL;
 	emu->pcm_capture_substream = NULL;
 	return 0;
 }
 
-static int snd_emu10k1_capture_mic_open(snd_pcm_substream_t * substream)
+static int snd_emu10k1_capture_mic_open(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	emu10k1_pcm_t *epcm;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_pcm *epcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
 	if (epcm == NULL)
@@ -1154,20 +1169,20 @@
 	return 0;
 }
 
-static int snd_emu10k1_capture_mic_close(snd_pcm_substream_t * substream)
+static int snd_emu10k1_capture_mic_close(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 
 	emu->capture_interrupt = NULL;
 	emu->pcm_capture_mic_substream = NULL;
 	return 0;
 }
 
-static int snd_emu10k1_capture_efx_open(snd_pcm_substream_t * substream)
+static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	emu10k1_pcm_t *epcm;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_pcm *epcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int nefx = emu->audigy ? 64 : 32;
 	int idx;
 
@@ -1204,16 +1219,16 @@
 	return 0;
 }
 
-static int snd_emu10k1_capture_efx_close(snd_pcm_substream_t * substream)
+static int snd_emu10k1_capture_efx_close(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
 
 	emu->capture_interrupt = NULL;
 	emu->pcm_capture_efx_substream = NULL;
 	return 0;
 }
 
-static snd_pcm_ops_t snd_emu10k1_playback_ops = {
+static struct snd_pcm_ops snd_emu10k1_playback_ops = {
 	.open =			snd_emu10k1_playback_open,
 	.close =		snd_emu10k1_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1225,7 +1240,7 @@
 	.page =			snd_pcm_sgbuf_ops_page,
 };
 
-static snd_pcm_ops_t snd_emu10k1_capture_ops = {
+static struct snd_pcm_ops snd_emu10k1_capture_ops = {
 	.open =			snd_emu10k1_capture_open,
 	.close =		snd_emu10k1_capture_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1237,7 +1252,7 @@
 };
 
 /* EFX playback */
-static snd_pcm_ops_t snd_emu10k1_efx_playback_ops = {
+static struct snd_pcm_ops snd_emu10k1_efx_playback_ops = {
 	.open =			snd_emu10k1_efx_playback_open,
 	.close =		snd_emu10k1_efx_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1249,17 +1264,10 @@
 	.page =			snd_pcm_sgbuf_ops_page,
 };
 
-static void snd_emu10k1_pcm_free(snd_pcm_t *pcm)
+int __devinit snd_emu10k1_pcm(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
 {
-	emu10k1_t *emu = pcm->private_data;
-	emu->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int __devinit snd_emu10k1_pcm(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *substream;
 	int err;
 
 	if (rpcm)
@@ -1269,7 +1277,6 @@
 		return err;
 
 	pcm->private_data = emu;
-	pcm->private_free = snd_emu10k1_pcm_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_ops);
@@ -1292,10 +1299,10 @@
 	return 0;
 }
 
-int __devinit snd_emu10k1_pcm_multi(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
+int __devinit snd_emu10k1_pcm_multi(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *substream;
 	int err;
 
 	if (rpcm)
@@ -1305,14 +1312,13 @@
 		return err;
 
 	pcm->private_data = emu;
-	pcm->private_free = snd_emu10k1_pcm_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_efx_playback_ops);
 
 	pcm->info_flags = 0;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
 	strcpy(pcm->name, "Multichannel Playback");
-	emu->pcm = pcm;
+	emu->pcm_multi = pcm;
 
 	for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
 		if ((err = snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(emu->pci), 64*1024, 64*1024)) < 0)
@@ -1325,7 +1331,7 @@
 }
 
 
-static snd_pcm_ops_t snd_emu10k1_capture_mic_ops = {
+static struct snd_pcm_ops snd_emu10k1_capture_mic_ops = {
 	.open =			snd_emu10k1_capture_mic_open,
 	.close =		snd_emu10k1_capture_mic_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1336,16 +1342,9 @@
 	.pointer =		snd_emu10k1_capture_pointer,
 };
 
-static void snd_emu10k1_pcm_mic_free(snd_pcm_t *pcm)
+int __devinit snd_emu10k1_pcm_mic(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
 {
-	emu10k1_t *emu = pcm->private_data;
-	emu->pcm_mic = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int __devinit snd_emu10k1_pcm_mic(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1355,7 +1354,6 @@
 		return err;
 
 	pcm->private_data = emu;
-	pcm->private_free = snd_emu10k1_pcm_mic_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_mic_ops);
 
@@ -1370,9 +1368,9 @@
 	return 0;
 }
 
-static int snd_emu10k1_pcm_efx_voices_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_emu10k1_pcm_efx_voices_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	int nefx = emu->audigy ? 64 : 32;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = nefx;
@@ -1381,9 +1379,9 @@
 	return 0;
 }
 
-static int snd_emu10k1_pcm_efx_voices_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_pcm_efx_voices_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	int nefx = emu->audigy ? 64 : 32;
 	int idx;
 	
@@ -1394,9 +1392,9 @@
 	return 0;
 }
 
-static int snd_emu10k1_pcm_efx_voices_mask_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_emu10k1_pcm_efx_voices_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int nval[2], bits;
 	int nefx = emu->audigy ? 64 : 32;
 	int nefxb = emu->audigy ? 7 : 6;
@@ -1425,7 +1423,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_emu10k1_pcm_efx_voices_mask = {
+static struct snd_kcontrol_new snd_emu10k1_pcm_efx_voices_mask = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.name = "Captured FX8010 Outputs",
 	.info = snd_emu10k1_pcm_efx_voices_mask_info,
@@ -1433,7 +1431,7 @@
 	.put = snd_emu10k1_pcm_efx_voices_mask_put
 };
 
-static snd_pcm_ops_t snd_emu10k1_capture_efx_ops = {
+static struct snd_pcm_ops snd_emu10k1_capture_efx_ops = {
 	.open =			snd_emu10k1_capture_efx_open,
 	.close =		snd_emu10k1_capture_efx_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1450,9 +1448,9 @@
 #define INITIAL_TRAM_SHIFT     14
 #define INITIAL_TRAM_POS(size) ((((size) / 2) - INITIAL_TRAM_SHIFT) - 1)
 
-static void snd_emu10k1_fx8010_playback_irq(emu10k1_t *emu, void *private_data)
+static void snd_emu10k1_fx8010_playback_irq(struct snd_emu10k1 *emu, void *private_data)
 {
-	snd_pcm_substream_t *substream = private_data;
+	struct snd_pcm_substream *substream = private_data;
 	snd_pcm_period_elapsed(substream);
 }
 
@@ -1476,11 +1474,11 @@
 	}
 }
 
-static void fx8010_pb_trans_copy(snd_pcm_substream_t *substream,
-				 snd_pcm_indirect_t *rec, size_t bytes)
+static void fx8010_pb_trans_copy(struct snd_pcm_substream *substream,
+				 struct snd_pcm_indirect *rec, size_t bytes)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
 	unsigned int tram_size = pcm->buffer_size;
 	unsigned short *src = (unsigned short *)(substream->runtime->dma_area + rec->sw_data);
 	unsigned int frames = bytes >> 2, count;
@@ -1505,25 +1503,25 @@
 	pcm->tram_shift = tram_shift;
 }
 
-static int snd_emu10k1_fx8010_playback_transfer(snd_pcm_substream_t *substream)
+static int snd_emu10k1_fx8010_playback_transfer(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
 
 	snd_pcm_indirect_playback_transfer(substream, &pcm->pcm_rec, fx8010_pb_trans_copy);
 	return 0;
 }
 
-static int snd_emu10k1_fx8010_playback_hw_params(snd_pcm_substream_t * substream,
-						 snd_pcm_hw_params_t * hw_params)
+static int snd_emu10k1_fx8010_playback_hw_params(struct snd_pcm_substream *substream,
+						 struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_emu10k1_fx8010_playback_hw_free(snd_pcm_substream_t * substream)
+static int snd_emu10k1_fx8010_playback_hw_free(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
 	unsigned int i;
 
 	for (i = 0; i < pcm->channels; i++)
@@ -1532,11 +1530,11 @@
 	return 0;
 }
 
-static int snd_emu10k1_fx8010_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_emu10k1_fx8010_playback_prepare(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
 	unsigned int i;
 	
 	// printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2);
@@ -1556,10 +1554,10 @@
 	return 0;
 }
 
-static int snd_emu10k1_fx8010_playback_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_emu10k1_fx8010_playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
 	int result = 0;
 
 	spin_lock(&emu->reg_lock);
@@ -1567,6 +1565,7 @@
 	case SNDRV_PCM_TRIGGER_START:
 		/* follow thru */
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
 #ifdef EMU10K1_SET_AC3_IEC958
 	{
 		int i;
@@ -1587,6 +1586,7 @@
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		snd_emu10k1_fx8010_unregister_irq_handler(emu, pcm->irq); pcm->irq = NULL;
 		snd_emu10k1_ptr_write(emu, emu->gpr_base + pcm->gpr_trigger, 0, 0);
 		pcm->tram_pos = INITIAL_TRAM_POS(pcm->buffer_size);
@@ -1601,10 +1601,10 @@
 	return result;
 }
 
-static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_emu10k1_fx8010_playback_pointer(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
 	size_t ptr; /* byte pointer */
 
 	if (!snd_emu10k1_ptr_read(emu, emu->gpr_base + pcm->gpr_trigger, 0))
@@ -1613,9 +1613,10 @@
 	return snd_pcm_indirect_playback_pointer(substream, &pcm->pcm_rec, ptr);
 }
 
-static snd_pcm_hardware_t snd_emu10k1_fx8010_playback =
+static struct snd_pcm_hardware snd_emu10k1_fx8010_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+				 SNDRV_PCM_INFO_RESUME |
 				 /* SNDRV_PCM_INFO_MMAP_VALID | */ SNDRV_PCM_INFO_PAUSE),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_48000,
@@ -1631,11 +1632,11 @@
 	.fifo_size =		0,
 };
 
-static int snd_emu10k1_fx8010_playback_open(snd_pcm_substream_t * substream)
+static int snd_emu10k1_fx8010_playback_open(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
 
 	runtime->hw = snd_emu10k1_fx8010_playback;
 	runtime->hw.channels_min = runtime->hw.channels_max = pcm->channels;
@@ -1650,10 +1651,10 @@
 	return 0;
 }
 
-static int snd_emu10k1_fx8010_playback_close(snd_pcm_substream_t * substream)
+static int snd_emu10k1_fx8010_playback_close(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_emu10k1_fx8010_pcm_t *pcm = &emu->fx8010.pcm[substream->number];
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
 
 	spin_lock_irq(&emu->reg_lock);
 	pcm->opened = 0;
@@ -1661,7 +1662,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_emu10k1_fx8010_playback_ops = {
+static struct snd_pcm_ops snd_emu10k1_fx8010_playback_ops = {
 	.open =			snd_emu10k1_fx8010_playback_open,
 	.close =		snd_emu10k1_fx8010_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1673,17 +1674,10 @@
 	.ack =			snd_emu10k1_fx8010_playback_transfer,
 };
 
-static void snd_emu10k1_pcm_efx_free(snd_pcm_t *pcm)
+int __devinit snd_emu10k1_pcm_efx(struct snd_emu10k1 * emu, int device, struct snd_pcm ** rpcm)
 {
-	emu10k1_t *emu = pcm->private_data;
-	emu->pcm_efx = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int __devinit snd_emu10k1_pcm_efx(emu10k1_t * emu, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
-	snd_kcontrol_t *kctl;
+	struct snd_pcm *pcm;
+	struct snd_kcontrol *kctl;
 	int err;
 
 	if (rpcm)
@@ -1693,7 +1687,6 @@
 		return err;
 
 	pcm->private_data = emu;
-	pcm->private_free = snd_emu10k1_pcm_efx_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_emu10k1_fx8010_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_emu10k1_capture_efx_ops);
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index cc22707..90f1c52 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -32,8 +32,9 @@
 #include <sound/emu10k1.h>
 #include "p16v.h"
 
-static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu,
-					  snd_info_buffer_t * buffer,
+#ifdef CONFIG_PROC_FS
+static void snd_emu10k1_proc_spdif_status(struct snd_emu10k1 * emu,
+					  struct snd_info_buffer *buffer,
 					  char *title,
 					  int status_reg,
 					  int rate_reg)
@@ -75,8 +76,8 @@
 
 }
 
-static void snd_emu10k1_proc_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_emu10k1_proc_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
 	/* FIXME - output names are in emufx.c too */
 	static char *creative_outs[32] = {
@@ -181,7 +182,7 @@
 		/* 63 */ "FXBUS2_31"
 	};
 
-	emu10k1_t *emu = entry->private_data;
+	struct snd_emu10k1 *emu = entry->private_data;
 	unsigned int val, val1;
 	int nefx = emu->audigy ? 64 : 32;
 	char **outputs = emu->audigy ? audigy_outs : creative_outs;
@@ -232,10 +233,10 @@
 		snd_iprintf(buffer, "  Output %02i [%s]\n", idx, outputs[idx]);
 }
 
-static void snd_emu10k1_proc_spdif_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_emu10k1_proc_spdif_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
-	emu10k1_t *emu = entry->private_data;
+	struct snd_emu10k1 *emu = entry->private_data;
 	snd_emu10k1_proc_spdif_status(emu, buffer, "CD-ROM S/PDIF In", CDCS, CDSRCS);
 	snd_emu10k1_proc_spdif_status(emu, buffer, "Optical or Coax S/PDIF In", GPSCS, GPSRCS);
 #if 0
@@ -246,11 +247,11 @@
 #endif
 }
 
-static void snd_emu10k1_proc_rates_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_emu10k1_proc_rates_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
 	static int samplerate[8] = { 44100, 48000, 96000, 192000, 4, 5, 6, 7 };
-	emu10k1_t *emu = entry->private_data;
+	struct snd_emu10k1 *emu = entry->private_data;
 	unsigned int val, tmp, n;
 	val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0);
 	tmp = (val >> 16) & 0x8;
@@ -261,11 +262,11 @@
 	}
 }
 
-static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry, 
-				        snd_info_buffer_t * buffer)
+static void snd_emu10k1_proc_acode_read(struct snd_info_entry *entry, 
+				        struct snd_info_buffer *buffer)
 {
 	u32 pc;
-	emu10k1_t *emu = entry->private_data;
+	struct snd_emu10k1 *emu = entry->private_data;
 
 	snd_iprintf(buffer, "FX8010 Instruction List '%s'\n", emu->fx8010.name);
 	snd_iprintf(buffer, "  Code dump      :\n");
@@ -304,12 +305,13 @@
 #define TOTAL_SIZE_CODE		(0x200*8)
 #define A_TOTAL_SIZE_CODE	(0x400*8)
 
-static long snd_emu10k1_fx8010_read(snd_info_entry_t *entry, void *file_private_data,
+static long snd_emu10k1_fx8010_read(struct snd_info_entry *entry,
+				    void *file_private_data,
 				    struct file *file, char __user *buf,
 				    unsigned long count, unsigned long pos)
 {
 	long size;
-	emu10k1_t *emu = entry->private_data;
+	struct snd_emu10k1 *emu = entry->private_data;
 	unsigned int offset;
 	int tram_addr = 0;
 	
@@ -349,11 +351,11 @@
 	return 0;
 }
 
-static void snd_emu10k1_proc_voices_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
-	emu10k1_t *emu = entry->private_data;
-	emu10k1_voice_t *voice;
+	struct snd_emu10k1 *emu = entry->private_data;
+	struct snd_emu10k1_voice *voice;
 	int idx;
 	
 	snd_iprintf(buffer, "ch\tuse\tpcm\tefx\tsynth\tmidi\n");
@@ -370,10 +372,10 @@
 }
 
 #ifdef CONFIG_SND_DEBUG
-static void snd_emu_proc_io_reg_read(snd_info_entry_t *entry,
-				     snd_info_buffer_t * buffer)
+static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry,
+				     struct snd_info_buffer *buffer)
 {
-	emu10k1_t *emu = entry->private_data;
+	struct snd_emu10k1 *emu = entry->private_data;
 	unsigned long value;
 	unsigned long flags;
 	int i;
@@ -386,10 +388,10 @@
 	}
 }
 
-static void snd_emu_proc_io_reg_write(snd_info_entry_t *entry,
-                                      snd_info_buffer_t * buffer)
+static void snd_emu_proc_io_reg_write(struct snd_info_entry *entry,
+                                      struct snd_info_buffer *buffer)
 {
-	emu10k1_t *emu = entry->private_data;
+	struct snd_emu10k1 *emu = entry->private_data;
 	unsigned long flags;
 	char line[64];
 	u32 reg, val;
@@ -404,7 +406,7 @@
 	}
 }
 
-static unsigned int snd_ptr_read(emu10k1_t * emu,
+static unsigned int snd_ptr_read(struct snd_emu10k1 * emu,
 				 unsigned int iobase,
 				 unsigned int reg,
 				 unsigned int chn)
@@ -421,7 +423,7 @@
 	return val;
 }
 
-static void snd_ptr_write(emu10k1_t *emu,
+static void snd_ptr_write(struct snd_emu10k1 *emu,
 			  unsigned int iobase,
 			  unsigned int reg,
 			  unsigned int chn,
@@ -439,13 +441,13 @@
 }
 
 
-static void snd_emu_proc_ptr_reg_read(snd_info_entry_t *entry,
-				      snd_info_buffer_t * buffer, int iobase, int offset, int length, int voices)
+static void snd_emu_proc_ptr_reg_read(struct snd_info_entry *entry,
+				      struct snd_info_buffer *buffer, int iobase, int offset, int length, int voices)
 {
-	emu10k1_t *emu = entry->private_data;
+	struct snd_emu10k1 *emu = entry->private_data;
 	unsigned long value;
 	int i,j;
-	if (offset+length > 0x80) {
+	if (offset+length > 0xa0) {
 		snd_iprintf(buffer, "Input values out of range\n");
 		return;
 	}
@@ -463,65 +465,71 @@
 	}
 }
 
-static void snd_emu_proc_ptr_reg_write(snd_info_entry_t *entry,
-				       snd_info_buffer_t * buffer, int iobase)
+static void snd_emu_proc_ptr_reg_write(struct snd_info_entry *entry,
+				       struct snd_info_buffer *buffer, int iobase)
 {
-	emu10k1_t *emu = entry->private_data;
+	struct snd_emu10k1 *emu = entry->private_data;
 	char line[64];
 	unsigned int reg, channel_id , val;
 	while (!snd_info_get_line(buffer, line, sizeof(line))) {
 		if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
 			continue;
-		if ((reg < 0x80) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) )
+		if ((reg < 0xa0) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) )
 			snd_ptr_write(emu, iobase, reg, channel_id, val);
 	}
 }
 
-static void snd_emu_proc_ptr_reg_write00(snd_info_entry_t *entry,
-					 snd_info_buffer_t * buffer)
+static void snd_emu_proc_ptr_reg_write00(struct snd_info_entry *entry,
+					 struct snd_info_buffer *buffer)
 {
 	snd_emu_proc_ptr_reg_write(entry, buffer, 0);
 }
 
-static void snd_emu_proc_ptr_reg_write20(snd_info_entry_t *entry,
-					 snd_info_buffer_t * buffer)
+static void snd_emu_proc_ptr_reg_write20(struct snd_info_entry *entry,
+					 struct snd_info_buffer *buffer)
 {
 	snd_emu_proc_ptr_reg_write(entry, buffer, 0x20);
 }
 	
 
-static void snd_emu_proc_ptr_reg_read00a(snd_info_entry_t *entry,
-					 snd_info_buffer_t * buffer)
+static void snd_emu_proc_ptr_reg_read00a(struct snd_info_entry *entry,
+					 struct snd_info_buffer *buffer)
 {
 	snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0, 0x40, 64);
 }
 
-static void snd_emu_proc_ptr_reg_read00b(snd_info_entry_t *entry,
-					 snd_info_buffer_t * buffer)
+static void snd_emu_proc_ptr_reg_read00b(struct snd_info_entry *entry,
+					 struct snd_info_buffer *buffer)
 {
 	snd_emu_proc_ptr_reg_read(entry, buffer, 0, 0x40, 0x40, 64);
 }
 
-static void snd_emu_proc_ptr_reg_read20a(snd_info_entry_t *entry,
-					 snd_info_buffer_t * buffer)
+static void snd_emu_proc_ptr_reg_read20a(struct snd_info_entry *entry,
+					 struct snd_info_buffer *buffer)
 {
 	snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0, 0x40, 4);
 }
 
-static void snd_emu_proc_ptr_reg_read20b(snd_info_entry_t *entry,
-					 snd_info_buffer_t * buffer)
+static void snd_emu_proc_ptr_reg_read20b(struct snd_info_entry *entry,
+					 struct snd_info_buffer *buffer)
 {
 	snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x40, 0x40, 4);
 }
+
+static void snd_emu_proc_ptr_reg_read20c(struct snd_info_entry *entry,
+					 struct snd_info_buffer * buffer)
+{
+	snd_emu_proc_ptr_reg_read(entry, buffer, 0x20, 0x80, 0x20, 4);
+}
 #endif
 
 static struct snd_info_entry_ops snd_emu10k1_proc_ops_fx8010 = {
 	.read = snd_emu10k1_fx8010_read,
 };
 
-int __devinit snd_emu10k1_proc_init(emu10k1_t * emu)
+int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 #ifdef CONFIG_SND_DEBUG
 	if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
 		snd_info_set_text_ops(entry, emu, 1024, snd_emu_proc_io_reg_read);
@@ -553,6 +561,12 @@
 		entry->c.text.write = snd_emu_proc_ptr_reg_write20;
 		entry->mode |= S_IWUSR;
 	}
+	if (! snd_card_proc_new(emu->card, "ptr_regs20c", &entry)) {
+		snd_info_set_text_ops(entry, emu, 65536, snd_emu_proc_ptr_reg_read20c);
+		entry->c.text.write_size = 64;
+		entry->c.text.write = snd_emu_proc_ptr_reg_write20;
+		entry->mode |= S_IWUSR;
+	}
 #endif
 	
 	if (! snd_card_proc_new(emu->card, "emu10k1", &entry))
@@ -607,3 +621,4 @@
 	}
 	return 0;
 }
+#endif /* CONFIG_PROC_FS */
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index b9d3ae0..ef5304d 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -29,8 +29,9 @@
 #include <linux/time.h>
 #include <sound/core.h>
 #include <sound/emu10k1.h>
+#include <linux/delay.h>
 
-unsigned int snd_emu10k1_ptr_read(emu10k1_t * emu, unsigned int reg, unsigned int chn)
+unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
 {
 	unsigned long flags;
 	unsigned int regptr, val;
@@ -61,7 +62,7 @@
 	}
 }
 
-void snd_emu10k1_ptr_write(emu10k1_t *emu, unsigned int reg, unsigned int chn, unsigned int data)
+void snd_emu10k1_ptr_write(struct snd_emu10k1 *emu, unsigned int reg, unsigned int chn, unsigned int data)
 {
 	unsigned int regptr;
 	unsigned long flags;
@@ -91,7 +92,7 @@
 	}
 }
 
-unsigned int snd_emu10k1_ptr20_read(emu10k1_t * emu, 
+unsigned int snd_emu10k1_ptr20_read(struct snd_emu10k1 * emu, 
 					  unsigned int reg, 
 					  unsigned int chn)
 {
@@ -107,7 +108,7 @@
 	return val;
 }
 
-void snd_emu10k1_ptr20_write(emu10k1_t *emu, 
+void snd_emu10k1_ptr20_write(struct snd_emu10k1 *emu, 
 				   unsigned int reg, 
 				   unsigned int chn, 
 				   unsigned int data)
@@ -123,7 +124,46 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_intr_enable(emu10k1_t *emu, unsigned int intrenb)
+int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
+				   unsigned int data)
+{
+	unsigned int reset, set;
+	unsigned int reg, tmp;
+	int n, result;
+	if (emu->card_capabilities->ca0108_chip)
+		reg = 0x3c; /* PTR20, reg 0x3c */
+	else {
+		/* For other chip types the SPI register
+		 * is currently unknown. */
+		return 1;
+	}
+	if (data > 0xffff) /* Only 16bit values allowed */
+		return 1;
+
+	tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
+	reset = (tmp & ~0x3ffff) | 0x20000; /* Set xxx20000 */
+	set = reset | 0x10000; /* Set xxx1xxxx */
+	snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
+	tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* write post */
+	snd_emu10k1_ptr20_write(emu, reg, 0, set | data);
+	result = 1;
+	/* Wait for status bit to return to 0 */
+	for (n = 0; n < 100; n++) {
+		udelay(10);
+		tmp = snd_emu10k1_ptr20_read(emu, reg, 0);
+		if (!(tmp & 0x10000)) {
+			result = 0;
+			break;
+		}
+	}
+	if (result) /* Timed out */
+		return 1;
+	snd_emu10k1_ptr20_write(emu, reg, 0, reset | data);
+	tmp = snd_emu10k1_ptr20_read(emu, reg, 0); /* Write post */
+	return 0;
+}
+
+void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
 {
 	unsigned long flags;
 	unsigned int enable;
@@ -134,7 +174,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_intr_disable(emu10k1_t *emu, unsigned int intrenb)
+void snd_emu10k1_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
 {
 	unsigned long flags;
 	unsigned int enable;
@@ -145,7 +185,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_voice_intr_enable(emu10k1_t *emu, unsigned int voicenum)
+void snd_emu10k1_voice_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
 {
 	unsigned long flags;
 	unsigned int val;
@@ -165,7 +205,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_voice_intr_disable(emu10k1_t *emu, unsigned int voicenum)
+void snd_emu10k1_voice_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
 {
 	unsigned long flags;
 	unsigned int val;
@@ -185,7 +225,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_voice_intr_ack(emu10k1_t *emu, unsigned int voicenum)
+void snd_emu10k1_voice_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
 {
 	unsigned long flags;
 
@@ -202,7 +242,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_voice_half_loop_intr_enable(emu10k1_t *emu, unsigned int voicenum)
+void snd_emu10k1_voice_half_loop_intr_enable(struct snd_emu10k1 *emu, unsigned int voicenum)
 {
 	unsigned long flags;
 	unsigned int val;
@@ -222,7 +262,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_voice_half_loop_intr_disable(emu10k1_t *emu, unsigned int voicenum)
+void snd_emu10k1_voice_half_loop_intr_disable(struct snd_emu10k1 *emu, unsigned int voicenum)
 {
 	unsigned long flags;
 	unsigned int val;
@@ -242,7 +282,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_voice_half_loop_intr_ack(emu10k1_t *emu, unsigned int voicenum)
+void snd_emu10k1_voice_half_loop_intr_ack(struct snd_emu10k1 *emu, unsigned int voicenum)
 {
 	unsigned long flags;
 
@@ -259,7 +299,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_voice_set_loop_stop(emu10k1_t *emu, unsigned int voicenum)
+void snd_emu10k1_voice_set_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
 {
 	unsigned long flags;
 	unsigned int sol;
@@ -279,7 +319,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_voice_clear_loop_stop(emu10k1_t *emu, unsigned int voicenum)
+void snd_emu10k1_voice_clear_loop_stop(struct snd_emu10k1 *emu, unsigned int voicenum)
 {
 	unsigned long flags;
 	unsigned int sol;
@@ -299,7 +339,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-void snd_emu10k1_wait(emu10k1_t *emu, unsigned int wait)
+void snd_emu10k1_wait(struct snd_emu10k1 *emu, unsigned int wait)
 {
 	volatile unsigned count;
 	unsigned int newtime = 0, curtime;
@@ -318,9 +358,9 @@
 	}
 }
 
-unsigned short snd_emu10k1_ac97_read(ac97_t *ac97, unsigned short reg)
+unsigned short snd_emu10k1_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
-	emu10k1_t *emu = ac97->private_data;
+	struct snd_emu10k1 *emu = ac97->private_data;
 	unsigned long flags;
 	unsigned short val;
 
@@ -331,9 +371,9 @@
 	return val;
 }
 
-void snd_emu10k1_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short data)
+void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data)
 {
-	emu10k1_t *emu = ac97->private_data;
+	struct snd_emu10k1 *emu = ac97->private_data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&emu->emu_lock, flags);
diff --git a/sound/pci/emu10k1/irq.c b/sound/pci/emu10k1/irq.c
index 594ea06..a8b3128 100644
--- a/sound/pci/emu10k1/irq.c
+++ b/sound/pci/emu10k1/irq.c
@@ -32,7 +32,7 @@
 
 irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	emu10k1_t *emu = dev_id;
+	struct snd_emu10k1 *emu = dev_id;
 	unsigned int status, status2, orig_status, orig_status2;
 	int handled = 0;
 
@@ -56,7 +56,7 @@
 			int voice;
 			int voice_max = status & IPR_CHANNELNUMBERMASK;
 			u32 val;
-			emu10k1_voice_t *pvoice = emu->voices;
+			struct snd_emu10k1_voice *pvoice = emu->voices;
 
 			val = snd_emu10k1_ptr_read(emu, CLIPL, 0);
 			for (voice = 0; voice <= voice_max; voice++) {
@@ -150,8 +150,8 @@
 		if (status & IPR_P16V) {
 			while ((status2 = inl(emu->port + IPR2)) != 0) {
 				u32 mask = INTE2_PLAYBACK_CH_0_LOOP;  /* Full Loop */
-				emu10k1_voice_t *pvoice = &(emu->p16v_voices[0]);
-				emu10k1_voice_t *cvoice = &(emu->p16v_capture_voice);
+				struct snd_emu10k1_voice *pvoice = &(emu->p16v_voices[0]);
+				struct snd_emu10k1_voice *cvoice = &(emu->p16v_capture_voice);
 
 				//printk(KERN_INFO "status2=0x%x\n", status2);
 				orig_status2 = status2;
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index d42e4ae..68c795c 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -48,7 +48,7 @@
 #define set_silent_ptb(emu,page)	__set_ptb_entry(emu,page,emu->silent_page.addr)
 #else
 /* fill PTB entries -- we need to fill UNIT_PAGES entries */
-static inline void set_ptb_entry(emu10k1_t *emu, int page, dma_addr_t addr)
+static inline void set_ptb_entry(struct snd_emu10k1 *emu, int page, dma_addr_t addr)
 {
 	int i;
 	page *= UNIT_PAGES;
@@ -57,7 +57,7 @@
 		addr += EMUPAGESIZE;
 	}
 }
-static inline void set_silent_ptb(emu10k1_t *emu, int page)
+static inline void set_silent_ptb(struct snd_emu10k1 *emu, int page)
 {
 	int i;
 	page *= UNIT_PAGES;
@@ -70,14 +70,14 @@
 
 /*
  */
-static int synth_alloc_pages(emu10k1_t *hw, emu10k1_memblk_t *blk);
-static int synth_free_pages(emu10k1_t *hw, emu10k1_memblk_t *blk);
+static int synth_alloc_pages(struct snd_emu10k1 *hw, struct snd_emu10k1_memblk *blk);
+static int synth_free_pages(struct snd_emu10k1 *hw, struct snd_emu10k1_memblk *blk);
 
-#define get_emu10k1_memblk(l,member)	list_entry(l, emu10k1_memblk_t, member)
+#define get_emu10k1_memblk(l,member)	list_entry(l, struct snd_emu10k1_memblk, member)
 
 
 /* initialize emu10k1 part */
-static void emu10k1_memblk_init(emu10k1_memblk_t *blk)
+static void emu10k1_memblk_init(struct snd_emu10k1_memblk *blk)
 {
 	blk->mapped_page = -1;
 	INIT_LIST_HEAD(&blk->mapped_link);
@@ -96,7 +96,7 @@
  * in nextp
  * if not found, return a negative error code.
  */
-static int search_empty_map_area(emu10k1_t *emu, int npages, struct list_head **nextp)
+static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct list_head **nextp)
 {
 	int page = 0, found_page = -ENOMEM;
 	int max_size = npages;
@@ -105,7 +105,7 @@
 	struct list_head *pos;
 
 	list_for_each (pos, &emu->mapped_link_head) {
-		emu10k1_memblk_t *blk = get_emu10k1_memblk(pos, mapped_link);
+		struct snd_emu10k1_memblk *blk = get_emu10k1_memblk(pos, mapped_link);
 		snd_assert(blk->mapped_page >= 0, continue);
 		size = blk->mapped_page - page;
 		if (size == npages) {
@@ -134,7 +134,7 @@
  *
  * call with memblk_lock held
  */
-static int map_memblk(emu10k1_t *emu, emu10k1_memblk_t *blk)
+static int map_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
 {
 	int page, pg;
 	struct list_head *next;
@@ -161,11 +161,11 @@
  *
  * call with memblk_lock held
  */
-static int unmap_memblk(emu10k1_t *emu, emu10k1_memblk_t *blk)
+static int unmap_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
 {
 	int start_page, end_page, mpage, pg;
 	struct list_head *p;
-	emu10k1_memblk_t *q;
+	struct snd_emu10k1_memblk *q;
 
 	/* calculate the expected size of empty region */
 	if ((p = blk->mapped_link.prev) != &emu->mapped_link_head) {
@@ -197,11 +197,11 @@
  *
  * unlike synth_alloc the memory block is aligned to the page start
  */
-static emu10k1_memblk_t *
-search_empty(emu10k1_t *emu, int size)
+static struct snd_emu10k1_memblk *
+search_empty(struct snd_emu10k1 *emu, int size)
 {
 	struct list_head *p;
-	emu10k1_memblk_t *blk;
+	struct snd_emu10k1_memblk *blk;
 	int page, psize;
 
 	psize = get_aligned_page(size + PAGE_SIZE -1);
@@ -217,7 +217,7 @@
 
 __found_pages:
 	/* create a new memory block */
-	blk = (emu10k1_memblk_t *)__snd_util_memblk_new(emu->memhdr, psize << PAGE_SHIFT, p->prev);
+	blk = (struct snd_emu10k1_memblk *)__snd_util_memblk_new(emu->memhdr, psize << PAGE_SHIFT, p->prev);
 	if (blk == NULL)
 		return NULL;
 	blk->mem.offset = aligned_page_offset(page); /* set aligned offset */
@@ -229,7 +229,7 @@
 /*
  * check if the given pointer is valid for pages
  */
-static int is_valid_page(emu10k1_t *emu, dma_addr_t addr)
+static int is_valid_page(struct snd_emu10k1 *emu, dma_addr_t addr)
 {
 	if (addr & ~emu->dma_mask) {
 		snd_printk(KERN_ERR "max memory size is 0x%lx (addr = 0x%lx)!!\n", emu->dma_mask, (unsigned long)addr);
@@ -248,12 +248,12 @@
  * if no empty pages are found, tries to release unsed memory blocks
  * and retry the mapping.
  */
-int snd_emu10k1_memblk_map(emu10k1_t *emu, emu10k1_memblk_t *blk)
+int snd_emu10k1_memblk_map(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
 {
 	int err;
 	int size;
 	struct list_head *p, *nextp;
-	emu10k1_memblk_t *deleted;
+	struct snd_emu10k1_memblk *deleted;
 	unsigned long flags;
 
 	spin_lock_irqsave(&emu->memblk_lock, flags);
@@ -288,13 +288,13 @@
 /*
  * page allocation for DMA
  */
-snd_util_memblk_t *
-snd_emu10k1_alloc_pages(emu10k1_t *emu, snd_pcm_substream_t *substream)
+struct snd_util_memblk *
+snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
-	snd_util_memhdr_t *hdr;
-	emu10k1_memblk_t *blk;
+	struct snd_util_memhdr *hdr;
+	struct snd_emu10k1_memblk *blk;
 	int page, err, idx;
 
 	snd_assert(emu, return NULL);
@@ -336,19 +336,19 @@
 	blk->map_locked = 1; /* do not unmap this block! */
 	err = snd_emu10k1_memblk_map(emu, blk);
 	if (err < 0) {
-		__snd_util_mem_free(hdr, (snd_util_memblk_t *)blk);
+		__snd_util_mem_free(hdr, (struct snd_util_memblk *)blk);
 		up(&hdr->block_mutex);
 		return NULL;
 	}
 	up(&hdr->block_mutex);
-	return (snd_util_memblk_t *)blk;
+	return (struct snd_util_memblk *)blk;
 }
 
 
 /*
  * release DMA buffer from page table
  */
-int snd_emu10k1_free_pages(emu10k1_t *emu, snd_util_memblk_t *blk)
+int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk)
 {
 	snd_assert(emu && blk, return -EINVAL);
 	return snd_emu10k1_synth_free(emu, blk);
@@ -363,26 +363,26 @@
 /*
  * allocate a synth sample area
  */
-snd_util_memblk_t *
-snd_emu10k1_synth_alloc(emu10k1_t *hw, unsigned int size)
+struct snd_util_memblk *
+snd_emu10k1_synth_alloc(struct snd_emu10k1 *hw, unsigned int size)
 {
-	emu10k1_memblk_t *blk;
-	snd_util_memhdr_t *hdr = hw->memhdr; 
+	struct snd_emu10k1_memblk *blk;
+	struct snd_util_memhdr *hdr = hw->memhdr; 
 
 	down(&hdr->block_mutex);
-	blk = (emu10k1_memblk_t *)__snd_util_mem_alloc(hdr, size);
+	blk = (struct snd_emu10k1_memblk *)__snd_util_mem_alloc(hdr, size);
 	if (blk == NULL) {
 		up(&hdr->block_mutex);
 		return NULL;
 	}
 	if (synth_alloc_pages(hw, blk)) {
-		__snd_util_mem_free(hdr, (snd_util_memblk_t *)blk);
+		__snd_util_mem_free(hdr, (struct snd_util_memblk *)blk);
 		up(&hdr->block_mutex);
 		return NULL;
 	}
 	snd_emu10k1_memblk_map(hw, blk);
 	up(&hdr->block_mutex);
-	return (snd_util_memblk_t *)blk;
+	return (struct snd_util_memblk *)blk;
 }
 
 
@@ -390,10 +390,10 @@
  * free a synth sample area
  */
 int
-snd_emu10k1_synth_free(emu10k1_t *emu, snd_util_memblk_t *memblk)
+snd_emu10k1_synth_free(struct snd_emu10k1 *emu, struct snd_util_memblk *memblk)
 {
-	snd_util_memhdr_t *hdr = emu->memhdr; 
-	emu10k1_memblk_t *blk = (emu10k1_memblk_t *)memblk;
+	struct snd_util_memhdr *hdr = emu->memhdr; 
+	struct snd_emu10k1_memblk *blk = (struct snd_emu10k1_memblk *)memblk;
 	unsigned long flags;
 
 	down(&hdr->block_mutex);
@@ -409,10 +409,12 @@
 
 
 /* check new allocation range */
-static void get_single_page_range(snd_util_memhdr_t *hdr, emu10k1_memblk_t *blk, int *first_page_ret, int *last_page_ret)
+static void get_single_page_range(struct snd_util_memhdr *hdr,
+				  struct snd_emu10k1_memblk *blk,
+				  int *first_page_ret, int *last_page_ret)
 {
 	struct list_head *p;
-	emu10k1_memblk_t *q;
+	struct snd_emu10k1_memblk *q;
 	int first_page, last_page;
 	first_page = blk->first_page;
 	if ((p = blk->mem.list.prev) != &hdr->block) {
@@ -433,7 +435,7 @@
 /*
  * allocate kernel pages
  */
-static int synth_alloc_pages(emu10k1_t *emu, emu10k1_memblk_t *blk)
+static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
 {
 	int page, first_page, last_page;
 	struct snd_dma_buffer dmab;
@@ -472,7 +474,7 @@
 /*
  * free pages
  */
-static int synth_free_pages(emu10k1_t *emu, emu10k1_memblk_t *blk)
+static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
 {
 	int page, first_page, last_page;
 	struct snd_dma_buffer dmab;
@@ -495,7 +497,7 @@
 }
 
 /* calculate buffer pointer from offset address */
-static inline void *offset_ptr(emu10k1_t *emu, int page, int offset)
+static inline void *offset_ptr(struct snd_emu10k1 *emu, int page, int offset)
 {
 	char *ptr;
 	snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL);
@@ -511,11 +513,12 @@
 /*
  * bzero(blk + offset, size)
  */
-int snd_emu10k1_synth_bzero(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, int size)
+int snd_emu10k1_synth_bzero(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
+			    int offset, int size)
 {
 	int page, nextofs, end_offset, temp, temp1;
 	void *ptr;
-	emu10k1_memblk_t *p = (emu10k1_memblk_t *)blk;
+	struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk;
 
 	offset += blk->offset & (PAGE_SIZE - 1);
 	end_offset = offset + size;
@@ -538,11 +541,12 @@
 /*
  * copy_from_user(blk + offset, data, size)
  */
-int snd_emu10k1_synth_copy_from_user(emu10k1_t *emu, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
+int snd_emu10k1_synth_copy_from_user(struct snd_emu10k1 *emu, struct snd_util_memblk *blk,
+				     int offset, const char __user *data, int size)
 {
 	int page, nextofs, end_offset, temp, temp1;
 	void *ptr;
-	emu10k1_memblk_t *p = (emu10k1_memblk_t *)blk;
+	struct snd_emu10k1_memblk *p = (struct snd_emu10k1_memblk *)blk;
 
 	offset += blk->offset & (PAGE_SIZE - 1);
 	end_offset = offset + size;
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index e27ebb9..9905651 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -93,6 +93,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -106,11 +107,11 @@
 #define PCM_FRONT_CHANNEL 0
 #define PCM_REAR_CHANNEL 1
 #define PCM_CENTER_LFE_CHANNEL 2
-#define PCM_UNKNOWN_CHANNEL 3
+#define PCM_SIDE_CHANNEL 3
 #define CONTROL_FRONT_CHANNEL 0
 #define CONTROL_REAR_CHANNEL 3
 #define CONTROL_CENTER_LFE_CHANNEL 1
-#define CONTROL_UNKNOWN_CHANNEL 2
+#define CONTROL_SIDE_CHANNEL 2
 
 /* Card IDs:
  * Class 0401: 1102:0004 (rev 04) Subsystem: 1102:2002 -> Audigy2 ZS 7.1 Model:SB0350
@@ -121,10 +122,11 @@
  */
 
  /* hardware definition */
-static snd_pcm_hardware_t snd_p16v_playback_hw = {
+static struct snd_pcm_hardware snd_p16v_playback_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | 
 				 SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_RESUME |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
 	.rates =		SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 
@@ -140,10 +142,11 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_p16v_capture_hw = {
+static struct snd_pcm_hardware snd_p16v_capture_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				 SNDRV_PCM_INFO_RESUME |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_S32_LE,
 	.rates =		SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100, 
@@ -159,9 +162,9 @@
 	.fifo_size =		0,
 };
 
-static void snd_p16v_pcm_free_substream(snd_pcm_runtime_t *runtime)
+static void snd_p16v_pcm_free_substream(struct snd_pcm_runtime *runtime)
 {
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
   
 	if (epcm) {
         	//snd_printk("epcm free: %p\n", epcm);
@@ -170,12 +173,12 @@
 }
 
 /* open_playback callback */
-static int snd_p16v_pcm_open_playback_channel(snd_pcm_substream_t *substream, int channel_id)
+static int snd_p16v_pcm_open_playback_channel(struct snd_pcm_substream *substream, int channel_id)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-        emu10k1_voice_t *channel = &(emu->p16v_voices[channel_id]);
-	emu10k1_pcm_t *epcm;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+        struct snd_emu10k1_voice *channel = &(emu->p16v_voices[channel_id]);
+	struct snd_emu10k1_pcm *epcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
@@ -206,12 +209,12 @@
 	return 0;
 }
 /* open_capture callback */
-static int snd_p16v_pcm_open_capture_channel(snd_pcm_substream_t *substream, int channel_id)
+static int snd_p16v_pcm_open_capture_channel(struct snd_pcm_substream *substream, int channel_id)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	emu10k1_voice_t *channel = &(emu->p16v_capture_voice);
-	emu10k1_pcm_t *epcm;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_emu10k1_voice *channel = &(emu->p16v_capture_voice);
+	struct snd_emu10k1_pcm *epcm;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	epcm = kzalloc(sizeof(*epcm), GFP_KERNEL);
@@ -244,41 +247,41 @@
 
 
 /* close callback */
-static int snd_p16v_pcm_close_playback(snd_pcm_substream_t *substream)
+static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	//snd_pcm_runtime_t *runtime = substream->runtime;
-	//emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	//struct snd_pcm_runtime *runtime = substream->runtime;
+	//struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0;
 	/* FIXME: maybe zero others */
 	return 0;
 }
 
 /* close callback */
-static int snd_p16v_pcm_close_capture(snd_pcm_substream_t *substream)
+static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	//snd_pcm_runtime_t *runtime = substream->runtime;
-	//emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	//struct snd_pcm_runtime *runtime = substream->runtime;
+	//struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	emu->p16v_capture_voice.use=0;
 	/* FIXME: maybe zero others */
 	return 0;
 }
 
-static int snd_p16v_pcm_open_playback_front(snd_pcm_substream_t *substream)
+static int snd_p16v_pcm_open_playback_front(struct snd_pcm_substream *substream)
 {
 	return snd_p16v_pcm_open_playback_channel(substream, PCM_FRONT_CHANNEL);
 }
 
-static int snd_p16v_pcm_open_capture(snd_pcm_substream_t *substream)
+static int snd_p16v_pcm_open_capture(struct snd_pcm_substream *substream)
 {
 	// Only using channel 0 for now, but the card has 2 channels.
 	return snd_p16v_pcm_open_capture_channel(substream, 0);
 }
 
 /* hw_params callback */
-static int snd_p16v_pcm_hw_params_playback(snd_pcm_substream_t *substream,
-				      snd_pcm_hw_params_t * hw_params)
+static int snd_p16v_pcm_hw_params_playback(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *hw_params)
 {
 	int result;
 	result = snd_pcm_lib_malloc_pages(substream,
@@ -287,8 +290,8 @@
 }
 
 /* hw_params callback */
-static int snd_p16v_pcm_hw_params_capture(snd_pcm_substream_t *substream,
-				      snd_pcm_hw_params_t * hw_params)
+static int snd_p16v_pcm_hw_params_capture(struct snd_pcm_substream *substream,
+				      struct snd_pcm_hw_params *hw_params)
 {
 	int result;
 	result = snd_pcm_lib_malloc_pages(substream,
@@ -298,7 +301,7 @@
 
 
 /* hw_free callback */
-static int snd_p16v_pcm_hw_free_playback(snd_pcm_substream_t *substream)
+static int snd_p16v_pcm_hw_free_playback(struct snd_pcm_substream *substream)
 {
 	int result;
 	result = snd_pcm_lib_free_pages(substream);
@@ -306,7 +309,7 @@
 }
 
 /* hw_free callback */
-static int snd_p16v_pcm_hw_free_capture(snd_pcm_substream_t *substream)
+static int snd_p16v_pcm_hw_free_capture(struct snd_pcm_substream *substream)
 {
 	int result;
 	result = snd_pcm_lib_free_pages(substream);
@@ -315,10 +318,10 @@
 
 
 /* prepare playback callback */
-static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream)
+static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int channel = substream->pcm->device - emu->p16v_device_offset;
 	u32 *table_base = (u32 *)(emu->p16v_buffer.area+(8*16*channel));
 	u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
@@ -364,10 +367,10 @@
 }
 
 /* prepare capture callback */
-static int snd_p16v_pcm_prepare_capture(snd_pcm_substream_t *substream)
+static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int channel = substream->pcm->device - emu->p16v_device_offset;
 	u32 tmp;
 	//printk("prepare capture:channel_number=%d, rate=%d, format=0x%x, channels=%d, buffer_size=%ld, period_size=%ld, frames_to_bytes=%d\n",channel, runtime->rate, runtime->format, runtime->channels, runtime->buffer_size, runtime->period_size,  frames_to_bytes(runtime, 1));
@@ -398,7 +401,7 @@
 	return 0;
 }
 
-static void snd_p16v_intr_enable(emu10k1_t *emu, unsigned int intrenb)
+static void snd_p16v_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
 {
 	unsigned long flags;
 	unsigned int enable;
@@ -409,7 +412,7 @@
 	spin_unlock_irqrestore(&emu->emu_lock, flags);
 }
 
-static void snd_p16v_intr_disable(emu10k1_t *emu, unsigned int intrenb)
+static void snd_p16v_intr_disable(struct snd_emu10k1 *emu, unsigned int intrenb)
 {
 	unsigned long flags;
 	unsigned int disable;
@@ -421,16 +424,16 @@
 }
 
 /* trigger_playback callback */
-static int snd_p16v_pcm_trigger_playback(snd_pcm_substream_t *substream,
+static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
 				    int cmd)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime;
-	emu10k1_pcm_t *epcm;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime;
+	struct snd_emu10k1_pcm *epcm;
 	int channel;
 	int result = 0;
 	struct list_head *pos;
-        snd_pcm_substream_t *s;
+        struct snd_pcm_substream *s;
 	u32 basic = 0;
 	u32 inte = 0;
 	int running=0;
@@ -474,12 +477,12 @@
 }
 
 /* trigger_capture callback */
-static int snd_p16v_pcm_trigger_capture(snd_pcm_substream_t *substream,
+static int snd_p16v_pcm_trigger_capture(struct snd_pcm_substream *substream,
                                    int cmd)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	int channel = 0;
 	int result = 0;
 	u32 inte = INTE2_CAPTURE_CH_0_LOOP | INTE2_CAPTURE_CH_0_HALF_LOOP;
@@ -505,11 +508,11 @@
 
 /* pointer_playback callback */
 static snd_pcm_uframes_t
-snd_p16v_pcm_pointer_playback(snd_pcm_substream_t *substream)
+snd_p16v_pcm_pointer_playback(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	snd_pcm_uframes_t ptr, ptr1, ptr2,ptr3,ptr4 = 0;
 	int channel = substream->pcm->device - emu->p16v_device_offset;
 	if (!epcm->running)
@@ -530,11 +533,11 @@
 
 /* pointer_capture callback */
 static snd_pcm_uframes_t
-snd_p16v_pcm_pointer_capture(snd_pcm_substream_t *substream)
+snd_p16v_pcm_pointer_capture(struct snd_pcm_substream *substream)
 {
-	emu10k1_t *emu = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	emu10k1_pcm_t *epcm = runtime->private_data;
+	struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_emu10k1_pcm *epcm = runtime->private_data;
 	snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
 	int channel = 0;
 
@@ -554,7 +557,7 @@
 }
 
 /* operators */
-static snd_pcm_ops_t snd_p16v_playback_front_ops = {
+static struct snd_pcm_ops snd_p16v_playback_front_ops = {
 	.open =        snd_p16v_pcm_open_playback_front,
 	.close =       snd_p16v_pcm_close_playback,
 	.ioctl =       snd_pcm_lib_ioctl,
@@ -565,7 +568,7 @@
 	.pointer =     snd_p16v_pcm_pointer_playback,
 };
 
-static snd_pcm_ops_t snd_p16v_capture_ops = {
+static struct snd_pcm_ops snd_p16v_capture_ops = {
 	.open =        snd_p16v_pcm_open_capture,
 	.close =       snd_p16v_pcm_close_capture,
 	.ioctl =       snd_pcm_lib_ioctl,
@@ -577,7 +580,7 @@
 };
 
 
-int snd_p16v_free(emu10k1_t *chip)
+int snd_p16v_free(struct snd_emu10k1 *chip)
 {
 	// release the data
 	if (chip->p16v_buffer.area) {
@@ -587,18 +590,10 @@
 	return 0;
 }
 
-static void snd_p16v_pcm_free(snd_pcm_t *pcm)
+int __devinit snd_p16v_pcm(struct snd_emu10k1 *emu, int device, struct snd_pcm **rpcm)
 {
-	emu10k1_t *emu = pcm->private_data;
-	//snd_printk("snd_p16v_pcm_free pcm: called\n");
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-	emu->pcm = NULL;
-}
-
-int snd_p16v_pcm(emu10k1_t *emu, int device, snd_pcm_t **rpcm)
-{
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *substream;
 	int err;
         int capture=1;
   
@@ -611,7 +606,6 @@
 		return err;
   
 	pcm->private_data = emu;
-	pcm->private_free = snd_p16v_pcm_free;
 	// Single playback 8 channel device.
 	// Single capture 2 channel device.
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_p16v_playback_front_ops);
@@ -620,7 +614,7 @@
 	pcm->info_flags = 0;
 	pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
 	strcpy(pcm->name, "p16v");
-	emu->pcm = pcm;
+	emu->pcm_p16v = pcm;
 
 	for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 
 	    substream; 
@@ -650,7 +644,8 @@
 	return 0;
 }
 
-static int snd_p16v_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_p16v_volume_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
         uinfo->count = 2;
@@ -659,241 +654,57 @@
         return 0;
 }
 
-static int snd_p16v_volume_get(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
+static int snd_p16v_volume_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-        emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-        u32 value;
+        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	int high_low = (kcontrol->private_value >> 8) & 0xff;
+	int reg = kcontrol->private_value & 0xff;
+	u32 value;
 
-        value = snd_emu10k1_ptr20_read(emu, reg, high_low);
-	if (high_low == 1) {
-        	ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
-        	ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
+	value = snd_emu10k1_ptr20_read(emu, reg, high_low);
+	if (high_low) {
+		ucontrol->value.integer.value[0] = 0xff - ((value >> 24) & 0xff); /* Left */
+		ucontrol->value.integer.value[1] = 0xff - ((value >> 16) & 0xff); /* Right */
 	} else {
-        	ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
-        	ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
+		ucontrol->value.integer.value[0] = 0xff - ((value >> 8) & 0xff); /* Left */
+		ucontrol->value.integer.value[1] = 0xff - ((value >> 0) & 0xff); /* Right */
 	}
-        return 0;
+	return 0;
 }
 
-static int snd_p16v_volume_get_spdif_front(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
+static int snd_p16v_volume_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	int high_low = 0;
-	int reg = PLAYBACK_VOLUME_MIXER7;
-        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
-}
+        struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
+	int high_low = (kcontrol->private_value >> 8) & 0xff;
+	int reg = kcontrol->private_value & 0xff;
+        u32 value, oval;
 
-static int snd_p16v_volume_get_spdif_center_lfe(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 1;
-	int reg = PLAYBACK_VOLUME_MIXER7;
-        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
-}
-static int snd_p16v_volume_get_spdif_unknown(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 0;
-	int reg = PLAYBACK_VOLUME_MIXER8;
-        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
-}
-static int snd_p16v_volume_get_spdif_rear(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 1;
-	int reg = PLAYBACK_VOLUME_MIXER8;
-        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_get_analog_front(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 0;
-	int reg = PLAYBACK_VOLUME_MIXER9;
-        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_get_analog_center_lfe(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 1;
-	int reg = PLAYBACK_VOLUME_MIXER9;
-        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
-}
-static int snd_p16v_volume_get_analog_rear(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 1;
-	int reg = PLAYBACK_VOLUME_MIXER10;
-        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_get_analog_unknown(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 0;
-	int reg = PLAYBACK_VOLUME_MIXER10;
-        return snd_p16v_volume_get(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_put(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol, int reg, int high_low)
-{
-        emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
-        u32 value;
-        value = snd_emu10k1_ptr20_read(emu, reg, 0);
-        //value = value & 0xffff;
+	oval = value = snd_emu10k1_ptr20_read(emu, reg, 0);
 	if (high_low == 1) {
 		value &= 0xffff;
-	        value = value | ((0xff - ucontrol->value.integer.value[0]) << 24) | ((0xff - ucontrol->value.integer.value[1]) << 16);
+		value |= ((0xff - ucontrol->value.integer.value[0]) << 24) |
+			((0xff - ucontrol->value.integer.value[1]) << 16);
 	} else {
 		value &= 0xffff0000;
-        	value = value | ((0xff - ucontrol->value.integer.value[0]) << 8) | ((0xff - ucontrol->value.integer.value[1]) );
+		value |= ((0xff - ucontrol->value.integer.value[0]) << 8) |
+			((0xff - ucontrol->value.integer.value[1]) );
 	}
-        	snd_emu10k1_ptr20_write(emu, reg, 0, value);
-        return 1;
+	if (value != oval) {
+		snd_emu10k1_ptr20_write(emu, reg, 0, value);
+		return 1;
+	}
+	return 0;
 }
 
-static int snd_p16v_volume_put_spdif_front(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
+static int snd_p16v_capture_source_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
 {
-	int high_low = 0;
-	int reg = PLAYBACK_VOLUME_MIXER7;
-        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_put_spdif_center_lfe(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 1;
-	int reg = PLAYBACK_VOLUME_MIXER7;
-        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_put_spdif_unknown(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 0;
-	int reg = PLAYBACK_VOLUME_MIXER8;
-        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_put_spdif_rear(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 1;
-	int reg = PLAYBACK_VOLUME_MIXER8;
-        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_put_analog_front(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 0;
-	int reg = PLAYBACK_VOLUME_MIXER9;
-        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_put_analog_center_lfe(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 1;
-	int reg = PLAYBACK_VOLUME_MIXER9;
-        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_put_analog_rear(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 1;
-	int reg = PLAYBACK_VOLUME_MIXER10;
-        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
-}
-
-static int snd_p16v_volume_put_analog_unknown(snd_kcontrol_t * kcontrol,
-                                       snd_ctl_elem_value_t * ucontrol)
-{
-	int high_low = 0;
-	int reg = PLAYBACK_VOLUME_MIXER10;
-        return snd_p16v_volume_put(kcontrol, ucontrol, reg, high_low);
-}
-
-static snd_kcontrol_new_t snd_p16v_volume_control_analog_front =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD Analog Front Playback Volume",
-        .info =         snd_p16v_volume_info,
-        .get =          snd_p16v_volume_get_analog_front,
-        .put =          snd_p16v_volume_put_analog_front
-};
-
-static snd_kcontrol_new_t snd_p16v_volume_control_analog_center_lfe =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD Analog Center/LFE Playback Volume",
-        .info =         snd_p16v_volume_info,
-        .get =          snd_p16v_volume_get_analog_center_lfe,
-        .put =          snd_p16v_volume_put_analog_center_lfe
-};
-
-static snd_kcontrol_new_t snd_p16v_volume_control_analog_unknown =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD Analog Unknown Playback Volume",
-        .info =         snd_p16v_volume_info,
-        .get =          snd_p16v_volume_get_analog_unknown,
-        .put =          snd_p16v_volume_put_analog_unknown
-};
-
-static snd_kcontrol_new_t snd_p16v_volume_control_analog_rear =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD Analog Rear Playback Volume",
-        .info =         snd_p16v_volume_info,
-        .get =          snd_p16v_volume_get_analog_rear,
-        .put =          snd_p16v_volume_put_analog_rear
-};
-
-static snd_kcontrol_new_t snd_p16v_volume_control_spdif_front =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD SPDIF Front Playback Volume",
-        .info =         snd_p16v_volume_info,
-        .get =          snd_p16v_volume_get_spdif_front,
-        .put =          snd_p16v_volume_put_spdif_front
-};
-
-static snd_kcontrol_new_t snd_p16v_volume_control_spdif_center_lfe =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD SPDIF Center/LFE Playback Volume",
-        .info =         snd_p16v_volume_info,
-        .get =          snd_p16v_volume_get_spdif_center_lfe,
-        .put =          snd_p16v_volume_put_spdif_center_lfe
-};
-
-static snd_kcontrol_new_t snd_p16v_volume_control_spdif_unknown =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD SPDIF Unknown Playback Volume",
-        .info =         snd_p16v_volume_info,
-        .get =          snd_p16v_volume_get_spdif_unknown,
-        .put =          snd_p16v_volume_put_spdif_unknown
-};
-
-static snd_kcontrol_new_t snd_p16v_volume_control_spdif_rear =
-{
-        .iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
-        .name =         "HD SPDIF Rear Playback Volume",
-        .info =         snd_p16v_volume_info,
-        .get =          snd_p16v_volume_get_spdif_rear,
-        .put =          snd_p16v_volume_put_spdif_rear
-};
-
-static int snd_p16v_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	static char *texts[8] = { "SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S", "CDIF", "FX", "AC97" };
+	static char *texts[8] = {
+		"SPDIF", "I2S", "SRC48", "SRCMulti_SPDIF", "SRCMulti_I2S",
+		"CDIF", "FX", "AC97"
+	};
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -904,19 +715,19 @@
 	return 0;
 }
 
-static int snd_p16v_capture_source_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_p16v_capture_source_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = emu->p16v_capture_source;
 	return 0;
 }
 
-static int snd_p16v_capture_source_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_p16v_capture_source_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change = 0;
 	u32 mask;
@@ -933,16 +744,8 @@
         return change;
 }
 
-static snd_kcontrol_new_t snd_p16v_capture_source __devinitdata =
-{
-	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name =		"HD source Capture",
-	.info =		snd_p16v_capture_source_info,
-	.get =		snd_p16v_capture_source_get,
-	.put =		snd_p16v_capture_source_put
-};
-
-static int snd_p16v_capture_channel_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_p16v_capture_channel_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = { "0", "1", "2", "3",  };
 
@@ -955,19 +758,19 @@
 	return 0;
 }
 
-static int snd_p16v_capture_channel_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_p16v_capture_channel_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = emu->p16v_capture_channel;
 	return 0;
 }
 
-static int snd_p16v_capture_channel_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_p16v_capture_channel_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	emu10k1_t *emu = snd_kcontrol_chip(kcontrol);
+	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change = 0;
 	u32 tmp;
@@ -982,60 +785,89 @@
         return change;
 }
 
-static snd_kcontrol_new_t snd_p16v_capture_channel __devinitdata =
-{
-	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name =		"HD channel Capture",
-	.info =		snd_p16v_capture_channel_info,
-	.get =		snd_p16v_capture_channel_get,
-	.put =		snd_p16v_capture_channel_put
+#define P16V_VOL(xname,xreg,xhl) { \
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
+	.info = snd_p16v_volume_info, \
+	.get = snd_p16v_volume_get, \
+	.put = snd_p16v_volume_put, \
+	.private_value = ((xreg) | ((xhl) << 8)) \
+}
+
+static struct snd_kcontrol_new p16v_mixer_controls[] __devinitdata = {
+	P16V_VOL("HD Analog Front Playback Volume", PLAYBACK_VOLUME_MIXER9, 0),
+	P16V_VOL("HD Analog Rear Playback Volume", PLAYBACK_VOLUME_MIXER10, 1),
+	P16V_VOL("HD Analog Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER9, 1),
+	P16V_VOL("HD Analog Side Playback Volume", PLAYBACK_VOLUME_MIXER10, 0),
+	P16V_VOL("HD SPDIF Front Playback Volume", PLAYBACK_VOLUME_MIXER7, 0),
+	P16V_VOL("HD SPDIF Rear Playback Volume", PLAYBACK_VOLUME_MIXER8, 1),
+	P16V_VOL("HD SPDIF Center/LFE Playback Volume", PLAYBACK_VOLUME_MIXER7, 1),
+	P16V_VOL("HD SPDIF Side Playback Volume", PLAYBACK_VOLUME_MIXER8, 0),
+	{
+		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name =		"HD source Capture",
+		.info =		snd_p16v_capture_source_info,
+		.get =		snd_p16v_capture_source_get,
+		.put =		snd_p16v_capture_source_put
+	},
+	{
+		.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name =		"HD channel Capture",
+		.info =		snd_p16v_capture_channel_info,
+		.get =		snd_p16v_capture_channel_get,
+		.put =		snd_p16v_capture_channel_put
+	},
 };
 
-int snd_p16v_mixer(emu10k1_t *emu)
+
+int __devinit snd_p16v_mixer(struct snd_emu10k1 *emu)
 {
-        int err;
-        snd_kcontrol_t *kctl;
-        snd_card_t *card = emu->card;
-        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_front, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_rear, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_center_lfe, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_analog_unknown, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_front, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_rear, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_center_lfe, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_p16v_volume_control_spdif_unknown, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_p16v_capture_source, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
-        if ((kctl = snd_ctl_new1(&snd_p16v_capture_channel, emu)) == NULL)
-                return -ENOMEM;
-        if ((err = snd_ctl_add(card, kctl)))
-                return err;
+	int i, err;
+        struct snd_card *card = emu->card;
+
+	for (i = 0; i < ARRAY_SIZE(p16v_mixer_controls); i++) {
+		if ((err = snd_ctl_add(card, snd_ctl_new1(&p16v_mixer_controls[i],
+							  emu))) < 0)
+			return err;
+	}
         return 0;
 }
 
+#ifdef CONFIG_PM
+
+#define NUM_CHS	1	/* up to 4, but only first channel is used */
+
+int __devinit snd_p16v_alloc_pm_buffer(struct snd_emu10k1 *emu)
+{
+	emu->p16v_saved = vmalloc(NUM_CHS * 4 * 0x80);
+	if (! emu->p16v_saved)
+		return -ENOMEM;
+	return 0;
+}
+
+void snd_p16v_free_pm_buffer(struct snd_emu10k1 *emu)
+{
+	vfree(emu->p16v_saved);
+}
+
+void snd_p16v_suspend(struct snd_emu10k1 *emu)
+{
+	int i, ch;
+	unsigned int *val;
+
+	val = emu->p16v_saved;
+	for (ch = 0; ch < NUM_CHS; ch++)
+		for (i = 0; i < 0x80; i++, val++)
+			*val = snd_emu10k1_ptr20_read(emu, i, ch);
+}
+
+void snd_p16v_resume(struct snd_emu10k1 *emu)
+{
+	int i, ch;
+	unsigned int *val;
+
+	val = emu->p16v_saved;
+	for (ch = 0; ch < NUM_CHS; ch++)
+		for (i = 0; i < 0x80; i++, val++)
+			snd_emu10k1_ptr20_write(emu, i, ch, *val);
+}
+#endif
diff --git a/sound/pci/emu10k1/timer.c b/sound/pci/emu10k1/timer.c
index d2e3646..6295b2d 100644
--- a/sound/pci/emu10k1/timer.c
+++ b/sound/pci/emu10k1/timer.c
@@ -30,9 +30,9 @@
 #include <sound/core.h>
 #include <sound/emu10k1.h>
 
-static int snd_emu10k1_timer_start(snd_timer_t *timer)
+static int snd_emu10k1_timer_start(struct snd_timer *timer)
 {
-	emu10k1_t *emu;
+	struct snd_emu10k1 *emu;
 	unsigned long flags;
 	unsigned int delay;
 
@@ -47,9 +47,9 @@
 	return 0;
 }
 
-static int snd_emu10k1_timer_stop(snd_timer_t *timer)
+static int snd_emu10k1_timer_stop(struct snd_timer *timer)
 {
-	emu10k1_t *emu;
+	struct snd_emu10k1 *emu;
 	unsigned long flags;
 
 	emu = snd_timer_chip(timer);
@@ -59,7 +59,7 @@
 	return 0;
 }
 
-static int snd_emu10k1_timer_precise_resolution(snd_timer_t *timer,
+static int snd_emu10k1_timer_precise_resolution(struct snd_timer *timer,
 					       unsigned long *num, unsigned long *den)
 {
 	*num = 1;
@@ -67,7 +67,7 @@
 	return 0;
 }
 
-static struct _snd_timer_hardware snd_emu10k1_timer_hw = {
+static struct snd_timer_hardware snd_emu10k1_timer_hw = {
 	.flags = SNDRV_TIMER_HW_AUTO,
 	.resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
 	.ticks = 1024,
@@ -76,10 +76,10 @@
 	.precise_resolution = snd_emu10k1_timer_precise_resolution,
 };
 
-int __devinit snd_emu10k1_timer(emu10k1_t *emu, int device)
+int __devinit snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
 {
-	snd_timer_t *timer = NULL;
-	snd_timer_id_t tid;
+	struct snd_timer *timer = NULL;
+	struct snd_timer_id tid;
 	int err;
 
 	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
diff --git a/sound/pci/emu10k1/tina2.h b/sound/pci/emu10k1/tina2.h
new file mode 100644
index 0000000..5c43abf
--- /dev/null
+++ b/sound/pci/emu10k1/tina2.h
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk>
+ *  Driver p16v chips
+ *  Version: 0.21
+ *
+ *
+ *  This code was initally based on code from ALSA's emu10k1x.c which is:
+ *  Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+/********************************************************************************************************/
+/* Audigy2 Tina2 (notebook) pointer-offset register set, accessed through the PTR2 and DATA2 registers  */
+/********************************************************************************************************/
+
+#define TINA2_VOLUME	0x71	/* Attenuate playback volume to prevent distortion. */
+				/* The windows driver does not use this register,
+				 * so it must use some other attenuation method.
+				 * Without this, the output is 12dB too loud,
+				 * resulting in distortion.
+				 */
+
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
index d251d34..56ffb7d 100644
--- a/sound/pci/emu10k1/voice.c
+++ b/sound/pci/emu10k1/voice.c
@@ -45,9 +45,10 @@
  *							--rlrevell
  */
 
-static int voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int number, emu10k1_voice_t **rvoice)
+static int voice_alloc(struct snd_emu10k1 *emu, int type, int number,
+		       struct snd_emu10k1_voice **rvoice)
 {
-	emu10k1_voice_t *voice;
+	struct snd_emu10k1_voice *voice;
 	int i, j, k, first_voice, last_voice, skip;
 
 	*rvoice = NULL;
@@ -105,7 +106,8 @@
 	return 0;
 }
 
-int snd_emu10k1_voice_alloc(emu10k1_t *emu, emu10k1_voice_type_t type, int number, emu10k1_voice_t **rvoice)
+int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number,
+			    struct snd_emu10k1_voice **rvoice)
 {
 	unsigned long flags;
 	int result;
@@ -123,7 +125,7 @@
 		if (emu->get_synth_voice) {
 			result = emu->get_synth_voice(emu);
 			if (result >= 0) {
-				emu10k1_voice_t *pvoice = &emu->voices[result];
+				struct snd_emu10k1_voice *pvoice = &emu->voices[result];
 				pvoice->interrupt = NULL;
 				pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0;
 				pvoice->epcm = NULL;
@@ -137,7 +139,8 @@
 	return result;
 }
 
-int snd_emu10k1_voice_free(emu10k1_t *emu, emu10k1_voice_t *pvoice)
+int snd_emu10k1_voice_free(struct snd_emu10k1 *emu,
+			   struct snd_emu10k1_voice *pvoice)
 {
 	unsigned long flags;
 
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 2daa575..55aaf11 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -19,6 +19,13 @@
  *
  */
 
+/* Power-Management-Code ( CONFIG_PM )
+ * for ens1371 only ( FIXME )
+ * derived from cs4281.c, atiixp.c and via82xx.c
+ * using http://www.alsa-project.org/~iwai/writing-an-alsa-driver/c1540.htm
+ * by Kurt J. Bosch
+ */
+
 #include <sound/driver.h>
 #include <asm/io.h>
 #include <linux/delay.h>
@@ -83,6 +90,10 @@
 static int joystick[SNDRV_CARDS];
 #endif
 #endif
+#ifdef CHIP1371
+static int spdif[SNDRV_CARDS];
+static int lineio[SNDRV_CARDS];
+#endif
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for Ensoniq AudioPCI soundcard.");
@@ -99,6 +110,12 @@
 MODULE_PARM_DESC(joystick, "Enable joystick.");
 #endif
 #endif /* SUPPORT_JOYSTICK */
+#ifdef CHIP1371
+module_param_array(spdif, int, NULL, 0444);
+MODULE_PARM_DESC(spdif, "S/PDIF output (-1 = none, 0 = auto, 1 = force).");
+module_param_array(lineio, int, NULL, 0444);
+MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force).");
+#endif
 
 /* ES1371 chip ID */
 /* This is a little confusing because all ES1371 compatible chips have the
@@ -360,9 +377,7 @@
 
  */
 
-typedef struct _snd_ensoniq ensoniq_t;
-
-struct _snd_ensoniq {
+struct ensoniq {
 	spinlock_t reg_lock;
 	struct semaphore src_mutex;
 
@@ -385,12 +400,12 @@
 	union {
 #ifdef CHIP1371
 		struct {
-			ac97_t *ac97;
+			struct snd_ac97 *ac97;
 		} es1371;
 #else
 		struct {
 			int pclkdiv_lock;
-			ak4531_t *ak4531;
+			struct snd_ak4531 *ak4531;
 		} es1370;
 #endif
 	} u;
@@ -398,21 +413,21 @@
 	struct pci_dev *pci;
 	unsigned short subsystem_vendor_id;
 	unsigned short subsystem_device_id;
-	snd_card_t *card;
-	snd_pcm_t *pcm1;	/* DAC1/ADC PCM */
-	snd_pcm_t *pcm2;	/* DAC2 PCM */
-	snd_pcm_substream_t *playback1_substream;
-	snd_pcm_substream_t *playback2_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_card *card;
+	struct snd_pcm *pcm1;	/* DAC1/ADC PCM */
+	struct snd_pcm *pcm2;	/* DAC2 PCM */
+	struct snd_pcm_substream *playback1_substream;
+	struct snd_pcm_substream *playback2_substream;
+	struct snd_pcm_substream *capture_substream;
 	unsigned int p1_dma_size;
 	unsigned int p2_dma_size;
 	unsigned int c_dma_size;
 	unsigned int p1_period_size;
 	unsigned int p2_period_size;
 	unsigned int c_period_size;
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *midi_input;
-	snd_rawmidi_substream_t *midi_output;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *midi_input;
+	struct snd_rawmidi_substream *midi_output;
 
 	unsigned int spdif;
 	unsigned int spdif_default;
@@ -452,39 +467,39 @@
 #ifdef CHIP1370
 static unsigned int snd_es1370_fixed_rates[] =
 	{5512, 11025, 22050, 44100};
-static snd_pcm_hw_constraint_list_t snd_es1370_hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list snd_es1370_hw_constraints_rates = {
 	.count = 4, 
 	.list = snd_es1370_fixed_rates,
 	.mask = 0,
 };
-static ratnum_t es1370_clock = {
+static struct snd_ratnum es1370_clock = {
 	.num = ES_1370_SRCLOCK,
 	.den_min = 29, 
 	.den_max = 353,
 	.den_step = 1,
 };
-static snd_pcm_hw_constraint_ratnums_t snd_es1370_hw_constraints_clock = {
+static struct snd_pcm_hw_constraint_ratnums snd_es1370_hw_constraints_clock = {
 	.nrats = 1,
 	.rats = &es1370_clock,
 };
 #else
-static ratden_t es1371_dac_clock = {
+static struct snd_ratden es1371_dac_clock = {
 	.num_min = 3000 * (1 << 15),
 	.num_max = 48000 * (1 << 15),
 	.num_step = 3000,
 	.den = 1 << 15,
 };
-static snd_pcm_hw_constraint_ratdens_t snd_es1371_hw_constraints_dac_clock = {
+static struct snd_pcm_hw_constraint_ratdens snd_es1371_hw_constraints_dac_clock = {
 	.nrats = 1,
 	.rats = &es1371_dac_clock,
 };
-static ratnum_t es1371_adc_clock = {
+static struct snd_ratnum es1371_adc_clock = {
 	.num = 48000 << 15,
 	.den_min = 32768, 
 	.den_max = 393216,
 	.den_step = 1,
 };
-static snd_pcm_hw_constraint_ratnums_t snd_es1371_hw_constraints_adc_clock = {
+static struct snd_pcm_hw_constraint_ratnums snd_es1371_hw_constraints_adc_clock = {
 	.nrats = 1,
 	.rats = &es1371_adc_clock,
 };
@@ -498,7 +513,7 @@
 
 #ifdef CHIP1371
 
-static unsigned int snd_es1371_wait_src_ready(ensoniq_t * ensoniq)
+static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq)
 {
 	unsigned int t, r = 0;
 
@@ -508,11 +523,12 @@
 			return r;
 		cond_resched();
 	}
-	snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r);
+	snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n",
+		   ES_REG(ensoniq, 1371_SMPRATE), r);
 	return 0;
 }
 
-static unsigned int snd_es1371_src_read(ensoniq_t * ensoniq, unsigned short reg)
+static unsigned int snd_es1371_src_read(struct ensoniq * ensoniq, unsigned short reg)
 {
 	unsigned int temp, i, orig, r;
 
@@ -546,7 +562,7 @@
 	return temp;
 }
 
-static void snd_es1371_src_write(ensoniq_t * ensoniq,
+static void snd_es1371_src_write(struct ensoniq * ensoniq,
 				 unsigned short reg, unsigned short data)
 {
 	unsigned int r;
@@ -562,14 +578,15 @@
 
 #ifdef CHIP1370
 
-static void snd_es1370_codec_write(ak4531_t *ak4531,
+static void snd_es1370_codec_write(struct snd_ak4531 *ak4531,
 				   unsigned short reg, unsigned short val)
 {
-	ensoniq_t *ensoniq = ak4531->private_data;
+	struct ensoniq *ensoniq = ak4531->private_data;
 	unsigned long end_time = jiffies + HZ / 10;
 
 #if 0
-	printk("CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x\n", reg, val, ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
+	printk("CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x\n",
+	       reg, val, ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));
 #endif
 	do {
 		if (!(inl(ES_REG(ensoniq, STATUS)) & ES_1370_CSTAT)) {
@@ -578,17 +595,18 @@
 		}
 		schedule_timeout_uninterruptible(1);
 	} while (time_after(end_time, jiffies));
-	snd_printk(KERN_ERR "codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));
+	snd_printk(KERN_ERR "codec write timeout, status = 0x%x\n",
+		   inl(ES_REG(ensoniq, STATUS)));
 }
 
 #endif /* CHIP1370 */
 
 #ifdef CHIP1371
 
-static void snd_es1371_codec_write(ac97_t *ac97,
+static void snd_es1371_codec_write(struct snd_ac97 *ac97,
 				   unsigned short reg, unsigned short val)
 {
-	ensoniq_t *ensoniq = ac97->private_data;
+	struct ensoniq *ensoniq = ac97->private_data;
 	unsigned int t, x;
 
 	down(&ensoniq->src_mutex);
@@ -602,12 +620,14 @@
 			/* wait for not busy (state 0) first to avoid
 			   transition states */
 			for (t = 0; t < POLL_COUNT; t++) {
-				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00000000)
+				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
+				    0x00000000)
 					break;
 			}
 			/* wait for a SAFE time to write addr/data and then do it, dammit */
 			for (t = 0; t < POLL_COUNT; t++) {
-				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00010000)
+				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
+				    0x00010000)
 					break;
 			}
 			outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC));
@@ -619,13 +639,14 @@
 		}
 	}
 	up(&ensoniq->src_mutex);
-	snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+	snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n",
+		   ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
 }
 
-static unsigned short snd_es1371_codec_read(ac97_t *ac97,
+static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97,
 					    unsigned short reg)
 {
-	ensoniq_t *ensoniq = ac97->private_data;
+	struct ensoniq *ensoniq = ac97->private_data;
 	unsigned int t, x, fail = 0;
 
       __again:
@@ -640,12 +661,14 @@
 			/* wait for not busy (state 0) first to avoid
 			   transition states */
 			for (t = 0; t < POLL_COUNT; t++) {
-				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00000000)
+				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
+				    0x00000000)
 					break;
 			}
 			/* wait for a SAFE time to write addr/data and then do it, dammit */
 			for (t = 0; t < POLL_COUNT; t++) {
-				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00010000)
+				if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) ==
+				    0x00010000)
 					break;
 			}
 			outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC));
@@ -666,18 +689,22 @@
 			}
 			up(&ensoniq->src_mutex);
 			if (++fail > 10) {
-				snd_printk(KERN_ERR "codec read timeout (final) at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC)));
+				snd_printk(KERN_ERR "codec read timeout (final) "
+					   "at 0x%lx, reg = 0x%x [0x%x]\n",
+					   ES_REG(ensoniq, 1371_CODEC), reg,
+					   inl(ES_REG(ensoniq, 1371_CODEC)));
 				return 0;
 			}
 			goto __again;
 		}
 	}
 	up(&ensoniq->src_mutex);
-	snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
+	snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n",
+		   ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));
 	return 0;
 }
 
-static void snd_es1371_codec_wait(ac97_t *ac97)
+static void snd_es1371_codec_wait(struct snd_ac97 *ac97)
 {
 	msleep(750);
 	snd_es1371_codec_read(ac97, AC97_RESET);
@@ -686,7 +713,7 @@
 	msleep(50);
 }
 
-static void snd_es1371_adc_rate(ensoniq_t * ensoniq, unsigned int rate)
+static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate)
 {
 	unsigned int n, truncm, freq, result;
 
@@ -709,60 +736,70 @@
 				0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
 	}
 	snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,
-			     (snd_es1371_src_read(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS) & 0x00ff) |
-				     ((freq >> 5) & 0xfc00));
+			     (snd_es1371_src_read(ensoniq, ES_SMPREG_ADC +
+						  ES_SMPREG_INT_REGS) & 0x00ff) |
+			     ((freq >> 5) & 0xfc00));
 	snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
 	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8);
 	snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8);
 	up(&ensoniq->src_mutex);
 }
 
-static void snd_es1371_dac1_rate(ensoniq_t * ensoniq, unsigned int rate)
+static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate)
 {
 	unsigned int freq, r;
 
 	down(&ensoniq->src_mutex);
 	freq = ((rate << 15) + 1500) / 3000;
-	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | ES_1371_DIS_P1;
+	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
+						   ES_1371_DIS_P2 | ES_1371_DIS_R1)) |
+		ES_1371_DIS_P1;
 	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
 	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS,
-			     (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS) & 0x00ff) |
+			     (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC1 +
+						  ES_SMPREG_INT_REGS) & 0x00ff) |
 			     ((freq >> 5) & 0xfc00));
 	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
-	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1));
+	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
+						   ES_1371_DIS_P2 | ES_1371_DIS_R1));
 	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
 	up(&ensoniq->src_mutex);
 }
 
-static void snd_es1371_dac2_rate(ensoniq_t * ensoniq, unsigned int rate)
+static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate)
 {
 	unsigned int freq, r;
 
 	down(&ensoniq->src_mutex);
 	freq = ((rate << 15) + 1500) / 3000;
-	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | ES_1371_DIS_P2;
+	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
+						   ES_1371_DIS_P1 | ES_1371_DIS_R1)) |
+		ES_1371_DIS_P2;
 	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
 	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS,
-			     (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS) & 0x00ff) |
+			     (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC2 +
+						  ES_SMPREG_INT_REGS) & 0x00ff) |
 			     ((freq >> 5) & 0xfc00));
-	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
-	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1));
+	snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC,
+			     freq & 0x7fff);
+	r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE |
+						   ES_1371_DIS_P1 | ES_1371_DIS_R1));
 	outl(r, ES_REG(ensoniq, 1371_SMPRATE));
 	up(&ensoniq->src_mutex);
 }
 
 #endif /* CHIP1371 */
 
-static int snd_ensoniq_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 	{
 		unsigned int what = 0;
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
+		struct snd_pcm_substream *s;
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == ensoniq->playback1_substream) {
@@ -788,7 +825,7 @@
 	{
 		unsigned int what = 0;
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
+		struct snd_pcm_substream *s;
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == ensoniq->playback1_substream) {
@@ -821,21 +858,21 @@
  *  PCM part
  */
 
-static int snd_ensoniq_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_ensoniq_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_ensoniq_hw_free(snd_pcm_substream_t * substream)
+static int snd_ensoniq_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_ensoniq_playback1_prepare(snd_pcm_substream_t * substream)
+static int snd_ensoniq_playback1_prepare(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int mode = 0;
 
 	ensoniq->p1_dma_size = snd_pcm_lib_buffer_bytes(substream);
@@ -860,7 +897,8 @@
 	ensoniq->sctrl &= ~(ES_P1_LOOP_SEL | ES_P1_PAUSE | ES_P1_SCT_RLD | ES_P1_MODEM);
 	ensoniq->sctrl |= ES_P1_INT_EN | ES_P1_MODEO(mode);
 	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
-	outl((ensoniq->p1_period_size >> snd_ensoniq_sample_shift[mode]) - 1, ES_REG(ensoniq, DAC1_COUNT));
+	outl((ensoniq->p1_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
+	     ES_REG(ensoniq, DAC1_COUNT));
 #ifdef CHIP1370
 	ensoniq->ctrl &= ~ES_1370_WTSRSELM;
 	switch (runtime->rate) {
@@ -879,10 +917,10 @@
 	return 0;
 }
 
-static int snd_ensoniq_playback2_prepare(snd_pcm_substream_t * substream)
+static int snd_ensoniq_playback2_prepare(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int mode = 0;
 
 	ensoniq->p2_dma_size = snd_pcm_lib_buffer_bytes(substream);
@@ -902,7 +940,8 @@
 	ensoniq->sctrl |= ES_P2_INT_EN | ES_P2_MODEO(mode) |
 			  ES_P2_END_INCO(mode & 2 ? 2 : 1) | ES_P2_ST_INCO(0);
 	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
-	outl((ensoniq->p2_period_size >> snd_ensoniq_sample_shift[mode]) - 1, ES_REG(ensoniq, DAC2_COUNT));
+	outl((ensoniq->p2_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
+	     ES_REG(ensoniq, DAC2_COUNT));
 #ifdef CHIP1370
 	if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_CAPTURE)) {
 		ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
@@ -918,10 +957,10 @@
 	return 0;
 }
 
-static int snd_ensoniq_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_ensoniq_capture_prepare(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int mode = 0;
 
 	ensoniq->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
@@ -939,7 +978,8 @@
 	ensoniq->sctrl &= ~(ES_R1_LOOP_SEL | ES_R1_MODEM);
 	ensoniq->sctrl |= ES_R1_INT_EN | ES_R1_MODEO(mode);
 	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
-	outl((ensoniq->c_period_size >> snd_ensoniq_sample_shift[mode]) - 1, ES_REG(ensoniq, ADC_COUNT));
+	outl((ensoniq->c_period_size >> snd_ensoniq_sample_shift[mode]) - 1,
+	     ES_REG(ensoniq, ADC_COUNT));
 #ifdef CHIP1370
 	if (!(ensoniq->u.es1370.pclkdiv_lock & ES_MODE_PLAY2)) {
 		ensoniq->ctrl &= ~ES_1370_PCLKDIVM;
@@ -955,9 +995,9 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_ensoniq_playback1_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ensoniq_playback1_pointer(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	spin_lock(&ensoniq->reg_lock);
@@ -972,9 +1012,9 @@
 	return ptr;
 }
 
-static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ensoniq_playback2_pointer(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	spin_lock(&ensoniq->reg_lock);
@@ -989,9 +1029,9 @@
 	return ptr;
 }
 
-static snd_pcm_uframes_t snd_ensoniq_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ensoniq_capture_pointer(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	spin_lock(&ensoniq->reg_lock);
@@ -1006,7 +1046,7 @@
 	return ptr;
 }
 
-static snd_pcm_hardware_t snd_ensoniq_playback1 =
+static struct snd_pcm_hardware snd_ensoniq_playback1 =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1033,7 +1073,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ensoniq_playback2 =
+static struct snd_pcm_hardware snd_ensoniq_playback2 =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1053,7 +1093,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ensoniq_capture =
+static struct snd_pcm_hardware snd_ensoniq_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1072,10 +1112,10 @@
 	.fifo_size =		0,
 };
 
-static int snd_ensoniq_playback1_open(snd_pcm_substream_t * substream)
+static int snd_ensoniq_playback1_open(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	ensoniq->mode |= ES_MODE_PLAY1;
 	ensoniq->playback1_substream = substream;
@@ -1095,10 +1135,10 @@
 	return 0;
 }
 
-static int snd_ensoniq_playback2_open(snd_pcm_substream_t * substream)
+static int snd_ensoniq_playback2_open(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	ensoniq->mode |= ES_MODE_PLAY2;
 	ensoniq->playback2_substream = substream;
@@ -1118,10 +1158,10 @@
 	return 0;
 }
 
-static int snd_ensoniq_capture_open(snd_pcm_substream_t * substream)
+static int snd_ensoniq_capture_open(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	ensoniq->mode |= ES_MODE_CAPTURE;
 	ensoniq->capture_substream = substream;
@@ -1137,18 +1177,18 @@
 	return 0;
 }
 
-static int snd_ensoniq_playback1_close(snd_pcm_substream_t * substream)
+static int snd_ensoniq_playback1_close(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
 
 	ensoniq->playback1_substream = NULL;
 	ensoniq->mode &= ~ES_MODE_PLAY1;
 	return 0;
 }
 
-static int snd_ensoniq_playback2_close(snd_pcm_substream_t * substream)
+static int snd_ensoniq_playback2_close(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
 
 	ensoniq->playback2_substream = NULL;
 	spin_lock_irq(&ensoniq->reg_lock);
@@ -1160,9 +1200,9 @@
 	return 0;
 }
 
-static int snd_ensoniq_capture_close(snd_pcm_substream_t * substream)
+static int snd_ensoniq_capture_close(struct snd_pcm_substream *substream)
 {
-	ensoniq_t *ensoniq = snd_pcm_substream_chip(substream);
+	struct ensoniq *ensoniq = snd_pcm_substream_chip(substream);
 
 	ensoniq->capture_substream = NULL;
 	spin_lock_irq(&ensoniq->reg_lock);
@@ -1174,7 +1214,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_ensoniq_playback1_ops = {
+static struct snd_pcm_ops snd_ensoniq_playback1_ops = {
 	.open =		snd_ensoniq_playback1_open,
 	.close =	snd_ensoniq_playback1_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1185,7 +1225,7 @@
 	.pointer =	snd_ensoniq_playback1_pointer,
 };
 
-static snd_pcm_ops_t snd_ensoniq_playback2_ops = {
+static struct snd_pcm_ops snd_ensoniq_playback2_ops = {
 	.open =		snd_ensoniq_playback2_open,
 	.close =	snd_ensoniq_playback2_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1196,7 +1236,7 @@
 	.pointer =	snd_ensoniq_playback2_pointer,
 };
 
-static snd_pcm_ops_t snd_ensoniq_capture_ops = {
+static struct snd_pcm_ops snd_ensoniq_capture_ops = {
 	.open =		snd_ensoniq_capture_open,
 	.close =	snd_ensoniq_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1207,16 +1247,10 @@
 	.pointer =	snd_ensoniq_capture_pointer,
 };
 
-static void snd_ensoniq_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_ensoniq_pcm(struct ensoniq * ensoniq, int device,
+				     struct snd_pcm ** rpcm)
 {
-	ensoniq_t *ensoniq = pcm->private_data;
-	ensoniq->pcm1 = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_ensoniq_pcm(ensoniq_t * ensoniq, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1237,7 +1271,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ensoniq_capture_ops);
 
 	pcm->private_data = ensoniq;
-	pcm->private_free = snd_ensoniq_pcm_free;
 	pcm->info_flags = 0;
 #ifdef CHIP1370
 	strcpy(pcm->name, "ES1370 DAC2/ADC");
@@ -1254,16 +1287,10 @@
 	return 0;
 }
 
-static void snd_ensoniq_pcm_free2(snd_pcm_t *pcm)
+static int __devinit snd_ensoniq_pcm2(struct ensoniq * ensoniq, int device,
+				      struct snd_pcm ** rpcm)
 {
-	ensoniq_t *ensoniq = pcm->private_data;
-	ensoniq->pcm2 = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_ensoniq_pcm2(ensoniq_t * ensoniq, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1282,7 +1309,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ensoniq_playback2_ops);
 #endif
 	pcm->private_data = ensoniq;
-	pcm->private_free = snd_ensoniq_pcm_free2;
 	pcm->info_flags = 0;
 #ifdef CHIP1370
 	strcpy(pcm->name, "ES1370 DAC1");
@@ -1307,17 +1333,18 @@
  * ENS1371 mixer (including SPDIF interface)
  */
 #ifdef CHIP1371
-static int snd_ens1373_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ens1373_spdif_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ens1373_spdif_default_get(snd_kcontrol_t * kcontrol,
-                                         snd_ctl_elem_value_t * ucontrol)
+static int snd_ens1373_spdif_default_get(struct snd_kcontrol *kcontrol,
+                                         struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	spin_lock_irq(&ensoniq->reg_lock);
 	ucontrol->value.iec958.status[0] = (ensoniq->spdif_default >> 0) & 0xff;
 	ucontrol->value.iec958.status[1] = (ensoniq->spdif_default >> 8) & 0xff;
@@ -1327,10 +1354,10 @@
 	return 0;
 }
 
-static int snd_ens1373_spdif_default_put(snd_kcontrol_t * kcontrol,
-                                         snd_ctl_elem_value_t * ucontrol)
+static int snd_ens1373_spdif_default_put(struct snd_kcontrol *kcontrol,
+                                         struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 
@@ -1341,14 +1368,15 @@
 	spin_lock_irq(&ensoniq->reg_lock);
 	change = ensoniq->spdif_default != val;
 	ensoniq->spdif_default = val;
-	if (change && ensoniq->playback1_substream == NULL && ensoniq->playback2_substream == NULL)
+	if (change && ensoniq->playback1_substream == NULL &&
+	    ensoniq->playback2_substream == NULL)
 		outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
 	spin_unlock_irq(&ensoniq->reg_lock);
 	return change;
 }
 
-static int snd_ens1373_spdif_mask_get(snd_kcontrol_t * kcontrol,
-                                         snd_ctl_elem_value_t * ucontrol)
+static int snd_ens1373_spdif_mask_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = 0xff;
 	ucontrol->value.iec958.status[1] = 0xff;
@@ -1357,10 +1385,10 @@
 	return 0;
 }
 
-static int snd_ens1373_spdif_stream_get(snd_kcontrol_t * kcontrol,
-                                         snd_ctl_elem_value_t * ucontrol)
+static int snd_ens1373_spdif_stream_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	spin_lock_irq(&ensoniq->reg_lock);
 	ucontrol->value.iec958.status[0] = (ensoniq->spdif_stream >> 0) & 0xff;
 	ucontrol->value.iec958.status[1] = (ensoniq->spdif_stream >> 8) & 0xff;
@@ -1370,10 +1398,10 @@
 	return 0;
 }
 
-static int snd_ens1373_spdif_stream_put(snd_kcontrol_t * kcontrol,
-                                        snd_ctl_elem_value_t * ucontrol)
+static int snd_ens1373_spdif_stream_put(struct snd_kcontrol *kcontrol,
+                                        struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 
@@ -1384,7 +1412,8 @@
 	spin_lock_irq(&ensoniq->reg_lock);
 	change = ensoniq->spdif_stream != val;
 	ensoniq->spdif_stream = val;
-	if (change && (ensoniq->playback1_substream != NULL || ensoniq->playback2_substream != NULL))
+	if (change && (ensoniq->playback1_substream != NULL ||
+		       ensoniq->playback2_substream != NULL))
 		outl(val, ES_REG(ensoniq, CHANNEL_STATUS));
 	spin_unlock_irq(&ensoniq->reg_lock);
 	return change;
@@ -1394,7 +1423,8 @@
 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_es1371_spdif_info, \
   .get = snd_es1371_spdif_get, .put = snd_es1371_spdif_put }
 
-static int snd_es1371_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_es1371_spdif_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
         uinfo->count = 1;
@@ -1403,9 +1433,10 @@
         return 0;
 }
 
-static int snd_es1371_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1371_spdif_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&ensoniq->reg_lock);
 	ucontrol->value.integer.value[0] = ensoniq->ctrl & ES_1373_SPDIF_THRU ? 1 : 0;
@@ -1413,9 +1444,10 @@
 	return 0;
 }
 
-static int snd_es1371_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1371_spdif_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	unsigned int nval1, nval2;
 	int change;
 	
@@ -1435,7 +1467,7 @@
 
 
 /* spdif controls */
-static snd_kcontrol_new_t snd_es1371_mixer_spdif[] __devinitdata = {
+static struct snd_kcontrol_new snd_es1371_mixer_spdif[] __devinitdata = {
 	ES1371_SPDIF(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH)),
 	{
 		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1461,7 +1493,8 @@
 };
 
 
-static int snd_es1373_rear_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_es1373_rear_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
         uinfo->count = 1;
@@ -1470,28 +1503,33 @@
         return 0;
 }
 
-static int snd_es1373_rear_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1373_rear_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	int val = 0;
 	
 	spin_lock_irq(&ensoniq->reg_lock);
-	if ((ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) == ES_1373_REAR_BIT26)
+	if ((ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|
+			      ES_1373_REAR_BIT24)) == ES_1373_REAR_BIT26)
 	    	val = 1;
 	ucontrol->value.integer.value[0] = val;
 	spin_unlock_irq(&ensoniq->reg_lock);
 	return 0;
 }
 
-static int snd_es1373_rear_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1373_rear_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	unsigned int nval1;
 	int change;
 	
-	nval1 = ucontrol->value.integer.value[0] ? ES_1373_REAR_BIT26 : (ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
+	nval1 = ucontrol->value.integer.value[0] ?
+		ES_1373_REAR_BIT26 : (ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
 	spin_lock_irq(&ensoniq->reg_lock);
-	change = (ensoniq->cssr & (ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) != nval1;
+	change = (ensoniq->cssr & (ES_1373_REAR_BIT27|
+				   ES_1373_REAR_BIT26|ES_1373_REAR_BIT24)) != nval1;
 	ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT26|ES_1373_REAR_BIT24);
 	ensoniq->cssr |= nval1;
 	outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
@@ -1499,7 +1537,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ens1373_rear __devinitdata =
+static struct snd_kcontrol_new snd_ens1373_rear __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"AC97 2ch->4ch Copy Switch",
@@ -1508,7 +1546,8 @@
 	.put =		snd_es1373_rear_put,
 };
 
-static int snd_es1373_line_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_es1373_line_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1517,9 +1556,10 @@
 	return 0;
 }
 
-static int snd_es1373_line_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1373_line_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	int val = 0;
 	
 	spin_lock_irq(&ensoniq->reg_lock);
@@ -1530,9 +1570,10 @@
 	return 0;
 }
 
-static int snd_es1373_line_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1373_line_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	int changed;
 	unsigned int ctrl;
 	
@@ -1549,7 +1590,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t snd_ens1373_line __devinitdata =
+static struct snd_kcontrol_new snd_ens1373_line __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Line In->Rear Out Switch",
@@ -1558,9 +1599,9 @@
 	.put =		snd_es1373_line_put,
 };
 
-static void snd_ensoniq_mixer_free_ac97(ac97_t *ac97)
+static void snd_ensoniq_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	ensoniq_t *ensoniq = ac97->private_data;
+	struct ensoniq *ensoniq = ac97->private_data;
 	ensoniq->u.es1371.ac97 = NULL;
 }
 
@@ -1577,13 +1618,13 @@
 	{ .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
 };
 
-static int snd_ensoniq_1371_mixer(ensoniq_t * ensoniq)
+static int snd_ensoniq_1371_mixer(struct ensoniq * ensoniq, int has_spdif, int has_line)
 {
-	snd_card_t *card = ensoniq->card;
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
+	struct snd_card *card = ensoniq->card;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
 	int err, idx;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_es1371_codec_write,
 		.read = snd_es1371_codec_read,
 		.wait = snd_es1371_codec_wait,
@@ -1599,13 +1640,17 @@
 	if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0)
 		return err;
 	for (idx = 0; es1371_spdif_present[idx].vid != (unsigned short)PCI_ANY_ID; idx++)
-		if (ensoniq->pci->vendor == es1371_spdif_present[idx].vid &&
-		    ensoniq->pci->device == es1371_spdif_present[idx].did &&
-		    ensoniq->rev == es1371_spdif_present[idx].rev) {
-		    	snd_kcontrol_t *kctl;
+		if ((ensoniq->pci->vendor == es1371_spdif_present[idx].vid &&
+		     ensoniq->pci->device == es1371_spdif_present[idx].did &&
+		     ensoniq->rev == es1371_spdif_present[idx].rev) || has_spdif > 0) {
+		    	struct snd_kcontrol *kctl;
 			int i, index = 0; 
 
-			ensoniq->spdif_default = ensoniq->spdif_stream = SNDRV_PCM_DEFAULT_CON_SPDIF;
+                        if (has_spdif < 0)
+                                break;
+
+			ensoniq->spdif_default = ensoniq->spdif_stream =
+				SNDRV_PCM_DEFAULT_CON_SPDIF;
 			outl(ensoniq->spdif_default, ES_REG(ensoniq, CHANNEL_STATUS));
 
 		    	if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SPDIF)
@@ -1632,7 +1677,8 @@
 	if (((ensoniq->subsystem_vendor_id == 0x1274) &&
 	    (ensoniq->subsystem_device_id == 0x2000)) || /* GA-7DXR */
 	    ((ensoniq->subsystem_vendor_id == 0x1458) &&
-	    (ensoniq->subsystem_device_id == 0xa000))) { /* GA-8IEXP */
+	    (ensoniq->subsystem_device_id == 0xa000)) || /* GA-8IEXP */
+	    has_line > 0) {
 		 err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line, ensoniq));
 		 if (err < 0)
 			 return err;
@@ -1650,7 +1696,8 @@
   .get = snd_ensoniq_control_get, .put = snd_ensoniq_control_put, \
   .private_value = mask }
 
-static int snd_ensoniq_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ensoniq_control_info(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
         uinfo->count = 1;
@@ -1659,9 +1706,10 @@
         return 0;
 }
 
-static int snd_ensoniq_control_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ensoniq_control_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	int mask = kcontrol->private_value;
 	
 	spin_lock_irq(&ensoniq->reg_lock);
@@ -1670,9 +1718,10 @@
 	return 0;
 }
 
-static int snd_ensoniq_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ensoniq_control_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	ensoniq_t *ensoniq = snd_kcontrol_chip(kcontrol);
+	struct ensoniq *ensoniq = snd_kcontrol_chip(kcontrol);
 	int mask = kcontrol->private_value;
 	unsigned int nval;
 	int change;
@@ -1691,23 +1740,23 @@
  * ENS1370 mixer
  */
 
-static snd_kcontrol_new_t snd_es1370_controls[2] __devinitdata = {
+static struct snd_kcontrol_new snd_es1370_controls[2] __devinitdata = {
 ENSONIQ_CONTROL("PCM 0 Output also on Line-In Jack", ES_1370_XCTL0),
 ENSONIQ_CONTROL("Mic +5V bias", ES_1370_XCTL1)
 };
 
 #define ES1370_CONTROLS ARRAY_SIZE(snd_es1370_controls)
 
-static void snd_ensoniq_mixer_free_ak4531(ak4531_t *ak4531)
+static void snd_ensoniq_mixer_free_ak4531(struct snd_ak4531 *ak4531)
 {
-	ensoniq_t *ensoniq = ak4531->private_data;
+	struct ensoniq *ensoniq = ak4531->private_data;
 	ensoniq->u.es1370.ak4531 = NULL;
 }
 
-static int __devinit snd_ensoniq_1370_mixer(ensoniq_t * ensoniq)
+static int __devinit snd_ensoniq_1370_mixer(struct ensoniq * ensoniq)
 {
-	snd_card_t *card = ensoniq->card;
-	ak4531_t ak4531;
+	struct snd_card *card = ensoniq->card;
+	struct snd_ak4531 ak4531;
 	unsigned int idx;
 	int err;
 
@@ -1761,7 +1810,7 @@
 }
 #endif
 
-static int __devinit snd_ensoniq_create_gameport(ensoniq_t *ensoniq, int dev)
+static int __devinit snd_ensoniq_create_gameport(struct ensoniq *ensoniq, int dev)
 {
 	struct gameport *gp;
 	int io_port;
@@ -1784,7 +1833,8 @@
 
 	default:
 		if (!request_region(io_port, 8, "ens137x: gameport")) {
-			printk(KERN_WARNING "ens137x: gameport io port 0x%#x in use\n", io_port);
+			printk(KERN_WARNING "ens137x: gameport io port 0x%#x in use\n",
+			       io_port);
 			return -EBUSY;
 		}
 		break;
@@ -1814,7 +1864,7 @@
 	return 0;
 }
 
-static void snd_ensoniq_free_gameport(ensoniq_t *ensoniq)
+static void snd_ensoniq_free_gameport(struct ensoniq *ensoniq)
 {
 	if (ensoniq->gameport) {
 		int port = ensoniq->gameport->io;
@@ -1827,36 +1877,40 @@
 	}
 }
 #else
-static inline int snd_ensoniq_create_gameport(ensoniq_t *ensoniq, long port) { return -ENOSYS; }
-static inline void snd_ensoniq_free_gameport(ensoniq_t *ensoniq) { }
+static inline int snd_ensoniq_create_gameport(struct ensoniq *ensoniq, long port) { return -ENOSYS; }
+static inline void snd_ensoniq_free_gameport(struct ensoniq *ensoniq) { }
 #endif /* SUPPORT_JOYSTICK */
 
 /*
 
  */
 
-static void snd_ensoniq_proc_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_ensoniq_proc_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
-	ensoniq_t *ensoniq = entry->private_data;
+	struct ensoniq *ensoniq = entry->private_data;
 
 #ifdef CHIP1370
 	snd_iprintf(buffer, "Ensoniq AudioPCI ES1370\n\n");
 #else
 	snd_iprintf(buffer, "Ensoniq AudioPCI ES1371\n\n");
 #endif
-	snd_iprintf(buffer, "Joystick enable  : %s\n", ensoniq->ctrl & ES_JYSTK_EN ? "on" : "off");
+	snd_iprintf(buffer, "Joystick enable  : %s\n",
+		    ensoniq->ctrl & ES_JYSTK_EN ? "on" : "off");
 #ifdef CHIP1370
-	snd_iprintf(buffer, "MIC +5V bias     : %s\n", ensoniq->ctrl & ES_1370_XCTL1 ? "on" : "off");
-	snd_iprintf(buffer, "Line In to AOUT  : %s\n", ensoniq->ctrl & ES_1370_XCTL0 ? "on" : "off");
+	snd_iprintf(buffer, "MIC +5V bias     : %s\n",
+		    ensoniq->ctrl & ES_1370_XCTL1 ? "on" : "off");
+	snd_iprintf(buffer, "Line In to AOUT  : %s\n",
+		    ensoniq->ctrl & ES_1370_XCTL0 ? "on" : "off");
 #else
-	snd_iprintf(buffer, "Joystick port    : 0x%x\n", (ES_1371_JOY_ASELI(ensoniq->ctrl) * 8) + 0x200);
+	snd_iprintf(buffer, "Joystick port    : 0x%x\n",
+		    (ES_1371_JOY_ASELI(ensoniq->ctrl) * 8) + 0x200);
 #endif
 }
 
-static void __devinit snd_ensoniq_proc_init(ensoniq_t * ensoniq)
+static void __devinit snd_ensoniq_proc_init(struct ensoniq * ensoniq)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(ensoniq->card, "audiopci", &entry))
 		snd_info_set_text_ops(entry, ensoniq, 1024, snd_ensoniq_proc_read);
@@ -1866,7 +1920,7 @@
 
  */
 
-static int snd_ensoniq_free(ensoniq_t *ensoniq)
+static int snd_ensoniq_free(struct ensoniq *ensoniq)
 {
 	snd_ensoniq_free_gameport(ensoniq);
 	if (ensoniq->irq < 0)
@@ -1886,16 +1940,16 @@
 		snd_dma_free_pages(&ensoniq->dma_bug);
 #endif
 	if (ensoniq->irq >= 0)
-		free_irq(ensoniq->irq, (void *)ensoniq);
+		free_irq(ensoniq->irq, ensoniq);
 	pci_release_regions(ensoniq->pci);
 	pci_disable_device(ensoniq->pci);
 	kfree(ensoniq);
 	return 0;
 }
 
-static int snd_ensoniq_dev_free(snd_device_t *device)
+static int snd_ensoniq_dev_free(struct snd_device *device)
 {
-	ensoniq_t *ensoniq = device->device_data;
+	struct ensoniq *ensoniq = device->device_data;
 	return snd_ensoniq_free(ensoniq);
 }
 
@@ -1924,85 +1978,22 @@
 };
 #endif
 
-static int __devinit snd_ensoniq_create(snd_card_t * card,
-				     struct pci_dev *pci,
-				     ensoniq_t ** rensoniq)
+static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
 {
-	ensoniq_t *ensoniq;
-	unsigned short cmdw;
-	unsigned char cmdb;
 #ifdef CHIP1371
 	int idx;
+	struct pci_dev *pci = ensoniq->pci;
 #endif
-	int err;
-	static snd_device_ops_t ops = {
-		.dev_free =	snd_ensoniq_dev_free,
-	};
-
-	*rensoniq = NULL;
-	if ((err = pci_enable_device(pci)) < 0)
-		return err;
-	ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL);
-	if (ensoniq == NULL) {
-		pci_disable_device(pci);
-		return -ENOMEM;
-	}
-	spin_lock_init(&ensoniq->reg_lock);
-	init_MUTEX(&ensoniq->src_mutex);
-	ensoniq->card = card;
-	ensoniq->pci = pci;
-	ensoniq->irq = -1;
-	if ((err = pci_request_regions(pci, "Ensoniq AudioPCI")) < 0) {
-		kfree(ensoniq);
-		pci_disable_device(pci);
-		return err;
-	}
-	ensoniq->port = pci_resource_start(pci, 0);
-	if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ, "Ensoniq AudioPCI", (void *)ensoniq)) {
-		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
-		snd_ensoniq_free(ensoniq);
-		return -EBUSY;
-	}
-	ensoniq->irq = pci->irq;
+	/* this code was part of snd_ensoniq_create before intruduction
+	  * of suspend/resume
+	  */
 #ifdef CHIP1370
-	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-				16, &ensoniq->dma_bug) < 0) {
-		snd_printk(KERN_ERR "unable to allocate space for phantom area - dma_bug\n");
-		snd_ensoniq_free(ensoniq);
-		return -EBUSY;
-	}
-#endif
-	pci_set_master(pci);
-	pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb);
-	ensoniq->rev = cmdb;
-	pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &cmdw);
-	ensoniq->subsystem_vendor_id = cmdw;
-	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &cmdw);
-	ensoniq->subsystem_device_id = cmdw;
-#ifdef CHIP1370
-#if 0
-	ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
-#else	/* get microphone working */
-	ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
-#endif
-	ensoniq->sctrl = 0;
-	/* initialize the chips */
 	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
 	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
 	outl(ES_MEM_PAGEO(ES_PAGE_ADC), ES_REG(ensoniq, MEM_PAGE));
 	outl(ensoniq->dma_bug.addr, ES_REG(ensoniq, PHANTOM_FRAME));
 	outl(0, ES_REG(ensoniq, PHANTOM_COUNT));
 #else
-	ensoniq->ctrl = 0;
-	ensoniq->sctrl = 0;
-	ensoniq->cssr = 0;
-	for (idx = 0; es1371_amplifier_hack[idx].svid != (unsigned short)PCI_ANY_ID; idx++)
-		if (ensoniq->subsystem_vendor_id == es1371_amplifier_hack[idx].svid &&
-		    ensoniq->subsystem_device_id == es1371_amplifier_hack[idx].sdid) {
-			ensoniq->ctrl |= ES_1371_GPIO_OUT(1);	/* turn amplifier on */
-			break;
-		}
-	/* initialize the chips */
 	outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
 	outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
 	outl(0, ES_REG(ensoniq, 1371_LEGACY));
@@ -2010,7 +2001,6 @@
 		if (pci->vendor == es1371_ac97_reset_hack[idx].vid &&
 		    pci->device == es1371_ac97_reset_hack[idx].did &&
 		    ensoniq->rev == es1371_ac97_reset_hack[idx].rev) {
-			ensoniq->cssr |= ES_1371_ST_AC97_RST;
 			outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
 			/* need to delay around 20ms(bleech) to give
 			some CODECs enough time to wakeup */
@@ -2055,6 +2045,137 @@
 	outb(0x00, ES_REG(ensoniq, UART_RES));
 	outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
 	synchronize_irq(ensoniq->irq);
+}
+
+#ifdef CONFIG_PM
+static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct ensoniq *ensoniq = card->private_data;
+	
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+
+	snd_pcm_suspend_all(ensoniq->pcm1);
+	snd_pcm_suspend_all(ensoniq->pcm2);
+	
+#ifdef CHIP1371	
+	snd_ac97_suspend(ensoniq->u.es1371.ac97);
+#else
+	snd_ak4531_suspend(ensoniq->u.es1370.ak4531);
+#endif	
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
+	return 0;
+}
+
+static int snd_ensoniq_resume(struct pci_dev *pci)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct ensoniq *ensoniq = card->private_data;
+
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
+	pci_set_master(pci);
+
+	snd_ensoniq_chip_init(ensoniq);
+
+#ifdef CHIP1371	
+	snd_ac97_resume(ensoniq->u.es1371.ac97);
+#else
+	snd_ak4531_resume(ensoniq->u.es1370.ak4531);
+#endif	
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+
+static int __devinit snd_ensoniq_create(struct snd_card *card,
+				     struct pci_dev *pci,
+				     struct ensoniq ** rensoniq)
+{
+	struct ensoniq *ensoniq;
+	unsigned short cmdw;
+	unsigned char cmdb;
+#ifdef CHIP1371
+	int idx;
+#endif
+	int err;
+	static struct snd_device_ops ops = {
+		.dev_free =	snd_ensoniq_dev_free,
+	};
+
+	*rensoniq = NULL;
+	if ((err = pci_enable_device(pci)) < 0)
+		return err;
+	ensoniq = kzalloc(sizeof(*ensoniq), GFP_KERNEL);
+	if (ensoniq == NULL) {
+		pci_disable_device(pci);
+		return -ENOMEM;
+	}
+	spin_lock_init(&ensoniq->reg_lock);
+	init_MUTEX(&ensoniq->src_mutex);
+	ensoniq->card = card;
+	ensoniq->pci = pci;
+	ensoniq->irq = -1;
+	if ((err = pci_request_regions(pci, "Ensoniq AudioPCI")) < 0) {
+		kfree(ensoniq);
+		pci_disable_device(pci);
+		return err;
+	}
+	ensoniq->port = pci_resource_start(pci, 0);
+	if (request_irq(pci->irq, snd_audiopci_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			"Ensoniq AudioPCI", ensoniq)) {
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+		snd_ensoniq_free(ensoniq);
+		return -EBUSY;
+	}
+	ensoniq->irq = pci->irq;
+#ifdef CHIP1370
+	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+				16, &ensoniq->dma_bug) < 0) {
+		snd_printk(KERN_ERR "unable to allocate space for phantom area - dma_bug\n");
+		snd_ensoniq_free(ensoniq);
+		return -EBUSY;
+	}
+#endif
+	pci_set_master(pci);
+	pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb);
+	ensoniq->rev = cmdb;
+	pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &cmdw);
+	ensoniq->subsystem_vendor_id = cmdw;
+	pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &cmdw);
+	ensoniq->subsystem_device_id = cmdw;
+#ifdef CHIP1370
+#if 0
+	ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE |
+		ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
+#else	/* get microphone working */
+	ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_PCLKDIVO(ES_1370_SRTODIV(8000));
+#endif
+	ensoniq->sctrl = 0;
+#else
+	ensoniq->ctrl = 0;
+	ensoniq->sctrl = 0;
+	ensoniq->cssr = 0;
+	for (idx = 0; es1371_amplifier_hack[idx].svid != (unsigned short)PCI_ANY_ID; idx++)
+		if (ensoniq->subsystem_vendor_id == es1371_amplifier_hack[idx].svid &&
+		    ensoniq->subsystem_device_id == es1371_amplifier_hack[idx].sdid) {
+			ensoniq->ctrl |= ES_1371_GPIO_OUT(1);	/* turn amplifier on */
+			break;
+		}
+	for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++)
+		if (pci->vendor == es1371_ac97_reset_hack[idx].vid &&
+		    pci->device == es1371_ac97_reset_hack[idx].did &&
+		    ensoniq->rev == es1371_ac97_reset_hack[idx].rev) {
+			ensoniq->cssr |= ES_1371_ST_AC97_RST;
+			break;
+		}
+#endif
+
+	snd_ensoniq_chip_init(ensoniq);
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ensoniq, &ops)) < 0) {
 		snd_ensoniq_free(ensoniq);
@@ -2073,9 +2194,9 @@
  *  MIDI section
  */
 
-static void snd_ensoniq_midi_interrupt(ensoniq_t * ensoniq)
+static void snd_ensoniq_midi_interrupt(struct ensoniq * ensoniq)
 {
-	snd_rawmidi_t * rmidi = ensoniq->rmidi;
+	struct snd_rawmidi *rmidi = ensoniq->rmidi;
 	unsigned char status, mask, byte;
 
 	if (rmidi == NULL)
@@ -2110,9 +2231,9 @@
 	spin_unlock(&ensoniq->reg_lock);
 }
 
-static int snd_ensoniq_midi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_ensoniq_midi_input_open(struct snd_rawmidi_substream *substream)
 {
-	ensoniq_t *ensoniq = substream->rmidi->private_data;
+	struct ensoniq *ensoniq = substream->rmidi->private_data;
 
 	spin_lock_irq(&ensoniq->reg_lock);
 	ensoniq->uartm |= ES_MODE_INPUT;
@@ -2126,9 +2247,9 @@
 	return 0;
 }
 
-static int snd_ensoniq_midi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_ensoniq_midi_input_close(struct snd_rawmidi_substream *substream)
 {
-	ensoniq_t *ensoniq = substream->rmidi->private_data;
+	struct ensoniq *ensoniq = substream->rmidi->private_data;
 
 	spin_lock_irq(&ensoniq->reg_lock);
 	if (!(ensoniq->uartm & ES_MODE_OUTPUT)) {
@@ -2143,9 +2264,9 @@
 	return 0;
 }
 
-static int snd_ensoniq_midi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_ensoniq_midi_output_open(struct snd_rawmidi_substream *substream)
 {
-	ensoniq_t *ensoniq = substream->rmidi->private_data;
+	struct ensoniq *ensoniq = substream->rmidi->private_data;
 
 	spin_lock_irq(&ensoniq->reg_lock);
 	ensoniq->uartm |= ES_MODE_OUTPUT;
@@ -2159,9 +2280,9 @@
 	return 0;
 }
 
-static int snd_ensoniq_midi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_ensoniq_midi_output_close(struct snd_rawmidi_substream *substream)
 {
-	ensoniq_t *ensoniq = substream->rmidi->private_data;
+	struct ensoniq *ensoniq = substream->rmidi->private_data;
 
 	spin_lock_irq(&ensoniq->reg_lock);
 	if (!(ensoniq->uartm & ES_MODE_INPUT)) {
@@ -2176,10 +2297,10 @@
 	return 0;
 }
 
-static void snd_ensoniq_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_ensoniq_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	ensoniq_t *ensoniq = substream->rmidi->private_data;
+	struct ensoniq *ensoniq = substream->rmidi->private_data;
 	int idx;
 
 	spin_lock_irqsave(&ensoniq->reg_lock, flags);
@@ -2200,10 +2321,10 @@
 	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
 }
 
-static void snd_ensoniq_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_ensoniq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
 	unsigned long flags;
-	ensoniq_t *ensoniq = substream->rmidi->private_data;
+	struct ensoniq *ensoniq = substream->rmidi->private_data;
 	unsigned char byte;
 
 	spin_lock_irqsave(&ensoniq->reg_lock, flags);
@@ -2230,23 +2351,24 @@
 	spin_unlock_irqrestore(&ensoniq->reg_lock, flags);
 }
 
-static snd_rawmidi_ops_t snd_ensoniq_midi_output =
+static struct snd_rawmidi_ops snd_ensoniq_midi_output =
 {
 	.open =		snd_ensoniq_midi_output_open,
 	.close =	snd_ensoniq_midi_output_close,
 	.trigger =	snd_ensoniq_midi_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_ensoniq_midi_input =
+static struct snd_rawmidi_ops snd_ensoniq_midi_input =
 {
 	.open =		snd_ensoniq_midi_input_open,
 	.close =	snd_ensoniq_midi_input_close,
 	.trigger =	snd_ensoniq_midi_input_trigger,
 };
 
-static int __devinit snd_ensoniq_midi(ensoniq_t * ensoniq, int device, snd_rawmidi_t **rrawmidi)
+static int __devinit snd_ensoniq_midi(struct ensoniq * ensoniq, int device,
+				      struct snd_rawmidi **rrawmidi)
 {
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	if (rrawmidi)
@@ -2260,7 +2382,8 @@
 #endif
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_ensoniq_midi_output);
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_ensoniq_midi_input);
-	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT | SNDRV_RAWMIDI_INFO_DUPLEX;
+	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
+		SNDRV_RAWMIDI_INFO_DUPLEX;
 	rmidi->private_data = ensoniq;
 	ensoniq->rmidi = rmidi;
 	if (rrawmidi)
@@ -2274,7 +2397,7 @@
 
 static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	ensoniq_t *ensoniq = dev_id;
+	struct ensoniq *ensoniq = dev_id;
 	unsigned int status, sctrl;
 
 	if (ensoniq == NULL)
@@ -2311,8 +2434,8 @@
 					const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	ensoniq_t *ensoniq;
+	struct snd_card *card;
+	struct ensoniq *ensoniq;
 	int err, pcm_devs[2];
 
 	if (dev >= SNDRV_CARDS)
@@ -2330,6 +2453,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = ensoniq;
 
 	pcm_devs[0] = 0; pcm_devs[1] = 1;
 #ifdef CHIP1370
@@ -2339,7 +2463,7 @@
 	}
 #endif
 #ifdef CHIP1371
-	if ((err = snd_ensoniq_1371_mixer(ensoniq)) < 0) {
+	if ((err = snd_ensoniq_1371_mixer(ensoniq, spdif[dev], lineio[dev])) < 0) {
 		snd_card_free(card);
 		return err;
 	}
@@ -2389,6 +2513,10 @@
 	.id_table = snd_audiopci_ids,
 	.probe = snd_audiopci_probe,
 	.remove = __devexit_p(snd_audiopci_remove),
+#ifdef CONFIG_PM
+	.suspend = snd_ensoniq_suspend,
+	.resume = snd_ensoniq_resume,
+#endif
 };
 	
 static int __init alsa_card_ens137x_init(void)
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index c134f48..0d556b0 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -191,11 +191,9 @@
 
  */
 
-typedef struct _snd_es1938 es1938_t;
-
 #define SAVED_REG_SIZE	32 /* max. number of registers to save */
 
-struct _snd_es1938 {
+struct es1938 {
 	int irq;
 
 	unsigned long io_port;
@@ -208,19 +206,18 @@
 	unsigned char irqmask;
 	unsigned char revision;
 
-	snd_kcontrol_t *hw_volume;
-	snd_kcontrol_t *hw_switch;
-	snd_kcontrol_t *master_volume;
-	snd_kcontrol_t *master_switch;
+	struct snd_kcontrol *hw_volume;
+	struct snd_kcontrol *hw_switch;
+	struct snd_kcontrol *master_volume;
+	struct snd_kcontrol *master_switch;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *capture_substream;
-	snd_pcm_substream_t *playback1_substream;
-	snd_pcm_substream_t *playback2_substream;
-	snd_kmixer_t *mixer;
-	snd_rawmidi_t *rmidi;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *capture_substream;
+	struct snd_pcm_substream *playback1_substream;
+	struct snd_pcm_substream *playback2_substream;
+	struct snd_rawmidi *rmidi;
 
 	unsigned int dma1_size;
 	unsigned int dma2_size;
@@ -232,7 +229,7 @@
 
 	spinlock_t reg_lock;
 	spinlock_t mixer_lock;
-        snd_info_entry_t *proc_entry;
+        struct snd_info_entry *proc_entry;
 
 #ifdef SUPPORT_JOYSTICK
 	struct gameport *gameport;
@@ -259,7 +256,7 @@
 /* -----------------------------------------------------------------
  * Write to a mixer register
  * -----------------------------------------------------------------*/
-static void snd_es1938_mixer_write(es1938_t *chip, unsigned char reg, unsigned char val)
+static void snd_es1938_mixer_write(struct es1938 *chip, unsigned char reg, unsigned char val)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&chip->mixer_lock, flags);
@@ -274,7 +271,7 @@
 /* -----------------------------------------------------------------
  * Read from a mixer register
  * -----------------------------------------------------------------*/
-static int snd_es1938_mixer_read(es1938_t *chip, unsigned char reg)
+static int snd_es1938_mixer_read(struct es1938 *chip, unsigned char reg)
 {
 	int data;
 	unsigned long flags;
@@ -291,7 +288,8 @@
 /* -----------------------------------------------------------------
  * Write to some bits of a mixer register (return old value)
  * -----------------------------------------------------------------*/
-static int snd_es1938_mixer_bits(es1938_t *chip, unsigned char reg, unsigned char mask, unsigned char val)
+static int snd_es1938_mixer_bits(struct es1938 *chip, unsigned char reg,
+				 unsigned char mask, unsigned char val)
 {
 	unsigned long flags;
 	unsigned char old, new, oval;
@@ -314,7 +312,7 @@
 /* -----------------------------------------------------------------
  * Write command to Controller Registers
  * -----------------------------------------------------------------*/
-static void snd_es1938_write_cmd(es1938_t *chip, unsigned char cmd)
+static void snd_es1938_write_cmd(struct es1938 *chip, unsigned char cmd)
 {
 	int i;
 	unsigned char v;
@@ -330,7 +328,7 @@
 /* -----------------------------------------------------------------
  * Read the Read Data Buffer
  * -----------------------------------------------------------------*/
-static int snd_es1938_get_byte(es1938_t *chip)
+static int snd_es1938_get_byte(struct es1938 *chip)
 {
 	int i;
 	unsigned char v;
@@ -344,7 +342,7 @@
 /* -----------------------------------------------------------------
  * Write value cmd register
  * -----------------------------------------------------------------*/
-static void snd_es1938_write(es1938_t *chip, unsigned char reg, unsigned char val)
+static void snd_es1938_write(struct es1938 *chip, unsigned char reg, unsigned char val)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -359,7 +357,7 @@
 /* -----------------------------------------------------------------
  * Read data from cmd register and return it
  * -----------------------------------------------------------------*/
-static unsigned char snd_es1938_read(es1938_t *chip, unsigned char reg)
+static unsigned char snd_es1938_read(struct es1938 *chip, unsigned char reg)
 {
 	unsigned char val;
 	unsigned long flags;
@@ -377,7 +375,8 @@
 /* -----------------------------------------------------------------
  * Write data to cmd register and return old value
  * -----------------------------------------------------------------*/
-static int snd_es1938_bits(es1938_t *chip, unsigned char reg, unsigned char mask, unsigned char val)
+static int snd_es1938_bits(struct es1938 *chip, unsigned char reg, unsigned char mask,
+			   unsigned char val)
 {
 	unsigned long flags;
 	unsigned char old, new, oval;
@@ -402,7 +401,7 @@
 /* --------------------------------------------------------------------
  * Reset the chip
  * --------------------------------------------------------------------*/
-static void snd_es1938_reset(es1938_t *chip)
+static void snd_es1938_reset(struct es1938 *chip)
 {
 	int i;
 
@@ -441,13 +440,13 @@
 /* --------------------------------------------------------------------
  * Reset the FIFOs
  * --------------------------------------------------------------------*/
-static void snd_es1938_reset_fifo(es1938_t *chip)
+static void snd_es1938_reset_fifo(struct es1938 *chip)
 {
 	outb(2, SLSB_REG(chip, RESET));
 	outb(0, SLSB_REG(chip, RESET));
 }
 
-static ratnum_t clocks[2] = {
+static struct snd_ratnum clocks[2] = {
 	{
 		.num = 793800,
 		.den_min = 1,
@@ -462,18 +461,18 @@
 	}
 };
 
-static snd_pcm_hw_constraint_ratnums_t hw_constraints_clocks = {
+static struct snd_pcm_hw_constraint_ratnums hw_constraints_clocks = {
 	.nrats = 2,
 	.rats = clocks,
 };
 
 
-static void snd_es1938_rate_set(es1938_t *chip, 
-				snd_pcm_substream_t *substream,
+static void snd_es1938_rate_set(struct es1938 *chip, 
+				struct snd_pcm_substream *substream,
 				int mode)
 {
 	unsigned int bits, div0;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (runtime->rate_num == clocks[0].num)
 		bits = 128 - runtime->rate_den;
 	else
@@ -495,7 +494,7 @@
  * Configure Solo1 builtin DMA Controller
  * --------------------------------------------------------------------*/
 
-static void snd_es1938_playback1_setdma(es1938_t *chip)
+static void snd_es1938_playback1_setdma(struct es1938 *chip)
 {
 	outb(0x00, SLIO_REG(chip, AUDIO2MODE));
 	outl(chip->dma2_start, SLIO_REG(chip, AUDIO2DMAADDR));
@@ -503,7 +502,7 @@
 	outw(chip->dma2_size, SLIO_REG(chip, AUDIO2DMACOUNT));
 }
 
-static void snd_es1938_playback2_setdma(es1938_t *chip)
+static void snd_es1938_playback2_setdma(struct es1938 *chip)
 {
 	/* Enable DMA controller */
 	outb(0xc4, SLDM_REG(chip, DMACOMMAND));
@@ -518,7 +517,7 @@
 	outb(0, SLDM_REG(chip, DMAMASK));
 }
 
-static void snd_es1938_capture_setdma(es1938_t *chip)
+static void snd_es1938_capture_setdma(struct es1938 *chip)
 {
 	/* Enable DMA controller */
 	outb(0xc4, SLDM_REG(chip, DMACOMMAND));
@@ -538,10 +537,10 @@
  *                           *** PCM part ***
  */
 
-static int snd_es1938_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_es1938_capture_trigger(struct snd_pcm_substream *substream,
 				      int cmd)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
 	int val;
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -561,10 +560,10 @@
 	return 0;
 }
 
-static int snd_es1938_playback1_trigger(snd_pcm_substream_t * substream,
+static int snd_es1938_playback1_trigger(struct snd_pcm_substream *substream,
 					int cmd)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
@@ -591,10 +590,10 @@
 	return 0;
 }
 
-static int snd_es1938_playback2_trigger(snd_pcm_substream_t * substream,
+static int snd_es1938_playback2_trigger(struct snd_pcm_substream *substream,
 					int cmd)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
 	int val;
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -614,7 +613,7 @@
 	return 0;
 }
 
-static int snd_es1938_playback_trigger(snd_pcm_substream_t *substream,
+static int snd_es1938_playback_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
 	switch (substream->number) {
@@ -630,10 +629,10 @@
 /* --------------------------------------------------------------------
  * First channel for Extended Mode Audio 1 ADC Operation
  * --------------------------------------------------------------------*/
-static int snd_es1938_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_es1938_capture_prepare(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int u, is8, mono;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -678,10 +677,10 @@
 /* ------------------------------------------------------------------------------
  * Second Audio channel DAC Operation
  * ------------------------------------------------------------------------------*/
-static int snd_es1938_playback1_prepare(snd_pcm_substream_t * substream)
+static int snd_es1938_playback1_prepare(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int u, is8, mono;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -706,7 +705,8 @@
 	snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2TCOUNTH, count >> 8);
 
 	/* initialize and configure Audio 2 DAC */
-	snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x40 | (u ? 0 : 4) | (mono ? 0 : 2) | (is8 ? 0 : 1));
+	snd_es1938_mixer_write(chip, ESSSB_IREG_AUDIO2CONTROL2, 0x40 | (u ? 0 : 4) |
+			       (mono ? 0 : 2) | (is8 ? 0 : 1));
 
 	/* program DMA */
 	snd_es1938_playback1_setdma(chip);
@@ -714,10 +714,10 @@
 	return 0;
 }
 
-static int snd_es1938_playback2_prepare(snd_pcm_substream_t * substream)
+static int snd_es1938_playback2_prepare(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int u, is8, mono;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -756,7 +756,7 @@
 	return 0;
 }
 
-static int snd_es1938_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_es1938_playback_prepare(struct snd_pcm_substream *substream)
 {
 	switch (substream->number) {
 	case 0:
@@ -768,9 +768,9 @@
 	return -EINVAL;
 }
 
-static snd_pcm_uframes_t snd_es1938_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_es1938_capture_pointer(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	size_t old, new;
 #if 1
@@ -785,9 +785,9 @@
 	return ptr >> chip->dma1_shift;
 }
 
-static snd_pcm_uframes_t snd_es1938_playback1_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_es1938_playback1_pointer(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 #if 1
 	ptr = chip->dma2_size - inw(SLIO_REG(chip, AUDIO2DMACOUNT));
@@ -797,9 +797,9 @@
 	return ptr >> chip->dma2_shift;
 }
 
-static snd_pcm_uframes_t snd_es1938_playback2_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_es1938_playback2_pointer(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	size_t old, new;
 #if 1
@@ -814,7 +814,7 @@
 	return ptr >> chip->dma1_shift;
 }
 
-static snd_pcm_uframes_t snd_es1938_playback_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_es1938_playback_pointer(struct snd_pcm_substream *substream)
 {
 	switch (substream->number) {
 	case 0:
@@ -826,14 +826,14 @@
 	return -EINVAL;
 }
 
-static int snd_es1938_capture_copy(snd_pcm_substream_t *substream,
+static int snd_es1938_capture_copy(struct snd_pcm_substream *substream,
 				   int channel,
 				   snd_pcm_uframes_t pos,
 				   void __user *dst,
 				   snd_pcm_uframes_t count)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	es1938_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
 	pos <<= chip->dma1_shift;
 	count <<= chip->dma1_shift;
 	snd_assert(pos + count <= chip->dma1_size, return -EINVAL);
@@ -852,8 +852,8 @@
 /*
  * buffer management
  */
-static int snd_es1938_pcm_hw_params(snd_pcm_substream_t *substream,
-				    snd_pcm_hw_params_t * hw_params)
+static int snd_es1938_pcm_hw_params(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *hw_params)
 
 {
 	int err;
@@ -863,7 +863,7 @@
 	return 0;
 }
 
-static int snd_es1938_pcm_hw_free(snd_pcm_substream_t *substream)
+static int snd_es1938_pcm_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
@@ -871,11 +871,12 @@
 /* ----------------------------------------------------------------------
  * Audio1 Capture (ADC)
  * ----------------------------------------------------------------------*/
-static snd_pcm_hardware_t snd_es1938_capture =
+static struct snd_pcm_hardware snd_es1938_capture =
 {
 	.info =			(SNDRV_PCM_INFO_INTERLEAVED |
 				SNDRV_PCM_INFO_BLOCK_TRANSFER),
-	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE,
+	.formats =		(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
+				 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		6000,
 	.rate_max =		48000,
@@ -892,12 +893,13 @@
 /* -----------------------------------------------------------------------
  * Audio2 Playback (DAC)
  * -----------------------------------------------------------------------*/
-static snd_pcm_hardware_t snd_es1938_playback =
+static struct snd_pcm_hardware snd_es1938_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID),
-	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE,
+	.formats =		(SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE |
+				 SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE),
 	.rates =		SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
 	.rate_min =		6000,
 	.rate_max =		48000,
@@ -911,10 +913,10 @@
 	.fifo_size =		256,
 };
 
-static int snd_es1938_capture_open(snd_pcm_substream_t * substream)
+static int snd_es1938_capture_open(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (chip->playback2_substream)
 		return -EAGAIN;
@@ -926,10 +928,10 @@
 	return 0;
 }
 
-static int snd_es1938_playback_open(snd_pcm_substream_t * substream)
+static int snd_es1938_playback_open(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	switch (substream->number) {
 	case 0:
@@ -951,17 +953,17 @@
 	return 0;
 }
 
-static int snd_es1938_capture_close(snd_pcm_substream_t * substream)
+static int snd_es1938_capture_close(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
 
 	chip->capture_substream = NULL;
 	return 0;
 }
 
-static int snd_es1938_playback_close(snd_pcm_substream_t * substream)
+static int snd_es1938_playback_close(struct snd_pcm_substream *substream)
 {
-	es1938_t *chip = snd_pcm_substream_chip(substream);
+	struct es1938 *chip = snd_pcm_substream_chip(substream);
 
 	switch (substream->number) {
 	case 0:
@@ -977,7 +979,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_es1938_playback_ops = {
+static struct snd_pcm_ops snd_es1938_playback_ops = {
 	.open =		snd_es1938_playback_open,
 	.close =	snd_es1938_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -988,7 +990,7 @@
 	.pointer =	snd_es1938_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_es1938_capture_ops = {
+static struct snd_pcm_ops snd_es1938_capture_ops = {
 	.open =		snd_es1938_capture_open,
 	.close =	snd_es1938_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1000,14 +1002,9 @@
 	.copy =		snd_es1938_capture_copy,
 };
 
-static void snd_es1938_free_pcm(snd_pcm_t *pcm)
+static int __devinit snd_es1938_new_pcm(struct es1938 *chip, int device)
 {
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_es1938_new_pcm(es1938_t *chip, int device)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(chip->card, "es-1938-1946", device, 2, 1, &pcm)) < 0)
@@ -1016,7 +1013,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_es1938_capture_ops);
 	
 	pcm->private_data = chip;
-	pcm->private_free = snd_es1938_free_pcm;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "ESS Solo-1");
 
@@ -1032,7 +1028,8 @@
  *                       *** Mixer part ***
  */
 
-static int snd_es1938_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es1938_info_mux(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[8] = {
 		"Mic", "Mic Master", "CD", "AOUT",
@@ -1048,16 +1045,18 @@
 	return 0;
 }
 
-static int snd_es1938_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_get_mux(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.enumerated.item[0] = snd_es1938_mixer_read(chip, 0x1c) & 0x07;
 	return 0;
 }
 
-static int snd_es1938_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_put_mux(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned char val = ucontrol->value.enumerated.item[0];
 	
 	if (val > 7)
@@ -1065,7 +1064,8 @@
 	return snd_es1938_mixer_bits(chip, 0x1c, 0x07, val) != val;
 }
 
-static int snd_es1938_info_spatializer_enable(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es1938_info_spatializer_enable(struct snd_kcontrol *kcontrol,
+					      struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1074,17 +1074,19 @@
 	return 0;
 }
 
-static int snd_es1938_get_spatializer_enable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_get_spatializer_enable(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned char val = snd_es1938_mixer_read(chip, 0x50);
 	ucontrol->value.integer.value[0] = !!(val & 8);
 	return 0;
 }
 
-static int snd_es1938_put_spatializer_enable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_put_spatializer_enable(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned char oval, nval;
 	int change;
 	nval = ucontrol->value.integer.value[0] ? 0x0c : 0x04;
@@ -1097,7 +1099,8 @@
 	return change;
 }
 
-static int snd_es1938_info_hw_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es1938_info_hw_volume(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -1106,15 +1109,17 @@
 	return 0;
 }
 
-static int snd_es1938_get_hw_volume(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_get_hw_volume(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = snd_es1938_mixer_read(chip, 0x61) & 0x3f;
 	ucontrol->value.integer.value[1] = snd_es1938_mixer_read(chip, 0x63) & 0x3f;
 	return 0;
 }
 
-static int snd_es1938_info_hw_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es1938_info_hw_switch(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -1123,24 +1128,25 @@
 	return 0;
 }
 
-static int snd_es1938_get_hw_switch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_get_hw_switch(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = !(snd_es1938_mixer_read(chip, 0x61) & 0x40);
 	ucontrol->value.integer.value[1] = !(snd_es1938_mixer_read(chip, 0x63) & 0x40);
 	return 0;
 }
 
-static void snd_es1938_hwv_free(snd_kcontrol_t *kcontrol)
+static void snd_es1938_hwv_free(struct snd_kcontrol *kcontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	chip->master_volume = NULL;
 	chip->master_switch = NULL;
 	chip->hw_volume = NULL;
 	chip->hw_switch = NULL;
 }
 
-static int snd_es1938_reg_bits(es1938_t *chip, unsigned char reg,
+static int snd_es1938_reg_bits(struct es1938 *chip, unsigned char reg,
 			       unsigned char mask, unsigned char val)
 {
 	if (reg < 0xa0)
@@ -1149,7 +1155,7 @@
 		return snd_es1938_bits(chip, reg, mask, val);
 }
 
-static int snd_es1938_reg_read(es1938_t *chip, unsigned char reg)
+static int snd_es1938_reg_read(struct es1938 *chip, unsigned char reg)
 {
 	if (reg < 0xa0)
 		return snd_es1938_mixer_read(chip, reg);
@@ -1163,7 +1169,8 @@
   .get = snd_es1938_get_single, .put = snd_es1938_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_es1938_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es1938_info_single(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -1174,9 +1181,10 @@
 	return 0;
 }
 
-static int snd_es1938_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_get_single(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -1190,9 +1198,10 @@
 	return 0;
 }
 
-static int snd_es1938_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_put_single(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -1213,7 +1222,8 @@
   .get = snd_es1938_get_double, .put = snd_es1938_put_double, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-static int snd_es1938_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_es1938_info_double(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -1224,9 +1234,10 @@
 	return 0;
 }
 
-static int snd_es1938_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_get_double(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1249,9 +1260,10 @@
 	return 0;
 }
 
-static int snd_es1938_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_es1938_put_double(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	es1938_t *chip = snd_kcontrol_chip(kcontrol);
+	struct es1938 *chip = snd_kcontrol_chip(kcontrol);
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1284,7 +1296,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_es1938_controls[] = {
+static struct snd_kcontrol_new snd_es1938_controls[] = {
 ES1938_DOUBLE("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0),
 ES1938_DOUBLE("Master Playback Switch", 0, 0x60, 0x62, 6, 6, 1, 1),
 {
@@ -1347,7 +1359,7 @@
 /*
  * initialize the chip - used by resume callback, too
  */
-static void snd_es1938_chip_init(es1938_t *chip)
+static void snd_es1938_chip_init(struct es1938 *chip)
 {
 	/* reset chip */
 	snd_es1938_reset(chip);
@@ -1386,11 +1398,13 @@
 };
 
 
-static int es1938_suspend(snd_card_t *card, pm_message_t state)
+static int es1938_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	es1938_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct es1938 *chip = card->private_data;
 	unsigned char *s, *d;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 
 	/* save mixer-related registers */
@@ -1399,20 +1413,23 @@
 
 	outb(0x00, SLIO_REG(chip, IRQCONTROL)); /* disable irqs */
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);  
-	pci_disable_device(chip->pci);
+		free_irq(chip->irq, chip);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int es1938_resume(snd_card_t *card)
+static int es1938_resume(struct pci_dev *pci)
 {
-	es1938_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct es1938 *chip = card->private_data;
 	unsigned char *s, *d;
 
-	pci_enable_device(chip->pci);
-	request_irq(chip->pci->irq, snd_es1938_interrupt,
-		    SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip);
-	chip->irq = chip->pci->irq;
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	request_irq(pci->irq, snd_es1938_interrupt,
+		    SA_INTERRUPT|SA_SHIRQ, "ES1938", chip);
+	chip->irq = pci->irq;
 	snd_es1938_chip_init(chip);
 
 	/* restore mixer-related registers */
@@ -1423,12 +1440,13 @@
 			snd_es1938_write(chip, *s, *d);
 	}
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_es1938_create_gameport(es1938_t *chip)
+static int __devinit snd_es1938_create_gameport(struct es1938 *chip)
 {
 	struct gameport *gp;
 
@@ -1448,7 +1466,7 @@
 	return 0;
 }
 
-static void snd_es1938_free_gameport(es1938_t *chip)
+static void snd_es1938_free_gameport(struct es1938 *chip)
 {
 	if (chip->gameport) {
 		gameport_unregister_port(chip->gameport);
@@ -1456,11 +1474,11 @@
 	}
 }
 #else
-static inline int snd_es1938_create_gameport(es1938_t *chip) { return -ENOSYS; }
-static inline void snd_es1938_free_gameport(es1938_t *chip) { }
+static inline int snd_es1938_create_gameport(struct es1938 *chip) { return -ENOSYS; }
+static inline void snd_es1938_free_gameport(struct es1938 *chip) { }
 #endif /* SUPPORT_JOYSTICK */
 
-static int snd_es1938_free(es1938_t *chip)
+static int snd_es1938_free(struct es1938 *chip)
 {
 	/* disable irqs */
 	outb(0x00, SLIO_REG(chip, IRQCONTROL));
@@ -1470,26 +1488,26 @@
 	snd_es1938_free_gameport(chip);
 
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
 	kfree(chip);
 	return 0;
 }
 
-static int snd_es1938_dev_free(snd_device_t *device)
+static int snd_es1938_dev_free(struct snd_device *device)
 {
-	es1938_t *chip = device->device_data;
+	struct es1938 *chip = device->device_data;
 	return snd_es1938_free(chip);
 }
 
-static int __devinit snd_es1938_create(snd_card_t * card,
+static int __devinit snd_es1938_create(struct snd_card *card,
 				    struct pci_dev * pci,
-				    es1938_t ** rchip)
+				    struct es1938 ** rchip)
 {
-	es1938_t *chip;
+	struct es1938 *chip;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_es1938_dev_free,
 	};
 
@@ -1525,7 +1543,8 @@
 	chip->vc_port = pci_resource_start(pci, 2);
 	chip->mpu_port = pci_resource_start(pci, 3);
 	chip->game_port = pci_resource_start(pci, 4);
-	if (request_irq(pci->irq, snd_es1938_interrupt, SA_INTERRUPT|SA_SHIRQ, "ES1938", (void *)chip)) {
+	if (request_irq(pci->irq, snd_es1938_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			"ES1938", chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_es1938_free(chip);
 		return -EBUSY;
@@ -1540,8 +1559,6 @@
 
 	snd_es1938_chip_init(chip);
 
-	snd_card_set_pm_callback(card, es1938_suspend, es1938_resume, chip);
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_es1938_free(chip);
 		return err;
@@ -1558,7 +1575,7 @@
  * -------------------------------------------------------------------- */
 static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	es1938_t *chip = dev_id;
+	struct es1938 *chip = dev_id;
 	unsigned char status, audiostatus;
 	int handled = 0;
 
@@ -1571,9 +1588,12 @@
 	if (status & 0x10) {
 #if 0
                 printk("Es1938debug - AUDIO channel 1 interrupt\n");
-		printk("Es1938debug - AUDIO channel 1 DMAC DMA count: %u\n", inw(SLDM_REG(chip, DMACOUNT)));
-		printk("Es1938debug - AUDIO channel 1 DMAC DMA base: %u\n", inl(SLDM_REG(chip, DMAADDR)));
-		printk("Es1938debug - AUDIO channel 1 DMAC DMA status: 0x%x\n", inl(SLDM_REG(chip, DMASTATUS)));
+		printk("Es1938debug - AUDIO channel 1 DMAC DMA count: %u\n",
+		       inw(SLDM_REG(chip, DMACOUNT)));
+		printk("Es1938debug - AUDIO channel 1 DMAC DMA base: %u\n",
+		       inl(SLDM_REG(chip, DMAADDR)));
+		printk("Es1938debug - AUDIO channel 1 DMAC DMA status: 0x%x\n",
+		       inl(SLDM_REG(chip, DMASTATUS)));
 #endif
 		/* clear irq */
 		handled = 1;
@@ -1588,8 +1608,10 @@
 	if (status & 0x20) {
 #if 0
                 printk("Es1938debug - AUDIO channel 2 interrupt\n");
-		printk("Es1938debug - AUDIO channel 2 DMAC DMA count: %u\n", inw(SLIO_REG(chip, AUDIO2DMACOUNT)));
-		printk("Es1938debug - AUDIO channel 2 DMAC DMA base: %u\n", inl(SLIO_REG(chip, AUDIO2DMAADDR)));
+		printk("Es1938debug - AUDIO channel 2 DMAC DMA count: %u\n",
+		       inw(SLIO_REG(chip, AUDIO2DMACOUNT)));
+		printk("Es1938debug - AUDIO channel 2 DMAC DMA base: %u\n",
+		       inl(SLIO_REG(chip, AUDIO2DMAADDR)));
 
 #endif
 		/* clear irq */
@@ -1606,8 +1628,10 @@
 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_switch->id);
 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->hw_volume->id);
 		if (!split) {
-			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_switch->id);
-			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->master_volume->id);
+			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+				       &chip->master_switch->id);
+			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+				       &chip->master_volume->id);
 		}
 		/* ack interrupt */
 		snd_es1938_mixer_write(chip, 0x66, 0x00);
@@ -1629,9 +1653,9 @@
 
 #define ES1938_DMA_SIZE 64
 
-static int __devinit snd_es1938_mixer(es1938_t *chip)
+static int __devinit snd_es1938_mixer(struct es1938 *chip)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	unsigned int idx;
 	int err;
 
@@ -1640,7 +1664,7 @@
 	strcpy(card->mixername, "ESS Solo-1");
 
 	for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {
-		snd_kcontrol_t *kctl;
+		struct snd_kcontrol *kctl;
 		kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);
 		switch (idx) {
 			case 0:
@@ -1671,9 +1695,9 @@
 				      const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	es1938_t *chip;
-	opl3_t *opl3;
+	struct snd_card *card;
+	struct es1938 *chip;
+	struct snd_opl3 *opl3;
 	int idx, err;
 
 	if (dev >= SNDRV_CARDS)
@@ -1697,6 +1721,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 
 	strcpy(card->driver, "ES1938");
 	strcpy(card->shortname, "ESS ES1938 (Solo-1)");
@@ -1761,7 +1786,10 @@
 	.id_table = snd_es1938_ids,
 	.probe = snd_es1938_probe,
 	.remove = __devexit_p(snd_es1938_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = es1938_suspend,
+	.resume = es1938_resume,
+#endif
 };
 
 static int __init alsa_card_es1938_init(void)
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 50079dc..9ffb600 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -176,7 +176,7 @@
 
 /* Values for the ESM_LEGACY_AUDIO_CONTROL */
 
-#define ESS_ENABLE_AUDIO	0x8000
+#define ESS_DISABLE_AUDIO	0x8000
 #define ESS_ENABLE_SERIAL_IRQ	0x4000
 #define IO_ADRESS_ALIAS		0x0020
 #define MPU401_IRQ_ENABLE	0x0010
@@ -195,7 +195,7 @@
 #define DMA_TDMA		0x0100
 #define DMA_PCPCI		0x0200
 #define POST_WRITE		0x0080
-#define ISA_TIMING		0x0040
+#define PCI_TIMING		0x0040
 #define SWAP_LR			0x0020
 #define SUBTR_DECODE		0x0002
 
@@ -470,10 +470,6 @@
 };
 
 
-typedef struct snd_es1968 es1968_t;
-typedef struct snd_esschan esschan_t;
-typedef struct snd_esm_memory esm_memory_t;
-
 /* APU use in the driver */
 enum snd_enum_apu_type {
 	ESM_APU_PCM_PLAY,
@@ -488,23 +484,23 @@
 };
 
 /* DMA Hack! */
-struct snd_esm_memory {
+struct esm_memory {
 	struct snd_dma_buffer buf;
 	int empty;	/* status */
 	struct list_head list;
 };
 
 /* Playback Channel */
-struct snd_esschan {
+struct esschan {
 	int running;
 
 	u8 apu[4];
 	u8 apu_mode[4];
 
 	/* playback/capture pcm buffer */
-	esm_memory_t *memory;
+	struct esm_memory *memory;
 	/* capture mixer buffer */
-	esm_memory_t *mixbuf;
+	struct esm_memory *mixbuf;
 
 	unsigned int hwptr;	/* current hw pointer in bytes */
 	unsigned int count;	/* sample counter in bytes */
@@ -519,7 +515,7 @@
 
 	int bob_freq;	/* required timer frequency */
 
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 
 	/* linked list */
 	struct list_head list;
@@ -529,7 +525,7 @@
 #endif
 };
 
-struct snd_es1968 {
+struct es1968 {
 	/* Module Config */
 	int total_bufsize;			/* in bytes */
 
@@ -550,19 +546,19 @@
 	unsigned long io_port;
 	int type;
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
 	int do_pm;		/* power-management enabled */
 
 	/* DMA memory block */
 	struct list_head buf_list;
 
 	/* ALSA Stuff */
-	ac97_t *ac97;
-	snd_kcontrol_t *master_switch; /* for h/w volume control */
-	snd_kcontrol_t *master_volume;
+	struct snd_ac97 *ac97;
+	struct snd_kcontrol *master_switch; /* for h/w volume control */
+	struct snd_kcontrol *master_volume;
 
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 
 	spinlock_t reg_lock;
 	spinlock_t ac97_lock;
@@ -610,14 +606,14 @@
    *********************/
 
 /* no spinlock */
-static void __maestro_write(es1968_t *chip, u16 reg, u16 data)
+static void __maestro_write(struct es1968 *chip, u16 reg, u16 data)
 {
 	outw(reg, chip->io_port + ESM_INDEX);
 	outw(data, chip->io_port + ESM_DATA);
 	chip->maestro_map[reg] = data;
 }
 
-static inline void maestro_write(es1968_t *chip, u16 reg, u16 data)
+static inline void maestro_write(struct es1968 *chip, u16 reg, u16 data)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -626,7 +622,7 @@
 }
 
 /* no spinlock */
-static u16 __maestro_read(es1968_t *chip, u16 reg)
+static u16 __maestro_read(struct es1968 *chip, u16 reg)
 {
 	if (READABLE_MAP & (1 << reg)) {
 		outw(reg, chip->io_port + ESM_INDEX);
@@ -635,7 +631,7 @@
 	return chip->maestro_map[reg];
 }
 
-static inline u16 maestro_read(es1968_t *chip, u16 reg)
+static inline u16 maestro_read(struct es1968 *chip, u16 reg)
 {
 	unsigned long flags;
 	u16 result;
@@ -646,7 +642,7 @@
 }
 
 /* Wait for the codec bus to be free */
-static int snd_es1968_ac97_wait(es1968_t *chip)
+static int snd_es1968_ac97_wait(struct es1968 *chip)
 {
 	int timeout = 100000;
 
@@ -659,9 +655,9 @@
 	return 1; /* timeout */
 }
 
-static void snd_es1968_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
-	es1968_t *chip = ac97->private_data;
+	struct es1968 *chip = ac97->private_data;
 	unsigned long flags;
 
 	snd_es1968_ac97_wait(chip);
@@ -675,10 +671,10 @@
 	spin_unlock_irqrestore(&chip->ac97_lock, flags);
 }
 
-static unsigned short snd_es1968_ac97_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
 	u16 data = 0;
-	es1968_t *chip = ac97->private_data;
+	struct es1968 *chip = ac97->private_data;
 	unsigned long flags;
 
 	snd_es1968_ac97_wait(chip);
@@ -697,7 +693,7 @@
 }
 
 /* no spinlock */
-static void apu_index_set(es1968_t *chip, u16 index)
+static void apu_index_set(struct es1968 *chip, u16 index)
 {
 	int i;
 	__maestro_write(chip, IDR1_CRAM_POINTER, index);
@@ -708,7 +704,7 @@
 }
 
 /* no spinlock */
-static void apu_data_set(es1968_t *chip, u16 data)
+static void apu_data_set(struct es1968 *chip, u16 data)
 {
 	int i;
 	for (i = 0; i < 1000; i++) {
@@ -720,7 +716,7 @@
 }
 
 /* no spinlock */
-static void __apu_set_register(es1968_t *chip, u16 channel, u8 reg, u16 data)
+static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
 {
 	snd_assert(channel < NR_APUS, return);
 #ifdef CONFIG_PM
@@ -731,7 +727,7 @@
 	apu_data_set(chip, data);
 }
 
-static inline void apu_set_register(es1968_t *chip, u16 channel, u8 reg, u16 data)
+static inline void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&chip->reg_lock, flags);
@@ -739,7 +735,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static u16 __apu_get_register(es1968_t *chip, u16 channel, u8 reg)
+static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
 {
 	snd_assert(channel < NR_APUS, return 0);
 	reg |= (channel << 4);
@@ -747,7 +743,7 @@
 	return __maestro_read(chip, IDR0_DATA_PORT);
 }
 
-static inline u16 apu_get_register(es1968_t *chip, u16 channel, u8 reg)
+static inline u16 apu_get_register(struct es1968 *chip, u16 channel, u8 reg)
 {
 	unsigned long flags;
 	u16 v;
@@ -759,7 +755,7 @@
 
 #if 0 /* ASSP is not supported */
 
-static void assp_set_register(es1968_t *chip, u32 reg, u32 value)
+static void assp_set_register(struct es1968 *chip, u32 reg, u32 value)
 {
 	unsigned long flags;
 
@@ -769,7 +765,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static u32 assp_get_register(es1968_t *chip, u32 reg)
+static u32 assp_get_register(struct es1968 *chip, u32 reg)
 {
 	unsigned long flags;
 	u32 value;
@@ -784,7 +780,7 @@
 
 #endif
 
-static void wave_set_register(es1968_t *chip, u16 reg, u16 value)
+static void wave_set_register(struct es1968 *chip, u16 reg, u16 value)
 {
 	unsigned long flags;
 
@@ -794,7 +790,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static u16 wave_get_register(es1968_t *chip, u16 reg)
+static u16 wave_get_register(struct es1968 *chip, u16 reg)
 {
 	unsigned long flags;
 	u16 value;
@@ -811,7 +807,7 @@
    * Bob the Timer!  *
    *******************/
 
-static void snd_es1968_bob_stop(es1968_t *chip)
+static void snd_es1968_bob_stop(struct es1968 *chip)
 {
 	u16 reg;
 
@@ -823,7 +819,7 @@
 	__maestro_write(chip, 0x17, reg);
 }
 
-static void snd_es1968_bob_start(es1968_t *chip)
+static void snd_es1968_bob_start(struct es1968 *chip)
 {
 	int prescale;
 	int divide;
@@ -863,7 +859,7 @@
 }
 
 /* call with substream spinlock */
-static void snd_es1968_bob_inc(es1968_t *chip, int freq)
+static void snd_es1968_bob_inc(struct es1968 *chip, int freq)
 {
 	chip->bobclient++;
 	if (chip->bobclient == 1) {
@@ -877,7 +873,7 @@
 }
 
 /* call with substream spinlock */
-static void snd_es1968_bob_dec(es1968_t *chip)
+static void snd_es1968_bob_dec(struct es1968 *chip)
 {
 	chip->bobclient--;
 	if (chip->bobclient <= 0)
@@ -887,7 +883,7 @@
 		struct list_head *p;
 		int max_freq = ESM_BOB_FREQ;
 		list_for_each(p, &chip->substream_list) {
-			esschan_t *es = list_entry(p, esschan_t, list);
+			struct esschan *es = list_entry(p, struct esschan, list);
 			if (max_freq < es->bob_freq)
 				max_freq = es->bob_freq;
 		}
@@ -900,8 +896,8 @@
 }
 
 static int
-snd_es1968_calc_bob_rate(es1968_t *chip, esschan_t *es,
-			 snd_pcm_runtime_t *runtime)
+snd_es1968_calc_bob_rate(struct es1968 *chip, struct esschan *es,
+			 struct snd_pcm_runtime *runtime)
 {
 	/* we acquire 4 interrupts per period for precise control.. */
 	int freq = runtime->rate * 4;
@@ -922,7 +918,7 @@
  *  PCM Part *
  *************/
 
-static u32 snd_es1968_compute_rate(es1968_t *chip, u32 freq)
+static u32 snd_es1968_compute_rate(struct es1968 *chip, u32 freq)
 {
 	u32 rate = (freq << 16) / chip->clock;
 #if 0 /* XXX: do we need this? */ 
@@ -934,7 +930,7 @@
 
 /* get current pointer */
 static inline unsigned int
-snd_es1968_get_dma_ptr(es1968_t *chip, esschan_t *es)
+snd_es1968_get_dma_ptr(struct es1968 *chip, struct esschan *es)
 {
 	unsigned int offset;
 
@@ -945,7 +941,7 @@
 	return (offset & 0xFFFE);	/* hardware is in words */
 }
 
-static void snd_es1968_apu_set_freq(es1968_t *chip, int apu, int freq)
+static void snd_es1968_apu_set_freq(struct es1968 *chip, int apu, int freq)
 {
 	apu_set_register(chip, apu, 2,
 			   (apu_get_register(chip, apu, 2) & 0x00FF) |
@@ -954,7 +950,7 @@
 }
 
 /* spin lock held */
-static inline void snd_es1968_trigger_apu(es1968_t *esm, int apu, int mode)
+static inline void snd_es1968_trigger_apu(struct es1968 *esm, int apu, int mode)
 {
 	/* set the APU mode */
 	__apu_set_register(esm, apu, 0,
@@ -962,7 +958,7 @@
 			   (mode << 4));
 }
 
-static void snd_es1968_pcm_start(es1968_t *chip, esschan_t *es)
+static void snd_es1968_pcm_start(struct es1968 *chip, struct esschan *es)
 {
 	spin_lock(&chip->reg_lock);
 	__apu_set_register(chip, es->apu[0], 5, es->base[0]);
@@ -982,7 +978,7 @@
 	spin_unlock(&chip->reg_lock);
 }
 
-static void snd_es1968_pcm_stop(es1968_t *chip, esschan_t *es)
+static void snd_es1968_pcm_stop(struct es1968 *chip, struct esschan *es)
 {
 	spin_lock(&chip->reg_lock);
 	snd_es1968_trigger_apu(chip, es->apu[0], 0);
@@ -995,7 +991,7 @@
 }
 
 /* set the wavecache control reg */
-static void snd_es1968_program_wavecache(es1968_t *chip, esschan_t *es,
+static void snd_es1968_program_wavecache(struct es1968 *chip, struct esschan *es,
 					 int channel, u32 addr, int capture)
 {
 	u32 tmpval = (addr - 0x10) & 0xFFF8;
@@ -1016,8 +1012,8 @@
 }
 
 
-static void snd_es1968_playback_setup(es1968_t *chip, esschan_t *es,
-				      snd_pcm_runtime_t *runtime)
+static void snd_es1968_playback_setup(struct es1968 *chip, struct esschan *es,
+				      struct snd_pcm_runtime *runtime)
 {
 	u32 pa;
 	int high_apu = 0;
@@ -1119,7 +1115,7 @@
 }
 
 
-static void init_capture_apu(es1968_t *chip, esschan_t *es, int channel,
+static void init_capture_apu(struct es1968 *chip, struct esschan *es, int channel,
 			     unsigned int pa, unsigned int bsize,
 			     int mode, int route)
 {
@@ -1164,8 +1160,8 @@
 	apu_set_register(chip, apu, 0, 0x400F);
 }
 
-static void snd_es1968_capture_setup(es1968_t *chip, esschan_t *es,
-				     snd_pcm_runtime_t *runtime)
+static void snd_es1968_capture_setup(struct es1968 *chip, struct esschan *es,
+				     struct snd_pcm_runtime *runtime)
 {
 	int size;
 	u32 freq;
@@ -1233,11 +1229,11 @@
  *  ALSA Interface *
  *******************/
 
-static int snd_es1968_pcm_prepare(snd_pcm_substream_t *substream)
+static int snd_es1968_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	es1968_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	esschan_t *es = runtime->private_data;
+	struct es1968 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct esschan *es = runtime->private_data;
 
 	es->dma_size = snd_pcm_lib_buffer_bytes(substream);
 	es->frag_size = snd_pcm_lib_period_bytes(substream);
@@ -1265,10 +1261,10 @@
 	return 0;
 }
 
-static int snd_es1968_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_es1968_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	es1968_t *chip = snd_pcm_substream_chip(substream);
-	esschan_t *es = substream->runtime->private_data;
+	struct es1968 *chip = snd_pcm_substream_chip(substream);
+	struct esschan *es = substream->runtime->private_data;
 
 	spin_lock(&chip->substream_lock);
 	switch (cmd) {
@@ -1295,10 +1291,10 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_es1968_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_es1968_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	es1968_t *chip = snd_pcm_substream_chip(substream);
-	esschan_t *es = substream->runtime->private_data;
+	struct es1968 *chip = snd_pcm_substream_chip(substream);
+	struct esschan *es = substream->runtime->private_data;
 	unsigned int ptr;
 
 	ptr = snd_es1968_get_dma_ptr(chip, es) << es->wav_shift;
@@ -1306,7 +1302,7 @@
 	return bytes_to_frames(substream->runtime, ptr % es->dma_size);
 }
 
-static snd_pcm_hardware_t snd_es1968_playback = {
+static struct snd_pcm_hardware snd_es1968_playback = {
 	.info =			(SNDRV_PCM_INFO_MMAP |
                		         SNDRV_PCM_INFO_MMAP_VALID |
 				 SNDRV_PCM_INFO_INTERLEAVED |
@@ -1327,7 +1323,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_es1968_capture = {
+static struct snd_pcm_hardware snd_es1968_capture = {
 	.info =			(SNDRV_PCM_INFO_NONINTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_MMAP_VALID |
@@ -1355,14 +1351,14 @@
 /* Because the Maestro can only take addresses relative to the PCM base address
    register :( */
 
-static int calc_available_memory_size(es1968_t *chip)
+static int calc_available_memory_size(struct es1968 *chip)
 {
 	struct list_head *p;
 	int max_size = 0;
 	
 	down(&chip->memory_mutex);
 	list_for_each(p, &chip->buf_list) {
-		esm_memory_t *buf = list_entry(p, esm_memory_t, list);
+		struct esm_memory *buf = list_entry(p, struct esm_memory, list);
 		if (buf->empty && buf->buf.bytes > max_size)
 			max_size = buf->buf.bytes;
 	}
@@ -1373,15 +1369,15 @@
 }
 
 /* allocate a new memory chunk with the specified size */
-static esm_memory_t *snd_es1968_new_memory(es1968_t *chip, int size)
+static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size)
 {
-	esm_memory_t *buf;
+	struct esm_memory *buf;
 	struct list_head *p;
 	
 	size = ((size + ESM_MEM_ALIGN - 1) / ESM_MEM_ALIGN) * ESM_MEM_ALIGN;
 	down(&chip->memory_mutex);
 	list_for_each(p, &chip->buf_list) {
-		buf = list_entry(p, esm_memory_t, list);
+		buf = list_entry(p, struct esm_memory, list);
 		if (buf->empty && buf->buf.bytes >= size)
 			goto __found;
 	}
@@ -1390,7 +1386,7 @@
 
 __found:
 	if (buf->buf.bytes > size) {
-		esm_memory_t *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL);
+		struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL);
 		if (chunk == NULL) {
 			up(&chip->memory_mutex);
 			return NULL;
@@ -1409,14 +1405,14 @@
 }
 
 /* free a memory chunk */
-static void snd_es1968_free_memory(es1968_t *chip, esm_memory_t *buf)
+static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf)
 {
-	esm_memory_t *chunk;
+	struct esm_memory *chunk;
 
 	down(&chip->memory_mutex);
 	buf->empty = 1;
 	if (buf->list.prev != &chip->buf_list) {
-		chunk = list_entry(buf->list.prev, esm_memory_t, list);
+		chunk = list_entry(buf->list.prev, struct esm_memory, list);
 		if (chunk->empty) {
 			chunk->buf.bytes += buf->buf.bytes;
 			list_del(&buf->list);
@@ -1425,7 +1421,7 @@
 		}
 	}
 	if (buf->list.next != &chip->buf_list) {
-		chunk = list_entry(buf->list.next, esm_memory_t, list);
+		chunk = list_entry(buf->list.next, struct esm_memory, list);
 		if (chunk->empty) {
 			buf->buf.bytes += chunk->buf.bytes;
 			list_del(&chunk->list);
@@ -1435,7 +1431,7 @@
 	up(&chip->memory_mutex);
 }
 
-static void snd_es1968_free_dmabuf(es1968_t *chip)
+static void snd_es1968_free_dmabuf(struct es1968 *chip)
 {
 	struct list_head *p;
 
@@ -1443,17 +1439,17 @@
 		return;
 	snd_dma_reserve_buf(&chip->dma, snd_dma_pci_buf_id(chip->pci));
 	while ((p = chip->buf_list.next) != &chip->buf_list) {
-		esm_memory_t *chunk = list_entry(p, esm_memory_t, list);
+		struct esm_memory *chunk = list_entry(p, struct esm_memory, list);
 		list_del(p);
 		kfree(chunk);
 	}
 }
 
 static int __devinit
-snd_es1968_init_dmabuf(es1968_t *chip)
+snd_es1968_init_dmabuf(struct es1968 *chip)
 {
 	int err;
-	esm_memory_t *chunk;
+	struct esm_memory *chunk;
 
 	chip->dma.dev.type = SNDRV_DMA_TYPE_DEV;
 	chip->dma.dev.dev = snd_dma_pci_data(chip->pci);
@@ -1493,12 +1489,12 @@
 
 /* setup the dma_areas */
 /* buffer is extracted from the pre-allocated memory chunk */
-static int snd_es1968_hw_params(snd_pcm_substream_t *substream,
-				snd_pcm_hw_params_t *hw_params)
+static int snd_es1968_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *hw_params)
 {
-	es1968_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	esschan_t *chan = runtime->private_data;
+	struct es1968 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct esschan *chan = runtime->private_data;
 	int size = params_buffer_bytes(hw_params);
 
 	if (chan->memory) {
@@ -1518,11 +1514,11 @@
 }
 
 /* remove dma areas if allocated */
-static int snd_es1968_hw_free(snd_pcm_substream_t * substream)
+static int snd_es1968_hw_free(struct snd_pcm_substream *substream)
 {
-	es1968_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	esschan_t *chan;
+	struct es1968 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct esschan *chan;
 	
 	if (runtime->private_data == NULL)
 		return 0;
@@ -1538,7 +1534,7 @@
 /*
  * allocate APU pair
  */
-static int snd_es1968_alloc_apu_pair(es1968_t *chip, int type)
+static int snd_es1968_alloc_apu_pair(struct es1968 *chip, int type)
 {
 	int apu;
 
@@ -1555,7 +1551,7 @@
 /*
  * release APU pair
  */
-static void snd_es1968_free_apu_pair(es1968_t *chip, int apu)
+static void snd_es1968_free_apu_pair(struct es1968 *chip, int apu)
 {
 	chip->apu[apu] = chip->apu[apu + 1] = ESM_APU_FREE;
 }
@@ -1565,11 +1561,11 @@
  * PCM open/close *
  ******************/
 
-static int snd_es1968_playback_open(snd_pcm_substream_t *substream)
+static int snd_es1968_playback_open(struct snd_pcm_substream *substream)
 {
-	es1968_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	esschan_t *es;
+	struct es1968 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct esschan *es;
 	int apu1;
 
 	/* search 2 APUs */
@@ -1606,11 +1602,11 @@
 	return 0;
 }
 
-static int snd_es1968_capture_open(snd_pcm_substream_t *substream)
+static int snd_es1968_capture_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	es1968_t *chip = snd_pcm_substream_chip(substream);
-	esschan_t *es;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct es1968 *chip = snd_pcm_substream_chip(substream);
+	struct esschan *es;
 	int apu1, apu2;
 
 	apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_CAPTURE);
@@ -1665,10 +1661,10 @@
 	return 0;
 }
 
-static int snd_es1968_playback_close(snd_pcm_substream_t * substream)
+static int snd_es1968_playback_close(struct snd_pcm_substream *substream)
 {
-	es1968_t *chip = snd_pcm_substream_chip(substream);
-	esschan_t *es;
+	struct es1968 *chip = snd_pcm_substream_chip(substream);
+	struct esschan *es;
 
 	if (substream->runtime->private_data == NULL)
 		return 0;
@@ -1682,10 +1678,10 @@
 	return 0;
 }
 
-static int snd_es1968_capture_close(snd_pcm_substream_t * substream)
+static int snd_es1968_capture_close(struct snd_pcm_substream *substream)
 {
-	es1968_t *chip = snd_pcm_substream_chip(substream);
-	esschan_t *es;
+	struct es1968 *chip = snd_pcm_substream_chip(substream);
+	struct esschan *es;
 
 	if (substream->runtime->private_data == NULL)
 		return 0;
@@ -1701,7 +1697,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_es1968_playback_ops = {
+static struct snd_pcm_ops snd_es1968_playback_ops = {
 	.open =		snd_es1968_playback_open,
 	.close =	snd_es1968_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1712,7 +1708,7 @@
 	.pointer =	snd_es1968_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_es1968_capture_ops = {
+static struct snd_pcm_ops snd_es1968_capture_ops = {
 	.open =		snd_es1968_capture_open,
 	.close =	snd_es1968_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1729,11 +1725,11 @@
  */
 #define CLOCK_MEASURE_BUFSIZE	16768	/* enough large for a single shot */
 
-static void __devinit es1968_measure_clock(es1968_t *chip)
+static void __devinit es1968_measure_clock(struct es1968 *chip)
 {
 	int i, apu;
 	unsigned int pa, offset, t;
-	esm_memory_t *memory;
+	struct esm_memory *memory;
 	struct timeval start_time, stop_time;
 
 	if (chip->clock == 0)
@@ -1824,17 +1820,17 @@
 /*
  */
 
-static void snd_es1968_pcm_free(snd_pcm_t *pcm)
+static void snd_es1968_pcm_free(struct snd_pcm *pcm)
 {
-	es1968_t *esm = pcm->private_data;
+	struct es1968 *esm = pcm->private_data;
 	snd_es1968_free_dmabuf(esm);
 	esm->pcm = NULL;
 }
 
 static int __devinit
-snd_es1968_pcm(es1968_t *chip, int device)
+snd_es1968_pcm(struct es1968 *chip, int device)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	/* get DMA buffer */
@@ -1870,11 +1866,11 @@
 /*
  * update pointer
  */
-static void snd_es1968_update_pcm(es1968_t *chip, esschan_t *es)
+static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
 {
 	unsigned int hwptr;
 	unsigned int diff;
-	snd_pcm_substream_t *subs = es->substream;
+	struct snd_pcm_substream *subs = es->substream;
         
 	if (subs == NULL || !es->running)
 		return;
@@ -1899,7 +1895,7 @@
  */
 static void es1968_update_hw_volume(unsigned long private_data)
 {
-	es1968_t *chip = (es1968_t *) private_data;
+	struct es1968 *chip = (struct es1968 *) private_data;
 	int x, val;
 	unsigned long flags;
 
@@ -1959,7 +1955,7 @@
  */
 static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	es1968_t *chip = dev_id;
+	struct es1968 *chip = dev_id;
 	u32 event;
 
 	if (!(event = inb(chip->io_port + 0x1A)))
@@ -1981,7 +1977,7 @@
 		struct list_head *p;
 		spin_lock(&chip->substream_lock);
 		list_for_each(p, &chip->substream_list) {
-			esschan_t *es = list_entry(p, esschan_t, list);
+			struct esschan *es = list_entry(p, struct esschan, list);
 			if (es->running)
 				snd_es1968_update_pcm(chip, es);
 		}
@@ -2002,13 +1998,13 @@
  */
 
 static int __devinit
-snd_es1968_mixer(es1968_t *chip)
+snd_es1968_mixer(struct es1968 *chip)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
-	snd_ctl_elem_id_t id;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
+	struct snd_ctl_elem_id id;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_es1968_ac97_write,
 		.read = snd_es1968_ac97_read,
 	};
@@ -2039,7 +2035,7 @@
  * reset ac97 codec
  */
 
-static void snd_es1968_ac97_reset(es1968_t *chip)
+static void snd_es1968_ac97_reset(struct es1968 *chip)
 {
 	unsigned long ioaddr = chip->io_port;
 
@@ -2144,7 +2140,7 @@
 	outb(0x3f, ioaddr+0xd0);
 }
 
-static void snd_es1968_reset(es1968_t *chip)
+static void snd_es1968_reset(struct es1968 *chip)
 {
 	/* Reset */
 	outw(ESM_RESET_MAESTRO | ESM_RESET_DIRECTSOUND,
@@ -2157,7 +2153,7 @@
 /*
  * power management
  */
-static void snd_es1968_set_acpi(es1968_t *chip, int state)
+static void snd_es1968_set_acpi(struct es1968 *chip, int state)
 {
 	u16 active_mask = acpi_state_mask[state];
 
@@ -2172,7 +2168,7 @@
 /*
  * initialize maestro chip
  */
-static void snd_es1968_chip_init(es1968_t *chip)
+static void snd_es1968_chip_init(struct es1968 *chip)
 {
 	struct pci_dev *pci = chip->pci;
 	int i;
@@ -2197,14 +2193,11 @@
 	/* Config Reg A */
 	pci_read_config_word(pci, ESM_CONFIG_A, &w);
 
-	/*      Use TDMA for now. TDMA works on all boards, so while its
-	 *      not the most efficient its the simplest. */
 	w &= ~DMA_CLEAR;	/* Clear DMA bits */
-	w |= DMA_TDMA;		/* TDMA on */
 	w &= ~(PIC_SNOOP1 | PIC_SNOOP2);	/* Clear Pic Snoop Mode Bits */
 	w &= ~SAFEGUARD;	/* Safeguard off */
 	w |= POST_WRITE;	/* Posted write */
-	w |= ISA_TIMING;	/* ISA timing on */
+	w |= PCI_TIMING;	/* PCI timing on */
 	/* XXX huh?  claims to be reserved.. */
 	w &= ~SWAP_LR;		/* swap left/right 
 				   seems to only have effect on SB
@@ -2245,7 +2238,7 @@
 
 	pci_read_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, &w);
 
-	w &= ~ESS_ENABLE_AUDIO;	/* Disable Legacy Audio */
+	w |= ESS_DISABLE_AUDIO;	/* Disable Legacy Audio */
 	w &= ~ESS_ENABLE_SERIAL_IRQ;	/* Disable SIRQ */
 	w &= ~(0x1f);		/* disable mpu irq/io, game port, fm, SB */
 
@@ -2369,7 +2362,7 @@
 }
 
 /* Enable IRQ's */
-static void snd_es1968_start_irq(es1968_t *chip)
+static void snd_es1968_start_irq(struct es1968 *chip)
 {
 	unsigned short w;
 	w = ESM_HIRQ_DSIE | ESM_HIRQ_HW_VOLUME;
@@ -2382,33 +2375,38 @@
 /*
  * PM support
  */
-static int es1968_suspend(snd_card_t *card, pm_message_t state)
+static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	es1968_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct es1968 *chip = card->private_data;
 
 	if (! chip->do_pm)
 		return 0;
 
 	chip->in_suspend = 1;
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
 	snd_es1968_bob_stop(chip);
 	snd_es1968_set_acpi(chip, ACPI_D3);
-	pci_disable_device(chip->pci);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int es1968_resume(snd_card_t *card)
+static int es1968_resume(struct pci_dev *pci)
 {
-	es1968_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct es1968 *chip = card->private_data;
 	struct list_head *p;
 
 	if (! chip->do_pm)
 		return 0;
 
 	/* restore all our config */
-	pci_enable_device(chip->pci);
-	pci_set_master(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci);
 	snd_es1968_chip_init(chip);
 
 	/* need to restore the base pointers.. */ 
@@ -2423,7 +2421,7 @@
 	snd_ac97_resume(chip->ac97);
 
 	list_for_each(p, &chip->substream_list) {
-		esschan_t *es = list_entry(p, esschan_t, list);
+		struct esschan *es = list_entry(p, struct esschan, list);
 		switch (es->mode) {
 		case ESM_MODE_PLAY:
 			snd_es1968_playback_setup(chip, es, es->substream->runtime);
@@ -2438,6 +2436,7 @@
 	if (chip->bobclient)
 		snd_es1968_bob_start(chip);
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	chip->in_suspend = 0;
 	return 0;
 }
@@ -2445,7 +2444,7 @@
 
 #ifdef SUPPORT_JOYSTICK
 #define JOYSTICK_ADDR	0x200
-static int __devinit snd_es1968_create_gameport(es1968_t *chip, int dev)
+static int __devinit snd_es1968_create_gameport(struct es1968 *chip, int dev)
 {
 	struct gameport *gp;
 	struct resource *r;
@@ -2479,7 +2478,7 @@
 	return 0;
 }
 
-static void snd_es1968_free_gameport(es1968_t *chip)
+static void snd_es1968_free_gameport(struct es1968 *chip)
 {
 	if (chip->gameport) {
 		struct resource *r = gameport_get_port_data(chip->gameport);
@@ -2491,11 +2490,11 @@
 	}
 }
 #else
-static inline int snd_es1968_create_gameport(es1968_t *chip, int dev) { return -ENOSYS; }
-static inline void snd_es1968_free_gameport(es1968_t *chip) { }
+static inline int snd_es1968_create_gameport(struct es1968 *chip, int dev) { return -ENOSYS; }
+static inline void snd_es1968_free_gameport(struct es1968 *chip) { }
 #endif
 
-static int snd_es1968_free(es1968_t *chip)
+static int snd_es1968_free(struct es1968 *chip)
 {
 	if (chip->io_port) {
 		synchronize_irq(chip->irq);
@@ -2515,9 +2514,9 @@
 	return 0;
 }
 
-static int snd_es1968_dev_free(snd_device_t *device)
+static int snd_es1968_dev_free(struct snd_device *device)
 {
-	es1968_t *chip = device->device_data;
+	struct es1968 *chip = device->device_data;
 	return snd_es1968_free(chip);
 }
 
@@ -2539,19 +2538,19 @@
 	{ TYPE_MAESTRO2, 0x125d },
 };
 
-static int __devinit snd_es1968_create(snd_card_t * card,
+static int __devinit snd_es1968_create(struct snd_card *card,
 				       struct pci_dev *pci,
 				       int total_bufsize,
 				       int play_streams,
 				       int capt_streams,
 				       int chip_type,
 				       int do_pm,
-				       es1968_t **chip_ret)
+				       struct es1968 **chip_ret)
 {
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_es1968_dev_free,
 	};
-	es1968_t *chip;
+	struct es1968 *chip;
 	int i, err;
 
 	*chip_ret = NULL;
@@ -2635,9 +2634,6 @@
 
 	snd_es1968_chip_init(chip);
 
-	if (chip->do_pm)
-		snd_card_set_pm_callback(card, es1968_suspend, es1968_resume, chip);
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_es1968_free(chip);
 		return err;
@@ -2657,8 +2653,8 @@
 				      const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	es1968_t *chip;
+	struct snd_card *card;
+	struct es1968 *chip;
 	unsigned int i;
 	int err;
 
@@ -2687,6 +2683,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 
 	switch (chip->type) {
 	case TYPE_MAESTRO2E:
@@ -2764,7 +2761,10 @@
 	.id_table = snd_es1968_ids,
 	.probe = snd_es1968_probe,
 	.remove = __devexit_p(snd_es1968_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = es1968_suspend,
+	.resume = es1968_resume,
+#endif
 };
 
 static int __init alsa_card_es1968_init(void)
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 4e1d343..6ab4aef 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -103,7 +103,11 @@
 #define FM801_OPL3_DATA1	0x6b	/* OPL3 Bank 1 Write */
 #define FM801_POWERDOWN		0x70	/* Blocks Power Down Control */
 
-#define FM801_AC97_ADDR_SHIFT	10
+/* codec access */
+#define FM801_AC97_READ		(1<<7)	/* read=1, write=0 */
+#define FM801_AC97_VALID	(1<<8)	/* port valid=1 */
+#define FM801_AC97_BUSY		(1<<9)	/* busy=1 */
+#define FM801_AC97_ADDR_SHIFT	10	/* codec id (2bit) */
 
 /* playback and record control register bits */
 #define FM801_BUF1_LAST		(1<<1)
@@ -147,9 +151,7 @@
 
  */
 
-typedef struct _snd_fm801 fm801_t;
-
-struct _snd_fm801 {
+struct fm801 {
 	int irq;
 
 	unsigned long port;	/* I/O port number */
@@ -172,24 +174,28 @@
 	unsigned int cap_size;
 	unsigned int cap_pos;
 
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97;
-	ac97_t *ac97_sec;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97;
+	struct snd_ac97 *ac97_sec;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_rawmidi_t *rmidi;
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_rawmidi *rmidi;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
 	unsigned int p_dma_size;
 	unsigned int c_dma_size;
 
 	spinlock_t reg_lock;
-	snd_info_entry_t *proc_entry;
+	struct snd_info_entry *proc_entry;
 
 #ifdef TEA575X_RADIO
-	tea575x_t tea;
+	struct snd_tea575x tea;
+#endif
+
+#ifdef CONFIG_PM
+	u16 saved_regs[0x20];
 #endif
 };
 
@@ -205,7 +211,7 @@
  *  common I/O routines
  */
 
-static int snd_fm801_update_bits(fm801_t *chip, unsigned short reg,
+static int snd_fm801_update_bits(struct fm801 *chip, unsigned short reg,
 				 unsigned short mask, unsigned short value)
 {
 	int change;
@@ -222,18 +228,18 @@
 	return change;
 }
 
-static void snd_fm801_codec_write(ac97_t *ac97,
+static void snd_fm801_codec_write(struct snd_ac97 *ac97,
 				  unsigned short reg,
 				  unsigned short val)
 {
-	fm801_t *chip = ac97->private_data;
+	struct fm801 *chip = ac97->private_data;
 	int idx;
 
 	/*
 	 *  Wait until the codec interface is not ready..
 	 */
 	for (idx = 0; idx < 100; idx++) {
-		if (!(inw(FM801_REG(chip, AC97_CMD)) & (1<<9)))
+		if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY))
 			goto ok1;
 		udelay(10);
 	}
@@ -248,23 +254,23 @@
 	 *  Wait until the write command is not completed..
          */
 	for (idx = 0; idx < 1000; idx++) {
-		if (!(inw(FM801_REG(chip, AC97_CMD)) & (1<<9)))
+		if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY))
 			return;
 		udelay(10);
 	}
 	snd_printk(KERN_ERR "AC'97 interface #%d is busy (2)\n", ac97->num);
 }
 
-static unsigned short snd_fm801_codec_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_fm801_codec_read(struct snd_ac97 *ac97, unsigned short reg)
 {
-	fm801_t *chip = ac97->private_data;
+	struct fm801 *chip = ac97->private_data;
 	int idx;
 
 	/*
 	 *  Wait until the codec interface is not ready..
 	 */
 	for (idx = 0; idx < 100; idx++) {
-		if (!(inw(FM801_REG(chip, AC97_CMD)) & (1<<9)))
+		if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY))
 			goto ok1;
 		udelay(10);
 	}
@@ -273,9 +279,10 @@
 
  ok1:
 	/* read command */
-	outw(reg | (ac97->addr << FM801_AC97_ADDR_SHIFT) | (1<<7), FM801_REG(chip, AC97_CMD));
+	outw(reg | (ac97->addr << FM801_AC97_ADDR_SHIFT) | FM801_AC97_READ,
+	     FM801_REG(chip, AC97_CMD));
 	for (idx = 0; idx < 100; idx++) {
-		if (!(inw(FM801_REG(chip, AC97_CMD)) & (1<<9)))
+		if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY))
 			goto ok2;
 		udelay(10);
 	}
@@ -284,7 +291,7 @@
 
  ok2:
 	for (idx = 0; idx < 1000; idx++) {
-		if (inw(FM801_REG(chip, AC97_CMD)) & (1<<8))
+		if (inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_VALID)
 			goto ok3;
 		udelay(10);
 	}
@@ -301,7 +308,7 @@
   38400, 44100, 48000
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 	.count = ARRAY_SIZE(rates),
 	.list = rates,
 	.mask = 0,
@@ -313,7 +320,7 @@
 
 #define CHANNELS sizeof(channels) / sizeof(channels[0])
 
-static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
+static struct snd_pcm_hw_constraint_list hw_constraints_channels = {
 	.count = CHANNELS,
 	.list = channels,
 	.mask = 0,
@@ -338,10 +345,10 @@
  *  PCM part
  */
 
-static int snd_fm801_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_fm801_playback_trigger(struct snd_pcm_substream *substream,
 				      int cmd)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
 
 	spin_lock(&chip->reg_lock);
 	switch (cmd) {
@@ -356,9 +363,11 @@
 		chip->ply_ctrl &= ~(FM801_START | FM801_PAUSE);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		chip->ply_ctrl |= FM801_PAUSE;
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		chip->ply_ctrl &= ~FM801_PAUSE;
 		break;
 	default:
@@ -371,10 +380,10 @@
 	return 0;
 }
 
-static int snd_fm801_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_fm801_capture_trigger(struct snd_pcm_substream *substream,
 				     int cmd)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
 
 	spin_lock(&chip->reg_lock);
 	switch (cmd) {
@@ -389,9 +398,11 @@
 		chip->cap_ctrl &= ~(FM801_START | FM801_PAUSE);
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
 		chip->cap_ctrl |= FM801_PAUSE;
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
 		chip->cap_ctrl &= ~FM801_PAUSE;
 		break;
 	default:
@@ -404,21 +415,21 @@
 	return 0;
 }
 
-static int snd_fm801_hw_params(snd_pcm_substream_t * substream,
-			       snd_pcm_hw_params_t * hw_params)
+static int snd_fm801_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_fm801_hw_free(snd_pcm_substream_t * substream)
+static int snd_fm801_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_fm801_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_fm801_playback_prepare(struct snd_pcm_substream *substream)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	chip->ply_size = snd_pcm_lib_buffer_bytes(substream);
 	chip->ply_count = snd_pcm_lib_period_bytes(substream);
@@ -447,10 +458,10 @@
 	return 0;
 }
 
-static int snd_fm801_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_fm801_capture_prepare(struct snd_pcm_substream *substream)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	chip->cap_size = snd_pcm_lib_buffer_bytes(substream);
 	chip->cap_count = snd_pcm_lib_period_bytes(substream);
@@ -473,9 +484,9 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_fm801_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_fm801_playback_pointer(struct snd_pcm_substream *substream)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(chip->ply_ctrl & FM801_START))
@@ -490,9 +501,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_fm801_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_fm801_capture_pointer(struct snd_pcm_substream *substream)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(chip->cap_ctrl & FM801_START))
@@ -509,7 +520,7 @@
 
 static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	fm801_t *chip = dev_id;
+	struct fm801 *chip = dev_id;
 	unsigned short status;
 	unsigned int tmp;
 
@@ -555,11 +566,11 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_hardware_t snd_fm801_playback =
+static struct snd_pcm_hardware snd_fm801_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_PAUSE |
+				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
@@ -575,11 +586,11 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_fm801_capture =
+static struct snd_pcm_hardware snd_fm801_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_PAUSE |
+				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
 				 SNDRV_PCM_INFO_MMAP_VALID),
 	.formats =		SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
 	.rates =		SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
@@ -595,55 +606,59 @@
 	.fifo_size =		0,
 };
 
-static int snd_fm801_playback_open(snd_pcm_substream_t * substream)
+static int snd_fm801_playback_open(struct snd_pcm_substream *substream)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	chip->playback_substream = substream;
 	runtime->hw = snd_fm801_playback;
-	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
+	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+				   &hw_constraints_rates);
 	if (chip->multichannel) {
 		runtime->hw.channels_max = 6;
-		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels);
+		snd_pcm_hw_constraint_list(runtime, 0,
+					   SNDRV_PCM_HW_PARAM_CHANNELS,
+					   &hw_constraints_channels);
 	}
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
 		return err;
 	return 0;
 }
 
-static int snd_fm801_capture_open(snd_pcm_substream_t * substream)
+static int snd_fm801_capture_open(struct snd_pcm_substream *substream)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	chip->capture_substream = substream;
 	runtime->hw = snd_fm801_capture;
-	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
+	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+				   &hw_constraints_rates);
 	if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
 		return err;
 	return 0;
 }
 
-static int snd_fm801_playback_close(snd_pcm_substream_t * substream)
+static int snd_fm801_playback_close(struct snd_pcm_substream *substream)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
 
 	chip->playback_substream = NULL;
 	return 0;
 }
 
-static int snd_fm801_capture_close(snd_pcm_substream_t * substream)
+static int snd_fm801_capture_close(struct snd_pcm_substream *substream)
 {
-	fm801_t *chip = snd_pcm_substream_chip(substream);
+	struct fm801 *chip = snd_pcm_substream_chip(substream);
 
 	chip->capture_substream = NULL;
 	return 0;
 }
 
-static snd_pcm_ops_t snd_fm801_playback_ops = {
+static struct snd_pcm_ops snd_fm801_playback_ops = {
 	.open =		snd_fm801_playback_open,
 	.close =	snd_fm801_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -654,7 +669,7 @@
 	.pointer =	snd_fm801_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_fm801_capture_ops = {
+static struct snd_pcm_ops snd_fm801_capture_ops = {
 	.open =		snd_fm801_capture_open,
 	.close =	snd_fm801_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -665,16 +680,9 @@
 	.pointer =	snd_fm801_capture_pointer,
 };
 
-static void snd_fm801_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pcm ** rpcm)
 {
-	fm801_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_fm801_pcm(fm801_t *chip, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -686,7 +694,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_fm801_capture_ops);
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_fm801_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "FM801");
 	chip->pcm = pcm;
@@ -711,9 +718,9 @@
 #define TEA_256PCS_WRITE_ENABLE		2	/* inverted */
 #define TEA_256PCS_BUS_CLOCK		3
 
-static void snd_fm801_tea575x_256pcs_write(tea575x_t *tea, unsigned int val)
+static void snd_fm801_tea575x_256pcs_write(struct snd_tea575x *tea, unsigned int val)
 {
-	fm801_t *chip = tea->private_data;
+	struct fm801 *chip = tea->private_data;
 	unsigned short reg;
 	int i = 25;
 
@@ -755,9 +762,9 @@
 	spin_unlock_irq(&chip->reg_lock);
 }
 
-static unsigned int snd_fm801_tea575x_256pcs_read(tea575x_t *tea)
+static unsigned int snd_fm801_tea575x_256pcs_read(struct snd_tea575x *tea)
 {
-	fm801_t *chip = tea->private_data;
+	struct fm801 *chip = tea->private_data;
 	unsigned short reg;
 	unsigned int val = 0;
 	int i;
@@ -799,9 +806,9 @@
 #define TEA_256PCPR_DATA		1
 #define TEA_256PCPR_WRITE_ENABLE	2	/* inverted */
 
-static void snd_fm801_tea575x_256pcpr_write(tea575x_t *tea, unsigned int val)
+static void snd_fm801_tea575x_256pcpr_write(struct snd_tea575x *tea, unsigned int val)
 {
-	fm801_t *chip = tea->private_data;
+	struct fm801 *chip = tea->private_data;
 	unsigned short reg;
 	int i = 25;
 
@@ -843,9 +850,9 @@
 	spin_unlock_irq(&chip->reg_lock);
 }
 
-static unsigned int snd_fm801_tea575x_256pcpr_read(tea575x_t *tea)
+static unsigned int snd_fm801_tea575x_256pcpr_read(struct snd_tea575x *tea)
 {
-	fm801_t *chip = tea->private_data;
+	struct fm801 *chip = tea->private_data;
 	unsigned short reg;
 	unsigned int val = 0;
 	int i;
@@ -887,9 +894,9 @@
 #define TEA_64PCR_WRITE_ENABLE		1	/* inverted */
 #define TEA_64PCR_DATA			2
 
-static void snd_fm801_tea575x_64pcr_write(tea575x_t *tea, unsigned int val)
+static void snd_fm801_tea575x_64pcr_write(struct snd_tea575x *tea, unsigned int val)
 {
-	fm801_t *chip = tea->private_data;
+	struct fm801 *chip = tea->private_data;
 	unsigned short reg;
 	int i = 25;
 
@@ -931,9 +938,9 @@
 	spin_unlock_irq(&chip->reg_lock);
 }
 
-static unsigned int snd_fm801_tea575x_64pcr_read(tea575x_t *tea)
+static unsigned int snd_fm801_tea575x_64pcr_read(struct snd_tea575x *tea)
 {
-	fm801_t *chip = tea->private_data;
+	struct fm801 *chip = tea->private_data;
 	unsigned short reg;
 	unsigned int val = 0;
 	int i;
@@ -998,7 +1005,8 @@
   .get = snd_fm801_get_single, .put = snd_fm801_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_fm801_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_fm801_info_single(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -1009,9 +1017,10 @@
 	return 0;
 }
 
-static int snd_fm801_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_fm801_get_single(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	fm801_t *chip = snd_kcontrol_chip(kcontrol);
+	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -1023,9 +1032,10 @@
 	return 0;
 }
 
-static int snd_fm801_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_fm801_put_single(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	fm801_t *chip = snd_kcontrol_chip(kcontrol);
+	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -1043,7 +1053,8 @@
   .get = snd_fm801_get_double, .put = snd_fm801_put_double, \
   .private_value = reg | (shift_left << 8) | (shift_right << 12) | (mask << 16) | (invert << 24) }
 
-static int snd_fm801_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_fm801_info_double(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -1054,9 +1065,10 @@
 	return 0;
 }
 
-static int snd_fm801_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_fm801_get_double(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	fm801_t *chip = snd_kcontrol_chip(kcontrol);
+	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
         int reg = kcontrol->private_value & 0xff;
 	int shift_left = (kcontrol->private_value >> 8) & 0x0f;
 	int shift_right = (kcontrol->private_value >> 12) & 0x0f;
@@ -1074,9 +1086,10 @@
 	return 0;
 }
 
-static int snd_fm801_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_fm801_put_double(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	fm801_t *chip = snd_kcontrol_chip(kcontrol);
+	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift_left = (kcontrol->private_value >> 8) & 0x0f;
 	int shift_right = (kcontrol->private_value >> 12) & 0x0f;
@@ -1095,7 +1108,8 @@
 				     (val1 << shift_left ) | (val2 << shift_right));
 }
 
-static int snd_fm801_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_fm801_info_mux(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[5] = {
 		"AC97 Primary", "FM", "I2S", "PCM", "AC97 Secondary"
@@ -1110,9 +1124,10 @@
 	return 0;
 }
 
-static int snd_fm801_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_fm801_get_mux(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
 {
-	fm801_t *chip = snd_kcontrol_chip(kcontrol);
+	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
         unsigned short val;
  
 	val = inw(FM801_REG(chip, REC_SRC)) & 7;
@@ -1122,9 +1137,10 @@
         return 0;
 }
 
-static int snd_fm801_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_fm801_put_mux(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
 {
-	fm801_t *chip = snd_kcontrol_chip(kcontrol);
+	struct fm801 *chip = snd_kcontrol_chip(kcontrol);
         unsigned short val;
  
         if ((val = ucontrol->value.enumerated.item[0]) > 4)
@@ -1132,9 +1148,9 @@
 	return snd_fm801_update_bits(chip, FM801_REC_SRC, 7, val);
 }
 
-#define FM801_CONTROLS (sizeof(snd_fm801_controls)/sizeof(snd_kcontrol_new_t))
+#define FM801_CONTROLS ARRAY_SIZE(snd_fm801_controls)
 
-static snd_kcontrol_new_t snd_fm801_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_fm801_controls[] __devinitdata = {
 FM801_DOUBLE("Wave Playback Volume", FM801_PCM_VOL, 0, 8, 31, 1),
 FM801_SINGLE("Wave Playback Switch", FM801_PCM_VOL, 15, 1, 1),
 FM801_DOUBLE("I2S Playback Volume", FM801_I2S_VOL, 0, 8, 31, 1),
@@ -1150,9 +1166,9 @@
 }
 };
 
-#define FM801_CONTROLS_MULTI (sizeof(snd_fm801_controls_multi)/sizeof(snd_kcontrol_new_t))
+#define FM801_CONTROLS_MULTI ARRAY_SIZE(snd_fm801_controls_multi)
 
-static snd_kcontrol_new_t snd_fm801_controls_multi[] __devinitdata = {
+static struct snd_kcontrol_new snd_fm801_controls_multi[] __devinitdata = {
 FM801_SINGLE("AC97 2ch->4ch Copy Switch", FM801_CODEC_CTRL, 7, 1, 0),
 FM801_SINGLE("AC97 18-bit Switch", FM801_CODEC_CTRL, 10, 1, 0),
 FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), FM801_I2S_MODE, 8, 1, 0),
@@ -1161,15 +1177,15 @@
 FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), FM801_GEN_CTRL, 2, 1, 0),
 };
 
-static void snd_fm801_mixer_free_ac97_bus(ac97_bus_t *bus)
+static void snd_fm801_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
 {
-	fm801_t *chip = bus->private_data;
+	struct fm801 *chip = bus->private_data;
 	chip->ac97_bus = NULL;
 }
 
-static void snd_fm801_mixer_free_ac97(ac97_t *ac97)
+static void snd_fm801_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	fm801_t *chip = ac97->private_data;
+	struct fm801 *chip = ac97->private_data;
 	if (ac97->num == 0) {
 		chip->ac97 = NULL;
 	} else {
@@ -1177,12 +1193,12 @@
 	}
 }
 
-static int __devinit snd_fm801_mixer(fm801_t *chip)
+static int __devinit snd_fm801_mixer(struct fm801 *chip)
 {
-	ac97_template_t ac97;
+	struct snd_ac97_template ac97;
 	unsigned int i;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_fm801_codec_write,
 		.read = snd_fm801_codec_read,
 	};
@@ -1215,7 +1231,86 @@
  *  initialization routines
  */
 
-static int snd_fm801_free(fm801_t *chip)
+static int wait_for_codec(struct fm801 *chip, unsigned int codec_id,
+			  unsigned short reg, unsigned long waits)
+{
+	unsigned long timeout = jiffies + waits;
+
+	outw(FM801_AC97_READ | (codec_id << FM801_AC97_ADDR_SHIFT) | reg,
+	     FM801_REG(chip, AC97_CMD));
+	udelay(5);
+	do {
+		if ((inw(FM801_REG(chip, AC97_CMD)) & (FM801_AC97_VALID|FM801_AC97_BUSY))
+		    == FM801_AC97_VALID)
+			return 0;
+		schedule_timeout_uninterruptible(1);
+	} while (time_after(timeout, jiffies));
+	return -EIO;
+}
+
+static int snd_fm801_chip_init(struct fm801 *chip, int resume)
+{
+	int id;
+	unsigned short cmdw;
+
+	/* codec cold reset + AC'97 warm reset */
+	outw((1<<5) | (1<<6), FM801_REG(chip, CODEC_CTRL));
+	inw(FM801_REG(chip, CODEC_CTRL)); /* flush posting data */
+	udelay(100);
+	outw(0, FM801_REG(chip, CODEC_CTRL));
+
+	if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0) {
+		snd_printk(KERN_ERR "Primary AC'97 codec not found\n");
+		if (! resume)
+			return -EIO;
+	}
+
+	if (chip->multichannel) {
+		if (chip->secondary_addr) {
+			wait_for_codec(chip, chip->secondary_addr,
+				       AC97_VENDOR_ID1, msecs_to_jiffies(50));
+		} else {
+			/* my card has the secondary codec */
+			/* at address #3, so the loop is inverted */
+			for (id = 3; id > 0; id--) {
+				if (! wait_for_codec(chip, id, AC97_VENDOR_ID1,
+						     msecs_to_jiffies(50))) {
+					cmdw = inw(FM801_REG(chip, AC97_DATA));
+					if (cmdw != 0xffff && cmdw != 0) {
+						chip->secondary = 1;
+						chip->secondary_addr = id;
+						break;
+					}
+				}
+			}
+		}
+
+		/* the recovery phase, it seems that probing for non-existing codec might */
+		/* cause timeout problems */
+		wait_for_codec(chip, 0, AC97_VENDOR_ID1, msecs_to_jiffies(750));
+	}
+
+	/* init volume */
+	outw(0x0808, FM801_REG(chip, PCM_VOL));
+	outw(0x9f1f, FM801_REG(chip, FM_VOL));
+	outw(0x8808, FM801_REG(chip, I2S_VOL));
+
+	/* I2S control - I2S mode */
+	outw(0x0003, FM801_REG(chip, I2S_MODE));
+
+	/* interrupt setup - unmask MPU, PLAYBACK & CAPTURE */
+	cmdw = inw(FM801_REG(chip, IRQ_MASK));
+	cmdw &= ~0x0083;
+	outw(cmdw, FM801_REG(chip, IRQ_MASK));
+
+	/* interrupt clear */
+	outw(FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU, FM801_REG(chip, IRQ_STATUS));
+
+	return 0;
+}
+
+
+static int snd_fm801_free(struct fm801 *chip)
 {
 	unsigned short cmdw;
 
@@ -1232,7 +1327,7 @@
 	snd_tea575x_exit(&chip->tea);
 #endif
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
 
@@ -1240,23 +1335,21 @@
 	return 0;
 }
 
-static int snd_fm801_dev_free(snd_device_t *device)
+static int snd_fm801_dev_free(struct snd_device *device)
 {
-	fm801_t *chip = device->device_data;
+	struct fm801 *chip = device->device_data;
 	return snd_fm801_free(chip);
 }
 
-static int __devinit snd_fm801_create(snd_card_t * card,
+static int __devinit snd_fm801_create(struct snd_card *card,
 				      struct pci_dev * pci,
 				      int tea575x_tuner,
-				      fm801_t ** rchip)
+				      struct fm801 ** rchip)
 {
-	fm801_t *chip;
-	unsigned char rev, id;
-	unsigned short cmdw;
-	unsigned long timeout;
+	struct fm801 *chip;
+	unsigned char rev;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_fm801_dev_free,
 	};
 
@@ -1278,7 +1371,8 @@
 		return err;
 	}
 	chip->port = pci_resource_start(pci, 0);
-	if (request_irq(pci->irq, snd_fm801_interrupt, SA_INTERRUPT|SA_SHIRQ, "FM801", (void *)chip)) {
+	if (request_irq(pci->irq, snd_fm801_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			"FM801", chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
 		snd_fm801_free(chip);
 		return -EBUSY;
@@ -1290,80 +1384,7 @@
 	if (rev >= 0xb1)	/* FM801-AU */
 		chip->multichannel = 1;
 
-	/* codec cold reset + AC'97 warm reset */
-	outw((1<<5)|(1<<6), FM801_REG(chip, CODEC_CTRL));
-	inw(FM801_REG(chip, CODEC_CTRL)); /* flush posting data */
-	udelay(100);
-	outw(0, FM801_REG(chip, CODEC_CTRL));
-
-	timeout = (jiffies + (3 * HZ) / 4) + 1;		/* min 750ms */
-
-	outw((1<<7) | (0 << FM801_AC97_ADDR_SHIFT), FM801_REG(chip, AC97_CMD));
-	udelay(5);
-	do {
-		if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
-			goto __ac97_secondary;
-		schedule_timeout_uninterruptible(1);
-	} while (time_after(timeout, jiffies));
-	snd_printk(KERN_ERR "Primary AC'97 codec not found\n");
-	snd_fm801_free(chip);
-	return -EIO;
-
-      __ac97_secondary:
-      	if (!chip->multichannel)	/* lookup is not required */
-      		goto __ac97_ok;
-	for (id = 3; id > 0; id--) {	/* my card has the secondary codec */
-					/* at address #3, so the loop is inverted */
-
-		timeout = jiffies + HZ / 20;
-
-		outw((1<<7) | (id << FM801_AC97_ADDR_SHIFT) | AC97_VENDOR_ID1, FM801_REG(chip, AC97_CMD));
-		udelay(5);
-		do {
-			if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8)) {
-				cmdw = inw(FM801_REG(chip, AC97_DATA));
-				if (cmdw != 0xffff && cmdw != 0) {
-					chip->secondary = 1;
-					chip->secondary_addr = id;
-					goto __ac97_ok;
-				}
-			}
-			schedule_timeout_uninterruptible(1);
-		} while (time_after(timeout, jiffies));
-	}
-
-	/* the recovery phase, it seems that probing for non-existing codec might */
-	/* cause timeout problems */
-	timeout = (jiffies + (3 * HZ) / 4) + 1;		/* min 750ms */
-
-	outw((1<<7) | (0 << FM801_AC97_ADDR_SHIFT), FM801_REG(chip, AC97_CMD));
-	udelay(5);
-	do {
-		if ((inw(FM801_REG(chip, AC97_CMD)) & (3<<8)) == (1<<8))
-			goto __ac97_ok;
-		schedule_timeout_uninterruptible(1);
-	} while (time_after(timeout, jiffies));
-	snd_printk(KERN_ERR "Primary AC'97 codec not responding\n");
-	snd_fm801_free(chip);
-	return -EIO;
-
-      __ac97_ok:
-
-	/* init volume */
-	outw(0x0808, FM801_REG(chip, PCM_VOL));
-	outw(0x9f1f, FM801_REG(chip, FM_VOL));
-	outw(0x8808, FM801_REG(chip, I2S_VOL));
-
-	/* I2S control - I2S mode */
-	outw(0x0003, FM801_REG(chip, I2S_MODE));
-
-	/* interrupt setup - unmask MPU, PLAYBACK & CAPTURE */
-	cmdw = inw(FM801_REG(chip, IRQ_MASK));
-	cmdw &= ~0x0083;
-	outw(cmdw, FM801_REG(chip, IRQ_MASK));
-
-	/* interrupt clear */
-	outw(FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU, FM801_REG(chip, IRQ_STATUS));
+	snd_fm801_chip_init(chip, 0);
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_fm801_free(chip);
@@ -1391,9 +1412,9 @@
 					  const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	fm801_t *chip;
-	opl3_t *opl3;
+	struct snd_card *card;
+	struct fm801 *chip;
+	struct snd_opl3 *opl3;
 	int err;
 
         if (dev >= SNDRV_CARDS)
@@ -1410,6 +1431,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 
 	strcpy(card->driver, "FM801");
 	strcpy(card->shortname, "ForteMedia FM801-");
@@ -1457,11 +1479,65 @@
 	pci_set_drvdata(pci, NULL);
 }
 
+#ifdef CONFIG_PM
+static unsigned char saved_regs[] = {
+	FM801_PCM_VOL, FM801_I2S_VOL, FM801_FM_VOL, FM801_REC_SRC,
+	FM801_PLY_CTRL, FM801_PLY_COUNT, FM801_PLY_BUF1, FM801_PLY_BUF2,
+	FM801_CAP_CTRL, FM801_CAP_COUNT, FM801_CAP_BUF1, FM801_CAP_BUF2,
+	FM801_CODEC_CTRL, FM801_I2S_MODE, FM801_VOLUME, FM801_GEN_CTRL,
+};
+
+static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct fm801 *chip = card->private_data;
+	int i;
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(chip->pcm);
+	snd_ac97_suspend(chip->ac97);
+	snd_ac97_suspend(chip->ac97_sec);
+	for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
+		chip->saved_regs[i] = inw(chip->port + saved_regs[i]);
+	/* FIXME: tea575x suspend */
+
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
+	return 0;
+}
+
+static int snd_fm801_resume(struct pci_dev *pci)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct fm801 *chip = card->private_data;
+	int i;
+
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
+	pci_set_master(pci);
+
+	snd_fm801_chip_init(chip, 1);
+	snd_ac97_resume(chip->ac97);
+	snd_ac97_resume(chip->ac97_sec);
+	for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
+		outw(chip->saved_regs[i], chip->port + saved_regs[i]);
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
 static struct pci_driver driver = {
 	.name = "FM801",
 	.id_table = snd_fm801_ids,
 	.probe = snd_card_fm801_probe,
 	.remove = __devexit_p(snd_card_fm801_remove),
+#ifdef CONFIG_PM
+	.suspend = snd_fm801_suspend,
+	.resume = snd_fm801_resume,
+#endif
 };
 
 static int __init alsa_card_fm801_init(void)
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 0dbeeaf..4a6dd97 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -155,8 +155,9 @@
 			    hda_nid_t *conn_list, int max_conns)
 {
 	unsigned int parm;
-	int i, j, conn_len, num_tupples, conns;
+	int i, conn_len, conns;
 	unsigned int shift, num_elems, mask;
+	hda_nid_t prev_nid;
 
 	snd_assert(conn_list && max_conns > 0, return -EINVAL);
 
@@ -171,7 +172,6 @@
 		num_elems = 4;
 	}
 	conn_len = parm & AC_CLIST_LENGTH;
-	num_tupples = num_elems / 2;
 	mask = (1 << (shift-1)) - 1;
 
 	if (! conn_len)
@@ -186,40 +186,38 @@
 
 	/* multi connection */
 	conns = 0;
-	for (i = 0; i < conn_len; i += num_elems) {
-		parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, i);
-		for (j = 0; j < num_tupples; j++) {
-			int range_val;
-			hda_nid_t val1, val2, n;
-			range_val = parm & (1 << (shift-1)); /* ranges */
-			val1 = parm & mask;
-			parm >>= shift;
-			val2 = parm & mask;
-			parm >>= shift;
-			if (range_val) {
-				/* ranges between val1 and val2 */
-				if (val1 > val2) {
-					snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", val1, val2);
-					continue;
-				}
-				for (n = val1; n <= val2; n++) {
-					if (conns >= max_conns)
-						return -EINVAL;
-					conn_list[conns++] = n;
-				}
-			} else {
-				if (! val1)
-					break;
-				if (conns >= max_conns)
-					return -EINVAL;
-				conn_list[conns++] = val1;
-				if (! val2)
-					break;
-				if (conns >= max_conns)
-					return -EINVAL;
-				conn_list[conns++] = val2;
+	prev_nid = 0;
+	for (i = 0; i < conn_len; i++) {
+		int range_val;
+		hda_nid_t val, n;
+
+		if (i % num_elems == 0)
+			parm = snd_hda_codec_read(codec, nid, 0,
+						  AC_VERB_GET_CONNECT_LIST, i);
+		range_val = !! (parm & (1 << (shift-1))); /* ranges */
+		val = parm & mask;
+		parm >>= shift;
+		if (range_val) {
+			/* ranges between the previous and this one */
+			if (! prev_nid || prev_nid >= val) {
+				snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val);
+				continue;
 			}
+			for (n = prev_nid + 1; n <= val; n++) {
+				if (conns >= max_conns) {
+					snd_printk(KERN_ERR "Too many connections\n");
+					return -EINVAL;
+				}
+				conn_list[conns++] = n;
+			}
+		} else {
+			if (conns >= max_conns) {
+				snd_printk(KERN_ERR "Too many connections\n");
+				return -EINVAL;
+			}
+			conn_list[conns++] = val;
 		}
+		prev_nid = val;
 	}
 	return conns;
 }
@@ -288,6 +286,9 @@
 {
 	struct hda_bus_unsolicited *unsol;
 
+	if (bus->unsol) /* already initialized */
+		return 0;
+
 	unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);
 	if (! unsol) {
 		snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
@@ -329,7 +330,7 @@
 	return 0;
 }
 
-static int snd_hda_bus_dev_free(snd_device_t *device)
+static int snd_hda_bus_dev_free(struct snd_device *device)
 {
 	struct hda_bus *bus = device->device_data;
 	return snd_hda_bus_free(bus);
@@ -343,12 +344,12 @@
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp,
+int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
 		    struct hda_bus **busp)
 {
 	struct hda_bus *bus;
 	int err;
-	static snd_device_ops_t dev_ops = {
+	static struct snd_device_ops dev_ops = {
 		.dev_free = snd_hda_bus_dev_free,
 	};
 
@@ -373,8 +374,6 @@
 	init_MUTEX(&bus->cmd_mutex);
 	INIT_LIST_HEAD(&bus->codec_list);
 
-	init_unsol_queue(bus);
-
 	if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) {
 		snd_hda_bus_free(bus);
 		return err;
@@ -455,6 +454,27 @@
 }
 
 /*
+ * read widget caps for each widget and store in cache
+ */
+static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
+{
+	int i;
+	hda_nid_t nid;
+
+	codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node,
+						 &codec->start_nid);
+	codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL);
+	if (! codec->wcaps)
+		return -ENOMEM;
+	nid = codec->start_nid;
+	for (i = 0; i < codec->num_nodes; i++, nid++)
+		codec->wcaps[i] = snd_hda_param_read(codec, nid,
+						     AC_PAR_AUDIO_WIDGET_CAP);
+	return 0;
+}
+
+
+/*
  * codec destructor
  */
 static void snd_hda_codec_free(struct hda_codec *codec)
@@ -465,6 +485,8 @@
 	codec->bus->caddr_tbl[codec->addr] = NULL;
 	if (codec->patch_ops.free)
 		codec->patch_ops.free(codec);
+	kfree(codec->amp_info);
+	kfree(codec->wcaps);
 	kfree(codec);
 }
 
@@ -518,6 +540,12 @@
 		return -ENODEV;
 	}
 
+	if (read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg) < 0) {
+		snd_printk(KERN_ERR "hda_codec: cannot malloc\n");
+		snd_hda_codec_free(codec);
+		return -ENOMEM;
+	}
+
 	if (! codec->subsystem_id) {
 		hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
 		codec->subsystem_id = snd_hda_codec_read(codec, nid, 0,
@@ -539,6 +567,9 @@
 		return err;
 	}
 
+	if (codec->patch_ops.unsol_event)
+		init_unsol_queue(bus);
+
 	snd_hda_codec_proc_new(codec);
 
 	sprintf(component, "HDA:%08x", codec->vendor_id);
@@ -586,6 +617,8 @@
 {
 	memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash));
 	codec->num_amp_entries = 0;
+	codec->amp_info_size = 0;
+	codec->amp_info = NULL;
 }
 
 /* query the hash.  allocate an entry if not found. */
@@ -603,9 +636,22 @@
 	}
 
 	/* add a new hash entry */
-	if (codec->num_amp_entries >= ARRAY_SIZE(codec->amp_info)) {
-		snd_printk(KERN_ERR "hda_codec: Tooooo many amps!\n");
-		return NULL;
+	if (codec->num_amp_entries >= codec->amp_info_size) {
+		/* reallocate the array */
+		int new_size = codec->amp_info_size + 64;
+		struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info),
+							GFP_KERNEL);
+		if (! new_info) {
+			snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n");
+			return NULL;
+		}
+		if (codec->amp_info) {
+			memcpy(new_info, codec->amp_info,
+			       codec->amp_info_size * sizeof(struct hda_amp_info));
+			kfree(codec->amp_info);
+		}
+		codec->amp_info_size = new_size;
+		codec->amp_info = new_info;
 	}
 	cur = codec->num_amp_entries++;
 	info = &codec->amp_info[cur];
@@ -627,7 +673,7 @@
 	if (! info)
 		return 0;
 	if (! (info->status & INFO_AMP_CAPS)) {
-		if (!(snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_AMP_OVRD))
+		if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
 			nid = codec->afg;
 		info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ?
 						    AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
@@ -712,7 +758,7 @@
 #define get_amp_index(kc)	(((kc)->private_value >> 19) & 0xf)
 
 /* volume */
-int snd_hda_mixer_amp_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	u16 nid = get_amp_nid(kcontrol);
@@ -733,7 +779,7 @@
 	return 0;
 }
 
-int snd_hda_mixer_amp_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = get_amp_nid(kcontrol);
@@ -749,7 +795,7 @@
 	return 0;
 }
 
-int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = get_amp_nid(kcontrol);
@@ -771,7 +817,7 @@
 }
 
 /* switch */
-int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int chs = get_amp_channels(kcontrol);
 
@@ -782,7 +828,7 @@
 	return 0;
 }
 
-int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = get_amp_nid(kcontrol);
@@ -798,7 +844,7 @@
 	return 0;
 }
 
-int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = get_amp_nid(kcontrol);
@@ -829,7 +875,7 @@
 #define AMP_VAL_IDX_SHIFT	19
 #define AMP_VAL_IDX_MASK	(0x0f<<19)
 
-int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	unsigned long pval;
@@ -844,7 +890,7 @@
 	return err;
 }
 
-int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	unsigned long pval;
@@ -869,14 +915,14 @@
  * SPDIF out controls
  */
 
-static int snd_hda_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_hda_spdif_cmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
 					   IEC958_AES0_NONAUDIO |
@@ -887,7 +933,7 @@
 	return 0;
 }
 
-static int snd_hda_spdif_pmask_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
 					   IEC958_AES0_NONAUDIO |
@@ -895,7 +941,7 @@
 	return 0;
 }
 
-static int snd_hda_spdif_default_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
@@ -958,7 +1004,7 @@
 	return sbits;
 }
 
-static int snd_hda_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value;
@@ -984,7 +1030,7 @@
 	return change;
 }
 
-static int snd_hda_spdif_out_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -993,7 +1039,7 @@
 	return 0;
 }
 
-static int snd_hda_spdif_out_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
@@ -1001,7 +1047,7 @@
 	return 0;
 }
 
-static int snd_hda_spdif_out_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value;
@@ -1024,7 +1070,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t dig_mixes[] = {
+static struct snd_kcontrol_new dig_mixes[] = {
 	{
 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1069,8 +1115,8 @@
 int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
 {
 	int err;
-	snd_kcontrol_t *kctl;
-	snd_kcontrol_new_t *dig_mix;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_new *dig_mix;
 
 	for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
 		kctl = snd_ctl_new1(dig_mix, codec);
@@ -1089,7 +1135,7 @@
 
 #define snd_hda_spdif_in_switch_info	snd_hda_spdif_out_switch_info
 
-static int snd_hda_spdif_in_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 
@@ -1097,7 +1143,7 @@
 	return 0;
 }
 
-static int snd_hda_spdif_in_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value;
@@ -1114,7 +1160,7 @@
 	return change;
 }
 
-static int snd_hda_spdif_in_status_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value;
@@ -1130,7 +1176,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t dig_in_ctls[] = {
+static struct snd_kcontrol_new dig_in_ctls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
@@ -1161,8 +1207,8 @@
 int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
 {
 	int err;
-	snd_kcontrol_t *kctl;
-	snd_kcontrol_new_t *dig_mix;
+	struct snd_kcontrol *kctl;
+	struct snd_kcontrol_new *dig_mix;
 
 	for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
 		kctl = snd_ctl_new1(dig_mix, codec);
@@ -1175,6 +1221,31 @@
 }
 
 
+/*
+ * set power state of the codec
+ */
+static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+				unsigned int power_state)
+{
+	hda_nid_t nid, nid_start;
+	int nodes;
+
+	snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE,
+			    power_state);
+
+	nodes = snd_hda_get_sub_nodes(codec, fg, &nid_start);
+	for (nid = nid_start; nid < nodes + nid_start; nid++) {
+		if (get_wcaps(codec, nid) & AC_WCAP_POWER)
+			snd_hda_codec_write(codec, nid, 0,
+					    AC_VERB_SET_POWER_STATE,
+					    power_state);
+	}
+
+	if (power_state == AC_PWRST_D0)
+		msleep(10);
+}
+
+
 /**
  * snd_hda_build_controls - build mixer controls
  * @bus: the BUS
@@ -1202,6 +1273,9 @@
 	list_for_each(p, &bus->codec_list) {
 		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
 		int err;
+		hda_set_power_state(codec,
+				    codec->afg ? codec->afg : codec->mfg,
+				    AC_PWRST_D0);
 		if (! codec->patch_ops.init)
 			continue;
 		err = codec->patch_ops.init(codec);
@@ -1320,7 +1394,7 @@
 
 	val = 0;
 	if (nid != codec->afg &&
-	    snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_FORMAT_OVRD) {
+	    (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) {
 		val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
 		if (val == -1)
 			return -EIO;
@@ -1342,7 +1416,7 @@
 		unsigned int bps;
 		unsigned int wcaps;
 
-		wcaps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
+		wcaps = get_wcaps(codec, nid);
 		streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
 		if (streams == -1)
 			return -EIO;
@@ -1412,7 +1486,7 @@
 	unsigned int val = 0, rate, stream;
 
 	if (nid != codec->afg &&
-	    snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_FORMAT_OVRD) {
+	    (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) {
 		val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
 		if (val == -1)
 			return 0;
@@ -1478,7 +1552,7 @@
  */
 static int hda_pcm_default_open_close(struct hda_pcm_stream *hinfo,
 				      struct hda_codec *codec,
-				      snd_pcm_substream_t *substream)
+				      struct snd_pcm_substream *substream)
 {
 	return 0;
 }
@@ -1487,7 +1561,7 @@
 				   struct hda_codec *codec,
 				   unsigned int stream_tag,
 				   unsigned int format,
-				   snd_pcm_substream_t *substream)
+				   struct snd_pcm_substream *substream)
 {
 	snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
 	return 0;
@@ -1495,7 +1569,7 @@
 
 static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
 				   struct hda_codec *codec,
-				   snd_pcm_substream_t *substream)
+				   struct snd_pcm_substream *substream)
 {
 	snd_hda_codec_setup_stream(codec, hinfo->nid, 0, 0, 0);
 	return 0;
@@ -1626,30 +1700,90 @@
 /**
  * snd_hda_add_new_ctls - create controls from the array
  * @codec: the HDA codec
- * @knew: the array of snd_kcontrol_new_t
+ * @knew: the array of struct snd_kcontrol_new
  *
  * This helper function creates and add new controls in the given array.
  * The array must be terminated with an empty entry as terminator.
  *
  * Returns 0 if successful, or a negative error code.
  */
-int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew)
+int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
 {
 	int err;
 
 	for (; knew->name; knew++) {
-		err = snd_ctl_add(codec->bus->card, snd_ctl_new1(knew, codec));
-		if (err < 0)
-			return err;
+		struct snd_kcontrol *kctl;
+		kctl = snd_ctl_new1(knew, codec);
+		if (! kctl)
+			return -ENOMEM;
+		err = snd_ctl_add(codec->bus->card, kctl);
+		if (err < 0) {
+			if (! codec->addr)
+				return err;
+			kctl = snd_ctl_new1(knew, codec);
+			if (! kctl)
+				return -ENOMEM;
+			kctl->id.device = codec->addr;
+			if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0)
+				return err;
+		}
 	}
 	return 0;
 }
 
 
 /*
+ * Channel mode helper
+ */
+int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo,
+			 const struct hda_channel_mode *chmode, int num_chmodes)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = num_chmodes;
+	if (uinfo->value.enumerated.item >= num_chmodes)
+		uinfo->value.enumerated.item = num_chmodes - 1;
+	sprintf(uinfo->value.enumerated.name, "%dch",
+		chmode[uinfo->value.enumerated.item].channels);
+	return 0;
+}
+
+int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
+			const struct hda_channel_mode *chmode, int num_chmodes,
+			int max_channels)
+{
+	int i;
+
+	for (i = 0; i < num_chmodes; i++) {
+		if (max_channels == chmode[i].channels) {
+			ucontrol->value.enumerated.item[0] = i;
+			break;
+		}
+	}
+	return 0;
+}
+
+int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
+			const struct hda_channel_mode *chmode, int num_chmodes,
+			int *max_channelsp)
+{
+	unsigned int mode;
+
+	mode = ucontrol->value.enumerated.item[0];
+	snd_assert(mode < num_chmodes, return -EINVAL);
+	if (*max_channelsp == chmode[mode].channels && ! codec->in_resume)
+		return 0;
+	/* change the current channel setting */
+	*max_channelsp = chmode[mode].channels;
+	if (chmode[mode].sequence)
+		snd_hda_sequence_write(codec, chmode[mode].sequence);
+	return 1;
+}
+
+/*
  * input MUX helper
  */
-int snd_hda_input_mux_info(const struct hda_input_mux *imux, snd_ctl_elem_info_t *uinfo)
+int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo)
 {
 	unsigned int index;
 
@@ -1664,7 +1798,7 @@
 }
 
 int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
-			  snd_ctl_elem_value_t *ucontrol, hda_nid_t nid,
+			  struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
 			  unsigned int *cur_val)
 {
 	unsigned int idx;
@@ -1715,7 +1849,7 @@
  * set up more restrictions for analog out
  */
 int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
-				  snd_pcm_substream_t *substream)
+				  struct snd_pcm_substream *substream)
 {
 	substream->runtime->hw.channels_max = mout->max_channels;
 	return snd_pcm_hw_constraint_step(substream->runtime, 0,
@@ -1729,7 +1863,7 @@
 int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
 				     unsigned int stream_tag,
 				     unsigned int format,
-				     snd_pcm_substream_t *substream)
+				     struct snd_pcm_substream *substream)
 {
 	hda_nid_t *nids = mout->dac_nids;
 	int chs = substream->runtime->channels;
@@ -1792,8 +1926,18 @@
 /*
  * Helper for automatic ping configuration
  */
+
+static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
+{
+	for (; *list; list++)
+		if (*list == nid)
+			return 1;
+	return 0;
+}
+
 /* parse all pin widgets and store the useful pin nids to cfg */
-int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg)
+int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
+				 hda_nid_t *ignore_nids)
 {
 	hda_nid_t nid, nid_start;
 	int i, j, nodes;
@@ -1806,8 +1950,7 @@
 
 	nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
 	for (nid = nid_start; nid < nodes + nid_start; nid++) {
-		unsigned int wid_caps = snd_hda_param_read(codec, nid,
-							   AC_PAR_AUDIO_WIDGET_CAP);
+		unsigned int wid_caps = get_wcaps(codec, nid);
 		unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 		unsigned int def_conf;
 		short assoc, loc;
@@ -1815,13 +1958,16 @@
 		/* read all default configuration for pin complex */
 		if (wid_type != AC_WID_PIN)
 			continue;
+		/* ignore the given nids (e.g. pc-beep returns error) */
+		if (ignore_nids && is_in_nid_list(nid, ignore_nids))
+			continue;
+
 		def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
 		if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
 			continue;
 		loc = get_defcfg_location(def_conf);
 		switch (get_defcfg_device(def_conf)) {
 		case AC_JACK_LINE_OUT:
-		case AC_JACK_SPEAKER:
 			seq = get_defcfg_sequence(def_conf);
 			assoc = get_defcfg_association(def_conf);
 			if (! assoc)
@@ -1836,6 +1982,9 @@
 			sequences[cfg->line_outs] = seq;
 			cfg->line_outs++;
 			break;
+		case AC_JACK_SPEAKER:
+			cfg->speaker_pin = nid;
+			break;
 		case AC_JACK_HP_OUT:
 			cfg->hp_pin = nid;
 			break;
@@ -1902,6 +2051,12 @@
 	return 0;
 }
 
+/* labels for input pins */
+const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = {
+	"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
+};
+
+
 #ifdef CONFIG_PM
 /*
  * power management
@@ -1923,6 +2078,9 @@
 		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
 		if (codec->patch_ops.suspend)
 			codec->patch_ops.suspend(codec, state);
+		hda_set_power_state(codec,
+				    codec->afg ? codec->afg : codec->mfg,
+				    AC_PWRST_D3);
 	}
 	return 0;
 }
@@ -1940,6 +2098,9 @@
 
 	list_for_each(p, &bus->codec_list) {
 		struct hda_codec *codec = list_entry(p, struct hda_codec, list);
+		hda_set_power_state(codec,
+				    codec->afg ? codec->afg : codec->mfg,
+				    AC_PWRST_D0);
 		if (codec->patch_ops.resume)
 			codec->patch_ops.resume(codec);
 	}
@@ -1949,15 +2110,15 @@
 /**
  * snd_hda_resume_ctls - resume controls in the new control list
  * @codec: the HDA codec
- * @knew: the array of snd_kcontrol_new_t
+ * @knew: the array of struct snd_kcontrol_new
  *
- * This function resumes the mixer controls in the snd_kcontrol_new_t array,
+ * This function resumes the mixer controls in the struct snd_kcontrol_new array,
  * originally for snd_hda_add_new_ctls().
  * The array must be terminated with an empty entry as terminator.
  */
-int snd_hda_resume_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew)
+int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
 {
-	snd_ctl_elem_value_t *val;
+	struct snd_ctl_elem_value *val;
 
 	val = kmalloc(sizeof(*val), GFP_KERNEL);
 	if (! val)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 1179d6c..63e26c7 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -98,7 +98,7 @@
 #define AC_VERB_SET_UNSOLICITED_ENABLE		0x708
 #define AC_VERB_SET_PIN_SENSE			0x709
 #define AC_VERB_SET_BEEP_CONTROL		0x70a
-#define AC_VERB_SET_EAPD_BTLENALBE		0x70c
+#define AC_VERB_SET_EAPD_BTLENABLE		0x70c
 #define AC_VERB_SET_DIGI_CONVERT_1		0x70d
 #define AC_VERB_SET_DIGI_CONVERT_2		0x70e
 #define AC_VERB_SET_VOLUME_KNOB_CONTROL		0x70f
@@ -214,6 +214,12 @@
 #define AC_PWRST_D2SUP			(1<<2)
 #define AC_PWRST_D3SUP			(1<<3)
 
+/* Power state values */
+#define AC_PWRST_D0			0x00
+#define AC_PWRST_D1			0x01
+#define AC_PWRST_D2			0x02
+#define AC_PWRST_D3			0x03
+
 /* Processing capabilies */
 #define AC_PCAP_BENIGN			(1<<0)
 #define AC_PCAP_NUM_COEF		(0xff<<8)
@@ -376,7 +382,7 @@
 };
 
 /* max. connections to a widget */
-#define HDA_MAX_CONNECTIONS	16
+#define HDA_MAX_CONNECTIONS	32
 
 /* max. codec address */
 #define HDA_MAX_CODEC_ADDRESS	0x0f
@@ -420,7 +426,7 @@
  * A hda_bus contains several codecs in the list codec_list.
  */
 struct hda_bus {
-	snd_card_t *card;
+	struct snd_card *card;
 
 	/* copied from template */
 	void *private_data;
@@ -437,7 +443,7 @@
 	/* unsolicited event queue */
 	struct hda_bus_unsolicited *unsol;
 
-	snd_info_entry_t *proc;
+	struct snd_info_entry *proc;
 };
 
 /*
@@ -481,14 +487,14 @@
 /* PCM callbacks */
 struct hda_pcm_ops {
 	int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
-		    snd_pcm_substream_t *substream);
+		    struct snd_pcm_substream *substream);
 	int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
-		     snd_pcm_substream_t *substream);
+		     struct snd_pcm_substream *substream);
 	int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
 		       unsigned int stream_tag, unsigned int format,
-		       snd_pcm_substream_t *substream);
+		       struct snd_pcm_substream *substream);
 	int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
-		       snd_pcm_substream_t *substream);
+		       struct snd_pcm_substream *substream);
 };
 
 /* PCM information for each substream */
@@ -542,10 +548,16 @@
 	/* codec specific info */
 	void *spec;
 
+	/* widget capabilities cache */
+	unsigned int num_nodes;
+	hda_nid_t start_nid;
+	u32 *wcaps;
+
 	/* hash for amp access */
 	u16 amp_hash[32];
 	int num_amp_entries;
-	struct hda_amp_info amp_info[128]; /* big enough? */
+	int amp_info_size;
+	struct hda_amp_info *amp_info;
 
 	struct semaphore spdif_mutex;
 	unsigned int spdif_status;	/* IEC958 status bits */
@@ -562,7 +574,7 @@
 /*
  * constructors
  */
-int snd_hda_bus_new(snd_card_t *card, const struct hda_bus_template *temp,
+int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
 		    struct hda_bus **busp);
 int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
 		      struct hda_codec **codecp);
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index d0eb9f2..39edfcf 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -32,7 +32,8 @@
 struct hda_gnode {
 	hda_nid_t nid;		/* NID of this widget */
 	unsigned short nconns;	/* number of input connections */
-	hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; /* input connections */
+	hda_nid_t *conn_list;
+	hda_nid_t slist[2];	/* temporay list */
 	unsigned int wid_caps;	/* widget capabilities */
 	unsigned char type;	/* widget type */
 	unsigned char pin_ctl;	/* pin controls */
@@ -84,6 +85,8 @@
 	/* free all widgets */
 	list_for_each_safe(p, n, &spec->nid_list) {
 		struct hda_gnode *node = list_entry(p, struct hda_gnode, list);
+		if (node->conn_list != node->slist)
+			kfree(node->conn_list);
 		kfree(node);
 	}
 	kfree(spec);
@@ -97,18 +100,32 @@
 {
 	struct hda_gnode *node;
 	int nconns;
+	hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
 
 	node = kzalloc(sizeof(*node), GFP_KERNEL);
 	if (node == NULL)
 		return -ENOMEM;
 	node->nid = nid;
-	nconns = snd_hda_get_connections(codec, nid, node->conn_list, HDA_MAX_CONNECTIONS);
+	nconns = snd_hda_get_connections(codec, nid, conn_list,
+					 HDA_MAX_CONNECTIONS);
 	if (nconns < 0) {
 		kfree(node);
 		return nconns;
 	}
+	if (nconns <= ARRAY_SIZE(node->slist))
+		node->conn_list = node->slist;
+	else {
+		node->conn_list = kmalloc(sizeof(hda_nid_t) * nconns,
+					  GFP_KERNEL);
+		if (! node->conn_list) {
+			snd_printk(KERN_ERR "hda-generic: cannot malloc\n");
+			kfree(node);
+			return -ENOMEM;
+		}
+	}
+	memcpy(node->conn_list, conn_list, nconns);
 	node->nconns = nconns;
-	node->wid_caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
+	node->wid_caps = get_wcaps(codec, nid);
 	node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
 
 	if (node->type == AC_WID_PIN) {
@@ -389,14 +406,14 @@
  */
 
 /* control callbacks */
-static int capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct hda_gspec *spec = codec->spec;
 	return snd_hda_input_mux_info(&spec->input_mux, uinfo);
 }
 
-static int capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int capture_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct hda_gspec *spec = codec->spec;
@@ -405,7 +422,7 @@
 	return 0;
 }
 
-static int capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int capture_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct hda_gspec *spec = codec->spec;
@@ -617,7 +634,7 @@
 	char name[32];
 	int err;
 	int created = 0;
-	snd_kcontrol_new_t knew;
+	struct snd_kcontrol_new knew;
 
 	if (type)
 		sprintf(name, "%s %s Switch", type, dir_sfx);
@@ -625,14 +642,14 @@
 		sprintf(name, "%s Switch", dir_sfx);
 	if ((node->wid_caps & AC_WCAP_IN_AMP) &&
 	    (node->amp_in_caps & AC_AMPCAP_MUTE)) {
-		knew = (snd_kcontrol_new_t)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT);
+		knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, index, HDA_INPUT);
 		snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
 		if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
 			return err;
 		created = 1;
 	} else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
 		   (node->amp_out_caps & AC_AMPCAP_MUTE)) {
-		knew = (snd_kcontrol_new_t)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT);
+		knew = (struct snd_kcontrol_new)HDA_CODEC_MUTE(name, node->nid, 0, HDA_OUTPUT);
 		snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
 		if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
 			return err;
@@ -645,14 +662,14 @@
 		sprintf(name, "%s Volume", dir_sfx);
 	if ((node->wid_caps & AC_WCAP_IN_AMP) &&
 	    (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) {
-		knew = (snd_kcontrol_new_t)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
+		knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
 		snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
 		if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
 			return err;
 		created = 1;
 	} else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
 		   (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) {
-		knew = (snd_kcontrol_new_t)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
+		knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
 		snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
 		if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0)
 			return err;
@@ -667,7 +684,7 @@
  */
 static int check_existing_control(struct hda_codec *codec, const char *type, const char *dir)
 {
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 	memset(&id, 0, sizeof(id));
 	sprintf(id.name, "%s %s Volume", type, dir);
 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -710,7 +727,7 @@
 
 	/* create input MUX if multiple sources are available */
 	if (spec->input_mux.num_items > 1) {
-		static snd_kcontrol_new_t cap_sel = {
+		static struct snd_kcontrol_new cap_sel = {
 			.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 			.name = "Capture Source",
 			.info = capture_source_info,
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ed525c0..a983deb 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -37,6 +37,7 @@
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -51,6 +52,7 @@
 static char *id = SNDRV_DEFAULT_STR1;
 static char *model;
 static int position_fix;
+static int probe_mask = -1;
 
 module_param(index, int, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -60,6 +62,9 @@
 MODULE_PARM_DESC(model, "Use the given board model.");
 module_param(position_fix, int, 0444);
 MODULE_PARM_DESC(position_fix, "Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
+module_param(probe_mask, int, 0444);
+MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
+
 
 /* just for backward compatibility */
 static int enable;
@@ -237,11 +242,7 @@
 /*
  */
 
-typedef struct snd_azx azx_t;
-typedef struct snd_azx_rb azx_rb_t;
-typedef struct snd_azx_dev azx_dev_t;
-
-struct snd_azx_dev {
+struct azx_dev {
 	u32 *bdl;			/* virtual address of the BDL */
 	dma_addr_t bdl_addr;		/* physical address of the BDL */
 	volatile u32 *posbuf;			/* position buffer pointer */
@@ -257,7 +258,7 @@
 	u32 sd_int_sta_mask;		/* stream int status mask */
 
 	/* pcm support */
-	snd_pcm_substream_t *substream;	/* assigned substream, set in PCM open */
+	struct snd_pcm_substream *substream;	/* assigned substream, set in PCM open */
 	unsigned int format_val;	/* format value to be set in the controller and the codec */
 	unsigned char stream_tag;	/* assigned stream */
 	unsigned char index;		/* stream index */
@@ -268,7 +269,7 @@
 };
 
 /* CORB/RIRB */
-struct snd_azx_rb {
+struct azx_rb {
 	u32 *buf;		/* CORB/RIRB buffer
 				 * Each CORB entry is 4byte, RIRB is 8byte
 				 */
@@ -279,8 +280,8 @@
 	u32 res;		/* last read value */
 };
 
-struct snd_azx {
-	snd_card_t *card;
+struct azx {
+	struct snd_card *card;
 	struct pci_dev *pci;
 
 	/* chip type specific */
@@ -301,19 +302,19 @@
 	struct semaphore open_mutex;
 
 	/* streams (x num_streams) */
-	azx_dev_t *azx_dev;
+	struct azx_dev *azx_dev;
 
 	/* PCM */
 	unsigned int pcm_devs;
-	snd_pcm_t *pcm[AZX_MAX_PCMS];
+	struct snd_pcm *pcm[AZX_MAX_PCMS];
 
 	/* HD codec */
 	unsigned short codec_mask;
 	struct hda_bus *bus;
 
 	/* CORB/RIRB */
-	azx_rb_t corb;
-	azx_rb_t rirb;
+	struct azx_rb corb;
+	struct azx_rb rirb;
 
 	/* BDL, CORB/RIRB and position buffers */
 	struct snd_dma_buffer bdl;
@@ -374,7 +375,7 @@
 	readb((dev)->sd_addr + ICH6_REG_##reg)
 
 /* for pcm support */
-#define get_azx_dev(substream) (azx_dev_t*)(substream->runtime->private_data)
+#define get_azx_dev(substream) (substream->runtime->private_data)
 
 /* Get the upper 32bit of the given dma_addr_t
  * Compiler should optimize and eliminate the code if dma_addr_t is 32bit
@@ -390,7 +391,7 @@
 /*
  * CORB / RIRB interface
  */
-static int azx_alloc_cmd_io(azx_t *chip)
+static int azx_alloc_cmd_io(struct azx *chip)
 {
 	int err;
 
@@ -404,7 +405,7 @@
 	return 0;
 }
 
-static void azx_init_cmd_io(azx_t *chip)
+static void azx_init_cmd_io(struct azx *chip)
 {
 	/* CORB set up */
 	chip->corb.addr = chip->rb.addr;
@@ -442,7 +443,7 @@
 	chip->rirb.rp = chip->rirb.cmds = 0;
 }
 
-static void azx_free_cmd_io(azx_t *chip)
+static void azx_free_cmd_io(struct azx *chip)
 {
 	/* disable ringbuffer DMAs */
 	azx_writeb(chip, RIRBCTL, 0);
@@ -453,7 +454,7 @@
 static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
 			unsigned int verb, unsigned int para)
 {
-	azx_t *chip = codec->bus->private_data;
+	struct azx *chip = codec->bus->private_data;
 	unsigned int wp;
 	u32 val;
 
@@ -480,7 +481,7 @@
 #define ICH6_RIRB_EX_UNSOL_EV	(1<<4)
 
 /* retrieve RIRB entry - called from interrupt handler */
-static void azx_update_rirb(azx_t *chip)
+static void azx_update_rirb(struct azx *chip)
 {
 	unsigned int rp, wp;
 	u32 res, res_ex;
@@ -509,12 +510,14 @@
 /* receive a response */
 static unsigned int azx_get_response(struct hda_codec *codec)
 {
-	azx_t *chip = codec->bus->private_data;
+	struct azx *chip = codec->bus->private_data;
 	int timeout = 50;
 
 	while (chip->rirb.cmds) {
 		if (! --timeout) {
-			snd_printk(KERN_ERR "azx_get_response timeout\n");
+			if (printk_ratelimit())
+				snd_printk(KERN_ERR
+					"azx_get_response timeout\n");
 			chip->rirb.rp = azx_readb(chip, RIRBWP);
 			chip->rirb.cmds = 0;
 			return -1;
@@ -543,7 +546,7 @@
 static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
 			unsigned int verb, unsigned int para)
 {
-	azx_t *chip = codec->bus->private_data;
+	struct azx *chip = codec->bus->private_data;
 	u32 val;
 	int timeout = 50;
 
@@ -571,7 +574,7 @@
 /* receive a response */
 static unsigned int azx_get_response(struct hda_codec *codec)
 {
-	azx_t *chip = codec->bus->private_data;
+	struct azx *chip = codec->bus->private_data;
 	int timeout = 50;
 
 	while (timeout--) {
@@ -589,7 +592,7 @@
 #endif /* USE_CORB_RIRB */
 
 /* reset codec link */
-static int azx_reset(azx_t *chip)
+static int azx_reset(struct azx *chip)
 {
 	int count;
 
@@ -639,7 +642,7 @@
  */  
 
 /* enable interrupts */
-static void azx_int_enable(azx_t *chip)
+static void azx_int_enable(struct azx *chip)
 {
 	/* enable controller CIE and GIE */
 	azx_writel(chip, INTCTL, azx_readl(chip, INTCTL) |
@@ -647,13 +650,13 @@
 }
 
 /* disable interrupts */
-static void azx_int_disable(azx_t *chip)
+static void azx_int_disable(struct azx *chip)
 {
 	int i;
 
 	/* disable interrupts in stream descriptor */
 	for (i = 0; i < chip->num_streams; i++) {
-		azx_dev_t *azx_dev = &chip->azx_dev[i];
+		struct azx_dev *azx_dev = &chip->azx_dev[i];
 		azx_sd_writeb(azx_dev, SD_CTL,
 			      azx_sd_readb(azx_dev, SD_CTL) & ~SD_INT_MASK);
 	}
@@ -667,13 +670,13 @@
 }
 
 /* clear interrupts */
-static void azx_int_clear(azx_t *chip)
+static void azx_int_clear(struct azx *chip)
 {
 	int i;
 
 	/* clear stream status */
 	for (i = 0; i < chip->num_streams; i++) {
-		azx_dev_t *azx_dev = &chip->azx_dev[i];
+		struct azx_dev *azx_dev = &chip->azx_dev[i];
 		azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK);
 	}
 
@@ -688,7 +691,7 @@
 }
 
 /* start a stream */
-static void azx_stream_start(azx_t *chip, azx_dev_t *azx_dev)
+static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
 {
 	/* enable SIE */
 	azx_writeb(chip, INTCTL,
@@ -699,7 +702,7 @@
 }
 
 /* stop a stream */
-static void azx_stream_stop(azx_t *chip, azx_dev_t *azx_dev)
+static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
 {
 	/* stop DMA */
 	azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) &
@@ -714,7 +717,7 @@
 /*
  * initialize the chip
  */
-static void azx_init_chip(azx_t *chip)
+static void azx_init_chip(struct azx *chip)
 {
 	unsigned char reg;
 
@@ -762,8 +765,8 @@
  */
 static irqreturn_t azx_interrupt(int irq, void* dev_id, struct pt_regs *regs)
 {
-	azx_t *chip = dev_id;
-	azx_dev_t *azx_dev;
+	struct azx *chip = dev_id;
+	struct azx_dev *azx_dev;
 	u32 status;
 	int i;
 
@@ -811,7 +814,7 @@
 /*
  * set up BDL entries
  */
-static void azx_setup_periods(azx_dev_t *azx_dev)
+static void azx_setup_periods(struct azx_dev *azx_dev)
 {
 	u32 *bdl = azx_dev->bdl;
 	dma_addr_t dma_addr = azx_dev->substream->runtime->dma_addr;
@@ -840,7 +843,7 @@
 /*
  * set up the SD for streaming
  */
-static int azx_setup_controller(azx_t *chip, azx_dev_t *azx_dev)
+static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
 {
 	unsigned char val;
 	int timeout;
@@ -900,7 +903,7 @@
  * Codec initialization
  */
 
-static int __devinit azx_codec_create(azx_t *chip, const char *model)
+static int __devinit azx_codec_create(struct azx *chip, const char *model)
 {
 	struct hda_bus_template bus_temp;
 	int c, codecs, err;
@@ -917,7 +920,7 @@
 
 	codecs = 0;
 	for (c = 0; c < AZX_MAX_CODECS; c++) {
-		if (chip->codec_mask & (1 << c)) {
+		if ((chip->codec_mask & (1 << c)) & probe_mask) {
 			err = snd_hda_codec_new(chip->bus, c, NULL);
 			if (err < 0)
 				continue;
@@ -938,7 +941,7 @@
  */
 
 /* assign a stream for the PCM */
-static inline azx_dev_t *azx_assign_device(azx_t *chip, int stream)
+static inline struct azx_dev *azx_assign_device(struct azx *chip, int stream)
 {
 	int dev, i, nums;
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -957,12 +960,12 @@
 }
 
 /* release the assigned stream */
-static inline void azx_release_device(azx_dev_t *azx_dev)
+static inline void azx_release_device(struct azx_dev *azx_dev)
 {
 	azx_dev->opened = 0;
 }
 
-static snd_pcm_hardware_t azx_pcm_hw = {
+static struct snd_pcm_hardware azx_pcm_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
 				 SNDRV_PCM_INFO_MMAP_VALID |
@@ -983,18 +986,18 @@
 };
 
 struct azx_pcm {
-	azx_t *chip;
+	struct azx *chip;
 	struct hda_codec *codec;
 	struct hda_pcm_stream *hinfo[2];
 };
 
-static int azx_pcm_open(snd_pcm_substream_t *substream)
+static int azx_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
 	struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
-	azx_t *chip = apcm->chip;
-	azx_dev_t *azx_dev;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct azx *chip = apcm->chip;
+	struct azx_dev *azx_dev;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 	int err;
 
@@ -1026,12 +1029,12 @@
 	return 0;
 }
 
-static int azx_pcm_close(snd_pcm_substream_t *substream)
+static int azx_pcm_close(struct snd_pcm_substream *substream)
 {
 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
 	struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
-	azx_t *chip = apcm->chip;
-	azx_dev_t *azx_dev = get_azx_dev(substream);
+	struct azx *chip = apcm->chip;
+	struct azx_dev *azx_dev = get_azx_dev(substream);
 	unsigned long flags;
 
 	down(&chip->open_mutex);
@@ -1045,15 +1048,15 @@
 	return 0;
 }
 
-static int azx_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *hw_params)
+static int azx_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int azx_pcm_hw_free(snd_pcm_substream_t *substream)
+static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
 {
 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
-	azx_dev_t *azx_dev = get_azx_dev(substream);
+	struct azx_dev *azx_dev = get_azx_dev(substream);
 	struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
 
 	/* reset BDL address */
@@ -1066,13 +1069,13 @@
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int azx_pcm_prepare(snd_pcm_substream_t *substream)
+static int azx_pcm_prepare(struct snd_pcm_substream *substream)
 {
 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
-	azx_t *chip = apcm->chip;
-	azx_dev_t *azx_dev = get_azx_dev(substream);
+	struct azx *chip = apcm->chip;
+	struct azx_dev *azx_dev = get_azx_dev(substream);
 	struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	azx_dev->bufsize = snd_pcm_lib_buffer_bytes(substream);
 	azx_dev->fragsize = snd_pcm_lib_period_bytes(substream);
@@ -1101,11 +1104,11 @@
 				  azx_dev->format_val, substream);
 }
 
-static int azx_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
-	azx_dev_t *azx_dev = get_azx_dev(substream);
-	azx_t *chip = apcm->chip;
+	struct azx_dev *azx_dev = get_azx_dev(substream);
+	struct azx *chip = apcm->chip;
 	int err = 0;
 
 	spin_lock(&chip->reg_lock);
@@ -1136,11 +1139,11 @@
 	return err;
 }
 
-static snd_pcm_uframes_t azx_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
 {
 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
-	azx_t *chip = apcm->chip;
-	azx_dev_t *azx_dev = get_azx_dev(substream);
+	struct azx *chip = apcm->chip;
+	struct azx_dev *azx_dev = get_azx_dev(substream);
 	unsigned int pos;
 
 	if (chip->position_fix == POS_FIX_POSBUF) {
@@ -1151,38 +1154,13 @@
 		pos = azx_sd_readl(azx_dev, SD_LPIB);
 		if (chip->position_fix == POS_FIX_FIFO)
 			pos += azx_dev->fifo_size;
-#if 0 /* disabled temprarily, auto-correction doesn't work well... */
-		else if (chip->position_fix == POS_FIX_AUTO && azx_dev->period_updating) {
-			/* check the validity of DMA position */
-			unsigned int diff = 0;
-			azx_dev->last_pos += azx_dev->fragsize;
-			if (azx_dev->last_pos > pos)
-				diff = azx_dev->last_pos - pos;
-			if (azx_dev->last_pos >= azx_dev->bufsize) {
-				if (pos < azx_dev->fragsize)
-					diff = 0;
-				azx_dev->last_pos = 0;
-			}
-			if (diff > 0 && diff <= azx_dev->fifo_size)
-				pos += azx_dev->fifo_size;
-			else {
-				snd_printdd(KERN_INFO "hda_intel: DMA position fix %d, switching to posbuf\n", diff);
-				chip->position_fix = POS_FIX_POSBUF;
-				pos = *azx_dev->posbuf;
-			}
-			azx_dev->period_updating = 0;
-		}
-#else
-		else if (chip->position_fix == POS_FIX_AUTO)
-			pos += azx_dev->fifo_size;
-#endif
 	}
 	if (pos >= azx_dev->bufsize)
 		pos = 0;
 	return bytes_to_frames(substream->runtime, pos);
 }
 
-static snd_pcm_ops_t azx_pcm_ops = {
+static struct snd_pcm_ops azx_pcm_ops = {
 	.open = azx_pcm_open,
 	.close = azx_pcm_close,
 	.ioctl = snd_pcm_lib_ioctl,
@@ -1193,16 +1171,16 @@
 	.pointer = azx_pcm_pointer,
 };
 
-static void azx_pcm_free(snd_pcm_t *pcm)
+static void azx_pcm_free(struct snd_pcm *pcm)
 {
 	kfree(pcm->private_data);
 }
 
-static int __devinit create_codec_pcm(azx_t *chip, struct hda_codec *codec,
+static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
 				      struct hda_pcm *cpcm, int pcm_dev)
 {
 	int err;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	struct azx_pcm *apcm;
 
 	snd_assert(cpcm->stream[0].substreams || cpcm->stream[1].substreams, return -EINVAL);
@@ -1236,7 +1214,7 @@
 	return 0;
 }
 
-static int __devinit azx_pcm_create(azx_t *chip)
+static int __devinit azx_pcm_create(struct azx *chip)
 {
 	struct list_head *p;
 	struct hda_codec *codec;
@@ -1288,7 +1266,7 @@
 /*
  * mixer creation - all stuff is implemented in hda module
  */
-static int __devinit azx_mixer_create(azx_t *chip)
+static int __devinit azx_mixer_create(struct azx *chip)
 {
 	return snd_hda_build_controls(chip->bus);
 }
@@ -1297,7 +1275,7 @@
 /*
  * initialize SD streams
  */
-static int __devinit azx_init_stream(azx_t *chip)
+static int __devinit azx_init_stream(struct azx *chip)
 {
 	int i;
 
@@ -1306,7 +1284,7 @@
 	 */
 	for (i = 0; i < chip->num_streams; i++) {
 		unsigned int off = sizeof(u32) * (i * AZX_MAX_FRAG * 4);
-		azx_dev_t *azx_dev = &chip->azx_dev[i];
+		struct azx_dev *azx_dev = &chip->azx_dev[i];
 		azx_dev->bdl = (u32 *)(chip->bdl.area + off);
 		azx_dev->bdl_addr = chip->bdl.addr + off;
 		azx_dev->posbuf = (volatile u32 *)(chip->posbuf.area + i * 8);
@@ -1327,28 +1305,33 @@
 /*
  * power management
  */
-static int azx_suspend(snd_card_t *card, pm_message_t state)
+static int azx_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	azx_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct azx *chip = card->private_data;
 	int i;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	for (i = 0; i < chip->pcm_devs; i++)
-		if (chip->pcm[i])
-			snd_pcm_suspend_all(chip->pcm[i]);
+		snd_pcm_suspend_all(chip->pcm[i]);
 	snd_hda_suspend(chip->bus, state);
 	azx_free_cmd_io(chip);
-	pci_disable_device(chip->pci);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int azx_resume(snd_card_t *card)
+static int azx_resume(struct pci_dev *pci)
 {
-	azx_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct azx *chip = card->private_data;
 
-	pci_enable_device(chip->pci);
-	pci_set_master(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci);
 	azx_init_chip(chip);
 	snd_hda_resume(chip->bus);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -1357,7 +1340,7 @@
 /*
  * destructor
  */
-static int azx_free(azx_t *chip)
+static int azx_free(struct azx *chip)
 {
 	if (chip->initialized) {
 		int i;
@@ -1399,7 +1382,7 @@
 	return 0;
 }
 
-static int azx_dev_free(snd_device_t *device)
+static int azx_dev_free(struct snd_device *device)
 {
 	return azx_free(device->device_data);
 }
@@ -1407,13 +1390,13 @@
 /*
  * constructor
  */
-static int __devinit azx_create(snd_card_t *card, struct pci_dev *pci,
-				int posfix, int driver_type,
-				azx_t **rchip)
+static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
+				int driver_type,
+				struct azx **rchip)
 {
-	azx_t *chip;
+	struct azx *chip;
 	int err = 0;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free = azx_dev_free,
 	};
 
@@ -1437,7 +1420,7 @@
 	chip->irq = -1;
 	chip->driver_type = driver_type;
 
-	chip->position_fix = posfix;
+	chip->position_fix = position_fix ? position_fix : POS_FIX_POSBUF;
 
 #if BITS_PER_LONG != 64
 	/* Fix up base address on ULI M5461 */
@@ -1545,8 +1528,8 @@
 
 static int __devinit azx_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
-	snd_card_t *card;
-	azx_t *chip;
+	struct snd_card *card;
+	struct azx *chip;
 	int err = 0;
 
 	card = snd_card_new(index, id, THIS_MODULE, 0);
@@ -1555,11 +1538,12 @@
 		return -ENOMEM;
 	}
 
-	if ((err = azx_create(card, pci, position_fix, pci_id->driver_data,
+	if ((err = azx_create(card, pci, pci_id->driver_data,
 			      &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 
 	/* create codec instances */
 	if ((err = azx_codec_create(chip, model)) < 0) {
@@ -1579,7 +1563,6 @@
 		return err;
 	}
 
-	snd_card_set_pm_callback(card, azx_suspend, azx_resume, chip);
 	snd_card_set_dev(card, &pci->dev);
 
 	if ((err = snd_card_register(card)) < 0) {
@@ -1619,7 +1602,10 @@
 	.id_table = azx_ids,
 	.probe = azx_probe,
 	.remove = __devexit_p(azx_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = azx_suspend,
+	.resume = azx_resume,
+#endif
 };
 
 static int __init alsa_card_azx_init(void)
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index f51a56f..c82d2a7 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -60,12 +60,12 @@
 #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
 	HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
 
-int snd_hda_mixer_amp_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo);
-int snd_hda_mixer_amp_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
-int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
-int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo);
-int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
-int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
+int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
+int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
 
 /* mono switch binding multiple inputs */
 #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
@@ -78,8 +78,8 @@
 /* stereo switch binding multiple inputs */
 #define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
 
-int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
-int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol);
+int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
 
 int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
 int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
@@ -87,7 +87,7 @@
 /*
  * input MUX helper
  */
-#define HDA_MAX_NUM_INPUTS	8
+#define HDA_MAX_NUM_INPUTS	16
 struct hda_input_mux_item {
 	const char *label;
 	unsigned int index;
@@ -97,12 +97,29 @@
 	struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS];
 };
 
-int snd_hda_input_mux_info(const struct hda_input_mux *imux, snd_ctl_elem_info_t *uinfo);
+int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo);
 int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
-			  snd_ctl_elem_value_t *ucontrol, hda_nid_t nid,
+			  struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
 			  unsigned int *cur_val);
 
 /*
+ * Channel mode helper
+ */
+struct hda_channel_mode {
+	int channels;
+	const struct hda_verb *sequence;
+};
+
+int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo,
+			 const struct hda_channel_mode *chmode, int num_chmodes);
+int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
+			const struct hda_channel_mode *chmode, int num_chmodes,
+			int max_channels);
+int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
+			const struct hda_channel_mode *chmode, int num_chmodes,
+			int *max_channelsp);
+
+/*
  * Multi-channel / digital-out PCM helper
  */
 
@@ -121,11 +138,11 @@
 int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
 int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
 int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
-				  snd_pcm_substream_t *substream);
+				  struct snd_pcm_substream *substream);
 int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
 				     unsigned int stream_tag,
 				     unsigned int format,
-				     snd_pcm_substream_t *substream);
+				     struct snd_pcm_substream *substream);
 int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout);
 
 /*
@@ -153,13 +170,13 @@
 };
 
 int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl);
-int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew);
+int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew);
 
 /*
  * power management
  */
 #ifdef CONFIG_PM
-int snd_hda_resume_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew);
+int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew);
 int snd_hda_resume_spdif_out(struct hda_codec *codec);
 int snd_hda_resume_spdif_in(struct hda_codec *codec);
 #endif
@@ -194,9 +211,12 @@
 	AUTO_PIN_LAST
 };
 
+extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
+
 struct auto_pin_cfg {
 	int line_outs;
-	hda_nid_t line_out_pins[4]; /* sorted in the order of Front/Surr/CLFE/Side */
+	hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */
+	hda_nid_t speaker_pin;
 	hda_nid_t hp_pin;
 	hda_nid_t input_pins[AUTO_PIN_LAST];
 	hda_nid_t dig_out_pin;
@@ -209,6 +229,33 @@
 #define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE)
 #define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
 
-int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg);
+int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
+				 hda_nid_t *ignore_nids);
+
+/* amp values */
+#define AMP_IN_MUTE(idx)	(0x7080 | ((idx)<<8))
+#define AMP_IN_UNMUTE(idx)	(0x7000 | ((idx)<<8))
+#define AMP_OUT_MUTE	0xb080
+#define AMP_OUT_UNMUTE	0xb000
+#define AMP_OUT_ZERO	0xb000
+/* pinctl values */
+#define PIN_IN		0x20
+#define PIN_VREF80	0x24
+#define PIN_VREF50	0x21
+#define PIN_OUT		0x40
+#define PIN_HP		0xc0
+#define PIN_HP_AMP	0x80
+
+/*
+ * get widget capabilities
+ */
+static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
+{
+	if (nid < codec->start_nid ||
+	    nid >= codec->start_nid + codec->num_nodes)
+		return snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
+	return codec->wcaps[nid - codec->start_nid];
+}
+
 
 #endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 39ddf1c..ca514a6 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -26,6 +26,7 @@
 #include <linux/pci.h>
 #include <sound/core.h>
 #include "hda_codec.h"
+#include "hda_local.h"
 
 static const char *get_wid_type_name(unsigned int wid_value)
 {
@@ -47,7 +48,7 @@
 		return "UNKOWN Widget";
 }
 
-static void print_amp_caps(snd_info_buffer_t *buffer,
+static void print_amp_caps(struct snd_info_buffer *buffer,
 			   struct hda_codec *codec, hda_nid_t nid, int dir)
 {
 	unsigned int caps;
@@ -66,7 +67,7 @@
 		    (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT);
 }
 
-static void print_amp_vals(snd_info_buffer_t *buffer,
+static void print_amp_vals(struct snd_info_buffer *buffer,
 			   struct hda_codec *codec, hda_nid_t nid,
 			   int dir, int stereo, int indices)
 {
@@ -91,7 +92,7 @@
 	snd_iprintf(buffer, "\n");
 }
 
-static void print_pcm_caps(snd_info_buffer_t *buffer,
+static void print_pcm_caps(struct snd_info_buffer *buffer,
 			   struct hda_codec *codec, hda_nid_t nid)
 {
 	unsigned int pcm = snd_hda_param_read(codec, nid, AC_PAR_PCM);
@@ -160,7 +161,7 @@
 		return "UNKNOWN";
 }
 
-static void print_pin_caps(snd_info_buffer_t *buffer,
+static void print_pin_caps(struct snd_info_buffer *buffer,
 			   struct hda_codec *codec, hda_nid_t nid)
 {
 	static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
@@ -194,7 +195,7 @@
 }
 
 
-static void print_codec_info(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void print_codec_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
 	struct hda_codec *codec = entry->private_data;
 	char buf[32];
@@ -309,7 +310,7 @@
 int snd_hda_codec_proc_new(struct hda_codec *codec)
 {
 	char name[32];
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	int err;
 
 	snprintf(name, sizeof(name), "codec#%d", codec->addr);
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index d7d636d..1ada1b0 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1,5 +1,5 @@
 /*
- * HD audio interface patch for AD1981HD, AD1983, AD1986A
+ * HD audio interface patch for AD1981HD, AD1983, AD1986A, AD1988
  *
  * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
  *
@@ -28,10 +28,10 @@
 #include "hda_local.h"
 
 struct ad198x_spec {
-	snd_kcontrol_new_t *mixers[5];
+	struct snd_kcontrol_new *mixers[5];
 	int num_mixers;
 
-	const struct hda_verb *init_verbs[3];	/* initialization verbs
+	const struct hda_verb *init_verbs[5];	/* initialization verbs
 						 * don't forget NULL termination!
 						 */
 	unsigned int num_init_verbs;
@@ -41,6 +41,7 @@
 					 * max_channels, dacs must be set
 					 * dig_out_nid and hp_nid are optional
 					 */
+	unsigned int cur_eapd;
 
 	/* capture */
 	unsigned int num_adc_nids;
@@ -49,10 +50,11 @@
 
 	/* capture source */
 	const struct hda_input_mux *input_mux;
+	hda_nid_t *capsrc_nids;
 	unsigned int cur_mux[3];
 
 	/* channel model */
-	const struct alc_channel_mode *channel_mode;
+	const struct hda_channel_mode *channel_mode;
 	int num_channel_mode;
 
 	/* PCM information */
@@ -60,12 +62,19 @@
 
 	struct semaphore amp_mutex;	/* PCM volume/mute control mutex */
 	unsigned int spdif_route;
+
+	/* dynamic controls, init_verbs and input_mux */
+	struct auto_pin_cfg autocfg;
+	unsigned int num_kctl_alloc, num_kctl_used;
+	struct snd_kcontrol_new *kctl_alloc;
+	struct hda_input_mux private_imux;
+	hda_nid_t private_dac_nids[4];
 };
 
 /*
  * input MUX handling (common part)
  */
-static int ad198x_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
@@ -73,7 +82,7 @@
 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
 }
 
-static int ad198x_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
@@ -83,14 +92,15 @@
 	return 0;
 }
 
-static int ad198x_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
 	unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 
 	return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
-				     spec->adc_nids[adc_idx], &spec->cur_mux[adc_idx]);
+				     spec->capsrc_nids[adc_idx],
+				     &spec->cur_mux[adc_idx]);
 }
 
 /*
@@ -135,7 +145,7 @@
  */
 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
 				    struct hda_codec *codec,
-				    snd_pcm_substream_t *substream)
+				    struct snd_pcm_substream *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
@@ -145,7 +155,7 @@
 				       struct hda_codec *codec,
 				       unsigned int stream_tag,
 				       unsigned int format,
-				       snd_pcm_substream_t *substream)
+				       struct snd_pcm_substream *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
@@ -154,7 +164,7 @@
 
 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 				       struct hda_codec *codec,
-				       snd_pcm_substream_t *substream)
+				       struct snd_pcm_substream *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
@@ -165,7 +175,7 @@
  */
 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 					struct hda_codec *codec,
-					snd_pcm_substream_t *substream)
+					struct snd_pcm_substream *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
@@ -173,7 +183,7 @@
 
 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 					 struct hda_codec *codec,
-					 snd_pcm_substream_t *substream)
+					 struct snd_pcm_substream *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
@@ -186,7 +196,7 @@
 				      struct hda_codec *codec,
 				      unsigned int stream_tag,
 				      unsigned int format,
-				      snd_pcm_substream_t *substream)
+				      struct snd_pcm_substream *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
@@ -196,7 +206,7 @@
 
 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 				      struct hda_codec *codec,
-				      snd_pcm_substream_t *substream)
+				      struct snd_pcm_substream *substream)
 {
 	struct ad198x_spec *spec = codec->spec;
 	snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
@@ -281,6 +291,14 @@
 
 static void ad198x_free(struct hda_codec *codec)
 {
+	struct ad198x_spec *spec = codec->spec;
+	unsigned int i;
+
+	if (spec->kctl_alloc) {
+		for (i = 0; i < spec->num_kctl_used; i++)
+			kfree(spec->kctl_alloc[i].name);
+		kfree(spec->kctl_alloc);
+	}
 	kfree(codec->spec);
 }
 
@@ -348,7 +366,7 @@
 
 #define ad1986a_pcm_amp_vol_info	snd_hda_mixer_amp_volume_info
 
-static int ad1986a_pcm_amp_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ad1986a_pcm_amp_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *ad = codec->spec;
@@ -359,7 +377,7 @@
 	return 0;
 }
 
-static int ad1986a_pcm_amp_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ad1986a_pcm_amp_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *ad = codec->spec;
@@ -377,7 +395,7 @@
 
 #define ad1986a_pcm_amp_sw_info		snd_hda_mixer_amp_switch_info
 
-static int ad1986a_pcm_amp_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ad1986a_pcm_amp_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *ad = codec->spec;
@@ -388,7 +406,7 @@
 	return 0;
 }
 
-static int ad1986a_pcm_amp_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ad1986a_pcm_amp_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *ad = codec->spec;
@@ -407,7 +425,7 @@
 /*
  * mixers
  */
-static snd_kcontrol_new_t ad1986a_mixers[] = {
+static struct snd_kcontrol_new ad1986a_mixers[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "PCM Playback Volume",
@@ -535,6 +553,7 @@
 	spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
 	spec->num_adc_nids = 1;
 	spec->adc_nids = ad1986a_adc_nids;
+	spec->capsrc_nids = ad1986a_adc_nids;
 	spec->input_mux = &ad1986a_capture_source;
 	spec->num_mixers = 1;
 	spec->mixers[0] = ad1986a_mixers;
@@ -570,7 +589,7 @@
 /*
  * SPDIF playback route
  */
-static int ad1983_spdif_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "PCM", "ADC" };
 
@@ -583,7 +602,7 @@
 	return 0;
 }
 
-static int ad1983_spdif_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
@@ -592,7 +611,7 @@
 	return 0;
 }
 
-static int ad1983_spdif_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct ad198x_spec *spec = codec->spec;
@@ -606,7 +625,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t ad1983_mixers[] = {
+static struct snd_kcontrol_new ad1983_mixers[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
@@ -698,6 +717,7 @@
 	spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
 	spec->num_adc_nids = 1;
 	spec->adc_nids = ad1983_adc_nids;
+	spec->capsrc_nids = ad1983_adc_nids;
 	spec->input_mux = &ad1983_capture_source;
 	spec->num_mixers = 1;
 	spec->mixers[0] = ad1983_mixers;
@@ -736,7 +756,7 @@
 	},
 };
 
-static snd_kcontrol_new_t ad1981_mixers[] = {
+static struct snd_kcontrol_new ad1981_mixers[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
@@ -843,6 +863,7 @@
 	spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
 	spec->num_adc_nids = 1;
 	spec->adc_nids = ad1981_adc_nids;
+	spec->capsrc_nids = ad1981_adc_nids;
 	spec->input_mux = &ad1981_capture_source;
 	spec->num_mixers = 1;
 	spec->mixers[0] = ad1981_mixers;
@@ -857,11 +878,1278 @@
 
 
 /*
+ * AD1988
+ *
+ * Output pins and routes
+ *
+ *        Pin               Mix     Sel     DAC (*)
+ * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
+ * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
+ * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
+ * port-D 0x12 (mute/hp) <- 0x29         <- 04
+ * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
+ * port-F 0x16 (mute)    <- 0x2a         <- 06
+ * port-G 0x24 (mute)    <- 0x27         <- 05
+ * port-H 0x25 (mute)    <- 0x28         <- 0a
+ * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
+ *
+ * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
+ * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
+ *
+ * Input pins and routes
+ *
+ *        pin     boost   mix input # / adc input #
+ * port-A 0x11 -> 0x38 -> mix 2, ADC 0
+ * port-B 0x14 -> 0x39 -> mix 0, ADC 1
+ * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
+ * port-D 0x12 -> 0x3d -> mix 3, ADC 8
+ * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
+ * port-F 0x16 -> 0x3b -> mix 5, ADC 3
+ * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
+ * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
+ *
+ *
+ * DAC assignment
+ *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
+ *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
+ *
+ * Inputs of Analog Mix (0x20)
+ *   0:Port-B (front mic)
+ *   1:Port-C/G/H (line-in)
+ *   2:Port-A
+ *   3:Port-D (line-in/2)
+ *   4:Port-E/G/H (mic-in)
+ *   5:Port-F (mic2-in)
+ *   6:CD
+ *   7:Beep
+ *
+ * ADC selection
+ *   0:Port-A
+ *   1:Port-B (front mic-in)
+ *   2:Port-C (line-in)
+ *   3:Port-F (mic2-in)
+ *   4:Port-E (mic-in)
+ *   5:CD
+ *   6:Port-G
+ *   7:Port-H
+ *   8:Port-D (line-in/2)
+ *   9:Mix
+ *
+ * Proposed pin assignments by the datasheet
+ *
+ * 6-stack
+ * Port-A front headphone
+ *      B front mic-in
+ *      C rear line-in
+ *      D rear front-out
+ *      E rear mic-in
+ *      F rear surround
+ *      G rear CLFE
+ *      H rear side
+ *
+ * 3-stack
+ * Port-A front headphone
+ *      B front mic
+ *      C rear line-in/surround
+ *      D rear front-out
+ *      E rear mic-in/CLFE
+ *
+ * laptop
+ * Port-A headphone
+ *      B mic-in
+ *      C docking station
+ *      D internal speaker (with EAPD)
+ *      E/F quad mic array
+ */
+
+
+/* models */
+enum {
+	AD1988_6STACK,
+	AD1988_6STACK_DIG,
+	AD1988_3STACK,
+	AD1988_3STACK_DIG,
+	AD1988_LAPTOP,
+	AD1988_LAPTOP_DIG,
+	AD1988_AUTO,
+	AD1988_MODEL_LAST,
+};
+
+/* reivision id to check workarounds */
+#define AD1988A_REV2		0x100200
+
+
+/*
+ * mixers
+ */
+
+static hda_nid_t ad1988_6stack_dac_nids[4] = {
+	0x04, 0x06, 0x05, 0x0a
+};
+
+static hda_nid_t ad1988_3stack_dac_nids[3] = {
+	0x04, 0x05, 0x0a
+};
+
+/* for AD1988A revision-2, DAC2-4 are swapped */
+static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
+	0x04, 0x05, 0x0a, 0x06
+};
+
+static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
+	0x04, 0x0a, 0x06
+};
+
+static hda_nid_t ad1988_adc_nids[3] = {
+	0x08, 0x09, 0x0f
+};
+
+static hda_nid_t ad1988_capsrc_nids[3] = {
+	0x0c, 0x0d, 0x0e
+};
+
+#define AD1988_SPDIF_OUT	0x02
+#define AD1988_SPDIF_IN		0x07
+
+static struct hda_input_mux ad1988_6stack_capture_source = {
+	.num_items = 5,
+	.items = {
+		{ "Front Mic", 0x0 },
+		{ "Line", 0x1 },
+		{ "Mic", 0x4 },
+		{ "CD", 0x5 },
+		{ "Mix", 0x9 },
+	},
+};
+
+static struct hda_input_mux ad1988_laptop_capture_source = {
+	.num_items = 3,
+	.items = {
+		{ "Mic/Line", 0x0 },
+		{ "CD", 0x5 },
+		{ "Mix", 0x9 },
+	},
+};
+
+/*
+ */
+static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
+				    spec->num_channel_mode);
+}
+
+static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
+				   spec->num_channel_mode, spec->multiout.max_channels);
+}
+
+static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+	return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
+				   spec->num_channel_mode, &spec->multiout.max_channels);
+}
+
+/*
+ * EAPD control
+ */
+static int ad1988_eapd_info(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int ad1988_eapd_get(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+	ucontrol->value.enumerated.item[0] = ! spec->cur_eapd;
+	return 0;
+}
+
+static int ad1988_eapd_put(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct ad198x_spec *spec = codec->spec;
+	unsigned int eapd;
+	eapd = ! ucontrol->value.enumerated.item[0];
+	if (eapd == spec->cur_eapd && ! codec->in_resume)
+		return 0;
+	spec->cur_eapd = eapd;
+	snd_hda_codec_write(codec, 0x12 /* port-D */,
+			    0, AC_VERB_SET_EAPD_BTLENABLE,
+			    eapd ? 0x02 : 0x00);
+	return 0;
+}
+
+/* 6-stack mode */
+static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
+};
+
+static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
+};
+
+static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
+	HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
+
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
+
+	HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+
+	HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
+
+	HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
+
+	{ } /* end */
+};
+
+/* 3-stack mode */
+static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
+};
+
+static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
+};
+
+static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
+	HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
+	HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
+	HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
+
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
+
+	HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+
+	HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
+
+	HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Channel Mode",
+		.info = ad198x_ch_mode_info,
+		.get = ad198x_ch_mode_get,
+		.put = ad198x_ch_mode_put,
+	},
+
+	{ } /* end */
+};
+
+/* laptop mode */
+static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
+	HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
+	HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
+
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
+
+	HDA_CODEC_VOLUME("Beep Playback Volume", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Beep Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+
+	HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
+
+	HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT),
+
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "External Amplifier",
+		.info = ad1988_eapd_info,
+		.get = ad1988_eapd_get,
+		.put = ad1988_eapd_put,
+	},
+
+	{ } /* end */
+};
+
+/* capture */
+static struct snd_kcontrol_new ad1988_capture_mixers[] = {
+	HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* The multiple "Capture Source" controls confuse alsamixer
+		 * So call somewhat different..
+		 * FIXME: the controls appear in the "playback" view!
+		 */
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 3,
+		.info = ad198x_mux_enum_info,
+		.get = ad198x_mux_enum_get,
+		.put = ad198x_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
+{
+	static char *texts[] = {
+		"PCM", "ADC1", "ADC2", "ADC3"
+	};
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 4;
+	if (uinfo->value.enumerated.item >= 4)
+		uinfo->value.enumerated.item = 3;
+	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	unsigned int sel;
+
+	sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
+	if (sel > 0) {
+		sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0);
+		if (sel <= 3)
+			sel++;
+		else
+			sel = 0;
+	}
+	ucontrol->value.enumerated.item[0] = sel;
+	return 0;
+}
+
+static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	unsigned int sel;
+	int change;
+
+	sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0);
+	if (! ucontrol->value.enumerated.item[0]) {
+		change = sel != 0;
+		if (change)
+			snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0);
+	} else {
+		change = sel == 0;
+		if (change)
+			snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1);
+		sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1;
+		change |= sel == ucontrol->value.enumerated.item[0];
+		if (change)
+			snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL,
+					    ucontrol->value.enumerated.item[0] - 1);
+	}
+	return change;
+}
+
+static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
+	HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "IEC958 Playback Source",
+		.info = ad1988_spdif_playback_source_info,
+		.get = ad1988_spdif_playback_source_get,
+		.put = ad1988_spdif_playback_source_put,
+	},
+	{ } /* end */
+};
+
+static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
+	HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
+	{ } /* end */
+};
+
+
+/*
+ * initialization verbs
+ */
+
+/*
+ * for 6-stack (+dig)
+ */
+static struct hda_verb ad1988_6stack_init_verbs[] = {
+	/* Front, Surround, CLFE, side DAC; unmute as default */
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Port-A front headphon path */
+	{0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	/* Port-D line-out path */
+	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	/* Port-F surround path */
+	{0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	/* Port-G CLFE path */
+	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	/* Port-H side path */
+	{0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	/* Mono out path */
+	{0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
+	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
+	/* Port-B front mic-in path */
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* Port-C line-in path */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Port-E mic-in path */
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
+
+	{ }
+};
+
+static struct hda_verb ad1988_capture_init_verbs[] = {
+	/* mute analog mix */
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
+	/* select ADCs - front-mic */
+	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
+	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
+	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
+	/* ADCs; muted */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+
+	{ }
+};
+
+static struct hda_verb ad1988_spdif_init_verbs[] = {
+	/* SPDIF out sel */
+	{0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
+	{0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
+	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	/* SPDIF out pin */
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x17}, /* 0dB */
+
+	{ }
+};
+
+/*
+ * verbs for 3stack (+dig)
+ */
+static struct hda_verb ad1988_3stack_ch2_init[] = {
+	/* set port-C to line-in */
+	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+	/* set port-E to mic-in */
+	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+	{ } /* end */
+};
+
+static struct hda_verb ad1988_3stack_ch6_init[] = {
+	/* set port-C to surround out */
+	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	/* set port-E to CLFE out */
+	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	{ } /* end */
+};
+
+static struct hda_channel_mode ad1988_3stack_modes[2] = {
+	{ 2, ad1988_3stack_ch2_init },
+	{ 6, ad1988_3stack_ch6_init },
+};
+
+static struct hda_verb ad1988_3stack_init_verbs[] = {
+	/* Front, Surround, CLFE, side DAC; unmute as default */
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Port-A front headphon path */
+	{0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	/* Port-D line-out path */
+	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	/* Mono out path */
+	{0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
+	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
+	/* Port-B front mic-in path */
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* Port-C line-in/surround path - 6ch mode as default */
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
+	{0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* Port-E mic-in/CLFE path - 6ch mode as default */
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
+	{0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* mute analog mix */
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
+	/* select ADCs - front-mic */
+	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
+	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
+	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
+	/* ADCs; muted */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{ }
+};
+
+/*
+ * verbs for laptop mode (+dig)
+ */
+static struct hda_verb ad1988_laptop_hp_on[] = {
+	/* unmute port-A and mute port-D */
+	{ 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	{ 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ } /* end */
+};
+static struct hda_verb ad1988_laptop_hp_off[] = {
+	/* mute port-A and unmute port-D */
+	{ 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	{ } /* end */
+};
+
+#define AD1988_HP_EVENT	0x01
+
+static struct hda_verb ad1988_laptop_init_verbs[] = {
+	/* Front, Surround, CLFE, side DAC; unmute as default */
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Port-A front headphon path */
+	{0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	/* unsolicited event for pin-sense */
+	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
+	/* Port-D line-out path + EAPD */
+	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
+	/* Mono out path */
+	{0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
+	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
+	/* Port-B mic-in path */
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* Port-C docking station - try to output */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
+	/* mute analog mix */
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
+	{0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
+	/* select ADCs - mic */
+	{0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
+	{0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
+	{0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
+	/* ADCs; muted */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{ }
+};
+
+static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+	if ((res >> 26) != AD1988_HP_EVENT)
+		return;
+	if (snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & (1 << 31))
+		snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
+	else
+		snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
+} 
+
+
+/*
+ * Automatic parse of I/O pins from the BIOS configuration
+ */
+
+#define NUM_CONTROL_ALLOC	32
+#define NUM_VERB_ALLOC		32
+
+enum {
+	AD_CTL_WIDGET_VOL,
+	AD_CTL_WIDGET_MUTE,
+	AD_CTL_BIND_MUTE,
+};
+static struct snd_kcontrol_new ad1988_control_templates[] = {
+	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
+	HDA_CODEC_MUTE(NULL, 0, 0, 0),
+	HDA_BIND_MUTE(NULL, 0, 0, 0),
+};
+
+/* add dynamic controls */
+static int add_control(struct ad198x_spec *spec, int type, const char *name,
+		       unsigned long val)
+{
+	struct snd_kcontrol_new *knew;
+
+	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
+		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
+
+		knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */
+		if (! knew)
+			return -ENOMEM;
+		if (spec->kctl_alloc) {
+			memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
+			kfree(spec->kctl_alloc);
+		}
+		spec->kctl_alloc = knew;
+		spec->num_kctl_alloc = num;
+	}
+
+	knew = &spec->kctl_alloc[spec->num_kctl_used];
+	*knew = ad1988_control_templates[type];
+	knew->name = kstrdup(name, GFP_KERNEL);
+	if (! knew->name)
+		return -ENOMEM;
+	knew->private_value = val;
+	spec->num_kctl_used++;
+	return 0;
+}
+
+#define AD1988_PIN_CD_NID		0x18
+#define AD1988_PIN_BEEP_NID		0x10
+
+static hda_nid_t ad1988_mixer_nids[8] = {
+	/* A     B     C     D     E     F     G     H */
+	0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
+};
+
+static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
+{
+	static hda_nid_t idx_to_dac[8] = {
+		/* A     B     C     D     E     F     G     H */
+		0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
+	};
+	static hda_nid_t idx_to_dac_rev2[8] = {
+		/* A     B     C     D     E     F     G     H */
+		0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
+	};
+	if (codec->revision_id == AD1988A_REV2)
+		return idx_to_dac_rev2[idx];
+	else
+		return idx_to_dac[idx];
+}
+
+static hda_nid_t ad1988_boost_nids[8] = {
+	0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
+};
+
+static int ad1988_pin_idx(hda_nid_t nid)
+{
+	static hda_nid_t ad1988_io_pins[8] = {
+		0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
+	};
+	int i;
+	for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
+		if (ad1988_io_pins[i] == nid)
+			return i;
+	return 0; /* should be -1 */
+}
+
+static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
+{
+	static int loopback_idx[8] = {
+		2, 0, 1, 3, 4, 5, 1, 4
+	};
+	switch (nid) {
+	case AD1988_PIN_CD_NID:
+		return 6;
+	default:
+		return loopback_idx[ad1988_pin_idx(nid)];
+	}
+}
+
+static int ad1988_pin_to_adc_idx(hda_nid_t nid)
+{
+	static int adc_idx[8] = {
+		0, 1, 2, 8, 4, 3, 6, 7
+	};
+	switch (nid) {
+	case AD1988_PIN_CD_NID:
+		return 5;
+	default:
+		return adc_idx[ad1988_pin_idx(nid)];
+	}
+}
+
+/* fill in the dac_nids table from the parsed pin configuration */
+static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
+				     const struct auto_pin_cfg *cfg)
+{
+	struct ad198x_spec *spec = codec->spec;
+	int i, idx;
+
+	spec->multiout.dac_nids = spec->private_dac_nids;
+
+	/* check the pins hardwired to audio widget */
+	for (i = 0; i < cfg->line_outs; i++) {
+		idx = ad1988_pin_idx(cfg->line_out_pins[i]);
+		spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
+	}
+	spec->multiout.num_dacs = cfg->line_outs;
+	return 0;
+}
+
+/* add playback controls from the parsed DAC table */
+static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
+					     const struct auto_pin_cfg *cfg)
+{
+	char name[32];
+	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+	hda_nid_t nid;
+	int i, err;
+
+	for (i = 0; i < cfg->line_outs; i++) {
+		hda_nid_t dac = spec->multiout.dac_nids[i];
+		if (! dac)
+			continue;
+		nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
+		if (i == 2) {
+			/* Center/LFE */
+			err = add_control(spec, AD_CTL_WIDGET_VOL,
+					  "Center Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
+			if (err < 0)
+				return err;
+			err = add_control(spec, AD_CTL_WIDGET_VOL,
+					  "LFE Playback Volume",
+					  HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
+			if (err < 0)
+				return err;
+			err = add_control(spec, AD_CTL_BIND_MUTE,
+					  "Center Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
+			if (err < 0)
+				return err;
+			err = add_control(spec, AD_CTL_BIND_MUTE,
+					  "LFE Playback Switch",
+					  HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
+			if (err < 0)
+				return err;
+		} else {
+			sprintf(name, "%s Playback Volume", chname[i]);
+			err = add_control(spec, AD_CTL_WIDGET_VOL, name,
+					  HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
+			if (err < 0)
+				return err;
+			sprintf(name, "%s Playback Switch", chname[i]);
+			err = add_control(spec, AD_CTL_BIND_MUTE, name,
+					  HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
+			if (err < 0)
+				return err;
+		}
+	}
+	return 0;
+}
+
+/* add playback controls for speaker and HP outputs */
+static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
+					const char *pfx)
+{
+	struct ad198x_spec *spec = codec->spec;
+	hda_nid_t nid;
+	int idx, err;
+	char name[32];
+
+	if (! pin)
+		return 0;
+
+	idx = ad1988_pin_idx(pin);
+	nid = ad1988_idx_to_dac(codec, idx);
+	if (! spec->multiout.dac_nids[0]) {
+		/* use this as the primary output */
+		spec->multiout.dac_nids[0] = nid;
+		if (! spec->multiout.num_dacs)
+			spec->multiout.num_dacs = 1;
+	} else 
+		/* specify the DAC as the extra output */
+		spec->multiout.hp_nid = nid;
+	/* control HP volume/switch on the output mixer amp */
+	sprintf(name, "%s Playback Volume", pfx);
+	if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
+			       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+		return err;
+	nid = ad1988_mixer_nids[idx];
+	sprintf(name, "%s Playback Switch", pfx);
+	if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
+			       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
+		return err;
+	return 0;
+}
+
+/* create input playback/capture controls for the given pin */
+static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
+			    const char *ctlname, int boost)
+{
+	char name[32];
+	int err, idx;
+
+	sprintf(name, "%s Playback Volume", ctlname);
+	idx = ad1988_pin_to_loopback_idx(pin);
+	if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
+			       HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
+		return err;
+	sprintf(name, "%s Playback Switch", ctlname);
+	if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
+			       HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
+		return err;
+	if (boost) {
+		hda_nid_t bnid;
+		idx = ad1988_pin_idx(pin);
+		bnid = ad1988_boost_nids[idx];
+		if (bnid) {
+			sprintf(name, "%s Boost", ctlname);
+			return add_control(spec, AD_CTL_WIDGET_VOL, name,
+					   HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
+
+		}
+	}
+	return 0;
+}
+
+/* create playback/capture controls for input pins */
+static int ad1988_auto_create_analog_input_ctls(struct ad198x_spec *spec,
+						const struct auto_pin_cfg *cfg)
+{
+	struct hda_input_mux *imux = &spec->private_imux;
+	int i, err;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		err = new_analog_input(spec, cfg->input_pins[i],
+				       auto_pin_cfg_labels[i],
+				       i <= AUTO_PIN_FRONT_MIC);
+		if (err < 0)
+			return err;
+		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+		imux->items[imux->num_items].index = ad1988_pin_to_adc_idx(cfg->input_pins[i]);
+		imux->num_items++;
+	}
+	imux->items[imux->num_items].label = "Mix";
+	imux->items[imux->num_items].index = 9;
+	imux->num_items++;
+
+	if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
+			       "Analog Mix Playback Volume",
+			       HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
+		return err;
+	if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
+			       "Analog Mix Playback Switch",
+			       HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
+		return err;
+
+	return 0;
+}
+
+static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
+					      hda_nid_t nid, int pin_type,
+					      int dac_idx)
+{
+	/* set as output */
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+	switch (nid) {
+	case 0x11: /* port-A - DAC 04 */
+		snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
+		break;
+	case 0x14: /* port-B - DAC 06 */
+		snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
+		break;
+	case 0x15: /* port-C - DAC 05 */
+		snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
+		break;
+	case 0x17: /* port-E - DAC 0a */
+		snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
+		break;
+	case 0x13: /* mono - DAC 04 */
+		snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
+		break;
+	}
+}
+
+static void ad1988_auto_init_multi_out(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < spec->autocfg.line_outs; i++) {
+		hda_nid_t nid = spec->autocfg.line_out_pins[i];
+		ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+	}
+}
+
+static void ad1988_auto_init_extra_out(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec = codec->spec;
+	hda_nid_t pin;
+
+	pin = spec->autocfg.speaker_pin;
+	if (pin) /* connect to front */
+		ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
+	pin = spec->autocfg.hp_pin;
+	if (pin) /* connect to front */
+		ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
+}
+
+static void ad1988_auto_init_analog_input(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec = codec->spec;
+	int i, idx;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		hda_nid_t nid = spec->autocfg.input_pins[i];
+		if (! nid)
+			continue;
+		switch (nid) {
+		case 0x15: /* port-C */
+			snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
+			break;
+		case 0x17: /* port-E */
+			snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
+			break;
+		}
+		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+				    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+		if (nid != AD1988_PIN_CD_NID)
+			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+					    AMP_OUT_MUTE);
+		idx = ad1988_pin_idx(nid);
+		if (ad1988_boost_nids[idx])
+			snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
+					    AC_VERB_SET_AMP_GAIN_MUTE,
+					    AMP_OUT_ZERO);
+	}
+}
+
+/* parse the BIOS configuration and set up the alc_spec */
+/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
+static int ad1988_parse_auto_config(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec = codec->spec;
+	int err;
+
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
+		return err;
+	if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
+		return err;
+	if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
+	    ! spec->autocfg.hp_pin)
+		return 0; /* can't find valid BIOS pin config */
+	if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
+	    (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin,
+						"Speaker")) < 0 ||
+	    (err = ad1988_auto_create_extra_out(codec, spec->autocfg.speaker_pin,
+						"Headphone")) < 0 ||
+	    (err = ad1988_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+		return err;
+
+	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+
+	if (spec->autocfg.dig_out_pin)
+		spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
+	if (spec->autocfg.dig_in_pin)
+		spec->dig_in_nid = AD1988_SPDIF_IN;
+
+	if (spec->kctl_alloc)
+		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+	spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
+
+	spec->input_mux = &spec->private_imux;
+
+	return 1;
+}
+
+/* init callback for auto-configuration model -- overriding the default init */
+static int ad1988_auto_init(struct hda_codec *codec)
+{
+	ad198x_init(codec);
+	ad1988_auto_init_multi_out(codec);
+	ad1988_auto_init_extra_out(codec);
+	ad1988_auto_init_analog_input(codec);
+	return 0;
+}
+
+
+/*
+ */
+
+static struct hda_board_config ad1988_cfg_tbl[] = {
+	{ .modelname = "6stack",	.config = AD1988_6STACK },
+	{ .modelname = "6stack-dig",	.config = AD1988_6STACK_DIG },
+	{ .modelname = "3stack",	.config = AD1988_3STACK },
+	{ .modelname = "3stack-dig",	.config = AD1988_3STACK_DIG },
+	{ .modelname = "laptop",	.config = AD1988_LAPTOP },
+	{ .modelname = "laptop-dig",	.config = AD1988_LAPTOP_DIG },
+	{ .modelname = "auto",		.config = AD1988_AUTO },
+	{}
+};
+
+static int patch_ad1988(struct hda_codec *codec)
+{
+	struct ad198x_spec *spec;
+	int board_config;
+
+	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	init_MUTEX(&spec->amp_mutex);
+	codec->spec = spec;
+
+	if (codec->revision_id == AD1988A_REV2)
+		snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
+
+	board_config = snd_hda_check_board_config(codec, ad1988_cfg_tbl);
+	if (board_config < 0 || board_config >= AD1988_MODEL_LAST) {
+		printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
+		board_config = AD1988_AUTO;
+	}
+
+	if (board_config == AD1988_AUTO) {
+		/* automatic parse from the BIOS config */
+		int err = ad1988_parse_auto_config(codec);
+		if (err < 0) {
+			ad198x_free(codec);
+			return err;
+		} else if (! err) {
+			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
+			board_config = AD1988_6STACK;
+		}
+	}
+
+	switch (board_config) {
+	case AD1988_6STACK:
+	case AD1988_6STACK_DIG:
+		spec->multiout.max_channels = 8;
+		spec->multiout.num_dacs = 4;
+		if (codec->revision_id == AD1988A_REV2)
+			spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
+		else
+			spec->multiout.dac_nids = ad1988_6stack_dac_nids;
+		spec->input_mux = &ad1988_6stack_capture_source;
+		spec->num_mixers = 2;
+		if (codec->revision_id == AD1988A_REV2)
+			spec->mixers[0] = ad1988_6stack_mixers1_rev2;
+		else
+			spec->mixers[0] = ad1988_6stack_mixers1;
+		spec->mixers[1] = ad1988_6stack_mixers2;
+		spec->num_init_verbs = 1;
+		spec->init_verbs[0] = ad1988_6stack_init_verbs;
+		if (board_config == AD1988_6STACK_DIG) {
+			spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
+			spec->dig_in_nid = AD1988_SPDIF_IN;
+		}
+		break;
+	case AD1988_3STACK:
+	case AD1988_3STACK_DIG:
+		spec->multiout.max_channels = 6;
+		spec->multiout.num_dacs = 3;
+		if (codec->revision_id == AD1988A_REV2)
+			spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
+		else
+			spec->multiout.dac_nids = ad1988_3stack_dac_nids;
+		spec->input_mux = &ad1988_6stack_capture_source;
+		spec->channel_mode = ad1988_3stack_modes;
+		spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
+		spec->num_mixers = 2;
+		if (codec->revision_id == AD1988A_REV2)
+			spec->mixers[0] = ad1988_3stack_mixers1_rev2;
+		else
+			spec->mixers[0] = ad1988_3stack_mixers1;
+		spec->mixers[1] = ad1988_3stack_mixers2;
+		spec->num_init_verbs = 1;
+		spec->init_verbs[0] = ad1988_3stack_init_verbs;
+		if (board_config == AD1988_3STACK_DIG)
+			spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
+		break;
+	case AD1988_LAPTOP:
+	case AD1988_LAPTOP_DIG:
+		spec->multiout.max_channels = 2;
+		spec->multiout.num_dacs = 1;
+		spec->multiout.dac_nids = ad1988_3stack_dac_nids;
+		spec->input_mux = &ad1988_laptop_capture_source;
+		spec->num_mixers = 1;
+		spec->mixers[0] = ad1988_laptop_mixers;
+		spec->num_init_verbs = 1;
+		spec->init_verbs[0] = ad1988_laptop_init_verbs;
+		if (board_config == AD1988_LAPTOP_DIG)
+			spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
+		break;
+	}
+
+	spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
+	spec->adc_nids = ad1988_adc_nids;
+	spec->capsrc_nids = ad1988_capsrc_nids;
+	spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
+	spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
+	if (spec->multiout.dig_out_nid) {
+		spec->mixers[spec->num_mixers++] = ad1988_spdif_out_mixers;
+		spec->init_verbs[spec->num_init_verbs++] = ad1988_spdif_init_verbs;
+	}
+	if (spec->dig_in_nid)
+		spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
+
+	codec->patch_ops = ad198x_patch_ops;
+	switch (board_config) {
+	case AD1988_AUTO:
+		codec->patch_ops.init = ad1988_auto_init;
+		break;
+	case AD1988_LAPTOP:
+	case AD1988_LAPTOP_DIG:
+		codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
+		break;
+	}
+
+	return 0;
+}
+
+
+/*
  * patch entries
  */
 struct hda_codec_preset snd_hda_preset_analog[] = {
 	{ .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
 	{ .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
 	{ .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
+	{ .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
 	{} /* terminator */
 };
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 523c362..d38ce22 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -44,7 +44,6 @@
 
 struct cmi_spec {
 	int board_config;
-	unsigned int surr_switch: 1;	/* switchable line,mic */
 	unsigned int no_line_in: 1;	/* no line-in (5-jack) */
 	unsigned int front_panel: 1;	/* has front-panel 2-jack */
 
@@ -62,9 +61,8 @@
 	unsigned int cur_mux[2];
 
 	/* channel mode */
-	unsigned int num_ch_modes;
-	unsigned int cur_ch_mode;
-	const struct cmi_channel_mode *channel_modes;
+	int num_channel_modes;
+	const struct hda_channel_mode *channel_modes;
 
 	struct hda_pcm pcm_rec[2];	/* PCM information */
 
@@ -78,30 +76,17 @@
 	struct hda_verb multi_init[9];	/* 2 verbs for each pin + terminator */
 };
 
-/* amp values */
-#define AMP_IN_MUTE(idx)	(0x7080 | ((idx)<<8))
-#define AMP_IN_UNMUTE(idx)	(0x7000 | ((idx)<<8))
-#define AMP_OUT_MUTE	0xb080
-#define AMP_OUT_UNMUTE	0xb000
-#define AMP_OUT_ZERO	0xb000
-/* pinctl values */
-#define PIN_IN		0x20
-#define PIN_VREF80	0x24
-#define PIN_VREF50	0x21
-#define PIN_OUT		0x40
-#define PIN_HP		0xc0
-
 /*
  * input MUX
  */
-static int cmi_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int cmi_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct cmi_spec *spec = codec->spec;
 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
 }
 
-static int cmi_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int cmi_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct cmi_spec *spec = codec->spec;
@@ -111,7 +96,7 @@
 	return 0;
 }
 
-static int cmi_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int cmi_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct cmi_spec *spec = codec->spec;
@@ -158,63 +143,39 @@
 	{}
 };
 
-struct cmi_channel_mode {
-	unsigned int channels;
-	const struct hda_verb *sequence;
-};
-
-static struct cmi_channel_mode cmi9880_channel_modes[3] = {
+static struct hda_channel_mode cmi9880_channel_modes[3] = {
 	{ 2, cmi9880_ch2_init },
 	{ 6, cmi9880_ch6_init },
 	{ 8, cmi9880_ch8_init },
 };
 
-static int cmi_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int cmi_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct cmi_spec *spec = codec->spec;
-
-	snd_assert(spec->channel_modes, return -EINVAL);
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = spec->num_ch_modes;
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
-	sprintf(uinfo->value.enumerated.name, "%dch",
-		spec->channel_modes[uinfo->value.enumerated.item].channels);
-	return 0;
+	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_modes,
+				    spec->num_channel_modes);
 }
 
-static int cmi_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int cmi_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct cmi_spec *spec = codec->spec;
-
-	ucontrol->value.enumerated.item[0] = spec->cur_ch_mode;
-	return 0;
+	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_modes,
+				   spec->num_channel_modes, spec->multiout.max_channels);
 }
 
-static int cmi_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int cmi_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct cmi_spec *spec = codec->spec;
-
-	snd_assert(spec->channel_modes, return -EINVAL);
-	if (ucontrol->value.enumerated.item[0] >= spec->num_ch_modes)
-		ucontrol->value.enumerated.item[0] = spec->num_ch_modes;
-	if (ucontrol->value.enumerated.item[0] == spec->cur_ch_mode &&
-	    ! codec->in_resume)
-		return 0;
-
-	spec->cur_ch_mode = ucontrol->value.enumerated.item[0];
-	snd_hda_sequence_write(codec, spec->channel_modes[spec->cur_ch_mode].sequence);
-	spec->multiout.max_channels = spec->channel_modes[spec->cur_ch_mode].channels;
-	return 1;
+	return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_modes,
+				   spec->num_channel_modes, &spec->multiout.max_channels);
 }
 
 /*
  */
-static snd_kcontrol_new_t cmi9880_basic_mixer[] = {
+static struct snd_kcontrol_new cmi9880_basic_mixer[] = {
 	/* CMI9880 has no playback volumes! */
 	HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */
 	HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT),
@@ -246,7 +207,7 @@
 /*
  * shared I/O pins
  */
-static snd_kcontrol_new_t cmi9880_ch_mode_mixer[] = {
+static struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Channel Mode",
@@ -361,7 +322,7 @@
 	err = snd_hda_add_new_ctls(codec, cmi9880_basic_mixer);
 	if (err < 0)
 		return err;
-	if (spec->surr_switch) {
+	if (spec->channel_modes) {
 		err = snd_hda_add_new_ctls(codec, cmi9880_ch_mode_mixer);
 		if (err < 0)
 			return err;
@@ -475,7 +436,7 @@
 
 	cmi9880_init(codec);
 	snd_hda_resume_ctls(codec, cmi9880_basic_mixer);
-	if (spec->surr_switch)
+	if (spec->channel_modes)
 		snd_hda_resume_ctls(codec, cmi9880_ch_mode_mixer);
 	if (spec->multiout.dig_out_nid)
 		snd_hda_resume_spdif_out(codec);
@@ -491,7 +452,7 @@
  */
 static int cmi9880_playback_pcm_open(struct hda_pcm_stream *hinfo,
 				     struct hda_codec *codec,
-				     snd_pcm_substream_t *substream)
+				     struct snd_pcm_substream *substream)
 {
 	struct cmi_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
@@ -501,7 +462,7 @@
 					struct hda_codec *codec,
 					unsigned int stream_tag,
 					unsigned int format,
-					snd_pcm_substream_t *substream)
+					struct snd_pcm_substream *substream)
 {
 	struct cmi_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
@@ -510,7 +471,7 @@
 
 static int cmi9880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 				       struct hda_codec *codec,
-				       snd_pcm_substream_t *substream)
+				       struct snd_pcm_substream *substream)
 {
 	struct cmi_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
@@ -521,7 +482,7 @@
  */
 static int cmi9880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 					 struct hda_codec *codec,
-					 snd_pcm_substream_t *substream)
+					 struct snd_pcm_substream *substream)
 {
 	struct cmi_spec *spec = codec->spec;
 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
@@ -529,7 +490,7 @@
 
 static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 					  struct hda_codec *codec,
-					  snd_pcm_substream_t *substream)
+					  struct snd_pcm_substream *substream)
 {
 	struct cmi_spec *spec = codec->spec;
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
@@ -542,7 +503,7 @@
 				      struct hda_codec *codec,
 				      unsigned int stream_tag,
 				      unsigned int format,
-				      snd_pcm_substream_t *substream)
+				      struct snd_pcm_substream *substream)
 {
 	struct cmi_spec *spec = codec->spec;
 
@@ -553,7 +514,7 @@
 
 static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 				      struct hda_codec *codec,
-				      snd_pcm_substream_t *substream)
+				      struct snd_pcm_substream *substream)
 {
 	struct cmi_spec *spec = codec->spec;
 
@@ -685,14 +646,13 @@
 	switch (spec->board_config) {
 	case CMI_MINIMAL:
 	case CMI_MIN_FP:
-		spec->surr_switch = 1;
+		spec->channel_modes = cmi9880_channel_modes;
 		if (spec->board_config == CMI_MINIMAL)
-			spec->num_ch_modes = 2;
+			spec->num_channel_modes = 2;
 		else {
 			spec->front_panel = 1;
-			spec->num_ch_modes = 3;
+			spec->num_channel_modes = 3;
 		}
-		spec->channel_modes = cmi9880_channel_modes;
 		spec->multiout.max_channels = cmi9880_channel_modes[0].channels;
 		spec->input_mux = &cmi9880_basic_mux;
 		break;
@@ -727,19 +687,18 @@
 		    get_defcfg_connect(port_f) == AC_JACK_PORT_NONE) {
 			port_g = snd_hda_codec_read(codec, 0x1f, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
 			port_h = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
-			spec->surr_switch = 1;
+			spec->channel_modes = cmi9880_channel_modes;
 			/* no front panel */
 			if (get_defcfg_connect(port_g) == AC_JACK_PORT_NONE ||
 			    get_defcfg_connect(port_h) == AC_JACK_PORT_NONE) {
 				/* no optional rear panel */
 				spec->board_config = CMI_MINIMAL;
 				spec->front_panel = 0;
-				spec->num_ch_modes = 2;
+				spec->num_channel_modes = 2;
 			} else {
 				spec->board_config = CMI_MIN_FP;
-				spec->num_ch_modes = 3;
+				spec->num_channel_modes = 3;
 			}
-			spec->channel_modes = cmi9880_channel_modes;
 			spec->input_mux = &cmi9880_basic_mux;
 			spec->multiout.max_channels = cmi9880_channel_modes[0].channels;
 		} else {
@@ -752,7 +711,7 @@
 				spec->dig_in_nid = CMI_DIG_IN_NID;
 			spec->multiout.max_channels = 8;
 		}
-		snd_hda_parse_pin_def_config(codec, &cfg);
+		snd_hda_parse_pin_def_config(codec, &cfg, NULL);
 		if (cfg.line_outs) {
 			spec->multiout.max_channels = cfg.line_outs * 2;
 			cmi9880_fill_multi_dac_nids(codec, &cfg);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index cffb83f..ad9e501 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -3,7 +3,8 @@
  *
  * HD audio interface patch for ALC 260/880/882 codecs
  *
- * Copyright (c) 2004 PeiSen Hou <pshou@realtek.com.tw>
+ * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
+ *                    PeiSen Hou <pshou@realtek.com.tw>
  *                    Takashi Iwai <tiwai@suse.de>
  *
  *  This driver is free software; you can redistribute it and/or modify
@@ -39,17 +40,20 @@
 	ALC880_5ST_DIG,
 	ALC880_W810,
 	ALC880_Z71V,
-	ALC880_AUTO,
 	ALC880_6ST,
 	ALC880_6ST_DIG,
 	ALC880_F1734,
 	ALC880_ASUS,
 	ALC880_ASUS_DIG,
 	ALC880_ASUS_W1V,
+	ALC880_ASUS_DIG2,
 	ALC880_UNIWILL_DIG,
+	ALC880_CLEVO,
+	ALC880_TCL_S700,
 #ifdef CONFIG_SND_DEBUG
 	ALC880_TEST,
 #endif
+	ALC880_AUTO,
 	ALC880_MODEL_LAST /* last tag */
 };
 
@@ -57,30 +61,45 @@
 enum {
 	ALC260_BASIC,
 	ALC260_HP,
-	ALC260_FUJITSU_S702x,
+	ALC260_HP_3013,
+	ALC260_FUJITSU_S702X,
+	ALC260_AUTO,
 	ALC260_MODEL_LAST /* last tag */
 };
 
-/* amp values */
-#define AMP_IN_MUTE(idx)	(0x7080 | ((idx)<<8))
-#define AMP_IN_UNMUTE(idx)	(0x7000 | ((idx)<<8))
-#define AMP_OUT_MUTE	0xb080
-#define AMP_OUT_UNMUTE	0xb000
-#define AMP_OUT_ZERO	0xb000
-/* pinctl values */
-#define PIN_IN		0x20
-#define PIN_VREF80	0x24
-#define PIN_VREF50	0x21
-#define PIN_OUT		0x40
-#define PIN_HP		0xc0
-#define PIN_HP_AMP	0x80
+/* ALC262 models */
+enum {
+	ALC262_BASIC,
+	ALC262_AUTO,
+	ALC262_MODEL_LAST /* last tag */
+};
+
+/* ALC861 models */
+enum {
+	ALC861_3ST,
+	ALC861_3ST_DIG,
+	ALC861_6ST_DIG,
+	ALC861_AUTO,
+	ALC861_MODEL_LAST,
+};
+
+/* ALC882 models */
+enum {
+	ALC882_3ST_DIG,
+	ALC882_6ST_DIG,
+	ALC882_AUTO,
+	ALC882_MODEL_LAST,
+};
+
+/* for GPIO Poll */
+#define GPIO_MASK	0x03
 
 struct alc_spec {
 	/* codec parameterization */
-	snd_kcontrol_new_t *mixers[3];	/* mixer arrays */
+	struct snd_kcontrol_new *mixers[5];	/* mixer arrays */
 	unsigned int num_mixers;
 
-	const struct hda_verb *init_verbs[3];	/* initialization verbs
+	const struct hda_verb *init_verbs[5];	/* initialization verbs
 						 * don't forget NULL termination!
 						 */
 	unsigned int num_init_verbs;
@@ -109,7 +128,7 @@
 	unsigned int cur_mux[3];
 
 	/* channel model */
-	const struct alc_channel_mode *channel_mode;
+	const struct hda_channel_mode *channel_mode;
 	int num_channel_mode;
 
 	/* PCM information */
@@ -118,23 +137,41 @@
 	/* dynamic controls, init_verbs and input_mux */
 	struct auto_pin_cfg autocfg;
 	unsigned int num_kctl_alloc, num_kctl_used;
-	snd_kcontrol_new_t *kctl_alloc;
+	struct snd_kcontrol_new *kctl_alloc;
 	struct hda_input_mux private_imux;
-	hda_nid_t private_dac_nids[4];
+	hda_nid_t private_dac_nids[5];
+};
+
+/*
+ * configuration template - to be copied to the spec instance
+ */
+struct alc_config_preset {
+	struct snd_kcontrol_new *mixers[5]; /* should be identical size with spec */
+	const struct hda_verb *init_verbs[5];
+	unsigned int num_dacs;
+	hda_nid_t *dac_nids;
+	hda_nid_t dig_out_nid;		/* optional */
+	hda_nid_t hp_nid;		/* optional */
+	unsigned int num_adc_nids;
+	hda_nid_t *adc_nids;
+	hda_nid_t dig_in_nid;
+	unsigned int num_channel_mode;
+	const struct hda_channel_mode *channel_mode;
+	const struct hda_input_mux *input_mux;
 };
 
 
 /*
  * input MUX handling
  */
-static int alc_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
 }
 
-static int alc_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
@@ -144,7 +181,7 @@
 	return 0;
 }
 
-static int alc_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
@@ -157,63 +194,28 @@
 /*
  * channel mode setting
  */
-struct alc_channel_mode {
-	int channels;
-	const struct hda_verb *sequence;
-};
-
-static int alc880_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
-	int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
-
-	snd_assert(spec->channel_mode, return -ENXIO);
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = items;
-	if (uinfo->value.enumerated.item >= items)
-		uinfo->value.enumerated.item = items - 1;
-	sprintf(uinfo->value.enumerated.name, "%dch",
-		spec->channel_mode[uinfo->value.enumerated.item].channels);
-	return 0;
+	return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
+				    spec->num_channel_mode);
 }
 
-static int alc880_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
-	int items = kcontrol->private_value ? (int)kcontrol->private_value : 2;
-	int i;
-
-	snd_assert(spec->channel_mode, return -ENXIO);
-	for (i = 0; i < items; i++) {
-		if (spec->multiout.max_channels == spec->channel_mode[i].channels) {
-			ucontrol->value.enumerated.item[0] = i;
-			break;
-		}
-	}
-	return 0;
+	return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
+				   spec->num_channel_mode, spec->multiout.max_channels);
 }
 
-static int alc880_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
-	int mode;
-
-	snd_assert(spec->channel_mode, return -ENXIO);
-	mode = ucontrol->value.enumerated.item[0] ? 1 : 0;
-	if (spec->multiout.max_channels == spec->channel_mode[mode].channels &&
-	    ! codec->in_resume)
-		return 0;
-
-	/* change the current channel setting */
-	spec->multiout.max_channels = spec->channel_mode[mode].channels;
-	if (spec->channel_mode[mode].sequence)
-		snd_hda_sequence_write(codec, spec->channel_mode[mode].sequence);
-
-	return 1;
+	return snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
+				   spec->num_channel_mode, &spec->multiout.max_channels);
 }
 
 
@@ -222,7 +224,7 @@
  * supported, so VrefEn can't be controlled using these functions as they
  * stand.
  */
-static int alc_pinctl_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc_pinctl_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -231,7 +233,7 @@
 	return 0;
 }
 
-static int alc_pinctl_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value & 0xffff;
@@ -244,7 +246,7 @@
 	return 0;
 }
 
-static int alc_pinctl_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_pinctl_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = kcontrol->private_value & 0xffff;
@@ -266,6 +268,36 @@
 	  .put = alc_pinctl_switch_put, \
 	  .private_value = (nid) | (mask<<16) }
 
+
+/*
+ * set up from the preset table
+ */
+static void setup_preset(struct alc_spec *spec, const struct alc_config_preset *preset)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
+		spec->mixers[spec->num_mixers++] = preset->mixers[i];
+	for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; i++)
+		spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i];
+	
+	spec->channel_mode = preset->channel_mode;
+	spec->num_channel_mode = preset->num_channel_mode;
+
+	spec->multiout.max_channels = spec->channel_mode[0].channels;
+
+	spec->multiout.num_dacs = preset->num_dacs;
+	spec->multiout.dac_nids = preset->dac_nids;
+	spec->multiout.dig_out_nid = preset->dig_out_nid;
+	spec->multiout.hp_nid = preset->hp_nid;
+	
+	spec->input_mux = preset->input_mux;
+
+	spec->num_adc_nids = preset->num_adc_nids;
+	spec->adc_nids = preset->adc_nids;
+	spec->dig_in_nid = preset->dig_in_nid;
+}
+
 /*
  * ALC880 3-stack model
  *
@@ -286,6 +318,7 @@
 
 /* The datasheet says the node 0x07 is connected from inputs,
  * but it shows zero connection in the real implementation on some devices.
+ * Note: this is a 915GAV bug, fixed on 915GLV
  */
 static hda_nid_t alc880_adc_nids_alt[2] = {
 	/* ADC1-2 */
@@ -328,12 +361,12 @@
 	{ } /* end */
 };
 
-static struct alc_channel_mode alc880_threestack_modes[2] = {
+static struct hda_channel_mode alc880_threestack_modes[2] = {
 	{ 2, alc880_threestack_ch2_init },
 	{ 6, alc880_threestack_ch6_init },
 };
 
-static snd_kcontrol_new_t alc880_three_stack_mixer[] = {
+static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
@@ -356,15 +389,15 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Channel Mode",
-		.info = alc880_ch_mode_info,
-		.get = alc880_ch_mode_get,
-		.put = alc880_ch_mode_put,
+		.info = alc_ch_mode_info,
+		.get = alc_ch_mode_get,
+		.put = alc_ch_mode_put,
 	},
 	{ } /* end */
 };
 
 /* capture mixer elements */
-static snd_kcontrol_new_t alc880_capture_mixer[] = {
+static struct snd_kcontrol_new alc880_capture_mixer[] = {
 	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
@@ -388,7 +421,7 @@
 };
 
 /* capture mixer elements (in case NID 0x07 not available) */
-static snd_kcontrol_new_t alc880_capture_alt_mixer[] = {
+static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
 	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
 	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
@@ -420,7 +453,7 @@
  */
 
 /* additional mixers to alc880_three_stack_mixer */
-static snd_kcontrol_new_t alc880_five_stack_mixer[] = {
+static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
 	{ } /* end */
@@ -443,7 +476,7 @@
 	{ } /* end */
 };
 
-static struct alc_channel_mode alc880_fivestack_modes[2] = {
+static struct hda_channel_mode alc880_fivestack_modes[2] = {
 	{ 6, alc880_fivestack_ch6_init },
 	{ 8, alc880_fivestack_ch8_init },
 };
@@ -473,11 +506,11 @@
 };
 
 /* fixed 8-channels */
-static struct alc_channel_mode alc880_sixstack_modes[1] = {
+static struct hda_channel_mode alc880_sixstack_modes[1] = {
 	{ 8, NULL },
 };
 
-static snd_kcontrol_new_t alc880_six_stack_mixer[] = {
+static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -501,9 +534,9 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Channel Mode",
-		.info = alc880_ch_mode_info,
-		.get = alc880_ch_mode_get,
-		.put = alc880_ch_mode_put,
+		.info = alc_ch_mode_info,
+		.get = alc_ch_mode_get,
+		.put = alc_ch_mode_put,
 	},
 	{ } /* end */
 };
@@ -540,12 +573,12 @@
 };
 
 /* fixed 6 channels */
-static struct alc_channel_mode alc880_w810_modes[1] = {
+static struct hda_channel_mode alc880_w810_modes[1] = {
 	{ 6, NULL }
 };
 
 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
-static snd_kcontrol_new_t alc880_w810_base_mixer[] = {
+static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -572,11 +605,11 @@
 #define ALC880_Z71V_HP_DAC	0x03
 
 /* fixed 2 channels */
-static struct alc_channel_mode alc880_2_jack_modes[1] = {
+static struct hda_channel_mode alc880_2_jack_modes[1] = {
 	{ 2, NULL }
 };
 
-static snd_kcontrol_new_t alc880_z71v_mixer[] = {
+static struct snd_kcontrol_new alc880_z71v_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -602,7 +635,7 @@
 };
 #define ALC880_F1734_HP_DAC	0x02
 
-static snd_kcontrol_new_t alc880_f1734_mixer[] = {
+static struct snd_kcontrol_new alc880_f1734_mixer[] = {
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -627,7 +660,7 @@
 #define alc880_asus_dac_nids	alc880_w810_dac_nids	/* identical with w810 */
 #define alc880_asus_modes	alc880_threestack_modes	/* 2/6 channel mode */
 
-static snd_kcontrol_new_t alc880_asus_mixer[] = {
+static struct snd_kcontrol_new alc880_asus_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -645,9 +678,9 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Channel Mode",
-		.info = alc880_ch_mode_info,
-		.get = alc880_ch_mode_get,
-		.put = alc880_ch_mode_put,
+		.info = alc_ch_mode_info,
+		.get = alc_ch_mode_get,
+		.put = alc_ch_mode_put,
 	},
 	{ } /* end */
 };
@@ -662,19 +695,46 @@
  */
 
 /* additional mixers to alc880_asus_mixer */
-static snd_kcontrol_new_t alc880_asus_w1v_mixer[] = {
+static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
 	HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
 	HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
 	{ } /* end */
 };
 
 /* additional mixers to alc880_asus_mixer */
-static snd_kcontrol_new_t alc880_pcbeep_mixer[] = {
+static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
 	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
 	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
 	{ } /* end */
 };
 
+/* TCL S700 */
+static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* The multiple "Capture Source" controls confuse alsamixer
+		 * So call somewhat different..
+		 * FIXME: the controls appear in the "playback" view!
+		 */
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 1,
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{ } /* end */
+};
+
 /*
  * build control elements
  */
@@ -974,6 +1034,8 @@
 	{0x01, AC_VERB_SET_GPIO_MASK, 0x01},
 	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
 	{0x01, AC_VERB_SET_GPIO_DATA, 0x01},
+
+	{ }
 };
 
 /* Enable GPIO mask and set output */
@@ -981,8 +1043,59 @@
 	{0x01, AC_VERB_SET_GPIO_MASK, 0x02},
 	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
 	{0x01, AC_VERB_SET_GPIO_DATA, 0x02},
+
+	{ }
 };
 
+/* Clevo m520g init */
+static struct hda_verb alc880_pin_clevo_init_verbs[] = {
+	/* headphone output */
+	{0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
+	/* line-out */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Line-in */
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* CD */
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Mic1 (rear panel) */
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* Mic2 (front panel) */
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	/* headphone */
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+        /* change to EAPD mode */
+	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
+	{0x20, AC_VERB_SET_PROC_COEF,  0x3060},
+
+	{ }
+};
+
+static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
+	/* Headphone output */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	/* Front output*/
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
+
+	/* Line In pin widget for input */
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	/* CD pin widget for input */
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	/* Mic1 (rear panel) pin widget for input and vref at 80% */
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
+
+	/* change to EAPD mode */
+	{0x20, AC_VERB_SET_COEF_INDEX, 0x07},
+	{0x20, AC_VERB_SET_PROC_COEF,  0x3070},
+
+	{ }
+};
 
 /*
  */
@@ -1023,7 +1136,7 @@
  */
 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
 				    struct hda_codec *codec,
-				    snd_pcm_substream_t *substream)
+				    struct snd_pcm_substream *substream)
 {
 	struct alc_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
@@ -1033,7 +1146,7 @@
 				       struct hda_codec *codec,
 				       unsigned int stream_tag,
 				       unsigned int format,
-				       snd_pcm_substream_t *substream)
+				       struct snd_pcm_substream *substream)
 {
 	struct alc_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
@@ -1042,7 +1155,7 @@
 
 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 				       struct hda_codec *codec,
-				       snd_pcm_substream_t *substream)
+				       struct snd_pcm_substream *substream)
 {
 	struct alc_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
@@ -1053,7 +1166,7 @@
  */
 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 					struct hda_codec *codec,
-					snd_pcm_substream_t *substream)
+					struct snd_pcm_substream *substream)
 {
 	struct alc_spec *spec = codec->spec;
 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
@@ -1061,7 +1174,7 @@
 
 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 					 struct hda_codec *codec,
-					 snd_pcm_substream_t *substream)
+					 struct snd_pcm_substream *substream)
 {
 	struct alc_spec *spec = codec->spec;
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
@@ -1074,7 +1187,7 @@
 				      struct hda_codec *codec,
 				      unsigned int stream_tag,
 				      unsigned int format,
-				      snd_pcm_substream_t *substream)
+				      struct snd_pcm_substream *substream)
 {
 	struct alc_spec *spec = codec->spec;
 
@@ -1085,7 +1198,7 @@
 
 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 				      struct hda_codec *codec,
-				      snd_pcm_substream_t *substream)
+				      struct snd_pcm_substream *substream)
 {
 	struct alc_spec *spec = codec->spec;
 
@@ -1147,15 +1260,23 @@
 	codec->pcm_info = info;
 
 	info->name = spec->stream_name_analog;
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
-	info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
-	info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
+	if (spec->stream_analog_playback) {
+		snd_assert(spec->multiout.dac_nids, return -EINVAL);
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
+	}
+	if (spec->stream_analog_capture) {
+		snd_assert(spec->adc_nids, return -EINVAL);
+		info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
+		info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
+	}
 
-	info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
-	for (i = 0; i < spec->num_channel_mode; i++) {
-		if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
-		    info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
+	if (spec->channel_mode) {
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
+		for (i = 0; i < spec->num_channel_mode; i++) {
+			if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
+				info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
+			}
 		}
 	}
 
@@ -1163,11 +1284,13 @@
 		codec->num_pcms++;
 		info++;
 		info->name = spec->stream_name_digital;
-		if (spec->multiout.dig_out_nid) {
+		if (spec->multiout.dig_out_nid &&
+		    spec->stream_digital_playback) {
 			info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
 			info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
 		}
-		if (spec->dig_in_nid) {
+		if (spec->dig_in_nid &&
+		    spec->stream_digital_capture) {
 			info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
 			info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
 		}
@@ -1227,14 +1350,14 @@
 	},
 };
 
-static struct alc_channel_mode alc880_test_modes[4] = {
+static struct hda_channel_mode alc880_test_modes[4] = {
 	{ 2, NULL },
 	{ 4, NULL },
 	{ 6, NULL },
 	{ 8, NULL },
 };
 
-static int alc_test_pin_ctl_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {
 		"N/A", "Line Out", "HP Out",
@@ -1249,7 +1372,7 @@
 	return 0;
 }
 
-static int alc_test_pin_ctl_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
@@ -1275,7 +1398,7 @@
 	return 0;
 }
 
-static int alc_test_pin_ctl_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
@@ -1301,7 +1424,7 @@
 	return 0;
 }
 
-static int alc_test_pin_src_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {
 		"Front", "Surround", "CLFE", "Side"
@@ -1315,7 +1438,7 @@
 	return 0;
 }
 
-static int alc_test_pin_src_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
@@ -1326,7 +1449,7 @@
 	return 0;
 }
 
-static int alc_test_pin_src_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
@@ -1359,7 +1482,7 @@
 			.private_value = nid	       \
 			}
 
-static snd_kcontrol_new_t alc880_test_mixer[] = {
+static struct snd_kcontrol_new alc880_test_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
@@ -1393,9 +1516,9 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Channel Mode",
-		.info = alc880_ch_mode_info,
-		.get = alc880_ch_mode_get,
-		.put = alc880_ch_mode_put,
+		.info = alc_ch_mode_info,
+		.get = alc_ch_mode_get,
+		.put = alc_ch_mode_put,
 	},
 	{ } /* end */
 };
@@ -1491,6 +1614,8 @@
 	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
 	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
 	{ .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
+	/* TCL S700 */
+	{ .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 },
 
 	/* Back 3 jack, front 2 jack (Internal add Aux-In) */
 	{ .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
@@ -1501,6 +1626,8 @@
 	{ .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
 	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
 	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG },
+	/* Clevo m520G NB */
+	{ .pci_subvendor = 0x1558, .pci_subdevice = 0x0520, .config = ALC880_CLEVO },
 
 	/* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
 	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
@@ -1538,6 +1665,8 @@
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
 
 	{ .modelname = "6stack", .config = ALC880_6ST },
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */
+	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST },
 	{ .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */
 
 	{ .modelname = "6stack-digout", .config = ALC880_6ST_DIG },
@@ -1545,6 +1674,11 @@
 	{ .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
 	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
 	{ .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG },
+	{ .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG },
+	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG },
+	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG },
+	{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG },
+	{ .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */
 
 	{ .modelname = "asus", .config = ALC880_ASUS },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
@@ -1558,37 +1692,26 @@
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
 	{ .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
+	{ .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 },
 
 	{ .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
 	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },	
 
 	{ .modelname = "F1734", .config = ALC880_F1734 },
 	{ .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
+	{ .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 },
 
 #ifdef CONFIG_SND_DEBUG
 	{ .modelname = "test", .config = ALC880_TEST },
 #endif
+	{ .modelname = "auto", .config = ALC880_AUTO },
 
 	{}
 };
 
 /*
- * configuration template - to be copied to the spec instance
+ * ALC880 codec presets
  */
-struct alc_config_preset {
-	snd_kcontrol_new_t *mixers[4];
-	const struct hda_verb *init_verbs[4];
-	unsigned int num_dacs;
-	hda_nid_t *dac_nids;
-	hda_nid_t dig_out_nid;		/* optional */
-	hda_nid_t hp_nid;		/* optional */
-	unsigned int num_adc_nids;
-	hda_nid_t *adc_nids;
-	unsigned int num_channel_mode;
-	const struct alc_channel_mode *channel_mode;
-	const struct hda_input_mux *input_mux;
-};
-
 static struct alc_config_preset alc880_presets[] = {
 	[ALC880_3ST] = {
 		.mixers = { alc880_three_stack_mixer },
@@ -1609,6 +1732,18 @@
 		.channel_mode = alc880_threestack_modes,
 		.input_mux = &alc880_capture_source,
 	},
+	[ALC880_TCL_S700] = {
+		.mixers = { alc880_tcl_s700_mixer },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_tcl_S700_init_verbs,
+				alc880_gpio2_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
+		.dac_nids = alc880_dac_nids,
+		.hp_nid = 0x03,
+		.num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
+		.channel_mode = alc880_2_jack_modes,
+		.input_mux = &alc880_capture_source,
+	},
 	[ALC880_5ST] = {
 		.mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer},
 		.init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs },
@@ -1700,6 +1835,17 @@
 		.channel_mode = alc880_asus_modes,
 		.input_mux = &alc880_capture_source,
 	},
+	[ALC880_ASUS_DIG2] = {
+		.mixers = { alc880_asus_mixer },
+		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
+				alc880_gpio2_init_verbs }, /* use GPIO2 */
+		.num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
+		.dac_nids = alc880_asus_dac_nids,
+		.dig_out_nid = ALC880_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
+		.channel_mode = alc880_asus_modes,
+		.input_mux = &alc880_capture_source,
+	},
 	[ALC880_ASUS_W1V] = {
 		.mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
 		.init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs,
@@ -1721,6 +1867,17 @@
 		.channel_mode = alc880_asus_modes,
 		.input_mux = &alc880_capture_source,
 	},
+	[ALC880_CLEVO] = {
+		.mixers = { alc880_three_stack_mixer },
+		.init_verbs = { alc880_volume_init_verbs,
+				alc880_pin_clevo_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc880_dac_nids),
+		.dac_nids = alc880_dac_nids,
+		.hp_nid = 0x03,
+		.num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
+		.channel_mode = alc880_threestack_modes,
+		.input_mux = &alc880_capture_source,
+	},
 #ifdef CONFIG_SND_DEBUG
 	[ALC880_TEST] = {
 		.mixers = { alc880_test_mixer },
@@ -1747,7 +1904,7 @@
 	ALC_CTL_WIDGET_MUTE,
 	ALC_CTL_BIND_MUTE,
 };
-static snd_kcontrol_new_t alc880_control_templates[] = {
+static struct snd_kcontrol_new alc880_control_templates[] = {
 	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
 	HDA_CODEC_MUTE(NULL, 0, 0, 0),
 	HDA_BIND_MUTE(NULL, 0, 0, 0),
@@ -1756,7 +1913,7 @@
 /* add dynamic controls */
 static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val)
 {
-	snd_kcontrol_new_t *knew;
+	struct snd_kcontrol_new *knew;
 
 	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
 		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
@@ -1809,7 +1966,7 @@
 		nid = cfg->line_out_pins[i];
 		if (alc880_is_fixed_pin(nid)) {
 			int idx = alc880_fixed_pin_idx(nid);
-			spec->multiout.dac_nids[i] = alc880_dac_to_idx(idx);
+			spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
 			assigned[idx] = 1;
 		}
 	}
@@ -1832,7 +1989,8 @@
 }
 
 /* add playback controls from the parsed DAC table */
-static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
+					     const struct auto_pin_cfg *cfg)
 {
 	char name[32];
 	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
@@ -1868,15 +2026,16 @@
 				return err;
 		}
 	}
-
 	return 0;
 }
 
-/* add playback controls for HP output */
-static int alc880_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
+/* add playback controls for speaker and HP outputs */
+static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
+					const char *pfx)
 {
 	hda_nid_t nid;
 	int err;
+	char name[32];
 
 	if (! pin)
 		return 0;
@@ -1889,14 +2048,16 @@
 			if (! spec->multiout.num_dacs)
 				spec->multiout.num_dacs = 1;
 		} else 
-			/* specify the DAC as the extra HP output */
+			/* specify the DAC as the extra output */
 			spec->multiout.hp_nid = nid;
 		/* control HP volume/switch on the output mixer amp */
 		nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
-		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
+		sprintf(name, "%s Playback Volume", pfx);
+		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
 				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
 			return err;
-		if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Headphone Playback Switch",
+		sprintf(name, "%s Playback Switch", pfx);
+		if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
 				       HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
 			return err;
 	} else if (alc880_is_multi_pin(pin)) {
@@ -1908,7 +2069,8 @@
 				spec->multiout.num_dacs = 1;
 		}
 		/* we have only a switch on HP-out PIN */
-		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
+		sprintf(name, "%s Playback Switch", pfx);
+		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
 				       HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0)
 			return err;
 	}
@@ -1916,38 +2078,39 @@
 }
 
 /* create input playback/capture controls for the given pin */
-static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname)
+static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname,
+			    int idx, hda_nid_t mix_nid)
 {
 	char name[32];
-	int err, idx;
+	int err;
 
 	sprintf(name, "%s Playback Volume", ctlname);
-	idx = alc880_input_pin_idx(pin);
 	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
-			       HDA_COMPOSE_AMP_VAL(0x0b, 3, idx, HDA_INPUT))) < 0)
+			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
 		return err;
 	sprintf(name, "%s Playback Switch", ctlname);
 	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
-			       HDA_COMPOSE_AMP_VAL(0x0b, 3, idx, HDA_INPUT))) < 0)
+			       HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0)
 		return err;
 	return 0;
 }
 
 /* create playback/capture controls for input pins */
-static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
+						const struct auto_pin_cfg *cfg)
 {
-	static char *labels[AUTO_PIN_LAST] = {
-		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
-	};
 	struct hda_input_mux *imux = &spec->private_imux;
-	int i, err;
+	int i, err, idx;
 
 	for (i = 0; i < AUTO_PIN_LAST; i++) {
 		if (alc880_is_input_pin(cfg->input_pins[i])) {
-			err = new_analog_input(spec, cfg->input_pins[i], labels[i]);
+			idx = alc880_input_pin_idx(cfg->input_pins[i]);
+			err = new_analog_input(spec, cfg->input_pins[i],
+					       auto_pin_cfg_labels[i],
+					       idx, 0x0b);
 			if (err < 0)
 				return err;
-			imux->items[imux->num_items].label = labels[i];
+			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
 			imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]);
 			imux->num_items++;
 		}
@@ -1955,7 +2118,8 @@
 	return 0;
 }
 
-static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, int pin_type,
+static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
+					      hda_nid_t nid, int pin_type,
 					      int dac_idx)
 {
 	/* set as output */
@@ -1982,11 +2146,14 @@
 	}
 }
 
-static void alc880_auto_init_hp_out(struct hda_codec *codec)
+static void alc880_auto_init_extra_out(struct hda_codec *codec)
 {
 	struct alc_spec *spec = codec->spec;
 	hda_nid_t pin;
 
+	pin = spec->autocfg.speaker_pin;
+	if (pin) /* connect to front */
+		alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
 	pin = spec->autocfg.hp_pin;
 	if (pin) /* connect to front */
 		alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
@@ -2015,15 +2182,21 @@
 {
 	struct alc_spec *spec = codec->spec;
 	int err;
+	static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
 
-	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0)
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+						alc880_ignore)) < 0)
 		return err;
-	if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0)
-		return err;
-	if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin)
+	if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
+	    ! spec->autocfg.hp_pin)
 		return 0; /* can't find valid BIOS pin config */
-	if ((err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
-	    (err = alc880_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 ||
+
+	if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
+	    (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
+	    (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin,
+						"Speaker")) < 0 ||
+	    (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin,
+						"Headphone")) < 0 ||
 	    (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
 		return err;
 
@@ -2049,7 +2222,7 @@
 {
 	alc_init(codec);
 	alc880_auto_init_multi_out(codec);
-	alc880_auto_init_hp_out(codec);
+	alc880_auto_init_extra_out(codec);
 	alc880_auto_init_analog_input(codec);
 	return 0;
 }
@@ -2062,7 +2235,7 @@
 {
 	struct alc_spec *spec;
 	int board_config;
-	int i, err;
+	int err;
 
 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
@@ -2088,36 +2261,8 @@
 		}
 	}
 
-	if (board_config != ALC880_AUTO) {
-		/* set up from the preset table */
-		const struct alc_config_preset *preset;
-
-		preset = &alc880_presets[board_config];
-
-		for (i = 0; preset->mixers[i]; i++) {
-			snd_assert(spec->num_mixers < ARRAY_SIZE(spec->mixers), break);
-			spec->mixers[spec->num_mixers++] = preset->mixers[i];
-		}
-		for (i = 0; preset->init_verbs[i]; i++) {
-			snd_assert(spec->num_init_verbs < ARRAY_SIZE(spec->init_verbs), break);
-			spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i];
-		}
-
-		spec->channel_mode = preset->channel_mode;
-		spec->num_channel_mode = preset->num_channel_mode;
-
-		spec->multiout.max_channels = spec->channel_mode[0].channels;
-
-		spec->multiout.num_dacs = preset->num_dacs;
-		spec->multiout.dac_nids = preset->dac_nids;
-		spec->multiout.dig_out_nid = preset->dig_out_nid;
-		spec->multiout.hp_nid = preset->hp_nid;
-
-		spec->input_mux = preset->input_mux;
-
-		spec->num_adc_nids = preset->num_adc_nids;
-		spec->adc_nids = preset->adc_nids;
-	}
+	if (board_config != ALC880_AUTO)
+		setup_preset(spec, &alc880_presets[board_config]);
 
 	spec->stream_name_analog = "ALC880 Analog";
 	spec->stream_analog_playback = &alc880_pcm_analog_playback;
@@ -2129,8 +2274,7 @@
 
 	if (! spec->adc_nids && spec->input_mux) {
 		/* check whether NID 0x07 is valid */
-		unsigned int wcap = snd_hda_param_read(codec, alc880_adc_nids[0],
-						       AC_PAR_AUDIO_WIDGET_CAP);
+		unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
 		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
 		if (wcap != AC_WID_AUD_IN) {
 			spec->adc_nids = alc880_adc_nids_alt;
@@ -2167,11 +2311,16 @@
 	0x04,
 };
 
-static hda_nid_t alc260_hp_adc_nids[1] = {
+static hda_nid_t alc260_adc_nids_alt[1] = {
 	/* ADC1 */
 	0x05,
 };
 
+static hda_nid_t alc260_hp_adc_nids[2] = {
+	/* ADC1, 0 */
+	0x05, 0x04
+};
+
 #define ALC260_DIGOUT_NID	0x03
 #define ALC260_DIGIN_NID	0x06
 
@@ -2202,13 +2351,30 @@
  * element which allows changing the channel mode, so the verb list is
  * never used.
  */
-static struct alc_channel_mode alc260_modes[1] = {
+static struct hda_channel_mode alc260_modes[1] = {
 	{ 2, NULL },
 };
 
-static snd_kcontrol_new_t alc260_base_mixer[] = {
+
+/* Mixer combinations
+ *
+ * basic: base_output + input + pc_beep + capture
+ * HP: base_output + input + capture_alt
+ * HP_3013: hp_3013 + input + capture
+ * fujitsu: fujitsu + capture
+ */
+
+static struct snd_kcontrol_new alc260_base_output_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
+	{ } /* end */
+};	
+
+static struct snd_kcontrol_new alc260_input_mixer[] = {
 	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
@@ -2217,52 +2383,28 @@
 	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
 	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
 	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
+	{ } /* end */
+};
+
+static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
 	HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
 	HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Capture Source",
-		.info = alc_mux_enum_info,
-		.get = alc_mux_enum_get,
-		.put = alc_mux_enum_put,
-	},
 	{ } /* end */
 };
 
-static snd_kcontrol_new_t alc260_hp_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
-	HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
-	HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
-	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
-	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
-	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
-	HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
-	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Capture Source",
-		.info = alc_mux_enum_info,
-		.get = alc_mux_enum_get,
-		.put = alc_mux_enum_put,
-	},
+static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
+	HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
 	{ } /* end */
 };
 
-static snd_kcontrol_new_t alc260_fujitsu_mixer[] = {
+static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
 	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
 	ALC_PINCTL_SWITCH("Headphone Amp Switch", 0x14, PIN_HP_AMP),
@@ -2274,11 +2416,24 @@
 	HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
 	HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
+	{ } /* end */
+};
+
+/* capture mixer elements */
+static struct snd_kcontrol_new alc260_capture_mixer[] = {
 	HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
 	HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Capture Source",
+		/* The multiple "Capture Source" controls confuse alsamixer
+		 * So call somewhat different..
+		 * FIXME: the controls appear in the "playback" view!
+		 */
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 2,
 		.info = alc_mux_enum_info,
 		.get = alc_mux_enum_get,
 		.put = alc_mux_enum_put,
@@ -2286,6 +2441,28 @@
 	{ } /* end */
 };
 
+static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
+	HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* The multiple "Capture Source" controls confuse alsamixer
+		 * So call somewhat different..
+		 * FIXME: the controls appear in the "playback" view!
+		 */
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 1,
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+/*
+ * initialization verbs
+ */
 static struct hda_verb alc260_init_verbs[] = {
 	/* Line In pin widget for input */
 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -2347,6 +2524,100 @@
 	{ }
 };
 
+static struct hda_verb alc260_hp_init_verbs[] = {
+	/* Headphone and output */
+	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
+	/* mono output */
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	/* Mic1 (rear panel) pin widget for input and vref at 80% */
+	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+	/* Mic2 (front panel) pin widget for input and vref at 80% */
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+	/* Line In pin widget for input */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+	/* Line-2 pin widget for output */
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	/* CD pin widget for input */
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+	/* unmute amp left and right */
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
+	/* set connection select to line in (default select for this ADC) */
+	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
+	/* unmute Line-Out mixer amp left and right (volume = 0) */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	/* mute pin widget amp left and right (no gain on this amp) */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
+	/* unmute HP mixer amp left and right (volume = 0) */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	/* mute pin widget amp left and right (no gain on this amp) */
+	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
+	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+	/* unmute CD */
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
+	/* unmute Line In */
+	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
+	/* unmute Mic */
+	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
+	/* Unmute Front out path */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	/* Unmute Headphone out path */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	/* Unmute Mono out path */
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	{ }
+};
+
+static struct hda_verb alc260_hp_3013_init_verbs[] = {
+	/* Line out and output */
+	{0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	/* mono output */
+	{0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	/* Mic1 (rear panel) pin widget for input and vref at 80% */
+	{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+	/* Mic2 (front panel) pin widget for input and vref at 80% */
+	{0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+	/* Line In pin widget for input */
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+	/* Headphone pin widget for output */
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
+	/* CD pin widget for input */
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+	/* unmute amp left and right */
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
+	/* set connection select to line in (default select for this ADC) */
+	{0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
+	/* unmute Line-Out mixer amp left and right (volume = 0) */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	/* mute pin widget amp left and right (no gain on this amp) */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
+	/* unmute HP mixer amp left and right (volume = 0) */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
+	/* mute pin widget amp left and right (no gain on this amp) */
+	{0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
+	/* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */
+	/* unmute CD */
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
+	/* unmute Line In */
+	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
+	/* unmute Mic */
+	{0x07,  AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	/* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
+	/* Unmute Front out path */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	/* Unmute Headphone out path */
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	/* Unmute Mono out path */
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
+	{ }
+};
+
 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
  * laptops.
  */
@@ -2399,6 +2670,8 @@
         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
+
+	{ }
 };
 
 static struct hda_pcm_stream alc260_pcm_analog_playback = {
@@ -2413,18 +2686,338 @@
 	.channels_max = 2,
 };
 
+#define alc260_pcm_digital_playback	alc880_pcm_digital_playback
+#define alc260_pcm_digital_capture	alc880_pcm_digital_capture
+
+/*
+ * for BIOS auto-configuration
+ */
+
+static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
+					const char *pfx)
+{
+	hda_nid_t nid_vol;
+	unsigned long vol_val, sw_val;
+	char name[32];
+	int err;
+
+	if (nid >= 0x0f && nid < 0x11) {
+		nid_vol = nid - 0x7;
+		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
+		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+	} else if (nid == 0x11) {
+		nid_vol = nid - 0x7;
+		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
+		sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
+	} else if (nid >= 0x12 && nid <= 0x15) {
+		nid_vol = 0x08;
+		vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
+		sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
+	} else
+		return 0; /* N/A */
+	
+	snprintf(name, sizeof(name), "%s Playback Volume", pfx);
+	if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0)
+		return err;
+	snprintf(name, sizeof(name), "%s Playback Switch", pfx);
+	if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0)
+		return err;
+	return 1;
+}
+
+/* add playback controls from the parsed DAC table */
+static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
+					     const struct auto_pin_cfg *cfg)
+{
+	hda_nid_t nid;
+	int err;
+
+	spec->multiout.num_dacs = 1;
+	spec->multiout.dac_nids = spec->private_dac_nids;
+	spec->multiout.dac_nids[0] = 0x02;
+
+	nid = cfg->line_out_pins[0];
+	if (nid) {
+		err = alc260_add_playback_controls(spec, nid, "Front");
+		if (err < 0)
+			return err;
+	}
+
+	nid = cfg->speaker_pin;
+	if (nid) {
+		err = alc260_add_playback_controls(spec, nid, "Speaker");
+		if (err < 0)
+			return err;
+	}
+
+	nid = cfg->hp_pin;
+	if (nid) {
+		err = alc260_add_playback_controls(spec, nid, "Headphone");
+		if (err < 0)
+			return err;
+	}
+	return 0;	
+}
+
+/* create playback/capture controls for input pins */
+static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
+						const struct auto_pin_cfg *cfg)
+{
+	struct hda_input_mux *imux = &spec->private_imux;
+	int i, err, idx;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		if (cfg->input_pins[i] >= 0x12) {
+			idx = cfg->input_pins[i] - 0x12;
+			err = new_analog_input(spec, cfg->input_pins[i],
+					       auto_pin_cfg_labels[i], idx, 0x07);
+			if (err < 0)
+				return err;
+			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+			imux->items[imux->num_items].index = idx;
+			imux->num_items++;
+		}
+		if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){
+			idx = cfg->input_pins[i] - 0x09;
+			err = new_analog_input(spec, cfg->input_pins[i],
+					       auto_pin_cfg_labels[i], idx, 0x07);
+			if (err < 0)
+				return err;
+			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+			imux->items[imux->num_items].index = idx;
+			imux->num_items++;
+		}
+	}
+	return 0;
+}
+
+static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
+					      hda_nid_t nid, int pin_type,
+					      int sel_idx)
+{
+	/* set as output */
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+	/* need the manual connection? */
+	if (nid >= 0x12) {
+		int idx = nid - 0x12;
+		snd_hda_codec_write(codec, idx + 0x0b, 0,
+				    AC_VERB_SET_CONNECT_SEL, sel_idx);
+				    
+	}
+}
+
+static void alc260_auto_init_multi_out(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	hda_nid_t nid;
+
+	nid = spec->autocfg.line_out_pins[0];	
+	if (nid)
+		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
+	
+	nid = spec->autocfg.speaker_pin;
+	if (nid)
+		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
+
+	nid = spec->autocfg.hp_pin;
+	if (nid)
+		alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
+}	
+
+#define ALC260_PIN_CD_NID		0x16
+static void alc260_auto_init_analog_input(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		hda_nid_t nid = spec->autocfg.input_pins[i];
+		if (nid >= 0x12) {
+			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+			if (nid != ALC260_PIN_CD_NID)
+				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+						    AMP_OUT_MUTE);
+		}
+	}
+}
+
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc260_volume_init_verbs[] = {
+	/*
+	 * Unmute ADC0-1 and set the default input to mic-in
+	 */
+	{0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	
+	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+	 * mixer widget
+	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
+	 * mic (mic 2)
+	 */
+	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+	/*
+	 * Set up output mixers (0x08 - 0x0a)
+	 */
+	/* set vol=0 to output mixers */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* set up input amps for analog loopback */
+	/* Amp Indices: DAC = 0, mixer = 1 */
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	
+	{ }
+};
+
+static int alc260_parse_auto_config(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	unsigned int wcap;
+	int err;
+	static hda_nid_t alc260_ignore[] = { 0x17, 0 };
+
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+						alc260_ignore)) < 0)
+		return err;
+	if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0)
+		return err;
+	if (! spec->kctl_alloc)
+		return 0; /* can't find valid BIOS pin config */
+	if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+		return err;
+
+	spec->multiout.max_channels = 2;
+
+	if (spec->autocfg.dig_out_pin)
+		spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
+	if (spec->kctl_alloc)
+		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+	spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
+
+	spec->input_mux = &spec->private_imux;
+
+	/* check whether NID 0x04 is valid */
+	wcap = get_wcaps(codec, 0x04);
+	wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+	if (wcap != AC_WID_AUD_IN) {
+		spec->adc_nids = alc260_adc_nids_alt;
+		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
+		spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
+	} else {
+		spec->adc_nids = alc260_adc_nids;
+		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
+		spec->mixers[spec->num_mixers] = alc260_capture_mixer;
+	}
+	spec->num_mixers++;
+
+	return 1;
+}
+
+/* init callback for auto-configuration model -- overriding the default init */
+static int alc260_auto_init(struct hda_codec *codec)
+{
+	alc_init(codec);
+	alc260_auto_init_multi_out(codec);
+	alc260_auto_init_analog_input(codec);
+	return 0;
+}
+
+/*
+ * ALC260 configurations
+ */
 static struct hda_board_config alc260_cfg_tbl[] = {
+	{ .modelname = "basic", .config = ALC260_BASIC },
 	{ .modelname = "hp", .config = ALC260_HP },
-	{ .pci_subvendor = 0x103c, .config = ALC260_HP },
-	{ .modelname = "fujitsu", .config = ALC260_FUJITSU_S702x },
-	{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702x },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP },
+	{ .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP },
+	{ .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X },
+	{ .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X },
+	{ .modelname = "auto", .config = ALC260_AUTO },
 	{}
 };
 
+static struct alc_config_preset alc260_presets[] = {
+	[ALC260_BASIC] = {
+		.mixers = { alc260_base_output_mixer,
+			    alc260_input_mixer,
+			    alc260_pc_beep_mixer,
+			    alc260_capture_mixer },
+		.init_verbs = { alc260_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
+		.dac_nids = alc260_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
+		.adc_nids = alc260_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc260_modes),
+		.channel_mode = alc260_modes,
+		.input_mux = &alc260_capture_source,
+	},
+	[ALC260_HP] = {
+		.mixers = { alc260_base_output_mixer,
+			    alc260_input_mixer,
+			    alc260_capture_alt_mixer },
+		.init_verbs = { alc260_hp_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
+		.dac_nids = alc260_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
+		.adc_nids = alc260_hp_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc260_modes),
+		.channel_mode = alc260_modes,
+		.input_mux = &alc260_capture_source,
+	},
+	[ALC260_HP_3013] = {
+		.mixers = { alc260_hp_3013_mixer,
+			    alc260_input_mixer,
+			    alc260_capture_alt_mixer },
+		.init_verbs = { alc260_hp_3013_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
+		.dac_nids = alc260_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
+		.adc_nids = alc260_hp_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc260_modes),
+		.channel_mode = alc260_modes,
+		.input_mux = &alc260_capture_source,
+	},
+	[ALC260_FUJITSU_S702X] = {
+		.mixers = { alc260_fujitsu_mixer,
+			    alc260_capture_mixer },
+		.init_verbs = { alc260_fujitsu_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc260_dac_nids),
+		.dac_nids = alc260_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
+		.adc_nids = alc260_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc260_modes),
+		.channel_mode = alc260_modes,
+		.input_mux = &alc260_fujitsu_capture_source,
+	},
+};
+
 static int patch_alc260(struct hda_codec *codec)
 {
 	struct alc_spec *spec;
-	int board_config;
+	int err, board_config;
 
 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
@@ -2435,60 +3028,35 @@
 	board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl);
 	if (board_config < 0 || board_config >= ALC260_MODEL_LAST) {
 		snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260\n");
-		board_config = ALC260_BASIC;
+		board_config = ALC260_AUTO;
 	}
 
-	switch (board_config) {
-	case ALC260_HP:
-		spec->mixers[spec->num_mixers] = alc260_hp_mixer;
-		spec->num_mixers++;
-		break;
-	case ALC260_FUJITSU_S702x:
-		spec->mixers[spec->num_mixers] = alc260_fujitsu_mixer;
-		spec->num_mixers++;
-		break;
-	default:
-		spec->mixers[spec->num_mixers] = alc260_base_mixer;
-		spec->num_mixers++;
-		break;
+	if (board_config == ALC260_AUTO) {
+		/* automatic parse from the BIOS config */
+		err = alc260_parse_auto_config(codec);
+		if (err < 0) {
+			alc_free(codec);
+			return err;
+		} else if (! err) {
+			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
+			board_config = ALC260_BASIC;
+		}
 	}
 
-	if (board_config != ALC260_FUJITSU_S702x) {
-		spec->init_verbs[0] = alc260_init_verbs;
-		spec->num_init_verbs = 1;
-	} else {
-		spec->init_verbs[0] = alc260_fujitsu_init_verbs;
-		spec->num_init_verbs = 1;
-	}
-
-	spec->channel_mode = alc260_modes;
-	spec->num_channel_mode = ARRAY_SIZE(alc260_modes);
+	if (board_config != ALC260_AUTO)
+		setup_preset(spec, &alc260_presets[board_config]);
 
 	spec->stream_name_analog = "ALC260 Analog";
 	spec->stream_analog_playback = &alc260_pcm_analog_playback;
 	spec->stream_analog_capture = &alc260_pcm_analog_capture;
 
-	spec->multiout.max_channels = spec->channel_mode[0].channels;
-	spec->multiout.num_dacs = ARRAY_SIZE(alc260_dac_nids);
-	spec->multiout.dac_nids = alc260_dac_nids;
-
-	if (board_config != ALC260_FUJITSU_S702x) {
-		spec->input_mux = &alc260_capture_source;
-	} else {
-		spec->input_mux = &alc260_fujitsu_capture_source;
-	}
-	switch (board_config) {
-	case ALC260_HP:
-		spec->num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids);
-		spec->adc_nids = alc260_hp_adc_nids;
-		break;
-	default:
-		spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
-		spec->adc_nids = alc260_adc_nids;
-		break;
-	}
+	spec->stream_name_digital = "ALC260 Digital";
+	spec->stream_digital_playback = &alc260_pcm_digital_playback;
+	spec->stream_digital_capture = &alc260_pcm_digital_capture;
 
 	codec->patch_ops = alc_patch_ops;
+	if (board_config == ALC260_AUTO)
+		codec->patch_ops.init = alc260_auto_init;
 
 	return 0;
 }
@@ -2505,8 +3073,10 @@
  * In addition, an independent DAC for the multi-playback (not used in this
  * driver yet).
  */
+#define ALC882_DIGOUT_NID	0x06
+#define ALC882_DIGIN_NID	0x0a
 
-static struct alc_channel_mode alc882_ch_modes[1] = {
+static struct hda_channel_mode alc882_ch_modes[1] = {
 	{ 8, NULL }
 };
 
@@ -2515,10 +3085,9 @@
 	0x02, 0x03, 0x04, 0x05
 };
 
-static hda_nid_t alc882_adc_nids[3] = {
-	/* ADC0-2 */
-	0x07, 0x08, 0x09,
-};
+/* identical with ALC880 */
+#define alc882_adc_nids		alc880_adc_nids
+#define alc882_adc_nids_alt	alc880_adc_nids_alt
 
 /* input MUX */
 /* FIXME: should be a matrix-type input source selection */
@@ -2536,7 +3105,7 @@
 #define alc882_mux_enum_info alc_mux_enum_info
 #define alc882_mux_enum_get alc_mux_enum_get
 
-static int alc882_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct alc_spec *spec = codec->spec;
@@ -2561,10 +3130,37 @@
 	return 1;
 }
 
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc882_sixstack_ch6_init[] = {
+	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ } /* end */
+};
+
+/*
+ * 8ch mode
+ */
+static struct hda_verb alc882_sixstack_ch8_init[] = {
+	{ 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ } /* end */
+};
+
+static struct hda_channel_mode alc882_sixstack_modes[2] = {
+	{ 6, alc882_sixstack_ch6_init },
+	{ 8, alc882_sixstack_ch8_init },
+};
+
 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
  */
-static snd_kcontrol_new_t alc882_base_mixer[] = {
+static struct snd_kcontrol_new alc882_base_mixer[] = {
 	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
 	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
 	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
@@ -2604,6 +3200,17 @@
 	{ } /* end */
 };
 
+static struct snd_kcontrol_new alc882_chmode_mixer[] = {
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Channel Mode",
+		.info = alc_ch_mode_info,
+		.get = alc_ch_mode_get,
+		.put = alc_ch_mode_put,
+	},
+	{ } /* end */
+};
+
 static struct hda_verb alc882_init_verbs[] = {
 	/* Front mixer: unmute input/output amp left and right (volume = 0) */
 	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -2684,9 +3291,264 @@
 	{ }
 };
 
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc882_auto_init_verbs[] = {
+	/*
+	 * Unmute ADC0-2 and set the default input to mic-in
+	 */
+	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+	 * mixer widget
+	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
+	 * mic (mic 2)
+	 */
+	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+	/*
+	 * Set up output mixers (0x0c - 0x0f)
+	 */
+	/* set vol=0 to output mixers */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* set up input amps for analog loopback */
+	/* Amp Indices: DAC = 0, mixer = 1 */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+	/* FIXME: use matrix-type input source selection */
+	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+	/* Input mixer2 */
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+	/* Input mixer3 */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+
+	{ }
+};
+
+/* capture mixer elements */
+static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* The multiple "Capture Source" controls confuse alsamixer
+		 * So call somewhat different..
+		 * FIXME: the controls appear in the "playback" view!
+		 */
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 2,
+		.info = alc882_mux_enum_info,
+		.get = alc882_mux_enum_get,
+		.put = alc882_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static struct snd_kcontrol_new alc882_capture_mixer[] = {
+	HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* The multiple "Capture Source" controls confuse alsamixer
+		 * So call somewhat different..
+		 * FIXME: the controls appear in the "playback" view!
+		 */
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 3,
+		.info = alc882_mux_enum_info,
+		.get = alc882_mux_enum_get,
+		.put = alc882_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+/* pcm configuration: identiacal with ALC880 */
+#define alc882_pcm_analog_playback	alc880_pcm_analog_playback
+#define alc882_pcm_analog_capture	alc880_pcm_analog_capture
+#define alc882_pcm_digital_playback	alc880_pcm_digital_playback
+#define alc882_pcm_digital_capture	alc880_pcm_digital_capture
+
+/*
+ * configuration and preset
+ */
+static struct hda_board_config alc882_cfg_tbl[] = {
+	{ .modelname = "3stack-dig", .config = ALC861_3ST_DIG },
+	{ .modelname = "6stack-dig", .config = ALC861_6ST_DIG },
+	{ .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* MSI  */
+	{ .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* Foxconn */
+	{ .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, .config = ALC882_6ST_DIG }, /* ECS */
+	{ .modelname = "auto", .config = ALC861_AUTO },
+	{}
+};
+
+static struct alc_config_preset alc882_presets[] = {
+	[ALC882_3ST_DIG] = {
+		.mixers = { alc882_base_mixer },
+		.init_verbs = { alc882_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
+		.dac_nids = alc882_dac_nids,
+		.dig_out_nid = ALC882_DIGOUT_NID,
+		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
+		.adc_nids = alc882_adc_nids,
+		.dig_in_nid = ALC882_DIGIN_NID,
+		.num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
+		.channel_mode = alc882_ch_modes,
+		.input_mux = &alc882_capture_source,
+	},
+	[ALC882_6ST_DIG] = {
+		.mixers = { alc882_base_mixer, alc882_chmode_mixer },
+		.init_verbs = { alc882_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
+		.dac_nids = alc882_dac_nids,
+		.dig_out_nid = ALC882_DIGOUT_NID,
+		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
+		.adc_nids = alc882_adc_nids,
+		.dig_in_nid = ALC882_DIGIN_NID,
+		.num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
+		.channel_mode = alc882_sixstack_modes,
+		.input_mux = &alc882_capture_source,
+	},
+};
+
+
+/*
+ * BIOS auto configuration
+ */
+static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
+					      hda_nid_t nid, int pin_type,
+					      int dac_idx)
+{
+	/* set as output */
+	struct alc_spec *spec = codec->spec;
+	int idx; 
+	
+	if (spec->multiout.dac_nids[dac_idx] == 0x25)
+		idx = 4;
+	else
+		idx = spec->multiout.dac_nids[dac_idx] - 2;
+
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
+
+}
+
+static void alc882_auto_init_multi_out(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i <= HDA_SIDE; i++) {
+		hda_nid_t nid = spec->autocfg.line_out_pins[i];	
+		if (nid)
+			alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
+	}
+}
+
+static void alc882_auto_init_hp_out(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	hda_nid_t pin;
+
+	pin = spec->autocfg.hp_pin;
+	if (pin) /* connect to front */
+		alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */
+}
+
+#define alc882_is_input_pin(nid)	alc880_is_input_pin(nid)
+#define ALC882_PIN_CD_NID		ALC880_PIN_CD_NID
+
+static void alc882_auto_init_analog_input(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		hda_nid_t nid = spec->autocfg.input_pins[i];
+		if (alc882_is_input_pin(nid)) {
+			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+			if (nid != ALC882_PIN_CD_NID)
+				snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+						    AMP_OUT_MUTE);
+		}
+	}
+}
+
+/* almost identical with ALC880 parser... */
+static int alc882_parse_auto_config(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int err = alc880_parse_auto_config(codec);
+
+	if (err < 0)
+		return err;
+	else if (err > 0)
+		/* hack - override the init verbs */
+		spec->init_verbs[0] = alc882_auto_init_verbs;
+	return err;
+}
+
+/* init callback for auto-configuration model -- overriding the default init */
+static int alc882_auto_init(struct hda_codec *codec)
+{
+	alc_init(codec);
+	alc882_auto_init_multi_out(codec);
+	alc882_auto_init_hp_out(codec);
+	alc882_auto_init_analog_input(codec);
+	return 0;
+}
+
+/*
+ *  ALC882 Headphone poll in 3.5.1a or 3.5.2
+ */
+
 static int patch_alc882(struct hda_codec *codec)
 {
 	struct alc_spec *spec;
+	int err, board_config;
 
 	spec = kzalloc(sizeof(*spec), GFP_KERNEL);
 	if (spec == NULL)
@@ -2694,44 +3556,1147 @@
 
 	codec->spec = spec;
 
-	spec->mixers[spec->num_mixers] = alc882_base_mixer;
-	spec->num_mixers++;
+	board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl);
 
-	spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
-	spec->dig_in_nid = ALC880_DIGIN_NID;
-	spec->init_verbs[0] = alc882_init_verbs;
-	spec->num_init_verbs = 1;
+	if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
+		printk(KERN_INFO "hda_codec: Unknown model for ALC882, trying auto-probe from BIOS...\n");
+		board_config = ALC882_AUTO;
+	}
 
-	spec->channel_mode = alc882_ch_modes;
-	spec->num_channel_mode = ARRAY_SIZE(alc882_ch_modes);
+	if (board_config == ALC882_AUTO) {
+		/* automatic parse from the BIOS config */
+		err = alc882_parse_auto_config(codec);
+		if (err < 0) {
+			alc_free(codec);
+			return err;
+		} else if (! err) {
+			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
+			board_config = ALC882_3ST_DIG;
+		}
+	}
+
+	if (board_config != ALC882_AUTO)
+		setup_preset(spec, &alc882_presets[board_config]);
 
 	spec->stream_name_analog = "ALC882 Analog";
-	spec->stream_analog_playback = &alc880_pcm_analog_playback;
-	spec->stream_analog_capture = &alc880_pcm_analog_capture;
+	spec->stream_analog_playback = &alc882_pcm_analog_playback;
+	spec->stream_analog_capture = &alc882_pcm_analog_capture;
 
 	spec->stream_name_digital = "ALC882 Digital";
-	spec->stream_digital_playback = &alc880_pcm_digital_playback;
-	spec->stream_digital_capture = &alc880_pcm_digital_capture;
+	spec->stream_digital_playback = &alc882_pcm_digital_playback;
+	spec->stream_digital_capture = &alc882_pcm_digital_capture;
 
-	spec->multiout.max_channels = spec->channel_mode[0].channels;
-	spec->multiout.num_dacs = ARRAY_SIZE(alc882_dac_nids);
-	spec->multiout.dac_nids = alc882_dac_nids;
-
-	spec->input_mux = &alc882_capture_source;
-	spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
-	spec->adc_nids = alc882_adc_nids;
+	if (! spec->adc_nids && spec->input_mux) {
+		/* check whether NID 0x07 is valid */
+		unsigned int wcap = get_wcaps(codec, 0x07);
+		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+		if (wcap != AC_WID_AUD_IN) {
+			spec->adc_nids = alc882_adc_nids_alt;
+			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
+			spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer;
+			spec->num_mixers++;
+		} else {
+			spec->adc_nids = alc882_adc_nids;
+			spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
+			spec->mixers[spec->num_mixers] = alc882_capture_mixer;
+			spec->num_mixers++;
+		}
+	}
 
 	codec->patch_ops = alc_patch_ops;
+	if (board_config == ALC882_AUTO)
+		codec->patch_ops.init = alc882_auto_init;
 
 	return 0;
 }
 
 /*
+ * ALC262 support
+ */
+
+#define ALC262_DIGOUT_NID	ALC880_DIGOUT_NID
+#define ALC262_DIGIN_NID	ALC880_DIGIN_NID
+
+#define alc262_dac_nids		alc260_dac_nids
+#define alc262_adc_nids		alc882_adc_nids
+#define alc262_adc_nids_alt	alc882_adc_nids_alt
+
+#define alc262_modes		alc260_modes
+#define alc262_capture_source	alc882_capture_source
+
+static struct snd_kcontrol_new alc262_base_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+	/* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
+	   HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.count = 1,
+		.info = alc882_mux_enum_info,
+		.get = alc882_mux_enum_get,
+		.put = alc882_mux_enum_put,
+	},
+	{ } /* end */
+};			
+	
+#define alc262_capture_mixer		alc882_capture_mixer
+#define alc262_capture_alt_mixer	alc882_capture_alt_mixer
+
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc262_init_verbs[] = {
+	/*
+	 * Unmute ADC0-2 and set the default input to mic-in
+	 */
+	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+	 * mixer widget
+	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
+	 * mic (mic 2)
+	 */
+	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+	/*
+	 * Set up output mixers (0x0c - 0x0e)
+	 */
+	/* set vol=0 to output mixers */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	/* set up input amps for analog loopback */
+	/* Amp Indices: DAC = 0, mixer = 1 */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
+
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
+	
+	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
+	
+	/* FIXME: use matrix-type input source selection */
+	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+	/* Input mixer2 */
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+	/* Input mixer3 */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},	
+
+	{ }
+};
+
+/* add playback controls from the parsed DAC table */
+static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+{
+	hda_nid_t nid;
+	int err;
+
+	spec->multiout.num_dacs = 1;	/* only use one dac */
+	spec->multiout.dac_nids = spec->private_dac_nids;
+	spec->multiout.dac_nids[0] = 2;
+
+	nid = cfg->line_out_pins[0];
+	if (nid) {
+		if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume",
+				       HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
+			return err;
+		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch",
+				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+			return err;
+	}
+
+	nid = cfg->speaker_pin;
+	if (nid) {
+		if (nid == 0x16) {
+			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
+					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
+				return err;
+			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+				return err;
+		} else {
+			if (! cfg->line_out_pins[0])
+				if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume",
+					       HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
+					return err;
+			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+				return err;
+		}
+	}
+	nid = cfg->hp_pin;
+	if (nid) {
+		/* spec->multiout.hp_nid = 2; */
+		if (nid == 0x16) {
+			if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
+					       HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0)
+				return err;
+			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+				return err;
+		} else {
+			if (! cfg->line_out_pins[0])
+				if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume",
+					       HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0)
+					return err;
+			if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+				return err;
+		}
+	}
+	return 0;	
+}
+
+/* identical with ALC880 */
+#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls
+
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc262_volume_init_verbs[] = {
+	/*
+	 * Unmute ADC0-2 and set the default input to mic-in
+	 */
+	{0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+
+	/* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
+	 * mixer widget
+	 * Note: PASD motherboards uses the Line In 2 as the input for front panel
+	 * mic (mic 2)
+	 */
+	/* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
+	{0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
+
+	/*
+	 * Set up output mixers (0x0c - 0x0f)
+	 */
+	/* set vol=0 to output mixers */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	
+	/* set up input amps for analog loopback */
+	/* Amp Indices: DAC = 0, mixer = 1 */
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+	/* FIXME: use matrix-type input source selection */
+	/* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
+	/* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+	{0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+	/* Input mixer2 */
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+	{0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+	/* Input mixer3 */
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
+
+	{ }
+};
+
+/* pcm configuration: identiacal with ALC880 */
+#define alc262_pcm_analog_playback	alc880_pcm_analog_playback
+#define alc262_pcm_analog_capture	alc880_pcm_analog_capture
+#define alc262_pcm_digital_playback	alc880_pcm_digital_playback
+#define alc262_pcm_digital_capture	alc880_pcm_digital_capture
+
+/*
+ * BIOS auto configuration
+ */
+static int alc262_parse_auto_config(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int err;
+	static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
+
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+						alc262_ignore)) < 0)
+		return err;
+	if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
+	    ! spec->autocfg.hp_pin)
+		return 0; /* can't find valid BIOS pin config */
+	if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
+	    (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+		return err;
+
+	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+
+	if (spec->autocfg.dig_out_pin)
+		spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
+	if (spec->autocfg.dig_in_pin)
+		spec->dig_in_nid = ALC262_DIGIN_NID;
+
+	if (spec->kctl_alloc)
+		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+	spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
+	spec->input_mux = &spec->private_imux;
+
+	return 1;
+}
+
+#define alc262_auto_init_multi_out	alc882_auto_init_multi_out
+#define alc262_auto_init_hp_out		alc882_auto_init_hp_out
+#define alc262_auto_init_analog_input	alc882_auto_init_analog_input
+
+
+/* init callback for auto-configuration model -- overriding the default init */
+static int alc262_auto_init(struct hda_codec *codec)
+{
+	alc_init(codec);
+	alc262_auto_init_multi_out(codec);
+	alc262_auto_init_hp_out(codec);
+	alc262_auto_init_analog_input(codec);
+	return 0;
+}
+
+/*
+ * configuration and preset
+ */
+static struct hda_board_config alc262_cfg_tbl[] = {
+	{ .modelname = "basic", .config = ALC262_BASIC },
+	{ .modelname = "auto", .config = ALC262_AUTO },
+	{}
+};
+
+static struct alc_config_preset alc262_presets[] = {
+	[ALC262_BASIC] = {
+		.mixers = { alc262_base_mixer },
+		.init_verbs = { alc262_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
+		.dac_nids = alc262_dac_nids,
+		.hp_nid = 0x03,
+		.num_channel_mode = ARRAY_SIZE(alc262_modes),
+		.channel_mode = alc262_modes,
+		.input_mux = &alc262_capture_source,
+	},
+};
+
+static int patch_alc262(struct hda_codec *codec)
+{
+	struct alc_spec *spec;
+	int board_config;
+	int err;
+
+	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	codec->spec = spec;
+#if 0
+	/* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is under-run */
+	{
+	int tmp;
+	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
+	tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
+	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
+	snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
+	}
+#endif
+
+	board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl);
+	if (board_config < 0 || board_config >= ALC262_MODEL_LAST) {
+		printk(KERN_INFO "hda_codec: Unknown model for ALC262, trying auto-probe from BIOS...\n");
+		board_config = ALC262_AUTO;
+	}
+
+	if (board_config == ALC262_AUTO) {
+		/* automatic parse from the BIOS config */
+		err = alc262_parse_auto_config(codec);
+		if (err < 0) {
+			alc_free(codec);
+			return err;
+		} else if (! err) {
+			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
+			board_config = ALC262_BASIC;
+		}
+	}
+
+	if (board_config != ALC262_AUTO)
+		setup_preset(spec, &alc262_presets[board_config]);
+
+	spec->stream_name_analog = "ALC262 Analog";
+	spec->stream_analog_playback = &alc262_pcm_analog_playback;
+	spec->stream_analog_capture = &alc262_pcm_analog_capture;
+		
+	spec->stream_name_digital = "ALC262 Digital";
+	spec->stream_digital_playback = &alc262_pcm_digital_playback;
+	spec->stream_digital_capture = &alc262_pcm_digital_capture;
+
+	if (! spec->adc_nids && spec->input_mux) {
+		/* check whether NID 0x07 is valid */
+		unsigned int wcap = get_wcaps(codec, 0x07);
+
+		wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
+		if (wcap != AC_WID_AUD_IN) {
+			spec->adc_nids = alc262_adc_nids_alt;
+			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
+			spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer;
+			spec->num_mixers++;
+		} else {
+			spec->adc_nids = alc262_adc_nids;
+			spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
+			spec->mixers[spec->num_mixers] = alc262_capture_mixer;
+			spec->num_mixers++;
+		}
+	}
+
+	codec->patch_ops = alc_patch_ops;
+	if (board_config == ALC262_AUTO)
+		codec->patch_ops.init = alc262_auto_init;
+	
+	return 0;
+}
+
+
+/*
+ *  ALC861 channel source setting (2/6 channel selection for 3-stack)
+ */
+
+/*
+ * set the path ways for 2 channel output
+ * need to set the codec line out and mic 1 pin widgets to inputs
+ */
+static struct hda_verb alc861_threestack_ch2_init[] = {
+	/* set pin widget 1Ah (line in) for input */
+	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	/* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
+	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+
+        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
+        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, //mic
+        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, //line in
+	{ } /* end */
+};
+/*
+ * 6ch mode
+ * need to set the codec line out and mic 1 pin widgets to outputs
+ */
+static struct hda_verb alc861_threestack_ch6_init[] = {
+	/* set pin widget 1Ah (line in) for output (Back Surround)*/
+	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	/* set pin widget 18h (mic1) for output (CLFE)*/
+	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+
+	{ 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
+        { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
+
+        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
+        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, //mic
+        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, //line in
+	{ } /* end */
+};
+
+static struct hda_channel_mode alc861_threestack_modes[2] = {
+	{ 2, alc861_threestack_ch2_init },
+	{ 6, alc861_threestack_ch6_init },
+};
+
+/* patch-ALC861 */
+
+static struct snd_kcontrol_new alc861_base_mixer[] = {
+        /* output mixer control */
+	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
+
+        /*Input mixer control */
+	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
+	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
+ 
+        /* Capture mixer control */
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.count = 1,
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static struct snd_kcontrol_new alc861_3ST_mixer[] = {
+        /* output mixer control */
+	HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
+	/*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
+
+	/* Input mixer control */
+	/* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
+	   HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
+ 
+	/* Capture mixer control */
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Source",
+		.count = 1,
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Channel Mode",
+		.info = alc_ch_mode_info,
+		.get = alc_ch_mode_get,
+		.put = alc_ch_mode_put,
+                .private_value = ARRAY_SIZE(alc861_threestack_modes),
+	},
+	{ } /* end */
+};			
+	
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc861_base_init_verbs[] = {
+	/*
+	 * Unmute ADC0 and set the default input to mic-in
+	 */
+	/* port-A for surround (rear panel) */
+	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{ 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
+	/* port-B for mic-in (rear panel) with vref */
+	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	/* port-C for line-in (rear panel) */
+	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	/* port-D for Front */
+	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
+	/* port-E for HP out (front panel) */
+	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	/* route front PCM to HP */
+	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
+	/* port-F for mic-in (front panel) with vref */
+	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	/* port-G for CLFE (rear panel) */
+	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{ 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
+	/* port-H for side (rear panel) */
+	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{ 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
+	/* CD-in */
+	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	/* route front mic to ADC1*/
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	
+	/* Unmute DAC0~3 & spdif out*/
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	
+	/* Unmute Mixer 14 (mic) 1c (Line in)*/
+	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	
+	/* Unmute Stereo Mixer 15 */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
+
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+
+	{ }
+};
+
+static struct hda_verb alc861_threestack_init_verbs[] = {
+	/*
+	 * Unmute ADC0 and set the default input to mic-in
+	 */
+	/* port-A for surround (rear panel) */
+	{ 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+	/* port-B for mic-in (rear panel) with vref */
+	{ 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	/* port-C for line-in (rear panel) */
+	{ 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	/* port-D for Front */
+	{ 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
+	{ 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
+	/* port-E for HP out (front panel) */
+	{ 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
+	/* route front PCM to HP */
+	{ 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 },
+	/* port-F for mic-in (front panel) with vref */
+	{ 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
+	/* port-G for CLFE (rear panel) */
+	{ 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+	/* port-H for side (rear panel) */
+	{ 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
+	/* CD-in */
+	{ 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
+	/* route front mic to ADC1*/
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	/* Unmute DAC0~3 & spdif out*/
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	
+	/* Unmute Mixer 14 (mic) 1c (Line in)*/
+	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+        {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+        {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	
+	/* Unmute Stereo Mixer 15 */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c          }, //Output 0~12 step
+
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front)
+        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{ }
+};
+/*
+ * generic initialization of ADC, input mixers and output mixers
+ */
+static struct hda_verb alc861_auto_init_verbs[] = {
+	/*
+	 * Unmute ADC0 and set the default input to mic-in
+	 */
+//	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	
+	/* Unmute DAC0~3 & spdif out*/
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	
+	/* Unmute Mixer 14 (mic) 1c (Line in)*/
+	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	
+	/* Unmute Stereo Mixer 15 */
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
+
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},	
+	{0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},		
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},	
+	{0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},	
+
+	{0x08, AC_VERB_SET_CONNECT_SEL, 0x00},	// set Mic 1
+
+	{ }
+};
+
+/* pcm configuration: identiacal with ALC880 */
+#define alc861_pcm_analog_playback	alc880_pcm_analog_playback
+#define alc861_pcm_analog_capture	alc880_pcm_analog_capture
+#define alc861_pcm_digital_playback	alc880_pcm_digital_playback
+#define alc861_pcm_digital_capture	alc880_pcm_digital_capture
+
+
+#define ALC861_DIGOUT_NID	0x07
+
+static struct hda_channel_mode alc861_8ch_modes[1] = {
+	{ 8, NULL }
+};
+
+static hda_nid_t alc861_dac_nids[4] = {
+	/* front, surround, clfe, side */
+	0x03, 0x06, 0x05, 0x04
+};
+
+static hda_nid_t alc861_adc_nids[1] = {
+	/* ADC0-2 */
+	0x08,
+};
+
+static struct hda_input_mux alc861_capture_source = {
+	.num_items = 5,
+	.items = {
+		{ "Mic", 0x0 },
+		{ "Front Mic", 0x3 },
+		{ "Line", 0x1 },
+		{ "CD", 0x4 },
+		{ "Mixer", 0x5 },
+	},
+};
+
+/* fill in the dac_nids table from the parsed pin configuration */
+static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+{
+	int i;
+	hda_nid_t nid;
+
+	spec->multiout.dac_nids = spec->private_dac_nids;
+	for (i = 0; i < cfg->line_outs; i++) {
+		nid = cfg->line_out_pins[i];
+		if (nid) {
+			if (i >= ARRAY_SIZE(alc861_dac_nids))
+				continue;
+			spec->multiout.dac_nids[i] = alc861_dac_nids[i];
+		}
+	}
+	spec->multiout.num_dacs = cfg->line_outs;
+	return 0;
+}
+
+/* add playback controls from the parsed DAC table */
+static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
+					     const struct auto_pin_cfg *cfg)
+{
+	char name[32];
+	static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" };
+	hda_nid_t nid;
+	int i, idx, err;
+
+	for (i = 0; i < cfg->line_outs; i++) {
+		nid = spec->multiout.dac_nids[i];
+		if (! nid)
+			continue;
+		if (nid == 0x05) {
+			/* Center/LFE */
+			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0)
+				return err;
+			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch",
+					       HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0)
+				return err;
+		} else {
+			for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++)
+				if (nid == alc861_dac_nids[idx])
+					break;
+			sprintf(name, "%s Playback Switch", chname[idx]);
+			if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
+					       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+				return err;
+		}
+	}
+	return 0;
+}
+
+static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
+{
+	int err;
+	hda_nid_t nid;
+
+	if (! pin)
+		return 0;
+
+	if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
+		nid = 0x03;
+		if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch",
+				       HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0)
+			return err;
+		spec->multiout.hp_nid = nid;
+	}
+	return 0;
+}
+
+/* create playback/capture controls for input pins */
+static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg)
+{
+	struct hda_input_mux *imux = &spec->private_imux;
+	int i, err, idx, idx1;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		switch(cfg->input_pins[i]) {
+		case 0x0c:
+			idx1 = 1;
+			idx = 2;	// Line In
+			break;
+		case 0x0f:
+			idx1 = 2;
+			idx = 2;	// Line In
+			break;
+		case 0x0d:
+			idx1 = 0;
+			idx = 1;	// Mic In 
+			break;
+		case 0x10:	
+			idx1 = 3;
+			idx = 1;	// Mic In 
+			break;
+		case 0x11:
+			idx1 = 4;
+			idx = 0;	// CD
+			break;
+		default:
+			continue;
+		}
+
+		err = new_analog_input(spec, cfg->input_pins[i],
+				       auto_pin_cfg_labels[i], idx, 0x15);
+		if (err < 0)
+			return err;
+
+		imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
+		imux->items[imux->num_items].index = idx1;
+		imux->num_items++;	
+	}
+	return 0;
+}
+
+static struct snd_kcontrol_new alc861_capture_mixer[] = {
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* The multiple "Capture Source" controls confuse alsamixer
+		 * So call somewhat different..
+		 *FIXME: the controls appear in the "playback" view!
+		 */
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 1,
+		.info = alc_mux_enum_info,
+		.get = alc_mux_enum_get,
+		.put = alc_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid,
+					      int pin_type, int dac_idx)
+{
+	/* set as output */
+
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+	snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
+
+}
+
+static void alc861_auto_init_multi_out(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < spec->autocfg.line_outs; i++) {
+		hda_nid_t nid = spec->autocfg.line_out_pins[i];
+		if (nid)
+			alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]);
+	}
+}
+
+static void alc861_auto_init_hp_out(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	hda_nid_t pin;
+
+	pin = spec->autocfg.hp_pin;
+	if (pin) /* connect to front */
+		alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]);
+}
+
+static void alc861_auto_init_analog_input(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int i;
+
+	for (i = 0; i < AUTO_PIN_LAST; i++) {
+		hda_nid_t nid = spec->autocfg.input_pins[i];
+		if ((nid>=0x0c) && (nid <=0x11)) {
+			snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+					    i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN);
+		}
+	}
+}
+
+/* parse the BIOS configuration and set up the alc_spec */
+/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
+static int alc861_parse_auto_config(struct hda_codec *codec)
+{
+	struct alc_spec *spec = codec->spec;
+	int err;
+	static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
+
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
+						alc861_ignore)) < 0)
+		return err;
+	if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin &&
+	    ! spec->autocfg.hp_pin)
+		return 0; /* can't find valid BIOS pin config */
+
+	if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
+	    (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
+	    (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pin)) < 0 ||
+	    (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0)
+		return err;
+
+	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
+
+	if (spec->autocfg.dig_out_pin)
+		spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
+
+	if (spec->kctl_alloc)
+		spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
+
+	spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
+
+	spec->input_mux = &spec->private_imux;
+
+	spec->adc_nids = alc861_adc_nids;
+	spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
+	spec->mixers[spec->num_mixers] = alc861_capture_mixer;
+	spec->num_mixers++;
+
+	return 1;
+}
+
+/* init callback for auto-configuration model -- overriding the default init */
+static int alc861_auto_init(struct hda_codec *codec)
+{
+	alc_init(codec);
+	alc861_auto_init_multi_out(codec);
+	alc861_auto_init_hp_out(codec);
+	alc861_auto_init_analog_input(codec);
+
+	return 0;
+}
+
+
+/*
+ * configuration and preset
+ */
+static struct hda_board_config alc861_cfg_tbl[] = {
+	{ .modelname = "3stack", .config = ALC861_3ST },
+	{ .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, .config = ALC861_3ST },
+	{ .modelname = "3stack-dig", .config = ALC861_3ST_DIG },
+	{ .modelname = "6stack-dig", .config = ALC861_6ST_DIG },
+	{ .modelname = "auto", .config = ALC861_AUTO },
+	{}
+};
+
+static struct alc_config_preset alc861_presets[] = {
+	[ALC861_3ST] = {
+		.mixers = { alc861_3ST_mixer },
+		.init_verbs = { alc861_threestack_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
+		.dac_nids = alc861_dac_nids,
+		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
+		.channel_mode = alc861_threestack_modes,
+		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
+		.adc_nids = alc861_adc_nids,
+		.input_mux = &alc861_capture_source,
+	},
+	[ALC861_3ST_DIG] = {
+		.mixers = { alc861_base_mixer },
+		.init_verbs = { alc861_threestack_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
+		.dac_nids = alc861_dac_nids,
+		.dig_out_nid = ALC861_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
+		.channel_mode = alc861_threestack_modes,
+		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
+		.adc_nids = alc861_adc_nids,
+		.input_mux = &alc861_capture_source,
+	},
+	[ALC861_6ST_DIG] = {
+		.mixers = { alc861_base_mixer },
+		.init_verbs = { alc861_base_init_verbs },
+		.num_dacs = ARRAY_SIZE(alc861_dac_nids),
+		.dac_nids = alc861_dac_nids,
+		.dig_out_nid = ALC861_DIGOUT_NID,
+		.num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
+		.channel_mode = alc861_8ch_modes,
+		.num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
+		.adc_nids = alc861_adc_nids,
+		.input_mux = &alc861_capture_source,
+	},
+};	
+
+
+static int patch_alc861(struct hda_codec *codec)
+{
+	struct alc_spec *spec;
+	int board_config;
+	int err;
+
+	spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
+	if (spec == NULL)
+		return -ENOMEM;
+
+	codec->spec = spec;	
+
+        board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl);
+	if (board_config < 0 || board_config >= ALC861_MODEL_LAST) {
+		printk(KERN_INFO "hda_codec: Unknown model for ALC861, trying auto-probe from BIOS...\n");
+		board_config = ALC861_AUTO;
+	}
+
+	if (board_config == ALC861_AUTO) {
+		/* automatic parse from the BIOS config */
+		err = alc861_parse_auto_config(codec);
+		if (err < 0) {
+			alc_free(codec);
+			return err;
+		} else if (! err) {
+			printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using base mode...\n");
+		   board_config = ALC861_3ST_DIG;
+		}
+	}
+
+	if (board_config != ALC861_AUTO)
+		setup_preset(spec, &alc861_presets[board_config]);
+
+	spec->stream_name_analog = "ALC861 Analog";
+	spec->stream_analog_playback = &alc861_pcm_analog_playback;
+	spec->stream_analog_capture = &alc861_pcm_analog_capture;
+
+	spec->stream_name_digital = "ALC861 Digital";
+	spec->stream_digital_playback = &alc861_pcm_digital_playback;
+	spec->stream_digital_capture = &alc861_pcm_digital_capture;
+
+	codec->patch_ops = alc_patch_ops;
+	if (board_config == ALC861_AUTO)
+		codec->patch_ops.init = alc861_auto_init;
+		
+	return 0;
+}
+
+/*
  * patch entries
  */
 struct hda_codec_preset snd_hda_preset_realtek[] = {
 	{ .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
+	{ .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
  	{ .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
 	{ .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
+	{ .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
+	{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
+	{ .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
 	{} /* terminator */
 };
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 9c7fe0b..8f8840e 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -95,8 +95,8 @@
 #define PRIVATE_REG(val) ((val>>16)&0xffff)
 #define PRIVATE_MASK(val) (val&0xffff)
 
-static int si3054_switch_info(snd_kcontrol_t *kcontrol,
-		               snd_ctl_elem_info_t *uinfo)
+static int si3054_switch_info(struct snd_kcontrol *kcontrol,
+		               struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -105,8 +105,8 @@
 	return 0;
 }
 
-static int si3054_switch_get(snd_kcontrol_t *kcontrol,
-		               snd_ctl_elem_value_t *uvalue)
+static int si3054_switch_get(struct snd_kcontrol *kcontrol,
+		               struct snd_ctl_elem_value *uvalue)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	u16 reg  = PRIVATE_REG(kcontrol->private_value);
@@ -115,8 +115,8 @@
 	return 0;
 }
 
-static int si3054_switch_put(snd_kcontrol_t *kcontrol,
-		               snd_ctl_elem_value_t *uvalue)
+static int si3054_switch_put(struct snd_kcontrol *kcontrol,
+		               struct snd_ctl_elem_value *uvalue)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	u16 reg  = PRIVATE_REG(kcontrol->private_value);
@@ -138,7 +138,7 @@
 }
 		
 
-static snd_kcontrol_new_t si3054_modem_mixer[] = {
+static struct snd_kcontrol_new si3054_modem_mixer[] = {
 	SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH),
 	SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID),
 	{}
@@ -158,7 +158,7 @@
 			      struct hda_codec *codec,
 			      unsigned int stream_tag,
 			      unsigned int format,
-			      snd_pcm_substream_t *substream)
+			      struct snd_pcm_substream *substream)
 {
 	u16 val;
 
@@ -175,10 +175,10 @@
 
 static int si3054_pcm_open(struct hda_pcm_stream *hinfo,
 			   struct hda_codec *codec,
-			    snd_pcm_substream_t *substream)
+			    struct snd_pcm_substream *substream)
 {
 	static unsigned int rates[] = { 8000, 9600, 16000 };
-	static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+	static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 		.count = ARRAY_SIZE(rates),
 		.list = rates,
 		.mask = 0,
@@ -295,6 +295,7 @@
  * patch entries
  */
 struct hda_codec_preset snd_hda_preset_si3054[] = {
+ 	{ .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 },
  	{ .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 },
 	{}
 };
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 33a8ada..6190384 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4,7 +4,7 @@
  * HD audio interface patch for SigmaTel STAC92xx
  *
  * Copyright (c) 2005 Embedded Alley Solutions, Inc.
- * <matt@embeddedalley.com>
+ * Matt Porter <mporter@embeddedalley.com>
  *
  * Based on patch_cmedia.c and patch_realtek.c
  * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
@@ -34,17 +34,22 @@
 #include "hda_codec.h"
 #include "hda_local.h"
 
-#undef STAC_TEST
-
 #define NUM_CONTROL_ALLOC	32
 #define STAC_HP_EVENT		0x37
 #define STAC_UNSOL_ENABLE 	(AC_USRSP_EN | STAC_HP_EVENT)
 
+#define STAC_REF		0
+#define STAC_D945GTP3		1
+#define STAC_D945GTP5		2
+
 struct sigmatel_spec {
-	snd_kcontrol_new_t *mixers[4];
+	struct snd_kcontrol_new *mixers[4];
 	unsigned int num_mixers;
 
+	int board_config;
 	unsigned int surr_switch: 1;
+	unsigned int line_switch: 1;
+	unsigned int mic_switch: 1;
 
 	/* playback */
 	struct hda_multi_out multiout;
@@ -57,31 +62,28 @@
 	unsigned int num_muxes;
 	hda_nid_t dig_in_nid;
 
-#ifdef STAC_TEST
 	/* pin widgets */
 	hda_nid_t *pin_nids;
 	unsigned int num_pins;
 	unsigned int *pin_configs;
-#endif
 
 	/* codec specific stuff */
 	struct hda_verb *init;
-	snd_kcontrol_new_t *mixer;
+	struct snd_kcontrol_new *mixer;
 
 	/* capture source */
 	struct hda_input_mux *input_mux;
 	unsigned int cur_mux[2];
 
-	/* channel mode */
-	unsigned int num_ch_modes;
-	unsigned int cur_ch_mode;
+	/* i/o switches */
+	unsigned int io_switch[2];
 
 	struct hda_pcm pcm_rec[2];	/* PCM information */
 
 	/* dynamic controls and input_mux */
 	struct auto_pin_cfg autocfg;
 	unsigned int num_kctl_alloc, num_kctl_used;
-	snd_kcontrol_new_t *kctl_alloc;
+	struct snd_kcontrol_new *kctl_alloc;
 	struct hda_input_mux private_imux;
 };
 
@@ -105,7 +107,6 @@
         0x12, 0x13,
 };
 
-#ifdef STAC_TEST
 static hda_nid_t stac9200_pin_nids[8] = {
 	0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
 };
@@ -114,16 +115,15 @@
 	0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
 	0x0f, 0x10, 0x11, 0x15, 0x1b,
 };
-#endif
 
-static int stac92xx_mux_enum_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct sigmatel_spec *spec = codec->spec;
 	return snd_hda_input_mux_info(spec->input_mux, uinfo);
 }
 
-static int stac92xx_mux_enum_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int stac92xx_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct sigmatel_spec *spec = codec->spec;
@@ -133,7 +133,7 @@
 	return 0;
 }
 
-static int stac92xx_mux_enum_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct sigmatel_spec *spec = codec->spec;
@@ -155,50 +155,7 @@
 	{}
 };
 
-static int stac922x_channel_modes[3] = {2, 6, 8};
-
-static int stac922x_ch_mode_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct sigmatel_spec *spec = codec->spec;
-
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
-	uinfo->value.enumerated.items = spec->num_ch_modes;
-	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
-		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
-	sprintf(uinfo->value.enumerated.name, "%dch",
-		stac922x_channel_modes[uinfo->value.enumerated.item]);
-	return 0;
-}
-
-static int stac922x_ch_mode_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct sigmatel_spec *spec = codec->spec;
-
-	ucontrol->value.enumerated.item[0] = spec->cur_ch_mode;
-	return 0;
-}
-
-static int stac922x_ch_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
-{
-	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct sigmatel_spec *spec = codec->spec;
-
-	if (ucontrol->value.enumerated.item[0] >= spec->num_ch_modes)
-		ucontrol->value.enumerated.item[0] = spec->num_ch_modes;
-	if (ucontrol->value.enumerated.item[0] == spec->cur_ch_mode &&
-	    ! codec->in_resume)
-		return 0;
-
-	spec->cur_ch_mode = ucontrol->value.enumerated.item[0];
-	spec->multiout.max_channels = stac922x_channel_modes[spec->cur_ch_mode];
-
-	return 1;
-}
-
-static snd_kcontrol_new_t stac9200_mixer[] = {
+static struct snd_kcontrol_new stac9200_mixer[] = {
 	HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT),
 	{
@@ -216,7 +173,7 @@
 };
 
 /* This needs to be generated dynamically based on sequence */
-static snd_kcontrol_new_t stac922x_mixer[] = {
+static struct snd_kcontrol_new stac922x_mixer[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Input Source",
@@ -226,22 +183,10 @@
 		.put = stac92xx_mux_enum_put,
 	},
 	HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_INPUT),
-	HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mux Capture Volume", 0x12, 0x0, HDA_OUTPUT),
 	{ } /* end */
 };
 
-static snd_kcontrol_new_t stac922x_ch_mode_mixer[] = {
-	{
-		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Channel Mode",
-		.info = stac922x_ch_mode_info,
-		.get = stac922x_ch_mode_get,
-		.put = stac922x_ch_mode_put,
-	},
-	{ } /* end */
-};
-
 static int stac92xx_build_controls(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec = codec->spec;
@@ -258,11 +203,6 @@
 			return err;
 	}
 
-	if (spec->surr_switch) {
-		err = snd_hda_add_new_ctls(codec, stac922x_ch_mode_mixer);
-		if (err < 0)
-			return err;
-	}
 	if (spec->multiout.dig_out_nid) {
 		err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
 		if (err < 0)
@@ -276,18 +216,67 @@
 	return 0;	
 }
 
-#ifdef STAC_TEST
-static unsigned int stac9200_pin_configs[8] = {
+static unsigned int ref9200_pin_configs[8] = {
 	0x01c47010, 0x01447010, 0x0221401f, 0x01114010,
 	0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
 };
 
-static unsigned int stac922x_pin_configs[10] = {
-	0x01014010, 0x01014011, 0x01014012, 0x0221401f,
-	0x01813122, 0x01014014, 0x01441030, 0x01c41030,
+static unsigned int *stac9200_brd_tbl[] = {
+	ref9200_pin_configs,
+};
+
+static struct hda_board_config stac9200_cfg_tbl[] = {
+	{ .modelname = "ref",
+	  .pci_subvendor = PCI_VENDOR_ID_INTEL,
+	  .pci_subdevice = 0x2668,	/* DFI LanParty */
+	  .config = STAC_REF },
+	{} /* terminator */
+};
+
+static unsigned int ref922x_pin_configs[10] = {
+	0x01014010, 0x01016011, 0x01012012, 0x0221401f,
+	0x01813122, 0x01011014, 0x01441030, 0x01c41030,
 	0x40000100, 0x40000100,
 };
 
+static unsigned int d945gtp3_pin_configs[10] = {
+	0x0221401f, 0x01a19022, 0x01813021, 0x01114010,
+	0x40000100, 0x40000100, 0x40000100, 0x40000100,
+	0x02a19120, 0x40000100,
+};
+
+static unsigned int d945gtp5_pin_configs[10] = {
+	0x0221401f, 0x01111012, 0x01813024, 0x01114010,
+	0x01a19021, 0x01116011, 0x01452130, 0x40000100,
+	0x02a19320, 0x40000100,
+};
+
+static unsigned int *stac922x_brd_tbl[] = {
+	ref922x_pin_configs,
+	d945gtp3_pin_configs,
+	d945gtp5_pin_configs,
+};
+
+static struct hda_board_config stac922x_cfg_tbl[] = {
+	{ .modelname = "ref",
+	  .pci_subvendor = PCI_VENDOR_ID_INTEL,
+	  .pci_subdevice = 0x2668,	/* DFI LanParty */
+	  .config = STAC_REF },		/* SigmaTel reference board */
+	{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
+	  .pci_subdevice = 0x0101,
+	  .config = STAC_D945GTP3 },	/* Intel D945GTP - 3 Stack */
+	{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
+	  .pci_subdevice = 0x0404,
+	  .config = STAC_D945GTP5 },	/* Intel D945GTP - 5 Stack */
+	{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
+	  .pci_subdevice = 0x0303,
+	  .config = STAC_D945GTP5 },	/* Intel D945GNT - 5 Stack */
+	{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
+	  .pci_subdevice = 0x0013,
+	  .config = STAC_D945GTP5 },	/* Intel D955XBK - 5 Stack */
+	{} /* terminator */
+};
+
 static void stac92xx_set_config_regs(struct hda_codec *codec)
 {
 	int i;
@@ -310,86 +299,34 @@
 		pin_cfg = snd_hda_codec_read(codec, spec->pin_nids[i], 0,
 					     AC_VERB_GET_CONFIG_DEFAULT,
 					     0x00);	
-		printk("pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg);
+		snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", spec->pin_nids[i], pin_cfg);
 	}
 }
-#endif
 
 /*
  * Analog playback callbacks
  */
 static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo,
 				      struct hda_codec *codec,
-				      snd_pcm_substream_t *substream)
+				      struct snd_pcm_substream *substream)
 {
 	struct sigmatel_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
 }
 
-/*
- * set up the i/o for analog out
- * when the digital out is available, copy the front out to digital out, too.
- */
-static int stac92xx_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
-				     unsigned int stream_tag,
-				     unsigned int format,
-				     snd_pcm_substream_t *substream)
-{
-	hda_nid_t *nids = mout->dac_nids;
-	int chs = substream->runtime->channels;
-	int i;
-
-	down(&codec->spdif_mutex);
-	if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
-		if (chs == 2 &&
-		    snd_hda_is_supported_format(codec, mout->dig_out_nid, format) &&
-		    ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) {
-			mout->dig_out_used = HDA_DIG_ANALOG_DUP;
-			/* setup digital receiver */
-			snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
-						   stream_tag, 0, format);
-		} else {
-			mout->dig_out_used = 0;
-			snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0);
-		}
-	}
-	up(&codec->spdif_mutex);
-
-	/* front */
-	snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format);
-	if (mout->hp_nid)
-		/* headphone out will just decode front left/right (stereo) */
-		snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format);
-	/* surrounds */
-	if (mout->max_channels > 2)
-		for (i = 1; i < mout->num_dacs; i++) {
-			if ((mout->max_channels == 6) && (i == 3))
-				break;
-			if (chs >= (i + 1) * 2) /* independent out */
-				snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2,
-						format);
-			else /* copy front */
-				snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0,
-						format);
-		}
-	return 0;
-}
-
-
 static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 					 struct hda_codec *codec,
 					 unsigned int stream_tag,
 					 unsigned int format,
-					 snd_pcm_substream_t *substream)
+					 struct snd_pcm_substream *substream)
 {
 	struct sigmatel_spec *spec = codec->spec;
-	return stac92xx_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
-						format, substream);
+	return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, format, substream);
 }
 
 static int stac92xx_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 					struct hda_codec *codec,
-					snd_pcm_substream_t *substream)
+					struct snd_pcm_substream *substream)
 {
 	struct sigmatel_spec *spec = codec->spec;
 	return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
@@ -400,7 +337,7 @@
  */
 static int stac92xx_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 					  struct hda_codec *codec,
-					  snd_pcm_substream_t *substream)
+					  struct snd_pcm_substream *substream)
 {
 	struct sigmatel_spec *spec = codec->spec;
 	return snd_hda_multi_out_dig_open(codec, &spec->multiout);
@@ -408,7 +345,7 @@
 
 static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 					   struct hda_codec *codec,
-					   snd_pcm_substream_t *substream)
+					   struct snd_pcm_substream *substream)
 {
 	struct sigmatel_spec *spec = codec->spec;
 	return snd_hda_multi_out_dig_close(codec, &spec->multiout);
@@ -422,7 +359,7 @@
 					struct hda_codec *codec,
 					unsigned int stream_tag,
 					unsigned int format,
-					snd_pcm_substream_t *substream)
+					struct snd_pcm_substream *substream)
 {
 	struct sigmatel_spec *spec = codec->spec;
 
@@ -433,7 +370,7 @@
 
 static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 					struct hda_codec *codec,
-					snd_pcm_substream_t *substream)
+					struct snd_pcm_substream *substream)
 {
 	struct sigmatel_spec *spec = codec->spec;
 
@@ -511,20 +448,76 @@
 	return 0;
 }
 
+static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
+
+{
+	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
+}
+
+static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct sigmatel_spec *spec = codec->spec;
+	int io_idx = kcontrol-> private_value & 0xff;
+
+	ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
+	return 0;
+}
+
+static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct sigmatel_spec *spec = codec->spec;
+        hda_nid_t nid = kcontrol->private_value >> 8;
+	int io_idx = kcontrol-> private_value & 0xff;
+        unsigned short val = ucontrol->value.integer.value[0];
+
+	spec->io_switch[io_idx] = val;
+
+	if (val)
+		stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_OUT_EN);
+	else
+		stac92xx_auto_set_pinctl(codec, nid, AC_PINCTL_IN_EN);
+
+        return 1;
+}
+
+#define STAC_CODEC_IO_SWITCH(xname, xpval) \
+	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+	  .name = xname, \
+	  .index = 0, \
+          .info = stac92xx_io_switch_info, \
+          .get = stac92xx_io_switch_get, \
+          .put = stac92xx_io_switch_put, \
+          .private_value = xpval, \
+	}
+
+
 enum {
 	STAC_CTL_WIDGET_VOL,
 	STAC_CTL_WIDGET_MUTE,
+	STAC_CTL_WIDGET_IO_SWITCH,
 };
 
-static snd_kcontrol_new_t stac92xx_control_templates[] = {
+static struct snd_kcontrol_new stac92xx_control_templates[] = {
 	HDA_CODEC_VOLUME(NULL, 0, 0, 0),
 	HDA_CODEC_MUTE(NULL, 0, 0, 0),
+	STAC_CODEC_IO_SWITCH(NULL, 0),
 };
 
 /* add dynamic controls */
 static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val)
 {
-	snd_kcontrol_new_t *knew;
+	struct snd_kcontrol_new *knew;
 
 	if (spec->num_kctl_used >= spec->num_kctl_alloc) {
 		int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
@@ -550,6 +543,51 @@
 	return 0;
 }
 
+/* flag inputs as additional dynamic lineouts */
+static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
+{
+	struct sigmatel_spec *spec = codec->spec;
+
+	switch (cfg->line_outs) {
+	case 3:
+		/* add line-in as side */
+		if (cfg->input_pins[AUTO_PIN_LINE]) {
+			cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE];
+			spec->line_switch = 1;
+			cfg->line_outs++;
+		}
+		break;
+	case 2:
+		/* add line-in as clfe and mic as side */
+		if (cfg->input_pins[AUTO_PIN_LINE]) {
+			cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE];
+			spec->line_switch = 1;
+			cfg->line_outs++;
+		}
+		if (cfg->input_pins[AUTO_PIN_MIC]) {
+			cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC];
+			spec->mic_switch = 1;
+			cfg->line_outs++;
+		}
+		break;
+	case 1:
+		/* add line-in as surr and mic as clfe */
+		if (cfg->input_pins[AUTO_PIN_LINE]) {
+			cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE];
+			spec->line_switch = 1;
+			cfg->line_outs++;
+		}
+		if (cfg->input_pins[AUTO_PIN_MIC]) {
+			cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC];
+			spec->mic_switch = 1;
+			cfg->line_outs++;
+		}
+		break;
+	}
+
+	return 0;
+}
+
 /* fill in the dac_nids table from the parsed pin configuration */
 static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
 {
@@ -578,7 +616,7 @@
 	int i, err;
 
 	for (i = 0; i < cfg->line_outs; i++) {
-		if (! spec->multiout.dac_nids[i])
+		if (!spec->multiout.dac_nids[i])
 			continue;
 
 		nid = spec->multiout.dac_nids[i];
@@ -609,6 +647,14 @@
 		}
 	}
 
+	if (spec->line_switch)
+		if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Line In as Output Switch", cfg->input_pins[AUTO_PIN_LINE] << 8)) < 0)
+			return err;
+
+	if (spec->mic_switch)
+		if ((err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, "Mic as Output Switch", (cfg->input_pins[AUTO_PIN_MIC] << 8) | 1)) < 0)
+			return err;
+
 	return 0;
 }
 
@@ -624,7 +670,7 @@
 	if (! pin)
 		return 0;
 
-	wid_caps = snd_hda_param_read(codec, pin, AC_PAR_AUDIO_WIDGET_CAP);
+	wid_caps = get_wcaps(codec, pin);
 	if (wid_caps & AC_WCAP_UNSOL_CAP)
 		/* Enable unsolicited responses on the HP widget */
 		snd_hda_codec_write(codec, pin, 0,
@@ -656,9 +702,6 @@
 static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
 {
 	struct sigmatel_spec *spec = codec->spec;
-	static char *labels[AUTO_PIN_LAST] = {
-		"Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
-	};
 	struct hda_input_mux *imux = &spec->private_imux;
 	hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
 	int i, j, k;
@@ -666,7 +709,10 @@
 	for (i = 0; i < AUTO_PIN_LAST; i++) {
 		int index = -1;
 		if (cfg->input_pins[i]) {
-			imux->items[imux->num_items].label = labels[i];
+			/* Enable active pin widget as an input */
+			stac92xx_auto_set_pinctl(codec, cfg->input_pins[i], AC_PINCTL_IN_EN);
+
+			imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
 
 			for (j=0; j<spec->num_muxes; j++) {
 				int num_cons = snd_hda_get_connections(codec, spec->mux_nids[j], con_lst, HDA_MAX_NUM_INPUTS);
@@ -686,12 +732,6 @@
 	return 0;
 }
 
-static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
-
-{
-	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
-}
-
 static void stac92xx_auto_init_multi_out(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec = codec->spec;
@@ -718,7 +758,9 @@
 	struct sigmatel_spec *spec = codec->spec;
 	int err;
 
-	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0)
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
+		return err;
+	if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
 		return err;
 	if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
 		return err;
@@ -731,15 +773,8 @@
 		return err;
 
 	spec->multiout.max_channels = spec->multiout.num_dacs * 2;
-	if (spec->multiout.max_channels > 2) {
+	if (spec->multiout.max_channels > 2)
 		spec->surr_switch = 1;
-		spec->cur_ch_mode = 1;
-		spec->num_ch_modes = 2;
-		if (spec->multiout.max_channels == 8) {
-			spec->cur_ch_mode++;
-			spec->num_ch_modes++;
-		}
-	}
 
 	if (spec->autocfg.dig_out_pin) {
 		spec->multiout.dig_out_nid = 0x08;
@@ -763,7 +798,7 @@
 	struct sigmatel_spec *spec = codec->spec;
 	int err;
 
-	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg)) < 0)
+	if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
 		return err;
 
 	if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
@@ -786,33 +821,10 @@
 	return 1;
 }
 
-static int stac92xx_init_pstate(struct hda_codec *codec)
-{
-       hda_nid_t nid, nid_start;
-       int nodes;
-
-	snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_POWER_STATE, 0x00);
-
-       nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
-       for (nid = nid_start; nid < nodes + nid_start; nid++) {
-               unsigned int wid_caps = snd_hda_param_read(codec, nid,
-                                                  AC_PAR_AUDIO_WIDGET_CAP);
-		if (wid_caps & AC_WCAP_POWER)
-			snd_hda_codec_write(codec, nid, 0,
-                                    AC_VERB_SET_POWER_STATE, 0x00);
-	}
-
-	mdelay(100);
-
-	return 0;
-}
-
 static int stac92xx_init(struct hda_codec *codec)
 {
 	struct sigmatel_spec *spec = codec->spec;
 
-	stac92xx_init_pstate(codec);
-
 	snd_hda_sequence_write(codec, spec->init);
 
 	stac92xx_auto_init_multi_out(codec);
@@ -924,13 +936,16 @@
 		return -ENOMEM;
 
 	codec->spec = spec;
+	spec->board_config = snd_hda_check_board_config(codec, stac9200_cfg_tbl);
+	if (spec->board_config < 0)
+                snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
+	else {
+		spec->num_pins = 8;
+		spec->pin_nids = stac9200_pin_nids;
+		spec->pin_configs = stac9200_brd_tbl[spec->board_config];
+		stac92xx_set_config_regs(codec);
+	}
 
-#ifdef STAC_TEST
-	spec->pin_nids = stac9200_pin_nids;
-	spec->num_pins = 8;
-	spec->pin_configs = stac9200_pin_configs;
-	stac92xx_set_config_regs(codec);
-#endif
 	spec->multiout.max_channels = 2;
 	spec->multiout.num_dacs = 1;
 	spec->multiout.dac_nids = stac9200_dac_nids;
@@ -962,13 +977,16 @@
 		return -ENOMEM;
 
 	codec->spec = spec;
+	spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl);
+	if (spec->board_config < 0)
+                snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, using BIOS defaults\n");
+	else {
+		spec->num_pins = 10;
+		spec->pin_nids = stac922x_pin_nids;
+		spec->pin_configs = stac922x_brd_tbl[spec->board_config];
+		stac92xx_set_config_regs(codec);
+	}
 
-#ifdef STAC_TEST
-	spec->num_pins = 10;
-	spec->pin_nids = stac922x_pin_nids;
-	spec->pin_configs = stac922x_pin_configs;
-	stac92xx_set_config_regs(codec);
-#endif
 	spec->adc_nids = stac922x_adc_nids;
 	spec->mux_nids = stac922x_mux_nids;
 	spec->num_muxes = 2;
diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
index ae9dc02..ab00cce 100644
--- a/sound/pci/ice1712/ak4xxx.c
+++ b/sound/pci/ice1712/ak4xxx.c
@@ -34,16 +34,16 @@
 MODULE_DESCRIPTION("ICEnsemble ICE17xx <-> AK4xxx AD/DA chip interface");
 MODULE_LICENSE("GPL");
 
-static void snd_ice1712_akm4xxx_lock(akm4xxx_t *ak, int chip)
+static void snd_ice1712_akm4xxx_lock(struct snd_akm4xxx *ak, int chip)
 {
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 
 	snd_ice1712_save_gpio_status(ice);
 }
 
-static void snd_ice1712_akm4xxx_unlock(akm4xxx_t *ak, int chip)
+static void snd_ice1712_akm4xxx_unlock(struct snd_akm4xxx *ak, int chip)
 {
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 
 	snd_ice1712_restore_gpio_status(ice);
 }
@@ -51,14 +51,14 @@
 /*
  * write AK4xxx register
  */
-static void snd_ice1712_akm4xxx_write(akm4xxx_t *ak, int chip,
+static void snd_ice1712_akm4xxx_write(struct snd_akm4xxx *ak, int chip,
 				      unsigned char addr, unsigned char data)
 {
 	unsigned int tmp;
 	int idx;
 	unsigned int addrdata;
 	struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 
 	snd_assert(chip >= 0 && chip < 4, return);
 
@@ -119,10 +119,10 @@
 }
 
 /*
- * initialize the akm4xxx_t record with the template
+ * initialize the struct snd_akm4xxx record with the template
  */
-int snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *temp,
-			     const struct snd_ak4xxx_private *_priv, ice1712_t *ice)
+int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *temp,
+			     const struct snd_ak4xxx_private *_priv, struct snd_ice1712 *ice)
 {
 	struct snd_ak4xxx_private *priv;
 
@@ -148,13 +148,13 @@
 	return 0;
 }
 
-void snd_ice1712_akm4xxx_free(ice1712_t *ice)
+void snd_ice1712_akm4xxx_free(struct snd_ice1712 *ice)
 {
 	unsigned int akidx;
 	if (ice->akm == NULL)
 		return;
 	for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
-		akm4xxx_t *ak = &ice->akm[akidx];
+		struct snd_akm4xxx *ak = &ice->akm[akidx];
 		kfree((void*)ak->private_value[0]);
 	}
 	kfree(ice->akm);
@@ -163,13 +163,13 @@
 /*
  * build AK4xxx controls
  */
-int snd_ice1712_akm4xxx_build_controls(ice1712_t *ice)
+int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice)
 {
 	unsigned int akidx;
 	int err;
 
 	for (akidx = 0; akidx < ice->akm_codecs; akidx++) {
-		akm4xxx_t *ak = &ice->akm[akidx];
+		struct snd_akm4xxx *ak = &ice->akm[akidx];
 		err = snd_akm4xxx_build_controls(ak);
 		if (err < 0)
 			return err;
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index 289b0b5..59c4078 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -33,14 +33,14 @@
 #include "envy24ht.h"
 #include "amp.h"
 
-static void wm_put(ice1712_t *ice, int reg, unsigned short val)
+static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
 {
 	unsigned short cval;
 	cval = (reg << 9) | val;
 	snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
 }
 
-static int __devinit snd_vt1724_amp_init(ice1712_t *ice)
+static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
 {
 	static unsigned short wm_inits[] = {
 		WM_ATTEN_L,	0x0000,	/* 0 db */
@@ -66,7 +66,7 @@
 	return 0;
 }
 
-static int __devinit snd_vt1724_amp_add_controls(ice1712_t *ice)
+static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
 {
 	/* we use pins 39 and 41 of the VT1616 for left and right read outputs */
 	snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index db12b03..8809812 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -22,7 +22,7 @@
  *
  * NOTES:
  *
- * - we reuse the akm4xxx_t record for storing the wm8770 codec data.
+ * - we reuse the struct snd_akm4xxx record for storing the wm8770 codec data.
  *   both wm and akm codecs are pretty similar, so we can integrate
  *   both controls in the future, once if wm codecs are reused in
  *   many boards.
@@ -85,7 +85,7 @@
 #define CS8415_C_BUFFER	0x20
 #define CS8415_ID		0x7F
 
-static void aureon_ac97_write(ice1712_t *ice, unsigned short reg, unsigned short val) {
+static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, unsigned short val) {
 	unsigned int tmp;
 
 	/* Send address to XILINX chip */
@@ -136,7 +136,7 @@
 	ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val;
 }
 
-static unsigned short aureon_ac97_read(ice1712_t *ice, unsigned short reg)
+static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
 {
        return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1];
 }
@@ -144,7 +144,7 @@
 /*
  * Initialize STAC9744 chip
  */
-static int aureon_ac97_init (ice1712_t *ice) {
+static int aureon_ac97_init (struct snd_ice1712 *ice) {
 	int i;
 	static unsigned short ac97_defaults[] = {
 		0x00, 0x9640,
@@ -196,7 +196,7 @@
 /*
  * AC'97 volume controls
  */
-static int aureon_ac97_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int aureon_ac97_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = kcontrol->private_value & AUREON_AC97_STEREO ? 2 : 1;
@@ -205,9 +205,9 @@
 	return 0;
 }
 
-static int aureon_ac97_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_ac97_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short vol;
 
 	down(&ice->gpio_mutex);
@@ -221,9 +221,9 @@
 	return 0;
 }
 
-static int aureon_ac97_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short ovol, nvol;
 	int change;
 	
@@ -248,9 +248,9 @@
  */
 #define aureon_ac97_mute_info	aureon_mono_bool_info
 
-static int aureon_ac97_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	down(&ice->gpio_mutex);
 
@@ -260,9 +260,9 @@
 	return 0;
 }
 
-static int aureon_ac97_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short ovol, nvol;
 	int change;
 
@@ -284,9 +284,9 @@
  */
 #define aureon_ac97_micboost_info	aureon_mono_bool_info
 
-static int aureon_ac97_micboost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_ac97_micboost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	down(&ice->gpio_mutex);
 
@@ -296,9 +296,9 @@
 	return 0;
 }
 
-static int aureon_ac97_micboost_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short ovol, nvol;
 	int change;
 
@@ -318,7 +318,7 @@
 /*
  * write data in the SPI mode
  */
-static void aureon_spi_write(ice1712_t *ice, unsigned int cs, unsigned int data, int bits)
+static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
 {
 	unsigned int tmp;
 	int i;
@@ -359,7 +359,7 @@
 /*
  * Read data in SPI mode
  */
-static void aureon_spi_read(ice1712_t *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) {
+static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) {
 	int i, j;
 	unsigned int tmp;
 
@@ -409,26 +409,26 @@
 	snd_ice1712_gpio_write(ice, tmp);
 }
 
-static unsigned char aureon_cs8415_get(ice1712_t *ice, int reg) {
+static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg) {
 	unsigned char val;
 	aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
 	aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1);
 	return val;
 }
 
-static void aureon_cs8415_read(ice1712_t *ice, int reg, unsigned char *buffer, int size) {
+static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg, unsigned char *buffer, int size) {
 	aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16);
 	aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size);
 }
 
-static void aureon_cs8415_put(ice1712_t *ice, int reg, unsigned char val) {
+static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg, unsigned char val) {
 	aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24);
 }
 
 /*
  * get the current register value of WM codec
  */
-static unsigned short wm_get(ice1712_t *ice, int reg)
+static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
 {
 	reg <<= 1;
 	return ((unsigned short)ice->akm[0].images[reg] << 8) |
@@ -438,7 +438,7 @@
 /*
  * set the register value of WM codec
  */
-static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
+static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
 {
 	aureon_spi_write(ice, AUREON_WM_CS, (reg << 9) | (val & 0x1ff), 16);
 }
@@ -446,7 +446,7 @@
 /*
  * set the register value of WM codec and remember it
  */
-static void wm_put(ice1712_t *ice, int reg, unsigned short val)
+static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
 {
 	wm_put_nocache(ice, reg, val);
 	reg <<= 1;
@@ -456,7 +456,7 @@
 
 /*
  */
-static int aureon_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+static int aureon_mono_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -470,9 +470,9 @@
  */
 #define aureon_ac97_mmute_info	aureon_mono_bool_info
 
-static int aureon_ac97_mmute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	down(&ice->gpio_mutex);
 
@@ -482,8 +482,8 @@
 	return 0;
 }
 
-static int aureon_ac97_mmute_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short ovol, nvol;
 	int change;
 	
@@ -521,7 +521,7 @@
 #define WM_VOL_MAX	(sizeof(wm_vol) - 1)
 #define WM_VOL_MUTE	0x8000
 
-static void wm_set_vol(ice1712_t *ice, unsigned int index, unsigned short vol, unsigned short master)
+static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
 {
 	unsigned char nvol;
 	
@@ -539,9 +539,9 @@
  */
 #define wm_pcm_mute_info	aureon_mono_bool_info
 
-static int wm_pcm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	down(&ice->gpio_mutex);
 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
@@ -549,9 +549,9 @@
 	return 0;
 }
 
-static int wm_pcm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short nval, oval;
 	int change;
 
@@ -568,7 +568,7 @@
 /*
  * Master volume attenuation mixer control
  */
-static int wm_master_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -577,18 +577,18 @@
 	return 0;
 }
 
-static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i;
 	for (i=0; i<2; i++)
 		ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE;
 	return 0;
 }
 
-static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int ch, change = 0;
 
 	snd_ice1712_save_gpio_status(ice);
@@ -611,7 +611,7 @@
 /*
  * DAC volume attenuation mixer control
  */
-static int wm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int voices = kcontrol->private_value >> 8;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -621,9 +621,9 @@
 	return 0;
 }
 
-static int wm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i, ofs, voices;
 
 	voices = kcontrol->private_value >> 8;
@@ -633,9 +633,9 @@
 	return 0;
 }
 
-static int wm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i, idx, ofs, voices;
 	int change = 0;
 
@@ -659,7 +659,7 @@
 /*
  * WM8770 mute control
  */
-static int wm_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = kcontrol->private_value >> 8;
 	uinfo->value.integer.min = 0;
@@ -667,9 +667,9 @@
 	return 0;
 }
 
-static int wm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int voices, ofs, i;
 	
 	voices = kcontrol->private_value >> 8;
@@ -680,9 +680,9 @@
 	return 0;
 }
 
-static int wm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change = 0, voices, ofs, i;
 
 	voices = kcontrol->private_value >> 8;
@@ -708,7 +708,7 @@
 /*
  * WM8770 master mute control
  */
-static int wm_master_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+static int wm_master_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
 	uinfo->value.integer.min = 0;
@@ -716,18 +716,18 @@
 	return 0;
 }
 
-static int wm_master_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1;
 	ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1;
 	return 0;
 }
 
-static int wm_master_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change = 0, i;
 
 	snd_ice1712_save_gpio_status(ice);
@@ -754,7 +754,7 @@
 #define PCM_0dB 0xff
 #define PCM_RES 128	/* -64dB */
 #define PCM_MIN (PCM_0dB - PCM_RES)
-static int wm_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -763,9 +763,9 @@
 	return 0;
 }
 
-static int wm_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	down(&ice->gpio_mutex);
@@ -776,9 +776,9 @@
 	return 0;
 }
 
-static int wm_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short ovol, nvol;
 	int change = 0;
 
@@ -798,7 +798,7 @@
 /*
  * ADC mute control
  */
-static int wm_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_adc_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -807,9 +807,9 @@
 	return 0;
 }
 
-static int wm_adc_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 	int i;
 
@@ -822,9 +822,9 @@
 	return 0;
 }
 
-static int wm_adc_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int wm_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short new, old;
 	int i, change = 0;
 
@@ -845,7 +845,7 @@
 /*
  * ADC gain mixer control
  */
-static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -854,9 +854,9 @@
 	return 0;
 }
 
-static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i, idx;
 	unsigned short vol;
 
@@ -870,9 +870,9 @@
 	return 0;
 }
 
-static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i, idx;
 	unsigned short ovol, nvol;
 	int change = 0;
@@ -894,7 +894,7 @@
 /*
  * ADC input mux mixer control
  */
-static int wm_adc_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {
 		"CD",		//AIN1
@@ -913,7 +913,7 @@
 		"Aux3",		//AIN7
 		"AC97"		//AIN8
 	};
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 2;
@@ -932,9 +932,9 @@
 	return 0;
 }
 
-static int wm_adc_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	down(&ice->gpio_mutex);
@@ -945,9 +945,9 @@
 	return 0;
 }
 
-static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short oval, nval;
 	int change;
 
@@ -966,9 +966,9 @@
 /*
  * CS8415 Input mux
  */
-static int aureon_cs8415_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	static char *aureon_texts[] = {
 		"CD",		//RXP0
 		"Optical"	//RXP1
@@ -989,9 +989,9 @@
 	return 0;
 }
 
-static int aureon_cs8415_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	//snd_ice1712_save_gpio_status(ice);
 	//val = aureon_cs8415_get(ice, CS8415_CTRL2);
@@ -1000,9 +1000,9 @@
 	return 0;
 }
 
-static int aureon_cs8415_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short oval, nval;
 	int change;
 
@@ -1018,7 +1018,7 @@
 	return change;
 }
 
-static int aureon_cs8415_rate_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -1027,9 +1027,9 @@
 	return 0;
 }
 
-static int aureon_cs8415_rate_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char ratio;
 	ratio = aureon_cs8415_get(ice, CS8415_RATIO);
 	ucontrol->value.integer.value[0] = (int)((unsigned int)ratio * 750);
@@ -1039,25 +1039,25 @@
 /*
  * CS8415A Mute
  */
-static int aureon_cs8415_mute_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int aureon_cs8415_mute_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int aureon_cs8415_mute_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	snd_ice1712_save_gpio_status(ice);
 	ucontrol->value.integer.value[0] = (aureon_cs8415_get(ice, CS8415_CTRL1) & 0x20) ? 0 : 1;
 	snd_ice1712_restore_gpio_status(ice);
 	return 0;
 }
 
-static int aureon_cs8415_mute_put (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char oval, nval;
 	int change;
 	snd_ice1712_save_gpio_status(ice);
@@ -1075,14 +1075,14 @@
 /*
  * CS8415A Q-Sub info
  */
-static int aureon_cs8415_qsub_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+static int aureon_cs8415_qsub_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
 	uinfo->count = 10;
 	return 0;
 }
 
-static int aureon_cs8415_qsub_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	
 	snd_ice1712_save_gpio_status(ice);
 	aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10);
@@ -1091,19 +1091,19 @@
 	return 0;
 }
 
-static int aureon_cs8415_spdif_info (snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+static int aureon_cs8415_spdif_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int aureon_cs8415_mask_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
+static int aureon_cs8415_mask_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
 	memset(ucontrol->value.iec958.status, 0xFF, 24);
 	return 0;
 }
 
-static int aureon_cs8415_spdif_get (snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+static int aureon_cs8415_spdif_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) {
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	snd_ice1712_save_gpio_status(ice);
 	aureon_cs8415_read(ice, CS8415_C_BUFFER, ucontrol->value.iec958.status, 24);
@@ -1114,7 +1114,7 @@
 /*
  * Headphone Amplifier
  */
-static int aureon_set_headphone_amp(ice1712_t *ice, int enable)
+static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
 {
 	unsigned int tmp, tmp2;
 
@@ -1130,7 +1130,7 @@
 	return 0;
 }
 
-static int aureon_get_headphone_amp(ice1712_t *ice)
+static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
 {
 	unsigned int tmp = snd_ice1712_gpio_read(ice);
 
@@ -1139,18 +1139,18 @@
 
 #define aureon_hpamp_info	aureon_mono_bool_info
 
-static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
 	return 0;
 }
 
 
-static int aureon_hpamp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
 }
@@ -1161,16 +1161,16 @@
 
 #define aureon_deemp_info	aureon_mono_bool_info
 
-static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
 	return 0;
 }
 
-static int aureon_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int temp, temp2;
 	temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
 	if (ucontrol->value.integer.value[0])
@@ -1187,7 +1187,7 @@
 /*
  * ADC Oversampling
  */
-static int aureon_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = { "128x", "64x"	};
 
@@ -1202,17 +1202,17 @@
         return 0;
 }
 
-static int aureon_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
 	return 0;
 }
 
-static int aureon_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	int temp, temp2;
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	temp2 = temp = wm_get(ice, WM_MASTER);
 
@@ -1232,7 +1232,7 @@
  * mixers
  */
 
-static snd_kcontrol_new_t aureon_dac_controls[] __devinitdata = {
+static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -1329,7 +1329,7 @@
 	}
 };
 
-static snd_kcontrol_new_t wm_controls[] __devinitdata = {
+static struct snd_kcontrol_new wm_controls[] __devinitdata = {
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "PCM Playback Switch",
@@ -1389,7 +1389,7 @@
 	}
 };
 
-static snd_kcontrol_new_t ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "AC97 Playback Switch",
@@ -1479,7 +1479,7 @@
  	}
 };
 
-static snd_kcontrol_new_t universe_ac97_controls[] __devinitdata = {
+static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
  	{
  		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "AC97 Playback Switch",
@@ -1586,7 +1586,7 @@
 };
 
 	
-static snd_kcontrol_new_t cs8415_controls[] __devinitdata = {
+static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
@@ -1632,7 +1632,7 @@
 };
 
  
-static int __devinit aureon_add_controls(ice1712_t *ice)
+static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i, counts;
 	int err;
@@ -1677,7 +1677,7 @@
 			snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1));
 		else {
 			for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) {
-				snd_kcontrol_t *kctl;
+				struct snd_kcontrol *kctl;
 				err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice)));
 				if (err < 0)
 					return err;
@@ -1695,7 +1695,7 @@
 /*
  * initialize the chip
  */
-static int __devinit aureon_init(ice1712_t *ice)
+static int __devinit aureon_init(struct snd_ice1712 *ice)
 {
 	static unsigned short wm_inits_aureon[] = {
 		/* These come first to reduce init pop noise */
@@ -1796,7 +1796,7 @@
 	}
 
 	/* to remeber the register values of CS8415 */
-	ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (! ice->akm)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 576f69d..9a51d34 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -44,7 +44,7 @@
  */
 
 /* send 8 bits */
-static void ap_cs8427_write_byte(ice1712_t *ice, unsigned char data, unsigned char tmp)
+static void ap_cs8427_write_byte(struct snd_ice1712 *ice, unsigned char data, unsigned char tmp)
 {
 	int idx;
 
@@ -61,7 +61,7 @@
 }
 
 /* read 8 bits */
-static unsigned char ap_cs8427_read_byte(ice1712_t *ice, unsigned char tmp)
+static unsigned char ap_cs8427_read_byte(struct snd_ice1712 *ice, unsigned char tmp)
 {
 	unsigned char data = 0;
 	int idx;
@@ -80,7 +80,7 @@
 }
 
 /* assert chip select */
-static unsigned char ap_cs8427_codec_select(ice1712_t *ice)
+static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)
 {
 	unsigned char tmp;
 	tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
@@ -105,7 +105,7 @@
 }
 
 /* deassert chip select */
-static void ap_cs8427_codec_deassert(ice1712_t *ice, unsigned char tmp)
+static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp)
 {
 	switch (ice->eeprom.subvendor) {
 	case ICE1712_SUBDEVICE_DELTA1010LT:
@@ -124,9 +124,9 @@
 }
 
 /* sequential write */
-static int ap_cs8427_sendbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
+static int ap_cs8427_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
 {
-	ice1712_t *ice = device->bus->private_data;
+	struct snd_ice1712 *ice = device->bus->private_data;
 	int res = count;
 	unsigned char tmp;
 
@@ -141,9 +141,9 @@
 }
 
 /* sequential read */
-static int ap_cs8427_readbytes(snd_i2c_device_t *device, unsigned char *bytes, int count)
+static int ap_cs8427_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
 {
-	ice1712_t *ice = device->bus->private_data;
+	struct snd_ice1712 *ice = device->bus->private_data;
 	int res = count;
 	unsigned char tmp;
 	
@@ -157,14 +157,14 @@
 	return res;
 }
 
-static int ap_cs8427_probeaddr(snd_i2c_bus_t *bus, unsigned short addr)
+static int ap_cs8427_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
 {
 	if (addr == 0x10)
 		return 1;
 	return -ENOENT;
 }
 
-static snd_i2c_ops_t ap_cs8427_i2c_ops = {
+static struct snd_i2c_ops ap_cs8427_i2c_ops = {
 	.sendbytes = ap_cs8427_sendbytes,
 	.readbytes = ap_cs8427_readbytes,
 	.probeaddr = ap_cs8427_probeaddr,
@@ -173,7 +173,7 @@
 /*
  */
 
-static void snd_ice1712_delta_cs8403_spdif_write(ice1712_t *ice, unsigned char bits)
+static void snd_ice1712_delta_cs8403_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
 {
 	unsigned char tmp, mask1, mask2;
 	int idx;
@@ -198,12 +198,12 @@
 }
 
 
-static void delta_spdif_default_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
+static void delta_spdif_default_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
 {
 	snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
 }
 
-static int delta_spdif_default_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
+static int delta_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned int val;
 	int change;
@@ -221,12 +221,12 @@
 	return change;
 }
 
-static void delta_spdif_stream_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
+static void delta_spdif_stream_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
 {
 	snd_cs8403_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
 }
 
-static int delta_spdif_stream_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
+static int delta_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned int val;
 	int change;
@@ -248,10 +248,10 @@
 /*
  * AK4524 on Delta 44 and 66 to choose the chip mask
  */
-static void delta_ak4524_lock(akm4xxx_t *ak, int chip)
+static void delta_ak4524_lock(struct snd_akm4xxx *ak, int chip)
 {
         struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
-        ice1712_t *ice = ak->private_data[0];
+        struct snd_ice1712 *ice = ak->private_data[0];
 
 	snd_ice1712_save_gpio_status(ice);
 	priv->cs_mask =
@@ -262,10 +262,10 @@
 /*
  * AK4524 on Delta1010LT to choose the chip address
  */
-static void delta1010lt_ak4524_lock(akm4xxx_t *ak, int chip)
+static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
 {
         struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
-        ice1712_t *ice = ak->private_data[0];
+        struct snd_ice1712 *ice = ak->private_data[0];
 
 	snd_ice1712_save_gpio_status(ice);
 	priv->cs_mask = ICE1712_DELTA_1010LT_CS;
@@ -275,10 +275,10 @@
 /*
  * AK4528 on VX442 to choose the chip mask
  */
-static void vx442_ak4524_lock(akm4xxx_t *ak, int chip)
+static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip)
 {
         struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
-        ice1712_t *ice = ak->private_data[0];
+        struct snd_ice1712 *ice = ak->private_data[0];
 
 	snd_ice1712_save_gpio_status(ice);
 	priv->cs_mask =
@@ -289,7 +289,7 @@
 /*
  * change the DFS bit according rate for Delta1010
  */
-static void delta_1010_set_rate_val(ice1712_t *ice, unsigned int rate)
+static void delta_1010_set_rate_val(struct snd_ice1712 *ice, unsigned int rate)
 {
 	unsigned char tmp, tmp2;
 
@@ -309,10 +309,10 @@
 /*
  * change the rate of AK4524 on Delta 44/66, AP, 1010LT
  */
-static void delta_ak4524_set_rate_val(akm4xxx_t *ak, unsigned int rate)
+static void delta_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
 {
 	unsigned char tmp, tmp2;
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 
 	if (rate == 0)	/* no hint - S/PDIF input is master, simply return */
 		return;
@@ -341,7 +341,7 @@
 /*
  * change the rate of AK4524 on VX442
  */
-static void vx442_ak4524_set_rate_val(akm4xxx_t *ak, unsigned int rate)
+static void vx442_ak4524_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
 {
 	unsigned char val;
 
@@ -361,13 +361,13 @@
  */
 
 /* open callback */
-static void delta_open_spdif(ice1712_t *ice, snd_pcm_substream_t * substream)
+static void delta_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
 {
 	ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
 }
 
 /* set up */
-static void delta_setup_spdif(ice1712_t *ice, int rate)
+static void delta_setup_spdif(struct snd_ice1712 *ice, int rate)
 {
 	unsigned long flags;
 	unsigned int tmp;
@@ -396,7 +396,7 @@
  * initialize the chips on M-Audio cards
  */
 
-static akm4xxx_t akm_audiophile __devinitdata = {
+static struct snd_akm4xxx akm_audiophile __devinitdata = {
 	.type = SND_AK4528,
 	.num_adcs = 2,
 	.num_dacs = 2,
@@ -417,7 +417,7 @@
 	.mask_flags = 0,
 };
 
-static akm4xxx_t akm_delta410 __devinitdata = {
+static struct snd_akm4xxx akm_delta410 __devinitdata = {
 	.type = SND_AK4529,
 	.num_adcs = 2,
 	.num_dacs = 8,
@@ -438,7 +438,7 @@
 	.mask_flags = 0,
 };
 
-static akm4xxx_t akm_delta1010lt __devinitdata = {
+static struct snd_akm4xxx akm_delta1010lt __devinitdata = {
 	.type = SND_AK4524,
 	.num_adcs = 8,
 	.num_dacs = 8,
@@ -460,7 +460,7 @@
 	.mask_flags = 0,
 };
 
-static akm4xxx_t akm_delta44 __devinitdata = {
+static struct snd_akm4xxx akm_delta44 __devinitdata = {
 	.type = SND_AK4524,
 	.num_adcs = 4,
 	.num_dacs = 4,
@@ -482,7 +482,7 @@
 	.mask_flags = 0,
 };
 
-static akm4xxx_t akm_vx442 __devinitdata = {
+static struct snd_akm4xxx akm_vx442 __devinitdata = {
 	.type = SND_AK4524,
 	.num_adcs = 4,
 	.num_dacs = 4,
@@ -504,10 +504,10 @@
 	.mask_flags = 0,
 };
 
-static int __devinit snd_ice1712_delta_init(ice1712_t *ice)
+static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
 {
 	int err;
-	akm4xxx_t *ak;
+	struct snd_akm4xxx *ak;
 
 	/* determine I2C, DACs and ADCs */
 	switch (ice->eeprom.subvendor) {
@@ -582,7 +582,7 @@
 	}
 
 	/* second stage of initialization, analog parts and others */
-	ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+	ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (! ak)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
@@ -617,19 +617,19 @@
  * additional controls for M-Audio cards
  */
 
-static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
-static snd_kcontrol_new_t snd_ice1712_delta1010lt_wordclock_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 1, 0);
-static snd_kcontrol_new_t snd_ice1712_delta1010_wordclock_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
-static snd_kcontrol_new_t snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
-static snd_kcontrol_new_t snd_ice1712_delta_spdif_in_status __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
 ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
 
 
-static int __devinit snd_ice1712_delta_add_controls(ice1712_t *ice)
+static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
 {
 	int err;
 
diff --git a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h
index f787802..b58afcd 100644
--- a/sound/pci/ice1712/envy24ht.h
+++ b/sound/pci/ice1712/envy24ht.h
@@ -209,7 +209,7 @@
 #define VT1724_MT_PDMA1_COUNT		0x76	/* word */
 
 
-unsigned char snd_vt1724_read_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr);
-void snd_vt1724_write_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr, unsigned char data);
+unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, unsigned char dev, unsigned char addr);
+void snd_vt1724_write_i2c(struct snd_ice1712 *ice, unsigned char dev, unsigned char addr, unsigned char data);
 
 #endif /* __SOUND_VT1724_H */
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index c8ec5ca..2c529e7 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -50,9 +50,9 @@
  */
 
 /* send SDA and SCL */
-static void ewx_i2c_setlines(snd_i2c_bus_t *bus, int clk, int data)
+static void ewx_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)
 {
-	ice1712_t *ice = bus->private_data;
+	struct snd_ice1712 *ice = bus->private_data;
 	unsigned char tmp = 0;
 	if (clk)
 		tmp |= ICE1712_EWX2496_SERIAL_CLOCK;
@@ -62,15 +62,15 @@
 	udelay(5);
 }
 
-static int ewx_i2c_getclock(snd_i2c_bus_t *bus)
+static int ewx_i2c_getclock(struct snd_i2c_bus *bus)
 {
-	ice1712_t *ice = bus->private_data;
+	struct snd_ice1712 *ice = bus->private_data;
 	return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA) & ICE1712_EWX2496_SERIAL_CLOCK ? 1 : 0;
 }
 
-static int ewx_i2c_getdata(snd_i2c_bus_t *bus, int ack)
+static int ewx_i2c_getdata(struct snd_i2c_bus *bus, int ack)
 {
-	ice1712_t *ice = bus->private_data;
+	struct snd_ice1712 *ice = bus->private_data;
 	int bit;
 	/* set RW pin to low */
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~ICE1712_EWX2496_RW);
@@ -85,9 +85,9 @@
 	return bit;
 }
 
-static void ewx_i2c_start(snd_i2c_bus_t *bus)
+static void ewx_i2c_start(struct snd_i2c_bus *bus)
 {
-	ice1712_t *ice = bus->private_data;
+	struct snd_ice1712 *ice = bus->private_data;
 	unsigned char mask;
 
 	snd_ice1712_save_gpio_status(ice);
@@ -104,15 +104,15 @@
 	snd_ice1712_gpio_write_bits(ice, mask, mask);
 }
 
-static void ewx_i2c_stop(snd_i2c_bus_t *bus)
+static void ewx_i2c_stop(struct snd_i2c_bus *bus)
 {
-	ice1712_t *ice = bus->private_data;
+	struct snd_ice1712 *ice = bus->private_data;
 	snd_ice1712_restore_gpio_status(ice);
 }
 
-static void ewx_i2c_direction(snd_i2c_bus_t *bus, int clock, int data)
+static void ewx_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)
 {
-	ice1712_t *ice = bus->private_data;
+	struct snd_ice1712 *ice = bus->private_data;
 	unsigned char mask = 0;
 
 	if (clock)
@@ -125,7 +125,7 @@
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~mask);
 }
 
-static snd_i2c_bit_ops_t snd_ice1712_ewx_cs8427_bit_ops = {
+static struct snd_i2c_bit_ops snd_ice1712_ewx_cs8427_bit_ops = {
 	.start = ewx_i2c_start,
 	.stop = ewx_i2c_stop,
 	.direction = ewx_i2c_direction,
@@ -140,7 +140,7 @@
  */
 
 /* AK4524 chip select; address 0x48 bit 0-3 */
-static int snd_ice1712_ews88mt_chip_select(ice1712_t *ice, int chip_mask)
+static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mask)
 {
 	unsigned char data, ndata;
 
@@ -162,9 +162,9 @@
 }
 
 /* start callback for EWS88MT, needs to select a certain chip mask */
-static void ews88mt_ak4524_lock(akm4xxx_t *ak, int chip)
+static void ews88mt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
 {
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 	unsigned char tmp;
 	/* assert AK4524 CS */
 	if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0)
@@ -179,18 +179,18 @@
 }
 
 /* stop callback for EWS88MT, needs to deselect chip mask */
-static void ews88mt_ak4524_unlock(akm4xxx_t *ak, int chip)
+static void ews88mt_ak4524_unlock(struct snd_akm4xxx *ak, int chip)
 {
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 	snd_ice1712_restore_gpio_status(ice);
 	udelay(1);
 	snd_ice1712_ews88mt_chip_select(ice, 0x0f);
 }
 
 /* start callback for EWX24/96 */
-static void ewx2496_ak4524_lock(akm4xxx_t *ak, int chip)
+static void ewx2496_ak4524_lock(struct snd_akm4xxx *ak, int chip)
 {
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 	unsigned char tmp;
 	snd_ice1712_save_gpio_status(ice);
 	tmp =  ICE1712_EWX2496_SERIAL_DATA |
@@ -203,10 +203,10 @@
 }
 
 /* start callback for DMX 6fire */
-static void dmx6fire_ak4524_lock(akm4xxx_t *ak, int chip)
+static void dmx6fire_ak4524_lock(struct snd_akm4xxx *ak, int chip)
 {
 	struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 	unsigned char tmp;
 	snd_ice1712_save_gpio_status(ice);
 	tmp = priv->cs_mask = priv->cs_addr = (1 << chip) & ICE1712_6FIRE_AK4524_CS_MASK;
@@ -222,7 +222,7 @@
  * CS8404 interface on EWS88MT/D
  */
 
-static void snd_ice1712_ews_cs8404_spdif_write(ice1712_t *ice, unsigned char bits)
+static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
 {
 	unsigned char bytes[2];
 
@@ -251,12 +251,12 @@
 /*
  */
 
-static void ews88_spdif_default_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
+static void ews88_spdif_default_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
 {
 	snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_bits);
 }
 
-static int ews88_spdif_default_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
+static int ews88_spdif_default_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned int val;
 	int change;
@@ -274,12 +274,12 @@
 	return change;
 }
 
-static void ews88_spdif_stream_get(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
+static void ews88_spdif_stream_get(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
 {
 	snd_cs8404_decode_spdif_bits(&ucontrol->value.iec958, ice->spdif.cs8403_stream_bits);
 }
 
-static int ews88_spdif_stream_put(ice1712_t *ice, snd_ctl_elem_value_t * ucontrol)
+static int ews88_spdif_stream_put(struct snd_ice1712 *ice, struct snd_ctl_elem_value *ucontrol)
 {
 	unsigned int val;
 	int change;
@@ -299,13 +299,13 @@
 
 
 /* open callback */
-static void ews88_open_spdif(ice1712_t *ice, snd_pcm_substream_t * substream)
+static void ews88_open_spdif(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
 {
 	ice->spdif.cs8403_stream_bits = ice->spdif.cs8403_bits;
 }
 
 /* set up SPDIF for EWS88MT / EWS88D */
-static void ews88_setup_spdif(ice1712_t *ice, int rate)
+static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
 {
 	unsigned long flags;
 	unsigned char tmp;
@@ -332,7 +332,7 @@
 
 /*
  */
-static akm4xxx_t akm_ews88mt __devinitdata = {
+static struct snd_akm4xxx akm_ews88mt __devinitdata = {
 	.num_adcs = 8,
 	.num_dacs = 8,
 	.type = SND_AK4524,
@@ -354,7 +354,7 @@
 	.mask_flags = 0,
 };
 
-static akm4xxx_t akm_ewx2496 __devinitdata = {
+static struct snd_akm4xxx akm_ewx2496 __devinitdata = {
 	.num_adcs = 2,
 	.num_dacs = 2,
 	.type = SND_AK4524,
@@ -375,7 +375,7 @@
 	.mask_flags = 0,
 };
 
-static akm4xxx_t akm_6fire __devinitdata = {
+static struct snd_akm4xxx akm_6fire __devinitdata = {
 	.num_adcs = 6,
 	.num_dacs = 6,
 	.type = SND_AK4524,
@@ -406,12 +406,12 @@
 #define PCF9554_REG_POLARITY   2
 #define PCF9554_REG_CONFIG     3
 
-static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char reg, unsigned char data);
+static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data);
 
-static int __devinit snd_ice1712_ews_init(ice1712_t *ice)
+static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
 {
 	int err;
-	akm4xxx_t *ak;
+	struct snd_akm4xxx *ak;
 
 	/* set the analog DACs */
 	switch (ice->eeprom.subvendor) {
@@ -507,7 +507,7 @@
 	}
 
 	/* analog section */
-	ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+	ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (! ak)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
@@ -536,7 +536,7 @@
  */
 
 /* i/o sensitivity - this callback is shared among other devices, too */
-static int snd_ice1712_ewx_io_sense_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo){
+static int snd_ice1712_ewx_io_sense_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo){
 
 	static char *texts[2] = {
 		"+4dBu", "-10dBV",
@@ -550,9 +550,9 @@
 	return 0;
 }
 
-static int snd_ice1712_ewx_io_sense_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_ewx_io_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char mask = kcontrol->private_value & 0xff;
 	
 	snd_ice1712_save_gpio_status(ice);
@@ -561,9 +561,9 @@
 	return 0;
 }
 
-static int snd_ice1712_ewx_io_sense_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char mask = kcontrol->private_value & 0xff;
 	int val, nval;
 
@@ -578,7 +578,7 @@
 	return val != nval;
 }
 
-static snd_kcontrol_new_t snd_ice1712_ewx2496_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Input Sensitivity Switch",
@@ -602,9 +602,9 @@
  * EWS88MT specific controls
  */
 /* analog output sensitivity;; address 0x48 bit 6 */
-static int snd_ice1712_ews88mt_output_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char data;
 
 	snd_i2c_lock(ice->i2c);
@@ -618,9 +618,9 @@
 }
 
 /* analog output sensitivity;; address 0x48 bit 6 */
-static int snd_ice1712_ews88mt_output_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char data, ndata;
 
 	snd_i2c_lock(ice->i2c);
@@ -638,9 +638,9 @@
 }
 
 /* analog input sensitivity; address 0x46 */
-static int snd_ice1712_ews88mt_input_sense_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	unsigned char data;
 
@@ -657,9 +657,9 @@
 }
 
 /* analog output sensitivity; address 0x46 */
-static int snd_ice1712_ews88mt_input_sense_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	unsigned char data, ndata;
 
@@ -678,7 +678,7 @@
 	return ndata != data;
 }
 
-static snd_kcontrol_new_t snd_ice1712_ews88mt_input_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Input Sensitivity Switch",
 	.info = snd_ice1712_ewx_io_sense_info,
@@ -687,7 +687,7 @@
 	.count = 8,
 };
 
-static snd_kcontrol_new_t snd_ice1712_ews88mt_output_sense __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Output Sensitivity Switch",
 	.info = snd_ice1712_ewx_io_sense_info,
@@ -700,7 +700,7 @@
  * EWS88D specific controls
  */
 
-static int snd_ice1712_ews88d_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ice1712_ews88d_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -709,9 +709,9 @@
 	return 0;
 }
 
-static int snd_ice1712_ews88d_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value >> 8) & 1;
 	unsigned char data[2];
@@ -729,9 +729,9 @@
 	return 0;
 }
 
-static int snd_ice1712_ews88d_control_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value >> 8) & 1;
 	unsigned char data[2], ndata[2];
@@ -769,7 +769,7 @@
   .private_value = xshift | (xinvert << 8),\
 }
 
-static snd_kcontrol_new_t snd_ice1712_ews88d_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
 	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
 	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
 	EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
@@ -782,7 +782,7 @@
  * DMX 6Fire specific controls
  */
 
-static int snd_ice1712_6fire_read_pca(ice1712_t *ice, unsigned char reg)
+static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg)
 {
 	unsigned char byte;
 	snd_i2c_lock(ice->i2c);
@@ -798,7 +798,7 @@
 	return byte;
 }
 
-static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char reg, unsigned char data)
+static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data)
 {
 	unsigned char bytes[2];
 	snd_i2c_lock(ice->i2c);
@@ -812,7 +812,7 @@
 	return 0;
 }
 
-static int snd_ice1712_6fire_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ice1712_6fire_control_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -821,9 +821,9 @@
 	return 0;
 }
 
-static int snd_ice1712_6fire_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_6fire_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value >> 8) & 1;
 	int data;
@@ -837,9 +837,9 @@
 	return 0;
 }
 
-static int snd_ice1712_6fire_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_6fire_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value >> 8) & 1;
 	int data, ndata;
@@ -858,7 +858,7 @@
 	return 0;
 }
 
-static int snd_ice1712_6fire_select_input_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ice1712_6fire_select_input_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = {
 		"Internal", "Front Input", "Rear Input", "Wave Table"
@@ -872,9 +872,9 @@
 	return 0;
 }
      
-static int snd_ice1712_6fire_select_input_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_6fire_select_input_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int data;
 	
 	if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
@@ -883,9 +883,9 @@
 	return 0;
 }
 
-static int snd_ice1712_6fire_select_input_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int data, ndata;
 	
 	if ((data = snd_ice1712_6fire_read_pca(ice, PCF9554_REG_OUTPUT)) < 0)
@@ -909,7 +909,7 @@
   .private_value = xshift | (xinvert << 8),\
 }
 
-static snd_kcontrol_new_t snd_ice1712_6fire_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Analog Input Select",
@@ -917,7 +917,7 @@
 		.get = snd_ice1712_6fire_select_input_get,
 		.put = snd_ice1712_6fire_select_input_put,
 	},
-	DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 0),
+	DMX6FIRE_CONTROL("Front Digital Input Switch", 2, 1),
 	// DMX6FIRE_CONTROL("Master Clock Select", 3, 0),
 	DMX6FIRE_CONTROL("Optical Digital Input Switch", 4, 0),
 	DMX6FIRE_CONTROL("Phono Analog Input Switch", 5, 0),
@@ -925,7 +925,7 @@
 };
 
 
-static int __devinit snd_ice1712_ews_add_controls(ice1712_t *ice)
+static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int idx;
 	int err;
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
index ab5fbd0..3f2f918 100644
--- a/sound/pci/ice1712/hoontech.c
+++ b/sound/pci/ice1712/hoontech.c
@@ -33,7 +33,7 @@
 #include "hoontech.h"
 
 
-static void __devinit snd_ice1712_stdsp24_gpio_write(ice1712_t *ice, unsigned char byte)
+static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
 {
 	byte |= ICE1712_STDSP24_CLOCK_BIT;
 	udelay(100);
@@ -46,7 +46,7 @@
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, byte);
 }
 
-static void __devinit snd_ice1712_stdsp24_darear(ice1712_t *ice, int activate)
+static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
 {
 	down(&ice->gpio_mutex);
 	ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate);
@@ -54,7 +54,7 @@
 	up(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_mute(ice1712_t *ice, int activate)
+static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
 {
 	down(&ice->gpio_mutex);
 	ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate);
@@ -62,7 +62,7 @@
 	up(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_insel(ice1712_t *ice, int activate)
+static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
 {
 	down(&ice->gpio_mutex);
 	ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate);
@@ -70,7 +70,7 @@
 	up(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_box_channel(ice1712_t *ice, int box, int chn, int activate)
+static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
 {
 	down(&ice->gpio_mutex);
 
@@ -118,7 +118,7 @@
 	up(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_box_midi(ice1712_t *ice, int box, int master)
+static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
 {
 	down(&ice->gpio_mutex);
 
@@ -144,7 +144,7 @@
 	up(&ice->gpio_mutex);
 }
 
-static void __devinit snd_ice1712_stdsp24_midi2(ice1712_t *ice, int activate)
+static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
 {
 	down(&ice->gpio_mutex);
 	ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate);
@@ -152,7 +152,7 @@
 	up(&ice->gpio_mutex);
 }
 
-static int __devinit snd_ice1712_hoontech_init(ice1712_t *ice)
+static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
 {
 	int box, chn;
 
@@ -221,9 +221,9 @@
  */
 
 /* start callback for STDSP24 with modified hardware */
-static void stdsp24_ak4524_lock(akm4xxx_t *ak, int chip)
+static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
 {
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 	unsigned char tmp;
 	snd_ice1712_save_gpio_status(ice);
 	tmp =	ICE1712_STDSP24_SERIAL_DATA |
@@ -234,10 +234,10 @@
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ~tmp);
 }
 
-static int __devinit snd_ice1712_value_init(ice1712_t *ice)
+static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
 {
 	/* Hoontech STDSP24 with modified hardware */
-	static akm4xxx_t akm_stdsp24_mv __devinitdata = {
+	static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
 		.num_adcs = 2,
 		.num_dacs = 2,
 		.type = SND_AK4524,
@@ -258,7 +258,7 @@
 	};
 
 	int err;
-	akm4xxx_t *ak;
+	struct snd_akm4xxx *ak;
 
 	/* set the analog DACs */
 	ice->num_total_dacs = 2;
@@ -267,7 +267,7 @@
 	ice->num_total_adcs = 2;
 	
 	/* analog section */
-	ak = ice->akm = kmalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+	ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (! ak)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
@@ -284,7 +284,7 @@
 	return 0;
 }
 
-static int __devinit snd_ice1712_ez8_init(ice1712_t *ice)
+static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice)
 {
 	ice->gpio.write_mask = ice->eeprom.gpiomask;
 	ice->gpio.direction = ice->eeprom.gpiodir;
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index bd71bf4..ef6f185 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -108,8 +108,8 @@
 
 MODULE_DEVICE_TABLE(pci, snd_ice1712_ids);
 
-static int snd_ice1712_build_pro_mixer(ice1712_t *ice);
-static int snd_ice1712_build_controls(ice1712_t *ice);
+static int snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice);
+static int snd_ice1712_build_controls(struct snd_ice1712 *ice);
 
 static int PRO_RATE_LOCKED;
 static int PRO_RATE_RESET = 1;
@@ -120,33 +120,33 @@
  */
  
 /* check whether the clock mode is spdif-in */
-static inline int is_spdif_master(ice1712_t *ice)
+static inline int is_spdif_master(struct snd_ice1712 *ice)
 {
 	return (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER) ? 1 : 0;
 }
 
-static inline int is_pro_rate_locked(ice1712_t *ice)
+static inline int is_pro_rate_locked(struct snd_ice1712 *ice)
 {
 	return is_spdif_master(ice) || PRO_RATE_LOCKED;
 }
 
-static inline void snd_ice1712_ds_write(ice1712_t * ice, u8 channel, u8 addr, u32 data)
+static inline void snd_ice1712_ds_write(struct snd_ice1712 * ice, u8 channel, u8 addr, u32 data)
 {
 	outb((channel << 4) | addr, ICEDS(ice, INDEX));
 	outl(data, ICEDS(ice, DATA));
 }
 
-static inline u32 snd_ice1712_ds_read(ice1712_t * ice, u8 channel, u8 addr)
+static inline u32 snd_ice1712_ds_read(struct snd_ice1712 * ice, u8 channel, u8 addr)
 {
 	outb((channel << 4) | addr, ICEDS(ice, INDEX));
 	return inl(ICEDS(ice, DATA));
 }
 
-static void snd_ice1712_ac97_write(ac97_t *ac97,
+static void snd_ice1712_ac97_write(struct snd_ac97 *ac97,
 				   unsigned short reg,
 				   unsigned short val)
 {
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
+	struct snd_ice1712 *ice = ac97->private_data;
 	int tm;
 	unsigned char old_cmd = 0;
 
@@ -167,10 +167,10 @@
 			break;
 }
 
-static unsigned short snd_ice1712_ac97_read(ac97_t *ac97,
+static unsigned short snd_ice1712_ac97_read(struct snd_ac97 *ac97,
 					    unsigned short reg)
 {
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
+	struct snd_ice1712 *ice = ac97->private_data;
 	int tm;
 	unsigned char old_cmd = 0;
 
@@ -196,11 +196,11 @@
  * pro ac97 section
  */
 
-static void snd_ice1712_pro_ac97_write(ac97_t *ac97,
+static void snd_ice1712_pro_ac97_write(struct snd_ac97 *ac97,
 				       unsigned short reg,
 				       unsigned short val)
 {
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
+	struct snd_ice1712 *ice = ac97->private_data;
 	int tm;
 	unsigned char old_cmd = 0;
 
@@ -222,10 +222,10 @@
 }
 
 
-static unsigned short snd_ice1712_pro_ac97_read(ac97_t *ac97,
+static unsigned short snd_ice1712_pro_ac97_read(struct snd_ac97 *ac97,
 						unsigned short reg)
 {
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
+	struct snd_ice1712 *ice = ac97->private_data;
 	int tm;
 	unsigned char old_cmd = 0;
 
@@ -250,7 +250,7 @@
 /*
  * consumer ac97 digital mix
  */
-static int snd_ice1712_digmix_route_ac97_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ice1712_digmix_route_ac97_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -259,17 +259,17 @@
 	return 0;
 }
 
-static int snd_ice1712_digmix_route_ac97_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_digmix_route_ac97_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0;
 	return 0;
 }
 
-static int snd_ice1712_digmix_route_ac97_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char val, nval;
 	
 	spin_lock_irq(&ice->reg_lock);
@@ -281,7 +281,7 @@
 	return val != nval;
 }
 
-static snd_kcontrol_new_t snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Digital Mixer To AC97",
 	.info = snd_ice1712_digmix_route_ac97_info,
@@ -293,24 +293,24 @@
 /*
  * gpio operations
  */
-static void snd_ice1712_set_gpio_dir(ice1712_t *ice, unsigned int data)
+static void snd_ice1712_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data)
 {
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, data);
 	inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
 }
 
-static void snd_ice1712_set_gpio_mask(ice1712_t *ice, unsigned int data)
+static void snd_ice1712_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
 {
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, data);
 	inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
 }
 
-static unsigned int snd_ice1712_get_gpio_data(ice1712_t *ice)
+static unsigned int snd_ice1712_get_gpio_data(struct snd_ice1712 *ice)
 {
 	return snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
 }
 
-static void snd_ice1712_set_gpio_data(ice1712_t *ice, unsigned int val)
+static void snd_ice1712_set_gpio_data(struct snd_ice1712 *ice, unsigned int val)
 {
 	snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, val);
 	inb(ICEREG(ice, DATA)); /* dummy read for pci-posting */
@@ -327,7 +327,7 @@
  * change the input clock selection
  * spdif_clock = 1 - IEC958 input, 0 - Envy24
  */
-static int snd_ice1712_cs8427_set_input_clock(ice1712_t *ice, int spdif_clock)
+static int snd_ice1712_cs8427_set_input_clock(struct snd_ice1712 *ice, int spdif_clock)
 {
 	unsigned char reg[2] = { 0x80 | 4, 0 };   /* CS8427 auto increment | register number 4 + data */
 	unsigned char val, nval;
@@ -362,17 +362,17 @@
 /*
  * spdif callbacks
  */
-static void open_cs8427(ice1712_t *ice, snd_pcm_substream_t * substream)
+static void open_cs8427(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
 {
 	snd_cs8427_iec958_active(ice->cs8427, 1);
 }
 
-static void close_cs8427(ice1712_t *ice, snd_pcm_substream_t * substream)
+static void close_cs8427(struct snd_ice1712 *ice, struct snd_pcm_substream *substream)
 {
 	snd_cs8427_iec958_active(ice->cs8427, 0);
 }
 
-static void setup_cs8427(ice1712_t *ice, int rate)
+static void setup_cs8427(struct snd_ice1712 *ice, int rate)
 {
 	snd_cs8427_iec958_pcm(ice->cs8427, rate);
 }
@@ -380,7 +380,7 @@
 /*
  * create and initialize callbacks for cs8427 interface
  */
-int __devinit snd_ice1712_init_cs8427(ice1712_t *ice, int addr)
+int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr)
 {
 	int err;
 
@@ -403,7 +403,7 @@
 
 static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	ice1712_t *ice = dev_id;
+	struct snd_ice1712 *ice = dev_id;
 	unsigned char status;
 	int handled = 0;
 
@@ -444,7 +444,7 @@
 		if (status & ICE1712_IRQ_PBKDS) {
 			u32 idx;
 			u16 pbkstatus;
-			snd_pcm_substream_t *substream;
+			struct snd_pcm_substream *substream;
 			pbkstatus = inw(ICEDS(ice, INTSTAT));
 			//printk("pbkstatus = 0x%x\n", pbkstatus);
 			for (idx = 0; idx < 6; idx++) {
@@ -475,13 +475,13 @@
  *  PCM part - misc
  */
 
-static int snd_ice1712_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_ice1712_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_ice1712_hw_free(snd_pcm_substream_t * substream)
+static int snd_ice1712_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
@@ -490,10 +490,10 @@
  *  PCM part - consumer I/O
  */
 
-static int snd_ice1712_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_ice1712_playback_trigger(struct snd_pcm_substream *substream,
 					int cmd)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	int result = 0;
 	u32 tmp;
 	
@@ -515,10 +515,10 @@
 	return result;
 }
 
-static int snd_ice1712_playback_ds_trigger(snd_pcm_substream_t * substream,
+static int snd_ice1712_playback_ds_trigger(struct snd_pcm_substream *substream,
 					   int cmd)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	int result = 0;
 	u32 tmp;
 	
@@ -540,10 +540,10 @@
 	return result;
 }
 
-static int snd_ice1712_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_ice1712_capture_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	int result = 0;
 	u8 tmp;
 	
@@ -561,10 +561,10 @@
 	return result;
 }
 
-static int snd_ice1712_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_ice1712_playback_prepare(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	u32 period_size, buf_size, rate, tmp;
 
 	period_size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1;
@@ -594,10 +594,10 @@
 	return 0;
 }
 
-static int snd_ice1712_playback_ds_prepare(snd_pcm_substream_t * substream)
+static int snd_ice1712_playback_ds_prepare(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	u32 period_size, buf_size, rate, tmp, chn;
 
 	period_size = snd_pcm_lib_period_bytes(substream) - 1;
@@ -629,10 +629,10 @@
 	return 0;
 }
 
-static int snd_ice1712_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_ice1712_capture_prepare(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	u32 period_size, buf_size;
 	u8 tmp;
 
@@ -654,10 +654,10 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_ice1712_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ice1712_playback_pointer(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	size_t ptr;
 
 	if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1))
@@ -668,9 +668,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	u8 addr;
 	size_t ptr;
 
@@ -687,9 +687,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_ice1712_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1))
@@ -700,7 +700,7 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_hardware_t snd_ice1712_playback =
+static struct snd_pcm_hardware snd_ice1712_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -720,7 +720,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ice1712_playback_ds =
+static struct snd_pcm_hardware snd_ice1712_playback_ds =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -740,7 +740,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ice1712_capture =
+static struct snd_pcm_hardware snd_ice1712_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -759,20 +759,20 @@
 	.fifo_size =		0,
 };
 
-static int snd_ice1712_playback_open(snd_pcm_substream_t * substream)
+static int snd_ice1712_playback_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	ice->playback_con_substream = substream;
 	runtime->hw = snd_ice1712_playback;
 	return 0;
 }
 
-static int snd_ice1712_playback_ds_open(snd_pcm_substream_t * substream)
+static int snd_ice1712_playback_ds_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	u32 tmp;
 
 	ice->playback_con_substream_ds[substream->number] = substream;
@@ -784,10 +784,10 @@
 	return 0;
 }
 
-static int snd_ice1712_capture_open(snd_pcm_substream_t * substream)
+static int snd_ice1712_capture_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	ice->capture_con_substream = substream;
 	runtime->hw = snd_ice1712_capture;
@@ -797,17 +797,17 @@
 	return 0;
 }
 
-static int snd_ice1712_playback_close(snd_pcm_substream_t * substream)
+static int snd_ice1712_playback_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	ice->playback_con_substream = NULL;
 	return 0;
 }
 
-static int snd_ice1712_playback_ds_close(snd_pcm_substream_t * substream)
+static int snd_ice1712_playback_ds_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	u32 tmp;
 
 	spin_lock_irq(&ice->reg_lock); 
@@ -818,15 +818,15 @@
 	return 0;
 }
 
-static int snd_ice1712_capture_close(snd_pcm_substream_t * substream)
+static int snd_ice1712_capture_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	ice->capture_con_substream = NULL;
 	return 0;
 }
 
-static snd_pcm_ops_t snd_ice1712_playback_ops = {
+static struct snd_pcm_ops snd_ice1712_playback_ops = {
 	.open =		snd_ice1712_playback_open,
 	.close =	snd_ice1712_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -837,7 +837,7 @@
 	.pointer =	snd_ice1712_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_ice1712_playback_ds_ops = {
+static struct snd_pcm_ops snd_ice1712_playback_ds_ops = {
 	.open =		snd_ice1712_playback_ds_open,
 	.close =	snd_ice1712_playback_ds_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -848,7 +848,7 @@
 	.pointer =	snd_ice1712_playback_ds_pointer,
 };
 
-static snd_pcm_ops_t snd_ice1712_capture_ops = {
+static struct snd_pcm_ops snd_ice1712_capture_ops = {
 	.open =		snd_ice1712_capture_open,
 	.close =	snd_ice1712_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -859,16 +859,9 @@
 	.pointer =	snd_ice1712_capture_pointer,
 };
 
-static void snd_ice1712_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_ice1712_pcm(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm)
 {
-	ice1712_t *ice = pcm->private_data;
-	ice->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_ice1712_pcm(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -881,7 +874,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_ops);
 
 	pcm->private_data = ice;
-	pcm->private_free = snd_ice1712_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "ICE1712 consumer");
 	ice->pcm = pcm;
@@ -897,16 +889,9 @@
 	return 0;
 }
 
-static void snd_ice1712_pcm_free_ds(snd_pcm_t *pcm)
+static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm)
 {
-	ice1712_t *ice = pcm->private_data;
-	ice->pcm_ds = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_ice1712_pcm_ds(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -918,7 +903,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ice1712_playback_ds_ops);
 
 	pcm->private_data = ice;
-	pcm->private_free = snd_ice1712_pcm_free_ds;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "ICE1712 consumer (DS)");
 	ice->pcm_ds = pcm;
@@ -939,16 +923,16 @@
 static unsigned int rates[] = { 8000, 9600, 11025, 12000, 16000, 22050, 24000,
 				32000, 44100, 48000, 64000, 88200, 96000 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 	.count = ARRAY_SIZE(rates),
 	.list = rates,
 	.mask = 0,
 };
 
-static int snd_ice1712_pro_trigger(snd_pcm_substream_t *substream,
+static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream,
 				   int cmd)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
@@ -975,7 +959,7 @@
 		unsigned int what = 0;
 		unsigned int old;
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
+		struct snd_pcm_substream *s;
 
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
@@ -1005,7 +989,7 @@
 
 /*
  */
-static void snd_ice1712_set_pro_rate(ice1712_t *ice, unsigned int rate, int force)
+static void snd_ice1712_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, int force)
 {
 	unsigned long flags;
 	unsigned char val, old;
@@ -1059,9 +1043,9 @@
 		ice->spdif.ops.setup_rate(ice, rate);
 }
 
-static int snd_ice1712_playback_pro_prepare(snd_pcm_substream_t * substream)
+static int snd_ice1712_playback_pro_prepare(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	ice->playback_pro_size = snd_pcm_lib_buffer_bytes(substream);
 	spin_lock_irq(&ice->reg_lock);
@@ -1073,18 +1057,18 @@
 	return 0;
 }
 
-static int snd_ice1712_playback_pro_hw_params(snd_pcm_substream_t * substream,
-					      snd_pcm_hw_params_t * hw_params)
+static int snd_ice1712_playback_pro_hw_params(struct snd_pcm_substream *substream,
+					      struct snd_pcm_hw_params *hw_params)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_ice1712_capture_pro_prepare(snd_pcm_substream_t * substream)
+static int snd_ice1712_capture_pro_prepare(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	ice->capture_pro_size = snd_pcm_lib_buffer_bytes(substream);
 	spin_lock_irq(&ice->reg_lock);
@@ -1095,18 +1079,18 @@
 	return 0;
 }
 
-static int snd_ice1712_capture_pro_hw_params(snd_pcm_substream_t * substream,
-					     snd_pcm_hw_params_t * hw_params)
+static int snd_ice1712_capture_pro_hw_params(struct snd_pcm_substream *substream,
+					     struct snd_pcm_hw_params *hw_params)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	snd_ice1712_set_pro_rate(ice, params_rate(hw_params), 0);
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START))
@@ -1117,9 +1101,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW))
@@ -1130,7 +1114,7 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_hardware_t snd_ice1712_playback_pro =
+static struct snd_pcm_hardware snd_ice1712_playback_pro =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1150,7 +1134,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ice1712_capture_pro =
+static struct snd_pcm_hardware snd_ice1712_capture_pro =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1170,10 +1154,10 @@
 	.fifo_size =		0,
 };
 
-static int snd_ice1712_playback_pro_open(snd_pcm_substream_t * substream)
+static int snd_ice1712_playback_pro_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	ice->playback_pro_substream = substream;
 	runtime->hw = snd_ice1712_playback_pro;
@@ -1187,10 +1171,10 @@
 	return 0;
 }
 
-static int snd_ice1712_capture_pro_open(snd_pcm_substream_t * substream)
+static int snd_ice1712_capture_pro_open(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	ice->capture_pro_substream = substream;
 	runtime->hw = snd_ice1712_capture_pro;
@@ -1200,9 +1184,9 @@
 	return 0;
 }
 
-static int snd_ice1712_playback_pro_close(snd_pcm_substream_t * substream)
+static int snd_ice1712_playback_pro_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	if (PRO_RATE_RESET)
 		snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
@@ -1213,9 +1197,9 @@
 	return 0;
 }
 
-static int snd_ice1712_capture_pro_close(snd_pcm_substream_t * substream)
+static int snd_ice1712_capture_pro_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	if (PRO_RATE_RESET)
 		snd_ice1712_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
@@ -1223,14 +1207,7 @@
 	return 0;
 }
 
-static void snd_ice1712_pcm_profi_free(snd_pcm_t *pcm)
-{
-	ice1712_t *ice = pcm->private_data;
-	ice->pcm_pro = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static snd_pcm_ops_t snd_ice1712_playback_pro_ops = {
+static struct snd_pcm_ops snd_ice1712_playback_pro_ops = {
 	.open =		snd_ice1712_playback_pro_open,
 	.close =	snd_ice1712_playback_pro_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1241,7 +1218,7 @@
 	.pointer =	snd_ice1712_playback_pro_pointer,
 };
 
-static snd_pcm_ops_t snd_ice1712_capture_pro_ops = {
+static struct snd_pcm_ops snd_ice1712_capture_pro_ops = {
 	.open =		snd_ice1712_capture_pro_open,
 	.close =	snd_ice1712_capture_pro_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1252,9 +1229,9 @@
 	.pointer =	snd_ice1712_capture_pro_pointer,
 };
 
-static int __devinit snd_ice1712_pcm_profi(ice1712_t * ice, int device, snd_pcm_t ** rpcm)
+static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1267,7 +1244,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ice1712_capture_pro_ops);
 
 	pcm->private_data = ice;
-	pcm->private_free = snd_ice1712_pcm_profi_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "ICE1712 multi");
 
@@ -1296,7 +1272,7 @@
  *  Mixer section
  */
 
-static void snd_ice1712_update_volume(ice1712_t *ice, int index)
+static void snd_ice1712_update_volume(struct snd_ice1712 *ice, int index)
 {
 	unsigned int vol = ice->pro_volumes[index];
 	unsigned short val = 0;
@@ -1307,7 +1283,7 @@
 	outw(val, ICEMT(ice, MONITOR_VOLUME));
 }
 
-static int snd_ice1712_pro_mixer_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_pro_mixer_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -1316,9 +1292,9 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_mixer_switch_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_mixer_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
 	
 	spin_lock_irq(&ice->reg_lock);
@@ -1328,9 +1304,9 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_mixer_switch_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_mixer_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
 	unsigned int nval, change;
 
@@ -1345,7 +1321,7 @@
 	return change;
 }
 
-static int snd_ice1712_pro_mixer_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_pro_mixer_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -1354,9 +1330,9 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_mixer_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_mixer_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
 	
 	spin_lock_irq(&ice->reg_lock);
@@ -1366,9 +1342,9 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_mixer_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int index = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value;
 	unsigned int nval, change;
 
@@ -1384,7 +1360,7 @@
 }
 
 
-static snd_kcontrol_new_t snd_ice1712_multi_playback_ctrls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Multi Playback Switch",
@@ -1405,7 +1381,7 @@
 	},
 };
 
-static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_switch __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "H/W Multi Capture Switch",
 	.info = snd_ice1712_pro_mixer_switch_info,
@@ -1414,7 +1390,7 @@
 	.private_value = 10,
 };
 
-static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_switch __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH),
 	.info = snd_ice1712_pro_mixer_switch_info,
@@ -1424,7 +1400,7 @@
 	.count = 2,
 };
 
-static snd_kcontrol_new_t snd_ice1712_multi_capture_analog_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "H/W Multi Capture Volume",
 	.info = snd_ice1712_pro_mixer_volume_info,
@@ -1433,7 +1409,7 @@
 	.private_value = 10,
 };
 
-static snd_kcontrol_new_t snd_ice1712_multi_capture_spdif_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME),
 	.info = snd_ice1712_pro_mixer_volume_info,
@@ -1443,9 +1419,9 @@
 	.count = 2,
 };
 
-static int __devinit snd_ice1712_build_pro_mixer(ice1712_t *ice)
+static int __devinit snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice)
 {
-	snd_card_t * card = ice->card;
+	struct snd_card *card = ice->card;
 	unsigned int idx;
 	int err;
 
@@ -1457,7 +1433,7 @@
 	}
 	
 	if (ice->num_total_adcs > 0) {
-		snd_kcontrol_new_t tmp = snd_ice1712_multi_capture_analog_switch;
+		struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_switch;
 		tmp.count = ice->num_total_adcs;
 		err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));
 		if (err < 0)
@@ -1469,7 +1445,7 @@
 		return err;
 
 	if (ice->num_total_adcs > 0) {
-		snd_kcontrol_new_t tmp = snd_ice1712_multi_capture_analog_volume;
+		struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_volume;
 		tmp.count = ice->num_total_adcs;
 		err = snd_ctl_add(card, snd_ctl_new1(&tmp, ice));
 		if (err < 0)
@@ -1496,22 +1472,22 @@
 	return 0;
 }
 
-static void snd_ice1712_mixer_free_ac97(ac97_t *ac97)
+static void snd_ice1712_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	ice1712_t *ice = ac97->private_data;
+	struct snd_ice1712 *ice = ac97->private_data;
 	ice->ac97 = NULL;
 }
 
-static int __devinit snd_ice1712_ac97_mixer(ice1712_t * ice)
+static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 * ice)
 {
 	int err, bus_num = 0;
-	ac97_template_t ac97;
-	ac97_bus_t *pbus;
-	static ac97_bus_ops_t con_ops = {
+	struct snd_ac97_template ac97;
+	struct snd_ac97_bus *pbus;
+	static struct snd_ac97_bus_ops con_ops = {
 		.write = snd_ice1712_ac97_write,
 		.read = snd_ice1712_ac97_read,
 	};
-	static ac97_bus_ops_t pro_ops = {
+	static struct snd_ac97_bus_ops pro_ops = {
 		.write = snd_ice1712_pro_ac97_write,
 		.read = snd_ice1712_pro_ac97_read,
 	};
@@ -1551,15 +1527,15 @@
  *
  */
 
-static inline unsigned int eeprom_double(ice1712_t *ice, int idx)
+static inline unsigned int eeprom_double(struct snd_ice1712 *ice, int idx)
 {
 	return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8);
 }
 
-static void snd_ice1712_proc_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_ice1712_proc_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
-	ice1712_t *ice = entry->private_data;
+	struct snd_ice1712 *ice = entry->private_data;
 	unsigned int idx;
 
 	snd_iprintf(buffer, "%s\n\n", ice->card->longname);
@@ -1593,9 +1569,9 @@
 	snd_iprintf(buffer, "  RATE             : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE)));
 }
 
-static void __devinit snd_ice1712_proc_init(ice1712_t * ice)
+static void __devinit snd_ice1712_proc_init(struct snd_ice1712 * ice)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(ice->card, "ice1712", &entry))
 		snd_info_set_text_ops(entry, ice, 1024, snd_ice1712_proc_read);
@@ -1605,22 +1581,24 @@
  *
  */
 
-static int snd_ice1712_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_eeprom_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
-	uinfo->count = sizeof(ice1712_eeprom_t);
+	uinfo->count = sizeof(struct snd_ice1712_eeprom);
 	return 0;
 }
 
-static int snd_ice1712_eeprom_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	
 	memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_ice1712_eeprom __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.name = "ICE1712 EEPROM",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1630,32 +1608,33 @@
 
 /*
  */
-static int snd_ice1712_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_spdif_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ice1712_spdif_default_get(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_spdif_default_get(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	if (ice->spdif.ops.default_get)
 		ice->spdif.ops.default_get(ice, ucontrol); 
 	return 0;
 }
 
-static int snd_ice1712_spdif_default_put(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	if (ice->spdif.ops.default_put)
 		return ice->spdif.ops.default_put(ice, ucontrol);
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_ice1712_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1664,10 +1643,10 @@
 	.put =		snd_ice1712_spdif_default_put
 };
 
-static int snd_ice1712_spdif_maskc_get(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_spdif_maskc_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	if (ice->spdif.ops.default_get) {
 		ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
 						     IEC958_AES0_PROFESSIONAL |
@@ -1686,10 +1665,10 @@
 	return 0;
 }
 
-static int snd_ice1712_spdif_maskp_get(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	if (ice->spdif.ops.default_get) {
 		ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
 						     IEC958_AES0_PROFESSIONAL |
@@ -1706,7 +1685,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_ice1712_spdif_maskc __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1715,7 +1694,7 @@
 	.get =		snd_ice1712_spdif_maskc_get,
 };
 
-static snd_kcontrol_new_t snd_ice1712_spdif_maskp __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1724,27 +1703,28 @@
 	.get =		snd_ice1712_spdif_maskp_get,
 };
 
-static int snd_ice1712_spdif_stream_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_spdif_stream_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	if (ice->spdif.ops.stream_get)
 		ice->spdif.ops.stream_get(ice, ucontrol);
 	return 0;
 }
 
-static int snd_ice1712_spdif_stream_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	if (ice->spdif.ops.stream_put)
 		return ice->spdif.ops.stream_put(ice, ucontrol);
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_ice1712_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
 {
-	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
+	.access =	(SNDRV_CTL_ELEM_ACCESS_READWRITE |
+			 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
 	.info =		snd_ice1712_spdif_info,
@@ -1752,7 +1732,8 @@
 	.put =		snd_ice1712_spdif_stream_put
 };
 
-int snd_ice1712_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+int snd_ice1712_gpio_info(struct snd_kcontrol *kcontrol,
+			  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1761,21 +1742,24 @@
 	return 0;
 }
 
-int snd_ice1712_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char mask = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
 	
 	snd_ice1712_save_gpio_status(ice);
-	ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert;
+	ucontrol->value.integer.value[0] =
+		(snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert;
 	snd_ice1712_restore_gpio_status(ice);
 	return 0;
 }
 
-int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char mask = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
 	unsigned int val, nval;
@@ -1795,7 +1779,8 @@
 /*
  *  rate
  */
-static int snd_ice1712_pro_internal_clock_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
+					       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {
 		"8000",		/* 0: 6 */
@@ -1822,9 +1807,10 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_internal_clock_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
+					      struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	static unsigned char xlate[16] = {
 		9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10
 	};
@@ -1845,9 +1831,10 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_internal_clock_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
+					      struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	static unsigned int xrate[13] = {
 		8000, 9600, 11025, 12000, 1600, 22050, 24000,
 		32000, 44100, 48000, 64000, 88200, 96000
@@ -1868,7 +1855,8 @@
 	change = inb(ICEMT(ice, RATE)) != oval;
 	spin_unlock_irq(&ice->reg_lock);
 
-	if ((oval & ICE1712_SPDIF_MASTER) != (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) {
+	if ((oval & ICE1712_SPDIF_MASTER) !=
+	    (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) {
 		/* change CS8427 clock source too */
 		if (ice->cs8427) {
 			snd_ice1712_cs8427_set_input_clock(ice, is_spdif_master(ice));
@@ -1886,7 +1874,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ice1712_pro_internal_clock __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Internal Clock",
 	.info = snd_ice1712_pro_internal_clock_info,
@@ -1894,7 +1882,8 @@
 	.put = snd_ice1712_pro_internal_clock_put
 };
 
-static int snd_ice1712_pro_internal_clock_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcontrol,
+						       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {
 		"8000",		/* 0: 6 */
@@ -1921,7 +1910,8 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_internal_clock_default_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcontrol,
+						      struct snd_ctl_elem_value *ucontrol)
 {
 	int val;
 	static unsigned int xrate[13] = {
@@ -1938,7 +1928,8 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_internal_clock_default_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcontrol,
+						      struct snd_ctl_elem_value *ucontrol)
 {
 	static unsigned int xrate[13] = {
 		8000, 9600, 11025, 12000, 1600, 22050, 24000,
@@ -1954,7 +1945,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ice1712_pro_internal_clock_default __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Internal Clock Default",
 	.info = snd_ice1712_pro_internal_clock_default_info,
@@ -1962,7 +1953,8 @@
 	.put = snd_ice1712_pro_internal_clock_default_put
 };
 
-static int snd_ice1712_pro_rate_locking_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_pro_rate_locking_info(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1971,15 +1963,17 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_rate_locking_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_rate_locking_get(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
 	return 0;
 }
 
-static int snd_ice1712_pro_rate_locking_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change = 0, nval;
 
 	nval = ucontrol->value.integer.value[0] ? 1 : 0;
@@ -1990,7 +1984,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ice1712_pro_rate_locking __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Rate Locking",
 	.info = snd_ice1712_pro_rate_locking_info,
@@ -1998,7 +1992,8 @@
 	.put = snd_ice1712_pro_rate_locking_put
 };
 
-static int snd_ice1712_pro_rate_reset_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_pro_rate_reset_info(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2007,15 +2002,17 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_rate_reset_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_rate_reset_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.integer.value[0] = PRO_RATE_RESET;
 	return 0;
 }
 
-static int snd_ice1712_pro_rate_reset_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change = 0, nval;
 
 	nval = ucontrol->value.integer.value[0] ? 1 : 0;
@@ -2026,7 +2023,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ice1712_pro_rate_reset __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Rate Reset",
 	.info = snd_ice1712_pro_rate_reset_info,
@@ -2037,7 +2034,8 @@
 /*
  * routing
  */
-static int snd_ice1712_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {
 		"PCM Out", /* 0 */
@@ -2049,16 +2047,18 @@
 	
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
-	uinfo->value.enumerated.items = snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11;
+	uinfo->value.enumerated.items =
+		snd_ctl_get_ioffidx(kcontrol, &uinfo->id) < 2 ? 12 : 11;
 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
 		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
 	strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
 	return 0;
 }
 
-static int snd_ice1712_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_pro_route_analog_get(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	unsigned int val, cval;
 
@@ -2081,9 +2081,10 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_pro_route_analog_put(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change, shift;
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	unsigned int val, old_val, nval;
@@ -2130,9 +2131,10 @@
 	return change;
 }
 
-static int snd_ice1712_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_pro_route_spdif_get(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	unsigned int val, cval;
 	val = inw(ICEMT(ice, ROUTE_SPDOUT));
@@ -2149,9 +2151,10 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change, shift;
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	unsigned int val, old_val, nval;
@@ -2187,7 +2190,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ice1712_mixer_pro_analog_route __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "H/W Playback Route",
 	.info = snd_ice1712_pro_route_info,
@@ -2195,7 +2198,7 @@
 	.put = snd_ice1712_pro_route_analog_put,
 };
 
-static snd_kcontrol_new_t snd_ice1712_mixer_pro_spdif_route __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
 	.info = snd_ice1712_pro_route_info,
@@ -2205,7 +2208,8 @@
 };
 
 
-static int snd_ice1712_pro_volume_rate_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_pro_volume_rate_info(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -2214,17 +2218,19 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_volume_rate_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_volume_rate_get(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE));
 	return 0;
 }
 
-static int snd_ice1712_pro_volume_rate_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change;
 
 	spin_lock_irq(&ice->reg_lock);
@@ -2234,7 +2240,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ice1712_mixer_pro_volume_rate __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Volume Rate",
 	.info = snd_ice1712_pro_volume_rate_info,
@@ -2242,7 +2248,8 @@
 	.put = snd_ice1712_pro_volume_rate_put
 };
 
-static int snd_ice1712_pro_peak_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ice1712_pro_peak_info(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 22;
@@ -2251,9 +2258,10 @@
 	return 0;
 }
 
-static int snd_ice1712_pro_peak_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx;
 	
 	spin_lock_irq(&ice->reg_lock);
@@ -2265,7 +2273,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_ice1712_mixer_pro_peak __devinitdata = {
+static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Peak",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -2287,7 +2295,7 @@
 	NULL,
 };
 
-static unsigned char __devinit snd_ice1712_read_i2c(ice1712_t *ice,
+static unsigned char __devinit snd_ice1712_read_i2c(struct snd_ice1712 *ice,
 						 unsigned char dev,
 						 unsigned char addr)
 {
@@ -2299,7 +2307,8 @@
 	return inb(ICEREG(ice, I2C_DATA));
 }
 
-static int __devinit snd_ice1712_read_eeprom(ice1712_t *ice, const char *modelname)
+static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
+					     const char *modelname)
 {
 	int dev = 0xa0;		/* EEPROM device address */
 	unsigned int i, size;
@@ -2312,7 +2321,8 @@
 				(snd_ice1712_read_i2c(ice, dev, 0x01) << 8) | 
 				(snd_ice1712_read_i2c(ice, dev, 0x02) << 16) | 
 				(snd_ice1712_read_i2c(ice, dev, 0x03) << 24);
-		if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
+		if (ice->eeprom.subvendor == 0 ||
+		    ice->eeprom.subvendor == (unsigned int)-1) {
 			/* invalid subvendor from EEPROM, try the PCI subststem ID instead */
 			u16 vendor, device;
 			pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
@@ -2341,7 +2351,8 @@
 			goto read_skipped;
 		}
 	}
-	printk(KERN_WARNING "ice1712: No matching model found for ID 0x%x\n", ice->eeprom.subvendor);
+	printk(KERN_WARNING "ice1712: No matching model found for ID 0x%x\n",
+	       ice->eeprom.subvendor);
 
  found:
 	ice->eeprom.size = snd_ice1712_read_i2c(ice, dev, 0x04);
@@ -2353,7 +2364,8 @@
 	}
 	ice->eeprom.version = snd_ice1712_read_i2c(ice, dev, 0x05);
 	if (ice->eeprom.version != 1) {
-		snd_printk(KERN_ERR "invalid EEPROM version %i\n", ice->eeprom.version);
+		snd_printk(KERN_ERR "invalid EEPROM version %i\n",
+			   ice->eeprom.version);
 		/* return -EIO; */
 	}
 	size = ice->eeprom.size - 6;
@@ -2370,7 +2382,7 @@
 
 
 
-static int __devinit snd_ice1712_chip_init(ice1712_t *ice)
+static int __devinit snd_ice1712_chip_init(struct snd_ice1712 *ice)
 {
 	outb(ICE1712_RESET | ICE1712_NATIVE, ICEREG(ice, CONTROL));
 	udelay(200);
@@ -2383,15 +2395,19 @@
 	if (ice->eeprom.subvendor != ICE1712_SUBDEVICE_STDSP24) {
 		ice->gpio.write_mask = ice->eeprom.gpiomask;
 		ice->gpio.direction = ice->eeprom.gpiodir;
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, ice->eeprom.gpiomask);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, ice->eeprom.gpiodir);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ice->eeprom.gpiostate);
+		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK,
+				  ice->eeprom.gpiomask);
+		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION,
+				  ice->eeprom.gpiodir);
+		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA,
+				  ice->eeprom.gpiostate);
 	} else {
 		ice->gpio.write_mask = 0xc0;
 		ice->gpio.direction = 0xff;
 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_WRITE_MASK, 0xc0);
 		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DIRECTION, 0xff);
-		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, ICE1712_STDSP24_CLOCK_BIT);
+		snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA,
+				  ICE1712_STDSP24_CLOCK_BIT);
 	}
 	snd_ice1712_write(ice, ICE1712_IREG_PRO_POWERDOWN, 0);
 	if (!(ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97)) {
@@ -2406,10 +2422,10 @@
 	return 0;
 }
 
-int __devinit snd_ice1712_spdif_build_controls(ice1712_t *ice)
+int __devinit snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice)
 {
 	int err;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	snd_assert(ice->pcm_pro != NULL, return -EIO);
 	err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice));
@@ -2433,7 +2449,7 @@
 }
 
 
-static int __devinit snd_ice1712_build_controls(ice1712_t *ice)
+static int __devinit snd_ice1712_build_controls(struct snd_ice1712 *ice)
 {
 	int err;
 
@@ -2455,7 +2471,7 @@
 		return err;
 
 	if (ice->num_total_dacs > 0) {
-		snd_kcontrol_new_t tmp = snd_ice1712_mixer_pro_analog_route;
+		struct snd_kcontrol_new tmp = snd_ice1712_mixer_pro_analog_route;
 		tmp.count = ice->num_total_dacs;
 		err = snd_ctl_add(ice->card, snd_ctl_new1(&tmp, ice));
 		if (err < 0)
@@ -2476,7 +2492,7 @@
 	return 0;
 }
 
-static int snd_ice1712_free(ice1712_t *ice)
+static int snd_ice1712_free(struct snd_ice1712 *ice)
 {
 	if (! ice->port)
 		goto __hw_end;
@@ -2487,7 +2503,7 @@
       __hw_end:
 	if (ice->irq >= 0) {
 		synchronize_irq(ice->irq);
-		free_irq(ice->irq, (void *) ice);
+		free_irq(ice->irq, ice);
 	}
 	if (ice->port)
 		pci_release_regions(ice->pci);
@@ -2497,22 +2513,22 @@
 	return 0;
 }
 
-static int snd_ice1712_dev_free(snd_device_t *device)
+static int snd_ice1712_dev_free(struct snd_device *device)
 {
-	ice1712_t *ice = device->device_data;
+	struct snd_ice1712 *ice = device->device_data;
 	return snd_ice1712_free(ice);
 }
 
-static int __devinit snd_ice1712_create(snd_card_t * card,
+static int __devinit snd_ice1712_create(struct snd_card *card,
 					struct pci_dev *pci,
 					const char *modelname,
 					int omni,
 					int cs8427_timeout,
-					ice1712_t ** r_ice1712)
+					struct snd_ice1712 ** r_ice1712)
 {
-	ice1712_t *ice;
+	struct snd_ice1712 *ice;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_ice1712_dev_free,
 	};
 
@@ -2572,7 +2588,8 @@
 	ice->dmapath_port = pci_resource_start(pci, 2);
 	ice->profi_port = pci_resource_start(pci, 3);
 
-	if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1712", (void *) ice)) {
+	if (request_irq(pci->irq, snd_ice1712_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			"ICE1712", ice)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_ice1712_free(ice);
 		return -EIO;
@@ -2590,8 +2607,10 @@
 	}
 
 	/* unmask used interrupts */
-	outb((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ? ICE1712_IRQ_MPU2 : 0 |
-	     (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ? ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0,
+	outb(((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) == 0 ?
+	      ICE1712_IRQ_MPU2 : 0) |
+	     ((ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97) ?
+	      ICE1712_IRQ_PBKDS | ICE1712_IRQ_CONCAP | ICE1712_IRQ_CONPBK : 0),
 	     ICEREG(ice, IRQMASK));
 	outb(0x00, ICEMT(ice, IRQ));
 
@@ -2619,8 +2638,8 @@
 				       const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	ice1712_t *ice;
+	struct snd_card *card;
+	struct snd_ice1712 *ice;
 	int pcm_dev = 0, err;
 	struct snd_ice1712_card_info **tbl, *c;
 
@@ -2638,7 +2657,8 @@
 	strcpy(card->driver, "ICE1712");
 	strcpy(card->shortname, "ICEnsemble ICE1712");
 	
-	if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev], cs8427_timeout[dev], &ice)) < 0) {
+	if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev],
+				      cs8427_timeout[dev], &ice)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 5ad4728..ce96b3b 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -215,9 +215,9 @@
  *  
  */
 
-typedef struct _snd_ice1712 ice1712_t;
+struct snd_ice1712;
 
-typedef struct {
+struct snd_ice1712_eeprom {
 	unsigned int subvendor;	/* PCI[2c-2f] */
 	unsigned char size;	/* size of EEPROM image in bytes */
 	unsigned char version;	/* must be 1 (or 2 for vt1724) */
@@ -225,7 +225,7 @@
 	unsigned int gpiomask;
 	unsigned int gpiostate;
 	unsigned int gpiodir;
-} ice1712_eeprom_t;
+};
 
 enum {
 	ICE_EEP1_CODEC = 0,	/* 06 */
@@ -266,28 +266,28 @@
 	unsigned int add_flags;		/* additional bits at init */
 	unsigned int mask_flags;	/* total mask bits */
 	struct snd_akm4xxx_ops {
-		void (*set_rate_val)(akm4xxx_t *ak, unsigned int rate);
+		void (*set_rate_val)(struct snd_akm4xxx *ak, unsigned int rate);
 	} ops;
 };
 
 struct snd_ice1712_spdif {
 	unsigned char cs8403_bits;
 	unsigned char cs8403_stream_bits;
-	snd_kcontrol_t *stream_ctl;
+	struct snd_kcontrol *stream_ctl;
 
 	struct snd_ice1712_spdif_ops {
-		void (*open)(ice1712_t *, snd_pcm_substream_t *);
-		void (*setup_rate)(ice1712_t *, int rate);
-		void (*close)(ice1712_t *, snd_pcm_substream_t *);
-		void (*default_get)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
-		int (*default_put)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
-		void (*stream_get)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
-		int (*stream_put)(ice1712_t *, snd_ctl_elem_value_t * ucontrol);
+		void (*open)(struct snd_ice1712 *, struct snd_pcm_substream *);
+		void (*setup_rate)(struct snd_ice1712 *, int rate);
+		void (*close)(struct snd_ice1712 *, struct snd_pcm_substream *);
+		void (*default_get)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
+		int (*default_put)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
+		void (*stream_get)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
+		int (*stream_put)(struct snd_ice1712 *, struct snd_ctl_elem_value *ucontrol);
 	} ops;
 };
 
 
-struct _snd_ice1712 {
+struct snd_ice1712 {
 	unsigned long conp_dma_size;
 	unsigned long conc_dma_size;
 	unsigned long prop_dma_size;
@@ -300,28 +300,28 @@
 	unsigned long profi_port;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_t *pcm_ds;
-	snd_pcm_t *pcm_pro;
-        snd_pcm_substream_t *playback_con_substream;
-        snd_pcm_substream_t *playback_con_substream_ds[6];
-        snd_pcm_substream_t *capture_con_substream;
-        snd_pcm_substream_t *playback_pro_substream;
-        snd_pcm_substream_t *capture_pro_substream;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm *pcm_ds;
+	struct snd_pcm *pcm_pro;
+        struct snd_pcm_substream *playback_con_substream;
+        struct snd_pcm_substream *playback_con_substream_ds[6];
+        struct snd_pcm_substream *capture_con_substream;
+        struct snd_pcm_substream *playback_pro_substream;
+        struct snd_pcm_substream *capture_pro_substream;
 	unsigned int playback_pro_size;
 	unsigned int capture_pro_size;
 	unsigned int playback_con_virt_addr[6];
 	unsigned int playback_con_active_buf[6];
 	unsigned int capture_con_virt_addr;
 	unsigned int ac97_ext_id;
-	ac97_t *ac97;
-	snd_rawmidi_t *rmidi[2];
+	struct snd_ac97 *ac97;
+	struct snd_rawmidi *rmidi[2];
 
 	spinlock_t reg_lock;
-	snd_info_entry_t *proc_entry;
+	struct snd_info_entry *proc_entry;
 
-	ice1712_eeprom_t eeprom;
+	struct snd_ice1712_eeprom eeprom;
 
 	unsigned int pro_volumes[20];
 	unsigned int omni: 1;		/* Delta Omni I/O */
@@ -335,16 +335,16 @@
 	unsigned int cur_rate;		/* current rate */
 
 	struct semaphore open_mutex;
-	snd_pcm_substream_t *pcm_reserved[4];
-	snd_pcm_hw_constraint_list_t *hw_rates; /* card-specific rate constraints */
+	struct snd_pcm_substream *pcm_reserved[4];
+	struct snd_pcm_hw_constraint_list *hw_rates; /* card-specific rate constraints */
 
 	unsigned int akm_codecs;
-	akm4xxx_t *akm;
+	struct snd_akm4xxx *akm;
 	struct snd_ice1712_spdif spdif;
 
 	struct semaphore i2c_mutex;	/* I2C mutex for ICE1724 registers */
-	snd_i2c_bus_t *i2c;		/* I2C bus */
-	snd_i2c_device_t *cs8427;	/* CS8427 I2C device */
+	struct snd_i2c_bus *i2c;		/* I2C bus */
+	struct snd_i2c_device *cs8427;	/* CS8427 I2C device */
 	unsigned int cs8427_timeout;	/* CS8427 reset timeout in HZ/100 */
 	
 	struct ice1712_gpio {
@@ -352,20 +352,20 @@
 		unsigned int write_mask;	/* current mask bits */
 		unsigned int saved[2];		/* for ewx_i2c */
 		/* operators */
-		void (*set_mask)(ice1712_t *ice, unsigned int data);
-		void (*set_dir)(ice1712_t *ice, unsigned int data);
-		void (*set_data)(ice1712_t *ice, unsigned int data);
-		unsigned int (*get_data)(ice1712_t *ice);
+		void (*set_mask)(struct snd_ice1712 *ice, unsigned int data);
+		void (*set_dir)(struct snd_ice1712 *ice, unsigned int data);
+		void (*set_data)(struct snd_ice1712 *ice, unsigned int data);
+		unsigned int (*get_data)(struct snd_ice1712 *ice);
 		/* misc operators - move to another place? */
-		void (*set_pro_rate)(ice1712_t *ice, unsigned int rate);
-		void (*i2s_mclk_changed)(ice1712_t *ice);
+		void (*set_pro_rate)(struct snd_ice1712 *ice, unsigned int rate);
+		void (*i2s_mclk_changed)(struct snd_ice1712 *ice);
 	} gpio;
 	struct semaphore gpio_mutex;
 
 	/* other board-specific data */
 	union {
 		/* additional i2c devices for EWS boards */
-		snd_i2c_device_t *i2cdevs[3];
+		struct snd_i2c_device *i2cdevs[3];
 		/* AC97 register cache for Aureon */
 		struct aureon_spec {
 			unsigned short stac9744[64];
@@ -385,7 +385,7 @@
 			unsigned short boxconfig[4];
 		} hoontech;
 		struct {
-			ak4114_t *ak4114;
+			struct ak4114 *ak4114;
 			unsigned int analog: 1;
 		} juli;
 	} spec;
@@ -396,22 +396,22 @@
 /*
  * gpio access functions
  */
-static inline void snd_ice1712_gpio_set_dir(ice1712_t *ice, unsigned int bits)
+static inline void snd_ice1712_gpio_set_dir(struct snd_ice1712 *ice, unsigned int bits)
 {
 	ice->gpio.set_dir(ice, bits);
 }
 
-static inline void snd_ice1712_gpio_set_mask(ice1712_t *ice, unsigned int bits)
+static inline void snd_ice1712_gpio_set_mask(struct snd_ice1712 *ice, unsigned int bits)
 {
 	ice->gpio.set_mask(ice, bits);
 }
 
-static inline void snd_ice1712_gpio_write(ice1712_t *ice, unsigned int val)
+static inline void snd_ice1712_gpio_write(struct snd_ice1712 *ice, unsigned int val)
 {
 	ice->gpio.set_data(ice, val);
 }
 
-static inline unsigned int snd_ice1712_gpio_read(ice1712_t *ice)
+static inline unsigned int snd_ice1712_gpio_read(struct snd_ice1712 *ice)
 {
 	return ice->gpio.get_data(ice);
 }
@@ -421,14 +421,14 @@
  * The access to gpio will be protected by mutex, so don't forget to
  * restore!
  */
-static inline void snd_ice1712_save_gpio_status(ice1712_t *ice)
+static inline void snd_ice1712_save_gpio_status(struct snd_ice1712 *ice)
 {
 	down(&ice->gpio_mutex);
 	ice->gpio.saved[0] = ice->gpio.direction;
 	ice->gpio.saved[1] = ice->gpio.write_mask;
 }
 
-static inline void snd_ice1712_restore_gpio_status(ice1712_t *ice)
+static inline void snd_ice1712_restore_gpio_status(struct snd_ice1712 *ice)
 {
 	ice->gpio.set_dir(ice, ice->gpio.saved[0]);
 	ice->gpio.set_mask(ice, ice->gpio.saved[1]);
@@ -443,14 +443,15 @@
   .get = snd_ice1712_gpio_get, .put = snd_ice1712_gpio_put, \
   .private_value = mask | (invert << 24) }
 
-int snd_ice1712_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo);
-int snd_ice1712_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
-int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol);
+int snd_ice1712_gpio_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
+int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
+int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
 
 /*
  * set gpio direction, write mask and data
  */
-static inline void snd_ice1712_gpio_write_bits(ice1712_t *ice, unsigned int mask, unsigned int bits)
+static inline void snd_ice1712_gpio_write_bits(struct snd_ice1712 *ice,
+					       unsigned int mask, unsigned int bits)
 {
 	ice->gpio.direction |= mask;
 	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
@@ -458,21 +459,22 @@
 	snd_ice1712_gpio_write(ice, mask & bits);
 }
 
-int snd_ice1712_spdif_build_controls(ice1712_t *ice);
+int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice);
 
-int snd_ice1712_akm4xxx_init(akm4xxx_t *ak, const akm4xxx_t *template, const struct snd_ak4xxx_private *priv, ice1712_t *ice);
-void snd_ice1712_akm4xxx_free(ice1712_t *ice);
-int snd_ice1712_akm4xxx_build_controls(ice1712_t *ice);
+int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *template,
+			     const struct snd_ak4xxx_private *priv, struct snd_ice1712 *ice);
+void snd_ice1712_akm4xxx_free(struct snd_ice1712 *ice);
+int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice);
 
-int snd_ice1712_init_cs8427(ice1712_t *ice, int addr);
+int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr);
 
-static inline void snd_ice1712_write(ice1712_t * ice, u8 addr, u8 data)
+static inline void snd_ice1712_write(struct snd_ice1712 * ice, u8 addr, u8 data)
 {
 	outb(addr, ICEREG(ice, INDEX));
 	outb(data, ICEREG(ice, DATA));
 }
 
-static inline u8 snd_ice1712_read(ice1712_t * ice, u8 addr)
+static inline u8 snd_ice1712_read(struct snd_ice1712 * ice, u8 addr)
 {
 	outb(addr, ICEREG(ice, INDEX));
 	return inb(ICEREG(ice, DATA));
@@ -488,8 +490,8 @@
 	char *name;
 	char *model;
 	char *driver;
-	int (*chip_init)(ice1712_t *);
-	int (*build_controls)(ice1712_t *);
+	int (*chip_init)(struct snd_ice1712 *);
+	int (*build_controls)(struct snd_ice1712 *);
 	unsigned int no_mpu401: 1;
 	unsigned int eeprom_size;
 	unsigned char *eeprom_data;
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 0b5389e..71f08c0 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -102,12 +102,12 @@
  */
  
 /* check whether the clock mode is spdif-in */
-static inline int is_spdif_master(ice1712_t *ice)
+static inline int is_spdif_master(struct snd_ice1712 *ice)
 {
 	return (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER) ? 1 : 0;
 }
 
-static inline int is_pro_rate_locked(ice1712_t *ice)
+static inline int is_pro_rate_locked(struct snd_ice1712 *ice)
 {
 	return is_spdif_master(ice) || PRO_RATE_LOCKED;
 }
@@ -116,7 +116,7 @@
  * ac97 section
  */
 
-static unsigned char snd_vt1724_ac97_ready(ice1712_t *ice)
+static unsigned char snd_vt1724_ac97_ready(struct snd_ice1712 *ice)
 {
 	unsigned char old_cmd;
 	int tm;
@@ -132,7 +132,7 @@
 	return old_cmd;
 }
 
-static int snd_vt1724_ac97_wait_bit(ice1712_t *ice, unsigned char bit)
+static int snd_vt1724_ac97_wait_bit(struct snd_ice1712 *ice, unsigned char bit)
 {
 	int tm;
 	for (tm = 0; tm < 0x10000; tm++)
@@ -142,11 +142,11 @@
 	return -EIO;
 }
 
-static void snd_vt1724_ac97_write(ac97_t *ac97,
+static void snd_vt1724_ac97_write(struct snd_ac97 *ac97,
 				  unsigned short reg,
 				  unsigned short val)
 {
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
+	struct snd_ice1712 *ice = ac97->private_data;
 	unsigned char old_cmd;
 
 	old_cmd = snd_vt1724_ac97_ready(ice);
@@ -158,9 +158,9 @@
 	snd_vt1724_ac97_wait_bit(ice, VT1724_AC97_WRITE);
 }
 
-static unsigned short snd_vt1724_ac97_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_vt1724_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
-	ice1712_t *ice = (ice1712_t *)ac97->private_data;
+	struct snd_ice1712 *ice = ac97->private_data;
 	unsigned char old_cmd;
 
 	old_cmd = snd_vt1724_ac97_ready(ice);
@@ -179,14 +179,14 @@
  */
 
 /* set gpio direction 0 = read, 1 = write */
-static void snd_vt1724_set_gpio_dir(ice1712_t *ice, unsigned int data)
+static void snd_vt1724_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data)
 {
 	outl(data, ICEREG1724(ice, GPIO_DIRECTION));
 	inw(ICEREG1724(ice, GPIO_DIRECTION)); /* dummy read for pci-posting */
 }
 
 /* set the gpio mask (0 = writable) */
-static void snd_vt1724_set_gpio_mask(ice1712_t *ice, unsigned int data)
+static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data)
 {
 	outw(data, ICEREG1724(ice, GPIO_WRITE_MASK));
 	if (! ice->vt1720) /* VT1720 supports only 16 GPIO bits */
@@ -194,7 +194,7 @@
 	inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */
 }
 
-static void snd_vt1724_set_gpio_data(ice1712_t *ice, unsigned int data)
+static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data)
 {
 	outw(data, ICEREG1724(ice, GPIO_DATA));
 	if (! ice->vt1720)
@@ -202,7 +202,7 @@
 	inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */
 }
 
-static unsigned int snd_vt1724_get_gpio_data(ice1712_t *ice)
+static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice)
 {
 	unsigned int data;
 	if (! ice->vt1720)
@@ -219,7 +219,7 @@
 
 static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	ice1712_t *ice = dev_id;
+	struct snd_ice1712 *ice = dev_id;
 	unsigned char status;
 	int handled = 0;
 
@@ -229,8 +229,10 @@
 			break;
 
 		handled = 1;		
-		/*  these should probably be separated at some point, 
-			but as we don't currently have MPU support on the board I will leave it */
+		/* these should probably be separated at some point, 
+		 * but as we don't currently have MPU support on the board
+		 * I will leave it
+		 */
 		if ((status & VT1724_IRQ_MPU_RX)||(status & VT1724_IRQ_MPU_TX)) {
 			if (ice->rmidi[0])
 				snd_mpu401_uart_interrupt(irq, ice->rmidi[0]->private_data, regs);
@@ -303,19 +305,19 @@
 	176400, 192000,
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates_96 = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates_96 = {
 	.count = ARRAY_SIZE(rates) - 2, /* up to 96000 */
 	.list = rates,
 	.mask = 0,
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates_48 = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates_48 = {
 	.count = ARRAY_SIZE(rates) - 5, /* up to 48000 */
 	.list = rates,
 	.mask = 0,
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates_192 = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates_192 = {
 	.count = ARRAY_SIZE(rates),
 	.list = rates,
 	.mask = 0,
@@ -328,13 +330,13 @@
 	unsigned int start;	/* start & pause bit */
 };
 
-static int snd_vt1724_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	unsigned char what;
 	unsigned char old;
 	struct list_head *pos;
-	snd_pcm_substream_t *s;
+	struct snd_pcm_substream *s;
 
 	what = 0;
 	snd_pcm_group_for_each(pos, substream) {
@@ -384,7 +386,7 @@
 #define DMA_PAUSES	(VT1724_RDMA0_PAUSE|VT1724_PDMA0_PAUSE|VT1724_RDMA1_PAUSE|\
 	VT1724_PDMA1_PAUSE|VT1724_PDMA2_PAUSE|VT1724_PDMA3_PAUSE|VT1724_PDMA4_PAUSE)
 
-static int get_max_rate(ice1712_t *ice)
+static int get_max_rate(struct snd_ice1712 *ice)
 {
 	if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
 		if ((ice->eeprom.data[ICE_EEP2_I2S] & 0x08) && !ice->vt1720)
@@ -395,7 +397,8 @@
 		return 48000;
 }
 
-static void snd_vt1724_set_pro_rate(ice1712_t *ice, unsigned int rate, int force)
+static void snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
+				    int force)
 {
 	unsigned long flags;
 	unsigned char val, old;
@@ -477,10 +480,10 @@
 		ice->spdif.ops.setup_rate(ice, rate);
 }
 
-static int snd_vt1724_pcm_hw_params(snd_pcm_substream_t * substream,
-				    snd_pcm_hw_params_t * hw_params)
+static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *hw_params)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	int i, chs;
 
 	chs = params_channels(hw_params);
@@ -490,7 +493,8 @@
 		/* PDMA0 can be multi-channel up to 8 */
 		chs = chs / 2 - 1;
 		for (i = 0; i < chs; i++) {
-			if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) {
+			if (ice->pcm_reserved[i] &&
+			    ice->pcm_reserved[i] != substream) {
 				up(&ice->open_mutex);
 				return -EBUSY;
 			}
@@ -504,7 +508,8 @@
 		for (i = 0; i < 3; i++) {
 			/* check individual playback stream */
 			if (ice->playback_con_substream_ds[i] == substream) {
-				if (ice->pcm_reserved[i] && ice->pcm_reserved[i] != substream) {
+				if (ice->pcm_reserved[i] &&
+				    ice->pcm_reserved[i] != substream) {
 					up(&ice->open_mutex);
 					return -EBUSY;
 				}
@@ -518,9 +523,9 @@
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_vt1724_pcm_hw_free(snd_pcm_substream_t * substream)
+static int snd_vt1724_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	int i;
 
 	down(&ice->open_mutex);
@@ -532,9 +537,9 @@
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_vt1724_playback_pro_prepare(snd_pcm_substream_t * substream)
+static int snd_vt1724_playback_pro_prepare(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	unsigned char val;
 	unsigned int size;
 
@@ -559,9 +564,9 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & VT1724_PDMA0_START))
@@ -575,7 +580,8 @@
 	ptr -= substream->runtime->dma_addr;
 	ptr = bytes_to_frames(substream->runtime, ptr);
 	if (ptr >= substream->runtime->buffer_size) {
-		snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->period_size);
+		snd_printd("ice1724: invalid ptr %d (size=%d)\n",
+			   (int)ptr, (int)substream->runtime->period_size);
 		return 0;
 	}
 #else /* read PLAYBACK_SIZE */
@@ -587,29 +593,32 @@
 	else if (ptr <= substream->runtime->buffer_size)
 		ptr = substream->runtime->buffer_size - ptr;
 	else {
-		snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->buffer_size);
+		snd_printd("ice1724: invalid ptr %d (size=%d)\n",
+			   (int)ptr, (int)substream->runtime->buffer_size);
 		ptr = 0;
 	}
 #endif
 	return ptr;
 }
 
-static int snd_vt1724_pcm_prepare(snd_pcm_substream_t *substream)
+static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	struct vt1724_pcm_reg *reg = substream->runtime->private_data;
 
 	spin_lock_irq(&ice->reg_lock);
 	outl(substream->runtime->dma_addr, ice->profi_port + reg->addr);
-	outw((snd_pcm_lib_buffer_bytes(substream) >> 2) - 1, ice->profi_port + reg->size);
-	outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1, ice->profi_port + reg->count);
+	outw((snd_pcm_lib_buffer_bytes(substream) >> 2) - 1,
+	     ice->profi_port + reg->size);
+	outw((snd_pcm_lib_period_bytes(substream) >> 2) - 1,
+	     ice->profi_port + reg->count);
 	spin_unlock_irq(&ice->reg_lock);
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_vt1724_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	struct vt1724_pcm_reg *reg = substream->runtime->private_data;
 	size_t ptr;
 
@@ -628,7 +637,8 @@
 	else if (ptr <= substream->runtime->buffer_size)
 		ptr = substream->runtime->buffer_size - ptr;
 	else {
-		snd_printd("ice1724: invalid ptr %d (size=%d)\n", (int)ptr, (int)substream->runtime->buffer_size);
+		snd_printd("ice1724: invalid ptr %d (size=%d)\n",
+			   (int)ptr, (int)substream->runtime->buffer_size);
 		ptr = 0;
 	}
 	return ptr;
@@ -649,7 +659,7 @@
 	.start = VT1724_RDMA0_START,
 };
 
-static snd_pcm_hardware_t snd_vt1724_playback_pro =
+static struct snd_pcm_hardware snd_vt1724_playback_pro =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -668,7 +678,7 @@
 	.periods_max =		1024,
 };
 
-static snd_pcm_hardware_t snd_vt1724_spdif =
+static struct snd_pcm_hardware snd_vt1724_spdif =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -690,7 +700,7 @@
 	.periods_max =		1024,
 };
 
-static snd_pcm_hardware_t snd_vt1724_2ch_stereo =
+static struct snd_pcm_hardware snd_vt1724_2ch_stereo =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -712,31 +722,41 @@
 /*
  * set rate constraints
  */
-static int set_rate_constraints(ice1712_t *ice, snd_pcm_substream_t *substream)
+static int set_rate_constraints(struct snd_ice1712 *ice,
+				struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	if (ice->hw_rates) {
 		/* hardware specific */
 		runtime->hw.rate_min = ice->hw_rates->list[0];
 		runtime->hw.rate_max = ice->hw_rates->list[ice->hw_rates->count - 1];
 		runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
-		return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, ice->hw_rates);
+		return snd_pcm_hw_constraint_list(runtime, 0,
+						  SNDRV_PCM_HW_PARAM_RATE,
+						  ice->hw_rates);
 	}
 	if (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S) {
 		/* I2S */
 		/* VT1720 doesn't support more than 96kHz */
 		if ((ice->eeprom.data[ICE_EEP2_I2S] & 0x08) && !ice->vt1720)
-			return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_192);
+			return snd_pcm_hw_constraint_list(runtime, 0,
+							  SNDRV_PCM_HW_PARAM_RATE,
+							  &hw_constraints_rates_192);
 		else {
-			runtime->hw.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_96000;
+			runtime->hw.rates = SNDRV_PCM_RATE_KNOT |
+				SNDRV_PCM_RATE_8000_96000;
 			runtime->hw.rate_max = 96000;
-			return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_96);
+			return snd_pcm_hw_constraint_list(runtime, 0,
+							  SNDRV_PCM_HW_PARAM_RATE,
+							  &hw_constraints_rates_96);
 		}
 	} else if (ice->ac97) {
 		/* ACLINK */
 		runtime->hw.rate_max = 48000;
 		runtime->hw.rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000;
-		return snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates_48);
+		return snd_pcm_hw_constraint_list(runtime, 0,
+						  SNDRV_PCM_HW_PARAM_RATE,
+						  &hw_constraints_rates_48);
 	}
 	return 0;
 }
@@ -746,10 +766,10 @@
  */
 #define VT1724_BUFFER_ALIGN	0x20
 
-static int snd_vt1724_playback_pro_open(snd_pcm_substream_t * substream)
+static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	int chs;
 
 	runtime->private_data = &vt1724_playback_pro_reg;
@@ -776,10 +796,10 @@
 	return 0;
 }
 
-static int snd_vt1724_capture_pro_open(snd_pcm_substream_t * substream)
+static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	runtime->private_data = &vt1724_capture_pro_reg;
 	ice->capture_pro_substream = substream;
@@ -794,9 +814,9 @@
 	return 0;
 }
 
-static int snd_vt1724_playback_pro_close(snd_pcm_substream_t * substream)
+static int snd_vt1724_playback_pro_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	if (PRO_RATE_RESET)
 		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
@@ -805,9 +825,9 @@
 	return 0;
 }
 
-static int snd_vt1724_capture_pro_close(snd_pcm_substream_t * substream)
+static int snd_vt1724_capture_pro_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	if (PRO_RATE_RESET)
 		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
@@ -815,7 +835,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_vt1724_playback_pro_ops = {
+static struct snd_pcm_ops snd_vt1724_playback_pro_ops = {
 	.open =		snd_vt1724_playback_pro_open,
 	.close =	snd_vt1724_playback_pro_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -826,7 +846,7 @@
 	.pointer =	snd_vt1724_playback_pro_pointer,
 };
 
-static snd_pcm_ops_t snd_vt1724_capture_pro_ops = {
+static struct snd_pcm_ops snd_vt1724_capture_pro_ops = {
 	.open =		snd_vt1724_capture_pro_open,
 	.close =	snd_vt1724_capture_pro_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -837,9 +857,9 @@
 	.pointer =	snd_vt1724_pcm_pointer,
 };
 
-static int __devinit snd_vt1724_pcm_profi(ice1712_t * ice, int device)
+static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 * ice, int device)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	err = snd_pcm_new(ice->card, "ICE1724", device, 1, 1, &pcm);
@@ -854,7 +874,8 @@
 	strcpy(pcm->name, "ICE1724");
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-					      snd_dma_pci_data(ice->pci), 256*1024, 256*1024);
+					      snd_dma_pci_data(ice->pci),
+					      256*1024, 256*1024);
 
 	ice->pcm_pro = pcm;
 
@@ -881,7 +902,7 @@
 };
 
 /* update spdif control bits; call with reg_lock */
-static void update_spdif_bits(ice1712_t *ice, unsigned int val)
+static void update_spdif_bits(struct snd_ice1712 *ice, unsigned int val)
 {
 	unsigned char cbit, disabled;
 
@@ -896,7 +917,7 @@
 }
 
 /* update SPDIF control bits according to the given rate */
-static void update_spdif_rate(ice1712_t *ice, unsigned int rate)
+static void update_spdif_rate(struct snd_ice1712 *ice, unsigned int rate)
 {
 	unsigned int val, nval;
 	unsigned long flags;
@@ -918,18 +939,18 @@
 	spin_unlock_irqrestore(&ice->reg_lock, flags);
 }
 
-static int snd_vt1724_playback_spdif_prepare(snd_pcm_substream_t * substream)
+static int snd_vt1724_playback_spdif_prepare(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	if (! ice->force_pdma4)
 		update_spdif_rate(ice, substream->runtime->rate);
 	return snd_vt1724_pcm_prepare(substream);
 }
 
-static int snd_vt1724_playback_spdif_open(snd_pcm_substream_t *substream)
+static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	runtime->private_data = &vt1724_playback_spdif_reg;
 	ice->playback_con_substream = substream;
@@ -947,9 +968,9 @@
 	return 0;
 }
 
-static int snd_vt1724_playback_spdif_close(snd_pcm_substream_t * substream)
+static int snd_vt1724_playback_spdif_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	if (PRO_RATE_RESET)
 		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
@@ -958,10 +979,10 @@
 	return 0;
 }
 
-static int snd_vt1724_capture_spdif_open(snd_pcm_substream_t *substream)
+static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	runtime->private_data = &vt1724_capture_spdif_reg;
 	ice->capture_con_substream = substream;
@@ -979,9 +1000,9 @@
 	return 0;
 }
 
-static int snd_vt1724_capture_spdif_close(snd_pcm_substream_t * substream)
+static int snd_vt1724_capture_spdif_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	if (PRO_RATE_RESET)
 		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
@@ -990,7 +1011,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_vt1724_playback_spdif_ops = {
+static struct snd_pcm_ops snd_vt1724_playback_spdif_ops = {
 	.open =		snd_vt1724_playback_spdif_open,
 	.close =	snd_vt1724_playback_spdif_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1001,7 +1022,7 @@
 	.pointer =	snd_vt1724_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_vt1724_capture_spdif_ops = {
+static struct snd_pcm_ops snd_vt1724_capture_spdif_ops = {
 	.open =		snd_vt1724_capture_spdif_open,
 	.close =	snd_vt1724_capture_spdif_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1013,10 +1034,10 @@
 };
 
 
-static int __devinit snd_vt1724_pcm_spdif(ice1712_t * ice, int device)
+static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device)
 {
 	char *name;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int play, capt;
 	int err;
 
@@ -1055,7 +1076,8 @@
 	strcpy(pcm->name, name);
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-					      snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
+					      snd_dma_pci_data(ice->pci),
+					      64*1024, 64*1024);
 
 	ice->pcm = pcm;
 
@@ -1088,9 +1110,9 @@
 	},
 };
 
-static int snd_vt1724_playback_indep_prepare(snd_pcm_substream_t * substream)
+static int snd_vt1724_playback_indep_prepare(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 	unsigned char val;
 
 	spin_lock_irq(&ice->reg_lock);
@@ -1101,10 +1123,10 @@
 	return snd_vt1724_pcm_prepare(substream);
 }
 
-static int snd_vt1724_playback_indep_open(snd_pcm_substream_t *substream)
+static int snd_vt1724_playback_indep_open(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	down(&ice->open_mutex);
 	/* already used by PDMA0? */
@@ -1122,9 +1144,9 @@
 	return 0;
 }
 
-static int snd_vt1724_playback_indep_close(snd_pcm_substream_t * substream)
+static int snd_vt1724_playback_indep_close(struct snd_pcm_substream *substream)
 {
-	ice1712_t *ice = snd_pcm_substream_chip(substream);
+	struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
 
 	if (PRO_RATE_RESET)
 		snd_vt1724_set_pro_rate(ice, PRO_RATE_DEFAULT, 0);
@@ -1134,7 +1156,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_vt1724_playback_indep_ops = {
+static struct snd_pcm_ops snd_vt1724_playback_indep_ops = {
 	.open =		snd_vt1724_playback_indep_open,
 	.close =	snd_vt1724_playback_indep_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1146,9 +1168,9 @@
 };
 
 
-static int __devinit snd_vt1724_pcm_indep(ice1712_t * ice, int device)
+static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 * ice, int device)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int play;
 	int err;
 
@@ -1168,7 +1190,8 @@
 	strcpy(pcm->name, "ICE1724 Surround PCM");
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
-					      snd_dma_pci_data(ice->pci), 64*1024, 64*1024);
+					      snd_dma_pci_data(ice->pci),
+					      64*1024, 64*1024);
 
 	ice->pcm_ds = pcm;
 
@@ -1180,14 +1203,14 @@
  *  Mixer section
  */
 
-static int __devinit snd_vt1724_ac97_mixer(ice1712_t * ice)
+static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 * ice)
 {
 	int err;
 
 	if (! (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) {
-		ac97_bus_t *pbus;
-		ac97_template_t ac97;
-		static ac97_bus_ops_t ops = {
+		struct snd_ac97_bus *pbus;
+		struct snd_ac97_template ac97;
+		static struct snd_ac97_bus_ops ops = {
 			.write = snd_vt1724_ac97_write,
 			.read = snd_vt1724_ac97_read,
 		};
@@ -1215,17 +1238,17 @@
  *
  */
 
-static inline unsigned int eeprom_triple(ice1712_t *ice, int idx)
+static inline unsigned int eeprom_triple(struct snd_ice1712 *ice, int idx)
 {
 	return (unsigned int)ice->eeprom.data[idx] | \
 		((unsigned int)ice->eeprom.data[idx + 1] << 8) | \
 		((unsigned int)ice->eeprom.data[idx + 2] << 16);
 }
 
-static void snd_vt1724_proc_read(snd_info_entry_t *entry, 
-				 snd_info_buffer_t * buffer)
+static void snd_vt1724_proc_read(struct snd_info_entry *entry, 
+				 struct snd_info_buffer *buffer)
 {
-	ice1712_t *ice = entry->private_data;
+	struct snd_ice1712 *ice = entry->private_data;
 	unsigned int idx;
 
 	snd_iprintf(buffer, "%s\n\n", ice->card->longname);
@@ -1234,28 +1257,39 @@
 	snd_iprintf(buffer, "  Subvendor        : 0x%x\n", ice->eeprom.subvendor);
 	snd_iprintf(buffer, "  Size             : %i bytes\n", ice->eeprom.size);
 	snd_iprintf(buffer, "  Version          : %i\n", ice->eeprom.version);
-	snd_iprintf(buffer, "  System Config    : 0x%x\n", ice->eeprom.data[ICE_EEP2_SYSCONF]);
-	snd_iprintf(buffer, "  ACLink           : 0x%x\n", ice->eeprom.data[ICE_EEP2_ACLINK]);
-	snd_iprintf(buffer, "  I2S              : 0x%x\n", ice->eeprom.data[ICE_EEP2_I2S]);
-	snd_iprintf(buffer, "  S/PDIF           : 0x%x\n", ice->eeprom.data[ICE_EEP2_SPDIF]);
-	snd_iprintf(buffer, "  GPIO direction   : 0x%x\n", ice->eeprom.gpiodir);
-	snd_iprintf(buffer, "  GPIO mask        : 0x%x\n", ice->eeprom.gpiomask);
-	snd_iprintf(buffer, "  GPIO state       : 0x%x\n", ice->eeprom.gpiostate);
+	snd_iprintf(buffer, "  System Config    : 0x%x\n",
+		    ice->eeprom.data[ICE_EEP2_SYSCONF]);
+	snd_iprintf(buffer, "  ACLink           : 0x%x\n",
+		    ice->eeprom.data[ICE_EEP2_ACLINK]);
+	snd_iprintf(buffer, "  I2S              : 0x%x\n",
+		    ice->eeprom.data[ICE_EEP2_I2S]);
+	snd_iprintf(buffer, "  S/PDIF           : 0x%x\n",
+		    ice->eeprom.data[ICE_EEP2_SPDIF]);
+	snd_iprintf(buffer, "  GPIO direction   : 0x%x\n",
+		    ice->eeprom.gpiodir);
+	snd_iprintf(buffer, "  GPIO mask        : 0x%x\n",
+		    ice->eeprom.gpiomask);
+	snd_iprintf(buffer, "  GPIO state       : 0x%x\n",
+		    ice->eeprom.gpiostate);
 	for (idx = 0x12; idx < ice->eeprom.size; idx++)
-		snd_iprintf(buffer, "  Extra #%02i        : 0x%x\n", idx, ice->eeprom.data[idx]);
+		snd_iprintf(buffer, "  Extra #%02i        : 0x%x\n",
+			    idx, ice->eeprom.data[idx]);
 
 	snd_iprintf(buffer, "\nRegisters:\n");
 
-	snd_iprintf(buffer, "  PSDOUT03 : 0x%08x\n", (unsigned)inl(ICEMT1724(ice, ROUTE_PLAYBACK)));
+	snd_iprintf(buffer, "  PSDOUT03 : 0x%08x\n",
+		    (unsigned)inl(ICEMT1724(ice, ROUTE_PLAYBACK)));
 	for (idx = 0x0; idx < 0x20 ; idx++)
-		snd_iprintf(buffer, "  CCS%02x    : 0x%02x\n", idx, inb(ice->port+idx));
+		snd_iprintf(buffer, "  CCS%02x    : 0x%02x\n",
+			    idx, inb(ice->port+idx));
 	for (idx = 0x0; idx < 0x30 ; idx++)
-		snd_iprintf(buffer, "  MT%02x     : 0x%02x\n", idx, inb(ice->profi_port+idx));
+		snd_iprintf(buffer, "  MT%02x     : 0x%02x\n",
+			    idx, inb(ice->profi_port+idx));
 }
 
-static void __devinit snd_vt1724_proc_init(ice1712_t * ice)
+static void __devinit snd_vt1724_proc_init(struct snd_ice1712 * ice)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(ice->card, "ice1724", &entry))
 		snd_info_set_text_ops(entry, ice, 1024, snd_vt1724_proc_read);
@@ -1265,22 +1299,24 @@
  *
  */
 
-static int snd_vt1724_eeprom_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_vt1724_eeprom_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
-	uinfo->count = sizeof(ice1712_eeprom_t);
+	uinfo->count = sizeof(struct snd_ice1712_eeprom);
 	return 0;
 }
 
-static int snd_vt1724_eeprom_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	
 	memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom));
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_vt1724_eeprom __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_CARD,
 	.name = "ICE1724 EEPROM",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1290,21 +1326,23 @@
 
 /*
  */
-static int snd_vt1724_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_vt1724_spdif_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static unsigned int encode_spdif_bits(snd_aes_iec958_t *diga)
+static unsigned int encode_spdif_bits(struct snd_aes_iec958 *diga)
 {
 	unsigned int val, rbits;
 
 	val = diga->status[0] & 0x03; /* professional, non-audio */
 	if (val & 0x01) {
 		/* professional */
-		if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015)
+		if ((diga->status[0] & IEC958_AES0_PRO_EMPHASIS) ==
+		    IEC958_AES0_PRO_EMPHASIS_5015)
 			val |= 1U << 3;
 		rbits = (diga->status[4] >> 3) & 0x0f;
 		if (rbits) {
@@ -1329,7 +1367,8 @@
 	} else {
 		/* consumer */
 		val |= diga->status[1] & 0x04; /* copyright */
-		if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS)== IEC958_AES0_CON_EMPHASIS_5015)
+		if ((diga->status[0] & IEC958_AES0_CON_EMPHASIS) ==
+		    IEC958_AES0_CON_EMPHASIS_5015)
 			val |= 1U << 3;
 		val |= (unsigned int)(diga->status[1] & 0x3f) << 4; /* category */
 		val |= (unsigned int)(diga->status[3] & IEC958_AES3_CON_FS) << 12; /* fs */
@@ -1337,7 +1376,7 @@
 	return val;
 }
 
-static void decode_spdif_bits(snd_aes_iec958_t *diga, unsigned int val)
+static void decode_spdif_bits(struct snd_aes_iec958 *diga, unsigned int val)
 {
 	memset(diga->status, 0, sizeof(diga->status));
 	diga->status[0] = val & 0x03; /* professional, non-audio */
@@ -1365,20 +1404,20 @@
 	}
 }
 
-static int snd_vt1724_spdif_default_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_spdif_default_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	val = inw(ICEMT1724(ice, SPDIF_CTRL));
 	decode_spdif_bits(&ucontrol->value.iec958, val);
 	return 0;
 }
 
-static int snd_vt1724_spdif_default_put(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned int val, old;
 
 	val = encode_spdif_bits(&ucontrol->value.iec958);
@@ -1390,7 +1429,7 @@
 	return (val != old);
 }
 
-static snd_kcontrol_new_t snd_vt1724_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1399,8 +1438,8 @@
 	.put =		snd_vt1724_spdif_default_put
 };
 
-static int snd_vt1724_spdif_maskc_get(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_spdif_maskc_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
 						     IEC958_AES0_PROFESSIONAL |
@@ -1412,8 +1451,8 @@
 	return 0;
 }
 
-static int snd_vt1724_spdif_maskp_get(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO |
 						     IEC958_AES0_PROFESSIONAL |
@@ -1422,7 +1461,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_vt1724_spdif_maskc __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1431,7 +1470,7 @@
 	.get =		snd_vt1724_spdif_maskc_get,
 };
 
-static snd_kcontrol_new_t snd_vt1724_spdif_maskp __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1440,7 +1479,8 @@
 	.get =		snd_vt1724_spdif_maskp_get,
 };
 
-static int snd_vt1724_spdif_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_vt1724_spdif_sw_info(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1449,16 +1489,19 @@
 	return 0;
 }
 
-static int snd_vt1724_spdif_sw_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_spdif_sw_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	ucontrol->value.integer.value[0] = inb(ICEREG1724(ice, SPDIF_CFG)) & VT1724_CFG_SPDIF_OUT_EN ? 1 : 0;
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.integer.value[0] = inb(ICEREG1724(ice, SPDIF_CFG)) &
+		VT1724_CFG_SPDIF_OUT_EN ? 1 : 0;
 	return 0;
 }
 
-static int snd_vt1724_spdif_sw_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char old, val;
 
 	spin_lock_irq(&ice->reg_lock);
@@ -1472,7 +1515,7 @@
 	return old != val;
 }
 
-static snd_kcontrol_new_t snd_vt1724_spdif_switch __devinitdata =
+static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	/* FIXME: the following conflict with IEC958 Playback Route */
@@ -1489,7 +1532,8 @@
  * GPIO access from extern
  */
 
-int snd_vt1724_gpio_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+int snd_vt1724_gpio_info(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1498,21 +1542,24 @@
 	return 0;
 }
 
-int snd_vt1724_gpio_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0;
 	
 	snd_ice1712_save_gpio_status(ice);
-	ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert;
+	ucontrol->value.integer.value[0] =
+		(snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert;
 	snd_ice1712_restore_gpio_status(ice);
 	return 0;
 }
 
-int snd_ice1712_gpio_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int shift = kcontrol->private_value & 0xff;
 	int invert = (kcontrol->private_value & (1<<24)) ? mask : 0;
 	unsigned int val, nval;
@@ -1533,7 +1580,8 @@
 /*
  *  rate
  */
-static int snd_vt1724_pro_internal_clock_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
+					      struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts_1724[] = {
 		"8000",		/* 0: 6 */
@@ -1569,7 +1617,7 @@
 		"96000",	/* 12: 7 */
 		"IEC958 Input",	/* 13: -- */
 	};
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -1582,9 +1630,10 @@
 	return 0;
 }
 
-static int snd_vt1724_pro_internal_clock_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	static unsigned char xlate[16] = {
 		9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 13, 255, 14, 10
 	};
@@ -1605,9 +1654,10 @@
 	return 0;
 }
 
-static int snd_vt1724_pro_internal_clock_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char oval;
 	int rate;
 	int change = 0;
@@ -1629,7 +1679,8 @@
 	change = inb(ICEMT1724(ice, RATE)) != oval;
 	spin_unlock_irq(&ice->reg_lock);
 
-	if ((oval & VT1724_SPDIF_MASTER) != (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER)) {
+	if ((oval & VT1724_SPDIF_MASTER) !=
+	    (inb(ICEMT1724(ice, RATE)) & VT1724_SPDIF_MASTER)) {
 		/* notify akm chips as well */
 		if (is_spdif_master(ice)) {
 			unsigned int i;
@@ -1642,7 +1693,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_vt1724_pro_internal_clock __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Internal Clock",
 	.info = snd_vt1724_pro_internal_clock_info,
@@ -1650,7 +1701,8 @@
 	.put = snd_vt1724_pro_internal_clock_put
 };
 
-static int snd_vt1724_pro_rate_locking_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_vt1724_pro_rate_locking_info(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1659,15 +1711,17 @@
 	return 0;
 }
 
-static int snd_vt1724_pro_rate_locking_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_pro_rate_locking_get(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.integer.value[0] = PRO_RATE_LOCKED;
 	return 0;
 }
 
-static int snd_vt1724_pro_rate_locking_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change = 0, nval;
 
 	nval = ucontrol->value.integer.value[0] ? 1 : 0;
@@ -1678,7 +1732,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_vt1724_pro_rate_locking __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Rate Locking",
 	.info = snd_vt1724_pro_rate_locking_info,
@@ -1686,7 +1740,8 @@
 	.put = snd_vt1724_pro_rate_locking_put
 };
 
-static int snd_vt1724_pro_rate_reset_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_vt1724_pro_rate_reset_info(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1695,15 +1750,17 @@
 	return 0;
 }
 
-static int snd_vt1724_pro_rate_reset_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_pro_rate_reset_get(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.integer.value[0] = PRO_RATE_RESET ? 1 : 0;
 	return 0;
 }
 
-static int snd_vt1724_pro_rate_reset_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change = 0, nval;
 
 	nval = ucontrol->value.integer.value[0] ? 1 : 0;
@@ -1714,7 +1771,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_vt1724_pro_rate_reset __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Rate Reset",
 	.info = snd_vt1724_pro_rate_reset_info,
@@ -1726,7 +1783,8 @@
 /*
  * routing
  */
-static int snd_vt1724_pro_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {
 		"PCM Out", /* 0 */
@@ -1753,7 +1811,7 @@
 	return idx * 3;
 }
 
-static int get_route_val(ice1712_t *ice, int shift)
+static int get_route_val(struct snd_ice1712 *ice, int shift)
 {
 	unsigned long val;
 	unsigned char eitem;
@@ -1772,7 +1830,7 @@
 	return eitem;
 }
 
-static int put_route_val(ice1712_t *ice, unsigned int val, int shift)
+static int put_route_val(struct snd_ice1712 *ice, unsigned int val, int shift)
 {
 	unsigned int old_val, nval;
 	int change;
@@ -1794,39 +1852,45 @@
 	return change;
 }
 
-static int snd_vt1724_pro_route_analog_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_vt1724_pro_route_analog_get(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-	ucontrol->value.enumerated.item[0] = get_route_val(ice, analog_route_shift(idx));
+	ucontrol->value.enumerated.item[0] =
+		get_route_val(ice, analog_route_shift(idx));
 	return 0;
 }
 
-static int snd_vt1724_pro_route_analog_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_vt1724_pro_route_analog_put(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	return put_route_val(ice, ucontrol->value.enumerated.item[0],
 			     analog_route_shift(idx));
 }
 
-static int snd_vt1724_pro_route_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_vt1724_pro_route_spdif_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
-	ucontrol->value.enumerated.item[0] = get_route_val(ice, digital_route_shift(idx));
+	ucontrol->value.enumerated.item[0] =
+		get_route_val(ice, digital_route_shift(idx));
 	return 0;
 }
 
-static int snd_vt1724_pro_route_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 	return put_route_val(ice, ucontrol->value.enumerated.item[0],
 			     digital_route_shift(idx));
 }
 
-static snd_kcontrol_new_t snd_vt1724_mixer_pro_analog_route __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "H/W Playback Route",
 	.info = snd_vt1724_pro_route_info,
@@ -1834,7 +1898,7 @@
 	.put = snd_vt1724_pro_route_analog_put,
 };
 
-static snd_kcontrol_new_t snd_vt1724_mixer_pro_spdif_route __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
 	.info = snd_vt1724_pro_route_info,
@@ -1844,7 +1908,8 @@
 };
 
 
-static int snd_vt1724_pro_peak_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_vt1724_pro_peak_info(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 22; /* FIXME: for compatibility with ice1712... */
@@ -1853,21 +1918,23 @@
 	return 0;
 }
 
-static int snd_vt1724_pro_peak_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx;
 	
 	spin_lock_irq(&ice->reg_lock);
 	for (idx = 0; idx < 22; idx++) {
 		outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX));
-		ucontrol->value.integer.value[idx] = inb(ICEMT1724(ice, MONITOR_PEAKDATA));
+		ucontrol->value.integer.value[idx] =
+			inb(ICEMT1724(ice, MONITOR_PEAKDATA));
 	}
 	spin_unlock_irq(&ice->reg_lock);
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_vt1724_mixer_pro_peak __devinitdata = {
+static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Multi Track Peak",
 	.access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -1897,7 +1964,7 @@
 /*
  */
 
-static void wait_i2c_busy(ice1712_t *ice)
+static void wait_i2c_busy(struct snd_ice1712 *ice)
 {
 	int t = 0x10000;
 	while ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_BUSY) && t--)
@@ -1906,7 +1973,8 @@
 		printk(KERN_ERR "ice1724: i2c busy timeout\n");
 }
 
-unsigned char snd_vt1724_read_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr)
+unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice,
+				  unsigned char dev, unsigned char addr)
 {
 	unsigned char val;
 
@@ -1920,7 +1988,8 @@
 	return val;
 }
 
-void snd_vt1724_write_i2c(ice1712_t *ice, unsigned char dev, unsigned char addr, unsigned char data)
+void snd_vt1724_write_i2c(struct snd_ice1712 *ice,
+			  unsigned char dev, unsigned char addr, unsigned char data)
 {
 	down(&ice->i2c_mutex);
 	wait_i2c_busy(ice);
@@ -1932,7 +2001,8 @@
 	up(&ice->i2c_mutex);
 }
 
-static int __devinit snd_vt1724_read_eeprom(ice1712_t *ice, const char *modelname)
+static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
+					    const char *modelname)
 {
 	const int dev = 0xa0;		/* EEPROM device address */
 	unsigned int i, size;
@@ -1946,13 +2016,19 @@
 				(snd_vt1724_read_i2c(ice, dev, 0x01) << 8) | 
 				(snd_vt1724_read_i2c(ice, dev, 0x02) << 16) | 
 				(snd_vt1724_read_i2c(ice, dev, 0x03) << 24);
-		if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
-			/* invalid subvendor from EEPROM, try the PCI subststem ID instead */
+		if (ice->eeprom.subvendor == 0 ||
+		    ice->eeprom.subvendor == (unsigned int)-1) {
+			/* invalid subvendor from EEPROM, try the PCI
+			 * subststem ID instead
+			 */
 			u16 vendor, device;
-			pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID, &vendor);
+			pci_read_config_word(ice->pci, PCI_SUBSYSTEM_VENDOR_ID,
+					     &vendor);
 			pci_read_config_word(ice->pci, PCI_SUBSYSTEM_ID, &device);
-			ice->eeprom.subvendor = ((unsigned int)swab16(vendor) << 16) | swab16(device);
-			if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) {
+			ice->eeprom.subvendor =
+				((unsigned int)swab16(vendor) << 16) | swab16(device);
+			if (ice->eeprom.subvendor == 0 ||
+			    ice->eeprom.subvendor == (unsigned int)-1) {
 				printk(KERN_ERR "ice1724: No valid ID is found\n");
 				return -ENXIO;
 			}
@@ -1960,8 +2036,10 @@
 	}
 	for (tbl = card_tables; *tbl; tbl++) {
 		for (c = *tbl; c->subvendor; c++) {
-			if (modelname && c->model && ! strcmp(modelname, c->model)) {
-				printk(KERN_INFO "ice1724: Using board model %s\n", c->name);
+			if (modelname && c->model &&
+			    ! strcmp(modelname, c->model)) {
+				printk(KERN_INFO "ice1724: Using board model %s\n",
+				       c->name);
 				ice->eeprom.subvendor = c->subvendor;
 			} else if (c->subvendor != ice->eeprom.subvendor)
 				continue;
@@ -1975,19 +2053,22 @@
 			goto read_skipped;
 		}
 	}
-	printk(KERN_WARNING "ice1724: No matching model found for ID 0x%x\n", ice->eeprom.subvendor);
+	printk(KERN_WARNING "ice1724: No matching model found for ID 0x%x\n",
+	       ice->eeprom.subvendor);
 
  found:
 	ice->eeprom.size = snd_vt1724_read_i2c(ice, dev, 0x04);
 	if (ice->eeprom.size < 6)
 		ice->eeprom.size = 32;
 	else if (ice->eeprom.size > 32) {
-		printk(KERN_ERR "ice1724: Invalid EEPROM (size = %i)\n", ice->eeprom.size);
+		printk(KERN_ERR "ice1724: Invalid EEPROM (size = %i)\n",
+		       ice->eeprom.size);
 		return -EIO;
 	}
 	ice->eeprom.version = snd_vt1724_read_i2c(ice, dev, 0x05);
 	if (ice->eeprom.version != 2)
-		printk(KERN_WARNING "ice1724: Invalid EEPROM version %i\n", ice->eeprom.version);
+		printk(KERN_WARNING "ice1724: Invalid EEPROM version %i\n",
+		       ice->eeprom.version);
 	size = ice->eeprom.size - 6;
 	for (i = 0; i < size; i++)
 		ice->eeprom.data[i] = snd_vt1724_read_i2c(ice, dev, i + 6);
@@ -2002,7 +2083,7 @@
 
 
 
-static int __devinit snd_vt1724_chip_init(ice1712_t *ice)
+static int __devinit snd_vt1724_chip_init(struct snd_ice1712 *ice)
 {
 	outb(VT1724_RESET , ICEREG1724(ice, CONTROL));
 	udelay(200);
@@ -2024,10 +2105,10 @@
 	return 0;
 }
 
-static int __devinit snd_vt1724_spdif_build_controls(ice1712_t *ice)
+static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice)
 {
 	int err;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	snd_assert(ice->pcm != NULL, return -EIO);
 
@@ -2062,7 +2143,7 @@
 }
 
 
-static int __devinit snd_vt1724_build_controls(ice1712_t *ice)
+static int __devinit snd_vt1724_build_controls(struct snd_ice1712 *ice)
 {
 	int err;
 
@@ -2081,7 +2162,7 @@
 		return err;
 
 	if (ice->num_total_dacs > 0) {
-		snd_kcontrol_new_t tmp = snd_vt1724_mixer_pro_analog_route;
+		struct snd_kcontrol_new tmp = snd_vt1724_mixer_pro_analog_route;
 		tmp.count = ice->num_total_dacs;
 		if (ice->vt1720 && tmp.count > 2)
 			tmp.count = 2;
@@ -2097,7 +2178,7 @@
 	return 0;
 }
 
-static int snd_vt1724_free(ice1712_t *ice)
+static int snd_vt1724_free(struct snd_ice1712 *ice)
 {
 	if (! ice->port)
 		goto __hw_end;
@@ -2108,7 +2189,7 @@
       __hw_end:
 	if (ice->irq >= 0) {
 		synchronize_irq(ice->irq);
-		free_irq(ice->irq, (void *) ice);
+		free_irq(ice->irq, ice);
 	}
 	pci_release_regions(ice->pci);
 	snd_ice1712_akm4xxx_free(ice);
@@ -2117,21 +2198,21 @@
 	return 0;
 }
 
-static int snd_vt1724_dev_free(snd_device_t *device)
+static int snd_vt1724_dev_free(struct snd_device *device)
 {
-	ice1712_t *ice = device->device_data;
+	struct snd_ice1712 *ice = device->device_data;
 	return snd_vt1724_free(ice);
 }
 
-static int __devinit snd_vt1724_create(snd_card_t * card,
+static int __devinit snd_vt1724_create(struct snd_card *card,
 				       struct pci_dev *pci,
 				       const char *modelname,
-				       ice1712_t ** r_ice1712)
+				       struct snd_ice1712 ** r_ice1712)
 {
-	ice1712_t *ice;
+	struct snd_ice1712 *ice;
 	int err;
 	unsigned char mask;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_vt1724_dev_free,
 	};
 
@@ -2170,7 +2251,8 @@
 	ice->port = pci_resource_start(pci, 0);
 	ice->profi_port = pci_resource_start(pci, 1);
 
-	if (request_irq(pci->irq, snd_vt1724_interrupt, SA_INTERRUPT|SA_SHIRQ, "ICE1724", (void *) ice)) {
+	if (request_irq(pci->irq, snd_vt1724_interrupt,
+			SA_INTERRUPT|SA_SHIRQ, "ICE1724", ice)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_vt1724_free(ice);
 		return -EIO;
@@ -2193,7 +2275,9 @@
 	else
 		mask = 0;
 	outb(mask, ICEREG1724(ice, IRQMASK));
-	/* don't handle FIFO overrun/underruns (just yet), since they cause machine lockups */
+	/* don't handle FIFO overrun/underruns (just yet),
+	 * since they cause machine lockups
+	 */
 	outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) {
@@ -2218,8 +2302,8 @@
 				      const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	ice1712_t *ice;
+	struct snd_card *card;
+	struct snd_ice1712 *ice;
 	int pcm_dev = 0, err;
 	struct snd_ice1712_card_info **tbl, *c;
 
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 2437876..5176b41 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -65,30 +65,30 @@
 
 static void juli_ak4114_write(void *private_data, unsigned char reg, unsigned char val)
 {
-	snd_vt1724_write_i2c((ice1712_t *)private_data, AK4114_ADDR, reg, val);
+	snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, reg, val);
 }
         
 static unsigned char juli_ak4114_read(void *private_data, unsigned char reg)
 {
-	return snd_vt1724_read_i2c((ice1712_t *)private_data, AK4114_ADDR, reg);
+	return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, reg);
 }
 
 /*
  * AK4358 section
  */
 
-static void juli_akm_lock(akm4xxx_t *ak, int chip)
+static void juli_akm_lock(struct snd_akm4xxx *ak, int chip)
 {
 }
 
-static void juli_akm_unlock(akm4xxx_t *ak, int chip)
+static void juli_akm_unlock(struct snd_akm4xxx *ak, int chip)
 {
 }
 
-static void juli_akm_write(akm4xxx_t *ak, int chip,
+static void juli_akm_write(struct snd_akm4xxx *ak, int chip,
 			   unsigned char addr, unsigned char data)
 {
-	ice1712_t *ice = ak->private_data[0];
+	struct snd_ice1712 *ice = ak->private_data[0];
 	 
 	snd_assert(chip == 0, return);
 	snd_vt1724_write_i2c(ice, AK4358_ADDR, addr, data);
@@ -97,7 +97,7 @@
 /*
  * change the rate of envy24HT, AK4358
  */
-static void juli_akm_set_rate_val(akm4xxx_t *ak, unsigned int rate)
+static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
 {
 	unsigned char old, tmp, dfs;
 
@@ -125,7 +125,7 @@
 	snd_akm4xxx_reset(ak, 0);
 }
 
-static akm4xxx_t akm_juli_dac __devinitdata = {
+static struct snd_akm4xxx akm_juli_dac __devinitdata = {
 	.type = SND_AK4358,
 	.num_dacs = 2,
 	.ops = {
@@ -136,7 +136,7 @@
 	}
 };
 
-static int __devinit juli_add_controls(ice1712_t *ice)
+static int __devinit juli_add_controls(struct snd_ice1712 *ice)
 {
 	return snd_ice1712_akm4xxx_build_controls(ice);
 }
@@ -144,7 +144,7 @@
 /*
  * initialize the chip
  */
-static int __devinit juli_init(ice1712_t *ice)
+static int __devinit juli_init(struct snd_ice1712 *ice)
 {
 	static unsigned char ak4114_init_vals[] = {
 		/* AK4117_REG_PWRDN */	AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
@@ -158,7 +158,7 @@
 		0x41, 0x02, 0x2c, 0x00, 0x00
 	};
 	int err;
-	akm4xxx_t *ak;
+	struct snd_akm4xxx *ak;
 
 #if 0
 	for (err = 0; err < 0x20; err++)
@@ -175,14 +175,21 @@
 	if (err < 0)
 		return err;
 
-	ice->spec.juli.analog = ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT;
+#if 0
+        /* it seems that the analog doughter board detection does not work
+           reliably, so force the analog flag; it should be very rare
+           to use Juli@ without the analog doughter board */
+	ice->spec.juli.analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1;
+#else
+        ice->spec.juli.analog = 1;
+#endif
 
 	if (ice->spec.juli.analog) {
 		printk(KERN_INFO "juli@: analog I/O detected\n");
 		ice->num_total_dacs = 2;
 		ice->num_total_adcs = 2;
 
-		ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+		ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 		if (! ak)
 			return -ENOMEM;
 		ice->akm_codecs = 1;
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index dcf1e8c..ec37578 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -86,7 +86,7 @@
 #define WM_VOL_MAX	(sizeof(wm_vol) - 1)
 #define WM_VOL_MUTE	0x8000
 
-static akm4xxx_t akm_phase22 __devinitdata = {
+static struct snd_akm4xxx akm_phase22 __devinitdata = {
 	.type = SND_AK4524,
 	.num_dacs = 2,
 	.num_adcs = 2,
@@ -104,9 +104,9 @@
 	.mask_flags =	0,
 };
 
-static int __devinit phase22_init(ice1712_t *ice)
+static int __devinit phase22_init(struct snd_ice1712 *ice)
 {
-	akm4xxx_t *ak;
+	struct snd_akm4xxx *ak;
 	int err;
 
 	// Configure DAC/ADC description for generic part of ice1724
@@ -122,7 +122,7 @@
 	}
 
 	// Initialize analog chips
-	ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+	ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (! ak)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
@@ -136,7 +136,7 @@
 	return 0;
 }
 
-static int __devinit phase22_add_controls(ice1712_t *ice)
+static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
 {
 	int err = 0;
 
@@ -184,7 +184,7 @@
 /*
  * write data in the SPI mode
  */
-static void phase28_spi_write(ice1712_t *ice, unsigned int cs, unsigned int data, int bits)
+static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits)
 {
 	unsigned int tmp;
 	int i;
@@ -225,7 +225,7 @@
 /*
  * get the current register value of WM codec
  */
-static unsigned short wm_get(ice1712_t *ice, int reg)
+static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
 {
 	reg <<= 1;
 	return ((unsigned short)ice->akm[0].images[reg] << 8) |
@@ -235,7 +235,7 @@
 /*
  * set the register value of WM codec
  */
-static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
+static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
 {
 	phase28_spi_write(ice, PHASE28_WM_CS, (reg << 9) | (val & 0x1ff), 16);
 }
@@ -243,7 +243,7 @@
 /*
  * set the register value of WM codec and remember it
  */
-static void wm_put(ice1712_t *ice, int reg, unsigned short val)
+static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
 {
 	wm_put_nocache(ice, reg, val);
 	reg <<= 1;
@@ -251,7 +251,7 @@
 	ice->akm[0].images[reg + 1] = val;
 }
 
-static void wm_set_vol(ice1712_t *ice, unsigned int index, unsigned short vol, unsigned short master)
+static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
 {
 	unsigned char nvol;
 
@@ -269,9 +269,9 @@
  */
 #define wm_pcm_mute_info	phase28_mono_bool_info
 
-static int wm_pcm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	down(&ice->gpio_mutex);
 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1;
@@ -279,9 +279,9 @@
 	return 0;
 }
 
-static int wm_pcm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short nval, oval;
 	int change;
 
@@ -298,7 +298,7 @@
 /*
  * Master volume attenuation mixer control
  */
-static int wm_master_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -307,18 +307,18 @@
 	return 0;
 }
 
-static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i;
 	for (i=0; i<2; i++)
 		ucontrol->value.integer.value[i] = ice->spec.phase28.master[i] & ~WM_VOL_MUTE;
 	return 0;
 }
 
-static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int ch, change = 0;
 
 	snd_ice1712_save_gpio_status(ice);
@@ -338,7 +338,7 @@
 	return change;
 }
 
-static int __devinit phase28_init(ice1712_t *ice)
+static int __devinit phase28_init(struct snd_ice1712 *ice)
 {
 	static unsigned short wm_inits_phase28[] = {
 		/* These come first to reduce init pop noise */
@@ -378,7 +378,7 @@
 	};
 
 	unsigned int tmp;
-	akm4xxx_t *ak;
+	struct snd_akm4xxx *ak;
 	unsigned short *p;
 	int i;
 
@@ -386,7 +386,7 @@
 	ice->num_total_adcs = 2;
 
 	// Initialize analog chips
-	ak = ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+	ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (!ak)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
@@ -427,7 +427,7 @@
 /*
  * DAC volume attenuation mixer control
  */
-static int wm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int voices = kcontrol->private_value >> 8;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -437,9 +437,9 @@
 	return 0;
 }
 
-static int wm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i, ofs, voices;
 
 	voices = kcontrol->private_value >> 8;
@@ -449,9 +449,9 @@
 	return 0;
 }
 
-static int wm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i, idx, ofs, voices;
 	int change = 0;
 
@@ -475,7 +475,7 @@
 /*
  * WM8770 mute control
  */
-static int wm_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = kcontrol->private_value >> 8;
 	uinfo->value.integer.min = 0;
@@ -483,9 +483,9 @@
 	return 0;
 }
 
-static int wm_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int voices, ofs, i;
 
 	voices = kcontrol->private_value >> 8;
@@ -496,9 +496,9 @@
 	return 0;
 }
 
-static int wm_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change = 0, voices, ofs, i;
 
 	voices = kcontrol->private_value >> 8;
@@ -524,7 +524,7 @@
 /*
  * WM8770 master mute control
  */
-static int wm_master_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) {
+static int wm_master_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
 	uinfo->value.integer.min = 0;
@@ -532,18 +532,18 @@
 	return 0;
 }
 
-static int wm_master_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.integer.value[0] = (ice->spec.phase28.master[0] & WM_VOL_MUTE) ? 0 : 1;
 	ucontrol->value.integer.value[1] = (ice->spec.phase28.master[1] & WM_VOL_MUTE) ? 0 : 1;
 	return 0;
 }
 
-static int wm_master_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int change = 0, i;
 
 	snd_ice1712_save_gpio_status(ice);
@@ -570,7 +570,7 @@
 #define PCM_0dB 0xff
 #define PCM_RES 128	/* -64dB */
 #define PCM_MIN (PCM_0dB - PCM_RES)
-static int wm_pcm_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -579,9 +579,9 @@
 	return 0;
 }
 
-static int wm_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 
 	down(&ice->gpio_mutex);
@@ -592,9 +592,9 @@
 	return 0;
 }
 
-static int wm_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short ovol, nvol;
 	int change = 0;
 
@@ -613,7 +613,7 @@
 
 /*
  */
-static int phase28_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+static int phase28_mono_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -627,16 +627,16 @@
  */
 #define phase28_deemp_info	phase28_mono_bool_info
 
-static int phase28_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int phase28_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
 	return 0;
 }
 
-static int phase28_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int phase28_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int temp, temp2;
 	temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
 	if (ucontrol->value.integer.value[0])
@@ -653,7 +653,7 @@
 /*
  * ADC Oversampling
  */
-static int phase28_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+static int phase28_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = { "128x", "64x"	};
 
@@ -668,17 +668,17 @@
         return 0;
 }
 
-static int phase28_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
 	return 0;
 }
 
-static int phase28_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	int temp, temp2;
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	temp2 = temp = wm_get(ice, WM_MASTER);
 
@@ -694,7 +694,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t phase28_dac_controls[] __devinitdata = {
+static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -791,7 +791,7 @@
 	}
 };
 
-static snd_kcontrol_new_t wm_controls[] __devinitdata = {
+static struct snd_kcontrol_new wm_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "PCM Playback Switch",
@@ -822,7 +822,7 @@
 	}
 };
 
-static int __devinit phase28_add_controls(ice1712_t *ice)
+static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i, counts;
 	int err;
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 773a1ec..0dccd77 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -76,7 +76,7 @@
 /*
  * get the current register value of WM codec
  */
-static unsigned short wm_get(ice1712_t *ice, int reg)
+static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
 {
 	reg <<= 1;
 	return ((unsigned short)ice->akm[0].images[reg] << 8) |
@@ -86,14 +86,14 @@
 /*
  * set the register value of WM codec and remember it
  */
-static void wm_put_nocache(ice1712_t *ice, int reg, unsigned short val)
+static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
 {
 	unsigned short cval;
 	cval = (reg << 9) | val;
 	snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
 }
 
-static void wm_put(ice1712_t *ice, int reg, unsigned short val)
+static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
 {
 	wm_put_nocache(ice, reg, val);
 	reg <<= 1;
@@ -109,7 +109,7 @@
 #define DAC_RES	128
 #define DAC_MIN	(DAC_0dB - DAC_RES)
 
-static int wm_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -118,9 +118,9 @@
 	return 0;
 }
 
-static int wm_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 	int i;
 
@@ -134,9 +134,9 @@
 	return 0;
 }
 
-static int wm_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short oval, nval;
 	int i, idx, change = 0;
 
@@ -164,7 +164,7 @@
 #define ADC_RES	128
 #define ADC_MIN	(ADC_0dB - ADC_RES)
 
-static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -173,9 +173,9 @@
 	return 0;
 }
 
-static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
 	int i;
 
@@ -189,9 +189,9 @@
 	return 0;
 }
 
-static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short ovol, nvol;
 	int i, idx, change = 0;
 
@@ -213,7 +213,7 @@
 /*
  * ADC input mux mixer control
  */
-static int wm_adc_mux_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -222,9 +222,9 @@
 	return 0;
 }
 
-static int wm_adc_mux_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_adc_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int bit = kcontrol->private_value;
 
 	down(&ice->gpio_mutex);
@@ -233,9 +233,9 @@
 	return 0;
 }
 
-static int wm_adc_mux_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int bit = kcontrol->private_value;
 	unsigned short oval, nval;
 	int change;
@@ -257,7 +257,7 @@
 /*
  * Analog bypass (In -> Out)
  */
-static int wm_bypass_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_bypass_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -266,9 +266,9 @@
 	return 0;
 }
 
-static int wm_bypass_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_bypass_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	down(&ice->gpio_mutex);
 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
@@ -276,9 +276,9 @@
 	return 0;
 }
 
-static int wm_bypass_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_bypass_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val, oval;
 	int change = 0;
 
@@ -299,7 +299,7 @@
 /*
  * Left/Right swap
  */
-static int wm_chswap_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int wm_chswap_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -308,9 +308,9 @@
 	return 0;
 }
 
-static int wm_chswap_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_chswap_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	down(&ice->gpio_mutex);
 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
@@ -318,9 +318,9 @@
 	return 0;
 }
 
-static int wm_chswap_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int wm_chswap_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val, oval;
 	int change = 0;
 
@@ -343,7 +343,7 @@
 /*
  * write data in the SPI mode
  */
-static void set_gpio_bit(ice1712_t *ice, unsigned int bit, int val)
+static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
 {
 	unsigned int tmp = snd_ice1712_gpio_read(ice);
 	if (val)
@@ -353,7 +353,7 @@
 	snd_ice1712_gpio_write(ice, tmp);
 }
 
-static void spi_send_byte(ice1712_t *ice, unsigned char data)
+static void spi_send_byte(struct snd_ice1712 *ice, unsigned char data)
 {
 	int i;
 	for (i = 0; i < 8; i++) {
@@ -367,7 +367,7 @@
 	}
 }
 
-static unsigned int spi_read_byte(ice1712_t *ice)
+static unsigned int spi_read_byte(struct snd_ice1712 *ice)
 {
 	int i;
 	unsigned int val = 0;
@@ -386,7 +386,7 @@
 }
 
 
-static void spi_write(ice1712_t *ice, unsigned int dev, unsigned int reg, unsigned int data)
+static void spi_write(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg, unsigned int data)
 {
 	snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
 	snd_ice1712_gpio_set_mask(ice, ~(PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK));
@@ -402,7 +402,7 @@
 	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
 }
 
-static unsigned int spi_read(ice1712_t *ice, unsigned int dev, unsigned int reg)
+static unsigned int spi_read(struct snd_ice1712 *ice, unsigned int dev, unsigned int reg)
 {
 	unsigned int val;
 	snd_ice1712_gpio_set_dir(ice, PONTIS_CS_CS|PONTIS_CS_WDATA|PONTIS_CS_CLK);
@@ -429,7 +429,7 @@
 /*
  * SPDIF input source
  */
-static int cs_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {
 		"Coax",		/* RXP0 */
@@ -445,9 +445,9 @@
 	return 0;
 }
 
-static int cs_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int cs_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	down(&ice->gpio_mutex);
 	ucontrol->value.enumerated.item[0] = ice->gpio.saved[0];
@@ -455,9 +455,9 @@
 	return 0;
 }
 
-static int cs_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int cs_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char val;
 	int change = 0;
 
@@ -476,7 +476,7 @@
 /*
  * GPIO controls
  */
-static int pontis_gpio_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int pontis_gpio_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -485,9 +485,9 @@
 	return 0;
 }
 
-static int pontis_gpio_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int pontis_gpio_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	down(&ice->gpio_mutex);
 	/* 4-7 reserved */
 	ucontrol->value.integer.value[0] = (~ice->gpio.write_mask & 0xffff) | 0x00f0;
@@ -495,9 +495,9 @@
 	return 0;
 }
 	
-static int pontis_gpio_mask_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int pontis_gpio_mask_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int changed;
 	down(&ice->gpio_mutex);
@@ -509,9 +509,9 @@
 	return changed;
 }
 
-static int pontis_gpio_dir_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int pontis_gpio_dir_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	down(&ice->gpio_mutex);
 	/* 4-7 reserved */
 	ucontrol->value.integer.value[0] = ice->gpio.direction & 0xff0f;
@@ -519,9 +519,9 @@
 	return 0;
 }
 	
-static int pontis_gpio_dir_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int pontis_gpio_dir_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int changed;
 	down(&ice->gpio_mutex);
@@ -533,9 +533,9 @@
 	return changed;
 }
 
-static int pontis_gpio_data_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int pontis_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	down(&ice->gpio_mutex);
 	snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
 	snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
@@ -544,9 +544,9 @@
 	return 0;
 }
 
-static int pontis_gpio_data_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned int val, nval;
 	int changed = 0;
 	down(&ice->gpio_mutex);
@@ -566,7 +566,7 @@
  * mixers
  */
 
-static snd_kcontrol_new_t pontis_controls[] __devinitdata = {
+static struct snd_kcontrol_new pontis_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "PCM Playback Volume",
@@ -646,9 +646,9 @@
 /*
  * WM codec registers
  */
-static void wm_proc_regs_write(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void wm_proc_regs_write(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	ice1712_t *ice = (ice1712_t *)entry->private_data;
+	struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data;
 	char line[64];
 	unsigned int reg, val;
 	down(&ice->gpio_mutex);
@@ -661,9 +661,9 @@
 	up(&ice->gpio_mutex);
 }
 
-static void wm_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void wm_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	ice1712_t *ice = (ice1712_t *)entry->private_data;
+	struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data;
 	int reg, val;
 
 	down(&ice->gpio_mutex);
@@ -674,9 +674,9 @@
 	up(&ice->gpio_mutex);
 }
 
-static void wm_proc_init(ice1712_t *ice)
+static void wm_proc_init(struct snd_ice1712 *ice)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	if (! snd_card_proc_new(ice->card, "wm_codec", &entry)) {
 		snd_info_set_text_ops(entry, ice, 1024, wm_proc_regs_read);
 		entry->mode |= S_IWUSR;
@@ -685,9 +685,9 @@
 	}
 }
 
-static void cs_proc_regs_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void cs_proc_regs_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	ice1712_t *ice = (ice1712_t *)entry->private_data;
+	struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data;
 	int reg, val;
 
 	down(&ice->gpio_mutex);
@@ -700,16 +700,16 @@
 	up(&ice->gpio_mutex);
 }
 
-static void cs_proc_init(ice1712_t *ice)
+static void cs_proc_init(struct snd_ice1712 *ice)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	if (! snd_card_proc_new(ice->card, "cs_codec", &entry)) {
 		snd_info_set_text_ops(entry, ice, 1024, cs_proc_regs_read);
 	}
 }
 
 
-static int __devinit pontis_add_controls(ice1712_t *ice)
+static int __devinit pontis_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i;
 	int err;
@@ -730,7 +730,7 @@
 /*
  * initialize the chip
  */
-static int __devinit pontis_init(ice1712_t *ice)
+static int __devinit pontis_init(struct snd_ice1712 *ice)
 {
 	static unsigned short wm_inits[] = {
 		/* These come first to reduce init pop noise */
@@ -781,7 +781,7 @@
 	ice->num_total_adcs = 2;
 
 	/* to remeber the register values */
-	ice->akm = kzalloc(sizeof(akm4xxx_t), GFP_KERNEL);
+	ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (! ice->akm)
 		return -ENOMEM;
 	ice->akm_codecs = 1;
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index d2c5963..fdb5cb8 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -36,12 +36,12 @@
 #include "prodigy192.h"
 #include "stac946x.h"
 
-static inline void stac9460_put(ice1712_t *ice, int reg, unsigned char val)
+static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val)
 {
 	snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
 }
 
-static inline unsigned char stac9460_get(ice1712_t *ice, int reg)
+static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
 {
 	return snd_vt1724_read_i2c(ice, PRODIGY192_STAC9460_ADDR, reg);
 }
@@ -49,7 +49,7 @@
 /*
  * DAC mute control
  */
-static int stac9460_dac_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int stac9460_dac_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -58,9 +58,9 @@
 	return 0;
 }
 
-static int stac9460_dac_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char val;
 	int idx;
 
@@ -73,9 +73,9 @@
 	return 0;
 }
 
-static int stac9460_dac_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char new, old;
 	int idx;
 	int change;
@@ -96,7 +96,7 @@
 /*
  * DAC volume attenuation mixer control
  */
-static int stac9460_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -105,9 +105,9 @@
 	return 0;
 }
 
-static int stac9460_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx;
 	unsigned char vol;
 
@@ -121,9 +121,9 @@
 	return 0;
 }
 
-static int stac9460_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int idx;
 	unsigned char tmp, ovol, nvol;
 	int change;
@@ -145,7 +145,7 @@
 /*
  * ADC mute control
  */
-static int stac9460_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int stac9460_adc_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -154,9 +154,9 @@
 	return 0;
 }
 
-static int stac9460_adc_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char val;
 	int i;
 
@@ -168,9 +168,9 @@
 	return 0;
 }
 
-static int stac9460_adc_mute_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	unsigned char new, old;
 	int i, reg;
 	int change;
@@ -190,7 +190,7 @@
 /*
  * ADC gain mixer control
  */
-static int stac9460_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -199,9 +199,9 @@
 	return 0;
 }
 
-static int stac9460_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i, reg;
 	unsigned char vol;
 
@@ -214,9 +214,9 @@
 	return 0;
 }
 
-static int stac9460_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int i, reg;
 	unsigned char ovol, nvol;
 	int change;
@@ -237,7 +237,7 @@
 /*
  * Headphone Amplifier
  */
-static int aureon_set_headphone_amp(ice1712_t *ice, int enable)
+static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
 {
 	unsigned int tmp, tmp2;
 
@@ -253,14 +253,14 @@
 	return 0;
 }
 
-static int aureon_get_headphone_amp(ice1712_t *ice)
+static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
 {
 	unsigned int tmp = snd_ice1712_gpio_read(ice);
 
 	return ( tmp & AUREON_HP_SEL )!= 0;
 }
 
-static int aureon_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+static int aureon_bool_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -269,18 +269,18 @@
 	return 0;
 }
 
-static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
 	return 0;
 }
 
 
-static int aureon_hpamp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
 }
@@ -288,16 +288,16 @@
 /*
  * Deemphasis
  */
-static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
 	return 0;
 }
 
-static int aureon_deemp_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	int temp, temp2;
 	temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
 	if (ucontrol->value.integer.value[0])
@@ -314,7 +314,7 @@
 /*
  * ADC Oversampling
  */
-static int aureon_oversampling_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
+static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = { "128x", "64x"	};
 
@@ -329,17 +329,17 @@
         return 0;
 }
 
-static int aureon_oversampling_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
 	return 0;
 }
 
-static int aureon_oversampling_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	int temp, temp2;
-	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
 
 	temp2 = temp = wm_get(ice, WM_MASTER);
 
@@ -360,7 +360,7 @@
  * mixers
  */
 
-static snd_kcontrol_new_t stac_controls[] __devinitdata = {
+static struct snd_kcontrol_new stac_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Master Playback Switch",
@@ -442,7 +442,7 @@
 #endif
 };
 
-static int __devinit prodigy192_add_controls(ice1712_t *ice)
+static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
 {
 	unsigned int i;
 	int err;
@@ -459,7 +459,7 @@
 /*
  * initialize the chip
  */
-static int __devinit prodigy192_init(ice1712_t *ice)
+static int __devinit prodigy192_init(struct snd_ice1712 *ice)
 {
 	static unsigned short stac_inits_prodigy[] = {
 		STAC946X_RESET, 0,
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index 1fe2100..b5754b3 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -33,7 +33,7 @@
 #include "envy24ht.h"
 #include "revo.h"
 
-static void revo_i2s_mclk_changed(ice1712_t *ice)
+static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
 {
 	/* assert PRST# to converters; MT05 bit 7 */
 	outb(inb(ICEMT1724(ice, AC97_CMD)) | 0x80, ICEMT1724(ice, AC97_CMD));
@@ -45,7 +45,7 @@
 /*
  * change the rate of envy24HT, AK4355 and AK4381
  */
-static void revo_set_rate_val(akm4xxx_t *ak, unsigned int rate)
+static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
 {
 	unsigned char old, tmp, dfs;
 	int reg, shift;
@@ -61,7 +61,7 @@
 	else
 		dfs = 0;
 
-	if (ak->type == SND_AK4355) {
+	if (ak->type == SND_AK4355 || ak->type == SND_AK4358) {
 		reg = 2;
 		shift = 4;
 	} else {
@@ -87,7 +87,7 @@
  * initialize the chips on M-Audio Revolution cards
  */
 
-static akm4xxx_t akm_revo_front __devinitdata = {
+static struct snd_akm4xxx akm_revo_front __devinitdata = {
 	.type = SND_AK4381,
 	.num_dacs = 2,
 	.ops = {
@@ -107,7 +107,7 @@
 	.mask_flags = 0,
 };
 
-static akm4xxx_t akm_revo_surround __devinitdata = {
+static struct snd_akm4xxx akm_revo_surround __devinitdata = {
 	.type = SND_AK4355,
 	.idx_offset = 1,
 	.num_dacs = 6,
@@ -128,9 +128,29 @@
 	.mask_flags = 0,
 };
 
-static int __devinit revo_init(ice1712_t *ice)
+static struct snd_akm4xxx akm_revo51 __devinitdata = {
+	.type = SND_AK4358,
+	.num_dacs = 6,
+	.ops = {
+		.set_rate_val = revo_set_rate_val
+	}
+};
+
+static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
+	.caddr = 2,
+	.cif = 0,
+	.data_mask = VT1724_REVO_CDOUT,
+	.clk_mask = VT1724_REVO_CCLK,
+	.cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+	.cs_addr = 0,
+	.cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2,
+	.add_flags = VT1724_REVO_CCLK, /* high at init */
+	.mask_flags = 0,
+};
+
+static int __devinit revo_init(struct snd_ice1712 *ice)
 {
-	akm4xxx_t *ak;
+	struct snd_akm4xxx *ak;
 	int err;
 
 	/* determine I2C, DACs and ADCs */
@@ -138,21 +158,25 @@
 	case VT1724_SUBDEVICE_REVOLUTION71:
 		ice->num_total_dacs = 8;
 		ice->num_total_adcs = 2;
+		ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
+		break;
+	case VT1724_SUBDEVICE_REVOLUTION51:
+		ice->num_total_dacs = 6;
+		ice->num_total_adcs = 2;
 		break;
 	default:
 		snd_BUG();
 		return -EINVAL;
 	}
 
-	ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed;
-
 	/* second stage of initialization, analog parts and others */
-	ak = ice->akm = kcalloc(2, sizeof(akm4xxx_t), GFP_KERNEL);
+	ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL);
 	if (! ak)
 		return -ENOMEM;
 	ice->akm_codecs = 2;
 	switch (ice->eeprom.subvendor) {
 	case VT1724_SUBDEVICE_REVOLUTION71:
+		ice->akm_codecs = 2;
 		if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0)
 			return err;
 		if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0)
@@ -160,18 +184,26 @@
 		/* unmute all codecs */
 		snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE);
 		break;
+	case VT1724_SUBDEVICE_REVOLUTION51:
+		ice->akm_codecs = 1;
+		if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, &akm_revo51_priv, ice)) < 0)
+			return err;
+		/* unmute all codecs - needed! */
+		snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE);
+		break;
 	}
 
 	return 0;
 }
 
 
-static int __devinit revo_add_controls(ice1712_t *ice)
+static int __devinit revo_add_controls(struct snd_ice1712 *ice)
 {
 	int err;
 
 	switch (ice->eeprom.subvendor) {
 	case VT1724_SUBDEVICE_REVOLUTION71:
+	case VT1724_SUBDEVICE_REVOLUTION51:
 		err = snd_ice1712_akm4xxx_build_controls(ice);
 		if (err < 0)
 			return err;
@@ -188,5 +220,12 @@
 		.chip_init = revo_init,
 		.build_controls = revo_add_controls,
 	},
+	{
+		.subvendor = VT1724_SUBDEVICE_REVOLUTION51,
+		.name = "M Audio Revolution-5.1",
+		.model = "revo51",
+		.chip_init = revo_init,
+		.build_controls = revo_add_controls,
+	},
 	{ } /* terminator */
 };
diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h
index ca4420b..dea52ea 100644
--- a/sound/pci/ice1712/revo.h
+++ b/sound/pci/ice1712/revo.h
@@ -25,9 +25,11 @@
  */      
 
 #define REVO_DEVICE_DESC \
-		"{MidiMan M Audio,Revolution 7.1},"
+		"{MidiMan M Audio,Revolution 7.1},"\
+		"{MidiMan M Audio,Revolution 5.1},"
 
 #define VT1724_SUBDEVICE_REVOLUTION71	0x12143036
+#define VT1724_SUBDEVICE_REVOLUTION51	0x12143136
 
 /* entry point */
 extern struct snd_ice1712_card_info snd_vt1724_revo_cards[];
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index 90c85cd..7ca263c1 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -33,7 +33,7 @@
 #include "vt1720_mobo.h"
 
 
-static int __devinit k8x800_init(ice1712_t *ice)
+static int __devinit k8x800_init(struct snd_ice1712 *ice)
 {
 	ice->vt1720 = 1;
 
@@ -47,7 +47,7 @@
 	return 0;
 }
 
-static int __devinit k8x800_add_controls(ice1712_t *ice)
+static int __devinit k8x800_add_controls(struct snd_ice1712 *ice)
 {
 	/* FIXME: needs some quirks for VT1616? */
 	return 0;
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index cf7801d..5466b1f 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -272,7 +272,8 @@
 #define ALI_INT_CPRAIS		(1<<7)	/* command port available */
 #define ALI_INT_SPRAIS		(1<<5)	/* status port available */
 #define ALI_INT_GPIO		(1<<1)
-#define ALI_INT_MASK		(ALI_INT_SPDIFOUT|ALI_INT_CODECSPDIFOUT|ALI_INT_MICIN|ALI_INT_PCMOUT|ALI_INT_PCMIN)
+#define ALI_INT_MASK		(ALI_INT_SPDIFOUT|ALI_INT_CODECSPDIFOUT|\
+				 ALI_INT_MICIN|ALI_INT_PCMOUT|ALI_INT_PCMIN)
 
 #define ICH_ALI_SC_RESET	(1<<31)	/* master reset */
 #define ICH_ALI_SC_AC97_DBL	(1<<30)
@@ -303,18 +304,40 @@
  *  
  */
 
-enum { ICHD_PCMIN, ICHD_PCMOUT, ICHD_MIC, ICHD_MIC2, ICHD_PCM2IN, ICHD_SPBAR, ICHD_LAST = ICHD_SPBAR };
-enum { NVD_PCMIN, NVD_PCMOUT, NVD_MIC, NVD_SPBAR, NVD_LAST = NVD_SPBAR };
-enum { ALID_PCMIN, ALID_PCMOUT, ALID_MIC, ALID_AC97SPDIFOUT, ALID_SPDIFIN, ALID_SPDIFOUT, ALID_LAST = ALID_SPDIFOUT };
+enum {
+	ICHD_PCMIN,
+	ICHD_PCMOUT,
+	ICHD_MIC,
+	ICHD_MIC2,
+	ICHD_PCM2IN,
+	ICHD_SPBAR,
+	ICHD_LAST = ICHD_SPBAR
+};
+enum {
+	NVD_PCMIN,
+	NVD_PCMOUT,
+	NVD_MIC,
+	NVD_SPBAR,
+	NVD_LAST = NVD_SPBAR
+};
+enum {
+	ALID_PCMIN,
+	ALID_PCMOUT,
+	ALID_MIC,
+	ALID_AC97SPDIFOUT,
+	ALID_SPDIFIN,
+	ALID_SPDIFOUT,
+	ALID_LAST = ALID_SPDIFOUT
+};
 
-#define get_ichdev(substream) (ichdev_t *)(substream->runtime->private_data)
+#define get_ichdev(substream) (substream->runtime->private_data)
 
-typedef struct {
+struct ichdev {
 	unsigned int ichd;			/* ich device number */
 	unsigned long reg_offset;		/* offset to bmaddr */
 	u32 *bdbar;				/* CPU address (32bit) */
 	unsigned int bdbar_addr;		/* PCI bus address (32bit) */
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	unsigned int physbuf;			/* physical address (32bit) */
         unsigned int size;
         unsigned int fragsize;
@@ -336,11 +359,9 @@
 	int pcm_open_flag;
 	unsigned int page_attr_changed: 1;
 	unsigned int suspended: 1;
-} ichdev_t;
+};
 
-typedef struct _snd_intel8x0 intel8x0_t;
-
-struct _snd_intel8x0 {
+struct intel8x0 {
 	unsigned int device_type;
 
 	int irq;
@@ -353,11 +374,11 @@
 	void __iomem *remap_bmaddr;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
+	struct snd_card *card;
 
 	int pcm_devs;
-	snd_pcm_t *pcm[6];
-	ichdev_t ichd[6];
+	struct snd_pcm *pcm[6];
+	struct ichdev ichd[6];
 
 	unsigned multi4: 1,
 		 multi6: 1,
@@ -374,8 +395,8 @@
 	int spdif_idx;	/* SPDIF BAR index; *_SPBAR or -1 if use PCMOUT */
 	unsigned int sdm_saved;	/* SDM reg value */
 
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97[3];
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97[3];
 	unsigned int ac97_sdin[3];
 
 	spinlock_t reg_lock;
@@ -418,7 +439,7 @@
  *  Lowlevel I/O - busmaster
  */
 
-static u8 igetbyte(intel8x0_t *chip, u32 offset)
+static u8 igetbyte(struct intel8x0 *chip, u32 offset)
 {
 	if (chip->bm_mmio)
 		return readb(chip->remap_bmaddr + offset);
@@ -426,7 +447,7 @@
 		return inb(chip->bmaddr + offset);
 }
 
-static u16 igetword(intel8x0_t *chip, u32 offset)
+static u16 igetword(struct intel8x0 *chip, u32 offset)
 {
 	if (chip->bm_mmio)
 		return readw(chip->remap_bmaddr + offset);
@@ -434,7 +455,7 @@
 		return inw(chip->bmaddr + offset);
 }
 
-static u32 igetdword(intel8x0_t *chip, u32 offset)
+static u32 igetdword(struct intel8x0 *chip, u32 offset)
 {
 	if (chip->bm_mmio)
 		return readl(chip->remap_bmaddr + offset);
@@ -442,7 +463,7 @@
 		return inl(chip->bmaddr + offset);
 }
 
-static void iputbyte(intel8x0_t *chip, u32 offset, u8 val)
+static void iputbyte(struct intel8x0 *chip, u32 offset, u8 val)
 {
 	if (chip->bm_mmio)
 		writeb(val, chip->remap_bmaddr + offset);
@@ -450,7 +471,7 @@
 		outb(val, chip->bmaddr + offset);
 }
 
-static void iputword(intel8x0_t *chip, u32 offset, u16 val)
+static void iputword(struct intel8x0 *chip, u32 offset, u16 val)
 {
 	if (chip->bm_mmio)
 		writew(val, chip->remap_bmaddr + offset);
@@ -458,7 +479,7 @@
 		outw(val, chip->bmaddr + offset);
 }
 
-static void iputdword(intel8x0_t *chip, u32 offset, u32 val)
+static void iputdword(struct intel8x0 *chip, u32 offset, u32 val)
 {
 	if (chip->bm_mmio)
 		writel(val, chip->remap_bmaddr + offset);
@@ -470,7 +491,7 @@
  *  Lowlevel I/O - AC'97 registers
  */
 
-static u16 iagetword(intel8x0_t *chip, u32 offset)
+static u16 iagetword(struct intel8x0 *chip, u32 offset)
 {
 	if (chip->mmio)
 		return readw(chip->remap_addr + offset);
@@ -478,7 +499,7 @@
 		return inw(chip->addr + offset);
 }
 
-static void iaputword(intel8x0_t *chip, u32 offset, u16 val)
+static void iaputword(struct intel8x0 *chip, u32 offset, u16 val)
 {
 	if (chip->mmio)
 		writew(val, chip->remap_addr + offset);
@@ -495,7 +516,7 @@
  */
 
 /* return the GLOB_STA bit for the corresponding codec */
-static unsigned int get_ich_codec_bit(intel8x0_t *chip, unsigned int codec)
+static unsigned int get_ich_codec_bit(struct intel8x0 *chip, unsigned int codec)
 {
 	static unsigned int codec_bit[3] = {
 		ICH_PCR, ICH_SCR, ICH_TCR
@@ -506,7 +527,7 @@
 	return codec_bit[codec];
 }
 
-static int snd_intel8x0_codec_semaphore(intel8x0_t *chip, unsigned int codec)
+static int snd_intel8x0_codec_semaphore(struct intel8x0 *chip, unsigned int codec)
 {
 	int time;
 	
@@ -545,11 +566,11 @@
 	return -EBUSY;
 }
  
-static void snd_intel8x0_codec_write(ac97_t *ac97,
+static void snd_intel8x0_codec_write(struct snd_ac97 *ac97,
 				     unsigned short reg,
 				     unsigned short val)
 {
-	intel8x0_t *chip = ac97->private_data;
+	struct intel8x0 *chip = ac97->private_data;
 	
 	if (snd_intel8x0_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
@@ -558,10 +579,10 @@
 	iaputword(chip, reg + ac97->num * 0x80, val);
 }
 
-static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
+static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97,
 					      unsigned short reg)
 {
-	intel8x0_t *chip = ac97->private_data;
+	struct intel8x0 *chip = ac97->private_data;
 	unsigned short res;
 	unsigned int tmp;
 
@@ -573,7 +594,8 @@
 		res = iagetword(chip, reg + ac97->num * 0x80);
 		if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
 			/* reset RCS and preserve other R/WC bits */
-			iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
+			iputdword(chip, ICHREG(GLOB_STA), tmp &
+				  ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
 			if (! chip->in_ac97_init)
 				snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
 			res = 0xffff;
@@ -582,7 +604,7 @@
 	return res;
 }
 
-static void snd_intel8x0_codec_read_test(intel8x0_t *chip, unsigned int codec)
+static void snd_intel8x0_codec_read_test(struct intel8x0 *chip, unsigned int codec)
 {
 	unsigned int tmp;
 
@@ -590,7 +612,8 @@
 		iagetword(chip, codec * 0x80);
 		if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
 			/* reset RCS and preserve other R/WC bits */
-			iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
+			iputdword(chip, ICHREG(GLOB_STA), tmp &
+				  ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
 		}
 	}
 }
@@ -598,7 +621,7 @@
 /*
  * access to AC97 for Ali5455
  */
-static int snd_intel8x0_ali_codec_ready(intel8x0_t *chip, int mask)
+static int snd_intel8x0_ali_codec_ready(struct intel8x0 *chip, int mask)
 {
 	int count = 0;
 	for (count = 0; count < 0x7f; count++) {
@@ -611,7 +634,7 @@
 	return -EBUSY;
 }
 
-static int snd_intel8x0_ali_codec_semaphore(intel8x0_t *chip)
+static int snd_intel8x0_ali_codec_semaphore(struct intel8x0 *chip)
 {
 	int time = 100;
 	if (chip->buggy_semaphore)
@@ -623,9 +646,9 @@
 	return snd_intel8x0_ali_codec_ready(chip, ALI_CSPSR_CODEC_READY);
 }
 
-static unsigned short snd_intel8x0_ali_codec_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_intel8x0_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg)
 {
-	intel8x0_t *chip = ac97->private_data;
+	struct intel8x0 *chip = ac97->private_data;
 	unsigned short data = 0xffff;
 
 	if (snd_intel8x0_ali_codec_semaphore(chip))
@@ -641,9 +664,10 @@
 	return data;
 }
 
-static void snd_intel8x0_ali_codec_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+static void snd_intel8x0_ali_codec_write(struct snd_ac97 *ac97, unsigned short reg,
+					 unsigned short val)
 {
-	intel8x0_t *chip = ac97->private_data;
+	struct intel8x0 *chip = ac97->private_data;
 
 	if (snd_intel8x0_ali_codec_semaphore(chip))
 		return;
@@ -658,7 +682,7 @@
 /*
  * DMA I/O
  */
-static void snd_intel8x0_setup_periods(intel8x0_t *chip, ichdev_t *ichdev) 
+static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ichdev) 
 {
 	int idx;
 	u32 *bdbar = ichdev->bdbar;
@@ -681,10 +705,15 @@
 		ichdev->ack_reload = ichdev->ack = 1;
 		ichdev->fragsize1 = ichdev->fragsize;
 		for (idx = 0; idx < (ICH_REG_LVI_MASK + 1) * 2; idx += 2) {
-			bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf + (((idx >> 1) * ichdev->fragsize) % ichdev->size));
+			bdbar[idx + 0] = cpu_to_le32(ichdev->physbuf +
+						     (((idx >> 1) * ichdev->fragsize) %
+						      ichdev->size));
 			bdbar[idx + 1] = cpu_to_le32(0x80000000 | /* interrupt on completion */
 						     ichdev->fragsize >> ichdev->pos_shift);
-			// printk("bdbar[%i] = 0x%x [0x%x]\n", idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
+#if 0
+			printk("bdbar[%i] = 0x%x [0x%x]\n",
+			       idx + 0, bdbar[idx + 0], bdbar[idx + 1]);
+#endif
 		}
 		ichdev->frags = ichdev->size / ichdev->fragsize;
 	}
@@ -722,7 +751,7 @@
  *  Interrupt handler
  */
 
-static inline void snd_intel8x0_update(intel8x0_t *chip, ichdev_t *ichdev)
+static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ichdev)
 {
 	unsigned long port = ichdev->reg_offset;
 	int status, civ, i, step;
@@ -757,7 +786,12 @@
 		ichdev->lvi_frag++;
 		ichdev->lvi_frag %= ichdev->frags;
 		ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1);
-	// printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n", ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), inl(port + 4), inb(port + ICH_REG_OFF_CR));
+#if 0
+	printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n",
+	       ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2],
+	       ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port),
+	       inl(port + 4), inb(port + ICH_REG_OFF_CR));
+#endif
 		if (--ichdev->ack == 0) {
 			ichdev->ack = ichdev->ack_reload;
 			ack = 1;
@@ -773,8 +807,8 @@
 
 static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	intel8x0_t *chip = dev_id;
-	ichdev_t *ichdev;
+	struct intel8x0 *chip = dev_id;
+	struct ichdev *ichdev;
 	unsigned int status;
 	unsigned int i;
 
@@ -808,10 +842,10 @@
  *  PCM part
  */
 
-static int snd_intel8x0_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	ichdev_t *ichdev = get_ichdev(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
+	struct ichdev *ichdev = get_ichdev(substream);
 	unsigned char val = 0;
 	unsigned long port = ichdev->reg_offset;
 
@@ -847,12 +881,14 @@
 	return 0;
 }
 
-static int snd_intel8x0_ali_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_intel8x0_ali_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	ichdev_t *ichdev = get_ichdev(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
+	struct ichdev *ichdev = get_ichdev(substream);
 	unsigned long port = ichdev->reg_offset;
-	static int fiforeg[] = { ICHREG(ALI_FIFOCR1), ICHREG(ALI_FIFOCR2), ICHREG(ALI_FIFOCR3) };
+	static int fiforeg[] = {
+		ICHREG(ALI_FIFOCR1), ICHREG(ALI_FIFOCR2), ICHREG(ALI_FIFOCR3)
+	};
 	unsigned int val, fifo;
 
 	val = igetdword(chip, ICHREG(ALI_DMACR));
@@ -871,14 +907,16 @@
 		}
 		iputbyte(chip, port + ICH_REG_OFF_CR, ICH_IOCE);
 		val &= ~(1 << (ichdev->ali_slot + 16)); /* clear PAUSE flag */
-		iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot)); /* start DMA */
+		/* start DMA */
+		iputdword(chip, ICHREG(ALI_DMACR), val | (1 << ichdev->ali_slot));
 		break;
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 		ichdev->suspended = 1;
 		/* fallthru */
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16))); /* pause */
+		/* pause */
+		iputdword(chip, ICHREG(ALI_DMACR), val | (1 << (ichdev->ali_slot + 16)));
 		iputbyte(chip, port + ICH_REG_OFF_CR, 0);
 		while (igetbyte(chip, port + ICH_REG_OFF_CR))
 			;
@@ -887,7 +925,8 @@
 		/* reset whole DMA things */
 		iputbyte(chip, port + ICH_REG_OFF_CR, ICH_RESETREGS);
 		/* clear interrupts */
-		iputbyte(chip, port + ICH_REG_OFF_SR, igetbyte(chip, port + ICH_REG_OFF_SR) | 0x1e);
+		iputbyte(chip, port + ICH_REG_OFF_SR,
+			 igetbyte(chip, port + ICH_REG_OFF_SR) | 0x1e);
 		iputdword(chip, ICHREG(ALI_INTERRUPTSR),
 			  igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & ichdev->int_sta_mask);
 		break;
@@ -897,12 +936,12 @@
 	return 0;
 }
 
-static int snd_intel8x0_hw_params(snd_pcm_substream_t * substream,
-				  snd_pcm_hw_params_t * hw_params)
+static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *hw_params)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	ichdev_t *ichdev = get_ichdev(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
+	struct ichdev *ichdev = get_ichdev(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int dbl = params_rate(hw_params) > 48000;
 	int err;
 
@@ -930,15 +969,16 @@
 		ichdev->pcm_open_flag = 1;
 		/* Force SPDIF setting */
 		if (ichdev->ichd == ICHD_PCMOUT && chip->spdif_idx < 0)
-			snd_ac97_set_rate(ichdev->pcm->r[0].codec[0], AC97_SPDIF, params_rate(hw_params));
+			snd_ac97_set_rate(ichdev->pcm->r[0].codec[0], AC97_SPDIF,
+					  params_rate(hw_params));
 	}
 	return err;
 }
 
-static int snd_intel8x0_hw_free(snd_pcm_substream_t * substream)
+static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	ichdev_t *ichdev = get_ichdev(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
+	struct ichdev *ichdev = get_ichdev(substream);
 
 	if (ichdev->pcm_open_flag) {
 		snd_ac97_pcm_close(ichdev->pcm);
@@ -951,8 +991,8 @@
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static void snd_intel8x0_setup_pcm_out(intel8x0_t *chip,
-				       snd_pcm_runtime_t *runtime)
+static void snd_intel8x0_setup_pcm_out(struct intel8x0 *chip,
+				       struct snd_pcm_runtime *runtime)
 {
 	unsigned int cnt;
 	int dbl = runtime->rate > 48000;
@@ -1004,11 +1044,11 @@
 	spin_unlock_irq(&chip->reg_lock);
 }
 
-static int snd_intel8x0_pcm_prepare(snd_pcm_substream_t * substream)
+static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ichdev_t *ichdev = get_ichdev(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct ichdev *ichdev = get_ichdev(substream);
 
 	ichdev->physbuf = runtime->dma_addr;
 	ichdev->size = snd_pcm_lib_buffer_bytes(substream);
@@ -1022,10 +1062,10 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	ichdev_t *ichdev = get_ichdev(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
+	struct ichdev *ichdev = get_ichdev(substream);
 	size_t ptr1, ptr;
 	int civ, timeout = 100;
 	unsigned int position;
@@ -1052,7 +1092,7 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_hardware_t snd_intel8x0_stream =
+static struct snd_pcm_hardware snd_intel8x0_stream =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1077,7 +1117,7 @@
 	2, 4,
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_channels4 = {
+static struct snd_pcm_hw_constraint_list hw_constraints_channels4 = {
 	.count = ARRAY_SIZE(channels4),
 	.list = channels4,
 	.mask = 0,
@@ -1087,16 +1127,16 @@
 	2, 4, 6,
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_channels6 = {
+static struct snd_pcm_hw_constraint_list hw_constraints_channels6 = {
 	.count = ARRAY_SIZE(channels6),
 	.list = channels6,
 	.mask = 0,
 };
 
-static int snd_intel8x0_pcm_open(snd_pcm_substream_t * substream, ichdev_t *ichdev)
+static int snd_intel8x0_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	ichdev->substream = substream;
@@ -1113,10 +1153,10 @@
 	return 0;
 }
 
-static int snd_intel8x0_playback_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0_playback_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	err = snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMOUT]);
@@ -1125,10 +1165,12 @@
 
 	if (chip->multi6) {
 		runtime->hw.channels_max = 6;
-		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels6);
+		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+					   &hw_constraints_channels6);
 	} else if (chip->multi4) {
 		runtime->hw.channels_max = 4;
-		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels4);
+		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+					   &hw_constraints_channels4);
 	}
 	if (chip->dra) {
 		snd_ac97_pcm_double_rate_rules(runtime);
@@ -1140,94 +1182,94 @@
 	return 0;
 }
 
-static int snd_intel8x0_playback_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0_playback_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	chip->ichd[ICHD_PCMOUT].substream = NULL;
 	return 0;
 }
 
-static int snd_intel8x0_capture_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0_capture_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMIN]);
 }
 
-static int snd_intel8x0_capture_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0_capture_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	chip->ichd[ICHD_PCMIN].substream = NULL;
 	return 0;
 }
 
-static int snd_intel8x0_mic_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0_mic_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC]);
 }
 
-static int snd_intel8x0_mic_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0_mic_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	chip->ichd[ICHD_MIC].substream = NULL;
 	return 0;
 }
 
-static int snd_intel8x0_mic2_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0_mic2_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_MIC2]);
 }
 
-static int snd_intel8x0_mic2_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0_mic2_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	chip->ichd[ICHD_MIC2].substream = NULL;
 	return 0;
 }
 
-static int snd_intel8x0_capture2_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0_capture2_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	return snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCM2IN]);
 }
 
-static int snd_intel8x0_capture2_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0_capture2_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	chip->ichd[ICHD_PCM2IN].substream = NULL;
 	return 0;
 }
 
-static int snd_intel8x0_spdif_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0_spdif_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 	int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;
 
 	return snd_intel8x0_pcm_open(substream, &chip->ichd[idx]);
 }
 
-static int snd_intel8x0_spdif_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0_spdif_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 	int idx = chip->device_type == DEVICE_NFORCE ? NVD_SPBAR : ICHD_SPBAR;
 
 	chip->ichd[idx].substream = NULL;
 	return 0;
 }
 
-static int snd_intel8x0_ali_ac97spdifout_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0_ali_ac97spdifout_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 	unsigned int val;
 
 	spin_lock_irq(&chip->reg_lock);
@@ -1240,9 +1282,9 @@
 	return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_AC97SPDIFOUT]);
 }
 
-static int snd_intel8x0_ali_ac97spdifout_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0_ali_ac97spdifout_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 	unsigned int val;
 
 	chip->ichd[ALID_AC97SPDIFOUT].substream = NULL;
@@ -1255,39 +1297,39 @@
 	return 0;
 }
 
-static int snd_intel8x0_ali_spdifin_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0_ali_spdifin_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFIN]);
 }
 
-static int snd_intel8x0_ali_spdifin_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0_ali_spdifin_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	chip->ichd[ALID_SPDIFIN].substream = NULL;
 	return 0;
 }
 
 #if 0 // NYI
-static int snd_intel8x0_ali_spdifout_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0_ali_spdifout_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	return snd_intel8x0_pcm_open(substream, &chip->ichd[ALID_SPDIFOUT]);
 }
 
-static int snd_intel8x0_ali_spdifout_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0_ali_spdifout_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 
 	chip->ichd[ALID_SPDIFOUT].substream = NULL;
 	return 0;
 }
 #endif
 
-static snd_pcm_ops_t snd_intel8x0_playback_ops = {
+static struct snd_pcm_ops snd_intel8x0_playback_ops = {
 	.open =		snd_intel8x0_playback_open,
 	.close =	snd_intel8x0_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1298,7 +1340,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_capture_ops = {
+static struct snd_pcm_ops snd_intel8x0_capture_ops = {
 	.open =		snd_intel8x0_capture_open,
 	.close =	snd_intel8x0_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1309,7 +1351,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_capture_mic_ops = {
+static struct snd_pcm_ops snd_intel8x0_capture_mic_ops = {
 	.open =		snd_intel8x0_mic_open,
 	.close =	snd_intel8x0_mic_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1320,7 +1362,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_capture_mic2_ops = {
+static struct snd_pcm_ops snd_intel8x0_capture_mic2_ops = {
 	.open =		snd_intel8x0_mic2_open,
 	.close =	snd_intel8x0_mic2_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1331,7 +1373,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_capture2_ops = {
+static struct snd_pcm_ops snd_intel8x0_capture2_ops = {
 	.open =		snd_intel8x0_capture2_open,
 	.close =	snd_intel8x0_capture2_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1342,7 +1384,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_spdif_ops = {
+static struct snd_pcm_ops snd_intel8x0_spdif_ops = {
 	.open =		snd_intel8x0_spdif_open,
 	.close =	snd_intel8x0_spdif_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1353,7 +1395,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_ali_playback_ops = {
+static struct snd_pcm_ops snd_intel8x0_ali_playback_ops = {
 	.open =		snd_intel8x0_playback_open,
 	.close =	snd_intel8x0_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1364,7 +1406,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_ali_capture_ops = {
+static struct snd_pcm_ops snd_intel8x0_ali_capture_ops = {
 	.open =		snd_intel8x0_capture_open,
 	.close =	snd_intel8x0_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1375,7 +1417,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_ali_capture_mic_ops = {
+static struct snd_pcm_ops snd_intel8x0_ali_capture_mic_ops = {
 	.open =		snd_intel8x0_mic_open,
 	.close =	snd_intel8x0_mic_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1386,7 +1428,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_ali_ac97spdifout_ops = {
+static struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = {
 	.open =		snd_intel8x0_ali_ac97spdifout_open,
 	.close =	snd_intel8x0_ali_ac97spdifout_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1397,7 +1439,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0_ali_spdifin_ops = {
+static struct snd_pcm_ops snd_intel8x0_ali_spdifin_ops = {
 	.open =		snd_intel8x0_ali_spdifin_open,
 	.close =	snd_intel8x0_ali_spdifin_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1409,7 +1451,7 @@
 };
 
 #if 0 // NYI
-static snd_pcm_ops_t snd_intel8x0_ali_spdifout_ops = {
+static struct snd_pcm_ops snd_intel8x0_ali_spdifout_ops = {
 	.open =		snd_intel8x0_ali_spdifout_open,
 	.close =	snd_intel8x0_ali_spdifout_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1423,16 +1465,17 @@
 
 struct ich_pcm_table {
 	char *suffix;
-	snd_pcm_ops_t *playback_ops;
-	snd_pcm_ops_t *capture_ops;
+	struct snd_pcm_ops *playback_ops;
+	struct snd_pcm_ops *capture_ops;
 	size_t prealloc_size;
 	size_t prealloc_max_size;
 	int ac97_idx;
 };
 
-static int __devinit snd_intel8x0_pcm1(intel8x0_t *chip, int device, struct ich_pcm_table *rec)
+static int __devinit snd_intel8x0_pcm1(struct intel8x0 *chip, int device,
+				       struct ich_pcm_table *rec)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 	char name[32];
 
@@ -1459,7 +1502,8 @@
 		strcpy(pcm->name, chip->card->shortname);
 	chip->pcm[device] = pcm;
 
-	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+					      snd_dma_pci_data(chip->pci),
 					      rec->prealloc_size, rec->prealloc_max_size);
 
 	return 0;
@@ -1557,7 +1601,7 @@
 #endif
 };
 
-static int __devinit snd_intel8x0_pcm(intel8x0_t *chip)
+static int __devinit snd_intel8x0_pcm(struct intel8x0 *chip)
 {
 	int i, tblsize, device, err;
 	struct ich_pcm_table *tbl, *rec;
@@ -1604,15 +1648,15 @@
  *  Mixer part
  */
 
-static void snd_intel8x0_mixer_free_ac97_bus(ac97_bus_t *bus)
+static void snd_intel8x0_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
 {
-	intel8x0_t *chip = bus->private_data;
+	struct intel8x0 *chip = bus->private_data;
 	chip->ac97_bus = NULL;
 }
 
-static void snd_intel8x0_mixer_free_ac97(ac97_t *ac97)
+static void snd_intel8x0_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	intel8x0_t *chip = ac97->private_data;
+	struct intel8x0 *chip = ac97->private_data;
 	chip->ac97[ac97->num] = NULL;
 }
 
@@ -1815,6 +1859,30 @@
 	},
 	{
 		.subvendor = 0x103c,
+		.subdevice = 0x0938,
+		.name = "HP nc4200",
+		.type = AC97_TUNE_HP_MUTE_LED
+	},
+	{
+		.subvendor = 0x103c,
+		.subdevice = 0x099c,
+		.name = "HP nc6120",
+		.type = AC97_TUNE_HP_MUTE_LED
+	},
+	{
+		.subvendor = 0x103c,
+		.subdevice = 0x0944,
+		.name = "HP nc6220",
+		.type = AC97_TUNE_HP_MUTE_LED
+	},
+	{
+		.subvendor = 0x103c,
+		.subdevice = 0x0934,
+		.name = "HP nc8220",
+		.type = AC97_TUNE_HP_MUTE_LED
+	},
+	{
+		.subvendor = 0x103c,
 		.subdevice = 0x12f1,
 		.name = "HP xw8200",	/* AD1981B*/
 		.type = AC97_TUNE_HP_ONLY
@@ -1868,6 +1936,12 @@
 		.type = AC97_TUNE_HP_ONLY
 	},
 	{
+		.subvendor = 0x10cf,
+		.subdevice = 0x12f2,
+		.name = "Fujitsu-Siemens Celsius H320",
+		.type = AC97_TUNE_SWAP_HP
+	},
+	{
 		.subvendor = 0x10f1,
 		.subdevice = 0x2665,
 		.name = "Fujitsu-Siemens Celsius",	/* AD1981? */
@@ -1961,19 +2035,20 @@
 	{ } /* terminator */
 };
 
-static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock, const char *quirk_override)
+static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
+					const char *quirk_override)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
 	int err;
 	unsigned int i, codecs;
 	unsigned int glob_sta = 0;
-	ac97_bus_ops_t *ops;
-	static ac97_bus_ops_t standard_bus_ops = {
+	struct snd_ac97_bus_ops *ops;
+	static struct snd_ac97_bus_ops standard_bus_ops = {
 		.write = snd_intel8x0_codec_write,
 		.read = snd_intel8x0_codec_read,
 	};
-	static ac97_bus_ops_t ali_bus_ops = {
+	static struct snd_ac97_bus_ops ali_bus_ops = {
 		.write = snd_intel8x0_ali_codec_write,
 		.read = snd_intel8x0_ali_codec_read,
 	};
@@ -2128,7 +2203,8 @@
  __err:
 	/* clear the cold-reset bit for the next chance */
 	if (chip->device_type != DEVICE_ALI)
-		iputdword(chip, ICHREG(GLOB_CNT), igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
+		iputdword(chip, ICHREG(GLOB_CNT),
+			  igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
 	return err;
 }
 
@@ -2137,7 +2213,7 @@
  *
  */
 
-static void do_ali_reset(intel8x0_t *chip)
+static void do_ali_reset(struct intel8x0 *chip)
 {
 	iputdword(chip, ICHREG(ALI_SCR), ICH_ALI_SC_RESET);
 	iputdword(chip, ICHREG(ALI_FIFOCR1), 0x83838383);
@@ -2149,11 +2225,7 @@
 	iputdword(chip, ICHREG(ALI_INTERRUPTSR), 0x00000000);
 }
 
-#define do_delay(chip) do {\
-	schedule_timeout_uninterruptible(1);\
-} while (0)
-
-static int snd_intel8x0_ich_chip_init(intel8x0_t *chip, int probing)
+static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing)
 {
 	unsigned long end_time;
 	unsigned int cnt, status, nstatus;
@@ -2176,9 +2248,10 @@
 	do {
 		if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
 			goto __ok;
-		do_delay(chip);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+	snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n",
+		   igetdword(chip, ICHREG(GLOB_CNT)));
 	return -EIO;
 
       __ok:
@@ -2189,14 +2262,16 @@
 		 */
 		end_time = jiffies + HZ;
 		do {
-			status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
+			status = igetdword(chip, ICHREG(GLOB_STA)) &
+				(ICH_PCR | ICH_SCR | ICH_TCR);
 			if (status)
 				break;
-			do_delay(chip);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 		if (! status) {
 			/* no codec is found */
-			snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n", igetdword(chip, ICHREG(GLOB_STA)));
+			snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n",
+				   igetdword(chip, ICHREG(GLOB_STA)));
 			return -EIO;
 		}
 
@@ -2210,7 +2285,7 @@
 		/* wait for other codecs ready status. */
 		end_time = jiffies + HZ / 4;
 		while (status != nstatus && time_after_eq(end_time, jiffies)) {
-			do_delay(chip);
+			schedule_timeout_uninterruptible(1);
 			status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus;
 		}
 
@@ -2224,10 +2299,11 @@
 		/* wait until all the probed codecs are ready */
 		end_time = jiffies + HZ;
 		do {
-			nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
+			nstatus = igetdword(chip, ICHREG(GLOB_STA)) &
+				(ICH_PCR | ICH_SCR | ICH_TCR);
 			if (status == nstatus)
 				break;
-			do_delay(chip);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 	}
 
@@ -2245,7 +2321,7 @@
       	return 0;
 }
 
-static int snd_intel8x0_ali_chip_init(intel8x0_t *chip, int probing)
+static int snd_intel8x0_ali_chip_init(struct intel8x0 *chip, int probing)
 {
 	u32 reg;
 	int i = 0;
@@ -2261,7 +2337,7 @@
 	for (i = 0; i < HZ / 2; i++) {
 		if (! (igetdword(chip, ICHREG(ALI_INTERRUPTSR)) & ALI_INT_GPIO))
 			goto __ok;
-		do_delay(chip);
+		schedule_timeout_uninterruptible(1);
 	}
 	snd_printk(KERN_ERR "AC'97 reset failed.\n");
 	if (probing)
@@ -2273,14 +2349,14 @@
 		if (reg & 0x80) /* primary codec */
 			break;
 		iputdword(chip, ICHREG(ALI_RTSR), reg | 0x80);
-		do_delay(chip);
+		schedule_timeout_uninterruptible(1);
 	}
 
 	do_ali_reset(chip);
 	return 0;
 }
 
-static int snd_intel8x0_chip_init(intel8x0_t *chip, int probing)
+static int snd_intel8x0_chip_init(struct intel8x0 *chip, int probing)
 {
 	unsigned int i;
 	int err;
@@ -2302,11 +2378,12 @@
 		iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
 	/* initialize Buffer Descriptor Lists */
 	for (i = 0; i < chip->bdbars_count; i++)
-		iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset, chip->ichd[i].bdbar_addr);
+		iputdword(chip, ICH_REG_OFF_BDBAR + chip->ichd[i].reg_offset,
+			  chip->ichd[i].bdbar_addr);
 	return 0;
 }
 
-static int snd_intel8x0_free(intel8x0_t *chip)
+static int snd_intel8x0_free(struct intel8x0 *chip)
 {
 	unsigned int i;
 
@@ -2329,7 +2406,7 @@
 	synchronize_irq(chip->irq);
       __hw_end:
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	if (chip->bdbars.area) {
 		if (chip->fix_nocache)
 			fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0);
@@ -2349,44 +2426,50 @@
 /*
  * power management
  */
-static int intel8x0_suspend(snd_card_t *card, pm_message_t state)
+static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	intel8x0_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct intel8x0 *chip = card->private_data;
 	int i;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	for (i = 0; i < chip->pcm_devs; i++)
 		snd_pcm_suspend_all(chip->pcm[i]);
 	/* clear nocache */
 	if (chip->fix_nocache) {
 		for (i = 0; i < chip->bdbars_count; i++) {
-			ichdev_t *ichdev = &chip->ichd[i];
+			struct ichdev *ichdev = &chip->ichd[i];
 			if (ichdev->substream && ichdev->page_attr_changed) {
-				snd_pcm_runtime_t *runtime = ichdev->substream->runtime;
+				struct snd_pcm_runtime *runtime = ichdev->substream->runtime;
 				if (runtime->dma_area)
 					fill_nocache(runtime->dma_area, runtime->dma_bytes, 0);
 			}
 		}
 	}
 	for (i = 0; i < 3; i++)
-		if (chip->ac97[i])
-			snd_ac97_suspend(chip->ac97[i]);
+		snd_ac97_suspend(chip->ac97[i]);
 	if (chip->device_type == DEVICE_INTEL_ICH4)
 		chip->sdm_saved = igetbyte(chip, ICHREG(SDM));
 
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
-	pci_disable_device(chip->pci);
+		free_irq(chip->irq, chip);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int intel8x0_resume(snd_card_t *card)
+static int intel8x0_resume(struct pci_dev *pci)
 {
-	intel8x0_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct intel8x0 *chip = card->private_data;
 	int i;
 
-	pci_enable_device(chip->pci);
-	pci_set_master(chip->pci);
-	request_irq(chip->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci);
+	request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ,
+		    card->shortname, chip);
+	chip->irq = pci->irq;
 	synchronize_irq(chip->irq);
 	snd_intel8x0_chip_init(chip, 1);
 
@@ -2405,15 +2488,14 @@
 		fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 1);
 
 	for (i = 0; i < 3; i++)
-		if (chip->ac97[i])
-			snd_ac97_resume(chip->ac97[i]);
+		snd_ac97_resume(chip->ac97[i]);
 
 	/* refill nocache */
 	if (chip->fix_nocache) {
 		for (i = 0; i < chip->bdbars_count; i++) {
-			ichdev_t *ichdev = &chip->ichd[i];
+			struct ichdev *ichdev = &chip->ichd[i];
 			if (ichdev->substream && ichdev->page_attr_changed) {
-				snd_pcm_runtime_t *runtime = ichdev->substream->runtime;
+				struct snd_pcm_runtime *runtime = ichdev->substream->runtime;
 				if (runtime->dma_area)
 					fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
 			}
@@ -2422,7 +2504,7 @@
 
 	/* resume status */
 	for (i = 0; i < chip->bdbars_count; i++) {
-		ichdev_t *ichdev = &chip->ichd[i];
+		struct ichdev *ichdev = &chip->ichd[i];
 		unsigned long port = ichdev->reg_offset;
 		if (! ichdev->substream || ! ichdev->suspended)
 			continue;
@@ -2434,16 +2516,17 @@
 		iputbyte(chip, port + ichdev->roff_sr, ICH_FIFOE | ICH_BCIS | ICH_LVBCI);
 	}
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
 #define INTEL8X0_TESTBUF_SIZE	32768	/* enough large for one shot */
 
-static void __devinit intel8x0_measure_ac97_clock(intel8x0_t *chip)
+static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip)
 {
-	snd_pcm_substream_t *subs;
-	ichdev_t *ichdev;
+	struct snd_pcm_substream *subs;
+	struct ichdev *ichdev;
 	unsigned long port;
 	unsigned long pos, t;
 	struct timeval start_time, stop_time;
@@ -2520,10 +2603,11 @@
 	printk(KERN_INFO "intel8x0: clocking to %d\n", chip->ac97_bus->clock);
 }
 
-static void snd_intel8x0_proc_read(snd_info_entry_t * entry,
-				   snd_info_buffer_t * buffer)
+#ifdef CONFIG_PROC_FS
+static void snd_intel8x0_proc_read(struct snd_info_entry * entry,
+				   struct snd_info_buffer *buffer)
 {
-	intel8x0_t *chip = entry->private_data;
+	struct intel8x0 *chip = entry->private_data;
 	unsigned int tmp;
 
 	snd_iprintf(buffer, "Intel8x0\n\n");
@@ -2546,17 +2630,20 @@
 			chip->ac97_sdin[2]);
 }
 
-static void __devinit snd_intel8x0_proc_init(intel8x0_t * chip)
+static void __devinit snd_intel8x0_proc_init(struct intel8x0 * chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(chip->card, "intel8x0", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, snd_intel8x0_proc_read);
 }
+#else
+#define snd_intel8x0_proc_init(x)
+#endif
 
-static int snd_intel8x0_dev_free(snd_device_t *device)
+static int snd_intel8x0_dev_free(struct snd_device *device)
 {
-	intel8x0_t *chip = device->device_data;
+	struct intel8x0 *chip = device->device_data;
 	return snd_intel8x0_free(chip);
 }
 
@@ -2565,17 +2652,17 @@
 	unsigned int offset;
 };
 
-static int __devinit snd_intel8x0_create(snd_card_t * card,
+static int __devinit snd_intel8x0_create(struct snd_card *card,
 					 struct pci_dev *pci,
 					 unsigned long device_type,
-					 intel8x0_t ** r_intel8x0)
+					 struct intel8x0 ** r_intel8x0)
 {
-	intel8x0_t *chip;
+	struct intel8x0 *chip;
 	int err;
 	unsigned int i;
 	unsigned int int_sta_masks;
-	ichdev_t *ichdev;
-	static snd_device_ops_t ops = {
+	struct ichdev *ichdev;
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_intel8x0_dev_free,
 	};
 
@@ -2738,7 +2825,7 @@
 
 	/* request irq after initializaing int_sta_mask, etc */
 	if (request_irq(pci->irq, snd_intel8x0_interrupt,
-			SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
+			SA_INTERRUPT|SA_SHIRQ, card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_intel8x0_free(chip);
 		return -EBUSY;
@@ -2752,8 +2839,6 @@
 		return err;
 	}
 
-	snd_card_set_pm_callback(card, intel8x0_suspend, intel8x0_resume, chip);
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_intel8x0_free(chip);
 		return err;
@@ -2797,8 +2882,8 @@
 static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
 					const struct pci_device_id *pci_id)
 {
-	snd_card_t *card;
-	intel8x0_t *chip;
+	struct snd_card *card;
+	struct intel8x0 *chip;
 	int err;
 	struct shortname_table *name;
 
@@ -2841,6 +2926,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 
 	if ((err = snd_intel8x0_mixer(chip, ac97_clock, ac97_quirk)) < 0) {
 		snd_card_free(card);
@@ -2879,7 +2965,10 @@
 	.id_table = snd_intel8x0_ids,
 	.probe = snd_intel8x0_probe,
 	.remove = __devexit_p(snd_intel8x0_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = intel8x0_suspend,
+	.resume = intel8x0_resume,
+#endif
 };
 
 
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index a420918..47e26aa 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -38,7 +38,8 @@
 #include <sound/initval.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; SiS 7013; NVidia MCP/2/2S/3 modems");
+MODULE_DESCRIPTION("Intel 82801AA,82901AB,i810,i820,i830,i840,i845,MX440; "
+		   "SiS 7013; NVidia MCP/2/2S/3 modems");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH},"
 		"{Intel,82901AB-ICH0},"
@@ -163,14 +164,14 @@
 enum { ICHD_MDMIN, ICHD_MDMOUT, ICHD_MDMLAST = ICHD_MDMOUT };
 enum { ALID_MDMIN, ALID_MDMOUT, ALID_MDMLAST = ALID_MDMOUT };
 
-#define get_ichdev(substream) (ichdev_t *)(substream->runtime->private_data)
+#define get_ichdev(substream) (substream->runtime->private_data)
 
-typedef struct {
+struct ichdev {
 	unsigned int ichd;			/* ich device number */
 	unsigned long reg_offset;		/* offset to bmaddr */
 	u32 *bdbar;				/* CPU address (32bit) */
 	unsigned int bdbar_addr;		/* PCI bus address (32bit) */
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	unsigned int physbuf;			/* physical address (32bit) */
         unsigned int size;
         unsigned int fragsize;
@@ -187,12 +188,10 @@
 	unsigned int roff_picb;
 	unsigned int int_sta_mask;		/* interrupt status mask */
 	unsigned int ali_slot;			/* ALI DMA slot */
-	ac97_t *ac97;
-} ichdev_t;
+	struct snd_ac97 *ac97;
+};
 
-typedef struct _snd_intel8x0m intel8x0_t;
-
-struct _snd_intel8x0m {
+struct intel8x0m {
 	unsigned int device_type;
 
 	int irq;
@@ -205,16 +204,16 @@
 	void __iomem *remap_bmaddr;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
+	struct snd_card *card;
 
 	int pcm_devs;
-	snd_pcm_t *pcm[2];
-	ichdev_t ichd[2];
+	struct snd_pcm *pcm[2];
+	struct ichdev ichd[2];
 
 	unsigned int in_ac97_init: 1;
 
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97;
 
 	spinlock_t reg_lock;
 	
@@ -254,7 +253,7 @@
  *  Lowlevel I/O - busmaster
  */
 
-static u8 igetbyte(intel8x0_t *chip, u32 offset)
+static u8 igetbyte(struct intel8x0m *chip, u32 offset)
 {
 	if (chip->bm_mmio)
 		return readb(chip->remap_bmaddr + offset);
@@ -262,7 +261,7 @@
 		return inb(chip->bmaddr + offset);
 }
 
-static u16 igetword(intel8x0_t *chip, u32 offset)
+static u16 igetword(struct intel8x0m *chip, u32 offset)
 {
 	if (chip->bm_mmio)
 		return readw(chip->remap_bmaddr + offset);
@@ -270,7 +269,7 @@
 		return inw(chip->bmaddr + offset);
 }
 
-static u32 igetdword(intel8x0_t *chip, u32 offset)
+static u32 igetdword(struct intel8x0m *chip, u32 offset)
 {
 	if (chip->bm_mmio)
 		return readl(chip->remap_bmaddr + offset);
@@ -278,7 +277,7 @@
 		return inl(chip->bmaddr + offset);
 }
 
-static void iputbyte(intel8x0_t *chip, u32 offset, u8 val)
+static void iputbyte(struct intel8x0m *chip, u32 offset, u8 val)
 {
 	if (chip->bm_mmio)
 		writeb(val, chip->remap_bmaddr + offset);
@@ -286,7 +285,7 @@
 		outb(val, chip->bmaddr + offset);
 }
 
-static void iputword(intel8x0_t *chip, u32 offset, u16 val)
+static void iputword(struct intel8x0m *chip, u32 offset, u16 val)
 {
 	if (chip->bm_mmio)
 		writew(val, chip->remap_bmaddr + offset);
@@ -294,7 +293,7 @@
 		outw(val, chip->bmaddr + offset);
 }
 
-static void iputdword(intel8x0_t *chip, u32 offset, u32 val)
+static void iputdword(struct intel8x0m *chip, u32 offset, u32 val)
 {
 	if (chip->bm_mmio)
 		writel(val, chip->remap_bmaddr + offset);
@@ -306,7 +305,7 @@
  *  Lowlevel I/O - AC'97 registers
  */
 
-static u16 iagetword(intel8x0_t *chip, u32 offset)
+static u16 iagetword(struct intel8x0m *chip, u32 offset)
 {
 	if (chip->mmio)
 		return readw(chip->remap_addr + offset);
@@ -314,7 +313,7 @@
 		return inw(chip->addr + offset);
 }
 
-static void iaputword(intel8x0_t *chip, u32 offset, u16 val)
+static void iaputword(struct intel8x0m *chip, u32 offset, u16 val)
 {
 	if (chip->mmio)
 		writew(val, chip->remap_addr + offset);
@@ -331,7 +330,7 @@
  */
 
 /* return the GLOB_STA bit for the corresponding codec */
-static unsigned int get_ich_codec_bit(intel8x0_t *chip, unsigned int codec)
+static unsigned int get_ich_codec_bit(struct intel8x0m *chip, unsigned int codec)
 {
 	static unsigned int codec_bit[3] = {
 		ICH_PCR, ICH_SCR, ICH_TCR
@@ -340,7 +339,7 @@
 	return codec_bit[codec];
 }
 
-static int snd_intel8x0m_codec_semaphore(intel8x0_t *chip, unsigned int codec)
+static int snd_intel8x0m_codec_semaphore(struct intel8x0m *chip, unsigned int codec)
 {
 	int time;
 	
@@ -370,11 +369,11 @@
 	return -EBUSY;
 }
  
-static void snd_intel8x0_codec_write(ac97_t *ac97,
+static void snd_intel8x0_codec_write(struct snd_ac97 *ac97,
 				     unsigned short reg,
 				     unsigned short val)
 {
-	intel8x0_t *chip = ac97->private_data;
+	struct intel8x0m *chip = ac97->private_data;
 	
 	if (snd_intel8x0m_codec_semaphore(chip, ac97->num) < 0) {
 		if (! chip->in_ac97_init)
@@ -383,10 +382,10 @@
 	iaputword(chip, reg + ac97->num * 0x80, val);
 }
 
-static unsigned short snd_intel8x0_codec_read(ac97_t *ac97,
+static unsigned short snd_intel8x0_codec_read(struct snd_ac97 *ac97,
 					      unsigned short reg)
 {
-	intel8x0_t *chip = ac97->private_data;
+	struct intel8x0m *chip = ac97->private_data;
 	unsigned short res;
 	unsigned int tmp;
 
@@ -398,7 +397,8 @@
 		res = iagetword(chip, reg + ac97->num * 0x80);
 		if ((tmp = igetdword(chip, ICHREG(GLOB_STA))) & ICH_RCS) {
 			/* reset RCS and preserve other R/WC bits */
-			iputdword(chip, ICHREG(GLOB_STA), tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
+			iputdword(chip, ICHREG(GLOB_STA),
+				  tmp & ~(ICH_SRI|ICH_PRI|ICH_TRI|ICH_GSCI));
 			if (! chip->in_ac97_init)
 				snd_printk(KERN_ERR "codec_read %d: read timeout for register 0x%x\n", ac97->num, reg);
 			res = 0xffff;
@@ -413,7 +413,7 @@
 /*
  * DMA I/O
  */
-static void snd_intel8x0_setup_periods(intel8x0_t *chip, ichdev_t *ichdev) 
+static void snd_intel8x0_setup_periods(struct intel8x0m *chip, struct ichdev *ichdev) 
 {
 	int idx;
 	u32 *bdbar = ichdev->bdbar;
@@ -460,7 +460,7 @@
  *  Interrupt handler
  */
 
-static inline void snd_intel8x0_update(intel8x0_t *chip, ichdev_t *ichdev)
+static inline void snd_intel8x0_update(struct intel8x0m *chip, struct ichdev *ichdev)
 {
 	unsigned long port = ichdev->reg_offset;
 	int civ, i, step;
@@ -489,8 +489,15 @@
 	for (i = 0; i < step; i++) {
 		ichdev->lvi_frag++;
 		ichdev->lvi_frag %= ichdev->frags;
-		ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf + ichdev->lvi_frag * ichdev->fragsize1);
-	// printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n", ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2], ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port), inl(port + 4), inb(port + ICH_REG_OFF_CR));
+		ichdev->bdbar[ichdev->lvi * 2] = cpu_to_le32(ichdev->physbuf +
+							     ichdev->lvi_frag *
+							     ichdev->fragsize1);
+#if 0
+		printk("new: bdbar[%i] = 0x%x [0x%x], prefetch = %i, all = 0x%x, 0x%x\n",
+		       ichdev->lvi * 2, ichdev->bdbar[ichdev->lvi * 2],
+		       ichdev->bdbar[ichdev->lvi * 2 + 1], inb(ICH_REG_OFF_PIV + port),
+		       inl(port + 4), inb(port + ICH_REG_OFF_CR));
+#endif
 		if (--ichdev->ack == 0) {
 			ichdev->ack = ichdev->ack_reload;
 			ack = 1;
@@ -506,8 +513,8 @@
 
 static irqreturn_t snd_intel8x0_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	intel8x0_t *chip = dev_id;
-	ichdev_t *ichdev;
+	struct intel8x0m *chip = dev_id;
+	struct ichdev *ichdev;
 	unsigned int status;
 	unsigned int i;
 
@@ -541,10 +548,10 @@
  *  PCM part
  */
 
-static int snd_intel8x0_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	ichdev_t *ichdev = get_ichdev(substream);
+	struct intel8x0m *chip = snd_pcm_substream_chip(substream);
+	struct ichdev *ichdev = get_ichdev(substream);
 	unsigned char val = 0;
 	unsigned long port = ichdev->reg_offset;
 
@@ -576,21 +583,21 @@
 	return 0;
 }
 
-static int snd_intel8x0_hw_params(snd_pcm_substream_t * substream,
-				  snd_pcm_hw_params_t * hw_params)
+static int snd_intel8x0_hw_params(struct snd_pcm_substream *substream,
+				  struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_intel8x0_hw_free(snd_pcm_substream_t * substream)
+static int snd_intel8x0_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	ichdev_t *ichdev = get_ichdev(substream);
+	struct intel8x0m *chip = snd_pcm_substream_chip(substream);
+	struct ichdev *ichdev = get_ichdev(substream);
 	size_t ptr1, ptr;
 
 	ptr1 = igetword(chip, ichdev->reg_offset + ichdev->roff_picb) << chip->pcm_pos_shift;
@@ -604,11 +611,11 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static int snd_intel8x0m_pcm_prepare(snd_pcm_substream_t * substream)
+static int snd_intel8x0m_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ichdev_t *ichdev = get_ichdev(substream);
+	struct intel8x0m *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct ichdev *ichdev = get_ichdev(substream);
 
 	ichdev->physbuf = runtime->dma_addr;
 	ichdev->size = snd_pcm_lib_buffer_bytes(substream);
@@ -619,7 +626,7 @@
 	return 0;
 }
 
-static snd_pcm_hardware_t snd_intel8x0m_stream =
+static struct snd_pcm_hardware snd_intel8x0m_stream =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -641,58 +648,59 @@
 };
 
 
-static int snd_intel8x0m_pcm_open(snd_pcm_substream_t * substream, ichdev_t *ichdev)
+static int snd_intel8x0m_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev)
 {
 	static unsigned int rates[] = { 8000,  9600, 12000, 16000 };
-	static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+	static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 		.count = ARRAY_SIZE(rates),
 		.list = rates,
 		.mask = 0,
 	};
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	ichdev->substream = substream;
 	runtime->hw = snd_intel8x0m_stream;
-	err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
+	err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+					 &hw_constraints_rates);
 	if ( err < 0 )
 		return err;
 	runtime->private_data = ichdev;
 	return 0;
 }
 
-static int snd_intel8x0m_playback_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0m_playback_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0m *chip = snd_pcm_substream_chip(substream);
 
 	return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMOUT]);
 }
 
-static int snd_intel8x0m_playback_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0m_playback_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0m *chip = snd_pcm_substream_chip(substream);
 
 	chip->ichd[ICHD_MDMOUT].substream = NULL;
 	return 0;
 }
 
-static int snd_intel8x0m_capture_open(snd_pcm_substream_t * substream)
+static int snd_intel8x0m_capture_open(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0m *chip = snd_pcm_substream_chip(substream);
 
 	return snd_intel8x0m_pcm_open(substream, &chip->ichd[ICHD_MDMIN]);
 }
 
-static int snd_intel8x0m_capture_close(snd_pcm_substream_t * substream)
+static int snd_intel8x0m_capture_close(struct snd_pcm_substream *substream)
 {
-	intel8x0_t *chip = snd_pcm_substream_chip(substream);
+	struct intel8x0m *chip = snd_pcm_substream_chip(substream);
 
 	chip->ichd[ICHD_MDMIN].substream = NULL;
 	return 0;
 }
 
 
-static snd_pcm_ops_t snd_intel8x0m_playback_ops = {
+static struct snd_pcm_ops snd_intel8x0m_playback_ops = {
 	.open =		snd_intel8x0m_playback_open,
 	.close =	snd_intel8x0m_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -703,7 +711,7 @@
 	.pointer =	snd_intel8x0_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_intel8x0m_capture_ops = {
+static struct snd_pcm_ops snd_intel8x0m_capture_ops = {
 	.open =		snd_intel8x0m_capture_open,
 	.close =	snd_intel8x0m_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -717,16 +725,17 @@
 
 struct ich_pcm_table {
 	char *suffix;
-	snd_pcm_ops_t *playback_ops;
-	snd_pcm_ops_t *capture_ops;
+	struct snd_pcm_ops *playback_ops;
+	struct snd_pcm_ops *capture_ops;
 	size_t prealloc_size;
 	size_t prealloc_max_size;
 	int ac97_idx;
 };
 
-static int __devinit snd_intel8x0_pcm1(intel8x0_t *chip, int device, struct ich_pcm_table *rec)
+static int __devinit snd_intel8x0_pcm1(struct intel8x0m *chip, int device,
+				       struct ich_pcm_table *rec)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 	char name[32];
 
@@ -772,7 +781,7 @@
 	},
 };
 
-static int __devinit snd_intel8x0_pcm(intel8x0_t *chip)
+static int __devinit snd_intel8x0_pcm(struct intel8x0m *chip)
 {
 	int i, tblsize, device, err;
 	struct ich_pcm_table *tbl, *rec;
@@ -819,27 +828,27 @@
  *  Mixer part
  */
 
-static void snd_intel8x0_mixer_free_ac97_bus(ac97_bus_t *bus)
+static void snd_intel8x0_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
 {
-	intel8x0_t *chip = bus->private_data;
+	struct intel8x0m *chip = bus->private_data;
 	chip->ac97_bus = NULL;
 }
 
-static void snd_intel8x0_mixer_free_ac97(ac97_t *ac97)
+static void snd_intel8x0_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	intel8x0_t *chip = ac97->private_data;
+	struct intel8x0m *chip = ac97->private_data;
 	chip->ac97 = NULL;
 }
 
 
-static int __devinit snd_intel8x0_mixer(intel8x0_t *chip, int ac97_clock)
+static int __devinit snd_intel8x0_mixer(struct intel8x0m *chip, int ac97_clock)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
-	ac97_t *x97;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
+	struct snd_ac97 *x97;
 	int err;
 	unsigned int glob_sta = 0;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_intel8x0_codec_write,
 		.read = snd_intel8x0_codec_read,
 	};
@@ -880,7 +889,8 @@
  __err:
 	/* clear the cold-reset bit for the next chance */
 	if (chip->device_type != DEVICE_ALI)
-		iputdword(chip, ICHREG(GLOB_CNT), igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
+		iputdword(chip, ICHREG(GLOB_CNT),
+			  igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_AC97COLD);
 	return err;
 }
 
@@ -889,11 +899,7 @@
  *
  */
 
-#define do_delay(chip) do {\
-	schedule_timeout_uninterruptible(1);\
-} while (0)
-
-static int snd_intel8x0m_ich_chip_init(intel8x0_t *chip, int probing)
+static int snd_intel8x0m_ich_chip_init(struct intel8x0m *chip, int probing)
 {
 	unsigned long end_time;
 	unsigned int cnt, status, nstatus;
@@ -914,9 +920,10 @@
 	do {
 		if ((igetdword(chip, ICHREG(GLOB_CNT)) & ICH_AC97WARM) == 0)
 			goto __ok;
-		do_delay(chip);
+		schedule_timeout_uninterruptible(1);
 	} while (time_after_eq(end_time, jiffies));
-	snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n", igetdword(chip, ICHREG(GLOB_CNT)));
+	snd_printk(KERN_ERR "AC'97 warm reset still in progress? [0x%x]\n",
+		   igetdword(chip, ICHREG(GLOB_CNT)));
 	return -EIO;
 
       __ok:
@@ -927,14 +934,16 @@
 		 */
 		end_time = jiffies + HZ;
 		do {
-			status = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
+			status = igetdword(chip, ICHREG(GLOB_STA)) &
+				(ICH_PCR | ICH_SCR | ICH_TCR);
 			if (status)
 				break;
-			do_delay(chip);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 		if (! status) {
 			/* no codec is found */
-			snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n", igetdword(chip, ICHREG(GLOB_STA)));
+			snd_printk(KERN_ERR "codec_ready: codec is not ready [0x%x]\n",
+				   igetdword(chip, ICHREG(GLOB_STA)));
 			return -EIO;
 		}
 
@@ -944,7 +953,7 @@
 		/* wait for other codecs ready status. */
 		end_time = jiffies + HZ / 4;
 		while (status != nstatus && time_after_eq(end_time, jiffies)) {
-			do_delay(chip);
+			schedule_timeout_uninterruptible(1);
 			status |= igetdword(chip, ICHREG(GLOB_STA)) & nstatus;
 		}
 
@@ -956,10 +965,11 @@
 		/* wait until all the probed codecs are ready */
 		end_time = jiffies + HZ;
 		do {
-			nstatus = igetdword(chip, ICHREG(GLOB_STA)) & (ICH_PCR | ICH_SCR | ICH_TCR);
+			nstatus = igetdword(chip, ICHREG(GLOB_STA)) &
+				(ICH_PCR | ICH_SCR | ICH_TCR);
 			if (status == nstatus)
 				break;
-			do_delay(chip);
+			schedule_timeout_uninterruptible(1);
 		} while (time_after_eq(end_time, jiffies));
 	}
 
@@ -971,7 +981,7 @@
       	return 0;
 }
 
-static int snd_intel8x0_chip_init(intel8x0_t *chip, int probing)
+static int snd_intel8x0_chip_init(struct intel8x0m *chip, int probing)
 {
 	unsigned int i;
 	int err;
@@ -992,7 +1002,7 @@
 	return 0;
 }
 
-static int snd_intel8x0_free(intel8x0_t *chip)
+static int snd_intel8x0_free(struct intel8x0m *chip)
 {
 	unsigned int i;
 
@@ -1014,7 +1024,7 @@
 	if (chip->remap_bmaddr)
 		iounmap(chip->remap_bmaddr);
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
 	kfree(chip);
@@ -1025,43 +1035,50 @@
 /*
  * power management
  */
-static int intel8x0m_suspend(snd_card_t *card, pm_message_t state)
+static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	intel8x0_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct intel8x0m *chip = card->private_data;
 	int i;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	for (i = 0; i < chip->pcm_devs; i++)
 		snd_pcm_suspend_all(chip->pcm[i]);
-	if (chip->ac97)
-		snd_ac97_suspend(chip->ac97);
-	pci_disable_device(chip->pci);
+	snd_ac97_suspend(chip->ac97);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int intel8x0m_resume(snd_card_t *card)
+static int intel8x0m_resume(struct pci_dev *pci)
 {
-	intel8x0_t *chip = card->pm_private_data;
-	pci_enable_device(chip->pci);
-	pci_set_master(chip->pci);
-	snd_intel8x0_chip_init(chip, 0);
-	if (chip->ac97)
-		snd_ac97_resume(chip->ac97);
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct intel8x0m *chip = card->private_data;
 
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci);
+	snd_intel8x0_chip_init(chip, 0);
+	snd_ac97_resume(chip->ac97);
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
-static void snd_intel8x0m_proc_read(snd_info_entry_t * entry,
-				   snd_info_buffer_t * buffer)
+#ifdef CONFIG_PROC_FS
+static void snd_intel8x0m_proc_read(struct snd_info_entry * entry,
+				   struct snd_info_buffer *buffer)
 {
-	intel8x0_t *chip = entry->private_data;
+	struct intel8x0m *chip = entry->private_data;
 	unsigned int tmp;
 
 	snd_iprintf(buffer, "Intel8x0m\n\n");
 	if (chip->device_type == DEVICE_ALI)
 		return;
 	tmp = igetdword(chip, ICHREG(GLOB_STA));
-	snd_iprintf(buffer, "Global control        : 0x%08x\n", igetdword(chip, ICHREG(GLOB_CNT)));
+	snd_iprintf(buffer, "Global control        : 0x%08x\n",
+		    igetdword(chip, ICHREG(GLOB_CNT)));
 	snd_iprintf(buffer, "Global status         : 0x%08x\n", tmp);
 	snd_iprintf(buffer, "AC'97 codecs ready    :%s%s%s%s\n",
 			tmp & ICH_PCR ? " primary" : "",
@@ -1070,17 +1087,21 @@
 			(tmp & (ICH_PCR | ICH_SCR | ICH_TCR)) == 0 ? " none" : "");
 }
 
-static void __devinit snd_intel8x0m_proc_init(intel8x0_t * chip)
+static void __devinit snd_intel8x0m_proc_init(struct intel8x0m * chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(chip->card, "intel8x0m", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, snd_intel8x0m_proc_read);
 }
+#else /* !CONFIG_PROC_FS */
+#define snd_intel8x0m_proc_init(chip)
+#endif /* CONFIG_PROC_FS */
 
-static int snd_intel8x0_dev_free(snd_device_t *device)
+
+static int snd_intel8x0_dev_free(struct snd_device *device)
 {
-	intel8x0_t *chip = device->device_data;
+	struct intel8x0m *chip = device->device_data;
 	return snd_intel8x0_free(chip);
 }
 
@@ -1089,17 +1110,17 @@
 	unsigned int offset;
 };
 
-static int __devinit snd_intel8x0m_create(snd_card_t * card,
+static int __devinit snd_intel8x0m_create(struct snd_card *card,
 					 struct pci_dev *pci,
 					 unsigned long device_type,
-					 intel8x0_t ** r_intel8x0)
+					 struct intel8x0m ** r_intel8x0)
 {
-	intel8x0_t *chip;
+	struct intel8x0m *chip;
 	int err;
 	unsigned int i;
 	unsigned int int_sta_masks;
-	ichdev_t *ichdev;
-	static snd_device_ops_t ops = {
+	struct ichdev *ichdev;
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_intel8x0_dev_free,
 	};
 	static struct ich_reg_info intel_regs[2] = {
@@ -1164,7 +1185,8 @@
 	}
 
  port_inited:
-	if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ, card->shortname, (void *)chip)) {
+	if (request_irq(pci->irq, snd_intel8x0_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			card->shortname, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_intel8x0_free(chip);
 		return -EBUSY;
@@ -1221,8 +1243,6 @@
 		return err;
 	}
 
-	snd_card_set_pm_callback(card, intel8x0m_suspend, intel8x0m_resume, chip);
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
 		snd_intel8x0_free(chip);
 		return err;
@@ -1263,8 +1283,8 @@
 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
 					const struct pci_device_id *pci_id)
 {
-	snd_card_t *card;
-	intel8x0_t *chip;
+	struct snd_card *card;
+	struct intel8x0m *chip;
 	int err;
 	struct shortname_table *name;
 
@@ -1286,6 +1306,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 
 	if ((err = snd_intel8x0_mixer(chip, ac97_clock)) < 0) {
 		snd_card_free(card);
@@ -1320,7 +1341,10 @@
 	.id_table = snd_intel8x0m_ids,
 	.probe = snd_intel8x0m_probe,
 	.remove = __devexit_p(snd_intel8x0m_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = intel8x0m_suspend,
+	.resume = intel8x0m_resume,
+#endif
 };
 
 
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index a110d66..4eddb51 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -41,8 +41,16 @@
 // Debug Stuff
 // ----------------------------------------------------------------------------
 #define K1212_DEBUG_LEVEL		0
-#define K1212_DEBUG_PRINTK		printk
-//#define K1212_DEBUG_PRINTK(x...)	printk("<0>" x)
+#if K1212_DEBUG_LEVEL > 0
+#define K1212_DEBUG_PRINTK(fmt,args...)	printk(KERN_DEBUG fmt,##args)
+#else
+#define K1212_DEBUG_PRINTK(fmt,...)
+#endif
+#if K1212_DEBUG_LEVEL > 1
+#define K1212_DEBUG_PRINTK_VERBOSE(fmt,args...)	printk(KERN_DEBUG fmt,##args)
+#else
+#define K1212_DEBUG_PRINTK_VERBOSE(fmt,...)
+#endif
 
 // ----------------------------------------------------------------------------
 // Record/Play Buffer Allocation Method. If K1212_LARGEALLOC is defined all 
@@ -53,7 +61,7 @@
 // ----------------------------------------------------------------------------
 // Valid states of the Korg 1212 I/O card.
 // ----------------------------------------------------------------------------
-typedef enum {
+enum CardState {
    K1212_STATE_NONEXISTENT,		// there is no card here
    K1212_STATE_UNINITIALIZED,		// the card is awaiting DSP download
    K1212_STATE_DSP_IN_PROCESS,		// the card is currently downloading its DSP code
@@ -69,13 +77,13 @@
    K1212_STATE_ERRORSTOP,		// the card has stopped itself because of an error and we
 					//    are in the process of cleaning things up.
    K1212_STATE_MAX_STATE		// state values of this and beyond are invalid
-} CardState;
+};
 
 // ----------------------------------------------------------------------------
 // The following enumeration defines the constants written to the card's
 // host-to-card doorbell to initiate a command.
 // ----------------------------------------------------------------------------
-typedef enum {
+enum korg1212_dbcnst {
    K1212_DB_RequestForData        = 0,    // sent by the card to request a buffer fill.
    K1212_DB_TriggerPlay           = 1,    // starts playback/record on the card.
    K1212_DB_SelectPlayMode        = 2,    // select monitor, playback setup, or stop.
@@ -93,14 +101,14 @@
    K1212_DB_DSPDownloadDone       = 0xAE, // sent by the card to indicate the download has
                                           //    completed.
    K1212_DB_StartDSPDownload      = 0xAF  // tells the card to download its DSP firmware.
-} korg1212_dbcnst_t;
+};
 
 
 // ----------------------------------------------------------------------------
 // The following enumeration defines return codes 
 // to the Korg 1212 I/O driver.
 // ----------------------------------------------------------------------------
-typedef enum {
+enum snd_korg1212rc {
    K1212_CMDRET_Success         = 0,   // command was successfully placed
    K1212_CMDRET_DIOCFailure,           // the DeviceIoControl call failed
    K1212_CMDRET_PMFailure,             // the protected mode call failed
@@ -118,27 +126,27 @@
 
    K1212_CMDRET_BadDevice,             // the specified wave device was out of range
    K1212_CMDRET_BadFormat              // the specified wave format is unsupported
-} snd_korg1212rc;
+};
 
 // ----------------------------------------------------------------------------
 // The following enumeration defines the constants used to select the play
 // mode for the card in the SelectPlayMode command.
 // ----------------------------------------------------------------------------
-typedef enum {
+enum PlayModeSelector {
    K1212_MODE_SetupPlay  = 0x00000001,     // provides card with pre-play information
    K1212_MODE_MonitorOn  = 0x00000002,     // tells card to turn on monitor mode
    K1212_MODE_MonitorOff = 0x00000004,     // tells card to turn off monitor mode
    K1212_MODE_StopPlay   = 0x00000008      // stops playback on the card
-} PlayModeSelector;
+};
 
 // ----------------------------------------------------------------------------
 // The following enumeration defines the constants used to select the monitor
 // mode for the card in the SetMonitorMode command.
 // ----------------------------------------------------------------------------
-typedef enum {
+enum MonitorModeSelector {
    K1212_MONMODE_Off  = 0,     // tells card to turn off monitor mode
    K1212_MONMODE_On            // tells card to turn on monitor mode
-} MonitorModeSelector;
+};
 
 #define MAILBOX0_OFFSET      0x40	// location of mailbox 0 relative to base address
 #define MAILBOX1_OFFSET      0x44	// location of mailbox 1 relative to base address
@@ -180,7 +188,7 @@
 #define K1212_CHANNELS		(K1212_ADAT_CHANNELS + K1212_ANALOG_CHANNELS)
 #define K1212_MIN_CHANNELS	1
 #define K1212_MAX_CHANNELS	K1212_CHANNELS
-#define K1212_FRAME_SIZE        (sizeof(KorgAudioFrame))
+#define K1212_FRAME_SIZE        (sizeof(struct KorgAudioFrame))
 #define K1212_MAX_SAMPLES	(kPlayBufferFrames*kNumBuffers)
 #define K1212_PERIODS		(kNumBuffers)
 #define K1212_PERIOD_BYTES	(K1212_FRAME_SIZE*kPlayBufferFrames)
@@ -256,14 +264,7 @@
 
 #include "korg1212-firmware.h"
 
-typedef struct _snd_korg1212 korg1212_t;
-
-typedef u16 K1212Sample;          // channels 0-9 use 16 bit samples
-typedef u32 K1212SpdifSample;     // channels 10-11 use 32 bits - only 20 are sent
-                                  //  across S/PDIF.
-typedef u32 K1212TimeCodeSample;  // holds the ADAT timecode value
-
-typedef enum {
+enum ClockSourceIndex {
    K1212_CLKIDX_AdatAt44_1K = 0,    // selects source as ADAT at 44.1 kHz
    K1212_CLKIDX_AdatAt48K,          // selects source as ADAT at 48 kHz
    K1212_CLKIDX_WordAt44_1K,        // selects source as S/PDIF at 44.1 kHz
@@ -271,36 +272,36 @@
    K1212_CLKIDX_LocalAt44_1K,       // selects source as local clock at 44.1 kHz
    K1212_CLKIDX_LocalAt48K,         // selects source as local clock at 48 kHz
    K1212_CLKIDX_Invalid             // used to check validity of the index
-} ClockSourceIndex;
+};
 
-typedef enum {
+enum ClockSourceType {
    K1212_CLKIDX_Adat = 0,    // selects source as ADAT
    K1212_CLKIDX_Word,        // selects source as S/PDIF
    K1212_CLKIDX_Local        // selects source as local clock
-} ClockSourceType;
+};
 
-typedef struct KorgAudioFrame {
-   K1212Sample          frameData16[k16BitChannels];
-   K1212SpdifSample     frameData32[k32BitChannels];
-   K1212TimeCodeSample  timeCodeVal;
-} KorgAudioFrame;
+struct KorgAudioFrame {
+	u16 frameData16[k16BitChannels]; /* channels 0-9 use 16 bit samples */
+	u32 frameData32[k32BitChannels]; /* channels 10-11 use 32 bits - only 20 are sent across S/PDIF */
+	u32 timeCodeVal; /* holds the ADAT timecode value */
+};
 
-typedef struct KorgAudioBuffer {
-   KorgAudioFrame  bufferData[kPlayBufferFrames];     /* buffer definition */
-} KorgAudioBuffer;
+struct KorgAudioBuffer {
+	struct KorgAudioFrame  bufferData[kPlayBufferFrames];     /* buffer definition */
+};
 
-typedef struct KorgSharedBuffer {
+struct KorgSharedBuffer {
 #ifdef K1212_LARGEALLOC
-   KorgAudioBuffer   playDataBufs[kNumBuffers];
-   KorgAudioBuffer   recordDataBufs[kNumBuffers];
+   struct KorgAudioBuffer   playDataBufs[kNumBuffers];
+   struct KorgAudioBuffer   recordDataBufs[kNumBuffers];
 #endif
    short             volumeData[kAudioChannels];
    u32               cardCommand;
    u16               routeData [kAudioChannels];
    u32               AdatTimeCode;                 // ADAT timecode value
-} KorgSharedBuffer;
+};
 
-typedef struct SensBits {
+struct SensBits {
    union {
       struct {
          unsigned int leftChanVal:8;
@@ -315,12 +316,12 @@
       } v;
       u16  rightSensBits;
    } r;
-} SensBits;
+};
 
-struct _snd_korg1212 {
-        snd_card_t *card;
+struct snd_korg1212 {
+        struct snd_card *card;
         struct pci_dev *pci;
-        snd_pcm_t *pcm;
+        struct snd_pcm *pcm;
         int irq;
 
         spinlock_t    lock;
@@ -347,10 +348,10 @@
 
 	u32 DataBufsSize;
 
-        KorgAudioBuffer  * playDataBufsPtr;
-        KorgAudioBuffer  * recordDataBufsPtr;
+        struct KorgAudioBuffer  * playDataBufsPtr;
+        struct KorgAudioBuffer  * recordDataBufsPtr;
 
-	KorgSharedBuffer * sharedBufferPtr;
+	struct KorgSharedBuffer * sharedBufferPtr;
 
 	u32 RecDataPhy;
 	u32 PlayDataPhy;
@@ -374,20 +375,20 @@
 	int channels;
         int currentBuffer;
 
-        snd_pcm_substream_t *playback_substream;
-        snd_pcm_substream_t *capture_substream;
+        struct snd_pcm_substream *playback_substream;
+        struct snd_pcm_substream *capture_substream;
 
 	pid_t capture_pid;
 	pid_t playback_pid;
 
- 	CardState cardState;
+ 	enum CardState cardState;
         int running;
         int idleMonitorOn;           // indicates whether the card is in idle monitor mode.
         u32 cmdRetryCount;           // tracks how many times we have retried sending to the card.
 
-        ClockSourceIndex clkSrcRate; // sample rate and clock source
+        enum ClockSourceIndex clkSrcRate; // sample rate and clock source
 
-        ClockSourceType clkSource;   // clock source
+        enum ClockSourceType clkSource;   // clock source
         int clkRate;                 // clock rate
 
         int volumePhase[kAudioChannels];
@@ -432,60 +433,58 @@
 	{ 0, },
 };
 
-static char* stateName[] = {
-		        "Non-existent",
-                        "Uninitialized",
-                        "DSP download in process",
-                        "DSP download complete",
-                        "Ready",
-                        "Open",
-                        "Setup for play",
-                        "Playing",
-                        "Monitor mode on",
-			"Calibrating",
-                        "Invalid"
-};
-
-static char* clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" };
-
-static char* clockSourceName[] = {
-                        "ADAT at 44.1 kHz",
-                        "ADAT at 48 kHz",
-                        "S/PDIF at 44.1 kHz",
-                        "S/PDIF at 48 kHz",
-                        "local clock at 44.1 kHz",
-                        "local clock at 48 kHz"
-};
-
-static char* channelName[] = {
-                        "ADAT-1",
-                        "ADAT-2",
-                        "ADAT-3",
-                        "ADAT-4",
-                        "ADAT-5",
-                        "ADAT-6",
-                        "ADAT-7",
-                        "ADAT-8",
-                        "Analog-L",
-                        "Analog-R",
-                        "SPDIF-L",
-                        "SPDIF-R",
-};
-
-static u16 ClockSourceSelector[] =
-                            {0x8000,   // selects source as ADAT at 44.1 kHz
-                             0x0000,   // selects source as ADAT at 48 kHz
-                             0x8001,   // selects source as S/PDIF at 44.1 kHz
-                             0x0001,   // selects source as S/PDIF at 48 kHz
-                             0x8002,   // selects source as local clock at 44.1 kHz
-                             0x0002    // selects source as local clock at 48 kHz
-                            };
-
-static snd_korg1212rc rc;
-
 MODULE_DEVICE_TABLE(pci, snd_korg1212_ids);
 
-typedef union swap_u32 { unsigned char c[4]; u32 i; } swap_u32;
+static char *stateName[] = {
+	"Non-existent",
+	"Uninitialized",
+	"DSP download in process",
+	"DSP download complete",
+	"Ready",
+	"Open",
+	"Setup for play",
+	"Playing",
+	"Monitor mode on",
+	"Calibrating",
+	"Invalid"
+};
+
+static char *clockSourceTypeName[] = { "ADAT", "S/PDIF", "local" };
+
+static char *clockSourceName[] = {
+	"ADAT at 44.1 kHz",
+	"ADAT at 48 kHz",
+	"S/PDIF at 44.1 kHz",
+	"S/PDIF at 48 kHz",
+	"local clock at 44.1 kHz",
+	"local clock at 48 kHz"
+};
+
+static char *channelName[] = {
+	"ADAT-1",
+	"ADAT-2",
+	"ADAT-3",
+	"ADAT-4",
+	"ADAT-5",
+	"ADAT-6",
+	"ADAT-7",
+	"ADAT-8",
+	"Analog-L",
+	"Analog-R",
+	"SPDIF-L",
+	"SPDIF-R",
+};
+
+static u16 ClockSourceSelector[] = {
+	0x8000,   // selects source as ADAT at 44.1 kHz
+	0x0000,   // selects source as ADAT at 48 kHz
+	0x8001,   // selects source as S/PDIF at 44.1 kHz
+	0x0001,   // selects source as S/PDIF at 48 kHz
+	0x8002,   // selects source as local clock at 44.1 kHz
+	0x0002    // selects source as local clock at 48 kHz
+};
+
+union swap_u32 { unsigned char c[4]; u32 i; };
 
 #ifdef SNDRV_BIG_ENDIAN
 static u32 LowerWordSwap(u32 swappee)
@@ -493,7 +492,7 @@
 static u32 UpperWordSwap(u32 swappee)
 #endif
 {
-   swap_u32 retVal, swapper;
+   union swap_u32 retVal, swapper;
 
    swapper.i = swappee;
    retVal.c[2] = swapper.c[3];
@@ -510,7 +509,7 @@
 static u32 LowerWordSwap(u32 swappee)
 #endif
 {
-   swap_u32 retVal, swapper;
+   union swap_u32 retVal, swapper;
 
    swapper.i = swappee;
    retVal.c[2] = swapper.c[2];
@@ -521,45 +520,27 @@
    return retVal.i;
 }
 
-#if 0 /* not used */
-
-static u32 EndianSwap(u32 swappee)
-{
-   swap_u32 retVal, swapper;
-
-   swapper.i = swappee;
-   retVal.c[0] = swapper.c[3];
-   retVal.c[1] = swapper.c[2];
-   retVal.c[2] = swapper.c[1];
-   retVal.c[3] = swapper.c[0];
-
-   return retVal.i;
-}
-
-#endif /* not used */
-
 #define SetBitInWord(theWord,bitPosition)       (*theWord) |= (0x0001 << bitPosition)
 #define SetBitInDWord(theWord,bitPosition)      (*theWord) |= (0x00000001 << bitPosition)
 #define ClearBitInWord(theWord,bitPosition)     (*theWord) &= ~(0x0001 << bitPosition)
 #define ClearBitInDWord(theWord,bitPosition)    (*theWord) &= ~(0x00000001 << bitPosition)
 
-static snd_korg1212rc snd_korg1212_Send1212Command(korg1212_t *korg1212, korg1212_dbcnst_t doorbellVal,
-                            u32 mailBox0Val, u32 mailBox1Val, u32 mailBox2Val, u32 mailBox3Val)
+static int snd_korg1212_Send1212Command(struct snd_korg1212 *korg1212,
+					enum korg1212_dbcnst doorbellVal,
+					u32 mailBox0Val, u32 mailBox1Val,
+					u32 mailBox2Val, u32 mailBox3Val)
 {
         u32 retryCount;
         u16 mailBox3Lo;
-	snd_korg1212rc rc = K1212_CMDRET_Success;
+	int rc = K1212_CMDRET_Success;
 
         if (!korg1212->outDoorbellPtr) {
-#if K1212_DEBUG_LEVEL > 1
-		K1212_DEBUG_PRINTK("K1212_DEBUG: CardUninitialized\n");
-#endif
+		K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: CardUninitialized\n");
                 return K1212_CMDRET_CardUninitialized;
 	}
 
-#if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- 0x%08x 0x%08x [%s]\n", doorbellVal, mailBox0Val, stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- 0x%08x 0x%08x [%s]\n",
+			   doorbellVal, mailBox0Val, stateName[korg1212->cardState]);
         for (retryCount = 0; retryCount < MAX_COMMAND_RETRIES; retryCount++) {
 		writel(mailBox3Val, korg1212->mailbox3Ptr);
                 writel(mailBox2Val, korg1212->mailbox2Ptr);
@@ -586,9 +567,7 @@
                 mailBox3Lo = readl(korg1212->mailbox3Ptr);
                 if (mailBox3Lo & COMMAND_ACK_MASK) {
                 	if ((mailBox3Lo & DOORBELL_VAL_MASK) == (doorbellVal & DOORBELL_VAL_MASK)) {
-#if K1212_DEBUG_LEVEL > 1
-				K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- Success\n");
-#endif
+				K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Card <- Success\n");
                                 rc = K1212_CMDRET_Success;
 				break;
                         }
@@ -597,9 +576,7 @@
         korg1212->cmdRetryCount += retryCount;
 
 	if (retryCount >= MAX_COMMAND_RETRIES) {
-#if K1212_DEBUG_LEVEL > 1
-		K1212_DEBUG_PRINTK("K1212_DEBUG: Card <- NoAckFromCard\n");
-#endif
+		K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Card <- NoAckFromCard\n");
         	rc = K1212_CMDRET_NoAckFromCard;
 	}
 
@@ -607,7 +584,7 @@
 }
 
 /* spinlock already held */
-static void snd_korg1212_SendStop(korg1212_t *korg1212)
+static void snd_korg1212_SendStop(struct snd_korg1212 *korg1212)
 {
 	if (! korg1212->stop_pending_cnt) {
 		korg1212->sharedBufferPtr->cardCommand = 0xffffffff;
@@ -618,7 +595,7 @@
 	}
 }
 
-static void snd_korg1212_SendStopAndWait(korg1212_t *korg1212)
+static void snd_korg1212_SendStopAndWait(struct snd_korg1212 *korg1212)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&korg1212->lock, flags);
@@ -631,17 +608,17 @@
 /* timer callback for checking the ack of stop request */
 static void snd_korg1212_timer_func(unsigned long data)
 {
-        korg1212_t *korg1212 = (korg1212_t *) data;
+        struct snd_korg1212 *korg1212 = (struct snd_korg1212 *) data;
+	unsigned long flags;
 	
-	spin_lock(&korg1212->lock);
+	spin_lock_irqsave(&korg1212->lock, flags);
 	if (korg1212->sharedBufferPtr->cardCommand == 0) {
 		/* ack'ed */
 		korg1212->stop_pending_cnt = 0;
 		korg1212->dsp_stop_is_processed = 1;
 		wake_up(&korg1212->wait);
-#if K1212_DEBUG_LEVEL > 1
-		K1212_DEBUG_PRINTK("K1212_DEBUG: Stop ack'ed [%s]\n", stateName[korg1212->cardState]);
-#endif
+		K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: Stop ack'ed [%s]\n",
+					   stateName[korg1212->cardState]);
 	} else {
 		if (--korg1212->stop_pending_cnt > 0) {
 			/* reprogram timer */
@@ -652,17 +629,17 @@
 			korg1212->sharedBufferPtr->cardCommand = 0;
 			korg1212->dsp_stop_is_processed = 1;
 			wake_up(&korg1212->wait);
-#if K1212_DEBUG_LEVEL > 0
-			K1212_DEBUG_PRINTK("K1212_DEBUG: Stop timeout [%s]\n", stateName[korg1212->cardState]);
-#endif
+			K1212_DEBUG_PRINTK("K1212_DEBUG: Stop timeout [%s]\n",
+					   stateName[korg1212->cardState]);
 		}
 	}
-	spin_unlock(&korg1212->lock);
+	spin_unlock_irqrestore(&korg1212->lock, flags);
 }
 
-static void snd_korg1212_TurnOnIdleMonitor(korg1212_t *korg1212)
+static int snd_korg1212_TurnOnIdleMonitor(struct snd_korg1212 *korg1212)
 {
 	unsigned long flags;
+	int rc;
 
         udelay(INTERCOMMAND_DELAY);
 	spin_lock_irqsave(&korg1212->lock, flags);
@@ -670,9 +647,10 @@
         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
 					  K1212_MODE_MonitorOn, 0, 0, 0);
         spin_unlock_irqrestore(&korg1212->lock, flags);
+	return rc;
 }
 
-static void snd_korg1212_TurnOffIdleMonitor(korg1212_t *korg1212)
+static void snd_korg1212_TurnOffIdleMonitor(struct snd_korg1212 *korg1212)
 {
         if (korg1212->idleMonitorOn) {
 		snd_korg1212_SendStopAndWait(korg1212);
@@ -680,16 +658,15 @@
         }
 }
 
-static inline void snd_korg1212_setCardState(korg1212_t * korg1212, CardState csState)
+static inline void snd_korg1212_setCardState(struct snd_korg1212 * korg1212, enum CardState csState)
 {
         korg1212->cardState = csState;
 }
 
-static int snd_korg1212_OpenCard(korg1212_t * korg1212)
+static int snd_korg1212_OpenCard(struct snd_korg1212 * korg1212)
 {
-#if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: OpenCard [%s] %d\n",
+			   stateName[korg1212->cardState], korg1212->opencnt);
 	down(&korg1212->open_mutex);
         if (korg1212->opencnt++ == 0) {
 		snd_korg1212_TurnOffIdleMonitor(korg1212);
@@ -700,11 +677,10 @@
         return 1;
 }
 
-static int snd_korg1212_CloseCard(korg1212_t * korg1212)
+static int snd_korg1212_CloseCard(struct snd_korg1212 * korg1212)
 {
-#if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n", stateName[korg1212->cardState], korg1212->opencnt);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard [%s] %d\n",
+			   stateName[korg1212->cardState], korg1212->opencnt);
 
 	down(&korg1212->open_mutex);
 	if (--(korg1212->opencnt)) {
@@ -713,12 +689,11 @@
 	}
 
         if (korg1212->cardState == K1212_STATE_SETUP) {
-                rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
+                int rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
                                 K1212_MODE_StopPlay, 0, 0, 0);
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
-
+		if (rc)
+			K1212_DEBUG_PRINTK("K1212_DEBUG: CloseCard - RC = %d [%s]\n",
+					   rc, stateName[korg1212->cardState]);
 		if (rc != K1212_CMDRET_Success) {
 			up(&korg1212->open_mutex);
                         return 0;
@@ -737,11 +712,12 @@
 }
 
 /* spinlock already held */
-static int snd_korg1212_SetupForPlay(korg1212_t * korg1212)
+static int snd_korg1212_SetupForPlay(struct snd_korg1212 * korg1212)
 {
-#if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay [%s] %d\n", stateName[korg1212->cardState], korg1212->setcnt);
-#endif
+	int rc;
+
+	K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay [%s] %d\n",
+			   stateName[korg1212->cardState], korg1212->setcnt);
 
         if (korg1212->setcnt++)
 		return 0;
@@ -749,10 +725,9 @@
         snd_korg1212_setCardState(korg1212, K1212_STATE_SETUP);
         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
                                         K1212_MODE_SetupPlay, 0, 0, 0);
-
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: SetupForPlay - RC = %d [%s]\n",
+				   rc, stateName[korg1212->cardState]);
         if (rc != K1212_CMDRET_Success) {
                 return 1;
         }
@@ -760,22 +735,21 @@
 }
 
 /* spinlock already held */
-static int snd_korg1212_TriggerPlay(korg1212_t * korg1212)
+static int snd_korg1212_TriggerPlay(struct snd_korg1212 * korg1212)
 {
-#if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay [%s] %d\n", stateName[korg1212->cardState], korg1212->playcnt);
-#endif
+	int rc;
+
+	K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay [%s] %d\n",
+			   stateName[korg1212->cardState], korg1212->playcnt);
 
         if (korg1212->playcnt++)
 		return 0;
 
         snd_korg1212_setCardState(korg1212, K1212_STATE_PLAYING);
         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_TriggerPlay, 0, 0, 0, 0);
-
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
-
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: TriggerPlay - RC = %d [%s]\n",
+				   rc, stateName[korg1212->cardState]);
         if (rc != K1212_CMDRET_Success) {
                 return 1;
         }
@@ -783,11 +757,10 @@
 }
 
 /* spinlock already held */
-static int snd_korg1212_StopPlay(korg1212_t * korg1212)
+static int snd_korg1212_StopPlay(struct snd_korg1212 * korg1212)
 {
-#if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: StopPlay [%s] %d\n", stateName[korg1212->cardState], korg1212->playcnt);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: StopPlay [%s] %d\n",
+			   stateName[korg1212->cardState], korg1212->playcnt);
 
         if (--(korg1212->playcnt)) 
 		return 0;
@@ -801,7 +774,7 @@
         return 0;
 }
 
-static void snd_korg1212_EnableCardInterrupts(korg1212_t * korg1212)
+static void snd_korg1212_EnableCardInterrupts(struct snd_korg1212 * korg1212)
 {
 	writel(PCI_INT_ENABLE_BIT            |
 	       PCI_DOORBELL_INT_ENABLE_BIT   |
@@ -813,37 +786,37 @@
 
 #if 0 /* not used */
 
-static int snd_korg1212_SetMonitorMode(korg1212_t *korg1212, MonitorModeSelector mode)
+static int snd_korg1212_SetMonitorMode(struct snd_korg1212 *korg1212,
+				       enum MonitorModeSelector mode)
 {
-#if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: SetMonitorMode [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: SetMonitorMode [%s]\n",
+			   stateName[korg1212->cardState]);
 
         switch (mode) {
-                case K1212_MONMODE_Off:
-                        if (korg1212->cardState != K1212_STATE_MONITOR) {
-                                return 0;
-                        } else {
-				snd_korg1212_SendStopAndWait(korg1212);
-                                snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
-                        }
-                        break;
+	case K1212_MONMODE_Off:
+		if (korg1212->cardState != K1212_STATE_MONITOR)
+			return 0;
+		else {
+			snd_korg1212_SendStopAndWait(korg1212);
+			snd_korg1212_setCardState(korg1212, K1212_STATE_OPEN);
+		}
+		break;
 
-                case K1212_MONMODE_On:
-                        if (korg1212->cardState != K1212_STATE_OPEN) {
-                                return 0;
-                        } else {
-                                snd_korg1212_setCardState(korg1212, K1212_STATE_MONITOR);
-                                rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
-                                                        K1212_MODE_MonitorOn, 0, 0, 0);
-                                if (rc != K1212_CMDRET_Success) {
-                                        return 0;
-                                }
-                        }
-                        break;
+	case K1212_MONMODE_On:
+		if (korg1212->cardState != K1212_STATE_OPEN)
+			return 0;
+		else {
+			int rc;
+			snd_korg1212_setCardState(korg1212, K1212_STATE_MONITOR);
+			rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
+							  K1212_MODE_MonitorOn, 0, 0, 0);
+			if (rc != K1212_CMDRET_Success)
+				return 0;
+		}
+		break;
 
-                default:
-                        return 0;
+	default:
+		return 0;
         }
 
         return 1;
@@ -851,44 +824,44 @@
 
 #endif /* not used */
 
-static inline int snd_korg1212_use_is_exclusive(korg1212_t *korg1212)
+static inline int snd_korg1212_use_is_exclusive(struct snd_korg1212 *korg1212)
 {
-	int ret = 1;
+	if (korg1212->playback_pid != korg1212->capture_pid &&
+	    korg1212->playback_pid >= 0 && korg1212->capture_pid >= 0)
+		return 0;
 
-	if ((korg1212->playback_pid != korg1212->capture_pid) &&
-	    (korg1212->playback_pid >= 0) && (korg1212->capture_pid >= 0)) {
-		ret = 0;
-	}
-	return ret;
+	return 1;
 }
 
-static int snd_korg1212_SetRate(korg1212_t *korg1212, int rate)
+static int snd_korg1212_SetRate(struct snd_korg1212 *korg1212, int rate)
 {
-        static ClockSourceIndex s44[] = { K1212_CLKIDX_AdatAt44_1K,
-                                          K1212_CLKIDX_WordAt44_1K,
-                                          K1212_CLKIDX_LocalAt44_1K };
-        static ClockSourceIndex s48[] = {
-                                          K1212_CLKIDX_AdatAt48K,
-                                          K1212_CLKIDX_WordAt48K,
-                                          K1212_CLKIDX_LocalAt48K };
-        int parm;
+        static enum ClockSourceIndex s44[] = {
+		K1212_CLKIDX_AdatAt44_1K,
+		K1212_CLKIDX_WordAt44_1K,
+		K1212_CLKIDX_LocalAt44_1K
+	};
+        static enum ClockSourceIndex s48[] = {
+		K1212_CLKIDX_AdatAt48K,
+		K1212_CLKIDX_WordAt48K,
+		K1212_CLKIDX_LocalAt48K
+	};
+        int parm, rc;
 
-        if (!snd_korg1212_use_is_exclusive (korg1212)) {
-                return -EBUSY;
-        }
+	if (!snd_korg1212_use_is_exclusive (korg1212))
+		return -EBUSY;
 
-        switch(rate) {
-                case 44100:
-                parm = s44[korg1212->clkSource];
-                break;
+	switch (rate) {
+	case 44100:
+		parm = s44[korg1212->clkSource];
+		break;
 
-                case 48000:
-                parm = s48[korg1212->clkSource];
-                break;
+	case 48000:
+		parm = s48[korg1212->clkSource];
+		break;
 
-                default:
-                return -EINVAL;
-        }
+	default:
+		return -EINVAL;
+	}
 
         korg1212->clkSrcRate = parm;
         korg1212->clkRate = rate;
@@ -897,19 +870,18 @@
 	rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
 					  ClockSourceSelector[korg1212->clkSrcRate],
 					  0, 0, 0);
-
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n",
+				   rc, stateName[korg1212->cardState]);
 
         return 0;
 }
 
-static int snd_korg1212_SetClockSource(korg1212_t *korg1212, int source)
+static int snd_korg1212_SetClockSource(struct snd_korg1212 *korg1212, int source)
 {
 
-        if (source<0 || source >2)
-           return -EINVAL;
+	if (source < 0 || source > 2)
+		return -EINVAL;
 
         korg1212->clkSource = source;
 
@@ -918,14 +890,14 @@
         return 0;
 }
 
-static void snd_korg1212_DisableCardInterrupts(korg1212_t *korg1212)
+static void snd_korg1212_DisableCardInterrupts(struct snd_korg1212 *korg1212)
 {
 	writel(0, korg1212->statusRegPtr);
 }
 
-static int snd_korg1212_WriteADCSensitivity(korg1212_t *korg1212)
+static int snd_korg1212_WriteADCSensitivity(struct snd_korg1212 *korg1212)
 {
-        SensBits  sensVals;
+        struct SensBits  sensVals;
         int       bitPosition;
         int       channel;
         int       clkIs48K;
@@ -935,9 +907,8 @@
         u16       count;
 	unsigned long flags;
 
-#if K1212_DEBUG_LEVEL > 0
-	K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity [%s]\n",
+			   stateName[korg1212->cardState]);
 
         // ----------------------------------------------------------------------------
         // initialize things.  The local init bit is always set when writing to the
@@ -1006,19 +977,17 @@
                 udelay(LOADSHIFT_DELAY);
 
                 for (bitPosition = 15; bitPosition >= 0; bitPosition--) {       // for all the bits
-                        if (channel == 0) {
-                                if (sensVals.l.leftSensBits & (0x0001 << bitPosition)) {
+			if (channel == 0) {
+				if (sensVals.l.leftSensBits & (0x0001 << bitPosition))
                                         SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS);     // data bit set high
-                                } else {
-                                        ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);   // data bit set low
-                                }
-                        } else {
-                                if (sensVals.r.rightSensBits & (0x0001 << bitPosition)) {
-                                SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS);     // data bit set high
-                                } else {
-                                ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);   // data bit set low
-                                }
-                        }
+				else
+					ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);   // data bit set low
+			} else {
+                                if (sensVals.r.rightSensBits & (0x0001 << bitPosition))
+					SetBitInWord(&controlValue, SET_SENS_DATA_BITPOS);     // data bit set high
+				else
+					ClearBitInWord(&controlValue, SET_SENS_DATA_BITPOS);   // data bit set low
+			}
 
                         ClearBitInWord(&controlValue, SET_SENS_CLOCK_BITPOS);
                         writew(controlValue, korg1212->sensRegPtr);                       // clock goes low
@@ -1059,12 +1028,11 @@
                 udelay(SENSCLKPULSE_WIDTH);
 
         if (monModeSet) {
-                rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
+                int rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SelectPlayMode,
                                 K1212_MODE_MonitorOn, 0, 0, 0);
-#if K1212_DEBUG_LEVEL > 0
-	        if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
-
+	        if (rc)
+			K1212_DEBUG_PRINTK("K1212_DEBUG: WriteADCSensivity - RC = %d [%s]\n",
+					   rc, stateName[korg1212->cardState]);
         }
 
 	spin_unlock_irqrestore(&korg1212->lock, flags);
@@ -1072,23 +1040,22 @@
         return 1;
 }
 
-static void snd_korg1212_OnDSPDownloadComplete(korg1212_t *korg1212)
+static void snd_korg1212_OnDSPDownloadComplete(struct snd_korg1212 *korg1212)
 {
-        int channel;
+        int channel, rc;
 
-#if K1212_DEBUG_LEVEL > 0
-        K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is complete. [%s]\n", stateName[korg1212->cardState]);
-#endif
+        K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is complete. [%s]\n",
+			   stateName[korg1212->cardState]);
 
         // ----------------------------------------------------
         // tell the card to boot
         // ----------------------------------------------------
         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_BootFromDSPPage4, 0, 0, 0, 0);
 
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Boot from Page 4 - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
-	mdelay(DSP_BOOT_DELAY_IN_MS);
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: Boot from Page 4 - RC = %d [%s]\n",
+				   rc, stateName[korg1212->cardState]);
+	msleep(DSP_BOOT_DELAY_IN_MS);
 
         // --------------------------------------------------------------------------------
         // Let the card know where all the buffers are.
@@ -1102,9 +1069,9 @@
                         0
         );
 
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Buffer Memory - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Buffer Memory - RC = %d [%s]\n",
+				   rc, stateName[korg1212->cardState]);
 
         udelay(INTERCOMMAND_DELAY);
 
@@ -1116,10 +1083,9 @@
                         0
         );
 
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Misc Memory - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
-
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: Configure Misc Memory - RC = %d [%s]\n",
+				   rc, stateName[korg1212->cardState]);
 
         // --------------------------------------------------------------------------------
         // Initialize the routing and volume tables, then update the card's state.
@@ -1138,16 +1104,16 @@
 	rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_SetClockSourceRate,
 					  ClockSourceSelector[korg1212->clkSrcRate],
 					  0, 0, 0);
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: Set Clock Source Selector - RC = %d [%s]\n",
+				   rc, stateName[korg1212->cardState]);
 
-	snd_korg1212_TurnOnIdleMonitor(korg1212);
+	rc = snd_korg1212_TurnOnIdleMonitor(korg1212);
 	snd_korg1212_setCardState(korg1212, K1212_STATE_READY);
 
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Set Monitor On - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: Set Monitor On - RC = %d [%s]\n",
+				   rc, stateName[korg1212->cardState]);
 
 	snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_COMPLETE);
 }
@@ -1155,7 +1121,7 @@
 static irqreturn_t snd_korg1212_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
         u32 doorbellValue;
-        korg1212_t *korg1212 = dev_id;
+        struct snd_korg1212 *korg1212 = dev_id;
 
 	if(irq != korg1212->irq)
 		return IRQ_NONE;
@@ -1176,9 +1142,9 @@
 
         switch (doorbellValue) {
                 case K1212_DB_DSPDownloadDone:
-#if K1212_DEBUG_LEVEL > 0
-                        K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DNLD count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]);
-#endif
+                        K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DNLD count - %ld, %x, [%s].\n",
+					   korg1212->irqcount, doorbellValue,
+					   stateName[korg1212->cardState]);
                         if (korg1212->cardState == K1212_STATE_DSP_IN_PROCESS) {
 				korg1212->dsp_is_loaded = 1;
 				wake_up(&korg1212->wait);
@@ -1189,10 +1155,10 @@
                 // an error occurred - stop the card
                 // ------------------------------------------------------------------------
                 case K1212_DB_DMAERROR:
-#if K1212_DEBUG_LEVEL > 1
-                        K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DMAE count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]);
-#endif
-			snd_printk(KERN_ERR "korg1212: DMA Error\n");	
+			K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ DMAE count - %ld, %x, [%s].\n",
+						   korg1212->irqcount, doorbellValue,
+						   stateName[korg1212->cardState]);
+			snd_printk(KERN_ERR "korg1212: DMA Error\n");
 			korg1212->errorcnt++;
 			korg1212->totalerrorcnt++;
 			korg1212->sharedBufferPtr->cardCommand = 0;
@@ -1204,17 +1170,16 @@
                 // the semaphore in case someone is waiting for this.
                 // ------------------------------------------------------------------------
                 case K1212_DB_CARDSTOPPED:
-#if K1212_DEBUG_LEVEL > 1
-                        K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ CSTP count - %ld, %x, [%s].\n", korg1212->irqcount, doorbellValue, stateName[korg1212->cardState]);
-#endif
+                        K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ CSTP count - %ld, %x, [%s].\n",
+						   korg1212->irqcount, doorbellValue,
+						   stateName[korg1212->cardState]);
 			korg1212->sharedBufferPtr->cardCommand = 0;
                         break;
 
                 default:
-#if K1212_DEBUG_LEVEL > 3
-                        K1212_DEBUG_PRINTK("K1212_DEBUG: IRQ DFLT count - %ld, %x, cpos=%d [%s].\n", korg1212->irqcount, doorbellValue, 
-				korg1212->currentBuffer, stateName[korg1212->cardState]);
-#endif
+			K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: IRQ DFLT count - %ld, %x, cpos=%d [%s].\n",
+			       korg1212->irqcount, doorbellValue, 
+			       korg1212->currentBuffer, stateName[korg1212->cardState]);
                         if ((korg1212->cardState > K1212_STATE_SETUP) || korg1212->idleMonitorOn) {
                                 korg1212->currentBuffer++;
 
@@ -1246,19 +1211,18 @@
 	return IRQ_HANDLED;
 }
 
-static int snd_korg1212_downloadDSPCode(korg1212_t *korg1212)
+static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212)
 {
+	int rc;
 
-#if K1212_DEBUG_LEVEL > 0
-        K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is starting... [%s]\n", stateName[korg1212->cardState]);
-#endif
+        K1212_DEBUG_PRINTK("K1212_DEBUG: DSP download is starting... [%s]\n",
+			   stateName[korg1212->cardState]);
 
         // ---------------------------------------------------------------
         // verify the state of the card before proceeding.
         // ---------------------------------------------------------------
-        if (korg1212->cardState >= K1212_STATE_DSP_IN_PROCESS) {
+        if (korg1212->cardState >= K1212_STATE_DSP_IN_PROCESS)
                 return 1;
-        }
 
         snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS);
 
@@ -1267,10 +1231,9 @@
         rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload,
                                      UpperWordSwap(korg1212->dma_dsp.addr),
                                      0, 0, 0);
-
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Start DSP Download RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: Start DSP Download RC = %d [%s]\n",
+				   rc, stateName[korg1212->cardState]);
 
 	korg1212->dsp_is_loaded = 0;
 	wait_event_timeout(korg1212->wait, korg1212->dsp_is_loaded, HZ * CARD_BOOT_TIMEOUT);
@@ -1282,7 +1245,7 @@
         return 0;
 }
 
-static snd_pcm_hardware_t snd_korg1212_playback_info =
+static struct snd_pcm_hardware snd_korg1212_playback_info =
 {
 	.info =              (SNDRV_PCM_INFO_MMAP |
                               SNDRV_PCM_INFO_MMAP_VALID |
@@ -1302,7 +1265,7 @@
         .fifo_size =          0,
 };
 
-static snd_pcm_hardware_t snd_korg1212_capture_info =
+static struct snd_pcm_hardware snd_korg1212_capture_info =
 {
         .info =              (SNDRV_PCM_INFO_MMAP |
                               SNDRV_PCM_INFO_MMAP_VALID |
@@ -1322,21 +1285,21 @@
         .fifo_size =          0,
 };
 
-static int snd_korg1212_silence(korg1212_t *korg1212, int pos, int count, int offset, int size)
+static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int count, int offset, int size)
 {
-	KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
+	struct KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
 	int i;
 
-#if K1212_DEBUG_LEVEL > 2
-	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count);
-#endif
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n",
+				   pos, offset, size, count);
 	snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
 
 	for (i=0; i < count; i++) {
 #if K1212_DEBUG_LEVEL > 0
 		if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
 		     (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
-			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_silence KERNEL EFAULT dst=%p iter=%d\n", dst, i);
+			printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_silence KERNEL EFAULT dst=%p iter=%d\n",
+			       dst, i);
 			return -EFAULT;
 		}
 #endif
@@ -1347,29 +1310,26 @@
 	return 0;
 }
 
-static int snd_korg1212_copy_to(korg1212_t *korg1212, void __user *dst, int pos, int count, int offset, int size)
+static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst, int pos, int count, int offset, int size)
 {
-	KorgAudioFrame * src =  korg1212->recordDataBufsPtr[0].bufferData + pos;
+	struct KorgAudioFrame * src =  korg1212->recordDataBufsPtr[0].bufferData + pos;
 	int i, rc;
 
-#if K1212_DEBUG_LEVEL > 2
-	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n", pos, offset, size);
-#endif
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n",
+				   pos, offset, size);
 	snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
 
 	for (i=0; i < count; i++) {
 #if K1212_DEBUG_LEVEL > 0
 		if ( (void *) src < (void *) korg1212->recordDataBufsPtr ||
 		     (void *) src > (void *) korg1212->recordDataBufsPtr[8].bufferData ) {
-			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
+			printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_to KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
 			return -EFAULT;
 		}
 #endif
 		rc = copy_to_user(dst + offset, src, size);
 		if (rc) {
-#if K1212_DEBUG_LEVEL > 0
 			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_to USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
-#endif
 			return -EFAULT;
 		}
 		src++;
@@ -1379,14 +1339,13 @@
 	return 0;
 }
 
-static int snd_korg1212_copy_from(korg1212_t *korg1212, void __user *src, int pos, int count, int offset, int size)
+static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *src, int pos, int count, int offset, int size)
 {
-	KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
+	struct KorgAudioFrame * dst =  korg1212->playDataBufsPtr[0].bufferData + pos;
 	int i, rc;
 
-#if K1212_DEBUG_LEVEL > 2
-	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count);
-#endif
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n",
+				   pos, offset, size, count);
 
 	snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL);
 
@@ -1394,15 +1353,13 @@
 #if K1212_DEBUG_LEVEL > 0
 		if ( (void *) dst < (void *) korg1212->playDataBufsPtr ||
 		     (void *) dst > (void *) korg1212->playDataBufsPtr[8].bufferData ) {
-			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
+			printk(KERN_DEBUG "K1212_DEBUG: snd_korg1212_copy_from KERNEL EFAULT, src=%p dst=%p iter=%d\n", src, dst, i);
 			return -EFAULT;
 		}
 #endif
 		rc = copy_from_user((void*) dst + offset, src, size);
 		if (rc) {
-#if K1212_DEBUG_LEVEL > 0
 			K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_copy_from USER EFAULT src=%p dst=%p iter=%d\n", src, dst, i);
-#endif
 			return -EFAULT;
 		}
 		dst++;
@@ -1412,26 +1369,24 @@
 	return 0;
 }
 
-static void snd_korg1212_free_pcm(snd_pcm_t *pcm)
+static void snd_korg1212_free_pcm(struct snd_pcm *pcm)
 {
-        korg1212_t *korg1212 = (korg1212_t *) pcm->private_data;
+        struct snd_korg1212 *korg1212 = pcm->private_data;
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_free_pcm [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_free_pcm [%s]\n",
+			   stateName[korg1212->cardState]);
 
         korg1212->pcm = NULL;
 }
 
-static int snd_korg1212_playback_open(snd_pcm_substream_t *substream)
+static int snd_korg1212_playback_open(struct snd_pcm_substream *substream)
 {
         unsigned long flags;
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
-        snd_pcm_runtime_t *runtime = substream->runtime;
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_pcm_runtime *runtime = substream->runtime;
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_open [%s]\n",
+			   stateName[korg1212->cardState]);
 
         snd_pcm_set_sync(substream);    // ???
 
@@ -1455,15 +1410,14 @@
 }
 
 
-static int snd_korg1212_capture_open(snd_pcm_substream_t *substream)
+static int snd_korg1212_capture_open(struct snd_pcm_substream *substream)
 {
         unsigned long flags;
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
-        snd_pcm_runtime_t *runtime = substream->runtime;
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_pcm_runtime *runtime = substream->runtime;
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_open [%s]\n",
+			   stateName[korg1212->cardState]);
 
         snd_pcm_set_sync(substream);
 
@@ -1481,18 +1435,18 @@
 
         spin_unlock_irqrestore(&korg1212->lock, flags);
 
-        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, kPlayBufferFrames, kPlayBufferFrames);
+        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+				     kPlayBufferFrames, kPlayBufferFrames);
         return 0;
 }
 
-static int snd_korg1212_playback_close(snd_pcm_substream_t *substream)
+static int snd_korg1212_playback_close(struct snd_pcm_substream *substream)
 {
         unsigned long flags;
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_close [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_close [%s]\n",
+			   stateName[korg1212->cardState]);
 
 	snd_korg1212_silence(korg1212, 0, K1212_MAX_SAMPLES, 0, korg1212->channels * 2);
 
@@ -1508,14 +1462,13 @@
         return 0;
 }
 
-static int snd_korg1212_capture_close(snd_pcm_substream_t *substream)
+static int snd_korg1212_capture_close(struct snd_pcm_substream *substream)
 {
         unsigned long flags;
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_close [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_close [%s]\n",
+			   stateName[korg1212->cardState]);
 
         spin_lock_irqsave(&korg1212->lock, flags);
 
@@ -1529,39 +1482,34 @@
         return 0;
 }
 
-static int snd_korg1212_ioctl(snd_pcm_substream_t *substream,
+static int snd_korg1212_ioctl(struct snd_pcm_substream *substream,
 			     unsigned int cmd, void *arg)
 {
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_ioctl: cmd=%d\n", cmd);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_ioctl: cmd=%d\n", cmd);
 
 	if (cmd == SNDRV_PCM_IOCTL1_CHANNEL_INFO ) {
-		snd_pcm_channel_info_t *info = arg;
+		struct snd_pcm_channel_info *info = arg;
         	info->offset = 0;
         	info->first = info->channel * 16;
         	info->step = 256;
-#if K1212_DEBUG_LEVEL > 0
 		K1212_DEBUG_PRINTK("K1212_DEBUG: channel_info %d:, offset=%ld, first=%d, step=%d\n", info->channel, info->offset, info->first, info->step);
-#endif
 		return 0;
 	}
 
         return snd_pcm_lib_ioctl(substream, cmd, arg);
 }
 
-static int snd_korg1212_hw_params(snd_pcm_substream_t *substream,
-                             snd_pcm_hw_params_t *params)
+static int snd_korg1212_hw_params(struct snd_pcm_substream *substream,
+                             struct snd_pcm_hw_params *params)
 {
         unsigned long flags;
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
         int err;
 	pid_t this_pid;
 	pid_t other_pid;
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_hw_params [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_hw_params [%s]\n",
+			   stateName[korg1212->cardState]);
 
         spin_lock_irqsave(&korg1212->lock, flags);
 
@@ -1603,22 +1551,20 @@
         return 0;
 }
 
-static int snd_korg1212_prepare(snd_pcm_substream_t *substream)
+static int snd_korg1212_prepare(struct snd_pcm_substream *substream)
 {
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
 	int rc;
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare [%s]\n",
+			   stateName[korg1212->cardState]);
 
 	spin_lock_irq(&korg1212->lock);
 
 	/* FIXME: we should wait for ack! */
 	if (korg1212->stop_pending_cnt > 0) {
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare - Stop is pending... [%s]\n", stateName[korg1212->cardState]);
-#endif
+		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_prepare - Stop is pending... [%s]\n",
+				   stateName[korg1212->cardState]);
         	spin_unlock_irq(&korg1212->lock);
 		return -EAGAIN;
 		/*
@@ -1637,24 +1583,21 @@
 	return rc ? -EINVAL : 0;
 }
 
-static int snd_korg1212_trigger(snd_pcm_substream_t *substream,
+static int snd_korg1212_trigger(struct snd_pcm_substream *substream,
                            int cmd)
 {
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
 	int rc;
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger [%s] cmd=%d\n", stateName[korg1212->cardState], cmd);
-#endif
+	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger [%s] cmd=%d\n",
+			   stateName[korg1212->cardState], cmd);
 
 	spin_lock(&korg1212->lock);
         switch (cmd) {
                 case SNDRV_PCM_TRIGGER_START:
 /*
 			if (korg1212->running) {
-#if K1212_DEBUG_LEVEL > 1
-				K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger: Already running?\n");
-#endif
+				K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_trigger: Already running?\n");
 				break;
 			}
 */
@@ -1665,9 +1608,7 @@
                 case SNDRV_PCM_TRIGGER_STOP:
 /*
 			if (!korg1212->running) {
-#if K1212_DEBUG_LEVEL > 1
-				K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_trigger: Already stopped?\n");
-#endif
+				K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_trigger: Already stopped?\n");
 				break;
 			}
 */
@@ -1683,82 +1624,75 @@
         return rc ? -EINVAL : 0;
 }
 
-static snd_pcm_uframes_t snd_korg1212_playback_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_korg1212_playback_pointer(struct snd_pcm_substream *substream)
 {
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
         snd_pcm_uframes_t pos;
 
 	pos = korg1212->currentBuffer * kPlayBufferFrames;
 
-#if K1212_DEBUG_LEVEL > 2
-	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_pointer [%s] %ld\n", 
-			stateName[korg1212->cardState], pos);
-#endif
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_pointer [%s] %ld\n", 
+				   stateName[korg1212->cardState], pos);
 
         return pos;
 }
 
-static snd_pcm_uframes_t snd_korg1212_capture_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_korg1212_capture_pointer(struct snd_pcm_substream *substream)
 {
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
         snd_pcm_uframes_t pos;
 
 	pos = korg1212->currentBuffer * kPlayBufferFrames;
 
-#if K1212_DEBUG_LEVEL > 2
-	K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_pointer [%s] %ld\n",
-			stateName[korg1212->cardState], pos);
-#endif
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_capture_pointer [%s] %ld\n",
+				   stateName[korg1212->cardState], pos);
 
         return pos;
 }
 
-static int snd_korg1212_playback_copy(snd_pcm_substream_t *substream,
+static int snd_korg1212_playback_copy(struct snd_pcm_substream *substream,
                         int channel, /* not used (interleaved data) */
                         snd_pcm_uframes_t pos,
                         void __user *src,
                         snd_pcm_uframes_t count)
 {
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
 
-#if K1212_DEBUG_LEVEL > 2
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_copy [%s] %ld %ld\n", stateName[korg1212->cardState], pos, count);
-#endif
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_copy [%s] %ld %ld\n",
+				   stateName[korg1212->cardState], pos, count);
  
 	return snd_korg1212_copy_from(korg1212, src, pos, count, 0, korg1212->channels * 2);
 
 }
 
-static int snd_korg1212_playback_silence(snd_pcm_substream_t *substream,
+static int snd_korg1212_playback_silence(struct snd_pcm_substream *substream,
                            int channel, /* not used (interleaved data) */
                            snd_pcm_uframes_t pos,
                            snd_pcm_uframes_t count)
 {
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
 
-#if K1212_DEBUG_LEVEL > 0
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_playback_silence [%s]\n", stateName[korg1212->cardState]);
-#endif
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_playback_silence [%s]\n",
+				   stateName[korg1212->cardState]);
 
 	return snd_korg1212_silence(korg1212, pos, count, 0, korg1212->channels * 2);
 }
 
-static int snd_korg1212_capture_copy(snd_pcm_substream_t *substream,
+static int snd_korg1212_capture_copy(struct snd_pcm_substream *substream,
                         int channel, /* not used (interleaved data) */
                         snd_pcm_uframes_t pos,
                         void __user *dst,
                         snd_pcm_uframes_t count)
 {
-        korg1212_t *korg1212 = snd_pcm_substream_chip(substream);
+        struct snd_korg1212 *korg1212 = snd_pcm_substream_chip(substream);
 
-#if K1212_DEBUG_LEVEL > 2
-		K1212_DEBUG_PRINTK("K1212_DEBUG: snd_korg1212_capture_copy [%s] %ld %ld\n", stateName[korg1212->cardState], pos, count);
-#endif
+	K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_capture_copy [%s] %ld %ld\n",
+				   stateName[korg1212->cardState], pos, count);
 
 	return snd_korg1212_copy_to(korg1212, dst, pos, count, 0, korg1212->channels * 2);
 }
 
-static snd_pcm_ops_t snd_korg1212_playback_ops = {
+static struct snd_pcm_ops snd_korg1212_playback_ops = {
         .open =		snd_korg1212_playback_open,
         .close =	snd_korg1212_playback_close,
         .ioctl =	snd_korg1212_ioctl,
@@ -1770,7 +1704,7 @@
         .silence =	snd_korg1212_playback_silence,
 };
 
-static snd_pcm_ops_t snd_korg1212_capture_ops = {
+static struct snd_pcm_ops snd_korg1212_capture_ops = {
 	.open =		snd_korg1212_capture_open,
 	.close =	snd_korg1212_capture_close,
 	.ioctl =	snd_korg1212_ioctl,
@@ -1785,16 +1719,18 @@
  * Control Interface
  */
 
-static int snd_korg1212_control_phase_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_korg1212_control_phase_info(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
 	return 0;
 }
 
-static int snd_korg1212_control_phase_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_phase_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *u)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
 	int i = kcontrol->private_value;
 
 	spin_lock_irq(&korg1212->lock);
@@ -1809,9 +1745,10 @@
         return 0;
 }
 
-static int snd_korg1212_control_phase_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_phase_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *u)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
         int change = 0;
         int i, val;
 
@@ -1846,7 +1783,8 @@
         return change;
 }
 
-static int snd_korg1212_control_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_korg1212_control_volume_info(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
@@ -1855,9 +1793,10 @@
         return 0;
 }
 
-static int snd_korg1212_control_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_volume_get(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *u)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
         int i;
 
 	spin_lock_irq(&korg1212->lock);
@@ -1873,9 +1812,10 @@
         return 0;
 }
 
-static int snd_korg1212_control_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_volume_put(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *u)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
         int change = 0;
         int i;
 	int val;
@@ -1905,7 +1845,8 @@
         return change;
 }
 
-static int snd_korg1212_control_route_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_korg1212_control_route_info(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = (kcontrol->private_value >= 8) ? 2 : 1;
@@ -1917,9 +1858,10 @@
 	return 0;
 }
 
-static int snd_korg1212_control_route_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_route_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *u)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
         int i;
 
 	spin_lock_irq(&korg1212->lock);
@@ -1935,9 +1877,10 @@
         return 0;
 }
 
-static int snd_korg1212_control_route_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_route_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *u)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
         int change = 0, i;
 
 	spin_lock_irq(&korg1212->lock);
@@ -1961,7 +1904,8 @@
         return change;
 }
 
-static int snd_korg1212_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_korg1212_control_info(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
 {
         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
         uinfo->count = 2;
@@ -1970,9 +1914,10 @@
         return 0;
 }
 
-static int snd_korg1212_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_get(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *u)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&korg1212->lock);
 
@@ -1984,9 +1929,10 @@
         return 0;
 }
 
-static int snd_korg1212_control_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+static int snd_korg1212_control_put(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *u)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
         int change = 0;
 
 	spin_lock_irq(&korg1212->lock);
@@ -2008,7 +1954,8 @@
         return change;
 }
 
-static int snd_korg1212_control_sync_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_korg1212_control_sync_info(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -2020,9 +1967,10 @@
 	return 0;
 }
 
-static int snd_korg1212_control_sync_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_korg1212_control_sync_get(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&korg1212->lock);
 
@@ -2032,9 +1980,10 @@
 	return 0;
 }
 
-static int snd_korg1212_control_sync_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_korg1212_control_sync_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	korg1212_t *korg1212 = snd_kcontrol_chip(kcontrol);
+	struct snd_korg1212 *korg1212 = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 
@@ -2075,7 +2024,7 @@
 		.private_value = ord,								\
         }
 
-static snd_kcontrol_new_t snd_korg1212_controls[] = {
+static struct snd_kcontrol_new snd_korg1212_controls[] = {
         MON_MIXER(8, "Analog"),
 	MON_MIXER(10, "SPDIF"), 
         MON_MIXER(0, "ADAT-1"), MON_MIXER(1, "ADAT-2"), MON_MIXER(2, "ADAT-3"), MON_MIXER(3, "ADAT-4"),
@@ -2102,10 +2051,11 @@
  * proc interface
  */
 
-static void snd_korg1212_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_korg1212_proc_read(struct snd_info_entry *entry,
+				   struct snd_info_buffer *buffer)
 {
 	int n;
-	korg1212_t *korg1212 = (korg1212_t *)entry->private_data;
+	struct snd_korg1212 *korg1212 = entry->private_data;
 
 	snd_iprintf(buffer, korg1212->card->longname);
 	snd_iprintf(buffer, " (index #%d)\n", korg1212->card->number + 1);
@@ -2129,23 +2079,23 @@
         snd_iprintf(buffer, "    Error count: %ld\n", korg1212->totalerrorcnt);
 }
 
-static void __devinit snd_korg1212_proc_init(korg1212_t *korg1212)
+static void __devinit snd_korg1212_proc_init(struct snd_korg1212 *korg1212)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(korg1212->card, "korg1212", &entry))
 		snd_info_set_text_ops(entry, korg1212, 1024, snd_korg1212_proc_read);
 }
 
 static int
-snd_korg1212_free(korg1212_t *korg1212)
+snd_korg1212_free(struct snd_korg1212 *korg1212)
 {
         snd_korg1212_TurnOffIdleMonitor(korg1212);
 
         if (korg1212->irq >= 0) {
                 synchronize_irq(korg1212->irq);                
                 snd_korg1212_DisableCardInterrupts(korg1212);
-                free_irq(korg1212->irq, (void *)korg1212);
+                free_irq(korg1212->irq, korg1212);
                 korg1212->irq = -1;
         }
         
@@ -2194,25 +2144,23 @@
         return 0;
 }
 
-static int snd_korg1212_dev_free(snd_device_t *device)
+static int snd_korg1212_dev_free(struct snd_device *device)
 {
-        korg1212_t *korg1212 = device->device_data;
-#if K1212_DEBUG_LEVEL > 0
+        struct snd_korg1212 *korg1212 = device->device_data;
         K1212_DEBUG_PRINTK("K1212_DEBUG: Freeing device\n");
-#endif
 	return snd_korg1212_free(korg1212);
 }
 
-static int __devinit snd_korg1212_create(snd_card_t * card, struct pci_dev *pci,
-                                         korg1212_t ** rchip)
+static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *pci,
+                                         struct snd_korg1212 ** rchip)
 
 {
-        int err;
+        int err, rc;
         unsigned int i;
 	unsigned ioport_size, iomem_size, iomem2_size;
-        korg1212_t * korg1212;
+        struct snd_korg1212 * korg1212;
 
-        static snd_device_ops_t ops = {
+        static struct snd_device_ops ops = {
                 .dev_free = snd_korg1212_dev_free,
         };
 
@@ -2270,7 +2218,6 @@
 	ioport_size = pci_resource_len(korg1212->pci, 1);
 	iomem2_size = pci_resource_len(korg1212->pci, 2);
 
-#if K1212_DEBUG_LEVEL > 0
         K1212_DEBUG_PRINTK("K1212_DEBUG: resources:\n"
                    "    iomem = 0x%lx (%d)\n"
 		   "    ioport  = 0x%lx (%d)\n"
@@ -2280,7 +2227,6 @@
 		   korg1212->ioport, ioport_size,
 		   korg1212->iomem2, iomem2_size,
 		   stateName[korg1212->cardState]);
-#endif
 
         if ((korg1212->iobase = ioremap(korg1212->iomem, iomem_size)) == NULL) {
 		snd_printk(KERN_ERR "korg1212: unable to remap memory region 0x%lx-0x%lx\n", korg1212->iomem,
@@ -2291,7 +2237,7 @@
 
         err = request_irq(pci->irq, snd_korg1212_interrupt,
                           SA_INTERRUPT|SA_SHIRQ,
-                          "korg1212", (void *) korg1212);
+                          "korg1212", korg1212);
 
         if (err) {
 		snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
@@ -2314,7 +2260,6 @@
         korg1212->sensRegPtr = (u16 __iomem *) (korg1212->iobase + SENS_CONTROL_OFFSET);
         korg1212->idRegPtr = (u32 __iomem *) (korg1212->iobase + DEV_VEND_ID_OFFSET);
 
-#if K1212_DEBUG_LEVEL > 0
         K1212_DEBUG_PRINTK("K1212_DEBUG: card registers:\n"
                    "    Status register = 0x%p\n"
                    "    OutDoorbell     = 0x%p\n"
@@ -2338,24 +2283,21 @@
                    korg1212->sensRegPtr,
                    korg1212->idRegPtr,
 		   stateName[korg1212->cardState]);
-#endif
 
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
-				sizeof(KorgSharedBuffer), &korg1212->dma_shared) < 0) {
-		snd_printk(KERN_ERR "korg1212: can not allocate shared buffer memory (%Zd bytes)\n", sizeof(KorgSharedBuffer));
+				sizeof(struct KorgSharedBuffer), &korg1212->dma_shared) < 0) {
+		snd_printk(KERN_ERR "korg1212: can not allocate shared buffer memory (%Zd bytes)\n", sizeof(struct KorgSharedBuffer));
                 snd_korg1212_free(korg1212);
                 return -ENOMEM;
         }
-        korg1212->sharedBufferPtr = (KorgSharedBuffer *)korg1212->dma_shared.area;
+        korg1212->sharedBufferPtr = (struct KorgSharedBuffer *)korg1212->dma_shared.area;
         korg1212->sharedBufferPhy = korg1212->dma_shared.addr;
 
-#if K1212_DEBUG_LEVEL > 0
-        K1212_DEBUG_PRINTK("K1212_DEBUG: Shared Buffer Area = 0x%p (0x%08lx), %d bytes\n", korg1212->sharedBufferPtr, korg1212->sharedBufferPhy, sizeof(KorgSharedBuffer));
-#endif
+        K1212_DEBUG_PRINTK("K1212_DEBUG: Shared Buffer Area = 0x%p (0x%08lx), %d bytes\n", korg1212->sharedBufferPtr, korg1212->sharedBufferPhy, sizeof(struct KorgSharedBuffer));
 
 #ifndef K1212_LARGEALLOC
 
-        korg1212->DataBufsSize = sizeof(KorgAudioBuffer) * kNumBuffers;
+        korg1212->DataBufsSize = sizeof(struct KorgAudioBuffer) * kNumBuffers;
 
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				korg1212->DataBufsSize, &korg1212->dma_play) < 0) {
@@ -2363,13 +2305,11 @@
                 snd_korg1212_free(korg1212);
                 return -ENOMEM;
         }
-	korg1212->playDataBufsPtr = (KorgAudioBuffer *)korg1212->dma_play.area;
+	korg1212->playDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_play.area;
 	korg1212->PlayDataPhy = korg1212->dma_play.addr;
 
-#if K1212_DEBUG_LEVEL > 0
         K1212_DEBUG_PRINTK("K1212_DEBUG: Play Data Area = 0x%p (0x%08x), %d bytes\n",
 		korg1212->playDataBufsPtr, korg1212->PlayDataPhy, korg1212->DataBufsSize);
-#endif
 
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				korg1212->DataBufsSize, &korg1212->dma_rec) < 0) {
@@ -2377,31 +2317,29 @@
                 snd_korg1212_free(korg1212);
                 return -ENOMEM;
         }
-        korg1212->recordDataBufsPtr = (KorgAudioBuffer *)korg1212->dma_rec.area;
+        korg1212->recordDataBufsPtr = (struct KorgAudioBuffer *)korg1212->dma_rec.area;
         korg1212->RecDataPhy = korg1212->dma_rec.addr;
 
-#if K1212_DEBUG_LEVEL > 0
         K1212_DEBUG_PRINTK("K1212_DEBUG: Record Data Area = 0x%p (0x%08x), %d bytes\n",
 		korg1212->recordDataBufsPtr, korg1212->RecDataPhy, korg1212->DataBufsSize);
-#endif
 
 #else // K1212_LARGEALLOC
 
         korg1212->recordDataBufsPtr = korg1212->sharedBufferPtr->recordDataBufs;
         korg1212->playDataBufsPtr = korg1212->sharedBufferPtr->playDataBufs;
-        korg1212->PlayDataPhy = (u32) &((KorgSharedBuffer *) korg1212->sharedBufferPhy)->playDataBufs;
-        korg1212->RecDataPhy  = (u32) &((KorgSharedBuffer *) korg1212->sharedBufferPhy)->recordDataBufs;
+        korg1212->PlayDataPhy = (u32) &((struct KorgSharedBuffer *) korg1212->sharedBufferPhy)->playDataBufs;
+        korg1212->RecDataPhy  = (u32) &((struct KorgSharedBuffer *) korg1212->sharedBufferPhy)->recordDataBufs;
 
 #endif // K1212_LARGEALLOC
 
         korg1212->dspCodeSize = sizeof (dspCode);
 
         korg1212->VolumeTablePhy = korg1212->sharedBufferPhy +
-		offsetof(KorgSharedBuffer, volumeData);
+		offsetof(struct KorgSharedBuffer, volumeData);
         korg1212->RoutingTablePhy = korg1212->sharedBufferPhy +
-		offsetof(KorgSharedBuffer, routeData);
+		offsetof(struct KorgSharedBuffer, routeData);
         korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
-		offsetof(KorgSharedBuffer, AdatTimeCode);
+		offsetof(struct KorgSharedBuffer, AdatTimeCode);
 
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				korg1212->dspCodeSize, &korg1212->dma_dsp) < 0) {
@@ -2410,17 +2348,14 @@
                 return -ENOMEM;
         }
 
-#if K1212_DEBUG_LEVEL > 0
         K1212_DEBUG_PRINTK("K1212_DEBUG: DSP Code area = 0x%p (0x%08x) %d bytes [%s]\n",
 		   korg1212->dma_dsp.area, korg1212->dma_dsp.addr, korg1212->dspCodeSize,
 		   stateName[korg1212->cardState]);
-#endif
 
 	rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
 
-#if K1212_DEBUG_LEVEL > 0
-	if (rc) K1212_DEBUG_PRINTK("K1212_DEBUG: Reboot Card - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
-#endif
+	if (rc)
+		K1212_DEBUG_PRINTK("K1212_DEBUG: Reboot Card - RC = %d [%s]\n", rc, stateName[korg1212->cardState]);
 
         if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, korg1212, &ops)) < 0) {
                 snd_korg1212_free(korg1212);
@@ -2434,8 +2369,7 @@
         if (snd_korg1212_downloadDSPCode(korg1212))
         	return -EBUSY;
 
-	snd_printk(KERN_ERR 
-	       "korg1212: dspMemPhy = %08x U[%08x], "
+        K1212_DEBUG_PRINTK("korg1212: dspMemPhy = %08x U[%08x], "
                "PlayDataPhy = %08x L[%08x]\n"
 	       "korg1212: RecDataPhy = %08x L[%08x], "
                "VolumeTablePhy = %08x L[%08x]\n"
@@ -2461,9 +2395,6 @@
 
 	korg1212->pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
 
-	//snd_pcm_lib_preallocate_pages_for_all(korg1212->pcm,
-	//			K1212_MAX_BUF_SIZE, K1212_MAX_BUF_SIZE, GFP_KERNEL);
-
         for (i = 0; i < ARRAY_SIZE(snd_korg1212_controls); i++) {
                 err = snd_ctl_add(korg1212->card, snd_ctl_new1(&snd_korg1212_controls[i], korg1212));
                 if (err < 0)
@@ -2488,8 +2419,8 @@
 		const struct pci_device_id *pci_id)
 {
 	static int dev;
-	korg1212_t *korg1212;
-	snd_card_t *card;
+	struct snd_korg1212 *korg1212;
+	struct snd_card *card;
 	int err;
 
 	if (dev >= SNDRV_CARDS) {
@@ -2513,9 +2444,7 @@
 	sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname,
 		korg1212->iomem, korg1212->irq);
 
-#if K1212_DEBUG_LEVEL > 0
         K1212_DEBUG_PRINTK("K1212_DEBUG: %s\n", card->longname);
-#endif
 
 	if ((err = snd_card_register(card)) < 0) {
 		snd_card_free(card);
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index ede7a75..d3ef0cc 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -767,9 +767,6 @@
 /*
  */
 
-typedef struct snd_m3_dma m3_dma_t;
-typedef struct snd_m3 m3_t;
-
 /* quirk lists */
 struct m3_quirk {
 	const char *name;	/* device name */
@@ -791,11 +788,10 @@
 	int max;
 };
 
-struct snd_m3_dma {
+struct m3_dma {
 
 	int number;
-	m3_t *chip;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 
 	struct assp_instance {
 		unsigned short code, data;
@@ -821,16 +817,16 @@
     
 struct snd_m3 {
 	
-	snd_card_t *card;
+	struct snd_card *card;
 
 	unsigned long iobase;
 
 	int irq;
 	unsigned int allegro_flag : 1;
 
-	ac97_t *ac97;
+	struct snd_ac97 *ac97;
 
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 
 	struct pci_dev *pci;
 	struct m3_quirk *quirk;
@@ -851,17 +847,17 @@
 	int amp_gpio;
 
 	/* midi */
-	snd_rawmidi_t *rmidi;
+	struct snd_rawmidi *rmidi;
 
 	/* pcm streams */
 	int num_substreams;
-	m3_dma_t *substreams;
+	struct m3_dma *substreams;
 
 	spinlock_t reg_lock;
 	spinlock_t ac97_lock;
 
-	snd_kcontrol_t *master_switch;
-	snd_kcontrol_t *master_volume;
+	struct snd_kcontrol *master_switch;
+	struct snd_kcontrol *master_volume;
 	struct tasklet_struct hwvol_tq;
 
 #ifdef CONFIG_PM
@@ -1021,22 +1017,22 @@
  * lowlevel functions
  */
 
-static inline void snd_m3_outw(m3_t *chip, u16 value, unsigned long reg)
+static inline void snd_m3_outw(struct snd_m3 *chip, u16 value, unsigned long reg)
 {
 	outw(value, chip->iobase + reg);
 }
 
-static inline u16 snd_m3_inw(m3_t *chip, unsigned long reg)
+static inline u16 snd_m3_inw(struct snd_m3 *chip, unsigned long reg)
 {
 	return inw(chip->iobase + reg);
 }
 
-static inline void snd_m3_outb(m3_t *chip, u8 value, unsigned long reg)
+static inline void snd_m3_outb(struct snd_m3 *chip, u8 value, unsigned long reg)
 {
 	outb(value, chip->iobase + reg);
 }
 
-static inline u8 snd_m3_inb(m3_t *chip, unsigned long reg)
+static inline u8 snd_m3_inb(struct snd_m3 *chip, unsigned long reg)
 {
 	return inb(chip->iobase + reg);
 }
@@ -1045,28 +1041,28 @@
  * access 16bit words to the code or data regions of the dsp's memory.
  * index addresses 16bit words.
  */
-static u16 snd_m3_assp_read(m3_t *chip, u16 region, u16 index)
+static u16 snd_m3_assp_read(struct snd_m3 *chip, u16 region, u16 index)
 {
 	snd_m3_outw(chip, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
 	snd_m3_outw(chip, index, DSP_PORT_MEMORY_INDEX);
 	return snd_m3_inw(chip, DSP_PORT_MEMORY_DATA);
 }
 
-static void snd_m3_assp_write(m3_t *chip, u16 region, u16 index, u16 data)
+static void snd_m3_assp_write(struct snd_m3 *chip, u16 region, u16 index, u16 data)
 {
 	snd_m3_outw(chip, region & MEMTYPE_MASK, DSP_PORT_MEMORY_TYPE);
 	snd_m3_outw(chip, index, DSP_PORT_MEMORY_INDEX);
 	snd_m3_outw(chip, data, DSP_PORT_MEMORY_DATA);
 }
 
-static void snd_m3_assp_halt(m3_t *chip)
+static void snd_m3_assp_halt(struct snd_m3 *chip)
 {
 	chip->reset_state = snd_m3_inb(chip, DSP_PORT_CONTROL_REG_B) & ~REGB_STOP_CLOCK;
 	msleep(10);
 	snd_m3_outb(chip, chip->reset_state & ~REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
 }
 
-static void snd_m3_assp_continue(m3_t *chip)
+static void snd_m3_assp_continue(struct snd_m3 *chip)
 {
 	snd_m3_outb(chip, chip->reset_state | REGB_ENABLE_RESET, DSP_PORT_CONTROL_REG_B);
 }
@@ -1080,7 +1076,7 @@
  * by the binary code images.
  */
 
-static int snd_m3_add_list(m3_t *chip, struct m3_list *list, u16 val)
+static int snd_m3_add_list(struct snd_m3 *chip, struct m3_list *list, u16 val)
 {
 	snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
 			  list->mem_addr + list->curlen,
@@ -1088,7 +1084,7 @@
 	return list->curlen++;
 }
 
-static void snd_m3_remove_list(m3_t *chip, struct m3_list *list, int index)
+static void snd_m3_remove_list(struct snd_m3 *chip, struct m3_list *list, int index)
 {
 	u16  val;
 	int lastindex = list->curlen - 1;
@@ -1108,7 +1104,7 @@
 	list->curlen--;
 }
 
-static void snd_m3_inc_timer_users(m3_t *chip)
+static void snd_m3_inc_timer_users(struct snd_m3 *chip)
 {
 	chip->timer_users++;
 	if (chip->timer_users != 1) 
@@ -1127,7 +1123,7 @@
 		    HOST_INT_CTRL);
 }
 
-static void snd_m3_dec_timer_users(m3_t *chip)
+static void snd_m3_dec_timer_users(struct snd_m3 *chip)
 {
 	chip->timer_users--;
 	if (chip->timer_users > 0)  
@@ -1151,7 +1147,8 @@
  */
 
 /* spinlock held! */
-static int snd_m3_pcm_start(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
+static int snd_m3_pcm_start(struct snd_m3 *chip, struct m3_dma *s,
+			    struct snd_pcm_substream *subs)
 {
 	if (! s || ! subs)
 		return -EINVAL;
@@ -1167,7 +1164,7 @@
 				  chip->dacs_active);
 		break;
 	case SNDRV_PCM_STREAM_CAPTURE:
-		snd_m3_assp_write(s->chip, MEMTYPE_INTERNAL_DATA,
+		snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
 				  KDATA_ADC1_REQUEST, 1);
 		snd_m3_assp_write(chip, MEMTYPE_INTERNAL_DATA,
 				  s->inst.data + CDATA_INSTANCE_READY, 1);
@@ -1177,7 +1174,8 @@
 }
 
 /* spinlock held! */
-static int snd_m3_pcm_stop(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
+static int snd_m3_pcm_stop(struct snd_m3 *chip, struct m3_dma *s,
+			   struct snd_pcm_substream *subs)
 {
 	if (! s || ! subs)
 		return -EINVAL;
@@ -1201,10 +1199,10 @@
 }
 
 static int
-snd_m3_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
+snd_m3_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
 {
-	m3_t *chip = snd_pcm_substream_chip(subs);
-	m3_dma_t *s = (m3_dma_t*)subs->runtime->private_data;
+	struct snd_m3 *chip = snd_pcm_substream_chip(subs);
+	struct m3_dma *s = subs->runtime->private_data;
 	int err = -EINVAL;
 
 	snd_assert(s != NULL, return -ENXIO);
@@ -1238,10 +1236,10 @@
  * setup
  */
 static void 
-snd_m3_pcm_setup1(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
+snd_m3_pcm_setup1(struct snd_m3 *chip, struct m3_dma *s, struct snd_pcm_substream *subs)
 {
 	int dsp_in_size, dsp_out_size, dsp_in_buffer, dsp_out_buffer;
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 
 	if (subs->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		dsp_in_size = MINISRC_IN_BUFFER_SIZE - (0x20 * 2);
@@ -1323,7 +1321,8 @@
 			  dsp_out_buffer);
 }
 
-static void snd_m3_pcm_setup2(m3_t *chip, m3_dma_t *s, snd_pcm_runtime_t *runtime)
+static void snd_m3_pcm_setup2(struct snd_m3 *chip, struct m3_dma *s,
+			      struct snd_pcm_runtime *runtime)
 {
 	u32 freq;
 
@@ -1389,7 +1388,8 @@
 
 /* the mode passed should be already shifted and masked */
 static void
-snd_m3_playback_setup(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
+snd_m3_playback_setup(struct snd_m3 *chip, struct m3_dma *s,
+		      struct snd_pcm_substream *subs)
 {
 	unsigned int i;
 
@@ -1455,7 +1455,7 @@
 };
 
 static void
-snd_m3_capture_setup(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
+snd_m3_capture_setup(struct snd_m3 *chip, struct m3_dma *s, struct snd_pcm_substream *subs)
 {
 	unsigned int i;
 
@@ -1481,10 +1481,10 @@
 				  s->inst.data + rv[i].addr, rv[i].val);
 }
 
-static int snd_m3_pcm_hw_params(snd_pcm_substream_t * substream,
-				snd_pcm_hw_params_t * hw_params)
+static int snd_m3_pcm_hw_params(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *hw_params)
 {
-	m3_dma_t *s = (m3_dma_t*) substream->runtime->private_data;
+	struct m3_dma *s = substream->runtime->private_data;
 	int err;
 
 	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
@@ -1498,24 +1498,24 @@
 	return 0;
 }
 
-static int snd_m3_pcm_hw_free(snd_pcm_substream_t * substream)
+static int snd_m3_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	m3_dma_t *s;
+	struct m3_dma *s;
 	
 	if (substream->runtime->private_data == NULL)
 		return 0;
-	s = (m3_dma_t*) substream->runtime->private_data;
+	s = substream->runtime->private_data;
 	snd_pcm_lib_free_pages(substream);
 	s->buffer_addr = 0;
 	return 0;
 }
 
 static int
-snd_m3_pcm_prepare(snd_pcm_substream_t *subs)
+snd_m3_pcm_prepare(struct snd_pcm_substream *subs)
 {
-	m3_t *chip = snd_pcm_substream_chip(subs);
-	snd_pcm_runtime_t *runtime = subs->runtime;
-	m3_dma_t *s = (m3_dma_t*)runtime->private_data;
+	struct snd_m3 *chip = snd_pcm_substream_chip(subs);
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct m3_dma *s = runtime->private_data;
 
 	snd_assert(s != NULL, return -ENXIO);
 
@@ -1546,7 +1546,7 @@
  * get current pointer
  */
 static unsigned int
-snd_m3_get_pointer(m3_t *chip, m3_dma_t *s, snd_pcm_substream_t *subs)
+snd_m3_get_pointer(struct snd_m3 *chip, struct m3_dma *s, struct snd_pcm_substream *subs)
 {
 	u16 hi = 0, lo = 0;
 	int retry = 10;
@@ -1571,11 +1571,11 @@
 }
 
 static snd_pcm_uframes_t
-snd_m3_pcm_pointer(snd_pcm_substream_t * subs)
+snd_m3_pcm_pointer(struct snd_pcm_substream *subs)
 {
-	m3_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_m3 *chip = snd_pcm_substream_chip(subs);
 	unsigned int ptr;
-	m3_dma_t *s = (m3_dma_t*)subs->runtime->private_data;
+	struct m3_dma *s = subs->runtime->private_data;
 	snd_assert(s != NULL, return 0);
 
 	spin_lock(&chip->reg_lock);
@@ -1587,9 +1587,9 @@
 
 /* update pointer */
 /* spinlock held! */
-static void snd_m3_update_ptr(m3_t *chip, m3_dma_t *s)
+static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
 {
-	snd_pcm_substream_t *subs = s->substream;
+	struct snd_pcm_substream *subs = s->substream;
 	unsigned int hwptr;
 	int diff;
 
@@ -1610,7 +1610,7 @@
 
 static void snd_m3_update_hw_volume(unsigned long private_data)
 {
-	m3_t *chip = (m3_t *) private_data;
+	struct snd_m3 *chip = (struct snd_m3 *) private_data;
 	int x, val;
 	unsigned long flags;
 
@@ -1673,7 +1673,7 @@
 static irqreturn_t
 snd_m3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	m3_t *chip = dev_id;
+	struct snd_m3 *chip = dev_id;
 	u8 status;
 	int i;
 
@@ -1698,7 +1698,7 @@
 				/* update adc/dac info if it was a timer int */
 				spin_lock(&chip->reg_lock);
 				for (i = 0; i < chip->num_substreams; i++) {
-					m3_dma_t *s = &chip->substreams[i];
+					struct m3_dma *s = &chip->substreams[i];
 					if (s->running)
 						snd_m3_update_ptr(chip, s);
 				}
@@ -1722,7 +1722,7 @@
 /*
  */
 
-static snd_pcm_hardware_t snd_m3_playback =
+static struct snd_pcm_hardware snd_m3_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_INTERLEAVED |
@@ -1743,7 +1743,7 @@
 	.periods_max =		1024,
 };
 
-static snd_pcm_hardware_t snd_m3_capture =
+static struct snd_pcm_hardware snd_m3_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_INTERLEAVED |
@@ -1769,10 +1769,10 @@
  */
 
 static int
-snd_m3_substream_open(m3_t *chip, snd_pcm_substream_t *subs)
+snd_m3_substream_open(struct snd_m3 *chip, struct snd_pcm_substream *subs)
 {
 	int i;
-	m3_dma_t *s;
+	struct m3_dma *s;
 
 	spin_lock_irq(&chip->reg_lock);
 	for (i = 0; i < chip->num_substreams; i++) {
@@ -1802,9 +1802,9 @@
 }
 
 static void
-snd_m3_substream_close(m3_t *chip, snd_pcm_substream_t *subs)
+snd_m3_substream_close(struct snd_m3 *chip, struct snd_pcm_substream *subs)
 {
-	m3_dma_t *s = (m3_dma_t*) subs->runtime->private_data;
+	struct m3_dma *s = subs->runtime->private_data;
 
 	if (s == NULL)
 		return; /* not opened properly */
@@ -1824,10 +1824,10 @@
 }
 
 static int
-snd_m3_playback_open(snd_pcm_substream_t *subs)
+snd_m3_playback_open(struct snd_pcm_substream *subs)
 {
-	m3_t *chip = snd_pcm_substream_chip(subs);
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_m3 *chip = snd_pcm_substream_chip(subs);
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	int err;
 
 	if ((err = snd_m3_substream_open(chip, subs)) < 0)
@@ -1840,19 +1840,19 @@
 }
 
 static int
-snd_m3_playback_close(snd_pcm_substream_t *subs)
+snd_m3_playback_close(struct snd_pcm_substream *subs)
 {
-	m3_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_m3 *chip = snd_pcm_substream_chip(subs);
 
 	snd_m3_substream_close(chip, subs);
 	return 0;
 }
 
 static int
-snd_m3_capture_open(snd_pcm_substream_t *subs)
+snd_m3_capture_open(struct snd_pcm_substream *subs)
 {
-	m3_t *chip = snd_pcm_substream_chip(subs);
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_m3 *chip = snd_pcm_substream_chip(subs);
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	int err;
 
 	if ((err = snd_m3_substream_open(chip, subs)) < 0)
@@ -1865,9 +1865,9 @@
 }
 
 static int
-snd_m3_capture_close(snd_pcm_substream_t *subs)
+snd_m3_capture_close(struct snd_pcm_substream *subs)
 {
-	m3_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_m3 *chip = snd_pcm_substream_chip(subs);
 
 	snd_m3_substream_close(chip, subs);
 	return 0;
@@ -1877,7 +1877,7 @@
  * create pcm instance
  */
 
-static snd_pcm_ops_t snd_m3_playback_ops = {
+static struct snd_pcm_ops snd_m3_playback_ops = {
 	.open =		snd_m3_playback_open,
 	.close =	snd_m3_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1888,7 +1888,7 @@
 	.pointer =	snd_m3_pcm_pointer,
 };
 
-static snd_pcm_ops_t snd_m3_capture_ops = {
+static struct snd_pcm_ops snd_m3_capture_ops = {
 	.open =		snd_m3_capture_open,
 	.close =	snd_m3_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1900,9 +1900,9 @@
 };
 
 static int __devinit
-snd_m3_pcm(m3_t * chip, int device)
+snd_m3_pcm(struct snd_m3 * chip, int device)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	err = snd_pcm_new(chip->card, chip->card->driver, device,
@@ -1933,7 +1933,7 @@
  * Wait for the ac97 serial bus to be free.
  * return nonzero if the bus is still busy.
  */
-static int snd_m3_ac97_wait(m3_t *chip)
+static int snd_m3_ac97_wait(struct snd_m3 *chip)
 {
 	int i = 10000;
 
@@ -1947,9 +1947,9 @@
 }
 
 static unsigned short
-snd_m3_ac97_read(ac97_t *ac97, unsigned short reg)
+snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
-	m3_t *chip = ac97->private_data;
+	struct snd_m3 *chip = ac97->private_data;
 	unsigned long flags;
 	unsigned short data;
 
@@ -1965,9 +1965,9 @@
 }
 
 static void
-snd_m3_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
+snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
-	m3_t *chip = ac97->private_data;
+	struct snd_m3 *chip = ac97->private_data;
 	unsigned long flags;
 
 	if (snd_m3_ac97_wait(chip))
@@ -1994,7 +1994,7 @@
 /* 
  * hack, returns non zero on err 
  */
-static int snd_m3_try_read_vendor(m3_t *chip)
+static int snd_m3_try_read_vendor(struct snd_m3 *chip)
 {
 	u16 ret;
 
@@ -2011,7 +2011,7 @@
 	return (ret == 0) || (ret == 0xffff);
 }
 
-static void snd_m3_ac97_reset(m3_t *chip)
+static void snd_m3_ac97_reset(struct snd_m3 *chip)
 {
 	u16 dir;
 	int delay1 = 0, delay2 = 0, i;
@@ -2078,13 +2078,13 @@
 #endif
 }
 
-static int __devinit snd_m3_mixer(m3_t *chip)
+static int __devinit snd_m3_mixer(struct snd_m3 *chip)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
-	snd_ctl_elem_id_t id;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
+	struct snd_ctl_elem_id id;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_m3_ac97_write,
 		.read = snd_m3_ac97_read,
 	};
@@ -2254,7 +2254,7 @@
 	0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
 };
 
-static void __devinit snd_m3_assp_init(m3_t *chip)
+static void __devinit snd_m3_assp_init(struct snd_m3 *chip)
 {
 	unsigned int i;
 
@@ -2343,7 +2343,7 @@
 }
 
 
-static int __devinit snd_m3_assp_client_init(m3_t *chip, m3_dma_t *s, int index)
+static int __devinit snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma *s, int index)
 {
 	int data_bytes = 2 * ( MINISRC_TMP_BUFFER_SIZE / 2 + 
 			       MINISRC_IN_BUFFER_SIZE / 2 +
@@ -2389,7 +2389,7 @@
  * this needs more magic for 4 speaker, but..
  */
 static void
-snd_m3_amp_enable(m3_t *chip, int enable)
+snd_m3_amp_enable(struct snd_m3 *chip, int enable)
 {
 	int io = chip->iobase;
 	u16 gpo, polarity;
@@ -2413,7 +2413,7 @@
 }
 
 static int
-snd_m3_chip_init(m3_t *chip)
+snd_m3_chip_init(struct snd_m3 *chip)
 {
 	struct pci_dev *pcidev = chip->pci;
 	unsigned long io = chip->iobase;
@@ -2486,7 +2486,7 @@
 } 
 
 static void
-snd_m3_enable_ints(m3_t *chip)
+snd_m3_enable_ints(struct snd_m3 *chip)
 {
 	unsigned long io = chip->iobase;
 	unsigned short val;
@@ -2504,9 +2504,9 @@
 /*
  */
 
-static int snd_m3_free(m3_t *chip)
+static int snd_m3_free(struct snd_m3 *chip)
 {
-	m3_dma_t *s;
+	struct m3_dma *s;
 	int i;
 
 	if (chip->substreams) {
@@ -2530,7 +2530,7 @@
 
 	if (chip->irq >= 0) {
 		synchronize_irq(chip->irq);
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	}
 
 	if (chip->iobase)
@@ -2546,14 +2546,16 @@
  * APM support
  */
 #ifdef CONFIG_PM
-static int m3_suspend(snd_card_t *card, pm_message_t state)
+static int m3_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	m3_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_m3 *chip = card->private_data;
 	int i, index;
 
 	if (chip->suspend_mem == NULL)
 		return 0;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
 
@@ -2574,20 +2576,23 @@
 	snd_m3_outw(chip, 0xffff, 0x54);
 	snd_m3_outw(chip, 0xffff, 0x56);
 
-	pci_disable_device(chip->pci);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int m3_resume(snd_card_t *card)
+static int m3_resume(struct pci_dev *pci)
 {
-	m3_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_m3 *chip = card->private_data;
 	int i, index;
 
 	if (chip->suspend_mem == NULL)
 		return 0;
 
-	pci_enable_device(chip->pci);
-	pci_set_master(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci);
 
 	/* first lets just bring everything back. .*/
 	snd_m3_outw(chip, 0, 0x54);
@@ -2617,6 +2622,7 @@
 	snd_m3_enable_ints(chip);
 	snd_m3_amp_enable(chip, 1);
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
@@ -2625,23 +2631,23 @@
 /*
  */
 
-static int snd_m3_dev_free(snd_device_t *device)
+static int snd_m3_dev_free(struct snd_device *device)
 {
-	m3_t *chip = device->device_data;
+	struct snd_m3 *chip = device->device_data;
 	return snd_m3_free(chip);
 }
 
 static int __devinit
-snd_m3_create(snd_card_t *card, struct pci_dev *pci,
+snd_m3_create(struct snd_card *card, struct pci_dev *pci,
 	      int enable_amp,
 	      int amp_gpio,
-	      m3_t **chip_ret)
+	      struct snd_m3 **chip_ret)
 {
-	m3_t *chip;
+	struct snd_m3 *chip;
 	int i, err;
 	struct m3_quirk *quirk;
 	struct m3_hv_quirk *hv_quirk;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_m3_dev_free,
 	};
 
@@ -2710,13 +2716,13 @@
 		chip->amp_gpio = GPO_EXT_AMP_M3;
 
 	chip->num_substreams = NR_DSPS;
-	chip->substreams = kmalloc(sizeof(m3_dma_t) * chip->num_substreams, GFP_KERNEL);
+	chip->substreams = kcalloc(chip->num_substreams, sizeof(struct m3_dma),
+				   GFP_KERNEL);
 	if (chip->substreams == NULL) {
 		kfree(chip);
 		pci_disable_device(pci);
 		return -ENOMEM;
 	}
-	memset(chip->substreams, 0, sizeof(m3_dma_t) * chip->num_substreams);
 
 	if ((err = pci_request_regions(pci, card->driver)) < 0) {
 		snd_m3_free(chip);
@@ -2737,7 +2743,7 @@
 	tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
 
 	if (request_irq(pci->irq, snd_m3_interrupt, SA_INTERRUPT|SA_SHIRQ,
-			card->driver, (void *)chip)) {
+			card->driver, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_m3_free(chip);
 		return -ENOMEM;
@@ -2748,8 +2754,6 @@
 	chip->suspend_mem = vmalloc(sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH));
 	if (chip->suspend_mem == NULL)
 		snd_printk(KERN_WARNING "can't allocate apm buffer\n");
-	else
-		snd_card_set_pm_callback(card, m3_suspend, m3_resume, chip);
 #endif
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
@@ -2761,8 +2765,7 @@
 		return err;
 
 	for (i = 0; i < chip->num_substreams; i++) {
-		m3_dma_t *s = &chip->substreams[i];
-		s->chip = chip;
+		struct m3_dma *s = &chip->substreams[i];
 		if ((err = snd_m3_assp_client_init(chip, s, i)) < 0)
 			return err;
 	}
@@ -2786,8 +2789,8 @@
 snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	m3_t *chip;
+	struct snd_card *card;
+	struct snd_m3 *chip;
 	int err;
 
 	/* don't pick up modems */
@@ -2826,6 +2829,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 
 	sprintf(card->shortname, "ESS %s PCI", card->driver);
 	sprintf(card->longname, "%s at 0x%lx, irq %d",
@@ -2861,7 +2865,10 @@
 	.id_table = snd_m3_ids,
 	.probe = snd_m3_probe,
 	.remove = __devexit_p(snd_m3_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = m3_suspend,
+	.resume = m3_resume,
+#endif
 };
 	
 static int __init alsa_card_m3_init(void)
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index b3090a1..b218e1d 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -66,11 +66,12 @@
 MODULE_DEVICE_TABLE(pci, snd_mixart_ids);
 
 
-static int mixart_set_pipe_state(mixart_mgr_t *mgr, mixart_pipe_t* pipe, int start)
+static int mixart_set_pipe_state(struct mixart_mgr *mgr,
+				 struct mixart_pipe *pipe, int start)
 {
-	mixart_group_state_req_t group_state;
-	mixart_group_state_resp_t group_state_resp;
-	mixart_msg_t request;
+	struct mixart_group_state_req group_state;
+	struct mixart_group_state_resp group_state_resp;
+	struct mixart_msg request;
 	int err;
 	u32 system_msg_uid;
 
@@ -92,7 +93,7 @@
 	/* wait on the last MSG_SYSTEM_SEND_SYNCHRO_CMD command to be really finished */
 
 	request.message_id = MSG_SYSTEM_WAIT_SYNCHRO_CMD;
-	request.uid = (mixart_uid_t){0,0};
+	request.uid = (struct mixart_uid){0,0};
 	request.data = &system_msg_uid;
 	request.size = sizeof(system_msg_uid);
 
@@ -113,7 +114,7 @@
 	else
 		request.message_id = MSG_STREAM_STOP_STREAM_GRP_PACKET;
 
-	request.uid = pipe->group_uid; /*(mixart_uid_t){0,0};*/
+	request.uid = pipe->group_uid; /*(struct mixart_uid){0,0};*/
 	request.data = &group_state;
 	request.size = sizeof(group_state);
 
@@ -137,7 +138,7 @@
 		/* in case of start send a synchro top */
 
 		request.message_id = MSG_SYSTEM_SEND_SYNCHRO_CMD;
-		request.uid = (mixart_uid_t){0,0};
+		request.uid = (struct mixart_uid){0,0};
 		request.data = NULL;
 		request.size = 0;
 
@@ -156,11 +157,12 @@
 }
 
 
-static int mixart_set_clock(mixart_mgr_t *mgr, mixart_pipe_t *pipe, unsigned int rate)
+static int mixart_set_clock(struct mixart_mgr *mgr,
+			    struct mixart_pipe *pipe, unsigned int rate)
 {
-	mixart_msg_t request;
-	mixart_clock_properties_t clock_properties;
-	mixart_clock_properties_resp_t clock_prop_resp;
+	struct mixart_msg request;
+	struct mixart_clock_properties clock_properties;
+	struct mixart_clock_properties_resp clock_prop_resp;
 	int err;
 
 	switch(pipe->status) {
@@ -208,11 +210,13 @@
 /*
  *  Allocate or reference output pipe for analog IOs (pcmp0/1)
  */
-mixart_pipe_t* snd_mixart_add_ref_pipe( mixart_t *chip, int pcm_number, int capture, int monitoring)
+struct mixart_pipe *
+snd_mixart_add_ref_pipe(struct snd_mixart *chip, int pcm_number, int capture,
+			int monitoring)
 {
 	int stream_count;
-	mixart_pipe_t *pipe;
-	mixart_msg_t request;
+	struct mixart_pipe *pipe;
+	struct mixart_msg request;
 
 	if(capture) {
 		if (pcm_number == MIXART_PCM_ANALOG) {
@@ -241,8 +245,8 @@
 	if( pipe->status == PIPE_UNDEFINED ) {
 		int err, i;
 		struct {
-			mixart_streaming_group_req_t sgroup_req;
-			mixart_streaming_group_t sgroup_resp;
+			struct mixart_streaming_group_req sgroup_req;
+			struct mixart_streaming_group sgroup_resp;
 		} *buf;
 
 		snd_printdd("add_ref_pipe audio chip(%d) pcm(%d)\n", chip->chip_idx, pcm_number);
@@ -251,7 +255,7 @@
 		if (!buf)
 			return NULL;
 
-		request.uid = (mixart_uid_t){0,0};      /* should be StreamManagerUID, but zero is OK if there is only one ! */
+		request.uid = (struct mixart_uid){0,0};      /* should be StreamManagerUID, but zero is OK if there is only one ! */
 		request.data = &buf->sgroup_req;
 		request.size = sizeof(buf->sgroup_req);
 
@@ -279,7 +283,7 @@
 			buf->sgroup_req.flow_entry[i] = j;
 
 			flowinfo = (struct mixart_flowinfo *)chip->mgr->flowinfo.area;
-			flowinfo[j].bufferinfo_array_phy_address = (u32)chip->mgr->bufferinfo.addr + (j * sizeof(mixart_bufferinfo_t));
+			flowinfo[j].bufferinfo_array_phy_address = (u32)chip->mgr->bufferinfo.addr + (j * sizeof(struct mixart_bufferinfo));
 			flowinfo[j].bufferinfo_count = 1;               /* 1 will set the miXart to ring-buffer mode ! */
 
 			bufferinfo = (struct mixart_bufferinfo *)chip->mgr->bufferinfo.area;
@@ -315,7 +319,8 @@
 }
 
 
-int snd_mixart_kill_ref_pipe( mixart_mgr_t *mgr, mixart_pipe_t *pipe, int monitoring)
+int snd_mixart_kill_ref_pipe(struct mixart_mgr *mgr,
+			     struct mixart_pipe *pipe, int monitoring)
 {
 	int err = 0;
 
@@ -329,8 +334,8 @@
 
 	if((pipe->references <= 0) && (pipe->monitoring == 0)) {
 
-		mixart_msg_t request;
-		mixart_delete_group_resp_t delete_resp;
+		struct mixart_msg request;
+		struct mixart_delete_group_resp delete_resp;
 
 		/* release the clock */
 		err = mixart_set_clock( mgr, pipe, 0);
@@ -345,7 +350,7 @@
 		}
 
 		request.message_id = MSG_STREAM_DELETE_GROUP;
-		request.uid = (mixart_uid_t){0,0};
+		request.uid = (struct mixart_uid){0,0};
 		request.data = &pipe->group_uid;            /* the streaming group ! */
 		request.size = sizeof(pipe->group_uid);
 
@@ -355,7 +360,7 @@
 			snd_printk(KERN_ERR "error MSG_STREAM_DELETE_GROUP err(%x), status(%x)\n", err, delete_resp.status);
 		}
 
-		pipe->group_uid = (mixart_uid_t){0,0};
+		pipe->group_uid = (struct mixart_uid){0,0};
 		pipe->stream_count = 0;
 		pipe->status = PIPE_UNDEFINED;
 	}
@@ -363,11 +368,11 @@
 	return err;
 }
 
-static int mixart_set_stream_state(mixart_stream_t *stream, int start)
+static int mixart_set_stream_state(struct mixart_stream *stream, int start)
 {
-	mixart_t *chip;
-	mixart_stream_state_req_t stream_state_req;
-	mixart_msg_t request;
+	struct snd_mixart *chip;
+	struct mixart_stream_state_req stream_state_req;
+	struct mixart_msg request;
 
 	if(!stream->substream)
 		return -EINVAL;
@@ -382,7 +387,7 @@
 	else
 		request.message_id = start ? MSG_STREAM_START_OUTPUT_STAGE_PACKET : MSG_STREAM_STOP_OUTPUT_STAGE_PACKET;
 
-	request.uid = (mixart_uid_t){0,0};
+	request.uid = (struct mixart_uid){0,0};
 	request.data = &stream_state_req;
 	request.size = sizeof(stream_state_req);
 
@@ -399,9 +404,9 @@
  *  Trigger callback
  */
 
-static int snd_mixart_trigger(snd_pcm_substream_t *subs, int cmd)
+static int snd_mixart_trigger(struct snd_pcm_substream *subs, int cmd)
 {
-	mixart_stream_t *stream = (mixart_stream_t*)subs->runtime->private_data;
+	struct mixart_stream *stream = subs->runtime->private_data;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -443,7 +448,7 @@
 	return 0;
 }
 
-static int mixart_sync_nonblock_events(mixart_mgr_t *mgr)
+static int mixart_sync_nonblock_events(struct mixart_mgr *mgr)
 {
 	unsigned long timeout = jiffies + HZ;
 	while (atomic_read(&mgr->msg_processed) > 0) {
@@ -459,10 +464,10 @@
 /*
  *  prepare callback for all pcms
  */
-static int snd_mixart_prepare(snd_pcm_substream_t *subs)
+static int snd_mixart_prepare(struct snd_pcm_substream *subs)
 {
-	mixart_t *chip = snd_pcm_substream_chip(subs);
-	mixart_stream_t *stream = (mixart_stream_t*)subs->runtime->private_data;
+	struct snd_mixart *chip = snd_pcm_substream_chip(subs);
+	struct mixart_stream *stream = subs->runtime->private_data;
 
 	/* TODO de façon non bloquante, réappliquer les hw_params (rate, bits, codec) */
 
@@ -485,13 +490,13 @@
 }
 
 
-static int mixart_set_format(mixart_stream_t *stream, snd_pcm_format_t format)
+static int mixart_set_format(struct mixart_stream *stream, snd_pcm_format_t format)
 {
 	int err;
-	mixart_t *chip;
-	mixart_msg_t request;
-	mixart_stream_param_desc_t stream_param;
-	mixart_return_uid_t resp;
+	struct snd_mixart *chip;
+	struct mixart_msg request;
+	struct mixart_stream_param_desc stream_param;
+	struct mixart_return_uid resp;
 
 	chip = snd_pcm_substream_chip(stream->substream);
 
@@ -552,7 +557,7 @@
 	stream_param.stream_desc[0].stream_idx = stream->substream->number;
 
 	request.message_id = MSG_STREAM_SET_INPUT_STAGE_PARAM;
-	request.uid = (mixart_uid_t){0,0};
+	request.uid = (struct mixart_uid){0,0};
 	request.data = &stream_param;
 	request.size = sizeof(stream_param);
 
@@ -568,12 +573,12 @@
 /*
  *  HW_PARAMS callback for all pcms
  */
-static int snd_mixart_hw_params(snd_pcm_substream_t *subs,
-                                snd_pcm_hw_params_t *hw)
+static int snd_mixart_hw_params(struct snd_pcm_substream *subs,
+                                struct snd_pcm_hw_params *hw)
 {
-	mixart_t *chip = snd_pcm_substream_chip(subs);
-	mixart_mgr_t *mgr = chip->mgr;
-	mixart_stream_t *stream = (mixart_stream_t*)subs->runtime->private_data;
+	struct snd_mixart *chip = snd_pcm_substream_chip(subs);
+	struct mixart_mgr *mgr = chip->mgr;
+	struct mixart_stream *stream = subs->runtime->private_data;
 	snd_pcm_format_t format;
 	int err;
 	int channels;
@@ -628,9 +633,9 @@
 	return err;
 }
 
-static int snd_mixart_hw_free(snd_pcm_substream_t *subs)
+static int snd_mixart_hw_free(struct snd_pcm_substream *subs)
 {
-	mixart_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_mixart *chip = snd_pcm_substream_chip(subs);
 	snd_pcm_lib_free_pages(subs);
 	mixart_sync_nonblock_events(chip->mgr);
 	return 0;
@@ -641,7 +646,7 @@
 /*
  *  TODO CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
  */
-static snd_pcm_hardware_t snd_mixart_analog_caps =
+static struct snd_pcm_hardware snd_mixart_analog_caps =
 {
 	.info             = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 			      SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
@@ -662,7 +667,7 @@
 	.periods_max      = (32*1024/256),
 };
 
-static snd_pcm_hardware_t snd_mixart_digital_caps =
+static struct snd_pcm_hardware snd_mixart_digital_caps =
 {
 	.info             = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 			      SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
@@ -684,14 +689,14 @@
 };
 
 
-static int snd_mixart_playback_open(snd_pcm_substream_t *subs)
+static int snd_mixart_playback_open(struct snd_pcm_substream *subs)
 {
-	mixart_t            *chip = snd_pcm_substream_chip(subs);
-	mixart_mgr_t        *mgr = chip->mgr;
-	snd_pcm_runtime_t   *runtime = subs->runtime;
-	snd_pcm_t           *pcm = subs->pcm;
-	mixart_stream_t     *stream;
-	mixart_pipe_t       *pipe;
+	struct snd_mixart            *chip = snd_pcm_substream_chip(subs);
+	struct mixart_mgr        *mgr = chip->mgr;
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct snd_pcm *pcm = subs->pcm;
+	struct mixart_stream     *stream;
+	struct mixart_pipe       *pipe;
 	int err = 0;
 	int pcm_number;
 
@@ -759,14 +764,14 @@
 }
 
 
-static int snd_mixart_capture_open(snd_pcm_substream_t *subs)
+static int snd_mixart_capture_open(struct snd_pcm_substream *subs)
 {
-	mixart_t            *chip = snd_pcm_substream_chip(subs);
-	mixart_mgr_t        *mgr = chip->mgr;
-	snd_pcm_runtime_t   *runtime = subs->runtime;
-	snd_pcm_t           *pcm = subs->pcm;
-	mixart_stream_t     *stream;
-	mixart_pipe_t       *pipe;
+	struct snd_mixart            *chip = snd_pcm_substream_chip(subs);
+	struct mixart_mgr        *mgr = chip->mgr;
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct snd_pcm *pcm = subs->pcm;
+	struct mixart_stream     *stream;
+	struct mixart_pipe       *pipe;
 	int err = 0;
 	int pcm_number;
 
@@ -838,11 +843,11 @@
 
 
 
-static int snd_mixart_close(snd_pcm_substream_t *subs)
+static int snd_mixart_close(struct snd_pcm_substream *subs)
 {
-	mixart_t *chip = snd_pcm_substream_chip(subs);
-	mixart_mgr_t *mgr = chip->mgr;
-	mixart_stream_t *stream = (mixart_stream_t*)subs->runtime->private_data;
+	struct snd_mixart *chip = snd_pcm_substream_chip(subs);
+	struct mixart_mgr *mgr = chip->mgr;
+	struct mixart_stream *stream = subs->runtime->private_data;
 
 	down(&mgr->setup_mutex);
 
@@ -868,17 +873,17 @@
 }
 
 
-static snd_pcm_uframes_t snd_mixart_stream_pointer(snd_pcm_substream_t * subs)
+static snd_pcm_uframes_t snd_mixart_stream_pointer(struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
-	mixart_stream_t   *stream  = (mixart_stream_t*)runtime->private_data;
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct mixart_stream   *stream  = runtime->private_data;
 
 	return (snd_pcm_uframes_t)((stream->buf_periods * runtime->period_size) + stream->buf_period_frag);
 }
 
 
 
-static snd_pcm_ops_t snd_mixart_playback_ops = {
+static struct snd_pcm_ops snd_mixart_playback_ops = {
 	.open      = snd_mixart_playback_open,
 	.close     = snd_mixart_close,
 	.ioctl     = snd_pcm_lib_ioctl,
@@ -889,7 +894,7 @@
 	.pointer   = snd_mixart_stream_pointer,
 };
 
-static snd_pcm_ops_t snd_mixart_capture_ops = {
+static struct snd_pcm_ops snd_mixart_capture_ops = {
 	.open      = snd_mixart_capture_open,
 	.close     = snd_mixart_close,
 	.ioctl     = snd_pcm_lib_ioctl,
@@ -900,10 +905,10 @@
 	.pointer   = snd_mixart_stream_pointer,
 };
 
-static void preallocate_buffers(mixart_t *chip, snd_pcm_t *pcm)
+static void preallocate_buffers(struct snd_mixart *chip, struct snd_pcm *pcm)
 {
 #if 0
-	snd_pcm_substream_t *subs;
+	struct snd_pcm_substream *subs;
 	int stream;
 
 	for (stream = 0; stream < 2; stream++) {
@@ -921,10 +926,10 @@
 
 /*
  */
-static int snd_mixart_pcm_analog(mixart_t *chip)
+static int snd_mixart_pcm_analog(struct snd_mixart *chip)
 {
 	int err;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	char name[32];
 
 	sprintf(name, "miXart analog %d", chip->chip_idx);
@@ -952,10 +957,10 @@
 
 /*
  */
-static int snd_mixart_pcm_digital(mixart_t *chip)
+static int snd_mixart_pcm_digital(struct snd_mixart *chip)
 {
 	int err;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	char name[32];
 
 	sprintf(name, "miXart AES/EBU %d", chip->chip_idx);
@@ -980,26 +985,26 @@
 	return 0;
 }
 
-static int snd_mixart_chip_free(mixart_t *chip)
+static int snd_mixart_chip_free(struct snd_mixart *chip)
 {
 	kfree(chip);
 	return 0;
 }
 
-static int snd_mixart_chip_dev_free(snd_device_t *device)
+static int snd_mixart_chip_dev_free(struct snd_device *device)
 {
-	mixart_t *chip = device->device_data;
+	struct snd_mixart *chip = device->device_data;
 	return snd_mixart_chip_free(chip);
 }
 
 
 /*
  */
-static int __devinit snd_mixart_create(mixart_mgr_t *mgr, snd_card_t *card, int idx)
+static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int idx)
 {
 	int err;
-	mixart_t *chip;
-	static snd_device_ops_t ops = {
+	struct snd_mixart *chip;
+	static struct snd_device_ops ops = {
 		.dev_free = snd_mixart_chip_dev_free,
 	};
 
@@ -1023,7 +1028,7 @@
 	return 0;
 }
 
-int snd_mixart_create_pcm(mixart_t* chip)
+int snd_mixart_create_pcm(struct snd_mixart* chip)
 {
 	int err;
 
@@ -1044,7 +1049,7 @@
 /*
  * release all the cards assigned to a manager instance
  */
-static int snd_mixart_free(mixart_mgr_t *mgr)
+static int snd_mixart_free(struct mixart_mgr *mgr)
 {
 	unsigned int i;
 
@@ -1092,7 +1097,7 @@
 /*
  * proc interface
  */
-static long long snd_mixart_BA0_llseek(snd_info_entry_t *entry,
+static long long snd_mixart_BA0_llseek(struct snd_info_entry *entry,
 				       void *private_file_data,
 				       struct file *file,
 				       long long offset,
@@ -1118,7 +1123,7 @@
 	return file->f_pos;
 }
 
-static long long snd_mixart_BA1_llseek(snd_info_entry_t *entry,
+static long long snd_mixart_BA1_llseek(struct snd_info_entry *entry,
 				       void *private_file_data,
 				       struct file *file,
 				       long long offset,
@@ -1147,11 +1152,11 @@
 /*
   mixart_BA0 proc interface for BAR 0 - read callback
  */
-static long snd_mixart_BA0_read(snd_info_entry_t *entry, void *file_private_data,
+static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private_data,
 				struct file *file, char __user *buf,
 				unsigned long count, unsigned long pos)
 {
-	mixart_mgr_t *mgr = entry->private_data;
+	struct mixart_mgr *mgr = entry->private_data;
 
 	count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
 	if(count <= 0)
@@ -1166,11 +1171,11 @@
 /*
   mixart_BA1 proc interface for BAR 1 - read callback
  */
-static long snd_mixart_BA1_read(snd_info_entry_t *entry, void *file_private_data,
+static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private_data,
 				struct file *file, char __user *buf,
 				unsigned long count, unsigned long pos)
 {
-	mixart_mgr_t *mgr = entry->private_data;
+	struct mixart_mgr *mgr = entry->private_data;
 
 	count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
 	if(count <= 0)
@@ -1193,10 +1198,10 @@
 };
 
 
-static void snd_mixart_proc_read(snd_info_entry_t *entry, 
-                                 snd_info_buffer_t * buffer)
+static void snd_mixart_proc_read(struct snd_info_entry *entry, 
+                                 struct snd_info_buffer *buffer)
 {
-	mixart_t *chip = entry->private_data;        
+	struct snd_mixart *chip = entry->private_data;        
 	u32 ref; 
 
 	snd_iprintf(buffer, "Digigram miXart (alsa card %d)\n\n", chip->chip_idx);
@@ -1229,9 +1234,9 @@
 	} /* endif elf loaded */
 }
 
-static void __devinit snd_mixart_proc_init(mixart_t *chip)
+static void __devinit snd_mixart_proc_init(struct snd_mixart *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	/* text interface to read perf and temp meters */
 	if (! snd_card_proc_new(chip->card, "board_info", &entry)) {
@@ -1263,7 +1268,7 @@
 				      const struct pci_device_id *pci_id)
 {
 	static int dev;
-	mixart_mgr_t *mgr;
+	struct mixart_mgr *mgr;
 	unsigned int i;
 	int err;
 	size_t size;
@@ -1338,12 +1343,12 @@
 	init_MUTEX(&mgr->setup_mutex);
 
 	/* init message taslket */
-	tasklet_init( &mgr->msg_taskq, snd_mixart_msg_tasklet, (unsigned long) mgr);
+	tasklet_init(&mgr->msg_taskq, snd_mixart_msg_tasklet, (unsigned long) mgr);
 
 	/* card assignment */
 	mgr->num_cards = MIXART_MAX_CARDS; /* 4  FIXME: configurable? */
 	for (i = 0; i < mgr->num_cards; i++) {
-		snd_card_t *card;
+		struct snd_card *card;
 		char tmpid[16];
 		int idx;
 
@@ -1384,7 +1389,8 @@
 	mgr->board_type = MIXART_DAUGHTER_TYPE_NONE;
 
 	/* create array of streaminfo */
-	size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS * sizeof(mixart_flowinfo_t)) );
+	size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS *
+			    sizeof(struct mixart_flowinfo)) );
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				size, &mgr->flowinfo) < 0) {
 		snd_mixart_free(mgr);
@@ -1394,7 +1400,8 @@
 	memset(mgr->flowinfo.area, 0, size);
 
 	/* create array of bufferinfo */
-	size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS * sizeof(mixart_bufferinfo_t)) );
+	size = PAGE_ALIGN( (MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS *
+			    sizeof(struct mixart_bufferinfo)) );
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
 				size, &mgr->bufferinfo) < 0) {
 		snd_mixart_free(mgr);
diff --git a/sound/pci/mixart/mixart.h b/sound/pci/mixart/mixart.h
index f87152f..3e84863 100644
--- a/sound/pci/mixart/mixart.h
+++ b/sound/pci/mixart/mixart.h
@@ -32,21 +32,7 @@
 /*
  */
 
-#define mixart_t_magic		0xa17a3e01
-#define mixart_mgr_t_magic	0xa17a3e02
-
-typedef struct snd_mixart mixart_t;
-typedef struct snd_mixart_mgr mixart_mgr_t;
-
-typedef struct snd_mixart_stream mixart_stream_t;
-typedef struct snd_mixart_pipe mixart_pipe_t;
-
-typedef struct mixart_bufferinfo mixart_bufferinfo_t;
-typedef struct mixart_flowinfo mixart_flowinfo_t;
-typedef struct mixart_uid mixart_uid_t;
-
-struct mixart_uid
-{
+struct mixart_uid {
 	u32 object_id;
 	u32 desc;
 };
@@ -58,7 +44,6 @@
 };
 
 
-typedef struct mixart_route mixart_route_t;
 struct mixart_route {
 	unsigned char connected;
 	unsigned char phase_inv;
@@ -77,9 +62,9 @@
 
 #define MIXART_MAX_PHYS_CONNECTORS  (MIXART_MAX_CARDS * 2 * 2) /* 4 * stereo * (analog+digital) */
 
-struct snd_mixart_mgr {
+struct mixart_mgr {
 	unsigned int num_cards;
-	mixart_t *chip[MIXART_MAX_CARDS];
+	struct snd_mixart *chip[MIXART_MAX_CARDS];
 
 	struct pci_dev *pci;
 
@@ -118,7 +103,7 @@
 	struct snd_dma_buffer flowinfo;
 	struct snd_dma_buffer bufferinfo;
 
-	mixart_uid_t         uid_console_manager;
+	struct mixart_uid         uid_console_manager;
 	int sample_rate;
 	int ref_count_rate;
 
@@ -151,9 +136,9 @@
 #define MIXART_NOTIFY_SUBS_MASK		0x007F
 
 
-struct snd_mixart_stream {
-	snd_pcm_substream_t *substream;
-	mixart_pipe_t *pipe;
+struct mixart_stream {
+	struct snd_pcm_substream *substream;
+	struct mixart_pipe *pipe;
 	int pcm_number;
 
 	int status;      /* nothing, running, draining */
@@ -173,11 +158,11 @@
 	PIPE_CLOCK_SET
 };
 
-struct snd_mixart_pipe {
-	mixart_uid_t group_uid;			/* id of the pipe, as returned by embedded */
+struct mixart_pipe {
+	struct mixart_uid group_uid;			/* id of the pipe, as returned by embedded */
 	int          stream_count;
-	mixart_uid_t uid_left_connector;	/* UID's for the audio connectors */
-	mixart_uid_t uid_right_connector;
+	struct mixart_uid uid_left_connector;	/* UID's for the audio connectors */
+	struct mixart_uid uid_right_connector;
 	enum mixart_pipe_status status;
 	int references;             /* number of subs openned */
 	int monitoring;             /* pipe used for monitoring issue */
@@ -185,28 +170,28 @@
 
 
 struct snd_mixart {
-	snd_card_t *card;
-	mixart_mgr_t *mgr;
+	struct snd_card *card;
+	struct mixart_mgr *mgr;
 	int chip_idx;               /* zero based */
-	snd_hwdep_t *hwdep;	    /* DSP loader, only for the first card */
+	struct snd_hwdep *hwdep;	    /* DSP loader, only for the first card */
 
-	snd_pcm_t *pcm;             /* PCM analog i/o */
-	snd_pcm_t *pcm_dig;         /* PCM digital i/o */
+	struct snd_pcm *pcm;             /* PCM analog i/o */
+	struct snd_pcm *pcm_dig;         /* PCM digital i/o */
 
 	/* allocate stereo pipe for instance */
-	mixart_pipe_t pipe_in_ana;
-	mixart_pipe_t pipe_out_ana;
+	struct mixart_pipe pipe_in_ana;
+	struct mixart_pipe pipe_out_ana;
 
 	/* if AES/EBU daughter board is available, additional pipes possible on pcm_dig */
-	mixart_pipe_t pipe_in_dig;
-	mixart_pipe_t pipe_out_dig;
+	struct mixart_pipe pipe_in_dig;
+	struct mixart_pipe pipe_out_dig;
 
-	mixart_stream_t playback_stream[MIXART_PCM_TOTAL][MIXART_PLAYBACK_STREAMS]; /* 0 = pcm, 1 = pcm_dig */
-	mixart_stream_t capture_stream[MIXART_PCM_TOTAL];                           /* 0 = pcm, 1 = pcm_dig */
+	struct mixart_stream playback_stream[MIXART_PCM_TOTAL][MIXART_PLAYBACK_STREAMS]; /* 0 = pcm, 1 = pcm_dig */
+	struct mixart_stream capture_stream[MIXART_PCM_TOTAL];                           /* 0 = pcm, 1 = pcm_dig */
 
 	/* UID's for the physical io's */
-	mixart_uid_t uid_out_analog_physio;
-	mixart_uid_t uid_in_analog_physio;
+	struct mixart_uid uid_out_analog_physio;
+	struct mixart_uid uid_in_analog_physio;
 
 	int analog_playback_active[2];		/* Mixer : Master Playback active (!mute) */
 	int analog_playback_volume[2];		/* Mixer : Master Playback Volume */
@@ -235,8 +220,8 @@
 };
 
 /* exported */
-int snd_mixart_create_pcm(mixart_t* chip);
-mixart_pipe_t* snd_mixart_add_ref_pipe( mixart_t *chip, int pcm_number, int capture, int monitoring);
-int snd_mixart_kill_ref_pipe( mixart_mgr_t *mgr, mixart_pipe_t *pipe, int monitoring);
+int snd_mixart_create_pcm(struct snd_mixart * chip);
+struct mixart_pipe *snd_mixart_add_ref_pipe(struct snd_mixart *chip, int pcm_number, int capture, int monitoring);
+int snd_mixart_kill_ref_pipe(struct mixart_mgr *mgr, struct mixart_pipe *pipe, int monitoring);
 
 #endif /* __SOUND_MIXART_H */
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
index ba0027f..07c707d 100644
--- a/sound/pci/mixart/mixart_core.c
+++ b/sound/pci/mixart/mixart_core.c
@@ -44,7 +44,7 @@
 #define MSG_CANCEL_NOTIFY_MASK      0x80000000    /* this bit is set for a notification that has been canceled */
 
 
-static int retrieve_msg_frame(mixart_mgr_t *mgr, u32 *msg_frame)
+static int retrieve_msg_frame(struct mixart_mgr *mgr, u32 *msg_frame)
 {
 	/* read the message frame fifo */
 	u32 headptr, tailptr;
@@ -69,7 +69,8 @@
 	return 1;
 }
 
-static int get_msg(mixart_mgr_t *mgr, mixart_msg_t *resp, u32 msg_frame_address )
+static int get_msg(struct mixart_mgr *mgr, struct mixart_msg *resp,
+		   u32 msg_frame_address )
 {
 	unsigned long flags;
 	u32  headptr;
@@ -137,8 +138,8 @@
  * send a message to miXart. return: the msg_frame used for this message
  */
 /* call with mgr->msg_lock held! */
-static int send_msg( mixart_mgr_t *mgr,
-		     mixart_msg_t *msg,
+static int send_msg( struct mixart_mgr *mgr,
+		     struct mixart_msg *msg,
 		     int max_answersize,
 		     int mark_pending,
 		     u32 *msg_event)
@@ -230,9 +231,9 @@
 }
 
 
-int snd_mixart_send_msg(mixart_mgr_t *mgr, mixart_msg_t *request, int max_resp_size, void *resp_data)
+int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int max_resp_size, void *resp_data)
 {
-	mixart_msg_t resp;
+	struct mixart_msg resp;
 	u32 msg_frame = 0; /* set to 0, so it's no notification to wait for, but the answer */
 	int err;
 	wait_queue_t wait;
@@ -264,9 +265,9 @@
 		return -EIO;
 	}
 
-	/* retrieve the answer into the same mixart_msg_t */
+	/* retrieve the answer into the same struct mixart_msg */
 	resp.message_id = 0;
-	resp.uid = (mixart_uid_t){0,0};
+	resp.uid = (struct mixart_uid){0,0};
 	resp.data = resp_data;
 	resp.size = max_resp_size;
 
@@ -280,7 +281,8 @@
 }
 
 
-int snd_mixart_send_msg_wait_notif(mixart_mgr_t *mgr, mixart_msg_t *request, u32 notif_event)
+int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr,
+				   struct mixart_msg *request, u32 notif_event)
 {
 	int err;
 	wait_queue_t wait;
@@ -321,7 +323,7 @@
 }
 
 
-int snd_mixart_send_msg_nonblock(mixart_mgr_t *mgr, mixart_msg_t *request)
+int snd_mixart_send_msg_nonblock(struct mixart_mgr *mgr, struct mixart_msg *request)
 {
 	u32 message_frame;
 	unsigned long flags;
@@ -332,7 +334,7 @@
 	err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 0, &message_frame);
 	spin_unlock_irqrestore(&mgr->msg_lock, flags);
 
-	/* the answer will be handled by snd_mixart_msg_tasklet()  */
+	/* the answer will be handled by snd_struct mixart_msgasklet()  */
 	atomic_inc(&mgr->msg_processed);
 
 	return err;
@@ -343,10 +345,10 @@
 static u32 mixart_msg_data[MSG_DEFAULT_SIZE / 4];
 
 
-void snd_mixart_msg_tasklet( unsigned long arg)
+void snd_mixart_msg_tasklet(unsigned long arg)
 {
-	mixart_mgr_t *mgr = ( mixart_mgr_t*)(arg);
-	mixart_msg_t resp;
+	struct mixart_mgr *mgr = ( struct mixart_mgr*)(arg);
+	struct mixart_msg resp;
 	u32 msg, addr, type;
 	int err;
 
@@ -406,9 +408,9 @@
 
 irqreturn_t snd_mixart_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	mixart_mgr_t *mgr = dev_id;
+	struct mixart_mgr *mgr = dev_id;
 	int err;
-	mixart_msg_t resp;
+	struct mixart_msg resp;
 
 	u32 msg;
 	u32 it_reg;
@@ -448,7 +450,8 @@
 
 			if(resp.message_id == MSG_SERVICES_TIMER_NOTIFY) {
 				int i;
-				mixart_timer_notify_t *notify = (mixart_timer_notify_t*)mixart_msg_data;
+				struct mixart_timer_notify *notify;
+				notify = (struct mixart_timer_notify *)mixart_msg_data;
 
 				for(i=0; i<notify->stream_count; i++) {
 
@@ -458,8 +461,8 @@
 					unsigned int sub_number  =   buffer_id & MIXART_NOTIFY_SUBS_MASK;             /* 0 to MIXART_PLAYBACK_STREAMS */
 					unsigned int is_capture  = ((buffer_id & MIXART_NOTIFY_CAPT_MASK) != 0);      /* playback == 0 / capture == 1 */
 
-					mixart_t *chip  = mgr->chip[chip_number];
-					mixart_stream_t *stream;
+					struct snd_mixart *chip  = mgr->chip[chip_number];
+					struct mixart_stream *stream;
 
 					if ((chip_number >= mgr->num_cards) || (pcm_number >= MIXART_PCM_TOTAL) || (sub_number >= MIXART_PLAYBACK_STREAMS)) {
 						snd_printk(KERN_ERR "error MSG_SERVICES_TIMER_NOTIFY buffer_id (%x) pos(%d)\n",
@@ -473,7 +476,7 @@
 						stream = &chip->playback_stream[pcm_number][sub_number];
 
 					if (stream->substream && (stream->status == MIXART_STREAM_STATUS_RUNNING)) {
-						snd_pcm_runtime_t *runtime = stream->substream->runtime;
+						struct snd_pcm_runtime *runtime = stream->substream->runtime;
 						int elapsed = 0;
 						u64 sample_count = ((u64)notify->streams[i].sample_pos_high_part) << 32;
 						sample_count |= notify->streams[i].sample_pos_low_part;
@@ -561,7 +564,7 @@
 }
 
 
-void snd_mixart_init_mailbox(mixart_mgr_t *mgr)
+void snd_mixart_init_mailbox(struct mixart_mgr *mgr)
 {
 	writel( 0, MIXART_MEM( mgr, MSG_HOST_RSC_PROTECTION ) );
 	writel( 0, MIXART_MEM( mgr, MSG_AGENT_RSC_PROTECTION ) );
@@ -573,14 +576,14 @@
 	return;
 }
 
-void snd_mixart_exit_mailbox(mixart_mgr_t *mgr)
+void snd_mixart_exit_mailbox(struct mixart_mgr *mgr)
 {
 	/* no more interrupts on outbound messagebox */
 	writel_le( MIXART_HOST_ALL_INTERRUPT_MASKED, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
 	return;
 }
 
-void snd_mixart_reset_board(mixart_mgr_t *mgr)
+void snd_mixart_reset_board(struct mixart_mgr *mgr)
 {
 	/* reset miXart */
 	writel_be( 1, MIXART_REG(mgr, MIXART_BA1_BRUTAL_RESET_OFFSET) );
diff --git a/sound/pci/mixart/mixart_core.h b/sound/pci/mixart/mixart_core.h
index 99450eb..1fe2bcf 100644
--- a/sound/pci/mixart/mixart_core.h
+++ b/sound/pci/mixart/mixart_core.h
@@ -63,25 +63,23 @@
 };
 
 
-typedef struct mixart_msg mixart_msg_t;
 struct mixart_msg
 {
 	u32          message_id;
-	mixart_uid_t uid;
+	struct mixart_uid uid;
 	void*        data;
 	size_t       size;
 };
 
 /* structs used to communicate with miXart */
 
-typedef struct mixart_enum_connector_resp mixart_enum_connector_resp_t;
 struct mixart_enum_connector_resp
 {
 	u32  error_code;
 	u32  first_uid_offset;
 	u32  uid_count;
 	u32  current_uid_index;
-	mixart_uid_t uid[MIXART_MAX_PHYS_CONNECTORS];
+	struct mixart_uid uid[MIXART_MAX_PHYS_CONNECTORS];
 } __attribute__((packed));
 
 
@@ -90,7 +88,6 @@
 #define MIXART_FLOAT_M_20_0_TO_HEX      0xc1a00000  /* -20.0f */
 #define MIXART_FLOAT____0_0_TO_HEX      0x00000000  /* 0.0f */
 
-typedef struct mixart_audio_info_req mixart_audio_info_req_t;
 struct mixart_audio_info_req
 {
 	u32 line_max_level;    /* float */
@@ -98,7 +95,6 @@
 	u32 cd_max_level;      /* float */
 } __attribute__((packed));
 
-typedef struct mixart_analog_hw_info mixart_analog_hw_info_t;
 struct mixart_analog_hw_info
 {
 	u32 is_present;
@@ -111,7 +107,6 @@
 	u32 zero_var;          /* float */
 } __attribute__((packed));
 
-typedef struct mixart_digital_hw_info mixart_digital_hw_info_t;
 struct mixart_digital_hw_info
 {
 	u32   hw_connection_type;
@@ -120,37 +115,33 @@
 	u32   reserved;
 } __attribute__((packed));
 
-typedef struct mixart_analog_info mixart_analog_info_t;
 struct mixart_analog_info
 {
 	u32                     type_mask;
-	mixart_analog_hw_info_t micro_info;
-	mixart_analog_hw_info_t line_info;
-	mixart_analog_hw_info_t cd_info;
+	struct mixart_analog_hw_info micro_info;
+	struct mixart_analog_hw_info line_info;
+	struct mixart_analog_hw_info cd_info;
 	u32                     analog_level_present;
 } __attribute__((packed));
 
-typedef struct mixart_digital_info mixart_digital_info_t;
 struct mixart_digital_info
 {
 	u32 type_mask;
-	mixart_digital_hw_info_t aes_info;
-	mixart_digital_hw_info_t adat_info;
+	struct mixart_digital_hw_info aes_info;
+	struct mixart_digital_hw_info adat_info;
 } __attribute__((packed));
 
-typedef struct mixart_audio_info mixart_audio_info_t;
 struct mixart_audio_info
 {
 	u32                   clock_type_mask;
-	mixart_analog_info_t  analog_info;
-	mixart_digital_info_t digital_info;
+	struct mixart_analog_info  analog_info;
+	struct mixart_digital_info digital_info;
 } __attribute__((packed));
 
-typedef struct mixart_audio_info_resp mixart_audio_info_resp_t;
 struct mixart_audio_info_resp
 {
 	u32                 txx_status;
-	mixart_audio_info_t info;
+	struct mixart_audio_info info;
 } __attribute__((packed));
 
 
@@ -158,7 +149,6 @@
 #define MIXART_FLOAT_P__4_0_TO_HEX      0x40800000  /* +4.0f */
 #define MIXART_FLOAT_P__8_0_TO_HEX      0x41000000  /* +8.0f */
 
-typedef struct mixart_stream_info mixart_stream_info_t;
 struct mixart_stream_info
 {
 	u32 size_max_byte_frame;
@@ -169,7 +159,6 @@
 /*  MSG_STREAM_ADD_INPUT_GROUP */
 /*  MSG_STREAM_ADD_OUTPUT_GROUP */
 
-typedef struct mixart_streaming_group_req mixart_streaming_group_req_t;
 struct mixart_streaming_group_req
 {
 	u32 stream_count;
@@ -177,33 +166,30 @@
 	u32 user_grp_number;
 	u32 first_phys_audio;
 	u32 latency;
-	mixart_stream_info_t stream_info[32];
-	mixart_uid_t connector;
+	struct mixart_stream_info stream_info[32];
+	struct mixart_uid connector;
 	u32 flow_entry[32];
 } __attribute__((packed));
 
-typedef struct mixart_stream_desc mixart_stream_desc_t;
 struct mixart_stream_desc
 {
-	mixart_uid_t stream_uid;
+	struct mixart_uid stream_uid;
 	u32          stream_desc;
 } __attribute__((packed));
 
-typedef struct mixart_streaming_group mixart_streaming_group_t;
 struct mixart_streaming_group
 {
 	u32                  status;
-	mixart_uid_t         group;
+	struct mixart_uid    group;
 	u32                  pipe_desc;
 	u32                  stream_count;
-	mixart_stream_desc_t stream[32];
+	struct mixart_stream_desc stream[32];
 } __attribute__((packed));
 
 /* MSG_STREAM_DELETE_GROUP */
 
 /* request : mixart_uid_t group */
 
-typedef struct mixart_delete_group_resp mixart_delete_group_resp_t;
 struct mixart_delete_group_resp
 {
 	u32  status;
@@ -217,55 +203,49 @@
 	MSG_STREAM_STOP_OUTPUT_STAGE_PACKET  = 0x130000 + 11,
  */
 
-typedef struct mixart_fx_couple_uid mixart_fx_couple_uid_t;
 struct mixart_fx_couple_uid
 {
-	mixart_uid_t uid_fx_code;
-	mixart_uid_t uid_fx_data;
+	struct mixart_uid uid_fx_code;
+	struct mixart_uid uid_fx_data;
 } __attribute__((packed));
 
-typedef struct mixart_txx_stream_desc mixart_txx_stream_desc_t;
 struct mixart_txx_stream_desc
 {
-	mixart_uid_t            uid_pipe;
+	struct mixart_uid       uid_pipe;
 	u32                     stream_idx;
 	u32                     fx_number;
-	mixart_fx_couple_uid_t  uid_fx[4];
+	struct mixart_fx_couple_uid  uid_fx[4];
 } __attribute__((packed));
 
-typedef struct mixart_flow_info mixart_flow_info_t;
 struct mixart_flow_info
 {
-	mixart_txx_stream_desc_t  stream_desc;
+	struct mixart_txx_stream_desc  stream_desc;
 	u32                       flow_entry;
 	u32                       flow_phy_addr;
 } __attribute__((packed));
 
-typedef struct mixart_stream_state_req mixart_stream_state_req_t;
 struct mixart_stream_state_req
 {
 	u32                 delayed;
 	u64                 scheduler;
 	u32                 reserved4np[3];
 	u32                 stream_count;  /* set to 1 for instance */
-	mixart_flow_info_t  stream_info;   /* could be an array[stream_count] */
+	struct mixart_flow_info  stream_info;   /* could be an array[stream_count] */
 } __attribute__((packed));
 
 /* 	MSG_STREAM_START_STREAM_GRP_PACKET   = 0x130000 + 6
 	MSG_STREAM_STOP_STREAM_GRP_PACKET    = 0x130000 + 9
  */
 
-typedef struct mixart_group_state_req mixart_group_state_req_t;
 struct mixart_group_state_req
 {
 	u32           delayed;
 	u64           scheduler;
 	u32           reserved4np[2];
 	u32           pipe_count;    /* set to 1 for instance */
-	mixart_uid_t  pipe_uid[1];   /* could be an array[pipe_count] */
+	struct mixart_uid  pipe_uid[1];   /* could be an array[pipe_count] */
 } __attribute__((packed));
 
-typedef struct mixart_group_state_resp mixart_group_state_resp_t;
 struct mixart_group_state_resp
 {
 	u32           txx_status;
@@ -276,7 +256,6 @@
 
 /* Structures used by the MSG_SERVICES_TIMER_NOTIFY command */
 
-typedef struct mixart_sample_pos mixart_sample_pos_t;
 struct mixart_sample_pos
 {
 	u32   buffer_id;
@@ -285,11 +264,10 @@
 	u32   sample_pos_low_part;
 } __attribute__((packed));
 
-typedef struct mixart_timer_notify mixart_timer_notify_t;
 struct mixart_timer_notify
 {
 	u32                  stream_count;
-	mixart_sample_pos_t  streams[MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS];
+	struct mixart_sample_pos  streams[MIXART_MAX_STREAM_PER_CARD * MIXART_MAX_CARDS];
 } __attribute__((packed));
 
 
@@ -298,11 +276,10 @@
 
 /* request is a uid with desc = MSG_CONSOLE_MANAGER | cardindex */
 
-typedef struct mixart_return_uid mixart_return_uid_t;
 struct mixart_return_uid
 {
 	u32 error_code;
-	mixart_uid_t uid;
+	struct mixart_uid uid;
 } __attribute__((packed));
 
 /*	MSG_CLOCK_CHECK_PROPERTIES           = 0x200001,
@@ -327,7 +304,6 @@
 };
 
 
-typedef struct mixart_clock_properties mixart_clock_properties_t;
 struct mixart_clock_properties
 {
 	u32 error_code;
@@ -336,17 +312,16 @@
 	u32 reference_frequency;
 	u32 clock_generic_type;
 	u32 clock_mode;
-	mixart_uid_t uid_clock_source;
-	mixart_uid_t uid_event_source;
+	struct mixart_uid uid_clock_source;
+	struct mixart_uid uid_event_source;
 	u32 event_mode;
 	u32 synchro_signal_presence;
 	u32 format;
 	u32 board_mask;
 	u32 nb_callers; /* set to 1 (see below) */
-	mixart_uid_t uid_caller[1];
+	struct mixart_uid uid_caller[1];
 } __attribute__((packed));
 
-typedef struct mixart_clock_properties_resp mixart_clock_properties_resp_t;
 struct mixart_clock_properties_resp
 {
 	u32 status;
@@ -388,7 +363,6 @@
 	ST_INTEGER_32LE
 };
 
-typedef struct mixart_stream_param_desc mixart_stream_param_desc_t;
 struct mixart_stream_param_desc
 {
 	u32 coding_type;  /* use enum mixart_coding_type */
@@ -432,7 +406,7 @@
 	u32 reserved4np[3];
 	u32 pipe_count;                           /* set to 1 (array size !) */
 	u32 stream_count;                         /* set to 1 (array size !) */
-	mixart_txx_stream_desc_t stream_desc[1];  /* only one stream per command, but this could be an array */
+	struct mixart_txx_stream_desc stream_desc[1];  /* only one stream per command, but this could be an array */
 
 } __attribute__((packed));
 
@@ -441,7 +415,6 @@
  */
 
 
-typedef struct mixart_get_out_audio_level mixart_get_out_audio_level_t;
 struct mixart_get_out_audio_level
 {
 	u32 txx_status;
@@ -465,7 +438,6 @@
 #define MIXART_AUDIO_LEVEL_MUTE_M1_MASK	0x10
 #define MIXART_AUDIO_LEVEL_MUTE_M2_MASK	0x20
 
-typedef struct mixart_set_out_audio_level mixart_set_out_audio_level_t;
 struct mixart_set_out_audio_level
 {
 	u32 delayed;
@@ -487,14 +459,13 @@
 
 #define MIXART_MAX_PHYS_IO  (MIXART_MAX_CARDS * 2 * 2) /* 4 * (analog+digital) * (playback+capture) */
 
-typedef struct mixart_uid_enumeration mixart_uid_enumeration_t;
 struct mixart_uid_enumeration
 {
 	u32 error_code;
 	u32 first_uid_offset;
 	u32 nb_uid;
 	u32 current_uid_index;
-	mixart_uid_t uid[MIXART_MAX_PHYS_IO];
+	struct mixart_uid uid[MIXART_MAX_PHYS_IO];
 } __attribute__((packed));
 
 
@@ -502,42 +473,38 @@
 	MSG_PHYSICALIO_GET_LEVEL             = 0x0F000C,
 */
 
-typedef struct mixart_io_channel_level mixart_io_channel_level_t;
 struct mixart_io_channel_level
 {
 	u32 analog_level;   /* float */
 	u32 unused[2];
 } __attribute__((packed));
 
-typedef struct mixart_io_level mixart_io_level_t;
 struct mixart_io_level
 {
 	s32 channel; /* 0=left, 1=right, -1=both, -2=both same */
-	mixart_io_channel_level_t level[2];
+	struct mixart_io_channel_level level[2];
 } __attribute__((packed));
 
 
 /*	MSG_STREAM_SET_IN_AUDIO_LEVEL        = 0x130015,
  */
 
-typedef struct mixart_in_audio_level_info mixart_in_audio_level_info_t;
 struct mixart_in_audio_level_info
 {
-	mixart_uid_t connector;
+	struct mixart_uid connector;
 	u32 valid_mask1;
 	u32 valid_mask2;
 	u32 digital_level;
 	u32 analog_level;
 } __attribute__((packed));
 
-typedef struct mixart_set_in_audio_level_req mixart_set_in_audio_level_req_t;
 struct mixart_set_in_audio_level_req
 {
 	u32 delayed;
 	u64 scheduler;
 	u32 audio_count;  /* set to <= 2 */
 	u32 reserved4np;
-	mixart_in_audio_level_info_t level[2];
+	struct mixart_in_audio_level_info level[2];
 } __attribute__((packed));
 
 /* response is a 32 bit status */
@@ -556,7 +523,6 @@
 #define MIXART_OUT_STREAM_SET_LEVEL_MUTE_1		0x40
 #define MIXART_OUT_STREAM_SET_LEVEL_MUTE_2		0x80
 
-typedef struct mixart_out_stream_level_info mixart_out_stream_level_info_t;
 struct mixart_out_stream_level_info
 {
 	u32 valid_mask1;
@@ -571,37 +537,35 @@
 	u32 mute2;
 } __attribute__((packed));
 
-typedef struct mixart_set_out_stream_level mixart_set_out_stream_level_t;
 struct mixart_set_out_stream_level
 {
-	mixart_txx_stream_desc_t desc;
-	mixart_out_stream_level_info_t out_level;
+	struct mixart_txx_stream_desc desc;
+	struct mixart_out_stream_level_info out_level;
 } __attribute__((packed));
 
-typedef struct mixart_set_out_stream_level_req mixart_set_out_stream_level_req_t;
 struct mixart_set_out_stream_level_req
 {
 	u32 delayed;
 	u64 scheduler;
 	u32 reserved4np[2];
 	u32 nb_of_stream;  /* set to 1 */
-	mixart_set_out_stream_level_t stream_level; /* could be an array */
+	struct mixart_set_out_stream_level stream_level; /* could be an array */
 } __attribute__((packed));
 
 /* response to this request is a u32 status value */
 
 
 /* exported */
-void snd_mixart_init_mailbox(mixart_mgr_t *mgr);
-void snd_mixart_exit_mailbox(mixart_mgr_t *mgr);
+void snd_mixart_init_mailbox(struct mixart_mgr *mgr);
+void snd_mixart_exit_mailbox(struct mixart_mgr *mgr);
 
-int  snd_mixart_send_msg(mixart_mgr_t *mgr, mixart_msg_t *request, int max_resp_size, void *resp_data);
-int  snd_mixart_send_msg_wait_notif(mixart_mgr_t *mgr, mixart_msg_t *request, u32 notif_event);
-int  snd_mixart_send_msg_nonblock(mixart_mgr_t *mgr, mixart_msg_t *request);
+int  snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int max_resp_size, void *resp_data);
+int  snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, struct mixart_msg *request, u32 notif_event);
+int  snd_mixart_send_msg_nonblock(struct mixart_mgr *mgr, struct mixart_msg *request);
 
 irqreturn_t snd_mixart_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-void snd_mixart_msg_tasklet( unsigned long arg);
+void snd_mixart_msg_tasklet(unsigned long arg);
 
-void snd_mixart_reset_board(mixart_mgr_t *mgr);
+void snd_mixart_reset_board(struct mixart_mgr *mgr);
 
 #endif /* __SOUND_MIXART_CORE_H */
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index edd1599..ca05075 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -40,7 +40,9 @@
  * @param value value
  * @param timeout timeout in centisenconds
  */
-static int mixart_wait_nice_for_register_value(mixart_mgr_t *mgr, u32 offset, int is_egal, u32 value, unsigned long timeout)
+static int mixart_wait_nice_for_register_value(struct mixart_mgr *mgr,
+					       u32 offset, int is_egal,
+					       u32 value, unsigned long timeout)
 {
 	unsigned long end_time = jiffies + (timeout * HZ / 100);
 	u32 read;
@@ -66,8 +68,6 @@
 /*
   structures needed to upload elf code packets 
  */
-typedef struct snd_mixart_elf32_ehdr snd_mixart_elf32_ehdr_t;
-
 struct snd_mixart_elf32_ehdr {
 	u8      e_ident[16];
 	u16     e_type;
@@ -85,8 +85,6 @@
 	u16     e_shstrndx;
 };
 
-typedef struct snd_mixart_elf32_phdr snd_mixart_elf32_phdr_t;
-
 struct snd_mixart_elf32_phdr {
 	u32     p_type;
 	u32     p_offset;
@@ -98,19 +96,19 @@
 	u32     p_align;
 };
 
-static int mixart_load_elf(mixart_mgr_t *mgr, const struct firmware *dsp )
+static int mixart_load_elf(struct mixart_mgr *mgr, const struct firmware *dsp )
 {
 	char                    elf32_magic_number[4] = {0x7f,'E','L','F'};
-	snd_mixart_elf32_ehdr_t *elf_header;
+	struct snd_mixart_elf32_ehdr *elf_header;
 	int                     i;
 
-	elf_header = (snd_mixart_elf32_ehdr_t *)dsp->data;
+	elf_header = (struct snd_mixart_elf32_ehdr *)dsp->data;
 	for( i=0; i<4; i++ )
 		if ( elf32_magic_number[i] != elf_header->e_ident[i] )
 			return -EINVAL;
 
 	if( elf_header->e_phoff != 0 ) {
-		snd_mixart_elf32_phdr_t     elf_programheader;
+		struct snd_mixart_elf32_phdr     elf_programheader;
 
 		for( i=0; i < be16_to_cpu(elf_header->e_phnum); i++ ) {
 			u32 pos = be32_to_cpu(elf_header->e_phoff) + (u32)(i * be16_to_cpu(elf_header->e_phentsize));
@@ -137,14 +135,14 @@
 #define MIXART_FIRST_ANA_AUDIO_ID       0
 #define MIXART_FIRST_DIG_AUDIO_ID       8
 
-static int mixart_enum_connectors(mixart_mgr_t *mgr)
+static int mixart_enum_connectors(struct mixart_mgr *mgr)
 {
 	u32 k;
 	int err;
-	mixart_msg_t request;
-	mixart_enum_connector_resp_t *connector;
-	mixart_audio_info_req_t  *audio_info_req;
-	mixart_audio_info_resp_t *audio_info;
+	struct mixart_msg request;
+	struct mixart_enum_connector_resp *connector;
+	struct mixart_audio_info_req  *audio_info_req;
+	struct mixart_audio_info_resp *audio_info;
 
 	connector = kmalloc(sizeof(*connector), GFP_KERNEL);
 	audio_info_req = kmalloc(sizeof(*audio_info_req), GFP_KERNEL);
@@ -159,7 +157,7 @@
 	audio_info_req->cd_max_level = MIXART_FLOAT____0_0_TO_HEX;
 
 	request.message_id = MSG_SYSTEM_ENUM_PLAY_CONNECTOR;
-	request.uid = (mixart_uid_t){0,0};  /* board num = 0 */
+	request.uid = (struct mixart_uid){0,0};  /* board num = 0 */
 	request.data = NULL;
 	request.size = 0;
 
@@ -171,7 +169,7 @@
 	}
 
 	for(k=0; k < connector->uid_count; k++) {
-		mixart_pipe_t* pipe;
+		struct mixart_pipe *pipe;
 
 		if(k < MIXART_FIRST_DIG_AUDIO_ID) {
 			pipe = &mgr->chip[k/2]->pipe_out_ana;
@@ -201,7 +199,7 @@
 	}
 
 	request.message_id = MSG_SYSTEM_ENUM_RECORD_CONNECTOR;
-	request.uid = (mixart_uid_t){0,0};  /* board num = 0 */
+	request.uid = (struct mixart_uid){0,0};  /* board num = 0 */
 	request.data = NULL;
 	request.size = 0;
 
@@ -213,7 +211,7 @@
 	}
 
 	for(k=0; k < connector->uid_count; k++) {
-		mixart_pipe_t* pipe;
+		struct mixart_pipe *pipe;
 
 		if(k < MIXART_FIRST_DIG_AUDIO_ID) {
 			pipe = &mgr->chip[k/2]->pipe_in_ana;
@@ -251,14 +249,14 @@
 	return err;
 }
 
-static int mixart_enum_physio(mixart_mgr_t *mgr)
+static int mixart_enum_physio(struct mixart_mgr *mgr)
 {
 	u32 k;
 	int err;
-	mixart_msg_t request;
-	mixart_uid_t get_console_mgr;
-	mixart_return_uid_t console_mgr;
-	mixart_uid_enumeration_t phys_io;
+	struct mixart_msg request;
+	struct mixart_uid get_console_mgr;
+	struct mixart_return_uid console_mgr;
+	struct mixart_uid_enumeration phys_io;
 
 	/* get the uid for the console manager */
 	get_console_mgr.object_id = 0;
@@ -280,7 +278,7 @@
 	mgr->uid_console_manager = console_mgr.uid;
 
 	request.message_id = MSG_SYSTEM_ENUM_PHYSICAL_IO;
-	request.uid = (mixart_uid_t){0,0};
+	request.uid = (struct mixart_uid){0,0};
 	request.data = &console_mgr.uid;
 	request.size = sizeof(console_mgr.uid);
 
@@ -301,11 +299,11 @@
 }
 
 
-static int mixart_first_init(mixart_mgr_t *mgr)
+static int mixart_first_init(struct mixart_mgr *mgr)
 {
 	u32 k;
 	int err;
-	mixart_msg_t request;
+	struct mixart_msg request;
 
 	if((err = mixart_enum_connectors(mgr)) < 0) return err;
 
@@ -314,7 +312,7 @@
 	/* send a synchro command to card (necessary to do this before first MSG_STREAM_START_STREAM_GRP_PACKET) */
 	/* though why not here */
 	request.message_id = MSG_SYSTEM_SEND_SYNCHRO_CMD;
-	request.uid = (mixart_uid_t){0,0};
+	request.uid = (struct mixart_uid){0,0};
 	request.data = NULL;
 	request.size = 0;
 	/* this command has no data. response is a 32 bit status */
@@ -331,7 +329,7 @@
 /* firmware base addresses (when hard coded) */
 #define MIXART_MOTHERBOARD_XLX_BASE_ADDRESS   0x00600000
 
-static int mixart_dsp_load(mixart_mgr_t* mgr, int index, const struct firmware *dsp)
+static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmware *dsp)
 {
 	int           err, card_index;
 	u32           status_xilinx, status_elf, status_daught;
@@ -513,7 +511,7 @@
 
        	/* create devices and mixer in accordance with HW options*/
         for (card_index = 0; card_index < mgr->num_cards; card_index++) {
-		mixart_t *chip = mgr->chip[card_index];
+		struct snd_mixart *chip = mgr->chip[card_index];
 
 		if ((err = snd_mixart_create_pcm(chip)) < 0)
 			return err;
@@ -541,7 +539,7 @@
 
 #ifdef SND_MIXART_FW_LOADER
 
-int snd_mixart_setup_firmware(mixart_mgr_t *mgr)
+int snd_mixart_setup_firmware(struct mixart_mgr *mgr)
 {
 	static char *fw_files[3] = {
 		"miXart8.xlx", "miXart8.elf", "miXart8AES.xlx"
@@ -573,19 +571,20 @@
 /* miXart hwdep interface id string */
 #define SND_MIXART_HWDEP_ID       "miXart Loader"
 
-static int mixart_hwdep_open(snd_hwdep_t *hw, struct file *file)
+static int mixart_hwdep_open(struct snd_hwdep *hw, struct file *file)
 {
 	return 0;
 }
 
-static int mixart_hwdep_release(snd_hwdep_t *hw, struct file *file)
+static int mixart_hwdep_release(struct snd_hwdep *hw, struct file *file)
 {
 	return 0;
 }
 
-static int mixart_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *info)
+static int mixart_hwdep_dsp_status(struct snd_hwdep *hw,
+				   struct snd_hwdep_dsp_status *info)
 {
-	mixart_mgr_t *mgr = hw->private_data;
+	struct mixart_mgr *mgr = hw->private_data;
 
 	strcpy(info->id, "miXart");
         info->num_dsps = MIXART_HARDW_FILES_MAX_INDEX;
@@ -597,9 +596,10 @@
 	return 0;
 }
 
-static int mixart_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp)
+static int mixart_hwdep_dsp_load(struct snd_hwdep *hw,
+				 struct snd_hwdep_dsp_image *dsp)
 {
-	mixart_mgr_t* mgr = hw->private_data;
+	struct mixart_mgr* mgr = hw->private_data;
 	struct firmware fw;
 	int err;
 
@@ -622,10 +622,10 @@
 	return err;
 }
 
-int snd_mixart_setup_firmware(mixart_mgr_t *mgr)
+int snd_mixart_setup_firmware(struct mixart_mgr *mgr)
 {
 	int err;
-	snd_hwdep_t *hw;
+	struct snd_hwdep *hw;
 
 	/* only create hwdep interface for first cardX (see "index" module parameter)*/
 	if ((err = snd_hwdep_new(mgr->chip[0]->card, SND_MIXART_HWDEP_ID, 0, &hw)) < 0)
diff --git a/sound/pci/mixart/mixart_hwdep.h b/sound/pci/mixart/mixart_hwdep.h
index 25190cc..a46f508 100644
--- a/sound/pci/mixart/mixart_hwdep.h
+++ b/sound/pci/mixart/mixart_hwdep.h
@@ -140,6 +140,6 @@
 #define MIXART_OIDI                             0x008   /* 0000 0000 1000 */
 
 
-int snd_mixart_setup_firmware(mixart_mgr_t *mgr);
+int snd_mixart_setup_firmware(struct mixart_mgr *mgr);
 
 #endif /* __SOUND_MIXART_HWDEP_H */
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
index 39c1541..36a7e9d 100644
--- a/sound/pci/mixart/mixart_mixer.c
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -298,12 +298,12 @@
 #define MIXART_ANALOG_PLAYBACK_LEVEL_MAX  192    /*   0.0 dB + 1.5 dB =  1.5 dB */
 #define MIXART_ANALOG_PLAYBACK_ZERO_LEVEL 189    /*  -1.5 dB + 1.5 dB =  0.0 dB */
 
-static int mixart_update_analog_audio_level(mixart_t* chip, int is_capture)
+static int mixart_update_analog_audio_level(struct snd_mixart* chip, int is_capture)
 {
 	int i, err;
-	mixart_msg_t request;
-	mixart_io_level_t io_level;
-	mixart_return_uid_t resp;
+	struct mixart_msg request;
+	struct mixart_io_level io_level;
+	struct mixart_return_uid resp;
 
 	memset(&io_level, 0, sizeof(io_level));
 	io_level.channel = -1; /* left and right */
@@ -336,7 +336,7 @@
 /*
  * analog level control
  */
-static int mixart_analog_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int mixart_analog_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -350,9 +350,9 @@
 	return 0;
 }
 
-static int mixart_analog_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_analog_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	down(&chip->mgr->mixer_mutex);
 	if(kcontrol->private_value == 0) {	/* playback */
 		ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
@@ -365,9 +365,9 @@
 	return 0;
 }
 
-static int mixart_analog_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	int changed = 0;
 	int is_capture, i;
 
@@ -386,7 +386,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t mixart_control_analog_level = {
+static struct snd_kcontrol_new mixart_control_analog_level = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	/* name will be filled later */
 	.info =		mixart_analog_vol_info,
@@ -395,7 +395,7 @@
 };
 
 /* shared */
-static int mixart_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int mixart_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -404,9 +404,9 @@
 	return 0;
 }
 
-static int mixart_audio_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_audio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 
 	down(&chip->mgr->mixer_mutex);
 	ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
@@ -415,9 +415,9 @@
 	return 0;
 }
 
-static int mixart_audio_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_audio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	int i, changed = 0;
 	down(&chip->mgr->mixer_mutex);
 	for(i=0; i<2; i++) {
@@ -431,7 +431,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t mixart_control_output_switch = {
+static struct snd_kcontrol_new mixart_control_output_switch = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Master Playback Switch",
 	.info =         mixart_sw_info,		/* shared */
@@ -703,14 +703,14 @@
 #define MIXART_DIGITAL_ZERO_LEVEL  219    /*  0.0 dB */
 
 
-int mixart_update_playback_stream_level(mixart_t* chip, int is_aes, int idx)
+int mixart_update_playback_stream_level(struct snd_mixart* chip, int is_aes, int idx)
 {
 	int err, i;
 	int volume[2];
-	mixart_msg_t request;
-	mixart_set_out_stream_level_req_t set_level;
+	struct mixart_msg request;
+	struct mixart_set_out_stream_level_req set_level;
 	u32 status;
-	mixart_pipe_t *pipe;
+	struct mixart_pipe *pipe;
 
 	memset(&set_level, 0, sizeof(set_level));
 	set_level.nb_of_stream = 1;
@@ -741,7 +741,7 @@
 	set_level.stream_level.out_level.right_to_out2_level = mixart_digital_level[volume[1]];
 
 	request.message_id = MSG_STREAM_SET_OUT_STREAM_LEVEL;
-	request.uid = (mixart_uid_t){0,0};
+	request.uid = (struct mixart_uid){0,0};
 	request.data = &set_level;
 	request.size = sizeof(set_level);
 
@@ -753,12 +753,12 @@
 	return 0;
 }
 
-int mixart_update_capture_stream_level(mixart_t* chip, int is_aes)
+int mixart_update_capture_stream_level(struct snd_mixart* chip, int is_aes)
 {
 	int err, i, idx;
-	mixart_pipe_t* pipe;
-	mixart_msg_t request;
-	mixart_set_in_audio_level_req_t set_level;
+	struct mixart_pipe *pipe;
+	struct mixart_msg request;
+	struct mixart_set_in_audio_level_req set_level;
 	u32 status;
 
 	if(is_aes) {
@@ -784,7 +784,7 @@
 	}
 
 	request.message_id = MSG_STREAM_SET_IN_AUDIO_LEVEL;
-	request.uid = (mixart_uid_t){0,0};
+	request.uid = (struct mixart_uid){0,0};
 	request.data = &set_level;
 	request.size = sizeof(set_level);
 
@@ -798,7 +798,7 @@
 
 
 /* shared */
-static int mixart_digital_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int mixart_digital_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -810,9 +810,9 @@
 #define MIXART_VOL_REC_MASK	1
 #define MIXART_VOL_AES_MASK	2
 
-static int mixart_pcm_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
 	int *stored_volume;
 	int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
@@ -832,9 +832,9 @@
 	return 0;
 }
 
-static int mixart_pcm_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
 	int changed = 0;
 	int is_capture = kcontrol->private_value & MIXART_VOL_REC_MASK;
@@ -864,7 +864,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t snd_mixart_pcm_vol =
+static struct snd_kcontrol_new snd_mixart_pcm_vol =
 {
 	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
 	/* name will be filled later */
@@ -875,9 +875,9 @@
 };
 
 
-static int mixart_pcm_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
 	snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); 
 	down(&chip->mgr->mixer_mutex);
@@ -889,9 +889,9 @@
 	return 0;
 }
 
-static int mixart_pcm_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	int changed = 0;
 	int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK;
 	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
@@ -911,7 +911,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t mixart_control_pcm_switch = {
+static struct snd_kcontrol_new mixart_control_pcm_switch = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	/* name will be filled later */
 	.count =        MIXART_PLAYBACK_STREAMS,
@@ -920,11 +920,11 @@
 	.put =          mixart_pcm_sw_put
 };
 
-static int mixart_update_monitoring(mixart_t* chip, int channel)
+static int mixart_update_monitoring(struct snd_mixart* chip, int channel)
 {
 	int err;
-	mixart_msg_t request;
-	mixart_set_out_audio_level_t audio_level;
+	struct mixart_msg request;
+	struct mixart_set_out_audio_level audio_level;
 	u32 resp;
 
 	if(chip->pipe_out_ana.status == PIPE_UNDEFINED)
@@ -953,9 +953,9 @@
  * monitoring level control
  */
 
-static int mixart_monitor_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_monitor_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	down(&chip->mgr->mixer_mutex);
 	ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
 	ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
@@ -963,9 +963,9 @@
 	return 0;
 }
 
-static int mixart_monitor_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_monitor_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	int changed = 0;
 	int i;
 	down(&chip->mgr->mixer_mutex);
@@ -980,7 +980,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t mixart_control_monitor_vol = {
+static struct snd_kcontrol_new mixart_control_monitor_vol = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Monitoring Volume",
 	.info =		mixart_digital_vol_info,		/* shared */
@@ -992,9 +992,9 @@
  * monitoring switch control
  */
 
-static int mixart_monitor_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_monitor_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	down(&chip->mgr->mixer_mutex);
 	ucontrol->value.integer.value[0] = chip->monitoring_active[0];
 	ucontrol->value.integer.value[1] = chip->monitoring_active[1];
@@ -1002,9 +1002,9 @@
 	return 0;
 }
 
-static int mixart_monitor_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixart_monitor_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	mixart_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_mixart *chip = snd_kcontrol_chip(kcontrol);
 	int changed = 0;
 	int i;
 	down(&chip->mgr->mixer_mutex);
@@ -1033,7 +1033,7 @@
 	return (changed != 0);
 }
 
-static snd_kcontrol_new_t mixart_control_monitor_sw = {
+static struct snd_kcontrol_new mixart_control_monitor_sw = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Monitoring Switch",
 	.info =         mixart_sw_info,		/* shared */
@@ -1042,7 +1042,7 @@
 };
 
 
-static void mixart_reset_audio_levels(mixart_t *chip)
+static void mixart_reset_audio_levels(struct snd_mixart *chip)
 {
 	/* analog volumes can be set even if there is no pipe */
 	mixart_update_analog_audio_level(chip, 0);
@@ -1054,15 +1054,15 @@
 }
 
 
-int snd_mixart_create_mixer(mixart_mgr_t *mgr)
+int snd_mixart_create_mixer(struct mixart_mgr *mgr)
 {
-	mixart_t *chip;
+	struct snd_mixart *chip;
 	int err, i;
 
 	init_MUTEX(&mgr->mixer_mutex); /* can be in another place */
 
 	for(i=0; i<mgr->num_cards; i++) {
-		snd_kcontrol_new_t temp;
+		struct snd_kcontrol_new temp;
 		chip = mgr->chip[i];
 
 		/* analog output level control */
diff --git a/sound/pci/mixart/mixart_mixer.h b/sound/pci/mixart/mixart_mixer.h
index b4d9535..04aa24e 100644
--- a/sound/pci/mixart/mixart_mixer.h
+++ b/sound/pci/mixart/mixart_mixer.h
@@ -24,8 +24,8 @@
 #define __SOUND_MIXART_MIXER_H
 
 /* exported */
-int mixart_update_playback_stream_level(mixart_t* chip, int is_aes, int idx);
-int mixart_update_capture_stream_level(mixart_t* chip, int is_aes);
-int snd_mixart_create_mixer(mixart_mgr_t* mgr);
+int mixart_update_playback_stream_level(struct snd_mixart* chip, int is_aes, int idx);
+int mixart_update_capture_stream_level(struct snd_mixart* chip, int is_aes);
+int snd_mixart_create_mixer(struct mixart_mgr* mgr);
 
 #endif /* __SOUND_MIXART_MIXER_H */
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 089d23b..0d0ff54 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -183,17 +183,10 @@
 #define NM_PBUFFER_WMARK (NM_PLAYBACK_REG_OFFSET + 0xc)
 #define NM_PBUFFER_CURRP (NM_PLAYBACK_REG_OFFSET + 0x8)
 
-/*
- * type definitions
- */
+struct nm256_stream {
 
-typedef struct snd_nm256 nm256_t;
-typedef struct snd_nm256_stream nm256_stream_t;
-
-struct snd_nm256_stream {
-
-	nm256_t *chip;
-	snd_pcm_substream_t *substream;
+	struct nm256 *chip;
+	struct snd_pcm_substream *substream;
 	int running;
 	int suspended;
 	
@@ -210,9 +203,9 @@
 
 };
 
-struct snd_nm256 {
+struct nm256 {
 	
-	snd_card_t *card;
+	struct snd_card *card;
 
 	void __iomem *cport;		/* control port */
 	struct resource *res_cport;	/* its resource */
@@ -244,11 +237,11 @@
 	int badintrcount;		/* counter to check bogus interrupts */
 	struct semaphore irq_mutex;
 
-	nm256_stream_t streams[2];
+	struct nm256_stream streams[2];
 
-	ac97_t *ac97;
+	struct snd_ac97 *ac97;
 
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 
 	struct pci_dev *pci;
 
@@ -281,48 +274,49 @@
  */
 
 static inline u8
-snd_nm256_readb(nm256_t *chip, int offset)
+snd_nm256_readb(struct nm256 *chip, int offset)
 {
 	return readb(chip->cport + offset);
 }
 
 static inline u16
-snd_nm256_readw(nm256_t *chip, int offset)
+snd_nm256_readw(struct nm256 *chip, int offset)
 {
 	return readw(chip->cport + offset);
 }
 
 static inline u32
-snd_nm256_readl(nm256_t *chip, int offset)
+snd_nm256_readl(struct nm256 *chip, int offset)
 {
 	return readl(chip->cport + offset);
 }
 
 static inline void
-snd_nm256_writeb(nm256_t *chip, int offset, u8 val)
+snd_nm256_writeb(struct nm256 *chip, int offset, u8 val)
 {
 	writeb(val, chip->cport + offset);
 }
 
 static inline void
-snd_nm256_writew(nm256_t *chip, int offset, u16 val)
+snd_nm256_writew(struct nm256 *chip, int offset, u16 val)
 {
 	writew(val, chip->cport + offset);
 }
 
 static inline void
-snd_nm256_writel(nm256_t *chip, int offset, u32 val)
+snd_nm256_writel(struct nm256 *chip, int offset, u32 val)
 {
 	writel(val, chip->cport + offset);
 }
 
 static inline void
-snd_nm256_write_buffer(nm256_t *chip, void *src, int offset, int size)
+snd_nm256_write_buffer(struct nm256 *chip, void *src, int offset, int size)
 {
 	offset -= chip->buffer_start;
 #ifdef CONFIG_SND_DEBUG
 	if (offset < 0 || offset >= chip->buffer_size) {
-		snd_printk(KERN_ERR "write_buffer invalid offset = %d size = %d\n", offset, size);
+		snd_printk(KERN_ERR "write_buffer invalid offset = %d size = %d\n",
+			   offset, size);
 		return;
 	}
 #endif
@@ -343,7 +337,7 @@
 }
 
 static void
-snd_nm256_load_one_coefficient(nm256_t *chip, int stream, u32 port, int which)
+snd_nm256_load_one_coefficient(struct nm256 *chip, int stream, u32 port, int which)
 {
 	u32 coeff_buf = chip->coeff_buf[stream];
 	u16 offset = snd_nm256_get_start_offset(which);
@@ -358,13 +352,15 @@
 }
 
 static void
-snd_nm256_load_coefficient(nm256_t *chip, int stream, int number)
+snd_nm256_load_coefficient(struct nm256 *chip, int stream, int number)
 {
 	/* The enable register for the specified engine.  */
-	u32 poffset = (stream == SNDRV_PCM_STREAM_CAPTURE ? NM_RECORD_ENABLE_REG : NM_PLAYBACK_ENABLE_REG);
+	u32 poffset = (stream == SNDRV_PCM_STREAM_CAPTURE ?
+		       NM_RECORD_ENABLE_REG : NM_PLAYBACK_ENABLE_REG);
 	u32 addr = NM_COEFF_START_OFFSET;
 
-	addr += (stream == SNDRV_PCM_STREAM_CAPTURE ? NM_RECORD_REG_OFFSET : NM_PLAYBACK_REG_OFFSET);
+	addr += (stream == SNDRV_PCM_STREAM_CAPTURE ?
+		 NM_RECORD_REG_OFFSET : NM_PLAYBACK_REG_OFFSET);
 
 	if (snd_nm256_readb(chip, poffset) & 1) {
 		snd_printd("NM256: Engine was enabled while loading coefficients!\n");
@@ -400,7 +396,7 @@
 static unsigned int samplerates[8] = {
 	8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
 };
-static snd_pcm_hw_constraint_list_t constraints_rates = {
+static struct snd_pcm_hw_constraint_list constraints_rates = {
 	.count = ARRAY_SIZE(samplerates), 
 	.list = samplerates,
 	.mask = 0,
@@ -425,9 +421,10 @@
  * set sample rate and format
  */
 static void
-snd_nm256_set_format(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *substream)
+snd_nm256_set_format(struct nm256 *chip, struct nm256_stream *s,
+		     struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int rate_index = snd_nm256_fixed_rate(runtime->rate);
 	unsigned char ratebits = (rate_index << 4) & NM_RATE_MASK;
 
@@ -460,12 +457,12 @@
 }
 
 /* acquire interrupt */
-static int snd_nm256_acquire_irq(nm256_t *chip)
+static int snd_nm256_acquire_irq(struct nm256 *chip)
 {
 	down(&chip->irq_mutex);
 	if (chip->irq < 0) {
 		if (request_irq(chip->pci->irq, chip->interrupt, SA_INTERRUPT|SA_SHIRQ,
-				chip->card->driver, (void*)chip)) {
+				chip->card->driver, chip)) {
 			snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
 			up(&chip->irq_mutex);
 			return -EBUSY;
@@ -478,13 +475,13 @@
 }
 
 /* release interrupt */
-static void snd_nm256_release_irq(nm256_t *chip)
+static void snd_nm256_release_irq(struct nm256 *chip)
 {
 	down(&chip->irq_mutex);
 	if (chip->irq_acks > 0)
 		chip->irq_acks--;
 	if (chip->irq_acks == 0 && chip->irq >= 0) {
-		free_irq(chip->irq, (void*)chip);
+		free_irq(chip->irq, chip);
 		chip->irq = -1;
 	}
 	up(&chip->irq_mutex);
@@ -495,7 +492,7 @@
  */
 
 /* update the watermark (current period) */
-static void snd_nm256_pcm_mark(nm256_t *chip, nm256_stream_t *s, int reg)
+static void snd_nm256_pcm_mark(struct nm256 *chip, struct nm256_stream *s, int reg)
 {
 	s->cur_period++;
 	s->cur_period %= s->periods;
@@ -506,7 +503,8 @@
 #define snd_nm256_capture_mark(chip, s)  snd_nm256_pcm_mark(chip, s, NM_RBUFFER_WMARK)
 
 static void
-snd_nm256_playback_start(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *substream)
+snd_nm256_playback_start(struct nm256 *chip, struct nm256_stream *s,
+			 struct snd_pcm_substream *substream)
 {
 	/* program buffer pointers */
 	snd_nm256_writel(chip, NM_PBUFFER_START, s->buf);
@@ -522,7 +520,8 @@
 }
 
 static void
-snd_nm256_capture_start(nm256_t *chip, nm256_stream_t *s, snd_pcm_substream_t *substream)
+snd_nm256_capture_start(struct nm256 *chip, struct nm256_stream *s,
+			struct snd_pcm_substream *substream)
 {
 	/* program buffer pointers */
 	snd_nm256_writel(chip, NM_RBUFFER_START, s->buf);
@@ -537,7 +536,7 @@
 
 /* Stop the play engine. */
 static void
-snd_nm256_playback_stop(nm256_t *chip)
+snd_nm256_playback_stop(struct nm256 *chip)
 {
 	/* Shut off sound from both channels. */
 	snd_nm256_writew(chip, NM_AUDIO_MUTE_REG,
@@ -547,17 +546,17 @@
 }
 
 static void
-snd_nm256_capture_stop(nm256_t *chip)
+snd_nm256_capture_stop(struct nm256 *chip)
 {
 	/* Disable recording engine. */
 	snd_nm256_writeb(chip, NM_RECORD_ENABLE_REG, 0);
 }
 
 static int
-snd_nm256_playback_trigger(snd_pcm_substream_t *substream, int cmd)
+snd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	nm256_t *chip = snd_pcm_substream_chip(substream);
-	nm256_stream_t *s = (nm256_stream_t*)substream->runtime->private_data;
+	struct nm256 *chip = snd_pcm_substream_chip(substream);
+	struct nm256_stream *s = substream->runtime->private_data;
 	int err = 0;
 
 	snd_assert(s != NULL, return -ENXIO);
@@ -591,10 +590,10 @@
 }
 
 static int
-snd_nm256_capture_trigger(snd_pcm_substream_t *substream, int cmd)
+snd_nm256_capture_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	nm256_t *chip = snd_pcm_substream_chip(substream);
-	nm256_stream_t *s = (nm256_stream_t*)substream->runtime->private_data;
+	struct nm256 *chip = snd_pcm_substream_chip(substream);
+	struct nm256_stream *s = substream->runtime->private_data;
 	int err = 0;
 
 	snd_assert(s != NULL, return -ENXIO);
@@ -627,11 +626,11 @@
 /*
  * prepare playback/capture channel
  */
-static int snd_nm256_pcm_prepare(snd_pcm_substream_t *substream)
+static int snd_nm256_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	nm256_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	nm256_stream_t *s = (nm256_stream_t*)runtime->private_data;
+	struct nm256 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct nm256_stream *s = runtime->private_data;
 
 	snd_assert(s, return -ENXIO);
 	s->dma_size = frames_to_bytes(runtime, substream->runtime->buffer_size);
@@ -652,10 +651,10 @@
  * get the current pointer
  */
 static snd_pcm_uframes_t
-snd_nm256_playback_pointer(snd_pcm_substream_t * substream)
+snd_nm256_playback_pointer(struct snd_pcm_substream *substream)
 {
-	nm256_t *chip = snd_pcm_substream_chip(substream);
-	nm256_stream_t *s = (nm256_stream_t*)substream->runtime->private_data;
+	struct nm256 *chip = snd_pcm_substream_chip(substream);
+	struct nm256_stream *s = substream->runtime->private_data;
 	unsigned long curp;
 
 	snd_assert(s, return 0);
@@ -665,10 +664,10 @@
 }
 
 static snd_pcm_uframes_t
-snd_nm256_capture_pointer(snd_pcm_substream_t * substream)
+snd_nm256_capture_pointer(struct snd_pcm_substream *substream)
 {
-	nm256_t *chip = snd_pcm_substream_chip(substream);
-	nm256_stream_t *s = (nm256_stream_t*)substream->runtime->private_data;
+	struct nm256 *chip = snd_pcm_substream_chip(substream);
+	struct nm256_stream *s = substream->runtime->private_data;
 	unsigned long curp;
 
 	snd_assert(s != NULL, return 0);
@@ -684,13 +683,13 @@
  * silence / copy for playback
  */
 static int
-snd_nm256_playback_silence(snd_pcm_substream_t *substream,
+snd_nm256_playback_silence(struct snd_pcm_substream *substream,
 			   int channel, /* not used (interleaved data) */
 			   snd_pcm_uframes_t pos,
 			   snd_pcm_uframes_t count)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	nm256_stream_t *s = (nm256_stream_t*)runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct nm256_stream *s = runtime->private_data;
 	count = frames_to_bytes(runtime, count);
 	pos = frames_to_bytes(runtime, pos);
 	memset_io(s->bufptr + pos, 0, count);
@@ -698,14 +697,14 @@
 }
 
 static int
-snd_nm256_playback_copy(snd_pcm_substream_t *substream,
+snd_nm256_playback_copy(struct snd_pcm_substream *substream,
 			int channel, /* not used (interleaved data) */
 			snd_pcm_uframes_t pos,
 			void __user *src,
 			snd_pcm_uframes_t count)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	nm256_stream_t *s = (nm256_stream_t*)runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct nm256_stream *s = runtime->private_data;
 	count = frames_to_bytes(runtime, count);
 	pos = frames_to_bytes(runtime, pos);
 	if (copy_from_user_toio(s->bufptr + pos, src, count))
@@ -717,14 +716,14 @@
  * copy to user
  */
 static int
-snd_nm256_capture_copy(snd_pcm_substream_t *substream,
+snd_nm256_capture_copy(struct snd_pcm_substream *substream,
 		       int channel, /* not used (interleaved data) */
 		       snd_pcm_uframes_t pos,
 		       void __user *dst,
 		       snd_pcm_uframes_t count)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	nm256_stream_t *s = (nm256_stream_t*)runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct nm256_stream *s = runtime->private_data;
 	count = frames_to_bytes(runtime, count);
 	pos = frames_to_bytes(runtime, pos);
 	if (copy_to_user_fromio(dst, s->bufptr + pos, count))
@@ -741,9 +740,9 @@
 
 /* spinlock held! */
 static void
-snd_nm256_playback_update(nm256_t *chip)
+snd_nm256_playback_update(struct nm256 *chip)
 {
-	nm256_stream_t *s;
+	struct nm256_stream *s;
 
 	s = &chip->streams[SNDRV_PCM_STREAM_PLAYBACK];
 	if (s->running && s->substream) {
@@ -756,9 +755,9 @@
 
 /* spinlock held! */
 static void
-snd_nm256_capture_update(nm256_t *chip)
+snd_nm256_capture_update(struct nm256 *chip)
 {
-	nm256_stream_t *s;
+	struct nm256_stream *s;
 
 	s = &chip->streams[SNDRV_PCM_STREAM_CAPTURE];
 	if (s->running && s->substream) {
@@ -772,7 +771,7 @@
 /*
  * hardware info
  */
-static snd_pcm_hardware_t snd_nm256_playback =
+static struct snd_pcm_hardware snd_nm256_playback =
 {
 	.info =			SNDRV_PCM_INFO_MMAP_IOMEM |SNDRV_PCM_INFO_MMAP_VALID |
 				SNDRV_PCM_INFO_INTERLEAVED |
@@ -791,7 +790,7 @@
 	.period_bytes_max =	128 * 1024,
 };
 
-static snd_pcm_hardware_t snd_nm256_capture =
+static struct snd_pcm_hardware snd_nm256_capture =
 {
 	.info =			SNDRV_PCM_INFO_MMAP_IOMEM | SNDRV_PCM_INFO_MMAP_VALID |
 				SNDRV_PCM_INFO_INTERLEAVED |
@@ -812,7 +811,8 @@
 
 
 /* set dma transfer size */
-static int snd_nm256_pcm_hw_params(snd_pcm_substream_t *substream, snd_pcm_hw_params_t *hw_params)
+static int snd_nm256_pcm_hw_params(struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *hw_params)
 {
 	/* area and addr are already set and unchanged */
 	substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
@@ -822,11 +822,11 @@
 /*
  * open
  */
-static void snd_nm256_setup_stream(nm256_t *chip, nm256_stream_t *s,
-				   snd_pcm_substream_t *substream,
-				   snd_pcm_hardware_t *hw_ptr)
+static void snd_nm256_setup_stream(struct nm256 *chip, struct nm256_stream *s,
+				   struct snd_pcm_substream *substream,
+				   struct snd_pcm_hardware *hw_ptr)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	s->running = 0;
 	runtime->hw = *hw_ptr;
@@ -844,9 +844,9 @@
 }
 
 static int
-snd_nm256_playback_open(snd_pcm_substream_t *substream)
+snd_nm256_playback_open(struct snd_pcm_substream *substream)
 {
-	nm256_t *chip = snd_pcm_substream_chip(substream);
+	struct nm256 *chip = snd_pcm_substream_chip(substream);
 
 	if (snd_nm256_acquire_irq(chip) < 0)
 		return -EBUSY;
@@ -856,9 +856,9 @@
 }
 
 static int
-snd_nm256_capture_open(snd_pcm_substream_t *substream)
+snd_nm256_capture_open(struct snd_pcm_substream *substream)
 {
-	nm256_t *chip = snd_pcm_substream_chip(substream);
+	struct nm256 *chip = snd_pcm_substream_chip(substream);
 
 	if (snd_nm256_acquire_irq(chip) < 0)
 		return -EBUSY;
@@ -871,9 +871,9 @@
  * close - we don't have to do special..
  */
 static int
-snd_nm256_playback_close(snd_pcm_substream_t *substream)
+snd_nm256_playback_close(struct snd_pcm_substream *substream)
 {
-	nm256_t *chip = snd_pcm_substream_chip(substream);
+	struct nm256 *chip = snd_pcm_substream_chip(substream);
 
 	snd_nm256_release_irq(chip);
 	return 0;
@@ -881,9 +881,9 @@
 
 
 static int
-snd_nm256_capture_close(snd_pcm_substream_t *substream)
+snd_nm256_capture_close(struct snd_pcm_substream *substream)
 {
-	nm256_t *chip = snd_pcm_substream_chip(substream);
+	struct nm256 *chip = snd_pcm_substream_chip(substream);
 
 	snd_nm256_release_irq(chip);
 	return 0;
@@ -892,7 +892,7 @@
 /*
  * create a pcm instance
  */
-static snd_pcm_ops_t snd_nm256_playback_ops = {
+static struct snd_pcm_ops snd_nm256_playback_ops = {
 	.open =		snd_nm256_playback_open,
 	.close =	snd_nm256_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -907,7 +907,7 @@
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-static snd_pcm_ops_t snd_nm256_capture_ops = {
+static struct snd_pcm_ops snd_nm256_capture_ops = {
 	.open =		snd_nm256_capture_open,
 	.close =	snd_nm256_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -922,13 +922,13 @@
 };
 
 static int __devinit
-snd_nm256_pcm(nm256_t *chip, int device)
+snd_nm256_pcm(struct nm256 *chip, int device)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int i, err;
 
 	for (i = 0; i < 2; i++) {
-		nm256_stream_t *s = &chip->streams[i];
+		struct nm256_stream *s = &chip->streams[i];
 		s->bufptr = chip->buffer + (s->buf - chip->buffer_start);
 		s->bufptr_addr = chip->buffer_addr + (s->buf - chip->buffer_start);
 	}
@@ -953,7 +953,7 @@
  * Initialize the hardware. 
  */
 static void
-snd_nm256_init_chip(nm256_t *chip)
+snd_nm256_init_chip(struct nm256 *chip)
 {
 	/* Reset everything. */
 	snd_nm256_writeb(chip, 0x0, 0x11);
@@ -965,7 +965,7 @@
 
 
 static irqreturn_t
-snd_nm256_intr_check(nm256_t *chip)
+snd_nm256_intr_check(struct nm256 *chip)
 {
 	if (chip->badintrcount++ > 1000) {
 		/*
@@ -1002,7 +1002,7 @@
 static irqreturn_t
 snd_nm256_interrupt(int irq, void *dev_id, struct pt_regs *dummy)
 {
-	nm256_t *chip = dev_id;
+	struct nm256 *chip = dev_id;
 	u16 status;
 	u8 cbyte;
 
@@ -1067,7 +1067,7 @@
 static irqreturn_t
 snd_nm256_interrupt_zx(int irq, void *dev_id, struct pt_regs *dummy)
 {
-	nm256_t *chip = dev_id;
+	struct nm256 *chip = dev_id;
 	u32 status;
 	u8 cbyte;
 
@@ -1131,7 +1131,7 @@
  * if it timed out.
  */
 static int
-snd_nm256_ac97_ready(nm256_t *chip)
+snd_nm256_ac97_ready(struct nm256 *chip)
 {
 	int timeout = 10;
 	u32 testaddr;
@@ -1154,9 +1154,9 @@
 /*
  */
 static unsigned short
-snd_nm256_ac97_read(ac97_t *ac97, unsigned short reg)
+snd_nm256_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
-	nm256_t *chip = ac97->private_data;
+	struct nm256 *chip = ac97->private_data;
 	int res;
 
 	if (reg >= 128)
@@ -1173,10 +1173,10 @@
 /* 
  */
 static void
-snd_nm256_ac97_write(ac97_t *ac97,
+snd_nm256_ac97_write(struct snd_ac97 *ac97,
 		     unsigned short reg, unsigned short val)
 {
-	nm256_t *chip = ac97->private_data;
+	struct nm256 *chip = ac97->private_data;
 	int tries = 2;
 	u32 base;
 
@@ -1196,9 +1196,9 @@
 
 /* initialize the ac97 into a known state */
 static void
-snd_nm256_ac97_reset(ac97_t *ac97)
+snd_nm256_ac97_reset(struct snd_ac97 *ac97)
 {
-	nm256_t *chip = ac97->private_data;
+	struct nm256 *chip = ac97->private_data;
 
 	/* Reset the mixer.  'Tis magic!  */
 	snd_nm256_writeb(chip, 0x6c0, 1);
@@ -1215,12 +1215,12 @@
 
 /* create an ac97 mixer interface */
 static int __devinit
-snd_nm256_mixer(nm256_t *chip)
+snd_nm256_mixer(struct nm256 *chip)
 {
-	ac97_bus_t *pbus;
-	ac97_template_t ac97;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
 	int i, err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.reset = snd_nm256_ac97_reset,
 		.write = snd_nm256_ac97_write,
 		.read = snd_nm256_ac97_read,
@@ -1263,7 +1263,7 @@
  */
 
 static int __devinit
-snd_nm256_peek_for_sig(nm256_t *chip)
+snd_nm256_peek_for_sig(struct nm256 *chip)
 {
 	/* The signature is located 1K below the end of video RAM.  */
 	void __iomem *temp;
@@ -1292,7 +1292,8 @@
 			return -ENODEV;
 		} else {
 			pointer_found = pointer;
-			printk(KERN_INFO "nm256: found card signature in video RAM: 0x%x\n", pointer);
+			printk(KERN_INFO "nm256: found card signature in video RAM: 0x%x\n",
+			       pointer);
 		}
 	}
 
@@ -1307,31 +1308,36 @@
  * APM event handler, so the card is properly reinitialized after a power
  * event.
  */
-static int nm256_suspend(snd_card_t *card, pm_message_t state)
+static int nm256_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	nm256_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct nm256 *chip = card->private_data;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 	snd_ac97_suspend(chip->ac97);
 	chip->coeffs_current = 0;
-	pci_disable_device(chip->pci);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int nm256_resume(snd_card_t *card)
+static int nm256_resume(struct pci_dev *pci)
 {
-	nm256_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct nm256 *chip = card->private_data;
 	int i;
 
 	/* Perform a full reset on the hardware */
-	pci_enable_device(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
 	snd_nm256_init_chip(chip);
 
 	/* restore ac97 */
 	snd_ac97_resume(chip->ac97);
 
 	for (i = 0; i < 2; i++) {
-		nm256_stream_t *s = &chip->streams[i];
+		struct nm256_stream *s = &chip->streams[i];
 		if (s->substream && s->suspended) {
 			spin_lock_irq(&chip->reg_lock);
 			snd_nm256_set_format(chip, s, s->substream);
@@ -1339,11 +1345,12 @@
 		}
 	}
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
-static int snd_nm256_free(nm256_t *chip)
+static int snd_nm256_free(struct nm256 *chip)
 {
 	if (chip->streams[SNDRV_PCM_STREAM_PLAYBACK].running)
 		snd_nm256_playback_stop(chip);
@@ -1360,30 +1367,26 @@
 	release_and_free_resource(chip->res_cport);
 	release_and_free_resource(chip->res_buffer);
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void*)chip);
+		free_irq(chip->irq, chip);
 
 	pci_disable_device(chip->pci);
 	kfree(chip);
 	return 0;
 }
 
-static int snd_nm256_dev_free(snd_device_t *device)
+static int snd_nm256_dev_free(struct snd_device *device)
 {
-	nm256_t *chip = device->device_data;
+	struct nm256 *chip = device->device_data;
 	return snd_nm256_free(chip);
 }
 
 static int __devinit
-snd_nm256_create(snd_card_t *card, struct pci_dev *pci,
-		 int play_bufsize, int capt_bufsize,
-		 int force_load,
-		 u32 buffertop,
-		 int usecache,
-		 nm256_t **chip_ret)
+snd_nm256_create(struct snd_card *card, struct pci_dev *pci,
+		 struct nm256 **chip_ret)
 {
-	nm256_t *chip;
+	struct nm256 *chip;
 	int err, pval;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_nm256_dev_free,
 	};
 	u32 addr;
@@ -1401,13 +1404,14 @@
 
 	chip->card = card;
 	chip->pci = pci;
-	chip->use_cache = usecache;
+	chip->use_cache = use_cache;
 	spin_lock_init(&chip->reg_lock);
 	chip->irq = -1;
 	init_MUTEX(&chip->irq_mutex);
 
-	chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = play_bufsize;
-	chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize = capt_bufsize;
+	/* store buffer sizes in bytes */
+	chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize = playback_bufsize * 1024;
+	chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize = capture_bufsize * 1024;
 
 	/* 
 	 * The NM256 has two memory ports.  The first port is nothing
@@ -1440,9 +1444,10 @@
 		/* Ok, try to see if this is a non-AC97 version of the hardware. */
 		pval = snd_nm256_readw(chip, NM_MIXER_PRESENCE);
 		if ((pval & NM_PRESENCE_MASK) != NM_PRESENCE_VALUE) {
-			if (! force_load) {
+			if (! force_ac97) {
 				printk(KERN_ERR "nm256: no ac97 is found!\n");
-				printk(KERN_ERR "  force the driver to load by passing in the module parameter\n");
+				printk(KERN_ERR "  force the driver to load by "
+				       "passing in the module parameter\n");
 				printk(KERN_ERR "    force_ac97=1\n");
 				printk(KERN_ERR "  or try sb16 or cs423x drivers instead.\n");
 				err = -ENXIO;
@@ -1465,14 +1470,15 @@
 		chip->mixer_status_mask = NM2_MIXER_READY_MASK;
 	}
 	
-	chip->buffer_size = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize + chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize;
+	chip->buffer_size = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].bufsize +
+		chip->streams[SNDRV_PCM_STREAM_CAPTURE].bufsize;
 	if (chip->use_cache)
 		chip->buffer_size += NM_TOTAL_COEFF_COUNT * 4;
 	else
 		chip->buffer_size += NM_MAX_PLAYBACK_COEF_SIZE + NM_MAX_RECORD_COEF_SIZE;
 
-	if (buffertop >= chip->buffer_size && buffertop < chip->buffer_end)
-		chip->buffer_end = buffertop;
+	if (buffer_top >= chip->buffer_size && buffer_top < chip->buffer_end)
+		chip->buffer_end = buffer_top;
 	else {
 		/* get buffer end pointer from signature */
 		if ((err = snd_nm256_peek_for_sig(chip)) < 0)
@@ -1524,8 +1530,6 @@
 
 	// pci_set_master(pci); /* needed? */
 	
-	snd_card_set_pm_callback(card, nm256_suspend, nm256_resume, chip);
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
 		goto __error;
 
@@ -1564,10 +1568,9 @@
 static int __devinit snd_nm256_probe(struct pci_dev *pci,
 				     const struct pci_device_id *pci_id)
 {
-	snd_card_t *card;
-	nm256_t *chip;
+	struct snd_card *card;
+	struct nm256 *chip;
 	int err;
-	unsigned int xbuffer_top;
 	struct nm256_quirk *q;
 	u16 subsystem_vendor, subsystem_device;
 
@@ -1578,7 +1581,8 @@
 		if (q->vendor == subsystem_vendor && q->device == subsystem_device) {
 			switch (q->type) {
 			case NM_BLACKLISTED:
-				printk(KERN_INFO "nm256: The device is blacklisted.  Loading stopped\n");
+				printk(KERN_INFO "nm256: The device is blacklisted. "
+				       "Loading stopped\n");
 				return -ENODEV;
 			case NM_RESET_WORKAROUND_2:
 				reset_workaround_2 = 1;
@@ -1611,9 +1615,7 @@
 	}
 
 	if (vaio_hack)
-		xbuffer_top = 0x25a800;	/* this avoids conflicts with XFree86 server */
-	else
-		xbuffer_top = buffer_top;
+		buffer_top = 0x25a800;	/* this avoids conflicts with XFree86 server */
 
 	if (playback_bufsize < 4)
 		playback_bufsize = 4;
@@ -1623,16 +1625,11 @@
 		capture_bufsize = 4;
 	if (capture_bufsize > 128)
 		capture_bufsize = 128;
-	if ((err = snd_nm256_create(card, pci,
-				    playback_bufsize * 1024, /* in bytes */
-				    capture_bufsize * 1024,  /* in bytes */
-				    force_ac97,
-				    xbuffer_top,
-				    use_cache,
-				    &chip)) < 0) {
+	if ((err = snd_nm256_create(card, pci, &chip)) < 0) {
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = chip;
 
 	if (reset_workaround) {
 		snd_printdd(KERN_INFO "nm256: reset_workaround activated\n");
@@ -1676,7 +1673,10 @@
 	.id_table = snd_nm256_ids,
 	.probe = snd_nm256_probe,
 	.remove = __devexit_p(snd_nm256_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = nm256_suspend,
+	.resume = nm256_resume,
+#endif
 };
 
 
diff --git a/sound/pci/pcxhr/Makefile b/sound/pci/pcxhr/Makefile
new file mode 100644
index 0000000..10473c0
--- /dev/null
+++ b/sound/pci/pcxhr/Makefile
@@ -0,0 +1,2 @@
+snd-pcxhr-objs := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o
+obj-$(CONFIG_SND_PCXHR) += snd-pcxhr.o
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
new file mode 100644
index 0000000..b8c0853
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -0,0 +1,1367 @@
+/*
+ * Driver for Digigram pcxhr compatible soundcards
+ *
+ * main file with alsa callbacks
+ *
+ * Copyright (c) 2004 by Digigram <alsa@digigram.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 <sound/driver.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/moduleparam.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/info.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include "pcxhr.h"
+#include "pcxhr_mixer.h"
+#include "pcxhr_hwdep.h"
+#include "pcxhr_core.h"
+
+#define DRIVER_NAME "pcxhr"
+
+MODULE_AUTHOR("Markus Bollinger <bollinger@digigram.com>");
+MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING);
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{Digigram," DRIVER_NAME "}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;		/* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;		/* ID for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;	/* Enable this card */
+static int mono[SNDRV_CARDS];					/* capture in mono only */
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for Digigram " DRIVER_NAME " soundcard");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable Digigram " DRIVER_NAME " soundcard");
+module_param_array(mono, bool, NULL, 0444);
+MODULE_PARM_DESC(mono, "Mono capture mode (default is stereo)");
+
+enum {
+	PCI_ID_VX882HR,
+	PCI_ID_PCX882HR,
+	PCI_ID_VX881HR,
+	PCI_ID_PCX881HR,
+	PCI_ID_PCX1222HR,
+	PCI_ID_PCX1221HR,
+	PCI_ID_LAST
+};
+
+static struct pci_device_id pcxhr_ids[] = {
+	{ 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, },   /* VX882HR */
+	{ 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, },  /* PCX882HR */
+	{ 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, },   /* VX881HR */
+	{ 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, },  /* PCX881HR */
+	{ 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, }, /* PCX1222HR */
+	{ 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, }, /* PCX1221HR */
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, pcxhr_ids);
+
+struct board_parameters {
+	char* board_name;
+	short playback_chips;
+	short capture_chips;
+	short firmware_num;
+};
+static struct board_parameters pcxhr_board_params[] = {
+[PCI_ID_VX882HR] =	{ "VX882HR",   4, 4, 41, },
+[PCI_ID_PCX882HR] =	{ "PCX882HR",  4, 4, 41, },
+[PCI_ID_VX881HR] =	{ "VX881HR",   4, 4, 41, },
+[PCI_ID_PCX881HR] =	{ "PCX881HR",  4, 4, 41, },
+[PCI_ID_PCX1222HR] =	{ "PCX1222HR", 6, 1, 42, },
+[PCI_ID_PCX1221HR] =	{ "PCX1221HR", 6, 1, 42, },
+};
+
+
+static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
+				   unsigned int* realfreq)
+{
+	unsigned int reg;
+
+	if (freq < 6900 || freq > 110250)
+		return -EINVAL;
+	reg = (28224000 * 10) / freq;
+	reg = (reg + 5) / 10;
+	if (reg < 0x200)
+		*pllreg = reg + 0x800;
+	else if (reg < 0x400)
+		*pllreg = reg & 0x1ff;
+	else if (reg < 0x800) {
+		*pllreg = ((reg >> 1) & 0x1ff) + 0x200;
+		reg &= ~1;
+	} else {
+		*pllreg = ((reg >> 2) & 0x1ff) + 0x400;
+		reg &= ~3;
+	}
+	if (realfreq)
+		*realfreq = ((28224000 * 10) / reg + 5) / 10;
+	return 0;
+}
+
+
+#define PCXHR_FREQ_REG_MASK		0x1f
+#define PCXHR_FREQ_QUARTZ_48000		0x00
+#define PCXHR_FREQ_QUARTZ_24000		0x01
+#define PCXHR_FREQ_QUARTZ_12000		0x09
+#define PCXHR_FREQ_QUARTZ_32000		0x08
+#define PCXHR_FREQ_QUARTZ_16000		0x04
+#define PCXHR_FREQ_QUARTZ_8000		0x0c
+#define PCXHR_FREQ_QUARTZ_44100		0x02
+#define PCXHR_FREQ_QUARTZ_22050		0x0a
+#define PCXHR_FREQ_QUARTZ_11025		0x06
+#define PCXHR_FREQ_PLL			0x05
+#define PCXHR_FREQ_QUARTZ_192000	0x10
+#define PCXHR_FREQ_QUARTZ_96000		0x18
+#define PCXHR_FREQ_QUARTZ_176400	0x14
+#define PCXHR_FREQ_QUARTZ_88200		0x1c
+#define PCXHR_FREQ_QUARTZ_128000	0x12
+#define PCXHR_FREQ_QUARTZ_64000		0x1a
+
+#define PCXHR_FREQ_WORD_CLOCK		0x0f
+#define PCXHR_FREQ_SYNC_AES		0x0e
+#define PCXHR_FREQ_AES_1		0x07
+#define PCXHR_FREQ_AES_2		0x0b
+#define PCXHR_FREQ_AES_3		0x03
+#define PCXHR_FREQ_AES_4		0x0d
+
+#define PCXHR_MODIFY_CLOCK_S_BIT	0x04
+
+#define PCXHR_IRQ_TIMER_FREQ		92000
+#define PCXHR_IRQ_TIMER_PERIOD		48
+
+static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
+			       unsigned int *reg, unsigned int *freq)
+{
+	unsigned int val, realfreq, pllreg;
+	struct pcxhr_rmh rmh;
+	int err;
+
+	realfreq = rate;
+	switch (mgr->use_clock_type) {
+	case PCXHR_CLOCK_TYPE_INTERNAL :	/* clock by quartz or pll */
+		switch (rate) {
+		case 48000 :	val = PCXHR_FREQ_QUARTZ_48000;	break;
+		case 24000 :	val = PCXHR_FREQ_QUARTZ_24000;	break;
+		case 12000 :	val = PCXHR_FREQ_QUARTZ_12000;	break;
+		case 32000 :	val = PCXHR_FREQ_QUARTZ_32000;	break;
+		case 16000 :	val = PCXHR_FREQ_QUARTZ_16000;	break;
+		case 8000 :	val = PCXHR_FREQ_QUARTZ_8000;	break;
+		case 44100 :	val = PCXHR_FREQ_QUARTZ_44100;	break;
+		case 22050 :	val = PCXHR_FREQ_QUARTZ_22050;	break;
+		case 11025 :	val = PCXHR_FREQ_QUARTZ_11025;	break;
+		case 192000 :	val = PCXHR_FREQ_QUARTZ_192000;	break;
+		case 96000 :	val = PCXHR_FREQ_QUARTZ_96000;	break;
+		case 176400 :	val = PCXHR_FREQ_QUARTZ_176400;	break;
+		case 88200 :	val = PCXHR_FREQ_QUARTZ_88200;	break;
+		case 128000 :	val = PCXHR_FREQ_QUARTZ_128000;	break;
+		case 64000 :	val = PCXHR_FREQ_QUARTZ_64000;	break;
+		default :
+			val = PCXHR_FREQ_PLL;
+			/* get the value for the pll register */
+			err = pcxhr_pll_freq_register(rate, &pllreg, &realfreq);
+			if (err)
+				return err;
+			pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
+			rmh.cmd[0] |= IO_NUM_REG_GENCLK;
+			rmh.cmd[1]  = pllreg & MASK_DSP_WORD;
+			rmh.cmd[2]  = pllreg >> 24;
+			rmh.cmd_len = 3;
+			err = pcxhr_send_msg(mgr, &rmh);
+			if (err < 0) {
+				snd_printk(KERN_ERR
+					   "error CMD_ACCESS_IO_WRITE for PLL register : %x!\n",
+					   err );
+				return err;
+			}
+		}
+		break;
+	case PCXHR_CLOCK_TYPE_WORD_CLOCK :	val = PCXHR_FREQ_WORD_CLOCK;	break;
+	case PCXHR_CLOCK_TYPE_AES_SYNC :	val = PCXHR_FREQ_SYNC_AES;	break;
+	case PCXHR_CLOCK_TYPE_AES_1 :		val = PCXHR_FREQ_AES_1;		break;
+	case PCXHR_CLOCK_TYPE_AES_2 :		val = PCXHR_FREQ_AES_2;		break;
+	case PCXHR_CLOCK_TYPE_AES_3 :		val = PCXHR_FREQ_AES_3;		break;
+	case PCXHR_CLOCK_TYPE_AES_4 :		val = PCXHR_FREQ_AES_4;		break;
+	default : return -EINVAL;
+	}
+	*reg = val;
+	*freq = realfreq;
+	return 0;
+}
+
+
+int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
+{
+	unsigned int val, realfreq, speed;
+	struct pcxhr_rmh rmh;
+	int err, changed;
+
+	if (rate == 0)
+		return 0; /* nothing to do */
+
+	err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq);
+	if (err)
+		return err;
+
+	/* codec speed modes */
+	if (rate < 55000)
+		speed = 0;	/* single speed */
+	else if (rate < 100000)
+		speed = 1;	/* dual speed */
+	else
+		speed = 2;	/* quad speed */
+	if (mgr->codec_speed != speed) {
+		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);	/* mute outputs */
+		rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
+		err = pcxhr_send_msg(mgr, &rmh);
+		if (err)
+			return err;
+
+		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);	/* set speed ratio */
+		rmh.cmd[0] |= IO_NUM_SPEED_RATIO;
+		rmh.cmd[1] = speed;
+		rmh.cmd_len = 2;
+		err = pcxhr_send_msg(mgr, &rmh);
+		if (err)
+			return err;
+	}
+	/* set the new frequency */
+	snd_printdd("clock register : set %x\n", val);
+	err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK, val, &changed);
+	if (err)
+		return err;
+	mgr->sample_rate_real = realfreq;
+	mgr->cur_clock_type = mgr->use_clock_type;
+
+	/* unmute after codec speed modes */
+	if (mgr->codec_speed != speed) {
+		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);	/* unmute outputs */
+		rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
+		err = pcxhr_send_msg(mgr, &rmh);
+		if (err)
+			return err;
+		mgr->codec_speed = speed;			/* save new codec speed */
+	}
+
+	if (changed) {
+		pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK);
+		rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT;		/* resync fifos  */
+		if (rate < PCXHR_IRQ_TIMER_FREQ)
+			rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD;
+		else
+			rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD * 2;
+		rmh.cmd[2] = rate;
+		rmh.cmd_len = 3;
+		err = pcxhr_send_msg(mgr, &rmh);
+		if (err)
+			return err;
+	}
+	snd_printdd("pcxhr_set_clock to %dHz (realfreq=%d)\n", rate, realfreq);
+	return 0;
+}
+
+
+int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_type,
+			     int *sample_rate)
+{
+	struct pcxhr_rmh rmh;
+	unsigned char reg;
+	int err, rate;
+
+	switch (clock_type) {
+	case PCXHR_CLOCK_TYPE_WORD_CLOCK :	reg = REG_STATUS_WORD_CLOCK;	break;
+	case PCXHR_CLOCK_TYPE_AES_SYNC :	reg = REG_STATUS_AES_SYNC;	break;
+	case PCXHR_CLOCK_TYPE_AES_1 :		reg = REG_STATUS_AES_1;		break;
+	case PCXHR_CLOCK_TYPE_AES_2 :		reg = REG_STATUS_AES_2;		break;
+	case PCXHR_CLOCK_TYPE_AES_3 :		reg = REG_STATUS_AES_3;		break;
+	case PCXHR_CLOCK_TYPE_AES_4 :		reg = REG_STATUS_AES_4;		break;
+	default : return -EINVAL;
+	}
+	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
+	rmh.cmd_len = 2;
+	rmh.cmd[0] |= IO_NUM_REG_STATUS;
+	if (mgr->last_reg_stat != reg) {
+		rmh.cmd[1]  = reg;
+		err = pcxhr_send_msg(mgr, &rmh);
+		if (err)
+			return err;
+		udelay(100);		/* wait minimum 2 sample_frames at 32kHz ! */
+		mgr->last_reg_stat = reg;
+	}
+	rmh.cmd[1]  = REG_STATUS_CURRENT;
+	err = pcxhr_send_msg(mgr, &rmh);
+	if (err)
+		return err;
+	switch (rmh.stat[1] & 0x0f) {
+	case REG_STATUS_SYNC_32000 :	rate = 32000; break;
+	case REG_STATUS_SYNC_44100 :	rate = 44100; break;
+	case REG_STATUS_SYNC_48000 :	rate = 48000; break;
+	case REG_STATUS_SYNC_64000 :	rate = 64000; break;
+	case REG_STATUS_SYNC_88200 :	rate = 88200; break;
+	case REG_STATUS_SYNC_96000 :	rate = 96000; break;
+	case REG_STATUS_SYNC_128000 :	rate = 128000; break;
+	case REG_STATUS_SYNC_176400 :	rate = 176400; break;
+	case REG_STATUS_SYNC_192000 :	rate = 192000; break;
+	default: rate = 0;
+	}
+	snd_printdd("External clock is at %d Hz\n", rate);
+	*sample_rate = rate;
+	return 0;
+}
+
+
+/*
+ *  start or stop playback/capture substream
+ */
+static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
+{
+	int err;
+	struct snd_pcxhr *chip;
+	struct pcxhr_rmh rmh;
+	int stream_mask, start;
+
+	if (stream->status == PCXHR_STREAM_STATUS_SCHEDULE_RUN)
+		start = 1;
+	else {
+		if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) {
+			snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state CANNOT be stopped\n");
+			return -EINVAL;
+		}
+		start = 0;
+	}
+	if (!stream->substream)
+		return -EINVAL;
+
+	stream->timer_abs_periods = 0;
+	stream->timer_period_frag = 0;            /* reset theoretical stream pos */
+	stream->timer_buf_periods = 0;
+	stream->timer_is_synced = 0;
+
+	stream_mask = stream->pipe->is_capture ? 1 : 1<<stream->substream->number;
+
+	pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM);
+	pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
+				  stream->pipe->first_audio, 0, stream_mask);
+
+	chip = snd_pcm_substream_chip(stream->substream);
+
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	if (err)
+		snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state err=%x;\n", err);
+	stream->status = start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED;
+	return err;
+}
+
+#define HEADER_FMT_BASE_LIN		0xfed00000
+#define HEADER_FMT_BASE_FLOAT		0xfad00000
+#define HEADER_FMT_INTEL		0x00008000
+#define HEADER_FMT_24BITS		0x00004000
+#define HEADER_FMT_16BITS		0x00002000
+#define HEADER_FMT_UPTO11		0x00000200
+#define HEADER_FMT_UPTO32		0x00000100
+#define HEADER_FMT_MONO			0x00000080
+
+static int pcxhr_set_format(struct pcxhr_stream *stream)
+{
+	int err, is_capture, sample_rate, stream_num;
+	struct snd_pcxhr *chip;
+	struct pcxhr_rmh rmh;
+	unsigned int header;
+
+	switch (stream->format) {
+	case SNDRV_PCM_FORMAT_U8:
+		header = HEADER_FMT_BASE_LIN;
+		break;
+	case SNDRV_PCM_FORMAT_S16_LE:
+		header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS | HEADER_FMT_INTEL;
+		break;
+	case SNDRV_PCM_FORMAT_S16_BE:
+		header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS;
+		break;
+	case SNDRV_PCM_FORMAT_S24_3LE:
+		header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS | HEADER_FMT_INTEL;
+		break;
+	case SNDRV_PCM_FORMAT_S24_3BE:
+		header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS;
+		break;
+	case SNDRV_PCM_FORMAT_FLOAT_LE:
+		header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL;
+		break;
+	default:
+		snd_printk(KERN_ERR "error pcxhr_set_format() : unknown format\n");
+		return -EINVAL;
+	}
+	chip = snd_pcm_substream_chip(stream->substream);
+
+	sample_rate = chip->mgr->sample_rate;
+	if (sample_rate <= 32000 && sample_rate !=0) {
+		if (sample_rate <= 11025)
+			header |= HEADER_FMT_UPTO11;
+		else
+			header |= HEADER_FMT_UPTO32;
+	}
+	if (stream->channels == 1)
+		header |= HEADER_FMT_MONO;
+
+	is_capture = stream->pipe->is_capture;
+	stream_num = is_capture ? 0 : stream->substream->number;
+
+	pcxhr_init_rmh(&rmh, is_capture ? CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
+	pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0);
+	if (is_capture)
+		rmh.cmd[0] |= 1<<12;
+	rmh.cmd[1] = 0;
+	rmh.cmd[2] = header >> 8;
+	rmh.cmd[3] = (header & 0xff) << 16;
+	rmh.cmd_len = 4;
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	if (err)
+		snd_printk(KERN_ERR "ERROR pcxhr_set_format err=%x;\n", err);
+	return err;
+}
+
+static int pcxhr_update_r_buffer(struct pcxhr_stream *stream)
+{
+	int err, is_capture, stream_num;
+	struct pcxhr_rmh rmh;
+	struct snd_pcm_substream *subs = stream->substream;
+	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
+
+	is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE);
+	stream_num = is_capture ? 0 : subs->number;
+
+	snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%x) subs(%d)\n",
+		    is_capture ? 'c' : 'p',
+		    chip->chip_idx, (void*)subs->runtime->dma_addr,
+		    subs->runtime->dma_bytes, subs->number);
+
+	pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS);
+	pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0);
+
+	snd_assert(subs->runtime->dma_bytes < 0x200000);	/* max buffer size is 2 MByte */
+	rmh.cmd[1] = subs->runtime->dma_bytes * 8;		/* size in bits */
+	rmh.cmd[2] = subs->runtime->dma_addr >> 24;		/* most significant byte */
+	rmh.cmd[2] |= 1<<19;					/* this is a circular buffer */
+	rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD;	/* least 3 significant bytes */
+	rmh.cmd_len = 4;
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	if (err)
+		snd_printk(KERN_ERR "ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err);
+	return err;
+}
+
+
+#if 0
+static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream, snd_pcm_uframes_t *sample_count)
+{
+	struct pcxhr_rmh rmh;
+	int err;
+	pcxhr_t *chip = snd_pcm_substream_chip(stream->substream);
+	pcxhr_init_rmh(&rmh, CMD_PIPE_SAMPLE_COUNT);
+	pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 0, 0,
+				  1<<stream->pipe->first_audio);
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	if (err == 0) {
+		*sample_count = ((snd_pcm_uframes_t)rmh.stat[0]) << 24;
+		*sample_count += (snd_pcm_uframes_t)rmh.stat[1];
+	}
+	snd_printdd("PIPE_SAMPLE_COUNT = %lx\n", *sample_count);
+	return err;
+}
+#endif
+
+static inline int pcxhr_stream_scheduled_get_pipe(struct pcxhr_stream *stream,
+						  struct pcxhr_pipe **pipe)
+{
+	if (stream->status == PCXHR_STREAM_STATUS_SCHEDULE_RUN) {
+		*pipe = stream->pipe;
+		return 1;
+	}
+	return 0;
+}
+
+static void pcxhr_trigger_tasklet(unsigned long arg)
+{
+	unsigned long flags;
+	int i, j, err;
+	struct pcxhr_pipe *pipe;
+	struct snd_pcxhr *chip;
+	struct pcxhr_mgr *mgr = (struct pcxhr_mgr*)(arg);
+	int capture_mask = 0;
+	int playback_mask = 0;
+
+#ifdef CONFIG_SND_DEBUG_DETECT
+	struct timeval my_tv1, my_tv2;
+	do_gettimeofday(&my_tv1);
+#endif
+	down(&mgr->setup_mutex);
+
+	/* check the pipes concerned and build pipe_array */
+	for (i = 0; i < mgr->num_cards; i++) {
+		chip = mgr->chip[i];
+		for (j = 0; j < chip->nb_streams_capt; j++) {
+			if (pcxhr_stream_scheduled_get_pipe(&chip->capture_stream[j], &pipe))
+				capture_mask |= (1 << pipe->first_audio);
+		}
+		for (j = 0; j < chip->nb_streams_play; j++) {
+			if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) {
+				playback_mask |= (1 << pipe->first_audio);
+				break;	/* add only once, as all playback streams of
+					 * one chip use the same pipe
+					 */
+			}
+		}
+	}
+	if (capture_mask == 0 && playback_mask == 0) {
+		up(&mgr->setup_mutex);
+		snd_printk(KERN_ERR "pcxhr_trigger_tasklet : no pipes\n");
+		return;
+	}
+
+	snd_printdd("pcxhr_trigger_tasklet : playback_mask=%x capture_mask=%x\n",
+		    playback_mask, capture_mask);
+
+	/* synchronous stop of all the pipes concerned */
+	err = pcxhr_set_pipe_state(mgr,  playback_mask, capture_mask, 0);
+	if (err) {
+		up(&mgr->setup_mutex);
+		snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error stop pipes (P%x C%x)\n",
+			   playback_mask, capture_mask);
+		return;
+	}
+
+	/* unfortunately the dsp lost format and buffer info with the stop pipe */
+	for (i = 0; i < mgr->num_cards; i++) {
+		struct pcxhr_stream *stream;
+		chip = mgr->chip[i];
+		for (j = 0; j < chip->nb_streams_capt; j++) {
+			stream = &chip->capture_stream[j];
+			if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) {
+				err = pcxhr_set_format(stream);
+				err = pcxhr_update_r_buffer(stream);
+			}
+		}
+		for (j = 0; j < chip->nb_streams_play; j++) {
+			stream = &chip->playback_stream[j];
+			if (pcxhr_stream_scheduled_get_pipe(stream, &pipe)) {
+				err = pcxhr_set_format(stream);
+				err = pcxhr_update_r_buffer(stream);
+			}
+		}
+	}
+	/* start all the streams */
+	for (i = 0; i < mgr->num_cards; i++) {
+		struct pcxhr_stream *stream;
+		chip = mgr->chip[i];
+		for (j = 0; j < chip->nb_streams_capt; j++) {
+			stream = &chip->capture_stream[j];
+			if (pcxhr_stream_scheduled_get_pipe(stream, &pipe))
+				err = pcxhr_set_stream_state(stream);
+		}
+		for (j = 0; j < chip->nb_streams_play; j++) {
+			stream = &chip->playback_stream[j];
+			if (pcxhr_stream_scheduled_get_pipe(stream, &pipe))
+				err = pcxhr_set_stream_state(stream);
+		}
+	}
+
+	/* synchronous start of all the pipes concerned */
+	err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
+	if (err) {
+		up(&mgr->setup_mutex);
+		snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error start pipes (P%x C%x)\n",
+			   playback_mask, capture_mask);
+		return;
+	}
+
+	/* put the streams into the running state now (increment pointer by interrupt) */
+	spin_lock_irqsave(&mgr->lock, flags);
+	for ( i =0; i < mgr->num_cards; i++) {
+		struct pcxhr_stream *stream;
+		chip = mgr->chip[i];
+		for(j = 0; j < chip->nb_streams_capt; j++) {
+			stream = &chip->capture_stream[j];
+			if(stream->status == PCXHR_STREAM_STATUS_STARTED)
+				stream->status = PCXHR_STREAM_STATUS_RUNNING;
+		}
+		for (j = 0; j < chip->nb_streams_play; j++) {
+			stream = &chip->playback_stream[j];
+			if (stream->status == PCXHR_STREAM_STATUS_STARTED) {
+				/* playback will already have advanced ! */
+				stream->timer_period_frag += PCXHR_GRANULARITY;
+				stream->status = PCXHR_STREAM_STATUS_RUNNING;
+			}
+		}
+	}
+	spin_unlock_irqrestore(&mgr->lock, flags);
+
+	up(&mgr->setup_mutex);
+
+#ifdef CONFIG_SND_DEBUG_DETECT
+	do_gettimeofday(&my_tv2);
+	snd_printdd("***TRIGGER TASKLET*** TIME = %ld (err = %x)\n",
+		    my_tv2.tv_usec - my_tv1.tv_usec, err);
+#endif
+}
+
+
+/*
+ *  trigger callback
+ */
+static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
+{
+	struct pcxhr_stream *stream;
+	struct list_head *pos;
+	struct snd_pcm_substream *s;
+	int i;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+		snd_printdd("SNDRV_PCM_TRIGGER_START\n");
+		i = 0;
+		snd_pcm_group_for_each(pos, subs) {
+			s = snd_pcm_group_substream_entry(pos);
+			stream = s->runtime->private_data;
+			stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN;
+			snd_pcm_trigger_done(s, subs);
+			i++;
+		}
+		if (i==1) {
+			snd_printdd("Only one Substream %c %d\n",
+				    stream->pipe->is_capture ? 'C' : 'P',
+				    stream->pipe->first_audio);
+			if (pcxhr_set_format(stream))
+				return -EINVAL;
+			if (pcxhr_update_r_buffer(stream))
+				return -EINVAL;
+
+			if (pcxhr_set_stream_state(stream))
+				return -EINVAL;
+			stream->status = PCXHR_STREAM_STATUS_RUNNING;
+		} else {
+			struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
+			tasklet_hi_schedule(&chip->mgr->trigger_taskq);
+		}
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+		snd_printdd("SNDRV_PCM_TRIGGER_STOP\n");
+		snd_pcm_group_for_each(pos, subs) {
+			s = snd_pcm_group_substream_entry(pos);
+			stream = s->runtime->private_data;
+			stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP;
+			if (pcxhr_set_stream_state(stream))
+				return -EINVAL;
+			snd_pcm_trigger_done(s, subs);
+		}
+		break;
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		/* TODO */
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+static int pcxhr_hardware_timer(struct pcxhr_mgr *mgr, int start)
+{
+	struct pcxhr_rmh rmh;
+	int err;
+
+	pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT);
+	if (start) {
+		mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;	/* last dsp time invalid */
+		rmh.cmd[0] |= PCXHR_GRANULARITY;
+	}
+	err = pcxhr_send_msg(mgr, &rmh);
+	if (err < 0)
+		snd_printk(KERN_ERR "error pcxhr_hardware_timer err(%x)\n", err);
+	return err;
+}
+
+/*
+ *  prepare callback for all pcms
+ */
+static int pcxhr_prepare(struct snd_pcm_substream *subs)
+{
+	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
+	struct pcxhr_mgr *mgr = chip->mgr;
+	/*
+	struct pcxhr_stream *stream = (pcxhr_stream_t*)subs->runtime->private_data;
+	*/
+	int err = 0;
+
+	snd_printdd("pcxhr_prepare : period_size(%lx) periods(%x) buffer_size(%lx)\n",
+		    subs->runtime->period_size, subs->runtime->periods,
+		    subs->runtime->buffer_size);
+
+	/*
+	if(subs->runtime->period_size <= PCXHR_GRANULARITY) {
+		snd_printk(KERN_ERR "pcxhr_prepare : error period_size too small (%x)\n",
+			   (unsigned int)subs->runtime->period_size);
+		return -EINVAL;
+	}
+	*/
+
+	down(&mgr->setup_mutex);
+
+	do {
+		/* if the stream was stopped before, format and buffer were reset */
+		/*
+		if(stream->status == PCXHR_STREAM_STATUS_STOPPED) {
+			err = pcxhr_set_format(stream);
+			if(err) break;
+			err = pcxhr_update_r_buffer(stream);
+			if(err) break;
+		}
+		*/
+
+		/* only the first stream can choose the sample rate */
+		/* the further opened streams will be limited to its frequency (see open) */
+		/* set the clock only once (first stream) */
+		if (mgr->sample_rate == 0) {
+			err = pcxhr_set_clock(mgr, subs->runtime->rate);
+			if (err)
+				break;
+			mgr->sample_rate = subs->runtime->rate;
+
+			err = pcxhr_hardware_timer(mgr, 1);	/* start the DSP-timer */
+		}
+	} while(0);	/* do only once (so we can use break instead of goto) */
+
+	up(&mgr->setup_mutex);
+
+	return err;
+}
+
+
+/*
+ *  HW_PARAMS callback for all pcms
+ */
+static int pcxhr_hw_params(struct snd_pcm_substream *subs,
+			   struct snd_pcm_hw_params *hw)
+{
+	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
+	struct pcxhr_mgr *mgr = chip->mgr;
+	struct pcxhr_stream *stream = subs->runtime->private_data;
+	snd_pcm_format_t format;
+	int err;
+	int channels;
+
+	/* set up channels */
+	channels = params_channels(hw);
+
+	/*  set up format for the stream */
+	format = params_format(hw);
+
+	down(&mgr->setup_mutex);
+
+	stream->channels = channels;
+	stream->format = format;
+
+	/* set the format to the board */
+	/*
+	err = pcxhr_set_format(stream);
+	if(err) {
+		up(&mgr->setup_mutex);
+		return err;
+	}
+	*/
+	/* allocate buffer */
+	err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw));
+
+	/*
+	if (err > 0) {
+		err = pcxhr_update_r_buffer(stream);
+	}
+	*/
+	up(&mgr->setup_mutex);
+
+	return err;
+}
+
+static int pcxhr_hw_free(struct snd_pcm_substream *subs)
+{
+	snd_pcm_lib_free_pages(subs);
+	return 0;
+}
+
+
+/*
+ *  CONFIGURATION SPACE for all pcms, mono pcm must update channels_max
+ */
+static struct snd_pcm_hardware pcxhr_caps =
+{
+	.info             = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
+			      SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START |
+			      0 /*SNDRV_PCM_INFO_PAUSE*/),
+	.formats	  = ( SNDRV_PCM_FMTBIT_U8 |
+			      SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |
+			      SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |
+			      SNDRV_PCM_FMTBIT_FLOAT_LE ),
+	.rates            = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
+	.rate_min         = 8000,
+	.rate_max         = 192000,
+	.channels_min     = 1,
+	.channels_max     = 2,
+	.buffer_bytes_max = (32*1024),
+	/* 1 byte == 1 frame U8 mono (PCXHR_GRANULARITY is frames!) */
+	.period_bytes_min = (2*PCXHR_GRANULARITY),
+	.period_bytes_max = (16*1024),
+	.periods_min      = 2,
+	.periods_max      = (32*1024/PCXHR_GRANULARITY),
+};
+
+
+static int pcxhr_open(struct snd_pcm_substream *subs)
+{
+	struct snd_pcxhr       *chip = snd_pcm_substream_chip(subs);
+	struct pcxhr_mgr       *mgr = chip->mgr;
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct pcxhr_stream    *stream;
+	int                 is_capture;
+
+	down(&mgr->setup_mutex);
+
+	/* copy the struct snd_pcm_hardware struct */
+	runtime->hw = pcxhr_caps;
+
+	if( subs->stream == SNDRV_PCM_STREAM_PLAYBACK ) {
+		snd_printdd("pcxhr_open playback chip%d subs%d\n",
+			    chip->chip_idx, subs->number);
+		is_capture = 0;
+		stream = &chip->playback_stream[subs->number];
+	} else {
+		snd_printdd("pcxhr_open capture chip%d subs%d\n",
+			    chip->chip_idx, subs->number);
+		is_capture = 1;
+		if (mgr->mono_capture)
+			runtime->hw.channels_max = 1;
+		else
+			runtime->hw.channels_min = 2;
+		stream = &chip->capture_stream[subs->number];
+	}
+	if (stream->status != PCXHR_STREAM_STATUS_FREE){
+		/* streams in use */
+		snd_printk(KERN_ERR "pcxhr_open chip%d subs%d in use\n",
+			   chip->chip_idx, subs->number);
+		up(&mgr->setup_mutex);
+		return -EBUSY;
+	}
+
+	/* if a sample rate is already used or fixed by external clock,
+	 * the stream cannot change
+	 */
+	if (mgr->sample_rate)
+		runtime->hw.rate_min = runtime->hw.rate_max = mgr->sample_rate;
+	else {
+		if (mgr->use_clock_type != PCXHR_CLOCK_TYPE_INTERNAL) {
+			int external_rate;
+			if (pcxhr_get_external_clock(mgr, mgr->use_clock_type,
+						     &external_rate) ||
+			    external_rate == 0) {
+				/* cannot detect the external clock rate */
+				up(&mgr->setup_mutex);
+				return -EBUSY;
+			}
+			runtime->hw.rate_min = runtime->hw.rate_max = external_rate;
+		}
+	}
+
+	stream->status      = PCXHR_STREAM_STATUS_OPEN;
+	stream->substream   = subs;
+	stream->channels    = 0; /* not configured yet */
+
+	runtime->private_data = stream;
+
+	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4);
+	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4);
+
+	mgr->ref_count_rate++;
+
+	up(&mgr->setup_mutex);
+	return 0;
+}
+
+
+static int pcxhr_close(struct snd_pcm_substream *subs)
+{
+	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
+	struct pcxhr_mgr *mgr = chip->mgr;
+	struct pcxhr_stream *stream = subs->runtime->private_data;
+
+	down(&mgr->setup_mutex);
+
+	snd_printdd("pcxhr_close chip%d subs%d\n", chip->chip_idx, subs->number);
+
+	/* sample rate released */
+	if (--mgr->ref_count_rate == 0) {
+		mgr->sample_rate = 0;		/* the sample rate is no more locked */
+		pcxhr_hardware_timer(mgr, 0);	/* stop the DSP-timer */
+	}
+
+	stream->status    = PCXHR_STREAM_STATUS_FREE;
+	stream->substream = NULL;
+
+	up(&mgr->setup_mutex);
+
+	return 0;
+}
+
+
+static snd_pcm_uframes_t pcxhr_stream_pointer(struct snd_pcm_substream *subs)
+{
+	unsigned long flags;
+	u_int32_t timer_period_frag;
+	int timer_buf_periods;
+	struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct pcxhr_stream *stream  = runtime->private_data;
+
+	spin_lock_irqsave(&chip->mgr->lock, flags);
+
+	/* get the period fragment and the nb of periods in the buffer */
+	timer_period_frag = stream->timer_period_frag;
+	timer_buf_periods = stream->timer_buf_periods;
+
+	spin_unlock_irqrestore(&chip->mgr->lock, flags);
+
+	return (snd_pcm_uframes_t)((timer_buf_periods * runtime->period_size) +
+				   timer_period_frag);
+}
+
+
+static struct snd_pcm_ops pcxhr_ops = {
+	.open      = pcxhr_open,
+	.close     = pcxhr_close,
+	.ioctl     = snd_pcm_lib_ioctl,
+	.prepare   = pcxhr_prepare,
+	.hw_params = pcxhr_hw_params,
+	.hw_free   = pcxhr_hw_free,
+	.trigger   = pcxhr_trigger,
+	.pointer   = pcxhr_stream_pointer,
+};
+
+/*
+ */
+int pcxhr_create_pcm(struct snd_pcxhr *chip)
+{
+	int err;
+	struct snd_pcm *pcm;
+	char name[32];
+
+	sprintf(name, "pcxhr %d", chip->chip_idx);
+	if ((err = snd_pcm_new(chip->card, name, 0,
+			       chip->nb_streams_play,
+			       chip->nb_streams_capt, &pcm)) < 0) {
+		snd_printk(KERN_ERR "cannot create pcm %s\n", name);
+		return err;
+	}
+	pcm->private_data = chip;
+
+	if (chip->nb_streams_play)
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pcxhr_ops);
+	if (chip->nb_streams_capt)
+		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pcxhr_ops);
+
+	pcm->info_flags = 0;
+	strcpy(pcm->name, name);
+
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+					      snd_dma_pci_data(chip->mgr->pci),
+					      32*1024, 32*1024);
+	chip->pcm = pcm;
+	return 0;
+}
+
+static int pcxhr_chip_free(struct snd_pcxhr *chip)
+{
+	kfree(chip);
+	return 0;
+}
+
+static int pcxhr_chip_dev_free(struct snd_device *device)
+{
+	struct snd_pcxhr *chip = device->device_data;
+	return pcxhr_chip_free(chip);
+}
+
+
+/*
+ */
+static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card, int idx)
+{
+	int err;
+	struct snd_pcxhr *chip;
+	static struct snd_device_ops ops = {
+		.dev_free = pcxhr_chip_dev_free,
+	};
+
+	mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+	if (! chip) {
+		snd_printk(KERN_ERR "cannot allocate chip\n");
+		return -ENOMEM;
+	}
+
+	chip->card = card;
+	chip->chip_idx = idx;
+	chip->mgr = mgr;
+
+	if (idx < mgr->playback_chips)
+		/* stereo or mono streams */
+		chip->nb_streams_play = PCXHR_PLAYBACK_STREAMS;
+
+	if (idx < mgr->capture_chips) {
+		if (mgr->mono_capture)
+			chip->nb_streams_capt = 2;	/* 2 mono streams (left+right) */
+		else
+			chip->nb_streams_capt = 1;	/* or 1 stereo stream */
+	}
+
+	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
+		pcxhr_chip_free(chip);
+		return err;
+	}
+
+	snd_card_set_dev(card, &mgr->pci->dev);
+
+	return 0;
+}
+
+/* proc interface */
+static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
+{
+	struct snd_pcxhr *chip = entry->private_data;
+	struct pcxhr_mgr *mgr = chip->mgr;
+
+	snd_iprintf(buffer, "\n%s\n", mgr->longname);
+
+	/* stats available when embedded DSP is running */
+	if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
+		struct pcxhr_rmh rmh;
+		short ver_maj = (mgr->dsp_version >> 16) & 0xff;
+		short ver_min = (mgr->dsp_version >> 8) & 0xff;
+		short ver_build = mgr->dsp_version & 0xff;
+		snd_iprintf(buffer, "module version %s\n", PCXHR_DRIVER_VERSION_STRING);
+		snd_iprintf(buffer, "dsp version %d.%d.%d\n", ver_maj, ver_min, ver_build);
+		if (mgr->board_has_analog)
+			snd_iprintf(buffer, "analog io available\n");
+		else
+			snd_iprintf(buffer, "digital only board\n");
+
+		/* calc cpu load of the dsp */
+		pcxhr_init_rmh(&rmh, CMD_GET_DSP_RESOURCES);
+		if( ! pcxhr_send_msg(mgr, &rmh) ) {
+			int cur = rmh.stat[0];
+			int ref = rmh.stat[1];
+			if (ref > 0) {
+				if (mgr->sample_rate_real != 0 &&
+				    mgr->sample_rate_real != 48000) {
+					ref = (ref * 48000) / mgr->sample_rate_real;
+					if (mgr->sample_rate_real >= PCXHR_IRQ_TIMER_FREQ)
+						ref *= 2;
+				}
+				cur = 100 - (100 * cur) / ref;
+				snd_iprintf(buffer, "cpu load    %d%%\n", cur);
+				snd_iprintf(buffer, "buffer pool %d/%d kWords\n",
+					    rmh.stat[2], rmh.stat[3]);
+			}
+		}
+		snd_iprintf(buffer, "dma granularity : %d\n", PCXHR_GRANULARITY);
+		snd_iprintf(buffer, "dsp time errors : %d\n", mgr->dsp_time_err);
+		snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n",
+			    mgr->async_err_pipe_xrun);
+		snd_iprintf(buffer, "dsp async stream xrun errors : %d\n",
+			    mgr->async_err_stream_xrun);
+		snd_iprintf(buffer, "dsp async last other error : %x\n",
+			    mgr->async_err_other_last);
+		/* debug zone dsp */
+		rmh.cmd[0] = 0x4200 + PCXHR_SIZE_MAX_STATUS;
+		rmh.cmd_len = 1;
+		rmh.stat_len = PCXHR_SIZE_MAX_STATUS;
+		rmh.dsp_stat = 0;
+		rmh.cmd_idx = CMD_LAST_INDEX;
+		if( ! pcxhr_send_msg(mgr, &rmh) ) {
+			int i;
+			for (i = 0; i < rmh.stat_len; i++)
+				snd_iprintf(buffer, "debug[%02d] = %06x\n", i,  rmh.stat[i]);
+		}
+	} else
+		snd_iprintf(buffer, "no firmware loaded\n");
+	snd_iprintf(buffer, "\n");
+}
+static void pcxhr_proc_sync(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
+{
+	struct snd_pcxhr *chip = entry->private_data;
+	struct pcxhr_mgr *mgr = chip->mgr;
+	static char *texts[7] = {
+		"Internal", "Word", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4"
+	};
+
+	snd_iprintf(buffer, "\n%s\n", mgr->longname);
+	snd_iprintf(buffer, "Current Sample Clock\t: %s\n", texts[mgr->cur_clock_type]);
+	snd_iprintf(buffer, "Current Sample Rate\t= %d\n", mgr->sample_rate_real);
+
+	/* commands available when embedded DSP is running */
+	if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
+		int i, err, sample_rate;
+		for (i = PCXHR_CLOCK_TYPE_WORD_CLOCK; i< (3 + mgr->capture_chips); i++) {
+			err = pcxhr_get_external_clock(mgr, i, &sample_rate);
+			if (err)
+				break;
+			snd_iprintf(buffer, "%s Clock\t\t= %d\n", texts[i], sample_rate);
+		}
+	} else
+		snd_iprintf(buffer, "no firmware loaded\n");
+	snd_iprintf(buffer, "\n");
+}
+
+static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
+{
+	struct snd_info_entry *entry;
+
+	if (! snd_card_proc_new(chip->card, "info", &entry))
+		snd_info_set_text_ops(entry, chip, 1024, pcxhr_proc_info);
+	if (! snd_card_proc_new(chip->card, "sync", &entry))
+		snd_info_set_text_ops(entry, chip, 1024, pcxhr_proc_sync);
+}
+/* end of proc interface */
+
+/*
+ * release all the cards assigned to a manager instance
+ */
+static int pcxhr_free(struct pcxhr_mgr *mgr)
+{
+	unsigned int i;
+
+	for (i = 0; i < mgr->num_cards; i++) {
+		if (mgr->chip[i])
+			snd_card_free(mgr->chip[i]->card);
+	}
+
+	/* reset board if some firmware was loaded */
+	if(mgr->dsp_loaded) {
+		pcxhr_reset_board(mgr);
+		snd_printdd("reset pcxhr !\n");
+	}
+
+	/* release irq  */
+	if (mgr->irq >= 0)
+		free_irq(mgr->irq, mgr);
+
+	pci_release_regions(mgr->pci);
+
+	/* free hostport purgebuffer */
+	if (mgr->hostport.area) {
+		snd_dma_free_pages(&mgr->hostport);
+		mgr->hostport.area = NULL;
+	}
+
+	kfree(mgr->prmh);
+
+	pci_disable_device(mgr->pci);
+	kfree(mgr);
+	return 0;
+}
+
+/*
+ *    probe function - creates the card manager
+ */
+static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+{
+	static int dev;
+	struct pcxhr_mgr *mgr;
+	unsigned int i;
+	int err;
+	size_t size;
+	char *card_name;
+
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (! enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	/* enable PCI device */
+	if ((err = pci_enable_device(pci)) < 0)
+		return err;
+	pci_set_master(pci);
+
+	/* check if we can restrict PCI DMA transfers to 32 bits */
+	if (pci_set_dma_mask(pci, 0xffffffff) < 0) {
+		snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n");
+		pci_disable_device(pci);
+		return -ENXIO;
+	}
+
+	/* alloc card manager */
+	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
+	if (! mgr) {
+		pci_disable_device(pci);
+		return -ENOMEM;
+	}
+
+	snd_assert(pci_id->driver_data < PCI_ID_LAST, return -ENODEV);
+	card_name = pcxhr_board_params[pci_id->driver_data].board_name;
+	mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips;
+	mgr->capture_chips  = pcxhr_board_params[pci_id->driver_data].capture_chips;
+	mgr->firmware_num  = pcxhr_board_params[pci_id->driver_data].firmware_num;
+	mgr->mono_capture = mono[dev];
+
+	/* resource assignment */
+	if ((err = pci_request_regions(pci, card_name)) < 0) {
+		kfree(mgr);
+		pci_disable_device(pci);
+		return err;
+	}
+	for (i = 0; i < 3; i++)
+		mgr->port[i] = pci_resource_start(pci, i);
+
+	mgr->pci = pci;
+	mgr->irq = -1;
+
+	if (request_irq(pci->irq, pcxhr_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			card_name, mgr)) {
+		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
+		pcxhr_free(mgr);
+		return -EBUSY;
+	}
+	mgr->irq = pci->irq;
+
+	sprintf(mgr->shortname, "Digigram %s", card_name);
+	sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i", mgr->shortname,
+		mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);
+
+	/* ISR spinlock  */
+	spin_lock_init(&mgr->lock);
+	spin_lock_init(&mgr->msg_lock);
+
+	/* init setup mutex*/
+	init_MUTEX(&mgr->setup_mutex);
+
+	/* init taslket */
+	tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet, (unsigned long) mgr);
+	tasklet_init(&mgr->trigger_taskq, pcxhr_trigger_tasklet, (unsigned long) mgr);
+	mgr->prmh = kmalloc(sizeof(*mgr->prmh) + 
+			    sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS - PCXHR_SIZE_MAX_STATUS),
+			    GFP_KERNEL);
+	if (! mgr->prmh) {
+		pcxhr_free(mgr);
+		return -ENOMEM;
+	}
+
+	for (i=0; i < PCXHR_MAX_CARDS; i++) {
+		struct snd_card *card;
+		char tmpid[16];
+		int idx;
+
+		if (i >= max(mgr->playback_chips, mgr->capture_chips))
+			break;
+		mgr->num_cards++;
+
+		if (index[dev] < 0)
+			idx = index[dev];
+		else
+			idx = index[dev] + i;
+
+		snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : card_name, i);
+		card = snd_card_new(idx, tmpid, THIS_MODULE, 0);
+
+		if (! card) {
+			snd_printk(KERN_ERR "cannot allocate the card %d\n", i);
+			pcxhr_free(mgr);
+			return -ENOMEM;
+		}
+
+		strcpy(card->driver, DRIVER_NAME);
+		sprintf(card->shortname, "%s [PCM #%d]", mgr->shortname, i);
+		sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
+
+		if ((err = pcxhr_create(mgr, card, i)) < 0) {
+			pcxhr_free(mgr);
+			return err;
+		}
+
+		if (i == 0)
+			/* init proc interface only for chip0 */
+			pcxhr_proc_init(mgr->chip[i]);
+
+		if ((err = snd_card_register(card)) < 0) {
+			pcxhr_free(mgr);
+			return err;
+		}
+	}
+
+	/* create hostport purgebuffer */
+	size = PAGE_ALIGN(sizeof(struct pcxhr_hostport));
+	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
+				size, &mgr->hostport) < 0) {
+		pcxhr_free(mgr);
+		return -ENOMEM;
+	}
+	/* init purgebuffer */
+	memset(mgr->hostport.area, 0, size);
+
+	/* create a DSP loader */
+	err = pcxhr_setup_firmware(mgr);
+	if (err < 0) {
+		pcxhr_free(mgr);
+		return err;
+	}
+
+	pci_set_drvdata(pci, mgr);
+	dev++;
+	return 0;
+}
+
+static void __devexit pcxhr_remove(struct pci_dev *pci)
+{
+	pcxhr_free(pci_get_drvdata(pci));
+	pci_set_drvdata(pci, NULL);
+}
+
+static struct pci_driver driver = {
+	.name = "Digigram pcxhr",
+	.id_table = pcxhr_ids,
+	.probe = pcxhr_probe,
+	.remove = __devexit_p(pcxhr_remove),
+};
+
+static int __init pcxhr_module_init(void)
+{
+	return pci_register_driver(&driver);
+}
+
+static void __exit pcxhr_module_exit(void)
+{
+	pci_unregister_driver(&driver);
+}
+
+module_init(pcxhr_module_init)
+module_exit(pcxhr_module_exit)
diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h
new file mode 100644
index 0000000..049f2b3
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr.h
@@ -0,0 +1,188 @@
+/*
+ * Driver for Digigram pcxhr soundcards
+ *
+ * main header file
+ *
+ * Copyright (c) 2004 by Digigram <alsa@digigram.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 __SOUND_PCXHR_H
+#define __SOUND_PCXHR_H
+
+#include <linux/interrupt.h>
+#include <sound/pcm.h>
+
+#define PCXHR_DRIVER_VERSION		0x000804	/* 0.8.4 */
+#define PCXHR_DRIVER_VERSION_STRING	"0.8.4"		/* 0.8.4 */
+
+
+#define PCXHR_MAX_CARDS			6
+#define PCXHR_PLAYBACK_STREAMS		4
+
+#define PCXHR_GRANULARITY		96	/* transfer granularity (should be min 96 and multiple of 48) */
+#define PCXHR_GRANULARITY_MIN		96	/* transfer granularity of pipes and the dsp time (MBOX4) */
+
+struct snd_pcxhr;
+struct pcxhr_mgr;
+
+struct pcxhr_stream;
+struct pcxhr_pipe;
+
+enum pcxhr_clock_type {
+	PCXHR_CLOCK_TYPE_INTERNAL = 0,
+	PCXHR_CLOCK_TYPE_WORD_CLOCK,
+	PCXHR_CLOCK_TYPE_AES_SYNC,
+	PCXHR_CLOCK_TYPE_AES_1,
+	PCXHR_CLOCK_TYPE_AES_2,
+	PCXHR_CLOCK_TYPE_AES_3,
+	PCXHR_CLOCK_TYPE_AES_4,
+};
+
+struct pcxhr_mgr {
+	unsigned int num_cards;
+	struct snd_pcxhr *chip[PCXHR_MAX_CARDS];
+
+	struct pci_dev *pci;
+
+	int irq;
+
+	/* card access with 1 mem bar and 2 io bar's */
+	unsigned long port[3];
+
+	/* share the name */
+	char shortname[32];		/* short name of this soundcard */
+	char longname[96];		/* name of this soundcard */
+
+	/* message tasklet */
+	struct tasklet_struct msg_taskq;
+	struct pcxhr_rmh *prmh;
+	/* trigger tasklet */
+	struct tasklet_struct trigger_taskq;
+
+	spinlock_t lock;		/* interrupt spinlock */
+	spinlock_t msg_lock;		/* message spinlock */
+
+	struct semaphore setup_mutex;	/* mutex used in hw_params, open and close */
+	struct semaphore mixer_mutex;	/* mutex for mixer */
+
+	/* hardware interface */
+	unsigned int dsp_loaded;	/* bit flags of loaded dsp indices */
+	unsigned int dsp_version;	/* read from embedded once firmware is loaded */
+	int board_has_analog;		/* if 0 the board is digital only */
+	int mono_capture;		/* if 1 the board does mono capture */
+	int playback_chips;		/* 4 or 6 */
+	int capture_chips;		/* 4 or 1 */
+	int firmware_num;		/* 41 or 42 */
+
+	struct snd_dma_buffer hostport;
+
+	enum pcxhr_clock_type use_clock_type;	/* clock type selected by mixer */
+	enum pcxhr_clock_type cur_clock_type;	/* current clock type synced */
+	int sample_rate;
+	int ref_count_rate;
+	int timer_toggle;		/* timer interrupt toggles between the two values 0x200 and 0x300 */
+	int dsp_time_last;		/* the last dsp time (read by interrupt) */
+	int dsp_time_err;		/* dsp time errors */
+	unsigned int src_it_dsp;	/* dsp interrupt source */
+	unsigned int io_num_reg_cont;	/* backup of IO_NUM_REG_CONT */
+	unsigned int codec_speed;	/* speed mode of the codecs */
+	unsigned int sample_rate_real;	/* current real sample rate */
+	int last_reg_stat;
+	int async_err_stream_xrun;
+	int async_err_pipe_xrun;
+	int async_err_other_last;
+};
+
+
+enum pcxhr_stream_status {
+	PCXHR_STREAM_STATUS_FREE,
+	PCXHR_STREAM_STATUS_OPEN,
+	PCXHR_STREAM_STATUS_SCHEDULE_RUN,
+	PCXHR_STREAM_STATUS_STARTED,
+	PCXHR_STREAM_STATUS_RUNNING,
+	PCXHR_STREAM_STATUS_SCHEDULE_STOP,
+	PCXHR_STREAM_STATUS_STOPPED,
+	PCXHR_STREAM_STATUS_PAUSED
+};
+
+struct pcxhr_stream {
+	struct snd_pcm_substream *substream;
+	snd_pcm_format_t format;
+	struct pcxhr_pipe *pipe;
+
+	enum pcxhr_stream_status status;	/* free, open, running, draining, pause */
+
+	u_int64_t timer_abs_periods;	/* timer: samples elapsed since TRIGGER_START (multiple of period_size) */
+	u_int32_t timer_period_frag;	/* timer: samples elapsed since last call to snd_pcm_period_elapsed (0..period_size) */
+	u_int32_t timer_buf_periods;	/* nb of periods in the buffer that have already elapsed */
+	int timer_is_synced;		/* if(0) : timer needs to be resynced with real hardware pointer */
+
+	int channels;
+};
+
+
+enum pcxhr_pipe_status {
+	PCXHR_PIPE_UNDEFINED,
+	PCXHR_PIPE_DEFINED
+};
+
+struct pcxhr_pipe {
+	enum pcxhr_pipe_status status;
+	int is_capture;		/* this is a capture pipe */
+	int first_audio;	/* first audio num */
+};
+
+
+struct snd_pcxhr {
+	struct snd_card *card;
+	struct pcxhr_mgr *mgr;
+	int chip_idx;		/* zero based */
+
+	struct snd_pcm *pcm;		/* PCM */
+
+	struct pcxhr_pipe playback_pipe;		/* 1 stereo pipe only */
+	struct pcxhr_pipe capture_pipe[2];		/* 1 stereo pipe or 2 mono pipes */
+
+	struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS];
+	struct pcxhr_stream capture_stream[2];	/* 1 stereo stream or 2 mono streams */
+	int nb_streams_play;
+	int nb_streams_capt;
+
+	int analog_playback_active[2];		/* Mixer : Master Playback active (!mute) */
+	int analog_playback_volume[2];		/* Mixer : Master Playback Volume */
+	int analog_capture_volume[2];		/* Mixer : Master Capture Volume */
+	int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2];	/* Mixer : Digital Playback Active [streams][stereo]*/
+	int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2];	/* Mixer : Digital Playback Volume [streams][stereo]*/
+	int digital_capture_volume[2];		/* Mixer : Digital Capture Volume [stereo] */
+	int monitoring_active[2];		/* Mixer : Monitoring Active */
+	int monitoring_volume[2];		/* Mixer : Monitoring Volume */
+	int audio_capture_source;		/* Mixer : Audio Capture Source */
+	unsigned char aes_bits[5];		/* Mixer : IEC958_AES bits */
+};
+
+struct pcxhr_hostport
+{
+	char purgebuffer[6];
+	char reserved[2];
+};
+
+/* exported */
+int pcxhr_create_pcm(struct snd_pcxhr *chip);
+int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate);
+int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_type, int *sample_rate);
+
+#endif /* __SOUND_PCXHR_H */
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
new file mode 100644
index 0000000..fa0d27e
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -0,0 +1,1214 @@
+/*
+ * Driver for Digigram pcxhr compatible soundcards
+ *
+ * low level interface with interrupt and message handling implementation
+ *
+ * Copyright (c) 2004 by Digigram <alsa@digigram.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 <sound/driver.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <sound/core.h>
+#include "pcxhr.h"
+#include "pcxhr_mixer.h"
+#include "pcxhr_hwdep.h"
+#include "pcxhr_core.h"
+
+
+/* registers used on the PLX (port 1) */
+#define PCXHR_PLX_OFFSET_MIN	0x40
+#define PCXHR_PLX_MBOX0		0x40
+#define PCXHR_PLX_MBOX1		0x44
+#define PCXHR_PLX_MBOX2		0x48
+#define PCXHR_PLX_MBOX3		0x4C
+#define PCXHR_PLX_MBOX4		0x50
+#define PCXHR_PLX_MBOX5		0x54
+#define PCXHR_PLX_MBOX6		0x58
+#define PCXHR_PLX_MBOX7		0x5C
+#define PCXHR_PLX_L2PCIDB	0x64
+#define PCXHR_PLX_IRQCS		0x68
+#define PCXHR_PLX_CHIPSC	0x6C
+
+/* registers used on the DSP (port 2) */
+#define PCXHR_DSP_ICR		0x00
+#define PCXHR_DSP_CVR		0x04
+#define PCXHR_DSP_ISR		0x08
+#define PCXHR_DSP_IVR		0x0C
+#define PCXHR_DSP_RXH		0x14
+#define PCXHR_DSP_TXH		0x14
+#define PCXHR_DSP_RXM		0x18
+#define PCXHR_DSP_TXM		0x18
+#define PCXHR_DSP_RXL		0x1C
+#define PCXHR_DSP_TXL		0x1C
+#define PCXHR_DSP_RESET		0x20
+#define PCXHR_DSP_OFFSET_MAX	0x20
+
+/* access to the card */
+#define PCXHR_PLX 1
+#define PCXHR_DSP 2
+
+#if (PCXHR_DSP_OFFSET_MAX > PCXHR_PLX_OFFSET_MIN)
+#undef  PCXHR_REG_TO_PORT(x)
+#else
+#define PCXHR_REG_TO_PORT(x)	((x)>PCXHR_DSP_OFFSET_MAX ? PCXHR_PLX : PCXHR_DSP)
+#endif
+#define PCXHR_INPB(mgr,x)	inb((mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
+#define PCXHR_INPL(mgr,x)	inl((mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
+#define PCXHR_OUTPB(mgr,x,data)	outb((data), (mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
+#define PCXHR_OUTPL(mgr,x,data)	outl((data), (mgr)->port[PCXHR_REG_TO_PORT(x)] + (x))
+/* attention : access the PCXHR_DSP_* registers with inb and outb only ! */
+
+/* params used with PCXHR_PLX_MBOX0 */
+#define PCXHR_MBOX0_HF5			(1 << 0)
+#define PCXHR_MBOX0_HF4			(1 << 1)
+#define PCXHR_MBOX0_BOOT_HERE		(1 << 23)
+/* params used with PCXHR_PLX_IRQCS */
+#define PCXHR_IRQCS_ENABLE_PCIIRQ	(1 << 8)
+#define PCXHR_IRQCS_ENABLE_PCIDB	(1 << 9)
+#define PCXHR_IRQCS_ACTIVE_PCIDB	(1 << 13)
+/* params used with PCXHR_PLX_CHIPSC */
+#define PCXHR_CHIPSC_INIT_VALUE		0x100D767E
+#define PCXHR_CHIPSC_RESET_XILINX	(1 << 16)
+#define PCXHR_CHIPSC_GPI_USERI		(1 << 17)
+#define PCXHR_CHIPSC_DATA_CLK		(1 << 24)
+#define PCXHR_CHIPSC_DATA_IN		(1 << 26)
+
+/* params used with PCXHR_DSP_ICR */
+#define PCXHR_ICR_HI08_RREQ		0x01
+#define PCXHR_ICR_HI08_TREQ		0x02
+#define PCXHR_ICR_HI08_HDRQ		0x04
+#define PCXHR_ICR_HI08_HF0		0x08
+#define PCXHR_ICR_HI08_HF1		0x10
+#define PCXHR_ICR_HI08_HLEND		0x20
+#define PCXHR_ICR_HI08_INIT		0x80
+/* params used with PCXHR_DSP_CVR */
+#define PCXHR_CVR_HI08_HC		0x80
+/* params used with PCXHR_DSP_ISR */
+#define PCXHR_ISR_HI08_RXDF		0x01
+#define PCXHR_ISR_HI08_TXDE		0x02
+#define PCXHR_ISR_HI08_TRDY		0x04
+#define PCXHR_ISR_HI08_ERR		0x08
+#define PCXHR_ISR_HI08_CHK		0x10
+#define PCXHR_ISR_HI08_HREQ		0x80
+
+
+/* constants used for delay in msec */
+#define PCXHR_WAIT_DEFAULT		2
+#define PCXHR_WAIT_IT			25
+#define PCXHR_WAIT_IT_EXTRA		65
+
+/*
+ * pcxhr_check_reg_bit - wait for the specified bit is set/reset on a register
+ * @reg: register to check
+ * @mask: bit mask
+ * @bit: resultant bit to be checked
+ * @time: time-out of loop in msec
+ *
+ * returns zero if a bit matches, or a negative error code.
+ */
+static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
+			       unsigned char mask, unsigned char bit, int time,
+			       unsigned char* read)
+{
+	int i = 0;
+	unsigned long end_time = jiffies + (time * HZ + 999) / 1000;
+	do {
+		*read = PCXHR_INPB(mgr, reg);
+		if ((*read & mask) == bit) {
+			if (i > 100)
+				snd_printdd("ATTENTION! check_reg(%x) loopcount=%d\n",
+					    reg, i);
+			return 0;
+		}
+		i++;
+	} while (time_after_eq(end_time, jiffies));
+	snd_printk(KERN_ERR "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=0x%x\n",
+		   reg, mask, *read);
+	return -EIO;
+}
+
+/* constants used with pcxhr_check_reg_bit() */
+#define PCXHR_TIMEOUT_DSP		200
+
+
+#define PCXHR_MASK_EXTRA_INFO		0x0000FE
+#define PCXHR_MASK_IT_HF0		0x000100
+#define PCXHR_MASK_IT_HF1		0x000200
+#define PCXHR_MASK_IT_NO_HF0_HF1	0x000400
+#define PCXHR_MASK_IT_MANAGE_HF5	0x000800
+#define PCXHR_MASK_IT_WAIT		0x010000
+#define PCXHR_MASK_IT_WAIT_EXTRA	0x020000
+
+#define PCXHR_IT_SEND_BYTE_XILINX	(0x0000003C | PCXHR_MASK_IT_HF0)
+#define PCXHR_IT_TEST_XILINX		(0x0000003C | PCXHR_MASK_IT_HF1 | \
+					 PCXHR_MASK_IT_MANAGE_HF5)
+#define PCXHR_IT_DOWNLOAD_BOOT		(0x0000000C | PCXHR_MASK_IT_HF1 | \
+					 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT)
+#define PCXHR_IT_RESET_BOARD_FUNC	(0x0000000C | PCXHR_MASK_IT_HF0 | \
+					 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT_EXTRA)
+#define PCXHR_IT_DOWNLOAD_DSP		(0x0000000C | \
+					 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT)
+#define PCXHR_IT_DEBUG			(0x0000005A | PCXHR_MASK_IT_NO_HF0_HF1)
+#define PCXHR_IT_RESET_SEMAPHORE	(0x0000005C | PCXHR_MASK_IT_NO_HF0_HF1)
+#define PCXHR_IT_MESSAGE		(0x00000074 | PCXHR_MASK_IT_NO_HF0_HF1)
+#define PCXHR_IT_RESET_CHK		(0x00000076 | PCXHR_MASK_IT_NO_HF0_HF1)
+#define PCXHR_IT_UPDATE_RBUFFER		(0x00000078 | PCXHR_MASK_IT_NO_HF0_HF1)
+
+static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atomic)
+{
+	int err;
+	unsigned char reg;
+
+	if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
+		/* clear hf5 bit */
+		PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0,
+			    PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & ~PCXHR_MBOX0_HF5);
+	}
+	if ((itdsp & PCXHR_MASK_IT_NO_HF0_HF1) == 0) {
+		reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ;
+		if (itdsp & PCXHR_MASK_IT_HF0)
+			reg |= PCXHR_ICR_HI08_HF0;
+		if (itdsp & PCXHR_MASK_IT_HF1)
+			reg |= PCXHR_ICR_HI08_HF1;
+		PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
+	}
+	reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) | PCXHR_CVR_HI08_HC);
+	PCXHR_OUTPB(mgr, PCXHR_DSP_CVR, reg);
+	if (itdsp & PCXHR_MASK_IT_WAIT) {
+		if (atomic)
+			mdelay(PCXHR_WAIT_IT);
+		else
+			msleep(PCXHR_WAIT_IT);
+	}
+	if (itdsp & PCXHR_MASK_IT_WAIT_EXTRA) {
+		if (atomic)
+			mdelay(PCXHR_WAIT_IT_EXTRA);
+		else
+			msleep(PCXHR_WAIT_IT);
+	}
+	/* wait for CVR_HI08_HC == 0 */
+	err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_CVR,  PCXHR_CVR_HI08_HC, 0,
+				  PCXHR_TIMEOUT_DSP, &reg);
+	if (err) {
+		snd_printk(KERN_ERR "pcxhr_send_it_dsp : TIMEOUT CVR\n");
+		return err;
+	}
+	if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
+		/* wait for hf5 bit */
+		err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0, PCXHR_MBOX0_HF5,
+					  PCXHR_MBOX0_HF5, PCXHR_TIMEOUT_DSP, &reg);
+		if (err) {
+			snd_printk(KERN_ERR "pcxhr_send_it_dsp : TIMEOUT HF5\n");
+			return err;
+		}
+	}
+	return 0; /* retry not handled here */
+}
+
+void pcxhr_reset_xilinx_com(struct pcxhr_mgr *mgr)
+{
+	/* reset second xilinx */
+	PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC,
+		    PCXHR_CHIPSC_INIT_VALUE & ~PCXHR_CHIPSC_RESET_XILINX);
+}
+
+static void pcxhr_enable_irq(struct pcxhr_mgr *mgr, int enable)
+{
+	unsigned int reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS);
+	/* enable/disable interrupts */
+	if (enable)
+		reg |=  (PCXHR_IRQCS_ENABLE_PCIIRQ | PCXHR_IRQCS_ENABLE_PCIDB);
+	else
+		reg &= ~(PCXHR_IRQCS_ENABLE_PCIIRQ | PCXHR_IRQCS_ENABLE_PCIDB);
+	PCXHR_OUTPL(mgr, PCXHR_PLX_IRQCS, reg);
+}
+
+void pcxhr_reset_dsp(struct pcxhr_mgr *mgr)
+{
+	/* disable interrupts */
+	pcxhr_enable_irq(mgr, 0);
+
+	/* let's reset the DSP */
+	PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, 0);
+	msleep( PCXHR_WAIT_DEFAULT ); /* wait 2 msec */
+	PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, 3);
+	msleep( PCXHR_WAIT_DEFAULT ); /* wait 2 msec */
+
+	/* reset mailbox */
+	PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0, 0);
+}
+
+void pcxhr_enable_dsp(struct pcxhr_mgr *mgr)
+{
+	/* enable interrupts */
+	pcxhr_enable_irq(mgr, 1);
+}
+
+/*
+ * load the xilinx image
+ */
+int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilinx, int second)
+{
+	unsigned int i;
+	unsigned int chipsc;
+	unsigned char data;
+	unsigned char mask;
+	unsigned char *image;
+
+	/* test first xilinx */
+	chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC);
+	if (!second) {
+		if (chipsc & PCXHR_CHIPSC_GPI_USERI) {
+			snd_printdd("no need to load first xilinx\n");
+			return 0; /* first xilinx is already present and cannot be reset */
+		}
+	} else {
+		if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) {
+			snd_printk(KERN_ERR "error loading first xilinx\n");
+			return -EINVAL;
+		}
+		/* activate second xilinx */
+		chipsc |= PCXHR_CHIPSC_RESET_XILINX;
+		PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
+		msleep( PCXHR_WAIT_DEFAULT ); /* wait 2 msec */
+	}
+	image = xilinx->data;
+	for (i = 0; i < xilinx->size; i++, image++) {
+		data = *image;
+		mask = 0x80;
+		while (mask) {
+			chipsc &= ~(PCXHR_CHIPSC_DATA_CLK | PCXHR_CHIPSC_DATA_IN);
+			if (data & mask)
+				chipsc |= PCXHR_CHIPSC_DATA_IN;
+			PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
+			chipsc |= PCXHR_CHIPSC_DATA_CLK;
+			PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
+			mask >>= 1;
+		}
+		/* don't take too much time in this loop... */
+		cond_resched();
+	}
+	chipsc &= ~(PCXHR_CHIPSC_DATA_CLK | PCXHR_CHIPSC_DATA_IN);
+	PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
+	/* wait 2 msec (time to boot the xilinx before any access) */
+	msleep( PCXHR_WAIT_DEFAULT );
+	return 0;
+}
+
+/*
+ * send an executable file to the DSP
+ */
+static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
+{
+	int err;
+	unsigned int i;
+	unsigned int len;
+	unsigned char *data;
+	unsigned char dummy;
+	/* check the length of boot image */
+	snd_assert(dsp->size > 0, return -EINVAL);
+	snd_assert(dsp->size % 3 == 0, return -EINVAL);
+	snd_assert(dsp->data, return -EINVAL);
+	/* transfert data buffer from PC to DSP */
+	for (i = 0; i < dsp->size; i += 3) {
+		data = dsp->data + i;
+		if (i == 0) {
+			/* test data header consistency */
+			len = (unsigned int)((data[0]<<16) + (data[1]<<8) + data[2]);
+			snd_assert((len==0) || (dsp->size == (len+2)*3), return -EINVAL);
+		}
+		/* wait DSP ready for new transfer */
+		err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
+					  PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &dummy);
+		if (err) {
+			snd_printk(KERN_ERR "dsp loading error at position %d\n", i);
+			return err;
+		}
+		/* send host data */
+		PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, data[0]);
+		PCXHR_OUTPB(mgr, PCXHR_DSP_TXM, data[1]);
+		PCXHR_OUTPB(mgr, PCXHR_DSP_TXL, data[2]);
+
+		/* don't take too much time in this loop... */
+		cond_resched();
+	}
+	/* give some time to boot the DSP */
+	msleep(PCXHR_WAIT_DEFAULT);
+	return 0;
+}
+
+/*
+ * load the eeprom image
+ */
+int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eeprom)
+{
+	int err;
+	unsigned char reg;
+
+	/* init value of the ICR register */
+	reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ;
+	if (PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & PCXHR_MBOX0_BOOT_HERE) {
+		/* no need to load the eeprom binary, but init the HI08 interface */
+		PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg | PCXHR_ICR_HI08_INIT);
+		msleep(PCXHR_WAIT_DEFAULT);
+		PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
+		msleep(PCXHR_WAIT_DEFAULT);
+		snd_printdd("no need to load eeprom boot\n");
+		return 0;
+	}
+	PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
+
+	err = pcxhr_download_dsp(mgr, eeprom);
+	if (err)
+		return err;
+	/* wait for chk bit */
+	return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK,
+				   PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &reg);
+}
+
+/*
+ * load the boot image
+ */
+int pcxhr_load_boot_binary(struct pcxhr_mgr *mgr, const struct firmware *boot)
+{
+	int err;
+	unsigned int physaddr = mgr->hostport.addr;
+	unsigned char dummy;
+
+	/* send the hostport address to the DSP (only the upper 24 bit !) */
+	snd_assert((physaddr & 0xff) == 0, return -EINVAL);
+	PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX1, (physaddr >> 8));
+
+	err = pcxhr_send_it_dsp(mgr, PCXHR_IT_DOWNLOAD_BOOT, 0);
+	if (err)
+		return err;
+	/* clear hf5 bit */
+	PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0,
+		    PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & ~PCXHR_MBOX0_HF5);
+
+	err = pcxhr_download_dsp(mgr, boot);
+	if (err)
+		return err;
+	/* wait for hf5 bit */
+	return pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0, PCXHR_MBOX0_HF5,
+				   PCXHR_MBOX0_HF5, PCXHR_TIMEOUT_DSP, &dummy);
+}
+
+/*
+ * load the final dsp image
+ */
+int pcxhr_load_dsp_binary(struct pcxhr_mgr *mgr, const struct firmware *dsp)
+{
+	int err;
+	unsigned char dummy;
+	err = pcxhr_send_it_dsp(mgr, PCXHR_IT_RESET_BOARD_FUNC, 0);
+	if (err)
+		return err;
+	err = pcxhr_send_it_dsp(mgr, PCXHR_IT_DOWNLOAD_DSP, 0);
+	if (err)
+		return err;
+	err = pcxhr_download_dsp(mgr, dsp);
+	if (err)
+		return err;
+	/* wait for chk bit */
+	return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK,
+				   PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &dummy);
+}
+
+
+struct pcxhr_cmd_info {
+	u32 opcode;		/* command word */
+	u16 st_length;		/* status length */
+	u16 st_type;		/* status type (RMH_SSIZE_XXX) */
+};
+
+/* RMH status type */
+enum {
+	RMH_SSIZE_FIXED = 0,	/* status size fix (st_length = 0..x) */
+	RMH_SSIZE_ARG = 1,	/* status size given in the LSB byte (used with st_length = 1) */
+	RMH_SSIZE_MASK = 2,	/* status size given in bitmask  (used with st_length = 1) */
+};
+
+/*
+ * Array of DSP commands
+ */
+static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
+[CMD_VERSION] =				{ 0x010000, 1, RMH_SSIZE_FIXED },
+[CMD_SUPPORTED] =			{ 0x020000, 4, RMH_SSIZE_FIXED },
+[CMD_TEST_IT] =				{ 0x040000, 1, RMH_SSIZE_FIXED },
+[CMD_SEND_IRQA] =			{ 0x070001, 0, RMH_SSIZE_FIXED },
+[CMD_ACCESS_IO_WRITE] =			{ 0x090000, 1, RMH_SSIZE_ARG },
+[CMD_ACCESS_IO_READ] =			{ 0x094000, 1, RMH_SSIZE_ARG },
+[CMD_ASYNC] =				{ 0x0a0000, 1, RMH_SSIZE_ARG },
+[CMD_MODIFY_CLOCK] =			{ 0x0d0000, 0, RMH_SSIZE_FIXED },
+[CMD_RESYNC_AUDIO_INPUTS] =		{ 0x0e0000, 0, RMH_SSIZE_FIXED },
+[CMD_GET_DSP_RESOURCES] =		{ 0x100000, 4, RMH_SSIZE_FIXED },
+[CMD_SET_TIMER_INTERRUPT] =		{ 0x110000, 0, RMH_SSIZE_FIXED },
+[CMD_RES_PIPE] =			{ 0x400000, 0, RMH_SSIZE_FIXED },
+[CMD_FREE_PIPE] =			{ 0x410000, 0, RMH_SSIZE_FIXED },
+[CMD_CONF_PIPE] =			{ 0x422101, 0, RMH_SSIZE_FIXED },
+[CMD_STOP_PIPE] =			{ 0x470004, 0, RMH_SSIZE_FIXED },
+[CMD_PIPE_SAMPLE_COUNT] =		{ 0x49a000, 2, RMH_SSIZE_FIXED },
+[CMD_CAN_START_PIPE] =			{ 0x4b0000, 1, RMH_SSIZE_FIXED },
+[CMD_START_STREAM] =			{ 0x802000, 0, RMH_SSIZE_FIXED },
+[CMD_STREAM_OUT_LEVEL_ADJUST] =		{ 0x822000, 0, RMH_SSIZE_FIXED },
+[CMD_STOP_STREAM] =			{ 0x832000, 0, RMH_SSIZE_FIXED },
+[CMD_UPDATE_R_BUFFERS] =		{ 0x840000, 0, RMH_SSIZE_FIXED },
+[CMD_FORMAT_STREAM_OUT] =		{ 0x860000, 0, RMH_SSIZE_FIXED },
+[CMD_FORMAT_STREAM_IN] =		{ 0x870000, 0, RMH_SSIZE_FIXED },
+[CMD_STREAM_SAMPLE_COUNT] =		{ 0x902000, 2, RMH_SSIZE_FIXED },	/* stat_len = nb_streams * 2 */
+[CMD_AUDIO_LEVEL_ADJUST] =		{ 0xc22000, 0, RMH_SSIZE_FIXED },
+};
+
+#ifdef CONFIG_SND_DEBUG_DETECT
+static char* cmd_names[] = {
+[CMD_VERSION] =				"CMD_VERSION",
+[CMD_SUPPORTED] =			"CMD_SUPPORTED",
+[CMD_TEST_IT] =				"CMD_TEST_IT",
+[CMD_SEND_IRQA] =			"CMD_SEND_IRQA",
+[CMD_ACCESS_IO_WRITE] =			"CMD_ACCESS_IO_WRITE",
+[CMD_ACCESS_IO_READ] =			"CMD_ACCESS_IO_READ",
+[CMD_ASYNC] =				"CMD_ASYNC",
+[CMD_MODIFY_CLOCK] =			"CMD_MODIFY_CLOCK",
+[CMD_RESYNC_AUDIO_INPUTS] =		"CMD_RESYNC_AUDIO_INPUTS",
+[CMD_GET_DSP_RESOURCES] =		"CMD_GET_DSP_RESOURCES",
+[CMD_SET_TIMER_INTERRUPT] =		"CMD_SET_TIMER_INTERRUPT",
+[CMD_RES_PIPE] =			"CMD_RES_PIPE",
+[CMD_FREE_PIPE] =			"CMD_FREE_PIPE",
+[CMD_CONF_PIPE] =			"CMD_CONF_PIPE",
+[CMD_STOP_PIPE] =			"CMD_STOP_PIPE",
+[CMD_PIPE_SAMPLE_COUNT] =		"CMD_PIPE_SAMPLE_COUNT",
+[CMD_CAN_START_PIPE] =			"CMD_CAN_START_PIPE",
+[CMD_START_STREAM] =			"CMD_START_STREAM",
+[CMD_STREAM_OUT_LEVEL_ADJUST] =		"CMD_STREAM_OUT_LEVEL_ADJUST",
+[CMD_STOP_STREAM] =			"CMD_STOP_STREAM",
+[CMD_UPDATE_R_BUFFERS] =		"CMD_UPDATE_R_BUFFERS",
+[CMD_FORMAT_STREAM_OUT] =		"CMD_FORMAT_STREAM_OUT",
+[CMD_FORMAT_STREAM_IN] =		"CMD_FORMAT_STREAM_IN",
+[CMD_STREAM_SAMPLE_COUNT] =		"CMD_STREAM_SAMPLE_COUNT",
+[CMD_AUDIO_LEVEL_ADJUST] =		"CMD_AUDIO_LEVEL_ADJUST",
+};
+#endif
+
+
+static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
+{
+	int err;
+	int i;
+	u32 data;
+	u32 size_mask;
+	unsigned char reg;
+	int max_stat_len;
+
+	if (rmh->stat_len < PCXHR_SIZE_MAX_STATUS)
+		max_stat_len = PCXHR_SIZE_MAX_STATUS;
+	else	max_stat_len = rmh->stat_len;
+
+	for (i = 0; i < rmh->stat_len; i++) {
+		/* wait for receiver full */
+		err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF,
+					  PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, &reg);
+		if (err) {
+			snd_printk(KERN_ERR "ERROR RMH stat: ISR:RXDF=1 (ISR = %x; i=%d )\n",
+				   reg, i);
+			return err;
+		}
+		/* read data */
+		data  = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16;
+		data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8;
+		data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
+
+		/* need to update rmh->stat_len on the fly ?? */
+		if (i==0) {
+			if (rmh->dsp_stat != RMH_SSIZE_FIXED) {
+				if (rmh->dsp_stat == RMH_SSIZE_ARG) {
+					rmh->stat_len = (u16)(data & 0x0000ff) + 1;
+					data &= 0xffff00;
+				} else {
+					/* rmh->dsp_stat == RMH_SSIZE_MASK */
+					rmh->stat_len = 1;
+					size_mask = data;
+					while (size_mask) {
+						if (size_mask & 1)
+							rmh->stat_len++;
+						size_mask >>= 1;
+					}
+				}
+			}
+		}
+#ifdef CONFIG_SND_DEBUG_DETECT
+		if (rmh->cmd_idx < CMD_LAST_INDEX)
+			snd_printdd("    stat[%d]=%x\n", i, data);
+#endif
+		if (i < max_stat_len)
+			rmh->stat[i] = data;
+	}
+	if (rmh->stat_len > max_stat_len) {
+		snd_printdd("PCXHR : rmh->stat_len=%x too big\n", rmh->stat_len);
+		rmh->stat_len = max_stat_len;
+	}
+	return 0;
+}
+
+static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
+{
+	int err;
+	int i;
+	u32 data;
+	unsigned char reg;
+
+	snd_assert(rmh->cmd_len<PCXHR_SIZE_MAX_CMD, return -EINVAL);
+	err = pcxhr_send_it_dsp(mgr, PCXHR_IT_MESSAGE, 1);
+	if (err) {
+		snd_printk(KERN_ERR "pcxhr_send_message : ED_DSP_CRASHED\n");
+		return err;
+	}
+	/* wait for chk bit */
+	err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK,
+				  PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &reg);
+	if (err)
+		return err;
+	/* reset irq chk */
+	err = pcxhr_send_it_dsp(mgr, PCXHR_IT_RESET_CHK, 1);
+	if (err)
+		return err;
+	/* wait for chk bit == 0*/
+	err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK, 0,
+				  PCXHR_TIMEOUT_DSP, &reg);
+	if (err)
+		return err;
+
+	data = rmh->cmd[0];
+
+	if (rmh->cmd_len > 1)
+		data |= 0x008000;	/* MASK_MORE_THAN_1_WORD_COMMAND */
+	else
+		data &= 0xff7fff;	/* MASK_1_WORD_COMMAND */
+#ifdef CONFIG_SND_DEBUG_DETECT
+	if (rmh->cmd_idx < CMD_LAST_INDEX)
+		snd_printdd("MSG cmd[0]=%x (%s)\n", data, cmd_names[rmh->cmd_idx]);
+#endif
+
+	err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
+				  PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &reg);
+	if (err)
+		return err;
+	PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
+	PCXHR_OUTPB(mgr, PCXHR_DSP_TXM, (data>>8)&0xFF);
+	PCXHR_OUTPB(mgr, PCXHR_DSP_TXL, (data&0xFF));
+
+	if (rmh->cmd_len > 1) {
+		/* send length */
+		data = rmh->cmd_len - 1;
+		err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
+					  PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &reg);
+		if (err)
+			return err;
+		PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
+		PCXHR_OUTPB(mgr, PCXHR_DSP_TXM, (data>>8)&0xFF);
+		PCXHR_OUTPB(mgr, PCXHR_DSP_TXL, (data&0xFF));
+
+		for (i=1; i < rmh->cmd_len; i++) {
+			/* send other words */
+			data = rmh->cmd[i];
+#ifdef CONFIG_SND_DEBUG_DETECT
+			if (rmh->cmd_idx < CMD_LAST_INDEX)
+				snd_printdd("    cmd[%d]=%x\n", i, data);
+#endif
+			err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
+						  PCXHR_ISR_HI08_TRDY,
+						  PCXHR_ISR_HI08_TRDY,
+						  PCXHR_TIMEOUT_DSP, &reg);
+			if (err)
+				return err;
+			PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
+			PCXHR_OUTPB(mgr, PCXHR_DSP_TXM, (data>>8)&0xFF);
+			PCXHR_OUTPB(mgr, PCXHR_DSP_TXL, (data&0xFF));
+		}
+	}
+	/* wait for chk bit */
+	err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK,
+				  PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &reg);
+	if (err)
+		return err;
+	/* test status ISR */
+	if (reg & PCXHR_ISR_HI08_ERR) {
+		/* ERROR, wait for receiver full */
+		err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF,
+					  PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, &reg);
+		if (err) {
+			snd_printk(KERN_ERR "ERROR RMH: ISR:RXDF=1 (ISR = %x)\n", reg);
+			return err;
+		}
+		/* read error code */
+		data  = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16;
+		data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8;
+		data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
+		snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n", rmh->cmd_idx, data);
+		err = -EINVAL;
+	} else {
+		/* read the response data */
+		err = pcxhr_read_rmh_status(mgr, rmh);
+	}
+	/* reset semaphore */
+	if (pcxhr_send_it_dsp(mgr, PCXHR_IT_RESET_SEMAPHORE, 1) < 0)
+		return -EIO;
+	return err;
+}
+
+
+/**
+ * pcxhr_init_rmh - initialize the RMH instance
+ * @rmh: the rmh pointer to be initialized
+ * @cmd: the rmh command to be set
+ */
+void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd)
+{
+	snd_assert(cmd < CMD_LAST_INDEX, return);
+	rmh->cmd[0] = pcxhr_dsp_cmds[cmd].opcode;
+	rmh->cmd_len = 1;
+	rmh->stat_len = pcxhr_dsp_cmds[cmd].st_length;
+	rmh->dsp_stat = pcxhr_dsp_cmds[cmd].st_type;
+	rmh->cmd_idx = cmd;
+}
+
+
+void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh *rmh, int capture,
+			       unsigned int param1, unsigned int param2,
+			       unsigned int param3)
+{
+	snd_assert(param1 <= MASK_FIRST_FIELD);
+	if (capture)
+		rmh->cmd[0] |= 0x800;		/* COMMAND_RECORD_MASK */
+	if (param1)
+		rmh->cmd[0] |= (param1 << FIELD_SIZE);
+	if (param2) {
+		snd_assert(param2 <= MASK_FIRST_FIELD);
+		rmh->cmd[0] |= param2;
+	}
+	if(param3) {
+		snd_assert(param3 <= MASK_DSP_WORD);
+		rmh->cmd[1] = param3;
+		rmh->cmd_len = 2;
+	}
+}
+
+/*
+ * pcxhr_send_msg - send a DSP message with spinlock
+ * @rmh: the rmh record to send and receive
+ *
+ * returns 0 if successful, or a negative error code.
+ */
+int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
+{
+	unsigned long flags;
+	int err;
+	spin_lock_irqsave(&mgr->msg_lock, flags);
+	err = pcxhr_send_msg_nolock(mgr, rmh);
+	spin_unlock_irqrestore(&mgr->msg_lock, flags);
+	return err;
+}
+
+static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
+{
+	int start_mask = PCXHR_INPL(mgr, PCXHR_PLX_MBOX2);
+	/* least segnificant 12 bits are the pipe states for the playback audios */
+	/* next 12 bits are the pipe states for the capture audios
+	 * (PCXHR_PIPE_STATE_CAPTURE_OFFSET)
+	 */
+	start_mask &= 0xffffff;
+	snd_printdd("CMD_PIPE_STATE MBOX2=0x%06x\n", start_mask);
+	return start_mask;
+}
+
+#define PCXHR_PIPE_STATE_CAPTURE_OFFSET		12
+#define MAX_WAIT_FOR_DSP			20
+
+static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr, int audio_mask, int *retry)
+{
+	struct pcxhr_rmh rmh;
+	int err;
+	int audio = 0;
+
+	*retry = 0;
+	while (audio_mask) {
+		if (audio_mask & 1) {
+			pcxhr_init_rmh(&rmh, CMD_CAN_START_PIPE);
+			if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET) {
+				/* can start playback pipe */
+				pcxhr_set_pipe_cmd_params(&rmh, 0, audio, 0, 0);
+			} else {
+				/* can start capture pipe */
+				pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
+							  PCXHR_PIPE_STATE_CAPTURE_OFFSET,
+							  0, 0);
+			}
+			err = pcxhr_send_msg(mgr, &rmh);
+			if (err) {
+				snd_printk(KERN_ERR
+					   "error pipe start (CMD_CAN_START_PIPE) err=%x!\n",
+					   err);
+				return err;
+			}
+			/* if the pipe couldn't be prepaired for start, retry it later */
+			if (rmh.stat[0] == 0)
+				*retry |= (1<<audio);
+		}
+		audio_mask>>=1;
+		audio++;
+	}
+	return 0;
+}
+
+static int pcxhr_stop_pipes(struct pcxhr_mgr *mgr, int audio_mask)
+{
+	struct pcxhr_rmh rmh;
+	int err;
+	int audio = 0;
+
+	while (audio_mask) {
+		if (audio_mask & 1) {
+			pcxhr_init_rmh(&rmh, CMD_STOP_PIPE);
+			if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET) {
+				/* stop playback pipe */
+				pcxhr_set_pipe_cmd_params(&rmh, 0, audio, 0, 0);
+			} else {
+				/* stop capture pipe */
+				pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
+							  PCXHR_PIPE_STATE_CAPTURE_OFFSET,
+							  0, 0);
+			}
+			err = pcxhr_send_msg(mgr, &rmh);
+			if (err) {
+				snd_printk(KERN_ERR
+					   "error pipe stop (CMD_STOP_PIPE) err=%x!\n",
+					   err);
+				return err;
+			}
+		}
+		audio_mask>>=1;
+		audio++;
+	}
+	return 0;
+}
+
+static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
+{
+	struct pcxhr_rmh rmh;
+	int err;
+	int audio = 0;
+
+	while (audio_mask) {
+		if (audio_mask & 1) {
+			pcxhr_init_rmh(&rmh, CMD_CONF_PIPE);
+			if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET)
+				pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0, 1 << audio);
+			else
+				pcxhr_set_pipe_cmd_params(&rmh, 1, 0, 0,
+							  1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET));
+			err = pcxhr_send_msg(mgr, &rmh);
+			if (err) {
+				snd_printk(KERN_ERR
+					   "error pipe start (CMD_CONF_PIPE) err=%x!\n",
+					   err);
+				return err;
+			}
+		}
+		audio_mask>>=1;
+		audio++;
+	}
+	/* now fire the interrupt on the card */
+	pcxhr_init_rmh(&rmh, CMD_SEND_IRQA);
+	err = pcxhr_send_msg(mgr, &rmh);
+	if (err) {
+		snd_printk(KERN_ERR "error pipe start (CMD_SEND_IRQA) err=%x!\n", err );
+		return err;
+	}
+	return 0;
+}
+
+
+
+int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_mask, int start)
+{
+	int state, i, err;
+	int audio_mask;
+
+#ifdef CONFIG_SND_DEBUG_DETECT
+	struct timeval my_tv1, my_tv2;
+	do_gettimeofday(&my_tv1);
+#endif
+	audio_mask = (playback_mask | (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET));
+	/* current pipe state (playback + record) */
+	state = pcxhr_pipes_running(mgr);
+	snd_printdd("pcxhr_set_pipe_state %s (mask %x current %x)\n",
+		    start ? "START" : "STOP", audio_mask, state);
+	if (start) {
+		audio_mask &= ~state;	/* start only pipes that are not yet started */
+		state = audio_mask;
+		for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
+			err = pcxhr_prepair_pipe_start(mgr, state, &state);
+			if (err)
+				return err;
+			if (state == 0)
+				break;	/* success, all pipes prepaired for start */
+			mdelay(1);		/* otherwise wait 1 millisecond and retry */
+		}
+	} else {
+		audio_mask &= state;	/* stop only pipes that are started */
+	}
+	if (audio_mask == 0)
+		return 0;
+
+	err = pcxhr_toggle_pipes(mgr, audio_mask);
+	if (err)
+		return err;
+
+	i = 0;
+	while (1) {
+		state = pcxhr_pipes_running(mgr);
+		/* have all pipes the new state ? */
+		if ((state & audio_mask) == (start ? audio_mask : 0))
+			break;
+		if (++i >= MAX_WAIT_FOR_DSP * 100) {
+			snd_printk(KERN_ERR "error pipe start/stop (ED_NO_RESPONSE_AT_IRQA)\n");
+			return -EBUSY;
+		}
+		udelay(10);			/* wait 10 microseconds */
+	}
+	if (!start) {
+		err = pcxhr_stop_pipes(mgr, audio_mask);
+		if (err)
+			return err;
+	}
+#ifdef CONFIG_SND_DEBUG_DETECT
+	do_gettimeofday(&my_tv2);
+	snd_printdd("***SET PIPE STATE*** TIME = %ld (err = %x)\n",
+		    my_tv2.tv_usec - my_tv1.tv_usec, err);
+#endif
+	return 0;
+}
+
+int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
+				unsigned int value, int *changed)
+{
+	struct pcxhr_rmh rmh;
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&mgr->msg_lock, flags);
+	if ((mgr->io_num_reg_cont & mask) == value) {
+		snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n", mask, value);
+		if (changed)
+			*changed = 0;
+		spin_unlock_irqrestore(&mgr->msg_lock, flags);
+		return 0;	/* already programmed */
+	}
+	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
+	rmh.cmd[0] |= IO_NUM_REG_CONT;
+	rmh.cmd[1]  = mask;
+	rmh.cmd[2]  = value;
+	rmh.cmd_len = 3;
+	err = pcxhr_send_msg_nolock(mgr, &rmh);
+	if (err == 0) {
+		mgr->io_num_reg_cont &= ~mask;
+		mgr->io_num_reg_cont |= value;
+		if (changed)
+			*changed = 1;
+	}
+	spin_unlock_irqrestore(&mgr->msg_lock, flags);
+	return err;
+}
+
+#define PCXHR_IRQ_TIMER		0x000300
+#define PCXHR_IRQ_FREQ_CHANGE	0x000800
+#define PCXHR_IRQ_TIME_CODE	0x001000
+#define PCXHR_IRQ_NOTIFY	0x002000
+#define PCXHR_IRQ_ASYNC		0x008000
+#define PCXHR_IRQ_MASK		0x00bb00
+#define PCXHR_FATAL_DSP_ERR	0xff0000
+
+enum pcxhr_async_err_src {
+	PCXHR_ERR_PIPE,
+	PCXHR_ERR_STREAM,
+	PCXHR_ERR_AUDIO
+};
+
+static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err,
+				  enum pcxhr_async_err_src err_src, int pipe,
+				  int is_capture)
+{
+#ifdef CONFIG_SND_DEBUG_DETECT
+	static char* err_src_name[] = {
+		[PCXHR_ERR_PIPE]	= "Pipe",
+		[PCXHR_ERR_STREAM]	= "Stream",
+		[PCXHR_ERR_AUDIO]	= "Audio"
+	};
+#endif
+	if (err & 0xfff)
+		err &= 0xfff;
+	else
+		err = ((err >> 12) & 0xfff);
+	if (!err)
+		return 0;
+	snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n", err_src_name[err_src],
+		    is_capture ? "Record" : "Play", pipe, err);
+	if (err == 0xe01)
+		mgr->async_err_stream_xrun++;
+	else if (err == 0xe10)
+		mgr->async_err_pipe_xrun++;
+	else
+		mgr->async_err_other_last = (int)err;
+	return 1;
+}
+
+
+void pcxhr_msg_tasklet(unsigned long arg)
+{
+	struct pcxhr_mgr *mgr = (struct pcxhr_mgr *)(arg);
+	struct pcxhr_rmh *prmh = mgr->prmh;
+	int err;
+	int i, j;
+
+	if (mgr->src_it_dsp & PCXHR_IRQ_FREQ_CHANGE)
+		snd_printdd("TASKLET : PCXHR_IRQ_FREQ_CHANGE event occured\n");
+	if (mgr->src_it_dsp & PCXHR_IRQ_TIME_CODE)
+		snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n");
+	if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY)
+		snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n");
+	if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) {
+		snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n");
+
+		pcxhr_init_rmh(prmh, CMD_ASYNC);
+		prmh->cmd[0] |= 1;	/* add SEL_ASYNC_EVENTS */
+		/* this is the only one extra long response command */
+		prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS;
+		err = pcxhr_send_msg(mgr, prmh);
+		if (err)
+			snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n", err);
+		i = 1;
+		while (i < prmh->stat_len) {
+			int nb_audio = (prmh->stat[i] >> FIELD_SIZE) & MASK_FIRST_FIELD;
+			int nb_stream = (prmh->stat[i] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD;
+			int pipe = prmh->stat[i] & MASK_FIRST_FIELD;
+			int is_capture = prmh->stat[i] & 0x400000;
+			u32 err;
+
+			if (prmh->stat[i] & 0x800000) {	/* if BIT_END */
+				snd_printdd("TASKLET : End%sPipe %d\n",
+					    is_capture ? "Record" : "Play", pipe);
+			}
+			i++;
+			err = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1];
+			if (err)
+				pcxhr_handle_async_err(mgr, err, PCXHR_ERR_PIPE,
+						       pipe, is_capture);
+			i += 2;
+			for (j = 0; j < nb_stream; j++) {
+				err = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1];
+				if (err)
+					pcxhr_handle_async_err(mgr, err, PCXHR_ERR_STREAM,
+							       pipe, is_capture);
+				i += 2;
+			}
+			for (j = 0; j < nb_audio; j++) {
+				err = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1];
+				if (err)
+					pcxhr_handle_async_err(mgr, err, PCXHR_ERR_AUDIO,
+							       pipe, is_capture);
+				i += 2;
+			}
+		}
+	}
+}
+
+static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
+					    struct pcxhr_stream *stream)
+{
+	u_int64_t hw_sample_count;
+	struct pcxhr_rmh rmh;
+	int err, stream_mask;
+
+	stream_mask = stream->pipe->is_capture ? 1 : 1<<stream->substream->number;
+
+	/* get sample count for one stream */
+	pcxhr_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
+	pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
+				  stream->pipe->first_audio, 0, stream_mask);
+	/* rmh.stat_len = 2; */		/* 2 resp data for each stream of the pipe */
+
+	err = pcxhr_send_msg(mgr, &rmh);
+	if (err)
+		return 0;
+
+	hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24;
+	hw_sample_count += (u_int64_t)rmh.stat[1];
+
+	snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n",
+		    stream->pipe->is_capture ? 'C':'P', stream->substream->number,
+		    (long unsigned int)hw_sample_count,
+		    (long unsigned int)(stream->timer_abs_periods +
+					stream->timer_period_frag + PCXHR_GRANULARITY));
+
+	return hw_sample_count;
+}
+
+static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
+				   struct pcxhr_stream *stream, int samples_to_add)
+{
+	if (stream->substream && (stream->status == PCXHR_STREAM_STATUS_RUNNING)) {
+		u_int64_t new_sample_count;
+		int elapsed = 0;
+		int hardware_read = 0;
+		struct snd_pcm_runtime *runtime = stream->substream->runtime;
+
+		if (samples_to_add < 0) {
+			stream->timer_is_synced = 0;
+			/* add default if no hardware_read possible */
+			samples_to_add = PCXHR_GRANULARITY;
+		}
+
+		if (!stream->timer_is_synced) {
+			if (stream->timer_abs_periods != 0 ||
+			    stream->timer_period_frag + PCXHR_GRANULARITY >=
+			    runtime->period_size) {
+				new_sample_count = pcxhr_stream_read_position(mgr, stream);
+				hardware_read = 1;
+				if (new_sample_count >= PCXHR_GRANULARITY_MIN) {
+					/* sub security offset because of jitter and
+					 * finer granularity of dsp time (MBOX4)
+					 */
+					new_sample_count -= PCXHR_GRANULARITY_MIN;
+					stream->timer_is_synced = 1;
+				}
+			}
+		}
+		if (!hardware_read) {
+			/* if we didn't try to sync the position, increment it
+			 * by PCXHR_GRANULARITY every timer interrupt
+			 */
+			new_sample_count = stream->timer_abs_periods +
+				stream->timer_period_frag + samples_to_add;
+		}
+		while (1) {
+			u_int64_t new_elapse_pos = stream->timer_abs_periods +
+				runtime->period_size;
+			if (new_elapse_pos > new_sample_count)
+				break;
+			elapsed = 1;
+			stream->timer_buf_periods++;
+			if (stream->timer_buf_periods >= runtime->periods)
+				stream->timer_buf_periods = 0;
+			stream->timer_abs_periods = new_elapse_pos;
+		}
+		if (new_sample_count >= stream->timer_abs_periods)
+			stream->timer_period_frag = (u_int32_t)(new_sample_count -
+								stream->timer_abs_periods);
+		else
+			snd_printk(KERN_ERR "ERROR new_sample_count too small ??? %lx\n",
+				   (long unsigned int)new_sample_count);
+
+		if (elapsed) {
+			spin_unlock(&mgr->lock);
+			snd_pcm_period_elapsed(stream->substream);
+			spin_lock(&mgr->lock);
+		}
+	}
+}
+
+
+irqreturn_t pcxhr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct pcxhr_mgr *mgr = dev_id;
+	unsigned int reg;
+	int i, j;
+	struct snd_pcxhr *chip;
+
+	spin_lock(&mgr->lock);
+
+	reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS);
+	if (! (reg & PCXHR_IRQCS_ACTIVE_PCIDB)) {
+		spin_unlock(&mgr->lock);
+		return IRQ_NONE;	/* this device did not cause the interrupt */
+	}
+
+	/* clear interrupt */
+	reg = PCXHR_INPL(mgr, PCXHR_PLX_L2PCIDB);
+	PCXHR_OUTPL(mgr, PCXHR_PLX_L2PCIDB, reg);
+
+	/* timer irq occured */
+	if (reg & PCXHR_IRQ_TIMER) {
+		int timer_toggle = reg & PCXHR_IRQ_TIMER;
+		/* is a 24 bit counter */
+		int dsp_time_new = PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK;
+		int dsp_time_diff = dsp_time_new - mgr->dsp_time_last;
+
+		if (dsp_time_diff < 0 && mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID) {
+			snd_printdd("ERROR DSP TIME old(%d) new(%d) -> "
+				    "resynchronize all streams\n",
+				    mgr->dsp_time_last, dsp_time_new);
+			mgr->dsp_time_err++;
+		}
+#ifdef CONFIG_SND_DEBUG_DETECT
+		if (dsp_time_diff == 0)
+			snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", dsp_time_new);
+		else if (dsp_time_diff >= (2*PCXHR_GRANULARITY))
+			snd_printdd("ERROR DSP TIME TOO BIG old(%d) add(%d)\n",
+				    mgr->dsp_time_last, dsp_time_new - mgr->dsp_time_last);
+#endif
+		mgr->dsp_time_last = dsp_time_new;
+
+		if (timer_toggle == mgr->timer_toggle)
+			snd_printk(KERN_ERR "ERROR TIMER TOGGLE\n");
+		mgr->timer_toggle = timer_toggle;
+
+		reg &= ~PCXHR_IRQ_TIMER;
+		for (i = 0; i < mgr->num_cards; i++) {
+			chip = mgr->chip[i];
+			for (j = 0; j < chip->nb_streams_capt; j++)
+				pcxhr_update_timer_pos(mgr, &chip->capture_stream[j],
+						       dsp_time_diff);
+		}
+		for (i = 0; i < mgr->num_cards; i++) {
+			chip = mgr->chip[i];
+			for (j = 0; j < chip->nb_streams_play; j++)
+				pcxhr_update_timer_pos(mgr, &chip->playback_stream[j],
+						       dsp_time_diff);
+		}
+	}
+	/* other irq's handled in the tasklet */
+	if (reg & PCXHR_IRQ_MASK) {
+
+		/* as we didn't request any notifications, some kind of xrun error
+		 * will probably occured
+		 */
+		/* better resynchronize all streams next interrupt : */
+		mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
+		
+		mgr->src_it_dsp = reg;
+		tasklet_hi_schedule(&mgr->msg_taskq);
+	}
+#ifdef CONFIG_SND_DEBUG_DETECT
+	if (reg & PCXHR_FATAL_DSP_ERR)
+		snd_printdd("FATAL DSP ERROR : %x\n", reg);
+#endif
+	spin_unlock(&mgr->lock);
+	return IRQ_HANDLED;	/* this device caused the interrupt */
+}
diff --git a/sound/pci/pcxhr/pcxhr_core.h b/sound/pci/pcxhr/pcxhr_core.h
new file mode 100644
index 0000000..e7415d6
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_core.h
@@ -0,0 +1,200 @@
+/*
+ * Driver for Digigram pcxhr compatible soundcards
+ *
+ * low level interface with interrupt ans message handling
+ *
+ * Copyright (c) 2004 by Digigram <alsa@digigram.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 __SOUND_PCXHR_CORE_H
+#define __SOUND_PCXHR_CORE_H
+
+struct firmware;
+struct pcxhr_mgr;
+
+/* init and firmware download commands */
+void pcxhr_reset_xilinx_com(struct pcxhr_mgr *mgr);
+void pcxhr_reset_dsp(struct pcxhr_mgr *mgr);
+void pcxhr_enable_dsp(struct pcxhr_mgr *mgr);
+int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilinx, int second);
+int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eeprom);
+int pcxhr_load_boot_binary(struct pcxhr_mgr *mgr, const struct firmware *boot);
+int pcxhr_load_dsp_binary(struct pcxhr_mgr *mgr, const struct firmware *dsp);
+
+/* DSP time available on MailBox4 register : 24 bit time samples() */
+#define PCXHR_DSP_TIME_MASK		0x00ffffff
+#define PCXHR_DSP_TIME_INVALID		0x10000000
+
+
+#define PCXHR_SIZE_MAX_CMD		8
+#define PCXHR_SIZE_MAX_STATUS		16
+#define PCXHR_SIZE_MAX_LONG_STATUS	256
+
+struct pcxhr_rmh {
+	u16	cmd_len;		/* length of the command to send (WORDs) */
+	u16	stat_len;		/* length of the status received (WORDs) */
+	u16	dsp_stat;		/* status type, RMP_SSIZE_XXX */
+	u16	cmd_idx;		/* index of the command */
+	u32	cmd[PCXHR_SIZE_MAX_CMD];
+	u32	stat[PCXHR_SIZE_MAX_STATUS];
+};
+
+enum {
+	CMD_VERSION,			/* cmd_len = 2	stat_len = 1 */
+	CMD_SUPPORTED,			/* cmd_len = 1	stat_len = 4 */
+	CMD_TEST_IT,			/* cmd_len = 1	stat_len = 1 */
+	CMD_SEND_IRQA,			/* cmd_len = 1	stat_len = 0 */
+	CMD_ACCESS_IO_WRITE,		/* cmd_len >= 1	stat_len >= 1 */
+	CMD_ACCESS_IO_READ,		/* cmd_len >= 1	stat_len >= 1 */
+	CMD_ASYNC,			/* cmd_len = 1	stat_len = 1 */
+	CMD_MODIFY_CLOCK,		/* cmd_len = 3	stat_len = 0 */
+	CMD_RESYNC_AUDIO_INPUTS,	/* cmd_len = 1	stat_len = 0 */
+	CMD_GET_DSP_RESOURCES,		/* cmd_len = 1	stat_len = 4 */
+	CMD_SET_TIMER_INTERRUPT,	/* cmd_len = 1	stat_len = 0 */
+	CMD_RES_PIPE,			/* cmd_len = 2	stat_len = 0 */
+	CMD_FREE_PIPE,			/* cmd_len = 1	stat_len = 0 */
+	CMD_CONF_PIPE,			/* cmd_len = 2	stat_len = 0 */
+	CMD_STOP_PIPE,			/* cmd_len = 1	stat_len = 0 */
+	CMD_PIPE_SAMPLE_COUNT,		/* cmd_len = 2	stat_len = 2 */
+	CMD_CAN_START_PIPE,		/* cmd_len >= 1	stat_len = 1 */
+	CMD_START_STREAM,		/* cmd_len = 2	stat_len = 0 */
+	CMD_STREAM_OUT_LEVEL_ADJUST,	/* cmd_len >= 1	stat_len = 0 */
+	CMD_STOP_STREAM,		/* cmd_len = 2	stat_len = 0 */
+	CMD_UPDATE_R_BUFFERS,		/* cmd_len = 4	stat_len = 0 */
+	CMD_FORMAT_STREAM_OUT,		/* cmd_len >= 2	stat_len = 0 */
+	CMD_FORMAT_STREAM_IN,		/* cmd_len >= 4	stat_len = 0 */
+	CMD_STREAM_SAMPLE_COUNT,	/* cmd_len = 2	stat_len = (2 * nb_stream) */
+	CMD_AUDIO_LEVEL_ADJUST,		/* cmd_len = 3	stat_len = 0 */
+	CMD_LAST_INDEX
+};
+
+#define MASK_DSP_WORD		0x00ffffff
+#define MASK_ALL_STREAM		0x00ffffff
+#define MASK_DSP_WORD_LEVEL	0x000001ff
+#define MASK_FIRST_FIELD	0x0000001f
+#define FIELD_SIZE		5
+
+/*
+ init the rmh struct; by default cmd_len is set to 1
+ */
+void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd);
+
+void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh* rmh, int capture, unsigned int param1,
+			       unsigned int param2, unsigned int param3);
+
+/*
+ send the rmh
+ */
+int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh);
+
+
+/* values used for CMD_ACCESS_IO_WRITE and CMD_ACCESS_IO_READ */
+#define IO_NUM_REG_CONT			0
+#define IO_NUM_REG_GENCLK		1
+#define IO_NUM_REG_MUTE_OUT		2
+#define IO_NUM_SPEED_RATIO		4
+#define IO_NUM_REG_STATUS		5
+#define IO_NUM_REG_CUER			10
+#define IO_NUM_UER_CHIP_REG		11
+#define IO_NUM_REG_OUT_ANA_LEVEL	20
+#define IO_NUM_REG_IN_ANA_LEVEL		21
+
+
+#define REG_CONT_UNMUTE_INPUTS		0x020000
+
+/* parameters used with register IO_NUM_REG_STATUS */
+#define REG_STATUS_OPTIONS		0
+#define REG_STATUS_AES_SYNC		8
+#define REG_STATUS_AES_1		9
+#define REG_STATUS_AES_2		10
+#define REG_STATUS_AES_3		11
+#define REG_STATUS_AES_4		12
+#define REG_STATUS_WORD_CLOCK		13
+#define REG_STATUS_INTER_SYNC		14
+#define REG_STATUS_CURRENT		0x80
+/* results */
+#define REG_STATUS_OPT_NO_VIDEO_SIGNAL	0x01
+#define REG_STATUS_OPT_DAUGHTER_MASK	0x1c
+#define REG_STATUS_OPT_ANALOG_BOARD	0x00
+#define REG_STATUS_OPT_NO_DAUGHTER	0x1c
+#define REG_STATUS_OPT_COMPANION_MASK	0xe0
+#define REG_STATUS_OPT_NO_COMPANION	0xe0
+#define REG_STATUS_SYNC_32000		0x00
+#define REG_STATUS_SYNC_44100		0x01
+#define REG_STATUS_SYNC_48000		0x02
+#define REG_STATUS_SYNC_64000		0x03
+#define REG_STATUS_SYNC_88200		0x04
+#define REG_STATUS_SYNC_96000		0x05
+#define REG_STATUS_SYNC_128000		0x06
+#define REG_STATUS_SYNC_176400		0x07
+#define REG_STATUS_SYNC_192000		0x08
+
+int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_mask, int start);
+
+int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
+				unsigned int value, int *changed);
+
+/* codec parameters */
+#define CS8416_RUN		0x200401
+#define CS8416_FORMAT_DETECT	0x200b00
+#define CS8416_CSB0		0x201900
+#define CS8416_CSB1		0x201a00
+#define CS8416_CSB2		0x201b00
+#define CS8416_CSB3		0x201c00
+#define CS8416_CSB4		0x201d00
+#define CS8416_VERSION		0x207f00
+
+#define CS8420_DATA_FLOW_CTL	0x200301
+#define CS8420_CLOCK_SRC_CTL	0x200401
+#define CS8420_RECEIVER_ERRORS	0x201000
+#define CS8420_SRC_RATIO	0x201e00
+#define CS8420_CSB0		0x202000
+#define CS8420_CSB1		0x202100
+#define CS8420_CSB2		0x202200
+#define CS8420_CSB3		0x202300
+#define CS8420_CSB4		0x202400
+#define CS8420_VERSION		0x207f00
+
+#define CS4271_MODE_CTL_1	0x200101
+#define CS4271_DAC_CTL		0x200201
+#define CS4271_VOLMIX		0x200301
+#define CS4271_VOLMUTE_LEFT	0x200401
+#define CS4271_VOLMUTE_RIGHT	0x200501
+#define CS4271_ADC_CTL		0x200601
+#define CS4271_MODE_CTL_2	0x200701
+
+#define CHIP_SIG_AND_MAP_SPI	0xff7f00
+
+/* codec selection */
+#define CS4271_01_CS		0x160018
+#define CS4271_23_CS		0x160019
+#define CS4271_45_CS		0x16001a
+#define CS4271_67_CS		0x16001b
+#define CS4271_89_CS		0x16001c
+#define CS4271_AB_CS		0x16001d
+#define CS8420_01_CS		0x080090
+#define CS8420_23_CS		0x080092
+#define CS8420_45_CS		0x080094
+#define CS8420_67_CS		0x080096
+#define CS8416_01_CS		0x080098
+
+
+/* interrupt handling */
+irqreturn_t pcxhr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+void pcxhr_msg_tasklet(unsigned long arg);
+
+#endif /* __SOUND_PCXHR_CORE_H */
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
new file mode 100644
index 0000000..03517c1
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -0,0 +1,438 @@
+/*
+ * Driver for Digigram pcxhr compatible soundcards
+ *
+ * hwdep device manager
+ *
+ * Copyright (c) 2004 by Digigram <alsa@digigram.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 <sound/driver.h>
+#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <sound/core.h>
+#include <sound/hwdep.h>
+#include "pcxhr.h"
+#include "pcxhr_mixer.h"
+#include "pcxhr_hwdep.h"
+#include "pcxhr_core.h"
+
+
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+#if !defined(CONFIG_USE_PCXHRLOADER) && !defined(CONFIG_SND_PCXHR) /* built-in kernel */
+#define SND_PCXHR_FW_LOADER	/* use the standard firmware loader */
+#endif
+#endif
+
+
+/*
+ * get basic information and init pcxhr card
+ */
+
+static int pcxhr_init_board(struct pcxhr_mgr *mgr)
+{
+	int err;
+	struct pcxhr_rmh rmh;
+	int card_streams;
+
+	/* calc the number of all streams used */
+	if (mgr->mono_capture)
+		card_streams = mgr->capture_chips * 2;
+	else
+		card_streams = mgr->capture_chips;
+	card_streams += mgr->playback_chips * PCXHR_PLAYBACK_STREAMS;
+
+	/* enable interrupts */
+	pcxhr_enable_dsp(mgr);
+
+	pcxhr_init_rmh(&rmh, CMD_SUPPORTED);
+	err = pcxhr_send_msg(mgr, &rmh);
+	if (err)
+		return err;
+	/* test 8 or 12 phys out */
+	snd_assert((rmh.stat[0] & MASK_FIRST_FIELD) == mgr->playback_chips*2,
+		   return -EINVAL);
+	/* test 8 or 2 phys in */
+	snd_assert(((rmh.stat[0] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD) ==
+		   mgr->capture_chips * 2, return -EINVAL);
+	/* test max nb substream per board */
+	snd_assert((rmh.stat[1] & 0x5F) >= card_streams, return -EINVAL);
+	/* test max nb substream per pipe */
+	snd_assert(((rmh.stat[1]>>7)&0x5F) >= PCXHR_PLAYBACK_STREAMS, return -EINVAL);
+
+	pcxhr_init_rmh(&rmh, CMD_VERSION);
+	/* firmware num for DSP */
+	rmh.cmd[0] |= mgr->firmware_num;
+	/* transfer granularity in samples (should be multiple of 48) */
+	rmh.cmd[1] = (1<<23) + PCXHR_GRANULARITY;
+	rmh.cmd_len = 2;
+	err = pcxhr_send_msg(mgr, &rmh);
+	if (err)
+		return err;
+	snd_printdd("PCXHR DSP version is %d.%d.%d\n",
+		    (rmh.stat[0]>>16)&0xff, (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff);
+	mgr->dsp_version = rmh.stat[0];
+
+	/* get options */
+	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
+	rmh.cmd[0] |= IO_NUM_REG_STATUS;
+	rmh.cmd[1]  = REG_STATUS_OPTIONS;
+	rmh.cmd_len = 2;
+	err = pcxhr_send_msg(mgr, &rmh);
+	if (err)
+		return err;
+
+	if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) == REG_STATUS_OPT_ANALOG_BOARD)
+		mgr->board_has_analog = 1;	/* analog addon board available */
+	else
+		/* analog addon board not available -> no support for instance */
+		return -EINVAL;	
+
+	/* unmute inputs */
+	err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
+					  REG_CONT_UNMUTE_INPUTS, NULL);
+	if (err)
+		return err;
+	/* unmute outputs */
+	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* a write to IO_NUM_REG_MUTE_OUT mutes! */
+	rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
+	err = pcxhr_send_msg(mgr, &rmh);
+	return err;
+}
+
+void pcxhr_reset_board(struct pcxhr_mgr *mgr)
+{
+	struct pcxhr_rmh rmh;
+
+	if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
+		/* mute outputs */
+		/* a read to IO_NUM_REG_MUTE_OUT register unmutes! */
+		pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
+		rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
+		pcxhr_send_msg(mgr, &rmh);
+		/* mute inputs */
+		pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, 0, NULL);
+	}
+	/* reset pcxhr dsp */
+	if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX))
+		pcxhr_reset_dsp(mgr);
+	/* reset second xilinx */
+	if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_XLX_COM_INDEX))
+		pcxhr_reset_xilinx_com(mgr);
+	return;
+}
+
+
+/*
+ *  allocate a playback/capture pipe (pcmp0/pcmc0)
+ */
+static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe,
+				    int is_capture, int pin)
+{
+	int stream_count, audio_count;
+	int err;
+	struct pcxhr_rmh rmh;
+
+	if (is_capture) {
+		stream_count = 1;
+		if (mgr->mono_capture)
+			audio_count = 1;
+		else
+			audio_count = 2;
+	} else {
+		stream_count = PCXHR_PLAYBACK_STREAMS;
+		audio_count = 2;	/* always stereo */
+	}
+	snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n", pin, is_capture ? 'c' : 'p');
+	pipe->is_capture = is_capture;
+	pipe->first_audio = pin;
+	/* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */
+	pcxhr_init_rmh(&rmh, CMD_RES_PIPE);
+	pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin, audio_count, stream_count); 
+	err = pcxhr_send_msg(mgr, &rmh);
+	if (err < 0) {
+		snd_printk(KERN_ERR "error pipe allocation (CMD_RES_PIPE) err=%x!\n", err );
+		return err;
+	}
+	pipe->status = PCXHR_PIPE_DEFINED;
+
+	return 0;
+}
+
+/*
+ *  free playback/capture pipe (pcmp0/pcmc0)
+ */
+#if 0
+static int pcxhr_dsp_free_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe)
+{
+	struct pcxhr_rmh rmh;
+	int capture_mask = 0;
+	int playback_mask = 0;
+	int err = 0;
+
+	if (pipe->is_capture)
+		capture_mask  = (1 << pipe->first_audio);
+	else
+		playback_mask = (1 << pipe->first_audio);
+
+	/* stop one pipe */
+	err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
+	if (err < 0)
+		snd_printk(KERN_ERR "error stopping pipe!\n");
+	/* release the pipe */
+	pcxhr_init_rmh(&rmh, CMD_FREE_PIPE);
+	pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio, 0, 0);
+	err = pcxhr_send_msg(mgr, &rmh);
+	if (err < 0)
+		snd_printk(KERN_ERR "error pipe release (CMD_FREE_PIPE) err(%x)\n", err);
+	pipe->status = PCXHR_PIPE_UNDEFINED;
+	return err;
+}
+#endif
+
+
+static int pcxhr_config_pipes(struct pcxhr_mgr *mgr)
+{
+	int err, i, j;
+	struct snd_pcxhr *chip;
+	struct pcxhr_pipe *pipe;
+
+	/* allocate the pipes on the dsp */
+	for (i = 0; i < mgr->num_cards; i++) {
+		chip = mgr->chip[i];
+		if (chip->nb_streams_play) {
+			pipe = &chip->playback_pipe;
+			err = pcxhr_dsp_allocate_pipe( mgr, pipe, 0, i*2);
+			if (err)
+				return err;
+			for(j = 0; j < chip->nb_streams_play; j++)
+				chip->playback_stream[j].pipe = pipe;
+		}
+		for (j = 0; j < chip->nb_streams_capt; j++) {
+			pipe = &chip->capture_pipe[j];
+			err = pcxhr_dsp_allocate_pipe(mgr, pipe, 1, i*2 + j);
+			if (err)
+				return err;
+			chip->capture_stream[j].pipe = pipe;
+		}
+	}
+	return 0;
+}
+
+static int pcxhr_start_pipes(struct pcxhr_mgr *mgr)
+{
+	int i, j;
+	struct snd_pcxhr *chip;
+	int playback_mask = 0;
+	int capture_mask = 0;
+
+	/* start all the pipes on the dsp */
+	for (i = 0; i < mgr->num_cards; i++) {
+		chip = mgr->chip[i];
+		if (chip->nb_streams_play)
+			playback_mask |= (1 << chip->playback_pipe.first_audio);
+		for (j = 0; j < chip->nb_streams_capt; j++)
+			capture_mask |= (1 << chip->capture_pipe[j].first_audio);
+	}
+	return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
+}
+
+
+static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, const struct firmware *dsp)
+{
+	int err, card_index;
+
+	snd_printdd("loading dsp [%d] size = %Zd\n", index, dsp->size);
+
+	switch (index) {
+	case PCXHR_FIRMWARE_XLX_INT_INDEX:
+		pcxhr_reset_xilinx_com(mgr);
+		return pcxhr_load_xilinx_binary(mgr, dsp, 0);
+
+	case PCXHR_FIRMWARE_XLX_COM_INDEX:
+		pcxhr_reset_xilinx_com(mgr);
+		return pcxhr_load_xilinx_binary(mgr, dsp, 1);
+
+	case PCXHR_FIRMWARE_DSP_EPRM_INDEX:
+		pcxhr_reset_dsp(mgr);
+		return pcxhr_load_eeprom_binary(mgr, dsp);
+
+	case PCXHR_FIRMWARE_DSP_BOOT_INDEX:
+		return pcxhr_load_boot_binary(mgr, dsp);
+
+	case PCXHR_FIRMWARE_DSP_MAIN_INDEX:
+		err = pcxhr_load_dsp_binary(mgr, dsp);
+		if (err)
+			return err;
+		break;	/* continue with first init */
+	default:
+		snd_printk(KERN_ERR "wrong file index\n");
+		return -EFAULT;
+	} /* end of switch file index*/
+
+	/* first communication with embedded */
+	err = pcxhr_init_board(mgr);
+        if (err < 0) {
+		snd_printk(KERN_ERR "pcxhr could not be set up\n");
+		return err;
+	}
+	err = pcxhr_config_pipes(mgr);
+        if (err < 0) {
+		snd_printk(KERN_ERR "pcxhr pipes could not be set up\n");
+		return err;
+	}
+       	/* create devices and mixer in accordance with HW options*/
+        for (card_index = 0; card_index < mgr->num_cards; card_index++) {
+		struct snd_pcxhr *chip = mgr->chip[card_index];
+
+		if ((err = pcxhr_create_pcm(chip)) < 0)
+			return err;
+
+		if (card_index == 0) {
+			if ((err = pcxhr_create_mixer(chip->mgr)) < 0)
+				return err;
+		}
+		if ((err = snd_card_register(chip->card)) < 0)
+			return err;
+	}
+	err = pcxhr_start_pipes(mgr);
+        if (err < 0) {
+		snd_printk(KERN_ERR "pcxhr pipes could not be started\n");
+		return err;
+	}
+	snd_printdd("pcxhr firmware downloaded and successfully set up\n");
+
+	return 0;
+}
+
+/*
+ * fw loader entry
+ */
+#ifdef SND_PCXHR_FW_LOADER
+
+int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
+{
+	static char *fw_files[5] = {
+		"xi_1_882.dat",
+		"xc_1_882.dat",
+		"e321_512.e56",
+		"b321_512.b56",
+		"d321_512.d56"
+	};
+	char path[32];
+
+	const struct firmware *fw_entry;
+	int i, err;
+
+	for (i = 0; i < ARRAY_SIZE(fw_files); i++) {
+		sprintf(path, "pcxhr/%s", fw_files[i]);
+		if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
+			snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n", path);
+			return -ENOENT;
+		}
+		/* fake hwdep dsp record */
+		err = pcxhr_dsp_load(mgr, i, fw_entry);
+		release_firmware(fw_entry);
+		if (err < 0)
+			return err;
+		mgr->dsp_loaded |= 1 << i;
+	}
+	return 0;
+}
+
+#else /* old style firmware loading */
+
+/* pcxhr hwdep interface id string */
+#define PCXHR_HWDEP_ID       "pcxhr loader"
+
+
+static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw,
+				  struct snd_hwdep_dsp_status *info)
+{
+	strcpy(info->id, "pcxhr");
+        info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX;
+
+	if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))
+		info->chip_ready = 1;
+
+	info->version = PCXHR_DRIVER_VERSION;
+	return 0;
+}
+
+static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw,
+				struct snd_hwdep_dsp_image *dsp)
+{
+	struct pcxhr_mgr *mgr = hw->private_data;
+	int err;
+	struct firmware fw;
+
+	fw.size = dsp->length;
+	fw.data = vmalloc(fw.size);
+	if (! fw.data) {
+		snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%d bytes)\n",
+			   fw.size);
+		return -ENOMEM;
+	}
+	if (copy_from_user(fw.data, dsp->image, dsp->length)) {
+		vfree(fw.data);
+		return -EFAULT;
+	}
+	err = pcxhr_dsp_load(mgr, dsp->index, &fw);
+	vfree(fw.data);
+	if (err < 0)
+		return err;
+	mgr->dsp_loaded |= 1 << dsp->index;
+	return 0;
+}
+
+static int pcxhr_hwdep_open(struct snd_hwdep *hw, struct file *file)
+{
+	return 0;
+}
+
+static int pcxhr_hwdep_release(struct snd_hwdep *hw, struct file *file)
+{
+	return 0;
+}
+
+int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
+{
+	int err;
+	struct snd_hwdep *hw;
+
+	/* only create hwdep interface for first cardX (see "index" module parameter)*/
+	if ((err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw)) < 0)
+		return err;
+
+	hw->iface = SNDRV_HWDEP_IFACE_PCXHR;
+	hw->private_data = mgr;
+	hw->ops.open = pcxhr_hwdep_open;
+	hw->ops.release = pcxhr_hwdep_release;
+	hw->ops.dsp_status = pcxhr_hwdep_dsp_status;
+	hw->ops.dsp_load = pcxhr_hwdep_dsp_load;
+	hw->exclusive = 1;
+	mgr->dsp_loaded = 0;
+	sprintf(hw->name, PCXHR_HWDEP_ID);
+
+	if ((err = snd_card_register(mgr->chip[0]->card)) < 0)
+		return err;
+	return 0;
+}
+
+#endif /* SND_PCXHR_FW_LOADER */
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.h b/sound/pci/pcxhr/pcxhr_hwdep.h
new file mode 100644
index 0000000..f561909
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_hwdep.h
@@ -0,0 +1,40 @@
+/*
+ * Driver for Digigram pcxhr compatible soundcards
+ *
+ * definitions and makros for basic card access
+ *
+ * Copyright (c) 2004 by Digigram <alsa@digigram.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 __SOUND_PCXHR_HWDEP_H
+#define __SOUND_PCXHR_HWDEP_H
+
+
+/* firmware status codes  */
+#define PCXHR_FIRMWARE_XLX_INT_INDEX   0
+#define PCXHR_FIRMWARE_XLX_COM_INDEX   1
+#define PCXHR_FIRMWARE_DSP_EPRM_INDEX  2
+#define PCXHR_FIRMWARE_DSP_BOOT_INDEX  3
+#define PCXHR_FIRMWARE_DSP_MAIN_INDEX  4
+#define PCXHR_FIRMWARE_FILES_MAX_INDEX 5
+
+
+/* exported */
+int  pcxhr_setup_firmware(struct pcxhr_mgr *mgr);
+void pcxhr_reset_board(struct pcxhr_mgr *mgr);
+
+#endif /* __SOUND_PCXHR_HWDEP_H */
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
new file mode 100644
index 0000000..760e733
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -0,0 +1,1020 @@
+#define __NO_VERSION__
+/*
+ * Driver for Digigram pcxhr compatible soundcards
+ *
+ * mixer callbacks
+ *
+ * Copyright (c) 2004 by Digigram <alsa@digigram.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 <sound/driver.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <sound/core.h>
+#include "pcxhr.h"
+#include "pcxhr_hwdep.h"
+#include "pcxhr_core.h"
+#include <sound/control.h>
+#include <sound/asoundef.h>
+#include "pcxhr_mixer.h"
+
+
+#define PCXHR_ANALOG_CAPTURE_LEVEL_MIN   0	/* -96.0 dB */
+#define PCXHR_ANALOG_CAPTURE_LEVEL_MAX   255	/* +31.5 dB */
+#define PCXHR_ANALOG_CAPTURE_ZERO_LEVEL  224	/* +16.0 dB ( +31.5 dB - fix level +15.5 dB ) */
+
+#define PCXHR_ANALOG_PLAYBACK_LEVEL_MIN  0	/* -128.0 dB */
+#define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX  128	/*    0.0 dB */
+#define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104	/*  -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */
+
+static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel)
+{
+	int err, vol;
+	struct pcxhr_rmh rmh;
+
+	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
+	if (is_capture) {
+		rmh.cmd[0] |= IO_NUM_REG_IN_ANA_LEVEL;
+		rmh.cmd[2] = chip->analog_capture_volume[channel];
+	} else {
+		rmh.cmd[0] |= IO_NUM_REG_OUT_ANA_LEVEL;
+		if (chip->analog_playback_active[channel])
+			vol = chip->analog_playback_volume[channel];
+		else
+			vol = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN;
+		rmh.cmd[2] = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX - vol;	/* playback analog levels are inversed */
+	}
+	rmh.cmd[1]  = 1 << ((2 * chip->chip_idx) + channel);	/* audio mask */
+	rmh.cmd_len = 3;
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	if (err < 0) {
+		snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d) "
+			   "is_capture(%d) err(%x)\n", chip->chip_idx, is_capture, err);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/*
+ * analog level control
+ */
+static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	if (kcontrol->private_value == 0) {	/* playback */
+		uinfo->value.integer.min = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN;	/* -128 dB */
+		uinfo->value.integer.max = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX;	/* 0 dB */
+	} else {				/* capture */
+		uinfo->value.integer.min = PCXHR_ANALOG_CAPTURE_LEVEL_MIN;	/* -96 dB */
+		uinfo->value.integer.max = PCXHR_ANALOG_CAPTURE_LEVEL_MAX;	/* 31.5 dB */
+	}
+	return 0;
+}
+
+static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	down(&chip->mgr->mixer_mutex);
+	if (kcontrol->private_value == 0) {	/* playback */
+		ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
+		ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
+	} else {				/* capture */
+		ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
+		ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
+	}
+	up(&chip->mgr->mixer_mutex);
+	return 0;
+}
+
+static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int changed = 0;
+	int is_capture, i;
+
+	down(&chip->mgr->mixer_mutex);
+	is_capture = (kcontrol->private_value != 0);
+	for (i = 0; i < 2; i++) {
+		int  new_volume = ucontrol->value.integer.value[i];
+		int* stored_volume = is_capture ? &chip->analog_capture_volume[i] :
+			&chip->analog_playback_volume[i];
+		if (*stored_volume != new_volume) {
+			*stored_volume = new_volume;
+			changed = 1;
+			pcxhr_update_analog_audio_level(chip, is_capture, i);
+		}
+	}
+	up(&chip->mgr->mixer_mutex);
+	return changed;
+}
+
+static struct snd_kcontrol_new pcxhr_control_analog_level = {
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	/* name will be filled later */
+	.info =		pcxhr_analog_vol_info,
+	.get =		pcxhr_analog_vol_get,
+	.put =		pcxhr_analog_vol_put,
+};
+
+/* shared */
+static int pcxhr_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+	uinfo->count = 2;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = 1;
+	return 0;
+}
+
+static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+
+	down(&chip->mgr->mixer_mutex);
+	ucontrol->value.integer.value[0] = chip->analog_playback_active[0];
+	ucontrol->value.integer.value[1] = chip->analog_playback_active[1];
+	up(&chip->mgr->mixer_mutex);
+	return 0;
+}
+
+static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int i, changed = 0;
+	down(&chip->mgr->mixer_mutex);
+	for(i = 0; i < 2; i++) {
+		if (chip->analog_playback_active[i] != ucontrol->value.integer.value[i]) {
+			chip->analog_playback_active[i] = ucontrol->value.integer.value[i];
+			changed = 1;
+			pcxhr_update_analog_audio_level(chip, 0, i);	/* update playback levels */
+		}
+	}
+	up(&chip->mgr->mixer_mutex);
+	return changed;
+}
+
+static struct snd_kcontrol_new pcxhr_control_output_switch = {
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"Master Playback Switch",
+	.info =		pcxhr_sw_info,		/* shared */
+	.get =		pcxhr_audio_sw_get,
+	.put =		pcxhr_audio_sw_put
+};
+
+
+#define PCXHR_DIGITAL_LEVEL_MIN		0x000	/* -110 dB */
+#define PCXHR_DIGITAL_LEVEL_MAX		0x1ff	/* +18 dB */
+#define PCXHR_DIGITAL_ZERO_LEVEL	0x1b7	/*  0 dB */
+
+
+#define MORE_THAN_ONE_STREAM_LEVEL	0x000001
+#define VALID_STREAM_PAN_LEVEL_MASK	0x800000
+#define VALID_STREAM_LEVEL_MASK		0x400000
+#define VALID_STREAM_LEVEL_1_MASK	0x200000
+#define VALID_STREAM_LEVEL_2_MASK	0x100000
+
+static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
+{
+	int err;
+	struct pcxhr_rmh rmh;
+	struct pcxhr_pipe *pipe = &chip->playback_pipe;
+	int left, right;
+
+	if (chip->digital_playback_active[idx][0])
+		left = chip->digital_playback_volume[idx][0];
+	else
+		left = PCXHR_DIGITAL_LEVEL_MIN;
+	if (chip->digital_playback_active[idx][1])
+		right = chip->digital_playback_volume[idx][1];
+	else
+		right = PCXHR_DIGITAL_LEVEL_MIN;
+
+	pcxhr_init_rmh(&rmh, CMD_STREAM_OUT_LEVEL_ADJUST);
+	/* add pipe and stream mask */
+	pcxhr_set_pipe_cmd_params(&rmh, 0, pipe->first_audio, 0, 1<<idx);
+	/* volume left->left / right->right panoramic level */
+	rmh.cmd[0] |= MORE_THAN_ONE_STREAM_LEVEL;
+	rmh.cmd[2]  = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_1_MASK;
+	rmh.cmd[2] |= (left << 10);
+	rmh.cmd[3]  = VALID_STREAM_PAN_LEVEL_MASK | VALID_STREAM_LEVEL_2_MASK;
+	rmh.cmd[3] |= right;
+	rmh.cmd_len = 4;
+
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	if (err < 0) {
+		snd_printk(KERN_DEBUG "error update_playback_stream_level "
+			   "card(%d) err(%x)\n", chip->chip_idx, err);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+#define AUDIO_IO_HAS_MUTE_LEVEL		0x400000
+#define AUDIO_IO_HAS_MUTE_MONITOR_1	0x200000
+#define VALID_AUDIO_IO_DIGITAL_LEVEL	0x000001
+#define VALID_AUDIO_IO_MONITOR_LEVEL	0x000002
+#define VALID_AUDIO_IO_MUTE_LEVEL	0x000004
+#define VALID_AUDIO_IO_MUTE_MONITOR_1	0x000008
+
+static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, int channel)
+{
+	int err;
+	struct pcxhr_rmh rmh;
+	struct pcxhr_pipe *pipe;
+
+	if (capture)
+		pipe = &chip->capture_pipe[0];
+	else
+		pipe = &chip->playback_pipe;
+
+	pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
+	/* add channel mask */
+	pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0, 1 << (channel + pipe->first_audio));
+	/* TODO : if mask (3 << pipe->first_audio) is used, left and right channel
+	 * will be programmed to the same params
+	 */
+	if (capture) {
+		rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
+		/* VALID_AUDIO_IO_MUTE_LEVEL not yet handled (capture pipe level) */
+		rmh.cmd[2] = chip->digital_capture_volume[channel];
+	} else {
+		rmh.cmd[0] |= VALID_AUDIO_IO_MONITOR_LEVEL | VALID_AUDIO_IO_MUTE_MONITOR_1;
+		/* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL not yet
+		 * handled (playback pipe level)
+		 */
+		rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
+		if (chip->monitoring_active[channel] == 0)
+			rmh.cmd[2] |= AUDIO_IO_HAS_MUTE_MONITOR_1;
+	}
+	rmh.cmd_len = 3;
+
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	if(err<0) {
+		snd_printk(KERN_DEBUG "error update_audio_level card(%d) err(%x)\n",
+			   chip->chip_idx, err);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+
+/* shared */
+static int pcxhr_digital_vol_info(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 2;
+	uinfo->value.integer.min = PCXHR_DIGITAL_LEVEL_MIN;   /* -109.5 dB */
+	uinfo->value.integer.max = PCXHR_DIGITAL_LEVEL_MAX;   /*   18.0 dB */
+	return 0;
+}
+
+
+static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);		/* index */
+	int *stored_volume;
+	int is_capture = kcontrol->private_value;
+
+	down(&chip->mgr->mixer_mutex);
+	if (is_capture)
+		stored_volume = chip->digital_capture_volume;		/* digital capture */
+	else
+		stored_volume = chip->digital_playback_volume[idx];	/* digital playback */
+	ucontrol->value.integer.value[0] = stored_volume[0];
+	ucontrol->value.integer.value[1] = stored_volume[1];
+	up(&chip->mgr->mixer_mutex);
+	return 0;
+}
+
+static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);		/* index */
+	int changed = 0;
+	int is_capture = kcontrol->private_value;
+	int *stored_volume;
+	int i;
+
+	down(&chip->mgr->mixer_mutex);
+	if (is_capture)
+		stored_volume = chip->digital_capture_volume;		/* digital capture */
+	else
+		stored_volume = chip->digital_playback_volume[idx];	/* digital playback */
+	for (i = 0; i < 2; i++) {
+		if (stored_volume[i] != ucontrol->value.integer.value[i]) {
+			stored_volume[i] = ucontrol->value.integer.value[i];
+			changed = 1;
+			if (is_capture)	/* update capture volume */
+				pcxhr_update_audio_pipe_level(chip, 1, i);
+		}
+	}
+	if (! is_capture && changed)
+		pcxhr_update_playback_stream_level(chip, idx);	/* update playback volume */
+	up(&chip->mgr->mixer_mutex);
+	return changed;
+}
+
+static struct snd_kcontrol_new snd_pcxhr_pcm_vol =
+{
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	/* name will be filled later */
+	/* count will be filled later */
+	.info =		pcxhr_digital_vol_info,		/* shared */
+	.get =		pcxhr_pcm_vol_get,
+	.put =		pcxhr_pcm_vol_put,
+};
+
+
+static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
+
+	down(&chip->mgr->mixer_mutex);
+	ucontrol->value.integer.value[0] = chip->digital_playback_active[idx][0];
+	ucontrol->value.integer.value[1] = chip->digital_playback_active[idx][1];
+	up(&chip->mgr->mixer_mutex);
+	return 0;
+}
+
+static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int changed = 0;
+	int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
+	int i, j;
+
+	down(&chip->mgr->mixer_mutex);
+	j = idx;
+	for (i = 0; i < 2; i++) {
+		if (chip->digital_playback_active[j][i] != ucontrol->value.integer.value[i]) {
+			chip->digital_playback_active[j][i] = ucontrol->value.integer.value[i];
+			changed = 1;
+		}
+	}
+	if (changed)
+		pcxhr_update_playback_stream_level(chip, idx);
+	up(&chip->mgr->mixer_mutex);
+	return changed;
+}
+
+static struct snd_kcontrol_new pcxhr_control_pcm_switch = {
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"PCM Playback Switch",
+	.count =	PCXHR_PLAYBACK_STREAMS,
+	.info =		pcxhr_sw_info,		/* shared */
+	.get =		pcxhr_pcm_sw_get,
+	.put =		pcxhr_pcm_sw_put
+};
+
+
+/*
+ * monitoring level control
+ */
+
+static int pcxhr_monitor_vol_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	down(&chip->mgr->mixer_mutex);
+	ucontrol->value.integer.value[0] = chip->monitoring_volume[0];
+	ucontrol->value.integer.value[1] = chip->monitoring_volume[1];
+	up(&chip->mgr->mixer_mutex);
+	return 0;
+}
+
+static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int changed = 0;
+	int i;
+
+	down(&chip->mgr->mixer_mutex);
+	for (i = 0; i < 2; i++) {
+		if (chip->monitoring_volume[i] != ucontrol->value.integer.value[i]) {
+			chip->monitoring_volume[i] = ucontrol->value.integer.value[i];
+			if(chip->monitoring_active[i])	/* do only when monitoring is unmuted */
+				/* update monitoring volume and mute */
+				pcxhr_update_audio_pipe_level(chip, 0, i);
+			changed = 1;
+		}
+	}
+	up(&chip->mgr->mixer_mutex);
+	return changed;
+}
+
+static struct snd_kcontrol_new pcxhr_control_monitor_vol = {
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         "Monitoring Volume",
+	.info =		pcxhr_digital_vol_info,		/* shared */
+	.get =		pcxhr_monitor_vol_get,
+	.put =		pcxhr_monitor_vol_put,
+};
+
+/*
+ * monitoring switch control
+ */
+
+static int pcxhr_monitor_sw_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	down(&chip->mgr->mixer_mutex);
+	ucontrol->value.integer.value[0] = chip->monitoring_active[0];
+	ucontrol->value.integer.value[1] = chip->monitoring_active[1];
+	up(&chip->mgr->mixer_mutex);
+	return 0;
+}
+
+static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int changed = 0;
+	int i;
+
+	down(&chip->mgr->mixer_mutex);
+	for (i = 0; i < 2; i++) {
+		if (chip->monitoring_active[i] != ucontrol->value.integer.value[i]) {
+			chip->monitoring_active[i] = ucontrol->value.integer.value[i];
+			changed |= (1<<i); /* mask 0x01 and 0x02 */
+		}
+	}
+	if(changed & 0x01)
+		/* update left monitoring volume and mute */
+		pcxhr_update_audio_pipe_level(chip, 0, 0);
+	if(changed & 0x02)
+		/* update right monitoring volume and mute */
+		pcxhr_update_audio_pipe_level(chip, 0, 1);
+
+	up(&chip->mgr->mixer_mutex);
+	return (changed != 0);
+}
+
+static struct snd_kcontrol_new pcxhr_control_monitor_sw = {
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =         "Monitoring Switch",
+	.info =         pcxhr_sw_info,		/* shared */
+	.get =          pcxhr_monitor_sw_get,
+	.put =          pcxhr_monitor_sw_put
+};
+
+
+
+/*
+ * audio source select
+ */
+#define PCXHR_SOURCE_AUDIO01_UER	0x000100
+#define PCXHR_SOURCE_AUDIO01_SYNC	0x000200
+#define PCXHR_SOURCE_AUDIO23_UER	0x000400
+#define PCXHR_SOURCE_AUDIO45_UER	0x001000
+#define PCXHR_SOURCE_AUDIO67_UER	0x040000
+
+static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
+{
+	struct pcxhr_rmh rmh;
+	unsigned int mask, reg;
+	unsigned int codec;
+	int err, use_src, changed;
+
+	switch (chip->chip_idx) {
+	case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
+	case 1 : mask = PCXHR_SOURCE_AUDIO23_UER; codec = CS8420_23_CS; break;
+	case 2 : mask = PCXHR_SOURCE_AUDIO45_UER; codec = CS8420_45_CS; break;
+	case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
+	default: return -EINVAL;
+	}
+	reg = 0;	/* audio source from analog plug */
+	use_src = 0;	/* do not activate codec SRC */
+
+	if (chip->audio_capture_source != 0) {
+		reg = mask;	/* audio source from digital plug */
+		if (chip->audio_capture_source == 2)
+			use_src = 1;
+	}
+	/* set the input source */
+	pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
+	/* resync them (otherwise channel inversion possible) */
+	if (changed) {
+		pcxhr_init_rmh(&rmh, CMD_RESYNC_AUDIO_INPUTS);
+		rmh.cmd[0] |= (1 << chip->chip_idx);
+		err = pcxhr_send_msg(chip->mgr, &rmh);
+		if (err)
+			return err;
+	}
+	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);	/* set codec SRC on off */
+	rmh.cmd_len = 3;
+	rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
+	rmh.cmd[1] = codec;
+	rmh.cmd[2] = (CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x54);
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	if(err)
+		return err;
+	rmh.cmd[2] = (CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x49);
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	return err;
+}
+
+static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
+{
+	static char *texts[3] = {"Analog", "Digital", "Digi+SRC"};
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = 3;
+	if (uinfo->value.enumerated.item > 2)
+		uinfo->value.enumerated.item = 2;
+	strcpy(uinfo->value.enumerated.name,
+		texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int pcxhr_audio_src_get(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.enumerated.item[0] = chip->audio_capture_source;
+	return 0;
+}
+
+static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int ret = 0;
+
+	down(&chip->mgr->mixer_mutex);
+	if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) {
+		chip->audio_capture_source = ucontrol->value.enumerated.item[0];
+		pcxhr_set_audio_source(chip);
+		ret = 1;
+	}
+	up(&chip->mgr->mixer_mutex);
+	return ret;
+}
+
+static struct snd_kcontrol_new pcxhr_control_audio_src = {
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"Capture Source",
+	.info =		pcxhr_audio_src_info,
+	.get =		pcxhr_audio_src_get,
+	.put =		pcxhr_audio_src_put,
+};
+
+
+/*
+ * clock type selection
+ * enum pcxhr_clock_type {
+ *		PCXHR_CLOCK_TYPE_INTERNAL = 0,
+ *		PCXHR_CLOCK_TYPE_WORD_CLOCK,
+ *		PCXHR_CLOCK_TYPE_AES_SYNC,
+ *		PCXHR_CLOCK_TYPE_AES_1,
+ *		PCXHR_CLOCK_TYPE_AES_2,
+ *		PCXHR_CLOCK_TYPE_AES_3,
+ *		PCXHR_CLOCK_TYPE_AES_4,
+ *	};
+ */
+
+static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
+{
+	static char *texts[7] = {
+		"Internal", "WordClock", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4"
+	};
+	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
+	int clock_items = 3 + mgr->capture_chips;
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = clock_items;
+	if (uinfo->value.enumerated.item >= clock_items)
+		uinfo->value.enumerated.item = clock_items-1;
+	strcpy(uinfo->value.enumerated.name,
+		texts[uinfo->value.enumerated.item]);
+	return 0;
+}
+
+static int pcxhr_clock_type_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
+	ucontrol->value.enumerated.item[0] = mgr->use_clock_type;
+	return 0;
+}
+
+static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
+	int rate, ret = 0;
+
+	down(&mgr->mixer_mutex);
+	if (mgr->use_clock_type != ucontrol->value.enumerated.item[0]) {
+		down(&mgr->setup_mutex);
+		mgr->use_clock_type = ucontrol->value.enumerated.item[0];
+		if (mgr->use_clock_type)
+			pcxhr_get_external_clock(mgr, mgr->use_clock_type, &rate);
+		else
+			rate = mgr->sample_rate;
+		if (rate) {
+			pcxhr_set_clock(mgr, rate);
+			if (mgr->sample_rate)
+				mgr->sample_rate = rate;
+		}
+		up(&mgr->setup_mutex);
+		ret = 1;	/* return 1 even if the set was not done. ok ? */
+	}
+	up(&mgr->mixer_mutex);
+	return ret;
+}
+
+static struct snd_kcontrol_new pcxhr_control_clock_type = {
+	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name =		"Clock Mode",
+	.info =		pcxhr_clock_type_info,
+	.get =		pcxhr_clock_type_get,
+	.put =		pcxhr_clock_type_put,
+};
+
+/*
+ * clock rate control
+ * specific control that scans the sample rates on the external plugs
+ */
+static int pcxhr_clock_rate_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
+{
+	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 3 + mgr->capture_chips;
+	uinfo->value.integer.min = 0;		/* clock not present */
+	uinfo->value.integer.max = 192000;	/* max sample rate 192 kHz */
+	return 0;
+}
+
+static int pcxhr_clock_rate_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
+	int i, err, rate;
+
+	down(&mgr->mixer_mutex);
+	for(i = 0; i < 3 + mgr->capture_chips; i++) {
+		if (i == PCXHR_CLOCK_TYPE_INTERNAL)
+			rate = mgr->sample_rate_real;
+		else {
+			err = pcxhr_get_external_clock(mgr, i, &rate);
+			if (err)
+				break;
+		}
+		ucontrol->value.integer.value[i] = rate;
+	}
+	up(&mgr->mixer_mutex);
+	return 0;
+}
+
+static struct snd_kcontrol_new pcxhr_control_clock_rate = {
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+	.iface =	SNDRV_CTL_ELEM_IFACE_CARD,
+	.name =		"Clock Rates",
+	.info =		pcxhr_clock_rate_info,
+	.get =		pcxhr_clock_rate_get,
+};
+
+/*
+ * IEC958 status bits
+ */
+static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+	uinfo->count = 1;
+	return 0;
+}
+
+static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char* aes_bits)
+{
+	int i, err;
+	unsigned char temp;
+	struct pcxhr_rmh rmh;
+
+	pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
+	rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
+	switch (chip->chip_idx) {
+	case 0:	rmh.cmd[1] = CS8420_01_CS; break;	/* use CS8416_01_CS for AES SYNC plug */
+	case 1:	rmh.cmd[1] = CS8420_23_CS; break;
+	case 2:	rmh.cmd[1] = CS8420_45_CS; break;
+	case 3:	rmh.cmd[1] = CS8420_67_CS; break;
+	default: return -EINVAL;
+	}
+	switch (aes_idx) {
+	case 0:	rmh.cmd[2] = CS8420_CSB0; break;	/* use CS8416_CSBx for AES SYNC plug */
+	case 1:	rmh.cmd[2] = CS8420_CSB1; break;
+	case 2:	rmh.cmd[2] = CS8420_CSB2; break;
+	case 3:	rmh.cmd[2] = CS8420_CSB3; break;
+	case 4:	rmh.cmd[2] = CS8420_CSB4; break;
+	default: return -EINVAL;
+	}
+	rmh.cmd[1] &= 0x0fffff;			/* size and code the chip id for the fpga */
+	rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI;	/* chip signature + map for spi read */
+	rmh.cmd_len = 3;
+	err = pcxhr_send_msg(chip->mgr, &rmh);
+	if (err)
+		return err;
+	temp = 0;
+	for (i = 0; i < 8; i++) {
+		/* attention : reversed bit order (not with CS8416_01_CS) */
+		temp <<= 1;
+		if (rmh.stat[1] & (1 << i))
+			temp |= 1;
+	}
+	snd_printdd("read iec958 AES %d byte %d = 0x%x\n", chip->chip_idx, aes_idx, temp);
+	*aes_bits = temp;
+	return 0;
+}
+
+static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	unsigned char aes_bits;
+	int i, err;
+
+	down(&chip->mgr->mixer_mutex);
+	for(i = 0; i < 5; i++) {
+		if (kcontrol->private_value == 0)	/* playback */
+			aes_bits = chip->aes_bits[i];
+		else {				/* capture */
+			err = pcxhr_iec958_capture_byte(chip, i, &aes_bits);
+			if (err)
+				break;
+		}
+		ucontrol->value.iec958.status[i] = aes_bits;
+	}
+	up(&chip->mgr->mixer_mutex);
+        return 0;
+}
+
+static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
+{
+	int i;
+	for (i = 0; i < 5; i++)
+		ucontrol->value.iec958.status[i] = 0xff;
+        return 0;
+}
+
+static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char aes_bits)
+{
+	int i, err, cmd;
+	unsigned char new_bits = aes_bits;
+	unsigned char old_bits = chip->aes_bits[aes_idx];
+	struct pcxhr_rmh rmh;
+
+	for (i = 0; i < 8; i++) {
+		if ((old_bits & 0x01) != (new_bits & 0x01)) {
+			cmd = chip->chip_idx & 0x03;		/* chip index 0..3 */
+			if(chip->chip_idx > 3)
+				/* new bit used if chip_idx>3 (PCX1222HR) */
+				cmd |= 1 << 22;
+			cmd |= ((aes_idx << 3) + i) << 2;	/* add bit offset */
+			cmd |= (new_bits & 0x01) << 23;		/* add bit value */
+			pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
+			rmh.cmd[0] |= IO_NUM_REG_CUER;
+			rmh.cmd[1] = cmd;
+			rmh.cmd_len = 2;
+			snd_printdd("write iec958 AES %d byte %d bit %d (cmd %x)\n",
+				    chip->chip_idx, aes_idx, i, cmd);
+			err = pcxhr_send_msg(chip->mgr, &rmh);
+			if (err)
+				return err;
+		}
+		old_bits >>= 1;
+		new_bits >>= 1;
+	}
+	chip->aes_bits[aes_idx] = aes_bits;
+	return 0;
+}
+
+static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
+	int i, changed = 0;
+
+	/* playback */
+	down(&chip->mgr->mixer_mutex);
+	for (i = 0; i < 5; i++) {
+		if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {
+			pcxhr_iec958_update_byte(chip, i, ucontrol->value.iec958.status[i]);
+			changed = 1;
+		}
+	}
+	up(&chip->mgr->mixer_mutex);
+	return changed;
+}
+
+static struct snd_kcontrol_new pcxhr_control_playback_iec958_mask = {
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,MASK),
+	.info =		pcxhr_iec958_info,
+	.get =		pcxhr_iec958_mask_get
+};
+static struct snd_kcontrol_new pcxhr_control_playback_iec958 = {
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+	.info =         pcxhr_iec958_info,
+	.get =          pcxhr_iec958_get,
+	.put =          pcxhr_iec958_put,
+	.private_value = 0 /* playback */
+};
+
+static struct snd_kcontrol_new pcxhr_control_capture_iec958_mask = {
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =		SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK),
+	.info =		pcxhr_iec958_info,
+	.get =		pcxhr_iec958_mask_get
+};
+static struct snd_kcontrol_new pcxhr_control_capture_iec958 = {
+	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
+	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
+	.name =         SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
+	.info =         pcxhr_iec958_info,
+	.get =          pcxhr_iec958_get,
+	.private_value = 1 /* capture */
+};
+
+static void pcxhr_init_audio_levels(struct snd_pcxhr *chip)
+{
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (chip->nb_streams_play) {
+			int j;
+			/* at boot time the digital volumes are unmuted 0dB */
+			for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) {
+				chip->digital_playback_active[j][i] = 1;
+				chip->digital_playback_volume[j][i] = PCXHR_DIGITAL_ZERO_LEVEL;
+			}
+			/* after boot, only two bits are set on the uer interface */
+			chip->aes_bits[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_FS_48000;
+/* only for test purpose, remove later */
+#ifdef CONFIG_SND_DEBUG
+			/* analog volumes for playback (is LEVEL_MIN after boot) */
+			chip->analog_playback_active[i] = 1;
+			chip->analog_playback_volume[i] = PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL;
+			pcxhr_update_analog_audio_level(chip, 0, i);
+#endif
+/* test end */
+		}
+		if (chip->nb_streams_capt) {
+			/* at boot time the digital volumes are unmuted 0dB */
+			chip->digital_capture_volume[i] = PCXHR_DIGITAL_ZERO_LEVEL;
+/* only for test purpose, remove later */
+#ifdef CONFIG_SND_DEBUG
+			/* analog volumes for playback (is LEVEL_MIN after boot) */
+			chip->analog_capture_volume[i]  = PCXHR_ANALOG_CAPTURE_ZERO_LEVEL;
+			pcxhr_update_analog_audio_level(chip, 1, i);
+#endif
+/* test end */
+		}
+	}
+
+	return;
+}
+
+
+int pcxhr_create_mixer(struct pcxhr_mgr *mgr)
+{
+	struct snd_pcxhr *chip;
+	int err, i;
+
+	init_MUTEX(&mgr->mixer_mutex); /* can be in another place */
+
+	for (i = 0; i < mgr->num_cards; i++) {
+		struct snd_kcontrol_new temp;
+		chip = mgr->chip[i];
+
+		if (chip->nb_streams_play) {
+			/* analog output level control */
+			temp = pcxhr_control_analog_level;
+			temp.name = "Master Playback Volume";
+			temp.private_value = 0; /* playback */
+			if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+				return err;
+			/* output mute controls */
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_output_switch,
+							    chip))) < 0)
+				return err;
+			
+			temp = snd_pcxhr_pcm_vol;
+			temp.name = "PCM Playback Volume";
+			temp.count = PCXHR_PLAYBACK_STREAMS;
+			temp.private_value = 0; /* playback */
+			if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+				return err;
+
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_pcm_switch,
+							    chip))) < 0)
+				return err;
+
+			/* IEC958 controls */
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_playback_iec958_mask,
+							    chip))) < 0)
+				return err;
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_playback_iec958,
+							    chip))) < 0)
+				return err;
+		}
+		if (chip->nb_streams_capt) {
+			/* analog input level control only on first two chips !*/
+			temp = pcxhr_control_analog_level;
+			temp.name = "Master Capture Volume";
+			temp.private_value = 1; /* capture */
+			if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+				return err;
+
+			temp = snd_pcxhr_pcm_vol;
+			temp.name = "PCM Capture Volume";
+			temp.count = 1;
+			temp.private_value = 1; /* capture */
+			if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0)
+				return err;
+			/* Audio source */
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_audio_src,
+							    chip))) < 0)
+				return err;
+			/* IEC958 controls */
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_capture_iec958_mask,
+							    chip))) < 0)
+				return err;
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_capture_iec958,
+							    chip))) < 0)
+				return err;
+		}
+		/* monitoring only if playback and capture device available */
+		if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) {
+			/* monitoring */
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_monitor_vol,
+							    chip))) < 0)
+				return err;
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_monitor_sw,
+							    chip))) < 0)
+				return err;
+		}
+
+		if (i == 0) {
+			/* clock mode only one control per pcxhr */
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_clock_type,
+							    mgr))) < 0)
+				return err;
+			/* non standard control used to scan the external clock presence/frequencies */
+			if ((err = snd_ctl_add(chip->card,
+					       snd_ctl_new1(&pcxhr_control_clock_rate,
+							    mgr))) < 0)
+				return err;
+		}
+
+		/* init values for the mixer data */
+		pcxhr_init_audio_levels(chip);
+	}
+
+	return 0;
+}
diff --git a/sound/pci/pcxhr/pcxhr_mixer.h b/sound/pci/pcxhr/pcxhr_mixer.h
new file mode 100644
index 0000000..4348d0e
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_mixer.h
@@ -0,0 +1,29 @@
+/*
+ * Driver for Digigram pcxhr compatible soundcards
+ *
+ * include file for mixer
+ *
+ * Copyright (c) 2004 by Digigram <alsa@digigram.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 __SOUND_PCXHR_MIXER_H
+#define __SOUND_PCXHR_MIXER_H
+
+/* exported */
+int pcxhr_create_mixer(struct pcxhr_mgr *mgr);
+
+#endif /* __SOUND_PCXHR_MIXER_H */
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index 783df76..0cbef5f 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -192,7 +192,7 @@
 #define RME32_PRO_REVISION_WITH_8414 150
 
 
-typedef struct snd_rme32 {
+struct rme32 {
 	spinlock_t lock;
 	int irq;
 	unsigned long port;
@@ -205,8 +205,8 @@
 
 	u8 rev;			/* card revision number */
 
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
 
 	int playback_frlog;	/* log2 of framesize */
 	int capture_frlog;
@@ -217,15 +217,15 @@
 	unsigned int fullduplex_mode;
 	int running;
 
-	snd_pcm_indirect_t playback_pcm;
-	snd_pcm_indirect_t capture_pcm;
+	struct snd_pcm_indirect playback_pcm;
+	struct snd_pcm_indirect capture_pcm;
 
-	snd_card_t *card;
-	snd_pcm_t *spdif_pcm;
-	snd_pcm_t *adat_pcm;
+	struct snd_card *card;
+	struct snd_pcm *spdif_pcm;
+	struct snd_pcm *adat_pcm;
 	struct pci_dev *pci;
-	snd_kcontrol_t *spdif_ctl;
-} rme32_t;
+	struct snd_kcontrol *spdif_ctl;
+};
 
 static struct pci_device_id snd_rme32_ids[] = {
 	{PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32,
@@ -242,17 +242,17 @@
 #define RME32_ISWORKING(rme32) ((rme32)->wcreg & RME32_WCR_START)
 #define RME32_PRO_WITH_8414(rme32) ((rme32)->pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO && (rme32)->rev == RME32_PRO_REVISION_WITH_8414)
 
-static int snd_rme32_playback_prepare(snd_pcm_substream_t * substream);
+static int snd_rme32_playback_prepare(struct snd_pcm_substream *substream);
 
-static int snd_rme32_capture_prepare(snd_pcm_substream_t * substream);
+static int snd_rme32_capture_prepare(struct snd_pcm_substream *substream);
 
-static int snd_rme32_pcm_trigger(snd_pcm_substream_t * substream, int cmd);
+static int snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
 
-static void snd_rme32_proc_init(rme32_t * rme32);
+static void snd_rme32_proc_init(struct rme32 * rme32);
 
-static int snd_rme32_create_switches(snd_card_t * card, rme32_t * rme32);
+static int snd_rme32_create_switches(struct snd_card *card, struct rme32 * rme32);
 
-static inline unsigned int snd_rme32_pcm_byteptr(rme32_t * rme32)
+static inline unsigned int snd_rme32_pcm_byteptr(struct rme32 * rme32)
 {
 	return (readl(rme32->iobase + RME32_IO_GET_POS)
 		& RME32_RCR_AUDIO_ADDR_MASK);
@@ -272,11 +272,11 @@
 }
 
 /* silence callback for halfduplex mode */
-static int snd_rme32_playback_silence(snd_pcm_substream_t * substream, int channel,	/* not used (interleaved data) */
+static int snd_rme32_playback_silence(struct snd_pcm_substream *substream, int channel,	/* not used (interleaved data) */
 				      snd_pcm_uframes_t pos,
 				      snd_pcm_uframes_t count)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	count <<= rme32->playback_frlog;
 	pos <<= rme32->playback_frlog;
 	memset_io(rme32->iobase + RME32_IO_DATA_BUFFER + pos, 0, count);
@@ -284,11 +284,11 @@
 }
 
 /* copy callback for halfduplex mode */
-static int snd_rme32_playback_copy(snd_pcm_substream_t * substream, int channel,	/* not used (interleaved data) */
+static int snd_rme32_playback_copy(struct snd_pcm_substream *substream, int channel,	/* not used (interleaved data) */
 				   snd_pcm_uframes_t pos,
 				   void __user *src, snd_pcm_uframes_t count)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	count <<= rme32->playback_frlog;
 	pos <<= rme32->playback_frlog;
 	if (copy_from_user_toio(rme32->iobase + RME32_IO_DATA_BUFFER + pos,
@@ -298,11 +298,11 @@
 }
 
 /* copy callback for halfduplex mode */
-static int snd_rme32_capture_copy(snd_pcm_substream_t * substream, int channel,	/* not used (interleaved data) */
+static int snd_rme32_capture_copy(struct snd_pcm_substream *substream, int channel,	/* not used (interleaved data) */
 				  snd_pcm_uframes_t pos,
 				  void __user *dst, snd_pcm_uframes_t count)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	count <<= rme32->capture_frlog;
 	pos <<= rme32->capture_frlog;
 	if (copy_to_user_fromio(dst,
@@ -315,7 +315,7 @@
 /*
  * SPDIF I/O capabilites (half-duplex mode)
  */
-static snd_pcm_hardware_t snd_rme32_spdif_info = {
+static struct snd_pcm_hardware snd_rme32_spdif_info = {
 	.info =		(SNDRV_PCM_INFO_MMAP_IOMEM |
 			 SNDRV_PCM_INFO_MMAP_VALID |
 			 SNDRV_PCM_INFO_INTERLEAVED | 
@@ -341,7 +341,7 @@
 /*
  * ADAT I/O capabilites (half-duplex mode)
  */
-static snd_pcm_hardware_t snd_rme32_adat_info =
+static struct snd_pcm_hardware snd_rme32_adat_info =
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_MMAP_VALID |
@@ -366,7 +366,7 @@
 /*
  * SPDIF I/O capabilites (full-duplex mode)
  */
-static snd_pcm_hardware_t snd_rme32_spdif_fd_info = {
+static struct snd_pcm_hardware snd_rme32_spdif_fd_info = {
 	.info =		(SNDRV_PCM_INFO_MMAP |
 			 SNDRV_PCM_INFO_MMAP_VALID |
 			 SNDRV_PCM_INFO_INTERLEAVED | 
@@ -392,7 +392,7 @@
 /*
  * ADAT I/O capabilites (full-duplex mode)
  */
-static snd_pcm_hardware_t snd_rme32_adat_fd_info =
+static struct snd_pcm_hardware snd_rme32_adat_fd_info =
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP |
 			      SNDRV_PCM_INFO_MMAP_VALID |
@@ -414,14 +414,14 @@
 	.fifo_size =	    0,
 };
 
-static void snd_rme32_reset_dac(rme32_t *rme32)
+static void snd_rme32_reset_dac(struct rme32 *rme32)
 {
         writel(rme32->wcreg | RME32_WCR_PD,
                rme32->iobase + RME32_IO_CONTROL_REGISTER);
         writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 }
 
-static int snd_rme32_playback_getrate(rme32_t * rme32)
+static int snd_rme32_playback_getrate(struct rme32 * rme32)
 {
 	int rate;
 
@@ -443,7 +443,7 @@
 	return (rme32->wcreg & RME32_WCR_DS_BM) ? rate << 1 : rate;
 }
 
-static int snd_rme32_capture_getrate(rme32_t * rme32, int *is_adat)
+static int snd_rme32_capture_getrate(struct rme32 * rme32, int *is_adat)
 {
 	int n;
 
@@ -505,7 +505,7 @@
 	return -1;
 }
 
-static int snd_rme32_playback_setrate(rme32_t * rme32, int rate)
+static int snd_rme32_playback_setrate(struct rme32 * rme32, int rate)
 {
         int ds;
 
@@ -561,7 +561,7 @@
 	return 0;
 }
 
-static int snd_rme32_setclockmode(rme32_t * rme32, int mode)
+static int snd_rme32_setclockmode(struct rme32 * rme32, int mode)
 {
 	switch (mode) {
 	case RME32_CLOCKMODE_SLAVE:
@@ -591,13 +591,13 @@
 	return 0;
 }
 
-static int snd_rme32_getclockmode(rme32_t * rme32)
+static int snd_rme32_getclockmode(struct rme32 * rme32)
 {
 	return ((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_0) & 1) +
 	    (((rme32->wcreg >> RME32_WCR_BITPOS_FREQ_1) & 1) << 1);
 }
 
-static int snd_rme32_setinputtype(rme32_t * rme32, int type)
+static int snd_rme32_setinputtype(struct rme32 * rme32, int type)
 {
 	switch (type) {
 	case RME32_INPUT_OPTICAL:
@@ -623,14 +623,14 @@
 	return 0;
 }
 
-static int snd_rme32_getinputtype(rme32_t * rme32)
+static int snd_rme32_getinputtype(struct rme32 * rme32)
 {
 	return ((rme32->wcreg >> RME32_WCR_BITPOS_INP_0) & 1) +
 	    (((rme32->wcreg >> RME32_WCR_BITPOS_INP_1) & 1) << 1);
 }
 
 static void
-snd_rme32_setframelog(rme32_t * rme32, int n_channels, int is_playback)
+snd_rme32_setframelog(struct rme32 * rme32, int n_channels, int is_playback)
 {
 	int frlog;
 
@@ -649,7 +649,7 @@
 	}
 }
 
-static int snd_rme32_setformat(rme32_t * rme32, int format)
+static int snd_rme32_setformat(struct rme32 * rme32, int format)
 {
 	switch (format) {
 	case SNDRV_PCM_FORMAT_S16_LE:
@@ -666,12 +666,12 @@
 }
 
 static int
-snd_rme32_playback_hw_params(snd_pcm_substream_t * substream,
-			     snd_pcm_hw_params_t * params)
+snd_rme32_playback_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
 {
 	int err, rate, dummy;
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (rme32->fullduplex_mode) {
 		err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
@@ -721,12 +721,12 @@
 }
 
 static int
-snd_rme32_capture_hw_params(snd_pcm_substream_t * substream,
-			    snd_pcm_hw_params_t * params)
+snd_rme32_capture_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params)
 {
 	int err, isadat, rate;
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (rme32->fullduplex_mode) {
 		err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
@@ -782,15 +782,15 @@
 	return 0;
 }
 
-static int snd_rme32_pcm_hw_free(snd_pcm_substream_t * substream)
+static int snd_rme32_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	if (! rme32->fullduplex_mode)
 		return 0;
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static void snd_rme32_pcm_start(rme32_t * rme32, int from_pause)
+static void snd_rme32_pcm_start(struct rme32 * rme32, int from_pause)
 {
 	if (!from_pause) {
 		writel(0, rme32->iobase + RME32_IO_RESET_POS);
@@ -800,7 +800,7 @@
 	writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 }
 
-static void snd_rme32_pcm_stop(rme32_t * rme32, int to_pause)
+static void snd_rme32_pcm_stop(struct rme32 * rme32, int to_pause)
 {
 	/*
 	 * Check if there is an unconfirmed IRQ, if so confirm it, or else
@@ -821,7 +821,7 @@
 static irqreturn_t
 snd_rme32_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	rme32_t *rme32 = (rme32_t *) dev_id;
+	struct rme32 *rme32 = (struct rme32 *) dev_id;
 
 	rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	if (!(rme32->rcreg & RME32_RCR_IRQ)) {
@@ -841,13 +841,13 @@
 static unsigned int period_bytes[] = { RME32_BLOCK_SIZE };
 
 
-static snd_pcm_hw_constraint_list_t hw_constraints_period_bytes = {
+static struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = {
 	.count = ARRAY_SIZE(period_bytes),
 	.list = period_bytes,
 	.mask = 0
 };
 
-static void snd_rme32_set_buffer_constraint(rme32_t *rme32, snd_pcm_runtime_t *runtime)
+static void snd_rme32_set_buffer_constraint(struct rme32 *rme32, struct snd_pcm_runtime *runtime)
 {
 	if (! rme32->fullduplex_mode) {
 		snd_pcm_hw_constraint_minmax(runtime,
@@ -859,11 +859,11 @@
 	}
 }
 
-static int snd_rme32_playback_spdif_open(snd_pcm_substream_t * substream)
+static int snd_rme32_playback_spdif_open(struct snd_pcm_substream *substream)
 {
 	int rate, dummy;
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_pcm_set_sync(substream);
 
@@ -902,11 +902,11 @@
 	return 0;
 }
 
-static int snd_rme32_capture_spdif_open(snd_pcm_substream_t * substream)
+static int snd_rme32_capture_spdif_open(struct snd_pcm_substream *substream)
 {
 	int isadat, rate;
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_pcm_set_sync(substream);
 
@@ -941,11 +941,11 @@
 }
 
 static int
-snd_rme32_playback_adat_open(snd_pcm_substream_t *substream)
+snd_rme32_playback_adat_open(struct snd_pcm_substream *substream)
 {
 	int rate, dummy;
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	
 	snd_pcm_set_sync(substream);
 
@@ -976,11 +976,11 @@
 }
 
 static int
-snd_rme32_capture_adat_open(snd_pcm_substream_t *substream)
+snd_rme32_capture_adat_open(struct snd_pcm_substream *substream)
 {
 	int isadat, rate;
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (rme32->fullduplex_mode)
 		runtime->hw = snd_rme32_adat_fd_info;
@@ -1009,9 +1009,9 @@
 	return 0;
 }
 
-static int snd_rme32_playback_close(snd_pcm_substream_t * substream)
+static int snd_rme32_playback_close(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	int spdif = 0;
 
 	spin_lock_irq(&rme32->lock);
@@ -1028,9 +1028,9 @@
 	return 0;
 }
 
-static int snd_rme32_capture_close(snd_pcm_substream_t * substream)
+static int snd_rme32_capture_close(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&rme32->lock);
 	rme32->capture_substream = NULL;
@@ -1039,9 +1039,9 @@
 	return 0;
 }
 
-static int snd_rme32_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_rme32_playback_prepare(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&rme32->lock);
 	if (rme32->fullduplex_mode) {
@@ -1058,9 +1058,9 @@
 	return 0;
 }
 
-static int snd_rme32_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_rme32_capture_prepare(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&rme32->lock);
 	if (rme32->fullduplex_mode) {
@@ -1076,11 +1076,11 @@
 }
 
 static int
-snd_rme32_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
+snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	struct list_head *pos;
-	snd_pcm_substream_t *s;
+	struct snd_pcm_substream *s;
 
 	spin_lock(&rme32->lock);
 	snd_pcm_group_for_each(pos, substream) {
@@ -1144,33 +1144,33 @@
 
 /* pointer callback for halfduplex mode */
 static snd_pcm_uframes_t
-snd_rme32_playback_pointer(snd_pcm_substream_t * substream)
+snd_rme32_playback_pointer(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	return snd_rme32_pcm_byteptr(rme32) >> rme32->playback_frlog;
 }
 
 static snd_pcm_uframes_t
-snd_rme32_capture_pointer(snd_pcm_substream_t * substream)
+snd_rme32_capture_pointer(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	return snd_rme32_pcm_byteptr(rme32) >> rme32->capture_frlog;
 }
 
 
 /* ack and pointer callbacks for fullduplex mode */
-static void snd_rme32_pb_trans_copy(snd_pcm_substream_t *substream,
-				    snd_pcm_indirect_t *rec, size_t bytes)
+static void snd_rme32_pb_trans_copy(struct snd_pcm_substream *substream,
+				    struct snd_pcm_indirect *rec, size_t bytes)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	memcpy_toio(rme32->iobase + RME32_IO_DATA_BUFFER + rec->hw_data,
 		    substream->runtime->dma_area + rec->sw_data, bytes);
 }
 
-static int snd_rme32_playback_fd_ack(snd_pcm_substream_t *substream)
+static int snd_rme32_playback_fd_ack(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
-	snd_pcm_indirect_t *rec, *cprec;
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_indirect *rec, *cprec;
 
 	rec = &rme32->playback_pcm;
 	cprec = &rme32->capture_pcm;
@@ -1184,41 +1184,41 @@
 	return 0;
 }
 
-static void snd_rme32_cp_trans_copy(snd_pcm_substream_t *substream,
-				    snd_pcm_indirect_t *rec, size_t bytes)
+static void snd_rme32_cp_trans_copy(struct snd_pcm_substream *substream,
+				    struct snd_pcm_indirect *rec, size_t bytes)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	memcpy_fromio(substream->runtime->dma_area + rec->sw_data,
 		      rme32->iobase + RME32_IO_DATA_BUFFER + rec->hw_data,
 		      bytes);
 }
 
-static int snd_rme32_capture_fd_ack(snd_pcm_substream_t *substream)
+static int snd_rme32_capture_fd_ack(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	snd_pcm_indirect_capture_transfer(substream, &rme32->capture_pcm,
 					  snd_rme32_cp_trans_copy);
 	return 0;
 }
 
 static snd_pcm_uframes_t
-snd_rme32_playback_fd_pointer(snd_pcm_substream_t * substream)
+snd_rme32_playback_fd_pointer(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	return snd_pcm_indirect_playback_pointer(substream, &rme32->playback_pcm,
 						 snd_rme32_pcm_byteptr(rme32));
 }
 
 static snd_pcm_uframes_t
-snd_rme32_capture_fd_pointer(snd_pcm_substream_t * substream)
+snd_rme32_capture_fd_pointer(struct snd_pcm_substream *substream)
 {
-	rme32_t *rme32 = snd_pcm_substream_chip(substream);
+	struct rme32 *rme32 = snd_pcm_substream_chip(substream);
 	return snd_pcm_indirect_capture_pointer(substream, &rme32->capture_pcm,
 						snd_rme32_pcm_byteptr(rme32));
 }
 
 /* for halfduplex mode */
-static snd_pcm_ops_t snd_rme32_playback_spdif_ops = {
+static struct snd_pcm_ops snd_rme32_playback_spdif_ops = {
 	.open =		snd_rme32_playback_spdif_open,
 	.close =	snd_rme32_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1232,7 +1232,7 @@
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-static snd_pcm_ops_t snd_rme32_capture_spdif_ops = {
+static struct snd_pcm_ops snd_rme32_capture_spdif_ops = {
 	.open =		snd_rme32_capture_spdif_open,
 	.close =	snd_rme32_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1245,7 +1245,7 @@
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-static snd_pcm_ops_t snd_rme32_playback_adat_ops = {
+static struct snd_pcm_ops snd_rme32_playback_adat_ops = {
 	.open =		snd_rme32_playback_adat_open,
 	.close =	snd_rme32_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1258,7 +1258,7 @@
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-static snd_pcm_ops_t snd_rme32_capture_adat_ops = {
+static struct snd_pcm_ops snd_rme32_capture_adat_ops = {
 	.open =		snd_rme32_capture_adat_open,
 	.close =	snd_rme32_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1271,7 +1271,7 @@
 };
 
 /* for fullduplex mode */
-static snd_pcm_ops_t snd_rme32_playback_spdif_fd_ops = {
+static struct snd_pcm_ops snd_rme32_playback_spdif_fd_ops = {
 	.open =		snd_rme32_playback_spdif_open,
 	.close =	snd_rme32_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1283,7 +1283,7 @@
 	.ack =		snd_rme32_playback_fd_ack,
 };
 
-static snd_pcm_ops_t snd_rme32_capture_spdif_fd_ops = {
+static struct snd_pcm_ops snd_rme32_capture_spdif_fd_ops = {
 	.open =		snd_rme32_capture_spdif_open,
 	.close =	snd_rme32_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1295,7 +1295,7 @@
 	.ack =		snd_rme32_capture_fd_ack,
 };
 
-static snd_pcm_ops_t snd_rme32_playback_adat_fd_ops = {
+static struct snd_pcm_ops snd_rme32_playback_adat_fd_ops = {
 	.open =		snd_rme32_playback_adat_open,
 	.close =	snd_rme32_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1306,7 +1306,7 @@
 	.ack =		snd_rme32_playback_fd_ack,
 };
 
-static snd_pcm_ops_t snd_rme32_capture_adat_fd_ops = {
+static struct snd_pcm_ops snd_rme32_capture_adat_fd_ops = {
 	.open =		snd_rme32_capture_adat_open,
 	.close =	snd_rme32_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1319,7 +1319,7 @@
 
 static void snd_rme32_free(void *private_data)
 {
-	rme32_t *rme32 = (rme32_t *) private_data;
+	struct rme32 *rme32 = (struct rme32 *) private_data;
 
 	if (rme32 == NULL) {
 		return;
@@ -1340,20 +1340,20 @@
 	pci_disable_device(rme32->pci);
 }
 
-static void snd_rme32_free_spdif_pcm(snd_pcm_t * pcm)
+static void snd_rme32_free_spdif_pcm(struct snd_pcm *pcm)
 {
-	rme32_t *rme32 = (rme32_t *) pcm->private_data;
+	struct rme32 *rme32 = (struct rme32 *) pcm->private_data;
 	rme32->spdif_pcm = NULL;
 }
 
 static void
-snd_rme32_free_adat_pcm(snd_pcm_t *pcm)
+snd_rme32_free_adat_pcm(struct snd_pcm *pcm)
 {
-	rme32_t *rme32 = (rme32_t *) pcm->private_data;
+	struct rme32 *rme32 = (struct rme32 *) pcm->private_data;
 	rme32->adat_pcm = NULL;
 }
 
-static int __devinit snd_rme32_create(rme32_t * rme32)
+static int __devinit snd_rme32_create(struct rme32 * rme32)
 {
 	struct pci_dev *pci = rme32->pci;
 	int err;
@@ -1479,10 +1479,10 @@
  */
 
 static void
-snd_rme32_proc_read(snd_info_entry_t * entry, snd_info_buffer_t * buffer)
+snd_rme32_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer)
 {
 	int n;
-	rme32_t *rme32 = (rme32_t *) entry->private_data;
+	struct rme32 *rme32 = (struct rme32 *) entry->private_data;
 
 	rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
 
@@ -1573,9 +1573,9 @@
 	}
 }
 
-static void __devinit snd_rme32_proc_init(rme32_t * rme32)
+static void __devinit snd_rme32_proc_init(struct rme32 * rme32)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(rme32->card, "rme32", &entry))
 		snd_info_set_text_ops(entry, rme32, 1024, snd_rme32_proc_read);
@@ -1586,8 +1586,8 @@
  */
 
 static int
-snd_rme32_info_loopback_control(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_info_t * uinfo)
+snd_rme32_info_loopback_control(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1596,10 +1596,10 @@
 	return 0;
 }
 static int
-snd_rme32_get_loopback_control(snd_kcontrol_t * kcontrol,
-			       snd_ctl_elem_value_t * ucontrol)
+snd_rme32_get_loopback_control(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&rme32->lock);
 	ucontrol->value.integer.value[0] =
@@ -1608,10 +1608,10 @@
 	return 0;
 }
 static int
-snd_rme32_put_loopback_control(snd_kcontrol_t * kcontrol,
-			       snd_ctl_elem_value_t * ucontrol)
+snd_rme32_put_loopback_control(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 
@@ -1630,10 +1630,10 @@
 }
 
 static int
-snd_rme32_info_inputtype_control(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_info_t * uinfo)
+snd_rme32_info_inputtype_control(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 	static char *texts[4] = { "Optical", "Coaxial", "Internal", "XLR" };
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -1660,10 +1660,10 @@
 	return 0;
 }
 static int
-snd_rme32_get_inputtype_control(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+snd_rme32_get_inputtype_control(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 	unsigned int items = 3;
 
 	spin_lock_irq(&rme32->lock);
@@ -1689,10 +1689,10 @@
 	return 0;
 }
 static int
-snd_rme32_put_inputtype_control(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+snd_rme32_put_inputtype_control(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change, items = 3;
 
@@ -1718,8 +1718,8 @@
 }
 
 static int
-snd_rme32_info_clockmode_control(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_info_t * uinfo)
+snd_rme32_info_clockmode_control(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = { "AutoSync", 
 				  "Internal 32.0kHz", 
@@ -1737,10 +1737,10 @@
 	return 0;
 }
 static int
-snd_rme32_get_clockmode_control(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+snd_rme32_get_clockmode_control(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&rme32->lock);
 	ucontrol->value.enumerated.item[0] = snd_rme32_getclockmode(rme32);
@@ -1748,10 +1748,10 @@
 	return 0;
 }
 static int
-snd_rme32_put_clockmode_control(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_value_t * ucontrol)
+snd_rme32_put_clockmode_control(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 
@@ -1763,7 +1763,7 @@
 	return change;
 }
 
-static u32 snd_rme32_convert_from_aes(snd_aes_iec958_t * aes)
+static u32 snd_rme32_convert_from_aes(struct snd_aes_iec958 * aes)
 {
 	u32 val = 0;
 	val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME32_WCR_PRO : 0;
@@ -1774,7 +1774,7 @@
 	return val;
 }
 
-static void snd_rme32_convert_to_aes(snd_aes_iec958_t * aes, u32 val)
+static void snd_rme32_convert_to_aes(struct snd_aes_iec958 * aes, u32 val)
 {
 	aes->status[0] = ((val & RME32_WCR_PRO) ? IEC958_AES0_PROFESSIONAL : 0);
 	if (val & RME32_WCR_PRO)
@@ -1783,28 +1783,28 @@
 		aes->status[0] |= (val & RME32_WCR_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
 }
 
-static int snd_rme32_control_spdif_info(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_info_t * uinfo)
+static int snd_rme32_control_spdif_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_rme32_control_spdif_get(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_rme32_control_spdif_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 
 	snd_rme32_convert_to_aes(&ucontrol->value.iec958,
 				 rme32->wcreg_spdif);
 	return 0;
 }
 
-static int snd_rme32_control_spdif_put(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_rme32_control_spdif_put(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 	int change;
 	u32 val;
 
@@ -1816,30 +1816,30 @@
 	return change;
 }
 
-static int snd_rme32_control_spdif_stream_info(snd_kcontrol_t * kcontrol,
-					       snd_ctl_elem_info_t * uinfo)
+static int snd_rme32_control_spdif_stream_info(struct snd_kcontrol *kcontrol,
+					       struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_rme32_control_spdif_stream_get(snd_kcontrol_t * kcontrol,
-					      snd_ctl_elem_value_t *
+static int snd_rme32_control_spdif_stream_get(struct snd_kcontrol *kcontrol,
+					      struct snd_ctl_elem_value *
 					      ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 
 	snd_rme32_convert_to_aes(&ucontrol->value.iec958,
 				 rme32->wcreg_spdif_stream);
 	return 0;
 }
 
-static int snd_rme32_control_spdif_stream_put(snd_kcontrol_t * kcontrol,
-					      snd_ctl_elem_value_t *
+static int snd_rme32_control_spdif_stream_put(struct snd_kcontrol *kcontrol,
+					      struct snd_ctl_elem_value *
 					      ucontrol)
 {
-	rme32_t *rme32 = snd_kcontrol_chip(kcontrol);
+	struct rme32 *rme32 = snd_kcontrol_chip(kcontrol);
 	int change;
 	u32 val;
 
@@ -1854,23 +1854,23 @@
 	return change;
 }
 
-static int snd_rme32_control_spdif_mask_info(snd_kcontrol_t * kcontrol,
-					     snd_ctl_elem_info_t * uinfo)
+static int snd_rme32_control_spdif_mask_info(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_rme32_control_spdif_mask_get(snd_kcontrol_t * kcontrol,
-					    snd_ctl_elem_value_t *
+static int snd_rme32_control_spdif_mask_get(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *
 					    ucontrol)
 {
 	ucontrol->value.iec958.status[0] = kcontrol->private_value;
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_rme32_controls[] = {
+static struct snd_kcontrol_new snd_rme32_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 		.name =	SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
@@ -1925,10 +1925,10 @@
 	}
 };
 
-static int snd_rme32_create_switches(snd_card_t * card, rme32_t * rme32)
+static int snd_rme32_create_switches(struct snd_card *card, struct rme32 * rme32)
 {
 	int idx, err;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	for (idx = 0; idx < (int)ARRAY_SIZE(snd_rme32_controls); idx++) {
 		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme32_controls[idx], rme32))) < 0)
@@ -1944,7 +1944,7 @@
  * Card initialisation
  */
 
-static void snd_rme32_card_free(snd_card_t * card)
+static void snd_rme32_card_free(struct snd_card *card)
 {
 	snd_rme32_free(card->private_data);
 }
@@ -1953,8 +1953,8 @@
 snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 {
 	static int dev;
-	rme32_t *rme32;
-	snd_card_t *card;
+	struct rme32 *rme32;
+	struct snd_card *card;
 	int err;
 
 	if (dev >= SNDRV_CARDS) {
@@ -1966,10 +1966,10 @@
 	}
 
 	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
-				 sizeof(rme32_t))) == NULL)
+				 sizeof(struct rme32))) == NULL)
 		return -ENOMEM;
 	card->private_free = snd_rme32_card_free;
-	rme32 = (rme32_t *) card->private_data;
+	rme32 = (struct rme32 *) card->private_data;
 	rme32->card = card;
 	rme32->pci = pci;
 	snd_card_set_dev(card, &pci->dev);
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 6d422ef..0e694b0 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -201,7 +201,7 @@
 #define RME96_AD1855_VOL_BITS 10
 
 
-typedef struct snd_rme96 {
+struct rme96 {
 	spinlock_t    lock;
 	int irq;
 	unsigned long port;
@@ -216,8 +216,8 @@
 
 	u8 rev; /* card revision number */
 
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
 
 	int playback_frlog; /* log2 of framesize */
 	int capture_frlog;
@@ -225,12 +225,12 @@
         size_t playback_periodsize; /* in bytes, zero if not used */
 	size_t capture_periodsize; /* in bytes, zero if not used */
 
-	snd_card_t         *card;
-	snd_pcm_t          *spdif_pcm;
-	snd_pcm_t          *adat_pcm; 
+	struct snd_card *card;
+	struct snd_pcm *spdif_pcm;
+	struct snd_pcm *adat_pcm; 
 	struct pci_dev     *pci;
-	snd_kcontrol_t	   *spdif_ctl;
-} rme96_t;
+	struct snd_kcontrol   *spdif_ctl;
+};
 
 static struct pci_device_id snd_rme96_ids[] = {
 	{ PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96,
@@ -257,44 +257,44 @@
 #define	RME96_185X_MAX_OUT(rme96) ((1 << (RME96_DAC_IS_1852(rme96) ? RME96_AD1852_VOL_BITS : RME96_AD1855_VOL_BITS)) - 1)
 
 static int
-snd_rme96_playback_prepare(snd_pcm_substream_t *substream);
+snd_rme96_playback_prepare(struct snd_pcm_substream *substream);
 
 static int
-snd_rme96_capture_prepare(snd_pcm_substream_t *substream);
+snd_rme96_capture_prepare(struct snd_pcm_substream *substream);
 
 static int
-snd_rme96_playback_trigger(snd_pcm_substream_t *substream, 
+snd_rme96_playback_trigger(struct snd_pcm_substream *substream, 
 			   int cmd);
 
 static int
-snd_rme96_capture_trigger(snd_pcm_substream_t *substream, 
+snd_rme96_capture_trigger(struct snd_pcm_substream *substream, 
 			  int cmd);
 
 static snd_pcm_uframes_t
-snd_rme96_playback_pointer(snd_pcm_substream_t *substream);
+snd_rme96_playback_pointer(struct snd_pcm_substream *substream);
 
 static snd_pcm_uframes_t
-snd_rme96_capture_pointer(snd_pcm_substream_t *substream);
+snd_rme96_capture_pointer(struct snd_pcm_substream *substream);
 
 static void __devinit 
-snd_rme96_proc_init(rme96_t *rme96);
+snd_rme96_proc_init(struct rme96 *rme96);
 
 static int
-snd_rme96_create_switches(snd_card_t *card,
-			  rme96_t *rme96);
+snd_rme96_create_switches(struct snd_card *card,
+			  struct rme96 *rme96);
 
 static int
-snd_rme96_getinputtype(rme96_t *rme96);
+snd_rme96_getinputtype(struct rme96 *rme96);
 
 static inline unsigned int
-snd_rme96_playback_ptr(rme96_t *rme96)
+snd_rme96_playback_ptr(struct rme96 *rme96)
 {
 	return (readl(rme96->iobase + RME96_IO_GET_PLAY_POS)
 		& RME96_RCR_AUDIO_ADDR_MASK) >> rme96->playback_frlog;
 }
 
 static inline unsigned int
-snd_rme96_capture_ptr(rme96_t *rme96)
+snd_rme96_capture_ptr(struct rme96 *rme96)
 {
 	return (readl(rme96->iobase + RME96_IO_GET_REC_POS)
 		& RME96_RCR_AUDIO_ADDR_MASK) >> rme96->capture_frlog;
@@ -315,12 +315,12 @@
 }
 
 static int
-snd_rme96_playback_silence(snd_pcm_substream_t *substream,
+snd_rme96_playback_silence(struct snd_pcm_substream *substream,
 			   int channel, /* not used (interleaved data) */
 			   snd_pcm_uframes_t pos,
 			   snd_pcm_uframes_t count)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	count <<= rme96->playback_frlog;
 	pos <<= rme96->playback_frlog;
 	memset_io(rme96->iobase + RME96_IO_PLAY_BUFFER + pos,
@@ -329,13 +329,13 @@
 }
 
 static int
-snd_rme96_playback_copy(snd_pcm_substream_t *substream,
+snd_rme96_playback_copy(struct snd_pcm_substream *substream,
 			int channel, /* not used (interleaved data) */
 			snd_pcm_uframes_t pos,
 			void __user *src,
 			snd_pcm_uframes_t count)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	count <<= rme96->playback_frlog;
 	pos <<= rme96->playback_frlog;
 	copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, src,
@@ -344,13 +344,13 @@
 }
 
 static int
-snd_rme96_capture_copy(snd_pcm_substream_t *substream,
+snd_rme96_capture_copy(struct snd_pcm_substream *substream,
 		       int channel, /* not used (interleaved data) */
 		       snd_pcm_uframes_t pos,
 		       void __user *dst,
 		       snd_pcm_uframes_t count)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	count <<= rme96->capture_frlog;
 	pos <<= rme96->capture_frlog;
 	copy_to_user_fromio(dst, rme96->iobase + RME96_IO_REC_BUFFER + pos,
@@ -361,7 +361,7 @@
 /*
  * Digital output capabilites (S/PDIF)
  */
-static snd_pcm_hardware_t snd_rme96_playback_spdif_info =
+static struct snd_pcm_hardware snd_rme96_playback_spdif_info =
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_MMAP_VALID |
@@ -390,7 +390,7 @@
 /*
  * Digital input capabilites (S/PDIF)
  */
-static snd_pcm_hardware_t snd_rme96_capture_spdif_info =
+static struct snd_pcm_hardware snd_rme96_capture_spdif_info =
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_MMAP_VALID |
@@ -419,7 +419,7 @@
 /*
  * Digital output capabilites (ADAT)
  */
-static snd_pcm_hardware_t snd_rme96_playback_adat_info =
+static struct snd_pcm_hardware snd_rme96_playback_adat_info =
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_MMAP_VALID |
@@ -444,7 +444,7 @@
 /*
  * Digital input capabilites (ADAT)
  */
-static snd_pcm_hardware_t snd_rme96_capture_adat_info =
+static struct snd_pcm_hardware snd_rme96_capture_adat_info =
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_MMAP_VALID |
@@ -479,7 +479,7 @@
  * the volume.
  */
 static void
-snd_rme96_write_SPI(rme96_t *rme96, u16 val)
+snd_rme96_write_SPI(struct rme96 *rme96, u16 val)
 {
 	int i;
 
@@ -506,7 +506,7 @@
 }
 
 static void
-snd_rme96_apply_dac_volume(rme96_t *rme96)
+snd_rme96_apply_dac_volume(struct rme96 *rme96)
 {
 	if (RME96_DAC_IS_1852(rme96)) {
 		snd_rme96_write_SPI(rme96, (rme96->vol[0] << 2) | 0x0);
@@ -518,7 +518,7 @@
 }
 
 static void
-snd_rme96_reset_dac(rme96_t *rme96)
+snd_rme96_reset_dac(struct rme96 *rme96)
 {
 	writel(rme96->wcreg | RME96_WCR_PD,
 	       rme96->iobase + RME96_IO_CONTROL_REGISTER);
@@ -526,14 +526,14 @@
 }
 
 static int
-snd_rme96_getmontracks(rme96_t *rme96)
+snd_rme96_getmontracks(struct rme96 *rme96)
 {
 	return ((rme96->wcreg >> RME96_WCR_BITPOS_MONITOR_0) & 1) +
 		(((rme96->wcreg >> RME96_WCR_BITPOS_MONITOR_1) & 1) << 1);
 }
 
 static int
-snd_rme96_setmontracks(rme96_t *rme96,
+snd_rme96_setmontracks(struct rme96 *rme96,
 		       int montracks)
 {
 	if (montracks & 1) {
@@ -551,14 +551,14 @@
 }
 
 static int
-snd_rme96_getattenuation(rme96_t *rme96)
+snd_rme96_getattenuation(struct rme96 *rme96)
 {
 	return ((rme96->wcreg >> RME96_WCR_BITPOS_GAIN_0) & 1) +
 		(((rme96->wcreg >> RME96_WCR_BITPOS_GAIN_1) & 1) << 1);
 }
 
 static int
-snd_rme96_setattenuation(rme96_t *rme96,
+snd_rme96_setattenuation(struct rme96 *rme96,
 			 int attenuation)
 {
 	switch (attenuation) {
@@ -586,7 +586,7 @@
 }
 
 static int
-snd_rme96_capture_getrate(rme96_t *rme96,
+snd_rme96_capture_getrate(struct rme96 *rme96,
 			  int *is_adat)
 {	
 	int n, rate;
@@ -649,7 +649,7 @@
 }
 
 static int
-snd_rme96_playback_getrate(rme96_t *rme96)
+snd_rme96_playback_getrate(struct rme96 *rme96)
 {
 	int rate, dummy;
 
@@ -679,7 +679,7 @@
 }
 
 static int
-snd_rme96_playback_setrate(rme96_t *rme96,
+snd_rme96_playback_setrate(struct rme96 *rme96,
 			   int rate)
 {
 	int ds;
@@ -731,7 +731,7 @@
 }
 
 static int
-snd_rme96_capture_analog_setrate(rme96_t *rme96,
+snd_rme96_capture_analog_setrate(struct rme96 *rme96,
 				 int rate)
 {
 	switch (rate) {
@@ -773,7 +773,7 @@
 }
 
 static int
-snd_rme96_setclockmode(rme96_t *rme96,
+snd_rme96_setclockmode(struct rme96 *rme96,
 		       int mode)
 {
 	switch (mode) {
@@ -801,7 +801,7 @@
 }
 
 static int
-snd_rme96_getclockmode(rme96_t *rme96)
+snd_rme96_getclockmode(struct rme96 *rme96)
 {
 	if (rme96->areg & RME96_AR_WSEL) {
 		return RME96_CLOCKMODE_WORDCLOCK;
@@ -811,7 +811,7 @@
 }
 
 static int
-snd_rme96_setinputtype(rme96_t *rme96,
+snd_rme96_setinputtype(struct rme96 *rme96,
 		       int type)
 {
 	int n;
@@ -872,7 +872,7 @@
 }
 
 static int
-snd_rme96_getinputtype(rme96_t *rme96)
+snd_rme96_getinputtype(struct rme96 *rme96)
 {
 	if (rme96->areg & RME96_AR_ANALOG) {
 		return RME96_INPUT_ANALOG;
@@ -882,7 +882,7 @@
 }
 
 static void
-snd_rme96_setframelog(rme96_t *rme96,
+snd_rme96_setframelog(struct rme96 *rme96,
 		      int n_channels,
 		      int is_playback)
 {
@@ -904,7 +904,7 @@
 }
 
 static int
-snd_rme96_playback_setformat(rme96_t *rme96,
+snd_rme96_playback_setformat(struct rme96 *rme96,
 			     int format)
 {
 	switch (format) {
@@ -922,7 +922,7 @@
 }
 
 static int
-snd_rme96_capture_setformat(rme96_t *rme96,
+snd_rme96_capture_setformat(struct rme96 *rme96,
 			    int format)
 {
 	switch (format) {
@@ -940,7 +940,7 @@
 }
 
 static void
-snd_rme96_set_period_properties(rme96_t *rme96,
+snd_rme96_set_period_properties(struct rme96 *rme96,
 				size_t period_bytes)
 {
 	switch (period_bytes) {
@@ -959,11 +959,11 @@
 }
 
 static int
-snd_rme96_playback_hw_params(snd_pcm_substream_t *substream,
-			     snd_pcm_hw_params_t *params)
+snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err, rate, dummy;
 
 	runtime->dma_area = (void __force *)(rme96->iobase +
@@ -1012,11 +1012,11 @@
 }
 
 static int
-snd_rme96_capture_hw_params(snd_pcm_substream_t *substream,
-			    snd_pcm_hw_params_t *params)
+snd_rme96_capture_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err, isadat, rate;
 	
 	runtime->dma_area = (void __force *)(rme96->iobase +
@@ -1066,7 +1066,7 @@
 }
 
 static void
-snd_rme96_playback_start(rme96_t *rme96,
+snd_rme96_playback_start(struct rme96 *rme96,
 			 int from_pause)
 {
 	if (!from_pause) {
@@ -1078,7 +1078,7 @@
 }
 
 static void
-snd_rme96_capture_start(rme96_t *rme96,
+snd_rme96_capture_start(struct rme96 *rme96,
 			int from_pause)
 {
 	if (!from_pause) {
@@ -1090,7 +1090,7 @@
 }
 
 static void
-snd_rme96_playback_stop(rme96_t *rme96)
+snd_rme96_playback_stop(struct rme96 *rme96)
 {
 	/*
 	 * Check if there is an unconfirmed IRQ, if so confirm it, or else
@@ -1105,7 +1105,7 @@
 }
 
 static void
-snd_rme96_capture_stop(rme96_t *rme96)
+snd_rme96_capture_stop(struct rme96 *rme96)
 {
 	rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
 	if (rme96->rcreg & RME96_RCR_IRQ_2) {
@@ -1120,7 +1120,7 @@
 		    void *dev_id,
 		    struct pt_regs *regs)
 {
-	rme96_t *rme96 = (rme96_t *)dev_id;
+	struct rme96 *rme96 = (struct rme96 *)dev_id;
 
 	rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
 	/* fastpath out, to ease interrupt sharing */
@@ -1145,18 +1145,18 @@
 
 static unsigned int period_bytes[] = { RME96_SMALL_BLOCK_SIZE, RME96_LARGE_BLOCK_SIZE };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_period_bytes = {
+static struct snd_pcm_hw_constraint_list hw_constraints_period_bytes = {
 	.count = ARRAY_SIZE(period_bytes),
 	.list = period_bytes,
 	.mask = 0
 };
 
 static int
-snd_rme96_playback_spdif_open(snd_pcm_substream_t *substream)
+snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
 {
         int rate, dummy;
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_pcm_set_sync(substream);
 
@@ -1191,11 +1191,11 @@
 }
 
 static int
-snd_rme96_capture_spdif_open(snd_pcm_substream_t *substream)
+snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
 {
         int isadat, rate;
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_pcm_set_sync(substream);
 
@@ -1226,11 +1226,11 @@
 }
 
 static int
-snd_rme96_playback_adat_open(snd_pcm_substream_t *substream)
+snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
 {
         int rate, dummy;
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;        
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;        
 	
 	snd_pcm_set_sync(substream);
 
@@ -1260,11 +1260,11 @@
 }
 
 static int
-snd_rme96_capture_adat_open(snd_pcm_substream_t *substream)
+snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
 {
         int isadat, rate;
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_pcm_set_sync(substream);
 
@@ -1297,9 +1297,9 @@
 }
 
 static int
-snd_rme96_playback_close(snd_pcm_substream_t *substream)
+snd_rme96_playback_close(struct snd_pcm_substream *substream)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	int spdif = 0;
 
 	spin_lock_irq(&rme96->lock);	
@@ -1319,9 +1319,9 @@
 }
 
 static int
-snd_rme96_capture_close(snd_pcm_substream_t *substream)
+snd_rme96_capture_close(struct snd_pcm_substream *substream)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	
 	spin_lock_irq(&rme96->lock);	
 	if (RME96_ISRECORDING(rme96)) {
@@ -1334,9 +1334,9 @@
 }
 
 static int
-snd_rme96_playback_prepare(snd_pcm_substream_t *substream)
+snd_rme96_playback_prepare(struct snd_pcm_substream *substream)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	
 	spin_lock_irq(&rme96->lock);	
 	if (RME96_ISPLAYING(rme96)) {
@@ -1348,9 +1348,9 @@
 }
 
 static int
-snd_rme96_capture_prepare(snd_pcm_substream_t *substream)
+snd_rme96_capture_prepare(struct snd_pcm_substream *substream)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	
 	spin_lock_irq(&rme96->lock);	
 	if (RME96_ISRECORDING(rme96)) {
@@ -1362,10 +1362,10 @@
 }
 
 static int
-snd_rme96_playback_trigger(snd_pcm_substream_t *substream, 
+snd_rme96_playback_trigger(struct snd_pcm_substream *substream, 
 			   int cmd)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -1405,10 +1405,10 @@
 }
 
 static int
-snd_rme96_capture_trigger(snd_pcm_substream_t *substream, 
+snd_rme96_capture_trigger(struct snd_pcm_substream *substream, 
 			  int cmd)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -1449,20 +1449,20 @@
 }
 
 static snd_pcm_uframes_t
-snd_rme96_playback_pointer(snd_pcm_substream_t *substream)
+snd_rme96_playback_pointer(struct snd_pcm_substream *substream)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	return snd_rme96_playback_ptr(rme96);
 }
 
 static snd_pcm_uframes_t
-snd_rme96_capture_pointer(snd_pcm_substream_t *substream)
+snd_rme96_capture_pointer(struct snd_pcm_substream *substream)
 {
-	rme96_t *rme96 = snd_pcm_substream_chip(substream);
+	struct rme96 *rme96 = snd_pcm_substream_chip(substream);
 	return snd_rme96_capture_ptr(rme96);
 }
 
-static snd_pcm_ops_t snd_rme96_playback_spdif_ops = {
+static struct snd_pcm_ops snd_rme96_playback_spdif_ops = {
 	.open =		snd_rme96_playback_spdif_open,
 	.close =	snd_rme96_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1475,7 +1475,7 @@
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-static snd_pcm_ops_t snd_rme96_capture_spdif_ops = {
+static struct snd_pcm_ops snd_rme96_capture_spdif_ops = {
 	.open =		snd_rme96_capture_spdif_open,
 	.close =	snd_rme96_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1487,7 +1487,7 @@
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-static snd_pcm_ops_t snd_rme96_playback_adat_ops = {
+static struct snd_pcm_ops snd_rme96_playback_adat_ops = {
 	.open =		snd_rme96_playback_adat_open,
 	.close =	snd_rme96_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1500,7 +1500,7 @@
 	.mmap =		snd_pcm_lib_mmap_iomem,
 };
 
-static snd_pcm_ops_t snd_rme96_capture_adat_ops = {
+static struct snd_pcm_ops snd_rme96_capture_adat_ops = {
 	.open =		snd_rme96_capture_adat_open,
 	.close =	snd_rme96_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1515,7 +1515,7 @@
 static void
 snd_rme96_free(void *private_data)
 {
-	rme96_t *rme96 = (rme96_t *)private_data;
+	struct rme96 *rme96 = (struct rme96 *)private_data;
 
 	if (rme96 == NULL) {
 	        return;
@@ -1540,21 +1540,21 @@
 }
 
 static void
-snd_rme96_free_spdif_pcm(snd_pcm_t *pcm)
+snd_rme96_free_spdif_pcm(struct snd_pcm *pcm)
 {
-	rme96_t *rme96 = (rme96_t *) pcm->private_data;
+	struct rme96 *rme96 = (struct rme96 *) pcm->private_data;
 	rme96->spdif_pcm = NULL;
 }
 
 static void
-snd_rme96_free_adat_pcm(snd_pcm_t *pcm)
+snd_rme96_free_adat_pcm(struct snd_pcm *pcm)
 {
-	rme96_t *rme96 = (rme96_t *) pcm->private_data;
+	struct rme96 *rme96 = (struct rme96 *) pcm->private_data;
 	rme96->adat_pcm = NULL;
 }
 
 static int __devinit
-snd_rme96_create(rme96_t *rme96)
+snd_rme96_create(struct rme96 *rme96)
 {
 	struct pci_dev *pci = rme96->pci;
 	int err;
@@ -1671,10 +1671,10 @@
  */
 
 static void 
-snd_rme96_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
 	int n;
-	rme96_t *rme96 = (rme96_t *)entry->private_data;
+	struct rme96 *rme96 = (struct rme96 *)entry->private_data;
 	
 	rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
 
@@ -1800,9 +1800,9 @@
 }
 
 static void __devinit 
-snd_rme96_proc_init(rme96_t *rme96)
+snd_rme96_proc_init(struct rme96 *rme96)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(rme96->card, "rme96", &entry))
 		snd_info_set_text_ops(entry, rme96, 1024, snd_rme96_proc_read);
@@ -1813,7 +1813,7 @@
  */
 
 static int
-snd_rme96_info_loopback_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_rme96_info_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1822,9 +1822,9 @@
 	return 0;
 }
 static int
-snd_rme96_get_loopback_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_get_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme96->lock);
 	ucontrol->value.integer.value[0] = rme96->wcreg & RME96_WCR_SEL ? 0 : 1;
@@ -1832,9 +1832,9 @@
 	return 0;
 }
 static int
-snd_rme96_put_loopback_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_put_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 	
@@ -1849,10 +1849,10 @@
 }
 
 static int
-snd_rme96_info_inputtype_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_rme96_info_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *_texts[5] = { "Optical", "Coaxial", "Internal", "XLR", "Analog" };
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	char *texts[5] = { _texts[0], _texts[1], _texts[2], _texts[3], _texts[4] };
 	
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -1886,9 +1886,9 @@
 	return 0;
 }
 static int
-snd_rme96_get_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	unsigned int items = 3;
 	
 	spin_lock_irq(&rme96->lock);
@@ -1925,9 +1925,9 @@
 	return 0;
 }
 static int
-snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_put_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change, items = 3;
 	
@@ -1967,7 +1967,7 @@
 }
 
 static int
-snd_rme96_info_clockmode_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_rme96_info_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = { "AutoSync", "Internal", "Word" };
 	
@@ -1981,9 +1981,9 @@
 	return 0;
 }
 static int
-snd_rme96_get_clockmode_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_get_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme96->lock);
 	ucontrol->value.enumerated.item[0] = snd_rme96_getclockmode(rme96);
@@ -1991,9 +1991,9 @@
 	return 0;
 }
 static int
-snd_rme96_put_clockmode_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_put_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 	
@@ -2006,7 +2006,7 @@
 }
 
 static int
-snd_rme96_info_attenuation_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_rme96_info_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = { "0 dB", "-6 dB", "-12 dB", "-18 dB" };
 	
@@ -2020,9 +2020,9 @@
 	return 0;
 }
 static int
-snd_rme96_get_attenuation_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_get_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme96->lock);
 	ucontrol->value.enumerated.item[0] = snd_rme96_getattenuation(rme96);
@@ -2030,9 +2030,9 @@
 	return 0;
 }
 static int
-snd_rme96_put_attenuation_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_put_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 	
@@ -2046,7 +2046,7 @@
 }
 
 static int
-snd_rme96_info_montracks_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_rme96_info_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = { "1+2", "3+4", "5+6", "7+8" };
 	
@@ -2060,9 +2060,9 @@
 	return 0;
 }
 static int
-snd_rme96_get_montracks_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_get_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme96->lock);
 	ucontrol->value.enumerated.item[0] = snd_rme96_getmontracks(rme96);
@@ -2070,9 +2070,9 @@
 	return 0;
 }
 static int
-snd_rme96_put_montracks_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+snd_rme96_put_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 	
@@ -2084,7 +2084,7 @@
 	return change;
 }
 
-static u32 snd_rme96_convert_from_aes(snd_aes_iec958_t *aes)
+static u32 snd_rme96_convert_from_aes(struct snd_aes_iec958 *aes)
 {
 	u32 val = 0;
 	val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME96_WCR_PRO : 0;
@@ -2096,7 +2096,7 @@
 	return val;
 }
 
-static void snd_rme96_convert_to_aes(snd_aes_iec958_t *aes, u32 val)
+static void snd_rme96_convert_to_aes(struct snd_aes_iec958 *aes, u32 val)
 {
 	aes->status[0] = ((val & RME96_WCR_PRO) ? IEC958_AES0_PROFESSIONAL : 0) |
 			 ((val & RME96_WCR_DOLBY) ? IEC958_AES0_NONAUDIO : 0);
@@ -2106,24 +2106,24 @@
 		aes->status[0] |= (val & RME96_WCR_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
 }
 
-static int snd_rme96_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme96_control_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_rme96_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme96_control_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	
 	snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif);
 	return 0;
 }
 
-static int snd_rme96_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme96_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	int change;
 	u32 val;
 	
@@ -2135,24 +2135,24 @@
 	return change;
 }
 
-static int snd_rme96_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme96_control_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_rme96_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme96_control_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	
 	snd_rme96_convert_to_aes(&ucontrol->value.iec958, rme96->wcreg_spdif_stream);
 	return 0;
 }
 
-static int snd_rme96_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme96_control_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	int change;
 	u32 val;
 	
@@ -2167,23 +2167,23 @@
 	return change;
 }
 
-static int snd_rme96_control_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme96_control_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_rme96_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme96_control_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = kcontrol->private_value;
 	return 0;
 }
 
 static int
-snd_rme96_dac_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+snd_rme96_dac_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 	
         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
         uinfo->count = 2;
@@ -2193,9 +2193,9 @@
 }
 
 static int
-snd_rme96_dac_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+snd_rme96_dac_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&rme96->lock);
         u->value.integer.value[0] = rme96->vol[0];
@@ -2206,9 +2206,9 @@
 }
 
 static int
-snd_rme96_dac_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *u)
+snd_rme96_dac_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *u)
 {
-	rme96_t *rme96 = snd_kcontrol_chip(kcontrol);
+	struct rme96 *rme96 = snd_kcontrol_chip(kcontrol);
         int change = 0;
 
 	if (!RME96_HAS_ANALOG_OUT(rme96)) {
@@ -2231,7 +2231,7 @@
         return change;
 }
 
-static snd_kcontrol_new_t snd_rme96_controls[] = {
+static struct snd_kcontrol_new snd_rme96_controls[] = {
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -2312,11 +2312,11 @@
 };
 
 static int
-snd_rme96_create_switches(snd_card_t *card,
-			  rme96_t *rme96)
+snd_rme96_create_switches(struct snd_card *card,
+			  struct rme96 *rme96)
 {
 	int idx, err;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	for (idx = 0; idx < 7; idx++) {
 		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme96_controls[idx], rme96))) < 0)
@@ -2338,7 +2338,7 @@
  * Card initialisation
  */
 
-static void snd_rme96_card_free(snd_card_t *card)
+static void snd_rme96_card_free(struct snd_card *card)
 {
 	snd_rme96_free(card->private_data);
 }
@@ -2348,8 +2348,8 @@
 		const struct pci_device_id *pci_id)
 {
 	static int dev;
-	rme96_t *rme96;
-	snd_card_t *card;
+	struct rme96 *rme96;
+	struct snd_card *card;
 	int err;
 	u8 val;
 
@@ -2361,10 +2361,10 @@
 		return -ENOENT;
 	}
 	if ((card = snd_card_new(index[dev], id[dev], THIS_MODULE,
-				 sizeof(rme96_t))) == NULL)
+				 sizeof(struct rme96))) == NULL)
 		return -ENOMEM;
 	card->private_free = snd_rme96_card_free;
-	rme96 = (rme96_t *)card->private_data;	
+	rme96 = (struct rme96 *)card->private_data;	
 	rme96->card = card;
 	rme96->pci = pci;
 	snd_card_set_dev(card, &pci->dev);
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index d15ffb3..ebf7a2b 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -394,11 +394,7 @@
 #endif
 #endif
 
-typedef struct _hdsp             hdsp_t;
-typedef struct _hdsp_midi        hdsp_midi_t;
-typedef struct _hdsp_9632_meters hdsp_9632_meters_t;
-
-struct _hdsp_9632_meters {
+struct hdsp_9632_meters {
     u32 input_peak[16];
     u32 playback_peak[16];
     u32 output_peak[16];
@@ -414,23 +410,23 @@
     u32 xxx_rms_high[16];
 };
 
-struct _hdsp_midi {
-    hdsp_t                  *hdsp;
+struct hdsp_midi {
+    struct hdsp             *hdsp;
     int                      id;
-    snd_rawmidi_t           *rmidi;
-    snd_rawmidi_substream_t *input;
-    snd_rawmidi_substream_t *output;
+    struct snd_rawmidi           *rmidi;
+    struct snd_rawmidi_substream *input;
+    struct snd_rawmidi_substream *output;
     char                     istimer; /* timer in use */
     struct timer_list	     timer;
     spinlock_t               lock;
     int			     pending;
 };
 
-struct _hdsp {
+struct hdsp {
 	spinlock_t            lock;
-	snd_pcm_substream_t  *capture_substream;
-	snd_pcm_substream_t  *playback_substream;
-        hdsp_midi_t           midi[2];
+	struct snd_pcm_substream *capture_substream;
+	struct snd_pcm_substream *playback_substream;
+        struct hdsp_midi      midi[2];
 	struct tasklet_struct midi_tasklet;
 	int		      use_midi_tasklet;
 	int                   precise_ptr;
@@ -440,7 +436,7 @@
 	u32                   creg_spdif_stream;
 	int                   clock_source_locked;
 	char                 *card_name;	     /* digiface/multiface */
-	HDSP_IO_Type          io_type;               /* ditto, but for code use */
+	enum HDSP_IO_Type     io_type;               /* ditto, but for code use */
         unsigned short        firmware_rev;
 	unsigned short	      state;		     /* stores state bits */
 	u32		      firmware_cache[24413]; /* this helps recover from accidental iobox power failure */
@@ -467,11 +463,11 @@
 	int                   irq;
 	unsigned long         port;
         void __iomem         *iobase;
-	snd_card_t           *card;
-	snd_pcm_t            *pcm;
-	snd_hwdep_t          *hwdep;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_hwdep          *hwdep;
 	struct pci_dev       *pci;
-	snd_kcontrol_t       *spdif_ctl;
+	struct snd_kcontrol *spdif_ctl;
         unsigned short        mixer_matrix[HDSP_MATRIX_MIXER_SIZE];
 };
 
@@ -585,17 +581,17 @@
 MODULE_DEVICE_TABLE(pci, snd_hdsp_ids);
 
 /* prototypes */
-static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp);
-static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp);
-static int snd_hdsp_enable_io (hdsp_t *hdsp);
-static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp);
-static void snd_hdsp_initialize_channels (hdsp_t *hdsp);
-static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout);
-static int hdsp_autosync_ref(hdsp_t *hdsp);
-static int snd_hdsp_set_defaults(hdsp_t *hdsp);
-static void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp);
+static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp);
+static int snd_hdsp_create_pcm(struct snd_card *card, struct hdsp *hdsp);
+static int snd_hdsp_enable_io (struct hdsp *hdsp);
+static void snd_hdsp_initialize_midi_flush (struct hdsp *hdsp);
+static void snd_hdsp_initialize_channels (struct hdsp *hdsp);
+static int hdsp_fifo_wait(struct hdsp *hdsp, int count, int timeout);
+static int hdsp_autosync_ref(struct hdsp *hdsp);
+static int snd_hdsp_set_defaults(struct hdsp *hdsp);
+static void snd_hdsp_9652_enable_mixer (struct hdsp *hdsp);
 
-static int hdsp_playback_to_output_key (hdsp_t *hdsp, int in, int out)
+static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
 {
 	switch (hdsp->firmware_rev) {
 	case 0xa:
@@ -608,7 +604,7 @@
 	}
 }
 
-static int hdsp_input_to_output_key (hdsp_t *hdsp, int in, int out)
+static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
 {
 	switch (hdsp->firmware_rev) {
 	case 0xa:
@@ -621,17 +617,17 @@
 	}
 }
 
-static void hdsp_write(hdsp_t *hdsp, int reg, int val)
+static void hdsp_write(struct hdsp *hdsp, int reg, int val)
 {
 	writel(val, hdsp->iobase + reg);
 }
 
-static unsigned int hdsp_read(hdsp_t *hdsp, int reg)
+static unsigned int hdsp_read(struct hdsp *hdsp, int reg)
 {
 	return readl (hdsp->iobase + reg);
 }
 
-static int hdsp_check_for_iobox (hdsp_t *hdsp)
+static int hdsp_check_for_iobox (struct hdsp *hdsp)
 {
 
 	if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
@@ -644,7 +640,7 @@
 
 }
 
-static int snd_hdsp_load_firmware_from_cache(hdsp_t *hdsp) {
+static int snd_hdsp_load_firmware_from_cache(struct hdsp *hdsp) {
 
 	int i;
 	unsigned long flags;
@@ -699,7 +695,7 @@
 	return 0;
 }
 
-static int hdsp_get_iobox_version (hdsp_t *hdsp)
+static int hdsp_get_iobox_version (struct hdsp *hdsp)
 {
 	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
 	
@@ -730,7 +726,7 @@
 }
 
 
-static int hdsp_check_for_firmware (hdsp_t *hdsp, int show_err)
+static int hdsp_check_for_firmware (struct hdsp *hdsp, int show_err)
 {
 	if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
 	if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
@@ -751,7 +747,7 @@
 }
 
 
-static int hdsp_fifo_wait(hdsp_t *hdsp, int count, int timeout)
+static int hdsp_fifo_wait(struct hdsp *hdsp, int count, int timeout)
 {    
 	int i;
 
@@ -776,7 +772,7 @@
 	return -1;
 }
 
-static int hdsp_read_gain (hdsp_t *hdsp, unsigned int addr)
+static int hdsp_read_gain (struct hdsp *hdsp, unsigned int addr)
 {
 	if (addr >= HDSP_MATRIX_MIXER_SIZE)
 		return 0;
@@ -784,7 +780,7 @@
 	return hdsp->mixer_matrix[addr];
 }
 
-static int hdsp_write_gain(hdsp_t *hdsp, unsigned int addr, unsigned short data)
+static int hdsp_write_gain(struct hdsp *hdsp, unsigned int addr, unsigned short data)
 {
 	unsigned int ad;
 
@@ -844,7 +840,7 @@
 	return 0;
 }
 
-static int snd_hdsp_use_is_exclusive(hdsp_t *hdsp)
+static int snd_hdsp_use_is_exclusive(struct hdsp *hdsp)
 {
 	unsigned long flags;
 	int ret = 1;
@@ -857,7 +853,7 @@
 	return ret;
 }
 
-static int hdsp_external_sample_rate (hdsp_t *hdsp)
+static int hdsp_external_sample_rate (struct hdsp *hdsp)
 {
 	unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
 	unsigned int rate_bits = status2 & HDSP_systemFrequencyMask;
@@ -874,7 +870,7 @@
 	}
 }
 
-static int hdsp_spdif_sample_rate(hdsp_t *hdsp)
+static int hdsp_spdif_sample_rate(struct hdsp *hdsp)
 {
 	unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);
 	unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);
@@ -905,12 +901,12 @@
 	return 0;
 }
 
-static void hdsp_compute_period_size(hdsp_t *hdsp)
+static void hdsp_compute_period_size(struct hdsp *hdsp)
 {
 	hdsp->period_bytes = 1 << ((hdsp_decode_latency(hdsp->control_register) + 8));
 }
 
-static snd_pcm_uframes_t hdsp_hw_pointer(hdsp_t *hdsp)
+static snd_pcm_uframes_t hdsp_hw_pointer(struct hdsp *hdsp)
 {
 	int position;
 
@@ -925,29 +921,29 @@
 	return position;
 }
 
-static void hdsp_reset_hw_pointer(hdsp_t *hdsp)
+static void hdsp_reset_hw_pointer(struct hdsp *hdsp)
 {
 	hdsp_write (hdsp, HDSP_resetPointer, 0);
 }
 
-static void hdsp_start_audio(hdsp_t *s)
+static void hdsp_start_audio(struct hdsp *s)
 {
 	s->control_register |= (HDSP_AudioInterruptEnable | HDSP_Start);
 	hdsp_write(s, HDSP_controlRegister, s->control_register);
 }
 
-static void hdsp_stop_audio(hdsp_t *s)
+static void hdsp_stop_audio(struct hdsp *s)
 {
 	s->control_register &= ~(HDSP_Start | HDSP_AudioInterruptEnable);
 	hdsp_write(s, HDSP_controlRegister, s->control_register);
 }
 
-static void hdsp_silence_playback(hdsp_t *hdsp)
+static void hdsp_silence_playback(struct hdsp *hdsp)
 {
 	memset(hdsp->playback_buffer, 0, HDSP_DMA_AREA_BYTES);
 }
 
-static int hdsp_set_interrupt_interval(hdsp_t *s, unsigned int frames)
+static int hdsp_set_interrupt_interval(struct hdsp *s, unsigned int frames)
 {
 	int n;
 
@@ -972,7 +968,7 @@
 	return 0;
 }
 
-static int hdsp_set_rate(hdsp_t *hdsp, int rate, int called_internally)
+static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
 {
 	int reject_if_open = 0;
 	int current_rate;
@@ -1114,7 +1110,7 @@
    MIDI
   ----------------------------------------------------------------------------*/
 
-static unsigned char snd_hdsp_midi_read_byte (hdsp_t *hdsp, int id)
+static unsigned char snd_hdsp_midi_read_byte (struct hdsp *hdsp, int id)
 {
 	/* the hardware already does the relevant bit-mask with 0xff */
 	if (id)
@@ -1123,7 +1119,7 @@
 		return hdsp_read(hdsp, HDSP_midiDataIn0);
 }
 
-static void snd_hdsp_midi_write_byte (hdsp_t *hdsp, int id, int val)
+static void snd_hdsp_midi_write_byte (struct hdsp *hdsp, int id, int val)
 {
 	/* the hardware already does the relevant bit-mask with 0xff */
 	if (id)
@@ -1132,7 +1128,7 @@
 		hdsp_write(hdsp, HDSP_midiDataOut0, val);
 }
 
-static int snd_hdsp_midi_input_available (hdsp_t *hdsp, int id)
+static int snd_hdsp_midi_input_available (struct hdsp *hdsp, int id)
 {
 	if (id)
 		return (hdsp_read(hdsp, HDSP_midiStatusIn1) & 0xff);
@@ -1140,7 +1136,7 @@
 		return (hdsp_read(hdsp, HDSP_midiStatusIn0) & 0xff);
 }
 
-static int snd_hdsp_midi_output_possible (hdsp_t *hdsp, int id)
+static int snd_hdsp_midi_output_possible (struct hdsp *hdsp, int id)
 {
 	int fifo_bytes_used;
 
@@ -1155,13 +1151,13 @@
 		return 0;
 }
 
-static void snd_hdsp_flush_midi_input (hdsp_t *hdsp, int id)
+static void snd_hdsp_flush_midi_input (struct hdsp *hdsp, int id)
 {
 	while (snd_hdsp_midi_input_available (hdsp, id))
 		snd_hdsp_midi_read_byte (hdsp, id);
 }
 
-static int snd_hdsp_midi_output_write (hdsp_midi_t *hmidi)
+static int snd_hdsp_midi_output_write (struct hdsp_midi *hmidi)
 {
 	unsigned long flags;
 	int n_pending;
@@ -1189,7 +1185,7 @@
 	return 0;
 }
 
-static int snd_hdsp_midi_input_read (hdsp_midi_t *hmidi)
+static int snd_hdsp_midi_input_read (struct hdsp_midi *hmidi)
 {
 	unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */
 	unsigned long flags;
@@ -1221,14 +1217,14 @@
 	return snd_hdsp_midi_output_write (hmidi);
 }
 
-static void snd_hdsp_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_hdsp_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	hdsp_t *hdsp;
-	hdsp_midi_t *hmidi;
+	struct hdsp *hdsp;
+	struct hdsp_midi *hmidi;
 	unsigned long flags;
 	u32 ie;
 
-	hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
 	hdsp = hmidi->hdsp;
 	ie = hmidi->id ? HDSP_Midi1InterruptEnable : HDSP_Midi0InterruptEnable;
 	spin_lock_irqsave (&hdsp->lock, flags);
@@ -1248,7 +1244,7 @@
 
 static void snd_hdsp_midi_output_timer(unsigned long data)
 {
-	hdsp_midi_t *hmidi = (hdsp_midi_t *) data;
+	struct hdsp_midi *hmidi = (struct hdsp_midi *) data;
 	unsigned long flags;
 	
 	snd_hdsp_midi_output_write(hmidi);
@@ -1268,12 +1264,12 @@
 	spin_unlock_irqrestore (&hmidi->lock, flags);
 }
 
-static void snd_hdsp_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_hdsp_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	hdsp_midi_t *hmidi;
+	struct hdsp_midi *hmidi;
 	unsigned long flags;
 
-	hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
 	spin_lock_irqsave (&hmidi->lock, flags);
 	if (up) {
 		if (!hmidi->istimer) {
@@ -1293,11 +1289,11 @@
 		snd_hdsp_midi_output_write(hmidi);
 }
 
-static int snd_hdsp_midi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_hdsp_midi_input_open(struct snd_rawmidi_substream *substream)
 {
-	hdsp_midi_t *hmidi;
+	struct hdsp_midi *hmidi;
 
-	hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
 	spin_lock_irq (&hmidi->lock);
 	snd_hdsp_flush_midi_input (hmidi->hdsp, hmidi->id);
 	hmidi->input = substream;
@@ -1306,11 +1302,11 @@
 	return 0;
 }
 
-static int snd_hdsp_midi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_hdsp_midi_output_open(struct snd_rawmidi_substream *substream)
 {
-	hdsp_midi_t *hmidi;
+	struct hdsp_midi *hmidi;
 
-	hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
 	spin_lock_irq (&hmidi->lock);
 	hmidi->output = substream;
 	spin_unlock_irq (&hmidi->lock);
@@ -1318,13 +1314,13 @@
 	return 0;
 }
 
-static int snd_hdsp_midi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_hdsp_midi_input_close(struct snd_rawmidi_substream *substream)
 {
-	hdsp_midi_t *hmidi;
+	struct hdsp_midi *hmidi;
 
 	snd_hdsp_midi_input_trigger (substream, 0);
 
-	hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
 	spin_lock_irq (&hmidi->lock);
 	hmidi->input = NULL;
 	spin_unlock_irq (&hmidi->lock);
@@ -1332,13 +1328,13 @@
 	return 0;
 }
 
-static int snd_hdsp_midi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_hdsp_midi_output_close(struct snd_rawmidi_substream *substream)
 {
-	hdsp_midi_t *hmidi;
+	struct hdsp_midi *hmidi;
 
 	snd_hdsp_midi_output_trigger (substream, 0);
 
-	hmidi = (hdsp_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdsp_midi *) substream->rmidi->private_data;
 	spin_lock_irq (&hmidi->lock);
 	hmidi->output = NULL;
 	spin_unlock_irq (&hmidi->lock);
@@ -1346,21 +1342,21 @@
 	return 0;
 }
 
-static snd_rawmidi_ops_t snd_hdsp_midi_output =
+static struct snd_rawmidi_ops snd_hdsp_midi_output =
 {
 	.open =		snd_hdsp_midi_output_open,
 	.close =	snd_hdsp_midi_output_close,
 	.trigger =	snd_hdsp_midi_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_hdsp_midi_input =
+static struct snd_rawmidi_ops snd_hdsp_midi_input =
 {
 	.open =		snd_hdsp_midi_input_open,
 	.close =	snd_hdsp_midi_input_close,
 	.trigger =	snd_hdsp_midi_input_trigger,
 };
 
-static int __devinit snd_hdsp_create_midi (snd_card_t *card, hdsp_t *hdsp, int id)
+static int __devinit snd_hdsp_create_midi (struct snd_card *card, struct hdsp *hdsp, int id)
 {
 	char buf[32];
 
@@ -1394,7 +1390,7 @@
   Control Interface
   ----------------------------------------------------------------------------*/
 
-static u32 snd_hdsp_convert_from_aes(snd_aes_iec958_t *aes)
+static u32 snd_hdsp_convert_from_aes(struct snd_aes_iec958 *aes)
 {
 	u32 val = 0;
 	val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? HDSP_SPDIFProfessional : 0;
@@ -1406,7 +1402,7 @@
 	return val;
 }
 
-static void snd_hdsp_convert_to_aes(snd_aes_iec958_t *aes, u32 val)
+static void snd_hdsp_convert_to_aes(struct snd_aes_iec958 *aes, u32 val)
 {
 	aes->status[0] = ((val & HDSP_SPDIFProfessional) ? IEC958_AES0_PROFESSIONAL : 0) |
 			 ((val & HDSP_SPDIFNonAudio) ? IEC958_AES0_NONAUDIO : 0);
@@ -1416,24 +1412,24 @@
 		aes->status[0] |= (val & HDSP_SPDIFEmphasis) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
 }
 
-static int snd_hdsp_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_control_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_hdsp_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_control_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif);
 	return 0;
 }
 
-static int snd_hdsp_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	u32 val;
 	
@@ -1445,24 +1441,24 @@
 	return change;
 }
 
-static int snd_hdsp_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_control_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_hdsp_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_control_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	snd_hdsp_convert_to_aes(&ucontrol->value.iec958, hdsp->creg_spdif_stream);
 	return 0;
 }
 
-static int snd_hdsp_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_control_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	u32 val;
 	
@@ -1476,14 +1472,14 @@
 	return change;
 }
 
-static int snd_hdsp_control_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_control_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_hdsp_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_control_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = kcontrol->private_value;
 	return 0;
@@ -1497,12 +1493,12 @@
   .get = snd_hdsp_get_spdif_in, \
   .put = snd_hdsp_put_spdif_in }
 
-static unsigned int hdsp_spdif_in(hdsp_t *hdsp)
+static unsigned int hdsp_spdif_in(struct hdsp *hdsp)
 {
 	return hdsp_decode_spdif_in(hdsp->control_register & HDSP_SPDIFInputMask);
 }
 
-static int hdsp_set_spdif_input(hdsp_t *hdsp, int in)
+static int hdsp_set_spdif_input(struct hdsp *hdsp, int in)
 {
 	hdsp->control_register &= ~HDSP_SPDIFInputMask;
 	hdsp->control_register |= hdsp_encode_spdif_in(in);
@@ -1510,10 +1506,10 @@
 	return 0;
 }
 
-static int snd_hdsp_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = {"Optical", "Coaxial", "Internal", "AES"};
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -1524,17 +1520,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_spdif_in(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -1554,12 +1550,12 @@
   .info = snd_hdsp_info_spdif_bits, \
   .get = snd_hdsp_get_spdif_out, .put = snd_hdsp_put_spdif_out }
 
-static int hdsp_spdif_out(hdsp_t *hdsp)
+static int hdsp_spdif_out(struct hdsp *hdsp)
 {
 	return (hdsp->control_register & HDSP_SPDIFOpticalOut) ? 1 : 0;
 }
 
-static int hdsp_set_spdif_output(hdsp_t *hdsp, int out)
+static int hdsp_set_spdif_output(struct hdsp *hdsp, int out)
 {
 	if (out)
 		hdsp->control_register |= HDSP_SPDIFOpticalOut;
@@ -1569,7 +1565,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_spdif_bits(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_spdif_bits(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1578,17 +1574,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = hdsp_spdif_out(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -1607,12 +1603,12 @@
   .info = snd_hdsp_info_spdif_bits, \
   .get = snd_hdsp_get_spdif_professional, .put = snd_hdsp_put_spdif_professional }
 
-static int hdsp_spdif_professional(hdsp_t *hdsp)
+static int hdsp_spdif_professional(struct hdsp *hdsp)
 {
 	return (hdsp->control_register & HDSP_SPDIFProfessional) ? 1 : 0;
 }
 
-static int hdsp_set_spdif_professional(hdsp_t *hdsp, int val)
+static int hdsp_set_spdif_professional(struct hdsp *hdsp, int val)
 {
 	if (val)
 		hdsp->control_register |= HDSP_SPDIFProfessional;
@@ -1622,17 +1618,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = hdsp_spdif_professional(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_spdif_professional(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_spdif_professional(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -1651,12 +1647,12 @@
   .info = snd_hdsp_info_spdif_bits, \
   .get = snd_hdsp_get_spdif_emphasis, .put = snd_hdsp_put_spdif_emphasis }
 
-static int hdsp_spdif_emphasis(hdsp_t *hdsp)
+static int hdsp_spdif_emphasis(struct hdsp *hdsp)
 {
 	return (hdsp->control_register & HDSP_SPDIFEmphasis) ? 1 : 0;
 }
 
-static int hdsp_set_spdif_emphasis(hdsp_t *hdsp, int val)
+static int hdsp_set_spdif_emphasis(struct hdsp *hdsp, int val)
 {
 	if (val)
 		hdsp->control_register |= HDSP_SPDIFEmphasis;
@@ -1666,17 +1662,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = hdsp_spdif_emphasis(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_spdif_emphasis(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_spdif_emphasis(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -1695,12 +1691,12 @@
   .info = snd_hdsp_info_spdif_bits, \
   .get = snd_hdsp_get_spdif_nonaudio, .put = snd_hdsp_put_spdif_nonaudio }
 
-static int hdsp_spdif_nonaudio(hdsp_t *hdsp)
+static int hdsp_spdif_nonaudio(struct hdsp *hdsp)
 {
 	return (hdsp->control_register & HDSP_SPDIFNonAudio) ? 1 : 0;
 }
 
-static int hdsp_set_spdif_nonaudio(hdsp_t *hdsp, int val)
+static int hdsp_set_spdif_nonaudio(struct hdsp *hdsp, int val)
 {
 	if (val)
 		hdsp->control_register |= HDSP_SPDIFNonAudio;
@@ -1710,17 +1706,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = hdsp_spdif_nonaudio(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_spdif_nonaudio(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_spdif_nonaudio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -1743,10 +1739,10 @@
   .get = snd_hdsp_get_spdif_sample_rate \
 }
 
-static int snd_hdsp_info_spdif_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"};
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -1757,9 +1753,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_spdif_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_spdif_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	switch (hdsp_spdif_sample_rate(hdsp)) {
 	case 32000:
@@ -1804,16 +1800,16 @@
   .get = snd_hdsp_get_system_sample_rate \
 }
 
-static int snd_hdsp_info_system_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_system_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_hdsp_get_system_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_system_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp->system_sample_rate;
 	return 0;
@@ -1828,9 +1824,9 @@
   .get = snd_hdsp_get_autosync_sample_rate \
 }
 
-static int snd_hdsp_info_autosync_sample_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	static char *texts[] = {"32000", "44100", "48000", "64000", "88200", "96000", "None", "128000", "176400", "192000"};	
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -1841,9 +1837,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_autosync_sample_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	switch (hdsp_external_sample_rate(hdsp)) {
 	case 32000:
@@ -1888,7 +1884,7 @@
   .get = snd_hdsp_get_system_clock_mode \
 }
 
-static int hdsp_system_clock_mode(hdsp_t *hdsp)
+static int hdsp_system_clock_mode(struct hdsp *hdsp)
 {
 	if (hdsp->control_register & HDSP_ClockModeMaster)
 		return 0;
@@ -1897,7 +1893,7 @@
 	return 1;
 }
 
-static int snd_hdsp_info_system_clock_mode(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"Master", "Slave" };
 	
@@ -1910,9 +1906,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_system_clock_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_system_clock_mode(hdsp);
 	return 0;
@@ -1927,7 +1923,7 @@
   .put = snd_hdsp_put_clock_source \
 }
 
-static int hdsp_clock_source(hdsp_t *hdsp)
+static int hdsp_clock_source(struct hdsp *hdsp)
 {
 	if (hdsp->control_register & HDSP_ClockModeMaster) {
 		switch (hdsp->system_sample_rate) {
@@ -1957,7 +1953,7 @@
 	}
 }
 
-static int hdsp_set_clock_source(hdsp_t *hdsp, int mode)
+static int hdsp_set_clock_source(struct hdsp *hdsp, int mode)
 {
 	int rate;
 	switch (mode) {
@@ -2006,10 +2002,10 @@
 	return 0;
 }
 
-static int snd_hdsp_info_clock_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"AutoSync", "Internal 32.0 kHz", "Internal 44.1 kHz", "Internal 48.0 kHz", "Internal 64.0 kHz", "Internal 88.2 kHz", "Internal 96.0 kHz", "Internal 128 kHz", "Internal 176.4 kHz", "Internal 192.0 KHz" };
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -2023,17 +2019,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_clock_source(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_clock_source(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_clock_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	int val;
 	
@@ -2057,7 +2053,7 @@
 	return change;
 }
 
-static int snd_hdsp_info_clock_source_lock(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2066,17 +2062,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = hdsp->clock_source_locked;
 	return 0;
 }
 
-static int snd_hdsp_put_clock_source_lock(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 
 	change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked;
@@ -2094,7 +2090,7 @@
   .put = snd_hdsp_put_da_gain \
 }
 
-static int hdsp_da_gain(hdsp_t *hdsp)
+static int hdsp_da_gain(struct hdsp *hdsp)
 {
 	switch (hdsp->control_register & HDSP_DAGainMask) {
 	case HDSP_DAGainHighGain:
@@ -2108,7 +2104,7 @@
 	}
 }
 
-static int hdsp_set_da_gain(hdsp_t *hdsp, int mode)
+static int hdsp_set_da_gain(struct hdsp *hdsp, int mode)
 {
 	hdsp->control_register &= ~HDSP_DAGainMask;
 	switch (mode) {
@@ -2129,7 +2125,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_da_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"Hi Gain", "+4 dBu", "-10 dbV"};
 	
@@ -2142,17 +2138,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_da_gain(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_da_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_da_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	int val;
 	
@@ -2179,7 +2175,7 @@
   .put = snd_hdsp_put_ad_gain \
 }
 
-static int hdsp_ad_gain(hdsp_t *hdsp)
+static int hdsp_ad_gain(struct hdsp *hdsp)
 {
 	switch (hdsp->control_register & HDSP_ADGainMask) {
 	case HDSP_ADGainMinus10dBV:
@@ -2193,7 +2189,7 @@
 	}
 }
 
-static int hdsp_set_ad_gain(hdsp_t *hdsp, int mode)
+static int hdsp_set_ad_gain(struct hdsp *hdsp, int mode)
 {
 	hdsp->control_register &= ~HDSP_ADGainMask;
 	switch (mode) {
@@ -2214,7 +2210,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_ad_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"-10 dBV", "+4 dBu", "Lo Gain"};
 	
@@ -2227,17 +2223,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_ad_gain(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_ad_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_ad_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	int val;
 	
@@ -2264,7 +2260,7 @@
   .put = snd_hdsp_put_phone_gain \
 }
 
-static int hdsp_phone_gain(hdsp_t *hdsp)
+static int hdsp_phone_gain(struct hdsp *hdsp)
 {
 	switch (hdsp->control_register & HDSP_PhoneGainMask) {
 	case HDSP_PhoneGain0dB:
@@ -2278,7 +2274,7 @@
 	}
 }
 
-static int hdsp_set_phone_gain(hdsp_t *hdsp, int mode)
+static int hdsp_set_phone_gain(struct hdsp *hdsp, int mode)
 {
 	hdsp->control_register &= ~HDSP_PhoneGainMask;
 	switch (mode) {
@@ -2299,7 +2295,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_phone_gain(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"0 dB", "-6 dB", "-12 dB"};
 	
@@ -2312,17 +2308,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_phone_gain(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_phone_gain(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_phone_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	int val;
 	
@@ -2349,14 +2345,14 @@
   .put = snd_hdsp_put_xlr_breakout_cable \
 }
 
-static int hdsp_xlr_breakout_cable(hdsp_t *hdsp)
+static int hdsp_xlr_breakout_cable(struct hdsp *hdsp)
 {
 	if (hdsp->control_register & HDSP_XLRBreakoutCable)
 		return 1;
 	return 0;
 }
 
-static int hdsp_set_xlr_breakout_cable(hdsp_t *hdsp, int mode)
+static int hdsp_set_xlr_breakout_cable(struct hdsp *hdsp, int mode)
 {
 	if (mode)
 		hdsp->control_register |= HDSP_XLRBreakoutCable;
@@ -2366,7 +2362,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_xlr_breakout_cable(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2375,17 +2371,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_xlr_breakout_cable(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_xlr_breakout_cable(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	int val;
 	
@@ -2412,14 +2408,14 @@
   .put = snd_hdsp_put_aeb \
 }
 
-static int hdsp_aeb(hdsp_t *hdsp)
+static int hdsp_aeb(struct hdsp *hdsp)
 {
 	if (hdsp->control_register & HDSP_AnalogExtensionBoard)
 		return 1;
 	return 0;
 }
 
-static int hdsp_set_aeb(hdsp_t *hdsp, int mode)
+static int hdsp_set_aeb(struct hdsp *hdsp, int mode)
 {
 	if (mode)
 		hdsp->control_register |= HDSP_AnalogExtensionBoard;
@@ -2429,7 +2425,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_aeb(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2438,17 +2434,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_aeb(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_aeb(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	int val;
 	
@@ -2471,7 +2467,7 @@
   .put = snd_hdsp_put_pref_sync_ref \
 }
 
-static int hdsp_pref_sync_ref(hdsp_t *hdsp)
+static int hdsp_pref_sync_ref(struct hdsp *hdsp)
 {
 	/* Notice that this looks at the requested sync source,
 	   not the one actually in use.
@@ -2496,7 +2492,7 @@
 	return 0;
 }
 
-static int hdsp_set_pref_sync_ref(hdsp_t *hdsp, int pref)
+static int hdsp_set_pref_sync_ref(struct hdsp *hdsp, int pref)
 {
 	hdsp->control_register &= ~HDSP_SyncRefMask;
 	switch (pref) {
@@ -2525,10 +2521,10 @@
 	return 0;
 }
 
-static int snd_hdsp_info_pref_sync_ref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"Word", "IEC958", "ADAT1", "ADAT Sync", "ADAT2", "ADAT3" };
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -2555,17 +2551,17 @@
 	return 0;
 }
 
-static int snd_hdsp_get_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_pref_sync_ref(hdsp);
 	return 0;
 }
 
-static int snd_hdsp_put_pref_sync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change, max;
 	unsigned int val;
 	
@@ -2604,7 +2600,7 @@
   .get = snd_hdsp_get_autosync_ref, \
 }
 
-static int hdsp_autosync_ref(hdsp_t *hdsp)
+static int hdsp_autosync_ref(struct hdsp *hdsp)
 {
 	/* This looks at the autosync selected sync reference */
 	unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
@@ -2630,7 +2626,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_autosync_ref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"Word", "ADAT Sync", "IEC958", "None", "ADAT1", "ADAT2", "ADAT3" };
 	
@@ -2643,9 +2639,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_autosync_ref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_autosync_ref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.enumerated.item[0] = hdsp_autosync_ref(hdsp);
 	return 0;
@@ -2660,12 +2656,12 @@
   .put = snd_hdsp_put_line_out \
 }
 
-static int hdsp_line_out(hdsp_t *hdsp)
+static int hdsp_line_out(struct hdsp *hdsp)
 {
 	return (hdsp->control_register & HDSP_LineOut) ? 1 : 0;
 }
 
-static int hdsp_set_line_output(hdsp_t *hdsp, int out)
+static int hdsp_set_line_output(struct hdsp *hdsp, int out)
 {
 	if (out)
 		hdsp->control_register |= HDSP_LineOut;
@@ -2675,7 +2671,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_line_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2684,9 +2680,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&hdsp->lock);
 	ucontrol->value.integer.value[0] = hdsp_line_out(hdsp);
@@ -2694,9 +2690,9 @@
 	return 0;
 }
 
-static int snd_hdsp_put_line_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -2719,7 +2715,7 @@
   .put = snd_hdsp_put_precise_pointer \
 }
 
-static int hdsp_set_precise_pointer(hdsp_t *hdsp, int precise)
+static int hdsp_set_precise_pointer(struct hdsp *hdsp, int precise)
 {
 	if (precise)
 		hdsp->precise_ptr = 1;
@@ -2728,7 +2724,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_precise_pointer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2737,9 +2733,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&hdsp->lock);
 	ucontrol->value.integer.value[0] = hdsp->precise_ptr;
@@ -2747,9 +2743,9 @@
 	return 0;
 }
 
-static int snd_hdsp_put_precise_pointer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -2772,7 +2768,7 @@
   .put = snd_hdsp_put_use_midi_tasklet \
 }
 
-static int hdsp_set_use_midi_tasklet(hdsp_t *hdsp, int use_tasklet)
+static int hdsp_set_use_midi_tasklet(struct hdsp *hdsp, int use_tasklet)
 {
 	if (use_tasklet)
 		hdsp->use_midi_tasklet = 1;
@@ -2781,7 +2777,7 @@
 	return 0;
 }
 
-static int snd_hdsp_info_use_midi_tasklet(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2790,9 +2786,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_use_midi_tasklet(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&hdsp->lock);
 	ucontrol->value.integer.value[0] = hdsp->use_midi_tasklet;
@@ -2800,9 +2796,9 @@
 	return 0;
 }
 
-static int snd_hdsp_put_use_midi_tasklet(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -2828,7 +2824,7 @@
   .put = snd_hdsp_put_mixer \
 }
 
-static int snd_hdsp_info_mixer(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 3;
@@ -2838,9 +2834,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int source;
 	int destination;
 	int addr;
@@ -2859,9 +2855,9 @@
 	return 0;
 }
 
-static int snd_hdsp_put_mixer(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_put_mixer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 	int change;
 	int source;
 	int destination;
@@ -2898,7 +2894,7 @@
   .get = snd_hdsp_get_wc_sync_check \
 }
 
-static int snd_hdsp_info_sync_check(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_hdsp_info_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = {"No Lock", "Lock", "Sync" };	
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -2910,7 +2906,7 @@
 	return 0;
 }
 
-static int hdsp_wc_sync_check(hdsp_t *hdsp)
+static int hdsp_wc_sync_check(struct hdsp *hdsp)
 {
 	int status2 = hdsp_read(hdsp, HDSP_status2Register);
 	if (status2 & HDSP_wc_lock) {
@@ -2923,9 +2919,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_wc_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_wc_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = hdsp_wc_sync_check(hdsp);
 	return 0;
@@ -2940,7 +2936,7 @@
   .get = snd_hdsp_get_spdif_sync_check \
 }
 
-static int hdsp_spdif_sync_check(hdsp_t *hdsp)
+static int hdsp_spdif_sync_check(struct hdsp *hdsp)
 {
 	int status = hdsp_read(hdsp, HDSP_statusRegister);
 	if (status & HDSP_SPDIFErrorFlag)
@@ -2954,9 +2950,9 @@
 	return 0;
 }
 
-static int snd_hdsp_get_spdif_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_spdif_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = hdsp_spdif_sync_check(hdsp);
 	return 0;
@@ -2971,7 +2967,7 @@
   .get = snd_hdsp_get_adatsync_sync_check \
 }
 
-static int hdsp_adatsync_sync_check(hdsp_t *hdsp)
+static int hdsp_adatsync_sync_check(struct hdsp *hdsp)
 {
 	int status = hdsp_read(hdsp, HDSP_statusRegister);
 	if (status & HDSP_TimecodeLock) {
@@ -2983,9 +2979,9 @@
 		return 0;
 }	
 
-static int snd_hdsp_get_adatsync_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_adatsync_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = hdsp_adatsync_sync_check(hdsp);
 	return 0;
@@ -2998,7 +2994,7 @@
   .get = snd_hdsp_get_adat_sync_check \
 }
 
-static int hdsp_adat_sync_check(hdsp_t *hdsp, int idx)
+static int hdsp_adat_sync_check(struct hdsp *hdsp, int idx)
 {	
 	int status = hdsp_read(hdsp, HDSP_statusRegister);
 	
@@ -3011,10 +3007,10 @@
 		return 0;
 } 
 
-static int snd_hdsp_get_adat_sync_check(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	int offset;
-	hdsp_t *hdsp = snd_kcontrol_chip(kcontrol);
+	struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
 
 	offset = ucontrol->id.index - 1;
 	snd_assert(offset >= 0);
@@ -3038,14 +3034,14 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_hdsp_9632_controls[] = {
+static struct snd_kcontrol_new snd_hdsp_9632_controls[] = {
 HDSP_DA_GAIN("DA Gain", 0),
 HDSP_AD_GAIN("AD Gain", 0),
 HDSP_PHONE_GAIN("Phones Gain", 0),
 HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0)
 };
 
-static snd_kcontrol_new_t snd_hdsp_controls[] = {
+static struct snd_kcontrol_new snd_hdsp_controls[] = {
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -3111,14 +3107,14 @@
 HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
 };
 
-static snd_kcontrol_new_t snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
-static snd_kcontrol_new_t snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
+static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
+static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
 
-static int snd_hdsp_create_controls(snd_card_t *card, hdsp_t *hdsp)
+static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
 {
 	unsigned int idx;
 	int err;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
 		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
@@ -3162,9 +3158,9 @@
  ------------------------------------------------------------*/
 
 static void
-snd_hdsp_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	hdsp_t *hdsp = (hdsp_t *) entry->private_data;
+	struct hdsp *hdsp = (struct hdsp *) entry->private_data;
 	unsigned int status;
 	unsigned int status2;
 	char *pref_sync_ref;
@@ -3469,21 +3465,21 @@
 
 }
 
-static void __devinit snd_hdsp_proc_init(hdsp_t *hdsp)
+static void __devinit snd_hdsp_proc_init(struct hdsp *hdsp)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(hdsp->card, "hdsp", &entry))
 		snd_info_set_text_ops(entry, hdsp, 1024, snd_hdsp_proc_read);
 }
 
-static void snd_hdsp_free_buffers(hdsp_t *hdsp)
+static void snd_hdsp_free_buffers(struct hdsp *hdsp)
 {
 	snd_hammerfall_free_buffer(&hdsp->capture_dma_buf, hdsp->pci);
 	snd_hammerfall_free_buffer(&hdsp->playback_dma_buf, hdsp->pci);
 }
 
-static int __devinit snd_hdsp_initialize_memory(hdsp_t *hdsp)
+static int __devinit snd_hdsp_initialize_memory(struct hdsp *hdsp)
 {
 	unsigned long pb_bus, cb_bus;
 
@@ -3511,7 +3507,7 @@
 	return 0;
 }
 
-static int snd_hdsp_set_defaults(hdsp_t *hdsp)
+static int snd_hdsp_set_defaults(struct hdsp *hdsp)
 {
 	unsigned int i;
 
@@ -3576,7 +3572,7 @@
 
 static void hdsp_midi_tasklet(unsigned long arg)
 {
-	hdsp_t *hdsp = (hdsp_t *)arg;
+	struct hdsp *hdsp = (struct hdsp *)arg;
 	
 	if (hdsp->midi[0].pending)
 		snd_hdsp_midi_input_read (&hdsp->midi[0]);
@@ -3586,7 +3582,7 @@
 
 static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	hdsp_t *hdsp = (hdsp_t *) dev_id;
+	struct hdsp *hdsp = (struct hdsp *) dev_id;
 	unsigned int status;
 	int audio;
 	int midi0;
@@ -3644,13 +3640,13 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_uframes_t snd_hdsp_hw_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_hdsp_hw_pointer(struct snd_pcm_substream *substream)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 	return hdsp_hw_pointer(hdsp);
 }
 
-static char *hdsp_channel_buffer_location(hdsp_t *hdsp,
+static char *hdsp_channel_buffer_location(struct hdsp *hdsp,
 					     int stream,
 					     int channel)
 
@@ -3668,10 +3664,10 @@
 		return hdsp->playback_buffer + (mapped_channel * HDSP_CHANNEL_BUFFER_BYTES);
 }
 
-static int snd_hdsp_playback_copy(snd_pcm_substream_t *substream, int channel,
+static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, int channel,
 				  snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 	char *channel_buf;
 
 	snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
@@ -3683,10 +3679,10 @@
 	return count;
 }
 
-static int snd_hdsp_capture_copy(snd_pcm_substream_t *substream, int channel,
+static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, int channel,
 				 snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 	char *channel_buf;
 
 	snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
@@ -3698,10 +3694,10 @@
 	return count;
 }
 
-static int snd_hdsp_hw_silence(snd_pcm_substream_t *substream, int channel,
+static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream, int channel,
 				  snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 	char *channel_buf;
 
 	channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel);
@@ -3710,11 +3706,11 @@
 	return count;
 }
 
-static int snd_hdsp_reset(snd_pcm_substream_t *substream)
+static int snd_hdsp_reset(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
-	snd_pcm_substream_t *other;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+	struct snd_pcm_substream *other;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		other = hdsp->capture_substream;
 	else
@@ -3725,8 +3721,8 @@
 		runtime->status->hw_ptr = 0;
 	if (other) {
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
-		snd_pcm_runtime_t *oruntime = other->runtime;
+		struct snd_pcm_substream *s;
+		struct snd_pcm_runtime *oruntime = other->runtime;
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == other) {
@@ -3738,10 +3734,10 @@
 	return 0;
 }
 
-static int snd_hdsp_hw_params(snd_pcm_substream_t *substream,
-				 snd_pcm_hw_params_t *params)
+static int snd_hdsp_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 	int err;
 	pid_t this_pid;
 	pid_t other_pid;
@@ -3813,10 +3809,10 @@
 	return 0;
 }
 
-static int snd_hdsp_channel_info(snd_pcm_substream_t *substream,
-				    snd_pcm_channel_info_t *info)
+static int snd_hdsp_channel_info(struct snd_pcm_substream *substream,
+				    struct snd_pcm_channel_info *info)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 	int mapped_channel;
 
 	snd_assert(info->channel < hdsp->max_channels, return -EINVAL);
@@ -3830,7 +3826,7 @@
 	return 0;
 }
 
-static int snd_hdsp_ioctl(snd_pcm_substream_t *substream,
+static int snd_hdsp_ioctl(struct snd_pcm_substream *substream,
 			     unsigned int cmd, void *arg)
 {
 	switch (cmd) {
@@ -3845,10 +3841,10 @@
 	return snd_pcm_lib_ioctl(substream, cmd, arg);
 }
 
-static int snd_hdsp_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
-	snd_pcm_substream_t *other;
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+	struct snd_pcm_substream *other;
 	int running;
 	
 	if (hdsp_check_for_iobox (hdsp))
@@ -3878,7 +3874,7 @@
 
 	if (other) {
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
+		struct snd_pcm_substream *s;
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == other) {
@@ -3915,9 +3911,9 @@
 	return 0;
 }
 
-static int snd_hdsp_prepare(snd_pcm_substream_t *substream)
+static int snd_hdsp_prepare(struct snd_pcm_substream *substream)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 	int result = 0;
 
 	if (hdsp_check_for_iobox (hdsp))
@@ -3933,7 +3929,7 @@
 	return result;
 }
 
-static snd_pcm_hardware_t snd_hdsp_playback_subinfo =
+static struct snd_pcm_hardware snd_hdsp_playback_subinfo =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_MMAP_VALID |
@@ -3963,7 +3959,7 @@
 	.fifo_size =		0
 };
 
-static snd_pcm_hardware_t snd_hdsp_capture_subinfo =
+static struct snd_pcm_hardware snd_hdsp_capture_subinfo =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_MMAP_VALID |
@@ -3994,7 +3990,7 @@
 
 static unsigned int hdsp_period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
 
-static snd_pcm_hw_constraint_list_t hdsp_hw_constraints_period_sizes = {
+static struct snd_pcm_hw_constraint_list hdsp_hw_constraints_period_sizes = {
 	.count = ARRAY_SIZE(hdsp_period_sizes),
 	.list = hdsp_period_sizes,
 	.mask = 0
@@ -4002,17 +3998,17 @@
 
 static unsigned int hdsp_9632_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 };
 
-static snd_pcm_hw_constraint_list_t hdsp_hw_constraints_9632_sample_rates = {
+static struct snd_pcm_hw_constraint_list hdsp_hw_constraints_9632_sample_rates = {
 	.count = ARRAY_SIZE(hdsp_9632_sample_rates),
 	.list = hdsp_9632_sample_rates,
 	.mask = 0
 };
 
-static int snd_hdsp_hw_rule_in_channels(snd_pcm_hw_params_t *params,
-					snd_pcm_hw_rule_t *rule)
+static int snd_hdsp_hw_rule_in_channels(struct snd_pcm_hw_params *params,
+					struct snd_pcm_hw_rule *rule)
 {
-	hdsp_t *hdsp = rule->private;
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct hdsp *hdsp = rule->private;
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 	if (hdsp->io_type == H9632) {
 		unsigned int list[3];
 		list[0] = hdsp->qs_in_channels;
@@ -4027,12 +4023,12 @@
 	}
 }
 
-static int snd_hdsp_hw_rule_out_channels(snd_pcm_hw_params_t *params,
-					snd_pcm_hw_rule_t *rule)
+static int snd_hdsp_hw_rule_out_channels(struct snd_pcm_hw_params *params,
+					struct snd_pcm_hw_rule *rule)
 {
 	unsigned int list[3];
-	hdsp_t *hdsp = rule->private;
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct hdsp *hdsp = rule->private;
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 	if (hdsp->io_type == H9632) {
 		list[0] = hdsp->qs_out_channels;
 		list[1] = hdsp->ds_out_channels;
@@ -4045,28 +4041,28 @@
 	return snd_interval_list(c, 2, list, 0);
 }
 
-static int snd_hdsp_hw_rule_in_channels_rate(snd_pcm_hw_params_t *params,
-					     snd_pcm_hw_rule_t *rule)
+static int snd_hdsp_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params,
+					     struct snd_pcm_hw_rule *rule)
 {
-	hdsp_t *hdsp = rule->private;
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct hdsp *hdsp = rule->private;
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (r->min > 96000 && hdsp->io_type == H9632) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = hdsp->qs_in_channels,
 			.max = hdsp->qs_in_channels,
 			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);	
 	} else if (r->min > 48000 && r->max <= 96000) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = hdsp->ds_in_channels,
 			.max = hdsp->ds_in_channels,
 			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);
 	} else if (r->max < 64000) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = hdsp->ss_in_channels,
 			.max = hdsp->ss_in_channels,
 			.integer = 1,
@@ -4076,28 +4072,28 @@
 	return 0;
 }
 
-static int snd_hdsp_hw_rule_out_channels_rate(snd_pcm_hw_params_t *params,
-					     snd_pcm_hw_rule_t *rule)
+static int snd_hdsp_hw_rule_out_channels_rate(struct snd_pcm_hw_params *params,
+					     struct snd_pcm_hw_rule *rule)
 {
-	hdsp_t *hdsp = rule->private;
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct hdsp *hdsp = rule->private;
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (r->min > 96000 && hdsp->io_type == H9632) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = hdsp->qs_out_channels,
 			.max = hdsp->qs_out_channels,
 			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);	
 	} else if (r->min > 48000 && r->max <= 96000) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = hdsp->ds_out_channels,
 			.max = hdsp->ds_out_channels,
 			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);
 	} else if (r->max < 64000) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = hdsp->ss_out_channels,
 			.max = hdsp->ss_out_channels,
 			.integer = 1,
@@ -4107,28 +4103,28 @@
 	return 0;
 }
 
-static int snd_hdsp_hw_rule_rate_out_channels(snd_pcm_hw_params_t *params,
-					     snd_pcm_hw_rule_t *rule)
+static int snd_hdsp_hw_rule_rate_out_channels(struct snd_pcm_hw_params *params,
+					     struct snd_pcm_hw_rule *rule)
 {
-	hdsp_t *hdsp = rule->private;
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct hdsp *hdsp = rule->private;
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (c->min >= hdsp->ss_out_channels) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 32000,
 			.max = 48000,
 			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	} else if (c->max <= hdsp->qs_out_channels && hdsp->io_type == H9632) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 128000,
 			.max = 192000,
 			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	} else if (c->max <= hdsp->ds_out_channels) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 64000,
 			.max = 96000,
 			.integer = 1,
@@ -4138,28 +4134,28 @@
 	return 0;
 }
 
-static int snd_hdsp_hw_rule_rate_in_channels(snd_pcm_hw_params_t *params,
-					     snd_pcm_hw_rule_t *rule)
+static int snd_hdsp_hw_rule_rate_in_channels(struct snd_pcm_hw_params *params,
+					     struct snd_pcm_hw_rule *rule)
 {
-	hdsp_t *hdsp = rule->private;
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct hdsp *hdsp = rule->private;
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (c->min >= hdsp->ss_in_channels) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 32000,
 			.max = 48000,
 			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	} else if (c->max <= hdsp->qs_in_channels && hdsp->io_type == H9632) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 128000,
 			.max = 192000,
 			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	} else if (c->max <= hdsp->ds_in_channels) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 64000,
 			.max = 96000,
 			.integer = 1,
@@ -4169,10 +4165,10 @@
 	return 0;
 }
 
-static int snd_hdsp_playback_open(snd_pcm_substream_t *substream)
+static int snd_hdsp_playback_open(struct snd_pcm_substream *substream)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
@@ -4224,9 +4220,9 @@
 	return 0;
 }
 
-static int snd_hdsp_playback_release(snd_pcm_substream_t *substream)
+static int snd_hdsp_playback_release(struct snd_pcm_substream *substream)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&hdsp->lock);
 
@@ -4242,10 +4238,10 @@
 }
 
 
-static int snd_hdsp_capture_open(snd_pcm_substream_t *substream)
+static int snd_hdsp_capture_open(struct snd_pcm_substream *substream)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (hdsp_check_for_iobox (hdsp))
 		return -EIO;
@@ -4287,9 +4283,9 @@
 	return 0;
 }
 
-static int snd_hdsp_capture_release(snd_pcm_substream_t *substream)
+static int snd_hdsp_capture_release(struct snd_pcm_substream *substream)
 {
-	hdsp_t *hdsp = snd_pcm_substream_chip(substream);
+	struct hdsp *hdsp = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&hdsp->lock);
 
@@ -4300,7 +4296,7 @@
 	return 0;
 }
 
-static int snd_hdsp_hwdep_dummy_op(snd_hwdep_t *hw, struct file *file)
+static int snd_hdsp_hwdep_dummy_op(struct snd_hwdep *hw, struct file *file)
 {
 	/* we have nothing to initialize but the call is required */
 	return 0;
@@ -4334,7 +4330,7 @@
 	return copy_to_user(dest, &rms, 8);
 }
 
-static int hdsp_9652_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
+static int hdsp_9652_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rms)
 {
 	int doublespeed = 0;
 	int i, j, channels, ofs;
@@ -4371,15 +4367,15 @@
 	return 0;
 }
 
-static int hdsp_9632_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
+static int hdsp_9632_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rms)
 {
 	int i, j;
-	hdsp_9632_meters_t __iomem *m;
+	struct hdsp_9632_meters __iomem *m;
 	int doublespeed = 0;
 
 	if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DoubleSpeedStatus)
 		doublespeed = 1;
-	m = (hdsp_9632_meters_t __iomem *)(hdsp->iobase+HDSP_9632_metersBase);
+	m = (struct hdsp_9632_meters __iomem *)(hdsp->iobase+HDSP_9632_metersBase);
 	for (i = 0, j = 0; i < 16; ++i, ++j) {
 		if (copy_u32_le(&peak_rms->input_peaks[i], &m->input_peak[j]))
 			return -EFAULT;
@@ -4401,7 +4397,7 @@
 	return 0;
 }
 
-static int hdsp_get_peak(hdsp_t *hdsp, hdsp_peak_rms_t __user *peak_rms)
+static int hdsp_get_peak(struct hdsp *hdsp, struct hdsp_peak_rms __user *peak_rms)
 {
 	int i;
 
@@ -4431,14 +4427,14 @@
 	return 0;
 }
 
-static int snd_hdsp_hwdep_ioctl(snd_hwdep_t *hw, struct file *file, unsigned int cmd, unsigned long arg)
+static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigned int cmd, unsigned long arg)
 {
-	hdsp_t *hdsp = (hdsp_t *)hw->private_data;	
+	struct hdsp *hdsp = (struct hdsp *)hw->private_data;	
 	void __user *argp = (void __user *)arg;
 
 	switch (cmd) {
 	case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: {
-		hdsp_peak_rms_t __user *peak_rms = (hdsp_peak_rms_t __user *)arg;
+		struct hdsp_peak_rms __user *peak_rms = (struct hdsp_peak_rms __user *)arg;
 
 		if (!(hdsp->state & HDSP_FirmwareLoaded)) {
 			snd_printk(KERN_ERR "Hammerfall-DSP: firmware needs to be uploaded to the card.\n");
@@ -4455,7 +4451,7 @@
 		}
 	}
 	case SNDRV_HDSP_IOCTL_GET_CONFIG_INFO: {
-		hdsp_config_info_t info;
+		struct hdsp_config_info info;
 		unsigned long flags;
 		int i;
 		
@@ -4498,7 +4494,7 @@
 		break;
 	}
 	case SNDRV_HDSP_IOCTL_GET_9632_AEB: {
-		hdsp_9632_aeb_t h9632_aeb;
+		struct hdsp_9632_aeb h9632_aeb;
 		
 		if (hdsp->io_type != H9632) return -EINVAL;
 		h9632_aeb.aebi = hdsp->ss_in_channels - H9632_SS_CHANNELS;
@@ -4508,7 +4504,7 @@
 		break;
 	}
 	case SNDRV_HDSP_IOCTL_GET_VERSION: {
-		hdsp_version_t hdsp_version;
+		struct hdsp_version hdsp_version;
 		int err;
 		
 		if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return -EINVAL;
@@ -4523,7 +4519,7 @@
 		break;
 	}
 	case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
-		hdsp_firmware_t __user *firmware;
+		struct hdsp_firmware __user *firmware;
 		u32 __user *firmware_data;
 		int err;
 		
@@ -4535,7 +4531,7 @@
 			return -EBUSY;
 
 		snd_printk(KERN_INFO "Hammerfall-DSP: initializing firmware upload\n");
-		firmware = (hdsp_firmware_t __user *)argp;
+		firmware = (struct hdsp_firmware __user *)argp;
 
 		if (get_user(firmware_data, &firmware->firmware_data))
 			return -EFAULT;
@@ -4566,7 +4562,7 @@
 		break;
 	}
 	case SNDRV_HDSP_IOCTL_GET_MIXER: {
-		hdsp_mixer_t __user *mixer = (hdsp_mixer_t __user *)argp;
+		struct hdsp_mixer __user *mixer = (struct hdsp_mixer __user *)argp;
 		if (copy_to_user(mixer->matrix, hdsp->mixer_matrix, sizeof(unsigned short)*HDSP_MATRIX_MIXER_SIZE))
 			return -EFAULT;
 		break;
@@ -4577,7 +4573,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_hdsp_playback_ops = {
+static struct snd_pcm_ops snd_hdsp_playback_ops = {
 	.open =		snd_hdsp_playback_open,
 	.close =	snd_hdsp_playback_release,
 	.ioctl =	snd_hdsp_ioctl,
@@ -4589,7 +4585,7 @@
 	.silence =	snd_hdsp_hw_silence,
 };
 
-static snd_pcm_ops_t snd_hdsp_capture_ops = {
+static struct snd_pcm_ops snd_hdsp_capture_ops = {
 	.open =		snd_hdsp_capture_open,
 	.close =	snd_hdsp_capture_release,
 	.ioctl =	snd_hdsp_ioctl,
@@ -4600,10 +4596,10 @@
 	.copy =		snd_hdsp_capture_copy,
 };
 
-static int __devinit snd_hdsp_create_hwdep(snd_card_t *card,
-					   hdsp_t *hdsp)
+static int __devinit snd_hdsp_create_hwdep(struct snd_card *card,
+					   struct hdsp *hdsp)
 {
-	snd_hwdep_t *hw;
+	struct snd_hwdep *hw;
 	int err;
 	
 	if ((err = snd_hwdep_new(card, "HDSP hwdep", 0, &hw)) < 0)
@@ -4620,9 +4616,9 @@
 	return 0;
 }
 
-static int snd_hdsp_create_pcm(snd_card_t *card, hdsp_t *hdsp)
+static int snd_hdsp_create_pcm(struct snd_card *card, struct hdsp *hdsp)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(card, hdsp->card_name, 0, 1, 1, &pcm)) < 0)
@@ -4640,13 +4636,13 @@
 	return 0;
 }
 
-static void snd_hdsp_9652_enable_mixer (hdsp_t *hdsp)
+static void snd_hdsp_9652_enable_mixer (struct hdsp *hdsp)
 {
         hdsp->control2_register |= HDSP_9652_ENABLE_MIXER;
 	hdsp_write (hdsp, HDSP_control2Reg, hdsp->control2_register);
 }
 
-static int snd_hdsp_enable_io (hdsp_t *hdsp)
+static int snd_hdsp_enable_io (struct hdsp *hdsp)
 {
 	int i;
 	
@@ -4663,7 +4659,7 @@
 	return 0;
 }
 
-static void snd_hdsp_initialize_channels(hdsp_t *hdsp)
+static void snd_hdsp_initialize_channels(struct hdsp *hdsp)
 {
 	int status, aebi_channels, aebo_channels;
 	
@@ -4706,13 +4702,13 @@
 	}
 }
 
-static void snd_hdsp_initialize_midi_flush (hdsp_t *hdsp)
+static void snd_hdsp_initialize_midi_flush (struct hdsp *hdsp)
 {
 	snd_hdsp_flush_midi_input (hdsp, 0);
 	snd_hdsp_flush_midi_input (hdsp, 1);
 }
 
-static int snd_hdsp_create_alsa_devices(snd_card_t *card, hdsp_t *hdsp)
+static int snd_hdsp_create_alsa_devices(struct snd_card *card, struct hdsp *hdsp)
 {
 	int err;
 	
@@ -4769,7 +4765,7 @@
 
 #ifdef HDSP_FW_LOADER
 /* load firmware via hotplug fw loader */
-static int __devinit hdsp_request_fw_loader(hdsp_t *hdsp)
+static int __devinit hdsp_request_fw_loader(struct hdsp *hdsp)
 {
 	const char *fwfile;
 	const struct firmware *fw;
@@ -4842,8 +4838,8 @@
 }
 #endif
 
-static int __devinit snd_hdsp_create(snd_card_t *card,
-				     hdsp_t *hdsp)
+static int __devinit snd_hdsp_create(struct snd_card *card,
+				     struct hdsp *hdsp)
 {
 	struct pci_dev *pci = hdsp->pci;
 	int err;
@@ -4980,7 +4976,7 @@
 	return 0;	
 }
 
-static int snd_hdsp_free(hdsp_t *hdsp)
+static int snd_hdsp_free(struct hdsp *hdsp)
 {
 	if (hdsp->port) {
 		/* stop the audio, and cancel all interrupts */
@@ -5004,9 +5000,9 @@
 	return 0;
 }
 
-static void snd_hdsp_card_free(snd_card_t *card)
+static void snd_hdsp_card_free(struct snd_card *card)
 {
-	hdsp_t *hdsp = (hdsp_t *) card->private_data;
+	struct hdsp *hdsp = (struct hdsp *) card->private_data;
 
 	if (hdsp)
 		snd_hdsp_free(hdsp);
@@ -5016,8 +5012,8 @@
 				    const struct pci_device_id *pci_id)
 {
 	static int dev;
-	hdsp_t *hdsp;
-	snd_card_t *card;
+	struct hdsp *hdsp;
+	struct snd_card *card;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -5027,10 +5023,10 @@
 		return -ENOENT;
 	}
 
-	if (!(card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(hdsp_t))))
+	if (!(card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct hdsp))))
 		return -ENOMEM;
 
-	hdsp = (hdsp_t *) card->private_data;
+	hdsp = (struct hdsp *) card->private_data;
 	card->private_free = snd_hdsp_card_free;
 	hdsp->dev = dev;
 	hdsp->pci = pci;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index a1aef6f..3dec616 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -318,25 +318,22 @@
 #define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
 #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
 
-typedef struct _hdspm hdspm_t;
-typedef struct _hdspm_midi hdspm_midi_t;
-
-struct _hdspm_midi {
-	hdspm_t *hdspm;
+struct hdspm_midi {
+	struct hdspm *hdspm;
 	int id;
-	snd_rawmidi_t *rmidi;
-	snd_rawmidi_substream_t *input;
-	snd_rawmidi_substream_t *output;
+	struct snd_rawmidi *rmidi;
+	struct snd_rawmidi_substream *input;
+	struct snd_rawmidi_substream *output;
 	char istimer;		/* timer in use */
 	struct timer_list timer;
 	spinlock_t lock;
 	int pending;
 };
 
-struct _hdspm {
+struct hdspm {
         spinlock_t lock;
-        snd_pcm_substream_t *capture_substream;	 /* only one playback */
-        snd_pcm_substream_t *playback_substream; /* and/or capture stream */
+        struct snd_pcm_substream *capture_substream;	 /* only one playback */
+        struct snd_pcm_substream *playback_substream; /* and/or capture stream */
 
 	char *card_name;	     /* for procinfo */
 	unsigned short firmware_rev; /* dont know if relevant */
@@ -347,7 +344,7 @@
 	u32 control_register;	/* cached value */
 	u32 control2_register;	/* cached value */
 
-	hdspm_midi_t midi[2];
+	struct hdspm_midi midi[2];
 	struct tasklet_struct midi_tasklet;
 
 	size_t period_bytes;
@@ -375,15 +372,15 @@
 
 	int irq_count;		/* for debug */
 
-	snd_card_t *card;	/* one card */
-	snd_pcm_t *pcm;		/* has one pcm */
-	snd_hwdep_t *hwdep;	/* and a hwdep for additional ioctl */
+	struct snd_card *card;	/* one card */
+	struct snd_pcm *pcm;		/* has one pcm */
+	struct snd_hwdep *hwdep;	/* and a hwdep for additional ioctl */
 	struct pci_dev *pci;	/* and an pci info */
 
 	/* Mixer vars */
-	snd_kcontrol_t *playback_mixer_ctls[HDSPM_MAX_CHANNELS];	/* fast alsa mixer */
-	snd_kcontrol_t *input_mixer_ctls[HDSPM_MAX_CHANNELS];	/* but input to much, so not used */
-	hdspm_mixer_t *mixer;	/* full mixer accessable over mixer ioctl or hwdep-device */
+	struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS];	/* fast alsa mixer */
+	struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS];	/* but input to much, so not used */
+	struct hdspm_mixer *mixer;	/* full mixer accessable over mixer ioctl or hwdep-device */
 
 };
 
@@ -444,28 +441,28 @@
 MODULE_DEVICE_TABLE(pci, snd_hdspm_ids);
 
 /* prototypes */
-static int __devinit snd_hdspm_create_alsa_devices(snd_card_t * card,
-						   hdspm_t * hdspm);
-static int __devinit snd_hdspm_create_pcm(snd_card_t * card,
-					  hdspm_t * hdspm);
+static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
+						   struct hdspm * hdspm);
+static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
+					  struct hdspm * hdspm);
 
-static inline void snd_hdspm_initialize_midi_flush(hdspm_t * hdspm);
-static int hdspm_update_simple_mixer_controls(hdspm_t * hdspm);
-static int hdspm_autosync_ref(hdspm_t * hdspm);
-static int snd_hdspm_set_defaults(hdspm_t * hdspm);
-static void hdspm_set_sgbuf(hdspm_t * hdspm, struct snd_sg_buf *sgbuf,
+static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm);
+static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm);
+static int hdspm_autosync_ref(struct hdspm * hdspm);
+static int snd_hdspm_set_defaults(struct hdspm * hdspm);
+static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf,
 			     unsigned int reg, int channels);
 
 /* Write/read to/from HDSPM with Adresses in Bytes
    not words but only 32Bit writes are allowed */
 
-static inline void hdspm_write(hdspm_t * hdspm, unsigned int reg,
+static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg,
 			       unsigned int val)
 {
 	writel(val, hdspm->iobase + reg);
 }
 
-static inline unsigned int hdspm_read(hdspm_t * hdspm, unsigned int reg)
+static inline unsigned int hdspm_read(struct hdspm * hdspm, unsigned int reg)
 {
 	return readl(hdspm->iobase + reg);
 }
@@ -474,7 +471,7 @@
    mixer is write only on hardware so we have to cache him for read 
    each fader is a u32, but uses only the first 16 bit */
 
-static inline int hdspm_read_in_gain(hdspm_t * hdspm, unsigned int chan,
+static inline int hdspm_read_in_gain(struct hdspm * hdspm, unsigned int chan,
 				     unsigned int in)
 {
 	if (chan > HDSPM_MIXER_CHANNELS || in > HDSPM_MIXER_CHANNELS)
@@ -483,7 +480,7 @@
 	return hdspm->mixer->ch[chan].in[in];
 }
 
-static inline int hdspm_read_pb_gain(hdspm_t * hdspm, unsigned int chan,
+static inline int hdspm_read_pb_gain(struct hdspm * hdspm, unsigned int chan,
 				     unsigned int pb)
 {
 	if (chan > HDSPM_MIXER_CHANNELS || pb > HDSPM_MIXER_CHANNELS)
@@ -491,7 +488,7 @@
 	return hdspm->mixer->ch[chan].pb[pb];
 }
 
-static inline int hdspm_write_in_gain(hdspm_t * hdspm, unsigned int chan,
+static inline int hdspm_write_in_gain(struct hdspm * hdspm, unsigned int chan,
 				      unsigned int in, unsigned short data)
 {
 	if (chan >= HDSPM_MIXER_CHANNELS || in >= HDSPM_MIXER_CHANNELS)
@@ -504,7 +501,7 @@
 	return 0;
 }
 
-static inline int hdspm_write_pb_gain(hdspm_t * hdspm, unsigned int chan,
+static inline int hdspm_write_pb_gain(struct hdspm * hdspm, unsigned int chan,
 				      unsigned int pb, unsigned short data)
 {
 	if (chan >= HDSPM_MIXER_CHANNELS || pb >= HDSPM_MIXER_CHANNELS)
@@ -519,18 +516,18 @@
 
 
 /* enable DMA for specific channels, now available for DSP-MADI */
-static inline void snd_hdspm_enable_in(hdspm_t * hdspm, int i, int v)
+static inline void snd_hdspm_enable_in(struct hdspm * hdspm, int i, int v)
 {
 	hdspm_write(hdspm, HDSPM_inputEnableBase + (4 * i), v);
 }
 
-static inline void snd_hdspm_enable_out(hdspm_t * hdspm, int i, int v)
+static inline void snd_hdspm_enable_out(struct hdspm * hdspm, int i, int v)
 {
 	hdspm_write(hdspm, HDSPM_outputEnableBase + (4 * i), v);
 }
 
 /* check if same process is writing and reading */
-static inline int snd_hdspm_use_is_exclusive(hdspm_t * hdspm)
+static inline int snd_hdspm_use_is_exclusive(struct hdspm * hdspm)
 {
 	unsigned long flags;
 	int ret = 1;
@@ -545,7 +542,7 @@
 }
 
 /* check for external sample rate */
-static inline int hdspm_external_sample_rate(hdspm_t * hdspm)
+static inline int hdspm_external_sample_rate(struct hdspm * hdspm)
 {
 	unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
 	unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
@@ -630,13 +627,13 @@
 }
 
 /* Latency function */
-static inline void hdspm_compute_period_size(hdspm_t * hdspm)
+static inline void hdspm_compute_period_size(struct hdspm * hdspm)
 {
 	hdspm->period_bytes =
 	    1 << ((hdspm_decode_latency(hdspm->control_register) + 8));
 }
 
-static snd_pcm_uframes_t hdspm_hw_pointer(hdspm_t * hdspm)
+static snd_pcm_uframes_t hdspm_hw_pointer(struct hdspm * hdspm)
 {
 	int position;
 
@@ -660,20 +657,20 @@
 }
 
 
-static inline void hdspm_start_audio(hdspm_t * s)
+static inline void hdspm_start_audio(struct hdspm * s)
 {
 	s->control_register |= (HDSPM_AudioInterruptEnable | HDSPM_Start);
 	hdspm_write(s, HDSPM_controlRegister, s->control_register);
 }
 
-static inline void hdspm_stop_audio(hdspm_t * s)
+static inline void hdspm_stop_audio(struct hdspm * s)
 {
 	s->control_register &= ~(HDSPM_Start | HDSPM_AudioInterruptEnable);
 	hdspm_write(s, HDSPM_controlRegister, s->control_register);
 }
 
 /* should I silence all or only opened ones ? doit all for first even is 4MB*/
-static inline void hdspm_silence_playback(hdspm_t * hdspm)
+static inline void hdspm_silence_playback(struct hdspm * hdspm)
 {
 	int i;
 	int n = hdspm->period_bytes;
@@ -687,7 +684,7 @@
 	}
 }
 
-static int hdspm_set_interrupt_interval(hdspm_t * s, unsigned int frames)
+static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames)
 {
 	int n;
 
@@ -713,7 +710,7 @@
 
 
 /* dummy set rate lets see what happens */
-static int hdspm_set_rate(hdspm_t * hdspm, int rate, int called_internally)
+static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
 {
 	int reject_if_open = 0;
 	int current_rate;
@@ -838,7 +835,7 @@
 }
 
 /* mainly for init to 0 on load */
-static void all_in_all_mixer(hdspm_t * hdspm, int sgain)
+static void all_in_all_mixer(struct hdspm * hdspm, int sgain)
 {
 	int i, j;
 	unsigned int gain =
@@ -855,7 +852,7 @@
    MIDI
   ----------------------------------------------------------------------------*/
 
-static inline unsigned char snd_hdspm_midi_read_byte (hdspm_t *hdspm, int id)
+static inline unsigned char snd_hdspm_midi_read_byte (struct hdspm *hdspm, int id)
 {
 	/* the hardware already does the relevant bit-mask with 0xff */
 	if (id)
@@ -864,7 +861,7 @@
 		return hdspm_read(hdspm, HDSPM_midiDataIn0);
 }
 
-static inline void snd_hdspm_midi_write_byte (hdspm_t *hdspm, int id, int val)
+static inline void snd_hdspm_midi_write_byte (struct hdspm *hdspm, int id, int val)
 {
 	/* the hardware already does the relevant bit-mask with 0xff */
 	if (id)
@@ -873,7 +870,7 @@
 		return hdspm_write(hdspm, HDSPM_midiDataOut0, val);
 }
 
-static inline int snd_hdspm_midi_input_available (hdspm_t *hdspm, int id)
+static inline int snd_hdspm_midi_input_available (struct hdspm *hdspm, int id)
 {
 	if (id)
 		return (hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xff);
@@ -881,7 +878,7 @@
 		return (hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xff);
 }
 
-static inline int snd_hdspm_midi_output_possible (hdspm_t *hdspm, int id)
+static inline int snd_hdspm_midi_output_possible (struct hdspm *hdspm, int id)
 {
 	int fifo_bytes_used;
 
@@ -896,13 +893,13 @@
 		return 0;
 }
 
-static inline void snd_hdspm_flush_midi_input (hdspm_t *hdspm, int id)
+static inline void snd_hdspm_flush_midi_input (struct hdspm *hdspm, int id)
 {
 	while (snd_hdspm_midi_input_available (hdspm, id))
 		snd_hdspm_midi_read_byte (hdspm, id);
 }
 
-static int snd_hdspm_midi_output_write (hdspm_midi_t *hmidi)
+static int snd_hdspm_midi_output_write (struct hdspm_midi *hmidi)
 {
 	unsigned long flags;
 	int n_pending;
@@ -930,7 +927,7 @@
 	return 0;
 }
 
-static int snd_hdspm_midi_input_read (hdspm_midi_t *hmidi)
+static int snd_hdspm_midi_input_read (struct hdspm_midi *hmidi)
 {
 	unsigned char buf[128]; /* this buffer is designed to match the MIDI input FIFO size */
 	unsigned long flags;
@@ -967,14 +964,14 @@
 	return snd_hdspm_midi_output_write (hmidi);
 }
 
-static void snd_hdspm_midi_input_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_hdspm_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	hdspm_t *hdspm;
-	hdspm_midi_t *hmidi;
+	struct hdspm *hdspm;
+	struct hdspm_midi *hmidi;
 	unsigned long flags;
 	u32 ie;
 
-	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
 	hdspm = hmidi->hdspm;
 	ie = hmidi->id ? HDSPM_Midi1InterruptEnable : HDSPM_Midi0InterruptEnable;
 	spin_lock_irqsave (&hdspm->lock, flags);
@@ -993,7 +990,7 @@
 
 static void snd_hdspm_midi_output_timer(unsigned long data)
 {
-	hdspm_midi_t *hmidi = (hdspm_midi_t *) data;
+	struct hdspm_midi *hmidi = (struct hdspm_midi *) data;
 	unsigned long flags;
 	
 	snd_hdspm_midi_output_write(hmidi);
@@ -1013,12 +1010,12 @@
 	spin_unlock_irqrestore (&hmidi->lock, flags);
 }
 
-static void snd_hdspm_midi_output_trigger(snd_rawmidi_substream_t * substream, int up)
+static void snd_hdspm_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	hdspm_midi_t *hmidi;
+	struct hdspm_midi *hmidi;
 	unsigned long flags;
 
-	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
 	spin_lock_irqsave (&hmidi->lock, flags);
 	if (up) {
 		if (!hmidi->istimer) {
@@ -1039,11 +1036,11 @@
 		snd_hdspm_midi_output_write(hmidi);
 }
 
-static int snd_hdspm_midi_input_open(snd_rawmidi_substream_t * substream)
+static int snd_hdspm_midi_input_open(struct snd_rawmidi_substream *substream)
 {
-	hdspm_midi_t *hmidi;
+	struct hdspm_midi *hmidi;
 
-	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
 	spin_lock_irq (&hmidi->lock);
 	snd_hdspm_flush_midi_input (hmidi->hdspm, hmidi->id);
 	hmidi->input = substream;
@@ -1052,11 +1049,11 @@
 	return 0;
 }
 
-static int snd_hdspm_midi_output_open(snd_rawmidi_substream_t * substream)
+static int snd_hdspm_midi_output_open(struct snd_rawmidi_substream *substream)
 {
-	hdspm_midi_t *hmidi;
+	struct hdspm_midi *hmidi;
 
-	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
 	spin_lock_irq (&hmidi->lock);
 	hmidi->output = substream;
 	spin_unlock_irq (&hmidi->lock);
@@ -1064,13 +1061,13 @@
 	return 0;
 }
 
-static int snd_hdspm_midi_input_close(snd_rawmidi_substream_t * substream)
+static int snd_hdspm_midi_input_close(struct snd_rawmidi_substream *substream)
 {
-	hdspm_midi_t *hmidi;
+	struct hdspm_midi *hmidi;
 
 	snd_hdspm_midi_input_trigger (substream, 0);
 
-	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
 	spin_lock_irq (&hmidi->lock);
 	hmidi->input = NULL;
 	spin_unlock_irq (&hmidi->lock);
@@ -1078,13 +1075,13 @@
 	return 0;
 }
 
-static int snd_hdspm_midi_output_close(snd_rawmidi_substream_t * substream)
+static int snd_hdspm_midi_output_close(struct snd_rawmidi_substream *substream)
 {
-	hdspm_midi_t *hmidi;
+	struct hdspm_midi *hmidi;
 
 	snd_hdspm_midi_output_trigger (substream, 0);
 
-	hmidi = (hdspm_midi_t *) substream->rmidi->private_data;
+	hmidi = (struct hdspm_midi *) substream->rmidi->private_data;
 	spin_lock_irq (&hmidi->lock);
 	hmidi->output = NULL;
 	spin_unlock_irq (&hmidi->lock);
@@ -1092,21 +1089,21 @@
 	return 0;
 }
 
-static snd_rawmidi_ops_t snd_hdspm_midi_output =
+static struct snd_rawmidi_ops snd_hdspm_midi_output =
 {
 	.open =		snd_hdspm_midi_output_open,
 	.close =	snd_hdspm_midi_output_close,
 	.trigger =	snd_hdspm_midi_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_hdspm_midi_input =
+static struct snd_rawmidi_ops snd_hdspm_midi_input =
 {
 	.open =		snd_hdspm_midi_input_open,
 	.close =	snd_hdspm_midi_input_close,
 	.trigger =	snd_hdspm_midi_input_trigger,
 };
 
-static int __devinit snd_hdspm_create_midi (snd_card_t *card, hdspm_t *hdspm, int id)
+static int __devinit snd_hdspm_create_midi (struct snd_card *card, struct hdspm *hdspm, int id)
 {
 	int err;
 	char buf[32];
@@ -1140,7 +1137,7 @@
 
 static void hdspm_midi_tasklet(unsigned long arg)
 {
-	hdspm_t *hdspm = (hdspm_t *)arg;
+	struct hdspm *hdspm = (struct hdspm *)arg;
 	
 	if (hdspm->midi[0].pending)
 		snd_hdspm_midi_input_read (&hdspm->midi[0]);
@@ -1164,19 +1161,19 @@
   .get = snd_hdspm_get_system_sample_rate \
 }
 
-static int snd_hdspm_info_system_sample_rate(snd_kcontrol_t * kcontrol,
-					     snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_system_sample_rate(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_hdspm_get_system_sample_rate(snd_kcontrol_t * kcontrol,
-					    snd_ctl_elem_value_t *
+static int snd_hdspm_get_system_sample_rate(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *
 					    ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = hdspm->system_sample_rate;
 	return 0;
@@ -1191,8 +1188,8 @@
   .get = snd_hdspm_get_autosync_sample_rate \
 }
 
-static int snd_hdspm_info_autosync_sample_rate(snd_kcontrol_t * kcontrol,
-					       snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol,
+					       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "32000", "44100", "48000",
 		"64000", "88200", "96000",
@@ -1210,11 +1207,11 @@
 	return 0;
 }
 
-static int snd_hdspm_get_autosync_sample_rate(snd_kcontrol_t * kcontrol,
-					      snd_ctl_elem_value_t *
+static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
+					      struct snd_ctl_elem_value *
 					      ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	switch (hdspm_external_sample_rate(hdspm)) {
 	case 32000:
@@ -1262,7 +1259,7 @@
 
 
 
-static int hdspm_system_clock_mode(hdspm_t * hdspm)
+static int hdspm_system_clock_mode(struct hdspm * hdspm)
 {
         /* Always reflect the hardware info, rme is never wrong !!!! */
 
@@ -1271,8 +1268,8 @@
 	return 1;
 }
 
-static int snd_hdspm_info_system_clock_mode(snd_kcontrol_t * kcontrol,
-					    snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "Master", "Slave" };
 
@@ -1287,10 +1284,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_system_clock_mode(snd_kcontrol_t * kcontrol,
-					   snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_system_clock_mode(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] =
 	    hdspm_system_clock_mode(hdspm);
@@ -1306,7 +1303,7 @@
   .put = snd_hdspm_put_clock_source \
 }
 
-static int hdspm_clock_source(hdspm_t * hdspm)
+static int hdspm_clock_source(struct hdspm * hdspm)
 {
 	if (hdspm->control_register & HDSPM_ClockModeMaster) {
 		switch (hdspm->system_sample_rate) {
@@ -1336,7 +1333,7 @@
 	}
 }
 
-static int hdspm_set_clock_source(hdspm_t * hdspm, int mode)
+static int hdspm_set_clock_source(struct hdspm * hdspm, int mode)
 {
 	int rate;
 	switch (mode) {
@@ -1386,8 +1383,8 @@
 	return 0;
 }
 
-static int snd_hdspm_info_clock_source(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_clock_source(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "AutoSync",
 		"Internal 32.0 kHz", "Internal 44.1 kHz",
@@ -1412,19 +1409,19 @@
 	return 0;
 }
 
-static int snd_hdspm_get_clock_source(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_clock_source(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = hdspm_clock_source(hdspm);
 	return 0;
 }
 
-static int snd_hdspm_put_clock_source(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int change;
 	int val;
 
@@ -1453,7 +1450,7 @@
   .put = snd_hdspm_put_pref_sync_ref \
 }
 
-static int hdspm_pref_sync_ref(hdspm_t * hdspm)
+static int hdspm_pref_sync_ref(struct hdspm * hdspm)
 {
 	/* Notice that this looks at the requested sync source,
 	   not the one actually in use.
@@ -1468,7 +1465,7 @@
 	return HDSPM_SYNC_FROM_WORD;
 }
 
-static int hdspm_set_pref_sync_ref(hdspm_t * hdspm, int pref)
+static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
 {
 	hdspm->control_register &= ~HDSPM_SyncRefMask;
 
@@ -1486,8 +1483,8 @@
 	return 0;
 }
 
-static int snd_hdspm_info_pref_sync_ref(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "Word", "MADI" };
 
@@ -1504,19 +1501,19 @@
 	return 0;
 }
 
-static int snd_hdspm_get_pref_sync_ref(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_pref_sync_ref(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm);
 	return 0;
 }
 
-static int snd_hdspm_put_pref_sync_ref(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int change, max;
 	unsigned int val;
 
@@ -1543,7 +1540,7 @@
   .get = snd_hdspm_get_autosync_ref, \
 }
 
-static int hdspm_autosync_ref(hdspm_t * hdspm)
+static int hdspm_autosync_ref(struct hdspm * hdspm)
 {
 	/* This looks at the autosync selected sync reference */
 	unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
@@ -1566,8 +1563,8 @@
 	return 0;
 }
 
-static int snd_hdspm_info_autosync_ref(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "WordClock", "MADI", "None" };
 
@@ -1582,10 +1579,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_autosync_ref(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm);
 	return 0;
@@ -1600,13 +1597,13 @@
   .put = snd_hdspm_put_line_out \
 }
 
-static int hdspm_line_out(hdspm_t * hdspm)
+static int hdspm_line_out(struct hdspm * hdspm)
 {
 	return (hdspm->control_register & HDSPM_LineOut) ? 1 : 0;
 }
 
 
-static int hdspm_set_line_output(hdspm_t * hdspm, int out)
+static int hdspm_set_line_output(struct hdspm * hdspm, int out)
 {
 	if (out)
 		hdspm->control_register |= HDSPM_LineOut;
@@ -1617,8 +1614,8 @@
 	return 0;
 }
 
-static int snd_hdspm_info_line_out(snd_kcontrol_t * kcontrol,
-				   snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_line_out(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1627,10 +1624,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_line_out(snd_kcontrol_t * kcontrol,
-				  snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_line_out(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&hdspm->lock);
 	ucontrol->value.integer.value[0] = hdspm_line_out(hdspm);
@@ -1638,10 +1635,10 @@
 	return 0;
 }
 
-static int snd_hdspm_put_line_out(snd_kcontrol_t * kcontrol,
-				  snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_put_line_out(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 
@@ -1664,12 +1661,12 @@
   .put = snd_hdspm_put_tx_64 \
 }
 
-static int hdspm_tx_64(hdspm_t * hdspm)
+static int hdspm_tx_64(struct hdspm * hdspm)
 {
 	return (hdspm->control_register & HDSPM_TX_64ch) ? 1 : 0;
 }
 
-static int hdspm_set_tx_64(hdspm_t * hdspm, int out)
+static int hdspm_set_tx_64(struct hdspm * hdspm, int out)
 {
 	if (out)
 		hdspm->control_register |= HDSPM_TX_64ch;
@@ -1680,8 +1677,8 @@
 	return 0;
 }
 
-static int snd_hdspm_info_tx_64(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_tx_64(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1690,10 +1687,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_tx_64(snd_kcontrol_t * kcontrol,
-			       snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_tx_64(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&hdspm->lock);
 	ucontrol->value.integer.value[0] = hdspm_tx_64(hdspm);
@@ -1701,10 +1698,10 @@
 	return 0;
 }
 
-static int snd_hdspm_put_tx_64(snd_kcontrol_t * kcontrol,
-			       snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_put_tx_64(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 
@@ -1727,12 +1724,12 @@
   .put = snd_hdspm_put_c_tms \
 }
 
-static int hdspm_c_tms(hdspm_t * hdspm)
+static int hdspm_c_tms(struct hdspm * hdspm)
 {
 	return (hdspm->control_register & HDSPM_clr_tms) ? 1 : 0;
 }
 
-static int hdspm_set_c_tms(hdspm_t * hdspm, int out)
+static int hdspm_set_c_tms(struct hdspm * hdspm, int out)
 {
 	if (out)
 		hdspm->control_register |= HDSPM_clr_tms;
@@ -1743,8 +1740,8 @@
 	return 0;
 }
 
-static int snd_hdspm_info_c_tms(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_c_tms(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1753,10 +1750,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_c_tms(snd_kcontrol_t * kcontrol,
-			       snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_c_tms(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&hdspm->lock);
 	ucontrol->value.integer.value[0] = hdspm_c_tms(hdspm);
@@ -1764,10 +1761,10 @@
 	return 0;
 }
 
-static int snd_hdspm_put_c_tms(snd_kcontrol_t * kcontrol,
-			       snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_put_c_tms(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 
@@ -1790,12 +1787,12 @@
   .put = snd_hdspm_put_safe_mode \
 }
 
-static int hdspm_safe_mode(hdspm_t * hdspm)
+static int hdspm_safe_mode(struct hdspm * hdspm)
 {
 	return (hdspm->control_register & HDSPM_AutoInp) ? 1 : 0;
 }
 
-static int hdspm_set_safe_mode(hdspm_t * hdspm, int out)
+static int hdspm_set_safe_mode(struct hdspm * hdspm, int out)
 {
 	if (out)
 		hdspm->control_register |= HDSPM_AutoInp;
@@ -1806,8 +1803,8 @@
 	return 0;
 }
 
-static int snd_hdspm_info_safe_mode(snd_kcontrol_t * kcontrol,
-				    snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_safe_mode(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1816,10 +1813,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_safe_mode(snd_kcontrol_t * kcontrol,
-				   snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_safe_mode(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&hdspm->lock);
 	ucontrol->value.integer.value[0] = hdspm_safe_mode(hdspm);
@@ -1827,10 +1824,10 @@
 	return 0;
 }
 
-static int snd_hdspm_put_safe_mode(snd_kcontrol_t * kcontrol,
-				   snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 
@@ -1853,12 +1850,12 @@
   .put = snd_hdspm_put_input_select \
 }
 
-static int hdspm_input_select(hdspm_t * hdspm)
+static int hdspm_input_select(struct hdspm * hdspm)
 {
 	return (hdspm->control_register & HDSPM_InputSelect0) ? 1 : 0;
 }
 
-static int hdspm_set_input_select(hdspm_t * hdspm, int out)
+static int hdspm_set_input_select(struct hdspm * hdspm, int out)
 {
 	if (out)
 		hdspm->control_register |= HDSPM_InputSelect0;
@@ -1869,8 +1866,8 @@
 	return 0;
 }
 
-static int snd_hdspm_info_input_select(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "optical", "coaxial" };
 
@@ -1887,10 +1884,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_input_select(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_input_select(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&hdspm->lock);
 	ucontrol->value.enumerated.item[0] = hdspm_input_select(hdspm);
@@ -1898,10 +1895,10 @@
 	return 0;
 }
 
-static int snd_hdspm_put_input_select(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 
@@ -1937,8 +1934,8 @@
   .put = snd_hdspm_put_mixer \
 }
 
-static int snd_hdspm_info_mixer(snd_kcontrol_t * kcontrol,
-				snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 3;
@@ -1948,10 +1945,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_mixer(snd_kcontrol_t * kcontrol,
-			       snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_mixer(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int source;
 	int destination;
 
@@ -1981,10 +1978,10 @@
 	return 0;
 }
 
-static int snd_hdspm_put_mixer(snd_kcontrol_t * kcontrol,
-			       snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_put_mixer(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int change;
 	int source;
 	int destination;
@@ -2041,8 +2038,8 @@
   .put = snd_hdspm_put_playback_mixer \
 }
 
-static int snd_hdspm_info_playback_mixer(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_playback_mixer(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -2052,10 +2049,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_playback_mixer(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int channel;
 	int mapped_channel;
 
@@ -2079,10 +2076,10 @@
 	return 0;
 }
 
-static int snd_hdspm_put_playback_mixer(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 	int change;
 	int channel;
 	int mapped_channel;
@@ -2121,8 +2118,8 @@
   .get = snd_hdspm_get_wc_sync_check \
 }
 
-static int snd_hdspm_info_sync_check(snd_kcontrol_t * kcontrol,
-				     snd_ctl_elem_info_t * uinfo)
+static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[] = { "No Lock", "Lock", "Sync" };
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -2136,7 +2133,7 @@
 	return 0;
 }
 
-static int hdspm_wc_sync_check(hdspm_t * hdspm)
+static int hdspm_wc_sync_check(struct hdspm * hdspm)
 {
 	int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
 	if (status2 & HDSPM_wcLock) {
@@ -2148,10 +2145,10 @@
 	return 0;
 }
 
-static int snd_hdspm_get_wc_sync_check(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] = hdspm_wc_sync_check(hdspm);
 	return 0;
@@ -2167,7 +2164,7 @@
   .get = snd_hdspm_get_madisync_sync_check \
 }
 
-static int hdspm_madisync_sync_check(hdspm_t * hdspm)
+static int hdspm_madisync_sync_check(struct hdspm * hdspm)
 {
 	int status = hdspm_read(hdspm, HDSPM_statusRegister);
 	if (status & HDSPM_madiLock) {
@@ -2179,11 +2176,11 @@
 	return 0;
 }
 
-static int snd_hdspm_get_madisync_sync_check(snd_kcontrol_t * kcontrol,
-					     snd_ctl_elem_value_t *
+static int snd_hdspm_get_madisync_sync_check(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_value *
 					     ucontrol)
 {
-	hdspm_t *hdspm = snd_kcontrol_chip(kcontrol);
+	struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
 
 	ucontrol->value.enumerated.item[0] =
 	    hdspm_madisync_sync_check(hdspm);
@@ -2193,7 +2190,7 @@
 
 
 
-static snd_kcontrol_new_t snd_hdspm_controls[] = {
+static struct snd_kcontrol_new snd_hdspm_controls[] = {
 
 	HDSPM_MIXER("Mixer", 0),
 /* 'Sample Clock Source' complies with the alsa control naming scheme */
@@ -2214,10 +2211,10 @@
 	HDSPM_INPUT_SELECT("Input Select", 0),
 };
 
-static snd_kcontrol_new_t snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
+static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
 
 
-static int hdspm_update_simple_mixer_controls(hdspm_t * hdspm)
+static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm)
 {
 	int i;
 
@@ -2241,11 +2238,11 @@
 }
 
 
-static int snd_hdspm_create_controls(snd_card_t * card, hdspm_t * hdspm)
+static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm)
 {
 	unsigned int idx, limit;
 	int err;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	/* add control list first */
 
@@ -2292,9 +2289,9 @@
  ------------------------------------------------------------*/
 
 static void
-snd_hdspm_proc_read(snd_info_entry_t * entry, snd_info_buffer_t * buffer)
+snd_hdspm_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer)
 {
-	hdspm_t *hdspm = (hdspm_t *) entry->private_data;
+	struct hdspm *hdspm = (struct hdspm *) entry->private_data;
 	unsigned int status;
 	unsigned int status2;
 	char *pref_sync_ref;
@@ -2487,9 +2484,9 @@
 	snd_iprintf(buffer, "\n");
 }
 
-static void __devinit snd_hdspm_proc_init(hdspm_t * hdspm)
+static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (!snd_card_proc_new(hdspm->card, "hdspm", &entry))
 		snd_info_set_text_ops(entry, hdspm, 1024,
@@ -2500,7 +2497,7 @@
    hdspm intitialize 
  ------------------------------------------------------------*/
 
-static int snd_hdspm_set_defaults(hdspm_t * hdspm)
+static int snd_hdspm_set_defaults(struct hdspm * hdspm)
 {
 	unsigned int i;
 
@@ -2562,7 +2559,7 @@
 static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id,
 				       struct pt_regs *regs)
 {
-	hdspm_t *hdspm = (hdspm_t *) dev_id;
+	struct hdspm *hdspm = (struct hdspm *) dev_id;
 	unsigned int status;
 	int audio;
 	int midi0;
@@ -2627,14 +2624,14 @@
   ------------------------------------------------------------*/
 
 
-static snd_pcm_uframes_t snd_hdspm_hw_pointer(snd_pcm_substream_t *
+static snd_pcm_uframes_t snd_hdspm_hw_pointer(struct snd_pcm_substream *
 					      substream)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
 	return hdspm_hw_pointer(hdspm);
 }
 
-static char *hdspm_channel_buffer_location(hdspm_t * hdspm,
+static char *hdspm_channel_buffer_location(struct hdspm * hdspm,
 					   int stream, int channel)
 {
 	int mapped_channel;
@@ -2656,11 +2653,11 @@
 
 
 /* dont know why need it ??? */
-static int snd_hdspm_playback_copy(snd_pcm_substream_t * substream,
+static int snd_hdspm_playback_copy(struct snd_pcm_substream *substream,
 				   int channel, snd_pcm_uframes_t pos,
 				   void __user *src, snd_pcm_uframes_t count)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
 	char *channel_buf;
 
 	snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
@@ -2675,11 +2672,11 @@
 	return copy_from_user(channel_buf + pos * 4, src, count * 4);
 }
 
-static int snd_hdspm_capture_copy(snd_pcm_substream_t * substream,
+static int snd_hdspm_capture_copy(struct snd_pcm_substream *substream,
 				  int channel, snd_pcm_uframes_t pos,
 				  void __user *dst, snd_pcm_uframes_t count)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
 	char *channel_buf;
 
 	snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4,
@@ -2692,11 +2689,11 @@
 	return copy_to_user(dst, channel_buf + pos * 4, count * 4);
 }
 
-static int snd_hdspm_hw_silence(snd_pcm_substream_t * substream,
+static int snd_hdspm_hw_silence(struct snd_pcm_substream *substream,
 				int channel, snd_pcm_uframes_t pos,
 				snd_pcm_uframes_t count)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
 	char *channel_buf;
 
 	channel_buf =
@@ -2707,11 +2704,11 @@
 	return 0;
 }
 
-static int snd_hdspm_reset(snd_pcm_substream_t * substream)
+static int snd_hdspm_reset(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
-	snd_pcm_substream_t *other;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_substream *other;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		other = hdspm->capture_substream;
@@ -2724,8 +2721,8 @@
 		runtime->status->hw_ptr = 0;
 	if (other) {
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
-		snd_pcm_runtime_t *oruntime = other->runtime;
+		struct snd_pcm_substream *s;
+		struct snd_pcm_runtime *oruntime = other->runtime;
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == other) {
@@ -2738,10 +2735,10 @@
 	return 0;
 }
 
-static int snd_hdspm_hw_params(snd_pcm_substream_t * substream,
-			       snd_pcm_hw_params_t * params)
+static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
+			       struct snd_pcm_hw_params *params)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
 	int err;
 	int i;
 	pid_t this_pid;
@@ -2839,10 +2836,10 @@
 	return 0;
 }
 
-static int snd_hdspm_hw_free(snd_pcm_substream_t * substream)
+static int snd_hdspm_hw_free(struct snd_pcm_substream *substream)
 {
 	int i;
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 
@@ -2865,10 +2862,10 @@
 	return 0;
 }
 
-static int snd_hdspm_channel_info(snd_pcm_substream_t * substream,
-				  snd_pcm_channel_info_t * info)
+static int snd_hdspm_channel_info(struct snd_pcm_substream *substream,
+				  struct snd_pcm_channel_info * info)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
 	int mapped_channel;
 
 	snd_assert(info->channel < HDSPM_MAX_CHANNELS, return -EINVAL);
@@ -2882,7 +2879,7 @@
 	return 0;
 }
 
-static int snd_hdspm_ioctl(snd_pcm_substream_t * substream,
+static int snd_hdspm_ioctl(struct snd_pcm_substream *substream,
 			   unsigned int cmd, void *arg)
 {
 	switch (cmd) {
@@ -2893,7 +2890,7 @@
 
 	case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
 		{
-			snd_pcm_channel_info_t *info = arg;
+			struct snd_pcm_channel_info *info = arg;
 			return snd_hdspm_channel_info(substream, info);
 		}
 	default:
@@ -2903,10 +2900,10 @@
 	return snd_pcm_lib_ioctl(substream, cmd, arg);
 }
 
-static int snd_hdspm_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
-	snd_pcm_substream_t *other;
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_substream *other;
 	int running;
 
 	spin_lock(&hdspm->lock);
@@ -2930,7 +2927,7 @@
 
 	if (other) {
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
+		struct snd_pcm_substream *s;
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == other) {
@@ -2968,7 +2965,7 @@
 	return 0;
 }
 
-static int snd_hdspm_prepare(snd_pcm_substream_t * substream)
+static int snd_hdspm_prepare(struct snd_pcm_substream *substream)
 {
 	return 0;
 }
@@ -2976,7 +2973,7 @@
 static unsigned int period_sizes[] =
     { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
 
-static snd_pcm_hardware_t snd_hdspm_playback_subinfo = {
+static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
 	.info = (SNDRV_PCM_INFO_MMAP |
 		 SNDRV_PCM_INFO_MMAP_VALID |
 		 SNDRV_PCM_INFO_NONINTERLEAVED |
@@ -3000,7 +2997,7 @@
 	.fifo_size = 0
 };
 
-static snd_pcm_hardware_t snd_hdspm_capture_subinfo = {
+static struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
 	.info = (SNDRV_PCM_INFO_MMAP |
 		 SNDRV_PCM_INFO_MMAP_VALID |
 		 SNDRV_PCM_INFO_NONINTERLEAVED |
@@ -3024,31 +3021,31 @@
 	.fifo_size = 0
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {
+static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
 	.count = ARRAY_SIZE(period_sizes),
 	.list = period_sizes,
 	.mask = 0
 };
 
 
-static int snd_hdspm_hw_rule_channels_rate(snd_pcm_hw_params_t * params,
-					   snd_pcm_hw_rule_t * rule)
+static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params,
+					   struct snd_pcm_hw_rule * rule)
 {
-	hdspm_t *hdspm = rule->private;
-	snd_interval_t *c =
+	struct hdspm *hdspm = rule->private;
+	struct snd_interval *c =
 	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	snd_interval_t *r =
+	struct snd_interval *r =
 	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 
 	if (r->min > 48000) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 1,
 			.max = hdspm->ds_channels,
 			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);
 	} else if (r->max < 64000) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 1,
 			.max = hdspm->ss_channels,
 			.integer = 1,
@@ -3058,24 +3055,24 @@
 	return 0;
 }
 
-static int snd_hdspm_hw_rule_rate_channels(snd_pcm_hw_params_t * params,
-					   snd_pcm_hw_rule_t * rule)
+static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
+					   struct snd_pcm_hw_rule * rule)
 {
-	hdspm_t *hdspm = rule->private;
-	snd_interval_t *c =
+	struct hdspm *hdspm = rule->private;
+	struct snd_interval *c =
 	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	snd_interval_t *r =
+	struct snd_interval *r =
 	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 
 	if (c->min <= hdspm->ss_channels) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 32000,
 			.max = 48000,
 			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	} else if (c->max > hdspm->ss_channels) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 64000,
 			.max = 96000,
 			.integer = 1,
@@ -3086,10 +3083,10 @@
 	return 0;
 }
 
-static int snd_hdspm_playback_open(snd_pcm_substream_t * substream)
+static int snd_hdspm_playback_open(struct snd_pcm_substream *substream)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_printdd("Open device substream %d\n", substream->stream);
 
@@ -3124,9 +3121,9 @@
 	return 0;
 }
 
-static int snd_hdspm_playback_release(snd_pcm_substream_t * substream)
+static int snd_hdspm_playback_release(struct snd_pcm_substream *substream)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&hdspm->lock);
 
@@ -3139,10 +3136,10 @@
 }
 
 
-static int snd_hdspm_capture_open(snd_pcm_substream_t * substream)
+static int snd_hdspm_capture_open(struct snd_pcm_substream *substream)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	spin_lock_irq(&hdspm->lock);
 	snd_pcm_set_sync(substream);
@@ -3171,9 +3168,9 @@
 	return 0;
 }
 
-static int snd_hdspm_capture_release(snd_pcm_substream_t * substream)
+static int snd_hdspm_capture_release(struct snd_pcm_substream *substream)
 {
-	hdspm_t *hdspm = snd_pcm_substream_chip(substream);
+	struct hdspm *hdspm = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&hdspm->lock);
 
@@ -3184,21 +3181,21 @@
 	return 0;
 }
 
-static int snd_hdspm_hwdep_dummy_op(snd_hwdep_t * hw, struct file *file)
+static int snd_hdspm_hwdep_dummy_op(struct snd_hwdep * hw, struct file *file)
 {
 	/* we have nothing to initialize but the call is required */
 	return 0;
 }
 
 
-static int snd_hdspm_hwdep_ioctl(snd_hwdep_t * hw, struct file *file,
+static int snd_hdspm_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
 				 unsigned int cmd, unsigned long arg)
 {
-	hdspm_t *hdspm = (hdspm_t *) hw->private_data;
-	struct sndrv_hdspm_mixer_ioctl mixer;
-	hdspm_config_info_t info;
-	hdspm_version_t hdspm_version;
-	struct sndrv_hdspm_peak_rms_ioctl rms;
+	struct hdspm *hdspm = (struct hdspm *) hw->private_data;
+	struct hdspm_mixer_ioctl mixer;
+	struct hdspm_config_info info;
+	struct hdspm_version hdspm_version;
+	struct hdspm_peak_rms_ioctl rms;
 
 	switch (cmd) {
 
@@ -3209,7 +3206,7 @@
 		/* maybe there is a chance to memorymap in future so dont touch just copy */
 		if(copy_to_user_fromio((void __user *)rms.peak,
 				       hdspm->iobase+HDSPM_MADI_peakrmsbase,
-				       sizeof(hdspm_peak_rms_t)) != 0 )
+				       sizeof(struct hdspm_peak_rms)) != 0 )
 			return -EFAULT;
 
 		break;
@@ -3250,7 +3247,7 @@
 		if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer)))
 			return -EFAULT;
 		if (copy_to_user
-		    ((void __user *)mixer.mixer, hdspm->mixer, sizeof(hdspm_mixer_t)))
+		    ((void __user *)mixer.mixer, hdspm->mixer, sizeof(struct hdspm_mixer)))
 			return -EFAULT;
 		break;
 
@@ -3260,7 +3257,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_hdspm_playback_ops = {
+static struct snd_pcm_ops snd_hdspm_playback_ops = {
 	.open = snd_hdspm_playback_open,
 	.close = snd_hdspm_playback_release,
 	.ioctl = snd_hdspm_ioctl,
@@ -3274,7 +3271,7 @@
 	.page = snd_pcm_sgbuf_ops_page,
 };
 
-static snd_pcm_ops_t snd_hdspm_capture_ops = {
+static struct snd_pcm_ops snd_hdspm_capture_ops = {
 	.open = snd_hdspm_capture_open,
 	.close = snd_hdspm_capture_release,
 	.ioctl = snd_hdspm_ioctl,
@@ -3287,10 +3284,10 @@
 	.page = snd_pcm_sgbuf_ops_page,
 };
 
-static int __devinit snd_hdspm_create_hwdep(snd_card_t * card,
-					    hdspm_t * hdspm)
+static int __devinit snd_hdspm_create_hwdep(struct snd_card *card,
+					    struct hdspm * hdspm)
 {
-	snd_hwdep_t *hw;
+	struct snd_hwdep *hw;
 	int err;
 
 	if ((err = snd_hwdep_new(card, "HDSPM hwdep", 0, &hw)) < 0)
@@ -3311,10 +3308,10 @@
 /*------------------------------------------------------------
    memory interface 
  ------------------------------------------------------------*/
-static int __devinit snd_hdspm_preallocate_memory(hdspm_t * hdspm)
+static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
 {
 	int err;
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	size_t wanted;
 
 	pcm = hdspm->pcm;
@@ -3336,16 +3333,7 @@
 	return 0;
 }
 
-static int snd_hdspm_memory_free(hdspm_t * hdspm)
-{
-	snd_printdd("memory_free_for_all %p\n", hdspm->pcm);
-
-	snd_pcm_lib_preallocate_free_for_all(hdspm->pcm);
-	return 0;
-}
-
-
-static void hdspm_set_sgbuf(hdspm_t * hdspm, struct snd_sg_buf *sgbuf,
+static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf,
 			     unsigned int reg, int channels)
 {
 	int i;
@@ -3356,10 +3344,10 @@
 }
 
 /* ------------- ALSA Devices ---------------------------- */
-static int __devinit snd_hdspm_create_pcm(snd_card_t * card,
-					  hdspm_t * hdspm)
+static int __devinit snd_hdspm_create_pcm(struct snd_card *card,
+					  struct hdspm * hdspm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(card, hdspm->card_name, 0, 1, 1, &pcm)) < 0)
@@ -3382,14 +3370,14 @@
 	return 0;
 }
 
-static inline void snd_hdspm_initialize_midi_flush(hdspm_t * hdspm)
+static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm)
 {
 	snd_hdspm_flush_midi_input(hdspm, 0);
 	snd_hdspm_flush_midi_input(hdspm, 1);
 }
 
-static int __devinit snd_hdspm_create_alsa_devices(snd_card_t * card,
-						   hdspm_t * hdspm)
+static int __devinit snd_hdspm_create_alsa_devices(struct snd_card *card,
+						   struct hdspm * hdspm)
 {
 	int err;
 
@@ -3439,7 +3427,7 @@
 	return 0;
 }
 
-static int __devinit snd_hdspm_create(snd_card_t * card, hdspm_t * hdspm,
+static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdspm,
 				      int precise_ptr, int enable_monitor)
 {
 	struct pci_dev *pci = hdspm->pci;
@@ -3523,12 +3511,11 @@
 	hdspm->monitor_outs = enable_monitor;
 
 	snd_printdd("kmalloc Mixer memory of %d Bytes\n",
-		   sizeof(hdspm_mixer_t));
-	if ((hdspm->mixer =
-	     (hdspm_mixer_t *) kmalloc(sizeof(hdspm_mixer_t), GFP_KERNEL))
+		   sizeof(struct hdspm_mixer));
+	if ((hdspm->mixer = kmalloc(sizeof(struct hdspm_mixer), GFP_KERNEL))
 	    == NULL) {
 		snd_printk(KERN_ERR "HDSPM: unable to kmalloc Mixer memory of %d Bytes\n",
-			   (int)sizeof(hdspm_mixer_t));
+			   (int)sizeof(struct hdspm_mixer));
 		return err;
 	}
 
@@ -3545,7 +3532,7 @@
 	return 0;
 }
 
-static int snd_hdspm_free(hdspm_t * hdspm)
+static int snd_hdspm_free(struct hdspm * hdspm)
 {
 
 	if (hdspm->port) {
@@ -3568,8 +3555,6 @@
 	if (hdspm->iobase)
 		iounmap(hdspm->iobase);
 
-	snd_hdspm_memory_free(hdspm);
-
 	if (hdspm->port)
 		pci_release_regions(hdspm->pci);
 
@@ -3577,9 +3562,9 @@
 	return 0;
 }
 
-static void snd_hdspm_card_free(snd_card_t * card)
+static void snd_hdspm_card_free(struct snd_card *card)
 {
-	hdspm_t *hdspm = (hdspm_t *) card->private_data;
+	struct hdspm *hdspm = (struct hdspm *) card->private_data;
 
 	if (hdspm)
 		snd_hdspm_free(hdspm);
@@ -3589,8 +3574,8 @@
 				     const struct pci_device_id *pci_id)
 {
 	static int dev;
-	hdspm_t *hdspm;
-	snd_card_t *card;
+	struct hdspm *hdspm;
+	struct snd_card *card;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -3601,10 +3586,10 @@
 	}
 
 	if (!(card = snd_card_new(index[dev], id[dev],
-				  THIS_MODULE, sizeof(hdspm_t))))
+				  THIS_MODULE, sizeof(struct hdspm))))
 		return -ENOMEM;
 
-	hdspm = (hdspm_t *) card->private_data;
+	hdspm = (struct hdspm *) card->private_data;
 	card->private_free = snd_hdspm_card_free;
 	hdspm->dev = dev;
 	hdspm->pci = pci;
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index f9d0c12..a687eb6 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -198,7 +198,7 @@
 #define RME9652_DMA_AREA_BYTES ((RME9652_NCHANNELS+1) * RME9652_CHANNEL_BUFFER_BYTES)
 #define RME9652_DMA_AREA_KILOBYTES (RME9652_DMA_AREA_BYTES/1024)
 
-typedef struct snd_rme9652 {
+struct snd_rme9652 {
 	int dev;
 
 	spinlock_t lock;
@@ -234,8 +234,8 @@
 	pid_t capture_pid;
 	pid_t playback_pid;
 
-	snd_pcm_substream_t *capture_substream;
-	snd_pcm_substream_t *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+	struct snd_pcm_substream *playback_substream;
 	int running;
 
         int passthru;                   /* non-zero if doing pass-thru */
@@ -246,12 +246,12 @@
 
         char *channel_map;
 
-	snd_card_t *card;
-	snd_pcm_t *pcm;
+	struct snd_card *card;
+	struct snd_pcm *pcm;
 	struct pci_dev *pci;
-	snd_kcontrol_t *spdif_ctl;
+	struct snd_kcontrol *spdif_ctl;
 
-} rme9652_t;
+};
 
 /* These tables map the ALSA channels 1..N to the channels that we
    need to use in order to find the relevant channel buffer. RME
@@ -327,17 +327,17 @@
 
 MODULE_DEVICE_TABLE(pci, snd_rme9652_ids);
 
-static inline void rme9652_write(rme9652_t *rme9652, int reg, int val)
+static inline void rme9652_write(struct snd_rme9652 *rme9652, int reg, int val)
 {
 	writel(val, rme9652->iobase + reg);
 }
 
-static inline unsigned int rme9652_read(rme9652_t *rme9652, int reg)
+static inline unsigned int rme9652_read(struct snd_rme9652 *rme9652, int reg)
 {
 	return readl(rme9652->iobase + reg);
 }
 
-static inline int snd_rme9652_use_is_exclusive(rme9652_t *rme9652)
+static inline int snd_rme9652_use_is_exclusive(struct snd_rme9652 *rme9652)
 {
 	unsigned long flags;
 	int ret = 1;
@@ -351,7 +351,7 @@
 	return ret;
 }
 
-static inline int rme9652_adat_sample_rate(rme9652_t *rme9652)
+static inline int rme9652_adat_sample_rate(struct snd_rme9652 *rme9652)
 {
 	if (rme9652_running_double_speed(rme9652)) {
 		return (rme9652_read(rme9652, RME9652_status_register) &
@@ -362,7 +362,7 @@
 	}
 }
 
-static inline void rme9652_compute_period_size(rme9652_t *rme9652)
+static inline void rme9652_compute_period_size(struct snd_rme9652 *rme9652)
 {
 	unsigned int i;
 
@@ -373,7 +373,7 @@
 	rme9652->max_jitter = 80;
 }
 
-static snd_pcm_uframes_t rme9652_hw_pointer(rme9652_t *rme9652)
+static snd_pcm_uframes_t rme9652_hw_pointer(struct snd_rme9652 *rme9652)
 {
 	int status;
 	unsigned int offset, frag;
@@ -420,7 +420,7 @@
 	return offset;
 }
 
-static inline void rme9652_reset_hw_pointer(rme9652_t *rme9652)
+static inline void rme9652_reset_hw_pointer(struct snd_rme9652 *rme9652)
 {
 	int i;
 
@@ -437,19 +437,19 @@
 	rme9652->prev_hw_offset = 0;
 }
 
-static inline void rme9652_start(rme9652_t *s)
+static inline void rme9652_start(struct snd_rme9652 *s)
 {
 	s->control_register |= (RME9652_IE | RME9652_start_bit);
 	rme9652_write(s, RME9652_control_register, s->control_register);
 }
 
-static inline void rme9652_stop(rme9652_t *s)
+static inline void rme9652_stop(struct snd_rme9652 *s)
 {
 	s->control_register &= ~(RME9652_start_bit | RME9652_IE);
 	rme9652_write(s, RME9652_control_register, s->control_register);
 }
 
-static int rme9652_set_interrupt_interval(rme9652_t *s,
+static int rme9652_set_interrupt_interval(struct snd_rme9652 *s,
 					  unsigned int frames)
 {
 	int restart = 0;
@@ -483,7 +483,7 @@
 	return 0;
 }
 
-static int rme9652_set_rate(rme9652_t *rme9652, int rate)
+static int rme9652_set_rate(struct snd_rme9652 *rme9652, int rate)
 {
 	int restart;
 	int reject_if_open = 0;
@@ -571,7 +571,7 @@
 	return 0;
 }
 
-static void rme9652_set_thru(rme9652_t *rme9652, int channel, int enable)
+static void rme9652_set_thru(struct snd_rme9652 *rme9652, int channel, int enable)
 {
 	int i;
 
@@ -612,7 +612,7 @@
 	}
 }
 
-static int rme9652_set_passthru(rme9652_t *rme9652, int onoff)
+static int rme9652_set_passthru(struct snd_rme9652 *rme9652, int onoff)
 {
 	if (onoff) {
 		rme9652_set_thru(rme9652, -1, 1);
@@ -640,7 +640,7 @@
 	return 0;
 }
 
-static void rme9652_spdif_set_bit (rme9652_t *rme9652, int mask, int onoff)
+static void rme9652_spdif_set_bit (struct snd_rme9652 *rme9652, int mask, int onoff)
 {
 	if (onoff) 
 		rme9652->control_register |= mask;
@@ -650,7 +650,7 @@
 	rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);
 }
 
-static void rme9652_spdif_write_byte (rme9652_t *rme9652, const int val)
+static void rme9652_spdif_write_byte (struct snd_rme9652 *rme9652, const int val)
 {
 	long mask;
 	long i;
@@ -666,7 +666,7 @@
 	}
 }
 
-static int rme9652_spdif_read_byte (rme9652_t *rme9652)
+static int rme9652_spdif_read_byte (struct snd_rme9652 *rme9652)
 {
 	long mask;
 	long val;
@@ -684,7 +684,7 @@
 	return val;
 }
 
-static void rme9652_write_spdif_codec (rme9652_t *rme9652, const int address, const int data)
+static void rme9652_write_spdif_codec (struct snd_rme9652 *rme9652, const int address, const int data)
 {
 	rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1);
 	rme9652_spdif_write_byte (rme9652, 0x20);
@@ -694,7 +694,7 @@
 }
 
 
-static int rme9652_spdif_read_codec (rme9652_t *rme9652, const int address)
+static int rme9652_spdif_read_codec (struct snd_rme9652 *rme9652, const int address)
 {
 	int ret;
 
@@ -711,7 +711,7 @@
 	return ret;
 }
 
-static void rme9652_initialize_spdif_receiver (rme9652_t *rme9652)
+static void rme9652_initialize_spdif_receiver (struct snd_rme9652 *rme9652)
 {
 	/* XXX what unsets this ? */
 
@@ -722,7 +722,7 @@
 	rme9652_write_spdif_codec (rme9652, 6, 0x02);
 }
 
-static inline int rme9652_spdif_sample_rate(rme9652_t *s)
+static inline int rme9652_spdif_sample_rate(struct snd_rme9652 *s)
 {
 	unsigned int rate_bits;
 
@@ -790,7 +790,7 @@
   Control Interface
   ----------------------------------------------------------------------------*/
 
-static u32 snd_rme9652_convert_from_aes(snd_aes_iec958_t *aes)
+static u32 snd_rme9652_convert_from_aes(struct snd_aes_iec958 *aes)
 {
 	u32 val = 0;
 	val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME9652_PRO : 0;
@@ -802,7 +802,7 @@
 	return val;
 }
 
-static void snd_rme9652_convert_to_aes(snd_aes_iec958_t *aes, u32 val)
+static void snd_rme9652_convert_to_aes(struct snd_aes_iec958 *aes, u32 val)
 {
 	aes->status[0] = ((val & RME9652_PRO) ? IEC958_AES0_PROFESSIONAL : 0) |
 			 ((val & RME9652_Dolby) ? IEC958_AES0_NONAUDIO : 0);
@@ -812,24 +812,24 @@
 		aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;
 }
 
-static int snd_rme9652_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_control_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_rme9652_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_control_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	
 	snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif);
 	return 0;
 }
 
-static int snd_rme9652_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	int change;
 	u32 val;
 	
@@ -841,24 +841,24 @@
 	return change;
 }
 
-static int snd_rme9652_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_control_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_rme9652_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_control_spdif_stream_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	
 	snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif_stream);
 	return 0;
 }
 
-static int snd_rme9652_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_control_spdif_stream_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	int change;
 	u32 val;
 	
@@ -872,14 +872,14 @@
 	return change;
 }
 
-static int snd_rme9652_control_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_control_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_rme9652_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_control_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = kcontrol->private_value;
 	return 0;
@@ -891,14 +891,14 @@
   .get = snd_rme9652_get_adat1_in, \
   .put = snd_rme9652_put_adat1_in }
 
-static unsigned int rme9652_adat1_in(rme9652_t *rme9652)
+static unsigned int rme9652_adat1_in(struct snd_rme9652 *rme9652)
 {
 	if (rme9652->control_register & RME9652_ADAT1_INTERNAL)
 		return 1; 
 	return 0;
 }
 
-static int rme9652_set_adat1_input(rme9652_t *rme9652, int internal)
+static int rme9652_set_adat1_input(struct snd_rme9652 *rme9652, int internal)
 {
 	int restart = 0;
 
@@ -923,7 +923,7 @@
 	return 0;
 }
 
-static int snd_rme9652_info_adat1_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = {"ADAT1", "Internal"};
 
@@ -936,9 +936,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme9652->lock);
 	ucontrol->value.enumerated.item[0] = rme9652_adat1_in(rme9652);
@@ -946,9 +946,9 @@
 	return 0;
 }
 
-static int snd_rme9652_put_adat1_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_put_adat1_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -968,13 +968,13 @@
   .info = snd_rme9652_info_spdif_in, \
   .get = snd_rme9652_get_spdif_in, .put = snd_rme9652_put_spdif_in }
 
-static unsigned int rme9652_spdif_in(rme9652_t *rme9652)
+static unsigned int rme9652_spdif_in(struct snd_rme9652 *rme9652)
 {
 	return rme9652_decode_spdif_in(rme9652->control_register &
 				       RME9652_inp);
 }
 
-static int rme9652_set_spdif_input(rme9652_t *rme9652, int in)
+static int rme9652_set_spdif_input(struct snd_rme9652 *rme9652, int in)
 {
 	int restart = 0;
 
@@ -994,7 +994,7 @@
 	return 0;
 }
 
-static int snd_rme9652_info_spdif_in(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = {"ADAT1", "Coaxial", "Internal"};
 
@@ -1007,9 +1007,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme9652->lock);
 	ucontrol->value.enumerated.item[0] = rme9652_spdif_in(rme9652);
@@ -1017,9 +1017,9 @@
 	return 0;
 }
 
-static int snd_rme9652_put_spdif_in(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_put_spdif_in(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -1039,12 +1039,12 @@
   .info = snd_rme9652_info_spdif_out, \
   .get = snd_rme9652_get_spdif_out, .put = snd_rme9652_put_spdif_out }
 
-static int rme9652_spdif_out(rme9652_t *rme9652)
+static int rme9652_spdif_out(struct snd_rme9652 *rme9652)
 {
 	return (rme9652->control_register & RME9652_opt_out) ? 1 : 0;
 }
 
-static int rme9652_set_spdif_output(rme9652_t *rme9652, int out)
+static int rme9652_set_spdif_output(struct snd_rme9652 *rme9652, int out)
 {
 	int restart = 0;
 
@@ -1067,7 +1067,7 @@
 	return 0;
 }
 
-static int snd_rme9652_info_spdif_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1076,9 +1076,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme9652->lock);
 	ucontrol->value.integer.value[0] = rme9652_spdif_out(rme9652);
@@ -1086,9 +1086,9 @@
 	return 0;
 }
 
-static int snd_rme9652_put_spdif_out(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_put_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -1107,7 +1107,7 @@
   .info = snd_rme9652_info_sync_mode, \
   .get = snd_rme9652_get_sync_mode, .put = snd_rme9652_put_sync_mode }
 
-static int rme9652_sync_mode(rme9652_t *rme9652)
+static int rme9652_sync_mode(struct snd_rme9652 *rme9652)
 {
 	if (rme9652->control_register & RME9652_wsel) {
 		return 2;
@@ -1118,7 +1118,7 @@
 	}
 }
 
-static int rme9652_set_sync_mode(rme9652_t *rme9652, int mode)
+static int rme9652_set_sync_mode(struct snd_rme9652 *rme9652, int mode)
 {
 	int restart = 0;
 
@@ -1150,7 +1150,7 @@
 	return 0;
 }
 
-static int snd_rme9652_info_sync_mode(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[3] = {"AutoSync", "Master", "Word Clock"};
 
@@ -1163,9 +1163,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme9652->lock);
 	ucontrol->value.enumerated.item[0] = rme9652_sync_mode(rme9652);
@@ -1173,9 +1173,9 @@
 	return 0;
 }
 
-static int snd_rme9652_put_sync_mode(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_put_sync_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	
@@ -1192,7 +1192,7 @@
   .info = snd_rme9652_info_sync_pref, \
   .get = snd_rme9652_get_sync_pref, .put = snd_rme9652_put_sync_pref }
 
-static int rme9652_sync_pref(rme9652_t *rme9652)
+static int rme9652_sync_pref(struct snd_rme9652 *rme9652)
 {
 	switch (rme9652->control_register & RME9652_SyncPref_Mask) {
 	case RME9652_SyncPref_ADAT1:
@@ -1208,7 +1208,7 @@
 	return 0;
 }
 
-static int rme9652_set_sync_pref(rme9652_t *rme9652, int pref)
+static int rme9652_set_sync_pref(struct snd_rme9652 *rme9652, int pref)
 {
 	int restart;
 
@@ -1241,10 +1241,10 @@
 	return 0;
 }
 
-static int snd_rme9652_info_sync_pref(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = {"IEC958 In", "ADAT1 In", "ADAT2 In", "ADAT3 In"};
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 	uinfo->count = 1;
@@ -1255,9 +1255,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme9652->lock);
 	ucontrol->value.enumerated.item[0] = rme9652_sync_pref(rme9652);
@@ -1265,9 +1265,9 @@
 	return 0;
 }
 
-static int snd_rme9652_put_sync_pref(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_put_sync_pref(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	int change, max;
 	unsigned int val;
 	
@@ -1282,9 +1282,9 @@
 	return change;
 }
 
-static int snd_rme9652_info_thru(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = rme9652->ss_channels;
 	uinfo->value.integer.min = 0;
@@ -1292,9 +1292,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	unsigned int k;
 	u32 thru_bits = rme9652->thru_bits;
 
@@ -1304,9 +1304,9 @@
 	return 0;
 }
 
-static int snd_rme9652_put_thru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_put_thru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int chn;
 	u32 thru_bits = 0;
@@ -1338,7 +1338,7 @@
   .put = snd_rme9652_put_passthru, \
   .get = snd_rme9652_get_passthru }
 
-static int snd_rme9652_info_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1347,9 +1347,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&rme9652->lock);
 	ucontrol->value.integer.value[0] = rme9652->passthru;
@@ -1357,9 +1357,9 @@
 	return 0;
 }
 
-static int snd_rme9652_put_passthru(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_put_passthru(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	int change;
 	unsigned int val;
 	int err = 0;
@@ -1384,7 +1384,7 @@
   .info = snd_rme9652_info_spdif_rate, \
   .get = snd_rme9652_get_spdif_rate }
 
-static int snd_rme9652_info_spdif_rate(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_spdif_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -1393,9 +1393,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_spdif_rate(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_spdif_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&rme9652->lock);
 	ucontrol->value.integer.value[0] = rme9652_spdif_sample_rate(rme9652);
@@ -1409,7 +1409,7 @@
   .info = snd_rme9652_info_adat_sync, \
   .get = snd_rme9652_get_adat_sync, .private_value = xidx }
 
-static int snd_rme9652_info_adat_sync(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = {"No Lock", "Lock", "No Lock Sync", "Lock Sync"};
 
@@ -1422,9 +1422,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_adat_sync(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_adat_sync(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	unsigned int mask1, mask2, val;
 	
 	switch (kcontrol->private_value) {
@@ -1445,7 +1445,7 @@
   .info = snd_rme9652_info_tc_valid, \
   .get = snd_rme9652_get_tc_valid }
 
-static int snd_rme9652_info_tc_valid(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_rme9652_info_tc_valid(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1454,9 +1454,9 @@
 	return 0;
 }
 
-static int snd_rme9652_get_tc_valid(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_rme9652_get_tc_valid(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol);
+	struct snd_rme9652 *rme9652 = snd_kcontrol_chip(kcontrol);
 	
 	ucontrol->value.integer.value[0] = 
 		(rme9652_read(rme9652, RME9652_status_register) & RME9652_tc_valid) ? 1 : 0;
@@ -1471,7 +1471,7 @@
 				    snd_kswitch_t *kswitch,
 				    snd_switch_t *uswitch)
 {
-	rme9652_t *s = (rme9652_t *) private_data;
+	struct snd_rme9652 *s = (struct snd_rme9652 *) private_data;
 	u32 value;
 	int i;
 
@@ -1520,7 +1520,7 @@
 
 #endif				/* ALSA_HAS_STANDARD_WAY_OF_RETURNING_TIMECODE */
 
-static snd_kcontrol_new_t snd_rme9652_controls[] = {
+static struct snd_kcontrol_new snd_rme9652_controls[] = {
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1575,17 +1575,17 @@
 RME9652_PASSTHRU("Passthru", 0)
 };
 
-static snd_kcontrol_new_t snd_rme9652_adat3_check =
+static struct snd_kcontrol_new snd_rme9652_adat3_check =
 RME9652_ADAT_SYNC("ADAT3 Sync Check", 0, 2);
 
-static snd_kcontrol_new_t snd_rme9652_adat1_input =
+static struct snd_kcontrol_new snd_rme9652_adat1_input =
 RME9652_ADAT1_IN("ADAT1 Input Source", 0);
 
-static int snd_rme9652_create_controls(snd_card_t *card, rme9652_t *rme9652)
+static int snd_rme9652_create_controls(struct snd_card *card, struct snd_rme9652 *rme9652)
 {
 	unsigned int idx;
 	int err;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	for (idx = 0; idx < ARRAY_SIZE(snd_rme9652_controls); idx++) {
 		if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme9652_controls[idx], rme9652))) < 0)
@@ -1610,9 +1610,9 @@
  ------------------------------------------------------------*/
 
 static void
-snd_rme9652_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+snd_rme9652_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	rme9652_t *rme9652 = (rme9652_t *) entry->private_data;
+	struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) entry->private_data;
 	u32 thru_bits = rme9652->thru_bits;
 	int show_auto_sync_source = 0;
 	int i;
@@ -1782,21 +1782,21 @@
 	snd_iprintf(buffer, "\n");
 }
 
-static void __devinit snd_rme9652_proc_init(rme9652_t *rme9652)
+static void __devinit snd_rme9652_proc_init(struct snd_rme9652 *rme9652)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(rme9652->card, "rme9652", &entry))
 		snd_info_set_text_ops(entry, rme9652, 1024, snd_rme9652_proc_read);
 }
 
-static void snd_rme9652_free_buffers(rme9652_t *rme9652)
+static void snd_rme9652_free_buffers(struct snd_rme9652 *rme9652)
 {
 	snd_hammerfall_free_buffer(&rme9652->capture_dma_buf, rme9652->pci);
 	snd_hammerfall_free_buffer(&rme9652->playback_dma_buf, rme9652->pci);
 }
 
-static int snd_rme9652_free(rme9652_t *rme9652)
+static int snd_rme9652_free(struct snd_rme9652 *rme9652)
 {
 	if (rme9652->irq >= 0)
 		rme9652_stop(rme9652);
@@ -1813,7 +1813,7 @@
 	return 0;
 }
 
-static int __devinit snd_rme9652_initialize_memory(rme9652_t *rme9652)
+static int __devinit snd_rme9652_initialize_memory(struct snd_rme9652 *rme9652)
 {
 	unsigned long pb_bus, cb_bus;
 
@@ -1841,7 +1841,7 @@
 	return 0;
 }
 
-static void snd_rme9652_set_defaults(rme9652_t *rme9652)
+static void snd_rme9652_set_defaults(struct snd_rme9652 *rme9652)
 {
 	unsigned int k;
 
@@ -1884,7 +1884,7 @@
 
 static irqreturn_t snd_rme9652_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	rme9652_t *rme9652 = (rme9652_t *) dev_id;
+	struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) dev_id;
 
 	if (!(rme9652_read(rme9652, RME9652_status_register) & RME9652_IRQ)) {
 		return IRQ_NONE;
@@ -1902,13 +1902,13 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_uframes_t snd_rme9652_hw_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_rme9652_hw_pointer(struct snd_pcm_substream *substream)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 	return rme9652_hw_pointer(rme9652);
 }
 
-static char *rme9652_channel_buffer_location(rme9652_t *rme9652,
+static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652,
 					     int stream,
 					     int channel)
 
@@ -1930,10 +1930,10 @@
 	}
 }
 
-static int snd_rme9652_playback_copy(snd_pcm_substream_t *substream, int channel,
+static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, int channel,
 				     snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 	char *channel_buf;
 
 	snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
@@ -1947,10 +1947,10 @@
 	return count;
 }
 
-static int snd_rme9652_capture_copy(snd_pcm_substream_t *substream, int channel,
+static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, int channel,
 				    snd_pcm_uframes_t pos, void __user *dst, snd_pcm_uframes_t count)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 	char *channel_buf;
 
 	snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL);
@@ -1964,10 +1964,10 @@
 	return count;
 }
 
-static int snd_rme9652_hw_silence(snd_pcm_substream_t *substream, int channel,
+static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream, int channel,
 				  snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 	char *channel_buf;
 
 	channel_buf = rme9652_channel_buffer_location (rme9652,
@@ -1978,11 +1978,11 @@
 	return count;
 }
 
-static int snd_rme9652_reset(snd_pcm_substream_t *substream)
+static int snd_rme9652_reset(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
-	snd_pcm_substream_t *other;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_substream *other;
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		other = rme9652->capture_substream;
 	else
@@ -1993,8 +1993,8 @@
 		runtime->status->hw_ptr = 0;
 	if (other) {
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
-		snd_pcm_runtime_t *oruntime = other->runtime;
+		struct snd_pcm_substream *s;
+		struct snd_pcm_runtime *oruntime = other->runtime;
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == other) {
@@ -2006,10 +2006,10 @@
 	return 0;
 }
 
-static int snd_rme9652_hw_params(snd_pcm_substream_t *substream,
-				 snd_pcm_hw_params_t *params)
+static int snd_rme9652_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *params)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 	int err;
 	pid_t this_pid;
 	pid_t other_pid;
@@ -2071,10 +2071,10 @@
 	return 0;
 }
 
-static int snd_rme9652_channel_info(snd_pcm_substream_t *substream,
-				    snd_pcm_channel_info_t *info)
+static int snd_rme9652_channel_info(struct snd_pcm_substream *substream,
+				    struct snd_pcm_channel_info *info)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 	int chn;
 
 	snd_assert(info->channel < RME9652_NCHANNELS, return -EINVAL);
@@ -2089,7 +2089,7 @@
 	return 0;
 }
 
-static int snd_rme9652_ioctl(snd_pcm_substream_t *substream,
+static int snd_rme9652_ioctl(struct snd_pcm_substream *substream,
 			     unsigned int cmd, void *arg)
 {
 	switch (cmd) {
@@ -2099,7 +2099,7 @@
 	}
 	case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
 	{
-		snd_pcm_channel_info_t *info = arg;
+		struct snd_pcm_channel_info *info = arg;
 		return snd_rme9652_channel_info(substream, info);
 	}
 	default:
@@ -2109,16 +2109,16 @@
 	return snd_pcm_lib_ioctl(substream, cmd, arg);
 }
 
-static void rme9652_silence_playback(rme9652_t *rme9652)
+static void rme9652_silence_playback(struct snd_rme9652 *rme9652)
 {
 	memset(rme9652->playback_buffer, 0, RME9652_DMA_AREA_BYTES);
 }
 
-static int snd_rme9652_trigger(snd_pcm_substream_t *substream,
+static int snd_rme9652_trigger(struct snd_pcm_substream *substream,
 			       int cmd)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
-	snd_pcm_substream_t *other;
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_substream *other;
 	int running;
 	spin_lock(&rme9652->lock);
 	running = rme9652->running;
@@ -2141,7 +2141,7 @@
 
 	if (other) {
 		struct list_head *pos;
-		snd_pcm_substream_t *s;
+		struct snd_pcm_substream *s;
 		snd_pcm_group_for_each(pos, substream) {
 			s = snd_pcm_group_substream_entry(pos);
 			if (s == other) {
@@ -2178,9 +2178,9 @@
 	return 0;
 }
 
-static int snd_rme9652_prepare(snd_pcm_substream_t *substream)
+static int snd_rme9652_prepare(struct snd_pcm_substream *substream)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 	unsigned long flags;
 	int result = 0;
 
@@ -2191,7 +2191,7 @@
 	return result;
 }
 
-static snd_pcm_hardware_t snd_rme9652_playback_subinfo =
+static struct snd_pcm_hardware snd_rme9652_playback_subinfo =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_MMAP_VALID |
@@ -2215,7 +2215,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_rme9652_capture_subinfo =
+static struct snd_pcm_hardware snd_rme9652_capture_subinfo =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_MMAP_VALID |
@@ -2240,36 +2240,36 @@
 
 static unsigned int period_sizes[] = { 64, 128, 256, 512, 1024, 2048, 4096, 8192 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_period_sizes = {
+static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes = {
 	.count = ARRAY_SIZE(period_sizes),
 	.list = period_sizes,
 	.mask = 0
 };
 
-static int snd_rme9652_hw_rule_channels(snd_pcm_hw_params_t *params,
-					snd_pcm_hw_rule_t *rule)
+static int snd_rme9652_hw_rule_channels(struct snd_pcm_hw_params *params,
+					struct snd_pcm_hw_rule *rule)
 {
-	rme9652_t *rme9652 = rule->private;
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_rme9652 *rme9652 = rule->private;
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 	unsigned int list[2] = { rme9652->ds_channels, rme9652->ss_channels };
 	return snd_interval_list(c, 2, list, 0);
 }
 
-static int snd_rme9652_hw_rule_channels_rate(snd_pcm_hw_params_t *params,
-					     snd_pcm_hw_rule_t *rule)
+static int snd_rme9652_hw_rule_channels_rate(struct snd_pcm_hw_params *params,
+					     struct snd_pcm_hw_rule *rule)
 {
-	rme9652_t *rme9652 = rule->private;
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_rme9652 *rme9652 = rule->private;
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (r->min > 48000) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = rme9652->ds_channels,
 			.max = rme9652->ds_channels,
 			.integer = 1,
 		};
 		return snd_interval_refine(c, &t);
 	} else if (r->max < 88200) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = rme9652->ss_channels,
 			.max = rme9652->ss_channels,
 			.integer = 1,
@@ -2279,21 +2279,21 @@
 	return 0;
 }
 
-static int snd_rme9652_hw_rule_rate_channels(snd_pcm_hw_params_t *params,
-					     snd_pcm_hw_rule_t *rule)
+static int snd_rme9652_hw_rule_rate_channels(struct snd_pcm_hw_params *params,
+					     struct snd_pcm_hw_rule *rule)
 {
-	rme9652_t *rme9652 = rule->private;
-	snd_interval_t *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	snd_interval_t *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_rme9652 *rme9652 = rule->private;
+	struct snd_interval *c = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	if (c->min >= rme9652->ss_channels) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 44100,
 			.max = 48000,
 			.integer = 1,
 		};
 		return snd_interval_refine(r, &t);
 	} else if (c->max <= rme9652->ds_channels) {
-		snd_interval_t t = {
+		struct snd_interval t = {
 			.min = 88200,
 			.max = 96000,
 			.integer = 1,
@@ -2303,10 +2303,10 @@
 	return 0;
 }
 
-static int snd_rme9652_playback_open(snd_pcm_substream_t *substream)
+static int snd_rme9652_playback_open(struct snd_pcm_substream *substream)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	spin_lock_irq(&rme9652->lock);
 
@@ -2345,9 +2345,9 @@
 	return 0;
 }
 
-static int snd_rme9652_playback_release(snd_pcm_substream_t *substream)
+static int snd_rme9652_playback_release(struct snd_pcm_substream *substream)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&rme9652->lock);
 
@@ -2363,10 +2363,10 @@
 }
 
 
-static int snd_rme9652_capture_open(snd_pcm_substream_t *substream)
+static int snd_rme9652_capture_open(struct snd_pcm_substream *substream)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	spin_lock_irq(&rme9652->lock);
 
@@ -2400,9 +2400,9 @@
 	return 0;
 }
 
-static int snd_rme9652_capture_release(snd_pcm_substream_t *substream)
+static int snd_rme9652_capture_release(struct snd_pcm_substream *substream)
 {
-	rme9652_t *rme9652 = snd_pcm_substream_chip(substream);
+	struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&rme9652->lock);
 
@@ -2413,7 +2413,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_rme9652_playback_ops = {
+static struct snd_pcm_ops snd_rme9652_playback_ops = {
 	.open =		snd_rme9652_playback_open,
 	.close =	snd_rme9652_playback_release,
 	.ioctl =	snd_rme9652_ioctl,
@@ -2425,7 +2425,7 @@
 	.silence =	snd_rme9652_hw_silence,
 };
 
-static snd_pcm_ops_t snd_rme9652_capture_ops = {
+static struct snd_pcm_ops snd_rme9652_capture_ops = {
 	.open =		snd_rme9652_capture_open,
 	.close =	snd_rme9652_capture_release,
 	.ioctl =	snd_rme9652_ioctl,
@@ -2436,10 +2436,10 @@
 	.copy =		snd_rme9652_capture_copy,
 };
 
-static int __devinit snd_rme9652_create_pcm(snd_card_t *card,
-					 rme9652_t *rme9652)
+static int __devinit snd_rme9652_create_pcm(struct snd_card *card,
+					 struct snd_rme9652 *rme9652)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(card,
@@ -2460,8 +2460,8 @@
 	return 0;
 }
 
-static int __devinit snd_rme9652_create(snd_card_t *card,
-				     rme9652_t *rme9652,
+static int __devinit snd_rme9652_create(struct snd_card *card,
+				     struct snd_rme9652 *rme9652,
 				     int precise_ptr)
 {
 	struct pci_dev *pci = rme9652->pci;
@@ -2591,9 +2591,9 @@
 	return 0;
 }
 
-static void snd_rme9652_card_free(snd_card_t *card)
+static void snd_rme9652_card_free(struct snd_card *card)
 {
-	rme9652_t *rme9652 = (rme9652_t *) card->private_data;
+	struct snd_rme9652 *rme9652 = (struct snd_rme9652 *) card->private_data;
 
 	if (rme9652)
 		snd_rme9652_free(rme9652);
@@ -2603,8 +2603,8 @@
 				       const struct pci_device_id *pci_id)
 {
 	static int dev;
-	rme9652_t *rme9652;
-	snd_card_t *card;
+	struct snd_rme9652 *rme9652;
+	struct snd_card *card;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -2615,12 +2615,12 @@
 	}
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
-			    sizeof(rme9652_t));
+			    sizeof(struct snd_rme9652));
 
 	if (!card)
 		return -ENOMEM;
 
-	rme9652 = (rme9652_t *) card->private_data;
+	rme9652 = (struct snd_rme9652 *) card->private_data;
 	card->private_free = snd_rme9652_card_free;
 	rme9652->dev = dev;
 	rme9652->pci = pci;
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index e92ef3a..7bbea37 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -195,9 +195,7 @@
 
  */
 
-typedef struct _snd_sonicvibes sonicvibes_t;
-
-struct _snd_sonicvibes {
+struct sonicvibes {
 	unsigned long dma1size;
 	unsigned long dma2size;
 	int irq;
@@ -224,20 +222,20 @@
 	unsigned int mode;
 
 	struct pci_dev *pci;
-	snd_card_t *card;
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *playback_substream;
-	snd_pcm_substream_t *capture_substream;
-	snd_rawmidi_t *rmidi;
-	snd_hwdep_t *fmsynth;	/* S3FM */
+	struct snd_card *card;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *playback_substream;
+	struct snd_pcm_substream *capture_substream;
+	struct snd_rawmidi *rmidi;
+	struct snd_hwdep *fmsynth;	/* S3FM */
 
 	spinlock_t reg_lock;
 
 	unsigned int p_dma_size;
 	unsigned int c_dma_size;
 
-	snd_kcontrol_t *master_mute;
-	snd_kcontrol_t *master_volume;
+	struct snd_kcontrol *master_mute;
+	struct snd_kcontrol *master_volume;
 
 #ifdef SUPPORT_JOYSTICK
 	struct gameport *gameport;
@@ -251,13 +249,13 @@
 
 MODULE_DEVICE_TABLE(pci, snd_sonic_ids);
 
-static ratden_t sonicvibes_adc_clock = {
+static struct snd_ratden sonicvibes_adc_clock = {
 	.num_min = 4000 * 65536,
 	.num_max = 48000UL * 65536,
 	.num_step = 1,
 	.den = 65536,
 };
-static snd_pcm_hw_constraint_ratdens_t snd_sonicvibes_hw_constraints_adc_clock = {
+static struct snd_pcm_hw_constraint_ratdens snd_sonicvibes_hw_constraints_adc_clock = {
 	.nrats = 1,
 	.rats = &sonicvibes_adc_clock,
 };
@@ -266,7 +264,7 @@
  *  common I/O routines
  */
 
-static inline void snd_sonicvibes_setdmaa(sonicvibes_t * sonic,
+static inline void snd_sonicvibes_setdmaa(struct sonicvibes * sonic,
 					  unsigned int addr,
 					  unsigned int count)
 {
@@ -279,7 +277,7 @@
 #endif
 }
 
-static inline void snd_sonicvibes_setdmac(sonicvibes_t * sonic,
+static inline void snd_sonicvibes_setdmac(struct sonicvibes * sonic,
 					  unsigned int addr,
 					  unsigned int count)
 {
@@ -294,18 +292,18 @@
 #endif
 }
 
-static inline unsigned int snd_sonicvibes_getdmaa(sonicvibes_t * sonic)
+static inline unsigned int snd_sonicvibes_getdmaa(struct sonicvibes * sonic)
 {
 	return (inl(sonic->dmaa_port + SV_DMA_COUNT0) & 0xffffff) + 1;
 }
 
-static inline unsigned int snd_sonicvibes_getdmac(sonicvibes_t * sonic)
+static inline unsigned int snd_sonicvibes_getdmac(struct sonicvibes * sonic)
 {
 	/* note: dmac is working in word mode!!! */
 	return ((inl(sonic->dmac_port + SV_DMA_COUNT0) & 0xffffff) + 1) << 1;
 }
 
-static void snd_sonicvibes_out1(sonicvibes_t * sonic,
+static void snd_sonicvibes_out1(struct sonicvibes * sonic,
 				unsigned char reg,
 				unsigned char value)
 {
@@ -315,7 +313,7 @@
 	udelay(10);
 }
 
-static void snd_sonicvibes_out(sonicvibes_t * sonic,
+static void snd_sonicvibes_out(struct sonicvibes * sonic,
 			       unsigned char reg,
 			       unsigned char value)
 {
@@ -329,7 +327,7 @@
 	spin_unlock_irqrestore(&sonic->reg_lock, flags);
 }
 
-static unsigned char snd_sonicvibes_in1(sonicvibes_t * sonic, unsigned char reg)
+static unsigned char snd_sonicvibes_in1(struct sonicvibes * sonic, unsigned char reg)
 {
 	unsigned char value;
 
@@ -340,7 +338,7 @@
 	return value;
 }
 
-static unsigned char snd_sonicvibes_in(sonicvibes_t * sonic, unsigned char reg)
+static unsigned char snd_sonicvibes_in(struct sonicvibes * sonic, unsigned char reg)
 {
 	unsigned long flags;
 	unsigned char value;
@@ -355,7 +353,7 @@
 }
 
 #if 0
-static void snd_sonicvibes_debug(sonicvibes_t * sonic)
+static void snd_sonicvibes_debug(struct sonicvibes * sonic)
 {
 	printk("SV REGS:          INDEX = 0x%02x  ", inb(SV_REG(sonic, INDEX)));
 	printk("                 STATUS = 0x%02x\n", inb(SV_REG(sonic, STATUS)));
@@ -427,7 +425,7 @@
 
 #endif
 
-static void snd_sonicvibes_setfmt(sonicvibes_t * sonic,
+static void snd_sonicvibes_setfmt(struct sonicvibes * sonic,
                                   unsigned char mask,
                                   unsigned char value)
 {
@@ -483,7 +481,7 @@
 #endif
 }
 
-static void snd_sonicvibes_setpll(sonicvibes_t * sonic,
+static void snd_sonicvibes_setpll(struct sonicvibes * sonic,
                                   unsigned char reg,
                                   unsigned int rate)
 {
@@ -499,7 +497,7 @@
 	}
 }
 
-static void snd_sonicvibes_set_adc_rate(sonicvibes_t * sonic, unsigned int rate)
+static void snd_sonicvibes_set_adc_rate(struct sonicvibes * sonic, unsigned int rate)
 {
 	unsigned long flags;
 	unsigned int div;
@@ -520,8 +518,8 @@
 	spin_unlock_irqrestore(&sonic->reg_lock, flags);
 }
 
-static int snd_sonicvibes_hw_constraint_dac_rate(snd_pcm_hw_params_t *params,
-						 snd_pcm_hw_rule_t *rule)
+static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *params,
+						 struct snd_pcm_hw_rule *rule)
 {
 	unsigned int rate, div, r, m, n;
 
@@ -545,7 +543,7 @@
 	return 0;
 }
 
-static void snd_sonicvibes_set_dac_rate(sonicvibes_t * sonic, unsigned int rate)
+static void snd_sonicvibes_set_dac_rate(struct sonicvibes * sonic, unsigned int rate)
 {
 	unsigned int div;
 	unsigned long flags;
@@ -559,7 +557,7 @@
 	spin_unlock_irqrestore(&sonic->reg_lock, flags);
 }
 
-static int snd_sonicvibes_trigger(sonicvibes_t * sonic, int what, int cmd)
+static int snd_sonicvibes_trigger(struct sonicvibes * sonic, int what, int cmd)
 {
 	int result = 0;
 
@@ -583,7 +581,7 @@
 
 static irqreturn_t snd_sonicvibes_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	sonicvibes_t *sonic = dev_id;
+	struct sonicvibes *sonic = dev_id;
 	unsigned char status;
 
 	status = inb(SV_REG(sonic, STATUS));
@@ -646,35 +644,35 @@
  *  PCM part
  */
 
-static int snd_sonicvibes_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_sonicvibes_playback_trigger(struct snd_pcm_substream *substream,
 					   int cmd)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
 	return snd_sonicvibes_trigger(sonic, 1, cmd);
 }
 
-static int snd_sonicvibes_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_sonicvibes_capture_trigger(struct snd_pcm_substream *substream,
 					  int cmd)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
 	return snd_sonicvibes_trigger(sonic, 2, cmd);
 }
 
-static int snd_sonicvibes_hw_params(snd_pcm_substream_t * substream,
-				    snd_pcm_hw_params_t * hw_params)
+static int snd_sonicvibes_hw_params(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_sonicvibes_hw_free(snd_pcm_substream_t * substream)
+static int snd_sonicvibes_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_sonicvibes_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_sonicvibes_playback_prepare(struct snd_pcm_substream *substream)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned char fmt = 0;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -695,10 +693,10 @@
 	return 0;
 }
 
-static int snd_sonicvibes_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_sonicvibes_capture_prepare(struct snd_pcm_substream *substream)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned char fmt = 0;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned int count = snd_pcm_lib_period_bytes(substream);
@@ -720,9 +718,9 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_sonicvibes_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_sonicvibes_playback_pointer(struct snd_pcm_substream *substream)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(sonic->enable & 1))
@@ -731,9 +729,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_sonicvibes_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_sonicvibes_capture_pointer(struct snd_pcm_substream *substream)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
 	size_t ptr;
 	if (!(sonic->enable & 2))
 		return 0;
@@ -741,7 +739,7 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_hardware_t snd_sonicvibes_playback =
+static struct snd_pcm_hardware snd_sonicvibes_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -760,7 +758,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_sonicvibes_capture =
+static struct snd_pcm_hardware snd_sonicvibes_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -779,10 +777,10 @@
 	.fifo_size =		0,
 };
 
-static int snd_sonicvibes_playback_open(snd_pcm_substream_t * substream)
+static int snd_sonicvibes_playback_open(struct snd_pcm_substream *substream)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	sonic->mode |= SV_MODE_PLAY;
 	sonic->playback_substream = substream;
@@ -791,10 +789,10 @@
 	return 0;
 }
 
-static int snd_sonicvibes_capture_open(snd_pcm_substream_t * substream)
+static int snd_sonicvibes_capture_open(struct snd_pcm_substream *substream)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	sonic->mode |= SV_MODE_CAPTURE;
 	sonic->capture_substream = substream;
@@ -804,25 +802,25 @@
 	return 0;
 }
 
-static int snd_sonicvibes_playback_close(snd_pcm_substream_t * substream)
+static int snd_sonicvibes_playback_close(struct snd_pcm_substream *substream)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
 
 	sonic->playback_substream = NULL;
 	sonic->mode &= ~SV_MODE_PLAY;
 	return 0;
 }
 
-static int snd_sonicvibes_capture_close(snd_pcm_substream_t * substream)
+static int snd_sonicvibes_capture_close(struct snd_pcm_substream *substream)
 {
-	sonicvibes_t *sonic = snd_pcm_substream_chip(substream);
+	struct sonicvibes *sonic = snd_pcm_substream_chip(substream);
 
 	sonic->capture_substream = NULL;
 	sonic->mode &= ~SV_MODE_CAPTURE;
 	return 0;
 }
 
-static snd_pcm_ops_t snd_sonicvibes_playback_ops = {
+static struct snd_pcm_ops snd_sonicvibes_playback_ops = {
 	.open =		snd_sonicvibes_playback_open,
 	.close =	snd_sonicvibes_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -833,7 +831,7 @@
 	.pointer =	snd_sonicvibes_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_sonicvibes_capture_ops = {
+static struct snd_pcm_ops snd_sonicvibes_capture_ops = {
 	.open =		snd_sonicvibes_capture_open,
 	.close =	snd_sonicvibes_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -844,16 +842,9 @@
 	.pointer =	snd_sonicvibes_capture_pointer,
 };
 
-static void snd_sonicvibes_pcm_free(snd_pcm_t *pcm)
+static int __devinit snd_sonicvibes_pcm(struct sonicvibes * sonic, int device, struct snd_pcm ** rpcm)
 {
-	sonicvibes_t *sonic = pcm->private_data;
-	sonic->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __devinit snd_sonicvibes_pcm(sonicvibes_t * sonic, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm)) < 0)
@@ -864,7 +855,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sonicvibes_capture_ops);
 
 	pcm->private_data = sonic;
-	pcm->private_free = snd_sonicvibes_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, "S3 SonicVibes");
 	sonic->pcm = pcm;
@@ -886,7 +876,7 @@
   .info = snd_sonicvibes_info_mux, \
   .get = snd_sonicvibes_get_mux, .put = snd_sonicvibes_put_mux }
 
-static int snd_sonicvibes_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sonicvibes_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[7] = {
 		"CD", "PCM", "Aux1", "Line", "Aux0", "Mic", "Mix"
@@ -901,9 +891,9 @@
 	return 0;
 }
 
-static int snd_sonicvibes_get_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sonicvibes_get_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
+	struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
 	
 	spin_lock_irq(&sonic->reg_lock);
 	ucontrol->value.enumerated.item[0] = ((snd_sonicvibes_in1(sonic, SV_IREG_LEFT_ADC) & SV_RECSRC_OUT) >> 5) - 1;
@@ -912,9 +902,9 @@
 	return 0;
 }
 
-static int snd_sonicvibes_put_mux(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sonicvibes_put_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
+	struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
 	unsigned short left, right, oval1, oval2;
 	int change;
 	
@@ -941,7 +931,7 @@
   .get = snd_sonicvibes_get_single, .put = snd_sonicvibes_put_single, \
   .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
 
-static int snd_sonicvibes_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sonicvibes_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -952,9 +942,9 @@
 	return 0;
 }
 
-static int snd_sonicvibes_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sonicvibes_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
+	struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -968,9 +958,9 @@
 	return 0;
 }
 
-static int snd_sonicvibes_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sonicvibes_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
+	struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -997,7 +987,7 @@
   .get = snd_sonicvibes_get_double, .put = snd_sonicvibes_put_double, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-static int snd_sonicvibes_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_sonicvibes_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -1008,9 +998,9 @@
 	return 0;
 }
 
-static int snd_sonicvibes_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sonicvibes_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
+	struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1029,9 +1019,9 @@
 	return 0;
 }
 
-static int snd_sonicvibes_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_sonicvibes_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
+	struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
 	int shift_left = (kcontrol->private_value >> 16) & 0x07;
@@ -1061,7 +1051,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_sonicvibes_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_sonicvibes_controls[] __devinitdata = {
 SONICVIBES_DOUBLE("Capture Volume", 0, SV_IREG_LEFT_ADC, SV_IREG_RIGHT_ADC, 0, 0, 15, 0),
 SONICVIBES_DOUBLE("Aux Playback Switch", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 7, 7, 1, 1),
 SONICVIBES_DOUBLE("Aux Playback Volume", 0, SV_IREG_LEFT_AUX1, SV_IREG_RIGHT_AUX1, 0, 0, 31, 1),
@@ -1085,17 +1075,17 @@
 SONICVIBES_MUX("Capture Source", 0)
 };
 
-static void snd_sonicvibes_master_free(snd_kcontrol_t *kcontrol)
+static void snd_sonicvibes_master_free(struct snd_kcontrol *kcontrol)
 {
-	sonicvibes_t *sonic = snd_kcontrol_chip(kcontrol);
+	struct sonicvibes *sonic = snd_kcontrol_chip(kcontrol);
 	sonic->master_mute = NULL;
 	sonic->master_volume = NULL;
 }
 
-static int __devinit snd_sonicvibes_mixer(sonicvibes_t * sonic)
+static int __devinit snd_sonicvibes_mixer(struct sonicvibes * sonic)
 {
-	snd_card_t *card;
-	snd_kcontrol_t *kctl;
+	struct snd_card *card;
+	struct snd_kcontrol *kctl;
 	unsigned int idx;
 	int err;
 
@@ -1118,10 +1108,10 @@
 
  */
 
-static void snd_sonicvibes_proc_read(snd_info_entry_t *entry, 
-				     snd_info_buffer_t * buffer)
+static void snd_sonicvibes_proc_read(struct snd_info_entry *entry, 
+				     struct snd_info_buffer *buffer)
 {
-	sonicvibes_t *sonic = entry->private_data;
+	struct sonicvibes *sonic = entry->private_data;
 	unsigned char tmp;
 
 	tmp = sonic->srs_space & 0x0f;
@@ -1148,9 +1138,9 @@
 	snd_iprintf(buffer, "MIDI to ext. Tx  : %s\n", tmp & 0x04 ? "on" : "off");
 }
 
-static void __devinit snd_sonicvibes_proc_init(sonicvibes_t * sonic)
+static void __devinit snd_sonicvibes_proc_init(struct sonicvibes * sonic)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(sonic->card, "sonicvibes", &entry))
 		snd_info_set_text_ops(entry, sonic, 1024, snd_sonicvibes_proc_read);
@@ -1161,10 +1151,10 @@
  */
 
 #ifdef SUPPORT_JOYSTICK
-static snd_kcontrol_new_t snd_sonicvibes_game_control __devinitdata =
+static struct snd_kcontrol_new snd_sonicvibes_game_control __devinitdata =
 SONICVIBES_SINGLE("Joystick Speed", 0, SV_IREG_GAME_PORT, 1, 15, 0);
 
-static int __devinit snd_sonicvibes_create_gameport(sonicvibes_t *sonic)
+static int __devinit snd_sonicvibes_create_gameport(struct sonicvibes *sonic)
 {
 	struct gameport *gp;
 
@@ -1186,7 +1176,7 @@
 	return 0;
 }
 
-static void snd_sonicvibes_free_gameport(sonicvibes_t *sonic)
+static void snd_sonicvibes_free_gameport(struct sonicvibes *sonic)
 {
 	if (sonic->gameport) {
 		gameport_unregister_port(sonic->gameport);
@@ -1194,11 +1184,11 @@
 	}
 }
 #else
-static inline int snd_sonicvibes_create_gameport(sonicvibes_t *sonic) { return -ENOSYS; }
-static inline void snd_sonicvibes_free_gameport(sonicvibes_t *sonic) { }
+static inline int snd_sonicvibes_create_gameport(struct sonicvibes *sonic) { return -ENOSYS; }
+static inline void snd_sonicvibes_free_gameport(struct sonicvibes *sonic) { }
 #endif
 
-static int snd_sonicvibes_free(sonicvibes_t *sonic)
+static int snd_sonicvibes_free(struct sonicvibes *sonic)
 {
 	snd_sonicvibes_free_gameport(sonic);
 	pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port);
@@ -1213,22 +1203,22 @@
 	return 0;
 }
 
-static int snd_sonicvibes_dev_free(snd_device_t *device)
+static int snd_sonicvibes_dev_free(struct snd_device *device)
 {
-	sonicvibes_t *sonic = device->device_data;
+	struct sonicvibes *sonic = device->device_data;
 	return snd_sonicvibes_free(sonic);
 }
 
-static int __devinit snd_sonicvibes_create(snd_card_t * card,
+static int __devinit snd_sonicvibes_create(struct snd_card *card,
 					struct pci_dev *pci,
 					int reverb,
 					int mge,
-					sonicvibes_t ** rsonic)
+					struct sonicvibes ** rsonic)
 {
-	sonicvibes_t *sonic;
+	struct sonicvibes *sonic;
 	unsigned int dmaa, dmac;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_sonicvibes_dev_free,
 	};
 
@@ -1373,7 +1363,7 @@
  *  MIDI section
  */
 
-static snd_kcontrol_new_t snd_sonicvibes_midi_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_sonicvibes_midi_controls[] __devinitdata = {
 SONICVIBES_SINGLE("SonicVibes Wave Source RAM", 0, SV_IREG_WAVE_SOURCE, 0, 1, 0),
 SONICVIBES_SINGLE("SonicVibes Wave Source RAM+ROM", 0, SV_IREG_WAVE_SOURCE, 1, 1, 0),
 SONICVIBES_SINGLE("SonicVibes Onboard Synth", 0, SV_IREG_MPU401, 0, 1, 0),
@@ -1381,24 +1371,25 @@
 SONICVIBES_SINGLE("SonicVibes External Tx", 0, SV_IREG_MPU401, 2, 1, 0)
 };
 
-static int snd_sonicvibes_midi_input_open(mpu401_t * mpu)
+static int snd_sonicvibes_midi_input_open(struct snd_mpu401 * mpu)
 {
-	sonicvibes_t *sonic = mpu->private_data;
+	struct sonicvibes *sonic = mpu->private_data;
 	outb(sonic->irqmask &= ~SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
 	return 0;
 }
 
-static void snd_sonicvibes_midi_input_close(mpu401_t * mpu)
+static void snd_sonicvibes_midi_input_close(struct snd_mpu401 * mpu)
 {
-	sonicvibes_t *sonic = mpu->private_data;
+	struct sonicvibes *sonic = mpu->private_data;
 	outb(sonic->irqmask |= SV_MIDI_MASK, SV_REG(sonic, IRQMASK));
 }
 
-static int __devinit snd_sonicvibes_midi(sonicvibes_t * sonic, snd_rawmidi_t * rmidi)
+static int __devinit snd_sonicvibes_midi(struct sonicvibes * sonic,
+					 struct snd_rawmidi *rmidi)
 {
-	mpu401_t * mpu = rmidi->private_data;
-	snd_card_t *card = sonic->card;
-	snd_rawmidi_str_t *dir;
+	struct snd_mpu401 * mpu = rmidi->private_data;
+	struct snd_card *card = sonic->card;
+	struct snd_rawmidi_str *dir;
 	unsigned int idx;
 	int err;
 
@@ -1416,10 +1407,10 @@
 				     const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	sonicvibes_t *sonic;
-	snd_rawmidi_t *midi_uart;
-	opl3_t *opl3;
+	struct snd_card *card;
+	struct sonicvibes *sonic;
+	struct snd_rawmidi *midi_uart;
+	struct snd_opl3 *opl3;
 	int idx, err;
 
 	if (dev >= SNDRV_CARDS)
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 940d531..2b21df1 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -76,8 +76,8 @@
 				       const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
-	trident_t *trident;
+	struct snd_card *card;
+	struct snd_trident *trident;
 	const char *str;
 	int err, pcm_dev = 0;
 
@@ -100,6 +100,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = trident;
 
 	switch (trident->device) {
 	case TRIDENT_DEVICE_ID_DX:
@@ -180,7 +181,10 @@
 	.id_table = snd_trident_ids,
 	.probe = snd_trident_probe,
 	.remove = __devexit_p(snd_trident_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = snd_trident_suspend,
+	.resume = snd_trident_resume,
+#endif
 };
 
 static int __init alsa_card_trident_init(void)
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index b9b93c7..83b7d8a 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -44,17 +44,19 @@
 
 #include <asm/io.h>
 
-static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream);
-static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t * voice, snd_pcm_substream_t *substream);
-static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-#ifdef CONFIG_PM
-static int snd_trident_suspend(snd_card_t *card, pm_message_t state);
-static int snd_trident_resume(snd_card_t *card);
-#endif
-static int snd_trident_sis_reset(trident_t *trident);
+static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
+				       struct snd_trident_voice * voice,
+				       struct snd_pcm_substream *substream);
+static int snd_trident_pcm_mixer_free(struct snd_trident *trident,
+				      struct snd_trident_voice * voice,
+				      struct snd_pcm_substream *substream);
+static irqreturn_t snd_trident_interrupt(int irq, void *dev_id,
+					 struct pt_regs *regs);
+static int snd_trident_sis_reset(struct snd_trident *trident);
 
-static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max);
-static int snd_trident_free(trident_t *trident);
+static void snd_trident_clear_voices(struct snd_trident * trident,
+				     unsigned short v_min, unsigned short v_max);
+static int snd_trident_free(struct snd_trident *trident);
 
 /*
  *  common I/O routines
@@ -62,7 +64,7 @@
 
 
 #if 0
-static void snd_trident_print_voice_regs(trident_t *trident, int voice)
+static void snd_trident_print_voice_regs(struct snd_trident *trident, int voice)
 {
 	unsigned int val, tmp;
 
@@ -104,7 +106,7 @@
 #endif
 
 /*---------------------------------------------------------------------------
-   unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
+   unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
   
    Description: This routine will do all of the reading from the external
                 CODEC (AC97).
@@ -115,12 +117,12 @@
    returns:     16 bit value read from the AC97.
   
   ---------------------------------------------------------------------------*/
-static unsigned short snd_trident_codec_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_trident_codec_read(struct snd_ac97 *ac97, unsigned short reg)
 {
 	unsigned int data = 0, treg;
 	unsigned short count = 0xffff;
 	unsigned long flags;
-	trident_t *trident = ac97->private_data;
+	struct snd_trident *trident = ac97->private_data;
 
 	spin_lock_irqsave(&trident->reg_lock, flags);
 	if (trident->device == TRIDENT_DEVICE_ID_DX) {
@@ -153,7 +155,8 @@
 	}
 
 	if (count == 0 && !trident->ac97_detect) {
-		snd_printk(KERN_ERR "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n", reg, data);
+		snd_printk(KERN_ERR "ac97 codec read TIMEOUT [0x%x/0x%x]!!!\n",
+			   reg, data);
 		data = 0;
 	}
 
@@ -162,7 +165,8 @@
 }
 
 /*---------------------------------------------------------------------------
-   void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata)
+   void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
+   unsigned short wdata)
   
    Description: This routine will do all of the writing to the external
                 CODEC (AC97).
@@ -174,12 +178,13 @@
    returns:     TRUE if everything went ok, else FALSE.
   
   ---------------------------------------------------------------------------*/
-static void snd_trident_codec_write(ac97_t *ac97, unsigned short reg, unsigned short wdata)
+static void snd_trident_codec_write(struct snd_ac97 *ac97, unsigned short reg,
+				    unsigned short wdata)
 {
 	unsigned int address, data;
 	unsigned short count = 0xffff;
 	unsigned long flags;
-	trident_t *trident = ac97->private_data;
+	struct snd_trident *trident = ac97->private_data;
 
 	data = ((unsigned long) wdata) << 16;
 
@@ -230,7 +235,7 @@
 }
 
 /*---------------------------------------------------------------------------
-   void snd_trident_enable_eso(trident_t *trident)
+   void snd_trident_enable_eso(struct snd_trident *trident)
   
    Description: This routine will enable end of loop interrupts.
                 End of loop interrupts will occur when a running
@@ -241,7 +246,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_enable_eso(trident_t * trident)
+static void snd_trident_enable_eso(struct snd_trident * trident)
 {
 	unsigned int val;
 
@@ -254,7 +259,7 @@
 }
 
 /*---------------------------------------------------------------------------
-   void snd_trident_disable_eso(trident_t *trident)
+   void snd_trident_disable_eso(struct snd_trident *trident)
   
    Description: This routine will disable end of loop interrupts.
                 End of loop interrupts will occur when a running
@@ -268,7 +273,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_disable_eso(trident_t * trident)
+static void snd_trident_disable_eso(struct snd_trident * trident)
 {
 	unsigned int tmp;
 
@@ -279,7 +284,7 @@
 }
 
 /*---------------------------------------------------------------------------
-   void snd_trident_start_voice(trident_t * trident, unsigned int voice)
+   void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
 
     Description: Start a voice, any channel 0 thru 63.
                  This routine automatically handles the fact that there are
@@ -292,7 +297,7 @@
 
   ---------------------------------------------------------------------------*/
 
-void snd_trident_start_voice(trident_t * trident, unsigned int voice)
+void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice)
 {
 	unsigned int mask = 1 << (voice & 0x1f);
 	unsigned int reg = (voice & 0x20) ? T4D_START_B : T4D_START_A;
@@ -301,7 +306,7 @@
 }
 
 /*---------------------------------------------------------------------------
-   void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
+   void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
 
     Description: Stop a voice, any channel 0 thru 63.
                  This routine automatically handles the fact that there are
@@ -314,7 +319,7 @@
 
   ---------------------------------------------------------------------------*/
 
-void snd_trident_stop_voice(trident_t * trident, unsigned int voice)
+void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice)
 {
 	unsigned int mask = 1 << (voice & 0x1f);
 	unsigned int reg = (voice & 0x20) ? T4D_STOP_B : T4D_STOP_A;
@@ -323,7 +328,7 @@
 }
 
 /*---------------------------------------------------------------------------
-    int snd_trident_allocate_pcm_channel(trident_t *trident)
+    int snd_trident_allocate_pcm_channel(struct snd_trident *trident)
   
     Description: Allocate hardware channel in Bank B (32-63).
   
@@ -333,7 +338,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_allocate_pcm_channel(trident_t * trident)
+static int snd_trident_allocate_pcm_channel(struct snd_trident * trident)
 {
 	int idx;
 
@@ -361,7 +366,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_free_pcm_channel(trident_t *trident, int channel)
+static void snd_trident_free_pcm_channel(struct snd_trident *trident, int channel)
 {
 	if (channel < 32 || channel > 63)
 		return;
@@ -383,7 +388,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_allocate_synth_channel(trident_t * trident)
+static int snd_trident_allocate_synth_channel(struct snd_trident * trident)
 {
 	int idx;
 
@@ -409,7 +414,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_free_synth_channel(trident_t *trident, int channel)
+static void snd_trident_free_synth_channel(struct snd_trident *trident, int channel)
 {
 	if (channel < 0 || channel > 31)
 		return;
@@ -432,8 +437,8 @@
   
   ---------------------------------------------------------------------------*/
 
-void snd_trident_write_voice_regs(trident_t * trident,
-				  snd_trident_voice_t * voice)
+void snd_trident_write_voice_regs(struct snd_trident * trident,
+				  struct snd_trident_voice * voice)
 {
 	unsigned int FmcRvolCvol;
 	unsigned int regs[5];
@@ -452,14 +457,16 @@
 				(voice->Vol & 0x000003ff) :
 				((voice->Vol & 0x00003fc) << (16-2)) |
 				(voice->EC & 0x00000fff);
-		regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);
+		regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) |
+			(voice->FMS & 0x0000000f);
 		regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
 		regs[3] = (voice->Attribute << 16) | FmcRvolCvol;
 		break;
 	case TRIDENT_DEVICE_ID_DX:
 		regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
 			   (voice->EC & 0x00000fff);
-		regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) | (voice->FMS & 0x0000000f);
+		regs[0] = (voice->CSO << 16) | ((voice->Alpha & 0x00000fff) << 4) |
+			(voice->FMS & 0x0000000f);
 		regs[2] = (voice->ESO << 16) | (voice->Delta & 0x0ffff);
 		regs[3] = FmcRvolCvol;
 		break;
@@ -467,8 +474,10 @@
 		regs[4] |= ((voice->Vol & 0x000003fc) << (16-2)) |
 			   (voice->EC & 0x00000fff);
 		regs[0] = (voice->Delta << 24) | (voice->CSO & 0x00ffffff);
-		regs[2] = ((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff);
-		regs[3] = (voice->Alpha << 20) | ((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol;
+		regs[2] = ((voice->Delta << 16) & 0xff000000) |
+			(voice->ESO & 0x00ffffff);
+		regs[3] = (voice->Alpha << 20) |
+			((voice->FMS & 0x0000000f) << 16) | FmcRvolCvol;
 		break;
 	default:
 		snd_BUG();
@@ -504,14 +513,17 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_write_cso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CSO)
+static void snd_trident_write_cso_reg(struct snd_trident * trident,
+				      struct snd_trident_voice * voice,
+				      unsigned int CSO)
 {
 	voice->CSO = CSO;
 	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
 	if (trident->device != TRIDENT_DEVICE_ID_NX) {
 		outw(voice->CSO, TRID_REG(trident, CH_DX_CSO_ALPHA_FMS) + 2);
 	} else {
-		outl((voice->Delta << 24) | (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO));
+		outl((voice->Delta << 24) |
+		     (voice->CSO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_CSO));
 	}
 }
 
@@ -527,14 +539,17 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int ESO)
+static void snd_trident_write_eso_reg(struct snd_trident * trident,
+				      struct snd_trident_voice * voice,
+				      unsigned int ESO)
 {
 	voice->ESO = ESO;
 	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
 	if (trident->device != TRIDENT_DEVICE_ID_NX) {
 		outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2);
 	} else {
-		outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff), TRID_REG(trident, CH_NX_DELTA_ESO));
+		outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff),
+		     TRID_REG(trident, CH_NX_DELTA_ESO));
 	}
 }
 
@@ -550,7 +565,9 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_write_vol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Vol)
+static void snd_trident_write_vol_reg(struct snd_trident * trident,
+				      struct snd_trident_voice * voice,
+				      unsigned int Vol)
 {
 	voice->Vol = Vol;
 	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
@@ -561,7 +578,8 @@
 		break;
 	case TRIDENT_DEVICE_ID_SI7018:
 		// printk("voice->Vol = 0x%x\n", voice->Vol);
-		outw((voice->CTRL << 12) | voice->Vol, TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
+		outw((voice->CTRL << 12) | voice->Vol,
+		     TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC));
 		break;
 	}
 }
@@ -578,11 +596,14 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_write_pan_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int Pan)
+static void snd_trident_write_pan_reg(struct snd_trident * trident,
+				      struct snd_trident_voice * voice,
+				      unsigned int Pan)
 {
 	voice->Pan = Pan;
 	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
-	outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f), TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3));
+	outb(((voice->GVSel & 0x01) << 7) | (voice->Pan & 0x7f),
+	     TRID_REG(trident, CH_GVSEL_PAN_VOL_CTRL_EC + 3));
 }
 
 /*---------------------------------------------------------------------------
@@ -597,12 +618,16 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_write_rvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int RVol)
+static void snd_trident_write_rvol_reg(struct snd_trident * trident,
+				       struct snd_trident_voice * voice,
+				       unsigned int RVol)
 {
 	voice->RVol = RVol;
 	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
-	outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),
-	     TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
+	outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) |
+	     (voice->CVol & 0x007f),
+	     TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ?
+		      CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
 }
 
 /*---------------------------------------------------------------------------
@@ -617,12 +642,16 @@
   
   ---------------------------------------------------------------------------*/
 
-static void snd_trident_write_cvol_reg(trident_t * trident, snd_trident_voice_t * voice, unsigned int CVol)
+static void snd_trident_write_cvol_reg(struct snd_trident * trident,
+				       struct snd_trident_voice * voice,
+				       unsigned int CVol)
 {
 	voice->CVol = CVol;
 	outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
-	outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) | (voice->CVol & 0x007f),
-	     TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ? CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
+	outw(((voice->FMC & 0x0003) << 14) | ((voice->RVol & 0x007f) << 7) |
+	     (voice->CVol & 0x007f),
+	     TRID_REG(trident, trident->device == TRIDENT_DEVICE_ID_NX ?
+		      CH_NX_ALPHA_FMS_FMC_RVOL_CVOL : CH_DX_FMC_RVOL_CVOL));
 }
 
 /*---------------------------------------------------------------------------
@@ -696,7 +725,8 @@
    Returns:     Delta value.
   
   ---------------------------------------------------------------------------*/
-static unsigned int snd_trident_spurious_threshold(unsigned int rate, unsigned int period_size)
+static unsigned int snd_trident_spurious_threshold(unsigned int rate,
+						   unsigned int period_size)
 {
 	unsigned int res = (rate * period_size) / 48000;
 	if (res < 64)
@@ -717,10 +747,10 @@
    Returns:     Control value.
   
   ---------------------------------------------------------------------------*/
-static unsigned int snd_trident_control_mode(snd_pcm_substream_t *substream)
+static unsigned int snd_trident_control_mode(struct snd_pcm_substream *substream)
 {
 	unsigned int CTRL;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	/* set ctrl mode
 	   CTRL default: 8-bit (unsigned) mono, loop mode enabled
@@ -752,7 +782,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_ioctl(snd_pcm_substream_t * substream,
+static int snd_trident_ioctl(struct snd_pcm_substream *substream,
 			     unsigned int cmd,
 			     void *arg)
 {
@@ -774,12 +804,12 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_allocate_pcm_mem(snd_pcm_substream_t * substream,
-					snd_pcm_hw_params_t * hw_params)
+static int snd_trident_allocate_pcm_mem(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
 	int err;
 
 	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
@@ -808,13 +838,13 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_allocate_evoice(snd_pcm_substream_t * substream,
-				       snd_pcm_hw_params_t * hw_params)
+static int snd_trident_allocate_evoice(struct snd_pcm_substream *substream,
+				       struct snd_pcm_hw_params *hw_params)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
-	snd_trident_voice_t *evoice = voice->extra;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
+	struct snd_trident_voice *evoice = voice->extra;
 
 	/* voice management */
 
@@ -848,8 +878,8 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_trident_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
 	int err;
 
@@ -870,12 +900,12 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_hw_free(snd_pcm_substream_t * substream)
+static int snd_trident_hw_free(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
-	snd_trident_voice_t *evoice = voice ? voice->extra : NULL;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
+	struct snd_trident_voice *evoice = voice ? voice->extra : NULL;
 
 	if (trident->tlb.entries) {
 		if (voice && voice->memblk) {
@@ -902,13 +932,13 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_playback_prepare(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
-	snd_trident_voice_t *evoice = voice->extra;
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number];
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
+	struct snd_trident_voice *evoice = voice->extra;
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number];
 
 	spin_lock_irq(&trident->reg_lock);	
 
@@ -988,8 +1018,8 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_capture_hw_params(snd_pcm_substream_t * substream,
-					 snd_pcm_hw_params_t * hw_params)
+static int snd_trident_capture_hw_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
 {
 	return snd_trident_allocate_pcm_mem(substream, hw_params);
 }
@@ -1005,11 +1035,11 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_capture_prepare(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
 	unsigned int val, ESO_bytes;
 
 	spin_lock_irq(&trident->reg_lock);
@@ -1097,8 +1127,8 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_si7018_capture_hw_params(snd_pcm_substream_t * substream,
-						snd_pcm_hw_params_t * hw_params)
+static int snd_trident_si7018_capture_hw_params(struct snd_pcm_substream *substream,
+						struct snd_pcm_hw_params *hw_params)
 {
 	int err;
 
@@ -1119,12 +1149,12 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_si7018_capture_hw_free(snd_pcm_substream_t * substream)
+static int snd_trident_si7018_capture_hw_free(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
-	snd_trident_voice_t *evoice = voice ? voice->extra : NULL;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
+	struct snd_trident_voice *evoice = voice ? voice->extra : NULL;
 
 	snd_pcm_lib_free_pages(substream);
 	if (evoice != NULL) {
@@ -1145,12 +1175,12 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_si7018_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_si7018_capture_prepare(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
-	snd_trident_voice_t *evoice = voice->extra;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
+	struct snd_trident_voice *evoice = voice->extra;
 
 	spin_lock_irq(&trident->reg_lock);
 
@@ -1216,12 +1246,12 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_foldback_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_foldback_prepare(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
-	snd_trident_voice_t *evoice = voice->extra;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
+	struct snd_trident_voice *evoice = voice->extra;
 
 	spin_lock_irq(&trident->reg_lock);
 
@@ -1294,10 +1324,10 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_spdif_hw_params(snd_pcm_substream_t * substream,
-				       snd_pcm_hw_params_t * hw_params)
+static int snd_trident_spdif_hw_params(struct snd_pcm_substream *substream,
+				       struct snd_pcm_hw_params *hw_params)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
 	unsigned int old_bits = 0, change = 0;
 	int err;
 
@@ -1359,13 +1389,13 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_spdif_prepare(snd_pcm_substream_t * substream)
+static int snd_trident_spdif_prepare(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
-	snd_trident_voice_t *evoice = voice->extra;
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[substream->number];
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
+	struct snd_trident_voice *evoice = voice->extra;
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[substream->number];
 	unsigned int RESO, LBAO;
 	unsigned int temp;
 
@@ -1498,15 +1528,15 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_trigger(snd_pcm_substream_t *substream,
+static int snd_trident_trigger(struct snd_pcm_substream *substream,
 			       int cmd)
 				    
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
 	struct list_head *pos;
-	snd_pcm_substream_t *s;
+	struct snd_pcm_substream *s;
 	unsigned int what, whati, capture_flag, spdif_flag;
-	snd_trident_voice_t *voice, *evoice;
+	struct snd_trident_voice *voice, *evoice;
 	unsigned int val, go;
 
 	switch (cmd) {
@@ -1528,8 +1558,8 @@
 	val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff;
 	snd_pcm_group_for_each(pos, substream) {
 		s = snd_pcm_group_substream_entry(pos);
-		if ((trident_t *) snd_pcm_substream_chip(s) == trident) {
-			voice = (snd_trident_voice_t *) s->runtime->private_data;
+		if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) {
+			voice = s->runtime->private_data;
 			evoice = voice->extra;
 			what |= 1 << (voice->number & 0x1f);
 			if (evoice == NULL) {
@@ -1596,11 +1626,11 @@
   
   ---------------------------------------------------------------------------*/
 
-static snd_pcm_uframes_t snd_trident_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_trident_playback_pointer(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
 	unsigned int cso;
 
 	if (!voice->running)
@@ -1635,11 +1665,11 @@
   
   ---------------------------------------------------------------------------*/
 
-static snd_pcm_uframes_t snd_trident_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_trident_capture_pointer(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
 	unsigned int result;
 
 	if (!voice->running)
@@ -1665,11 +1695,11 @@
   
   ---------------------------------------------------------------------------*/
 
-static snd_pcm_uframes_t snd_trident_spdif_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_trident_spdif_pointer(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
 	unsigned int result;
 
 	if (!voice->running)
@@ -1684,7 +1714,7 @@
  *  Playback support device description
  */
 
-static snd_pcm_hardware_t snd_trident_playback =
+static struct snd_pcm_hardware snd_trident_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1709,7 +1739,7 @@
  *  Capture support device description
  */
 
-static snd_pcm_hardware_t snd_trident_capture =
+static struct snd_pcm_hardware snd_trident_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1734,7 +1764,7 @@
  *  Foldback capture support device description
  */
 
-static snd_pcm_hardware_t snd_trident_foldback =
+static struct snd_pcm_hardware snd_trident_foldback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1758,7 +1788,7 @@
  *  SPDIF playback support device description
  */
 
-static snd_pcm_hardware_t snd_trident_spdif =
+static struct snd_pcm_hardware snd_trident_spdif =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1779,7 +1809,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_trident_spdif_7018 =
+static struct snd_pcm_hardware snd_trident_spdif_7018 =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1799,10 +1829,10 @@
 	.fifo_size =		0,
 };
 
-static void snd_trident_pcm_free_substream(snd_pcm_runtime_t *runtime)
+static void snd_trident_pcm_free_substream(struct snd_pcm_runtime *runtime)
 {
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
-	trident_t *trident;
+	struct snd_trident_voice *voice = runtime->private_data;
+	struct snd_trident *trident;
 
 	if (voice) {
 		trident = voice->trident;
@@ -1810,11 +1840,11 @@
 	}
 }
 
-static int snd_trident_playback_open(snd_pcm_substream_t * substream)
+static int snd_trident_playback_open(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice;
 
 	voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
 	if (voice == NULL)
@@ -1838,11 +1868,11 @@
    Parameters:	substream  - PCM substream class
 
   ---------------------------------------------------------------------------*/
-static int snd_trident_playback_close(snd_pcm_substream_t * substream)
+static int snd_trident_playback_close(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_trident_voice *voice = runtime->private_data;
 
 	snd_trident_pcm_mixer_free(trident, voice, substream);
 	return 0;
@@ -1859,11 +1889,11 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_spdif_open(snd_pcm_substream_t * substream)
+static int snd_trident_spdif_open(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_trident_voice_t *voice;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_trident_voice *voice;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	
 	voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
 	if (voice == NULL)
@@ -1900,9 +1930,9 @@
 
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_spdif_close(snd_pcm_substream_t * substream)
+static int snd_trident_spdif_close(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
 	unsigned int temp;
 
 	spin_lock_irq(&trident->reg_lock);
@@ -1938,11 +1968,11 @@
 
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_capture_open(snd_pcm_substream_t * substream)
+static int snd_trident_capture_open(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_trident_voice_t *voice;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_trident_voice *voice;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
 	if (voice == NULL)
@@ -1966,7 +1996,7 @@
    Parameters:	substream  - PCM substream class
 
   ---------------------------------------------------------------------------*/
-static int snd_trident_capture_close(snd_pcm_substream_t * substream)
+static int snd_trident_capture_close(struct snd_pcm_substream *substream)
 {
 	return 0;
 }
@@ -1982,11 +2012,11 @@
 
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_foldback_open(snd_pcm_substream_t * substream)
+static int snd_trident_foldback_open(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_trident_voice_t *voice;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_trident_voice *voice;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	voice = snd_trident_alloc_voice(trident, SNDRV_TRIDENT_VOICE_TYPE_PCM, 0, 0);
 	if (voice == NULL)
@@ -2009,12 +2039,12 @@
    Parameters:	substream  - PCM substream class
 
   ---------------------------------------------------------------------------*/
-static int snd_trident_foldback_close(snd_pcm_substream_t * substream)
+static int snd_trident_foldback_close(struct snd_pcm_substream *substream)
 {
-	trident_t *trident = snd_pcm_substream_chip(substream);
-	snd_trident_voice_t *voice;
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	voice = (snd_trident_voice_t *) runtime->private_data;
+	struct snd_trident *trident = snd_pcm_substream_chip(substream);
+	struct snd_trident_voice *voice;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	voice = runtime->private_data;
 	
 	/* stop capture channel */
 	spin_lock_irq(&trident->reg_lock);
@@ -2027,7 +2057,7 @@
    PCM operations
   ---------------------------------------------------------------------------*/
 
-static snd_pcm_ops_t snd_trident_playback_ops = {
+static struct snd_pcm_ops snd_trident_playback_ops = {
 	.open =		snd_trident_playback_open,
 	.close =	snd_trident_playback_close,
 	.ioctl =	snd_trident_ioctl,
@@ -2038,7 +2068,7 @@
 	.pointer =	snd_trident_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_trident_nx_playback_ops = {
+static struct snd_pcm_ops snd_trident_nx_playback_ops = {
 	.open =		snd_trident_playback_open,
 	.close =	snd_trident_playback_close,
 	.ioctl =	snd_trident_ioctl,
@@ -2050,7 +2080,7 @@
 	.page =		snd_pcm_sgbuf_ops_page,
 };
 
-static snd_pcm_ops_t snd_trident_capture_ops = {
+static struct snd_pcm_ops snd_trident_capture_ops = {
 	.open =		snd_trident_capture_open,
 	.close =	snd_trident_capture_close,
 	.ioctl =	snd_trident_ioctl,
@@ -2061,7 +2091,7 @@
 	.pointer =	snd_trident_capture_pointer,
 };
 
-static snd_pcm_ops_t snd_trident_si7018_capture_ops = {
+static struct snd_pcm_ops snd_trident_si7018_capture_ops = {
 	.open =		snd_trident_capture_open,
 	.close =	snd_trident_capture_close,
 	.ioctl =	snd_trident_ioctl,
@@ -2072,7 +2102,7 @@
 	.pointer =	snd_trident_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_trident_foldback_ops = {
+static struct snd_pcm_ops snd_trident_foldback_ops = {
 	.open =		snd_trident_foldback_open,
 	.close =	snd_trident_foldback_close,
 	.ioctl =	snd_trident_ioctl,
@@ -2083,7 +2113,7 @@
 	.pointer =	snd_trident_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_trident_nx_foldback_ops = {
+static struct snd_pcm_ops snd_trident_nx_foldback_ops = {
 	.open =		snd_trident_foldback_open,
 	.close =	snd_trident_foldback_close,
 	.ioctl =	snd_trident_ioctl,
@@ -2095,7 +2125,7 @@
 	.page =		snd_pcm_sgbuf_ops_page,
 };
 
-static snd_pcm_ops_t snd_trident_spdif_ops = {
+static struct snd_pcm_ops snd_trident_spdif_ops = {
 	.open =		snd_trident_spdif_open,
 	.close =	snd_trident_spdif_close,
 	.ioctl =	snd_trident_ioctl,
@@ -2106,7 +2136,7 @@
 	.pointer =	snd_trident_spdif_pointer,
 };
 
-static snd_pcm_ops_t snd_trident_spdif_7018_ops = {
+static struct snd_pcm_ops snd_trident_spdif_7018_ops = {
 	.open =		snd_trident_spdif_open,
 	.close =	snd_trident_spdif_close,
 	.ioctl =	snd_trident_ioctl,
@@ -2118,37 +2148,6 @@
 };
 
 /*---------------------------------------------------------------------------
-   snd_trident_pcm_free
-  
-   Description: This routine release the 4DWave private data.
-                
-   Paramters:   private_data - pointer to 4DWave device info.
-
-   Returns:     None
-  
-  ---------------------------------------------------------------------------*/
-static void snd_trident_pcm_free(snd_pcm_t *pcm)
-{
-	trident_t *trident = pcm->private_data;
-	trident->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static void snd_trident_foldback_pcm_free(snd_pcm_t *pcm)
-{
-	trident_t *trident = pcm->private_data;
-	trident->foldback = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static void snd_trident_spdif_pcm_free(snd_pcm_t *pcm)
-{
-	trident_t *trident = pcm->private_data;
-	trident->spdif = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-/*---------------------------------------------------------------------------
    snd_trident_pcm
   
    Description: This routine registers the 4DWave device for PCM support.
@@ -2159,9 +2158,10 @@
   
   ---------------------------------------------------------------------------*/
 
-int __devinit snd_trident_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
+int __devinit snd_trident_pcm(struct snd_trident * trident,
+			      int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -2170,7 +2170,6 @@
 		return err;
 
 	pcm->private_data = trident;
-	pcm->private_free = snd_trident_pcm_free;
 
 	if (trident->tlb.entries) {
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_nx_playback_ops);
@@ -2188,7 +2187,7 @@
 	trident->pcm = pcm;
 
 	if (trident->tlb.entries) {
-		snd_pcm_substream_t *substream;
+		struct snd_pcm_substream *substream;
 		for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; substream; substream = substream->next)
 			snd_pcm_lib_preallocate_pages(substream, SNDRV_DMA_TYPE_DEV_SG,
 						      snd_dma_pci_data(trident->pci),
@@ -2217,12 +2216,13 @@
   
   ---------------------------------------------------------------------------*/
 
-int __devinit snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
+int __devinit snd_trident_foldback_pcm(struct snd_trident * trident,
+				       int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *foldback;
+	struct snd_pcm *foldback;
 	int err;
 	int num_chan = 3;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 
 	if (rpcm)
 		*rpcm = NULL;
@@ -2232,7 +2232,6 @@
 		return err;
 
 	foldback->private_data = trident;
-	foldback->private_free = snd_trident_foldback_pcm_free;
 	if (trident->tlb.entries)
 		snd_pcm_set_ops(foldback, SNDRV_PCM_STREAM_CAPTURE, &snd_trident_nx_foldback_ops);
 	else
@@ -2274,9 +2273,10 @@
   
   ---------------------------------------------------------------------------*/
 
-int __devinit snd_trident_spdif_pcm(trident_t * trident, int device, snd_pcm_t ** rpcm)
+int __devinit snd_trident_spdif_pcm(struct snd_trident * trident,
+				    int device, struct snd_pcm ** rpcm)
 {
-	snd_pcm_t *spdif;
+	struct snd_pcm *spdif;
 	int err;
 
 	if (rpcm)
@@ -2285,7 +2285,6 @@
 		return err;
 
 	spdif->private_data = trident;
-	spdif->private_free = snd_trident_spdif_pcm_free;
 	if (trident->device != TRIDENT_DEVICE_ID_SI7018) {
 		snd_pcm_set_ops(spdif, SNDRV_PCM_STREAM_PLAYBACK, &snd_trident_spdif_ops);
 	} else {
@@ -2313,7 +2312,8 @@
     Description: enable/disable S/PDIF out from ac97 mixer
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_spdif_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_spdif_control_info(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2322,10 +2322,10 @@
 	return 0;
 }
 
-static int snd_trident_spdif_control_get(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_control_get(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 	unsigned char val;
 
 	spin_lock_irq(&trident->reg_lock);
@@ -2335,10 +2335,10 @@
 	return 0;
 }
 
-static int snd_trident_spdif_control_put(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_control_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 	unsigned char val;
 	int change;
 
@@ -2366,7 +2366,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_trident_spdif_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_control __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
@@ -2382,17 +2382,18 @@
     Description: put/get the S/PDIF default settings
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_spdif_default_info(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_trident_spdif_default_get(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_default_get(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&trident->reg_lock);
 	ucontrol->value.iec958.status[0] = (trident->spdif_bits >> 0) & 0xff;
@@ -2403,10 +2404,10 @@
 	return 0;
 }
 
-static int snd_trident_spdif_default_put(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_default_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 
@@ -2428,7 +2429,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_trident_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_default __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -2443,15 +2444,16 @@
     Description: put/get the S/PDIF mask
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_spdif_mask_info(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_trident_spdif_mask_get(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_mask_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
 	ucontrol->value.iec958.status[0] = 0xff;
 	ucontrol->value.iec958.status[1] = 0xff;
@@ -2460,7 +2462,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_trident_spdif_mask __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_mask __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2475,17 +2477,18 @@
     Description: put/get the S/PDIF stream settings
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_spdif_stream_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_trident_spdif_stream_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_stream_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&trident->reg_lock);
 	ucontrol->value.iec958.status[0] = (trident->spdif_pcm_bits >> 0) & 0xff;
@@ -2496,10 +2499,10 @@
 	return 0;
 }
 
-static int snd_trident_spdif_stream_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_spdif_stream_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 
@@ -2521,7 +2524,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_trident_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_trident_spdif_stream __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -2537,7 +2540,8 @@
     Description: enable/disable rear path for ac97
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_ac97_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_ac97_control_info(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -2546,10 +2550,10 @@
 	return 0;
 }
 
-static int snd_trident_ac97_control_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_ac97_control_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 	unsigned char val;
 
 	spin_lock_irq(&trident->reg_lock);
@@ -2559,10 +2563,10 @@
 	return 0;
 }
 
-static int snd_trident_ac97_control_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_ac97_control_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 	unsigned char val;
 	int change = 0;
 
@@ -2578,7 +2582,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_trident_ac97_rear_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_ac97_rear_control __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Rear Path",
@@ -2594,7 +2598,8 @@
     Description: wave & music volume control
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_vol_control_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -2603,10 +2608,10 @@
 	return 0;
 }
 
-static int snd_trident_vol_control_get(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_vol_control_get(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 
 	val = trident->musicvol_wavevol;
@@ -2615,10 +2620,10 @@
 	return 0;
 }
 
-static int snd_trident_vol_control_put(snd_kcontrol_t * kcontrol,
-				       snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change = 0;
 
@@ -2633,7 +2638,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_trident_vol_music_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_vol_music_control __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Music Playback Volume",
@@ -2643,7 +2648,7 @@
 	.private_value = 16,
 };
 
-static snd_kcontrol_new_t snd_trident_vol_wave_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_vol_wave_control __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "Wave Playback Volume",
@@ -2659,9 +2664,10 @@
     Description: PCM front volume control
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_pcm_vol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_pcm_vol_control_info(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_info *uinfo)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
 
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -2672,11 +2678,11 @@
 	return 0;
 }
 
-static int snd_trident_pcm_vol_control_get(snd_kcontrol_t * kcontrol,
-					   snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_vol_control_get(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
 
 	if (trident->device == TRIDENT_DEVICE_ID_SI7018) {
 		ucontrol->value.integer.value[0] = 1023 - mix->vol;
@@ -2686,11 +2692,11 @@
 	return 0;
 }
 
-static int snd_trident_pcm_vol_control_put(snd_kcontrol_t * kcontrol,
-					   snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_vol_control_put(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
 	unsigned int val;
 	int change = 0;
 
@@ -2708,7 +2714,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_trident_pcm_vol_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_vol_control __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "PCM Front Playback Volume",
@@ -2725,7 +2731,8 @@
     Description: PCM front pan control
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_pcm_pan_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_pcm_pan_control_info(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -2734,11 +2741,11 @@
 	return 0;
 }
 
-static int snd_trident_pcm_pan_control_get(snd_kcontrol_t * kcontrol,
-					   snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_pan_control_get(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
 
 	ucontrol->value.integer.value[0] = mix->pan;
 	if (ucontrol->value.integer.value[0] & 0x40) {
@@ -2749,11 +2756,11 @@
 	return 0;
 }
 
-static int snd_trident_pcm_pan_control_put(snd_kcontrol_t * kcontrol,
-					   snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_pan_control_put(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
 	unsigned char val;
 	int change = 0;
 
@@ -2770,7 +2777,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_trident_pcm_pan_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_pan_control __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "PCM Pan Playback Control",
@@ -2787,7 +2794,8 @@
     Description: PCM reverb volume control
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_pcm_rvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_pcm_rvol_control_info(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -2796,21 +2804,21 @@
 	return 0;
 }
 
-static int snd_trident_pcm_rvol_control_get(snd_kcontrol_t * kcontrol,
-					    snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_rvol_control_get(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
 
 	ucontrol->value.integer.value[0] = 127 - mix->rvol;
 	return 0;
 }
 
-static int snd_trident_pcm_rvol_control_put(snd_kcontrol_t * kcontrol,
-					    snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
 	unsigned short val;
 	int change = 0;
 
@@ -2824,7 +2832,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_trident_pcm_rvol_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_rvol_control __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "PCM Reverb Playback Volume",
@@ -2841,7 +2849,8 @@
     Description: PCM chorus volume control
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_pcm_cvol_control_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_trident_pcm_cvol_control_info(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -2850,21 +2859,21 @@
 	return 0;
 }
 
-static int snd_trident_pcm_cvol_control_get(snd_kcontrol_t * kcontrol,
-					    snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_cvol_control_get(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
 
 	ucontrol->value.integer.value[0] = 127 - mix->cvol;
 	return 0;
 }
 
-static int snd_trident_pcm_cvol_control_put(snd_kcontrol_t * kcontrol,
-					    snd_ctl_elem_value_t * ucontrol)
+static int snd_trident_pcm_cvol_control_put(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	trident_t *trident = snd_kcontrol_chip(kcontrol);
-	snd_trident_pcm_mixer_t *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
+	struct snd_trident *trident = snd_kcontrol_chip(kcontrol);
+	struct snd_trident_pcm_mixer *mix = &trident->pcm_mixer[snd_ctl_get_ioffnum(kcontrol, &ucontrol->id)];
 	unsigned short val;
 	int change = 0;
 
@@ -2878,7 +2887,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_trident_pcm_cvol_control __devinitdata =
+static struct snd_kcontrol_new snd_trident_pcm_cvol_control __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =         "PCM Chorus Playback Volume",
@@ -2889,9 +2898,11 @@
 	.put =		snd_trident_pcm_cvol_control_put,
 };
 
-static void snd_trident_notify_pcm_change1(snd_card_t * card, snd_kcontrol_t *kctl, int num, int activate)
+static void snd_trident_notify_pcm_change1(struct snd_card *card,
+					   struct snd_kcontrol *kctl,
+					   int num, int activate)
 {
-	snd_ctl_elem_id_t id;
+	struct snd_ctl_elem_id id;
 
 	if (! kctl)
 		return;
@@ -2904,7 +2915,9 @@
 		       snd_ctl_build_ioff(&id, kctl, num));
 }
 
-static void snd_trident_notify_pcm_change(trident_t *trident, snd_trident_pcm_mixer_t *tmix, int num, int activate)
+static void snd_trident_notify_pcm_change(struct snd_trident *trident,
+					  struct snd_trident_pcm_mixer *tmix,
+					  int num, int activate)
 {
 	snd_trident_notify_pcm_change1(trident->card, trident->ctl_vol, num, activate);
 	snd_trident_notify_pcm_change1(trident->card, trident->ctl_pan, num, activate);
@@ -2912,9 +2925,11 @@
 	snd_trident_notify_pcm_change1(trident->card, trident->ctl_cvol, num, activate);
 }
 
-static int snd_trident_pcm_mixer_build(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream)
+static int snd_trident_pcm_mixer_build(struct snd_trident *trident,
+				       struct snd_trident_voice *voice,
+				       struct snd_pcm_substream *substream)
 {
-	snd_trident_pcm_mixer_t *tmix;
+	struct snd_trident_pcm_mixer *tmix;
 
 	snd_assert(trident != NULL && voice != NULL && substream != NULL, return -EINVAL);
 	tmix = &trident->pcm_mixer[substream->number];
@@ -2927,9 +2942,9 @@
 	return 0;
 }
 
-static int snd_trident_pcm_mixer_free(trident_t *trident, snd_trident_voice_t *voice, snd_pcm_substream_t *substream)
+static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_trident_voice *voice, struct snd_pcm_substream *substream)
 {
-	snd_trident_pcm_mixer_t *tmix;
+	struct snd_trident_pcm_mixer *tmix;
 
 	snd_assert(trident != NULL && substream != NULL, return -EINVAL);
 	tmix = &trident->pcm_mixer[substream->number];
@@ -2949,14 +2964,14 @@
   
   ---------------------------------------------------------------------------*/
 
-static int __devinit snd_trident_mixer(trident_t * trident, int pcm_spdif_device)
+static int __devinit snd_trident_mixer(struct snd_trident * trident, int pcm_spdif_device)
 {
-	ac97_template_t _ac97;
-	snd_card_t * card = trident->card;
-	snd_kcontrol_t *kctl;
-	snd_ctl_elem_value_t *uctl;
+	struct snd_ac97_template _ac97;
+	struct snd_card *card = trident->card;
+	struct snd_kcontrol *kctl;
+	struct snd_ctl_elem_value *uctl;
 	int idx, err, retries = 2;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_trident_codec_write,
 		.read = snd_trident_codec_read,
 	};
@@ -2993,7 +3008,7 @@
 			snd_printk(KERN_ERR "SI7018: the secondary codec - invalid access\n");
 #if 0	// only for my testing purpose --jk
 		{
-			ac97_t *mc97;
+			struct snd_ac97 *mc97;
 			err = snd_ac97_modem(trident->card, &_ac97, &mc97);
 			if (err < 0)
 				snd_printk(KERN_ERR "snd_ac97_modem returned error %i\n", err);
@@ -3016,7 +3031,7 @@
 	}
 
 	for (idx = 0; idx < 32; idx++) {
-		snd_trident_pcm_mixer_t *tmix;
+		struct snd_trident_pcm_mixer *tmix;
 		
 		tmix = &trident->pcm_mixer[idx];
 		tmix->voice = NULL;
@@ -3114,7 +3129,7 @@
 
 static unsigned char snd_trident_gameport_read(struct gameport *gameport)
 {
-	trident_t *chip = gameport_get_port_data(gameport);
+	struct snd_trident *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return 0);
 	return inb(TRID_REG(chip, GAMEPORT_LEGACY));
@@ -3122,7 +3137,7 @@
 
 static void snd_trident_gameport_trigger(struct gameport *gameport)
 {
-	trident_t *chip = gameport_get_port_data(gameport);
+	struct snd_trident *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return);
 	outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY));
@@ -3130,7 +3145,7 @@
 
 static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
 {
-	trident_t *chip = gameport_get_port_data(gameport);
+	struct snd_trident *chip = gameport_get_port_data(gameport);
 	int i;
 
 	snd_assert(chip, return 0);
@@ -3147,7 +3162,7 @@
 
 static int snd_trident_gameport_open(struct gameport *gameport, int mode)
 {
-	trident_t *chip = gameport_get_port_data(gameport);
+	struct snd_trident *chip = gameport_get_port_data(gameport);
 
 	snd_assert(chip, return 0);
 
@@ -3164,7 +3179,7 @@
 	}
 }
 
-int __devinit snd_trident_create_gameport(trident_t *chip)
+int __devinit snd_trident_create_gameport(struct snd_trident *chip)
 {
 	struct gameport *gp;
 
@@ -3190,7 +3205,7 @@
 	return 0;
 }
 
-static inline void snd_trident_free_gameport(trident_t *chip)
+static inline void snd_trident_free_gameport(struct snd_trident *chip)
 {
 	if (chip->gameport) {
 		gameport_unregister_port(chip->gameport);
@@ -3198,14 +3213,14 @@
 	}
 }
 #else
-int __devinit snd_trident_create_gameport(trident_t *chip) { return -ENOSYS; }
-static inline void snd_trident_free_gameport(trident_t *chip) { }
+int __devinit snd_trident_create_gameport(struct snd_trident *chip) { return -ENOSYS; }
+static inline void snd_trident_free_gameport(struct snd_trident *chip) { }
 #endif /* CONFIG_GAMEPORT */
 
 /*
  * delay for 1 tick
  */
-static inline void do_delay(trident_t *chip)
+static inline void do_delay(struct snd_trident *chip)
 {
 	schedule_timeout_uninterruptible(1);
 }
@@ -3214,7 +3229,7 @@
  *  SiS reset routine
  */
 
-static int snd_trident_sis_reset(trident_t *trident)
+static int snd_trident_sis_reset(struct snd_trident *trident)
 {
 	unsigned long end_time;
 	unsigned int i;
@@ -3267,10 +3282,10 @@
  *  /proc interface
  */
 
-static void snd_trident_proc_read(snd_info_entry_t *entry, 
-				  snd_info_buffer_t * buffer)
+static void snd_trident_proc_read(struct snd_info_entry *entry, 
+				  struct snd_info_buffer *buffer)
 {
-	trident_t *trident = entry->private_data;
+	struct snd_trident *trident = entry->private_data;
 	char *s;
 
 	switch (trident->device) {
@@ -3308,9 +3323,9 @@
 #endif
 }
 
-static void __devinit snd_trident_proc_init(trident_t * trident)
+static void __devinit snd_trident_proc_init(struct snd_trident * trident)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	const char *s = "trident";
 	
 	if (trident->device == TRIDENT_DEVICE_ID_SI7018)
@@ -3319,9 +3334,9 @@
 		snd_info_set_text_ops(entry, trident, 1024, snd_trident_proc_read);
 }
 
-static int snd_trident_dev_free(snd_device_t *device)
+static int snd_trident_dev_free(struct snd_device *device)
 {
-	trident_t *trident = device->device_data;
+	struct snd_trident *trident = device->device_data;
 	return snd_trident_free(trident);
 }
 
@@ -3337,7 +3352,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static int __devinit snd_trident_tlb_alloc(trident_t *trident)
+static int __devinit snd_trident_tlb_alloc(struct snd_trident *trident)
 {
 	int i;
 
@@ -3352,7 +3367,7 @@
 	trident->tlb.entries = (unsigned int*)(((unsigned long)trident->tlb.buffer.area + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1));
 	trident->tlb.entries_dmaaddr = (trident->tlb.buffer.addr + SNDRV_TRIDENT_MAX_PAGES * 4 - 1) & ~(SNDRV_TRIDENT_MAX_PAGES * 4 - 1);
 	/* allocate shadow TLB page table (virtual addresses) */
-	trident->tlb.shadow_entries = (unsigned long *)vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
+	trident->tlb.shadow_entries = vmalloc(SNDRV_TRIDENT_MAX_PAGES*sizeof(unsigned long));
 	if (trident->tlb.shadow_entries == NULL) {
 		snd_printk(KERN_ERR "trident: unable to allocate shadow TLB entries\n");
 		return -ENOMEM;
@@ -3374,7 +3389,7 @@
 	if (trident->tlb.memhdr == NULL)
 		return -ENOMEM;
 
-	trident->tlb.memhdr->block_extra_size = sizeof(snd_trident_memblk_arg_t);
+	trident->tlb.memhdr->block_extra_size = sizeof(struct snd_trident_memblk_arg);
 	return 0;
 }
 
@@ -3382,7 +3397,7 @@
  * initialize 4D DX chip
  */
 
-static void snd_trident_stop_all_voices(trident_t *trident)
+static void snd_trident_stop_all_voices(struct snd_trident *trident)
 {
 	outl(0xffffffff, TRID_REG(trident, T4D_STOP_A));
 	outl(0xffffffff, TRID_REG(trident, T4D_STOP_B));
@@ -3390,7 +3405,7 @@
 	outl(0, TRID_REG(trident, T4D_AINTEN_B));
 }
 
-static int snd_trident_4d_dx_init(trident_t *trident)
+static int snd_trident_4d_dx_init(struct snd_trident *trident)
 {
 	struct pci_dev *pci = trident->pci;
 	unsigned long end_time;
@@ -3430,7 +3445,7 @@
 /*
  * initialize 4D NX chip
  */
-static int snd_trident_4d_nx_init(trident_t *trident)
+static int snd_trident_4d_nx_init(struct snd_trident *trident)
 {
 	struct pci_dev *pci = trident->pci;
 	unsigned long end_time;
@@ -3487,7 +3502,7 @@
 /*
  * initialize sis7018 chip
  */
-static int snd_trident_sis_init(trident_t *trident)
+static int snd_trident_sis_init(struct snd_trident *trident)
 {
 	int err;
 
@@ -3518,18 +3533,18 @@
   
   ---------------------------------------------------------------------------*/
 
-int __devinit snd_trident_create(snd_card_t * card,
+int __devinit snd_trident_create(struct snd_card *card,
 		       struct pci_dev *pci,
 		       int pcm_streams,
 		       int pcm_spdif_device,
 		       int max_wavetable_size,
-		       trident_t ** rtrident)
+		       struct snd_trident ** rtrident)
 {
-	trident_t *trident;
+	struct snd_trident *trident;
 	int i, err;
-	snd_trident_voice_t *voice;
-	snd_trident_pcm_mixer_t *tmix;
-	static snd_device_ops_t ops = {
+	struct snd_trident_voice *voice;
+	struct snd_trident_pcm_mixer *tmix;
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_trident_dev_free,
 	};
 
@@ -3577,7 +3592,8 @@
 	}
 	trident->port = pci_resource_start(pci, 0);
 
-	if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ, "Trident Audio", (void *) trident)) {
+	if (request_irq(pci->irq, snd_trident_interrupt, SA_INTERRUPT|SA_SHIRQ,
+			"Trident Audio", trident)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_trident_free(trident);
 		return -EBUSY;
@@ -3641,8 +3657,6 @@
 
 	snd_trident_enable_eso(trident);
 
-	
-	snd_card_set_pm_callback(card, snd_trident_suspend, snd_trident_resume, trident);
 	snd_trident_proc_init(trident);
 	snd_card_set_dev(card, &pci->dev);
 	*rtrident = trident;
@@ -3661,7 +3675,7 @@
   
   ---------------------------------------------------------------------------*/
 
-static int snd_trident_free(trident_t *trident)
+static int snd_trident_free(struct snd_trident *trident)
 {
 	snd_trident_free_gameport(trident);
 	snd_trident_disable_eso(trident);
@@ -3681,7 +3695,7 @@
 		snd_dma_free_pages(&trident->tlb.buffer);
 	}
 	if (trident->irq >= 0)
-		free_irq(trident->irq, (void *)trident);
+		free_irq(trident->irq, trident);
 	pci_release_regions(trident->pci);
 	pci_disable_device(trident->pci);
 	kfree(trident);
@@ -3708,10 +3722,10 @@
 
 static irqreturn_t snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	trident_t *trident = dev_id;
+	struct snd_trident *trident = dev_id;
 	unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
 	int delta;
-	snd_trident_voice_t *voice;
+	struct snd_trident_voice *voice;
 
 	audio_int = inl(TRID_REG(trident, T4D_MISCINT));
 	if ((audio_int & (ADDRESS_IRQ|MPU401_IRQ)) == 0)
@@ -3813,21 +3827,21 @@
    Returns:     None.
   
   ---------------------------------------------------------------------------*/
-int snd_trident_attach_synthesizer(trident_t *trident)
+int snd_trident_attach_synthesizer(struct snd_trident *trident)
 {	
 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
 	if (snd_seq_device_new(trident->card, 1, SNDRV_SEQ_DEV_ID_TRIDENT,
-			       sizeof(trident_t*), &trident->seq_dev) >= 0) {
+			       sizeof(struct snd_trident *), &trident->seq_dev) >= 0) {
 		strcpy(trident->seq_dev->name, "4DWave");
-		*(trident_t**)SNDRV_SEQ_DEVICE_ARGPTR(trident->seq_dev) = trident;
+		*(struct snd_trident **)SNDRV_SEQ_DEVICE_ARGPTR(trident->seq_dev) = trident;
 	}
 #endif
 	return 0;
 }
 
-snd_trident_voice_t *snd_trident_alloc_voice(trident_t * trident, int type, int client, int port)
+struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type, int client, int port)
 {
-	snd_trident_voice_t *pvoice;
+	struct snd_trident_voice *pvoice;
 	unsigned long flags;
 	int idx;
 
@@ -3869,10 +3883,10 @@
 	return NULL;
 }
 
-void snd_trident_free_voice(trident_t * trident, snd_trident_voice_t *voice)
+void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice)
 {
 	unsigned long flags;
-	void (*private_free)(snd_trident_voice_t *);
+	void (*private_free)(struct snd_trident_voice *);
 	void *private_data;
 
 	if (voice == NULL || !voice->use)
@@ -3897,7 +3911,7 @@
 		private_free(voice);
 }
 
-static void snd_trident_clear_voices(trident_t * trident, unsigned short v_min, unsigned short v_max)
+static void snd_trident_clear_voices(struct snd_trident * trident, unsigned short v_min, unsigned short v_max)
 {
 	unsigned int i, val, mask[2] = { 0, 0 };
 
@@ -3918,20 +3932,19 @@
 }
 
 #ifdef CONFIG_PM
-static int snd_trident_suspend(snd_card_t *card, pm_message_t state)
+int snd_trident_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	trident_t *trident = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_trident *trident = card->private_data;
 
 	trident->in_suspend = 1;
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(trident->pcm);
-	if (trident->foldback)
-		snd_pcm_suspend_all(trident->foldback);
-	if (trident->spdif)
-		snd_pcm_suspend_all(trident->spdif);
+	snd_pcm_suspend_all(trident->foldback);
+	snd_pcm_suspend_all(trident->spdif);
 
 	snd_ac97_suspend(trident->ac97);
-	if (trident->ac97_sec)
-		snd_ac97_suspend(trident->ac97_sec);
+	snd_ac97_suspend(trident->ac97_sec);
 
 	switch (trident->device) {
 	case TRIDENT_DEVICE_ID_DX:
@@ -3940,19 +3953,19 @@
 	case TRIDENT_DEVICE_ID_SI7018:
 		break;
 	}
-	pci_disable_device(trident->pci);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int snd_trident_resume(snd_card_t *card)
+int snd_trident_resume(struct pci_dev *pci)
 {
-	trident_t *trident = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_trident *trident = card->private_data;
 
-	pci_enable_device(trident->pci);
-	if (pci_set_dma_mask(trident->pci, 0x3fffffff) < 0 ||
-	    pci_set_consistent_dma_mask(trident->pci, 0x3fffffff) < 0)
-		snd_printk(KERN_WARNING "trident: can't set the proper DMA mask\n");
-	pci_set_master(trident->pci); /* to be sure */
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci); /* to be sure */
 
 	switch (trident->device) {
 	case TRIDENT_DEVICE_ID_DX:
@@ -3967,14 +3980,14 @@
 	}
 
 	snd_ac97_resume(trident->ac97);
-	if (trident->ac97_sec)
-		snd_ac97_resume(trident->ac97_sec);
+	snd_ac97_resume(trident->ac97_sec);
 
 	/* restore some registers */
 	outl(trident->musicvol_wavevol, TRID_REG(trident, T4D_MUSICVOL_WAVEVOL));
 
 	snd_trident_enable_eso(trident);
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	trident->in_suspend = 0;
 	return 0;
 }
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index f3e6c54..cf09ea9 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -68,13 +68,14 @@
 #define page_to_addr(trident,page)	__tlb_to_addr(trident, (page) << 1)
 
 /* fill TLB entries -- we need to fill two entries */
-static inline void set_tlb_bus(trident_t *trident, int page, unsigned long ptr, dma_addr_t addr)
+static inline void set_tlb_bus(struct snd_trident *trident, int page,
+			       unsigned long ptr, dma_addr_t addr)
 {
 	page <<= 1;
 	__set_tlb_bus(trident, page, ptr, addr);
 	__set_tlb_bus(trident, page+1, ptr + SNDRV_TRIDENT_PAGE_SIZE, addr + SNDRV_TRIDENT_PAGE_SIZE);
 }
-static inline void set_silent_tlb(trident_t *trident, int page)
+static inline void set_silent_tlb(struct snd_trident *trident, int page)
 {
 	page <<= 1;
 	__set_tlb_bus(trident, page, (unsigned long)trident->tlb.silent_page.area, trident->tlb.silent_page.addr);
@@ -97,7 +98,8 @@
 #define page_to_addr(trident,page)	__tlb_to_addr(trident, (page) * UNIT_PAGES)
 
 /* fill TLB entries -- UNIT_PAGES entries must be filled */
-static inline void set_tlb_bus(trident_t *trident, int page, unsigned long ptr, dma_addr_t addr)
+static inline void set_tlb_bus(struct snd_trident *trident, int page,
+			       unsigned long ptr, dma_addr_t addr)
 {
 	int i;
 	page *= UNIT_PAGES;
@@ -107,7 +109,7 @@
 		addr += SNDRV_TRIDENT_PAGE_SIZE;
 	}
 }
-static inline void set_silent_tlb(trident_t *trident, int page)
+static inline void set_silent_tlb(struct snd_trident *trident, int page)
 {
 	int i;
 	page *= UNIT_PAGES;
@@ -118,7 +120,7 @@
 #endif /* PAGE_SIZE */
 
 /* calculate buffer pointer from offset address */
-static inline void *offset_ptr(trident_t *trident, int offset)
+static inline void *offset_ptr(struct snd_trident *trident, int offset)
 {
 	char *ptr;
 	ptr = page_to_ptr(trident, get_aligned_page(offset));
@@ -127,16 +129,16 @@
 }
 
 /* first and last (aligned) pages of memory block */
-#define firstpg(blk)	(((snd_trident_memblk_arg_t*)snd_util_memblk_argptr(blk))->first_page)
-#define lastpg(blk)	(((snd_trident_memblk_arg_t*)snd_util_memblk_argptr(blk))->last_page)
+#define firstpg(blk)	(((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->first_page)
+#define lastpg(blk)	(((struct snd_trident_memblk_arg *)snd_util_memblk_argptr(blk))->last_page)
 
 /*
  * search empty pages which may contain given size
  */
-static snd_util_memblk_t *
-search_empty(snd_util_memhdr_t *hdr, int size)
+static struct snd_util_memblk *
+search_empty(struct snd_util_memhdr *hdr, int size)
 {
-	snd_util_memblk_t *blk, *prev;
+	struct snd_util_memblk *blk, *prev;
 	int page, psize;
 	struct list_head *p;
 
@@ -144,7 +146,7 @@
 	prev = NULL;
 	page = 0;
 	list_for_each(p, &hdr->block) {
-		blk = list_entry(p, snd_util_memblk_t, list);
+		blk = list_entry(p, struct snd_util_memblk, list);
 		if (page + psize <= firstpg(blk))
 			goto __found_pages;
 		page = lastpg(blk) + 1;
@@ -183,12 +185,13 @@
 /*
  * page allocation for DMA (Scatter-Gather version)
  */
-static snd_util_memblk_t *
-snd_trident_alloc_sg_pages(trident_t *trident, snd_pcm_substream_t *substream)
+static struct snd_util_memblk *
+snd_trident_alloc_sg_pages(struct snd_trident *trident,
+			   struct snd_pcm_substream *substream)
 {
-	snd_util_memhdr_t *hdr;
-	snd_util_memblk_t *blk;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_util_memhdr *hdr;
+	struct snd_util_memblk *blk;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int idx, page;
 	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
 
@@ -230,13 +233,14 @@
 /*
  * page allocation for DMA (contiguous version)
  */
-static snd_util_memblk_t *
-snd_trident_alloc_cont_pages(trident_t *trident, snd_pcm_substream_t *substream)
+static struct snd_util_memblk *
+snd_trident_alloc_cont_pages(struct snd_trident *trident,
+			     struct snd_pcm_substream *substream)
 {
-	snd_util_memhdr_t *hdr;
-	snd_util_memblk_t *blk;
+	struct snd_util_memhdr *hdr;
+	struct snd_util_memblk *blk;
 	int page;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	dma_addr_t addr;
 	unsigned long ptr;
 
@@ -270,8 +274,9 @@
 /*
  * page allocation for DMA
  */
-snd_util_memblk_t *
-snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream)
+struct snd_util_memblk *
+snd_trident_alloc_pages(struct snd_trident *trident,
+			struct snd_pcm_substream *substream)
 {
 	snd_assert(trident != NULL, return NULL);
 	snd_assert(substream != NULL, return NULL);
@@ -285,9 +290,10 @@
 /*
  * release DMA buffer from page table
  */
-int snd_trident_free_pages(trident_t *trident, snd_util_memblk_t *blk)
+int snd_trident_free_pages(struct snd_trident *trident,
+			   struct snd_util_memblk *blk)
 {
-	snd_util_memhdr_t *hdr;
+	struct snd_util_memhdr *hdr;
 	int page;
 
 	snd_assert(trident != NULL, return -EINVAL);
@@ -314,17 +320,17 @@
 
 /*
  */
-static int synth_alloc_pages(trident_t *hw, snd_util_memblk_t *blk);
-static int synth_free_pages(trident_t *hw, snd_util_memblk_t *blk);
+static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk);
+static int synth_free_pages(struct snd_trident *hw, struct snd_util_memblk *blk);
 
 /*
  * allocate a synth sample area
  */
-snd_util_memblk_t *
-snd_trident_synth_alloc(trident_t *hw, unsigned int size)
+struct snd_util_memblk *
+snd_trident_synth_alloc(struct snd_trident *hw, unsigned int size)
 {
-	snd_util_memblk_t *blk;
-	snd_util_memhdr_t *hdr = hw->tlb.memhdr; 
+	struct snd_util_memblk *blk;
+	struct snd_util_memhdr *hdr = hw->tlb.memhdr; 
 
 	down(&hdr->block_mutex);
 	blk = __snd_util_mem_alloc(hdr, size);
@@ -346,9 +352,9 @@
  * free a synth sample area
  */
 int
-snd_trident_synth_free(trident_t *hw, snd_util_memblk_t *blk)
+snd_trident_synth_free(struct snd_trident *hw, struct snd_util_memblk *blk)
 {
-	snd_util_memhdr_t *hdr = hw->tlb.memhdr; 
+	struct snd_util_memhdr *hdr = hw->tlb.memhdr; 
 
 	down(&hdr->block_mutex);
 	synth_free_pages(hw, blk);
@@ -361,7 +367,7 @@
 /*
  * reset TLB entry and free kernel page
  */
-static void clear_tlb(trident_t *trident, int page)
+static void clear_tlb(struct snd_trident *trident, int page)
 {
 	void *ptr = page_to_ptr(trident, page);
 	dma_addr_t addr = page_to_addr(trident, page);
@@ -378,20 +384,22 @@
 }
 
 /* check new allocation range */
-static void get_single_page_range(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk, int *first_page_ret, int *last_page_ret)
+static void get_single_page_range(struct snd_util_memhdr *hdr,
+				  struct snd_util_memblk *blk,
+				  int *first_page_ret, int *last_page_ret)
 {
 	struct list_head *p;
-	snd_util_memblk_t *q;
+	struct snd_util_memblk *q;
 	int first_page, last_page;
 	first_page = firstpg(blk);
 	if ((p = blk->list.prev) != &hdr->block) {
-		q = list_entry(p, snd_util_memblk_t, list);
+		q = list_entry(p, struct snd_util_memblk, list);
 		if (lastpg(q) == first_page)
 			first_page++;  /* first page was already allocated */
 	}
 	last_page = lastpg(blk);
 	if ((p = blk->list.next) != &hdr->block) {
-		q = list_entry(p, snd_util_memblk_t, list);
+		q = list_entry(p, struct snd_util_memblk, list);
 		if (firstpg(q) == last_page)
 			last_page--; /* last page was already allocated */
 	}
@@ -402,7 +410,7 @@
 /*
  * allocate kernel pages and assign them to TLB
  */
-static int synth_alloc_pages(trident_t *hw, snd_util_memblk_t *blk)
+static int synth_alloc_pages(struct snd_trident *hw, struct snd_util_memblk *blk)
 {
 	int page, first_page, last_page;
 	struct snd_dma_buffer dmab;
@@ -438,7 +446,7 @@
 /*
  * free pages
  */
-static int synth_free_pages(trident_t *trident, snd_util_memblk_t *blk)
+static int synth_free_pages(struct snd_trident *trident, struct snd_util_memblk *blk)
 {
 	int page, first_page, last_page;
 
@@ -452,7 +460,9 @@
 /*
  * copy_from_user(blk + offset, data, size)
  */
-int snd_trident_synth_copy_from_user(trident_t *trident, snd_util_memblk_t *blk, int offset, const char __user *data, int size)
+int snd_trident_synth_copy_from_user(struct snd_trident *trident,
+				     struct snd_util_memblk *blk,
+				     int offset, const char __user *data, int size)
 {
 	int page, nextofs, end_offset, temp, temp1;
 
diff --git a/sound/pci/trident/trident_synth.c b/sound/pci/trident/trident_synth.c
index 5d5a719..cc7af8b 100644
--- a/sound/pci/trident/trident_synth.c
+++ b/sound/pci/trident/trident_synth.c
@@ -192,15 +192,15 @@
  * Sample handling operations
  */
 
-static void sample_start(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position);
-static void sample_stop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_stop_mode_t mode);
-static void sample_freq(trident_t * trident, snd_trident_voice_t * voice, snd_seq_frequency_t freq);
-static void sample_volume(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_volume_t * volume);
-static void sample_loop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_loop_t * loop);
-static void sample_pos(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position);
-static void sample_private1(trident_t * trident, snd_trident_voice_t * voice, unsigned char *data);
+static void sample_start(struct snd_trident * trident, struct snd_trident_voice * voice, snd_seq_position_t position);
+static void sample_stop(struct snd_trident * trident, struct snd_trident_voice * voice, int mode);
+static void sample_freq(struct snd_trident * trident, struct snd_trident_voice * voice, snd_seq_frequency_t freq);
+static void sample_volume(struct snd_trident * trident, struct snd_trident_voice * voice, struct snd_seq_ev_volume * volume);
+static void sample_loop(struct snd_trident * trident, struct snd_trident_voice * voice, struct snd_seq_ev_loop * loop);
+static void sample_pos(struct snd_trident * trident, struct snd_trident_voice * voice, snd_seq_position_t position);
+static void sample_private1(struct snd_trident * trident, struct snd_trident_voice * voice, unsigned char *data);
 
-static snd_trident_sample_ops_t sample_ops =
+static struct snd_trident_sample_ops sample_ops =
 {
 	sample_start,
 	sample_stop,
@@ -211,7 +211,7 @@
 	sample_private1
 };
 
-static void snd_trident_simple_init(snd_trident_voice_t * voice)
+static void snd_trident_simple_init(struct snd_trident_voice * voice)
 {
 	//voice->handler_wave = interrupt_wave;
 	//voice->handler_volume = interrupt_volume;
@@ -220,10 +220,10 @@
 	voice->sample_ops = &sample_ops;
 }
 
-static void sample_start(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position)
+static void sample_start(struct snd_trident * trident, struct snd_trident_voice * voice, snd_seq_position_t position)
 {
-	simple_instrument_t *simple;
-	snd_seq_kinstr_t *instr;
+	struct simple_instrument *simple;
+	struct snd_seq_kinstr *instr;
 	unsigned long flags;
 	unsigned int loop_start, loop_end, sample_start, sample_end, start_offset;
 	unsigned int value;
@@ -305,7 +305,7 @@
 	snd_seq_instr_free_use(trident->synth.ilist, instr);
 }
 
-static void sample_stop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_stop_mode_t mode)
+static void sample_stop(struct snd_trident * trident, struct snd_trident_voice * voice, int mode)
 {
 	unsigned long flags;
 
@@ -329,7 +329,7 @@
 	}
 }
 
-static void sample_freq(trident_t * trident, snd_trident_voice_t * voice, snd_seq_frequency_t freq)
+static void sample_freq(struct snd_trident * trident, struct snd_trident_voice * voice, snd_seq_frequency_t freq)
 {
 	unsigned long flags;
 	freq >>= 4;
@@ -355,7 +355,7 @@
 	spin_unlock_irqrestore(&trident->reg_lock, flags);
 }
 
-static void sample_volume(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_volume_t * volume)
+static void sample_volume(struct snd_trident * trident, struct snd_trident_voice * voice, struct snd_seq_ev_volume * volume)
 {
 	unsigned long flags;
 	unsigned short value;
@@ -407,11 +407,11 @@
 	spin_unlock_irqrestore(&trident->reg_lock, flags);
 }
 
-static void sample_loop(trident_t * trident, snd_trident_voice_t * voice, snd_seq_ev_loop_t * loop)
+static void sample_loop(struct snd_trident * trident, struct snd_trident_voice * voice, struct snd_seq_ev_loop * loop)
 {
 	unsigned long flags;
-	simple_instrument_t *simple;
-	snd_seq_kinstr_t *instr;
+	struct simple_instrument *simple;
+	struct snd_seq_kinstr *instr;
 	unsigned int loop_start, loop_end;
 
 	instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1);
@@ -446,11 +446,11 @@
 	snd_seq_instr_free_use(trident->synth.ilist, instr);
 }
 
-static void sample_pos(trident_t * trident, snd_trident_voice_t * voice, snd_seq_position_t position)
+static void sample_pos(struct snd_trident * trident, struct snd_trident_voice * voice, snd_seq_position_t position)
 {
 	unsigned long flags;
-	simple_instrument_t *simple;
-	snd_seq_kinstr_t *instr;
+	struct simple_instrument *simple;
+	struct snd_seq_kinstr *instr;
 	unsigned int value;
 
 	instr = snd_seq_instr_find(trident->synth.ilist, &voice->instr, 0, 1);
@@ -496,7 +496,7 @@
 	snd_seq_instr_free_use(trident->synth.ilist, instr);
 }
 
-static void sample_private1(trident_t * trident, snd_trident_voice_t * voice, unsigned char *data)
+static void sample_private1(struct snd_trident * trident, struct snd_trident_voice * voice, unsigned char *data)
 {
 }
 
@@ -504,10 +504,11 @@
  * Memory management / sample loading
  */
 
-static int snd_trident_simple_put_sample(void *private_data, simple_instrument_t * instr,
+static int snd_trident_simple_put_sample(void *private_data,
+					 struct simple_instrument * instr,
 					 char __user *data, long len, int atomic)
 {
-	trident_t *trident = private_data;
+	struct snd_trident *trident = private_data;
 	int size = instr->size;
 	int shift = 0;
 
@@ -529,7 +530,7 @@
 		return -EFAULT;
 
 	if (trident->tlb.entries) {
-		snd_util_memblk_t *memblk;
+		struct snd_util_memblk *memblk;
 		memblk = snd_trident_synth_alloc(trident, size); 
 		if (memblk == NULL)
 			return -ENOMEM;
@@ -557,10 +558,11 @@
 	return 0;
 }
 
-static int snd_trident_simple_get_sample(void *private_data, simple_instrument_t * instr,
+static int snd_trident_simple_get_sample(void *private_data,
+					 struct simple_instrument * instr,
 					 char __user *data, long len, int atomic)
 {
-	//trident_t *trident = private_data;
+	//struct snd_trident *trident = private_data;
 	int size = instr->size;
 	int shift = 0;
 
@@ -578,10 +580,11 @@
 	return -EBUSY;
 }
 
-static int snd_trident_simple_remove_sample(void *private_data, simple_instrument_t * instr,
+static int snd_trident_simple_remove_sample(void *private_data,
+					    struct simple_instrument * instr,
 					    int atomic)
 {
-	trident_t *trident = private_data;
+	struct snd_trident *trident = private_data;
 	int size = instr->size;
 
 	if (instr->format & SIMPLE_WAVE_16BIT)
@@ -590,7 +593,7 @@
 		size <<= 1;
 
 	if (trident->tlb.entries) {
-		snd_util_memblk_t *memblk = (snd_util_memblk_t*)instr->address.ptr;
+		struct snd_util_memblk *memblk = (struct snd_util_memblk *)instr->address.ptr;
 		if (memblk)
 			snd_trident_synth_free(trident, memblk);
 		else
@@ -612,9 +615,9 @@
 	return 0;
 }
 
-static void select_instrument(trident_t * trident, snd_trident_voice_t * v)
+static void select_instrument(struct snd_trident * trident, struct snd_trident_voice * v)
 {
-	snd_seq_kinstr_t *instr;
+	struct snd_seq_kinstr *instr;
 	instr = snd_seq_instr_find(trident->synth.ilist, &v->instr, 0, 1);
 	if (instr != NULL) {
 		if (instr->ops) {
@@ -629,7 +632,7 @@
 
  */
 
-static void event_sample(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
+static void event_sample(struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v)
 {
 	if (v->sample_ops && v->sample_ops->sample_stop)
 		v->sample_ops->sample_stop(p->trident, v, SAMPLE_STOP_IMMEDIATELY);
@@ -643,7 +646,7 @@
 	select_instrument(p->trident, v);
 }
 
-static void event_cluster(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
+static void event_cluster(struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v)
 {
 	if (v->sample_ops && v->sample_ops->sample_stop)
 		v->sample_ops->sample_stop(p->trident, v, SAMPLE_STOP_IMMEDIATELY);
@@ -651,49 +654,49 @@
 	select_instrument(p->trident, v);
 }
 
-static void event_start(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
+static void event_start(struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v)
 {
 	if (v->sample_ops && v->sample_ops->sample_start)
 		v->sample_ops->sample_start(p->trident, v, ev->data.sample.param.position);
 }
 
-static void event_stop(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
+static void event_stop(struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v)
 {
 	if (v->sample_ops && v->sample_ops->sample_stop)
 		v->sample_ops->sample_stop(p->trident, v, ev->data.sample.param.stop_mode);
 }
 
-static void event_freq(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
+static void event_freq(struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v)
 {
 	if (v->sample_ops && v->sample_ops->sample_freq)
 		v->sample_ops->sample_freq(p->trident, v, ev->data.sample.param.frequency);
 }
 
-static void event_volume(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
+static void event_volume(struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v)
 {
 	if (v->sample_ops && v->sample_ops->sample_volume)
 		v->sample_ops->sample_volume(p->trident, v, &ev->data.sample.param.volume);
 }
 
-static void event_loop(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
+static void event_loop(struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v)
 {
 	if (v->sample_ops && v->sample_ops->sample_loop)
 		v->sample_ops->sample_loop(p->trident, v, &ev->data.sample.param.loop);
 }
 
-static void event_position(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
+static void event_position(struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v)
 {
 	if (v->sample_ops && v->sample_ops->sample_pos)
 		v->sample_ops->sample_pos(p->trident, v, ev->data.sample.param.position);
 }
 
-static void event_private1(snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v)
+static void event_private1(struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v)
 {
 	if (v->sample_ops && v->sample_ops->sample_private1)
 		v->sample_ops->sample_private1(p->trident, v, (unsigned char *) &ev->data.sample.param.raw8);
 }
 
-typedef void (trident_sample_event_handler_t) (snd_seq_event_t * ev, snd_trident_port_t * p, snd_trident_voice_t * v);
+typedef void (trident_sample_event_handler_t) (struct snd_seq_event * ev, struct snd_trident_port * p, struct snd_trident_voice * v);
 
 static trident_sample_event_handler_t *trident_sample_event_handlers[9] =
 {
@@ -708,11 +711,11 @@
 	event_private1
 };
 
-static void snd_trident_sample_event(snd_seq_event_t * ev, snd_trident_port_t * p)
+static void snd_trident_sample_event(struct snd_seq_event * ev, struct snd_trident_port * p)
 {
 	int idx, voice;
-	trident_t *trident = p->trident;
-	snd_trident_voice_t *v;
+	struct snd_trident *trident = p->trident;
+	struct snd_trident_voice *v;
 	unsigned long flags;
 
 	idx = ev->type - SNDRV_SEQ_EVENT_SAMPLE;
@@ -735,10 +738,10 @@
 
  */
 
-static void snd_trident_synth_free_voices(trident_t * trident, int client, int port)
+static void snd_trident_synth_free_voices(struct snd_trident * trident, int client, int port)
 {
 	int idx;
-	snd_trident_voice_t *voice;
+	struct snd_trident_voice *voice;
 
 	for (idx = 0; idx < 32; idx++) {
 		voice = &trident->synth.voices[idx];
@@ -747,11 +750,11 @@
 	}
 }
 
-static int snd_trident_synth_use(void *private_data, snd_seq_port_subscribe_t * info)
+static int snd_trident_synth_use(void *private_data, struct snd_seq_port_subscribe * info)
 {
-	snd_trident_port_t *port = (snd_trident_port_t *) private_data;
-	trident_t *trident = port->trident;
-	snd_trident_voice_t *voice;
+	struct snd_trident_port *port = private_data;
+	struct snd_trident *trident = port->trident;
+	struct snd_trident_voice *voice;
 	unsigned int idx;
 	unsigned long flags;
 
@@ -786,10 +789,10 @@
 	return 0;
 }
 
-static int snd_trident_synth_unuse(void *private_data, snd_seq_port_subscribe_t * info)
+static int snd_trident_synth_unuse(void *private_data, struct snd_seq_port_subscribe * info)
 {
-	snd_trident_port_t *port = (snd_trident_port_t *) private_data;
-	trident_t *trident = port->trident;
+	struct snd_trident_port *port = private_data;
+	struct snd_trident *trident = port->trident;
 	unsigned long flags;
 
 	spin_lock_irqsave(&trident->reg_lock, flags);
@@ -802,18 +805,18 @@
 
  */
 
-static void snd_trident_synth_free_private_instruments(snd_trident_port_t * p, int client)
+static void snd_trident_synth_free_private_instruments(struct snd_trident_port * p, int client)
 {
-	snd_seq_instr_header_t ifree;
+	struct snd_seq_instr_header ifree;
 
 	memset(&ifree, 0, sizeof(ifree));
 	ifree.cmd = SNDRV_SEQ_INSTR_FREE_CMD_PRIVATE;
 	snd_seq_instr_list_free_cond(p->trident->synth.ilist, &ifree, client, 0);
 }
 
-static int snd_trident_synth_event_input(snd_seq_event_t * ev, int direct, void *private_data, int atomic, int hop)
+static int snd_trident_synth_event_input(struct snd_seq_event * ev, int direct, void *private_data, int atomic, int hop)
 {
-	snd_trident_port_t *p = (snd_trident_port_t *) private_data;
+	struct snd_trident_port *p = (struct snd_trident_port *) private_data;
 
 	if (p == NULL)
 		return -EINVAL;
@@ -841,12 +844,12 @@
 }
 
 static void snd_trident_synth_instr_notify(void *private_data,
-					   snd_seq_kinstr_t * instr,
+					   struct snd_seq_kinstr * instr,
 					   int what)
 {
 	int idx;
-	trident_t *trident = private_data;
-	snd_trident_voice_t *pvoice;
+	struct snd_trident *trident = private_data;
+	struct snd_trident_voice *pvoice;
 	unsigned long flags;
 
 	spin_lock_irqsave(&trident->event_lock, flags);
@@ -870,16 +873,16 @@
 
 static void snd_trident_synth_free_port(void *private_data)
 {
-	snd_trident_port_t *p = (snd_trident_port_t *) private_data;
+	struct snd_trident_port *p = (struct snd_trident_port *) private_data;
 
 	if (p)
 		snd_midi_channel_free_set(p->chset);
 }
 
-static int snd_trident_synth_create_port(trident_t * trident, int idx)
+static int snd_trident_synth_create_port(struct snd_trident * trident, int idx)
 {
-	snd_trident_port_t *p;
-	snd_seq_port_callback_t callbacks;
+	struct snd_trident_port *p;
+	struct snd_seq_port_callback callbacks;
 	char name[32];
 	char *str;
 	int result;
@@ -927,43 +930,31 @@
 
  */
 
-static int snd_trident_synth_new_device(snd_seq_device_t *dev)
+static int snd_trident_synth_new_device(struct snd_seq_device *dev)
 {
-	trident_t *trident;
+	struct snd_trident *trident;
 	int client, i;
-	snd_seq_client_callback_t callbacks;
-	snd_seq_client_info_t cinfo;
-	snd_seq_port_subscribe_t sub;
-	snd_simple_ops_t *simpleops;
+	struct snd_seq_port_subscribe sub;
+	struct snd_simple_ops *simpleops;
 	char *str;
 
-	trident = *(trident_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	trident = *(struct snd_trident **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	if (trident == NULL)
 		return -EINVAL;
 
 	trident->synth.seq_client = -1;
 
 	/* allocate new client */
-	memset(&callbacks, 0, sizeof(callbacks));
-	callbacks.private_data = trident;
-	callbacks.allow_output = callbacks.allow_input = 1;
-	client = trident->synth.seq_client =
-	    snd_seq_create_kernel_client(trident->card, 1, &callbacks);
-	if (client < 0)
-		return client;
-
-	/* change name of client */
-	memset(&cinfo, 0, sizeof(cinfo));
-	cinfo.client = client;
-	cinfo.type = KERNEL_CLIENT;
 	str = "???";
 	switch (trident->device) {
 	case TRIDENT_DEVICE_ID_DX:	str = "Trident 4DWave-DX"; break;
 	case TRIDENT_DEVICE_ID_NX:	str = "Trident 4DWave-NX"; break;
 	case TRIDENT_DEVICE_ID_SI7018:	str = "SiS 7018"; break;
 	}
-	sprintf(cinfo.name, str);
-	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
+	client = trident->synth.seq_client =
+		snd_seq_create_kernel_client(trident->card, 1, str);
+	if (client < 0)
+		return client;
 
 	for (i = 0; i < 4; i++)
 		snd_trident_synth_create_port(trident, i);
@@ -993,11 +984,11 @@
 	return 0;
 }
 
-static int snd_trident_synth_delete_device(snd_seq_device_t *dev)
+static int snd_trident_synth_delete_device(struct snd_seq_device *dev)
 {
-	trident_t *trident;
+	struct snd_trident *trident;
 
-	trident = *(trident_t **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
+	trident = *(struct snd_trident **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
 	if (trident == NULL)
 		return -EINVAL;
 
@@ -1012,14 +1003,14 @@
 
 static int __init alsa_trident_synth_init(void)
 {
-	static snd_seq_dev_ops_t ops =
+	static struct snd_seq_dev_ops ops =
 	{
 		snd_trident_synth_new_device,
 		snd_trident_synth_delete_device
 	};
 
 	return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_TRIDENT, &ops,
-					      sizeof(trident_t*));
+					      sizeof(struct snd_trident *));
 }
 
 static void __exit alsa_trident_synth_exit(void)
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index fad2a24..ed26a15 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -303,12 +303,6 @@
 
 
 /*
- */
-
-typedef struct _snd_via82xx via82xx_t;
-typedef struct via_dev viadev_t;
-
-/*
  * pcm stream
  */
 
@@ -319,11 +313,11 @@
 
 #define VIA_TABLE_SIZE	255
 
-struct via_dev {
+struct viadev {
 	unsigned int reg_offset;
 	unsigned long port;
 	int direction;	/* playback = 0, capture = 1 */
-        snd_pcm_substream_t *substream;
+        struct snd_pcm_substream *substream;
 	int running;
 	unsigned int tbl_entries; /* # descriptors */
 	struct snd_dma_buffer table;
@@ -350,7 +344,7 @@
 	int used;
 };
 
-struct _snd_via82xx {
+struct via82xx {
 	int irq;
 
 	unsigned long port;
@@ -374,27 +368,27 @@
 	unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
 
 	struct pci_dev *pci;
-	snd_card_t *card;
+	struct snd_card *card;
 
 	unsigned int num_devs;
 	unsigned int playback_devno, multi_devno, capture_devno;
-	viadev_t devs[VIA_MAX_DEVS];
+	struct viadev devs[VIA_MAX_DEVS];
 	struct via_rate_lock rates[2]; /* playback and capture */
 	unsigned int dxs_fixed: 1;	/* DXS channel accepts only 48kHz */
 	unsigned int no_vra: 1;		/* no need to set VRA on DXS channels */
 	unsigned int dxs_src: 1;	/* use full SRC capabilities of DXS */
 	unsigned int spdif_on: 1;	/* only spdif rates work to external DACs */
 
-	snd_pcm_t *pcms[2];
-	snd_rawmidi_t *rmidi;
+	struct snd_pcm *pcms[2];
+	struct snd_rawmidi *rmidi;
 
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97;
 	unsigned int ac97_clock;
 	unsigned int ac97_secondary;	/* secondary AC'97 codec is present */
 
 	spinlock_t reg_lock;
-	snd_info_entry_t *proc_entry;
+	struct snd_info_entry *proc_entry;
 
 #ifdef SUPPORT_JOYSTICK
 	struct gameport *gameport;
@@ -419,12 +413,12 @@
  * periods = number of periods
  * fragsize = period size in bytes
  */
-static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
+static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substream,
 			   struct pci_dev *pci,
 			   unsigned int periods, unsigned int fragsize)
 {
 	unsigned int i, idx, ofs, rest;
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
 	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
 
 	if (dev->table.area == NULL) {
@@ -487,7 +481,7 @@
 }
 
 
-static int clean_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
+static int clean_via_table(struct viadev *dev, struct snd_pcm_substream *substream,
 			   struct pci_dev *pci)
 {
 	if (dev->table.area) {
@@ -503,17 +497,17 @@
  *  Basic I/O
  */
 
-static inline unsigned int snd_via82xx_codec_xread(via82xx_t *chip)
+static inline unsigned int snd_via82xx_codec_xread(struct via82xx *chip)
 {
 	return inl(VIAREG(chip, AC97));
 }
  
-static inline void snd_via82xx_codec_xwrite(via82xx_t *chip, unsigned int val)
+static inline void snd_via82xx_codec_xwrite(struct via82xx *chip, unsigned int val)
 {
 	outl(val, VIAREG(chip, AC97));
 }
  
-static int snd_via82xx_codec_ready(via82xx_t *chip, int secondary)
+static int snd_via82xx_codec_ready(struct via82xx *chip, int secondary)
 {
 	unsigned int timeout = 1000;	/* 1ms */
 	unsigned int val;
@@ -523,11 +517,12 @@
 		if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
 			return val & 0xffff;
 	}
-	snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_via82xx_codec_xread(chip));
+	snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n",
+		   secondary, snd_via82xx_codec_xread(chip));
 	return -EIO;
 }
  
-static int snd_via82xx_codec_valid(via82xx_t *chip, int secondary)
+static int snd_via82xx_codec_valid(struct via82xx *chip, int secondary)
 {
 	unsigned int timeout = 1000;	/* 1ms */
 	unsigned int val, val1;
@@ -544,20 +539,20 @@
 	return -EIO;
 }
  
-static void snd_via82xx_codec_wait(ac97_t *ac97)
+static void snd_via82xx_codec_wait(struct snd_ac97 *ac97)
 {
-	via82xx_t *chip = ac97->private_data;
+	struct via82xx *chip = ac97->private_data;
 	int err;
 	err = snd_via82xx_codec_ready(chip, ac97->num);
 	/* here we need to wait fairly for long time.. */
 	msleep(500);
 }
 
-static void snd_via82xx_codec_write(ac97_t *ac97,
+static void snd_via82xx_codec_write(struct snd_ac97 *ac97,
 				    unsigned short reg,
 				    unsigned short val)
 {
-	via82xx_t *chip = ac97->private_data;
+	struct via82xx *chip = ac97->private_data;
 	unsigned int xval;
 
 	xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
@@ -568,9 +563,9 @@
 	snd_via82xx_codec_ready(chip, ac97->num);
 }
 
-static unsigned short snd_via82xx_codec_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_via82xx_codec_read(struct snd_ac97 *ac97, unsigned short reg)
 {
-	via82xx_t *chip = ac97->private_data;
+	struct via82xx *chip = ac97->private_data;
 	unsigned int xval, val = 0xffff;
 	int again = 0;
 
@@ -580,7 +575,8 @@
 	xval |= (reg & 0x7f) << VIA_REG_AC97_CMD_SHIFT;
       	while (1) {
       		if (again++ > 3) {
-			snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n", ac97->num, snd_via82xx_codec_xread(chip));
+			snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n",
+				   ac97->num, snd_via82xx_codec_xread(chip));
 		      	return 0xffff;
 		}
 		snd_via82xx_codec_xwrite(chip, xval);
@@ -594,7 +590,7 @@
 	return val & 0xffff;
 }
 
-static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
+static void snd_via82xx_channel_reset(struct via82xx *chip, struct viadev *viadev)
 {
 	outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET,
 	     VIADEV_REG(viadev, OFFSET_CONTROL));
@@ -617,7 +613,7 @@
  */
 static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	via82xx_t *chip = dev_id;
+	struct via82xx *chip = dev_id;
 	unsigned int status;
 	unsigned int i;
 
@@ -632,7 +628,7 @@
 	/* check status for each stream */
 	spin_lock(&chip->reg_lock);
 	for (i = 0; i < chip->num_devs; i++) {
-		viadev_t *viadev = &chip->devs[i];
+		struct viadev *viadev = &chip->devs[i];
 		unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
 		if (! (c_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED)))
 			continue;
@@ -663,7 +659,7 @@
  */
 static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	via82xx_t *chip = dev_id;
+	struct via82xx *chip = dev_id;
 	unsigned int status;
 	unsigned int i;
 	int irqreturn = 0;
@@ -673,8 +669,8 @@
 	status = inl(VIAREG(chip, SGD_SHADOW));
 
 	for (i = 0; i < chip->num_devs; i++) {
-		viadev_t *viadev = &chip->devs[i];
-		snd_pcm_substream_t *substream;
+		struct viadev *viadev = &chip->devs[i];
+		struct snd_pcm_substream *substream;
 		unsigned char c_status, shadow_status;
 
 		shadow_status = (status >> viadev->shadow_shift) &
@@ -719,10 +715,10 @@
 /*
  * trigger callback
  */
-static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_via82xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 	unsigned char val;
 
 	if (chip->chip_type != TYPE_VIA686)
@@ -766,9 +762,11 @@
  */
 
 #define check_invalid_pos(viadev,pos) \
-	((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))
+	((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 ||\
+				     viadev->lastpos < viadev->bufsize2))
 
-static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
+static inline unsigned int calc_linear_pos(struct viadev *viadev, unsigned int idx,
+					   unsigned int count)
 {
 	unsigned int size, base, res;
 
@@ -780,7 +778,8 @@
 
 	/* check the validity of the calculated position */
 	if (size < count) {
-		snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count);
+		snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n",
+			   (int)size, (int)count);
 		res = viadev->lastpos;
 	} else {
 		if (! count) {
@@ -796,12 +795,18 @@
 		}
 		if (check_invalid_pos(viadev, res)) {
 #ifdef POINTER_DEBUG
-			printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+			printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, "
+			       "bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, "
+			       "count = 0x%x\n", idx, viadev->tbl_entries,
+			       viadev->lastpos, viadev->bufsize2,
+			       viadev->idx_table[idx].offset,
+			       viadev->idx_table[idx].size, count);
 #endif
 			/* count register returns full size when end of buffer is reached */
 			res = base + size;
 			if (check_invalid_pos(viadev, res)) {
-				snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n");
+				snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), "
+					   "using last valid pointer\n");
 				res = viadev->lastpos;
 			}
 		}
@@ -812,10 +817,10 @@
 /*
  * get the current pointer on via686
  */
-static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 	unsigned int idx, ptr, count, res;
 
 	snd_assert(viadev->tbl_entries, return 0);
@@ -842,10 +847,10 @@
 /*
  * get the current pointer on via823x
  */
-static snd_pcm_uframes_t snd_via8233_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_via8233_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 	unsigned int idx, count, res;
 	int status;
 	
@@ -865,7 +870,8 @@
 		idx = count >> 24;
 		if (idx >= viadev->tbl_entries) {
 #ifdef POINTER_DEBUG
-			printk(KERN_DEBUG "fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
+			printk(KERN_DEBUG "fail: invalid idx = %i/%i\n", idx,
+			       viadev->tbl_entries);
 #endif
 			res = viadev->lastpos;
 		} else {
@@ -895,11 +901,11 @@
  * hw_params callback:
  * allocate the buffer and build up the buffer description table
  */
-static int snd_via82xx_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_via82xx_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 	int err;
 
 	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
@@ -918,10 +924,10 @@
  * hw_free callback:
  * clean up the buffer description table and release the buffer
  */
-static int snd_via82xx_hw_free(snd_pcm_substream_t * substream)
+static int snd_via82xx_hw_free(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 
 	clean_via_table(viadev, substream, chip->pci);
 	snd_pcm_lib_free_pages(substream);
@@ -932,7 +938,7 @@
 /*
  * set up the table pointer
  */
-static void snd_via82xx_set_table_ptr(via82xx_t *chip, viadev_t *viadev)
+static void snd_via82xx_set_table_ptr(struct via82xx *chip, struct viadev *viadev)
 {
 	snd_via82xx_codec_ready(chip, 0);
 	outl((u32)viadev->table.addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR));
@@ -943,7 +949,8 @@
 /*
  * prepare callback for playback and capture on via686
  */
-static void via686_setup_format(via82xx_t *chip, viadev_t *viadev, snd_pcm_runtime_t *runtime)
+static void via686_setup_format(struct via82xx *chip, struct viadev *viadev,
+				struct snd_pcm_runtime *runtime)
 {
 	snd_via82xx_channel_reset(chip, viadev);
 	/* this must be set after channel_reset */
@@ -956,11 +963,11 @@
 	     VIA_REG_TYPE_INT_FLAG, VIADEV_REG(viadev, OFFSET_TYPE));
 }
 
-static int snd_via686_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_via686_playback_prepare(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate);
 	snd_ac97_set_rate(chip->ac97, AC97_SPDIF, runtime->rate);
@@ -968,11 +975,11 @@
 	return 0;
 }
 
-static int snd_via686_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_via686_capture_prepare(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
 	via686_setup_format(chip, viadev, runtime);
@@ -1002,11 +1009,11 @@
 /*
  * prepare callback for DSX playback on via823x
  */
-static int snd_via8233_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_via8233_playback_prepare(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int ac97_rate = chip->dxs_src ? 48000 : runtime->rate;
 	int rate_changed;
 	u32 rbits;
@@ -1022,12 +1029,15 @@
 	if (runtime->rate == 48000)
 		rbits = 0xfffff;
 	else
-		rbits = (0x100000 / 48000) * runtime->rate + ((0x100000 % 48000) * runtime->rate) / 48000;
+		rbits = (0x100000 / 48000) * runtime->rate +
+			((0x100000 % 48000) * runtime->rate) / 48000;
 	snd_assert((rbits & ~0xfffff) == 0, return -EINVAL);
 	snd_via82xx_channel_reset(chip, viadev);
 	snd_via82xx_set_table_ptr(chip, viadev);
-	outb(chip->playback_volume[viadev->reg_offset / 0x10][0], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
-	outb(chip->playback_volume[viadev->reg_offset / 0x10][1], VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
+	outb(chip->playback_volume[viadev->reg_offset / 0x10][0],
+	     VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_L));
+	outb(chip->playback_volume[viadev->reg_offset / 0x10][1],
+	     VIADEV_REG(viadev, OFS_PLAYBACK_VOLUME_R));
 	outl((runtime->format == SNDRV_PCM_FORMAT_S16_LE ? VIA8233_REG_TYPE_16BIT : 0) | /* format */
 	     (runtime->channels > 1 ? VIA8233_REG_TYPE_STEREO : 0) | /* stereo */
 	     rbits | /* rate */
@@ -1041,11 +1051,11 @@
 /*
  * prepare callback for multi-channel playback on via823x
  */
-static int snd_via8233_multi_prepare(snd_pcm_substream_t *substream)
+static int snd_via8233_multi_prepare(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int slots;
 	int fmt;
 
@@ -1058,7 +1068,8 @@
 	snd_via82xx_channel_reset(chip, viadev);
 	snd_via82xx_set_table_ptr(chip, viadev);
 
-	fmt = (runtime->format == SNDRV_PCM_FORMAT_S16_LE) ? VIA_REG_MULTPLAY_FMT_16BIT : VIA_REG_MULTPLAY_FMT_8BIT;
+	fmt = (runtime->format == SNDRV_PCM_FORMAT_S16_LE) ?
+		VIA_REG_MULTPLAY_FMT_16BIT : VIA_REG_MULTPLAY_FMT_8BIT;
 	fmt |= runtime->channels << 4;
 	outb(fmt, VIADEV_REG(viadev, OFS_MULTPLAY_FORMAT));
 #if 0
@@ -1089,11 +1100,11 @@
 /*
  * prepare callback for capture on via823x
  */
-static int snd_via8233_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_via8233_capture_prepare(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	if (via_lock_rate(&chip->rates[1], runtime->rate) < 0)
 		return -EINVAL;
@@ -1114,7 +1125,7 @@
 /*
  * pcm hardware definition, identical for both playback and capture
  */
-static snd_pcm_hardware_t snd_via82xx_hw =
+static struct snd_pcm_hardware snd_via82xx_hw =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1139,9 +1150,10 @@
 /*
  * open callback skeleton
  */
-static int snd_via82xx_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_substream_t * substream)
+static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev,
+				struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 	struct via_rate_lock *ratep;
 
@@ -1191,10 +1203,10 @@
 /*
  * open callback for playback on via686 and via823x DSX
  */
-static int snd_via82xx_playback_open(snd_pcm_substream_t * substream)
+static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = &chip->devs[chip->playback_devno + substream->number];
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
 	int err;
 
 	if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
@@ -1205,10 +1217,10 @@
 /*
  * open callback for playback on via823x multi-channel
  */
-static int snd_via8233_multi_open(snd_pcm_substream_t * substream)
+static int snd_via8233_multi_open(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = &chip->devs[chip->multi_devno];
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = &chip->devs[chip->multi_devno];
 	int err;
 	/* channels constraint for VIA8233A
 	 * 3 and 5 channels are not supported
@@ -1216,7 +1228,7 @@
 	static unsigned int channels[] = {
 		1, 2, 4, 6
 	};
-	static snd_pcm_hw_constraint_list_t hw_constraints_channels = {
+	static struct snd_pcm_hw_constraint_list hw_constraints_channels = {
 		.count = ARRAY_SIZE(channels),
 		.list = channels,
 		.mask = 0,
@@ -1226,17 +1238,19 @@
 		return err;
 	substream->runtime->hw.channels_max = 6;
 	if (chip->revision == VIA_REV_8233A)
-		snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels);
+		snd_pcm_hw_constraint_list(substream->runtime, 0,
+					   SNDRV_PCM_HW_PARAM_CHANNELS,
+					   &hw_constraints_channels);
 	return 0;
 }
 
 /*
  * open callback for capture on via686 and via823x
  */
-static int snd_via82xx_capture_open(snd_pcm_substream_t * substream)
+static int snd_via82xx_capture_open(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
 
 	return snd_via82xx_pcm_open(chip, viadev, substream);
 }
@@ -1244,10 +1258,10 @@
 /*
  * close callback
  */
-static int snd_via82xx_pcm_close(snd_pcm_substream_t * substream)
+static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 	struct via_rate_lock *ratep;
 
 	/* release the rate lock */
@@ -1264,7 +1278,7 @@
 
 
 /* via686 playback callbacks */
-static snd_pcm_ops_t snd_via686_playback_ops = {
+static struct snd_pcm_ops snd_via686_playback_ops = {
 	.open =		snd_via82xx_playback_open,
 	.close =	snd_via82xx_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1277,7 +1291,7 @@
 };
 
 /* via686 capture callbacks */
-static snd_pcm_ops_t snd_via686_capture_ops = {
+static struct snd_pcm_ops snd_via686_capture_ops = {
 	.open =		snd_via82xx_capture_open,
 	.close =	snd_via82xx_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1290,7 +1304,7 @@
 };
 
 /* via823x DSX playback callbacks */
-static snd_pcm_ops_t snd_via8233_playback_ops = {
+static struct snd_pcm_ops snd_via8233_playback_ops = {
 	.open =		snd_via82xx_playback_open,
 	.close =	snd_via82xx_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1303,7 +1317,7 @@
 };
 
 /* via823x multi-channel playback callbacks */
-static snd_pcm_ops_t snd_via8233_multi_ops = {
+static struct snd_pcm_ops snd_via8233_multi_ops = {
 	.open =		snd_via8233_multi_open,
 	.close =	snd_via82xx_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1316,7 +1330,7 @@
 };
 
 /* via823x capture callbacks */
-static snd_pcm_ops_t snd_via8233_capture_ops = {
+static struct snd_pcm_ops snd_via8233_capture_ops = {
 	.open =		snd_via82xx_capture_open,
 	.close =	snd_via82xx_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1329,7 +1343,8 @@
 };
 
 
-static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int shadow_pos, int direction)
+static void init_viadev(struct via82xx *chip, int idx, unsigned int reg_offset,
+			int shadow_pos, int direction)
 {
 	chip->devs[idx].reg_offset = reg_offset;
 	chip->devs[idx].shadow_shift = shadow_pos * 4;
@@ -1340,9 +1355,9 @@
 /*
  * create pcm instances for VIA8233, 8233C and 8235 (not 8233A)
  */
-static int __devinit snd_via8233_pcm_new(via82xx_t *chip)
+static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int i, err;
 
 	chip->playback_devno = 0;	/* x 4 */
@@ -1367,7 +1382,8 @@
 	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
-							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
+							 snd_dma_pci_data(chip->pci),
+							 64*1024, 128*1024)) < 0)
 		return err;
 
 	/* PCM #1:  multi-channel playback and 2nd capture */
@@ -1385,7 +1401,8 @@
 	init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
-						         snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
+						         snd_dma_pci_data(chip->pci),
+							 64*1024, 128*1024)) < 0)
 		return err;
 
 	return 0;
@@ -1394,9 +1411,9 @@
 /*
  * create pcm instances for VIA8233A
  */
-static int __devinit snd_via8233a_pcm_new(via82xx_t *chip)
+static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	chip->multi_devno = 0;
@@ -1420,7 +1437,8 @@
 	init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
-							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
+							 snd_dma_pci_data(chip->pci),
+							 64*1024, 128*1024)) < 0)
 		return err;
 
 	/* SPDIF supported? */
@@ -1439,7 +1457,8 @@
 	init_viadev(chip, chip->playback_devno, 0x30, 3, 0);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
-							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
+							 snd_dma_pci_data(chip->pci),
+							 64*1024, 128*1024)) < 0)
 		return err;
 
 	return 0;
@@ -1448,9 +1467,9 @@
 /*
  * create a pcm instance for via686a/b
  */
-static int __devinit snd_via686_pcm_new(via82xx_t *chip)
+static int __devinit snd_via686_pcm_new(struct via82xx *chip)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	chip->playback_devno = 0;
@@ -1470,7 +1489,8 @@
 	init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
-							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
+							 snd_dma_pci_data(chip->pci),
+							 64*1024, 128*1024)) < 0)
 		return err;
 
 	return 0;
@@ -1481,7 +1501,8 @@
  *  Mixer part
  */
 
-static int snd_via8233_capture_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_via8233_capture_source_info(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_info *uinfo)
 {
 	/* formerly they were "Line" and "Mic", but it looks like that they
 	 * have nothing to do with the actual physical connections...
@@ -1498,17 +1519,19 @@
 	return 0;
 }
 
-static int snd_via8233_capture_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_via8233_capture_source_get(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
-	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct via82xx *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long port = chip->port + (kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL);
 	ucontrol->value.enumerated.item[0] = inb(port) & VIA_REG_CAPTURE_CHANNEL_MIC ? 1 : 0;
 	return 0;
 }
 
-static int snd_via8233_capture_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_via8233_capture_source_put(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_value *ucontrol)
 {
-	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct via82xx *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long port = chip->port + (kcontrol->id.index ? (VIA_REG_CAPTURE_CHANNEL + 0x10) : VIA_REG_CAPTURE_CHANNEL);
 	u8 val, oval;
 
@@ -1523,7 +1546,7 @@
 	return val != oval;
 }
 
-static snd_kcontrol_new_t snd_via8233_capture_source __devinitdata = {
+static struct snd_kcontrol_new snd_via8233_capture_source __devinitdata = {
 	.name = "Input Source Select",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_via8233_capture_source_info,
@@ -1531,7 +1554,8 @@
 	.put = snd_via8233_capture_source_put,
 };
 
-static int snd_via8233_dxs3_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_via8233_dxs3_spdif_info(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1540,9 +1564,10 @@
 	return 0;
 }
 
-static int snd_via8233_dxs3_spdif_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_via8233_dxs3_spdif_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct via82xx *chip = snd_kcontrol_chip(kcontrol);
 	u8 val;
 
 	pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &val);
@@ -1550,9 +1575,10 @@
 	return 0;
 }
 
-static int snd_via8233_dxs3_spdif_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_via8233_dxs3_spdif_put(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct via82xx *chip = snd_kcontrol_chip(kcontrol);
 	u8 val, oval;
 
 	pci_read_config_byte(chip->pci, VIA8233_SPDIF_CTRL, &oval);
@@ -1568,7 +1594,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_via8233_dxs3_spdif_control __devinitdata = {
+static struct snd_kcontrol_new snd_via8233_dxs3_spdif_control __devinitdata = {
 	.name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH),
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_via8233_dxs3_spdif_info,
@@ -1576,7 +1602,8 @@
 	.put = snd_via8233_dxs3_spdif_put,
 };
 
-static int snd_via8233_dxs_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_via8233_dxs_volume_info(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -1585,9 +1612,10 @@
 	return 0;
 }
 
-static int snd_via8233_dxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_via8233_dxs_volume_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct via82xx *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
 
 	ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
@@ -1595,17 +1623,19 @@
 	return 0;
 }
 
-static int snd_via8233_pcmdxs_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_via8233_pcmdxs_volume_get(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct via82xx *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[0];
 	ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume_c[1];
 	return 0;
 }
 
-static int snd_via8233_dxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_via8233_dxs_volume_put(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct via82xx *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id);
 	unsigned long port = chip->port + 0x10 * idx;
 	unsigned char val;
@@ -1625,9 +1655,10 @@
 	return change;
 }
 
-static int snd_via8233_pcmdxs_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_via8233_pcmdxs_volume_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	via82xx_t *chip = snd_kcontrol_chip(kcontrol);
+	struct via82xx *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int idx;
 	unsigned char val;
 	int i, change = 0;
@@ -1650,7 +1681,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_via8233_pcmdxs_volume_control __devinitdata = {
+static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = {
 	.name = "PCM Playback Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_via8233_dxs_volume_info,
@@ -1658,7 +1689,7 @@
 	.put = snd_via8233_pcmdxs_volume_put,
 };
 
-static snd_kcontrol_new_t snd_via8233_dxs_volume_control __devinitdata = {
+static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
 	.name = "VIA DXS Playback Volume",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.count = 4,
@@ -1670,15 +1701,15 @@
 /*
  */
 
-static void snd_via82xx_mixer_free_ac97_bus(ac97_bus_t *bus)
+static void snd_via82xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
 {
-	via82xx_t *chip = bus->private_data;
+	struct via82xx *chip = bus->private_data;
 	chip->ac97_bus = NULL;
 }
 
-static void snd_via82xx_mixer_free_ac97(ac97_t *ac97)
+static void snd_via82xx_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	via82xx_t *chip = ac97->private_data;
+	struct via82xx *chip = ac97->private_data;
 	chip->ac97 = NULL;
 }
 
@@ -1732,14 +1763,20 @@
 		.name = "Arima Notebook",
 		.type = AC97_TUNE_HP_ONLY,
 	},
+	{
+		.subvendor = 0x161f,
+		.subdevice = 0x2032,
+		.name = "Targa Traveller 811",
+		.type = AC97_TUNE_HP_ONLY,
+	},
 	{ } /* terminator */
 };
 
-static int __devinit snd_via82xx_mixer_new(via82xx_t *chip, const char *quirk_override)
+static int __devinit snd_via82xx_mixer_new(struct via82xx *chip, const char *quirk_override)
 {
-	ac97_template_t ac97;
+	struct snd_ac97_template ac97;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_via82xx_codec_write,
 		.read = snd_via82xx_codec_read,
 		.wait = snd_via82xx_codec_wait,
@@ -1770,7 +1807,7 @@
 
 #ifdef SUPPORT_JOYSTICK
 #define JOYSTICK_ADDR	0x200
-static int __devinit snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
+static int __devinit snd_via686_create_gameport(struct via82xx *chip, unsigned char *legacy)
 {
 	struct gameport *gp;
 	struct resource *r;
@@ -1780,7 +1817,8 @@
 
 	r = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport");
 	if (!r) {
-		printk(KERN_WARNING "via82xx: cannot reserve joystick port 0x%#x\n", JOYSTICK_ADDR);
+		printk(KERN_WARNING "via82xx: cannot reserve joystick port 0x%#x\n",
+		       JOYSTICK_ADDR);
 		return -EBUSY;
 	}
 
@@ -1806,7 +1844,7 @@
 	return 0;
 }
 
-static void snd_via686_free_gameport(via82xx_t *chip)
+static void snd_via686_free_gameport(struct via82xx *chip)
 {
 	if (chip->gameport) {
 		struct resource *r = gameport_get_port_data(chip->gameport);
@@ -1817,11 +1855,11 @@
 	}
 }
 #else
-static inline int snd_via686_create_gameport(via82xx_t *chip, unsigned char *legacy)
+static inline int snd_via686_create_gameport(struct via82xx *chip, unsigned char *legacy)
 {
 	return -ENOSYS;
 }
-static inline void snd_via686_free_gameport(via82xx_t *chip) { }
+static inline void snd_via686_free_gameport(struct via82xx *chip) { }
 #endif
 
 
@@ -1829,7 +1867,7 @@
  *
  */
 
-static int __devinit snd_via8233_init_misc(via82xx_t *chip)
+static int __devinit snd_via8233_init_misc(struct via82xx *chip)
 {
 	int i, err, caps;
 	unsigned char val;
@@ -1850,7 +1888,7 @@
 		/* when no h/w PCM volume control is found, use DXS volume control
 		 * as the PCM vol control
 		 */
-		snd_ctl_elem_id_t sid;
+		struct snd_ctl_elem_id sid;
 		memset(&sid, 0, sizeof(sid));
 		strcpy(sid.name, "PCM Playback Volume");
 		sid.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
@@ -1877,7 +1915,7 @@
 	return 0;
 }
 
-static int __devinit snd_via686_init_misc(via82xx_t *chip)
+static int __devinit snd_via686_init_misc(struct via82xx *chip)
 {
 	unsigned char legacy, legacy_cfg;
 	int rev_h = 0;
@@ -1954,9 +1992,10 @@
 /*
  * proc interface
  */
-static void snd_via82xx_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_via82xx_proc_read(struct snd_info_entry *entry,
+				  struct snd_info_buffer *buffer)
 {
-	via82xx_t *chip = entry->private_data;
+	struct via82xx *chip = entry->private_data;
 	int i;
 	
 	snd_iprintf(buffer, "%s\n\n", chip->card->longname);
@@ -1965,9 +2004,9 @@
 	}
 }
 
-static void __devinit snd_via82xx_proc_init(via82xx_t *chip)
+static void __devinit snd_via82xx_proc_init(struct via82xx *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(chip->card, "via82xx", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read);
@@ -1977,7 +2016,7 @@
  *
  */
 
-static int snd_via82xx_chip_init(via82xx_t *chip)
+static int snd_via82xx_chip_init(struct via82xx *chip)
 {
 	unsigned int val;
 	unsigned long end_time;
@@ -2080,7 +2119,8 @@
 			unsigned long port = chip->port + 0x10 * idx;
 			for (i = 0; i < 2; i++) {
 				chip->playback_volume[idx][i]=chip->playback_volume_c[i];
-				outb(chip->playback_volume_c[i], port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
+				outb(chip->playback_volume_c[i],
+				     port + VIA_REG_OFS_PLAYBACK_VOLUME_L + i);
 			}
 		}
 	}
@@ -2092,14 +2132,15 @@
 /*
  * power management
  */
-static int snd_via82xx_suspend(snd_card_t *card, pm_message_t state)
+static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	via82xx_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct via82xx *chip = card->private_data;
 	int i;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	for (i = 0; i < 2; i++)
-		if (chip->pcms[i])
-			snd_pcm_suspend_all(chip->pcms[i]);
+		snd_pcm_suspend_all(chip->pcms[i]);
 	for (i = 0; i < chip->num_devs; i++)
 		snd_via82xx_channel_reset(chip, &chip->devs[i]);
 	synchronize_irq(chip->irq);
@@ -2112,18 +2153,21 @@
 		chip->capture_src_saved[1] = inb(chip->port + VIA_REG_CAPTURE_CHANNEL + 0x10);
 	}
 
-	pci_set_power_state(chip->pci, 3);
-	pci_disable_device(chip->pci);
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int snd_via82xx_resume(snd_card_t *card)
+static int snd_via82xx_resume(struct pci_dev *pci)
 {
-	via82xx_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct via82xx *chip = card->private_data;
 	int i;
 
-	pci_enable_device(chip->pci);
-	pci_set_power_state(chip->pci, 0);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
 
 	snd_via82xx_chip_init(chip);
 
@@ -2143,11 +2187,12 @@
 	for (i = 0; i < chip->num_devs; i++)
 		snd_via82xx_channel_reset(chip, &chip->devs[i]);
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
-static int snd_via82xx_free(via82xx_t *chip)
+static int snd_via82xx_free(struct via82xx *chip)
 {
 	unsigned int i;
 
@@ -2159,7 +2204,7 @@
 	synchronize_irq(chip->irq);
       __end_hw:
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	release_and_free_resource(chip->mpu_res);
 	pci_release_regions(chip->pci);
 
@@ -2173,22 +2218,22 @@
 	return 0;
 }
 
-static int snd_via82xx_dev_free(snd_device_t *device)
+static int snd_via82xx_dev_free(struct snd_device *device)
 {
-	via82xx_t *chip = device->device_data;
+	struct via82xx *chip = device->device_data;
 	return snd_via82xx_free(chip);
 }
 
-static int __devinit snd_via82xx_create(snd_card_t * card,
+static int __devinit snd_via82xx_create(struct snd_card *card,
 					struct pci_dev *pci,
 					int chip_type,
 					int revision,
 					unsigned int ac97_clock,
-					via82xx_t ** r_via)
+					struct via82xx ** r_via)
 {
-	via82xx_t *chip;
+	struct via82xx *chip;
 	int err;
-        static snd_device_ops_t ops = {
+        static struct snd_device_ops ops = {
 		.dev_free =	snd_via82xx_dev_free,
         };
 
@@ -2225,7 +2270,7 @@
 			chip_type == TYPE_VIA8233 ?
 			snd_via8233_interrupt :	snd_via686_interrupt,
 			SA_INTERRUPT|SA_SHIRQ,
-			card->driver, (void *)chip)) {
+			card->driver, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
 		return -EBUSY;
@@ -2307,6 +2352,7 @@
 		{ .subvendor = 0x1458, .subdevice = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
 		{ .subvendor = 0x1462, .subdevice = 0x0080, .action = VIA_DXS_SRC }, /* MSI K8T Neo-FIS2R */
 		{ .subvendor = 0x1462, .subdevice = 0x0430, .action = VIA_DXS_SRC }, /* MSI 7142 (K8MM-V) */
+		{ .subvendor = 0x1462, .subdevice = 0x0470, .action = VIA_DXS_SRC }, /* MSI KT880 Delta-FSR */
 		{ .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
 		{ .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
 		{ .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_NO_VRA }, /* MSI K8T Neo2-FI */
@@ -2326,6 +2372,7 @@
 		{ .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */
 		{ .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */
 		{ .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */
+		{ .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */
 		{ .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */
 		{ .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC },	/* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */
 		{ } /* terminator */
@@ -2362,8 +2409,8 @@
 static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 				       const struct pci_device_id *pci_id)
 {
-	snd_card_t *card;
-	via82xx_t *chip;
+	struct snd_card *card;
+	struct via82xx *chip;
 	unsigned char revision;
 	int chip_type = 0, card_type;
 	unsigned int i;
@@ -2418,6 +2465,7 @@
 	if ((err = snd_via82xx_create(card, pci, chip_type, revision,
 				      ac97_clock, &chip)) < 0)
 		goto __error;
+	card->private_data = chip;
 	if ((err = snd_via82xx_mixer_new(chip, ac97_quirk)) < 0)
 		goto __error;
 
@@ -2446,8 +2494,6 @@
 			goto __error;
 	}
 
-	snd_card_set_pm_callback(card, snd_via82xx_suspend, snd_via82xx_resume, chip);
-
 	/* disable interrupts */
 	for (i = 0; i < chip->num_devs; i++)
 		snd_via82xx_channel_reset(chip, &chip->devs[i]);
@@ -2481,7 +2527,10 @@
 	.id_table = snd_via82xx_ids,
 	.probe = snd_via82xx_probe,
 	.remove = __devexit_p(snd_via82xx_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = snd_via82xx_suspend,
+	.resume = snd_via82xx_resume,
+#endif
 };
 
 static int __init alsa_card_via82xx_init(void)
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index b83660b..22ce4d3 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -206,9 +206,6 @@
                                  VIA_MC97_CTRL_SECONDARY)
 
 
-typedef struct _snd_via82xx_modem via82xx_t;
-typedef struct via_dev viadev_t;
-
 /*
  * pcm stream
  */
@@ -220,11 +217,11 @@
 
 #define VIA_TABLE_SIZE	255
 
-struct via_dev {
+struct viadev {
 	unsigned int reg_offset;
 	unsigned long port;
 	int direction;	/* playback = 0, capture = 1 */
-        snd_pcm_substream_t *substream;
+        struct snd_pcm_substream *substream;
 	int running;
 	unsigned int tbl_entries; /* # descriptors */
 	struct snd_dma_buffer table;
@@ -239,7 +236,7 @@
 
 #define VIA_MAX_MODEM_DEVS	2
 
-struct _snd_via82xx_modem {
+struct via82xx_modem {
 	int irq;
 
 	unsigned long port;
@@ -247,21 +244,21 @@
 	unsigned int intr_mask; /* SGD_SHADOW mask to check interrupts */
 
 	struct pci_dev *pci;
-	snd_card_t *card;
+	struct snd_card *card;
 
 	unsigned int num_devs;
 	unsigned int playback_devno, capture_devno;
-	viadev_t devs[VIA_MAX_MODEM_DEVS];
+	struct viadev devs[VIA_MAX_MODEM_DEVS];
 
-	snd_pcm_t *pcms[2];
+	struct snd_pcm *pcms[2];
 
-	ac97_bus_t *ac97_bus;
-	ac97_t *ac97;
+	struct snd_ac97_bus *ac97_bus;
+	struct snd_ac97 *ac97;
 	unsigned int ac97_clock;
 	unsigned int ac97_secondary;	/* secondary AC'97 codec is present */
 
 	spinlock_t reg_lock;
-	snd_info_entry_t *proc_entry;
+	struct snd_info_entry *proc_entry;
 };
 
 static struct pci_device_id snd_via82xx_modem_ids[] = {
@@ -279,12 +276,12 @@
  * periods = number of periods
  * fragsize = period size in bytes
  */
-static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
+static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substream,
 			   struct pci_dev *pci,
 			   unsigned int periods, unsigned int fragsize)
 {
 	unsigned int i, idx, ofs, rest;
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
+	struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
 	struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
 
 	if (dev->table.area == NULL) {
@@ -346,7 +343,7 @@
 }
 
 
-static int clean_via_table(viadev_t *dev, snd_pcm_substream_t *substream,
+static int clean_via_table(struct viadev *dev, struct snd_pcm_substream *substream,
 			   struct pci_dev *pci)
 {
 	if (dev->table.area) {
@@ -362,17 +359,17 @@
  *  Basic I/O
  */
 
-static inline unsigned int snd_via82xx_codec_xread(via82xx_t *chip)
+static inline unsigned int snd_via82xx_codec_xread(struct via82xx_modem *chip)
 {
 	return inl(VIAREG(chip, AC97));
 }
  
-static inline void snd_via82xx_codec_xwrite(via82xx_t *chip, unsigned int val)
+static inline void snd_via82xx_codec_xwrite(struct via82xx_modem *chip, unsigned int val)
 {
 	outl(val, VIAREG(chip, AC97));
 }
  
-static int snd_via82xx_codec_ready(via82xx_t *chip, int secondary)
+static int snd_via82xx_codec_ready(struct via82xx_modem *chip, int secondary)
 {
 	unsigned int timeout = 1000;	/* 1ms */
 	unsigned int val;
@@ -382,11 +379,12 @@
 		if (!((val = snd_via82xx_codec_xread(chip)) & VIA_REG_AC97_BUSY))
 			return val & 0xffff;
 	}
-	snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n", secondary, snd_via82xx_codec_xread(chip));
+	snd_printk(KERN_ERR "codec_ready: codec %i is not ready [0x%x]\n",
+		   secondary, snd_via82xx_codec_xread(chip));
 	return -EIO;
 }
  
-static int snd_via82xx_codec_valid(via82xx_t *chip, int secondary)
+static int snd_via82xx_codec_valid(struct via82xx_modem *chip, int secondary)
 {
 	unsigned int timeout = 1000;	/* 1ms */
 	unsigned int val, val1;
@@ -403,20 +401,20 @@
 	return -EIO;
 }
  
-static void snd_via82xx_codec_wait(ac97_t *ac97)
+static void snd_via82xx_codec_wait(struct snd_ac97 *ac97)
 {
-	via82xx_t *chip = ac97->private_data;
+	struct via82xx_modem *chip = ac97->private_data;
 	int err;
 	err = snd_via82xx_codec_ready(chip, ac97->num);
 	/* here we need to wait fairly for long time.. */
 	msleep(500);
 }
 
-static void snd_via82xx_codec_write(ac97_t *ac97,
+static void snd_via82xx_codec_write(struct snd_ac97 *ac97,
 				    unsigned short reg,
 				    unsigned short val)
 {
-	via82xx_t *chip = ac97->private_data;
+	struct via82xx_modem *chip = ac97->private_data;
 	unsigned int xval;
 	if(reg == AC97_GPIO_STATUS) {
 		outl(val, VIAREG(chip, GPI_STATUS));
@@ -430,9 +428,9 @@
 	snd_via82xx_codec_ready(chip, ac97->num);
 }
 
-static unsigned short snd_via82xx_codec_read(ac97_t *ac97, unsigned short reg)
+static unsigned short snd_via82xx_codec_read(struct snd_ac97 *ac97, unsigned short reg)
 {
-	via82xx_t *chip = ac97->private_data;
+	struct via82xx_modem *chip = ac97->private_data;
 	unsigned int xval, val = 0xffff;
 	int again = 0;
 
@@ -442,7 +440,8 @@
 	xval |= (reg & 0x7f) << VIA_REG_AC97_CMD_SHIFT;
       	while (1) {
       		if (again++ > 3) {
-			snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n", ac97->num, snd_via82xx_codec_xread(chip));
+			snd_printk(KERN_ERR "codec_read: codec %i is not valid [0x%x]\n",
+				   ac97->num, snd_via82xx_codec_xread(chip));
 		      	return 0xffff;
 		}
 		snd_via82xx_codec_xwrite(chip, xval);
@@ -456,7 +455,7 @@
 	return val & 0xffff;
 }
 
-static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
+static void snd_via82xx_channel_reset(struct via82xx_modem *chip, struct viadev *viadev)
 {
 	outb(VIA_REG_CTRL_PAUSE | VIA_REG_CTRL_TERMINATE | VIA_REG_CTRL_RESET,
 	     VIADEV_REG(viadev, OFFSET_CONTROL));
@@ -478,7 +477,7 @@
 
 static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	via82xx_t *chip = dev_id;
+	struct via82xx_modem *chip = dev_id;
 	unsigned int status;
 	unsigned int i;
 
@@ -491,7 +490,7 @@
 	/* check status for each stream */
 	spin_lock(&chip->reg_lock);
 	for (i = 0; i < chip->num_devs; i++) {
-		viadev_t *viadev = &chip->devs[i];
+		struct viadev *viadev = &chip->devs[i];
 		unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
 		c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
 		if (! c_status)
@@ -514,10 +513,10 @@
 /*
  * trigger callback
  */
-static int snd_via82xx_pcm_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_via82xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 	unsigned char val = 0;
 
 	switch (cmd) {
@@ -555,9 +554,11 @@
  */
 
 #define check_invalid_pos(viadev,pos) \
-	((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))
+	((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 ||\
+				     viadev->lastpos < viadev->bufsize2))
 
-static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
+static inline unsigned int calc_linear_pos(struct viadev *viadev, unsigned int idx,
+					   unsigned int count)
 {
 	unsigned int size, res;
 
@@ -566,24 +567,33 @@
 
 	/* check the validity of the calculated position */
 	if (size < count) {
-		snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count);
+		snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n",
+			   (int)size, (int)count);
 		res = viadev->lastpos;
 	} else if (check_invalid_pos(viadev, res)) {
 #ifdef POINTER_DEBUG
-		printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+		printk(KERN_DEBUG "fail: idx = %i/%i, lastpos = 0x%x, "
+		       "bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, "
+		       "count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos,
+		       viadev->bufsize2, viadev->idx_table[idx].offset,
+		       viadev->idx_table[idx].size, count);
 #endif
 		if (count && size < count) {
-			snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
+			snd_printd(KERN_ERR "invalid via82xx_cur_ptr, "
+				   "using last valid pointer\n");
 			res = viadev->lastpos;
 		} else {
 			if (! count)
 				/* bogus count 0 on the DMA boundary? */
 				res = viadev->idx_table[idx].offset;
 			else
-				/* count register returns full size when end of buffer is reached */
+				/* count register returns full size
+				 * when end of buffer is reached
+				 */
 				res = viadev->idx_table[idx].offset + size;
 			if (check_invalid_pos(viadev, res)) {
-				snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n");
+				snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), "
+					   "using last valid pointer\n");
 				res = viadev->lastpos;
 			}
 		}
@@ -597,10 +607,10 @@
 /*
  * get the current pointer on via686
  */
-static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 	unsigned int idx, ptr, count, res;
 
 	snd_assert(viadev->tbl_entries, return 0);
@@ -616,7 +626,8 @@
 	if (ptr <= (unsigned int)viadev->table.addr)
 		idx = 0;
 	else /* CURR_PTR holds the address + 8 */
-		idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
+		idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) %
+			viadev->tbl_entries;
 	res = calc_linear_pos(viadev, idx, count);
 	spin_unlock(&chip->reg_lock);
 
@@ -627,11 +638,11 @@
  * hw_params callback:
  * allocate the buffer and build up the buffer description table
  */
-static int snd_via82xx_hw_params(snd_pcm_substream_t * substream,
-				 snd_pcm_hw_params_t * hw_params)
+static int snd_via82xx_hw_params(struct snd_pcm_substream *substream,
+				 struct snd_pcm_hw_params *hw_params)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 	int err;
 
 	err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
@@ -653,10 +664,10 @@
  * hw_free callback:
  * clean up the buffer description table and release the buffer
  */
-static int snd_via82xx_hw_free(snd_pcm_substream_t * substream)
+static int snd_via82xx_hw_free(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 
 	clean_via_table(viadev, substream, chip->pci);
 	snd_pcm_lib_free_pages(substream);
@@ -667,7 +678,7 @@
 /*
  * set up the table pointer
  */
-static void snd_via82xx_set_table_ptr(via82xx_t *chip, viadev_t *viadev)
+static void snd_via82xx_set_table_ptr(struct via82xx_modem *chip, struct viadev *viadev)
 {
 	snd_via82xx_codec_ready(chip, chip->ac97_secondary);
 	outl((u32)viadev->table.addr, VIADEV_REG(viadev, OFFSET_TABLE_PTR));
@@ -678,10 +689,10 @@
 /*
  * prepare callback for playback and capture
  */
-static int snd_via82xx_pcm_prepare(snd_pcm_substream_t *substream)
+static int snd_via82xx_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = substream->runtime->private_data;
 
 	snd_via82xx_channel_reset(chip, viadev);
 	/* this must be set after channel_reset */
@@ -694,7 +705,7 @@
 /*
  * pcm hardware definition, identical for both playback and capture
  */
-static snd_pcm_hardware_t snd_via82xx_hw =
+static struct snd_pcm_hardware snd_via82xx_hw =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -719,12 +730,13 @@
 /*
  * open callback skeleton
  */
-static int snd_via82xx_modem_pcm_open(via82xx_t *chip, viadev_t *viadev, snd_pcm_substream_t * substream)
+static int snd_via82xx_modem_pcm_open(struct via82xx_modem *chip, struct viadev *viadev,
+				      struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
         static unsigned int rates[] = { 8000,  9600, 12000, 16000 };
-        static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+        static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
                 .count = ARRAY_SIZE(rates),
                 .list = rates,
                 .mask = 0,
@@ -732,7 +744,8 @@
 
 	runtime->hw = snd_via82xx_hw;
 	
-        if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates)) < 0)
+        if ((err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+					      &hw_constraints_rates)) < 0)
                 return err;
 
 	/* we may remove following constaint when we modify table entries
@@ -750,10 +763,10 @@
 /*
  * open callback for playback
  */
-static int snd_via82xx_playback_open(snd_pcm_substream_t * substream)
+static int snd_via82xx_playback_open(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = &chip->devs[chip->playback_devno + substream->number];
+	struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = &chip->devs[chip->playback_devno + substream->number];
 
 	return snd_via82xx_modem_pcm_open(chip, viadev, substream);
 }
@@ -761,10 +774,10 @@
 /*
  * open callback for capture
  */
-static int snd_via82xx_capture_open(snd_pcm_substream_t * substream)
+static int snd_via82xx_capture_open(struct snd_pcm_substream *substream)
 {
-	via82xx_t *chip = snd_pcm_substream_chip(substream);
-	viadev_t *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
+	struct via82xx_modem *chip = snd_pcm_substream_chip(substream);
+	struct viadev *viadev = &chip->devs[chip->capture_devno + substream->pcm->device];
 
 	return snd_via82xx_modem_pcm_open(chip, viadev, substream);
 }
@@ -772,9 +785,9 @@
 /*
  * close callback
  */
-static int snd_via82xx_pcm_close(snd_pcm_substream_t * substream)
+static int snd_via82xx_pcm_close(struct snd_pcm_substream *substream)
 {
-	viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
+	struct viadev *viadev = substream->runtime->private_data;
 
 	viadev->substream = NULL;
 	return 0;
@@ -782,7 +795,7 @@
 
 
 /* via686 playback callbacks */
-static snd_pcm_ops_t snd_via686_playback_ops = {
+static struct snd_pcm_ops snd_via686_playback_ops = {
 	.open =		snd_via82xx_playback_open,
 	.close =	snd_via82xx_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -795,7 +808,7 @@
 };
 
 /* via686 capture callbacks */
-static snd_pcm_ops_t snd_via686_capture_ops = {
+static struct snd_pcm_ops snd_via686_capture_ops = {
 	.open =		snd_via82xx_capture_open,
 	.close =	snd_via82xx_pcm_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -808,7 +821,8 @@
 };
 
 
-static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
+static void init_viadev(struct via82xx_modem *chip, int idx, unsigned int reg_offset,
+			int direction)
 {
 	chip->devs[idx].reg_offset = reg_offset;
 	chip->devs[idx].direction = direction;
@@ -818,9 +832,9 @@
 /*
  * create a pcm instance for via686a/b
  */
-static int __devinit snd_via686_pcm_new(via82xx_t *chip)
+static int __devinit snd_via686_pcm_new(struct via82xx_modem *chip)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	chip->playback_devno = 0;
@@ -841,7 +855,8 @@
 	init_viadev(chip, 1, VIA_REG_MI_STATUS, 1);
 
 	if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
-							 snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
+							 snd_dma_pci_data(chip->pci),
+							 64*1024, 128*1024)) < 0)
 		return err;
 
 	return 0;
@@ -853,24 +868,24 @@
  */
 
 
-static void snd_via82xx_mixer_free_ac97_bus(ac97_bus_t *bus)
+static void snd_via82xx_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
 {
-	via82xx_t *chip = bus->private_data;
+	struct via82xx_modem *chip = bus->private_data;
 	chip->ac97_bus = NULL;
 }
 
-static void snd_via82xx_mixer_free_ac97(ac97_t *ac97)
+static void snd_via82xx_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	via82xx_t *chip = ac97->private_data;
+	struct via82xx_modem *chip = ac97->private_data;
 	chip->ac97 = NULL;
 }
 
 
-static int __devinit snd_via82xx_mixer_new(via82xx_t *chip)
+static int __devinit snd_via82xx_mixer_new(struct via82xx_modem *chip)
 {
-	ac97_template_t ac97;
+	struct snd_ac97_template ac97;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_via82xx_codec_write,
 		.read = snd_via82xx_codec_read,
 		.wait = snd_via82xx_codec_wait,
@@ -898,9 +913,9 @@
 /*
  * proc interface
  */
-static void snd_via82xx_proc_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void snd_via82xx_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	via82xx_t *chip = entry->private_data;
+	struct via82xx_modem *chip = entry->private_data;
 	int i;
 	
 	snd_iprintf(buffer, "%s\n\n", chip->card->longname);
@@ -909,9 +924,9 @@
 	}
 }
 
-static void __devinit snd_via82xx_proc_init(via82xx_t *chip)
+static void __devinit snd_via82xx_proc_init(struct via82xx_modem *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(chip->card, "via82xx", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, snd_via82xx_proc_read);
@@ -921,7 +936,7 @@
  *
  */
 
-static int snd_via82xx_chip_init(via82xx_t *chip)
+static int snd_via82xx_chip_init(struct via82xx_modem *chip)
 {
 	unsigned int val;
 	unsigned long end_time;
@@ -1004,31 +1019,35 @@
 /*
  * power management
  */
-static int snd_via82xx_suspend(snd_card_t *card, pm_message_t state)
+static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	via82xx_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct via82xx_modem *chip = card->private_data;
 	int i;
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	for (i = 0; i < 2; i++)
-		if (chip->pcms[i])
-			snd_pcm_suspend_all(chip->pcms[i]);
+		snd_pcm_suspend_all(chip->pcms[i]);
 	for (i = 0; i < chip->num_devs; i++)
 		snd_via82xx_channel_reset(chip, &chip->devs[i]);
 	synchronize_irq(chip->irq);
 	snd_ac97_suspend(chip->ac97);
-	pci_set_power_state(chip->pci, 3);
-	pci_disable_device(chip->pci);
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int snd_via82xx_resume(snd_card_t *card)
+static int snd_via82xx_resume(struct pci_dev *pci)
 {
-	via82xx_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct via82xx_modem *chip = card->private_data;
 	int i;
 
-	pci_enable_device(chip->pci);
-	pci_set_power_state(chip->pci, 0);
-	pci_set_master(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
+	pci_set_master(pci);
 
 	snd_via82xx_chip_init(chip);
 
@@ -1037,11 +1056,12 @@
 	for (i = 0; i < chip->num_devs; i++)
 		snd_via82xx_channel_reset(chip, &chip->devs[i]);
 
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
-static int snd_via82xx_free(via82xx_t *chip)
+static int snd_via82xx_free(struct via82xx_modem *chip)
 {
 	unsigned int i;
 
@@ -1053,29 +1073,29 @@
 	synchronize_irq(chip->irq);
       __end_hw:
 	if (chip->irq >= 0)
-		free_irq(chip->irq, (void *)chip);
+		free_irq(chip->irq, chip);
 	pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
 	kfree(chip);
 	return 0;
 }
 
-static int snd_via82xx_dev_free(snd_device_t *device)
+static int snd_via82xx_dev_free(struct snd_device *device)
 {
-	via82xx_t *chip = device->device_data;
+	struct via82xx_modem *chip = device->device_data;
 	return snd_via82xx_free(chip);
 }
 
-static int __devinit snd_via82xx_create(snd_card_t * card,
+static int __devinit snd_via82xx_create(struct snd_card *card,
 					struct pci_dev *pci,
 					int chip_type,
 					int revision,
 					unsigned int ac97_clock,
-					via82xx_t ** r_via)
+					struct via82xx_modem ** r_via)
 {
-	via82xx_t *chip;
+	struct via82xx_modem *chip;
 	int err;
-        static snd_device_ops_t ops = {
+        static struct snd_device_ops ops = {
 		.dev_free =	snd_via82xx_dev_free,
         };
 
@@ -1099,7 +1119,7 @@
 	}
 	chip->port = pci_resource_start(pci, 0);
 	if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
-			card->driver, (void *)chip)) {
+			card->driver, chip)) {
 		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
 		snd_via82xx_free(chip);
 		return -EBUSY;
@@ -1134,8 +1154,8 @@
 static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 				       const struct pci_device_id *pci_id)
 {
-	snd_card_t *card;
-	via82xx_t *chip;
+	struct snd_card *card;
+	struct via82xx_modem *chip;
 	unsigned char revision;
 	int chip_type = 0, card_type;
 	unsigned int i;
@@ -1161,14 +1181,13 @@
 	if ((err = snd_via82xx_create(card, pci, chip_type, revision,
 				      ac97_clock, &chip)) < 0)
 		goto __error;
+	card->private_data = chip;
 	if ((err = snd_via82xx_mixer_new(chip)) < 0)
 		goto __error;
 
 	if ((err = snd_via686_pcm_new(chip)) < 0 )
 		goto __error;
 
-	snd_card_set_pm_callback(card, snd_via82xx_suspend, snd_via82xx_resume, chip);
-
 	/* disable interrupts */
 	for (i = 0; i < chip->num_devs; i++)
 		snd_via82xx_channel_reset(chip, &chip->devs[i]);
@@ -1201,7 +1220,10 @@
 	.id_table = snd_via82xx_modem_ids,
 	.probe = snd_via82xx_probe,
 	.remove = __devexit_p(snd_via82xx_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = snd_via82xx_suspend,
+	.resume = snd_via82xx_resume,
+#endif
 };
 
 static int __init alsa_card_via82xx_init(void)
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index dca6bd2..c816ddf 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -108,7 +108,7 @@
 
 /*
  */
-static int snd_vx222_free(vx_core_t *chip)
+static int snd_vx222_free(struct vx_core *chip)
 {
 	struct snd_vx222 *vx = (struct snd_vx222 *)chip;
 
@@ -121,21 +121,21 @@
 	return 0;
 }
 
-static int snd_vx222_dev_free(snd_device_t *device)
+static int snd_vx222_dev_free(struct snd_device *device)
 {
-	vx_core_t *chip = device->device_data;
+	struct vx_core *chip = device->device_data;
 	return snd_vx222_free(chip);
 }
 
 
-static int __devinit snd_vx222_create(snd_card_t *card, struct pci_dev *pci,
+static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
 				      struct snd_vx_hardware *hw,
 				      struct snd_vx222 **rchip)
 {
-	vx_core_t *chip;
+	struct vx_core *chip;
 	struct snd_vx222 *vx;
 	int i, err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_vx222_dev_free,
 	};
 	struct snd_vx_ops *vx_ops;
@@ -147,7 +147,7 @@
 
 	vx_ops = hw->type == VX_TYPE_BOARD ? &vx222_old_ops : &vx222_ops;
 	chip = snd_vx_create(card, hw, vx_ops,
-			     sizeof(struct snd_vx222) - sizeof(vx_core_t));
+			     sizeof(struct snd_vx222) - sizeof(struct vx_core));
 	if (! chip) {
 		pci_disable_device(pci);
 		return -ENOMEM;
@@ -186,7 +186,7 @@
 				     const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_vx_hardware *hw;
 	struct snd_vx222 *vx;
 	int err;
@@ -218,6 +218,7 @@
 		snd_card_free(card);
 		return err;
 	}
+	card->private_data = vx;
 	vx->core.ibl.size = ibl[dev];
 
 	sprintf(card->longname, "%s at 0x%lx & 0x%lx, irq %i",
@@ -250,12 +251,42 @@
 	pci_set_drvdata(pci, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_vx222_suspend(struct pci_dev *pci, pm_message_t state)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_vx222 *vx = card->private_data;
+	int err;
+
+	err = snd_vx_suspend(&vx->core, state);
+	pci_set_power_state(pci, PCI_D3hot);
+	pci_disable_device(pci);
+	pci_save_state(pci);
+	return err;
+}
+
+static int snd_vx222_resume(struct pci_dev *pci)
+{
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_vx222 *vx = card->private_data;
+
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_power_state(pci, PCI_D0);
+	pci_set_master(pci);
+	return snd_vx_resume(&vx->core);
+}
+#endif
+
 static struct pci_driver driver = {
 	.name = "Digigram VX222",
 	.id_table = snd_vx222_ids,
 	.probe = snd_vx222_probe,
 	.remove = __devexit_p(snd_vx222_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = snd_vx222_suspend,
+	.resume = snd_vx222_resume,
+#endif
 };
 
 static int __init alsa_card_vx222_init(void)
diff --git a/sound/pci/vx222/vx222.h b/sound/pci/vx222/vx222.h
index 18478ae..2f0d78f 100644
--- a/sound/pci/vx222/vx222.h
+++ b/sound/pci/vx222/vx222.h
@@ -25,7 +25,7 @@
 
 struct snd_vx222 {
 
-	vx_core_t core;
+	struct vx_core core;
 
 	/* h/w config; for PLX and for DSP */
 	struct pci_dev *pci;
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index 967bd5e..c705af4 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -82,7 +82,7 @@
 	[VX_GPIOC]	= 0,	/* on the PLX */
 };
 
-static inline unsigned long vx2_reg_addr(vx_core_t *_chip, int reg)
+static inline unsigned long vx2_reg_addr(struct vx_core *_chip, int reg)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 	return chip->port[vx2_reg_index[reg]] + vx2_reg_offset[reg];
@@ -92,7 +92,7 @@
  * snd_vx_inb - read a byte from the register
  * @offset: register enum
  */
-static unsigned char vx2_inb(vx_core_t *chip, int offset)
+static unsigned char vx2_inb(struct vx_core *chip, int offset)
 {
 	return inb(vx2_reg_addr(chip, offset));
 }
@@ -102,7 +102,7 @@
  * @offset: the register offset
  * @val: the value to write
  */
-static void vx2_outb(vx_core_t *chip, int offset, unsigned char val)
+static void vx2_outb(struct vx_core *chip, int offset, unsigned char val)
 {
 	outb(val, vx2_reg_addr(chip, offset));
 	//printk("outb: %x -> %x\n", val, vx2_reg_addr(chip, offset));
@@ -112,7 +112,7 @@
  * snd_vx_inl - read a 32bit word from the register
  * @offset: register enum
  */
-static unsigned int vx2_inl(vx_core_t *chip, int offset)
+static unsigned int vx2_inl(struct vx_core *chip, int offset)
 {
 	return inl(vx2_reg_addr(chip, offset));
 }
@@ -122,7 +122,7 @@
  * @offset: the register enum
  * @val: the value to write
  */
-static void vx2_outl(vx_core_t *chip, int offset, unsigned int val)
+static void vx2_outl(struct vx_core *chip, int offset, unsigned int val)
 {
 	// printk("outl: %x -> %x\n", val, vx2_reg_addr(chip, offset));
 	outl(val, vx2_reg_addr(chip, offset));
@@ -132,13 +132,13 @@
  * redefine macros to call directly
  */
 #undef vx_inb
-#define vx_inb(chip,reg)	vx2_inb((vx_core_t*)(chip), VX_##reg)
+#define vx_inb(chip,reg)	vx2_inb((struct vx_core*)(chip), VX_##reg)
 #undef vx_outb
-#define vx_outb(chip,reg,val)	vx2_outb((vx_core_t*)(chip), VX_##reg, val)
+#define vx_outb(chip,reg,val)	vx2_outb((struct vx_core*)(chip), VX_##reg, val)
 #undef vx_inl
-#define vx_inl(chip,reg)	vx2_inl((vx_core_t*)(chip), VX_##reg)
+#define vx_inl(chip,reg)	vx2_inl((struct vx_core*)(chip), VX_##reg)
 #undef vx_outl
-#define vx_outl(chip,reg,val)	vx2_outl((vx_core_t*)(chip), VX_##reg, val)
+#define vx_outl(chip,reg,val)	vx2_outl((struct vx_core*)(chip), VX_##reg, val)
 
 
 /*
@@ -147,14 +147,14 @@
 
 #define XX_DSP_RESET_WAIT_TIME		2	/* ms */
 
-static void vx2_reset_dsp(vx_core_t *_chip)
+static void vx2_reset_dsp(struct vx_core *_chip)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 
 	/* set the reset dsp bit to 0 */
 	vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_DSP_RESET_MASK);
 
-	snd_vx_delay(_chip, XX_DSP_RESET_WAIT_TIME);
+	mdelay(XX_DSP_RESET_WAIT_TIME);
 
 	chip->regCDSP |= VX_CDSP_DSP_RESET_MASK;
 	/* set the reset dsp bit to 1 */
@@ -162,7 +162,7 @@
 }
 
 
-static int vx2_test_xilinx(vx_core_t *_chip)
+static int vx2_test_xilinx(struct vx_core *_chip)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 	unsigned int data;
@@ -219,7 +219,7 @@
  * vx_setup_pseudo_dma - set up the pseudo dma read/write mode.
  * @do_write: 0 = read, 1 = set up for DMA write
  */
-static void vx2_setup_pseudo_dma(vx_core_t *chip, int do_write)
+static void vx2_setup_pseudo_dma(struct vx_core *chip, int do_write)
 {
 	/* Interrupt mode and HREQ pin enabled for host transmit data transfers
 	 * (in case of the use of the pseudo-dma facility).
@@ -235,7 +235,7 @@
 /*
  * vx_release_pseudo_dma - disable the pseudo-DMA mode
  */
-static inline void vx2_release_pseudo_dma(vx_core_t *chip)
+static inline void vx2_release_pseudo_dma(struct vx_core *chip)
 {
 	/* HREQ pin disabled. */
 	vx_outl(chip, ICR, 0);
@@ -244,8 +244,8 @@
 
 
 /* pseudo-dma write */
-static void vx2_dma_write(vx_core_t *chip, snd_pcm_runtime_t *runtime,
-			  vx_pipe_t *pipe, int count)
+static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+			  struct vx_pipe *pipe, int count)
 {
 	unsigned long port = vx2_reg_addr(chip, VX_DMA);
 	int offset = pipe->hw_ptr;
@@ -282,8 +282,8 @@
 
 
 /* pseudo dma read */
-static void vx2_dma_read(vx_core_t *chip, snd_pcm_runtime_t *runtime,
-			 vx_pipe_t *pipe, int count)
+static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+			 struct vx_pipe *pipe, int count)
 {
 	int offset = pipe->hw_ptr;
 	u32 *addr = (u32 *)(runtime->dma_area + offset);
@@ -321,7 +321,7 @@
 /*
  * transfer counts bits to PLX
  */
-static int put_xilinx_data(vx_core_t *chip, unsigned int port, unsigned int counts, unsigned char data)
+static int put_xilinx_data(struct vx_core *chip, unsigned int port, unsigned int counts, unsigned char data)
 {
 	unsigned int i;
 
@@ -353,7 +353,7 @@
 /*
  * load the xilinx image
  */
-static int vx2_load_xilinx_binary(vx_core_t *chip, const struct firmware *xilinx)
+static int vx2_load_xilinx_binary(struct vx_core *chip, const struct firmware *xilinx)
 {
 	unsigned int i;
 	unsigned int port;
@@ -362,10 +362,10 @@
 	/* XILINX reset (wait at least 1 milisecond between reset on and off). */
 	vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK);
 	vx_inl(chip, CNTRL);
-	snd_vx_delay(chip, 10);
+	msleep(10);
 	vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE);
 	vx_inl(chip, CNTRL);
-	snd_vx_delay(chip, 10);
+	msleep(10);
 
 	if (chip->type == VX_TYPE_BOARD)
 		port = VX_CNTRL;
@@ -381,7 +381,7 @@
 	}
 	put_xilinx_data(chip, port, 4, 0xff); /* end signature */
 
-	snd_vx_delay(chip, 200);
+	msleep(200);
 
 	/* test after loading (is buggy with VX222) */
 	if (chip->type != VX_TYPE_BOARD) {
@@ -400,7 +400,7 @@
 /*
  * load the boot/dsp images
  */
-static int vx2_load_dsp(vx_core_t *vx, int index, const struct firmware *dsp)
+static int vx2_load_dsp(struct vx_core *vx, int index, const struct firmware *dsp)
 {
 	int err;
 
@@ -432,7 +432,7 @@
  *
  * spinlock held!
  */
-static int vx2_test_and_ack(vx_core_t *chip)
+static int vx2_test_and_ack(struct vx_core *chip)
 {
 	/* not booted yet? */
 	if (! (chip->chip_status & VX_STAT_XILINX_LOADED))
@@ -463,7 +463,7 @@
 /*
  * vx_validate_irq - enable/disable IRQ
  */
-static void vx2_validate_irq(vx_core_t *_chip, int enable)
+static void vx2_validate_irq(struct vx_core *_chip, int enable)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 
@@ -484,7 +484,7 @@
 /*
  * write an AKM codec data (24bit)
  */
-static void vx2_write_codec_reg(vx_core_t *chip, unsigned int data)
+static void vx2_write_codec_reg(struct vx_core *chip, unsigned int data)
 {
 	unsigned int i;
 
@@ -660,7 +660,7 @@
 /*
  * pseudo-codec write entry
  */
-static void vx2_write_akm(vx_core_t *chip, int reg, unsigned int data)
+static void vx2_write_akm(struct vx_core *chip, int reg, unsigned int data)
 {
 	unsigned int val;
 
@@ -695,7 +695,7 @@
 /*
  * write codec bit for old VX222 board
  */
-static void vx2_old_write_codec_bit(vx_core_t *chip, int codec, unsigned int data)
+static void vx2_old_write_codec_bit(struct vx_core *chip, int codec, unsigned int data)
 {
 	int i;
 
@@ -713,24 +713,24 @@
 /*
  * reset codec bit
  */
-static void vx2_reset_codec(vx_core_t *_chip)
+static void vx2_reset_codec(struct vx_core *_chip)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 
 	/* Set the reset CODEC bit to 0. */
 	vx_outl(chip, CDSP, chip->regCDSP &~ VX_CDSP_CODEC_RESET_MASK);
 	vx_inl(chip, CDSP);
-	snd_vx_delay(_chip, 10);
+	msleep(10);
 	/* Set the reset CODEC bit to 1. */
 	chip->regCDSP |= VX_CDSP_CODEC_RESET_MASK;
 	vx_outl(chip, CDSP, chip->regCDSP);
 	vx_inl(chip, CDSP);
 	if (_chip->type == VX_TYPE_BOARD) {
-		snd_vx_delay(_chip, 1);
+		msleep(1);
 		return;
 	}
 
-	snd_vx_delay(_chip, 5);  /* additionnel wait time for AKM's */
+	msleep(5);  /* additionnel wait time for AKM's */
 
 	vx2_write_codec_reg(_chip, AKM_CODEC_POWER_CONTROL_CMD); /* DAC power up, ADC power up, Vref power down */
 	
@@ -755,7 +755,7 @@
 /*
  * change the audio source
  */
-static void vx2_change_audio_source(vx_core_t *_chip, int src)
+static void vx2_change_audio_source(struct vx_core *_chip, int src)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 
@@ -774,7 +774,7 @@
 /*
  * set the clock source
  */
-static void vx2_set_clock_source(vx_core_t *_chip, int source)
+static void vx2_set_clock_source(struct vx_core *_chip, int source)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 
@@ -788,7 +788,7 @@
 /*
  * reset the board
  */
-static void vx2_reset_board(vx_core_t *_chip, int cold_reset)
+static void vx2_reset_board(struct vx_core *_chip, int cold_reset)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 
@@ -848,7 +848,7 @@
  */
 
 /* input levels */
-static int vx_input_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_input_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -857,9 +857,9 @@
 	return 0;
 }
 
-static int vx_input_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_input_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 	down(&_chip->mixer_mutex);
 	ucontrol->value.integer.value[0] = chip->input_level[0];
@@ -868,9 +868,9 @@
 	return 0;
 }
 
-static int vx_input_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_input_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 	down(&_chip->mixer_mutex);
 	if (chip->input_level[0] != ucontrol->value.integer.value[0] ||
@@ -886,7 +886,7 @@
 }
 
 /* mic level */
-static int vx_mic_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -895,17 +895,17 @@
 	return 0;
 }
 
-static int vx_mic_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 	ucontrol->value.integer.value[0] = chip->mic_level;
 	return 0;
 }
 
-static int vx_mic_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 	down(&_chip->mixer_mutex);
 	if (chip->mic_level != ucontrol->value.integer.value[0]) {
@@ -918,7 +918,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vx_control_input_level = {
+static struct snd_kcontrol_new vx_control_input_level = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Capture Volume",
 	.info =		vx_input_level_info,
@@ -926,7 +926,7 @@
 	.put =		vx_input_level_put,
 };
 
-static snd_kcontrol_new_t vx_control_mic_level = {
+static struct snd_kcontrol_new vx_control_mic_level = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Mic Capture Volume",
 	.info =		vx_mic_level_info,
@@ -938,7 +938,7 @@
  * FIXME: compressor/limiter implementation is missing yet...
  */
 
-static int vx2_add_mic_controls(vx_core_t *_chip)
+static int vx2_add_mic_controls(struct vx_core *_chip)
 {
 	struct snd_vx222 *chip = (struct snd_vx222 *)_chip;
 	int err;
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index d013237..dab9b83 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -31,7 +31,7 @@
 #include <sound/initval.h>
 
 MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
-MODULE_DESCRIPTION("Yamaha DS-XG PCI");
+MODULE_DESCRIPTION("Yamaha DS-1 PCI");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF724},"
 		"{Yamaha,YMF724F},"
@@ -51,11 +51,11 @@
 static int rear_switch[SNDRV_CARDS];
 
 module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for the Yamaha DS-XG PCI soundcard.");
+MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard.");
 module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for the Yamaha DS-XG PCI soundcard.");
+MODULE_PARM_DESC(id, "ID string for the Yamaha DS-1 PCI soundcard.");
 module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable Yamaha DS-XG soundcard.");
+MODULE_PARM_DESC(enable, "Enable Yamaha DS-1 soundcard.");
 module_param_array(mpu_port, long, NULL, 0444);
 MODULE_PARM_DESC(mpu_port, "MPU-401 Port.");
 module_param_array(fm_port, long, NULL, 0444);
@@ -80,7 +80,7 @@
 MODULE_DEVICE_TABLE(pci, snd_ymfpci_ids);
 
 #ifdef SUPPORT_JOYSTICK
-static int __devinit snd_ymfpci_create_gameport(ymfpci_t *chip, int dev,
+static int __devinit snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev,
 						int legacy_ctrl, int legacy_ctrl2)
 {
 	struct gameport *gp;
@@ -152,7 +152,7 @@
 	return 0;
 }
 
-void snd_ymfpci_free_gameport(ymfpci_t *chip)
+void snd_ymfpci_free_gameport(struct snd_ymfpci *chip)
 {
 	if (chip->gameport) {
 		struct resource *r = gameport_get_port_data(chip->gameport);
@@ -164,20 +164,20 @@
 	}
 }
 #else
-static inline int snd_ymfpci_create_gameport(ymfpci_t *chip, int dev, int l, int l2) { return -ENOSYS; }
-void snd_ymfpci_free_gameport(ymfpci_t *chip) { }
+static inline int snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, int l, int l2) { return -ENOSYS; }
+void snd_ymfpci_free_gameport(struct snd_ymfpci *chip) { }
 #endif /* SUPPORT_JOYSTICK */
 
 static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
 					   const struct pci_device_id *pci_id)
 {
 	static int dev;
-	snd_card_t *card;
+	struct snd_card *card;
 	struct resource *fm_res = NULL;
 	struct resource *mpu_res = NULL;
-	ymfpci_t *chip;
-	opl3_t *opl3;
-	char *str;
+	struct snd_ymfpci *chip;
+	struct snd_opl3 *opl3;
+	const char *str, *model;
 	int err;
 	u16 legacy_ctrl, legacy_ctrl2, old_legacy_ctrl;
 
@@ -193,13 +193,13 @@
 		return -ENOMEM;
 
 	switch (pci_id->device) {
-	case 0x0004: str = "YMF724"; break;
-	case 0x000d: str = "YMF724F"; break;
-	case 0x000a: str = "YMF740"; break;
-	case 0x000c: str = "YMF740C"; break;
-	case 0x0010: str = "YMF744"; break;
-	case 0x0012: str = "YMF754"; break;
-	default: str = "???"; break;
+	case 0x0004: str = "YMF724";  model = "DS-1"; break;
+	case 0x000d: str = "YMF724F"; model = "DS-1"; break;
+	case 0x000a: str = "YMF740";  model = "DS-1L"; break;
+	case 0x000c: str = "YMF740C"; model = "DS-1L"; break;
+	case 0x0010: str = "YMF744";  model = "DS-1S"; break;
+	case 0x0012: str = "YMF754";  model = "DS-1E"; break;
+	default: model = str = "???"; break;
 	}
 
 	legacy_ctrl = 0;
@@ -271,8 +271,10 @@
 	}
 	chip->fm_res = fm_res;
 	chip->mpu_res = mpu_res;
+	card->private_data = chip;
+
 	strcpy(card->driver, str);
-	sprintf(card->shortname, "Yamaha DS-XG (%s)", str);
+	sprintf(card->shortname, "Yamaha %s (%s)", model, str);
 	sprintf(card->longname, "%s at 0x%lx, irq %i",
 		card->shortname,
 		chip->reg_area_phys,
@@ -343,11 +345,14 @@
 }
 
 static struct pci_driver driver = {
-	.name = "Yamaha DS-XG PCI",
+	.name = "Yamaha DS-1 PCI",
 	.id_table = snd_ymfpci_ids,
 	.probe = snd_card_ymfpci_probe,
 	.remove = __devexit_p(snd_card_ymfpci_remove),
-	SND_PCI_PM_CALLBACKS
+#ifdef CONFIG_PM
+	.suspend = snd_ymfpci_suspend,
+	.resume = snd_ymfpci_resume,
+#endif
 };
 
 static int __init alsa_card_ymfpci_init(void)
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 88a43e0..1dfc723 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -50,39 +50,39 @@
  *  common I/O routines
  */
 
-static void snd_ymfpci_irq_wait(ymfpci_t *chip);
+static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip);
 
-static inline u8 snd_ymfpci_readb(ymfpci_t *chip, u32 offset)
+static inline u8 snd_ymfpci_readb(struct snd_ymfpci *chip, u32 offset)
 {
 	return readb(chip->reg_area_virt + offset);
 }
 
-static inline void snd_ymfpci_writeb(ymfpci_t *chip, u32 offset, u8 val)
+static inline void snd_ymfpci_writeb(struct snd_ymfpci *chip, u32 offset, u8 val)
 {
 	writeb(val, chip->reg_area_virt + offset);
 }
 
-static inline u16 snd_ymfpci_readw(ymfpci_t *chip, u32 offset)
+static inline u16 snd_ymfpci_readw(struct snd_ymfpci *chip, u32 offset)
 {
 	return readw(chip->reg_area_virt + offset);
 }
 
-static inline void snd_ymfpci_writew(ymfpci_t *chip, u32 offset, u16 val)
+static inline void snd_ymfpci_writew(struct snd_ymfpci *chip, u32 offset, u16 val)
 {
 	writew(val, chip->reg_area_virt + offset);
 }
 
-static inline u32 snd_ymfpci_readl(ymfpci_t *chip, u32 offset)
+static inline u32 snd_ymfpci_readl(struct snd_ymfpci *chip, u32 offset)
 {
 	return readl(chip->reg_area_virt + offset);
 }
 
-static inline void snd_ymfpci_writel(ymfpci_t *chip, u32 offset, u32 val)
+static inline void snd_ymfpci_writel(struct snd_ymfpci *chip, u32 offset, u32 val)
 {
 	writel(val, chip->reg_area_virt + offset);
 }
 
-static int snd_ymfpci_codec_ready(ymfpci_t *chip, int secondary)
+static int snd_ymfpci_codec_ready(struct snd_ymfpci *chip, int secondary)
 {
 	unsigned long end_time;
 	u32 reg = secondary ? YDSXGR_SECSTATUSADR : YDSXGR_PRISTATUSADR;
@@ -98,9 +98,9 @@
 	return -EBUSY;
 }
 
-static void snd_ymfpci_codec_write(ac97_t *ac97, u16 reg, u16 val)
+static void snd_ymfpci_codec_write(struct snd_ac97 *ac97, u16 reg, u16 val)
 {
-	ymfpci_t *chip = ac97->private_data;
+	struct snd_ymfpci *chip = ac97->private_data;
 	u32 cmd;
 	
 	snd_ymfpci_codec_ready(chip, 0);
@@ -108,9 +108,9 @@
 	snd_ymfpci_writel(chip, YDSXGR_AC97CMDDATA, cmd);
 }
 
-static u16 snd_ymfpci_codec_read(ac97_t *ac97, u16 reg)
+static u16 snd_ymfpci_codec_read(struct snd_ac97 *ac97, u16 reg)
 {
-	ymfpci_t *chip = ac97->private_data;
+	struct snd_ymfpci *chip = ac97->private_data;
 
 	if (snd_ymfpci_codec_ready(chip, 0))
 		return ~0;
@@ -182,7 +182,7 @@
  *  Hardware start management
  */
 
-static void snd_ymfpci_hw_start(ymfpci_t *chip)
+static void snd_ymfpci_hw_start(struct snd_ymfpci *chip)
 {
 	unsigned long flags;
 
@@ -196,7 +196,7 @@
       	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-static void snd_ymfpci_hw_stop(ymfpci_t *chip)
+static void snd_ymfpci_hw_stop(struct snd_ymfpci *chip)
 {
 	unsigned long flags;
 	long timeout = 1000;
@@ -222,9 +222,11 @@
  *  Playback voice management
  */
 
-static int voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice)
+static int voice_alloc(struct snd_ymfpci *chip,
+		       enum snd_ymfpci_voice_type type, int pair,
+		       struct snd_ymfpci_voice **rvoice)
 {
-	ymfpci_voice_t *voice, *voice2;
+	struct snd_ymfpci_voice *voice, *voice2;
 	int idx;
 	
 	*rvoice = NULL;
@@ -258,7 +260,9 @@
 	return -ENOMEM;
 }
 
-static int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice)
+static int snd_ymfpci_voice_alloc(struct snd_ymfpci *chip,
+				  enum snd_ymfpci_voice_type type, int pair,
+				  struct snd_ymfpci_voice **rvoice)
 {
 	unsigned long flags;
 	int result;
@@ -278,7 +282,7 @@
 	return result;		
 }
 
-static int snd_ymfpci_voice_free(ymfpci_t *chip, ymfpci_voice_t *pvoice)
+static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voice *pvoice)
 {
 	unsigned long flags;
 	
@@ -296,9 +300,9 @@
  *  PCM part
  */
 
-static void snd_ymfpci_pcm_interrupt(ymfpci_t *chip, ymfpci_voice_t *voice)
+static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_voice *voice)
 {
-	ymfpci_pcm_t *ypcm;
+	struct snd_ymfpci_pcm *ypcm;
 	u32 pos, delta;
 	
 	if ((ypcm = voice->ypcm) == NULL)
@@ -325,7 +329,7 @@
 		if (unlikely(ypcm->update_pcm_vol)) {
 			unsigned int subs = ypcm->substream->number;
 			unsigned int next_bank = 1 - chip->active_bank;
-			snd_ymfpci_playback_bank_t *bank;
+			struct snd_ymfpci_playback_bank *bank;
 			u32 volume;
 			
 			bank = &voice->bank[next_bank];
@@ -345,11 +349,11 @@
 	spin_unlock(&chip->reg_lock);
 }
 
-static void snd_ymfpci_pcm_capture_interrupt(snd_pcm_substream_t *substream)
+static void snd_ymfpci_pcm_capture_interrupt(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm = runtime->private_data;
-	ymfpci_t *chip = ypcm->chip;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm = runtime->private_data;
+	struct snd_ymfpci *chip = ypcm->chip;
 	u32 pos, delta;
 	
 	spin_lock(&chip->reg_lock);
@@ -372,11 +376,11 @@
 	spin_unlock(&chip->reg_lock);
 }
 
-static int snd_ymfpci_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	ymfpci_pcm_t *ypcm = substream->runtime->private_data;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
 	int result = 0;
 
 	spin_lock(&chip->reg_lock);
@@ -409,11 +413,11 @@
 	spin_unlock(&chip->reg_lock);
 	return result;
 }
-static int snd_ymfpci_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_ymfpci_capture_trigger(struct snd_pcm_substream *substream,
 				      int cmd)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	ymfpci_pcm_t *ypcm = substream->runtime->private_data;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
 	int result = 0;
 	u32 tmp;
 
@@ -441,7 +445,7 @@
 	return result;
 }
 
-static int snd_ymfpci_pcm_voice_alloc(ymfpci_pcm_t *ypcm, int voices)
+static int snd_ymfpci_pcm_voice_alloc(struct snd_ymfpci_pcm *ypcm, int voices)
 {
 	int err;
 
@@ -471,16 +475,16 @@
 	return 0;
 }
 
-static void snd_ymfpci_pcm_init_voice(ymfpci_pcm_t *ypcm, unsigned int voiceidx,
-				      snd_pcm_runtime_t *runtime,
+static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int voiceidx,
+				      struct snd_pcm_runtime *runtime,
 				      int has_pcm_volume)
 {
-	ymfpci_voice_t *voice = ypcm->voices[voiceidx];
+	struct snd_ymfpci_voice *voice = ypcm->voices[voiceidx];
 	u32 format;
 	u32 delta = snd_ymfpci_calc_delta(runtime->rate);
 	u32 lpfQ = snd_ymfpci_calc_lpfQ(runtime->rate);
 	u32 lpfK = snd_ymfpci_calc_lpfK(runtime->rate);
-	snd_ymfpci_playback_bank_t *bank;
+	struct snd_ymfpci_playback_bank *bank;
 	unsigned int nbank;
 	u32 vol_left, vol_right;
 	u8 use_left, use_right;
@@ -544,7 +548,7 @@
 	}
 }
 
-static int __devinit snd_ymfpci_ac3_init(ymfpci_t *chip)
+static int __devinit snd_ymfpci_ac3_init(struct snd_ymfpci *chip)
 {
 	if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
 				4096, &chip->ac3_tmp_base) < 0)
@@ -566,7 +570,7 @@
 	return 0;
 }
 
-static int snd_ymfpci_ac3_done(ymfpci_t *chip)
+static int snd_ymfpci_ac3_done(struct snd_ymfpci *chip)
 {
 	spin_lock_irq(&chip->reg_lock);
 	snd_ymfpci_writel(chip, YDSXGR_MAPOFEFFECT,
@@ -580,11 +584,11 @@
 	return 0;
 }
 
-static int snd_ymfpci_playback_hw_params(snd_pcm_substream_t * substream,
-					 snd_pcm_hw_params_t * hw_params)
+static int snd_ymfpci_playback_hw_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm = runtime->private_data;
 	int err;
 
 	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params))) < 0)
@@ -594,11 +598,11 @@
 	return 0;
 }
 
-static int snd_ymfpci_playback_hw_free(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_hw_free(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm;
 	
 	if (runtime->private_data == NULL)
 		return 0;
@@ -618,11 +622,11 @@
 	return 0;
 }
 
-static int snd_ymfpci_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_prepare(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm = runtime->private_data;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm = runtime->private_data;
 	unsigned int nvoice;
 
 	ypcm->period_size = runtime->period_size;
@@ -635,27 +639,27 @@
 	return 0;
 }
 
-static int snd_ymfpci_capture_hw_params(snd_pcm_substream_t * substream,
-					snd_pcm_hw_params_t * hw_params)
+static int snd_ymfpci_capture_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_ymfpci_capture_hw_free(snd_pcm_substream_t * substream)
+static int snd_ymfpci_capture_hw_free(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
 
 	/* wait, until the PCI operations are not finished */
 	snd_ymfpci_irq_wait(chip);
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_ymfpci_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_ymfpci_capture_prepare(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm = runtime->private_data;
-	snd_ymfpci_capture_bank_t * bank;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm = runtime->private_data;
+	struct snd_ymfpci_capture_bank * bank;
 	int nbank;
 	u32 rate, format;
 
@@ -694,30 +698,30 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_ymfpci_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ymfpci_playback_pointer(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm = runtime->private_data;
-	ymfpci_voice_t *voice = ypcm->voices[0];
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm = runtime->private_data;
+	struct snd_ymfpci_voice *voice = ypcm->voices[0];
 
 	if (!(ypcm->running && voice))
 		return 0;
 	return le32_to_cpu(voice->bank[chip->active_bank].start);
 }
 
-static snd_pcm_uframes_t snd_ymfpci_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_ymfpci_capture_pointer(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm = runtime->private_data;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm = runtime->private_data;
 
 	if (!ypcm->running)
 		return 0;
 	return le32_to_cpu(chip->bank_capture[ypcm->capture_bank_number][chip->active_bank]->start) >> ypcm->shift;
 }
 
-static void snd_ymfpci_irq_wait(ymfpci_t *chip)
+static void snd_ymfpci_irq_wait(struct snd_ymfpci *chip)
 {
 	wait_queue_t wait;
 	int loops = 4;
@@ -735,9 +739,9 @@
 
 static irqreturn_t snd_ymfpci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	ymfpci_t *chip = dev_id;
+	struct snd_ymfpci *chip = dev_id;
 	u32 status, nvoice, mode;
-	ymfpci_voice_t *voice;
+	struct snd_ymfpci_voice *voice;
 
 	status = snd_ymfpci_readl(chip, YDSXGR_STATUS);
 	if (status & 0x80000000) {
@@ -783,7 +787,7 @@
 	return IRQ_HANDLED;
 }
 
-static snd_pcm_hardware_t snd_ymfpci_playback =
+static struct snd_pcm_hardware snd_ymfpci_playback =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_MMAP_VALID | 
@@ -805,7 +809,7 @@
 	.fifo_size =		0,
 };
 
-static snd_pcm_hardware_t snd_ymfpci_capture =
+static struct snd_pcm_hardware snd_ymfpci_capture =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP |
 				 SNDRV_PCM_INFO_MMAP_VALID |
@@ -827,16 +831,16 @@
 	.fifo_size =		0,
 };
 
-static void snd_ymfpci_pcm_free_substream(snd_pcm_runtime_t *runtime)
+static void snd_ymfpci_pcm_free_substream(struct snd_pcm_runtime *runtime)
 {
 	kfree(runtime->private_data);
 }
 
-static int snd_ymfpci_playback_open_1(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm;
 
 	ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
 	if (ypcm == NULL)
@@ -853,7 +857,7 @@
 }
 
 /* call with spinlock held */
-static void ymfpci_open_extension(ymfpci_t *chip)
+static void ymfpci_open_extension(struct snd_ymfpci *chip)
 {
 	if (! chip->rear_opened) {
 		if (! chip->spdif_opened) /* set AC3 */
@@ -866,7 +870,7 @@
 }
 
 /* call with spinlock held */
-static void ymfpci_close_extension(ymfpci_t *chip)
+static void ymfpci_close_extension(struct snd_ymfpci *chip)
 {
 	if (! chip->rear_opened) {
 		if (! chip->spdif_opened)
@@ -877,12 +881,12 @@
 	}
 }
 
-static int snd_ymfpci_playback_open(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_open(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm;
-	snd_kcontrol_t *kctl;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm;
+	struct snd_kcontrol *kctl;
 	int err;
 	
 	if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
@@ -903,11 +907,11 @@
 	return 0;
 }
 
-static int snd_ymfpci_playback_spdif_open(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_spdif_open(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm;
 	int err;
 	
 	if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
@@ -930,11 +934,11 @@
 	return 0;
 }
 
-static int snd_ymfpci_playback_4ch_open(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_4ch_open(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm;
 	int err;
 	
 	if ((err = snd_ymfpci_playback_open_1(substream)) < 0)
@@ -949,12 +953,12 @@
 	return 0;
 }
 
-static int snd_ymfpci_capture_open(snd_pcm_substream_t * substream,
+static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream,
 				   u32 capture_bank_number)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm;
 
 	ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL);
 	if (ypcm == NULL)
@@ -973,26 +977,26 @@
 	return 0;
 }
 
-static int snd_ymfpci_capture_rec_open(snd_pcm_substream_t * substream)
+static int snd_ymfpci_capture_rec_open(struct snd_pcm_substream *substream)
 {
 	return snd_ymfpci_capture_open(substream, 0);
 }
 
-static int snd_ymfpci_capture_ac97_open(snd_pcm_substream_t * substream)
+static int snd_ymfpci_capture_ac97_open(struct snd_pcm_substream *substream)
 {
 	return snd_ymfpci_capture_open(substream, 1);
 }
 
-static int snd_ymfpci_playback_close_1(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_close_1(struct snd_pcm_substream *substream)
 {
 	return 0;
 }
 
-static int snd_ymfpci_playback_close(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_close(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	ymfpci_pcm_t *ypcm = substream->runtime->private_data;
-	snd_kcontrol_t *kctl;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
+	struct snd_kcontrol *kctl;
 
 	spin_lock_irq(&chip->reg_lock);
 	if (ypcm->output_rear && chip->rear_opened > 0) {
@@ -1006,9 +1010,9 @@
 	return snd_ymfpci_playback_close_1(substream);
 }
 
-static int snd_ymfpci_playback_spdif_close(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_spdif_close(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&chip->reg_lock);
 	chip->spdif_opened = 0;
@@ -1023,9 +1027,9 @@
 	return snd_ymfpci_playback_close_1(substream);
 }
 
-static int snd_ymfpci_playback_4ch_close(snd_pcm_substream_t * substream)
+static int snd_ymfpci_playback_4ch_close(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
 
 	spin_lock_irq(&chip->reg_lock);
 	if (chip->rear_opened > 0) {
@@ -1036,11 +1040,11 @@
 	return snd_ymfpci_playback_close_1(substream);
 }
 
-static int snd_ymfpci_capture_close(snd_pcm_substream_t * substream)
+static int snd_ymfpci_capture_close(struct snd_pcm_substream *substream)
 {
-	ymfpci_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	ymfpci_pcm_t *ypcm = runtime->private_data;
+	struct snd_ymfpci *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_ymfpci_pcm *ypcm = runtime->private_data;
 
 	if (ypcm != NULL) {
 		chip->capture_substream[ypcm->capture_bank_number] = NULL;
@@ -1049,7 +1053,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_ymfpci_playback_ops = {
+static struct snd_pcm_ops snd_ymfpci_playback_ops = {
 	.open =			snd_ymfpci_playback_open,
 	.close =		snd_ymfpci_playback_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1060,7 +1064,7 @@
 	.pointer =		snd_ymfpci_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_ymfpci_capture_rec_ops = {
+static struct snd_pcm_ops snd_ymfpci_capture_rec_ops = {
 	.open =			snd_ymfpci_capture_rec_open,
 	.close =		snd_ymfpci_capture_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1071,16 +1075,9 @@
 	.pointer =		snd_ymfpci_capture_pointer,
 };
 
-static void snd_ymfpci_pcm_free(snd_pcm_t *pcm)
+int __devinit snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
 {
-	ymfpci_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int __devinit snd_ymfpci_pcm(ymfpci_t *chip, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1088,7 +1085,6 @@
 	if ((err = snd_pcm_new(chip->card, "YMFPCI", device, 32, 1, &pcm)) < 0)
 		return err;
 	pcm->private_data = chip;
-	pcm->private_free = snd_ymfpci_pcm_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_ops);
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ymfpci_capture_rec_ops);
@@ -1106,7 +1102,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_ymfpci_capture_ac97_ops = {
+static struct snd_pcm_ops snd_ymfpci_capture_ac97_ops = {
 	.open =			snd_ymfpci_capture_ac97_open,
 	.close =		snd_ymfpci_capture_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1117,16 +1113,9 @@
 	.pointer =		snd_ymfpci_capture_pointer,
 };
 
-static void snd_ymfpci_pcm2_free(snd_pcm_t *pcm)
+int __devinit snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
 {
-	ymfpci_t *chip = pcm->private_data;
-	chip->pcm2 = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int __devinit snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1134,7 +1123,6 @@
 	if ((err = snd_pcm_new(chip->card, "YMFPCI - PCM2", device, 0, 1, &pcm)) < 0)
 		return err;
 	pcm->private_data = chip;
-	pcm->private_free = snd_ymfpci_pcm2_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ymfpci_capture_ac97_ops);
 
@@ -1152,7 +1140,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_ymfpci_playback_spdif_ops = {
+static struct snd_pcm_ops snd_ymfpci_playback_spdif_ops = {
 	.open =			snd_ymfpci_playback_spdif_open,
 	.close =		snd_ymfpci_playback_spdif_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1163,16 +1151,9 @@
 	.pointer =		snd_ymfpci_playback_pointer,
 };
 
-static void snd_ymfpci_pcm_spdif_free(snd_pcm_t *pcm)
+int __devinit snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
 {
-	ymfpci_t *chip = pcm->private_data;
-	chip->pcm_spdif = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int __devinit snd_ymfpci_pcm_spdif(ymfpci_t *chip, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1180,7 +1161,6 @@
 	if ((err = snd_pcm_new(chip->card, "YMFPCI - IEC958", device, 1, 0, &pcm)) < 0)
 		return err;
 	pcm->private_data = chip;
-	pcm->private_free = snd_ymfpci_pcm_spdif_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_spdif_ops);
 
@@ -1197,7 +1177,7 @@
 	return 0;
 }
 
-static snd_pcm_ops_t snd_ymfpci_playback_4ch_ops = {
+static struct snd_pcm_ops snd_ymfpci_playback_4ch_ops = {
 	.open =			snd_ymfpci_playback_4ch_open,
 	.close =		snd_ymfpci_playback_4ch_close,
 	.ioctl =		snd_pcm_lib_ioctl,
@@ -1208,16 +1188,9 @@
 	.pointer =		snd_ymfpci_playback_pointer,
 };
 
-static void snd_ymfpci_pcm_4ch_free(snd_pcm_t *pcm)
+int __devinit snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
 {
-	ymfpci_t *chip = pcm->private_data;
-	chip->pcm_4ch = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int __devinit snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t ** rpcm)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if (rpcm)
@@ -1225,7 +1198,6 @@
 	if ((err = snd_pcm_new(chip->card, "YMFPCI - Rear", device, 1, 0, &pcm)) < 0)
 		return err;
 	pcm->private_data = chip;
-	pcm->private_free = snd_ymfpci_pcm_4ch_free;
 
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ymfpci_playback_4ch_ops);
 
@@ -1242,17 +1214,17 @@
 	return 0;
 }
 
-static int snd_ymfpci_spdif_default_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ymfpci_spdif_default_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ymfpci_spdif_default_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_spdif_default_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&chip->reg_lock);
 	ucontrol->value.iec958.status[0] = (chip->spdif_bits >> 0) & 0xff;
@@ -1261,10 +1233,10 @@
 	return 0;
 }
 
-static int snd_ymfpci_spdif_default_put(snd_kcontrol_t * kcontrol,
-					 snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_spdif_default_put(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 
@@ -1279,7 +1251,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ymfpci_spdif_default __devinitdata =
+static struct snd_kcontrol_new snd_ymfpci_spdif_default __devinitdata =
 {
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
 	.name =         SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1288,17 +1260,17 @@
 	.put =		snd_ymfpci_spdif_default_put
 };
 
-static int snd_ymfpci_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ymfpci_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ymfpci_spdif_mask_get(snd_kcontrol_t * kcontrol,
-				      snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_spdif_mask_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&chip->reg_lock);
 	ucontrol->value.iec958.status[0] = 0x3e;
@@ -1307,7 +1279,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_ymfpci_spdif_mask __devinitdata =
+static struct snd_kcontrol_new snd_ymfpci_spdif_mask __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READ,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1316,17 +1288,17 @@
 	.get =		snd_ymfpci_spdif_mask_get,
 };
 
-static int snd_ymfpci_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ymfpci_spdif_stream_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
 	uinfo->count = 1;
 	return 0;
 }
 
-static int snd_ymfpci_spdif_stream_get(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_spdif_stream_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 
 	spin_lock_irq(&chip->reg_lock);
 	ucontrol->value.iec958.status[0] = (chip->spdif_pcm_bits >> 0) & 0xff;
@@ -1335,10 +1307,10 @@
 	return 0;
 }
 
-static int snd_ymfpci_spdif_stream_put(snd_kcontrol_t * kcontrol,
-					snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_spdif_stream_put(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int val;
 	int change;
 
@@ -1353,7 +1325,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t snd_ymfpci_spdif_stream __devinitdata =
+static struct snd_kcontrol_new snd_ymfpci_spdif_stream __devinitdata =
 {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE,
 	.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1363,7 +1335,7 @@
 	.put =		snd_ymfpci_spdif_stream_put
 };
 
-static int snd_ymfpci_drec_source_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info)
+static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info)
 {
 	static char *texts[3] = {"AC'97", "IEC958", "ZV Port"};
 
@@ -1376,9 +1348,9 @@
 	return 0;
 }
 
-static int snd_ymfpci_drec_source_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	u16 reg;
 
 	spin_lock_irq(&chip->reg_lock);
@@ -1391,9 +1363,9 @@
 	return 0;
 }
 
-static int snd_ymfpci_drec_source_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value)
+static int snd_ymfpci_drec_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	u16 reg, old_reg;
 
 	spin_lock_irq(&chip->reg_lock);
@@ -1407,7 +1379,7 @@
 	return reg != old_reg;
 }
 
-static snd_kcontrol_new_t snd_ymfpci_drec_source __devinitdata = {
+static struct snd_kcontrol_new snd_ymfpci_drec_source __devinitdata = {
 	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Direct Recording Source",
@@ -1426,8 +1398,8 @@
   .get = snd_ymfpci_get_single, .put = snd_ymfpci_put_single, \
   .private_value = ((reg) | ((shift) << 16)) }
 
-static int snd_ymfpci_info_single(snd_kcontrol_t *kcontrol,
-				  snd_ctl_elem_info_t *uinfo)
+static int snd_ymfpci_info_single(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	int reg = kcontrol->private_value & 0xffff;
 
@@ -1443,10 +1415,10 @@
 	return 0;
 }
 
-static int snd_ymfpci_get_single(snd_kcontrol_t *kcontrol,
-				 snd_ctl_elem_value_t *ucontrol)
+static int snd_ymfpci_get_single(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xffff;
 	unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
 	unsigned int mask = 1;
@@ -1461,10 +1433,10 @@
 	return 0;
 }
 
-static int snd_ymfpci_put_single(snd_kcontrol_t *kcontrol,
-				 snd_ctl_elem_value_t *ucontrol)
+static int snd_ymfpci_put_single(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xffff;
 	unsigned int shift = (kcontrol->private_value >> 16) & 0xff;
  	unsigned int mask = 1;
@@ -1493,7 +1465,7 @@
   .get = snd_ymfpci_get_double, .put = snd_ymfpci_put_double, \
   .private_value = reg }
 
-static int snd_ymfpci_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ymfpci_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	unsigned int reg = kcontrol->private_value;
 
@@ -1506,9 +1478,9 @@
 	return 0;
 }
 
-static int snd_ymfpci_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int reg = kcontrol->private_value;
 	unsigned int shift_left = 0, shift_right = 16, mask = 16383;
 	unsigned int val;
@@ -1523,9 +1495,9 @@
 	return 0;
 }
 
-static int snd_ymfpci_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int reg = kcontrol->private_value;
 	unsigned int shift_left = 0, shift_right = 16, mask = 16383;
 	int change;
@@ -1549,7 +1521,7 @@
 /*
  * 4ch duplication
  */
-static int snd_ymfpci_info_dup4ch(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int snd_ymfpci_info_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1558,16 +1530,16 @@
 	return 0;
 }
 
-static int snd_ymfpci_get_dup4ch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_get_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = chip->mode_dup4ch;
 	return 0;
 }
 
-static int snd_ymfpci_put_dup4ch(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	int change;
 	change = (ucontrol->value.integer.value[0] != chip->mode_dup4ch);
 	if (change)
@@ -1576,7 +1548,7 @@
 }
 
 
-static snd_kcontrol_new_t snd_ymfpci_controls[] __devinitdata = {
+static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = {
 YMFPCI_DOUBLE("Wave Playback Volume", 0, YDSXGR_NATIVEDACOUTVOL),
 YMFPCI_DOUBLE("Wave Capture Volume", 0, YDSXGR_NATIVEDACLOOPVOL),
 YMFPCI_DOUBLE("Digital Capture Volume", 0, YDSXGR_NATIVEDACINVOL),
@@ -1607,7 +1579,7 @@
  * GPIO
  */
 
-static int snd_ymfpci_get_gpio_out(ymfpci_t *chip, int pin)
+static int snd_ymfpci_get_gpio_out(struct snd_ymfpci *chip, int pin)
 {
 	u16 reg, mode;
 	unsigned long flags;
@@ -1627,7 +1599,7 @@
 	return (mode >> pin) & 1;
 }
 
-static int snd_ymfpci_set_gpio_out(ymfpci_t *chip, int pin, int enable)
+static int snd_ymfpci_set_gpio_out(struct snd_ymfpci *chip, int pin, int enable)
 {
 	u16 reg;
 	unsigned long flags;
@@ -1644,7 +1616,7 @@
 	return 0;
 }
 
-static int snd_ymfpci_gpio_sw_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_ymfpci_gpio_sw_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1653,17 +1625,17 @@
 	return 0;
 }
 
-static int snd_ymfpci_gpio_sw_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ymfpci_gpio_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	int pin = (int)kcontrol->private_value;
 	ucontrol->value.integer.value[0] = snd_ymfpci_get_gpio_out(chip, pin);
 	return 0;
 }
 
-static int snd_ymfpci_gpio_sw_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_ymfpci_gpio_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	int pin = (int)kcontrol->private_value;
 
 	if (snd_ymfpci_get_gpio_out(chip, pin) != ucontrol->value.integer.value[0]) {
@@ -1674,7 +1646,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_ymfpci_rear_shared __devinitdata = {
+static struct snd_kcontrol_new snd_ymfpci_rear_shared __devinitdata = {
 	.name = "Shared Rear/Line-In Switch",
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.info = snd_ymfpci_gpio_sw_info,
@@ -1687,8 +1659,8 @@
  * PCM voice volume
  */
 
-static int snd_ymfpci_pcm_vol_info(snd_kcontrol_t *kcontrol,
-				   snd_ctl_elem_info_t *uinfo)
+static int snd_ymfpci_pcm_vol_info(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -1697,10 +1669,10 @@
 	return 0;
 }
 
-static int snd_ymfpci_pcm_vol_get(snd_kcontrol_t *kcontrol,
-				  snd_ctl_elem_value_t *ucontrol)
+static int snd_ymfpci_pcm_vol_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int subs = kcontrol->id.subdevice;
 
 	ucontrol->value.integer.value[0] = chip->pcm_mixer[subs].left;
@@ -1708,12 +1680,12 @@
 	return 0;
 }
 
-static int snd_ymfpci_pcm_vol_put(snd_kcontrol_t *kcontrol,
-				  snd_ctl_elem_value_t *ucontrol)
+static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	ymfpci_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_ymfpci *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int subs = kcontrol->id.subdevice;
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 	unsigned long flags;
 
 	if (ucontrol->value.integer.value[0] != chip->pcm_mixer[subs].left ||
@@ -1721,10 +1693,10 @@
 		chip->pcm_mixer[subs].left = ucontrol->value.integer.value[0];
 		chip->pcm_mixer[subs].right = ucontrol->value.integer.value[1];
 
-		substream = (snd_pcm_substream_t *)kcontrol->private_value;
+		substream = (struct snd_pcm_substream *)kcontrol->private_value;
 		spin_lock_irqsave(&chip->voice_lock, flags);
 		if (substream->runtime && substream->runtime->private_data) {
-			ymfpci_pcm_t *ypcm = substream->runtime->private_data;
+			struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
 			ypcm->update_pcm_vol = 2;
 		}
 		spin_unlock_irqrestore(&chip->voice_lock, flags);
@@ -1733,7 +1705,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t snd_ymfpci_pcm_volume __devinitdata = {
+static struct snd_kcontrol_new snd_ymfpci_pcm_volume __devinitdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
 	.name = "PCM Playback Volume",
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -1748,26 +1720,26 @@
  *  Mixer routines
  */
 
-static void snd_ymfpci_mixer_free_ac97_bus(ac97_bus_t *bus)
+static void snd_ymfpci_mixer_free_ac97_bus(struct snd_ac97_bus *bus)
 {
-	ymfpci_t *chip = bus->private_data;
+	struct snd_ymfpci *chip = bus->private_data;
 	chip->ac97_bus = NULL;
 }
 
-static void snd_ymfpci_mixer_free_ac97(ac97_t *ac97)
+static void snd_ymfpci_mixer_free_ac97(struct snd_ac97 *ac97)
 {
-	ymfpci_t *chip = ac97->private_data;
+	struct snd_ymfpci *chip = ac97->private_data;
 	chip->ac97 = NULL;
 }
 
-int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch)
+int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch)
 {
-	ac97_template_t ac97;
-	snd_kcontrol_t *kctl;
-	snd_pcm_substream_t *substream;
+	struct snd_ac97_template ac97;
+	struct snd_kcontrol *kctl;
+	struct snd_pcm_substream *substream;
 	unsigned int idx;
 	int err;
-	static ac97_bus_ops_t ops = {
+	static struct snd_ac97_bus_ops ops = {
 		.write = snd_ymfpci_codec_write,
 		.read = snd_ymfpci_codec_read,
 	};
@@ -1843,9 +1815,9 @@
  * timer
  */
 
-static int snd_ymfpci_timer_start(snd_timer_t *timer)
+static int snd_ymfpci_timer_start(struct snd_timer *timer)
 {
-	ymfpci_t *chip;
+	struct snd_ymfpci *chip;
 	unsigned long flags;
 	unsigned int count;
 
@@ -1858,9 +1830,9 @@
 	return 0;
 }
 
-static int snd_ymfpci_timer_stop(snd_timer_t *timer)
+static int snd_ymfpci_timer_stop(struct snd_timer *timer)
 {
-	ymfpci_t *chip;
+	struct snd_ymfpci *chip;
 	unsigned long flags;
 
 	chip = snd_timer_chip(timer);
@@ -1870,7 +1842,7 @@
 	return 0;
 }
 
-static int snd_ymfpci_timer_precise_resolution(snd_timer_t *timer,
+static int snd_ymfpci_timer_precise_resolution(struct snd_timer *timer,
 					       unsigned long *num, unsigned long *den)
 {
 	*num = 1;
@@ -1878,7 +1850,7 @@
 	return 0;
 }
 
-static struct _snd_timer_hardware snd_ymfpci_timer_hw = {
+static struct snd_timer_hardware snd_ymfpci_timer_hw = {
 	.flags = SNDRV_TIMER_HW_AUTO,
 	.resolution = 20833, /* 1/fs = 20.8333...us */
 	.ticks = 0x8000,
@@ -1887,10 +1859,10 @@
 	.precise_resolution = snd_ymfpci_timer_precise_resolution,
 };
 
-int __devinit snd_ymfpci_timer(ymfpci_t *chip, int device)
+int __devinit snd_ymfpci_timer(struct snd_ymfpci *chip, int device)
 {
-	snd_timer_t *timer = NULL;
-	snd_timer_id_t tid;
+	struct snd_timer *timer = NULL;
+	struct snd_timer_id tid;
 	int err;
 
 	tid.dev_class = SNDRV_TIMER_CLASS_CARD;
@@ -1912,10 +1884,10 @@
  *  proc interface
  */
 
-static void snd_ymfpci_proc_read(snd_info_entry_t *entry, 
-				 snd_info_buffer_t * buffer)
+static void snd_ymfpci_proc_read(struct snd_info_entry *entry, 
+				 struct snd_info_buffer *buffer)
 {
-	ymfpci_t *chip = entry->private_data;
+	struct snd_ymfpci *chip = entry->private_data;
 	int i;
 	
 	snd_iprintf(buffer, "YMFPCI\n\n");
@@ -1923,9 +1895,9 @@
 		snd_iprintf(buffer, "%04x: %04x\n", i, snd_ymfpci_readl(chip, i));
 }
 
-static int __devinit snd_ymfpci_proc_init(snd_card_t * card, ymfpci_t *chip)
+static int __devinit snd_ymfpci_proc_init(struct snd_card *card, struct snd_ymfpci *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	
 	if (! snd_card_proc_new(card, "ymfpci", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, snd_ymfpci_proc_read);
@@ -1954,12 +1926,12 @@
 #endif
 }
 
-static void snd_ymfpci_enable_dsp(ymfpci_t *chip)
+static void snd_ymfpci_enable_dsp(struct snd_ymfpci *chip)
 {
 	snd_ymfpci_writel(chip, YDSXGR_CONFIG, 0x00000001);
 }
 
-static void snd_ymfpci_disable_dsp(ymfpci_t *chip)
+static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip)
 {
 	u32 val;
 	int timeout = 1000;
@@ -1976,7 +1948,7 @@
 
 #include "ymfpci_image.h"
 
-static void snd_ymfpci_download_image(ymfpci_t *chip)
+static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
 {
 	int i;
 	u16 ctrl;
@@ -2016,7 +1988,7 @@
 	snd_ymfpci_enable_dsp(chip);
 }
 
-static int __devinit snd_ymfpci_memalloc(ymfpci_t *chip)
+static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip)
 {
 	long size, playback_ctrl_size;
 	int voice, bank, reg;
@@ -2051,10 +2023,10 @@
 	ptr_addr += (playback_ctrl_size + 0x00ff) & ~0x00ff;
 	for (voice = 0; voice < YDSXG_PLAYBACK_VOICES; voice++) {
 		chip->voices[voice].number = voice;
-		chip->voices[voice].bank = (snd_ymfpci_playback_bank_t *)ptr;
+		chip->voices[voice].bank = (struct snd_ymfpci_playback_bank *)ptr;
 		chip->voices[voice].bank_addr = ptr_addr;
 		for (bank = 0; bank < 2; bank++) {
-			chip->bank_playback[voice][bank] = (snd_ymfpci_playback_bank_t *)ptr;
+			chip->bank_playback[voice][bank] = (struct snd_ymfpci_playback_bank *)ptr;
 			ptr += chip->bank_size_playback;
 			ptr_addr += chip->bank_size_playback;
 		}
@@ -2065,7 +2037,7 @@
 	chip->bank_base_capture_addr = ptr_addr;
 	for (voice = 0; voice < YDSXG_CAPTURE_VOICES; voice++)
 		for (bank = 0; bank < 2; bank++) {
-			chip->bank_capture[voice][bank] = (snd_ymfpci_capture_bank_t *)ptr;
+			chip->bank_capture[voice][bank] = (struct snd_ymfpci_capture_bank *)ptr;
 			ptr += chip->bank_size_capture;
 			ptr_addr += chip->bank_size_capture;
 		}
@@ -2075,7 +2047,7 @@
 	chip->bank_base_effect_addr = ptr_addr;
 	for (voice = 0; voice < YDSXG_EFFECT_VOICES; voice++)
 		for (bank = 0; bank < 2; bank++) {
-			chip->bank_effect[voice][bank] = (snd_ymfpci_effect_bank_t *)ptr;
+			chip->bank_effect[voice][bank] = (struct snd_ymfpci_effect_bank *)ptr;
 			ptr += chip->bank_size_effect;
 			ptr_addr += chip->bank_size_effect;
 		}
@@ -2114,7 +2086,7 @@
 	return 0;
 }
 
-static int snd_ymfpci_free(ymfpci_t *chip)
+static int snd_ymfpci_free(struct snd_ymfpci *chip)
 {
 	u16 ctrl;
 
@@ -2167,9 +2139,9 @@
 	return 0;
 }
 
-static int snd_ymfpci_dev_free(snd_device_t *device)
+static int snd_ymfpci_dev_free(struct snd_device *device)
 {
-	ymfpci_t *chip = device->device_data;
+	struct snd_ymfpci *chip = device->device_data;
 	return snd_ymfpci_free(chip);
 }
 
@@ -2203,11 +2175,13 @@
 };
 #define YDSXGR_NUM_SAVED_REGS	ARRAY_SIZE(saved_regs_index)
 
-static int snd_ymfpci_suspend(snd_card_t *card, pm_message_t state)
+int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
 {
-	ymfpci_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_ymfpci *chip = card->private_data;
 	unsigned int i;
 	
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 	snd_pcm_suspend_all(chip->pcm2);
 	snd_pcm_suspend_all(chip->pcm_spdif);
@@ -2218,18 +2192,21 @@
 	chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE);
 	snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0);
 	snd_ymfpci_disable_dsp(chip);
-	pci_disable_device(chip->pci);
+	pci_disable_device(pci);
+	pci_save_state(pci);
 	return 0;
 }
 
-static int snd_ymfpci_resume(snd_card_t *card)
+int snd_ymfpci_resume(struct pci_dev *pci)
 {
-	ymfpci_t *chip = card->pm_private_data;
+	struct snd_card *card = pci_get_drvdata(pci);
+	struct snd_ymfpci *chip = card->private_data;
 	unsigned int i;
 
-	pci_enable_device(chip->pci);
-	pci_set_master(chip->pci);
-	snd_ymfpci_aclink_reset(chip->pci);
+	pci_restore_state(pci);
+	pci_enable_device(pci);
+	pci_set_master(pci);
+	snd_ymfpci_aclink_reset(pci);
 	snd_ymfpci_codec_ready(chip, 0);
 	snd_ymfpci_download_image(chip);
 	udelay(100);
@@ -2246,18 +2223,19 @@
 		chip->active_bank = snd_ymfpci_readl(chip, YDSXGR_CTRLSELECT);
 		spin_unlock_irq(&chip->reg_lock);
 	}
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif /* CONFIG_PM */
 
-int __devinit snd_ymfpci_create(snd_card_t * card,
+int __devinit snd_ymfpci_create(struct snd_card *card,
 				struct pci_dev * pci,
 				unsigned short old_legacy_ctrl,
-				ymfpci_t ** rchip)
+				struct snd_ymfpci ** rchip)
 {
-	ymfpci_t *chip;
+	struct snd_ymfpci *chip;
 	int err;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_ymfpci_dev_free,
 	};
 	
@@ -2324,7 +2302,6 @@
 		snd_ymfpci_free(chip);
 		return -ENOMEM;
 	}
-	snd_card_set_pm_callback(card, snd_ymfpci_suspend, snd_ymfpci_resume, chip);
 #endif
 
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index d6918b4..77caf43 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -52,16 +52,13 @@
 /*
  */
 
-static dev_info_t dev_info = "snd-pdaudiocf";
-static snd_card_t *card_list[SNDRV_CARDS];
-static dev_link_t *dev_list;
+static struct snd_card *card_list[SNDRV_CARDS];
 
 /*
  * prototypes
  */
 static void pdacf_config(dev_link_t *link);
-static int pdacf_event(event_t event, int priority, event_callback_args_t *args);
-static void snd_pdacf_detach(dev_link_t *link);
+static void snd_pdacf_detach(struct pcmcia_device *p_dev);
 
 static void pdacf_release(dev_link_t *link)
 {
@@ -77,16 +74,12 @@
 /*
  * destructor
  */
-static int snd_pdacf_free(pdacf_t *pdacf)
+static int snd_pdacf_free(struct snd_pdacf *pdacf)
 {
 	dev_link_t *link = &pdacf->link;
 
 	pdacf_release(link);
 
-	/* Break the link with Card Services */
-	if (link->handle)
-		pcmcia_deregister_client(link->handle);
-
 	card_list[pdacf->index] = NULL;
 	pdacf->card = NULL;
 
@@ -94,23 +87,22 @@
 	return 0;
 }
 
-static int snd_pdacf_dev_free(snd_device_t *device)
+static int snd_pdacf_dev_free(struct snd_device *device)
 {
-	pdacf_t *chip = device->device_data;
+	struct snd_pdacf *chip = device->device_data;
 	return snd_pdacf_free(chip);
 }
 
 /*
  * snd_pdacf_attach - attach callback for cs
  */
-static dev_link_t *snd_pdacf_attach(void)
+static int snd_pdacf_attach(struct pcmcia_device *p_dev)
 {
-	client_reg_t client_reg;	/* Register with cardmgr */
-	dev_link_t *link;		/* Info for cardmgr */
-	int i, ret;
-	pdacf_t *pdacf;
-	snd_card_t *card;
-	static snd_device_ops_t ops = {
+	int i;
+	dev_link_t *link;               /* Info for cardmgr */
+	struct snd_pdacf *pdacf;
+	struct snd_card *card;
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_pdacf_dev_free,
 	};
 
@@ -122,26 +114,26 @@
 	}
 	if (i >= SNDRV_CARDS) {
 		snd_printk(KERN_ERR "pdacf: too many cards found\n");
-		return NULL;
+		return -EINVAL;
 	}
 	if (! enable[i])
-		return NULL; /* disabled explicitly */
+		return -ENODEV; /* disabled explicitly */
 
 	/* ok, create a card instance */
 	card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
 	if (card == NULL) {
 		snd_printk(KERN_ERR "pdacf: cannot create a card instance\n");
-		return NULL;
+		return -ENOMEM;
 	}
 
 	pdacf = snd_pdacf_create(card);
 	if (! pdacf)
-		return NULL;
+		return -EIO;
 
 	if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) {
 		kfree(pdacf);
 		snd_card_free(card);
-		return NULL;
+		return -ENODEV;
 	}
 
 	pdacf->index = i;
@@ -165,22 +157,12 @@
 	link->conf.Present = PRESENT_OPTION;
 
 	/* Chain drivers */
-	link->next = dev_list;
-	dev_list = link;
+	link->next = NULL;
 
-	/* Register with Card Services */
-	client_reg.dev_info = &dev_info;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
+	link->handle = p_dev;
+	pdacf_config(link);
 
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		snd_pdacf_detach(link);
-		return NULL;
-	}
-
-	return link;
+	return 0;
 }
 
 
@@ -194,10 +176,10 @@
  *
  * returns 0 if successful, or a negative error code.
  */
-static int snd_pdacf_assign_resources(pdacf_t *pdacf, int port, int irq)
+static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq)
 {
 	int err;
-	snd_card_t *card = pdacf->card;
+	struct snd_card *card = pdacf->card;
 
 	snd_printdd(KERN_DEBUG "pdacf assign resources: port = 0x%x, irq = %d\n", port, irq);
 	pdacf->port = port;
@@ -217,8 +199,6 @@
 	if (err < 0)
 		return err;
 
-	snd_card_set_pm_callback(card, snd_pdacf_suspend, snd_pdacf_resume, pdacf);
-
 	if ((err = snd_card_register(card)) < 0)
 		return err;
 
@@ -229,21 +209,13 @@
 /*
  * snd_pdacf_detach - detach callback for cs
  */
-static void snd_pdacf_detach(dev_link_t *link)
+static void snd_pdacf_detach(struct pcmcia_device *p_dev)
 {
-	pdacf_t *chip = link->priv;
+	dev_link_t *link = dev_to_instance(p_dev);
+	struct snd_pdacf *chip = link->priv;
 
 	snd_printdd(KERN_DEBUG "pdacf_detach called\n");
-	/* Remove the interface data from the linked list */
-	{
-		dev_link_t **linkp;
-		/* Locate device structure */
-		for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-			if (*linkp == link)
-				break;
-		if (*linkp)
-			*linkp = link->next;
-	}
+
 	if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED)
 		snd_pdacf_powerdown(chip);
 	chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */
@@ -261,7 +233,7 @@
 static void pdacf_config(dev_link_t *link)
 {
 	client_handle_t handle = link->handle;
-	pdacf_t *pdacf = link->priv;
+	struct snd_pdacf *pdacf = link->priv;
 	tuple_t tuple;
 	cisparse_t *parse = NULL;
 	config_info_t conf;
@@ -312,62 +284,51 @@
 	pcmcia_release_irq(link->handle, &link->irq);
 }
 
-/*
- * event callback
- */
-static int pdacf_event(event_t event, int priority, event_callback_args_t *args)
-{
-	dev_link_t *link = args->client_data;
-	pdacf_t *chip = link->priv;
-
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n");
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG) {
-			chip->chip_status |= PDAUDIOCF_STAT_IS_STALE;
-		}
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
-		link->state |= DEV_PRESENT;
-		pdacf_config(link);
-		break;
 #ifdef CONFIG_PM
-	case CS_EVENT_PM_SUSPEND:
-		snd_printdd(KERN_DEBUG "SUSPEND\n");
-		link->state |= DEV_SUSPEND;
-		if (chip) {
-			snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n");
-			snd_pdacf_suspend(chip->card, PMSG_SUSPEND);
-		}
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		snd_printdd(KERN_DEBUG "RESUME\n");
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		snd_printdd(KERN_DEBUG "CARD_RESET\n");
-		if (DEV_OK(link)) {
-			snd_printdd(KERN_DEBUG "requestconfig...\n");
-			pcmcia_request_configuration(link->handle, &link->conf);
-			if (chip) {
-				snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n");
-				snd_pdacf_resume(chip->card);
-			}
-		}
-		snd_printdd(KERN_DEBUG "resume done!\n");
-		break;
-#endif
+
+static int pdacf_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	struct snd_pdacf *chip = link->priv;
+
+	snd_printdd(KERN_DEBUG "SUSPEND\n");
+	link->state |= DEV_SUSPEND;
+	if (chip) {
+		snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n");
+		snd_pdacf_suspend(chip, PMSG_SUSPEND);
 	}
+
+	snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
 	return 0;
 }
 
+static int pdacf_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	struct snd_pdacf *chip = link->priv;
+
+	snd_printdd(KERN_DEBUG "RESUME\n");
+	link->state &= ~DEV_SUSPEND;
+
+	snd_printdd(KERN_DEBUG "CARD_RESET\n");
+	if (DEV_OK(link)) {
+		snd_printdd(KERN_DEBUG "requestconfig...\n");
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (chip) {
+			snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n");
+			snd_pdacf_resume(chip);
+		}
+	}
+	snd_printdd(KERN_DEBUG "resume done!\n");
+
+	return 0;
+}
+
+#endif
+
 /*
  * Module entry points
  */
@@ -382,10 +343,14 @@
 	.drv		= {
 		.name	= "snd-pdaudiocf",
 	},
-	.attach		= snd_pdacf_attach,
-	.event		= pdacf_event,
-	.detach		= snd_pdacf_detach,
+	.probe		= snd_pdacf_attach,
+	.remove		= snd_pdacf_detach,
 	.id_table	= snd_pdacf_ids,
+#ifdef CONFIG_PM
+	.suspend	= pdacf_suspend,
+	.resume		= pdacf_resume,
+#endif
+
 };
 
 static int __init init_pdacf(void)
@@ -396,7 +361,6 @@
 static void __exit exit_pdacf(void)
 {
 	pcmcia_unregister_driver(&pdacf_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_pdacf);
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
index c7a9628..2744f18 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h
@@ -83,8 +83,8 @@
 #define PDAUDIOCF_STAT_IS_CONFIGURED (1<<1)
 #define PDAUDIOCF_STAT_IS_SUSPENDED (1<<2)
 
-typedef struct {
-	snd_card_t *card;
+struct snd_pdacf {
+	struct snd_card *card;
 	int index;
 
 	unsigned long port;
@@ -96,12 +96,12 @@
 	struct tasklet_struct tq;
 
 	spinlock_t ak4117_lock;
-	ak4117_t *ak4117;
+	struct ak4117 *ak4117;
 
 	unsigned int chip_status;
 
-	snd_pcm_t *pcm;
-	snd_pcm_substream_t *pcm_substream;
+	struct snd_pcm *pcm;
+	struct snd_pcm_substream *pcm_substream;
 	unsigned int pcm_running: 1;
 	unsigned int pcm_channels;
 	unsigned int pcm_swab;
@@ -118,28 +118,28 @@
 	/* pcmcia stuff */
 	dev_link_t link;
 	dev_node_t node;
-} pdacf_t;
+};
 
-static inline void pdacf_reg_write(pdacf_t *chip, unsigned char reg, unsigned short val)
+static inline void pdacf_reg_write(struct snd_pdacf *chip, unsigned char reg, unsigned short val)
 {
 	outw(chip->regmap[reg>>1] = val, chip->port + reg);
 }
 
-static inline unsigned short pdacf_reg_read(pdacf_t *chip, unsigned char reg)
+static inline unsigned short pdacf_reg_read(struct snd_pdacf *chip, unsigned char reg)
 {
 	return inw(chip->port + reg);
 }
 
-pdacf_t *snd_pdacf_create(snd_card_t *card);
-int snd_pdacf_ak4117_create(pdacf_t *pdacf);
-void snd_pdacf_powerdown(pdacf_t *chip);
+struct snd_pdacf *snd_pdacf_create(struct snd_card *card);
+int snd_pdacf_ak4117_create(struct snd_pdacf *pdacf);
+void snd_pdacf_powerdown(struct snd_pdacf *chip);
 #ifdef CONFIG_PM
-int snd_pdacf_suspend(snd_card_t *card, pm_message_t state);
-int snd_pdacf_resume(snd_card_t *card);
+int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state);
+int snd_pdacf_resume(struct snd_pdacf *chip);
 #endif
-int snd_pdacf_pcm_new(pdacf_t *chip);
+int snd_pdacf_pcm_new(struct snd_pdacf *chip);
 irqreturn_t pdacf_interrupt(int irq, void *dev, struct pt_regs *regs);
 void pdacf_tasklet(unsigned long private_data);
-void pdacf_reinit(pdacf_t *chip, int resume);
+void pdacf_reinit(struct snd_pdacf *chip, int resume);
 
 #endif /* __PDAUDIOCF_H */
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index 0208c54..bd0d70f 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -30,7 +30,7 @@
  */
 static unsigned char pdacf_ak4117_read(void *private_data, unsigned char reg)
 {
-	pdacf_t *chip = private_data;
+	struct snd_pdacf *chip = private_data;
 	unsigned long timeout;
 	unsigned long flags;
 	unsigned char res;
@@ -62,7 +62,7 @@
 
 static void pdacf_ak4117_write(void *private_data, unsigned char reg, unsigned char val)
 {
-	pdacf_t *chip = private_data;
+	struct snd_pdacf *chip = private_data;
 	unsigned long timeout;
 	unsigned long flags;
 
@@ -81,7 +81,7 @@
 }
 
 #if 0
-void pdacf_dump(pdacf_t *chip)
+void pdacf_dump(struct snd_pdacf *chip)
 {
 	printk("PDAUDIOCF DUMP (0x%lx):\n", chip->port);
 	printk("WPD         : 0x%x\n", inw(chip->port + PDAUDIOCF_REG_WDP));
@@ -94,7 +94,7 @@
 }
 #endif
 
-static int pdacf_reset(pdacf_t *chip, int powerdown)
+static int pdacf_reset(struct snd_pdacf *chip, int powerdown)
 {
 	u16 val;
 	
@@ -117,7 +117,7 @@
 	return 0;
 }
 
-void pdacf_reinit(pdacf_t *chip, int resume)
+void pdacf_reinit(struct snd_pdacf *chip, int resume)
 {
 	pdacf_reset(chip, 0);
 	if (resume)
@@ -127,10 +127,10 @@
 	pdacf_reg_write(chip, PDAUDIOCF_REG_IER, chip->regmap[PDAUDIOCF_REG_IER>>1]);
 }
 
-static void pdacf_proc_read(snd_info_entry_t * entry,
-                            snd_info_buffer_t * buffer)
+static void pdacf_proc_read(struct snd_info_entry * entry,
+                            struct snd_info_buffer *buffer)
 {
-	pdacf_t *chip = entry->private_data;
+	struct snd_pdacf *chip = entry->private_data;
 	u16 tmp;
 
 	snd_iprintf(buffer, "PDAudioCF\n\n");
@@ -139,17 +139,17 @@
 	                                   
 }
 
-static void pdacf_proc_init(pdacf_t *chip)
+static void pdacf_proc_init(struct snd_pdacf *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 
 	if (! snd_card_proc_new(chip->card, "pdaudiocf", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, pdacf_proc_read);
 }
 
-pdacf_t *snd_pdacf_create(snd_card_t *card)
+struct snd_pdacf *snd_pdacf_create(struct snd_card *card)
 {
-	pdacf_t *chip;
+	struct snd_pdacf *chip;
 
 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 	if (chip == NULL)
@@ -164,9 +164,9 @@
 	return chip;
 }
 
-static void snd_pdacf_ak4117_change(ak4117_t *ak4117, unsigned char c0, unsigned char c1)
+static void snd_pdacf_ak4117_change(struct ak4117 *ak4117, unsigned char c0, unsigned char c1)
 {
-	pdacf_t *chip = ak4117->change_callback_private;
+	struct snd_pdacf *chip = ak4117->change_callback_private;
 	unsigned long flags;
 	u16 val;
 
@@ -182,7 +182,7 @@
 	spin_unlock_irqrestore(&chip->reg_lock, flags);
 }
 
-int snd_pdacf_ak4117_create(pdacf_t *chip)
+int snd_pdacf_ak4117_create(struct snd_pdacf *chip)
 {
 	int err;
 	u16 val;
@@ -238,7 +238,7 @@
 	return 0;
 }
 
-void snd_pdacf_powerdown(pdacf_t *chip)
+void snd_pdacf_powerdown(struct snd_pdacf *chip)
 {
 	u16 val;
 
@@ -255,11 +255,11 @@
 
 #ifdef CONFIG_PM
 
-int snd_pdacf_suspend(snd_card_t *card, pm_message_t state)
+int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state)
 {
-	pdacf_t *chip = card->pm_private_data;
 	u16 val;
 	
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
 	snd_pcm_suspend_all(chip->pcm);
 	/* disable interrupts, but use direct write to preserve old register value in chip->regmap */
 	val = inw(chip->port + PDAUDIOCF_REG_IER);
@@ -270,14 +270,13 @@
 	return 0;
 }
 
-static inline int check_signal(pdacf_t *chip)
+static inline int check_signal(struct snd_pdacf *chip)
 {
 	return (chip->ak4117->rcs0 & AK4117_UNLCK) == 0;
 }
 
-int snd_pdacf_resume(snd_card_t *card)
+int snd_pdacf_resume(struct snd_pdacf *chip)
 {
-	pdacf_t *chip = card->pm_private_data;
 	int timeout = 40;
 
 	pdacf_reinit(chip, 1);
@@ -286,6 +285,7 @@
 	       (snd_ak4117_external_rate(chip->ak4117) <= 0 || !check_signal(chip)))
 		mdelay(1);
 	chip->chip_status &= ~PDAUDIOCF_STAT_IS_SUSPENDED;
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
 #endif
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
index 255b634..7c5f21e 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
@@ -28,7 +28,7 @@
  */
 irqreturn_t pdacf_interrupt(int irq, void *dev, struct pt_regs *regs)
 {
-	pdacf_t *chip = dev;
+	struct snd_pdacf *chip = dev;
 	unsigned short stat;
 
 	if ((chip->chip_status & (PDAUDIOCF_STAT_IS_STALE|
@@ -204,7 +204,7 @@
 	}
 }
 
-static void pdacf_transfer(pdacf_t *chip, unsigned int size, unsigned int off)
+static void pdacf_transfer(struct snd_pdacf *chip, unsigned int size, unsigned int off)
 {
 	unsigned long rdp_port = chip->port + PDAUDIOCF_REG_MD;
 	unsigned int xor = chip->pcm_xor;
@@ -258,7 +258,7 @@
 
 void pdacf_tasklet(unsigned long private_data)
 {
-	pdacf_t *chip = (pdacf_t *) private_data;
+	struct snd_pdacf *chip = (struct snd_pdacf *) private_data;
 	int size, off, cont, rdp, wdp;
 
 	if ((chip->chip_status & (PDAUDIOCF_STAT_IS_STALE|PDAUDIOCF_STAT_IS_CONFIGURED)) != PDAUDIOCF_STAT_IS_CONFIGURED)
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
index 20b86d8..09cb250 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_pcm.c
@@ -34,7 +34,7 @@
  */
 
 /* get the physical page pointer on the given offset */
-static struct page *snd_pcm_get_vmalloc_page(snd_pcm_substream_t *subs, unsigned long offset)
+static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, unsigned long offset)
 {
 	void *pageptr = subs->runtime->dma_area + offset;
 	return vmalloc_to_page(pageptr);
@@ -44,9 +44,9 @@
  * hw_params callback
  * NOTE: this may be called not only once per pcm open!
  */
-static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size)
+static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	if (runtime->dma_area) {
 		if (runtime->dma_bytes >= size)
 			return 0; /* already enough large */
@@ -63,9 +63,9 @@
  * hw_free callback
  * NOTE: this may be called not only once per pcm open!
  */
-static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs)
+static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	if (runtime->dma_area) {
 		vfree(runtime->dma_area);
 		runtime->dma_area = NULL;
@@ -76,7 +76,7 @@
 /*
  * clear the SRAM contents
  */
-static int pdacf_pcm_clear_sram(pdacf_t *chip)
+static int pdacf_pcm_clear_sram(struct snd_pdacf *chip)
 {
 	int max_loop = 64 * 1024;
 
@@ -91,10 +91,10 @@
 /*
  * pdacf_pcm_trigger - trigger callback for capture
  */
-static int pdacf_pcm_trigger(snd_pcm_substream_t *subs, int cmd)
+static int pdacf_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
 {
-	pdacf_t *chip = snd_pcm_substream_chip(subs);
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	int inc, ret = 0, rate;
 	unsigned short mask, val, tmp;
 
@@ -146,8 +146,8 @@
 /*
  * pdacf_pcm_hw_params - hw_params callback for playback and capture
  */
-static int pdacf_pcm_hw_params(snd_pcm_substream_t *subs,
-				     snd_pcm_hw_params_t *hw_params)
+static int pdacf_pcm_hw_params(struct snd_pcm_substream *subs,
+				     struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params));
 }
@@ -155,7 +155,7 @@
 /*
  * pdacf_pcm_hw_free - hw_free callback for playback and capture
  */
-static int pdacf_pcm_hw_free(snd_pcm_substream_t *subs)
+static int pdacf_pcm_hw_free(struct snd_pcm_substream *subs)
 {
 	return snd_pcm_free_vmalloc_buffer(subs);
 }
@@ -163,10 +163,10 @@
 /*
  * pdacf_pcm_prepare - prepare callback for playback and capture
  */
-static int pdacf_pcm_prepare(snd_pcm_substream_t *subs)
+static int pdacf_pcm_prepare(struct snd_pcm_substream *subs)
 {
-	pdacf_t *chip = snd_pcm_substream_chip(subs);
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	u16 val, nval, aval;
 
 	if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE)
@@ -239,7 +239,7 @@
  * capture hw information
  */
 
-static snd_pcm_hardware_t pdacf_pcm_capture_hw = {
+static struct snd_pcm_hardware pdacf_pcm_capture_hw = {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME |
 				 SNDRV_PCM_INFO_MMAP_VALID),
@@ -269,10 +269,10 @@
 /*
  * pdacf_pcm_capture_open - open callback for capture
  */
-static int pdacf_pcm_capture_open(snd_pcm_substream_t *subs)
+static int pdacf_pcm_capture_open(struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
-	pdacf_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pcm_runtime *runtime = subs->runtime;
+	struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
 
 	if (chip->chip_status & PDAUDIOCF_STAT_IS_STALE)
 		return -EBUSY;
@@ -287,9 +287,9 @@
 /*
  * pdacf_pcm_capture_close - close callback for capture
  */
-static int pdacf_pcm_capture_close(snd_pcm_substream_t *subs)
+static int pdacf_pcm_capture_close(struct snd_pcm_substream *subs)
 {
-	pdacf_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
 
 	if (!chip)
 		return -EINVAL;
@@ -302,16 +302,16 @@
 /*
  * pdacf_pcm_capture_pointer - pointer callback for capture
  */
-static snd_pcm_uframes_t pdacf_pcm_capture_pointer(snd_pcm_substream_t *subs)
+static snd_pcm_uframes_t pdacf_pcm_capture_pointer(struct snd_pcm_substream *subs)
 {
-	pdacf_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pdacf *chip = snd_pcm_substream_chip(subs);
 	return chip->pcm_hwptr;
 }
 
 /*
  * operators for PCM capture
  */
-static snd_pcm_ops_t pdacf_pcm_capture_ops = {
+static struct snd_pcm_ops pdacf_pcm_capture_ops = {
 	.open =		pdacf_pcm_capture_open,
 	.close =	pdacf_pcm_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -325,20 +325,11 @@
 
 
 /*
- * free callback for pcm
- */
-static void snd_pdacf_pcm_free(snd_pcm_t *pcm)
-{
-	pdacf_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-}
-
-/*
  * snd_pdacf_pcm_new - create and initialize a pcm
  */
-int snd_pdacf_pcm_new(pdacf_t *chip)
+int snd_pdacf_pcm_new(struct snd_pdacf *chip)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	err = snd_pcm_new(chip->card, "PDAudioCF", 0, 0, 1, &pcm);
@@ -348,7 +339,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pdacf_pcm_capture_ops);
 
 	pcm->private_data = chip;
-	pcm->private_free = snd_pdacf_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcm = pcm;
diff --git a/sound/pcmcia/vx/vxp_mixer.c b/sound/pcmcia/vx/vxp_mixer.c
index aeaef3d..9450149 100644
--- a/sound/pcmcia/vx/vxp_mixer.c
+++ b/sound/pcmcia/vx/vxp_mixer.c
@@ -31,7 +31,7 @@
 /*
  * mic level control (for VXPocket)
  */
-static int vx_mic_level_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -40,17 +40,17 @@
 	return 0;
 }
 
-static int vx_mic_level_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 	ucontrol->value.integer.value[0] = chip->mic_level;
 	return 0;
 }
 
-static int vx_mic_level_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 	down(&_chip->mixer_mutex);
 	if (chip->mic_level != ucontrol->value.integer.value[0]) {
@@ -63,7 +63,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vx_control_mic_level = {
+static struct snd_kcontrol_new vx_control_mic_level = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Mic Capture Volume",
 	.info =		vx_mic_level_info,
@@ -74,7 +74,7 @@
 /*
  * mic boost level control (for VXP440)
  */
-static int vx_mic_boost_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int vx_mic_boost_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -83,17 +83,17 @@
 	return 0;
 }
 
-static int vx_mic_boost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 	ucontrol->value.integer.value[0] = chip->mic_level;
 	return 0;
 }
 
-static int vx_mic_boost_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	vx_core_t *_chip = snd_kcontrol_chip(kcontrol);
+	struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 	down(&_chip->mixer_mutex);
 	if (chip->mic_level != ucontrol->value.integer.value[0]) {
@@ -106,7 +106,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t vx_control_mic_boost = {
+static struct snd_kcontrol_new vx_control_mic_boost = {
 	.iface =	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name =		"Mic Boost",
 	.info =		vx_mic_boost_info,
@@ -115,7 +115,7 @@
 };
 
 
-int vxp_add_mic_controls(vx_core_t *_chip)
+int vxp_add_mic_controls(struct vx_core *_chip)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 	int err;
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
index 6f15c3d..7f82f61 100644
--- a/sound/pcmcia/vx/vxp_ops.c
+++ b/sound/pcmcia/vx/vxp_ops.c
@@ -49,7 +49,7 @@
 };
 
 
-static inline unsigned long vxp_reg_addr(vx_core_t *_chip, int reg)
+static inline unsigned long vxp_reg_addr(struct vx_core *_chip, int reg)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 	return chip->port + vxp_reg_offset[reg];
@@ -59,7 +59,7 @@
  * snd_vx_inb - read a byte from the register
  * @offset: register offset
  */
-static unsigned char vxp_inb(vx_core_t *chip, int offset)
+static unsigned char vxp_inb(struct vx_core *chip, int offset)
 {
 	return inb(vxp_reg_addr(chip, offset));
 }
@@ -69,7 +69,7 @@
  * @offset: the register offset
  * @val: the value to write
  */
-static void vxp_outb(vx_core_t *chip, int offset, unsigned char val)
+static void vxp_outb(struct vx_core *chip, int offset, unsigned char val)
 {
 	outb(val, vxp_reg_addr(chip, offset));
 }
@@ -78,9 +78,9 @@
  * redefine macros to call directly
  */
 #undef vx_inb
-#define vx_inb(chip,reg)	vxp_inb((vx_core_t*)(chip), VX_##reg)
+#define vx_inb(chip,reg)	vxp_inb((struct vx_core *)(chip), VX_##reg)
 #undef vx_outb
-#define vx_outb(chip,reg,val)	vxp_outb((vx_core_t*)(chip), VX_##reg,val)
+#define vx_outb(chip,reg,val)	vxp_outb((struct vx_core *)(chip), VX_##reg,val)
 
 
 /*
@@ -88,7 +88,7 @@
  *
  * returns zero if a magic word is detected, or a negative error code.
  */
-static int vx_check_magic(vx_core_t *chip)
+static int vx_check_magic(struct vx_core *chip)
 {
 	unsigned long end_time = jiffies + HZ / 5;
 	int c;
@@ -96,7 +96,7 @@
 		c = vx_inb(chip, CDSP);
 		if (c == CDSP_MAGIC)
 			return 0;
-		snd_vx_delay(chip, 10);
+		msleep(10);
 	} while (time_after_eq(end_time, jiffies));
 	snd_printk(KERN_ERR "cannot find xilinx magic word (%x)\n", c);
 	return -EIO;
@@ -109,7 +109,7 @@
 
 #define XX_DSP_RESET_WAIT_TIME		2	/* ms */
 
-static void vxp_reset_dsp(vx_core_t *_chip)
+static void vxp_reset_dsp(struct vx_core *_chip)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 
@@ -127,26 +127,26 @@
 /*
  * reset codec bit
  */
-static void vxp_reset_codec(vx_core_t *_chip)
+static void vxp_reset_codec(struct vx_core *_chip)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 
 	/* Set the reset CODEC bit to 1. */
 	vx_outb(chip, CDSP, chip->regCDSP | VXP_CDSP_CODEC_RESET_MASK);
 	vx_inb(chip, CDSP);
-	snd_vx_delay(_chip, 10);
+	msleep(10);
 	/* Set the reset CODEC bit to 0. */
 	chip->regCDSP &= ~VXP_CDSP_CODEC_RESET_MASK;
 	vx_outb(chip, CDSP, chip->regCDSP);
 	vx_inb(chip, CDSP);
-	snd_vx_delay(_chip, 1);
+	msleep(1);
 }
 
 /*
  * vx_load_xilinx_binary - load the xilinx binary image
  * the binary image is the binary array converted from the bitstream file.
  */
-static int vxp_load_xilinx_binary(vx_core_t *_chip, const struct firmware *fw)
+static int vxp_load_xilinx_binary(struct vx_core *_chip, const struct firmware *fw)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 	unsigned int i;
@@ -207,7 +207,7 @@
 	vx_outb(chip, ICR, ICR_HF0);
 
 	/* TEMPO 250ms : wait until Xilinx is downloaded */
-	snd_vx_delay(_chip, 300);
+	msleep(300);
 
 	/* test magical word */
 	if (vx_check_magic(_chip) < 0)
@@ -221,7 +221,7 @@
 	chip->regDIALOG |= VXP_DLG_XILINX_REPROG_MASK;
 	vx_outb(chip, DIALOG, chip->regDIALOG);
 	vx_inb(chip, DIALOG);
-	snd_vx_delay(_chip, 10);
+	msleep(10);
 	chip->regDIALOG &= ~VXP_DLG_XILINX_REPROG_MASK;
 	vx_outb(chip, DIALOG, chip->regDIALOG);
 	vx_inb(chip, DIALOG);
@@ -244,7 +244,7 @@
 /*
  * vxp_load_dsp - load_dsp callback
  */
-static int vxp_load_dsp(vx_core_t *vx, int index, const struct firmware *fw)
+static int vxp_load_dsp(struct vx_core *vx, int index, const struct firmware *fw)
 {
 	int err;
 
@@ -279,7 +279,7 @@
  *
  * spinlock held!
  */
-static int vxp_test_and_ack(vx_core_t *_chip)
+static int vxp_test_and_ack(struct vx_core *_chip)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 
@@ -306,7 +306,7 @@
 /*
  * vx_validate_irq - enable/disable IRQ
  */
-static void vxp_validate_irq(vx_core_t *_chip, int enable)
+static void vxp_validate_irq(struct vx_core *_chip, int enable)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 
@@ -322,7 +322,7 @@
  * vx_setup_pseudo_dma - set up the pseudo dma read/write mode.
  * @do_write: 0 = read, 1 = set up for DMA write
  */
-static void vx_setup_pseudo_dma(vx_core_t *_chip, int do_write)
+static void vx_setup_pseudo_dma(struct vx_core *_chip, int do_write)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 
@@ -342,7 +342,7 @@
 /*
  * vx_release_pseudo_dma - disable the pseudo-DMA mode
  */
-static void vx_release_pseudo_dma(vx_core_t *_chip)
+static void vx_release_pseudo_dma(struct vx_core *_chip)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 
@@ -362,8 +362,8 @@
  * data size must be aligned to 6 bytes to ensure the 24bit alignment on DSP.
  * NB: call with a certain lock!
  */
-static void vxp_dma_write(vx_core_t *chip, snd_pcm_runtime_t *runtime,
-			  vx_pipe_t *pipe, int count)
+static void vxp_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+			  struct vx_pipe *pipe, int count)
 {
 	long port = vxp_reg_addr(chip, VX_DMA);
 	int offset = pipe->hw_ptr;
@@ -401,8 +401,8 @@
  * the read length must be aligned to 6 bytes, as well as write.
  * NB: call with a certain lock!
  */
-static void vxp_dma_read(vx_core_t *chip, snd_pcm_runtime_t *runtime,
-			 vx_pipe_t *pipe, int count)
+static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
+			 struct vx_pipe *pipe, int count)
 {
 	struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip;
 	long port = vxp_reg_addr(chip, VX_DMA);
@@ -442,7 +442,7 @@
 /*
  * write a codec data (24bit)
  */
-static void vxp_write_codec_reg(vx_core_t *chip, int codec, unsigned int data)
+static void vxp_write_codec_reg(struct vx_core *chip, int codec, unsigned int data)
 {
 	int i;
 
@@ -465,7 +465,7 @@
  * vx_set_mic_boost - set mic boost level (on vxp440 only)
  * @boost: 0 = 20dB, 1 = +38dB
  */
-void vx_set_mic_boost(vx_core_t *chip, int boost)
+void vx_set_mic_boost(struct vx_core *chip, int boost)
 {
 	struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip;
 	unsigned long flags;
@@ -508,7 +508,7 @@
  * vx_set_mic_level - set mic level (on vxpocket only)
  * @level: the mic level = 0 - 8 (max)
  */
-void vx_set_mic_level(vx_core_t *chip, int level)
+void vx_set_mic_level(struct vx_core *chip, int level)
 {
 	struct snd_vxpocket *pchip = (struct snd_vxpocket *)chip;
 	unsigned long flags;
@@ -528,7 +528,7 @@
 /*
  * change the input audio source
  */
-static void vxp_change_audio_source(vx_core_t *_chip, int src)
+static void vxp_change_audio_source(struct vx_core *_chip, int src)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 
@@ -568,7 +568,7 @@
  * change the clock source
  * source = INTERNAL_QUARTZ or UER_SYNC
  */
-static void vxp_set_clock_source(vx_core_t *_chip, int source)
+static void vxp_set_clock_source(struct vx_core *_chip, int source)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 
@@ -583,7 +583,7 @@
 /*
  * reset the board
  */
-static void vxp_reset_board(vx_core_t *_chip, int cold_reset)
+static void vxp_reset_board(struct vx_core *_chip, int cold_reset)
 {
 	struct snd_vxpocket *chip = (struct snd_vxpocket *)_chip;
 
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 1e8f16b..66900d2 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -55,11 +55,6 @@
  */
 
 static unsigned int card_alloc;
-static dev_link_t *dev_list;		/* Linked list of devices */
-static dev_info_t dev_info = "snd-vxpocket";
-
-
-static int vxpocket_event(event_t event, int priority, event_callback_args_t *args);
 
 
 /*
@@ -73,19 +68,14 @@
 		pcmcia_release_irq(link->handle, &link->irq);
 		link->state &= ~DEV_CONFIG;
 	}
-	if (link->handle) {
-		/* Break the link with Card Services */
-		pcmcia_deregister_client(link->handle);
-		link->handle = NULL;
-	}
 }
 
 /*
  * destructor, called from snd_card_free_in_thread()
  */
-static int snd_vxpocket_dev_free(snd_device_t *device)
+static int snd_vxpocket_dev_free(struct snd_device *device)
 {
-	vx_core_t *chip = device->device_data;
+	struct vx_core *chip = device->device_data;
 
 	snd_vx_free_firmware(chip);
 	kfree(chip);
@@ -142,19 +132,17 @@
 /*
  * create vxpocket instance
  */
-static struct snd_vxpocket *snd_vxpocket_new(snd_card_t *card, int ibl)
+static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
 {
-	client_reg_t client_reg;	/* Register with cardmgr */
 	dev_link_t *link;		/* Info for cardmgr */
-	vx_core_t *chip;
+	struct vx_core *chip;
 	struct snd_vxpocket *vxp;
-	int ret;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_vxpocket_dev_free,
 	};
 
 	chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops,
-			     sizeof(struct snd_vxpocket) - sizeof(vx_core_t));
+			     sizeof(struct snd_vxpocket) - sizeof(struct vx_core));
 	if (! chip)
 		return NULL;
 
@@ -184,26 +172,6 @@
 	link->conf.ConfigIndex = 1;
 	link->conf.Present = PRESENT_OPTION;
 
-	/* Register with Card Services */
-	memset(&client_reg, 0, sizeof(client_reg));
-	client_reg.dev_info = &dev_info;
-	client_reg.EventMask = 
-		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL
-#ifdef CONFIG_PM
-		| CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET
-		| CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME
-#endif
-		;
-	client_reg.event_handler = &vxpocket_event;
-	client_reg.Version = 0x0210;
-	client_reg.event_callback_args.client_data = link;
-
-	ret = pcmcia_register_client(&link->handle, &client_reg);
-	if (ret != CS_SUCCESS) {
-		cs_error(link->handle, RegisterClient, ret);
-		return NULL;
-	}
-
 	return vxp;
 }
 
@@ -218,10 +186,10 @@
  *
  * returns 0 if successful, or a negative error code.
  */
-static int snd_vxpocket_assign_resources(vx_core_t *chip, int port, int irq)
+static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq)
 {
 	int err;
-	snd_card_t *card = chip->card;
+	struct snd_card *card = chip->card;
 	struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
 
 	snd_printdd(KERN_DEBUG "vxpocket assign resources: port = 0x%x, irq = %d\n", port, irq);
@@ -250,7 +218,7 @@
 static void vxpocket_config(dev_link_t *link)
 {
 	client_handle_t handle = link->handle;
-	vx_core_t *chip = link->priv;
+	struct vx_core *chip = link->priv;
 	struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
 	tuple_t tuple;
 	cisparse_t *parse;
@@ -317,69 +285,57 @@
 	kfree(parse);
 }
 
-
-/*
- * event callback
- */
-static int vxpocket_event(event_t event, int priority, event_callback_args_t *args)
-{
-	dev_link_t *link = args->client_data;
-	vx_core_t *chip = link->priv;
-
-	switch (event) {
-	case CS_EVENT_CARD_REMOVAL:
-		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n");
-		link->state &= ~DEV_PRESENT;
-		if (link->state & DEV_CONFIG)
-			chip->chip_status |= VX_STAT_IS_STALE;
-		break;
-	case CS_EVENT_CARD_INSERTION:
-		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n");
-		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-		vxpocket_config(link);
-		break;
 #ifdef CONFIG_PM
-	case CS_EVENT_PM_SUSPEND:
-		snd_printdd(KERN_DEBUG "SUSPEND\n");
-		link->state |= DEV_SUSPEND;
-		if (chip && chip->card->pm_suspend) {
-			snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
-			chip->card->pm_suspend(chip->card, PMSG_SUSPEND);
-		}
-		/* Fall through... */
-	case CS_EVENT_RESET_PHYSICAL:
-		snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
-		if (link->state & DEV_CONFIG)
-			pcmcia_release_configuration(link->handle);
-		break;
-	case CS_EVENT_PM_RESUME:
-		snd_printdd(KERN_DEBUG "RESUME\n");
-		link->state &= ~DEV_SUSPEND;
-		/* Fall through... */
-	case CS_EVENT_CARD_RESET:
-		snd_printdd(KERN_DEBUG "CARD_RESET\n");
-		if (DEV_OK(link)) {
-			//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
-			snd_printdd(KERN_DEBUG "requestconfig...\n");
-			pcmcia_request_configuration(link->handle, &link->conf);
-			if (chip && chip->card->pm_resume) {
-				snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
-				chip->card->pm_resume(chip->card);
-			}
-		}
-		snd_printdd(KERN_DEBUG "resume done!\n");
-		break;
-#endif
+
+static int vxp_suspend(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	struct vx_core *chip = link->priv;
+
+	snd_printdd(KERN_DEBUG "SUSPEND\n");
+	link->state |= DEV_SUSPEND;
+	if (chip) {
+		snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
+		snd_vx_suspend(chip, PMSG_SUSPEND);
 	}
+	snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n");
+	if (link->state & DEV_CONFIG)
+		pcmcia_release_configuration(link->handle);
+
 	return 0;
 }
 
+static int vxp_resume(struct pcmcia_device *dev)
+{
+	dev_link_t *link = dev_to_instance(dev);
+	struct vx_core *chip = link->priv;
+
+	snd_printdd(KERN_DEBUG "RESUME\n");
+	link->state &= ~DEV_SUSPEND;
+
+	snd_printdd(KERN_DEBUG "CARD_RESET\n");
+	if (DEV_OK(link)) {
+		//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
+		snd_printdd(KERN_DEBUG "requestconfig...\n");
+		pcmcia_request_configuration(link->handle, &link->conf);
+		if (chip) {
+			snd_printdd(KERN_DEBUG "calling snd_vx_resume\n");
+			snd_vx_resume(chip);
+		}
+	}
+	snd_printdd(KERN_DEBUG "resume done!\n");
+
+	return 0;
+}
+
+#endif
+
 
 /*
  */
-static dev_link_t *vxpocket_attach(void)
+static int vxpocket_attach(struct pcmcia_device *p_dev)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	struct snd_vxpocket *vxp;
 	int i;
 
@@ -390,54 +346,52 @@
 	}
 	if (i >= SNDRV_CARDS) {
 		snd_printk(KERN_ERR "vxpocket: too many cards found\n");
-		return NULL;
+		return -EINVAL;
 	}
 	if (! enable[i])
-		return NULL; /* disabled explicitly */
+		return -ENODEV; /* disabled explicitly */
 
 	/* ok, create a card instance */
 	card = snd_card_new(index[i], id[i], THIS_MODULE, 0);
 	if (card == NULL) {
 		snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n");
-		return NULL;
+		return -ENOMEM;
 	}
 
 	vxp = snd_vxpocket_new(card, ibl[i]);
 	if (! vxp) {
 		snd_card_free(card);
-		return NULL;
+		return -ENODEV;
 	}
+	card->private_data = vxp;
 
 	vxp->index = i;
 	card_alloc |= 1 << i;
 
 	/* Chain drivers */
-	vxp->link.next = dev_list;
-	dev_list = &vxp->link;
+	vxp->link.next = NULL;
 
-	return &vxp->link;
+	vxp->link.handle = p_dev;
+	vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+	p_dev->instance = &vxp->link;
+	vxpocket_config(&vxp->link);
+
+	return 0;
 }
 
-static void vxpocket_detach(dev_link_t *link)
+static void vxpocket_detach(struct pcmcia_device *p_dev)
 {
+	dev_link_t *link = dev_to_instance(p_dev);
 	struct snd_vxpocket *vxp;
-	vx_core_t *chip;
-	dev_link_t **linkp;
+	struct vx_core *chip;
 
 	if (! link)
 		return;
 
 	vxp = link->priv;
-	chip = (vx_core_t *)vxp;
+	chip = (struct vx_core *)vxp;
 	card_alloc &= ~(1 << vxp->index);
 
-	/* Remove the interface data from the linked list */
-	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-		if (*linkp == link) {
-			*linkp = link->next;
-			break;
-		}
-
 	chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */
 	snd_card_disconnect(chip->card);
 	vxpocket_release(link);
@@ -459,10 +413,13 @@
 	.drv		= {
 		.name	= "snd-vxpocket",
 	},
-	.attach		= vxpocket_attach,
-	.detach		= vxpocket_detach,
-	.event		= vxpocket_event,
+	.probe		= vxpocket_attach,
+	.remove		= vxpocket_detach,
 	.id_table	= vxp_ids,
+#ifdef CONFIG_PM
+	.suspend	= vxp_suspend,
+	.resume		= vxp_resume,
+#endif
 };
 
 static int __init init_vxpocket(void)
@@ -473,7 +430,6 @@
 static void __exit exit_vxpocket(void)
 {
 	pcmcia_unregister_driver(&vxp_cs_driver);
-	BUG_ON(dev_list != NULL);
 }
 
 module_init(init_vxpocket);
diff --git a/sound/pcmcia/vx/vxpocket.h b/sound/pcmcia/vx/vxpocket.h
index 70754aa..67efae3 100644
--- a/sound/pcmcia/vx/vxpocket.h
+++ b/sound/pcmcia/vx/vxpocket.h
@@ -30,7 +30,7 @@
 
 struct snd_vxpocket {
 
-	vx_core_t core;
+	struct vx_core core;
 
 	unsigned long port;
 
@@ -48,10 +48,10 @@
 
 extern struct snd_vx_ops snd_vxpocket_ops;
 
-void vx_set_mic_boost(vx_core_t *chip, int boost);
-void vx_set_mic_level(vx_core_t *chip, int level);
+void vx_set_mic_boost(struct vx_core *chip, int boost);
+void vx_set_mic_level(struct vx_core *chip, int level);
 
-int vxp_add_mic_controls(vx_core_t *chip);
+int vxp_add_mic_controls(struct vx_core *chip);
 
 /* Constants used to access the CDSP register (0x08). */
 #define CDSP_MAGIC	0xA7	/* magic value (for read) */
diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig
index 206b933..a3fb149 100644
--- a/sound/ppc/Kconfig
+++ b/sound/ppc/Kconfig
@@ -13,7 +13,6 @@
 	tristate "PowerMac (AWACS, DACA, Burgundy, Tumbler, Keywest)"
 	depends on SND && I2C && INPUT && PPC_PMAC
 	select SND_PCM
-	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for the integrated sound device.
 
diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c
index 758ca1b..82d791b 100644
--- a/sound/ppc/awacs.c
+++ b/sound/ppc/awacs.c
@@ -35,18 +35,18 @@
 #endif
 
 #ifdef PMAC_AMP_AVAIL
-typedef struct awacs_amp {
+struct awacs_amp {
 	unsigned char amp_master;
 	unsigned char amp_vol[2][2];
 	unsigned char amp_tone[2];
-} awacs_amp_t;
+};
 
 #define CHECK_CUDA_AMP() (sys_ctrler == SYS_CTRLER_CUDA)
 
 #endif /* PMAC_AMP_AVAIL */
 
 
-static void snd_pmac_screamer_wait(pmac_t *chip)
+static void snd_pmac_screamer_wait(struct snd_pmac *chip)
 {
 	long timeout = 2000;
 	while (!(in_le32(&chip->awacs->codec_stat) & MASK_VALID)) {
@@ -62,7 +62,7 @@
  * write AWACS register
  */
 static void
-snd_pmac_awacs_write(pmac_t *chip, int val)
+snd_pmac_awacs_write(struct snd_pmac *chip, int val)
 {
 	long timeout = 5000000;
 
@@ -78,21 +78,21 @@
 }
 
 static void
-snd_pmac_awacs_write_reg(pmac_t *chip, int reg, int val)
+snd_pmac_awacs_write_reg(struct snd_pmac *chip, int reg, int val)
 {
 	snd_pmac_awacs_write(chip, val | (reg << 12));
 	chip->awacs_reg[reg] = val;
 }
 
 static void
-snd_pmac_awacs_write_noreg(pmac_t *chip, int reg, int val)
+snd_pmac_awacs_write_noreg(struct snd_pmac *chip, int reg, int val)
 {
 	snd_pmac_awacs_write(chip, val | (reg << 12));
 }
 
 #ifdef CONFIG_PM
 /* Recalibrate chip */
-static void screamer_recalibrate(pmac_t *chip)
+static void screamer_recalibrate(struct snd_pmac *chip)
 {
 	if (chip->model != PMAC_SCREAMER)
 		return;
@@ -105,7 +105,8 @@
 		/* delay for broken crystal part */
 		msleep(750);
 	snd_pmac_awacs_write_noreg(chip, 1,
-				   chip->awacs_reg[1] | MASK_RECALIBRATE | MASK_CMUTE | MASK_AMUTE);
+				   chip->awacs_reg[1] | MASK_RECALIBRATE |
+				   MASK_CMUTE | MASK_AMUTE);
 	snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
 	snd_pmac_awacs_write_noreg(chip, 6, chip->awacs_reg[6]);
 }
@@ -118,7 +119,7 @@
 /*
  * additional callback to set the pcm format
  */
-static void snd_pmac_awacs_set_format(pmac_t *chip)
+static void snd_pmac_awacs_set_format(struct snd_pmac *chip)
 {
 	chip->awacs_reg[1] &= ~MASK_SAMPLERATE;
 	chip->awacs_reg[1] |= chip->rate_index << 3;
@@ -132,7 +133,8 @@
 /*
  * volumes: 0-15 stereo
  */
-static int snd_pmac_awacs_info_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_pmac_awacs_info_volume(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -141,9 +143,10 @@
 	return 0;
 }
  
-static int snd_pmac_awacs_get_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_get_volume(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int lshift = (kcontrol->private_value >> 8) & 0xff;
 	int inverted = (kcontrol->private_value >> 16) & 1;
@@ -163,9 +166,10 @@
 	return 0;
 }
 
-static int snd_pmac_awacs_put_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_put_volume(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int lshift = (kcontrol->private_value >> 8) & 0xff;
 	int inverted = (kcontrol->private_value >> 16) & 1;
@@ -203,9 +207,10 @@
 /*
  * mute master/ogain for AWACS: mono
  */
-static int snd_pmac_awacs_get_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_get_switch(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int invert = (kcontrol->private_value >> 16) & 1;
@@ -221,9 +226,10 @@
 	return 0;
 }
 
-static int snd_pmac_awacs_put_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_put_switch(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int invert = (kcontrol->private_value >> 16) & 1;
@@ -268,7 +274,7 @@
 /*
  * level = 0 - 14, 7 = 0 dB
  */
-static void awacs_amp_set_tone(awacs_amp_t *amp, int bass, int treble)
+static void awacs_amp_set_tone(struct awacs_amp *amp, int bass, int treble)
 {
 	amp->amp_tone[0] = bass;
 	amp->amp_tone[1] = treble;
@@ -282,7 +288,8 @@
 /*
  * vol = 0 - 31 (attenuation), 32 = mute bit, stereo
  */
-static int awacs_amp_set_vol(awacs_amp_t *amp, int index, int lvol, int rvol, int do_check)
+static int awacs_amp_set_vol(struct awacs_amp *amp, int index, int lvol, int rvol,
+			     int do_check)
 {
 	if (do_check && amp->amp_vol[index][0] == lvol &&
 	    amp->amp_vol[index][1] == rvol)
@@ -297,7 +304,7 @@
 /*
  * 0 = -79 dB, 79 = 0 dB, 99 = +20 dB
  */
-static void awacs_amp_set_master(awacs_amp_t *amp, int vol)
+static void awacs_amp_set_master(struct awacs_amp *amp, int vol)
 {
 	amp->amp_master = vol;
 	if (vol <= 79)
@@ -307,9 +314,9 @@
 	awacs_set_cuda(1, vol);
 }
 
-static void awacs_amp_free(pmac_t *chip)
+static void awacs_amp_free(struct snd_pmac *chip)
 {
-	awacs_amp_t *amp = chip->mixer_data;
+	struct awacs_amp *amp = chip->mixer_data;
 	snd_assert(amp, return);
 	kfree(amp);
 	chip->mixer_data = NULL;
@@ -320,7 +327,8 @@
 /*
  * mixer controls
  */
-static int snd_pmac_awacs_info_volume_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_pmac_awacs_info_volume_amp(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -329,11 +337,12 @@
 	return 0;
 }
  
-static int snd_pmac_awacs_get_volume_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_get_volume_amp(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int index = kcontrol->private_value;
-	awacs_amp_t *amp = chip->mixer_data;
+	struct awacs_amp *amp = chip->mixer_data;
 	snd_assert(amp, return -EINVAL);
 	snd_assert(index >= 0 && index <= 1, return -EINVAL);
 	ucontrol->value.integer.value[0] = 31 - (amp->amp_vol[index][0] & 31);
@@ -341,12 +350,13 @@
 	return 0;
 }
 
-static int snd_pmac_awacs_put_volume_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_put_volume_amp(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int index = kcontrol->private_value;
 	int vol[2];
-	awacs_amp_t *amp = chip->mixer_data;
+	struct awacs_amp *amp = chip->mixer_data;
 	snd_assert(amp, return -EINVAL);
 	snd_assert(index >= 0 && index <= 1, return -EINVAL);
 
@@ -355,11 +365,12 @@
 	return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
 }
 
-static int snd_pmac_awacs_get_switch_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_get_switch_amp(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int index = kcontrol->private_value;
-	awacs_amp_t *amp = chip->mixer_data;
+	struct awacs_amp *amp = chip->mixer_data;
 	snd_assert(amp, return -EINVAL);
 	snd_assert(index >= 0 && index <= 1, return -EINVAL);
 	ucontrol->value.integer.value[0] = (amp->amp_vol[index][0] & 32) ? 0 : 1;
@@ -367,12 +378,13 @@
 	return 0;
 }
 
-static int snd_pmac_awacs_put_switch_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_put_switch_amp(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int index = kcontrol->private_value;
 	int vol[2];
-	awacs_amp_t *amp = chip->mixer_data;
+	struct awacs_amp *amp = chip->mixer_data;
 	snd_assert(amp, return -EINVAL);
 	snd_assert(index >= 0 && index <= 1, return -EINVAL);
 
@@ -381,7 +393,8 @@
 	return awacs_amp_set_vol(amp, index, vol[0], vol[1], 1);
 }
 
-static int snd_pmac_awacs_info_tone_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_pmac_awacs_info_tone_amp(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -390,22 +403,24 @@
 	return 0;
 }
  
-static int snd_pmac_awacs_get_tone_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_get_tone_amp(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int index = kcontrol->private_value;
-	awacs_amp_t *amp = chip->mixer_data;
+	struct awacs_amp *amp = chip->mixer_data;
 	snd_assert(amp, return -EINVAL);
 	snd_assert(index >= 0 && index <= 1, return -EINVAL);
 	ucontrol->value.integer.value[0] = amp->amp_tone[index];
 	return 0;
 }
 
-static int snd_pmac_awacs_put_tone_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_put_tone_amp(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int index = kcontrol->private_value;
-	awacs_amp_t *amp = chip->mixer_data;
+	struct awacs_amp *amp = chip->mixer_data;
 	snd_assert(amp, return -EINVAL);
 	snd_assert(index >= 0 && index <= 1, return -EINVAL);
 	if (ucontrol->value.integer.value[0] != amp->amp_tone[index]) {
@@ -416,7 +431,8 @@
 	return 0;
 }
 
-static int snd_pmac_awacs_info_master_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_pmac_awacs_info_master_amp(struct snd_kcontrol *kcontrol,
+					  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -425,19 +441,21 @@
 	return 0;
 }
  
-static int snd_pmac_awacs_get_master_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_get_master_amp(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	awacs_amp_t *amp = chip->mixer_data;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct awacs_amp *amp = chip->mixer_data;
 	snd_assert(amp, return -EINVAL);
 	ucontrol->value.integer.value[0] = amp->amp_master;
 	return 0;
 }
 
-static int snd_pmac_awacs_put_master_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_awacs_put_master_amp(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	awacs_amp_t *amp = chip->mixer_data;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct awacs_amp *amp = chip->mixer_data;
 	snd_assert(amp, return -EINVAL);
 	if (ucontrol->value.integer.value[0] != amp->amp_master) {
 		amp->amp_master = ucontrol->value.integer.value[0];
@@ -450,7 +468,7 @@
 #define AMP_CH_SPK	0
 #define AMP_CH_HD	1
 
-static snd_kcontrol_new_t snd_pmac_awacs_amp_vol[] __initdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_amp_vol[] __initdata = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "PC Speaker Playback Volume",
 	  .info = snd_pmac_awacs_info_volume_amp,
@@ -487,7 +505,7 @@
 	},
 };
 
-static snd_kcontrol_new_t snd_pmac_awacs_amp_hp_sw __initdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_amp_hp_sw __initdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Headphone Playback Switch",
 	.info = snd_pmac_boolean_stereo_info,
@@ -496,7 +514,7 @@
 	.private_value = AMP_CH_HD,
 };
 
-static snd_kcontrol_new_t snd_pmac_awacs_amp_spk_sw __initdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_amp_spk_sw __initdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PC Speaker Playback Switch",
 	.info = snd_pmac_boolean_stereo_info,
@@ -511,7 +529,8 @@
 /*
  * mic boost for screamer
  */
-static int snd_pmac_screamer_mic_boost_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_pmac_screamer_mic_boost_info(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -520,9 +539,10 @@
 	return 0;
 }
 
-static int snd_pmac_screamer_mic_boost_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_screamer_mic_boost_get(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int val;
 	unsigned long flags;
 
@@ -538,9 +558,10 @@
 	return 0;
 }
 
-static int snd_pmac_screamer_mic_boost_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_screamer_mic_boost_put(struct snd_kcontrol *kcontrol,
+					   struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int changed = 0;
 	int val0, val6;
 	unsigned long flags;
@@ -568,7 +589,7 @@
 /*
  * lists of mixer elements
  */
-static snd_kcontrol_new_t snd_pmac_awacs_mixers[] __initdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mixers[] __initdata = {
 	AWACS_VOLUME("Master Playback Volume", 2, 6, 1),
 	AWACS_SWITCH("Master Capture Switch", 1, SHIFT_LOOPTHRU, 0),
 	AWACS_VOLUME("Capture Volume", 0, 4, 0),
@@ -578,24 +599,24 @@
 /* FIXME: is this correct order?
  * screamer (powerbook G3 pismo) seems to have different bits...
  */
-static snd_kcontrol_new_t snd_pmac_awacs_mixers2[] __initdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mixers2[] __initdata = {
 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_LINE, 0),
 	AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_MIC, 0),
 };
 
-static snd_kcontrol_new_t snd_pmac_screamer_mixers2[] __initdata = {
+static struct snd_kcontrol_new snd_pmac_screamer_mixers2[] __initdata = {
 	AWACS_SWITCH("Line Capture Switch", 0, SHIFT_MUX_MIC, 0),
 	AWACS_SWITCH("Mic Capture Switch", 0, SHIFT_MUX_LINE, 0),
 };
 
-static snd_kcontrol_new_t snd_pmac_awacs_master_sw __initdata =
+static struct snd_kcontrol_new snd_pmac_awacs_master_sw __initdata =
 AWACS_SWITCH("Master Playback Switch", 1, SHIFT_HDMUTE, 1);
 
-static snd_kcontrol_new_t snd_pmac_awacs_mic_boost[] __initdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_mic_boost[] __initdata = {
 	AWACS_SWITCH("Mic Boost", 0, SHIFT_GAINLINE, 0),
 };
 
-static snd_kcontrol_new_t snd_pmac_screamer_mic_boost[] __initdata = {
+static struct snd_kcontrol_new snd_pmac_screamer_mic_boost[] __initdata = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Mic Boost",
 	  .info = snd_pmac_screamer_mic_boost_info,
@@ -604,17 +625,17 @@
 	},
 };
 
-static snd_kcontrol_new_t snd_pmac_awacs_speaker_vol[] __initdata = {
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_vol[] __initdata = {
 	AWACS_VOLUME("PC Speaker Playback Volume", 4, 6, 1),
 };
-static snd_kcontrol_new_t snd_pmac_awacs_speaker_sw __initdata =
+static struct snd_kcontrol_new snd_pmac_awacs_speaker_sw __initdata =
 AWACS_SWITCH("PC Speaker Playback Switch", 1, SHIFT_SPKMUTE, 1);
 
 
 /*
  * add new mixer elements to the card
  */
-static int build_mixers(pmac_t *chip, int nums, snd_kcontrol_new_t *mixers)
+static int build_mixers(struct snd_pmac *chip, int nums, struct snd_kcontrol_new *mixers)
 {
 	int i, err;
 
@@ -629,7 +650,7 @@
 /*
  * restore all registers
  */
-static void awacs_restore_all_regs(pmac_t *chip)
+static void awacs_restore_all_regs(struct snd_pmac *chip)
 {
 	snd_pmac_awacs_write_noreg(chip, 0, chip->awacs_reg[0]);
 	snd_pmac_awacs_write_noreg(chip, 1, chip->awacs_reg[1]);
@@ -643,13 +664,13 @@
 }
 
 #ifdef CONFIG_PM
-static void snd_pmac_awacs_suspend(pmac_t *chip)
+static void snd_pmac_awacs_suspend(struct snd_pmac *chip)
 {
 	snd_pmac_awacs_write_noreg(chip, 1, (chip->awacs_reg[1]
 					     | MASK_AMUTE | MASK_CMUTE));
 }
 
-static void snd_pmac_awacs_resume(pmac_t *chip)
+static void snd_pmac_awacs_resume(struct snd_pmac *chip)
 {
 	if (machine_is_compatible("PowerBook3,1")
 	    || machine_is_compatible("PowerBook3,2")) {
@@ -668,7 +689,7 @@
 	screamer_recalibrate(chip);
 #ifdef PMAC_AMP_AVAIL
 	if (chip->mixer_data) {
-		awacs_amp_t *amp = chip->mixer_data;
+		struct awacs_amp *amp = chip->mixer_data;
 		awacs_amp_set_vol(amp, 0, amp->amp_vol[0][0], amp->amp_vol[0][1], 0);
 		awacs_amp_set_vol(amp, 1, amp->amp_vol[1][0], amp->amp_vol[1][1], 0);
 		awacs_amp_set_tone(amp, amp->amp_tone[0], amp->amp_tone[1]);
@@ -682,13 +703,13 @@
 /*
  * auto-mute stuffs
  */
-static int snd_pmac_awacs_detect_headphone(pmac_t *chip)
+static int snd_pmac_awacs_detect_headphone(struct snd_pmac *chip)
 {
 	return (in_le32(&chip->awacs->codec_stat) & chip->hp_stat_mask) ? 1 : 0;
 }
 
 #ifdef PMAC_AMP_AVAIL
-static int toggle_amp_mute(awacs_amp_t *amp, int index, int mute)
+static int toggle_amp_mute(struct awacs_amp *amp, int index, int mute)
 {
 	int vol[2];
 	vol[0] = amp->amp_vol[index][0] & 31;
@@ -701,12 +722,12 @@
 }
 #endif
 
-static void snd_pmac_awacs_update_automute(pmac_t *chip, int do_notify)
+static void snd_pmac_awacs_update_automute(struct snd_pmac *chip, int do_notify)
 {
 	if (chip->auto_mute) {
 #ifdef PMAC_AMP_AVAIL
 		if (chip->mixer_data) {
-			awacs_amp_t *amp = chip->mixer_data;
+			struct awacs_amp *amp = chip->mixer_data;
 			int changed;
 			if (snd_pmac_awacs_detect_headphone(chip)) {
 				changed = toggle_amp_mute(amp, AMP_CH_HD, 0);
@@ -746,7 +767,7 @@
  * initialize chip
  */
 int __init
-snd_pmac_awacs_init(pmac_t *chip)
+snd_pmac_awacs_init(struct snd_pmac *chip)
 {
 	int err, vol;
 
@@ -780,7 +801,7 @@
 	chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf;
 #ifdef PMAC_AMP_AVAIL
 	if (chip->revision == 3 && chip->has_iic && CHECK_CUDA_AMP()) {
-		awacs_amp_t *amp = kmalloc(sizeof(*amp), GFP_KERNEL);
+		struct awacs_amp *amp = kmalloc(sizeof(*amp), GFP_KERNEL);
 		if (! amp)
 			return -ENOMEM;
 		chip->mixer_data = amp;
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index d4ec6cc..5fec1e5 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -30,7 +30,7 @@
 #include <sound/control.h>
 #include "pmac.h"
 
-struct snd_pmac_beep {
+struct pmac_beep {
 	int running;		/* boolean */
 	int volume;		/* mixer volume: 0-100 */
 	int volume_play;	/* currently playing volume */
@@ -44,9 +44,9 @@
 /*
  * stop beep if running
  */
-void snd_pmac_beep_stop(pmac_t *chip)
+void snd_pmac_beep_stop(struct snd_pmac *chip)
 {
-	pmac_beep_t *beep = chip->beep;
+	struct pmac_beep *beep = chip->beep;
 	if (beep && beep->running) {
 		beep->running = 0;
 		snd_pmac_beep_dma_stop(chip);
@@ -97,10 +97,11 @@
 #define BEEP_BUFLEN	512
 #define BEEP_VOLUME	15	/* 0 - 100 */
 
-static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type, unsigned int code, int hz)
+static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
+			       unsigned int code, int hz)
 {
-	pmac_t *chip;
-	pmac_beep_t *beep;
+	struct snd_pmac *chip;
+	struct pmac_beep *beep;
 	unsigned long flags;
 	int beep_speed = 0;
 	int srate;
@@ -171,7 +172,8 @@
  * beep volume mixer
  */
 
-static int snd_pmac_info_beep(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_pmac_info_beep(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
@@ -180,17 +182,19 @@
 	return 0;
 }
 
-static int snd_pmac_get_beep(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_get_beep(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	snd_assert(chip->beep, return -ENXIO);
 	ucontrol->value.integer.value[0] = chip->beep->volume;
 	return 0;
 }
 
-static int snd_pmac_put_beep(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_put_beep(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int oval;
 	snd_assert(chip->beep, return -ENXIO);
 	oval = chip->beep->volume;
@@ -198,7 +202,7 @@
 	return oval != chip->beep->volume;
 }
 
-static snd_kcontrol_new_t snd_pmac_beep_mixer = {
+static struct snd_kcontrol_new snd_pmac_beep_mixer = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Beep Playback Volume",
 	.info = snd_pmac_info_beep,
@@ -207,9 +211,9 @@
 };
 
 /* Initialize beep stuff */
-int __init snd_pmac_attach_beep(pmac_t *chip)
+int __init snd_pmac_attach_beep(struct snd_pmac *chip)
 {
-	pmac_beep_t *beep;
+	struct pmac_beep *beep;
 	struct input_dev *input_dev;
 	void *dmabuf;
 	int err = -ENOMEM;
@@ -255,7 +259,7 @@
 	return err;
 }
 
-void snd_pmac_detach_beep(pmac_t *chip)
+void snd_pmac_detach_beep(struct snd_pmac *chip)
 {
 	if (chip->beep) {
 		input_unregister_device(chip->beep->dev);
diff --git a/sound/ppc/burgundy.c b/sound/ppc/burgundy.c
index edbc048..e02263f 100644
--- a/sound/ppc/burgundy.c
+++ b/sound/ppc/burgundy.c
@@ -31,7 +31,7 @@
 
 /* Waits for busy flag to clear */
 static inline void
-snd_pmac_burgundy_busy_wait(pmac_t *chip)
+snd_pmac_burgundy_busy_wait(struct snd_pmac *chip)
 {
 	int timeout = 50;
 	while ((in_le32(&chip->awacs->codec_ctrl) & MASK_NEWECMD) && timeout--)
@@ -41,7 +41,7 @@
 }
 
 static inline void
-snd_pmac_burgundy_extend_wait(pmac_t *chip)
+snd_pmac_burgundy_extend_wait(struct snd_pmac *chip)
 {
 	int timeout;
 	timeout = 50;
@@ -57,7 +57,7 @@
 }
 
 static void
-snd_pmac_burgundy_wcw(pmac_t *chip, unsigned addr, unsigned val)
+snd_pmac_burgundy_wcw(struct snd_pmac *chip, unsigned addr, unsigned val)
 {
 	out_le32(&chip->awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff));
 	snd_pmac_burgundy_busy_wait(chip);
@@ -70,7 +70,7 @@
 }
 
 static unsigned
-snd_pmac_burgundy_rcw(pmac_t *chip, unsigned addr)
+snd_pmac_burgundy_rcw(struct snd_pmac *chip, unsigned addr)
 {
 	unsigned val = 0;
 	unsigned long flags;
@@ -103,14 +103,14 @@
 }
 
 static void
-snd_pmac_burgundy_wcb(pmac_t *chip, unsigned int addr, unsigned int val)
+snd_pmac_burgundy_wcb(struct snd_pmac *chip, unsigned int addr, unsigned int val)
 {
 	out_le32(&chip->awacs->codec_ctrl, addr + 0x300000 + (val & 0xff));
 	snd_pmac_burgundy_busy_wait(chip);
 }
 
 static unsigned
-snd_pmac_burgundy_rcb(pmac_t *chip, unsigned int addr)
+snd_pmac_burgundy_rcb(struct snd_pmac *chip, unsigned int addr)
 {
 	unsigned val = 0;
 	unsigned long flags;
@@ -131,7 +131,8 @@
  * Burgundy volume: 0 - 100, stereo
  */
 static void
-snd_pmac_burgundy_write_volume(pmac_t *chip, unsigned int address, long *volume, int shift)
+snd_pmac_burgundy_write_volume(struct snd_pmac *chip, unsigned int address,
+			       long *volume, int shift)
 {
 	int hardvolume, lvolume, rvolume;
 
@@ -146,7 +147,8 @@
 }
 
 static void
-snd_pmac_burgundy_read_volume(pmac_t *chip, unsigned int address, long *volume, int shift)
+snd_pmac_burgundy_read_volume(struct snd_pmac *chip, unsigned int address,
+			      long *volume, int shift)
 {
 	int wvolume;
 
@@ -171,7 +173,8 @@
 #define BASE2ADDR(base)	((base) << 12)
 #define ADDR2BASE(addr)	((addr) >> 12)
 
-static int snd_pmac_burgundy_info_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_pmac_burgundy_info_volume(struct snd_kcontrol *kcontrol,
+					 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -180,23 +183,27 @@
 	return 0;
 }
 
-static int snd_pmac_burgundy_get_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_burgundy_get_volume(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
 	int shift = (kcontrol->private_value >> 8) & 0xff;
-	snd_pmac_burgundy_read_volume(chip, addr, ucontrol->value.integer.value, shift);
+	snd_pmac_burgundy_read_volume(chip, addr, ucontrol->value.integer.value,
+				      shift);
 	return 0;
 }
 
-static int snd_pmac_burgundy_put_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_burgundy_put_volume(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	long nvoices[2];
 
-	snd_pmac_burgundy_write_volume(chip, addr, ucontrol->value.integer.value, shift);
+	snd_pmac_burgundy_write_volume(chip, addr, ucontrol->value.integer.value,
+				       shift);
 	snd_pmac_burgundy_read_volume(chip, addr, nvoices, shift);
 	return (nvoices[0] != ucontrol->value.integer.value[0] ||
 		nvoices[1] != ucontrol->value.integer.value[1]);
@@ -211,7 +218,8 @@
 
 /* lineout/speaker */
 
-static int snd_pmac_burgundy_info_switch_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_pmac_burgundy_info_switch_out(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
 {
 	int stereo = (kcontrol->private_value >> 24) & 1;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
@@ -221,9 +229,10 @@
 	return 0;
 }
 
-static int snd_pmac_burgundy_get_switch_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_burgundy_get_switch_out(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int lmask = kcontrol->private_value & 0xff;
 	int rmask = (kcontrol->private_value >> 8) & 0xff;
 	int stereo = (kcontrol->private_value >> 24) & 1;
@@ -234,9 +243,10 @@
 	return 0;
 }
 
-static int snd_pmac_burgundy_put_switch_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_burgundy_put_switch_out(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	int lmask = kcontrol->private_value & 0xff;
 	int rmask = (kcontrol->private_value >> 8) & 0xff;
 	int stereo = (kcontrol->private_value >> 24) & 1;
@@ -259,7 +269,8 @@
   .private_value = ((lmask) | ((rmask) << 8) | ((stereo) << 24)) }
 
 /* line/speaker output volume */
-static int snd_pmac_burgundy_info_volume_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_pmac_burgundy_info_volume_out(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_info *uinfo)
 {
 	int stereo = (kcontrol->private_value >> 24) & 1;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
@@ -269,9 +280,10 @@
 	return 0;
 }
 
-static int snd_pmac_burgundy_get_volume_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_burgundy_get_volume_out(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
 	int stereo = (kcontrol->private_value >> 24) & 1;
 	int oval;
@@ -283,9 +295,10 @@
 	return 0;
 }
 
-static int snd_pmac_burgundy_put_volume_out(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_pmac_burgundy_put_volume_out(struct snd_kcontrol *kcontrol,
+					    struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	unsigned int addr = BASE2ADDR(kcontrol->private_value & 0xff);
 	int stereo = (kcontrol->private_value >> 24) & 1;
 	int oval, val;
@@ -308,7 +321,7 @@
   .put = snd_pmac_burgundy_put_volume_out,\
   .private_value = (ADDR2BASE(addr) | ((stereo) << 24)) }
 
-static snd_kcontrol_new_t snd_pmac_burgundy_mixers[] __initdata = {
+static struct snd_kcontrol_new snd_pmac_burgundy_mixers[] __initdata = {
 	BURGUNDY_VOLUME("Master Playback Volume", 0, MASK_ADDR_BURGUNDY_MASTER_VOLUME, 8),
 	BURGUNDY_VOLUME("Line Playback Volume", 0, MASK_ADDR_BURGUNDY_VOLLINE, 16),
 	BURGUNDY_VOLUME("CD Playback Volume", 0, MASK_ADDR_BURGUNDY_VOLCD, 16),
@@ -317,9 +330,9 @@
 	/*BURGUNDY_OUTPUT_VOLUME("PCM Playback Volume", 0, MASK_ADDR_BURGUNDY_ATTENLINEOUT, 1),*/
 	BURGUNDY_OUTPUT_VOLUME("Headphone Playback Volume", 0, MASK_ADDR_BURGUNDY_ATTENSPEAKER, 1),
 };	
-static snd_kcontrol_new_t snd_pmac_burgundy_master_sw __initdata = 
+static struct snd_kcontrol_new snd_pmac_burgundy_master_sw __initdata = 
 BURGUNDY_OUTPUT_SWITCH("Headphone Playback Switch", 0, BURGUNDY_OUTPUT_LEFT, BURGUNDY_OUTPUT_RIGHT, 1);
-static snd_kcontrol_new_t snd_pmac_burgundy_speaker_sw __initdata = 
+static struct snd_kcontrol_new snd_pmac_burgundy_speaker_sw __initdata = 
 BURGUNDY_OUTPUT_SWITCH("PC Speaker Playback Switch", 0, BURGUNDY_OUTPUT_INTERN, 0, 0);
 
 
@@ -327,12 +340,12 @@
 /*
  * auto-mute stuffs
  */
-static int snd_pmac_burgundy_detect_headphone(pmac_t *chip)
+static int snd_pmac_burgundy_detect_headphone(struct snd_pmac *chip)
 {
 	return (in_le32(&chip->awacs->codec_stat) & chip->hp_stat_mask) ? 1 : 0;
 }
 
-static void snd_pmac_burgundy_update_automute(pmac_t *chip, int do_notify)
+static void snd_pmac_burgundy_update_automute(struct snd_pmac *chip, int do_notify)
 {
 	if (chip->auto_mute) {
 		int reg, oreg;
@@ -361,7 +374,7 @@
 /*
  * initialize burgundy
  */
-int __init snd_pmac_burgundy_init(pmac_t *chip)
+int __init snd_pmac_burgundy_init(struct snd_pmac *chip)
 {
 	int i, err;
 
diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c
index a737f29..08cde51 100644
--- a/sound/ppc/daca.c
+++ b/sound/ppc/daca.c
@@ -40,18 +40,18 @@
 #define DACA_VOL_MAX	0x38
 
 
-typedef struct pmac_daca_t {
-	pmac_keywest_t i2c;
+struct pmac_daca {
+	struct pmac_keywest i2c;
 	int left_vol, right_vol;
 	unsigned int deemphasis : 1;
 	unsigned int amp_on : 1;
-} pmac_daca_t;
+};
 
 
 /*
  * initialize / detect DACA
  */
-static int daca_init_client(pmac_keywest_t *i2c)
+static int daca_init_client(struct pmac_keywest *i2c)
 {
 	unsigned short wdata = 0x00;
 	/* SR: no swap, 1bit delay, 32-48kHz */
@@ -66,7 +66,7 @@
 /*
  * update volume
  */
-static int daca_set_volume(pmac_daca_t *mix)
+static int daca_set_volume(struct pmac_daca *mix)
 {
 	unsigned char data[2];
   
@@ -92,7 +92,8 @@
 
 
 /* deemphasis switch */
-static int daca_info_deemphasis(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int daca_info_deemphasis(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -101,20 +102,22 @@
 	return 0;
 }
 
-static int daca_get_deemphasis(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int daca_get_deemphasis(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_daca_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_daca *mix;
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	ucontrol->value.integer.value[0] = mix->deemphasis ? 1 : 0;
 	return 0;
 }
 
-static int daca_put_deemphasis(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int daca_put_deemphasis(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_daca_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_daca *mix;
 	int change;
 
 	if (! (mix = chip->mixer_data))
@@ -128,7 +131,8 @@
 }
 
 /* output volume */
-static int daca_info_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int daca_info_volume(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -137,10 +141,11 @@
 	return 0;
 }
 
-static int daca_get_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int daca_get_volume(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_daca_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_daca *mix;
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	ucontrol->value.integer.value[0] = mix->left_vol;
@@ -148,10 +153,11 @@
 	return 0;
 }
 
-static int daca_put_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int daca_put_volume(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_daca_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_daca *mix;
 	int change;
 
 	if (! (mix = chip->mixer_data))
@@ -169,20 +175,22 @@
 /* amplifier switch */
 #define daca_info_amp	daca_info_deemphasis
 
-static int daca_get_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int daca_get_amp(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_daca_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_daca *mix;
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	ucontrol->value.integer.value[0] = mix->amp_on ? 1 : 0;
 	return 0;
 }
 
-static int daca_put_amp(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int daca_put_amp(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_daca_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_daca *mix;
 	int change;
 
 	if (! (mix = chip->mixer_data))
@@ -196,7 +204,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t daca_mixers[] = {
+static struct snd_kcontrol_new daca_mixers[] = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Deemphasis Switch",
 	  .info = daca_info_deemphasis,
@@ -219,9 +227,9 @@
 
 
 #ifdef CONFIG_PM
-static void daca_resume(pmac_t *chip)
+static void daca_resume(struct snd_pmac *chip)
 {
-	pmac_daca_t *mix = chip->mixer_data;
+	struct pmac_daca *mix = chip->mixer_data;
 	i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_SR, 0x08);
 	i2c_smbus_write_byte_data(mix->i2c.client, DACA_REG_GCFG,
 				  mix->amp_on ? 0x05 : 0x04);
@@ -230,9 +238,9 @@
 #endif /* CONFIG_PM */
 
 
-static void daca_cleanup(pmac_t *chip)
+static void daca_cleanup(struct snd_pmac *chip)
 {
-	pmac_daca_t *mix = chip->mixer_data;
+	struct pmac_daca *mix = chip->mixer_data;
 	if (! mix)
 		return;
 	snd_pmac_keywest_cleanup(&mix->i2c);
@@ -241,10 +249,10 @@
 }
 
 /* exported */
-int __init snd_pmac_daca_init(pmac_t *chip)
+int __init snd_pmac_daca_init(struct snd_pmac *chip)
 {
 	int i, err;
-	pmac_daca_t *mix;
+	struct pmac_daca *mix;
 
 #ifdef CONFIG_KMOD
 	if (current->fs->root)
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index df073a0..6058c2d 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -32,7 +32,7 @@
  * we have to keep a static variable here since i2c attach_adapter
  * callback cannot pass a private data.
  */
-static pmac_keywest_t *keywest_ctx;
+static struct pmac_keywest *keywest_ctx;
 
 
 #define I2C_DRIVERID_KEYWEST	0xFEBA
@@ -41,9 +41,10 @@
 static int keywest_detach_client(struct i2c_client *client);
 
 struct i2c_driver keywest_driver = {  
-	.name = "PMac Keywest Audio",
+	.driver = {
+		.name = "PMac Keywest Audio",
+	},
 	.id = I2C_DRIVERID_KEYWEST,
-	.flags = I2C_DF_NOTIFY,
 	.attach_adapter = &keywest_attach_adapter,
 	.detach_client = &keywest_detach_client,
 };
@@ -106,7 +107,7 @@
 }
 
 /* exported */
-void snd_pmac_keywest_cleanup(pmac_keywest_t *i2c)
+void snd_pmac_keywest_cleanup(struct pmac_keywest *i2c)
 {
 	if (keywest_ctx && keywest_ctx == i2c) {
 		i2c_del_driver(&keywest_driver);
@@ -126,7 +127,7 @@
 }
 
 /* exported */
-int __init snd_pmac_keywest_init(pmac_keywest_t *i2c)
+int __init snd_pmac_keywest_init(struct pmac_keywest *i2c)
 {
 	int err;
 
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index db2f1815..9b2b00fd 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -36,14 +36,6 @@
 #include <asm/pci-bridge.h>
 
 
-#ifdef CONFIG_PM
-static int snd_pmac_register_sleep_notifier(pmac_t *chip);
-static int snd_pmac_unregister_sleep_notifier(pmac_t *chip);
-static int snd_pmac_suspend(snd_card_t *card, pm_message_t state);
-static int snd_pmac_resume(snd_card_t *card);
-#endif
-
-
 /* fixed frequency table for awacs, screamer, burgundy, DACA (44100 max) */
 static int awacs_freqs[8] = {
 	44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350
@@ -56,7 +48,7 @@
 /*
  * allocate DBDMA command arrays
  */
-static int snd_pmac_dbdma_alloc(pmac_t *chip, pmac_dbdma_t *rec, int size)
+static int snd_pmac_dbdma_alloc(struct snd_pmac *chip, struct pmac_dbdma *rec, int size)
 {
 	unsigned int rsize = sizeof(struct dbdma_cmd) * (size + 1);
 
@@ -72,7 +64,7 @@
 	return 0;
 }
 
-static void snd_pmac_dbdma_free(pmac_t *chip, pmac_dbdma_t *rec)
+static void snd_pmac_dbdma_free(struct snd_pmac *chip, struct pmac_dbdma *rec)
 {
 	if (rec) {
 		unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1);
@@ -90,7 +82,7 @@
  * look up frequency table
  */
 
-unsigned int snd_pmac_rate_index(pmac_t *chip, pmac_stream_t *rec, unsigned int rate)
+unsigned int snd_pmac_rate_index(struct snd_pmac *chip, struct pmac_stream *rec, unsigned int rate)
 {
 	int i, ok, found;
 
@@ -119,8 +111,8 @@
 /*
  * allocate buffers
  */
-static int snd_pmac_pcm_hw_params(snd_pcm_substream_t *subs,
-				  snd_pcm_hw_params_t *hw_params)
+static int snd_pmac_pcm_hw_params(struct snd_pcm_substream *subs,
+				  struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw_params));
 }
@@ -128,7 +120,7 @@
 /*
  * release buffers
  */
-static int snd_pmac_pcm_hw_free(snd_pcm_substream_t *subs)
+static int snd_pmac_pcm_hw_free(struct snd_pcm_substream *subs)
 {
 	snd_pcm_lib_free_pages(subs);
 	return 0;
@@ -137,7 +129,7 @@
 /*
  * get a stream of the opposite direction
  */
-static pmac_stream_t *snd_pmac_get_stream(pmac_t *chip, int stream)
+static struct pmac_stream *snd_pmac_get_stream(struct snd_pmac *chip, int stream)
 {
 	switch (stream) {
 	case SNDRV_PCM_STREAM_PLAYBACK:
@@ -154,7 +146,7 @@
  * wait while run status is on
  */
 static inline void
-snd_pmac_wait_ack(pmac_stream_t *rec)
+snd_pmac_wait_ack(struct pmac_stream *rec)
 {
 	int timeout = 50000;
 	while ((in_le32(&rec->dma->status) & RUN) && timeout-- > 0)
@@ -165,7 +157,7 @@
  * set the format and rate to the chip.
  * call the lowlevel function if defined (e.g. for AWACS).
  */
-static void snd_pmac_pcm_set_format(pmac_t *chip)
+static void snd_pmac_pcm_set_format(struct snd_pmac *chip)
 {
 	/* set up frequency and format */
 	out_le32(&chip->awacs->control, chip->control_mask | (chip->rate_index << 8));
@@ -177,7 +169,7 @@
 /*
  * stop the DMA transfer
  */
-static inline void snd_pmac_dma_stop(pmac_stream_t *rec)
+static inline void snd_pmac_dma_stop(struct pmac_stream *rec)
 {
 	out_le32(&rec->dma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
 	snd_pmac_wait_ack(rec);
@@ -186,7 +178,7 @@
 /*
  * set the command pointer address
  */
-static inline void snd_pmac_dma_set_command(pmac_stream_t *rec, pmac_dbdma_t *cmd)
+static inline void snd_pmac_dma_set_command(struct pmac_stream *rec, struct pmac_dbdma *cmd)
 {
 	out_le32(&rec->dma->cmdptr, cmd->addr);
 }
@@ -194,7 +186,7 @@
 /*
  * start the DMA
  */
-static inline void snd_pmac_dma_run(pmac_stream_t *rec, int status)
+static inline void snd_pmac_dma_run(struct pmac_stream *rec, int status)
 {
 	out_le32(&rec->dma->control, status | (status << 16));
 }
@@ -203,14 +195,14 @@
 /*
  * prepare playback/capture stream
  */
-static int snd_pmac_pcm_prepare(pmac_t *chip, pmac_stream_t *rec, snd_pcm_substream_t *subs)
+static int snd_pmac_pcm_prepare(struct snd_pmac *chip, struct pmac_stream *rec, struct snd_pcm_substream *subs)
 {
 	int i;
 	volatile struct dbdma_cmd __iomem *cp;
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	int rate_index;
 	long offset;
-	pmac_stream_t *astr;
+	struct pmac_stream *astr;
 	
 	rec->dma_size = snd_pcm_lib_buffer_bytes(subs);
 	rec->period_size = snd_pcm_lib_period_bytes(subs);
@@ -267,8 +259,8 @@
 /*
  * PCM trigger/stop
  */
-static int snd_pmac_pcm_trigger(pmac_t *chip, pmac_stream_t *rec,
-				snd_pcm_substream_t *subs, int cmd)
+static int snd_pmac_pcm_trigger(struct snd_pmac *chip, struct pmac_stream *rec,
+				struct snd_pcm_substream *subs, int cmd)
 {
 	volatile struct dbdma_cmd __iomem *cp;
 	int i, command;
@@ -314,8 +306,9 @@
  * return the current pointer
  */
 inline
-static snd_pcm_uframes_t snd_pmac_pcm_pointer(pmac_t *chip, pmac_stream_t *rec,
-					      snd_pcm_substream_t *subs)
+static snd_pcm_uframes_t snd_pmac_pcm_pointer(struct snd_pmac *chip,
+					      struct pmac_stream *rec,
+					      struct snd_pcm_substream *subs)
 {
 	int count = 0;
 
@@ -338,22 +331,22 @@
  * playback
  */
 
-static int snd_pmac_playback_prepare(snd_pcm_substream_t *subs)
+static int snd_pmac_playback_prepare(struct snd_pcm_substream *subs)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 	return snd_pmac_pcm_prepare(chip, &chip->playback, subs);
 }
 
-static int snd_pmac_playback_trigger(snd_pcm_substream_t *subs,
+static int snd_pmac_playback_trigger(struct snd_pcm_substream *subs,
 				     int cmd)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 	return snd_pmac_pcm_trigger(chip, &chip->playback, subs, cmd);
 }
 
-static snd_pcm_uframes_t snd_pmac_playback_pointer(snd_pcm_substream_t *subs)
+static snd_pcm_uframes_t snd_pmac_playback_pointer(struct snd_pcm_substream *subs)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 	return snd_pmac_pcm_pointer(chip, &chip->playback, subs);
 }
 
@@ -362,22 +355,22 @@
  * capture
  */
 
-static int snd_pmac_capture_prepare(snd_pcm_substream_t *subs)
+static int snd_pmac_capture_prepare(struct snd_pcm_substream *subs)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 	return snd_pmac_pcm_prepare(chip, &chip->capture, subs);
 }
 
-static int snd_pmac_capture_trigger(snd_pcm_substream_t *subs,
+static int snd_pmac_capture_trigger(struct snd_pcm_substream *subs,
 				    int cmd)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 	return snd_pmac_pcm_trigger(chip, &chip->capture, subs, cmd);
 }
 
-static snd_pcm_uframes_t snd_pmac_capture_pointer(snd_pcm_substream_t *subs)
+static snd_pcm_uframes_t snd_pmac_capture_pointer(struct snd_pcm_substream *subs)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 	return snd_pmac_pcm_pointer(chip, &chip->capture, subs);
 }
 
@@ -385,7 +378,7 @@
 /*
  * update playback/capture pointer from interrupts
  */
-static void snd_pmac_pcm_update(pmac_t *chip, pmac_stream_t *rec)
+static void snd_pmac_pcm_update(struct snd_pmac *chip, struct pmac_stream *rec)
 {
 	volatile struct dbdma_cmd __iomem *cp;
 	int c;
@@ -421,7 +414,7 @@
  * hw info
  */
 
-static snd_pcm_hardware_t snd_pmac_playback =
+static struct snd_pcm_hardware snd_pmac_playback =
 {
 	.info =			(SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP |
@@ -440,7 +433,7 @@
 	.periods_max =		PMAC_MAX_FRAGS,
 };
 
-static snd_pcm_hardware_t snd_pmac_capture =
+static struct snd_pcm_hardware snd_pmac_capture =
 {
 	.info =			(SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP |
@@ -461,11 +454,11 @@
 
 
 #if 0 // NYI
-static int snd_pmac_hw_rule_rate(snd_pcm_hw_params_t *params,
-				 snd_pcm_hw_rule_t *rule)
+static int snd_pmac_hw_rule_rate(struct snd_pcm_hw_params *params,
+				 struct snd_pcm_hw_rule *rule)
 {
-	pmac_t *chip = rule->private;
-	pmac_stream_t *rec = snd_pmac_get_stream(chip, rule->deps[0]);
+	struct snd_pmac *chip = rule->private;
+	struct pmac_stream *rec = snd_pmac_get_stream(chip, rule->deps[0]);
 	int i, freq_table[8], num_freqs;
 
 	if (! rec)
@@ -480,11 +473,11 @@
 				 num_freqs, freq_table, 0);
 }
 
-static int snd_pmac_hw_rule_format(snd_pcm_hw_params_t *params,
-				   snd_pcm_hw_rule_t *rule)
+static int snd_pmac_hw_rule_format(struct snd_pcm_hw_params *params,
+				   struct snd_pcm_hw_rule *rule)
 {
-	pmac_t *chip = rule->private;
-	pmac_stream_t *rec = snd_pmac_get_stream(chip, rule->deps[0]);
+	struct snd_pmac *chip = rule->private;
+	struct pmac_stream *rec = snd_pmac_get_stream(chip, rule->deps[0]);
 
 	if (! rec)
 		return -EINVAL;
@@ -493,9 +486,10 @@
 }
 #endif // NYI
 
-static int snd_pmac_pcm_open(pmac_t *chip, pmac_stream_t *rec, snd_pcm_substream_t *subs)
+static int snd_pmac_pcm_open(struct snd_pmac *chip, struct pmac_stream *rec,
+			     struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	int i, j, fflags;
 	static int typical_freqs[] = {
 		44100,
@@ -565,9 +559,10 @@
 	return 0;
 }
 
-static int snd_pmac_pcm_close(pmac_t *chip, pmac_stream_t *rec, snd_pcm_substream_t *subs)
+static int snd_pmac_pcm_close(struct snd_pmac *chip, struct pmac_stream *rec,
+			      struct snd_pcm_substream *subs)
 {
-	pmac_stream_t *astr;
+	struct pmac_stream *astr;
 
 	snd_pmac_dma_stop(rec);
 
@@ -582,32 +577,32 @@
 	return 0;
 }
 
-static int snd_pmac_playback_open(snd_pcm_substream_t *subs)
+static int snd_pmac_playback_open(struct snd_pcm_substream *subs)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 
 	subs->runtime->hw = snd_pmac_playback;
 	return snd_pmac_pcm_open(chip, &chip->playback, subs);
 }
 
-static int snd_pmac_capture_open(snd_pcm_substream_t *subs)
+static int snd_pmac_capture_open(struct snd_pcm_substream *subs)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 
 	subs->runtime->hw = snd_pmac_capture;
 	return snd_pmac_pcm_open(chip, &chip->capture, subs);
 }
 
-static int snd_pmac_playback_close(snd_pcm_substream_t *subs)
+static int snd_pmac_playback_close(struct snd_pcm_substream *subs)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 
 	return snd_pmac_pcm_close(chip, &chip->playback, subs);
 }
 
-static int snd_pmac_capture_close(snd_pcm_substream_t *subs)
+static int snd_pmac_capture_close(struct snd_pcm_substream *subs)
 {
-	pmac_t *chip = snd_pcm_substream_chip(subs);
+	struct snd_pmac *chip = snd_pcm_substream_chip(subs);
 
 	return snd_pmac_pcm_close(chip, &chip->capture, subs);
 }
@@ -615,7 +610,7 @@
 /*
  */
 
-static snd_pcm_ops_t snd_pmac_playback_ops = {
+static struct snd_pcm_ops snd_pmac_playback_ops = {
 	.open =		snd_pmac_playback_open,
 	.close =	snd_pmac_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -626,7 +621,7 @@
 	.pointer =	snd_pmac_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_pmac_capture_ops = {
+static struct snd_pcm_ops snd_pmac_capture_ops = {
 	.open =		snd_pmac_capture_open,
 	.close =	snd_pmac_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -637,14 +632,9 @@
 	.pointer =	snd_pmac_capture_pointer,
 };
 
-static void pmac_pcm_free(snd_pcm_t *pcm)
+int __init snd_pmac_pcm_new(struct snd_pmac *chip)
 {
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int __init snd_pmac_pcm_new(pmac_t *chip)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 	int num_captures = 1;
 
@@ -659,7 +649,6 @@
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_pmac_capture_ops);
 
 	pcm->private_data = chip;
-	pcm->private_free = pmac_pcm_free;
 	pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
 	strcpy(pcm->name, chip->card->shortname);
 	chip->pcm = pcm;
@@ -682,7 +671,7 @@
 }
 
 
-static void snd_pmac_dbdma_reset(pmac_t *chip)
+static void snd_pmac_dbdma_reset(struct snd_pmac *chip)
 {
 	out_le32(&chip->playback.dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
 	snd_pmac_wait_ack(&chip->playback);
@@ -694,9 +683,9 @@
 /*
  * handling beep
  */
-void snd_pmac_beep_dma_start(pmac_t *chip, int bytes, unsigned long addr, int speed)
+void snd_pmac_beep_dma_start(struct snd_pmac *chip, int bytes, unsigned long addr, int speed)
 {
-	pmac_stream_t *rec = &chip->playback;
+	struct pmac_stream *rec = &chip->playback;
 
 	snd_pmac_dma_stop(rec);
 	st_le16(&chip->extra_dma.cmds->req_count, bytes);
@@ -712,7 +701,7 @@
 	snd_pmac_dma_run(rec, RUN);
 }
 
-void snd_pmac_beep_dma_stop(pmac_t *chip)
+void snd_pmac_beep_dma_stop(struct snd_pmac *chip)
 {
 	snd_pmac_dma_stop(&chip->playback);
 	st_le16(&chip->extra_dma.cmds->command, DBDMA_STOP);
@@ -726,7 +715,7 @@
 static irqreturn_t
 snd_pmac_tx_intr(int irq, void *devid, struct pt_regs *regs)
 {
-	pmac_t *chip = devid;
+	struct snd_pmac *chip = devid;
 	snd_pmac_pcm_update(chip, &chip->playback);
 	return IRQ_HANDLED;
 }
@@ -735,7 +724,7 @@
 static irqreturn_t
 snd_pmac_rx_intr(int irq, void *devid, struct pt_regs *regs)
 {
-	pmac_t *chip = devid;
+	struct snd_pmac *chip = devid;
 	snd_pmac_pcm_update(chip, &chip->capture);
 	return IRQ_HANDLED;
 }
@@ -744,7 +733,7 @@
 static irqreturn_t
 snd_pmac_ctrl_intr(int irq, void *devid, struct pt_regs *regs)
 {
-	pmac_t *chip = devid;
+	struct snd_pmac *chip = devid;
 	int ctrl = in_le32(&chip->awacs->control);
 
 	/*printk("pmac: control interrupt.. 0x%x\n", ctrl);*/
@@ -767,7 +756,7 @@
 /*
  * a wrapper to feature call for compatibility
  */
-static void snd_pmac_sound_feature(pmac_t *chip, int enable)
+static void snd_pmac_sound_feature(struct snd_pmac *chip, int enable)
 {
 	if (ppc_md.feature_call)
 		ppc_md.feature_call(PMAC_FTR_SOUND_CHIP_ENABLE, chip->node, 0, enable);
@@ -777,7 +766,7 @@
  * release resources
  */
 
-static int snd_pmac_free(pmac_t *chip)
+static int snd_pmac_free(struct snd_pmac *chip)
 {
 	/* stop sounds */
 	if (chip->initialized) {
@@ -787,9 +776,6 @@
 	}
 
 	snd_pmac_sound_feature(chip, 0);
-#ifdef CONFIG_PM
-	snd_pmac_unregister_sleep_notifier(chip);
-#endif
 
 	/* clean up mixer if any */
 	if (chip->mixer_free)
@@ -842,9 +828,9 @@
 /*
  * free the device
  */
-static int snd_pmac_dev_free(snd_device_t *device)
+static int snd_pmac_dev_free(struct snd_device *device)
 {
-	pmac_t *chip = device->device_data;
+	struct snd_pmac *chip = device->device_data;
 	return snd_pmac_free(chip);
 }
 
@@ -853,7 +839,7 @@
  * check the machine support byteswap (little-endian)
  */
 
-static void __init detect_byte_swap(pmac_t *chip)
+static void __init detect_byte_swap(struct snd_pmac *chip)
 {
 	struct device_node *mio;
 
@@ -879,7 +865,7 @@
 /*
  * detect a sound chip
  */
-static int __init snd_pmac_detect(pmac_t *chip)
+static int __init snd_pmac_detect(struct snd_pmac *chip)
 {
 	struct device_node *sound = NULL;
 	unsigned int *prop, l;
@@ -987,11 +973,11 @@
 		 * single frequency until proper i2s control is implemented
 		 */
 		switch(layout_id) {
-		case 0x48:
-		case 0x46:
-		case 0x33:
-		case 0x29:
 		case 0x24:
+		case 0x29:
+		case 0x33:
+		case 0x46:
+		case 0x48:
 		case 0x50:
 		case 0x5c:
 			chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
@@ -1067,8 +1053,8 @@
 /*
  * exported - boolean info callbacks for ease of programming
  */
-int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol,
-				 snd_ctl_elem_info_t *uinfo)
+int snd_pmac_boolean_stereo_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 2;
@@ -1077,8 +1063,8 @@
 	return 0;
 }
 
-int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol,
-			       snd_ctl_elem_info_t *uinfo)
+int snd_pmac_boolean_mono_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1091,16 +1077,18 @@
 /*
  * auto-mute
  */
-static int pmac_auto_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int pmac_auto_mute_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	ucontrol->value.integer.value[0] = chip->auto_mute;
 	return 0;
 }
 
-static int pmac_auto_mute_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int pmac_auto_mute_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	if (ucontrol->value.integer.value[0] != chip->auto_mute) {
 		chip->auto_mute = ucontrol->value.integer.value[0];
 		if (chip->update_automute)
@@ -1110,9 +1098,10 @@
 	return 0;
 }
 
-static int pmac_hp_detect_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int pmac_hp_detect_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	if (chip->detect_headphone)
 		ucontrol->value.integer.value[0] = chip->detect_headphone(chip);
 	else
@@ -1120,7 +1109,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t auto_mute_controls[] __initdata = {
+static struct snd_kcontrol_new auto_mute_controls[] __initdata = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Auto Mute Switch",
 	  .info = snd_pmac_boolean_mono_info,
@@ -1135,7 +1124,7 @@
 	},
 };
 
-int __init snd_pmac_add_automute(pmac_t *chip)
+int __init snd_pmac_add_automute(struct snd_pmac *chip)
 {
 	int err;
 	chip->auto_mute = 1;
@@ -1152,13 +1141,13 @@
 /*
  * create and detect a pmac chip record
  */
-int __init snd_pmac_new(snd_card_t *card, pmac_t **chip_return)
+int __init snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
 {
-	pmac_t *chip;
+	struct snd_pmac *chip;
 	struct device_node *np;
 	int i, err;
 	unsigned long ctrl_addr, txdma_addr, rxdma_addr;
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_pmac_dev_free,
 	};
 
@@ -1298,12 +1287,6 @@
 	/* Reset dbdma channels */
 	snd_pmac_dbdma_reset(chip);
 
-#ifdef CONFIG_PM
-	/* add sleep notifier */
-	if (! snd_pmac_register_sleep_notifier(chip))
-		snd_card_set_pm_callback(chip->card, snd_pmac_suspend, snd_pmac_resume, chip);
-#endif
-
 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
 		goto __error;
 
@@ -1328,11 +1311,11 @@
  * Save state when going to sleep, restore it afterwards.
  */
 
-static int snd_pmac_suspend(snd_card_t *card, pm_message_t state)
+void snd_pmac_suspend(struct snd_pmac *chip)
 {
-	pmac_t *chip = card->pm_private_data;
 	unsigned long flags;
 
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot);
 	if (chip->suspend)
 		chip->suspend(chip);
 	snd_pcm_suspend_all(chip->pcm);
@@ -1346,22 +1329,18 @@
 	if (chip->rx_irq >= 0)
 		disable_irq(chip->rx_irq);
 	snd_pmac_sound_feature(chip, 0);
-	return 0;
 }
 
-static int snd_pmac_resume(snd_card_t *card)
+void snd_pmac_resume(struct snd_pmac *chip)
 {
-	pmac_t *chip = card->pm_private_data;
-
 	snd_pmac_sound_feature(chip, 1);
 	if (chip->resume)
 		chip->resume(chip);
 	/* enable CD sound input */
-	if (chip->macio_base && chip->is_pbook_G3) {
+	if (chip->macio_base && chip->is_pbook_G3)
 		out_8(chip->macio_base + 0x37, 3);
-	} else if (chip->is_pbook_3400) {
+	else if (chip->is_pbook_3400)
 		in_8(chip->latch_base + 0x190);
-	}
 
 	snd_pmac_pcm_set_format(chip);
 
@@ -1372,53 +1351,7 @@
 	if (chip->rx_irq >= 0)
 		enable_irq(chip->rx_irq);
 
-	return 0;
-}
-
-/* the chip is stored statically by snd_pmac_register_sleep_notifier
- * because we can't have any private data for notify callback.
- */
-static pmac_t *sleeping_pmac = NULL;
-
-static int snd_pmac_sleep_notify(struct pmu_sleep_notifier *self, int when)
-{
-	pmac_t *chip;
-
-	chip = sleeping_pmac;
-	if (! chip)
-		return 0;
-
-	switch (when) {
-	case PBOOK_SLEEP_NOW:
-		snd_pmac_suspend(chip->card, PMSG_SUSPEND);
-		break;
-	case PBOOK_WAKE:
-		snd_pmac_resume(chip->card);
-		break;
-	}
-	return PBOOK_SLEEP_OK;
-}
-
-static struct pmu_sleep_notifier snd_pmac_sleep_notifier = {
-	snd_pmac_sleep_notify, SLEEP_LEVEL_SOUND,
-};
-
-static int __init snd_pmac_register_sleep_notifier(pmac_t *chip)
-{
-	/* should be protected here.. */
-	snd_assert(! sleeping_pmac, return -EBUSY);
-	sleeping_pmac = chip;
-	pmu_register_sleep_notifier(&snd_pmac_sleep_notifier);
-	return 0;
-}
-						    
-static int snd_pmac_unregister_sleep_notifier(pmac_t *chip)
-{
-	/* should be protected here.. */
-	snd_assert(sleeping_pmac == chip, return -ENODEV);
-	pmu_unregister_sleep_notifier(&snd_pmac_sleep_notifier);
-	sleeping_pmac = NULL;
-	return 0;
+	snd_power_change_state(chip->card, SNDRV_CTL_POWER_D0);
 }
 
 #endif /* CONFIG_PM */
diff --git a/sound/ppc/pmac.h b/sound/ppc/pmac.h
index bfff788..086da7a 100644
--- a/sound/ppc/pmac.h
+++ b/sound/ppc/pmac.h
@@ -47,18 +47,9 @@
 #define PMAC_SUPPORT_AUTOMUTE
 
 /*
- * typedefs
- */
-typedef struct snd_pmac pmac_t;
-typedef struct snd_pmac_stream pmac_stream_t;
-typedef struct snd_pmac_beep pmac_beep_t;
-typedef struct snd_pmac_dbdma pmac_dbdma_t;
-
-
-/*
  * DBDMA space
  */
-struct snd_pmac_dbdma {
+struct pmac_dbdma {
 	dma_addr_t dma_base;
 	dma_addr_t addr;
 	struct dbdma_cmd __iomem *cmds;
@@ -69,7 +60,7 @@
 /*
  * playback/capture stream
  */
-struct snd_pmac_stream {
+struct pmac_stream {
 	int running;	/* boolean */
 
 	int stream;	/* PLAYBACK/CAPTURE */
@@ -79,10 +70,10 @@
 	int buffer_size; /* in kbytes */
 	int nperiods, cur_period;
 
-	pmac_dbdma_t cmd;
+	struct pmac_dbdma cmd;
 	volatile struct dbdma_regs __iomem *dma;
 
-	snd_pcm_substream_t *substream;
+	struct snd_pcm_substream *substream;
 
 	unsigned int cur_freqs;		/* currently available frequencies */
 	unsigned int cur_formats;	/* currently available formats */
@@ -98,7 +89,7 @@
 };
 
 struct snd_pmac {
-	snd_card_t *card;
+	struct snd_card *card;
 
 	/* h/w info */
 	struct device_node *node;
@@ -140,75 +131,80 @@
 	unsigned char __iomem *latch_base;
 	unsigned char __iomem *macio_base;
 
-	pmac_stream_t playback;
-	pmac_stream_t capture;
+	struct pmac_stream playback;
+	struct pmac_stream capture;
 
-	pmac_dbdma_t extra_dma;
+	struct pmac_dbdma extra_dma;
 
 	int irq, tx_irq, rx_irq;
 
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 
-	pmac_beep_t *beep;
+	struct pmac_beep *beep;
 
 	unsigned int control_mask;	/* control mask */
 
 	/* mixer stuffs */
 	void *mixer_data;
-	void (*mixer_free)(pmac_t *);
-	snd_kcontrol_t *master_sw_ctl;
-	snd_kcontrol_t *speaker_sw_ctl;
-	snd_kcontrol_t *drc_sw_ctl;	/* only used for tumbler -ReneR */
-	snd_kcontrol_t *hp_detect_ctl;
-	snd_kcontrol_t *lineout_sw_ctl;
+	void (*mixer_free)(struct snd_pmac *);
+	struct snd_kcontrol *master_sw_ctl;
+	struct snd_kcontrol *speaker_sw_ctl;
+	struct snd_kcontrol *drc_sw_ctl;	/* only used for tumbler -ReneR */
+	struct snd_kcontrol *hp_detect_ctl;
+	struct snd_kcontrol *lineout_sw_ctl;
 
 	/* lowlevel callbacks */
-	void (*set_format)(pmac_t *chip);
-	void (*update_automute)(pmac_t *chip, int do_notify);
-	int (*detect_headphone)(pmac_t *chip);
+	void (*set_format)(struct snd_pmac *chip);
+	void (*update_automute)(struct snd_pmac *chip, int do_notify);
+	int (*detect_headphone)(struct snd_pmac *chip);
 #ifdef CONFIG_PM
-	void (*suspend)(pmac_t *chip);
-	void (*resume)(pmac_t *chip);
+	void (*suspend)(struct snd_pmac *chip);
+	void (*resume)(struct snd_pmac *chip);
 #endif
 
 };
 
 
 /* exported functions */
-int snd_pmac_new(snd_card_t *card, pmac_t **chip_return);
-int snd_pmac_pcm_new(pmac_t *chip);
-int snd_pmac_attach_beep(pmac_t *chip);
-void snd_pmac_detach_beep(pmac_t *chip);
-void snd_pmac_beep_stop(pmac_t *chip);
-unsigned int snd_pmac_rate_index(pmac_t *chip, pmac_stream_t *rec, unsigned int rate);
+int snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return);
+int snd_pmac_pcm_new(struct snd_pmac *chip);
+int snd_pmac_attach_beep(struct snd_pmac *chip);
+void snd_pmac_detach_beep(struct snd_pmac *chip);
+void snd_pmac_beep_stop(struct snd_pmac *chip);
+unsigned int snd_pmac_rate_index(struct snd_pmac *chip, struct pmac_stream *rec, unsigned int rate);
 
-void snd_pmac_beep_dma_start(pmac_t *chip, int bytes, unsigned long addr, int speed);
-void snd_pmac_beep_dma_stop(pmac_t *chip);
+void snd_pmac_beep_dma_start(struct snd_pmac *chip, int bytes, unsigned long addr, int speed);
+void snd_pmac_beep_dma_stop(struct snd_pmac *chip);
+
+#ifdef CONFIG_PM
+void snd_pmac_suspend(struct snd_pmac *chip);
+void snd_pmac_resume(struct snd_pmac *chip);
+#endif
 
 /* initialize mixer */
-int snd_pmac_awacs_init(pmac_t *chip);
-int snd_pmac_burgundy_init(pmac_t *chip);
-int snd_pmac_daca_init(pmac_t *chip);
-int snd_pmac_tumbler_init(pmac_t *chip);
+int snd_pmac_awacs_init(struct snd_pmac *chip);
+int snd_pmac_burgundy_init(struct snd_pmac *chip);
+int snd_pmac_daca_init(struct snd_pmac *chip);
+int snd_pmac_tumbler_init(struct snd_pmac *chip);
 int snd_pmac_tumbler_post_init(void);
-int snd_pmac_toonie_init(pmac_t *chip);
+int snd_pmac_toonie_init(struct snd_pmac *chip);
 
 /* i2c functions */
-typedef struct snd_pmac_keywest {
+struct pmac_keywest {
 	int addr;
 	struct i2c_client *client;
 	int id;
-	int (*init_client)(struct snd_pmac_keywest *i2c);
+	int (*init_client)(struct pmac_keywest *i2c);
 	char *name;
-} pmac_keywest_t;
+};
 
-int snd_pmac_keywest_init(pmac_keywest_t *i2c);
-void snd_pmac_keywest_cleanup(pmac_keywest_t *i2c);
+int snd_pmac_keywest_init(struct pmac_keywest *i2c);
+void snd_pmac_keywest_cleanup(struct pmac_keywest *i2c);
 
 /* misc */
-int snd_pmac_boolean_stereo_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo);
-int snd_pmac_boolean_mono_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo);
+int snd_pmac_boolean_stereo_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
+int snd_pmac_boolean_mono_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
 
-int snd_pmac_add_automute(pmac_t *chip);
+int snd_pmac_add_automute(struct snd_pmac *chip);
 
 #endif /* __PMAC_H */
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index a6d8cbf..f4902a2 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -20,6 +20,8 @@
 
 #include <sound/driver.h>
 #include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
 #include <linux/moduleparam.h>
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -44,20 +46,16 @@
 module_param(enable_beep, bool, 0444);
 MODULE_PARM_DESC(enable_beep, "Enable beep using PCM.");
 
+static struct platform_device *device;
 
-/*
- * card entry
- */
-
-static snd_card_t *snd_pmac_card = NULL;
 
 /*
  */
 
-static int __init snd_pmac_probe(void)
+static int __init snd_pmac_probe(struct platform_device *devptr)
 {
-	snd_card_t *card;
-	pmac_t *chip;
+	struct snd_card *card;
+	struct snd_pmac *chip;
 	char *name_ext;
 	int err;
 
@@ -67,6 +65,7 @@
 
 	if ((err = snd_pmac_new(card, &chip)) < 0)
 		goto __error;
+	card->private_data = chip;
 
 	switch (chip->model) {
 	case PMAC_BURGUNDY:
@@ -131,13 +130,12 @@
 	if (enable_beep)
 		snd_pmac_attach_beep(chip);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto __error;
+	snd_card_set_dev(card, &devptr->dev);
 
 	if ((err = snd_card_register(card)) < 0)
 		goto __error;
 
-	snd_pmac_card = card;
+	platform_set_drvdata(devptr, card);
 	return 0;
 
 __error:
@@ -146,23 +144,62 @@
 }
 
 
-/*
- * MODULE stuff
- */
+static int __devexit snd_pmac_remove(struct platform_device *devptr)
+{
+	snd_card_free(platform_get_drvdata(devptr));
+	platform_set_drvdata(devptr, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_pmac_driver_suspend(struct platform_device *devptr, pm_message_t state)
+{
+	struct snd_card *card = platform_get_drvdata(devptr);
+	snd_pmac_suspend(card->private_data);
+	return 0;
+}
+
+static int snd_pmac_driver_resume(struct platform_device *devptr)
+{
+	struct snd_card *card = platform_get_drvdata(devptr);
+	snd_pmac_resume(card->private_data);
+	return 0;
+}
+#endif
+
+#define SND_PMAC_DRIVER		"snd_powermac"
+
+static struct platform_driver snd_pmac_driver = {
+	.probe		= snd_pmac_probe,
+	.remove		= __devexit_p(snd_pmac_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_pmac_driver_suspend,
+	.resume		= snd_pmac_driver_resume,
+#endif
+	.driver		= {
+		.name	= SND_PMAC_DRIVER
+	},
+};
 
 static int __init alsa_card_pmac_init(void)
 {
 	int err;
-	if ((err = snd_pmac_probe()) < 0)
+
+	if ((err = platform_driver_register(&snd_pmac_driver)) < 0)
 		return err;
+	device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0);
+	if (IS_ERR(device)) {
+		platform_driver_unregister(&snd_pmac_driver);
+		return PTR_ERR(device);
+	}
 	return 0;
 
 }
 
 static void __exit alsa_card_pmac_exit(void)
 {
-	if (snd_pmac_card)
-		snd_card_free(snd_pmac_card);
+	platform_device_unregister(device);
+	platform_driver_unregister(&snd_pmac_driver);
 }
 
 module_init(alsa_card_pmac_init)
diff --git a/sound/ppc/toonie.c b/sound/ppc/toonie.c
index 082bc4b..053b8f2 100644
--- a/sound/ppc/toonie.c
+++ b/sound/ppc/toonie.c
@@ -101,10 +101,10 @@
 
 enum { TOONIE_MUTE_HP, TOONIE_MUTE_AMP };
 
-static int toonie_get_mute_switch(snd_kcontrol_t *kcontrol,
-				  snd_ctl_elem_value_t *ucontrol)
+static int toonie_get_mute_switch(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	struct pmac_toonie *mix = chip->mixer_data;
 	struct pmac_gpio *gp;
 
@@ -124,10 +124,10 @@
 	return 0;
 }
 
-static int toonie_put_mute_switch(snd_kcontrol_t *kcontrol,
-				   snd_ctl_elem_value_t *ucontrol)
+static int toonie_put_mute_switch(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	struct pmac_toonie *mix = chip->mixer_data;
 	struct pmac_gpio *gp;
 	int val;
@@ -156,7 +156,7 @@
 	return 0;
 }
 
-static snd_kcontrol_new_t toonie_hp_sw __initdata = {
+static struct snd_kcontrol_new toonie_hp_sw __initdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Headphone Playback Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -164,7 +164,7 @@
 	.put = toonie_put_mute_switch,
 	.private_value = TOONIE_MUTE_HP,
 };
-static snd_kcontrol_new_t toonie_speaker_sw __initdata = {
+static struct snd_kcontrol_new toonie_speaker_sw __initdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PC Speaker Playback Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -176,7 +176,7 @@
 /*
  * auto-mute stuffs
  */
-static int toonie_detect_headphone(pmac_t *chip)
+static int toonie_detect_headphone(struct snd_pmac *chip)
 {
 	struct pmac_toonie *mix = chip->mixer_data;
 	int detect = 0;
@@ -186,8 +186,8 @@
 	return detect;
 }
 
-static void toonie_check_mute(pmac_t *chip, struct pmac_gpio *gp, int val,
-			      int do_notify, snd_kcontrol_t *sw)
+static void toonie_check_mute(struct snd_pmac *chip, struct pmac_gpio *gp, int val,
+			      int do_notify, struct snd_kcontrol *sw)
 {
 	if (check_audio_gpio(gp) != val) {
 		write_audio_gpio(gp, val);
@@ -199,7 +199,7 @@
 
 static void toonie_detect_handler(void *self)
 {
-	pmac_t *chip = (pmac_t*) self;
+	struct snd_pmac *chip = (struct snd_pmac *) self;
 	struct pmac_toonie *mix;
 	int headphone;
 
@@ -232,7 +232,7 @@
 	}
 }
 
-static void toonie_update_automute(pmac_t *chip, int do_notify)
+static void toonie_update_automute(struct snd_pmac *chip, int do_notify)
 {
 	if (chip->auto_mute) {
 		struct pmac_toonie *mix;
@@ -246,7 +246,7 @@
 /* interrupt - headphone plug changed */
 static irqreturn_t toonie_hp_intr(int irq, void *devid, struct pt_regs *regs)
 {
-	pmac_t *chip = devid;
+	struct snd_pmac *chip = devid;
 
 	if (chip->update_automute && chip->initialized) {
 		chip->update_automute(chip, 1);
@@ -325,7 +325,7 @@
 	return (np->n_intrs > 0) ? np->intrs[0].line : 0;
 }
 
-static void toonie_cleanup(pmac_t *chip)
+static void toonie_cleanup(struct snd_pmac *chip)
 {
 	struct pmac_toonie *mix = chip->mixer_data;
 	if (! mix)
@@ -336,7 +336,7 @@
 	chip->mixer_data = NULL;
 }
 
-int snd_pmac_toonie_init(pmac_t *chip)
+int snd_pmac_toonie_init(struct snd_pmac *chip)
 {
 	struct pmac_toonie *mix;
 
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index d74bfab..15c63cb 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -82,21 +82,21 @@
 	VOL_IDX_LAST_MIX
 };
 
-typedef struct pmac_gpio {
+struct pmac_gpio {
 	unsigned int addr;
 	u8 active_val;
 	u8 inactive_val;
 	u8 active_state;
-} pmac_gpio_t;
+};
 
-typedef struct pmac_tumbler_t {
-	pmac_keywest_t i2c;
-	pmac_gpio_t audio_reset;
-	pmac_gpio_t amp_mute;
-	pmac_gpio_t line_mute;
-	pmac_gpio_t line_detect;
-	pmac_gpio_t hp_mute;
-	pmac_gpio_t hp_detect;
+struct pmac_tumbler {
+	struct pmac_keywest i2c;
+	struct pmac_gpio audio_reset;
+	struct pmac_gpio amp_mute;
+	struct pmac_gpio line_mute;
+	struct pmac_gpio line_detect;
+	struct pmac_gpio hp_mute;
+	struct pmac_gpio hp_detect;
 	int headphone_irq;
 	int lineout_irq;
 	unsigned int save_master_vol[2];
@@ -112,13 +112,13 @@
 	int auto_mute_notify;
 	int reset_on_sleep;
 	u8  acs;
-} pmac_tumbler_t;
+};
 
 
 /*
  */
 
-static int send_init_client(pmac_keywest_t *i2c, unsigned int *regs)
+static int send_init_client(struct pmac_keywest *i2c, unsigned int *regs)
 {
 	while (*regs > 0) {
 		int err, count = 10;
@@ -138,7 +138,7 @@
 }
 
 
-static int tumbler_init_client(pmac_keywest_t *i2c)
+static int tumbler_init_client(struct pmac_keywest *i2c)
 {
 	static unsigned int regs[] = {
 		/* normal operation, SCLK=64fps, i2s output, i2s input, 16bit width */
@@ -149,7 +149,7 @@
 	return send_init_client(i2c, regs);
 }
 
-static int snapper_init_client(pmac_keywest_t *i2c)
+static int snapper_init_client(struct pmac_keywest *i2c)
 {
 	static unsigned int regs[] = {
 		/* normal operation, SCLK=64fps, i2s output, 16bit width */
@@ -173,7 +173,7 @@
 	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
 #define tumbler_gpio_free(gp) /* NOP */
 
-static void write_audio_gpio(pmac_gpio_t *gp, int active)
+static void write_audio_gpio(struct pmac_gpio *gp, int active)
 {
 	if (! gp->addr)
 		return;
@@ -182,7 +182,7 @@
 	DBG("(I) gpio %x write %d\n", gp->addr, active);
 }
 
-static int check_audio_gpio(pmac_gpio_t *gp)
+static int check_audio_gpio(struct pmac_gpio *gp)
 {
 	int ret;
 
@@ -194,7 +194,7 @@
 	return (ret & 0xd) == (gp->active_val & 0xd);
 }
 
-static int read_audio_gpio(pmac_gpio_t *gp)
+static int read_audio_gpio(struct pmac_gpio *gp)
 {
 	int ret;
 	if (! gp->addr)
@@ -206,7 +206,7 @@
 /*
  * update master volume
  */
-static int tumbler_set_master_volume(pmac_tumbler_t *mix)
+static int tumbler_set_master_volume(struct pmac_tumbler *mix)
 {
 	unsigned char block[6];
 	unsigned int left_vol, right_vol;
@@ -249,7 +249,8 @@
 
 
 /* output volume */
-static int tumbler_info_master_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int tumbler_info_master_volume(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -258,20 +259,22 @@
 	return 0;
 }
 
-static int tumbler_get_master_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_get_master_volume(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix = chip->mixer_data;
 	snd_assert(mix, return -ENODEV);
 	ucontrol->value.integer.value[0] = mix->master_vol[0];
 	ucontrol->value.integer.value[1] = mix->master_vol[1];
 	return 0;
 }
 
-static int tumbler_put_master_volume(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_put_master_volume(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix = chip->mixer_data;
 	int change;
 
 	snd_assert(mix, return -ENODEV);
@@ -286,20 +289,22 @@
 }
 
 /* output switch */
-static int tumbler_get_master_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_get_master_switch(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix = chip->mixer_data;
 	snd_assert(mix, return -ENODEV);
 	ucontrol->value.integer.value[0] = mix->master_switch[0];
 	ucontrol->value.integer.value[1] = mix->master_switch[1];
 	return 0;
 }
 
-static int tumbler_put_master_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_put_master_switch(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix = chip->mixer_data;
 	int change;
 
 	snd_assert(mix, return -ENODEV);
@@ -320,7 +325,7 @@
 
 #define TAS3001_DRC_MAX		0x5f
 
-static int tumbler_set_drc(pmac_tumbler_t *mix)
+static int tumbler_set_drc(struct pmac_tumbler *mix)
 {
 	unsigned char val[2];
 
@@ -354,7 +359,7 @@
 
 #define TAS3004_DRC_MAX		0xef
 
-static int snapper_set_drc(pmac_tumbler_t *mix)
+static int snapper_set_drc(struct pmac_tumbler *mix)
 {
 	unsigned char val[6];
 
@@ -384,9 +389,10 @@
 	return 0;
 }
 
-static int tumbler_info_drc_value(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int tumbler_info_drc_value(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 1;
 	uinfo->value.integer.min = 0;
@@ -395,20 +401,22 @@
 	return 0;
 }
 
-static int tumbler_get_drc_value(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_get_drc_value(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	ucontrol->value.integer.value[0] = mix->drc_range;
 	return 0;
 }
 
-static int tumbler_put_drc_value(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_put_drc_value(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
 	int change;
 
 	if (! (mix = chip->mixer_data))
@@ -424,20 +432,22 @@
 	return change;
 }
 
-static int tumbler_get_drc_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_get_drc_switch(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	ucontrol->value.integer.value[0] = mix->drc_enable;
 	return 0;
 }
 
-static int tumbler_put_drc_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_put_drc_switch(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
 	int change;
 
 	if (! (mix = chip->mixer_data))
@@ -466,7 +476,8 @@
 	unsigned int *table;
 };
 
-static int tumbler_set_mono_volume(pmac_tumbler_t *mix, struct tumbler_mono_vol *info)
+static int tumbler_set_mono_volume(struct pmac_tumbler *mix,
+				   struct tumbler_mono_vol *info)
 {
 	unsigned char block[4];
 	unsigned int vol;
@@ -489,7 +500,8 @@
 	return 0;
 }
 
-static int tumbler_info_mono(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int tumbler_info_mono(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_info *uinfo)
 {
 	struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
 
@@ -500,22 +512,24 @@
 	return 0;
 }
 
-static int tumbler_get_mono(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_get_mono(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
 {
 	struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	ucontrol->value.integer.value[0] = mix->mono_vol[info->index];
 	return 0;
 }
 
-static int tumbler_put_mono(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_put_mono(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
 {
 	struct tumbler_mono_vol *info = (struct tumbler_mono_vol *)kcontrol->private_value;
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
 	int change;
 
 	if (! (mix = chip->mixer_data))
@@ -594,7 +608,7 @@
  * snapper mixer volumes
  */
 
-static int snapper_set_mix_vol1(pmac_tumbler_t *mix, int idx, int ch, int reg)
+static int snapper_set_mix_vol1(struct pmac_tumbler *mix, int idx, int ch, int reg)
 {
 	int i, j, vol;
 	unsigned char block[9];
@@ -618,7 +632,7 @@
 	return 0;
 }
 
-static int snapper_set_mix_vol(pmac_tumbler_t *mix, int idx)
+static int snapper_set_mix_vol(struct pmac_tumbler *mix, int idx)
 {
 	if (! mix->i2c.client)
 		return -ENODEV;
@@ -628,7 +642,8 @@
 	return 0;
 }
 
-static int snapper_info_mix(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snapper_info_mix(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -637,11 +652,12 @@
 	return 0;
 }
 
-static int snapper_get_mix(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snapper_get_mix(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
 {
 	int idx = (int)kcontrol->private_value;
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	ucontrol->value.integer.value[0] = mix->mix_vol[idx][0];
@@ -649,11 +665,12 @@
 	return 0;
 }
 
-static int snapper_put_mix(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snapper_put_mix(struct snd_kcontrol *kcontrol,
+			   struct snd_ctl_elem_value *ucontrol)
 {
 	int idx = (int)kcontrol->private_value;
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
 	int change;
 
 	if (! (mix = chip->mixer_data))
@@ -676,11 +693,12 @@
 
 enum { TUMBLER_MUTE_HP, TUMBLER_MUTE_AMP, TUMBLER_MUTE_LINE };
 
-static int tumbler_get_mute_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_get_mute_switch(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
-	pmac_gpio_t *gp;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
+	struct pmac_gpio *gp;
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	switch(kcontrol->private_value) {
@@ -699,11 +717,12 @@
 	return 0;
 }
 
-static int tumbler_put_mute_switch(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int tumbler_put_mute_switch(struct snd_kcontrol *kcontrol,
+				   struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix;
-	pmac_gpio_t *gp;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix;
+	struct pmac_gpio *gp;
 	int val;
 #ifdef PMAC_SUPPORT_AUTOMUTE
 	if (chip->update_automute && chip->auto_mute)
@@ -731,7 +750,7 @@
 	return 0;
 }
 
-static int snapper_set_capture_source(pmac_tumbler_t *mix)
+static int snapper_set_capture_source(struct pmac_tumbler *mix)
 {
 	if (! mix->i2c.client)
 		return -ENODEV;
@@ -742,7 +761,8 @@
 	return i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs);
 }
 
-static int snapper_info_capture_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snapper_info_capture_source(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[2] = {
 		"Line", "Mic"
@@ -756,20 +776,22 @@
 	return 0;
 }
 
-static int snapper_get_capture_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snapper_get_capture_source(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix = chip->mixer_data;
 
 	snd_assert(mix, return -ENODEV);
 	ucontrol->value.integer.value[0] = mix->capture_source;
 	return 0;
 }
 
-static int snapper_put_capture_source(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snapper_put_capture_source(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
 {
-	pmac_t *chip = snd_kcontrol_chip(kcontrol);
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct snd_pmac *chip = snd_kcontrol_chip(kcontrol);
+	struct pmac_tumbler *mix = chip->mixer_data;
 	int change;
 
 	snd_assert(mix, return -ENODEV);
@@ -794,7 +816,7 @@
 
 /*
  */
-static snd_kcontrol_new_t tumbler_mixers[] __initdata = {
+static struct snd_kcontrol_new tumbler_mixers[] __initdata = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Master Playback Volume",
 	  .info = tumbler_info_master_volume,
@@ -818,7 +840,7 @@
 	},
 };
 
-static snd_kcontrol_new_t snapper_mixers[] __initdata = {
+static struct snd_kcontrol_new snapper_mixers[] __initdata = {
 	{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	  .name = "Master Playback Volume",
 	  .info = tumbler_info_master_volume,
@@ -850,7 +872,7 @@
 	},
 };
 
-static snd_kcontrol_new_t tumbler_hp_sw __initdata = {
+static struct snd_kcontrol_new tumbler_hp_sw __initdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Headphone Playback Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -858,7 +880,7 @@
 	.put = tumbler_put_mute_switch,
 	.private_value = TUMBLER_MUTE_HP,
 };
-static snd_kcontrol_new_t tumbler_speaker_sw __initdata = {
+static struct snd_kcontrol_new tumbler_speaker_sw __initdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "PC Speaker Playback Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -866,7 +888,7 @@
 	.put = tumbler_put_mute_switch,
 	.private_value = TUMBLER_MUTE_AMP,
 };
-static snd_kcontrol_new_t tumbler_lineout_sw __initdata = {
+static struct snd_kcontrol_new tumbler_lineout_sw __initdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "Line Out Playback Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -874,7 +896,7 @@
 	.put = tumbler_put_mute_switch,
 	.private_value = TUMBLER_MUTE_LINE,
 };
-static snd_kcontrol_new_t tumbler_drc_sw __initdata = {
+static struct snd_kcontrol_new tumbler_drc_sw __initdata = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "DRC Switch",
 	.info = snd_pmac_boolean_mono_info,
@@ -887,9 +909,9 @@
 /*
  * auto-mute stuffs
  */
-static int tumbler_detect_headphone(pmac_t *chip)
+static int tumbler_detect_headphone(struct snd_pmac *chip)
 {
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct pmac_tumbler *mix = chip->mixer_data;
 	int detect = 0;
 
 	if (mix->hp_detect.addr)
@@ -897,9 +919,9 @@
 	return detect;
 }
 
-static int tumbler_detect_lineout(pmac_t *chip)
+static int tumbler_detect_lineout(struct snd_pmac *chip)
 {
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct pmac_tumbler *mix = chip->mixer_data;
 	int detect = 0;
 
 	if (mix->line_detect.addr)
@@ -907,7 +929,8 @@
 	return detect;
 }
 
-static void check_mute(pmac_t *chip, pmac_gpio_t *gp, int val, int do_notify, snd_kcontrol_t *sw)
+static void check_mute(struct snd_pmac *chip, struct pmac_gpio *gp, int val, int do_notify,
+		       struct snd_kcontrol *sw)
 {
 	if (check_audio_gpio(gp) != val) {
 		write_audio_gpio(gp, val);
@@ -921,8 +944,8 @@
 
 static void device_change_handler(void *self)
 {
-	pmac_t *chip = (pmac_t*) self;
-	pmac_tumbler_t *mix;
+	struct snd_pmac *chip = self;
+	struct pmac_tumbler *mix;
 	int headphone, lineout;
 
 	if (!chip)
@@ -979,10 +1002,10 @@
 	tumbler_set_master_volume(mix);
 }
 
-static void tumbler_update_automute(pmac_t *chip, int do_notify)
+static void tumbler_update_automute(struct snd_pmac *chip, int do_notify)
 {
 	if (chip->auto_mute) {
-		pmac_tumbler_t *mix;
+		struct pmac_tumbler *mix;
 		mix = chip->mixer_data;
 		snd_assert(mix, return);
 		mix->auto_mute_notify = do_notify;
@@ -995,7 +1018,7 @@
 /* interrupt - headphone plug changed */
 static irqreturn_t headphone_intr(int irq, void *devid, struct pt_regs *regs)
 {
-	pmac_t *chip = devid;
+	struct snd_pmac *chip = devid;
 	if (chip->update_automute && chip->initialized) {
 		chip->update_automute(chip, 1);
 		return IRQ_HANDLED;
@@ -1035,7 +1058,8 @@
 }
 
 /* find an audio device and get its address */
-static long tumbler_find_device(const char *device, const char *platform, pmac_gpio_t *gp, int is_compatible)
+static long tumbler_find_device(const char *device, const char *platform,
+				struct pmac_gpio *gp, int is_compatible)
 {
 	struct device_node *node;
 	u32 *base, addr;
@@ -1101,9 +1125,9 @@
 }
 
 /* reset audio */
-static void tumbler_reset_audio(pmac_t *chip)
+static void tumbler_reset_audio(struct snd_pmac *chip)
 {
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct pmac_tumbler *mix = chip->mixer_data;
 
 	if (mix->anded_reset) {
 		DBG("(I) codec anded reset !\n");
@@ -1130,9 +1154,9 @@
 
 #ifdef CONFIG_PM
 /* suspend mixer */
-static void tumbler_suspend(pmac_t *chip)
+static void tumbler_suspend(struct snd_pmac *chip)
 {
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct pmac_tumbler *mix = chip->mixer_data;
 
 	if (mix->headphone_irq >= 0)
 		disable_irq(mix->headphone_irq);
@@ -1160,9 +1184,9 @@
 }
 
 /* resume mixer */
-static void tumbler_resume(pmac_t *chip)
+static void tumbler_resume(struct snd_pmac *chip)
 {
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct pmac_tumbler *mix = chip->mixer_data;
 
 	snd_assert(mix, return);
 
@@ -1208,10 +1232,10 @@
 #endif
 
 /* initialize tumbler */
-static int __init tumbler_init(pmac_t *chip)
+static int __init tumbler_init(struct snd_pmac *chip)
 {
 	int irq;
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct pmac_tumbler *mix = chip->mixer_data;
 	snd_assert(mix, return -EINVAL);
 
 	if (tumbler_find_device("audio-hw-reset",
@@ -1259,9 +1283,9 @@
 	return 0;
 }
 
-static void tumbler_cleanup(pmac_t *chip)
+static void tumbler_cleanup(struct snd_pmac *chip)
 {
-	pmac_tumbler_t *mix = chip->mixer_data;
+	struct pmac_tumbler *mix = chip->mixer_data;
 	if (! mix)
 		return;
 
@@ -1279,10 +1303,10 @@
 }
 
 /* exported */
-int __init snd_pmac_tumbler_init(pmac_t *chip)
+int __init snd_pmac_tumbler_init(struct snd_pmac *chip)
 {
 	int i, err;
-	pmac_tumbler_t *mix;
+	struct pmac_tumbler *mix;
 	u32 *paddr;
 	struct device_node *tas_node, *np;
 	char *chipname;
diff --git a/sound/sparc/Kconfig b/sound/sparc/Kconfig
index 09ab138..079e22a 100644
--- a/sound/sparc/Kconfig
+++ b/sound/sparc/Kconfig
@@ -1,13 +1,12 @@
 # ALSA Sparc drivers
 
 menu "ALSA Sparc devices"
-	depends on SND!=n && (SPARC32 || SPARC64)
+	depends on SND!=n && SPARC
 
 config SND_SUN_AMD7930
 	tristate "Sun AMD7930"
 	depends on SBUS && SND
 	select SND_PCM
-	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for AMD7930 sound device on Sun.
 
@@ -18,7 +17,6 @@
 	tristate "Sun CS4231"
 	depends on SND
 	select SND_PCM
-	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for CS4231 sound device on Sun.
 
@@ -29,7 +27,6 @@
 	tristate "Sun DBRI"
 	depends on SND && SBUS
 	select SND_PCM
-	select SND_GENERIC_DRIVER
 	help
 	  Say Y here to include support for DBRI sound device on Sun.
 
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index 46d504b..5549334 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -311,7 +311,7 @@
 #define	AMR_PP_PPCR2			0xC8
 #define	AMR_PP_PPCR3			0xC9
 
-typedef struct snd_amd7930 {
+struct snd_amd7930 {
 	spinlock_t		lock;
 	void __iomem		*regs;
 	u32			flags;
@@ -320,10 +320,10 @@
 
 	struct amd7930_map	map;
 
-	snd_card_t		*card;
-	snd_pcm_t		*pcm;
-	snd_pcm_substream_t	*playback_substream;
-	snd_pcm_substream_t	*capture_substream;
+	struct snd_card		*card;
+	struct snd_pcm		*pcm;
+	struct snd_pcm_substream	*playback_substream;
+	struct snd_pcm_substream	*capture_substream;
 
 	/* Playback/Capture buffer state. */
 	unsigned char		*p_orig, *p_cur;
@@ -339,12 +339,12 @@
 	unsigned int		irq;
 	unsigned int		regs_size;
 	struct snd_amd7930	*next;
-} amd7930_t;
+};
 
-static amd7930_t *amd7930_list;
+static struct snd_amd7930 *amd7930_list;
 
 /* Idle the AMD7930 chip.  The amd->lock is not held.  */
-static __inline__ void amd7930_idle(amd7930_t *amd)
+static __inline__ void amd7930_idle(struct snd_amd7930 *amd)
 {
 	unsigned long flags;
 
@@ -355,7 +355,7 @@
 }
 
 /* Enable chip interrupts.  The amd->lock is not held.  */
-static __inline__ void amd7930_enable_ints(amd7930_t *amd)
+static __inline__ void amd7930_enable_ints(struct snd_amd7930 *amd)
 {
 	unsigned long flags;
 
@@ -366,7 +366,7 @@
 }
 
 /* Disable chip interrupts.  The amd->lock is not held.  */
-static __inline__ void amd7930_disable_ints(amd7930_t *amd)
+static __inline__ void amd7930_disable_ints(struct snd_amd7930 *amd)
 {
 	unsigned long flags;
 
@@ -379,7 +379,7 @@
 /* Commit amd7930_map settings to the hardware.
  * The amd->lock is held and local interrupts are disabled.
  */
-static void __amd7930_write_map(amd7930_t *amd)
+static void __amd7930_write_map(struct snd_amd7930 *amd)
 {
 	struct amd7930_map *map = &amd->map;
 
@@ -473,7 +473,7 @@
 /* Update amd7930_map settings and program them into the hardware.
  * The amd->lock is held and local interrupts are disabled.
  */
-static void __amd7930_update_map(amd7930_t *amd)
+static void __amd7930_update_map(struct snd_amd7930 *amd)
 {
 	struct amd7930_map *map = &amd->map;
 	int level;
@@ -493,7 +493,7 @@
 
 static irqreturn_t snd_amd7930_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	amd7930_t *amd = dev_id;
+	struct snd_amd7930 *amd = dev_id;
 	unsigned int elapsed;
 	u8 ir;
 
@@ -534,7 +534,7 @@
 	return IRQ_HANDLED;
 }
 
-static int snd_amd7930_trigger(amd7930_t *amd, unsigned int flag, int cmd)
+static int snd_amd7930_trigger(struct snd_amd7930 *amd, unsigned int flag, int cmd)
 {
 	unsigned long flags;
 	int result = 0;
@@ -564,24 +564,24 @@
 	return result;
 }
 
-static int snd_amd7930_playback_trigger(snd_pcm_substream_t * substream,
+static int snd_amd7930_playback_trigger(struct snd_pcm_substream *substream,
 					int cmd)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
 	return snd_amd7930_trigger(amd, AMD7930_FLAG_PLAYBACK, cmd);
 }
 
-static int snd_amd7930_capture_trigger(snd_pcm_substream_t * substream,
+static int snd_amd7930_capture_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
 	return snd_amd7930_trigger(amd, AMD7930_FLAG_CAPTURE, cmd);
 }
 
-static int snd_amd7930_playback_prepare(snd_pcm_substream_t * substream)
+static int snd_amd7930_playback_prepare(struct snd_pcm_substream *substream)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned long flags;
 	u8 new_mmr1;
@@ -610,10 +610,10 @@
 	return 0;
 }
 
-static int snd_amd7930_capture_prepare(snd_pcm_substream_t * substream)
+static int snd_amd7930_capture_prepare(struct snd_pcm_substream *substream)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned int size = snd_pcm_lib_buffer_bytes(substream);
 	unsigned long flags;
 	u8 new_mmr1;
@@ -642,9 +642,9 @@
 	return 0;
 }
 
-static snd_pcm_uframes_t snd_amd7930_playback_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_amd7930_playback_pointer(struct snd_pcm_substream *substream)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(amd->flags & AMD7930_FLAG_PLAYBACK))
@@ -653,9 +653,9 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_amd7930_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_amd7930_capture_pointer(struct snd_pcm_substream *substream)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
 	size_t ptr;
 
 	if (!(amd->flags & AMD7930_FLAG_CAPTURE))
@@ -666,7 +666,7 @@
 }
 
 /* Playback and capture have identical properties.  */
-static snd_pcm_hardware_t snd_amd7930_pcm_hw =
+static struct snd_pcm_hardware snd_amd7930_pcm_hw =
 {
 	.info			= (SNDRV_PCM_INFO_MMAP |
 				   SNDRV_PCM_INFO_MMAP_VALID |
@@ -686,54 +686,54 @@
 	.periods_max		= 1024,
 };
 
-static int snd_amd7930_playback_open(snd_pcm_substream_t * substream)
+static int snd_amd7930_playback_open(struct snd_pcm_substream *substream)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	amd->playback_substream = substream;
 	runtime->hw = snd_amd7930_pcm_hw;
 	return 0;
 }
 
-static int snd_amd7930_capture_open(snd_pcm_substream_t * substream)
+static int snd_amd7930_capture_open(struct snd_pcm_substream *substream)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	amd->capture_substream = substream;
 	runtime->hw = snd_amd7930_pcm_hw;
 	return 0;
 }
 
-static int snd_amd7930_playback_close(snd_pcm_substream_t * substream)
+static int snd_amd7930_playback_close(struct snd_pcm_substream *substream)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
 
 	amd->playback_substream = NULL;
 	return 0;
 }
 
-static int snd_amd7930_capture_close(snd_pcm_substream_t * substream)
+static int snd_amd7930_capture_close(struct snd_pcm_substream *substream)
 {
-	amd7930_t *amd = snd_pcm_substream_chip(substream);
+	struct snd_amd7930 *amd = snd_pcm_substream_chip(substream);
 
 	amd->capture_substream = NULL;
 	return 0;
 }
 
-static int snd_amd7930_hw_params(snd_pcm_substream_t * substream,
-				    snd_pcm_hw_params_t * hw_params)
+static int snd_amd7930_hw_params(struct snd_pcm_substream *substream,
+				    struct snd_pcm_hw_params *hw_params)
 {
 	return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
 }
 
-static int snd_amd7930_hw_free(snd_pcm_substream_t * substream)
+static int snd_amd7930_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static snd_pcm_ops_t snd_amd7930_playback_ops = {
+static struct snd_pcm_ops snd_amd7930_playback_ops = {
 	.open		=	snd_amd7930_playback_open,
 	.close		=	snd_amd7930_playback_close,
 	.ioctl		=	snd_pcm_lib_ioctl,
@@ -744,7 +744,7 @@
 	.pointer	=	snd_amd7930_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_amd7930_capture_ops = {
+static struct snd_pcm_ops snd_amd7930_capture_ops = {
 	.open		=	snd_amd7930_capture_open,
 	.close		=	snd_amd7930_capture_close,
 	.ioctl		=	snd_pcm_lib_ioctl,
@@ -755,17 +755,9 @@
 	.pointer	=	snd_amd7930_capture_pointer,
 };
 
-static void snd_amd7930_pcm_free(snd_pcm_t *pcm)
+static int __init snd_amd7930_pcm(struct snd_amd7930 *amd)
 {
-	amd7930_t *amd = pcm->private_data;
-
-	amd->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-static int __init snd_amd7930_pcm(amd7930_t *amd)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(amd->card,
@@ -780,7 +772,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_amd7930_capture_ops);
 
 	pcm->private_data = amd;
-	pcm->private_free = snd_amd7930_pcm_free;
 	pcm->info_flags = 0;
 	strcpy(pcm->name, amd->card->shortname);
 	amd->pcm = pcm;
@@ -796,7 +787,7 @@
 #define VOLUME_CAPTURE	1
 #define VOLUME_PLAYBACK	2
 
-static int snd_amd7930_info_volume(snd_kcontrol_t *kctl, snd_ctl_elem_info_t *uinfo)
+static int snd_amd7930_info_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *uinfo)
 {
 	int type = kctl->private_value;
 
@@ -813,9 +804,9 @@
 	return 0;
 }
 
-static int snd_amd7930_get_volume(snd_kcontrol_t *kctl, snd_ctl_elem_value_t *ucontrol)
+static int snd_amd7930_get_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
 {
-	amd7930_t *amd = snd_kcontrol_chip(kctl);
+	struct snd_amd7930 *amd = snd_kcontrol_chip(kctl);
 	int type = kctl->private_value;
 	int *swval;
 
@@ -841,9 +832,9 @@
 	return 0;
 }
 
-static int snd_amd7930_put_volume(snd_kcontrol_t *kctl, snd_ctl_elem_value_t *ucontrol)
+static int snd_amd7930_put_volume(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *ucontrol)
 {
-	amd7930_t *amd = snd_kcontrol_chip(kctl);
+	struct snd_amd7930 *amd = snd_kcontrol_chip(kctl);
 	unsigned long flags;
 	int type = kctl->private_value;
 	int *swval, change;
@@ -879,7 +870,7 @@
 	return change;
 }
 
-static snd_kcontrol_new_t amd7930_controls[] __initdata = {
+static struct snd_kcontrol_new amd7930_controls[] __initdata = {
 	{
 		.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name		=	"Monitor Volume",
@@ -909,9 +900,9 @@
 	},
 };
 
-static int __init snd_amd7930_mixer(amd7930_t *amd)
+static int __init snd_amd7930_mixer(struct snd_amd7930 *amd)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	int idx, err;
 
 	snd_assert(amd != NULL && amd->card != NULL, return -EINVAL);
@@ -928,7 +919,7 @@
 	return 0;
 }
 
-static int snd_amd7930_free(amd7930_t *amd)
+static int snd_amd7930_free(struct snd_amd7930 *amd)
 {
 	amd7930_idle(amd);
 
@@ -943,27 +934,27 @@
 	return 0;
 }
 
-static int snd_amd7930_dev_free(snd_device_t *device)
+static int snd_amd7930_dev_free(struct snd_device *device)
 {
-	amd7930_t *amd = device->device_data;
+	struct snd_amd7930 *amd = device->device_data;
 
 	return snd_amd7930_free(amd);
 }
 
-static snd_device_ops_t snd_amd7930_dev_ops = {
+static struct snd_device_ops snd_amd7930_dev_ops = {
 	.dev_free	=	snd_amd7930_dev_free,
 };
 
-static int __init snd_amd7930_create(snd_card_t *card,
+static int __init snd_amd7930_create(struct snd_card *card,
 				     struct sbus_dev *sdev,
 				     struct resource *rp,
 				     unsigned int reg_size,
 				     struct linux_prom_irqs *irq_prop,
 				     int dev,
-				     amd7930_t **ramd)
+				     struct snd_amd7930 **ramd)
 {
 	unsigned long flags;
-	amd7930_t *amd;
+	struct snd_amd7930 *amd;
 	int err;
 
 	*ramd = NULL;
@@ -1032,8 +1023,8 @@
 	struct linux_prom_registers reg_prop;
 	struct linux_prom_irqs irq_prop;
 	struct resource res, *rp;
-	snd_card_t *card;
-	amd7930_t *amd;
+	struct snd_card *card;
+	struct snd_amd7930 *amd;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -1088,9 +1079,6 @@
 	if ((err = snd_amd7930_mixer(amd)) < 0)
 		goto out_err;
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto out_err;
-
 	if ((err = snd_card_register(card)) < 0)
 		goto out_err;
 
@@ -1132,10 +1120,10 @@
 
 static void __exit amd7930_exit(void)
 {
-	amd7930_t *p = amd7930_list;
+	struct snd_amd7930 *p = amd7930_list;
 
 	while (p != NULL) {
-		amd7930_t *next = p->next;
+		struct snd_amd7930 *next = p->next;
 
 		snd_card_free(p->card);
 
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 1f8d27a..e9086e9 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -62,49 +62,47 @@
 MODULE_SUPPORTED_DEVICE("{{Sun,CS4231}}");
 
 #ifdef SBUS_SUPPORT
-typedef struct sbus_dma_info {
+struct sbus_dma_info {
        spinlock_t      lock;
        int             dir;
        void __iomem    *regs;
-} sbus_dma_info_t;
+};
 #endif
 
-typedef struct snd_cs4231 cs4231_t;
-
-typedef struct cs4231_dma_control {
+struct cs4231_dma_control {
         void		(*prepare)(struct cs4231_dma_control *dma_cont, int dir);
         void		(*enable)(struct cs4231_dma_control *dma_cont, int on);
         int		(*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len);
         unsigned int	(*address)(struct cs4231_dma_control *dma_cont);
-        void		(*reset)(cs4231_t *chip); 
-        void		(*preallocate)(cs4231_t *chip, snd_pcm_t *pcm); 
+        void		(*reset)(struct snd_cs4231 *chip); 
+        void		(*preallocate)(struct snd_cs4231 *chip, struct snd_snd_pcm *pcm); 
 #ifdef EBUS_SUPPORT
 	struct		ebus_dma_info	ebus_info;
 #endif
 #ifdef SBUS_SUPPORT
 	struct		sbus_dma_info	sbus_info;
 #endif
-} cs4231_dma_control_t;
+};
 
 struct snd_cs4231 {
 	spinlock_t		lock;
 	void __iomem		*port;
 
-	cs4231_dma_control_t	p_dma;
-	cs4231_dma_control_t	c_dma;
+	struct cs4231_dma_control	p_dma;
+	struct cs4231_dma_control	c_dma;
 
 	u32			flags;
 #define CS4231_FLAG_EBUS	0x00000001
 #define CS4231_FLAG_PLAYBACK	0x00000002
 #define CS4231_FLAG_CAPTURE	0x00000004
 
-	snd_card_t		*card;
-	snd_pcm_t		*pcm;
-	snd_pcm_substream_t	*playback_substream;
+	struct snd_card		*card;
+	struct snd_pcm		*pcm;
+	struct snd_pcm_substream	*playback_substream;
 	unsigned int		p_periods_sent;
-	snd_pcm_substream_t	*capture_substream;
+	struct snd_pcm_substream	*capture_substream;
 	unsigned int		c_periods_sent;
-	snd_timer_t		*timer;
+	struct snd_timer	*timer;
 
 	unsigned short mode;
 #define CS4231_MODE_NONE	0x0000
@@ -132,7 +130,7 @@
 	struct snd_cs4231	*next;
 };
 
-static cs4231_t *cs4231_list;
+static struct snd_cs4231 *cs4231_list;
 
 /* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for
  * now....  -DaveM
@@ -341,12 +339,12 @@
 	27042, 32000, 33075, 37800, 44100, 48000
 };
 
-static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
+static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
 	.count	= 14,
 	.list	= rates,
 };
 
-static int snd_cs4231_xrate(snd_pcm_runtime_t *runtime)
+static int snd_cs4231_xrate(struct snd_pcm_runtime *runtime)
 {
 	return snd_pcm_hw_constraint_list(runtime, 0,
 					  SNDRV_PCM_HW_PARAM_RATE,
@@ -389,7 +387,7 @@
 	0x00,			/* 1f/31 - cbrl */
 };
 
-static u8 __cs4231_readb(cs4231_t *cp, void __iomem *reg_addr)
+static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr)
 {
 #ifdef EBUS_SUPPORT
 	if (cp->flags & CS4231_FLAG_EBUS) {
@@ -404,7 +402,7 @@
 #endif
 }
 
-static void __cs4231_writeb(cs4231_t *cp, u8 val, void __iomem *reg_addr)
+static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, void __iomem *reg_addr)
 {
 #ifdef EBUS_SUPPORT
 	if (cp->flags & CS4231_FLAG_EBUS) {
@@ -423,7 +421,7 @@
  *  Basic I/O functions
  */
 
-static void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
+static void snd_cs4231_outm(struct snd_cs4231 *chip, unsigned char reg,
 		     unsigned char mask, unsigned char value)
 {
 	int timeout;
@@ -450,7 +448,7 @@
 	}
 }
 
-static void snd_cs4231_dout(cs4231_t *chip, unsigned char reg, unsigned char value)
+static void snd_cs4231_dout(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
 {
 	int timeout;
 
@@ -467,7 +465,7 @@
 	mb();
 }
 
-static void snd_cs4231_out(cs4231_t *chip, unsigned char reg, unsigned char value)
+static void snd_cs4231_out(struct snd_cs4231 *chip, unsigned char reg, unsigned char value)
 {
 	int timeout;
 
@@ -485,7 +483,7 @@
 	mb();
 }
 
-static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg)
+static unsigned char snd_cs4231_in(struct snd_cs4231 *chip, unsigned char reg)
 {
 	int timeout;
 	unsigned char ret;
@@ -508,7 +506,7 @@
  *  CS4231 detection / MCE routines
  */
 
-static void snd_cs4231_busy_wait(cs4231_t *chip)
+static void snd_cs4231_busy_wait(struct snd_cs4231 *chip)
 {
 	int timeout;
 
@@ -523,7 +521,7 @@
 	     	udelay(1000);
 }
 
-static void snd_cs4231_mce_up(cs4231_t *chip)
+static void snd_cs4231_mce_up(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 	int timeout;
@@ -544,7 +542,7 @@
 	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
-static void snd_cs4231_mce_down(cs4231_t *chip)
+static void snd_cs4231_mce_down(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 	int timeout;
@@ -602,9 +600,11 @@
 	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
-static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, snd_pcm_substream_t *substream, unsigned int *periods_sent)
+static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont,
+				   struct snd_pcm_substream *substream,
+				   unsigned int *periods_sent)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_pcm_runtime *runtime = substream->runtime;
 
 	while (1) {
 		unsigned int period_size = snd_pcm_lib_period_bytes(substream);
@@ -619,10 +619,11 @@
 	}
 }
 
-static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on)
+static void cs4231_dma_trigger(struct snd_pcm_substream *substream,
+			       unsigned int what, int on)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	cs4231_dma_control_t *dma_cont;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct cs4231_dma_control *dma_cont;
 
 	if (what & CS4231_PLAYBACK_ENABLE) {
 		dma_cont = &chip->p_dma;
@@ -650,9 +651,9 @@
 	}
 }
 
-static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_cs4231_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	int result = 0;
 
 	switch (cmd) {
@@ -660,7 +661,7 @@
 	case SNDRV_PCM_TRIGGER_STOP:
 	{
 		unsigned int what = 0;
-		snd_pcm_substream_t *s;
+		struct snd_pcm_substream *s;
 		struct list_head *pos;
 		unsigned long flags;
 
@@ -711,7 +712,7 @@
 	return freq_bits[13];
 }
 
-static unsigned char snd_cs4231_get_format(cs4231_t *chip, int format, int channels)
+static unsigned char snd_cs4231_get_format(struct snd_cs4231 *chip, int format, int channels)
 {
 	unsigned char rformat;
 
@@ -728,7 +729,7 @@
 	return rformat;
 }
 
-static void snd_cs4231_calibrate_mute(cs4231_t *chip, int mute)
+static void snd_cs4231_calibrate_mute(struct snd_cs4231 *chip, int mute)
 {
 	unsigned long flags;
 
@@ -768,7 +769,7 @@
 	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
-static void snd_cs4231_playback_format(cs4231_t *chip, snd_pcm_hw_params_t *params,
+static void snd_cs4231_playback_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params,
 				       unsigned char pdfr)
 {
 	unsigned long flags;
@@ -791,7 +792,7 @@
 	up(&chip->mce_mutex);
 }
 
-static void snd_cs4231_capture_format(cs4231_t *chip, snd_pcm_hw_params_t *params,
+static void snd_cs4231_capture_format(struct snd_cs4231 *chip, struct snd_pcm_hw_params *params,
                                       unsigned char cdfr)
 {
 	unsigned long flags;
@@ -824,18 +825,18 @@
  *  Timer interface
  */
 
-static unsigned long snd_cs4231_timer_resolution(snd_timer_t *timer)
+static unsigned long snd_cs4231_timer_resolution(struct snd_timer *timer)
 {
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 
 	return chip->image[CS4231_PLAYBK_FORMAT] & 1 ? 9969 : 9920;
 }
 
-static int snd_cs4231_timer_start(snd_timer_t *timer)
+static int snd_cs4231_timer_start(struct snd_timer *timer)
 {
 	unsigned long flags;
 	unsigned int ticks;
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 
 	spin_lock_irqsave(&chip->lock, flags);
 	ticks = timer->sticks;
@@ -856,10 +857,10 @@
 	return 0;
 }
 
-static int snd_cs4231_timer_stop(snd_timer_t *timer)
+static int snd_cs4231_timer_stop(struct snd_timer *timer)
 {
 	unsigned long flags;
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 
 	spin_lock_irqsave(&chip->lock, flags);
 	snd_cs4231_out(chip, CS4231_ALT_FEATURE_1,
@@ -869,7 +870,7 @@
 	return 0;
 }
 
-static void snd_cs4231_init(cs4231_t *chip)
+static void __init snd_cs4231_init(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 
@@ -927,7 +928,7 @@
 #endif
 }
 
-static int snd_cs4231_open(cs4231_t *chip, unsigned int mode)
+static int snd_cs4231_open(struct snd_cs4231 *chip, unsigned int mode)
 {
 	unsigned long flags;
 
@@ -962,7 +963,7 @@
 	return 0;
 }
 
-static void snd_cs4231_close(cs4231_t *chip, unsigned int mode)
+static void snd_cs4231_close(struct snd_cs4231 *chip, unsigned int mode)
 {
 	unsigned long flags;
 
@@ -1013,21 +1014,21 @@
  *  timer open/close
  */
 
-static int snd_cs4231_timer_open(snd_timer_t *timer)
+static int snd_cs4231_timer_open(struct snd_timer *timer)
 {
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 	snd_cs4231_open(chip, CS4231_MODE_TIMER);
 	return 0;
 }
 
-static int snd_cs4231_timer_close(snd_timer_t * timer)
+static int snd_cs4231_timer_close(struct snd_timer * timer)
 {
-	cs4231_t *chip = snd_timer_chip(timer);
+	struct snd_cs4231 *chip = snd_timer_chip(timer);
 	snd_cs4231_close(chip, CS4231_MODE_TIMER);
 	return 0;
 }
 
-static struct _snd_timer_hardware snd_cs4231_timer_table =
+static struct snd_timer_hardware snd_cs4231_timer_table =
 {
 	.flags		=	SNDRV_TIMER_HW_AUTO,
 	.resolution	=	9945,
@@ -1043,10 +1044,10 @@
  *  ok.. exported functions..
  */
 
-static int snd_cs4231_playback_hw_params(snd_pcm_substream_t *substream,
-					 snd_pcm_hw_params_t *hw_params)
+static int snd_cs4231_playback_hw_params(struct snd_pcm_substream *substream,
+					 struct snd_pcm_hw_params *hw_params)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	unsigned char new_pdfr;
 	int err;
 
@@ -1061,15 +1062,15 @@
 	return 0;
 }
 
-static int snd_cs4231_playback_hw_free(snd_pcm_substream_t *substream)
+static int snd_cs4231_playback_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream)
+static int snd_cs4231_playback_prepare(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	unsigned long flags;
 
 	spin_lock_irqsave(&chip->lock, flags);
@@ -1086,10 +1087,10 @@
 	return 0;
 }
 
-static int snd_cs4231_capture_hw_params(snd_pcm_substream_t *substream,
-					snd_pcm_hw_params_t *hw_params)
+static int snd_cs4231_capture_hw_params(struct snd_pcm_substream *substream,
+					struct snd_pcm_hw_params *hw_params)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	unsigned char new_cdfr;
 	int err;
 
@@ -1104,14 +1105,14 @@
 	return 0;
 }
 
-static int snd_cs4231_capture_hw_free(snd_pcm_substream_t *substream)
+static int snd_cs4231_capture_hw_free(struct snd_pcm_substream *substream)
 {
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream)
+static int snd_cs4231_capture_prepare(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 	unsigned long flags;
 
 	spin_lock_irqsave(&chip->lock, flags);
@@ -1125,7 +1126,7 @@
 	return 0;
 }
 
-static void snd_cs4231_overrange(cs4231_t *chip)
+static void snd_cs4231_overrange(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 	unsigned char res;
@@ -1138,10 +1139,8 @@
 		chip->capture_substream->runtime->overrange++;
 }
 
-static void snd_cs4231_play_callback(cs4231_t *cookie)
+static void snd_cs4231_play_callback(struct snd_cs4231 *chip)
 {
-	cs4231_t *chip = cookie;
-
 	if (chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) {
 		snd_pcm_period_elapsed(chip->playback_substream);
 		snd_cs4231_advance_dma(&chip->p_dma, chip->playback_substream,
@@ -1149,10 +1148,8 @@
 	}
 }
 
-static void snd_cs4231_capture_callback(cs4231_t *cookie)
+static void snd_cs4231_capture_callback(struct snd_cs4231 *chip)
 {
-	cs4231_t *chip = cookie;
-
 	if (chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) {
 		snd_pcm_period_elapsed(chip->capture_substream);
 		snd_cs4231_advance_dma(&chip->c_dma, chip->capture_substream,
@@ -1160,10 +1157,10 @@
 	}
 }
 
-static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_cs4231_playback_pointer(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	cs4231_dma_control_t *dma_cont = &chip->p_dma;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct cs4231_dma_control *dma_cont = &chip->p_dma;
 	size_t ptr;
 	
 	if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE))
@@ -1175,10 +1172,10 @@
 	return bytes_to_frames(substream->runtime, ptr);
 }
 
-static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_cs4231_capture_pointer(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	cs4231_dma_control_t *dma_cont = &chip->c_dma;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct cs4231_dma_control *dma_cont = &chip->c_dma;
 	size_t ptr;
 	
 	if (!(chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE))
@@ -1194,7 +1191,7 @@
 
  */
 
-static int snd_cs4231_probe(cs4231_t *chip)
+static int __init snd_cs4231_probe(struct snd_cs4231 *chip)
 {
 	unsigned long flags;
 	int i, id, vers;
@@ -1259,7 +1256,7 @@
 	return 0;		/* all things are ok.. */
 }
 
-static snd_pcm_hardware_t snd_cs4231_playback =
+static struct snd_pcm_hardware snd_cs4231_playback =
 {
 	.info			= (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
@@ -1279,7 +1276,7 @@
 	.periods_max		= 1024,
 };
 
-static snd_pcm_hardware_t snd_cs4231_capture =
+static struct snd_pcm_hardware snd_cs4231_capture =
 {
 	.info			= (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START),
@@ -1299,10 +1296,10 @@
 	.periods_max		= 1024,
 };
 
-static int snd_cs4231_playback_open(snd_pcm_substream_t *substream)
+static int snd_cs4231_playback_open(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	runtime->hw = snd_cs4231_playback;
@@ -1319,10 +1316,10 @@
 	return 0;
 }
 
-static int snd_cs4231_capture_open(snd_pcm_substream_t *substream)
+static int snd_cs4231_capture_open(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
 
 	runtime->hw = snd_cs4231_capture;
@@ -1339,9 +1336,9 @@
 	return 0;
 }
 
-static int snd_cs4231_playback_close(snd_pcm_substream_t *substream)
+static int snd_cs4231_playback_close(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 
 	snd_cs4231_close(chip, CS4231_MODE_PLAY);
 	chip->playback_substream = NULL;
@@ -1349,9 +1346,9 @@
 	return 0;
 }
 
-static int snd_cs4231_capture_close(snd_pcm_substream_t *substream)
+static int snd_cs4231_capture_close(struct snd_pcm_substream *substream)
 {
-	cs4231_t *chip = snd_pcm_substream_chip(substream);
+	struct snd_cs4231 *chip = snd_pcm_substream_chip(substream);
 
 	snd_cs4231_close(chip, CS4231_MODE_RECORD);
 	chip->capture_substream = NULL;
@@ -1363,7 +1360,7 @@
  * XXX the audio AUXIO register...
  */
 
-static snd_pcm_ops_t snd_cs4231_playback_ops = {
+static struct snd_pcm_ops snd_cs4231_playback_ops = {
 	.open		=	snd_cs4231_playback_open,
 	.close		=	snd_cs4231_playback_close,
 	.ioctl		=	snd_pcm_lib_ioctl,
@@ -1374,7 +1371,7 @@
 	.pointer	=	snd_cs4231_playback_pointer,
 };
 
-static snd_pcm_ops_t snd_cs4231_capture_ops = {
+static struct snd_pcm_ops snd_cs4231_capture_ops = {
 	.open		=	snd_cs4231_capture_open,
 	.close		=	snd_cs4231_capture_close,
 	.ioctl		=	snd_pcm_lib_ioctl,
@@ -1385,16 +1382,9 @@
 	.pointer	=	snd_cs4231_capture_pointer,
 };
 
-static void snd_cs4231_pcm_free(snd_pcm_t *pcm)
+static int __init snd_cs4231_pcm(struct snd_cs4231 *chip)
 {
-	cs4231_t *chip = pcm->private_data;
-	chip->pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-int snd_cs4231_pcm(cs4231_t *chip)
-{
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(chip->card, "CS4231", 0, 1, 1, &pcm)) < 0)
@@ -1405,7 +1395,6 @@
 	
 	/* global setup */
 	pcm->private_data = chip;
-	pcm->private_free = snd_cs4231_pcm_free;
 	pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
 	strcpy(pcm->name, "CS4231");
 
@@ -1416,16 +1405,10 @@
 	return 0;
 }
 
-static void snd_cs4231_timer_free(snd_timer_t *timer)
+static int __init snd_cs4231_timer(struct snd_cs4231 *chip)
 {
-	cs4231_t *chip = timer->private_data;
-	chip->timer = NULL;
-}
-
-int snd_cs4231_timer(cs4231_t *chip)
-{
-	snd_timer_t *timer;
-	snd_timer_id_t tid;
+	struct snd_timer *timer;
+	struct snd_timer_id tid;
 	int err;
 
 	/* Timer initialization */
@@ -1438,7 +1421,6 @@
 		return err;
 	strcpy(timer->name, "CS4231");
 	timer->private_data = chip;
-	timer->private_free = snd_cs4231_timer_free;
 	timer->hw = snd_cs4231_timer_table;
 	chip->timer = timer;
 
@@ -1449,12 +1431,13 @@
  *  MIXER part
  */
 
-static int snd_cs4231_info_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_cs4231_info_mux(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
 {
 	static char *texts[4] = {
 		"Line", "CD", "Mic", "Mix"
 	};
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 
 	snd_assert(chip->card != NULL, return -EINVAL);
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
@@ -1467,9 +1450,10 @@
 	return 0;
 }
 
-static int snd_cs4231_get_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cs4231_get_mux(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	
 	spin_lock_irqsave(&chip->lock, flags);
@@ -1482,9 +1466,10 @@
 	return 0;
 }
 
-static int snd_cs4231_put_mux(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cs4231_put_mux(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	unsigned short left, right;
 	int change;
@@ -1509,7 +1494,8 @@
 	return change;
 }
 
-int snd_cs4231_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_cs4231_info_single(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -1522,9 +1508,10 @@
 	return 0;
 }
 
-int snd_cs4231_get_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cs4231_get_single(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -1544,9 +1531,10 @@
 	return 0;
 }
 
-int snd_cs4231_put_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cs4231_put_single(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int reg = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -1571,7 +1559,8 @@
 	return change;
 }
 
-int snd_cs4231_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_cs4231_info_double(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -1584,9 +1573,10 @@
 	return 0;
 }
 
-int snd_cs4231_get_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cs4231_get_double(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -1612,9 +1602,10 @@
 	return 0;
 }
 
-int snd_cs4231_put_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_cs4231_put_double(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	cs4231_t *chip = snd_kcontrol_chip(kcontrol);
+	struct snd_cs4231 *chip = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int left_reg = kcontrol->private_value & 0xff;
 	int right_reg = (kcontrol->private_value >> 8) & 0xff;
@@ -1659,7 +1650,7 @@
   .get = snd_cs4231_get_double, .put = snd_cs4231_put_double, \
   .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
 
-static snd_kcontrol_new_t snd_cs4231_controls[] = {
+static struct snd_kcontrol_new snd_cs4231_controls[] __initdata = {
 CS4231_DOUBLE("PCM Playback Switch", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
 CS4231_DOUBLE("PCM Playback Volume", 0, CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
 CS4231_DOUBLE("Line Playback Switch", 0, CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
@@ -1688,9 +1679,9 @@
 CS4231_SINGLE("Headphone Out Switch", 0, CS4231_PIN_CTRL, 7, 1, 1)
 };
                                         
-int snd_cs4231_mixer(cs4231_t *chip)
+static int __init snd_cs4231_mixer(struct snd_cs4231 *chip)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	int err, idx;
 
 	snd_assert(chip != NULL && chip->pcm != NULL, return -EINVAL);
@@ -1710,9 +1701,9 @@
 
 static int dev;
 
-static int cs4231_attach_begin(snd_card_t **rcard)
+static int __init cs4231_attach_begin(struct snd_card **rcard)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 
 	*rcard = NULL;
 
@@ -1735,7 +1726,7 @@
 	return 0;
 }
 
-static int cs4231_attach_finish(snd_card_t *card, cs4231_t *chip)
+static int __init cs4231_attach_finish(struct snd_card *card, struct snd_cs4231 *chip)
 {
 	int err;
 
@@ -1748,9 +1739,6 @@
 	if ((err = snd_cs4231_timer(chip)) < 0)
 		goto out_err;
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto out_err;
-
 	if ((err = snd_card_register(card)) < 0)
 		goto out_err;
 
@@ -1772,7 +1760,7 @@
 	unsigned long flags;
 	unsigned char status;
 	u32 csr;
-	cs4231_t *chip = dev_id;
+	struct snd_cs4231 *chip = dev_id;
 
 	/*This is IRQ is not raised by the cs4231*/
 	if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
@@ -1817,12 +1805,12 @@
  * SBUS DMA routines
  */
 
-int sbus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
+static int sbus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
 {
 	unsigned long flags;
 	u32 test, csr;
 	int err;
-	sbus_dma_info_t *base = &dma_cont->sbus_info;
+	struct sbus_dma_info *base = &dma_cont->sbus_info;
 	
 	if (len >= (1 << 24))
 		return -EINVAL;
@@ -1849,11 +1837,11 @@
 	return err;
 }
 
-void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d)
+static void sbus_dma_prepare(struct cs4231_dma_control *dma_cont, int d)
 {
 	unsigned long flags;
 	u32 csr, test;
-	sbus_dma_info_t *base = &dma_cont->sbus_info;
+	struct sbus_dma_info *base = &dma_cont->sbus_info;
 
 	spin_lock_irqsave(&base->lock, flags);
 	csr = sbus_readl(base->regs + APCCSR);
@@ -1868,11 +1856,11 @@
 	spin_unlock_irqrestore(&base->lock, flags);
 }
 
-void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
+static void sbus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
 {
 	unsigned long flags;
 	u32 csr, shift;
-	sbus_dma_info_t *base = &dma_cont->sbus_info;
+	struct sbus_dma_info *base = &dma_cont->sbus_info;
 
 	spin_lock_irqsave(&base->lock, flags);
 	if (!on) {
@@ -1905,14 +1893,14 @@
 	spin_unlock_irqrestore(&base->lock, flags);
 }
 
-unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
+static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
 {
-	sbus_dma_info_t *base = &dma_cont->sbus_info;
+	struct sbus_dma_info *base = &dma_cont->sbus_info;
 
         return sbus_readl(base->regs + base->dir + APCVA);
 }
 
-void sbus_dma_reset(cs4231_t *chip)
+static void sbus_dma_reset(struct snd_cs4231 *chip)
 {
         sbus_writel(APC_CHIP_RESET, chip->port + APCCSR);
         sbus_writel(0x00, chip->port + APCCSR);
@@ -1929,7 +1917,7 @@
 	               chip->port + APCCSR);
 }
 
-void sbus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm)
+static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
 {
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
 					      snd_dma_sbus_data(chip->dev_u.sdev),
@@ -1940,7 +1928,7 @@
  * Init and exit routines
  */
 
-static int snd_cs4231_sbus_free(cs4231_t *chip)
+static int snd_cs4231_sbus_free(struct snd_cs4231 *chip)
 {
 	if (chip->irq[0])
 		free_irq(chip->irq[0], chip);
@@ -1948,31 +1936,28 @@
 	if (chip->port)
 		sbus_iounmap(chip->port, chip->regs_size);
 
-	if (chip->timer)
-		snd_device_free(chip->card, chip->timer);
-
 	kfree(chip);
 
 	return 0;
 }
 
-static int snd_cs4231_sbus_dev_free(snd_device_t *device)
+static int snd_cs4231_sbus_dev_free(struct snd_device *device)
 {
-	cs4231_t *cp = device->device_data;
+	struct snd_cs4231 *cp = device->device_data;
 
 	return snd_cs4231_sbus_free(cp);
 }
 
-static snd_device_ops_t snd_cs4231_sbus_dev_ops = {
+static struct snd_device_ops snd_cs4231_sbus_dev_ops = {
 	.dev_free	=	snd_cs4231_sbus_dev_free,
 };
 
-static int __init snd_cs4231_sbus_create(snd_card_t *card,
+static int __init snd_cs4231_sbus_create(struct snd_card *card,
 					 struct sbus_dev *sdev,
 					 int dev,
-					 cs4231_t **rchip)
+					 struct snd_cs4231 **rchip)
 {
-	cs4231_t *chip;
+	struct snd_cs4231 *chip;
 	int err;
 
 	*rchip = NULL;
@@ -2043,11 +2028,11 @@
 	return 0;
 }
 
-static int cs4231_sbus_attach(struct sbus_dev *sdev)
+static int __init cs4231_sbus_attach(struct sbus_dev *sdev)
 {
 	struct resource *rp = &sdev->resource[0];
-	cs4231_t *cp;
-	snd_card_t *card;
+	struct snd_cs4231 *cp;
+	struct snd_card *card;
 	int err;
 
 	err = cs4231_attach_begin(&card);
@@ -2073,14 +2058,14 @@
 
 static void snd_cs4231_ebus_play_callback(struct ebus_dma_info *p, int event, void *cookie)
 {
-	cs4231_t *chip = cookie;
+	struct snd_cs4231 *chip = cookie;
 	
 	snd_cs4231_play_callback(chip);
 }
 
 static void snd_cs4231_ebus_capture_callback(struct ebus_dma_info *p, int event, void *cookie)
 {
-	cs4231_t *chip = cookie;
+	struct snd_cs4231 *chip = cookie;
 
 	snd_cs4231_capture_callback(chip);
 }
@@ -2089,32 +2074,32 @@
  * EBUS DMA wrappers
  */
 
-int _ebus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
+static int _ebus_dma_request(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len)
 {
 	return ebus_dma_request(&dma_cont->ebus_info, bus_addr, len);
 }
 
-void _ebus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
+static void _ebus_dma_enable(struct cs4231_dma_control *dma_cont, int on)
 {
 	ebus_dma_enable(&dma_cont->ebus_info, on);
 }
 
-void _ebus_dma_prepare(struct cs4231_dma_control *dma_cont, int dir)
+static void _ebus_dma_prepare(struct cs4231_dma_control *dma_cont, int dir)
 {
 	ebus_dma_prepare(&dma_cont->ebus_info, dir);
 }
 
-unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
+static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
 {
 	return ebus_dma_addr(&dma_cont->ebus_info);
 }
 
-void _ebus_dma_reset(cs4231_t *chip)
+static void _ebus_dma_reset(struct snd_cs4231 *chip)
 {
 	return;
 }
 
-void _ebus_dma_preallocate(cs4231_t *chip, snd_pcm_t *pcm)
+static void _ebus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
 {
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 				      snd_dma_pci_data(chip->dev_u.pdev),
@@ -2125,7 +2110,7 @@
  * Init and exit routines
  */
 
-static int snd_cs4231_ebus_free(cs4231_t *chip)
+static int snd_cs4231_ebus_free(struct snd_cs4231 *chip)
 {
 	if (chip->c_dma.ebus_info.regs) {
 		ebus_dma_unregister(&chip->c_dma.ebus_info);
@@ -2138,31 +2123,29 @@
 
 	if (chip->port)
 		iounmap(chip->port);
-	if (chip->timer)
-		snd_device_free(chip->card, chip->timer);
 
 	kfree(chip);
 
 	return 0;
 }
 
-static int snd_cs4231_ebus_dev_free(snd_device_t *device)
+static int snd_cs4231_ebus_dev_free(struct snd_device *device)
 {
-	cs4231_t *cp = device->device_data;
+	struct snd_cs4231 *cp = device->device_data;
 
 	return snd_cs4231_ebus_free(cp);
 }
 
-static snd_device_ops_t snd_cs4231_ebus_dev_ops = {
+static struct snd_device_ops snd_cs4231_ebus_dev_ops = {
 	.dev_free	=	snd_cs4231_ebus_dev_free,
 };
 
-static int __init snd_cs4231_ebus_create(snd_card_t *card,
+static int __init snd_cs4231_ebus_create(struct snd_card *card,
 					 struct linux_ebus_device *edev,
 					 int dev,
-					 cs4231_t **rchip)
+					 struct snd_cs4231 **rchip)
 {
-	cs4231_t *chip;
+	struct snd_cs4231 *chip;
 	int err;
 
 	*rchip = NULL;
@@ -2252,10 +2235,10 @@
 	return 0;
 }
 
-static int cs4231_ebus_attach(struct linux_ebus_device *edev)
+static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
 {
-	snd_card_t *card;
-	cs4231_t *chip;
+	struct snd_card *card;
+	struct snd_cs4231 *chip;
 	int err;
 
 	err = cs4231_attach_begin(&card);
@@ -2328,10 +2311,10 @@
 
 static void __exit cs4231_exit(void)
 {
-	cs4231_t *p = cs4231_list;
+	struct snd_cs4231 *p = cs4231_list;
 
 	while (p != NULL) {
-		cs4231_t *next = p->next;
+		struct snd_cs4231 *next = p->next;
 
 		snd_card_free(p->card);
 
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 59a77129..2164b7d 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -299,8 +299,8 @@
 };
 
 /* Per stream (playback or record) information */
-typedef struct dbri_streaminfo {
-	snd_pcm_substream_t *substream;
+struct dbri_streaminfo {
+	struct snd_pcm_substream *substream;
 	u32 dvma_buffer;	/* Device view of Alsa DMA buffer */
 	int left;		/* # of bytes left in DMA buffer  */
 	int size;		/* Size of DMA buffer             */
@@ -309,12 +309,12 @@
 	int left_gain;		/* mixer elements                 */
 	int right_gain;
 	int balance;
-} dbri_streaminfo_t;
+};
 
 /* This structure holds the information for both chips (DBRI & CS4215) */
-typedef struct snd_dbri {
-	snd_card_t *card;	/* ALSA card */
-	snd_pcm_t *pcm;
+struct snd_dbri {
+	struct snd_card *card;	/* ALSA card */
+	struct snd_pcm *pcm;
 
 	int regs_size, irq;	/* Needed for unload */
 	struct sbus_dev *sdev;	/* SBUS device info */
@@ -341,7 +341,7 @@
 	struct dbri_streaminfo stream_info[DBRI_NO_STREAMS];
 
 	struct snd_dbri *next;
-} snd_dbri_t;
+};
 
 #define DBRI_MAX_VOLUME		63	/* Output volume */
 #define DBRI_MAX_GAIN		15	/* Input gain */
@@ -593,7 +593,7 @@
 /* Return a pointer to dbri_streaminfo */
 #define DBRI_STREAM(dbri, substream)	&dbri->stream_info[DBRI_STREAMNO(substream)]
 
-static snd_dbri_t *dbri_list = NULL;	/* All DBRI devices */
+static struct snd_dbri *dbri_list = NULL;	/* All DBRI devices */
 
 /*
  * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr.
@@ -652,12 +652,12 @@
 
 */
 
-static void dbri_process_interrupt_buffer(snd_dbri_t * dbri);
+static void dbri_process_interrupt_buffer(struct snd_dbri * dbri);
 
-enum dbri_lock_t { NoGetLock, GetLock };
+enum dbri_lock { NoGetLock, GetLock };
 #define MAXLOOPS 10
 
-static volatile s32 *dbri_cmdlock(snd_dbri_t * dbri, enum dbri_lock_t get)
+static volatile s32 *dbri_cmdlock(struct snd_dbri * dbri, enum dbri_lock get)
 {
 	int maxloops = MAXLOOPS;
 
@@ -687,7 +687,7 @@
 	return &dbri->dma->cmd[0];
 }
 
-static void dbri_cmdsend(snd_dbri_t * dbri, volatile s32 * cmd)
+static void dbri_cmdsend(struct snd_dbri * dbri, volatile s32 * cmd)
 {
 	volatile s32 *ptr;
 	u32	reg;
@@ -717,7 +717,7 @@
 }
 
 /* Lock must be held when calling this */
-static void dbri_reset(snd_dbri_t * dbri)
+static void dbri_reset(struct snd_dbri * dbri)
 {
 	int i;
 
@@ -732,7 +732,7 @@
 }
 
 /* Lock must not be held before calling this */
-static void dbri_initialize(snd_dbri_t * dbri)
+static void dbri_initialize(struct snd_dbri * dbri)
 {
 	volatile s32 *cmd;
 	u32 dma_addr, tmp;
@@ -795,7 +795,7 @@
 here interface closely with the transmit and receive interrupt code.
 
 */
-static int pipe_active(snd_dbri_t * dbri, int pipe)
+static int pipe_active(struct snd_dbri * dbri, int pipe)
 {
 	return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1));
 }
@@ -805,7 +805,7 @@
  * Called on an in-use pipe to clear anything being transmitted or received
  * Lock must be held before calling this.
  */
-static void reset_pipe(snd_dbri_t * dbri, int pipe)
+static void reset_pipe(struct snd_dbri * dbri, int pipe)
 {
 	int sdp;
 	int desc;
@@ -838,7 +838,7 @@
 }
 
 /* FIXME: direction as an argument? */
-static void setup_pipe(snd_dbri_t * dbri, int pipe, int sdp)
+static void setup_pipe(struct snd_dbri * dbri, int pipe, int sdp)
 {
 	if (pipe < 0 || pipe > 31) {
 		printk(KERN_ERR "DBRI: setup_pipe called with illegal pipe number\n");
@@ -869,7 +869,7 @@
 }
 
 /* FIXME: direction not needed */
-static void link_time_slot(snd_dbri_t * dbri, int pipe,
+static void link_time_slot(struct snd_dbri * dbri, int pipe,
 			   enum in_or_out direction, int basepipe,
 			   int length, int cycle)
 {
@@ -959,7 +959,7 @@
 	dbri_cmdsend(dbri, cmd);
 }
 
-static void unlink_time_slot(snd_dbri_t * dbri, int pipe,
+static void unlink_time_slot(struct snd_dbri * dbri, int pipe,
 			     enum in_or_out direction, int prevpipe,
 			     int nextpipe)
 {
@@ -1003,7 +1003,7 @@
  * in the low-order 8 bits, filled either MSB-first or LSB-first,
  * depending on the settings passed to setup_pipe()
  */
-static void xmit_fixed(snd_dbri_t * dbri, int pipe, unsigned int data)
+static void xmit_fixed(struct snd_dbri * dbri, int pipe, unsigned int data)
 {
 	volatile s32 *cmd;
 
@@ -1040,7 +1040,7 @@
 	dbri_cmdsend(dbri, cmd);
 }
 
-static void recv_fixed(snd_dbri_t * dbri, int pipe, volatile __u32 * ptr)
+static void recv_fixed(struct snd_dbri * dbri, int pipe, volatile __u32 * ptr)
 {
 	if (pipe < 16 || pipe > 31) {
 		printk(KERN_ERR "DBRI: recv_fixed called with illegal pipe number\n");
@@ -1072,9 +1072,9 @@
  * data buffers.  Buffers too large for a single descriptor will
  * be spread across multiple descriptors.
  */
-static int setup_descs(snd_dbri_t * dbri, int streamno, unsigned int period)
+static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period)
 {
-	dbri_streaminfo_t *info = &dbri->stream_info[streamno];
+	struct dbri_streaminfo *info = &dbri->stream_info[streamno];
 	__u32 dvma_buffer;
 	int desc = 0;
 	int len;
@@ -1207,7 +1207,7 @@
 
 enum master_or_slave { CHImaster, CHIslave };
 
-static void reset_chi(snd_dbri_t * dbri, enum master_or_slave master_or_slave,
+static void reset_chi(struct snd_dbri * dbri, enum master_or_slave master_or_slave,
 		      int bits_per_frame)
 {
 	volatile s32 *cmd;
@@ -1308,7 +1308,7 @@
 to the DBRI via the CHI interface and few of the DBRI's PIO pins.
 
 */
-static void cs4215_setup_pipes(snd_dbri_t * dbri)
+static void cs4215_setup_pipes(struct snd_dbri * dbri)
 {
 	/*
 	 * Data mode:
@@ -1369,7 +1369,7 @@
 	return 0;
 }
 
-static void cs4215_setdata(snd_dbri_t * dbri, int muted)
+static void cs4215_setdata(struct snd_dbri * dbri, int muted)
 {
 	if (muted) {
 		dbri->mm.data[0] |= 63;
@@ -1378,7 +1378,7 @@
 		dbri->mm.data[3] &= ~15;
 	} else {
 		/* Start by setting the playback attenuation. */
-		dbri_streaminfo_t *info = &dbri->stream_info[DBRI_PLAY];
+		struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY];
 		int left_gain = info->left_gain % 64;
 		int right_gain = info->right_gain % 64;
 
@@ -1409,7 +1409,7 @@
 /*
  * Set the CS4215 to data mode.
  */
-static void cs4215_open(snd_dbri_t * dbri)
+static void cs4215_open(struct snd_dbri * dbri)
 {
 	int data_width;
 	u32 tmp;
@@ -1471,7 +1471,7 @@
 /*
  * Send the control information (i.e. audio format)
  */
-static int cs4215_setctrl(snd_dbri_t * dbri)
+static int cs4215_setctrl(struct snd_dbri * dbri)
 {
 	int i, val;
 	u32 tmp;
@@ -1570,7 +1570,7 @@
  * As part of the process we resend the settings for the data
  * timeslots as well.
  */
-static int cs4215_prepare(snd_dbri_t * dbri, unsigned int rate,
+static int cs4215_prepare(struct snd_dbri * dbri, unsigned int rate,
 			  snd_pcm_format_t format, unsigned int channels)
 {
 	int freq_idx;
@@ -1628,7 +1628,7 @@
 /*
  *
  */
-static int cs4215_init(snd_dbri_t * dbri)
+static int cs4215_init(struct snd_dbri * dbri)
 {
 	u32 reg2 = sbus_readl(dbri->regs + REG2);
 	dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2);
@@ -1697,8 +1697,8 @@
  */
 static void xmit_descs(unsigned long data)
 {
-	snd_dbri_t *dbri = (snd_dbri_t *) data;
-	dbri_streaminfo_t *info;
+	struct snd_dbri *dbri = (struct snd_dbri *) data;
+	struct dbri_streaminfo *info;
 	volatile s32 *cmd;
 	unsigned long flags;
 	int first_td;
@@ -1780,9 +1780,9 @@
  * done by the xmit_descs() tasklet above since that could take longer.
  */
 
-static void transmission_complete_intr(snd_dbri_t * dbri, int pipe)
+static void transmission_complete_intr(struct snd_dbri * dbri, int pipe)
 {
-	dbri_streaminfo_t *info;
+	struct dbri_streaminfo *info;
 	int td;
 	int status;
 
@@ -1830,9 +1830,9 @@
 		snd_pcm_period_elapsed(info->substream);
 }
 
-static void reception_complete_intr(snd_dbri_t * dbri, int pipe)
+static void reception_complete_intr(struct snd_dbri * dbri, int pipe)
 {
-	dbri_streaminfo_t *info;
+	struct dbri_streaminfo *info;
 	int rd = dbri->pipes[pipe].desc;
 	s32 status;
 
@@ -1874,7 +1874,7 @@
 		snd_pcm_period_elapsed(info->substream);
 }
 
-static void dbri_process_one_interrupt(snd_dbri_t * dbri, int x)
+static void dbri_process_one_interrupt(struct snd_dbri * dbri, int x)
 {
 	int val = D_INTR_GETVAL(x);
 	int channel = D_INTR_GETCHAN(x);
@@ -1950,7 +1950,7 @@
  * order is important since we might recurse back into this function
  * and need to make sure the pointer has been advanced first.
  */
-static void dbri_process_interrupt_buffer(snd_dbri_t * dbri)
+static void dbri_process_interrupt_buffer(struct snd_dbri * dbri)
 {
 	s32 x;
 
@@ -1969,7 +1969,7 @@
 static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id,
 				      struct pt_regs *regs)
 {
-	snd_dbri_t *dbri = dev_id;
+	struct snd_dbri *dbri = dev_id;
 	static int errcnt = 0;
 	int x;
 
@@ -2030,7 +2030,7 @@
 /****************************************************************************
 		PCM Interface
 ****************************************************************************/
-static snd_pcm_hardware_t snd_dbri_pcm_hw = {
+static struct snd_pcm_hardware snd_dbri_pcm_hw = {
 	.info			= (SNDRV_PCM_INFO_MMAP |
 				   SNDRV_PCM_INFO_INTERLEAVED |
 				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -2051,11 +2051,11 @@
 	.periods_max		= 1024,
 };
 
-static int snd_dbri_open(snd_pcm_substream_t * substream)
+static int snd_dbri_open(struct snd_pcm_substream *substream)
 {
-	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
 	unsigned long flags;
 
 	dprintk(D_USR, "open audio output.\n");
@@ -2074,10 +2074,10 @@
 	return 0;
 }
 
-static int snd_dbri_close(snd_pcm_substream_t * substream)
+static int snd_dbri_close(struct snd_pcm_substream *substream)
 {
-	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
-	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
+	struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
 
 	dprintk(D_USR, "close audio output.\n");
 	info->substream = NULL;
@@ -2087,12 +2087,12 @@
 	return 0;
 }
 
-static int snd_dbri_hw_params(snd_pcm_substream_t * substream,
-			      snd_pcm_hw_params_t * hw_params)
+static int snd_dbri_hw_params(struct snd_pcm_substream *substream,
+			      struct snd_pcm_hw_params *hw_params)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
-	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
+	struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
 	int direction;
 	int ret;
 
@@ -2129,10 +2129,10 @@
 	return 0;
 }
 
-static int snd_dbri_hw_free(snd_pcm_substream_t * substream)
+static int snd_dbri_hw_free(struct snd_pcm_substream *substream)
 {
-	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
-	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
+	struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
 	int direction;
 	dprintk(D_USR, "hw_free.\n");
 
@@ -2153,11 +2153,11 @@
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static int snd_dbri_prepare(snd_pcm_substream_t * substream)
+static int snd_dbri_prepare(struct snd_pcm_substream *substream)
 {
-	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
-	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
+	struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
+	struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	int ret;
 
 	info->size = snd_pcm_lib_buffer_bytes(substream);
@@ -2184,10 +2184,10 @@
 	return ret;
 }
 
-static int snd_dbri_trigger(snd_pcm_substream_t * substream, int cmd)
+static int snd_dbri_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
-	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
+	struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
 	int ret = 0;
 
 	switch (cmd) {
@@ -2211,10 +2211,10 @@
 	return ret;
 }
 
-static snd_pcm_uframes_t snd_dbri_pointer(snd_pcm_substream_t * substream)
+static snd_pcm_uframes_t snd_dbri_pointer(struct snd_pcm_substream *substream)
 {
-	snd_dbri_t *dbri = snd_pcm_substream_chip(substream);
-	dbri_streaminfo_t *info = DBRI_STREAM(dbri, substream);
+	struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
+	struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
 	snd_pcm_uframes_t ret;
 
 	ret = bytes_to_frames(substream->runtime, info->offset)
@@ -2224,7 +2224,7 @@
 	return ret;
 }
 
-static snd_pcm_ops_t snd_dbri_ops = {
+static struct snd_pcm_ops snd_dbri_ops = {
 	.open = snd_dbri_open,
 	.close = snd_dbri_close,
 	.ioctl = snd_pcm_lib_ioctl,
@@ -2235,9 +2235,9 @@
 	.pointer = snd_dbri_pointer,
 };
 
-static int __devinit snd_dbri_pcm(snd_dbri_t * dbri)
+static int __devinit snd_dbri_pcm(struct snd_dbri * dbri)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err;
 
 	if ((err = snd_pcm_new(dbri->card,
@@ -2270,8 +2270,8 @@
 			Mixer interface
 *****************************************************************************/
 
-static int snd_cs4215_info_volume(snd_kcontrol_t * kcontrol,
-				  snd_ctl_elem_info_t * uinfo)
+static int snd_cs4215_info_volume(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	uinfo->count = 2;
@@ -2284,11 +2284,11 @@
 	return 0;
 }
 
-static int snd_cs4215_get_volume(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4215_get_volume(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol);
-	dbri_streaminfo_t *info;
+	struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
+	struct dbri_streaminfo *info;
 	snd_assert(dbri != NULL, return -EINVAL);
 	info = &dbri->stream_info[kcontrol->private_value];
 	snd_assert(info != NULL, return -EINVAL);
@@ -2298,11 +2298,11 @@
 	return 0;
 }
 
-static int snd_cs4215_put_volume(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol);
-	dbri_streaminfo_t *info = &dbri->stream_info[kcontrol->private_value];
+	struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
+	struct dbri_streaminfo *info = &dbri->stream_info[kcontrol->private_value];
 	unsigned long flags;
 	int changed = 0;
 
@@ -2329,8 +2329,8 @@
 	return changed;
 }
 
-static int snd_cs4215_info_single(snd_kcontrol_t * kcontrol,
-				  snd_ctl_elem_info_t * uinfo)
+static int snd_cs4215_info_single(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_info *uinfo)
 {
 	int mask = (kcontrol->private_value >> 16) & 0xff;
 
@@ -2342,10 +2342,10 @@
 	return 0;
 }
 
-static int snd_cs4215_get_single(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4215_get_single(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol);
+	struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
 	int elem = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
 	int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -2367,10 +2367,10 @@
 	return 0;
 }
 
-static int snd_cs4215_put_single(snd_kcontrol_t * kcontrol,
-				 snd_ctl_elem_value_t * ucontrol)
+static int snd_cs4215_put_single(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_value *ucontrol)
 {
-	snd_dbri_t *dbri = snd_kcontrol_chip(kcontrol);
+	struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
 	int elem = kcontrol->private_value & 0xff;
 	int shift = (kcontrol->private_value >> 8) & 0xff;
@@ -2425,7 +2425,7 @@
   .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \
   .private_value = entry | (shift << 8) | (mask << 16) | (invert << 24) },
 
-static snd_kcontrol_new_t dbri_controls[] __devinitdata = {
+static struct snd_kcontrol_new dbri_controls[] __devinitdata = {
 	{
 	 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	 .name  = "Playback Volume",
@@ -2452,11 +2452,11 @@
 	CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
 };
 
-#define NUM_CS4215_CONTROLS (sizeof(dbri_controls)/sizeof(snd_kcontrol_new_t))
+#define NUM_CS4215_CONTROLS (sizeof(dbri_controls)/sizeof(struct snd_kcontrol_new))
 
-static int __init snd_dbri_mixer(snd_dbri_t * dbri)
+static int __init snd_dbri_mixer(struct snd_dbri * dbri)
 {
-	snd_card_t *card;
+	struct snd_card *card;
 	int idx, err;
 
 	snd_assert(dbri != NULL && dbri->card != NULL, return -EINVAL);
@@ -2482,9 +2482,9 @@
 /****************************************************************************
 			/proc interface
 ****************************************************************************/
-static void dbri_regs_read(snd_info_entry_t * entry, snd_info_buffer_t * buffer)
+static void dbri_regs_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer)
 {
-	snd_dbri_t *dbri = entry->private_data;
+	struct snd_dbri *dbri = entry->private_data;
 
 	snd_iprintf(buffer, "REG0: 0x%x\n", sbus_readl(dbri->regs + REG0));
 	snd_iprintf(buffer, "REG2: 0x%x\n", sbus_readl(dbri->regs + REG2));
@@ -2493,10 +2493,10 @@
 }
 
 #ifdef DBRI_DEBUG
-static void dbri_debug_read(snd_info_entry_t * entry,
-			    snd_info_buffer_t * buffer)
+static void dbri_debug_read(struct snd_info_entry * entry,
+			    struct snd_info_buffer *buffer)
 {
-	snd_dbri_t *dbri = entry->private_data;
+	struct snd_dbri *dbri = entry->private_data;
 	int pipe;
 	snd_iprintf(buffer, "debug=%d\n", dbri_debug);
 
@@ -2516,18 +2516,18 @@
 }
 #endif
 
-void snd_dbri_proc(snd_dbri_t * dbri)
+void snd_dbri_proc(struct snd_dbri * dbri)
 {
-	snd_info_entry_t *entry;
-	int err;
+	struct snd_info_entry *entry;
 
-	err = snd_card_proc_new(dbri->card, "regs", &entry);
-	snd_info_set_text_ops(entry, dbri, 1024, dbri_regs_read);
+	if (! snd_card_proc_new(dbri->card, "regs", &entry))
+		snd_info_set_text_ops(entry, dbri, 1024, dbri_regs_read);
 
 #ifdef DBRI_DEBUG
-	err = snd_card_proc_new(dbri->card, "debug", &entry);
-	snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read);
-	entry->mode = S_IFREG | S_IRUGO;	/* Readable only. */
+	if (! snd_card_proc_new(dbri->card, "debug", &entry)) {
+		snd_info_set_text_ops(entry, dbri, 4096, dbri_debug_read);
+		entry->mode = S_IFREG | S_IRUGO;	/* Readable only. */
+	}
 #endif
 }
 
@@ -2536,13 +2536,13 @@
 **************************** Initialization ********************************
 ****************************************************************************
 */
-static void snd_dbri_free(snd_dbri_t * dbri);
+static void snd_dbri_free(struct snd_dbri * dbri);
 
-static int __init snd_dbri_create(snd_card_t * card,
+static int __init snd_dbri_create(struct snd_card *card,
 				  struct sbus_dev *sdev,
 				  struct linux_prom_irqs *irq, int dev)
 {
-	snd_dbri_t *dbri = card->private_data;
+	struct snd_dbri *dbri = card->private_data;
 	int err;
 
 	spin_lock_init(&dbri->lock);
@@ -2593,7 +2593,7 @@
 	return 0;
 }
 
-static void snd_dbri_free(snd_dbri_t * dbri)
+static void snd_dbri_free(struct snd_dbri * dbri)
 {
 	dprintk(D_GEN, "snd_dbri_free\n");
 	dbri_reset(dbri);
@@ -2611,10 +2611,10 @@
 
 static int __init dbri_attach(int prom_node, struct sbus_dev *sdev)
 {
-	snd_dbri_t *dbri;
+	struct snd_dbri *dbri;
 	struct linux_prom_irqs irq;
 	struct resource *rp;
-	snd_card_t *card;
+	struct snd_card *card;
 	static int dev = 0;
 	int err;
 
@@ -2638,7 +2638,7 @@
 	}
 
 	card = snd_card_new(index[dev], id[dev], THIS_MODULE,
-			    sizeof(snd_dbri_t));
+			    sizeof(struct snd_dbri));
 	if (card == NULL)
 		return -ENOMEM;
 
@@ -2654,7 +2654,7 @@
 		return err;
 	}
 
-	dbri = (snd_dbri_t *) card->private_data;
+	dbri = card->private_data;
 	if ((err = snd_dbri_pcm(dbri)) < 0)
 		goto _err;
 
@@ -2664,9 +2664,6 @@
 	/* /proc file handling */
 	snd_dbri_proc(dbri);
 
-	if ((err = snd_card_set_generic_dev(card)) < 0)
-		goto _err;
-
 	if ((err = snd_card_register(card)) < 0)
 		goto _err;
 
@@ -2709,11 +2706,11 @@
 
 static void __exit dbri_exit(void)
 {
-	snd_dbri_t *this = dbri_list;
+	struct snd_dbri *this = dbri_list;
 
 	while (this != NULL) {
-		snd_dbri_t *next = this->next;
-		snd_card_t *card = this->card;
+		struct snd_dbri *next = this->next;
+		struct snd_card *card = this->card;
 
 		snd_dbri_free(this);
 		snd_card_free(card);
diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c
index 9e2b4c0..7c8e328 100644
--- a/sound/synth/emux/emux.c
+++ b/sound/synth/emux/emux.c
@@ -35,9 +35,9 @@
 /*
  * create a new hardware dependent device for Emu8000/Emu10k1
  */
-int snd_emux_new(snd_emux_t **remu)
+int snd_emux_new(struct snd_emux **remu)
 {
-	snd_emux_t *emu;
+	struct snd_emux *emu;
 
 	*remu = NULL;
 	emu = kzalloc(sizeof(*emu), GFP_KERNEL);
@@ -66,10 +66,33 @@
 
 /*
  */
-int snd_emux_register(snd_emux_t *emu, snd_card_t *card, int index, char *name)
+static int sf_sample_new(void *private_data, struct snd_sf_sample *sp,
+				  struct snd_util_memhdr *hdr,
+				  const void __user *buf, long count)
+{
+	struct snd_emux *emu = private_data;
+	return emu->ops.sample_new(emu, sp, hdr, buf, count);
+	
+}
+
+static int sf_sample_free(void *private_data, struct snd_sf_sample *sp,
+				   struct snd_util_memhdr *hdr)
+{
+	struct snd_emux *emu = private_data;
+	return emu->ops.sample_free(emu, sp, hdr);
+	
+}
+
+static void sf_sample_reset(void *private_data)
+{
+	struct snd_emux *emu = private_data;
+	emu->ops.sample_reset(emu);
+}
+
+int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, char *name)
 {
 	int err;
-	snd_sf_callback_t sf_cb;
+	struct snd_sf_callback sf_cb;
 
 	snd_assert(emu->hw != NULL, return -EINVAL);
 	snd_assert(emu->max_voices > 0, return -EINVAL);
@@ -78,16 +101,20 @@
 
 	emu->card = card;
 	emu->name = kstrdup(name, GFP_KERNEL);
-	emu->voices = kcalloc(emu->max_voices, sizeof(snd_emux_voice_t), GFP_KERNEL);
+	emu->voices = kcalloc(emu->max_voices, sizeof(struct snd_emux_voice),
+			      GFP_KERNEL);
 	if (emu->voices == NULL)
 		return -ENOMEM;
 
 	/* create soundfont list */
 	memset(&sf_cb, 0, sizeof(sf_cb));
 	sf_cb.private_data = emu;
-	sf_cb.sample_new = (snd_sf_sample_new_t)emu->ops.sample_new;
-	sf_cb.sample_free = (snd_sf_sample_free_t)emu->ops.sample_free;
-	sf_cb.sample_reset = (snd_sf_sample_reset_t)emu->ops.sample_reset;
+	if (emu->ops.sample_new)
+		sf_cb.sample_new = sf_sample_new;
+	if (emu->ops.sample_free)
+		sf_cb.sample_free = sf_sample_free;
+	if (emu->ops.sample_reset)
+		sf_cb.sample_reset = sf_sample_reset;
 	emu->sflist = snd_sf_new(&sf_cb, emu->memhdr);
 	if (emu->sflist == NULL)
 		return -ENOMEM;
@@ -112,7 +139,7 @@
 
 /*
  */
-int snd_emux_free(snd_emux_t *emu)
+int snd_emux_free(struct snd_emux *emu)
 {
 	unsigned long flags;
 
diff --git a/sound/synth/emux/emux_effect.c b/sound/synth/emux/emux_effect.c
index 4764940..a447218 100644
--- a/sound/synth/emux/emux_effect.c
+++ b/sound/synth/emux/emux_effect.c
@@ -32,7 +32,7 @@
 
 #define xoffsetof(type,tag)	((long)(&((type)NULL)->tag) - (long)(NULL))
 
-#define parm_offset(tag)	xoffsetof(soundfont_voice_parm_t*, tag)
+#define parm_offset(tag)	xoffsetof(struct soundfont_voice_parm *, tag)
 
 #define PARM_IS_BYTE		(1 << 0)
 #define PARM_IS_WORD		(1 << 1)
@@ -97,10 +97,10 @@
 
 /* set byte effect value */
 static void
-effect_set_byte(unsigned char *valp, snd_midi_channel_t *chan, int type)
+effect_set_byte(unsigned char *valp, struct snd_midi_channel *chan, int type)
 {
 	short effect;
-	snd_emux_effect_table_t *fx = chan->private;
+	struct snd_emux_effect_table *fx = chan->private;
 
 	effect = fx->val[type];
 	if (fx->flag[type] == EMUX_FX_FLAG_ADD) {
@@ -118,10 +118,10 @@
 
 /* set word effect value */
 static void
-effect_set_word(unsigned short *valp, snd_midi_channel_t *chan, int type)
+effect_set_word(unsigned short *valp, struct snd_midi_channel *chan, int type)
 {
 	int effect;
-	snd_emux_effect_table_t *fx = chan->private;
+	struct snd_emux_effect_table *fx = chan->private;
 
 	effect = *(unsigned short*)&fx->val[type];
 	if (fx->flag[type] == EMUX_FX_FLAG_ADD)
@@ -135,10 +135,10 @@
 
 /* address offset */
 static int
-effect_get_offset(snd_midi_channel_t *chan, int lo, int hi, int mode)
+effect_get_offset(struct snd_midi_channel *chan, int lo, int hi, int mode)
 {
 	int addr = 0;
-	snd_emux_effect_table_t *fx = chan->private;
+	struct snd_emux_effect_table *fx = chan->private;
 
 	if (fx->flag[hi])
 		addr = (short)fx->val[hi];
@@ -153,7 +153,8 @@
 #ifdef CONFIG_SND_SEQUENCER_OSS
 /* change effects - for OSS sequencer compatibility */
 void
-snd_emux_send_effect_oss(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val)
+snd_emux_send_effect_oss(struct snd_emux_port *port,
+			 struct snd_midi_channel *chan, int type, int val)
 {
 	int mode;
 
@@ -173,13 +174,14 @@
  * if update is necessary, call emu8000_control
  */
 void
-snd_emux_send_effect(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val, int mode)
+snd_emux_send_effect(struct snd_emux_port *port, struct snd_midi_channel *chan,
+		     int type, int val, int mode)
 {
 	int i;
 	int offset;
 	unsigned char *srcp, *origp;
-	snd_emux_t *emu;
-	snd_emux_effect_table_t *fx;
+	struct snd_emux *emu;
+	struct snd_emux_effect_table *fx;
 	unsigned long flags;
 
 	emu = port->emu;
@@ -206,7 +208,7 @@
 	/* modify the register values */
 	spin_lock_irqsave(&emu->voice_lock, flags);
 	for (i = 0; i < emu->max_voices; i++) {
-		snd_emux_voice_t *vp = &emu->voices[i];
+		struct snd_emux_voice *vp = &emu->voices[i];
 		if (!STATE_IS_PLAYING(vp->state) || vp->chan != chan)
 			continue;
 		srcp = (unsigned char*)&vp->reg.parm + offset;
@@ -228,10 +230,10 @@
 
 /* copy wavetable registers to voice table */
 void
-snd_emux_setup_effect(snd_emux_voice_t *vp)
+snd_emux_setup_effect(struct snd_emux_voice *vp)
 {
-	snd_midi_channel_t *chan = vp->chan;
-	snd_emux_effect_table_t *fx;
+	struct snd_midi_channel *chan = vp->chan;
+	struct snd_emux_effect_table *fx;
 	unsigned char *srcp;
 	int i;
 
@@ -275,10 +277,11 @@
  * effect table
  */
 void
-snd_emux_create_effect(snd_emux_port_t *p)
+snd_emux_create_effect(struct snd_emux_port *p)
 {
 	int i;
-	p->effect = kcalloc(p->chset.max_channels, sizeof(snd_emux_effect_table_t), GFP_KERNEL);
+	p->effect = kcalloc(p->chset.max_channels,
+			    sizeof(struct snd_emux_effect_table), GFP_KERNEL);
 	if (p->effect) {
 		for (i = 0; i < p->chset.max_channels; i++)
 			p->chset.channels[i].private = p->effect + i;
@@ -289,17 +292,18 @@
 }
 
 void
-snd_emux_delete_effect(snd_emux_port_t *p)
+snd_emux_delete_effect(struct snd_emux_port *p)
 {
 	kfree(p->effect);
 	p->effect = NULL;
 }
 
 void
-snd_emux_clear_effect(snd_emux_port_t *p)
+snd_emux_clear_effect(struct snd_emux_port *p)
 {
 	if (p->effect) {
-		memset(p->effect, 0, sizeof(snd_emux_effect_table_t) * p->chset.max_channels);
+		memset(p->effect, 0, sizeof(struct snd_emux_effect_table) *
+		       p->chset.max_channels);
 	}
 }
 
diff --git a/sound/synth/emux/emux_hwdep.c b/sound/synth/emux/emux_hwdep.c
index 4182b44..9b63814 100644
--- a/sound/synth/emux/emux_hwdep.c
+++ b/sound/synth/emux/emux_hwdep.c
@@ -29,7 +29,7 @@
  * open the hwdep device
  */
 static int
-snd_emux_hwdep_open(snd_hwdep_t *hw, struct file *file)
+snd_emux_hwdep_open(struct snd_hwdep *hw, struct file *file)
 {
 	return 0;
 }
@@ -39,7 +39,7 @@
  * close the device
  */
 static int
-snd_emux_hwdep_release(snd_hwdep_t *hw, struct file *file)
+snd_emux_hwdep_release(struct snd_hwdep *hw, struct file *file)
 {
 	return 0;
 }
@@ -51,10 +51,10 @@
  * load patch
  */
 static int
-snd_emux_hwdep_load_patch(snd_emux_t *emu, void __user *arg)
+snd_emux_hwdep_load_patch(struct snd_emux *emu, void __user *arg)
 {
 	int err;
-	soundfont_patch_info_t patch;
+	struct soundfont_patch_info patch;
 
 	if (copy_from_user(&patch, arg, sizeof(patch)))
 		return -EFAULT;
@@ -77,9 +77,9 @@
  * set misc mode
  */
 static int
-snd_emux_hwdep_misc_mode(snd_emux_t *emu, void __user *arg)
+snd_emux_hwdep_misc_mode(struct snd_emux *emu, void __user *arg)
 {
-	struct sndrv_emux_misc_mode info;
+	struct snd_emux_misc_mode info;
 	int i;
 
 	if (copy_from_user(&info, arg, sizeof(info)))
@@ -102,9 +102,10 @@
  * ioctl
  */
 static int
-snd_emux_hwdep_ioctl(snd_hwdep_t * hw, struct file *file, unsigned int cmd, unsigned long arg)
+snd_emux_hwdep_ioctl(struct snd_hwdep * hw, struct file *file,
+		     unsigned int cmd, unsigned long arg)
 {
-	snd_emux_t *emu = hw->private_data;
+	struct snd_emux *emu = hw->private_data;
 
 	switch (cmd) {
 	case SNDRV_EMUX_IOCTL_VERSION:
@@ -136,9 +137,9 @@
  */
 
 int
-snd_emux_init_hwdep(snd_emux_t *emu)
+snd_emux_init_hwdep(struct snd_emux *emu)
 {
-	snd_hwdep_t *hw;
+	struct snd_hwdep *hw;
 	int err;
 
 	if ((err = snd_hwdep_new(emu->card, SNDRV_EMUX_HWDEP_NAME, emu->hwdep_idx, &hw)) < 0)
@@ -162,7 +163,7 @@
  * unregister
  */
 void
-snd_emux_delete_hwdep(snd_emux_t *emu)
+snd_emux_delete_hwdep(struct snd_emux *emu)
 {
 	if (emu->hwdep) {
 		snd_device_free(emu->card, emu->hwdep);
diff --git a/sound/synth/emux/emux_nrpn.c b/sound/synth/emux/emux_nrpn.c
index 25edff9..c6917ba 100644
--- a/sound/synth/emux/emux_nrpn.c
+++ b/sound/synth/emux/emux_nrpn.c
@@ -27,11 +27,11 @@
  */
 
 /* NRPN / CC -> Emu8000 parameter converter */
-typedef struct {
+struct nrpn_conv_table {
 	int control;
 	int effect;
 	int (*convert)(int val);
-} nrpn_conv_table;
+};
 
 /* effect sensitivity */
 
@@ -48,8 +48,9 @@
  * convert NRPN/control values
  */
 
-static int send_converted_effect(nrpn_conv_table *table, int num_tables,
-				 snd_emux_port_t *port, snd_midi_channel_t *chan,
+static int send_converted_effect(struct nrpn_conv_table *table, int num_tables,
+				 struct snd_emux_port *port,
+				 struct snd_midi_channel *chan,
 				 int type, int val, int mode)
 {
 	int i, cval;
@@ -178,7 +179,7 @@
 }
 
 
-static nrpn_conv_table awe_effects[] =
+static struct nrpn_conv_table awe_effects[] =
 {
 	{ 0, EMUX_FX_LFO1_DELAY,	fx_lfo1_delay},
 	{ 1, EMUX_FX_LFO1_FREQ,	fx_lfo1_freq},
@@ -265,7 +266,7 @@
 	return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
 }
 
-static nrpn_conv_table gs_effects[] =
+static struct nrpn_conv_table gs_effects[] =
 {
 	{32, EMUX_FX_CUTOFF,	gs_cutoff},
 	{33, EMUX_FX_FILTERQ,	gs_filterQ},
@@ -282,9 +283,10 @@
  * NRPN events
  */
 void
-snd_emux_nrpn(void *p, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset)
+snd_emux_nrpn(void *p, struct snd_midi_channel *chan,
+	      struct snd_midi_channel_set *chset)
 {
-	snd_emux_port_t *port;
+	struct snd_emux_port *port;
 
 	port = p;
 	snd_assert(port != NULL, return);
@@ -348,7 +350,7 @@
 	return -(val - 64) * xg_sense[FX_RELEASE] / 64;
 }
 
-static nrpn_conv_table xg_effects[] =
+static struct nrpn_conv_table xg_effects[] =
 {
 	{71, EMUX_FX_CUTOFF,	xg_cutoff},
 	{74, EMUX_FX_FILTERQ,	xg_filterQ},
@@ -357,7 +359,8 @@
 };
 
 int
-snd_emux_xg_control(snd_emux_port_t *port, snd_midi_channel_t *chan, int param)
+snd_emux_xg_control(struct snd_emux_port *port, struct snd_midi_channel *chan,
+		    int param)
 {
 	return send_converted_effect(xg_effects, ARRAY_SIZE(xg_effects),
 				     port, chan, param,
@@ -369,10 +372,11 @@
  * receive sysex
  */
 void
-snd_emux_sysex(void *p, unsigned char *buf, int len, int parsed, snd_midi_channel_set_t *chset)
+snd_emux_sysex(void *p, unsigned char *buf, int len, int parsed,
+	       struct snd_midi_channel_set *chset)
 {
-	snd_emux_port_t *port;
-	snd_emux_t *emu;
+	struct snd_emux_port *port;
+	struct snd_emux *emu;
 
 	port = p;
 	snd_assert(port != NULL, return);
diff --git a/sound/synth/emux/emux_oss.c b/sound/synth/emux/emux_oss.c
index 5272f4a..dfbfcfb 100644
--- a/sound/synth/emux/emux_oss.c
+++ b/sound/synth/emux/emux_oss.c
@@ -31,19 +31,25 @@
 #include "emux_voice.h"
 #include <sound/asoundef.h>
 
-static int snd_emux_open_seq_oss(snd_seq_oss_arg_t *arg, void *closure);
-static int snd_emux_close_seq_oss(snd_seq_oss_arg_t *arg);
-static int snd_emux_ioctl_seq_oss(snd_seq_oss_arg_t *arg, unsigned int cmd, unsigned long ioarg);
-static int snd_emux_load_patch_seq_oss(snd_seq_oss_arg_t *arg, int format, const char __user *buf, int offs, int count);
-static int snd_emux_reset_seq_oss(snd_seq_oss_arg_t *arg);
-static int snd_emux_event_oss_input(snd_seq_event_t *ev, int direct, void *private, int atomic, int hop);
-static void reset_port_mode(snd_emux_port_t *port, int midi_mode);
-static void emuspec_control(snd_emux_t *emu, snd_emux_port_t *port, int cmd, unsigned char *event, int atomic, int hop);
-static void gusspec_control(snd_emux_t *emu, snd_emux_port_t *port, int cmd, unsigned char *event, int atomic, int hop);
-static void fake_event(snd_emux_t *emu, snd_emux_port_t *port, int ch, int param, int val, int atomic, int hop);
+static int snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure);
+static int snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg);
+static int snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd,
+				  unsigned long ioarg);
+static int snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
+				       const char __user *buf, int offs, int count);
+static int snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg);
+static int snd_emux_event_oss_input(struct snd_seq_event *ev, int direct,
+				    void *private, int atomic, int hop);
+static void reset_port_mode(struct snd_emux_port *port, int midi_mode);
+static void emuspec_control(struct snd_emux *emu, struct snd_emux_port *port,
+			    int cmd, unsigned char *event, int atomic, int hop);
+static void gusspec_control(struct snd_emux *emu, struct snd_emux_port *port,
+			    int cmd, unsigned char *event, int atomic, int hop);
+static void fake_event(struct snd_emux *emu, struct snd_emux_port *port,
+		       int ch, int param, int val, int atomic, int hop);
 
 /* operators */
-static snd_seq_oss_callback_t oss_callback = {
+static struct snd_seq_oss_callback oss_callback = {
 	.owner = THIS_MODULE,
 	.open = snd_emux_open_seq_oss,
 	.close = snd_emux_close_seq_oss,
@@ -58,13 +64,13 @@
  */
 
 void
-snd_emux_init_seq_oss(snd_emux_t *emu)
+snd_emux_init_seq_oss(struct snd_emux *emu)
 {
-	snd_seq_oss_reg_t *arg;
-	snd_seq_device_t *dev;
+	struct snd_seq_oss_reg *arg;
+	struct snd_seq_device *dev;
 
 	if (snd_seq_device_new(emu->card, 0, SNDRV_SEQ_DEV_ID_OSS,
-			       sizeof(snd_seq_oss_reg_t), &dev) < 0)
+			       sizeof(struct snd_seq_oss_reg), &dev) < 0)
 		return;
 
 	emu->oss_synth = dev;
@@ -85,7 +91,7 @@
  * unregister
  */
 void
-snd_emux_detach_seq_oss(snd_emux_t *emu)
+snd_emux_detach_seq_oss(struct snd_emux *emu)
 {
 	if (emu->oss_synth) {
 		snd_device_free(emu->card, emu->oss_synth);
@@ -101,11 +107,11 @@
  * open port for OSS sequencer
  */
 static int
-snd_emux_open_seq_oss(snd_seq_oss_arg_t *arg, void *closure)
+snd_emux_open_seq_oss(struct snd_seq_oss_arg *arg, void *closure)
 {
-	snd_emux_t *emu;
-	snd_emux_port_t *p;
-	snd_seq_port_callback_t callback;
+	struct snd_emux *emu;
+	struct snd_emux_port *p;
+	struct snd_seq_port_callback callback;
 	char tmpname[64];
 
 	emu = closure;
@@ -153,7 +159,7 @@
  * reset port mode
  */
 static void
-reset_port_mode(snd_emux_port_t *port, int midi_mode)
+reset_port_mode(struct snd_emux_port *port, int midi_mode)
 {
 	if (midi_mode) {
 		port->port_mode = SNDRV_EMUX_PORT_MODE_OSS_MIDI;
@@ -173,10 +179,10 @@
  * close port
  */
 static int
-snd_emux_close_seq_oss(snd_seq_oss_arg_t *arg)
+snd_emux_close_seq_oss(struct snd_seq_oss_arg *arg)
 {
-	snd_emux_t *emu;
-	snd_emux_port_t *p;
+	struct snd_emux *emu;
+	struct snd_emux_port *p;
 
 	snd_assert(arg != NULL, return -ENXIO);
 	p = arg->private_data;
@@ -200,11 +206,11 @@
  * load patch
  */
 static int
-snd_emux_load_patch_seq_oss(snd_seq_oss_arg_t *arg, int format,
+snd_emux_load_patch_seq_oss(struct snd_seq_oss_arg *arg, int format,
 			    const char __user *buf, int offs, int count)
 {
-	snd_emux_t *emu;
-	snd_emux_port_t *p;
+	struct snd_emux *emu;
+	struct snd_emux_port *p;
 	int rc;
 
 	snd_assert(arg != NULL, return -ENXIO);
@@ -218,7 +224,7 @@
 		rc = snd_soundfont_load_guspatch(emu->sflist, buf, count,
 						 SF_CLIENT_NO(p->chset.port));
 	else if (format == SNDRV_OSS_SOUNDFONT_PATCH) {
-		soundfont_patch_info_t patch;
+		struct soundfont_patch_info patch;
 		if (count < (int)sizeof(patch))
 			rc = -EINVAL;
 		if (copy_from_user(&patch, buf, sizeof(patch)))
@@ -242,10 +248,10 @@
  * ioctl
  */
 static int
-snd_emux_ioctl_seq_oss(snd_seq_oss_arg_t *arg, unsigned int cmd, unsigned long ioarg)
+snd_emux_ioctl_seq_oss(struct snd_seq_oss_arg *arg, unsigned int cmd, unsigned long ioarg)
 {
-	snd_emux_port_t *p;
-	snd_emux_t *emu;
+	struct snd_emux_port *p;
+	struct snd_emux *emu;
 
 	snd_assert(arg != NULL, return -ENXIO);
 	p = arg->private_data;
@@ -273,9 +279,9 @@
  * reset device
  */
 static int
-snd_emux_reset_seq_oss(snd_seq_oss_arg_t *arg)
+snd_emux_reset_seq_oss(struct snd_seq_oss_arg *arg)
 {
-	snd_emux_port_t *p;
+	struct snd_emux_port *p;
 
 	snd_assert(arg != NULL, return -ENXIO);
 	p = arg->private_data;
@@ -289,11 +295,11 @@
  * receive raw events: only SEQ_PRIVATE is accepted.
  */
 static int
-snd_emux_event_oss_input(snd_seq_event_t *ev, int direct, void *private_data,
+snd_emux_event_oss_input(struct snd_seq_event *ev, int direct, void *private_data,
 			 int atomic, int hop)
 {
-	snd_emux_t *emu;
-	snd_emux_port_t *p;
+	struct snd_emux *emu;
+	struct snd_emux_port *p;
 	unsigned char cmd, *data;
 
 	p = private_data;
@@ -320,14 +326,14 @@
  * OSS/AWE driver specific h/w controls
  */
 static void
-emuspec_control(snd_emux_t *emu, snd_emux_port_t *port, int cmd,
+emuspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
 		unsigned char *event, int atomic, int hop)
 {
 	int voice;
 	unsigned short p1;
 	short p2;
 	int i;
-	snd_midi_channel_t *chan;
+	struct snd_midi_channel *chan;
 
 	voice = event[3];
 	if (voice < 0 || voice >= port->chset.max_channels)
@@ -415,14 +421,14 @@
 #include <linux/ultrasound.h>
 
 static void
-gusspec_control(snd_emux_t *emu, snd_emux_port_t *port, int cmd,
+gusspec_control(struct snd_emux *emu, struct snd_emux_port *port, int cmd,
 		unsigned char *event, int atomic, int hop)
 {
 	int voice;
 	unsigned short p1;
 	short p2;
 	int plong;
-	snd_midi_channel_t *chan;
+	struct snd_midi_channel *chan;
 
 	if (port->port_mode != SNDRV_EMUX_PORT_MODE_OSS_SYNTH)
 		return;
@@ -483,9 +489,9 @@
  * send an event to midi emulation
  */
 static void
-fake_event(snd_emux_t *emu, snd_emux_port_t *port, int ch, int param, int val, int atomic, int hop)
+fake_event(struct snd_emux *emu, struct snd_emux_port *port, int ch, int param, int val, int atomic, int hop)
 {
-	snd_seq_event_t ev;
+	struct snd_seq_event ev;
 	memset(&ev, 0, sizeof(ev));
 	ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
 	ev.data.control.channel = ch;
diff --git a/sound/synth/emux/emux_proc.c b/sound/synth/emux/emux_proc.c
index 0f155d6..a70a179 100644
--- a/sound/synth/emux/emux_proc.c
+++ b/sound/synth/emux/emux_proc.c
@@ -30,10 +30,10 @@
 #ifdef CONFIG_PROC_FS
 
 static void
-snd_emux_proc_info_read(snd_info_entry_t *entry, 
-			snd_info_buffer_t *buf)
+snd_emux_proc_info_read(struct snd_info_entry *entry, 
+			struct snd_info_buffer *buf)
 {
-	snd_emux_t *emu;
+	struct snd_emux *emu;
 	int i;
 
 	emu = entry->private_data;
@@ -66,7 +66,7 @@
 	}
 #if 0  /* debug */
 	if (emu->voices[0].state != SNDRV_EMUX_ST_OFF && emu->voices[0].ch >= 0) {
-		snd_emux_voice_t *vp = &emu->voices[0];
+		struct snd_emux_voice *vp = &emu->voices[0];
 		snd_iprintf(buf, "voice 0: on\n");
 		snd_iprintf(buf, "mod delay=%x, atkhld=%x, dcysus=%x, rel=%x\n",
 			    vp->reg.parm.moddelay,
@@ -107,9 +107,9 @@
 }
 
 
-void snd_emux_proc_init(snd_emux_t *emu, snd_card_t *card, int device)
+void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	char name[64];
 
 	sprintf(name, "wavetableD%d", device);
@@ -127,7 +127,7 @@
 		emu->proc = entry;
 }
 
-void snd_emux_proc_free(snd_emux_t *emu)
+void snd_emux_proc_free(struct snd_emux *emu)
 {
 	if (emu->proc) {
 		snd_info_unregister(emu->proc);
diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c
index 8ccd33f..1a973d7 100644
--- a/sound/synth/emux/emux_seq.c
+++ b/sound/synth/emux/emux_seq.c
@@ -25,15 +25,14 @@
 
 /* Prototypes for static functions */
 static void free_port(void *private);
-static void snd_emux_init_port(snd_emux_port_t *p);
-static int snd_emux_use(void *private_data, snd_seq_port_subscribe_t *info);
-static int snd_emux_unuse(void *private_data, snd_seq_port_subscribe_t *info);
-static int get_client(snd_card_t *card, int index, char *name);
+static void snd_emux_init_port(struct snd_emux_port *p);
+static int snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info);
+static int snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info);
 
 /*
  * MIDI emulation operators
  */
-static snd_midi_op_t emux_ops = {
+static struct snd_midi_op emux_ops = {
 	snd_emux_note_on,
 	snd_emux_note_off,
 	snd_emux_key_press,
@@ -65,14 +64,14 @@
  * can connect to these ports to play midi data.
  */
 int
-snd_emux_init_seq(snd_emux_t *emu, snd_card_t *card, int index)
+snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index)
 {
 	int  i;
-	snd_seq_port_callback_t pinfo;
+	struct snd_seq_port_callback pinfo;
 	char tmpname[64];
 
-	sprintf(tmpname, "%s WaveTable", emu->name);
-	emu->client = get_client(card, index, tmpname);
+	emu->client = snd_seq_create_kernel_client(card, index,
+						   "%s WaveTable", emu->name);
 	if (emu->client < 0) {
 		snd_printk("can't create client\n");
 		return -ENODEV;
@@ -94,7 +93,7 @@
 	pinfo.event_input = snd_emux_event_input;
 
 	for (i = 0; i < emu->num_ports; i++) {
-		snd_emux_port_t *p;
+		struct snd_emux_port *p;
 
 		sprintf(tmpname, "%s Port %d", emu->name, i);
 		p = snd_emux_create_port(emu, tmpname, MIDI_CHANNELS,
@@ -119,7 +118,7 @@
  * destroy the kernel client.
  */
 void
-snd_emux_detach_seq(snd_emux_t *emu)
+snd_emux_detach_seq(struct snd_emux *emu)
 {
 	if (emu->voices)
 		snd_emux_terminate_all(emu);
@@ -137,12 +136,12 @@
  * create a sequencer port and channel_set
  */
 
-snd_emux_port_t *
-snd_emux_create_port(snd_emux_t *emu, char *name,
-			int max_channels, int oss_port,
-			snd_seq_port_callback_t *callback)
+struct snd_emux_port *
+snd_emux_create_port(struct snd_emux *emu, char *name,
+		     int max_channels, int oss_port,
+		     struct snd_seq_port_callback *callback)
 {
-	snd_emux_port_t *p;
+	struct snd_emux_port *p;
 	int i, type, cap;
 
 	/* Allocate structures for this channel */
@@ -150,7 +149,7 @@
 		snd_printk("no memory\n");
 		return NULL;
 	}
-	p->chset.channels = kcalloc(max_channels, sizeof(snd_midi_channel_t), GFP_KERNEL);
+	p->chset.channels = kcalloc(max_channels, sizeof(struct snd_midi_channel), GFP_KERNEL);
 	if (p->chset.channels == NULL) {
 		snd_printk("no memory\n");
 		kfree(p);
@@ -190,7 +189,7 @@
 static void
 free_port(void *private_data)
 {
-	snd_emux_port_t *p;
+	struct snd_emux_port *p;
 
 	p = private_data;
 	if (p) {
@@ -209,7 +208,7 @@
  * initialize the port specific parameters
  */
 static void
-snd_emux_init_port(snd_emux_port_t *p)
+snd_emux_init_port(struct snd_emux_port *p)
 {
 	p->drum_flags = DEFAULT_DRUM_FLAGS;
 	p->volume_atten = 0;
@@ -222,7 +221,7 @@
  * reset port
  */
 void
-snd_emux_reset_port(snd_emux_port_t *port)
+snd_emux_reset_port(struct snd_emux_port *port)
 {
 	int i;
 
@@ -241,7 +240,7 @@
 	port->ctrls[EMUX_MD_REALTIME_PAN] = 1;
 
 	for (i = 0; i < port->chset.max_channels; i++) {
-		snd_midi_channel_t *chan = port->chset.channels + i;
+		struct snd_midi_channel *chan = port->chset.channels + i;
 		chan->drum_channel = ((port->drum_flags >> i) & 1) ? 1 : 0;
 	}
 }
@@ -251,10 +250,10 @@
  * input sequencer event
  */
 int
-snd_emux_event_input(snd_seq_event_t *ev, int direct, void *private_data,
+snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private_data,
 		     int atomic, int hop)
 {
-	snd_emux_port_t *port;
+	struct snd_emux_port *port;
 
 	port = private_data;
 	snd_assert(port != NULL && ev != NULL, return -EINVAL);
@@ -269,7 +268,7 @@
  * increment usage count
  */
 int
-snd_emux_inc_count(snd_emux_t *emu)
+snd_emux_inc_count(struct snd_emux *emu)
 {
 	emu->used++;
 	if (!try_module_get(emu->ops.owner))
@@ -288,7 +287,7 @@
  * decrease usage count
  */
 void
-snd_emux_dec_count(snd_emux_t *emu)
+snd_emux_dec_count(struct snd_emux *emu)
 {
 	module_put(emu->card->module);
 	emu->used--;
@@ -302,10 +301,10 @@
  * Routine that is called upon a first use of a particular port
  */
 static int
-snd_emux_use(void *private_data, snd_seq_port_subscribe_t *info)
+snd_emux_use(void *private_data, struct snd_seq_port_subscribe *info)
 {
-	snd_emux_port_t *p;
-	snd_emux_t *emu;
+	struct snd_emux_port *p;
+	struct snd_emux *emu;
 
 	p = private_data;
 	snd_assert(p != NULL, return -EINVAL);
@@ -323,10 +322,10 @@
  * Routine that is called upon the last unuse() of a particular port.
  */
 static int
-snd_emux_unuse(void *private_data, snd_seq_port_subscribe_t *info)
+snd_emux_unuse(void *private_data, struct snd_seq_port_subscribe *info)
 {
-	snd_emux_port_t *p;
-	snd_emux_t *emu;
+	struct snd_emux_port *p;
+	struct snd_emux *emu;
 
 	p = private_data;
 	snd_assert(p != NULL, return -EINVAL);
@@ -342,39 +341,9 @@
 
 
 /*
- * Create a sequencer client
- */
-static int
-get_client(snd_card_t *card, int index, char *name)
-{
-	snd_seq_client_callback_t callbacks;
-	snd_seq_client_info_t cinfo;
-	int client;
-
-	memset(&callbacks, 0, sizeof(callbacks));
-	callbacks.private_data = NULL;
-	callbacks.allow_input = 1;
-	callbacks.allow_output = 1;
-
-	/* Find a free client, start from 1 as the MPU expects to use 0 */
-	client = snd_seq_create_kernel_client(card, index, &callbacks);
-	if (client < 0)
-		return client;
-
-	memset(&cinfo, 0, sizeof(cinfo));
-	cinfo.client = client;
-	cinfo.type = KERNEL_CLIENT;
-	strcpy(cinfo.name, name);
-	snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, &cinfo);
-
-	return client;
-}
-
-
-/*
  * attach virtual rawmidi devices
  */
-int snd_emux_init_virmidi(snd_emux_t *emu, snd_card_t *card)
+int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card)
 {
 	int i;
 
@@ -382,13 +351,13 @@
 	if (emu->midi_ports <= 0)
 		return 0;
 
-	emu->vmidi = kcalloc(emu->midi_ports, sizeof(snd_rawmidi_t*), GFP_KERNEL);
+	emu->vmidi = kcalloc(emu->midi_ports, sizeof(struct snd_rawmidi *), GFP_KERNEL);
 	if (emu->vmidi == NULL)
 		return -ENOMEM;
 
 	for (i = 0; i < emu->midi_ports; i++) {
-		snd_rawmidi_t *rmidi;
-		snd_virmidi_dev_t *rdev;
+		struct snd_rawmidi *rmidi;
+		struct snd_virmidi_dev *rdev;
 		if (snd_virmidi_new(card, emu->midi_devidx + i, &rmidi) < 0)
 			goto __error;
 		rdev = rmidi->private_data;
@@ -411,7 +380,7 @@
 	return -ENOMEM;
 }
 
-int snd_emux_delete_virmidi(snd_emux_t *emu)
+int snd_emux_delete_virmidi(struct snd_emux *emu)
 {
 	int i;
 
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index bd71b73..24705d1 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -36,30 +36,34 @@
 #define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
 #define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
 
-static int get_zone(snd_emux_t *emu, snd_emux_port_t *port, int *notep, int vel, snd_midi_channel_t *chan, snd_sf_zone_t **table);
-static int get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan);
-static void terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free);
-static void exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass);
-static void terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free);
-static void update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update);
-static void setup_voice(snd_emux_voice_t *vp);
-static int calc_pan(snd_emux_voice_t *vp);
-static int calc_volume(snd_emux_voice_t *vp);
-static int calc_pitch(snd_emux_voice_t *vp);
+static int get_zone(struct snd_emux *emu, struct snd_emux_port *port,
+		    int *notep, int vel, struct snd_midi_channel *chan,
+		    struct snd_sf_zone **table);
+static int get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan);
+static void terminate_note1(struct snd_emux *emu, int note,
+			    struct snd_midi_channel *chan, int free);
+static void exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port,
+			       int exclass);
+static void terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free);
+static void update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update);
+static void setup_voice(struct snd_emux_voice *vp);
+static int calc_pan(struct snd_emux_voice *vp);
+static int calc_volume(struct snd_emux_voice *vp);
+static int calc_pitch(struct snd_emux_voice *vp);
 
 
 /*
  * Start a note.
  */
 void
-snd_emux_note_on(void *p, int note, int vel, snd_midi_channel_t *chan)
+snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
 {
-	snd_emux_t *emu;
+	struct snd_emux *emu;
 	int i, key, nvoices;
-	snd_emux_voice_t *vp;
-	snd_sf_zone_t *table[SNDRV_EMUX_MAX_MULTI_VOICES];
+	struct snd_emux_voice *vp;
+	struct snd_sf_zone *table[SNDRV_EMUX_MAX_MULTI_VOICES];
 	unsigned long flags;
-	snd_emux_port_t *port;
+	struct snd_emux_port *port;
 
 	port = p;
 	snd_assert(port != NULL && chan != NULL, return);
@@ -76,7 +80,7 @@
 
 	/* exclusive note off */
 	for (i = 0; i < nvoices; i++) {
-		snd_sf_zone_t *zp = table[i];
+		struct snd_sf_zone *zp = table[i];
 		if (zp && zp->v.exclusiveClass)
 			exclusive_note_off(emu, port, zp->v.exclusiveClass);
 	}
@@ -138,7 +142,7 @@
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
 	if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
 		/* clear voice position for the next note on this channel */
-		snd_emux_effect_table_t *fx = chan->private;
+		struct snd_emux_effect_table *fx = chan->private;
 		if (fx) {
 			fx->flag[EMUX_FX_SAMPLE_START] = 0;
 			fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
@@ -151,13 +155,13 @@
  * Release a note in response to a midi note off.
  */
 void
-snd_emux_note_off(void *p, int note, int vel, snd_midi_channel_t *chan)
+snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
 {
 	int ch;
-	snd_emux_t *emu;
-	snd_emux_voice_t *vp;
+	struct snd_emux *emu;
+	struct snd_emux_voice *vp;
 	unsigned long flags;
-	snd_emux_port_t *port;
+	struct snd_emux_port *port;
 
 	port = p;
 	snd_assert(port != NULL && chan != NULL, return);
@@ -199,11 +203,12 @@
  */
 void snd_emux_timer_callback(unsigned long data)
 {
-	snd_emux_t *emu = (snd_emux_t*) data;
-	snd_emux_voice_t *vp;
+	struct snd_emux *emu = (struct snd_emux *) data;
+	struct snd_emux_voice *vp;
+	unsigned long flags;
 	int ch, do_again = 0;
 
-	spin_lock(&emu->voice_lock);
+	spin_lock_irqsave(&emu->voice_lock, flags);
 	for (ch = 0; ch < emu->max_voices; ch++) {
 		vp = &emu->voices[ch];
 		if (vp->state == SNDRV_EMUX_ST_PENDING) {
@@ -221,20 +226,20 @@
 		emu->timer_active = 1;
 	} else
 		emu->timer_active = 0;
-	spin_unlock(&emu->voice_lock);
+	spin_unlock_irqrestore(&emu->voice_lock, flags);
 }
 
 /*
  * key pressure change
  */
 void
-snd_emux_key_press(void *p, int note, int vel, snd_midi_channel_t *chan)
+snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
 {
 	int ch;
-	snd_emux_t *emu;
-	snd_emux_voice_t *vp;
+	struct snd_emux *emu;
+	struct snd_emux_voice *vp;
 	unsigned long flags;
-	snd_emux_port_t *port;
+	struct snd_emux_port *port;
 
 	port = p;
 	snd_assert(port != NULL && chan != NULL, return);
@@ -260,10 +265,10 @@
  * Modulate the voices which belong to the channel
  */
 void
-snd_emux_update_channel(snd_emux_port_t *port, snd_midi_channel_t *chan, int update)
+snd_emux_update_channel(struct snd_emux_port *port, struct snd_midi_channel *chan, int update)
 {
-	snd_emux_t *emu;
-	snd_emux_voice_t *vp;
+	struct snd_emux *emu;
+	struct snd_emux_voice *vp;
 	int i;
 	unsigned long flags;
 
@@ -287,10 +292,10 @@
  * Modulate all the voices which belong to the port.
  */
 void
-snd_emux_update_port(snd_emux_port_t *port, int update)
+snd_emux_update_port(struct snd_emux_port *port, int update)
 {
-	snd_emux_t *emu; 
-	snd_emux_voice_t *vp;
+	struct snd_emux *emu; 
+	struct snd_emux_voice *vp;
 	int i;
 	unsigned long flags;
 
@@ -316,9 +321,9 @@
  * control events, not just the midi controllers
  */
 void
-snd_emux_control(void *p, int type, snd_midi_channel_t *chan)
+snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
 {
-	snd_emux_port_t *port;
+	struct snd_emux_port *port;
 
 	port = p;
 	snd_assert(port != NULL && chan != NULL, return);
@@ -364,10 +369,10 @@
  * terminate note - if free flag is true, free the terminated voice
  */
 static void
-terminate_note1(snd_emux_t *emu, int note, snd_midi_channel_t *chan, int free)
+terminate_note1(struct snd_emux *emu, int note, struct snd_midi_channel *chan, int free)
 {
 	int  i;
-	snd_emux_voice_t *vp;
+	struct snd_emux_voice *vp;
 	unsigned long flags;
 
 	spin_lock_irqsave(&emu->voice_lock, flags);
@@ -385,10 +390,10 @@
  * terminate note - exported for midi emulation
  */
 void
-snd_emux_terminate_note(void *p, int note, snd_midi_channel_t *chan)
+snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan)
 {
-	snd_emux_t *emu;
-	snd_emux_port_t *port;
+	struct snd_emux *emu;
+	struct snd_emux_port *port;
 
 	port = p;
 	snd_assert(port != NULL && chan != NULL, return);
@@ -405,10 +410,10 @@
  * Terminate all the notes
  */
 void
-snd_emux_terminate_all(snd_emux_t *emu)
+snd_emux_terminate_all(struct snd_emux *emu)
 {
 	int i;
-	snd_emux_voice_t *vp;
+	struct snd_emux_voice *vp;
 	unsigned long flags;
 
 	spin_lock_irqsave(&emu->voice_lock, flags);
@@ -434,11 +439,11 @@
  * Terminate all voices associated with the given port
  */
 void
-snd_emux_sounds_off_all(snd_emux_port_t *port)
+snd_emux_sounds_off_all(struct snd_emux_port *port)
 {
 	int i;
-	snd_emux_t *emu;
-	snd_emux_voice_t *vp;
+	struct snd_emux *emu;
+	struct snd_emux_voice *vp;
 	unsigned long flags;
 
 	snd_assert(port != NULL, return);
@@ -468,9 +473,9 @@
  * is mainly for drums.
  */
 static void
-exclusive_note_off(snd_emux_t *emu, snd_emux_port_t *port, int exclass)
+exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port, int exclass)
 {
-	snd_emux_voice_t *vp;
+	struct snd_emux_voice *vp;
 	int  i;
 	unsigned long flags;
 
@@ -490,7 +495,7 @@
  * if free flag is true, call free_voice after termination
  */
 static void
-terminate_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int free)
+terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free)
 {
 	emu->ops.terminate(vp);
 	vp->time = emu->use_time++;
@@ -508,7 +513,7 @@
  * Modulate the voice
  */
 static void
-update_voice(snd_emux_t *emu, snd_emux_voice_t *vp, int update)
+update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update)
 {
 	if (!STATE_IS_PLAYING(vp->state))
 		return;
@@ -543,9 +548,9 @@
  * will be needed later.
  */
 static void
-setup_voice(snd_emux_voice_t *vp)
+setup_voice(struct snd_emux_voice *vp)
 {
-	soundfont_voice_parm_t *parm;
+	struct soundfont_voice_parm *parm;
 	int pitch;
 
 	/* copy the original register values */
@@ -636,9 +641,9 @@
 };
 
 static int
-calc_pan(snd_emux_voice_t *vp)
+calc_pan(struct snd_emux_voice *vp)
 {
-	snd_midi_channel_t *chan = vp->chan;
+	struct snd_midi_channel *chan = vp->chan;
 	int pan;
 
 	/* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
@@ -737,12 +742,12 @@
  * voice and channels parameters.
  */
 static int
-calc_volume(snd_emux_voice_t *vp)
+calc_volume(struct snd_emux_voice *vp)
 {
 	int vol;
 	int main_vol, expression_vol, master_vol;
-	snd_midi_channel_t *chan = vp->chan;
-	snd_emux_port_t *port = vp->port;
+	struct snd_midi_channel *chan = vp->chan;
+	struct snd_emux_port *port = vp->port;
 
 	expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION];
 	LIMITMAX(vp->velocity, 127);
@@ -775,7 +780,7 @@
 
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
 	if (chan->private) {
-		snd_emux_effect_table_t *fx = chan->private;
+		struct snd_emux_effect_table *fx = chan->private;
 		vol += fx->val[EMUX_FX_ATTEN];
 	}
 #endif
@@ -808,9 +813,9 @@
  */
 
 static int
-calc_pitch(snd_emux_voice_t *vp)
+calc_pitch(struct snd_emux_voice *vp)
 {
-	snd_midi_channel_t *chan = vp->chan;
+	struct snd_midi_channel *chan = vp->chan;
 	int offset;
 
 	/* calculate offset */
@@ -837,7 +842,7 @@
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
 	/* add initial pitch correction */
 	if (chan->private) {
-		snd_emux_effect_table_t *fx = chan->private;
+		struct snd_emux_effect_table *fx = chan->private;
 		if (fx->flag[EMUX_FX_INIT_PITCH])
 			offset += fx->val[EMUX_FX_INIT_PITCH];
 	}
@@ -857,7 +862,7 @@
  * Get the bank number assigned to the channel
  */
 static int
-get_bank(snd_emux_port_t *port, snd_midi_channel_t *chan)
+get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan)
 {
 	int val;
 
@@ -886,8 +891,9 @@
  * The resultant zones are stored on table.
  */
 static int
-get_zone(snd_emux_t *emu, snd_emux_port_t *port,
-	 int *notep, int vel, snd_midi_channel_t *chan, snd_sf_zone_t **table)
+get_zone(struct snd_emux *emu, struct snd_emux_port *port,
+	 int *notep, int vel, struct snd_midi_channel *chan,
+	 struct snd_sf_zone **table)
 {
 	int preset, bank, def_preset, def_bank;
 
@@ -910,9 +916,9 @@
 /*
  */
 void
-snd_emux_init_voices(snd_emux_t *emu)
+snd_emux_init_voices(struct snd_emux *emu)
 {
-	snd_emux_voice_t *vp;
+	struct snd_emux_voice *vp;
 	int i;
 	unsigned long flags;
 
@@ -932,7 +938,7 @@
 
 /*
  */
-void snd_emux_lock_voice(snd_emux_t *emu, int voice)
+void snd_emux_lock_voice(struct snd_emux *emu, int voice)
 {
 	unsigned long flags;
 
@@ -947,7 +953,7 @@
 
 /*
  */
-void snd_emux_unlock_voice(snd_emux_t *emu, int voice)
+void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
 {
 	unsigned long flags;
 
diff --git a/sound/synth/emux/emux_voice.h b/sound/synth/emux/emux_voice.h
index 67eb553..0a56ca18 100644
--- a/sound/synth/emux/emux_voice.h
+++ b/sound/synth/emux/emux_voice.h
@@ -29,60 +29,69 @@
 #include <sound/emux_synth.h>
 
 /* Prototypes for emux_seq.c */
-int snd_emux_init_seq(snd_emux_t *emu, snd_card_t *card, int index);
-void snd_emux_detach_seq(snd_emux_t *emu);
-snd_emux_port_t *snd_emux_create_port(snd_emux_t *emu, char *name, int max_channels, int type, snd_seq_port_callback_t *callback);
-void snd_emux_reset_port(snd_emux_port_t *port);
-int snd_emux_event_input(snd_seq_event_t *ev, int direct, void *private, int atomic, int hop);
-int snd_emux_inc_count(snd_emux_t *emu);
-void snd_emux_dec_count(snd_emux_t *emu);
-int snd_emux_init_virmidi(snd_emux_t *emu, snd_card_t *card);
-int snd_emux_delete_virmidi(snd_emux_t *emu);
+int snd_emux_init_seq(struct snd_emux *emu, struct snd_card *card, int index);
+void snd_emux_detach_seq(struct snd_emux *emu);
+struct snd_emux_port *snd_emux_create_port(struct snd_emux *emu, char *name,
+					   int max_channels, int type,
+					   struct snd_seq_port_callback *callback);
+void snd_emux_reset_port(struct snd_emux_port *port);
+int snd_emux_event_input(struct snd_seq_event *ev, int direct, void *private,
+			 int atomic, int hop);
+int snd_emux_inc_count(struct snd_emux *emu);
+void snd_emux_dec_count(struct snd_emux *emu);
+int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card);
+int snd_emux_delete_virmidi(struct snd_emux *emu);
 
 /* Prototypes for emux_synth.c */
-void snd_emux_init_voices(snd_emux_t *emu);
+void snd_emux_init_voices(struct snd_emux *emu);
 
 void snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan);
 void snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan);
 void snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan);
-void snd_emux_terminate_note(void *p, int note, snd_midi_channel_t *chan);
+void snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan);
 void snd_emux_control(void *p, int type, struct snd_midi_channel *chan);
 
-void snd_emux_sounds_off_all(snd_emux_port_t *port);
-void snd_emux_update_channel(snd_emux_port_t *port, snd_midi_channel_t *chan, int update);
-void snd_emux_update_port(snd_emux_port_t *port, int update);
+void snd_emux_sounds_off_all(struct snd_emux_port *port);
+void snd_emux_update_channel(struct snd_emux_port *port,
+			     struct snd_midi_channel *chan, int update);
+void snd_emux_update_port(struct snd_emux_port *port, int update);
 
 void snd_emux_timer_callback(unsigned long data);
 
 /* emux_effect.c */
 #ifdef SNDRV_EMUX_USE_RAW_EFFECT
-void snd_emux_create_effect(snd_emux_port_t *p);
-void snd_emux_delete_effect(snd_emux_port_t *p);
-void snd_emux_clear_effect(snd_emux_port_t *p);
-void snd_emux_setup_effect(snd_emux_voice_t *vp);
-void snd_emux_send_effect_oss(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val);
-void snd_emux_send_effect(snd_emux_port_t *port, snd_midi_channel_t *chan, int type, int val, int mode);
+void snd_emux_create_effect(struct snd_emux_port *p);
+void snd_emux_delete_effect(struct snd_emux_port *p);
+void snd_emux_clear_effect(struct snd_emux_port *p);
+void snd_emux_setup_effect(struct snd_emux_voice *vp);
+void snd_emux_send_effect_oss(struct snd_emux_port *port,
+			      struct snd_midi_channel *chan, int type, int val);
+void snd_emux_send_effect(struct snd_emux_port *port,
+			  struct snd_midi_channel *chan, int type, int val, int mode);
 #endif
 
 /* emux_nrpn.c */
-void snd_emux_sysex(void *private_data, unsigned char *buf, int len, int parsed, snd_midi_channel_set_t *chset);
-int snd_emux_xg_control(snd_emux_port_t *port, snd_midi_channel_t *chan, int param);
-void snd_emux_nrpn(void *private_data, snd_midi_channel_t *chan, snd_midi_channel_set_t *chset);
+void snd_emux_sysex(void *private_data, unsigned char *buf, int len,
+		    int parsed, struct snd_midi_channel_set *chset);
+int snd_emux_xg_control(struct snd_emux_port *port,
+			struct snd_midi_channel *chan, int param);
+void snd_emux_nrpn(void *private_data, struct snd_midi_channel *chan,
+		   struct snd_midi_channel_set *chset);
 
 /* emux_oss.c */
-void snd_emux_init_seq_oss(snd_emux_t *emu);
-void snd_emux_detach_seq_oss(snd_emux_t *emu);
+void snd_emux_init_seq_oss(struct snd_emux *emu);
+void snd_emux_detach_seq_oss(struct snd_emux *emu);
 
 /* emux_proc.c */
 #ifdef CONFIG_PROC_FS
-void snd_emux_proc_init(snd_emux_t *emu, snd_card_t *card, int device);
-void snd_emux_proc_free(snd_emux_t *emu);
+void snd_emux_proc_init(struct snd_emux *emu, struct snd_card *card, int device);
+void snd_emux_proc_free(struct snd_emux *emu);
 #endif
 
 #define STATE_IS_PLAYING(s) ((s) & SNDRV_EMUX_ST_ON)
 
 /* emux_hwdep.c */
-int snd_emux_init_hwdep(snd_emux_t *emu);
-void snd_emux_delete_hwdep(snd_emux_t *emu);
+int snd_emux_init_hwdep(struct snd_emux *emu);
+void snd_emux_delete_hwdep(struct snd_emux *emu);
 
 #endif
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index d0925ea..4c5754d 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -34,38 +34,49 @@
 
 /* Prototypes for static functions */
 
-static int open_patch(snd_sf_list_t *sflist, const char __user *data, int count, int client);
-static snd_soundfont_t *newsf(snd_sf_list_t *sflist, int type, char *name);
-static int is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name);
-static int close_patch(snd_sf_list_t *sflist);
-static int probe_data(snd_sf_list_t *sflist, int sample_id);
-static void set_zone_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_zone_t *zp);
-static snd_sf_zone_t *sf_zone_new(snd_sf_list_t *sflist, snd_soundfont_t *sf);
-static void set_sample_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp);
-static snd_sf_sample_t *sf_sample_new(snd_sf_list_t *sflist, snd_soundfont_t *sf);
-static void sf_sample_delete(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp);
-static int load_map(snd_sf_list_t *sflist, const void __user *data, int count);
-static int load_info(snd_sf_list_t *sflist, const void __user *data, long count);
-static int remove_info(snd_sf_list_t *sflist, snd_soundfont_t *sf, int bank, int instr);
-static void init_voice_info(soundfont_voice_info_t *avp);
-static void init_voice_parm(soundfont_voice_parm_t *pp);
-static snd_sf_sample_t *set_sample(snd_soundfont_t *sf, soundfont_voice_info_t *avp);
-static snd_sf_sample_t *find_sample(snd_soundfont_t *sf, int sample_id);
-static int load_data(snd_sf_list_t *sflist, const void __user *data, long count);
-static void rebuild_presets(snd_sf_list_t *sflist);
-static void add_preset(snd_sf_list_t *sflist, snd_sf_zone_t *cur);
-static void delete_preset(snd_sf_list_t *sflist, snd_sf_zone_t *zp);
-static snd_sf_zone_t *search_first_zone(snd_sf_list_t *sflist, int bank, int preset, int key);
-static int search_zones(snd_sf_list_t *sflist, int *notep, int vel, int preset, int bank, snd_sf_zone_t **table, int max_layers, int level);
+static int open_patch(struct snd_sf_list *sflist, const char __user *data,
+		      int count, int client);
+static struct snd_soundfont *newsf(struct snd_sf_list *sflist, int type, char *name);
+static int is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name);
+static int close_patch(struct snd_sf_list *sflist);
+static int probe_data(struct snd_sf_list *sflist, int sample_id);
+static void set_zone_counter(struct snd_sf_list *sflist,
+			     struct snd_soundfont *sf, struct snd_sf_zone *zp);
+static struct snd_sf_zone *sf_zone_new(struct snd_sf_list *sflist,
+				       struct snd_soundfont *sf);
+static void set_sample_counter(struct snd_sf_list *sflist,
+			       struct snd_soundfont *sf, struct snd_sf_sample *sp);
+static struct snd_sf_sample *sf_sample_new(struct snd_sf_list *sflist,
+					   struct snd_soundfont *sf);
+static void sf_sample_delete(struct snd_sf_list *sflist,
+			     struct snd_soundfont *sf, struct snd_sf_sample *sp);
+static int load_map(struct snd_sf_list *sflist, const void __user *data, int count);
+static int load_info(struct snd_sf_list *sflist, const void __user *data, long count);
+static int remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
+		       int bank, int instr);
+static void init_voice_info(struct soundfont_voice_info *avp);
+static void init_voice_parm(struct soundfont_voice_parm *pp);
+static struct snd_sf_sample *set_sample(struct snd_soundfont *sf,
+					struct soundfont_voice_info *avp);
+static struct snd_sf_sample *find_sample(struct snd_soundfont *sf, int sample_id);
+static int load_data(struct snd_sf_list *sflist, const void __user *data, long count);
+static void rebuild_presets(struct snd_sf_list *sflist);
+static void add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur);
+static void delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp);
+static struct snd_sf_zone *search_first_zone(struct snd_sf_list *sflist,
+					     int bank, int preset, int key);
+static int search_zones(struct snd_sf_list *sflist, int *notep, int vel,
+			int preset, int bank, struct snd_sf_zone **table,
+			int max_layers, int level);
 static int get_index(int bank, int instr, int key);
-static void snd_sf_init(snd_sf_list_t *sflist);
-static void snd_sf_clear(snd_sf_list_t *sflist);
+static void snd_sf_init(struct snd_sf_list *sflist);
+static void snd_sf_clear(struct snd_sf_list *sflist);
 
 /*
  * lock access to sflist
  */
 static void
-lock_preset(snd_sf_list_t *sflist)
+lock_preset(struct snd_sf_list *sflist)
 {
 	unsigned long flags;
 	down(&sflist->presets_mutex);
@@ -79,7 +90,7 @@
  * remove lock
  */
 static void
-unlock_preset(snd_sf_list_t *sflist)
+unlock_preset(struct snd_sf_list *sflist)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&sflist->lock, flags);
@@ -93,7 +104,7 @@
  * close the patch if the patch was opened by this client.
  */
 int
-snd_soundfont_close_check(snd_sf_list_t *sflist, int client)
+snd_soundfont_close_check(struct snd_sf_list *sflist, int client)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&sflist->lock, flags);
@@ -115,9 +126,10 @@
  * it wants to do with it.
  */
 int
-snd_soundfont_load(snd_sf_list_t *sflist, const void __user *data, long count, int client)
+snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data,
+		   long count, int client)
 {
-	soundfont_patch_info_t patch;
+	struct soundfont_patch_info patch;
 	unsigned long flags;
 	int  rc;
 
@@ -215,10 +227,11 @@
 
 /* open patch; create sf list */
 static int
-open_patch(snd_sf_list_t *sflist, const char __user *data, int count, int client)
+open_patch(struct snd_sf_list *sflist, const char __user *data,
+	   int count, int client)
 {
-	soundfont_open_parm_t parm;
-	snd_soundfont_t *sf;
+	struct soundfont_open_parm parm;
+	struct snd_soundfont *sf;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sflist->lock, flags);
@@ -251,10 +264,10 @@
 /*
  * Allocate a new soundfont structure.
  */
-static snd_soundfont_t *
-newsf(snd_sf_list_t *sflist, int type, char *name)
+static struct snd_soundfont *
+newsf(struct snd_sf_list *sflist, int type, char *name)
 {
-	snd_soundfont_t *sf;
+	struct snd_soundfont *sf;
 
 	/* check the shared fonts */
 	if (type & SNDRV_SFNT_PAT_SHARED) {
@@ -287,7 +300,7 @@
 
 /* check if the given name matches to the existing list */
 static int
-is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name)
+is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name)
 {
 	return ((sf->type & SNDRV_SFNT_PAT_SHARED) &&
 		(sf->type & 0x0f) == (type & 0x0f) &&
@@ -299,7 +312,7 @@
  * Close the current patch.
  */
 static int
-close_patch(snd_sf_list_t *sflist)
+close_patch(struct snd_sf_list *sflist)
 {
 	unsigned long flags;
 
@@ -316,7 +329,7 @@
 
 /* probe sample in the current list -- nothing to be loaded */
 static int
-probe_data(snd_sf_list_t *sflist, int sample_id)
+probe_data(struct snd_sf_list *sflist, int sample_id)
 {
 	/* patch must be opened */
 	if (sflist->currsf) {
@@ -331,7 +344,8 @@
  * increment zone counter
  */
 static void
-set_zone_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_zone_t *zp)
+set_zone_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
+		 struct snd_sf_zone *zp)
 {
 	zp->counter = sflist->zone_counter++;
 	if (sf->type & SNDRV_SFNT_PAT_LOCKED)
@@ -341,10 +355,10 @@
 /*
  * allocate a new zone record
  */
-static snd_sf_zone_t *
-sf_zone_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
+static struct snd_sf_zone *
+sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
 {
-	snd_sf_zone_t *zp;
+	struct snd_sf_zone *zp;
 
 	if ((zp = kzalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
 		return NULL;
@@ -362,7 +376,8 @@
  * increment sample couter
  */
 static void
-set_sample_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp)
+set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
+		   struct snd_sf_sample *sp)
 {
 	sp->counter = sflist->sample_counter++;
 	if (sf->type & SNDRV_SFNT_PAT_LOCKED)
@@ -372,10 +387,10 @@
 /*
  * allocate a new sample list record
  */
-static snd_sf_sample_t *
-sf_sample_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
+static struct snd_sf_sample *
+sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
 {
-	snd_sf_sample_t *sp;
+	struct snd_sf_sample *sp;
 
 	if ((sp = kzalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
 		return NULL;
@@ -392,7 +407,8 @@
  * only the last allocated sample can be deleted.
  */
 static void
-sf_sample_delete(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp)
+sf_sample_delete(struct snd_sf_list *sflist, struct snd_soundfont *sf,
+		 struct snd_sf_sample *sp)
 {
 	/* only last sample is accepted */
 	if (sp == sf->samples) {
@@ -404,11 +420,11 @@
 
 /* load voice map */
 static int
-load_map(snd_sf_list_t *sflist, const void __user *data, int count)
+load_map(struct snd_sf_list *sflist, const void __user *data, int count)
 {
-	snd_sf_zone_t *zp, *prevp;
-	snd_soundfont_t *sf;
-	soundfont_voice_map_t map;
+	struct snd_sf_zone *zp, *prevp;
+	struct snd_soundfont *sf;
+	struct soundfont_voice_map map;
 
 	/* get the link info */
 	if (count < (int)sizeof(map))
@@ -469,9 +485,10 @@
 
 /* remove the present instrument layers */
 static int
-remove_info(snd_sf_list_t *sflist, snd_soundfont_t *sf, int bank, int instr)
+remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
+	    int bank, int instr)
 {
-	snd_sf_zone_t *prev, *next, *p;
+	struct snd_sf_zone *prev, *next, *p;
 	int removed = 0;
 
 	prev = NULL;
@@ -500,11 +517,11 @@
  * open soundfont.
  */
 static int
-load_info(snd_sf_list_t *sflist, const void __user *data, long count)
+load_info(struct snd_sf_list *sflist, const void __user *data, long count)
 {
-	snd_soundfont_t *sf;
-	snd_sf_zone_t *zone;
-	soundfont_voice_rec_hdr_t hdr;
+	struct snd_soundfont *sf;
+	struct snd_sf_zone *zone;
+	struct soundfont_voice_rec_hdr hdr;
 	int i;
 
 	/* patch must be opened */
@@ -529,7 +546,7 @@
 		return -EINVAL;
 	}
 
-	if (count < (long)sizeof(soundfont_voice_info_t)*hdr.nvoices) {
+	if (count < (long)sizeof(struct soundfont_voice_info) * hdr.nvoices) {
 		printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n",
 		       count, hdr.nvoices);
 		return -EINVAL;
@@ -553,7 +570,7 @@
 	}
 
 	for (i = 0; i < hdr.nvoices; i++) {
-		snd_sf_zone_t tmpzone;
+		struct snd_sf_zone tmpzone;
 
 		/* copy awe_voice_info parameters */
 		if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
@@ -590,7 +607,7 @@
 
 /* initialize voice_info record */
 static void
-init_voice_info(soundfont_voice_info_t *avp)
+init_voice_info(struct soundfont_voice_info *avp)
 {
 	memset(avp, 0, sizeof(*avp));
 
@@ -614,7 +631,7 @@
  * Chorus and Reverb effects are zero.
  */
 static void
-init_voice_parm(soundfont_voice_parm_t *pp)
+init_voice_parm(struct soundfont_voice_parm *pp)
 {
 	memset(pp, 0, sizeof(*pp));
 
@@ -635,10 +652,10 @@
 }	
 
 /* search the specified sample */
-static snd_sf_sample_t *
-set_sample(snd_soundfont_t *sf, soundfont_voice_info_t *avp)
+static struct snd_sf_sample *
+set_sample(struct snd_soundfont *sf, struct soundfont_voice_info *avp)
 {
-	snd_sf_sample_t *sample;
+	struct snd_sf_sample *sample;
 
 	sample = find_sample(sf, avp->sample);
 	if (sample == NULL)
@@ -661,10 +678,10 @@
 }
 
 /* find the sample pointer with the given id in the soundfont */
-static snd_sf_sample_t *
-find_sample(snd_soundfont_t *sf, int sample_id)
+static struct snd_sf_sample *
+find_sample(struct snd_soundfont *sf, int sample_id)
 {
-	snd_sf_sample_t *p;
+	struct snd_sf_sample *p;
 
 	if (sf == NULL)
 		return NULL;
@@ -684,11 +701,11 @@
  * routine.
  */
 static int
-load_data(snd_sf_list_t *sflist, const void __user *data, long count)
+load_data(struct snd_sf_list *sflist, const void __user *data, long count)
 {
-	snd_soundfont_t *sf;
-	soundfont_sample_info_t sample_info;
-	snd_sf_sample_t *sp;
+	struct snd_soundfont *sf;
+	struct soundfont_sample_info sample_info;
+	struct snd_sf_sample *sp;
 	long off;
 
 	/* patch must be opened */
@@ -922,12 +939,13 @@
 
 /* load GUS patch */
 static int
-load_guspatch(snd_sf_list_t *sflist, const char __user *data, long count, int client)
+load_guspatch(struct snd_sf_list *sflist, const char __user *data,
+	      long count, int client)
 {
 	struct patch_info patch;
-	snd_soundfont_t *sf;
-	snd_sf_zone_t *zone;
-	snd_sf_sample_t *smp;
+	struct snd_soundfont *sf;
+	struct snd_sf_zone *zone;
+	struct snd_sf_sample *smp;
 	int note, sample_id;
 	int rc;
 
@@ -992,7 +1010,8 @@
 	 */
 	if (sflist->callback.sample_new) {
 		rc = sflist->callback.sample_new
-			(sflist->callback.private_data, smp, sflist->memhdr, data, count);
+			(sflist->callback.private_data, smp, sflist->memhdr,
+			 data, count);
 		if (rc < 0) {
 			sf_sample_delete(sflist, sf, smp);
 			return rc;
@@ -1095,7 +1114,7 @@
 
 /* load GUS patch */
 int
-snd_soundfont_load_guspatch(snd_sf_list_t *sflist, const char __user *data,
+snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
 			    long count, int client)
 {
 	int rc;
@@ -1114,10 +1133,10 @@
  * bank/key combination).
  */
 static void
-rebuild_presets(snd_sf_list_t *sflist)
+rebuild_presets(struct snd_sf_list *sflist)
 {
-	snd_soundfont_t *sf;
-	snd_sf_zone_t *cur;
+	struct snd_soundfont *sf;
+	struct snd_sf_zone *cur;
 
 	/* clear preset table */
 	memset(sflist->presets, 0, sizeof(sflist->presets));
@@ -1142,15 +1161,15 @@
  * add the given zone to preset table
  */
 static void
-add_preset(snd_sf_list_t *sflist, snd_sf_zone_t *cur)
+add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
 {
-	snd_sf_zone_t *zone;
+	struct snd_sf_zone *zone;
 	int index;
 
 	zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
 	if (zone && zone->v.sf_id != cur->v.sf_id) {
 		/* different instrument was already defined */
-		snd_sf_zone_t *p;
+		struct snd_sf_zone *p;
 		/* compare the allocated time */
 		for (p = zone; p; p = p->next_zone) {
 			if (p->counter > cur->counter)
@@ -1174,10 +1193,10 @@
  * delete the given zones from preset_table
  */
 static void
-delete_preset(snd_sf_list_t *sflist, snd_sf_zone_t *zp)
+delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
 {
 	int index;
-	snd_sf_zone_t *p;
+	struct snd_sf_zone *p;
 
 	if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
 		return;
@@ -1200,10 +1219,10 @@
  * This function returns the number of found zones.  0 if not found.
  */
 int
-snd_soundfont_search_zone(snd_sf_list_t *sflist, int *notep, int vel,
+snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
 			  int preset, int bank,
 			  int def_preset, int def_bank,
-			  snd_sf_zone_t **table, int max_layers)
+			  struct snd_sf_zone **table, int max_layers)
 {
 	int nvoices;
 	unsigned long flags;
@@ -1217,10 +1236,13 @@
 		spin_unlock_irqrestore(&sflist->lock, flags);
 		return 0;
 	}
-	nvoices = search_zones(sflist, notep, vel, preset, bank, table, max_layers, 0);
+	nvoices = search_zones(sflist, notep, vel, preset, bank,
+			       table, max_layers, 0);
 	if (! nvoices) {
 		if (preset != def_preset || bank != def_bank)
-			nvoices = search_zones(sflist, notep, vel, def_preset, def_bank, table, max_layers, 0);
+			nvoices = search_zones(sflist, notep, vel,
+					       def_preset, def_bank,
+					       table, max_layers, 0);
 	}
 	spin_unlock_irqrestore(&sflist->lock, flags);
 	return nvoices;
@@ -1230,11 +1252,11 @@
 /*
  * search the first matching zone
  */
-static snd_sf_zone_t *
-search_first_zone(snd_sf_list_t *sflist, int bank, int preset, int key)
+static struct snd_sf_zone *
+search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
 {
 	int index;
-	snd_sf_zone_t *zp;
+	struct snd_sf_zone *zp;
 
 	if ((index = get_index(bank, preset, key)) < 0)
 		return NULL;
@@ -1250,9 +1272,11 @@
  * search matching zones from sflist.  can be called recursively.
  */
 static int
-search_zones(snd_sf_list_t *sflist, int *notep, int vel, int preset, int bank, snd_sf_zone_t **table, int max_layers, int level)
+search_zones(struct snd_sf_list *sflist, int *notep, int vel,
+	     int preset, int bank, struct snd_sf_zone **table,
+	     int max_layers, int level)
 {
-	snd_sf_zone_t *zp;
+	struct snd_sf_zone *zp;
 	int nvoices;
 
 	zp = search_first_zone(sflist, bank, preset, *notep);
@@ -1310,7 +1334,7 @@
  * Initialise the sflist structure.
  */
 static void
-snd_sf_init(snd_sf_list_t *sflist)
+snd_sf_init(struct snd_sf_list *sflist)
 {
 	memset(sflist->presets, 0, sizeof(sflist->presets));
 
@@ -1329,11 +1353,11 @@
  * Release all list records
  */
 static void
-snd_sf_clear(snd_sf_list_t *sflist)
+snd_sf_clear(struct snd_sf_list *sflist)
 {
-	snd_soundfont_t *sf, *nextsf;
-	snd_sf_zone_t *zp, *nextzp;
-	snd_sf_sample_t *sp, *nextsp;
+	struct snd_soundfont *sf, *nextsf;
+	struct snd_sf_zone *zp, *nextzp;
+	struct snd_sf_sample *sp, *nextsp;
 
 	for (sf = sflist->fonts; sf; sf = nextsf) {
 		nextsf = sf->next;
@@ -1344,7 +1368,8 @@
 		for (sp = sf->samples; sp; sp = nextsp) {
 			nextsp = sp->next;
 			if (sflist->callback.sample_free)
-				sflist->callback.sample_free(sflist->callback.private_data, sp, sflist->memhdr);
+				sflist->callback.sample_free(sflist->callback.private_data,
+							     sp, sflist->memhdr);
 			kfree(sp);
 		}
 		kfree(sf);
@@ -1357,10 +1382,10 @@
 /*
  * Create a new sflist structure
  */
-snd_sf_list_t *
-snd_sf_new(snd_sf_callback_t *callback, snd_util_memhdr_t *hdr)
+struct snd_sf_list *
+snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
 {
-	snd_sf_list_t *sflist;
+	struct snd_sf_list *sflist;
 
 	if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
 		return NULL;
@@ -1381,7 +1406,7 @@
  * Free everything allocated off the sflist structure.
  */
 void
-snd_sf_free(snd_sf_list_t *sflist)
+snd_sf_free(struct snd_sf_list *sflist)
 {
 	if (sflist == NULL)
 		return;
@@ -1400,7 +1425,7 @@
  * The soundcard should be silet before calling this function.
  */
 int
-snd_soundfont_remove_samples(snd_sf_list_t *sflist)
+snd_soundfont_remove_samples(struct snd_sf_list *sflist)
 {
 	lock_preset(sflist);
 	if (sflist->callback.sample_reset)
@@ -1416,11 +1441,11 @@
  * The soundcard should be silent before calling this function.
  */
 int
-snd_soundfont_remove_unlocked(snd_sf_list_t *sflist)
+snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
 {
-	snd_soundfont_t *sf;
-	snd_sf_zone_t *zp, *nextzp;
-	snd_sf_sample_t *sp, *nextsp;
+	struct snd_soundfont *sf;
+	struct snd_sf_zone *zp, *nextzp;
+	struct snd_sf_sample *sp, *nextsp;
 
 	lock_preset(sflist);
 
@@ -1446,7 +1471,8 @@
 			sf->samples = nextsp;
 			sflist->mem_used -= sp->v.truesize;
 			if (sflist->callback.sample_free)
-				sflist->callback.sample_free(sflist->callback.private_data, sp, sflist->memhdr);
+				sflist->callback.sample_free(sflist->callback.private_data,
+							     sp, sflist->memhdr);
 			kfree(sp);
 		}
 	}
diff --git a/sound/synth/util_mem.c b/sound/synth/util_mem.c
index 5f75bf3..217e8e5 100644
--- a/sound/synth/util_mem.c
+++ b/sound/synth/util_mem.c
@@ -28,15 +28,15 @@
 MODULE_DESCRIPTION("Generic memory management routines for soundcard memory allocation");
 MODULE_LICENSE("GPL");
 
-#define get_memblk(p)	list_entry(p, snd_util_memblk_t, list)
+#define get_memblk(p)	list_entry(p, struct snd_util_memblk, list)
 
 /*
  * create a new memory manager
  */
-snd_util_memhdr_t *
+struct snd_util_memhdr *
 snd_util_memhdr_new(int memsize)
 {
-	snd_util_memhdr_t *hdr;
+	struct snd_util_memhdr *hdr;
 
 	hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
 	if (hdr == NULL)
@@ -51,7 +51,7 @@
 /*
  * free a memory manager
  */
-void snd_util_memhdr_free(snd_util_memhdr_t *hdr)
+void snd_util_memhdr_free(struct snd_util_memhdr *hdr)
 {
 	struct list_head *p;
 
@@ -67,11 +67,11 @@
 /*
  * allocate a memory block (without mutex)
  */
-snd_util_memblk_t *
-__snd_util_mem_alloc(snd_util_memhdr_t *hdr, int size)
+struct snd_util_memblk *
+__snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
 {
-	snd_util_memblk_t *blk;
-	snd_util_unit_t units, prev_offset;
+	struct snd_util_memblk *blk;
+	unsigned int units, prev_offset;
 	struct list_head *p;
 
 	snd_assert(hdr != NULL, return NULL);
@@ -104,20 +104,21 @@
  * create a new memory block with the given size
  * the block is linked next to prev
  */
-snd_util_memblk_t *
-__snd_util_memblk_new(snd_util_memhdr_t *hdr, snd_util_unit_t units,
+struct snd_util_memblk *
+__snd_util_memblk_new(struct snd_util_memhdr *hdr, unsigned int units,
 		      struct list_head *prev)
 {
-	snd_util_memblk_t *blk;
+	struct snd_util_memblk *blk;
 
-	blk = kmalloc(sizeof(snd_util_memblk_t) + hdr->block_extra_size, GFP_KERNEL);
+	blk = kmalloc(sizeof(struct snd_util_memblk) + hdr->block_extra_size,
+		      GFP_KERNEL);
 	if (blk == NULL)
 		return NULL;
 
 	if (! prev || prev == &hdr->block)
 		blk->offset = 0;
 	else {
-		snd_util_memblk_t *p = get_memblk(prev);
+		struct snd_util_memblk *p = get_memblk(prev);
 		blk->offset = p->offset + p->size;
 	}
 	blk->size = units;
@@ -131,10 +132,10 @@
 /*
  * allocate a memory block (with mutex)
  */
-snd_util_memblk_t *
-snd_util_mem_alloc(snd_util_memhdr_t *hdr, int size)
+struct snd_util_memblk *
+snd_util_mem_alloc(struct snd_util_memhdr *hdr, int size)
 {
-	snd_util_memblk_t *blk;
+	struct snd_util_memblk *blk;
 	down(&hdr->block_mutex);
 	blk = __snd_util_mem_alloc(hdr, size);
 	up(&hdr->block_mutex);
@@ -147,7 +148,7 @@
  * (without mutex)
  */
 void
-__snd_util_mem_free(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk)
+__snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
 {
 	list_del(&blk->list);
 	hdr->nblocks--;
@@ -158,7 +159,7 @@
 /*
  * free a memory block (with mutex)
  */
-int snd_util_mem_free(snd_util_memhdr_t *hdr, snd_util_memblk_t *blk)
+int snd_util_mem_free(struct snd_util_memhdr *hdr, struct snd_util_memblk *blk)
 {
 	snd_assert(hdr && blk, return -EINVAL);
 
@@ -171,7 +172,7 @@
 /*
  * return available memory size
  */
-int snd_util_mem_avail(snd_util_memhdr_t *hdr)
+int snd_util_mem_avail(struct snd_util_memhdr *hdr)
 {
 	unsigned int size;
 	down(&hdr->block_mutex);
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 99dae02..a1bd804 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -102,10 +102,6 @@
 #define SYNC_URBS	4	/* always four urbs for sync */
 #define MIN_PACKS_URB	1	/* minimum 1 packet per urb */
 
-typedef struct snd_usb_substream snd_usb_substream_t;
-typedef struct snd_usb_stream snd_usb_stream_t;
-typedef struct snd_urb_ctx snd_urb_ctx_t;
-
 struct audioformat {
 	struct list_head list;
 	snd_pcm_format_t format;	/* format type */
@@ -125,25 +121,27 @@
 	unsigned int *rate_table;	/* rate table */
 };
 
+struct snd_usb_substream;
+
 struct snd_urb_ctx {
 	struct urb *urb;
 	unsigned int buffer_size;	/* size of data buffer, if data URB */
-	snd_usb_substream_t *subs;
+	struct snd_usb_substream *subs;
 	int index;	/* index for urb array */
 	int packets;	/* number of packets per urb */
 };
 
 struct snd_urb_ops {
-	int (*prepare)(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime, struct urb *u);
-	int (*retire)(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime, struct urb *u);
-	int (*prepare_sync)(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime, struct urb *u);
-	int (*retire_sync)(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime, struct urb *u);
+	int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
+	int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
+	int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
+	int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u);
 };
 
 struct snd_usb_substream {
-	snd_usb_stream_t *stream;
+	struct snd_usb_stream *stream;
 	struct usb_device *dev;
-	snd_pcm_substream_t *pcm_substream;
+	struct snd_pcm_substream *pcm_substream;
 	int direction;	/* playback or capture */
 	int interface;	/* current interface */
 	int endpoint;	/* assigned endpoint */
@@ -175,8 +173,8 @@
 	unsigned long unlink_mask;	/* bitmask of unlinked urbs */
 
 	unsigned int nurbs;			/* # urbs */
-	snd_urb_ctx_t dataurb[MAX_URBS];	/* data urb table */
-	snd_urb_ctx_t syncurb[SYNC_URBS];	/* sync urb table */
+	struct snd_urb_ctx dataurb[MAX_URBS];	/* data urb table */
+	struct snd_urb_ctx syncurb[SYNC_URBS];	/* sync urb table */
 	char *syncbuf;				/* sync buffer for all sync URBs */
 	dma_addr_t sync_dma;			/* DMA address of syncbuf */
 
@@ -190,11 +188,11 @@
 
 
 struct snd_usb_stream {
-	snd_usb_audio_t *chip;
-	snd_pcm_t *pcm;
+	struct snd_usb_audio *chip;
+	struct snd_pcm *pcm;
 	int pcm_index;
 	unsigned int fmt_type;		/* USB audio format type (1-3) */
-	snd_usb_substream_t substream[2];
+	struct snd_usb_substream substream[2];
 	struct list_head list;
 };
 
@@ -205,7 +203,7 @@
  */
 
 static DECLARE_MUTEX(register_mutex);
-static snd_usb_audio_t *usb_chip[SNDRV_CARDS];
+static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
 
 
 /*
@@ -245,12 +243,12 @@
  * fill the length and offset of each urb descriptor.
  * the fixed 10.14 frequency is passed through the pipe.
  */
-static int prepare_capture_sync_urb(snd_usb_substream_t *subs,
-				    snd_pcm_runtime_t *runtime,
+static int prepare_capture_sync_urb(struct snd_usb_substream *subs,
+				    struct snd_pcm_runtime *runtime,
 				    struct urb *urb)
 {
 	unsigned char *cp = urb->transfer_buffer;
-	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
+	struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
 
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
 	urb->iso_frame_desc[0].length = 3;
@@ -267,12 +265,12 @@
  * fill the length and offset of each urb descriptor.
  * the fixed 12.13 frequency is passed as 16.16 through the pipe.
  */
-static int prepare_capture_sync_urb_hs(snd_usb_substream_t *subs,
-				       snd_pcm_runtime_t *runtime,
+static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs,
+				       struct snd_pcm_runtime *runtime,
 				       struct urb *urb)
 {
 	unsigned char *cp = urb->transfer_buffer;
-	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
+	struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
 
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
 	urb->iso_frame_desc[0].length = 4;
@@ -288,8 +286,8 @@
  * process after capture sync complete
  * - nothing to do
  */
-static int retire_capture_sync_urb(snd_usb_substream_t *subs,
-				   snd_pcm_runtime_t *runtime,
+static int retire_capture_sync_urb(struct snd_usb_substream *subs,
+				   struct snd_pcm_runtime *runtime,
 				   struct urb *urb)
 {
 	return 0;
@@ -305,12 +303,12 @@
  * write onto the pcm buffer directly...  the data is thus copied
  * later at complete callback to the global buffer.
  */
-static int prepare_capture_urb(snd_usb_substream_t *subs,
-			       snd_pcm_runtime_t *runtime,
+static int prepare_capture_urb(struct snd_usb_substream *subs,
+			       struct snd_pcm_runtime *runtime,
 			       struct urb *urb)
 {
 	int i, offs;
-	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
+	struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
 
 	offs = 0;
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
@@ -340,8 +338,8 @@
  * copy the data from each desctiptor to the pcm buffer, and
  * update the current position.
  */
-static int retire_capture_urb(snd_usb_substream_t *subs,
-			      snd_pcm_runtime_t *runtime,
+static int retire_capture_urb(struct snd_usb_substream *subs,
+			      struct snd_pcm_runtime *runtime,
 			      struct urb *urb)
 {
 	unsigned long flags;
@@ -395,11 +393,11 @@
  * set up the offset and length to receive the current frequency.
  */
 
-static int prepare_playback_sync_urb(snd_usb_substream_t *subs,
-				     snd_pcm_runtime_t *runtime,
+static int prepare_playback_sync_urb(struct snd_usb_substream *subs,
+				     struct snd_pcm_runtime *runtime,
 				     struct urb *urb)
 {
-	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
+	struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
 
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
 	urb->iso_frame_desc[0].length = 3;
@@ -413,11 +411,11 @@
  * set up the offset and length to receive the current frequency.
  */
 
-static int prepare_playback_sync_urb_hs(snd_usb_substream_t *subs,
-					snd_pcm_runtime_t *runtime,
+static int prepare_playback_sync_urb_hs(struct snd_usb_substream *subs,
+					struct snd_pcm_runtime *runtime,
 					struct urb *urb)
 {
-	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
+	struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
 
 	urb->dev = ctx->subs->dev; /* we need to set this at each time */
 	urb->iso_frame_desc[0].length = 4;
@@ -431,8 +429,8 @@
  * retrieve the current 10.14 frequency from pipe, and set it.
  * the value is referred in prepare_playback_urb().
  */
-static int retire_playback_sync_urb(snd_usb_substream_t *subs,
-				    snd_pcm_runtime_t *runtime,
+static int retire_playback_sync_urb(struct snd_usb_substream *subs,
+				    struct snd_pcm_runtime *runtime,
 				    struct urb *urb)
 {
 	unsigned int f;
@@ -457,8 +455,8 @@
  * retrieve the current 12.13 frequency from pipe, and set it.
  * the value is referred in prepare_playback_urb().
  */
-static int retire_playback_sync_urb_hs(snd_usb_substream_t *subs,
-				       snd_pcm_runtime_t *runtime,
+static int retire_playback_sync_urb_hs(struct snd_usb_substream *subs,
+				       struct snd_pcm_runtime *runtime,
 				       struct urb *urb)
 {
 	unsigned int f;
@@ -482,12 +480,12 @@
  *
  * We don't care about (or have) any data, so we just send a transfer delimiter.
  */
-static int prepare_startup_playback_urb(snd_usb_substream_t *subs,
-					snd_pcm_runtime_t *runtime,
+static int prepare_startup_playback_urb(struct snd_usb_substream *subs,
+					struct snd_pcm_runtime *runtime,
 					struct urb *urb)
 {
 	unsigned int i;
-	snd_urb_ctx_t *ctx = urb->context;
+	struct snd_urb_ctx *ctx = urb->context;
 
 	urb->dev = ctx->subs->dev;
 	urb->number_of_packets = subs->packs_per_ms;
@@ -507,15 +505,15 @@
  * To avoid inconsistencies when updating hwptr_done, we use double buffering
  * for all URBs.
  */
-static int prepare_playback_urb(snd_usb_substream_t *subs,
-				snd_pcm_runtime_t *runtime,
+static int prepare_playback_urb(struct snd_usb_substream *subs,
+				struct snd_pcm_runtime *runtime,
 				struct urb *urb)
 {
 	int i, stride, offs;
 	unsigned int counts;
 	unsigned long flags;
 	int period_elapsed = 0;
-	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
+	struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
 
 	stride = runtime->frame_bits >> 3;
 
@@ -597,8 +595,8 @@
  * process after playback data complete
  * - nothing to do
  */
-static int retire_playback_urb(snd_usb_substream_t *subs,
-			       snd_pcm_runtime_t *runtime,
+static int retire_playback_urb(struct snd_usb_substream *subs,
+			       struct snd_pcm_runtime *runtime,
 			       struct urb *urb)
 {
 	return 0;
@@ -642,9 +640,9 @@
  */
 static void snd_complete_urb(struct urb *urb, struct pt_regs *regs)
 {
-	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
-	snd_usb_substream_t *subs = ctx->subs;
-	snd_pcm_substream_t *substream = ctx->subs->pcm_substream;
+	struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
+	struct snd_usb_substream *subs = ctx->subs;
+	struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
 	int err = 0;
 
 	if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) ||
@@ -665,9 +663,9 @@
  */
 static void snd_complete_sync_urb(struct urb *urb, struct pt_regs *regs)
 {
-	snd_urb_ctx_t *ctx = (snd_urb_ctx_t *)urb->context;
-	snd_usb_substream_t *subs = ctx->subs;
-	snd_pcm_substream_t *substream = ctx->subs->pcm_substream;
+	struct snd_urb_ctx *ctx = (struct snd_urb_ctx *)urb->context;
+	struct snd_usb_substream *subs = ctx->subs;
+	struct snd_pcm_substream *substream = ctx->subs->pcm_substream;
 	int err = 0;
 
 	if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) ||
@@ -684,7 +682,7 @@
 
 
 /* get the physical page pointer at the given offset */
-static struct page *snd_pcm_get_vmalloc_page(snd_pcm_substream_t *subs,
+static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
 					     unsigned long offset)
 {
 	void *pageptr = subs->runtime->dma_area + offset;
@@ -692,9 +690,9 @@
 }
 
 /* allocate virtual buffer; may be called more than once */
-static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size)
+static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	if (runtime->dma_area) {
 		if (runtime->dma_bytes >= size)
 			return 0; /* already large enough */
@@ -708,9 +706,9 @@
 }
 
 /* free virtual buffer; may be called more than once */
-static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs)
+static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
 {
-	snd_pcm_runtime_t *runtime = subs->runtime;
+	struct snd_pcm_runtime *runtime = subs->runtime;
 	if (runtime->dma_area) {
 		vfree(runtime->dma_area);
 		runtime->dma_area = NULL;
@@ -722,7 +720,7 @@
 /*
  * unlink active urbs.
  */
-static int deactivate_urbs(snd_usb_substream_t *subs, int force, int can_sleep)
+static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep)
 {
 	unsigned int i;
 	int async;
@@ -768,7 +766,7 @@
 /*
  * set up and start data/sync urbs
  */
-static int start_urbs(snd_usb_substream_t *subs, snd_pcm_runtime_t *runtime)
+static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime)
 {
 	unsigned int i;
 	int err;
@@ -824,7 +822,7 @@
 /*
  *  wait until all urbs are processed.
  */
-static int wait_clear_urbs(snd_usb_substream_t *subs)
+static int wait_clear_urbs(struct snd_usb_substream *subs)
 {
 	unsigned long end_time = jiffies + msecs_to_jiffies(1000);
 	unsigned int i;
@@ -855,12 +853,12 @@
 /*
  * return the current pcm pointer.  just return the hwptr_done value.
  */
-static snd_pcm_uframes_t snd_usb_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	snd_usb_substream_t *subs;
+	struct snd_usb_substream *subs;
 	snd_pcm_uframes_t hwptr_done;
 	
-	subs = (snd_usb_substream_t *)substream->runtime->private_data;
+	subs = (struct snd_usb_substream *)substream->runtime->private_data;
 	spin_lock(&subs->lock);
 	hwptr_done = subs->hwptr_done;
 	spin_unlock(&subs->lock);
@@ -871,10 +869,10 @@
 /*
  * start/stop playback substream
  */
-static int snd_usb_pcm_playback_trigger(snd_pcm_substream_t *substream,
+static int snd_usb_pcm_playback_trigger(struct snd_pcm_substream *substream,
 					int cmd)
 {
-	snd_usb_substream_t *subs = substream->runtime->private_data;
+	struct snd_usb_substream *subs = substream->runtime->private_data;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -890,10 +888,10 @@
 /*
  * start/stop capture substream
  */
-static int snd_usb_pcm_capture_trigger(snd_pcm_substream_t *substream,
+static int snd_usb_pcm_capture_trigger(struct snd_pcm_substream *substream,
 				       int cmd)
 {
-	snd_usb_substream_t *subs = substream->runtime->private_data;
+	struct snd_usb_substream *subs = substream->runtime->private_data;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -909,7 +907,7 @@
 /*
  * release a urb data
  */
-static void release_urb_ctx(snd_urb_ctx_t *u)
+static void release_urb_ctx(struct snd_urb_ctx *u)
 {
 	if (u->urb) {
 		if (u->buffer_size)
@@ -924,7 +922,7 @@
 /*
  * release a substream
  */
-static void release_substream_urbs(snd_usb_substream_t *subs, int force)
+static void release_substream_urbs(struct snd_usb_substream *subs, int force)
 {
 	int i;
 
@@ -945,7 +943,7 @@
 /*
  * initialize a substream for plaback/capture
  */
-static int init_substream_urbs(snd_usb_substream_t *subs, unsigned int period_bytes,
+static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int period_bytes,
 			       unsigned int rate, unsigned int frame_bits)
 {
 	unsigned int maxsize, n, i;
@@ -1045,7 +1043,7 @@
 
 	/* allocate and initialize data urbs */
 	for (i = 0; i < subs->nurbs; i++) {
-		snd_urb_ctx_t *u = &subs->dataurb[i];
+		struct snd_urb_ctx *u = &subs->dataurb[i];
 		u->index = i;
 		u->subs = subs;
 		u->packets = npacks[i];
@@ -1074,7 +1072,7 @@
 		if (! subs->syncbuf)
 			goto out_of_memory;
 		for (i = 0; i < SYNC_URBS; i++) {
-			snd_urb_ctx_t *u = &subs->syncurb[i];
+			struct snd_urb_ctx *u = &subs->syncurb[i];
 			u->index = i;
 			u->subs = subs;
 			u->packets = 1;
@@ -1104,7 +1102,7 @@
 /*
  * find a matching audio format
  */
-static struct audioformat *find_format(snd_usb_substream_t *subs, unsigned int format,
+static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
 				       unsigned int rate, unsigned int channels)
 {
 	struct list_head *p;
@@ -1229,7 +1227,7 @@
 /*
  * find a matching format and set up the interface
  */
-static int set_format(snd_usb_substream_t *subs, struct audioformat *fmt)
+static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
 {
 	struct usb_device *dev = subs->dev;
 	struct usb_host_interface *alts;
@@ -1358,10 +1356,10 @@
  * if sg buffer is supported on the later version of alsa, we'll follow
  * that.
  */
-static int snd_usb_hw_params(snd_pcm_substream_t *substream,
-			     snd_pcm_hw_params_t *hw_params)
+static int snd_usb_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *hw_params)
 {
-	snd_usb_substream_t *subs = (snd_usb_substream_t *)substream->runtime->private_data;
+	struct snd_usb_substream *subs = (struct snd_usb_substream *)substream->runtime->private_data;
 	struct audioformat *fmt;
 	unsigned int channels, rate, format;
 	int ret, changed;
@@ -1415,9 +1413,9 @@
  *
  * reset the audio format and release the buffer
  */
-static int snd_usb_hw_free(snd_pcm_substream_t *substream)
+static int snd_usb_hw_free(struct snd_pcm_substream *substream)
 {
-	snd_usb_substream_t *subs = (snd_usb_substream_t *)substream->runtime->private_data;
+	struct snd_usb_substream *subs = (struct snd_usb_substream *)substream->runtime->private_data;
 
 	subs->cur_audiofmt = NULL;
 	subs->cur_rate = 0;
@@ -1431,10 +1429,10 @@
  *
  * only a few subtle things...
  */
-static int snd_usb_pcm_prepare(snd_pcm_substream_t *substream)
+static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usb_substream_t *subs = runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_usb_substream *subs = runtime->private_data;
 
 	if (! subs->cur_audiofmt) {
 		snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
@@ -1463,7 +1461,7 @@
 		return 0;
 }
 
-static snd_pcm_hardware_t snd_usb_playback =
+static struct snd_pcm_hardware snd_usb_playback =
 {
 	.info =			SNDRV_PCM_INFO_MMAP |
 				SNDRV_PCM_INFO_MMAP_VALID |
@@ -1477,7 +1475,7 @@
 	.periods_max =		1024,
 };
 
-static snd_pcm_hardware_t snd_usb_capture =
+static struct snd_pcm_hardware snd_usb_capture =
 {
 	.info =			SNDRV_PCM_INFO_MMAP |
 				SNDRV_PCM_INFO_MMAP_VALID |
@@ -1501,11 +1499,11 @@
 #define hwc_debug(fmt, args...) /**/
 #endif
 
-static int hw_check_valid_format(snd_pcm_hw_params_t *params, struct audioformat *fp)
+static int hw_check_valid_format(struct snd_pcm_hw_params *params, struct audioformat *fp)
 {
-	snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
-	snd_interval_t *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
-	snd_mask_t *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval *ct = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_mask *fmts = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 
 	/* check the format */
 	if (! snd_mask_test(fmts, fp->format)) {
@@ -1529,12 +1527,12 @@
 	return 1;
 }
 
-static int hw_rule_rate(snd_pcm_hw_params_t *params,
-			snd_pcm_hw_rule_t *rule)
+static int hw_rule_rate(struct snd_pcm_hw_params *params,
+			struct snd_pcm_hw_rule *rule)
 {
-	snd_usb_substream_t *subs = rule->private;
+	struct snd_usb_substream *subs = rule->private;
 	struct list_head *p;
-	snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
+	struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE);
 	unsigned int rmin, rmax;
 	int changed;
 
@@ -1583,12 +1581,12 @@
 }
 
 
-static int hw_rule_channels(snd_pcm_hw_params_t *params,
-			    snd_pcm_hw_rule_t *rule)
+static int hw_rule_channels(struct snd_pcm_hw_params *params,
+			    struct snd_pcm_hw_rule *rule)
 {
-	snd_usb_substream_t *subs = rule->private;
+	struct snd_usb_substream *subs = rule->private;
 	struct list_head *p;
-	snd_interval_t *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
+	struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
 	unsigned int rmin, rmax;
 	int changed;
 
@@ -1636,12 +1634,12 @@
 	return changed;
 }
 
-static int hw_rule_format(snd_pcm_hw_params_t *params,
-			  snd_pcm_hw_rule_t *rule)
+static int hw_rule_format(struct snd_pcm_hw_params *params,
+			  struct snd_pcm_hw_rule *rule)
 {
-	snd_usb_substream_t *subs = rule->private;
+	struct snd_usb_substream *subs = rule->private;
 	struct list_head *p;
-	snd_mask_t *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
+	struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
 	u64 fbits;
 	u32 oldbits[2];
 	int changed;
@@ -1674,7 +1672,7 @@
 /*
  * check whether the registered audio formats need special hw-constraints
  */
-static int check_hw_params_convention(snd_usb_substream_t *subs)
+static int check_hw_params_convention(struct snd_usb_substream *subs)
 {
 	int i;
 	u32 *channels;
@@ -1758,7 +1756,7 @@
  * set up the runtime hardware information.
  */
 
-static int setup_hw_info(snd_pcm_runtime_t *runtime, snd_usb_substream_t *subs)
+static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substream *subs)
 {
 	struct list_head *p;
 	int err;
@@ -1819,12 +1817,12 @@
 	return 0;
 }
 
-static int snd_usb_pcm_open(snd_pcm_substream_t *substream, int direction,
-			    snd_pcm_hardware_t *hw)
+static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction,
+			    struct snd_pcm_hardware *hw)
 {
-	snd_usb_stream_t *as = snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usb_substream_t *subs = &as->substream[direction];
+	struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_usb_substream *subs = &as->substream[direction];
 
 	subs->interface = -1;
 	subs->format = 0;
@@ -1834,10 +1832,10 @@
 	return setup_hw_info(runtime, subs);
 }
 
-static int snd_usb_pcm_close(snd_pcm_substream_t *substream, int direction)
+static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction)
 {
-	snd_usb_stream_t *as = snd_pcm_substream_chip(substream);
-	snd_usb_substream_t *subs = &as->substream[direction];
+	struct snd_usb_stream *as = snd_pcm_substream_chip(substream);
+	struct snd_usb_substream *subs = &as->substream[direction];
 
 	if (subs->interface >= 0) {
 		usb_set_interface(subs->dev, subs->interface, 0);
@@ -1847,27 +1845,27 @@
 	return 0;
 }
 
-static int snd_usb_playback_open(snd_pcm_substream_t *substream)
+static int snd_usb_playback_open(struct snd_pcm_substream *substream)
 {
 	return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK, &snd_usb_playback);
 }
 
-static int snd_usb_playback_close(snd_pcm_substream_t *substream)
+static int snd_usb_playback_close(struct snd_pcm_substream *substream)
 {
 	return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_PLAYBACK);
 }
 
-static int snd_usb_capture_open(snd_pcm_substream_t *substream)
+static int snd_usb_capture_open(struct snd_pcm_substream *substream)
 {
 	return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_CAPTURE, &snd_usb_capture);
 }
 
-static int snd_usb_capture_close(snd_pcm_substream_t *substream)
+static int snd_usb_capture_close(struct snd_pcm_substream *substream)
 {
 	return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE);
 }
 
-static snd_pcm_ops_t snd_usb_playback_ops = {
+static struct snd_pcm_ops snd_usb_playback_ops = {
 	.open =		snd_usb_playback_open,
 	.close =	snd_usb_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1879,7 +1877,7 @@
 	.page =		snd_pcm_get_vmalloc_page,
 };
 
-static snd_pcm_ops_t snd_usb_capture_ops = {
+static struct snd_pcm_ops snd_usb_capture_ops = {
 	.open =		snd_usb_capture_open,
 	.close =	snd_usb_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
@@ -1996,7 +1994,6 @@
 MODULE_DEVICE_TABLE (usb, usb_audio_ids);
 
 static struct usb_driver usb_audio_driver = {
-	.owner =	THIS_MODULE,
 	.name =		"snd-usb-audio",
 	.probe =	usb_audio_probe,
 	.disconnect =	usb_audio_disconnect,
@@ -2007,7 +2004,7 @@
 /*
  * proc interface for list the supported pcm formats
  */
-static void proc_dump_substream_formats(snd_usb_substream_t *subs, snd_info_buffer_t *buffer)
+static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
 {
 	struct list_head *p;
 	static char *sync_types[4] = {
@@ -2043,7 +2040,7 @@
 	}
 }
 
-static void proc_dump_substream_status(snd_usb_substream_t *subs, snd_info_buffer_t *buffer)
+static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
 {
 	if (subs->running) {
 		unsigned int i;
@@ -2065,9 +2062,9 @@
 	}
 }
 
-static void proc_pcm_format_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	snd_usb_stream_t *stream = entry->private_data;
+	struct snd_usb_stream *stream = entry->private_data;
 
 	snd_iprintf(buffer, "%s : %s\n", stream->chip->card->longname, stream->pcm->name);
 
@@ -2083,11 +2080,11 @@
 	}
 }
 
-static void proc_pcm_format_add(snd_usb_stream_t *stream)
+static void proc_pcm_format_add(struct snd_usb_stream *stream)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	char name[32];
-	snd_card_t *card = stream->chip->card;
+	struct snd_card *card = stream->chip->card;
 
 	sprintf(name, "stream%d", stream->pcm_index);
 	if (! snd_card_proc_new(card, name, &entry))
@@ -2099,9 +2096,9 @@
  * initialize the substream instance.
  */
 
-static void init_substream(snd_usb_stream_t *as, int stream, struct audioformat *fp)
+static void init_substream(struct snd_usb_stream *as, int stream, struct audioformat *fp)
 {
-	snd_usb_substream_t *subs = &as->substream[stream];
+	struct snd_usb_substream *subs = &as->substream[stream];
 
 	INIT_LIST_HEAD(&subs->fmt_list);
 	spin_lock_init(&subs->lock);
@@ -2128,7 +2125,7 @@
 /*
  * free a substream
  */
-static void free_substream(snd_usb_substream_t *subs)
+static void free_substream(struct snd_usb_substream *subs)
 {
 	struct list_head *p, *n;
 
@@ -2145,7 +2142,7 @@
 /*
  * free a usb stream instance
  */
-static void snd_usb_audio_stream_free(snd_usb_stream_t *stream)
+static void snd_usb_audio_stream_free(struct snd_usb_stream *stream)
 {
 	free_substream(&stream->substream[0]);
 	free_substream(&stream->substream[1]);
@@ -2153,9 +2150,9 @@
 	kfree(stream);
 }
 
-static void snd_usb_audio_pcm_free(snd_pcm_t *pcm)
+static void snd_usb_audio_pcm_free(struct snd_pcm *pcm)
 {
-	snd_usb_stream_t *stream = pcm->private_data;
+	struct snd_usb_stream *stream = pcm->private_data;
 	if (stream) {
 		stream->pcm = NULL;
 		snd_usb_audio_stream_free(stream);
@@ -2168,16 +2165,16 @@
  * if a stream with the same endpoint already exists, append to it.
  * if not, create a new pcm stream.
  */
-static int add_audio_endpoint(snd_usb_audio_t *chip, int stream, struct audioformat *fp)
+static int add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp)
 {
 	struct list_head *p;
-	snd_usb_stream_t *as;
-	snd_usb_substream_t *subs;
-	snd_pcm_t *pcm;
+	struct snd_usb_stream *as;
+	struct snd_usb_substream *subs;
+	struct snd_pcm *pcm;
 	int err;
 
 	list_for_each(p, &chip->pcm_list) {
-		as = list_entry(p, snd_usb_stream_t, list);
+		as = list_entry(p, struct snd_usb_stream, list);
 		if (as->fmt_type != fp->fmt_type)
 			continue;
 		subs = &as->substream[stream];
@@ -2192,7 +2189,7 @@
 	}
 	/* look for an empty stream */
 	list_for_each(p, &chip->pcm_list) {
-		as = list_entry(p, snd_usb_stream_t, list);
+		as = list_entry(p, struct snd_usb_stream, list);
 		if (as->fmt_type != fp->fmt_type)
 			continue;
 		subs = &as->substream[stream];
@@ -2244,7 +2241,7 @@
 /*
  * check if the device uses big-endian samples
  */
-static int is_big_endian_format(snd_usb_audio_t *chip, struct audioformat *fp)
+static int is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
 {
 	switch (chip->usb_id) {
 	case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
@@ -2266,7 +2263,7 @@
  * @format: the format tag (wFormatTag)
  * @fmt: the format type descriptor
  */
-static int parse_audio_format_i_type(snd_usb_audio_t *chip, struct audioformat *fp,
+static int parse_audio_format_i_type(struct snd_usb_audio *chip, struct audioformat *fp,
 				     int format, unsigned char *fmt)
 {
 	int pcm_format;
@@ -2349,7 +2346,7 @@
  * @offset: the start offset of descriptor pointing the rate type
  *          (7 for type I and II, 8 for type II)
  */
-static int parse_audio_format_rates(snd_usb_audio_t *chip, struct audioformat *fp,
+static int parse_audio_format_rates(struct snd_usb_audio *chip, struct audioformat *fp,
 				    unsigned char *fmt, int offset)
 {
 	int nr_rates = fmt[offset];
@@ -2402,7 +2399,7 @@
 /*
  * parse the format type I and III descriptors
  */
-static int parse_audio_format_i(snd_usb_audio_t *chip, struct audioformat *fp,
+static int parse_audio_format_i(struct snd_usb_audio *chip, struct audioformat *fp,
 				int format, unsigned char *fmt)
 {
 	int pcm_format;
@@ -2431,7 +2428,7 @@
 /*
  * prase the format type II descriptor
  */
-static int parse_audio_format_ii(snd_usb_audio_t *chip, struct audioformat *fp,
+static int parse_audio_format_ii(struct snd_usb_audio *chip, struct audioformat *fp,
 				 int format, unsigned char *fmt)
 {
 	int brate, framesize;
@@ -2458,7 +2455,7 @@
 	return parse_audio_format_rates(chip, fp, fmt, 8); /* fmt[8..] sample rates */
 }
 
-static int parse_audio_format(snd_usb_audio_t *chip, struct audioformat *fp,
+static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp,
 			      int format, unsigned char *fmt, int stream)
 {
 	int err;
@@ -2495,7 +2492,7 @@
 	return 0;
 }
 
-static int parse_audio_endpoints(snd_usb_audio_t *chip, int iface_no)
+static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
 {
 	struct usb_device *dev;
 	struct usb_interface *iface;
@@ -2646,10 +2643,10 @@
 static void snd_usb_stream_disconnect(struct list_head *head)
 {
 	int idx;
-	snd_usb_stream_t *as;
-	snd_usb_substream_t *subs;
+	struct snd_usb_stream *as;
+	struct snd_usb_substream *subs;
 
-	as = list_entry(head, snd_usb_stream_t, list);
+	as = list_entry(head, struct snd_usb_stream, list);
 	for (idx = 0; idx < 2; idx++) {
 		subs = &as->substream[idx];
 		if (!subs->num_formats)
@@ -2662,7 +2659,7 @@
 /*
  * parse audio control descriptor and create pcm/midi streams
  */
-static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif)
+static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
 {
 	struct usb_device *dev = chip->dev;
 	struct usb_host_interface *host_iface;
@@ -2729,9 +2726,9 @@
 /*
  * create a stream for an endpoint/altsetting without proper descriptors
  */
-static int create_fixed_stream_quirk(snd_usb_audio_t *chip,
+static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 				     struct usb_interface *iface,
-				     const snd_usb_audio_quirk_t *quirk)
+				     const struct snd_usb_audio_quirk *quirk)
 {
 	struct audioformat *fp;
 	struct usb_host_interface *alts;
@@ -2778,9 +2775,9 @@
 /*
  * create a stream for an interface with proper descriptors
  */
-static int create_standard_audio_quirk(snd_usb_audio_t *chip,
+static int create_standard_audio_quirk(struct snd_usb_audio *chip,
 				       struct usb_interface *iface,
-				       const snd_usb_audio_quirk_t *quirk)
+				       const struct snd_usb_audio_quirk *quirk)
 {
 	struct usb_host_interface *alts;
 	struct usb_interface_descriptor *altsd;
@@ -2803,9 +2800,9 @@
  * Create a stream for an Edirol UA-700/UA-25 interface.  The only way
  * to detect the sample rate is by looking at wMaxPacketSize.
  */
-static int create_ua700_ua25_quirk(snd_usb_audio_t *chip,
+static int create_ua700_ua25_quirk(struct snd_usb_audio *chip,
 				   struct usb_interface *iface,
-				   const snd_usb_audio_quirk_t *quirk)
+				   const struct snd_usb_audio_quirk *quirk)
 {
 	static const struct audioformat ua_format = {
 		.format = SNDRV_PCM_FORMAT_S24_3LE,
@@ -2827,19 +2824,19 @@
 	altsd = get_iface_desc(alts);
 
 	if (altsd->bNumEndpoints == 2) {
-		static const snd_usb_midi_endpoint_info_t ua700_ep = {
+		static const struct snd_usb_midi_endpoint_info ua700_ep = {
 			.out_cables = 0x0003,
 			.in_cables  = 0x0003
 		};
-		static const snd_usb_audio_quirk_t ua700_quirk = {
+		static const struct snd_usb_audio_quirk ua700_quirk = {
 			.type = QUIRK_MIDI_FIXED_ENDPOINT,
 			.data = &ua700_ep
 		};
-		static const snd_usb_midi_endpoint_info_t ua25_ep = {
+		static const struct snd_usb_midi_endpoint_info ua25_ep = {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		};
-		static const snd_usb_audio_quirk_t ua25_quirk = {
+		static const struct snd_usb_audio_quirk ua25_quirk = {
 			.type = QUIRK_MIDI_FIXED_ENDPOINT,
 			.data = &ua25_ep
 		};
@@ -2896,9 +2893,9 @@
 /*
  * Create a stream for an Edirol UA-1000 interface.
  */
-static int create_ua1000_quirk(snd_usb_audio_t *chip,
+static int create_ua1000_quirk(struct snd_usb_audio *chip,
 			       struct usb_interface *iface,
-			       const snd_usb_audio_quirk_t *quirk)
+			       const struct snd_usb_audio_quirk *quirk)
 {
 	static const struct audioformat ua1000_format = {
 		.format = SNDRV_PCM_FORMAT_S32_LE,
@@ -2945,16 +2942,16 @@
 	return 0;
 }
 
-static int snd_usb_create_quirk(snd_usb_audio_t *chip,
+static int snd_usb_create_quirk(struct snd_usb_audio *chip,
 				struct usb_interface *iface,
-				const snd_usb_audio_quirk_t *quirk);
+				const struct snd_usb_audio_quirk *quirk);
 
 /*
  * handle the quirks for the contained interfaces
  */
-static int create_composite_quirk(snd_usb_audio_t *chip,
+static int create_composite_quirk(struct snd_usb_audio *chip,
 				  struct usb_interface *iface,
-				  const snd_usb_audio_quirk_t *quirk)
+				  const struct snd_usb_audio_quirk *quirk)
 {
 	int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
 	int err;
@@ -2975,9 +2972,9 @@
 	return 0;
 }
 
-static int ignore_interface_quirk(snd_usb_audio_t *chip,
+static int ignore_interface_quirk(struct snd_usb_audio *chip,
 				  struct usb_interface *iface,
-				  const snd_usb_audio_quirk_t *quirk)
+				  const struct snd_usb_audio_quirk *quirk)
 {
 	return 0;
 }
@@ -3040,12 +3037,12 @@
  * after this.
  * returns a negative value at error.
  */
-static int snd_usb_create_quirk(snd_usb_audio_t *chip,
+static int snd_usb_create_quirk(struct snd_usb_audio *chip,
 				struct usb_interface *iface,
-				const snd_usb_audio_quirk_t *quirk)
+				const struct snd_usb_audio_quirk *quirk)
 {
-	typedef int (*quirk_func_t)(snd_usb_audio_t *, struct usb_interface *,
-				    const snd_usb_audio_quirk_t *);
+	typedef int (*quirk_func_t)(struct snd_usb_audio *, struct usb_interface *,
+				    const struct snd_usb_audio_quirk *);
 	static const quirk_func_t quirk_funcs[] = {
 		[QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
 		[QUIRK_COMPOSITE] = create_composite_quirk,
@@ -3075,25 +3072,25 @@
 /*
  * common proc files to show the usb device info
  */
-static void proc_audio_usbbus_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	snd_usb_audio_t *chip = entry->private_data;
+	struct snd_usb_audio *chip = entry->private_data;
 	if (! chip->shutdown)
 		snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
 }
 
-static void proc_audio_usbid_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
+static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
-	snd_usb_audio_t *chip = entry->private_data;
+	struct snd_usb_audio *chip = entry->private_data;
 	if (! chip->shutdown)
 		snd_iprintf(buffer, "%04x:%04x\n", 
 			    USB_ID_VENDOR(chip->usb_id),
 			    USB_ID_PRODUCT(chip->usb_id));
 }
 
-static void snd_usb_audio_create_proc(snd_usb_audio_t *chip)
+static void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
 {
-	snd_info_entry_t *entry;
+	struct snd_info_entry *entry;
 	if (! snd_card_proc_new(chip->card, "usbbus", &entry))
 		snd_info_set_text_ops(entry, chip, 1024, proc_audio_usbbus_read);
 	if (! snd_card_proc_new(chip->card, "usbid", &entry))
@@ -3107,15 +3104,15 @@
  *
  */
 
-static int snd_usb_audio_free(snd_usb_audio_t *chip)
+static int snd_usb_audio_free(struct snd_usb_audio *chip)
 {
 	kfree(chip);
 	return 0;
 }
 
-static int snd_usb_audio_dev_free(snd_device_t *device)
+static int snd_usb_audio_dev_free(struct snd_device *device)
 {
-	snd_usb_audio_t *chip = device->device_data;
+	struct snd_usb_audio *chip = device->device_data;
 	return snd_usb_audio_free(chip);
 }
 
@@ -3124,14 +3121,14 @@
  * create a chip instance and set its names.
  */
 static int snd_usb_audio_create(struct usb_device *dev, int idx,
-				const snd_usb_audio_quirk_t *quirk,
-				snd_usb_audio_t **rchip)
+				const struct snd_usb_audio_quirk *quirk,
+				struct snd_usb_audio **rchip)
 {
-	snd_card_t *card;
-	snd_usb_audio_t *chip;
+	struct snd_card *card;
+	struct snd_usb_audio *chip;
 	int err, len;
 	char component[14];
-	static snd_device_ops_t ops = {
+	static struct snd_device_ops ops = {
 		.dev_free =	snd_usb_audio_dev_free,
 	};
 
@@ -3235,9 +3232,9 @@
 				 struct usb_interface *intf,
 				 const struct usb_device_id *usb_id)
 {
-	const snd_usb_audio_quirk_t *quirk = (const snd_usb_audio_quirk_t *)usb_id->driver_info;
+	const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
 	int i, err;
-	snd_usb_audio_t *chip;
+	struct snd_usb_audio *chip;
 	struct usb_host_interface *alts;
 	int ifnum;
 	u32 id;
@@ -3338,8 +3335,8 @@
  */
 static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
 {
-	snd_usb_audio_t *chip;
-	snd_card_t *card;
+	struct snd_usb_audio *chip;
+	struct snd_card *card;
 	struct list_head *p;
 
 	if (ptr == (void *)-1L)
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index b580202..ecd724b 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -126,12 +126,10 @@
 /*
  */
 
-typedef struct snd_usb_audio snd_usb_audio_t;
-
 struct snd_usb_audio {
 	int index;
 	struct usb_device *dev;
-	snd_card_t *card;
+	struct snd_card *card;
 	u32 usb_id;
 	int shutdown;
 	int num_interfaces;
@@ -172,9 +170,6 @@
 	QUIRK_TYPE_COUNT
 };
 
-typedef struct snd_usb_audio_quirk snd_usb_audio_quirk_t;
-typedef struct snd_usb_midi_endpoint_info snd_usb_midi_endpoint_info_t;
-
 struct snd_usb_audio_quirk {
 	const char *vendor_name;
 	const char *product_name;
@@ -228,12 +223,15 @@
 void *snd_usb_find_desc(void *descstart, int desclen, void *after, u8 dtype);
 void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsubtype);
 
-int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout);
+int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe,
+		    __u8 request, __u8 requesttype, __u16 value, __u16 index,
+		    void *data, __u16 size, int timeout);
 
-int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif);
+int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif);
 void snd_usb_mixer_disconnect(struct list_head *p);
 
-int snd_usb_create_midi_interface(snd_usb_audio_t *chip, struct usb_interface *iface, const snd_usb_audio_quirk_t *quirk);
+int snd_usb_create_midi_interface(struct snd_usb_audio *chip, struct usb_interface *iface,
+				  const struct snd_usb_audio_quirk *quirk);
 void snd_usbmidi_input_stop(struct list_head* p);
 void snd_usbmidi_input_start(struct list_head* p);
 void snd_usbmidi_disconnect(struct list_head *p);
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index f8aa662..f15b021 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -84,39 +84,36 @@
 	__u8  baAssocJackID[0];
 } __attribute__ ((packed));
 
-typedef struct snd_usb_midi snd_usb_midi_t;
-typedef struct snd_usb_midi_endpoint snd_usb_midi_endpoint_t;
-typedef struct snd_usb_midi_out_endpoint snd_usb_midi_out_endpoint_t;
-typedef struct snd_usb_midi_in_endpoint snd_usb_midi_in_endpoint_t;
-typedef struct usbmidi_out_port usbmidi_out_port_t;
-typedef struct usbmidi_in_port usbmidi_in_port_t;
+struct snd_usb_midi_in_endpoint;
+struct snd_usb_midi_out_endpoint;
+struct snd_usb_midi_endpoint;
 
 struct usb_protocol_ops {
-	void (*input)(snd_usb_midi_in_endpoint_t*, uint8_t*, int);
-	void (*output)(snd_usb_midi_out_endpoint_t*);
+	void (*input)(struct snd_usb_midi_in_endpoint*, uint8_t*, int);
+	void (*output)(struct snd_usb_midi_out_endpoint*);
 	void (*output_packet)(struct urb*, uint8_t, uint8_t, uint8_t, uint8_t);
-	void (*init_out_endpoint)(snd_usb_midi_out_endpoint_t*);
-	void (*finish_out_endpoint)(snd_usb_midi_out_endpoint_t*);
+	void (*init_out_endpoint)(struct snd_usb_midi_out_endpoint*);
+	void (*finish_out_endpoint)(struct snd_usb_midi_out_endpoint*);
 };
 
 struct snd_usb_midi {
-	snd_usb_audio_t *chip;
+	struct snd_usb_audio *chip;
 	struct usb_interface *iface;
-	const snd_usb_audio_quirk_t *quirk;
-	snd_rawmidi_t* rmidi;
+	const struct snd_usb_audio_quirk *quirk;
+	struct snd_rawmidi *rmidi;
 	struct usb_protocol_ops* usb_protocol_ops;
 	struct list_head list;
 	struct timer_list error_timer;
 
 	struct snd_usb_midi_endpoint {
-		snd_usb_midi_out_endpoint_t *out;
-		snd_usb_midi_in_endpoint_t *in;
+		struct snd_usb_midi_out_endpoint *out;
+		struct snd_usb_midi_in_endpoint *in;
 	} endpoints[MIDI_MAX_ENDPOINTS];
 	unsigned long input_triggered;
 };
 
 struct snd_usb_midi_out_endpoint {
-	snd_usb_midi_t* umidi;
+	struct snd_usb_midi* umidi;
 	struct urb* urb;
 	int urb_active;
 	int max_transfer;		/* size of urb buffer */
@@ -125,8 +122,8 @@
 	spinlock_t buffer_lock;
 
 	struct usbmidi_out_port {
-		snd_usb_midi_out_endpoint_t* ep;
-		snd_rawmidi_substream_t* substream;
+		struct snd_usb_midi_out_endpoint* ep;
+		struct snd_rawmidi_substream *substream;
 		int active;
 		uint8_t cable;		/* cable number << 4 */
 		uint8_t state;
@@ -143,17 +140,17 @@
 };
 
 struct snd_usb_midi_in_endpoint {
-	snd_usb_midi_t* umidi;
+	struct snd_usb_midi* umidi;
 	struct urb* urb;
 	struct usbmidi_in_port {
-		snd_rawmidi_substream_t* substream;
+		struct snd_rawmidi_substream *substream;
 	} ports[0x10];
 	u8 seen_f5;
 	u8 error_resubmit;
 	int current_port;
 };
 
-static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep);
+static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep);
 
 static const uint8_t snd_usbmidi_cin_length[] = {
 	0, 0, 2, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1
@@ -196,10 +193,10 @@
 /*
  * Receives a chunk of MIDI data.
  */
-static void snd_usbmidi_input_data(snd_usb_midi_in_endpoint_t* ep, int portidx,
+static void snd_usbmidi_input_data(struct snd_usb_midi_in_endpoint* ep, int portidx,
 				   uint8_t* data, int length)
 {
-	usbmidi_in_port_t* port = &ep->ports[portidx];
+	struct usbmidi_in_port* port = &ep->ports[portidx];
 
 	if (!port->substream) {
 		snd_printd("unexpected port %d!\n", portidx);
@@ -227,7 +224,7 @@
  */
 static void snd_usbmidi_in_urb_complete(struct urb* urb, struct pt_regs *regs)
 {
-	snd_usb_midi_in_endpoint_t* ep = urb->context;
+	struct snd_usb_midi_in_endpoint* ep = urb->context;
 
 	if (urb->status == 0) {
 		dump_urb("received", urb->transfer_buffer, urb->actual_length);
@@ -251,7 +248,7 @@
 
 static void snd_usbmidi_out_urb_complete(struct urb* urb, struct pt_regs *regs)
 {
-	snd_usb_midi_out_endpoint_t* ep = urb->context;
+	struct snd_usb_midi_out_endpoint* ep = urb->context;
 
 	spin_lock(&ep->buffer_lock);
 	ep->urb_active = 0;
@@ -272,7 +269,7 @@
  * This is called when some data should be transferred to the device
  * (from one or more substreams).
  */
-static void snd_usbmidi_do_output(snd_usb_midi_out_endpoint_t* ep)
+static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
 {
 	struct urb* urb = ep->urb;
 	unsigned long flags;
@@ -297,7 +294,7 @@
 
 static void snd_usbmidi_out_tasklet(unsigned long data)
 {
-	snd_usb_midi_out_endpoint_t* ep = (snd_usb_midi_out_endpoint_t *) data;
+	struct snd_usb_midi_out_endpoint* ep = (struct snd_usb_midi_out_endpoint *) data;
 
 	snd_usbmidi_do_output(ep);
 }
@@ -305,11 +302,11 @@
 /* called after transfers had been interrupted due to some USB error */
 static void snd_usbmidi_error_timer(unsigned long data)
 {
-	snd_usb_midi_t *umidi = (snd_usb_midi_t *)data;
+	struct snd_usb_midi *umidi = (struct snd_usb_midi *)data;
 	int i;
 
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
-		snd_usb_midi_in_endpoint_t *in = umidi->endpoints[i].in;
+		struct snd_usb_midi_in_endpoint *in = umidi->endpoints[i].in;
 		if (in && in->error_resubmit) {
 			in->error_resubmit = 0;
 			in->urb->dev = umidi->chip->dev;
@@ -321,7 +318,7 @@
 }
 
 /* helper function to send static data that may not DMA-able */
-static int send_bulk_static_data(snd_usb_midi_out_endpoint_t* ep,
+static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep,
 				 const void *data, int len)
 {
 	int err;
@@ -342,7 +339,7 @@
  * fourth byte in each packet, and uses length instead of CIN.
  */
 
-static void snd_usbmidi_standard_input(snd_usb_midi_in_endpoint_t* ep,
+static void snd_usbmidi_standard_input(struct snd_usb_midi_in_endpoint* ep,
 				       uint8_t* buffer, int buffer_length)
 {
 	int i;
@@ -355,7 +352,7 @@
 		}
 }
 
-static void snd_usbmidi_midiman_input(snd_usb_midi_in_endpoint_t* ep,
+static void snd_usbmidi_midiman_input(struct snd_usb_midi_in_endpoint* ep,
 				      uint8_t* buffer, int buffer_length)
 {
 	int i;
@@ -401,7 +398,7 @@
 /*
  * Converts MIDI commands to USB MIDI packets.
  */
-static void snd_usbmidi_transmit_byte(usbmidi_out_port_t* port,
+static void snd_usbmidi_transmit_byte(struct usbmidi_out_port* port,
 				      uint8_t b, struct urb* urb)
 {
 	uint8_t p0 = port->cable;
@@ -495,14 +492,14 @@
 	}
 }
 
-static void snd_usbmidi_standard_output(snd_usb_midi_out_endpoint_t* ep)
+static void snd_usbmidi_standard_output(struct snd_usb_midi_out_endpoint* ep)
 {
 	struct urb* urb = ep->urb;
 	int p;
 
 	/* FIXME: lower-numbered ports can starve higher-numbered ports */
 	for (p = 0; p < 0x10; ++p) {
-		usbmidi_out_port_t* port = &ep->ports[p];
+		struct usbmidi_out_port* port = &ep->ports[p];
 		if (!port->active)
 			continue;
 		while (urb->transfer_buffer_length + 3 < ep->max_transfer) {
@@ -534,7 +531,7 @@
  * at the third byte.
  */
 
-static void snd_usbmidi_novation_input(snd_usb_midi_in_endpoint_t* ep,
+static void snd_usbmidi_novation_input(struct snd_usb_midi_in_endpoint* ep,
 				       uint8_t* buffer, int buffer_length)
 {
 	if (buffer_length < 2 || !buffer[0] || buffer_length < buffer[0] + 1)
@@ -542,7 +539,7 @@
 	snd_usbmidi_input_data(ep, 0, &buffer[2], buffer[0] - 1);
 }
 
-static void snd_usbmidi_novation_output(snd_usb_midi_out_endpoint_t* ep)
+static void snd_usbmidi_novation_output(struct snd_usb_midi_out_endpoint* ep)
 {
 	uint8_t* transfer_buffer;
 	int count;
@@ -571,13 +568,13 @@
  * "raw" protocol: used by the MOTU FastLane.
  */
 
-static void snd_usbmidi_raw_input(snd_usb_midi_in_endpoint_t* ep,
+static void snd_usbmidi_raw_input(struct snd_usb_midi_in_endpoint* ep,
 				  uint8_t* buffer, int buffer_length)
 {
 	snd_usbmidi_input_data(ep, 0, buffer, buffer_length);
 }
 
-static void snd_usbmidi_raw_output(snd_usb_midi_out_endpoint_t* ep)
+static void snd_usbmidi_raw_output(struct snd_usb_midi_out_endpoint* ep)
 {
 	int count;
 
@@ -602,7 +599,7 @@
  * Emagic USB MIDI protocol: raw MIDI with "F5 xx" port switching.
  */
 
-static void snd_usbmidi_emagic_init_out(snd_usb_midi_out_endpoint_t* ep)
+static void snd_usbmidi_emagic_init_out(struct snd_usb_midi_out_endpoint* ep)
 {
 	static const u8 init_data[] = {
 		/* initialization magic: "get version" */
@@ -619,7 +616,7 @@
 	send_bulk_static_data(ep, init_data, sizeof(init_data));
 }
 
-static void snd_usbmidi_emagic_finish_out(snd_usb_midi_out_endpoint_t* ep)
+static void snd_usbmidi_emagic_finish_out(struct snd_usb_midi_out_endpoint* ep)
 {
 	static const u8 finish_data[] = {
 		/* switch to patch mode with last preset */
@@ -635,7 +632,7 @@
 	send_bulk_static_data(ep, finish_data, sizeof(finish_data));
 }
 
-static void snd_usbmidi_emagic_input(snd_usb_midi_in_endpoint_t* ep,
+static void snd_usbmidi_emagic_input(struct snd_usb_midi_in_endpoint* ep,
 				     uint8_t* buffer, int buffer_length)
 {
 	int i;
@@ -679,7 +676,7 @@
 	}
 }
 
-static void snd_usbmidi_emagic_output(snd_usb_midi_out_endpoint_t* ep)
+static void snd_usbmidi_emagic_output(struct snd_usb_midi_out_endpoint* ep)
 {
 	int port0 = ep->current_port;
 	uint8_t* buf = ep->urb->transfer_buffer;
@@ -689,7 +686,7 @@
 	for (i = 0; i < 0x10; ++i) {
 		/* round-robin, starting at the last current port */
 		int portnum = (port0 + i) & 15;
-		usbmidi_out_port_t* port = &ep->ports[portnum];
+		struct usbmidi_out_port* port = &ep->ports[portnum];
 
 		if (!port->active)
 			continue;
@@ -733,10 +730,10 @@
 };
 
 
-static int snd_usbmidi_output_open(snd_rawmidi_substream_t* substream)
+static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
 {
-	snd_usb_midi_t* umidi = substream->rmidi->private_data;
-	usbmidi_out_port_t* port = NULL;
+	struct snd_usb_midi* umidi = substream->rmidi->private_data;
+	struct usbmidi_out_port* port = NULL;
 	int i, j;
 
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
@@ -755,14 +752,14 @@
 	return 0;
 }
 
-static int snd_usbmidi_output_close(snd_rawmidi_substream_t* substream)
+static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
 {
 	return 0;
 }
 
-static void snd_usbmidi_output_trigger(snd_rawmidi_substream_t* substream, int up)
+static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	usbmidi_out_port_t* port = (usbmidi_out_port_t*)substream->runtime->private_data;
+	struct usbmidi_out_port* port = (struct usbmidi_out_port*)substream->runtime->private_data;
 
 	port->active = up;
 	if (up) {
@@ -777,19 +774,19 @@
 	}
 }
 
-static int snd_usbmidi_input_open(snd_rawmidi_substream_t* substream)
+static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream)
 {
 	return 0;
 }
 
-static int snd_usbmidi_input_close(snd_rawmidi_substream_t* substream)
+static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream)
 {
 	return 0;
 }
 
-static void snd_usbmidi_input_trigger(snd_rawmidi_substream_t* substream, int up)
+static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
 {
-	snd_usb_midi_t* umidi = substream->rmidi->private_data;
+	struct snd_usb_midi* umidi = substream->rmidi->private_data;
 
 	if (up)
 		set_bit(substream->number, &umidi->input_triggered);
@@ -797,13 +794,13 @@
 		clear_bit(substream->number, &umidi->input_triggered);
 }
 
-static snd_rawmidi_ops_t snd_usbmidi_output_ops = {
+static struct snd_rawmidi_ops snd_usbmidi_output_ops = {
 	.open = snd_usbmidi_output_open,
 	.close = snd_usbmidi_output_close,
 	.trigger = snd_usbmidi_output_trigger,
 };
 
-static snd_rawmidi_ops_t snd_usbmidi_input_ops = {
+static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
 	.open = snd_usbmidi_input_open,
 	.close = snd_usbmidi_input_close,
 	.trigger = snd_usbmidi_input_trigger
@@ -813,7 +810,7 @@
  * Frees an input endpoint.
  * May be called when ep hasn't been initialized completely.
  */
-static void snd_usbmidi_in_endpoint_delete(snd_usb_midi_in_endpoint_t* ep)
+static void snd_usbmidi_in_endpoint_delete(struct snd_usb_midi_in_endpoint* ep)
 {
 	if (ep->urb) {
 		usb_buffer_free(ep->umidi->chip->dev,
@@ -828,11 +825,11 @@
 /*
  * Creates an input endpoint.
  */
-static int snd_usbmidi_in_endpoint_create(snd_usb_midi_t* umidi,
-					  snd_usb_midi_endpoint_info_t* ep_info,
-					  snd_usb_midi_endpoint_t* rep)
+static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
+					  struct snd_usb_midi_endpoint_info* ep_info,
+					  struct snd_usb_midi_endpoint* rep)
 {
-	snd_usb_midi_in_endpoint_t* ep;
+	struct snd_usb_midi_in_endpoint* ep;
 	void* buffer;
 	unsigned int pipe;
 	int length;
@@ -885,7 +882,7 @@
  * Frees an output endpoint.
  * May be called when ep hasn't been initialized completely.
  */
-static void snd_usbmidi_out_endpoint_delete(snd_usb_midi_out_endpoint_t* ep)
+static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep)
 {
 	if (ep->urb) {
 		usb_buffer_free(ep->umidi->chip->dev, ep->max_transfer,
@@ -899,11 +896,11 @@
 /*
  * Creates an output endpoint, and initializes output ports.
  */
-static int snd_usbmidi_out_endpoint_create(snd_usb_midi_t* umidi,
-					   snd_usb_midi_endpoint_info_t* ep_info,
-			 		   snd_usb_midi_endpoint_t* rep)
+static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
+					   struct snd_usb_midi_endpoint_info* ep_info,
+			 		   struct snd_usb_midi_endpoint* rep)
 {
-	snd_usb_midi_out_endpoint_t* ep;
+	struct snd_usb_midi_out_endpoint* ep;
 	int i;
 	unsigned int pipe;
 	void* buffer;
@@ -951,12 +948,12 @@
 /*
  * Frees everything.
  */
-static void snd_usbmidi_free(snd_usb_midi_t* umidi)
+static void snd_usbmidi_free(struct snd_usb_midi* umidi)
 {
 	int i;
 
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
-		snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];
+		struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
 		if (ep->out)
 			snd_usbmidi_out_endpoint_delete(ep->out);
 		if (ep->in)
@@ -970,13 +967,13 @@
  */
 void snd_usbmidi_disconnect(struct list_head* p)
 {
-	snd_usb_midi_t* umidi;
+	struct snd_usb_midi* umidi;
 	int i;
 
-	umidi = list_entry(p, snd_usb_midi_t, list);
+	umidi = list_entry(p, struct snd_usb_midi, list);
 	del_timer_sync(&umidi->error_timer);
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
-		snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];
+		struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
 		if (ep->out)
 			tasklet_kill(&ep->out->tasklet);
 		if (ep->out && ep->out->urb) {
@@ -989,19 +986,19 @@
 	}
 }
 
-static void snd_usbmidi_rawmidi_free(snd_rawmidi_t* rmidi)
+static void snd_usbmidi_rawmidi_free(struct snd_rawmidi *rmidi)
 {
-	snd_usb_midi_t* umidi = rmidi->private_data;
+	struct snd_usb_midi* umidi = rmidi->private_data;
 	snd_usbmidi_free(umidi);
 }
 
-static snd_rawmidi_substream_t* snd_usbmidi_find_substream(snd_usb_midi_t* umidi,
+static struct snd_rawmidi_substream *snd_usbmidi_find_substream(struct snd_usb_midi* umidi,
 							   int stream, int number)
 {
 	struct list_head* list;
 
 	list_for_each(list, &umidi->rmidi->streams[stream].substreams) {
-		snd_rawmidi_substream_t* substream = list_entry(list, snd_rawmidi_substream_t, list);
+		struct snd_rawmidi_substream *substream = list_entry(list, struct snd_rawmidi_substream, list);
 		if (substream->number == number)
 			return substream;
 	}
@@ -1097,14 +1094,14 @@
 	{ USB_ID(0x086a, 0x0003), 4, "%s Broadcast" },
 };
 
-static void snd_usbmidi_init_substream(snd_usb_midi_t* umidi,
+static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
 				       int stream, int number,
-				       snd_rawmidi_substream_t** rsubstream)
+				       struct snd_rawmidi_substream ** rsubstream)
 {
 	int i;
 	const char *name_format;
 
-	snd_rawmidi_substream_t* substream = snd_usbmidi_find_substream(umidi, stream, number);
+	struct snd_rawmidi_substream *substream = snd_usbmidi_find_substream(umidi, stream, number);
 	if (!substream) {
 		snd_printd(KERN_ERR "substream %d:%d not found\n", stream, number);
 		return;
@@ -1128,8 +1125,8 @@
 /*
  * Creates the endpoints and their ports.
  */
-static int snd_usbmidi_create_endpoints(snd_usb_midi_t* umidi,
-					snd_usb_midi_endpoint_info_t* endpoints)
+static int snd_usbmidi_create_endpoints(struct snd_usb_midi* umidi,
+					struct snd_usb_midi_endpoint_info* endpoints)
 {
 	int i, j, err;
 	int out_ports = 0, in_ports = 0;
@@ -1169,8 +1166,8 @@
 /*
  * Returns MIDIStreaming device capabilities.
  */
-static int snd_usbmidi_get_ms_info(snd_usb_midi_t* umidi,
-			   	   snd_usb_midi_endpoint_info_t* endpoints)
+static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
+			   	   struct snd_usb_midi_endpoint_info* endpoints)
 {
 	struct usb_interface* intf;
 	struct usb_host_interface *hostif;
@@ -1244,7 +1241,7 @@
  * On Roland devices, use the second alternate setting to be able to use
  * the interrupt input endpoint.
  */
-static void snd_usbmidi_switch_roland_altsetting(snd_usb_midi_t* umidi)
+static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi)
 {
 	struct usb_interface* intf;
 	struct usb_host_interface *hostif;
@@ -1270,8 +1267,8 @@
 /*
  * Try to find any usable endpoints in the interface.
  */
-static int snd_usbmidi_detect_endpoints(snd_usb_midi_t* umidi,
-					snd_usb_midi_endpoint_info_t* endpoint,
+static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
+					struct snd_usb_midi_endpoint_info* endpoint,
 					int max_endpoints)
 {
 	struct usb_interface* intf;
@@ -1318,8 +1315,8 @@
 /*
  * Detects the endpoints for one-port-per-endpoint protocols.
  */
-static int snd_usbmidi_detect_per_port_endpoints(snd_usb_midi_t* umidi,
-						 snd_usb_midi_endpoint_info_t* endpoints)
+static int snd_usbmidi_detect_per_port_endpoints(struct snd_usb_midi* umidi,
+						 struct snd_usb_midi_endpoint_info* endpoints)
 {
 	int err, i;
 	
@@ -1336,8 +1333,8 @@
 /*
  * Detects the endpoints and ports of Yamaha devices.
  */
-static int snd_usbmidi_detect_yamaha(snd_usb_midi_t* umidi,
-				     snd_usb_midi_endpoint_info_t* endpoint)
+static int snd_usbmidi_detect_yamaha(struct snd_usb_midi* umidi,
+				     struct snd_usb_midi_endpoint_info* endpoint)
 {
 	struct usb_interface* intf;
 	struct usb_host_interface *hostif;
@@ -1375,10 +1372,10 @@
 /*
  * Creates the endpoints and their ports for Midiman devices.
  */
-static int snd_usbmidi_create_endpoints_midiman(snd_usb_midi_t* umidi,
-						snd_usb_midi_endpoint_info_t* endpoint)
+static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi,
+						struct snd_usb_midi_endpoint_info* endpoint)
 {
-	snd_usb_midi_endpoint_info_t ep_info;
+	struct snd_usb_midi_endpoint_info ep_info;
 	struct usb_interface* intf;
 	struct usb_host_interface *hostif;
 	struct usb_interface_descriptor* intfd;
@@ -1458,10 +1455,10 @@
 	return 0;
 }
 
-static int snd_usbmidi_create_rawmidi(snd_usb_midi_t* umidi,
+static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
 				      int out_ports, int in_ports)
 {
-	snd_rawmidi_t* rmidi;
+	struct snd_rawmidi *rmidi;
 	int err;
 
 	err = snd_rawmidi_new(umidi->chip->card, "USB MIDI",
@@ -1487,18 +1484,18 @@
  */
 void snd_usbmidi_input_stop(struct list_head* p)
 {
-	snd_usb_midi_t* umidi;
+	struct snd_usb_midi* umidi;
 	int i;
 
-	umidi = list_entry(p, snd_usb_midi_t, list);
+	umidi = list_entry(p, struct snd_usb_midi, list);
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
-		snd_usb_midi_endpoint_t* ep = &umidi->endpoints[i];
+		struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i];
 		if (ep->in)
 			usb_kill_urb(ep->in->urb);
 	}
 }
 
-static void snd_usbmidi_input_start_ep(snd_usb_midi_in_endpoint_t* ep)
+static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep)
 {
 	if (ep) {
 		struct urb* urb = ep->urb;
@@ -1512,10 +1509,10 @@
  */
 void snd_usbmidi_input_start(struct list_head* p)
 {
-	snd_usb_midi_t* umidi;
+	struct snd_usb_midi* umidi;
 	int i;
 
-	umidi = list_entry(p, snd_usb_midi_t, list);
+	umidi = list_entry(p, struct snd_usb_midi, list);
 	for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
 		snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
 }
@@ -1523,12 +1520,12 @@
 /*
  * Creates and registers everything needed for a MIDI streaming interface.
  */
-int snd_usb_create_midi_interface(snd_usb_audio_t* chip,
+int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
 				  struct usb_interface* iface,
-				  const snd_usb_audio_quirk_t* quirk)
+				  const struct snd_usb_audio_quirk* quirk)
 {
-	snd_usb_midi_t* umidi;
-	snd_usb_midi_endpoint_info_t endpoints[MIDI_MAX_ENDPOINTS];
+	struct snd_usb_midi* umidi;
+	struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS];
 	int out_ports, in_ports;
 	int i, err;
 
@@ -1551,7 +1548,7 @@
 		break;
 	case QUIRK_MIDI_FIXED_ENDPOINT:
 		memcpy(&endpoints[0], quirk->data,
-		       sizeof(snd_usb_midi_endpoint_info_t));
+		       sizeof(struct snd_usb_midi_endpoint_info));
 		err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
 		break;
 	case QUIRK_MIDI_YAMAHA:
@@ -1560,7 +1557,7 @@
 	case QUIRK_MIDI_MIDIMAN:
 		umidi->usb_protocol_ops = &snd_usbmidi_midiman_ops;
 		memcpy(&endpoints[0], quirk->data,
-		       sizeof(snd_usb_midi_endpoint_info_t));
+		       sizeof(struct snd_usb_midi_endpoint_info));
 		err = 0;
 		break;
 	case QUIRK_MIDI_NOVATION:
@@ -1574,7 +1571,7 @@
 	case QUIRK_MIDI_EMAGIC:
 		umidi->usb_protocol_ops = &snd_usbmidi_emagic_ops;
 		memcpy(&endpoints[0], quirk->data,
-		       sizeof(snd_usb_midi_endpoint_info_t));
+		       sizeof(struct snd_usb_midi_endpoint_info));
 		err = snd_usbmidi_detect_endpoints(umidi, &endpoints[0], 1);
 		break;
 	case QUIRK_MIDI_MIDITECH:
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index e570d14..678dac2 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -46,18 +46,13 @@
 /* ignore error from controls - for debugging */
 /* #define IGNORE_CTL_ERROR */
 
-typedef struct usb_mixer_build mixer_build_t;
-typedef struct usb_audio_term usb_audio_term_t;
-typedef struct usb_mixer_elem_info usb_mixer_elem_info_t;
-
-
 struct usb_mixer_interface {
-	snd_usb_audio_t *chip;
+	struct snd_usb_audio *chip;
 	unsigned int ctrlif;
 	struct list_head list;
 	unsigned int ignore_ctl_error;
 	struct urb *urb;
-	usb_mixer_elem_info_t **id_elems; /* array[256], indexed by unit id */
+	struct usb_mixer_elem_info **id_elems; /* array[256], indexed by unit id */
 
 	/* Sound Blaster remote control stuff */
 	enum {
@@ -86,21 +81,21 @@
 
 struct usbmix_name_map;
 
-struct usb_mixer_build {
-	snd_usb_audio_t *chip;
+struct mixer_build {
+	struct snd_usb_audio *chip;
 	struct usb_mixer_interface *mixer;
 	unsigned char *buffer;
 	unsigned int buflen;
 	DECLARE_BITMAP(unitbitmap, 256);
-	usb_audio_term_t oterm;
+	struct usb_audio_term oterm;
 	const struct usbmix_name_map *map;
 	const struct usbmix_selector_map *selector_map;
 };
 
 struct usb_mixer_elem_info {
 	struct usb_mixer_interface *mixer;
-	usb_mixer_elem_info_t *next_id_elem; /* list of controls with same id */
-	snd_ctl_elem_id_t *elem_id;
+	struct usb_mixer_elem_info *next_id_elem; /* list of controls with same id */
+	struct snd_ctl_elem_id *elem_id;
 	unsigned int id;
 	unsigned int control;	/* CS or ICN (high byte) */
 	unsigned int cmask; /* channel mask bitmap: 0 = master */
@@ -179,7 +174,7 @@
 #include "usbmixer_maps.c"
 
 /* get the mapped name if the unit matches */
-static int check_mapped_name(mixer_build_t *state, int unitid, int control, char *buf, int buflen)
+static int check_mapped_name(struct mixer_build *state, int unitid, int control, char *buf, int buflen)
 {
 	const struct usbmix_name_map *p;
 
@@ -197,7 +192,7 @@
 }
 
 /* check whether the control should be ignored */
-static int check_ignored_ctl(mixer_build_t *state, int unitid, int control)
+static int check_ignored_ctl(struct mixer_build *state, int unitid, int control)
 {
 	const struct usbmix_name_map *p;
 
@@ -214,7 +209,7 @@
 }
 
 /* get the mapped selector source name */
-static int check_mapped_selector_name(mixer_build_t *state, int unitid,
+static int check_mapped_selector_name(struct mixer_build *state, int unitid,
 				      int index, char *buf, int buflen)
 {
 	const struct usbmix_selector_map *p;
@@ -231,7 +226,7 @@
 /*
  * find an audio control unit with the given unit id
  */
-static void *find_audio_control_unit(mixer_build_t *state, unsigned char unit)
+static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit)
 {
 	unsigned char *p;
 
@@ -248,7 +243,7 @@
 /*
  * copy a string with the given id
  */
-static int snd_usb_copy_string_desc(mixer_build_t *state, int index, char *buf, int maxlen)
+static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen)
 {
 	int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
 	buf[len] = 0;
@@ -258,7 +253,7 @@
 /*
  * convert from the byte/word on usb descriptor to the zero-based integer
  */
-static int convert_signed_value(usb_mixer_elem_info_t *cval, int val)
+static int convert_signed_value(struct usb_mixer_elem_info *cval, int val)
 {
 	switch (cval->val_type) {
 	case USB_MIXER_BOOLEAN:
@@ -288,7 +283,7 @@
 /*
  * convert from the zero-based int to the byte/word for usb descriptor
  */
-static int convert_bytes_value(usb_mixer_elem_info_t *cval, int val)
+static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val)
 {
 	switch (cval->val_type) {
 	case USB_MIXER_BOOLEAN:
@@ -305,7 +300,7 @@
 	return 0; /* not reached */
 }
 
-static int get_relative_value(usb_mixer_elem_info_t *cval, int val)
+static int get_relative_value(struct usb_mixer_elem_info *cval, int val)
 {
 	if (! cval->res)
 		cval->res = 1;
@@ -317,7 +312,7 @@
 		return (val - cval->min) / cval->res;
 }
 
-static int get_abs_value(usb_mixer_elem_info_t *cval, int val)
+static int get_abs_value(struct usb_mixer_elem_info *cval, int val)
 {
 	if (val < 0)
 		return cval->min;
@@ -335,7 +330,7 @@
  * retrieve a mixer value
  */
 
-static int get_ctl_value(usb_mixer_elem_info_t *cval, int request, int validx, int *value_ret)
+static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret)
 {
 	unsigned char buf[2];
 	int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
@@ -357,13 +352,13 @@
 	return -EINVAL;
 }
 
-static int get_cur_ctl_value(usb_mixer_elem_info_t *cval, int validx, int *value)
+static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value)
 {
 	return get_ctl_value(cval, GET_CUR, validx, value);
 }
 
 /* channel = 0: master, 1 = first channel */
-static inline int get_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int *value)
+static inline int get_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, int *value)
 {
 	return get_ctl_value(cval, GET_CUR, (cval->control << 8) | channel, value);
 }
@@ -372,7 +367,7 @@
  * set a mixer value
  */
 
-static int set_ctl_value(usb_mixer_elem_info_t *cval, int request, int validx, int value_set)
+static int set_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int value_set)
 {
 	unsigned char buf[2];
 	int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1;
@@ -394,12 +389,12 @@
 	return -EINVAL;
 }
 
-static int set_cur_ctl_value(usb_mixer_elem_info_t *cval, int validx, int value)
+static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value)
 {
 	return set_ctl_value(cval, SET_CUR, validx, value);
 }
 
-static inline int set_cur_mix_value(usb_mixer_elem_info_t *cval, int channel, int value)
+static inline int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, int value)
 {
 	return set_ctl_value(cval, SET_CUR, (cval->control << 8) | channel, value);
 }
@@ -409,7 +404,7 @@
  * parser routines begin here...
  */
 
-static int parse_audio_unit(mixer_build_t *state, int unitid);
+static int parse_audio_unit(struct mixer_build *state, int unitid);
 
 
 /*
@@ -430,9 +425,9 @@
  * if failed, give up and free the control instance.
  */
 
-static int add_control_to_empty(mixer_build_t *state, snd_kcontrol_t *kctl)
+static int add_control_to_empty(struct mixer_build *state, struct snd_kcontrol *kctl)
 {
-	usb_mixer_elem_info_t *cval = kctl->private_data;
+	struct usb_mixer_elem_info *cval = kctl->private_data;
 	int err;
 
 	while (snd_ctl_find_id(state->chip->card, &kctl->id))
@@ -496,7 +491,7 @@
 	{ 0 },
 };
 
-static int get_term_name(mixer_build_t *state, usb_audio_term_t *iterm,
+static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm,
 			 unsigned char *name, int maxlen, int term_only)
 {
 	struct iterm_name_combo *names;
@@ -546,7 +541,7 @@
  * parse the source unit recursively until it reaches to a terminal
  * or a branched unit.
  */
-static int check_input_term(mixer_build_t *state, int id, usb_audio_term_t *term)
+static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term)
 {
 	unsigned char *p1;
 
@@ -621,7 +616,7 @@
 
 
 /* private_free callback */
-static void usb_mixer_elem_free(snd_kcontrol_t *kctl)
+static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
 {
 	kfree(kctl->private_data);
 	kctl->private_data = NULL;
@@ -635,7 +630,7 @@
 /*
  * retrieve the minimum and maximum values for the specified control
  */
-static int get_min_max(usb_mixer_elem_info_t *cval, int default_min)
+static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
 {
 	/* for failsafe */
 	cval->min = default_min;
@@ -683,9 +678,9 @@
 
 
 /* get a feature/mixer unit info */
-static int mixer_ctl_feature_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	usb_mixer_elem_info_t *cval = kcontrol->private_data;
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 
 	if (cval->val_type == USB_MIXER_BOOLEAN ||
 	    cval->val_type == USB_MIXER_INV_BOOLEAN)
@@ -707,9 +702,9 @@
 }
 
 /* get the current value from feature/mixer unit */
-static int mixer_ctl_feature_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	usb_mixer_elem_info_t *cval = kcontrol->private_data;
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 	int c, cnt, val, err;
 
 	if (cval->cmask) {
@@ -748,9 +743,9 @@
 }
 
 /* put the current value to feature/mixer unit */
-static int mixer_ctl_feature_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	usb_mixer_elem_info_t *cval = kcontrol->private_data;
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 	int c, cnt, val, oval, err;
 	int changed = 0;
 
@@ -791,7 +786,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t usb_feature_unit_ctl = {
+static struct snd_kcontrol_new usb_feature_unit_ctl = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "", /* will be filled later manually */
 	.info = mixer_ctl_feature_info,
@@ -804,15 +799,15 @@
  * build a feature control
  */
 
-static void build_feature_ctl(mixer_build_t *state, unsigned char *desc,
+static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
 			      unsigned int ctl_mask, int control,
-			      usb_audio_term_t *iterm, int unitid)
+			      struct usb_audio_term *iterm, int unitid)
 {
 	unsigned int len = 0;
 	int mapped_name = 0;
 	int nameid = desc[desc[0] - 1];
-	snd_kcontrol_t *kctl;
-	usb_mixer_elem_info_t *cval;
+	struct snd_kcontrol *kctl;
+	struct usb_mixer_elem_info *cval;
 
 	control++; /* change from zero-based to 1-based value */
 
@@ -928,10 +923,10 @@
  *
  * most of controlls are defined here.
  */
-static int parse_audio_feature_unit(mixer_build_t *state, int unitid, unsigned char *ftr)
+static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsigned char *ftr)
 {
 	int channels, i, j;
-	usb_audio_term_t iterm;
+	struct usb_audio_term iterm;
 	unsigned int master_bits, first_ch_bits;
 	int err, csize;
 
@@ -984,15 +979,15 @@
  * input channel number (zero based) is given in control field instead.
  */
 
-static void build_mixer_unit_ctl(mixer_build_t *state, unsigned char *desc,
+static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
 				 int in_pin, int in_ch, int unitid,
-				 usb_audio_term_t *iterm)
+				 struct usb_audio_term *iterm)
 {
-	usb_mixer_elem_info_t *cval;
+	struct usb_mixer_elem_info *cval;
 	unsigned int input_pins = desc[4];
 	unsigned int num_outs = desc[5 + input_pins];
 	unsigned int i, len;
-	snd_kcontrol_t *kctl;
+	struct snd_kcontrol *kctl;
 
 	if (check_ignored_ctl(state, unitid, 0))
 		return;
@@ -1039,9 +1034,9 @@
 /*
  * parse a mixer unit
  */
-static int parse_audio_mixer_unit(mixer_build_t *state, int unitid, unsigned char *desc)
+static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, unsigned char *desc)
 {
-	usb_audio_term_t iterm;
+	struct usb_audio_term iterm;
 	int input_pins, num_ins, num_outs;
 	int pin, ich, err;
 
@@ -1089,9 +1084,9 @@
  */
 
 /* get callback for processing/extension unit */
-static int mixer_ctl_procunit_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	usb_mixer_elem_info_t *cval = kcontrol->private_data;
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 	int err, val;
 
 	err = get_cur_ctl_value(cval, cval->control << 8, &val);
@@ -1107,9 +1102,9 @@
 }
 
 /* put callback for processing/extension unit */
-static int mixer_ctl_procunit_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	usb_mixer_elem_info_t *cval = kcontrol->private_data;
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 	int val, oval, err;
 
 	err = get_cur_ctl_value(cval, cval->control << 8, &oval);
@@ -1128,7 +1123,7 @@
 }
 
 /* alsa control interface for processing/extension unit */
-static snd_kcontrol_new_t mixer_procunit_ctl = {
+static struct snd_kcontrol_new mixer_procunit_ctl = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "", /* will be filled later */
 	.info = mixer_ctl_feature_info,
@@ -1205,11 +1200,11 @@
 /*
  * build a processing/extension unit
  */
-static int build_audio_procunit(mixer_build_t *state, int unitid, unsigned char *dsc, struct procunit_info *list, char *name)
+static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned char *dsc, struct procunit_info *list, char *name)
 {
 	int num_ins = dsc[6];
-	usb_mixer_elem_info_t *cval;
-	snd_kcontrol_t *kctl;
+	struct usb_mixer_elem_info *cval;
+	struct snd_kcontrol *kctl;
 	int i, err, nameid, type, len;
 	struct procunit_info *info;
 	struct procunit_value_info *valinfo;
@@ -1297,12 +1292,12 @@
 }
 
 
-static int parse_audio_processing_unit(mixer_build_t *state, int unitid, unsigned char *desc)
+static int parse_audio_processing_unit(struct mixer_build *state, int unitid, unsigned char *desc)
 {
 	return build_audio_procunit(state, unitid, desc, procunits, "Processing Unit");
 }
 
-static int parse_audio_extension_unit(mixer_build_t *state, int unitid, unsigned char *desc)
+static int parse_audio_extension_unit(struct mixer_build *state, int unitid, unsigned char *desc)
 {
 	return build_audio_procunit(state, unitid, desc, NULL, "Extension Unit");
 }
@@ -1315,9 +1310,9 @@
 /* info callback for selector unit
  * use an enumerator type for routing
  */
-static int mixer_ctl_selector_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	usb_mixer_elem_info_t *cval = kcontrol->private_data;
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 	char **itemlist = (char **)kcontrol->private_value;
 
 	snd_assert(itemlist, return -EINVAL);
@@ -1331,9 +1326,9 @@
 }
 
 /* get callback for selector unit */
-static int mixer_ctl_selector_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	usb_mixer_elem_info_t *cval = kcontrol->private_data;
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 	int val, err;
 
 	err = get_cur_ctl_value(cval, 0, &val);
@@ -1350,9 +1345,9 @@
 }
 
 /* put callback for selector unit */
-static int mixer_ctl_selector_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
-	usb_mixer_elem_info_t *cval = kcontrol->private_data;
+	struct usb_mixer_elem_info *cval = kcontrol->private_data;
 	int val, oval, err;
 
 	err = get_cur_ctl_value(cval, 0, &oval);
@@ -1371,7 +1366,7 @@
 }
 
 /* alsa control interface for selector unit */
-static snd_kcontrol_new_t mixer_selectunit_ctl = {
+static struct snd_kcontrol_new mixer_selectunit_ctl = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "", /* will be filled later */
 	.info = mixer_ctl_selector_info,
@@ -1383,12 +1378,12 @@
 /* private free callback.
  * free both private_data and private_value
  */
-static void usb_mixer_selector_elem_free(snd_kcontrol_t *kctl)
+static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl)
 {
 	int i, num_ins = 0;
 
 	if (kctl->private_data) {
-		usb_mixer_elem_info_t *cval = kctl->private_data;
+		struct usb_mixer_elem_info *cval = kctl->private_data;
 		num_ins = cval->max;
 		kfree(cval);
 		kctl->private_data = NULL;
@@ -1405,13 +1400,13 @@
 /*
  * parse a selector unit
  */
-static int parse_audio_selector_unit(mixer_build_t *state, int unitid, unsigned char *desc)
+static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsigned char *desc)
 {
 	unsigned int num_ins = desc[4];
 	unsigned int i, nameid, len;
 	int err;
-	usb_mixer_elem_info_t *cval;
-	snd_kcontrol_t *kctl;
+	struct usb_mixer_elem_info *cval;
+	struct snd_kcontrol *kctl;
 	char **namelist;
 
 	if (! num_ins || desc[0] < 6 + num_ins) {
@@ -1452,7 +1447,7 @@
 	}
 #define MAX_ITEM_NAME_LEN	64
 	for (i = 0; i < num_ins; i++) {
-		usb_audio_term_t iterm;
+		struct usb_audio_term iterm;
 		len = 0;
 		namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL);
 		if (! namelist[i]) {
@@ -1511,7 +1506,7 @@
  * parse an audio unit recursively
  */
 
-static int parse_audio_unit(mixer_build_t *state, int unitid)
+static int parse_audio_unit(struct mixer_build *state, int unitid)
 {
 	unsigned char *p1;
 
@@ -1556,7 +1551,7 @@
 	kfree(mixer);
 }
 
-static int snd_usb_mixer_dev_free(snd_device_t *device)
+static int snd_usb_mixer_dev_free(struct snd_device *device)
 {
 	struct usb_mixer_interface *mixer = device->device_data;
 	snd_usb_mixer_free(mixer);
@@ -1571,7 +1566,7 @@
 static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer)
 {
 	unsigned char *desc;
-	mixer_build_t state;
+	struct mixer_build state;
 	int err;
 	const struct usbmix_ctl_map *map;
 	struct usb_host_interface *hostif;
@@ -1611,7 +1606,7 @@
 static void snd_usb_mixer_notify_id(struct usb_mixer_interface *mixer,
 				    int unitid)
 {
-	usb_mixer_elem_info_t *info;
+	struct usb_mixer_elem_info *info;
 
 	for (info = mixer->id_elems[unitid]; info; info = info->next_id_elem)
 		snd_ctl_notify(mixer->chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
@@ -1725,7 +1720,7 @@
 	wake_up(&mixer->rc_waitq);
 }
 
-static int snd_usb_sbrc_hwdep_open(snd_hwdep_t *hw, struct file *file)
+static int snd_usb_sbrc_hwdep_open(struct snd_hwdep *hw, struct file *file)
 {
 	struct usb_mixer_interface *mixer = hw->private_data;
 
@@ -1734,7 +1729,7 @@
 	return 0;
 }
 
-static int snd_usb_sbrc_hwdep_release(snd_hwdep_t *hw, struct file *file)
+static int snd_usb_sbrc_hwdep_release(struct snd_hwdep *hw, struct file *file)
 {
 	struct usb_mixer_interface *mixer = hw->private_data;
 
@@ -1743,7 +1738,7 @@
 	return 0;
 }
 
-static long snd_usb_sbrc_hwdep_read(snd_hwdep_t *hw, char __user *buf,
+static long snd_usb_sbrc_hwdep_read(struct snd_hwdep *hw, char __user *buf,
 				     long count, loff_t *offset)
 {
 	struct usb_mixer_interface *mixer = hw->private_data;
@@ -1763,7 +1758,7 @@
 	return err < 0 ? err : count;
 }
 
-static unsigned int snd_usb_sbrc_hwdep_poll(snd_hwdep_t *hw, struct file *file,
+static unsigned int snd_usb_sbrc_hwdep_poll(struct snd_hwdep *hw, struct file *file,
 					    poll_table *wait)
 {
 	struct usb_mixer_interface *mixer = hw->private_data;
@@ -1774,7 +1769,7 @@
 
 static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer)
 {
-	snd_hwdep_t *hwdep;
+	struct snd_hwdep *hwdep;
 	int err, len;
 
 	switch (mixer->chip->usb_id) {
@@ -1825,7 +1820,7 @@
 	return 0;
 }
 
-static int snd_audigy2nx_led_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+static int snd_audigy2nx_led_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -1834,7 +1829,7 @@
 	return 0;
 }
 
-static int snd_audigy2nx_led_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_audigy2nx_led_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
 	int index = kcontrol->private_value;
@@ -1843,7 +1838,7 @@
 	return 0;
 }
 
-static int snd_audigy2nx_led_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
 	int index = kcontrol->private_value;
@@ -1863,7 +1858,7 @@
 	return changed;
 }
 
-static snd_kcontrol_new_t snd_audigy2nx_controls[] = {
+static struct snd_kcontrol_new snd_audigy2nx_controls[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "CMSS LED Switch",
@@ -1904,8 +1899,8 @@
 	return 0;
 }
 
-static void snd_audigy2nx_proc_read(snd_info_entry_t *entry,
-				    snd_info_buffer_t *buffer)
+static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
+				    struct snd_info_buffer *buffer)
 {
 	static const struct {
 		int unitid;
@@ -1935,9 +1930,9 @@
 	}
 }
 
-int snd_usb_create_mixer(snd_usb_audio_t *chip, int ctrlif)
+int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif)
 {
-	static snd_device_ops_t dev_ops = {
+	static struct snd_device_ops dev_ops = {
 		.dev_free = snd_usb_mixer_dev_free
 	};
 	struct usb_mixer_interface *mixer;
@@ -1967,7 +1962,7 @@
 		goto _error;
 
 	if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020)) {
-		snd_info_entry_t *entry;
+		struct snd_info_entry *entry;
 
 		if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
 			goto _error;
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index ba506c3..6190ada 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -45,7 +45,7 @@
 
 #define YAMAHA_DEVICE(id, name) { \
 	USB_DEVICE(0x0499, id), \
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { \
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { \
 		.vendor_name = "Yamaha", \
 		.product_name = name, \
 		.ifnum = QUIRK_ANY_INTERFACE, \
@@ -54,7 +54,7 @@
 }
 #define YAMAHA_INTERFACE(id, intf, name) { \
 	USB_DEVICE_VENDOR_SPEC(0x0499, id), \
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) { \
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { \
 		.vendor_name = "Yamaha", \
 		.product_name = name, \
 		.ifnum = intf, \
@@ -149,12 +149,12 @@
  */
 {
 	USB_DEVICE(0x0582, 0x0000),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "UA-100",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
@@ -192,7 +192,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0007,
 					.in_cables  = 0x0007
 				}
@@ -205,12 +205,12 @@
 },
 {
 	USB_DEVICE(0x0582, 0x0002),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UM-4",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -222,7 +222,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x000f,
 					.in_cables  = 0x000f
 				}
@@ -235,12 +235,12 @@
 },
 {
 	USB_DEVICE(0x0582, 0x0003),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "SC-8850",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -252,7 +252,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x003f,
 					.in_cables  = 0x003f
 				}
@@ -265,12 +265,12 @@
 },
 {
 	USB_DEVICE(0x0582, 0x0004),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "U-8",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -282,7 +282,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0005,
 					.in_cables  = 0x0005
 				}
@@ -296,12 +296,12 @@
 {
 	/* a later revision uses ID 0x0099 */
 	USB_DEVICE(0x0582, 0x0005),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UM-2",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -313,7 +313,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0003,
 					.in_cables  = 0x0003
 				}
@@ -326,12 +326,12 @@
 },
 {
 	USB_DEVICE(0x0582, 0x0007),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "SC-8820",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -343,7 +343,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0013,
 					.in_cables  = 0x0013
 				}
@@ -356,12 +356,12 @@
 },
 {
 	USB_DEVICE(0x0582, 0x0008),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "PC-300",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -373,7 +373,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0001,
 					.in_cables  = 0x0001
 				}
@@ -387,12 +387,12 @@
 {
 	/* a later revision uses ID 0x009d */
 	USB_DEVICE(0x0582, 0x0009),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UM-1",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -404,7 +404,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0001,
 					.in_cables  = 0x0001
 				}
@@ -417,12 +417,12 @@
 },
 {
 	USB_DEVICE(0x0582, 0x000b),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "SK-500",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -434,7 +434,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0013,
 					.in_cables  = 0x0013
 				}
@@ -449,12 +449,12 @@
 	/* thanks to Emiliano Grilli <emillo@libero.it>
 	 * for helping researching this data */
 	USB_DEVICE(0x0582, 0x000c),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "SC-D70",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
@@ -492,7 +492,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0007,
 					.in_cables  = 0x0007
 				}
@@ -513,12 +513,12 @@
 	 * the 96kHz sample rate.
 	 */
 	USB_DEVICE(0x0582, 0x0010),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UA-5",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 1,
 				.type = QUIRK_AUDIO_STANDARD_INTERFACE
@@ -536,12 +536,12 @@
 {
 	/* has ID 0x0013 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0012),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "XV-5050",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -550,12 +550,12 @@
 {
 	/* has ID 0x0015 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0014),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UM-880",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x01ff,
 			.in_cables  = 0x01ff
 		}
@@ -564,12 +564,12 @@
 {
 	/* has ID 0x0017 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0016),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "SD-90",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -581,7 +581,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x000f,
 					.in_cables  = 0x000f
 				}
@@ -595,12 +595,12 @@
 {
 	/* has ID 0x001c when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x001b),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "MMP-2",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -612,7 +612,7 @@
 			{
 				.ifnum = 2,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0001,
 					.in_cables  = 0x0001
 				}
@@ -626,12 +626,12 @@
 {
 	/* has ID 0x001e when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x001d),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "V-SYNTH",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -640,12 +640,12 @@
 {
 	/* has ID 0x0024 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0023),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UM-550",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x003f,
 			.in_cables  = 0x003f
 		}
@@ -658,23 +658,57 @@
 	 * and no MIDI.
 	 */
 	USB_DEVICE(0x0582, 0x0025),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UA-20",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
 			{
 				.ifnum = 1,
-				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = & (const struct audioformat) {
+					.format = SNDRV_PCM_FORMAT_S24_3LE,
+					.channels = 2,
+					.iface = 1,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = 0,
+					.endpoint = 0x01,
+					.ep_attr = 0x01,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 44100,
+					.rate_max = 44100,
+				}
 			},
 			{
 				.ifnum = 2,
-				.type = QUIRK_AUDIO_STANDARD_INTERFACE
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = & (const struct audioformat) {
+					.format = SNDRV_PCM_FORMAT_S24_3LE,
+					.channels = 2,
+					.iface = 2,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = 0,
+					.endpoint = 0x82,
+					.ep_attr = 0x01,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 44100,
+					.rate_max = 44100,
+				}
 			},
 			{
 				.ifnum = 3,
-				.type = QUIRK_MIDI_STANDARD_INTERFACE
+				.type = QUIRK_MIDI_FIXED_ENDPOINT,
+				.data = & (const struct snd_usb_midi_endpoint_info) {
+					.out_cables = 0x0001,
+					.in_cables  = 0x0001
+				}
 			},
 			{
 				.ifnum = -1
@@ -685,12 +719,12 @@
 {
 	/* has ID 0x0028 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0027),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "SD-20",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0003,
 			.in_cables  = 0x0007
 		}
@@ -699,12 +733,12 @@
 {
 	/* has ID 0x002a when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0029),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "SD-80",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x000f,
 			.in_cables  = 0x000f
 		}
@@ -717,12 +751,12 @@
 	 * but offers only 16-bit PCM and no MIDI.
 	 */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x002b),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UA-700",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 1,
 				.type = QUIRK_AUDIO_EDIROL_UA700_UA25
@@ -744,12 +778,12 @@
 {
 	/* has ID 0x002e when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x002d),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "XV-2020",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -758,12 +792,12 @@
 {
 	/* has ID 0x0030 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x002f),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "VariOS",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0007,
 			.in_cables  = 0x0007
 		}
@@ -772,12 +806,12 @@
 {
 	/* has ID 0x0034 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0033),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "PCR",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0003,
 			.in_cables  = 0x0007
 		}
@@ -790,12 +824,12 @@
 	 * later revisions use IDs 0x0054 and 0x00a2.
 	 */
 	USB_DEVICE(0x0582, 0x0037),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "Digital Piano",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -808,12 +842,12 @@
 	 * and no MIDI.
 	 */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x003b),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "BOSS",
 		.product_name = "GS-10",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = & (const snd_usb_audio_quirk_t[]) {
+		.data = & (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 1,
 				.type = QUIRK_AUDIO_STANDARD_INTERFACE
@@ -835,12 +869,12 @@
 {
 	/* has ID 0x0041 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0040),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "GI-20",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -849,12 +883,12 @@
 {
 	/* has ID 0x0043 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0042),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "RS-70",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -862,12 +896,12 @@
 },
 {
 	USB_DEVICE(0x0582, 0x0044),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "UA-1000",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 1,
 				.type = QUIRK_AUDIO_EDIROL_UA1000
@@ -879,7 +913,7 @@
 			{
 				.ifnum = 3,
 				.type = QUIRK_MIDI_FIXED_ENDPOINT,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0003,
 					.in_cables  = 0x0003
 				}
@@ -893,12 +927,12 @@
 {
 	/* has ID 0x004a when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0048),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UR-80",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0003,
 			.in_cables  = 0x0007
 		}
@@ -908,12 +942,12 @@
 {
 	/* has ID 0x004f when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x004d),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "PCR-A",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0003,
 			.in_cables  = 0x0007
 		}
@@ -925,12 +959,12 @@
 	 * is standard compliant, but has only 16-bit PCM.
 	 */
 	USB_DEVICE(0x0582, 0x0050),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UA-3FX",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 1,
 				.type = QUIRK_AUDIO_STANDARD_INTERFACE
@@ -947,7 +981,7 @@
 },
 {
 	USB_DEVICE(0x0582, 0x0052),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UM-1SX",
 		.ifnum = 0,
@@ -958,12 +992,12 @@
 {
 	/* has ID 0x0067 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0065),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "PCR-1",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0003
 		}
@@ -972,12 +1006,12 @@
 {
 	/* has ID 0x006b when not in "Advanced Driver" mode */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x006a),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "SP-606",
 		.ifnum = 3,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -986,12 +1020,12 @@
 {
 	/* has ID 0x006e when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x006d),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		.product_name = "FANTOM-X",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -1004,12 +1038,12 @@
 	 * offers only 16-bit PCM at 44.1 kHz and no MIDI.
 	 */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x0074),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "EDIROL",
 		.product_name = "UA-25",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const snd_usb_audio_quirk_t[]) {
+		.data = (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_AUDIO_EDIROL_UA700_UA25
@@ -1031,12 +1065,12 @@
 {
 	/* has ID 0x0076 when not in "Advanced Driver" mode */
 	USB_DEVICE(0x0582, 0x0075),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "BOSS",
 		.product_name = "DR-880",
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -1045,12 +1079,12 @@
 {
 	/* has ID 0x007b when not in "Advanced Driver" mode */
 	USB_DEVICE_VENDOR_SPEC(0x0582, 0x007a),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Roland",
 		/* "RD" or "RD-700SX"? */
 		.ifnum = 0,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0003,
 			.in_cables  = 0x0003
 		}
@@ -1066,12 +1100,12 @@
 	 * compliant USB MIDI ports for external MIDI and controls.
 	 */
 	USB_DEVICE_VENDOR_SPEC(0x06f8, 0xb000),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Hercules",
 		.product_name = "DJ Console (WE)",
 		.ifnum = 4,
 		.type = QUIRK_MIDI_FIXED_ENDPOINT,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables = 0x0001
 		}
@@ -1090,12 +1124,12 @@
 /* Midiman/M-Audio devices */
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x1002),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "MidiSport 2x2",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_MIDI_MIDIMAN,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0003,
 			.in_cables  = 0x0003
 		}
@@ -1103,12 +1137,12 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x1011),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "MidiSport 1x1",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_MIDI_MIDIMAN,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -1116,12 +1150,12 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x1015),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "Keystation",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_MIDI_MIDIMAN,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -1129,12 +1163,12 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x1021),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "MidiSport 4x4",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_MIDI_MIDIMAN,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x000f,
 			.in_cables  = 0x000f
 		}
@@ -1147,12 +1181,12 @@
 	 * Thanks to Olaf Giesbrecht <Olaf_Giesbrecht@yahoo.de>
 	 */
 	USB_DEVICE_VER(0x0763, 0x1031, 0x0100, 0x0109),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "MidiSport 8x8",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_MIDI_MIDIMAN,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x01ff,
 			.in_cables  = 0x01ff
 		}
@@ -1160,12 +1194,12 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x1033),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "MidiSport 8x8",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_MIDI_MIDIMAN,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x01ff,
 			.in_cables  = 0x01ff
 		}
@@ -1173,12 +1207,12 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x1041),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "MidiSport 2x4",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_MIDI_MIDIMAN,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x000f,
 			.in_cables  = 0x0003
 		}
@@ -1186,12 +1220,12 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x2001),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "Quattro",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = & (const snd_usb_audio_quirk_t[]) {
+		.data = & (const struct snd_usb_audio_quirk[]) {
 			/*
 			 * Interfaces 0-2 are "Windows-compatible", 16-bit only,
 			 * and share endpoints with the other interfaces.
@@ -1237,7 +1271,7 @@
 			{
 				.ifnum = 9,
 				.type = QUIRK_MIDI_MIDIMAN,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0001,
 					.in_cables  = 0x0001
 				}
@@ -1250,12 +1284,12 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x2003),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "AudioPhile",
 		.ifnum = 6,
 		.type = QUIRK_MIDI_MIDIMAN,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -1263,12 +1297,12 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x2008),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "Ozone",
 		.ifnum = 3,
 		.type = QUIRK_MIDI_MIDIMAN,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x0001,
 			.in_cables  = 0x0001
 		}
@@ -1276,12 +1310,12 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0763, 0x200d),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "M-Audio",
 		.product_name = "OmniStudio",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = & (const snd_usb_audio_quirk_t[]) {
+		.data = & (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_IGNORE_INTERFACE
@@ -1321,7 +1355,7 @@
 			{
 				.ifnum = 9,
 				.type = QUIRK_MIDI_MIDIMAN,
-				.data = & (const snd_usb_midi_endpoint_info_t) {
+				.data = & (const struct snd_usb_midi_endpoint_info) {
 					.out_cables = 0x0001,
 					.in_cables  = 0x0001
 				}
@@ -1342,12 +1376,12 @@
 	.idVendor = 0x07fd,
 	.idProduct = 0x0001,
 	.bDeviceSubClass = 2,
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "MOTU",
 		.product_name = "Fastlane",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = & (const snd_usb_audio_quirk_t[]) {
+		.data = & (const struct snd_usb_audio_quirk[]) {
 			{
 				.ifnum = 0,
 				.type = QUIRK_MIDI_RAW
@@ -1366,7 +1400,7 @@
 {
 	/* Creative Sound Blaster MP3+ */
 	USB_DEVICE(0x041e, 0x3010),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Creative Labs",
 		.product_name = "Sound Blaster MP3+",
 		.ifnum = QUIRK_NO_INTERFACE
@@ -1377,12 +1411,12 @@
 /* Emagic devices */
 {
 	USB_DEVICE(0x086a, 0x0001),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Emagic",
 		/* .product_name = "Unitor8", */
 		.ifnum = 2,
 		.type = QUIRK_MIDI_EMAGIC,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x80ff,
 			.in_cables  = 0x80ff
 		}
@@ -1390,12 +1424,12 @@
 },
 {
 	USB_DEVICE(0x086a, 0x0002),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Emagic",
 		/* .product_name = "AMT8", */
 		.ifnum = 2,
 		.type = QUIRK_MIDI_EMAGIC,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x80ff,
 			.in_cables  = 0x80ff
 		}
@@ -1403,12 +1437,12 @@
 },
 {
 	USB_DEVICE(0x086a, 0x0003),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Emagic",
 		/* .product_name = "MT4", */
 		.ifnum = 2,
 		.type = QUIRK_MIDI_EMAGIC,
-		.data = & (const snd_usb_midi_endpoint_info_t) {
+		.data = & (const struct snd_usb_midi_endpoint_info) {
 			.out_cables = 0x800f,
 			.in_cables  = 0x8003
 		}
@@ -1418,7 +1452,7 @@
 /* TerraTec devices */
 {
 	USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0012),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "TerraTec",
 		.product_name = "PHASE 26",
 		.ifnum = 3,
@@ -1427,7 +1461,7 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0013),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "TerraTec",
 		.product_name = "PHASE 26",
 		.ifnum = 3,
@@ -1438,7 +1472,7 @@
 /* Novation EMS devices */
 {
 	USB_DEVICE_VENDOR_SPEC(0x1235, 0x0001),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Novation",
 		.product_name = "ReMOTE Audio/XStation",
 		.ifnum = 4,
@@ -1447,7 +1481,7 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x1235, 0x0002),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Novation",
 		.product_name = "Speedio",
 		.ifnum = 3,
@@ -1456,7 +1490,7 @@
 },
 {
 	USB_DEVICE_VENDOR_SPEC(0x1235, 0x4661),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Novation",
 		.product_name = "ReMOTE25",
 		.ifnum = 0,
@@ -1466,7 +1500,7 @@
 
 {
 	USB_DEVICE(0x4752, 0x0011),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Miditech",
 		.product_name = "Midistart-2",
 		.ifnum = 0,
@@ -1475,7 +1509,7 @@
 },
 {
 	USB_DEVICE(0x7104, 0x2202),
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.vendor_name = "Miditech",
 		.product_name = "MidiStudio-2",
 		.ifnum = 0,
@@ -1492,7 +1526,7 @@
 		       USB_DEVICE_ID_MATCH_INT_SUBCLASS,
 	.bInterfaceClass = USB_CLASS_AUDIO,
 	.bInterfaceSubClass = USB_SUBCLASS_MIDI_STREAMING,
-	.driver_info = (unsigned long) & (const snd_usb_audio_quirk_t) {
+	.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_MIDI_STANDARD_INTERFACE
 	}
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 8abe086..4b52d18 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -31,7 +31,7 @@
 #include "usbusx2y.h"
 #include "usX2Yhwdep.h"
 
-int usX2Y_hwdep_pcm_new(snd_card_t* card);
+int usX2Y_hwdep_pcm_new(struct snd_card *card);
 
 
 static struct page * snd_us428ctls_vm_nopage(struct vm_area_struct *area, unsigned long address, int *type)
@@ -49,7 +49,7 @@
 	offset = area->vm_pgoff << PAGE_SHIFT;
 	offset += address - area->vm_start;
 	snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_OOM);
-	vaddr = (char*)((usX2Ydev_t*)area->vm_private_data)->us428ctls_sharedmem + offset;
+	vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->us428ctls_sharedmem + offset;
 	page = virt_to_page(vaddr);
 	get_page(page);
 	snd_printdd( "vaddr=%p made us428ctls_vm_nopage() return %p; offset=%lX\n", vaddr, page, offset);
@@ -64,27 +64,27 @@
 	.nopage = snd_us428ctls_vm_nopage,
 };
 
-static int snd_us428ctls_mmap(snd_hwdep_t * hw, struct file *filp, struct vm_area_struct *area)
+static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
 {
 	unsigned long	size = (unsigned long)(area->vm_end - area->vm_start);
-	usX2Ydev_t	*us428 = (usX2Ydev_t*)hw->private_data;
+	struct usX2Ydev	*us428 = hw->private_data;
 
 	// FIXME this hwdep interface is used twice: fpga download and mmap for controlling Lights etc. Maybe better using 2 hwdep devs?
 	// so as long as the device isn't fully initialised yet we return -EBUSY here.
- 	if (!(((usX2Ydev_t*)hw->private_data)->chip_status & USX2Y_STAT_CHIP_INIT))
+ 	if (!(us428->chip_status & USX2Y_STAT_CHIP_INIT))
 		return -EBUSY;
 
 	/* if userspace tries to mmap beyond end of our buffer, fail */ 
-        if (size > ((PAGE_SIZE - 1 + sizeof(us428ctls_sharedmem_t)) / PAGE_SIZE) * PAGE_SIZE) {
-		snd_printd( "%lu > %lu\n", size, (unsigned long)sizeof(us428ctls_sharedmem_t)); 
+        if (size > PAGE_ALIGN(sizeof(struct us428ctls_sharedmem))) {
+		snd_printd( "%lu > %lu\n", size, (unsigned long)sizeof(struct us428ctls_sharedmem)); 
                 return -EINVAL;
 	}
 
 	if (!us428->us428ctls_sharedmem) {
 		init_waitqueue_head(&us428->us428ctls_wait_queue_head);
-		if(!(us428->us428ctls_sharedmem = snd_malloc_pages(sizeof(us428ctls_sharedmem_t), GFP_KERNEL)))
+		if(!(us428->us428ctls_sharedmem = snd_malloc_pages(sizeof(struct us428ctls_sharedmem), GFP_KERNEL)))
 			return -ENOMEM;
-		memset(us428->us428ctls_sharedmem, -1, sizeof(us428ctls_sharedmem_t));
+		memset(us428->us428ctls_sharedmem, -1, sizeof(struct us428ctls_sharedmem));
 		us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
 	}
 	area->vm_ops = &us428ctls_vm_ops;
@@ -93,11 +93,11 @@
 	return 0;
 }
 
-static unsigned int snd_us428ctls_poll(snd_hwdep_t *hw, struct file *file, poll_table *wait)
+static unsigned int snd_us428ctls_poll(struct snd_hwdep *hw, struct file *file, poll_table *wait)
 {
 	unsigned int	mask = 0;
-	usX2Ydev_t	*us428 = (usX2Ydev_t*)hw->private_data;
-	us428ctls_sharedmem_t *shm = us428->us428ctls_sharedmem;
+	struct usX2Ydev	*us428 = hw->private_data;
+	struct us428ctls_sharedmem *shm = us428->us428ctls_sharedmem;
 	if (us428->chip_status & USX2Y_STAT_CHIP_HUP)
 		return POLLHUP;
 
@@ -110,26 +110,28 @@
 }
 
 
-static int snd_usX2Y_hwdep_open(snd_hwdep_t *hw, struct file *file)
+static int snd_usX2Y_hwdep_open(struct snd_hwdep *hw, struct file *file)
 {
 	return 0;
 }
 
-static int snd_usX2Y_hwdep_release(snd_hwdep_t *hw, struct file *file)
+static int snd_usX2Y_hwdep_release(struct snd_hwdep *hw, struct file *file)
 {
 	return 0;
 }
 
-static int snd_usX2Y_hwdep_dsp_status(snd_hwdep_t *hw, snd_hwdep_dsp_status_t *info)
+static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
+				      struct snd_hwdep_dsp_status *info)
 {
 	static char *type_ids[USX2Y_TYPE_NUMS] = {
 		[USX2Y_TYPE_122] = "us122",
 		[USX2Y_TYPE_224] = "us224",
 		[USX2Y_TYPE_428] = "us428",
 	};
+	struct usX2Ydev	*us428 = hw->private_data;
 	int id = -1;
 
-	switch (le16_to_cpu(((usX2Ydev_t*)hw->private_data)->chip.dev->descriptor.idProduct)) {
+	switch (le16_to_cpu(us428->chip.dev->descriptor.idProduct)) {
 	case USB_ID_US122:
 		id = USX2Y_TYPE_122;
 		break;
@@ -144,35 +146,35 @@
 		return -ENODEV;
 	strcpy(info->id, type_ids[id]);
 	info->num_dsps = 2;		// 0: Prepad Data, 1: FPGA Code
- 	if (((usX2Ydev_t*)hw->private_data)->chip_status & USX2Y_STAT_CHIP_INIT) 
+	if (us428->chip_status & USX2Y_STAT_CHIP_INIT)
 		info->chip_ready = 1;
  	info->version = USX2Y_DRIVER_VERSION; 
 	return 0;
 }
 
 
-static int usX2Y_create_usbmidi(snd_card_t* card )
+static int usX2Y_create_usbmidi(struct snd_card *card)
 {
-	static snd_usb_midi_endpoint_info_t quirk_data_1 = {
-		.out_ep =0x06,
+	static struct snd_usb_midi_endpoint_info quirk_data_1 = {
+		.out_ep = 0x06,
 		.in_ep = 0x06,
 		.out_cables =	0x001,
 		.in_cables =	0x001
 	};
-	static snd_usb_audio_quirk_t quirk_1 = {
+	static struct snd_usb_audio_quirk quirk_1 = {
 		.vendor_name =	"TASCAM",
 		.product_name =	NAME_ALLCAPS,
 		.ifnum = 	0,
        		.type = QUIRK_MIDI_FIXED_ENDPOINT,
 		.data = &quirk_data_1
 	};
-	static snd_usb_midi_endpoint_info_t quirk_data_2 = {
-		.out_ep =0x06,
+	static struct snd_usb_midi_endpoint_info quirk_data_2 = {
+		.out_ep = 0x06,
 		.in_ep = 0x06,
 		.out_cables =	0x003,
 		.in_cables =	0x003
 	};
-	static snd_usb_audio_quirk_t quirk_2 = {
+	static struct snd_usb_audio_quirk quirk_2 = {
 		.vendor_name =	"TASCAM",
 		.product_name =	"US428",
 		.ifnum = 	0,
@@ -181,13 +183,15 @@
 	};
 	struct usb_device *dev = usX2Y(card)->chip.dev;
 	struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
-	snd_usb_audio_quirk_t *quirk = le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ? &quirk_2 : &quirk_1;
+	struct snd_usb_audio_quirk *quirk =
+		le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ?
+		&quirk_2 : &quirk_1;
 
 	snd_printdd("usX2Y_create_usbmidi \n");
 	return snd_usb_create_midi_interface(&usX2Y(card)->chip, iface, quirk);
 }
 
-static int usX2Y_create_alsa_devices(snd_card_t* card)
+static int usX2Y_create_alsa_devices(struct snd_card *card)
 {
 	int err;
 
@@ -207,9 +211,10 @@
 	return err;
 } 
 
-static int snd_usX2Y_hwdep_dsp_load(snd_hwdep_t *hw, snd_hwdep_dsp_image_t *dsp)
+static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
+				    struct snd_hwdep_dsp_image *dsp)
 {
-	usX2Ydev_t *priv = hw->private_data;
+	struct usX2Ydev *priv = hw->private_data;
 	int	lret, err = -EINVAL;
 	snd_printdd( "dsp_load %s\n", dsp->name);
 
@@ -256,10 +261,10 @@
 }
 
 
-int usX2Y_hwdep_new(snd_card_t* card, struct usb_device* device)
+int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device)
 {
 	int err;
-	snd_hwdep_t *hw;
+	struct snd_hwdep *hw;
 
 	if ((err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw)) < 0)
 		return err;
diff --git a/sound/usb/usx2y/usX2Yhwdep.h b/sound/usb/usx2y/usX2Yhwdep.h
index d612a26..c095d5b 100644
--- a/sound/usb/usx2y/usX2Yhwdep.h
+++ b/sound/usb/usx2y/usX2Yhwdep.h
@@ -1,6 +1,6 @@
 #ifndef USX2YHWDEP_H
 #define USX2YHWDEP_H
 
-int usX2Y_hwdep_new(snd_card_t* card, struct usb_device* device);
+int usX2Y_hwdep_new(struct snd_card *card, struct usb_device* device);
 
 #endif
diff --git a/sound/usb/usx2y/usbus428ctldefs.h b/sound/usb/usx2y/usbus428ctldefs.h
index 6af1643..b864e7e 100644
--- a/sound/usb/usx2y/usbus428ctldefs.h
+++ b/sound/usb/usx2y/usbus428ctldefs.h
@@ -51,7 +51,7 @@
 #define T_NULL  0x80
 
 
-struct us428_ctls{
+struct us428_ctls {
 	unsigned char   Fader[9];
 	unsigned char 	Transport;
 	unsigned char 	Modifier;
@@ -63,46 +63,42 @@
 	unsigned char   Wheel[5];
 };
 
-typedef struct us428_ctls us428_ctls_t;
-
-typedef struct us428_setByte{
+struct us428_setByte {
 	unsigned char Offset,
 		Value;
-}us428_setByte_t;
+};
 
 enum {
 	eLT_Volume = 0,
 	eLT_Light
 };
 
-typedef struct usX2Y_volume {
+struct usX2Y_volume {
 	unsigned char Channel,
 		LH,
 		LL,
 		RH,
 		RL;
-} usX2Y_volume_t;
-
-struct us428_lights{
-	us428_setByte_t Light[7];
 };
-typedef struct us428_lights us428_lights_t;
 
-typedef struct {
+struct us428_lights {
+	struct us428_setByte Light[7];
+};
+
+struct us428_p4out {
 	char type;
 	union {
-		usX2Y_volume_t	vol;
-		us428_lights_t  lights;
+		struct usX2Y_volume vol;
+		struct us428_lights lights;
 	} val;
-} us428_p4out_t;
+};
 
 #define N_us428_ctl_BUFS 16
 #define N_us428_p4out_BUFS 16
 struct us428ctls_sharedmem{
-	us428_ctls_t	CtlSnapShot[N_us428_ctl_BUFS];
-	int		CtlSnapShotDiffersAt[N_us428_ctl_BUFS];
-	int		CtlSnapShotLast, CtlSnapShotRed;
-	us428_p4out_t	p4out[N_us428_p4out_BUFS];
-	int		p4outLast, p4outSent;
+	struct us428_ctls	CtlSnapShot[N_us428_ctl_BUFS];
+	int			CtlSnapShotDiffersAt[N_us428_ctl_BUFS];
+	int			CtlSnapShotLast, CtlSnapShotRed;
+	struct us428_p4out	p4out[N_us428_p4out_BUFS];
+	int			p4outLast, p4outSent;
 };
-typedef struct us428ctls_sharedmem us428ctls_sharedmem_t;
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index cf77313..e0abb56 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -167,28 +167,28 @@
 static int snd_usX2Y_card_used[SNDRV_CARDS];
 
 static void usX2Y_usb_disconnect(struct usb_device* usb_device, void* ptr);
-static void snd_usX2Y_card_private_free(snd_card_t *card);
+static void snd_usX2Y_card_private_free(struct snd_card *card);
 
 /* 
  * pipe 4 is used for switching the lamps, setting samplerate, volumes ....   
  */
-static void i_usX2Y_Out04Int(struct urb* urb, struct pt_regs *regs)
+static void i_usX2Y_Out04Int(struct urb *urb, struct pt_regs *regs)
 {
 #ifdef CONFIG_SND_DEBUG
 	if (urb->status) {
 		int 		i;
-		usX2Ydev_t*	usX2Y = urb->context;
+		struct usX2Ydev *usX2Y = urb->context;
 		for (i = 0; i < 10 && usX2Y->AS04.urb[i] != urb; i++);
 		snd_printdd("i_usX2Y_Out04Int() urb %i status=%i\n", i, urb->status);
 	}
 #endif
 }
 
-static void i_usX2Y_In04Int(struct urb* urb, struct pt_regs *regs)
+static void i_usX2Y_In04Int(struct urb *urb, struct pt_regs *regs)
 {
 	int			err = 0;
-	usX2Ydev_t		*usX2Y = urb->context;
-	us428ctls_sharedmem_t	*us428ctls = usX2Y->us428ctls_sharedmem;
+	struct usX2Ydev		*usX2Y = urb->context;
+	struct us428ctls_sharedmem	*us428ctls = usX2Y->us428ctls_sharedmem;
 
 	usX2Y->In04IntCalls++;
 
@@ -239,10 +239,10 @@
 					send = 0;
 				for (j = 0; j < URBS_AsyncSeq  &&  !err; ++j)
 					if (0 == usX2Y->AS04.urb[j]->status) {
-						us428_p4out_t *p4out = us428ctls->p4out + send;	// FIXME if more then 1 p4out is new, 1 gets lost.
+						struct us428_p4out *p4out = us428ctls->p4out + send;	// FIXME if more then 1 p4out is new, 1 gets lost.
 						usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->chip.dev,
 								  usb_sndbulkpipe(usX2Y->chip.dev, 0x04), &p4out->val.vol, 
-								  p4out->type == eLT_Light ? sizeof(us428_lights_t) : 5,
+								  p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5,
 								  i_usX2Y_Out04Int, usX2Y);
 						err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC);
 						us428ctls->p4outSent = send;
@@ -261,7 +261,7 @@
 /*
  * Prepare some urbs
  */
-int usX2Y_AsyncSeq04_init(usX2Ydev_t* usX2Y)
+int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y)
 {
 	int	err = 0,
 		i;
@@ -283,9 +283,8 @@
 	return err;
 }
 
-int usX2Y_In04_init(usX2Ydev_t* usX2Y)
+int usX2Y_In04_init(struct usX2Ydev *usX2Y)
 {
-	int	err = 0;
 	if (! (usX2Y->In04urb = usb_alloc_urb(0, GFP_KERNEL)))
 		return -ENOMEM;
 
@@ -299,11 +298,10 @@
 			 usX2Y->In04Buf, 21,
 			 i_usX2Y_In04Int, usX2Y,
 			 10);
-	err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
-	return err;
+	return usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
 }
 
-static void usX2Y_unlinkSeq(snd_usX2Y_AsyncSeq_t* S)
+static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S)
 {
 	int	i;
 	for (i = 0; i < URBS_AsyncSeq; ++i) {
@@ -336,16 +334,16 @@
 	{ /* terminator */ }
 };
 
-static snd_card_t* usX2Y_create_card(struct usb_device* device)
+static struct snd_card *usX2Y_create_card(struct usb_device *device)
 {
 	int		dev;
-	snd_card_t*	card;
+	struct snd_card *	card;
 	for (dev = 0; dev < SNDRV_CARDS; ++dev)
 		if (enable[dev] && !snd_usX2Y_card_used[dev])
 			break;
 	if (dev >= SNDRV_CARDS)
 		return NULL;
-	card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(usX2Ydev_t));
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(struct usX2Ydev));
 	if (!card)
 		return NULL;
 	snd_usX2Y_card_used[usX2Y(card)->chip.index = dev] = 1;
@@ -369,10 +367,10 @@
 }
 
 
-static void* usX2Y_usb_probe(struct usb_device* device, struct usb_interface *intf, const struct usb_device_id* device_id)
+static void *usX2Y_usb_probe(struct usb_device *device, struct usb_interface *intf, const struct usb_device_id *device_id)
 {
 	int		err;
-	snd_card_t*	card;
+	struct snd_card *	card;
 	if (le16_to_cpu(device->descriptor.idVendor) != 0x1604 ||
 	    (le16_to_cpu(device->descriptor.idProduct) != USB_ID_US122 &&
 	     le16_to_cpu(device->descriptor.idProduct) != USB_ID_US224 &&
@@ -409,14 +407,13 @@
 
 MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table);
 static struct usb_driver snd_usX2Y_usb_driver = {
- 	.owner =	THIS_MODULE,
 	.name =		"snd-usb-usx2y",
 	.probe =	snd_usX2Y_probe,
 	.disconnect =	snd_usX2Y_disconnect,
 	.id_table =	snd_usX2Y_usb_id_table,
 };
 
-static void snd_usX2Y_card_private_free(snd_card_t *card)
+static void snd_usX2Y_card_private_free(struct snd_card *card)
 {
 	kfree(usX2Y(card)->In04Buf);
 	usb_free_urb(usX2Y(card)->In04urb);
@@ -429,23 +426,24 @@
 /*
  * Frees the device.
  */
-static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr)
+static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr)
 {
 	if (ptr) {
-		usX2Ydev_t* usX2Y = usX2Y((snd_card_t*)ptr);
-		struct list_head* p;
+		struct snd_card *card = ptr;
+		struct usX2Ydev *usX2Y = usX2Y(card);
+		struct list_head *p;
 		usX2Y->chip.shutdown = 1;
 		usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;
 		usX2Y_unlinkSeq(&usX2Y->AS04);
 		usb_kill_urb(usX2Y->In04urb);
-		snd_card_disconnect((snd_card_t*)ptr);
+		snd_card_disconnect(card);
 		/* release the midi resources */
 		list_for_each(p, &usX2Y->chip.midi_list) {
 			snd_usbmidi_disconnect(p);
 		}
 		if (usX2Y->us428ctls_sharedmem) 
 			wake_up(&usX2Y->us428ctls_wait_queue_head);
-		snd_card_free((snd_card_t*)ptr);
+		snd_card_free(card);
 	}
 }
 
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index f65f3a7..435c1fe 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -8,47 +8,46 @@
 
 #define URBS_AsyncSeq 10
 #define URB_DataLen_AsyncSeq 32
-typedef struct {
-	struct urb*	urb[URBS_AsyncSeq];
-	char*   buffer;
-} snd_usX2Y_AsyncSeq_t;
+struct snd_usX2Y_AsyncSeq {
+	struct urb	*urb[URBS_AsyncSeq];
+	char		*buffer;
+};
 
-typedef struct {
+struct snd_usX2Y_urbSeq {
 	int	submitted;
 	int	len;
-	struct urb*	urb[0];
-} snd_usX2Y_urbSeq_t;
+	struct urb	*urb[0];
+};
 
-typedef struct snd_usX2Y_substream snd_usX2Y_substream_t;
 #include "usx2yhwdeppcm.h"
 
-typedef struct {
-	snd_usb_audio_t 	chip;
+struct usX2Ydev {
+	struct snd_usb_audio 	chip;
 	int			stride;
 	struct urb		*In04urb;
 	void			*In04Buf;
 	char			In04Last[24];
 	unsigned		In04IntCalls;
-	snd_usX2Y_urbSeq_t	*US04;
+	struct snd_usX2Y_urbSeq	*US04;
 	wait_queue_head_t	In04WaitQueue;
-	snd_usX2Y_AsyncSeq_t	AS04;
+	struct snd_usX2Y_AsyncSeq	AS04;
 	unsigned int		rate,
 				format;
 	int			chip_status;
 	struct semaphore	prepare_mutex;
-	us428ctls_sharedmem_t	*us428ctls_sharedmem;
+	struct us428ctls_sharedmem	*us428ctls_sharedmem;
 	int			wait_iso_frame;
 	wait_queue_head_t	us428ctls_wait_queue_head;
-	snd_usX2Y_hwdep_pcm_shm_t	*hwdep_pcm_shm;
-	snd_usX2Y_substream_t	*subs[4];
-	snd_usX2Y_substream_t	* volatile  prepare_subs;
+	struct snd_usX2Y_hwdep_pcm_shm	*hwdep_pcm_shm;
+	struct snd_usX2Y_substream	*subs[4];
+	struct snd_usX2Y_substream	* volatile  prepare_subs;
 	wait_queue_head_t	prepare_wait_queue;
-} usX2Ydev_t;
+};
 
 
 struct snd_usX2Y_substream {
-	usX2Ydev_t	*usX2Y;
-	snd_pcm_substream_t *pcm_substream;
+	struct usX2Ydev	*usX2Y;
+	struct snd_pcm_substream *pcm_substream;
 
 	int			endpoint;		
 	unsigned int		maxpacksize;		/* max packet size in bytes */
@@ -72,12 +71,12 @@
 };
 
 
-#define usX2Y(c) ((usX2Ydev_t*)(c)->private_data)
+#define usX2Y(c) ((struct usX2Ydev *)(c)->private_data)
 
-int usX2Y_audio_create(snd_card_t* card);
+int usX2Y_audio_create(struct snd_card *card);
 
-int usX2Y_AsyncSeq04_init(usX2Ydev_t* usX2Y);
-int usX2Y_In04_init(usX2Ydev_t* usX2Y);
+int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y);
+int usX2Y_In04_init(struct usX2Ydev *usX2Y);
 
 #define NAME_ALLCAPS "US-X2Y"
 
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index affda97..a6bbc7a 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -67,18 +67,20 @@
 #endif
 
 
-static int usX2Y_urb_capt_retire(snd_usX2Y_substream_t *subs)
+static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs)
 {
 	struct urb	*urb = subs->completed_urb;
-	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
+	struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
 	unsigned char	*cp;
 	int 		i, len, lens = 0, hwptr_done = subs->hwptr_done;
-	usX2Ydev_t	*usX2Y = subs->usX2Y;
+	struct usX2Ydev	*usX2Y = subs->usX2Y;
 
 	for (i = 0; i < nr_of_packs(); i++) {
 		cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
 		if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */
-			snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status);
+			snd_printk(KERN_ERR "active frame status %i. "
+				   "Most propably some hardware problem.\n",
+				   urb->iso_frame_desc[i].status);
 			return urb->iso_frame_desc[i].status;
 		}
 		len = urb->iso_frame_desc[i].actual_length / usX2Y->stride;
@@ -94,7 +96,8 @@
 			memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, blen);
 			memcpy(runtime->dma_area, cp + blen, len * usX2Y->stride - blen);
 		} else {
-			memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp, len * usX2Y->stride);
+			memcpy(runtime->dma_area + hwptr_done * usX2Y->stride, cp,
+			       len * usX2Y->stride);
 		}
 		lens += len;
 		if ((hwptr_done += len) >= runtime->buffer_size)
@@ -120,13 +123,13 @@
  * it directly from the buffer.  thus the data is once copied to
  * a temporary buffer and urb points to that.
  */
-static int usX2Y_urb_play_prepare(snd_usX2Y_substream_t *subs,
+static int usX2Y_urb_play_prepare(struct snd_usX2Y_substream *subs,
 				  struct urb *cap_urb,
 				  struct urb *urb)
 {
 	int count, counts, pack;
-	usX2Ydev_t* usX2Y = subs->usX2Y;
-	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
+	struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
 
 	count = 0;
 	for (pack = 0; pack <  nr_of_packs(); pack++) {
@@ -139,7 +142,8 @@
 		}
 		/* set up descriptor */
 		urb->iso_frame_desc[pack].offset = pack ?
-			urb->iso_frame_desc[pack - 1].offset + urb->iso_frame_desc[pack - 1].length :
+			urb->iso_frame_desc[pack - 1].offset +
+			urb->iso_frame_desc[pack - 1].length :
 			0;
 		urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
 	}
@@ -151,8 +155,10 @@
 			int len;
 			len = runtime->buffer_size - subs->hwptr;
 			urb->transfer_buffer = subs->tmpbuf;
-			memcpy(subs->tmpbuf, runtime->dma_area + subs->hwptr * usX2Y->stride, len * usX2Y->stride);
-			memcpy(subs->tmpbuf + len * usX2Y->stride, runtime->dma_area, (count - len) * usX2Y->stride);
+			memcpy(subs->tmpbuf, runtime->dma_area +
+			       subs->hwptr * usX2Y->stride, len * usX2Y->stride);
+			memcpy(subs->tmpbuf + len * usX2Y->stride,
+			       runtime->dma_area, (count - len) * usX2Y->stride);
 			subs->hwptr += count;
 			subs->hwptr -= runtime->buffer_size;
 		} else {
@@ -172,9 +178,9 @@
  *
  * update the current position and call callback if a period is processed.
  */
-static void usX2Y_urb_play_retire(snd_usX2Y_substream_t *subs, struct urb *urb)
+static void usX2Y_urb_play_retire(struct snd_usX2Y_substream *subs, struct urb *urb)
 {
-	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
+	struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
 	int		len = urb->actual_length / subs->usX2Y->stride;
 
 	subs->transfer_done += len;
@@ -187,7 +193,7 @@
 	}
 }
 
-static int usX2Y_urb_submit(snd_usX2Y_substream_t *subs, struct urb *urb, int frame)
+static int usX2Y_urb_submit(struct snd_usX2Y_substream *subs, struct urb *urb, int frame)
 {
 	int err;
 	if (!urb)
@@ -202,50 +208,47 @@
 	return 0;
 }
 
-static inline int usX2Y_usbframe_complete(snd_usX2Y_substream_t *capsubs, snd_usX2Y_substream_t *playbacksubs, int frame)
+static inline int usX2Y_usbframe_complete(struct snd_usX2Y_substream *capsubs,
+					  struct snd_usX2Y_substream *playbacksubs,
+					  int frame)
 {
 	int err, state;
-	{
-		struct urb *urb = playbacksubs->completed_urb;
+	struct urb *urb = playbacksubs->completed_urb;
 
-		state = atomic_read(&playbacksubs->state);
-		if (NULL != urb) {
-			if (state == state_RUNNING)
-				usX2Y_urb_play_retire(playbacksubs, urb);
-			else
-				if (state >= state_PRERUNNING) {
-					atomic_inc(&playbacksubs->state);
-				}
-		} else {
-			switch (state) {
-			case state_STARTING1:
-				urb = playbacksubs->urb[0];
-				atomic_inc(&playbacksubs->state);
-				break;
-			case state_STARTING2:
-				urb = playbacksubs->urb[1];
-				atomic_inc(&playbacksubs->state);
-				break;
-			}
+	state = atomic_read(&playbacksubs->state);
+	if (NULL != urb) {
+		if (state == state_RUNNING)
+			usX2Y_urb_play_retire(playbacksubs, urb);
+		else if (state >= state_PRERUNNING)
+			atomic_inc(&playbacksubs->state);
+	} else {
+		switch (state) {
+		case state_STARTING1:
+			urb = playbacksubs->urb[0];
+			atomic_inc(&playbacksubs->state);
+			break;
+		case state_STARTING2:
+			urb = playbacksubs->urb[1];
+			atomic_inc(&playbacksubs->state);
+			break;
 		}
-		if (urb) {
-			if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
-			    (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
-				return err;
-			}
-		}
-
-		playbacksubs->completed_urb = NULL;
 	}
+	if (urb) {
+		if ((err = usX2Y_urb_play_prepare(playbacksubs, capsubs->completed_urb, urb)) ||
+		    (err = usX2Y_urb_submit(playbacksubs, urb, frame))) {
+			return err;
+		}
+	}
+
+	playbacksubs->completed_urb = NULL;
+
 	state = atomic_read(&capsubs->state);
 	if (state >= state_PREPARED) {
 		if (state == state_RUNNING) {
 			if ((err = usX2Y_urb_capt_retire(capsubs)))
 				return err;
-		} else
-			if (state >= state_PRERUNNING) {
-				atomic_inc(&capsubs->state);
-			}
+		} else if (state >= state_PRERUNNING)
+			atomic_inc(&capsubs->state);
 		if ((err = usX2Y_urb_submit(capsubs, capsubs->completed_urb, frame)))
 			return err;
 	}
@@ -254,18 +257,19 @@
 }
 
 
-static void usX2Y_clients_stop(usX2Ydev_t *usX2Y)
+static void usX2Y_clients_stop(struct usX2Ydev *usX2Y)
 {
 	int s, u;
+
 	for (s = 0; s < 4; s++) {
-		snd_usX2Y_substream_t *subs = usX2Y->subs[s];
+		struct snd_usX2Y_substream *subs = usX2Y->subs[s];
 		if (subs) {
 			snd_printdd("%i %p state=%i\n", s, subs, atomic_read(&subs->state));
 			atomic_set(&subs->state, state_STOPPED);
 		}
 	}
 	for (s = 0; s < 4; s++) {
-		snd_usX2Y_substream_t *subs = usX2Y->subs[s];
+		struct snd_usX2Y_substream *subs = usX2Y->subs[s];
 		if (subs) {
 			if (atomic_read(&subs->state) >= state_PRERUNNING) {
 				snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
@@ -273,7 +277,8 @@
 			for (u = 0; u < NRURBS; u++) {
 				struct urb *urb = subs->urb[u];
 				if (NULL != urb)
-					snd_printdd("%i status=%i start_frame=%i\n", u, urb->status, urb->start_frame);
+					snd_printdd("%i status=%i start_frame=%i\n",
+						    u, urb->status, urb->start_frame);
 			}
 		}
 	}
@@ -281,30 +286,36 @@
 	wake_up(&usX2Y->prepare_wait_queue);
 }
 
-static void usX2Y_error_urb_status(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
+static void usX2Y_error_urb_status(struct usX2Ydev *usX2Y,
+				   struct snd_usX2Y_substream *subs, struct urb *urb)
 {
 	snd_printk(KERN_ERR "ep=%i stalled with status=%i\n", subs->endpoint, urb->status);
 	urb->status = 0;
 	usX2Y_clients_stop(usX2Y);
 }
 
-static void usX2Y_error_sequence(usX2Ydev_t *usX2Y, snd_usX2Y_substream_t *subs, struct urb *urb)
+static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
+				 struct snd_usX2Y_substream *subs, struct urb *urb)
 {
 	snd_printk(KERN_ERR "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
 		   KERN_ERR "Most propably some urb of usb-frame %i is still missing.\n"
 		   KERN_ERR "Cause could be too long delays in usb-hcd interrupt handling.\n",
 		   usb_get_current_frame_number(usX2Y->chip.dev),
-		   subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
+		   subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
+		   usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
 	usX2Y_clients_stop(usX2Y);
 }
 
 static void i_usX2Y_urb_complete(struct urb *urb, struct pt_regs *regs)
 {
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
-	usX2Ydev_t *usX2Y = subs->usX2Y;
+	struct snd_usX2Y_substream *subs = urb->context;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
 
 	if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
-		snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", usb_get_current_frame_number(usX2Y->chip.dev), subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", urb->status, urb->start_frame);
+		snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
+			    usb_get_current_frame_number(usX2Y->chip.dev),
+			    subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
+			    urb->status, urb->start_frame);
 		return;
 	}
 	if (unlikely(urb->status)) {
@@ -318,10 +329,12 @@
 		return;
 	}
 	{
-		snd_usX2Y_substream_t *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
+		struct snd_usX2Y_substream *capsubs = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE],
 			*playbacksubs = usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
-		if (capsubs->completed_urb && atomic_read(&capsubs->state) >= state_PREPARED &&
-		    (playbacksubs->completed_urb || atomic_read(&playbacksubs->state) < state_PREPARED)) {
+		if (capsubs->completed_urb &&
+		    atomic_read(&capsubs->state) >= state_PREPARED &&
+		    (playbacksubs->completed_urb ||
+		     atomic_read(&playbacksubs->state) < state_PREPARED)) {
 			if (!usX2Y_usbframe_complete(capsubs, playbacksubs, urb->start_frame)) {
 				if (nr_of_packs() <= urb->start_frame &&
 				    urb->start_frame <= (2 * nr_of_packs() - 1))	// uhci and ohci
@@ -336,11 +349,12 @@
 	}
 }
 
-static void usX2Y_urbs_set_complete(usX2Ydev_t * usX2Y, void (*complete)(struct urb *, struct pt_regs *))
+static void usX2Y_urbs_set_complete(struct usX2Ydev * usX2Y,
+				    void (*complete)(struct urb *, struct pt_regs *))
 {
 	int s, u;
 	for (s = 0; s < 4; s++) {
-		snd_usX2Y_substream_t *subs = usX2Y->subs[s];
+		struct snd_usX2Y_substream *subs = usX2Y->subs[s];
 		if (NULL != subs)
 			for (u = 0; u < NRURBS; u++) {
 				struct urb * urb = subs->urb[u];
@@ -350,7 +364,7 @@
 	}
 }
 
-static void usX2Y_subs_startup_finish(usX2Ydev_t * usX2Y)
+static void usX2Y_subs_startup_finish(struct usX2Ydev * usX2Y)
 {
 	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_urb_complete);
 	usX2Y->prepare_subs = NULL;
@@ -358,9 +372,9 @@
 
 static void i_usX2Y_subs_startup(struct urb *urb, struct pt_regs *regs)
 {
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
-	usX2Ydev_t *usX2Y = subs->usX2Y;
-	snd_usX2Y_substream_t *prepare_subs = usX2Y->prepare_subs;
+	struct snd_usX2Y_substream *subs = urb->context;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
+	struct snd_usX2Y_substream *prepare_subs = usX2Y->prepare_subs;
 	if (NULL != prepare_subs)
 		if (urb->start_frame == prepare_subs->urb[0]->start_frame) {
 			usX2Y_subs_startup_finish(usX2Y);
@@ -371,9 +385,10 @@
 	i_usX2Y_urb_complete(urb, regs);
 }
 
-static void usX2Y_subs_prepare(snd_usX2Y_substream_t *subs)
+static void usX2Y_subs_prepare(struct snd_usX2Y_substream *subs)
 {
-	snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n", subs, subs->endpoint, subs->urb[0], subs->urb[1]);
+	snd_printdd("usX2Y_substream_prepare(%p) ep=%i urb0=%p urb1=%p\n",
+		    subs, subs->endpoint, subs->urb[0], subs->urb[1]);
 	/* reset the pointer */
 	subs->hwptr = 0;
 	subs->hwptr_done = 0;
@@ -381,7 +396,7 @@
 }
 
 
-static void usX2Y_urb_release(struct urb** urb, int free_tb)
+static void usX2Y_urb_release(struct urb **urb, int free_tb)
 {
 	if (*urb) {
 		usb_kill_urb(*urb);
@@ -394,12 +409,13 @@
 /*
  * release a substreams urbs
  */
-static void usX2Y_urbs_release(snd_usX2Y_substream_t *subs)
+static void usX2Y_urbs_release(struct snd_usX2Y_substream *subs)
 {
 	int i;
 	snd_printdd("usX2Y_urbs_release() %i\n", subs->endpoint);
 	for (i = 0; i < NRURBS; i++)
-		usX2Y_urb_release(subs->urb + i, subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
+		usX2Y_urb_release(subs->urb + i,
+				  subs != subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]);
 
 	kfree(subs->tmpbuf);
 	subs->tmpbuf = NULL;
@@ -407,7 +423,7 @@
 /*
  * initialize a substream's urbs
  */
-static int usX2Y_urbs_allocate(snd_usX2Y_substream_t *subs)
+static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
 {
 	int i;
 	unsigned int pipe;
@@ -429,7 +445,7 @@
 	}
 	/* allocate and initialize data urbs */
 	for (i = 0; i < NRURBS; i++) {
-		struct urb** purb = subs->urb + i;
+		struct urb **purb = subs->urb + i;
 		if (*purb) {
 			usb_kill_urb(*purb);
 			continue;
@@ -457,88 +473,86 @@
 	return 0;
 }
 
-static void usX2Y_subs_startup(snd_usX2Y_substream_t *subs)
+static void usX2Y_subs_startup(struct snd_usX2Y_substream *subs)
 {
-	usX2Ydev_t *usX2Y = subs->usX2Y;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
 	usX2Y->prepare_subs = subs;
 	subs->urb[0]->start_frame = -1;
 	wmb();
 	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_subs_startup);
 }
 
-static int usX2Y_urbs_start(snd_usX2Y_substream_t *subs)
+static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
 {
 	int i, err;
-	usX2Ydev_t *usX2Y = subs->usX2Y;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
 
 	if ((err = usX2Y_urbs_allocate(subs)) < 0)
 		return err;
 	subs->completed_urb = NULL;
 	for (i = 0; i < 4; i++) {
-		snd_usX2Y_substream_t *subs = usX2Y->subs[i];
+		struct snd_usX2Y_substream *subs = usX2Y->subs[i];
 		if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
 			goto start;
 	}
 	usX2Y->wait_iso_frame = -1;
- start:
-	{
-		usX2Y_subs_startup(subs);
-		for (i = 0; i < NRURBS; i++) {
-			struct urb *urb = subs->urb[i];
-			if (usb_pipein(urb->pipe)) {
-				unsigned long pack;
-				if (0 == i)
-					atomic_set(&subs->state, state_STARTING3);
-				urb->dev = usX2Y->chip.dev;
-				urb->transfer_flags = URB_ISO_ASAP;
-				for (pack = 0; pack < nr_of_packs(); pack++) {
-					urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
-					urb->iso_frame_desc[pack].length = subs->maxpacksize;
-				}
-				urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); 
-				if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
-					snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
-					err = -EPIPE;
-					goto cleanup;
-				} else {
-					if (0 > usX2Y->wait_iso_frame)
-						usX2Y->wait_iso_frame = urb->start_frame;
-				}
-				urb->transfer_flags = 0;
-			} else {
-				atomic_set(&subs->state, state_STARTING1);
-				break;
-			}
-		}
-		err = 0;
-		wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
-		if (atomic_read(&subs->state) != state_PREPARED) {
-			err = -EPIPE;
-		}
 
-	cleanup:
-		if (err) {
-			usX2Y_subs_startup_finish(usX2Y);
-			usX2Y_clients_stop(usX2Y);		// something is completely wroong > stop evrything
+ start:
+	usX2Y_subs_startup(subs);
+	for (i = 0; i < NRURBS; i++) {
+		struct urb *urb = subs->urb[i];
+		if (usb_pipein(urb->pipe)) {
+			unsigned long pack;
+			if (0 == i)
+				atomic_set(&subs->state, state_STARTING3);
+			urb->dev = usX2Y->chip.dev;
+			urb->transfer_flags = URB_ISO_ASAP;
+			for (pack = 0; pack < nr_of_packs(); pack++) {
+				urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
+				urb->iso_frame_desc[pack].length = subs->maxpacksize;
+			}
+			urb->transfer_buffer_length = subs->maxpacksize * nr_of_packs(); 
+			if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
+				snd_printk (KERN_ERR "cannot submit datapipe for urb %d, err = %d\n", i, err);
+				err = -EPIPE;
+				goto cleanup;
+			} else {
+				if (0 > usX2Y->wait_iso_frame)
+					usX2Y->wait_iso_frame = urb->start_frame;
+			}
+			urb->transfer_flags = 0;
+		} else {
+			atomic_set(&subs->state, state_STARTING1);
+			break;
 		}
 	}
+	err = 0;
+	wait_event(usX2Y->prepare_wait_queue, NULL == usX2Y->prepare_subs);
+	if (atomic_read(&subs->state) != state_PREPARED)
+		err = -EPIPE;
+
+ cleanup:
+	if (err) {
+		usX2Y_subs_startup_finish(usX2Y);
+		usX2Y_clients_stop(usX2Y);		// something is completely wroong > stop evrything
+	}
 	return err;
 }
 
 /*
  * return the current pcm pointer.  just return the hwptr_done value.
  */
-static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(snd_pcm_substream_t *substream)
+static snd_pcm_uframes_t snd_usX2Y_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
+	struct snd_usX2Y_substream *subs = substream->runtime->private_data;
 	return subs->hwptr_done;
 }
 /*
  * start/stop substream
  */
-static int snd_usX2Y_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
+static int snd_usX2Y_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)substream->runtime->private_data;
+	struct snd_usX2Y_substream *subs = substream->runtime->private_data;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
@@ -649,9 +663,9 @@
 };
 #define NOOF_SETRATE_URBS ARRAY_SIZE(SetRate48000)
 
-static void i_usX2Y_04Int(struct urb* urb, struct pt_regs *regs)
+static void i_usX2Y_04Int(struct urb *urb, struct pt_regs *regs)
 {
-	usX2Ydev_t*	usX2Y = urb->context;
+	struct usX2Ydev *usX2Y = urb->context;
 	
 	if (urb->status)
 		snd_printk(KERN_ERR "snd_usX2Y_04Int() urb->status=%i\n", urb->status);
@@ -659,21 +673,20 @@
 		wake_up(&usX2Y->In04WaitQueue);
 }
 
-static int usX2Y_rate_set(usX2Ydev_t *usX2Y, int rate)
+static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
 {
 	int			err = 0, i;
-	snd_usX2Y_urbSeq_t	*us = NULL;
+	struct snd_usX2Y_urbSeq	*us = NULL;
 	int			*usbdata = NULL;
 	struct s_c2		*ra = rate == 48000 ? SetRate48000 : SetRate44100;
 
 	if (usX2Y->rate != rate) {
-		us = kmalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
+		us = kzalloc(sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS, GFP_KERNEL);
 		if (NULL == us) {
 			err = -ENOMEM;
 			goto cleanup;
 		}
-		memset(us, 0, sizeof(*us) + sizeof(struct urb*) * NOOF_SETRATE_URBS); 
-		usbdata = kmalloc(sizeof(int)*NOOF_SETRATE_URBS, GFP_KERNEL);
+		usbdata = kmalloc(sizeof(int) * NOOF_SETRATE_URBS, GFP_KERNEL);
 		if (NULL == usbdata) {
 			err = -ENOMEM;
 			goto cleanup;
@@ -713,9 +726,8 @@
 			usX2Y->US04 = NULL;
 			kfree(usbdata);
 			kfree(us);
-			if (!err) {
+			if (!err)
 				usX2Y->rate = rate;
-			}
 		}
 	}
 
@@ -723,7 +735,7 @@
 }
 
 
-static int usX2Y_format_set(usX2Ydev_t *usX2Y, snd_pcm_format_t format)
+static int usX2Y_format_set(struct usX2Ydev *usX2Y, snd_pcm_format_t format)
 {
 	int alternate, err;
 	struct list_head* p;
@@ -753,40 +765,40 @@
 }
 
 
-static int snd_usX2Y_pcm_hw_params(snd_pcm_substream_t *substream,
-				   snd_pcm_hw_params_t *hw_params)
+static int snd_usX2Y_pcm_hw_params(struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *hw_params)
 {
 	int			err = 0;
 	unsigned int		rate = params_rate(hw_params);
 	snd_pcm_format_t	format = params_format(hw_params);
-	snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
+	struct snd_card *card = substream->pstr->pcm->card;
+	struct list_head *list;
 
-	{	// all pcm substreams off one usX2Y have to operate at the same rate & format
-		snd_card_t *card = substream->pstr->pcm->card;
-		struct list_head *list;
-		list_for_each(list, &card->devices) {
-			snd_device_t *dev;
-			snd_pcm_t *pcm;
-			int s;
-			dev = snd_device(list);
-			if (dev->type != SNDRV_DEV_PCM)
-				continue;
-			pcm = dev->device_data;
-			for (s = 0; s < 2; ++s) {
-				snd_pcm_substream_t *test_substream;
-				test_substream = pcm->streams[s].substream;
-				if (test_substream && test_substream != substream  &&
-				    test_substream->runtime &&
-				    ((test_substream->runtime->format &&
-				      test_substream->runtime->format != format) ||
-				     (test_substream->runtime->rate &&
-				      test_substream->runtime->rate != rate)))
-					return -EINVAL;
-			}
+	snd_printdd("snd_usX2Y_hw_params(%p, %p)\n", substream, hw_params);
+	// all pcm substreams off one usX2Y have to operate at the same rate & format
+	list_for_each(list, &card->devices) {
+		struct snd_device *dev;
+		struct snd_pcm *pcm;
+		int s;
+		dev = snd_device(list);
+		if (dev->type != SNDRV_DEV_PCM)
+			continue;
+		pcm = dev->device_data;
+		for (s = 0; s < 2; ++s) {
+			struct snd_pcm_substream *test_substream;
+			test_substream = pcm->streams[s].substream;
+			if (test_substream && test_substream != substream  &&
+			    test_substream->runtime &&
+			    ((test_substream->runtime->format &&
+			      test_substream->runtime->format != format) ||
+			     (test_substream->runtime->rate &&
+			      test_substream->runtime->rate != rate)))
+				return -EINVAL;
 		}
 	}
 	if (0 > (err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)))) {
-		snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n", substream, params_buffer_bytes(hw_params), err);
+		snd_printk(KERN_ERR "snd_pcm_lib_malloc_pages(%p, %i) returned %i\n",
+			   substream, params_buffer_bytes(hw_params), err);
 		return err;
 	}
 	return 0;
@@ -795,15 +807,15 @@
 /*
  * free the buffer
  */
-static int snd_usX2Y_pcm_hw_free(snd_pcm_substream_t *substream)
+static int snd_usX2Y_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_usX2Y_substream *subs = runtime->private_data;
 	down(&subs->usX2Y->prepare_mutex);
 	snd_printdd("snd_usX2Y_hw_free(%p)\n", substream);
 
 	if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
-		snd_usX2Y_substream_t *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+		struct snd_usX2Y_substream *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
 		atomic_set(&subs->state, state_STOPPED);
 		usX2Y_urbs_release(subs);
 		if (!cap_subs->pcm_substream ||
@@ -814,7 +826,7 @@
 			usX2Y_urbs_release(cap_subs);
 		}
 	} else {
-		snd_usX2Y_substream_t *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+		struct snd_usX2Y_substream *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
 		if (atomic_read(&playback_subs->state) < state_PREPARED) {
 			atomic_set(&subs->state, state_STOPPED);
 			usX2Y_urbs_release(subs);
@@ -828,12 +840,12 @@
  *
  * set format and initialize urbs
  */
-static int snd_usX2Y_pcm_prepare(snd_pcm_substream_t *substream)
+static int snd_usX2Y_pcm_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
-	usX2Ydev_t *usX2Y = subs->usX2Y;
-	snd_usX2Y_substream_t *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_usX2Y_substream *subs = runtime->private_data;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
+	struct snd_usX2Y_substream *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
 	int err = 0;
 	snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
 
@@ -861,7 +873,7 @@
 	return err;
 }
 
-static snd_pcm_hardware_t snd_usX2Y_2c =
+static struct snd_pcm_hardware snd_usX2Y_2c =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -882,11 +894,11 @@
 
 
 
-static int snd_usX2Y_pcm_open(snd_pcm_substream_t *substream)
+static int snd_usX2Y_pcm_open(struct snd_pcm_substream *substream)
 {
-	snd_usX2Y_substream_t	*subs = ((snd_usX2Y_substream_t **)
+	struct snd_usX2Y_substream	*subs = ((struct snd_usX2Y_substream **)
 					 snd_pcm_substream_chip(substream))[substream->stream];
-	snd_pcm_runtime_t	*runtime = substream->runtime;
+	struct snd_pcm_runtime	*runtime = substream->runtime;
 
 	if (subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS)
 		return -EBUSY;
@@ -900,19 +912,18 @@
 
 
 
-static int snd_usX2Y_pcm_close(snd_pcm_substream_t *substream)
+static int snd_usX2Y_pcm_close(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
-	int err = 0;
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_usX2Y_substream *subs = runtime->private_data;
 
 	subs->pcm_substream = NULL;
 
-	return err;
+	return 0;
 }
 
 
-static snd_pcm_ops_t snd_usX2Y_pcm_ops = 
+static struct snd_pcm_ops snd_usX2Y_pcm_ops = 
 {
 	.open =		snd_usX2Y_pcm_open,
 	.close =	snd_usX2Y_pcm_close,
@@ -928,7 +939,7 @@
 /*
  * free a usb stream instance
  */
-static void usX2Y_audio_stream_free(snd_usX2Y_substream_t **usX2Y_substream)
+static void usX2Y_audio_stream_free(struct snd_usX2Y_substream **usX2Y_substream)
 {
 	if (NULL != usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]) {
 		kfree(usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]);
@@ -938,25 +949,23 @@
 	usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE] = NULL;
 }
 
-static void snd_usX2Y_pcm_private_free(snd_pcm_t *pcm)
+static void snd_usX2Y_pcm_private_free(struct snd_pcm *pcm)
 {
-	snd_usX2Y_substream_t **usX2Y_stream = pcm->private_data;
-	if (usX2Y_stream) {
-		snd_pcm_lib_preallocate_free_for_all(pcm);
+	struct snd_usX2Y_substream **usX2Y_stream = pcm->private_data;
+	if (usX2Y_stream)
 		usX2Y_audio_stream_free(usX2Y_stream);
-	}
 }
 
-static int usX2Y_audio_stream_new(snd_card_t *card, int playback_endpoint, int capture_endpoint)
+static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint, int capture_endpoint)
 {
-	snd_pcm_t *pcm;
+	struct snd_pcm *pcm;
 	int err, i;
-	snd_usX2Y_substream_t **usX2Y_substream =
+	struct snd_usX2Y_substream **usX2Y_substream =
 		usX2Y(card)->subs + 2 * usX2Y(card)->chip.pcm_devs;
 
 	for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
 	     i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
-		usX2Y_substream[i] = kzalloc(sizeof(snd_usX2Y_substream_t), GFP_KERNEL);
+		usX2Y_substream[i] = kzalloc(sizeof(struct snd_usX2Y_substream), GFP_KERNEL);
 		if (NULL == usX2Y_substream[i]) {
 			snd_printk(KERN_ERR "cannot malloc\n");
 			return -ENOMEM;
@@ -1006,7 +1015,7 @@
 /*
  * create a chip instance and set its names.
  */
-int usX2Y_audio_create(snd_card_t* card)
+int usX2Y_audio_create(struct snd_card *card)
 {
 	int err = 0;
 	
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index c9136a9..796a7dce 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -58,12 +58,12 @@
 #include <sound/hwdep.h>
 
 
-static int usX2Y_usbpcm_urb_capt_retire(snd_usX2Y_substream_t *subs)
+static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs)
 {
 	struct urb	*urb = subs->completed_urb;
-	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
+	struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
 	int 		i, lens = 0, hwptr_done = subs->hwptr_done;
-	usX2Ydev_t	*usX2Y = subs->usX2Y;
+	struct usX2Ydev	*usX2Y = subs->usX2Y;
 	if (0 > usX2Y->hwdep_pcm_shm->capture_iso_start) { //FIXME
 		int head = usX2Y->hwdep_pcm_shm->captured_iso_head + 1;
 		if (head >= ARRAY_SIZE(usX2Y->hwdep_pcm_shm->captured_iso))
@@ -90,7 +90,8 @@
 	return 0;
 }
 
-static inline int usX2Y_iso_frames_per_buffer(snd_pcm_runtime_t *runtime, usX2Ydev_t * usX2Y)
+static inline int usX2Y_iso_frames_per_buffer(struct snd_pcm_runtime *runtime,
+					      struct usX2Ydev * usX2Y)
 {
 	return (runtime->buffer_size * 1000) / usX2Y->rate + 1;	//FIXME: so far only correct period_size == 2^x ?
 }
@@ -105,13 +106,13 @@
  * it directly from the buffer.  thus the data is once copied to
  * a temporary buffer and urb points to that.
  */
-static int usX2Y_hwdep_urb_play_prepare(snd_usX2Y_substream_t *subs,
-				  struct urb *urb)
+static int usX2Y_hwdep_urb_play_prepare(struct snd_usX2Y_substream *subs,
+					struct urb *urb)
 {
 	int count, counts, pack;
-	usX2Ydev_t *usX2Y = subs->usX2Y;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
 	struct snd_usX2Y_hwdep_pcm_shm *shm = usX2Y->hwdep_pcm_shm;
-	snd_pcm_runtime_t *runtime = subs->pcm_substream->runtime;
+	struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime;
 
 	if (0 > shm->playback_iso_start) {
 		shm->playback_iso_start = shm->captured_iso_head -
@@ -144,13 +145,14 @@
 }
 
 
-static inline void usX2Y_usbpcm_urb_capt_iso_advance(snd_usX2Y_substream_t *subs, struct urb *urb)
+static inline void usX2Y_usbpcm_urb_capt_iso_advance(struct snd_usX2Y_substream *subs,
+						     struct urb *urb)
 {
 	int pack;
 	for (pack = 0; pack < nr_of_packs(); ++pack) {
 		struct usb_iso_packet_descriptor *desc = urb->iso_frame_desc + pack;
 		if (NULL != subs) {
-			snd_usX2Y_hwdep_pcm_shm_t *shm = subs->usX2Y->hwdep_pcm_shm;
+			struct snd_usX2Y_hwdep_pcm_shm *shm = subs->usX2Y->hwdep_pcm_shm;
 			int head = shm->captured_iso_head + 1;
 			if (head >= ARRAY_SIZE(shm->captured_iso))
 				head = 0;
@@ -166,9 +168,10 @@
 	}
 }
 
-static inline int usX2Y_usbpcm_usbframe_complete(snd_usX2Y_substream_t *capsubs,
-					   snd_usX2Y_substream_t *capsubs2,
-					   snd_usX2Y_substream_t *playbacksubs, int frame)
+static inline int usX2Y_usbpcm_usbframe_complete(struct snd_usX2Y_substream *capsubs,
+						 struct snd_usX2Y_substream *capsubs2,
+						 struct snd_usX2Y_substream *playbacksubs,
+						 int frame)
 {
 	int err, state;
 	struct urb *urb = playbacksubs->completed_urb;
@@ -177,10 +180,8 @@
 	if (NULL != urb) {
 		if (state == state_RUNNING)
 			usX2Y_urb_play_retire(playbacksubs, urb);
-		else
-			if (state >= state_PRERUNNING) {
-				atomic_inc(&playbacksubs->state);
-			}
+		else if (state >= state_PRERUNNING)
+			atomic_inc(&playbacksubs->state);
 	} else {
 		switch (state) {
 		case state_STARTING1:
@@ -207,10 +208,8 @@
 		if (state == state_RUNNING) {
 			if ((err = usX2Y_usbpcm_urb_capt_retire(capsubs)))
 				return err;
-		} else {
-			if (state >= state_PRERUNNING)
-				atomic_inc(&capsubs->state);
-		}
+		} else if (state >= state_PRERUNNING)
+			atomic_inc(&capsubs->state);
 		usX2Y_usbpcm_urb_capt_iso_advance(capsubs, capsubs->completed_urb);
 		if (NULL != capsubs2)
 			usX2Y_usbpcm_urb_capt_iso_advance(NULL, capsubs2->completed_urb);
@@ -229,12 +228,15 @@
 
 static void i_usX2Y_usbpcm_urb_complete(struct urb *urb, struct pt_regs *regs)
 {
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
-	usX2Ydev_t *usX2Y = subs->usX2Y;
-	snd_usX2Y_substream_t *capsubs, *capsubs2, *playbacksubs;
+	struct snd_usX2Y_substream *subs = urb->context;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
+	struct snd_usX2Y_substream *capsubs, *capsubs2, *playbacksubs;
 
 	if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
-		snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", usb_get_current_frame_number(usX2Y->chip.dev), subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", urb->status, urb->start_frame);
+		snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
+			    usb_get_current_frame_number(usX2Y->chip.dev),
+			    subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
+			    urb->status, urb->start_frame);
 		return;
 	}
 	if (unlikely(urb->status)) {
@@ -268,7 +270,7 @@
 }
 
 
-static void usX2Y_hwdep_urb_release(struct urb** urb)
+static void usX2Y_hwdep_urb_release(struct urb **urb)
 {
 	usb_kill_urb(*urb);
 	usb_free_urb(*urb);
@@ -278,7 +280,7 @@
 /*
  * release a substream
  */
-static void usX2Y_usbpcm_urbs_release(snd_usX2Y_substream_t *subs)
+static void usX2Y_usbpcm_urbs_release(struct snd_usX2Y_substream *subs)
 {
 	int i;
 	snd_printdd("snd_usX2Y_urbs_release() %i\n", subs->endpoint);
@@ -286,7 +288,7 @@
 		usX2Y_hwdep_urb_release(subs->urb + i);
 }
 
-static void usX2Y_usbpcm_subs_startup_finish(usX2Ydev_t * usX2Y)
+static void usX2Y_usbpcm_subs_startup_finish(struct usX2Ydev * usX2Y)
 {
 	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_urb_complete);
 	usX2Y->prepare_subs = NULL;
@@ -294,14 +296,14 @@
 
 static void i_usX2Y_usbpcm_subs_startup(struct urb *urb, struct pt_regs *regs)
 {
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t*)urb->context;
-	usX2Ydev_t *usX2Y = subs->usX2Y;
-	snd_usX2Y_substream_t *prepare_subs = usX2Y->prepare_subs;
+	struct snd_usX2Y_substream *subs = urb->context;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
+	struct snd_usX2Y_substream *prepare_subs = usX2Y->prepare_subs;
 	if (NULL != prepare_subs &&
 	    urb->start_frame == prepare_subs->urb[0]->start_frame) {
 		atomic_inc(&prepare_subs->state);
 		if (prepare_subs == usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE]) {
-			snd_usX2Y_substream_t *cap_subs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
+			struct snd_usX2Y_substream *cap_subs2 = usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
 			if (cap_subs2 != NULL)
 				atomic_inc(&cap_subs2->state);
 		}
@@ -315,7 +317,7 @@
 /*
  * initialize a substream's urbs
  */
-static int usX2Y_usbpcm_urbs_allocate(snd_usX2Y_substream_t *subs)
+static int usX2Y_usbpcm_urbs_allocate(struct snd_usX2Y_substream *subs)
 {
 	int i;
 	unsigned int pipe;
@@ -330,7 +332,7 @@
 
 	/* allocate and initialize data urbs */
 	for (i = 0; i < NRURBS; i++) {
-		struct urb** purb = subs->urb + i;
+		struct urb **purb = subs->urb + i;
 		if (*purb) {
 			usb_kill_urb(*purb);
 			continue;
@@ -359,16 +361,16 @@
 /*
  * free the buffer
  */
-static int snd_usX2Y_usbpcm_hw_free(snd_pcm_substream_t *substream)
+static int snd_usX2Y_usbpcm_hw_free(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data,
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_usX2Y_substream *subs = runtime->private_data,
 		*cap_subs2 = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE + 2];
 	down(&subs->usX2Y->prepare_mutex);
 	snd_printdd("snd_usX2Y_usbpcm_hw_free(%p)\n", substream);
 
 	if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
-		snd_usX2Y_substream_t *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+		struct snd_usX2Y_substream *cap_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
 		atomic_set(&subs->state, state_STOPPED);
 		usX2Y_usbpcm_urbs_release(subs);
 		if (!cap_subs->pcm_substream ||
@@ -383,7 +385,7 @@
 				usX2Y_usbpcm_urbs_release(cap_subs2);
 		}
 	} else {
-		snd_usX2Y_substream_t *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
+		struct snd_usX2Y_substream *playback_subs = subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
 		if (atomic_read(&playback_subs->state) < state_PREPARED) {
 			atomic_set(&subs->state, state_STOPPED);
 			if (NULL != cap_subs2)
@@ -397,20 +399,20 @@
 	return snd_pcm_lib_free_pages(substream);
 }
 
-static void usX2Y_usbpcm_subs_startup(snd_usX2Y_substream_t *subs)
+static void usX2Y_usbpcm_subs_startup(struct snd_usX2Y_substream *subs)
 {
-	usX2Ydev_t * usX2Y = subs->usX2Y;
+	struct usX2Ydev * usX2Y = subs->usX2Y;
 	usX2Y->prepare_subs = subs;
 	subs->urb[0]->start_frame = -1;
 	smp_wmb();	// Make shure above modifications are seen by i_usX2Y_subs_startup()
 	usX2Y_urbs_set_complete(usX2Y, i_usX2Y_usbpcm_subs_startup);
 }
 
-static int usX2Y_usbpcm_urbs_start(snd_usX2Y_substream_t *subs)
+static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
 {
 	int	p, u, err,
 		stream = subs->pcm_substream->stream;
-	usX2Ydev_t *usX2Y = subs->usX2Y;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
 
 	if (SNDRV_PCM_STREAM_CAPTURE == stream) {
 		usX2Y->hwdep_pcm_shm->captured_iso_head = -1;
@@ -418,7 +420,7 @@
 	}
 
 	for (p = 0; 3 >= (stream + p); p += 2) {
-		snd_usX2Y_substream_t *subs = usX2Y->subs[stream + p];
+		struct snd_usX2Y_substream *subs = usX2Y->subs[stream + p];
 		if (subs != NULL) {
 			if ((err = usX2Y_usbpcm_urbs_allocate(subs)) < 0)
 				return err;
@@ -427,7 +429,7 @@
 	}
 
 	for (p = 0; p < 4; p++) {
-		snd_usX2Y_substream_t *subs = usX2Y->subs[p];
+		struct snd_usX2Y_substream *subs = usX2Y->subs[p];
 		if (subs != NULL && atomic_read(&subs->state) >= state_PREPARED)
 			goto start;
 	}
@@ -437,7 +439,7 @@
 	usX2Y_usbpcm_subs_startup(subs);
 	for (u = 0; u < NRURBS; u++) {
 		for (p = 0; 3 >= (stream + p); p += 2) {
-			snd_usX2Y_substream_t *subs = usX2Y->subs[stream + p];
+			struct snd_usX2Y_substream *subs = usX2Y->subs[stream + p];
 			if (subs != NULL) {
 				struct urb *urb = subs->urb[u];
 				if (usb_pipein(urb->pipe)) {
@@ -486,19 +488,19 @@
  *
  * set format and initialize urbs
  */
-static int snd_usX2Y_usbpcm_prepare(snd_pcm_substream_t *substream)
+static int snd_usX2Y_usbpcm_prepare(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
-	usX2Ydev_t *usX2Y = subs->usX2Y;
-	snd_usX2Y_substream_t *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_usX2Y_substream *subs = runtime->private_data;
+	struct usX2Ydev *usX2Y = subs->usX2Y;
+	struct snd_usX2Y_substream *capsubs = subs->usX2Y->subs[SNDRV_PCM_STREAM_CAPTURE];
 	int err = 0;
 	snd_printdd("snd_usX2Y_pcm_prepare(%p)\n", substream);
 
 	if (NULL == usX2Y->hwdep_pcm_shm) {
-		if (NULL == (usX2Y->hwdep_pcm_shm = snd_malloc_pages(sizeof(snd_usX2Y_hwdep_pcm_shm_t), GFP_KERNEL)))
+		if (NULL == (usX2Y->hwdep_pcm_shm = snd_malloc_pages(sizeof(struct snd_usX2Y_hwdep_pcm_shm), GFP_KERNEL)))
 			return -ENOMEM;
-		memset(usX2Y->hwdep_pcm_shm, 0, sizeof(snd_usX2Y_hwdep_pcm_shm_t));
+		memset(usX2Y->hwdep_pcm_shm, 0, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
 	}
 
 	down(&usX2Y->prepare_mutex);
@@ -512,7 +514,8 @@
 		if (usX2Y->rate != runtime->rate)
 			if ((err = usX2Y_rate_set(usX2Y, runtime->rate)) < 0)
 				goto up_prepare_mutex;
-		snd_printdd("starting capture pipe for %s\n", subs == capsubs ? "self" : "playpipe");
+		snd_printdd("starting capture pipe for %s\n", subs == capsubs ?
+			    "self" : "playpipe");
 		if (0 > (err = usX2Y_usbpcm_urbs_start(capsubs)))
 			goto up_prepare_mutex;
 	}
@@ -520,8 +523,12 @@
 	if (subs != capsubs) {
 		usX2Y->hwdep_pcm_shm->playback_iso_start = -1;
 		if (atomic_read(&subs->state) < state_PREPARED) {
-			while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) > usX2Y->hwdep_pcm_shm->captured_iso_frames) {
-				snd_printd("Wait: iso_frames_per_buffer=%i,captured_iso_frames=%i\n", usX2Y_iso_frames_per_buffer(runtime, usX2Y), usX2Y->hwdep_pcm_shm->captured_iso_frames);
+			while (usX2Y_iso_frames_per_buffer(runtime, usX2Y) >
+			       usX2Y->hwdep_pcm_shm->captured_iso_frames) {
+				snd_printdd("Wait: iso_frames_per_buffer=%i,"
+					    "captured_iso_frames=%i\n",
+					    usX2Y_iso_frames_per_buffer(runtime, usX2Y),
+					    usX2Y->hwdep_pcm_shm->captured_iso_frames);
 				if (msleep_interruptible(10)) {
 					err = -ERESTARTSYS;
 					goto up_prepare_mutex;
@@ -530,7 +537,9 @@
 			if (0 > (err = usX2Y_usbpcm_urbs_start(subs)))
 				goto up_prepare_mutex;
 		}
-		snd_printd("Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n", usX2Y_iso_frames_per_buffer(runtime, usX2Y), usX2Y->hwdep_pcm_shm->captured_iso_frames);
+		snd_printdd("Ready: iso_frames_per_buffer=%i,captured_iso_frames=%i\n",
+			    usX2Y_iso_frames_per_buffer(runtime, usX2Y),
+			    usX2Y->hwdep_pcm_shm->captured_iso_frames);
 	} else
 		usX2Y->hwdep_pcm_shm->capture_iso_start = -1;
 
@@ -539,7 +548,7 @@
 	return err;
 }
 
-static snd_pcm_hardware_t snd_usX2Y_4c =
+static struct snd_pcm_hardware snd_usX2Y_4c =
 {
 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -560,11 +569,11 @@
 
 
 
-static int snd_usX2Y_usbpcm_open(snd_pcm_substream_t *substream)
+static int snd_usX2Y_usbpcm_open(struct snd_pcm_substream *substream)
 {
-	snd_usX2Y_substream_t	*subs = ((snd_usX2Y_substream_t **)
+	struct snd_usX2Y_substream	*subs = ((struct snd_usX2Y_substream **)
 					 snd_pcm_substream_chip(substream))[substream->stream];
-	snd_pcm_runtime_t	*runtime = substream->runtime;
+	struct snd_pcm_runtime	*runtime = substream->runtime;
 
 	if (!(subs->usX2Y->chip_status & USX2Y_STAT_CHIP_MMAP_PCM_URBS))
 		return -EBUSY;
@@ -578,18 +587,17 @@
 }
 
 
-static int snd_usX2Y_usbpcm_close(snd_pcm_substream_t *substream)
+static int snd_usX2Y_usbpcm_close(struct snd_pcm_substream *substream)
 {
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_usX2Y_substream_t *subs = (snd_usX2Y_substream_t *)runtime->private_data;
-	int err = 0;
-	snd_printd("\n");
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_usX2Y_substream *subs = runtime->private_data;
+
 	subs->pcm_substream = NULL;
-	return err;
+	return 0;
 }
 
 
-static snd_pcm_ops_t snd_usX2Y_usbpcm_ops = 
+static struct snd_pcm_ops snd_usX2Y_usbpcm_ops = 
 {
 	.open =		snd_usX2Y_usbpcm_open,
 	.close =	snd_usX2Y_usbpcm_close,
@@ -602,11 +610,11 @@
 };
 
 
-static int usX2Y_pcms_lock_check(snd_card_t *card)
+static int usX2Y_pcms_lock_check(struct snd_card *card)
 {
 	struct list_head *list;
-	snd_device_t *dev;
-	snd_pcm_t *pcm;
+	struct snd_device *dev;
+	struct snd_pcm *pcm;
 	int err = 0;
 	list_for_each(list, &card->devices) {
 		dev = snd_device(list);
@@ -622,7 +630,7 @@
 			continue;
 		pcm = dev->device_data;
 		for (s = 0; s < 2; ++s) {
-			snd_pcm_substream_t *substream;
+			struct snd_pcm_substream *substream;
 			substream = pcm->streams[s].substream;
 			if (substream && substream->ffile != NULL)
 				err = -EBUSY;
@@ -632,11 +640,11 @@
 }
 
 
-static void usX2Y_pcms_unlock(snd_card_t *card)
+static void usX2Y_pcms_unlock(struct snd_card *card)
 {
 	struct list_head *list;
-	snd_device_t *dev;
-	snd_pcm_t *pcm;
+	struct snd_device *dev;
+	struct snd_pcm *pcm;
 	list_for_each(list, &card->devices) {
 		dev = snd_device(list);
 		if (dev->type != SNDRV_DEV_PCM)
@@ -647,10 +655,10 @@
 }
 
 
-static int snd_usX2Y_hwdep_pcm_open(snd_hwdep_t *hw, struct file *file)
+static int snd_usX2Y_hwdep_pcm_open(struct snd_hwdep *hw, struct file *file)
 {
 	// we need to be the first 
-	snd_card_t *card = hw->card;
+	struct snd_card *card = hw->card;
 	int err = usX2Y_pcms_lock_check(card);
 	if (0 == err)
 		usX2Y(card)->chip_status |= USX2Y_STAT_CHIP_MMAP_PCM_URBS;
@@ -659,9 +667,9 @@
 }
 
 
-static int snd_usX2Y_hwdep_pcm_release(snd_hwdep_t *hw, struct file *file)
+static int snd_usX2Y_hwdep_pcm_release(struct snd_hwdep *hw, struct file *file)
 {
-	snd_card_t *card = hw->card;
+	struct snd_card *card = hw->card;
 	int err = usX2Y_pcms_lock_check(card);
 	if (0 == err)
 		usX2Y(hw->card)->chip_status &= ~USX2Y_STAT_CHIP_MMAP_PCM_URBS;
@@ -689,7 +697,7 @@
 	offset = area->vm_pgoff << PAGE_SHIFT;
 	offset += address - area->vm_start;
 	snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_OOM);
-	vaddr = (char*)((usX2Ydev_t*)area->vm_private_data)->hwdep_pcm_shm + offset;
+	vaddr = (char*)((struct usX2Ydev *)area->vm_private_data)->hwdep_pcm_shm + offset;
 	page = virt_to_page(vaddr);
 	get_page(page);
 
@@ -707,17 +715,17 @@
 };
 
 
-static int snd_usX2Y_hwdep_pcm_mmap(snd_hwdep_t * hw, struct file *filp, struct vm_area_struct *area)
+static int snd_usX2Y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, struct vm_area_struct *area)
 {
 	unsigned long	size = (unsigned long)(area->vm_end - area->vm_start);
-	usX2Ydev_t	*usX2Y = (usX2Ydev_t*)hw->private_data;
+	struct usX2Ydev	*usX2Y = hw->private_data;
 
-	if (!(((usX2Ydev_t*)hw->private_data)->chip_status & USX2Y_STAT_CHIP_INIT))
+	if (!(usX2Y->chip_status & USX2Y_STAT_CHIP_INIT))
 		return -EBUSY;
 
 	/* if userspace tries to mmap beyond end of our buffer, fail */ 
-	if (size > PAGE_ALIGN(sizeof(snd_usX2Y_hwdep_pcm_shm_t))) {
-		snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(snd_usX2Y_hwdep_pcm_shm_t)); 
+	if (size > PAGE_ALIGN(sizeof(struct snd_usX2Y_hwdep_pcm_shm))) {
+		snd_printd("%lu > %lu\n", size, (unsigned long)sizeof(struct snd_usX2Y_hwdep_pcm_shm)); 
 		return -EINVAL;
 	}
 
@@ -726,39 +734,31 @@
 	}
 	area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
 	area->vm_flags |= VM_RESERVED;
-	snd_printd("vm_flags=0x%lX\n", area->vm_flags);
 	area->vm_private_data = hw->private_data;
 	return 0;
 }
 
 
-static void snd_usX2Y_hwdep_pcm_private_free(snd_hwdep_t *hwdep)
+static void snd_usX2Y_hwdep_pcm_private_free(struct snd_hwdep *hwdep)
 {
-	usX2Ydev_t *usX2Y = (usX2Ydev_t *)hwdep->private_data;
+	struct usX2Ydev *usX2Y = hwdep->private_data;
 	if (NULL != usX2Y->hwdep_pcm_shm)
-		snd_free_pages(usX2Y->hwdep_pcm_shm, sizeof(snd_usX2Y_hwdep_pcm_shm_t));
+		snd_free_pages(usX2Y->hwdep_pcm_shm, sizeof(struct snd_usX2Y_hwdep_pcm_shm));
 }
 
 
-static void snd_usX2Y_usbpcm_private_free(snd_pcm_t *pcm)
-{
-	snd_pcm_lib_preallocate_free_for_all(pcm);
-}
-
-
-int usX2Y_hwdep_pcm_new(snd_card_t* card)
+int usX2Y_hwdep_pcm_new(struct snd_card *card)
 {
 	int err;
-	snd_hwdep_t *hw;
-	snd_pcm_t *pcm;
+	struct snd_hwdep *hw;
+	struct snd_pcm *pcm;
 	struct usb_device *dev = usX2Y(card)->chip.dev;
 	if (1 != nr_of_packs())
 		return 0;
 
-	if ((err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw)) < 0) {
-		snd_printd("\n");
+	if ((err = snd_hwdep_new(card, SND_USX2Y_USBPCM_ID, 1, &hw)) < 0)
 		return err;
-	}
+
 	hw->iface = SNDRV_HWDEP_IFACE_USX2Y_PCM;
 	hw->private_data = usX2Y(card);
 	hw->private_free = snd_usX2Y_hwdep_pcm_private_free;
@@ -776,7 +776,6 @@
 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_usX2Y_usbpcm_ops);
 
 	pcm->private_data = usX2Y(card)->subs;
-	pcm->private_free = snd_usX2Y_usbpcm_private_free;
 	pcm->info_flags = 0;
 
 	sprintf(pcm->name, NAME_ALLCAPS" hwdep Audio");
@@ -788,7 +787,6 @@
 	    					     SNDRV_DMA_TYPE_CONTINUOUS,
 	    					     snd_dma_continuous_data(GFP_KERNEL),
 						     64*1024, 128*1024))) {
-		snd_usX2Y_usbpcm_private_free(pcm);
 		return err;
 	}
 
@@ -798,7 +796,7 @@
 
 #else
 
-int usX2Y_hwdep_pcm_new(snd_card_t* card)
+int usX2Y_hwdep_pcm_new(struct snd_card *card)
 {
 	return 0;
 }
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.h b/sound/usb/usx2y/usx2yhwdeppcm.h
index d68f0cb..c3382fd 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.h
+++ b/sound/usb/usx2y/usx2yhwdeppcm.h
@@ -18,4 +18,3 @@
 	volatile unsigned captured_iso_frames;
 	int capture_iso_start;
 };
-typedef struct snd_usX2Y_hwdep_pcm_shm snd_usX2Y_hwdep_pcm_shm_t;